diff --git a/Documentation/ABI/stable/sysfs-driver-dma-idxd b/Documentation/ABI/stable/sysfs-driver-dma-idxd
index f4be46cc6cb6..b5bebf642db6 100644
--- a/Documentation/ABI/stable/sysfs-driver-dma-idxd
+++ b/Documentation/ABI/stable/sysfs-driver-dma-idxd
@@ -1,3 +1,9 @@
+What:		sys/bus/dsa/devices/dsa<m>/version
+Date:		Apr 15, 2020
+KernelVersion:	5.8.0
+Contact:	dmaengine@vger.kernel.org
+Description:	The hardware version number.
+
 What:           sys/bus/dsa/devices/dsa<m>/cdev_major
 Date:           Oct 25, 2019
 KernelVersion: 	5.6.0
diff --git a/Documentation/ABI/testing/debugfs-cec-error-inj b/Documentation/ABI/testing/debugfs-cec-error-inj
index 4c3596c6d25b..5afcd78fbdb7 100644
--- a/Documentation/ABI/testing/debugfs-cec-error-inj
+++ b/Documentation/ABI/testing/debugfs-cec-error-inj
@@ -37,4 +37,4 @@ when changes are made.
 
 The following CEC error injection implementations exist:
 
-- Documentation/media/uapi/cec/cec-pin-error-inj.rst
+- Documentation/userspace-api/media/cec/cec-pin-error-inj.rst
diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs
index bd8a0d19abe6..427f5b45c67f 100644
--- a/Documentation/ABI/testing/sysfs-fs-f2fs
+++ b/Documentation/ABI/testing/sysfs-fs-f2fs
@@ -323,3 +323,18 @@ What:		/sys/fs/f2fs/<disk>/mounted_time_sec
 Date:		February 2020
 Contact:	"Jaegeuk Kim" <jaegeuk@kernel.org>
 Description:	Show the mounted time in secs of this partition.
+
+What:		/sys/fs/f2fs/<disk>/data_io_flag
+Date:		April 2020
+Contact:	"Jaegeuk Kim" <jaegeuk@kernel.org>
+Description:	Give a way to attach REQ_META|FUA to data writes
+		given temperature-based bits. Now the bits indicate:
+		*      REQ_META     |      REQ_FUA      |
+		*    5 |    4 |   3 |    2 |    1 |   0 |
+		* Cold | Warm | Hot | Cold | Warm | Hot |
+
+What:		/sys/fs/f2fs/<disk>/iostat_period_ms
+Date:		April 2020
+Contact:	"Daeho Jeong" <daehojeong@google.com>
+Description:	Give a way to change iostat_period time. 3secs by default.
+		The new iostat trace gives stats gap given the period.
diff --git a/Documentation/Makefile b/Documentation/Makefile
index cc786d11a028..7e12d10ca8e0 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -55,15 +55,15 @@ I18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
 loop_cmd = $(echo-cmd) $(cmd_$(1)) || exit;
 
 # $2 sphinx builder e.g. "html"
-# $3 name of the build subfolder / e.g. "media", used as:
+# $3 name of the build subfolder / e.g. "userspace-api/media", used as:
 #    * dest folder relative to $(BUILDDIR) and
 #    * cache folder relative to $(BUILDDIR)/.doctrees
-# $4 dest subfolder e.g. "man" for man pages at media/man
+# $4 dest subfolder e.g. "man" for man pages at userspace-api/media/man
 # $5 reST source folder relative to $(srctree)/$(src),
-#    e.g. "media" for the linux-tv book-set at ./Documentation/media
+#    e.g. "userspace-api/media" for the linux-tv book-set at ./Documentation/userspace-api/media
 
 quiet_cmd_sphinx = SPHINX  $@ --> file://$(abspath $(BUILDDIR)/$3/$4)
-      cmd_sphinx = $(MAKE) BUILDDIR=$(abspath $(BUILDDIR)) $(build)=Documentation/media $2 && \
+      cmd_sphinx = $(MAKE) BUILDDIR=$(abspath $(BUILDDIR)) $(build)=Documentation/userspace-api/media $2 && \
 	PYTHONDONTWRITEBYTECODE=1 \
 	BUILDDIR=$(abspath $(BUILDDIR)) SPHINX_CONF=$(abspath $(srctree)/$(src)/$5/$(SPHINX_CONF)) \
 	$(PYTHON) $(srctree)/scripts/jobserver-exec \
@@ -120,7 +120,7 @@ refcheckdocs:
 
 cleandocs:
 	$(Q)rm -rf $(BUILDDIR)
-	$(Q)$(MAKE) BUILDDIR=$(abspath $(BUILDDIR)) $(build)=Documentation/media clean
+	$(Q)$(MAKE) BUILDDIR=$(abspath $(BUILDDIR)) $(build)=Documentation/userspace-api/media clean
 
 dochelp:
 	@echo  ' Linux kernel internal documentation in different formats from ReST:'
diff --git a/Documentation/admin-guide/device-mapper/dm-integrity.rst b/Documentation/admin-guide/device-mapper/dm-integrity.rst
index c00f9f11e3f3..8439d2ae689b 100644
--- a/Documentation/admin-guide/device-mapper/dm-integrity.rst
+++ b/Documentation/admin-guide/device-mapper/dm-integrity.rst
@@ -182,12 +182,15 @@ fix_padding
 	space-efficient. If this option is not present, large padding is
 	used - that is for compatibility with older kernels.
 
-
-The journal mode (D/J), buffer_sectors, journal_watermark, commit_time can
-be changed when reloading the target (load an inactive table and swap the
-tables with suspend and resume). The other arguments should not be changed
-when reloading the target because the layout of disk data depend on them
-and the reloaded target would be non-functional.
+allow_discards
+	Allow block discard requests (a.k.a. TRIM) for the integrity device.
+	Discards are only allowed to devices using internal hash.
+
+The journal mode (D/J), buffer_sectors, journal_watermark, commit_time and
+allow_discards can be changed when reloading the target (load an inactive
+table and swap the tables with suspend and resume). The other arguments
+should not be changed when reloading the target because the layout of disk
+data depend on them and the reloaded target would be non-functional.
 
 
 The layout of the formatted block device:
diff --git a/Documentation/admin-guide/index.rst b/Documentation/admin-guide/index.rst
index 5a6269fb8593..58c7f9fc2396 100644
--- a/Documentation/admin-guide/index.rst
+++ b/Documentation/admin-guide/index.rst
@@ -93,6 +93,7 @@ configure specific aspects of kernel behavior to your liking.
    lockup-watchdogs
    LSM/index
    md
+   media/index
    mm/index
    module-signing
    mono
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index f2a93c8679e8..83cdd68da2b4 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -458,7 +458,7 @@
 	bttv.card=	[HW,V4L] bttv (bt848 + bt878 based grabber cards)
 	bttv.radio=	Most important insmod options are available as
 			kernel args too.
-	bttv.pll=	See Documentation/media/v4l-drivers/bttv.rst
+	bttv.pll=	See Documentation/admin-guide/media/bttv.rst
 	bttv.tuner=
 
 	bulk_remove=off	[PPC]  This parameter disables the use of the pSeries
@@ -2705,7 +2705,7 @@
 			See Documentation/admin-guide/pm/sleep-states.rst.
 
 	meye.*=		[HW] Set MotionEye Camera parameters
-			See Documentation/media/v4l-drivers/meye.rst.
+			See Documentation/admin-guide/media/meye.rst.
 
 	mfgpt_irq=	[IA-32] Specify the IRQ to use for the
 			Multi-Function General Purpose Timers on AMD Geode
@@ -4210,12 +4210,24 @@
 			Duration of CPU stall (s) to test RCU CPU stall
 			warnings, zero to disable.
 
+	rcutorture.stall_cpu_block= [KNL]
+			Sleep while stalling if set.  This will result
+			in warnings from preemptible RCU in addition
+			to any other stall-related activity.
+
 	rcutorture.stall_cpu_holdoff= [KNL]
 			Time to wait (s) after boot before inducing stall.
 
 	rcutorture.stall_cpu_irqsoff= [KNL]
 			Disable interrupts while stalling if set.
 
+	rcutorture.stall_gp_kthread= [KNL]
+			Duration (s) of forced sleep within RCU
+			grace-period kthread to test RCU CPU stall
+			warnings, zero to disable.  If both stall_cpu
+			and stall_gp_kthread are specified, the
+			kthread is starved first, then the CPU.
+
 	rcutorture.stat_interval= [KNL]
 			Time (s) between statistics printk()s.
 
@@ -4286,6 +4298,13 @@
 			only normal grace-period primitives.  No effect
 			on CONFIG_TINY_RCU kernels.
 
+	rcupdate.rcu_task_ipi_delay= [KNL]
+			Set time in jiffies during which RCU tasks will
+			avoid sending IPIs, starting with the beginning
+			of a given grace period.  Setting a large
+			number avoids disturbing real-time workloads,
+			but lengthens grace periods.
+
 	rcupdate.rcu_task_stall_timeout= [KNL]
 			Set timeout in jiffies for RCU task stall warning
 			messages.  Disable with a value less than or equal
diff --git a/Documentation/admin-guide/media/au0828-cardlist.rst b/Documentation/admin-guide/media/au0828-cardlist.rst
new file mode 100644
index 000000000000..aaaadc934e7a
--- /dev/null
+++ b/Documentation/admin-guide/media/au0828-cardlist.rst
@@ -0,0 +1,39 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+AU0828 cards list
+=================
+
+.. tabularcolumns:: |p{1.4cm}|p{6.5cm}|p{10.0cm}|
+
+.. flat-table::
+   :header-rows: 1
+   :widths: 2 19 18
+   :stub-columns: 0
+
+   * - Card number
+     - Card name
+     - USB IDs
+
+   * - 0
+     - Unknown board
+     -
+
+   * - 1
+     - Hauppauge HVR950Q
+     - 2040:7200, 2040:7210, 2040:7217, 2040:721b, 2040:721e, 2040:721f, 2040:7280, 0fd9:0008, 2040:7260, 2040:7213, 2040:7270
+
+   * - 2
+     - Hauppauge HVR850
+     - 2040:7240
+
+   * - 3
+     - DViCO FusionHDTV USB
+     - 0fe9:d620
+
+   * - 4
+     - Hauppauge HVR950Q rev xxF8
+     - 2040:7201, 2040:7211, 2040:7281
+
+   * - 5
+     - Hauppauge Woodbury
+     - 05e1:0480, 2040:8200
diff --git a/Documentation/admin-guide/media/avermedia.rst b/Documentation/admin-guide/media/avermedia.rst
new file mode 100644
index 000000000000..93ff74002d20
--- /dev/null
+++ b/Documentation/admin-guide/media/avermedia.rst
@@ -0,0 +1,94 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+======================================
+Avermedia DVB-T on BT878 Release Notes
+======================================
+
+February 14th 2006
+
+.. note::
+
+   Several other Avermedia devices are supported. For a more
+   broader and updated content about that, please check:
+
+   https://linuxtv.org/wiki/index.php/AVerMedia
+
+The Avermedia DVB-T
+~~~~~~~~~~~~~~~~~~~
+
+The Avermedia DVB-T is a budget PCI DVB card. It has 3 inputs:
+
+* RF Tuner Input
+* Composite Video Input (RCA Jack)
+* SVIDEO Input (Mini-DIN)
+
+The  RF  Tuner  Input  is the input to the tuner module of the
+card.  The  Tuner  is  otherwise known as the "Frontend" . The
+Frontend of the Avermedia DVB-T is a Microtune 7202D. A timely
+post  to  the  linux-dvb  mailing  list  ascertained  that the
+Microtune  7202D  is  supported  by the sp887x driver which is
+found in the dvb-hw CVS module.
+
+The  DVB-T card is based around the BT878 chip which is a very
+common multimedia bridge and often found on Analogue TV cards.
+There is no on-board MPEG2 decoder, which means that all MPEG2
+decoding  must  be done in software, or if you have one, on an
+MPEG2 hardware decoding card or chipset.
+
+
+Getting the card going
+~~~~~~~~~~~~~~~~~~~~~~
+
+At  this  stage,  it  has  not  been  able  to  ascertain  the
+functionality  of the remaining device nodes in respect of the
+Avermedia  DVBT.  However,  full  functionality  in respect of
+tuning,  receiving  and  supplying  the  MPEG2  data stream is
+possible  with the currently available versions of the driver.
+It  may be possible that additional functionality is available
+from  the  card  (i.e.  viewing the additional analogue inputs
+that  the card presents), but this has not been tested yet. If
+I get around to this, I'll update the document with whatever I
+find.
+
+To  power  up  the  card,  load  the  following modules in the
+following order:
+
+* modprobe bttv (normally loaded automatically)
+* modprobe dvb-bt8xx (or place dvb-bt8xx in /etc/modules)
+
+Insertion  of  these  modules  into  the  running  kernel will
+activate the appropriate DVB device nodes. It is then possible
+to start accessing the card with utilities such as scan, tzap,
+dvbstream etc.
+
+The frontend module sp887x.o, requires an external   firmware.
+Please use  the  command "get_dvb_firmware sp887x" to download
+it. Then copy it to /usr/lib/hotplug/firmware or /lib/firmware/
+(depending on configuration of firmware hotplug).
+
+Known Limitations
+~~~~~~~~~~~~~~~~~
+
+At  present  I can say with confidence that the frontend tunes
+via /dev/dvb/adapter{x}/frontend0 and supplies an MPEG2 stream
+via   /dev/dvb/adapter{x}/dvr0.   I   have   not   tested  the
+functionality  of any other part of the card yet. I will do so
+over time and update this document.
+
+There  are some limitations in the i2c layer due to a returned
+error message inconsistency. Although this generates errors in
+dmesg  and  the  system logs, it does not appear to affect the
+ability of the frontend to function correctly.
+
+Further Update
+~~~~~~~~~~~~~~
+
+dvbstream  and  VideoLAN  Client on windows works a treat with
+DVB,  in  fact  this  is  currently  serving as my main way of
+viewing  DVB-T  at  the  moment.  Additionally, VLC is happily
+decoding  HDTV  signals,  although  the PC is dropping the odd
+frame here and there - I assume due to processing capability -
+as all the decoding is being done under windows in software.
+
+Many  thanks to Nigel Pearson for the updates to this document
+since the recent revision of the driver.
diff --git a/Documentation/admin-guide/media/bt8xx.rst b/Documentation/admin-guide/media/bt8xx.rst
new file mode 100644
index 000000000000..a55f4f5af042
--- /dev/null
+++ b/Documentation/admin-guide/media/bt8xx.rst
@@ -0,0 +1,156 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+==================================
+How to get the bt8xx cards working
+==================================
+
+Authors:
+	 Richard Walker,
+	 Jamie Honan,
+	 Michael Hunold,
+	 Manu Abraham,
+	 Uwe Bugla,
+	 Michael Krufky
+
+General information
+-------------------
+
+This class of cards has a bt878a as the PCI interface, and require the bttv driver
+for accessing the i2c bus and the gpio pins of the bt8xx chipset.
+
+Please see :doc:`cards` for a complete list of Cards based on the
+Conexant Bt8xx PCI bridge supported by the Linux Kernel.
+
+In order to be able to compile the kernel, some config options should be
+enabled::
+
+    ./scripts/config -e PCI
+    ./scripts/config -e INPUT
+    ./scripts/config -m I2C
+    ./scripts/config -m MEDIA_SUPPORT
+    ./scripts/config -e MEDIA_PCI_SUPPORT
+    ./scripts/config -e MEDIA_ANALOG_TV_SUPPORT
+    ./scripts/config -e MEDIA_DIGITAL_TV_SUPPORT
+    ./scripts/config -e MEDIA_RADIO_SUPPORT
+    ./scripts/config -e RC_CORE
+    ./scripts/config -m VIDEO_BT848
+    ./scripts/config -m DVB_BT8XX
+
+If you want to automatically support all possible variants of the Bt8xx
+cards, you should also do::
+
+    ./scripts/config -e MEDIA_SUBDRV_AUTOSELECT
+
+.. note::
+
+   Please use the following options with care as deselection of drivers which
+   are in fact necessary may result in DVB devices that cannot be tuned due
+   to lack of driver support.
+
+If your goal is to just support an specific board, you may, instead,
+disable MEDIA_SUBDRV_AUTOSELECT and manually select the frontend drivers
+required by your board. With that, you can save some RAM.
+
+You can do that by calling make xconfig/qconfig/menuconfig and look at
+the options on those menu options (only enabled if
+``Autoselect ancillary drivers`` is disabled:
+
+#) ``Device drivers`` => ``Multimedia support`` => ``Customize TV tuners``
+#) ``Device drivers`` => ``Multimedia support`` => ``Customize DVB frontends``
+
+Then, on each of the above menu, please select your card-specific
+frontend and tuner modules.
+
+
+Loading Modules
+---------------
+
+Regular case: If the bttv driver detects a bt8xx-based DVB card, all
+frontend and backend modules will be loaded automatically.
+
+Exceptions are:
+
+- Old TV cards without EEPROMs, sharing a common PCI ID;
+- Old TwinHan DST cards or clones with or without CA slot and not
+  containing an Eeprom.
+
+In the following cases overriding the PCI type detection for bttv and
+for dvb-bt8xx drivers by passing modprobe parameters may be necessary.
+
+Running TwinHan and Clones
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+As shown at :doc:`bttv-cardlist`, TwinHan and
+clones use ``card=113`` modprobe parameter. So, in order to properly
+detect it for devices without EEPROM, you should use::
+
+	$ modprobe bttv card=113
+	$ modprobe dst
+
+Useful parameters for verbosity level and debugging the dst module::
+
+	verbose=0:		messages are disabled
+		1:		only error messages are displayed
+		2:		notifications are displayed
+		3:		other useful messages are displayed
+		4:		debug setting
+	dst_addons=0:		card is a free to air (FTA) card only
+		0x20:	card has a conditional access slot for scrambled channels
+	dst_algo=0:		(default) Software tuning algorithm
+	         1:		Hardware tuning algorithm
+
+
+The autodetected values are determined by the cards' "response string".
+
+In your logs see f. ex.: dst_get_device_id: Recognize [DSTMCI].
+
+For bug reports please send in a complete log with verbose=4 activated.
+Please also see :doc:`ci`.
+
+Running multiple cards
+~~~~~~~~~~~~~~~~~~~~~~
+
+See :doc:`bttv-cardlist` for a complete list of
+Card ID. Some examples:
+
+	===========================	===
+	Brand name			ID
+	===========================	===
+	Pinnacle PCTV Sat		 94
+	Nebula Electronics Digi TV	104
+	pcHDTV HD-2000 TV		112
+	Twinhan DST and clones		113
+	Avermedia AverTV DVB-T 77:	123
+	Avermedia AverTV DVB-T 761	124
+	DViCO FusionHDTV DVB-T Lite	128
+	DViCO FusionHDTV 5 Lite		135
+	===========================	===
+
+.. note::
+
+   When you have multiple cards, the order of the card ID should
+   match the order where they're detected by the system. Please notice
+   that removing/inserting other PCI cards may change the detection
+   order.
+
+Example::
+
+	$ modprobe bttv card=113 card=135
+
+In case of further problems please subscribe and send questions to
+the mailing list: linux-media@vger.kernel.org.
+
+Probing the cards with broken PCI subsystem ID
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+There are some TwinHan cards whose EEPROM has become corrupted for some
+reason. The cards do not have a correct PCI subsystem ID.
+Still, it is possible to force probing the cards with::
+
+	$ echo 109e 0878 $subvendor $subdevice > \
+		/sys/bus/pci/drivers/bt878/new_id
+
+The two numbers there are::
+
+	109e: PCI_VENDOR_ID_BROOKTREE
+	0878: PCI_DEVICE_ID_BROOKTREE_878
diff --git a/Documentation/admin-guide/media/bttv-cardlist.rst b/Documentation/admin-guide/media/bttv-cardlist.rst
new file mode 100644
index 000000000000..f5806856b5a1
--- /dev/null
+++ b/Documentation/admin-guide/media/bttv-cardlist.rst
@@ -0,0 +1,683 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+BTTV cards list
+===============
+
+.. tabularcolumns:: |p{1.4cm}|p{11.1cm}|p{4.2cm}|
+
+.. flat-table::
+   :header-rows: 1
+   :widths: 2 19 18
+   :stub-columns: 0
+
+   * - Card number
+     - Card name
+     - PCI IDs
+
+   * - 0
+     -  *** UNKNOWN/GENERIC ***
+     -
+
+   * - 1
+     - MIRO PCTV
+     -
+
+   * - 2
+     - Hauppauge (bt848)
+     -
+
+   * - 3
+     - STB, Gateway P/N 6000699 (bt848)
+     -
+
+   * - 4
+     - Intel Create and Share PCI/ Smart Video Recorder III
+     -
+
+   * - 5
+     - Diamond DTV2000
+     -
+
+   * - 6
+     - AVerMedia TVPhone
+     -
+
+   * - 7
+     - MATRIX-Vision MV-Delta
+     -
+
+   * - 8
+     - Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26
+     -
+
+   * - 9
+     - IMS/IXmicro TurboTV
+     -
+
+   * - 10
+     - Hauppauge (bt878)
+     - 0070:13eb, 0070:3900, 2636:10b4
+
+   * - 11
+     - MIRO PCTV pro
+     -
+
+   * - 12
+     - ADS Technologies Channel Surfer TV (bt848)
+     -
+
+   * - 13
+     - AVerMedia TVCapture 98
+     - 1461:0002, 1461:0004, 1461:0300
+
+   * - 14
+     - Aimslab Video Highway Xtreme (VHX)
+     -
+
+   * - 15
+     - Zoltrix TV-Max
+     - a1a0:a0fc
+
+   * - 16
+     - Prolink Pixelview PlayTV (bt878)
+     -
+
+   * - 17
+     - Leadtek WinView 601
+     -
+
+   * - 18
+     - AVEC Intercapture
+     -
+
+   * - 19
+     - Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)
+     -
+
+   * - 20
+     - CEI Raffles Card
+     -
+
+   * - 21
+     - Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50
+     -
+
+   * - 22
+     - Askey CPH050/ Phoebe Tv Master + FM
+     - 14ff:3002
+
+   * - 23
+     - Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878
+     - 14c7:0101
+
+   * - 24
+     - Askey CPH05X/06X (bt878) [many vendors]
+     - 144f:3002, 144f:3005, 144f:5000, 14ff:3000
+
+   * - 25
+     - Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar
+     -
+
+   * - 26
+     - Hauppauge WinCam newer (bt878)
+     -
+
+   * - 27
+     - Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50
+     -
+
+   * - 28
+     - Terratec TerraTV+ Version 1.1 (bt878)
+     - 153b:1127, 1852:1852
+
+   * - 29
+     - Imagenation PXC200
+     - 1295:200a
+
+   * - 30
+     - Lifeview FlyVideo 98 LR50
+     - 1f7f:1850
+
+   * - 31
+     - Formac iProTV, Formac ProTV I (bt848)
+     -
+
+   * - 32
+     - Intel Create and Share PCI/ Smart Video Recorder III
+     -
+
+   * - 33
+     - Terratec TerraTValue Version Bt878
+     - 153b:1117, 153b:1118, 153b:1119, 153b:111a, 153b:1134, 153b:5018
+
+   * - 34
+     - Leadtek WinFast 2000/ WinFast 2000 XP
+     - 107d:6606, 107d:6609, 6606:217d, f6ff:fff6
+
+   * - 35
+     - Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II
+     - 1851:1850, 1851:a050
+
+   * - 36
+     - Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner
+     - 1852:1852
+
+   * - 37
+     - Prolink PixelView PlayTV pro
+     -
+
+   * - 38
+     - Askey CPH06X TView99
+     - 144f:3000, 144f:a005, a04f:a0fc
+
+   * - 39
+     - Pinnacle PCTV Studio/Rave
+     - 11bd:0012, bd11:1200, bd11:ff00, 11bd:ff12
+
+   * - 40
+     - STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100
+     - 10b4:2636, 10b4:2645, 121a:3060
+
+   * - 41
+     - AVerMedia TVPhone 98
+     - 1461:0001, 1461:0003
+
+   * - 42
+     - ProVideo PV951
+     - aa0c:146c
+
+   * - 43
+     - Little OnAir TV
+     -
+
+   * - 44
+     - Sigma TVII-FM
+     -
+
+   * - 45
+     - MATRIX-Vision MV-Delta 2
+     -
+
+   * - 46
+     - Zoltrix Genie TV/FM
+     - 15b0:4000, 15b0:400a, 15b0:400d, 15b0:4010, 15b0:4016
+
+   * - 47
+     - Terratec TV/Radio+
+     - 153b:1123
+
+   * - 48
+     - Askey CPH03x/ Dynalink Magic TView
+     -
+
+   * - 49
+     - IODATA GV-BCTV3/PCI
+     - 10fc:4020
+
+   * - 50
+     - Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP
+     -
+
+   * - 51
+     - Eagle Wireless Capricorn2 (bt878A)
+     -
+
+   * - 52
+     - Pinnacle PCTV Studio Pro
+     -
+
+   * - 53
+     - Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS
+     -
+
+   * - 54
+     - Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90]
+     -
+
+   * - 55
+     - Askey CPH031/ BESTBUY Easy TV
+     -
+
+   * - 56
+     - Lifeview FlyVideo 98FM LR50
+     - a051:41a0
+
+   * - 57
+     - GrandTec 'Grand Video Capture' (Bt848)
+     - 4344:4142
+
+   * - 58
+     - Askey CPH060/ Phoebe TV Master Only (No FM)
+     -
+
+   * - 59
+     - Askey CPH03x TV Capturer
+     -
+
+   * - 60
+     - Modular Technology MM100PCTV
+     -
+
+   * - 61
+     - AG Electronics GMV1
+     - 15cb:0101
+
+   * - 62
+     - Askey CPH061/ BESTBUY Easy TV (bt878)
+     -
+
+   * - 63
+     - ATI TV-Wonder
+     - 1002:0001
+
+   * - 64
+     - ATI TV-Wonder VE
+     - 1002:0003
+
+   * - 65
+     - Lifeview FlyVideo 2000S LR90
+     -
+
+   * - 66
+     - Terratec TValueRadio
+     - 153b:1135, 153b:ff3b
+
+   * - 67
+     - IODATA GV-BCTV4/PCI
+     - 10fc:4050
+
+   * - 68
+     - 3Dfx VoodooTV FM (Euro)
+     - 10b4:2637
+
+   * - 69
+     - Active Imaging AIMMS
+     -
+
+   * - 70
+     - Prolink Pixelview PV-BT878P+ (Rev.4C,8E)
+     -
+
+   * - 71
+     - Lifeview FlyVideo 98EZ (capture only) LR51
+     - 1851:1851
+
+   * - 72
+     - Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)
+     - 1554:4011
+
+   * - 73
+     - Sensoray 311/611
+     - 6000:0311, 6000:0611
+
+   * - 74
+     - RemoteVision MX (RV605)
+     -
+
+   * - 75
+     - Powercolor MTV878/ MTV878R/ MTV878F
+     -
+
+   * - 76
+     - Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)
+     - 0e11:0079
+
+   * - 77
+     - GrandTec Multi Capture Card (Bt878)
+     -
+
+   * - 78
+     - Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF
+     - 0a01:17de
+
+   * - 79
+     - DSP Design TCVIDEO
+     -
+
+   * - 80
+     - Hauppauge WinTV PVR
+     - 0070:4500
+
+   * - 81
+     - IODATA GV-BCTV5/PCI
+     - 10fc:4070, 10fc:d018
+
+   * - 82
+     - Osprey 100/150 (878)
+     - 0070:ff00
+
+   * - 83
+     - Osprey 100/150 (848)
+     -
+
+   * - 84
+     - Osprey 101 (848)
+     -
+
+   * - 85
+     - Osprey 101/151
+     -
+
+   * - 86
+     - Osprey 101/151 w/ svid
+     -
+
+   * - 87
+     - Osprey 200/201/250/251
+     -
+
+   * - 88
+     - Osprey 200/250
+     - 0070:ff01
+
+   * - 89
+     - Osprey 210/220/230
+     -
+
+   * - 90
+     - Osprey 500
+     - 0070:ff02
+
+   * - 91
+     - Osprey 540
+     - 0070:ff04
+
+   * - 92
+     - Osprey 2000
+     - 0070:ff03
+
+   * - 93
+     - IDS Eagle
+     -
+
+   * - 94
+     - Pinnacle PCTV Sat
+     - 11bd:001c
+
+   * - 95
+     - Formac ProTV II (bt878)
+     -
+
+   * - 96
+     - MachTV
+     -
+
+   * - 97
+     - Euresys Picolo
+     -
+
+   * - 98
+     - ProVideo PV150
+     - aa00:1460, aa01:1461, aa02:1462, aa03:1463, aa04:1464, aa05:1465, aa06:1466, aa07:1467
+
+   * - 99
+     - AD-TVK503
+     -
+
+   * - 100
+     - Hercules Smart TV Stereo
+     -
+
+   * - 101
+     - Pace TV & Radio Card
+     -
+
+   * - 102
+     - IVC-200
+     - 0000:a155, 0001:a155, 0002:a155, 0003:a155, 0100:a155, 0101:a155, 0102:a155, 0103:a155, 0800:a155, 0801:a155, 0802:a155, 0803:a155
+
+   * - 103
+     - Grand X-Guard / Trust 814PCI
+     - 0304:0102
+
+   * - 104
+     - Nebula Electronics DigiTV
+     - 0071:0101
+
+   * - 105
+     - ProVideo PV143
+     - aa00:1430, aa00:1431, aa00:1432, aa00:1433, aa03:1433
+
+   * - 106
+     - PHYTEC VD-009-X1 VD-011 MiniDIN (bt878)
+     -
+
+   * - 107
+     - PHYTEC VD-009-X1 VD-011 Combi (bt878)
+     -
+
+   * - 108
+     - PHYTEC VD-009 MiniDIN (bt878)
+     -
+
+   * - 109
+     - PHYTEC VD-009 Combi (bt878)
+     -
+
+   * - 110
+     - IVC-100
+     - ff00:a132
+
+   * - 111
+     - IVC-120G
+     - ff00:a182, ff01:a182, ff02:a182, ff03:a182, ff04:a182, ff05:a182, ff06:a182, ff07:a182, ff08:a182, ff09:a182, ff0a:a182, ff0b:a182, ff0c:a182, ff0d:a182, ff0e:a182, ff0f:a182
+
+   * - 112
+     - pcHDTV HD-2000 TV
+     - 7063:2000
+
+   * - 113
+     - Twinhan DST + clones
+     - 11bd:0026, 1822:0001, 270f:fc00, 1822:0026
+
+   * - 114
+     - Winfast VC100
+     - 107d:6607
+
+   * - 115
+     - Teppro TEV-560/InterVision IV-560
+     -
+
+   * - 116
+     - SIMUS GVC1100
+     - aa6a:82b2
+
+   * - 117
+     - NGS NGSTV+
+     -
+
+   * - 118
+     - LMLBT4
+     -
+
+   * - 119
+     - Tekram M205 PRO
+     -
+
+   * - 120
+     - Conceptronic CONTVFMi
+     -
+
+   * - 121
+     - Euresys Picolo Tetra
+     - 1805:0105, 1805:0106, 1805:0107, 1805:0108
+
+   * - 122
+     - Spirit TV Tuner
+     -
+
+   * - 123
+     - AVerMedia AVerTV DVB-T 771
+     - 1461:0771
+
+   * - 124
+     - AverMedia AverTV DVB-T 761
+     - 1461:0761
+
+   * - 125
+     - MATRIX Vision Sigma-SQ
+     -
+
+   * - 126
+     - MATRIX Vision Sigma-SLC
+     -
+
+   * - 127
+     - APAC Viewcomp 878(AMAX)
+     -
+
+   * - 128
+     - DViCO FusionHDTV DVB-T Lite
+     - 18ac:db10, 18ac:db11
+
+   * - 129
+     - V-Gear MyVCD
+     -
+
+   * - 130
+     - Super TV Tuner
+     -
+
+   * - 131
+     - Tibet Systems 'Progress DVR' CS16
+     -
+
+   * - 132
+     - Kodicom 4400R (master)
+     -
+
+   * - 133
+     - Kodicom 4400R (slave)
+     -
+
+   * - 134
+     - Adlink RTV24
+     -
+
+   * - 135
+     - DViCO FusionHDTV 5 Lite
+     - 18ac:d500
+
+   * - 136
+     - Acorp Y878F
+     - 9511:1540
+
+   * - 137
+     - Conceptronic CTVFMi v2
+     - 036e:109e
+
+   * - 138
+     - Prolink Pixelview PV-BT878P+ (Rev.2E)
+     -
+
+   * - 139
+     - Prolink PixelView PlayTV MPEG2 PV-M4900
+     -
+
+   * - 140
+     - Osprey 440
+     - 0070:ff07
+
+   * - 141
+     - Asound Skyeye PCTV
+     -
+
+   * - 142
+     - Sabrent TV-FM (bttv version)
+     -
+
+   * - 143
+     - Hauppauge ImpactVCB (bt878)
+     - 0070:13eb
+
+   * - 144
+     - MagicTV
+     -
+
+   * - 145
+     - SSAI Security Video Interface
+     - 4149:5353
+
+   * - 146
+     - SSAI Ultrasound Video Interface
+     - 414a:5353
+
+   * - 147
+     - VoodooTV 200 (USA)
+     - 121a:3000
+
+   * - 148
+     - DViCO FusionHDTV 2
+     - dbc0:d200
+
+   * - 149
+     - Typhoon TV-Tuner PCI (50684)
+     -
+
+   * - 150
+     - Geovision GV-600
+     - 008a:763c
+
+   * - 151
+     - Kozumi KTV-01C
+     -
+
+   * - 152
+     - Encore ENL TV-FM-2
+     - 1000:1801
+
+   * - 153
+     - PHYTEC VD-012 (bt878)
+     -
+
+   * - 154
+     - PHYTEC VD-012-X1 (bt878)
+     -
+
+   * - 155
+     - PHYTEC VD-012-X2 (bt878)
+     -
+
+   * - 156
+     - IVCE-8784
+     - 0000:f050, 0001:f050, 0002:f050, 0003:f050
+
+   * - 157
+     - Geovision GV-800(S) (master)
+     - 800a:763d
+
+   * - 158
+     - Geovision GV-800(S) (slave)
+     - 800b:763d, 800c:763d, 800d:763d
+
+   * - 159
+     - ProVideo PV183
+     - 1830:1540, 1831:1540, 1832:1540, 1833:1540, 1834:1540, 1835:1540, 1836:1540, 1837:1540
+
+   * - 160
+     - Tongwei Video Technology TD-3116
+     - f200:3116
+
+   * - 161
+     - Aposonic W-DVR
+     - 0279:0228
+
+   * - 162
+     - Adlink MPG24
+     -
+
+   * - 163
+     - Bt848 Capture 14MHz
+     -
+
+   * - 164
+     - CyberVision CV06 (SV)
+     -
+
+   * - 165
+     - Kworld V-Stream Xpert TV PVR878
+     -
+
+   * - 166
+     - PCI-8604PW
+     -
diff --git a/Documentation/admin-guide/media/bttv.rst b/Documentation/admin-guide/media/bttv.rst
new file mode 100644
index 000000000000..49382377b1dc
--- /dev/null
+++ b/Documentation/admin-guide/media/bttv.rst
@@ -0,0 +1,1761 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+===============
+The bttv driver
+===============
+
+Release notes for bttv
+----------------------
+
+You'll need at least these config options for bttv::
+
+    ./scripts/config -e PCI
+    ./scripts/config -m I2C
+    ./scripts/config -m INPUT
+    ./scripts/config -m MEDIA_SUPPORT
+    ./scripts/config -e MEDIA_PCI_SUPPORT
+    ./scripts/config -e MEDIA_ANALOG_TV_SUPPORT
+    ./scripts/config -e MEDIA_DIGITAL_TV_SUPPORT
+    ./scripts/config -e MEDIA_RADIO_SUPPORT
+    ./scripts/config -e RC_CORE
+    ./scripts/config -m VIDEO_BT848
+
+If your board has digital TV, you'll also need::
+
+    ./scripts/config -m DVB_BT8XX
+
+In this case, please see :doc:`bt8xx` for additional notes.
+
+Make bttv work with your card
+-----------------------------
+
+If you have bttv compiled and installed, just booting the Kernel
+should be enough for it to try probing it. However, depending
+on the model, the Kernel may require additional information about
+the hardware, as the device may not be able to provide such info
+directly to the Kernel.
+
+If it doesn't bttv likely could not autodetect your card and needs some
+insmod options.  The most important insmod option for bttv is "card=n"
+to select the correct card type.  If you get video but no sound you've
+very likely specified the wrong (or no) card type.  A list of supported
+cards is in :doc:`bttv-cardlist`.
+
+If bttv takes very long to load (happens sometimes with the cheap
+cards which have no tuner), try adding this to your modules configuration
+file (usually, it is either ``/etc/modules.conf`` or some file at
+``/etc/modules-load.d/``, but the actual place depends on your
+distribution)::
+
+	options i2c-algo-bit bit_test=1
+
+Some cards may require an extra firmware file to work. For example,
+for the WinTV/PVR you need one firmware file from its driver CD,
+called: ``hcwamc.rbf``. It is inside a self-extracting zip file
+called ``pvr45xxx.exe``.  Just placing it at the ``/etc/firmware``
+directory should be enough for it to be autoload during the driver's
+probing mode (e. g. when the Kernel boots or when the driver is
+manually loaded via ``modprobe`` command).
+
+If your card isn't listed in :doc:`bttv-cardlist` or if you have
+trouble making audio work, please read :ref:`still_doesnt_work`.
+
+
+Autodetecting cards
+-------------------
+
+bttv uses the PCI Subsystem ID to autodetect the card type.  lspci lists
+the Subsystem ID in the second line, looks like this:
+
+.. code-block:: none
+
+	00:0a.0 Multimedia video controller: Brooktree Corporation Bt878 (rev 02)
+		Subsystem: Hauppauge computer works Inc. WinTV/GO
+		Flags: bus master, medium devsel, latency 32, IRQ 5
+		Memory at e2000000 (32-bit, prefetchable) [size=4K]
+
+only bt878-based cards can have a subsystem ID (which does not mean
+that every card really has one).  bt848 cards can't have a Subsystem
+ID and therefore can't be autodetected.  There is a list with the ID's
+at :doc:`bttv-cardlist` (in case you are intrested or want to mail
+patches with updates).
+
+
+.. _still_doesnt_work:
+
+Still doesn't work?
+-------------------
+
+I do NOT have a lab with 30+ different grabber boards and a
+PAL/NTSC/SECAM test signal generator at home, so I often can't
+reproduce your problems.  This makes debugging very difficult for me.
+
+If you have some knowledge and spare time, please try to fix this
+yourself (patches very welcome of course...)  You know: The linux
+slogan is "Do it yourself".
+
+There is a mailing list at
+http://vger.kernel.org/vger-lists.html#linux-media
+
+If you have trouble with some specific TV card, try to ask there
+instead of mailing me directly.  The chance that someone with the
+same card listens there is much higher...
+
+For problems with sound:  There are a lot of different systems used
+for TV sound all over the world.  And there are also different chips
+which decode the audio signal.  Reports about sound problems ("stereo
+doesn't work") are pretty useless unless you include some details
+about your hardware and the TV sound scheme used in your country (or
+at least the country you are living in).
+
+Modprobe options
+----------------
+
+.. note::
+
+
+   The following argument list can be outdated, as we might add more
+   options if ever needed. In case of doubt, please check with
+   ``modinfo <module>``.
+
+   This command prints various information about a kernel
+   module, among them a complete and up-to-date list of insmod options.
+
+
+
+bttv
+	The bt848/878 (grabber chip) driver
+
+    insmod args::
+
+	    card=n		card type, see CARDLIST for a list.
+	    tuner=n		tuner type, see CARDLIST for a list.
+	    radio=0/1	card supports radio
+	    pll=0/1/2	pll settings
+
+			    0: don't use PLL
+			    1: 28 MHz crystal installed
+			    2: 35 MHz crystal installed
+
+	    triton1=0/1     for Triton1 (+others) compatibility
+	    vsfx=0/1	yet another chipset bug compatibility bit
+			    see README.quirks for details on these two.
+
+	    bigendian=n	Set the endianness of the gfx framebuffer.
+			    Default is native endian.
+	    fieldnr=0/1	Count fields.  Some TV descrambling software
+			    needs this, for others it only generates
+			    50 useless IRQs/sec.  default is 0 (off).
+	    autoload=0/1	autoload helper modules (tuner, audio).
+			    default is 1 (on).
+	    bttv_verbose=0/1/2  verbose level (at insmod time, while
+			    looking at the hardware).  default is 1.
+	    bttv_debug=0/1	debug messages (for capture).
+			    default is 0 (off).
+	    irq_debug=0/1	irq handler debug messages.
+			    default is 0 (off).
+	    gbuffers=2-32	number of capture buffers for mmap'ed capture.
+			    default is 4.
+	    gbufsize=	size of capture buffers. default and
+			    maximum value is 0x208000 (~2MB)
+	    no_overlay=0	Enable overlay on broken hardware.  There
+			    are some chipsets (SIS for example) which
+			    are known to have problems with the PCI DMA
+			    push used by bttv.  bttv will disable overlay
+			    by default on this hardware to avoid crashes.
+			    With this insmod option you can override this.
+	    no_overlay=1	Disable overlay. It should be used by broken
+			    hardware that doesn't support PCI2PCI direct
+			    transfers.
+	    automute=0/1	Automatically mutes the sound if there is
+			    no TV signal, on by default.  You might try
+			    to disable this if you have bad input signal
+			    quality which leading to unwanted sound
+			    dropouts.
+	    chroma_agc=0/1	AGC of chroma signal, off by default.
+	    adc_crush=0/1	Luminance ADC crush, on by default.
+	    i2c_udelay=     Allow reduce I2C speed. Default is 5 usecs
+			    (meaning 66,67 Kbps). The default is the
+			    maximum supported speed by kernel bitbang
+			    algorithm. You may use lower numbers, if I2C
+			    messages are lost (16 is known to work on
+			    all supported cards).
+
+	    bttv_gpio=0/1
+	    gpiomask=
+	    audioall=
+	    audiomux=
+			    See Sound-FAQ for a detailed description.
+
+	remap, card, radio and pll accept up to four comma-separated arguments
+	(for multiple boards).
+
+tuner
+	The tuner driver.  You need this unless you want to use only
+	with a camera or the board doesn't provide analog TV tuning.
+
+	insmod args::
+
+		debug=1		print some debug info to the syslog
+		type=n		type of the tuner chip. n as follows:
+				see CARDLIST for a complete list.
+		pal=[bdgil]	select PAL variant (used for some tuners
+				only, important for the audio carrier).
+
+tvaudio
+	Provide a single driver for all simple i2c audio control
+	chips (tda/tea*).
+
+	insmod args::
+
+		tda8425  = 1	enable/disable the support for the
+		tda9840  = 1	various chips.
+		tda9850  = 1	The tea6300 can't be autodetected and is
+		tda9855  = 1	therefore off by default, if you have
+		tda9873  = 1	this one on your card (STB uses these)
+		tda9874a = 1	you have to enable it explicitly.
+		tea6300  = 0	The two tda985x chips use the same i2c
+		tea6420  = 1	address and can't be disturgished from
+		pic16c54 = 1	each other, you might have to disable
+				the wrong one.
+		debug = 1	print debug messages
+
+msp3400
+	The driver for the msp34xx sound processor chips. If you have a
+	stereo card, you probably want to insmod this one.
+
+	insmod args::
+
+		debug=1/2	print some debug info to the syslog,
+				2 is more verbose.
+		simple=1	Use the "short programming" method.  Newer
+				msp34xx versions support this.  You need this
+				for dbx stereo.  Default is on if supported by
+				the chip.
+		once=1		Don't check the TV-stations Audio mode
+				every few seconds, but only once after
+				channel switches.
+		amsound=1	Audio carrier is AM/NICAM at 6.5 Mhz.  This
+				should improve things for french people, the
+				carrier autoscan seems to work with FM only...
+
+If the box freezes hard with bttv
+---------------------------------
+
+It might be a bttv driver bug.  It also might be bad hardware.  It also
+might be something else ...
+
+Just mailing me "bttv freezes" isn't going to help much.  This README
+has a few hints how you can help to pin down the problem.
+
+
+bttv bugs
+~~~~~~~~~
+
+If some version works and another doesn't it is likely to be a driver
+bug.  It is very helpful if you can tell where exactly it broke
+(i.e. the last working and the first broken version).
+
+With a hard freeze you probably doesn't find anything in the logfiles.
+The only way to capture any kernel messages is to hook up a serial
+console and let some terminal application log the messages.  /me uses
+screen.  See :doc:`/admin-guide/serial-console` for details on setting
+up a serial console.
+
+Read :doc:`/admin-guide/bug-hunting` to learn how to get any useful
+information out of a register+stack dump printed by the kernel on
+protection faults (so-called "kernel oops").
+
+If you run into some kind of deadlock, you can try to dump a call trace
+for each process using sysrq-t (see :doc:`/admin-guide/sysrq`).
+This way it is possible to figure where *exactly* some process in "D"
+state is stuck.
+
+I've seen reports that bttv 0.7.x crashes whereas 0.8.x works rock solid
+for some people.  Thus probably a small buglet left somewhere in bttv
+0.7.x.  I have no idea where exactly, it works stable for me and a lot of
+other people.  But in case you have problems with the 0.7.x versions you
+can give 0.8.x a try ...
+
+
+hardware bugs
+~~~~~~~~~~~~~
+
+Some hardware can't deal with PCI-PCI transfers (i.e. grabber => vga).
+Sometimes problems show up with bttv just because of the high load on
+the PCI bus. The bt848/878 chips have a few workarounds for known
+incompatibilities, see README.quirks.
+
+Some folks report that increasing the pci latency helps too,
+althrought I'm not sure whenever this really fixes the problems or
+only makes it less likely to happen.  Both bttv and btaudio have a
+insmod option to set the PCI latency of the device.
+
+Some mainboard have problems to deal correctly with multiple devices
+doing DMA at the same time.  bttv + ide seems to cause this sometimes,
+if this is the case you likely see freezes only with video and hard disk
+access at the same time.  Updating the IDE driver to get the latest and
+greatest workarounds for hardware bugs might fix these problems.
+
+
+other
+~~~~~
+
+If you use some binary-only yunk (like nvidia module) try to reproduce
+the problem without.
+
+IRQ sharing is known to cause problems in some cases.  It works just
+fine in theory and many configurations.  Neverless it might be worth a
+try to shuffle around the PCI cards to give bttv another IRQ or make
+it share the IRQ with some other piece of hardware.  IRQ sharing with
+VGA cards seems to cause trouble sometimes.  I've also seen funny
+effects with bttv sharing the IRQ with the ACPI bridge (and
+apci-enabled kernel).
+
+Bttv quirks
+-----------
+
+Below is what the bt878 data book says about the PCI bug compatibility
+modes of the bt878 chip.
+
+The triton1 insmod option sets the EN_TBFX bit in the control register.
+The vsfx insmod option does the same for EN_VSFX bit.  If you have
+stability problems you can try if one of these options makes your box
+work solid.
+
+drivers/pci/quirks.c knows about these issues, this way these bits are
+enabled automagically for known-buggy chipsets (look at the kernel
+messages, bttv tells you).
+
+Normal PCI Mode
+~~~~~~~~~~~~~~~
+
+The PCI REQ signal is the logical-or of the incoming function requests.
+The inter-nal GNT[0:1] signals are gated asynchronously with GNT and
+demultiplexed by the audio request signal. Thus the arbiter defaults to
+the video function at power-up and parks there during no requests for
+bus access. This is desirable since the video will request the bus more
+often. However, the audio will have highest bus access priority. Thus
+the audio will have first access to the bus even when issuing a request
+after the video request but before the PCI external arbiter has granted
+access to the Bt879. Neither function can preempt the other once on the
+bus. The duration to empty the entire video PCI FIFO onto the PCI bus is
+very short compared to the bus access latency the audio PCI FIFO can
+tolerate.
+
+
+430FX Compatibility Mode
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+When using the 430FX PCI, the following rules will ensure
+compatibility:
+
+ (1) Deassert REQ at the same time as asserting FRAME.
+ (2) Do not reassert REQ to request another bus transaction until after
+     finish-ing the previous transaction.
+
+Since the individual bus masters do not have direct control of REQ, a
+simple logical-or of video and audio requests would violate the rules.
+Thus, both the arbiter and the initiator contain 430FX compatibility
+mode logic. To enable 430FX mode, set the EN_TBFX bit as indicated in
+Device Control Register on page 104.
+
+When EN_TBFX is enabled, the arbiter ensures that the two compatibility
+rules are satisfied. Before GNT is asserted by the PCI arbiter, this
+internal arbiter may still logical-or the two requests. However, once
+the GNT is issued, this arbiter must lock in its decision and now route
+only the granted request to the REQ pin. The arbiter decision lock
+happens regardless of the state of FRAME because it does not know when
+FRAME will be asserted (typically - each initiator will assert FRAME on
+the cycle following GNT). When FRAME is asserted, it is the initiator s
+responsibility to remove its request at the same time. It is the
+arbiters responsibility to allow this request to flow through to REQ and
+not allow the other request to hold REQ asserted. The decision lock may
+be removed at the end of the transaction: for example, when the bus is
+idle (FRAME and IRDY). The arbiter decision may then continue
+asynchronously until GNT is again asserted.
+
+
+Interfacing with Non-PCI 2.1 Compliant Core Logic
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A small percentage of core logic devices may start a bus transaction
+during the same cycle that GNT is de-asserted. This is non PCI 2.1
+compliant. To ensure compatibility when using PCs with these PCI
+controllers, the EN_VSFX bit must be enabled (refer to Device Control
+Register on page 104). When in this mode, the arbiter does not pass GNT
+to the internal functions unless REQ is asserted. This prevents a bus
+transaction from starting the same cycle as GNT is de-asserted. This
+also has the side effect of not being able to take advantage of bus
+parking, thus lowering arbitration performance. The Bt879 drivers must
+query for these non-compliant devices, and set the EN_VSFX bit only if
+required.
+
+
+Other elements of the tvcards array
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you are trying to make a new card work you might find it useful to
+know what the other elements in the tvcards array are good for::
+
+	video_inputs    - # of video inputs the card has
+	audio_inputs    - historical cruft, not used any more.
+	tuner           - which input is the tuner
+	svhs            - which input is svhs (all others are labeled composite)
+	muxsel          - video mux, input->registervalue mapping
+	pll             - same as pll= insmod option
+	tuner_type      - same as tuner= insmod option
+	*_modulename    - hint whenever some card needs this or that audio
+			module loaded to work properly.
+	has_radio	- whenever this TV card has a radio tuner.
+	no_msp34xx	- "1" disables loading of msp3400.o module
+	no_tda9875	- "1" disables loading of tda9875.o module
+	needs_tvaudio	- set to "1" to load tvaudio.o module
+
+If some config item is specified both from the tvcards array and as
+insmod option, the insmod option takes precedence.
+
+Cards
+-----
+
+.. note::
+
+   For a more updated list, please check
+   https://linuxtv.org/wiki/index.php/Hardware_Device_Information
+
+Supported cards: Bt848/Bt848a/Bt849/Bt878/Bt879 cards
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+All cards with Bt848/Bt848a/Bt849/Bt878/Bt879 and normal
+Composite/S-VHS inputs are supported.  Teletext and Intercast support
+(PAL only) for ALL cards via VBI sample decoding in software.
+
+Some cards with additional multiplexing of inputs or other additional
+fancy chips are only partially supported (unless specifications by the
+card manufacturer are given).  When a card is listed here it isn't
+necessarily fully supported.
+
+All other cards only differ by additional components as tuners, sound
+decoders, EEPROMs, teletext decoders ...
+
+
+MATRIX Vision
+~~~~~~~~~~~~~
+
+MV-Delta
+- Bt848A
+- 4 Composite inputs, 1 S-VHS input (shared with 4th composite)
+- EEPROM
+
+http://www.matrix-vision.de/
+
+This card has no tuner but supports all 4 composite (1 shared with an
+S-VHS input) of the Bt848A.
+Very nice card if you only have satellite TV but several tuners connected
+to the card via composite.
+
+Many thanks to Matrix-Vision for giving us 2 cards for free which made
+Bt848a/Bt849 single crystal operation support possible!!!
+
+
+
+Miro/Pinnacle PCTV
+~~~~~~~~~~~~~~~~~~
+
+- Bt848
+  some (all??) come with 2 crystals for PAL/SECAM and NTSC
+- PAL, SECAM or NTSC TV tuner (Philips or TEMIC)
+- MSP34xx sound decoder on add on board
+  decoder is supported but AFAIK does not yet work
+  (other sound MUX setting in GPIO port needed??? somebody who fixed this???)
+- 1 tuner, 1 composite and 1 S-VHS input
+- tuner type is autodetected
+
+http://www.miro.de/
+http://www.miro.com/
+
+
+Many thanks for the free card which made first NTSC support possible back
+in 1997!
+
+
+Hauppauge Win/TV pci
+~~~~~~~~~~~~~~~~~~~~
+
+There are many different versions of the Hauppauge cards with different
+tuners (TV+Radio ...), teletext decoders.
+Note that even cards with same model numbers have (depending on the revision)
+different chips on it.
+
+- Bt848 (and others but always in 2 crystal operation???)
+  newer cards have a Bt878
+
+- PAL, SECAM, NTSC or tuner with or without Radio support
+
+e.g.:
+
+- PAL:
+
+  - TDA5737: VHF, hyperband and UHF mixer/oscillator for TV and VCR 3-band tuners
+  - TSA5522: 1.4 GHz I2C-bus controlled synthesizer, I2C 0xc2-0xc3
+
+- NTSC:
+
+  - TDA5731: VHF, hyperband and UHF mixer/oscillator for TV and VCR 3-band tuners
+  - TSA5518: no datasheet available on Philips site
+
+- Philips SAA5246 or SAA5284 ( or no) Teletext decoder chip
+  with buffer RAM (e.g. Winbond W24257AS-35: 32Kx8 CMOS static RAM)
+  SAA5246 (I2C 0x22) is supported
+
+- 256 bytes EEPROM: Microchip 24LC02B or Philips 8582E2Y
+  with configuration information
+  I2C address 0xa0 (24LC02B also responds to 0xa2-0xaf)
+
+- 1 tuner, 1 composite and (depending on model) 1 S-VHS input
+
+- 14052B: mux for selection of sound source
+
+- sound decoder: TDA9800, MSP34xx (stereo cards)
+
+
+Askey CPH-Series
+~~~~~~~~~~~~~~~~
+Developed by TelSignal(?), OEMed by many vendors (Typhoon, Anubis, Dynalink)
+
+- Card series:
+  - CPH01x: BT848 capture only
+  - CPH03x: BT848
+  - CPH05x: BT878 with FM
+  - CPH06x: BT878 (w/o FM)
+  - CPH07x: BT878 capture only
+
+- TV standards:
+  - CPH0x0: NTSC-M/M
+  - CPH0x1: PAL-B/G
+  - CPH0x2: PAL-I/I
+  - CPH0x3: PAL-D/K
+  - CPH0x4: SECAM-L/L
+  - CPH0x5: SECAM-B/G
+  - CPH0x6: SECAM-D/K
+  - CPH0x7: PAL-N/N
+  - CPH0x8: PAL-B/H
+  - CPH0x9: PAL-M/M
+
+- CPH03x was often sold as "TV capturer".
+
+Identifying:
+
+  #) 878 cards can be identified by PCI Subsystem-ID:
+     - 144f:3000 = CPH06x
+     - 144F:3002 = CPH05x w/ FM
+     - 144F:3005 = CPH06x_LC (w/o remote control)
+  #) The cards have a sticker with "CPH"-model on the back.
+  #) These cards have a number printed on the PCB just above the tuner metal box:
+     - "80-CP2000300-x" = CPH03X
+     - "80-CP2000500-x" = CPH05X
+     - "80-CP2000600-x" = CPH06X / CPH06x_LC
+
+  Askey sells these cards as "Magic TView series", Brand "MagicXpress".
+  Other OEM often call these "Tview", "TView99" or else.
+
+Lifeview Flyvideo Series:
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The naming of these series differs in time and space.
+
+Identifying:
+  #) Some models can be identified by PCI subsystem ID:
+
+     - 1852:1852 = Flyvideo 98 FM
+     - 1851:1850 = Flyvideo 98
+     - 1851:1851 = Flyvideo 98 EZ (capture only)
+
+  #) There is a print on the PCB:
+
+     - LR25       = Flyvideo (Zoran ZR36120, SAA7110A)
+     - LR26 Rev.N = Flyvideo II (Bt848)
+     - LR26 Rev.O = Flyvideo II (Bt878)
+     - LR37 Rev.C = Flyvideo EZ (Capture only, ZR36120 + SAA7110)
+     - LR38 Rev.A1= Flyvideo II EZ (Bt848 capture only)
+     - LR50 Rev.Q = Flyvideo 98 (w/eeprom and PCI subsystem ID)
+     - LR50 Rev.W = Flyvideo 98 (no eeprom)
+     - LR51 Rev.E = Flyvideo 98 EZ (capture only)
+     - LR90       = Flyvideo 2000 (Bt878)
+     - LR90 Flyvideo 2000S (Bt878) w/Stereo TV (Package incl. LR91 daughterboard)
+     - LR91       = Stereo daughter card for LR90
+     - LR97       = Flyvideo DVBS
+     - LR99 Rev.E = Low profile card for OEM integration (only internal audio!) bt878
+     - LR136	 = Flyvideo 2100/3100 (Low profile, SAA7130/SAA7134)
+     - LR137      = Flyvideo DV2000/DV3000 (SAA7130/SAA7134 + IEEE1394)
+     - LR138 Rev.C= Flyvideo 2000 (SAA7130)
+     - LR138 Flyvideo 3000 (SAA7134) w/Stereo TV
+
+	- These exist in variations w/FM and w/Remote sometimes denoted
+	  by suffixes "FM" and "R".
+
+  #) You have a laptop (miniPCI card):
+
+      - Product    = FlyTV Platinum Mini
+      - Model/Chip = LR212/saa7135
+
+      - Lifeview.com.tw states (Feb. 2002):
+        "The FlyVideo2000 and FlyVideo2000s product name have renamed to FlyVideo98."
+        Their Bt8x8 cards are listed as discontinued.
+      - Flyvideo 2000S was probably sold as Flyvideo 3000 in some countries(Europe?).
+        The new Flyvideo 2000/3000 are SAA7130/SAA7134 based.
+
+"Flyvideo II" had been the name for the 848 cards, nowadays (in Germany)
+this name is re-used for LR50 Rev.W.
+
+The Lifeview website mentioned Flyvideo III at some time, but such a card
+has not yet been seen (perhaps it was the german name for LR90 [stereo]).
+These cards are sold by many OEMs too.
+
+FlyVideo A2 (Elta 8680)= LR90 Rev.F (w/Remote, w/o FM, stereo TV by tda9821) {Germany}
+
+Lifeview 3000 (Elta 8681) as sold by Plus(April 2002), Germany = LR138 w/ saa7134
+
+lifeview config coding on gpio pins 0-9
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+- LR50 rev. Q ("PARTS: 7031505116), Tuner wurde als Nr. 5 erkannt, Eingänge
+  SVideo, TV, Composite, Audio, Remote:
+
+ - CP9..1=100001001 (1: 0-Ohm-Widerstand gegen GND unbestückt; 0: bestückt)
+
+
+Typhoon TV card series:
+~~~~~~~~~~~~~~~~~~~~~~~
+
+These can be CPH, Flyvideo, Pixelview or KNC1 series.
+
+Typhoon is the brand of Anubis.
+
+Model 50680 got re-used, some model no. had different contents over time.
+
+Models:
+
+  - 50680 "TV Tuner PCI Pal BG"(old,red package)=can be CPH03x(bt848) or CPH06x(bt878)
+  - 50680 "TV Tuner Pal BG" (blue package)= Pixelview PV-BT878P+ (Rev 9B)
+  - 50681 "TV Tuner PCI Pal I" (variant of 50680)
+  - 50682 "TView TV/FM Tuner Pal BG"       = Flyvideo 98FM (LR50 Rev.Q)
+
+  .. note::
+
+	 The package has a picture of CPH05x (which would be a real TView)
+
+  - 50683 "TV Tuner PCI SECAM" (variant of 50680)
+  - 50684 "TV Tuner Pal BG"                = Pixelview 878TV(Rev.3D)
+  - 50686 "TV Tuner"                       = KNC1 TV Station
+  - 50687 "TV Tuner stereo"                = KNC1 TV Station pro
+  - 50688 "TV Tuner RDS" (black package)   = KNC1 TV Station RDS
+  - 50689  TV SAT DVB-S CARD CI PCI (SAA7146AH, SU1278?) = "KNC1 TV Station DVB-S"
+  - 50692 "TV/FM Tuner" (small PCB)
+  - 50694  TV TUNER CARD RDS (PHILIPS CHIPSET SAA7134HL)
+  - 50696  TV TUNER STEREO (PHILIPS CHIPSET SAA7134HL, MK3ME Tuner)
+  - 50804  PC-SAT TV/Audio Karte = Techni-PC-Sat (ZORAN 36120PQC, Tuner:Alps)
+  - 50866  TVIEW SAT RECEIVER+ADR
+  - 50868 "TV/FM Tuner Pal I" (variant of 50682)
+  - 50999 "TV/FM Tuner Secam" (variant of 50682)
+
+Guillemot
+~~~~~~~~~
+
+Models:
+
+- Maxi-TV PCI (ZR36120)
+- Maxi TV Video 2 = LR50 Rev.Q (FI1216MF, PAL BG+SECAM)
+- Maxi TV Video 3 = CPH064 (PAL BG + SECAM)
+
+Mentor
+~~~~~~
+
+Mentor TV card ("55-878TV-U1") = Pixelview 878TV(Rev.3F) (w/FM w/Remote)
+
+Prolink
+~~~~~~~
+
+- TV cards:
+
+  - PixelView Play TV pro - (Model: PV-BT878P+ REV 8E)
+  - PixelView Play TV pro - (Model: PV-BT878P+ REV 9D)
+  - PixelView Play TV pro - (Model: PV-BT878P+ REV 4C / 8D / 10A )
+  - PixelView Play TV - (Model: PV-BT848P+)
+  - 878TV - (Model: PV-BT878TV)
+
+- Multimedia TV packages (card + software pack):
+
+  - PixelView Play TV Theater - (Model: PV-M4200) =  PixelView Play TV pro + Software
+  - PixelView Play TV PAK -     (Model: PV-BT878P+ REV 4E)
+  - PixelView Play TV/VCR -     (Model: PV-M3200 REV 4C / 8D / 10A )
+  - PixelView Studio PAK -      (Model:    M2200 REV 4C / 8D / 10A )
+  - PixelView PowerStudio PAK - (Model: PV-M3600 REV 4E)
+  - PixelView DigitalVCR PAK -  (Model: PV-M2400 REV 4C / 8D / 10A )
+  - PixelView PlayTV PAK II (TV/FM card + usb camera)  PV-M3800
+  - PixelView PlayTV XP PV-M4700,PV-M4700(w/FM)
+  - PixelView PlayTV DVR PV-M4600  package contents:PixelView PlayTV pro, windvr & videoMail s/w
+
+- Further Cards:
+
+  - PV-BT878P+rev.9B (Play TV Pro, opt. w/FM w/NICAM)
+  - PV-BT878P+rev.2F
+  - PV-BT878P Rev.1D (bt878, capture only)
+
+  - XCapture PV-CX881P (cx23881)
+  - PlayTV HD PV-CX881PL+, PV-CX881PL+(w/FM) (cx23881)
+
+  - DTV3000 PV-DTV3000P+ DVB-S CI = Twinhan VP-1030
+  - DTV2000 DVB-S = Twinhan VP-1020
+
+- Video Conferencing:
+
+  - PixelView Meeting PAK - (Model: PV-BT878P)
+  - PixelView Meeting PAK Lite - (Model: PV-BT878P)
+  - PixelView Meeting PAK plus - (Model: PV-BT878P+rev 4C/8D/10A)
+  - PixelView Capture - (Model: PV-BT848P)
+  - PixelView PlayTV USB pro
+  - Model No. PV-NT1004+, PV-NT1004+ (w/FM) = NT1004 USB decoder chip + SAA7113 video decoder chip
+
+Dynalink
+~~~~~~~~
+
+These are CPH series.
+
+Phoebemicro
+~~~~~~~~~~~
+
+- TV Master    = CPH030 or CPH060
+- TV Master FM = CPH050
+
+Genius/Kye
+~~~~~~~~~~
+
+- Video Wonder/Genius Internet Video Kit = LR37 Rev.C
+- Video Wonder Pro II (848 or 878) = LR26
+
+Tekram
+~~~~~~
+
+- VideoCap C205 (Bt848)
+- VideoCap C210 (zr36120 +Philips)
+- CaptureTV M200 (ISA)
+- CaptureTV M205 (Bt848)
+
+Lucky Star
+~~~~~~~~~~
+
+- Image World Conference TV = LR50 Rev. Q
+
+Leadtek
+~~~~~~~
+
+- WinView 601 (Bt848)
+- WinView 610 (Zoran)
+- WinFast2000
+- WinFast2000 XP
+
+Support for the Leadtek WinView 601 TV/FM
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Author of this section: Jon Tombs <jon@gte.esi.us.es>
+
+This card is basically the same as all the rest (Bt484A, Philips tuner),
+the main difference is that they have attached a programmable attenuator to 3
+GPIO lines in order to give some volume control. They have also stuck an
+infra-red remote control decoded on the board, I will add support for this
+when I get time (it simple generates an interrupt for each key press, with
+the key code is placed in the GPIO port).
+
+I don't yet have any application to test the radio support. The tuner
+frequency setting should work but it is possible that the audio multiplexer
+is wrong. If it doesn't work, send me email.
+
+
+- No Thanks to Leadtek they refused to answer any questions about their
+  hardware. The driver was written by visual inspection of the card. If you
+  use this driver, send an email insult to them, and tell them you won't
+  continue buying their hardware unless they support Linux.
+
+- Little thanks to Princeton Technology Corp (http://www.princeton.com.tw)
+  who make the audio attenuator. Their publicly available data-sheet available
+  on their web site doesn't include the chip programming information! Hidden
+  on their server are the full data-sheets, but don't ask how I found it.
+
+To use the driver I use the following options, the tuner and pll settings might
+be different in your country. You can force it via modprobe parameters.
+For example::
+
+    modprobe bttv  tuner=1 pll=28 radio=1 card=17
+
+Sets tuner type 1 (Philips PAL_I), PLL with a 28 MHz crystal, enables
+FM radio and selects bttv card ID 17 (Leadtek WinView 601).
+
+
+KNC One
+~~~~~~~
+
+- TV-Station
+- TV-Station SE (+Software Bundle)
+- TV-Station pro (+TV stereo)
+- TV-Station FM (+Radio)
+- TV-Station RDS (+RDS)
+- TV Station SAT (analog satellite)
+- TV-Station DVB-S
+
+.. note:: newer Cards have saa7134, but model name stayed the same?
+
+Provideo
+~~~~~~~~
+
+-  PV951 or PV-951, now named PV-951T
+   (also are sold as:
+   Boeder TV-FM Video Capture Card,
+   Titanmedia Supervision TV-2400,
+   Provideo PV951 TF,
+   3DeMon PV951,
+   MediaForte TV-Vision PV951,
+   Yoko PV951,
+   Vivanco Tuner Card PCI Art.-Nr.: 68404
+   )
+
+- Surveillance Series:
+
+ - PV-141
+ - PV-143
+ - PV-147
+ - PV-148 (capture only)
+ - PV-150
+ - PV-151
+
+- TV-FM Tuner Series:
+
+ - PV-951TDV (tv tuner + 1394)
+ - PV-951T/TF
+ - PV-951PT/TF
+ - PV-956T/TF Low Profile
+ - PV-911
+
+Highscreen
+~~~~~~~~~~
+
+Models:
+
+- TV Karte = LR50 Rev.S
+- TV-Boostar = Terratec Terra TV+ Version 1.0 (Bt848, tda9821) "ceb105.pcb"
+
+Zoltrix
+~~~~~~~
+
+Models:
+
+- Face to Face Capture (Bt848 capture only) (PCB "VP-2848")
+- Face To Face TV MAX (Bt848) (PCB "VP-8482 Rev1.3")
+- Genie TV (Bt878) (PCB "VP-8790 Rev 2.1")
+- Genie Wonder Pro
+
+AVerMedia
+~~~~~~~~~
+
+- AVer FunTV Lite (ISA, AV3001 chipset)  "M101.C"
+- AVerTV
+- AVerTV Stereo
+- AVerTV Studio (w/FM)
+- AVerMedia TV98 with Remote
+- AVerMedia TV/FM98 Stereo
+- AVerMedia TVCAM98
+- TVCapture (Bt848)
+- TVPhone (Bt848)
+- TVCapture98 (="AVerMedia TV98" in USA) (Bt878)
+- TVPhone98 (Bt878, w/FM)
+
+======== =========== =============== ======= ====== ======== =======================
+PCB      PCI-ID      Model-Name      Eeprom  Tuner  Sound    Country
+======== =========== =============== ======= ====== ======== =======================
+M101.C   ISA !
+M108-B      Bt848                     --     FR1236		 US   [#f2]_, [#f3]_
+M1A8-A      Bt848    AVer TV-Phone           FM1216  --
+M168-T   1461:0003   AVerTV Studio   48:17   FM1216 TDA9840T  D    [#f1]_ w/FM w/Remote
+M168-U   1461:0004   TVCapture98     40:11   FI1216   --      D    w/Remote
+M168II-B 1461:0003   Medion MD9592   48:16   FM1216 TDA9873H  D    w/FM
+======== =========== =============== ======= ====== ======== =======================
+
+.. [#f1] Daughterboard MB68-A with TDA9820T and TDA9840T
+.. [#f2] Sony NE41S soldered (stereo sound?)
+.. [#f3] Daughterboard M118-A w/ pic 16c54 and 4 MHz quartz
+
+- US site has different drivers for (as of 09/2002):
+
+  - EZ Capture/InterCam PCI (BT-848 chip)
+  - EZ Capture/InterCam PCI (BT-878 chip)
+  - TV-Phone (BT-848 chip)
+  - TV98 (BT-848 chip)
+  - TV98 With Remote (BT-848 chip)
+  - TV98 (BT-878 chip)
+  - TV98 With Remote (BT-878)
+  - TV/FM98 (BT-878 chip)
+  - AVerTV
+  - AverTV Stereo
+  - AVerTV Studio
+
+DE hat diverse Treiber fuer diese Modelle (Stand 09/2002):
+
+  - TVPhone (848) mit Philips tuner FR12X6 (w/ FM radio)
+  - TVPhone (848) mit Philips tuner FM12X6 (w/ FM radio)
+  - TVCapture (848) w/Philips tuner FI12X6
+  - TVCapture (848) non-Philips tuner
+  - TVCapture98 (Bt878)
+  - TVPhone98 (Bt878)
+  - AVerTV und TVCapture98 w/VCR (Bt 878)
+  - AVerTVStudio und TVPhone98 w/VCR (Bt878)
+  - AVerTV GO Serie (Kein SVideo Input)
+  - AVerTV98 (BT-878 chip)
+  - AVerTV98 mit Fernbedienung (BT-878 chip)
+  - AVerTV/FM98 (BT-878 chip)
+
+  - VDOmate (www.averm.com.cn) = M168U ?
+
+Aimslab
+~~~~~~~
+
+Models:
+
+- Video Highway or "Video Highway TR200" (ISA)
+- Video Highway Xtreme (aka "VHX") (Bt848, FM w/ TEA5757)
+
+IXMicro (former: IMS=Integrated Micro Solutions)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Models:
+
+- IXTV BT848 (=TurboTV)
+- IXTV BT878
+- IMS TurboTV (Bt848)
+
+Lifetec/Medion/Tevion/Aldi
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Models:
+
+- LT9306/MD9306 = CPH061
+- LT9415/MD9415 = LR90 Rev.F or Rev.G
+- MD9592 = Avermedia TVphone98 (PCI_ID=1461:0003), PCB-Rev=M168II-B (w/TDA9873H)
+- MD9717 = KNC One (Rev D4, saa7134, FM1216 MK2 tuner)
+- MD5044 = KNC One (Rev D4, saa7134, FM1216ME MK3 tuner)
+
+Modular Technologies (www.modulartech.com) UK
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Models:
+
+- MM100 PCTV (Bt848)
+- MM201 PCTV (Bt878, Bt832) w/ Quartzsight camera
+- MM202 PCTV (Bt878, Bt832, tda9874)
+- MM205 PCTV (Bt878)
+- MM210 PCTV (Bt878) (Galaxy TV, Galaxymedia ?)
+
+Terratec
+~~~~~~~~
+
+Models:
+
+- Terra TV+ Version 1.0 (Bt848), "ceb105.PCB" printed on the PCB, TDA9821
+- Terra TV+ Version 1.1 (Bt878), "LR74 Rev.E" printed on the PCB, TDA9821
+- Terra TValueRadio,             "LR102 Rev.C" printed on the PCB
+- Terra TV/Radio+ Version 1.0,   "80-CP2830100-0" TTTV3 printed on the PCB,
+  "CPH010-E83" on the back, SAA6588T, TDA9873H
+- Terra TValue Version BT878,    "80-CP2830110-0 TTTV4" printed on the PCB,
+  "CPH011-D83" on back
+- Terra TValue Version 1.0       "ceb105.PCB" (really identical to Terra TV+ Version 1.0)
+- Terra TValue New Revision	  "LR102 Rec.C"
+- Terra Active Radio Upgrade (tea5757h, saa6588t)
+
+- LR74 is a newer PCB revision of ceb105 (both incl. connector for Active Radio Upgrade)
+
+- Cinergy 400 (saa7134), "E877 11(S)", "PM820092D" printed on PCB
+- Cinergy 600 (saa7134)
+
+Technisat
+~~~~~~~~~
+
+Models:
+
+- Discos ADR PC-Karte ISA (no TV!)
+- Discos ADR PC-Karte PCI (probably no TV?)
+- Techni-PC-Sat (Sat. analog)
+  Rev 1.2 (zr36120, vpx3220, stv0030, saa5246, BSJE3-494A)
+- Mediafocus I (zr36120/zr36125, drp3510, Sat. analog + ADR Radio)
+- Mediafocus II (saa7146, Sat. analog)
+- SatADR Rev 2.1 (saa7146a, saa7113h, stv0056a, msp3400c, drp3510a, BSKE3-307A)
+- SkyStar 1 DVB  (AV7110) = Technotrend Premium
+- SkyStar 2 DVB  (B2C2) (=Sky2PC)
+
+Siemens
+~~~~~~~
+
+Multimedia eXtension Board (MXB) (SAA7146, SAA7111)
+
+Powercolor
+~~~~~~~~~~
+
+Models:
+
+- MTV878
+       Package comes with different contents:
+
+           a) pcb "MTV878" (CARD=75)
+           b) Pixelview Rev. 4\_
+
+- MTV878R w/Remote Control
+- MTV878F w/Remote Control w/FM radio
+
+Pinnacle
+~~~~~~~~
+
+PCTV models:
+
+- Mirovideo PCTV (Bt848)
+- Mirovideo PCTV SE (Bt848)
+- Mirovideo PCTV Pro (Bt848 + Daughterboard for TV Stereo and FM)
+- Studio PCTV Rave (Bt848 Version = Mirovideo PCTV)
+- Studio PCTV Rave (Bt878 package w/o infrared)
+- Studio PCTV      (Bt878)
+- Studio PCTV Pro  (Bt878 stereo w/ FM)
+- Pinnacle PCTV    (Bt878, MT2032)
+- Pinnacle PCTV Pro (Bt878, MT2032)
+- Pinncale PCTV Sat (bt878a, HM1821/1221) ["Conexant CX24110 with CX24108 tuner, aka HM1221/HM1811"]
+- Pinnacle PCTV Sat XE
+
+M(J)PEG capture and playback models:
+
+- DC1+ (ISA)
+- DC10  (zr36057,     zr36060,      saa7110, adv7176)
+- DC10+ (zr36067,     zr36060,      saa7110, adv7176)
+- DC20  (ql16x24b,zr36050, zr36016, saa7110, saa7187 ...)
+- DC30  (zr36057, zr36050, zr36016, vpx3220, adv7176, ad1843, tea6415, miro FST97A1)
+- DC30+ (zr36067, zr36050, zr36016, vpx3220, adv7176)
+- DC50  (zr36067, zr36050, zr36016, saa7112, adv7176 (2 pcs.?), ad1843, miro FST97A1, Lattice ???)
+
+Lenco
+~~~~~
+
+Models:
+
+- MXR-9565 (=Technisat Mediafocus?)
+- MXR-9571 (Bt848) (=CPH031?)
+- MXR-9575
+- MXR-9577 (Bt878) (=Prolink 878TV Rev.3x)
+- MXTV-9578CP (Bt878) (= Prolink PV-BT878P+4E)
+
+Iomega
+~~~~~~
+
+Buz (zr36067, zr36060, saa7111, saa7185)
+
+LML
+~~~
+   LML33 (zr36067, zr36060, bt819, bt856)
+
+Grandtec
+~~~~~~~~
+
+Models:
+
+- Grand Video Capture (Bt848)
+- Multi Capture Card  (Bt878)
+
+Koutech
+~~~~~~~
+
+Models:
+
+- KW-606 (Bt848)
+- KW-607 (Bt848 capture only)
+- KW-606RSF
+- KW-607A (capture only)
+- KW-608 (Zoran capture only)
+
+IODATA (jp)
+~~~~~~~~~~~
+
+Models:
+
+- GV-BCTV/PCI
+- GV-BCTV2/PCI
+- GV-BCTV3/PCI
+- GV-BCTV4/PCI
+- GV-VCP/PCI (capture only)
+- GV-VCP2/PCI (capture only)
+
+Canopus (jp)
+~~~~~~~~~~~~
+
+WinDVR	= Kworld "KW-TVL878RF"
+
+www.sigmacom.co.kr
+~~~~~~~~~~~~~~~~~~
+
+Sigma Cyber TV II
+
+www.sasem.co.kr
+~~~~~~~~~~~~~~~
+
+Litte OnAir TV
+
+hama
+~~~~
+
+TV/Radio-Tuner Card, PCI (Model 44677) = CPH051
+
+Sigma Designs
+~~~~~~~~~~~~~
+
+Hollywood plus (em8300, em9010, adv7175), (PCB "M340-10") MPEG DVD decoder
+
+Formac
+~~~~~~
+
+Models:
+
+- iProTV (Card for iMac Mezzanine slot, Bt848+SCSI)
+- ProTV (Bt848)
+- ProTV II = ProTV Stereo (Bt878) ["stereo" means FM stereo, tv is still mono]
+
+ATI
+~~~
+
+Models:
+
+- TV-Wonder
+- TV-Wonder VE
+
+Diamond Multimedia
+~~~~~~~~~~~~~~~~~~
+
+DTV2000 (Bt848, tda9875)
+
+Aopen
+~~~~~
+
+- VA1000 Plus (w/ Stereo)
+- VA1000 Lite
+- VA1000 (=LR90)
+
+Intel
+~~~~~
+
+Models:
+
+- Smart Video Recorder (ISA full-length)
+- Smart Video Recorder pro (ISA half-length)
+- Smart Video Recorder III (Bt848)
+
+STB
+~~~
+
+Models:
+
+- STB Gateway 6000704 (bt878)
+- STB Gateway 6000699 (bt848)
+- STB Gateway 6000402 (bt848)
+- STB TV130 PCI
+
+Videologic
+~~~~~~~~~~
+
+Models:
+
+- Captivator Pro/TV (ISA?)
+- Captivator PCI/VC (Bt848 bundled with camera) (capture only)
+
+Technotrend
+~~~~~~~~~~~~
+
+Models:
+
+- TT-SAT PCI (PCB "Sat-PCI Rev.:1.3.1"; zr36125, vpx3225d, stc0056a, Tuner:BSKE6-155A
+- TT-DVB-Sat
+   - revisions 1.1, 1.3, 1.5, 1.6 and 2.1
+   - This card is sold as OEM from:
+
+	- Siemens DVB-s Card
+	- Hauppauge WinTV DVB-S
+	- Technisat SkyStar 1 DVB
+	- Galaxis DVB Sat
+
+   - Now this card is called TT-PCline Premium Family
+   - TT-Budget (saa7146, bsru6-701a)
+     This card is sold as OEM from:
+
+	- Hauppauge WinTV Nova
+	- Satelco Standard PCI (DVB-S)
+   - TT-DVB-C PCI
+
+Teles
+~~~~~
+
+ DVB-s (Rev. 2.2, BSRV2-301A, data only?)
+
+Remote Vision
+~~~~~~~~~~~~~
+
+MX RV605 (Bt848 capture only)
+
+Boeder
+~~~~~~
+
+Models:
+
+- PC ChatCam (Model 68252) (Bt848 capture only)
+- Tv/Fm Capture Card  (Model 68404) = PV951
+
+Media-Surfer  (esc-kathrein.de)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Models:
+
+- Sat-Surfer (ISA)
+- Sat-Surfer PCI = Techni-PC-Sat
+- Cable-Surfer 1
+- Cable-Surfer 2
+- Cable-Surfer PCI (zr36120)
+- Audio-Surfer (ISA Radio card)
+
+Jetway (www.jetway.com.tw)
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Models:
+
+- JW-TV 878M
+- JW-TV 878  = KWorld KW-TV878RF
+
+Galaxis
+~~~~~~~
+
+Models:
+
+- Galaxis DVB Card S CI
+- Galaxis DVB Card C CI
+- Galaxis DVB Card S
+- Galaxis DVB Card C
+- Galaxis plug.in S [neuer Name: Galaxis DVB Card S CI
+
+Hauppauge
+~~~~~~~~~
+
+Models:
+
+- many many WinTV models ...
+- WinTV DVBs = Technotrend Premium 1.3
+- WinTV NOVA = Technotrend Budget 1.1 "S-DVB DATA"
+- WinTV NOVA-CI "SDVBACI"
+- WinTV Nova USB (=Technotrend USB 1.0)
+- WinTV-Nexus-s (=Technotrend Premium 2.1 or 2.2)
+- WinTV PVR
+- WinTV PVR 250
+- WinTV PVR 450
+
+US models
+
+-990 WinTV-PVR-350 (249USD) (iTVC15 chipset + radio)
+-980 WinTV-PVR-250 (149USD) (iTVC15 chipset)
+-880 WinTV-PVR-PCI (199USD) (KFIR chipset + bt878)
+-881 WinTV-PVR-USB
+-190 WinTV-GO
+-191 WinTV-GO-FM
+-404 WinTV
+-401 WinTV-radio
+-495 WinTV-Theater
+-602 WinTV-USB
+-621 WinTV-USB-FM
+-600 USB-Live
+-698 WinTV-HD
+-697 WinTV-D
+-564 WinTV-Nexus-S
+
+Deutsche Modelle:
+
+-603 WinTV GO
+-719 WinTV Primio-FM
+-718 WinTV PCI-FM
+-497 WinTV Theater
+-569 WinTV USB
+-568 WinTV USB-FM
+-882 WinTV PVR
+-981 WinTV PVR 250
+-891 WinTV-PVR-USB
+-541 WinTV Nova
+-488 WinTV Nova-Ci
+-564 WinTV-Nexus-s
+-727 WinTV-DVB-c
+-545 Common Interface
+-898 WinTV-Nova-USB
+
+UK models:
+
+-607 WinTV Go
+-693,793 WinTV Primio FM
+-647,747 WinTV PCI FM
+-498 WinTV Theater
+-883 WinTV PVR
+-893 WinTV PVR USB  (Duplicate entry)
+-566 WinTV USB (UK)
+-573 WinTV USB FM
+-429 Impact VCB (bt848)
+-600 USB Live (Video-In 1x Comp, 1xSVHS)
+-542 WinTV Nova
+-717 WinTV DVB-S
+-909 Nova-t PCI
+-893 Nova-t USB   (Duplicate entry)
+-802 MyTV
+-804 MyView
+-809 MyVideo
+-872 MyTV2Go FM
+-546 WinTV Nova-S CI
+-543 WinTV Nova
+-907 Nova-S USB
+-908 Nova-T USB
+-717 WinTV Nexus-S
+-157 DEC3000-s Standalone + USB
+
+Spain:
+
+-685 WinTV-Go
+-690 WinTV-PrimioFM
+-416 WinTV-PCI Nicam Estereo
+-677 WinTV-PCI-FM
+-699 WinTV-Theater
+-683 WinTV-USB
+-678 WinTV-USB-FM
+-983 WinTV-PVR-250
+-883 WinTV-PVR-PCI
+-993 WinTV-PVR-350
+-893 WinTV-PVR-USB
+-728 WinTV-DVB-C PCI
+-832 MyTV2Go
+-869 MyTV2Go-FM
+-805 MyVideo (USB)
+
+
+Matrix-Vision
+~~~~~~~~~~~~~
+
+Models:
+
+- MATRIX-Vision MV-Delta
+- MATRIX-Vision MV-Delta 2
+- MVsigma-SLC (Bt848)
+
+Conceptronic (.net)
+~~~~~~~~~~~~~~~~~~~
+
+Models:
+
+- TVCON FM,  TV card w/ FM = CPH05x
+- TVCON = CPH06x
+
+BestData
+~~~~~~~~
+
+Models:
+
+- HCC100 = VCC100rev1 + camera
+- VCC100 rev1 (bt848)
+- VCC100 rev2 (bt878)
+
+Gallant  (www.gallantcom.com) www.minton.com.tw
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Models:
+
+- Intervision IV-510 (capture only bt8x8)
+- Intervision IV-550 (bt8x8)
+- Intervision IV-100 (zoran)
+- Intervision IV-1000 (bt8x8)
+
+Asonic (www.asonic.com.cn) (website down)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+SkyEye tv 878
+
+Hoontech
+~~~~~~~~
+
+878TV/FM
+
+Teppro (www.itcteppro.com.tw)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Models:
+
+- ITC PCITV (Card Ver 1.0) "Teppro TV1/TVFM1 Card"
+- ITC PCITV (Card Ver 2.0)
+- ITC PCITV (Card Ver 3.0) = "PV-BT878P+ (REV.9D)"
+- ITC PCITV (Card Ver 4.0)
+- TEPPRO IV-550 (For BT848 Main Chip)
+- ITC DSTTV (bt878, satellite)
+- ITC VideoMaker (saa7146, StreamMachine sm2110, tvtuner) "PV-SM2210P+ (REV:1C)"
+
+Kworld (www.kworld.com.tw)
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+PC TV Station:
+
+- KWORLD KW-TV878R  TV (no radio)
+- KWORLD KW-TV878RF TV (w/ radio)
+- KWORLD KW-TVL878RF (low profile)
+- KWORLD KW-TV713XRF (saa7134)
+
+
+ MPEG TV Station (same cards as above plus WinDVR Software MPEG en/decoder)
+
+- KWORLD KW-TV878R -Pro   TV (no Radio)
+- KWORLD KW-TV878RF-Pro   TV (w/ Radio)
+- KWORLD KW-TV878R -Ultra TV (no Radio)
+- KWORLD KW-TV878RF-Ultra TV (w/ Radio)
+
+JTT/ Justy Corp.(http://www.jtt.ne.jp/)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+JTT-02 (JTT TV) "TV watchmate pro" (bt848)
+
+ADS www.adstech.com
+~~~~~~~~~~~~~~~~~~~
+
+Models:
+
+- Channel Surfer TV ( CHX-950 )
+- Channel Surfer TV+FM ( CHX-960FM )
+
+AVEC www.prochips.com
+~~~~~~~~~~~~~~~~~~~~~
+
+AVEC Intercapture (bt848, tea6320)
+
+NoBrand
+~~~~~~~
+
+TV Excel = Australian Name for "PV-BT878P+ 8E" or "878TV Rev.3\_"
+
+Mach www.machspeed.com
+~~~~~~~~~~~~~~~~~~~~~~
+
+Mach TV 878
+
+Eline www.eline-net.com/
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Models:
+
+- Eline Vision TVMaster / TVMaster FM (ELV-TVM/ ELV-TVM-FM) = LR26  (bt878)
+- Eline Vision TVMaster-2000 (ELV-TVM-2000, ELV-TVM-2000-FM)= LR138 (saa713x)
+
+Spirit
+~~~~~~
+
+- Spirit TV Tuner/Video Capture Card (bt848)
+
+Boser www.boser.com.tw
+~~~~~~~~~~~~~~~~~~~~~~
+
+Models:
+
+- HS-878 Mini PCI Capture Add-on Card
+- HS-879 Mini PCI 3D Audio and Capture Add-on Card (w/ ES1938 Solo-1)
+
+Satelco www.citycom-gmbh.de, www.satelco.de
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Models:
+
+- TV-FM =KNC1 saa7134
+- Standard PCI (DVB-S) = Technotrend Budget
+- Standard PCI (DVB-S) w/ CI
+- Satelco Highend PCI (DVB-S) = Technotrend Premium
+
+
+Sensoray www.sensoray.com
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Models:
+
+- Sensoray 311 (PC/104 bus)
+- Sensoray 611 (PCI)
+
+CEI (Chartered Electronics Industries Pte Ltd [CEI] [FCC ID HBY])
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Models:
+
+- TV Tuner  -  HBY-33A-RAFFLES  Brooktree Bt848KPF + Philips
+- TV Tuner MG9910  -  HBY33A-TVO  CEI + Philips SAA7110 + OKI M548262 + ST STV8438CV
+- Primetime TV (ISA)
+
+  - acquired by Singapore Technologies
+  - now operating as Chartered Semiconductor Manufacturing
+  - Manufacturer of video cards is listed as:
+
+    - Cogent Electronics Industries [CEI]
+
+AITech
+~~~~~~
+
+Models:
+
+- Wavewatcher TV (ISA)
+- AITech WaveWatcher TV-PCI = can be LR26 (Bt848) or LR50 (BT878)
+- WaveWatcher TVR-202 TV/FM Radio Card (ISA)
+
+MAXRON
+~~~~~~
+
+Maxron MaxTV/FM Radio (KW-TV878-FNT) = Kworld or JW-TV878-FBK
+
+www.ids-imaging.de
+~~~~~~~~~~~~~~~~~~
+
+Models:
+
+- Falcon Series (capture only)
+
+In USA: http://www.theimagingsource.com/
+- DFG/LC1
+
+www.sknet-web.co.jp
+~~~~~~~~~~~~~~~~~~~
+
+SKnet Monster TV (saa7134)
+
+A-Max www.amaxhk.com (Colormax, Amax, Napa)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+APAC Viewcomp 878
+
+Cybertainment
+~~~~~~~~~~~~~
+
+Models:
+
+- CyberMail AV Video Email Kit w/ PCI Capture Card (capture only)
+- CyberMail Xtreme
+
+These are Flyvideo
+
+VCR (http://www.vcrinc.com/)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Video Catcher 16
+
+Twinhan
+~~~~~~~
+
+Models:
+
+- DST Card/DST-IP (bt878, twinhan asic) VP-1020
+  - Sold as:
+
+    - KWorld DVBS Satellite TV-Card
+    - Powercolor DSTV Satellite Tuner Card
+    - Prolink Pixelview DTV2000
+    - Provideo PV-911 Digital Satellite TV Tuner Card With Common Interface ?
+
+- DST-CI Card (DVB Satellite) VP-1030
+- DCT Card (DVB cable)
+
+MSI
+~~~
+
+Models:
+
+- MSI TV@nywhere Tuner Card (MS-8876) (CX23881/883) Not Bt878 compatible.
+- MS-8401 DVB-S
+
+Focus www.focusinfo.com
+~~~~~~~~~~~~~~~~~~~~~~~
+
+InVideo PCI (bt878)
+
+Sdisilk www.sdisilk.com/
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Models:
+
+- SDI Silk 100
+- SDI Silk 200 SDI Input Card
+
+www.euresys.com
+~~~~~~~~~~~~~~~
+
+PICOLO series
+
+PMC/Pace
+~~~~~~~~
+
+www.pacecom.co.uk website closed
+
+Mercury www.kobian.com (UK and FR)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Models:
+
+- LR50
+- LR138RBG-Rx  == LR138
+
+TEC sound
+~~~~~~~~~
+
+TV-Mate = Zoltrix VP-8482
+
+Though educated googling found: www.techmakers.com
+
+(package and manuals don't have any other manufacturer info) TecSound
+
+Lorenzen www.lorenzen.de
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+SL DVB-S PCI = Technotrend Budget PCI (su1278 or bsru version)
+
+Origo (.uk) www.origo2000.com
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+PC TV Card = LR50
+
+I/O Magic www.iomagic.com
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+PC PVR - Desktop TV Personal Video Recorder DR-PCTV100 = Pinnacle ROB2D-51009464 4.0 + Cyberlink PowerVCR II
+
+Arowana
+~~~~~~~
+
+TV-Karte / Poso Power TV (?) = Zoltrix VP-8482 (?)
+
+iTVC15 boards
+~~~~~~~~~~~~~
+
+kuroutoshikou.com ITVC15
+yuan.com MPG160 PCI TV (Internal PCI MPEG2 encoder card plus TV-tuner)
+
+Asus www.asuscom.com
+~~~~~~~~~~~~~~~~~~~~
+
+Models:
+
+- Asus TV Tuner Card 880 NTSC (low profile, cx23880)
+- Asus TV (saa7134)
+
+Hoontech
+~~~~~~~~
+
+http://www.hoontech.de/
+
+- HART Vision 848 (H-ART Vision 848)
+- HART Vision 878 (H-Art Vision 878)
+
+
+
+Chips used at bttv devices
+--------------------------
+
+- all boards:
+
+  - Brooktree Bt848/848A/849/878/879: video capture chip
+
+- Board specific
+
+  - Miro PCTV:
+
+    - Philips or Temic Tuner
+
+  - Hauppauge Win/TV pci (version 405):
+
+    - Microchip 24LC02B or Philips 8582E2Y:
+
+       - 256 Byte EEPROM with configuration information
+       - I2C 0xa0-0xa1, (24LC02B also responds to 0xa2-0xaf)
+
+    - Philips SAA5246AGP/E: Videotext decoder chip, I2C 0x22-0x23
+
+    - TDA9800: sound decoder
+
+    - Winbond W24257AS-35: 32Kx8 CMOS static RAM (Videotext buffer mem)
+
+    - 14052B: analog switch for selection of sound source
+
+- PAL:
+
+  - TDA5737: VHF, hyperband and UHF mixer/oscillator for TV and VCR 3-band tuners
+  - TSA5522: 1.4 GHz I2C-bus controlled synthesizer, I2C 0xc2-0xc3
+
+- NTSC:
+
+  - TDA5731: VHF, hyperband and UHF mixer/oscillator for TV and VCR 3-band tuners
+  - TSA5518: no datasheet available on Philips site
+
+- STB TV pci:
+
+  - ???
+  - if you want better support for STB cards send me info!
+    Look at the board! What chips are on it?
+
+
+
+
+Specs
+-----
+
+Philips		http://www.Semiconductors.COM/pip/
+
+Conexant	http://www.conexant.com/
+
+Micronas	http://www.micronas.com/en/home/index.html
+
+Thanks
+------
+
+Many thanks to:
+
+- Markus Schroeder <schroedm@uni-duesseldorf.de> for information on the Bt848
+  and tuner programming and his control program xtvc.
+
+- Martin Buck <martin-2.buck@student.uni-ulm.de> for his great Videotext
+  package.
+
+- Gerd Hoffmann for the MSP3400 support and the modular
+  I2C, tuner, ... support.
+
+
+- MATRIX Vision for giving us 2 cards for free, which made support of
+  single crystal operation possible.
+
+- MIRO for providing a free PCTV card and detailed information about the
+  components on their cards. (E.g. how the tuner type is detected)
+  Without their card I could not have debugged the NTSC mode.
+
+- Hauppauge for telling how the sound input is selected and what components
+  they do and will use on their radio cards.
+  Also many thanks for faxing me the FM1216 data sheet.
+
+Contributors
+------------
+
+Michael Chu <mmchu@pobox.com>
+  AverMedia fix and more flexible card recognition
+
+Alan Cox <alan@lxorguk.ukuu.org.uk>
+  Video4Linux interface and 2.1.x kernel adaptation
+
+Chris Kleitsch
+  Hardware I2C
+
+Gerd Hoffmann
+  Radio card (ITT sound processor)
+
+bigfoot <bigfoot@net-way.net>
+
+Ragnar Hojland Espinosa <ragnar@macula.net>
+  ConferenceTV card
+
+
++ many more (please mail me if you are missing in this list and would
+	     like to be mentioned)
diff --git a/Documentation/admin-guide/media/cafe_ccic.rst b/Documentation/admin-guide/media/cafe_ccic.rst
new file mode 100644
index 000000000000..ff7fbce1342a
--- /dev/null
+++ b/Documentation/admin-guide/media/cafe_ccic.rst
@@ -0,0 +1,62 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+The cafe_ccic driver
+====================
+
+Author: Jonathan Corbet <corbet@lwn.net>
+
+Introduction
+------------
+
+"cafe_ccic" is a driver for the Marvell 88ALP01 "cafe" CMOS camera
+controller.  This is the controller found in first-generation OLPC systems,
+and this driver was written with support from the OLPC project.
+
+Current status: the core driver works.  It can generate data in YUV422,
+RGB565, and RGB444 formats.  (Anybody looking at the code will see RGB32 as
+well, but that is a debugging aid which will be removed shortly).  VGA and
+QVGA modes work; CIF is there but the colors remain funky.  Only the OV7670
+sensor is known to work with this controller at this time.
+
+To try it out: either of these commands will work:
+
+.. code-block:: none
+
+     $ mplayer tv:// -tv driver=v4l2:width=640:height=480 -nosound
+     $ mplayer tv:// -tv driver=v4l2:width=640:height=480:outfmt=bgr16 -nosound
+
+The "xawtv" utility also works; gqcam does not, for unknown reasons.
+
+Load time options
+-----------------
+
+There are a few load-time options, most of which can be changed after
+loading via sysfs as well:
+
+ - alloc_bufs_at_load:  Normally, the driver will not allocate any DMA
+   buffers until the time comes to transfer data.  If this option is set,
+   then worst-case-sized buffers will be allocated at module load time.
+   This option nails down the memory for the life of the module, but
+   perhaps decreases the chances of an allocation failure later on.
+
+ - dma_buf_size: The size of DMA buffers to allocate.  Note that this
+   option is only consulted for load-time allocation; when buffers are
+   allocated at run time, they will be sized appropriately for the current
+   camera settings.
+
+ - n_dma_bufs: The controller can cycle through either two or three DMA
+   buffers.  Normally, the driver tries to use three buffers; on faster
+   systems, however, it will work well with only two.
+
+ - min_buffers: The minimum number of streaming I/O buffers that the driver
+   will consent to work with.  Default is one, but, on slower systems,
+   better behavior with mplayer can be achieved by setting to a higher
+   value (like six).
+
+ - max_buffers: The maximum number of streaming I/O buffers; default is
+   ten.  That number was carefully picked out of a hat and should not be
+   assumed to actually mean much of anything.
+
+ - flip: If this boolean parameter is set, the sensor will be instructed to
+   invert the video image.  Whether it makes sense is determined by how
+   your particular camera is mounted.
diff --git a/Documentation/admin-guide/media/cardlist.rst b/Documentation/admin-guide/media/cardlist.rst
new file mode 100644
index 000000000000..5c9c3c97bcb2
--- /dev/null
+++ b/Documentation/admin-guide/media/cardlist.rst
@@ -0,0 +1,21 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Cards List
+==========
+
+.. toctree::
+	:maxdepth: 1
+
+	au0828-cardlist
+	bttv-cardlist
+	cx18-cardlist
+	cx23885-cardlist
+	cx88-cardlist
+	em28xx-cardlist
+	ivtv-cardlist
+	saa7134-cardlist
+	saa7164-cardlist
+	tm6000-cardlist
+	tuner-cardlist
+	usbvision-cardlist
+	gspca-cardlist
diff --git a/Documentation/admin-guide/media/cards.rst b/Documentation/admin-guide/media/cards.rst
new file mode 100644
index 000000000000..e2e30a56b450
--- /dev/null
+++ b/Documentation/admin-guide/media/cards.rst
@@ -0,0 +1,146 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Hardware supported by the linuxtv.org DVB drivers
+=================================================
+
+.. note::
+
+   This documentation is outdated. Please check at the DVB wiki
+   at https://linuxtv.org/wiki for more updated info.
+
+   Please look at
+   https://linuxtv.org/wiki/index.php/Hardware_Device_Information
+   for an updated list of supported cards.
+
+Generally, the DVB hardware manufacturers frequently change the
+frontends (i.e. tuner / demodulator units) used, usually without
+changing the product name, revision number or specs. Some cards
+are also available in versions with different frontends for
+DVB-S/DVB-C/DVB-T. Thus the frontend drivers are listed separately.
+
+.. note::
+
+  #) There is no guarantee that every frontend driver works
+     out of the box with every card, because of different wiring.
+
+  #) The demodulator chips can be used with a variety of
+     tuner/PLL chips, and not all combinations are supported. Often
+     the demodulator and tuner/PLL chip are inside a metal box for
+     shielding, and the whole metal box has its own part number.
+
+
+- Frontends drivers:
+
+  - dvb_dummy_fe: for testing...
+
+  DVB-S:
+   - ves1x93		: Alps BSRV2 (ves1893 demodulator) and dbox2 (ves1993)
+   - cx24110		: Conexant HM1221/HM1811 (cx24110 or cx24106 demod, cx24108 PLL)
+   - grundig_29504-491	: Grundig 29504-491 (Philips TDA8083 demodulator), tsa5522 PLL
+   - mt312		: Zarlink mt312 or Mitel vp310 demodulator, sl1935 or tsa5059 PLLi, Technisat Sky2Pc with bios Rev. 2.3
+   - stv0299		: Alps BSRU6 (tsa5059 PLL), LG TDQB-S00x (tsa5059 PLL),
+			  LG TDQF-S001F (sl1935 PLL), Philips SU1278 (tua6100 PLL),
+			  Philips SU1278SH (tsa5059 PLL), Samsung TBMU24112IMB, Technisat Sky2Pc with bios Rev. 2.6
+
+  DVB-C:
+   - ves1820		: various (ves1820 demodulator, sp5659c or spXXXX PLL)
+   - at76c651		: Atmel AT76c651(B) with DAT7021 PLL
+
+  DVB-T:
+   - alps_tdlb7		: Alps TDLB7 (sp8870 demodulator, sp5659 PLL)
+   - alps_tdmb7		: Alps TDMB7 (cx22700 demodulator)
+   - grundig_29504-401	: Grundig 29504-401 (LSI L64781 demodulator), tsa5060 PLL
+   - tda1004x		: Philips tda10045h (td1344 or tdm1316l PLL)
+   - nxt6000 		: Alps TDME7 (MITEL SP5659 PLL), Alps TDED4 (TI ALP510 PLL), Comtech DVBT-6k07 (SP5730 PLL), (NxtWave Communications NXT6000 demodulator)
+   - sp887x		: Microtune 7202D
+   - dib3000mb	: DiBcom 3000-MB demodulator
+
+  DVB-S/C/T:
+   - dst		: TwinHan DST Frontend
+
+  ATSC:
+   - nxt200x		: Nxtwave NXT2002 & NXT2004
+   - or51211		: or51211 based (pcHDTV HD2000 card)
+   - or51132		: or51132 based (pcHDTV HD3000 card)
+   - bcm3510		: Broadcom BCM3510
+   - lgdt330x		: LG Electronics DT3302 & DT3303
+
+
+- Cards based on the Phillips saa7146 multimedia PCI bridge chip:
+
+  - TI AV7110 based cards (i.e. with hardware MPEG decoder):
+    - Siemens/Technotrend/Hauppauge PCI DVB card revision 1.1, 1.3, 1.5, 1.6, 2.1 (aka Hauppauge Nexus)
+  - "budget" cards (i.e. without hardware MPEG decoder):
+    - Technotrend Budget / Hauppauge WinTV-Nova PCI Cards
+    - SATELCO Multimedia PCI
+    - KNC1 DVB-S, Typhoon DVB-S, Terratec Cinergy 1200 DVB-S (no CI support)
+    - Typhoon DVB-S budget
+    - Fujitsu-Siemens Activy DVB-S budget card
+
+- Cards based on the B2C2 Inc. FlexCopII/IIb/III:
+
+  - Technisat SkyStar2 PCI DVB card revision 2.3, 2.6B, 2.6C
+
+- Cards based on the Conexant Bt8xx PCI bridge:
+
+  - Pinnacle PCTV Sat DVB
+  - Nebula Electronics DigiTV
+  - TwinHan DST
+  - Avermedia DVB-T
+  - ChainTech digitop DST-1000 DVB-S
+  - pcHDTV HD-2000 TV
+  - DViCO FusionHDTV DVB-T Lite
+  - DViCO FusionHDTV5 Lite
+
+- Technotrend / Hauppauge DVB USB devices:
+
+  - Nova USB
+  - DEC 2000-T, 3000-S, 2540-T
+
+- DiBcom DVB-T USB based devices:
+
+  - Twinhan VisionPlus VisionDTV USB-Ter DVB-T Device
+  - HAMA DVB-T USB device
+  - CTS Portable (Chinese Television System)
+  - KWorld V-Stream XPERT DTV DVB-T USB
+  - JetWay DTV DVB-T USB
+  - ADSTech Instant TV DVB-T USB
+  - Ultima Electronic/Artec T1 USB TVBOX (AN2135 and AN2235)
+  - Compro Videomate DVB-U2000 - DVB-T USB
+  - Grandtec USB DVB-T
+  - Avermedia AverTV DVBT USB
+  - DiBcom USB DVB-T reference device (non-public)
+  - Yakumo DVB-T mobile USB2.0
+  - DiBcom USB2.0 DVB-T reference device (non-public)
+
+- Experimental support for the analog module of the Siemens DVB-C PCI card
+
+- Cards based on the Conexant cx2388x PCI bridge:
+
+  - ADS Tech Instant TV DVB-T PCI
+  - ATI HDTV Wonder
+  - digitalnow DNTV Live! DVB-T
+  - DViCO FusionHDTV DVB-T1
+  - DViCO FusionHDTV DVB-T Plus
+  - DViCO FusionHDTV3 Gold-Q
+  - DViCO FusionHDTV3 Gold-T
+  - DViCO FusionHDTV5 Gold
+  - Hauppauge Nova-T DVB-T
+  - KWorld/VStream XPert DVB-T
+  - pcHDTV HD3000 HDTV
+  - TerraTec Cinergy 1400 DVB-T
+  - WinFast DTV1000-T
+
+- Cards based on the Phillips saa7134 PCI bridge:
+
+  - Medion 7134
+  - Pinnacle PCTV 300i DVB-T + PAL
+  - LifeView FlyDVB-T DUO
+  - Typhoon DVB-T Duo Digital/Analog Cardbus
+  - Philips TOUGH DVB-T reference design
+  - Philips EUROPA V3 reference design
+  - Compro Videomate DVB-T300
+  - Compro Videomate DVB-T200
+  - AVerMedia AVerTVHD MCE A180
+  - KWorld PC150-U ATSC Hybrid
+
diff --git a/Documentation/admin-guide/media/ci.rst b/Documentation/admin-guide/media/ci.rst
new file mode 100644
index 000000000000..ded4d8fbbf92
--- /dev/null
+++ b/Documentation/admin-guide/media/ci.rst
@@ -0,0 +1,77 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Digital TV Conditional Access Interface
+=======================================
+
+
+.. note::
+
+   This documentation is outdated.
+
+This document describes the usage of the high level CI API as
+in accordance to the Linux DVB API. This is a not a documentation for the,
+existing low level CI API.
+
+.. note::
+
+   For the Twinhan/Twinhan clones, the dst_ca module handles the CI
+   hardware handling. This module is loaded automatically if a CI
+   (Common Interface, that holds the CAM (Conditional Access Module)
+   is detected.
+
+ca_zap
+~~~~~~
+
+A userspace application, like ``ca_zap`` is required to handle encrypted
+MPEG-TS streams.
+
+The ``ca_zap`` userland application is in charge of sending the
+descrambling related information to the Conditional Access Module (CAM).
+
+This application requires the following to function properly as of now.
+
+a) Tune to a valid channel, with szap.
+
+  eg: $ szap -c channels.conf -r "TMC" -x
+
+b) a channels.conf containing a valid PMT PID
+
+  eg: TMC:11996:h:0:27500:278:512:650:321
+
+  here 278 is a valid PMT PID. the rest of the values are the
+  same ones that szap uses.
+
+c) after running a szap, you have to run ca_zap, for the
+   descrambler to function,
+
+  eg: $ ca_zap channels.conf "TMC"
+
+d) Hopefully enjoy your favourite subscribed channel as you do with
+   a FTA card.
+
+.. note::
+
+  Currently ca_zap, and dst_test, both are meant for demonstration
+  purposes only, they can become full fledged applications if necessary.
+
+
+Cards that fall in this category
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+At present the cards that fall in this category are the Twinhan and its
+clones, these cards are available as VVMER, Tomato, Hercules, Orange and
+so on.
+
+CI modules that are supported
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The CI module support is largely dependent upon the firmware on the cards
+Some cards do support almost all of the available CI modules. There is
+nothing much that can be done in order to make additional CI modules
+working with these cards.
+
+Modules that have been tested by this driver at present are
+
+(1) Irdeto 1 and 2 from SCM
+(2) Viaccess from SCM
+(3) Dragoncam
diff --git a/Documentation/admin-guide/media/cpia2.rst b/Documentation/admin-guide/media/cpia2.rst
new file mode 100644
index 000000000000..f6ffef686462
--- /dev/null
+++ b/Documentation/admin-guide/media/cpia2.rst
@@ -0,0 +1,145 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+The cpia2 driver
+================
+
+Authors: Peter Pregler <Peter_Pregler@email.com>,
+Scott J. Bertin <scottbertin@yahoo.com>, and
+Jarl Totland <Jarl.Totland@bdc.no> for the original cpia driver, which
+this one was modelled from.
+
+Introduction
+------------
+
+This is a driver for STMicroelectronics's CPiA2 (second generation
+Colour Processor Interface ASIC) based cameras. This camera outputs an MJPEG
+stream at up to vga size. It implements the Video4Linux interface as much as
+possible.  Since the V4L interface does not support compressed formats, only
+an mjpeg enabled application can be used with the camera. We have modified the
+gqcam application to view this stream.
+
+The driver is implemented as two kernel modules. The cpia2 module
+contains the camera functions and the V4L interface.  The cpia2_usb module
+contains usb specific functions.  The main reason for this was the size of the
+module was getting out of hand, so I separated them.  It is not likely that
+there will be a parallel port version.
+
+Features
+--------
+
+- Supports cameras with the Vision stv6410 (CIF) and stv6500 (VGA) cmos
+  sensors. I only have the vga sensor, so can't test the other.
+- Image formats: VGA, QVGA, CIF, QCIF, and a number of sizes in between.
+  VGA and QVGA are the native image sizes for the VGA camera. CIF is done
+  in the coprocessor by scaling QVGA.  All other sizes are done by clipping.
+- Palette: YCrCb, compressed with MJPEG.
+- Some compression parameters are settable.
+- Sensor framerate is adjustable (up to 30 fps CIF, 15 fps VGA).
+- Adjust brightness, color, contrast while streaming.
+- Flicker control settable for 50 or 60 Hz mains frequency.
+
+Making and installing the stv672 driver modules
+-----------------------------------------------
+
+Requirements
+~~~~~~~~~~~~
+
+Video4Linux must be either compiled into the kernel or
+available as a module.  Video4Linux2 is automatically detected and made
+available at compile time.
+
+Setup
+~~~~~
+
+Use ``modprobe cpia2`` to load and ``modprobe -r cpia2`` to unload. This
+may be done automatically by your distribution.
+
+Driver options
+~~~~~~~~~~~~~~
+
+.. tabularcolumns:: |p{13ex}|L|
+
+
+==============  ========================================================
+Option		Description
+==============  ========================================================
+video_nr	video device to register (0=/dev/video0, etc)
+		range -1 to 64.  default is -1 (first available)
+		If you have more than 1 camera, this MUST be -1.
+buffer_size	Size for each frame buffer in bytes (default 68k)
+num_buffers	Number of frame buffers (1-32, default 3)
+alternate	USB Alternate (2-7, default 7)
+flicker_freq	Frequency for flicker reduction(50 or 60, default 60)
+flicker_mode	0 to disable, or 1 to enable flicker reduction.
+		(default 0). This is only effective if the camera
+		uses a stv0672 coprocessor.
+==============  ========================================================
+
+Setting the options
+~~~~~~~~~~~~~~~~~~~
+
+If you are using modules, edit /etc/modules.conf and add an options
+line like this::
+
+	options cpia2 num_buffers=3 buffer_size=65535
+
+If the driver is compiled into the kernel, at boot time specify them
+like this::
+
+	cpia2.num_buffers=3 cpia2.buffer_size=65535
+
+What buffer size should I use?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The maximum image size depends on the alternate you choose, and the
+frame rate achieved by the camera.  If the compression engine is able to
+keep up with the frame rate, the maximum image size is given by the table
+below.
+
+The compression engine starts out at maximum compression, and will
+increase image quality until it is close to the size in the table.  As long
+as the compression engine can keep up with the frame rate, after a short time
+the images will all be about the size in the table, regardless of resolution.
+
+At low alternate settings, the compression engine may not be able to
+compress the image enough and will reduce the frame rate by producing larger
+images.
+
+The default of 68k should be good for most users.  This will handle
+any alternate at frame rates down to 15fps.  For lower frame rates, it may
+be necessary to increase the buffer size to avoid having frames dropped due
+to insufficient space.
+
+========== ========== ======== =====
+Alternate  bytes/ms   15fps    30fps
+========== ========== ======== =====
+    2         128      8533     4267
+    3         384     25600    12800
+    4         640     42667    21333
+    5         768     51200    25600
+    6         896     59733    29867
+    7        1023     68200    34100
+========== ========== ======== =====
+
+Table: Image size(bytes)
+
+
+How many buffers should I use?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+For normal streaming, 3 should give the best results.  With only 2,
+it is possible for the camera to finish sending one image just after a
+program has started reading the other.  If this happens, the driver must drop
+a frame.  The exception to this is if you have a heavily loaded machine.  In
+this case use 2 buffers.  You are probably not reading at the full frame rate.
+If the camera can send multiple images before a read finishes, it could
+overwrite the third buffer before the read finishes, leading to a corrupt
+image.  Single and double buffering have extra checks to avoid overwriting.
+
+Using the camera
+~~~~~~~~~~~~~~~~
+
+We are providing a modified gqcam application to view the output. In
+order to avoid confusion, here it is called mview.  There is also the qx5view
+program which can also control the lights on the qx5 microscope. MJPEG Tools
+(http://mjpeg.sourceforge.net) can also be used to record from the camera.
diff --git a/Documentation/admin-guide/media/cx18-cardlist.rst b/Documentation/admin-guide/media/cx18-cardlist.rst
new file mode 100644
index 000000000000..26f2da9aa542
--- /dev/null
+++ b/Documentation/admin-guide/media/cx18-cardlist.rst
@@ -0,0 +1,17 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+CX18 cards list
+===============
+
+Those cards are supported by cx18 driver:
+
+- Hauppauge HVR-1600 (ESMT memory)
+- Hauppauge HVR-1600 (Samsung memory)
+- Compro VideoMate H900
+- Yuan MPC718 MiniPCI DVB-T/Analog
+- Conexant Raptor PAL/SECAM
+- Toshiba Qosmio DVB-T/Analog
+- Leadtek WinFast PVR2100
+- Leadtek WinFast DVR3100
+- GoTView PCI DVD3 Hybrid
+- Hauppauge HVR-1600 (s5h1411/tda18271)
diff --git a/Documentation/admin-guide/media/cx23885-cardlist.rst b/Documentation/admin-guide/media/cx23885-cardlist.rst
new file mode 100644
index 000000000000..0415b8e0be6f
--- /dev/null
+++ b/Documentation/admin-guide/media/cx23885-cardlist.rst
@@ -0,0 +1,267 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+cx23885 cards list
+==================
+
+.. tabularcolumns:: |p{1.4cm}|p{11.1cm}|p{4.2cm}|
+
+.. flat-table::
+   :header-rows: 1
+   :widths: 2 19 18
+   :stub-columns: 0
+
+   * - Card number
+     - Card name
+     - PCI IDs
+
+   * - 0
+     - UNKNOWN/GENERIC
+     - 0070:3400
+
+   * - 1
+     - Hauppauge WinTV-HVR1800lp
+     - 0070:7600
+
+   * - 2
+     - Hauppauge WinTV-HVR1800
+     - 0070:7800, 0070:7801, 0070:7809
+
+   * - 3
+     - Hauppauge WinTV-HVR1250
+     - 0070:7911
+
+   * - 4
+     - DViCO FusionHDTV5 Express
+     - 18ac:d500
+
+   * - 5
+     - Hauppauge WinTV-HVR1500Q
+     - 0070:7790, 0070:7797
+
+   * - 6
+     - Hauppauge WinTV-HVR1500
+     - 0070:7710, 0070:7717
+
+   * - 7
+     - Hauppauge WinTV-HVR1200
+     - 0070:71d1, 0070:71d3
+
+   * - 8
+     - Hauppauge WinTV-HVR1700
+     - 0070:8101
+
+   * - 9
+     - Hauppauge WinTV-HVR1400
+     - 0070:8010
+
+   * - 10
+     - DViCO FusionHDTV7 Dual Express
+     - 18ac:d618
+
+   * - 11
+     - DViCO FusionHDTV DVB-T Dual Express
+     - 18ac:db78
+
+   * - 12
+     - Leadtek Winfast PxDVR3200 H
+     - 107d:6681
+
+   * - 13
+     - Compro VideoMate E650F
+     - 185b:e800
+
+   * - 14
+     - TurboSight TBS 6920
+     - 6920:8888
+
+   * - 15
+     - TeVii S470
+     - d470:9022
+
+   * - 16
+     - DVBWorld DVB-S2 2005
+     - 0001:2005
+
+   * - 17
+     - NetUP Dual DVB-S2 CI
+     - 1b55:2a2c
+
+   * - 18
+     - Hauppauge WinTV-HVR1270
+     - 0070:2211
+
+   * - 19
+     - Hauppauge WinTV-HVR1275
+     - 0070:2215, 0070:221d, 0070:22f2
+
+   * - 20
+     - Hauppauge WinTV-HVR1255
+     - 0070:2251, 0070:22f1
+
+   * - 21
+     - Hauppauge WinTV-HVR1210
+     - 0070:2291, 0070:2295, 0070:2299, 0070:229d, 0070:22f0, 0070:22f3, 0070:22f4, 0070:22f5
+
+   * - 22
+     - Mygica X8506 DMB-TH
+     - 14f1:8651
+
+   * - 23
+     - Magic-Pro ProHDTV Extreme 2
+     - 14f1:8657
+
+   * - 24
+     - Hauppauge WinTV-HVR1850
+     - 0070:8541
+
+   * - 25
+     - Compro VideoMate E800
+     - 1858:e800
+
+   * - 26
+     - Hauppauge WinTV-HVR1290
+     - 0070:8551
+
+   * - 27
+     - Mygica X8558 PRO DMB-TH
+     - 14f1:8578
+
+   * - 28
+     - LEADTEK WinFast PxTV1200
+     - 107d:6f22
+
+   * - 29
+     - GoTView X5 3D Hybrid
+     - 5654:2390
+
+   * - 30
+     - NetUP Dual DVB-T/C-CI RF
+     - 1b55:e2e4
+
+   * - 31
+     - Leadtek Winfast PxDVR3200 H XC4000
+     - 107d:6f39
+
+   * - 32
+     - MPX-885
+     -
+
+   * - 33
+     - Mygica X8502/X8507 ISDB-T
+     - 14f1:8502
+
+   * - 34
+     - TerraTec Cinergy T PCIe Dual
+     - 153b:117e
+
+   * - 35
+     - TeVii S471
+     - d471:9022
+
+   * - 36
+     - Hauppauge WinTV-HVR1255
+     - 0070:2259
+
+   * - 37
+     - Prof Revolution DVB-S2 8000
+     - 8000:3034
+
+   * - 38
+     - Hauppauge WinTV-HVR4400/HVR5500
+     - 0070:c108, 0070:c138, 0070:c1f8
+
+   * - 39
+     - AVerTV Hybrid Express Slim HC81R
+     - 1461:d939
+
+   * - 40
+     - TurboSight TBS 6981
+     - 6981:8888
+
+   * - 41
+     - TurboSight TBS 6980
+     - 6980:8888
+
+   * - 42
+     - Leadtek Winfast PxPVR2200
+     - 107d:6f21
+
+   * - 43
+     - Hauppauge ImpactVCB-e
+     - 0070:7133, 0070:7137
+
+   * - 44
+     - DViCO FusionHDTV DVB-T Dual Express2
+     - 18ac:db98
+
+   * - 45
+     - DVBSky T9580
+     - 4254:9580
+
+   * - 46
+     - DVBSky T980C
+     - 4254:980c
+
+   * - 47
+     - DVBSky S950C
+     - 4254:950c
+
+   * - 48
+     - Technotrend TT-budget CT2-4500 CI
+     - 13c2:3013
+
+   * - 49
+     - DVBSky S950
+     - 4254:0950
+
+   * - 50
+     - DVBSky S952
+     - 4254:0952
+
+   * - 51
+     - DVBSky T982
+     - 4254:0982
+
+   * - 52
+     - Hauppauge WinTV-HVR5525
+     - 0070:f038
+
+   * - 53
+     - Hauppauge WinTV Starburst
+     - 0070:c12a
+
+   * - 54
+     - ViewCast 260e
+     - 1576:0260
+
+   * - 55
+     - ViewCast 460e
+     - 1576:0460
+
+   * - 56
+     - Hauppauge WinTV-QuadHD-DVB
+     - 0070:6a28, 0070:6b28
+
+   * - 57
+     - Hauppauge WinTV-QuadHD-ATSC
+     - 0070:6a18, 0070:6b18
+
+   * - 58
+     - Hauppauge WinTV-HVR-1265(161111)
+     - 0070:2a18
+
+   * - 59
+     - Hauppauge WinTV-Starburst2
+     - 0070:f02a
+
+   * - 60
+     - Hauppauge WinTV-QuadHD-DVB(885)
+     -
+
+   * - 61
+     - Hauppauge WinTV-QuadHD-ATSC(885)
+     -
+
+   * - 62
+     - AVerMedia CE310B
+     - 1461:3100
diff --git a/Documentation/admin-guide/media/cx88-cardlist.rst b/Documentation/admin-guide/media/cx88-cardlist.rst
new file mode 100644
index 000000000000..4524dfb13d18
--- /dev/null
+++ b/Documentation/admin-guide/media/cx88-cardlist.rst
@@ -0,0 +1,383 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+CX88 cards list
+===============
+
+.. tabularcolumns:: |p{1.4cm}|p{11.1cm}|p{4.2cm}|
+
+.. flat-table::
+   :header-rows: 1
+   :widths: 2 19 18
+   :stub-columns: 0
+
+   * - Card number
+     - Card name
+     - PCI IDs
+
+   * - 0
+     - UNKNOWN/GENERIC
+     -
+
+   * - 1
+     - Hauppauge WinTV 34xxx models
+     - 0070:3400, 0070:3401
+
+   * - 2
+     - GDI Black Gold
+     - 14c7:0106, 14c7:0107
+
+   * - 3
+     - PixelView
+     - 1554:4811
+
+   * - 4
+     - ATI TV Wonder Pro
+     - 1002:00f8, 1002:00f9
+
+   * - 5
+     - Leadtek Winfast 2000XP Expert
+     - 107d:6611, 107d:6613
+
+   * - 6
+     - AverTV Studio 303 (M126)
+     - 1461:000b
+
+   * - 7
+     - MSI TV-@nywhere Master
+     - 1462:8606
+
+   * - 8
+     - Leadtek Winfast DV2000
+     - 107d:6620, 107d:6621
+
+   * - 9
+     - Leadtek PVR 2000
+     - 107d:663b, 107d:663c, 107d:6632, 107d:6630, 107d:6638, 107d:6631, 107d:6637, 107d:663d
+
+   * - 10
+     - IODATA GV-VCP3/PCI
+     - 10fc:d003
+
+   * - 11
+     - Prolink PlayTV PVR
+     -
+
+   * - 12
+     - ASUS PVR-416
+     - 1043:4823, 1461:c111
+
+   * - 13
+     - MSI TV-@nywhere
+     -
+
+   * - 14
+     - KWorld/VStream XPert DVB-T
+     - 17de:08a6
+
+   * - 15
+     - DViCO FusionHDTV DVB-T1
+     - 18ac:db00
+
+   * - 16
+     - KWorld LTV883RF
+     -
+
+   * - 17
+     - DViCO FusionHDTV 3 Gold-Q
+     - 18ac:d810, 18ac:d800
+
+   * - 18
+     - Hauppauge Nova-T DVB-T
+     - 0070:9002, 0070:9001, 0070:9000
+
+   * - 19
+     - Conexant DVB-T reference design
+     - 14f1:0187
+
+   * - 20
+     - Provideo PV259
+     - 1540:2580
+
+   * - 21
+     - DViCO FusionHDTV DVB-T Plus
+     - 18ac:db10, 18ac:db11
+
+   * - 22
+     - pcHDTV HD3000 HDTV
+     - 7063:3000
+
+   * - 23
+     - digitalnow DNTV Live! DVB-T
+     - 17de:a8a6
+
+   * - 24
+     - Hauppauge WinTV 28xxx (Roslyn) models
+     - 0070:2801
+
+   * - 25
+     - Digital-Logic MICROSPACE Entertainment Center (MEC)
+     - 14f1:0342
+
+   * - 26
+     - IODATA GV/BCTV7E
+     - 10fc:d035
+
+   * - 27
+     - PixelView PlayTV Ultra Pro (Stereo)
+     -
+
+   * - 28
+     - DViCO FusionHDTV 3 Gold-T
+     - 18ac:d820
+
+   * - 29
+     - ADS Tech Instant TV DVB-T PCI
+     - 1421:0334
+
+   * - 30
+     - TerraTec Cinergy 1400 DVB-T
+     - 153b:1166
+
+   * - 31
+     - DViCO FusionHDTV 5 Gold
+     - 18ac:d500
+
+   * - 32
+     - AverMedia UltraTV Media Center PCI 550
+     - 1461:8011
+
+   * - 33
+     - Kworld V-Stream Xpert DVD
+     -
+
+   * - 34
+     - ATI HDTV Wonder
+     - 1002:a101
+
+   * - 35
+     - WinFast DTV1000-T
+     - 107d:665f
+
+   * - 36
+     - AVerTV 303 (M126)
+     - 1461:000a
+
+   * - 37
+     - Hauppauge Nova-S-Plus DVB-S
+     - 0070:9201, 0070:9202
+
+   * - 38
+     - Hauppauge Nova-SE2 DVB-S
+     - 0070:9200
+
+   * - 39
+     - KWorld DVB-S 100
+     - 17de:08b2, 1421:0341
+
+   * - 40
+     - Hauppauge WinTV-HVR1100 DVB-T/Hybrid
+     - 0070:9400, 0070:9402
+
+   * - 41
+     - Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profile)
+     - 0070:9800, 0070:9802
+
+   * - 42
+     - digitalnow DNTV Live! DVB-T Pro
+     - 1822:0025, 1822:0019
+
+   * - 43
+     - KWorld/VStream XPert DVB-T with cx22702
+     - 17de:08a1, 12ab:2300
+
+   * - 44
+     - DViCO FusionHDTV DVB-T Dual Digital
+     - 18ac:db50, 18ac:db54
+
+   * - 45
+     - KWorld HardwareMpegTV XPert
+     - 17de:0840, 1421:0305
+
+   * - 46
+     - DViCO FusionHDTV DVB-T Hybrid
+     - 18ac:db40, 18ac:db44
+
+   * - 47
+     - pcHDTV HD5500 HDTV
+     - 7063:5500
+
+   * - 48
+     - Kworld MCE 200 Deluxe
+     - 17de:0841
+
+   * - 49
+     - PixelView PlayTV P7000
+     - 1554:4813
+
+   * - 50
+     - NPG Tech Real TV FM Top 10
+     - 14f1:0842
+
+   * - 51
+     - WinFast DTV2000 H
+     - 107d:665e
+
+   * - 52
+     - Geniatech DVB-S
+     - 14f1:0084
+
+   * - 53
+     - Hauppauge WinTV-HVR3000 TriMode Analog/DVB-S/DVB-T
+     - 0070:1404, 0070:1400, 0070:1401, 0070:1402
+
+   * - 54
+     - Norwood Micro TV Tuner
+     -
+
+   * - 55
+     - Shenzhen Tungsten Ages Tech TE-DTV-250 / Swann OEM
+     - c180:c980
+
+   * - 56
+     - Hauppauge WinTV-HVR1300 DVB-T/Hybrid MPEG Encoder
+     - 0070:9600, 0070:9601, 0070:9602
+
+   * - 57
+     - ADS Tech Instant Video PCI
+     - 1421:0390
+
+   * - 58
+     - Pinnacle PCTV HD 800i
+     - 11bd:0051
+
+   * - 59
+     - DViCO FusionHDTV 5 PCI nano
+     - 18ac:d530
+
+   * - 60
+     - Pinnacle Hybrid PCTV
+     - 12ab:1788
+
+   * - 61
+     - Leadtek TV2000 XP Global
+     - 107d:6f18, 107d:6618, 107d:6619
+
+   * - 62
+     - PowerColor RA330
+     - 14f1:ea3d
+
+   * - 63
+     - Geniatech X8000-MT DVBT
+     - 14f1:8852
+
+   * - 64
+     - DViCO FusionHDTV DVB-T PRO
+     - 18ac:db30
+
+   * - 65
+     - DViCO FusionHDTV 7 Gold
+     - 18ac:d610
+
+   * - 66
+     - Prolink Pixelview MPEG 8000GT
+     - 1554:4935
+
+   * - 67
+     - Kworld PlusTV HD PCI 120 (ATSC 120)
+     - 17de:08c1
+
+   * - 68
+     - Hauppauge WinTV-HVR4000 DVB-S/S2/T/Hybrid
+     - 0070:6900, 0070:6904, 0070:6902
+
+   * - 69
+     - Hauppauge WinTV-HVR4000(Lite) DVB-S/S2
+     - 0070:6905, 0070:6906
+
+   * - 70
+     - TeVii S460 DVB-S/S2
+     - d460:9022
+
+   * - 71
+     - Omicom SS4 DVB-S/S2 PCI
+     - A044:2011
+
+   * - 72
+     - TBS 8920 DVB-S/S2
+     - 8920:8888
+
+   * - 73
+     - TeVii S420 DVB-S
+     - d420:9022
+
+   * - 74
+     - Prolink Pixelview Global Extreme
+     - 1554:4976
+
+   * - 75
+     - PROF 7300 DVB-S/S2
+     - B033:3033
+
+   * - 76
+     - SATTRADE ST4200 DVB-S/S2
+     - b200:4200
+
+   * - 77
+     - TBS 8910 DVB-S
+     - 8910:8888
+
+   * - 78
+     - Prof 6200 DVB-S
+     - b022:3022
+
+   * - 79
+     - Terratec Cinergy HT PCI MKII
+     - 153b:1177
+
+   * - 80
+     - Hauppauge WinTV-IR Only
+     - 0070:9290
+
+   * - 81
+     - Leadtek WinFast DTV1800 Hybrid
+     - 107d:6654
+
+   * - 82
+     - WinFast DTV2000 H rev. J
+     - 107d:6f2b
+
+   * - 83
+     - Prof 7301 DVB-S/S2
+     - b034:3034
+
+   * - 84
+     - Samsung SMT 7020 DVB-S
+     - 18ac:dc00, 18ac:dccd
+
+   * - 85
+     - Twinhan VP-1027 DVB-S
+     - 1822:0023
+
+   * - 86
+     - TeVii S464 DVB-S/S2
+     - d464:9022
+
+   * - 87
+     - Leadtek WinFast DTV2000 H PLUS
+     - 107d:6f42
+
+   * - 88
+     - Leadtek WinFast DTV1800 H (XC4000)
+     - 107d:6f38
+
+   * - 89
+     - Leadtek TV2000 XP Global (SC4100)
+     - 107d:6f36
+
+   * - 90
+     - Leadtek TV2000 XP Global (XC4100)
+     - 107d:6f43
+
+   * - 91
+     - NotOnlyTV LV3H
+     -
diff --git a/Documentation/admin-guide/media/cx88.rst b/Documentation/admin-guide/media/cx88.rst
new file mode 100644
index 000000000000..e4badb18199d
--- /dev/null
+++ b/Documentation/admin-guide/media/cx88.rst
@@ -0,0 +1,58 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+The cx88 driver
+===============
+
+Author:  Gerd Hoffmann
+
+This is a v4l2 device driver for the cx2388x chip.
+
+
+Current status
+--------------
+
+video
+	- Works.
+	- Overlay isn't supported.
+
+audio
+	- Works. The TV standard detection is made by the driver, as the
+	  hardware has bugs to auto-detect.
+	- audio data dma (i.e. recording without loopback cable to the
+	  sound card) is supported via cx88-alsa.
+
+vbi
+	- Works.
+
+
+How to add support for new cards
+--------------------------------
+
+The driver needs some config info for the TV cards.  This stuff is in
+cx88-cards.c.  If the driver doesn't work well you likely need a new
+entry for your card in that file.  Check the kernel log (using dmesg)
+to see whenever the driver knows your card or not.  There is a line
+like this one:
+
+.. code-block:: none
+
+	cx8800[0]: subsystem: 0070:3400, board: Hauppauge WinTV \
+		34xxx models [card=1,autodetected]
+
+If your card is listed as "board: UNKNOWN/GENERIC" it is unknown to
+the driver.  What to do then?
+
+1) Try upgrading to the latest snapshot, maybe it has been added
+   meanwhile.
+2) You can try to create a new entry yourself, have a look at
+   cx88-cards.c.  If that worked, mail me your changes as unified
+   diff ("diff -u").
+3) Or you can mail me the config information.  We need at least the
+   following information to add the card:
+
+     - the PCI Subsystem ID ("0070:3400" from the line above,
+       "lspci -v" output is fine too).
+     - the tuner type used by the card.  You can try to find one by
+       trial-and-error using the tuner=<n> insmod option.  If you
+       know which one the card has you can also have a look at the
+       list in CARDLIST.tuner
diff --git a/Documentation/admin-guide/media/davinci-vpbe.rst b/Documentation/admin-guide/media/davinci-vpbe.rst
new file mode 100644
index 000000000000..9e6360fd02db
--- /dev/null
+++ b/Documentation/admin-guide/media/davinci-vpbe.rst
@@ -0,0 +1,65 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+The VPBE V4L2 driver design
+===========================
+
+Functional partitioning
+-----------------------
+
+Consists of the following:
+
+ 1. V4L2 display driver
+
+    Implements creation of video2 and video3 device nodes and
+    provides v4l2 device interface to manage VID0 and VID1 layers.
+
+ 2. Display controller
+
+    Loads up VENC, OSD and external encoders such as ths8200. It provides
+    a set of API calls to V4L2 drivers to set the output/standards
+    in the VENC or external sub devices. It also provides
+    a device object to access the services from OSD subdevice
+    using sub device ops. The connection of external encoders to VENC LCD
+    controller port is done at init time based on default output and standard
+    selection or at run time when application change the output through
+    V4L2 IOCTLs.
+
+    When connected to an external encoder, vpbe controller is also responsible
+    for setting up the interface between VENC and external encoders based on
+    board specific settings (specified in board-xxx-evm.c). This allows
+    interfacing external encoders such as ths8200. The setup_if_config()
+    is implemented for this as well as configure_venc() (part of the next patch)
+    API to set timings in VENC for a specific display resolution. As of this
+    patch series, the interconnection and enabling and setting of the external
+    encoders is not present, and would be a part of the next patch series.
+
+ 3. VENC subdevice module
+
+    Responsible for setting outputs provided through internal DACs and also
+    setting timings at LCD controller port when external encoders are connected
+    at the port or LCD panel timings required. When external encoder/LCD panel
+    is connected, the timings for a specific standard/preset is retrieved from
+    the board specific table and the values are used to set the timings in
+    venc using non-standard timing mode.
+
+    Support LCD Panel displays using the VENC. For example to support a Logic
+    PD display, it requires setting up the LCD controller port with a set of
+    timings for the resolution supported and setting the dot clock. So we could
+    add the available outputs as a board specific entry (i.e add the "LogicPD"
+    output name to board-xxx-evm.c). A table of timings for various LCDs
+    supported can be maintained in the board specific setup file to support
+    various LCD displays.As of this patch a basic driver is present, and this
+    support for external encoders and displays forms a part of the next
+    patch series.
+
+ 4. OSD module
+
+    OSD module implements all OSD layer management and hardware specific
+    features. The VPBE module interacts with the OSD for enabling and
+    disabling appropriate features of the OSD.
+
+Current status
+--------------
+
+A fully functional working version of the V4L2 driver is available. This
+driver has been tested with NTSC and PAL standards and buffer streaming.
diff --git a/Documentation/admin-guide/media/dvb_intro.rst b/Documentation/admin-guide/media/dvb_intro.rst
new file mode 100644
index 000000000000..44eac9b3be6c
--- /dev/null
+++ b/Documentation/admin-guide/media/dvb_intro.rst
@@ -0,0 +1,616 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+==============================
+Using the Digital TV Framework
+==============================
+
+Introduction
+~~~~~~~~~~~~
+
+One significant difference between Digital TV and Analogue TV that the
+unwary (like myself) should consider is that, although the component
+structure of DVB-T cards are substantially similar to Analogue TV cards,
+they function in substantially different ways.
+
+The purpose of an Analogue TV is to receive and display an Analogue
+Television signal. An Analogue TV signal (otherwise known as composite
+video) is an analogue encoding of a sequence of image frames (25 frames
+per second in Europe) rasterised using an interlacing technique.
+Interlacing takes two fields to represent one frame. Therefore, an
+Analogue TV card for a PC has the following purpose:
+
+* Tune the receiver to receive a broadcast signal
+* demodulate the broadcast signal
+* demultiplex the analogue video signal and analogue audio
+  signal.
+
+  .. note::
+
+     some countries employ a digital audio signal
+     embedded within the modulated composite analogue signal -
+     using NICAM signaling.)
+
+* digitize the analogue video signal and make the resulting datastream
+  available to the data bus.
+
+The digital datastream from an Analogue TV card is generated by
+circuitry on the card and is often presented uncompressed. For a PAL TV
+signal encoded at a resolution of 768x576 24-bit color pixels over 25
+frames per second - a fair amount of data is generated and must be
+processed by the PC before it can be displayed on the video monitor
+screen. Some Analogue TV cards for PCs have onboard MPEG2 encoders which
+permit the raw digital data stream to be presented to the PC in an
+encoded and compressed form - similar to the form that is used in
+Digital TV.
+
+The purpose of a simple budget digital TV card (DVB-T,C or S) is to
+simply:
+
+* Tune the received to receive a broadcast signal. * Extract the encoded
+  digital datastream from the broadcast signal.
+* Make the encoded digital datastream (MPEG2) available to the data bus.
+
+The significant difference between the two is that the tuner on the
+analogue TV card spits out an Analogue signal, whereas the tuner on the
+digital TV card spits out a compressed encoded digital datastream. As
+the signal is already digitised, it is trivial to pass this datastream
+to the PC databus with minimal additional processing and then extract
+the digital video and audio datastreams passing them to the appropriate
+software or hardware for decoding and viewing.
+
+Getting the card going
+~~~~~~~~~~~~~~~~~~~~~~
+
+The Device Driver API for DVB under Linux will the following
+device nodes via the devfs filesystem:
+
+* /dev/dvb/adapter0/demux0
+* /dev/dvb/adapter0/dvr0
+* /dev/dvb/adapter0/frontend0
+
+The ``/dev/dvb/adapter0/dvr0`` device node is used to read the MPEG2
+Data Stream and the ``/dev/dvb/adapter0/frontend0`` device node is used
+to tune the frontend tuner module. The ``/dev/dvb/adapter0/demux0`` is
+used to control what programs will be received.
+
+Depending on the card's feature set, the Device Driver API could also
+expose other device nodes:
+
+* /dev/dvb/adapter0/ca0
+* /dev/dvb/adapter0/audio0
+* /dev/dvb/adapter0/net0
+* /dev/dvb/adapter0/osd0
+* /dev/dvb/adapter0/video0
+
+The ``/dev/dvb/adapter0/ca0`` is used to decode encrypted channels. The
+other device nodes are found only on devices that use the av7110
+driver, with is now obsoleted, together with the extra API whose such
+devices use.
+
+Receiving a digital TV channel
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This section attempts to explain how it works and how this affects the
+configuration of a Digital TV card.
+
+On this example, we're considering tuning into DVB-T channels in
+Australia, at the Melbourne region.
+
+The frequencies broadcast by Mount Dandenong transmitters are,
+currently:
+
+Table 1. Transponder Frequencies Mount Dandenong, Vic, Aus.
+
+===========	===========
+Broadcaster	Frequency
+===========	===========
+Seven		177.500 Mhz
+SBS		184.500 Mhz
+Nine		191.625 Mhz
+Ten		219.500 Mhz
+ABC		226.500 Mhz
+Channel 31	557.625 Mhz
+===========	===========
+
+The digital TV Scan utilities (like dvbv5-scan) have use a set of
+compiled-in defaults for various countries and regions. Those are
+currently provided as a separate package, called dtv-scan-tables. It's
+git tree is located at LinuxTV.org:
+
+    https://git.linuxtv.org/dtv-scan-tables.git/
+
+If none of the tables there suit, you can specify a data file on the
+command line which contains the transponder frequencies. Here is a
+sample file for the above channel transponders, in the old "channel"
+format::
+
+	# Data file for DVB scan program
+	#
+	# C Frequency SymbolRate FEC QAM
+	# S Frequency Polarisation SymbolRate FEC
+	# T Frequency Bandwidth FEC FEC2 QAM Mode Guard Hier
+
+	T 177500000 7MHz AUTO AUTO QAM64 8k 1/16 NONE
+	T 184500000 7MHz AUTO AUTO QAM64 8k 1/8 NONE
+	T 191625000 7MHz AUTO AUTO QAM64 8k 1/16 NONE
+	T 219500000 7MHz AUTO AUTO QAM64 8k 1/16 NONE
+	T 226500000 7MHz AUTO AUTO QAM64 8k 1/16 NONE
+	T 557625000 7MHz AUTO AUTO QPSK 8k 1/16 NONE
+
+Nowadays, we prefer to use a newer format, with is more verbose and easier
+to understand. With the new format, the "Seven" channel transponder's
+data is represented by::
+
+	[Seven]
+		DELIVERY_SYSTEM = DVBT
+		FREQUENCY = 177500000
+		BANDWIDTH_HZ = 7000000
+		CODE_RATE_HP = AUTO
+		CODE_RATE_LP = AUTO
+		MODULATION = QAM/64
+		TRANSMISSION_MODE = 8K
+		GUARD_INTERVAL = 1/16
+		HIERARCHY = NONE
+		INVERSION = AUTO
+
+For an updated version of the complete table, please see:
+
+    https://git.linuxtv.org/dtv-scan-tables.git/tree/dvb-t/au-Melbourne
+
+When the Digital TV scanning utility runs, it will output a file
+containing the information for all the audio and video programs that
+exists into each channel's transponders which the card's frontend can
+lock onto. (i.e. any whose signal is strong enough at your antenna).
+
+Here's the output of the dvbv5 tools from a channel scan took from
+Melburne::
+
+    [ABC HDTV]
+	    SERVICE_ID = 560
+	    VIDEO_PID = 2307
+	    AUDIO_PID = 0
+	    DELIVERY_SYSTEM = DVBT
+	    FREQUENCY = 226500000
+	    INVERSION = OFF
+	    BANDWIDTH_HZ = 7000000
+	    CODE_RATE_HP = 3/4
+	    CODE_RATE_LP = 3/4
+	    MODULATION = QAM/64
+	    TRANSMISSION_MODE = 8K
+	    GUARD_INTERVAL = 1/16
+	    HIERARCHY = NONE
+
+    [ABC TV Melbourne]
+	    SERVICE_ID = 561
+	    VIDEO_PID = 512
+	    AUDIO_PID = 650
+	    DELIVERY_SYSTEM = DVBT
+	    FREQUENCY = 226500000
+	    INVERSION = OFF
+	    BANDWIDTH_HZ = 7000000
+	    CODE_RATE_HP = 3/4
+	    CODE_RATE_LP = 3/4
+	    MODULATION = QAM/64
+	    TRANSMISSION_MODE = 8K
+	    GUARD_INTERVAL = 1/16
+	    HIERARCHY = NONE
+
+    [ABC TV 2]
+	    SERVICE_ID = 562
+	    VIDEO_PID = 512
+	    AUDIO_PID = 650
+	    DELIVERY_SYSTEM = DVBT
+	    FREQUENCY = 226500000
+	    INVERSION = OFF
+	    BANDWIDTH_HZ = 7000000
+	    CODE_RATE_HP = 3/4
+	    CODE_RATE_LP = 3/4
+	    MODULATION = QAM/64
+	    TRANSMISSION_MODE = 8K
+	    GUARD_INTERVAL = 1/16
+	    HIERARCHY = NONE
+
+    [ABC TV 3]
+	    SERVICE_ID = 563
+	    VIDEO_PID = 512
+	    AUDIO_PID = 650
+	    DELIVERY_SYSTEM = DVBT
+	    FREQUENCY = 226500000
+	    INVERSION = OFF
+	    BANDWIDTH_HZ = 7000000
+	    CODE_RATE_HP = 3/4
+	    CODE_RATE_LP = 3/4
+	    MODULATION = QAM/64
+	    TRANSMISSION_MODE = 8K
+	    GUARD_INTERVAL = 1/16
+	    HIERARCHY = NONE
+
+    [ABC TV 4]
+	    SERVICE_ID = 564
+	    VIDEO_PID = 512
+	    AUDIO_PID = 650
+	    DELIVERY_SYSTEM = DVBT
+	    FREQUENCY = 226500000
+	    INVERSION = OFF
+	    BANDWIDTH_HZ = 7000000
+	    CODE_RATE_HP = 3/4
+	    CODE_RATE_LP = 3/4
+	    MODULATION = QAM/64
+	    TRANSMISSION_MODE = 8K
+	    GUARD_INTERVAL = 1/16
+	    HIERARCHY = NONE
+
+    [ABC DiG Radio]
+	    SERVICE_ID = 566
+	    VIDEO_PID = 0
+	    AUDIO_PID = 2311
+	    DELIVERY_SYSTEM = DVBT
+	    FREQUENCY = 226500000
+	    INVERSION = OFF
+	    BANDWIDTH_HZ = 7000000
+	    CODE_RATE_HP = 3/4
+	    CODE_RATE_LP = 3/4
+	    MODULATION = QAM/64
+	    TRANSMISSION_MODE = 8K
+	    GUARD_INTERVAL = 1/16
+	    HIERARCHY = NONE
+
+    [TEN Digital]
+	    SERVICE_ID = 1585
+	    VIDEO_PID = 512
+	    AUDIO_PID = 650
+	    DELIVERY_SYSTEM = DVBT
+	    FREQUENCY = 219500000
+	    INVERSION = OFF
+	    BANDWIDTH_HZ = 7000000
+	    CODE_RATE_HP = 3/4
+	    CODE_RATE_LP = 1/2
+	    MODULATION = QAM/64
+	    TRANSMISSION_MODE = 8K
+	    GUARD_INTERVAL = 1/16
+	    HIERARCHY = NONE
+
+    [TEN Digital 1]
+	    SERVICE_ID = 1586
+	    VIDEO_PID = 512
+	    AUDIO_PID = 650
+	    DELIVERY_SYSTEM = DVBT
+	    FREQUENCY = 219500000
+	    INVERSION = OFF
+	    BANDWIDTH_HZ = 7000000
+	    CODE_RATE_HP = 3/4
+	    CODE_RATE_LP = 1/2
+	    MODULATION = QAM/64
+	    TRANSMISSION_MODE = 8K
+	    GUARD_INTERVAL = 1/16
+	    HIERARCHY = NONE
+
+    [TEN Digital 2]
+	    SERVICE_ID = 1587
+	    VIDEO_PID = 512
+	    AUDIO_PID = 650
+	    DELIVERY_SYSTEM = DVBT
+	    FREQUENCY = 219500000
+	    INVERSION = OFF
+	    BANDWIDTH_HZ = 7000000
+	    CODE_RATE_HP = 3/4
+	    CODE_RATE_LP = 1/2
+	    MODULATION = QAM/64
+	    TRANSMISSION_MODE = 8K
+	    GUARD_INTERVAL = 1/16
+	    HIERARCHY = NONE
+
+    [TEN Digital 3]
+	    SERVICE_ID = 1588
+	    VIDEO_PID = 512
+	    AUDIO_PID = 650
+	    DELIVERY_SYSTEM = DVBT
+	    FREQUENCY = 219500000
+	    INVERSION = OFF
+	    BANDWIDTH_HZ = 7000000
+	    CODE_RATE_HP = 3/4
+	    CODE_RATE_LP = 1/2
+	    MODULATION = QAM/64
+	    TRANSMISSION_MODE = 8K
+	    GUARD_INTERVAL = 1/16
+	    HIERARCHY = NONE
+
+    [TEN Digital]
+	    SERVICE_ID = 1589
+	    VIDEO_PID = 512
+	    AUDIO_PID = 650
+	    DELIVERY_SYSTEM = DVBT
+	    FREQUENCY = 219500000
+	    INVERSION = OFF
+	    BANDWIDTH_HZ = 7000000
+	    CODE_RATE_HP = 3/4
+	    CODE_RATE_LP = 1/2
+	    MODULATION = QAM/64
+	    TRANSMISSION_MODE = 8K
+	    GUARD_INTERVAL = 1/16
+	    HIERARCHY = NONE
+
+    [TEN Digital 4]
+	    SERVICE_ID = 1590
+	    VIDEO_PID = 512
+	    AUDIO_PID = 650
+	    DELIVERY_SYSTEM = DVBT
+	    FREQUENCY = 219500000
+	    INVERSION = OFF
+	    BANDWIDTH_HZ = 7000000
+	    CODE_RATE_HP = 3/4
+	    CODE_RATE_LP = 1/2
+	    MODULATION = QAM/64
+	    TRANSMISSION_MODE = 8K
+	    GUARD_INTERVAL = 1/16
+	    HIERARCHY = NONE
+
+    [TEN Digital]
+	    SERVICE_ID = 1591
+	    VIDEO_PID = 512
+	    AUDIO_PID = 650
+	    DELIVERY_SYSTEM = DVBT
+	    FREQUENCY = 219500000
+	    INVERSION = OFF
+	    BANDWIDTH_HZ = 7000000
+	    CODE_RATE_HP = 3/4
+	    CODE_RATE_LP = 1/2
+	    MODULATION = QAM/64
+	    TRANSMISSION_MODE = 8K
+	    GUARD_INTERVAL = 1/16
+	    HIERARCHY = NONE
+
+    [TEN HD]
+	    SERVICE_ID = 1592
+	    VIDEO_PID = 514
+	    AUDIO_PID = 0
+	    DELIVERY_SYSTEM = DVBT
+	    FREQUENCY = 219500000
+	    INVERSION = OFF
+	    BANDWIDTH_HZ = 7000000
+	    CODE_RATE_HP = 3/4
+	    CODE_RATE_LP = 1/2
+	    MODULATION = QAM/64
+	    TRANSMISSION_MODE = 8K
+	    GUARD_INTERVAL = 1/16
+	    HIERARCHY = NONE
+
+    [TEN Digital]
+	    SERVICE_ID = 1593
+	    VIDEO_PID = 512
+	    AUDIO_PID = 650
+	    DELIVERY_SYSTEM = DVBT
+	    FREQUENCY = 219500000
+	    INVERSION = OFF
+	    BANDWIDTH_HZ = 7000000
+	    CODE_RATE_HP = 3/4
+	    CODE_RATE_LP = 1/2
+	    MODULATION = QAM/64
+	    TRANSMISSION_MODE = 8K
+	    GUARD_INTERVAL = 1/16
+	    HIERARCHY = NONE
+
+    [Nine Digital]
+	    SERVICE_ID = 1072
+	    VIDEO_PID = 513
+	    AUDIO_PID = 660
+	    DELIVERY_SYSTEM = DVBT
+	    FREQUENCY = 191625000
+	    INVERSION = OFF
+	    BANDWIDTH_HZ = 7000000
+	    CODE_RATE_HP = 3/4
+	    CODE_RATE_LP = 1/2
+	    MODULATION = QAM/64
+	    TRANSMISSION_MODE = 8K
+	    GUARD_INTERVAL = 1/16
+	    HIERARCHY = NONE
+
+    [Nine Digital HD]
+	    SERVICE_ID = 1073
+	    VIDEO_PID = 512
+	    AUDIO_PID = 0
+	    DELIVERY_SYSTEM = DVBT
+	    FREQUENCY = 191625000
+	    INVERSION = OFF
+	    BANDWIDTH_HZ = 7000000
+	    CODE_RATE_HP = 3/4
+	    CODE_RATE_LP = 1/2
+	    MODULATION = QAM/64
+	    TRANSMISSION_MODE = 8K
+	    GUARD_INTERVAL = 1/16
+	    HIERARCHY = NONE
+
+    [Nine Guide]
+	    SERVICE_ID = 1074
+	    VIDEO_PID = 514
+	    AUDIO_PID = 670
+	    DELIVERY_SYSTEM = DVBT
+	    FREQUENCY = 191625000
+	    INVERSION = OFF
+	    BANDWIDTH_HZ = 7000000
+	    CODE_RATE_HP = 3/4
+	    CODE_RATE_LP = 1/2
+	    MODULATION = QAM/64
+	    TRANSMISSION_MODE = 8K
+	    GUARD_INTERVAL = 1/16
+	    HIERARCHY = NONE
+
+    [7 Digital]
+	    SERVICE_ID = 1328
+	    VIDEO_PID = 769
+	    AUDIO_PID = 770
+	    DELIVERY_SYSTEM = DVBT
+	    FREQUENCY = 177500000
+	    INVERSION = OFF
+	    BANDWIDTH_HZ = 7000000
+	    CODE_RATE_HP = 2/3
+	    CODE_RATE_LP = 2/3
+	    MODULATION = QAM/64
+	    TRANSMISSION_MODE = 8K
+	    GUARD_INTERVAL = 1/8
+	    HIERARCHY = NONE
+
+    [7 Digital 1]
+	    SERVICE_ID = 1329
+	    VIDEO_PID = 769
+	    AUDIO_PID = 770
+	    DELIVERY_SYSTEM = DVBT
+	    FREQUENCY = 177500000
+	    INVERSION = OFF
+	    BANDWIDTH_HZ = 7000000
+	    CODE_RATE_HP = 2/3
+	    CODE_RATE_LP = 2/3
+	    MODULATION = QAM/64
+	    TRANSMISSION_MODE = 8K
+	    GUARD_INTERVAL = 1/8
+	    HIERARCHY = NONE
+
+    [7 Digital 2]
+	    SERVICE_ID = 1330
+	    VIDEO_PID = 769
+	    AUDIO_PID = 770
+	    DELIVERY_SYSTEM = DVBT
+	    FREQUENCY = 177500000
+	    INVERSION = OFF
+	    BANDWIDTH_HZ = 7000000
+	    CODE_RATE_HP = 2/3
+	    CODE_RATE_LP = 2/3
+	    MODULATION = QAM/64
+	    TRANSMISSION_MODE = 8K
+	    GUARD_INTERVAL = 1/8
+	    HIERARCHY = NONE
+
+    [7 Digital 3]
+	    SERVICE_ID = 1331
+	    VIDEO_PID = 769
+	    AUDIO_PID = 770
+	    DELIVERY_SYSTEM = DVBT
+	    FREQUENCY = 177500000
+	    INVERSION = OFF
+	    BANDWIDTH_HZ = 7000000
+	    CODE_RATE_HP = 2/3
+	    CODE_RATE_LP = 2/3
+	    MODULATION = QAM/64
+	    TRANSMISSION_MODE = 8K
+	    GUARD_INTERVAL = 1/8
+	    HIERARCHY = NONE
+
+    [7 HD Digital]
+	    SERVICE_ID = 1332
+	    VIDEO_PID = 833
+	    AUDIO_PID = 834
+	    DELIVERY_SYSTEM = DVBT
+	    FREQUENCY = 177500000
+	    INVERSION = OFF
+	    BANDWIDTH_HZ = 7000000
+	    CODE_RATE_HP = 2/3
+	    CODE_RATE_LP = 2/3
+	    MODULATION = QAM/64
+	    TRANSMISSION_MODE = 8K
+	    GUARD_INTERVAL = 1/8
+	    HIERARCHY = NONE
+
+    [7 Program Guide]
+	    SERVICE_ID = 1334
+	    VIDEO_PID = 865
+	    AUDIO_PID = 866
+	    DELIVERY_SYSTEM = DVBT
+	    FREQUENCY = 177500000
+	    INVERSION = OFF
+	    BANDWIDTH_HZ = 7000000
+	    CODE_RATE_HP = 2/3
+	    CODE_RATE_LP = 2/3
+	    MODULATION = QAM/64
+	    TRANSMISSION_MODE = 8K
+	    GUARD_INTERVAL = 1/8
+	    HIERARCHY = NONE
+
+    [SBS HD]
+	    SERVICE_ID = 784
+	    VIDEO_PID = 102
+	    AUDIO_PID = 103
+	    DELIVERY_SYSTEM = DVBT
+	    FREQUENCY = 536500000
+	    INVERSION = OFF
+	    BANDWIDTH_HZ = 7000000
+	    CODE_RATE_HP = 2/3
+	    CODE_RATE_LP = 2/3
+	    MODULATION = QAM/64
+	    TRANSMISSION_MODE = 8K
+	    GUARD_INTERVAL = 1/8
+	    HIERARCHY = NONE
+
+    [SBS DIGITAL 1]
+	    SERVICE_ID = 785
+	    VIDEO_PID = 161
+	    AUDIO_PID = 81
+	    DELIVERY_SYSTEM = DVBT
+	    FREQUENCY = 536500000
+	    INVERSION = OFF
+	    BANDWIDTH_HZ = 7000000
+	    CODE_RATE_HP = 2/3
+	    CODE_RATE_LP = 2/3
+	    MODULATION = QAM/64
+	    TRANSMISSION_MODE = 8K
+	    GUARD_INTERVAL = 1/8
+	    HIERARCHY = NONE
+
+    [SBS DIGITAL 2]
+	    SERVICE_ID = 786
+	    VIDEO_PID = 162
+	    AUDIO_PID = 83
+	    DELIVERY_SYSTEM = DVBT
+	    FREQUENCY = 536500000
+	    INVERSION = OFF
+	    BANDWIDTH_HZ = 7000000
+	    CODE_RATE_HP = 2/3
+	    CODE_RATE_LP = 2/3
+	    MODULATION = QAM/64
+	    TRANSMISSION_MODE = 8K
+	    GUARD_INTERVAL = 1/8
+	    HIERARCHY = NONE
+
+    [SBS EPG]
+	    SERVICE_ID = 787
+	    VIDEO_PID = 163
+	    AUDIO_PID = 85
+	    DELIVERY_SYSTEM = DVBT
+	    FREQUENCY = 536500000
+	    INVERSION = OFF
+	    BANDWIDTH_HZ = 7000000
+	    CODE_RATE_HP = 2/3
+	    CODE_RATE_LP = 2/3
+	    MODULATION = QAM/64
+	    TRANSMISSION_MODE = 8K
+	    GUARD_INTERVAL = 1/8
+	    HIERARCHY = NONE
+
+    [SBS RADIO 1]
+	    SERVICE_ID = 798
+	    VIDEO_PID = 0
+	    AUDIO_PID = 201
+	    DELIVERY_SYSTEM = DVBT
+	    FREQUENCY = 536500000
+	    INVERSION = OFF
+	    BANDWIDTH_HZ = 7000000
+	    CODE_RATE_HP = 2/3
+	    CODE_RATE_LP = 2/3
+	    MODULATION = QAM/64
+	    TRANSMISSION_MODE = 8K
+	    GUARD_INTERVAL = 1/8
+	    HIERARCHY = NONE
+
+    [SBS RADIO 2]
+	    SERVICE_ID = 799
+	    VIDEO_PID = 0
+	    AUDIO_PID = 202
+	    DELIVERY_SYSTEM = DVBT
+	    FREQUENCY = 536500000
+	    INVERSION = OFF
+	    BANDWIDTH_HZ = 7000000
+	    CODE_RATE_HP = 2/3
+	    CODE_RATE_LP = 2/3
+	    MODULATION = QAM/64
+	    TRANSMISSION_MODE = 8K
+	    GUARD_INTERVAL = 1/8
+	    HIERARCHY = NONE
diff --git a/Documentation/admin-guide/media/dvb_references.rst b/Documentation/admin-guide/media/dvb_references.rst
new file mode 100644
index 000000000000..48445ac76275
--- /dev/null
+++ b/Documentation/admin-guide/media/dvb_references.rst
@@ -0,0 +1,29 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+References
+==========
+
+The main development site and GIT repository for Digital TV
+drivers is https://linuxtv.org.
+
+The DVB mailing list linux-dvb is hosted at vger. Please see
+http://vger.kernel.org/vger-lists.html#linux-media for details.
+
+There are also some other old lists hosted at:
+https://linuxtv.org/lists.php. If you're insterested on that for historic
+reasons, please check the archive at https://linuxtv.org/pipermail/linux-dvb/.
+
+The media subsystem Wiki is hosted at https://linuxtv.org/wiki/.
+There, you'll find lots of information, from both development and usage
+of media boards. Please check it before asking newbie questions on the
+mailing list or IRC channels.
+
+The API documentation is documented at the Kernel tree. You can find it
+in both html and pdf formats, together with other useful documentation at:
+
+  - https://linuxtv.org/docs.php.
+
+You may also find useful material at https://linuxtv.org/downloads/.
+
+In order to get the needed firmware for some drivers to work, there's
+a script at the kernel tree, at scripts/get_dvb_firmware.
diff --git a/Documentation/admin-guide/media/em28xx-cardlist.rst b/Documentation/admin-guide/media/em28xx-cardlist.rst
new file mode 100644
index 000000000000..cb2e693a56a2
--- /dev/null
+++ b/Documentation/admin-guide/media/em28xx-cardlist.rst
@@ -0,0 +1,432 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+EM28xx cards list
+=================
+
+.. tabularcolumns:: |p{1.4cm}|p{10.0cm}|p{1.9cm}|p{4.2cm}|
+
+.. flat-table::
+   :header-rows: 1
+   :widths: 2 12 3 16
+   :stub-columns: 0
+
+   * - Card number
+     - Card name
+     - Empia Chip
+     - USB IDs
+   * - 0
+     - Unknown EM2800 video grabber
+     - em2800
+     - eb1a:2800
+   * - 1
+     - Unknown EM2750/28xx video grabber
+     - em2820 or em2840
+     - eb1a:2710, eb1a:2820, eb1a:2821, eb1a:2860, eb1a:2861, eb1a:2862, eb1a:2863, eb1a:2870, eb1a:2881, eb1a:2883, eb1a:2868, eb1a:2875
+   * - 2
+     - Terratec Cinergy 250 USB
+     - em2820 or em2840
+     - 0ccd:0036
+   * - 3
+     - Pinnacle PCTV USB 2
+     - em2820 or em2840
+     - 2304:0208
+   * - 4
+     - Hauppauge WinTV USB 2
+     - em2820 or em2840
+     - 2040:4200, 2040:4201
+   * - 5
+     - MSI VOX USB 2.0
+     - em2820 or em2840
+     -
+   * - 6
+     - Terratec Cinergy 200 USB
+     - em2800
+     -
+   * - 7
+     - Leadtek Winfast USB II
+     - em2800
+     - 0413:6023
+   * - 8
+     - Kworld USB2800
+     - em2800
+     -
+   * - 9
+     - Pinnacle Dazzle DVC 90/100/101/107 / Kaiser Baas Video to DVD maker / Kworld DVD Maker 2 / Plextor ConvertX PX-AV100U
+     - em2820 or em2840
+     - 1b80:e302, 1b80:e304, 2304:0207, 2304:021a, 093b:a003
+   * - 10
+     - Hauppauge WinTV HVR 900
+     - em2880
+     - 2040:6500
+   * - 11
+     - Terratec Hybrid XS
+     - em2880
+     -
+   * - 12
+     - Kworld PVR TV 2800 RF
+     - em2820 or em2840
+     -
+   * - 13
+     - Terratec Prodigy XS
+     - em2880
+     -
+   * - 14
+     - SIIG AVTuner-PVR / Pixelview Prolink PlayTV USB 2.0
+     - em2820 or em2840
+     -
+   * - 15
+     - V-Gear PocketTV
+     - em2800
+     -
+   * - 16
+     - Hauppauge WinTV HVR 950
+     - em2883
+     - 2040:6513, 2040:6517, 2040:651b
+   * - 17
+     - Pinnacle PCTV HD Pro Stick
+     - em2880
+     - 2304:0227
+   * - 18
+     - Hauppauge WinTV HVR 900 (R2)
+     - em2880
+     - 2040:6502
+   * - 19
+     - EM2860/SAA711X Reference Design
+     - em2860
+     -
+   * - 20
+     - AMD ATI TV Wonder HD 600
+     - em2880
+     - 0438:b002
+   * - 21
+     - eMPIA Technology, Inc. GrabBeeX+ Video Encoder
+     - em2800
+     - eb1a:2801
+   * - 22
+     - EM2710/EM2750/EM2751 webcam grabber
+     - em2750
+     - eb1a:2750, eb1a:2751
+   * - 23
+     - Huaqi DLCW-130
+     - em2750
+     -
+   * - 24
+     - D-Link DUB-T210 TV Tuner
+     - em2820 or em2840
+     - 2001:f112
+   * - 25
+     - Gadmei UTV310
+     - em2820 or em2840
+     -
+   * - 26
+     - Hercules Smart TV USB 2.0
+     - em2820 or em2840
+     -
+   * - 27
+     - Pinnacle PCTV USB 2 (Philips FM1216ME)
+     - em2820 or em2840
+     -
+   * - 28
+     - Leadtek Winfast USB II Deluxe
+     - em2820 or em2840
+     -
+   * - 29
+     - EM2860/TVP5150 Reference Design
+     - em2860
+     - eb1a:5051
+   * - 30
+     - Videology 20K14XUSB USB2.0
+     - em2820 or em2840
+     -
+   * - 31
+     - Usbgear VD204v9
+     - em2821
+     -
+   * - 32
+     - Supercomp USB 2.0 TV
+     - em2821
+     -
+   * - 33
+     - Elgato Video Capture
+     - em2860
+     - 0fd9:0033
+   * - 34
+     - Terratec Cinergy A Hybrid XS
+     - em2860
+     - 0ccd:004f
+   * - 35
+     - Typhoon DVD Maker
+     - em2860
+     -
+   * - 36
+     - NetGMBH Cam
+     - em2860
+     -
+   * - 37
+     - Gadmei UTV330
+     - em2860
+     - eb1a:50a6
+   * - 38
+     - Yakumo MovieMixer
+     - em2861
+     -
+   * - 39
+     - KWorld PVRTV 300U
+     - em2861
+     - eb1a:e300
+   * - 40
+     - Plextor ConvertX PX-TV100U
+     - em2861
+     - 093b:a005
+   * - 41
+     - Kworld 350 U DVB-T
+     - em2870
+     - eb1a:e350
+   * - 42
+     - Kworld 355 U DVB-T
+     - em2870
+     - eb1a:e355, eb1a:e357, eb1a:e359
+   * - 43
+     - Terratec Cinergy T XS
+     - em2870
+     -
+   * - 44
+     - Terratec Cinergy T XS (MT2060)
+     - em2870
+     - 0ccd:0043
+   * - 45
+     - Pinnacle PCTV DVB-T
+     - em2870
+     -
+   * - 46
+     - Compro, VideoMate U3
+     - em2870
+     - 185b:2870
+   * - 47
+     - KWorld DVB-T 305U
+     - em2880
+     - eb1a:e305
+   * - 48
+     - KWorld DVB-T 310U
+     - em2880
+     -
+   * - 49
+     - MSI DigiVox A/D
+     - em2880
+     - eb1a:e310
+   * - 50
+     - MSI DigiVox A/D II
+     - em2880
+     - eb1a:e320
+   * - 51
+     - Terratec Hybrid XS Secam
+     - em2880
+     - 0ccd:004c
+   * - 52
+     - DNT DA2 Hybrid
+     - em2881
+     -
+   * - 53
+     - Pinnacle Hybrid Pro
+     - em2881
+     -
+   * - 54
+     - Kworld VS-DVB-T 323UR
+     - em2882
+     - eb1a:e323
+   * - 55
+     - Terratec Cinergy Hybrid T USB XS (em2882)
+     - em2882
+     - 0ccd:005e, 0ccd:0042
+   * - 56
+     - Pinnacle Hybrid Pro (330e)
+     - em2882
+     - 2304:0226
+   * - 57
+     - Kworld PlusTV HD Hybrid 330
+     - em2883
+     - eb1a:a316
+   * - 58
+     - Compro VideoMate ForYou/Stereo
+     - em2820 or em2840
+     - 185b:2041
+   * - 59
+     - Pinnacle PCTV HD Mini
+     - em2874
+     - 2304:023f
+   * - 60
+     - Hauppauge WinTV HVR 850
+     - em2883
+     - 2040:651f
+   * - 61
+     - Pixelview PlayTV Box 4 USB 2.0
+     - em2820 or em2840
+     -
+   * - 62
+     - Gadmei TVR200
+     - em2820 or em2840
+     -
+   * - 63
+     - Kaiomy TVnPC U2
+     - em2860
+     - eb1a:e303
+   * - 64
+     - Easy Cap Capture DC-60
+     - em2860
+     - 1b80:e309
+   * - 65
+     - IO-DATA GV-MVP/SZ
+     - em2820 or em2840
+     - 04bb:0515
+   * - 66
+     - Empire dual TV
+     - em2880
+     -
+   * - 67
+     - Terratec Grabby
+     - em2860
+     - 0ccd:0096, 0ccd:10AF
+   * - 68
+     - Terratec AV350
+     - em2860
+     - 0ccd:0084
+   * - 69
+     - KWorld ATSC 315U HDTV TV Box
+     - em2882
+     - eb1a:a313
+   * - 70
+     - Evga inDtube
+     - em2882
+     -
+   * - 71
+     - Silvercrest Webcam 1.3mpix
+     - em2820 or em2840
+     -
+   * - 72
+     - Gadmei UTV330+
+     - em2861
+     -
+   * - 73
+     - Reddo DVB-C USB TV Box
+     - em2870
+     -
+   * - 74
+     - Actionmaster/LinXcel/Digitus VC211A
+     - em2800
+     -
+   * - 75
+     - Dikom DK300
+     - em2882
+     -
+   * - 76
+     - KWorld PlusTV 340U or UB435-Q (ATSC)
+     - em2870
+     - 1b80:a340
+   * - 77
+     - EM2874 Leadership ISDBT
+     - em2874
+     -
+   * - 78
+     - PCTV nanoStick T2 290e
+     - em28174
+     - 2013:024f
+   * - 79
+     - Terratec Cinergy H5
+     - em2884
+     - eb1a:2885, 0ccd:10a2, 0ccd:10ad, 0ccd:10b6
+   * - 80
+     - PCTV DVB-S2 Stick (460e)
+     - em28174
+     - 2013:024c
+   * - 81
+     - Hauppauge WinTV HVR 930C
+     - em2884
+     - 2040:1605
+   * - 82
+     - Terratec Cinergy HTC Stick
+     - em2884
+     - 0ccd:00b2
+   * - 83
+     - Honestech Vidbox NW03
+     - em2860
+     - eb1a:5006
+   * - 84
+     - MaxMedia UB425-TC
+     - em2874
+     - 1b80:e425
+   * - 85
+     - PCTV QuatroStick (510e)
+     - em2884
+     - 2304:0242
+   * - 86
+     - PCTV QuatroStick nano (520e)
+     - em2884
+     - 2013:0251
+   * - 87
+     - Terratec Cinergy HTC USB XS
+     - em2884
+     - 0ccd:008e, 0ccd:00ac
+   * - 88
+     - C3 Tech Digital Duo HDTV/SDTV USB
+     - em2884
+     - 1b80:e755
+   * - 89
+     - Delock 61959
+     - em2874
+     - 1b80:e1cc
+   * - 90
+     - KWorld USB ATSC TV Stick UB435-Q V2
+     - em2874
+     - 1b80:e346
+   * - 91
+     - SpeedLink Vicious And Devine Laplace webcam
+     - em2765
+     - 1ae7:9003, 1ae7:9004
+   * - 92
+     - PCTV DVB-S2 Stick (461e)
+     - em28178
+     - 2013:0258
+   * - 93
+     - KWorld USB ATSC TV Stick UB435-Q V3
+     - em2874
+     - 1b80:e34c
+   * - 94
+     - PCTV tripleStick (292e)
+     - em28178
+     - 2013:025f, 2013:0264, 2040:0264, 2040:8264, 2040:8268
+   * - 95
+     - Leadtek VC100
+     - em2861
+     - 0413:6f07
+   * - 96
+     - Terratec Cinergy T2 Stick HD
+     - em28178
+     - eb1a:8179
+   * - 97
+     - Elgato EyeTV Hybrid 2008 INT
+     - em2884
+     - 0fd9:0018
+   * - 98
+     - PLEX PX-BCUD
+     - em28178
+     - 3275:0085
+   * - 99
+     - Hauppauge WinTV-dualHD DVB
+     - em28174
+     - 2040:0265, 2040:8265
+   * - 100
+     - Hauppauge WinTV-dualHD 01595 ATSC/QAM
+     - em28174
+     - 2040:026d, 2040:826d
+   * - 101
+     - Terratec Cinergy H6 rev. 2
+     - em2884
+     - 0ccd:10b2
+   * - 102
+     - :ZOLID HYBRID TV STICK
+     - em2882
+     -
+   * - 103
+     - Magix USB Videowandler-2
+     - em2861
+     - 1b80:e349
diff --git a/Documentation/admin-guide/media/faq.rst b/Documentation/admin-guide/media/faq.rst
new file mode 100644
index 000000000000..b63548b6f313
--- /dev/null
+++ b/Documentation/admin-guide/media/faq.rst
@@ -0,0 +1,216 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+FAQ
+===
+
+.. note::
+
+     1. With Digital TV, a single physical channel may have different
+	contents inside it. The specs call each one as a *service*.
+	This is what a TV user would call "channel". So, in order to
+	avoid confusion, we're calling *transponders* as the physical
+	channel on this FAQ, and *services* for the logical channel.
+     2. The LinuxTV community maintains some Wiki pages with contain
+        a lot of information related to the media subsystem. If you
+        don't find an answer for your needs here, it is likely that
+        you'll be able to get something useful there. It is hosted
+	at:
+
+	https://www.linuxtv.org/wiki/
+
+Some very frequently asked questions about Linux Digital TV support
+
+1. The signal seems to die a few seconds after tuning.
+
+	It's not a bug, it's a feature. Because the frontends have
+	significant power requirements (and hence get very hot), they
+	are powered down if they are unused (i.e. if the frontend device
+	is closed). The ``dvb-core`` module parameter ``dvb_shutdown_timeout``
+	allow you to change the timeout (default 5 seconds). Setting the
+	timeout to 0 disables the timeout feature.
+
+2. How can I watch TV?
+
+	Together with the Linux Kernel, the Digital TV developers support
+	some simple utilities which are mainly intended for testing
+	and to demonstrate how the DVB API works. This is called DVB v5
+	tools and are grouped together with the ``v4l-utils`` git repository:
+
+	    https://git.linuxtv.org/v4l-utils.git/
+
+	You can find more information at the LinuxTV wiki:
+
+	    https://www.linuxtv.org/wiki/index.php/DVBv5_Tools
+
+	The first step is to get a list of services that are transmitted.
+
+	This is done by using several existing tools. You can use
+	for example the ``dvbv5-scan`` tool. You can find more information
+	about it at:
+
+	    https://www.linuxtv.org/wiki/index.php/Dvbv5-scan
+
+	There are some other applications like ``w_scan`` [#]_ that do a
+	blind scan, trying hard to find all possible channels, but
+	those consumes a large amount of time to run.
+
+	.. [#] https://www.linuxtv.org/wiki/index.php/W_scan
+
+	Also, some applications like ``kaffeine`` have their own code
+	to scan for services. So, you don't need to use an external
+	application to obtain such list.
+
+	Most of such tools need a file containing a list of channel
+	transponders available on your area. So, LinuxTV developers
+	maintain tables of Digital TV channel transponders, receiving
+	patches from the community to keep them updated.
+
+	This list is hosted at:
+
+	    https://git.linuxtv.org/dtv-scan-tables.git
+
+	And packaged on several distributions.
+
+	Kaffeine has some blind scan support for some terrestrial standards.
+	It also relies on DTV scan tables, although it contains a copy
+	of it internally (and, if requested by the user, it will download
+	newer versions of it).
+
+	If you are lucky you can just use one of the supplied channel
+	transponders. If not, you may need to seek for such info at
+	the Internet and create a new file. There are several sites with
+	contains physical channel lists. For cable and satellite, usually
+	knowing how to tune into a single channel is enough for the
+	scanning tool to identify the other channels. On some places,
+	this could also work for terrestrial transmissions.
+
+	Once you have a transponders list, you need to generate a services
+	list with a tool like ``dvbv5-scan``.
+
+	Almost all modern Digital TV cards don't have built-in hardware
+	MPEG-decoders. So, it is up to the application to get a MPEG-TS
+	stream provided by the board, split it into audio, video and other
+	data and decode.
+
+3. Which Digital TV applications exist?
+
+	Several media player applications are capable of tuning into
+	digital TV channels, including Kaffeine, Vlc, mplayer and MythTV.
+
+	Kaffeine aims to be very user-friendly, and it is maintained
+	by one of the Kernel driver developers.
+
+	A comprehensive list of those and other apps can be found at:
+
+	    https://www.linuxtv.org/wiki/index.php/TV_Related_Software
+
+	Some of the most popular ones are linked below:
+
+	https://kde.org/applications/multimedia/org.kde.kaffeine
+		KDE media player, focused on Digital TV support
+
+	https://www.linuxtv.org/vdrwiki/index.php/Main_Page
+		Klaus Schmidinger's Video Disk Recorder
+
+	https://linuxtv.org/downloads and https://git.linuxtv.org/
+		Digital TV and other media-related applications and
+		Kernel drivers. The ``v4l-utils`` package there contains
+		several swiss knife tools for using with Digital TV.
+
+	http://sourceforge.net/projects/dvbtools/
+		Dave Chapman's dvbtools package, including
+		dvbstream and dvbtune
+
+	http://www.dbox2.info/
+		LinuxDVB on the dBox2
+
+	http://www.tuxbox.org/
+		the TuxBox CVS many interesting DVB applications and the dBox2
+		DVB source
+
+	http://www.nenie.org/misc/mpsys/
+		MPSYS: a MPEG2 system library and tools
+
+	https://www.videolan.org/vlc/index.pt.html
+		Vlc
+
+	http://mplayerhq.hu/
+		MPlayer
+
+	http://xine.sourceforge.net/ and http://xinehq.de/
+		Xine
+
+	http://www.mythtv.org/
+		MythTV - analog TV and digital TV PVR
+
+	http://dvbsnoop.sourceforge.net/
+		DVB sniffer program to monitor, analyze, debug, dump
+		or view dvb/mpeg/dsm-cc/mhp stream information (TS,
+		PES, SECTION)
+
+4. Can't get a signal tuned correctly
+
+	That could be due to a lot of problems. On my personal experience,
+	usually TV cards need stronger signals than TV sets, and are more
+	sensitive to noise. So, perhaps you just need a better antenna or
+	cabling. Yet, it could also be some hardware or driver issue.
+
+	For example, if you are using a Technotrend/Hauppauge DVB-C card
+	*without* analog module, you might have to use module parameter
+	adac=-1 (dvb-ttpci.o).
+
+	Please see the FAQ page at linuxtv.org, as it could contain some
+	valuable information:
+
+	    https://www.linuxtv.org/wiki/index.php/FAQ_%26_Troubleshooting
+
+	If that doesn't work, check at the linux-media ML archives, to
+	see if someone else had a similar problem with your hardware
+	and/or digital TV service provider:
+
+	    https://lore.kernel.org/linux-media/
+
+	If none of this works, you can try sending an e-mail to the
+	linux-media ML and see if someone else could shed some light.
+	The e-mail is linux-media AT vger.kernel.org.
+
+5. The dvb_net device doesn't give me any packets at all
+
+	Run ``tcpdump`` on the ``dvb0_0`` interface. This sets the interface
+	into promiscuous mode so it accepts any packets from the PID
+	you have configured with the ``dvbnet`` utility. Check if there
+	are any packets with the IP addr and MAC addr you have
+	configured with ``ifconfig`` or with ``ip addr``.
+
+	If ``tcpdump`` doesn't give you any output, check the statistics
+	which ``ifconfig`` or ``netstat -ni`` outputs. (Note: If the MAC
+	address is wrong, ``dvb_net`` won't get any input; thus you have to
+	run ``tcpdump`` before checking the statistics.) If there are no
+	packets at all then maybe the PID is wrong. If there are error packets,
+	then either the PID is wrong or the stream does not conform to
+	the MPE standard (EN 301 192, http://www.etsi.org/). You can
+	use e.g. ``dvbsnoop`` for debugging.
+
+6. The ``dvb_net`` device doesn't give me any multicast packets
+
+	Check your routes if they include the multicast address range.
+	Additionally make sure that "source validation by reversed path
+	lookup" is disabled::
+
+	  $ "echo 0 > /proc/sys/net/ipv4/conf/dvb0/rp_filter"
+
+7. What are all those modules that need to be loaded?
+
+	In order to make it more flexible and support different hardware
+	combinations, the media subsystem is written on a modular way.
+
+	So, besides the Digital TV hardware module for the main chipset,
+	it also needs to load a frontend driver, plus the Digital TV
+	core. If the board also has remote controller, it will also
+	need the remote controller core and the remote controller tables.
+	The same happens if the board has support for analog TV: the
+	core support for video4linux need to be loaded.
+
+	The actual module names are Linux-kernel version specific, as,
+	from time to time, things change, in order to make the media
+	support more flexible.
diff --git a/Documentation/admin-guide/media/fimc.rst b/Documentation/admin-guide/media/fimc.rst
new file mode 100644
index 000000000000..0b8ddc4a3008
--- /dev/null
+++ b/Documentation/admin-guide/media/fimc.rst
@@ -0,0 +1,153 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: <isonum.txt>
+
+The Samsung S5P/EXYNOS4 FIMC driver
+===================================
+
+Copyright |copy| 2012 - 2013 Samsung Electronics Co., Ltd.
+
+The FIMC (Fully Interactive Mobile Camera) device available in Samsung
+SoC Application Processors is an integrated camera host interface, color
+space converter, image resizer and rotator.  It's also capable of capturing
+data from LCD controller (FIMD) through the SoC internal writeback data
+path.  There are multiple FIMC instances in the SoCs (up to 4), having
+slightly different capabilities, like pixel alignment constraints, rotator
+availability, LCD writeback support, etc. The driver is located at
+drivers/media/platform/exynos4-is directory.
+
+Supported SoCs
+--------------
+
+S5PC100 (mem-to-mem only), S5PV210, EXYNOS4210
+
+Supported features
+------------------
+
+- camera parallel interface capture (ITU-R.BT601/565);
+- camera serial interface capture (MIPI-CSI2);
+- memory-to-memory processing (color space conversion, scaling, mirror
+  and rotation);
+- dynamic pipeline re-configuration at runtime (re-attachment of any FIMC
+  instance to any parallel video input or any MIPI-CSI front-end);
+- runtime PM and system wide suspend/resume
+
+Not currently supported
+-----------------------
+
+- LCD writeback input
+- per frame clock gating (mem-to-mem)
+
+User space interfaces
+---------------------
+
+Media device interface
+~~~~~~~~~~~~~~~~~~~~~~
+
+The driver supports Media Controller API as defined at :ref:`media_controller`.
+The media device driver name is "SAMSUNG S5P FIMC".
+
+The purpose of this interface is to allow changing assignment of FIMC instances
+to the SoC peripheral camera input at runtime and optionally to control internal
+connections of the MIPI-CSIS device(s) to the FIMC entities.
+
+The media device interface allows to configure the SoC for capturing image
+data from the sensor through more than one FIMC instance (e.g. for simultaneous
+viewfinder and still capture setup).
+
+Reconfiguration is done by enabling/disabling media links created by the driver
+during initialization. The internal device topology can be easily discovered
+through media entity and links enumeration.
+
+Memory-to-memory video node
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+V4L2 memory-to-memory interface at /dev/video? device node.  This is standalone
+video device, it has no media pads. However please note the mem-to-mem and
+capture video node operation on same FIMC instance is not allowed.  The driver
+detects such cases but the applications should prevent them to avoid an
+undefined behaviour.
+
+Capture video node
+~~~~~~~~~~~~~~~~~~
+
+The driver supports V4L2 Video Capture Interface as defined at
+:ref:`devices`.
+
+At the capture and mem-to-mem video nodes only the multi-planar API is
+supported. For more details see: :ref:`planar-apis`.
+
+Camera capture subdevs
+~~~~~~~~~~~~~~~~~~~~~~
+
+Each FIMC instance exports a sub-device node (/dev/v4l-subdev?), a sub-device
+node is also created per each available and enabled at the platform level
+MIPI-CSI receiver device (currently up to two).
+
+sysfs
+~~~~~
+
+In order to enable more precise camera pipeline control through the sub-device
+API the driver creates a sysfs entry associated with "s5p-fimc-md" platform
+device. The entry path is: /sys/platform/devices/s5p-fimc-md/subdev_conf_mode.
+
+In typical use case there could be a following capture pipeline configuration:
+sensor subdev -> mipi-csi subdev -> fimc subdev -> video node
+
+When we configure these devices through sub-device API at user space, the
+configuration flow must be from left to right, and the video node is
+configured as last one.
+
+When we don't use sub-device user space API the whole configuration of all
+devices belonging to the pipeline is done at the video node driver.
+The sysfs entry allows to instruct the capture node driver not to configure
+the sub-devices (format, crop), to avoid resetting the subdevs' configuration
+when the last configuration steps at the video node is performed.
+
+For full sub-device control support (subdevs configured at user space before
+starting streaming):
+
+.. code-block:: none
+
+	# echo "sub-dev" > /sys/platform/devices/s5p-fimc-md/subdev_conf_mode
+
+For V4L2 video node control only (subdevs configured internally by the host
+driver):
+
+.. code-block:: none
+
+	# echo "vid-dev" > /sys/platform/devices/s5p-fimc-md/subdev_conf_mode
+
+This is a default option.
+
+5. Device mapping to video and subdev device nodes
+--------------------------------------------------
+
+There are associated two video device nodes with each device instance in
+hardware - video capture and mem-to-mem and additionally a subdev node for
+more precise FIMC capture subsystem control. In addition a separate v4l2
+sub-device node is created per each MIPI-CSIS device.
+
+How to find out which /dev/video? or /dev/v4l-subdev? is assigned to which
+device?
+
+You can either grep through the kernel log to find relevant information, i.e.
+
+.. code-block:: none
+
+	# dmesg | grep -i fimc
+
+(note that udev, if present, might still have rearranged the video nodes),
+
+or retrieve the information from /dev/media? with help of the media-ctl tool:
+
+.. code-block:: none
+
+	# media-ctl -p
+
+7. Build
+--------
+
+If the driver is built as a loadable kernel module (CONFIG_VIDEO_SAMSUNG_S5P_FIMC=m)
+two modules are created (in addition to the core v4l2 modules): s5p-fimc.ko and
+optional s5p-csis.ko (MIPI-CSI receiver subdev).
diff --git a/Documentation/admin-guide/media/gspca-cardlist.rst b/Documentation/admin-guide/media/gspca-cardlist.rst
new file mode 100644
index 000000000000..adda933616f1
--- /dev/null
+++ b/Documentation/admin-guide/media/gspca-cardlist.rst
@@ -0,0 +1,451 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+The gspca cards list
+====================
+
+The modules for the gspca webcam drivers are:
+
+- gspca_main: main driver
+- gspca\_\ *driver*: subdriver module with *driver* as follows
+
+=========	=========	===================================================================
+*driver*	vend:prod	Device
+=========	=========	===================================================================
+spca501         0000:0000	MystFromOri Unknown Camera
+spca508         0130:0130	Clone Digital Webcam 11043
+se401           03e8:0004	Endpoints/AoxSE401
+zc3xx           03f0:1b07	HP Premium Starter Cam
+m5602           0402:5602	ALi Video Camera Controller
+spca501         040a:0002	Kodak DVC-325
+spca500         040a:0300	Kodak EZ200
+zc3xx           041e:041e	Creative WebCam Live!
+ov519           041e:4003	Video Blaster WebCam Go Plus
+stv0680         041e:4007	Go Mini
+spca500         041e:400a	Creative PC-CAM 300
+sunplus         041e:400b	Creative PC-CAM 600
+sunplus         041e:4012	PC-Cam350
+sunplus         041e:4013	Creative Pccam750
+zc3xx           041e:4017	Creative Webcam Mobile PD1090
+spca508         041e:4018	Creative Webcam Vista (PD1100)
+spca561         041e:401a	Creative Webcam Vista (PD1100)
+zc3xx           041e:401c	Creative NX
+spca505         041e:401d	Creative Webcam NX ULTRA
+zc3xx           041e:401e	Creative Nx Pro
+zc3xx           041e:401f	Creative Webcam Notebook PD1171
+zc3xx           041e:4022	Webcam NX Pro
+pac207          041e:4028	Creative Webcam Vista Plus
+zc3xx           041e:4029	Creative WebCam Vista Pro
+zc3xx           041e:4034	Creative Instant P0620
+zc3xx           041e:4035	Creative Instant P0620D
+zc3xx           041e:4036	Creative Live !
+sq930x          041e:4038	Creative Joy-IT
+zc3xx           041e:403a	Creative Nx Pro 2
+spca561         041e:403b	Creative Webcam Vista (VF0010)
+sq930x          041e:403c	Creative Live! Ultra
+sq930x          041e:403d	Creative Live! Ultra for Notebooks
+sq930x          041e:4041	Creative Live! Motion
+zc3xx           041e:4051	Creative Live!Cam Notebook Pro (VF0250)
+ov519           041e:4052	Creative Live! VISTA IM
+zc3xx           041e:4053	Creative Live!Cam Video IM
+vc032x          041e:405b	Creative Live! Cam Notebook Ultra (VC0130)
+ov519           041e:405f	Creative Live! VISTA VF0330
+ov519           041e:4060	Creative Live! VISTA VF0350
+ov519           041e:4061	Creative Live! VISTA VF0400
+ov519           041e:4064	Creative Live! VISTA VF0420
+ov519           041e:4067	Creative Live! Cam Video IM (VF0350)
+ov519           041e:4068	Creative Live! VISTA VF0470
+sn9c2028        0458:7003	GeniusVideocam Live v2
+spca561         0458:7004	Genius VideoCAM Express V2
+sn9c2028        0458:7005	Genius Smart 300, version 2
+sunplus         0458:7006	Genius Dsc 1.3 Smart
+zc3xx           0458:7007	Genius VideoCam V2
+zc3xx           0458:700c	Genius VideoCam V3
+zc3xx           0458:700f	Genius VideoCam Web V2
+sonixj          0458:7025	Genius Eye 311Q
+sn9c20x         0458:7029	Genius Look 320s
+sonixj          0458:702e	Genius Slim 310 NB
+sn9c20x         0458:7045	Genius Look 1320 V2
+sn9c20x         0458:704a	Genius Slim 1320
+sn9c20x         0458:704c	Genius i-Look 1321
+sn9c20x         045e:00f4	LifeCam VX-6000 (SN9C20x + OV9650)
+sonixj          045e:00f5	MicroSoft VX3000
+sonixj          045e:00f7	MicroSoft VX1000
+ov519           045e:028c	Micro$oft xbox cam
+kinect          045e:02ae	Xbox NUI Camera
+kinect          045e:02bf	Kinect for Windows NUI Camera
+spca561         0461:0815	Micro Innovations IC200 Webcam
+sunplus         0461:0821	Fujifilm MV-1
+zc3xx           0461:0a00	MicroInnovation WebCam320
+stv06xx         046D:08F0	QuickCamMessenger
+stv06xx         046D:08F5	QuickCamCommunicate
+stv06xx         046D:08F6	QuickCamMessenger (new)
+stv06xx         046d:0840	QuickCamExpress
+stv06xx         046d:0850	LEGOcam / QuickCam Web
+stv06xx         046d:0870	DexxaWebCam USB
+spca500         046d:0890	Logitech QuickCam traveler
+vc032x          046d:0892	Logitech Orbicam
+vc032x          046d:0896	Logitech Orbicam
+vc032x          046d:0897	Logitech QuickCam for Dell notebooks
+zc3xx           046d:089d	Logitech QuickCam E2500
+zc3xx           046d:08a0	Logitech QC IM
+zc3xx           046d:08a1	Logitech QC IM 0x08A1 +sound
+zc3xx           046d:08a2	Labtec Webcam Pro
+zc3xx           046d:08a3	Logitech QC Chat
+zc3xx           046d:08a6	Logitech QCim
+zc3xx           046d:08a7	Logitech QuickCam Image
+zc3xx           046d:08a9	Logitech Notebook Deluxe
+zc3xx           046d:08aa	Labtec Webcam Notebook
+zc3xx           046d:08ac	Logitech QuickCam Cool
+zc3xx           046d:08ad	Logitech QCCommunicate STX
+zc3xx           046d:08ae	Logitech QuickCam for Notebooks
+zc3xx           046d:08af	Logitech QuickCam Cool
+zc3xx           046d:08b9	Logitech QuickCam Express
+zc3xx           046d:08d7	Logitech QCam STX
+zc3xx           046d:08d8	Logitech Notebook Deluxe
+zc3xx           046d:08d9	Logitech QuickCam IM/Connect
+zc3xx           046d:08da	Logitech QuickCam Messenger
+zc3xx           046d:08dd	Logitech QuickCam for Notebooks
+spca500         046d:0900	Logitech Inc. ClickSmart 310
+spca500         046d:0901	Logitech Inc. ClickSmart 510
+sunplus         046d:0905	Logitech ClickSmart 820
+tv8532          046d:0920	Logitech QuickCam Express
+tv8532          046d:0921	Labtec Webcam
+spca561         046d:0928	Logitech QC Express Etch2
+spca561         046d:0929	Labtec Webcam Elch2
+spca561         046d:092a	Logitech QC for Notebook
+spca561         046d:092b	Labtec Webcam Plus
+spca561         046d:092c	Logitech QC chat Elch2
+spca561         046d:092d	Logitech QC Elch2
+spca561         046d:092e	Logitech QC Elch2
+spca561         046d:092f	Logitech QuickCam Express Plus
+sunplus         046d:0960	Logitech ClickSmart 420
+nw80x           046d:d001	Logitech QuickCam Pro (dark focus ring)
+se401           0471:030b	PhilipsPCVC665K
+sunplus         0471:0322	Philips DMVC1300K
+zc3xx           0471:0325	Philips SPC 200 NC
+zc3xx           0471:0326	Philips SPC 300 NC
+sonixj          0471:0327	Philips SPC 600 NC
+sonixj          0471:0328	Philips SPC 700 NC
+zc3xx           0471:032d	Philips SPC 210 NC
+zc3xx           0471:032e	Philips SPC 315 NC
+sonixj          0471:0330	Philips SPC 710 NC
+se401           047d:5001	Kensington67014
+se401           047d:5002	Kensington6701(5/7)
+se401           047d:5003	Kensington67016
+spca501         0497:c001	Smile International
+sunplus         04a5:3003	Benq DC 1300
+sunplus         04a5:3008	Benq DC 1500
+sunplus         04a5:300a	Benq DC 3410
+spca500         04a5:300c	Benq DC 1016
+benq            04a5:3035	Benq DC E300
+vicam           04c1:009d	HomeConnect Webcam [vicam]
+konica          04c8:0720	IntelYC 76
+finepix         04cb:0104	Fujifilm FinePix 4800
+finepix         04cb:0109	Fujifilm FinePix A202
+finepix         04cb:010b	Fujifilm FinePix A203
+finepix         04cb:010f	Fujifilm FinePix A204
+finepix         04cb:0111	Fujifilm FinePix A205
+finepix         04cb:0113	Fujifilm FinePix A210
+finepix         04cb:0115	Fujifilm FinePix A303
+finepix         04cb:0117	Fujifilm FinePix A310
+finepix         04cb:0119	Fujifilm FinePix F401
+finepix         04cb:011b	Fujifilm FinePix F402
+finepix         04cb:011d	Fujifilm FinePix F410
+finepix         04cb:0121	Fujifilm FinePix F601
+finepix         04cb:0123	Fujifilm FinePix F700
+finepix         04cb:0125	Fujifilm FinePix M603
+finepix         04cb:0127	Fujifilm FinePix S300
+finepix         04cb:0129	Fujifilm FinePix S304
+finepix         04cb:012b	Fujifilm FinePix S500
+finepix         04cb:012d	Fujifilm FinePix S602
+finepix         04cb:012f	Fujifilm FinePix S700
+finepix         04cb:0131	Fujifilm FinePix unknown model
+finepix         04cb:013b	Fujifilm FinePix unknown model
+finepix         04cb:013d	Fujifilm FinePix unknown model
+finepix         04cb:013f	Fujifilm FinePix F420
+sunplus         04f1:1001	JVC GC A50
+spca561         04fc:0561	Flexcam 100
+spca1528        04fc:1528	Sunplus MD80 clone
+sunplus         04fc:500c	Sunplus CA500C
+sunplus         04fc:504a	Aiptek Mini PenCam 1.3
+sunplus         04fc:504b	Maxell MaxPocket LE 1.3
+sunplus         04fc:5330	Digitrex 2110
+sunplus         04fc:5360	Sunplus Generic
+spca500         04fc:7333	PalmPixDC85
+sunplus         04fc:ffff	Pure DigitalDakota
+nw80x           0502:d001	DVC V6
+spca501         0506:00df	3Com HomeConnect Lite
+sunplus         052b:1507	Megapixel 5 Pretec DC-1007
+sunplus         052b:1513	Megapix V4
+sunplus         052b:1803	MegaImage VI
+nw80x           052b:d001	EZCam Pro p35u
+tv8532          0545:808b	Veo Stingray
+tv8532          0545:8333	Veo Stingray
+sunplus         0546:3155	Polaroid PDC3070
+sunplus         0546:3191	Polaroid Ion 80
+sunplus         0546:3273	Polaroid PDC2030
+touptek         0547:6801	TTUCMOS08000KPB, AS MU800
+dtcs033         0547:7303	Anchor Chips, Inc
+ov519           054c:0154	Sonny toy4
+ov519           054c:0155	Sonny toy5
+cpia1           0553:0002	CPIA CPiA (version1) based cameras
+stv0680         0553:0202	STV0680 Camera
+zc3xx           055f:c005	Mustek Wcam300A
+spca500         055f:c200	Mustek Gsmart 300
+sunplus         055f:c211	Kowa Bs888e Microcamera
+spca500         055f:c220	Gsmart Mini
+sunplus         055f:c230	Mustek Digicam 330K
+sunplus         055f:c232	Mustek MDC3500
+sunplus         055f:c360	Mustek DV4000 Mpeg4
+sunplus         055f:c420	Mustek gSmart Mini 2
+sunplus         055f:c430	Mustek Gsmart LCD 2
+sunplus         055f:c440	Mustek DV 3000
+sunplus         055f:c520	Mustek gSmart Mini 3
+sunplus         055f:c530	Mustek Gsmart LCD 3
+sunplus         055f:c540	Gsmart D30
+sunplus         055f:c630	Mustek MDC4000
+sunplus         055f:c650	Mustek MDC5500Z
+nw80x           055f:d001	Mustek Wcam 300 mini
+zc3xx           055f:d003	Mustek WCam300A
+zc3xx           055f:d004	Mustek WCam300 AN
+conex           0572:0041	Creative Notebook cx11646
+ov519           05a9:0511	Video Blaster WebCam 3/WebCam Plus, D-Link USB Digital Video Camera
+ov519           05a9:0518	Creative WebCam
+ov519           05a9:0519	OV519 Microphone
+ov519           05a9:0530	OmniVision
+ov534_9         05a9:1550	OmniVision VEHO Filmscanner
+ov519           05a9:2800	OmniVision SuperCAM
+ov519           05a9:4519	Webcam Classic
+ov534_9         05a9:8065	OmniVision test kit ov538+ov9712
+ov519           05a9:8519	OmniVision
+ov519           05a9:a511	D-Link USB Digital Video Camera
+ov519           05a9:a518	D-Link DSB-C310 Webcam
+sunplus         05da:1018	Digital Dream Enigma 1.3
+stk014          05e1:0893	Syntek DV4000
+gl860           05e3:0503	Genesys Logic PC Camera
+gl860           05e3:f191	Genesys Logic PC Camera
+vicam           0602:1001	ViCam Webcam
+spca561         060b:a001	Maxell Compact Pc PM3
+zc3xx           0698:2003	CTX M730V built in
+topro           06a2:0003	TP6800 PC Camera, CmoX CX0342 webcam
+topro           06a2:6810	Creative Qmax
+nw80x           06a5:0000	Typhoon Webcam 100 USB
+nw80x           06a5:d001	Divio based webcams
+nw80x           06a5:d800	Divio Chicony TwinkleCam, Trust SpaceCam
+spca500         06bd:0404	Agfa CL20
+spca500         06be:0800	Optimedia
+nw80x           06be:d001	EZCam Pro p35u
+sunplus         06d6:0031	Trust 610 LCD PowerC@m Zoom
+sunplus         06d6:0041	Aashima Technology B.V.
+spca506         06e1:a190	ADS Instant VCD
+ov534           06f8:3002	Hercules Blog Webcam
+ov534_9         06f8:3003	Hercules Dualpix HD Weblog
+sonixj          06f8:3004	Hercules Classic Silver
+sonixj          06f8:3008	Hercules Deluxe Optical Glass
+pac7302         06f8:3009	Hercules Classic Link
+pac7302         06f8:301b	Hercules Link
+nw80x           0728:d001	AVerMedia Camguard
+spca508         0733:0110	ViewQuest VQ110
+spca501         0733:0401	Intel Create and Share
+spca501         0733:0402	ViewQuest M318B
+spca505         0733:0430	Intel PC Camera Pro
+sunplus         0733:1311	Digital Dream Epsilon 1.3
+sunplus         0733:1314	Mercury 2.1MEG Deluxe Classic Cam
+sunplus         0733:2211	Jenoptik jdc 21 LCD
+sunplus         0733:2221	Mercury Digital Pro 3.1p
+sunplus         0733:3261	Concord 3045 spca536a
+sunplus         0733:3281	Cyberpix S550V
+spca506         0734:043b	3DeMon USB Capture aka
+cpia1           0813:0001	QX3 camera
+ov519           0813:0002	Dual Mode USB Camera Plus
+spca500         084d:0003	D-Link DSC-350
+spca500         08ca:0103	Aiptek PocketDV
+sunplus         08ca:0104	Aiptek PocketDVII 1.3
+sunplus         08ca:0106	Aiptek Pocket DV3100+
+mr97310a        08ca:0110	Trust Spyc@m 100
+mr97310a        08ca:0111	Aiptek PenCam VGA+
+sunplus         08ca:2008	Aiptek Mini PenCam 2 M
+sunplus         08ca:2010	Aiptek PocketCam 3M
+sunplus         08ca:2016	Aiptek PocketCam 2 Mega
+sunplus         08ca:2018	Aiptek Pencam SD 2M
+sunplus         08ca:2020	Aiptek Slim 3000F
+sunplus         08ca:2022	Aiptek Slim 3200
+sunplus         08ca:2024	Aiptek DV3500 Mpeg4
+sunplus         08ca:2028	Aiptek PocketCam4M
+sunplus         08ca:2040	Aiptek PocketDV4100M
+sunplus         08ca:2042	Aiptek PocketDV5100
+sunplus         08ca:2050	Medion MD 41437
+sunplus         08ca:2060	Aiptek PocketDV5300
+tv8532          0923:010f	ICM532 cams
+mr97310a        093a:010e	All known CIF cams with this ID
+mr97310a        093a:010f	All known VGA cams with this ID
+mars            093a:050f	Mars-Semi Pc-Camera
+pac207          093a:2460	Qtec Webcam 100
+pac207          093a:2461	HP Webcam
+pac207          093a:2463	Philips SPC 220 NC
+pac207          093a:2464	Labtec Webcam 1200
+pac207          093a:2468	Webcam WB-1400T
+pac207          093a:2470	Genius GF112
+pac207          093a:2471	Genius VideoCam ge111
+pac207          093a:2472	Genius VideoCam ge110
+pac207          093a:2474	Genius iLook 111
+pac207          093a:2476	Genius e-Messenger 112
+pac7311         093a:2600	PAC7311 Typhoon
+pac7311         093a:2601	Philips SPC 610 NC
+pac7311         093a:2603	Philips SPC 500 NC
+pac7311         093a:2608	Trust WB-3300p
+pac7311         093a:260e	Gigaware VGA PC Camera, Trust WB-3350p, SIGMA cam 2350
+pac7311         093a:260f	SnakeCam
+pac7302         093a:2620	Apollo AC-905
+pac7302         093a:2621	PAC731x
+pac7302         093a:2622	Genius Eye 312
+pac7302         093a:2623	Pixart Imaging, Inc.
+pac7302         093a:2624	PAC7302
+pac7302         093a:2625	Genius iSlim 310
+pac7302         093a:2626	Labtec 2200
+pac7302         093a:2627	Genius FaceCam 300
+pac7302         093a:2628	Genius iLook 300
+pac7302         093a:2629	Genious iSlim 300
+pac7302         093a:262a	Webcam 300k
+pac7302         093a:262c	Philips SPC 230 NC
+jl2005bcd       0979:0227	Various brands, 19 known cameras supported
+jeilinj         0979:0270	Sakar 57379
+jeilinj         0979:0280	Sportscam DV15, Sakar 57379
+zc3xx           0ac8:0301	Web Camera
+zc3xx           0ac8:0302	Z-star Vimicro zc0302
+vc032x          0ac8:0321	Vimicro generic vc0321
+vc032x          0ac8:0323	Vimicro Vc0323
+vc032x          0ac8:0328	A4Tech PK-130MG
+zc3xx           0ac8:301b	Z-Star zc301b
+zc3xx           0ac8:303b	Vimicro 0x303b
+zc3xx           0ac8:305b	Z-star Vimicro zc0305b
+zc3xx           0ac8:307b	PC Camera (ZS0211)
+vc032x          0ac8:c001	Sony embedded vimicro
+vc032x          0ac8:c002	Sony embedded vimicro
+vc032x          0ac8:c301	Samsung Q1 Ultra Premium
+spca508         0af9:0010	Hama USB Sightcam 100
+spca508         0af9:0011	Hama USB Sightcam 100
+ov519           0b62:0059	iBOT2 Webcam
+sonixb          0c45:6001	Genius VideoCAM NB
+sonixb          0c45:6005	Microdia Sweex Mini Webcam
+sonixb          0c45:6007	Sonix sn9c101 + Tas5110D
+sonixb          0c45:6009	spcaCam@120
+sonixb          0c45:600d	spcaCam@120
+sonixb          0c45:6011	Microdia PC Camera (SN9C102)
+sonixb          0c45:6019	Generic Sonix OV7630
+sonixb          0c45:6024	Generic Sonix Tas5130c
+sonixb          0c45:6025	Xcam Shanga
+sonixb          0c45:6027	GeniusEye 310
+sonixb          0c45:6028	Sonix Btc Pc380
+sonixb          0c45:6029	spcaCam@150
+sonixb          0c45:602a	Meade ETX-105EC Camera
+sonixb          0c45:602c	Generic Sonix OV7630
+sonixb          0c45:602d	LIC-200 LG
+sonixb          0c45:602e	Genius VideoCam Messenger
+sonixj          0c45:6040	Speed NVC 350K
+sonixj          0c45:607c	Sonix sn9c102p Hv7131R
+sonixb          0c45:6083	VideoCAM Look
+sonixb          0c45:608c	VideoCAM Look
+sonixb          0c45:608f	PC Camera (SN9C103 + OV7630)
+sonixb          0c45:60a8	VideoCAM Look
+sonixb          0c45:60aa	VideoCAM Look
+sonixb          0c45:60af	VideoCAM Look
+sonixb          0c45:60b0	Genius VideoCam Look
+sonixj          0c45:60c0	Sangha Sn535
+sonixj          0c45:60ce	USB-PC-Camera-168 (TALK-5067)
+sonixj          0c45:60ec	SN9C105+MO4000
+sonixj          0c45:60fb	Surfer NoName
+sonixj          0c45:60fc	LG-LIC300
+sonixj          0c45:60fe	Microdia Audio
+sonixj          0c45:6100	PC Camera (SN9C128)
+sonixj          0c45:6102	PC Camera (SN9C128)
+sonixj          0c45:610a	PC Camera (SN9C128)
+sonixj          0c45:610b	PC Camera (SN9C128)
+sonixj          0c45:610c	PC Camera (SN9C128)
+sonixj          0c45:610e	PC Camera (SN9C128)
+sonixj          0c45:6128	Microdia/Sonix SNP325
+sonixj          0c45:612a	Avant Camera
+sonixj          0c45:612b	Speed-Link REFLECT2
+sonixj          0c45:612c	Typhoon Rasy Cam 1.3MPix
+sonixj          0c45:612e	PC Camera (SN9C110)
+sonixj          0c45:6130	Sonix Pccam
+sonixj          0c45:6138	Sn9c120 Mo4000
+sonixj          0c45:613a	Microdia Sonix PC Camera
+sonixj          0c45:613b	Surfer SN-206
+sonixj          0c45:613c	Sonix Pccam168
+sonixj          0c45:613e	PC Camera (SN9C120)
+sonixj          0c45:6142	Hama PC-Webcam AC-150
+sonixj          0c45:6143	Sonix Pccam168
+sonixj          0c45:6148	Digitus DA-70811/ZSMC USB PC Camera ZS211/Microdia
+sonixj          0c45:614a	Frontech E-Ccam (JIL-2225)
+sn9c20x         0c45:6240	PC Camera (SN9C201 + MT9M001)
+sn9c20x         0c45:6242	PC Camera (SN9C201 + MT9M111)
+sn9c20x         0c45:6248	PC Camera (SN9C201 + OV9655)
+sn9c20x         0c45:624c	PC Camera (SN9C201 + MT9M112)
+sn9c20x         0c45:624e	PC Camera (SN9C201 + SOI968)
+sn9c20x         0c45:624f	PC Camera (SN9C201 + OV9650)
+sn9c20x         0c45:6251	PC Camera (SN9C201 + OV9650)
+sn9c20x         0c45:6253	PC Camera (SN9C201 + OV9650)
+sn9c20x         0c45:6260	PC Camera (SN9C201 + OV7670)
+sn9c20x         0c45:6270	PC Camera (SN9C201 + MT9V011/MT9V111/MT9V112)
+sn9c20x         0c45:627b	PC Camera (SN9C201 + OV7660)
+sn9c20x         0c45:627c	PC Camera (SN9C201 + HV7131R)
+sn9c20x         0c45:627f	PC Camera (SN9C201 + OV9650)
+sn9c20x         0c45:6280	PC Camera (SN9C202 + MT9M001)
+sn9c20x         0c45:6282	PC Camera (SN9C202 + MT9M111)
+sn9c20x         0c45:6288	PC Camera (SN9C202 + OV9655)
+sn9c20x         0c45:628c	PC Camera (SN9C201 + MT9M112)
+sn9c20x         0c45:628e	PC Camera (SN9C202 + SOI968)
+sn9c20x         0c45:628f	PC Camera (SN9C202 + OV9650)
+sn9c20x         0c45:62a0	PC Camera (SN9C202 + OV7670)
+sn9c20x         0c45:62b0	PC Camera (SN9C202 + MT9V011/MT9V111/MT9V112)
+sn9c20x         0c45:62b3	PC Camera (SN9C202 + OV9655)
+sn9c20x         0c45:62bb	PC Camera (SN9C202 + OV7660)
+sn9c20x         0c45:62bc	PC Camera (SN9C202 + HV7131R)
+sn9c2028        0c45:8001	Wild Planet Digital Spy Camera
+sn9c2028        0c45:8003	Sakar #11199, #6637x, #67480 keychain cams
+sn9c2028        0c45:8008	Mini-Shotz ms-350
+sn9c2028        0c45:800a	Vivitar Vivicam 3350B
+sunplus         0d64:0303	Sunplus FashionCam DXG
+ov519           0e96:c001	TRUST 380 USB2 SPACEC@M
+etoms           102c:6151	Qcam Sangha CIF
+etoms           102c:6251	Qcam xxxxxx VGA
+ov519           1046:9967	W9967CF/W9968CF WebCam IC, Video Blaster WebCam Go
+zc3xx           10fd:0128	Typhoon Webshot II USB 300k 0x0128
+spca561         10fd:7e50	FlyCam Usb 100
+zc3xx           10fd:804d	Typhoon Webshot II Webcam [zc0301]
+zc3xx           10fd:8050	Typhoon Webshot II USB 300k
+ov534           1415:2000	Sony HD Eye for PS3 (SLEH 00201)
+pac207          145f:013a	Trust WB-1300N
+pac7302         145f:013c	Trust
+sn9c20x         145f:013d	Trust WB-3600R
+vc032x          15b8:6001	HP 2.0 Megapixel
+vc032x          15b8:6002	HP 2.0 Megapixel rz406aa
+stk1135         174f:6a31	ASUSlaptop, MT9M112 sensor
+spca501         1776:501c	Arowana 300K CMOS Camera
+t613            17a1:0128	TASCORP JPEG Webcam, NGS Cyclops
+vc032x          17ef:4802	Lenovo Vc0323+MI1310_SOC
+pac7302         1ae7:2001	SpeedLinkSnappy Mic SL-6825-SBK
+pac207          2001:f115	D-Link DSB-C120
+sq905c          2770:9050	Disney pix micro (CIF)
+sq905c          2770:9051	Lego Bionicle
+sq905c          2770:9052	Disney pix micro 2 (VGA)
+sq905c          2770:905c	All 11 known cameras with this ID
+sq905           2770:9120	All 24 known cameras with this ID
+sq905c          2770:913d	All 4 known cameras with this ID
+sq930x          2770:930b	Sweex Motion Tracking / I-Tec iCam Tracer
+sq930x          2770:930c	Trust WB-3500T / NSG Robbie 2.0
+spca500         2899:012c	Toptro Industrial
+ov519           8020:ef04	ov519
+spca508         8086:0110	Intel Easy PC Camera
+spca500         8086:0630	Intel Pocket PC Camera
+spca506         99fa:8988	Grandtec V.cap
+sn9c20x         a168:0610	Dino-Lite Digital Microscope (SN9C201 + HV7131R)
+sn9c20x         a168:0611	Dino-Lite Digital Microscope (SN9C201 + HV7131R)
+sn9c20x         a168:0613	Dino-Lite Digital Microscope (SN9C201 + HV7131R)
+sn9c20x         a168:0614	Dino-Lite Digital Microscope (SN9C201 + MT9M111)
+sn9c20x         a168:0615	Dino-Lite Digital Microscope (SN9C201 + MT9M111)
+sn9c20x         a168:0617	Dino-Lite Digital Microscope (SN9C201 + MT9M111)
+sn9c20x         a168:0618	Dino-Lite Digital Microscope (SN9C201 + HV7131R)
+spca561         abcd:cdee	Petcam
+=========	=========	===================================================================
diff --git a/Documentation/admin-guide/media/imx.rst b/Documentation/admin-guide/media/imx.rst
new file mode 100644
index 000000000000..5bb464754379
--- /dev/null
+++ b/Documentation/admin-guide/media/imx.rst
@@ -0,0 +1,650 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+i.MX Video Capture Driver
+=========================
+
+Introduction
+------------
+
+The Freescale i.MX5/6 contains an Image Processing Unit (IPU), which
+handles the flow of image frames to and from capture devices and
+display devices.
+
+For image capture, the IPU contains the following internal subunits:
+
+- Image DMA Controller (IDMAC)
+- Camera Serial Interface (CSI)
+- Image Converter (IC)
+- Sensor Multi-FIFO Controller (SMFC)
+- Image Rotator (IRT)
+- Video De-Interlacing or Combining Block (VDIC)
+
+The IDMAC is the DMA controller for transfer of image frames to and from
+memory. Various dedicated DMA channels exist for both video capture and
+display paths. During transfer, the IDMAC is also capable of vertical
+image flip, 8x8 block transfer (see IRT description), pixel component
+re-ordering (for example UYVY to YUYV) within the same colorspace, and
+packed <--> planar conversion. The IDMAC can also perform a simple
+de-interlacing by interweaving even and odd lines during transfer
+(without motion compensation which requires the VDIC).
+
+The CSI is the backend capture unit that interfaces directly with
+camera sensors over Parallel, BT.656/1120, and MIPI CSI-2 buses.
+
+The IC handles color-space conversion, resizing (downscaling and
+upscaling), horizontal flip, and 90/270 degree rotation operations.
+
+There are three independent "tasks" within the IC that can carry out
+conversions concurrently: pre-process encoding, pre-process viewfinder,
+and post-processing. Within each task, conversions are split into three
+sections: downsizing section, main section (upsizing, flip, colorspace
+conversion, and graphics plane combining), and rotation section.
+
+The IPU time-shares the IC task operations. The time-slice granularity
+is one burst of eight pixels in the downsizing section, one image line
+in the main processing section, one image frame in the rotation section.
+
+The SMFC is composed of four independent FIFOs that each can transfer
+captured frames from sensors directly to memory concurrently via four
+IDMAC channels.
+
+The IRT carries out 90 and 270 degree image rotation operations. The
+rotation operation is carried out on 8x8 pixel blocks at a time. This
+operation is supported by the IDMAC which handles the 8x8 block transfer
+along with block reordering, in coordination with vertical flip.
+
+The VDIC handles the conversion of interlaced video to progressive, with
+support for different motion compensation modes (low, medium, and high
+motion). The deinterlaced output frames from the VDIC can be sent to the
+IC pre-process viewfinder task for further conversions. The VDIC also
+contains a Combiner that combines two image planes, with alpha blending
+and color keying.
+
+In addition to the IPU internal subunits, there are also two units
+outside the IPU that are also involved in video capture on i.MX:
+
+- MIPI CSI-2 Receiver for camera sensors with the MIPI CSI-2 bus
+  interface. This is a Synopsys DesignWare core.
+- Two video multiplexers for selecting among multiple sensor inputs
+  to send to a CSI.
+
+For more info, refer to the latest versions of the i.MX5/6 reference
+manuals [#f1]_ and [#f2]_.
+
+
+Features
+--------
+
+Some of the features of this driver include:
+
+- Many different pipelines can be configured via media controller API,
+  that correspond to the hardware video capture pipelines supported in
+  the i.MX.
+
+- Supports parallel, BT.565, and MIPI CSI-2 interfaces.
+
+- Concurrent independent streams, by configuring pipelines to multiple
+  video capture interfaces using independent entities.
+
+- Scaling, color-space conversion, horizontal and vertical flip, and
+  image rotation via IC task subdevs.
+
+- Many pixel formats supported (RGB, packed and planar YUV, partial
+  planar YUV).
+
+- The VDIC subdev supports motion compensated de-interlacing, with three
+  motion compensation modes: low, medium, and high motion. Pipelines are
+  defined that allow sending frames to the VDIC subdev directly from the
+  CSI. There is also support in the future for sending frames to the
+  VDIC from memory buffers via a output/mem2mem devices.
+
+- Includes a Frame Interval Monitor (FIM) that can correct vertical sync
+  problems with the ADV718x video decoders.
+
+
+Topology
+--------
+
+The following shows the media topologies for the i.MX6Q SabreSD and
+i.MX6Q SabreAuto. Refer to these diagrams in the entity descriptions
+in the next section.
+
+The i.MX5/6 topologies can differ upstream from the IPUv3 CSI video
+multiplexers, but the internal IPUv3 topology downstream from there
+is common to all i.MX5/6 platforms. For example, the SabreSD, with the
+MIPI CSI-2 OV5640 sensor, requires the i.MX6 MIPI CSI-2 receiver. But
+the SabreAuto has only the ADV7180 decoder on a parallel bt.656 bus, and
+therefore does not require the MIPI CSI-2 receiver, so it is missing in
+its graph.
+
+.. _imx6q_topology_graph:
+
+.. kernel-figure:: imx6q-sabresd.dot
+    :alt:   Diagram of the i.MX6Q SabreSD media pipeline topology
+    :align: center
+
+    Media pipeline graph on i.MX6Q SabreSD
+
+.. kernel-figure:: imx6q-sabreauto.dot
+    :alt:   Diagram of the i.MX6Q SabreAuto media pipeline topology
+    :align: center
+
+    Media pipeline graph on i.MX6Q SabreAuto
+
+Entities
+--------
+
+imx6-mipi-csi2
+--------------
+
+This is the MIPI CSI-2 receiver entity. It has one sink pad to receive
+the MIPI CSI-2 stream (usually from a MIPI CSI-2 camera sensor). It has
+four source pads, corresponding to the four MIPI CSI-2 demuxed virtual
+channel outputs. Multiple source pads can be enabled to independently
+stream from multiple virtual channels.
+
+This entity actually consists of two sub-blocks. One is the MIPI CSI-2
+core. This is a Synopsys Designware MIPI CSI-2 core. The other sub-block
+is a "CSI-2 to IPU gasket". The gasket acts as a demultiplexer of the
+four virtual channels streams, providing four separate parallel buses
+containing each virtual channel that are routed to CSIs or video
+multiplexers as described below.
+
+On i.MX6 solo/dual-lite, all four virtual channel buses are routed to
+two video multiplexers. Both CSI0 and CSI1 can receive any virtual
+channel, as selected by the video multiplexers.
+
+On i.MX6 Quad, virtual channel 0 is routed to IPU1-CSI0 (after selected
+by a video mux), virtual channels 1 and 2 are hard-wired to IPU1-CSI1
+and IPU2-CSI0, respectively, and virtual channel 3 is routed to
+IPU2-CSI1 (again selected by a video mux).
+
+ipuX_csiY_mux
+-------------
+
+These are the video multiplexers. They have two or more sink pads to
+select from either camera sensors with a parallel interface, or from
+MIPI CSI-2 virtual channels from imx6-mipi-csi2 entity. They have a
+single source pad that routes to a CSI (ipuX_csiY entities).
+
+On i.MX6 solo/dual-lite, there are two video mux entities. One sits
+in front of IPU1-CSI0 to select between a parallel sensor and any of
+the four MIPI CSI-2 virtual channels (a total of five sink pads). The
+other mux sits in front of IPU1-CSI1, and again has five sink pads to
+select between a parallel sensor and any of the four MIPI CSI-2 virtual
+channels.
+
+On i.MX6 Quad, there are two video mux entities. One sits in front of
+IPU1-CSI0 to select between a parallel sensor and MIPI CSI-2 virtual
+channel 0 (two sink pads). The other mux sits in front of IPU2-CSI1 to
+select between a parallel sensor and MIPI CSI-2 virtual channel 3 (two
+sink pads).
+
+ipuX_csiY
+---------
+
+These are the CSI entities. They have a single sink pad receiving from
+either a video mux or from a MIPI CSI-2 virtual channel as described
+above.
+
+This entity has two source pads. The first source pad can link directly
+to the ipuX_vdic entity or the ipuX_ic_prp entity, using hardware links
+that require no IDMAC memory buffer transfer.
+
+When the direct source pad is routed to the ipuX_ic_prp entity, frames
+from the CSI can be processed by one or both of the IC pre-processing
+tasks.
+
+When the direct source pad is routed to the ipuX_vdic entity, the VDIC
+will carry out motion-compensated de-interlace using "high motion" mode
+(see description of ipuX_vdic entity).
+
+The second source pad sends video frames directly to memory buffers
+via the SMFC and an IDMAC channel, bypassing IC pre-processing. This
+source pad is routed to a capture device node, with a node name of the
+format "ipuX_csiY capture".
+
+Note that since the IDMAC source pad makes use of an IDMAC channel,
+pixel reordering within the same colorspace can be carried out by the
+IDMAC channel. For example, if the CSI sink pad is receiving in UYVY
+order, the capture device linked to the IDMAC source pad can capture
+in YUYV order. Also, if the CSI sink pad is receiving a packed YUV
+format, the capture device can capture a planar YUV format such as
+YUV420.
+
+The IDMAC channel at the IDMAC source pad also supports simple
+interweave without motion compensation, which is activated if the source
+pad's field type is sequential top-bottom or bottom-top, and the
+requested capture interface field type is set to interlaced (t-b, b-t,
+or unqualified interlaced). The capture interface will enforce the same
+field order as the source pad field order (interlaced-bt if source pad
+is seq-bt, interlaced-tb if source pad is seq-tb).
+
+For events produced by ipuX_csiY, see ref:`imx_api_ipuX_csiY`.
+
+Cropping in ipuX_csiY
+---------------------
+
+The CSI supports cropping the incoming raw sensor frames. This is
+implemented in the ipuX_csiY entities at the sink pad, using the
+crop selection subdev API.
+
+The CSI also supports fixed divide-by-two downscaling independently in
+width and height. This is implemented in the ipuX_csiY entities at
+the sink pad, using the compose selection subdev API.
+
+The output rectangle at the ipuX_csiY source pad is the same as
+the compose rectangle at the sink pad. So the source pad rectangle
+cannot be negotiated, it must be set using the compose selection
+API at sink pad (if /2 downscale is desired, otherwise source pad
+rectangle is equal to incoming rectangle).
+
+To give an example of crop and /2 downscale, this will crop a
+1280x960 input frame to 640x480, and then /2 downscale in both
+dimensions to 320x240 (assumes ipu1_csi0 is linked to ipu1_csi0_mux):
+
+.. code-block:: none
+
+   media-ctl -V "'ipu1_csi0_mux':2[fmt:UYVY2X8/1280x960]"
+   media-ctl -V "'ipu1_csi0':0[crop:(0,0)/640x480]"
+   media-ctl -V "'ipu1_csi0':0[compose:(0,0)/320x240]"
+
+Frame Skipping in ipuX_csiY
+---------------------------
+
+The CSI supports frame rate decimation, via frame skipping. Frame
+rate decimation is specified by setting the frame intervals at
+sink and source pads. The ipuX_csiY entity then applies the best
+frame skip setting to the CSI to achieve the desired frame rate
+at the source pad.
+
+The following example reduces an assumed incoming 60 Hz frame
+rate by half at the IDMAC output source pad:
+
+.. code-block:: none
+
+   media-ctl -V "'ipu1_csi0':0[fmt:UYVY2X8/640x480@1/60]"
+   media-ctl -V "'ipu1_csi0':2[fmt:UYVY2X8/640x480@1/30]"
+
+Frame Interval Monitor in ipuX_csiY
+-----------------------------------
+
+See ref:`imx_api_FIM`.
+
+ipuX_vdic
+---------
+
+The VDIC carries out motion compensated de-interlacing, with three
+motion compensation modes: low, medium, and high motion. The mode is
+specified with the menu control V4L2_CID_DEINTERLACING_MODE. The VDIC
+has two sink pads and a single source pad.
+
+The direct sink pad receives from an ipuX_csiY direct pad. With this
+link the VDIC can only operate in high motion mode.
+
+When the IDMAC sink pad is activated, it receives from an output
+or mem2mem device node. With this pipeline, the VDIC can also operate
+in low and medium modes, because these modes require receiving
+frames from memory buffers. Note that an output or mem2mem device
+is not implemented yet, so this sink pad currently has no links.
+
+The source pad routes to the IC pre-processing entity ipuX_ic_prp.
+
+ipuX_ic_prp
+-----------
+
+This is the IC pre-processing entity. It acts as a router, routing
+data from its sink pad to one or both of its source pads.
+
+This entity has a single sink pad. The sink pad can receive from the
+ipuX_csiY direct pad, or from ipuX_vdic.
+
+This entity has two source pads. One source pad routes to the
+pre-process encode task entity (ipuX_ic_prpenc), the other to the
+pre-process viewfinder task entity (ipuX_ic_prpvf). Both source pads
+can be activated at the same time if the sink pad is receiving from
+ipuX_csiY. Only the source pad to the pre-process viewfinder task entity
+can be activated if the sink pad is receiving from ipuX_vdic (frames
+from the VDIC can only be processed by the pre-process viewfinder task).
+
+ipuX_ic_prpenc
+--------------
+
+This is the IC pre-processing encode entity. It has a single sink
+pad from ipuX_ic_prp, and a single source pad. The source pad is
+routed to a capture device node, with a node name of the format
+"ipuX_ic_prpenc capture".
+
+This entity performs the IC pre-process encode task operations:
+color-space conversion, resizing (downscaling and upscaling),
+horizontal and vertical flip, and 90/270 degree rotation. Flip
+and rotation are provided via standard V4L2 controls.
+
+Like the ipuX_csiY IDMAC source, this entity also supports simple
+de-interlace without motion compensation, and pixel reordering.
+
+ipuX_ic_prpvf
+-------------
+
+This is the IC pre-processing viewfinder entity. It has a single sink
+pad from ipuX_ic_prp, and a single source pad. The source pad is routed
+to a capture device node, with a node name of the format
+"ipuX_ic_prpvf capture".
+
+This entity is identical in operation to ipuX_ic_prpenc, with the same
+resizing and CSC operations and flip/rotation controls. It will receive
+and process de-interlaced frames from the ipuX_vdic if ipuX_ic_prp is
+receiving from ipuX_vdic.
+
+Like the ipuX_csiY IDMAC source, this entity supports simple
+interweaving without motion compensation. However, note that if the
+ipuX_vdic is included in the pipeline (ipuX_ic_prp is receiving from
+ipuX_vdic), it's not possible to use interweave in ipuX_ic_prpvf,
+since the ipuX_vdic has already carried out de-interlacing (with
+motion compensation) and therefore the field type output from
+ipuX_vdic can only be none (progressive).
+
+Capture Pipelines
+-----------------
+
+The following describe the various use-cases supported by the pipelines.
+
+The links shown do not include the backend sensor, video mux, or mipi
+csi-2 receiver links. This depends on the type of sensor interface
+(parallel or mipi csi-2). So these pipelines begin with:
+
+sensor -> ipuX_csiY_mux -> ...
+
+for parallel sensors, or:
+
+sensor -> imx6-mipi-csi2 -> (ipuX_csiY_mux) -> ...
+
+for mipi csi-2 sensors. The imx6-mipi-csi2 receiver may need to route
+to the video mux (ipuX_csiY_mux) before sending to the CSI, depending
+on the mipi csi-2 virtual channel, hence ipuX_csiY_mux is shown in
+parenthesis.
+
+Unprocessed Video Capture:
+--------------------------
+
+Send frames directly from sensor to camera device interface node, with
+no conversions, via ipuX_csiY IDMAC source pad:
+
+-> ipuX_csiY:2 -> ipuX_csiY capture
+
+IC Direct Conversions:
+----------------------
+
+This pipeline uses the preprocess encode entity to route frames directly
+from the CSI to the IC, to carry out scaling up to 1024x1024 resolution,
+CSC, flipping, and image rotation:
+
+-> ipuX_csiY:1 -> 0:ipuX_ic_prp:1 -> 0:ipuX_ic_prpenc:1 -> ipuX_ic_prpenc capture
+
+Motion Compensated De-interlace:
+--------------------------------
+
+This pipeline routes frames from the CSI direct pad to the VDIC entity to
+support motion-compensated de-interlacing (high motion mode only),
+scaling up to 1024x1024, CSC, flip, and rotation:
+
+-> ipuX_csiY:1 -> 0:ipuX_vdic:2 -> 0:ipuX_ic_prp:2 -> 0:ipuX_ic_prpvf:1 -> ipuX_ic_prpvf capture
+
+
+Usage Notes
+-----------
+
+To aid in configuration and for backward compatibility with V4L2
+applications that access controls only from video device nodes, the
+capture device interfaces inherit controls from the active entities
+in the current pipeline, so controls can be accessed either directly
+from the subdev or from the active capture device interface. For
+example, the FIM controls are available either from the ipuX_csiY
+subdevs or from the active capture device.
+
+The following are specific usage notes for the Sabre* reference
+boards:
+
+
+i.MX6Q SabreLite with OV5642 and OV5640
+---------------------------------------
+
+This platform requires the OmniVision OV5642 module with a parallel
+camera interface, and the OV5640 module with a MIPI CSI-2
+interface. Both modules are available from Boundary Devices:
+
+- https://boundarydevices.com/product/nit6x_5mp
+- https://boundarydevices.com/product/nit6x_5mp_mipi
+
+Note that if only one camera module is available, the other sensor
+node can be disabled in the device tree.
+
+The OV5642 module is connected to the parallel bus input on the i.MX
+internal video mux to IPU1 CSI0. It's i2c bus connects to i2c bus 2.
+
+The MIPI CSI-2 OV5640 module is connected to the i.MX internal MIPI CSI-2
+receiver, and the four virtual channel outputs from the receiver are
+routed as follows: vc0 to the IPU1 CSI0 mux, vc1 directly to IPU1 CSI1,
+vc2 directly to IPU2 CSI0, and vc3 to the IPU2 CSI1 mux. The OV5640 is
+also connected to i2c bus 2 on the SabreLite, therefore the OV5642 and
+OV5640 must not share the same i2c slave address.
+
+The following basic example configures unprocessed video capture
+pipelines for both sensors. The OV5642 is routed to ipu1_csi0, and
+the OV5640, transmitting on MIPI CSI-2 virtual channel 1 (which is
+imx6-mipi-csi2 pad 2), is routed to ipu1_csi1. Both sensors are
+configured to output 640x480, and the OV5642 outputs YUYV2X8, the
+OV5640 UYVY2X8:
+
+.. code-block:: none
+
+   # Setup links for OV5642
+   media-ctl -l "'ov5642 1-0042':0 -> 'ipu1_csi0_mux':1[1]"
+   media-ctl -l "'ipu1_csi0_mux':2 -> 'ipu1_csi0':0[1]"
+   media-ctl -l "'ipu1_csi0':2 -> 'ipu1_csi0 capture':0[1]"
+   # Setup links for OV5640
+   media-ctl -l "'ov5640 1-0040':0 -> 'imx6-mipi-csi2':0[1]"
+   media-ctl -l "'imx6-mipi-csi2':2 -> 'ipu1_csi1':0[1]"
+   media-ctl -l "'ipu1_csi1':2 -> 'ipu1_csi1 capture':0[1]"
+   # Configure pads for OV5642 pipeline
+   media-ctl -V "'ov5642 1-0042':0 [fmt:YUYV2X8/640x480 field:none]"
+   media-ctl -V "'ipu1_csi0_mux':2 [fmt:YUYV2X8/640x480 field:none]"
+   media-ctl -V "'ipu1_csi0':2 [fmt:AYUV32/640x480 field:none]"
+   # Configure pads for OV5640 pipeline
+   media-ctl -V "'ov5640 1-0040':0 [fmt:UYVY2X8/640x480 field:none]"
+   media-ctl -V "'imx6-mipi-csi2':2 [fmt:UYVY2X8/640x480 field:none]"
+   media-ctl -V "'ipu1_csi1':2 [fmt:AYUV32/640x480 field:none]"
+
+Streaming can then begin independently on the capture device nodes
+"ipu1_csi0 capture" and "ipu1_csi1 capture". The v4l2-ctl tool can
+be used to select any supported YUV pixelformat on the capture device
+nodes, including planar.
+
+i.MX6Q SabreAuto with ADV7180 decoder
+-------------------------------------
+
+On the i.MX6Q SabreAuto, an on-board ADV7180 SD decoder is connected to the
+parallel bus input on the internal video mux to IPU1 CSI0.
+
+The following example configures a pipeline to capture from the ADV7180
+video decoder, assuming NTSC 720x480 input signals, using simple
+interweave (unconverted and without motion compensation). The adv7180
+must output sequential or alternating fields (field type 'seq-bt' for
+NTSC, or 'alternate'):
+
+.. code-block:: none
+
+   # Setup links
+   media-ctl -l "'adv7180 3-0021':0 -> 'ipu1_csi0_mux':1[1]"
+   media-ctl -l "'ipu1_csi0_mux':2 -> 'ipu1_csi0':0[1]"
+   media-ctl -l "'ipu1_csi0':2 -> 'ipu1_csi0 capture':0[1]"
+   # Configure pads
+   media-ctl -V "'adv7180 3-0021':0 [fmt:UYVY2X8/720x480 field:seq-bt]"
+   media-ctl -V "'ipu1_csi0_mux':2 [fmt:UYVY2X8/720x480]"
+   media-ctl -V "'ipu1_csi0':2 [fmt:AYUV32/720x480]"
+   # Configure "ipu1_csi0 capture" interface (assumed at /dev/video4)
+   v4l2-ctl -d4 --set-fmt-video=field=interlaced_bt
+
+Streaming can then begin on /dev/video4. The v4l2-ctl tool can also be
+used to select any supported YUV pixelformat on /dev/video4.
+
+This example configures a pipeline to capture from the ADV7180
+video decoder, assuming PAL 720x576 input signals, with Motion
+Compensated de-interlacing. The adv7180 must output sequential or
+alternating fields (field type 'seq-tb' for PAL, or 'alternate').
+
+.. code-block:: none
+
+   # Setup links
+   media-ctl -l "'adv7180 3-0021':0 -> 'ipu1_csi0_mux':1[1]"
+   media-ctl -l "'ipu1_csi0_mux':2 -> 'ipu1_csi0':0[1]"
+   media-ctl -l "'ipu1_csi0':1 -> 'ipu1_vdic':0[1]"
+   media-ctl -l "'ipu1_vdic':2 -> 'ipu1_ic_prp':0[1]"
+   media-ctl -l "'ipu1_ic_prp':2 -> 'ipu1_ic_prpvf':0[1]"
+   media-ctl -l "'ipu1_ic_prpvf':1 -> 'ipu1_ic_prpvf capture':0[1]"
+   # Configure pads
+   media-ctl -V "'adv7180 3-0021':0 [fmt:UYVY2X8/720x576 field:seq-tb]"
+   media-ctl -V "'ipu1_csi0_mux':2 [fmt:UYVY2X8/720x576]"
+   media-ctl -V "'ipu1_csi0':1 [fmt:AYUV32/720x576]"
+   media-ctl -V "'ipu1_vdic':2 [fmt:AYUV32/720x576 field:none]"
+   media-ctl -V "'ipu1_ic_prp':2 [fmt:AYUV32/720x576 field:none]"
+   media-ctl -V "'ipu1_ic_prpvf':1 [fmt:AYUV32/720x576 field:none]"
+   # Configure "ipu1_ic_prpvf capture" interface (assumed at /dev/video2)
+   v4l2-ctl -d2 --set-fmt-video=field=none
+
+Streaming can then begin on /dev/video2. The v4l2-ctl tool can also be
+used to select any supported YUV pixelformat on /dev/video2.
+
+This platform accepts Composite Video analog inputs to the ADV7180 on
+Ain1 (connector J42).
+
+i.MX6DL SabreAuto with ADV7180 decoder
+--------------------------------------
+
+On the i.MX6DL SabreAuto, an on-board ADV7180 SD decoder is connected to the
+parallel bus input on the internal video mux to IPU1 CSI0.
+
+The following example configures a pipeline to capture from the ADV7180
+video decoder, assuming NTSC 720x480 input signals, using simple
+interweave (unconverted and without motion compensation). The adv7180
+must output sequential or alternating fields (field type 'seq-bt' for
+NTSC, or 'alternate'):
+
+.. code-block:: none
+
+   # Setup links
+   media-ctl -l "'adv7180 4-0021':0 -> 'ipu1_csi0_mux':4[1]"
+   media-ctl -l "'ipu1_csi0_mux':5 -> 'ipu1_csi0':0[1]"
+   media-ctl -l "'ipu1_csi0':2 -> 'ipu1_csi0 capture':0[1]"
+   # Configure pads
+   media-ctl -V "'adv7180 4-0021':0 [fmt:UYVY2X8/720x480 field:seq-bt]"
+   media-ctl -V "'ipu1_csi0_mux':5 [fmt:UYVY2X8/720x480]"
+   media-ctl -V "'ipu1_csi0':2 [fmt:AYUV32/720x480]"
+   # Configure "ipu1_csi0 capture" interface (assumed at /dev/video0)
+   v4l2-ctl -d0 --set-fmt-video=field=interlaced_bt
+
+Streaming can then begin on /dev/video0. The v4l2-ctl tool can also be
+used to select any supported YUV pixelformat on /dev/video0.
+
+This example configures a pipeline to capture from the ADV7180
+video decoder, assuming PAL 720x576 input signals, with Motion
+Compensated de-interlacing. The adv7180 must output sequential or
+alternating fields (field type 'seq-tb' for PAL, or 'alternate').
+
+.. code-block:: none
+
+   # Setup links
+   media-ctl -l "'adv7180 4-0021':0 -> 'ipu1_csi0_mux':4[1]"
+   media-ctl -l "'ipu1_csi0_mux':5 -> 'ipu1_csi0':0[1]"
+   media-ctl -l "'ipu1_csi0':1 -> 'ipu1_vdic':0[1]"
+   media-ctl -l "'ipu1_vdic':2 -> 'ipu1_ic_prp':0[1]"
+   media-ctl -l "'ipu1_ic_prp':2 -> 'ipu1_ic_prpvf':0[1]"
+   media-ctl -l "'ipu1_ic_prpvf':1 -> 'ipu1_ic_prpvf capture':0[1]"
+   # Configure pads
+   media-ctl -V "'adv7180 4-0021':0 [fmt:UYVY2X8/720x576 field:seq-tb]"
+   media-ctl -V "'ipu1_csi0_mux':5 [fmt:UYVY2X8/720x576]"
+   media-ctl -V "'ipu1_csi0':1 [fmt:AYUV32/720x576]"
+   media-ctl -V "'ipu1_vdic':2 [fmt:AYUV32/720x576 field:none]"
+   media-ctl -V "'ipu1_ic_prp':2 [fmt:AYUV32/720x576 field:none]"
+   media-ctl -V "'ipu1_ic_prpvf':1 [fmt:AYUV32/720x576 field:none]"
+   # Configure "ipu1_ic_prpvf capture" interface (assumed at /dev/video2)
+   v4l2-ctl -d2 --set-fmt-video=field=none
+
+Streaming can then begin on /dev/video2. The v4l2-ctl tool can also be
+used to select any supported YUV pixelformat on /dev/video2.
+
+This platform accepts Composite Video analog inputs to the ADV7180 on
+Ain1 (connector J42).
+
+i.MX6Q SabreSD with MIPI CSI-2 OV5640
+-------------------------------------
+
+Similarly to i.MX6Q SabreLite, the i.MX6Q SabreSD supports a parallel
+interface OV5642 module on IPU1 CSI0, and a MIPI CSI-2 OV5640
+module. The OV5642 connects to i2c bus 1 and the OV5640 to i2c bus 2.
+
+The device tree for SabreSD includes OF graphs for both the parallel
+OV5642 and the MIPI CSI-2 OV5640, but as of this writing only the MIPI
+CSI-2 OV5640 has been tested, so the OV5642 node is currently disabled.
+The OV5640 module connects to MIPI connector J5 (sorry I don't have the
+compatible module part number or URL).
+
+The following example configures a direct conversion pipeline to capture
+from the OV5640, transmitting on MIPI CSI-2 virtual channel 1. $sensorfmt
+can be any format supported by the OV5640. $sensordim is the frame
+dimension part of $sensorfmt (minus the mbus pixel code). $outputfmt can
+be any format supported by the ipu1_ic_prpenc entity at its output pad:
+
+.. code-block:: none
+
+   # Setup links
+   media-ctl -l "'ov5640 1-003c':0 -> 'imx6-mipi-csi2':0[1]"
+   media-ctl -l "'imx6-mipi-csi2':2 -> 'ipu1_csi1':0[1]"
+   media-ctl -l "'ipu1_csi1':1 -> 'ipu1_ic_prp':0[1]"
+   media-ctl -l "'ipu1_ic_prp':1 -> 'ipu1_ic_prpenc':0[1]"
+   media-ctl -l "'ipu1_ic_prpenc':1 -> 'ipu1_ic_prpenc capture':0[1]"
+   # Configure pads
+   media-ctl -V "'ov5640 1-003c':0 [fmt:$sensorfmt field:none]"
+   media-ctl -V "'imx6-mipi-csi2':2 [fmt:$sensorfmt field:none]"
+   media-ctl -V "'ipu1_csi1':1 [fmt:AYUV32/$sensordim field:none]"
+   media-ctl -V "'ipu1_ic_prp':1 [fmt:AYUV32/$sensordim field:none]"
+   media-ctl -V "'ipu1_ic_prpenc':1 [fmt:$outputfmt field:none]"
+
+Streaming can then begin on "ipu1_ic_prpenc capture" node. The v4l2-ctl
+tool can be used to select any supported YUV or RGB pixelformat on the
+capture device node.
+
+
+Known Issues
+------------
+
+1. When using 90 or 270 degree rotation control at capture resolutions
+   near the IC resizer limit of 1024x1024, and combined with planar
+   pixel formats (YUV420, YUV422p), frame capture will often fail with
+   no end-of-frame interrupts from the IDMAC channel. To work around
+   this, use lower resolution and/or packed formats (YUYV, RGB3, etc.)
+   when 90 or 270 rotations are needed.
+
+
+File list
+---------
+
+drivers/staging/media/imx/
+include/media/imx.h
+include/linux/imx-media.h
+
+References
+----------
+
+.. [#f1] http://www.nxp.com/assets/documents/data/en/reference-manuals/IMX6DQRM.pdf
+.. [#f2] http://www.nxp.com/assets/documents/data/en/reference-manuals/IMX6SDLRM.pdf
+
+
+Authors
+-------
+
+- Steve Longerbeam <steve_longerbeam@mentor.com>
+- Philipp Zabel <kernel@pengutronix.de>
+- Russell King <linux@armlinux.org.uk>
+
+Copyright (C) 2012-2017 Mentor Graphics Inc.
diff --git a/Documentation/admin-guide/media/imx6q-sabreauto.dot b/Documentation/admin-guide/media/imx6q-sabreauto.dot
new file mode 100644
index 000000000000..bd6cf0b358c0
--- /dev/null
+++ b/Documentation/admin-guide/media/imx6q-sabreauto.dot
@@ -0,0 +1,51 @@
+digraph board {
+	rankdir=TB
+	n00000001 [label="{{<port0> 0} | ipu1_csi0\n/dev/v4l-subdev0 | {<port1> 1 | <port2> 2}}", shape=Mrecord, style=filled, fillcolor=green]
+	n00000001:port2 -> n00000005 [style=dashed]
+	n00000001:port1 -> n0000000f:port0 [style=dashed]
+	n00000001:port1 -> n0000000b:port0 [style=dashed]
+	n00000005 [label="ipu1_csi0 capture\n/dev/video0", shape=box, style=filled, fillcolor=yellow]
+	n0000000b [label="{{<port0> 0 | <port1> 1} | ipu1_vdic\n/dev/v4l-subdev1 | {<port2> 2}}", shape=Mrecord, style=filled, fillcolor=green]
+	n0000000b:port2 -> n0000000f:port0 [style=dashed]
+	n0000000f [label="{{<port0> 0} | ipu1_ic_prp\n/dev/v4l-subdev2 | {<port1> 1 | <port2> 2}}", shape=Mrecord, style=filled, fillcolor=green]
+	n0000000f:port1 -> n00000013:port0 [style=dashed]
+	n0000000f:port2 -> n0000001c:port0 [style=dashed]
+	n00000013 [label="{{<port0> 0} | ipu1_ic_prpenc\n/dev/v4l-subdev3 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n00000013:port1 -> n00000016 [style=dashed]
+	n00000016 [label="ipu1_ic_prpenc capture\n/dev/video1", shape=box, style=filled, fillcolor=yellow]
+	n0000001c [label="{{<port0> 0} | ipu1_ic_prpvf\n/dev/v4l-subdev4 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n0000001c:port1 -> n0000001f [style=dashed]
+	n0000001f [label="ipu1_ic_prpvf capture\n/dev/video2", shape=box, style=filled, fillcolor=yellow]
+	n0000002f [label="{{<port0> 0} | ipu1_csi1\n/dev/v4l-subdev5 | {<port1> 1 | <port2> 2}}", shape=Mrecord, style=filled, fillcolor=green]
+	n0000002f:port2 -> n00000033 [style=dashed]
+	n0000002f:port1 -> n0000000f:port0 [style=dashed]
+	n0000002f:port1 -> n0000000b:port0 [style=dashed]
+	n00000033 [label="ipu1_csi1 capture\n/dev/video3", shape=box, style=filled, fillcolor=yellow]
+	n0000003d [label="{{<port0> 0} | ipu2_csi0\n/dev/v4l-subdev6 | {<port1> 1 | <port2> 2}}", shape=Mrecord, style=filled, fillcolor=green]
+	n0000003d:port2 -> n00000041 [style=dashed]
+	n0000003d:port1 -> n0000004b:port0 [style=dashed]
+	n0000003d:port1 -> n00000047:port0 [style=dashed]
+	n00000041 [label="ipu2_csi0 capture\n/dev/video4", shape=box, style=filled, fillcolor=yellow]
+	n00000047 [label="{{<port0> 0 | <port1> 1} | ipu2_vdic\n/dev/v4l-subdev7 | {<port2> 2}}", shape=Mrecord, style=filled, fillcolor=green]
+	n00000047:port2 -> n0000004b:port0 [style=dashed]
+	n0000004b [label="{{<port0> 0} | ipu2_ic_prp\n/dev/v4l-subdev8 | {<port1> 1 | <port2> 2}}", shape=Mrecord, style=filled, fillcolor=green]
+	n0000004b:port1 -> n0000004f:port0 [style=dashed]
+	n0000004b:port2 -> n00000058:port0 [style=dashed]
+	n0000004f [label="{{<port0> 0} | ipu2_ic_prpenc\n/dev/v4l-subdev9 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n0000004f:port1 -> n00000052 [style=dashed]
+	n00000052 [label="ipu2_ic_prpenc capture\n/dev/video5", shape=box, style=filled, fillcolor=yellow]
+	n00000058 [label="{{<port0> 0} | ipu2_ic_prpvf\n/dev/v4l-subdev10 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n00000058:port1 -> n0000005b [style=dashed]
+	n0000005b [label="ipu2_ic_prpvf capture\n/dev/video6", shape=box, style=filled, fillcolor=yellow]
+	n0000006b [label="{{<port0> 0} | ipu2_csi1\n/dev/v4l-subdev11 | {<port1> 1 | <port2> 2}}", shape=Mrecord, style=filled, fillcolor=green]
+	n0000006b:port2 -> n0000006f [style=dashed]
+	n0000006b:port1 -> n0000004b:port0 [style=dashed]
+	n0000006b:port1 -> n00000047:port0 [style=dashed]
+	n0000006f [label="ipu2_csi1 capture\n/dev/video7", shape=box, style=filled, fillcolor=yellow]
+	n00000079 [label="{{<port0> 0 | <port1> 1} | ipu1_csi0_mux\n/dev/v4l-subdev12 | {<port2> 2}}", shape=Mrecord, style=filled, fillcolor=green]
+	n00000079:port2 -> n00000001:port0 [style=dashed]
+	n0000007d [label="{{<port0> 0 | <port1> 1} | ipu2_csi1_mux\n/dev/v4l-subdev13 | {<port2> 2}}", shape=Mrecord, style=filled, fillcolor=green]
+	n0000007d:port2 -> n0000006b:port0 [style=dashed]
+	n00000081 [label="{{} | adv7180 3-0021\n/dev/v4l-subdev14 | {<port0> 0}}", shape=Mrecord, style=filled, fillcolor=green]
+	n00000081:port0 -> n00000079:port1 [style=dashed]
+}
diff --git a/Documentation/admin-guide/media/imx6q-sabresd.dot b/Documentation/admin-guide/media/imx6q-sabresd.dot
new file mode 100644
index 000000000000..7d56cafa1944
--- /dev/null
+++ b/Documentation/admin-guide/media/imx6q-sabresd.dot
@@ -0,0 +1,56 @@
+digraph board {
+	rankdir=TB
+	n00000001 [label="{{<port0> 0} | ipu1_csi0\n/dev/v4l-subdev0 | {<port1> 1 | <port2> 2}}", shape=Mrecord, style=filled, fillcolor=green]
+	n00000001:port2 -> n00000005 [style=dashed]
+	n00000001:port1 -> n0000000f:port0 [style=dashed]
+	n00000001:port1 -> n0000000b:port0 [style=dashed]
+	n00000005 [label="ipu1_csi0 capture\n/dev/video0", shape=box, style=filled, fillcolor=yellow]
+	n0000000b [label="{{<port0> 0 | <port1> 1} | ipu1_vdic\n/dev/v4l-subdev1 | {<port2> 2}}", shape=Mrecord, style=filled, fillcolor=green]
+	n0000000b:port2 -> n0000000f:port0 [style=dashed]
+	n0000000f [label="{{<port0> 0} | ipu1_ic_prp\n/dev/v4l-subdev2 | {<port1> 1 | <port2> 2}}", shape=Mrecord, style=filled, fillcolor=green]
+	n0000000f:port1 -> n00000013:port0 [style=dashed]
+	n0000000f:port2 -> n0000001c:port0 [style=dashed]
+	n00000013 [label="{{<port0> 0} | ipu1_ic_prpenc\n/dev/v4l-subdev3 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n00000013:port1 -> n00000016 [style=dashed]
+	n00000016 [label="ipu1_ic_prpenc capture\n/dev/video1", shape=box, style=filled, fillcolor=yellow]
+	n0000001c [label="{{<port0> 0} | ipu1_ic_prpvf\n/dev/v4l-subdev4 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n0000001c:port1 -> n0000001f [style=dashed]
+	n0000001f [label="ipu1_ic_prpvf capture\n/dev/video2", shape=box, style=filled, fillcolor=yellow]
+	n0000002f [label="{{<port0> 0} | ipu1_csi1\n/dev/v4l-subdev5 | {<port1> 1 | <port2> 2}}", shape=Mrecord, style=filled, fillcolor=green]
+	n0000002f:port2 -> n00000033 [style=dashed]
+	n0000002f:port1 -> n0000000f:port0 [style=dashed]
+	n0000002f:port1 -> n0000000b:port0 [style=dashed]
+	n00000033 [label="ipu1_csi1 capture\n/dev/video3", shape=box, style=filled, fillcolor=yellow]
+	n0000003d [label="{{<port0> 0} | ipu2_csi0\n/dev/v4l-subdev6 | {<port1> 1 | <port2> 2}}", shape=Mrecord, style=filled, fillcolor=green]
+	n0000003d:port2 -> n00000041 [style=dashed]
+	n0000003d:port1 -> n0000004b:port0 [style=dashed]
+	n0000003d:port1 -> n00000047:port0 [style=dashed]
+	n00000041 [label="ipu2_csi0 capture\n/dev/video4", shape=box, style=filled, fillcolor=yellow]
+	n00000047 [label="{{<port0> 0 | <port1> 1} | ipu2_vdic\n/dev/v4l-subdev7 | {<port2> 2}}", shape=Mrecord, style=filled, fillcolor=green]
+	n00000047:port2 -> n0000004b:port0 [style=dashed]
+	n0000004b [label="{{<port0> 0} | ipu2_ic_prp\n/dev/v4l-subdev8 | {<port1> 1 | <port2> 2}}", shape=Mrecord, style=filled, fillcolor=green]
+	n0000004b:port1 -> n0000004f:port0 [style=dashed]
+	n0000004b:port2 -> n00000058:port0 [style=dashed]
+	n0000004f [label="{{<port0> 0} | ipu2_ic_prpenc\n/dev/v4l-subdev9 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n0000004f:port1 -> n00000052 [style=dashed]
+	n00000052 [label="ipu2_ic_prpenc capture\n/dev/video5", shape=box, style=filled, fillcolor=yellow]
+	n00000058 [label="{{<port0> 0} | ipu2_ic_prpvf\n/dev/v4l-subdev10 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n00000058:port1 -> n0000005b [style=dashed]
+	n0000005b [label="ipu2_ic_prpvf capture\n/dev/video6", shape=box, style=filled, fillcolor=yellow]
+	n0000006b [label="{{<port0> 0} | ipu2_csi1\n/dev/v4l-subdev11 | {<port1> 1 | <port2> 2}}", shape=Mrecord, style=filled, fillcolor=green]
+	n0000006b:port2 -> n0000006f [style=dashed]
+	n0000006b:port1 -> n0000004b:port0 [style=dashed]
+	n0000006b:port1 -> n00000047:port0 [style=dashed]
+	n0000006f [label="ipu2_csi1 capture\n/dev/video7", shape=box, style=filled, fillcolor=yellow]
+	n00000079 [label="{{<port0> 0} | imx6-mipi-csi2\n/dev/v4l-subdev12 | {<port1> 1 | <port2> 2 | <port3> 3 | <port4> 4}}", shape=Mrecord, style=filled, fillcolor=green]
+	n00000079:port2 -> n0000002f:port0 [style=dashed]
+	n00000079:port3 -> n0000003d:port0 [style=dashed]
+	n00000079:port1 -> n0000007f:port0 [style=dashed]
+	n00000079:port4 -> n00000083:port0 [style=dashed]
+	n0000007f [label="{{<port0> 0 | <port1> 1} | ipu1_csi0_mux\n/dev/v4l-subdev13 | {<port2> 2}}", shape=Mrecord, style=filled, fillcolor=green]
+	n0000007f:port2 -> n00000001:port0 [style=dashed]
+	n00000083 [label="{{<port0> 0 | <port1> 1} | ipu2_csi1_mux\n/dev/v4l-subdev14 | {<port2> 2}}", shape=Mrecord, style=filled, fillcolor=green]
+	n00000083:port2 -> n0000006b:port0 [style=dashed]
+	n00000087 [label="{{} | ov5640 1-003c\n/dev/v4l-subdev15 | {<port0> 0}}", shape=Mrecord, style=filled, fillcolor=green]
+	n00000087:port0 -> n00000079:port0 [style=dashed]
+}
diff --git a/Documentation/admin-guide/media/imx7.rst b/Documentation/admin-guide/media/imx7.rst
new file mode 100644
index 000000000000..1e442c97da47
--- /dev/null
+++ b/Documentation/admin-guide/media/imx7.rst
@@ -0,0 +1,161 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+i.MX7 Video Capture Driver
+==========================
+
+Introduction
+------------
+
+The i.MX7 contrary to the i.MX5/6 family does not contain an Image Processing
+Unit (IPU); because of that the capabilities to perform operations or
+manipulation of the capture frames are less feature rich.
+
+For image capture the i.MX7 has three units:
+- CMOS Sensor Interface (CSI)
+- Video Multiplexer
+- MIPI CSI-2 Receiver
+
+.. code-block:: none
+
+   MIPI Camera Input ---> MIPI CSI-2 --- > |\
+                                           | \
+                                           |  \
+                                           | M |
+                                           | U | ------>  CSI ---> Capture
+                                           | X |
+                                           |  /
+   Parallel Camera Input ----------------> | /
+                                           |/
+
+For additional information, please refer to the latest versions of the i.MX7
+reference manual [#f1]_.
+
+Entities
+--------
+
+imx7-mipi-csi2
+--------------
+
+This is the MIPI CSI-2 receiver entity. It has one sink pad to receive the pixel
+data from MIPI CSI-2 camera sensor. It has one source pad, corresponding to the
+virtual channel 0. This module is compliant to previous version of Samsung
+D-phy, and supports two D-PHY Rx Data lanes.
+
+csi-mux
+-------
+
+This is the video multiplexer. It has two sink pads to select from either camera
+sensor with a parallel interface or from MIPI CSI-2 virtual channel 0.  It has
+a single source pad that routes to the CSI.
+
+csi
+---
+
+The CSI enables the chip to connect directly to external CMOS image sensor. CSI
+can interface directly with Parallel and MIPI CSI-2 buses. It has 256 x 64 FIFO
+to store received image pixel data and embedded DMA controllers to transfer data
+from the FIFO through AHB bus.
+
+This entity has one sink pad that receives from the csi-mux entity and a single
+source pad that routes video frames directly to memory buffers. This pad is
+routed to a capture device node.
+
+Usage Notes
+-----------
+
+To aid in configuration and for backward compatibility with V4L2 applications
+that access controls only from video device nodes, the capture device interfaces
+inherit controls from the active entities in the current pipeline, so controls
+can be accessed either directly from the subdev or from the active capture
+device interface. For example, the sensor controls are available either from the
+sensor subdevs or from the active capture device.
+
+Warp7 with OV2680
+-----------------
+
+On this platform an OV2680 MIPI CSI-2 module is connected to the internal MIPI
+CSI-2 receiver. The following example configures a video capture pipeline with
+an output of 800x600, and BGGR 10 bit bayer format:
+
+.. code-block:: none
+
+   # Setup links
+   media-ctl -l "'ov2680 1-0036':0 -> 'imx7-mipi-csis.0':0[1]"
+   media-ctl -l "'imx7-mipi-csis.0':1 -> 'csi-mux':1[1]"
+   media-ctl -l "'csi-mux':2 -> 'csi':0[1]"
+   media-ctl -l "'csi':1 -> 'csi capture':0[1]"
+
+   # Configure pads for pipeline
+   media-ctl -V "'ov2680 1-0036':0 [fmt:SBGGR10_1X10/800x600 field:none]"
+   media-ctl -V "'csi-mux':1 [fmt:SBGGR10_1X10/800x600 field:none]"
+   media-ctl -V "'csi-mux':2 [fmt:SBGGR10_1X10/800x600 field:none]"
+   media-ctl -V "'imx7-mipi-csis.0':0 [fmt:SBGGR10_1X10/800x600 field:none]"
+   media-ctl -V "'csi':0 [fmt:SBGGR10_1X10/800x600 field:none]"
+
+After this streaming can start. The v4l2-ctl tool can be used to select any of
+the resolutions supported by the sensor.
+
+.. code-block:: none
+
+	# media-ctl -p
+	Media controller API version 5.2.0
+
+	Media device information
+	------------------------
+	driver          imx7-csi
+	model           imx-media
+	serial
+	bus info
+	hw revision     0x0
+	driver version  5.2.0
+
+	Device topology
+	- entity 1: csi (2 pads, 2 links)
+	            type V4L2 subdev subtype Unknown flags 0
+	            device node name /dev/v4l-subdev0
+	        pad0: Sink
+	                [fmt:SBGGR10_1X10/800x600 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:full-range]
+	                <- "csi-mux":2 [ENABLED]
+	        pad1: Source
+	                [fmt:SBGGR10_1X10/800x600 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:full-range]
+	                -> "csi capture":0 [ENABLED]
+
+	- entity 4: csi capture (1 pad, 1 link)
+	            type Node subtype V4L flags 0
+	            device node name /dev/video0
+	        pad0: Sink
+	                <- "csi":1 [ENABLED]
+
+	- entity 10: csi-mux (3 pads, 2 links)
+	             type V4L2 subdev subtype Unknown flags 0
+	             device node name /dev/v4l-subdev1
+	        pad0: Sink
+	                [fmt:Y8_1X8/1x1 field:none]
+	        pad1: Sink
+	               [fmt:SBGGR10_1X10/800x600 field:none]
+	                <- "imx7-mipi-csis.0":1 [ENABLED]
+	        pad2: Source
+	                [fmt:SBGGR10_1X10/800x600 field:none]
+	                -> "csi":0 [ENABLED]
+
+	- entity 14: imx7-mipi-csis.0 (2 pads, 2 links)
+	             type V4L2 subdev subtype Unknown flags 0
+	             device node name /dev/v4l-subdev2
+	        pad0: Sink
+	                [fmt:SBGGR10_1X10/800x600 field:none]
+	                <- "ov2680 1-0036":0 [ENABLED]
+	        pad1: Source
+	                [fmt:SBGGR10_1X10/800x600 field:none]
+	                -> "csi-mux":1 [ENABLED]
+
+	- entity 17: ov2680 1-0036 (1 pad, 1 link)
+	             type V4L2 subdev subtype Sensor flags 0
+	             device node name /dev/v4l-subdev3
+	        pad0: Source
+	                [fmt:SBGGR10_1X10/800x600@1/30 field:none colorspace:srgb]
+	                -> "imx7-mipi-csis.0":0 [ENABLED]
+
+References
+----------
+
+.. [#f1] https://www.nxp.com/docs/en/reference-manual/IMX7SRM.pdf
diff --git a/Documentation/admin-guide/media/index.rst b/Documentation/admin-guide/media/index.rst
new file mode 100644
index 000000000000..6e5e6bdb6d4b
--- /dev/null
+++ b/Documentation/admin-guide/media/index.rst
@@ -0,0 +1,122 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: <isonum.txt>
+
+============================
+Media subsystem usage guides
+============================
+
+This section contains usage information about media subsystem and
+its supported drivers.
+
+Please see:
+
+- :doc:`/userspace-api/media/index`
+     for the userspace APIs used on media devices.
+
+- :doc:`/driver-api/media/index`
+     for driver development information and Kernel APIs used by
+     media devices;
+
+.. _uapi-v4l-drivers:
+
+################################################
+Video4Linux (V4L)  driver-specific documentation
+################################################
+
+.. only:: html
+
+    .. class:: toc-title
+
+        Table of Contents
+
+.. toctree::
+	:maxdepth: 5
+	:numbered:
+
+	cardlist
+
+	v4l-with-ir
+
+	bttv
+	cafe_ccic
+	cpia2
+	cx88
+	davinci-vpbe
+	fimc
+	imx
+	imx7
+	ipu3
+	ivtv
+	meye
+	omap3isp
+	omap4_camera
+	philips
+	qcom_camss
+	rcar-fdp1
+	saa7134
+	si470x
+	si4713
+	si476x
+	vimc
+	vivid
+
+##############################################
+Linux Digital TV driver-specific documentation
+##############################################
+
+.. only:: html
+
+    .. class:: toc-title
+
+        Table of Contents
+
+.. toctree::
+	:maxdepth: 5
+	:numbered:
+
+	dvb_intro
+	ci
+	faq
+	dvb_references
+
+	cards
+	avermedia
+	bt8xx
+	lmedm04
+	opera-firmware
+	technisat
+	ttusb-dec
+	zr364xx
+
+#################################
+CEC driver-specific documentation
+#################################
+
+.. only:: html
+
+    .. class:: toc-title
+
+        Table of Contents
+
+.. toctree::
+	:maxdepth: 5
+	:numbered:
+
+	pulse8-cec
+
+**Copyright** |copy| 1999-2020 : LinuxTV Developers
+
+::
+
+  This documentation is free software; you can redistribute it and/or modify it
+  under the terms of the 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.
+
+  For more details see the file COPYING in the source distribution of Linux.
diff --git a/Documentation/admin-guide/media/ipu3.rst b/Documentation/admin-guide/media/ipu3.rst
new file mode 100644
index 000000000000..11e2ac4888f5
--- /dev/null
+++ b/Documentation/admin-guide/media/ipu3.rst
@@ -0,0 +1,571 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: <isonum.txt>
+
+===============================================================
+Intel Image Processing Unit 3 (IPU3) Imaging Unit (ImgU) driver
+===============================================================
+
+Copyright |copy| 2018 Intel Corporation
+
+Introduction
+============
+
+This file documents the Intel IPU3 (3rd generation Image Processing Unit)
+Imaging Unit drivers located under drivers/media/pci/intel/ipu3 (CIO2) as well
+as under drivers/staging/media/ipu3 (ImgU).
+
+The Intel IPU3 found in certain Kaby Lake (as well as certain Sky Lake)
+platforms (U/Y processor lines) is made up of two parts namely the Imaging Unit
+(ImgU) and the CIO2 device (MIPI CSI2 receiver).
+
+The CIO2 device receives the raw Bayer data from the sensors and outputs the
+frames in a format that is specific to the IPU3 (for consumption by the IPU3
+ImgU). The CIO2 driver is available as drivers/media/pci/intel/ipu3/ipu3-cio2*
+and is enabled through the CONFIG_VIDEO_IPU3_CIO2 config option.
+
+The Imaging Unit (ImgU) is responsible for processing images captured
+by the IPU3 CIO2 device. The ImgU driver sources can be found under
+drivers/staging/media/ipu3 directory. The driver is enabled through the
+CONFIG_VIDEO_IPU3_IMGU config option.
+
+The two driver modules are named ipu3_csi2 and ipu3_imgu, respectively.
+
+The drivers has been tested on Kaby Lake platforms (U/Y processor lines).
+
+Both of the drivers implement V4L2, Media Controller and V4L2 sub-device
+interfaces. The IPU3 CIO2 driver supports camera sensors connected to the CIO2
+MIPI CSI-2 interfaces through V4L2 sub-device sensor drivers.
+
+CIO2
+====
+
+The CIO2 is represented as a single V4L2 subdev, which provides a V4L2 subdev
+interface to the user space. There is a video node for each CSI-2 receiver,
+with a single media controller interface for the entire device.
+
+The CIO2 contains four independent capture channel, each with its own MIPI CSI-2
+receiver and DMA engine. Each channel is modelled as a V4L2 sub-device exposed
+to userspace as a V4L2 sub-device node and has two pads:
+
+.. tabularcolumns:: |p{0.8cm}|p{4.0cm}|p{4.0cm}|
+
+.. flat-table::
+
+    * - pad
+      - direction
+      - purpose
+
+    * - 0
+      - sink
+      - MIPI CSI-2 input, connected to the sensor subdev
+
+    * - 1
+      - source
+      - Raw video capture, connected to the V4L2 video interface
+
+The V4L2 video interfaces model the DMA engines. They are exposed to userspace
+as V4L2 video device nodes.
+
+Capturing frames in raw Bayer format
+------------------------------------
+
+CIO2 MIPI CSI2 receiver is used to capture frames (in packed raw Bayer format)
+from the raw sensors connected to the CSI2 ports. The captured frames are used
+as input to the ImgU driver.
+
+Image processing using IPU3 ImgU requires tools such as raw2pnm [#f1]_, and
+yavta [#f2]_ due to the following unique requirements and / or features specific
+to IPU3.
+
+-- The IPU3 CSI2 receiver outputs the captured frames from the sensor in packed
+raw Bayer format that is specific to IPU3.
+
+-- Multiple video nodes have to be operated simultaneously.
+
+Let us take the example of ov5670 sensor connected to CSI2 port 0, for a
+2592x1944 image capture.
+
+Using the media contorller APIs, the ov5670 sensor is configured to send
+frames in packed raw Bayer format to IPU3 CSI2 receiver.
+
+# This example assumes /dev/media0 as the CIO2 media device
+
+export MDEV=/dev/media0
+
+# and that ov5670 sensor is connected to i2c bus 10 with address 0x36
+
+export SDEV=$(media-ctl -d $MDEV -e "ov5670 10-0036")
+
+# Establish the link for the media devices using media-ctl [#f3]_
+media-ctl -d $MDEV -l "ov5670:0 -> ipu3-csi2 0:0[1]"
+
+# Set the format for the media devices
+media-ctl -d $MDEV -V "ov5670:0 [fmt:SGRBG10/2592x1944]"
+
+media-ctl -d $MDEV -V "ipu3-csi2 0:0 [fmt:SGRBG10/2592x1944]"
+
+media-ctl -d $MDEV -V "ipu3-csi2 0:1 [fmt:SGRBG10/2592x1944]"
+
+Once the media pipeline is configured, desired sensor specific settings
+(such as exposure and gain settings) can be set, using the yavta tool.
+
+e.g
+
+yavta -w 0x009e0903 444 $SDEV
+
+yavta -w 0x009e0913 1024 $SDEV
+
+yavta -w 0x009e0911 2046 $SDEV
+
+Once the desired sensor settings are set, frame captures can be done as below.
+
+e.g
+
+yavta --data-prefix -u -c10 -n5 -I -s2592x1944 --file=/tmp/frame-#.bin \
+      -f IPU3_SGRBG10 $(media-ctl -d $MDEV -e "ipu3-cio2 0")
+
+With the above command, 10 frames are captured at 2592x1944 resolution, with
+sGRBG10 format and output as IPU3_SGRBG10 format.
+
+The captured frames are available as /tmp/frame-#.bin files.
+
+ImgU
+====
+
+The ImgU is represented as two V4L2 subdevs, each of which provides a V4L2
+subdev interface to the user space.
+
+Each V4L2 subdev represents a pipe, which can support a maximum of 2 streams.
+This helps to support advanced camera features like Continuous View Finder (CVF)
+and Snapshot During Video(SDV).
+
+The ImgU contains two independent pipes, each modelled as a V4L2 sub-device
+exposed to userspace as a V4L2 sub-device node.
+
+Each pipe has two sink pads and three source pads for the following purpose:
+
+.. tabularcolumns:: |p{0.8cm}|p{4.0cm}|p{4.0cm}|
+
+.. flat-table::
+
+    * - pad
+      - direction
+      - purpose
+
+    * - 0
+      - sink
+      - Input raw video stream
+
+    * - 1
+      - sink
+      - Processing parameters
+
+    * - 2
+      - source
+      - Output processed video stream
+
+    * - 3
+      - source
+      - Output viewfinder video stream
+
+    * - 4
+      - source
+      - 3A statistics
+
+Each pad is connected to a corresponding V4L2 video interface, exposed to 
+userspace as a V4L2 video device node.
+
+Device operation
+----------------
+
+With ImgU, once the input video node ("ipu3-imgu 0/1":0, in
+<entity>:<pad-number> format) is queued with buffer (in packed raw Bayer
+format), ImgU starts processing the buffer and produces the video output in YUV
+format and statistics output on respective output nodes. The driver is expected
+to have buffers ready for all of parameter, output and statistics nodes, when
+input video node is queued with buffer.
+
+At a minimum, all of input, main output, 3A statistics and viewfinder
+video nodes should be enabled for IPU3 to start image processing.
+
+Each ImgU V4L2 subdev has the following set of video nodes.
+
+input, output and viewfinder video nodes
+----------------------------------------
+
+The frames (in packed raw Bayer format specific to the IPU3) received by the
+input video node is processed by the IPU3 Imaging Unit and are output to 2 video
+nodes, with each targeting a different purpose (main output and viewfinder
+output).
+
+Details onand the Bayer format specific to the IPU3 can be found in
+:ref:`v4l2-pix-fmt-ipu3-sbggr10`.
+
+The driver supports V4L2 Video Capture Interface as defined at :ref:`devices`.
+
+Only the multi-planar API is supported. More details can be found at
+:ref:`planar-apis`.
+
+Parameters video node
+---------------------
+
+The parameters video node receives the ImgU algorithm parameters that are used
+to configure how the ImgU algorithms process the image.
+
+Details on processing parameters specific to the IPU3 can be found in
+:ref:`v4l2-meta-fmt-params`.
+
+3A statistics video node
+------------------------
+
+3A statistics video node is used by the ImgU driver to output the 3A (auto
+focus, auto exposure and auto white balance) statistics for the frames that are
+being processed by the ImgU to user space applications. User space applications
+can use this statistics data to compute the desired algorithm parameters for
+the ImgU.
+
+Configuring the Intel IPU3
+==========================
+
+The IPU3 ImgU pipelines can be configured using the Media Controller, defined at
+:ref:`media_controller`.
+
+Firmware binary selection
+-------------------------
+
+The firmware binary is selected using the V4L2_CID_INTEL_IPU3_MODE, currently
+defined in drivers/staging/media/ipu3/include/intel-ipu3.h . "VIDEO" and "STILL"
+modes are available.
+
+Processing the image in raw Bayer format
+----------------------------------------
+
+Configuring ImgU V4L2 subdev for image processing
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ImgU V4L2 subdevs have to be configured with media controller APIs to have
+all the video nodes setup correctly.
+
+Let us take "ipu3-imgu 0" subdev as an example.
+
+media-ctl -d $MDEV -r
+
+media-ctl -d $MDEV -l "ipu3-imgu 0 input":0 -> "ipu3-imgu 0":0[1]
+
+media-ctl -d $MDEV -l "ipu3-imgu 0":2 -> "ipu3-imgu 0 output":0[1]
+
+media-ctl -d $MDEV -l "ipu3-imgu 0":3 -> "ipu3-imgu 0 viewfinder":0[1]
+
+media-ctl -d $MDEV -l "ipu3-imgu 0":4 -> "ipu3-imgu 0 3a stat":0[1]
+
+Also the pipe mode of the corresponding V4L2 subdev should be set as desired
+(e.g 0 for video mode or 1 for still mode) through the control id 0x009819a1 as
+below.
+
+yavta -w "0x009819A1 1" /dev/v4l-subdev7
+
+Certain hardware blocks in ImgU pipeline can change the frame resolution by
+cropping or scaling, these hardware blocks include Input Feeder(IF), Bayer Down
+Scaler (BDS) and Geometric Distortion Correction (GDC).
+There is also a block which can change the frame resolution - YUV Scaler, it is
+only applicable to the secondary output.
+
+RAW Bayer frames go through these ImgU pipeline hardware blocks and the final
+processed image output to the DDR memory.
+
+.. kernel-figure::  ipu3_rcb.svg
+   :alt: ipu3 resolution blocks image
+
+   IPU3 resolution change hardware blocks
+
+**Input Feeder**
+
+Input Feeder gets the Bayer frame data from the sensor, it can enable cropping
+of lines and columns from the frame and then store pixels into device's internal
+pixel buffer which are ready to readout by following blocks.
+
+**Bayer Down Scaler**
+
+Bayer Down Scaler is capable of performing image scaling in Bayer domain, the
+downscale factor can be configured from 1X to 1/4X in each axis with
+configuration steps of 0.03125 (1/32).
+
+**Geometric Distortion Correction**
+
+Geometric Distortion Correction is used to performe correction of distortions
+and image filtering. It needs some extra filter and envelop padding pixels to
+work, so the input resolution of GDC should be larger than the output
+resolution.
+
+**YUV Scaler**
+
+YUV Scaler which similar with BDS, but it is mainly do image down scaling in
+YUV domain, it can support up to 1/12X down scaling, but it can not be applied
+to the main output.
+
+The ImgU V4L2 subdev has to be configured with the supported resolutions in all
+the above hardware blocks, for a given input resolution.
+For a given supported resolution for an input frame, the Input Feeder, Bayer
+Down Scaler and GDC blocks should be configured with the supported resolutions
+as each hardware block has its own alignment requirement.
+
+You must configure the output resolution of the hardware blocks smartly to meet
+the hardware requirement along with keeping the maximum field of view. The
+intermediate resolutions can be generated by specific tool -
+
+https://github.com/intel/intel-ipu3-pipecfg
+
+This tool can be used to generate intermediate resolutions. More information can
+be obtained by looking at the following IPU3 ImgU configuration table.
+
+https://chromium.googlesource.com/chromiumos/overlays/board-overlays/+/master
+
+Under baseboard-poppy/media-libs/cros-camera-hal-configs-poppy/files/gcss
+directory, graph_settings_ov5670.xml can be used as an example.
+
+The following steps prepare the ImgU pipeline for the image processing.
+
+1. The ImgU V4L2 subdev data format should be set by using the
+VIDIOC_SUBDEV_S_FMT on pad 0, using the GDC width and height obtained above.
+
+2. The ImgU V4L2 subdev cropping should be set by using the
+VIDIOC_SUBDEV_S_SELECTION on pad 0, with V4L2_SEL_TGT_CROP as the target,
+using the input feeder height and width.
+
+3. The ImgU V4L2 subdev composing should be set by using the
+VIDIOC_SUBDEV_S_SELECTION on pad 0, with V4L2_SEL_TGT_COMPOSE as the target,
+using the BDS height and width.
+
+For the ov5670 example, for an input frame with a resolution of 2592x1944
+(which is input to the ImgU subdev pad 0), the corresponding resolutions
+for input feeder, BDS and GDC are 2592x1944, 2592x1944 and 2560x1920
+respectively.
+
+Once this is done, the received raw Bayer frames can be input to the ImgU
+V4L2 subdev as below, using the open source application v4l2n [#f1]_.
+
+For an image captured with 2592x1944 [#f4]_ resolution, with desired output
+resolution as 2560x1920 and viewfinder resolution as 2560x1920, the following
+v4l2n command can be used. This helps process the raw Bayer frames and produces
+the desired results for the main output image and the viewfinder output, in NV12
+format.
+
+v4l2n --pipe=4 --load=/tmp/frame-#.bin --open=/dev/video4
+--fmt=type:VIDEO_OUTPUT_MPLANE,width=2592,height=1944,pixelformat=0X47337069
+--reqbufs=type:VIDEO_OUTPUT_MPLANE,count:1 --pipe=1 --output=/tmp/frames.out
+--open=/dev/video5
+--fmt=type:VIDEO_CAPTURE_MPLANE,width=2560,height=1920,pixelformat=NV12
+--reqbufs=type:VIDEO_CAPTURE_MPLANE,count:1 --pipe=2 --output=/tmp/frames.vf
+--open=/dev/video6
+--fmt=type:VIDEO_CAPTURE_MPLANE,width=2560,height=1920,pixelformat=NV12
+--reqbufs=type:VIDEO_CAPTURE_MPLANE,count:1 --pipe=3 --open=/dev/video7
+--output=/tmp/frames.3A --fmt=type:META_CAPTURE,?
+--reqbufs=count:1,type:META_CAPTURE --pipe=1,2,3,4 --stream=5
+
+You can also use yavta [#f2]_ command to do same thing as above:
+
+.. code-block:: none
+
+	yavta --data-prefix -Bcapture-mplane -c10 -n5 -I -s2592x1944 \
+	--file=frame-#.out-f NV12 /dev/video5 & \
+	yavta --data-prefix -Bcapture-mplane -c10 -n5 -I -s2592x1944 \
+	--file=frame-#.vf -f NV12 /dev/video6 & \
+	yavta --data-prefix -Bmeta-capture -c10 -n5 -I \
+	--file=frame-#.3a /dev/video7 & \
+	yavta --data-prefix -Boutput-mplane -c10 -n5 -I -s2592x1944 \
+	--file=/tmp/frame-in.cio2 -f IPU3_SGRBG10 /dev/video4
+
+where /dev/video4, /dev/video5, /dev/video6 and /dev/video7 devices point to
+input, output, viewfinder and 3A statistics video nodes respectively.
+
+Converting the raw Bayer image into YUV domain
+----------------------------------------------
+
+The processed images after the above step, can be converted to YUV domain
+as below.
+
+Main output frames
+~~~~~~~~~~~~~~~~~~
+
+raw2pnm -x2560 -y1920 -fNV12 /tmp/frames.out /tmp/frames.out.ppm
+
+where 2560x1920 is output resolution, NV12 is the video format, followed
+by input frame and output PNM file.
+
+Viewfinder output frames
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+raw2pnm -x2560 -y1920 -fNV12 /tmp/frames.vf /tmp/frames.vf.ppm
+
+where 2560x1920 is output resolution, NV12 is the video format, followed
+by input frame and output PNM file.
+
+Example user space code for IPU3
+================================
+
+User space code that configures and uses IPU3 is available here.
+
+https://chromium.googlesource.com/chromiumos/platform/arc-camera/+/master/
+
+The source can be located under hal/intel directory.
+
+Overview of IPU3 pipeline
+=========================
+
+IPU3 pipeline has a number of image processing stages, each of which takes a
+set of parameters as input. The major stages of pipelines are shown here:
+
+.. kernel-render:: DOT
+   :alt: IPU3 ImgU Pipeline
+   :caption: IPU3 ImgU Pipeline Diagram
+
+   digraph "IPU3 ImgU" {
+       node [shape=box]
+       splines="ortho"
+       rankdir="LR"
+
+       a [label="Raw pixels"]
+       b [label="Bayer Downscaling"]
+       c [label="Optical Black Correction"]
+       d [label="Linearization"]
+       e [label="Lens Shading Correction"]
+       f [label="White Balance / Exposure / Focus Apply"]
+       g [label="Bayer Noise Reduction"]
+       h [label="ANR"]
+       i [label="Demosaicing"]
+       j [label="Color Correction Matrix"]
+       k [label="Gamma correction"]
+       l [label="Color Space Conversion"]
+       m [label="Chroma Down Scaling"]
+       n [label="Chromatic Noise Reduction"]
+       o [label="Total Color Correction"]
+       p [label="XNR3"]
+       q [label="TNR"]
+       r [label="DDR", style=filled, fillcolor=yellow, shape=cylinder]
+       s [label="YUV Downscaling"]
+       t [label="DDR", style=filled, fillcolor=yellow, shape=cylinder]
+
+       { rank=same; a -> b -> c -> d -> e -> f -> g -> h -> i }
+       { rank=same; j -> k -> l -> m -> n -> o -> p -> q -> s -> t}
+
+       a -> j [style=invis, weight=10]
+       i -> j
+       q -> r
+   }
+
+The table below presents a description of the above algorithms.
+
+======================== =======================================================
+Name			 Description
+======================== =======================================================
+Optical Black Correction Optical Black Correction block subtracts a pre-defined
+			 value from the respective pixel values to obtain better
+			 image quality.
+			 Defined in :c:type:`ipu3_uapi_obgrid_param`.
+Linearization		 This algo block uses linearization parameters to
+			 address non-linearity sensor effects. The Lookup table
+			 table is defined in
+			 :c:type:`ipu3_uapi_isp_lin_vmem_params`.
+SHD			 Lens shading correction is used to correct spatial
+			 non-uniformity of the pixel response due to optical
+			 lens shading. This is done by applying a different gain
+			 for each pixel. The gain, black level etc are
+			 configured in :c:type:`ipu3_uapi_shd_config_static`.
+BNR			 Bayer noise reduction block removes image noise by
+			 applying a bilateral filter.
+			 See :c:type:`ipu3_uapi_bnr_static_config` for details.
+ANR			 Advanced Noise Reduction is a block based algorithm
+			 that performs noise reduction in the Bayer domain. The
+			 convolution matrix etc can be found in
+			 :c:type:`ipu3_uapi_anr_config`.
+DM			 Demosaicing converts raw sensor data in Bayer format
+			 into RGB (Red, Green, Blue) presentation. Then add
+			 outputs of estimation of Y channel for following stream
+			 processing by Firmware. The struct is defined as
+			 :c:type:`ipu3_uapi_dm_config`.
+Color Correction	 Color Correction algo transforms sensor specific color
+			 space to the standard "sRGB" color space. This is done
+			 by applying 3x3 matrix defined in
+			 :c:type:`ipu3_uapi_ccm_mat_config`.
+Gamma correction	 Gamma correction :c:type:`ipu3_uapi_gamma_config` is a
+			 basic non-linear tone mapping correction that is
+			 applied per pixel for each pixel component.
+CSC			 Color space conversion transforms each pixel from the
+			 RGB primary presentation to YUV (Y: brightness,
+			 UV: Luminance) presentation. This is done by applying
+			 a 3x3 matrix defined in
+			 :c:type:`ipu3_uapi_csc_mat_config`
+CDS			 Chroma down sampling
+			 After the CSC is performed, the Chroma Down Sampling
+			 is applied for a UV plane down sampling by a factor
+			 of 2 in each direction for YUV 4:2:0 using a 4x2
+			 configurable filter :c:type:`ipu3_uapi_cds_params`.
+CHNR			 Chroma noise reduction
+			 This block processes only the chrominance pixels and
+			 performs noise reduction by cleaning the high
+			 frequency noise.
+			 See struct :c:type:`ipu3_uapi_yuvp1_chnr_config`.
+TCC			 Total color correction as defined in struct
+			 :c:type:`ipu3_uapi_yuvp2_tcc_static_config`.
+XNR3			 eXtreme Noise Reduction V3 is the third revision of
+			 noise reduction algorithm used to improve image
+			 quality. This removes the low frequency noise in the
+			 captured image. Two related structs are  being defined,
+			 :c:type:`ipu3_uapi_isp_xnr3_params` for ISP data memory
+			 and :c:type:`ipu3_uapi_isp_xnr3_vmem_params` for vector
+			 memory.
+TNR			 Temporal Noise Reduction block compares successive
+			 frames in time to remove anomalies / noise in pixel
+			 values. :c:type:`ipu3_uapi_isp_tnr3_vmem_params` and
+			 :c:type:`ipu3_uapi_isp_tnr3_params` are defined for ISP
+			 vector and data memory respectively.
+======================== =======================================================
+
+Other often encountered acronyms not listed in above table:
+
+	ACC
+		Accelerator cluster
+	AWB_FR
+		Auto white balance filter response statistics
+	BDS
+		Bayer downscaler parameters
+	CCM
+		Color correction matrix coefficients
+	IEFd
+		Image enhancement filter directed
+	Obgrid
+		Optical black level compensation
+	OSYS
+		Output system configuration
+	ROI
+		Region of interest
+	YDS
+		Y down sampling
+	YTM
+		Y-tone mapping
+
+A few stages of the pipeline will be executed by firmware running on the ISP
+processor, while many others will use a set of fixed hardware blocks also
+called accelerator cluster (ACC) to crunch pixel data and produce statistics.
+
+ACC parameters of individual algorithms, as defined by
+:c:type:`ipu3_uapi_acc_param`, can be chosen to be applied by the user
+space through struct :c:type:`ipu3_uapi_flags` embedded in
+:c:type:`ipu3_uapi_params` structure. For parameters that are configured as
+not enabled by the user space, the corresponding structs are ignored by the
+driver, in which case the existing configuration of the algorithm will be
+preserved.
+
+References
+==========
+
+.. [#f5] drivers/staging/media/ipu3/include/intel-ipu3.h
+
+.. [#f1] https://github.com/intel/nvt
+
+.. [#f2] http://git.ideasonboard.org/yavta.git
+
+.. [#f3] http://git.ideasonboard.org/?p=media-ctl.git;a=summary
+
+.. [#f4] ImgU limitation requires an additional 16x16 for all input resolutions
diff --git a/Documentation/admin-guide/media/ipu3_rcb.svg b/Documentation/admin-guide/media/ipu3_rcb.svg
new file mode 100644
index 000000000000..d878421b42a0
--- /dev/null
+++ b/Documentation/admin-guide/media/ipu3_rcb.svg
@@ -0,0 +1,331 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="774pt" height="152pt" viewBox="0 0 774 152" version="1.1">
+<defs>
+<g>
+<symbol overflow="visible" id="glyph0-0">
+<path style="stroke:none;" d="M 1 0 L 1 -15 L 9 -15 L 9 0 Z M 8 -1 L 8 -14 L 2 -14 L 2 -1 Z M 8 -1 "/>
+</symbol>
+<symbol overflow="visible" id="glyph0-1">
+<path style="stroke:none;" d="M 4.6875 -1.15625 C 5.519531 -1.15625 6.15625 -1.316406 6.59375 -1.640625 C 7.039062 -1.960938 7.265625 -2.441406 7.265625 -3.078125 C 7.265625 -3.460938 7.179688 -3.789062 7.015625 -4.0625 C 6.859375 -4.34375 6.644531 -4.582031 6.375 -4.78125 C 6.113281 -4.988281 5.816406 -5.171875 5.484375 -5.328125 C 5.148438 -5.484375 4.804688 -5.628906 4.453125 -5.765625 C 4.054688 -5.921875 3.675781 -6.097656 3.3125 -6.296875 C 2.945312 -6.492188 2.617188 -6.726562 2.328125 -7 C 2.046875 -7.269531 1.820312 -7.582031 1.65625 -7.9375 C 1.488281 -8.300781 1.40625 -8.726562 1.40625 -9.21875 C 1.40625 -10.300781 1.742188 -11.144531 2.421875 -11.75 C 3.097656 -12.351562 4.046875 -12.65625 5.265625 -12.65625 C 5.597656 -12.65625 5.925781 -12.628906 6.25 -12.578125 C 6.570312 -12.535156 6.875 -12.476562 7.15625 -12.40625 C 7.4375 -12.34375 7.6875 -12.265625 7.90625 -12.171875 C 8.125 -12.085938 8.300781 -12 8.4375 -11.90625 L 7.921875 -10.515625 C 7.648438 -10.679688 7.28125 -10.84375 6.8125 -11 C 6.351562 -11.15625 5.835938 -11.234375 5.265625 -11.234375 C 4.660156 -11.234375 4.140625 -11.082031 3.703125 -10.78125 C 3.265625 -10.488281 3.046875 -10.039062 3.046875 -9.4375 C 3.046875 -9.09375 3.109375 -8.800781 3.234375 -8.5625 C 3.359375 -8.320312 3.53125 -8.109375 3.75 -7.921875 C 3.96875 -7.742188 4.222656 -7.582031 4.515625 -7.4375 C 4.804688 -7.289062 5.128906 -7.144531 5.484375 -7 C 5.984375 -6.789062 6.441406 -6.578125 6.859375 -6.359375 C 7.285156 -6.148438 7.648438 -5.894531 7.953125 -5.59375 C 8.253906 -5.300781 8.488281 -4.953125 8.65625 -4.546875 C 8.820312 -4.148438 8.90625 -3.664062 8.90625 -3.09375 C 8.90625 -2.019531 8.539062 -1.191406 7.8125 -0.609375 C 7.082031 -0.0234375 6.039062 0.265625 4.6875 0.265625 C 4.238281 0.265625 3.820312 0.234375 3.4375 0.171875 C 3.050781 0.109375 2.707031 0.03125 2.40625 -0.0625 C 2.101562 -0.15625 1.835938 -0.25 1.609375 -0.34375 C 1.390625 -0.4375 1.21875 -0.519531 1.09375 -0.59375 L 1.59375 -1.953125 C 1.863281 -1.804688 2.257812 -1.632812 2.78125 -1.4375 C 3.300781 -1.25 3.9375 -1.15625 4.6875 -1.15625 Z M 4.6875 -1.15625 "/>
+</symbol>
+<symbol overflow="visible" id="glyph0-2">
+<path style="stroke:none;" d="M 5.1875 -9.5 C 6.4375 -9.5 7.398438 -9.109375 8.078125 -8.328125 C 8.753906 -7.546875 9.09375 -6.363281 9.09375 -4.78125 L 9.09375 -4.203125 L 2.453125 -4.203125 C 2.523438 -3.242188 2.84375 -2.515625 3.40625 -2.015625 C 3.976562 -1.515625 4.773438 -1.265625 5.796875 -1.265625 C 6.390625 -1.265625 6.890625 -1.3125 7.296875 -1.40625 C 7.710938 -1.5 8.023438 -1.597656 8.234375 -1.703125 L 8.453125 -0.296875 C 8.253906 -0.191406 7.894531 -0.0820312 7.375 0.03125 C 6.851562 0.15625 6.269531 0.21875 5.625 0.21875 C 4.820312 0.21875 4.113281 0.0976562 3.5 -0.140625 C 2.894531 -0.390625 2.394531 -0.726562 2 -1.15625 C 1.601562 -1.582031 1.300781 -2.09375 1.09375 -2.6875 C 0.894531 -3.28125 0.796875 -3.925781 0.796875 -4.625 C 0.796875 -5.445312 0.921875 -6.164062 1.171875 -6.78125 C 1.429688 -7.394531 1.765625 -7.898438 2.171875 -8.296875 C 2.585938 -8.703125 3.054688 -9.003906 3.578125 -9.203125 C 4.097656 -9.398438 4.632812 -9.5 5.1875 -9.5 Z M 7.421875 -5.546875 C 7.421875 -6.328125 7.210938 -6.945312 6.796875 -7.40625 C 6.390625 -7.863281 5.84375 -8.09375 5.15625 -8.09375 C 4.769531 -8.09375 4.421875 -8.019531 4.109375 -7.875 C 3.796875 -7.726562 3.523438 -7.535156 3.296875 -7.296875 C 3.066406 -7.054688 2.882812 -6.78125 2.75 -6.46875 C 2.625 -6.164062 2.539062 -5.859375 2.5 -5.546875 Z M 7.421875 -5.546875 "/>
+</symbol>
+<symbol overflow="visible" id="glyph0-3">
+<path style="stroke:none;" d="M 1.421875 -9.015625 C 2.015625 -9.160156 2.609375 -9.273438 3.203125 -9.359375 C 3.796875 -9.441406 4.351562 -9.484375 4.875 -9.484375 C 6.113281 -9.484375 7.050781 -9.160156 7.6875 -8.515625 C 8.320312 -7.878906 8.640625 -6.851562 8.640625 -5.4375 L 8.640625 0 L 7 0 L 7 -5.140625 C 7 -5.742188 6.945312 -6.226562 6.84375 -6.59375 C 6.738281 -6.96875 6.585938 -7.257812 6.390625 -7.46875 C 6.191406 -7.675781 5.957031 -7.816406 5.6875 -7.890625 C 5.414062 -7.972656 5.117188 -8.015625 4.796875 -8.015625 C 4.535156 -8.015625 4.253906 -8 3.953125 -7.96875 C 3.648438 -7.9375 3.359375 -7.894531 3.078125 -7.84375 L 3.078125 0 L 1.421875 0 Z M 1.421875 -9.015625 "/>
+</symbol>
+<symbol overflow="visible" id="glyph0-4">
+<path style="stroke:none;" d="M 7.015625 -2.3125 C 7.015625 -2.644531 6.878906 -2.914062 6.609375 -3.125 C 6.335938 -3.34375 6 -3.53125 5.59375 -3.6875 C 5.1875 -3.851562 4.742188 -4.015625 4.265625 -4.171875 C 3.785156 -4.328125 3.335938 -4.515625 2.921875 -4.734375 C 2.515625 -4.960938 2.175781 -5.242188 1.90625 -5.578125 C 1.632812 -5.910156 1.5 -6.34375 1.5 -6.875 C 1.5 -7.625 1.800781 -8.25 2.40625 -8.75 C 3.007812 -9.25 3.960938 -9.5 5.265625 -9.5 C 5.765625 -9.5 6.285156 -9.460938 6.828125 -9.390625 C 7.367188 -9.316406 7.832031 -9.21875 8.21875 -9.09375 L 7.921875 -7.625 C 7.816406 -7.675781 7.671875 -7.726562 7.484375 -7.78125 C 7.296875 -7.84375 7.082031 -7.894531 6.84375 -7.9375 C 6.601562 -7.988281 6.34375 -8.023438 6.0625 -8.046875 C 5.789062 -8.078125 5.53125 -8.09375 5.28125 -8.09375 C 3.84375 -8.09375 3.125 -7.703125 3.125 -6.921875 C 3.125 -6.640625 3.257812 -6.398438 3.53125 -6.203125 C 3.800781 -6.015625 4.144531 -5.835938 4.5625 -5.671875 C 4.976562 -5.515625 5.425781 -5.351562 5.90625 -5.1875 C 6.382812 -5.019531 6.828125 -4.816406 7.234375 -4.578125 C 7.648438 -4.335938 7.992188 -4.046875 8.265625 -3.703125 C 8.546875 -3.367188 8.6875 -2.941406 8.6875 -2.421875 C 8.6875 -1.578125 8.359375 -0.925781 7.703125 -0.46875 C 7.046875 -0.0078125 6.007812 0.21875 4.59375 0.21875 C 3.957031 0.21875 3.375 0.164062 2.84375 0.0625 C 2.3125 -0.0390625 1.800781 -0.203125 1.3125 -0.421875 L 1.640625 -1.921875 C 2.109375 -1.703125 2.597656 -1.523438 3.109375 -1.390625 C 3.617188 -1.253906 4.171875 -1.1875 4.765625 -1.1875 C 6.265625 -1.1875 7.015625 -1.5625 7.015625 -2.3125 Z M 7.015625 -2.3125 "/>
+</symbol>
+<symbol overflow="visible" id="glyph0-5">
+<path style="stroke:none;" d="M 9.203125 -4.640625 C 9.203125 -3.910156 9.097656 -3.25 8.890625 -2.65625 C 8.679688 -2.0625 8.390625 -1.550781 8.015625 -1.125 C 7.640625 -0.695312 7.191406 -0.363281 6.671875 -0.125 C 6.160156 0.101562 5.597656 0.21875 4.984375 0.21875 C 4.378906 0.21875 3.820312 0.101562 3.3125 -0.125 C 2.800781 -0.363281 2.359375 -0.695312 1.984375 -1.125 C 1.609375 -1.550781 1.316406 -2.0625 1.109375 -2.65625 C 0.898438 -3.25 0.796875 -3.910156 0.796875 -4.640625 C 0.796875 -5.367188 0.898438 -6.035156 1.109375 -6.640625 C 1.316406 -7.242188 1.609375 -7.753906 1.984375 -8.171875 C 2.359375 -8.585938 2.800781 -8.910156 3.3125 -9.140625 C 3.820312 -9.378906 4.378906 -9.5 4.984375 -9.5 C 5.597656 -9.5 6.160156 -9.378906 6.671875 -9.140625 C 7.191406 -8.910156 7.640625 -8.585938 8.015625 -8.171875 C 8.390625 -7.753906 8.679688 -7.242188 8.890625 -6.640625 C 9.097656 -6.035156 9.203125 -5.367188 9.203125 -4.640625 Z M 7.5 -4.640625 C 7.5 -5.691406 7.269531 -6.519531 6.8125 -7.125 C 6.363281 -7.738281 5.753906 -8.046875 4.984375 -8.046875 C 4.222656 -8.046875 3.617188 -7.738281 3.171875 -7.125 C 2.722656 -6.519531 2.5 -5.691406 2.5 -4.640625 C 2.5 -3.597656 2.722656 -2.773438 3.171875 -2.171875 C 3.617188 -1.566406 4.222656 -1.265625 4.984375 -1.265625 C 5.753906 -1.265625 6.363281 -1.566406 6.8125 -2.171875 C 7.269531 -2.773438 7.5 -3.597656 7.5 -4.640625 Z M 7.5 -4.640625 "/>
+</symbol>
+<symbol overflow="visible" id="glyph0-6">
+<path style="stroke:none;" d="M 2.140625 0 L 2.140625 -8.78125 C 3.503906 -9.25 4.878906 -9.484375 6.265625 -9.484375 C 6.691406 -9.484375 7.097656 -9.460938 7.484375 -9.421875 C 7.867188 -9.390625 8.296875 -9.320312 8.765625 -9.21875 L 8.453125 -7.765625 C 8.023438 -7.878906 7.648438 -7.953125 7.328125 -7.984375 C 7.003906 -8.023438 6.648438 -8.046875 6.265625 -8.046875 C 5.453125 -8.046875 4.625 -7.929688 3.78125 -7.703125 L 3.78125 0 Z M 2.140625 0 "/>
+</symbol>
+<symbol overflow="visible" id="glyph0-7">
+<path style="stroke:none;" d="M 5.8125 -10.984375 L 5.8125 -1.40625 L 8.21875 -1.40625 L 8.21875 0 L 1.78125 0 L 1.78125 -1.40625 L 4.1875 -1.40625 L 4.1875 -10.984375 L 1.78125 -10.984375 L 1.78125 -12.375 L 8.21875 -12.375 L 8.21875 -10.984375 Z M 5.8125 -10.984375 "/>
+</symbol>
+<symbol overflow="visible" id="glyph0-8">
+<path style="stroke:none;" d="M 1.8125 0 L 1.8125 -12.375 L 8.84375 -12.375 L 8.84375 -10.984375 L 3.453125 -10.984375 L 3.453125 -7.125 L 8.203125 -7.125 L 8.203125 -5.734375 L 3.453125 -5.734375 L 3.453125 0 Z M 1.8125 0 "/>
+</symbol>
+<symbol overflow="visible" id="glyph0-9">
+<path style="stroke:none;" d="M 4.078125 0.09375 C 3.878906 0.09375 3.644531 0.0859375 3.375 0.078125 C 3.113281 0.0664062 2.847656 0.0507812 2.578125 0.03125 C 2.316406 0.0078125 2.050781 -0.0195312 1.78125 -0.0625 C 1.507812 -0.101562 1.273438 -0.148438 1.078125 -0.203125 L 1.078125 -12.203125 C 1.273438 -12.253906 1.503906 -12.300781 1.765625 -12.34375 C 2.023438 -12.382812 2.289062 -12.410156 2.5625 -12.421875 C 2.84375 -12.441406 3.113281 -12.457031 3.375 -12.46875 C 3.632812 -12.488281 3.867188 -12.5 4.078125 -12.5 C 4.691406 -12.5 5.265625 -12.445312 5.796875 -12.34375 C 6.328125 -12.238281 6.789062 -12.054688 7.1875 -11.796875 C 7.582031 -11.546875 7.890625 -11.210938 8.109375 -10.796875 C 8.328125 -10.390625 8.4375 -9.878906 8.4375 -9.265625 C 8.4375 -8.960938 8.390625 -8.675781 8.296875 -8.40625 C 8.203125 -8.132812 8.070312 -7.878906 7.90625 -7.640625 C 7.738281 -7.398438 7.546875 -7.1875 7.328125 -7 C 7.109375 -6.820312 6.875 -6.6875 6.625 -6.59375 C 7.300781 -6.40625 7.867188 -6.0625 8.328125 -5.5625 C 8.785156 -5.0625 9.015625 -4.414062 9.015625 -3.625 C 9.015625 -2.394531 8.617188 -1.46875 7.828125 -0.84375 C 7.046875 -0.21875 5.796875 0.09375 4.078125 0.09375 Z M 2.71875 -5.78125 L 2.71875 -1.359375 C 2.75 -1.347656 2.898438 -1.332031 3.171875 -1.3125 C 3.441406 -1.289062 3.785156 -1.28125 4.203125 -1.28125 C 4.609375 -1.28125 5 -1.3125 5.375 -1.375 C 5.757812 -1.445312 6.097656 -1.570312 6.390625 -1.75 C 6.691406 -1.925781 6.929688 -2.160156 7.109375 -2.453125 C 7.285156 -2.753906 7.375 -3.132812 7.375 -3.59375 C 7.375 -4.007812 7.289062 -4.359375 7.125 -4.640625 C 6.957031 -4.921875 6.738281 -5.144531 6.46875 -5.3125 C 6.195312 -5.476562 5.878906 -5.597656 5.515625 -5.671875 C 5.160156 -5.742188 4.789062 -5.78125 4.40625 -5.78125 Z M 2.71875 -7.140625 L 4.015625 -7.140625 C 4.347656 -7.140625 4.679688 -7.171875 5.015625 -7.234375 C 5.347656 -7.304688 5.644531 -7.414062 5.90625 -7.5625 C 6.175781 -7.707031 6.390625 -7.90625 6.546875 -8.15625 C 6.710938 -8.414062 6.796875 -8.738281 6.796875 -9.125 C 6.796875 -9.476562 6.722656 -9.78125 6.578125 -10.03125 C 6.429688 -10.289062 6.238281 -10.5 6 -10.65625 C 5.757812 -10.820312 5.484375 -10.9375 5.171875 -11 C 4.859375 -11.0625 4.53125 -11.09375 4.1875 -11.09375 C 3.832031 -11.09375 3.523438 -11.085938 3.265625 -11.078125 C 3.003906 -11.078125 2.820312 -11.066406 2.71875 -11.046875 Z M 2.71875 -7.140625 "/>
+</symbol>
+<symbol overflow="visible" id="glyph0-10">
+<path style="stroke:none;" d="M 9.203125 -6.203125 C 9.203125 -5.054688 9.054688 -4.082031 8.765625 -3.28125 C 8.484375 -2.476562 8.09375 -1.828125 7.59375 -1.328125 C 7.09375 -0.828125 6.5 -0.460938 5.8125 -0.234375 C 5.125 -0.015625 4.378906 0.09375 3.578125 0.09375 C 2.753906 0.09375 1.921875 -0.00390625 1.078125 -0.203125 L 1.078125 -12.203125 C 1.921875 -12.398438 2.753906 -12.5 3.578125 -12.5 C 4.378906 -12.5 5.125 -12.382812 5.8125 -12.15625 C 6.5 -11.925781 7.09375 -11.554688 7.59375 -11.046875 C 8.09375 -10.546875 8.484375 -9.894531 8.765625 -9.09375 C 9.054688 -8.300781 9.203125 -7.335938 9.203125 -6.203125 Z M 2.71875 -1.375 C 3.050781 -1.332031 3.390625 -1.3125 3.734375 -1.3125 C 4.335938 -1.3125 4.875 -1.398438 5.34375 -1.578125 C 5.8125 -1.765625 6.203125 -2.054688 6.515625 -2.453125 C 6.835938 -2.847656 7.082031 -3.351562 7.25 -3.96875 C 7.425781 -4.59375 7.515625 -5.335938 7.515625 -6.203125 C 7.515625 -7.878906 7.191406 -9.109375 6.546875 -9.890625 C 5.898438 -10.679688 4.945312 -11.078125 3.6875 -11.078125 C 3.507812 -11.078125 3.335938 -11.070312 3.171875 -11.0625 C 3.003906 -11.0625 2.851562 -11.046875 2.71875 -11.015625 Z M 2.71875 -1.375 "/>
+</symbol>
+<symbol overflow="visible" id="glyph0-11">
+<path style="stroke:none;" d="M 7.453125 -6.09375 L 9.09375 -6.09375 L 9.09375 -0.296875 C 8.84375 -0.203125 8.4375 -0.0859375 7.875 0.046875 C 7.320312 0.191406 6.664062 0.265625 5.90625 0.265625 C 5.15625 0.265625 4.472656 0.125 3.859375 -0.15625 C 3.242188 -0.445312 2.71875 -0.863281 2.28125 -1.40625 C 1.851562 -1.957031 1.519531 -2.632812 1.28125 -3.4375 C 1.039062 -4.25 0.921875 -5.171875 0.921875 -6.203125 C 0.921875 -7.242188 1.050781 -8.160156 1.3125 -8.953125 C 1.582031 -9.753906 1.945312 -10.425781 2.40625 -10.96875 C 2.863281 -11.519531 3.398438 -11.9375 4.015625 -12.21875 C 4.628906 -12.507812 5.289062 -12.65625 6 -12.65625 C 6.457031 -12.65625 6.859375 -12.617188 7.203125 -12.546875 C 7.546875 -12.484375 7.835938 -12.40625 8.078125 -12.3125 C 8.328125 -12.226562 8.53125 -12.132812 8.6875 -12.03125 C 8.851562 -11.925781 8.976562 -11.847656 9.0625 -11.796875 L 8.515625 -10.421875 C 8.210938 -10.660156 7.847656 -10.851562 7.421875 -11 C 7.003906 -11.15625 6.5625 -11.234375 6.09375 -11.234375 C 5.59375 -11.234375 5.125 -11.113281 4.6875 -10.875 C 4.257812 -10.632812 3.890625 -10.296875 3.578125 -9.859375 C 3.273438 -9.421875 3.035156 -8.890625 2.859375 -8.265625 C 2.679688 -7.648438 2.59375 -6.960938 2.59375 -6.203125 C 2.59375 -5.453125 2.671875 -4.769531 2.828125 -4.15625 C 2.984375 -3.539062 3.207031 -3.015625 3.5 -2.578125 C 3.789062 -2.140625 4.148438 -1.796875 4.578125 -1.546875 C 5.015625 -1.304688 5.515625 -1.1875 6.078125 -1.1875 C 6.460938 -1.1875 6.757812 -1.210938 6.96875 -1.265625 C 7.1875 -1.316406 7.347656 -1.367188 7.453125 -1.421875 Z M 7.453125 -6.09375 "/>
+</symbol>
+<symbol overflow="visible" id="glyph0-12">
+<path style="stroke:none;" d="M 9.203125 -0.515625 C 8.734375 -0.253906 8.234375 -0.0625 7.703125 0.0625 C 7.179688 0.195312 6.617188 0.265625 6.015625 0.265625 C 5.285156 0.265625 4.609375 0.132812 3.984375 -0.125 C 3.367188 -0.382812 2.832031 -0.773438 2.375 -1.296875 C 1.925781 -1.828125 1.570312 -2.5 1.3125 -3.3125 C 1.050781 -4.132812 0.921875 -5.097656 0.921875 -6.203125 C 0.921875 -7.253906 1.054688 -8.179688 1.328125 -8.984375 C 1.597656 -9.785156 1.96875 -10.457031 2.4375 -11 C 2.90625 -11.539062 3.453125 -11.953125 4.078125 -12.234375 C 4.703125 -12.515625 5.367188 -12.65625 6.078125 -12.65625 C 6.566406 -12.65625 7.066406 -12.585938 7.578125 -12.453125 C 8.097656 -12.328125 8.601562 -12.109375 9.09375 -11.796875 L 8.625 -10.4375 C 7.738281 -10.945312 6.910156 -11.203125 6.140625 -11.203125 C 5.585938 -11.203125 5.09375 -11.082031 4.65625 -10.84375 C 4.226562 -10.613281 3.859375 -10.28125 3.546875 -9.84375 C 3.242188 -9.40625 3.007812 -8.878906 2.84375 -8.265625 C 2.675781 -7.648438 2.59375 -6.960938 2.59375 -6.203125 C 2.59375 -5.347656 2.679688 -4.609375 2.859375 -3.984375 C 3.046875 -3.359375 3.296875 -2.835938 3.609375 -2.421875 C 3.929688 -2.003906 4.316406 -1.695312 4.765625 -1.5 C 5.210938 -1.300781 5.695312 -1.203125 6.21875 -1.203125 C 6.601562 -1.203125 7.007812 -1.25 7.4375 -1.34375 C 7.863281 -1.445312 8.304688 -1.625 8.765625 -1.875 Z M 9.203125 -0.515625 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-0">
+<path style="stroke:none;" d="M 0.59375 0 L 0.59375 -9 L 5.40625 -9 L 5.40625 0 Z M 4.796875 -0.59375 L 4.796875 -8.40625 L 1.203125 -8.40625 L 1.203125 -0.59375 Z M 4.796875 -0.59375 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-1">
+<path style="stroke:none;" d="M 2.515625 0 L 2.515625 -2.765625 C 2.023438 -3.554688 1.582031 -4.332031 1.1875 -5.09375 C 0.789062 -5.851562 0.445312 -6.628906 0.15625 -7.421875 L 1.265625 -7.421875 C 1.492188 -6.753906 1.757812 -6.113281 2.0625 -5.5 C 2.363281 -4.882812 2.6875 -4.253906 3.03125 -3.609375 C 3.394531 -4.285156 3.71875 -4.929688 4 -5.546875 C 4.28125 -6.160156 4.539062 -6.785156 4.78125 -7.421875 L 5.859375 -7.421875 C 5.554688 -6.640625 5.207031 -5.875 4.8125 -5.125 C 4.414062 -4.382812 3.976562 -3.601562 3.5 -2.78125 L 3.5 0 Z M 2.515625 0 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-2">
+<path style="stroke:none;" d="M 3 0.15625 C 2.5625 0.15625 2.1875 0.09375 1.875 -0.03125 C 1.570312 -0.164062 1.320312 -0.347656 1.125 -0.578125 C 0.9375 -0.804688 0.796875 -1.085938 0.703125 -1.421875 C 0.617188 -1.765625 0.578125 -2.144531 0.578125 -2.5625 L 0.578125 -7.421875 L 1.5625 -7.421875 L 1.5625 -2.65625 C 1.5625 -2.28125 1.59375 -1.96875 1.65625 -1.71875 C 1.726562 -1.46875 1.828125 -1.265625 1.953125 -1.109375 C 2.078125 -0.960938 2.222656 -0.859375 2.390625 -0.796875 C 2.566406 -0.734375 2.769531 -0.703125 3 -0.703125 C 3.226562 -0.703125 3.425781 -0.734375 3.59375 -0.796875 C 3.769531 -0.859375 3.921875 -0.960938 4.046875 -1.109375 C 4.171875 -1.265625 4.265625 -1.46875 4.328125 -1.71875 C 4.398438 -1.96875 4.4375 -2.28125 4.4375 -2.65625 L 4.4375 -7.421875 L 5.421875 -7.421875 L 5.421875 -2.5625 C 5.421875 -2.144531 5.375 -1.765625 5.28125 -1.421875 C 5.195312 -1.085938 5.054688 -0.804688 4.859375 -0.578125 C 4.671875 -0.347656 4.421875 -0.164062 4.109375 -0.03125 C 3.804688 0.09375 3.4375 0.15625 3 0.15625 Z M 3 0.15625 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-3">
+<path style="stroke:none;" d="M 1.21875 -7.421875 C 1.320312 -6.921875 1.445312 -6.375 1.59375 -5.78125 C 1.738281 -5.1875 1.890625 -4.585938 2.046875 -3.984375 C 2.210938 -3.390625 2.378906 -2.820312 2.546875 -2.28125 C 2.722656 -1.738281 2.882812 -1.265625 3.03125 -0.859375 C 3.15625 -1.265625 3.300781 -1.742188 3.46875 -2.296875 C 3.644531 -2.847656 3.816406 -3.421875 3.984375 -4.015625 C 4.148438 -4.609375 4.304688 -5.203125 4.453125 -5.796875 C 4.609375 -6.390625 4.734375 -6.929688 4.828125 -7.421875 L 5.859375 -7.421875 C 5.796875 -7.109375 5.691406 -6.679688 5.546875 -6.140625 C 5.398438 -5.597656 5.226562 -4.992188 5.03125 -4.328125 C 4.832031 -3.660156 4.609375 -2.953125 4.359375 -2.203125 C 4.117188 -1.453125 3.863281 -0.71875 3.59375 0 L 2.375 0 C 2.125 -0.71875 1.878906 -1.445312 1.640625 -2.1875 C 1.410156 -2.9375 1.195312 -3.644531 1 -4.3125 C 0.800781 -4.976562 0.628906 -5.582031 0.484375 -6.125 C 0.335938 -6.675781 0.226562 -7.109375 0.15625 -7.421875 Z M 1.21875 -7.421875 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-4">
+<path style="stroke:none;" d=""/>
+</symbol>
+<symbol overflow="visible" id="glyph1-5">
+<path style="stroke:none;" d="M 5.515625 -3.71875 C 5.515625 -3.03125 5.425781 -2.445312 5.25 -1.96875 C 5.082031 -1.488281 4.847656 -1.097656 4.546875 -0.796875 C 4.253906 -0.492188 3.898438 -0.273438 3.484375 -0.140625 C 3.078125 -0.00390625 2.628906 0.0625 2.140625 0.0625 C 1.648438 0.0625 1.148438 0 0.640625 -0.125 L 0.640625 -7.3125 C 1.148438 -7.4375 1.648438 -7.5 2.140625 -7.5 C 2.628906 -7.5 3.078125 -7.429688 3.484375 -7.296875 C 3.898438 -7.160156 4.253906 -6.941406 4.546875 -6.640625 C 4.847656 -6.335938 5.082031 -5.941406 5.25 -5.453125 C 5.425781 -4.972656 5.515625 -4.394531 5.515625 -3.71875 Z M 1.625 -0.828125 C 1.832031 -0.804688 2.039062 -0.796875 2.25 -0.796875 C 2.601562 -0.796875 2.921875 -0.847656 3.203125 -0.953125 C 3.484375 -1.054688 3.71875 -1.226562 3.90625 -1.46875 C 4.101562 -1.707031 4.253906 -2.007812 4.359375 -2.375 C 4.460938 -2.75 4.515625 -3.195312 4.515625 -3.71875 C 4.515625 -4.726562 4.316406 -5.46875 3.921875 -5.9375 C 3.535156 -6.40625 2.960938 -6.640625 2.203125 -6.640625 C 2.097656 -6.640625 1.992188 -6.640625 1.890625 -6.640625 C 1.796875 -6.640625 1.707031 -6.628906 1.625 -6.609375 Z M 1.625 -0.828125 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-6">
+<path style="stroke:none;" d="M 5.515625 -2.78125 C 5.515625 -2.34375 5.453125 -1.945312 5.328125 -1.59375 C 5.203125 -1.238281 5.023438 -0.929688 4.796875 -0.671875 C 4.578125 -0.410156 4.3125 -0.210938 4 -0.078125 C 3.695312 0.0546875 3.359375 0.125 2.984375 0.125 C 2.628906 0.125 2.296875 0.0546875 1.984375 -0.078125 C 1.679688 -0.210938 1.414062 -0.410156 1.1875 -0.671875 C 0.96875 -0.929688 0.796875 -1.238281 0.671875 -1.59375 C 0.546875 -1.945312 0.484375 -2.34375 0.484375 -2.78125 C 0.484375 -3.21875 0.546875 -3.617188 0.671875 -3.984375 C 0.796875 -4.347656 0.96875 -4.65625 1.1875 -4.90625 C 1.414062 -5.15625 1.679688 -5.347656 1.984375 -5.484375 C 2.296875 -5.628906 2.628906 -5.703125 2.984375 -5.703125 C 3.359375 -5.703125 3.695312 -5.628906 4 -5.484375 C 4.3125 -5.347656 4.578125 -5.15625 4.796875 -4.90625 C 5.023438 -4.65625 5.203125 -4.347656 5.328125 -3.984375 C 5.453125 -3.617188 5.515625 -3.21875 5.515625 -2.78125 Z M 4.5 -2.78125 C 4.5 -3.414062 4.363281 -3.914062 4.09375 -4.28125 C 3.820312 -4.644531 3.453125 -4.828125 2.984375 -4.828125 C 2.523438 -4.828125 2.160156 -4.644531 1.890625 -4.28125 C 1.628906 -3.914062 1.5 -3.414062 1.5 -2.78125 C 1.5 -2.15625 1.628906 -1.660156 1.890625 -1.296875 C 2.160156 -0.929688 2.523438 -0.75 2.984375 -0.75 C 3.453125 -0.75 3.820312 -0.929688 4.09375 -1.296875 C 4.363281 -1.660156 4.5 -2.15625 4.5 -2.78125 Z M 4.5 -2.78125 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-7">
+<path style="stroke:none;" d="M 4.109375 0 C 3.992188 -0.269531 3.890625 -0.515625 3.796875 -0.734375 C 3.710938 -0.960938 3.628906 -1.1875 3.546875 -1.40625 C 3.460938 -1.632812 3.378906 -1.867188 3.296875 -2.109375 C 3.210938 -2.359375 3.113281 -2.640625 3 -2.953125 C 2.882812 -2.640625 2.78125 -2.359375 2.6875 -2.109375 C 2.601562 -1.867188 2.519531 -1.632812 2.4375 -1.40625 C 2.351562 -1.1875 2.265625 -0.960938 2.171875 -0.734375 C 2.085938 -0.515625 1.984375 -0.269531 1.859375 0 L 1.109375 0 C 0.890625 -0.976562 0.707031 -1.953125 0.5625 -2.921875 C 0.414062 -3.890625 0.304688 -4.769531 0.234375 -5.5625 L 1.15625 -5.5625 C 1.1875 -5.25 1.210938 -4.941406 1.234375 -4.640625 C 1.265625 -4.347656 1.300781 -4.035156 1.34375 -3.703125 C 1.382812 -3.378906 1.429688 -3.023438 1.484375 -2.640625 C 1.535156 -2.253906 1.59375 -1.820312 1.65625 -1.34375 C 1.78125 -1.664062 1.882812 -1.945312 1.96875 -2.1875 C 2.0625 -2.425781 2.144531 -2.648438 2.21875 -2.859375 C 2.289062 -3.078125 2.359375 -3.296875 2.421875 -3.515625 C 2.492188 -3.742188 2.570312 -4 2.65625 -4.28125 L 3.390625 -4.28125 C 3.472656 -4 3.546875 -3.742188 3.609375 -3.515625 C 3.671875 -3.296875 3.738281 -3.078125 3.8125 -2.859375 C 3.882812 -2.648438 3.957031 -2.425781 4.03125 -2.1875 C 4.113281 -1.945312 4.21875 -1.671875 4.34375 -1.359375 C 4.414062 -1.796875 4.476562 -2.203125 4.53125 -2.578125 C 4.59375 -2.953125 4.640625 -3.304688 4.671875 -3.640625 C 4.710938 -3.972656 4.75 -4.296875 4.78125 -4.609375 C 4.820312 -4.921875 4.851562 -5.238281 4.875 -5.5625 L 5.765625 -5.5625 C 5.734375 -5.164062 5.6875 -4.738281 5.625 -4.28125 C 5.570312 -3.820312 5.503906 -3.351562 5.421875 -2.875 C 5.335938 -2.394531 5.25 -1.910156 5.15625 -1.421875 C 5.0625 -0.929688 4.960938 -0.457031 4.859375 0 Z M 4.109375 0 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-8">
+<path style="stroke:none;" d="M 0.859375 -5.40625 C 1.210938 -5.5 1.566406 -5.566406 1.921875 -5.609375 C 2.273438 -5.660156 2.609375 -5.6875 2.921875 -5.6875 C 3.671875 -5.6875 4.234375 -5.492188 4.609375 -5.109375 C 4.992188 -4.722656 5.1875 -4.109375 5.1875 -3.265625 L 5.1875 0 L 4.203125 0 L 4.203125 -3.078125 C 4.203125 -3.441406 4.171875 -3.734375 4.109375 -3.953125 C 4.046875 -4.179688 3.953125 -4.359375 3.828125 -4.484375 C 3.710938 -4.609375 3.570312 -4.691406 3.40625 -4.734375 C 3.25 -4.785156 3.070312 -4.8125 2.875 -4.8125 C 2.71875 -4.8125 2.546875 -4.800781 2.359375 -4.78125 C 2.179688 -4.757812 2.007812 -4.734375 1.84375 -4.703125 L 1.84375 0 L 0.859375 0 Z M 0.859375 -5.40625 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-9">
+<path style="stroke:none;" d="M 4.21875 -1.390625 C 4.21875 -1.585938 4.132812 -1.75 3.96875 -1.875 C 3.800781 -2.007812 3.59375 -2.125 3.34375 -2.21875 C 3.101562 -2.3125 2.835938 -2.40625 2.546875 -2.5 C 2.265625 -2.59375 2 -2.707031 1.75 -2.84375 C 1.507812 -2.976562 1.304688 -3.144531 1.140625 -3.34375 C 0.984375 -3.539062 0.90625 -3.800781 0.90625 -4.125 C 0.90625 -4.570312 1.082031 -4.945312 1.4375 -5.25 C 1.800781 -5.550781 2.375 -5.703125 3.15625 -5.703125 C 3.457031 -5.703125 3.769531 -5.675781 4.09375 -5.625 C 4.414062 -5.582031 4.695312 -5.523438 4.9375 -5.453125 L 4.75 -4.578125 C 4.6875 -4.609375 4.597656 -4.640625 4.484375 -4.671875 C 4.367188 -4.710938 4.238281 -4.742188 4.09375 -4.765625 C 3.957031 -4.796875 3.804688 -4.816406 3.640625 -4.828125 C 3.472656 -4.847656 3.316406 -4.859375 3.171875 -4.859375 C 2.304688 -4.859375 1.875 -4.625 1.875 -4.15625 C 1.875 -3.988281 1.953125 -3.84375 2.109375 -3.71875 C 2.273438 -3.601562 2.484375 -3.5 2.734375 -3.40625 C 2.984375 -3.3125 3.25 -3.210938 3.53125 -3.109375 C 3.820312 -3.015625 4.09375 -2.894531 4.34375 -2.75 C 4.59375 -2.601562 4.796875 -2.425781 4.953125 -2.21875 C 5.117188 -2.019531 5.203125 -1.765625 5.203125 -1.453125 C 5.203125 -0.953125 5.003906 -0.5625 4.609375 -0.28125 C 4.222656 -0.0078125 3.609375 0.125 2.765625 0.125 C 2.378906 0.125 2.023438 0.09375 1.703125 0.03125 C 1.378906 -0.03125 1.078125 -0.125 0.796875 -0.25 L 0.984375 -1.15625 C 1.265625 -1.019531 1.554688 -0.910156 1.859375 -0.828125 C 2.171875 -0.742188 2.503906 -0.703125 2.859375 -0.703125 C 3.765625 -0.703125 4.21875 -0.929688 4.21875 -1.390625 Z M 4.21875 -1.390625 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-10">
+<path style="stroke:none;" d="M 0.59375 -2.765625 C 0.59375 -3.273438 0.671875 -3.710938 0.828125 -4.078125 C 0.984375 -4.441406 1.203125 -4.742188 1.484375 -4.984375 C 1.765625 -5.234375 2.09375 -5.414062 2.46875 -5.53125 C 2.84375 -5.644531 3.238281 -5.703125 3.65625 -5.703125 C 3.925781 -5.703125 4.195312 -5.679688 4.46875 -5.640625 C 4.738281 -5.609375 5.023438 -5.546875 5.328125 -5.453125 L 5.09375 -4.59375 C 4.832031 -4.6875 4.59375 -4.75 4.375 -4.78125 C 4.15625 -4.8125 3.929688 -4.828125 3.703125 -4.828125 C 3.421875 -4.828125 3.148438 -4.785156 2.890625 -4.703125 C 2.640625 -4.628906 2.414062 -4.507812 2.21875 -4.34375 C 2.03125 -4.1875 1.878906 -3.976562 1.765625 -3.71875 C 1.660156 -3.457031 1.609375 -3.140625 1.609375 -2.765625 C 1.609375 -2.421875 1.660156 -2.117188 1.765625 -1.859375 C 1.867188 -1.609375 2.015625 -1.398438 2.203125 -1.234375 C 2.390625 -1.078125 2.613281 -0.957031 2.875 -0.875 C 3.144531 -0.789062 3.4375 -0.75 3.75 -0.75 C 4.007812 -0.75 4.253906 -0.765625 4.484375 -0.796875 C 4.722656 -0.828125 4.984375 -0.890625 5.265625 -0.984375 L 5.40625 -0.15625 C 5.125 -0.0507812 4.835938 0.0195312 4.546875 0.0625 C 4.265625 0.101562 3.957031 0.125 3.625 0.125 C 3.175781 0.125 2.765625 0.0664062 2.390625 -0.046875 C 2.023438 -0.171875 1.707031 -0.351562 1.4375 -0.59375 C 1.164062 -0.832031 0.957031 -1.132812 0.8125 -1.5 C 0.664062 -1.863281 0.59375 -2.285156 0.59375 -2.765625 Z M 0.59375 -2.765625 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-11">
+<path style="stroke:none;" d="M 3.0625 -0.703125 C 3.3125 -0.703125 3.53125 -0.707031 3.71875 -0.71875 C 3.914062 -0.738281 4.082031 -0.765625 4.21875 -0.796875 L 4.21875 -2.453125 C 4.082031 -2.492188 3.925781 -2.523438 3.75 -2.546875 C 3.570312 -2.566406 3.382812 -2.578125 3.1875 -2.578125 C 3 -2.578125 2.816406 -2.5625 2.640625 -2.53125 C 2.460938 -2.507812 2.304688 -2.460938 2.171875 -2.390625 C 2.035156 -2.316406 1.921875 -2.222656 1.828125 -2.109375 C 1.742188 -1.992188 1.703125 -1.847656 1.703125 -1.671875 C 1.703125 -1.304688 1.820312 -1.050781 2.0625 -0.90625 C 2.3125 -0.769531 2.644531 -0.703125 3.0625 -0.703125 Z M 2.96875 -5.703125 C 3.382812 -5.703125 3.734375 -5.648438 4.015625 -5.546875 C 4.296875 -5.441406 4.523438 -5.296875 4.703125 -5.109375 C 4.878906 -4.929688 5.003906 -4.707031 5.078125 -4.4375 C 5.148438 -4.175781 5.1875 -3.890625 5.1875 -3.578125 L 5.1875 -0.09375 C 4.957031 -0.0507812 4.648438 -0.00390625 4.265625 0.046875 C 3.890625 0.0976562 3.5 0.125 3.09375 0.125 C 2.789062 0.125 2.492188 0.0976562 2.203125 0.046875 C 1.921875 -0.00390625 1.664062 -0.09375 1.4375 -0.21875 C 1.21875 -0.351562 1.039062 -0.535156 0.90625 -0.765625 C 0.769531 -0.992188 0.703125 -1.289062 0.703125 -1.65625 C 0.703125 -1.976562 0.769531 -2.25 0.90625 -2.46875 C 1.039062 -2.6875 1.21875 -2.863281 1.4375 -3 C 1.664062 -3.132812 1.921875 -3.234375 2.203125 -3.296875 C 2.484375 -3.359375 2.769531 -3.390625 3.0625 -3.390625 C 3.445312 -3.390625 3.832031 -3.34375 4.21875 -3.25 L 4.21875 -3.53125 C 4.21875 -3.695312 4.195312 -3.859375 4.15625 -4.015625 C 4.125 -4.171875 4.054688 -4.3125 3.953125 -4.4375 C 3.847656 -4.5625 3.707031 -4.660156 3.53125 -4.734375 C 3.363281 -4.816406 3.144531 -4.859375 2.875 -4.859375 C 2.53125 -4.859375 2.226562 -4.832031 1.96875 -4.78125 C 1.71875 -4.738281 1.523438 -4.691406 1.390625 -4.640625 L 1.265625 -5.453125 C 1.398438 -5.523438 1.625 -5.582031 1.9375 -5.625 C 2.257812 -5.675781 2.601562 -5.703125 2.96875 -5.703125 Z M 2.96875 -5.703125 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-12">
+<path style="stroke:none;" d="M 4.0625 0.125 C 3.707031 0.125 3.410156 0.078125 3.171875 -0.015625 C 2.941406 -0.109375 2.757812 -0.25 2.625 -0.4375 C 2.488281 -0.632812 2.390625 -0.875 2.328125 -1.15625 C 2.273438 -1.4375 2.25 -1.765625 2.25 -2.140625 L 2.25 -7.421875 L 0.640625 -7.421875 L 0.640625 -8.25 L 3.234375 -8.25 L 3.234375 -2.140625 C 3.234375 -1.867188 3.25 -1.644531 3.28125 -1.46875 C 3.320312 -1.289062 3.378906 -1.144531 3.453125 -1.03125 C 3.535156 -0.925781 3.628906 -0.851562 3.734375 -0.8125 C 3.847656 -0.769531 3.984375 -0.75 4.140625 -0.75 C 4.367188 -0.75 4.582031 -0.773438 4.78125 -0.828125 C 4.988281 -0.890625 5.144531 -0.953125 5.25 -1.015625 L 5.40625 -0.1875 C 5.351562 -0.15625 5.28125 -0.117188 5.1875 -0.078125 C 5.101562 -0.046875 5 -0.015625 4.875 0.015625 C 4.757812 0.046875 4.628906 0.0703125 4.484375 0.09375 C 4.347656 0.113281 4.207031 0.125 4.0625 0.125 Z M 4.0625 0.125 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-13">
+<path style="stroke:none;" d="M 2.515625 -6.4375 C 2.304688 -6.4375 2.125 -6.503906 1.96875 -6.640625 C 1.8125 -6.785156 1.734375 -6.984375 1.734375 -7.234375 C 1.734375 -7.484375 1.8125 -7.679688 1.96875 -7.828125 C 2.125 -7.972656 2.304688 -8.046875 2.515625 -8.046875 C 2.722656 -8.046875 2.898438 -7.972656 3.046875 -7.828125 C 3.203125 -7.679688 3.28125 -7.484375 3.28125 -7.234375 C 3.28125 -6.984375 3.203125 -6.785156 3.046875 -6.640625 C 2.898438 -6.503906 2.722656 -6.4375 2.515625 -6.4375 Z M 2.25 -4.734375 L 0.640625 -4.734375 L 0.640625 -5.5625 L 3.234375 -5.5625 L 3.234375 -2.140625 C 3.234375 -1.585938 3.3125 -1.21875 3.46875 -1.03125 C 3.625 -0.84375 3.851562 -0.75 4.15625 -0.75 C 4.382812 -0.75 4.597656 -0.773438 4.796875 -0.828125 C 4.992188 -0.890625 5.144531 -0.953125 5.25 -1.015625 L 5.40625 -0.1875 C 5.351562 -0.15625 5.28125 -0.117188 5.1875 -0.078125 C 5.101562 -0.046875 5.003906 -0.015625 4.890625 0.015625 C 4.773438 0.046875 4.644531 0.0703125 4.5 0.09375 C 4.363281 0.113281 4.21875 0.125 4.0625 0.125 C 3.71875 0.125 3.425781 0.078125 3.1875 -0.015625 C 2.957031 -0.109375 2.769531 -0.25 2.625 -0.4375 C 2.488281 -0.632812 2.390625 -0.875 2.328125 -1.15625 C 2.273438 -1.4375 2.25 -1.765625 2.25 -2.140625 Z M 2.25 -4.734375 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-14">
+<path style="stroke:none;" d="M 4.15625 -0.515625 C 4.039062 -0.453125 3.863281 -0.382812 3.625 -0.3125 C 3.394531 -0.238281 3.128906 -0.203125 2.828125 -0.203125 C 2.503906 -0.203125 2.195312 -0.253906 1.90625 -0.359375 C 1.625 -0.472656 1.378906 -0.640625 1.171875 -0.859375 C 0.960938 -1.078125 0.796875 -1.351562 0.671875 -1.6875 C 0.546875 -2.03125 0.484375 -2.4375 0.484375 -2.90625 C 0.484375 -3.3125 0.539062 -3.679688 0.65625 -4.015625 C 0.769531 -4.359375 0.9375 -4.65625 1.15625 -4.90625 C 1.375 -5.15625 1.644531 -5.347656 1.96875 -5.484375 C 2.289062 -5.628906 2.65625 -5.703125 3.0625 -5.703125 C 3.539062 -5.703125 3.945312 -5.664062 4.28125 -5.59375 C 4.625 -5.53125 4.910156 -5.46875 5.140625 -5.40625 L 5.140625 -0.4375 C 5.140625 0.425781 4.921875 1.050781 4.484375 1.4375 C 4.054688 1.820312 3.398438 2.015625 2.515625 2.015625 C 2.160156 2.015625 1.835938 1.984375 1.546875 1.921875 C 1.253906 1.867188 0.992188 1.804688 0.765625 1.734375 L 0.953125 0.859375 C 1.160156 0.941406 1.394531 1.007812 1.65625 1.0625 C 1.925781 1.125 2.222656 1.15625 2.546875 1.15625 C 3.117188 1.15625 3.53125 1.035156 3.78125 0.796875 C 4.03125 0.566406 4.15625 0.191406 4.15625 -0.328125 Z M 4.15625 -4.6875 C 4.0625 -4.71875 3.925781 -4.75 3.75 -4.78125 C 3.582031 -4.8125 3.359375 -4.828125 3.078125 -4.828125 C 2.554688 -4.828125 2.160156 -4.648438 1.890625 -4.296875 C 1.628906 -3.941406 1.5 -3.472656 1.5 -2.890625 C 1.5 -2.566406 1.535156 -2.289062 1.609375 -2.0625 C 1.691406 -1.84375 1.796875 -1.65625 1.921875 -1.5 C 2.054688 -1.351562 2.207031 -1.242188 2.375 -1.171875 C 2.539062 -1.109375 2.722656 -1.078125 2.921875 -1.078125 C 3.160156 -1.078125 3.390625 -1.113281 3.609375 -1.1875 C 3.835938 -1.257812 4.019531 -1.34375 4.15625 -1.4375 Z M 4.15625 -4.6875 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-15">
+<path style="stroke:none;" d="M 2.8125 -0.703125 C 3.3125 -0.703125 3.691406 -0.796875 3.953125 -0.984375 C 4.222656 -1.171875 4.359375 -1.457031 4.359375 -1.84375 C 4.359375 -2.082031 4.304688 -2.28125 4.203125 -2.4375 C 4.109375 -2.601562 3.984375 -2.75 3.828125 -2.875 C 3.671875 -3 3.488281 -3.109375 3.28125 -3.203125 C 3.082031 -3.296875 2.878906 -3.378906 2.671875 -3.453125 C 2.429688 -3.546875 2.203125 -3.648438 1.984375 -3.765625 C 1.765625 -3.890625 1.566406 -4.03125 1.390625 -4.1875 C 1.222656 -4.351562 1.085938 -4.546875 0.984375 -4.765625 C 0.890625 -4.984375 0.84375 -5.238281 0.84375 -5.53125 C 0.84375 -6.175781 1.046875 -6.679688 1.453125 -7.046875 C 1.859375 -7.410156 2.425781 -7.59375 3.15625 -7.59375 C 3.351562 -7.59375 3.550781 -7.578125 3.75 -7.546875 C 3.945312 -7.523438 4.128906 -7.492188 4.296875 -7.453125 C 4.460938 -7.410156 4.609375 -7.359375 4.734375 -7.296875 C 4.867188 -7.242188 4.976562 -7.191406 5.0625 -7.140625 L 4.75 -6.3125 C 4.59375 -6.40625 4.375 -6.5 4.09375 -6.59375 C 3.8125 -6.695312 3.5 -6.75 3.15625 -6.75 C 2.789062 -6.75 2.476562 -6.65625 2.21875 -6.46875 C 1.957031 -6.289062 1.828125 -6.019531 1.828125 -5.65625 C 1.828125 -5.457031 1.863281 -5.285156 1.9375 -5.140625 C 2.007812 -4.992188 2.113281 -4.863281 2.25 -4.75 C 2.382812 -4.644531 2.535156 -4.546875 2.703125 -4.453125 C 2.878906 -4.367188 3.070312 -4.285156 3.28125 -4.203125 C 3.59375 -4.078125 3.875 -3.945312 4.125 -3.8125 C 4.375 -3.6875 4.585938 -3.535156 4.765625 -3.359375 C 4.953125 -3.179688 5.09375 -2.972656 5.1875 -2.734375 C 5.289062 -2.492188 5.34375 -2.203125 5.34375 -1.859375 C 5.34375 -1.210938 5.125 -0.710938 4.6875 -0.359375 C 4.25 -0.015625 3.625 0.15625 2.8125 0.15625 C 2.539062 0.15625 2.289062 0.132812 2.0625 0.09375 C 1.832031 0.0625 1.625 0.0195312 1.4375 -0.03125 C 1.257812 -0.09375 1.101562 -0.148438 0.96875 -0.203125 C 0.832031 -0.253906 0.726562 -0.304688 0.65625 -0.359375 L 0.953125 -1.171875 C 1.117188 -1.085938 1.359375 -0.988281 1.671875 -0.875 C 1.984375 -0.757812 2.363281 -0.703125 2.8125 -0.703125 Z M 2.8125 -0.703125 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-16">
+<path style="stroke:none;" d="M 3.109375 -5.703125 C 3.859375 -5.703125 4.4375 -5.46875 4.84375 -5 C 5.25 -4.53125 5.453125 -3.820312 5.453125 -2.875 L 5.453125 -2.515625 L 1.46875 -2.515625 C 1.507812 -1.941406 1.703125 -1.503906 2.046875 -1.203125 C 2.390625 -0.898438 2.867188 -0.75 3.484375 -0.75 C 3.835938 -0.75 4.132812 -0.773438 4.375 -0.828125 C 4.625 -0.890625 4.8125 -0.953125 4.9375 -1.015625 L 5.078125 -0.1875 C 4.953125 -0.113281 4.734375 -0.046875 4.421875 0.015625 C 4.109375 0.0859375 3.757812 0.125 3.375 0.125 C 2.894531 0.125 2.472656 0.0507812 2.109375 -0.09375 C 1.742188 -0.238281 1.441406 -0.4375 1.203125 -0.6875 C 0.960938 -0.945312 0.78125 -1.253906 0.65625 -1.609375 C 0.539062 -1.960938 0.484375 -2.347656 0.484375 -2.765625 C 0.484375 -3.265625 0.554688 -3.695312 0.703125 -4.0625 C 0.859375 -4.4375 1.0625 -4.742188 1.3125 -4.984375 C 1.5625 -5.222656 1.835938 -5.398438 2.140625 -5.515625 C 2.453125 -5.640625 2.773438 -5.703125 3.109375 -5.703125 Z M 4.453125 -3.328125 C 4.453125 -3.796875 4.328125 -4.164062 4.078125 -4.4375 C 3.828125 -4.71875 3.5 -4.859375 3.09375 -4.859375 C 2.863281 -4.859375 2.65625 -4.8125 2.46875 -4.71875 C 2.28125 -4.632812 2.117188 -4.519531 1.984375 -4.375 C 1.847656 -4.226562 1.738281 -4.0625 1.65625 -3.875 C 1.570312 -3.695312 1.519531 -3.515625 1.5 -3.328125 Z M 4.453125 -3.328125 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-17">
+<path style="stroke:none;" d="M 4.15625 -4.390625 C 4.039062 -4.492188 3.875 -4.59375 3.65625 -4.6875 C 3.445312 -4.78125 3.222656 -4.828125 2.984375 -4.828125 C 2.722656 -4.828125 2.5 -4.773438 2.3125 -4.671875 C 2.125 -4.566406 1.96875 -4.421875 1.84375 -4.234375 C 1.726562 -4.054688 1.640625 -3.84375 1.578125 -3.59375 C 1.523438 -3.34375 1.5 -3.070312 1.5 -2.78125 C 1.5 -2.132812 1.648438 -1.632812 1.953125 -1.28125 C 2.253906 -0.925781 2.648438 -0.75 3.140625 -0.75 C 3.390625 -0.75 3.597656 -0.757812 3.765625 -0.78125 C 3.941406 -0.8125 4.070312 -0.835938 4.15625 -0.859375 Z M 4.15625 -8.140625 L 5.140625 -8.3125 L 5.140625 -0.15625 C 4.929688 -0.09375 4.65625 -0.03125 4.3125 0.03125 C 3.976562 0.09375 3.585938 0.125 3.140625 0.125 C 2.742188 0.125 2.378906 0.0546875 2.046875 -0.078125 C 1.722656 -0.210938 1.441406 -0.40625 1.203125 -0.65625 C 0.972656 -0.90625 0.796875 -1.207031 0.671875 -1.5625 C 0.546875 -1.925781 0.484375 -2.332031 0.484375 -2.78125 C 0.484375 -3.21875 0.535156 -3.613281 0.640625 -3.96875 C 0.742188 -4.320312 0.898438 -4.625 1.109375 -4.875 C 1.316406 -5.132812 1.566406 -5.335938 1.859375 -5.484375 C 2.148438 -5.628906 2.488281 -5.703125 2.875 -5.703125 C 3.164062 -5.703125 3.421875 -5.664062 3.640625 -5.59375 C 3.867188 -5.519531 4.039062 -5.441406 4.15625 -5.359375 Z M 4.15625 -8.140625 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-18">
+<path style="stroke:none;" d="M 1.28125 0 L 1.28125 -5.265625 C 2.101562 -5.546875 2.925781 -5.6875 3.75 -5.6875 C 4.007812 -5.6875 4.253906 -5.675781 4.484375 -5.65625 C 4.722656 -5.632812 4.976562 -5.59375 5.25 -5.53125 L 5.078125 -4.65625 C 4.816406 -4.726562 4.585938 -4.773438 4.390625 -4.796875 C 4.203125 -4.816406 3.988281 -4.828125 3.75 -4.828125 C 3.269531 -4.828125 2.773438 -4.757812 2.265625 -4.625 L 2.265625 0 Z M 1.28125 0 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-19">
+<path style="stroke:none;" d="M 0.609375 1.046875 C 0.679688 1.085938 0.78125 1.117188 0.90625 1.140625 C 1.039062 1.160156 1.164062 1.171875 1.28125 1.171875 C 1.675781 1.171875 1.984375 1.082031 2.203125 0.90625 C 2.421875 0.738281 2.625 0.460938 2.8125 0.078125 C 2.363281 -0.773438 1.941406 -1.6875 1.546875 -2.65625 C 1.148438 -3.625 0.828125 -4.59375 0.578125 -5.5625 L 1.65625 -5.5625 C 1.738281 -5.25 1.832031 -4.90625 1.9375 -4.53125 C 2.039062 -4.15625 2.160156 -3.769531 2.296875 -3.375 C 2.441406 -2.988281 2.585938 -2.597656 2.734375 -2.203125 C 2.890625 -1.804688 3.054688 -1.425781 3.234375 -1.0625 C 3.367188 -1.4375 3.488281 -1.800781 3.59375 -2.15625 C 3.707031 -2.519531 3.8125 -2.882812 3.90625 -3.25 C 4.007812 -3.613281 4.109375 -3.984375 4.203125 -4.359375 C 4.296875 -4.742188 4.394531 -5.144531 4.5 -5.5625 L 5.53125 -5.5625 C 5.269531 -4.53125 4.984375 -3.523438 4.671875 -2.546875 C 4.359375 -1.566406 4.019531 -0.660156 3.65625 0.171875 C 3.519531 0.484375 3.375 0.753906 3.21875 0.984375 C 3.0625 1.222656 2.890625 1.414062 2.703125 1.5625 C 2.523438 1.71875 2.316406 1.832031 2.078125 1.90625 C 1.847656 1.976562 1.585938 2.015625 1.296875 2.015625 C 1.140625 2.015625 0.972656 1.992188 0.796875 1.953125 C 0.617188 1.910156 0.5 1.875 0.4375 1.84375 Z M 0.609375 1.046875 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-20">
+<path style="stroke:none;" d="M 0.34375 -3.71875 C 0.34375 -4.382812 0.40625 -4.960938 0.53125 -5.453125 C 0.664062 -5.941406 0.847656 -6.34375 1.078125 -6.65625 C 1.304688 -6.96875 1.582031 -7.203125 1.90625 -7.359375 C 2.238281 -7.515625 2.601562 -7.59375 3 -7.59375 C 3.394531 -7.59375 3.753906 -7.515625 4.078125 -7.359375 C 4.410156 -7.203125 4.691406 -6.96875 4.921875 -6.65625 C 5.148438 -6.34375 5.328125 -5.941406 5.453125 -5.453125 C 5.585938 -4.960938 5.65625 -4.382812 5.65625 -3.71875 C 5.65625 -3.050781 5.585938 -2.472656 5.453125 -1.984375 C 5.328125 -1.503906 5.148438 -1.101562 4.921875 -0.78125 C 4.691406 -0.457031 4.410156 -0.21875 4.078125 -0.0625 C 3.753906 0.0820312 3.394531 0.15625 3 0.15625 C 2.601562 0.15625 2.238281 0.0820312 1.90625 -0.0625 C 1.582031 -0.21875 1.304688 -0.457031 1.078125 -0.78125 C 0.847656 -1.101562 0.664062 -1.503906 0.53125 -1.984375 C 0.40625 -2.472656 0.34375 -3.050781 0.34375 -3.71875 Z M 1.359375 -3.71875 C 1.359375 -2.738281 1.488281 -1.988281 1.75 -1.46875 C 2.007812 -0.957031 2.414062 -0.703125 2.96875 -0.703125 C 3.53125 -0.703125 3.953125 -0.957031 4.234375 -1.46875 C 4.515625 -1.988281 4.65625 -2.738281 4.65625 -3.71875 C 4.65625 -4.695312 4.515625 -5.445312 4.234375 -5.96875 C 3.953125 -6.488281 3.53125 -6.75 2.96875 -6.75 C 2.414062 -6.75 2.007812 -6.488281 1.75 -5.96875 C 1.488281 -5.445312 1.359375 -4.695312 1.359375 -3.71875 Z M 1.359375 -3.71875 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-21">
+<path style="stroke:none;" d="M 5.140625 -0.15625 C 4.929688 -0.101562 4.644531 -0.046875 4.28125 0.015625 C 3.925781 0.0859375 3.507812 0.125 3.03125 0.125 C 2.613281 0.125 2.265625 0.0625 1.984375 -0.0625 C 1.703125 -0.1875 1.472656 -0.363281 1.296875 -0.59375 C 1.117188 -0.820312 0.992188 -1.09375 0.921875 -1.40625 C 0.847656 -1.71875 0.8125 -2.0625 0.8125 -2.4375 L 0.8125 -5.5625 L 1.796875 -5.5625 L 1.796875 -2.65625 C 1.796875 -1.96875 1.894531 -1.476562 2.09375 -1.1875 C 2.300781 -0.894531 2.644531 -0.75 3.125 -0.75 C 3.226562 -0.75 3.332031 -0.753906 3.4375 -0.765625 C 3.550781 -0.773438 3.65625 -0.785156 3.75 -0.796875 C 3.851562 -0.804688 3.9375 -0.816406 4 -0.828125 C 4.070312 -0.847656 4.125 -0.859375 4.15625 -0.859375 L 4.15625 -5.5625 L 5.140625 -5.5625 Z M 5.140625 -0.15625 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-22">
+<path style="stroke:none;" d="M 2.921875 -5.5625 L 5.265625 -5.5625 L 5.265625 -4.734375 L 2.921875 -4.734375 L 2.921875 -2.140625 C 2.921875 -1.867188 2.9375 -1.644531 2.96875 -1.46875 C 3.007812 -1.289062 3.078125 -1.144531 3.171875 -1.03125 C 3.265625 -0.925781 3.382812 -0.851562 3.53125 -0.8125 C 3.675781 -0.769531 3.851562 -0.75 4.0625 -0.75 C 4.34375 -0.75 4.570312 -0.773438 4.75 -0.828125 C 4.925781 -0.878906 5.09375 -0.941406 5.25 -1.015625 L 5.40625 -0.1875 C 5.289062 -0.132812 5.109375 -0.0703125 4.859375 0 C 4.617188 0.0820312 4.316406 0.125 3.953125 0.125 C 3.546875 0.125 3.207031 0.078125 2.9375 -0.015625 C 2.675781 -0.109375 2.46875 -0.25 2.3125 -0.4375 C 2.164062 -0.632812 2.066406 -0.875 2.015625 -1.15625 C 1.960938 -1.4375 1.9375 -1.765625 1.9375 -2.140625 L 1.9375 -4.734375 L 0.75 -4.734375 L 0.75 -5.5625 L 1.9375 -5.5625 L 1.9375 -7.125 L 2.921875 -7.296875 Z M 2.921875 -5.5625 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-23">
+<path style="stroke:none;" d="M 4.5 -2.765625 C 4.5 -3.421875 4.347656 -3.925781 4.046875 -4.28125 C 3.742188 -4.632812 3.347656 -4.8125 2.859375 -4.8125 C 2.585938 -4.8125 2.375 -4.796875 2.21875 -4.765625 C 2.0625 -4.742188 1.9375 -4.71875 1.84375 -4.6875 L 1.84375 -1.171875 C 1.957031 -1.066406 2.117188 -0.96875 2.328125 -0.875 C 2.546875 -0.789062 2.773438 -0.75 3.015625 -0.75 C 3.273438 -0.75 3.5 -0.800781 3.6875 -0.90625 C 3.875 -1.007812 4.023438 -1.148438 4.140625 -1.328125 C 4.265625 -1.515625 4.351562 -1.726562 4.40625 -1.96875 C 4.46875 -2.21875 4.5 -2.484375 4.5 -2.765625 Z M 5.515625 -2.765625 C 5.515625 -2.347656 5.460938 -1.957031 5.359375 -1.59375 C 5.253906 -1.238281 5.097656 -0.929688 4.890625 -0.671875 C 4.679688 -0.421875 4.429688 -0.222656 4.140625 -0.078125 C 3.847656 0.0546875 3.507812 0.125 3.125 0.125 C 2.832031 0.125 2.570312 0.0859375 2.34375 0.015625 C 2.125 -0.046875 1.957031 -0.125 1.84375 -0.21875 L 1.84375 1.984375 L 0.859375 1.984375 L 0.859375 -5.40625 C 1.066406 -5.46875 1.34375 -5.53125 1.6875 -5.59375 C 2.03125 -5.65625 2.421875 -5.6875 2.859375 -5.6875 C 3.253906 -5.6875 3.613281 -5.617188 3.9375 -5.484375 C 4.269531 -5.347656 4.550781 -5.15625 4.78125 -4.90625 C 5.019531 -4.65625 5.203125 -4.347656 5.328125 -3.984375 C 5.453125 -3.617188 5.515625 -3.210938 5.515625 -2.765625 Z M 5.515625 -2.765625 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-24">
+<path style="stroke:none;" d="M 3.015625 -3.734375 L 4.15625 -7.421875 L 5.09375 -7.421875 C 5.25 -6.253906 5.359375 -5.054688 5.421875 -3.828125 C 5.492188 -2.609375 5.554688 -1.332031 5.609375 0 L 4.65625 0 C 4.644531 -0.425781 4.632812 -0.890625 4.625 -1.390625 C 4.625 -1.898438 4.613281 -2.421875 4.59375 -2.953125 C 4.582031 -3.492188 4.570312 -4.039062 4.5625 -4.59375 C 4.550781 -5.144531 4.539062 -5.679688 4.53125 -6.203125 L 3.4375 -2.8125 L 2.578125 -2.8125 L 1.46875 -6.203125 C 1.46875 -5.679688 1.457031 -5.144531 1.4375 -4.59375 C 1.425781 -4.050781 1.414062 -3.507812 1.40625 -2.96875 C 1.394531 -2.425781 1.382812 -1.898438 1.375 -1.390625 C 1.363281 -0.890625 1.351562 -0.425781 1.34375 0 L 0.390625 0 C 0.410156 -0.601562 0.4375 -1.222656 0.46875 -1.859375 C 0.5 -2.503906 0.535156 -3.144531 0.578125 -3.78125 C 0.617188 -4.414062 0.671875 -5.039062 0.734375 -5.65625 C 0.796875 -6.269531 0.863281 -6.859375 0.9375 -7.421875 L 1.84375 -7.421875 Z M 3.015625 -3.734375 "/>
+</symbol>
+<symbol overflow="visible" id="glyph2-0">
+<path style="stroke:none;" d="M 0.640625 2.296875 L 0.640625 -9.171875 L 7.140625 -9.171875 L 7.140625 2.296875 Z M 1.375 1.578125 L 6.421875 1.578125 L 6.421875 -8.4375 L 1.375 -8.4375 Z M 1.375 1.578125 "/>
+</symbol>
+<symbol overflow="visible" id="glyph2-1">
+<path style="stroke:none;" d="M 6.34375 -6.84375 L 6.34375 -5.75 C 6.007812 -5.925781 5.675781 -6.0625 5.34375 -6.15625 C 5.007812 -6.25 4.675781 -6.296875 4.34375 -6.296875 C 3.582031 -6.296875 2.992188 -6.050781 2.578125 -5.5625 C 2.160156 -5.082031 1.953125 -4.410156 1.953125 -3.546875 C 1.953125 -2.679688 2.160156 -2.007812 2.578125 -1.53125 C 2.992188 -1.050781 3.582031 -0.8125 4.34375 -0.8125 C 4.675781 -0.8125 5.007812 -0.851562 5.34375 -0.9375 C 5.675781 -1.03125 6.007812 -1.171875 6.34375 -1.359375 L 6.34375 -0.265625 C 6.019531 -0.117188 5.679688 -0.0078125 5.328125 0.0625 C 4.984375 0.144531 4.613281 0.1875 4.21875 0.1875 C 3.144531 0.1875 2.289062 -0.144531 1.65625 -0.8125 C 1.03125 -1.488281 0.71875 -2.398438 0.71875 -3.546875 C 0.71875 -4.703125 1.035156 -5.613281 1.671875 -6.28125 C 2.304688 -6.945312 3.179688 -7.28125 4.296875 -7.28125 C 4.648438 -7.28125 5 -7.242188 5.34375 -7.171875 C 5.6875 -7.097656 6.019531 -6.988281 6.34375 -6.84375 Z M 6.34375 -6.84375 "/>
+</symbol>
+<symbol overflow="visible" id="glyph2-2">
+<path style="stroke:none;" d="M 5.34375 -6.015625 C 5.207031 -6.085938 5.0625 -6.140625 4.90625 -6.171875 C 4.757812 -6.210938 4.59375 -6.234375 4.40625 -6.234375 C 3.75 -6.234375 3.242188 -6.019531 2.890625 -5.59375 C 2.535156 -5.164062 2.359375 -4.550781 2.359375 -3.75 L 2.359375 0 L 1.1875 0 L 1.1875 -7.109375 L 2.359375 -7.109375 L 2.359375 -6 C 2.597656 -6.4375 2.914062 -6.757812 3.3125 -6.96875 C 3.707031 -7.175781 4.1875 -7.28125 4.75 -7.28125 C 4.832031 -7.28125 4.921875 -7.273438 5.015625 -7.265625 C 5.109375 -7.253906 5.21875 -7.238281 5.34375 -7.21875 Z M 5.34375 -6.015625 "/>
+</symbol>
+<symbol overflow="visible" id="glyph2-3">
+<path style="stroke:none;" d="M 3.984375 -6.296875 C 3.359375 -6.296875 2.863281 -6.050781 2.5 -5.5625 C 2.132812 -5.070312 1.953125 -4.398438 1.953125 -3.546875 C 1.953125 -2.691406 2.128906 -2.019531 2.484375 -1.53125 C 2.847656 -1.050781 3.347656 -0.8125 3.984375 -0.8125 C 4.597656 -0.8125 5.085938 -1.054688 5.453125 -1.546875 C 5.816406 -2.035156 6 -2.703125 6 -3.546875 C 6 -4.390625 5.816406 -5.054688 5.453125 -5.546875 C 5.085938 -6.046875 4.597656 -6.296875 3.984375 -6.296875 Z M 3.984375 -7.28125 C 4.992188 -7.28125 5.789062 -6.945312 6.375 -6.28125 C 6.957031 -5.625 7.25 -4.710938 7.25 -3.546875 C 7.25 -2.378906 6.957031 -1.460938 6.375 -0.796875 C 5.789062 -0.140625 4.992188 0.1875 3.984375 0.1875 C 2.960938 0.1875 2.160156 -0.140625 1.578125 -0.796875 C 1.003906 -1.460938 0.71875 -2.378906 0.71875 -3.546875 C 0.71875 -4.710938 1.003906 -5.625 1.578125 -6.28125 C 2.160156 -6.945312 2.960938 -7.28125 3.984375 -7.28125 Z M 3.984375 -7.28125 "/>
+</symbol>
+<symbol overflow="visible" id="glyph2-4">
+<path style="stroke:none;" d="M 2.359375 -1.0625 L 2.359375 2.703125 L 1.1875 2.703125 L 1.1875 -7.109375 L 2.359375 -7.109375 L 2.359375 -6.03125 C 2.597656 -6.457031 2.90625 -6.769531 3.28125 -6.96875 C 3.65625 -7.175781 4.101562 -7.28125 4.625 -7.28125 C 5.488281 -7.28125 6.191406 -6.9375 6.734375 -6.25 C 7.273438 -5.5625 7.546875 -4.660156 7.546875 -3.546875 C 7.546875 -2.429688 7.273438 -1.53125 6.734375 -0.84375 C 6.191406 -0.15625 5.488281 0.1875 4.625 0.1875 C 4.101562 0.1875 3.65625 0.0820312 3.28125 -0.125 C 2.90625 -0.332031 2.597656 -0.644531 2.359375 -1.0625 Z M 6.328125 -3.546875 C 6.328125 -4.410156 6.148438 -5.082031 5.796875 -5.5625 C 5.441406 -6.050781 4.957031 -6.296875 4.34375 -6.296875 C 3.726562 -6.296875 3.242188 -6.050781 2.890625 -5.5625 C 2.535156 -5.082031 2.359375 -4.410156 2.359375 -3.546875 C 2.359375 -2.691406 2.535156 -2.019531 2.890625 -1.53125 C 3.242188 -1.039062 3.726562 -0.796875 4.34375 -0.796875 C 4.957031 -0.796875 5.441406 -1.039062 5.796875 -1.53125 C 6.148438 -2.019531 6.328125 -2.691406 6.328125 -3.546875 Z M 6.328125 -3.546875 "/>
+</symbol>
+<symbol overflow="visible" id="glyph2-5">
+<path style="stroke:none;" d="M 5.75 -6.90625 L 5.75 -5.796875 C 5.425781 -5.960938 5.085938 -6.085938 4.734375 -6.171875 C 4.378906 -6.253906 4.007812 -6.296875 3.625 -6.296875 C 3.039062 -6.296875 2.601562 -6.207031 2.3125 -6.03125 C 2.03125 -5.851562 1.890625 -5.585938 1.890625 -5.234375 C 1.890625 -4.960938 1.988281 -4.75 2.1875 -4.59375 C 2.394531 -4.445312 2.816406 -4.300781 3.453125 -4.15625 L 3.84375 -4.0625 C 4.675781 -3.882812 5.265625 -3.632812 5.609375 -3.3125 C 5.960938 -2.988281 6.140625 -2.539062 6.140625 -1.96875 C 6.140625 -1.300781 5.878906 -0.773438 5.359375 -0.390625 C 4.835938 -0.00390625 4.117188 0.1875 3.203125 0.1875 C 2.816406 0.1875 2.414062 0.148438 2 0.078125 C 1.59375 0.00390625 1.160156 -0.109375 0.703125 -0.265625 L 0.703125 -1.46875 C 1.140625 -1.238281 1.566406 -1.066406 1.984375 -0.953125 C 2.398438 -0.847656 2.8125 -0.796875 3.21875 -0.796875 C 3.769531 -0.796875 4.191406 -0.890625 4.484375 -1.078125 C 4.785156 -1.265625 4.9375 -1.53125 4.9375 -1.875 C 4.9375 -2.1875 4.828125 -2.425781 4.609375 -2.59375 C 4.398438 -2.769531 3.9375 -2.9375 3.21875 -3.09375 L 2.8125 -3.1875 C 2.082031 -3.34375 1.554688 -3.578125 1.234375 -3.890625 C 0.910156 -4.203125 0.75 -4.632812 0.75 -5.1875 C 0.75 -5.851562 0.984375 -6.367188 1.453125 -6.734375 C 1.929688 -7.097656 2.609375 -7.28125 3.484375 -7.28125 C 3.910156 -7.28125 4.316406 -7.25 4.703125 -7.1875 C 5.085938 -7.125 5.4375 -7.03125 5.75 -6.90625 Z M 5.75 -6.90625 "/>
+</symbol>
+<symbol overflow="visible" id="glyph2-6">
+<path style="stroke:none;" d="M 4.453125 -3.578125 C 3.515625 -3.578125 2.863281 -3.46875 2.5 -3.25 C 2.132812 -3.03125 1.953125 -2.660156 1.953125 -2.140625 C 1.953125 -1.734375 2.085938 -1.40625 2.359375 -1.15625 C 2.628906 -0.914062 3 -0.796875 3.46875 -0.796875 C 4.113281 -0.796875 4.632812 -1.023438 5.03125 -1.484375 C 5.425781 -1.941406 5.625 -2.550781 5.625 -3.3125 L 5.625 -3.578125 Z M 6.78125 -4.0625 L 6.78125 0 L 5.625 0 L 5.625 -1.078125 C 5.351562 -0.648438 5.019531 -0.332031 4.625 -0.125 C 4.226562 0.0820312 3.738281 0.1875 3.15625 0.1875 C 2.425781 0.1875 1.847656 -0.015625 1.421875 -0.421875 C 0.992188 -0.835938 0.78125 -1.382812 0.78125 -2.0625 C 0.78125 -2.863281 1.046875 -3.46875 1.578125 -3.875 C 2.117188 -4.28125 2.921875 -4.484375 3.984375 -4.484375 L 5.625 -4.484375 L 5.625 -4.609375 C 5.625 -5.140625 5.445312 -5.550781 5.09375 -5.84375 C 4.738281 -6.144531 4.238281 -6.296875 3.59375 -6.296875 C 3.1875 -6.296875 2.789062 -6.242188 2.40625 -6.140625 C 2.019531 -6.046875 1.648438 -5.898438 1.296875 -5.703125 L 1.296875 -6.78125 C 1.722656 -6.945312 2.140625 -7.070312 2.546875 -7.15625 C 2.953125 -7.238281 3.34375 -7.28125 3.71875 -7.28125 C 4.75 -7.28125 5.515625 -7.015625 6.015625 -6.484375 C 6.523438 -5.953125 6.78125 -5.144531 6.78125 -4.0625 Z M 6.78125 -4.0625 "/>
+</symbol>
+<symbol overflow="visible" id="glyph2-7">
+<path style="stroke:none;" d="M 1.21875 -9.875 L 2.390625 -9.875 L 2.390625 0 L 1.21875 0 Z M 1.21875 -9.875 "/>
+</symbol>
+<symbol overflow="visible" id="glyph2-8">
+<path style="stroke:none;" d="M 7.3125 -3.84375 L 7.3125 -3.28125 L 1.9375 -3.28125 C 1.988281 -2.46875 2.226562 -1.851562 2.65625 -1.4375 C 3.09375 -1.019531 3.695312 -0.8125 4.46875 -0.8125 C 4.914062 -0.8125 5.347656 -0.863281 5.765625 -0.96875 C 6.191406 -1.082031 6.613281 -1.25 7.03125 -1.46875 L 7.03125 -0.359375 C 6.613281 -0.179688 6.179688 -0.046875 5.734375 0.046875 C 5.296875 0.140625 4.851562 0.1875 4.40625 0.1875 C 3.269531 0.1875 2.367188 -0.140625 1.703125 -0.796875 C 1.046875 -1.460938 0.71875 -2.359375 0.71875 -3.484375 C 0.71875 -4.648438 1.03125 -5.570312 1.65625 -6.25 C 2.289062 -6.9375 3.140625 -7.28125 4.203125 -7.28125 C 5.160156 -7.28125 5.914062 -6.972656 6.46875 -6.359375 C 7.03125 -5.742188 7.3125 -4.90625 7.3125 -3.84375 Z M 6.140625 -4.1875 C 6.128906 -4.820312 5.945312 -5.332031 5.59375 -5.71875 C 5.25 -6.101562 4.789062 -6.296875 4.21875 -6.296875 C 3.5625 -6.296875 3.035156 -6.109375 2.640625 -5.734375 C 2.253906 -5.367188 2.03125 -4.851562 1.96875 -4.1875 Z M 6.140625 -4.1875 "/>
+</symbol>
+<symbol overflow="visible" id="glyph2-9">
+<path style="stroke:none;" d="M 6.328125 -3.546875 C 6.328125 -4.410156 6.148438 -5.082031 5.796875 -5.5625 C 5.441406 -6.050781 4.957031 -6.296875 4.34375 -6.296875 C 3.726562 -6.296875 3.242188 -6.050781 2.890625 -5.5625 C 2.535156 -5.082031 2.359375 -4.410156 2.359375 -3.546875 C 2.359375 -2.691406 2.535156 -2.019531 2.890625 -1.53125 C 3.242188 -1.039062 3.726562 -0.796875 4.34375 -0.796875 C 4.957031 -0.796875 5.441406 -1.039062 5.796875 -1.53125 C 6.148438 -2.019531 6.328125 -2.691406 6.328125 -3.546875 Z M 2.359375 -6.03125 C 2.597656 -6.457031 2.90625 -6.769531 3.28125 -6.96875 C 3.65625 -7.175781 4.101562 -7.28125 4.625 -7.28125 C 5.488281 -7.28125 6.191406 -6.9375 6.734375 -6.25 C 7.273438 -5.5625 7.546875 -4.660156 7.546875 -3.546875 C 7.546875 -2.429688 7.273438 -1.53125 6.734375 -0.84375 C 6.191406 -0.15625 5.488281 0.1875 4.625 0.1875 C 4.101562 0.1875 3.65625 0.0820312 3.28125 -0.125 C 2.90625 -0.332031 2.597656 -0.644531 2.359375 -1.0625 L 2.359375 0 L 1.1875 0 L 1.1875 -9.875 L 2.359375 -9.875 Z M 2.359375 -6.03125 "/>
+</symbol>
+<symbol overflow="visible" id="glyph2-10">
+<path style="stroke:none;" d="M 1.21875 -7.109375 L 2.390625 -7.109375 L 2.390625 0 L 1.21875 0 Z M 1.21875 -9.875 L 2.390625 -9.875 L 2.390625 -8.390625 L 1.21875 -8.390625 Z M 1.21875 -9.875 "/>
+</symbol>
+<symbol overflow="visible" id="glyph2-11">
+<path style="stroke:none;" d="M 7.140625 -4.296875 L 7.140625 0 L 5.96875 0 L 5.96875 -4.25 C 5.96875 -4.925781 5.835938 -5.429688 5.578125 -5.765625 C 5.316406 -6.097656 4.921875 -6.265625 4.390625 -6.265625 C 3.765625 -6.265625 3.269531 -6.0625 2.90625 -5.65625 C 2.539062 -5.257812 2.359375 -4.710938 2.359375 -4.015625 L 2.359375 0 L 1.1875 0 L 1.1875 -7.109375 L 2.359375 -7.109375 L 2.359375 -6 C 2.640625 -6.425781 2.96875 -6.742188 3.34375 -6.953125 C 3.71875 -7.171875 4.15625 -7.28125 4.65625 -7.28125 C 5.46875 -7.28125 6.082031 -7.023438 6.5 -6.515625 C 6.925781 -6.015625 7.140625 -5.273438 7.140625 -4.296875 Z M 7.140625 -4.296875 "/>
+</symbol>
+<symbol overflow="visible" id="glyph2-12">
+<path style="stroke:none;" d="M 5.90625 -3.640625 C 5.90625 -4.484375 5.726562 -5.132812 5.375 -5.59375 C 5.03125 -6.0625 4.539062 -6.296875 3.90625 -6.296875 C 3.28125 -6.296875 2.789062 -6.0625 2.4375 -5.59375 C 2.09375 -5.132812 1.921875 -4.484375 1.921875 -3.640625 C 1.921875 -2.796875 2.09375 -2.140625 2.4375 -1.671875 C 2.789062 -1.210938 3.28125 -0.984375 3.90625 -0.984375 C 4.539062 -0.984375 5.03125 -1.210938 5.375 -1.671875 C 5.726562 -2.140625 5.90625 -2.796875 5.90625 -3.640625 Z M 7.078125 -0.875 C 7.078125 0.332031 6.804688 1.226562 6.265625 1.8125 C 5.722656 2.40625 4.898438 2.703125 3.796875 2.703125 C 3.390625 2.703125 3.003906 2.671875 2.640625 2.609375 C 2.273438 2.546875 1.921875 2.453125 1.578125 2.328125 L 1.578125 1.1875 C 1.921875 1.375 2.257812 1.507812 2.59375 1.59375 C 2.925781 1.6875 3.265625 1.734375 3.609375 1.734375 C 4.378906 1.734375 4.953125 1.535156 5.328125 1.140625 C 5.710938 0.742188 5.90625 0.140625 5.90625 -0.671875 L 5.90625 -1.25 C 5.664062 -0.832031 5.351562 -0.519531 4.96875 -0.3125 C 4.59375 -0.101562 4.144531 0 3.625 0 C 2.75 0 2.046875 -0.332031 1.515625 -1 C 0.984375 -1.664062 0.71875 -2.546875 0.71875 -3.640625 C 0.71875 -4.734375 0.984375 -5.613281 1.515625 -6.28125 C 2.046875 -6.945312 2.75 -7.28125 3.625 -7.28125 C 4.144531 -7.28125 4.59375 -7.175781 4.96875 -6.96875 C 5.351562 -6.757812 5.664062 -6.445312 5.90625 -6.03125 L 5.90625 -7.109375 L 7.078125 -7.109375 Z M 7.078125 -0.875 "/>
+</symbol>
+<symbol overflow="visible" id="glyph2-13">
+<path style="stroke:none;" d="M 5.125 -8.609375 C 4.1875 -8.609375 3.441406 -8.257812 2.890625 -7.5625 C 2.347656 -6.875 2.078125 -5.929688 2.078125 -4.734375 C 2.078125 -3.535156 2.347656 -2.585938 2.890625 -1.890625 C 3.441406 -1.203125 4.1875 -0.859375 5.125 -0.859375 C 6.050781 -0.859375 6.785156 -1.203125 7.328125 -1.890625 C 7.878906 -2.585938 8.15625 -3.535156 8.15625 -4.734375 C 8.15625 -5.929688 7.878906 -6.875 7.328125 -7.5625 C 6.785156 -8.257812 6.050781 -8.609375 5.125 -8.609375 Z M 5.125 -9.65625 C 6.445312 -9.65625 7.503906 -9.207031 8.296875 -8.3125 C 9.097656 -7.414062 9.5 -6.222656 9.5 -4.734375 C 9.5 -3.234375 9.097656 -2.035156 8.296875 -1.140625 C 7.503906 -0.253906 6.445312 0.1875 5.125 0.1875 C 3.789062 0.1875 2.722656 -0.253906 1.921875 -1.140625 C 1.128906 -2.035156 0.734375 -3.234375 0.734375 -4.734375 C 0.734375 -6.222656 1.128906 -7.414062 1.921875 -8.3125 C 2.722656 -9.207031 3.789062 -9.65625 5.125 -9.65625 Z M 5.125 -9.65625 "/>
+</symbol>
+<symbol overflow="visible" id="glyph2-14">
+<path style="stroke:none;" d="M 1.109375 -2.8125 L 1.109375 -7.109375 L 2.265625 -7.109375 L 2.265625 -2.84375 C 2.265625 -2.175781 2.394531 -1.671875 2.65625 -1.328125 C 2.925781 -0.992188 3.320312 -0.828125 3.84375 -0.828125 C 4.476562 -0.828125 4.976562 -1.023438 5.34375 -1.421875 C 5.707031 -1.828125 5.890625 -2.378906 5.890625 -3.078125 L 5.890625 -7.109375 L 7.0625 -7.109375 L 7.0625 0 L 5.890625 0 L 5.890625 -1.09375 C 5.609375 -0.65625 5.28125 -0.332031 4.90625 -0.125 C 4.53125 0.0820312 4.09375 0.1875 3.59375 0.1875 C 2.78125 0.1875 2.160156 -0.0664062 1.734375 -0.578125 C 1.316406 -1.085938 1.109375 -1.832031 1.109375 -2.8125 Z M 4.046875 -7.28125 Z M 4.046875 -7.28125 "/>
+</symbol>
+<symbol overflow="visible" id="glyph2-15">
+<path style="stroke:none;" d="M 2.375 -9.125 L 2.375 -7.109375 L 4.78125 -7.109375 L 4.78125 -6.203125 L 2.375 -6.203125 L 2.375 -2.34375 C 2.375 -1.757812 2.453125 -1.382812 2.609375 -1.21875 C 2.773438 -1.0625 3.101562 -0.984375 3.59375 -0.984375 L 4.78125 -0.984375 L 4.78125 0 L 3.59375 0 C 2.6875 0 2.0625 -0.164062 1.71875 -0.5 C 1.375 -0.84375 1.203125 -1.457031 1.203125 -2.34375 L 1.203125 -6.203125 L 0.34375 -6.203125 L 0.34375 -7.109375 L 1.203125 -7.109375 L 1.203125 -9.125 Z M 2.375 -9.125 "/>
+</symbol>
+<symbol overflow="visible" id="glyph2-16">
+<path style="stroke:none;" d=""/>
+</symbol>
+<symbol overflow="visible" id="glyph2-17">
+<path style="stroke:none;" d="M 1.28125 -9.484375 L 6.71875 -9.484375 L 6.71875 -8.390625 L 2.5625 -8.390625 L 2.5625 -5.609375 L 6.3125 -5.609375 L 6.3125 -4.53125 L 2.5625 -4.53125 L 2.5625 0 L 1.28125 0 Z M 1.28125 -9.484375 "/>
+</symbol>
+<symbol overflow="visible" id="glyph2-18">
+<path style="stroke:none;" d="M 6.765625 -5.75 C 7.054688 -6.269531 7.40625 -6.65625 7.8125 -6.90625 C 8.21875 -7.15625 8.695312 -7.28125 9.25 -7.28125 C 9.988281 -7.28125 10.554688 -7.019531 10.953125 -6.5 C 11.359375 -5.976562 11.5625 -5.242188 11.5625 -4.296875 L 11.5625 0 L 10.390625 0 L 10.390625 -4.25 C 10.390625 -4.9375 10.265625 -5.441406 10.015625 -5.765625 C 9.773438 -6.097656 9.410156 -6.265625 8.921875 -6.265625 C 8.316406 -6.265625 7.835938 -6.0625 7.484375 -5.65625 C 7.128906 -5.257812 6.953125 -4.710938 6.953125 -4.015625 L 6.953125 0 L 5.78125 0 L 5.78125 -4.25 C 5.78125 -4.9375 5.660156 -5.441406 5.421875 -5.765625 C 5.179688 -6.097656 4.804688 -6.265625 4.296875 -6.265625 C 3.703125 -6.265625 3.226562 -6.0625 2.875 -5.65625 C 2.53125 -5.25 2.359375 -4.703125 2.359375 -4.015625 L 2.359375 0 L 1.1875 0 L 1.1875 -7.109375 L 2.359375 -7.109375 L 2.359375 -6 C 2.617188 -6.4375 2.9375 -6.757812 3.3125 -6.96875 C 3.6875 -7.175781 4.128906 -7.28125 4.640625 -7.28125 C 5.160156 -7.28125 5.597656 -7.148438 5.953125 -6.890625 C 6.316406 -6.628906 6.585938 -6.25 6.765625 -5.75 Z M 6.765625 -5.75 "/>
+</symbol>
+<symbol overflow="visible" id="glyph2-19">
+<path style="stroke:none;" d="M 6.953125 -9.171875 L 6.953125 -7.921875 C 6.472656 -8.148438 6.015625 -8.320312 5.578125 -8.4375 C 5.148438 -8.550781 4.734375 -8.609375 4.328125 -8.609375 C 3.628906 -8.609375 3.085938 -8.472656 2.703125 -8.203125 C 2.328125 -7.929688 2.140625 -7.546875 2.140625 -7.046875 C 2.140625 -6.628906 2.265625 -6.3125 2.515625 -6.09375 C 2.773438 -5.882812 3.253906 -5.710938 3.953125 -5.578125 L 4.734375 -5.421875 C 5.679688 -5.234375 6.382812 -4.910156 6.84375 -4.453125 C 7.300781 -3.992188 7.53125 -3.378906 7.53125 -2.609375 C 7.53125 -1.691406 7.222656 -0.992188 6.609375 -0.515625 C 5.992188 -0.046875 5.085938 0.1875 3.890625 0.1875 C 3.441406 0.1875 2.960938 0.132812 2.453125 0.03125 C 1.953125 -0.0703125 1.429688 -0.222656 0.890625 -0.421875 L 0.890625 -1.734375 C 1.410156 -1.441406 1.921875 -1.222656 2.421875 -1.078125 C 2.921875 -0.929688 3.410156 -0.859375 3.890625 -0.859375 C 4.628906 -0.859375 5.195312 -1 5.59375 -1.28125 C 5.988281 -1.570312 6.1875 -1.984375 6.1875 -2.515625 C 6.1875 -2.984375 6.039062 -3.347656 5.75 -3.609375 C 5.46875 -3.867188 5.003906 -4.066406 4.359375 -4.203125 L 3.578125 -4.359375 C 2.617188 -4.546875 1.925781 -4.84375 1.5 -5.25 C 1.070312 -5.65625 0.859375 -6.21875 0.859375 -6.9375 C 0.859375 -7.78125 1.148438 -8.441406 1.734375 -8.921875 C 2.328125 -9.410156 3.144531 -9.65625 4.1875 -9.65625 C 4.625 -9.65625 5.070312 -9.613281 5.53125 -9.53125 C 6 -9.445312 6.472656 -9.328125 6.953125 -9.171875 Z M 6.953125 -9.171875 "/>
+</symbol>
+<symbol overflow="visible" id="glyph2-20">
+<path style="stroke:none;" d="M 4.1875 0.65625 C 3.851562 1.507812 3.53125 2.0625 3.21875 2.3125 C 2.90625 2.570312 2.488281 2.703125 1.96875 2.703125 L 1.03125 2.703125 L 1.03125 1.734375 L 1.71875 1.734375 C 2.039062 1.734375 2.289062 1.65625 2.46875 1.5 C 2.644531 1.34375 2.835938 0.984375 3.046875 0.421875 L 3.265625 -0.109375 L 0.390625 -7.109375 L 1.625 -7.109375 L 3.84375 -1.546875 L 6.0625 -7.109375 L 7.3125 -7.109375 Z M 4.1875 0.65625 "/>
+</symbol>
+</g>
+</defs>
+<g id="surface268880">
+<rect x="0" y="0" width="774" height="152" style="fill:rgb(100%,100%,100%);fill-opacity:1;stroke:none;"/>
+<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 21.75297 10.408118 L 26.433829 10.408118 L 26.433829 12.281165 L 21.75297 12.281165 Z M 21.75297 10.408118 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
+<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 29.079728 10.51222 L 32.829728 10.51222 L 32.829728 12.149915 L 29.079728 12.149915 Z M 29.079728 10.51222 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+  <use xlink:href="#glyph0-1" x="20.171875" y="57.705621"/>
+  <use xlink:href="#glyph0-2" x="30.171875" y="57.705621"/>
+  <use xlink:href="#glyph0-3" x="40.171875" y="57.705621"/>
+  <use xlink:href="#glyph0-4" x="50.171875" y="57.705621"/>
+  <use xlink:href="#glyph0-5" x="60.171875" y="57.705621"/>
+  <use xlink:href="#glyph0-6" x="70.171875" y="57.705621"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+  <use xlink:href="#glyph0-7" x="174.203125" y="60.053277"/>
+  <use xlink:href="#glyph0-8" x="184.203125" y="60.053277"/>
+</g>
+<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 40.925236 10.544446 L 44.675236 10.544446 L 44.675236 12.090345 L 40.925236 12.090345 Z M 40.925236 10.544446 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
+<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 34.883439 10.536634 L 38.633439 10.536634 L 38.633439 12.120032 L 34.883439 12.120032 Z M 34.883439 10.536634 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
+<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 47.084806 10.484876 L 52.045743 10.484876 L 52.045743 12.130774 L 47.084806 12.130774 Z M 47.084806 10.484876 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
+<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 53.980118 10.376868 L 59.866642 10.376868 L 59.866642 12.279603 L 53.980118 12.279603 Z M 53.980118 10.376868 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
+<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 54.048478 13.825501 L 59.868009 13.825501 L 59.868009 15.490345 L 54.048478 15.490345 Z M 54.048478 13.825501 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
+<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 26.481876 11.338001 L 28.593009 11.332337 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
+<path style="fill-rule:evenodd;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 28.968009 11.33136 L 28.468595 11.582728 L 28.593009 11.332337 L 28.467228 11.082728 Z M 28.968009 11.33136 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
+<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 32.876798 11.329798 L 34.396525 11.328626 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
+<path style="fill-rule:evenodd;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 34.771525 11.328431 L 34.27172 11.578821 L 34.396525 11.328626 L 34.271329 11.078821 Z M 34.771525 11.328431 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
+<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 38.633439 11.328431 L 40.438517 11.319642 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
+<path style="fill-rule:evenodd;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 40.813517 11.317884 L 40.314689 11.570228 L 40.438517 11.319642 L 40.312345 11.070423 Z M 40.813517 11.317884 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
+<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 44.675236 11.317298 L 46.597892 11.309876 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
+<path style="fill-rule:evenodd;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 46.972892 11.308313 L 46.473868 11.560267 L 46.597892 11.309876 L 46.471915 11.060267 Z M 46.972892 11.308313 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
+<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 52.045743 11.307923 L 53.4934 11.323157 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
+<path style="fill-rule:evenodd;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 53.8684 11.327063 L 53.365861 11.57179 L 53.4934 11.323157 L 53.370939 11.07179 Z M 53.8684 11.327063 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+  <use xlink:href="#glyph0-9" x="286.757813" y="60.611871"/>
+  <use xlink:href="#glyph0-10" x="296.757813" y="60.611871"/>
+  <use xlink:href="#glyph0-1" x="306.757813" y="60.611871"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+  <use xlink:href="#glyph0-11" x="405.660156" y="59.904839"/>
+  <use xlink:href="#glyph0-10" x="415.660156" y="59.904839"/>
+  <use xlink:href="#glyph0-12" x="425.660156" y="59.904839"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+  <use xlink:href="#glyph1-1" x="511.308594" y="58.064616"/>
+  <use xlink:href="#glyph1-2" x="517.308757" y="58.064616"/>
+  <use xlink:href="#glyph1-3" x="523.308919" y="58.064616"/>
+  <use xlink:href="#glyph1-4" x="529.309082" y="58.064616"/>
+  <use xlink:href="#glyph1-5" x="535.309245" y="58.064616"/>
+  <use xlink:href="#glyph1-6" x="541.309408" y="58.064616"/>
+  <use xlink:href="#glyph1-7" x="547.30957" y="58.064616"/>
+  <use xlink:href="#glyph1-8" x="553.309733" y="58.064616"/>
+  <use xlink:href="#glyph1-9" x="559.309896" y="58.064616"/>
+  <use xlink:href="#glyph1-10" x="565.310059" y="58.064616"/>
+  <use xlink:href="#glyph1-11" x="571.310221" y="58.064616"/>
+  <use xlink:href="#glyph1-12" x="577.310384" y="58.064616"/>
+  <use xlink:href="#glyph1-13" x="583.310547" y="58.064616"/>
+  <use xlink:href="#glyph1-8" x="589.31071" y="58.064616"/>
+  <use xlink:href="#glyph1-14" x="595.310872" y="58.064616"/>
+</g>
+<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 45.671915 11.342298 L 45.655704 11.342298 L 45.655704 14.657923 L 53.561759 14.657923 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
+<path style="fill-rule:evenodd;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 53.936759 14.657923 L 53.436759 14.907923 L 53.561759 14.657923 L 53.436759 14.407923 Z M 53.936759 14.657923 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+  <use xlink:href="#glyph1-15" x="657.078125" y="57.724772"/>
+  <use xlink:href="#glyph1-16" x="663.078288" y="57.724772"/>
+  <use xlink:href="#glyph1-10" x="669.078451" y="57.724772"/>
+  <use xlink:href="#glyph1-6" x="675.078613" y="57.724772"/>
+  <use xlink:href="#glyph1-8" x="681.078776" y="57.724772"/>
+  <use xlink:href="#glyph1-17" x="687.078939" y="57.724772"/>
+  <use xlink:href="#glyph1-11" x="693.079102" y="57.724772"/>
+  <use xlink:href="#glyph1-18" x="699.079264" y="57.724772"/>
+  <use xlink:href="#glyph1-19" x="705.079427" y="57.724772"/>
+  <use xlink:href="#glyph1-4" x="711.07959" y="57.724772"/>
+  <use xlink:href="#glyph1-20" x="717.079753" y="57.724772"/>
+  <use xlink:href="#glyph1-21" x="723.079915" y="57.724772"/>
+  <use xlink:href="#glyph1-22" x="729.080078" y="57.724772"/>
+  <use xlink:href="#glyph1-23" x="735.080241" y="57.724772"/>
+  <use xlink:href="#glyph1-21" x="741.080404" y="57.724772"/>
+  <use xlink:href="#glyph1-22" x="747.080566" y="57.724772"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+  <use xlink:href="#glyph1-24" x="673.335938" y="124.170085"/>
+  <use xlink:href="#glyph1-11" x="679.3361" y="124.170085"/>
+  <use xlink:href="#glyph1-13" x="685.336263" y="124.170085"/>
+  <use xlink:href="#glyph1-8" x="691.336426" y="124.170085"/>
+  <use xlink:href="#glyph1-4" x="697.336589" y="124.170085"/>
+  <use xlink:href="#glyph1-20" x="703.336751" y="124.170085"/>
+  <use xlink:href="#glyph1-21" x="709.336914" y="124.170085"/>
+  <use xlink:href="#glyph1-22" x="715.337077" y="124.170085"/>
+  <use xlink:href="#glyph1-23" x="721.33724" y="124.170085"/>
+  <use xlink:href="#glyph1-21" x="727.337402" y="124.170085"/>
+  <use xlink:href="#glyph1-22" x="733.337565" y="124.170085"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+  <use xlink:href="#glyph2-1" x="168.71875" y="31.959093"/>
+  <use xlink:href="#glyph2-2" x="175.866102" y="31.959093"/>
+  <use xlink:href="#glyph2-3" x="180.92551" y="31.959093"/>
+  <use xlink:href="#glyph2-4" x="188.879069" y="31.959093"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+  <use xlink:href="#glyph2-5" x="288.109375" y="31.681749"/>
+  <use xlink:href="#glyph2-1" x="294.882378" y="31.681749"/>
+  <use xlink:href="#glyph2-6" x="302.029731" y="31.681749"/>
+  <use xlink:href="#glyph2-7" x="309.996039" y="31.681749"/>
+  <use xlink:href="#glyph2-8" x="313.607964" y="31.681749"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+  <use xlink:href="#glyph2-5" x="535.988281" y="33.365343"/>
+  <use xlink:href="#glyph2-1" x="542.761285" y="33.365343"/>
+  <use xlink:href="#glyph2-6" x="549.908637" y="33.365343"/>
+  <use xlink:href="#glyph2-7" x="557.874946" y="33.365343"/>
+  <use xlink:href="#glyph2-8" x="561.486871" y="33.365343"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+  <use xlink:href="#glyph2-9" x="26.695313" y="32.365343"/>
+  <use xlink:href="#glyph2-10" x="34.947266" y="32.365343"/>
+  <use xlink:href="#glyph2-11" x="38.559191" y="32.365343"/>
+  <use xlink:href="#glyph2-11" x="46.798394" y="32.365343"/>
+  <use xlink:href="#glyph2-10" x="55.037598" y="32.365343"/>
+  <use xlink:href="#glyph2-11" x="58.649523" y="32.365343"/>
+  <use xlink:href="#glyph2-12" x="66.888726" y="32.365343"/>
+</g>
+<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-dasharray:0.14,0.14;stroke-miterlimit:10;" d="M 45.300431 9.486438 L 60.373478 9.486438 L 60.373478 16.175696 L 45.300431 16.175696 Z M 45.300431 9.486438 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+  <use xlink:href="#glyph2-13" x="532.003906" y="11.904405"/>
+  <use xlink:href="#glyph2-14" x="542.236382" y="11.904405"/>
+  <use xlink:href="#glyph2-15" x="550.475586" y="11.904405"/>
+  <use xlink:href="#glyph2-4" x="555.5727" y="11.904405"/>
+  <use xlink:href="#glyph2-14" x="563.824653" y="11.904405"/>
+  <use xlink:href="#glyph2-15" x="572.063856" y="11.904405"/>
+  <use xlink:href="#glyph2-16" x="577.16097" y="11.904405"/>
+  <use xlink:href="#glyph2-17" x="581.293186" y="11.904405"/>
+  <use xlink:href="#glyph2-3" x="588.307346" y="11.904405"/>
+  <use xlink:href="#glyph2-2" x="596.260905" y="11.904405"/>
+  <use xlink:href="#glyph2-18" x="601.377279" y="11.904405"/>
+  <use xlink:href="#glyph2-6" x="614.040853" y="11.904405"/>
+  <use xlink:href="#glyph2-15" x="622.007161" y="11.904405"/>
+  <use xlink:href="#glyph2-15" x="627.104275" y="11.904405"/>
+  <use xlink:href="#glyph2-8" x="632.201389" y="11.904405"/>
+  <use xlink:href="#glyph2-2" x="640.199436" y="11.904405"/>
+  <use xlink:href="#glyph2-16" x="645.544217" y="11.904405"/>
+  <use xlink:href="#glyph2-19" x="649.676432" y="11.904405"/>
+  <use xlink:href="#glyph2-20" x="657.928385" y="11.904405"/>
+  <use xlink:href="#glyph2-5" x="665.621799" y="11.904405"/>
+  <use xlink:href="#glyph2-15" x="672.394803" y="11.904405"/>
+  <use xlink:href="#glyph2-8" x="677.491916" y="11.904405"/>
+  <use xlink:href="#glyph2-18" x="685.489963" y="11.904405"/>
+</g>
+</g>
+</svg>
diff --git a/Documentation/admin-guide/media/ivtv-cardlist.rst b/Documentation/admin-guide/media/ivtv-cardlist.rst
new file mode 100644
index 000000000000..c34a9ebc9ac2
--- /dev/null
+++ b/Documentation/admin-guide/media/ivtv-cardlist.rst
@@ -0,0 +1,139 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+IVTV cards list
+===============
+
+.. tabularcolumns:: |p{1.4cm}|p{12.7cm}|p{3.4cm}|
+
+.. flat-table::
+   :header-rows: 1
+   :widths: 2 19 18
+   :stub-columns: 0
+
+   * - Card number
+     - Card name
+     - PCI IDs
+
+   * - 0
+     - Hauppauge WinTV PVR-250
+     - IVTV16 104d:813d
+
+   * - 1
+     - Hauppauge WinTV PVR-350
+     - IVTV16 104d:813d
+
+   * - 2
+     - Hauppauge WinTV PVR-150
+     - IVTV16 104d:813d
+
+   * - 3
+     - AVerMedia M179
+     - IVTV15 1461:a3cf, IVTV15 1461:a3ce
+
+   * - 4
+     - Yuan MPG600, Kuroutoshikou ITVC16-STVLP
+     - IVTV16 12ab:fff3, IVTV16 12ab:ffff
+
+   * - 5
+     - YUAN MPG160, Kuroutoshikou ITVC15-STVLP, I/O Data GV-M2TV/PCI
+     - IVTV15 10fc:40a0
+
+   * - 6
+     - Yuan PG600, Diamond PVR-550
+     - IVTV16 ff92:0070, IVTV16 ffab:0600
+
+   * - 7
+     - Adaptec VideOh! AVC-2410
+     - IVTV16 9005:0093
+
+   * - 8
+     - Adaptec VideOh! AVC-2010
+     - IVTV16 9005:0092
+
+   * - 9
+     - Nagase Transgear 5000TV
+     - IVTV16 1461:bfff
+
+   * - 10
+     - AOpen VA2000MAX-SNT6
+     - IVTV16 0000:ff5f
+
+   * - 11
+     - Yuan MPG600GR, Kuroutoshikou CX23416GYC-STVLP
+     - IVTV16 12ab:0600, IVTV16 fbab:0600, IVTV16 1154:0523
+
+   * - 12
+     - I/O Data GV-MVP/RX, GV-MVP/RX2W (dual tuner)
+     - IVTV16 10fc:d01e, IVTV16 10fc:d038, IVTV16 10fc:d039
+
+   * - 13
+     - I/O Data GV-MVP/RX2E
+     - IVTV16 10fc:d025
+
+   * - 14
+     - GotView PCI DVD
+     - IVTV16 12ab:0600
+
+   * - 15
+     - GotView PCI DVD2 Deluxe
+     - IVTV16 ffac:0600
+
+   * - 16
+     - Yuan MPC622
+     - IVTV16 ff01:d998
+
+   * - 17
+     - Digital Cowboy DCT-MTVP1
+     - IVTV16 1461:bfff
+
+   * - 18
+     - Yuan PG600-2, GotView PCI DVD Lite
+     - IVTV16 ffab:0600, IVTV16 ffad:0600
+
+   * - 19
+     - Club3D ZAP-TV1x01
+     - IVTV16 ffab:0600
+
+   * - 20
+     - AVerTV MCE 116 Plus
+     - IVTV16 1461:c439
+
+   * - 21
+     - ASUS Falcon2
+     - IVTV16 1043:4b66, IVTV16 1043:462e, IVTV16 1043:4b2e
+
+   * - 22
+     - AVerMedia PVR-150 Plus / AVerTV M113 Partsnic (Daewoo) Tuner
+     - IVTV16 1461:c034, IVTV16 1461:c035
+
+   * - 23
+     - AVerMedia EZMaker PCI Deluxe
+     - IVTV16 1461:c03f
+
+   * - 24
+     - AVerMedia M104
+     - IVTV16 1461:c136
+
+   * - 25
+     - Buffalo PC-MV5L/PCI
+     - IVTV16 1154:052b
+
+   * - 26
+     - AVerMedia UltraTV 1500 MCE / AVerTV M113 Philips Tuner
+     - IVTV16 1461:c019, IVTV16 1461:c01b
+
+   * - 27
+     - Sony VAIO Giga Pocket (ENX Kikyou)
+     - IVTV16 104d:813d
+
+   * - 28
+     - Hauppauge WinTV PVR-350 (V1)
+     - IVTV16 104d:813d
+
+   * - 29
+     - Yuan MPG600GR, Kuroutoshikou CX23416GYC-STVLP (no GR)
+     - IVTV16 104d:813d
+
+   * - 30
+     - Yuan MPG600GR, Kuroutoshikou CX23416GYC-STVLP (no GR/YCS)
+     - IVTV16 104d:813d
diff --git a/Documentation/admin-guide/media/ivtv.rst b/Documentation/admin-guide/media/ivtv.rst
new file mode 100644
index 000000000000..7b8775d20214
--- /dev/null
+++ b/Documentation/admin-guide/media/ivtv.rst
@@ -0,0 +1,218 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+The ivtv driver
+===============
+
+Author: Hans Verkuil <hverkuil@xs4all.nl>
+
+This is a v4l2 device driver for the Conexant cx23415/6 MPEG encoder/decoder.
+The cx23415 can do both encoding and decoding, the cx23416 can only do MPEG
+encoding. Currently the only card featuring full decoding support is the
+Hauppauge PVR-350.
+
+.. note::
+
+   #) This driver requires the latest encoder firmware (version 2.06.039, size
+      376836 bytes). Get the firmware from here:
+
+      https://linuxtv.org/downloads/firmware/#conexant
+
+   #) 'normal' TV applications do not work with this driver, you need
+      an application that can handle MPEG input such as mplayer, xine, MythTV,
+      etc.
+
+The primary goal of the IVTV project is to provide a "clean room" Linux
+Open Source driver implementation for video capture cards based on the
+iCompression iTVC15 or Conexant CX23415/CX23416 MPEG Codec.
+
+Features
+--------
+
+ * Hardware mpeg2 capture of broadcast video (and sound) via the tuner or
+   S-Video/Composite and audio line-in.
+ * Hardware mpeg2 capture of FM radio where hardware support exists
+ * Supports NTSC, PAL, SECAM with stereo sound
+ * Supports SAP and bilingual transmissions.
+ * Supports raw VBI (closed captions and teletext).
+ * Supports sliced VBI (closed captions and teletext) and is able to insert
+   this into the captured MPEG stream.
+ * Supports raw YUV and PCM input.
+
+Additional features for the PVR-350 (CX23415 based)
+---------------------------------------------------
+
+ * Provides hardware mpeg2 playback
+ * Provides comprehensive OSD (On Screen Display: ie. graphics overlaying the
+   video signal)
+ * Provides a framebuffer (allowing X applications to appear on the video
+   device)
+ * Supports raw YUV output.
+
+IMPORTANT: In case of problems first read this page:
+	https://help.ubuntu.com/community/Install_IVTV_Troubleshooting
+
+See also
+--------
+
+https://linuxtv.org
+
+IRC
+---
+
+irc://irc.freenode.net/#v4l
+
+----------------------------------------------------------
+
+Devices
+-------
+
+A maximum of 12 ivtv boards are allowed at the moment.
+
+Cards that don't have a video output capability (i.e. non PVR350 cards)
+lack the vbi8, vbi16, video16 and video48 devices. They also do not
+support the framebuffer device /dev/fbx for OSD.
+
+The radio0 device may or may not be present, depending on whether the
+card has a radio tuner or not.
+
+Here is a list of the base v4l devices:
+
+.. code-block:: none
+
+	crw-rw----    1 root     video     81,   0 Jun 19 22:22 /dev/video0
+	crw-rw----    1 root     video     81,  16 Jun 19 22:22 /dev/video16
+	crw-rw----    1 root     video     81,  24 Jun 19 22:22 /dev/video24
+	crw-rw----    1 root     video     81,  32 Jun 19 22:22 /dev/video32
+	crw-rw----    1 root     video     81,  48 Jun 19 22:22 /dev/video48
+	crw-rw----    1 root     video     81,  64 Jun 19 22:22 /dev/radio0
+	crw-rw----    1 root     video     81, 224 Jun 19 22:22 /dev/vbi0
+	crw-rw----    1 root     video     81, 228 Jun 19 22:22 /dev/vbi8
+	crw-rw----    1 root     video     81, 232 Jun 19 22:22 /dev/vbi16
+
+Base devices
+------------
+
+For every extra card you have the numbers increased by one. For example,
+/dev/video0 is listed as the 'base' encoding capture device so we have:
+
+- /dev/video0  is the encoding capture device for the first card (card 0)
+- /dev/video1  is the encoding capture device for the second card (card 1)
+- /dev/video2  is the encoding capture device for the third card (card 2)
+
+Note that if the first card doesn't have a feature (eg no decoder, so no
+video16, the second card will still use video17. The simple rule is 'add
+the card number to the base device number'. If you have other capture
+cards (e.g. WinTV PCI) that are detected first, then you have to tell
+the ivtv module about it so that it will start counting at 1 (or 2, or
+whatever). Otherwise the device numbers can get confusing. The ivtv
+'ivtv_first_minor' module option can be used for that.
+
+
+- /dev/video0
+
+  The encoding capture device(s).
+
+  Read-only.
+
+  Reading from this device gets you the MPEG1/2 program stream.
+  Example:
+
+  .. code-block:: none
+
+	cat /dev/video0 > my.mpg (you need to hit ctrl-c to exit)
+
+
+- /dev/video16
+
+  The decoder output device(s)
+
+  Write-only. Only present if the MPEG decoder (i.e. CX23415) exists.
+
+  An mpeg2 stream sent to this device will appear on the selected video
+  display, audio will appear on the line-out/audio out.  It is only
+  available for cards that support video out. Example:
+
+  .. code-block:: none
+
+	cat my.mpg >/dev/video16
+
+
+- /dev/video24
+
+  The raw audio capture device(s).
+
+  Read-only
+
+  The raw audio PCM stereo stream from the currently selected
+  tuner or audio line-in.  Reading from this device results in a raw
+  (signed 16 bit Little Endian, 48000 Hz, stereo pcm) capture.
+  This device only captures audio. This should be replaced by an ALSA
+  device in the future.
+  Note that there is no corresponding raw audio output device, this is
+  not supported in the decoder firmware.
+
+
+- /dev/video32
+
+  The raw video capture device(s)
+
+  Read-only
+
+  The raw YUV video output from the current video input. The YUV format
+  is non-standard (V4L2_PIX_FMT_HM12).
+
+  Note that the YUV and PCM streams are not synchronized, so they are of
+  limited use.
+
+
+- /dev/video48
+
+  The raw video display device(s)
+
+  Write-only. Only present if the MPEG decoder (i.e. CX23415) exists.
+
+  Writes a YUV stream to the decoder of the card.
+
+
+- /dev/radio0
+
+  The radio tuner device(s)
+
+  Cannot be read or written.
+
+  Used to enable the radio tuner and tune to a frequency. You cannot
+  read or write audio streams with this device.  Once you use this
+  device to tune the radio, use /dev/video24 to read the raw pcm stream
+  or /dev/video0 to get an mpeg2 stream with black video.
+
+
+- /dev/vbi0
+
+  The 'vertical blank interval' (Teletext, CC, WSS etc) capture device(s)
+
+  Read-only
+
+  Captures the raw (or sliced) video data sent during the Vertical Blank
+  Interval. This data is used to encode teletext, closed captions, VPS,
+  widescreen signalling, electronic program guide information, and other
+  services.
+
+
+- /dev/vbi8
+
+  Processed vbi feedback device(s)
+
+  Read-only. Only present if the MPEG decoder (i.e. CX23415) exists.
+
+  The sliced VBI data embedded in an MPEG stream is reproduced on this
+  device. So while playing back a recording on /dev/video16, you can
+  read the embedded VBI data from /dev/vbi8.
+
+
+- /dev/vbi16
+
+  The vbi 'display' device(s)
+
+  Write-only. Only present if the MPEG decoder (i.e. CX23415) exists.
+
+  Can be used to send sliced VBI data to the video-out connector.
diff --git a/Documentation/admin-guide/media/lmedm04.rst b/Documentation/admin-guide/media/lmedm04.rst
new file mode 100644
index 000000000000..a6ee33413748
--- /dev/null
+++ b/Documentation/admin-guide/media/lmedm04.rst
@@ -0,0 +1,107 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Firmware files for lmedm04 cards
+================================
+
+To extract firmware for the DM04/QQBOX you need to copy the
+following file(s) to this directory.
+
+For DM04+/QQBOX LME2510C (Sharp 7395 Tuner)
+-------------------------------------------
+
+The Sharp 7395 driver can be found in windows/system32/drivers
+
+US2A0D.sys (dated 17 Mar 2009)
+
+
+and run:
+
+.. code-block:: none
+
+	scripts/get_dvb_firmware lme2510c_s7395
+
+will produce dvb-usb-lme2510c-s7395.fw
+
+An alternative but older firmware can be found on the driver
+disk DVB-S_EN_3.5A in BDADriver/driver
+
+LMEBDA_DVBS7395C.sys (dated 18 Jan 2008)
+
+and run:
+
+.. code-block:: none
+
+	./get_dvb_firmware lme2510c_s7395_old
+
+will produce dvb-usb-lme2510c-s7395.fw
+
+The LG firmware can be found on the driver
+disk DM04+_5.1A[LG] in BDADriver/driver
+
+For DM04 LME2510 (LG Tuner)
+---------------------------
+
+LMEBDA_DVBS.sys (dated 13 Nov 2007)
+
+and run:
+
+
+.. code-block:: none
+
+	./get_dvb_firmware lme2510_lg
+
+will produce dvb-usb-lme2510-lg.fw
+
+
+Other LG firmware can be extracted manually from US280D.sys
+only found in windows/system32/drivers
+
+dd if=US280D.sys ibs=1 skip=42360 count=3924 of=dvb-usb-lme2510-lg.fw
+
+For DM04 LME2510C (LG Tuner)
+----------------------------
+
+.. code-block:: none
+
+	dd if=US280D.sys ibs=1 skip=35200 count=3850 of=dvb-usb-lme2510c-lg.fw
+
+
+The Sharp 0194 tuner driver can be found in windows/system32/drivers
+
+US290D.sys (dated 09 Apr 2009)
+
+For LME2510
+-----------
+
+.. code-block:: none
+
+	dd if=US290D.sys ibs=1 skip=36856 count=3976 of=dvb-usb-lme2510-s0194.fw
+
+
+For LME2510C
+------------
+
+
+.. code-block:: none
+
+	dd if=US290D.sys ibs=1 skip=33152 count=3697 of=dvb-usb-lme2510c-s0194.fw
+
+
+The m88rs2000 tuner driver can be found in windows/system32/drivers
+
+US2B0D.sys (dated 29 Jun 2010)
+
+
+.. code-block:: none
+
+	dd if=US2B0D.sys ibs=1 skip=34432 count=3871 of=dvb-usb-lme2510c-rs2000.fw
+
+We need to modify id of rs2000 firmware or it will warm boot id 3344:1120.
+
+
+.. code-block:: none
+
+
+	echo -ne \\xF0\\x22 | dd conv=notrunc bs=1 count=2 seek=266 of=dvb-usb-lme2510c-rs2000.fw
+
+Copy the firmware file(s) to /lib/firmware
diff --git a/Documentation/admin-guide/media/meye.rst b/Documentation/admin-guide/media/meye.rst
new file mode 100644
index 000000000000..9098a1e65f8b
--- /dev/null
+++ b/Documentation/admin-guide/media/meye.rst
@@ -0,0 +1,93 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: <isonum.txt>
+
+Vaio Picturebook Motion Eye Camera Driver
+=========================================
+
+Copyright |copy| 2001-2004 Stelian Pop <stelian@popies.net>
+
+Copyright |copy| 2001-2002 Alcôve <www.alcove.com>
+
+Copyright |copy| 2000 Andrew Tridgell <tridge@samba.org>
+
+This driver enable the use of video4linux compatible applications with the
+Motion Eye camera. This driver requires the "Sony Laptop Extras" driver (which
+can be found in the "Misc devices" section of the kernel configuration utility)
+to be compiled and installed (using its "camera=1" parameter).
+
+It can do at maximum 30 fps @ 320x240 or 15 fps @ 640x480.
+
+Grabbing is supported in packed YUV colorspace only.
+
+MJPEG hardware grabbing is supported via a private API (see below).
+
+Hardware supported
+------------------
+
+This driver supports the 'second' version of the MotionEye camera :)
+
+The first version was connected directly on the video bus of the Neomagic
+video card and is unsupported.
+
+The second one, made by Kawasaki Steel is fully supported by this
+driver (PCI vendor/device is 0x136b/0xff01)
+
+The third one, present in recent (more or less last year) Picturebooks
+(C1M* models), is not supported. The manufacturer has given the specs
+to the developers under a NDA (which allows the development of a GPL
+driver however), but things are not moving very fast (see
+http://r-engine.sourceforge.net/) (PCI vendor/device is 0x10cf/0x2011).
+
+There is a forth model connected on the USB bus in TR1* Vaio laptops.
+This camera is not supported at all by the current driver, in fact
+little information if any is available for this camera
+(USB vendor/device is 0x054c/0x0107).
+
+Driver options
+--------------
+
+Several options can be passed to the meye driver using the standard
+module argument syntax (<param>=<value> when passing the option to the
+module or meye.<param>=<value> on the kernel boot line when meye is
+statically linked into the kernel). Those options are:
+
+.. code-block:: none
+
+	gbuffers:	number of capture buffers, default is 2 (32 max)
+
+	gbufsize:	size of each capture buffer, default is 614400
+
+	video_nr:	video device to register (0 = /dev/video0, etc)
+
+Module use
+----------
+
+In order to automatically load the meye module on use, you can put those lines
+in your /etc/modprobe.d/meye.conf file:
+
+.. code-block:: none
+
+	alias char-major-81 videodev
+	alias char-major-81-0 meye
+	options meye gbuffers=32
+
+Usage:
+------
+
+.. code-block:: none
+
+	xawtv >= 3.49 (<http://bytesex.org/xawtv/>)
+		for display and uncompressed video capture:
+
+			xawtv -c /dev/video0 -geometry 640x480
+				or
+			xawtv -c /dev/video0 -geometry 320x240
+
+	motioneye (<http://popies.net/meye/>)
+		for getting ppm or jpg snapshots, mjpeg video
+
+Bugs / Todo
+-----------
+
+- 'motioneye' still uses the meye private v4l1 API extensions.
diff --git a/Documentation/admin-guide/media/omap3isp.rst b/Documentation/admin-guide/media/omap3isp.rst
new file mode 100644
index 000000000000..bc447bbec7ce
--- /dev/null
+++ b/Documentation/admin-guide/media/omap3isp.rst
@@ -0,0 +1,92 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: <isonum.txt>
+
+OMAP 3 Image Signal Processor (ISP) driver
+==========================================
+
+Copyright |copy| 2010 Nokia Corporation
+
+Copyright |copy| 2009 Texas Instruments, Inc.
+
+Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>,
+Sakari Ailus <sakari.ailus@iki.fi>, David Cohen <dacohen@gmail.com>
+
+
+Introduction
+------------
+
+This file documents the Texas Instruments OMAP 3 Image Signal Processor (ISP)
+driver located under drivers/media/platform/omap3isp. The original driver was
+written by Texas Instruments but since that it has been rewritten (twice) at
+Nokia.
+
+The driver has been successfully used on the following versions of OMAP 3:
+
+- 3430
+- 3530
+- 3630
+
+The driver implements V4L2, Media controller and v4l2_subdev interfaces.
+Sensor, lens and flash drivers using the v4l2_subdev interface in the kernel
+are supported.
+
+
+Split to subdevs
+----------------
+
+The OMAP 3 ISP is split into V4L2 subdevs, each of the blocks inside the ISP
+having one subdev to represent it. Each of the subdevs provide a V4L2 subdev
+interface to userspace.
+
+- OMAP3 ISP CCP2
+- OMAP3 ISP CSI2a
+- OMAP3 ISP CCDC
+- OMAP3 ISP preview
+- OMAP3 ISP resizer
+- OMAP3 ISP AEWB
+- OMAP3 ISP AF
+- OMAP3 ISP histogram
+
+Each possible link in the ISP is modelled by a link in the Media controller
+interface. For an example program see [#]_.
+
+
+Controlling the OMAP 3 ISP
+--------------------------
+
+In general, the settings given to the OMAP 3 ISP take effect at the beginning
+of the following frame. This is done when the module becomes idle during the
+vertical blanking period on the sensor. In memory-to-memory operation the pipe
+is run one frame at a time. Applying the settings is done between the frames.
+
+All the blocks in the ISP, excluding the CSI-2 and possibly the CCP2 receiver,
+insist on receiving complete frames. Sensors must thus never send the ISP
+partial frames.
+
+Autoidle does have issues with some ISP blocks on the 3430, at least.
+Autoidle is only enabled on 3630 when the omap3isp module parameter autoidle
+is non-zero.
+
+Technical reference manuals (TRMs) and other documentation
+----------------------------------------------------------
+
+OMAP 3430 TRM:
+<URL:http://focus.ti.com/pdfs/wtbu/OMAP34xx_ES3.1.x_PUBLIC_TRM_vZM.zip>
+Referenced 2011-03-05.
+
+OMAP 35xx TRM:
+<URL:http://www.ti.com/litv/pdf/spruf98o> Referenced 2011-03-05.
+
+OMAP 3630 TRM:
+<URL:http://focus.ti.com/pdfs/wtbu/OMAP36xx_ES1.x_PUBLIC_TRM_vQ.zip>
+Referenced 2011-03-05.
+
+DM 3730 TRM:
+<URL:http://www.ti.com/litv/pdf/sprugn4h> Referenced 2011-03-06.
+
+
+References
+----------
+
+.. [#] http://git.ideasonboard.org/?p=media-ctl.git;a=summary
diff --git a/Documentation/admin-guide/media/omap4_camera.rst b/Documentation/admin-guide/media/omap4_camera.rst
new file mode 100644
index 000000000000..24db4222d36d
--- /dev/null
+++ b/Documentation/admin-guide/media/omap4_camera.rst
@@ -0,0 +1,62 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+OMAP4 ISS Driver
+================
+
+Author: Sergio Aguirre <sergio.a.aguirre@gmail.com>
+
+Copyright (C) 2012, Texas Instruments
+
+Introduction
+------------
+
+The OMAP44XX family of chips contains the Imaging SubSystem (a.k.a. ISS),
+Which contains several components that can be categorized in 3 big groups:
+
+- Interfaces (2 Interfaces: CSI2-A & CSI2-B/CCP2)
+- ISP (Image Signal Processor)
+- SIMCOP (Still Image Coprocessor)
+
+For more information, please look in [#f1]_ for latest version of:
+"OMAP4430 Multimedia Device Silicon Revision 2.x"
+
+As of Revision AB, the ISS is described in detail in section 8.
+
+This driver is supporting **only** the CSI2-A/B interfaces for now.
+
+It makes use of the Media Controller framework [#f2]_, and inherited most of the
+code from OMAP3 ISP driver (found under drivers/media/platform/omap3isp/\*),
+except that it doesn't need an IOMMU now for ISS buffers memory mapping.
+
+Supports usage of MMAP buffers only (for now).
+
+Tested platforms
+----------------
+
+- OMAP4430SDP, w/ ES2.1 GP & SEVM4430-CAM-V1-0 (Contains IMX060 & OV5640, in
+  which only the last one is supported, outputting YUV422 frames).
+
+- TI Blaze MDP, w/ OMAP4430 ES2.2 EMU (Contains 1 IMX060 & 2 OV5650 sensors, in
+  which only the OV5650 are supported, outputting RAW10 frames).
+
+- PandaBoard, Rev. A2, w/ OMAP4430 ES2.1 GP & OV adapter board, tested with
+  following sensors:
+  * OV5640
+  * OV5650
+
+- Tested on mainline kernel:
+
+	http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=summary
+
+  Tag: v3.3 (commit c16fa4f2ad19908a47c63d8fa436a1178438c7e7)
+
+File list
+---------
+drivers/staging/media/omap4iss/
+include/linux/platform_data/media/omap4iss.h
+
+References
+----------
+
+.. [#f1] http://focus.ti.com/general/docs/wtbu/wtbudocumentcenter.tsp?navigationId=12037&templateId=6123#62
+.. [#f2] http://lwn.net/Articles/420485/
diff --git a/Documentation/admin-guide/media/opera-firmware.rst b/Documentation/admin-guide/media/opera-firmware.rst
new file mode 100644
index 000000000000..fab3581551de
--- /dev/null
+++ b/Documentation/admin-guide/media/opera-firmware.rst
@@ -0,0 +1,33 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Opera firmware
+==============
+
+Author: Marco Gittler <g.marco@freenet.de>
+
+To extract the firmware for the Opera DVB-S1 USB-Box
+you need to copy the files:
+
+2830SCap2.sys
+2830SLoad2.sys
+
+from the windriver disk into this directory.
+
+Then run:
+
+.. code-block:: none
+
+	scripts/get_dvb_firmware opera1
+
+and after that you have 2 files:
+
+dvb-usb-opera-01.fw
+dvb-usb-opera1-fpga-01.fw
+
+in here.
+
+Copy them into /lib/firmware/ .
+
+After that the driver can load the firmware
+(if you have enabled firmware loading
+in kernel config and have hotplug running).
diff --git a/Documentation/admin-guide/media/philips.rst b/Documentation/admin-guide/media/philips.rst
new file mode 100644
index 000000000000..e2840be10d08
--- /dev/null
+++ b/Documentation/admin-guide/media/philips.rst
@@ -0,0 +1,247 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Philips webcams (pwc driver)
+============================
+
+This file contains some additional information for the Philips and OEM webcams.
+E-mail: webcam@smcc.demon.nl                        Last updated: 2004-01-19
+Site: http://www.smcc.demon.nl/webcam/
+
+As of this moment, the following cameras are supported:
+
+ * Philips PCA645
+ * Philips PCA646
+ * Philips PCVC675
+ * Philips PCVC680
+ * Philips PCVC690
+ * Philips PCVC720/40
+ * Philips PCVC730
+ * Philips PCVC740
+ * Philips PCVC750
+ * Askey VC010
+ * Creative Labs Webcam 5
+ * Creative Labs Webcam Pro Ex
+ * Logitech QuickCam 3000 Pro
+ * Logitech QuickCam 4000 Pro
+ * Logitech QuickCam Notebook Pro
+ * Logitech QuickCam Zoom
+ * Logitech QuickCam Orbit
+ * Logitech QuickCam Sphere
+ * Samsung MPC-C10
+ * Samsung MPC-C30
+ * Sotec Afina Eye
+ * AME CU-001
+ * Visionite VCS-UM100
+ * Visionite VCS-UC300
+
+The main webpage for the Philips driver is at the address above. It contains
+a lot of extra information, a FAQ, and the binary plugin 'PWCX'. This plugin
+contains decompression routines that allow you to use higher image sizes and
+framerates; in addition the webcam uses less bandwidth on the USB bus (handy
+if you want to run more than 1 camera simultaneously). These routines fall
+under a NDA, and may therefore not be distributed as source; however, its use
+is completely optional.
+
+You can build this code either into your kernel, or as a module. I recommend
+the latter, since it makes troubleshooting a lot easier. The built-in
+microphone is supported through the USB Audio class.
+
+When you load the module you can set some default settings for the
+camera; some programs depend on a particular image-size or -format and
+don't know how to set it properly in the driver. The options are:
+
+size
+   Can be one of 'sqcif', 'qsif', 'qcif', 'sif', 'cif' or
+   'vga', for an image size of resp. 128x96, 160x120, 176x144,
+   320x240, 352x288 and 640x480 (of course, only for those cameras that
+   support these resolutions).
+
+fps
+   Specifies the desired framerate. Is an integer in the range of 4-30.
+
+fbufs
+   This parameter specifies the number of internal buffers to use for storing
+   frames from the cam. This will help if the process that reads images from
+   the cam is a bit slow or momentarily busy. However, on slow machines it
+   only introduces lag, so choose carefully. The default is 3, which is
+   reasonable. You can set it between 2 and 5.
+
+mbufs
+   This is an integer between 1 and 10. It will tell the module the number of
+   buffers to reserve for mmap(), VIDIOCCGMBUF, VIDIOCMCAPTURE and friends.
+   The default is 2, which is adequate for most applications (double
+   buffering).
+
+   Should you experience a lot of 'Dumping frame...' messages during
+   grabbing with a tool that uses mmap(), you might want to increase if.
+   However, it doesn't really buffer images, it just gives you a bit more
+   slack when your program is behind. But you need a multi-threaded or
+   forked program to really take advantage of these buffers.
+
+   The absolute maximum is 10, but don't set it too high!  Every buffer takes
+   up 460 KB of RAM, so unless you have a lot of memory setting this to
+   something more than 4 is an absolute waste.  This memory is only
+   allocated during open(), so nothing is wasted when the camera is not in
+   use.
+
+power_save
+   When power_save is enabled (set to 1), the module will try to shut down
+   the cam on close() and re-activate on open(). This will save power and
+   turn off the LED. Not all cameras support this though (the 645 and 646
+   don't have power saving at all), and some models don't work either (they
+   will shut down, but never wake up). Consider this experimental. By
+   default this option is disabled.
+
+compression (only useful with the plugin)
+   With this option you can control the compression factor that the camera
+   uses to squeeze the image through the USB bus. You can set the
+   parameter between 0 and 3::
+
+     0 = prefer uncompressed images; if the requested mode is not available
+	 in an uncompressed format, the driver will silently switch to low
+	 compression.
+     1 = low compression.
+     2 = medium compression.
+     3 = high compression.
+
+   High compression takes less bandwidth of course, but it could also
+   introduce some unwanted artefacts. The default is 2, medium compression.
+   See the FAQ on the website for an overview of which modes require
+   compression.
+
+   The compression parameter does not apply to the 645 and 646 cameras
+   and OEM models derived from those (only a few). Most cams honour this
+   parameter.
+
+leds
+   This settings takes 2 integers, that define the on/off time for the LED
+   (in milliseconds). One of the interesting things that you can do with
+   this is let the LED blink while the camera is in use. This::
+
+     leds=500,500
+
+   will blink the LED once every second. But with::
+
+     leds=0,0
+
+   the LED never goes on, making it suitable for silent surveillance.
+
+   By default the camera's LED is on solid while in use, and turned off
+   when the camera is not used anymore.
+
+   This parameter works only with the ToUCam range of cameras (720, 730, 740,
+   750) and OEMs. For other cameras this command is silently ignored, and
+   the LED cannot be controlled.
+
+   Finally: this parameters does not take effect UNTIL the first time you
+   open the camera device. Until then, the LED remains on.
+
+dev_hint
+   A long standing problem with USB devices is their dynamic nature: you
+   never know what device a camera gets assigned; it depends on module load
+   order, the hub configuration, the order in which devices are plugged in,
+   and the phase of the moon (i.e. it can be random). With this option you
+   can give the driver a hint as to what video device node (/dev/videoX) it
+   should use with a specific camera. This is also handy if you have two
+   cameras of the same model.
+
+   A camera is specified by its type (the number from the camera model,
+   like PCA645, PCVC750VC, etc) and optionally the serial number (visible
+   in /sys/kernel/debug/usb/devices). A hint consists of a string with the
+   following format::
+
+      [type[.serialnumber]:]node
+
+   The square brackets mean that both the type and the serialnumber are
+   optional, but a serialnumber cannot be specified without a type (which
+   would be rather pointless). The serialnumber is separated from the type
+   by a '.'; the node number by a ':'.
+
+   This somewhat cryptic syntax is best explained by a few examples::
+
+     dev_hint=3,5              The first detected cam gets assigned
+			       /dev/video3, the second /dev/video5. Any
+			       other cameras will get the first free
+			       available slot (see below).
+
+     dev_hint=645:1,680:2      The PCA645 camera will get /dev/video1,
+			       and a PCVC680 /dev/video2.
+
+     dev_hint=645.0123:3,645.4567:0	The PCA645 camera with serialnumber
+					0123 goes to /dev/video3, the same
+					camera model with the 4567 serial
+					gets /dev/video0.
+
+     dev_hint=750:1,4,5,6       The PCVC750 camera will get /dev/video1, the
+				next 3 Philips cams will use /dev/video4
+				through /dev/video6.
+
+   Some points worth knowing:
+
+   - Serialnumbers are case sensitive and must be written full, including
+     leading zeroes (it's treated as a string).
+   - If a device node is already occupied, registration will fail and
+     the webcam is not available.
+   - You can have up to 64 video devices; be sure to make enough device
+     nodes in /dev if you want to spread the numbers.
+     After /dev/video9 comes /dev/video10 (not /dev/videoA).
+   - If a camera does not match any dev_hint, it will simply get assigned
+     the first available device node, just as it used to be.
+
+trace
+   In order to better detect problems, it is now possible to turn on a
+   'trace' of some of the calls the module makes; it logs all items in your
+   kernel log at debug level.
+
+   The trace variable is a bitmask; each bit represents a certain feature.
+   If you want to trace something, look up the bit value(s) in the table
+   below, add the values together and supply that to the trace variable.
+
+   ====== ======= ================================================ =======
+   Value  Value   Description					   Default
+   (dec)  (hex)
+   ====== ======= ================================================ =======
+       1    0x1   Module initialization; this will log messages       On
+		  while loading and unloading the module
+
+       2    0x2   probe() and disconnect() traces                     On
+
+       4    0x4   Trace open() and close() calls                      Off
+
+       8    0x8   read(), mmap() and associated ioctl() calls         Off
+
+      16   0x10   Memory allocation of buffers, etc.                  Off
+
+      32   0x20   Showing underflow, overflow and Dumping frame       On
+		  messages
+
+      64   0x40   Show viewport and image sizes                       Off
+
+     128   0x80   PWCX debugging                                      Off
+   ====== ======= ================================================ =======
+
+   For example, to trace the open() & read() functions, sum 8 + 4 = 12,
+   so you would supply trace=12 during insmod or modprobe. If
+   you want to turn the initialization and probing tracing off, set trace=0.
+   The default value for trace is 35 (0x23).
+
+
+
+Example::
+
+     # modprobe pwc size=cif fps=15 power_save=1
+
+The fbufs, mbufs and trace parameters are global and apply to all connected
+cameras. Each camera has its own set of buffers.
+
+size and fps only specify defaults when you open() the device; this is to
+accommodate some tools that don't set the size. You can change these
+settings after open() with the Video4Linux ioctl() calls. The default of
+defaults is QCIF size at 10 fps.
+
+The compression parameter is semiglobal; it sets the initial compression
+preference for all camera's, but this parameter can be set per camera with
+the VIDIOCPWCSCQUAL ioctl() call.
+
+All parameters are optional.
+
diff --git a/Documentation/admin-guide/media/pulse8-cec.rst b/Documentation/admin-guide/media/pulse8-cec.rst
new file mode 100644
index 000000000000..356d08b519f3
--- /dev/null
+++ b/Documentation/admin-guide/media/pulse8-cec.rst
@@ -0,0 +1,13 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Pulse-Eight CEC Adapter driver
+==============================
+
+The pulse8-cec driver implements the following module option:
+
+``persistent_config``
+---------------------
+
+By default this is off, but when set to 1 the driver will store the current
+settings to the device's internal eeprom and restore it the next time the
+device is connected to the USB port.
diff --git a/Documentation/admin-guide/media/qcom_camss.rst b/Documentation/admin-guide/media/qcom_camss.rst
new file mode 100644
index 000000000000..a72e17d09cb7
--- /dev/null
+++ b/Documentation/admin-guide/media/qcom_camss.rst
@@ -0,0 +1,185 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: <isonum.txt>
+
+Qualcomm Camera Subsystem driver
+================================
+
+Introduction
+------------
+
+This file documents the Qualcomm Camera Subsystem driver located under
+drivers/media/platform/qcom/camss.
+
+The current version of the driver supports the Camera Subsystem found on
+Qualcomm MSM8916/APQ8016 and MSM8996/APQ8096 processors.
+
+The driver implements V4L2, Media controller and V4L2 subdev interfaces.
+Camera sensor using V4L2 subdev interface in the kernel is supported.
+
+The driver is implemented using as a reference the Qualcomm Camera Subsystem
+driver for Android as found in Code Aurora [#f1]_ [#f2]_.
+
+
+Qualcomm Camera Subsystem hardware
+----------------------------------
+
+The Camera Subsystem hardware found on 8x16 / 8x96 processors and supported by
+the driver consists of:
+
+- 2 / 3 CSIPHY modules. They handle the Physical layer of the CSI2 receivers.
+  A separate camera sensor can be connected to each of the CSIPHY module;
+- 2 / 4 CSID (CSI Decoder) modules. They handle the Protocol and Application
+  layer of the CSI2 receivers. A CSID can decode data stream from any of the
+  CSIPHY. Each CSID also contains a TG (Test Generator) block which can generate
+  artificial input data for test purposes;
+- ISPIF (ISP Interface) module. Handles the routing of the data streams from
+  the CSIDs to the inputs of the VFE;
+- 1 / 2 VFE (Video Front End) module(s). Contain a pipeline of image processing
+  hardware blocks. The VFE has different input interfaces. The PIX (Pixel) input
+  interface feeds the input data to the image processing pipeline. The image
+  processing pipeline contains also a scale and crop module at the end. Three
+  RDI (Raw Dump Interface) input interfaces bypass the image processing
+  pipeline. The VFE also contains the AXI bus interface which writes the output
+  data to memory.
+
+
+Supported functionality
+-----------------------
+
+The current version of the driver supports:
+
+- Input from camera sensor via CSIPHY;
+- Generation of test input data by the TG in CSID;
+- RDI interface of VFE
+
+  - Raw dump of the input data to memory.
+
+    Supported formats:
+
+    - YUYV/UYVY/YVYU/VYUY (packed YUV 4:2:2 - V4L2_PIX_FMT_YUYV /
+      V4L2_PIX_FMT_UYVY / V4L2_PIX_FMT_YVYU / V4L2_PIX_FMT_VYUY);
+    - MIPI RAW8 (8bit Bayer RAW - V4L2_PIX_FMT_SRGGB8 /
+      V4L2_PIX_FMT_SGRBG8 / V4L2_PIX_FMT_SGBRG8 / V4L2_PIX_FMT_SBGGR8);
+    - MIPI RAW10 (10bit packed Bayer RAW - V4L2_PIX_FMT_SBGGR10P /
+      V4L2_PIX_FMT_SGBRG10P / V4L2_PIX_FMT_SGRBG10P / V4L2_PIX_FMT_SRGGB10P /
+      V4L2_PIX_FMT_Y10P);
+    - MIPI RAW12 (12bit packed Bayer RAW - V4L2_PIX_FMT_SRGGB12P /
+      V4L2_PIX_FMT_SGBRG12P / V4L2_PIX_FMT_SGRBG12P / V4L2_PIX_FMT_SRGGB12P).
+    - (8x96 only) MIPI RAW14 (14bit packed Bayer RAW - V4L2_PIX_FMT_SRGGB14P /
+      V4L2_PIX_FMT_SGBRG14P / V4L2_PIX_FMT_SGRBG14P / V4L2_PIX_FMT_SRGGB14P).
+
+  - (8x96 only) Format conversion of the input data.
+
+    Supported input formats:
+
+    - MIPI RAW10 (10bit packed Bayer RAW - V4L2_PIX_FMT_SBGGR10P / V4L2_PIX_FMT_Y10P).
+
+    Supported output formats:
+
+    - Plain16 RAW10 (10bit unpacked Bayer RAW - V4L2_PIX_FMT_SBGGR10 / V4L2_PIX_FMT_Y10).
+
+- PIX interface of VFE
+
+  - Format conversion of the input data.
+
+    Supported input formats:
+
+    - YUYV/UYVY/YVYU/VYUY (packed YUV 4:2:2 - V4L2_PIX_FMT_YUYV /
+      V4L2_PIX_FMT_UYVY / V4L2_PIX_FMT_YVYU / V4L2_PIX_FMT_VYUY).
+
+    Supported output formats:
+
+    - NV12/NV21 (two plane YUV 4:2:0 - V4L2_PIX_FMT_NV12 / V4L2_PIX_FMT_NV21);
+    - NV16/NV61 (two plane YUV 4:2:2 - V4L2_PIX_FMT_NV16 / V4L2_PIX_FMT_NV61).
+    - (8x96 only) YUYV/UYVY/YVYU/VYUY (packed YUV 4:2:2 - V4L2_PIX_FMT_YUYV /
+      V4L2_PIX_FMT_UYVY / V4L2_PIX_FMT_YVYU / V4L2_PIX_FMT_VYUY).
+
+  - Scaling support. Configuration of the VFE Encoder Scale module
+    for downscalling with ratio up to 16x.
+
+  - Cropping support. Configuration of the VFE Encoder Crop module.
+
+- Concurrent and independent usage of two (8x96: three) data inputs -
+  could be camera sensors and/or TG.
+
+
+Driver Architecture and Design
+------------------------------
+
+The driver implements the V4L2 subdev interface. With the goal to model the
+hardware links between the modules and to expose a clean, logical and usable
+interface, the driver is split into V4L2 sub-devices as follows (8x16 / 8x96):
+
+- 2 / 3 CSIPHY sub-devices - each CSIPHY is represented by a single sub-device;
+- 2 / 4 CSID sub-devices - each CSID is represented by a single sub-device;
+- 2 / 4 ISPIF sub-devices - ISPIF is represented by a number of sub-devices
+  equal to the number of CSID sub-devices;
+- 4 / 8 VFE sub-devices - VFE is represented by a number of sub-devices equal to
+  the number of the input interfaces (3 RDI and 1 PIX for each VFE).
+
+The considerations to split the driver in this particular way are as follows:
+
+- representing CSIPHY and CSID modules by a separate sub-device for each module
+  allows to model the hardware links between these modules;
+- representing VFE by a separate sub-devices for each input interface allows
+  to use the input interfaces concurrently and independently as this is
+  supported by the hardware;
+- representing ISPIF by a number of sub-devices equal to the number of CSID
+  sub-devices allows to create linear media controller pipelines when using two
+  cameras simultaneously. This avoids branches in the pipelines which otherwise
+  will require a) userspace and b) media framework (e.g. power on/off
+  operations) to  make assumptions about the data flow from a sink pad to a
+  source pad on a single media entity.
+
+Each VFE sub-device is linked to a separate video device node.
+
+The media controller pipeline graph is as follows (with connected two / three
+OV5645 camera sensors):
+
+.. _qcom_camss_graph:
+
+.. kernel-figure:: qcom_camss_graph.dot
+    :alt:   qcom_camss_graph.dot
+    :align: center
+
+    Media pipeline graph 8x16
+
+.. kernel-figure:: qcom_camss_8x96_graph.dot
+    :alt:   qcom_camss_8x96_graph.dot
+    :align: center
+
+    Media pipeline graph 8x96
+
+
+Implementation
+--------------
+
+Runtime configuration of the hardware (updating settings while streaming) is
+not required to implement the currently supported functionality. The complete
+configuration on each hardware module is applied on STREAMON ioctl based on
+the current active media links, formats and controls set.
+
+The output size of the scaler module in the VFE is configured with the actual
+compose selection rectangle on the sink pad of the 'msm_vfe0_pix' entity.
+
+The crop output area of the crop module in the VFE is configured with the actual
+crop selection rectangle on the source pad of the 'msm_vfe0_pix' entity.
+
+
+Documentation
+-------------
+
+APQ8016 Specification:
+https://developer.qualcomm.com/download/sd410/snapdragon-410-processor-device-specification.pdf
+Referenced 2016-11-24.
+
+APQ8096 Specification:
+https://developer.qualcomm.com/download/sd820e/qualcomm-snapdragon-820e-processor-apq8096sge-device-specification.pdf
+Referenced 2018-06-22.
+
+References
+----------
+
+.. [#f1] https://source.codeaurora.org/quic/la/kernel/msm-3.10/
+.. [#f2] https://source.codeaurora.org/quic/la/kernel/msm-3.18/
diff --git a/Documentation/admin-guide/media/qcom_camss_8x96_graph.dot b/Documentation/admin-guide/media/qcom_camss_8x96_graph.dot
new file mode 100644
index 000000000000..7ed243b41b67
--- /dev/null
+++ b/Documentation/admin-guide/media/qcom_camss_8x96_graph.dot
@@ -0,0 +1,106 @@
+# SPDX-License-Identifier: GPL-2.0
+
+digraph board {
+	rankdir=TB
+	n00000001 [label="{{<port0> 0} | msm_csiphy0\n/dev/v4l-subdev0 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n00000001:port1 -> n0000000a:port0 [style=dashed]
+	n00000001:port1 -> n0000000d:port0 [style=dashed]
+	n00000001:port1 -> n00000010:port0 [style=dashed]
+	n00000001:port1 -> n00000013:port0 [style=dashed]
+	n00000004 [label="{{<port0> 0} | msm_csiphy1\n/dev/v4l-subdev1 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n00000004:port1 -> n0000000a:port0 [style=dashed]
+	n00000004:port1 -> n0000000d:port0 [style=dashed]
+	n00000004:port1 -> n00000010:port0 [style=dashed]
+	n00000004:port1 -> n00000013:port0 [style=dashed]
+	n00000007 [label="{{<port0> 0} | msm_csiphy2\n/dev/v4l-subdev2 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n00000007:port1 -> n0000000a:port0 [style=dashed]
+	n00000007:port1 -> n0000000d:port0 [style=dashed]
+	n00000007:port1 -> n00000010:port0 [style=dashed]
+	n00000007:port1 -> n00000013:port0 [style=dashed]
+	n0000000a [label="{{<port0> 0} | msm_csid0\n/dev/v4l-subdev3 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n0000000a:port1 -> n00000016:port0 [style=dashed]
+	n0000000a:port1 -> n00000019:port0 [style=dashed]
+	n0000000a:port1 -> n0000001c:port0 [style=dashed]
+	n0000000a:port1 -> n0000001f:port0 [style=dashed]
+	n0000000d [label="{{<port0> 0} | msm_csid1\n/dev/v4l-subdev4 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n0000000d:port1 -> n00000016:port0 [style=dashed]
+	n0000000d:port1 -> n00000019:port0 [style=dashed]
+	n0000000d:port1 -> n0000001c:port0 [style=dashed]
+	n0000000d:port1 -> n0000001f:port0 [style=dashed]
+	n00000010 [label="{{<port0> 0} | msm_csid2\n/dev/v4l-subdev5 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n00000010:port1 -> n00000016:port0 [style=dashed]
+	n00000010:port1 -> n00000019:port0 [style=dashed]
+	n00000010:port1 -> n0000001c:port0 [style=dashed]
+	n00000010:port1 -> n0000001f:port0 [style=dashed]
+	n00000013 [label="{{<port0> 0} | msm_csid3\n/dev/v4l-subdev6 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n00000013:port1 -> n00000016:port0 [style=dashed]
+	n00000013:port1 -> n00000019:port0 [style=dashed]
+	n00000013:port1 -> n0000001c:port0 [style=dashed]
+	n00000013:port1 -> n0000001f:port0 [style=dashed]
+	n00000016 [label="{{<port0> 0} | msm_ispif0\n/dev/v4l-subdev7 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n00000016:port1 -> n00000022:port0 [style=dashed]
+	n00000016:port1 -> n0000002b:port0 [style=dashed]
+	n00000016:port1 -> n00000034:port0 [style=dashed]
+	n00000016:port1 -> n0000003d:port0 [style=dashed]
+	n00000016:port1 -> n00000046:port0 [style=dashed]
+	n00000016:port1 -> n0000004f:port0 [style=dashed]
+	n00000016:port1 -> n00000058:port0 [style=dashed]
+	n00000016:port1 -> n00000061:port0 [style=dashed]
+	n00000019 [label="{{<port0> 0} | msm_ispif1\n/dev/v4l-subdev8 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n00000019:port1 -> n00000022:port0 [style=dashed]
+	n00000019:port1 -> n0000002b:port0 [style=dashed]
+	n00000019:port1 -> n00000034:port0 [style=dashed]
+	n00000019:port1 -> n0000003d:port0 [style=dashed]
+	n00000019:port1 -> n00000046:port0 [style=dashed]
+	n00000019:port1 -> n0000004f:port0 [style=dashed]
+	n00000019:port1 -> n00000058:port0 [style=dashed]
+	n00000019:port1 -> n00000061:port0 [style=dashed]
+	n0000001c [label="{{<port0> 0} | msm_ispif2\n/dev/v4l-subdev9 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n0000001c:port1 -> n00000022:port0 [style=dashed]
+	n0000001c:port1 -> n0000002b:port0 [style=dashed]
+	n0000001c:port1 -> n00000034:port0 [style=dashed]
+	n0000001c:port1 -> n0000003d:port0 [style=dashed]
+	n0000001c:port1 -> n00000046:port0 [style=dashed]
+	n0000001c:port1 -> n0000004f:port0 [style=dashed]
+	n0000001c:port1 -> n00000058:port0 [style=dashed]
+	n0000001c:port1 -> n00000061:port0 [style=dashed]
+	n0000001f [label="{{<port0> 0} | msm_ispif3\n/dev/v4l-subdev10 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n0000001f:port1 -> n00000022:port0 [style=dashed]
+	n0000001f:port1 -> n0000002b:port0 [style=dashed]
+	n0000001f:port1 -> n00000034:port0 [style=dashed]
+	n0000001f:port1 -> n0000003d:port0 [style=dashed]
+	n0000001f:port1 -> n00000046:port0 [style=dashed]
+	n0000001f:port1 -> n0000004f:port0 [style=dashed]
+	n0000001f:port1 -> n00000058:port0 [style=dashed]
+	n0000001f:port1 -> n00000061:port0 [style=dashed]
+	n00000022 [label="{{<port0> 0} | msm_vfe0_rdi0\n/dev/v4l-subdev11 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n00000022:port1 -> n00000025 [style=bold]
+	n00000025 [label="msm_vfe0_video0\n/dev/video0", shape=box, style=filled, fillcolor=yellow]
+	n0000002b [label="{{<port0> 0} | msm_vfe0_rdi1\n/dev/v4l-subdev12 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n0000002b:port1 -> n0000002e [style=bold]
+	n0000002e [label="msm_vfe0_video1\n/dev/video1", shape=box, style=filled, fillcolor=yellow]
+	n00000034 [label="{{<port0> 0} | msm_vfe0_rdi2\n/dev/v4l-subdev13 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n00000034:port1 -> n00000037 [style=bold]
+	n00000037 [label="msm_vfe0_video2\n/dev/video2", shape=box, style=filled, fillcolor=yellow]
+	n0000003d [label="{{<port0> 0} | msm_vfe0_pix\n/dev/v4l-subdev14 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n0000003d:port1 -> n00000040 [style=bold]
+	n00000040 [label="msm_vfe0_video3\n/dev/video3", shape=box, style=filled, fillcolor=yellow]
+	n00000046 [label="{{<port0> 0} | msm_vfe1_rdi0\n/dev/v4l-subdev15 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n00000046:port1 -> n00000049 [style=bold]
+	n00000049 [label="msm_vfe1_video0\n/dev/video4", shape=box, style=filled, fillcolor=yellow]
+	n0000004f [label="{{<port0> 0} | msm_vfe1_rdi1\n/dev/v4l-subdev16 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n0000004f:port1 -> n00000052 [style=bold]
+	n00000052 [label="msm_vfe1_video1\n/dev/video5", shape=box, style=filled, fillcolor=yellow]
+	n00000058 [label="{{<port0> 0} | msm_vfe1_rdi2\n/dev/v4l-subdev17 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n00000058:port1 -> n0000005b [style=bold]
+	n0000005b [label="msm_vfe1_video2\n/dev/video6", shape=box, style=filled, fillcolor=yellow]
+	n00000061 [label="{{<port0> 0} | msm_vfe1_pix\n/dev/v4l-subdev18 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n00000061:port1 -> n00000064 [style=bold]
+	n00000064 [label="msm_vfe1_video3\n/dev/video7", shape=box, style=filled, fillcolor=yellow]
+	n000000e2 [label="{{} | ov5645 3-0039\n/dev/v4l-subdev19 | {<port0> 0}}", shape=Mrecord, style=filled, fillcolor=green]
+	n000000e2:port0 -> n00000004:port0 [style=bold]
+	n000000e4 [label="{{} | ov5645 3-003a\n/dev/v4l-subdev20 | {<port0> 0}}", shape=Mrecord, style=filled, fillcolor=green]
+	n000000e4:port0 -> n00000007:port0 [style=bold]
+	n000000e6 [label="{{} | ov5645 3-003b\n/dev/v4l-subdev21 | {<port0> 0}}", shape=Mrecord, style=filled, fillcolor=green]
+	n000000e6:port0 -> n00000001:port0 [style=bold]
+}
diff --git a/Documentation/admin-guide/media/qcom_camss_graph.dot b/Documentation/admin-guide/media/qcom_camss_graph.dot
new file mode 100644
index 000000000000..ef7dca92fd0b
--- /dev/null
+++ b/Documentation/admin-guide/media/qcom_camss_graph.dot
@@ -0,0 +1,43 @@
+# SPDX-License-Identifier: GPL-2.0
+
+digraph board {
+	rankdir=TB
+	n00000001 [label="{{<port0> 0} | msm_csiphy0\n/dev/v4l-subdev0 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n00000001:port1 -> n00000007:port0 [style=dashed]
+	n00000001:port1 -> n0000000a:port0 [style=dashed]
+	n00000004 [label="{{<port0> 0} | msm_csiphy1\n/dev/v4l-subdev1 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n00000004:port1 -> n00000007:port0 [style=dashed]
+	n00000004:port1 -> n0000000a:port0 [style=dashed]
+	n00000007 [label="{{<port0> 0} | msm_csid0\n/dev/v4l-subdev2 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n00000007:port1 -> n0000000d:port0 [style=dashed]
+	n00000007:port1 -> n00000010:port0 [style=dashed]
+	n0000000a [label="{{<port0> 0} | msm_csid1\n/dev/v4l-subdev3 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n0000000a:port1 -> n0000000d:port0 [style=dashed]
+	n0000000a:port1 -> n00000010:port0 [style=dashed]
+	n0000000d [label="{{<port0> 0} | msm_ispif0\n/dev/v4l-subdev4 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n0000000d:port1 -> n00000013:port0 [style=dashed]
+	n0000000d:port1 -> n0000001c:port0 [style=dashed]
+	n0000000d:port1 -> n00000025:port0 [style=dashed]
+	n0000000d:port1 -> n0000002e:port0 [style=dashed]
+	n00000010 [label="{{<port0> 0} | msm_ispif1\n/dev/v4l-subdev5 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n00000010:port1 -> n00000013:port0 [style=dashed]
+	n00000010:port1 -> n0000001c:port0 [style=dashed]
+	n00000010:port1 -> n00000025:port0 [style=dashed]
+	n00000010:port1 -> n0000002e:port0 [style=dashed]
+	n00000013 [label="{{<port0> 0} | msm_vfe0_rdi0\n/dev/v4l-subdev6 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n00000013:port1 -> n00000016 [style=bold]
+	n00000016 [label="msm_vfe0_video0\n/dev/video0", shape=box, style=filled, fillcolor=yellow]
+	n0000001c [label="{{<port0> 0} | msm_vfe0_rdi1\n/dev/v4l-subdev7 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n0000001c:port1 -> n0000001f [style=bold]
+	n0000001f [label="msm_vfe0_video1\n/dev/video1", shape=box, style=filled, fillcolor=yellow]
+	n00000025 [label="{{<port0> 0} | msm_vfe0_rdi2\n/dev/v4l-subdev8 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n00000025:port1 -> n00000028 [style=bold]
+	n00000028 [label="msm_vfe0_video2\n/dev/video2", shape=box, style=filled, fillcolor=yellow]
+	n0000002e [label="{{<port0> 0} | msm_vfe0_pix\n/dev/v4l-subdev9 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n0000002e:port1 -> n00000031 [style=bold]
+	n00000031 [label="msm_vfe0_video3\n/dev/video3", shape=box, style=filled, fillcolor=yellow]
+	n00000057 [label="{{} | ov5645 1-0076\n/dev/v4l-subdev10 | {<port0> 0}}", shape=Mrecord, style=filled, fillcolor=green]
+	n00000057:port0 -> n00000001:port0 [style=bold]
+	n00000059 [label="{{} | ov5645 1-0074\n/dev/v4l-subdev11 | {<port0> 0}}", shape=Mrecord, style=filled, fillcolor=green]
+	n00000059:port0 -> n00000004:port0 [style=bold]
+}
diff --git a/Documentation/admin-guide/media/rcar-fdp1.rst b/Documentation/admin-guide/media/rcar-fdp1.rst
new file mode 100644
index 000000000000..88b0edcf9046
--- /dev/null
+++ b/Documentation/admin-guide/media/rcar-fdp1.rst
@@ -0,0 +1,39 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Renesas R-Car Fine Display Processor (FDP1) Driver
+==================================================
+
+The R-Car FDP1 driver implements driver-specific controls as follows.
+
+``V4L2_CID_DEINTERLACING_MODE (menu)``
+    The video deinterlacing mode (such as Bob, Weave, ...). The R-Car FDP1
+    driver implements the following modes.
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 4
+
+    * - ``"Progressive" (0)``
+      - The input image video stream is progressive (not interlaced). No
+        deinterlacing is performed. Apart from (optional) format and encoding
+        conversion output frames are identical to the input frames.
+    * - ``"Adaptive 2D/3D" (1)``
+      - Motion adaptive version of 2D and 3D deinterlacing. Use 3D deinterlacing
+        in the presence of fast motion and 2D deinterlacing with diagonal
+        interpolation otherwise.
+    * - ``"Fixed 2D" (2)``
+      - The current field is scaled vertically by averaging adjacent lines to
+        recover missing lines. This method is also known as blending or Line
+        Averaging (LAV).
+    * - ``"Fixed 3D" (3)``
+      - The previous and next fields are averaged to recover lines missing from
+        the current field. This method is also known as Field Averaging (FAV).
+    * - ``"Previous field" (4)``
+      - The current field is weaved with the previous field, i.e. the previous
+        field is used to fill missing lines from the current field. This method
+        is also known as weave deinterlacing.
+    * - ``"Next field" (5)``
+      - The current field is weaved with the next field, i.e. the next field is
+        used to fill missing lines from the current field. This method is also
+        known as weave deinterlacing.
diff --git a/Documentation/admin-guide/media/saa7134-cardlist.rst b/Documentation/admin-guide/media/saa7134-cardlist.rst
new file mode 100644
index 000000000000..afb0e2fb52b0
--- /dev/null
+++ b/Documentation/admin-guide/media/saa7134-cardlist.rst
@@ -0,0 +1,803 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+SAA7134 cards list
+==================
+
+.. tabularcolumns:: |p{1.4cm}|p{11.1cm}|p{4.2cm}|
+
+.. flat-table::
+   :header-rows: 1
+   :widths: 2 19 18
+   :stub-columns: 0
+
+   * - Card number
+     - Card name
+     - PCI IDs
+
+   * - 0
+     - UNKNOWN/GENERIC
+     -
+
+   * - 1
+     - Proteus Pro [philips reference design]
+     - 1131:2001, 1131:2001
+
+   * - 2
+     - LifeView FlyVIDEO3000
+     - 5168:0138, 4e42:0138
+
+   * - 3
+     - LifeView/Typhoon FlyVIDEO2000
+     - 5168:0138, 4e42:0138
+
+   * - 4
+     - EMPRESS
+     - 1131:6752
+
+   * - 5
+     - SKNet Monster TV
+     - 1131:4e85
+
+   * - 6
+     - Tevion MD 9717
+     -
+
+   * - 7
+     - KNC One TV-Station RDS / Typhoon TV Tuner RDS
+     - 1131:fe01, 1894:fe01
+
+   * - 8
+     - Terratec Cinergy 400 TV
+     - 153b:1142
+
+   * - 9
+     - Medion 5044
+     -
+
+   * - 10
+     - Kworld/KuroutoShikou SAA7130-TVPCI
+     -
+
+   * - 11
+     - Terratec Cinergy 600 TV
+     - 153b:1143
+
+   * - 12
+     - Medion 7134
+     - 16be:0003, 16be:5000
+
+   * - 13
+     - Typhoon TV+Radio 90031
+     -
+
+   * - 14
+     - ELSA EX-VISION 300TV
+     - 1048:226b
+
+   * - 15
+     - ELSA EX-VISION 500TV
+     - 1048:226a
+
+   * - 16
+     - ASUS TV-FM 7134
+     - 1043:4842, 1043:4830, 1043:4840
+
+   * - 17
+     - AOPEN VA1000 POWER
+     - 1131:7133
+
+   * - 18
+     - BMK MPEX No Tuner
+     -
+
+   * - 19
+     - Compro VideoMate TV
+     - 185b:c100
+
+   * - 20
+     - Matrox CronosPlus
+     - 102B:48d0
+
+   * - 21
+     - 10MOONS PCI TV CAPTURE CARD
+     - 1131:2001
+
+   * - 22
+     - AverMedia M156 / Medion 2819
+     - 1461:a70b
+
+   * - 23
+     - BMK MPEX Tuner
+     -
+
+   * - 24
+     - KNC One TV-Station DVR
+     - 1894:a006
+
+   * - 25
+     - ASUS TV-FM 7133
+     - 1043:4843
+
+   * - 26
+     - Pinnacle PCTV Stereo (saa7134)
+     - 11bd:002b
+
+   * - 27
+     - Manli MuchTV M-TV002
+     -
+
+   * - 28
+     - Manli MuchTV M-TV001
+     -
+
+   * - 29
+     - Nagase Sangyo TransGear 3000TV
+     - 1461:050c
+
+   * - 30
+     - Elitegroup ECS TVP3XP FM1216 Tuner Card(PAL-BG,FM)
+     - 1019:4cb4
+
+   * - 31
+     - Elitegroup ECS TVP3XP FM1236 Tuner Card (NTSC,FM)
+     - 1019:4cb5
+
+   * - 32
+     - AVACS SmartTV
+     -
+
+   * - 33
+     - AVerMedia DVD EZMaker
+     - 1461:10ff
+
+   * - 34
+     - Noval Prime TV 7133
+     -
+
+   * - 35
+     - AverMedia AverTV Studio 305
+     - 1461:2115
+
+   * - 36
+     - UPMOST PURPLE TV
+     - 12ab:0800
+
+   * - 37
+     - Items MuchTV Plus / IT-005
+     -
+
+   * - 38
+     - Terratec Cinergy 200 TV
+     - 153b:1152
+
+   * - 39
+     - LifeView FlyTV Platinum Mini
+     - 5168:0212, 4e42:0212, 5169:1502
+
+   * - 40
+     - Compro VideoMate TV PVR/FM
+     - 185b:c100
+
+   * - 41
+     - Compro VideoMate TV Gold+
+     - 185b:c100
+
+   * - 42
+     - Sabrent SBT-TVFM (saa7130)
+     -
+
+   * - 43
+     - :Zolid Xpert TV7134
+     -
+
+   * - 44
+     - Empire PCI TV-Radio LE
+     -
+
+   * - 45
+     - Avermedia AVerTV Studio 307
+     - 1461:9715
+
+   * - 46
+     - AVerMedia Cardbus TV/Radio (E500)
+     - 1461:d6ee
+
+   * - 47
+     - Terratec Cinergy 400 mobile
+     - 153b:1162
+
+   * - 48
+     - Terratec Cinergy 600 TV MK3
+     - 153b:1158
+
+   * - 49
+     - Compro VideoMate Gold+ Pal
+     - 185b:c200
+
+   * - 50
+     - Pinnacle PCTV 300i DVB-T + PAL
+     - 11bd:002d
+
+   * - 51
+     - ProVideo PV952
+     - 1540:9524
+
+   * - 52
+     - AverMedia AverTV/305
+     - 1461:2108
+
+   * - 53
+     - ASUS TV-FM 7135
+     - 1043:4845
+
+   * - 54
+     - LifeView FlyTV Platinum FM / Gold
+     - 5168:0214, 5168:5214, 1489:0214, 5168:0304
+
+   * - 55
+     - LifeView FlyDVB-T DUO / MSI TV@nywhere Duo
+     - 5168:0306, 4E42:0306
+
+   * - 56
+     - Avermedia AVerTV 307
+     - 1461:a70a
+
+   * - 57
+     - Avermedia AVerTV GO 007 FM
+     - 1461:f31f
+
+   * - 58
+     - ADS Tech Instant TV (saa7135)
+     - 1421:0350, 1421:0351, 1421:0370, 1421:1370
+
+   * - 59
+     - Kworld/Tevion V-Stream Xpert TV PVR7134
+     -
+
+   * - 60
+     - LifeView/Typhoon/Genius FlyDVB-T Duo Cardbus
+     - 5168:0502, 4e42:0502, 1489:0502
+
+   * - 61
+     - Philips TOUGH DVB-T reference design
+     - 1131:2004
+
+   * - 62
+     - Compro VideoMate TV Gold+II
+     -
+
+   * - 63
+     - Kworld Xpert TV PVR7134
+     -
+
+   * - 64
+     - FlyTV mini Asus Digimatrix
+     - 1043:0210
+
+   * - 65
+     - V-Stream Studio TV Terminator
+     -
+
+   * - 66
+     - Yuan TUN-900 (saa7135)
+     -
+
+   * - 67
+     - Beholder BeholdTV 409 FM
+     - 0000:4091
+
+   * - 68
+     - GoTView 7135 PCI
+     - 5456:7135
+
+   * - 69
+     - Philips EUROPA V3 reference design
+     - 1131:2004
+
+   * - 70
+     - Compro Videomate DVB-T300
+     - 185b:c900
+
+   * - 71
+     - Compro Videomate DVB-T200
+     - 185b:c901
+
+   * - 72
+     - RTD Embedded Technologies VFG7350
+     - 1435:7350
+
+   * - 73
+     - RTD Embedded Technologies VFG7330
+     - 1435:7330
+
+   * - 74
+     - LifeView FlyTV Platinum Mini2
+     - 14c0:1212
+
+   * - 75
+     - AVerMedia AVerTVHD MCE A180
+     - 1461:1044
+
+   * - 76
+     - SKNet MonsterTV Mobile
+     - 1131:4ee9
+
+   * - 77
+     - Pinnacle PCTV 40i/50i/110i (saa7133)
+     - 11bd:002e
+
+   * - 78
+     - ASUSTeK P7131 Dual
+     - 1043:4862
+
+   * - 79
+     - Sedna/MuchTV PC TV Cardbus TV/Radio (ITO25 Rev:2B)
+     -
+
+   * - 80
+     - ASUS Digimatrix TV
+     - 1043:0210
+
+   * - 81
+     - Philips Tiger reference design
+     - 1131:2018
+
+   * - 82
+     - MSI TV@Anywhere plus
+     - 1462:6231, 1462:8624
+
+   * - 83
+     - Terratec Cinergy 250 PCI TV
+     - 153b:1160
+
+   * - 84
+     - LifeView FlyDVB Trio
+     - 5168:0319
+
+   * - 85
+     - AverTV DVB-T 777
+     - 1461:2c05, 1461:2c05
+
+   * - 86
+     - LifeView FlyDVB-T / Genius VideoWonder DVB-T
+     - 5168:0301, 1489:0301
+
+   * - 87
+     - ADS Instant TV Duo Cardbus PTV331
+     - 0331:1421
+
+   * - 88
+     - Tevion/KWorld DVB-T 220RF
+     - 17de:7201
+
+   * - 89
+     - ELSA EX-VISION 700TV
+     - 1048:226c
+
+   * - 90
+     - Kworld ATSC110/115
+     - 17de:7350, 17de:7352
+
+   * - 91
+     - AVerMedia A169 B
+     - 1461:7360
+
+   * - 92
+     - AVerMedia A169 B1
+     - 1461:6360
+
+   * - 93
+     - Medion 7134 Bridge #2
+     - 16be:0005
+
+   * - 94
+     - LifeView FlyDVB-T Hybrid Cardbus/MSI TV @nywhere A/D NB
+     - 5168:3306, 5168:3502, 5168:3307, 4e42:3502
+
+   * - 95
+     - LifeView FlyVIDEO3000 (NTSC)
+     - 5169:0138
+
+   * - 96
+     - Medion Md8800 Quadro
+     - 16be:0007, 16be:0008, 16be:000d
+
+   * - 97
+     - LifeView FlyDVB-S /Acorp TV134DS
+     - 5168:0300, 4e42:0300
+
+   * - 98
+     - Proteus Pro 2309
+     - 0919:2003
+
+   * - 99
+     - AVerMedia TV Hybrid A16AR
+     - 1461:2c00
+
+   * - 100
+     - Asus Europa2 OEM
+     - 1043:4860
+
+   * - 101
+     - Pinnacle PCTV 310i
+     - 11bd:002f
+
+   * - 102
+     - Avermedia AVerTV Studio 507
+     - 1461:9715
+
+   * - 103
+     - Compro Videomate DVB-T200A
+     -
+
+   * - 104
+     - Hauppauge WinTV-HVR1110 DVB-T/Hybrid
+     - 0070:6700, 0070:6701, 0070:6702, 0070:6703, 0070:6704, 0070:6705
+
+   * - 105
+     - Terratec Cinergy HT PCMCIA
+     - 153b:1172
+
+   * - 106
+     - Encore ENLTV
+     - 1131:2342, 1131:2341, 3016:2344
+
+   * - 107
+     - Encore ENLTV-FM
+     - 1131:230f
+
+   * - 108
+     - Terratec Cinergy HT PCI
+     - 153b:1175
+
+   * - 109
+     - Philips Tiger - S Reference design
+     -
+
+   * - 110
+     - Avermedia M102
+     - 1461:f31e
+
+   * - 111
+     - ASUS P7131 4871
+     - 1043:4871
+
+   * - 112
+     - ASUSTeK P7131 Hybrid
+     - 1043:4876
+
+   * - 113
+     - Elitegroup ECS TVP3XP FM1246 Tuner Card (PAL,FM)
+     - 1019:4cb6
+
+   * - 114
+     - KWorld DVB-T 210
+     - 17de:7250
+
+   * - 115
+     - Sabrent PCMCIA TV-PCB05
+     - 0919:2003
+
+   * - 116
+     - 10MOONS TM300 TV Card
+     - 1131:2304
+
+   * - 117
+     - Avermedia Super 007
+     - 1461:f01d
+
+   * - 118
+     - Beholder BeholdTV 401
+     - 0000:4016
+
+   * - 119
+     - Beholder BeholdTV 403
+     - 0000:4036
+
+   * - 120
+     - Beholder BeholdTV 403 FM
+     - 0000:4037
+
+   * - 121
+     - Beholder BeholdTV 405
+     - 0000:4050
+
+   * - 122
+     - Beholder BeholdTV 405 FM
+     - 0000:4051
+
+   * - 123
+     - Beholder BeholdTV 407
+     - 0000:4070
+
+   * - 124
+     - Beholder BeholdTV 407 FM
+     - 0000:4071
+
+   * - 125
+     - Beholder BeholdTV 409
+     - 0000:4090
+
+   * - 126
+     - Beholder BeholdTV 505 FM
+     - 5ace:5050
+
+   * - 127
+     - Beholder BeholdTV 507 FM / BeholdTV 509 FM
+     - 5ace:5070, 5ace:5090
+
+   * - 128
+     - Beholder BeholdTV Columbus TV/FM
+     - 0000:5201
+
+   * - 129
+     - Beholder BeholdTV 607 FM
+     - 5ace:6070
+
+   * - 130
+     - Beholder BeholdTV M6
+     - 5ace:6190
+
+   * - 131
+     - Twinhan Hybrid DTV-DVB 3056 PCI
+     - 1822:0022
+
+   * - 132
+     - Genius TVGO AM11MCE
+     -
+
+   * - 133
+     - NXP Snake DVB-S reference design
+     -
+
+   * - 134
+     - Medion/Creatix CTX953 Hybrid
+     - 16be:0010
+
+   * - 135
+     - MSI TV@nywhere A/D v1.1
+     - 1462:8625
+
+   * - 136
+     - AVerMedia Cardbus TV/Radio (E506R)
+     - 1461:f436
+
+   * - 137
+     - AVerMedia Hybrid TV/Radio (A16D)
+     - 1461:f936
+
+   * - 138
+     - Avermedia M115
+     - 1461:a836
+
+   * - 139
+     - Compro VideoMate T750
+     - 185b:c900
+
+   * - 140
+     - Avermedia DVB-S Pro A700
+     - 1461:a7a1
+
+   * - 141
+     - Avermedia DVB-S Hybrid+FM A700
+     - 1461:a7a2
+
+   * - 142
+     - Beholder BeholdTV H6
+     - 5ace:6290
+
+   * - 143
+     - Beholder BeholdTV M63
+     - 5ace:6191
+
+   * - 144
+     - Beholder BeholdTV M6 Extra
+     - 5ace:6193
+
+   * - 145
+     - AVerMedia MiniPCI DVB-T Hybrid M103
+     - 1461:f636, 1461:f736
+
+   * - 146
+     - ASUSTeK P7131 Analog
+     -
+
+   * - 147
+     - Asus Tiger 3in1
+     - 1043:4878
+
+   * - 148
+     - Encore ENLTV-FM v5.3
+     - 1a7f:2008
+
+   * - 149
+     - Avermedia PCI pure analog (M135A)
+     - 1461:f11d
+
+   * - 150
+     - Zogis Real Angel 220
+     -
+
+   * - 151
+     - ADS Tech Instant HDTV
+     - 1421:0380
+
+   * - 152
+     - Asus Tiger Rev:1.00
+     - 1043:4857
+
+   * - 153
+     - Kworld Plus TV Analog Lite PCI
+     - 17de:7128
+
+   * - 154
+     - Avermedia AVerTV GO 007 FM Plus
+     - 1461:f31d
+
+   * - 155
+     - Hauppauge WinTV-HVR1150 ATSC/QAM-Hybrid
+     - 0070:6706, 0070:6708
+
+   * - 156
+     - Hauppauge WinTV-HVR1120 DVB-T/Hybrid
+     - 0070:6707, 0070:6709, 0070:670a
+
+   * - 157
+     - Avermedia AVerTV Studio 507UA
+     - 1461:a11b
+
+   * - 158
+     - AVerMedia Cardbus TV/Radio (E501R)
+     - 1461:b7e9
+
+   * - 159
+     - Beholder BeholdTV 505 RDS
+     - 0000:505B
+
+   * - 160
+     - Beholder BeholdTV 507 RDS
+     - 0000:5071
+
+   * - 161
+     - Beholder BeholdTV 507 RDS
+     - 0000:507B
+
+   * - 162
+     - Beholder BeholdTV 607 FM
+     - 5ace:6071
+
+   * - 163
+     - Beholder BeholdTV 609 FM
+     - 5ace:6090
+
+   * - 164
+     - Beholder BeholdTV 609 FM
+     - 5ace:6091
+
+   * - 165
+     - Beholder BeholdTV 607 RDS
+     - 5ace:6072
+
+   * - 166
+     - Beholder BeholdTV 607 RDS
+     - 5ace:6073
+
+   * - 167
+     - Beholder BeholdTV 609 RDS
+     - 5ace:6092
+
+   * - 168
+     - Beholder BeholdTV 609 RDS
+     - 5ace:6093
+
+   * - 169
+     - Compro VideoMate S350/S300
+     - 185b:c900
+
+   * - 170
+     - AverMedia AverTV Studio 505
+     - 1461:a115
+
+   * - 171
+     - Beholder BeholdTV X7
+     - 5ace:7595
+
+   * - 172
+     - RoverMedia TV Link Pro FM
+     - 19d1:0138
+
+   * - 173
+     - Zolid Hybrid TV Tuner PCI
+     - 1131:2004
+
+   * - 174
+     - Asus Europa Hybrid OEM
+     - 1043:4847
+
+   * - 175
+     - Leadtek Winfast DTV1000S
+     - 107d:6655
+
+   * - 176
+     - Beholder BeholdTV 505 RDS
+     - 0000:5051
+
+   * - 177
+     - Hawell HW-404M7
+     -
+
+   * - 178
+     - Beholder BeholdTV H7
+     - 5ace:7190
+
+   * - 179
+     - Beholder BeholdTV A7
+     - 5ace:7090
+
+   * - 180
+     - Avermedia PCI M733A
+     - 1461:4155, 1461:4255
+
+   * - 181
+     - TechoTrend TT-budget T-3000
+     - 13c2:2804
+
+   * - 182
+     - Kworld PCI SBTVD/ISDB-T Full-Seg Hybrid
+     - 17de:b136
+
+   * - 183
+     - Compro VideoMate Vista M1F
+     - 185b:c900
+
+   * - 184
+     - Encore ENLTV-FM 3
+     - 1a7f:2108
+
+   * - 185
+     - MagicPro ProHDTV Pro2 DMB-TH/Hybrid
+     - 17de:d136
+
+   * - 186
+     - Beholder BeholdTV 501
+     - 5ace:5010
+
+   * - 187
+     - Beholder BeholdTV 503 FM
+     - 5ace:5030
+
+   * - 188
+     - Sensoray 811/911
+     - 6000:0811, 6000:0911
+
+   * - 189
+     - Kworld PC150-U
+     - 17de:a134
+
+   * - 190
+     - Asus My Cinema PS3-100
+     - 1043:48cd
+
+   * - 191
+     - Hawell HW-9004V1
+     -
+
+   * - 192
+     - AverMedia AverTV Satellite Hybrid+FM A706
+     - 1461:2055
+
+   * - 193
+     - WIS Voyager or compatible
+     - 1905:7007
+
+   * - 194
+     - AverMedia AverTV/505
+     - 1461:a10a
+
+   * - 195
+     - Leadtek Winfast TV2100 FM
+     - 107d:6f3a
+
+   * - 196
+     - SnaZio* TVPVR PRO
+     - 1779:13cf
diff --git a/Documentation/admin-guide/media/saa7134.rst b/Documentation/admin-guide/media/saa7134.rst
new file mode 100644
index 000000000000..7ab9c70b9abe
--- /dev/null
+++ b/Documentation/admin-guide/media/saa7134.rst
@@ -0,0 +1,88 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+The saa7134 driver
+==================
+
+Author Gerd Hoffmann
+
+
+This is a v4l2/oss device driver for saa7130/33/34/35 based capture / TV
+boards.
+
+
+Status
+------
+
+Almost everything is working.  video, sound, tuner, radio, mpeg ts, ...
+
+As with bttv, card-specific tweaks are needed.  Check CARDLIST for a
+list of known TV cards and saa7134-cards.c for the drivers card
+configuration info.
+
+
+Build
+-----
+
+Once you pick up a Kernel source, you should configure, build,
+install and boot the new kernel.  You'll need at least
+these config options::
+
+    ./scripts/config -e PCI
+    ./scripts/config -e INPUT
+    ./scripts/config -m I2C
+    ./scripts/config -m MEDIA_SUPPORT
+    ./scripts/config -e MEDIA_PCI_SUPPORT
+    ./scripts/config -e MEDIA_ANALOG_TV_SUPPORT
+    ./scripts/config -e MEDIA_DIGITAL_TV_SUPPORT
+    ./scripts/config -e MEDIA_RADIO_SUPPORT
+    ./scripts/config -e RC_CORE
+    ./scripts/config -e MEDIA_SUBDRV_AUTOSELECT
+    ./scripts/config -m VIDEO_SAA7134
+    ./scripts/config -e SAA7134_ALSA
+    ./scripts/config -e VIDEO_SAA7134_RC
+    ./scripts/config -e VIDEO_SAA7134_DVB
+    ./scripts/config -e VIDEO_SAA7134_GO7007
+
+To build and install, you should run::
+
+    make && make modules_install && make install
+
+Once the new Kernel is booted, saa7134 driver should be loaded automatically.
+
+Depending on the card you might have to pass ``card=<nr>`` as insmod option.
+If so, please check :doc:`saa7134-cardlist` for valid choices.
+
+Once you have your card type number, you can pass a modules configuration
+via a file (usually, it is either ``/etc/modules.conf`` or some file at
+``/etc/modules-load.d/``, but the actual place depends on your
+distribution), with this content::
+
+    options saa7134 card=13 # Assuming that your card type is #13
+
+
+Changes / Fixes
+---------------
+
+Please mail to linux-media AT vger.kernel.org unified diffs against
+the linux media git tree:
+
+    https://git.linuxtv.org/media_tree.git/
+
+This is done by committing a patch at a clone of the git tree and
+submitting the patch using ``git send-email``. Don't forget to
+describe at the lots  what it changes / which problem it fixes / whatever
+it is good for ...
+
+
+Known Problems
+--------------
+
+* The tuner for the flyvideos isn't detected automatically and the
+  default might not work for you depending on which version you have.
+  There is a ``tuner=`` insmod option to override the driver's default.
+
+Credits
+-------
+
+andrew.stevens@philips.com + werner.leeb@philips.com for providing
+saa7134 hardware specs and sample board.
diff --git a/Documentation/admin-guide/media/saa7164-cardlist.rst b/Documentation/admin-guide/media/saa7164-cardlist.rst
new file mode 100644
index 000000000000..e8f36e084537
--- /dev/null
+++ b/Documentation/admin-guide/media/saa7164-cardlist.rst
@@ -0,0 +1,71 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+SAA7164 cards list
+==================
+
+.. tabularcolumns:: |p{1.4cm}|p{11.1cm}|p{4.2cm}|
+
+.. flat-table::
+   :header-rows: 1
+   :widths: 2 19 18
+   :stub-columns: 0
+
+   * - Card number
+     - Card name
+     - PCI IDs
+
+   * - 0
+     - Unknown
+     -
+
+   * - 1
+     - Generic Rev2
+     -
+
+   * - 2
+     - Generic Rev3
+     -
+
+   * - 3
+     - Hauppauge WinTV-HVR2250
+     - 0070:8880, 0070:8810
+
+   * - 4
+     - Hauppauge WinTV-HVR2200
+     - 0070:8980
+
+   * - 5
+     - Hauppauge WinTV-HVR2200
+     - 0070:8900
+
+   * - 6
+     - Hauppauge WinTV-HVR2200
+     - 0070:8901
+
+   * - 7
+     - Hauppauge WinTV-HVR2250
+     - 0070:8891, 0070:8851
+
+   * - 8
+     - Hauppauge WinTV-HVR2250
+     - 0070:88A1
+
+   * - 9
+     - Hauppauge WinTV-HVR2200
+     - 0070:8940
+
+   * - 10
+     - Hauppauge WinTV-HVR2200
+     - 0070:8953
+
+   * - 11
+     - Hauppauge WinTV-HVR2255(proto)
+     - 0070:f111
+
+   * - 12
+     - Hauppauge WinTV-HVR2255
+     - 0070:f111
+
+   * - 13
+     - Hauppauge WinTV-HVR2205
+     - 0070:f123, 0070:f120
diff --git a/Documentation/admin-guide/media/si470x.rst b/Documentation/admin-guide/media/si470x.rst
new file mode 100644
index 000000000000..d53bf5f95200
--- /dev/null
+++ b/Documentation/admin-guide/media/si470x.rst
@@ -0,0 +1,167 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: <isonum.txt>
+
+The Silicon Labs Si470x FM Radio Receivers driver
+=================================================
+
+Copyright |copy| 2009 Tobias Lorenz <tobias.lorenz@gmx.net>
+
+
+Information from Silicon Labs
+-----------------------------
+
+Silicon Laboratories is the manufacturer of the radio ICs, that nowadays are the
+most often used radio receivers in cell phones. Usually they are connected with
+I2C. But SiLabs also provides a reference design, which integrates this IC,
+together with a small microcontroller C8051F321, to form a USB radio.
+Part of this reference design is also a radio application in binary and source
+code. The software also contains an automatic firmware upgrade to the most
+current version. Information on these can be downloaded here:
+http://www.silabs.com/usbradio
+
+
+Supported ICs
+-------------
+
+The following ICs have a very similar register set, so that they are or will be
+supported somewhen by the driver:
+
+- Si4700: FM radio receiver
+- Si4701: FM radio receiver, RDS Support
+- Si4702: FM radio receiver
+- Si4703: FM radio receiver, RDS Support
+- Si4704: FM radio receiver, no external antenna required
+- Si4705: FM radio receiver, no external antenna required, RDS support, Dig I/O
+- Si4706: Enhanced FM RDS/TMC radio receiver, no external antenna required, RDS
+	  Support
+- Si4707: Dedicated weather band radio receiver with SAME decoder, RDS Support
+- Si4708: Smallest FM receivers
+- Si4709: Smallest FM receivers, RDS Support
+
+More information on these can be downloaded here:
+http://www.silabs.com/products/mcu/Pages/USBFMRadioRD.aspx
+
+
+Supported USB devices
+---------------------
+
+Currently the following USB radios (vendor:product) with the Silicon Labs si470x
+chips are known to work:
+
+- 10c4:818a: Silicon Labs USB FM Radio Reference Design
+- 06e1:a155: ADS/Tech FM Radio Receiver (formerly Instant FM Music) (RDX-155-EF)
+- 1b80:d700: KWorld USB FM Radio SnapMusic Mobile 700 (FM700)
+- 10c5:819a: Sanei Electric, Inc. FM USB Radio (sold as DealExtreme.com PCear)
+
+
+Software
+--------
+
+Testing is usually done with most application under Debian/testing:
+
+- fmtools - Utility for managing FM tuner cards
+- gnomeradio - FM-radio tuner for the GNOME desktop
+- gradio - GTK FM radio tuner
+- kradio - Comfortable Radio Application for KDE
+- radio - ncurses-based radio application
+- mplayer - The Ultimate Movie Player For Linux
+- v4l2-ctl - Collection of command line video4linux utilities
+
+For example, you can use:
+
+.. code-block:: none
+
+	v4l2-ctl -d /dev/radio0 --set-ctrl=volume=10,mute=0 --set-freq=95.21 --all
+
+There is also a library libv4l, which can be used. It's going to have a function
+for frequency seeking, either by using hardware functionality as in radio-si470x
+or by implementing a function as we currently have in every of the mentioned
+programs. Somewhen the radio programs should make use of libv4l.
+
+For processing RDS information, there is a project ongoing at:
+http://rdsd.berlios.de/
+
+There is currently no project for making TMC sentences human readable.
+
+
+Audio Listing
+-------------
+
+USB Audio is provided by the ALSA snd_usb_audio module. It is recommended to
+also select SND_USB_AUDIO, as this is required to get sound from the radio. For
+listing you have to redirect the sound, for example using one of the following
+commands. Please adjust the audio devices to your needs (/dev/dsp* and hw:x,x).
+
+If you just want to test audio (very poor quality):
+
+.. code-block:: none
+
+	cat /dev/dsp1 > /dev/dsp
+
+If you use sox + OSS try:
+
+.. code-block:: none
+
+	sox -2 --endian little -r 96000 -t oss /dev/dsp1 -t oss /dev/dsp
+
+or using sox + alsa:
+
+.. code-block:: none
+
+	sox --endian little -c 2 -S -r 96000 -t alsa hw:1 -t alsa -r 96000 hw:0
+
+If you use arts try:
+
+.. code-block:: none
+
+	arecord -D hw:1,0 -r96000 -c2 -f S16_LE | artsdsp aplay -B -
+
+If you use mplayer try:
+
+.. code-block:: none
+
+	mplayer -radio adevice=hw=1.0:arate=96000 \
+		-rawaudio rate=96000 \
+		radio://<frequency>/capture
+
+Module Parameters
+-----------------
+
+After loading the module, you still have access to some of them in the sysfs
+mount under /sys/module/radio_si470x/parameters. The contents of read-only files
+(0444) are not updated, even if space, band and de are changed using private
+video controls. The others are runtime changeable.
+
+
+Errors
+------
+
+Increase tune_timeout, if you often get -EIO errors.
+
+When timed out or band limit is reached, hw_freq_seek returns -EAGAIN.
+
+If you get any errors from snd_usb_audio, please report them to the ALSA people.
+
+
+Open Issues
+-----------
+
+V4L minor device allocation and parameter setting is not perfect. A solution is
+currently under discussion.
+
+There is an USB interface for downloading/uploading new firmware images. Support
+for it can be implemented using the request_firmware interface.
+
+There is a RDS interrupt mode. The driver is already using the same interface
+for polling RDS information, but is currently not using the interrupt mode.
+
+There is a LED interface, which can be used to override the LED control
+programmed in the firmware. This can be made available using the LED support
+functions in the kernel.
+
+
+Other useful information and links
+----------------------------------
+
+http://www.silabs.com/usbradio
diff --git a/Documentation/admin-guide/media/si4713.rst b/Documentation/admin-guide/media/si4713.rst
new file mode 100644
index 000000000000..be8e6b49b7b4
--- /dev/null
+++ b/Documentation/admin-guide/media/si4713.rst
@@ -0,0 +1,192 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: <isonum.txt>
+
+The Silicon Labs Si4713 FM Radio Transmitter Driver
+===================================================
+
+Copyright |copy| 2009 Nokia Corporation
+
+Contact: Eduardo Valentin <eduardo.valentin@nokia.com>
+
+
+Information about the Device
+----------------------------
+
+This chip is a Silicon Labs product. It is a I2C device, currently on 0x63 address.
+Basically, it has transmission and signal noise level measurement features.
+
+The Si4713 integrates transmit functions for FM broadcast stereo transmission.
+The chip also allows integrated receive power scanning to identify low signal
+power FM channels.
+
+The chip is programmed using commands and responses. There are also several
+properties which can change the behavior of this chip.
+
+Users must comply with local regulations on radio frequency (RF) transmission.
+
+Device driver description
+-------------------------
+
+There are two modules to handle this device. One is a I2C device driver
+and the other is a platform driver.
+
+The I2C device driver exports a v4l2-subdev interface to the kernel.
+All properties can also be accessed by v4l2 extended controls interface, by
+using the v4l2-subdev calls (g_ext_ctrls, s_ext_ctrls).
+
+The platform device driver exports a v4l2 radio device interface to user land.
+So, it uses the I2C device driver as a sub device in order to send the user
+commands to the actual device. Basically it is a wrapper to the I2C device driver.
+
+Applications can use v4l2 radio API to specify frequency of operation, mute state,
+etc. But mostly of its properties will be present in the extended controls.
+
+When the v4l2 mute property is set to 1 (true), the driver will turn the chip off.
+
+Properties description
+----------------------
+
+The properties can be accessed using v4l2 extended controls.
+Here is an output from v4l2-ctl util:
+
+.. code-block:: none
+
+	/ # v4l2-ctl -d /dev/radio0 --all -L
+	Driver Info:
+		Driver name   : radio-si4713
+		Card type     : Silicon Labs Si4713 Modulator
+		Bus info      :
+		Driver version: 0
+		Capabilities  : 0x00080800
+			RDS Output
+			Modulator
+	Audio output: 0 (FM Modulator Audio Out)
+	Frequency: 1408000 (88.000000 MHz)
+	Video Standard = 0x00000000
+	Modulator:
+		Name                 : FM Modulator
+		Capabilities         : 62.5 Hz stereo rds
+		Frequency range      : 76.0 MHz - 108.0 MHz
+		Subchannel modulation: stereo+rds
+
+	User Controls
+
+				mute (bool) : default=1 value=0
+
+	FM Radio Modulator Controls
+
+		rds_signal_deviation (int)  : min=0 max=90000 step=10 default=200 value=200 flags=slider
+			rds_program_id (int)  : min=0 max=65535 step=1 default=0 value=0
+		rds_program_type (int)  : min=0 max=31 step=1 default=0 value=0
+			rds_ps_name (str)  : min=0 max=96 step=8 value='si4713  '
+			rds_radio_text (str)  : min=0 max=384 step=32 value=''
+	audio_limiter_feature_enabled (bool) : default=1 value=1
+	audio_limiter_release_time (int)  : min=250 max=102390 step=50 default=5010 value=5010 flags=slider
+		audio_limiter_deviation (int)  : min=0 max=90000 step=10 default=66250 value=66250 flags=slider
+	audio_compression_feature_enabl (bool) : default=1 value=1
+		audio_compression_gain (int)  : min=0 max=20 step=1 default=15 value=15 flags=slider
+	audio_compression_threshold (int)  : min=-40 max=0 step=1 default=-40 value=-40 flags=slider
+	audio_compression_attack_time (int)  : min=0 max=5000 step=500 default=0 value=0 flags=slider
+	audio_compression_release_time (int)  : min=100000 max=1000000 step=100000 default=1000000 value=1000000 flags=slider
+	pilot_tone_feature_enabled (bool) : default=1 value=1
+		pilot_tone_deviation (int)  : min=0 max=90000 step=10 default=6750 value=6750 flags=slider
+		pilot_tone_frequency (int)  : min=0 max=19000 step=1 default=19000 value=19000 flags=slider
+		pre_emphasis_settings (menu) : min=0 max=2 default=1 value=1
+		tune_power_level (int)  : min=0 max=120 step=1 default=88 value=88 flags=slider
+		tune_antenna_capacitor (int)  : min=0 max=191 step=1 default=0 value=110 flags=slider
+
+Here is a summary of them:
+
+* Pilot is an audible tone sent by the device.
+
+- pilot_frequency - Configures the frequency of the stereo pilot tone.
+- pilot_deviation - Configures pilot tone frequency deviation level.
+- pilot_enabled - Enables or disables the pilot tone feature.
+
+* The si4713 device is capable of applying audio compression to the
+  transmitted signal.
+
+- acomp_enabled - Enables or disables the audio dynamic range control feature.
+- acomp_gain - Sets the gain for audio dynamic range control.
+- acomp_threshold - Sets the threshold level for audio dynamic range control.
+- acomp_attack_time - Sets the attack time for audio dynamic range control.
+- acomp_release_time - Sets the release time for audio dynamic range control.
+
+* Limiter setups audio deviation limiter feature. Once a over deviation occurs,
+  it is possible to adjust the front-end gain of the audio input and always
+  prevent over deviation.
+
+- limiter_enabled - Enables or disables the limiter feature.
+- limiter_deviation - Configures audio frequency deviation level.
+- limiter_release_time - Sets the limiter release time.
+
+* Tuning power
+
+- power_level - Sets the output power level for signal transmission.
+  antenna_capacitor - This selects the value of antenna tuning capacitor
+  manually or automatically if set to zero.
+
+* RDS related
+
+- rds_ps_name - Sets the RDS ps name field for transmission.
+- rds_radio_text - Sets the RDS radio text for transmission.
+- rds_pi - Sets the RDS PI field for transmission.
+- rds_pty - Sets the RDS PTY field for transmission.
+
+* Region related
+
+- preemphasis - sets the preemphasis to be applied for transmission.
+
+RNL
+---
+
+This device also has an interface to measure received noise level. To do that, you should
+ioctl the device node. Here is an code of example:
+
+.. code-block:: none
+
+	int main (int argc, char *argv[])
+	{
+		struct si4713_rnl rnl;
+		int fd = open("/dev/radio0", O_RDWR);
+		int rval;
+
+		if (argc < 2)
+			return -EINVAL;
+
+		if (fd < 0)
+			return fd;
+
+		sscanf(argv[1], "%d", &rnl.frequency);
+
+		rval = ioctl(fd, SI4713_IOC_MEASURE_RNL, &rnl);
+		if (rval < 0)
+			return rval;
+
+		printf("received noise level: %d\n", rnl.rnl);
+
+		close(fd);
+	}
+
+The struct si4713_rnl and SI4713_IOC_MEASURE_RNL are defined under
+include/linux/platform_data/media/si4713.h.
+
+Stereo/Mono and RDS subchannels
+-------------------------------
+
+The device can also be configured using the available sub channels for
+transmission. To do that use S/G_MODULATOR ioctl and configure txsubchans properly.
+Refer to the V4L2 API specification for proper use of this ioctl.
+
+Testing
+-------
+Testing is usually done with v4l2-ctl utility for managing FM tuner cards.
+The tool can be found in v4l-dvb repository under v4l2-apps/util directory.
+
+Example for setting rds ps name:
+
+.. code-block:: none
+
+	# v4l2-ctl -d /dev/radio0 --set-ctrl=rds_ps_name="Dummy"
+
diff --git a/Documentation/admin-guide/media/si476x.rst b/Documentation/admin-guide/media/si476x.rst
new file mode 100644
index 000000000000..87062301d6a1
--- /dev/null
+++ b/Documentation/admin-guide/media/si476x.rst
@@ -0,0 +1,160 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: <isonum.txt>
+
+
+The SI476x Driver
+=================
+
+Copyright |copy| 2013 Andrey Smirnov <andrew.smirnov@gmail.com>
+
+TODO for the driver
+-------------------
+
+- According to the SiLabs' datasheet it is possible to update the
+  firmware of the radio chip in the run-time, thus bringing it to the
+  most recent version. Unfortunately I couldn't find any mentioning of
+  the said firmware update for the old chips that I tested the driver
+  against, so for chips like that the driver only exposes the old
+  functionality.
+
+
+Parameters exposed over debugfs
+-------------------------------
+SI476x allow user to get multiple characteristics that can be very
+useful for EoL testing/RF performance estimation, parameters that have
+very little to do with V4L2 subsystem. Such parameters are exposed via
+debugfs and can be accessed via regular file I/O operations.
+
+The drivers exposes following files:
+
+* /sys/kernel/debug/<device-name>/acf
+  This file contains ACF(Automatically Controlled Features) status
+  information. The contents of the file is binary data of the
+  following layout:
+
+  .. tabularcolumns:: |p{7ex}|p{12ex}|L|
+
+  =============  ==============   ====================================
+  Offset	 Name		  Description
+  =============  ==============   ====================================
+  0x00		 blend_int	  Flag, set when stereo separation has
+				  crossed below the blend threshold
+  0x01		 hblend_int	  Flag, set when HiBlend cutoff
+				  frequency is lower than threshold
+  0x02		 hicut_int	  Flag, set when HiCut cutoff
+				  frequency is lower than threshold
+  0x03		 chbw_int	  Flag, set when channel filter
+				  bandwidth is less than threshold
+  0x04		 softmute_int	  Flag indicating that softmute
+				  attenuation has increased above
+				  softmute threshold
+  0x05		 smute		  0 - Audio is not soft muted
+				  1 - Audio is soft muted
+  0x06		 smattn		  Soft mute attenuation level in dB
+  0x07		 chbw		  Channel filter bandwidth in kHz
+  0x08		 hicut		  HiCut cutoff frequency in units of
+				  100Hz
+  0x09		 hiblend	  HiBlend cutoff frequency in units
+				  of 100 Hz
+  0x10		 pilot		  0 - Stereo pilot is not present
+				  1 - Stereo pilot is present
+  0x11		 stblend	  Stereo blend in %
+  =============  ==============   ====================================
+
+
+* /sys/kernel/debug/<device-name>/rds_blckcnt
+  This file contains statistics about RDS receptions. It's binary data
+  has the following layout:
+
+  .. tabularcolumns:: |p{7ex}|p{12ex}|L|
+
+  =============  ==============   ====================================
+  Offset	 Name		  Description
+  =============  ==============   ====================================
+  0x00		 expected	  Number of expected RDS blocks
+  0x02		 received	  Number of received RDS blocks
+  0x04		 uncorrectable	  Number of uncorrectable RDS blocks
+  =============  ==============   ====================================
+
+* /sys/kernel/debug/<device-name>/agc
+  This file contains information about parameters pertaining to
+  AGC(Automatic Gain Control)
+
+  The layout is:
+
+  .. tabularcolumns:: |p{7ex}|p{12ex}|L|
+
+  =============  ==============   ====================================
+  Offset	 Name		  Description
+  =============  ==============   ====================================
+  0x00		 mxhi		  0 - FM Mixer PD high threshold is
+				  not tripped
+				  1 - FM Mixer PD high threshold is
+				  tripped
+  0x01		 mxlo		  ditto for FM Mixer PD low
+  0x02		 lnahi		  ditto for FM LNA PD high
+  0x03		 lnalo		  ditto for FM LNA PD low
+  0x04		 fmagc1		  FMAGC1 attenuator resistance
+				  (see datasheet for more detail)
+  0x05		 fmagc2		  ditto for FMAGC2
+  0x06		 pgagain	  PGA gain in dB
+  0x07		 fmwblang	  FM/WB LNA Gain in dB
+  =============  ==============   ====================================
+
+* /sys/kernel/debug/<device-name>/rsq
+  This file contains information about parameters pertaining to
+  RSQ(Received Signal Quality)
+
+  The layout is:
+
+  .. tabularcolumns:: |p{7ex}|p{12ex}|p{60ex}|
+
+  =============  ==============   ====================================
+  Offset	 Name		  Description
+  =============  ==============   ====================================
+  0x00		 multhint	  0 - multipath value has not crossed
+				  the Multipath high threshold
+				  1 - multipath value has crossed
+				  the Multipath high threshold
+  0x01		 multlint	  ditto for Multipath low threshold
+  0x02		 snrhint	  0 - received signal's SNR has not
+				  crossed high threshold
+				  1 - received signal's SNR has
+				  crossed high threshold
+  0x03		 snrlint	  ditto for low threshold
+  0x04		 rssihint	  ditto for RSSI high threshold
+  0x05		 rssilint	  ditto for RSSI low threshold
+  0x06		 bltf		  Flag indicating if seek command
+				  reached/wrapped seek band limit
+  0x07		 snr_ready	  Indicates that SNR metrics is ready
+  0x08		 rssiready	  ditto for RSSI metrics
+  0x09		 injside	  0 - Low-side injection is being used
+				  1 - High-side injection is used
+  0x10		 afcrl		  Flag indicating if AFC rails
+  0x11		 valid		  Flag indicating if channel is valid
+  0x12		 readfreq	  Current tuned frequency
+  0x14		 freqoff	  Signed frequency offset in units of
+				  2ppm
+  0x15		 rssi		  Signed value of RSSI in dBuV
+  0x16		 snr		  Signed RF SNR in dB
+  0x17		 issi		  Signed Image Strength Signal
+				  indicator
+  0x18		 lassi		  Signed Low side adjacent Channel
+				  Strength indicator
+  0x19		 hassi		  ditto fpr High side
+  0x20		 mult		  Multipath indicator
+  0x21		 dev		  Frequency deviation
+  0x24		 assi		  Adjacent channel SSI
+  0x25		 usn		  Ultrasonic noise indicator
+  0x26		 pilotdev	  Pilot deviation in units of 100 Hz
+  0x27		 rdsdev		  ditto for RDS
+  0x28		 assidev	  ditto for ASSI
+  0x29		 strongdev	  Frequency deviation
+  0x30		 rdspi		  RDS PI code
+  =============  ==============   ====================================
+
+* /sys/kernel/debug/<device-name>/rsq_primary
+  This file contains information about parameters pertaining to
+  RSQ(Received Signal Quality) for primary tuner only. Layout is as
+  the one above.
diff --git a/Documentation/admin-guide/media/technisat.rst b/Documentation/admin-guide/media/technisat.rst
new file mode 100644
index 000000000000..9eaa12366bbf
--- /dev/null
+++ b/Documentation/admin-guide/media/technisat.rst
@@ -0,0 +1,100 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+How to set up the Technisat/B2C2 Flexcop devices
+================================================
+
+.. note::
+
+   This documentation is outdated.
+
+Author: Uwe Bugla <uwe.bugla@gmx.de> August 2009
+
+Find out what device you have
+-----------------------------
+
+Important Notice: The driver does NOT support Technisat USB 2 devices!
+
+First start your linux box with a shipped kernel:
+
+.. code-block:: none
+
+	lspci -vvv for a PCI device (lsusb -vvv for an USB device) will show you for example:
+	02:0b.0 Network controller: Techsan Electronics Co Ltd B2C2 FlexCopII DVB chip /
+	Technisat SkyStar2 DVB card (rev 02)
+
+	dmesg | grep frontend may show you for example:
+	DVB: registering frontend 0 (Conexant CX24123/CX24109)...
+
+Kernel compilation:
+-------------------
+
+If the Flexcop / Technisat is the only DVB / TV / Radio device in your box
+get rid of unnecessary modules and check this one:
+
+``Multimedia support`` => ``Customise analog and hybrid tuner modules to build``
+
+In this directory uncheck every driver which is activated there
+(except ``Simple tuner support`` for ATSC 3rd generation only -> see case 9 please).
+
+Then please activate:
+
+- Main module part:
+
+  ``Multimedia support`` => ``DVB/ATSC adapters`` => ``Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters``
+
+  #) => ``Technisat/B2C2 Air/Sky/Cable2PC PCI`` (PCI card) or
+  #) => ``Technisat/B2C2 Air/Sky/Cable2PC USB`` (USB 1.1 adapter)
+     and for troubleshooting purposes:
+  #) => ``Enable debug for the B2C2 FlexCop drivers``
+
+- Frontend / Tuner / Demodulator module part:
+
+  ``Multimedia support`` => ``DVB/ATSC adapters``
+   => ``Customise the frontend modules to build`` ``Customise DVB frontends`` =>
+
+  - SkyStar DVB-S Revision 2.3:
+
+    #) => ``Zarlink VP310/MT312/ZL10313 based``
+    #) => ``Generic I2C PLL based tuners``
+
+  - SkyStar DVB-S Revision 2.6:
+
+    #) => ``ST STV0299 based``
+    #) => ``Generic I2C PLL based tuners``
+
+  - SkyStar DVB-S Revision 2.7:
+
+    #) => ``Samsung S5H1420 based``
+    #) => ``Integrant ITD1000 Zero IF tuner for DVB-S/DSS``
+    #) => ``ISL6421 SEC controller``
+
+  - SkyStar DVB-S Revision 2.8:
+
+    #) => ``Conexant CX24123 based``
+    #) => ``Conexant CX24113/CX24128 tuner for DVB-S/DSS``
+    #) => ``ISL6421 SEC controller``
+
+  - AirStar DVB-T card:
+
+    #) => ``Zarlink MT352 based``
+    #) => ``Generic I2C PLL based tuners``
+
+  - CableStar DVB-C card:
+
+    #) => ``ST STV0297 based``
+    #) => ``Generic I2C PLL based tuners``
+
+  - AirStar ATSC card 1st generation:
+
+    #) => ``Broadcom BCM3510``
+
+  - AirStar ATSC card 2nd generation:
+
+    #) => ``NxtWave Communications NXT2002/NXT2004 based``
+    #) => ``Generic I2C PLL based tuners``
+
+  - AirStar ATSC card 3rd generation:
+
+    #) => ``LG Electronics LGDT3302/LGDT3303 based``
+    #) ``Multimedia support`` => ``Customise analog and hybrid tuner modules to build`` => ``Simple tuner support``
+
diff --git a/Documentation/admin-guide/media/tm6000-cardlist.rst b/Documentation/admin-guide/media/tm6000-cardlist.rst
new file mode 100644
index 000000000000..6d2769c0f4d8
--- /dev/null
+++ b/Documentation/admin-guide/media/tm6000-cardlist.rst
@@ -0,0 +1,83 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+TM6000 cards list
+=================
+
+.. tabularcolumns:: |p{1.4cm}|p{11.1cm}|p{4.2cm}|
+
+.. flat-table::
+   :header-rows: 1
+   :widths: 2 19 18
+   :stub-columns: 0
+
+   * - Card number
+     - Card name
+     - USB IDs
+
+   * - 0
+     - Unknown tm6000 video grabber
+     -
+
+   * - 1
+     - Generic tm5600 board
+     - 6000:0001
+
+   * - 2
+     - Generic tm6000 board
+     -
+
+   * - 3
+     - Generic tm6010 board
+     - 6000:0002
+
+   * - 4
+     - 10Moons UT 821
+     -
+
+   * - 5
+     - 10Moons UT 330
+     -
+
+   * - 6
+     - ADSTECH Dual TV USB
+     - 06e1:f332
+
+   * - 7
+     - Freecom Hybrid Stick / Moka DVB-T Receiver Dual
+     - 14aa:0620
+
+   * - 8
+     - ADSTECH Mini Dual TV USB
+     - 06e1:b339
+
+   * - 9
+     - Hauppauge WinTV HVR-900H / WinTV USB2-Stick
+     - 2040:6600, 2040:6601, 2040:6610, 2040:6611
+
+   * - 10
+     - Beholder Wander DVB-T/TV/FM USB2.0
+     - 6000:dec0
+
+   * - 11
+     - Beholder Voyager TV/FM USB2.0
+     - 6000:dec1
+
+   * - 12
+     - Terratec Cinergy Hybrid XE / Cinergy Hybrid-Stick
+     - 0ccd:0086, 0ccd:00A5
+
+   * - 13
+     - Twinhan TU501(704D1)
+     - 13d3:3240, 13d3:3241, 13d3:3243, 13d3:3264
+
+   * - 14
+     - Beholder Wander Lite DVB-T/TV/FM USB2.0
+     - 6000:dec2
+
+   * - 15
+     - Beholder Voyager Lite TV/FM USB2.0
+     - 6000:dec3
+
+   * - 16
+     - Terratec Grabster AV 150/250 MX
+     - 0ccd:0079
diff --git a/Documentation/admin-guide/media/ttusb-dec.rst b/Documentation/admin-guide/media/ttusb-dec.rst
new file mode 100644
index 000000000000..516bbab8a872
--- /dev/null
+++ b/Documentation/admin-guide/media/ttusb-dec.rst
@@ -0,0 +1,45 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+TechnoTrend/Hauppauge DEC USB Driver
+====================================
+
+Driver Status
+-------------
+
+Supported:
+
+	- DEC2000-t
+	- DEC2450-t
+	- DEC3000-s
+	- Video Streaming
+	- Audio Streaming
+	- Section Filters
+	- Channel Zapping
+	- Hotplug firmware loader
+
+To Do:
+
+	- Tuner status information
+	- DVB network interface
+	- Streaming video PC->DEC
+	- Conax support for 2450-t
+
+Getting the Firmware
+--------------------
+To download the firmware, use the following commands:
+
+.. code-block:: none
+
+	scripts/get_dvb_firmware dec2000t
+	scripts/get_dvb_firmware dec2540t
+	scripts/get_dvb_firmware dec3000s
+
+
+Hotplug Firmware Loading
+------------------------
+
+Since 2.6 kernels, the firmware is loaded at the point that the driver module
+is loaded.
+
+Copy the three files downloaded above into the /usr/lib/hotplug/firmware or
+/lib/firmware directory (depending on configuration of firmware hotplug).
diff --git a/Documentation/admin-guide/media/tuner-cardlist.rst b/Documentation/admin-guide/media/tuner-cardlist.rst
new file mode 100644
index 000000000000..362617c59c5d
--- /dev/null
+++ b/Documentation/admin-guide/media/tuner-cardlist.rst
@@ -0,0 +1,100 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Tuner cards list
+================
+
+============ =====================================================
+Tuner number Card name
+============ =====================================================
+0            Temic PAL (4002 FH5)
+1            Philips PAL_I (FI1246 and compatibles)
+2            Philips NTSC (FI1236,FM1236 and compatibles)
+3            Philips (SECAM+PAL_BG) (FI1216MF, FM1216MF, FR1216MF)
+4            NoTuner
+5            Philips PAL_BG (FI1216 and compatibles)
+6            Temic NTSC (4032 FY5)
+7            Temic PAL_I (4062 FY5)
+8            Temic NTSC (4036 FY5)
+9            Alps HSBH1
+10           Alps TSBE1
+11           Alps TSBB5
+12           Alps TSBE5
+13           Alps TSBC5
+14           Temic PAL_BG (4006FH5)
+15           Alps TSCH6
+16           Temic PAL_DK (4016 FY5)
+17           Philips NTSC_M (MK2)
+18           Temic PAL_I (4066 FY5)
+19           Temic PAL* auto (4006 FN5)
+20           Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)
+21           Temic NTSC (4039 FR5)
+22           Temic PAL/SECAM multi (4046 FM5)
+23           Philips PAL_DK (FI1256 and compatibles)
+24           Philips PAL/SECAM multi (FQ1216ME)
+25           LG PAL_I+FM (TAPC-I001D)
+26           LG PAL_I (TAPC-I701D)
+27           LG NTSC+FM (TPI8NSR01F)
+28           LG PAL_BG+FM (TPI8PSB01D)
+29           LG PAL_BG (TPI8PSB11D)
+30           Temic PAL* auto + FM (4009 FN5)
+31           SHARP NTSC_JP (2U5JF5540)
+32           Samsung PAL TCPM9091PD27
+33           MT20xx universal
+34           Temic PAL_BG (4106 FH5)
+35           Temic PAL_DK/SECAM_L (4012 FY5)
+36           Temic NTSC (4136 FY5)
+37           LG PAL (newer TAPC series)
+38           Philips PAL/SECAM multi (FM1216ME MK3)
+39           LG NTSC (newer TAPC series)
+40           HITACHI V7-J180AT
+41           Philips PAL_MK (FI1216 MK)
+42           Philips FCV1236D ATSC/NTSC dual in
+43           Philips NTSC MK3 (FM1236MK3 or FM1236/F)
+44           Philips 4 in 1 (ATI TV Wonder Pro/Conexant)
+45           Microtune 4049 FM5
+46           Panasonic VP27s/ENGE4324D
+47           LG NTSC (TAPE series)
+48           Tenna TNF 8831 BGFF)
+49           Microtune 4042 FI5 ATSC/NTSC dual in
+50           TCL 2002N
+51           Philips PAL/SECAM_D (FM 1256 I-H3)
+52           Thomson DTT 7610 (ATSC/NTSC)
+53           Philips FQ1286
+54           Philips/NXP TDA 8290/8295 + 8275/8275A/18271
+55           TCL 2002MB
+56           Philips PAL/SECAM multi (FQ1216AME MK4)
+57           Philips FQ1236A MK4
+58           Ymec TVision TVF-8531MF/8831MF/8731MF
+59           Ymec TVision TVF-5533MF
+60           Thomson DTT 761X (ATSC/NTSC)
+61           Tena TNF9533-D/IF/TNF9533-B/DF
+62           Philips TEA5767HN FM Radio
+63           Philips FMD1216ME MK3 Hybrid Tuner
+64           LG TDVS-H06xF
+65           Ymec TVF66T5-B/DFF
+66           LG TALN series
+67           Philips TD1316 Hybrid Tuner
+68           Philips TUV1236D ATSC/NTSC dual in
+69           Tena TNF 5335 and similar models
+70           Samsung TCPN 2121P30A
+71           Xceive xc2028/xc3028 tuner
+72           Thomson FE6600
+73           Samsung TCPG 6121P30A
+75           Philips TEA5761 FM Radio
+76           Xceive 5000 tuner
+77           TCL tuner MF02GIP-5N-E
+78           Philips FMD1216MEX MK3 Hybrid Tuner
+79           Philips PAL/SECAM multi (FM1216 MK5)
+80           Philips FQ1216LME MK3 PAL/SECAM w/active loopthrough
+81           Partsnic (Daewoo) PTI-5NF05
+82           Philips CU1216L
+83           NXP TDA18271
+84           Sony BTF-Pxn01Z
+85           Philips FQ1236 MK5
+86           Tena TNF5337 MFD
+87           Xceive 4000 tuner
+88           Xceive 5000C tuner
+89           Sony BTF-PG472Z PAL/SECAM
+90           Sony BTF-PK467Z NTSC-M-JP
+91           Sony BTF-PB463Z NTSC-M
+============ =====================================================
diff --git a/Documentation/admin-guide/media/usbvision-cardlist.rst b/Documentation/admin-guide/media/usbvision-cardlist.rst
new file mode 100644
index 000000000000..6aee115ee6e2
--- /dev/null
+++ b/Documentation/admin-guide/media/usbvision-cardlist.rst
@@ -0,0 +1,283 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+USBvision cards list
+====================
+
+.. tabularcolumns:: |p{1.4cm}|p{11.1cm}|p{4.2cm}|
+
+.. flat-table::
+   :header-rows: 1
+   :widths: 2 19 18
+   :stub-columns: 0
+
+   * - Card number
+     - Card name
+     - USB IDs
+
+   * - 0
+     - Xanboo
+     - 0a6f:0400
+
+   * - 1
+     - Belkin USB VideoBus II Adapter
+     - 050d:0106
+
+   * - 2
+     - Belkin Components USB VideoBus
+     - 050d:0207
+
+   * - 3
+     - Belkin USB VideoBus II
+     - 050d:0208
+
+   * - 4
+     - echoFX InterView Lite
+     - 0571:0002
+
+   * - 5
+     - USBGear USBG-V1 resp. HAMA USB
+     - 0573:0003
+
+   * - 6
+     - D-Link V100
+     - 0573:0400
+
+   * - 7
+     - X10 USB Camera
+     - 0573:2000
+
+   * - 8
+     - Hauppauge WinTV USB Live (PAL B/G)
+     - 0573:2d00
+
+   * - 9
+     - Hauppauge WinTV USB Live Pro (NTSC M/N)
+     - 0573:2d01
+
+   * - 10
+     - Zoran Co. PMD (Nogatech) AV-grabber Manhattan
+     - 0573:2101
+
+   * - 11
+     - Nogatech USB-TV (NTSC) FM
+     - 0573:4100
+
+   * - 12
+     - PNY USB-TV (NTSC) FM
+     - 0573:4110
+
+   * - 13
+     - PixelView PlayTv-USB PRO (PAL) FM
+     - 0573:4450
+
+   * - 14
+     - ZTV ZT-721 2.4GHz USB A/V Receiver
+     - 0573:4550
+
+   * - 15
+     - Hauppauge WinTV USB (NTSC M/N)
+     - 0573:4d00
+
+   * - 16
+     - Hauppauge WinTV USB (PAL B/G)
+     - 0573:4d01
+
+   * - 17
+     - Hauppauge WinTV USB (PAL I)
+     - 0573:4d02
+
+   * - 18
+     - Hauppauge WinTV USB (PAL/SECAM L)
+     - 0573:4d03
+
+   * - 19
+     - Hauppauge WinTV USB (PAL D/K)
+     - 0573:4d04
+
+   * - 20
+     - Hauppauge WinTV USB (NTSC FM)
+     - 0573:4d10
+
+   * - 21
+     - Hauppauge WinTV USB (PAL B/G FM)
+     - 0573:4d11
+
+   * - 22
+     - Hauppauge WinTV USB (PAL I FM)
+     - 0573:4d12
+
+   * - 23
+     - Hauppauge WinTV USB (PAL D/K FM)
+     - 0573:4d14
+
+   * - 24
+     - Hauppauge WinTV USB Pro (NTSC M/N)
+     - 0573:4d2a
+
+   * - 25
+     - Hauppauge WinTV USB Pro (NTSC M/N) V2
+     - 0573:4d2b
+
+   * - 26
+     - Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L)
+     - 0573:4d2c
+
+   * - 27
+     - Hauppauge WinTV USB Pro (NTSC M/N) V3
+     - 0573:4d20
+
+   * - 28
+     - Hauppauge WinTV USB Pro (PAL B/G)
+     - 0573:4d21
+
+   * - 29
+     - Hauppauge WinTV USB Pro (PAL I)
+     - 0573:4d22
+
+   * - 30
+     - Hauppauge WinTV USB Pro (PAL/SECAM L)
+     - 0573:4d23
+
+   * - 31
+     - Hauppauge WinTV USB Pro (PAL D/K)
+     - 0573:4d24
+
+   * - 32
+     - Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L)
+     - 0573:4d25
+
+   * - 33
+     - Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L) V2
+     - 0573:4d26
+
+   * - 34
+     - Hauppauge WinTV USB Pro (PAL B/G) V2
+     - 0573:4d27
+
+   * - 35
+     - Hauppauge WinTV USB Pro (PAL B/G,D/K)
+     - 0573:4d28
+
+   * - 36
+     - Hauppauge WinTV USB Pro (PAL I,D/K)
+     - 0573:4d29
+
+   * - 37
+     - Hauppauge WinTV USB Pro (NTSC M/N FM)
+     - 0573:4d30
+
+   * - 38
+     - Hauppauge WinTV USB Pro (PAL B/G FM)
+     - 0573:4d31
+
+   * - 39
+     - Hauppauge WinTV USB Pro (PAL I FM)
+     - 0573:4d32
+
+   * - 40
+     - Hauppauge WinTV USB Pro (PAL D/K FM)
+     - 0573:4d34
+
+   * - 41
+     - Hauppauge WinTV USB Pro (Temic PAL/SECAM B/G/I/D/K/L FM)
+     - 0573:4d35
+
+   * - 42
+     - Hauppauge WinTV USB Pro (Temic PAL B/G FM)
+     - 0573:4d36
+
+   * - 43
+     - Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L FM)
+     - 0573:4d37
+
+   * - 44
+     - Hauppauge WinTV USB Pro (NTSC M/N FM) V2
+     - 0573:4d38
+
+   * - 45
+     - Camtel Technology USB TV Genie Pro FM Model TVB330
+     - 0768:0006
+
+   * - 46
+     - Digital Video Creator I
+     - 07d0:0001
+
+   * - 47
+     - Global Village GV-007 (NTSC)
+     - 07d0:0002
+
+   * - 48
+     - Dazzle Fusion Model DVC-50 Rev 1 (NTSC)
+     - 07d0:0003
+
+   * - 49
+     - Dazzle Fusion Model DVC-80 Rev 1 (PAL)
+     - 07d0:0004
+
+   * - 50
+     - Dazzle Fusion Model DVC-90 Rev 1 (SECAM)
+     - 07d0:0005
+
+   * - 51
+     - Eskape Labs MyTV2Go
+     - 07f8:9104
+
+   * - 52
+     - Pinnacle Studio PCTV USB (PAL)
+     - 2304:010d
+
+   * - 53
+     - Pinnacle Studio PCTV USB (SECAM)
+     - 2304:0109
+
+   * - 54
+     - Pinnacle Studio PCTV USB (PAL) FM
+     - 2304:0110
+
+   * - 55
+     - Miro PCTV USB
+     - 2304:0111
+
+   * - 56
+     - Pinnacle Studio PCTV USB (NTSC) FM
+     - 2304:0112
+
+   * - 57
+     - Pinnacle Studio PCTV USB (PAL) FM V2
+     - 2304:0210
+
+   * - 58
+     - Pinnacle Studio PCTV USB (NTSC) FM V2
+     - 2304:0212
+
+   * - 59
+     - Pinnacle Studio PCTV USB (PAL) FM V3
+     - 2304:0214
+
+   * - 60
+     - Pinnacle Studio Linx Video input cable (NTSC)
+     - 2304:0300
+
+   * - 61
+     - Pinnacle Studio Linx Video input cable (PAL)
+     - 2304:0301
+
+   * - 62
+     - Pinnacle PCTV Bungee USB (PAL) FM
+     - 2304:0419
+
+   * - 63
+     - Hauppauge WinTv-USB
+     - 2400:4200
+
+   * - 64
+     - Pinnacle Studio PCTV USB (NTSC) FM V3
+     - 2304:0113
+
+   * - 65
+     - Nogatech USB MicroCam NTSC (NV3000N)
+     - 0573:3000
+
+   * - 66
+     - Nogatech USB MicroCam PAL (NV3001P)
+     - 0573:3001
diff --git a/Documentation/admin-guide/media/v4l-with-ir.rst b/Documentation/admin-guide/media/v4l-with-ir.rst
new file mode 100644
index 000000000000..ce23c8a7bc93
--- /dev/null
+++ b/Documentation/admin-guide/media/v4l-with-ir.rst
@@ -0,0 +1,75 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Infrared remote control support in video4linux drivers
+======================================================
+
+Authors: Gerd Hoffmann, Mauro Carvalho Chehab
+
+Basics
+------
+
+Most analog and digital TV boards support remote controllers. Several of
+them have a microprocessor that receives the IR carriers, convert into
+pulse/space sequences and then to scan codes, returning such codes to
+userspace ("scancode mode"). Other boards return just the pulse/space
+sequences ("raw mode").
+
+The support for remote controller in scancode mode is provided by the
+standard Linux input layer. The support for raw mode is provided via LIRC.
+
+In order to check the support and test it, it is suggested to download
+the `v4l-utils <https://git.linuxtv.org/v4l-utils.git/>`_. It provides
+two tools to handle remote controllers:
+
+- ir-keytable: provides a way to query the remote controller, list the
+  protocols it supports, enable in-kernel support for IR decoder or
+  switch the protocol and to test the reception of scan codes;
+
+- ir-ctl: provide tools to handle remote controllers that support raw mode
+  via LIRC interface.
+
+Usually, the remote controller module is auto-loaded when the TV card is
+detected. However, for a few devices, you need to manually load the
+ir-kbd-i2c module.
+
+How it works
+------------
+
+The modules register the remote as keyboard within the linux input
+layer, i.e. you'll see the keys of the remote as normal key strokes
+(if CONFIG_INPUT_KEYBOARD is enabled).
+
+Using the event devices (CONFIG_INPUT_EVDEV) it is possible for
+applications to access the remote via /dev/input/event<n> devices.
+The udev/systemd will automatically create the devices. If you install
+the `v4l-utils <https://git.linuxtv.org/v4l-utils.git/>`_, it may also
+automatically load a different keytable than the default one. Please see
+`v4l-utils <https://git.linuxtv.org/v4l-utils.git/>`_ ir-keytable.1
+man page for details.
+
+The ir-keytable tool is nice for trouble shooting, i.e. to check
+whenever the input device is really present, which of the devices it
+is, check whenever pressing keys on the remote actually generates
+events and the like.  You can also use any other input utility that changes
+the keymaps, like the input kbd utility.
+
+
+Using with lircd
+================
+
+The latest versions of the lircd daemon supports reading events from the
+linux input layer (via event device). It also supports receiving IR codes
+in lirc mode.
+
+
+Using without lircd
+===================
+
+Xorg recognizes several IR keycodes that have its numerical value lower
+than 247. With the advent of Wayland, the input driver got updated too,
+and should now accept all keycodes. Yet, you may want to just reasign
+the keycodes to something that your favorite media application likes.
+
+This can be done by setting
+`v4l-utils <https://git.linuxtv.org/v4l-utils.git/>`_ to load your own
+keytable in runtime. Please read  ir-keytable.1 man page for details.
diff --git a/Documentation/admin-guide/media/vimc.dot b/Documentation/admin-guide/media/vimc.dot
new file mode 100644
index 000000000000..57863a13fa39
--- /dev/null
+++ b/Documentation/admin-guide/media/vimc.dot
@@ -0,0 +1,22 @@
+# SPDX-License-Identifier: GPL-2.0
+
+digraph board {
+	rankdir=TB
+	n00000001 [label="{{} | Sensor A\n/dev/v4l-subdev0 | {<port0> 0}}", shape=Mrecord, style=filled, fillcolor=green]
+	n00000001:port0 -> n00000005:port0 [style=bold]
+	n00000001:port0 -> n0000000b [style=bold]
+	n00000003 [label="{{} | Sensor B\n/dev/v4l-subdev1 | {<port0> 0}}", shape=Mrecord, style=filled, fillcolor=green]
+	n00000003:port0 -> n00000008:port0 [style=bold]
+	n00000003:port0 -> n0000000f [style=bold]
+	n00000005 [label="{{<port0> 0} | Debayer A\n/dev/v4l-subdev2 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n00000005:port1 -> n00000017:port0
+	n00000008 [label="{{<port0> 0} | Debayer B\n/dev/v4l-subdev3 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n00000008:port1 -> n00000017:port0 [style=dashed]
+	n0000000b [label="Raw Capture 0\n/dev/video0", shape=box, style=filled, fillcolor=yellow]
+	n0000000f [label="Raw Capture 1\n/dev/video1", shape=box, style=filled, fillcolor=yellow]
+	n00000013 [label="RGB/YUV Input\n/dev/video2", shape=box, style=filled, fillcolor=yellow]
+	n00000013 -> n00000017:port0 [style=dashed]
+	n00000017 [label="{{<port0> 0} | Scaler\n/dev/v4l-subdev4 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+	n00000017:port1 -> n0000001a [style=bold]
+	n0000001a [label="RGB/YUV Capture\n/dev/video3", shape=box, style=filled, fillcolor=yellow]
+}
diff --git a/Documentation/admin-guide/media/vimc.rst b/Documentation/admin-guide/media/vimc.rst
new file mode 100644
index 000000000000..211cc8972410
--- /dev/null
+++ b/Documentation/admin-guide/media/vimc.rst
@@ -0,0 +1,90 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+The Virtual Media Controller Driver (vimc)
+==========================================
+
+The vimc driver emulates complex video hardware using the V4L2 API and the Media
+API. It has a capture device and three subdevices: sensor, debayer and scaler.
+
+Topology
+--------
+
+The topology is hardcoded, although you could modify it in vimc-core and
+recompile the driver to achieve your own topology. This is the default topology:
+
+.. _vimc_topology_graph:
+
+.. kernel-figure:: vimc.dot
+    :alt:   Diagram of the default media pipeline topology
+    :align: center
+
+    Media pipeline graph on vimc
+
+Configuring the topology
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Each subdevice will come with its default configuration (pixelformat, height,
+width, ...). One needs to configure the topology in order to match the
+configuration on each linked subdevice to stream frames through the pipeline.
+If the configuration doesn't match, the stream will fail. The ``v4l-utils``
+package is a bundle of user-space applications, that comes with ``media-ctl`` and
+``v4l2-ctl`` that can be used to configure the vimc configuration. This sequence
+of commands fits for the default topology:
+
+.. code-block:: bash
+
+        media-ctl -d platform:vimc -V '"Sensor A":0[fmt:SBGGR8_1X8/640x480]'
+        media-ctl -d platform:vimc -V '"Debayer A":0[fmt:SBGGR8_1X8/640x480]'
+        media-ctl -d platform:vimc -V '"Sensor B":0[fmt:SBGGR8_1X8/640x480]'
+        media-ctl -d platform:vimc -V '"Debayer B":0[fmt:SBGGR8_1X8/640x480]'
+        v4l2-ctl -z platform:vimc -d "RGB/YUV Capture" -v width=1920,height=1440
+        v4l2-ctl -z platform:vimc -d "Raw Capture 0" -v pixelformat=BA81
+        v4l2-ctl -z platform:vimc -d "Raw Capture 1" -v pixelformat=BA81
+
+Subdevices
+----------
+
+Subdevices define the behavior of an entity in the topology. Depending on the
+subdevice, the entity can have multiple pads of type source or sink.
+
+vimc-sensor:
+	Generates images in several formats using video test pattern generator.
+	Exposes:
+
+	* 1 Pad source
+
+vimc-debayer:
+	Transforms images in bayer format into a non-bayer format.
+	Exposes:
+
+	* 1 Pad sink
+	* 1 Pad source
+
+vimc-scaler:
+	Scale up the image by a factor of 3. E.g.: a 640x480 image becomes a
+        1920x1440 image. (this value can be configured, see at
+        `Module options`_).
+	Exposes:
+
+	* 1 Pad sink
+	* 1 Pad source
+
+vimc-capture:
+	Exposes node /dev/videoX to allow userspace to capture the stream.
+	Exposes:
+
+	* 1 Pad sink
+	* 1 Pad source
+
+
+Module options
+--------------
+
+Vimc has a module parameter to configure the driver.
+
+* ``sca_mult=<unsigned int>``
+
+        Image size multiplier factor to be used to multiply both width and
+        height, so the image size will be ``sca_mult^2`` bigger than the
+        original one. Currently, only supports scaling up (the default value
+        is 3).
diff --git a/Documentation/admin-guide/media/vivid.rst b/Documentation/admin-guide/media/vivid.rst
new file mode 100644
index 000000000000..52e57b773f07
--- /dev/null
+++ b/Documentation/admin-guide/media/vivid.rst
@@ -0,0 +1,1393 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+The Virtual Video Test Driver (vivid)
+=====================================
+
+This driver emulates video4linux hardware of various types: video capture, video
+output, vbi capture and output, metadata capture and output, radio receivers and
+transmitters, touch capture and a software defined radio receiver. In addition a
+simple framebuffer device is available for testing capture and output overlays.
+
+Up to 64 vivid instances can be created, each with up to 16 inputs and 16 outputs.
+
+Each input can be a webcam, TV capture device, S-Video capture device or an HDMI
+capture device. Each output can be an S-Video output device or an HDMI output
+device.
+
+These inputs and outputs act exactly as a real hardware device would behave. This
+allows you to use this driver as a test input for application development, since
+you can test the various features without requiring special hardware.
+
+This document describes the features implemented by this driver:
+
+- Support for read()/write(), MMAP, USERPTR and DMABUF streaming I/O.
+- A large list of test patterns and variations thereof
+- Working brightness, contrast, saturation and hue controls
+- Support for the alpha color component
+- Full colorspace support, including limited/full RGB range
+- All possible control types are present
+- Support for various pixel aspect ratios and video aspect ratios
+- Error injection to test what happens if errors occur
+- Supports crop/compose/scale in any combination for both input and output
+- Can emulate up to 4K resolutions
+- All Field settings are supported for testing interlaced capturing
+- Supports all standard YUV and RGB formats, including two multiplanar YUV formats
+- Raw and Sliced VBI capture and output support
+- Radio receiver and transmitter support, including RDS support
+- Software defined radio (SDR) support
+- Capture and output overlay support
+- Metadata capture and output support
+- Touch capture support
+
+These features will be described in more detail below.
+
+Configuring the driver
+----------------------
+
+By default the driver will create a single instance that has a video capture
+device with webcam, TV, S-Video and HDMI inputs, a video output device with
+S-Video and HDMI outputs, one vbi capture device, one vbi output device, one
+radio receiver device, one radio transmitter device and one SDR device.
+
+The number of instances, devices, video inputs and outputs and their types are
+all configurable using the following module options:
+
+- n_devs:
+
+	number of driver instances to create. By default set to 1. Up to 64
+	instances can be created.
+
+- node_types:
+
+	which devices should each driver instance create. An array of
+	hexadecimal values, one for each instance. The default is 0x1d3d.
+	Each value is a bitmask with the following meaning:
+
+		- bit 0: Video Capture node
+		- bit 2-3: VBI Capture node: 0 = none, 1 = raw vbi, 2 = sliced vbi, 3 = both
+		- bit 4: Radio Receiver node
+		- bit 5: Software Defined Radio Receiver node
+		- bit 8: Video Output node
+		- bit 10-11: VBI Output node: 0 = none, 1 = raw vbi, 2 = sliced vbi, 3 = both
+		- bit 12: Radio Transmitter node
+		- bit 16: Framebuffer for testing overlays
+		- bit 17: Metadata Capture node
+		- bit 18: Metadata Output node
+		- bit 19: Touch Capture node
+
+	So to create four instances, the first two with just one video capture
+	device, the second two with just one video output device you would pass
+	these module options to vivid:
+
+	.. code-block:: none
+
+		n_devs=4 node_types=0x1,0x1,0x100,0x100
+
+- num_inputs:
+
+	the number of inputs, one for each instance. By default 4 inputs
+	are created for each video capture device. At most 16 inputs can be created,
+	and there must be at least one.
+
+- input_types:
+
+	the input types for each instance, the default is 0xe4. This defines
+	what the type of each input is when the inputs are created for each driver
+	instance. This is a hexadecimal value with up to 16 pairs of bits, each
+	pair gives the type and bits 0-1 map to input 0, bits 2-3 map to input 1,
+	30-31 map to input 15. Each pair of bits has the following meaning:
+
+		- 00: this is a webcam input
+		- 01: this is a TV tuner input
+		- 10: this is an S-Video input
+		- 11: this is an HDMI input
+
+	So to create a video capture device with 8 inputs where input 0 is a TV
+	tuner, inputs 1-3 are S-Video inputs and inputs 4-7 are HDMI inputs you
+	would use the following module options:
+
+	.. code-block:: none
+
+		num_inputs=8 input_types=0xffa9
+
+- num_outputs:
+
+	the number of outputs, one for each instance. By default 2 outputs
+	are created for each video output device. At most 16 outputs can be
+	created, and there must be at least one.
+
+- output_types:
+
+	the output types for each instance, the default is 0x02. This defines
+	what the type of each output is when the outputs are created for each
+	driver instance. This is a hexadecimal value with up to 16 bits, each bit
+	gives the type and bit 0 maps to output 0, bit 1 maps to output 1, bit
+	15 maps to output 15. The meaning of each bit is as follows:
+
+		- 0: this is an S-Video output
+		- 1: this is an HDMI output
+
+	So to create a video output device with 8 outputs where outputs 0-3 are
+	S-Video outputs and outputs 4-7 are HDMI outputs you would use the
+	following module options:
+
+	.. code-block:: none
+
+		num_outputs=8 output_types=0xf0
+
+- vid_cap_nr:
+
+	give the desired videoX start number for each video capture device.
+	The default is -1 which will just take the first free number. This allows
+	you to map capture video nodes to specific videoX device nodes. Example:
+
+	.. code-block:: none
+
+		n_devs=4 vid_cap_nr=2,4,6,8
+
+	This will attempt to assign /dev/video2 for the video capture device of
+	the first vivid instance, video4 for the next up to video8 for the last
+	instance. If it can't succeed, then it will just take the next free
+	number.
+
+- vid_out_nr:
+
+	give the desired videoX start number for each video output device.
+	The default is -1 which will just take the first free number.
+
+- vbi_cap_nr:
+
+	give the desired vbiX start number for each vbi capture device.
+	The default is -1 which will just take the first free number.
+
+- vbi_out_nr:
+
+	give the desired vbiX start number for each vbi output device.
+	The default is -1 which will just take the first free number.
+
+- radio_rx_nr:
+
+	give the desired radioX start number for each radio receiver device.
+	The default is -1 which will just take the first free number.
+
+- radio_tx_nr:
+
+	give the desired radioX start number for each radio transmitter
+	device. The default is -1 which will just take the first free number.
+
+- sdr_cap_nr:
+
+	give the desired swradioX start number for each SDR capture device.
+	The default is -1 which will just take the first free number.
+
+- meta_cap_nr:
+
+        give the desired videoX start number for each metadata capture device.
+        The default is -1 which will just take the first free number.
+
+- meta_out_nr:
+
+        give the desired videoX start number for each metadata output device.
+        The default is -1 which will just take the first free number.
+
+- touch_cap_nr:
+
+        give the desired v4l-touchX start number for each touch capture device.
+        The default is -1 which will just take the first free number.
+
+- ccs_cap_mode:
+
+	specify the allowed video capture crop/compose/scaling combination
+	for each driver instance. Video capture devices can have any combination
+	of cropping, composing and scaling capabilities and this will tell the
+	vivid driver which of those is should emulate. By default the user can
+	select this through controls.
+
+	The value is either -1 (controlled by the user) or a set of three bits,
+	each enabling (1) or disabling (0) one of the features:
+
+	- bit 0:
+
+		Enable crop support. Cropping will take only part of the
+		incoming picture.
+	- bit 1:
+
+		Enable compose support. Composing will copy the incoming
+		picture into a larger buffer.
+
+	- bit 2:
+
+		Enable scaling support. Scaling can scale the incoming
+		picture. The scaler of the vivid driver can enlarge up
+		or down to four times the original size. The scaler is
+		very simple and low-quality. Simplicity and speed were
+		key, not quality.
+
+	Note that this value is ignored by webcam inputs: those enumerate
+	discrete framesizes and that is incompatible with cropping, composing
+	or scaling.
+
+- ccs_out_mode:
+
+	specify the allowed video output crop/compose/scaling combination
+	for each driver instance. Video output devices can have any combination
+	of cropping, composing and scaling capabilities and this will tell the
+	vivid driver which of those is should emulate. By default the user can
+	select this through controls.
+
+	The value is either -1 (controlled by the user) or a set of three bits,
+	each enabling (1) or disabling (0) one of the features:
+
+	- bit 0:
+
+		Enable crop support. Cropping will take only part of the
+		outgoing buffer.
+
+	- bit 1:
+
+		Enable compose support. Composing will copy the incoming
+		buffer into a larger picture frame.
+
+	- bit 2:
+
+		Enable scaling support. Scaling can scale the incoming
+		buffer. The scaler of the vivid driver can enlarge up
+		or down to four times the original size. The scaler is
+		very simple and low-quality. Simplicity and speed were
+		key, not quality.
+
+- multiplanar:
+
+	select whether each device instance supports multi-planar formats,
+	and thus the V4L2 multi-planar API. By default device instances are
+	single-planar.
+
+	This module option can override that for each instance. Values are:
+
+		- 1: this is a single-planar instance.
+		- 2: this is a multi-planar instance.
+
+- vivid_debug:
+
+	enable driver debugging info
+
+- no_error_inj:
+
+	if set disable the error injecting controls. This option is
+	needed in order to run a tool like v4l2-compliance. Tools like that
+	exercise all controls including a control like 'Disconnect' which
+	emulates a USB disconnect, making the device inaccessible and so
+	all tests that v4l2-compliance is doing will fail afterwards.
+
+	There may be other situations as well where you want to disable the
+	error injection support of vivid. When this option is set, then the
+	controls that select crop, compose and scale behavior are also
+	removed. Unless overridden by ccs_cap_mode and/or ccs_out_mode the
+	will default to enabling crop, compose and scaling.
+
+- allocators:
+
+	memory allocator selection, default is 0. It specifies the way buffers
+	will be allocated.
+
+		- 0: vmalloc
+		- 1: dma-contig
+
+Taken together, all these module options allow you to precisely customize
+the driver behavior and test your application with all sorts of permutations.
+It is also very suitable to emulate hardware that is not yet available, e.g.
+when developing software for a new upcoming device.
+
+
+Video Capture
+-------------
+
+This is probably the most frequently used feature. The video capture device
+can be configured by using the module options num_inputs, input_types and
+ccs_cap_mode (see section 1 for more detailed information), but by default
+four inputs are configured: a webcam, a TV tuner, an S-Video and an HDMI
+input, one input for each input type. Those are described in more detail
+below.
+
+Special attention has been given to the rate at which new frames become
+available. The jitter will be around 1 jiffie (that depends on the HZ
+configuration of your kernel, so usually 1/100, 1/250 or 1/1000 of a second),
+but the long-term behavior is exactly following the framerate. So a
+framerate of 59.94 Hz is really different from 60 Hz. If the framerate
+exceeds your kernel's HZ value, then you will get dropped frames, but the
+frame/field sequence counting will keep track of that so the sequence
+count will skip whenever frames are dropped.
+
+
+Webcam Input
+~~~~~~~~~~~~
+
+The webcam input supports three framesizes: 320x180, 640x360 and 1280x720. It
+supports frames per second settings of 10, 15, 25, 30, 50 and 60 fps. Which ones
+are available depends on the chosen framesize: the larger the framesize, the
+lower the maximum frames per second.
+
+The initially selected colorspace when you switch to the webcam input will be
+sRGB.
+
+
+TV and S-Video Inputs
+~~~~~~~~~~~~~~~~~~~~~
+
+The only difference between the TV and S-Video input is that the TV has a
+tuner. Otherwise they behave identically.
+
+These inputs support audio inputs as well: one TV and one Line-In. They
+both support all TV standards. If the standard is queried, then the Vivid
+controls 'Standard Signal Mode' and 'Standard' determine what
+the result will be.
+
+These inputs support all combinations of the field setting. Special care has
+been taken to faithfully reproduce how fields are handled for the different
+TV standards. This is particularly noticeable when generating a horizontally
+moving image so the temporal effect of using interlaced formats becomes clearly
+visible. For 50 Hz standards the top field is the oldest and the bottom field
+is the newest in time. For 60 Hz standards that is reversed: the bottom field
+is the oldest and the top field is the newest in time.
+
+When you start capturing in V4L2_FIELD_ALTERNATE mode the first buffer will
+contain the top field for 50 Hz standards and the bottom field for 60 Hz
+standards. This is what capture hardware does as well.
+
+Finally, for PAL/SECAM standards the first half of the top line contains noise.
+This simulates the Wide Screen Signal that is commonly placed there.
+
+The initially selected colorspace when you switch to the TV or S-Video input
+will be SMPTE-170M.
+
+The pixel aspect ratio will depend on the TV standard. The video aspect ratio
+can be selected through the 'Standard Aspect Ratio' Vivid control.
+Choices are '4x3', '16x9' which will give letterboxed widescreen video and
+'16x9 Anamorphic' which will give full screen squashed anamorphic widescreen
+video that will need to be scaled accordingly.
+
+The TV 'tuner' supports a frequency range of 44-958 MHz. Channels are available
+every 6 MHz, starting from 49.25 MHz. For each channel the generated image
+will be in color for the +/- 0.25 MHz around it, and in grayscale for
++/- 1 MHz around the channel. Beyond that it is just noise. The VIDIOC_G_TUNER
+ioctl will return 100% signal strength for +/- 0.25 MHz and 50% for +/- 1 MHz.
+It will also return correct afc values to show whether the frequency is too
+low or too high.
+
+The audio subchannels that are returned are MONO for the +/- 1 MHz range around
+a valid channel frequency. When the frequency is within +/- 0.25 MHz of the
+channel it will return either MONO, STEREO, either MONO | SAP (for NTSC) or
+LANG1 | LANG2 (for others), or STEREO | SAP.
+
+Which one is returned depends on the chosen channel, each next valid channel
+will cycle through the possible audio subchannel combinations. This allows
+you to test the various combinations by just switching channels..
+
+Finally, for these inputs the v4l2_timecode struct is filled in in the
+dequeued v4l2_buffer struct.
+
+
+HDMI Input
+~~~~~~~~~~
+
+The HDMI inputs supports all CEA-861 and DMT timings, both progressive and
+interlaced, for pixelclock frequencies between 25 and 600 MHz. The field
+mode for interlaced formats is always V4L2_FIELD_ALTERNATE. For HDMI the
+field order is always top field first, and when you start capturing an
+interlaced format you will receive the top field first.
+
+The initially selected colorspace when you switch to the HDMI input or
+select an HDMI timing is based on the format resolution: for resolutions
+less than or equal to 720x576 the colorspace is set to SMPTE-170M, for
+others it is set to REC-709 (CEA-861 timings) or sRGB (VESA DMT timings).
+
+The pixel aspect ratio will depend on the HDMI timing: for 720x480 is it
+set as for the NTSC TV standard, for 720x576 it is set as for the PAL TV
+standard, and for all others a 1:1 pixel aspect ratio is returned.
+
+The video aspect ratio can be selected through the 'DV Timings Aspect Ratio'
+Vivid control. Choices are 'Source Width x Height' (just use the
+same ratio as the chosen format), '4x3' or '16x9', either of which can
+result in pillarboxed or letterboxed video.
+
+For HDMI inputs it is possible to set the EDID. By default a simple EDID
+is provided. You can only set the EDID for HDMI inputs. Internally, however,
+the EDID is shared between all HDMI inputs.
+
+No interpretation is done of the EDID data with the exception of the
+physical address. See the CEC section for more details.
+
+There is a maximum of 15 HDMI inputs (if there are more, then they will be
+reduced to 15) since that's the limitation of the EDID physical address.
+
+
+Video Output
+------------
+
+The video output device can be configured by using the module options
+num_outputs, output_types and ccs_out_mode (see section 1 for more detailed
+information), but by default two outputs are configured: an S-Video and an
+HDMI input, one output for each output type. Those are described in more detail
+below.
+
+Like with video capture the framerate is also exact in the long term.
+
+
+S-Video Output
+~~~~~~~~~~~~~~
+
+This output supports audio outputs as well: "Line-Out 1" and "Line-Out 2".
+The S-Video output supports all TV standards.
+
+This output supports all combinations of the field setting.
+
+The initially selected colorspace when you switch to the TV or S-Video input
+will be SMPTE-170M.
+
+
+HDMI Output
+~~~~~~~~~~~
+
+The HDMI output supports all CEA-861 and DMT timings, both progressive and
+interlaced, for pixelclock frequencies between 25 and 600 MHz. The field
+mode for interlaced formats is always V4L2_FIELD_ALTERNATE.
+
+The initially selected colorspace when you switch to the HDMI output or
+select an HDMI timing is based on the format resolution: for resolutions
+less than or equal to 720x576 the colorspace is set to SMPTE-170M, for
+others it is set to REC-709 (CEA-861 timings) or sRGB (VESA DMT timings).
+
+The pixel aspect ratio will depend on the HDMI timing: for 720x480 is it
+set as for the NTSC TV standard, for 720x576 it is set as for the PAL TV
+standard, and for all others a 1:1 pixel aspect ratio is returned.
+
+An HDMI output has a valid EDID which can be obtained through VIDIOC_G_EDID.
+
+There is a maximum of 15 HDMI outputs (if there are more, then they will be
+reduced to 15) since that's the limitation of the EDID physical address. See
+also the CEC section for more details.
+
+VBI Capture
+-----------
+
+There are three types of VBI capture devices: those that only support raw
+(undecoded) VBI, those that only support sliced (decoded) VBI and those that
+support both. This is determined by the node_types module option. In all
+cases the driver will generate valid VBI data: for 60 Hz standards it will
+generate Closed Caption and XDS data. The closed caption stream will
+alternate between "Hello world!" and "Closed captions test" every second.
+The XDS stream will give the current time once a minute. For 50 Hz standards
+it will generate the Wide Screen Signal which is based on the actual Video
+Aspect Ratio control setting and teletext pages 100-159, one page per frame.
+
+The VBI device will only work for the S-Video and TV inputs, it will give
+back an error if the current input is a webcam or HDMI.
+
+
+VBI Output
+----------
+
+There are three types of VBI output devices: those that only support raw
+(undecoded) VBI, those that only support sliced (decoded) VBI and those that
+support both. This is determined by the node_types module option.
+
+The sliced VBI output supports the Wide Screen Signal and the teletext signal
+for 50 Hz standards and Closed Captioning + XDS for 60 Hz standards.
+
+The VBI device will only work for the S-Video output, it will give
+back an error if the current output is HDMI.
+
+
+Radio Receiver
+--------------
+
+The radio receiver emulates an FM/AM/SW receiver. The FM band also supports RDS.
+The frequency ranges are:
+
+	- FM: 64 MHz - 108 MHz
+	- AM: 520 kHz - 1710 kHz
+	- SW: 2300 kHz - 26.1 MHz
+
+Valid channels are emulated every 1 MHz for FM and every 100 kHz for AM and SW.
+The signal strength decreases the further the frequency is from the valid
+frequency until it becomes 0% at +/- 50 kHz (FM) or 5 kHz (AM/SW) from the
+ideal frequency. The initial frequency when the driver is loaded is set to
+95 MHz.
+
+The FM receiver supports RDS as well, both using 'Block I/O' and 'Controls'
+modes. In the 'Controls' mode the RDS information is stored in read-only
+controls. These controls are updated every time the frequency is changed,
+or when the tuner status is requested. The Block I/O method uses the read()
+interface to pass the RDS blocks on to the application for decoding.
+
+The RDS signal is 'detected' for +/- 12.5 kHz around the channel frequency,
+and the further the frequency is away from the valid frequency the more RDS
+errors are randomly introduced into the block I/O stream, up to 50% of all
+blocks if you are +/- 12.5 kHz from the channel frequency. All four errors
+can occur in equal proportions: blocks marked 'CORRECTED', blocks marked
+'ERROR', blocks marked 'INVALID' and dropped blocks.
+
+The generated RDS stream contains all the standard fields contained in a
+0B group, and also radio text and the current time.
+
+The receiver supports HW frequency seek, either in Bounded mode, Wrap Around
+mode or both, which is configurable with the "Radio HW Seek Mode" control.
+
+
+Radio Transmitter
+-----------------
+
+The radio transmitter emulates an FM/AM/SW transmitter. The FM band also supports RDS.
+The frequency ranges are:
+
+	- FM: 64 MHz - 108 MHz
+	- AM: 520 kHz - 1710 kHz
+	- SW: 2300 kHz - 26.1 MHz
+
+The initial frequency when the driver is loaded is 95.5 MHz.
+
+The FM transmitter supports RDS as well, both using 'Block I/O' and 'Controls'
+modes. In the 'Controls' mode the transmitted RDS information is configured
+using controls, and in 'Block I/O' mode the blocks are passed to the driver
+using write().
+
+
+Software Defined Radio Receiver
+-------------------------------
+
+The SDR receiver has three frequency bands for the ADC tuner:
+
+	- 300 kHz
+	- 900 kHz - 2800 kHz
+	- 3200 kHz
+
+The RF tuner supports 50 MHz - 2000 MHz.
+
+The generated data contains the In-phase and Quadrature components of a
+1 kHz tone that has an amplitude of sqrt(2).
+
+
+Metadata Capture
+----------------
+
+The Metadata capture generates UVC format metadata. The PTS and SCR are
+transmitted based on the values set in vivid contols.
+
+The Metadata device will only work for the Webcam input, it will give
+back an error for all other inputs.
+
+
+Metadata Output
+---------------
+
+The Metadata output can be used to set brightness, contrast, saturation and hue.
+
+The Metadata device will only work for the Webcam output, it will give
+back an error for all other outputs.
+
+
+Touch Capture
+-------------
+
+The Touch capture generates touch patterns simulating single tap, double tap,
+triple tap, move from left to right, zoom in, zoom out, palm press (simulating
+a large area being pressed on a touchpad), and simulating 16 simultaneous
+touch points.
+
+Controls
+--------
+
+Different devices support different controls. The sections below will describe
+each control and which devices support them.
+
+
+User Controls - Test Controls
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The Button, Boolean, Integer 32 Bits, Integer 64 Bits, Menu, String, Bitmask and
+Integer Menu are controls that represent all possible control types. The Menu
+control and the Integer Menu control both have 'holes' in their menu list,
+meaning that one or more menu items return EINVAL when VIDIOC_QUERYMENU is called.
+Both menu controls also have a non-zero minimum control value.  These features
+allow you to check if your application can handle such things correctly.
+These controls are supported for every device type.
+
+
+User Controls - Video Capture
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following controls are specific to video capture.
+
+The Brightness, Contrast, Saturation and Hue controls actually work and are
+standard. There is one special feature with the Brightness control: each
+video input has its own brightness value, so changing input will restore
+the brightness for that input. In addition, each video input uses a different
+brightness range (minimum and maximum control values). Switching inputs will
+cause a control event to be sent with the V4L2_EVENT_CTRL_CH_RANGE flag set.
+This allows you to test controls that can change their range.
+
+The 'Gain, Automatic' and Gain controls can be used to test volatile controls:
+if 'Gain, Automatic' is set, then the Gain control is volatile and changes
+constantly. If 'Gain, Automatic' is cleared, then the Gain control is a normal
+control.
+
+The 'Horizontal Flip' and 'Vertical Flip' controls can be used to flip the
+image. These combine with the 'Sensor Flipped Horizontally/Vertically' Vivid
+controls.
+
+The 'Alpha Component' control can be used to set the alpha component for
+formats containing an alpha channel.
+
+
+User Controls - Audio
+~~~~~~~~~~~~~~~~~~~~~
+
+The following controls are specific to video capture and output and radio
+receivers and transmitters.
+
+The 'Volume' and 'Mute' audio controls are typical for such devices to
+control the volume and mute the audio. They don't actually do anything in
+the vivid driver.
+
+
+Vivid Controls
+~~~~~~~~~~~~~~
+
+These vivid custom controls control the image generation, error injection, etc.
+
+
+Test Pattern Controls
+^^^^^^^^^^^^^^^^^^^^^
+
+The Test Pattern Controls are all specific to video capture.
+
+- Test Pattern:
+
+	selects which test pattern to use. Use the CSC Colorbar for
+	testing colorspace conversions: the colors used in that test pattern
+	map to valid colors in all colorspaces. The colorspace conversion
+	is disabled for the other test patterns.
+
+- OSD Text Mode:
+
+	selects whether the text superimposed on the
+	test pattern should be shown, and if so, whether only counters should
+	be displayed or the full text.
+
+- Horizontal Movement:
+
+	selects whether the test pattern should
+	move to the left or right and at what speed.
+
+- Vertical Movement:
+
+	does the same for the vertical direction.
+
+- Show Border:
+
+	show a two-pixel wide border at the edge of the actual image,
+	excluding letter or pillarboxing.
+
+- Show Square:
+
+	show a square in the middle of the image. If the image is
+	displayed with the correct pixel and image aspect ratio corrections,
+	then the width and height of the square on the monitor should be
+	the same.
+
+- Insert SAV Code in Image:
+
+	adds a SAV (Start of Active Video) code to the image.
+	This can be used to check if such codes in the image are inadvertently
+	interpreted instead of being ignored.
+
+- Insert EAV Code in Image:
+
+	does the same for the EAV (End of Active Video) code.
+
+
+Capture Feature Selection Controls
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+These controls are all specific to video capture.
+
+- Sensor Flipped Horizontally:
+
+	the image is flipped horizontally and the
+	V4L2_IN_ST_HFLIP input status flag is set. This emulates the case where
+	a sensor is for example mounted upside down.
+
+- Sensor Flipped Vertically:
+
+	the image is flipped vertically and the
+	V4L2_IN_ST_VFLIP input status flag is set. This emulates the case where
+	a sensor is for example mounted upside down.
+
+- Standard Aspect Ratio:
+
+	selects if the image aspect ratio as used for the TV or
+	S-Video input should be 4x3, 16x9 or anamorphic widescreen. This may
+	introduce letterboxing.
+
+- DV Timings Aspect Ratio:
+
+	selects if the image aspect ratio as used for the HDMI
+	input should be the same as the source width and height ratio, or if
+	it should be 4x3 or 16x9. This may introduce letter or pillarboxing.
+
+- Timestamp Source:
+
+	selects when the timestamp for each buffer is taken.
+
+- Colorspace:
+
+	selects which colorspace should be used when generating the image.
+	This only applies if the CSC Colorbar test pattern is selected,
+	otherwise the test pattern will go through unconverted.
+	This behavior is also what you want, since a 75% Colorbar
+	should really have 75% signal intensity and should not be affected
+	by colorspace conversions.
+
+	Changing the colorspace will result in the V4L2_EVENT_SOURCE_CHANGE
+	to be sent since it emulates a detected colorspace change.
+
+- Transfer Function:
+
+	selects which colorspace transfer function should be used when
+	generating an image. This only applies if the CSC Colorbar test pattern is
+	selected, otherwise the test pattern will go through unconverted.
+	This behavior is also what you want, since a 75% Colorbar
+	should really have 75% signal intensity and should not be affected
+	by colorspace conversions.
+
+	Changing the transfer function will result in the V4L2_EVENT_SOURCE_CHANGE
+	to be sent since it emulates a detected colorspace change.
+
+- Y'CbCr Encoding:
+
+	selects which Y'CbCr encoding should be used when generating
+	a Y'CbCr image.	This only applies if the format is set to a Y'CbCr format
+	as opposed to an RGB format.
+
+	Changing the Y'CbCr encoding will result in the V4L2_EVENT_SOURCE_CHANGE
+	to be sent since it emulates a detected colorspace change.
+
+- Quantization:
+
+	selects which quantization should be used for the RGB or Y'CbCr
+	encoding when generating the test pattern.
+
+	Changing the quantization will result in the V4L2_EVENT_SOURCE_CHANGE
+	to be sent since it emulates a detected colorspace change.
+
+- Limited RGB Range (16-235):
+
+	selects if the RGB range of the HDMI source should
+	be limited or full range. This combines with the Digital Video 'Rx RGB
+	Quantization Range' control and can be used to test what happens if
+	a source provides you with the wrong quantization range information.
+	See the description of that control for more details.
+
+- Apply Alpha To Red Only:
+
+	apply the alpha channel as set by the 'Alpha Component'
+	user control to the red color of the test pattern only.
+
+- Enable Capture Cropping:
+
+	enables crop support. This control is only present if
+	the ccs_cap_mode module option is set to the default value of -1 and if
+	the no_error_inj module option is set to 0 (the default).
+
+- Enable Capture Composing:
+
+	enables composing support. This control is only
+	present if the ccs_cap_mode module option is set to the default value of
+	-1 and if the no_error_inj module option is set to 0 (the default).
+
+- Enable Capture Scaler:
+
+	enables support for a scaler (maximum 4 times upscaling
+	and downscaling). This control is only present if the ccs_cap_mode
+	module option is set to the default value of -1 and if the no_error_inj
+	module option is set to 0 (the default).
+
+- Maximum EDID Blocks:
+
+	determines how many EDID blocks the driver supports.
+	Note that the vivid driver does not actually interpret new EDID
+	data, it just stores it. It allows for up to 256 EDID blocks
+	which is the maximum supported by the standard.
+
+- Fill Percentage of Frame:
+
+	can be used to draw only the top X percent
+	of the image. Since each frame has to be drawn by the driver, this
+	demands a lot of the CPU. For large resolutions this becomes
+	problematic. By drawing only part of the image this CPU load can
+	be reduced.
+
+
+Output Feature Selection Controls
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+These controls are all specific to video output.
+
+- Enable Output Cropping:
+
+	enables crop support. This control is only present if
+	the ccs_out_mode module option is set to the default value of -1 and if
+	the no_error_inj module option is set to 0 (the default).
+
+- Enable Output Composing:
+
+	enables composing support. This control is only
+	present if the ccs_out_mode module option is set to the default value of
+	-1 and if the no_error_inj module option is set to 0 (the default).
+
+- Enable Output Scaler:
+
+	enables support for a scaler (maximum 4 times upscaling
+	and downscaling). This control is only present if the ccs_out_mode
+	module option is set to the default value of -1 and if the no_error_inj
+	module option is set to 0 (the default).
+
+
+Error Injection Controls
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following two controls are only valid for video and vbi capture.
+
+- Standard Signal Mode:
+
+	selects the behavior of VIDIOC_QUERYSTD: what should it return?
+
+	Changing this control will result in the V4L2_EVENT_SOURCE_CHANGE
+	to be sent since it emulates a changed input condition (e.g. a cable
+	was plugged in or out).
+
+- Standard:
+
+	selects the standard that VIDIOC_QUERYSTD should return if the
+	previous control is set to "Selected Standard".
+
+	Changing this control will result in the V4L2_EVENT_SOURCE_CHANGE
+	to be sent since it emulates a changed input standard.
+
+
+The following two controls are only valid for video capture.
+
+- DV Timings Signal Mode:
+
+	selects the behavior of VIDIOC_QUERY_DV_TIMINGS: what
+	should it return?
+
+	Changing this control will result in the V4L2_EVENT_SOURCE_CHANGE
+	to be sent since it emulates a changed input condition (e.g. a cable
+	was plugged in or out).
+
+- DV Timings:
+
+	selects the timings the VIDIOC_QUERY_DV_TIMINGS should return
+	if the previous control is set to "Selected DV Timings".
+
+	Changing this control will result in the V4L2_EVENT_SOURCE_CHANGE
+	to be sent since it emulates changed input timings.
+
+
+The following controls are only present if the no_error_inj module option
+is set to 0 (the default). These controls are valid for video and vbi
+capture and output streams and for the SDR capture device except for the
+Disconnect control which is valid for all devices.
+
+- Wrap Sequence Number:
+
+	test what happens when you wrap the sequence number in
+	struct v4l2_buffer around.
+
+- Wrap Timestamp:
+
+	test what happens when you wrap the timestamp in struct
+	v4l2_buffer around.
+
+- Percentage of Dropped Buffers:
+
+	sets the percentage of buffers that
+	are never returned by the driver (i.e., they are dropped).
+
+- Disconnect:
+
+	emulates a USB disconnect. The device will act as if it has
+	been disconnected. Only after all open filehandles to the device
+	node have been closed will the device become 'connected' again.
+
+- Inject V4L2_BUF_FLAG_ERROR:
+
+	when pressed, the next frame returned by
+	the driver will have the error flag set (i.e. the frame is marked
+	corrupt).
+
+- Inject VIDIOC_REQBUFS Error:
+
+	when pressed, the next REQBUFS or CREATE_BUFS
+	ioctl call will fail with an error. To be precise: the videobuf2
+	queue_setup() op will return -EINVAL.
+
+- Inject VIDIOC_QBUF Error:
+
+	when pressed, the next VIDIOC_QBUF or
+	VIDIOC_PREPARE_BUFFER ioctl call will fail with an error. To be
+	precise: the videobuf2 buf_prepare() op will return -EINVAL.
+
+- Inject VIDIOC_STREAMON Error:
+
+	when pressed, the next VIDIOC_STREAMON ioctl
+	call will fail with an error. To be precise: the videobuf2
+	start_streaming() op will return -EINVAL.
+
+- Inject Fatal Streaming Error:
+
+	when pressed, the streaming core will be
+	marked as having suffered a fatal error, the only way to recover
+	from that is to stop streaming. To be precise: the videobuf2
+	vb2_queue_error() function is called.
+
+
+VBI Raw Capture Controls
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+- Interlaced VBI Format:
+
+	if set, then the raw VBI data will be interlaced instead
+	of providing it grouped by field.
+
+
+Digital Video Controls
+~~~~~~~~~~~~~~~~~~~~~~
+
+- Rx RGB Quantization Range:
+
+	sets the RGB quantization detection of the HDMI
+	input. This combines with the Vivid 'Limited RGB Range (16-235)'
+	control and can be used to test what happens if a source provides
+	you with the wrong quantization range information. This can be tested
+	by selecting an HDMI input, setting this control to Full or Limited
+	range and selecting the opposite in the 'Limited RGB Range (16-235)'
+	control. The effect is easy to see if the 'Gray Ramp' test pattern
+	is selected.
+
+- Tx RGB Quantization Range:
+
+	sets the RGB quantization detection of the HDMI
+	output. It is currently not used for anything in vivid, but most HDMI
+	transmitters would typically have this control.
+
+- Transmit Mode:
+
+	sets the transmit mode of the HDMI output to HDMI or DVI-D. This
+	affects the reported colorspace since DVI_D outputs will always use
+	sRGB.
+
+- Display Present:
+
+	sets the presence of a "display" on the HDMI output. This affects
+	the tx_edid_present, tx_hotplug and tx_rxsense controls.
+
+
+FM Radio Receiver Controls
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+- RDS Reception:
+
+	set if the RDS receiver should be enabled.
+
+- RDS Program Type:
+
+
+- RDS PS Name:
+
+
+- RDS Radio Text:
+
+
+- RDS Traffic Announcement:
+
+
+- RDS Traffic Program:
+
+
+- RDS Music:
+
+	these are all read-only controls. If RDS Rx I/O Mode is set to
+	"Block I/O", then they are inactive as well. If RDS Rx I/O Mode is set
+	to "Controls", then these controls report the received RDS data.
+
+.. note::
+	The vivid implementation of this is pretty basic: they are only
+	updated when you set a new frequency or when you get the tuner status
+	(VIDIOC_G_TUNER).
+
+- Radio HW Seek Mode:
+
+	can be one of "Bounded", "Wrap Around" or "Both". This
+	determines if VIDIOC_S_HW_FREQ_SEEK will be bounded by the frequency
+	range or wrap-around or if it is selectable by the user.
+
+- Radio Programmable HW Seek:
+
+	if set, then the user can provide the lower and
+	upper bound of the HW Seek. Otherwise the frequency range boundaries
+	will be used.
+
+- Generate RBDS Instead of RDS:
+
+	if set, then generate RBDS (the US variant of
+	RDS) data instead of RDS (European-style RDS). This affects only the
+	PICODE and PTY codes.
+
+- RDS Rx I/O Mode:
+
+	this can be "Block I/O" where the RDS blocks have to be read()
+	by the application, or "Controls" where the RDS data is provided by
+	the RDS controls mentioned above.
+
+
+FM Radio Modulator Controls
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+- RDS Program ID:
+
+
+- RDS Program Type:
+
+
+- RDS PS Name:
+
+
+- RDS Radio Text:
+
+
+- RDS Stereo:
+
+
+- RDS Artificial Head:
+
+
+- RDS Compressed:
+
+
+- RDS Dynamic PTY:
+
+
+- RDS Traffic Announcement:
+
+
+- RDS Traffic Program:
+
+
+- RDS Music:
+
+	these are all controls that set the RDS data that is transmitted by
+	the FM modulator.
+
+- RDS Tx I/O Mode:
+
+	this can be "Block I/O" where the application has to use write()
+	to pass the RDS blocks to the driver, or "Controls" where the RDS data
+	is Provided by the RDS controls mentioned above.
+
+Metadata Capture Controls
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+- Generate PTS
+
+        if set, then the generated metadata stream contains Presentation timestamp.
+
+- Generate SCR
+
+        if set, then the generated metadata stream contains Source Clock information.
+
+Video, VBI and RDS Looping
+--------------------------
+
+The vivid driver supports looping of video output to video input, VBI output
+to VBI input and RDS output to RDS input. For video/VBI looping this emulates
+as if a cable was hooked up between the output and input connector. So video
+and VBI looping is only supported between S-Video and HDMI inputs and outputs.
+VBI is only valid for S-Video as it makes no sense for HDMI.
+
+Since radio is wireless this looping always happens if the radio receiver
+frequency is close to the radio transmitter frequency. In that case the radio
+transmitter will 'override' the emulated radio stations.
+
+Looping is currently supported only between devices created by the same
+vivid driver instance.
+
+
+Video and Sliced VBI looping
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The way to enable video/VBI looping is currently fairly crude. A 'Loop Video'
+control is available in the "Vivid" control class of the video
+capture and VBI capture devices. When checked the video looping will be enabled.
+Once enabled any video S-Video or HDMI input will show a static test pattern
+until the video output has started. At that time the video output will be
+looped to the video input provided that:
+
+- the input type matches the output type. So the HDMI input cannot receive
+  video from the S-Video output.
+
+- the video resolution of the video input must match that of the video output.
+  So it is not possible to loop a 50 Hz (720x576) S-Video output to a 60 Hz
+  (720x480) S-Video input, or a 720p60 HDMI output to a 1080p30 input.
+
+- the pixel formats must be identical on both sides. Otherwise the driver would
+  have to do pixel format conversion as well, and that's taking things too far.
+
+- the field settings must be identical on both sides. Same reason as above:
+  requiring the driver to convert from one field format to another complicated
+  matters too much. This also prohibits capturing with 'Field Top' or 'Field
+  Bottom' when the output video is set to 'Field Alternate'. This combination,
+  while legal, became too complicated to support. Both sides have to be 'Field
+  Alternate' for this to work. Also note that for this specific case the
+  sequence and field counting in struct v4l2_buffer on the capture side may not
+  be 100% accurate.
+
+- field settings V4L2_FIELD_SEQ_TB/BT are not supported. While it is possible to
+  implement this, it would mean a lot of work to get this right. Since these
+  field values are rarely used the decision was made not to implement this for
+  now.
+
+- on the input side the "Standard Signal Mode" for the S-Video input or the
+  "DV Timings Signal Mode" for the HDMI input should be configured so that a
+  valid signal is passed to the video input.
+
+The framerates do not have to match, although this might change in the future.
+
+By default you will see the OSD text superimposed on top of the looped video.
+This can be turned off by changing the "OSD Text Mode" control of the video
+capture device.
+
+For VBI looping to work all of the above must be valid and in addition the vbi
+output must be configured for sliced VBI. The VBI capture side can be configured
+for either raw or sliced VBI. Note that at the moment only CC/XDS (60 Hz formats)
+and WSS (50 Hz formats) VBI data is looped. Teletext VBI data is not looped.
+
+
+Radio & RDS Looping
+~~~~~~~~~~~~~~~~~~~
+
+As mentioned in section 6 the radio receiver emulates stations are regular
+frequency intervals. Depending on the frequency of the radio receiver a
+signal strength value is calculated (this is returned by VIDIOC_G_TUNER).
+However, it will also look at the frequency set by the radio transmitter and
+if that results in a higher signal strength than the settings of the radio
+transmitter will be used as if it was a valid station. This also includes
+the RDS data (if any) that the transmitter 'transmits'. This is received
+faithfully on the receiver side. Note that when the driver is loaded the
+frequencies of the radio receiver and transmitter are not identical, so
+initially no looping takes place.
+
+
+Cropping, Composing, Scaling
+----------------------------
+
+This driver supports cropping, composing and scaling in any combination. Normally
+which features are supported can be selected through the Vivid controls,
+but it is also possible to hardcode it when the module is loaded through the
+ccs_cap_mode and ccs_out_mode module options. See section 1 on the details of
+these module options.
+
+This allows you to test your application for all these variations.
+
+Note that the webcam input never supports cropping, composing or scaling. That
+only applies to the TV/S-Video/HDMI inputs and outputs. The reason is that
+webcams, including this virtual implementation, normally use
+VIDIOC_ENUM_FRAMESIZES to list a set of discrete framesizes that it supports.
+And that does not combine with cropping, composing or scaling. This is
+primarily a limitation of the V4L2 API which is carefully reproduced here.
+
+The minimum and maximum resolutions that the scaler can achieve are 16x16 and
+(4096 * 4) x (2160 x 4), but it can only scale up or down by a factor of 4 or
+less. So for a source resolution of 1280x720 the minimum the scaler can do is
+320x180 and the maximum is 5120x2880. You can play around with this using the
+qv4l2 test tool and you will see these dependencies.
+
+This driver also supports larger 'bytesperline' settings, something that
+VIDIOC_S_FMT allows but that few drivers implement.
+
+The scaler is a simple scaler that uses the Coarse Bresenham algorithm. It's
+designed for speed and simplicity, not quality.
+
+If the combination of crop, compose and scaling allows it, then it is possible
+to change crop and compose rectangles on the fly.
+
+
+Formats
+-------
+
+The driver supports all the regular packed and planar 4:4:4, 4:2:2 and 4:2:0
+YUYV formats, 8, 16, 24 and 32 RGB packed formats and various multiplanar
+formats.
+
+The alpha component can be set through the 'Alpha Component' User control
+for those formats that support it. If the 'Apply Alpha To Red Only' control
+is set, then the alpha component is only used for the color red and set to
+0 otherwise.
+
+The driver has to be configured to support the multiplanar formats. By default
+the driver instances are single-planar. This can be changed by setting the
+multiplanar module option, see section 1 for more details on that option.
+
+If the driver instance is using the multiplanar formats/API, then the first
+single planar format (YUYV) and the multiplanar NV16M and NV61M formats the
+will have a plane that has a non-zero data_offset of 128 bytes. It is rare for
+data_offset to be non-zero, so this is a useful feature for testing applications.
+
+Video output will also honor any data_offset that the application set.
+
+
+Capture Overlay
+---------------
+
+Note: capture overlay support is implemented primarily to test the existing
+V4L2 capture overlay API. In practice few if any GPUs support such overlays
+anymore, and neither are they generally needed anymore since modern hardware
+is so much more capable. By setting flag 0x10000 in the node_types module
+option the vivid driver will create a simple framebuffer device that can be
+used for testing this API. Whether this API should be used for new drivers is
+questionable.
+
+This driver has support for a destructive capture overlay with bitmap clipping
+and list clipping (up to 16 rectangles) capabilities. Overlays are not
+supported for multiplanar formats. It also honors the struct v4l2_window field
+setting: if it is set to FIELD_TOP or FIELD_BOTTOM and the capture setting is
+FIELD_ALTERNATE, then only the top or bottom fields will be copied to the overlay.
+
+The overlay only works if you are also capturing at that same time. This is a
+vivid limitation since it copies from a buffer to the overlay instead of
+filling the overlay directly. And if you are not capturing, then no buffers
+are available to fill.
+
+In addition, the pixelformat of the capture format and that of the framebuffer
+must be the same for the overlay to work. Otherwise VIDIOC_OVERLAY will return
+an error.
+
+In order to really see what it going on you will need to create two vivid
+instances: the first with a framebuffer enabled. You configure the capture
+overlay of the second instance to use the framebuffer of the first, then
+you start capturing in the second instance. For the first instance you setup
+the output overlay for the video output, turn on video looping and capture
+to see the blended framebuffer overlay that's being written to by the second
+instance. This setup would require the following commands:
+
+.. code-block:: none
+
+	$ sudo modprobe vivid n_devs=2 node_types=0x10101,0x1
+	$ v4l2-ctl -d1 --find-fb
+	/dev/fb1 is the framebuffer associated with base address 0x12800000
+	$ sudo v4l2-ctl -d2 --set-fbuf fb=1
+	$ v4l2-ctl -d1 --set-fbuf fb=1
+	$ v4l2-ctl -d0 --set-fmt-video=pixelformat='AR15'
+	$ v4l2-ctl -d1 --set-fmt-video-out=pixelformat='AR15'
+	$ v4l2-ctl -d2 --set-fmt-video=pixelformat='AR15'
+	$ v4l2-ctl -d0 -i2
+	$ v4l2-ctl -d2 -i2
+	$ v4l2-ctl -d2 -c horizontal_movement=4
+	$ v4l2-ctl -d1 --overlay=1
+	$ v4l2-ctl -d1 -c loop_video=1
+	$ v4l2-ctl -d2 --stream-mmap --overlay=1
+
+And from another console:
+
+.. code-block:: none
+
+	$ v4l2-ctl -d1 --stream-out-mmap
+
+And yet another console:
+
+.. code-block:: none
+
+	$ qv4l2
+
+and start streaming.
+
+As you can see, this is not for the faint of heart...
+
+
+Output Overlay
+--------------
+
+Note: output overlays are primarily implemented in order to test the existing
+V4L2 output overlay API. Whether this API should be used for new drivers is
+questionable.
+
+This driver has support for an output overlay and is capable of:
+
+	- bitmap clipping,
+	- list clipping (up to 16 rectangles)
+	- chromakey
+	- source chromakey
+	- global alpha
+	- local alpha
+	- local inverse alpha
+
+Output overlays are not supported for multiplanar formats. In addition, the
+pixelformat of the capture format and that of the framebuffer must be the
+same for the overlay to work. Otherwise VIDIOC_OVERLAY will return an error.
+
+Output overlays only work if the driver has been configured to create a
+framebuffer by setting flag 0x10000 in the node_types module option. The
+created framebuffer has a size of 720x576 and supports ARGB 1:5:5:5 and
+RGB 5:6:5.
+
+In order to see the effects of the various clipping, chromakeying or alpha
+processing capabilities you need to turn on video looping and see the results
+on the capture side. The use of the clipping, chromakeying or alpha processing
+capabilities will slow down the video loop considerably as a lot of checks have
+to be done per pixel.
+
+
+CEC (Consumer Electronics Control)
+----------------------------------
+
+If there are HDMI inputs then a CEC adapter will be created that has
+the same number of input ports. This is the equivalent of e.g. a TV that
+has that number of inputs. Each HDMI output will also create a
+CEC adapter that is hooked up to the corresponding input port, or (if there
+are more outputs than inputs) is not hooked up at all. In other words,
+this is the equivalent of hooking up each output device to an input port of
+the TV. Any remaining output devices remain unconnected.
+
+The EDID that each output reads reports a unique CEC physical address that is
+based on the physical address of the EDID of the input. So if the EDID of the
+receiver has physical address A.B.0.0, then each output will see an EDID
+containing physical address A.B.C.0 where C is 1 to the number of inputs. If
+there are more outputs than inputs then the remaining outputs have a CEC adapter
+that is disabled and reports an invalid physical address.
+
+
+Some Future Improvements
+------------------------
+
+Just as a reminder and in no particular order:
+
+- Add a virtual alsa driver to test audio
+- Add virtual sub-devices and media controller support
+- Some support for testing compressed video
+- Add support to loop raw VBI output to raw VBI input
+- Add support to loop teletext sliced VBI output to VBI input
+- Fix sequence/field numbering when looping of video with alternate fields
+- Add support for V4L2_CID_BG_COLOR for video outputs
+- Add ARGB888 overlay support: better testing of the alpha channel
+- Improve pixel aspect support in the tpg code by passing a real v4l2_fract
+- Use per-queue locks and/or per-device locks to improve throughput
+- Add support to loop from a specific output to a specific input across
+  vivid instances
+- The SDR radio should use the same 'frequencies' for stations as the normal
+  radio receiver, and give back noise if the frequency doesn't match up with
+  a station frequency
+- Make a thread for the RDS generation, that would help in particular for the
+  "Controls" RDS Rx I/O Mode as the read-only RDS controls could be updated
+  in real-time.
+- Changing the EDID should cause hotplug detect emulation to happen.
diff --git a/Documentation/admin-guide/media/zr364xx.rst b/Documentation/admin-guide/media/zr364xx.rst
new file mode 100644
index 000000000000..7291e54b8be3
--- /dev/null
+++ b/Documentation/admin-guide/media/zr364xx.rst
@@ -0,0 +1,102 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Zoran 364xx based USB webcam module
+===================================
+
+site: http://royale.zerezo.com/zr364xx/
+
+mail: royale@zerezo.com
+
+
+Introduction
+------------
+
+
+This brings support under Linux for the Aiptek PocketDV 3300 and similar
+devices in webcam mode. If you just want to get on your PC the pictures
+and movies on the camera, you should use the usb-storage module instead.
+
+The driver works with several other cameras in webcam mode (see the list
+below).
+
+Possible chipsets are : ZR36430 (ZR36430BGC) and
+maybe ZR36431, ZR36440, ZR36442...
+
+You can try the experience changing the vendor/product ID values (look
+at the source code).
+
+You can get these values by looking at /var/log/messages when you plug
+your camera, or by typing : cat /sys/kernel/debug/usb/devices.
+
+
+Install
+-------
+
+In order to use this driver, you must compile it with your kernel,
+with the following config options::
+
+    ./scripts/config -e USB
+    ./scripts/config -m MEDIA_SUPPORT
+    ./scripts/config -e MEDIA_USB_SUPPORT
+    ./scripts/config -e MEDIA_CAMERA_SUPPORT
+    ./scripts/config -m USB_ZR364XX
+
+Usage
+-----
+
+modprobe zr364xx debug=X mode=Y
+
+- debug      : set to 1 to enable verbose debug messages
+- mode       : 0 = 320x240, 1 = 160x120, 2 = 640x480
+
+You can then use the camera with V4L2 compatible applications, for
+example Ekiga.
+
+To capture a single image, try this: dd if=/dev/video0 of=test.jpg bs=1M
+count=1
+
+links
+-----
+
+http://mxhaard.free.fr/ (support for many others cams including some Aiptek PocketDV)
+http://www.harmwal.nl/pccam880/ (this project also supports cameras based on this chipset)
+
+Supported devices
+-----------------
+
+======  =======  ==============  ====================
+Vendor  Product  Distributor     Model
+======  =======  ==============  ====================
+0x08ca  0x0109   Aiptek          PocketDV 3300
+0x08ca  0x0109   Maxell          Maxcam PRO DV3
+0x041e  0x4024   Creative        PC-CAM 880
+0x0d64  0x0108   Aiptek          Fidelity 3200
+0x0d64  0x0108   Praktica        DCZ 1.3 S
+0x0d64  0x0108   Genius          Digital Camera (?)
+0x0d64  0x0108   DXG Technology  Fashion Cam
+0x0546  0x3187   Polaroid        iON 230
+0x0d64  0x3108   Praktica        Exakta DC 2200
+0x0d64  0x3108   Genius          G-Shot D211
+0x0595  0x4343   Concord         Eye-Q Duo 1300
+0x0595  0x4343   Concord         Eye-Q Duo 2000
+0x0595  0x4343   Fujifilm        EX-10
+0x0595  0x4343   Ricoh           RDC-6000
+0x0595  0x4343   Digitrex        DSC 1300
+0x0595  0x4343   Firstline       FDC 2000
+0x0bb0  0x500d   Concord         EyeQ Go Wireless
+0x0feb  0x2004   CRS Electronic  3.3 Digital Camera
+0x0feb  0x2004   Packard Bell    DSC-300
+0x055f  0xb500   Mustek          MDC 3000
+0x08ca  0x2062   Aiptek          PocketDV 5700
+0x052b  0x1a18   Chiphead        Megapix V12
+0x04c8  0x0729   Konica          Revio 2
+0x04f2  0xa208   Creative        PC-CAM 850
+0x0784  0x0040   Traveler        Slimline X5
+0x06d6  0x0034   Trust           Powerc@m 750
+0x0a17  0x0062   Pentax          Optio 50L
+0x06d6  0x003b   Trust           Powerc@m 970Z
+0x0a17  0x004e   Pentax          Optio 50
+0x041e  0x405d   Creative        DiVi CAM 516
+0x08ca  0x2102   Aiptek          DV T300
+0x06d6  0x003d   Trust           Powerc@m 910Z
+======  =======  ==============  ====================
diff --git a/Documentation/admin-guide/sysctl/kernel.rst b/Documentation/admin-guide/sysctl/kernel.rst
index 39c95c0e13d3..0d427fd10941 100644
--- a/Documentation/admin-guide/sysctl/kernel.rst
+++ b/Documentation/admin-guide/sysctl/kernel.rst
@@ -390,9 +390,17 @@ When ``kptr_restrict`` is set to 2, kernel pointers printed using
 modprobe
 ========
 
-This gives the full path of the modprobe command which the kernel will
-use to load modules. This can be used to debug module loading
-requests::
+The full path to the usermode helper for autoloading kernel modules,
+by default "/sbin/modprobe".  This binary is executed when the kernel
+requests a module.  For example, if userspace passes an unknown
+filesystem type to mount(), then the kernel will automatically request
+the corresponding filesystem module by executing this usermode helper.
+This usermode helper should insert the needed module into the kernel.
+
+This sysctl only affects module autoloading.  It has no effect on the
+ability to explicitly insert modules.
+
+This sysctl can be used to debug module loading requests::
 
     echo '#! /bin/sh' > /tmp/modprobe
     echo 'echo "$@" >> /tmp/modprobe.log' >> /tmp/modprobe
@@ -400,10 +408,15 @@ requests::
     chmod a+x /tmp/modprobe
     echo /tmp/modprobe > /proc/sys/kernel/modprobe
 
-This only applies when the *kernel* is requesting that the module be
-loaded; it won't have any effect if the module is being loaded
-explicitly using ``modprobe`` from userspace.
+Alternatively, if this sysctl is set to the empty string, then module
+autoloading is completely disabled.  The kernel will not try to
+execute a usermode helper at all, nor will it call the
+kernel_module_request LSM hook.
 
+If CONFIG_STATIC_USERMODEHELPER=y is set in the kernel configuration,
+then the configured static usermode helper overrides this sysctl,
+except that the empty string is still accepted to completely disable
+module autoloading as described above.
 
 modules_disabled
 ================
@@ -446,28 +459,6 @@ Notes:
      successful IPC object allocation. If an IPC object allocation syscall
      fails, it is undefined if the value remains unmodified or is reset to -1.
 
-modprobe:
-=========
-
-The path to the usermode helper for autoloading kernel modules, by
-default "/sbin/modprobe".  This binary is executed when the kernel
-requests a module.  For example, if userspace passes an unknown
-filesystem type to mount(), then the kernel will automatically request
-the corresponding filesystem module by executing this usermode helper.
-This usermode helper should insert the needed module into the kernel.
-
-This sysctl only affects module autoloading.  It has no effect on the
-ability to explicitly insert modules.
-
-If this sysctl is set to the empty string, then module autoloading is
-completely disabled.  The kernel will not try to execute a usermode
-helper at all, nor will it call the kernel_module_request LSM hook.
-
-If CONFIG_STATIC_USERMODEHELPER=y is set in the kernel configuration,
-then the configured static usermode helper overrides this sysctl,
-except that the empty string is still accepted to completely disable
-module autoloading as described above.
-
 nmi_watchdog
 ============
 
diff --git a/Documentation/atomic_t.txt b/Documentation/atomic_t.txt
index 0ab747e0d5ac..0f1fdedf36bb 100644
--- a/Documentation/atomic_t.txt
+++ b/Documentation/atomic_t.txt
@@ -85,21 +85,21 @@ smp_store_release() respectively. Therefore, if you find yourself only using
 the Non-RMW operations of atomic_t, you do not in fact need atomic_t at all
 and are doing it wrong.
 
-A subtle detail of atomic_set{}() is that it should be observable to the RMW
-ops. That is:
+A note for the implementation of atomic_set{}() is that it must not break the
+atomicity of the RMW ops. That is:
 
-  C atomic-set
+  C Atomic-RMW-ops-are-atomic-WRT-atomic_set
 
   {
-    atomic_set(v, 1);
+    atomic_t v = ATOMIC_INIT(1);
   }
 
-  P1(atomic_t *v)
+  P0(atomic_t *v)
   {
-    atomic_add_unless(v, 1, 0);
+    (void)atomic_add_unless(v, 1, 0);
   }
 
-  P2(atomic_t *v)
+  P1(atomic_t *v)
   {
     atomic_set(v, 0);
   }
@@ -233,19 +233,19 @@ as well. Similarly, something like:
 is an ACQUIRE pattern (though very much not typical), but again the barrier is
 strictly stronger than ACQUIRE. As illustrated:
 
-  C strong-acquire
+  C Atomic-RMW+mb__after_atomic-is-stronger-than-acquire
 
   {
   }
 
-  P1(int *x, atomic_t *y)
+  P0(int *x, atomic_t *y)
   {
     r0 = READ_ONCE(*x);
     smp_rmb();
     r1 = atomic_read(y);
   }
 
-  P2(int *x, atomic_t *y)
+  P1(int *x, atomic_t *y)
   {
     atomic_inc(y);
     smp_mb__after_atomic();
@@ -253,14 +253,14 @@ strictly stronger than ACQUIRE. As illustrated:
   }
 
   exists
-  (r0=1 /\ r1=0)
+  (0:r0=1 /\ 0:r1=0)
 
 This should not happen; but a hypothetical atomic_inc_acquire() --
 (void)atomic_fetch_inc_acquire() for instance -- would allow the outcome,
 because it would not order the W part of the RMW against the following
 WRITE_ONCE.  Thus:
 
-  P1			P2
+  P0			P1
 
 			t = LL.acq *y (0)
 			t++;
diff --git a/Documentation/core-api/timekeeping.rst b/Documentation/core-api/timekeeping.rst
index c0ffa30c7c37..729e24864fe7 100644
--- a/Documentation/core-api/timekeeping.rst
+++ b/Documentation/core-api/timekeeping.rst
@@ -154,9 +154,9 @@ architectures. These are the recommended replacements:
 
 	Use ktime_get() or ktime_get_ts64() instead.
 
-.. c:function:: struct timeval do_gettimeofday( void )
-		struct timespec getnstimeofday( void )
-		struct timespec64 getnstimeofday64( void )
+.. c:function:: void do_gettimeofday( struct timeval * )
+		void getnstimeofday( struct timespec * )
+		void getnstimeofday64( struct timespec64 * )
 		void ktime_get_real_ts( struct timespec * )
 
 	ktime_get_real_ts64() is a direct replacement, but consider using
diff --git a/Documentation/core-api/xarray.rst b/Documentation/core-api/xarray.rst
index 640934b6f7b4..62f62540bea2 100644
--- a/Documentation/core-api/xarray.rst
+++ b/Documentation/core-api/xarray.rst
@@ -390,12 +390,13 @@ The xas_create_range() function allocates all the necessary memory
 to store every entry in a range.  It will set ENOMEM in the xa_state if
 it cannot allocate memory.
 
-You can use xas_init_marks() to reset the marks on an entry
-to their default state.  This is usually all marks clear, unless the
-XArray is marked with ``XA_FLAGS_TRACK_FREE``, in which case mark 0 is set
-and all other marks are clear.  Replacing one entry with another using
-xas_store() will not reset the marks on that entry; if you want
-the marks reset, you should do that explicitly.
+You can use xas_init_marks() to reset the marks on an entry to their
+default state.  This is usually all marks clear, unless the XArray is
+marked with ``XA_FLAGS_TRACK_FREE``, in which case mark 0 is set and all
+other marks are clear.  Replacing one entry with another using xas_store()
+will not reset the marks on that entry; if you want the marks reset, you
+should do that explicitly.  If you know that the marks are initialised,
+you can use __xas_store() when storing ``NULL``.
 
 The xas_load() will walk the xa_state as close to the entry
 as it can.  If you know the xa_state has already been walked to the
diff --git a/Documentation/dev-tools/index.rst b/Documentation/dev-tools/index.rst
index 09dee10d2592..f7809c7b1ba9 100644
--- a/Documentation/dev-tools/index.rst
+++ b/Documentation/dev-tools/index.rst
@@ -21,6 +21,7 @@ whole; patches welcome!
    kasan
    ubsan
    kmemleak
+   kcsan
    gdb-kernel-debugging
    kgdb
    kselftest
diff --git a/Documentation/dev-tools/kcov.rst b/Documentation/dev-tools/kcov.rst
index 1c4e1825d769..8548b0b04e43 100644
--- a/Documentation/dev-tools/kcov.rst
+++ b/Documentation/dev-tools/kcov.rst
@@ -217,14 +217,15 @@ This allows to collect coverage from two types of kernel background
 threads: the global ones, that are spawned during kernel boot in a limited
 number of instances (e.g. one USB hub_event() worker thread is spawned per
 USB HCD); and the local ones, that are spawned when a user interacts with
-some kernel interface (e.g. vhost workers).
+some kernel interface (e.g. vhost workers); as well as from soft
+interrupts.
 
-To enable collecting coverage from a global background thread, a unique
-global handle must be assigned and passed to the corresponding
-kcov_remote_start() call. Then a userspace process can pass a list of such
-handles to the KCOV_REMOTE_ENABLE ioctl in the handles array field of the
-kcov_remote_arg struct. This will attach the used kcov device to the code
-sections, that are referenced by those handles.
+To enable collecting coverage from a global background thread or from a
+softirq, a unique global handle must be assigned and passed to the
+corresponding kcov_remote_start() call. Then a userspace process can pass
+a list of such handles to the KCOV_REMOTE_ENABLE ioctl in the handles
+array field of the kcov_remote_arg struct. This will attach the used kcov
+device to the code sections, that are referenced by those handles.
 
 Since there might be many local background threads spawned from different
 userspace processes, we can't use a single global handle per annotation.
@@ -242,7 +243,7 @@ handles as they don't belong to a particular subsystem. The bytes 4-7 are
 currently reserved and must be zero. In the future the number of bytes
 used for the subsystem or handle ids might be increased.
 
-When a particular userspace proccess collects coverage by via a common
+When a particular userspace proccess collects coverage via a common
 handle, kcov will collect coverage for each code section that is annotated
 to use the common handle obtained as kcov_handle from the current
 task_struct. However non common handles allow to collect coverage
diff --git a/Documentation/dev-tools/kcsan.rst b/Documentation/dev-tools/kcsan.rst
new file mode 100644
index 000000000000..f4b5766f12cc
--- /dev/null
+++ b/Documentation/dev-tools/kcsan.rst
@@ -0,0 +1,328 @@
+The Kernel Concurrency Sanitizer (KCSAN)
+========================================
+
+The Kernel Concurrency Sanitizer (KCSAN) is a dynamic race detector, which
+relies on compile-time instrumentation, and uses a watchpoint-based sampling
+approach to detect races. KCSAN's primary purpose is to detect `data races`_.
+
+Usage
+-----
+
+KCSAN is supported in both GCC and Clang. With GCC it requires version 7.3.0 or
+later. With Clang it requires version 7.0.0 or later.
+
+To enable KCSAN configure the kernel with::
+
+    CONFIG_KCSAN = y
+
+KCSAN provides several other configuration options to customize behaviour (see
+the respective help text in ``lib/Kconfig.kcsan`` for more info).
+
+Error reports
+~~~~~~~~~~~~~
+
+A typical data race report looks like this::
+
+    ==================================================================
+    BUG: KCSAN: data-race in generic_permission / kernfs_refresh_inode
+
+    write to 0xffff8fee4c40700c of 4 bytes by task 175 on cpu 4:
+     kernfs_refresh_inode+0x70/0x170
+     kernfs_iop_permission+0x4f/0x90
+     inode_permission+0x190/0x200
+     link_path_walk.part.0+0x503/0x8e0
+     path_lookupat.isra.0+0x69/0x4d0
+     filename_lookup+0x136/0x280
+     user_path_at_empty+0x47/0x60
+     vfs_statx+0x9b/0x130
+     __do_sys_newlstat+0x50/0xb0
+     __x64_sys_newlstat+0x37/0x50
+     do_syscall_64+0x85/0x260
+     entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+    read to 0xffff8fee4c40700c of 4 bytes by task 166 on cpu 6:
+     generic_permission+0x5b/0x2a0
+     kernfs_iop_permission+0x66/0x90
+     inode_permission+0x190/0x200
+     link_path_walk.part.0+0x503/0x8e0
+     path_lookupat.isra.0+0x69/0x4d0
+     filename_lookup+0x136/0x280
+     user_path_at_empty+0x47/0x60
+     do_faccessat+0x11a/0x390
+     __x64_sys_access+0x3c/0x50
+     do_syscall_64+0x85/0x260
+     entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+    Reported by Kernel Concurrency Sanitizer on:
+    CPU: 6 PID: 166 Comm: systemd-journal Not tainted 5.3.0-rc7+ #1
+    Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014
+    ==================================================================
+
+The header of the report provides a short summary of the functions involved in
+the race. It is followed by the access types and stack traces of the 2 threads
+involved in the data race.
+
+The other less common type of data race report looks like this::
+
+    ==================================================================
+    BUG: KCSAN: data-race in e1000_clean_rx_irq+0x551/0xb10
+
+    race at unknown origin, with read to 0xffff933db8a2ae6c of 1 bytes by interrupt on cpu 0:
+     e1000_clean_rx_irq+0x551/0xb10
+     e1000_clean+0x533/0xda0
+     net_rx_action+0x329/0x900
+     __do_softirq+0xdb/0x2db
+     irq_exit+0x9b/0xa0
+     do_IRQ+0x9c/0xf0
+     ret_from_intr+0x0/0x18
+     default_idle+0x3f/0x220
+     arch_cpu_idle+0x21/0x30
+     do_idle+0x1df/0x230
+     cpu_startup_entry+0x14/0x20
+     rest_init+0xc5/0xcb
+     arch_call_rest_init+0x13/0x2b
+     start_kernel+0x6db/0x700
+
+    Reported by Kernel Concurrency Sanitizer on:
+    CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.3.0-rc7+ #2
+    Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014
+    ==================================================================
+
+This report is generated where it was not possible to determine the other
+racing thread, but a race was inferred due to the data value of the watched
+memory location having changed. These can occur either due to missing
+instrumentation or e.g. DMA accesses. These reports will only be generated if
+``CONFIG_KCSAN_REPORT_RACE_UNKNOWN_ORIGIN=y`` (selected by default).
+
+Selective analysis
+~~~~~~~~~~~~~~~~~~
+
+It may be desirable to disable data race detection for specific accesses,
+functions, compilation units, or entire subsystems.  For static blacklisting,
+the below options are available:
+
+* KCSAN understands the ``data_race(expr)`` annotation, which tells KCSAN that
+  any data races due to accesses in ``expr`` should be ignored and resulting
+  behaviour when encountering a data race is deemed safe.
+
+* Disabling data race detection for entire functions can be accomplished by
+  using the function attribute ``__no_kcsan``::
+
+    __no_kcsan
+    void foo(void) {
+        ...
+
+  To dynamically limit for which functions to generate reports, see the
+  `DebugFS interface`_ blacklist/whitelist feature.
+
+  For ``__always_inline`` functions, replace ``__always_inline`` with
+  ``__no_kcsan_or_inline`` (which implies ``__always_inline``)::
+
+    static __no_kcsan_or_inline void foo(void) {
+        ...
+
+  Note: Older compiler versions (GCC < 9) also do not always honor the
+  ``__no_kcsan`` attribute on regular ``inline`` functions. If false positives
+  with these compilers cannot be tolerated, for small functions where
+  ``__always_inline`` would be appropriate, ``__no_kcsan_or_inline`` should be
+  preferred instead.
+
+* To disable data race detection for a particular compilation unit, add to the
+  ``Makefile``::
+
+    KCSAN_SANITIZE_file.o := n
+
+* To disable data race detection for all compilation units listed in a
+  ``Makefile``, add to the respective ``Makefile``::
+
+    KCSAN_SANITIZE := n
+
+Furthermore, it is possible to tell KCSAN to show or hide entire classes of
+data races, depending on preferences. These can be changed via the following
+Kconfig options:
+
+* ``CONFIG_KCSAN_REPORT_VALUE_CHANGE_ONLY``: If enabled and a conflicting write
+  is observed via a watchpoint, but the data value of the memory location was
+  observed to remain unchanged, do not report the data race.
+
+* ``CONFIG_KCSAN_ASSUME_PLAIN_WRITES_ATOMIC``: Assume that plain aligned writes
+  up to word size are atomic by default. Assumes that such writes are not
+  subject to unsafe compiler optimizations resulting in data races. The option
+  causes KCSAN to not report data races due to conflicts where the only plain
+  accesses are aligned writes up to word size.
+
+DebugFS interface
+~~~~~~~~~~~~~~~~~
+
+The file ``/sys/kernel/debug/kcsan`` provides the following interface:
+
+* Reading ``/sys/kernel/debug/kcsan`` returns various runtime statistics.
+
+* Writing ``on`` or ``off`` to ``/sys/kernel/debug/kcsan`` allows turning KCSAN
+  on or off, respectively.
+
+* Writing ``!some_func_name`` to ``/sys/kernel/debug/kcsan`` adds
+  ``some_func_name`` to the report filter list, which (by default) blacklists
+  reporting data races where either one of the top stackframes are a function
+  in the list.
+
+* Writing either ``blacklist`` or ``whitelist`` to ``/sys/kernel/debug/kcsan``
+  changes the report filtering behaviour. For example, the blacklist feature
+  can be used to silence frequently occurring data races; the whitelist feature
+  can help with reproduction and testing of fixes.
+
+Tuning performance
+~~~~~~~~~~~~~~~~~~
+
+Core parameters that affect KCSAN's overall performance and bug detection
+ability are exposed as kernel command-line arguments whose defaults can also be
+changed via the corresponding Kconfig options.
+
+* ``kcsan.skip_watch`` (``CONFIG_KCSAN_SKIP_WATCH``): Number of per-CPU memory
+  operations to skip, before another watchpoint is set up. Setting up
+  watchpoints more frequently will result in the likelihood of races to be
+  observed to increase. This parameter has the most significant impact on
+  overall system performance and race detection ability.
+
+* ``kcsan.udelay_task`` (``CONFIG_KCSAN_UDELAY_TASK``): For tasks, the
+  microsecond delay to stall execution after a watchpoint has been set up.
+  Larger values result in the window in which we may observe a race to
+  increase.
+
+* ``kcsan.udelay_interrupt`` (``CONFIG_KCSAN_UDELAY_INTERRUPT``): For
+  interrupts, the microsecond delay to stall execution after a watchpoint has
+  been set up. Interrupts have tighter latency requirements, and their delay
+  should generally be smaller than the one chosen for tasks.
+
+They may be tweaked at runtime via ``/sys/module/kcsan/parameters/``.
+
+Data Races
+----------
+
+In an execution, two memory accesses form a *data race* if they *conflict*,
+they happen concurrently in different threads, and at least one of them is a
+*plain access*; they *conflict* if both access the same memory location, and at
+least one is a write. For a more thorough discussion and definition, see `"Plain
+Accesses and Data Races" in the LKMM`_.
+
+.. _"Plain Accesses and Data Races" in the LKMM: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/memory-model/Documentation/explanation.txt#n1922
+
+Relationship with the Linux-Kernel Memory Consistency Model (LKMM)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The LKMM defines the propagation and ordering rules of various memory
+operations, which gives developers the ability to reason about concurrent code.
+Ultimately this allows to determine the possible executions of concurrent code,
+and if that code is free from data races.
+
+KCSAN is aware of *marked atomic operations* (``READ_ONCE``, ``WRITE_ONCE``,
+``atomic_*``, etc.), but is oblivious of any ordering guarantees and simply
+assumes that memory barriers are placed correctly. In other words, KCSAN
+assumes that as long as a plain access is not observed to race with another
+conflicting access, memory operations are correctly ordered.
+
+This means that KCSAN will not report *potential* data races due to missing
+memory ordering. Developers should therefore carefully consider the required
+memory ordering requirements that remain unchecked. If, however, missing
+memory ordering (that is observable with a particular compiler and
+architecture) leads to an observable data race (e.g. entering a critical
+section erroneously), KCSAN would report the resulting data race.
+
+Race Detection Beyond Data Races
+--------------------------------
+
+For code with complex concurrency design, race-condition bugs may not always
+manifest as data races. Race conditions occur if concurrently executing
+operations result in unexpected system behaviour. On the other hand, data races
+are defined at the C-language level. The following macros can be used to check
+properties of concurrent code where bugs would not manifest as data races.
+
+.. kernel-doc:: include/linux/kcsan-checks.h
+    :functions: ASSERT_EXCLUSIVE_WRITER ASSERT_EXCLUSIVE_WRITER_SCOPED
+                ASSERT_EXCLUSIVE_ACCESS ASSERT_EXCLUSIVE_ACCESS_SCOPED
+                ASSERT_EXCLUSIVE_BITS
+
+Implementation Details
+----------------------
+
+KCSAN relies on observing that two accesses happen concurrently. Crucially, we
+want to (a) increase the chances of observing races (especially for races that
+manifest rarely), and (b) be able to actually observe them. We can accomplish
+(a) by injecting various delays, and (b) by using address watchpoints (or
+breakpoints).
+
+If we deliberately stall a memory access, while we have a watchpoint for its
+address set up, and then observe the watchpoint to fire, two accesses to the
+same address just raced. Using hardware watchpoints, this is the approach taken
+in `DataCollider
+<http://usenix.org/legacy/events/osdi10/tech/full_papers/Erickson.pdf>`_.
+Unlike DataCollider, KCSAN does not use hardware watchpoints, but instead
+relies on compiler instrumentation and "soft watchpoints".
+
+In KCSAN, watchpoints are implemented using an efficient encoding that stores
+access type, size, and address in a long; the benefits of using "soft
+watchpoints" are portability and greater flexibility. KCSAN then relies on the
+compiler instrumenting plain accesses. For each instrumented plain access:
+
+1. Check if a matching watchpoint exists; if yes, and at least one access is a
+   write, then we encountered a racing access.
+
+2. Periodically, if no matching watchpoint exists, set up a watchpoint and
+   stall for a small randomized delay.
+
+3. Also check the data value before the delay, and re-check the data value
+   after delay; if the values mismatch, we infer a race of unknown origin.
+
+To detect data races between plain and marked accesses, KCSAN also annotates
+marked accesses, but only to check if a watchpoint exists; i.e. KCSAN never
+sets up a watchpoint on marked accesses. By never setting up watchpoints for
+marked operations, if all accesses to a variable that is accessed concurrently
+are properly marked, KCSAN will never trigger a watchpoint and therefore never
+report the accesses.
+
+Key Properties
+~~~~~~~~~~~~~~
+
+1. **Memory Overhead:**  The overall memory overhead is only a few MiB
+   depending on configuration. The current implementation uses a small array of
+   longs to encode watchpoint information, which is negligible.
+
+2. **Performance Overhead:** KCSAN's runtime aims to be minimal, using an
+   efficient watchpoint encoding that does not require acquiring any shared
+   locks in the fast-path. For kernel boot on a system with 8 CPUs:
+
+   - 5.0x slow-down with the default KCSAN config;
+   - 2.8x slow-down from runtime fast-path overhead only (set very large
+     ``KCSAN_SKIP_WATCH`` and unset ``KCSAN_SKIP_WATCH_RANDOMIZE``).
+
+3. **Annotation Overheads:** Minimal annotations are required outside the KCSAN
+   runtime. As a result, maintenance overheads are minimal as the kernel
+   evolves.
+
+4. **Detects Racy Writes from Devices:** Due to checking data values upon
+   setting up watchpoints, racy writes from devices can also be detected.
+
+5. **Memory Ordering:** KCSAN is *not* explicitly aware of the LKMM's ordering
+   rules; this may result in missed data races (false negatives).
+
+6. **Analysis Accuracy:** For observed executions, due to using a sampling
+   strategy, the analysis is *unsound* (false negatives possible), but aims to
+   be complete (no false positives).
+
+Alternatives Considered
+-----------------------
+
+An alternative data race detection approach for the kernel can be found in the
+`Kernel Thread Sanitizer (KTSAN) <https://github.com/google/ktsan/wiki>`_.
+KTSAN is a happens-before data race detector, which explicitly establishes the
+happens-before order between memory operations, which can then be used to
+determine data races as defined in `Data Races`_.
+
+To build a correct happens-before relation, KTSAN must be aware of all ordering
+rules of the LKMM and synchronization primitives. Unfortunately, any omission
+leads to large numbers of false positives, which is especially detrimental in
+the context of the kernel which includes numerous custom synchronization
+mechanisms. To track the happens-before relation, KTSAN's implementation
+requires metadata for each memory location (shadow memory), which for each page
+corresponds to 4 pages of shadow memory, and can translate into overhead of
+tens of GiB on a large system.
diff --git a/Documentation/devicetree/bindings/arm/altera.yaml b/Documentation/devicetree/bindings/arm/altera.yaml
index 49e0362ddc11..b388c5aa7984 100644
--- a/Documentation/devicetree/bindings/arm/altera.yaml
+++ b/Documentation/devicetree/bindings/arm/altera.yaml
@@ -13,8 +13,8 @@ properties:
   compatible:
     items:
       - enum:
-        - altr,socfpga-cyclone5
-        - altr,socfpga-arria5
-        - altr,socfpga-arria10
+          - altr,socfpga-cyclone5
+          - altr,socfpga-arria5
+          - altr,socfpga-arria10
       - const: altr,socfpga
 ...
diff --git a/Documentation/devicetree/bindings/arm/amlogic/amlogic,meson-gx-ao-secure.yaml b/Documentation/devicetree/bindings/arm/amlogic/amlogic,meson-gx-ao-secure.yaml
index 66213bd95e6e..6cc74523ebfd 100644
--- a/Documentation/devicetree/bindings/arm/amlogic/amlogic,meson-gx-ao-secure.yaml
+++ b/Documentation/devicetree/bindings/arm/amlogic/amlogic,meson-gx-ao-secure.yaml
@@ -25,7 +25,7 @@ select:
 
 properties:
   compatible:
-   items:
+    items:
       - const: amlogic,meson-gx-ao-secure
       - const: syscon
 
diff --git a/Documentation/devicetree/bindings/arm/bitmain.yaml b/Documentation/devicetree/bindings/arm/bitmain.yaml
index 0efdb4ac028e..5cd5b36cff2d 100644
--- a/Documentation/devicetree/bindings/arm/bitmain.yaml
+++ b/Documentation/devicetree/bindings/arm/bitmain.yaml
@@ -13,6 +13,6 @@ properties:
   compatible:
     items:
       - enum:
-        - bitmain,sophon-edge
+          - bitmain,sophon-edge
       - const: bitmain,bm1880
 ...
diff --git a/Documentation/devicetree/bindings/arm/cpus.yaml b/Documentation/devicetree/bindings/arm/cpus.yaml
index a01814765ddb..44791d2b41c1 100644
--- a/Documentation/devicetree/bindings/arm/cpus.yaml
+++ b/Documentation/devicetree/bindings/arm/cpus.yaml
@@ -167,6 +167,7 @@ properties:
       - qcom,kryo260
       - qcom,kryo280
       - qcom,kryo385
+      - qcom,kryo468
       - qcom,kryo485
       - qcom,scorpion
 
diff --git a/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt b/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt
index 623fedf12180..715047444391 100644
--- a/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt
+++ b/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt
@@ -108,7 +108,8 @@ This binding uses the i.MX common pinctrl binding[3].
 Required properties:
 - compatible:		Should be one of:
 			"fsl,imx8qm-iomuxc",
-			"fsl,imx8qxp-iomuxc".
+			"fsl,imx8qxp-iomuxc",
+			"fsl,imx8dxl-iomuxc".
 
 Required properties for Pinctrl sub nodes:
 - fsl,pins:		Each entry consists of 3 integers which represents
@@ -116,7 +117,8 @@ Required properties for Pinctrl sub nodes:
 			integers <pin_id mux_mode> are specified using a
 			PIN_FUNC_ID macro, which can be found in
 			<dt-bindings/pinctrl/pads-imx8qm.h>,
-			<dt-bindings/pinctrl/pads-imx8qxp.h>.
+			<dt-bindings/pinctrl/pads-imx8qxp.h>,
+			<dt-bindings/pinctrl/pads-imx8dxl.h>.
 			The last integer CONFIG is the pad setting value like
 			pull-up on this pin.
 
diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml
index cd3fbe7e3948..1d99f62a02fb 100644
--- a/Documentation/devicetree/bindings/arm/fsl.yaml
+++ b/Documentation/devicetree/bindings/arm/fsl.yaml
@@ -177,7 +177,9 @@ properties:
               - technologic,imx6dl-ts4900
               - technologic,imx6dl-ts7970
               - toradex,colibri_imx6dl          # Colibri iMX6 Module
+              - toradex,colibri_imx6dl-v1_1     # Colibri iMX6 Module V1.1
               - toradex,colibri_imx6dl-eval-v3  # Colibri iMX6 Module on Colibri Evaluation Board V3
+              - toradex,colibri_imx6dl-v1_1-eval-v3 # Colibri iMX6 Module V1.1 on Colibri Evaluation Board V3
               - ysoft,imx6dl-yapp4-draco  # i.MX6 DualLite Y Soft IOTA Draco board
               - ysoft,imx6dl-yapp4-hydra  # i.MX6 DualLite Y Soft IOTA Hydra board
               - ysoft,imx6dl-yapp4-ursa   # i.MX6 Solo Y Soft IOTA Ursa board
diff --git a/Documentation/devicetree/bindings/arm/mediatek.yaml b/Documentation/devicetree/bindings/arm/mediatek.yaml
index 4043c5046441..abc544dde692 100644
--- a/Documentation/devicetree/bindings/arm/mediatek.yaml
+++ b/Documentation/devicetree/bindings/arm/mediatek.yaml
@@ -84,6 +84,28 @@ properties:
           - enum:
               - mediatek,mt8135-evbp1
           - const: mediatek,mt8135
+      - description: Google Elm (Acer Chromebook R13)
+        items:
+          - const: google,elm-rev8
+          - const: google,elm-rev7
+          - const: google,elm-rev6
+          - const: google,elm-rev5
+          - const: google,elm-rev4
+          - const: google,elm-rev3
+          - const: google,elm
+          - const: mediatek,mt8173
+      - description: Google Hana (Lenovo Chromebook N23 Yoga, C330, 300e,...)
+        items:
+          - const: google,hana-rev6
+          - const: google,hana-rev5
+          - const: google,hana-rev4
+          - const: google,hana-rev3
+          - const: google,hana
+          - const: mediatek,mt8173
+      - description: Google Hana rev7 (Poin2 Chromebook 11C)
+        items:
+          - const: google,hana-rev7
+          - const: mediatek,mt8173
       - items:
           - enum:
               - mediatek,mt8173-evb
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
index 301eefbe1618..8d6a9d98e7a6 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
@@ -1,7 +1,8 @@
 Mediatek mmsys controller
 ============================
 
-The Mediatek mmsys controller provides various clocks to the system.
+The Mediatek mmsys system controller provides clock control, routing control,
+and miscellaneous control in mmsys partition.
 
 Required Properties:
 
@@ -15,13 +16,13 @@ Required Properties:
 	- "mediatek,mt8183-mmsys", "syscon"
 - #clock-cells: Must be 1
 
-The mmsys controller uses the common clk binding from
+For the clock control, the mmsys controller uses the common clk binding from
 Documentation/devicetree/bindings/clock/clock-bindings.txt
 The available clocks are defined in dt-bindings/clock/mt*-clk.h.
 
 Example:
 
-mmsys: clock-controller@14000000 {
+mmsys: syscon@14000000 {
 	compatible = "mediatek,mt8173-mmsys", "syscon";
 	reg = <0 0x14000000 0 0x1000>;
 	#clock-cells = <1>;
diff --git a/Documentation/devicetree/bindings/arm/nxp/lpc32xx.yaml b/Documentation/devicetree/bindings/arm/nxp/lpc32xx.yaml
index 07f39d3eee7e..f7f024910e71 100644
--- a/Documentation/devicetree/bindings/arm/nxp/lpc32xx.yaml
+++ b/Documentation/devicetree/bindings/arm/nxp/lpc32xx.yaml
@@ -17,9 +17,8 @@ properties:
           - nxp,lpc3230
           - nxp,lpc3240
       - items:
-        - enum:
-            - ea,ea3250
-            - phytec,phy3250
-        - const: nxp,lpc3250
-
+          - enum:
+              - ea,ea3250
+              - phytec,phy3250
+          - const: nxp,lpc3250
 ...
diff --git a/Documentation/devicetree/bindings/arm/realtek.yaml b/Documentation/devicetree/bindings/arm/realtek.yaml
index ab59de17152d..845f9c76d6f7 100644
--- a/Documentation/devicetree/bindings/arm/realtek.yaml
+++ b/Documentation/devicetree/bindings/arm/realtek.yaml
@@ -14,6 +14,13 @@ properties:
     const: '/'
   compatible:
     oneOf:
+      # RTD1195 SoC based boards
+      - items:
+          - enum:
+              - mele,x1000 # MeLE X1000
+              - realtek,horseradish # Realtek Horseradish EVB
+          - const: realtek,rtd1195
+
       # RTD1293 SoC based boards
       - items:
           - enum:
@@ -25,6 +32,7 @@ properties:
           - enum:
               - mele,v9 # MeLE V9
               - probox2,ava # ProBox2 AVA
+              - xnano,x5 # Xnano X5
               - zidoo,x9s # Zidoo X9S
           - const: realtek,rtd1295
 
@@ -33,4 +41,17 @@ properties:
           - enum:
               - synology,ds418 # Synology DiskStation DS418
           - const: realtek,rtd1296
+
+      # RTD1395 SoC based boards
+      - items:
+          - enum:
+              - bananapi,bpi-m4 # Banana Pi BPI-M4
+              - realtek,lion-skin # Realtek Lion Skin EVB
+          - const: realtek,rtd1395
+
+      # RTD1619 SoC based boards
+      - items:
+          - enum:
+              - realtek,mjolnir # Realtek Mjolnir EVB
+          - const: realtek,rtd1619
 ...
diff --git a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
index 63acd57c4799..eb92f9eefaba 100644
--- a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
+++ b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
@@ -52,6 +52,7 @@ properties:
         items:
           - enum:
               - insignal,origen                 # Insignal Origen
+              - samsung,i9100                   # Samsung Galaxy S2 (GT-I9100)
               - samsung,smdkv310                # Samsung SMDKV310 eval
               - samsung,trats                   # Samsung Tizen Reference
               - samsung,universal_c210          # Samsung C210
diff --git a/Documentation/devicetree/bindings/arm/socionext/uniphier.yaml b/Documentation/devicetree/bindings/arm/socionext/uniphier.yaml
index 65ad6d8a3c99..113f93b9ae55 100644
--- a/Documentation/devicetree/bindings/arm/socionext/uniphier.yaml
+++ b/Documentation/devicetree/bindings/arm/socionext/uniphier.yaml
@@ -17,45 +17,45 @@ properties:
       - description: LD4 SoC boards
         items:
           - enum:
-            - socionext,uniphier-ld4-ref
+              - socionext,uniphier-ld4-ref
           - const: socionext,uniphier-ld4
       - description: Pro4 SoC boards
         items:
           - enum:
-            - socionext,uniphier-pro4-ace
-            - socionext,uniphier-pro4-ref
-            - socionext,uniphier-pro4-sanji
+              - socionext,uniphier-pro4-ace
+              - socionext,uniphier-pro4-ref
+              - socionext,uniphier-pro4-sanji
           - const: socionext,uniphier-pro4
       - description: sLD8 SoC boards
         items:
           - enum:
-            - socionext,uniphier-sld8-ref
+              - socionext,uniphier-sld8-ref
           - const: socionext,uniphier-sld8
       - description: PXs2 SoC boards
         items:
           - enum:
-            - socionext,uniphier-pxs2-gentil
-            - socionext,uniphier-pxs2-vodka
+              - socionext,uniphier-pxs2-gentil
+              - socionext,uniphier-pxs2-vodka
           - const: socionext,uniphier-pxs2
       - description: LD6b SoC boards
         items:
           - enum:
-            - socionext,uniphier-ld6b-ref
+              - socionext,uniphier-ld6b-ref
           - const: socionext,uniphier-ld6b
       - description: LD11 SoC boards
         items:
           - enum:
-            - socionext,uniphier-ld11-global
-            - socionext,uniphier-ld11-ref
+              - socionext,uniphier-ld11-global
+              - socionext,uniphier-ld11-ref
           - const: socionext,uniphier-ld11
       - description: LD20 SoC boards
         items:
           - enum:
-            - socionext,uniphier-ld20-global
-            - socionext,uniphier-ld20-ref
+              - socionext,uniphier-ld20-global
+              - socionext,uniphier-ld20-ref
           - const: socionext,uniphier-ld20
       - description: PXs3 SoC boards
         items:
           - enum:
-            - socionext,uniphier-pxs3-ref
+              - socionext,uniphier-pxs3-ref
           - const: socionext,uniphier-pxs3
diff --git a/Documentation/devicetree/bindings/arm/stm32/st,mlahb.yaml b/Documentation/devicetree/bindings/arm/stm32/st,mlahb.yaml
index 55f7938c4826..9f276bc9efa0 100644
--- a/Documentation/devicetree/bindings/arm/stm32/st,mlahb.yaml
+++ b/Documentation/devicetree/bindings/arm/stm32/st,mlahb.yaml
@@ -20,7 +20,7 @@ description: |
   [2]: https://wiki.st.com/stm32mpu/wiki/STM32MP15_RAM_mapping
 
 allOf:
- - $ref: /schemas/simple-bus.yaml#
+  - $ref: /schemas/simple-bus.yaml#
 
 properties:
   compatible:
diff --git a/Documentation/devicetree/bindings/arm/stm32/st,stm32-syscon.yaml b/Documentation/devicetree/bindings/arm/stm32/st,stm32-syscon.yaml
index baff80197d5a..cf5db5e273f3 100644
--- a/Documentation/devicetree/bindings/arm/stm32/st,stm32-syscon.yaml
+++ b/Documentation/devicetree/bindings/arm/stm32/st,stm32-syscon.yaml
@@ -14,9 +14,9 @@ properties:
   compatible:
     oneOf:
       - items:
-        - enum:
-          - st,stm32mp157-syscfg
-        - const: syscon
+          - enum:
+              - st,stm32mp157-syscfg
+          - const: syscon
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/arm/sunxi.yaml b/Documentation/devicetree/bindings/arm/sunxi.yaml
index abf2d97fb7ae..87817ff0cd35 100644
--- a/Documentation/devicetree/bindings/arm/sunxi.yaml
+++ b/Documentation/devicetree/bindings/arm/sunxi.yaml
@@ -561,6 +561,11 @@ properties:
           - const: olimex,a20-olinuxino-lime
           - const: allwinner,sun7i-a20
 
+      - description: Olimex A20-OlinuXino LIME (with eMMC)
+        items:
+          - const: olimex,a20-olinuxino-lime-emmc
+          - const: allwinner,sun7i-a20
+
       - description: Olimex A20-OlinuXino LIME2
         items:
           - const: olimex,a20-olinuxino-lime2
diff --git a/Documentation/devicetree/bindings/arm/sunxi/allwinner,sun4i-a10-mbus.yaml b/Documentation/devicetree/bindings/arm/sunxi/allwinner,sun4i-a10-mbus.yaml
index aa0738b4d534..e713a6fe4cf7 100644
--- a/Documentation/devicetree/bindings/arm/sunxi/allwinner,sun4i-a10-mbus.yaml
+++ b/Documentation/devicetree/bindings/arm/sunxi/allwinner,sun4i-a10-mbus.yaml
@@ -42,6 +42,10 @@ properties:
     description:
       See section 2.3.9 of the DeviceTree Specification.
 
+  '#address-cells': true
+
+  '#size-cells': true
+
 required:
   - "#interconnect-cells"
   - compatible
@@ -59,6 +63,8 @@ examples:
         compatible = "allwinner,sun5i-a13-mbus";
         reg = <0x01c01000 0x1000>;
         clocks = <&ccu CLK_MBUS>;
+        #address-cells = <1>;
+        #size-cells = <1>;
         dma-ranges = <0x00000000 0x40000000 0x20000000>;
         #interconnect-cells = <1>;
     };
diff --git a/Documentation/devicetree/bindings/ata/faraday,ftide010.yaml b/Documentation/devicetree/bindings/ata/faraday,ftide010.yaml
index bfc6357476fd..6451928dd2ce 100644
--- a/Documentation/devicetree/bindings/ata/faraday,ftide010.yaml
+++ b/Documentation/devicetree/bindings/ata/faraday,ftide010.yaml
@@ -26,8 +26,8 @@ properties:
     oneOf:
       - const: faraday,ftide010
       - items:
-        - const: cortina,gemini-pata
-        - const: faraday,ftide010
+          - const: cortina,gemini-pata
+          - const: faraday,ftide010
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/bus/allwinner,sun8i-a23-rsb.yaml b/Documentation/devicetree/bindings/bus/allwinner,sun8i-a23-rsb.yaml
index 80973619342d..32d33b983d66 100644
--- a/Documentation/devicetree/bindings/bus/allwinner,sun8i-a23-rsb.yaml
+++ b/Documentation/devicetree/bindings/bus/allwinner,sun8i-a23-rsb.yaml
@@ -21,8 +21,8 @@ properties:
     oneOf:
       - const: allwinner,sun8i-a23-rsb
       - items:
-        - const: allwinner,sun8i-a83t-rsb
-        - const: allwinner,sun8i-a23-rsb
+          - const: allwinner,sun8i-a83t-rsb
+          - const: allwinner,sun8i-a23-rsb
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-gates-clk.yaml b/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-gates-clk.yaml
index ed1b2126a81b..9a37a357cb4e 100644
--- a/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-gates-clk.yaml
+++ b/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-gates-clk.yaml
@@ -52,12 +52,12 @@ properties:
       - const: allwinner,sun4i-a10-dram-gates-clk
 
       - items:
-        - const: allwinner,sun5i-a13-dram-gates-clk
-        - const: allwinner,sun4i-a10-gates-clk
+          - const: allwinner,sun5i-a13-dram-gates-clk
+          - const: allwinner,sun4i-a10-gates-clk
 
       - items:
-        - const: allwinner,sun8i-h3-apb0-gates-clk
-        - const: allwinner,sun4i-a10-gates-clk
+          - const: allwinner,sun8i-h3-apb0-gates-clk
+          - const: allwinner,sun4i-a10-gates-clk
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/clock/arm,syscon-icst.yaml b/Documentation/devicetree/bindings/clock/arm,syscon-icst.yaml
index de9a465096db..444aeea27db8 100644
--- a/Documentation/devicetree/bindings/clock/arm,syscon-icst.yaml
+++ b/Documentation/devicetree/bindings/clock/arm,syscon-icst.yaml
@@ -91,7 +91,7 @@ required:
 
 examples:
   - |
-    vco1: clock@00 {
+    vco1: clock {
       compatible = "arm,impd1-vco1";
       #clock-cells = <0>;
       lock-offset = <0x08>;
diff --git a/Documentation/devicetree/bindings/clock/fsl,plldig.yaml b/Documentation/devicetree/bindings/clock/fsl,plldig.yaml
index a203d5d498db..8141f22410dd 100644
--- a/Documentation/devicetree/bindings/clock/fsl,plldig.yaml
+++ b/Documentation/devicetree/bindings/clock/fsl,plldig.yaml
@@ -28,15 +28,14 @@ properties:
     const: 0
 
   fsl,vco-hz:
-     description: Optional for VCO frequency of the PLL in Hertz.
-        The VCO frequency of this PLL cannot be changed during runtime
-        only at startup. Therefore, the output frequencies are very
-        limited and might not even closely match the requested frequency.
-        To work around this restriction the user may specify its own
-        desired VCO frequency for the PLL.
-     minimum: 650000000
-     maximum: 1300000000
-     default: 1188000000
+    description: Optional for VCO frequency of the PLL in Hertz. The VCO frequency
+      of this PLL cannot be changed during runtime only at startup. Therefore,
+      the output frequencies are very limited and might not even closely match
+      the requested frequency. To work around this restriction the user may specify
+      its own desired VCO frequency for the PLL.
+    minimum: 650000000
+    maximum: 1300000000
+    default: 1188000000
 
 required:
   - compatible
diff --git a/Documentation/devicetree/bindings/clock/qcom,mmcc.yaml b/Documentation/devicetree/bindings/clock/qcom,mmcc.yaml
index f684fe67db84..acc31b3991bd 100644
--- a/Documentation/devicetree/bindings/clock/qcom,mmcc.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,mmcc.yaml
@@ -15,15 +15,15 @@ description: |
   power domains.
 
 properties:
-  compatible :
+  compatible:
     enum:
-       - qcom,mmcc-apq8064
-       - qcom,mmcc-apq8084
-       - qcom,mmcc-msm8660
-       - qcom,mmcc-msm8960
-       - qcom,mmcc-msm8974
-       - qcom,mmcc-msm8996
-       - qcom,mmcc-msm8998
+      - qcom,mmcc-apq8064
+      - qcom,mmcc-apq8084
+      - qcom,mmcc-msm8660
+      - qcom,mmcc-msm8960
+      - qcom,mmcc-msm8974
+      - qcom,mmcc-msm8996
+      - qcom,mmcc-msm8998
 
   clocks:
     items:
diff --git a/Documentation/devicetree/bindings/connector/usb-connector.yaml b/Documentation/devicetree/bindings/connector/usb-connector.yaml
index 4638d7adb806..369c58e22a06 100644
--- a/Documentation/devicetree/bindings/connector/usb-connector.yaml
+++ b/Documentation/devicetree/bindings/connector/usb-connector.yaml
@@ -144,7 +144,7 @@ required:
 
 examples:
   # Micro-USB connector with HS lines routed via controller (MUIC).
-  - |+
+  - |
     muic-max77843 {
       usb_con1: connector {
         compatible = "usb-b-connector";
@@ -156,7 +156,7 @@ examples:
   # USB-C connector attached to CC controller (s2mm005), HS lines routed
   # to companion PMIC (max77865), SS lines to USB3 PHY and SBU to DisplayPort.
   # DisplayPort video lines are routed to the connector via SS mux in USB3 PHY.
-  - |+
+  - |
     ccic: s2mm005 {
       usb_con2: connector {
         compatible = "usb-c-connector";
@@ -190,7 +190,7 @@ examples:
 
   # USB-C connector attached to a typec port controller(ptn5110), which has
   # power delivery support and enables drp.
-  - |+
+  - |
     #include <dt-bindings/usb/pd.h>
     typec: ptn5110 {
       usb_con3: connector {
diff --git a/Documentation/devicetree/bindings/crypto/allwinner,sun4i-a10-crypto.yaml b/Documentation/devicetree/bindings/crypto/allwinner,sun4i-a10-crypto.yaml
index 8b9a8f337f16..fc823572bcff 100644
--- a/Documentation/devicetree/bindings/crypto/allwinner,sun4i-a10-crypto.yaml
+++ b/Documentation/devicetree/bindings/crypto/allwinner,sun4i-a10-crypto.yaml
@@ -15,16 +15,16 @@ properties:
     oneOf:
       - const: allwinner,sun4i-a10-crypto
       - items:
-        - const: allwinner,sun5i-a13-crypto
-        - const: allwinner,sun4i-a10-crypto
+          - const: allwinner,sun5i-a13-crypto
+          - const: allwinner,sun4i-a10-crypto
       - items:
-        - const: allwinner,sun6i-a31-crypto
-        - const: allwinner,sun4i-a10-crypto
+          - const: allwinner,sun6i-a31-crypto
+          - const: allwinner,sun4i-a10-crypto
       - items:
-        - const: allwinner,sun7i-a20-crypto
-        - const: allwinner,sun4i-a10-crypto
+          - const: allwinner,sun7i-a20-crypto
+          - const: allwinner,sun4i-a10-crypto
       - items:
-        - const: allwinner,sun8i-a33-crypto
+          - const: allwinner,sun8i-a33-crypto
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/crypto/allwinner,sun8i-ce.yaml b/Documentation/devicetree/bindings/crypto/allwinner,sun8i-ce.yaml
index 2c459b8c76ff..7a60d84289cc 100644
--- a/Documentation/devicetree/bindings/crypto/allwinner,sun8i-ce.yaml
+++ b/Documentation/devicetree/bindings/crypto/allwinner,sun8i-ce.yaml
@@ -50,16 +50,16 @@ if:
         const: allwinner,sun50i-h6-crypto
 then:
   properties:
-      clocks:
-        minItems: 3
-      clock-names:
-        minItems: 3
+    clocks:
+      minItems: 3
+    clock-names:
+      minItems: 3
 else:
   properties:
-      clocks:
-        maxItems: 2
-      clock-names:
-        maxItems: 2
+    clocks:
+      maxItems: 2
+    clock-names:
+      maxItems: 2
 
 required:
   - compatible
diff --git a/Documentation/devicetree/bindings/crypto/amlogic,gxl-crypto.yaml b/Documentation/devicetree/bindings/crypto/amlogic,gxl-crypto.yaml
index 5becc60a0e28..385b23d255c3 100644
--- a/Documentation/devicetree/bindings/crypto/amlogic,gxl-crypto.yaml
+++ b/Documentation/devicetree/bindings/crypto/amlogic,gxl-crypto.yaml
@@ -12,7 +12,7 @@ maintainers:
 properties:
   compatible:
     items:
-    - const: amlogic,gxl-crypto
+      - const: amlogic,gxl-crypto
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-hdmi.yaml b/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-hdmi.yaml
index 5d4915aed1e2..75e6479397a5 100644
--- a/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-hdmi.yaml
+++ b/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-hdmi.yaml
@@ -21,8 +21,8 @@ properties:
       - const: allwinner,sun5i-a10s-hdmi
       - const: allwinner,sun6i-a31-hdmi
       - items:
-        - const: allwinner,sun7i-a20-hdmi
-        - const: allwinner,sun5i-a10s-hdmi
+          - const: allwinner,sun7i-a20-hdmi
+          - const: allwinner,sun5i-a10s-hdmi
 
   reg:
     maxItems: 1
@@ -33,32 +33,32 @@ properties:
   clocks:
     oneOf:
       - items:
-        - description: The HDMI interface clock
-        - description: The HDMI module clock
-        - description: The first video PLL
-        - description: The second video PLL
+          - description: The HDMI interface clock
+          - description: The HDMI module clock
+          - description: The first video PLL
+          - description: The second video PLL
 
       - items:
-        - description: The HDMI interface clock
-        - description: The HDMI module clock
-        - description: The HDMI DDC clock
-        - description: The first video PLL
-        - description: The second video PLL
+          - description: The HDMI interface clock
+          - description: The HDMI module clock
+          - description: The HDMI DDC clock
+          - description: The first video PLL
+          - description: The second video PLL
 
   clock-names:
     oneOf:
       - items:
-        - const: ahb
-        - const: mod
-        - const: pll-0
-        - const: pll-1
+          - const: ahb
+          - const: mod
+          - const: pll-0
+          - const: pll-1
 
       - items:
-        - const: ahb
-        - const: mod
-        - const: ddc
-        - const: pll-0
-        - const: pll-1
+          - const: ahb
+          - const: mod
+          - const: ddc
+          - const: pll-0
+          - const: pll-1
 
   resets:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-tcon.yaml b/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-tcon.yaml
index e5344c4ae226..87cb77b32ee3 100644
--- a/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-tcon.yaml
+++ b/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-tcon.yaml
@@ -35,26 +35,26 @@ properties:
       - const: allwinner,sun9i-a80-tcon-tv
 
       - items:
-        - enum:
-          - allwinner,sun7i-a20-tcon0
-          - allwinner,sun7i-a20-tcon1
-        - const: allwinner,sun7i-a20-tcon
+          - enum:
+              - allwinner,sun7i-a20-tcon0
+              - allwinner,sun7i-a20-tcon1
+          - const: allwinner,sun7i-a20-tcon
 
       - items:
-        - enum:
-            - allwinner,sun50i-a64-tcon-lcd
-        - const: allwinner,sun8i-a83t-tcon-lcd
+          - enum:
+              - allwinner,sun50i-a64-tcon-lcd
+          - const: allwinner,sun8i-a83t-tcon-lcd
 
       - items:
-        - enum:
-          - allwinner,sun8i-h3-tcon-tv
-          - allwinner,sun50i-a64-tcon-tv
-        - const: allwinner,sun8i-a83t-tcon-tv
+          - enum:
+              - allwinner,sun8i-h3-tcon-tv
+              - allwinner,sun50i-a64-tcon-tv
+          - const: allwinner,sun8i-a83t-tcon-tv
 
       - items:
-        - enum:
-          - allwinner,sun50i-h6-tcon-tv
-        - const: allwinner,sun8i-r40-tcon-tv
+          - enum:
+              - allwinner,sun50i-h6-tcon-tv
+          - const: allwinner,sun8i-r40-tcon-tv
 
   reg:
     maxItems: 1
@@ -83,37 +83,37 @@ properties:
   resets:
     anyOf:
       - items:
-        - description: TCON Reset Line
+          - description: TCON Reset Line
 
       - items:
-        - description: TCON Reset Line
-        - description: TCON LVDS Reset Line
+          - description: TCON Reset Line
+          - description: TCON LVDS Reset Line
 
       - items:
-        - description: TCON Reset Line
-        - description: TCON eDP Reset Line
+          - description: TCON Reset Line
+          - description: TCON eDP Reset Line
 
       - items:
-        - description: TCON Reset Line
-        - description: TCON eDP Reset Line
-        - description: TCON LVDS Reset Line
+          - description: TCON Reset Line
+          - description: TCON eDP Reset Line
+          - description: TCON LVDS Reset Line
 
   reset-names:
     oneOf:
       - const: lcd
 
       - items:
-        - const: lcd
-        - const: lvds
+          - const: lcd
+          - const: lvds
 
       - items:
-        - const: lcd
-        - const: edp
+          - const: lcd
+          - const: edp
 
       - items:
-        - const: lcd
-        - const: edp
-        - const: lvds
+          - const: lcd
+          - const: edp
+          - const: lvds
 
   ports:
     type: object
diff --git a/Documentation/devicetree/bindings/display/allwinner,sun6i-a31-mipi-dsi.yaml b/Documentation/devicetree/bindings/display/allwinner,sun6i-a31-mipi-dsi.yaml
index 9e90c2b00960..63f948175239 100644
--- a/Documentation/devicetree/bindings/display/allwinner,sun6i-a31-mipi-dsi.yaml
+++ b/Documentation/devicetree/bindings/display/allwinner,sun6i-a31-mipi-dsi.yaml
@@ -76,28 +76,28 @@ required:
 allOf:
   - if:
       properties:
-         compatible:
-           contains:
-             const: allwinner,sun6i-a31-mipi-dsi
+        compatible:
+          contains:
+            const: allwinner,sun6i-a31-mipi-dsi
 
     then:
-        properties:
-          clocks:
-            minItems: 2
+      properties:
+        clocks:
+          minItems: 2
 
-        required:
-          - clock-names
+      required:
+        - clock-names
 
   - if:
       properties:
-         compatible:
-           contains:
-             const: allwinner,sun50i-a64-mipi-dsi
+        compatible:
+          contains:
+            const: allwinner,sun50i-a64-mipi-dsi
 
     then:
-        properties:
-          clocks:
-            minItems: 1
+      properties:
+        clocks:
+          minItems: 1
 
 additionalProperties: false
 
@@ -119,7 +119,7 @@ examples:
         panel@0 {
                 compatible = "bananapi,lhr050h41", "ilitek,ili9881c";
                 reg = <0>;
-                power-gpios = <&pio 1 7 0>; /* PB07 */
+                power-supply = <&reg_display>;
                 reset-gpios = <&r_pio 0 5 1>; /* PL05 */
                 backlight = <&pwm_bl>;
         };
diff --git a/Documentation/devicetree/bindings/display/allwinner,sun8i-a83t-dw-hdmi.yaml b/Documentation/devicetree/bindings/display/allwinner,sun8i-a83t-dw-hdmi.yaml
index 4d6795690ac3..fa4769a0b26e 100644
--- a/Documentation/devicetree/bindings/display/allwinner,sun8i-a83t-dw-hdmi.yaml
+++ b/Documentation/devicetree/bindings/display/allwinner,sun8i-a83t-dw-hdmi.yaml
@@ -29,11 +29,11 @@ properties:
       - const: allwinner,sun50i-h6-dw-hdmi
 
       - items:
-        - enum:
-          - allwinner,sun8i-h3-dw-hdmi
-          - allwinner,sun8i-r40-dw-hdmi
-          - allwinner,sun50i-a64-dw-hdmi
-        - const: allwinner,sun8i-a83t-dw-hdmi
+          - enum:
+              - allwinner,sun8i-h3-dw-hdmi
+              - allwinner,sun8i-r40-dw-hdmi
+              - allwinner,sun50i-a64-dw-hdmi
+          - const: allwinner,sun8i-a83t-dw-hdmi
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/display/bridge/adi,adv7123.txt b/Documentation/devicetree/bindings/display/bridge/adi,adv7123.txt
index a6b2b2b8f3d9..d3c2a4914ea2 100644
--- a/Documentation/devicetree/bindings/display/bridge/adi,adv7123.txt
+++ b/Documentation/devicetree/bindings/display/bridge/adi,adv7123.txt
@@ -1,5 +1,5 @@
-Analog Device ADV7123 Video DAC
--------------------------------
+Analog Devices ADV7123 Video DAC
+--------------------------------
 
 The ADV7123 is a digital-to-analog converter that outputs VGA signals from a
 parallel video input.
diff --git a/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt b/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt
index e8ddec5d9d91..659523f538bf 100644
--- a/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt
+++ b/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt
@@ -1,5 +1,5 @@
-Analog Device ADV7511(W)/13/33/35 HDMI Encoders
------------------------------------------
+Analog Devices ADV7511(W)/13/33/35 HDMI Encoders
+------------------------------------------------
 
 The ADV7511, ADV7511W, ADV7513, ADV7533 and ADV7535 are HDMI audio and video
 transmitters compatible with HDMI 1.4 and DVI 1.0. They support color space
diff --git a/Documentation/devicetree/bindings/display/bridge/lvds-codec.yaml b/Documentation/devicetree/bindings/display/bridge/lvds-codec.yaml
index 8f373029f5d2..e737951f5873 100644
--- a/Documentation/devicetree/bindings/display/bridge/lvds-codec.yaml
+++ b/Documentation/devicetree/bindings/display/bridge/lvds-codec.yaml
@@ -32,17 +32,17 @@ properties:
   compatible:
     oneOf:
       - items:
-        - enum:
-          - ti,ds90c185       # For the TI DS90C185 FPD-Link Serializer
-          - ti,ds90c187       # For the TI DS90C187 FPD-Link Serializer
-          - ti,sn75lvds83     # For the TI SN75LVDS83 FlatLink transmitter
-        - const: lvds-encoder # Generic LVDS encoder compatible fallback
+          - enum:
+              - ti,ds90c185   # For the TI DS90C185 FPD-Link Serializer
+              - ti,ds90c187   # For the TI DS90C187 FPD-Link Serializer
+              - ti,sn75lvds83 # For the TI SN75LVDS83 FlatLink transmitter
+          - const: lvds-encoder # Generic LVDS encoder compatible fallback
       - items:
-        - enum:
-          - ti,ds90cf384a     # For the DS90CF384A FPD-Link LVDS Receiver
-        - const: lvds-decoder # Generic LVDS decoders compatible fallback
+          - enum:
+              - ti,ds90cf384a # For the DS90CF384A FPD-Link LVDS Receiver
+          - const: lvds-decoder # Generic LVDS decoders compatible fallback
       - enum:
-        - thine,thc63lvdm83d  # For the THC63LVDM83D LVDS serializer
+          - thine,thc63lvdm83d # For the THC63LVDM83D LVDS serializer
 
   ports:
     type: object
diff --git a/Documentation/devicetree/bindings/display/bridge/nwl-dsi.yaml b/Documentation/devicetree/bindings/display/bridge/nwl-dsi.yaml
new file mode 100644
index 000000000000..8aff2d68fc33
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/bridge/nwl-dsi.yaml
@@ -0,0 +1,226 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/bridge/nwl-dsi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Northwest Logic MIPI-DSI controller on i.MX SoCs
+
+maintainers:
+  - Guido Gúnther <agx@sigxcpu.org>
+  - Robert Chiras <robert.chiras@nxp.com>
+
+description: |
+  NWL MIPI-DSI host controller found on i.MX8 platforms. This is a dsi bridge for
+  the SOCs NWL MIPI-DSI host controller.
+
+properties:
+  compatible:
+    const: fsl,imx8mq-nwl-dsi
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  '#address-cells':
+    const: 1
+
+  '#size-cells':
+    const: 0
+
+  clocks:
+    items:
+      - description: DSI core clock
+      - description: RX_ESC clock (used in escape mode)
+      - description: TX_ESC clock (used in escape mode)
+      - description: PHY_REF clock
+      - description: LCDIF clock
+
+  clock-names:
+    items:
+      - const: core
+      - const: rx_esc
+      - const: tx_esc
+      - const: phy_ref
+      - const: lcdif
+
+  mux-controls:
+    description:
+      mux controller node to use for operating the input mux
+
+  phys:
+    maxItems: 1
+    description:
+      A phandle to the phy module representing the DPHY
+
+  phy-names:
+    items:
+      - const: dphy
+
+  power-domains:
+    maxItems: 1
+
+  resets:
+    items:
+      - description: dsi byte reset line
+      - description: dsi dpi reset line
+      - description: dsi esc reset line
+      - description: dsi pclk reset line
+
+  reset-names:
+    items:
+      - const: byte
+      - const: dpi
+      - const: esc
+      - const: pclk
+
+  ports:
+    type: object
+    description:
+      A node containing DSI input & output port nodes with endpoint
+      definitions as documented in
+      Documentation/devicetree/bindings/graph.txt.
+    properties:
+      port@0:
+        type: object
+        description:
+          Input port node to receive pixel data from the
+          display controller. Exactly one endpoint must be
+          specified.
+        properties:
+          '#address-cells':
+            const: 1
+
+          '#size-cells':
+            const: 0
+
+          endpoint@0:
+            description: sub-node describing the input from LCDIF
+            type: object
+
+          endpoint@1:
+            description: sub-node describing the input from DCSS
+            type: object
+
+          reg:
+            const: 0
+
+        required:
+          - '#address-cells'
+          - '#size-cells'
+          - reg
+
+        oneOf:
+          - required:
+              - endpoint@0
+          - required:
+              - endpoint@1
+
+        additionalProperties: false
+
+      port@1:
+        type: object
+        description:
+          DSI output port node to the panel or the next bridge
+          in the chain
+
+      '#address-cells':
+        const: 1
+
+      '#size-cells':
+        const: 0
+
+    required:
+      - '#address-cells'
+      - '#size-cells'
+      - port@0
+      - port@1
+
+    additionalProperties: false
+
+patternProperties:
+  "^panel@[0-9]+$":
+    type: object
+
+required:
+  - '#address-cells'
+  - '#size-cells'
+  - clock-names
+  - clocks
+  - compatible
+  - interrupts
+  - mux-controls
+  - phy-names
+  - phys
+  - ports
+  - reg
+  - reset-names
+  - resets
+
+additionalProperties: false
+
+examples:
+ - |
+
+   #include <dt-bindings/clock/imx8mq-clock.h>
+   #include <dt-bindings/interrupt-controller/arm-gic.h>
+   #include <dt-bindings/reset/imx8mq-reset.h>
+
+   mipi_dsi: mipi_dsi@30a00000 {
+              #address-cells = <1>;
+              #size-cells = <0>;
+              compatible = "fsl,imx8mq-nwl-dsi";
+              reg = <0x30A00000 0x300>;
+              clocks = <&clk IMX8MQ_CLK_DSI_CORE>,
+                       <&clk IMX8MQ_CLK_DSI_AHB>,
+                       <&clk IMX8MQ_CLK_DSI_IPG_DIV>,
+                       <&clk IMX8MQ_CLK_DSI_PHY_REF>,
+                       <&clk IMX8MQ_CLK_LCDIF_PIXEL>;
+              clock-names = "core", "rx_esc", "tx_esc", "phy_ref", "lcdif";
+              interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+              mux-controls = <&mux 0>;
+              power-domains = <&pgc_mipi>;
+              resets = <&src IMX8MQ_RESET_MIPI_DSI_RESET_BYTE_N>,
+                       <&src IMX8MQ_RESET_MIPI_DSI_DPI_RESET_N>,
+                       <&src IMX8MQ_RESET_MIPI_DSI_ESC_RESET_N>,
+                       <&src IMX8MQ_RESET_MIPI_DSI_PCLK_RESET_N>;
+              reset-names = "byte", "dpi", "esc", "pclk";
+              phys = <&dphy>;
+              phy-names = "dphy";
+
+              panel@0 {
+                      #address-cells = <1>;
+                      #size-cells = <0>;
+                      compatible = "rocktech,jh057n00900";
+                      reg = <0>;
+                      port@0 {
+                           reg = <0>;
+                           panel_in: endpoint {
+                                     remote-endpoint = <&mipi_dsi_out>;
+                           };
+                      };
+              };
+
+              ports {
+                    #address-cells = <1>;
+                    #size-cells = <0>;
+
+                    port@0 {
+                           #size-cells = <0>;
+                           #address-cells = <1>;
+                           reg = <0>;
+                           mipi_dsi_in: endpoint@0 {
+                                        reg = <0>;
+                                        remote-endpoint = <&lcdif_mipi_dsi>;
+                           };
+                    };
+                    port@1 {
+                           reg = <1>;
+                           mipi_dsi_out: endpoint {
+                                         remote-endpoint = <&panel_in>;
+                           };
+                    };
+              };
+      };
diff --git a/Documentation/devicetree/bindings/display/dsi-controller.yaml b/Documentation/devicetree/bindings/display/dsi-controller.yaml
index fd986c36c737..85b71b1fd28a 100644
--- a/Documentation/devicetree/bindings/display/dsi-controller.yaml
+++ b/Documentation/devicetree/bindings/display/dsi-controller.yaml
@@ -28,7 +28,7 @@ description: |
 
 properties:
   $nodename:
-    pattern: "^dsi-controller(@.*)?$"
+    pattern: "^dsi(@.*)?$"
 
   "#address-cells":
     const: 1
@@ -76,7 +76,7 @@ patternProperties:
 examples:
   - |
     #include <dt-bindings/gpio/gpio.h>
-    dsi-controller@a0351000 {
+    dsi@a0351000 {
         reg = <0xa0351000 0x1000>;
         #address-cells = <1>;
         #size-cells = <0>;
diff --git a/Documentation/devicetree/bindings/display/panel/arm,versatile-tft-panel.txt b/Documentation/devicetree/bindings/display/panel/arm,versatile-tft-panel.txt
deleted file mode 100644
index 0601a9e34703..000000000000
--- a/Documentation/devicetree/bindings/display/panel/arm,versatile-tft-panel.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-ARM Versatile TFT Panels
-
-These panels are connected to the daughterboards found on the
-ARM Versatile reference designs.
-
-This device node must appear as a child to a "syscon"-compatible
-node.
-
-Required properties:
-- compatible: should be "arm,versatile-tft-panel"
-
-Required subnodes:
-- port: see display/panel/panel-common.yaml, graph.txt
-
-
-Example:
-
-sysreg@0 {
-	compatible = "arm,versatile-sysreg", "syscon", "simple-mfd";
-	reg = <0x00000 0x1000>;
-
-	panel: display@0 {
-		compatible = "arm,versatile-tft-panel";
-
-		port {
-			panel_in: endpoint {
-				remote-endpoint = <&foo>;
-			};
-		};
-	};
-};
diff --git a/Documentation/devicetree/bindings/display/panel/arm,versatile-tft-panel.yaml b/Documentation/devicetree/bindings/display/panel/arm,versatile-tft-panel.yaml
new file mode 100644
index 000000000000..41fd5713c156
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/arm,versatile-tft-panel.yaml
@@ -0,0 +1,54 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/arm,versatile-tft-panel.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ARM Versatile TFT Panels
+
+maintainers:
+  - Linus Walleij <linus.walleij@linaro.org>
+
+description: |
+  These panels are connected to the daughterboards found on the
+  ARM Versatile reference designs.
+
+  This device node must appear as a child to a "syscon"-compatible
+  node.
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+    const: arm,versatile-tft-panel
+
+  port: true
+
+required:
+  - compatible
+  - port
+
+additionalProperties: false
+
+examples:
+  - |
+    sysreg {
+        compatible = "arm,versatile-sysreg", "syscon", "simple-mfd";
+        reg = <0x00000 0x1000>;
+
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        panel {
+            compatible = "arm,versatile-tft-panel";
+
+            port {
+                panel_in: endpoint {
+                    remote-endpoint = <&foo>;
+                };
+            };
+        };
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/display/panel/boe,himax8279d.txt b/Documentation/devicetree/bindings/display/panel/boe,himax8279d.txt
deleted file mode 100644
index 3caea2172b1b..000000000000
--- a/Documentation/devicetree/bindings/display/panel/boe,himax8279d.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-Boe Himax8279d 1200x1920 TFT LCD panel
-
-Required properties:
-- compatible: should be "boe,himax8279d8p" and one of: "boe,himax8279d10p"
-- reg: DSI virtual channel of the peripheral
-- enable-gpios: panel enable gpio
-- pp33-gpios: a GPIO phandle for the 3.3v pin that provides the supply voltage
-- pp18-gpios: a GPIO phandle for the 1.8v pin that provides the supply voltage
-
-Optional properties:
-- backlight: phandle of the backlight device attached to the panel
-
-Example:
-
-	&mipi_dsi {
-		panel {
-			compatible = "boe,himax8279d8p", "boe,himax8279d10p";
-			reg = <0>;
-			backlight = <&backlight>;
-			enable-gpios = <&gpio 45 GPIO_ACTIVE_HIGH>;
-			pp33-gpios = <&gpio 35 GPIO_ACTIVE_HIGH>;
-			pp18-gpios = <&gpio 36 GPIO_ACTIVE_HIGH>;
-		};
-	};
diff --git a/Documentation/devicetree/bindings/display/panel/boe,himax8279d.yaml b/Documentation/devicetree/bindings/display/panel/boe,himax8279d.yaml
new file mode 100644
index 000000000000..272a3a018a33
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/boe,himax8279d.yaml
@@ -0,0 +1,59 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/boe,himax8279d.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Boe Himax8279d 1200x1920 TFT LCD panel
+
+maintainers:
+  - Jerry Han <jerry.han.hq@gmail.com>
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+    items:
+      - const: boe,himax8279d8p
+      - const: boe,himax8279d10p
+
+  backlight: true
+  enable-gpios: true
+  reg: true
+
+  pp33-gpios:
+    maxItems: 1
+    description: GPIO for the 3.3v pin that provides the supply voltage
+
+  pp18-gpios:
+    maxItems: 1
+    description: GPIO for the 1.8v pin that provides the supply voltage
+
+required:
+  - compatible
+  - reg
+  - enable-gpios
+  - pp33-gpios
+  - pp18-gpios
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    dsi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+        panel@0 {
+            compatible = "boe,himax8279d8p", "boe,himax8279d10p";
+            reg = <0>;
+            backlight = <&backlight>;
+            enable-gpios = <&gpio 45 GPIO_ACTIVE_HIGH>;
+            pp33-gpios = <&gpio 35 GPIO_ACTIVE_HIGH>;
+            pp18-gpios = <&gpio 36 GPIO_ACTIVE_HIGH>;
+        };
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/display/panel/boe,tv101wum-nl6.yaml b/Documentation/devicetree/bindings/display/panel/boe,tv101wum-nl6.yaml
index 740213459134..7f5df5851017 100644
--- a/Documentation/devicetree/bindings/display/panel/boe,tv101wum-nl6.yaml
+++ b/Documentation/devicetree/bindings/display/panel/boe,tv101wum-nl6.yaml
@@ -24,6 +24,8 @@ properties:
       - boe,tv101wum-n53
         # AUO B101UAN08.3 10.1" WUXGA TFT LCD panel
       - auo,b101uan08.3
+        # BOE TV105WUM-NW0 10.5" WUXGA TFT LCD panel
+      - boe,tv105wum-nw0
 
   reg:
     description: the virtual channel number of a DSI peripheral
diff --git a/Documentation/devicetree/bindings/display/panel/display-timings.yaml b/Documentation/devicetree/bindings/display/panel/display-timings.yaml
index c8c0c9cb0492..56903ded005e 100644
--- a/Documentation/devicetree/bindings/display/panel/display-timings.yaml
+++ b/Documentation/devicetree/bindings/display/panel/display-timings.yaml
@@ -4,7 +4,7 @@
 $id: http://devicetree.org/schemas/display/panel/display-timings.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title: display timing bindings
+title: display timings bindings
 
 maintainers:
   - Thierry Reding <thierry.reding@gmail.com>
@@ -14,7 +14,7 @@ maintainers:
 description: |
   A display panel may be able to handle several display timings,
   with different resolutions.
-  The display-timings node makes it possible to specify the timing
+  The display-timings node makes it possible to specify the timings
   and to specify the timing that is native for the display.
 
 properties:
@@ -25,8 +25,8 @@ properties:
     $ref: /schemas/types.yaml#/definitions/phandle
     description: |
       The default display timing is the one specified as native-mode.
-      If no native-mode is specified then the first node is assumed the
-      native mode.
+      If no native-mode is specified then the first node is assumed
+      to be the native mode.
 
 patternProperties:
   "^timing":
diff --git a/Documentation/devicetree/bindings/display/panel/feiyang,fy07024di26a30d.txt b/Documentation/devicetree/bindings/display/panel/feiyang,fy07024di26a30d.txt
deleted file mode 100644
index 82caa7b65ae8..000000000000
--- a/Documentation/devicetree/bindings/display/panel/feiyang,fy07024di26a30d.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-Feiyang FY07024DI26A30-D 7" MIPI-DSI LCD Panel
-
-Required properties:
-- compatible: must be "feiyang,fy07024di26a30d"
-- reg: DSI virtual channel used by that screen
-- avdd-supply: analog regulator dc1 switch
-- dvdd-supply: 3v3 digital regulator
-- reset-gpios: a GPIO phandle for the reset pin
-
-Optional properties:
-- backlight: phandle for the backlight control.
-
-panel@0 {
-	compatible = "feiyang,fy07024di26a30d";
-	reg = <0>;
-	avdd-supply = <&reg_dc1sw>;
-	dvdd-supply = <&reg_dldo2>;
-	reset-gpios = <&pio 3 24 GPIO_ACTIVE_HIGH>; /* LCD-RST: PD24 */
-	backlight = <&backlight>;
-};
diff --git a/Documentation/devicetree/bindings/display/panel/feiyang,fy07024di26a30d.yaml b/Documentation/devicetree/bindings/display/panel/feiyang,fy07024di26a30d.yaml
new file mode 100644
index 000000000000..95acf9e96f1c
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/feiyang,fy07024di26a30d.yaml
@@ -0,0 +1,58 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/feiyang,fy07024di26a30d.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Feiyang FY07024DI26A30-D 7" MIPI-DSI LCD Panel
+
+maintainers:
+  - Jagan Teki <jagan@amarulasolutions.com>
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+    const: feiyang,fy07024di26a30d
+
+  reg:
+    description: DSI virtual channel used by that screen
+    maxItems: 1
+
+  avdd-supply:
+    description: analog regulator dc1 switch
+
+  dvdd-supply:
+    description: 3v3 digital regulator
+
+  reset-gpios: true
+
+  backlight: true
+
+required:
+  - compatible
+  - reg
+  - avdd-supply
+  - dvdd-supply
+  - reset-gpios
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    dsi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        panel@0 {
+            compatible = "feiyang,fy07024di26a30d";
+            reg = <0>;
+            avdd-supply = <&reg_dc1sw>;
+            dvdd-supply = <&reg_dldo2>;
+            reset-gpios = <&pio 3 24 GPIO_ACTIVE_HIGH>; /* LCD-RST: PD24 */
+            backlight = <&backlight>;
+        };
+    };
diff --git a/Documentation/devicetree/bindings/display/panel/ilitek,ili9322.txt b/Documentation/devicetree/bindings/display/panel/ilitek,ili9322.txt
deleted file mode 100644
index 3d5ce6ad6ec7..000000000000
--- a/Documentation/devicetree/bindings/display/panel/ilitek,ili9322.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-Ilitek ILI9322 TFT panel driver with SPI control bus
-
-This is a driver for 320x240 TFT panels, accepting a variety of input
-streams that get adapted and scaled to the panel. The panel output has
-960 TFT source driver pins and 240 TFT gate driver pins, VCOM, VCOML and
-VCOMH outputs.
-
-Required properties:
-  - compatible: "dlink,dir-685-panel", "ilitek,ili9322"
-    (full system-specific compatible is always required to look up configuration)
-  - reg: address of the panel on the SPI bus
-
-Optional properties:
-  - vcc-supply: core voltage supply, see regulator/regulator.txt
-  - iovcc-supply: voltage supply for the interface input/output signals,
-    see regulator/regulator.txt
-  - vci-supply: voltage supply for analog parts, see regulator/regulator.txt
-  - reset-gpios: a GPIO spec for the reset pin, see gpio/gpio.txt
-
-  The following optional properties only apply to RGB and YUV input modes and
-  can be omitted for BT.656 input modes:
-
-  - pixelclk-active: see display/panel/display-timing.txt
-  - de-active: see display/panel/display-timing.txt
-  - hsync-active: see display/panel/display-timing.txt
-  - vsync-active: see display/panel/display-timing.txt
-
-The panel must obey the rules for a SPI slave device as specified in
-spi/spi-bus.txt
-
-The device node can contain one 'port' child node with one child
-'endpoint' node, according to the bindings defined in
-media/video-interfaces.txt. This node should describe panel's video bus.
-
-Example:
-
-panel: display@0 {
-	compatible = "dlink,dir-685-panel", "ilitek,ili9322";
-	reg = <0>;
-	vcc-supply = <&vdisp>;
-	iovcc-supply = <&vdisp>;
-	vci-supply = <&vdisp>;
-
-	port {
-		panel_in: endpoint {
-			remote-endpoint = <&display_out>;
-		};
-	};
-};
diff --git a/Documentation/devicetree/bindings/display/panel/ilitek,ili9322.yaml b/Documentation/devicetree/bindings/display/panel/ilitek,ili9322.yaml
new file mode 100644
index 000000000000..177d48c5bd97
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/ilitek,ili9322.yaml
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/ilitek,ili9322.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Ilitek ILI9322 TFT panel driver with SPI control bus
+
+maintainers:
+  - Linus Walleij <linus.walleij@linaro.org>
+
+description: |
+  This is a driver for 320x240 TFT panels, accepting a variety of input
+  streams that get adapted and scaled to the panel. The panel output has
+  960 TFT source driver pins and 240 TFT gate driver pins, VCOM, VCOML and
+  VCOMH outputs.
+
+  The panel must obey the rules for a SPI slave device as specified in
+  spi/spi-controller.yaml
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+    items:
+      - enum:
+        - dlink,dir-685-panel
+
+      - const: ilitek,ili9322
+
+  reset-gpios: true
+  port: true
+
+  vcc-supply:
+    description: Core voltage supply
+
+  iovcc-supply:
+    description: Voltage supply for the interface input/output signals
+
+  vci-supply:
+    description: Voltage supply for analog parts
+
+required:
+  - compatible
+  - reg
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    spi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        panel: display@0 {
+            compatible = "dlink,dir-685-panel", "ilitek,ili9322";
+            reg = <0>;
+            vcc-supply = <&vdisp>;
+            iovcc-supply = <&vdisp>;
+            vci-supply = <&vdisp>;
+
+            port {
+                panel_in: endpoint {
+                    remote-endpoint = <&display_out>;
+                };
+            };
+        };
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.txt b/Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.txt
deleted file mode 100644
index 4a041acb4e18..000000000000
--- a/Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-Ilitek ILI9881c based MIPI-DSI panels
-
-Required properties:
-  - compatible: must be "ilitek,ili9881c" and one of:
-    * "bananapi,lhr050h41"
-  - reg: DSI virtual channel used by that screen
-  - power-supply: phandle to the power regulator
-  - reset-gpios: a GPIO phandle for the reset pin
-
-Optional properties:
-  - backlight: phandle to the backlight used
-
-Example:
-panel@0 {
-	compatible = "bananapi,lhr050h41", "ilitek,ili9881c";
-	reg = <0>;
-	power-supply = <&reg_display>;
-	reset-gpios = <&r_pio 0 5 GPIO_ACTIVE_LOW>; /* PL05 */
-	backlight = <&pwm_bl>;
-};
diff --git a/Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml b/Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml
new file mode 100644
index 000000000000..a39332276bab
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml
@@ -0,0 +1,50 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/ilitek,ili9881c.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Ilitek ILI9881c based MIPI-DSI panels
+
+maintainers:
+  - Maxime Ripard <mripard@kernel.org>
+
+properties:
+  compatible:
+    items:
+      - enum:
+        - bananapi,lhr050h41
+
+      - const: ilitek,ili9881c
+
+  backlight: true
+  power-supply: true
+  reg: true
+  reset-gpios: true
+
+required:
+  - compatible
+  - power-supply
+  - reg
+  - reset-gpios
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    dsi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        panel@0 {
+            compatible = "bananapi,lhr050h41", "ilitek,ili9881c";
+            reg = <0>;
+            power-supply = <&reg_display>;
+            reset-gpios = <&r_pio 0 5 GPIO_ACTIVE_LOW>; /* PL05 */
+            backlight = <&pwm_bl>;
+        };
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/display/panel/innolux,p097pfg.txt b/Documentation/devicetree/bindings/display/panel/innolux,p097pfg.txt
deleted file mode 100644
index d1cab3a8f0fb..000000000000
--- a/Documentation/devicetree/bindings/display/panel/innolux,p097pfg.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-Innolux P097PFG 9.7" 1536x2048 TFT LCD panel
-
-Required properties:
-- compatible: should be "innolux,p097pfg"
-- reg: DSI virtual channel of the peripheral
-- avdd-supply: phandle of the regulator that provides positive voltage
-- avee-supply: phandle of the regulator that provides negative voltage
-- enable-gpios: panel enable gpio
-
-Optional properties:
-- backlight: phandle of the backlight device attached to the panel
-
-Example:
-
-	&mipi_dsi {
-		panel@0 {
-			compatible = "innolux,p079zca";
-			reg = <0>;
-			avdd-supply = <...>;
-			avee-supply = <...>;
-			backlight = <&backlight>;
-			enable-gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>;
-		};
-	};
diff --git a/Documentation/devicetree/bindings/display/panel/innolux,p097pfg.yaml b/Documentation/devicetree/bindings/display/panel/innolux,p097pfg.yaml
new file mode 100644
index 000000000000..5a5f071627fb
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/innolux,p097pfg.yaml
@@ -0,0 +1,56 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/innolux,p097pfg.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Innolux P097PFG 9.7" 1536x2048 TFT LCD panel
+
+maintainers:
+  - Lin Huang <hl@rock-chips.com>
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+    const: innolux,p097pfg
+
+  backlight: true
+  enable-gpios: true
+  reg: true
+
+  avdd-supply:
+    description: The regulator that provides positive voltage
+
+  avee-supply:
+    description: The regulator that provides negative voltage
+
+required:
+  - compatible
+  - reg
+  - avdd-supply
+  - avee-supply
+  - enable-gpios
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    dsi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        panel@0 {
+            compatible = "innolux,p097pfg";
+            reg = <0>;
+            avdd-supply = <&avdd>;
+            avee-supply = <&avee>;
+            backlight = <&backlight>;
+            enable-gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>;
+        };
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/display/panel/innolux,p120zdg-bf1.txt b/Documentation/devicetree/bindings/display/panel/innolux,p120zdg-bf1.txt
deleted file mode 100644
index 513f03466aba..000000000000
--- a/Documentation/devicetree/bindings/display/panel/innolux,p120zdg-bf1.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-Innolux P120ZDG-BF1 12.02 inch eDP 2K display panel
-
-This binding is compatible with the simple-panel binding, which is specified
-in simple-panel.txt in this directory.
-
-Required properties:
-- compatible: should be "innolux,p120zdg-bf1"
-- power-supply: regulator to provide the supply voltage
-
-Optional properties:
-- enable-gpios: GPIO pin to enable or disable the panel
-- backlight: phandle of the backlight device attached to the panel
-- no-hpd: If HPD isn't hooked up; add this property.
-
-Example:
-	panel_edp: panel-edp {
-		compatible = "innolux,p120zdg-bf1";
-		enable-gpios = <&msmgpio 31 GPIO_ACTIVE_LOW>;
-		power-supply = <&pm8916_l2>;
-		backlight = <&backlight>;
-		no-hpd;
-	};
diff --git a/Documentation/devicetree/bindings/display/panel/innolux,p120zdg-bf1.yaml b/Documentation/devicetree/bindings/display/panel/innolux,p120zdg-bf1.yaml
new file mode 100644
index 000000000000..243dac2416f3
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/innolux,p120zdg-bf1.yaml
@@ -0,0 +1,43 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/innolux,p120zdg-bf1.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Innolux P120ZDG-BF1 12.02 inch eDP 2K display panel
+
+maintainers:
+  - Sandeep Panda <spanda@codeaurora.org>
+  - Douglas Anderson <dianders@chromium.org>
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+    const: innolux,p120zdg-bf1
+
+  enable-gpios: true
+  power-supply: true
+  backlight: true
+  no-hpd: true
+
+required:
+  - compatible
+  - power-supply
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    panel_edp: panel-edp {
+        compatible = "innolux,p120zdg-bf1";
+        enable-gpios = <&msmgpio 31 GPIO_ACTIVE_LOW>;
+        power-supply = <&pm8916_l2>;
+        backlight = <&backlight>;
+        no-hpd;
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt b/Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt
deleted file mode 100644
index 4989c91d505f..000000000000
--- a/Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-JDI model LT070ME05000 1200x1920 7" DSI Panel
-
-Required properties:
-- compatible: should be "jdi,lt070me05000"
-- vddp-supply: phandle of the regulator that provides the supply voltage
-  Power IC supply (3-5V)
-- iovcc-supply: phandle of the regulator that provides the supply voltage
-  IOVCC , power supply for LCM (1.8V)
-- enable-gpios: phandle of gpio for enable line
-  LED_EN, LED backlight enable, High active
-- reset-gpios: phandle of gpio for reset line
-  This should be 8mA, gpio can be configured using mux, pinctrl, pinctrl-names
-  XRES, Reset, Low active
-- dcdc-en-gpios: phandle of the gpio for power ic line
-  Power IC supply enable, High active
-
-Example:
-
-	dsi0: qcom,mdss_dsi@4700000 {
-		panel@0 {
-			compatible = "jdi,lt070me05000";
-			reg = <0>;
-
-			vddp-supply = <&pm8921_l17>;
-			iovcc-supply = <&pm8921_lvs7>;
-
-			enable-gpios = <&pm8921_gpio 36 GPIO_ACTIVE_HIGH>;
-			reset-gpios = <&tlmm_pinmux 54 GPIO_ACTIVE_LOW>;
-			dcdc-en-gpios = <&pm8921_gpio 23 GPIO_ACTIVE_HIGH>;
-		};
-	};
diff --git a/Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.yaml b/Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.yaml
new file mode 100644
index 000000000000..b8b9435e464c
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.yaml
@@ -0,0 +1,69 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/jdi,lt070me05000.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: JDI model LT070ME05000 1200x1920 7" DSI Panel
+
+maintainers:
+  - Vinay Simha BN <simhavcs@gmail.com>
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+    const: jdi,lt070me05000
+
+  enable-gpios: true
+  reg: true
+  reset-gpios: true
+
+  vddp-supply:
+    description: |
+      The regulator that provides the supply voltage Power IC supply (3-5V)
+
+  iovcc-supply:
+    description: |
+      The regulator that provides the supply voltage IOVCC,
+      power supply for LCM (1.8V)
+
+  dcdc-en-gpios:
+    description: |
+      phandle of the gpio for power ic line
+      Power IC supply enable, High active
+
+required:
+  - compatible
+  - reg
+  - vddp-supply
+  - iovcc-supply
+  - enable-gpios
+  - reset-gpios
+  - dcdc-en-gpios
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    dsi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        panel@0 {
+            compatible = "jdi,lt070me05000";
+            reg = <0>;
+
+            vddp-supply = <&pm8921_l17>;
+            iovcc-supply = <&pm8921_lvs7>;
+
+            enable-gpios = <&pm8921_gpio 36 GPIO_ACTIVE_HIGH>;
+            reset-gpios = <&tlmm_pinmux 54 GPIO_ACTIVE_LOW>;
+            dcdc-en-gpios = <&pm8921_gpio 23 GPIO_ACTIVE_HIGH>;
+        };
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/display/panel/kingdisplay,kd035g6-54nt.txt b/Documentation/devicetree/bindings/display/panel/kingdisplay,kd035g6-54nt.txt
deleted file mode 100644
index fa9596082e44..000000000000
--- a/Documentation/devicetree/bindings/display/panel/kingdisplay,kd035g6-54nt.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-King Display KD035G6-54NT 3.5" (320x240 pixels) 24-bit TFT LCD panel
-
-Required properties:
-- compatible: should be "kingdisplay,kd035g6-54nt"
-- power-supply: See panel-common.txt
-- reset-gpios: See panel-common.txt
-
-Optional properties:
-- backlight: see panel-common.txt
-
-The generic bindings for the SPI slaves documented in [1] also apply.
-
-The device node can contain one 'port' child node with one child
-'endpoint' node, according to the bindings defined in [2]. This
-node should describe panel's video bus.
-
-[1]: Documentation/devicetree/bindings/spi/spi-bus.txt
-[2]: Documentation/devicetree/bindings/graph.txt
-
-Example:
-
-&spi {
-	panel@0 {
-		compatible = "kingdisplay,kd035g6-54nt";
-		reg = <0>;
-
-		spi-max-frequency = <3125000>;
-		spi-3wire;
-		spi-cs-high;
-
-		reset-gpios = <&gpe 2 GPIO_ACTIVE_LOW>;
-
-		backlight = <&backlight>;
-		power-supply = <&ldo6>;
-
-		port {
-			panel_input: endpoint {
-				remote-endpoint = <&panel_output>;
-			};
-		};
-	};
-};
diff --git a/Documentation/devicetree/bindings/display/panel/kingdisplay,kd035g6-54nt.yaml b/Documentation/devicetree/bindings/display/panel/kingdisplay,kd035g6-54nt.yaml
new file mode 100644
index 000000000000..6960036975fa
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/kingdisplay,kd035g6-54nt.yaml
@@ -0,0 +1,65 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/kingdisplay,kd035g6-54nt.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: King Display KD035G6-54NT 3.5" (320x240 pixels) 24-bit TFT LCD panel
+
+description: |
+  The panel must obey the rules for a SPI slave device as specified in
+  spi/spi-controller.yaml
+
+maintainers:
+  - Paul Cercueil <paul@crapouillou.net>
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+    const: kingdisplay,kd035g6-54nt
+
+  backlight: true
+  port: true
+  power-supply: true
+  reg: true
+  reset-gpios: true
+
+required:
+  - compatible
+  - power-supply
+  - reset-gpios
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    spi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        panel@0 {
+            compatible = "kingdisplay,kd035g6-54nt";
+            reg = <0>;
+
+            spi-max-frequency = <3125000>;
+            spi-3wire;
+            spi-cs-high;
+
+            reset-gpios = <&gpe 2 GPIO_ACTIVE_LOW>;
+
+            backlight = <&backlight>;
+            power-supply = <&ldo6>;
+
+            port {
+                panel_input: endpoint {
+                    remote-endpoint = <&panel_output>;
+                };
+            };
+        };
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/display/panel/kingdisplay,kd097d04.txt b/Documentation/devicetree/bindings/display/panel/kingdisplay,kd097d04.txt
deleted file mode 100644
index cfefff688614..000000000000
--- a/Documentation/devicetree/bindings/display/panel/kingdisplay,kd097d04.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-Kingdisplay KD097D04 9.7" 1536x2048 TFT LCD panel
-
-Required properties:
-- compatible: should be "kingdisplay,kd097d04"
-- reg: DSI virtual channel of the peripheral
-- power-supply: phandle of the regulator that provides the supply voltage
-- enable-gpios: panel enable gpio
-
-Optional properties:
-- backlight: phandle of the backlight device attached to the panel
-
-Example:
-
-	&mipi_dsi {
-		panel@0 {
-			compatible = "kingdisplay,kd097d04";
-			reg = <0>;
-			power-supply = <...>;
-			backlight = <&backlight>;
-			enable-gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>;
-		};
-	};
diff --git a/Documentation/devicetree/bindings/display/panel/leadtek,ltk050h3146w.yaml b/Documentation/devicetree/bindings/display/panel/leadtek,ltk050h3146w.yaml
new file mode 100644
index 000000000000..a372bdc5bde1
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/leadtek,ltk050h3146w.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/leadtek,ltk050h3146w.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Leadtek LTK050H3146W 5.0in 720x1280 DSI panel
+
+maintainers:
+  - Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+    enum:
+      - leadtek,ltk050h3146w
+      - leadtek,ltk050h3146w-a2
+  reg: true
+  backlight: true
+  reset-gpios: true
+  iovcc-supply:
+     description: regulator that supplies the iovcc voltage
+  vci-supply:
+     description: regulator that supplies the vci voltage
+
+required:
+  - compatible
+  - reg
+  - backlight
+  - iovcc-supply
+  - vci-supply
+
+additionalProperties: false
+
+examples:
+  - |
+    dsi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+        panel@0 {
+            compatible = "leadtek,ltk050h3146w";
+            reg = <0>;
+            backlight = <&backlight>;
+            iovcc-supply = <&vcc_1v8>;
+            vci-supply = <&vcc3v3_lcd>;
+        };
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/display/panel/leadtek,ltk500hd1829.yaml b/Documentation/devicetree/bindings/display/panel/leadtek,ltk500hd1829.yaml
index fd931b293816..b900973b5f7b 100644
--- a/Documentation/devicetree/bindings/display/panel/leadtek,ltk500hd1829.yaml
+++ b/Documentation/devicetree/bindings/display/panel/leadtek,ltk500hd1829.yaml
@@ -37,7 +37,6 @@ examples:
     dsi {
         #address-cells = <1>;
         #size-cells = <0>;
-        reg = <0xff450000 0x1000>;
 
         panel@0 {
             compatible = "leadtek,ltk500hd1829";
diff --git a/Documentation/devicetree/bindings/display/panel/lg,acx467akm-7.txt b/Documentation/devicetree/bindings/display/panel/lg,acx467akm-7.txt
deleted file mode 100644
index fc1e1b325e49..000000000000
--- a/Documentation/devicetree/bindings/display/panel/lg,acx467akm-7.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-LG ACX467AKM-7 4.95" 1080×1920 LCD Panel
-
-Required properties:
-- compatible: must be "lg,acx467akm-7"
-
-This binding is compatible with the simple-panel binding, which is specified
-in simple-panel.txt in this directory.
diff --git a/Documentation/devicetree/bindings/display/panel/lg,ld070wx3-sl01.txt b/Documentation/devicetree/bindings/display/panel/lg,ld070wx3-sl01.txt
deleted file mode 100644
index 5e649cb9aa1a..000000000000
--- a/Documentation/devicetree/bindings/display/panel/lg,ld070wx3-sl01.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-LG Corporation 7" WXGA TFT LCD panel
-
-Required properties:
-- compatible: should be "lg,ld070wx3-sl01"
-
-This binding is compatible with the simple-panel binding, which is specified
-in simple-panel.txt in this directory.
diff --git a/Documentation/devicetree/bindings/display/panel/lg,lg4573.txt b/Documentation/devicetree/bindings/display/panel/lg,lg4573.txt
deleted file mode 100644
index 824441f4e95a..000000000000
--- a/Documentation/devicetree/bindings/display/panel/lg,lg4573.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-LG LG4573 TFT Liquid Crystal Display with SPI control bus
-
-Required properties:
-  - compatible: "lg,lg4573"
-  - reg: address of the panel on the SPI bus
-
-The panel must obey rules for SPI slave device specified in document [1].
-
-[1]: Documentation/devicetree/bindings/spi/spi-bus.txt
-
-Example:
-
-	lcd_panel: display@0 {
-		#address-cells = <1>;
-		#size-cells = <1>;
-		compatible = "lg,lg4573";
-		spi-max-frequency = <10000000>;
-		reg = <0>;
-	};
diff --git a/Documentation/devicetree/bindings/display/panel/lg,lg4573.yaml b/Documentation/devicetree/bindings/display/panel/lg,lg4573.yaml
new file mode 100644
index 000000000000..b4314ce7b411
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/lg,lg4573.yaml
@@ -0,0 +1,45 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/lg,lg4573.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: LG LG4573 TFT Liquid Crystal Display with SPI control bus
+
+description: |
+  The panel must obey the rules for a SPI slave device as specified in
+  spi/spi-controller.yaml
+
+maintainers:
+  - Heiko Schocher <hs@denx.de>
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+    const: lg,lg4573
+
+  reg: true
+  spi-max-frequency: true
+
+required:
+  - compatible
+  - reg
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    spi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        lcd_panel: display@0 {
+            compatible = "lg,lg4573";
+            spi-max-frequency = <10000000>;
+            reg = <0>;
+        };
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/display/panel/lg,lh500wx1-sd03.txt b/Documentation/devicetree/bindings/display/panel/lg,lh500wx1-sd03.txt
deleted file mode 100644
index a04fd2b2e73d..000000000000
--- a/Documentation/devicetree/bindings/display/panel/lg,lh500wx1-sd03.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-LG Corporation 5" HD TFT LCD panel
-
-Required properties:
-- compatible: should be "lg,lh500wx1-sd03"
-
-This binding is compatible with the simple-panel binding, which is specified
-in simple-panel.txt in this directory.
diff --git a/Documentation/devicetree/bindings/display/panel/lgphilips,lb035q02.txt b/Documentation/devicetree/bindings/display/panel/lgphilips,lb035q02.txt
deleted file mode 100644
index 1a1e653e5407..000000000000
--- a/Documentation/devicetree/bindings/display/panel/lgphilips,lb035q02.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-LG.Philips LB035Q02 Panel
-=========================
-
-Required properties:
-- compatible: "lgphilips,lb035q02"
-- enable-gpios: panel enable gpio
-
-Optional properties:
-- label: a symbolic name for the panel
-
-Required nodes:
-- Video port for DPI input
-
-Example
--------
-
-lcd-panel: panel@0 {
-	compatible = "lgphilips,lb035q02";
-	reg = <0>;
-	spi-max-frequency = <100000>;
-	spi-cpol;
-	spi-cpha;
-
-	label = "lcd";
-
-	enable-gpios = <&gpio7 7 0>;
-
-	port {
-		lcd_in: endpoint {
-			remote-endpoint = <&dpi_out>;
-		};
-	};
-};
diff --git a/Documentation/devicetree/bindings/display/panel/lgphilips,lb035q02.yaml b/Documentation/devicetree/bindings/display/panel/lgphilips,lb035q02.yaml
new file mode 100644
index 000000000000..830e335ddb53
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/lgphilips,lb035q02.yaml
@@ -0,0 +1,59 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/lgphilips,lb035q02.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: LG.Philips LB035Q02 Panel
+
+description: |
+  The panel must obey the rules for a SPI slave device as specified in
+  spi/spi-controller.yaml
+
+maintainers:
+  - Tomi Valkeinen <tomi.valkeinen@ti.com>
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+    const: lgphilips,lb035q02
+
+  label: true
+  enable-gpios: true
+  port: true
+
+required:
+  - compatible
+  - enable-gpios
+  - port
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    spi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        panel: panel@0 {
+            compatible = "lgphilips,lb035q02";
+            reg = <0>;
+            spi-max-frequency = <100000>;
+            spi-cpol;
+            spi-cpha;
+
+            label = "lcd";
+
+            enable-gpios = <&gpio7 7 0>;
+
+            port {
+                lcd_in: endpoint {
+                    remote-endpoint = <&dpi_out>;
+                };
+            };
+        };
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/display/panel/lvds.yaml b/Documentation/devicetree/bindings/display/panel/lvds.yaml
index d0083301acbe..946dd354256c 100644
--- a/Documentation/devicetree/bindings/display/panel/lvds.yaml
+++ b/Documentation/devicetree/bindings/display/panel/lvds.yaml
@@ -96,12 +96,20 @@ properties:
       If set, reverse the bit order described in the data mappings below on all
       data lanes, transmitting bits for slots 6 to 0 instead of 0 to 6.
 
+  port: true
+  ports: true
+
 required:
   - compatible
   - data-mapping
   - width-mm
   - height-mm
   - panel-timing
-  - port
+
+oneOf:
+  - required:
+      - port
+  - required:
+      - ports
 
 ...
diff --git a/Documentation/devicetree/bindings/display/panel/olimex,lcd-olinuxino.txt b/Documentation/devicetree/bindings/display/panel/olimex,lcd-olinuxino.txt
deleted file mode 100644
index a89f9c830a85..000000000000
--- a/Documentation/devicetree/bindings/display/panel/olimex,lcd-olinuxino.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-Binding for Olimex Ltd. LCD-OLinuXino bridge panel.
-
-This device can be used as bridge between a host controller and LCD panels.
-Currently supported LCDs are:
-  - LCD-OLinuXino-4.3TS
-  - LCD-OLinuXino-5
-  - LCD-OLinuXino-7
-  - LCD-OLinuXino-10
-
-The panel itself contains:
-  - AT24C16C EEPROM holding panel identification and timing requirements
-  - AR1021 resistive touch screen controller (optional)
-  - FT5x6 capacitive touch screnn controller (optional)
-  - GT911/GT928 capacitive touch screen controller (optional)
-
-The above chips share same I2C bus. The EEPROM is factory preprogrammed with
-device information (id, serial, etc.) and timing requirements.
-
-Touchscreen bingings can be found in these files:
-  - input/touchscreen/goodix.txt
-  - input/touchscreen/edt-ft5x06.txt
-  - input/touchscreen/ar1021.txt
-
-Required properties:
-  - compatible: should be "olimex,lcd-olinuxino"
-  - reg: address of the configuration EEPROM, should be <0x50>
-  - power-supply: phandle of the regulator that provides the supply voltage
-
-Optional properties:
-  - enable-gpios: GPIO pin to enable or disable the panel
-  - backlight: phandle of the backlight device attacked to the panel
-
-Example:
-&i2c2 {
-	panel@50 {
-		compatible = "olimex,lcd-olinuxino";
-		reg = <0x50>;
-		power-supply = <&reg_vcc5v0>;
-		enable-gpios = <&pio 7 8 GPIO_ACTIVE_HIGH>;
-		backlight = <&backlight>;
-	};
-};
diff --git a/Documentation/devicetree/bindings/display/panel/olimex,lcd-olinuxino.yaml b/Documentation/devicetree/bindings/display/panel/olimex,lcd-olinuxino.yaml
new file mode 100644
index 000000000000..2329d9610f83
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/olimex,lcd-olinuxino.yaml
@@ -0,0 +1,70 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/olimex,lcd-olinuxino.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Binding for Olimex Ltd. LCD-OLinuXino bridge panel.
+
+maintainers:
+  - Stefan Mavrodiev <stefan@olimex.com>
+
+description: |
+  This device can be used as bridge between a host controller and LCD panels.
+  Currently supported LCDs are:
+    - LCD-OLinuXino-4.3TS
+    - LCD-OLinuXino-5
+    - LCD-OLinuXino-7
+    - LCD-OLinuXino-10
+
+  The panel itself contains:
+    - AT24C16C EEPROM holding panel identification and timing requirements
+    - AR1021 resistive touch screen controller (optional)
+    - FT5x6 capacitive touch screnn controller (optional)
+    - GT911/GT928 capacitive touch screen controller (optional)
+
+  The above chips share same I2C bus. The EEPROM is factory preprogrammed with
+  device information (id, serial, etc.) and timing requirements.
+
+  Touchscreen bingings can be found in these files:
+    - input/touchscreen/goodix.yaml
+    - input/touchscreen/edt-ft5x06.txt
+    - input/touchscreen/ar1021.txt
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+    const: olimex,lcd-olinuxino
+
+  backlight: true
+  enable-gpios: true
+  power-supply: true
+  reg: true
+
+required:
+  - compatible
+  - reg
+  - power-supply
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        panel@50 {
+            compatible = "olimex,lcd-olinuxino";
+            reg = <0x50>;
+            power-supply = <&reg_vcc5v0>;
+            enable-gpios = <&pio 7 8 GPIO_ACTIVE_HIGH>;
+            backlight = <&backlight>;
+        };
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/display/panel/osddisplays,osd101t2587-53ts.txt b/Documentation/devicetree/bindings/display/panel/osddisplays,osd101t2587-53ts.txt
deleted file mode 100644
index 9d88e96003fc..000000000000
--- a/Documentation/devicetree/bindings/display/panel/osddisplays,osd101t2587-53ts.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-One Stop Displays OSD101T2587-53TS 10.1" 1920x1200 panel
-
-The panel is similar to OSD101T2045-53TS, but it needs additional
-MIPI_DSI_TURN_ON_PERIPHERAL message from the host.
-
-Required properties:
-- compatible: should be "osddisplays,osd101t2587-53ts"
-- power-supply: as specified in the base binding
-
-Optional properties:
-- backlight: as specified in the base binding
-
-This binding is compatible with the simple-panel binding, which is specified
-in simple-panel.txt in this directory.
diff --git a/Documentation/devicetree/bindings/display/panel/panel-common.yaml b/Documentation/devicetree/bindings/display/panel/panel-common.yaml
index ed051ba12084..17b8367f12dd 100644
--- a/Documentation/devicetree/bindings/display/panel/panel-common.yaml
+++ b/Documentation/devicetree/bindings/display/panel/panel-common.yaml
@@ -63,9 +63,9 @@ properties:
 
   display-timings:
     description:
-      Some display panels supports several resolutions with different timing.
+      Some display panels support several resolutions with different timings.
       The display-timings bindings supports specifying several timings and
-      optional specify which is the native mode.
+      optionally specifying which is the native mode.
     allOf:
       - $ref: display-timings.yaml#
 
@@ -124,6 +124,13 @@ properties:
       while active. Active high reset signals can be supported by inverting the
       GPIO specifier polarity flag.
 
+  te-gpios:
+    maxItems: 1
+    description:
+      GPIO spec for the tearing effect synchronization signal.
+      The tearing effect signal is active high. Active low signals can be
+      supported by inverting the GPIO specifier polarity flag.
+
   # Power
   power-supply:
     description:
diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple-dsi.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple-dsi.yaml
index b2e8742fd6af..423532f57e89 100644
--- a/Documentation/devicetree/bindings/display/panel/panel-simple-dsi.yaml
+++ b/Documentation/devicetree/bindings/display/panel/panel-simple-dsi.yaml
@@ -29,6 +29,18 @@ properties:
       # compatible must be listed in alphabetical order, ordered by compatible.
       # The description in the comment is mandatory for each compatible.
 
+        # AU Optronics Corporation 8.0" WUXGA TFT LCD panel
+      - auo,b080uan01
+        # Boe Corporation 8.0" WUXGA TFT LCD panel
+      - boe,tv080wum-nl0
+        # Kingdisplay KD097D04 9.7" 1536x2048 TFT LCD panel
+      - kingdisplay,kd097d04
+        # LG ACX467AKM-7 4.95" 1080×1920 LCD Panel
+      - lg,acx467akm-7
+        # LG Corporation 7" WXGA TFT LCD panel
+      - lg,ld070wx3-sl01
+        # One Stop Displays OSD101T2587-53TS 10.1" 1920x1200 panel
+      - osddisplays,osd101t2587-53ts
         # Panasonic 10" WUXGA TFT LCD panel
       - panasonic,vvx10f034n00
 
diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
index 393ffc6acbba..989cb3ca6d58 100644
--- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
+++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
@@ -33,8 +33,6 @@ properties:
       - ampire,am-480272h3tmqw-t01h
         # Ampire AM-800480R3TMQW-A1H 7.0" WVGA TFT LCD panel
       - ampire,am800480r3tmqwa1h
-        # AU Optronics Corporation 8.0" WUXGA TFT LCD panel
-      - auo,b080uan01
         # AU Optronics Corporation 10.1" WSVGA TFT LCD panel
       - auo,b101aw03
         # AU Optronics Corporation 10.1" WSVGA TFT LCD panel
@@ -71,8 +69,6 @@ properties:
       - boe,nv101wxmn51
         # BOE NV140FHM-N49 14.0" FHD a-Si FT panel
       - boe,nv140fhmn49
-        # Boe Corporation 8.0" WUXGA TFT LCD panel
-      - boe,tv080wum-nl0
         # CDTech(H.K.) Electronics Limited 4.3" 480x272 color TFT-LCD panel
       - cdtech,s043wq26h-ct7
         # CDTech(H.K.) Electronics Limited 7" 800x480 color TFT-LCD panel
@@ -155,6 +151,8 @@ properties:
       - lemaker,bl035-rgb-002
         # LG 7" (800x480 pixels) TFT LCD panel
       - lg,lb070wv8
+        # LG Corporation 5" HD TFT LCD panel
+      - lg,lh500wx1-sd03
         # LG LP079QX1-SP0V 7.9" (1536x2048 pixels) TFT LCD panel
       - lg,lp079qx1-sp0v
         # LG 9.7" (2048x1536 pixels) TFT LCD panel
@@ -227,6 +225,8 @@ properties:
       - sharp,ls020b1dd01d
         # Shelly SCA07010-BFN-LNN 7.0" WVGA TFT LCD panel
       - shelly,sca07010-bfn-lnn
+        # Starry KR070PE2T 7" WVGA TFT LCD panel
+      - starry,kr070pe2t
         # Starry 12.2" (1920x1200 pixels) TFT LCD panel
       - starry,kr122ea0sra
         # Tianma Micro-electronics TM070JDHG30 7.0" WXGA TFT LCD panel
diff --git a/Documentation/devicetree/bindings/display/panel/raydium,rm67191.txt b/Documentation/devicetree/bindings/display/panel/raydium,rm67191.txt
deleted file mode 100644
index 10424695aa02..000000000000
--- a/Documentation/devicetree/bindings/display/panel/raydium,rm67191.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-Raydium RM67171 OLED LCD panel with MIPI-DSI protocol
-
-Required properties:
-- compatible: 		"raydium,rm67191"
-- reg:			virtual channel for MIPI-DSI protocol
-			must be <0>
-- dsi-lanes:		number of DSI lanes to be used
-			must be <3> or <4>
-- port: 		input port node with endpoint definition as
-			defined in Documentation/devicetree/bindings/graph.txt;
-			the input port should be connected to a MIPI-DSI device
-			driver
-
-Optional properties:
-- reset-gpios:		a GPIO spec for the RST_B GPIO pin
-- v3p3-supply:		phandle to 3.3V regulator that powers the VDD_3V3 pin
-- v1p8-supply:		phandle to 1.8V regulator that powers the VDD_1V8 pin
-- width-mm:		see panel-common.txt
-- height-mm:		see panel-common.txt
-- video-mode:		0 - burst-mode
-			1 - non-burst with sync event
-			2 - non-burst with sync pulse
-
-Example:
-
-	panel@0 {
-		compatible = "raydium,rm67191";
-		reg = <0>;
-		pinctrl-0 = <&pinctrl_mipi_dsi_0_1_en>;
-		pinctrl-names = "default";
-		reset-gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
-		dsi-lanes = <4>;
-		width-mm = <68>;
-		height-mm = <121>;
-
-		port {
-			panel_in: endpoint {
-				remote-endpoint = <&mipi_out>;
-			};
-		};
-	};
diff --git a/Documentation/devicetree/bindings/display/panel/raydium,rm67191.yaml b/Documentation/devicetree/bindings/display/panel/raydium,rm67191.yaml
new file mode 100644
index 000000000000..745dd247c409
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/raydium,rm67191.yaml
@@ -0,0 +1,75 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/raydium,rm67191.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Raydium RM67171 OLED LCD panel with MIPI-DSI protocol
+
+maintainers:
+  - Robert Chiras <robert.chiras@nxp.com>
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+    const: raydium,rm67191
+
+  reg: true
+  port: true
+  reset-gpios: true
+  width-mm: true
+  height-mm: true
+
+  dsi-lanes:
+    description: Number of DSI lanes to be used must be <3> or <4>
+    enum: [3, 4]
+
+  v3p3-supply:
+    description: phandle to 3.3V regulator that powers the VDD_3V3 pin
+
+  v1p8-supply:
+    description: phandle to 1.8V regulator that powers the VDD_1V8 pin
+
+  video-mode:
+    description: |
+      0 - burst-mode
+      1 - non-burst with sync event
+      2 - non-burst with sync pulse
+    enum: [0, 1, 2]
+
+required:
+  - compatible
+  - reg
+  - dsi-lanes
+  - port
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    dsi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        panel@0 {
+            compatible = "raydium,rm67191";
+            reg = <0>;
+            reset-gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
+            dsi-lanes = <4>;
+            width-mm = <68>;
+            height-mm = <121>;
+            video-mode = <1>;
+
+            port {
+                panel_in: endpoint {
+                    remote-endpoint = <&mipi_out>;
+                };
+            };
+        };
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/display/panel/samsung,amoled-mipi-dsi.yaml b/Documentation/devicetree/bindings/display/panel/samsung,amoled-mipi-dsi.yaml
new file mode 100644
index 000000000000..96bdde9298e0
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/samsung,amoled-mipi-dsi.yaml
@@ -0,0 +1,65 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/samsung,amoled-mipi-dsi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung AMOLED MIPI-DSI panels
+
+maintainers:
+  - Hoegeun Kwon <hoegeun.kwon@samsung.com>
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+    enum:
+        # Samsung S6E63J0X03 1.63" 320x320 AMOLED panel
+      - samsung,s6e63j0x03
+        # Samsung S6E3HA2 5.7" 1440x2560 AMOLED panel
+      - samsung,s6e3ha2
+        # Samsung S6E3HF2 5.65" 1600x2560 AMOLED panel
+      - samsung,s6e3hf2
+
+  reg: true
+  reset-gpios: true
+  enable-gpios: true
+  te-gpios: true
+
+  vdd3-supply:
+    description: I/O voltage supply
+
+  vci-supply:
+    description: voltage supply for analog circuits
+
+required:
+  - compatible
+  - reg
+  - vdd3-supply
+  - vci-supply
+  - reset-gpios
+  - enable-gpios
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    dsi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        panel@0 {
+            compatible = "samsung,s6e3ha2";
+            reg = <0>;
+            vdd3-supply = <&ldo27_reg>;
+            vci-supply = <&ldo28_reg>;
+            reset-gpios = <&gpg0 0 GPIO_ACTIVE_LOW>;
+            enable-gpios = <&gpf1 5 GPIO_ACTIVE_HIGH>;
+            te-gpios = <&gpf1 3 GPIO_ACTIVE_HIGH>;
+        };
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/display/panel/samsung,ld9040.txt b/Documentation/devicetree/bindings/display/panel/samsung,ld9040.txt
deleted file mode 100644
index 354d4d1df4ff..000000000000
--- a/Documentation/devicetree/bindings/display/panel/samsung,ld9040.txt
+++ /dev/null
@@ -1,66 +0,0 @@
-Samsung LD9040 AMOLED LCD parallel RGB panel with SPI control bus
-
-Required properties:
-  - compatible: "samsung,ld9040"
-  - reg: address of the panel on SPI bus
-  - vdd3-supply: core voltage supply
-  - vci-supply: voltage supply for analog circuits
-  - reset-gpios: a GPIO spec for the reset pin
-  - display-timings: timings for the connected panel according to [1]
-
-The panel must obey rules for SPI slave device specified in document [2].
-
-Optional properties:
-  - power-on-delay: delay after turning regulators on [ms]
-  - reset-delay: delay after reset sequence [ms]
-  - panel-width-mm: physical panel width [mm]
-  - panel-height-mm: physical panel height [mm]
-
-The device node can contain one 'port' child node with one child
-'endpoint' node, according to the bindings defined in [3]. This
-node should describe panel's video bus.
-
-[1]: Documentation/devicetree/bindings/display/panel/display-timing.txt
-[2]: Documentation/devicetree/bindings/spi/spi-bus.txt
-[3]: Documentation/devicetree/bindings/media/video-interfaces.txt
-
-Example:
-
-	lcd@0 {
-		compatible = "samsung,ld9040";
-		reg = <0>;
-		vdd3-supply = <&ldo7_reg>;
-		vci-supply = <&ldo17_reg>;
-		reset-gpios = <&gpy4 5 0>;
-		spi-max-frequency = <1200000>;
-		spi-cpol;
-		spi-cpha;
-		power-on-delay = <10>;
-		reset-delay = <10>;
-		panel-width-mm = <90>;
-		panel-height-mm = <154>;
-
-		display-timings {
-			timing {
-				clock-frequency = <23492370>;
-				hactive = <480>;
-				vactive = <800>;
-				hback-porch = <16>;
-				hfront-porch = <16>;
-				vback-porch = <2>;
-				vfront-porch = <28>;
-				hsync-len = <2>;
-				vsync-len = <1>;
-				hsync-active = <0>;
-				vsync-active = <0>;
-				de-active = <0>;
-				pixelclk-active = <0>;
-			};
-		};
-
-		port {
-			lcd_ep: endpoint {
-				remote-endpoint = <&fimd_dpi_ep>;
-			};
-		};
-	};
diff --git a/Documentation/devicetree/bindings/display/panel/samsung,ld9040.yaml b/Documentation/devicetree/bindings/display/panel/samsung,ld9040.yaml
new file mode 100644
index 000000000000..060ee27a4749
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/samsung,ld9040.yaml
@@ -0,0 +1,107 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/samsung,ld9040.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung LD9040 AMOLED LCD parallel RGB panel with SPI control bus
+
+description: |
+  The panel must obey the rules for a SPI slave device as specified in
+  spi/spi-controller.yaml
+
+maintainers:
+  - Andrzej Hajda <a.hajda@samsung.com>
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+    const: samsung,ld9040
+
+  display-timings: true
+  port: true
+  reg: true
+  reset-gpios: true
+
+  vdd3-supply:
+    description: core voltage supply
+
+  vci-supply:
+    description: voltage supply for analog circuits
+
+  power-on-delay:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: delay after turning regulators on [ms]
+
+  reset-delay:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: delay after reset sequence [ms]
+
+  panel-width-mm:
+    description: physical panel width [mm]
+
+  panel-height-mm:
+    description: physical panel height [mm]
+
+required:
+  - compatible
+  - reg
+  - vdd3-supply
+  - vci-supply
+  - reset-gpios
+  - display-timings
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    spi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        lcd@0 {
+            compatible = "samsung,ld9040";
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            reg = <0>;
+            vdd3-supply = <&ldo7_reg>;
+            vci-supply = <&ldo17_reg>;
+            reset-gpios = <&gpy4 5 0>;
+            spi-max-frequency = <1200000>;
+            spi-cpol;
+            spi-cpha;
+            power-on-delay = <10>;
+            reset-delay = <10>;
+            panel-width-mm = <90>;
+            panel-height-mm = <154>;
+
+            display-timings {
+                timing {
+                    clock-frequency = <23492370>;
+                    hactive = <480>;
+                    vactive = <800>;
+                    hback-porch = <16>;
+                    hfront-porch = <16>;
+                    vback-porch = <2>;
+                    vfront-porch = <28>;
+                    hsync-len = <2>;
+                    vsync-len = <1>;
+                    hsync-active = <0>;
+                    vsync-active = <0>;
+                    de-active = <0>;
+                    pixelclk-active = <0>;
+                };
+            };
+
+            port {
+                lcd_ep: endpoint {
+                    remote-endpoint = <&fimd_dpi_ep>;
+                };
+            };
+        };
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/display/panel/samsung,s6d16d0.txt b/Documentation/devicetree/bindings/display/panel/samsung,s6d16d0.txt
deleted file mode 100644
index b94e366f451b..000000000000
--- a/Documentation/devicetree/bindings/display/panel/samsung,s6d16d0.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-Samsung S6D16D0 4" 864x480 AMOLED panel
-
-Required properties:
-  - compatible: should be:
-    "samsung,s6d16d0",
-  - reg: the virtual channel number of a DSI peripheral
-  - vdd1-supply: I/O voltage supply
-  - reset-gpios: a GPIO spec for the reset pin (active low)
-
-The device node can contain one 'port' child node with one child
-'endpoint' node, according to the bindings defined in
-media/video-interfaces.txt. This node should describe panel's video bus.
-
-Example:
-&dsi {
-	...
-
-	panel@0 {
-		compatible = "samsung,s6d16d0";
-		reg = <0>;
-		vdd1-supply = <&foo>;
-		reset-gpios = <&foo_gpio 0 GPIO_ACTIVE_LOW>;
-
-		port {
-			panel_in: endpoint {
-				remote-endpoint = <&dsi_out>;
-			};
-		};
-	};
-};
diff --git a/Documentation/devicetree/bindings/display/panel/samsung,s6d16d0.yaml b/Documentation/devicetree/bindings/display/panel/samsung,s6d16d0.yaml
new file mode 100644
index 000000000000..66d147496bc3
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/samsung,s6d16d0.yaml
@@ -0,0 +1,56 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/samsung,s6d16d0.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung S6D16D0 4" 864x480 AMOLED panel
+
+maintainers:
+  - Linus Walleij <linus.walleij@linaro.org>
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+    const: samsung,s6d16d0
+
+  port: true
+  reg: true
+  reset-gpios: true
+
+  vdd1-supply:
+    description: I/O voltage supply
+
+required:
+  - compatible
+  - reg
+  - vdd1-supply
+  - reset-gpios
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    dsi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        panel@0 {
+            compatible = "samsung,s6d16d0";
+            reg = <0>;
+            vdd1-supply = <&foo>;
+            reset-gpios = <&foo_gpio 0 GPIO_ACTIVE_LOW>;
+
+            port {
+                panel_in: endpoint {
+                    remote-endpoint = <&dsi_out>;
+                };
+            };
+        };
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/display/panel/samsung,s6e3ha2.txt b/Documentation/devicetree/bindings/display/panel/samsung,s6e3ha2.txt
deleted file mode 100644
index 4acea25c244b..000000000000
--- a/Documentation/devicetree/bindings/display/panel/samsung,s6e3ha2.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-Samsung S6E3HA2 5.7" 1440x2560 AMOLED panel
-Samsung S6E3HF2 5.65" 1600x2560 AMOLED panel
-
-Required properties:
-  - compatible: should be one of:
-    "samsung,s6e3ha2",
-    "samsung,s6e3hf2".
-  - reg: the virtual channel number of a DSI peripheral
-  - vdd3-supply: I/O voltage supply
-  - vci-supply: voltage supply for analog circuits
-  - reset-gpios: a GPIO spec for the reset pin (active low)
-  - enable-gpios: a GPIO spec for the panel enable pin (active high)
-
-Optional properties:
-  - te-gpios: a GPIO spec for the tearing effect synchronization signal
-    gpio pin (active high)
-
-Example:
-&dsi {
-	...
-
-	panel@0 {
-		compatible = "samsung,s6e3ha2";
-		reg = <0>;
-		vdd3-supply = <&ldo27_reg>;
-		vci-supply = <&ldo28_reg>;
-		reset-gpios = <&gpg0 0 GPIO_ACTIVE_LOW>;
-		enable-gpios = <&gpf1 5 GPIO_ACTIVE_HIGH>;
-		te-gpios = <&gpf1 3 GPIO_ACTIVE_HIGH>;
-	};
-};
diff --git a/Documentation/devicetree/bindings/display/panel/samsung,s6e63j0x03.txt b/Documentation/devicetree/bindings/display/panel/samsung,s6e63j0x03.txt
deleted file mode 100644
index 3f1a8392af7f..000000000000
--- a/Documentation/devicetree/bindings/display/panel/samsung,s6e63j0x03.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-Samsung S6E63J0X03 1.63" 320x320 AMOLED panel (interface: MIPI-DSI command mode)
-
-Required properties:
-  - compatible: "samsung,s6e63j0x03"
-  - reg: the virtual channel number of a DSI peripheral
-  - vdd3-supply: I/O voltage supply
-  - vci-supply: voltage supply for analog circuits
-  - reset-gpios: a GPIO spec for the reset pin (active low)
-  - te-gpios: a GPIO spec for the tearing effect synchronization signal
-    gpio pin (active high)
-
-Example:
-&dsi {
-	...
-
-	panel@0 {
-		compatible = "samsung,s6e63j0x03";
-		reg = <0>;
-		vdd3-supply = <&ldo16_reg>;
-		vci-supply = <&ldo20_reg>;
-		reset-gpios = <&gpe0 1 GPIO_ACTIVE_LOW>;
-		te-gpios = <&gpx0 6 GPIO_ACTIVE_HIGH>;
-	};
-};
diff --git a/Documentation/devicetree/bindings/display/panel/samsung,s6e63m0.txt b/Documentation/devicetree/bindings/display/panel/samsung,s6e63m0.txt
deleted file mode 100644
index 9fb9ebeef8e4..000000000000
--- a/Documentation/devicetree/bindings/display/panel/samsung,s6e63m0.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-Samsung s6e63m0 AMOLED LCD panel
-
-Required properties:
-  - compatible: "samsung,s6e63m0"
-  - reset-gpios: GPIO spec for reset pin
-  - vdd3-supply: VDD regulator
-  - vci-supply: VCI regulator
-
-The panel must obey rules for SPI slave device specified in document [1].
-
-The device node can contain one 'port' child node with one child
-'endpoint' node, according to the bindings defined in [2]. This
-node should describe panel's video bus.
-
-[1]: Documentation/devicetree/bindings/spi/spi-bus.txt
-[2]: Documentation/devicetree/bindings/media/video-interfaces.txt
-
-Example:
-
-		s6e63m0: display@0 {
-			compatible = "samsung,s6e63m0";
-			reg = <0>;
-			reset-gpio = <&mp05 5 1>;
-			vdd3-supply = <&ldo12_reg>;
-			vci-supply = <&ldo11_reg>;
-			spi-max-frequency = <1200000>;
-
-			port {
-				lcd_ep: endpoint {
-					remote-endpoint = <&fimd_ep>;
-				};
-			};
-		};
diff --git a/Documentation/devicetree/bindings/display/panel/samsung,s6e63m0.yaml b/Documentation/devicetree/bindings/display/panel/samsung,s6e63m0.yaml
new file mode 100644
index 000000000000..1dab80ae1d0a
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/samsung,s6e63m0.yaml
@@ -0,0 +1,60 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/samsung,s6e63m0.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung s6e63m0 AMOLED LCD panel
+
+maintainers:
+  - Jonathan Bakker <xc-racer2@live.ca>
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+    const: samsung,s6e63m0
+
+  reg: true
+  reset-gpios: true
+  port: true
+
+  vdd3-supply:
+    description: VDD regulator
+
+  vci-supply:
+    description: VCI regulator
+
+required:
+  - compatible
+  - reset-gpios
+  - vdd3-supply
+  - vci-supply
+  - port
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    spi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        display@0 {
+            compatible = "samsung,s6e63m0";
+            reg = <0>;
+            reset-gpios = <&mp05 5 1>;
+            vdd3-supply = <&ldo12_reg>;
+            vci-supply = <&ldo11_reg>;
+            spi-max-frequency = <1200000>;
+
+            port {
+                lcd_ep: endpoint {
+                    remote-endpoint = <&fimd_ep>;
+                };
+            };
+        };
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/display/panel/seiko,43wvf1g.txt b/Documentation/devicetree/bindings/display/panel/seiko,43wvf1g.txt
deleted file mode 100644
index aae57ef36cdd..000000000000
--- a/Documentation/devicetree/bindings/display/panel/seiko,43wvf1g.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-Seiko Instruments Inc. 4.3" WVGA (800 x RGB x 480) TFT with Touch-Panel
-
-Required properties:
-- compatible: should be "sii,43wvf1g".
-- "dvdd-supply": 3v3 digital regulator.
-- "avdd-supply": 5v analog regulator.
-
-Optional properties:
-- backlight: phandle for the backlight control.
-
-Example:
-
-	panel {
-		compatible = "sii,43wvf1g";
-		backlight = <&backlight_display>;
-		dvdd-supply = <&reg_lcd_3v3>;
-		avdd-supply = <&reg_lcd_5v>;
-		port {
-			panel_in: endpoint {
-				remote-endpoint = <&display_out>;
-			};
-		};
-	};
diff --git a/Documentation/devicetree/bindings/display/panel/seiko,43wvf1g.yaml b/Documentation/devicetree/bindings/display/panel/seiko,43wvf1g.yaml
new file mode 100644
index 000000000000..cfaa50cf5f5d
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/seiko,43wvf1g.yaml
@@ -0,0 +1,50 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/seiko,43wvf1g.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Seiko Instruments Inc. 4.3" WVGA (800 x RGB x 480) TFT with Touch-Panel
+
+maintainers:
+  - Marco Franchi <marco.franchi@nxp.com>
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+    const: sii,43wvf1g
+
+  backlight: true
+  port: true
+
+  dvdd-supply:
+    description: 3v3 digital regulator
+
+  avdd-supply:
+    description: 5v analog regulator
+
+required:
+  - compatible
+  - dvdd-supply
+  - avdd-supply
+
+additionalProperties: false
+
+examples:
+  - |
+    panel {
+        compatible = "sii,43wvf1g";
+
+        backlight = <&backlight_display>;
+        dvdd-supply = <&reg_lcd_3v3>;
+        avdd-supply = <&reg_lcd_5v>;
+        port {
+            panel_in: endpoint {
+                remote-endpoint = <&display_out>;
+            };
+        };
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/display/panel/sharp,lq150x1lg11.txt b/Documentation/devicetree/bindings/display/panel/sharp,lq150x1lg11.txt
deleted file mode 100644
index 0f57c3143506..000000000000
--- a/Documentation/devicetree/bindings/display/panel/sharp,lq150x1lg11.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-Sharp 15" LQ150X1LG11 XGA TFT LCD panel
-
-Required properties:
-- compatible: should be "sharp,lq150x1lg11"
-- power-supply: regulator to provide the VCC supply voltage (3.3 volts)
-
-Optional properties:
-- backlight: phandle of the backlight device
-- rlud-gpios: a single GPIO for the RL/UD (rotate 180 degrees) pin.
-- sellvds-gpios: a single GPIO for the SELLVDS pin.
-
-If rlud-gpios and/or sellvds-gpios are not specified, the RL/UD and/or SELLVDS
-pins are assumed to be handled appropriately by the hardware.
-
-Example:
-
-	backlight: backlight {
-		compatible = "pwm-backlight";
-		pwms = <&pwm 0 100000>;                      /* VBR */
-
-		brightness-levels = <0 20 40 60 80 100>;
-		default-brightness-level = <2>;
-
-		power-supply = <&vdd_12v_reg>;               /* VDD */
-		enable-gpios = <&gpio 42 GPIO_ACTIVE_HIGH>;  /* XSTABY */
-	};
-
-	panel {
-		compatible = "sharp,lq150x1lg11";
-
-		power-supply = <&vcc_3v3_reg>;               /* VCC */
-
-		backlight = <&backlight>;
-		rlud-gpios = <&gpio 17 GPIO_ACTIVE_HIGH>;    /* RL/UD */
-		sellvds-gpios = <&gpio 18 GPIO_ACTIVE_HIGH>; /* SELLVDS */
-	};
diff --git a/Documentation/devicetree/bindings/display/panel/sharp,lq150x1lg11.yaml b/Documentation/devicetree/bindings/display/panel/sharp,lq150x1lg11.yaml
new file mode 100644
index 000000000000..92f2d12f4f4c
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/sharp,lq150x1lg11.yaml
@@ -0,0 +1,58 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/sharp,lq150x1lg11.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Sharp 15" LQ150X1LG11 XGA TFT LCD panel
+
+maintainers:
+  - Peter Rosin <peda@axentia.se>
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+    const: sharp,lq150x1lg11
+
+  power-supply: true
+  backlight: true
+
+  rlud-gpios:
+    maxItems: 1
+    description: |
+      GPIO for the RL/UD (rotate 180 degrees) pin.
+      If rlud-gpios and/or sellvds-gpios are not specified,
+      the RL/UD and/or SELLVDS pins are assumed to be handled
+      appropriately by the hardware.
+
+  sellvds-gpios:
+    maxItems: 1
+    description: |
+      GPIO for the SELLVDS pin.
+      If rlud-gpios and/or sellvds-gpios are not specified,
+      the RL/UD and/or SELLVDS pins are assumed to be handled
+      appropriately by the hardware.
+
+required:
+  - compatible
+  - power-supply
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    panel {
+        compatible = "sharp,lq150x1lg11";
+
+        power-supply = <&vcc_3v3_reg>;               /* VCC */
+
+        backlight = <&backlight>;
+        rlud-gpios = <&gpio 17 GPIO_ACTIVE_HIGH>;    /* RL/UD */
+        sellvds-gpios = <&gpio 18 GPIO_ACTIVE_HIGH>; /* SELLVDS */
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/display/panel/sharp,ls037v7dw01.txt b/Documentation/devicetree/bindings/display/panel/sharp,ls037v7dw01.txt
deleted file mode 100644
index 0cc8981e9d49..000000000000
--- a/Documentation/devicetree/bindings/display/panel/sharp,ls037v7dw01.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-SHARP LS037V7DW01 TFT-LCD panel
-===================================
-
-Required properties:
-- compatible: "sharp,ls037v7dw01"
-
-Optional properties:
-- label: a symbolic name for the panel
-- enable-gpios: a GPIO spec for the optional enable pin.
-  This pin is the INI pin as specified in the LS037V7DW01.pdf file.
-- reset-gpios: a GPIO spec for the optional reset pin.
-  This pin is the RESB pin as specified in the LS037V7DW01.pdf file.
-- mode-gpios: a GPIO
-  ordered MO, LR, and UD as specified in the LS037V7DW01.pdf file.
-
-Required nodes:
-- Video port for DPI input
-
-This panel can have zero to five GPIOs to configure to change configuration
-between QVGA and VGA mode and the scan direction. As these pins can be also
-configured with external pulls, all the GPIOs are considered optional with holes
-in the array.
-
-Example
--------
-
-Example when connected to a omap2+ based device:
-
-lcd0: display {
-	compatible = "sharp,ls037v7dw01";
-	power-supply = <&lcd_3v3>;
-	enable-gpios = <&gpio5 24 GPIO_ACTIVE_HIGH>;	/* gpio152, lcd INI */
-	reset-gpios = <&gpio5 27 GPIO_ACTIVE_HIGH>;	/* gpio155, lcd RESB */
-	mode-gpios = <&gpio5 26 GPIO_ACTIVE_HIGH	/* gpio154, lcd MO */
-		      &gpio1 2 GPIO_ACTIVE_HIGH		/* gpio2, lcd LR */
-		      &gpio1 3 GPIO_ACTIVE_HIGH>;	/* gpio3, lcd UD */
-
-	port {
-		lcd_in: endpoint {
-			remote-endpoint = <&dpi_out>;
-		};
-	};
-};
diff --git a/Documentation/devicetree/bindings/display/panel/sharp,ls037v7dw01.yaml b/Documentation/devicetree/bindings/display/panel/sharp,ls037v7dw01.yaml
new file mode 100644
index 000000000000..8c47a9b0b507
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/sharp,ls037v7dw01.yaml
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/sharp,ls037v7dw01.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SHARP LS037V7DW01 TFT-LCD panel
+
+description: |
+  This panel can have zero to five GPIOs to configure to change configuration
+  between QVGA and VGA mode and the scan direction. As these pins can be also
+  configured with external pulls, all the GPIOs are considered optional with holes
+  in the array.
+
+maintainers:
+  - Tony Lindgren <tony@atomide.com>
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+    const: sharp,ls037v7dw01
+
+  label: true
+  enable-gpios: true
+  reset-gpios: true
+  port: true
+  power-supply: true
+
+  mode-gpios:
+    minItems: 1
+    maxItems: 3
+    description: |
+      GPIO ordered MO, LR, and UD as specified in LS037V7DW01.pdf
+      This panel can have zero to three GPIOs to configure to
+      change configuration between QVGA and VGA mode and the
+      scan direction. As these pins can be also configured
+      with external pulls, all the GPIOs are considered
+      optional with holes in the array.
+
+required:
+  - compatible
+  - port
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    lcd0: display {
+        compatible = "sharp,ls037v7dw01";
+        power-supply = <&lcd_3v3>;
+        enable-gpios = <&gpio5 24 GPIO_ACTIVE_HIGH>;    /* gpio152, lcd INI */
+        reset-gpios = <&gpio5 27 GPIO_ACTIVE_HIGH>;     /* gpio155, lcd RESB */
+        mode-gpios = <&gpio5 26 GPIO_ACTIVE_HIGH        /* gpio154, lcd MO */
+                      &gpio1 2 GPIO_ACTIVE_HIGH         /* gpio2, lcd LR */
+                      &gpio1 3 GPIO_ACTIVE_HIGH>;       /* gpio3, lcd UD */
+
+        port {
+            lcd_in: endpoint {
+                remote-endpoint = <&dpi_out>;
+            };
+        };
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/display/panel/sharp,ls043t1le01.txt b/Documentation/devicetree/bindings/display/panel/sharp,ls043t1le01.txt
deleted file mode 100644
index 3770a111968b..000000000000
--- a/Documentation/devicetree/bindings/display/panel/sharp,ls043t1le01.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-Sharp Microelectronics 4.3" qHD TFT LCD panel
-
-Required properties:
-- compatible: should be "sharp,ls043t1le01-qhd"
-- reg: DSI virtual channel of the peripheral
-- power-supply: phandle of the regulator that provides the supply voltage
-
-Optional properties:
-- backlight: phandle of the backlight device attached to the panel
-- reset-gpios: a GPIO spec for the reset pin
-
-Example:
-
-	mdss_dsi@fd922800 {
-		panel@0 {
-			compatible = "sharp,ls043t1le01-qhd";
-			reg = <0>;
-			avdd-supply = <&pm8941_l22>;
-			backlight = <&pm8941_wled>;
-			reset-gpios = <&pm8941_gpios 19 GPIO_ACTIVE_HIGH>;
-		};
-	};
diff --git a/Documentation/devicetree/bindings/display/panel/sharp,ls043t1le01.yaml b/Documentation/devicetree/bindings/display/panel/sharp,ls043t1le01.yaml
new file mode 100644
index 000000000000..a90d0d8bf7c9
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/sharp,ls043t1le01.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/sharp,ls043t1le01.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Sharp Microelectronics 4.3" qHD TFT LCD panel
+
+maintainers:
+  - Werner Johansson <werner.johansson@sonymobile.com>
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+    const: sharp,ls043t1le01-qhd
+
+  reg: true
+  backlight: true
+  reset-gpios: true
+  port: true
+
+  avdd-supply:
+    description: handle of the regulator that provides the supply voltage
+
+required:
+  - compatible
+  - reg
+  - avdd-supply
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    dsi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        panel@0 {
+            compatible = "sharp,ls043t1le01-qhd";
+            reg = <0>;
+            avdd-supply = <&pm8941_l22>;
+            backlight = <&pm8941_wled>;
+            reset-gpios = <&pm8941_gpios 19 GPIO_ACTIVE_HIGH>;
+        };
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/display/panel/simple-panel.txt b/Documentation/devicetree/bindings/display/panel/simple-panel.txt
deleted file mode 100644
index e11208fb7da8..000000000000
--- a/Documentation/devicetree/bindings/display/panel/simple-panel.txt
+++ /dev/null
@@ -1 +0,0 @@
-See panel-common.yaml in this directory.
diff --git a/Documentation/devicetree/bindings/display/panel/sitronix,st7701.txt b/Documentation/devicetree/bindings/display/panel/sitronix,st7701.txt
deleted file mode 100644
index ccd17597f1f6..000000000000
--- a/Documentation/devicetree/bindings/display/panel/sitronix,st7701.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-Sitronix ST7701 based LCD panels
-
-ST7701 designed for small and medium sizes of TFT LCD display, is
-capable of supporting up to 480RGBX864 in resolution. It provides
-several system interfaces like MIPI/RGB/SPI.
-
-Techstar TS8550B is 480x854, 2-lane MIPI DSI LCD panel which has
-inbuilt ST7701 chip.
-
-Required properties:
-- compatible: must be "sitronix,st7701" and one of
-  * "techstar,ts8550b"
-- reset-gpios: a GPIO phandle for the reset pin
-
-Required properties for techstar,ts8550b:
-- reg: DSI virtual channel used by that screen
-- VCC-supply: analog regulator for MIPI circuit
-- IOVCC-supply: I/O system regulator
-
-Optional properties:
-- backlight: phandle for the backlight control.
-
-panel@0 {
-	compatible = "techstar,ts8550b", "sitronix,st7701";
-	reg = <0>;
-	VCC-supply = <&reg_dldo2>;
-	IOVCC-supply = <&reg_dldo2>;
-	reset-gpios = <&pio 3 24 GPIO_ACTIVE_HIGH>; /* LCD-RST: PD24 */
-	backlight = <&backlight>;
-};
diff --git a/Documentation/devicetree/bindings/display/panel/sitronix,st7701.yaml b/Documentation/devicetree/bindings/display/panel/sitronix,st7701.yaml
new file mode 100644
index 000000000000..6dff59fe4be1
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/sitronix,st7701.yaml
@@ -0,0 +1,69 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/sitronix,st7701.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Sitronix ST7701 based LCD panels
+
+maintainers:
+  - Jagan Teki <jagan@amarulasolutions.com>
+
+description: |
+  ST7701 designed for small and medium sizes of TFT LCD display, is
+  capable of supporting up to 480RGBX864 in resolution. It provides
+  several system interfaces like MIPI/RGB/SPI.
+
+  Techstar TS8550B is 480x854, 2-lane MIPI DSI LCD panel which has
+  inbuilt ST7701 chip.
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - techstar,ts8550b
+      - const: sitronix,st7701
+
+  reg:
+    description: DSI virtual channel used by that screen
+    maxItems: 1
+
+  VCC-supply:
+    description: analog regulator for MIPI circuit
+
+  IOVCC-supply:
+    description: I/O system regulator
+
+  reset-gpios: true
+
+  backlight: true
+
+required:
+  - compatible
+  - reg
+  - VCC-supply
+  - IOVCC-supply
+  - reset-gpios
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    dsi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        panel@0 {
+            compatible = "techstar,ts8550b", "sitronix,st7701";
+            reg = <0>;
+            VCC-supply = <&reg_dldo2>;
+            IOVCC-supply = <&reg_dldo2>;
+            reset-gpios = <&pio 3 24 GPIO_ACTIVE_HIGH>; /* LCD-RST: PD24 */
+            backlight = <&backlight>;
+        };
+    };
diff --git a/Documentation/devicetree/bindings/display/panel/sitronix,st7789v.txt b/Documentation/devicetree/bindings/display/panel/sitronix,st7789v.txt
deleted file mode 100644
index c6995dde641b..000000000000
--- a/Documentation/devicetree/bindings/display/panel/sitronix,st7789v.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-Sitronix ST7789V RGB panel with SPI control bus
-
-Required properties:
-  - compatible: "sitronix,st7789v"
-  - reg: Chip select of the panel on the SPI bus
-  - reset-gpios: a GPIO phandle for the reset pin
-  - power-supply: phandle of the regulator that provides the supply voltage
-
-Optional properties:
-  - backlight: phandle to the backlight used
-
-The generic bindings for the SPI slaves documented in [1] also applies
-
-The device node can contain one 'port' child node with one child
-'endpoint' node, according to the bindings defined in [2]. This
-node should describe panel's video bus.
-
-[1]: Documentation/devicetree/bindings/spi/spi-bus.txt
-[2]: Documentation/devicetree/bindings/graph.txt
-
-Example:
-
-panel@0 {
-	compatible = "sitronix,st7789v";
-	reg = <0>;
-	reset-gpios = <&pio 6 11 GPIO_ACTIVE_LOW>;
-	backlight = <&pwm_bl>;
-	spi-max-frequency = <100000>;
-	spi-cpol;
-	spi-cpha;
-
-	port {
-		panel_input: endpoint {
-			remote-endpoint = <&tcon0_out_panel>;
-		};
-	};
-};
diff --git a/Documentation/devicetree/bindings/display/panel/sitronix,st7789v.yaml b/Documentation/devicetree/bindings/display/panel/sitronix,st7789v.yaml
new file mode 100644
index 000000000000..fa46d151e7b3
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/sitronix,st7789v.yaml
@@ -0,0 +1,63 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/sitronix,st7789v.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Sitronix ST7789V RGB panel with SPI control bus
+
+description: |
+  The panel must obey the rules for a SPI slave device as specified in
+  spi/spi-controller.yaml
+
+maintainers:
+  - Maxime Ripard <mripard@kernel.org>
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+    const: sitronix,st7789v
+
+  reg: true
+  reset-gpios: true
+  power-supply: true
+  backlight: true
+  port: true
+
+required:
+  - compatible
+  - reg
+  - reset-gpios
+  - power-supply
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    spi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        panel@0 {
+            compatible = "sitronix,st7789v";
+            reg = <0>;
+            reset-gpios = <&pio 6 11 GPIO_ACTIVE_LOW>;
+            backlight = <&pwm_bl>;
+            power-supply = <&power>;
+            spi-max-frequency = <100000>;
+            spi-cpol;
+            spi-cpha;
+
+            port {
+                panel_input: endpoint {
+                    remote-endpoint = <&tcon0_out_panel>;
+                };
+            };
+        };
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/display/panel/sony,acx424akp.yaml b/Documentation/devicetree/bindings/display/panel/sony,acx424akp.yaml
index 185dcc8fd1f9..78d060097052 100644
--- a/Documentation/devicetree/bindings/display/panel/sony,acx424akp.yaml
+++ b/Documentation/devicetree/bindings/display/panel/sony,acx424akp.yaml
@@ -18,7 +18,7 @@ properties:
   reg: true
   reset-gpios: true
   vddi-supply:
-     description: regulator that supplies the vddi voltage
+    description: regulator that supplies the vddi voltage
   enforce-video-mode: true
 
 required:
diff --git a/Documentation/devicetree/bindings/display/panel/sony,acx565akm.txt b/Documentation/devicetree/bindings/display/panel/sony,acx565akm.txt
deleted file mode 100644
index e12333280749..000000000000
--- a/Documentation/devicetree/bindings/display/panel/sony,acx565akm.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-Sony ACX565AKM SDI Panel
-========================
-
-Required properties:
-- compatible: "sony,acx565akm"
-
-Optional properties:
-- label: a symbolic name for the panel
-- reset-gpios: panel reset gpio
-
-Required nodes:
-- Video port for SDI input
-
-Example
--------
-
-acx565akm@2 {
-	compatible = "sony,acx565akm";
-	spi-max-frequency = <6000000>;
-	reg = <2>;
-
-	label = "lcd";
-	reset-gpios = <&gpio3 26 GPIO_ACTIVE_HIGH>; /* 90 */
-
-	port {
-		lcd_in: endpoint {
-			remote-endpoint = <&sdi_out>;
-		};
-	};
-};
diff --git a/Documentation/devicetree/bindings/display/panel/sony,acx565akm.yaml b/Documentation/devicetree/bindings/display/panel/sony,acx565akm.yaml
new file mode 100644
index 000000000000..95d053c548ab
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/sony,acx565akm.yaml
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/sony,acx565akm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Sony ACX565AKM SDI Panel
+
+description: |
+  The panel must obey the rules for a SPI slave device as specified in
+  spi/spi-controller.yaml
+
+maintainers:
+  - Tomi Valkeinen <tomi.valkeinen@ti.com>
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+    const: sony,acx565akm
+
+  label: true
+  reset-gpios: true
+  port: true
+
+required:
+  - compatible
+  - port
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    spi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        panel@2 {
+            compatible = "sony,acx565akm";
+            spi-max-frequency = <6000000>;
+            reg = <2>;
+
+            label = "lcd";
+            reset-gpios = <&gpio3 26 GPIO_ACTIVE_HIGH>; /* 90 */
+
+            port {
+                lcd_in: endpoint {
+                    remote-endpoint = <&sdi_out>;
+                };
+            };
+        };
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/display/panel/startek,startek-kd050c.txt b/Documentation/devicetree/bindings/display/panel/startek,startek-kd050c.txt
deleted file mode 100644
index 70cd8d18d841..000000000000
--- a/Documentation/devicetree/bindings/display/panel/startek,startek-kd050c.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Startek Electronic Technology Co. KD050C 5.0" WVGA TFT LCD panel
-
-Required properties:
-- compatible: should be "startek,startek-kd050c"
diff --git a/Documentation/devicetree/bindings/display/panel/startek,startek-kd050c.yaml b/Documentation/devicetree/bindings/display/panel/startek,startek-kd050c.yaml
new file mode 100644
index 000000000000..fd668640afd1
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/startek,startek-kd050c.yaml
@@ -0,0 +1,33 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/startek,startek-kd050c.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Startek Electronic Technology Co. KD050C 5.0" WVGA TFT LCD panel
+
+maintainers:
+  - Nikita Kiryanov <nikita@compulab.co.il>
+
+allOf:
+  - $ref: panel-dpi.yaml#
+
+properties:
+  compatible:
+    items:
+      - const: startek,startek-kd050c
+      - {} # panel-dpi, but not listed here to avoid false select
+
+  backlight: true
+  enable-gpios: true
+  height-mm: true
+  label: true
+  panel-timing: true
+  port: true
+  power-supply: true
+  reset-gpios: true
+  width-mm: true
+
+additionalProperties: false
+
+...
diff --git a/Documentation/devicetree/bindings/display/panel/tpo,td.yaml b/Documentation/devicetree/bindings/display/panel/tpo,td.yaml
new file mode 100644
index 000000000000..4aa605613445
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/tpo,td.yaml
@@ -0,0 +1,65 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/tpo,td.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Toppoly TD Panels
+
+description: |
+  The panel must obey the rules for a SPI slave device as specified in
+  spi/spi-controller.yaml
+
+maintainers:
+  - Marek Belisko <marek@goldelico.com>
+  - H. Nikolaus Schaller <hns@goldelico.com>
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+    enum:
+        # Toppoly TD028TTEC1 Panel
+      - tpo,td028ttec1
+        # Toppoly TD043MTEA1 Panel
+      - tpo,td043mtea1
+
+  reg: true
+  label: true
+  reset-gpios: true
+  backlight: true
+  port: true
+
+required:
+  - compatible
+  - port
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    spi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        panel: panel@0 {
+            compatible = "tpo,td043mtea1";
+            reg = <0>;
+            spi-max-frequency = <100000>;
+            spi-cpol;
+            spi-cpha;
+
+            label = "lcd";
+
+            reset-gpios = <&gpio7 7 0>;
+
+            port {
+                lcd_in: endpoint {
+                    remote-endpoint = <&dpi_out>;
+                };
+            };
+        };
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/display/panel/tpo,td028ttec1.txt b/Documentation/devicetree/bindings/display/panel/tpo,td028ttec1.txt
deleted file mode 100644
index 898e06ecf4ef..000000000000
--- a/Documentation/devicetree/bindings/display/panel/tpo,td028ttec1.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-Toppoly TD028TTEC1 Panel
-========================
-
-Required properties:
-- compatible: "tpo,td028ttec1"
-
-Optional properties:
-- label: a symbolic name for the panel
-- backlight: phandle of the backlight device
-
-Required nodes:
-- Video port for DPI input
-
-Example
--------
-
-lcd-panel: td028ttec1@0 {
-	compatible = "tpo,td028ttec1";
-	reg = <0>;
-	spi-max-frequency = <100000>;
-	spi-cpol;
-	spi-cpha;
-
-	label = "lcd";
-	backlight = <&backlight>;
-	port {
-		lcd_in: endpoint {
-			remote-endpoint = <&dpi_out>;
-		};
-	};
-};
-
diff --git a/Documentation/devicetree/bindings/display/panel/tpo,td043mtea1.txt b/Documentation/devicetree/bindings/display/panel/tpo,td043mtea1.txt
deleted file mode 100644
index ec6d62975162..000000000000
--- a/Documentation/devicetree/bindings/display/panel/tpo,td043mtea1.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-TPO TD043MTEA1 Panel
-====================
-
-Required properties:
-- compatible: "tpo,td043mtea1"
-- reset-gpios: panel reset gpio
-
-Optional properties:
-- label: a symbolic name for the panel
-
-Required nodes:
-- Video port for DPI input
-
-Example
--------
-
-lcd-panel: panel@0 {
-	compatible = "tpo,td043mtea1";
-	reg = <0>;
-	spi-max-frequency = <100000>;
-	spi-cpol;
-	spi-cpha;
-
-	label = "lcd";
-
-	reset-gpios = <&gpio7 7 0>;
-
-	port {
-		lcd_in: endpoint {
-			remote-endpoint = <&dpi_out>;
-		};
-	};
-};
diff --git a/Documentation/devicetree/bindings/display/panel/visionox,rm69299.yaml b/Documentation/devicetree/bindings/display/panel/visionox,rm69299.yaml
new file mode 100644
index 000000000000..b36f39f6b233
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/visionox,rm69299.yaml
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/visionox,rm69299.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Visionox model RM69299 Panels Device Tree Bindings.
+
+maintainers:
+ - Harigovindan P <harigovi@codeaurora.org>
+
+description: |
+  This binding is for display panels using a Visionox RM692999 panel.
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+    const: visionox,rm69299-1080p-display
+
+  vdda-supply:
+    description: |
+      Phandle of the regulator that provides the vdda supply voltage.
+
+  vdd3p3-supply:
+    description: |
+      Phandle of the regulator that provides the vdd3p3 supply voltage.
+
+  port: true
+  reset-gpios: true
+
+additionalProperties: false
+
+required:
+  - compatible
+  - vdda-supply
+  - vdd3p3-supply
+  - reset-gpios
+  - port
+
+examples:
+  - |
+    panel {
+        compatible = "visionox,rm69299-1080p-display";
+
+        vdda-supply = <&src_pp1800_l8c>;
+        vdd3p3-supply = <&src_pp2800_l18a>;
+
+        reset-gpios = <&pm6150l_gpio 3 0>;
+        port {
+            panel0_in: endpoint {
+                remote-endpoint = <&dsi0_out>;
+            };
+        };
+    };
+...
diff --git a/Documentation/devicetree/bindings/display/panel/xinpeng,xpp055c272.yaml b/Documentation/devicetree/bindings/display/panel/xinpeng,xpp055c272.yaml
index d9fdb58e06b4..d5c46a3cc2b0 100644
--- a/Documentation/devicetree/bindings/display/panel/xinpeng,xpp055c272.yaml
+++ b/Documentation/devicetree/bindings/display/panel/xinpeng,xpp055c272.yaml
@@ -19,9 +19,9 @@ properties:
   backlight: true
   reset-gpios: true
   iovcc-supply:
-     description: regulator that supplies the iovcc voltage
+    description: regulator that supplies the iovcc voltage
   vci-supply:
-     description: regulator that supplies the vci voltage
+    description: regulator that supplies the vci voltage
 
 required:
   - compatible
@@ -37,7 +37,6 @@ examples:
     dsi {
         #address-cells = <1>;
         #size-cells = <0>;
-        reg = <0xff450000 0x1000>;
 
         panel@0 {
             compatible = "xinpeng,xpp055c272";
diff --git a/Documentation/devicetree/bindings/display/renesas,cmm.yaml b/Documentation/devicetree/bindings/display/renesas,cmm.yaml
index a57037b9e9ba..005406c89507 100644
--- a/Documentation/devicetree/bindings/display/renesas,cmm.yaml
+++ b/Documentation/devicetree/bindings/display/renesas,cmm.yaml
@@ -21,15 +21,15 @@ properties:
   compatible:
     oneOf:
       - items:
-        - enum:
-          - renesas,r8a7795-cmm
-          - renesas,r8a7796-cmm
-          - renesas,r8a77965-cmm
-          - renesas,r8a77990-cmm
-          - renesas,r8a77995-cmm
-        - const: renesas,rcar-gen3-cmm
+          - enum:
+              - renesas,r8a7795-cmm
+              - renesas,r8a7796-cmm
+              - renesas,r8a77965-cmm
+              - renesas,r8a77990-cmm
+              - renesas,r8a77995-cmm
+          - const: renesas,rcar-gen3-cmm
       - items:
-        - const: renesas,rcar-gen2-cmm
+          - const: renesas,rcar-gen2-cmm
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt
deleted file mode 100644
index 8b3a5f514205..000000000000
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt
+++ /dev/null
@@ -1,74 +0,0 @@
-device-tree bindings for rockchip soc display controller (vop)
-
-VOP (Visual Output Processor) is the Display Controller for the Rockchip
-series of SoCs which transfers the image data from a video memory
-buffer to an external LCD interface.
-
-Required properties:
-- compatible: value should be one of the following
-		"rockchip,rk3036-vop";
-		"rockchip,rk3126-vop";
-		"rockchip,px30-vop-lit";
-		"rockchip,px30-vop-big";
-		"rockchip,rk3066-vop";
-		"rockchip,rk3188-vop";
-		"rockchip,rk3288-vop";
-		"rockchip,rk3368-vop";
-		"rockchip,rk3366-vop";
-		"rockchip,rk3399-vop-big";
-		"rockchip,rk3399-vop-lit";
-		"rockchip,rk3228-vop";
-		"rockchip,rk3328-vop";
-
-- reg: Must contain one entry corresponding to the base address and length
-	of the register space. Can optionally contain a second entry
-	corresponding to the CRTC gamma LUT address.
-
-- interrupts: should contain a list of all VOP IP block interrupts in the
-		 order: VSYNC, LCD_SYSTEM. The interrupt specifier
-		 format depends on the interrupt controller used.
-
-- clocks: must include clock specifiers corresponding to entries in the
-		clock-names property.
-
-- clock-names: Must contain
-		aclk_vop: for ddr buffer transfer.
-		hclk_vop: for ahb bus to R/W the phy regs.
-		dclk_vop: pixel clock.
-
-- resets: Must contain an entry for each entry in reset-names.
-  See ../reset/reset.txt for details.
-- reset-names: Must include the following entries:
-  - axi
-  - ahb
-  - dclk
-
-- iommus: required a iommu node
-
-- port: A port node with endpoint definitions as defined in
-  Documentation/devicetree/bindings/media/video-interfaces.txt.
-
-Example:
-SoC specific DT entry:
-	vopb: vopb@ff930000 {
-		compatible = "rockchip,rk3288-vop";
-		reg = <0x0 0xff930000 0x0 0x19c>, <0x0 0xff931000 0x0 0x1000>;
-		interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cru ACLK_VOP0>, <&cru DCLK_VOP0>, <&cru HCLK_VOP0>;
-		clock-names = "aclk_vop", "dclk_vop", "hclk_vop";
-		resets = <&cru SRST_LCDC1_AXI>, <&cru SRST_LCDC1_AHB>, <&cru SRST_LCDC1_DCLK>;
-		reset-names = "axi", "ahb", "dclk";
-		iommus = <&vopb_mmu>;
-		vopb_out: port {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			vopb_out_edp: endpoint@0 {
-				reg = <0>;
-				remote-endpoint=<&edp_in_vopb>;
-			};
-			vopb_out_hdmi: endpoint@1 {
-				reg = <1>;
-				remote-endpoint=<&hdmi_in_vopb>;
-			};
-		};
-	};
diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.yaml
new file mode 100644
index 000000000000..1695e3e4bcec
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.yaml
@@ -0,0 +1,134 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/rockchip/rockchip-vop.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip SoC display controller (VOP)
+
+description:
+  VOP (Video Output Processor) is the display controller for the Rockchip
+  series of SoCs which transfers the image data from a video memory
+  buffer to an external LCD interface.
+
+maintainers:
+  - Sandy Huang <hjc@rock-chips.com>
+  - Heiko Stuebner <heiko@sntech.de>
+
+properties:
+  compatible:
+    enum:
+      - rockchip,px30-vop-big
+      - rockchip,px30-vop-lit
+      - rockchip,rk3036-vop
+      - rockchip,rk3066-vop
+      - rockchip,rk3126-vop
+      - rockchip,rk3188-vop
+      - rockchip,rk3228-vop
+      - rockchip,rk3288-vop
+      - rockchip,rk3328-vop
+      - rockchip,rk3366-vop
+      - rockchip,rk3368-vop
+      - rockchip,rk3399-vop-big
+      - rockchip,rk3399-vop-lit
+
+  reg:
+    minItems: 1
+    items:
+      - description:
+          Must contain one entry corresponding to the base address and length
+          of the register space.
+      - description:
+          Can optionally contain a second entry corresponding to
+          the CRTC gamma LUT address.
+
+  interrupts:
+    maxItems: 1
+    description:
+      The VOP interrupt is shared by several interrupt sources, such as
+      frame start (VSYNC), line flag and other status interrupts.
+
+  clocks:
+    items:
+      - description: Clock for ddr buffer transfer.
+      - description: Pixel clock.
+      - description: Clock for the ahb bus to R/W the phy regs.
+
+  clock-names:
+    items:
+      - const: aclk_vop
+      - const: dclk_vop
+      - const: hclk_vop
+
+  resets:
+    maxItems: 3
+
+  reset-names:
+    items:
+      - const: axi
+      - const: ahb
+      - const: dclk
+
+  port:
+    type: object
+    description:
+      A port node with endpoint definitions as defined in
+      Documentation/devicetree/bindings/media/video-interfaces.txt.
+
+  assigned-clocks:
+    maxItems: 2
+
+  assigned-clock-rates:
+    maxItems: 2
+
+  iommus:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - resets
+  - reset-names
+  - port
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/rk3288-cru.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/power/rk3288-power.h>
+    vopb: vopb@ff930000 {
+      compatible = "rockchip,rk3288-vop";
+      reg = <0x0 0xff930000 0x0 0x19c>,
+            <0x0 0xff931000 0x0 0x1000>;
+      interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+      clocks = <&cru ACLK_VOP0>,
+               <&cru DCLK_VOP0>,
+               <&cru HCLK_VOP0>;
+      clock-names = "aclk_vop", "dclk_vop", "hclk_vop";
+      power-domains = <&power RK3288_PD_VIO>;
+      resets = <&cru SRST_LCDC1_AXI>,
+               <&cru SRST_LCDC1_AHB>,
+               <&cru SRST_LCDC1_DCLK>;
+      reset-names = "axi", "ahb", "dclk";
+      iommus = <&vopb_mmu>;
+      vopb_out: port {
+        #address-cells = <1>;
+        #size-cells = <0>;
+        vopb_out_edp: endpoint@0 {
+          reg = <0>;
+          remote-endpoint=<&edp_in_vopb>;
+        };
+        vopb_out_hdmi: endpoint@1 {
+          reg = <1>;
+          remote-endpoint=<&hdmi_in_vopb>;
+        };
+      };
+    };
diff --git a/Documentation/devicetree/bindings/dma/adi,axi-dmac.txt b/Documentation/devicetree/bindings/dma/adi,axi-dmac.txt
index b38ee732efa9..cd17684aaab5 100644
--- a/Documentation/devicetree/bindings/dma/adi,axi-dmac.txt
+++ b/Documentation/devicetree/bindings/dma/adi,axi-dmac.txt
@@ -1,4 +1,4 @@
-Analog Device AXI-DMAC DMA controller
+Analog Devices AXI-DMAC DMA controller
 
 Required properties:
  - compatible: Must be "adi,axi-dmac-1.00.a".
diff --git a/Documentation/devicetree/bindings/dma/fsl-edma.txt b/Documentation/devicetree/bindings/dma/fsl-edma.txt
index e77b08ebcd06..ee1754739b4b 100644
--- a/Documentation/devicetree/bindings/dma/fsl-edma.txt
+++ b/Documentation/devicetree/bindings/dma/fsl-edma.txt
@@ -10,7 +10,8 @@ Required properties:
 - compatible :
 	- "fsl,vf610-edma" for eDMA used similar to that on Vybrid vf610 SoC
 	- "fsl,imx7ulp-edma" for eDMA2 used similar to that on i.mx7ulp
-	- "fsl,fsl,ls1028a-edma" for eDMA used similar to that on Vybrid vf610 SoC
+	- "fsl,ls1028a-edma" followed by "fsl,vf610-edma" for eDMA used on the
+	  LS1028A SoC.
 - reg : Specifies base physical address(s) and size of the eDMA registers.
 	The 1st region is eDMA control register's address and size.
 	The 2nd and the 3rd regions are programmable channel multiplexing
diff --git a/Documentation/devicetree/bindings/dma/socionext,uniphier-xdmac.yaml b/Documentation/devicetree/bindings/dma/socionext,uniphier-xdmac.yaml
index 86cfb599256e..371f18773198 100644
--- a/Documentation/devicetree/bindings/dma/socionext,uniphier-xdmac.yaml
+++ b/Documentation/devicetree/bindings/dma/socionext,uniphier-xdmac.yaml
@@ -22,9 +22,7 @@ properties:
     const: socionext,uniphier-xdmac
 
   reg:
-    items:
-      - description: XDMAC base register region (offset and length)
-      - description: XDMAC extension register region (offset and length)
+    maxItems: 1
 
   interrupts:
     maxItems: 1
@@ -49,12 +47,13 @@ required:
   - reg
   - interrupts
   - "#dma-cells"
+  - dma-channels
 
 examples:
   - |
     xdmac: dma-controller@5fc10000 {
         compatible = "socionext,uniphier-xdmac";
-        reg = <0x5fc10000 0x1000>, <0x5fc20000 0x800>;
+        reg = <0x5fc10000 0x5300>;
         interrupts = <0 188 4>;
         #dma-cells = <2>;
         dma-channels = <16>;
diff --git a/Documentation/devicetree/bindings/dma/ti/k3-udma.yaml b/Documentation/devicetree/bindings/dma/ti/k3-udma.yaml
index 39ea05e6e5ff..85056982a242 100644
--- a/Documentation/devicetree/bindings/dma/ti/k3-udma.yaml
+++ b/Documentation/devicetree/bindings/dma/ti/k3-udma.yaml
@@ -69,10 +69,10 @@ properties:
     maxItems: 3
 
   reg-names:
-   items:
-     - const: gcfg
-     - const: rchanrt
-     - const: tchanrt
+    items:
+      - const: gcfg
+      - const: rchanrt
+      - const: tchanrt
 
   msi-parent: true
 
diff --git a/Documentation/devicetree/bindings/firmware/intel,stratix10-svc.txt b/Documentation/devicetree/bindings/firmware/intel,stratix10-svc.txt
index 1fa66065acc6..6eff1afd8daf 100644
--- a/Documentation/devicetree/bindings/firmware/intel,stratix10-svc.txt
+++ b/Documentation/devicetree/bindings/firmware/intel,stratix10-svc.txt
@@ -23,7 +23,7 @@ Required properties:
 The svc node has the following mandatory properties, must be located under
 the firmware node.
 
-- compatible: "intel,stratix10-svc"
+- compatible: "intel,stratix10-svc" or "intel,agilex-svc"
 - method: smc or hvc
         smc - Secure Monitor Call
         hvc - Hypervisor Call
diff --git a/Documentation/devicetree/bindings/fpga/intel-stratix10-soc-fpga-mgr.txt b/Documentation/devicetree/bindings/fpga/intel-stratix10-soc-fpga-mgr.txt
index 6e03f79287fb..0f874137ca46 100644
--- a/Documentation/devicetree/bindings/fpga/intel-stratix10-soc-fpga-mgr.txt
+++ b/Documentation/devicetree/bindings/fpga/intel-stratix10-soc-fpga-mgr.txt
@@ -4,7 +4,8 @@ Required properties:
 The fpga_mgr node has the following mandatory property, must be located under
 firmware/svc node.
 
-- compatible : should contain "intel,stratix10-soc-fpga-mgr"
+- compatible : should contain "intel,stratix10-soc-fpga-mgr" or
+	       "intel,agilex-soc-fpga-mgr"
 
 Example:
 
diff --git a/Documentation/devicetree/bindings/gpio/brcm,xgs-iproc-gpio.yaml b/Documentation/devicetree/bindings/gpio/brcm,xgs-iproc-gpio.yaml
index 5f1ed20e43ee..4f2cbd8307a7 100644
--- a/Documentation/devicetree/bindings/gpio/brcm,xgs-iproc-gpio.yaml
+++ b/Documentation/devicetree/bindings/gpio/brcm,xgs-iproc-gpio.yaml
@@ -27,7 +27,7 @@ properties:
   gpio-controller: true
 
   '#gpio-cells':
-      const: 2
+    const: 2
 
   ngpios:
     minimum: 0
diff --git a/Documentation/devicetree/bindings/gpio/snps,dw-apb-gpio.yaml b/Documentation/devicetree/bindings/gpio/snps,dw-apb-gpio.yaml
new file mode 100644
index 000000000000..04a3c51e1dc1
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/snps,dw-apb-gpio.yaml
@@ -0,0 +1,134 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/gpio/snps,dw-apb-gpio.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Synopsys DesignWare APB GPIO controller
+
+description: |
+  Synopsys DesignWare GPIO controllers have a configurable number of ports,
+  each of which are intended to be represented as child nodes with the generic
+  GPIO-controller properties as desribed in this bindings file.
+
+maintainers:
+  - Hoan Tran <hoan@os.amperecomputing.com>
+  - Serge Semin <fancer.lancer@gmail.com>
+
+properties:
+  $nodename:
+    pattern: "^gpio@[0-9a-f]+$"
+
+  compatible:
+    const: snps,dw-apb-gpio
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 0
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    minItems: 1
+    items:
+      - description: APB interface clock source
+      - description: DW GPIO debounce reference clock source
+
+  clock-names:
+    minItems: 1
+    items:
+      - const: bus
+      - const: db
+
+  resets:
+    maxItems: 1
+
+patternProperties:
+  "^gpio-(port|controller)@[0-9a-f]+$":
+    type: object
+    properties:
+      compatible:
+        const: snps,dw-apb-gpio-port
+
+      reg:
+        maxItems: 1
+
+      gpio-controller: true
+
+      '#gpio-cells':
+        const: 2
+
+      snps,nr-gpios:
+        description: The number of GPIO pins exported by the port.
+        default: 32
+        allOf:
+          - $ref: /schemas/types.yaml#/definitions/uint32
+          - minimum: 1
+            maximum: 32
+
+      interrupts:
+        description: |
+          The interrupts to the parent controller raised when GPIOs generate
+          the interrupts. If the controller provides one combined interrupt
+          for all GPIOs, specify a single interrupt. If the controller provides
+          one interrupt for each GPIO, provide a list of interrupts that
+          correspond to each of the GPIO pins.
+        minItems: 1
+        maxItems: 32
+
+      interrupt-controller: true
+
+      '#interrupt-cells':
+        const: 2
+
+    required:
+      - compatible
+      - reg
+      - gpio-controller
+      - '#gpio-cells'
+
+    dependencies:
+      interrupt-controller: [ interrupts ]
+
+    additionalProperties: false
+
+additionalProperties: false
+
+required:
+  - compatible
+  - reg
+  - "#address-cells"
+  - "#size-cells"
+
+examples:
+  - |
+    gpio: gpio@20000 {
+      compatible = "snps,dw-apb-gpio";
+      reg = <0x20000 0x1000>;
+      #address-cells = <1>;
+      #size-cells = <0>;
+
+      porta: gpio-port@0 {
+        compatible = "snps,dw-apb-gpio-port";
+        reg = <0>;
+        gpio-controller;
+        #gpio-cells = <2>;
+        snps,nr-gpios = <8>;
+        interrupt-controller;
+        #interrupt-cells = <2>;
+        interrupt-parent = <&vic1>;
+        interrupts = <0>;
+      };
+
+      portb: gpio-port@1 {
+        compatible = "snps,dw-apb-gpio-port";
+        reg = <1>;
+        gpio-controller;
+        #gpio-cells = <2>;
+        snps,nr-gpios = <8>;
+      };
+    };
+...
diff --git a/Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt b/Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt
deleted file mode 100644
index 839dd32ffe11..000000000000
--- a/Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt
+++ /dev/null
@@ -1,65 +0,0 @@
-* Synopsys DesignWare APB GPIO controller
-
-Required properties:
-- compatible : Should contain "snps,dw-apb-gpio"
-- reg : Address and length of the register set for the device.
-- #address-cells : should be 1 (for addressing port subnodes).
-- #size-cells : should be 0 (port subnodes).
-
-The GPIO controller has a configurable number of ports, each of which are
-represented as child nodes with the following properties:
-
-Required properties:
-- compatible : "snps,dw-apb-gpio-port"
-- gpio-controller : Marks the device node as a gpio controller.
-- #gpio-cells : Should be two.  The first cell is the pin number and
-  the second cell is used to specify the gpio polarity:
-      0 = active high
-      1 = active low
-- reg : The integer port index of the port, a single cell.
-
-Optional properties:
-- interrupt-controller : The first port may be configured to be an interrupt
-controller.
-- #interrupt-cells : Specifies the number of cells needed to encode an
-  interrupt.  Shall be set to 2.  The first cell defines the interrupt number,
-  the second encodes the triger flags encoded as described in
-  Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
-- interrupts : The interrupts to the parent controller raised when GPIOs
-  generate the interrupts. If the controller provides one combined interrupt
-  for all GPIOs, specify a single interrupt. If the controller provides one
-  interrupt for each GPIO, provide a list of interrupts that correspond to each
-  of the GPIO pins. When specifying multiple interrupts, if any are unconnected,
-  use the interrupts-extended property to specify the interrupts and set the
-  interrupt controller handle for unused interrupts to 0.
-- snps,nr-gpios : The number of pins in the port, a single cell.
-- resets : Reset line for the controller.
-
-Example:
-
-gpio: gpio@20000 {
-	compatible = "snps,dw-apb-gpio";
-	reg = <0x20000 0x1000>;
-	#address-cells = <1>;
-	#size-cells = <0>;
-
-	porta: gpio@0 {
-		compatible = "snps,dw-apb-gpio-port";
-		gpio-controller;
-		#gpio-cells = <2>;
-		snps,nr-gpios = <8>;
-		reg = <0>;
-		interrupt-controller;
-		#interrupt-cells = <2>;
-		interrupt-parent = <&vic1>;
-		interrupts = <0>;
-	};
-
-	portb: gpio@1 {
-		compatible = "snps,dw-apb-gpio-port";
-		gpio-controller;
-		#gpio-cells = <2>;
-		snps,nr-gpios = <8>;
-		reg = <1>;
-	};
-};
diff --git a/Documentation/devicetree/bindings/gpu/arm,mali-midgard.yaml b/Documentation/devicetree/bindings/gpu/arm,mali-midgard.yaml
index 0407e45eb8c4..a7a67e0a42e5 100644
--- a/Documentation/devicetree/bindings/gpu/arm,mali-midgard.yaml
+++ b/Documentation/devicetree/bindings/gpu/arm,mali-midgard.yaml
@@ -16,33 +16,33 @@ properties:
     oneOf:
       - items:
           - enum:
-             - samsung,exynos5250-mali
+              - samsung,exynos5250-mali
           - const: arm,mali-t604
       - items:
           - enum:
-             - samsung,exynos5420-mali
+              - samsung,exynos5420-mali
           - const: arm,mali-t628
       - items:
           - enum:
-             - allwinner,sun50i-h6-mali
+              - allwinner,sun50i-h6-mali
           - const: arm,mali-t720
       - items:
           - enum:
-             - amlogic,meson-gxm-mali
-             - realtek,rtd1295-mali
+              - amlogic,meson-gxm-mali
+              - realtek,rtd1295-mali
           - const: arm,mali-t820
       - items:
           - enum:
-             - arm,juno-mali
+              - arm,juno-mali
           - const: arm,mali-t624
       - items:
           - enum:
-             - rockchip,rk3288-mali
-             - samsung,exynos5433-mali
+              - rockchip,rk3288-mali
+              - samsung,exynos5433-mali
           - const: arm,mali-t760
       - items:
           - enum:
-             - rockchip,rk3399-mali
+              - rockchip,rk3399-mali
           - const: arm,mali-t860
 
           # "arm,mali-t830"
diff --git a/Documentation/devicetree/bindings/gpu/vivante,gc.yaml b/Documentation/devicetree/bindings/gpu/vivante,gc.yaml
index 0bc4b38d5cbb..e1ac6ff5a230 100644
--- a/Documentation/devicetree/bindings/gpu/vivante,gc.yaml
+++ b/Documentation/devicetree/bindings/gpu/vivante,gc.yaml
@@ -9,7 +9,7 @@ title: Vivante GPU Bindings
 description: Vivante GPU core devices
 
 maintainers:
-  -  Lucas Stach <l.stach@pengutronix.de>
+  - Lucas Stach <l.stach@pengutronix.de>
 
 properties:
   compatible:
diff --git a/Documentation/devicetree/bindings/hwmon/adi,axi-fan-control.yaml b/Documentation/devicetree/bindings/hwmon/adi,axi-fan-control.yaml
index 57a240d2d026..7db78767c02d 100644
--- a/Documentation/devicetree/bindings/hwmon/adi,axi-fan-control.yaml
+++ b/Documentation/devicetree/bindings/hwmon/adi,axi-fan-control.yaml
@@ -2,7 +2,7 @@
 # Copyright 2019 Analog Devices Inc.
 %YAML 1.2
 ---
-$id: http://devicetree.org/schemas/bindings/hwmon/adi,axi-fan-control.yaml#
+$id: http://devicetree.org/schemas/hwmon/adi,axi-fan-control.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
 title: Analog Devices AXI FAN Control Device Tree Bindings
@@ -47,7 +47,7 @@ required:
 
 examples:
   - |
-    fpga_axi: fpga-axi@0 {
+    fpga_axi: fpga-axi {
             #address-cells = <0x2>;
             #size-cells = <0x1>;
 
diff --git a/Documentation/devicetree/bindings/hwmon/adt7475.yaml b/Documentation/devicetree/bindings/hwmon/adt7475.yaml
index 76985034ea73..46c441574f98 100644
--- a/Documentation/devicetree/bindings/hwmon/adt7475.yaml
+++ b/Documentation/devicetree/bindings/hwmon/adt7475.yaml
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
 %YAML 1.2
 ---
-$id: http://devicetree.org/schemas/adt7475.yaml#
+$id: http://devicetree.org/schemas/hwmon/adt7475.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
 title: ADT7475 hwmon sensor
diff --git a/Documentation/devicetree/bindings/i2c/cdns,i2c-r1p10.yaml b/Documentation/devicetree/bindings/i2c/cdns,i2c-r1p10.yaml
new file mode 100644
index 000000000000..dc0952f3780f
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/cdns,i2c-r1p10.yaml
@@ -0,0 +1,58 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/i2c/cdns,i2c-r1p10.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Cadence I2C controller Device Tree Bindings
+
+maintainers:
+  - Michal Simek <michal.simek@xilinx.com>
+
+allOf:
+  - $ref: /schemas/i2c/i2c-controller.yaml#
+
+properties:
+  compatible:
+    enum:
+      - cdns,i2c-r1p10 # cadence i2c controller version 1.0
+      - cdns,i2c-r1p14 # cadence i2c controller version 1.4
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    minItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clock-frequency:
+    minimum: 1
+    maximum: 400000
+    description: |
+      Desired operating frequency, in Hz, of the bus.
+
+  clock-name:
+    const: pclk
+    description: |
+      Input clock name.
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - interrupts
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    i2c@e0004000 {
+        compatible = "cdns,i2c-r1p10";
+        clocks = <&clkc 38>;
+        interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+        reg = <0xe0004000 0x1000>;
+        clock-frequency = <400000>;
+        #address-cells = <1>;
+        #size-cells = <0>;
+    };
diff --git a/Documentation/devicetree/bindings/i2c/i2c-cadence.txt b/Documentation/devicetree/bindings/i2c/i2c-cadence.txt
deleted file mode 100644
index ebaa90c58c8e..000000000000
--- a/Documentation/devicetree/bindings/i2c/i2c-cadence.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-Binding for the Cadence I2C controller
-
-Required properties:
-  - reg: Physical base address and size of the controller's register area.
-  - compatible: Should contain one of:
-		* "cdns,i2c-r1p10"
-		Note:	Use this when cadence i2c controller version 1.0 is used.
-		* "cdns,i2c-r1p14"
-		Note:	Use this when cadence i2c controller version 1.4 is used.
-  - clocks: Input clock specifier. Refer to common clock bindings.
-  - interrupts: Interrupt specifier. Refer to interrupt bindings.
-  - #address-cells: Should be 1.
-  - #size-cells: Should be 0.
-
-Optional properties:
-  - clock-frequency: Desired operating frequency, in Hz, of the bus.
-  - clock-names: Input clock name, should be 'pclk'.
-
-Example:
-	i2c@e0004000 {
-		compatible = "cdns,i2c-r1p10";
-		clocks = <&clkc 38>;
-		interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
-		reg = <0xe0004000 0x1000>;
-		clock-frequency = <400000>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-	};
diff --git a/Documentation/devicetree/bindings/i2c/i2c-rk3x.yaml b/Documentation/devicetree/bindings/i2c/i2c-rk3x.yaml
index 61eac76c84c4..790aa7218ee0 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-rk3x.yaml
+++ b/Documentation/devicetree/bindings/i2c/i2c-rk3x.yaml
@@ -28,14 +28,14 @@ properties:
       - const: rockchip,rk3399-i2c
       - items:
           - enum:
-            - rockchip,rk3036-i2c
-            - rockchip,rk3368-i2c
+              - rockchip,rk3036-i2c
+              - rockchip,rk3368-i2c
           - const: rockchip,rk3288-i2c
       - items:
           - enum:
-            - rockchip,px30-i2c
-            - rockchip,rk3308-i2c
-            - rockchip,rk3328-i2c
+              - rockchip,px30-i2c
+              - rockchip,rk3308-i2c
+              - rockchip,rk3328-i2c
           - const: rockchip,rk3399-i2c
 
   reg:
diff --git a/Documentation/devicetree/bindings/i2c/i2c-xiic.txt b/Documentation/devicetree/bindings/i2c/i2c-xiic.txt
deleted file mode 100644
index caf42e989462..000000000000
--- a/Documentation/devicetree/bindings/i2c/i2c-xiic.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-Xilinx IIC controller:
-
-Required properties:
-- compatible : Must be "xlnx,xps-iic-2.00.a"
-- reg : IIC register location and length
-- interrupts : IIC controller unterrupt
-- #address-cells = <1>
-- #size-cells = <0>
-- clocks: Input clock specifier. Refer to common clock bindings.
-
-Optional properties:
-- Child nodes conforming to i2c bus binding
-- clock-names: Input clock name, should be 'pclk'.
-
-Example:
-
-	axi_iic_0: i2c@40800000 {
-		compatible = "xlnx,xps-iic-2.00.a";
-		clocks = <&clkc 15>;
-		interrupts = < 1 2 >;
-		reg = < 0x40800000 0x10000 >;
-
-		#size-cells = <0>;
-		#address-cells = <1>;
-	};
diff --git a/Documentation/devicetree/bindings/i2c/xlnx,xps-iic-2.00.a.yaml b/Documentation/devicetree/bindings/i2c/xlnx,xps-iic-2.00.a.yaml
new file mode 100644
index 000000000000..67c1c84ba3dc
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/xlnx,xps-iic-2.00.a.yaml
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/i2c/xlnx,xps-iic-2.00.a.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: ilinx IIC controller Device Tree Bindings
+
+maintainers:
+  - info@mocean-labs.com
+
+allOf:
+  - $ref: /schemas/i2c/i2c-controller.yaml#
+
+properties:
+  compatible:
+    const: xlnx,xps-iic-2.00.a
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    minItems: 1
+
+  clock-name:
+    const: pclk
+    description: |
+      Input clock name.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+
+examples:
+  - |
+    axi_iic_0: i2c@40800000 {
+      compatible = "xlnx,xps-iic-2.00.a";
+      clocks = <&clkc 15>;
+      interrupts = < 1 2 >;
+      reg = < 0x40800000 0x10000 >;
+
+      #size-cells = <0>;
+      #address-cells = <1>;
+    };
diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7124.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad7124.yaml
index f0934b295edc..97087a45ce54 100644
--- a/Documentation/devicetree/bindings/iio/adc/adi,ad7124.yaml
+++ b/Documentation/devicetree/bindings/iio/adc/adi,ad7124.yaml
@@ -72,8 +72,8 @@ patternProperties:
           The channel number. It can have up to 8 channels on ad7124-4
           and 16 channels on ad7124-8, numbered from 0 to 15.
         items:
-         minimum: 0
-         maximum: 15
+          minimum: 0
+          maximum: 15
 
       adi,reference-select:
         description: |
diff --git a/Documentation/devicetree/bindings/iio/adc/lltc,ltc2496.yaml b/Documentation/devicetree/bindings/iio/adc/lltc,ltc2496.yaml
index 118809a03279..97f521d654ea 100644
--- a/Documentation/devicetree/bindings/iio/adc/lltc,ltc2496.yaml
+++ b/Documentation/devicetree/bindings/iio/adc/lltc,ltc2496.yaml
@@ -7,9 +7,9 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
 title: Linear Technology / Analog Devices LTC2496 ADC
 
 maintainers:
- - Lars-Peter Clausen <lars@metafoo.de>
- - Michael Hennerich <Michael.Hennerich@analog.com>
- - Stefan Popa <stefan.popa@analog.com>
+  - Lars-Peter Clausen <lars@metafoo.de>
+  - Michael Hennerich <Michael.Hennerich@analog.com>
+  - Stefan Popa <stefan.popa@analog.com>
 
 properties:
   compatible:
diff --git a/Documentation/devicetree/bindings/iio/dac/ad5755.txt b/Documentation/devicetree/bindings/iio/dac/ad5755.txt
index f0bbd7e1029b..502e1e55adbd 100644
--- a/Documentation/devicetree/bindings/iio/dac/ad5755.txt
+++ b/Documentation/devicetree/bindings/iio/dac/ad5755.txt
@@ -1,4 +1,4 @@
-* Analog Device AD5755 IIO Multi-Channel DAC Linux Driver
+* Analog Devices AD5755 IIO Multi-Channel DAC Linux Driver
 
 Required properties:
  - compatible: Has to contain one of the following:
diff --git a/Documentation/devicetree/bindings/iio/dac/adi,ad5770r.yaml b/Documentation/devicetree/bindings/iio/dac/adi,ad5770r.yaml
index d9c25cf4b92f..58d81ca43460 100644
--- a/Documentation/devicetree/bindings/iio/dac/adi,ad5770r.yaml
+++ b/Documentation/devicetree/bindings/iio/dac/adi,ad5770r.yaml
@@ -2,7 +2,7 @@
 # Copyright 2020 Analog Devices Inc.
 %YAML 1.2
 ---
-$id: http://devicetree.org/schemas/bindings/iio/dac/adi,ad5770r.yaml#
+$id: http://devicetree.org/schemas/iio/dac/adi,ad5770r.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
 title: Analog Devices AD5770R DAC device driver
@@ -49,93 +49,86 @@ properties:
       asserted during driver probe.
     maxItems: 1
 
-  channel0:
+  channel@0:
     description: Represents an external channel which are
       connected to the DAC. Channel 0 can act both as a current
       source and sink.
     type: object
 
     properties:
-      num:
+      reg:
         description: This represents the channel number.
-        items:
-          const: 0
+        const: 0
 
       adi,range-microamp:
           description: Output range of the channel.
           oneOf:
-            - $ref: /schemas/types.yaml#/definitions/int32-array
             - items:
-                - enum: [0 300000]
-                - enum: [-60000 0]
-                - enum: [-60000 300000]
+                - const: 0
+                - const: 300000
+            - items:
+                - const: -60000
+                - const: 0
+            - items:
+                - const: -60000
+                - const: 300000
 
-  channel1:
+  channel@1:
     description: Represents an external channel which are
       connected to the DAC.
     type: object
 
     properties:
-      num:
+      reg:
         description: This represents the channel number.
-        items:
-          const: 1
+        const: 1
 
       adi,range-microamp:
           description: Output range of the channel.
-          oneOf:
-            - $ref: /schemas/types.yaml#/definitions/uint32-array
-            - items:
-                - enum: [0 140000]
-                - enum: [0 250000]
+          items:
+            - const: 0
+            - enum: [ 140000, 250000 ]
 
-  channel2:
+  channel@2:
     description: Represents an external channel which are
       connected to the DAC.
     type: object
 
     properties:
-      num:
+      reg:
         description: This represents the channel number.
-        items:
-          const: 2
+        const: 2
 
       adi,range-microamp:
           description: Output range of the channel.
-          oneOf:
-            - $ref: /schemas/types.yaml#/definitions/uint32-array
-            - items:
-                - enum: [0 140000]
-                - enum: [0 250000]
+          items:
+            - const: 0
+            - enum: [ 55000, 150000 ]
 
 patternProperties:
   "^channel@([3-5])$":
     type: object
     description: Represents the external channels which are connected to the DAC.
     properties:
-      num:
+      reg:
         description: This represents the channel number.
-        items:
-          minimum: 3
-          maximum: 5
+        minimum: 3
+        maximum: 5
 
       adi,range-microamp:
           description: Output range of the channel.
-          oneOf:
-            - $ref: /schemas/types.yaml#/definitions/uint32-array
-            - items:
-                - enum: [0 45000]
-                - enum: [0 100000]
+          items:
+            - const: 0
+            - enum: [ 45000, 100000 ]
 
 required:
 - reg
-- diff-channels
-- channel0
-- channel1
-- channel2
-- channel3
-- channel4
-- channel5
+- channel@0
+- channel@1
+- channel@2
+- channel@3
+- channel@4
+- channel@5
 
 examples:
   - |
@@ -144,40 +137,42 @@ examples:
                 #size-cells = <0>;
 
                 ad5770r@0 {
-                        compatible = "ad5770r";
+                        compatible = "adi,ad5770r";
                         reg = <0>;
                         spi-max-frequency = <1000000>;
                         vref-supply = <&vref>;
                         adi,external-resistor;
                         reset-gpios = <&gpio 22 0>;
+                        #address-cells = <1>;
+                        #size-cells = <0>;
 
                         channel@0 {
-                                num = <0>;
-                                adi,range-microamp = <(-60000) 300000>;
+                                reg = <0>;
+                                adi,range-microamp = <0 300000>;
                         };
 
                         channel@1 {
-                                num = <1>;
+                                reg = <1>;
                                 adi,range-microamp = <0 140000>;
                         };
 
                         channel@2 {
-                                num = <2>;
+                                reg = <2>;
                                 adi,range-microamp = <0 55000>;
                         };
 
                         channel@3 {
-                                num = <3>;
+                                reg = <3>;
                                 adi,range-microamp = <0 45000>;
                         };
 
                         channel@4 {
-                                num = <4>;
+                                reg = <4>;
                                 adi,range-microamp = <0 45000>;
                         };
 
                         channel@5 {
-                                num = <5>;
+                                reg = <5>;
                                 adi,range-microamp = <0 45000>;
                         };
                 };
diff --git a/Documentation/devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml b/Documentation/devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml
index 5b3b71c9c018..512a6af5aa42 100644
--- a/Documentation/devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml
+++ b/Documentation/devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml
@@ -16,8 +16,8 @@ properties:
       - const: allwinner,sun4i-a10-lradc-keys
       - const: allwinner,sun8i-a83t-r-lradc
       - items:
-        - const: allwinner,sun50i-a64-lradc
-        - const: allwinner,sun8i-a83t-r-lradc
+          - const: allwinner,sun50i-a64-lradc
+          - const: allwinner,sun8i-a83t-r-lradc
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/input/gpio-keys-polled.txt b/Documentation/devicetree/bindings/input/gpio-keys-polled.txt
deleted file mode 100644
index 4d9a3717eaaf..000000000000
--- a/Documentation/devicetree/bindings/input/gpio-keys-polled.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-Device-Tree bindings for input/gpio_keys_polled.c keyboard driver
-
-Required properties:
-	- compatible = "gpio-keys-polled";
-	- poll-interval: Poll interval time in milliseconds
-
-Optional properties:
-	- autorepeat: Boolean, Enable auto repeat feature of Linux input
-	  subsystem.
-
-Each button (key) is represented as a sub-node of "gpio-keys-polled":
-Subnode properties:
-
-	- gpios: OF device-tree gpio specification.
-	- label: Descriptive name of the key.
-	- linux,code: Key / Axis code to emit.
-
-Optional subnode-properties:
-	- linux,input-type: Specify event type this button/key generates.
-	  If not specified defaults to <1> == EV_KEY.
-	- linux,input-value: If linux,input-type is EV_ABS or EV_REL then this
-	  value is sent for events this button generates when pressed.
-	  EV_ABS/EV_REL axis will generate an event with a value of 0 when
-	  all buttons with linux,input-type == type and linux,code == axis
-	  are released. This value is interpreted as a signed 32 bit value,
-	  e.g. to make a button generate a value of -1 use:
-	  linux,input-value = <0xffffffff>; /* -1 */
-	- debounce-interval: Debouncing interval time in milliseconds.
-	  If not specified defaults to 5.
-	- wakeup-source: Boolean, button can wake-up the system.
-			 (Legacy property supported: "gpio-key,wakeup")
-
-Example nodes:
-
-	gpio_keys_polled {
-			compatible = "gpio-keys-polled";
-			poll-interval = <100>;
-			autorepeat;
-
-			button21 {
-				label = "GPIO Key UP";
-				linux,code = <103>;
-				gpios = <&gpio1 0 1>;
-			};
-			...
diff --git a/Documentation/devicetree/bindings/input/gpio-keys.txt b/Documentation/devicetree/bindings/input/gpio-keys.txt
deleted file mode 100644
index 7cccc49b6bea..000000000000
--- a/Documentation/devicetree/bindings/input/gpio-keys.txt
+++ /dev/null
@@ -1,58 +0,0 @@
-Device-Tree bindings for input/keyboard/gpio_keys.c keyboard driver
-
-Required properties:
-	- compatible = "gpio-keys";
-
-Optional properties:
-	- autorepeat: Boolean, Enable auto repeat feature of Linux input
-	  subsystem.
-	- label: String, name of the input device.
-
-Each button (key) is represented as a sub-node of "gpio-keys":
-Subnode properties:
-
-	- gpios: OF device-tree gpio specification.
-	- interrupts: the interrupt line for that input.
-	- label: Descriptive name of the key.
-	- linux,code: Keycode to emit.
-
-Note that either "interrupts" or "gpios" properties can be omitted, but not
-both at the same time. Specifying both properties is allowed.
-
-Optional subnode-properties:
-	- linux,input-type: Specify event type this button/key generates.
-	  If not specified defaults to <1> == EV_KEY.
-	- debounce-interval: Debouncing interval time in milliseconds.
-	  If not specified defaults to 5.
-	- wakeup-source: Boolean, button can wake-up the system.
-			 (Legacy property supported: "gpio-key,wakeup")
-	- wakeup-event-action: Specifies whether the key should wake the
-	  system when asserted, when deasserted, or both. This property is
-	  only valid for keys that wake up the system (e.g., when the
-	  "wakeup-source" property is also provided).
-	  Supported values are defined in linux-event-codes.h:
-		EV_ACT_ASSERTED		- asserted
-		EV_ACT_DEASSERTED	- deasserted
-		EV_ACT_ANY		- both asserted and deasserted
-	- linux,can-disable: Boolean, indicates that button is connected
-	  to dedicated (not shared) interrupt which can be disabled to
-	  suppress events from the button.
-
-Example nodes:
-
-	gpio-keys {
-			compatible = "gpio-keys";
-			autorepeat;
-
-			up {
-				label = "GPIO Key UP";
-				linux,code = <103>;
-				gpios = <&gpio1 0 1>;
-			};
-
-			down {
-				label = "GPIO Key DOWN";
-				linux,code = <108>;
-				interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
-			};
-			...
diff --git a/Documentation/devicetree/bindings/input/gpio-keys.yaml b/Documentation/devicetree/bindings/input/gpio-keys.yaml
new file mode 100644
index 000000000000..c0b389572340
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/gpio-keys.yaml
@@ -0,0 +1,152 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/gpio-keys.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Device-Tree bindings for GPIO attached keys
+
+maintainers:
+  - Rob Herring <robh@kernel.org>
+
+properties:
+  compatible:
+    enum:
+      - gpio-keys
+      - gpio-keys-polled
+
+patternProperties:
+  ".*":
+    if:
+      type: object
+    then:
+      allOf:
+        - $ref: input.yaml#
+
+      properties:
+        gpios:
+          maxItems: 1
+
+        interrupts:
+          maxItems: 1
+
+        label:
+          description: Descriptive name of the key.
+
+        linux,code:
+          description: Key / Axis code to emit.
+          $ref: /schemas/types.yaml#definitions/uint32
+
+        linux,input-type:
+          description:
+            Specify event type this button/key generates. If not specified defaults to
+            <1> == EV_KEY.
+          allOf:
+            - $ref: /schemas/types.yaml#definitions/uint32
+          default: 1
+
+        linux,input-value:
+          description: |
+            If linux,input-type is EV_ABS or EV_REL then this
+            value is sent for events this button generates when pressed.
+            EV_ABS/EV_REL axis will generate an event with a value of 0
+            when all buttons with linux,input-type == type and
+            linux,code == axis are released. This value is interpreted
+            as a signed 32 bit value, e.g. to make a button generate a
+            value of -1 use:
+
+            linux,input-value = <0xffffffff>; /* -1 */
+
+          allOf:
+            - $ref: /schemas/types.yaml#definitions/uint32
+
+        debounce-interval:
+          description:
+            Debouncing interval time in milliseconds. If not specified defaults to 5.
+          allOf:
+            - $ref: /schemas/types.yaml#definitions/uint32
+          default: 5
+
+        wakeup-source:
+          description: Button can wake-up the system.
+
+        wakeup-event-action:
+          description: |
+            Specifies whether the key should wake the system when asserted, when
+            deasserted, or both. This property is only valid for keys that wake up the
+            system (e.g., when the "wakeup-source" property is also provided).
+
+            Supported values are defined in linux-event-codes.h:
+
+              EV_ACT_ANY        - both asserted and deasserted
+              EV_ACT_ASSERTED   - asserted
+              EV_ACT_DEASSERTED - deasserted
+          allOf:
+            - $ref: /schemas/types.yaml#definitions/uint32
+          enum: [ 0, 1, 2 ]
+
+        linux,can-disable:
+          description:
+            Indicates that button is connected to dedicated (not shared) interrupt
+            which can be disabled to suppress events from the button.
+          type: boolean
+
+        pinctrl-0:
+          maxItems: 1
+
+        pinctrl-names:
+          maxItems: 1
+
+      required:
+        - linux,code
+
+      anyOf:
+        - required:
+            - interrupts
+        - required:
+            - gpios
+
+      dependencies:
+        wakeup-event-action: [ wakeup-source ]
+        linux,input-value: [ gpios ]
+
+      unevaluatedProperties: false
+
+if:
+  properties:
+    compatible:
+      const: gpio-keys-polled
+then:
+  properties:
+    poll-interval:
+      description:
+        Poll interval time in milliseconds
+      $ref: /schemas/types.yaml#definitions/uint32
+
+  required:
+    - poll-interval
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    gpio-keys {
+        compatible = "gpio-keys";
+        autorepeat;
+
+        up {
+            label = "GPIO Key UP";
+            linux,code = <103>;
+            gpios = <&gpio1 0 1>;
+        };
+
+        down {
+            label = "GPIO Key DOWN";
+            linux,code = <108>;
+            interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+        };
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.yaml b/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.yaml
index 8d58709d4b47..383d64a91854 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.yaml
+++ b/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.yaml
@@ -109,7 +109,7 @@ examples:
   - |
     #include <dt-bindings/gpio/gpio.h>
     #include <dt-bindings/interrupt-controller/arm-gic.h>
-    i2c@00000000 {
+    i2c {
       #address-cells = <1>;
       #size-cells = <0>;
       edt-ft5x06@38 {
diff --git a/Documentation/devicetree/bindings/input/touchscreen/goodix.yaml b/Documentation/devicetree/bindings/input/touchscreen/goodix.yaml
index c8ea9434c9cc..e81cfa56f25a 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/goodix.yaml
+++ b/Documentation/devicetree/bindings/input/touchscreen/goodix.yaml
@@ -63,7 +63,7 @@ required:
   - interrupts
 
 examples:
-- |
+  - |
     i2c {
       #address-cells = <1>;
       #size-cells = <0>;
diff --git a/Documentation/devicetree/bindings/interconnect/qcom,msm8916.yaml b/Documentation/devicetree/bindings/interconnect/qcom,msm8916.yaml
index 4107e60cab12..e1009ae4e8f7 100644
--- a/Documentation/devicetree/bindings/interconnect/qcom,msm8916.yaml
+++ b/Documentation/devicetree/bindings/interconnect/qcom,msm8916.yaml
@@ -10,8 +10,8 @@ maintainers:
   - Georgi Djakov <georgi.djakov@linaro.org>
 
 description: |
-   The Qualcomm MSM8916 interconnect providers support adjusting the
-   bandwidth requirements between the various NoC fabrics.
+  The Qualcomm MSM8916 interconnect providers support adjusting the
+  bandwidth requirements between the various NoC fabrics.
 
 properties:
   compatible:
diff --git a/Documentation/devicetree/bindings/interconnect/qcom,msm8974.yaml b/Documentation/devicetree/bindings/interconnect/qcom,msm8974.yaml
index 9af3c6e59cff..8004c4baf397 100644
--- a/Documentation/devicetree/bindings/interconnect/qcom,msm8974.yaml
+++ b/Documentation/devicetree/bindings/interconnect/qcom,msm8974.yaml
@@ -10,8 +10,8 @@ maintainers:
   - Brian Masney <masneyb@onstation.org>
 
 description: |
-   The Qualcomm MSM8974 interconnect providers support setting system
-   bandwidth requirements between various network-on-chip fabrics.
+  The Qualcomm MSM8974 interconnect providers support setting system
+  bandwidth requirements between various network-on-chip fabrics.
 
 properties:
   reg:
diff --git a/Documentation/devicetree/bindings/interconnect/qcom,qcs404.yaml b/Documentation/devicetree/bindings/interconnect/qcom,qcs404.yaml
index 8d65c5f80679..3fbb8785fbc9 100644
--- a/Documentation/devicetree/bindings/interconnect/qcom,qcs404.yaml
+++ b/Documentation/devicetree/bindings/interconnect/qcom,qcs404.yaml
@@ -10,8 +10,8 @@ maintainers:
   - Georgi Djakov <georgi.djakov@linaro.org>
 
 description: |
-   The Qualcomm QCS404 interconnect providers support adjusting the
-   bandwidth requirements between the various NoC fabrics.
+  The Qualcomm QCS404 interconnect providers support adjusting the
+  bandwidth requirements between the various NoC fabrics.
 
 properties:
   reg:
diff --git a/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun7i-a20-sc-nmi.yaml b/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun7i-a20-sc-nmi.yaml
index cf09055da78b..7cd6b8bacfa0 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun7i-a20-sc-nmi.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun7i-a20-sc-nmi.yaml
@@ -27,15 +27,15 @@ properties:
         deprecated: true
       - const: allwinner,sun7i-a20-sc-nmi
       - items:
-        - const: allwinner,sun8i-a83t-r-intc
-        - const: allwinner,sun6i-a31-r-intc
+          - const: allwinner,sun8i-a83t-r-intc
+          - const: allwinner,sun6i-a31-r-intc
       - const: allwinner,sun9i-a80-sc-nmi
       - items:
-        - const: allwinner,sun50i-a64-r-intc
-        - const: allwinner,sun6i-a31-r-intc
+          - const: allwinner,sun50i-a64-r-intc
+          - const: allwinner,sun6i-a31-r-intc
       - items:
-        - const: allwinner,sun50i-h6-r-intc
-        - const: allwinner,sun6i-a31-r-intc
+          - const: allwinner,sun50i-h6-r-intc
+          - const: allwinner,sun6i-a31-r-intc
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/interrupt-controller/intel,ixp4xx-interrupt.yaml b/Documentation/devicetree/bindings/interrupt-controller/intel,ixp4xx-interrupt.yaml
index ccc507f384d2..14dced11877b 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/intel,ixp4xx-interrupt.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/intel,ixp4xx-interrupt.yaml
@@ -25,10 +25,10 @@ properties:
   compatible:
     items:
       - enum:
-        - intel,ixp42x-interrupt
-        - intel,ixp43x-interrupt
-        - intel,ixp45x-interrupt
-        - intel,ixp46x-interrupt
+          - intel,ixp42x-interrupt
+          - intel,ixp43x-interrupt
+          - intel,ixp45x-interrupt
+          - intel,ixp46x-interrupt
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/interrupt-controller/loongson,liointc.yaml b/Documentation/devicetree/bindings/interrupt-controller/loongson,liointc.yaml
index 9c6b91fee477..26f1fcf0857a 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/loongson,liointc.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/loongson,liointc.yaml
@@ -56,9 +56,8 @@ properties:
       cell with zero.
     allOf:
       - $ref: /schemas/types.yaml#/definitions/uint32-array
-      - items:
-          minItems: 4
-          maxItems: 4
+      - minItems: 4
+        maxItems: 4
 
 
 required:
diff --git a/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.yaml b/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.yaml
index 9e5c6608b4e3..2a5b29567926 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.yaml
@@ -14,13 +14,13 @@ properties:
   compatible:
     oneOf:
       - items:
-        - enum:
-          - st,stm32-exti
-          - st,stm32h7-exti
+          - enum:
+              - st,stm32-exti
+              - st,stm32h7-exti
       - items:
-        - enum:
-          - st,stm32mp1-exti
-        - const: syscon
+          - enum:
+              - st,stm32mp1-exti
+          - const: syscon
 
   "#interrupt-cells":
     const: 2
diff --git a/Documentation/devicetree/bindings/iommu/samsung,sysmmu.yaml b/Documentation/devicetree/bindings/iommu/samsung,sysmmu.yaml
index 0e33cd9e010e..af51b91c893e 100644
--- a/Documentation/devicetree/bindings/iommu/samsung,sysmmu.yaml
+++ b/Documentation/devicetree/bindings/iommu/samsung,sysmmu.yaml
@@ -54,13 +54,13 @@ properties:
   clock-names:
     oneOf:
       - items:
-        - const: sysmmu
+          - const: sysmmu
       - items:
-        - const: sysmmu
-        - const: master
+          - const: sysmmu
+          - const: master
       - items:
-        - const: aclk
-        - const: pclk
+          - const: aclk
+          - const: pclk
 
   "#iommu-cells":
     const: 0
diff --git a/Documentation/devicetree/bindings/mailbox/st,stm32-ipcc.yaml b/Documentation/devicetree/bindings/mailbox/st,stm32-ipcc.yaml
index 5b13d6672996..db851541d619 100644
--- a/Documentation/devicetree/bindings/mailbox/st,stm32-ipcc.yaml
+++ b/Documentation/devicetree/bindings/mailbox/st,stm32-ipcc.yaml
@@ -24,7 +24,7 @@ properties:
     maxItems: 1
 
   clocks:
-     maxItems: 1
+    maxItems: 1
 
   interrupts:
     items:
diff --git a/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml b/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml
index 8453ee340b9f..09318830db47 100644
--- a/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml
+++ b/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml
@@ -20,11 +20,11 @@ properties:
       - const: allwinner,sun4i-a10-csi1
       - const: allwinner,sun7i-a20-csi0
       - items:
-        - const: allwinner,sun7i-a20-csi1
-        - const: allwinner,sun4i-a10-csi1
+          - const: allwinner,sun7i-a20-csi1
+          - const: allwinner,sun4i-a10-csi1
       - items:
-        - const: allwinner,sun8i-r40-csi0
-        - const: allwinner,sun7i-a20-csi0
+          - const: allwinner,sun8i-r40-csi0
+          - const: allwinner,sun7i-a20-csi0
 
   reg:
     maxItems: 1
@@ -35,24 +35,24 @@ properties:
   clocks:
     oneOf:
       - items:
-        - description: The CSI interface clock
-        - description: The CSI DRAM clock
+          - description: The CSI interface clock
+          - description: The CSI DRAM clock
 
       - items:
-        - description: The CSI interface clock
-        - description: The CSI ISP clock
-        - description: The CSI DRAM clock
+          - description: The CSI interface clock
+          - description: The CSI ISP clock
+          - description: The CSI DRAM clock
 
   clock-names:
     oneOf:
       - items:
-        - const: bus
-        - const: ram
+          - const: bus
+          - const: ram
 
       - items:
-        - const: bus
-        - const: isp
-        - const: ram
+          - const: bus
+          - const: isp
+          - const: ram
 
   resets:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/media/amlogic,gx-vdec.yaml b/Documentation/devicetree/bindings/media/amlogic,gx-vdec.yaml
index 37d77e065491..5a1da4029c37 100644
--- a/Documentation/devicetree/bindings/media/amlogic,gx-vdec.yaml
+++ b/Documentation/devicetree/bindings/media/amlogic,gx-vdec.yaml
@@ -29,14 +29,14 @@ properties:
   compatible:
     oneOf:
       - items:
-        - enum:
-          - amlogic,gxbb-vdec # GXBB (S905)
-          - amlogic,gxl-vdec # GXL (S905X, S905D)
-          - amlogic,gxm-vdec # GXM (S912)
-        - const: amlogic,gx-vdec
+          - enum:
+              - amlogic,gxbb-vdec # GXBB (S905)
+              - amlogic,gxl-vdec # GXL (S905X, S905D)
+              - amlogic,gxm-vdec # GXM (S912)
+          - const: amlogic,gx-vdec
       - enum:
-        - amlogic,g12a-vdec # G12A (S905X2, S905D2)
-        - amlogic,sm1-vdec # SM1 (S905X3, S905D3)
+          - amlogic,g12a-vdec # G12A (S905X2, S905D2)
+          - amlogic,sm1-vdec # SM1 (S905X3, S905D3)
 
   interrupts:
     minItems: 2
diff --git a/Documentation/devicetree/bindings/media/renesas,ceu.yaml b/Documentation/devicetree/bindings/media/renesas,ceu.yaml
index fcb5f13704a5..f2393458814e 100644
--- a/Documentation/devicetree/bindings/media/renesas,ceu.yaml
+++ b/Documentation/devicetree/bindings/media/renesas,ceu.yaml
@@ -32,23 +32,23 @@ properties:
     additionalProperties: false
 
     properties:
-       endpoint:
-         type: object
-         additionalProperties: false
+      endpoint:
+        type: object
+        additionalProperties: false
 
          # Properties described in
          # Documentation/devicetree/bindings/media/video-interfaces.txt
-         properties:
-           remote-endpoint: true
-           hsync-active: true
-           vsync-active: true
-           field-even-active: false
-           bus-width:
-             enum: [8, 16]
-             default: 8
-
-         required:
-           - remote-endpoint
+        properties:
+          remote-endpoint: true
+          hsync-active: true
+          vsync-active: true
+          field-even-active: false
+          bus-width:
+            enum: [8, 16]
+            default: 8
+
+        required:
+          - remote-endpoint
 
     required:
       - endpoint
diff --git a/Documentation/devicetree/bindings/media/renesas,vin.yaml b/Documentation/devicetree/bindings/media/renesas,vin.yaml
index 1ec947b4781f..ecc09f1124d4 100644
--- a/Documentation/devicetree/bindings/media/renesas,vin.yaml
+++ b/Documentation/devicetree/bindings/media/renesas,vin.yaml
@@ -261,13 +261,13 @@ properties:
 
         anyOf:
           - required:
-            - endpoint@0
+              - endpoint@0
           - required:
-            - endpoint@1
+              - endpoint@1
           - required:
-            - endpoint@2
+              - endpoint@2
           - required:
-            - endpoint@3
+              - endpoint@3
 
         additionalProperties: false
 
diff --git a/Documentation/devicetree/bindings/media/rockchip-vpu.txt b/Documentation/devicetree/bindings/media/rockchip-vpu.txt
deleted file mode 100644
index 339252d9c515..000000000000
--- a/Documentation/devicetree/bindings/media/rockchip-vpu.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-device-tree bindings for rockchip VPU codec
-
-Rockchip (Video Processing Unit) present in various Rockchip platforms,
-such as RK3288, RK3328 and RK3399.
-
-Required properties:
-- compatible: value should be one of the following
-		"rockchip,rk3288-vpu";
-		"rockchip,rk3328-vpu";
-		"rockchip,rk3399-vpu";
-- interrupts: encoding and decoding interrupt specifiers
-- interrupt-names: should be
-		"vepu", "vdpu" on RK3288 and RK3399,
-		"vdpu" on RK3328.
-- clocks: phandle to VPU aclk, hclk clocks
-- clock-names: should be "aclk" and "hclk"
-- power-domains: phandle to power domain node
-- iommus: phandle to a iommu node
-
-Example:
-SoC-specific DT entry:
-	vpu: video-codec@ff9a0000 {
-		compatible = "rockchip,rk3288-vpu";
-		reg = <0x0 0xff9a0000 0x0 0x800>;
-		interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-names = "vepu", "vdpu";
-		clocks = <&cru ACLK_VCODEC>, <&cru HCLK_VCODEC>;
-		clock-names = "aclk", "hclk";
-		power-domains = <&power RK3288_PD_VIDEO>;
-		iommus = <&vpu_mmu>;
-	};
-
-	vpu: video-codec@ff350000 {
-		compatible = "rockchip,rk3328-vpu";
-		reg = <0x0 0xff350000 0x0 0x800>;
-		interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-names = "vdpu";
-		clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
-		clock-names = "aclk", "hclk";
-		power-domains = <&power RK3328_PD_VPU>;
-		iommus = <&vpu_mmu>;
-	};
diff --git a/Documentation/devicetree/bindings/media/rockchip-vpu.yaml b/Documentation/devicetree/bindings/media/rockchip-vpu.yaml
new file mode 100644
index 000000000000..d7a42e6f9bcf
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/rockchip-vpu.yaml
@@ -0,0 +1,74 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/media/rockchip-vpu.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Hantro G1 VPU codecs implemented on Rockchip SoCs
+
+maintainers:
+  - Ezequiel Garcia <ezequiel@collabora.com>
+
+description:
+  Hantro G1 video encode and decode accelerators present on Rockchip SoCs.
+
+properties:
+  compatible:
+    enum:
+      - rockchip,rk3288-vpu
+      - rockchip,rk3328-vpu
+      - rockchip,rk3399-vpu
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 2
+
+  interrupt-names:
+    items:
+      - const: vepu
+      - const: vdpu
+
+  clocks:
+    maxItems: 2
+
+  clock-names:
+    items:
+      - const: aclk
+      - const: hclk
+
+  power-domains:
+    maxItems: 1
+
+  iommus:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - interrupt-names
+  - clocks
+  - clock-names
+
+additionalProperties: false
+
+examples:
+  - |
+        #include <dt-bindings/clock/rk3288-cru.h>
+        #include <dt-bindings/interrupt-controller/arm-gic.h>
+        #include <dt-bindings/power/rk3288-power.h>
+
+        vpu: video-codec@ff9a0000 {
+                compatible = "rockchip,rk3288-vpu";
+                reg = <0x0 0xff9a0000 0x0 0x800>;
+                interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+                             <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+                interrupt-names = "vepu", "vdpu";
+                clocks = <&cru ACLK_VCODEC>, <&cru HCLK_VCODEC>;
+                clock-names = "aclk", "hclk";
+                power-domains = <&power RK3288_PD_VIDEO>;
+                iommus = <&vpu_mmu>;
+        };
diff --git a/Documentation/devicetree/bindings/media/ti,vpe.yaml b/Documentation/devicetree/bindings/media/ti,vpe.yaml
index f3a8a350e85f..ef473f287399 100644
--- a/Documentation/devicetree/bindings/media/ti,vpe.yaml
+++ b/Documentation/devicetree/bindings/media/ti,vpe.yaml
@@ -17,7 +17,7 @@ description: |-
 
 properties:
   compatible:
-      const: ti,dra7-vpe
+    const: ti,dra7-vpe
 
   reg:
     items:
diff --git a/Documentation/devicetree/bindings/memory-controllers/exynos-srom.yaml b/Documentation/devicetree/bindings/memory-controllers/exynos-srom.yaml
index cdfe3f7f0ea9..1250087b4ee6 100644
--- a/Documentation/devicetree/bindings/memory-controllers/exynos-srom.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/exynos-srom.yaml
@@ -51,9 +51,7 @@ patternProperties:
         maxItems: 1
 
       reg-io-width:
-        allOf:
-          - $ref: /schemas/types.yaml#/definitions/uint32
-          - enum: [1, 2]
+        enum: [1, 2]
         description:
           Data width in bytes (1 or 2). If omitted, default of 1 is used.
 
diff --git a/Documentation/devicetree/bindings/memory-controllers/fsl/imx8m-ddrc.yaml b/Documentation/devicetree/bindings/memory-controllers/fsl/imx8m-ddrc.yaml
index c9e6c22cb5be..445e46feda69 100644
--- a/Documentation/devicetree/bindings/memory-controllers/fsl/imx8m-ddrc.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/fsl/imx8m-ddrc.yaml
@@ -25,9 +25,9 @@ properties:
   compatible:
     items:
       - enum:
-        - fsl,imx8mn-ddrc
-        - fsl,imx8mm-ddrc
-        - fsl,imx8mq-ddrc
+          - fsl,imx8mn-ddrc
+          - fsl,imx8mm-ddrc
+          - fsl,imx8mq-ddrc
       - const: fsl,imx8m-ddrc
 
   reg:
diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra186-mc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra186-mc.yaml
index 12516bd89cf9..611bda38d187 100644
--- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra186-mc.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra186-mc.yaml
@@ -97,30 +97,35 @@ examples:
     #include <dt-bindings/clock/tegra186-clock.h>
     #include <dt-bindings/interrupt-controller/arm-gic.h>
 
-    memory-controller@2c00000 {
-        compatible = "nvidia,tegra186-mc";
-        reg = <0x0 0x02c00000 0x0 0xb0000>;
-        interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>;
-
+    bus {
         #address-cells = <2>;
         #size-cells = <2>;
 
-        ranges = <0x0 0x02c00000 0x02c00000 0x0 0xb0000>;
+        memory-controller@2c00000 {
+            compatible = "nvidia,tegra186-mc";
+            reg = <0x0 0x02c00000 0x0 0xb0000>;
+            interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>;
+
+            #address-cells = <2>;
+            #size-cells = <2>;
+
+            ranges = <0x0 0x02c00000 0x0 0x02c00000 0x0 0xb0000>;
 
-        /*
-         * Memory clients have access to all 40 bits that the memory
-         * controller can address.
-         */
-        dma-ranges = <0x0 0x0 0x0 0x0 0x100 0x0>;
+            /*
+             * Memory clients have access to all 40 bits that the memory
+             * controller can address.
+             */
+            dma-ranges = <0x0 0x0 0x0 0x0 0x100 0x0>;
 
-        external-memory-controller@2c60000 {
-            compatible = "nvidia,tegra186-emc";
-            reg = <0x0 0x02c60000 0x0 0x50000>;
-            interrupts = <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
-            clocks = <&bpmp TEGRA186_CLK_EMC>;
-            clock-names = "emc";
+            external-memory-controller@2c60000 {
+                compatible = "nvidia,tegra186-emc";
+                reg = <0x0 0x02c60000 0x0 0x50000>;
+                interrupts = <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
+                clocks = <&bpmp TEGRA186_CLK_EMC>;
+                clock-names = "emc";
 
-            nvidia,bpmp = <&bpmp>;
+                nvidia,bpmp = <&bpmp>;
+            };
         };
     };
 
diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra210-emc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra210-emc.yaml
new file mode 100644
index 000000000000..49ab09252e52
--- /dev/null
+++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra210-emc.yaml
@@ -0,0 +1,82 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/memory-controllers/nvidia,tegra210-emc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVIDIA Tegra210 SoC External Memory Controller
+
+maintainers:
+  - Thierry Reding <thierry.reding@gmail.com>
+  - Jon Hunter <jonathanh@nvidia.com>
+
+description: |
+  The EMC interfaces with the off-chip SDRAM to service the request stream
+  sent from the memory controller.
+
+properties:
+  compatible:
+    const: nvidia,tegra210-emc
+
+  reg:
+    maxItems: 3
+
+  clocks:
+    items:
+      - description: external memory clock
+
+  clock-names:
+    items:
+      - const: emc
+
+  interrupts:
+    items:
+      - description: EMC general interrupt
+
+  memory-region:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      phandle to a reserved memory region describing the table of EMC
+      frequencies trained by the firmware
+
+  nvidia,memory-controller:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      phandle of the memory controller node
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - nvidia,memory-controller
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/tegra210-car.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    reserved-memory {
+        #address-cells = <1>;
+        #size-cells = <1>;
+        ranges;
+
+        emc_table: emc-table@83400000 {
+            compatible = "nvidia,tegra210-emc-table";
+            reg = <0x83400000 0x10000>;
+        };
+    };
+
+    external-memory-controller@7001b000 {
+        compatible = "nvidia,tegra210-emc";
+        reg = <0x7001b000 0x1000>,
+              <0x7001e000 0x1000>,
+              <0x7001f000 0x1000>;
+        clocks = <&tegra_car TEGRA210_CLK_EMC>;
+        clock-names = "emc";
+        interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
+        memory-region = <&emc_table>;
+        nvidia,memory-controller = <&mc>;
+    };
diff --git a/Documentation/devicetree/bindings/mfd/rohm,bd71837-pmic.yaml b/Documentation/devicetree/bindings/mfd/rohm,bd71837-pmic.yaml
index aa922c560fcc..65018a019e1d 100644
--- a/Documentation/devicetree/bindings/mfd/rohm,bd71837-pmic.yaml
+++ b/Documentation/devicetree/bindings/mfd/rohm,bd71837-pmic.yaml
@@ -123,7 +123,9 @@ examples:
     #include <dt-bindings/leds/common.h>
 
     i2c {
-      pmic: pmic@4b {
+        #address-cells = <1>;
+        #size-cells = <0>;
+        pmic: pmic@4b {
             compatible = "rohm,bd71837";
             reg = <0x4b>;
             interrupt-parent = <&gpio1>;
diff --git a/Documentation/devicetree/bindings/mfd/rohm,bd71847-pmic.yaml b/Documentation/devicetree/bindings/mfd/rohm,bd71847-pmic.yaml
index 402e40dfe0b8..77bcca2d414f 100644
--- a/Documentation/devicetree/bindings/mfd/rohm,bd71847-pmic.yaml
+++ b/Documentation/devicetree/bindings/mfd/rohm,bd71847-pmic.yaml
@@ -128,7 +128,9 @@ examples:
     #include <dt-bindings/leds/common.h>
 
     i2c {
-      pmic: pmic@4b {
+        #address-cells = <1>;
+        #size-cells = <0>;
+        pmic: pmic@4b {
             compatible = "rohm,bd71847";
             reg = <0x4b>;
             interrupt-parent = <&gpio1>;
diff --git a/Documentation/devicetree/bindings/mfd/st,stm32-lptimer.yaml b/Documentation/devicetree/bindings/mfd/st,stm32-lptimer.yaml
index ddf190cb800b..e675611f80d0 100644
--- a/Documentation/devicetree/bindings/mfd/st,stm32-lptimer.yaml
+++ b/Documentation/devicetree/bindings/mfd/st,stm32-lptimer.yaml
@@ -66,8 +66,8 @@ patternProperties:
       reg:
         description: Identify trigger hardware block.
         items:
-         minimum: 0
-         maximum: 2
+          minimum: 0
+          maximum: 2
 
     required:
       - compatible
diff --git a/Documentation/devicetree/bindings/mfd/st,stm32-timers.yaml b/Documentation/devicetree/bindings/mfd/st,stm32-timers.yaml
index 590849ee9f32..4acda7ce3b44 100644
--- a/Documentation/devicetree/bindings/mfd/st,stm32-timers.yaml
+++ b/Documentation/devicetree/bindings/mfd/st,stm32-timers.yaml
@@ -102,8 +102,8 @@ patternProperties:
       reg:
         description: Identify trigger hardware block.
         items:
-         minimum: 0
-         maximum: 16
+          minimum: 0
+          maximum: 16
 
     required:
       - compatible
diff --git a/Documentation/devicetree/bindings/mfd/st,stpmic1.yaml b/Documentation/devicetree/bindings/mfd/st,stpmic1.yaml
index d9ad9260e348..f88d13d70441 100644
--- a/Documentation/devicetree/bindings/mfd/st,stpmic1.yaml
+++ b/Documentation/devicetree/bindings/mfd/st,stpmic1.yaml
@@ -274,7 +274,7 @@ examples:
   - |
     #include <dt-bindings/mfd/st,stpmic1.h>
     #include <dt-bindings/interrupt-controller/arm-gic.h>
-    i2c@0 {
+    i2c {
       #address-cells = <1>;
       #size-cells = <0>;
       pmic@33 {
diff --git a/Documentation/devicetree/bindings/mfd/syscon.yaml b/Documentation/devicetree/bindings/mfd/syscon.yaml
index 39375e4313d2..7a39486b215a 100644
--- a/Documentation/devicetree/bindings/mfd/syscon.yaml
+++ b/Documentation/devicetree/bindings/mfd/syscon.yaml
@@ -33,13 +33,13 @@ properties:
   compatible:
     anyOf:
       - items:
-        - enum:
-          - allwinner,sun8i-a83t-system-controller
-          - allwinner,sun8i-h3-system-controller
-          - allwinner,sun8i-v3s-system-controller
-          - allwinner,sun50i-a64-system-controller
+          - enum:
+              - allwinner,sun8i-a83t-system-controller
+              - allwinner,sun8i-h3-system-controller
+              - allwinner,sun8i-v3s-system-controller
+              - allwinner,sun50i-a64-system-controller
 
-        - const: syscon
+          - const: syscon
 
       - contains:
           const: syscon
diff --git a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt
index 428685eb2ded..630fe707f5c4 100644
--- a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt
+++ b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt
@@ -18,6 +18,9 @@ Required Properties:
     - "xlnx,zynqmp-8.9a": ZynqMP SDHCI 8.9a PHY
       For this device it is strongly suggested to include clock-output-names and
       #clock-cells.
+    - "xlnx,versal-8.9a": Versal SDHCI 8.9a PHY
+      For this device it is strongly suggested to include clock-output-names and
+      #clock-cells.
     - "ti,am654-sdhci-5.1", "arasan,sdhci-5.1": TI AM654 MMC PHY
 	Note: This binding has been deprecated and moved to [5].
     - "intel,lgm-sdhci-5.1-emmc", "arasan,sdhci-5.1": Intel LGM eMMC PHY
@@ -104,6 +107,18 @@ Example:
 		clk-phase-sd-hs = <63>, <72>;
 	};
 
+	sdhci: mmc@f1040000 {
+		compatible = "xlnx,versal-8.9a", "arasan,sdhci-8.9a";
+		interrupt-parent = <&gic>;
+		interrupts = <0 126 4>;
+		reg = <0x0 0xf1040000 0x0 0x10000>;
+		clocks = <&clk200>, <&clk200>;
+		clock-names = "clk_xin", "clk_ahb";
+		clock-output-names = "clk_out_sd0", "clk_in_sd0";
+		#clock-cells = <1>;
+		clk-phase-sd-hs = <132>, <60>;
+	};
+
 	emmc: sdhci@ec700000 {
 		compatible = "intel,lgm-sdhci-5.1-emmc", "arasan,sdhci-5.1";
 		reg = <0xec700000 0x300>;
diff --git a/Documentation/devicetree/bindings/mmc/cdns,sdhci.yaml b/Documentation/devicetree/bindings/mmc/cdns,sdhci.yaml
index 2f45dd0d04db..d43a0c557a44 100644
--- a/Documentation/devicetree/bindings/mmc/cdns,sdhci.yaml
+++ b/Documentation/devicetree/bindings/mmc/cdns,sdhci.yaml
@@ -17,7 +17,7 @@ properties:
   compatible:
     items:
       - enum:
-         - socionext,uniphier-sd4hc
+          - socionext,uniphier-sd4hc
       - const: cdns,sd4hc
 
   reg:
diff --git a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.yaml b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.yaml
index 89c3edd6a728..4ee3ed6efab4 100644
--- a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.yaml
+++ b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.yaml
@@ -30,21 +30,21 @@ properties:
       - items:
           - enum:
             # for Rockchip PX30
-            - rockchip,px30-dw-mshc
+              - rockchip,px30-dw-mshc
             # for Rockchip RK3036
-            - rockchip,rk3036-dw-mshc
+              - rockchip,rk3036-dw-mshc
             # for Rockchip RK322x
-            - rockchip,rk3228-dw-mshc
+              - rockchip,rk3228-dw-mshc
             # for Rockchip RK3308
-            - rockchip,rk3308-dw-mshc
+              - rockchip,rk3308-dw-mshc
             # for Rockchip RK3328
-            - rockchip,rk3328-dw-mshc
+              - rockchip,rk3328-dw-mshc
             # for Rockchip RK3368
-            - rockchip,rk3368-dw-mshc
+              - rockchip,rk3368-dw-mshc
             # for Rockchip RK3399
-            - rockchip,rk3399-dw-mshc
+              - rockchip,rk3399-dw-mshc
             # for Rockchip RV1108
-            - rockchip,rv1108-dw-mshc
+              - rockchip,rv1108-dw-mshc
           - const: rockchip,rk3288-dw-mshc
 
   reg:
diff --git a/Documentation/devicetree/bindings/mmc/socionext,uniphier-sd.yaml b/Documentation/devicetree/bindings/mmc/socionext,uniphier-sd.yaml
index cdfac9b4411b..8d6413f48823 100644
--- a/Documentation/devicetree/bindings/mmc/socionext,uniphier-sd.yaml
+++ b/Documentation/devicetree/bindings/mmc/socionext,uniphier-sd.yaml
@@ -35,15 +35,15 @@ properties:
     oneOf:
       - const: host
       - items:
-        - const: host
-        - const: bridge
+          - const: host
+          - const: bridge
       - items:
-        - const: host
-        - const: hw
+          - const: host
+          - const: hw
       - items:
-        - const: host
-        - const: bridge
-        - const: hw
+          - const: host
+          - const: bridge
+          - const: hw
 
   resets:
     minItems: 1
diff --git a/Documentation/devicetree/bindings/mtd/denali,nand.yaml b/Documentation/devicetree/bindings/mtd/denali,nand.yaml
index 46e6b6726bc0..c07b91592cbd 100644
--- a/Documentation/devicetree/bindings/mtd/denali,nand.yaml
+++ b/Documentation/devicetree/bindings/mtd/denali,nand.yaml
@@ -54,8 +54,8 @@ properties:
         reg:  register reset
     oneOf:
       - items:
-        - const: nand
-        - const: reg
+          - const: nand
+          - const: reg
       - const: nand
       - const: reg
 
diff --git a/Documentation/devicetree/bindings/net/allwinner,sun8i-a83t-emac.yaml b/Documentation/devicetree/bindings/net/allwinner,sun8i-a83t-emac.yaml
index db36b4d86484..c7c9ad4e3f9f 100644
--- a/Documentation/devicetree/bindings/net/allwinner,sun8i-a83t-emac.yaml
+++ b/Documentation/devicetree/bindings/net/allwinner,sun8i-a83t-emac.yaml
@@ -19,8 +19,8 @@ properties:
       - const: allwinner,sun8i-v3s-emac
       - const: allwinner,sun50i-a64-emac
       - items:
-        - const: allwinner,sun50i-h6-emac
-        - const: allwinner,sun50i-a64-emac
+          - const: allwinner,sun50i-h6-emac
+          - const: allwinner,sun50i-a64-emac
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/net/can/bosch,m_can.yaml b/Documentation/devicetree/bindings/net/can/bosch,m_can.yaml
index cccf8202c8f7..7a784dc4e513 100644
--- a/Documentation/devicetree/bindings/net/can/bosch,m_can.yaml
+++ b/Documentation/devicetree/bindings/net/can/bosch,m_can.yaml
@@ -9,7 +9,7 @@ title: Bosch MCAN controller Bindings
 description: Bosch MCAN controller for CAN bus
 
 maintainers:
-  -  Sriram Dash <sriram.dash@samsung.com>
+  - Sriram Dash <sriram.dash@samsung.com>
 
 properties:
   compatible:
@@ -51,31 +51,31 @@ properties:
 
   bosch,mram-cfg:
     description: |
-                 Message RAM configuration data.
-                 Multiple M_CAN instances can share the same Message RAM
-                 and each element(e.g Rx FIFO or Tx Buffer and etc) number
-                 in Message RAM is also configurable, so this property is
-                 telling driver how the shared or private Message RAM are
-                 used by this M_CAN controller.
-
-                 The format should be as follows:
-                 <offset sidf_elems xidf_elems rxf0_elems rxf1_elems rxb_elems txe_elems txb_elems>
-                 The 'offset' is an address offset of the Message RAM where
-                 the following elements start from. This is usually set to
-                 0x0 if you're using a private Message RAM. The remain cells
-                 are used to specify how many elements are used for each FIFO/Buffer.
-
-                 M_CAN includes the following elements according to user manual:
-                 11-bit Filter	0-128 elements / 0-128 words
-                 29-bit Filter	0-64 elements / 0-128 words
-                 Rx FIFO 0	0-64 elements / 0-1152 words
-                 Rx FIFO 1	0-64 elements / 0-1152 words
-                 Rx Buffers	0-64 elements / 0-1152 words
-                 Tx Event FIFO	0-32 elements / 0-64 words
-                 Tx Buffers	0-32 elements / 0-576 words
-
-                 Please refer to 2.4.1 Message RAM Configuration in Bosch
-                 M_CAN user manual for details.
+      Message RAM configuration data.
+      Multiple M_CAN instances can share the same Message RAM
+      and each element(e.g Rx FIFO or Tx Buffer and etc) number
+      in Message RAM is also configurable, so this property is
+      telling driver how the shared or private Message RAM are
+      used by this M_CAN controller.
+
+      The format should be as follows:
+      <offset sidf_elems xidf_elems rxf0_elems rxf1_elems rxb_elems txe_elems txb_elems>
+      The 'offset' is an address offset of the Message RAM where
+      the following elements start from. This is usually set to
+      0x0 if you're using a private Message RAM. The remain cells
+      are used to specify how many elements are used for each FIFO/Buffer.
+
+      M_CAN includes the following elements according to user manual:
+      11-bit Filter	0-128 elements / 0-128 words
+      29-bit Filter	0-64 elements / 0-128 words
+      Rx FIFO 0	0-64 elements / 0-1152 words
+      Rx FIFO 1	0-64 elements / 0-1152 words
+      Rx Buffers	0-64 elements / 0-1152 words
+      Tx Event FIFO	0-32 elements / 0-64 words
+      Tx Buffers	0-32 elements / 0-576 words
+
+      Please refer to 2.4.1 Message RAM Configuration in Bosch
+      M_CAN user manual for details.
     allOf:
       - $ref: /schemas/types.yaml#/definitions/int32-array
       - items:
diff --git a/Documentation/devicetree/bindings/net/ethernet-phy.yaml b/Documentation/devicetree/bindings/net/ethernet-phy.yaml
index 8927941c74bb..5aa141ccc113 100644
--- a/Documentation/devicetree/bindings/net/ethernet-phy.yaml
+++ b/Documentation/devicetree/bindings/net/ethernet-phy.yaml
@@ -43,6 +43,9 @@ properties:
           second group of digits is the Phy Identifier 2 register,
           this is the chip vendor OUI bits 19:24, followed by 10
           bits of a vendor specific ID.
+      - items:
+          - pattern: "^ethernet-phy-id[a-f0-9]{4}\\.[a-f0-9]{4}$"
+          - const: ethernet-phy-ieee802.3-c22
       - items:
           - pattern: "^ethernet-phy-id[a-f0-9]{4}\\.[a-f0-9]{4}$"
           - const: ethernet-phy-ieee802.3-c45
diff --git a/Documentation/devicetree/bindings/net/fsl-fec.txt b/Documentation/devicetree/bindings/net/fsl-fec.txt
index 5b88fae0307d..ff8b0f211aa1 100644
--- a/Documentation/devicetree/bindings/net/fsl-fec.txt
+++ b/Documentation/devicetree/bindings/net/fsl-fec.txt
@@ -22,6 +22,8 @@ Optional properties:
 - fsl,err006687-workaround-present: If present indicates that the system has
   the hardware workaround for ERR006687 applied and does not need a software
   workaround.
+- gpr: phandle of SoC general purpose register mode. Required for wake on LAN
+  on some SoCs
  -interrupt-names:  names of the interrupts listed in interrupts property in
   the same order. The defaults if not specified are
   __Number of interrupts__   __Default__
diff --git a/Documentation/devicetree/bindings/net/qcom,ipq8064-mdio.yaml b/Documentation/devicetree/bindings/net/qcom,ipq8064-mdio.yaml
index b9f90081046f..67df3fe861ee 100644
--- a/Documentation/devicetree/bindings/net/qcom,ipq8064-mdio.yaml
+++ b/Documentation/devicetree/bindings/net/qcom,ipq8064-mdio.yaml
@@ -48,6 +48,7 @@ examples:
 
         switch@10 {
             compatible = "qca,qca8337";
+            reg = <0x10>;
             /* ... */
         };
     };
diff --git a/Documentation/devicetree/bindings/net/qualcomm-bluetooth.txt b/Documentation/devicetree/bindings/net/qualcomm-bluetooth.txt
index beca6466d59a..aad2632c6443 100644
--- a/Documentation/devicetree/bindings/net/qualcomm-bluetooth.txt
+++ b/Documentation/devicetree/bindings/net/qualcomm-bluetooth.txt
@@ -13,6 +13,7 @@ Required properties:
    * "qcom,wcn3990-bt"
    * "qcom,wcn3991-bt"
    * "qcom,wcn3998-bt"
+   * "qcom,qca6390-bt"
 
 Optional properties for compatible string qcom,qca6174-bt:
 
@@ -29,7 +30,7 @@ Required properties for compatible string qcom,wcn399x-bt:
 
 Optional properties for compatible string qcom,wcn399x-bt:
 
- - max-speed: see Documentation/devicetree/bindings/serial/slave-device.txt
+ - max-speed: see Documentation/devicetree/bindings/serial/serial.yaml
  - firmware-name: specify the name of nvm firmware to load
  - clocks: clock provided to the controller
 
diff --git a/Documentation/devicetree/bindings/net/renesas,ether.yaml b/Documentation/devicetree/bindings/net/renesas,ether.yaml
index 7f84df9790e2..2eaa8799e002 100644
--- a/Documentation/devicetree/bindings/net/renesas,ether.yaml
+++ b/Documentation/devicetree/bindings/net/renesas,ether.yaml
@@ -40,8 +40,8 @@ properties:
 
   reg:
     items:
-       - description: E-DMAC/feLic registers
-       - description: TSU registers
+      - description: E-DMAC/feLic registers
+      - description: TSU registers
     minItems: 1
 
   interrupts:
diff --git a/Documentation/devicetree/bindings/net/snps,dwmac.yaml b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
index e08cd4c4d568..439115b7663c 100644
--- a/Documentation/devicetree/bindings/net/snps,dwmac.yaml
+++ b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
@@ -27,6 +27,7 @@ select:
           - snps,dwmac-3.710
           - snps,dwmac-4.00
           - snps,dwmac-4.10a
+          - snps,dwmac-4.20a
           - snps,dwxgmac
           - snps,dwxgmac-2.10
 
@@ -62,6 +63,7 @@ properties:
         - snps,dwmac-3.710
         - snps,dwmac-4.00
         - snps,dwmac-4.10a
+        - snps,dwmac-4.20a
         - snps,dwxgmac
         - snps,dwxgmac-2.10
 
@@ -87,7 +89,8 @@ properties:
 
   clocks:
     minItems: 1
-    maxItems: 3
+    maxItems: 5
+    additionalItems: true
     items:
       - description: GMAC main clock
       - description: Peripheral registers interface clock
@@ -97,6 +100,8 @@ properties:
           clock will be used and this is fine on some platforms.
 
   clock-names:
+    minItems: 1
+    maxItems: 5
     additionalItems: true
     contains:
       enum:
@@ -342,6 +347,7 @@ allOf:
               - allwinner,sun50i-a64-emac
               - snps,dwmac-4.00
               - snps,dwmac-4.10a
+              - snps,dwmac-4.20a
               - snps,dwxgmac
               - snps,dwxgmac-2.10
               - st,spear600-gmac
diff --git a/Documentation/devicetree/bindings/net/stm32-dwmac.txt b/Documentation/devicetree/bindings/net/stm32-dwmac.txt
deleted file mode 100644
index a90eef11dc46..000000000000
--- a/Documentation/devicetree/bindings/net/stm32-dwmac.txt
+++ /dev/null
@@ -1,44 +0,0 @@
-STMicroelectronics STM32 / MCU DWMAC glue layer controller
-
-This file documents platform glue layer for stmmac.
-Please see stmmac.txt for the other unchanged properties.
-
-The device node has following properties.
-
-Required properties:
-- compatible:  For MCU family should be "st,stm32-dwmac" to select glue, and
-	       "snps,dwmac-3.50a" to select IP version.
-	       For MPU family should be "st,stm32mp1-dwmac" to select
-	       glue, and "snps,dwmac-4.20a" to select IP version.
-- clocks: Must contain a phandle for each entry in clock-names.
-- clock-names: Should be "stmmaceth" for the host clock.
-	       Should be "mac-clk-tx" for the MAC TX clock.
-	       Should be "mac-clk-rx" for the MAC RX clock.
-	       For MPU family need to add also "ethstp" for power mode clock
-- interrupt-names: Should contain a list of interrupt names corresponding to
-           the interrupts in the interrupts property, if available.
-		   Should be "macirq" for the main MAC IRQ
-		   Should be "eth_wake_irq" for the IT which wake up system
-- st,syscon : Should be phandle/offset pair. The phandle to the syscon node which
-	       encompases the glue register, and the offset of the control register.
-
-Optional properties:
-- clock-names:     For MPU family "eth-ck" for PHY without quartz
-- st,eth-clk-sel (boolean) : set this property in RGMII PHY when you want to select RCC clock instead of ETH_CLK125.
-- st,eth-ref-clk-sel (boolean) :  set this property in RMII mode when you have PHY without crystal 50MHz and want to select RCC clock instead of ETH_REF_CLK.
-
-Example:
-
-	ethernet@40028000 {
-		compatible = "st,stm32-dwmac", "snps,dwmac-3.50a";
-		reg = <0x40028000 0x8000>;
-		reg-names = "stmmaceth";
-		interrupts = <0 61 0>, <0 62 0>;
-		interrupt-names = "macirq", "eth_wake_irq";
-		clock-names = "stmmaceth", "mac-clk-tx", "mac-clk-rx";
-		clocks = <&rcc 0 25>, <&rcc 0 26>, <&rcc 0 27>;
-		st,syscon = <&syscfg 0x4>;
-		snps,pbl = <8>;
-		snps,mixed-burst;
-		dma-ranges;
-	};
diff --git a/Documentation/devicetree/bindings/net/stm32-dwmac.yaml b/Documentation/devicetree/bindings/net/stm32-dwmac.yaml
new file mode 100644
index 000000000000..2207910ee79b
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/stm32-dwmac.yaml
@@ -0,0 +1,149 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright 2019 BayLibre, SAS
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/net/stm32-dwmac.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: STMicroelectronics STM32 / MCU DWMAC glue layer controller
+
+maintainers:
+  - Alexandre Torgue <alexandre.torgue@st.com>
+  - Christophe Roullier <christophe.roullier@st.com>
+
+description:
+  This file documents platform glue layer for stmmac.
+
+# We need a select here so we don't match all nodes with 'snps,dwmac'
+select:
+  properties:
+    compatible:
+      contains:
+        enum:
+          - st,stm32-dwmac
+          - st,stm32mp1-dwmac
+  required:
+    - compatible
+
+allOf:
+  - $ref: "snps,dwmac.yaml#"
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - st,stm32mp1-dwmac
+          - const: snps,dwmac-4.20a
+      - items:
+          - enum:
+              - st,stm32-dwmac
+          - const: snps,dwmac-4.10a
+      - items:
+          - enum:
+              - st,stm32-dwmac
+          - const: snps,dwmac-3.50a
+
+  clocks:
+    minItems: 3
+    maxItems: 5
+    items:
+        - description: GMAC main clock
+        - description: MAC TX clock
+        - description: MAC RX clock
+        - description: For MPU family, used for power mode
+        - description: For MPU family, used for PHY without quartz
+
+  clock-names:
+    minItems: 3
+    maxItems: 5
+    contains:
+      enum:
+        - stmmaceth
+        - mac-clk-tx
+        - mac-clk-rx
+        - ethstp
+        - eth-ck
+
+  st,syscon:
+    allOf:
+      - $ref: "/schemas/types.yaml#/definitions/phandle-array"
+    description:
+      Should be phandle/offset pair. The phandle to the syscon node which
+      encompases the glue register, and the offset of the control register
+
+  st,eth-clk-sel:
+    description:
+      set this property in RGMII PHY when you want to select RCC clock instead of ETH_CLK125.
+    type: boolean
+
+  st,eth-ref-clk-sel:
+    description:
+      set this property in RMII mode when you have PHY without crystal 50MHz and want to
+      select RCC clock instead of ETH_REF_CLK.
+    type: boolean
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+  - st,syscon
+
+examples:
+ - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/stm32mp1-clks.h>
+    #include <dt-bindings/reset/stm32mp1-resets.h>
+    #include <dt-bindings/mfd/stm32h7-rcc.h>
+    //Example 1
+     ethernet0: ethernet@5800a000 {
+           compatible = "st,stm32mp1-dwmac", "snps,dwmac-4.20a";
+           reg = <0x5800a000 0x2000>;
+           reg-names = "stmmaceth";
+           interrupts = <&intc GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+           interrupt-names = "macirq";
+           clock-names = "stmmaceth",
+                     "mac-clk-tx",
+                     "mac-clk-rx",
+                     "ethstp",
+                     "eth-ck";
+           clocks = <&rcc ETHMAC>,
+                <&rcc ETHTX>,
+                <&rcc ETHRX>,
+                <&rcc ETHSTP>,
+                <&rcc ETHCK_K>;
+           st,syscon = <&syscfg 0x4>;
+           snps,pbl = <2>;
+           snps,axi-config = <&stmmac_axi_config_0>;
+           snps,tso;
+           phy-mode = "rgmii";
+       };
+
+    //Example 2 (MCU example)
+     ethernet1: ethernet@40028000 {
+           compatible = "st,stm32-dwmac", "snps,dwmac-3.50a";
+           reg = <0x40028000 0x8000>;
+           reg-names = "stmmaceth";
+           interrupts = <0 61 0>, <0 62 0>;
+           interrupt-names = "macirq", "eth_wake_irq";
+           clock-names = "stmmaceth", "mac-clk-tx", "mac-clk-rx";
+           clocks = <&rcc 0 25>, <&rcc 0 26>, <&rcc 0 27>;
+           st,syscon = <&syscfg 0x4>;
+           snps,pbl = <8>;
+           snps,mixed-burst;
+           phy-mode = "mii";
+       };
+
+    //Example 3
+     ethernet2: ethernet@40027000 {
+           compatible = "st,stm32-dwmac", "snps,dwmac-4.10a";
+           reg = <0x40028000 0x8000>;
+           reg-names = "stmmaceth";
+           interrupts = <61>;
+           interrupt-names = "macirq";
+           clock-names = "stmmaceth", "mac-clk-tx", "mac-clk-rx";
+           clocks = <&rcc 62>, <&rcc 61>, <&rcc 60>;
+           st,syscon = <&syscfg 0x4>;
+           snps,pbl = <8>;
+           phy-mode = "mii";
+       };
diff --git a/Documentation/devicetree/bindings/net/ti,cpsw-switch.yaml b/Documentation/devicetree/bindings/net/ti,cpsw-switch.yaml
index 976f139bb66e..8fc8d3be303b 100644
--- a/Documentation/devicetree/bindings/net/ti,cpsw-switch.yaml
+++ b/Documentation/devicetree/bindings/net/ti,cpsw-switch.yaml
@@ -23,14 +23,14 @@ properties:
     oneOf:
       - const: ti,cpsw-switch
       - items:
-         - const: ti,am335x-cpsw-switch
-         - const: ti,cpsw-switch
+          - const: ti,am335x-cpsw-switch
+          - const: ti,cpsw-switch
       - items:
-        - const: ti,am4372-cpsw-switch
-        - const: ti,cpsw-switch
+          - const: ti,am4372-cpsw-switch
+          - const: ti,cpsw-switch
       - items:
-        - const: ti,dra7-cpsw-switch
-        - const: ti,cpsw-switch
+          - const: ti,dra7-cpsw-switch
+          - const: ti,cpsw-switch
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/net/ti,davinci-mdio.yaml b/Documentation/devicetree/bindings/net/ti,davinci-mdio.yaml
index 242ac4935a4b..2ea14ab29254 100644
--- a/Documentation/devicetree/bindings/net/ti,davinci-mdio.yaml
+++ b/Documentation/devicetree/bindings/net/ti,davinci-mdio.yaml
@@ -18,25 +18,24 @@ allOf:
 properties:
   compatible:
     oneOf:
-       - const: ti,davinci_mdio
-       - items:
-         - const: ti,keystone_mdio
-         - const: ti,davinci_mdio
-       - items:
-         - const: ti,cpsw-mdio
-         - const: ti,davinci_mdio
-       - items:
-         - const: ti,am4372-mdio
-         - const: ti,cpsw-mdio
-         - const: ti,davinci_mdio
+      - const: ti,davinci_mdio
+      - items:
+          - const: ti,keystone_mdio
+          - const: ti,davinci_mdio
+      - items:
+          - const: ti,cpsw-mdio
+          - const: ti,davinci_mdio
+      - items:
+          - const: ti,am4372-mdio
+          - const: ti,cpsw-mdio
+          - const: ti,davinci_mdio
 
   reg:
     maxItems: 1
 
   bus_freq:
-      maximum: 2500000
-      description:
-        MDIO Bus frequency
+    maximum: 2500000
+    description: MDIO Bus frequency
 
   ti,hwmods:
     description: TI hwmod name
diff --git a/Documentation/devicetree/bindings/phy/intel,lgm-emmc-phy.yaml b/Documentation/devicetree/bindings/phy/intel,lgm-emmc-phy.yaml
index 9a346d6290d9..77bb5309918e 100644
--- a/Documentation/devicetree/bindings/phy/intel,lgm-emmc-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/intel,lgm-emmc-phy.yaml
@@ -23,7 +23,7 @@ description: |+
 
 properties:
   compatible:
-      const: intel,lgm-emmc-phy
+    const: intel,lgm-emmc-phy
 
   "#phy-cells":
     const: 0
diff --git a/Documentation/devicetree/bindings/phy/ti,phy-j721e-wiz.yaml b/Documentation/devicetree/bindings/phy/ti,phy-j721e-wiz.yaml
index fd1982c56104..3f913d6d1c3d 100644
--- a/Documentation/devicetree/bindings/phy/ti,phy-j721e-wiz.yaml
+++ b/Documentation/devicetree/bindings/phy/ti,phy-j721e-wiz.yaml
@@ -146,7 +146,7 @@ patternProperties:
       bindings specified in
       Documentation/devicetree/bindings/phy/phy-cadence-sierra.txt
       Torrent SERDES should follow the bindings specified in
-      Documentation/devicetree/bindings/phy/phy-cadence-dp.txt
+      Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml
 
 required:
   - compatible
diff --git a/Documentation/devicetree/bindings/pwm/google,cros-ec-pwm.yaml b/Documentation/devicetree/bindings/pwm/google,cros-ec-pwm.yaml
index 24c217b76580..41ece1d85315 100644
--- a/Documentation/devicetree/bindings/pwm/google,cros-ec-pwm.yaml
+++ b/Documentation/devicetree/bindings/pwm/google,cros-ec-pwm.yaml
@@ -31,10 +31,17 @@ additionalProperties: false
 
 examples:
   - |
-    cros-ec@0 {
-        compatible = "google,cros-ec-spi";
-        cros_ec_pwm: ec-pwm {
-            compatible = "google,cros-ec-pwm";
-            #pwm-cells = <1>;
+    spi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        cros-ec@0 {
+            compatible = "google,cros-ec-spi";
+            reg = <0>;
+
+            cros_ec_pwm: ec-pwm {
+                compatible = "google,cros-ec-pwm";
+                #pwm-cells = <1>;
+            };
         };
     };
diff --git a/Documentation/devicetree/bindings/pwm/pwm-samsung.yaml b/Documentation/devicetree/bindings/pwm/pwm-samsung.yaml
index ea7f32905172..4fe64f4dd594 100644
--- a/Documentation/devicetree/bindings/pwm/pwm-samsung.yaml
+++ b/Documentation/devicetree/bindings/pwm/pwm-samsung.yaml
@@ -49,17 +49,17 @@ properties:
       are available.
     oneOf:
       - items:
-        - const: timers
+          - const: timers
       - items:
-        - const: timers
-        - const: pwm-tclk0
+          - const: timers
+          - const: pwm-tclk0
       - items:
-        - const: timers
-        - const: pwm-tclk1
+          - const: timers
+          - const: pwm-tclk1
       - items:
-        - const: timers
-        - const: pwm-tclk0
-        - const: pwm-tclk1
+          - const: timers
+          - const: pwm-tclk0
+          - const: pwm-tclk1
 
   interrupts:
     description:
diff --git a/Documentation/devicetree/bindings/pwm/renesas,pwm-rcar.yaml b/Documentation/devicetree/bindings/pwm/renesas,pwm-rcar.yaml
index 945c14e1be35..620a2ff40fc7 100644
--- a/Documentation/devicetree/bindings/pwm/renesas,pwm-rcar.yaml
+++ b/Documentation/devicetree/bindings/pwm/renesas,pwm-rcar.yaml
@@ -27,6 +27,7 @@ properties:
           - renesas,pwm-r8a7794   # R-Car E2
           - renesas,pwm-r8a7795   # R-Car H3
           - renesas,pwm-r8a7796   # R-Car M3-W
+          - renesas,pwm-r8a77961  # R-Car M3-W+
           - renesas,pwm-r8a77965  # R-Car M3-N
           - renesas,pwm-r8a77970  # R-Car V3M
           - renesas,pwm-r8a77980  # R-Car V3H
diff --git a/Documentation/devicetree/bindings/remoteproc/st,stm32-rproc.yaml b/Documentation/devicetree/bindings/remoteproc/st,stm32-rproc.yaml
index c0d83865e933..4ff4d3df0a06 100644
--- a/Documentation/devicetree/bindings/remoteproc/st,stm32-rproc.yaml
+++ b/Documentation/devicetree/bindings/remoteproc/st,stm32-rproc.yaml
@@ -25,7 +25,7 @@ properties:
     maxItems: 3
 
   resets:
-     maxItems: 1
+    maxItems: 1
 
   st,syscfg-holdboot:
     allOf:
diff --git a/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
index bac4afa3b197..4dd20de6977f 100644
--- a/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
+++ b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
@@ -77,6 +77,8 @@ Regions in the /reserved-memory node may be referenced by other device
 nodes by adding a memory-region property to the device node.
 
 memory-region (optional) - phandle, specifier pairs to children of /reserved-memory
+memory-region-names (optional) - a list of names, one for each corresponding
+  entry in the memory-region property
 
 Example
 -------
diff --git a/Documentation/devicetree/bindings/reset/brcm,bcm7216-pcie-sata-rescal.yaml b/Documentation/devicetree/bindings/reset/brcm,bcm7216-pcie-sata-rescal.yaml
index 512a33bdb208..dfce6738b033 100644
--- a/Documentation/devicetree/bindings/reset/brcm,bcm7216-pcie-sata-rescal.yaml
+++ b/Documentation/devicetree/bindings/reset/brcm,bcm7216-pcie-sata-rescal.yaml
@@ -7,7 +7,9 @@ $schema: "http://devicetree.org/meta-schemas/core.yaml#"
 
 title: BCM7216 RESCAL reset controller
 
-description: This document describes the BCM7216 RESCAL reset controller which is responsible for controlling the reset of the SATA and PCIe0/1 instances on BCM7216.
+description: This document describes the BCM7216 RESCAL reset controller
+  which is responsible for controlling the reset of the SATA and PCIe0/1
+  instances on BCM7216.
 
 maintainers:
   - Florian Fainelli <f.fainelli@gmail.com>
diff --git a/Documentation/devicetree/bindings/reset/fsl,imx7-src.txt b/Documentation/devicetree/bindings/reset/fsl,imx7-src.txt
index c2489e41a801..e10502d9153e 100644
--- a/Documentation/devicetree/bindings/reset/fsl,imx7-src.txt
+++ b/Documentation/devicetree/bindings/reset/fsl,imx7-src.txt
@@ -9,6 +9,8 @@ Required properties:
 	- For i.MX7 SoCs should be "fsl,imx7d-src", "syscon"
 	- For i.MX8MQ SoCs should be "fsl,imx8mq-src", "syscon"
 	- For i.MX8MM SoCs should be "fsl,imx8mm-src", "fsl,imx8mq-src", "syscon"
+	- For i.MX8MN SoCs should be "fsl,imx8mn-src", "fsl,imx8mq-src", "syscon"
+	- For i.MX8MP SoCs should be "fsl,imx8mp-src", "syscon"
 - reg: should be register base and length as documented in the
   datasheet
 - interrupts: Should contain SRC interrupt
@@ -49,4 +51,6 @@ Example:
 For list of all valid reset indices see
 <dt-bindings/reset/imx7-reset.h> for i.MX7,
 <dt-bindings/reset/imx8mq-reset.h> for i.MX8MQ and
-<dt-bindings/reset/imx8mq-reset.h> for i.MX8MM
+<dt-bindings/reset/imx8mq-reset.h> for i.MX8MM and
+<dt-bindings/reset/imx8mq-reset.h> for i.MX8MN and
+<dt-bindings/reset/imx8mp-reset.h> for i.MX8MP
diff --git a/Documentation/devicetree/bindings/rng/arm-cctrng.yaml b/Documentation/devicetree/bindings/rng/arm-cctrng.yaml
new file mode 100644
index 000000000000..ca6aad19b6ba
--- /dev/null
+++ b/Documentation/devicetree/bindings/rng/arm-cctrng.yaml
@@ -0,0 +1,54 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/rng/arm-cctrng.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Arm TrustZone CryptoCell TRNG engine
+
+maintainers:
+  - Hadar Gat <hadar.gat@arm.com>
+
+description: |+
+  Arm TrustZone CryptoCell TRNG (True Random Number Generator) engine.
+
+properties:
+  compatible:
+    enum:
+      - arm,cryptocell-713-trng
+      - arm,cryptocell-703-trng
+
+  interrupts:
+    maxItems: 1
+
+  reg:
+    maxItems: 1
+
+  arm,rosc-ratio:
+    description:
+      Arm TrustZone CryptoCell TRNG engine has 4 ring oscillators.
+      Sampling ratio values for these 4 ring oscillators. (from calibration)
+    allOf:
+      - $ref: /schemas/types.yaml#/definitions/uint32-array
+      - items:
+          maxItems: 4
+
+  clocks:
+    maxItems: 1
+
+required:
+  - compatible
+  - interrupts
+  - reg
+  - arm,rosc-ratio
+
+additionalProperties: false
+
+examples:
+  - |
+    arm_cctrng: rng@60000000 {
+        compatible = "arm,cryptocell-713-trng";
+        interrupts = <0 29 4>;
+        reg = <0x60000000 0x10000>;
+        arm,rosc-ratio = <5000 1000 500 0>;
+    };
diff --git a/Documentation/devicetree/bindings/rng/brcm,bcm2835.yaml b/Documentation/devicetree/bindings/rng/brcm,bcm2835.yaml
index 89ab67f20a7f..c147900f9041 100644
--- a/Documentation/devicetree/bindings/rng/brcm,bcm2835.yaml
+++ b/Documentation/devicetree/bindings/rng/brcm,bcm2835.yaml
@@ -39,7 +39,7 @@ additionalProperties: false
 
 examples:
   - |
-    rng {
+    rng@7e104000 {
         compatible = "brcm,bcm2835-rng";
         reg = <0x7e104000 0x10>;
         interrupts = <2 29>;
diff --git a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.yaml b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.yaml
index 48c6cafca90c..57b087574aa1 100644
--- a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.yaml
+++ b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.yaml
@@ -38,10 +38,10 @@ properties:
           minItems: 3
           maxItems: 3
     description: |
-       Phandle/offset/mask triplet. The phandle to pwrcfg used to
-       access control register at offset, and change the dbp (Disable Backup
-       Protection) bit represented by the mask, mandatory to disable/enable backup
-       domain (RTC registers) write protection.
+      Phandle/offset/mask triplet. The phandle to pwrcfg used to
+      access control register at offset, and change the dbp (Disable Backup
+      Protection) bit represented by the mask, mandatory to disable/enable backup
+      domain (RTC registers) write protection.
 
   assigned-clocks:
     description: |
@@ -78,14 +78,14 @@ allOf:
             const: st,stm32h7-rtc
 
     then:
-       properties:
-         clocks:
-           minItems: 2
-           maxItems: 2
+      properties:
+        clocks:
+          minItems: 2
+          maxItems: 2
 
-       required:
-         - clock-names
-         - st,syscfg
+      required:
+        - clock-names
+        - st,syscfg
 
   - if:
       properties:
@@ -94,16 +94,16 @@ allOf:
             const: st,stm32mp1-rtc
 
     then:
-       properties:
-         clocks:
-           minItems: 2
-           maxItems: 2
+      properties:
+        clocks:
+          minItems: 2
+          maxItems: 2
 
-         assigned-clocks: false
-         assigned-clock-parents: false
+        assigned-clocks: false
+        assigned-clock-parents: false
 
-       required:
-         - clock-names
+      required:
+        - clock-names
 
 required:
   - compatible
diff --git a/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml b/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml
index d4178ab0d675..75ebc9952a99 100644
--- a/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml
+++ b/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml
@@ -24,18 +24,18 @@ properties:
     oneOf:
       - description: Always-on power domain UART controller
         items:
-        - enum:
+          - enum:
+              - amlogic,meson6-uart
+              - amlogic,meson8-uart
+              - amlogic,meson8b-uart
+              - amlogic,meson-gx-uart
+          - const: amlogic,meson-ao-uart
+      - description: Everything-Else power domain UART controller
+        enum:
           - amlogic,meson6-uart
           - amlogic,meson8-uart
           - amlogic,meson8b-uart
           - amlogic,meson-gx-uart
-        - const: amlogic,meson-ao-uart
-      - description: Everything-Else power domain UART controller
-        enum:
-        - amlogic,meson6-uart
-        - amlogic,meson8-uart
-        - amlogic,meson8b-uart
-        - amlogic,meson-gx-uart
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/serial/rs485.yaml b/Documentation/devicetree/bindings/serial/rs485.yaml
index d4beaf11222d..2b8261ea6d9c 100644
--- a/Documentation/devicetree/bindings/serial/rs485.yaml
+++ b/Documentation/devicetree/bindings/serial/rs485.yaml
@@ -6,13 +6,12 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
 
 title: RS485 serial communications Bindings
 
-description: The RTS signal is capable of automatically controlling
-             line direction for the built-in half-duplex mode.
-             The properties described hereafter shall be given to a
-             half-duplex capable UART node.
+description: The RTS signal is capable of automatically controlling line
+  direction for the built-in half-duplex mode. The properties described
+  hereafter shall be given to a half-duplex capable UART node.
 
 maintainers:
-  -  Rob Herring <robh@kernel.org>
+  - Rob Herring <robh@kernel.org>
 
 properties:
   rs485-rts-delay:
@@ -37,9 +36,11 @@ properties:
     $ref: /schemas/types.yaml#/definitions/flag
 
   linux,rs485-enabled-at-boot-time:
-    description: enables the rs485 feature at boot time. It can be disabled later with proper ioctl.
+    description: enables the rs485 feature at boot time. It can be disabled
+      later with proper ioctl.
     $ref: /schemas/types.yaml#/definitions/flag
 
   rs485-rx-during-tx:
-   description: enables the receiving of data even while sending data.
-   $ref: /schemas/types.yaml#/definitions/flag
+    description: enables the receiving of data even while sending data.
+    $ref: /schemas/types.yaml#/definitions/flag
+...
diff --git a/Documentation/devicetree/bindings/soc/amlogic/amlogic,canvas.yaml b/Documentation/devicetree/bindings/soc/amlogic/amlogic,canvas.yaml
index cb008fd188d8..02b2d5ba01d6 100644
--- a/Documentation/devicetree/bindings/soc/amlogic/amlogic,canvas.yaml
+++ b/Documentation/devicetree/bindings/soc/amlogic/amlogic,canvas.yaml
@@ -26,11 +26,11 @@ properties:
   compatible:
     oneOf:
       - items:
-        - enum:
-          - amlogic,meson8-canvas
-          - amlogic,meson8b-canvas
-          - amlogic,meson8m2-canvas
-        - const: amlogic,canvas
+          - enum:
+              - amlogic,meson8-canvas
+              - amlogic,meson8b-canvas
+              - amlogic,meson8m2-canvas
+          - const: amlogic,canvas
       - const: amlogic,canvas # GXBB and newer SoCs
 
   reg:
diff --git a/Documentation/devicetree/bindings/sound/renesas,fsi.yaml b/Documentation/devicetree/bindings/sound/renesas,fsi.yaml
index d1b65554e681..91cf4176abd5 100644
--- a/Documentation/devicetree/bindings/sound/renesas,fsi.yaml
+++ b/Documentation/devicetree/bindings/sound/renesas,fsi.yaml
@@ -17,16 +17,16 @@ properties:
     oneOf:
       # for FSI2 SoC
       - items:
-        - enum:
-          - renesas,fsi2-sh73a0
-          - renesas,fsi2-r8a7740
-        - enum:
-          - renesas,sh_fsi2
+          - enum:
+              - renesas,fsi2-sh73a0
+              - renesas,fsi2-r8a7740
+          - enum:
+              - renesas,sh_fsi2
       # for Generic
       - items:
-        - enum:
-          - renesas,sh_fsi
-          - renesas,sh_fsi2
+          - enum:
+              - renesas,sh_fsi
+              - renesas,sh_fsi2
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/sound/rockchip-i2s.yaml b/Documentation/devicetree/bindings/sound/rockchip-i2s.yaml
index 7cd0e278ed85..a3ba2186d6a1 100644
--- a/Documentation/devicetree/bindings/sound/rockchip-i2s.yaml
+++ b/Documentation/devicetree/bindings/sound/rockchip-i2s.yaml
@@ -56,6 +56,9 @@ properties:
       - const: tx
       - const: rx
 
+  power-domains:
+    maxItems: 1
+
   rockchip,capture-channels:
     allOf:
       - $ref: /schemas/types.yaml#/definitions/uint32
diff --git a/Documentation/devicetree/bindings/sound/rockchip-spdif.txt b/Documentation/devicetree/bindings/sound/rockchip-spdif.txt
deleted file mode 100644
index ec20c1271e92..000000000000
--- a/Documentation/devicetree/bindings/sound/rockchip-spdif.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-* Rockchip SPDIF transceiver
-
-The S/PDIF audio block is a stereo transceiver that allows the
-processor to receive and transmit digital audio via an coaxial cable or
-a fibre cable.
-
-Required properties:
-
-- compatible: should be one of the following:
-   - "rockchip,rk3066-spdif"
-   - "rockchip,rk3188-spdif"
-   - "rockchip,rk3228-spdif"
-   - "rockchip,rk3288-spdif"
-   - "rockchip,rk3328-spdif"
-   - "rockchip,rk3366-spdif"
-   - "rockchip,rk3368-spdif"
-   - "rockchip,rk3399-spdif"
-- reg: physical base address of the controller and length of memory mapped
-  region.
-- interrupts: should contain the SPDIF interrupt.
-- dmas: DMA specifiers for tx dma. See the DMA client binding,
-  Documentation/devicetree/bindings/dma/dma.txt
-- dma-names: should be "tx"
-- clocks: a list of phandle + clock-specifier pairs, one for each entry
-  in clock-names.
-- clock-names: should contain following:
-   - "hclk": clock for SPDIF controller
-   - "mclk" : clock for SPDIF bus
-
-Required properties on RK3288:
-  - rockchip,grf: the phandle of the syscon node for the general register
-                   file (GRF)
-
-Example for the rk3188 SPDIF controller:
-
-spdif: spdif@1011e000 {
-	compatible = "rockchip,rk3188-spdif", "rockchip,rk3066-spdif";
-	reg = <0x1011e000 0x2000>;
-	interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
-	dmas = <&dmac1_s 8>;
-	dma-names = "tx";
-	clock-names = "hclk", "mclk";
-	clocks = <&cru HCLK_SPDIF>, <&cru SCLK_SPDIF>;
-	#sound-dai-cells = <0>;
-};
diff --git a/Documentation/devicetree/bindings/sound/rockchip-spdif.yaml b/Documentation/devicetree/bindings/sound/rockchip-spdif.yaml
new file mode 100644
index 000000000000..c467152656f7
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/rockchip-spdif.yaml
@@ -0,0 +1,101 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/rockchip-spdif.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip SPDIF transceiver
+
+description:
+  The S/PDIF audio block is a stereo transceiver that allows the
+  processor to receive and transmit digital audio via a coaxial or
+  fibre cable.
+
+maintainers:
+  - Heiko Stuebner <heiko@sntech.de>
+
+properties:
+  compatible:
+    oneOf:
+      - const: rockchip,rk3066-spdif
+      - const: rockchip,rk3228-spdif
+      - const: rockchip,rk3328-spdif
+      - const: rockchip,rk3366-spdif
+      - const: rockchip,rk3368-spdif
+      - const: rockchip,rk3399-spdif
+      - items:
+          - enum:
+            - rockchip,rk3188-spdif
+            - rockchip,rk3288-spdif
+          - const: rockchip,rk3066-spdif
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: clock for SPDIF bus
+      - description: clock for SPDIF controller
+
+  clock-names:
+    items:
+      - const: mclk
+      - const: hclk
+
+  dmas:
+    maxItems: 1
+
+  dma-names:
+    const: tx
+
+  power-domains:
+    maxItems: 1
+
+  rockchip,grf:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      The phandle of the syscon node for the GRF register.
+      Required property on RK3288.
+
+  "#sound-dai-cells":
+    const: 0
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - dmas
+  - dma-names
+  - "#sound-dai-cells"
+
+if:
+  properties:
+    compatible:
+      contains:
+        const: rockchip,rk3288-spdif
+
+then:
+  required:
+    - rockchip,grf
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/rk3188-cru.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    spdif: spdif@1011e000 {
+      compatible = "rockchip,rk3188-spdif", "rockchip,rk3066-spdif";
+      reg = <0x1011e000 0x2000>;
+      interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+      clocks = <&cru SCLK_SPDIF>, <&cru HCLK_SPDIF>;
+      clock-names = "mclk", "hclk";
+      dmas = <&dmac1_s 8>;
+      dma-names = "tx";
+      #sound-dai-cells = <0>;
+    };
diff --git a/Documentation/devicetree/bindings/spi/qcom,spi-qcom-qspi.yaml b/Documentation/devicetree/bindings/spi/qcom,spi-qcom-qspi.yaml
index 0cf470eaf2a0..0178831b0662 100644
--- a/Documentation/devicetree/bindings/spi/qcom,spi-qcom-qspi.yaml
+++ b/Documentation/devicetree/bindings/spi/qcom,spi-qcom-qspi.yaml
@@ -8,12 +8,12 @@ $schema: "http://devicetree.org/meta-schemas/core.yaml#"
 title: Qualcomm Quad Serial Peripheral Interface (QSPI)
 
 maintainers:
- - Mukesh Savaliya <msavaliy@codeaurora.org>
- - Akash Asthana <akashast@codeaurora.org>
+  - Mukesh Savaliya <msavaliy@codeaurora.org>
+  - Akash Asthana <akashast@codeaurora.org>
 
-description:
- The QSPI controller allows SPI protocol communication in single, dual, or quad
- wire transmission modes for read/write access to slaves such as NOR flash.
+description: The QSPI controller allows SPI protocol communication in single,
+  dual, or quad wire transmission modes for read/write access to slaves such
+  as NOR flash.
 
 allOf:
   - $ref: /spi/spi-controller.yaml#
@@ -61,7 +61,7 @@ examples:
     #include <dt-bindings/clock/qcom,gcc-sdm845.h>
     #include <dt-bindings/interrupt-controller/arm-gic.h>
 
-    soc: soc@0 {
+    soc: soc {
         #address-cells = <2>;
         #size-cells = <2>;
 
diff --git a/Documentation/devicetree/bindings/spi/renesas,hspi.yaml b/Documentation/devicetree/bindings/spi/renesas,hspi.yaml
index c429cf4bea5b..f492cb9fea12 100644
--- a/Documentation/devicetree/bindings/spi/renesas,hspi.yaml
+++ b/Documentation/devicetree/bindings/spi/renesas,hspi.yaml
@@ -16,8 +16,8 @@ properties:
   compatible:
     items:
       - enum:
-        - renesas,hspi-r8a7778 # R-Car M1A
-        - renesas,hspi-r8a7779 # R-Car H1
+          - renesas,hspi-r8a7778 # R-Car M1A
+          - renesas,hspi-r8a7779 # R-Car H1
       - const: renesas,hspi
 
   reg:
diff --git a/Documentation/devicetree/bindings/spi/renesas,rspi.yaml b/Documentation/devicetree/bindings/spi/renesas,rspi.yaml
new file mode 100644
index 000000000000..c54ac059043f
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/renesas,rspi.yaml
@@ -0,0 +1,144 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/renesas,rspi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas (Quad) Serial Peripheral Interface (RSPI/QSPI)
+
+maintainers:
+  - Geert Uytterhoeven <geert+renesas@glider.be>
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - renesas,rspi-sh7757    # SH7757
+          - const: renesas,rspi        # Legacy SH
+
+      - items:
+          - enum:
+              - renesas,rspi-r7s72100  # RZ/A1H
+              - renesas,rspi-r7s9210   # RZ/A2
+          - const: renesas,rspi-rz     # RZ/A
+
+      - items:
+          - enum:
+              - renesas,qspi-r8a7743   # RZ/G1M
+              - renesas,qspi-r8a7744   # RZ/G1N
+              - renesas,qspi-r8a7745   # RZ/G1E
+              - renesas,qspi-r8a77470  # RZ/G1C
+              - renesas,qspi-r8a7790   # R-Car H2
+              - renesas,qspi-r8a7791   # R-Car M2-W
+              - renesas,qspi-r8a7792   # R-Car V2H
+              - renesas,qspi-r8a7793   # R-Car M2-N
+              - renesas,qspi-r8a7794   # R-Car E2
+          - const: renesas,qspi        # R-Car Gen2 and RZ/G1
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    oneOf:
+      - items:
+          - description: A combined interrupt
+      - items:
+          - description: Error interrupt (SPEI)
+          - description: Receive Interrupt (SPRI)
+          - description: Transmit Interrupt (SPTI)
+
+  interrupt-names:
+    oneOf:
+      - items:
+          - const: mux
+      - items:
+          - const: error
+          - const: rx
+          - const: tx
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  resets:
+    maxItems: 1
+
+  dmas:
+    description:
+      Must contain a list of pairs of references to DMA specifiers, one for
+      transmission, and one for reception.
+
+  dma-names:
+    minItems: 2
+    maxItems: 4
+    items:
+      enum:
+        - tx
+        - rx
+
+  num-cs:
+    description: |
+      Total number of native chip selects.
+      Hardware limitations related to chip selects:
+        - When using GPIO chip selects, at least one native chip select must
+          be left unused, as it will be driven anyway.
+    minimum: 1
+    maximum: 2
+    default: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - power-domains
+  - '#address-cells'
+  - '#size-cells'
+
+allOf:
+  - $ref: spi-controller.yaml#
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - renesas,rspi-rz
+    then:
+      properties:
+        interrupts:
+          minItems: 3
+      required:
+        - interrupt-names
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - renesas,qspi
+    then:
+      required:
+        - resets
+
+examples:
+  - |
+    #include <dt-bindings/clock/r8a7791-cpg-mssr.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/power/r8a7791-sysc.h>
+
+    qspi: spi@e6b10000 {
+            compatible = "renesas,qspi-r8a7791", "renesas,qspi";
+            reg = <0xe6b10000 0x2c>;
+            interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
+            clocks = <&cpg CPG_MOD 917>;
+            dmas = <&dmac0 0x17>, <&dmac0 0x18>, <&dmac1 0x17>, <&dmac1 0x18>;
+            dma-names = "tx", "rx", "tx", "rx";
+            power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+            resets = <&cpg 917>;
+            num-cs = <1>;
+            #address-cells = <1>;
+            #size-cells = <0>;
+    };
diff --git a/Documentation/devicetree/bindings/spi/spi-pl022.yaml b/Documentation/devicetree/bindings/spi/spi-pl022.yaml
index dfb697c69341..22ba4e90655b 100644
--- a/Documentation/devicetree/bindings/spi/spi-pl022.yaml
+++ b/Documentation/devicetree/bindings/spi/spi-pl022.yaml
@@ -51,7 +51,7 @@ properties:
 
   pl022,rt:
     description: indicates the controller should run the message pump with realtime
-               priority to minimise the transfer latency on the bus (boolean)
+      priority to minimise the transfer latency on the bus (boolean)
     type: boolean
 
   dmas:
diff --git a/Documentation/devicetree/bindings/spi/spi-rspi.txt b/Documentation/devicetree/bindings/spi/spi-rspi.txt
deleted file mode 100644
index 421722b93992..000000000000
--- a/Documentation/devicetree/bindings/spi/spi-rspi.txt
+++ /dev/null
@@ -1,73 +0,0 @@
-Device tree configuration for Renesas RSPI/QSPI driver
-
-Required properties:
-- compatible       : For Renesas Serial Peripheral Interface on legacy SH:
-		     "renesas,rspi-<soctype>", "renesas,rspi" as fallback.
-		     For Renesas Serial Peripheral Interface on RZ/A:
-		     "renesas,rspi-<soctype>", "renesas,rspi-rz" as fallback.
-		     For Quad Serial Peripheral Interface on R-Car Gen2 and
-		     RZ/G1 devices:
-		     "renesas,qspi-<soctype>", "renesas,qspi" as fallback.
-		     Examples with soctypes are:
-		        - "renesas,rspi-sh7757" (SH)
-			- "renesas,rspi-r7s72100" (RZ/A1H)
-			- "renesas,rspi-r7s9210" (RZ/A2)
-			- "renesas,qspi-r8a7743" (RZ/G1M)
-			- "renesas,qspi-r8a7744" (RZ/G1N)
-			- "renesas,qspi-r8a7745" (RZ/G1E)
-			- "renesas,qspi-r8a77470" (RZ/G1C)
-			- "renesas,qspi-r8a7790" (R-Car H2)
-			- "renesas,qspi-r8a7791" (R-Car M2-W)
-			- "renesas,qspi-r8a7792" (R-Car V2H)
-			- "renesas,qspi-r8a7793" (R-Car M2-N)
-			- "renesas,qspi-r8a7794" (R-Car E2)
-- reg              : Address start and address range size of the device
-- interrupts       : A list of interrupt-specifiers, one for each entry in
-		     interrupt-names.
-		     If interrupt-names is not present, an interrupt specifier
-		     for a single muxed interrupt.
-- interrupt-names  : A list of interrupt names. Should contain (if present):
-		       - "error" for SPEI,
-		       - "rx" for SPRI,
-		       - "tx" to SPTI,
-		       - "mux" for a single muxed interrupt.
-- num-cs	   : Number of chip selects. Some RSPI cores have more than 1.
-- #address-cells   : Must be <1>
-- #size-cells      : Must be <0>
-
-Optional properties:
-- clocks           : Must contain a reference to the functional clock.
-- dmas             : Must contain a list of two references to DMA specifiers,
-		     one for transmission, and one for reception.
-- dma-names        : Must contain a list of two DMA names, "tx" and "rx".
-
-Pinctrl properties might be needed, too.  See
-Documentation/devicetree/bindings/pinctrl/renesas,*.
-
-Examples:
-
-	spi0: spi@e800c800 {
-		compatible = "renesas,rspi-r7s72100", "renesas,rspi-rz";
-		reg = <0xe800c800 0x24>;
-		interrupts = <0 238 IRQ_TYPE_LEVEL_HIGH>,
-			     <0 239 IRQ_TYPE_LEVEL_HIGH>,
-			     <0 240 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-names = "error", "rx", "tx";
-		interrupt-parent = <&gic>;
-		num-cs = <1>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-	};
-
-	spi: spi@e6b10000 {
-		compatible = "renesas,qspi-r8a7791", "renesas,qspi";
-		reg = <0 0xe6b10000 0 0x2c>;
-		interrupt-parent = <&gic>;
-		interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&mstp9_clks R8A7791_CLK_QSPI_MOD>;
-		num-cs = <1>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		dmas = <&dmac0 0x17>, <&dmac0 0x18>;
-		dma-names = "tx", "rx";
-	};
diff --git a/Documentation/devicetree/bindings/spi/st,stm32-qspi.yaml b/Documentation/devicetree/bindings/spi/st,stm32-qspi.yaml
index 3665a5fe6b7f..1a342ce1f798 100644
--- a/Documentation/devicetree/bindings/spi/st,stm32-qspi.yaml
+++ b/Documentation/devicetree/bindings/spi/st,stm32-qspi.yaml
@@ -24,8 +24,8 @@ properties:
 
   reg-names:
     items:
-     - const: qspi
-     - const: qspi_mm
+      - const: qspi
+      - const: qspi_mm
 
   clocks:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/sram/allwinner,sun4i-a10-system-control.yaml b/Documentation/devicetree/bindings/sram/allwinner,sun4i-a10-system-control.yaml
index 4b5509436588..f5825935fd22 100644
--- a/Documentation/devicetree/bindings/sram/allwinner,sun4i-a10-system-control.yaml
+++ b/Documentation/devicetree/bindings/sram/allwinner,sun4i-a10-system-control.yaml
@@ -29,8 +29,8 @@ properties:
       - const: allwinner,sun4i-a10-system-control
       - const: allwinner,sun5i-a13-system-control
       - items:
-        - const: allwinner,sun7i-a20-system-control
-        - const: allwinner,sun4i-a10-system-control
+          - const: allwinner,sun7i-a20-system-control
+          - const: allwinner,sun4i-a10-system-control
       - const: allwinner,sun8i-a23-system-control
       - const: allwinner,sun8i-h3-system-control
       - const: allwinner,sun50i-a64-sram-controller
@@ -38,11 +38,11 @@ properties:
       - const: allwinner,sun50i-a64-system-control
       - const: allwinner,sun50i-h5-system-control
       - items:
-        - const: allwinner,sun50i-h6-system-control
-        - const: allwinner,sun50i-a64-system-control
+          - const: allwinner,sun50i-h6-system-control
+          - const: allwinner,sun50i-a64-system-control
       - items:
-        - const: allwinner,suniv-f1c100s-system-control
-        - const: allwinner,sun4i-a10-system-control
+          - const: allwinner,suniv-f1c100s-system-control
+          - const: allwinner,sun4i-a10-system-control
 
   reg:
     maxItems: 1
@@ -69,44 +69,44 @@ patternProperties:
               - const: allwinner,sun4i-a10-sram-d
               - const: allwinner,sun50i-a64-sram-c
               - items:
-                - const: allwinner,sun5i-a13-sram-a3-a4
-                - const: allwinner,sun4i-a10-sram-a3-a4
+                  - const: allwinner,sun5i-a13-sram-a3-a4
+                  - const: allwinner,sun4i-a10-sram-a3-a4
               - items:
-                - const: allwinner,sun7i-a20-sram-a3-a4
-                - const: allwinner,sun4i-a10-sram-a3-a4
+                  - const: allwinner,sun7i-a20-sram-a3-a4
+                  - const: allwinner,sun4i-a10-sram-a3-a4
               - items:
-                - const: allwinner,sun5i-a13-sram-c1
-                - const: allwinner,sun4i-a10-sram-c1
+                  - const: allwinner,sun5i-a13-sram-c1
+                  - const: allwinner,sun4i-a10-sram-c1
               - items:
-                - const: allwinner,sun7i-a20-sram-c1
-                - const: allwinner,sun4i-a10-sram-c1
+                  - const: allwinner,sun7i-a20-sram-c1
+                  - const: allwinner,sun4i-a10-sram-c1
               - items:
-                - const: allwinner,sun8i-a23-sram-c1
-                - const: allwinner,sun4i-a10-sram-c1
+                  - const: allwinner,sun8i-a23-sram-c1
+                  - const: allwinner,sun4i-a10-sram-c1
               - items:
-                - const: allwinner,sun8i-h3-sram-c1
-                - const: allwinner,sun4i-a10-sram-c1
+                  - const: allwinner,sun8i-h3-sram-c1
+                  - const: allwinner,sun4i-a10-sram-c1
               - items:
-                - const: allwinner,sun50i-a64-sram-c1
-                - const: allwinner,sun4i-a10-sram-c1
+                  - const: allwinner,sun50i-a64-sram-c1
+                  - const: allwinner,sun4i-a10-sram-c1
               - items:
-                - const: allwinner,sun50i-h5-sram-c1
-                - const: allwinner,sun4i-a10-sram-c1
+                  - const: allwinner,sun50i-h5-sram-c1
+                  - const: allwinner,sun4i-a10-sram-c1
               - items:
-                - const: allwinner,sun50i-h6-sram-c1
-                - const: allwinner,sun4i-a10-sram-c1
+                  - const: allwinner,sun50i-h6-sram-c1
+                  - const: allwinner,sun4i-a10-sram-c1
               - items:
-                - const: allwinner,sun5i-a13-sram-d
-                - const: allwinner,sun4i-a10-sram-d
+                  - const: allwinner,sun5i-a13-sram-d
+                  - const: allwinner,sun4i-a10-sram-d
               - items:
-                - const: allwinner,sun7i-a20-sram-d
-                - const: allwinner,sun4i-a10-sram-d
+                  - const: allwinner,sun7i-a20-sram-d
+                  - const: allwinner,sun4i-a10-sram-d
               - items:
-                - const: allwinner,suniv-f1c100s-sram-d
-                - const: allwinner,sun4i-a10-sram-d
+                  - const: allwinner,suniv-f1c100s-sram-d
+                  - const: allwinner,sun4i-a10-sram-d
               - items:
-                - const: allwinner,sun50i-h6-sram-c
-                - const: allwinner,sun50i-a64-sram-c
+                  - const: allwinner,sun50i-h6-sram-c
+                  - const: allwinner,sun50i-a64-sram-c
 
 required:
   - "#address-cells"
diff --git a/Documentation/devicetree/bindings/sram/sram.yaml b/Documentation/devicetree/bindings/sram/sram.yaml
index 7b83cc6c9bfa..0aea3d239a48 100644
--- a/Documentation/devicetree/bindings/sram/sram.yaml
+++ b/Documentation/devicetree/bindings/sram/sram.yaml
@@ -73,6 +73,8 @@ patternProperties:
             - allwinner,sun50i-a64-sram-c
             - amlogic,meson8-smp-sram
             - amlogic,meson8b-smp-sram
+            - amlogic,meson-gxbb-scp-shmem
+            - amlogic,meson-axg-scp-shmem
             - renesas,smp-sram
             - rockchip,rk3066-smp-sram
             - samsung,exynos4210-sysram
diff --git a/Documentation/devicetree/bindings/thermal/amlogic,thermal.yaml b/Documentation/devicetree/bindings/thermal/amlogic,thermal.yaml
index e43ec50bda37..999c6b365f1d 100644
--- a/Documentation/devicetree/bindings/thermal/amlogic,thermal.yaml
+++ b/Documentation/devicetree/bindings/thermal/amlogic,thermal.yaml
@@ -13,11 +13,11 @@ description: Binding for Amlogic Thermal
 
 properties:
   compatible:
-      items:
-        - enum:
-            - amlogic,g12a-cpu-thermal
-            - amlogic,g12a-ddr-thermal
-        - const: amlogic,g12a-thermal
+    items:
+      - enum:
+          - amlogic,g12a-cpu-thermal
+          - amlogic,g12a-ddr-thermal
+      - const: amlogic,g12a-thermal
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/thermal/ti,am654-thermal.yaml b/Documentation/devicetree/bindings/thermal/ti,am654-thermal.yaml
new file mode 100644
index 000000000000..25b9209c2e5d
--- /dev/null
+++ b/Documentation/devicetree/bindings/thermal/ti,am654-thermal.yaml
@@ -0,0 +1,56 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/thermal/ti,am654-thermal.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Texas Instruments AM654 VTM (DTS) binding
+
+maintainers:
+  - Keerthy <j-keerthy@ti.com>
+
+properties:
+  compatible:
+    const: ti,am654-vtm
+
+  reg:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#thermal-sensor-cells":
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - power-domains
+  - "#thermal-sensor-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/soc/ti,sci_pm_domain.h>
+    vtm: thermal@42050000 {
+        compatible = "ti,am654-vtm";
+        reg = <0x0 0x42050000 0x0 0x25c>;
+        power-domains = <&k3_pds 80 TI_SCI_PD_EXCLUSIVE>;
+        #thermal-sensor-cells = <1>;
+    };
+
+    mpu0_thermal: mpu0_thermal {
+        polling-delay-passive = <250>; /* milliseconds */
+        polling-delay = <500>; /* milliseconds */
+        thermal-sensors = <&vtm0 0>;
+
+        trips {
+                mpu0_crit: mpu0_crit {
+                        temperature = <125000>; /* milliCelsius */
+                        hysteresis = <2000>; /* milliCelsius */
+                        type = "critical";
+                };
+        };
+    };
+...
diff --git a/Documentation/devicetree/bindings/timer/arm,arch_timer.yaml b/Documentation/devicetree/bindings/timer/arm,arch_timer.yaml
index fa255672e8e5..135186f83925 100644
--- a/Documentation/devicetree/bindings/timer/arm,arch_timer.yaml
+++ b/Documentation/devicetree/bindings/timer/arm,arch_timer.yaml
@@ -28,10 +28,10 @@ properties:
               - arm,armv7-timer
       - items:
           - enum:
-            - arm,armv7-timer
+              - arm,armv7-timer
       - items:
           - enum:
-            - arm,armv8-timer
+              - arm,armv8-timer
 
   interrupts:
     items:
diff --git a/Documentation/devicetree/bindings/timer/arm,arch_timer_mmio.yaml b/Documentation/devicetree/bindings/timer/arm,arch_timer_mmio.yaml
index 582bbef62b95..6ff718ede184 100644
--- a/Documentation/devicetree/bindings/timer/arm,arch_timer_mmio.yaml
+++ b/Documentation/devicetree/bindings/timer/arm,arch_timer_mmio.yaml
@@ -20,7 +20,7 @@ properties:
   compatible:
     items:
       - enum:
-        - arm,armv7-timer-mem
+          - arm,armv7-timer-mem
 
   reg:
     maxItems: 1
@@ -77,7 +77,7 @@ patternProperties:
           - description: physical timer irq
           - description: virtual timer irq
 
-      reg :
+      reg:
         minItems: 1
         maxItems: 2
         items:
diff --git a/Documentation/devicetree/bindings/timer/cadence,ttc-timer.txt b/Documentation/devicetree/bindings/timer/cadence,ttc-timer.txt
deleted file mode 100644
index eeee6cd51e5c..000000000000
--- a/Documentation/devicetree/bindings/timer/cadence,ttc-timer.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-Cadence TTC - Triple Timer Counter
-
-Required properties:
-- compatible : Should be "cdns,ttc".
-- reg : Specifies base physical address and size of the registers.
-- interrupts : A list of 3 interrupts; one per timer channel.
-- clocks: phandle to the source clock
-
-Optional properties:
-- timer-width: Bit width of the timer, necessary if not 16.
-
-Example:
-
-ttc0: ttc0@f8001000 {
-	interrupt-parent = <&intc>;
-	interrupts = < 0 10 4 0 11 4 0 12 4 >;
-	compatible = "cdns,ttc";
-	reg = <0xF8001000 0x1000>;
-	clocks = <&cpu_clk 3>;
-	timer-width = <32>;
-};
diff --git a/Documentation/devicetree/bindings/timer/cdns,ttc.yaml b/Documentation/devicetree/bindings/timer/cdns,ttc.yaml
new file mode 100644
index 000000000000..c532b60b9c63
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/cdns,ttc.yaml
@@ -0,0 +1,48 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/timer/cdns,ttc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Cadence TTC - Triple Timer Counter
+
+maintainers:
+  - Michal Simek <michal.simek@xilinx.com>
+
+properties:
+  compatible:
+    const: cdns,ttc
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    minItems: 3
+    maxItems: 3
+    description: |
+      A list of 3 interrupts; one per timer channel.
+
+  clocks:
+    maxItems: 1
+
+  timer-width:
+    $ref: "/schemas/types.yaml#/definitions/uint32"
+    description: |
+      Bit width of the timer, necessary if not 16.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+
+examples:
+  - |
+    ttc0: ttc0@f8001000 {
+        interrupt-parent = <&intc>;
+        interrupts = <0 10 4>, <0 11 4>, <0 12 4>;
+        compatible = "cdns,ttc";
+        reg = <0xF8001000 0x1000>;
+        clocks = <&cpu_clk 3>;
+        timer-width = <32>;
+    };
diff --git a/Documentation/devicetree/bindings/usb/dwc2.yaml b/Documentation/devicetree/bindings/usb/dwc2.yaml
index 0d6d850a7f17..fb2f62aef5fa 100644
--- a/Documentation/devicetree/bindings/usb/dwc2.yaml
+++ b/Documentation/devicetree/bindings/usb/dwc2.yaml
@@ -62,14 +62,14 @@ properties:
 
   resets:
     items:
-     - description: common reset
-     - description: ecc reset
+      - description: common reset
+      - description: ecc reset
     minItems: 1
 
   reset-names:
     items:
-     - const: dwc2
-     - const: dwc2-ecc
+      - const: dwc2
+      - const: dwc2-ecc
     minItems: 1
 
   phys:
diff --git a/Documentation/devicetree/bindings/usb/generic-ehci.yaml b/Documentation/devicetree/bindings/usb/generic-ehci.yaml
index 10edd05872ea..848eea59bc00 100644
--- a/Documentation/devicetree/bindings/usb/generic-ehci.yaml
+++ b/Documentation/devicetree/bindings/usb/generic-ehci.yaml
@@ -36,6 +36,9 @@ properties:
         - if a USB DRD channel: first clock should be host and second
           one should be peripheral
 
+  power-domains:
+    maxItems: 1
+
   big-endian:
     $ref: /schemas/types.yaml#/definitions/flag
     description:
diff --git a/Documentation/devicetree/bindings/usb/generic-ohci.yaml b/Documentation/devicetree/bindings/usb/generic-ohci.yaml
index bcffec1f1341..d7efddf27b22 100644
--- a/Documentation/devicetree/bindings/usb/generic-ohci.yaml
+++ b/Documentation/devicetree/bindings/usb/generic-ohci.yaml
@@ -36,6 +36,9 @@ properties:
         - if a USB DRD channel: first clock should be host and second
           one should be peripheral
 
+  power-domains:
+    maxItems: 1
+
   big-endian:
     $ref: /schemas/types.yaml#/definitions/flag
     description:
diff --git a/Documentation/devicetree/bindings/usb/ingenic,musb.yaml b/Documentation/devicetree/bindings/usb/ingenic,musb.yaml
index 1d6877875077..c2d2ee43ba67 100644
--- a/Documentation/devicetree/bindings/usb/ingenic,musb.yaml
+++ b/Documentation/devicetree/bindings/usb/ingenic,musb.yaml
@@ -56,7 +56,7 @@ additionalProperties: false
 examples:
   - |
     #include <dt-bindings/clock/jz4740-cgu.h>
-    usb_phy: usb-phy@0 {
+    usb_phy: usb-phy {
       compatible = "usb-nop-xceiv";
       #phy-cells = <0>;
     };
diff --git a/Documentation/devicetree/bindings/usb/qcom,dwc3.txt b/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
index cb695aa3fba4..fbdd01756752 100644
--- a/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
+++ b/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
@@ -52,8 +52,8 @@ A child node must exist to represent the core DWC3 IP block. The name of
 the node is not important. The content of the node is defined in dwc3.txt.
 
 Phy documentation is provided in the following places:
-Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt   - USB3 QMP PHY
-Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt - USB2 QUSB2 PHY
+Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt    - USB3 QMP PHY
+Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml - USB2 QUSB2 PHY
 
 Example device nodes:
 
diff --git a/Documentation/devicetree/bindings/usb/renesas,usb3-peri.yaml b/Documentation/devicetree/bindings/usb/renesas,usb3-peri.yaml
index 92d8631b9aa6..031452aa25bc 100644
--- a/Documentation/devicetree/bindings/usb/renesas,usb3-peri.yaml
+++ b/Documentation/devicetree/bindings/usb/renesas,usb3-peri.yaml
@@ -18,6 +18,7 @@ properties:
           - renesas,r8a774c0-usb3-peri # RZ/G2E
           - renesas,r8a7795-usb3-peri  # R-Car H3
           - renesas,r8a7796-usb3-peri  # R-Car M3-W
+          - renesas,r8a77961-usb3-peri # R-Car M3-W+
           - renesas,r8a77965-usb3-peri # R-Car M3-N
           - renesas,r8a77990-usb3-peri # R-Car E3
       - const: renesas,rcar-gen3-usb3-peri
diff --git a/Documentation/devicetree/bindings/usb/renesas,usbhs.yaml b/Documentation/devicetree/bindings/usb/renesas,usbhs.yaml
index 469affa872d3..a7ae95598ccb 100644
--- a/Documentation/devicetree/bindings/usb/renesas,usbhs.yaml
+++ b/Documentation/devicetree/bindings/usb/renesas,usbhs.yaml
@@ -40,6 +40,7 @@ properties:
               - renesas,usbhs-r8a774c0 # RZ/G2E
               - renesas,usbhs-r8a7795  # R-Car H3
               - renesas,usbhs-r8a7796  # R-Car M3-W
+              - renesas,usbhs-r8a77961 # R-Car M3-W+
               - renesas,usbhs-r8a77965 # R-Car M3-N
               - renesas,usbhs-r8a77990 # R-Car E3
               - renesas,usbhs-r8a77995 # R-Car D3
diff --git a/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt b/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt
index c8c4b00ecb94..94520493233b 100644
--- a/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt
+++ b/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt
@@ -16,7 +16,7 @@ A child node must exist to represent the core DWC3 IP block. The name of
 the node is not important. The content of the node is defined in dwc3.txt.
 
 Phy documentation is provided in the following places:
-Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.txt - USB2.0 PHY
+Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.yaml - USB2.0 PHY
 Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt     - Type-C PHY
 
 Example device nodes:
diff --git a/Documentation/devicetree/bindings/usb/usb-xhci.txt b/Documentation/devicetree/bindings/usb/usb-xhci.txt
index 3f378951d624..dc025f126d71 100644
--- a/Documentation/devicetree/bindings/usb/usb-xhci.txt
+++ b/Documentation/devicetree/bindings/usb/usb-xhci.txt
@@ -16,7 +16,8 @@ Required properties:
     - "renesas,xhci-r8a7791" for r8a7791 SoC
     - "renesas,xhci-r8a7793" for r8a7793 SoC
     - "renesas,xhci-r8a7795" for r8a7795 SoC
-    - "renesas,xhci-r8a7796" for r8a7796 SoC
+    - "renesas,xhci-r8a7796" for r8a77960 SoC
+    - "renesas,xhci-r8a77961" for r8a77961 SoC
     - "renesas,xhci-r8a77965" for r8a77965 SoC
     - "renesas,xhci-r8a77990" for r8a77990 SoC
     - "renesas,rcar-gen2-xhci" for a generic R-Car Gen2 or RZ/G1 compatible
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index d3891386d671..66a7382add95 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -59,6 +59,8 @@ patternProperties:
     description: Allwinner Technology Co., Ltd.
   "^alphascale,.*":
     description: AlphaScale Integrated Circuits Systems, Inc.
+  "^alps,.*":
+    description: Alps Electric Co., Ltd.
   "^altr,.*":
     description: Altera Corp.
   "^amarula,.*":
@@ -143,6 +145,8 @@ patternProperties:
     description: BIPAI KEJI LIMITED
   "^beacon,.*":
     description: Compass Electronics Group, LLC
+  "^beagle,.*":
+    description: BeagleBoard.org Foundation
   "^bhf,.*":
     description: Beckhoff Automation GmbH & Co. KG
   "^bitmain,.*":
@@ -181,6 +185,8 @@ patternProperties:
     description: CDTech(H.K.) Electronics Limited
   "^ceva,.*":
     description: Ceva, Inc.
+  "^checkpoint,.*":
+    description: Check Point Software Technologies Ltd.
   "^chipidea,.*":
     description: Chipidea, Inc
   "^chipone,.*":
@@ -808,6 +814,8 @@ patternProperties:
     description: Primux Trading, S.L.
   "^probox2,.*":
     description: PROBOX2 (by W2COMP Co., Ltd.)
+  "^prt,.*":
+    description: Protonic Holland
   "^pulsedlight,.*":
     description: PulsedLight, Inc
   "^purism,.*":
@@ -1125,6 +1133,8 @@ patternProperties:
     description: Shenzhen Xinpeng Technology Co., Ltd
   "^xlnx,.*":
     description: Xilinx
+  "^xnano,.*":
+    description: Xnano
   "^xunlong,.*":
     description: Shenzhen Xunlong Software CO.,Limited
   "^xylon,.*":
diff --git a/Documentation/doc-guide/parse-headers.rst b/Documentation/doc-guide/parse-headers.rst
index 24cfaa15dd81..f7135b058246 100644
--- a/Documentation/doc-guide/parse-headers.rst
+++ b/Documentation/doc-guide/parse-headers.rst
@@ -10,7 +10,7 @@ if a symbol is not found at the documentation. That helps to keep the
 uAPI documentation in sync with the Kernel changes.
 The :ref:`parse_headers.pl <parse_headers>` provide a way to generate such
 cross-references. It has to be called via Makefile, while building the
-documentation. Please see ``Documentation/media/Makefile`` for an example
+documentation. Please see ``Documentation/userspace-api/media/Makefile`` for an example
 about how to use it inside the Kernel tree.
 
 .. _parse_headers:
diff --git a/Documentation/driver-api/index.rst b/Documentation/driver-api/index.rst
index d4e78cb3ef4d..dcc47c029f8e 100644
--- a/Documentation/driver-api/index.rst
+++ b/Documentation/driver-api/index.rst
@@ -63,6 +63,7 @@ available subsections can be seen below.
    pinctl
    gpio/index
    md/index
+   media/index
    misc_devices
    nfc/index
    dmaengine/index
diff --git a/Documentation/driver-api/media/cec-core.rst b/Documentation/driver-api/media/cec-core.rst
new file mode 100644
index 000000000000..3ce26b7c2b2b
--- /dev/null
+++ b/Documentation/driver-api/media/cec-core.rst
@@ -0,0 +1,474 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+CEC Kernel Support
+==================
+
+The CEC framework provides a unified kernel interface for use with HDMI CEC
+hardware. It is designed to handle a multiple types of hardware (receivers,
+transmitters, USB dongles). The framework also gives the option to decide
+what to do in the kernel driver and what should be handled by userspace
+applications. In addition it integrates the remote control passthrough
+feature into the kernel's remote control framework.
+
+
+The CEC Protocol
+----------------
+
+The CEC protocol enables consumer electronic devices to communicate with each
+other through the HDMI connection. The protocol uses logical addresses in the
+communication. The logical address is strictly connected with the functionality
+provided by the device. The TV acting as the communication hub is always
+assigned address 0. The physical address is determined by the physical
+connection between devices.
+
+The CEC framework described here is up to date with the CEC 2.0 specification.
+It is documented in the HDMI 1.4 specification with the new 2.0 bits documented
+in the HDMI 2.0 specification. But for most of the features the freely available
+HDMI 1.3a specification is sufficient:
+
+http://www.microprocessor.org/HDMISpecification13a.pdf
+
+
+CEC Adapter Interface
+---------------------
+
+The struct cec_adapter represents the CEC adapter hardware. It is created by
+calling cec_allocate_adapter() and deleted by calling cec_delete_adapter():
+
+.. c:function::
+   struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, void *priv,
+   const char *name, u32 caps, u8 available_las);
+
+.. c:function::
+   void cec_delete_adapter(struct cec_adapter *adap);
+
+To create an adapter you need to pass the following information:
+
+ops:
+	adapter operations which are called by the CEC framework and that you
+	have to implement.
+
+priv:
+	will be stored in adap->priv and can be used by the adapter ops.
+	Use cec_get_drvdata(adap) to get the priv pointer.
+
+name:
+	the name of the CEC adapter. Note: this name will be copied.
+
+caps:
+	capabilities of the CEC adapter. These capabilities determine the
+	capabilities of the hardware and which parts are to be handled
+	by userspace and which parts are handled by kernelspace. The
+	capabilities are returned by CEC_ADAP_G_CAPS.
+
+available_las:
+	the number of simultaneous logical addresses that this
+	adapter can handle. Must be 1 <= available_las <= CEC_MAX_LOG_ADDRS.
+
+To obtain the priv pointer use this helper function:
+
+.. c:function::
+	void *cec_get_drvdata(const struct cec_adapter *adap);
+
+To register the /dev/cecX device node and the remote control device (if
+CEC_CAP_RC is set) you call:
+
+.. c:function::
+	int cec_register_adapter(struct cec_adapter *adap, struct device *parent);
+
+where parent is the parent device.
+
+To unregister the devices call:
+
+.. c:function::
+	void cec_unregister_adapter(struct cec_adapter *adap);
+
+Note: if cec_register_adapter() fails, then call cec_delete_adapter() to
+clean up. But if cec_register_adapter() succeeded, then only call
+cec_unregister_adapter() to clean up, never cec_delete_adapter(). The
+unregister function will delete the adapter automatically once the last user
+of that /dev/cecX device has closed its file handle.
+
+
+Implementing the Low-Level CEC Adapter
+--------------------------------------
+
+The following low-level adapter operations have to be implemented in
+your driver:
+
+.. c:type:: struct cec_adap_ops
+
+.. code-block:: none
+
+	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);
+		void (*adap_status)(struct cec_adapter *adap, struct seq_file *file);
+		void (*adap_free)(struct cec_adapter *adap);
+
+		/* Error injection callbacks */
+		...
+
+		/* High-level callbacks */
+		...
+	};
+
+The seven low-level ops deal with various aspects of controlling the CEC adapter
+hardware:
+
+
+To enable/disable the hardware:
+
+.. c:function::
+	int (*adap_enable)(struct cec_adapter *adap, bool enable);
+
+This callback enables or disables the CEC hardware. Enabling the CEC hardware
+means powering it up in a state where no logical addresses are claimed. This
+op assumes that the physical address (adap->phys_addr) is valid when enable is
+true and will not change while the CEC adapter remains enabled. The initial
+state of the CEC adapter after calling cec_allocate_adapter() is disabled.
+
+Note that adap_enable must return 0 if enable is false.
+
+
+To enable/disable the 'monitor all' mode:
+
+.. c:function::
+	int (*adap_monitor_all_enable)(struct cec_adapter *adap, bool enable);
+
+If enabled, then the adapter should be put in a mode to also monitor messages
+that not for us. Not all hardware supports this and this function is only
+called if the CEC_CAP_MONITOR_ALL capability is set. This callback is optional
+(some hardware may always be in 'monitor all' mode).
+
+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::
+	int (*adap_log_addr)(struct cec_adapter *adap, u8 logical_addr);
+
+If logical_addr == CEC_LOG_ADDR_INVALID then all programmed logical addresses
+are to be erased. Otherwise the given logical address should be programmed.
+If the maximum number of available logical addresses is exceeded, then it
+should return -ENXIO. Once a logical address is programmed the CEC hardware
+can receive directed messages to that address.
+
+Note that adap_log_addr must return 0 if logical_addr is CEC_LOG_ADDR_INVALID.
+
+
+To transmit a new message:
+
+.. c:function::
+	int (*adap_transmit)(struct cec_adapter *adap, u8 attempts,
+			     u32 signal_free_time, struct cec_msg *msg);
+
+This transmits a new message. The attempts argument is the suggested number of
+attempts for the transmit.
+
+The signal_free_time is the number of data bit periods that the adapter should
+wait when the line is free before attempting to send a message. This value
+depends on whether this transmit is a retry, a message from a new initiator or
+a new message for the same initiator. Most hardware will handle this
+automatically, but in some cases this information is needed.
+
+The CEC_FREE_TIME_TO_USEC macro can be used to convert signal_free_time to
+microseconds (one data bit period is 2.4 ms).
+
+
+To log the current CEC hardware status:
+
+.. c:function::
+	void (*adap_status)(struct cec_adapter *adap, struct seq_file *file);
+
+This optional callback can be used to show the status of the CEC hardware.
+The status is available through debugfs: cat /sys/kernel/debug/cec/cecX/status
+
+To free any resources when the adapter is deleted:
+
+.. c:function::
+	void (*adap_free)(struct cec_adapter *adap);
+
+This optional callback can be used to free any resources that might have been
+allocated by the driver. It's called from cec_delete_adapter.
+
+
+Your adapter driver will also have to react to events (typically interrupt
+driven) by calling into the framework in the following situations:
+
+When a transmit finished (successfully or otherwise):
+
+.. c:function::
+	void cec_transmit_done(struct cec_adapter *adap, u8 status, u8 arb_lost_cnt,
+		       u8 nack_cnt, u8 low_drive_cnt, u8 error_cnt);
+
+or:
+
+.. c:function::
+	void cec_transmit_attempt_done(struct cec_adapter *adap, u8 status);
+
+The status can be one of:
+
+CEC_TX_STATUS_OK:
+	the transmit was successful.
+
+CEC_TX_STATUS_ARB_LOST:
+	arbitration was lost: another CEC initiator
+	took control of the CEC line and you lost the arbitration.
+
+CEC_TX_STATUS_NACK:
+	the message was nacked (for a directed message) or
+	acked (for a broadcast message). A retransmission is needed.
+
+CEC_TX_STATUS_LOW_DRIVE:
+	low drive was detected on the CEC bus. This indicates that
+	a follower detected an error on the bus and requested a
+	retransmission.
+
+CEC_TX_STATUS_ERROR:
+	some unspecified error occurred: this can be one of ARB_LOST
+	or LOW_DRIVE if the hardware cannot differentiate or something
+	else entirely. Some hardware only supports OK and FAIL as the
+	result of a transmit, i.e. there is no way to differentiate
+	between the different possible errors. In that case map FAIL
+	to CEC_TX_STATUS_NACK and not to CEC_TX_STATUS_ERROR.
+
+CEC_TX_STATUS_MAX_RETRIES:
+	could not transmit the message after trying multiple times.
+	Should only be set by the driver if it has hardware support for
+	retrying messages. If set, then the framework assumes that it
+	doesn't have to make another attempt to transmit the message
+	since the hardware did that already.
+
+The hardware must be able to differentiate between OK, NACK and 'something
+else'.
+
+The \*_cnt arguments are the number of error conditions that were seen.
+This may be 0 if no information is available. Drivers that do not support
+hardware retry can just set the counter corresponding to the transmit error
+to 1, if the hardware does support retry then either set these counters to
+0 if the hardware provides no feedback of which errors occurred and how many
+times, or fill in the correct values as reported by the hardware.
+
+Be aware that calling these functions can immediately start a new transmit
+if there is one pending in the queue. So make sure that the hardware is in
+a state where new transmits can be started *before* calling these functions.
+
+The cec_transmit_attempt_done() function is a helper for cases where the
+hardware never retries, so the transmit is always for just a single
+attempt. It will call cec_transmit_done() in turn, filling in 1 for the
+count argument corresponding to the status. Or all 0 if the status was OK.
+
+When a CEC message was received:
+
+.. c:function::
+	void cec_received_msg(struct cec_adapter *adap, struct cec_msg *msg);
+
+Speaks for itself.
+
+Implementing the interrupt handler
+----------------------------------
+
+Typically the CEC hardware provides interrupts that signal when a transmit
+finished and whether it was successful or not, and it provides and interrupt
+when a CEC message was received.
+
+The CEC driver should always process the transmit interrupts first before
+handling the receive interrupt. The framework expects to see the cec_transmit_done
+call before the cec_received_msg call, otherwise it can get confused if the
+received message was in reply to the transmitted message.
+
+Optional: Implementing Error Injection Support
+----------------------------------------------
+
+If the CEC adapter supports Error Injection functionality, then that can
+be exposed through the Error Injection callbacks:
+
+.. code-block:: none
+
+	struct cec_adap_ops {
+		/* Low-level callbacks */
+		...
+
+		/* Error injection callbacks */
+		int (*error_inj_show)(struct cec_adapter *adap, struct seq_file *sf);
+		bool (*error_inj_parse_line)(struct cec_adapter *adap, char *line);
+
+		/* High-level CEC message callback */
+		...
+	};
+
+If both callbacks are set, then an ``error-inj`` file will appear in debugfs.
+The basic syntax is as follows:
+
+Leading spaces/tabs are ignored. If the next character is a ``#`` or the end of the
+line was reached, then the whole line is ignored. Otherwise a command is expected.
+
+This basic parsing is done in the CEC Framework. It is up to the driver to decide
+what commands to implement. The only requirement is that the command ``clear`` without
+any arguments must be implemented and that it will remove all current error injection
+commands.
+
+This ensures that you can always do ``echo clear >error-inj`` to clear any error
+injections without having to know the details of the driver-specific commands.
+
+Note that the output of ``error-inj`` shall be valid as input to ``error-inj``.
+So this must work:
+
+.. code-block:: none
+
+	$ cat error-inj >einj.txt
+	$ cat einj.txt >error-inj
+
+The first callback is called when this file is read and it should show the
+the current error injection state:
+
+.. c:function::
+	int (*error_inj_show)(struct cec_adapter *adap, struct seq_file *sf);
+
+It is recommended that it starts with a comment block with basic usage
+information. It returns 0 for success and an error otherwise.
+
+The second callback will parse commands written to the ``error-inj`` file:
+
+.. c:function::
+	bool (*error_inj_parse_line)(struct cec_adapter *adap, char *line);
+
+The ``line`` argument points to the start of the command. Any leading
+spaces or tabs have already been skipped. It is a single line only (so there
+are no embedded newlines) and it is 0-terminated. The callback is free to
+modify the contents of the buffer. It is only called for lines containing a
+command, so this callback is never called for empty lines or comment lines.
+
+Return true if the command was valid or false if there were syntax errors.
+
+Implementing the High-Level CEC Adapter
+---------------------------------------
+
+The low-level operations drive the hardware, the high-level operations are
+CEC protocol driven. The following high-level callbacks are available:
+
+.. code-block:: none
+
+	struct cec_adap_ops {
+		/* Low-level callbacks */
+		...
+
+		/* Error injection callbacks */
+		...
+
+		/* High-level CEC message callback */
+		int (*received)(struct cec_adapter *adap, struct cec_msg *msg);
+	};
+
+The received() callback allows the driver to optionally handle a newly
+received CEC message
+
+.. c:function::
+	int (*received)(struct cec_adapter *adap, struct cec_msg *msg);
+
+If the driver wants to process a CEC message, then it can implement this
+callback. If it doesn't want to handle this message, then it should return
+-ENOMSG, otherwise the CEC framework assumes it processed this message and
+it will not do anything with it.
+
+
+CEC framework functions
+-----------------------
+
+CEC Adapter drivers can call the following CEC framework functions:
+
+.. c:function::
+	int cec_transmit_msg(struct cec_adapter *adap, struct cec_msg *msg,
+			     bool block);
+
+Transmit a CEC message. If block is true, then wait until the message has been
+transmitted, otherwise just queue it and return.
+
+.. c:function::
+	void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr,
+			     bool block);
+
+Change the physical address. This function will set adap->phys_addr and
+send an event if it has changed. If cec_s_log_addrs() has been called and
+the physical address has become valid, then the CEC framework will start
+claiming the logical addresses. If block is true, then this function won't
+return until this process has finished.
+
+When the physical address is set to a valid value the CEC adapter will
+be enabled (see the adap_enable op). When it is set to CEC_PHYS_ADDR_INVALID,
+then the CEC adapter will be disabled. If you change a valid physical address
+to another valid physical address, then this function will first set the
+address to CEC_PHYS_ADDR_INVALID before enabling the new physical address.
+
+.. c:function::
+	void cec_s_phys_addr_from_edid(struct cec_adapter *adap,
+				       const struct edid *edid);
+
+A helper function that extracts the physical address from the edid struct
+and calls cec_s_phys_addr() with that address, or CEC_PHYS_ADDR_INVALID
+if the EDID did not contain a physical address or edid was a NULL pointer.
+
+.. c:function::
+	int cec_s_log_addrs(struct cec_adapter *adap,
+			    struct cec_log_addrs *log_addrs, bool block);
+
+Claim the CEC logical addresses. Should never be called if CEC_CAP_LOG_ADDRS
+is set. If block is true, then wait until the logical addresses have been
+claimed, otherwise just queue it and return. To unconfigure all logical
+addresses call this function with log_addrs set to NULL or with
+log_addrs->num_log_addrs set to 0. The block argument is ignored when
+unconfiguring. This function will just return if the physical address is
+invalid. Once the physical address becomes valid, then the framework will
+attempt to claim these logical addresses.
+
+CEC Pin framework
+-----------------
+
+Most CEC hardware operates on full CEC messages where the software provides
+the message and the hardware handles the low-level CEC protocol. But some
+hardware only drives the CEC pin and software has to handle the low-level
+CEC protocol. The CEC pin framework was created to handle such devices.
+
+Note that due to the close-to-realtime requirements it can never be guaranteed
+to work 100%. This framework uses highres timers internally, but if a
+timer goes off too late by more than 300 microseconds wrong results can
+occur. In reality it appears to be fairly reliable.
+
+One advantage of this low-level implementation is that it can be used as
+a cheap CEC analyser, especially if interrupts can be used to detect
+CEC pin transitions from low to high or vice versa.
+
+.. kernel-doc:: include/media/cec-pin.h
+
+CEC Notifier framework
+----------------------
+
+Most drm HDMI implementations have an integrated CEC implementation and no
+notifier support is needed. But some have independent CEC implementations
+that have their own driver. This could be an IP block for an SoC or a
+completely separate chip that deals with the CEC pin. For those cases a
+drm driver can install a notifier and use the notifier to inform the
+CEC driver about changes in the physical address.
+
+.. kernel-doc:: include/media/cec-notifier.h
diff --git a/Documentation/driver-api/media/csi2.rst b/Documentation/driver-api/media/csi2.rst
new file mode 100644
index 000000000000..e111ff7bfd3d
--- /dev/null
+++ b/Documentation/driver-api/media/csi2.rst
@@ -0,0 +1,85 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+MIPI CSI-2
+==========
+
+CSI-2 is a data bus intended for transferring images from cameras to
+the host SoC. It is defined by the `MIPI alliance`_.
+
+.. _`MIPI alliance`: http://www.mipi.org/
+
+Transmitter drivers
+-------------------
+
+CSI-2 transmitter, such as a sensor or a TV tuner, drivers need to
+provide the CSI-2 receiver with information on the CSI-2 bus
+configuration. These include the V4L2_CID_LINK_FREQ and
+V4L2_CID_PIXEL_RATE controls and
+(:c:type:`v4l2_subdev_video_ops`->s_stream() callback). These
+interface elements must be present on the sub-device represents the
+CSI-2 transmitter.
+
+The V4L2_CID_LINK_FREQ control is used to tell the receiver driver the
+frequency (and not the symbol rate) of the link. The
+V4L2_CID_PIXEL_RATE is may be used by the receiver to obtain the pixel
+rate the transmitter uses. The
+:c:type:`v4l2_subdev_video_ops`->s_stream() callback provides an
+ability to start and stop the stream.
+
+The value of the V4L2_CID_PIXEL_RATE is calculated as follows::
+
+	pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample
+
+where
+
+.. list-table:: variables in pixel rate calculation
+   :header-rows: 1
+
+   * - variable or constant
+     - description
+   * - link_freq
+     - The value of the V4L2_CID_LINK_FREQ integer64 menu item.
+   * - nr_of_lanes
+     - Number of data lanes used on the CSI-2 link. This can
+       be obtained from the OF endpoint configuration.
+   * - 2
+     - Two bits are transferred per clock cycle per lane.
+   * - bits_per_sample
+     - Number of bits per sample.
+
+The transmitter drivers must, if possible, configure the CSI-2
+transmitter to *LP-11 mode* whenever the transmitter is powered on but
+not active, and maintain *LP-11 mode* until stream on. Only at stream
+on should the transmitter activate the clock on the clock lane and
+transition to *HS mode*.
+
+Some transmitters do this automatically but some have to be explicitly
+programmed to do so, and some are unable to do so altogether due to
+hardware constraints.
+
+Stopping the transmitter
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+A transmitter stops sending the stream of images as a result of
+calling the ``.s_stream()`` callback. Some transmitters may stop the
+stream at a frame boundary whereas others stop immediately,
+effectively leaving the current frame unfinished. The receiver driver
+should not make assumptions either way, but function properly in both
+cases.
+
+Receiver drivers
+----------------
+
+Before the receiver driver may enable the CSI-2 transmitter by using
+the :c:type:`v4l2_subdev_video_ops`->s_stream(), it must have powered
+the transmitter up by using the
+:c:type:`v4l2_subdev_core_ops`->s_power() callback. This may take
+place either indirectly by using :c:func:`v4l2_pipeline_pm_get` or
+directly.
+
+Formats
+-------
+
+The media bus pixel codes document parallel formats. Should the pixel data be
+transported over a serial bus, the media bus pixel code that describes a
+parallel format that transfers a sample on a single clock cycle is used.
diff --git a/Documentation/driver-api/media/drivers/bttv-devel.rst b/Documentation/driver-api/media/drivers/bttv-devel.rst
new file mode 100644
index 000000000000..c9aa8b95a5e5
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/bttv-devel.rst
@@ -0,0 +1,116 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+The bttv driver
+===============
+
+bttv and sound mini howto
+-------------------------
+
+There are a lot of different bt848/849/878/879 based boards available.
+Making video work often is not a big deal, because this is handled
+completely by the bt8xx chip, which is common on all boards.  But
+sound is handled in slightly different ways on each board.
+
+To handle the grabber boards correctly, there is a array tvcards[] in
+bttv-cards.c, which holds the information required for each board.
+Sound will work only, if the correct entry is used (for video it often
+makes no difference).  The bttv driver prints a line to the kernel
+log, telling which card type is used.  Like this one::
+
+	bttv0: model: BT848(Hauppauge old) [autodetected]
+
+You should verify this is correct.  If it isn't, you have to pass the
+correct board type as insmod argument, ``insmod bttv card=2`` for
+example.  The file :doc:`/admin-guide/media/bttv-cardlist` has a list
+of valid arguments for card.
+
+If your card isn't listed there, you might check the source code for
+new entries which are not listed yet.  If there isn't one for your
+card, you can check if one of the existing entries does work for you
+(just trial and error...).
+
+Some boards have an extra processor for sound to do stereo decoding
+and other nice features.  The msp34xx chips are used by Hauppauge for
+example.  If your board has one, you might have to load a helper
+module like ``msp3400`` to make sound work.  If there isn't one for the
+chip used on your board:  Bad luck.  Start writing a new one.  Well,
+you might want to check the video4linux mailing list archive first...
+
+Of course you need a correctly installed soundcard unless you have the
+speakers connected directly to the grabber board.  Hint: check the
+mixer settings too.  ALSA for example has everything muted by default.
+
+
+How sound works in detail
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Still doesn't work?  Looks like some driver hacking is required.
+Below is a do-it-yourself description for you.
+
+The bt8xx chips have 32 general purpose pins, and registers to control
+these pins.  One register is the output enable register
+(``BT848_GPIO_OUT_EN``), it says which pins are actively driven by the
+bt848 chip.  Another one is the data register (``BT848_GPIO_DATA``), where
+you can get/set the status if these pins.  They can be used for input
+and output.
+
+Most grabber board vendors use these pins to control an external chip
+which does the sound routing.  But every board is a little different.
+These pins are also used by some companies to drive remote control
+receiver chips.  Some boards use the i2c bus instead of the gpio pins
+to connect the mux chip.
+
+As mentioned above, there is a array which holds the required
+information for each known board.  You basically have to create a new
+line for your board.  The important fields are these two::
+
+  struct tvcard
+  {
+	[ ... ]
+	u32 gpiomask;
+	u32 audiomux[6]; /* Tuner, Radio, external, internal, mute, stereo */
+  };
+
+gpiomask specifies which pins are used to control the audio mux chip.
+The corresponding bits in the output enable register
+(``BT848_GPIO_OUT_EN``) will be set as these pins must be driven by the
+bt848 chip.
+
+The ``audiomux[]`` array holds the data values for the different inputs
+(i.e. which pins must be high/low for tuner/mute/...).  This will be
+written to the data register (``BT848_GPIO_DATA``) to switch the audio
+mux.
+
+
+What you have to do is figure out the correct values for gpiomask and
+the audiomux array.  If you have Windows and the drivers four your
+card installed, you might to check out if you can read these registers
+values used by the windows driver.  A tool to do this is available
+from http://btwincap.sourceforge.net/download.html.
+
+You might also dig around in the ``*.ini`` files of the Windows applications.
+You can have a look at the board to see which of the gpio pins are
+connected at all and then start trial-and-error ...
+
+
+Starting with release 0.7.41 bttv has a number of insmod options to
+make the gpio debugging easier:
+
+	=================	==============================================
+	bttv_gpio=0/1		enable/disable gpio debug messages
+	gpiomask=n		set the gpiomask value
+	audiomux=i,j,...	set the values of the audiomux array
+	audioall=a		set the values of the audiomux array (one
+				value for all array elements, useful to check
+				out which effect the particular value has).
+	=================	==============================================
+
+The messages printed with ``bttv_gpio=1`` look like this::
+
+	bttv0: gpio: en=00000027, out=00000024 in=00ffffd8 [audio: off]
+
+	en  =	output _en_able register (BT848_GPIO_OUT_EN)
+	out =	_out_put bits of the data register (BT848_GPIO_DATA),
+		i.e. BT848_GPIO_DATA & BT848_GPIO_OUT_EN
+	in  = 	_in_put bits of the data register,
+		i.e. BT848_GPIO_DATA & ~BT848_GPIO_OUT_EN
diff --git a/Documentation/driver-api/media/drivers/contributors.rst b/Documentation/driver-api/media/drivers/contributors.rst
new file mode 100644
index 000000000000..f23b6e6faf46
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/contributors.rst
@@ -0,0 +1,131 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Contributors
+============
+
+.. note::
+
+   This documentation is outdated. There are several other DVB contributors
+   that aren't listed below.
+
+Thanks go to the following people for patches and contributions:
+
+- Michael Hunold <m.hunold@gmx.de>
+
+  - for the initial saa7146 driver and its recent overhaul
+
+- Christian Theiss
+
+  - for his work on the initial Linux DVB driver
+
+- Marcus Metzler <mocm@metzlerbros.de> and
+  Ralph Metzler <rjkm@metzlerbros.de>
+
+  - for their continuing work on the DVB driver
+
+- Michael Holzt <kju@debian.org>
+
+  - for his contributions to the dvb-net driver
+
+- Diego Picciani <d.picciani@novacomp.it>
+
+  - for CyberLogin for Linux which allows logging onto EON
+    (in case you are wondering where CyberLogin is, EON changed its login
+    procedure and CyberLogin is no longer used.)
+
+- Martin Schaller <martin@smurf.franken.de>
+
+  - for patching the cable card decoder driver
+
+- Klaus Schmidinger <Klaus.Schmidinger@cadsoft.de>
+
+  - for various fixes regarding tuning, OSD and CI stuff and his work on VDR
+
+- Steve Brown <sbrown@cortland.com>
+
+  - for his AFC kernel thread
+
+- Christoph Martin <martin@uni-mainz.de>
+
+  - for his LIRC infrared handler
+
+- Andreas Oberritter <obi@linuxtv.org>,
+  Dennis Noermann <dennis.noermann@noernet.de>,
+  Felix Domke <tmbinc@elitedvb.net>,
+  Florian Schirmer <jolt@tuxbox.org>,
+  Ronny Strutz <3des@elitedvb.de>,
+  Wolfram Joost <dbox2@frokaschwei.de>
+  and all the other dbox2 people
+
+  - for many bugfixes in the generic DVB Core, frontend drivers and
+    their work on the dbox2 port of the DVB driver
+
+- Oliver Endriss <o.endriss@gmx.de>
+
+  - for many bugfixes
+
+- Andrew de Quincey <adq_dvb@lidskialf.net>
+
+  - for the tda1004x frontend driver, and various bugfixes
+
+- Peter Schildmann <peter.schildmann@web.de>
+
+  - for the driver for the Technisat SkyStar2 PCI DVB card
+
+- Vadim Catana <skystar@moldova.cc>,
+  Roberto Ragusa <r.ragusa@libero.it> and
+  Augusto Cardoso <augusto@carhil.net>
+
+  - for all the work for the FlexCopII chipset by B2C2,Inc.
+
+- Davor Emard <emard@softhome.net>
+
+  - for his work on the budget drivers, the demux code,
+    the module unloading problems, ...
+
+- Hans-Frieder Vogt <hfvogt@arcor.de>
+
+  - for his work on calculating and checking the crc's for the
+    TechnoTrend/Hauppauge DEC driver firmware
+
+- Michael Dreher <michael@5dot1.de> and
+  Andreas 'randy' Weinberger
+
+  - for the support of the Fujitsu-Siemens Activy budget DVB-S
+
+- Kenneth Aafløy <ke-aa@frisurf.no>
+
+  - for adding support for Typhoon DVB-S budget card
+
+- Ernst Peinlich <e.peinlich@inode.at>
+
+  - for tuning/DiSEqC support for the DEC 3000-s
+
+- Peter Beutner <p.beutner@gmx.net>
+
+  - for the IR code for the ttusb-dec driver
+
+- Wilson Michaels <wilsonmichaels@earthlink.net>
+
+  - for the lgdt330x frontend driver, and various bugfixes
+
+- Michael Krufky <mkrufky@linuxtv.org>
+
+  - for maintaining v4l/dvb inter-tree dependencies
+
+- Taylor Jacob <rtjacob@earthlink.net>
+
+  - for the nxt2002 frontend driver
+
+- Jean-Francois Thibert <jeanfrancois@sagetv.com>
+
+  - for the nxt2004 frontend driver
+
+- Kirk Lapray <kirk.lapray@gmail.com>
+
+  - for the or51211 and or51132 frontend drivers, and
+    for merging the nxt2002 and nxt2004 modules into a
+    single nxt200x frontend driver.
+
+(If you think you should be in this list, but you are not, drop a
+line to the DVB mailing list)
diff --git a/Documentation/driver-api/media/drivers/cpia2_devel.rst b/Documentation/driver-api/media/drivers/cpia2_devel.rst
new file mode 100644
index 000000000000..decaa4768c78
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/cpia2_devel.rst
@@ -0,0 +1,56 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+The cpia2 driver
+================
+
+Authors: Peter Pregler <Peter_Pregler@email.com>,
+Scott J. Bertin <scottbertin@yahoo.com>, and
+Jarl Totland <Jarl.Totland@bdc.no> for the original cpia driver, which
+this one was modelled from.
+
+
+Notes to developers
+~~~~~~~~~~~~~~~~~~~
+
+   - This is a driver version stripped of the 2.4 back compatibility
+     and old MJPEG ioctl API. See cpia2.sf.net for 2.4 support.
+
+Programmer's overview of cpia2 driver
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Cpia2 is the second generation video coprocessor from VLSI Vision Ltd (now a
+division of ST Microelectronics).  There are two versions.  The first is the
+STV0672, which is capable of up to 30 frames per second (fps) in frame sizes
+up to CIF, and 15 fps for VGA frames.  The STV0676 is an improved version,
+which can handle up to 30 fps VGA.  Both coprocessors can be attached to two
+CMOS sensors - the vvl6410 CIF sensor and the vvl6500 VGA sensor.  These will
+be referred to as the 410 and the 500 sensors, or the CIF and VGA sensors.
+
+The two chipsets operate almost identically.  The core is an 8051 processor,
+running two different versions of firmware.  The 672 runs the VP4 video
+processor code, the 676 runs VP5.  There are a few differences in register
+mappings for the two chips.  In these cases, the symbols defined in the
+header files are marked with VP4 or VP5 as part of the symbol name.
+
+The cameras appear externally as three sets of registers. Setting register
+values is the only way to control the camera.  Some settings are
+interdependant, such as the sequence required to power up the camera. I will
+try to make note of all of these cases.
+
+The register sets are called blocks.  Block 0 is the system block.  This
+section is always powered on when the camera is plugged in.  It contains
+registers that control housekeeping functions such as powering up the video
+processor.  The video processor is the VP block.  These registers control
+how the video from the sensor is processed.  Examples are timing registers,
+user mode (vga, qvga), scaling, cropping, framerates, and so on.  The last
+block is the video compressor (VC).  The video stream sent from the camera is
+compressed as Motion JPEG (JPEGA).  The VC controls all of the compression
+parameters.  Looking at the file cpia2_registers.h, you can get a full view
+of these registers and the possible values for most of them.
+
+One or more registers can be set or read by sending a usb control message to
+the camera.  There are three modes for this.  Block mode requests a number
+of contiguous registers.  Random mode reads or writes random registers with
+a tuple structure containing address/value pairs.  The repeat mode is only
+used by VP4 to load a firmware patch.  It contains a starting address and
+a sequence of bytes to be written into a gpio port.
diff --git a/Documentation/driver-api/media/drivers/cx2341x-devel.rst b/Documentation/driver-api/media/drivers/cx2341x-devel.rst
new file mode 100644
index 000000000000..97699df6ea2e
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/cx2341x-devel.rst
@@ -0,0 +1,3685 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+The cx2341x driver
+==================
+
+Memory at cx2341x chips
+-----------------------
+
+This section describes the cx2341x memory map and documents some of the
+register space.
+
+.. note:: the memory long words are little-endian ('intel format').
+
+.. warning::
+
+	This information was figured out from searching through the memory
+	and registers, this information may not be correct and is certainly
+	not complete, and was not derived from anything more than searching
+	through the memory space with commands like:
+
+	.. code-block:: none
+
+		ivtvctl -O min=0x02000000,max=0x020000ff
+
+	So take this as is, I'm always searching for more stuff, it's a large
+	register space :-).
+
+Memory Map
+~~~~~~~~~~
+
+The cx2341x exposes its entire 64M memory space to the PCI host via the PCI BAR0
+(Base Address Register 0). The addresses here are offsets relative to the
+address held in BAR0.
+
+.. code-block:: none
+
+	0x00000000-0x00ffffff Encoder memory space
+	0x00000000-0x0003ffff Encode.rom
+	???-???         MPEG buffer(s)
+	???-???         Raw video capture buffer(s)
+	???-???         Raw audio capture buffer(s)
+	???-???         Display buffers (6 or 9)
+
+	0x01000000-0x01ffffff Decoder memory space
+	0x01000000-0x0103ffff Decode.rom
+	???-???         MPEG buffers(s)
+	0x0114b000-0x0115afff Audio.rom (deprecated?)
+
+	0x02000000-0x0200ffff Register Space
+
+Registers
+~~~~~~~~~
+
+The registers occupy the 64k space starting at the 0x02000000 offset from BAR0.
+All of these registers are 32 bits wide.
+
+.. code-block:: none
+
+	DMA Registers 0x000-0xff:
+
+	0x00 - Control:
+		0=reset/cancel, 1=read, 2=write, 4=stop
+	0x04 - DMA status:
+		1=read busy, 2=write busy, 4=read error, 8=write error, 16=link list error
+	0x08 - pci DMA pointer for read link list
+	0x0c - pci DMA pointer for write link list
+	0x10 - read/write DMA enable:
+		1=read enable, 2=write enable
+	0x14 - always 0xffffffff, if set any lower instability occurs, 0x00 crashes
+	0x18 - ??
+	0x1c - always 0x20 or 32, smaller values slow down DMA transactions
+	0x20 - always value of 0x780a010a
+	0x24-0x3c - usually just random values???
+	0x40 - Interrupt status
+	0x44 - Write a bit here and shows up in Interrupt status 0x40
+	0x48 - Interrupt Mask
+	0x4C - always value of 0xfffdffff,
+		if changed to 0xffffffff DMA write interrupts break.
+	0x50 - always 0xffffffff
+	0x54 - always 0xffffffff (0x4c, 0x50, 0x54 seem like interrupt masks, are
+		3 processors on chip, Java ones, VPU, SPU, APU, maybe these are the
+		interrupt masks???).
+	0x60-0x7C - random values
+	0x80 - first write linked list reg, for Encoder Memory addr
+	0x84 - first write linked list reg, for pci memory addr
+	0x88 - first write linked list reg, for length of buffer in memory addr
+		(|0x80000000 or this for last link)
+	0x8c-0xdc - rest of write linked list reg, 8 sets of 3 total, DMA goes here
+		from linked list addr in reg 0x0c, firmware must push through or
+		something.
+	0xe0 - first (and only) read linked list reg, for pci memory addr
+	0xe4 - first (and only) read linked list reg, for Decoder memory addr
+	0xe8 - first (and only) read linked list reg, for length of buffer
+	0xec-0xff - Nothing seems to be in these registers, 0xec-f4 are 0x00000000.
+
+Memory locations for Encoder Buffers 0x700-0x7ff:
+
+These registers show offsets of memory locations pertaining to each
+buffer area used for encoding, have to shift them by <<1 first.
+
+- 0x07F8: Encoder SDRAM refresh
+- 0x07FC: Encoder SDRAM pre-charge
+
+Memory locations for Decoder Buffers 0x800-0x8ff:
+
+These registers show offsets of memory locations pertaining to each
+buffer area used for decoding, have to shift them by <<1 first.
+
+- 0x08F8: Decoder SDRAM refresh
+- 0x08FC: Decoder SDRAM pre-charge
+
+Other memory locations:
+
+- 0x2800: Video Display Module control
+- 0x2D00: AO (audio output?) control
+- 0x2D24: Bytes Flushed
+- 0x7000: LSB I2C write clock bit (inverted)
+- 0x7004: LSB I2C write data bit (inverted)
+- 0x7008: LSB I2C read clock bit
+- 0x700c: LSB I2C read data bit
+- 0x9008: GPIO get input state
+- 0x900c: GPIO set output state
+- 0x9020: GPIO direction (Bit7 (GPIO 0..7) - 0:input, 1:output)
+- 0x9050: SPU control
+- 0x9054: Reset HW blocks
+- 0x9058: VPU control
+- 0xA018: Bit6: interrupt pending?
+- 0xA064: APU command
+
+
+Interrupt Status Register
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The definition of the bits in the interrupt status register 0x0040, and the
+interrupt mask 0x0048. If a bit is cleared in the mask, then we want our ISR to
+execute.
+
+- bit 31 Encoder Start Capture
+- bit 30 Encoder EOS
+- bit 29 Encoder VBI capture
+- bit 28 Encoder Video Input Module reset event
+- bit 27 Encoder DMA complete
+- bit 24 Decoder audio mode change detection event (through event notification)
+- bit 22 Decoder data request
+- bit 20 Decoder DMA complete
+- bit 19 Decoder VBI re-insertion
+- bit 18 Decoder DMA err (linked-list bad)
+
+Missing documentation
+---------------------
+
+- Encoder API post(?)
+- Decoder API post(?)
+- Decoder VTRACE event
+
+
+The cx2341x firmware upload
+---------------------------
+
+This document describes how to upload the cx2341x firmware to the card.
+
+How to find
+~~~~~~~~~~~
+
+See the web pages of the various projects that uses this chip for information
+on how to obtain the firmware.
+
+The firmware stored in a Windows driver can be detected as follows:
+
+- Each firmware image is 256k bytes.
+- The 1st 32-bit word of the Encoder image is 0x0000da7
+- The 1st 32-bit word of the Decoder image is 0x00003a7
+- The 2nd 32-bit word of both images is 0xaa55bb66
+
+How to load
+~~~~~~~~~~~
+
+- Issue the FWapi command to stop the encoder if it is running. Wait for the
+  command to complete.
+- Issue the FWapi command to stop the decoder if it is running. Wait for the
+  command to complete.
+- Issue the I2C command to the digitizer to stop emitting VSYNC events.
+- Issue the FWapi command to halt the encoder's firmware.
+- Sleep for 10ms.
+- Issue the FWapi command to halt the decoder's firmware.
+- Sleep for 10ms.
+- Write 0x00000000 to register 0x2800 to stop the Video Display Module.
+- Write 0x00000005 to register 0x2D00 to stop the AO (audio output?).
+- Write 0x00000000 to register 0xA064 to ping? the APU.
+- Write 0xFFFFFFFE to register 0x9058 to stop the VPU.
+- Write 0xFFFFFFFF to register 0x9054 to reset the HW blocks.
+- Write 0x00000001 to register 0x9050 to stop the SPU.
+- Sleep for 10ms.
+- Write 0x0000001A to register 0x07FC to init the Encoder SDRAM's pre-charge.
+- Write 0x80000640 to register 0x07F8 to init the Encoder SDRAM's refresh to 1us.
+- Write 0x0000001A to register 0x08FC to init the Decoder SDRAM's pre-charge.
+- Write 0x80000640 to register 0x08F8 to init the Decoder SDRAM's refresh to 1us.
+- Sleep for 512ms. (600ms is recommended)
+- Transfer the encoder's firmware image to offset 0 in Encoder memory space.
+- Transfer the decoder's firmware image to offset 0 in Decoder memory space.
+- Use a read-modify-write operation to Clear bit 0 of register 0x9050 to
+  re-enable the SPU.
+- Sleep for 1 second.
+- Use a read-modify-write operation to Clear bits 3 and 0 of register 0x9058
+  to re-enable the VPU.
+- Sleep for 1 second.
+- Issue status API commands to both firmware images to verify.
+
+
+How to call the firmware API
+----------------------------
+
+The preferred calling convention is known as the firmware mailbox. The
+mailboxes are basically a fixed length array that serves as the call-stack.
+
+Firmware mailboxes can be located by searching the encoder and decoder memory
+for a 16 byte signature. That signature will be located on a 256-byte boundary.
+
+Signature:
+
+.. code-block:: none
+
+	0x78, 0x56, 0x34, 0x12, 0x12, 0x78, 0x56, 0x34,
+	0x34, 0x12, 0x78, 0x56, 0x56, 0x34, 0x12, 0x78
+
+The firmware implements 20 mailboxes of 20 32-bit words. The first 10 are
+reserved for API calls. The second 10 are used by the firmware for event
+notification.
+
+  ====== =================
+  Index  Name
+  ====== =================
+  0      Flags
+  1      Command
+  2      Return value
+  3      Timeout
+  4-19   Parameter/Result
+  ====== =================
+
+
+The flags are defined in the following table. The direction is from the
+perspective of the firmware.
+
+  ==== ========== ============================================
+  Bit  Direction  Purpose
+  ==== ========== ============================================
+  2    O          Firmware has processed the command.
+  1    I          Driver has finished setting the parameters.
+  0    I          Driver is using this mailbox.
+  ==== ========== ============================================
+
+The command is a 32-bit enumerator. The API specifics may be found in this
+chapter.
+
+The return value is a 32-bit enumerator. Only two values are currently defined:
+
+- 0=success
+- -1=command undefined.
+
+There are 16 parameters/results 32-bit fields. The driver populates these fields
+with values for all the parameters required by the call. The driver overwrites
+these fields with result values returned by the call.
+
+The timeout value protects the card from a hung driver thread. If the driver
+doesn't handle the completed call within the timeout specified, the firmware
+will reset that mailbox.
+
+To make an API call, the driver iterates over each mailbox looking for the
+first one available (bit 0 has been cleared). The driver sets that bit, fills
+in the command enumerator, the timeout value and any required parameters. The
+driver then sets the parameter ready bit (bit 1). The firmware scans the
+mailboxes for pending commands, processes them, sets the result code, populates
+the result value array with that call's return values and sets the call
+complete bit (bit 2). Once bit 2 is set, the driver should retrieve the results
+and clear all the flags. If the driver does not perform this task within the
+time set in the timeout register, the firmware will reset that mailbox.
+
+Event notifications are sent from the firmware to the host. The host tells the
+firmware which events it is interested in via an API call. That call tells the
+firmware which notification mailbox to use. The firmware signals the host via
+an interrupt. Only the 16 Results fields are used, the Flags, Command, Return
+value and Timeout words are not used.
+
+
+OSD firmware API description
+----------------------------
+
+.. note:: this API is part of the decoder firmware, so it's cx23415 only.
+
+
+
+CX2341X_OSD_GET_FRAMEBUFFER
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 65/0x41
+
+Description
+^^^^^^^^^^^
+
+Return base and length of contiguous OSD memory.
+
+Result[0]
+^^^^^^^^^
+
+OSD base address
+
+Result[1]
+^^^^^^^^^
+
+OSD length
+
+
+
+CX2341X_OSD_GET_PIXEL_FORMAT
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 66/0x42
+
+Description
+^^^^^^^^^^^
+
+Query OSD format
+
+Result[0]
+^^^^^^^^^
+
+0=8bit index
+1=16bit RGB 5:6:5
+2=16bit ARGB 1:5:5:5
+3=16bit ARGB 1:4:4:4
+4=32bit ARGB 8:8:8:8
+
+
+
+CX2341X_OSD_SET_PIXEL_FORMAT
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 67/0x43
+
+Description
+^^^^^^^^^^^
+
+Assign pixel format
+
+Param[0]
+^^^^^^^^
+
+- 0=8bit index
+- 1=16bit RGB 5:6:5
+- 2=16bit ARGB 1:5:5:5
+- 3=16bit ARGB 1:4:4:4
+- 4=32bit ARGB 8:8:8:8
+
+
+
+CX2341X_OSD_GET_STATE
+~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 68/0x44
+
+Description
+^^^^^^^^^^^
+
+Query OSD state
+
+Result[0]
+^^^^^^^^^
+
+- Bit  0   0=off, 1=on
+- Bits 1:2 alpha control
+- Bits 3:5 pixel format
+
+
+
+CX2341X_OSD_SET_STATE
+~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 69/0x45
+
+Description
+^^^^^^^^^^^
+
+OSD switch
+
+Param[0]
+^^^^^^^^
+
+0=off, 1=on
+
+
+
+CX2341X_OSD_GET_OSD_COORDS
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 70/0x46
+
+Description
+^^^^^^^^^^^
+
+Retrieve coordinates of OSD area blended with video
+
+Result[0]
+^^^^^^^^^
+
+OSD buffer address
+
+Result[1]
+^^^^^^^^^
+
+Stride in pixels
+
+Result[2]
+^^^^^^^^^
+
+Lines in OSD buffer
+
+Result[3]
+^^^^^^^^^
+
+Horizontal offset in buffer
+
+Result[4]
+^^^^^^^^^
+
+Vertical offset in buffer
+
+
+
+CX2341X_OSD_SET_OSD_COORDS
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 71/0x47
+
+Description
+^^^^^^^^^^^
+
+Assign the coordinates of the OSD area to blend with video
+
+Param[0]
+^^^^^^^^
+
+buffer address
+
+Param[1]
+^^^^^^^^
+
+buffer stride in pixels
+
+Param[2]
+^^^^^^^^
+
+lines in buffer
+
+Param[3]
+^^^^^^^^
+
+horizontal offset
+
+Param[4]
+^^^^^^^^
+
+vertical offset
+
+
+
+CX2341X_OSD_GET_SCREEN_COORDS
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 72/0x48
+
+Description
+^^^^^^^^^^^
+
+Retrieve OSD screen area coordinates
+
+Result[0]
+^^^^^^^^^
+
+top left horizontal offset
+
+Result[1]
+^^^^^^^^^
+
+top left vertical offset
+
+Result[2]
+^^^^^^^^^
+
+bottom right horizontal offset
+
+Result[3]
+^^^^^^^^^
+
+bottom right vertical offset
+
+
+
+CX2341X_OSD_SET_SCREEN_COORDS
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 73/0x49
+
+Description
+^^^^^^^^^^^
+
+Assign the coordinates of the screen area to blend with video
+
+Param[0]
+^^^^^^^^
+
+top left horizontal offset
+
+Param[1]
+^^^^^^^^
+
+top left vertical offset
+
+Param[2]
+^^^^^^^^
+
+bottom left horizontal offset
+
+Param[3]
+^^^^^^^^
+
+bottom left vertical offset
+
+
+
+CX2341X_OSD_GET_GLOBAL_ALPHA
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 74/0x4A
+
+Description
+^^^^^^^^^^^
+
+Retrieve OSD global alpha
+
+Result[0]
+^^^^^^^^^
+
+global alpha: 0=off, 1=on
+
+Result[1]
+^^^^^^^^^
+
+bits 0:7 global alpha
+
+
+
+CX2341X_OSD_SET_GLOBAL_ALPHA
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 75/0x4B
+
+Description
+^^^^^^^^^^^
+
+Update global alpha
+
+Param[0]
+^^^^^^^^
+
+global alpha: 0=off, 1=on
+
+Param[1]
+^^^^^^^^
+
+global alpha (8 bits)
+
+Param[2]
+^^^^^^^^
+
+local alpha: 0=on, 1=off
+
+
+
+CX2341X_OSD_SET_BLEND_COORDS
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 78/0x4C
+
+Description
+^^^^^^^^^^^
+
+Move start of blending area within display buffer
+
+Param[0]
+^^^^^^^^
+
+horizontal offset in buffer
+
+Param[1]
+^^^^^^^^
+
+vertical offset in buffer
+
+
+
+CX2341X_OSD_GET_FLICKER_STATE
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 79/0x4F
+
+Description
+^^^^^^^^^^^
+
+Retrieve flicker reduction module state
+
+Result[0]
+^^^^^^^^^
+
+flicker state: 0=off, 1=on
+
+
+
+CX2341X_OSD_SET_FLICKER_STATE
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 80/0x50
+
+Description
+^^^^^^^^^^^
+
+Set flicker reduction module state
+
+Param[0]
+^^^^^^^^
+
+State: 0=off, 1=on
+
+
+
+CX2341X_OSD_BLT_COPY
+~~~~~~~~~~~~~~~~~~~~
+
+Enum: 82/0x52
+
+Description
+^^^^^^^^^^^
+
+BLT copy
+
+Param[0]
+^^^^^^^^
+
+.. code-block:: none
+
+	'0000'  zero
+	'0001' ~destination AND ~source
+	'0010' ~destination AND  source
+	'0011' ~destination
+	'0100'  destination AND ~source
+	'0101'                  ~source
+	'0110'  destination XOR  source
+	'0111' ~destination OR  ~source
+	'1000' ~destination AND ~source
+	'1001'  destination XNOR source
+	'1010'                   source
+	'1011' ~destination OR   source
+	'1100'  destination
+	'1101'  destination OR  ~source
+	'1110'  destination OR   source
+	'1111'  one
+
+
+Param[1]
+^^^^^^^^
+
+Resulting alpha blending
+
+- '01' source_alpha
+- '10' destination_alpha
+- '11' source_alpha*destination_alpha+1
+  (zero if both source and destination alpha are zero)
+
+Param[2]
+^^^^^^^^
+
+.. code-block:: none
+
+	'00' output_pixel = source_pixel
+
+	'01' if source_alpha=0:
+		 output_pixel = destination_pixel
+	     if 256 > source_alpha > 1:
+		 output_pixel = ((source_alpha + 1)*source_pixel +
+				 (255 - source_alpha)*destination_pixel)/256
+
+	'10' if destination_alpha=0:
+		 output_pixel = source_pixel
+	      if 255 > destination_alpha > 0:
+		 output_pixel = ((255 - destination_alpha)*source_pixel +
+				 (destination_alpha + 1)*destination_pixel)/256
+
+	'11' if source_alpha=0:
+		 source_temp = 0
+	     if source_alpha=255:
+		 source_temp = source_pixel*256
+	     if 255 > source_alpha > 0:
+		 source_temp = source_pixel*(source_alpha + 1)
+	     if destination_alpha=0:
+		 destination_temp = 0
+	     if destination_alpha=255:
+		 destination_temp = destination_pixel*256
+	     if 255 > destination_alpha > 0:
+		 destination_temp = destination_pixel*(destination_alpha + 1)
+	     output_pixel = (source_temp + destination_temp)/256
+
+Param[3]
+^^^^^^^^
+
+width
+
+Param[4]
+^^^^^^^^
+
+height
+
+Param[5]
+^^^^^^^^
+
+destination pixel mask
+
+Param[6]
+^^^^^^^^
+
+destination rectangle start address
+
+Param[7]
+^^^^^^^^
+
+destination stride in dwords
+
+Param[8]
+^^^^^^^^
+
+source stride in dwords
+
+Param[9]
+^^^^^^^^
+
+source rectangle start address
+
+
+
+CX2341X_OSD_BLT_FILL
+~~~~~~~~~~~~~~~~~~~~
+
+Enum: 83/0x53
+
+Description
+^^^^^^^^^^^
+
+BLT fill color
+
+Param[0]
+^^^^^^^^
+
+Same as Param[0] on API 0x52
+
+Param[1]
+^^^^^^^^
+
+Same as Param[1] on API 0x52
+
+Param[2]
+^^^^^^^^
+
+Same as Param[2] on API 0x52
+
+Param[3]
+^^^^^^^^
+
+width
+
+Param[4]
+^^^^^^^^
+
+height
+
+Param[5]
+^^^^^^^^
+
+destination pixel mask
+
+Param[6]
+^^^^^^^^
+
+destination rectangle start address
+
+Param[7]
+^^^^^^^^
+
+destination stride in dwords
+
+Param[8]
+^^^^^^^^
+
+color fill value
+
+
+
+CX2341X_OSD_BLT_TEXT
+~~~~~~~~~~~~~~~~~~~~
+
+Enum: 84/0x54
+
+Description
+^^^^^^^^^^^
+
+BLT for 8 bit alpha text source
+
+Param[0]
+^^^^^^^^
+
+Same as Param[0] on API 0x52
+
+Param[1]
+^^^^^^^^
+
+Same as Param[1] on API 0x52
+
+Param[2]
+^^^^^^^^
+
+Same as Param[2] on API 0x52
+
+Param[3]
+^^^^^^^^
+
+width
+
+Param[4]
+^^^^^^^^
+
+height
+
+Param[5]
+^^^^^^^^
+
+destination pixel mask
+
+Param[6]
+^^^^^^^^
+
+destination rectangle start address
+
+Param[7]
+^^^^^^^^
+
+destination stride in dwords
+
+Param[8]
+^^^^^^^^
+
+source stride in dwords
+
+Param[9]
+^^^^^^^^
+
+source rectangle start address
+
+Param[10]
+^^^^^^^^^
+
+color fill value
+
+
+
+CX2341X_OSD_SET_FRAMEBUFFER_WINDOW
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 86/0x56
+
+Description
+^^^^^^^^^^^
+
+Positions the main output window on the screen. The coordinates must be
+such that the entire window fits on the screen.
+
+Param[0]
+^^^^^^^^
+
+window width
+
+Param[1]
+^^^^^^^^
+
+window height
+
+Param[2]
+^^^^^^^^
+
+top left window corner horizontal offset
+
+Param[3]
+^^^^^^^^
+
+top left window corner vertical offset
+
+
+
+CX2341X_OSD_SET_CHROMA_KEY
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 96/0x60
+
+Description
+^^^^^^^^^^^
+
+Chroma key switch and color
+
+Param[0]
+^^^^^^^^
+
+state: 0=off, 1=on
+
+Param[1]
+^^^^^^^^
+
+color
+
+
+
+CX2341X_OSD_GET_ALPHA_CONTENT_INDEX
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 97/0x61
+
+Description
+^^^^^^^^^^^
+
+Retrieve alpha content index
+
+Result[0]
+^^^^^^^^^
+
+alpha content index, Range 0:15
+
+
+
+CX2341X_OSD_SET_ALPHA_CONTENT_INDEX
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 98/0x62
+
+Description
+^^^^^^^^^^^
+
+Assign alpha content index
+
+Param[0]
+^^^^^^^^
+
+alpha content index, range 0:15
+
+
+Encoder firmware API description
+--------------------------------
+
+CX2341X_ENC_PING_FW
+~~~~~~~~~~~~~~~~~~~
+
+Enum: 128/0x80
+
+Description
+^^^^^^^^^^^
+
+Does nothing. Can be used to check if the firmware is responding.
+
+
+
+CX2341X_ENC_START_CAPTURE
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 129/0x81
+
+Description
+^^^^^^^^^^^
+
+Commences the capture of video, audio and/or VBI data. All encoding
+parameters must be initialized prior to this API call. Captures frames
+continuously or until a predefined number of frames have been captured.
+
+Param[0]
+^^^^^^^^
+
+Capture stream type:
+
+	- 0=MPEG
+	- 1=Raw
+	- 2=Raw passthrough
+	- 3=VBI
+
+
+Param[1]
+^^^^^^^^
+
+Bitmask:
+
+	- Bit 0 when set, captures YUV
+	- Bit 1 when set, captures PCM audio
+	- Bit 2 when set, captures VBI (same as param[0]=3)
+	- Bit 3 when set, the capture destination is the decoder
+	  (same as param[0]=2)
+	- Bit 4 when set, the capture destination is the host
+
+.. note:: this parameter is only meaningful for RAW capture type.
+
+
+
+CX2341X_ENC_STOP_CAPTURE
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 130/0x82
+
+Description
+^^^^^^^^^^^
+
+Ends a capture in progress
+
+Param[0]
+^^^^^^^^
+
+- 0=stop at end of GOP (generates IRQ)
+- 1=stop immediate (no IRQ)
+
+Param[1]
+^^^^^^^^
+
+Stream type to stop, see param[0] of API 0x81
+
+Param[2]
+^^^^^^^^
+
+Subtype, see param[1] of API 0x81
+
+
+
+CX2341X_ENC_SET_AUDIO_ID
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 137/0x89
+
+Description
+^^^^^^^^^^^
+
+Assigns the transport stream ID of the encoded audio stream
+
+Param[0]
+^^^^^^^^
+
+Audio Stream ID
+
+
+
+CX2341X_ENC_SET_VIDEO_ID
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 139/0x8B
+
+Description
+^^^^^^^^^^^
+
+Set video transport stream ID
+
+Param[0]
+^^^^^^^^
+
+Video stream ID
+
+
+
+CX2341X_ENC_SET_PCR_ID
+~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 141/0x8D
+
+Description
+^^^^^^^^^^^
+
+Assigns the transport stream ID for PCR packets
+
+Param[0]
+^^^^^^^^
+
+PCR Stream ID
+
+
+
+CX2341X_ENC_SET_FRAME_RATE
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 143/0x8F
+
+Description
+^^^^^^^^^^^
+
+Set video frames per second. Change occurs at start of new GOP.
+
+Param[0]
+^^^^^^^^
+
+- 0=30fps
+- 1=25fps
+
+
+
+CX2341X_ENC_SET_FRAME_SIZE
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 145/0x91
+
+Description
+^^^^^^^^^^^
+
+Select video stream encoding resolution.
+
+Param[0]
+^^^^^^^^
+
+Height in lines. Default 480
+
+Param[1]
+^^^^^^^^
+
+Width in pixels. Default 720
+
+
+
+CX2341X_ENC_SET_BIT_RATE
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 149/0x95
+
+Description
+^^^^^^^^^^^
+
+Assign average video stream bitrate.
+
+Param[0]
+^^^^^^^^
+
+0=variable bitrate, 1=constant bitrate
+
+Param[1]
+^^^^^^^^
+
+bitrate in bits per second
+
+Param[2]
+^^^^^^^^
+
+peak bitrate in bits per second, divided by 400
+
+Param[3]
+^^^^^^^^
+
+Mux bitrate in bits per second, divided by 400. May be 0 (default).
+
+Param[4]
+^^^^^^^^
+
+Rate Control VBR Padding
+
+Param[5]
+^^^^^^^^
+
+VBV Buffer used by encoder
+
+.. note::
+
+	#) Param\[3\] and Param\[4\] seem to be always 0
+	#) Param\[5\] doesn't seem to be used.
+
+
+
+CX2341X_ENC_SET_GOP_PROPERTIES
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 151/0x97
+
+Description
+^^^^^^^^^^^
+
+Setup the GOP structure
+
+Param[0]
+^^^^^^^^
+
+GOP size (maximum is 34)
+
+Param[1]
+^^^^^^^^
+
+Number of B frames between the I and P frame, plus 1.
+For example: IBBPBBPBBPBB --> GOP size: 12, number of B frames: 2+1 = 3
+
+.. note::
+
+	GOP size must be a multiple of (B-frames + 1).
+
+
+
+CX2341X_ENC_SET_ASPECT_RATIO
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 153/0x99
+
+Description
+^^^^^^^^^^^
+
+Sets the encoding aspect ratio. Changes in the aspect ratio take effect
+at the start of the next GOP.
+
+Param[0]
+^^^^^^^^
+
+- '0000' forbidden
+- '0001' 1:1 square
+- '0010' 4:3
+- '0011' 16:9
+- '0100' 2.21:1
+- '0101' to '1111' reserved
+
+
+
+CX2341X_ENC_SET_DNR_FILTER_MODE
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 155/0x9B
+
+Description
+^^^^^^^^^^^
+
+Assign Dynamic Noise Reduction operating mode
+
+Param[0]
+^^^^^^^^
+
+Bit0: Spatial filter, set=auto, clear=manual
+Bit1: Temporal filter, set=auto, clear=manual
+
+Param[1]
+^^^^^^^^
+
+Median filter:
+
+- 0=Disabled
+- 1=Horizontal
+- 2=Vertical
+- 3=Horiz/Vert
+- 4=Diagonal
+
+
+
+CX2341X_ENC_SET_DNR_FILTER_PROPS
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 157/0x9D
+
+Description
+^^^^^^^^^^^
+
+These Dynamic Noise Reduction filter values are only meaningful when
+the respective filter is set to "manual" (See API 0x9B)
+
+Param[0]
+^^^^^^^^
+
+Spatial filter: default 0, range 0:15
+
+Param[1]
+^^^^^^^^
+
+Temporal filter: default 0, range 0:31
+
+
+
+CX2341X_ENC_SET_CORING_LEVELS
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 159/0x9F
+
+Description
+^^^^^^^^^^^
+
+Assign Dynamic Noise Reduction median filter properties.
+
+Param[0]
+^^^^^^^^
+
+Threshold above which the luminance median filter is enabled.
+Default: 0, range 0:255
+
+Param[1]
+^^^^^^^^
+
+Threshold below which the luminance median filter is enabled.
+Default: 255, range 0:255
+
+Param[2]
+^^^^^^^^
+
+Threshold above which the chrominance median filter is enabled.
+Default: 0, range 0:255
+
+Param[3]
+^^^^^^^^
+
+Threshold below which the chrominance median filter is enabled.
+Default: 255, range 0:255
+
+
+
+CX2341X_ENC_SET_SPATIAL_FILTER_TYPE
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 161/0xA1
+
+Description
+^^^^^^^^^^^
+
+Assign spatial prefilter parameters
+
+Param[0]
+^^^^^^^^
+
+Luminance filter
+
+- 0=Off
+- 1=1D Horizontal
+- 2=1D Vertical
+- 3=2D H/V Separable (default)
+- 4=2D Symmetric non-separable
+
+Param[1]
+^^^^^^^^
+
+Chrominance filter
+
+- 0=Off
+- 1=1D Horizontal (default)
+
+
+
+CX2341X_ENC_SET_VBI_LINE
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 183/0xB7
+
+Description
+^^^^^^^^^^^
+
+Selects VBI line number.
+
+Param[0]
+^^^^^^^^
+
+- Bits 0:4 	line number
+- Bit  31		0=top_field, 1=bottom_field
+- Bits 0:31 	all set specifies "all lines"
+
+Param[1]
+^^^^^^^^
+
+VBI line information features: 0=disabled, 1=enabled
+
+Param[2]
+^^^^^^^^
+
+Slicing: 0=None, 1=Closed Caption
+Almost certainly not implemented. Set to 0.
+
+Param[3]
+^^^^^^^^
+
+Luminance samples in this line.
+Almost certainly not implemented. Set to 0.
+
+Param[4]
+^^^^^^^^
+
+Chrominance samples in this line
+Almost certainly not implemented. Set to 0.
+
+
+
+CX2341X_ENC_SET_STREAM_TYPE
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 185/0xB9
+
+Description
+^^^^^^^^^^^
+
+Assign stream type
+
+.. note::
+
+	Transport stream is not working in recent firmwares.
+	And in older firmwares the timestamps in the TS seem to be
+	unreliable.
+
+Param[0]
+^^^^^^^^
+
+- 0=Program stream
+- 1=Transport stream
+- 2=MPEG1 stream
+- 3=PES A/V stream
+- 5=PES Video stream
+- 7=PES Audio stream
+- 10=DVD stream
+- 11=VCD stream
+- 12=SVCD stream
+- 13=DVD_S1 stream
+- 14=DVD_S2 stream
+
+
+
+CX2341X_ENC_SET_OUTPUT_PORT
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 187/0xBB
+
+Description
+^^^^^^^^^^^
+
+Assign stream output port. Normally 0 when the data is copied through
+the PCI bus (DMA), and 1 when the data is streamed to another chip
+(pvrusb and cx88-blackbird).
+
+Param[0]
+^^^^^^^^
+
+- 0=Memory (default)
+- 1=Streaming
+- 2=Serial
+
+Param[1]
+^^^^^^^^
+
+Unknown, but leaving this to 0 seems to work best. Indications are that
+this might have to do with USB support, although passing anything but 0
+only breaks things.
+
+
+
+CX2341X_ENC_SET_AUDIO_PROPERTIES
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 189/0xBD
+
+Description
+^^^^^^^^^^^
+
+Set audio stream properties, may be called while encoding is in progress.
+
+.. note::
+
+	All bitfields are consistent with ISO11172 documentation except
+	bits 2:3 which ISO docs define as:
+
+	- '11' Layer I
+	- '10' Layer II
+	- '01' Layer III
+	- '00' Undefined
+
+	This discrepancy may indicate a possible error in the documentation.
+	Testing indicated that only Layer II is actually working, and that
+	the minimum bitrate should be 192 kbps.
+
+Param[0]
+^^^^^^^^
+
+Bitmask:
+
+.. code-block:: none
+
+	   0:1  '00' 44.1Khz
+		'01' 48Khz
+		'10' 32Khz
+		'11' reserved
+
+	   2:3  '01'=Layer I
+		'10'=Layer II
+
+	   4:7  Bitrate:
+		     Index | Layer I     | Layer II
+		     ------+-------------+------------
+		    '0000' | free format | free format
+		    '0001' |  32 kbit/s  |  32 kbit/s
+		    '0010' |  64 kbit/s  |  48 kbit/s
+		    '0011' |  96 kbit/s  |  56 kbit/s
+		    '0100' | 128 kbit/s  |  64 kbit/s
+		    '0101' | 160 kbit/s  |  80 kbit/s
+		    '0110' | 192 kbit/s  |  96 kbit/s
+		    '0111' | 224 kbit/s  | 112 kbit/s
+		    '1000' | 256 kbit/s  | 128 kbit/s
+		    '1001' | 288 kbit/s  | 160 kbit/s
+		    '1010' | 320 kbit/s  | 192 kbit/s
+		    '1011' | 352 kbit/s  | 224 kbit/s
+		    '1100' | 384 kbit/s  | 256 kbit/s
+		    '1101' | 416 kbit/s  | 320 kbit/s
+		    '1110' | 448 kbit/s  | 384 kbit/s
+
+		.. note::
+
+			For Layer II, not all combinations of total bitrate
+			and mode are allowed. See ISO11172-3 3-Annex B,
+			Table 3-B.2
+
+	   8:9  '00'=Stereo
+		'01'=JointStereo
+		'10'=Dual
+		'11'=Mono
+
+		.. note::
+
+			The cx23415 cannot decode Joint Stereo properly.
+
+	  10:11 Mode Extension used in joint_stereo mode.
+		In Layer I and II they indicate which subbands are in
+		intensity_stereo. All other subbands are coded in stereo.
+		    '00' subbands 4-31 in intensity_stereo, bound==4
+		    '01' subbands 8-31 in intensity_stereo, bound==8
+		    '10' subbands 12-31 in intensity_stereo, bound==12
+		    '11' subbands 16-31 in intensity_stereo, bound==16
+
+	  12:13 Emphasis:
+		    '00' None
+		    '01' 50/15uS
+		    '10' reserved
+		    '11' CCITT J.17
+
+	  14 	CRC:
+		    '0' off
+		    '1' on
+
+	  15    Copyright:
+		    '0' off
+		    '1' on
+
+	  16    Generation:
+		    '0' copy
+		    '1' original
+
+
+
+CX2341X_ENC_HALT_FW
+~~~~~~~~~~~~~~~~~~~
+
+Enum: 195/0xC3
+
+Description
+^^^^^^^^^^^
+
+The firmware is halted and no further API calls are serviced until the
+firmware is uploaded again.
+
+
+
+CX2341X_ENC_GET_VERSION
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 196/0xC4
+
+Description
+^^^^^^^^^^^
+
+Returns the version of the encoder firmware.
+
+Result[0]
+^^^^^^^^^
+
+Version bitmask:
+- Bits  0:15 build
+- Bits 16:23 minor
+- Bits 24:31 major
+
+
+
+CX2341X_ENC_SET_GOP_CLOSURE
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 197/0xC5
+
+Description
+^^^^^^^^^^^
+
+Assigns the GOP open/close property.
+
+Param[0]
+^^^^^^^^
+
+- 0=Open
+- 1=Closed
+
+
+
+CX2341X_ENC_GET_SEQ_END
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 198/0xC6
+
+Description
+^^^^^^^^^^^
+
+Obtains the sequence end code of the encoder's buffer. When a capture
+is started a number of interrupts are still generated, the last of
+which will have Result[0] set to 1 and Result[1] will contain the size
+of the buffer.
+
+Result[0]
+^^^^^^^^^
+
+State of the transfer (1 if last buffer)
+
+Result[1]
+^^^^^^^^^
+
+If Result[0] is 1, this contains the size of the last buffer, undefined
+otherwise.
+
+
+
+CX2341X_ENC_SET_PGM_INDEX_INFO
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 199/0xC7
+
+Description
+^^^^^^^^^^^
+
+Sets the Program Index Information.
+The information is stored as follows:
+
+.. code-block:: c
+
+	struct info {
+		u32 length;		// Length of this frame
+		u32 offset_low;		// Offset in the file of the
+		u32 offset_high;	// start of this frame
+		u32 mask1;		// Bits 0-2 are the type mask:
+					// 1=I, 2=P, 4=B
+					// 0=End of Program Index, other fields
+					//   are invalid.
+		u32 pts;		// The PTS of the frame
+		u32 mask2;		// Bit 0 is bit 32 of the pts.
+	};
+	u32 table_ptr;
+	struct info index[400];
+
+The table_ptr is the encoder memory address in the table were
+*new* entries will be written.
+
+.. note:: This is a ringbuffer, so the table_ptr will wraparound.
+
+Param[0]
+^^^^^^^^
+
+Picture Mask:
+- 0=No index capture
+- 1=I frames
+- 3=I,P frames
+- 7=I,P,B frames
+
+(Seems to be ignored, it always indexes I, P and B frames)
+
+Param[1]
+^^^^^^^^
+
+Elements requested (up to 400)
+
+Result[0]
+^^^^^^^^^
+
+Offset in the encoder memory of the start of the table.
+
+Result[1]
+^^^^^^^^^
+
+Number of allocated elements up to a maximum of Param[1]
+
+
+
+CX2341X_ENC_SET_VBI_CONFIG
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 200/0xC8
+
+Description
+^^^^^^^^^^^
+
+Configure VBI settings
+
+Param[0]
+^^^^^^^^
+
+Bitmap:
+
+.. code-block:: none
+
+	    0    Mode '0' Sliced, '1' Raw
+	    1:3  Insertion:
+		     '000' insert in extension & user data
+		     '001' insert in private packets
+		     '010' separate stream and user data
+		     '111' separate stream and private data
+	    8:15 Stream ID (normally 0xBD)
+
+Param[1]
+^^^^^^^^
+
+Frames per interrupt (max 8). Only valid in raw mode.
+
+Param[2]
+^^^^^^^^
+
+Total raw VBI frames. Only valid in raw mode.
+
+Param[3]
+^^^^^^^^
+
+Start codes
+
+Param[4]
+^^^^^^^^
+
+Stop codes
+
+Param[5]
+^^^^^^^^
+
+Lines per frame
+
+Param[6]
+^^^^^^^^
+
+Byte per line
+
+Result[0]
+^^^^^^^^^
+
+Observed frames per interrupt in raw mode only. Rage 1 to Param[1]
+
+Result[1]
+^^^^^^^^^
+
+Observed number of frames in raw mode. Range 1 to Param[2]
+
+Result[2]
+^^^^^^^^^
+
+Memory offset to start or raw VBI data
+
+
+
+CX2341X_ENC_SET_DMA_BLOCK_SIZE
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 201/0xC9
+
+Description
+^^^^^^^^^^^
+
+Set DMA transfer block size
+
+Param[0]
+^^^^^^^^
+
+DMA transfer block size in bytes or frames. When unit is bytes,
+supported block sizes are 2^7, 2^8 and 2^9 bytes.
+
+Param[1]
+^^^^^^^^
+
+Unit: 0=bytes, 1=frames
+
+
+
+CX2341X_ENC_GET_PREV_DMA_INFO_MB_10
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 202/0xCA
+
+Description
+^^^^^^^^^^^
+
+Returns information on the previous DMA transfer in conjunction with
+bit 27 of the interrupt mask. Uses mailbox 10.
+
+Result[0]
+^^^^^^^^^
+
+Type of stream
+
+Result[1]
+^^^^^^^^^
+
+Address Offset
+
+Result[2]
+^^^^^^^^^
+
+Maximum size of transfer
+
+
+
+CX2341X_ENC_GET_PREV_DMA_INFO_MB_9
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 203/0xCB
+
+Description
+^^^^^^^^^^^
+
+Returns information on the previous DMA transfer in conjunction with
+bit 27 or 18 of the interrupt mask. Uses mailbox 9.
+
+Result[0]
+^^^^^^^^^
+
+Status bits:
+- 0   read completed
+- 1   write completed
+- 2   DMA read error
+- 3   DMA write error
+- 4   Scatter-Gather array error
+
+Result[1]
+^^^^^^^^^
+
+DMA type
+
+Result[2]
+^^^^^^^^^
+
+Presentation Time Stamp bits 0..31
+
+Result[3]
+^^^^^^^^^
+
+Presentation Time Stamp bit 32
+
+
+
+CX2341X_ENC_SCHED_DMA_TO_HOST
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 204/0xCC
+
+Description
+^^^^^^^^^^^
+
+Setup DMA to host operation
+
+Param[0]
+^^^^^^^^
+
+Memory address of link list
+
+Param[1]
+^^^^^^^^
+
+Length of link list (wtf: what units ???)
+
+Param[2]
+^^^^^^^^
+
+DMA type (0=MPEG)
+
+
+
+CX2341X_ENC_INITIALIZE_INPUT
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 205/0xCD
+
+Description
+^^^^^^^^^^^
+
+Initializes the video input
+
+
+
+CX2341X_ENC_SET_FRAME_DROP_RATE
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 208/0xD0
+
+Description
+^^^^^^^^^^^
+
+For each frame captured, skip specified number of frames.
+
+Param[0]
+^^^^^^^^
+
+Number of frames to skip
+
+
+
+CX2341X_ENC_PAUSE_ENCODER
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 210/0xD2
+
+Description
+^^^^^^^^^^^
+
+During a pause condition, all frames are dropped instead of being encoded.
+
+Param[0]
+^^^^^^^^
+
+- 0=Pause encoding
+- 1=Continue encoding
+
+
+
+CX2341X_ENC_REFRESH_INPUT
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 211/0xD3
+
+Description
+^^^^^^^^^^^
+
+Refreshes the video input
+
+
+
+CX2341X_ENC_SET_COPYRIGHT
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 212/0xD4
+
+Description
+^^^^^^^^^^^
+
+Sets stream copyright property
+
+Param[0]
+^^^^^^^^
+
+
+- 0=Stream is not copyrighted
+- 1=Stream is copyrighted
+
+
+
+CX2341X_ENC_SET_EVENT_NOTIFICATION
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 213/0xD5
+
+Description
+^^^^^^^^^^^
+
+Setup firmware to notify the host about a particular event. Host must
+unmask the interrupt bit.
+
+Param[0]
+^^^^^^^^
+
+Event (0=refresh encoder input)
+
+Param[1]
+^^^^^^^^
+
+Notification 0=disabled 1=enabled
+
+Param[2]
+^^^^^^^^
+
+Interrupt bit
+
+Param[3]
+^^^^^^^^
+
+Mailbox slot, -1 if no mailbox required.
+
+
+
+CX2341X_ENC_SET_NUM_VSYNC_LINES
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 214/0xD6
+
+Description
+^^^^^^^^^^^
+
+Depending on the analog video decoder used, this assigns the number
+of lines for field 1 and 2.
+
+Param[0]
+^^^^^^^^
+
+Field 1 number of lines:
+- 0x00EF for SAA7114
+- 0x00F0 for SAA7115
+- 0x0105 for Micronas
+
+Param[1]
+^^^^^^^^
+
+Field 2 number of lines:
+- 0x00EF for SAA7114
+- 0x00F0 for SAA7115
+- 0x0106 for Micronas
+
+
+
+CX2341X_ENC_SET_PLACEHOLDER
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 215/0xD7
+
+Description
+^^^^^^^^^^^
+
+Provides a mechanism of inserting custom user data in the MPEG stream.
+
+Param[0]
+^^^^^^^^
+
+- 0=extension & user data
+- 1=private packet with stream ID 0xBD
+
+Param[1]
+^^^^^^^^
+
+Rate at which to insert data, in units of frames (for private packet)
+or GOPs (for ext. & user data)
+
+Param[2]
+^^^^^^^^
+
+Number of data DWORDs (below) to insert
+
+Param[3]
+^^^^^^^^
+
+Custom data 0
+
+Param[4]
+^^^^^^^^
+
+Custom data 1
+
+Param[5]
+^^^^^^^^
+
+Custom data 2
+
+Param[6]
+^^^^^^^^
+
+Custom data 3
+
+Param[7]
+^^^^^^^^
+
+Custom data 4
+
+Param[8]
+^^^^^^^^
+
+Custom data 5
+
+Param[9]
+^^^^^^^^
+
+Custom data 6
+
+Param[10]
+^^^^^^^^^
+
+Custom data 7
+
+Param[11]
+^^^^^^^^^
+
+Custom data 8
+
+
+
+CX2341X_ENC_MUTE_VIDEO
+~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 217/0xD9
+
+Description
+^^^^^^^^^^^
+
+Video muting
+
+Param[0]
+^^^^^^^^
+
+Bit usage:
+
+.. code-block:: none
+
+	 0    	'0'=video not muted
+		'1'=video muted, creates frames with the YUV color defined below
+	 1:7  	Unused
+	 8:15 	V chrominance information
+	16:23 	U chrominance information
+	24:31 	Y luminance information
+
+
+
+CX2341X_ENC_MUTE_AUDIO
+~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 218/0xDA
+
+Description
+^^^^^^^^^^^
+
+Audio muting
+
+Param[0]
+^^^^^^^^
+
+- 0=audio not muted
+- 1=audio muted (produces silent mpeg audio stream)
+
+
+
+CX2341X_ENC_SET_VERT_CROP_LINE
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 219/0xDB
+
+Description
+^^^^^^^^^^^
+
+Something to do with 'Vertical Crop Line'
+
+Param[0]
+^^^^^^^^
+
+If saa7114 and raw VBI capture and 60 Hz, then set to 10001.
+Else 0.
+
+
+
+CX2341X_ENC_MISC
+~~~~~~~~~~~~~~~~
+
+Enum: 220/0xDC
+
+Description
+^^^^^^^^^^^
+
+Miscellaneous actions. Not known for 100% what it does. It's really a
+sort of ioctl call. The first parameter is a command number, the second
+the value.
+
+Param[0]
+^^^^^^^^
+
+Command number:
+
+.. code-block:: none
+
+	 1=set initial SCR value when starting encoding (works).
+	 2=set quality mode (apparently some test setting).
+	 3=setup advanced VIM protection handling.
+	   Always 1 for the cx23416 and 0 for cx23415.
+	 4=generate DVD compatible PTS timestamps
+	 5=USB flush mode
+	 6=something to do with the quantization matrix
+	 7=set navigation pack insertion for DVD: adds 0xbf (private stream 2)
+	   packets to the MPEG. The size of these packets is 2048 bytes (including
+	   the header of 6 bytes: 0x000001bf + length). The payload is zeroed and
+	   it is up to the application to fill them in. These packets are apparently
+	   inserted every four frames.
+	 8=enable scene change detection (seems to be a failure)
+	 9=set history parameters of the video input module
+	10=set input field order of VIM
+	11=set quantization matrix
+	12=reset audio interface after channel change or input switch (has no argument).
+	   Needed for the cx2584x, not needed for the mspx4xx, but it doesn't seem to
+	   do any harm calling it regardless.
+	13=set audio volume delay
+	14=set audio delay
+
+
+Param[1]
+^^^^^^^^
+
+Command value.
+
+Decoder firmware API description
+--------------------------------
+
+.. note:: this API is part of the decoder firmware, so it's cx23415 only.
+
+
+
+CX2341X_DEC_PING_FW
+~~~~~~~~~~~~~~~~~~~
+
+Enum: 0/0x00
+
+Description
+^^^^^^^^^^^
+
+This API call does nothing. It may be used to check if the firmware
+is responding.
+
+
+
+CX2341X_DEC_START_PLAYBACK
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 1/0x01
+
+Description
+^^^^^^^^^^^
+
+Begin or resume playback.
+
+Param[0]
+^^^^^^^^
+
+0 based frame number in GOP to begin playback from.
+
+Param[1]
+^^^^^^^^
+
+Specifies the number of muted audio frames to play before normal
+audio resumes. (This is not implemented in the firmware, leave at 0)
+
+
+
+CX2341X_DEC_STOP_PLAYBACK
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 2/0x02
+
+Description
+^^^^^^^^^^^
+
+Ends playback and clears all decoder buffers. If PTS is not zero,
+playback stops at specified PTS.
+
+Param[0]
+^^^^^^^^
+
+Display 0=last frame, 1=black
+
+.. note::
+
+	this takes effect immediately, so if you want to wait for a PTS,
+	then use '0', otherwise the screen goes to black at once.
+	You can call this later (even if there is no playback) with a 1 value
+	to set the screen to black.
+
+Param[1]
+^^^^^^^^
+
+PTS low
+
+Param[2]
+^^^^^^^^
+
+PTS high
+
+
+
+CX2341X_DEC_SET_PLAYBACK_SPEED
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 3/0x03
+
+Description
+^^^^^^^^^^^
+
+Playback stream at speed other than normal. There are two modes of
+operation:
+
+	- Smooth: host transfers entire stream and firmware drops unused
+	  frames.
+	- Coarse: host drops frames based on indexing as required to achieve
+	  desired speed.
+
+Param[0]
+^^^^^^^^
+
+.. code-block:: none
+
+	Bitmap:
+	    0:7  0 normal
+		 1 fast only "1.5 times"
+		 n nX fast, 1/nX slow
+	    30   Framedrop:
+		     '0' during 1.5 times play, every other B frame is dropped
+		     '1' during 1.5 times play, stream is unchanged (bitrate
+			 must not exceed 8mbps)
+	    31   Speed:
+		     '0' slow
+		     '1' fast
+
+.. note::
+
+	n is limited to 2. Anything higher does not result in
+	faster playback. Instead the host should start dropping frames.
+
+Param[1]
+^^^^^^^^
+
+Direction: 0=forward, 1=reverse
+
+.. note::
+
+	to make reverse playback work you have to write full GOPs in
+	reverse order.
+
+Param[2]
+^^^^^^^^
+
+.. code-block:: none
+
+	Picture mask:
+	    1=I frames
+	    3=I, P frames
+	    7=I, P, B frames
+
+Param[3]
+^^^^^^^^
+
+B frames per GOP (for reverse play only)
+
+.. note::
+
+	for reverse playback the Picture Mask should be set to I or I, P.
+	Adding B frames to the mask will result in corrupt video. This field
+	has to be set to the correct value in order to keep the timing correct.
+
+Param[4]
+^^^^^^^^
+
+Mute audio: 0=disable, 1=enable
+
+Param[5]
+^^^^^^^^
+
+Display 0=frame, 1=field
+
+Param[6]
+^^^^^^^^
+
+Specifies the number of muted audio frames to play before normal audio
+resumes. (Not implemented in the firmware, leave at 0)
+
+
+
+CX2341X_DEC_STEP_VIDEO
+~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 5/0x05
+
+Description
+^^^^^^^^^^^
+
+Each call to this API steps the playback to the next unit defined below
+in the current playback direction.
+
+Param[0]
+^^^^^^^^
+
+0=frame, 1=top field, 2=bottom field
+
+
+
+CX2341X_DEC_SET_DMA_BLOCK_SIZE
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 8/0x08
+
+Description
+^^^^^^^^^^^
+
+Set DMA transfer block size. Counterpart to API 0xC9
+
+Param[0]
+^^^^^^^^
+
+DMA transfer block size in bytes. A different size may be specified
+when issuing the DMA transfer command.
+
+
+
+CX2341X_DEC_GET_XFER_INFO
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 9/0x09
+
+Description
+^^^^^^^^^^^
+
+This API call may be used to detect an end of stream condition.
+
+Result[0]
+^^^^^^^^^
+
+Stream type
+
+Result[1]
+^^^^^^^^^
+
+Address offset
+
+Result[2]
+^^^^^^^^^
+
+Maximum bytes to transfer
+
+Result[3]
+^^^^^^^^^
+
+Buffer fullness
+
+
+
+CX2341X_DEC_GET_DMA_STATUS
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 10/0x0A
+
+Description
+^^^^^^^^^^^
+
+Status of the last DMA transfer
+
+Result[0]
+^^^^^^^^^
+
+Bit 1 set means transfer complete
+Bit 2 set means DMA error
+Bit 3 set means linked list error
+
+Result[1]
+^^^^^^^^^
+
+DMA type: 0=MPEG, 1=OSD, 2=YUV
+
+
+
+CX2341X_DEC_SCHED_DMA_FROM_HOST
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 11/0x0B
+
+Description
+^^^^^^^^^^^
+
+Setup DMA from host operation. Counterpart to API 0xCC
+
+Param[0]
+^^^^^^^^
+
+Memory address of link list
+
+Param[1]
+^^^^^^^^
+
+Total # of bytes to transfer
+
+Param[2]
+^^^^^^^^
+
+DMA type (0=MPEG, 1=OSD, 2=YUV)
+
+
+
+CX2341X_DEC_PAUSE_PLAYBACK
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 13/0x0D
+
+Description
+^^^^^^^^^^^
+
+Freeze playback immediately. In this mode, when internal buffers are
+full, no more data will be accepted and data request IRQs will be
+masked.
+
+Param[0]
+^^^^^^^^
+
+Display: 0=last frame, 1=black
+
+
+
+CX2341X_DEC_HALT_FW
+~~~~~~~~~~~~~~~~~~~
+
+Enum: 14/0x0E
+
+Description
+^^^^^^^^^^^
+
+The firmware is halted and no further API calls are serviced until
+the firmware is uploaded again.
+
+
+
+CX2341X_DEC_SET_STANDARD
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 16/0x10
+
+Description
+^^^^^^^^^^^
+
+Selects display standard
+
+Param[0]
+^^^^^^^^
+
+0=NTSC, 1=PAL
+
+
+
+CX2341X_DEC_GET_VERSION
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 17/0x11
+
+Description
+^^^^^^^^^^^
+
+Returns decoder firmware version information
+
+Result[0]
+^^^^^^^^^
+
+Version bitmask:
+	- Bits  0:15 build
+	- Bits 16:23 minor
+	- Bits 24:31 major
+
+
+
+CX2341X_DEC_SET_STREAM_INPUT
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 20/0x14
+
+Description
+^^^^^^^^^^^
+
+Select decoder stream input port
+
+Param[0]
+^^^^^^^^
+
+0=memory (default), 1=streaming
+
+
+
+CX2341X_DEC_GET_TIMING_INFO
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 21/0x15
+
+Description
+^^^^^^^^^^^
+
+Returns timing information from start of playback
+
+Result[0]
+^^^^^^^^^
+
+Frame count by decode order
+
+Result[1]
+^^^^^^^^^
+
+Video PTS bits 0:31 by display order
+
+Result[2]
+^^^^^^^^^
+
+Video PTS bit 32 by display order
+
+Result[3]
+^^^^^^^^^
+
+SCR bits 0:31 by display order
+
+Result[4]
+^^^^^^^^^
+
+SCR bit 32 by display order
+
+
+
+CX2341X_DEC_SET_AUDIO_MODE
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 22/0x16
+
+Description
+^^^^^^^^^^^
+
+Select audio mode
+
+Param[0]
+^^^^^^^^
+
+Dual mono mode action
+	0=Stereo, 1=Left, 2=Right, 3=Mono, 4=Swap, -1=Unchanged
+
+Param[1]
+^^^^^^^^
+
+Stereo mode action:
+	0=Stereo, 1=Left, 2=Right, 3=Mono, 4=Swap, -1=Unchanged
+
+
+
+CX2341X_DEC_SET_EVENT_NOTIFICATION
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 23/0x17
+
+Description
+^^^^^^^^^^^
+
+Setup firmware to notify the host about a particular event.
+Counterpart to API 0xD5
+
+Param[0]
+^^^^^^^^
+
+Event:
+	- 0=Audio mode change between mono, (joint) stereo and dual channel.
+	- 3=Decoder started
+	- 4=Unknown: goes off 10-15 times per second while decoding.
+	- 5=Some sync event: goes off once per frame.
+
+Param[1]
+^^^^^^^^
+
+Notification 0=disabled, 1=enabled
+
+Param[2]
+^^^^^^^^
+
+Interrupt bit
+
+Param[3]
+^^^^^^^^
+
+Mailbox slot, -1 if no mailbox required.
+
+
+
+CX2341X_DEC_SET_DISPLAY_BUFFERS
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 24/0x18
+
+Description
+^^^^^^^^^^^
+
+Number of display buffers. To decode all frames in reverse playback you
+must use nine buffers.
+
+Param[0]
+^^^^^^^^
+
+0=six buffers, 1=nine buffers
+
+
+
+CX2341X_DEC_EXTRACT_VBI
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 25/0x19
+
+Description
+^^^^^^^^^^^
+
+Extracts VBI data
+
+Param[0]
+^^^^^^^^
+
+0=extract from extension & user data, 1=extract from private packets
+
+Result[0]
+^^^^^^^^^
+
+VBI table location
+
+Result[1]
+^^^^^^^^^
+
+VBI table size
+
+
+
+CX2341X_DEC_SET_DECODER_SOURCE
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 26/0x1A
+
+Description
+^^^^^^^^^^^
+
+Selects decoder source. Ensure that the parameters passed to this
+API match the encoder settings.
+
+Param[0]
+^^^^^^^^
+
+Mode: 0=MPEG from host, 1=YUV from encoder, 2=YUV from host
+
+Param[1]
+^^^^^^^^
+
+YUV picture width
+
+Param[2]
+^^^^^^^^
+
+YUV picture height
+
+Param[3]
+^^^^^^^^
+
+Bitmap: see Param[0] of API 0xBD
+
+
+
+CX2341X_DEC_SET_PREBUFFERING
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 30/0x1E
+
+Description
+^^^^^^^^^^^
+
+Decoder prebuffering, when enabled up to 128KB are buffered for
+streams <8mpbs or 640KB for streams >8mbps
+
+Param[0]
+^^^^^^^^
+
+0=off, 1=on
+
+PVR350 Video decoder registers 0x02002800 -> 0x02002B00
+-------------------------------------------------------
+
+Author: Ian Armstrong <ian@iarmst.demon.co.uk>
+
+Version: v0.4
+
+Date: 12 March 2007
+
+
+This list has been worked out through trial and error. There will be mistakes
+and omissions. Some registers have no obvious effect so it's hard to say what
+they do, while others interact with each other, or require a certain load
+sequence. Horizontal filter setup is one example, with six registers working
+in unison and requiring a certain load sequence to correctly configure. The
+indexed colour palette is much easier to set at just two registers, but again
+it requires a certain load sequence.
+
+Some registers are fussy about what they are set to. Load in a bad value & the
+decoder will fail. A firmware reload will often recover, but sometimes a reset
+is required. For registers containing size information, setting them to 0 is
+generally a bad idea. For other control registers i.e. 2878, you'll only find
+out what values are bad when it hangs.
+
+.. code-block:: none
+
+	--------------------------------------------------------------------------------
+	2800
+	bit 0
+		Decoder enable
+		0 = disable
+		1 = enable
+	--------------------------------------------------------------------------------
+	2804
+	bits 0:31
+		Decoder horizontal Y alias register 1
+	---------------
+	2808
+	bits 0:31
+		Decoder horizontal Y alias register 2
+	---------------
+	280C
+	bits 0:31
+		Decoder horizontal Y alias register 3
+	---------------
+	2810
+	bits 0:31
+		Decoder horizontal Y alias register 4
+	---------------
+	2814
+	bits 0:31
+		Decoder horizontal Y alias register 5
+	---------------
+	2818
+	bits 0:31
+		Decoder horizontal Y alias trigger
+
+	These six registers control the horizontal aliasing filter for the Y plane.
+	The first five registers must all be loaded before accessing the trigger
+	(2818), as this register actually clocks the data through for the first
+	five.
+
+	To correctly program set the filter, this whole procedure must be done 16
+	times. The actual register contents are copied from a lookup-table in the
+	firmware which contains 4 different filter settings.
+
+	--------------------------------------------------------------------------------
+	281C
+	bits 0:31
+		Decoder horizontal UV alias register 1
+	---------------
+	2820
+	bits 0:31
+		Decoder horizontal UV alias register 2
+	---------------
+	2824
+	bits 0:31
+		Decoder horizontal UV alias register 3
+	---------------
+	2828
+	bits 0:31
+		Decoder horizontal UV alias register 4
+	---------------
+	282C
+	bits 0:31
+		Decoder horizontal UV alias register 5
+	---------------
+	2830
+	bits 0:31
+		Decoder horizontal UV alias trigger
+
+	These six registers control the horizontal aliasing for the UV plane.
+	Operation is the same as the Y filter, with 2830 being the trigger
+	register.
+
+	--------------------------------------------------------------------------------
+	2834
+	bits 0:15
+		Decoder Y source width in pixels
+
+	bits 16:31
+		Decoder Y destination width in pixels
+	---------------
+	2838
+	bits 0:15
+		Decoder UV source width in pixels
+
+	bits 16:31
+		Decoder UV destination width in pixels
+
+	NOTE: For both registers, the resulting image must be fully visible on
+	screen. If the image exceeds the right edge both the source and destination
+	size must be adjusted to reflect the visible portion. For the source width,
+	you must take into account the scaling when calculating the new value.
+	--------------------------------------------------------------------------------
+
+	283C
+	bits 0:31
+		Decoder Y horizontal scaling
+			Normally = Reg 2854 >> 2
+	---------------
+	2840
+	bits 0:31
+		Decoder ?? unknown - horizontal scaling
+		Usually 0x00080514
+	---------------
+	2844
+	bits 0:31
+		Decoder UV horizontal scaling
+		Normally = Reg 2854 >> 2
+	---------------
+	2848
+	bits 0:31
+		Decoder ?? unknown - horizontal scaling
+		Usually 0x00100514
+	---------------
+	284C
+	bits 0:31
+		Decoder ?? unknown - Y plane
+		Usually 0x00200020
+	---------------
+	2850
+	bits 0:31
+		Decoder ?? unknown - UV plane
+		Usually 0x00200020
+	---------------
+	2854
+	bits 0:31
+		Decoder 'master' value for horizontal scaling
+	---------------
+	2858
+	bits 0:31
+		Decoder ?? unknown
+		Usually 0
+	---------------
+	285C
+	bits 0:31
+		Decoder ?? unknown
+		Normally = Reg 2854 >> 1
+	---------------
+	2860
+	bits 0:31
+		Decoder ?? unknown
+		Usually 0
+	---------------
+	2864
+	bits 0:31
+		Decoder ?? unknown
+		Normally = Reg 2854 >> 1
+	---------------
+	2868
+	bits 0:31
+		Decoder ?? unknown
+		Usually 0
+
+	Most of these registers either control horizontal scaling, or appear linked
+	to it in some way. Register 2854 contains the 'master' value & the other
+	registers can be calculated from that one. You must also remember to
+	correctly set the divider in Reg 2874.
+
+	To enlarge:
+		Reg 2854 = (source_width * 0x00200000) / destination_width
+		Reg 2874 = No divide
+
+	To reduce from full size down to half size:
+		Reg 2854 = (source_width/2 * 0x00200000) / destination width
+		Reg 2874 = Divide by 2
+
+	To reduce from half size down to quarter size:
+		Reg 2854 = (source_width/4 * 0x00200000) / destination width
+		Reg 2874 = Divide by 4
+
+	The result is always rounded up.
+
+	--------------------------------------------------------------------------------
+	286C
+	bits 0:15
+		Decoder horizontal Y buffer offset
+
+	bits 15:31
+		Decoder horizontal UV buffer offset
+
+	Offset into the video image buffer. If the offset is gradually incremented,
+	the on screen image will move left & wrap around higher up on the right.
+
+	--------------------------------------------------------------------------------
+	2870
+	bits 0:15
+		Decoder horizontal Y output offset
+
+	bits 16:31
+		Decoder horizontal UV output offset
+
+	Offsets the actual video output. Controls output alignment of the Y & UV
+	planes. The higher the value, the greater the shift to the left. Use
+	reg 2890 to move the image right.
+
+	--------------------------------------------------------------------------------
+	2874
+	bits 0:1
+		Decoder horizontal Y output size divider
+		00 = No divide
+		01 = Divide by 2
+		10 = Divide by 3
+
+	bits 4:5
+		Decoder horizontal UV output size divider
+		00 = No divide
+		01 = Divide by 2
+		10 = Divide by 3
+
+	bit 8
+		Decoder ?? unknown
+		0 = Normal
+		1 = Affects video output levels
+
+	bit 16
+		Decoder ?? unknown
+		0 = Normal
+		1 = Disable horizontal filter
+
+	--------------------------------------------------------------------------------
+	2878
+	bit 0
+		?? unknown
+
+	bit 1
+		osd on/off
+		0 = osd off
+		1 = osd on
+
+	bit 2
+		Decoder + osd video timing
+		0 = NTSC
+		1 = PAL
+
+	bits 3:4
+		?? unknown
+
+	bit 5
+		Decoder + osd
+		Swaps upper & lower fields
+
+	--------------------------------------------------------------------------------
+	287C
+	bits 0:10
+		Decoder & osd ?? unknown
+		Moves entire screen horizontally. Starts at 0x005 with the screen
+		shifted heavily to the right. Incrementing in steps of 0x004 will
+		gradually shift the screen to the left.
+
+	bits 11:31
+		?? unknown
+
+	Normally contents are 0x00101111 (NTSC) or 0x1010111d (PAL)
+
+	--------------------------------------------------------------------------------
+	2880  --------    ?? unknown
+	2884  --------    ?? unknown
+	--------------------------------------------------------------------------------
+	2888
+	bit 0
+		Decoder + osd ?? unknown
+		0 = Normal
+		1 = Misaligned fields (Correctable through 289C & 28A4)
+
+	bit 4
+		?? unknown
+
+	bit 8
+		?? unknown
+
+	Warning: Bad values will require a firmware reload to recover.
+			Known to be bad are 0x000,0x011,0x100,0x111
+	--------------------------------------------------------------------------------
+	288C
+	bits 0:15
+		osd ?? unknown
+		Appears to affect the osd position stability. The higher the value the
+		more unstable it becomes. Decoder output remains stable.
+
+	bits 16:31
+		osd ?? unknown
+		Same as bits 0:15
+
+	--------------------------------------------------------------------------------
+	2890
+	bits 0:11
+		Decoder output horizontal offset.
+
+	Horizontal offset moves the video image right. A small left shift is
+	possible, but it's better to use reg 2870 for that due to its greater
+	range.
+
+	NOTE: Video corruption will occur if video window is shifted off the right
+	edge. To avoid this read the notes for 2834 & 2838.
+	--------------------------------------------------------------------------------
+	2894
+	bits 0:23
+		Decoder output video surround colour.
+
+	Contains the colour (in yuv) used to fill the screen when the video is
+	running in a window.
+	--------------------------------------------------------------------------------
+	2898
+	bits 0:23
+		Decoder video window colour
+		Contains the colour (in yuv) used to fill the video window when the
+		video is turned off.
+
+	bit 24
+		Decoder video output
+		0 = Video on
+		1 = Video off
+
+	bit 28
+		Decoder plane order
+		0 = Y,UV
+		1 = UV,Y
+
+	bit 29
+		Decoder second plane byte order
+		0 = Normal (UV)
+		1 = Swapped (VU)
+
+	In normal usage, the first plane is Y & the second plane is UV. Though the
+	order of the planes can be swapped, only the byte order of the second plane
+	can be swapped. This isn't much use for the Y plane, but can be useful for
+	the UV plane.
+
+	--------------------------------------------------------------------------------
+	289C
+	bits 0:15
+		Decoder vertical field offset 1
+
+	bits 16:31
+		Decoder vertical field offset 2
+
+	Controls field output vertical alignment. The higher the number, the lower
+	the image on screen. Known starting values are 0x011E0017 (NTSC) &
+	0x01500017 (PAL)
+	--------------------------------------------------------------------------------
+	28A0
+	bits 0:15
+		Decoder & osd width in pixels
+
+	bits 16:31
+		Decoder & osd height in pixels
+
+	All output from the decoder & osd are disabled beyond this area. Decoder
+	output will simply go black outside of this region. If the osd tries to
+	exceed this area it will become corrupt.
+	--------------------------------------------------------------------------------
+	28A4
+	bits 0:11
+		osd left shift.
+
+	Has a range of 0x770->0x7FF. With the exception of 0, any value outside of
+	this range corrupts the osd.
+	--------------------------------------------------------------------------------
+	28A8
+	bits 0:15
+		osd vertical field offset 1
+
+	bits 16:31
+		osd vertical field offset 2
+
+	Controls field output vertical alignment. The higher the number, the lower
+	the image on screen. Known starting values are 0x011E0017 (NTSC) &
+	0x01500017 (PAL)
+	--------------------------------------------------------------------------------
+	28AC  --------    ?? unknown
+	|
+	V
+	28BC  --------    ?? unknown
+	--------------------------------------------------------------------------------
+	28C0
+	bit 0
+		Current output field
+		0 = first field
+		1 = second field
+
+	bits 16:31
+		Current scanline
+		The scanline counts from the top line of the first field
+		through to the last line of the second field.
+	--------------------------------------------------------------------------------
+	28C4  --------    ?? unknown
+	|
+	V
+	28F8  --------    ?? unknown
+	--------------------------------------------------------------------------------
+	28FC
+	bit 0
+		?? unknown
+		0 = Normal
+		1 = Breaks decoder & osd output
+	--------------------------------------------------------------------------------
+	2900
+	bits 0:31
+		Decoder vertical Y alias register 1
+	---------------
+	2904
+	bits 0:31
+		Decoder vertical Y alias register 2
+	---------------
+	2908
+	bits 0:31
+		Decoder vertical Y alias trigger
+
+	These three registers control the vertical aliasing filter for the Y plane.
+	Operation is similar to the horizontal Y filter (2804). The only real
+	difference is that there are only two registers to set before accessing
+	the trigger register (2908). As for the horizontal filter, the values are
+	taken from a lookup table in the firmware, and the procedure must be
+	repeated 16 times to fully program the filter.
+	--------------------------------------------------------------------------------
+	290C
+	bits 0:31
+		Decoder vertical UV alias register 1
+	---------------
+	2910
+	bits 0:31
+		Decoder vertical UV alias register 2
+	---------------
+	2914
+	bits 0:31
+		Decoder vertical UV alias trigger
+
+	These three registers control the vertical aliasing filter for the UV
+	plane. Operation is the same as the Y filter, with 2914 being the trigger.
+	--------------------------------------------------------------------------------
+	2918
+	bits 0:15
+		Decoder Y source height in pixels
+
+	bits 16:31
+		Decoder Y destination height in pixels
+	---------------
+	291C
+	bits 0:15
+		Decoder UV source height in pixels divided by 2
+
+	bits 16:31
+		Decoder UV destination height in pixels
+
+	NOTE: For both registers, the resulting image must be fully visible on
+	screen. If the image exceeds the bottom edge both the source and
+	destination size must be adjusted to reflect the visible portion. For the
+	source height, you must take into account the scaling when calculating the
+	new value.
+	--------------------------------------------------------------------------------
+	2920
+	bits 0:31
+		Decoder Y vertical scaling
+		Normally = Reg 2930 >> 2
+	---------------
+	2924
+	bits 0:31
+		Decoder Y vertical scaling
+		Normally = Reg 2920 + 0x514
+	---------------
+	2928
+	bits 0:31
+		Decoder UV vertical scaling
+		When enlarging = Reg 2930 >> 2
+		When reducing = Reg 2930 >> 3
+	---------------
+	292C
+	bits 0:31
+		Decoder UV vertical scaling
+		Normally = Reg 2928 + 0x514
+	---------------
+	2930
+	bits 0:31
+		Decoder 'master' value for vertical scaling
+	---------------
+	2934
+	bits 0:31
+		Decoder ?? unknown - Y vertical scaling
+	---------------
+	2938
+	bits 0:31
+		Decoder Y vertical scaling
+		Normally = Reg 2930
+	---------------
+	293C
+	bits 0:31
+		Decoder ?? unknown - Y vertical scaling
+	---------------
+	2940
+	bits 0:31
+		Decoder UV vertical scaling
+		When enlarging = Reg 2930 >> 1
+		When reducing = Reg 2930
+	---------------
+	2944
+	bits 0:31
+		Decoder ?? unknown - UV vertical scaling
+	---------------
+	2948
+	bits 0:31
+		Decoder UV vertical scaling
+		Normally = Reg 2940
+	---------------
+	294C
+	bits 0:31
+		Decoder ?? unknown - UV vertical scaling
+
+	Most of these registers either control vertical scaling, or appear linked
+	to it in some way. Register 2930 contains the 'master' value & all other
+	registers can be calculated from that one. You must also remember to
+	correctly set the divider in Reg 296C
+
+	To enlarge:
+		Reg 2930 = (source_height * 0x00200000) / destination_height
+		Reg 296C = No divide
+
+	To reduce from full size down to half size:
+		Reg 2930 = (source_height/2 * 0x00200000) / destination height
+		Reg 296C = Divide by 2
+
+	To reduce from half down to quarter.
+		Reg 2930 = (source_height/4 * 0x00200000) / destination height
+		Reg 296C = Divide by 4
+
+	--------------------------------------------------------------------------------
+	2950
+	bits 0:15
+		Decoder Y line index into display buffer, first field
+
+	bits 16:31
+		Decoder Y vertical line skip, first field
+	--------------------------------------------------------------------------------
+	2954
+	bits 0:15
+		Decoder Y line index into display buffer, second field
+
+	bits 16:31
+		Decoder Y vertical line skip, second field
+	--------------------------------------------------------------------------------
+	2958
+	bits 0:15
+		Decoder UV line index into display buffer, first field
+
+	bits 16:31
+		Decoder UV vertical line skip, first field
+	--------------------------------------------------------------------------------
+	295C
+	bits 0:15
+		Decoder UV line index into display buffer, second field
+
+	bits 16:31
+		Decoder UV vertical line skip, second field
+	--------------------------------------------------------------------------------
+	2960
+	bits 0:15
+		Decoder destination height minus 1
+
+	bits 16:31
+		Decoder destination height divided by 2
+	--------------------------------------------------------------------------------
+	2964
+	bits 0:15
+		Decoder Y vertical offset, second field
+
+	bits 16:31
+		Decoder Y vertical offset, first field
+
+	These two registers shift the Y plane up. The higher the number, the
+	greater the shift.
+	--------------------------------------------------------------------------------
+	2968
+	bits 0:15
+		Decoder UV vertical offset, second field
+
+	bits 16:31
+		Decoder UV vertical offset, first field
+
+	These two registers shift the UV plane up. The higher the number, the
+	greater the shift.
+	--------------------------------------------------------------------------------
+	296C
+	bits 0:1
+		Decoder vertical Y output size divider
+		00 = No divide
+		01 = Divide by 2
+		10 = Divide by 4
+
+	bits 8:9
+		Decoder vertical UV output size divider
+		00 = No divide
+		01 = Divide by 2
+		10 = Divide by 4
+	--------------------------------------------------------------------------------
+	2970
+	bit 0
+		Decoder ?? unknown
+		0 = Normal
+		1 = Affect video output levels
+
+	bit 16
+		Decoder ?? unknown
+		0 = Normal
+		1 = Disable vertical filter
+
+	--------------------------------------------------------------------------------
+	2974  --------   ?? unknown
+	|
+	V
+	29EF  --------   ?? unknown
+	--------------------------------------------------------------------------------
+	2A00
+	bits 0:2
+		osd colour mode
+		000 = 8 bit indexed
+		001 = 16 bit (565)
+		010 = 15 bit (555)
+		011 = 12 bit (444)
+		100 = 32 bit (8888)
+
+	bits 4:5
+		osd display bpp
+		01 = 8 bit
+		10 = 16 bit
+		11 = 32 bit
+
+	bit 8
+		osd global alpha
+		0 = Off
+		1 = On
+
+	bit 9
+		osd local alpha
+		0 = Off
+		1 = On
+
+	bit 10
+		osd colour key
+		0 = Off
+		1 = On
+
+	bit 11
+		osd ?? unknown
+		Must be 1
+
+	bit 13
+		osd colour space
+		0 = ARGB
+		1 = AYVU
+
+	bits 16:31
+		osd ?? unknown
+		Must be 0x001B (some kind of buffer pointer ?)
+
+	When the bits-per-pixel is set to 8, the colour mode is ignored and
+	assumed to be 8 bit indexed. For 16 & 32 bits-per-pixel the colour depth
+	is honoured, and when using a colour depth that requires fewer bytes than
+	allocated the extra bytes are used as padding. So for a 32 bpp with 8 bit
+	index colour, there are 3 padding bytes per pixel. It's also possible to
+	select 16bpp with a 32 bit colour mode. This results in the pixel width
+	being doubled, but the color key will not work as expected in this mode.
+
+	Colour key is as it suggests. You designate a colour which will become
+	completely transparent. When using 565, 555 or 444 colour modes, the
+	colour key is always 16 bits wide. The colour to key on is set in Reg 2A18.
+
+	Local alpha works differently depending on the colour mode. For 32bpp & 8
+	bit indexed, local alpha is a per-pixel 256 step transparency, with 0 being
+	transparent and 255 being solid. For the 16bpp modes 555 & 444, the unused
+	bit(s) act as a simple transparency switch, with 0 being solid & 1 being
+	fully transparent. There is no local alpha support for 16bit 565.
+
+	Global alpha is a 256 step transparency that applies to the entire osd,
+	with 0 being transparent & 255 being solid.
+
+	It's possible to combine colour key, local alpha & global alpha.
+	--------------------------------------------------------------------------------
+	2A04
+	bits 0:15
+		osd x coord for left edge
+
+	bits 16:31
+		osd y coord for top edge
+	---------------
+	2A08
+	bits 0:15
+		osd x coord for right edge
+
+	bits 16:31
+		osd y coord for bottom edge
+
+	For both registers, (0,0) = top left corner of the display area. These
+	registers do not control the osd size, only where it's positioned & how
+	much is visible. The visible osd area cannot exceed the right edge of the
+	display, otherwise the osd will become corrupt. See reg 2A10 for
+	setting osd width.
+	--------------------------------------------------------------------------------
+	2A0C
+	bits 0:31
+		osd buffer index
+
+	An index into the osd buffer. Slowly incrementing this moves the osd left,
+	wrapping around onto the right edge
+	--------------------------------------------------------------------------------
+	2A10
+	bits 0:11
+		osd buffer 32 bit word width
+
+	Contains the width of the osd measured in 32 bit words. This means that all
+	colour modes are restricted to a byte width which is divisible by 4.
+	--------------------------------------------------------------------------------
+	2A14
+	bits 0:15
+		osd height in pixels
+
+	bits 16:32
+		osd line index into buffer
+		osd will start displaying from this line.
+	--------------------------------------------------------------------------------
+	2A18
+	bits 0:31
+		osd colour key
+
+	Contains the colour value which will be transparent.
+	--------------------------------------------------------------------------------
+	2A1C
+	bits 0:7
+		osd global alpha
+
+	Contains the global alpha value (equiv ivtvfbctl --alpha XX)
+	--------------------------------------------------------------------------------
+	2A20  --------    ?? unknown
+	|
+	V
+	2A2C  --------    ?? unknown
+	--------------------------------------------------------------------------------
+	2A30
+	bits 0:7
+		osd colour to change in indexed palette
+	---------------
+	2A34
+	bits 0:31
+		osd colour for indexed palette
+
+	To set the new palette, first load the index of the colour to change into
+	2A30, then load the new colour into 2A34. The full palette is 256 colours,
+	so the index range is 0x00-0xFF
+	--------------------------------------------------------------------------------
+	2A38  --------    ?? unknown
+	2A3C  --------    ?? unknown
+	--------------------------------------------------------------------------------
+	2A40
+	bits 0:31
+		osd ?? unknown
+
+	Affects overall brightness, wrapping around to black
+	--------------------------------------------------------------------------------
+	2A44
+	bits 0:31
+		osd ?? unknown
+
+	Green tint
+	--------------------------------------------------------------------------------
+	2A48
+	bits 0:31
+		osd ?? unknown
+
+	Red tint
+	--------------------------------------------------------------------------------
+	2A4C
+	bits 0:31
+		osd ?? unknown
+
+	Affects overall brightness, wrapping around to black
+	--------------------------------------------------------------------------------
+	2A50
+	bits 0:31
+		osd ?? unknown
+
+	Colour shift
+	--------------------------------------------------------------------------------
+	2A54
+	bits 0:31
+		osd ?? unknown
+
+	Colour shift
+	--------------------------------------------------------------------------------
+	2A58  --------    ?? unknown
+	|
+	V
+	2AFC  --------    ?? unknown
+	--------------------------------------------------------------------------------
+	2B00
+	bit 0
+		osd filter control
+		0 = filter off
+		1 = filter on
+
+	bits 1:4
+		osd ?? unknown
+
+	--------------------------------------------------------------------------------
+
+The cx231xx DMA engine
+----------------------
+
+
+This page describes the structures and procedures used by the cx2341x DMA
+engine.
+
+Introduction
+~~~~~~~~~~~~
+
+The cx2341x PCI interface is busmaster capable. This means it has a DMA
+engine to efficiently transfer large volumes of data between the card and main
+memory without requiring help from a CPU. Like most hardware, it must operate
+on contiguous physical memory. This is difficult to come by in large quantities
+on virtual memory machines.
+
+Therefore, it also supports a technique called "scatter-gather". The card can
+transfer multiple buffers in one operation. Instead of allocating one large
+contiguous buffer, the driver can allocate several smaller buffers.
+
+In practice, I've seen the average transfer to be roughly 80K, but transfers
+above 128K were not uncommon, particularly at startup. The 128K figure is
+important, because that is the largest block that the kernel can normally
+allocate. Even still, 128K blocks are hard to come by, so the driver writer is
+urged to choose a smaller block size and learn the scatter-gather technique.
+
+Mailbox #10 is reserved for DMA transfer information.
+
+Note: the hardware expects little-endian data ('intel format').
+
+Flow
+~~~~
+
+This section describes, in general, the order of events when handling DMA
+transfers. Detailed information follows this section.
+
+- The card raises the Encoder interrupt.
+- The driver reads the transfer type, offset and size from Mailbox #10.
+- The driver constructs the scatter-gather array from enough free dma buffers
+  to cover the size.
+- The driver schedules the DMA transfer via the ScheduleDMAtoHost API call.
+- The card raises the DMA Complete interrupt.
+- The driver checks the DMA status register for any errors.
+- The driver post-processes the newly transferred buffers.
+
+NOTE! It is possible that the Encoder and DMA Complete interrupts get raised
+simultaneously. (End of the last, start of the next, etc.)
+
+Mailbox #10
+~~~~~~~~~~~
+
+The Flags, Command, Return Value and Timeout fields are ignored.
+
+- Name:       Mailbox #10
+- Results[0]: Type: 0: MPEG.
+- Results[1]: Offset: The position relative to the card's memory space.
+- Results[2]: Size: The exact number of bytes to transfer.
+
+My speculation is that since the StartCapture API has a capture type of "RAW"
+available, that the type field will have other values that correspond to YUV
+and PCM data.
+
+Scatter-Gather Array
+~~~~~~~~~~~~~~~~~~~~
+
+The scatter-gather array is a contiguously allocated block of memory that
+tells the card the source and destination of each data-block to transfer.
+Card "addresses" are derived from the offset supplied by Mailbox #10. Host
+addresses are the physical memory location of the target DMA buffer.
+
+Each S-G array element is a struct of three 32-bit words. The first word is
+the source address, the second is the destination address. Both take up the
+entire 32 bits. The lowest 18 bits of the third word is the transfer byte
+count. The high-bit of the third word is the "last" flag. The last-flag tells
+the card to raise the DMA_DONE interrupt. From hard personal experience, if
+you forget to set this bit, the card will still "work" but the stream will
+most likely get corrupted.
+
+The transfer count must be a multiple of 256. Therefore, the driver will need
+to track how much data in the target buffer is valid and deal with it
+accordingly.
+
+Array Element:
+
+- 32-bit Source Address
+- 32-bit Destination Address
+- 14-bit reserved (high bit is the last flag)
+- 18-bit byte count
+
+DMA Transfer Status
+~~~~~~~~~~~~~~~~~~~
+
+Register 0x0004 holds the DMA Transfer Status:
+
+- bit 0:   read completed
+- bit 1:   write completed
+- bit 2:   DMA read error
+- bit 3:   DMA write error
+- bit 4:   Scatter-Gather array error
diff --git a/Documentation/driver-api/media/drivers/cx88-devel.rst b/Documentation/driver-api/media/drivers/cx88-devel.rst
new file mode 100644
index 000000000000..cfe7c03f4930
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/cx88-devel.rst
@@ -0,0 +1,113 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+The cx88 driver
+===============
+
+Author:  Gerd Hoffmann
+
+Documentation missing at the cx88 datasheet
+-------------------------------------------
+
+MO_OUTPUT_FORMAT (0x310164)
+
+.. code-block:: none
+
+  Previous default from DScaler: 0x1c1f0008
+  Digit 8: 31-28
+  28: PREVREMOD = 1
+
+  Digit 7: 27-24 (0xc = 12 = b1100 )
+  27: COMBALT = 1
+  26: PAL_INV_PHASE
+    (DScaler apparently set this to 1, resulted in sucky picture)
+
+  Digits 6,5: 23-16
+  25-16: COMB_RANGE = 0x1f [default] (9 bits -> max 512)
+
+  Digit 4: 15-12
+  15: DISIFX = 0
+  14: INVCBF = 0
+  13: DISADAPT = 0
+  12: NARROWADAPT = 0
+
+  Digit 3: 11-8
+  11: FORCE2H
+  10: FORCEREMD
+  9: NCHROMAEN
+  8: NREMODEN
+
+  Digit 2: 7-4
+  7-6: YCORE
+  5-4: CCORE
+
+  Digit 1: 3-0
+  3: RANGE = 1
+  2: HACTEXT
+  1: HSFMT
+
+0x47 is the sync byte for MPEG-2 transport stream packets.
+Datasheet incorrectly states to use 47 decimal. 188 is the length.
+All DVB compliant frontends output packets with this start code.
+
+Hauppauge WinTV cx88 IR information
+-----------------------------------
+
+The controls for the mux are GPIO [0,1] for source, and GPIO 2 for muting.
+
+====== ======== =================================================
+GPIO0  GPIO1
+====== ======== =================================================
+  0        0    TV Audio
+  1        0    FM radio
+  0        1    Line-In
+  1        1    Mono tuner bypass or CD passthru (tuner specific)
+====== ======== =================================================
+
+GPIO 16(I believe) is tied to the IR port (if present).
+
+
+From the data sheet:
+
+- Register 24'h20004  PCI Interrupt Status
+
+ - bit [18]  IR_SMP_INT Set when 32 input samples have been collected over
+ - gpio[16] pin into GP_SAMPLE register.
+
+What's missing from the data sheet:
+
+- Setup 4KHz sampling rate (roughly 2x oversampled; good enough for our RC5
+  compat remote)
+- set register 0x35C050 to  0xa80a80
+- enable sampling
+- set register 0x35C054 to 0x5
+- enable the IRQ bit 18 in the interrupt mask register (and
+  provide for a handler)
+
+GP_SAMPLE register is at 0x35C058
+
+Bits are then right shifted into the GP_SAMPLE register at the specified
+rate; you get an interrupt when a full DWORD is received.
+You need to recover the actual RC5 bits out of the (oversampled) IR sensor
+bits. (Hint: look for the 0/1and 1/0 crossings of the RC5 bi-phase data)  An
+actual raw RC5 code will span 2-3 DWORDS, depending on the actual alignment.
+
+I'm pretty sure when no IR signal is present the receiver is always in a
+marking state(1); but stray light, etc can cause intermittent noise values
+as well.  Remember, this is a free running sample of the IR receiver state
+over time, so don't assume any sample starts at any particular place.
+
+Additional info
+~~~~~~~~~~~~~~~
+
+This data sheet (google search) seems to have a lovely description of the
+RC5 basics:
+http://www.atmel.com/dyn/resources/prod_documents/doc2817.pdf
+
+This document has more data:
+http://www.nenya.be/beor/electronics/rc5.htm
+
+This document has a  how to decode a bi-phase data stream:
+http://www.ee.washington.edu/circuit_archive/text/ir_decode.txt
+
+This document has still more info:
+http://www.xs4all.nl/~sbp/knowledge/ir/rc5.htm
diff --git a/Documentation/driver-api/media/drivers/davinci-vpbe-devel.rst b/Documentation/driver-api/media/drivers/davinci-vpbe-devel.rst
new file mode 100644
index 000000000000..f0961672e6a3
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/davinci-vpbe-devel.rst
@@ -0,0 +1,39 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+The VPBE V4L2 driver design
+===========================
+
+File partitioning
+-----------------
+
+ V4L2 display device driver
+         drivers/media/platform/davinci/vpbe_display.c
+         drivers/media/platform/davinci/vpbe_display.h
+
+ VPBE display controller
+         drivers/media/platform/davinci/vpbe.c
+         drivers/media/platform/davinci/vpbe.h
+
+ VPBE venc sub device driver
+         drivers/media/platform/davinci/vpbe_venc.c
+         drivers/media/platform/davinci/vpbe_venc.h
+         drivers/media/platform/davinci/vpbe_venc_regs.h
+
+ VPBE osd driver
+         drivers/media/platform/davinci/vpbe_osd.c
+         drivers/media/platform/davinci/vpbe_osd.h
+         drivers/media/platform/davinci/vpbe_osd_regs.h
+
+To be done
+----------
+
+vpbe display controller
+    - Add support for external encoders.
+    - add support for selecting external encoder as default at probe time.
+
+vpbe venc sub device
+    - add timings for supporting ths8200
+    - add support for LogicPD LCD.
+
+FB drivers
+    - Add support for fbdev drivers.- Ready and part of subsequent patches.
diff --git a/Documentation/driver-api/media/drivers/dvb-usb.rst b/Documentation/driver-api/media/drivers/dvb-usb.rst
new file mode 100644
index 000000000000..b2d5d9e62b30
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/dvb-usb.rst
@@ -0,0 +1,357 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Idea behind the dvb-usb-framework
+=================================
+
+.. note::
+
+   #) This documentation is outdated. Please check at the DVB wiki
+      at https://linuxtv.org/wiki for more updated info.
+
+   #) **deprecated:** Newer DVB USB drivers should use the dvb-usb-v2 framework.
+
+In March 2005 I got the new Twinhan USB2.0 DVB-T device. They provided specs
+and a firmware.
+
+Quite keen I wanted to put the driver (with some quirks of course) into dibusb.
+After reading some specs and doing some USB snooping, it realized, that the
+dibusb-driver would be a complete mess afterwards. So I decided to do it in a
+different way: With the help of a dvb-usb-framework.
+
+The framework provides generic functions (mostly kernel API calls), such as:
+
+- Transport Stream URB handling in conjunction with dvb-demux-feed-control
+  (bulk and isoc are supported)
+- registering the device for the DVB-API
+- registering an I2C-adapter if applicable
+- remote-control/input-device handling
+- firmware requesting and loading (currently just for the Cypress USB
+  controllers)
+- other functions/methods which can be shared by several drivers (such as
+  functions for bulk-control-commands)
+- TODO: a I2C-chunker. It creates device-specific chunks of register-accesses
+  depending on length of a register and the number of values that can be
+  multi-written and multi-read.
+
+The source code of the particular DVB USB devices does just the communication
+with the device via the bus. The connection between the DVB-API-functionality
+is done via callbacks, assigned in a static device-description (struct
+dvb_usb_device) each device-driver has to have.
+
+For an example have a look in drivers/media/usb/dvb-usb/vp7045*.
+
+Objective is to migrate all the usb-devices (dibusb, cinergyT2, maybe the
+ttusb; flexcop-usb already benefits from the generic flexcop-device) to use
+the dvb-usb-lib.
+
+TODO: dynamic enabling and disabling of the pid-filter in regard to number of
+feeds requested.
+
+Supported devices
+-----------------
+
+See the LinuxTV DVB Wiki at https://linuxtv.org for a complete list of
+cards/drivers/firmwares:
+https://linuxtv.org/wiki/index.php/DVB_USB
+
+0. History & News:
+
+  2005-06-30
+
+  - added support for WideView WT-220U (Thanks to Steve Chang)
+
+  2005-05-30
+
+  - added basic isochronous support to the dvb-usb-framework
+  - added support for Conexant Hybrid reference design and Nebula
+	       DigiTV USB
+
+  2005-04-17
+
+  - all dibusb devices ported to make use of the dvb-usb-framework
+
+  2005-04-02
+
+  - re-enabled and improved remote control code.
+
+  2005-03-31
+
+  - ported the Yakumo/Hama/Typhoon DVB-T USB2.0 device to dvb-usb.
+
+  2005-03-30
+
+  - first commit of the dvb-usb-module based on the dibusb-source.
+    First device is a new driver for the
+    TwinhanDTV Alpha / MagicBox II USB2.0-only DVB-T device.
+  - (change from dvb-dibusb to dvb-usb)
+
+  2005-03-28
+
+  - added support for the AVerMedia AverTV DVB-T USB2.0 device
+    (Thanks to Glen Harris and Jiun-Kuei Jung, AVerMedia)
+
+  2005-03-14
+
+  - added support for the Typhoon/Yakumo/HAMA DVB-T mobile USB2.0
+
+  2005-02-11
+
+  - added support for the KWorld/ADSTech Instant DVB-T USB2.0.
+    Thanks a lot to Joachim von Caron
+
+  2005-02-02
+  - added support for the Hauppauge Win-TV Nova-T USB2
+
+  2005-01-31
+  - distorted streaming is gone for USB1.1 devices
+
+  2005-01-13
+
+  - moved the mirrored pid_filter_table back to dvb-dibusb
+    first almost working version for HanfTek UMT-010
+    found out, that Yakumo/HAMA/Typhoon are predecessors of the HanfTek UMT-010
+
+  2005-01-10
+
+  - refactoring completed, now everything is very delightful
+
+  - tuner quirks for some weird devices (Artec T1 AN2235 device has sometimes a
+    Panasonic Tuner assembled). Tunerprobing implemented.
+    Thanks a lot to Gunnar Wittich.
+
+  2004-12-29
+
+  - after several days of struggling around bug of no returning URBs fixed.
+
+  2004-12-26
+
+  - refactored the dibusb-driver, split into separate files
+  - i2c-probing enabled
+
+  2004-12-06
+
+  - possibility for demod i2c-address probing
+  - new usb IDs (Compro, Artec)
+
+  2004-11-23
+
+  - merged changes from DiB3000MC_ver2.1
+  - revised the debugging
+  - possibility to deliver the complete TS for USB2.0
+
+  2004-11-21
+
+  - first working version of the dib3000mc/p frontend driver.
+
+  2004-11-12
+
+  - added additional remote control keys. Thanks to Uwe Hanke.
+
+  2004-11-07
+
+  - added remote control support. Thanks to David Matthews.
+
+  2004-11-05
+
+  - added support for a new devices (Grandtec/Avermedia/Artec)
+  - merged my changes (for dib3000mb/dibusb) to the FE_REFACTORING, because it became HEAD
+  - moved transfer control (pid filter, fifo control) from usb driver to frontend, it seems
+    better settled there (added xfer_ops-struct)
+  - created a common files for frontends (mc/p/mb)
+
+  2004-09-28
+
+  - added support for a new device (Unknown, vendor ID is Hyper-Paltek)
+
+  2004-09-20
+
+  - added support for a new device (Compro DVB-U2000), thanks
+    to Amaury Demol for reporting
+  - changed usb TS transfer method (several urbs, stopping transfer
+    before setting a new pid)
+
+  2004-09-13
+
+  - added support for a new device (Artec T1 USB TVBOX), thanks
+    to Christian Motschke for reporting
+
+  2004-09-05
+
+  - released the dibusb device and dib3000mb-frontend driver
+    (old news for vp7041.c)
+
+  2004-07-15
+
+  - found out, by accident, that the device has a TUA6010XS for PLL
+
+  2004-07-12
+
+  - figured out, that the driver should also work with the
+    CTS Portable (Chinese Television System)
+
+  2004-07-08
+
+  - firmware-extraction-2.422-problem solved, driver is now working
+    properly with firmware extracted from 2.422
+  - #if for 2.6.4 (dvb), compile issue
+  - changed firmware handling, see vp7041.txt sec 1.1
+
+  2004-07-02
+
+  - some tuner modifications, v0.1, cleanups, first public
+
+  2004-06-28
+
+  - now using the dvb_dmx_swfilter_packets, everything runs fine now
+
+  2004-06-27
+
+  - able to watch and switching channels (pre-alpha)
+  - no section filtering yet
+
+  2004-06-06
+
+  - first TS received, but kernel oops :/
+
+  2004-05-14
+
+  - firmware loader is working
+
+  2004-05-11
+
+  - start writing the driver
+
+How to use?
+-----------
+
+Firmware
+~~~~~~~~
+
+Most of the USB drivers need to download a firmware to the device before start
+working.
+
+Have a look at the Wikipage for the DVB-USB-drivers to find out, which firmware
+you need for your device:
+
+https://linuxtv.org/wiki/index.php/DVB_USB
+
+Compiling
+~~~~~~~~~
+
+Since the driver is in the linux kernel, activating the driver in
+your favorite config-environment should sufficient. I recommend
+to compile the driver as module. Hotplug does the rest.
+
+If you use dvb-kernel enter the build-2.6 directory run 'make' and 'insmod.sh
+load' afterwards.
+
+Loading the drivers
+~~~~~~~~~~~~~~~~~~~
+
+Hotplug is able to load the driver, when it is needed (because you plugged
+in the device).
+
+If you want to enable debug output, you have to load the driver manually and
+from within the dvb-kernel cvs repository.
+
+first have a look, which debug level are available:
+
+.. code-block:: none
+
+	# modinfo dvb-usb
+	# modinfo dvb-usb-vp7045
+
+	etc.
+
+.. code-block:: none
+
+	modprobe dvb-usb debug=<level>
+	modprobe dvb-usb-vp7045 debug=<level>
+	etc.
+
+should do the trick.
+
+When the driver is loaded successfully, the firmware file was in
+the right place and the device is connected, the "Power"-LED should be
+turned on.
+
+At this point you should be able to start a dvb-capable application. I'm use
+(t|s)zap, mplayer and dvbscan to test the basics. VDR-xine provides the
+long-term test scenario.
+
+Known problems and bugs
+-----------------------
+
+- Don't remove the USB device while running an DVB application, your system
+  will go crazy or die most likely.
+
+Adding support for devices
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+TODO
+
+USB1.1 Bandwidth limitation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A lot of the currently supported devices are USB1.1 and thus they have a
+maximum bandwidth of about 5-6 MBit/s when connected to a USB2.0 hub.
+This is not enough for receiving the complete transport stream of a
+DVB-T channel (which is about 16 MBit/s). Normally this is not a
+problem, if you only want to watch TV (this does not apply for HDTV),
+but watching a channel while recording another channel on the same
+frequency simply does not work very well. This applies to all USB1.1
+DVB-T devices, not just the dvb-usb-devices)
+
+The bug, where the TS is distorted by a heavy usage of the device is gone
+definitely. All dvb-usb-devices I was using (Twinhan, Kworld, DiBcom) are
+working like charm now with VDR. Sometimes I even was able to record a channel
+and watch another one.
+
+Comments
+~~~~~~~~
+
+Patches, comments and suggestions are very very welcome.
+
+3. Acknowledgements
+-------------------
+
+   Amaury Demol (Amaury.Demol@parrot.com) and Francois Kanounnikoff from DiBcom for
+   providing specs, code and help, on which the dvb-dibusb, dib3000mb and
+   dib3000mc are based.
+
+   David Matthews for identifying a new device type (Artec T1 with AN2235)
+   and for extending dibusb with remote control event handling. Thank you.
+
+   Alex Woods for frequently answering question about usb and dvb
+   stuff, a big thank you.
+
+   Bernd Wagner for helping with huge bug reports and discussions.
+
+   Gunnar Wittich and Joachim von Caron for their trust for providing
+   root-shells on their machines to implement support for new devices.
+
+   Allan Third and Michael Hutchinson for their help to write the Nebula
+   digitv-driver.
+
+   Glen Harris for bringing up, that there is a new dibusb-device and Jiun-Kuei
+   Jung from AVerMedia who kindly provided a special firmware to get the device
+   up and running in Linux.
+
+   Jennifer Chen, Jeff and Jack from Twinhan for kindly supporting by
+   writing the vp7045-driver.
+
+   Steve Chang from WideView for providing information for new devices and
+   firmware files.
+
+   Michael Paxton for submitting remote control keymaps.
+
+   Some guys on the linux-dvb mailing list for encouraging me.
+
+   Peter Schildmann >peter.schildmann-nospam-at-web.de< for his
+   user-level firmware loader, which saves a lot of time
+   (when writing the vp7041 driver)
+
+   Ulf Hermenau for helping me out with traditional chinese.
+
+   André Smoktun and Christian Frömmel for supporting me with
+   hardware and listening to my problems very patiently.
diff --git a/Documentation/driver-api/media/drivers/fimc-devel.rst b/Documentation/driver-api/media/drivers/fimc-devel.rst
new file mode 100644
index 000000000000..956e3a9901f8
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/fimc-devel.rst
@@ -0,0 +1,33 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: <isonum.txt>
+
+The Samsung S5P/EXYNOS4 FIMC driver
+===================================
+
+Copyright |copy| 2012 - 2013 Samsung Electronics Co., Ltd.
+
+Files partitioning
+------------------
+
+- media device driver
+
+  drivers/media/platform/exynos4-is/media-dev.[ch]
+
+- camera capture video device driver
+
+  drivers/media/platform/exynos4-is/fimc-capture.c
+
+- MIPI-CSI2 receiver subdev
+
+  drivers/media/platform/exynos4-is/mipi-csis.[ch]
+
+- video post-processor (mem-to-mem)
+
+  drivers/media/platform/exynos4-is/fimc-core.c
+
+- common files
+
+  drivers/media/platform/exynos4-is/fimc-core.h
+  drivers/media/platform/exynos4-is/fimc-reg.h
+  drivers/media/platform/exynos4-is/regs-fimc.h
diff --git a/Documentation/driver-api/media/drivers/frontends.rst b/Documentation/driver-api/media/drivers/frontends.rst
new file mode 100644
index 000000000000..7b8336ece681
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/frontends.rst
@@ -0,0 +1,32 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+****************
+Frontend drivers
+****************
+
+Frontend attach headers
+***********************
+
+.. Keep it on alphabetic order
+
+.. kernel-doc:: drivers/media/dvb-frontends/a8293.h
+.. kernel-doc:: drivers/media/dvb-frontends/af9013.h
+.. kernel-doc:: drivers/media/dvb-frontends/ascot2e.h
+.. kernel-doc:: drivers/media/dvb-frontends/cxd2820r.h
+.. kernel-doc:: drivers/media/dvb-frontends/drxk.h
+.. kernel-doc:: drivers/media/dvb-frontends/dvb-pll.h
+.. kernel-doc:: drivers/media/dvb-frontends/helene.h
+.. kernel-doc:: drivers/media/dvb-frontends/horus3a.h
+.. kernel-doc:: drivers/media/dvb-frontends/ix2505v.h
+.. kernel-doc:: drivers/media/dvb-frontends/m88ds3103.h
+.. kernel-doc:: drivers/media/dvb-frontends/mb86a20s.h
+.. kernel-doc:: drivers/media/dvb-frontends/mn88472.h
+.. kernel-doc:: drivers/media/dvb-frontends/rtl2830.h
+.. kernel-doc:: drivers/media/dvb-frontends/rtl2832.h
+.. kernel-doc:: drivers/media/dvb-frontends/rtl2832_sdr.h
+.. kernel-doc:: drivers/media/dvb-frontends/stb6000.h
+.. kernel-doc:: drivers/media/dvb-frontends/tda10071.h
+.. kernel-doc:: drivers/media/dvb-frontends/tda826x.h
+.. kernel-doc:: drivers/media/dvb-frontends/zd1301_demod.h
+.. kernel-doc:: drivers/media/dvb-frontends/zl10036.h
+
diff --git a/Documentation/driver-api/media/drivers/index.rst b/Documentation/driver-api/media/drivers/index.rst
new file mode 100644
index 000000000000..0df85fc96605
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/index.rst
@@ -0,0 +1,38 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: <isonum.txt>
+
+===================================
+Media driver-specific documentation
+===================================
+
+Video4Linux (V4L) drivers
+=========================
+
+.. toctree::
+	:maxdepth: 5
+
+	bttv-devel
+	cpia2_devel
+	cx2341x-devel
+	cx88-devel
+	davinci-vpbe-devel
+	fimc-devel
+	pvrusb2
+	pxa_camera
+	radiotrack
+	saa7134-devel
+	sh_mobile_ceu_camera
+	tuners
+	vimc-devel
+
+
+Digital TV drivers
+==================
+
+.. toctree::
+	:maxdepth: 5
+
+	dvb-usb
+	frontends
+	contributors
diff --git a/Documentation/driver-api/media/drivers/pvrusb2.rst b/Documentation/driver-api/media/drivers/pvrusb2.rst
new file mode 100644
index 000000000000..83bfaa531ea8
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/pvrusb2.rst
@@ -0,0 +1,202 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+The pvrusb2 driver
+==================
+
+Author: Mike Isely <isely@pobox.com>
+
+Background
+----------
+
+This driver is intended for the "Hauppauge WinTV PVR USB 2.0", which
+is a USB 2.0 hosted TV Tuner.  This driver is a work in progress.
+Its history started with the reverse-engineering effort by Björn
+Danielsson <pvrusb2@dax.nu> whose web page can be found here:
+http://pvrusb2.dax.nu/
+
+From there Aurelien Alleaume <slts@free.fr> began an effort to
+create a video4linux compatible driver.  I began with Aurelien's
+last known snapshot and evolved the driver to the state it is in
+here.
+
+More information on this driver can be found at:
+http://www.isely.net/pvrusb2.html
+
+
+This driver has a strong separation of layers.  They are very
+roughly:
+
+1. Low level wire-protocol implementation with the device.
+
+2. I2C adaptor implementation and corresponding I2C client drivers
+   implemented elsewhere in V4L.
+
+3. High level hardware driver implementation which coordinates all
+   activities that ensure correct operation of the device.
+
+4. A "context" layer which manages instancing of driver, setup,
+   tear-down, arbitration, and interaction with high level
+   interfaces appropriately as devices are hotplugged in the
+   system.
+
+5. High level interfaces which glue the driver to various published
+   Linux APIs (V4L, sysfs, maybe DVB in the future).
+
+The most important shearing layer is between the top 2 layers.  A
+lot of work went into the driver to ensure that any kind of
+conceivable API can be laid on top of the core driver.  (Yes, the
+driver internally leverages V4L to do its work but that really has
+nothing to do with the API published by the driver to the outside
+world.)  The architecture allows for different APIs to
+simultaneously access the driver.  I have a strong sense of fairness
+about APIs and also feel that it is a good design principle to keep
+implementation and interface isolated from each other.  Thus while
+right now the V4L high level interface is the most complete, the
+sysfs high level interface will work equally well for similar
+functions, and there's no reason I see right now why it shouldn't be
+possible to produce a DVB high level interface that can sit right
+alongside V4L.
+
+Building
+--------
+
+To build these modules essentially amounts to just running "Make",
+but you need the kernel source tree nearby and you will likely also
+want to set a few controlling environment variables first in order
+to link things up with that source tree.  Please see the Makefile
+here for comments that explain how to do that.
+
+Source file list / functional overview
+--------------------------------------
+
+(Note: The term "module" used below generally refers to loosely
+defined functional units within the pvrusb2 driver and bears no
+relation to the Linux kernel's concept of a loadable module.)
+
+pvrusb2-audio.[ch] - This is glue logic that resides between this
+    driver and the msp3400.ko I2C client driver (which is found
+    elsewhere in V4L).
+
+pvrusb2-context.[ch] - This module implements the context for an
+    instance of the driver.  Everything else eventually ties back to
+    or is otherwise instanced within the data structures implemented
+    here.  Hotplugging is ultimately coordinated here.  All high level
+    interfaces tie into the driver through this module.  This module
+    helps arbitrate each interface's access to the actual driver core,
+    and is designed to allow concurrent access through multiple
+    instances of multiple interfaces (thus you can for example change
+    the tuner's frequency through sysfs while simultaneously streaming
+    video through V4L out to an instance of mplayer).
+
+pvrusb2-debug.h - This header defines a printk() wrapper and a mask
+    of debugging bit definitions for the various kinds of debug
+    messages that can be enabled within the driver.
+
+pvrusb2-debugifc.[ch] - This module implements a crude command line
+    oriented debug interface into the driver.  Aside from being part
+    of the process for implementing manual firmware extraction (see
+    the pvrusb2 web site mentioned earlier), probably I'm the only one
+    who has ever used this.  It is mainly a debugging aid.
+
+pvrusb2-eeprom.[ch] - This is glue logic that resides between this
+    driver the tveeprom.ko module, which is itself implemented
+    elsewhere in V4L.
+
+pvrusb2-encoder.[ch] - This module implements all protocol needed to
+    interact with the Conexant mpeg2 encoder chip within the pvrusb2
+    device.  It is a crude echo of corresponding logic in ivtv,
+    however the design goals (strict isolation) and physical layer
+    (proxy through USB instead of PCI) are enough different that this
+    implementation had to be completely different.
+
+pvrusb2-hdw-internal.h - This header defines the core data structure
+    in the driver used to track ALL internal state related to control
+    of the hardware.  Nobody outside of the core hardware-handling
+    modules should have any business using this header.  All external
+    access to the driver should be through one of the high level
+    interfaces (e.g. V4L, sysfs, etc), and in fact even those high
+    level interfaces are restricted to the API defined in
+    pvrusb2-hdw.h and NOT this header.
+
+pvrusb2-hdw.h - This header defines the full internal API for
+    controlling the hardware.  High level interfaces (e.g. V4L, sysfs)
+    will work through here.
+
+pvrusb2-hdw.c - This module implements all the various bits of logic
+    that handle overall control of a specific pvrusb2 device.
+    (Policy, instantiation, and arbitration of pvrusb2 devices fall
+    within the jurisdiction of pvrusb-context not here).
+
+pvrusb2-i2c-chips-\*.c - These modules implement the glue logic to
+    tie together and configure various I2C modules as they attach to
+    the I2C bus.  There are two versions of this file.  The "v4l2"
+    version is intended to be used in-tree alongside V4L, where we
+    implement just the logic that makes sense for a pure V4L
+    environment.  The "all" version is intended for use outside of
+    V4L, where we might encounter other possibly "challenging" modules
+    from ivtv or older kernel snapshots (or even the support modules
+    in the standalone snapshot).
+
+pvrusb2-i2c-cmd-v4l1.[ch] - This module implements generic V4L1
+    compatible commands to the I2C modules.  It is here where state
+    changes inside the pvrusb2 driver are translated into V4L1
+    commands that are in turn send to the various I2C modules.
+
+pvrusb2-i2c-cmd-v4l2.[ch] - This module implements generic V4L2
+    compatible commands to the I2C modules.  It is here where state
+    changes inside the pvrusb2 driver are translated into V4L2
+    commands that are in turn send to the various I2C modules.
+
+pvrusb2-i2c-core.[ch] - This module provides an implementation of a
+    kernel-friendly I2C adaptor driver, through which other external
+    I2C client drivers (e.g. msp3400, tuner, lirc) may connect and
+    operate corresponding chips within the pvrusb2 device.  It is
+    through here that other V4L modules can reach into this driver to
+    operate specific pieces (and those modules are in turn driven by
+    glue logic which is coordinated by pvrusb2-hdw, doled out by
+    pvrusb2-context, and then ultimately made available to users
+    through one of the high level interfaces).
+
+pvrusb2-io.[ch] - This module implements a very low level ring of
+    transfer buffers, required in order to stream data from the
+    device.  This module is *very* low level.  It only operates the
+    buffers and makes no attempt to define any policy or mechanism for
+    how such buffers might be used.
+
+pvrusb2-ioread.[ch] - This module layers on top of pvrusb2-io.[ch]
+    to provide a streaming API usable by a read() system call style of
+    I/O.  Right now this is the only layer on top of pvrusb2-io.[ch],
+    however the underlying architecture here was intended to allow for
+    other styles of I/O to be implemented with additional modules, like
+    mmap()'ed buffers or something even more exotic.
+
+pvrusb2-main.c - This is the top level of the driver.  Module level
+    and USB core entry points are here.  This is our "main".
+
+pvrusb2-sysfs.[ch] - This is the high level interface which ties the
+    pvrusb2 driver into sysfs.  Through this interface you can do
+    everything with the driver except actually stream data.
+
+pvrusb2-tuner.[ch] - This is glue logic that resides between this
+    driver and the tuner.ko I2C client driver (which is found
+    elsewhere in V4L).
+
+pvrusb2-util.h - This header defines some common macros used
+    throughout the driver.  These macros are not really specific to
+    the driver, but they had to go somewhere.
+
+pvrusb2-v4l2.[ch] - This is the high level interface which ties the
+    pvrusb2 driver into video4linux.  It is through here that V4L
+    applications can open and operate the driver in the usual V4L
+    ways.  Note that **ALL** V4L functionality is published only
+    through here and nowhere else.
+
+pvrusb2-video-\*.[ch] - This is glue logic that resides between this
+    driver and the saa711x.ko I2C client driver (which is found
+    elsewhere in V4L).  Note that saa711x.ko used to be known as
+    saa7115.ko in ivtv.  There are two versions of this; one is
+    selected depending on the particular saa711[5x].ko that is found.
+
+pvrusb2.h - This header contains compile time tunable parameters
+    (and at the moment the driver has very little that needs to be
+    tuned).
diff --git a/Documentation/driver-api/media/drivers/pxa_camera.rst b/Documentation/driver-api/media/drivers/pxa_camera.rst
new file mode 100644
index 000000000000..ee1bd96b66dd
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/pxa_camera.rst
@@ -0,0 +1,194 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+PXA-Camera Host Driver
+======================
+
+Author: Robert Jarzmik <robert.jarzmik@free.fr>
+
+Constraints
+-----------
+
+a) Image size for YUV422P format
+   All YUV422P images are enforced to have width x height % 16 = 0.
+   This is due to DMA constraints, which transfers only planes of 8 byte
+   multiples.
+
+
+Global video workflow
+---------------------
+
+a) QCI stopped
+   Initially, the QCI interface is stopped.
+   When a buffer is queued (pxa_videobuf_ops->buf_queue), the QCI starts.
+
+b) QCI started
+   More buffers can be queued while the QCI is started without halting the
+   capture.  The new buffers are "appended" at the tail of the DMA chain, and
+   smoothly captured one frame after the other.
+
+   Once a buffer is filled in the QCI interface, it is marked as "DONE" and
+   removed from the active buffers list. It can be then requeud or dequeued by
+   userland application.
+
+   Once the last buffer is filled in, the QCI interface stops.
+
+c) Capture global finite state machine schema
+
+.. code-block:: none
+
+	+----+                             +---+  +----+
+	| DQ |                             | Q |  | DQ |
+	|    v                             |   v  |    v
+	+-----------+                     +------------------------+
+	|   STOP    |                     | Wait for capture start |
+	+-----------+         Q           +------------------------+
+	+-> | QCI: stop | ------------------> | QCI: run               | <------------+
+	|   | DMA: stop |                     | DMA: stop              |              |
+	|   +-----------+             +-----> +------------------------+              |
+	|                            /                            |                   |
+	|                           /             +---+  +----+   |                   |
+	|capture list empty        /              | Q |  | DQ |   | QCI Irq EOF       |
+	|                         /               |   v  |    v   v                   |
+	|   +--------------------+             +----------------------+               |
+	|   | DMA hotlink missed |             |    Capture running   |               |
+	|   +--------------------+             +----------------------+               |
+	|   | QCI: run           |     +-----> | QCI: run             | <-+           |
+	|   | DMA: stop          |    /        | DMA: run             |   |           |
+	|   +--------------------+   /         +----------------------+   | Other     |
+	|     ^                     /DMA still            |               | channels  |
+	|     | capture list       /  running             | DMA Irq End   | not       |
+	|     | not empty         /                       |               | finished  |
+	|     |                  /                        v               | yet       |
+	|   +----------------------+           +----------------------+   |           |
+	|   |  Videobuf released   |           |  Channel completed   |   |           |
+	|   +----------------------+           +----------------------+   |           |
+	+-- | QCI: run             |           | QCI: run             | --+           |
+	| DMA: run             |           | DMA: run             |               |
+	+----------------------+           +----------------------+               |
+		^                      /           |                           |
+		|          no overrun /            | overrun                   |
+		|                    /             v                           |
+	+--------------------+         /   +----------------------+               |
+	|  Frame completed   |        /    |     Frame overran    |               |
+	+--------------------+ <-----+     +----------------------+ restart frame |
+	| QCI: run           |             | QCI: stop            | --------------+
+	| DMA: run           |             | DMA: stop            |
+	+--------------------+             +----------------------+
+
+	Legend: - each box is a FSM state
+		- each arrow is the condition to transition to another state
+		- an arrow with a comment is a mandatory transition (no condition)
+		- arrow "Q" means : a buffer was enqueued
+		- arrow "DQ" means : a buffer was dequeued
+		- "QCI: stop" means the QCI interface is not enabled
+		- "DMA: stop" means all 3 DMA channels are stopped
+		- "DMA: run" means at least 1 DMA channel is still running
+
+DMA usage
+---------
+
+a) DMA flow
+     - first buffer queued for capture
+       Once a first buffer is queued for capture, the QCI is started, but data
+       transfer is not started. On "End Of Frame" interrupt, the irq handler
+       starts the DMA chain.
+     - capture of one videobuffer
+       The DMA chain starts transferring data into videobuffer RAM pages.
+       When all pages are transferred, the DMA irq is raised on "ENDINTR" status
+     - finishing one videobuffer
+       The DMA irq handler marks the videobuffer as "done", and removes it from
+       the active running queue
+       Meanwhile, the next videobuffer (if there is one), is transferred by DMA
+     - finishing the last videobuffer
+       On the DMA irq of the last videobuffer, the QCI is stopped.
+
+b) DMA prepared buffer will have this structure
+
+.. code-block:: none
+
+     +------------+-----+---------------+-----------------+
+     | desc-sg[0] | ... | desc-sg[last] | finisher/linker |
+     +------------+-----+---------------+-----------------+
+
+This structure is pointed by dma->sg_cpu.
+The descriptors are used as follows:
+
+- desc-sg[i]: i-th descriptor, transferring the i-th sg
+  element to the video buffer scatter gather
+- finisher: has ddadr=DADDR_STOP, dcmd=ENDIRQEN
+- linker: has ddadr= desc-sg[0] of next video buffer, dcmd=0
+
+For the next schema, let's assume d0=desc-sg[0] .. dN=desc-sg[N],
+"f" stands for finisher and "l" for linker.
+A typical running chain is :
+
+.. code-block:: none
+
+         Videobuffer 1         Videobuffer 2
+     +---------+----+---+  +----+----+----+---+
+     | d0 | .. | dN | l |  | d0 | .. | dN | f |
+     +---------+----+-|-+  ^----+----+----+---+
+                      |    |
+                      +----+
+
+After the chaining is finished, the chain looks like :
+
+.. code-block:: none
+
+         Videobuffer 1         Videobuffer 2         Videobuffer 3
+     +---------+----+---+  +----+----+----+---+  +----+----+----+---+
+     | d0 | .. | dN | l |  | d0 | .. | dN | l |  | d0 | .. | dN | f |
+     +---------+----+-|-+  ^----+----+----+-|-+  ^----+----+----+---+
+                      |    |                |    |
+                      +----+                +----+
+                                           new_link
+
+c) DMA hot chaining timeslice issue
+
+As DMA chaining is done while DMA _is_ running, the linking may be done
+while the DMA jumps from one Videobuffer to another. On the schema, that
+would be a problem if the following sequence is encountered :
+
+- DMA chain is Videobuffer1 + Videobuffer2
+- pxa_videobuf_queue() is called to queue Videobuffer3
+- DMA controller finishes Videobuffer2, and DMA stops
+
+.. code-block:: none
+
+      =>
+         Videobuffer 1         Videobuffer 2
+     +---------+----+---+  +----+----+----+---+
+     | d0 | .. | dN | l |  | d0 | .. | dN | f |
+     +---------+----+-|-+  ^----+----+----+-^-+
+                      |    |                |
+                      +----+                +-- DMA DDADR loads DDADR_STOP
+
+- pxa_dma_add_tail_buf() is called, the Videobuffer2 "finisher" is
+  replaced by a "linker" to Videobuffer3 (creation of new_link)
+- pxa_videobuf_queue() finishes
+- the DMA irq handler is called, which terminates Videobuffer2
+- Videobuffer3 capture is not scheduled on DMA chain (as it stopped !!!)
+
+.. code-block:: none
+
+         Videobuffer 1         Videobuffer 2         Videobuffer 3
+     +---------+----+---+  +----+----+----+---+  +----+----+----+---+
+     | d0 | .. | dN | l |  | d0 | .. | dN | l |  | d0 | .. | dN | f |
+     +---------+----+-|-+  ^----+----+----+-|-+  ^----+----+----+---+
+                      |    |                |    |
+                      +----+                +----+
+                                           new_link
+                                          DMA DDADR still is DDADR_STOP
+
+- pxa_camera_check_link_miss() is called
+  This checks if the DMA is finished and a buffer is still on the
+  pcdev->capture list. If that's the case, the capture will be restarted,
+  and Videobuffer3 is scheduled on DMA chain.
+- the DMA irq handler finishes
+
+.. note::
+
+     If DMA stops just after pxa_camera_check_link_miss() reads DDADR()
+     value, we have the guarantee that the DMA irq handler will be called back
+     when the DMA will finish the buffer, and pxa_camera_check_link_miss() will
+     be called again, to reschedule Videobuffer3.
diff --git a/Documentation/driver-api/media/drivers/radiotrack.rst b/Documentation/driver-api/media/drivers/radiotrack.rst
new file mode 100644
index 000000000000..a85cb6205db8
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/radiotrack.rst
@@ -0,0 +1,168 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+The Radiotrack radio driver
+===========================
+
+Author: Stephen M. Benoit <benoits@servicepro.com>
+
+Date:  Dec 14, 1996
+
+ACKNOWLEDGMENTS
+----------------
+
+This document was made based on 'C' code for Linux from Gideon le Grange
+(legrang@active.co.za or legrang@cs.sun.ac.za) in 1994, and elaborations from
+Frans Brinkman (brinkman@esd.nl) in 1996.  The results reported here are from
+experiments that the author performed on his own setup, so your mileage may
+vary... I make no guarantees, claims or warranties to the suitability or
+validity of this information.  No other documentation on the AIMS
+Lab (http://www.aimslab.com/) RadioTrack card was made available to the
+author.  This document is offered in the hopes that it might help users who
+want to use the RadioTrack card in an environment other than MS Windows.
+
+WHY THIS DOCUMENT?
+------------------
+
+I have a RadioTrack card from back when I ran an MS-Windows platform.  After
+converting to Linux, I found Gideon le Grange's command-line software for
+running the card, and found that it was good!  Frans Brinkman made a
+comfortable X-windows interface, and added a scanning feature.  For hack
+value, I wanted to see if the tuner could be tuned beyond the usual FM radio
+broadcast band, so I could pick up the audio carriers from North American
+broadcast TV channels, situated just below and above the 87.0-109.0 MHz range.
+I did not get much success, but I learned about programming ioports under
+Linux and gained some insights about the hardware design used for the card.
+
+So, without further delay, here are the details.
+
+
+PHYSICAL DESCRIPTION
+--------------------
+
+The RadioTrack card is an ISA 8-bit FM radio card.  The radio frequency (RF)
+input is simply an antenna lead, and the output is a power audio signal
+available through a miniature phone plug.  Its RF frequencies of operation are
+more or less limited from 87.0 to 109.0 MHz (the commercial FM broadcast
+band).  Although the registers can be programmed to request frequencies beyond
+these limits, experiments did not give promising results.  The variable
+frequency oscillator (VFO) that demodulates the intermediate frequency (IF)
+signal probably has a small range of useful frequencies, and wraps around or
+gets clipped beyond the limits mentioned above.
+
+
+CONTROLLING THE CARD WITH IOPORT
+--------------------------------
+
+The RadioTrack (base) ioport is configurable for 0x30c or 0x20c.  Only one
+ioport seems to be involved.  The ioport decoding circuitry must be pretty
+simple, as individual ioport bits are directly matched to specific functions
+(or blocks) of the radio card.  This way, many functions can be changed in
+parallel with one write to the ioport.  The only feedback available through
+the ioports appears to be the "Stereo Detect" bit.
+
+The bits of the ioport are arranged as follows:
+
+.. code-block:: none
+
+	MSb                                                         LSb
+	+------+------+------+--------+--------+-------+---------+--------+
+	| VolA | VolB | ???? | Stereo | Radio  | TuneA | TuneB   | Tune   |
+	|  (+) |  (-) |      | Detect | Audio  | (bit) | (latch) | Update |
+	|      |      |      | Enable | Enable |       |         | Enable |
+	+------+------+------+--------+--------+-------+---------+--------+
+
+
+====  ====  =================================
+VolA  VolB  Description
+====  ====  =================================
+0	 0  audio mute
+0	 1  volume +    (some delay required)
+1	 0  volume -    (some delay required)
+1	 1  stay at present volume
+====  ====  =================================
+
+====================	===========
+Stereo Detect Enable	Description
+====================	===========
+0			No Detect
+1			Detect
+====================	===========
+
+Results available by reading ioport >60 msec after last port write.
+
+  0xff ==> no stereo detected,  0xfd ==> stereo detected.
+
+=============================	=============================
+Radio to Audio (path) Enable	Description
+=============================	=============================
+0				Disable path (silence)
+1				Enable path  (audio produced)
+=============================	=============================
+
+=====  =====  ==================
+TuneA  TuneB  Description
+=====  =====  ==================
+0	0     "zero" bit phase 1
+0	1     "zero" bit phase 2
+1	0     "one" bit phase 1
+1	1     "one" bit phase 2
+=====  =====  ==================
+
+
+24-bit code, where bits = (freq*40) + 10486188.
+The Most Significant 11 bits must be 1010 xxxx 0x0 to be valid.
+The bits are shifted in LSb first.
+
+==================	===========================
+Tune Update Enable	Description
+==================	===========================
+0			Tuner held constant
+1			Tuner updating in progress
+==================	===========================
+
+
+PROGRAMMING EXAMPLES
+--------------------
+
+.. code-block:: none
+
+	Default:        BASE <-- 0xc8  (current volume, no stereo detect,
+					radio enable, tuner adjust disable)
+
+	Card Off:	BASE <-- 0x00  (audio mute, no stereo detect,
+					radio disable, tuner adjust disable)
+
+	Card On:	BASE <-- 0x00  (see "Card Off", clears any unfinished business)
+			BASE <-- 0xc8  (see "Default")
+
+	Volume Down:    BASE <-- 0x48  (volume down, no stereo detect,
+					radio enable, tuner adjust disable)
+			wait 10 msec
+			BASE <-- 0xc8  (see "Default")
+
+	Volume Up:      BASE <-- 0x88  (volume up, no stereo detect,
+					radio enable, tuner adjust disable)
+			wait 10 msec
+			BASE <-- 0xc8  (see "Default")
+
+	Check Stereo:   BASE <-- 0xd8  (current volume, stereo detect,
+					radio enable, tuner adjust disable)
+			wait 100 msec
+			x <-- BASE     (read ioport)
+			BASE <-- 0xc8  (see "Default")
+
+			x=0xff ==> "not stereo", x=0xfd ==> "stereo detected"
+
+	Set Frequency:  code = (freq*40) + 10486188
+			foreach of the 24 bits in code,
+			(from Least to Most Significant):
+			to write a "zero" bit,
+			BASE <-- 0x01  (audio mute, no stereo detect, radio
+					disable, "zero" bit phase 1, tuner adjust)
+			BASE <-- 0x03  (audio mute, no stereo detect, radio
+					disable, "zero" bit phase 2, tuner adjust)
+			to write a "one" bit,
+			BASE <-- 0x05  (audio mute, no stereo detect, radio
+					disable, "one" bit phase 1, tuner adjust)
+			BASE <-- 0x07  (audio mute, no stereo detect, radio
+					disable, "one" bit phase 2, tuner adjust)
diff --git a/Documentation/driver-api/media/drivers/saa7134-devel.rst b/Documentation/driver-api/media/drivers/saa7134-devel.rst
new file mode 100644
index 000000000000..167fd729bc8c
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/saa7134-devel.rst
@@ -0,0 +1,67 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+The saa7134 driver
+==================
+
+Author Gerd Hoffmann
+
+
+Card Variations:
+----------------
+
+Cards can use either of these two crystals (xtal):
+
+- 32.11 MHz -> .audio_clock=0x187de7
+- 24.576MHz -> .audio_clock=0x200000 (xtal * .audio_clock = 51539600)
+
+Some details about 30/34/35:
+
+- saa7130 - low-price chip, doesn't have mute, that is why all those
+  cards should have .mute field defined in their tuner structure.
+
+- saa7134 - usual chip
+
+- saa7133/35 - saa7135 is probably a marketing decision, since all those
+  chips identifies itself as 33 on pci.
+
+LifeView GPIOs
+--------------
+
+This section was authored by: Peter Missel <peter.missel@onlinehome.de>
+
+- LifeView FlyTV Platinum FM (LR214WF)
+
+    - GP27    MDT2005 PB4 pin 10
+    - GP26    MDT2005 PB3 pin 9
+    - GP25    MDT2005 PB2 pin 8
+    - GP23    MDT2005 PB1 pin 7
+    - GP22    MDT2005 PB0 pin 6
+    - GP21    MDT2005 PB5 pin 11
+    - GP20    MDT2005 PB6 pin 12
+    - GP19    MDT2005 PB7 pin 13
+    - nc      MDT2005 PA3 pin 2
+    - Remote  MDT2005 PA2 pin 1
+    - GP18    MDT2005 PA1 pin 18
+    - nc      MDT2005 PA0 pin 17 strap low
+    - GP17    Strap "GP7"=High
+    - GP16    Strap "GP6"=High
+
+	- 0=Radio 1=TV
+	- Drives SA630D ENCH1 and HEF4052 A1 pinsto do FM radio through
+	  SIF input
+
+    - GP15    nc
+    - GP14    nc
+    - GP13    nc
+    - GP12    Strap "GP5" = High
+    - GP11    Strap "GP4" = High
+    - GP10    Strap "GP3" = High
+    - GP09    Strap "GP2" = Low
+    - GP08    Strap "GP1" = Low
+    - GP07.00 nc
+
+Credits
+-------
+
+andrew.stevens@philips.com + werner.leeb@philips.com for providing
+saa7134 hardware specs and sample board.
diff --git a/Documentation/driver-api/media/drivers/sh_mobile_ceu_camera.rst b/Documentation/driver-api/media/drivers/sh_mobile_ceu_camera.rst
new file mode 100644
index 000000000000..822fcb8368ae
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/sh_mobile_ceu_camera.rst
@@ -0,0 +1,142 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Cropping and Scaling algorithm, used in the sh_mobile_ceu_camera driver
+=======================================================================
+
+Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+
+Terminology
+-----------
+
+sensor scales: horizontal and vertical scales, configured by the sensor driver
+host scales: -"- host driver
+combined scales: sensor_scale * host_scale
+
+
+Generic scaling / cropping scheme
+---------------------------------
+
+.. code-block:: none
+
+	-1--
+	|
+	-2-- -\
+	|      --\
+	|         --\
+	+-5-- .      -- -3-- -\
+	|      `...            -\
+	|          `... -4-- .   - -7..
+	|                     `.
+	|                       `. .6--
+	|
+	|                        . .6'-
+	|                      .´
+	|           ... -4'- .´
+	|       ...´             - -7'.
+	+-5'- .´               -/
+	|            -- -3'- -/
+	|         --/
+	|      --/
+	-2'- -/
+	|
+	|
+	-1'-
+
+In the above chart minuses and slashes represent "real" data amounts, points and
+accents represent "useful" data, basically, CEU scaled and cropped output,
+mapped back onto the client's source plane.
+
+Such a configuration can be produced by user requests:
+
+S_CROP(left / top = (5) - (1), width / height = (5') - (5))
+S_FMT(width / height = (6') - (6))
+
+Here:
+
+(1) to (1') - whole max width or height
+(1) to (2)  - sensor cropped left or top
+(2) to (2') - sensor cropped width or height
+(3) to (3') - sensor scale
+(3) to (4)  - CEU cropped left or top
+(4) to (4') - CEU cropped width or height
+(5) to (5') - reverse sensor scale applied to CEU cropped width or height
+(2) to (5)  - reverse sensor scale applied to CEU cropped left or top
+(6) to (6') - CEU scale - user window
+
+
+S_FMT
+-----
+
+Do not touch input rectangle - it is already optimal.
+
+1. Calculate current sensor scales:
+
+	scale_s = ((2') - (2)) / ((3') - (3))
+
+2. Calculate "effective" input crop (sensor subwindow) - CEU crop scaled back at
+current sensor scales onto input window - this is user S_CROP:
+
+	width_u = (5') - (5) = ((4') - (4)) * scale_s
+
+3. Calculate new combined scales from "effective" input window to requested user
+window:
+
+	scale_comb = width_u / ((6') - (6))
+
+4. Calculate sensor output window by applying combined scales to real input
+window:
+
+	width_s_out = ((7') - (7)) = ((2') - (2)) / scale_comb
+
+5. Apply iterative sensor S_FMT for sensor output window.
+
+	subdev->video_ops->s_fmt(.width = width_s_out)
+
+6. Retrieve sensor output window (g_fmt)
+
+7. Calculate new sensor scales:
+
+	scale_s_new = ((3')_new - (3)_new) / ((2') - (2))
+
+8. Calculate new CEU crop - apply sensor scales to previously calculated
+"effective" crop:
+
+	width_ceu = (4')_new - (4)_new = width_u / scale_s_new
+	left_ceu = (4)_new - (3)_new = ((5) - (2)) / scale_s_new
+
+9. Use CEU cropping to crop to the new window:
+
+	ceu_crop(.width = width_ceu, .left = left_ceu)
+
+10. Use CEU scaling to scale to the requested user window:
+
+	scale_ceu = width_ceu / width
+
+
+S_CROP
+------
+
+The :ref:`V4L2 crop API <crop-scale>` says:
+
+"...specification does not define an origin or units. However by convention
+drivers should horizontally count unscaled samples relative to 0H."
+
+We choose to follow the advise and interpret cropping units as client input
+pixels.
+
+Cropping is performed in the following 6 steps:
+
+1. Request exactly user rectangle from the sensor.
+
+2. If smaller - iterate until a larger one is obtained. Result: sensor cropped
+   to 2 : 2', target crop 5 : 5', current output format 6' - 6.
+
+3. In the previous step the sensor has tried to preserve its output frame as
+   good as possible, but it could have changed. Retrieve it again.
+
+4. Sensor scaled to 3 : 3'. Sensor's scale is (2' - 2) / (3' - 3). Calculate
+   intermediate window: 4' - 4 = (5' - 5) * (3' - 3) / (2' - 2)
+
+5. Calculate and apply host scale = (6' - 6) / (4' - 4)
+
+6. Calculate and apply host crop: 6 - 7 = (5 - 2) * (6' - 6) / (5' - 5)
diff --git a/Documentation/driver-api/media/drivers/tuners.rst b/Documentation/driver-api/media/drivers/tuners.rst
new file mode 100644
index 000000000000..7509be888909
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/tuners.rst
@@ -0,0 +1,133 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Tuner drivers
+=============
+
+Simple tuner Programming
+------------------------
+
+There are some flavors of Tuner programming APIs.
+These differ mainly by the bandswitch byte.
+
+- L= LG_API       (VHF_LO=0x01, VHF_HI=0x02, UHF=0x08, radio=0x04)
+- P= PHILIPS_API  (VHF_LO=0xA0, VHF_HI=0x90, UHF=0x30, radio=0x04)
+- T= TEMIC_API    (VHF_LO=0x02, VHF_HI=0x04, UHF=0x01)
+- A= ALPS_API     (VHF_LO=0x14, VHF_HI=0x12, UHF=0x11)
+- M= PHILIPS_MK3  (VHF_LO=0x01, VHF_HI=0x02, UHF=0x04, radio=0x19)
+
+Tuner Manufacturers
+-------------------
+
+- SAMSUNG Tuner identification: (e.g. TCPM9091PD27)
+
+.. code-block:: none
+
+ TCP [ABCJLMNQ] 90[89][125] [DP] [ACD] 27 [ABCD]
+ [ABCJLMNQ]:
+   A= BG+DK
+   B= BG
+   C= I+DK
+   J= NTSC-Japan
+   L= Secam LL
+   M= BG+I+DK
+   N= NTSC
+   Q= BG+I+DK+LL
+ [89]: ?
+ [125]:
+   2: No FM
+   5: With FM
+ [DP]:
+   D= NTSC
+   P= PAL
+ [ACD]:
+   A= F-connector
+   C= Phono connector
+   D= Din Jack
+ [ABCD]:
+   3-wire/I2C tuning, 2-band/3-band
+
+These Tuners are PHILIPS_API compatible.
+
+Philips Tuner identification: (e.g. FM1216MF)
+
+.. code-block:: none
+
+  F[IRMQ]12[1345]6{MF|ME|MP}
+  F[IRMQ]:
+   FI12x6: Tuner Series
+   FR12x6: Tuner + Radio IF
+   FM12x6: Tuner + FM
+   FQ12x6: special
+   FMR12x6: special
+   TD15xx: Digital Tuner ATSC
+  12[1345]6:
+   1216: PAL BG
+   1236: NTSC
+   1246: PAL I
+   1256: Pal DK
+  {MF|ME|MP}
+   MF: BG LL w/ Secam (Multi France)
+   ME: BG DK I LL   (Multi Europe)
+   MP: BG DK I      (Multi PAL)
+   MR: BG DK M (?)
+   MG: BG DKI M (?)
+  MK2 series PHILIPS_API, most tuners are compatible to this one !
+  MK3 series introduced in 2002 w/ PHILIPS_MK3_API
+
+Temic Tuner identification: (.e.g 4006FH5)
+
+.. code-block:: none
+
+   4[01][0136][269]F[HYNR]5
+    40x2: Tuner (5V/33V), TEMIC_API.
+    40x6: Tuner 5V
+    41xx: Tuner compact
+    40x9: Tuner+FM compact
+   [0136]
+    xx0x: PAL BG
+    xx1x: Pal DK, Secam LL
+    xx3x: NTSC
+    xx6x: PAL I
+   F[HYNR]5
+    FH5: Pal BG
+    FY5: others
+    FN5: multistandard
+    FR5: w/ FM radio
+   3X xxxx: order number with specific connector
+  Note: Only 40x2 series has TEMIC_API, all newer tuners have PHILIPS_API.
+
+LG Innotek Tuner:
+
+- TPI8NSR11 : NTSC J/M    (TPI8NSR01 w/FM)  (P,210/497)
+- TPI8PSB11 : PAL B/G     (TPI8PSB01 w/FM)  (P,170/450)
+- TAPC-I701 : PAL I       (TAPC-I001 w/FM)  (P,170/450)
+- TPI8PSB12 : PAL D/K+B/G (TPI8PSB02 w/FM)  (P,170/450)
+- TAPC-H701P: NTSC_JP     (TAPC-H001P w/FM) (L,170/450)
+- TAPC-G701P: PAL B/G     (TAPC-G001P w/FM) (L,170/450)
+- TAPC-W701P: PAL I       (TAPC-W001P w/FM) (L,170/450)
+- TAPC-Q703P: PAL D/K     (TAPC-Q001P w/FM) (L,170/450)
+- TAPC-Q704P: PAL D/K+I   (L,170/450)
+- TAPC-G702P: PAL D/K+B/G (L,170/450)
+
+- TADC-H002F: NTSC (L,175/410?; 2-B, C-W+11, W+12-69)
+- TADC-M201D: PAL D/K+B/G+I (L,143/425)  (sound control at I2C address 0xc8)
+- TADC-T003F: NTSC Taiwan  (L,175/410?; 2-B, C-W+11, W+12-69)
+
+Suffix:
+  - P= Standard phono female socket
+  - D= IEC female socket
+  - F= F-connector
+
+Other Tuners:
+
+- TCL2002MB-1 : PAL BG + DK       =TUNER_LG_PAL_NEW_TAPC
+- TCL2002MB-1F: PAL BG + DK w/FM  =PHILIPS_PAL
+- TCL2002MI-2 : PAL I		= ??
+
+ALPS Tuners:
+
+- Most are LG_API compatible
+- TSCH6 has ALPS_API (TSCH5 ?)
+- TSBE1 has extra API 05,02,08 Control_byte=0xCB Source:[#f1]_
+
+.. [#f1] conexant100029b-PCI-Decoder-ApplicationNote.pdf
diff --git a/Documentation/driver-api/media/drivers/vimc-devel.rst b/Documentation/driver-api/media/drivers/vimc-devel.rst
new file mode 100644
index 000000000000..9e984f914b13
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/vimc-devel.rst
@@ -0,0 +1,15 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+The Virtual Media Controller Driver (vimc)
+==========================================
+
+Source code documentation
+-------------------------
+
+vimc-streamer
+~~~~~~~~~~~~~
+
+.. kernel-doc:: drivers/media/test-drivers/vimc/vimc-streamer.h
+   :internal:
+
+.. kernel-doc:: drivers/media/test-drivers/vimc/vimc-streamer.c
diff --git a/Documentation/driver-api/media/dtv-ca.rst b/Documentation/driver-api/media/dtv-ca.rst
new file mode 100644
index 000000000000..8a09862b428b
--- /dev/null
+++ b/Documentation/driver-api/media/dtv-ca.rst
@@ -0,0 +1,6 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Digital TV Conditional Access kABI
+----------------------------------
+
+.. kernel-doc:: include/media/dvb_ca_en50221.h
diff --git a/Documentation/driver-api/media/dtv-common.rst b/Documentation/driver-api/media/dtv-common.rst
new file mode 100644
index 000000000000..f8b2c4dc8170
--- /dev/null
+++ b/Documentation/driver-api/media/dtv-common.rst
@@ -0,0 +1,62 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Digital TV Common functions
+---------------------------
+
+Math functions
+~~~~~~~~~~~~~~
+
+Provide some commonly-used math functions, usually required in order to
+estimate signal strength and signal to noise measurements in dB.
+
+.. kernel-doc:: include/media/dvb_math.h
+
+
+DVB devices
+~~~~~~~~~~~
+
+Those functions are responsible for handling the DVB device nodes.
+
+.. kernel-doc:: include/media/dvbdev.h
+
+Digital TV Ring buffer
+~~~~~~~~~~~~~~~~~~~~~~
+
+Those routines implement ring buffers used to handle digital TV data and
+copy it from/to userspace.
+
+.. note::
+
+  1) For performance reasons read and write routines don't check buffer sizes
+     and/or number of bytes free/available. This has to be done before these
+     routines are called. For example:
+
+   .. code-block:: c
+
+        /* write @buflen: bytes */
+        free = dvb_ringbuffer_free(rbuf);
+        if (free >= buflen)
+                count = dvb_ringbuffer_write(rbuf, buffer, buflen);
+        else
+                /* do something */
+
+        /* read min. 1000, max. @bufsize: bytes */
+        avail = dvb_ringbuffer_avail(rbuf);
+        if (avail >= 1000)
+                count = dvb_ringbuffer_read(rbuf, buffer, min(avail, bufsize));
+        else
+                /* do something */
+
+  2) If there is exactly one reader and one writer, there is no need
+     to lock read or write operations.
+     Two or more readers must be locked against each other.
+     Flushing the buffer counts as a read operation.
+     Resetting the buffer counts as a read and write operation.
+     Two or more writers must be locked against each other.
+
+.. kernel-doc:: include/media/dvb_ringbuffer.h
+
+Digital TV VB2 handler
+~~~~~~~~~~~~~~~~~~~~~~
+
+.. kernel-doc:: include/media/dvb_vb2.h
diff --git a/Documentation/driver-api/media/dtv-core.rst b/Documentation/driver-api/media/dtv-core.rst
new file mode 100644
index 000000000000..82c5b85ed9b1
--- /dev/null
+++ b/Documentation/driver-api/media/dtv-core.rst
@@ -0,0 +1,39 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Digital TV (DVB) devices
+------------------------
+
+Digital TV devices are implemented by several different drivers:
+
+- A bridge driver that is responsible to talk with the bus where the other
+  devices are connected (PCI, USB, SPI), bind to the other drivers and
+  implement the digital demux logic (either in software or in hardware);
+
+- Frontend drivers that are usually implemented as two separate drivers:
+
+  - A tuner driver that implements the logic which commands the part of
+    the hardware responsible for tuning into a digital TV transponder or
+    physical channel. The output of a tuner is usually a baseband or
+    Intermediate Frequency (IF) signal;
+
+  - A demodulator driver (a.k.a "demod") that implements the logic which
+    commands the digital TV decoding hardware. The output of a demod is
+    a digital stream, with multiple audio, video and data channels typically
+    multiplexed using MPEG Transport Stream [#f1]_.
+
+On most hardware, the frontend drivers talk with the bridge driver using an
+I2C bus.
+
+.. [#f1] Some standards use TCP/IP for multiplexing data, like DVB-H (an
+   abandoned standard, not used anymore) and ATSC version 3.0 current
+   proposals. Currently, the DVB subsystem doesn't implement those standards.
+
+
+.. toctree::
+    :maxdepth: 1
+
+    dtv-common
+    dtv-frontend
+    dtv-demux
+    dtv-ca
+    dtv-net
diff --git a/Documentation/driver-api/media/dtv-demux.rst b/Documentation/driver-api/media/dtv-demux.rst
new file mode 100644
index 000000000000..c0ae5dec5328
--- /dev/null
+++ b/Documentation/driver-api/media/dtv-demux.rst
@@ -0,0 +1,84 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Digital TV Demux kABI
+---------------------
+
+Digital TV Demux
+~~~~~~~~~~~~~~~~
+
+The Kernel Digital TV Demux kABI defines a driver-internal interface for
+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
+``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.
+When the demux client allocates a resource via the demux kABI, it receives
+a pointer to the kABI of that resource.
+
+Each demux receives its TS input from a DVB front-end or from memory, as
+set via this demux kABI. In a system with more than one front-end, the kABI
+can be used to select one of the DVB front-ends as a TS source for a demux,
+unless this is fixed in the HW platform.
+
+The demux kABI only controls front-ends regarding to their connections with
+demuxes; the kABI used to set the other front-end parameters, such as
+tuning, are devined via the Digital TV Frontend kABI.
+
+The functions that implement the abstract interface demux should be defined
+static or module private and registered to the Demux core for external
+access. It is not necessary to implement every function in the struct
+:c:type:`dmx_demux`. For example, a demux interface might support Section filtering,
+but not PES filtering. The kABI client is expected to check the value of any
+function pointer before calling the function: the value of ``NULL`` means
+that the function is not available.
+
+Whenever the functions of the demux API modify shared data, the
+possibilities of lost update and race condition problems should be
+addressed, e.g. by protecting parts of code with mutexes.
+
+Note that functions called from a bottom half context must not sleep.
+Even a simple memory allocation without using ``GFP_ATOMIC`` can result in a
+kernel thread being put to sleep if swapping is needed. For example, the
+Linux Kernel calls the functions of a network device interface from a
+bottom half context. Thus, if a demux kABI function is called from network
+device code, the function must not sleep.
+
+Demux Callback API
+~~~~~~~~~~~~~~~~~~
+
+This kernel-space API comprises the callback functions that deliver filtered
+data to the demux client. Unlike the other DVB kABIs, these functions are
+provided by the client and called from the demux code.
+
+The function pointers of this abstract interface are not packed into a
+structure as in the other demux APIs, because the callback functions are
+registered and used independent of each other. As an example, it is possible
+for the API client to provide several callback functions for receiving TS
+packets and no callbacks for PES packets or sections.
+
+The functions that implement the callback API need not be re-entrant: when
+a demux driver calls one of these functions, the driver is not allowed to
+call the function again before the original call returns. If a callback is
+triggered by a hardware interrupt, it is recommended to use the Linux
+bottom half mechanism or start a tasklet instead of making the callback
+function call directly from a hardware interrupt.
+
+This mechanism is implemented by :c:func:`dmx_ts_cb()` and :c:func:`dmx_section_cb()`
+callbacks.
+
+Digital TV Demux device registration functions and data structures
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. kernel-doc:: include/media/dmxdev.h
+
+High-level Digital TV demux interface
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. kernel-doc:: include/media/dvb_demux.h
+
+Driver-internal low-level hardware specific driver demux interface
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. kernel-doc:: include/media/demux.h
diff --git a/Documentation/driver-api/media/dtv-frontend.rst b/Documentation/driver-api/media/dtv-frontend.rst
new file mode 100644
index 000000000000..b362109bb131
--- /dev/null
+++ b/Documentation/driver-api/media/dtv-frontend.rst
@@ -0,0 +1,445 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Digital TV Frontend kABI
+------------------------
+
+Digital TV Frontend
+~~~~~~~~~~~~~~~~~~~
+
+The Digital TV Frontend kABI defines a driver-internal interface for
+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
+``include/media/``.
+
+Demodulator driver
+^^^^^^^^^^^^^^^^^^
+
+The demodulator driver is responsible for talking with the decoding part of the
+hardware. Such driver should implement :c:type:`dvb_frontend_ops`, which
+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 ``include/media/dvb_frontend.c``.
+
+A typical example of such struct in a driver ``foo`` is::
+
+	static struct dvb_frontend_ops foo_ops = {
+		.delsys = { SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A },
+		.info = {
+			.name	= "foo DVB-T/T2/C driver",
+			.caps = FE_CAN_FEC_1_2 |
+				FE_CAN_FEC_2_3 |
+				FE_CAN_FEC_3_4 |
+				FE_CAN_FEC_5_6 |
+				FE_CAN_FEC_7_8 |
+				FE_CAN_FEC_AUTO |
+				FE_CAN_QPSK |
+				FE_CAN_QAM_16 |
+				FE_CAN_QAM_32 |
+				FE_CAN_QAM_64 |
+				FE_CAN_QAM_128 |
+				FE_CAN_QAM_256 |
+				FE_CAN_QAM_AUTO |
+				FE_CAN_TRANSMISSION_MODE_AUTO |
+				FE_CAN_GUARD_INTERVAL_AUTO |
+				FE_CAN_HIERARCHY_AUTO |
+				FE_CAN_MUTE_TS |
+				FE_CAN_2G_MODULATION,
+			.frequency_min = 42000000, /* Hz */
+			.frequency_max = 1002000000, /* Hz */
+			.symbol_rate_min = 870000,
+			.symbol_rate_max = 11700000
+		},
+		.init = foo_init,
+		.sleep = foo_sleep,
+		.release = foo_release,
+		.set_frontend = foo_set_frontend,
+		.get_frontend = foo_get_frontend,
+		.read_status = foo_get_status_and_stats,
+		.tune = foo_tune,
+		.i2c_gate_ctrl = foo_i2c_gate_ctrl,
+		.get_frontend_algo = foo_get_algo,
+	};
+
+A typical example of such struct in a driver ``bar`` meant to be used on
+Satellite TV reception is::
+
+	static const struct dvb_frontend_ops bar_ops = {
+		.delsys = { SYS_DVBS, SYS_DVBS2 },
+		.info = {
+			.name		= "Bar DVB-S/S2 demodulator",
+			.frequency_min	= 500000, /* KHz */
+			.frequency_max	= 2500000, /* KHz */
+			.frequency_stepsize	= 0,
+			.symbol_rate_min = 1000000,
+			.symbol_rate_max = 45000000,
+			.symbol_rate_tolerance = 500,
+			.caps = FE_CAN_INVERSION_AUTO |
+				FE_CAN_FEC_AUTO |
+				FE_CAN_QPSK,
+		},
+		.init = bar_init,
+		.sleep = bar_sleep,
+		.release = bar_release,
+		.set_frontend = bar_set_frontend,
+		.get_frontend = bar_get_frontend,
+		.read_status = bar_get_status_and_stats,
+		.i2c_gate_ctrl = bar_i2c_gate_ctrl,
+		.get_frontend_algo = bar_get_algo,
+		.tune = bar_tune,
+
+		/* Satellite-specific */
+		.diseqc_send_master_cmd = bar_send_diseqc_msg,
+		.diseqc_send_burst = bar_send_burst,
+		.set_tone = bar_set_tone,
+		.set_voltage = bar_set_voltage,
+	};
+
+.. note::
+
+   #) For satellite digital TV standards (DVB-S, DVB-S2, ISDB-S), the
+      frequencies are specified in kHz, while, for terrestrial and cable
+      standards, they're specified in Hz. Due to that, if the same frontend
+      supports both types, you'll need to have two separate
+      :c:type:`dvb_frontend_ops` structures, one for each standard.
+   #) The ``.i2c_gate_ctrl`` field is present only when the hardware has
+      allows controlling an I2C gate (either directly of via some GPIO pin),
+      in order to remove the tuner from the I2C bus after a channel is
+      tuned.
+   #) All new drivers should implement the
+      :ref:`DVBv5 statistics <dvbv5_stats>` via ``.read_status``.
+      Yet, there are a number of callbacks meant to get statistics for
+      signal strength, S/N and UCB. Those are there to provide backward
+      compatibility with legacy applications that don't support the DVBv5
+      API. Implementing those callbacks are optional. Those callbacks may be
+      removed in the future, after we have all existing drivers supporting
+      DVBv5 stats.
+   #) Other callbacks are required for satellite TV standards, in order to
+      control LNBf and DiSEqC: ``.diseqc_send_master_cmd``,
+      ``.diseqc_send_burst``, ``.set_tone``, ``.set_voltage``.
+
+.. |delta|   unicode:: U+00394
+
+The ``include/media/dvb_frontend.c`` has a kernel thread which is
+responsible for tuning the device. It supports multiple algorithms to
+detect a channel, as defined at enum :c:func:`dvbfe_algo`.
+
+The algorithm to be used is obtained via ``.get_frontend_algo``. If the driver
+doesn't fill its field at struct :c:type:`dvb_frontend_ops`, it will default to
+``DVBFE_ALGO_SW``, meaning that the dvb-core will do a zigzag when tuning,
+e. g. it will try first to use the specified center frequency ``f``,
+then, it will do ``f`` + |delta|, ``f`` - |delta|, ``f`` + 2 x |delta|,
+``f`` - 2 x |delta| and so on.
+
+If the hardware has internally a some sort of zigzag algorithm, you should
+define a ``.get_frontend_algo`` function that would return ``DVBFE_ALGO_HW``.
+
+.. note::
+
+   The core frontend support also supports
+   a third type (``DVBFE_ALGO_CUSTOM``), in order to allow the driver to
+   define its own hardware-assisted algorithm. Very few hardware need to
+   use it nowadays. Using ``DVBFE_ALGO_CUSTOM`` require to provide other
+   function callbacks at struct :c:type:`dvb_frontend_ops`.
+
+Attaching frontend driver to the bridge driver
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Before using the Digital TV frontend core, the bridge driver should attach
+the frontend demod, tuner and SEC devices and call
+:c:func:`dvb_register_frontend()`,
+in order to register the new frontend at the subsystem. At device
+detach/removal, the bridge driver should call
+:c:func:`dvb_unregister_frontend()` to
+remove the frontend from the core and then :c:func:`dvb_frontend_detach()`
+to free the memory allocated by the frontend drivers.
+
+The drivers should also call :c:func:`dvb_frontend_suspend()` as part of
+their handler for the :c:type:`device_driver`.\ ``suspend()``, and
+:c:func:`dvb_frontend_resume()` as
+part of their handler for :c:type:`device_driver`.\ ``resume()``.
+
+A few other optional functions are provided to handle some special cases.
+
+.. _dvbv5_stats:
+
+Digital TV Frontend statistics
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Introduction
+^^^^^^^^^^^^
+
+Digital TV frontends provide a range of
+:ref:`statistics <frontend-stat-properties>` meant to help tuning the device
+and measuring the quality of service.
+
+For each statistics measurement, the driver should set the type of scale used,
+or ``FE_SCALE_NOT_AVAILABLE`` if the statistics is not available on a given
+time. Drivers should also provide the number of statistics for each type.
+that's usually 1 for most video standards [#f2]_.
+
+Drivers should initialize each statistic counters with length and
+scale at its init code. For example, if the frontend provides signal
+strength, it should have, on its init code::
+
+	struct dtv_frontend_properties *c = &state->fe.dtv_property_cache;
+
+	c->strength.len = 1;
+	c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+
+And, when the statistics got updated, set the scale::
+
+	c->strength.stat[0].scale = FE_SCALE_DECIBEL;
+	c->strength.stat[0].uvalue = strength;
+
+.. [#f2] For ISDB-T, it may provide both a global statistics and a per-layer
+   set of statistics. On such cases, len should be equal to 4. The first
+   value corresponds to the global stat; the other ones to each layer, e. g.:
+
+   - c->cnr.stat[0] for global S/N carrier ratio,
+   - c->cnr.stat[1] for Layer A S/N carrier ratio,
+   - c->cnr.stat[2] for layer B S/N carrier ratio,
+   - c->cnr.stat[3] for layer C S/N carrier ratio.
+
+.. note:: Please prefer to use ``FE_SCALE_DECIBEL`` instead of
+   ``FE_SCALE_RELATIVE`` for signal strength and CNR measurements.
+
+Groups of statistics
+^^^^^^^^^^^^^^^^^^^^
+
+There are several groups of statistics currently supported:
+
+Signal strength (:ref:`DTV-STAT-SIGNAL-STRENGTH`)
+  - Measures the signal strength level at the analog part of the tuner or
+    demod.
+
+  - Typically obtained from the gain applied to the tuner and/or frontend
+    in order to detect the carrier. When no carrier is detected, the gain is
+    at the maximum value (so, strength is on its minimal).
+
+  - As the gain is visible through the set of registers that adjust the gain,
+    typically, this statistics is always available [#f3]_.
+
+  - Drivers should try to make it available all the times, as these statistics
+    can be used when adjusting an antenna position and to check for troubles
+    at the cabling.
+
+  .. [#f3] On a few devices, the gain keeps floating if there is no carrier.
+     On such devices, strength report should check first if carrier is
+     detected at the tuner (``FE_HAS_CARRIER``, see :c:type:`fe_status`),
+     and otherwise return the lowest possible value.
+
+Carrier Signal to Noise ratio (:ref:`DTV-STAT-CNR`)
+  - Signal to Noise ratio for the main carrier.
+
+  - Signal to Noise measurement depends on the device. On some hardware, it is
+    available when the main carrier is detected. On those hardware, CNR
+    measurement usually comes from the tuner (e. g. after ``FE_HAS_CARRIER``,
+    see :c:type:`fe_status`).
+
+    On other devices, it requires inner FEC decoding,
+    as the frontend measures it indirectly from other parameters (e. g. after
+    ``FE_HAS_VITERBI``, see :c:type:`fe_status`).
+
+    Having it available after inner FEC is more common.
+
+Bit counts post-FEC (:ref:`DTV-STAT-POST-ERROR-BIT-COUNT` and :ref:`DTV-STAT-POST-TOTAL-BIT-COUNT`)
+  - Those counters measure the number of bits and bit errors errors after
+    the forward error correction (FEC) on the inner coding block
+    (after Viterbi, LDPC or other inner code).
+
+  - Due to its nature, those statistics depend on full coding lock
+    (e. g. after ``FE_HAS_SYNC`` or after ``FE_HAS_LOCK``,
+    see :c:type:`fe_status`).
+
+Bit counts pre-FEC (:ref:`DTV-STAT-PRE-ERROR-BIT-COUNT` and :ref:`DTV-STAT-PRE-TOTAL-BIT-COUNT`)
+  - Those counters measure the number of bits and bit errors errors before
+    the forward error correction (FEC) on the inner coding block
+    (before Viterbi, LDPC or other inner code).
+
+  - Not all frontends provide this kind of statistics.
+
+  - Due to its nature, those statistics depend on inner coding lock (e. g.
+    after ``FE_HAS_VITERBI``, see :c:type:`fe_status`).
+
+Block counts (:ref:`DTV-STAT-ERROR-BLOCK-COUNT` and :ref:`DTV-STAT-TOTAL-BLOCK-COUNT`)
+  - Those counters measure the number of blocks and block errors errors after
+    the forward error correction (FEC) on the inner coding block
+    (before Viterbi, LDPC or other inner code).
+
+  - Due to its nature, those statistics depend on full coding lock
+    (e. g. after ``FE_HAS_SYNC`` or after
+    ``FE_HAS_LOCK``, see :c:type:`fe_status`).
+
+.. note:: All counters should be monotonically increased as they're
+   collected from the hardware.
+
+A typical example of the logic that handle status and statistics is::
+
+	static int foo_get_status_and_stats(struct dvb_frontend *fe)
+	{
+		struct foo_state *state = fe->demodulator_priv;
+		struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+
+		int rc;
+		enum fe_status *status;
+
+		/* Both status and strength are always available */
+		rc = foo_read_status(fe, &status);
+		if (rc < 0)
+			return rc;
+
+		rc = foo_read_strength(fe);
+		if (rc < 0)
+			return rc;
+
+		/* Check if CNR is available */
+		if (!(fe->status & FE_HAS_CARRIER))
+			return 0;
+
+		rc = foo_read_cnr(fe);
+		if (rc < 0)
+			return rc;
+
+		/* Check if pre-BER stats are available */
+		if (!(fe->status & FE_HAS_VITERBI))
+			return 0;
+
+		rc = foo_get_pre_ber(fe);
+		if (rc < 0)
+			return rc;
+
+		/* Check if post-BER stats are available */
+		if (!(fe->status & FE_HAS_SYNC))
+			return 0;
+
+		rc = foo_get_post_ber(fe);
+		if (rc < 0)
+			return rc;
+	}
+
+	static const struct dvb_frontend_ops ops = {
+		/* ... */
+		.read_status = foo_get_status_and_stats,
+	};
+
+Statistics collection
+^^^^^^^^^^^^^^^^^^^^^
+
+On almost all frontend hardware, the bit and byte counts are stored by
+the hardware after a certain amount of time or after the total bit/block
+counter reaches a certain value (usually programmable), for example, on
+every 1000 ms or after receiving 1,000,000 bits.
+
+So, if you read the registers too soon, you'll end by reading the same
+value as in the previous reading, causing the monotonic value to be
+incremented too often.
+
+Drivers should take the responsibility to avoid too often reads. That
+can be done using two approaches:
+
+if the driver have a bit that indicates when a collected data is ready
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Driver should check such bit before making the statistics available.
+
+An example of such behavior can be found at this code snippet (adapted
+from mb86a20s driver's logic)::
+
+	static int foo_get_pre_ber(struct dvb_frontend *fe)
+	{
+		struct foo_state *state = fe->demodulator_priv;
+		struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+		int rc, bit_error;
+
+		/* Check if the BER measures are already available */
+		rc = foo_read_u8(state, 0x54);
+		if (rc < 0)
+			return rc;
+
+		if (!rc)
+			return 0;
+
+		/* Read Bit Error Count */
+		bit_error = foo_read_u32(state, 0x55);
+		if (bit_error < 0)
+			return bit_error;
+
+		/* Read Total Bit Count */
+		rc = foo_read_u32(state, 0x51);
+		if (rc < 0)
+			return rc;
+
+		c->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
+		c->pre_bit_error.stat[0].uvalue += bit_error;
+		c->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
+		c->pre_bit_count.stat[0].uvalue += rc;
+
+		return 0;
+	}
+
+If the driver doesn't provide a statistics available check bit
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+A few devices, however, may not provide a way to check if the stats are
+available (or the way to check it is unknown). They may not even provide
+a way to directly read the total number of bits or blocks.
+
+On those devices, the driver need to ensure that it won't be reading from
+the register too often and/or estimate the total number of bits/blocks.
+
+On such drivers, a typical routine to get statistics would be like
+(adapted from dib8000 driver's logic)::
+
+	struct foo_state {
+		/* ... */
+
+		unsigned long per_jiffies_stats;
+	}
+
+	static int foo_get_pre_ber(struct dvb_frontend *fe)
+	{
+		struct foo_state *state = fe->demodulator_priv;
+		struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+		int rc, bit_error;
+		u64 bits;
+
+		/* Check if time for stats was elapsed */
+		if (!time_after(jiffies, state->per_jiffies_stats))
+			return 0;
+
+		/* Next stat should be collected in 1000 ms */
+		state->per_jiffies_stats = jiffies + msecs_to_jiffies(1000);
+
+		/* Read Bit Error Count */
+		bit_error = foo_read_u32(state, 0x55);
+		if (bit_error < 0)
+			return bit_error;
+
+		/*
+		 * On this particular frontend, there's no register that
+		 * would provide the number of bits per 1000ms sample. So,
+		 * some function would calculate it based on DTV properties
+		 */
+		bits = get_number_of_bits_per_1000ms(fe);
+
+		c->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
+		c->pre_bit_error.stat[0].uvalue += bit_error;
+		c->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
+		c->pre_bit_count.stat[0].uvalue += bits;
+
+		return 0;
+	}
+
+Please notice that, on both cases, we're getting the statistics using the
+:c:type:`dvb_frontend_ops` ``.read_status`` callback. The rationale is that
+the frontend core will automatically call this function periodically
+(usually, 3 times per second, when the frontend is locked).
+
+That warrants that we won't miss to collect a counter and increment the
+monotonic stats at the right time.
+
+Digital TV Frontend functions and types
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. kernel-doc:: include/media/dvb_frontend.h
diff --git a/Documentation/driver-api/media/dtv-net.rst b/Documentation/driver-api/media/dtv-net.rst
new file mode 100644
index 000000000000..deb6bffe96bb
--- /dev/null
+++ b/Documentation/driver-api/media/dtv-net.rst
@@ -0,0 +1,6 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Digital TV Network kABI
+-----------------------
+
+.. kernel-doc:: include/media/dvb_net.h
diff --git a/Documentation/driver-api/media/index.rst b/Documentation/driver-api/media/index.rst
new file mode 100644
index 000000000000..328350924853
--- /dev/null
+++ b/Documentation/driver-api/media/index.rst
@@ -0,0 +1,54 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: <isonum.txt>
+
+===================================
+Media subsystem kernel internal API
+===================================
+
+This section contains usage information about media subsystem and
+its supported drivers.
+
+Please see:
+
+- :doc:`/admin-guide/media/index`
+    for usage information about media subsystem and supported drivers;
+
+- :doc:`/userspace-api/media/index`
+     for the userspace APIs used on media devices.
+
+
+.. only:: html
+
+   .. class:: toc-title
+
+        Table of Contents
+
+.. toctree::
+    :maxdepth: 5
+    :numbered:
+
+    v4l2-core
+    dtv-core
+    rc-core
+    mc-core
+    cec-core
+    csi2
+
+    drivers/index
+
+**Copyright** |copy| 2009-2020 : LinuxTV Developers
+
+::
+
+  This documentation is free software; you can redistribute it and/or modify it
+  under the terms of the 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.
+
+  For more details see the file COPYING in the source distribution of Linux.
diff --git a/Documentation/driver-api/media/mc-core.rst b/Documentation/driver-api/media/mc-core.rst
new file mode 100644
index 000000000000..05bba0b61748
--- /dev/null
+++ b/Documentation/driver-api/media/mc-core.rst
@@ -0,0 +1,309 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Media Controller devices
+------------------------
+
+Media Controller
+~~~~~~~~~~~~~~~~
+
+The media controller userspace API is documented in
+:ref:`the Media Controller uAPI book <media_controller>`. This document focus
+on the kernel-side implementation of the media framework.
+
+Abstract media device model
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Discovering a device internal topology, and configuring it at runtime, is one
+of the goals of the media framework. To achieve this, hardware devices are
+modelled as an oriented graph of building blocks called entities connected
+through pads.
+
+An entity is a basic media hardware building block. It can correspond to
+a large variety of logical blocks such as physical hardware devices
+(CMOS sensor for instance), logical hardware devices (a building block
+in a System-on-Chip image processing pipeline), DMA channels or physical
+connectors.
+
+A pad is a connection endpoint through which an entity can interact with
+other entities. Data (not restricted to video) produced by an entity
+flows from the entity's output to one or more entity inputs. Pads should
+not be confused with physical pins at chip boundaries.
+
+A link is a point-to-point oriented connection between two pads, either
+on the same entity or on different entities. Data flows from a source
+pad to a sink pad.
+
+Media device
+^^^^^^^^^^^^
+
+A media device is represented by a struct :c:type:`media_device`
+instance, defined in ``include/media/media-device.h``.
+Allocation of the structure is handled by the media device driver, usually by
+embedding the :c:type:`media_device` instance in a larger driver-specific
+structure.
+
+Drivers register media device instances by calling
+:c:func:`__media_device_register()` via the macro ``media_device_register()``
+and unregistered by calling :c:func:`media_device_unregister()`.
+
+Entities
+^^^^^^^^
+
+Entities are represented by a struct :c:type:`media_entity`
+instance, defined in ``include/media/media-entity.h``. The structure is usually
+embedded into a higher-level structure, such as
+:c:type:`v4l2_subdev` or :c:type:`video_device`
+instances, although drivers can allocate entities directly.
+
+Drivers initialize entity pads by calling
+:c:func:`media_entity_pads_init()`.
+
+Drivers register entities with a media device by calling
+:c:func:`media_device_register_entity()`
+and unregistered by calling
+:c:func:`media_device_unregister_entity()`.
+
+Interfaces
+^^^^^^^^^^
+
+Interfaces are represented by a
+struct :c:type:`media_interface` instance, defined in
+``include/media/media-entity.h``. Currently, only one type of interface is
+defined: a device node. Such interfaces are represented by a
+struct :c:type:`media_intf_devnode`.
+
+Drivers initialize and create device node interfaces by calling
+:c:func:`media_devnode_create()`
+and remove them by calling:
+:c:func:`media_devnode_remove()`.
+
+Pads
+^^^^
+Pads are represented by a struct :c:type:`media_pad` instance,
+defined in ``include/media/media-entity.h``. Each entity stores its pads in
+a pads array managed by the entity driver. Drivers usually embed the array in
+a driver-specific structure.
+
+Pads are identified by their entity and their 0-based index in the pads
+array.
+
+Both information are stored in the struct :c:type:`media_pad`,
+making the struct :c:type:`media_pad` pointer the canonical way
+to store and pass link references.
+
+Pads have flags that describe the pad capabilities and state.
+
+``MEDIA_PAD_FL_SINK`` indicates that the pad supports sinking data.
+``MEDIA_PAD_FL_SOURCE`` indicates that the pad supports sourcing data.
+
+.. note::
+
+  One and only one of ``MEDIA_PAD_FL_SINK`` or ``MEDIA_PAD_FL_SOURCE`` must
+  be set for each pad.
+
+Links
+^^^^^
+
+Links are represented by a struct :c:type:`media_link` instance,
+defined in ``include/media/media-entity.h``. There are two types of links:
+
+**1. pad to pad links**:
+
+Associate two entities via their PADs. Each entity has a list that points
+to all links originating at or targeting any of its pads.
+A given link is thus stored twice, once in the source entity and once in
+the target entity.
+
+Drivers create pad to pad links by calling:
+:c:func:`media_create_pad_link()` and remove with
+:c:func:`media_entity_remove_links()`.
+
+**2. interface to entity links**:
+
+Associate one interface to a Link.
+
+Drivers create interface to entity links by calling:
+:c:func:`media_create_intf_link()` and remove with
+:c:func:`media_remove_intf_links()`.
+
+.. note::
+
+   Links can only be created after having both ends already created.
+
+Links have flags that describe the link capabilities and state. The
+valid values are described at :c:func:`media_create_pad_link()` and
+:c:func:`media_create_intf_link()`.
+
+Graph traversal
+^^^^^^^^^^^^^^^
+
+The media framework provides APIs to iterate over entities in a graph.
+
+To iterate over all entities belonging to a media device, drivers can use
+the media_device_for_each_entity macro, defined in
+``include/media/media-device.h``.
+
+..  code-block:: c
+
+    struct media_entity *entity;
+
+    media_device_for_each_entity(entity, mdev) {
+    // entity will point to each entity in turn
+    ...
+    }
+
+Drivers might also need to iterate over all entities in a graph that can be
+reached only through enabled links starting at a given entity. The media
+framework provides a depth-first graph traversal API for that purpose.
+
+.. note::
+
+   Graphs with cycles (whether directed or undirected) are **NOT**
+   supported by the graph traversal API. To prevent infinite loops, the graph
+   traversal code limits the maximum depth to ``MEDIA_ENTITY_ENUM_MAX_DEPTH``,
+   currently defined as 16.
+
+Drivers initiate a graph traversal by calling
+:c:func:`media_graph_walk_start()`
+
+The graph structure, provided by the caller, is initialized to start graph
+traversal at the given entity.
+
+Drivers can then retrieve the next entity by calling
+:c:func:`media_graph_walk_next()`
+
+When the graph traversal is complete the function will return ``NULL``.
+
+Graph traversal can be interrupted at any moment. No cleanup function call
+is required and the graph structure can be freed normally.
+
+Helper functions can be used to find a link between two given pads, or a pad
+connected to another pad through an enabled link
+:c:func:`media_entity_find_link()` and
+:c:func:`media_entity_remote_pad()`.
+
+Use count and power handling
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Due to the wide differences between drivers regarding power management
+needs, the media controller does not implement power management. However,
+the struct :c:type:`media_entity` includes a ``use_count``
+field that media drivers
+can use to track the number of users of every entity for power management
+needs.
+
+The :c:type:`media_entity<media_entity>`.\ ``use_count`` field is owned by
+media drivers and must not be
+touched by entity drivers. Access to the field must be protected by the
+:c:type:`media_device`.\ ``graph_mutex`` lock.
+
+Links setup
+^^^^^^^^^^^
+
+Link properties can be modified at runtime by calling
+:c:func:`media_entity_setup_link()`.
+
+Pipelines and media streams
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+When starting streaming, drivers must notify all entities in the pipeline to
+prevent link states from being modified during streaming by calling
+:c:func:`media_pipeline_start()`.
+
+The function will mark all entities connected to the given entity through
+enabled links, either directly or indirectly, as streaming.
+
+The struct :c:type:`media_pipeline` instance pointed to by
+the pipe argument will be stored in every entity in the pipeline.
+Drivers should embed the struct :c:type:`media_pipeline`
+in higher-level pipeline structures and can then access the
+pipeline through the struct :c:type:`media_entity`
+pipe field.
+
+Calls to :c:func:`media_pipeline_start()` can be nested.
+The pipeline pointer must be identical for all nested calls to the function.
+
+:c:func:`media_pipeline_start()` may return an error. In that case,
+it will clean up any of the changes it did by itself.
+
+When stopping the stream, drivers must notify the entities with
+:c:func:`media_pipeline_stop()`.
+
+If multiple calls to :c:func:`media_pipeline_start()` have been
+made the same number of :c:func:`media_pipeline_stop()` calls
+are required to stop streaming.
+The :c:type:`media_entity`.\ ``pipe`` field is reset to ``NULL`` on the last
+nested stop call.
+
+Link configuration will fail with ``-EBUSY`` by default if either end of the
+link is a streaming entity. Links that can be modified while streaming must
+be marked with the ``MEDIA_LNK_FL_DYNAMIC`` flag.
+
+If other operations need to be disallowed on streaming entities (such as
+changing entities configuration parameters) drivers can explicitly check the
+media_entity stream_count field to find out if an entity is streaming. This
+operation must be done with the media_device graph_mutex held.
+
+Link validation
+^^^^^^^^^^^^^^^
+
+Link validation is performed by :c:func:`media_pipeline_start()`
+for any entity which has sink pads in the pipeline. The
+:c:type:`media_entity`.\ ``link_validate()`` callback is used for that
+purpose. In ``link_validate()`` callback, entity driver should check
+that the properties of the source pad of the connected entity and its own
+sink pad match. It is up to the type of the entity (and in the end, the
+properties of the hardware) what matching actually means.
+
+Subsystems should facilitate link validation by providing subsystem specific
+helper functions to provide easy access for commonly needed information, and
+in the end provide a way to use driver-specific callbacks.
+
+Media Controller Device Allocator API
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+When the media device belongs to more than one driver, the shared media
+device is allocated with the shared struct device as the key for look ups.
+
+The shared media device should stay in registered state until the last
+driver unregisters it. In addition, the media device should be released when
+all the references are released. Each driver gets a reference to the media
+device during probe, when it allocates the media device. If media device is
+already allocated, the allocate API bumps up the refcount and returns the
+existing media device. The driver puts the reference back in its disconnect
+routine when it calls :c:func:`media_device_delete()`.
+
+The media device is unregistered and cleaned up from the kref put handler to
+ensure that the media device stays in registered state until the last driver
+unregisters the media device.
+
+**Driver Usage**
+
+Drivers should use the appropriate media-core routines to manage the shared
+media device life-time handling the two states:
+1. allocate -> register -> delete
+2. get reference to already registered device -> delete
+
+call :c:func:`media_device_delete()` routine to make sure the shared media
+device delete is handled correctly.
+
+**driver probe:**
+Call :c:func:`media_device_usb_allocate()` to allocate or get a reference
+Call :c:func:`media_device_register()`, if media devnode isn't registered
+
+**driver disconnect:**
+Call :c:func:`media_device_delete()` to free the media_device. Freeing is
+handled by the kref put handler.
+
+API Definitions
+^^^^^^^^^^^^^^^
+
+.. kernel-doc:: include/media/media-device.h
+
+.. kernel-doc:: include/media/media-devnode.h
+
+.. kernel-doc:: include/media/media-entity.h
+
+.. kernel-doc:: include/media/media-request.h
+
+.. kernel-doc:: include/media/media-dev-allocator.h
diff --git a/Documentation/driver-api/media/rc-core.rst b/Documentation/driver-api/media/rc-core.rst
new file mode 100644
index 000000000000..53f5e643b6e9
--- /dev/null
+++ b/Documentation/driver-api/media/rc-core.rst
@@ -0,0 +1,88 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Remote Controller devices
+-------------------------
+
+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
diff --git a/Documentation/driver-api/media/v4l2-async.rst b/Documentation/driver-api/media/v4l2-async.rst
new file mode 100644
index 000000000000..3422330b3b1f
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-async.rst
@@ -0,0 +1,5 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+V4L2 async kAPI
+^^^^^^^^^^^^^^^
+.. kernel-doc:: include/media/v4l2-async.h
diff --git a/Documentation/driver-api/media/v4l2-clocks.rst b/Documentation/driver-api/media/v4l2-clocks.rst
new file mode 100644
index 000000000000..5c22eecab7ba
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-clocks.rst
@@ -0,0 +1,31 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+V4L2 clocks
+-----------
+
+.. attention::
+
+	This is a temporary API and it shall be replaced by the generic
+	clock API, when the latter becomes widely available.
+
+Many subdevices, like camera sensors, TV decoders and encoders, need a clock
+signal to be supplied by the system. Often this clock is supplied by the
+respective bridge device. The Linux kernel provides a Common Clock Framework for
+this purpose. However, it is not (yet) available on all architectures. Besides,
+the nature of the multi-functional (clock, data + synchronisation, I2C control)
+connection of subdevices to the system might impose special requirements on the
+clock API usage. E.g. V4L2 has to support clock provider driver unregistration
+while a subdevice driver is holding a reference to the clock. For these reasons
+a V4L2 clock helper API has been developed and is provided to bridge and
+subdevice drivers.
+
+The API consists of two parts: two functions to register and unregister a V4L2
+clock source: v4l2_clk_register() and v4l2_clk_unregister() and calls to control
+a clock object, similar to the respective generic clock API calls:
+v4l2_clk_get(), v4l2_clk_put(), v4l2_clk_enable(), v4l2_clk_disable(),
+v4l2_clk_get_rate(), and v4l2_clk_set_rate(). Clock suppliers have to provide
+clock operations that will be called when clock users invoke respective API
+methods.
+
+It is expected that once the CCF becomes available on all relevant
+architectures this API will be removed.
diff --git a/Documentation/driver-api/media/v4l2-common.rst b/Documentation/driver-api/media/v4l2-common.rst
new file mode 100644
index 000000000000..b1e70eb56aa4
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-common.rst
@@ -0,0 +1,8 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+V4L2 common functions and data structures
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. kernel-doc:: include/media/v4l2-common.h
+
+.. kernel-doc:: include/media/v4l2-ioctl.h
diff --git a/Documentation/driver-api/media/v4l2-controls.rst b/Documentation/driver-api/media/v4l2-controls.rst
new file mode 100644
index 000000000000..5129019afb49
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-controls.rst
@@ -0,0 +1,823 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+V4L2 Controls
+=============
+
+Introduction
+------------
+
+The V4L2 control API seems simple enough, but quickly becomes very hard to
+implement correctly in drivers. But much of the code needed to handle controls
+is actually not driver specific and can be moved to the V4L core framework.
+
+After all, the only part that a driver developer is interested in is:
+
+1) How do I add a control?
+2) How do I set the control's value? (i.e. s_ctrl)
+
+And occasionally:
+
+3) How do I get the control's value? (i.e. g_volatile_ctrl)
+4) How do I validate the user's proposed control value? (i.e. try_ctrl)
+
+All the rest is something that can be done centrally.
+
+The control framework was created in order to implement all the rules of the
+V4L2 specification with respect to controls in a central place. And to make
+life as easy as possible for the driver developer.
+
+Note that the control framework relies on the presence of a struct
+:c:type:`v4l2_device` for V4L2 drivers and struct :c:type:`v4l2_subdev` for
+sub-device drivers.
+
+
+Objects in the framework
+------------------------
+
+There are two main objects:
+
+The :c:type:`v4l2_ctrl` object describes the control properties and keeps
+track of the control's value (both the current value and the proposed new
+value).
+
+:c:type:`v4l2_ctrl_handler` is the object that keeps track of controls. It
+maintains a list of v4l2_ctrl objects that it owns and another list of
+references to controls, possibly to controls owned by other handlers.
+
+
+Basic usage for V4L2 and sub-device drivers
+-------------------------------------------
+
+1) Prepare the driver:
+
+.. code-block:: c
+
+	#include <media/v4l2-ctrls.h>
+
+1.1) Add the handler to your driver's top-level struct:
+
+For V4L2 drivers:
+
+.. code-block:: c
+
+	struct foo_dev {
+		...
+		struct v4l2_device v4l2_dev;
+		...
+		struct v4l2_ctrl_handler ctrl_handler;
+		...
+	};
+
+For sub-device drivers:
+
+.. code-block:: c
+
+	struct foo_dev {
+		...
+		struct v4l2_subdev sd;
+		...
+		struct v4l2_ctrl_handler ctrl_handler;
+		...
+	};
+
+1.2) Initialize the handler:
+
+.. code-block:: c
+
+	v4l2_ctrl_handler_init(&foo->ctrl_handler, nr_of_controls);
+
+The second argument is a hint telling the function how many controls this
+handler is expected to handle. It will allocate a hashtable based on this
+information. It is a hint only.
+
+1.3) Hook the control handler into the driver:
+
+For V4L2 drivers:
+
+.. code-block:: c
+
+	foo->v4l2_dev.ctrl_handler = &foo->ctrl_handler;
+
+For sub-device drivers:
+
+.. code-block:: c
+
+	foo->sd.ctrl_handler = &foo->ctrl_handler;
+
+1.4) Clean up the handler at the end:
+
+.. code-block:: c
+
+	v4l2_ctrl_handler_free(&foo->ctrl_handler);
+
+
+2) Add controls:
+
+You add non-menu controls by calling :c:func:`v4l2_ctrl_new_std`:
+
+.. code-block:: c
+
+	struct v4l2_ctrl *v4l2_ctrl_new_std(struct v4l2_ctrl_handler *hdl,
+			const struct v4l2_ctrl_ops *ops,
+			u32 id, s32 min, s32 max, u32 step, s32 def);
+
+Menu and integer menu controls are added by calling
+:c:func:`v4l2_ctrl_new_std_menu`:
+
+.. code-block:: c
+
+	struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl,
+			const struct v4l2_ctrl_ops *ops,
+			u32 id, s32 max, s32 skip_mask, s32 def);
+
+Menu controls with a driver specific menu are added by calling
+:c:func:`v4l2_ctrl_new_std_menu_items`:
+
+.. code-block:: c
+
+       struct v4l2_ctrl *v4l2_ctrl_new_std_menu_items(
+                       struct v4l2_ctrl_handler *hdl,
+                       const struct v4l2_ctrl_ops *ops, u32 id, s32 max,
+                       s32 skip_mask, s32 def, const char * const *qmenu);
+
+Standard compound controls can be added by calling
+:c:func:`v4l2_ctrl_new_std_compound`:
+
+.. code-block:: c
+
+       struct v4l2_ctrl *v4l2_ctrl_new_std_compound(struct v4l2_ctrl_handler *hdl,
+                       const struct v4l2_ctrl_ops *ops, u32 id,
+                       const union v4l2_ctrl_ptr p_def);
+
+Integer menu controls with a driver specific menu can be added by calling
+:c:func:`v4l2_ctrl_new_int_menu`:
+
+.. code-block:: c
+
+	struct v4l2_ctrl *v4l2_ctrl_new_int_menu(struct v4l2_ctrl_handler *hdl,
+			const struct v4l2_ctrl_ops *ops,
+			u32 id, s32 max, s32 def, const s64 *qmenu_int);
+
+These functions are typically called right after the
+:c:func:`v4l2_ctrl_handler_init`:
+
+.. code-block:: c
+
+	static const s64 exp_bias_qmenu[] = {
+	       -2, -1, 0, 1, 2
+	};
+	static const char * const test_pattern[] = {
+		"Disabled",
+		"Vertical Bars",
+		"Solid Black",
+		"Solid White",
+	};
+
+	v4l2_ctrl_handler_init(&foo->ctrl_handler, nr_of_controls);
+	v4l2_ctrl_new_std(&foo->ctrl_handler, &foo_ctrl_ops,
+			V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
+	v4l2_ctrl_new_std(&foo->ctrl_handler, &foo_ctrl_ops,
+			V4L2_CID_CONTRAST, 0, 255, 1, 128);
+	v4l2_ctrl_new_std_menu(&foo->ctrl_handler, &foo_ctrl_ops,
+			V4L2_CID_POWER_LINE_FREQUENCY,
+			V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0,
+			V4L2_CID_POWER_LINE_FREQUENCY_DISABLED);
+	v4l2_ctrl_new_int_menu(&foo->ctrl_handler, &foo_ctrl_ops,
+			V4L2_CID_EXPOSURE_BIAS,
+			ARRAY_SIZE(exp_bias_qmenu) - 1,
+			ARRAY_SIZE(exp_bias_qmenu) / 2 - 1,
+			exp_bias_qmenu);
+	v4l2_ctrl_new_std_menu_items(&foo->ctrl_handler, &foo_ctrl_ops,
+			V4L2_CID_TEST_PATTERN, ARRAY_SIZE(test_pattern) - 1, 0,
+			0, test_pattern);
+	...
+	if (foo->ctrl_handler.error) {
+		int err = foo->ctrl_handler.error;
+
+		v4l2_ctrl_handler_free(&foo->ctrl_handler);
+		return err;
+	}
+
+The :c:func:`v4l2_ctrl_new_std` function returns the v4l2_ctrl pointer to
+the new control, but if you do not need to access the pointer outside the
+control ops, then there is no need to store it.
+
+The :c:func:`v4l2_ctrl_new_std` function will fill in most fields based on
+the control ID except for the min, max, step and default values. These are
+passed in the last four arguments. These values are driver specific while
+control attributes like type, name, flags are all global. The control's
+current value will be set to the default value.
+
+The :c:func:`v4l2_ctrl_new_std_menu` function is very similar but it is
+used for menu controls. There is no min argument since that is always 0 for
+menu controls, and instead of a step there is a skip_mask argument: if bit
+X is 1, then menu item X is skipped.
+
+The :c:func:`v4l2_ctrl_new_int_menu` function creates a new standard
+integer menu control with driver-specific items in the menu. It differs
+from v4l2_ctrl_new_std_menu in that it doesn't have the mask argument and
+takes as the last argument an array of signed 64-bit integers that form an
+exact menu item list.
+
+The :c:func:`v4l2_ctrl_new_std_menu_items` function is very similar to
+v4l2_ctrl_new_std_menu but takes an extra parameter qmenu, which is the
+driver specific menu for an otherwise standard menu control. A good example
+for this control is the test pattern control for capture/display/sensors
+devices that have the capability to generate test patterns. These test
+patterns are hardware specific, so the contents of the menu will vary from
+device to device.
+
+Note that if something fails, the function will return NULL or an error and
+set ctrl_handler->error to the error code. If ctrl_handler->error was already
+set, then it will just return and do nothing. This is also true for
+v4l2_ctrl_handler_init if it cannot allocate the internal data structure.
+
+This makes it easy to init the handler and just add all controls and only check
+the error code at the end. Saves a lot of repetitive error checking.
+
+It is recommended to add controls in ascending control ID order: it will be
+a bit faster that way.
+
+3) Optionally force initial control setup:
+
+.. code-block:: c
+
+	v4l2_ctrl_handler_setup(&foo->ctrl_handler);
+
+This will call s_ctrl for all controls unconditionally. Effectively this
+initializes the hardware to the default control values. It is recommended
+that you do this as this ensures that both the internal data structures and
+the hardware are in sync.
+
+4) Finally: implement the :c:type:`v4l2_ctrl_ops`
+
+.. code-block:: c
+
+	static const struct v4l2_ctrl_ops foo_ctrl_ops = {
+		.s_ctrl = foo_s_ctrl,
+	};
+
+Usually all you need is s_ctrl:
+
+.. code-block:: c
+
+	static int foo_s_ctrl(struct v4l2_ctrl *ctrl)
+	{
+		struct foo *state = container_of(ctrl->handler, struct foo, ctrl_handler);
+
+		switch (ctrl->id) {
+		case V4L2_CID_BRIGHTNESS:
+			write_reg(0x123, ctrl->val);
+			break;
+		case V4L2_CID_CONTRAST:
+			write_reg(0x456, ctrl->val);
+			break;
+		}
+		return 0;
+	}
+
+The control ops are called with the v4l2_ctrl pointer as argument.
+The new control value has already been validated, so all you need to do is
+to actually update the hardware registers.
+
+You're done! And this is sufficient for most of the drivers we have. No need
+to do any validation of control values, or implement QUERYCTRL, QUERY_EXT_CTRL
+and QUERYMENU. And G/S_CTRL as well as G/TRY/S_EXT_CTRLS are automatically supported.
+
+
+.. note::
+
+   The remainder sections deal with more advanced controls topics and scenarios.
+   In practice the basic usage as described above is sufficient for most drivers.
+
+
+Inheriting Sub-device Controls
+------------------------------
+
+When a sub-device is registered with a V4L2 driver by calling
+v4l2_device_register_subdev() and the ctrl_handler fields of both v4l2_subdev
+and v4l2_device are set, then the controls of the subdev will become
+automatically available in the V4L2 driver as well. If the subdev driver
+contains controls that already exist in the V4L2 driver, then those will be
+skipped (so a V4L2 driver can always override a subdev control).
+
+What happens here is that v4l2_device_register_subdev() calls
+v4l2_ctrl_add_handler() adding the controls of the subdev to the controls
+of v4l2_device.
+
+
+Accessing Control Values
+------------------------
+
+The following union is used inside the control framework to access control
+values:
+
+.. code-block:: c
+
+	union v4l2_ctrl_ptr {
+		s32 *p_s32;
+		s64 *p_s64;
+		char *p_char;
+		void *p;
+	};
+
+The v4l2_ctrl struct contains these fields that can be used to access both
+current and new values:
+
+.. code-block:: c
+
+	s32 val;
+	struct {
+		s32 val;
+	} cur;
+
+
+	union v4l2_ctrl_ptr p_new;
+	union v4l2_ctrl_ptr p_cur;
+
+If the control has a simple s32 type type, then:
+
+.. code-block:: c
+
+	&ctrl->val == ctrl->p_new.p_s32
+	&ctrl->cur.val == ctrl->p_cur.p_s32
+
+For all other types use ctrl->p_cur.p<something>. Basically the val
+and cur.val fields can be considered an alias since these are used so often.
+
+Within the control ops you can freely use these. The val and cur.val speak for
+themselves. The p_char pointers point to character buffers of length
+ctrl->maximum + 1, and are always 0-terminated.
+
+Unless the control is marked volatile the p_cur field points to the the
+current cached control value. When you create a new control this value is made
+identical to the default value. After calling v4l2_ctrl_handler_setup() this
+value is passed to the hardware. It is generally a good idea to call this
+function.
+
+Whenever a new value is set that new value is automatically cached. This means
+that most drivers do not need to implement the g_volatile_ctrl() op. The
+exception is for controls that return a volatile register such as a signal
+strength read-out that changes continuously. In that case you will need to
+implement g_volatile_ctrl like this:
+
+.. code-block:: c
+
+	static int foo_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
+	{
+		switch (ctrl->id) {
+		case V4L2_CID_BRIGHTNESS:
+			ctrl->val = read_reg(0x123);
+			break;
+		}
+	}
+
+Note that you use the 'new value' union as well in g_volatile_ctrl. In general
+controls that need to implement g_volatile_ctrl are read-only controls. If they
+are not, a V4L2_EVENT_CTRL_CH_VALUE will not be generated when the control
+changes.
+
+To mark a control as volatile you have to set V4L2_CTRL_FLAG_VOLATILE:
+
+.. code-block:: c
+
+	ctrl = v4l2_ctrl_new_std(&sd->ctrl_handler, ...);
+	if (ctrl)
+		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+
+For try/s_ctrl the new values (i.e. as passed by the user) are filled in and
+you can modify them in try_ctrl or set them in s_ctrl. The 'cur' union
+contains the current value, which you can use (but not change!) as well.
+
+If s_ctrl returns 0 (OK), then the control framework will copy the new final
+values to the 'cur' union.
+
+While in g_volatile/s/try_ctrl you can access the value of all controls owned
+by the same handler since the handler's lock is held. If you need to access
+the value of controls owned by other handlers, then you have to be very careful
+not to introduce deadlocks.
+
+Outside of the control ops you have to go through to helper functions to get
+or set a single control value safely in your driver:
+
+.. code-block:: c
+
+	s32 v4l2_ctrl_g_ctrl(struct v4l2_ctrl *ctrl);
+	int v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val);
+
+These functions go through the control framework just as VIDIOC_G/S_CTRL ioctls
+do. Don't use these inside the control ops g_volatile/s/try_ctrl, though, that
+will result in a deadlock since these helpers lock the handler as well.
+
+You can also take the handler lock yourself:
+
+.. code-block:: c
+
+	mutex_lock(&state->ctrl_handler.lock);
+	pr_info("String value is '%s'\n", ctrl1->p_cur.p_char);
+	pr_info("Integer value is '%s'\n", ctrl2->cur.val);
+	mutex_unlock(&state->ctrl_handler.lock);
+
+
+Menu Controls
+-------------
+
+The v4l2_ctrl struct contains this union:
+
+.. code-block:: c
+
+	union {
+		u32 step;
+		u32 menu_skip_mask;
+	};
+
+For menu controls menu_skip_mask is used. What it does is that it allows you
+to easily exclude certain menu items. This is used in the VIDIOC_QUERYMENU
+implementation where you can return -EINVAL if a certain menu item is not
+present. Note that VIDIOC_QUERYCTRL always returns a step value of 1 for
+menu controls.
+
+A good example is the MPEG Audio Layer II Bitrate menu control where the
+menu is a list of standardized possible bitrates. But in practice hardware
+implementations will only support a subset of those. By setting the skip
+mask you can tell the framework which menu items should be skipped. Setting
+it to 0 means that all menu items are supported.
+
+You set this mask either through the v4l2_ctrl_config struct for a custom
+control, or by calling v4l2_ctrl_new_std_menu().
+
+
+Custom Controls
+---------------
+
+Driver specific controls can be created using v4l2_ctrl_new_custom():
+
+.. code-block:: c
+
+	static const struct v4l2_ctrl_config ctrl_filter = {
+		.ops = &ctrl_custom_ops,
+		.id = V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER,
+		.name = "Spatial Filter",
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.flags = V4L2_CTRL_FLAG_SLIDER,
+		.max = 15,
+		.step = 1,
+	};
+
+	ctrl = v4l2_ctrl_new_custom(&foo->ctrl_handler, &ctrl_filter, NULL);
+
+The last argument is the priv pointer which can be set to driver-specific
+private data.
+
+The v4l2_ctrl_config struct also has a field to set the is_private flag.
+
+If the name field is not set, then the framework will assume this is a standard
+control and will fill in the name, type and flags fields accordingly.
+
+
+Active and Grabbed Controls
+---------------------------
+
+If you get more complex relationships between controls, then you may have to
+activate and deactivate controls. For example, if the Chroma AGC control is
+on, then the Chroma Gain control is inactive. That is, you may set it, but
+the value will not be used by the hardware as long as the automatic gain
+control is on. Typically user interfaces can disable such input fields.
+
+You can set the 'active' status using v4l2_ctrl_activate(). By default all
+controls are active. Note that the framework does not check for this flag.
+It is meant purely for GUIs. The function is typically called from within
+s_ctrl.
+
+The other flag is the 'grabbed' flag. A grabbed control means that you cannot
+change it because it is in use by some resource. Typical examples are MPEG
+bitrate controls that cannot be changed while capturing is in progress.
+
+If a control is set to 'grabbed' using v4l2_ctrl_grab(), then the framework
+will return -EBUSY if an attempt is made to set this control. The
+v4l2_ctrl_grab() function is typically called from the driver when it
+starts or stops streaming.
+
+
+Control Clusters
+----------------
+
+By default all controls are independent from the others. But in more
+complex scenarios you can get dependencies from one control to another.
+In that case you need to 'cluster' them:
+
+.. code-block:: c
+
+	struct foo {
+		struct v4l2_ctrl_handler ctrl_handler;
+	#define AUDIO_CL_VOLUME (0)
+	#define AUDIO_CL_MUTE   (1)
+		struct v4l2_ctrl *audio_cluster[2];
+		...
+	};
+
+	state->audio_cluster[AUDIO_CL_VOLUME] =
+		v4l2_ctrl_new_std(&state->ctrl_handler, ...);
+	state->audio_cluster[AUDIO_CL_MUTE] =
+		v4l2_ctrl_new_std(&state->ctrl_handler, ...);
+	v4l2_ctrl_cluster(ARRAY_SIZE(state->audio_cluster), state->audio_cluster);
+
+From now on whenever one or more of the controls belonging to the same
+cluster is set (or 'gotten', or 'tried'), only the control ops of the first
+control ('volume' in this example) is called. You effectively create a new
+composite control. Similar to how a 'struct' works in C.
+
+So when s_ctrl is called with V4L2_CID_AUDIO_VOLUME as argument, you should set
+all two controls belonging to the audio_cluster:
+
+.. code-block:: c
+
+	static int foo_s_ctrl(struct v4l2_ctrl *ctrl)
+	{
+		struct foo *state = container_of(ctrl->handler, struct foo, ctrl_handler);
+
+		switch (ctrl->id) {
+		case V4L2_CID_AUDIO_VOLUME: {
+			struct v4l2_ctrl *mute = ctrl->cluster[AUDIO_CL_MUTE];
+
+			write_reg(0x123, mute->val ? 0 : ctrl->val);
+			break;
+		}
+		case V4L2_CID_CONTRAST:
+			write_reg(0x456, ctrl->val);
+			break;
+		}
+		return 0;
+	}
+
+In the example above the following are equivalent for the VOLUME case:
+
+.. code-block:: c
+
+	ctrl == ctrl->cluster[AUDIO_CL_VOLUME] == state->audio_cluster[AUDIO_CL_VOLUME]
+	ctrl->cluster[AUDIO_CL_MUTE] == state->audio_cluster[AUDIO_CL_MUTE]
+
+In practice using cluster arrays like this becomes very tiresome. So instead
+the following equivalent method is used:
+
+.. code-block:: c
+
+	struct {
+		/* audio cluster */
+		struct v4l2_ctrl *volume;
+		struct v4l2_ctrl *mute;
+	};
+
+The anonymous struct is used to clearly 'cluster' these two control pointers,
+but it serves no other purpose. The effect is the same as creating an
+array with two control pointers. So you can just do:
+
+.. code-block:: c
+
+	state->volume = v4l2_ctrl_new_std(&state->ctrl_handler, ...);
+	state->mute = v4l2_ctrl_new_std(&state->ctrl_handler, ...);
+	v4l2_ctrl_cluster(2, &state->volume);
+
+And in foo_s_ctrl you can use these pointers directly: state->mute->val.
+
+Note that controls in a cluster may be NULL. For example, if for some
+reason mute was never added (because the hardware doesn't support that
+particular feature), then mute will be NULL. So in that case we have a
+cluster of 2 controls, of which only 1 is actually instantiated. The
+only restriction is that the first control of the cluster must always be
+present, since that is the 'master' control of the cluster. The master
+control is the one that identifies the cluster and that provides the
+pointer to the v4l2_ctrl_ops struct that is used for that cluster.
+
+Obviously, all controls in the cluster array must be initialized to either
+a valid control or to NULL.
+
+In rare cases you might want to know which controls of a cluster actually
+were set explicitly by the user. For this you can check the 'is_new' flag of
+each control. For example, in the case of a volume/mute cluster the 'is_new'
+flag of the mute control would be set if the user called VIDIOC_S_CTRL for
+mute only. If the user would call VIDIOC_S_EXT_CTRLS for both mute and volume
+controls, then the 'is_new' flag would be 1 for both controls.
+
+The 'is_new' flag is always 1 when called from v4l2_ctrl_handler_setup().
+
+
+Handling autogain/gain-type Controls with Auto Clusters
+-------------------------------------------------------
+
+A common type of control cluster is one that handles 'auto-foo/foo'-type
+controls. Typical examples are autogain/gain, autoexposure/exposure,
+autowhitebalance/red balance/blue balance. In all cases you have one control
+that determines whether another control is handled automatically by the hardware,
+or whether it is under manual control from the user.
+
+If the cluster is in automatic mode, then the manual controls should be
+marked inactive and volatile. When the volatile controls are read the
+g_volatile_ctrl operation should return the value that the hardware's automatic
+mode set up automatically.
+
+If the cluster is put in manual mode, then the manual controls should become
+active again and the volatile flag is cleared (so g_volatile_ctrl is no longer
+called while in manual mode). In addition just before switching to manual mode
+the current values as determined by the auto mode are copied as the new manual
+values.
+
+Finally the V4L2_CTRL_FLAG_UPDATE should be set for the auto control since
+changing that control affects the control flags of the manual controls.
+
+In order to simplify this a special variation of v4l2_ctrl_cluster was
+introduced:
+
+.. code-block:: c
+
+	void v4l2_ctrl_auto_cluster(unsigned ncontrols, struct v4l2_ctrl **controls,
+				    u8 manual_val, bool set_volatile);
+
+The first two arguments are identical to v4l2_ctrl_cluster. The third argument
+tells the framework which value switches the cluster into manual mode. The
+last argument will optionally set V4L2_CTRL_FLAG_VOLATILE for the non-auto controls.
+If it is false, then the manual controls are never volatile. You would typically
+use that if the hardware does not give you the option to read back to values as
+determined by the auto mode (e.g. if autogain is on, the hardware doesn't allow
+you to obtain the current gain value).
+
+The first control of the cluster is assumed to be the 'auto' control.
+
+Using this function will ensure that you don't need to handle all the complex
+flag and volatile handling.
+
+
+VIDIOC_LOG_STATUS Support
+-------------------------
+
+This ioctl allow you to dump the current status of a driver to the kernel log.
+The v4l2_ctrl_handler_log_status(ctrl_handler, prefix) can be used to dump the
+value of the controls owned by the given handler to the log. You can supply a
+prefix as well. If the prefix didn't end with a space, then ': ' will be added
+for you.
+
+
+Different Handlers for Different Video Nodes
+--------------------------------------------
+
+Usually the V4L2 driver has just one control handler that is global for
+all video nodes. But you can also specify different control handlers for
+different video nodes. You can do that by manually setting the ctrl_handler
+field of struct video_device.
+
+That is no problem if there are no subdevs involved but if there are, then
+you need to block the automatic merging of subdev controls to the global
+control handler. You do that by simply setting the ctrl_handler field in
+struct v4l2_device to NULL. Now v4l2_device_register_subdev() will no longer
+merge subdev controls.
+
+After each subdev was added, you will then have to call v4l2_ctrl_add_handler
+manually to add the subdev's control handler (sd->ctrl_handler) to the desired
+control handler. This control handler may be specific to the video_device or
+for a subset of video_device's. For example: the radio device nodes only have
+audio controls, while the video and vbi device nodes share the same control
+handler for the audio and video controls.
+
+If you want to have one handler (e.g. for a radio device node) have a subset
+of another handler (e.g. for a video device node), then you should first add
+the controls to the first handler, add the other controls to the second
+handler and finally add the first handler to the second. For example:
+
+.. code-block:: c
+
+	v4l2_ctrl_new_std(&radio_ctrl_handler, &radio_ops, V4L2_CID_AUDIO_VOLUME, ...);
+	v4l2_ctrl_new_std(&radio_ctrl_handler, &radio_ops, V4L2_CID_AUDIO_MUTE, ...);
+	v4l2_ctrl_new_std(&video_ctrl_handler, &video_ops, V4L2_CID_BRIGHTNESS, ...);
+	v4l2_ctrl_new_std(&video_ctrl_handler, &video_ops, V4L2_CID_CONTRAST, ...);
+	v4l2_ctrl_add_handler(&video_ctrl_handler, &radio_ctrl_handler, NULL);
+
+The last argument to v4l2_ctrl_add_handler() is a filter function that allows
+you to filter which controls will be added. Set it to NULL if you want to add
+all controls.
+
+Or you can add specific controls to a handler:
+
+.. code-block:: c
+
+	volume = v4l2_ctrl_new_std(&video_ctrl_handler, &ops, V4L2_CID_AUDIO_VOLUME, ...);
+	v4l2_ctrl_new_std(&video_ctrl_handler, &ops, V4L2_CID_BRIGHTNESS, ...);
+	v4l2_ctrl_new_std(&video_ctrl_handler, &ops, V4L2_CID_CONTRAST, ...);
+
+What you should not do is make two identical controls for two handlers.
+For example:
+
+.. code-block:: c
+
+	v4l2_ctrl_new_std(&radio_ctrl_handler, &radio_ops, V4L2_CID_AUDIO_MUTE, ...);
+	v4l2_ctrl_new_std(&video_ctrl_handler, &video_ops, V4L2_CID_AUDIO_MUTE, ...);
+
+This would be bad since muting the radio would not change the video mute
+control. The rule is to have one control for each hardware 'knob' that you
+can twiddle.
+
+
+Finding Controls
+----------------
+
+Normally you have created the controls yourself and you can store the struct
+v4l2_ctrl pointer into your own struct.
+
+But sometimes you need to find a control from another handler that you do
+not own. For example, if you have to find a volume control from a subdev.
+
+You can do that by calling v4l2_ctrl_find:
+
+.. code-block:: c
+
+	struct v4l2_ctrl *volume;
+
+	volume = v4l2_ctrl_find(sd->ctrl_handler, V4L2_CID_AUDIO_VOLUME);
+
+Since v4l2_ctrl_find will lock the handler you have to be careful where you
+use it. For example, this is not a good idea:
+
+.. code-block:: c
+
+	struct v4l2_ctrl_handler ctrl_handler;
+
+	v4l2_ctrl_new_std(&ctrl_handler, &video_ops, V4L2_CID_BRIGHTNESS, ...);
+	v4l2_ctrl_new_std(&ctrl_handler, &video_ops, V4L2_CID_CONTRAST, ...);
+
+...and in video_ops.s_ctrl:
+
+.. code-block:: c
+
+	case V4L2_CID_BRIGHTNESS:
+		contrast = v4l2_find_ctrl(&ctrl_handler, V4L2_CID_CONTRAST);
+		...
+
+When s_ctrl is called by the framework the ctrl_handler.lock is already taken, so
+attempting to find another control from the same handler will deadlock.
+
+It is recommended not to use this function from inside the control ops.
+
+
+Preventing Controls inheritance
+-------------------------------
+
+When one control handler is added to another using v4l2_ctrl_add_handler, then
+by default all controls from one are merged to the other. But a subdev might
+have low-level controls that make sense for some advanced embedded system, but
+not when it is used in consumer-level hardware. In that case you want to keep
+those low-level controls local to the subdev. You can do this by simply
+setting the 'is_private' flag of the control to 1:
+
+.. code-block:: c
+
+	static const struct v4l2_ctrl_config ctrl_private = {
+		.ops = &ctrl_custom_ops,
+		.id = V4L2_CID_...,
+		.name = "Some Private Control",
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.max = 15,
+		.step = 1,
+		.is_private = 1,
+	};
+
+	ctrl = v4l2_ctrl_new_custom(&foo->ctrl_handler, &ctrl_private, NULL);
+
+These controls will now be skipped when v4l2_ctrl_add_handler is called.
+
+
+V4L2_CTRL_TYPE_CTRL_CLASS Controls
+----------------------------------
+
+Controls of this type can be used by GUIs to get the name of the control class.
+A fully featured GUI can make a dialog with multiple tabs with each tab
+containing the controls belonging to a particular control class. The name of
+each tab can be found by querying a special control with ID <control class | 1>.
+
+Drivers do not have to care about this. The framework will automatically add
+a control of this type whenever the first control belonging to a new control
+class is added.
+
+
+Adding Notify Callbacks
+-----------------------
+
+Sometimes the platform or bridge driver needs to be notified when a control
+from a sub-device driver changes. You can set a notify callback by calling
+this function:
+
+.. code-block:: c
+
+	void v4l2_ctrl_notify(struct v4l2_ctrl *ctrl,
+		void (*notify)(struct v4l2_ctrl *ctrl, void *priv), void *priv);
+
+Whenever the give control changes value the notify callback will be called
+with a pointer to the control and the priv pointer that was passed with
+v4l2_ctrl_notify. Note that the control's handler lock is held when the
+notify function is called.
+
+There can be only one notify function per control handler. Any attempt
+to set another notify function will cause a WARN_ON.
+
+v4l2_ctrl functions and data structures
+---------------------------------------
+
+.. kernel-doc:: include/media/v4l2-ctrls.h
diff --git a/Documentation/driver-api/media/v4l2-core.rst b/Documentation/driver-api/media/v4l2-core.rst
new file mode 100644
index 000000000000..0dcad7a23141
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-core.rst
@@ -0,0 +1,29 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Video4Linux devices
+-------------------
+
+.. toctree::
+    :maxdepth: 1
+
+    v4l2-intro
+    v4l2-dev
+    v4l2-device
+    v4l2-fh
+    v4l2-subdev
+    v4l2-event
+    v4l2-controls
+    v4l2-videobuf
+    v4l2-videobuf2
+    v4l2-clocks
+    v4l2-dv-timings
+    v4l2-flash-led-class
+    v4l2-mc
+    v4l2-mediabus
+    v4l2-mem2mem
+    v4l2-async
+    v4l2-fwnode
+    v4l2-rect
+    v4l2-tuner
+    v4l2-common
+    v4l2-tveeprom
diff --git a/Documentation/driver-api/media/v4l2-dev.rst b/Documentation/driver-api/media/v4l2-dev.rst
new file mode 100644
index 000000000000..63c064837c00
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-dev.rst
@@ -0,0 +1,375 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Video device' s internal representation
+=======================================
+
+The actual device nodes in the ``/dev`` directory are created using the
+:c:type:`video_device` struct (``v4l2-dev.h``). This struct can either be
+allocated dynamically or embedded in a larger struct.
+
+To allocate it dynamically use :c:func:`video_device_alloc`:
+
+.. code-block:: c
+
+	struct video_device *vdev = video_device_alloc();
+
+	if (vdev == NULL)
+		return -ENOMEM;
+
+	vdev->release = video_device_release;
+
+If you embed it in a larger struct, then you must set the ``release()``
+callback to your own function:
+
+.. code-block:: c
+
+	struct video_device *vdev = &my_vdev->vdev;
+
+	vdev->release = my_vdev_release;
+
+The ``release()`` callback must be set and it is called when the last user
+of the video device exits.
+
+The default :c:func:`video_device_release` callback currently
+just calls ``kfree`` to free the allocated memory.
+
+There is also a :c:func:`video_device_release_empty` function that does
+nothing (is empty) and should be used if the struct is embedded and there
+is nothing to do when it is released.
+
+You should also set these fields of :c:type:`video_device`:
+
+- :c:type:`video_device`->v4l2_dev: must be set to the :c:type:`v4l2_device`
+  parent device.
+
+- :c:type:`video_device`->name: set to something descriptive and unique.
+
+- :c:type:`video_device`->vfl_dir: set this to ``VFL_DIR_RX`` for capture
+  devices (``VFL_DIR_RX`` has value 0, so this is normally already the
+  default), set to ``VFL_DIR_TX`` for output devices and ``VFL_DIR_M2M`` for mem2mem (codec) devices.
+
+- :c:type:`video_device`->fops: set to the :c:type:`v4l2_file_operations`
+  struct.
+
+- :c:type:`video_device`->ioctl_ops: if you use the :c:type:`v4l2_ioctl_ops`
+  to simplify ioctl maintenance (highly recommended to use this and it might
+  become compulsory in the future!), then set this to your
+  :c:type:`v4l2_ioctl_ops` struct. The :c:type:`video_device`->vfl_type and
+  :c:type:`video_device`->vfl_dir fields are used to disable ops that do not
+  match the type/dir combination. E.g. VBI ops are disabled for non-VBI nodes,
+  and output ops  are disabled for a capture device. This makes it possible to
+  provide just one :c:type:`v4l2_ioctl_ops` struct for both vbi and
+  video nodes.
+
+- :c:type:`video_device`->lock: leave to ``NULL`` if you want to do all the
+  locking  in the driver. Otherwise you give it a pointer to a struct
+  ``mutex_lock`` and before the :c:type:`video_device`->unlocked_ioctl
+  file operation is called this lock will be taken by the core and released
+  afterwards. See the next section for more details.
+
+- :c:type:`video_device`->queue: a pointer to the struct :c:type:`vb2_queue`
+  associated with this device node.
+  If queue is not ``NULL``, and queue->lock is not ``NULL``, then queue->lock
+  is used for the queuing ioctls (``VIDIOC_REQBUFS``, ``CREATE_BUFS``,
+  ``QBUF``, ``DQBUF``,  ``QUERYBUF``, ``PREPARE_BUF``, ``STREAMON`` and
+  ``STREAMOFF``) instead of the lock above.
+  That way the :ref:`vb2 <vb2_framework>` queuing framework does not have
+  to wait for other ioctls.   This queue pointer is also used by the
+  :ref:`vb2 <vb2_framework>` helper functions to check for
+  queuing ownership (i.e. is the filehandle calling it allowed to do the
+  operation).
+
+- :c:type:`video_device`->prio: keeps track of the priorities. Used to
+  implement ``VIDIOC_G_PRIORITY`` and ``VIDIOC_S_PRIORITY``.
+  If left to ``NULL``, then it will use the struct :c:type:`v4l2_prio_state`
+  in :c:type:`v4l2_device`. If you want to have a separate priority state per
+  (group of) device node(s),   then you can point it to your own struct
+  :c:type:`v4l2_prio_state`.
+
+- :c:type:`video_device`->dev_parent: you only set this if v4l2_device was
+  registered with ``NULL`` as the parent ``device`` struct. This only happens
+  in cases where one hardware device has multiple PCI devices that all share
+  the same :c:type:`v4l2_device` core.
+
+  The cx88 driver is an example of this: one core :c:type:`v4l2_device` struct,
+  but   it is used by both a raw video PCI device (cx8800) and a MPEG PCI device
+  (cx8802). Since the :c:type:`v4l2_device` cannot be associated with two PCI
+  devices at the same time it is setup without a parent device. But when the
+  struct :c:type:`video_device` is initialized you **do** know which parent
+  PCI device to use and so you set ``dev_device`` to the correct PCI device.
+
+If you use :c:type:`v4l2_ioctl_ops`, then you should set
+:c:type:`video_device`->unlocked_ioctl to :c:func:`video_ioctl2` in your
+:c:type:`v4l2_file_operations` struct.
+
+In some cases you want to tell the core that a function you had specified in
+your :c:type:`v4l2_ioctl_ops` should be ignored. You can mark such ioctls by
+calling this function before :c:func:`video_register_device` is called:
+
+	:c:func:`v4l2_disable_ioctl <v4l2_disable_ioctl>`
+	(:c:type:`vdev <video_device>`, cmd).
+
+This tends to be needed if based on external factors (e.g. which card is
+being used) you want to turns off certain features in :c:type:`v4l2_ioctl_ops`
+without having to make a new struct.
+
+The :c:type:`v4l2_file_operations` struct is a subset of file_operations.
+The main difference is that the inode argument is omitted since it is never
+used.
+
+If integration with the media framework is needed, you must initialize the
+:c:type:`media_entity` struct embedded in the :c:type:`video_device` struct
+(entity field) by calling :c:func:`media_entity_pads_init`:
+
+.. code-block:: c
+
+	struct media_pad *pad = &my_vdev->pad;
+	int err;
+
+	err = media_entity_pads_init(&vdev->entity, 1, pad);
+
+The pads array must have been previously initialized. There is no need to
+manually set the struct media_entity type and name fields.
+
+A reference to the entity will be automatically acquired/released when the
+video device is opened/closed.
+
+ioctls and locking
+------------------
+
+The V4L core provides optional locking services. The main service is the
+lock field in struct :c:type:`video_device`, which is a pointer to a mutex.
+If you set this pointer, then that will be used by unlocked_ioctl to
+serialize all ioctls.
+
+If you are using the :ref:`videobuf2 framework <vb2_framework>`, then there
+is a second lock that you can set: :c:type:`video_device`->queue->lock. If
+set, then this lock will be used instead of :c:type:`video_device`->lock
+to serialize all queuing ioctls (see the previous section
+for the full list of those ioctls).
+
+The advantage of using a different lock for the queuing ioctls is that for some
+drivers (particularly USB drivers) certain commands such as setting controls
+can take a long time, so you want to use a separate lock for the buffer queuing
+ioctls. That way your ``VIDIOC_DQBUF`` doesn't stall because the driver is busy
+changing the e.g. exposure of the webcam.
+
+Of course, you can always do all the locking yourself by leaving both lock
+pointers at ``NULL``.
+
+If you use the old :ref:`videobuf framework <vb_framework>` then you must
+pass the :c:type:`video_device`->lock to the videobuf queue initialize
+function: if videobuf has to wait for a frame to arrive, then it will
+temporarily unlock the lock and relock it afterwards. If your driver also
+waits in the code, then you should do the same to allow other
+processes to access the device node while the first process is waiting for
+something.
+
+In the case of :ref:`videobuf2 <vb2_framework>` you will need to implement the
+``wait_prepare()`` and ``wait_finish()`` callbacks to unlock/lock if applicable.
+If you use the ``queue->lock`` pointer, then you can use the helper functions
+:c:func:`vb2_ops_wait_prepare` and :c:func:`vb2_ops_wait_finish`.
+
+The implementation of a hotplug disconnect should also take the lock from
+:c:type:`video_device` before calling v4l2_device_disconnect. If you are also
+using :c:type:`video_device`->queue->lock, then you have to first lock
+:c:type:`video_device`->queue->lock followed by :c:type:`video_device`->lock.
+That way you can be sure no ioctl is running when you call
+:c:func:`v4l2_device_disconnect`.
+
+Video device registration
+-------------------------
+
+Next you register the video device with :c:func:`video_register_device`.
+This will create the character device for you.
+
+.. code-block:: c
+
+	err = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
+	if (err) {
+		video_device_release(vdev); /* or kfree(my_vdev); */
+		return err;
+	}
+
+If the :c:type:`v4l2_device` parent device has a not ``NULL`` mdev field,
+the video device entity will be automatically registered with the media
+device.
+
+Which device is registered depends on the type argument. The following
+types exist:
+
+========================== ====================	 ==============================
+:c:type:`vfl_devnode_type` Device name		 Usage
+========================== ====================	 ==============================
+``VFL_TYPE_VIDEO``         ``/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
+to let the v4l2 framework pick the first free number. But sometimes users
+want to select a specific node number. It is common that drivers allow
+the user to select a specific device node number through a driver module
+option. That number is then passed to this function and video_register_device
+will attempt to select that device node number. If that number was already
+in use, then the next free device node number will be selected and it
+will send a warning to the kernel log.
+
+Another use-case is if a driver creates many devices. In that case it can
+be useful to place different video devices in separate ranges. For example,
+video capture devices start at 0, video output devices start at 16.
+So you can use the last argument to specify a minimum device node number
+and the v4l2 framework will try to pick the first free number that is equal
+or higher to what you passed. If that fails, then it will just pick the
+first free number.
+
+Since in this case you do not care about a warning about not being able
+to select the specified device node number, you can call the function
+:c:func:`video_register_device_no_warn` instead.
+
+Whenever a device node is created some attributes are also created for you.
+If you look in ``/sys/class/video4linux`` you see the devices. Go into e.g.
+``video0`` and you will see 'name', 'dev_debug' and 'index' attributes. The
+'name' attribute is the 'name' field of the video_device struct. The
+'dev_debug' attribute can be used to enable core debugging. See the next
+section for more detailed information on this.
+
+The 'index' attribute is the index of the device node: for each call to
+:c:func:`video_register_device()` the index is just increased by 1. The
+first video device node you register always starts with index 0.
+
+Users can setup udev rules that utilize the index attribute to make fancy
+device names (e.g. '``mpegX``' for MPEG video capture device nodes).
+
+After the device was successfully registered, then you can use these fields:
+
+- :c:type:`video_device`->vfl_type: the device type passed to
+  :c:func:`video_register_device`.
+- :c:type:`video_device`->minor: the assigned device minor number.
+- :c:type:`video_device`->num: the device node number (i.e. the X in
+  ``videoX``).
+- :c:type:`video_device`->index: the device index number.
+
+If the registration failed, then you need to call
+:c:func:`video_device_release` to free the allocated :c:type:`video_device`
+struct, or free your own struct if the :c:type:`video_device` was embedded in
+it. The ``vdev->release()`` callback will never be called if the registration
+failed, nor should you ever attempt to unregister the device if the
+registration failed.
+
+video device debugging
+----------------------
+
+The 'dev_debug' attribute that is created for each video, vbi, radio or swradio
+device in ``/sys/class/video4linux/<devX>/`` allows you to enable logging of
+file operations.
+
+It is a bitmask and the following bits can be set:
+
+.. tabularcolumns:: |p{5ex}|L|
+
+===== ================================================================
+Mask  Description
+===== ================================================================
+0x01  Log the ioctl name and error code. VIDIOC_(D)QBUF ioctls are
+      only logged if bit 0x08 is also set.
+0x02  Log the ioctl name arguments and error code. VIDIOC_(D)QBUF
+      ioctls are
+      only logged if bit 0x08 is also set.
+0x04  Log the file operations open, release, read, write, mmap and
+      get_unmapped_area. The read and write operations are only
+      logged if bit 0x08 is also set.
+0x08  Log the read and write file operations and the VIDIOC_QBUF and
+      VIDIOC_DQBUF ioctls.
+0x10  Log the poll file operation.
+0x20  Log error and messages in the control operations.
+===== ================================================================
+
+Video device cleanup
+--------------------
+
+When the video device nodes have to be removed, either during the unload
+of the driver or because the USB device was disconnected, then you should
+unregister them with:
+
+	:c:func:`video_unregister_device`
+	(:c:type:`vdev <video_device>`);
+
+This will remove the device nodes from sysfs (causing udev to remove them
+from ``/dev``).
+
+After :c:func:`video_unregister_device` returns no new opens can be done.
+However, in the case of USB devices some application might still have one of
+these device nodes open. So after the unregister all file operations (except
+release, of course) will return an error as well.
+
+When the last user of the video device node exits, then the ``vdev->release()``
+callback is called and you can do the final cleanup there.
+
+Don't forget to cleanup the media entity associated with the video device if
+it has been initialized:
+
+	:c:func:`media_entity_cleanup <media_entity_cleanup>`
+	(&vdev->entity);
+
+This can be done from the release callback.
+
+
+helper functions
+----------------
+
+There are a few useful helper functions:
+
+- file and :c:type:`video_device` private data
+
+You can set/get driver private data in the video_device struct using:
+
+	:c:func:`video_get_drvdata <video_get_drvdata>`
+	(:c:type:`vdev <video_device>`);
+
+	:c:func:`video_set_drvdata <video_set_drvdata>`
+	(:c:type:`vdev <video_device>`);
+
+Note that you can safely call :c:func:`video_set_drvdata` before calling
+:c:func:`video_register_device`.
+
+And this function:
+
+	:c:func:`video_devdata <video_devdata>`
+	(struct file \*file);
+
+returns the video_device belonging to the file struct.
+
+The :c:func:`video_devdata` function combines :c:func:`video_get_drvdata`
+with :c:func:`video_devdata`:
+
+	:c:func:`video_drvdata <video_drvdata>`
+	(struct file \*file);
+
+You can go from a :c:type:`video_device` struct to the v4l2_device struct using:
+
+.. code-block:: c
+
+	struct v4l2_device *v4l2_dev = vdev->v4l2_dev;
+
+- Device node name
+
+The :c:type:`video_device` node kernel name can be retrieved using:
+
+	:c:func:`video_device_node_name <video_device_node_name>`
+	(:c:type:`vdev <video_device>`);
+
+The name is used as a hint by userspace tools such as udev. The function
+should be used where possible instead of accessing the video_device::num and
+video_device::minor fields.
+
+video_device functions and data structures
+------------------------------------------
+
+.. kernel-doc:: include/media/v4l2-dev.h
diff --git a/Documentation/driver-api/media/v4l2-device.rst b/Documentation/driver-api/media/v4l2-device.rst
new file mode 100644
index 000000000000..5e25bf182c18
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-device.rst
@@ -0,0 +1,146 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+V4L2 device instance
+--------------------
+
+Each device instance is represented by a struct :c:type:`v4l2_device`.
+Very simple devices can just allocate this struct, but most of the time you
+would embed this struct inside a larger struct.
+
+You must register the device instance by calling:
+
+	:c:func:`v4l2_device_register <v4l2_device_register>`
+	(dev, :c:type:`v4l2_dev <v4l2_device>`).
+
+Registration will initialize the :c:type:`v4l2_device` struct. If the
+dev->driver_data field is ``NULL``, it will be linked to
+:c:type:`v4l2_dev <v4l2_device>` argument.
+
+Drivers that want integration with the media device framework need to set
+dev->driver_data manually to point to the driver-specific device structure
+that embed the struct :c:type:`v4l2_device` instance. This is achieved by a
+``dev_set_drvdata()`` call before registering the V4L2 device instance.
+They must also set the struct :c:type:`v4l2_device` mdev field to point to a
+properly initialized and registered :c:type:`media_device` instance.
+
+If :c:type:`v4l2_dev <v4l2_device>`\ ->name is empty then it will be set to a
+value derived from dev (driver name followed by the bus_id, to be precise).
+If you set it up before  calling :c:func:`v4l2_device_register` then it will
+be untouched. If dev is ``NULL``, then you **must** setup
+:c:type:`v4l2_dev <v4l2_device>`\ ->name before calling
+:c:func:`v4l2_device_register`.
+
+You can use :c:func:`v4l2_device_set_name` to set the name based on a driver
+name and a driver-global atomic_t instance. This will generate names like
+``ivtv0``, ``ivtv1``, etc. If the name ends with a digit, then it will insert
+a dash: ``cx18-0``, ``cx18-1``, etc. This function returns the instance number.
+
+The first ``dev`` argument is normally the ``struct device`` pointer of a
+``pci_dev``, ``usb_interface`` or ``platform_device``. It is rare for dev to
+be ``NULL``, but it happens with ISA devices or when one device creates
+multiple PCI devices, thus making it impossible to associate
+:c:type:`v4l2_dev <v4l2_device>` with a particular parent.
+
+You can also supply a ``notify()`` callback that can be called by sub-devices
+to notify you of events. Whether you need to set this depends on the
+sub-device. Any notifications a sub-device supports must be defined in a header
+in ``include/media/subdevice.h``.
+
+V4L2 devices are unregistered by calling:
+
+	:c:func:`v4l2_device_unregister`
+	(:c:type:`v4l2_dev <v4l2_device>`).
+
+If the dev->driver_data field points to :c:type:`v4l2_dev <v4l2_device>`,
+it will be reset to ``NULL``. Unregistering will also automatically unregister
+all subdevs from the device.
+
+If you have a hotpluggable device (e.g. a USB device), then when a disconnect
+happens the parent device becomes invalid. Since :c:type:`v4l2_device` has a
+pointer to that parent device it has to be cleared as well to mark that the
+parent is gone. To do this call:
+
+	:c:func:`v4l2_device_disconnect`
+	(:c:type:`v4l2_dev <v4l2_device>`).
+
+This does *not* unregister the subdevs, so you still need to call the
+:c:func:`v4l2_device_unregister` function for that. If your driver is not
+hotpluggable, then there is no need to call :c:func:`v4l2_device_disconnect`.
+
+Sometimes you need to iterate over all devices registered by a specific
+driver. This is usually the case if multiple device drivers use the same
+hardware. E.g. the ivtvfb driver is a framebuffer driver that uses the ivtv
+hardware. The same is true for alsa drivers for example.
+
+You can iterate over all registered devices as follows:
+
+.. code-block:: c
+
+	static int callback(struct device *dev, void *p)
+	{
+		struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
+
+		/* test if this device was inited */
+		if (v4l2_dev == NULL)
+			return 0;
+		...
+		return 0;
+	}
+
+	int iterate(void *p)
+	{
+		struct device_driver *drv;
+		int err;
+
+		/* Find driver 'ivtv' on the PCI bus.
+		pci_bus_type is a global. For USB buses use usb_bus_type. */
+		drv = driver_find("ivtv", &pci_bus_type);
+		/* iterate over all ivtv device instances */
+		err = driver_for_each_device(drv, NULL, p, callback);
+		put_driver(drv);
+		return err;
+	}
+
+Sometimes you need to keep a running counter of the device instance. This is
+commonly used to map a device instance to an index of a module option array.
+
+The recommended approach is as follows:
+
+.. code-block:: c
+
+	static atomic_t drv_instance = ATOMIC_INIT(0);
+
+	static int drv_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
+	{
+		...
+		state->instance = atomic_inc_return(&drv_instance) - 1;
+	}
+
+If you have multiple device nodes then it can be difficult to know when it is
+safe to unregister :c:type:`v4l2_device` for hotpluggable devices. For this
+purpose :c:type:`v4l2_device` has refcounting support. The refcount is
+increased whenever :c:func:`video_register_device` is called and it is
+decreased whenever that device node is released. When the refcount reaches
+zero, then the :c:type:`v4l2_device` release() callback is called. You can
+do your final cleanup there.
+
+If other device nodes (e.g. ALSA) are created, then you can increase and
+decrease the refcount manually as well by calling:
+
+	:c:func:`v4l2_device_get`
+	(:c:type:`v4l2_dev <v4l2_device>`).
+
+or:
+
+	:c:func:`v4l2_device_put`
+	(:c:type:`v4l2_dev <v4l2_device>`).
+
+Since the initial refcount is 1 you also need to call
+:c:func:`v4l2_device_put` in the ``disconnect()`` callback (for USB devices)
+or in the ``remove()`` callback (for e.g. PCI devices), otherwise the refcount
+will never reach 0.
+
+v4l2_device functions and data structures
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. kernel-doc:: include/media/v4l2-device.h
diff --git a/Documentation/driver-api/media/v4l2-dv-timings.rst b/Documentation/driver-api/media/v4l2-dv-timings.rst
new file mode 100644
index 000000000000..b178f931518b
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-dv-timings.rst
@@ -0,0 +1,6 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+V4L2 DV Timings functions
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. kernel-doc:: include/media/v4l2-dv-timings.h
diff --git a/Documentation/driver-api/media/v4l2-event.rst b/Documentation/driver-api/media/v4l2-event.rst
new file mode 100644
index 000000000000..a4b7ae2b94d8
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-event.rst
@@ -0,0 +1,181 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+V4L2 events
+-----------
+
+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 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.
+
+The :c:type:`v4l2_fh` struct has a list of subscribed events on its
+``subscribed`` field.
+
+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
+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.
+
+A good example of these ``replace``/``merge`` callbacks is in v4l2-event.c:
+``ctrls_replace()`` and ``ctrls_merge()`` callbacks for the control event.
+
+.. note::
+	these callbacks can be called from interrupt context, so they must
+	be fast.
+
+In order to queue events to video device, drivers should call:
+
+	:c:func:`v4l2_event_queue <v4l2_event_queue>`
+	(:c:type:`vdev <video_device>`, :c:type:`ev <v4l2_event>`)
+
+The driver's only responsibility is to fill in the type and the data fields.
+The other fields will be filled in by V4L2.
+
+Event subscription
+~~~~~~~~~~~~~~~~~~
+
+Subscribing to an event is via:
+
+	:c:func:`v4l2_event_subscribe <v4l2_event_subscribe>`
+	(:c:type:`fh <v4l2_fh>`, :c:type:`sub <v4l2_event_subscription>` ,
+	elems, :c:type:`ops <v4l2_subscribed_event_ops>`)
+
+
+This function is used to implement :c:type:`video_device`->
+:c:type:`ioctl_ops <v4l2_ioctl_ops>`-> ``vidioc_subscribe_event``,
+but the driver must check first if the driver is able to produce events
+with specified event id, and then should call
+:c:func:`v4l2_event_subscribe` to subscribe the event.
+
+The elems argument is the size of the event queue for this event. If it is 0,
+then the framework will fill in a default value (this depends on the event
+type).
+
+The ops argument allows the driver to specify a number of callbacks:
+
+.. tabularcolumns:: |p{1.5cm}|p{16.0cm}|
+
+======== ==============================================================
+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)
+del      called when a listener stops listening
+replace  replace event 'old' with event 'new'.
+merge    merge event 'old' into event 'new'.
+======== ==============================================================
+
+All 4 callbacks are optional, if you don't want to specify any callbacks
+the ops argument itself maybe ``NULL``.
+
+Unsubscribing an event
+~~~~~~~~~~~~~~~~~~~~~~
+
+Unsubscribing to an event is via:
+
+	:c:func:`v4l2_event_unsubscribe <v4l2_event_unsubscribe>`
+	(:c:type:`fh <v4l2_fh>`, :c:type:`sub <v4l2_event_subscription>`)
+
+This function is used to implement :c:type:`video_device`->
+:c:type:`ioctl_ops <v4l2_ioctl_ops>`-> ``vidioc_unsubscribe_event``.
+A driver may call :c:func:`v4l2_event_unsubscribe` directly unless it
+wants to be involved in unsubscription process.
+
+The special type ``V4L2_EVENT_ALL`` may be used to unsubscribe all events. The
+drivers may want to handle this in a special way.
+
+Check if there's a pending event
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Checking if there's a pending event is via:
+
+	:c:func:`v4l2_event_pending <v4l2_event_pending>`
+	(:c:type:`fh <v4l2_fh>`)
+
+
+This function returns the number of pending events. Useful when implementing
+poll.
+
+How events work
+~~~~~~~~~~~~~~~
+
+Events are delivered to user space through the poll system call. The driver
+can use :c:type:`v4l2_fh`->wait (a wait_queue_head_t) as the argument for
+``poll_wait()``.
+
+There are standard and private events. New standard events must use the
+smallest available event type. The drivers must allocate their events from
+their own class starting from class base. Class base is
+``V4L2_EVENT_PRIVATE_START`` + n * 1000 where n is the lowest available number.
+The first event type in the class is reserved for future use, so the first
+available event type is 'class base + 1'.
+
+An example on how the V4L2 events may be used can be found in the OMAP
+3 ISP driver (``drivers/media/platform/omap3isp``).
+
+A subdev can directly send an event to the :c:type:`v4l2_device` notify
+function with ``V4L2_DEVICE_NOTIFY_EVENT``. This allows the bridge to map
+the subdev that sends the event to the video node(s) associated with the
+subdev that need to be informed about such an event.
+
+V4L2 event functions and data structures
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. kernel-doc:: include/media/v4l2-event.h
+
diff --git a/Documentation/driver-api/media/v4l2-fh.rst b/Documentation/driver-api/media/v4l2-fh.rst
new file mode 100644
index 000000000000..4c62b19af744
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-fh.rst
@@ -0,0 +1,141 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+V4L2 File handlers
+------------------
+
+struct :c:type:`v4l2_fh` provides a way to easily keep file handle specific
+data that is used by the V4L2 framework.
+
+.. attention::
+	New drivers must use struct :c:type:`v4l2_fh`
+	since it is also used to implement priority handling
+	(:ref:`VIDIOC_G_PRIORITY`).
+
+The users of :c:type:`v4l2_fh` (in the V4L2 framework, not the driver) know
+whether a driver uses :c:type:`v4l2_fh` as its ``file->private_data`` pointer
+by testing the ``V4L2_FL_USES_V4L2_FH`` bit in :c:type:`video_device`->flags.
+This bit is set whenever :c:func:`v4l2_fh_init` is called.
+
+struct :c:type:`v4l2_fh` is allocated as a part of the driver's own file handle
+structure and ``file->private_data`` is set to it in the driver's ``open()``
+function by the driver.
+
+In many cases the struct :c:type:`v4l2_fh` will be embedded in a larger
+structure. In that case you should call:
+
+#) :c:func:`v4l2_fh_init` and :c:func:`v4l2_fh_add` in ``open()``
+#) :c:func:`v4l2_fh_del` and :c:func:`v4l2_fh_exit` in ``release()``
+
+Drivers can extract their own file handle structure by using the container_of
+macro.
+
+Example:
+
+.. code-block:: c
+
+	struct my_fh {
+		int blah;
+		struct v4l2_fh fh;
+	};
+
+	...
+
+	int my_open(struct file *file)
+	{
+		struct my_fh *my_fh;
+		struct video_device *vfd;
+		int ret;
+
+		...
+
+		my_fh = kzalloc(sizeof(*my_fh), GFP_KERNEL);
+
+		...
+
+		v4l2_fh_init(&my_fh->fh, vfd);
+
+		...
+
+		file->private_data = &my_fh->fh;
+		v4l2_fh_add(&my_fh->fh);
+		return 0;
+	}
+
+	int my_release(struct file *file)
+	{
+		struct v4l2_fh *fh = file->private_data;
+		struct my_fh *my_fh = container_of(fh, struct my_fh, fh);
+
+		...
+		v4l2_fh_del(&my_fh->fh);
+		v4l2_fh_exit(&my_fh->fh);
+		kfree(my_fh);
+		return 0;
+	}
+
+Below is a short description of the :c:type:`v4l2_fh` functions used:
+
+:c:func:`v4l2_fh_init <v4l2_fh_init>`
+(:c:type:`fh <v4l2_fh>`, :c:type:`vdev <video_device>`)
+
+
+- Initialise the file handle. This **MUST** be performed in the driver's
+  :c:type:`v4l2_file_operations`->open() handler.
+
+
+:c:func:`v4l2_fh_add <v4l2_fh_add>`
+(:c:type:`fh <v4l2_fh>`)
+
+- Add a :c:type:`v4l2_fh` to :c:type:`video_device` file handle list.
+  Must be called once the file handle is completely initialized.
+
+:c:func:`v4l2_fh_del <v4l2_fh_del>`
+(:c:type:`fh <v4l2_fh>`)
+
+- Unassociate the file handle from :c:type:`video_device`. The file handle
+  exit function may now be called.
+
+:c:func:`v4l2_fh_exit <v4l2_fh_exit>`
+(:c:type:`fh <v4l2_fh>`)
+
+- Uninitialise the file handle. After uninitialisation the :c:type:`v4l2_fh`
+  memory can be freed.
+
+
+If struct :c:type:`v4l2_fh` is not embedded, then you can use these helper functions:
+
+:c:func:`v4l2_fh_open <v4l2_fh_open>`
+(struct file \*filp)
+
+- This allocates a struct :c:type:`v4l2_fh`, initializes it and adds it to
+  the struct :c:type:`video_device` associated with the file struct.
+
+:c:func:`v4l2_fh_release <v4l2_fh_release>`
+(struct file \*filp)
+
+- This deletes it from the struct :c:type:`video_device` associated with the
+  file struct, uninitialised the :c:type:`v4l2_fh` and frees it.
+
+These two functions can be plugged into the v4l2_file_operation's ``open()``
+and ``release()`` ops.
+
+Several drivers need to do something when the first file handle is opened and
+when the last file handle closes. Two helper functions were added to check
+whether the :c:type:`v4l2_fh` struct is the only open filehandle of the
+associated device node:
+
+:c:func:`v4l2_fh_is_singular <v4l2_fh_is_singular>`
+(:c:type:`fh <v4l2_fh>`)
+
+-  Returns 1 if the file handle is the only open file handle, else 0.
+
+:c:func:`v4l2_fh_is_singular_file <v4l2_fh_is_singular_file>`
+(struct file \*filp)
+
+- Same, but it calls v4l2_fh_is_singular with filp->private_data.
+
+
+V4L2 fh functions and data structures
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. kernel-doc:: include/media/v4l2-fh.h
diff --git a/Documentation/driver-api/media/v4l2-flash-led-class.rst b/Documentation/driver-api/media/v4l2-flash-led-class.rst
new file mode 100644
index 000000000000..2aa6bed9b8db
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-flash-led-class.rst
@@ -0,0 +1,6 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+V4L2 flash functions and data structures
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. kernel-doc:: include/media/v4l2-flash-led-class.h
diff --git a/Documentation/driver-api/media/v4l2-fwnode.rst b/Documentation/driver-api/media/v4l2-fwnode.rst
new file mode 100644
index 000000000000..e313b6cddcd0
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-fwnode.rst
@@ -0,0 +1,5 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+V4L2 fwnode kAPI
+^^^^^^^^^^^^^^^^
+.. kernel-doc:: include/media/v4l2-fwnode.h
diff --git a/Documentation/driver-api/media/v4l2-intro.rst b/Documentation/driver-api/media/v4l2-intro.rst
new file mode 100644
index 000000000000..4d54fa9d7a12
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-intro.rst
@@ -0,0 +1,76 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Introduction
+------------
+
+The V4L2 drivers tend to be very complex due to the complexity of the
+hardware: most devices have multiple ICs, export multiple device nodes in
+/dev, and create also non-V4L2 devices such as DVB, ALSA, FB, I2C and input
+(IR) devices.
+
+Especially the fact that V4L2 drivers have to setup supporting ICs to
+do audio/video muxing/encoding/decoding makes it more complex than most.
+Usually these ICs are connected to the main bridge driver through one or
+more I2C buses, but other buses can also be used. Such devices are
+called 'sub-devices'.
+
+For a long time the framework was limited to the video_device struct for
+creating V4L device nodes and video_buf for handling the video buffers
+(note that this document does not discuss the video_buf framework).
+
+This meant that all drivers had to do the setup of device instances and
+connecting to sub-devices themselves. Some of this is quite complicated
+to do right and many drivers never did do it correctly.
+
+There is also a lot of common code that could never be refactored due to
+the lack of a framework.
+
+So this framework sets up the basic building blocks that all drivers
+need and this same framework should make it much easier to refactor
+common code into utility functions shared by all drivers.
+
+A good example to look at as a reference is the v4l2-pci-skeleton.c
+source that is available in samples/v4l/. It is a skeleton driver for
+a PCI capture card, and demonstrates how to use the V4L2 driver
+framework. It can be used as a template for real PCI video capture driver.
+
+Structure of a V4L driver
+-------------------------
+
+All drivers have the following structure:
+
+1) A struct for each device instance containing the device state.
+
+2) A way of initializing and commanding sub-devices (if any).
+
+3) Creating V4L2 device nodes (/dev/videoX, /dev/vbiX and /dev/radioX)
+   and keeping track of device-node specific data.
+
+4) Filehandle-specific structs containing per-filehandle data;
+
+5) video buffer handling.
+
+This is a rough schematic of how it all relates:
+
+.. code-block:: none
+
+    device instances
+      |
+      +-sub-device instances
+      |
+      \-V4L2 device nodes
+	  |
+	  \-filehandle instances
+
+
+Structure of the V4L2 framework
+-------------------------------
+
+The framework closely resembles the driver structure: it has a v4l2_device
+struct for the device instance data, a v4l2_subdev struct to refer to
+sub-device instances, the video_device struct stores V4L2 device node data
+and the v4l2_fh struct keeps track of filehandle instances.
+
+The V4L2 framework also optionally integrates with the media framework. If a
+driver sets the struct v4l2_device mdev field, sub-devices and video nodes
+will automatically appear in the media framework as entities.
diff --git a/Documentation/driver-api/media/v4l2-mc.rst b/Documentation/driver-api/media/v4l2-mc.rst
new file mode 100644
index 000000000000..0c352ac588b2
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-mc.rst
@@ -0,0 +1,6 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+V4L2 Media Controller functions and data structures
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. kernel-doc:: include/media/v4l2-mc.h
diff --git a/Documentation/driver-api/media/v4l2-mediabus.rst b/Documentation/driver-api/media/v4l2-mediabus.rst
new file mode 100644
index 000000000000..1f2254cba92d
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-mediabus.rst
@@ -0,0 +1,6 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+V4L2 Media Bus functions and data structures
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. kernel-doc:: include/media/v4l2-mediabus.h
diff --git a/Documentation/driver-api/media/v4l2-mem2mem.rst b/Documentation/driver-api/media/v4l2-mem2mem.rst
new file mode 100644
index 000000000000..a43b31cc8261
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-mem2mem.rst
@@ -0,0 +1,6 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+V4L2 Memory to Memory functions and data structures
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. kernel-doc:: include/media/v4l2-mem2mem.h
diff --git a/Documentation/driver-api/media/v4l2-rect.rst b/Documentation/driver-api/media/v4l2-rect.rst
new file mode 100644
index 000000000000..fc315cd84156
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-rect.rst
@@ -0,0 +1,6 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+V4L2 rect helper functions
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. kernel-doc:: include/media/v4l2-rect.h
diff --git a/Documentation/driver-api/media/v4l2-subdev.rst b/Documentation/driver-api/media/v4l2-subdev.rst
new file mode 100644
index 000000000000..29e07e23f888
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-subdev.rst
@@ -0,0 +1,444 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+V4L2 sub-devices
+----------------
+
+Many drivers need to communicate with sub-devices. These devices can do all
+sort of tasks, but most commonly they handle audio and/or video muxing,
+encoding or decoding. For webcams common sub-devices are sensors and camera
+controllers.
+
+Usually these are I2C devices, but not necessarily. In order to provide the
+driver with a consistent interface to these sub-devices the
+:c:type:`v4l2_subdev` struct (v4l2-subdev.h) was created.
+
+Each sub-device driver must have a :c:type:`v4l2_subdev` struct. This struct
+can be stand-alone for simple sub-devices or it might be embedded in a larger
+struct if more state information needs to be stored. Usually there is a
+low-level device struct (e.g. ``i2c_client``) that contains the device data as
+setup by the kernel. It is recommended to store that pointer in the private
+data of :c:type:`v4l2_subdev` using :c:func:`v4l2_set_subdevdata`. That makes
+it easy to go from a :c:type:`v4l2_subdev` to the actual low-level bus-specific
+device data.
+
+You also need a way to go from the low-level struct to :c:type:`v4l2_subdev`.
+For the common i2c_client struct the i2c_set_clientdata() call is used to store
+a :c:type:`v4l2_subdev` pointer, for other buses you may have to use other
+methods.
+
+Bridges might also need to store per-subdev private data, such as a pointer to
+bridge-specific per-subdev private data. The :c:type:`v4l2_subdev` structure
+provides host private data for that purpose that can be accessed with
+:c:func:`v4l2_get_subdev_hostdata` and :c:func:`v4l2_set_subdev_hostdata`.
+
+From the bridge driver perspective, you load the sub-device module and somehow
+obtain the :c:type:`v4l2_subdev` pointer. For i2c devices this is easy: you call
+``i2c_get_clientdata()``. For other buses something similar needs to be done.
+Helper functions exists for sub-devices on an I2C bus that do most of this
+tricky work for you.
+
+Each :c:type:`v4l2_subdev` contains function pointers that sub-device drivers
+can implement (or leave ``NULL`` if it is not applicable). Since sub-devices can
+do so many different things and you do not want to end up with a huge ops struct
+of which only a handful of ops are commonly implemented, the function pointers
+are sorted according to category and each category has its own ops struct.
+
+The top-level ops struct contains pointers to the category ops structs, which
+may be NULL if the subdev driver does not support anything from that category.
+
+It looks like this:
+
+.. code-block:: c
+
+	struct v4l2_subdev_core_ops {
+		int (*log_status)(struct v4l2_subdev *sd);
+		int (*init)(struct v4l2_subdev *sd, u32 val);
+		...
+	};
+
+	struct v4l2_subdev_tuner_ops {
+		...
+	};
+
+	struct v4l2_subdev_audio_ops {
+		...
+	};
+
+	struct v4l2_subdev_video_ops {
+		...
+	};
+
+	struct v4l2_subdev_pad_ops {
+		...
+	};
+
+	struct v4l2_subdev_ops {
+		const struct v4l2_subdev_core_ops  *core;
+		const struct v4l2_subdev_tuner_ops *tuner;
+		const struct v4l2_subdev_audio_ops *audio;
+		const struct v4l2_subdev_video_ops *video;
+		const struct v4l2_subdev_pad_ops *video;
+	};
+
+The core ops are common to all subdevs, the other categories are implemented
+depending on the sub-device. E.g. a video device is unlikely to support the
+audio ops and vice versa.
+
+This setup limits the number of function pointers while still making it easy
+to add new ops and categories.
+
+A sub-device driver initializes the :c:type:`v4l2_subdev` struct using:
+
+	:c:func:`v4l2_subdev_init <v4l2_subdev_init>`
+	(:c:type:`sd <v4l2_subdev>`, &\ :c:type:`ops <v4l2_subdev_ops>`).
+
+
+Afterwards you need to initialize :c:type:`sd <v4l2_subdev>`->name with a
+unique name and set the module owner. This is done for you if you use the
+i2c helper functions.
+
+If integration with the media framework is needed, you must initialize the
+:c:type:`media_entity` struct embedded in the :c:type:`v4l2_subdev` struct
+(entity field) by calling :c:func:`media_entity_pads_init`, if the entity has
+pads:
+
+.. code-block:: c
+
+	struct media_pad *pads = &my_sd->pads;
+	int err;
+
+	err = media_entity_pads_init(&sd->entity, npads, pads);
+
+The pads array must have been previously initialized. There is no need to
+manually set the struct :c:type:`media_entity` function and name fields, but the
+revision field must be initialized if needed.
+
+A reference to the entity will be automatically acquired/released when the
+subdev device node (if any) is opened/closed.
+
+Don't forget to cleanup the media entity before the sub-device is destroyed:
+
+.. code-block:: c
+
+	media_entity_cleanup(&sd->entity);
+
+If the subdev driver intends to process video and integrate with the media
+framework, it must implement format related functionality using
+:c:type:`v4l2_subdev_pad_ops` instead of :c:type:`v4l2_subdev_video_ops`.
+
+In that case, the subdev driver may set the link_validate field to provide
+its own link validation function. The link validation function is called for
+every link in the pipeline where both of the ends of the links are V4L2
+sub-devices. The driver is still responsible for validating the correctness
+of the format configuration between sub-devices and video nodes.
+
+If link_validate op is not set, the default function
+:c:func:`v4l2_subdev_link_validate_default` is used instead. This function
+ensures that width, height and the media bus pixel code are equal on both source
+and sink of the link. Subdev drivers are also free to use this function to
+perform the checks mentioned above in addition to their own checks.
+
+There are currently two ways to register subdevices with the V4L2 core. The
+first (traditional) possibility is to have subdevices registered by bridge
+drivers. This can be done when the bridge driver has the complete information
+about subdevices connected to it and knows exactly when to register them. This
+is typically the case for internal subdevices, like video data processing units
+within SoCs or complex PCI(e) boards, camera sensors in USB cameras or connected
+to SoCs, which pass information about them to bridge drivers, usually in their
+platform data.
+
+There are however also situations where subdevices have to be registered
+asynchronously to bridge devices. An example of such a configuration is a Device
+Tree based system where information about subdevices is made available to the
+system independently from the bridge devices, e.g. when subdevices are defined
+in DT as I2C device nodes. The API used in this second case is described further
+below.
+
+Using one or the other registration method only affects the probing process, the
+run-time bridge-subdevice interaction is in both cases the same.
+
+In the synchronous case a device (bridge) driver needs to register the
+:c:type:`v4l2_subdev` with the v4l2_device:
+
+	:c:func:`v4l2_device_register_subdev <v4l2_device_register_subdev>`
+	(:c:type:`v4l2_dev <v4l2_device>`, :c:type:`sd <v4l2_subdev>`).
+
+This can fail if the subdev module disappeared before it could be registered.
+After this function was called successfully the subdev->dev field points to
+the :c:type:`v4l2_device`.
+
+If the v4l2_device parent device has a non-NULL mdev field, the sub-device
+entity will be automatically registered with the media device.
+
+You can unregister a sub-device using:
+
+	:c:func:`v4l2_device_unregister_subdev <v4l2_device_unregister_subdev>`
+	(:c:type:`sd <v4l2_subdev>`).
+
+
+Afterwards the subdev module can be unloaded and
+:c:type:`sd <v4l2_subdev>`->dev == ``NULL``.
+
+You can call an ops function either directly:
+
+.. code-block:: c
+
+	err = sd->ops->core->g_std(sd, &norm);
+
+but it is better and easier to use this macro:
+
+.. code-block:: c
+
+	err = v4l2_subdev_call(sd, core, g_std, &norm);
+
+The macro will to the right ``NULL`` pointer checks and returns ``-ENODEV``
+if :c:type:`sd <v4l2_subdev>` is ``NULL``, ``-ENOIOCTLCMD`` if either
+:c:type:`sd <v4l2_subdev>`->core or :c:type:`sd <v4l2_subdev>`->core->g_std is ``NULL``, or the actual result of the
+:c:type:`sd <v4l2_subdev>`->ops->core->g_std ops.
+
+It is also possible to call all or a subset of the sub-devices:
+
+.. code-block:: c
+
+	v4l2_device_call_all(v4l2_dev, 0, core, g_std, &norm);
+
+Any subdev that does not support this ops is skipped and error results are
+ignored. If you want to check for errors use this:
+
+.. code-block:: c
+
+	err = v4l2_device_call_until_err(v4l2_dev, 0, core, g_std, &norm);
+
+Any error except ``-ENOIOCTLCMD`` will exit the loop with that error. If no
+errors (except ``-ENOIOCTLCMD``) occurred, then 0 is returned.
+
+The second argument to both calls is a group ID. If 0, then all subdevs are
+called. If non-zero, then only those whose group ID match that value will
+be called. Before a bridge driver registers a subdev it can set
+:c:type:`sd <v4l2_subdev>`->grp_id to whatever value it wants (it's 0 by
+default). This value is owned by the bridge driver and the sub-device driver
+will never modify or use it.
+
+The group ID gives the bridge driver more control how callbacks are called.
+For example, there may be multiple audio chips on a board, each capable of
+changing the volume. But usually only one will actually be used when the
+user want to change the volume. You can set the group ID for that subdev to
+e.g. AUDIO_CONTROLLER and specify that as the group ID value when calling
+``v4l2_device_call_all()``. That ensures that it will only go to the subdev
+that needs it.
+
+If the sub-device needs to notify its v4l2_device parent of an event, then
+it can call ``v4l2_subdev_notify(sd, notification, arg)``. This macro checks
+whether there is a ``notify()`` callback defined and returns ``-ENODEV`` if not.
+Otherwise the result of the ``notify()`` call is returned.
+
+The advantage of using :c:type:`v4l2_subdev` is that it is a generic struct and
+does not contain any knowledge about the underlying hardware. So a driver might
+contain several subdevs that use an I2C bus, but also a subdev that is
+controlled through GPIO pins. This distinction is only relevant when setting
+up the device, but once the subdev is registered it is completely transparent.
+
+In the asynchronous case subdevice probing can be invoked independently of the
+bridge driver availability. The subdevice driver then has to verify whether all
+the requirements for a successful probing are satisfied. This can include a
+check for a master clock availability. If any of the conditions aren't satisfied
+the driver might decide to return ``-EPROBE_DEFER`` to request further reprobing
+attempts. Once all conditions are met the subdevice shall be registered using
+the :c:func:`v4l2_async_register_subdev` function. Unregistration is
+performed using the :c:func:`v4l2_async_unregister_subdev` call. Subdevices
+registered this way are stored in a global list of subdevices, ready to be
+picked up by bridge drivers.
+
+Bridge drivers in turn have to register a notifier object. This is
+performed using the :c:func:`v4l2_async_notifier_register` call. To
+unregister the notifier the driver has to call
+:c:func:`v4l2_async_notifier_unregister`. The former of the two functions
+takes two arguments: a pointer to struct :c:type:`v4l2_device` and a
+pointer to struct :c:type:`v4l2_async_notifier`.
+
+Before registering the notifier, bridge drivers must do two things:
+first, the notifier must be initialized using the
+:c:func:`v4l2_async_notifier_init`. Second, bridge drivers can then
+begin to form a list of subdevice descriptors that the bridge device
+needs for its operation. Subdevice descriptors are added to the notifier
+using the :c:func:`v4l2_async_notifier_add_subdev` call. This function
+takes two arguments: a pointer to struct :c:type:`v4l2_async_notifier`,
+and a pointer to the subdevice descripter, which is of type struct
+:c:type:`v4l2_async_subdev`.
+
+The V4L2 core will then use these descriptors to match asynchronously
+registered subdevices to them. If a match is detected the ``.bound()``
+notifier callback is called. After all subdevices have been located the
+.complete() callback is called. When a subdevice is removed from the
+system the .unbind() method is called. All three callbacks are optional.
+
+V4L2 sub-device userspace API
+-----------------------------
+
+Beside exposing a kernel API through the :c:type:`v4l2_subdev_ops` structure,
+V4L2 sub-devices can also be controlled directly by userspace applications.
+
+Device nodes named ``v4l-subdev``\ *X* can be created in ``/dev`` to access
+sub-devices directly. If a sub-device supports direct userspace configuration
+it must set the ``V4L2_SUBDEV_FL_HAS_DEVNODE`` flag before being registered.
+
+After registering sub-devices, the :c:type:`v4l2_device` driver can create
+device nodes for all registered sub-devices marked with
+``V4L2_SUBDEV_FL_HAS_DEVNODE`` by calling
+:c:func:`v4l2_device_register_subdev_nodes`. Those device nodes will be
+automatically removed when sub-devices are unregistered.
+
+The device node handles a subset of the V4L2 API.
+
+``VIDIOC_QUERYCTRL``,
+``VIDIOC_QUERYMENU``,
+``VIDIOC_G_CTRL``,
+``VIDIOC_S_CTRL``,
+``VIDIOC_G_EXT_CTRLS``,
+``VIDIOC_S_EXT_CTRLS`` and
+``VIDIOC_TRY_EXT_CTRLS``:
+
+	The controls ioctls are identical to the ones defined in V4L2. They
+	behave identically, with the only exception that they deal only with
+	controls implemented in the sub-device. Depending on the driver, those
+	controls can be also be accessed through one (or several) V4L2 device
+	nodes.
+
+``VIDIOC_DQEVENT``,
+``VIDIOC_SUBSCRIBE_EVENT`` and
+``VIDIOC_UNSUBSCRIBE_EVENT``
+
+	The events ioctls are identical to the ones defined in V4L2. They
+	behave identically, with the only exception that they deal only with
+	events generated by the sub-device. Depending on the driver, those
+	events can also be reported by one (or several) V4L2 device nodes.
+
+	Sub-device drivers that want to use events need to set the
+	``V4L2_SUBDEV_USES_EVENTS`` :c:type:`v4l2_subdev`.flags and initialize
+	:c:type:`v4l2_subdev`.nevents to events queue depth before registering
+	the sub-device. After registration events can be queued as usual on the
+	:c:type:`v4l2_subdev`.devnode device node.
+
+	To properly support events, the ``poll()`` file operation is also
+	implemented.
+
+Private ioctls
+
+	All ioctls not in the above list are passed directly to the sub-device
+	driver through the core::ioctl operation.
+
+
+I2C sub-device drivers
+----------------------
+
+Since these drivers are so common, special helper functions are available to
+ease the use of these drivers (``v4l2-common.h``).
+
+The recommended method of adding :c:type:`v4l2_subdev` support to an I2C driver
+is to embed the :c:type:`v4l2_subdev` struct into the state struct that is
+created for each I2C device instance. Very simple devices have no state
+struct and in that case you can just create a :c:type:`v4l2_subdev` directly.
+
+A typical state struct would look like this (where 'chipname' is replaced by
+the name of the chip):
+
+.. code-block:: c
+
+	struct chipname_state {
+		struct v4l2_subdev sd;
+		...  /* additional state fields */
+	};
+
+Initialize the :c:type:`v4l2_subdev` struct as follows:
+
+.. code-block:: c
+
+	v4l2_i2c_subdev_init(&state->sd, client, subdev_ops);
+
+This function will fill in all the fields of :c:type:`v4l2_subdev` ensure that
+the :c:type:`v4l2_subdev` and i2c_client both point to one another.
+
+You should also add a helper inline function to go from a :c:type:`v4l2_subdev`
+pointer to a chipname_state struct:
+
+.. code-block:: c
+
+	static inline struct chipname_state *to_state(struct v4l2_subdev *sd)
+	{
+		return container_of(sd, struct chipname_state, sd);
+	}
+
+Use this to go from the :c:type:`v4l2_subdev` struct to the ``i2c_client``
+struct:
+
+.. code-block:: c
+
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+And this to go from an ``i2c_client`` to a :c:type:`v4l2_subdev` struct:
+
+.. code-block:: c
+
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+Make sure to call
+:c:func:`v4l2_device_unregister_subdev`\ (:c:type:`sd <v4l2_subdev>`)
+when the ``remove()`` callback is called. This will unregister the sub-device
+from the bridge driver. It is safe to call this even if the sub-device was
+never registered.
+
+You need to do this because when the bridge driver destroys the i2c adapter
+the ``remove()`` callbacks are called of the i2c devices on that adapter.
+After that the corresponding v4l2_subdev structures are invalid, so they
+have to be unregistered first. Calling
+:c:func:`v4l2_device_unregister_subdev`\ (:c:type:`sd <v4l2_subdev>`)
+from the ``remove()`` callback ensures that this is always done correctly.
+
+
+The bridge driver also has some helper functions it can use:
+
+.. code-block:: c
+
+	struct v4l2_subdev *sd = v4l2_i2c_new_subdev(v4l2_dev, adapter,
+					"module_foo", "chipid", 0x36, NULL);
+
+This loads the given module (can be ``NULL`` if no module needs to be loaded)
+and calls :c:func:`i2c_new_device` with the given ``i2c_adapter`` and
+chip/address arguments. If all goes well, then it registers the subdev with
+the v4l2_device.
+
+You can also use the last argument of :c:func:`v4l2_i2c_new_subdev` to pass
+an array of possible I2C addresses that it should probe. These probe addresses
+are only used if the previous argument is 0. A non-zero argument means that you
+know the exact i2c address so in that case no probing will take place.
+
+Both functions return ``NULL`` if something went wrong.
+
+Note that the chipid you pass to :c:func:`v4l2_i2c_new_subdev` is usually
+the same as the module name. It allows you to specify a chip variant, e.g.
+"saa7114" or "saa7115". In general though the i2c driver autodetects this.
+The use of chipid is something that needs to be looked at more closely at a
+later date. It differs between i2c drivers and as such can be confusing.
+To see which chip variants are supported you can look in the i2c driver code
+for the i2c_device_id table. This lists all the possibilities.
+
+There are one more helper function:
+
+:c:func:`v4l2_i2c_new_subdev_board` uses an :c:type:`i2c_board_info` struct
+which is passed to the i2c driver and replaces the irq, platform_data and addr
+arguments.
+
+If the subdev supports the s_config core ops, then that op is called with
+the irq and platform_data arguments after the subdev was setup.
+
+The :c:func:`v4l2_i2c_new_subdev` function will call
+:c:func:`v4l2_i2c_new_subdev_board`, internally filling a
+:c:type:`i2c_board_info` structure using the ``client_type`` and the
+``addr`` to fill it.
+
+V4L2 sub-device functions and data structures
+---------------------------------------------
+
+.. kernel-doc:: include/media/v4l2-subdev.h
+
+.. kernel-doc:: include/media/v4l2-async.h
diff --git a/Documentation/driver-api/media/v4l2-tuner.rst b/Documentation/driver-api/media/v4l2-tuner.rst
new file mode 100644
index 000000000000..e6caa3321566
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-tuner.rst
@@ -0,0 +1,8 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Tuner functions and data structures
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. kernel-doc:: include/media/tuner.h
+
+.. kernel-doc:: include/media/tuner-types.h
diff --git a/Documentation/driver-api/media/v4l2-tveeprom.rst b/Documentation/driver-api/media/v4l2-tveeprom.rst
new file mode 100644
index 000000000000..43fb391edaba
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-tveeprom.rst
@@ -0,0 +1,6 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Hauppauge TV EEPROM functions and data structures
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. kernel-doc:: include/media/tveeprom.h
diff --git a/Documentation/driver-api/media/v4l2-videobuf.rst b/Documentation/driver-api/media/v4l2-videobuf.rst
new file mode 100644
index 000000000000..4b1d84eefeb8
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-videobuf.rst
@@ -0,0 +1,403 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. _vb_framework:
+
+Videobuf Framework
+==================
+
+Author: Jonathan Corbet <corbet@lwn.net>
+
+Current as of 2.6.33
+
+.. note::
+
+   The videobuf framework was deprecated in favor of videobuf2. Shouldn't
+   be used on new drivers.
+
+Introduction
+------------
+
+The videobuf layer functions as a sort of glue layer between a V4L2 driver
+and user space.  It handles the allocation and management of buffers for
+the storage of video frames.  There is a set of functions which can be used
+to implement many of the standard POSIX I/O system calls, including read(),
+poll(), and, happily, mmap().  Another set of functions can be used to
+implement the bulk of the V4L2 ioctl() calls related to streaming I/O,
+including buffer allocation, queueing and dequeueing, and streaming
+control.  Using videobuf imposes a few design decisions on the driver
+author, but the payback comes in the form of reduced code in the driver and
+a consistent implementation of the V4L2 user-space API.
+
+Buffer types
+------------
+
+Not all video devices use the same kind of buffers.  In fact, there are (at
+least) three common variations:
+
+ - Buffers which are scattered in both the physical and (kernel) virtual
+   address spaces.  (Almost) all user-space buffers are like this, but it
+   makes great sense to allocate kernel-space buffers this way as well when
+   it is possible.  Unfortunately, it is not always possible; working with
+   this kind of buffer normally requires hardware which can do
+   scatter/gather DMA operations.
+
+ - Buffers which are physically scattered, but which are virtually
+   contiguous; buffers allocated with vmalloc(), in other words.  These
+   buffers are just as hard to use for DMA operations, but they can be
+   useful in situations where DMA is not available but virtually-contiguous
+   buffers are convenient.
+
+ - Buffers which are physically contiguous.  Allocation of this kind of
+   buffer can be unreliable on fragmented systems, but simpler DMA
+   controllers cannot deal with anything else.
+
+Videobuf can work with all three types of buffers, but the driver author
+must pick one at the outset and design the driver around that decision.
+
+[It's worth noting that there's a fourth kind of buffer: "overlay" buffers
+which are located within the system's video memory.  The overlay
+functionality is considered to be deprecated for most use, but it still
+shows up occasionally in system-on-chip drivers where the performance
+benefits merit the use of this technique.  Overlay buffers can be handled
+as a form of scattered buffer, but there are very few implementations in
+the kernel and a description of this technique is currently beyond the
+scope of this document.]
+
+Data structures, callbacks, and initialization
+----------------------------------------------
+
+Depending on which type of buffers are being used, the driver should
+include one of the following files:
+
+.. code-block:: none
+
+    <media/videobuf-dma-sg.h>		/* Physically scattered */
+    <media/videobuf-vmalloc.h>		/* vmalloc() buffers	*/
+    <media/videobuf-dma-contig.h>	/* Physically contiguous */
+
+The driver's data structure describing a V4L2 device should include a
+struct videobuf_queue instance for the management of the buffer queue,
+along with a list_head for the queue of available buffers.  There will also
+need to be an interrupt-safe spinlock which is used to protect (at least)
+the queue.
+
+The next step is to write four simple callbacks to help videobuf deal with
+the management of buffers:
+
+.. code-block:: none
+
+    struct videobuf_queue_ops {
+	int (*buf_setup)(struct videobuf_queue *q,
+			 unsigned int *count, unsigned int *size);
+	int (*buf_prepare)(struct videobuf_queue *q,
+			   struct videobuf_buffer *vb,
+			   enum v4l2_field field);
+	void (*buf_queue)(struct videobuf_queue *q,
+			  struct videobuf_buffer *vb);
+	void (*buf_release)(struct videobuf_queue *q,
+			    struct videobuf_buffer *vb);
+    };
+
+buf_setup() is called early in the I/O process, when streaming is being
+initiated; its purpose is to tell videobuf about the I/O stream.  The count
+parameter will be a suggested number of buffers to use; the driver should
+check it for rationality and adjust it if need be.  As a practical rule, a
+minimum of two buffers are needed for proper streaming, and there is
+usually a maximum (which cannot exceed 32) which makes sense for each
+device.  The size parameter should be set to the expected (maximum) size
+for each frame of data.
+
+Each buffer (in the form of a struct videobuf_buffer pointer) will be
+passed to buf_prepare(), which should set the buffer's size, width, height,
+and field fields properly.  If the buffer's state field is
+VIDEOBUF_NEEDS_INIT, the driver should pass it to:
+
+.. code-block:: none
+
+    int videobuf_iolock(struct videobuf_queue* q, struct videobuf_buffer *vb,
+			struct v4l2_framebuffer *fbuf);
+
+Among other things, this call will usually allocate memory for the buffer.
+Finally, the buf_prepare() function should set the buffer's state to
+VIDEOBUF_PREPARED.
+
+When a buffer is queued for I/O, it is passed to buf_queue(), which should
+put it onto the driver's list of available buffers and set its state to
+VIDEOBUF_QUEUED.  Note that this function is called with the queue spinlock
+held; if it tries to acquire it as well things will come to a screeching
+halt.  Yes, this is the voice of experience.  Note also that videobuf may
+wait on the first buffer in the queue; placing other buffers in front of it
+could again gum up the works.  So use list_add_tail() to enqueue buffers.
+
+Finally, buf_release() is called when a buffer is no longer intended to be
+used.  The driver should ensure that there is no I/O active on the buffer,
+then pass it to the appropriate free routine(s):
+
+.. code-block:: none
+
+    /* Scatter/gather drivers */
+    int videobuf_dma_unmap(struct videobuf_queue *q,
+			   struct videobuf_dmabuf *dma);
+    int videobuf_dma_free(struct videobuf_dmabuf *dma);
+
+    /* vmalloc drivers */
+    void videobuf_vmalloc_free (struct videobuf_buffer *buf);
+
+    /* Contiguous drivers */
+    void videobuf_dma_contig_free(struct videobuf_queue *q,
+				  struct videobuf_buffer *buf);
+
+One way to ensure that a buffer is no longer under I/O is to pass it to:
+
+.. code-block:: none
+
+    int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr);
+
+Here, vb is the buffer, non_blocking indicates whether non-blocking I/O
+should be used (it should be zero in the buf_release() case), and intr
+controls whether an interruptible wait is used.
+
+File operations
+---------------
+
+At this point, much of the work is done; much of the rest is slipping
+videobuf calls into the implementation of the other driver callbacks.  The
+first step is in the open() function, which must initialize the
+videobuf queue.  The function to use depends on the type of buffer used:
+
+.. code-block:: none
+
+    void videobuf_queue_sg_init(struct videobuf_queue *q,
+				struct videobuf_queue_ops *ops,
+				struct device *dev,
+				spinlock_t *irqlock,
+				enum v4l2_buf_type type,
+				enum v4l2_field field,
+				unsigned int msize,
+				void *priv);
+
+    void videobuf_queue_vmalloc_init(struct videobuf_queue *q,
+				struct videobuf_queue_ops *ops,
+				struct device *dev,
+				spinlock_t *irqlock,
+				enum v4l2_buf_type type,
+				enum v4l2_field field,
+				unsigned int msize,
+				void *priv);
+
+    void videobuf_queue_dma_contig_init(struct videobuf_queue *q,
+				       struct videobuf_queue_ops *ops,
+				       struct device *dev,
+				       spinlock_t *irqlock,
+				       enum v4l2_buf_type type,
+				       enum v4l2_field field,
+				       unsigned int msize,
+				       void *priv);
+
+In each case, the parameters are the same: q is the queue structure for the
+device, ops is the set of callbacks as described above, dev is the device
+structure for this video device, irqlock is an interrupt-safe spinlock to
+protect access to the data structures, type is the buffer type used by the
+device (cameras will use V4L2_BUF_TYPE_VIDEO_CAPTURE, for example), field
+describes which field is being captured (often V4L2_FIELD_NONE for
+progressive devices), msize is the size of any containing structure used
+around struct videobuf_buffer, and priv is a private data pointer which
+shows up in the priv_data field of struct videobuf_queue.  Note that these
+are void functions which, evidently, are immune to failure.
+
+V4L2 capture drivers can be written to support either of two APIs: the
+read() system call and the rather more complicated streaming mechanism.  As
+a general rule, it is necessary to support both to ensure that all
+applications have a chance of working with the device.  Videobuf makes it
+easy to do that with the same code.  To implement read(), the driver need
+only make a call to one of:
+
+.. code-block:: none
+
+    ssize_t videobuf_read_one(struct videobuf_queue *q,
+			      char __user *data, size_t count,
+			      loff_t *ppos, int nonblocking);
+
+    ssize_t videobuf_read_stream(struct videobuf_queue *q,
+				 char __user *data, size_t count,
+				 loff_t *ppos, int vbihack, int nonblocking);
+
+Either one of these functions will read frame data into data, returning the
+amount actually read; the difference is that videobuf_read_one() will only
+read a single frame, while videobuf_read_stream() will read multiple frames
+if they are needed to satisfy the count requested by the application.  A
+typical driver read() implementation will start the capture engine, call
+one of the above functions, then stop the engine before returning (though a
+smarter implementation might leave the engine running for a little while in
+anticipation of another read() call happening in the near future).
+
+The poll() function can usually be implemented with a direct call to:
+
+.. code-block:: none
+
+    unsigned int videobuf_poll_stream(struct file *file,
+				      struct videobuf_queue *q,
+				      poll_table *wait);
+
+Note that the actual wait queue eventually used will be the one associated
+with the first available buffer.
+
+When streaming I/O is done to kernel-space buffers, the driver must support
+the mmap() system call to enable user space to access the data.  In many
+V4L2 drivers, the often-complex mmap() implementation simplifies to a
+single call to:
+
+.. code-block:: none
+
+    int videobuf_mmap_mapper(struct videobuf_queue *q,
+			     struct vm_area_struct *vma);
+
+Everything else is handled by the videobuf code.
+
+The release() function requires two separate videobuf calls:
+
+.. code-block:: none
+
+    void videobuf_stop(struct videobuf_queue *q);
+    int videobuf_mmap_free(struct videobuf_queue *q);
+
+The call to videobuf_stop() terminates any I/O in progress - though it is
+still up to the driver to stop the capture engine.  The call to
+videobuf_mmap_free() will ensure that all buffers have been unmapped; if
+so, they will all be passed to the buf_release() callback.  If buffers
+remain mapped, videobuf_mmap_free() returns an error code instead.  The
+purpose is clearly to cause the closing of the file descriptor to fail if
+buffers are still mapped, but every driver in the 2.6.32 kernel cheerfully
+ignores its return value.
+
+ioctl() operations
+------------------
+
+The V4L2 API includes a very long list of driver callbacks to respond to
+the many ioctl() commands made available to user space.  A number of these
+- those associated with streaming I/O - turn almost directly into videobuf
+calls.  The relevant helper functions are:
+
+.. code-block:: none
+
+    int videobuf_reqbufs(struct videobuf_queue *q,
+			 struct v4l2_requestbuffers *req);
+    int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b);
+    int videobuf_qbuf(struct videobuf_queue *q, struct v4l2_buffer *b);
+    int videobuf_dqbuf(struct videobuf_queue *q, struct v4l2_buffer *b,
+		       int nonblocking);
+    int videobuf_streamon(struct videobuf_queue *q);
+    int videobuf_streamoff(struct videobuf_queue *q);
+
+So, for example, a VIDIOC_REQBUFS call turns into a call to the driver's
+vidioc_reqbufs() callback which, in turn, usually only needs to locate the
+proper struct videobuf_queue pointer and pass it to videobuf_reqbufs().
+These support functions can replace a great deal of buffer management
+boilerplate in a lot of V4L2 drivers.
+
+The vidioc_streamon() and vidioc_streamoff() functions will be a bit more
+complex, of course, since they will also need to deal with starting and
+stopping the capture engine.
+
+Buffer allocation
+-----------------
+
+Thus far, we have talked about buffers, but have not looked at how they are
+allocated.  The scatter/gather case is the most complex on this front.  For
+allocation, the driver can leave buffer allocation entirely up to the
+videobuf layer; in this case, buffers will be allocated as anonymous
+user-space pages and will be very scattered indeed.  If the application is
+using user-space buffers, no allocation is needed; the videobuf layer will
+take care of calling get_user_pages() and filling in the scatterlist array.
+
+If the driver needs to do its own memory allocation, it should be done in
+the vidioc_reqbufs() function, *after* calling videobuf_reqbufs().  The
+first step is a call to:
+
+.. code-block:: none
+
+    struct videobuf_dmabuf *videobuf_to_dma(struct videobuf_buffer *buf);
+
+The returned videobuf_dmabuf structure (defined in
+<media/videobuf-dma-sg.h>) includes a couple of relevant fields:
+
+.. code-block:: none
+
+    struct scatterlist  *sglist;
+    int                 sglen;
+
+The driver must allocate an appropriately-sized scatterlist array and
+populate it with pointers to the pieces of the allocated buffer; sglen
+should be set to the length of the array.
+
+Drivers using the vmalloc() method need not (and cannot) concern themselves
+with buffer allocation at all; videobuf will handle those details.  The
+same is normally true of contiguous-DMA drivers as well; videobuf will
+allocate the buffers (with dma_alloc_coherent()) when it sees fit.  That
+means that these drivers may be trying to do high-order allocations at any
+time, an operation which is not always guaranteed to work.  Some drivers
+play tricks by allocating DMA space at system boot time; videobuf does not
+currently play well with those drivers.
+
+As of 2.6.31, contiguous-DMA drivers can work with a user-supplied buffer,
+as long as that buffer is physically contiguous.  Normal user-space
+allocations will not meet that criterion, but buffers obtained from other
+kernel drivers, or those contained within huge pages, will work with these
+drivers.
+
+Filling the buffers
+-------------------
+
+The final part of a videobuf implementation has no direct callback - it's
+the portion of the code which actually puts frame data into the buffers,
+usually in response to interrupts from the device.  For all types of
+drivers, this process works approximately as follows:
+
+ - Obtain the next available buffer and make sure that somebody is actually
+   waiting for it.
+
+ - Get a pointer to the memory and put video data there.
+
+ - Mark the buffer as done and wake up the process waiting for it.
+
+Step (1) above is done by looking at the driver-managed list_head structure
+- the one which is filled in the buf_queue() callback.  Because starting
+the engine and enqueueing buffers are done in separate steps, it's possible
+for the engine to be running without any buffers available - in the
+vmalloc() case especially.  So the driver should be prepared for the list
+to be empty.  It is equally possible that nobody is yet interested in the
+buffer; the driver should not remove it from the list or fill it until a
+process is waiting on it.  That test can be done by examining the buffer's
+done field (a wait_queue_head_t structure) with waitqueue_active().
+
+A buffer's state should be set to VIDEOBUF_ACTIVE before being mapped for
+DMA; that ensures that the videobuf layer will not try to do anything with
+it while the device is transferring data.
+
+For scatter/gather drivers, the needed memory pointers will be found in the
+scatterlist structure described above.  Drivers using the vmalloc() method
+can get a memory pointer with:
+
+.. code-block:: none
+
+    void *videobuf_to_vmalloc(struct videobuf_buffer *buf);
+
+For contiguous DMA drivers, the function to use is:
+
+.. code-block:: none
+
+    dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf);
+
+The contiguous DMA API goes out of its way to hide the kernel-space address
+of the DMA buffer from drivers.
+
+The final step is to set the size field of the relevant videobuf_buffer
+structure to the actual size of the captured image, set state to
+VIDEOBUF_DONE, then call wake_up() on the done queue.  At this point, the
+buffer is owned by the videobuf layer and the driver should not touch it
+again.
+
+Developers who are interested in more information can go into the relevant
+header files; there are a few low-level functions declared there which have
+not been talked about here.  Note also that all of these calls are exported
+GPL-only, so they will not be available to non-GPL kernel modules.
diff --git a/Documentation/driver-api/media/v4l2-videobuf2.rst b/Documentation/driver-api/media/v4l2-videobuf2.rst
new file mode 100644
index 000000000000..1044f64ff168
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-videobuf2.rst
@@ -0,0 +1,12 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. _vb2_framework:
+
+V4L2 videobuf2 functions and data structures
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. kernel-doc:: include/media/videobuf2-core.h
+
+.. kernel-doc:: include/media/videobuf2-v4l2.h
+
+.. kernel-doc:: include/media/videobuf2-memops.h
diff --git a/Documentation/fb/api.rst b/Documentation/fb/api.rst
index 79ec33dded74..4f00e7196fef 100644
--- a/Documentation/fb/api.rst
+++ b/Documentation/fb/api.rst
@@ -290,12 +290,12 @@ the FB_CAP_FOURCC bit in the fb_fix_screeninfo capabilities field.
 FOURCC definitions are located in the linux/videodev2.h header. However, and
 despite starting with the V4L2_PIX_FMT_prefix, they are not restricted to V4L2
 and don't require usage of the V4L2 subsystem. FOURCC documentation is
-available in Documentation/media/uapi/v4l/pixfmt.rst.
+available in Documentation/userspace-api/media/v4l/pixfmt.rst.
 
 To select a format, applications set the grayscale field to the desired FOURCC.
 For YUV formats, they should also select the appropriate colorspace by setting
 the colorspace field to one of the colorspaces listed in linux/videodev2.h and
-documented in Documentation/media/uapi/v4l/colorspaces.rst.
+documented in Documentation/userspace-api/media/v4l/colorspaces.rst.
 
 The red, green, blue and transp fields are not used with the FOURCC-based API.
 For forward compatibility reasons applications must zero those fields, and
diff --git a/Documentation/features/debug/debug-vm-pgtable/arch-support.txt b/Documentation/features/debug/debug-vm-pgtable/arch-support.txt
new file mode 100644
index 000000000000..c527d05c0459
--- /dev/null
+++ b/Documentation/features/debug/debug-vm-pgtable/arch-support.txt
@@ -0,0 +1,34 @@
+#
+# Feature name:          debug-vm-pgtable
+#         Kconfig:       ARCH_HAS_DEBUG_VM_PGTABLE
+#         description:   arch supports pgtable tests for semantics compliance
+#
+    -----------------------
+    |         arch |status|
+    -----------------------
+    |       alpha: | TODO |
+    |         arc: |  ok  |
+    |         arm: | TODO |
+    |       arm64: |  ok  |
+    |         c6x: | TODO |
+    |        csky: | TODO |
+    |       h8300: | TODO |
+    |     hexagon: | TODO |
+    |        ia64: | TODO |
+    |        m68k: | TODO |
+    |  microblaze: | TODO |
+    |        mips: | TODO |
+    |       nds32: | TODO |
+    |       nios2: | TODO |
+    |    openrisc: | TODO |
+    |      parisc: | TODO |
+    |     powerpc: |  ok  |
+    |       riscv: | TODO |
+    |        s390: |  ok  |
+    |          sh: | TODO |
+    |       sparc: | TODO |
+    |          um: | TODO |
+    |   unicore32: | TODO |
+    |         x86: |  ok  |
+    |      xtensa: | TODO |
+    -----------------------
diff --git a/Documentation/filesystems/gfs2-glocks.rst b/Documentation/filesystems/gfs2-glocks.rst
new file mode 100644
index 000000000000..d14f230f0b12
--- /dev/null
+++ b/Documentation/filesystems/gfs2-glocks.rst
@@ -0,0 +1,253 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+============================
+Glock internal locking rules
+============================
+
+This documents the basic principles of the glock state machine
+internals. Each glock (struct gfs2_glock in fs/gfs2/incore.h)
+has two main (internal) locks:
+
+ 1. A spinlock (gl_lockref.lock) which protects the internal state such
+    as gl_state, gl_target and the list of holders (gl_holders)
+ 2. A non-blocking bit lock, GLF_LOCK, which is used to prevent other
+    threads from making calls to the DLM, etc. at the same time. If a
+    thread takes this lock, it must then call run_queue (usually via the
+    workqueue) when it releases it in order to ensure any pending tasks
+    are completed.
+
+The gl_holders list contains all the queued lock requests (not
+just the holders) associated with the glock. If there are any
+held locks, then they will be contiguous entries at the head
+of the list. Locks are granted in strictly the order that they
+are queued, except for those marked LM_FLAG_PRIORITY which are
+used only during recovery, and even then only for journal locks.
+
+There are three lock states that users of the glock layer can request,
+namely shared (SH), deferred (DF) and exclusive (EX). Those translate
+to the following DLM lock modes:
+
+==========	====== =====================================================
+Glock mode      DLM    lock mode
+==========	====== =====================================================
+    UN          IV/NL  Unlocked (no DLM lock associated with glock) or NL
+    SH          PR     (Protected read)
+    DF          CW     (Concurrent write)
+    EX          EX     (Exclusive)
+==========	====== =====================================================
+
+Thus DF is basically a shared mode which is incompatible with the "normal"
+shared lock mode, SH. In GFS2 the DF mode is used exclusively for direct I/O
+operations. The glocks are basically a lock plus some routines which deal
+with cache management. The following rules apply for the cache:
+
+==========      ==========   ==============   ==========   ==============
+Glock mode      Cache data   Cache Metadata   Dirty Data   Dirty Metadata
+==========      ==========   ==============   ==========   ==============
+    UN             No              No             No            No
+    SH             Yes             Yes            No            No
+    DF             No              Yes            No            No
+    EX             Yes             Yes            Yes           Yes
+==========      ==========   ==============   ==========   ==============
+
+These rules are implemented using the various glock operations which
+are defined for each type of glock. Not all types of glocks use
+all the modes. Only inode glocks use the DF mode for example.
+
+Table of glock operations and per type constants:
+
+=============      =============================================================
+Field              Purpose
+=============      =============================================================
+go_xmote_th        Called before remote state change (e.g. to sync dirty data)
+go_xmote_bh        Called after remote state change (e.g. to refill cache)
+go_inval           Called if remote state change requires invalidating the cache
+go_demote_ok       Returns boolean value of whether its ok to demote a glock
+                   (e.g. checks timeout, and that there is no cached data)
+go_lock            Called for the first local holder of a lock
+go_unlock          Called on the final local unlock of a lock
+go_dump            Called to print content of object for debugfs file, or on
+                   error to dump glock to the log.
+go_type            The type of the glock, ``LM_TYPE_*``
+go_callback	   Called if the DLM sends a callback to drop this lock
+go_flags	   GLOF_ASPACE is set, if the glock has an address space
+                   associated with it
+=============      =============================================================
+
+The minimum hold time for each lock is the time after a remote lock
+grant for which we ignore remote demote requests. This is in order to
+prevent a situation where locks are being bounced around the cluster
+from node to node with none of the nodes making any progress. This
+tends to show up most with shared mmaped files which are being written
+to by multiple nodes. By delaying the demotion in response to a
+remote callback, that gives the userspace program time to make
+some progress before the pages are unmapped.
+
+There is a plan to try and remove the go_lock and go_unlock callbacks
+if possible, in order to try and speed up the fast path though the locking.
+Also, eventually we hope to make the glock "EX" mode locally shared
+such that any local locking will be done with the i_mutex as required
+rather than via the glock.
+
+Locking rules for glock operations:
+
+=============    ======================    =============================
+Operation        GLF_LOCK bit lock held    gl_lockref.lock spinlock held
+=============    ======================    =============================
+go_xmote_th           Yes                       No
+go_xmote_bh           Yes                       No
+go_inval              Yes                       No
+go_demote_ok          Sometimes                 Yes
+go_lock               Yes                       No
+go_unlock             Yes                       No
+go_dump               Sometimes                 Yes
+go_callback           Sometimes (N/A)           Yes
+=============    ======================    =============================
+
+.. Note::
+
+   Operations must not drop either the bit lock or the spinlock
+   if its held on entry. go_dump and do_demote_ok must never block.
+   Note that go_dump will only be called if the glock's state
+   indicates that it is caching uptodate data.
+
+Glock locking order within GFS2:
+
+ 1. i_rwsem (if required)
+ 2. Rename glock (for rename only)
+ 3. Inode glock(s)
+    (Parents before children, inodes at "same level" with same parent in
+    lock number order)
+ 4. Rgrp glock(s) (for (de)allocation operations)
+ 5. Transaction glock (via gfs2_trans_begin) for non-read operations
+ 6. i_rw_mutex (if required)
+ 7. Page lock  (always last, very important!)
+
+There are two glocks per inode. One deals with access to the inode
+itself (locking order as above), and the other, known as the iopen
+glock is used in conjunction with the i_nlink field in the inode to
+determine the lifetime of the inode in question. Locking of inodes
+is on a per-inode basis. Locking of rgrps is on a per rgrp basis.
+In general we prefer to lock local locks prior to cluster locks.
+
+Glock Statistics
+----------------
+
+The stats are divided into two sets: those relating to the
+super block and those relating to an individual glock. The
+super block stats are done on a per cpu basis in order to
+try and reduce the overhead of gathering them. They are also
+further divided by glock type. All timings are in nanoseconds.
+
+In the case of both the super block and glock statistics,
+the same information is gathered in each case. The super
+block timing statistics are used to provide default values for
+the glock timing statistics, so that newly created glocks
+should have, as far as possible, a sensible starting point.
+The per-glock counters are initialised to zero when the
+glock is created. The per-glock statistics are lost when
+the glock is ejected from memory.
+
+The statistics are divided into three pairs of mean and
+variance, plus two counters. The mean/variance pairs are
+smoothed exponential estimates and the algorithm used is
+one which will be very familiar to those used to calculation
+of round trip times in network code. See "TCP/IP Illustrated,
+Volume 1", W. Richard Stevens, sect 21.3, "Round-Trip Time Measurement",
+p. 299 and onwards. Also, Volume 2, Sect. 25.10, p. 838 and onwards.
+Unlike the TCP/IP Illustrated case, the mean and variance are
+not scaled, but are in units of integer nanoseconds.
+
+The three pairs of mean/variance measure the following
+things:
+
+ 1. DLM lock time (non-blocking requests)
+ 2. DLM lock time (blocking requests)
+ 3. Inter-request time (again to the DLM)
+
+A non-blocking request is one which will complete right
+away, whatever the state of the DLM lock in question. That
+currently means any requests when (a) the current state of
+the lock is exclusive, i.e. a lock demotion (b) the requested
+state is either null or unlocked (again, a demotion) or (c) the
+"try lock" flag is set. A blocking request covers all the other
+lock requests.
+
+There are two counters. The first is there primarily to show
+how many lock requests have been made, and thus how much data
+has gone into the mean/variance calculations. The other counter
+is counting queuing of holders at the top layer of the glock
+code. Hopefully that number will be a lot larger than the number
+of dlm lock requests issued.
+
+So why gather these statistics? There are several reasons
+we'd like to get a better idea of these timings:
+
+1. To be able to better set the glock "min hold time"
+2. To spot performance issues more easily
+3. To improve the algorithm for selecting resource groups for
+   allocation (to base it on lock wait time, rather than blindly
+   using a "try lock")
+
+Due to the smoothing action of the updates, a step change in
+some input quantity being sampled will only fully be taken
+into account after 8 samples (or 4 for the variance) and this
+needs to be carefully considered when interpreting the
+results.
+
+Knowing both the time it takes a lock request to complete and
+the average time between lock requests for a glock means we
+can compute the total percentage of the time for which the
+node is able to use a glock vs. time that the rest of the
+cluster has its share. That will be very useful when setting
+the lock min hold time.
+
+Great care has been taken to ensure that we
+measure exactly the quantities that we want, as accurately
+as possible. There are always inaccuracies in any
+measuring system, but I hope this is as accurate as we
+can reasonably make it.
+
+Per sb stats can be found here::
+
+    /sys/kernel/debug/gfs2/<fsname>/sbstats
+
+Per glock stats can be found here::
+
+    /sys/kernel/debug/gfs2/<fsname>/glstats
+
+Assuming that debugfs is mounted on /sys/kernel/debug and also
+that <fsname> is replaced with the name of the gfs2 filesystem
+in question.
+
+The abbreviations used in the output as are follows:
+
+=========  ================================================================
+srtt       Smoothed round trip time for non blocking dlm requests
+srttvar    Variance estimate for srtt
+srttb      Smoothed round trip time for (potentially) blocking dlm requests
+srttvarb   Variance estimate for srttb
+sirt       Smoothed inter request time (for dlm requests)
+sirtvar    Variance estimate for sirt
+dlm        Number of dlm requests made (dcnt in glstats file)
+queue      Number of glock requests queued (qcnt in glstats file)
+=========  ================================================================
+
+The sbstats file contains a set of these stats for each glock type (so 8 lines
+for each type) and for each cpu (one column per cpu). The glstats file contains
+a set of these stats for each glock in a similar format to the glocks file, but
+using the format mean/variance for each of the timing stats.
+
+The gfs2_glock_lock_time tracepoint prints out the current values of the stats
+for the glock in question, along with some addition information on each dlm
+reply that is received:
+
+======   =======================================
+status   The status of the dlm request
+flags    The dlm request flags
+tdiff    The time taken by this specific request
+======   =======================================
+
+(remaining fields as per above list)
+
+
diff --git a/Documentation/filesystems/gfs2-glocks.txt b/Documentation/filesystems/gfs2-glocks.txt
deleted file mode 100644
index 7059623635b2..000000000000
--- a/Documentation/filesystems/gfs2-glocks.txt
+++ /dev/null
@@ -1,232 +0,0 @@
-                   Glock internal locking rules
-                  ------------------------------
-
-This documents the basic principles of the glock state machine
-internals. Each glock (struct gfs2_glock in fs/gfs2/incore.h)
-has two main (internal) locks:
-
- 1. A spinlock (gl_lockref.lock) which protects the internal state such
-    as gl_state, gl_target and the list of holders (gl_holders)
- 2. A non-blocking bit lock, GLF_LOCK, which is used to prevent other
-    threads from making calls to the DLM, etc. at the same time. If a
-    thread takes this lock, it must then call run_queue (usually via the
-    workqueue) when it releases it in order to ensure any pending tasks
-    are completed.
-
-The gl_holders list contains all the queued lock requests (not
-just the holders) associated with the glock. If there are any
-held locks, then they will be contiguous entries at the head
-of the list. Locks are granted in strictly the order that they
-are queued, except for those marked LM_FLAG_PRIORITY which are
-used only during recovery, and even then only for journal locks.
-
-There are three lock states that users of the glock layer can request,
-namely shared (SH), deferred (DF) and exclusive (EX). Those translate
-to the following DLM lock modes:
-
-Glock mode    | DLM lock mode
-------------------------------
-    UN        |    IV/NL  Unlocked (no DLM lock associated with glock) or NL
-    SH        |    PR     (Protected read)
-    DF        |    CW     (Concurrent write)
-    EX        |    EX     (Exclusive)
-
-Thus DF is basically a shared mode which is incompatible with the "normal"
-shared lock mode, SH. In GFS2 the DF mode is used exclusively for direct I/O
-operations. The glocks are basically a lock plus some routines which deal
-with cache management. The following rules apply for the cache:
-
-Glock mode   |  Cache data | Cache Metadata | Dirty Data | Dirty Metadata
---------------------------------------------------------------------------
-    UN       |     No      |       No       |     No     |      No
-    SH       |     Yes     |       Yes      |     No     |      No
-    DF       |     No      |       Yes      |     No     |      No
-    EX       |     Yes     |       Yes      |     Yes    |      Yes
-
-These rules are implemented using the various glock operations which
-are defined for each type of glock. Not all types of glocks use
-all the modes. Only inode glocks use the DF mode for example.
-
-Table of glock operations and per type constants:
-
-Field            | Purpose
-----------------------------------------------------------------------------
-go_xmote_th      | Called before remote state change (e.g. to sync dirty data)
-go_xmote_bh      | Called after remote state change (e.g. to refill cache)
-go_inval         | Called if remote state change requires invalidating the cache
-go_demote_ok     | Returns boolean value of whether its ok to demote a glock
-                 | (e.g. checks timeout, and that there is no cached data)
-go_lock          | Called for the first local holder of a lock
-go_unlock        | Called on the final local unlock of a lock
-go_dump          | Called to print content of object for debugfs file, or on
-                 | error to dump glock to the log.
-go_type          | The type of the glock, LM_TYPE_.....
-go_callback	 | Called if the DLM sends a callback to drop this lock
-go_flags	 | GLOF_ASPACE is set, if the glock has an address space
-                 | associated with it
-
-The minimum hold time for each lock is the time after a remote lock
-grant for which we ignore remote demote requests. This is in order to
-prevent a situation where locks are being bounced around the cluster
-from node to node with none of the nodes making any progress. This
-tends to show up most with shared mmaped files which are being written
-to by multiple nodes. By delaying the demotion in response to a
-remote callback, that gives the userspace program time to make
-some progress before the pages are unmapped.
-
-There is a plan to try and remove the go_lock and go_unlock callbacks
-if possible, in order to try and speed up the fast path though the locking.
-Also, eventually we hope to make the glock "EX" mode locally shared
-such that any local locking will be done with the i_mutex as required
-rather than via the glock.
-
-Locking rules for glock operations:
-
-Operation     |  GLF_LOCK bit lock held |  gl_lockref.lock spinlock held
--------------------------------------------------------------------------
-go_xmote_th   |       Yes               |       No
-go_xmote_bh   |       Yes               |       No
-go_inval      |       Yes               |       No
-go_demote_ok  |       Sometimes         |       Yes
-go_lock       |       Yes               |       No
-go_unlock     |       Yes               |       No
-go_dump       |       Sometimes         |       Yes
-go_callback   |       Sometimes (N/A)   |       Yes
-
-N.B. Operations must not drop either the bit lock or the spinlock
-if its held on entry. go_dump and do_demote_ok must never block.
-Note that go_dump will only be called if the glock's state
-indicates that it is caching uptodate data.
-
-Glock locking order within GFS2:
-
- 1. i_rwsem (if required)
- 2. Rename glock (for rename only)
- 3. Inode glock(s)
-    (Parents before children, inodes at "same level" with same parent in
-     lock number order)
- 4. Rgrp glock(s) (for (de)allocation operations)
- 5. Transaction glock (via gfs2_trans_begin) for non-read operations
- 6. i_rw_mutex (if required)
- 7. Page lock  (always last, very important!)
-
-There are two glocks per inode. One deals with access to the inode
-itself (locking order as above), and the other, known as the iopen
-glock is used in conjunction with the i_nlink field in the inode to
-determine the lifetime of the inode in question. Locking of inodes
-is on a per-inode basis. Locking of rgrps is on a per rgrp basis.
-In general we prefer to lock local locks prior to cluster locks.
-
-                            Glock Statistics
-                           ------------------
-
-The stats are divided into two sets: those relating to the
-super block and those relating to an individual glock. The
-super block stats are done on a per cpu basis in order to
-try and reduce the overhead of gathering them. They are also
-further divided by glock type. All timings are in nanoseconds.
-
-In the case of both the super block and glock statistics,
-the same information is gathered in each case. The super
-block timing statistics are used to provide default values for
-the glock timing statistics, so that newly created glocks
-should have, as far as possible, a sensible starting point.
-The per-glock counters are initialised to zero when the
-glock is created. The per-glock statistics are lost when
-the glock is ejected from memory.
-
-The statistics are divided into three pairs of mean and
-variance, plus two counters. The mean/variance pairs are
-smoothed exponential estimates and the algorithm used is
-one which will be very familiar to those used to calculation
-of round trip times in network code. See "TCP/IP Illustrated,
-Volume 1", W. Richard Stevens, sect 21.3, "Round-Trip Time Measurement",
-p. 299 and onwards. Also, Volume 2, Sect. 25.10, p. 838 and onwards.
-Unlike the TCP/IP Illustrated case, the mean and variance are
-not scaled, but are in units of integer nanoseconds.
-
-The three pairs of mean/variance measure the following
-things:
-
- 1. DLM lock time (non-blocking requests)
- 2. DLM lock time (blocking requests)
- 3. Inter-request time (again to the DLM)
-
-A non-blocking request is one which will complete right
-away, whatever the state of the DLM lock in question. That
-currently means any requests when (a) the current state of
-the lock is exclusive, i.e. a lock demotion (b) the requested
-state is either null or unlocked (again, a demotion) or (c) the
-"try lock" flag is set. A blocking request covers all the other
-lock requests.
-
-There are two counters. The first is there primarily to show
-how many lock requests have been made, and thus how much data
-has gone into the mean/variance calculations. The other counter
-is counting queuing of holders at the top layer of the glock
-code. Hopefully that number will be a lot larger than the number
-of dlm lock requests issued.
-
-So why gather these statistics? There are several reasons
-we'd like to get a better idea of these timings:
-
-1. To be able to better set the glock "min hold time"
-2. To spot performance issues more easily
-3. To improve the algorithm for selecting resource groups for
-allocation (to base it on lock wait time, rather than blindly
-using a "try lock")
-
-Due to the smoothing action of the updates, a step change in
-some input quantity being sampled will only fully be taken
-into account after 8 samples (or 4 for the variance) and this
-needs to be carefully considered when interpreting the
-results.
-
-Knowing both the time it takes a lock request to complete and
-the average time between lock requests for a glock means we
-can compute the total percentage of the time for which the
-node is able to use a glock vs. time that the rest of the
-cluster has its share. That will be very useful when setting
-the lock min hold time.
-
-Great care has been taken to ensure that we
-measure exactly the quantities that we want, as accurately
-as possible. There are always inaccuracies in any
-measuring system, but I hope this is as accurate as we
-can reasonably make it.
-
-Per sb stats can be found here:
-/sys/kernel/debug/gfs2/<fsname>/sbstats
-Per glock stats can be found here:
-/sys/kernel/debug/gfs2/<fsname>/glstats
-
-Assuming that debugfs is mounted on /sys/kernel/debug and also
-that <fsname> is replaced with the name of the gfs2 filesystem
-in question.
-
-The abbreviations used in the output as are follows:
-
-srtt     - Smoothed round trip time for non-blocking dlm requests
-srttvar  - Variance estimate for srtt
-srttb    - Smoothed round trip time for (potentially) blocking dlm requests
-srttvarb - Variance estimate for srttb
-sirt     - Smoothed inter-request time (for dlm requests)
-sirtvar  - Variance estimate for sirt
-dlm      - Number of dlm requests made (dcnt in glstats file)
-queue    - Number of glock requests queued (qcnt in glstats file)
-
-The sbstats file contains a set of these stats for each glock type (so 8 lines
-for each type) and for each cpu (one column per cpu). The glstats file contains
-a set of these stats for each glock in a similar format to the glocks file, but
-using the format mean/variance for each of the timing stats.
-
-The gfs2_glock_lock_time tracepoint prints out the current values of the stats
-for the glock in question, along with some addition information on each dlm
-reply that is received:
-
-status - The status of the dlm request
-flags  - The dlm request flags
-tdiff  - The time taken by this specific request
-(remaining fields as per above list)
-
-
diff --git a/Documentation/filesystems/index.rst b/Documentation/filesystems/index.rst
index e7b46dac7079..0641429f53a2 100644
--- a/Documentation/filesystems/index.rst
+++ b/Documentation/filesystems/index.rst
@@ -69,6 +69,7 @@ Documentation for filesystem implementations.
    f2fs
    gfs2
    gfs2-uevents
+   gfs2-glocks
    hfs
    hfsplus
    hpfs
diff --git a/Documentation/gpu/amdgpu.rst b/Documentation/gpu/amdgpu.rst
index 0efede580039..4cc74325bf91 100644
--- a/Documentation/gpu/amdgpu.rst
+++ b/Documentation/gpu/amdgpu.rst
@@ -202,3 +202,91 @@ busy_percent
 
 .. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
    :doc: busy_percent
+
+GPU Product Information
+=======================
+
+Information about the GPU can be obtained on certain cards
+via sysfs
+
+product_name
+------------
+
+.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+   :doc: product_name
+
+product_number
+--------------
+
+.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+   :doc: product_name
+
+serial_number
+-------------
+
+.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+   :doc: serial_number
+
+unique_id
+---------
+
+.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
+   :doc: unique_id
+
+GPU Memory Usage Information
+============================
+
+Various memory accounting can be accessed via sysfs
+
+mem_info_vram_total
+-------------------
+
+.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
+   :doc: mem_info_vram_total
+
+mem_info_vram_used
+------------------
+
+.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
+   :doc: mem_info_vram_used
+
+mem_info_vis_vram_total
+-----------------------
+
+.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
+   :doc: mem_info_vis_vram_total
+
+mem_info_vis_vram_used
+----------------------
+
+.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
+   :doc: mem_info_vis_vram_used
+
+mem_info_gtt_total
+------------------
+
+.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
+   :doc: mem_info_gtt_total
+
+mem_info_gtt_used
+-----------------
+
+.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
+   :doc: mem_info_gtt_used
+
+PCIe Accounting Information
+===========================
+
+pcie_bw
+-------
+
+.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
+   :doc: pcie_bw
+
+pcie_replay_count
+-----------------
+
+.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+   :doc: pcie_replay_count
+
+
diff --git a/Documentation/gpu/drm-internals.rst b/Documentation/gpu/drm-internals.rst
index a73320576ca9..12272b168580 100644
--- a/Documentation/gpu/drm-internals.rst
+++ b/Documentation/gpu/drm-internals.rst
@@ -132,6 +132,18 @@ be unmapped; on many devices, the ROM address decoder is shared with
 other BARs, so leaving it mapped could cause undesired behaviour like
 hangs or memory corruption.
 
+Managed Resources
+-----------------
+
+.. kernel-doc:: drivers/gpu/drm/drm_managed.c
+   :doc: managed resources
+
+.. kernel-doc:: drivers/gpu/drm/drm_managed.c
+   :export:
+
+.. kernel-doc:: include/drm/drm_managed.h
+   :internal:
+
 Bus-specific Device Registration and PCI Support
 ------------------------------------------------
 
diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst
index 906771e03103..397314d08f77 100644
--- a/Documentation/gpu/drm-kms.rst
+++ b/Documentation/gpu/drm-kms.rst
@@ -3,7 +3,7 @@ Kernel Mode Setting (KMS)
 =========================
 
 Drivers must initialize the mode setting core by calling
-drm_mode_config_init() on the DRM device. The function
+drmm_mode_config_init() on the DRM device. The function
 initializes the :c:type:`struct drm_device <drm_device>`
 mode_config field and never fails. Once done, mode configuration must
 be setup by initializing the following fields.
@@ -397,6 +397,9 @@ Connector Functions Reference
 Writeback Connectors
 --------------------
 
+.. kernel-doc:: include/drm/drm_writeback.h
+  :internal:
+
 .. kernel-doc:: drivers/gpu/drm/drm_writeback.c
   :doc: overview
 
diff --git a/Documentation/gpu/drm-mm.rst b/Documentation/gpu/drm-mm.rst
index c77b32601260..1839762044be 100644
--- a/Documentation/gpu/drm-mm.rst
+++ b/Documentation/gpu/drm-mm.rst
@@ -373,15 +373,6 @@ GEM CMA Helper Functions Reference
 .. kernel-doc:: drivers/gpu/drm/drm_gem_cma_helper.c
    :export:
 
-VRAM Helper Function Reference
-==============================
-
-.. kernel-doc:: drivers/gpu/drm/drm_vram_helper_common.c
-   :doc: overview
-
-.. kernel-doc:: include/drm/drm_gem_vram_helper.h
-   :internal:
-
 GEM VRAM Helper Functions Reference
 -----------------------------------
 
diff --git a/Documentation/gpu/i915.rst b/Documentation/gpu/i915.rst
index f6d363b6756e..429b08aac797 100644
--- a/Documentation/gpu/i915.rst
+++ b/Documentation/gpu/i915.rst
@@ -391,19 +391,19 @@ Global GTT views
 GTT Fences and Swizzling
 ------------------------
 
-.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_fence_reg.c
+.. kernel-doc:: drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c
    :internal:
 
 Global GTT Fence Handling
 ~~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_fence_reg.c
+.. kernel-doc:: drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c
    :doc: fence register handling
 
 Hardware Tiling and Swizzling Details
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_fence_reg.c
+.. kernel-doc:: drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c
    :doc: tiling swizzling details
 
 Object Tiling IOCTLs
diff --git a/Documentation/hwmon/isl68137.rst b/Documentation/hwmon/isl68137.rst
index cc4b61447b63..0e71b22047f8 100644
--- a/Documentation/hwmon/isl68137.rst
+++ b/Documentation/hwmon/isl68137.rst
@@ -16,7 +16,7 @@ Supported chips:
 
   * Renesas ISL68220
 
-    Prefix: 'raa_dmpvr2_2rail'
+    Prefix: 'isl68220'
 
     Addresses scanned: -
 
@@ -26,7 +26,7 @@ Supported chips:
 
   * Renesas ISL68221
 
-    Prefix: 'raa_dmpvr2_3rail'
+    Prefix: 'isl68221'
 
     Addresses scanned: -
 
@@ -36,7 +36,7 @@ Supported chips:
 
   * Renesas ISL68222
 
-    Prefix: 'raa_dmpvr2_2rail'
+    Prefix: 'isl68222'
 
     Addresses scanned: -
 
@@ -46,7 +46,7 @@ Supported chips:
 
   * Renesas ISL68223
 
-    Prefix: 'raa_dmpvr2_2rail'
+    Prefix: 'isl68223'
 
     Addresses scanned: -
 
@@ -56,7 +56,7 @@ Supported chips:
 
   * Renesas ISL68224
 
-    Prefix: 'raa_dmpvr2_3rail'
+    Prefix: 'isl68224'
 
     Addresses scanned: -
 
@@ -66,7 +66,7 @@ Supported chips:
 
   * Renesas ISL68225
 
-    Prefix: 'raa_dmpvr2_2rail'
+    Prefix: 'isl68225'
 
     Addresses scanned: -
 
@@ -76,7 +76,7 @@ Supported chips:
 
   * Renesas ISL68226
 
-    Prefix: 'raa_dmpvr2_3rail'
+    Prefix: 'isl68226'
 
     Addresses scanned: -
 
@@ -86,7 +86,7 @@ Supported chips:
 
   * Renesas ISL68227
 
-    Prefix: 'raa_dmpvr2_1rail'
+    Prefix: 'isl68227'
 
     Addresses scanned: -
 
@@ -96,7 +96,7 @@ Supported chips:
 
   * Renesas ISL68229
 
-    Prefix: 'raa_dmpvr2_3rail'
+    Prefix: 'isl68229'
 
     Addresses scanned: -
 
@@ -106,7 +106,7 @@ Supported chips:
 
   * Renesas ISL68233
 
-    Prefix: 'raa_dmpvr2_2rail'
+    Prefix: 'isl68233'
 
     Addresses scanned: -
 
@@ -116,7 +116,7 @@ Supported chips:
 
   * Renesas ISL68239
 
-    Prefix: 'raa_dmpvr2_3rail'
+    Prefix: 'isl68239'
 
     Addresses scanned: -
 
@@ -126,7 +126,7 @@ Supported chips:
 
   * Renesas ISL69222
 
-    Prefix: 'raa_dmpvr2_2rail'
+    Prefix: 'isl69222'
 
     Addresses scanned: -
 
@@ -136,7 +136,7 @@ Supported chips:
 
   * Renesas ISL69223
 
-    Prefix: 'raa_dmpvr2_3rail'
+    Prefix: 'isl69223'
 
     Addresses scanned: -
 
@@ -146,7 +146,7 @@ Supported chips:
 
   * Renesas ISL69224
 
-    Prefix: 'raa_dmpvr2_2rail'
+    Prefix: 'isl69224'
 
     Addresses scanned: -
 
@@ -156,7 +156,7 @@ Supported chips:
 
   * Renesas ISL69225
 
-    Prefix: 'raa_dmpvr2_2rail'
+    Prefix: 'isl69225'
 
     Addresses scanned: -
 
@@ -166,7 +166,7 @@ Supported chips:
 
   * Renesas ISL69227
 
-    Prefix: 'raa_dmpvr2_3rail'
+    Prefix: 'isl69227'
 
     Addresses scanned: -
 
@@ -176,7 +176,7 @@ Supported chips:
 
   * Renesas ISL69228
 
-    Prefix: 'raa_dmpvr2_3rail'
+    Prefix: 'isl69228'
 
     Addresses scanned: -
 
@@ -186,7 +186,7 @@ Supported chips:
 
   * Renesas ISL69234
 
-    Prefix: 'raa_dmpvr2_2rail'
+    Prefix: 'isl69234'
 
     Addresses scanned: -
 
@@ -196,7 +196,7 @@ Supported chips:
 
   * Renesas ISL69236
 
-    Prefix: 'raa_dmpvr2_2rail'
+    Prefix: 'isl69236'
 
     Addresses scanned: -
 
@@ -206,7 +206,7 @@ Supported chips:
 
   * Renesas ISL69239
 
-    Prefix: 'raa_dmpvr2_3rail'
+    Prefix: 'isl69239'
 
     Addresses scanned: -
 
@@ -216,7 +216,7 @@ Supported chips:
 
   * Renesas ISL69242
 
-    Prefix: 'raa_dmpvr2_2rail'
+    Prefix: 'isl69242'
 
     Addresses scanned: -
 
@@ -226,7 +226,7 @@ Supported chips:
 
   * Renesas ISL69243
 
-    Prefix: 'raa_dmpvr2_1rail'
+    Prefix: 'isl69243'
 
     Addresses scanned: -
 
@@ -236,7 +236,7 @@ Supported chips:
 
   * Renesas ISL69247
 
-    Prefix: 'raa_dmpvr2_2rail'
+    Prefix: 'isl69247'
 
     Addresses scanned: -
 
@@ -246,7 +246,7 @@ Supported chips:
 
   * Renesas ISL69248
 
-    Prefix: 'raa_dmpvr2_2rail'
+    Prefix: 'isl69248'
 
     Addresses scanned: -
 
@@ -256,7 +256,7 @@ Supported chips:
 
   * Renesas ISL69254
 
-    Prefix: 'raa_dmpvr2_2rail'
+    Prefix: 'isl69254'
 
     Addresses scanned: -
 
@@ -266,7 +266,7 @@ Supported chips:
 
   * Renesas ISL69255
 
-    Prefix: 'raa_dmpvr2_2rail'
+    Prefix: 'isl69255'
 
     Addresses scanned: -
 
@@ -276,7 +276,7 @@ Supported chips:
 
   * Renesas ISL69256
 
-    Prefix: 'raa_dmpvr2_2rail'
+    Prefix: 'isl69256'
 
     Addresses scanned: -
 
@@ -286,7 +286,7 @@ Supported chips:
 
   * Renesas ISL69259
 
-    Prefix: 'raa_dmpvr2_2rail'
+    Prefix: 'isl69259'
 
     Addresses scanned: -
 
@@ -296,7 +296,7 @@ Supported chips:
 
   * Renesas ISL69260
 
-    Prefix: 'raa_dmpvr2_2rail'
+    Prefix: 'isl69260'
 
     Addresses scanned: -
 
@@ -306,7 +306,7 @@ Supported chips:
 
   * Renesas ISL69268
 
-    Prefix: 'raa_dmpvr2_2rail'
+    Prefix: 'isl69268'
 
     Addresses scanned: -
 
@@ -316,7 +316,7 @@ Supported chips:
 
   * Renesas ISL69269
 
-    Prefix: 'raa_dmpvr2_3rail'
+    Prefix: 'isl69269'
 
     Addresses scanned: -
 
@@ -326,7 +326,7 @@ Supported chips:
 
   * Renesas ISL69298
 
-    Prefix: 'raa_dmpvr2_2rail'
+    Prefix: 'isl69298'
 
     Addresses scanned: -
 
@@ -336,7 +336,7 @@ Supported chips:
 
   * Renesas RAA228000
 
-    Prefix: 'raa_dmpvr2_hv'
+    Prefix: 'raa228000'
 
     Addresses scanned: -
 
@@ -346,7 +346,7 @@ Supported chips:
 
   * Renesas RAA228004
 
-    Prefix: 'raa_dmpvr2_hv'
+    Prefix: 'raa228004'
 
     Addresses scanned: -
 
@@ -356,7 +356,7 @@ Supported chips:
 
   * Renesas RAA228006
 
-    Prefix: 'raa_dmpvr2_hv'
+    Prefix: 'raa228006'
 
     Addresses scanned: -
 
@@ -366,7 +366,7 @@ Supported chips:
 
   * Renesas RAA228228
 
-    Prefix: 'raa_dmpvr2_2rail'
+    Prefix: 'raa228228'
 
     Addresses scanned: -
 
@@ -376,7 +376,7 @@ Supported chips:
 
   * Renesas RAA229001
 
-    Prefix: 'raa_dmpvr2_2rail'
+    Prefix: 'raa229001'
 
     Addresses scanned: -
 
@@ -386,7 +386,7 @@ Supported chips:
 
   * Renesas RAA229004
 
-    Prefix: 'raa_dmpvr2_2rail'
+    Prefix: 'raa229004'
 
     Addresses scanned: -
 
diff --git a/Documentation/index.rst b/Documentation/index.rst
index 9599c0f3eea8..af2b87afebc8 100644
--- a/Documentation/index.rst
+++ b/Documentation/index.rst
@@ -109,7 +109,6 @@ needed).
    isdn/index
    infiniband/index
    leds/index
-   media/index
    netlabel/index
    networking/index
    pcmcia/index
diff --git a/Documentation/litmus-tests/README b/Documentation/litmus-tests/README
new file mode 100644
index 000000000000..79d187f75679
--- /dev/null
+++ b/Documentation/litmus-tests/README
@@ -0,0 +1,14 @@
+============
+LITMUS TESTS
+============
+
+RCU (/rcu directory)
+--------------------
+MP+onceassign+derefonce.litmus
+    Demonstrates that rcu_assign_pointer() and rcu_dereference() to
+    ensure that an RCU reader will not see pre-initialization garbage.
+
+RCU+sync+read.litmus
+RCU+sync+free.litmus
+    Both the above litmus tests demonstrate the RCU grace period guarantee
+    that an RCU read-side critical section can never span a grace period.
diff --git a/Documentation/litmus-tests/atomic/Atomic-RMW+mb__after_atomic-is-stronger-than-acquire.litmus b/Documentation/litmus-tests/atomic/Atomic-RMW+mb__after_atomic-is-stronger-than-acquire.litmus
new file mode 100644
index 000000000000..9a8e31a44b28
--- /dev/null
+++ b/Documentation/litmus-tests/atomic/Atomic-RMW+mb__after_atomic-is-stronger-than-acquire.litmus
@@ -0,0 +1,32 @@
+C Atomic-RMW+mb__after_atomic-is-stronger-than-acquire
+
+(*
+ * Result: Never
+ *
+ * Test that an atomic RMW followed by a smp_mb__after_atomic() is
+ * stronger than a normal acquire: both the read and write parts of
+ * the RMW are ordered before the subsequential memory accesses.
+ *)
+
+{
+}
+
+P0(int *x, atomic_t *y)
+{
+	int r0;
+	int r1;
+
+	r0 = READ_ONCE(*x);
+	smp_rmb();
+	r1 = atomic_read(y);
+}
+
+P1(int *x, atomic_t *y)
+{
+	atomic_inc(y);
+	smp_mb__after_atomic();
+	WRITE_ONCE(*x, 1);
+}
+
+exists
+(0:r0=1 /\ 0:r1=0)
diff --git a/Documentation/litmus-tests/atomic/Atomic-RMW-ops-are-atomic-WRT-atomic_set.litmus b/Documentation/litmus-tests/atomic/Atomic-RMW-ops-are-atomic-WRT-atomic_set.litmus
new file mode 100644
index 000000000000..49385314d911
--- /dev/null
+++ b/Documentation/litmus-tests/atomic/Atomic-RMW-ops-are-atomic-WRT-atomic_set.litmus
@@ -0,0 +1,24 @@
+C Atomic-RMW-ops-are-atomic-WRT-atomic_set
+
+(*
+ * Result: Never
+ *
+ * Test that atomic_set() cannot break the atomicity of atomic RMWs.
+ *)
+
+{
+	atomic_t v = ATOMIC_INIT(1);
+}
+
+P0(atomic_t *v)
+{
+	(void)atomic_add_unless(v, 1, 0);
+}
+
+P1(atomic_t *v)
+{
+	atomic_set(v, 0);
+}
+
+exists
+(v=2)
diff --git a/Documentation/litmus-tests/atomic/README b/Documentation/litmus-tests/atomic/README
new file mode 100644
index 000000000000..714cf93816ea
--- /dev/null
+++ b/Documentation/litmus-tests/atomic/README
@@ -0,0 +1,16 @@
+This directory contains litmus tests that are typical to describe the semantics
+of our atomic APIs. For more information about how to "run" a litmus test or
+how to generate a kernel test module based on a litmus test, please see
+tools/memory-model/README.
+
+============
+LITMUS TESTS
+============
+
+Atomic-RMW+mb__after_atomic-is-stronger-than-acquire
+	Test that an atomic RMW followed by a smp_mb__after_atomic() is
+	stronger than a normal acquire: both the read and write parts of
+	the RMW are ordered before the subsequential memory accesses.
+
+Atomic-RMW-ops-are-atomic-WRT-atomic_set.litmus
+	Test that atomic_set() cannot break the atomicity of atomic RMWs.
diff --git a/Documentation/litmus-tests/rcu/MP+onceassign+derefonce.litmus b/Documentation/litmus-tests/rcu/MP+onceassign+derefonce.litmus
new file mode 100644
index 000000000000..97731b4bbdd8
--- /dev/null
+++ b/Documentation/litmus-tests/rcu/MP+onceassign+derefonce.litmus
@@ -0,0 +1,34 @@
+C MP+onceassign+derefonce
+
+(*
+ * Result: Never
+ *
+ * This litmus test demonstrates that rcu_assign_pointer() and
+ * rcu_dereference() suffice to ensure that an RCU reader will not see
+ * pre-initialization garbage when it traverses an RCU-protected data
+ * structure containing a newly inserted element.
+ *)
+
+{
+y=z;
+z=0;
+}
+
+P0(int *x, int **y)
+{
+	WRITE_ONCE(*x, 1);
+	rcu_assign_pointer(*y, x);
+}
+
+P1(int *x, int **y)
+{
+	int *r0;
+	int r1;
+
+	rcu_read_lock();
+	r0 = rcu_dereference(*y);
+	r1 = READ_ONCE(*r0);
+	rcu_read_unlock();
+}
+
+exists (1:r0=x /\ 1:r1=0)
diff --git a/Documentation/litmus-tests/rcu/RCU+sync+free.litmus b/Documentation/litmus-tests/rcu/RCU+sync+free.litmus
new file mode 100644
index 000000000000..4ee67e12f513
--- /dev/null
+++ b/Documentation/litmus-tests/rcu/RCU+sync+free.litmus
@@ -0,0 +1,42 @@
+C RCU+sync+free
+
+(*
+ * Result: Never
+ *
+ * This litmus test demonstrates that an RCU reader can never see a write that
+ * follows a grace period, if it did not see writes that precede that grace
+ * period.
+ *
+ * This is a typical pattern of RCU usage, where the write before the grace
+ * period assigns a pointer, and the writes following the grace period destroy
+ * the object that the pointer used to point to.
+ *
+ * This is one implication of the RCU grace-period guarantee, which says (among
+ * other things) that an RCU read-side critical section cannot span a grace period.
+ *)
+
+{
+int x = 1;
+int *y = &x;
+int z = 1;
+}
+
+P0(int *x, int *z, int **y)
+{
+	int *r0;
+	int r1;
+
+	rcu_read_lock();
+	r0 = rcu_dereference(*y);
+	r1 = READ_ONCE(*r0);
+	rcu_read_unlock();
+}
+
+P1(int *x, int *z, int **y)
+{
+	rcu_assign_pointer(*y, z);
+	synchronize_rcu();
+	WRITE_ONCE(*x, 0);
+}
+
+exists (0:r0=x /\ 0:r1=0)
diff --git a/Documentation/litmus-tests/rcu/RCU+sync+read.litmus b/Documentation/litmus-tests/rcu/RCU+sync+read.litmus
new file mode 100644
index 000000000000..f34176720231
--- /dev/null
+++ b/Documentation/litmus-tests/rcu/RCU+sync+read.litmus
@@ -0,0 +1,37 @@
+C RCU+sync+read
+
+(*
+ * Result: Never
+ *
+ * This litmus test demonstrates that after a grace period, an RCU updater always
+ * sees all stores done in prior RCU read-side critical sections. Such
+ * read-side critical sections would have ended before the grace period ended.
+ *
+ * This is one implication of the RCU grace-period guarantee, which says (among
+ * other things) that an RCU read-side critical section cannot span a grace period.
+ *)
+
+{
+int x = 0;
+int y = 0;
+}
+
+P0(int *x, int *y)
+{
+	rcu_read_lock();
+	WRITE_ONCE(*x, 1);
+	WRITE_ONCE(*y, 1);
+	rcu_read_unlock();
+}
+
+P1(int *x, int *y)
+{
+	int r0;
+	int r1;
+
+	r0 = READ_ONCE(*x);
+	synchronize_rcu();
+	r1 = READ_ONCE(*y);
+}
+
+exists (1:r0=1 /\ 1:r1=0)
diff --git a/Documentation/media/.gitignore b/Documentation/media/.gitignore
deleted file mode 100644
index 53adc029061f..000000000000
--- a/Documentation/media/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-*.pdf
-# Files generated from *.dot
-uapi/v4l/pipeline.svg
diff --git a/Documentation/media/Makefile b/Documentation/media/Makefile
deleted file mode 100644
index d75d70f191bc..000000000000
--- a/Documentation/media/Makefile
+++ /dev/null
@@ -1,69 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-# Rules to convert a .h file to inline RST documentation
-
-SRC_DIR=$(srctree)/Documentation/media
-PARSER = $(srctree)/Documentation/sphinx/parse-headers.pl
-UAPI = $(srctree)/include/uapi/linux
-KAPI = $(srctree)/include/linux
-
-FILES = audio.h.rst ca.h.rst dmx.h.rst frontend.h.rst net.h.rst video.h.rst \
-	  videodev2.h.rst media.h.rst cec.h.rst lirc.h.rst
-
-TARGETS := $(addprefix $(BUILDDIR)/, $(FILES))
-
-gen_rst = \
-	echo ${PARSER} $< $@ $(SRC_DIR)/$(notdir $@).exceptions; \
-	${PARSER} $< $@ $(SRC_DIR)/$(notdir $@).exceptions
-
-quiet_gen_rst = echo '  PARSE   $(patsubst $(srctree)/%,%,$<)'; \
-	${PARSER} $< $@ $(SRC_DIR)/$(notdir $@).exceptions
-
-silent_gen_rst = ${gen_rst}
-
-$(BUILDDIR)/audio.h.rst: ${UAPI}/dvb/audio.h ${PARSER} $(SRC_DIR)/audio.h.rst.exceptions
-	@$($(quiet)gen_rst)
-
-$(BUILDDIR)/ca.h.rst: ${UAPI}/dvb/ca.h ${PARSER} $(SRC_DIR)/ca.h.rst.exceptions
-	@$($(quiet)gen_rst)
-
-$(BUILDDIR)/dmx.h.rst: ${UAPI}/dvb/dmx.h ${PARSER} $(SRC_DIR)/dmx.h.rst.exceptions
-	@$($(quiet)gen_rst)
-
-$(BUILDDIR)/frontend.h.rst: ${UAPI}/dvb/frontend.h ${PARSER} $(SRC_DIR)/frontend.h.rst.exceptions
-	@$($(quiet)gen_rst)
-
-$(BUILDDIR)/net.h.rst: ${UAPI}/dvb/net.h ${PARSER} $(SRC_DIR)/net.h.rst.exceptions
-	@$($(quiet)gen_rst)
-
-$(BUILDDIR)/video.h.rst: ${UAPI}/dvb/video.h ${PARSER} $(SRC_DIR)/video.h.rst.exceptions
-	@$($(quiet)gen_rst)
-
-$(BUILDDIR)/videodev2.h.rst: ${UAPI}/videodev2.h ${PARSER} $(SRC_DIR)/videodev2.h.rst.exceptions
-	@$($(quiet)gen_rst)
-
-$(BUILDDIR)/media.h.rst: ${UAPI}/media.h ${PARSER} $(SRC_DIR)/media.h.rst.exceptions
-	@$($(quiet)gen_rst)
-
-$(BUILDDIR)/cec.h.rst: ${UAPI}/cec.h ${PARSER} $(SRC_DIR)/cec.h.rst.exceptions
-	@$($(quiet)gen_rst)
-
-$(BUILDDIR)/lirc.h.rst: ${UAPI}/lirc.h ${PARSER} $(SRC_DIR)/lirc.h.rst.exceptions
-	@$($(quiet)gen_rst)
-
-# Media build rules
-
-.PHONY: all html epub xml latex
-
-all: $(IMGDOT) $(BUILDDIR) ${TARGETS}
-html: all
-epub: all
-xml: all
-latex: $(IMGPDF) all
-linkcheck:
-
-clean:
-	-rm -f $(DOTTGT) $(IMGTGT) ${TARGETS} 2>/dev/null
-
-$(BUILDDIR):
-	$(Q)mkdir -p $@
diff --git a/Documentation/media/audio.h.rst.exceptions b/Documentation/media/audio.h.rst.exceptions
deleted file mode 100644
index cf6620477f73..000000000000
--- a/Documentation/media/audio.h.rst.exceptions
+++ /dev/null
@@ -1,19 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-# Ignore header name
-ignore define _DVBAUDIO_H_
-
-# Undocumented audio caps, as this is a deprecated API anyway
-ignore define AUDIO_CAP_DTS
-ignore define AUDIO_CAP_LPCM
-ignore define AUDIO_CAP_MP1
-ignore define AUDIO_CAP_MP2
-ignore define AUDIO_CAP_MP3
-ignore define AUDIO_CAP_AAC
-ignore define AUDIO_CAP_OGG
-ignore define AUDIO_CAP_SDDS
-ignore define AUDIO_CAP_AC3
-
-# some typedefs should point to struct/enums
-replace typedef audio_mixer_t :c:type:`audio_mixer`
-replace typedef audio_status_t :c:type:`audio_status`
diff --git a/Documentation/media/ca.h.rst.exceptions b/Documentation/media/ca.h.rst.exceptions
deleted file mode 100644
index f6828238eb48..000000000000
--- a/Documentation/media/ca.h.rst.exceptions
+++ /dev/null
@@ -1,25 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-# Ignore header name
-ignore define _DVBCA_H_
-
-# struct ca_slot_info defines
-replace define CA_CI :c:type:`ca_slot_info`
-replace define CA_CI_LINK :c:type:`ca_slot_info`
-replace define CA_CI_PHYS :c:type:`ca_slot_info`
-replace define CA_DESCR :c:type:`ca_slot_info`
-replace define CA_SC :c:type:`ca_slot_info`
-replace define CA_CI_MODULE_PRESENT :c:type:`ca_slot_info`
-replace define CA_CI_MODULE_READY :c:type:`ca_slot_info`
-
-# struct ca_descr_info defines
-replace define CA_ECD :c:type:`ca_descr_info`
-replace define CA_NDS :c:type:`ca_descr_info`
-replace define CA_DSS :c:type:`ca_descr_info`
-
-# some typedefs should point to struct/enums
-replace typedef ca_slot_info_t :c:type:`ca_slot_info`
-replace typedef ca_descr_info_t :c:type:`ca_descr_info`
-replace typedef ca_caps_t :c:type:`ca_caps`
-replace typedef ca_msg_t :c:type:`ca_msg`
-replace typedef ca_descr_t :c:type:`ca_descr`
diff --git a/Documentation/media/cec-drivers/index.rst b/Documentation/media/cec-drivers/index.rst
deleted file mode 100644
index 2b7fcaa4311b..000000000000
--- a/Documentation/media/cec-drivers/index.rst
+++ /dev/null
@@ -1,34 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-.. include:: <isonum.txt>
-
-.. _cec-drivers:
-
-#################################
-CEC driver-specific documentation
-#################################
-
-**Copyright** |copy| 2017 : LinuxTV Developers
-
-This documentation is free software; 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.
-
-For more details see the file COPYING in the source distribution of Linux.
-
-.. only:: html
-
-    .. class:: toc-title
-
-        Table of Contents
-
-.. toctree::
-	:maxdepth: 5
-	:numbered:
-
-	pulse8-cec
diff --git a/Documentation/media/cec-drivers/pulse8-cec.rst b/Documentation/media/cec-drivers/pulse8-cec.rst
deleted file mode 100644
index 356d08b519f3..000000000000
--- a/Documentation/media/cec-drivers/pulse8-cec.rst
+++ /dev/null
@@ -1,13 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-Pulse-Eight CEC Adapter driver
-==============================
-
-The pulse8-cec driver implements the following module option:
-
-``persistent_config``
----------------------
-
-By default this is off, but when set to 1 the driver will store the current
-settings to the device's internal eeprom and restore it the next time the
-device is connected to the USB port.
diff --git a/Documentation/media/cec.h.rst.exceptions b/Documentation/media/cec.h.rst.exceptions
deleted file mode 100644
index d83790ccac8e..000000000000
--- a/Documentation/media/cec.h.rst.exceptions
+++ /dev/null
@@ -1,575 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-# Ignore header name
-ignore define _CEC_UAPI_H
-
-# define macros to ignore
-
-ignore define CEC_MAX_MSG_SIZE
-ignore define CEC_MAX_LOG_ADDRS
-
-ignore define CEC_LOG_ADDR_MASK_TV
-ignore define CEC_LOG_ADDR_MASK_RECORD
-ignore define CEC_LOG_ADDR_MASK_TUNER
-ignore define CEC_LOG_ADDR_MASK_PLAYBACK
-ignore define CEC_LOG_ADDR_MASK_AUDIOSYSTEM
-ignore define CEC_LOG_ADDR_MASK_BACKUP
-ignore define CEC_LOG_ADDR_MASK_SPECIFIC
-ignore define CEC_LOG_ADDR_MASK_UNREGISTERED
-
-# Shouldn't them be documented?
-ignore define CEC_LOG_ADDR_INVALID
-ignore define CEC_PHYS_ADDR_INVALID
-
-ignore define CEC_VENDOR_ID_NONE
-
-ignore define CEC_MODE_INITIATOR_MSK
-ignore define CEC_MODE_FOLLOWER_MSK
-
-# Part of CEC 2.0 spec - shouldn't be documented too?
-ignore define CEC_LOG_ADDR_TV
-ignore define CEC_LOG_ADDR_RECORD_1
-ignore define CEC_LOG_ADDR_RECORD_2
-ignore define CEC_LOG_ADDR_TUNER_1
-ignore define CEC_LOG_ADDR_PLAYBACK_1
-ignore define CEC_LOG_ADDR_AUDIOSYSTEM
-ignore define CEC_LOG_ADDR_TUNER_2
-ignore define CEC_LOG_ADDR_TUNER_3
-ignore define CEC_LOG_ADDR_PLAYBACK_2
-ignore define CEC_LOG_ADDR_RECORD_3
-ignore define CEC_LOG_ADDR_TUNER_4
-ignore define CEC_LOG_ADDR_PLAYBACK_3
-ignore define CEC_LOG_ADDR_BACKUP_1
-ignore define CEC_LOG_ADDR_BACKUP_2
-ignore define CEC_LOG_ADDR_SPECIFIC
-ignore define CEC_LOG_ADDR_UNREGISTERED
-ignore define CEC_LOG_ADDR_BROADCAST
-
-# IMHO, those should also be documented
-
-ignore define CEC_MSG_ACTIVE_SOURCE
-ignore define CEC_MSG_IMAGE_VIEW_ON
-ignore define CEC_MSG_TEXT_VIEW_ON
-
-ignore define CEC_MSG_INACTIVE_SOURCE
-ignore define CEC_MSG_REQUEST_ACTIVE_SOURCE
-ignore define CEC_MSG_ROUTING_CHANGE
-ignore define CEC_MSG_ROUTING_INFORMATION
-ignore define CEC_MSG_SET_STREAM_PATH
-
-ignore define CEC_MSG_STANDBY
-
-ignore define CEC_MSG_RECORD_OFF
-ignore define CEC_MSG_RECORD_ON
-
-ignore define CEC_OP_RECORD_SRC_OWN
-ignore define CEC_OP_RECORD_SRC_DIGITAL
-ignore define CEC_OP_RECORD_SRC_ANALOG
-ignore define CEC_OP_RECORD_SRC_EXT_PLUG
-ignore define CEC_OP_RECORD_SRC_EXT_PHYS_ADDR
-
-ignore define CEC_OP_SERVICE_ID_METHOD_BY_DIG_ID
-ignore define CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL
-
-ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_GEN
-ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_GEN
-ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_GEN
-ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_BS
-ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_CS
-ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_T
-ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_CABLE
-ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_SAT
-ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_T
-ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_C
-ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_S
-ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_S2
-ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_T
-
-ignore define CEC_OP_ANA_BCAST_TYPE_CABLE
-ignore define CEC_OP_ANA_BCAST_TYPE_SATELLITE
-ignore define CEC_OP_ANA_BCAST_TYPE_TERRESTRIAL
-
-ignore define CEC_OP_BCAST_SYSTEM_PAL_BG
-ignore define CEC_OP_BCAST_SYSTEM_SECAM_LQ
-ignore define CEC_OP_BCAST_SYSTEM_PAL_M
-ignore define CEC_OP_BCAST_SYSTEM_NTSC_M
-ignore define CEC_OP_BCAST_SYSTEM_PAL_I
-ignore define CEC_OP_BCAST_SYSTEM_SECAM_DK
-ignore define CEC_OP_BCAST_SYSTEM_SECAM_BG
-ignore define CEC_OP_BCAST_SYSTEM_SECAM_L
-ignore define CEC_OP_BCAST_SYSTEM_PAL_DK
-ignore define CEC_OP_BCAST_SYSTEM_OTHER
-
-ignore define CEC_OP_CHANNEL_NUMBER_FMT_1_PART
-ignore define CEC_OP_CHANNEL_NUMBER_FMT_2_PART
-
-ignore define CEC_MSG_RECORD_STATUS
-
-ignore define CEC_OP_RECORD_STATUS_CUR_SRC
-ignore define CEC_OP_RECORD_STATUS_DIG_SERVICE
-ignore define CEC_OP_RECORD_STATUS_ANA_SERVICE
-ignore define CEC_OP_RECORD_STATUS_EXT_INPUT
-ignore define CEC_OP_RECORD_STATUS_NO_DIG_SERVICE
-ignore define CEC_OP_RECORD_STATUS_NO_ANA_SERVICE
-ignore define CEC_OP_RECORD_STATUS_NO_SERVICE
-ignore define CEC_OP_RECORD_STATUS_INVALID_EXT_PLUG
-ignore define CEC_OP_RECORD_STATUS_INVALID_EXT_PHYS_ADDR
-ignore define CEC_OP_RECORD_STATUS_UNSUP_CA
-ignore define CEC_OP_RECORD_STATUS_NO_CA_ENTITLEMENTS
-ignore define CEC_OP_RECORD_STATUS_CANT_COPY_SRC
-ignore define CEC_OP_RECORD_STATUS_NO_MORE_COPIES
-ignore define CEC_OP_RECORD_STATUS_NO_MEDIA
-ignore define CEC_OP_RECORD_STATUS_PLAYING
-ignore define CEC_OP_RECORD_STATUS_ALREADY_RECORDING
-ignore define CEC_OP_RECORD_STATUS_MEDIA_PROT
-ignore define CEC_OP_RECORD_STATUS_NO_SIGNAL
-ignore define CEC_OP_RECORD_STATUS_MEDIA_PROBLEM
-ignore define CEC_OP_RECORD_STATUS_NO_SPACE
-ignore define CEC_OP_RECORD_STATUS_PARENTAL_LOCK
-ignore define CEC_OP_RECORD_STATUS_TERMINATED_OK
-ignore define CEC_OP_RECORD_STATUS_ALREADY_TERM
-ignore define CEC_OP_RECORD_STATUS_OTHER
-
-ignore define CEC_MSG_RECORD_TV_SCREEN
-
-ignore define CEC_MSG_CLEAR_ANALOGUE_TIMER
-
-ignore define CEC_OP_REC_SEQ_SUNDAY
-ignore define CEC_OP_REC_SEQ_MONDAY
-ignore define CEC_OP_REC_SEQ_TUESDAY
-ignore define CEC_OP_REC_SEQ_WEDNESDAY
-ignore define CEC_OP_REC_SEQ_THURSDAY
-ignore define CEC_OP_REC_SEQ_FRIDAY
-ignore define CEC_OP_REC_SEQ_SATERDAY
-ignore define CEC_OP_REC_SEQ_ONCE_ONLY
-
-ignore define CEC_MSG_CLEAR_DIGITAL_TIMER
-
-ignore define CEC_MSG_CLEAR_EXT_TIMER
-
-ignore define CEC_OP_EXT_SRC_PLUG
-ignore define CEC_OP_EXT_SRC_PHYS_ADDR
-
-ignore define CEC_MSG_SET_ANALOGUE_TIMER
-ignore define CEC_MSG_SET_DIGITAL_TIMER
-ignore define CEC_MSG_SET_EXT_TIMER
-
-ignore define CEC_MSG_SET_TIMER_PROGRAM_TITLE
-ignore define CEC_MSG_TIMER_CLEARED_STATUS
-
-ignore define CEC_OP_TIMER_CLR_STAT_RECORDING
-ignore define CEC_OP_TIMER_CLR_STAT_NO_MATCHING
-ignore define CEC_OP_TIMER_CLR_STAT_NO_INFO
-ignore define CEC_OP_TIMER_CLR_STAT_CLEARED
-
-ignore define CEC_MSG_TIMER_STATUS
-
-ignore define CEC_OP_TIMER_OVERLAP_WARNING_NO_OVERLAP
-ignore define CEC_OP_TIMER_OVERLAP_WARNING_OVERLAP
-
-ignore define CEC_OP_MEDIA_INFO_UNPROT_MEDIA
-ignore define CEC_OP_MEDIA_INFO_PROT_MEDIA
-ignore define CEC_OP_MEDIA_INFO_NO_MEDIA
-
-ignore define CEC_OP_PROG_IND_NOT_PROGRAMMED
-ignore define CEC_OP_PROG_IND_PROGRAMMED
-
-ignore define CEC_OP_PROG_INFO_ENOUGH_SPACE
-ignore define CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE
-ignore define CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE
-ignore define CEC_OP_PROG_INFO_NONE_AVAILABLE
-
-ignore define CEC_OP_PROG_ERROR_NO_FREE_TIMER
-ignore define CEC_OP_PROG_ERROR_DATE_OUT_OF_RANGE
-ignore define CEC_OP_PROG_ERROR_REC_SEQ_ERROR
-ignore define CEC_OP_PROG_ERROR_INV_EXT_PLUG
-ignore define CEC_OP_PROG_ERROR_INV_EXT_PHYS_ADDR
-ignore define CEC_OP_PROG_ERROR_CA_UNSUPP
-ignore define CEC_OP_PROG_ERROR_INSUF_CA_ENTITLEMENTS
-ignore define CEC_OP_PROG_ERROR_RESOLUTION_UNSUPP
-ignore define CEC_OP_PROG_ERROR_PARENTAL_LOCK
-ignore define CEC_OP_PROG_ERROR_CLOCK_FAILURE
-ignore define CEC_OP_PROG_ERROR_DUPLICATE
-
-ignore define CEC_MSG_CEC_VERSION
-
-ignore define CEC_OP_CEC_VERSION_1_3A
-ignore define CEC_OP_CEC_VERSION_1_4
-ignore define CEC_OP_CEC_VERSION_2_0
-
-ignore define CEC_MSG_GET_CEC_VERSION
-ignore define CEC_MSG_GIVE_PHYSICAL_ADDR
-ignore define CEC_MSG_GET_MENU_LANGUAGE
-ignore define CEC_MSG_REPORT_PHYSICAL_ADDR
-
-ignore define CEC_OP_PRIM_DEVTYPE_TV
-ignore define CEC_OP_PRIM_DEVTYPE_RECORD
-ignore define CEC_OP_PRIM_DEVTYPE_TUNER
-ignore define CEC_OP_PRIM_DEVTYPE_PLAYBACK
-ignore define CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM
-ignore define CEC_OP_PRIM_DEVTYPE_SWITCH
-ignore define CEC_OP_PRIM_DEVTYPE_PROCESSOR
-
-ignore define CEC_MSG_SET_MENU_LANGUAGE
-ignore define CEC_MSG_REPORT_FEATURES
-
-ignore define CEC_OP_ALL_DEVTYPE_TV
-ignore define CEC_OP_ALL_DEVTYPE_RECORD
-ignore define CEC_OP_ALL_DEVTYPE_TUNER
-ignore define CEC_OP_ALL_DEVTYPE_PLAYBACK
-ignore define CEC_OP_ALL_DEVTYPE_AUDIOSYSTEM
-ignore define CEC_OP_ALL_DEVTYPE_SWITCH
-
-ignore define CEC_OP_FEAT_EXT
-
-ignore define CEC_OP_FEAT_RC_TV_PROFILE_NONE
-ignore define CEC_OP_FEAT_RC_TV_PROFILE_1
-ignore define CEC_OP_FEAT_RC_TV_PROFILE_2
-ignore define CEC_OP_FEAT_RC_TV_PROFILE_3
-ignore define CEC_OP_FEAT_RC_TV_PROFILE_4
-ignore define CEC_OP_FEAT_RC_SRC_HAS_DEV_ROOT_MENU
-ignore define CEC_OP_FEAT_RC_SRC_HAS_DEV_SETUP_MENU
-ignore define CEC_OP_FEAT_RC_SRC_HAS_CONTENTS_MENU
-ignore define CEC_OP_FEAT_RC_SRC_HAS_MEDIA_TOP_MENU
-ignore define CEC_OP_FEAT_RC_SRC_HAS_MEDIA_CONTEXT_MENU
-
-ignore define CEC_OP_FEAT_DEV_HAS_RECORD_TV_SCREEN
-ignore define CEC_OP_FEAT_DEV_HAS_SET_OSD_STRING
-ignore define CEC_OP_FEAT_DEV_HAS_DECK_CONTROL
-ignore define CEC_OP_FEAT_DEV_HAS_SET_AUDIO_RATE
-ignore define CEC_OP_FEAT_DEV_SINK_HAS_ARC_TX
-ignore define CEC_OP_FEAT_DEV_SOURCE_HAS_ARC_RX
-
-ignore define CEC_MSG_GIVE_FEATURES
-
-ignore define CEC_MSG_DECK_CONTROL
-
-ignore define CEC_OP_DECK_CTL_MODE_SKIP_FWD
-ignore define CEC_OP_DECK_CTL_MODE_SKIP_REV
-ignore define CEC_OP_DECK_CTL_MODE_STOP
-ignore define CEC_OP_DECK_CTL_MODE_EJECT
-
-ignore define CEC_MSG_DECK_STATUS
-
-ignore define CEC_OP_DECK_INFO_PLAY
-ignore define CEC_OP_DECK_INFO_RECORD
-ignore define CEC_OP_DECK_INFO_PLAY_REV
-ignore define CEC_OP_DECK_INFO_STILL
-ignore define CEC_OP_DECK_INFO_SLOW
-ignore define CEC_OP_DECK_INFO_SLOW_REV
-ignore define CEC_OP_DECK_INFO_FAST_FWD
-ignore define CEC_OP_DECK_INFO_FAST_REV
-ignore define CEC_OP_DECK_INFO_NO_MEDIA
-ignore define CEC_OP_DECK_INFO_STOP
-ignore define CEC_OP_DECK_INFO_SKIP_FWD
-ignore define CEC_OP_DECK_INFO_SKIP_REV
-ignore define CEC_OP_DECK_INFO_INDEX_SEARCH_FWD
-ignore define CEC_OP_DECK_INFO_INDEX_SEARCH_REV
-ignore define CEC_OP_DECK_INFO_OTHER
-
-ignore define CEC_MSG_GIVE_DECK_STATUS
-
-ignore define CEC_OP_STATUS_REQ_ON
-ignore define CEC_OP_STATUS_REQ_OFF
-ignore define CEC_OP_STATUS_REQ_ONCE
-
-ignore define CEC_MSG_PLAY
-
-ignore define CEC_OP_PLAY_MODE_PLAY_FWD
-ignore define CEC_OP_PLAY_MODE_PLAY_REV
-ignore define CEC_OP_PLAY_MODE_PLAY_STILL
-ignore define CEC_OP_PLAY_MODE_PLAY_FAST_FWD_MIN
-ignore define CEC_OP_PLAY_MODE_PLAY_FAST_FWD_MED
-ignore define CEC_OP_PLAY_MODE_PLAY_FAST_FWD_MAX
-ignore define CEC_OP_PLAY_MODE_PLAY_FAST_REV_MIN
-ignore define CEC_OP_PLAY_MODE_PLAY_FAST_REV_MED
-ignore define CEC_OP_PLAY_MODE_PLAY_FAST_REV_MAX
-ignore define CEC_OP_PLAY_MODE_PLAY_SLOW_FWD_MIN
-ignore define CEC_OP_PLAY_MODE_PLAY_SLOW_FWD_MED
-ignore define CEC_OP_PLAY_MODE_PLAY_SLOW_FWD_MAX
-ignore define CEC_OP_PLAY_MODE_PLAY_SLOW_REV_MIN
-ignore define CEC_OP_PLAY_MODE_PLAY_SLOW_REV_MED
-ignore define CEC_OP_PLAY_MODE_PLAY_SLOW_REV_MAX
-
-ignore define CEC_MSG_GIVE_TUNER_DEVICE_STATUS
-ignore define CEC_MSG_SELECT_ANALOGUE_SERVICE
-ignore define CEC_MSG_SELECT_DIGITAL_SERVICE
-ignore define CEC_MSG_TUNER_DEVICE_STATUS
-
-ignore define CEC_OP_REC_FLAG_USED
-ignore define CEC_OP_REC_FLAG_NOT_USED
-
-ignore define CEC_OP_TUNER_DISPLAY_INFO_DIGITAL
-ignore define CEC_OP_TUNER_DISPLAY_INFO_NONE
-ignore define CEC_OP_TUNER_DISPLAY_INFO_ANALOGUE
-
-ignore define CEC_MSG_TUNER_STEP_DECREMENT
-ignore define CEC_MSG_TUNER_STEP_INCREMENT
-
-ignore define CEC_MSG_DEVICE_VENDOR_ID
-ignore define CEC_MSG_GIVE_DEVICE_VENDOR_ID
-ignore define CEC_MSG_VENDOR_COMMAND
-ignore define CEC_MSG_VENDOR_COMMAND_WITH_ID
-ignore define CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN
-ignore define CEC_MSG_VENDOR_REMOTE_BUTTON_UP
-
-ignore define CEC_MSG_SET_OSD_STRING
-
-ignore define CEC_OP_DISP_CTL_DEFAULT
-ignore define CEC_OP_DISP_CTL_UNTIL_CLEARED
-ignore define CEC_OP_DISP_CTL_CLEAR
-
-ignore define CEC_MSG_GIVE_OSD_NAME
-ignore define CEC_MSG_SET_OSD_NAME
-
-ignore define CEC_MSG_MENU_REQUEST
-
-ignore define CEC_OP_MENU_REQUEST_ACTIVATE
-ignore define CEC_OP_MENU_REQUEST_DEACTIVATE
-ignore define CEC_OP_MENU_REQUEST_QUERY
-
-ignore define CEC_MSG_MENU_STATUS
-
-ignore define CEC_OP_MENU_STATE_ACTIVATED
-ignore define CEC_OP_MENU_STATE_DEACTIVATED
-
-ignore define CEC_MSG_USER_CONTROL_PRESSED
-
-ignore define CEC_OP_UI_CMD_SELECT
-ignore define CEC_OP_UI_CMD_UP
-ignore define CEC_OP_UI_CMD_DOWN
-ignore define CEC_OP_UI_CMD_LEFT
-ignore define CEC_OP_UI_CMD_RIGHT
-ignore define CEC_OP_UI_CMD_RIGHT_UP
-ignore define CEC_OP_UI_CMD_RIGHT_DOWN
-ignore define CEC_OP_UI_CMD_LEFT_UP
-ignore define CEC_OP_UI_CMD_LEFT_DOWN
-ignore define CEC_OP_UI_CMD_DEVICE_ROOT_MENU
-ignore define CEC_OP_UI_CMD_DEVICE_SETUP_MENU
-ignore define CEC_OP_UI_CMD_CONTENTS_MENU
-ignore define CEC_OP_UI_CMD_FAVORITE_MENU
-ignore define CEC_OP_UI_CMD_BACK
-ignore define CEC_OP_UI_CMD_MEDIA_TOP_MENU
-ignore define CEC_OP_UI_CMD_MEDIA_CONTEXT_SENSITIVE_MENU
-ignore define CEC_OP_UI_CMD_NUMBER_ENTRY_MODE
-ignore define CEC_OP_UI_CMD_NUMBER_11
-ignore define CEC_OP_UI_CMD_NUMBER_12
-ignore define CEC_OP_UI_CMD_NUMBER_0_OR_NUMBER_10
-ignore define CEC_OP_UI_CMD_NUMBER_1
-ignore define CEC_OP_UI_CMD_NUMBER_2
-ignore define CEC_OP_UI_CMD_NUMBER_3
-ignore define CEC_OP_UI_CMD_NUMBER_4
-ignore define CEC_OP_UI_CMD_NUMBER_5
-ignore define CEC_OP_UI_CMD_NUMBER_6
-ignore define CEC_OP_UI_CMD_NUMBER_7
-ignore define CEC_OP_UI_CMD_NUMBER_8
-ignore define CEC_OP_UI_CMD_NUMBER_9
-ignore define CEC_OP_UI_CMD_DOT
-ignore define CEC_OP_UI_CMD_ENTER
-ignore define CEC_OP_UI_CMD_CLEAR
-ignore define CEC_OP_UI_CMD_NEXT_FAVORITE
-ignore define CEC_OP_UI_CMD_CHANNEL_UP
-ignore define CEC_OP_UI_CMD_CHANNEL_DOWN
-ignore define CEC_OP_UI_CMD_PREVIOUS_CHANNEL
-ignore define CEC_OP_UI_CMD_SOUND_SELECT
-ignore define CEC_OP_UI_CMD_INPUT_SELECT
-ignore define CEC_OP_UI_CMD_DISPLAY_INFORMATION
-ignore define CEC_OP_UI_CMD_HELP
-ignore define CEC_OP_UI_CMD_PAGE_UP
-ignore define CEC_OP_UI_CMD_PAGE_DOWN
-ignore define CEC_OP_UI_CMD_POWER
-ignore define CEC_OP_UI_CMD_VOLUME_UP
-ignore define CEC_OP_UI_CMD_VOLUME_DOWN
-ignore define CEC_OP_UI_CMD_MUTE
-ignore define CEC_OP_UI_CMD_PLAY
-ignore define CEC_OP_UI_CMD_STOP
-ignore define CEC_OP_UI_CMD_PAUSE
-ignore define CEC_OP_UI_CMD_RECORD
-ignore define CEC_OP_UI_CMD_REWIND
-ignore define CEC_OP_UI_CMD_FAST_FORWARD
-ignore define CEC_OP_UI_CMD_EJECT
-ignore define CEC_OP_UI_CMD_SKIP_FORWARD
-ignore define CEC_OP_UI_CMD_SKIP_BACKWARD
-ignore define CEC_OP_UI_CMD_STOP_RECORD
-ignore define CEC_OP_UI_CMD_PAUSE_RECORD
-ignore define CEC_OP_UI_CMD_ANGLE
-ignore define CEC_OP_UI_CMD_SUB_PICTURE
-ignore define CEC_OP_UI_CMD_VIDEO_ON_DEMAND
-ignore define CEC_OP_UI_CMD_ELECTRONIC_PROGRAM_GUIDE
-ignore define CEC_OP_UI_CMD_TIMER_PROGRAMMING
-ignore define CEC_OP_UI_CMD_INITIAL_CONFIGURATION
-ignore define CEC_OP_UI_CMD_SELECT_BROADCAST_TYPE
-ignore define CEC_OP_UI_CMD_SELECT_SOUND_PRESENTATION
-ignore define CEC_OP_UI_CMD_AUDIO_DESCRIPTION
-ignore define CEC_OP_UI_CMD_INTERNET
-ignore define CEC_OP_UI_CMD_3D_MODE
-ignore define CEC_OP_UI_CMD_PLAY_FUNCTION
-ignore define CEC_OP_UI_CMD_PAUSE_PLAY_FUNCTION
-ignore define CEC_OP_UI_CMD_RECORD_FUNCTION
-ignore define CEC_OP_UI_CMD_PAUSE_RECORD_FUNCTION
-ignore define CEC_OP_UI_CMD_STOP_FUNCTION
-ignore define CEC_OP_UI_CMD_MUTE_FUNCTION
-ignore define CEC_OP_UI_CMD_RESTORE_VOLUME_FUNCTION
-ignore define CEC_OP_UI_CMD_TUNE_FUNCTION
-ignore define CEC_OP_UI_CMD_SELECT_MEDIA_FUNCTION
-ignore define CEC_OP_UI_CMD_SELECT_AV_INPUT_FUNCTION
-ignore define CEC_OP_UI_CMD_SELECT_AUDIO_INPUT_FUNCTION
-ignore define CEC_OP_UI_CMD_POWER_TOGGLE_FUNCTION
-ignore define CEC_OP_UI_CMD_POWER_OFF_FUNCTION
-ignore define CEC_OP_UI_CMD_POWER_ON_FUNCTION
-ignore define CEC_OP_UI_CMD_F1_BLUE
-ignore define CEC_OP_UI_CMD_F2_RED
-ignore define CEC_OP_UI_CMD_F3_GREEN
-ignore define CEC_OP_UI_CMD_F4_YELLOW
-ignore define CEC_OP_UI_CMD_F5
-ignore define CEC_OP_UI_CMD_DATA
-
-ignore define CEC_OP_UI_BCAST_TYPE_TOGGLE_ALL
-ignore define CEC_OP_UI_BCAST_TYPE_TOGGLE_DIG_ANA
-ignore define CEC_OP_UI_BCAST_TYPE_ANALOGUE
-ignore define CEC_OP_UI_BCAST_TYPE_ANALOGUE_T
-ignore define CEC_OP_UI_BCAST_TYPE_ANALOGUE_CABLE
-ignore define CEC_OP_UI_BCAST_TYPE_ANALOGUE_SAT
-ignore define CEC_OP_UI_BCAST_TYPE_DIGITAL
-ignore define CEC_OP_UI_BCAST_TYPE_DIGITAL_T
-ignore define CEC_OP_UI_BCAST_TYPE_DIGITAL_CABLE
-ignore define CEC_OP_UI_BCAST_TYPE_DIGITAL_SAT
-ignore define CEC_OP_UI_BCAST_TYPE_DIGITAL_COM_SAT
-ignore define CEC_OP_UI_BCAST_TYPE_DIGITAL_COM_SAT2
-ignore define CEC_OP_UI_BCAST_TYPE_IP
-
-ignore define CEC_OP_UI_SND_PRES_CTL_DUAL_MONO
-ignore define CEC_OP_UI_SND_PRES_CTL_KARAOKE
-ignore define CEC_OP_UI_SND_PRES_CTL_DOWNMIX
-ignore define CEC_OP_UI_SND_PRES_CTL_REVERB
-ignore define CEC_OP_UI_SND_PRES_CTL_EQUALIZER
-ignore define CEC_OP_UI_SND_PRES_CTL_BASS_UP
-ignore define CEC_OP_UI_SND_PRES_CTL_BASS_NEUTRAL
-ignore define CEC_OP_UI_SND_PRES_CTL_BASS_DOWN
-ignore define CEC_OP_UI_SND_PRES_CTL_TREBLE_UP
-ignore define CEC_OP_UI_SND_PRES_CTL_TREBLE_NEUTRAL
-ignore define CEC_OP_UI_SND_PRES_CTL_TREBLE_DOWN
-
-ignore define CEC_MSG_USER_CONTROL_RELEASED
-
-ignore define CEC_MSG_GIVE_DEVICE_POWER_STATUS
-ignore define CEC_MSG_REPORT_POWER_STATUS
-
-ignore define CEC_OP_POWER_STATUS_ON
-ignore define CEC_OP_POWER_STATUS_STANDBY
-ignore define CEC_OP_POWER_STATUS_TO_ON
-ignore define CEC_OP_POWER_STATUS_TO_STANDBY
-
-ignore define CEC_MSG_FEATURE_ABORT
-
-ignore define CEC_OP_ABORT_UNRECOGNIZED_OP
-ignore define CEC_OP_ABORT_INCORRECT_MODE
-ignore define CEC_OP_ABORT_NO_SOURCE
-ignore define CEC_OP_ABORT_INVALID_OP
-ignore define CEC_OP_ABORT_REFUSED
-ignore define CEC_OP_ABORT_UNDETERMINED
-
-ignore define CEC_MSG_ABORT
-
-ignore define CEC_MSG_GIVE_AUDIO_STATUS
-ignore define CEC_MSG_GIVE_SYSTEM_AUDIO_MODE_STATUS
-ignore define CEC_MSG_REPORT_AUDIO_STATUS
-
-ignore define CEC_OP_AUD_MUTE_STATUS_OFF
-ignore define CEC_OP_AUD_MUTE_STATUS_ON
-
-ignore define CEC_MSG_REPORT_SHORT_AUDIO_DESCRIPTOR
-ignore define CEC_MSG_REQUEST_SHORT_AUDIO_DESCRIPTOR
-ignore define CEC_MSG_SET_SYSTEM_AUDIO_MODE
-
-ignore define CEC_OP_SYS_AUD_STATUS_OFF
-ignore define CEC_OP_SYS_AUD_STATUS_ON
-
-ignore define CEC_MSG_SYSTEM_AUDIO_MODE_REQUEST
-ignore define CEC_MSG_SYSTEM_AUDIO_MODE_STATUS
-
-ignore define CEC_OP_AUD_FMT_ID_CEA861
-ignore define CEC_OP_AUD_FMT_ID_CEA861_CXT
-
-ignore define CEC_MSG_SET_AUDIO_RATE
-
-ignore define CEC_OP_AUD_RATE_OFF
-ignore define CEC_OP_AUD_RATE_WIDE_STD
-ignore define CEC_OP_AUD_RATE_WIDE_FAST
-ignore define CEC_OP_AUD_RATE_WIDE_SLOW
-ignore define CEC_OP_AUD_RATE_NARROW_STD
-ignore define CEC_OP_AUD_RATE_NARROW_FAST
-ignore define CEC_OP_AUD_RATE_NARROW_SLOW
-
-ignore define CEC_MSG_INITIATE_ARC
-ignore define CEC_MSG_REPORT_ARC_INITIATED
-ignore define CEC_MSG_REPORT_ARC_TERMINATED
-ignore define CEC_MSG_REQUEST_ARC_INITIATION
-ignore define CEC_MSG_REQUEST_ARC_TERMINATION
-ignore define CEC_MSG_TERMINATE_ARC
-
-ignore define CEC_MSG_REQUEST_CURRENT_LATENCY
-ignore define CEC_MSG_REPORT_CURRENT_LATENCY
-
-ignore define CEC_OP_LOW_LATENCY_MODE_OFF
-ignore define CEC_OP_LOW_LATENCY_MODE_ON
-
-ignore define CEC_OP_AUD_OUT_COMPENSATED_NA
-ignore define CEC_OP_AUD_OUT_COMPENSATED_DELAY
-ignore define CEC_OP_AUD_OUT_COMPENSATED_NO_DELAY
-ignore define CEC_OP_AUD_OUT_COMPENSATED_PARTIAL_DELAY
-
-ignore define CEC_MSG_CDC_MESSAGE
-
-ignore define CEC_MSG_CDC_HEC_INQUIRE_STATE
-ignore define CEC_MSG_CDC_HEC_REPORT_STATE
-
-ignore define CEC_OP_HEC_FUNC_STATE_NOT_SUPPORTED
-ignore define CEC_OP_HEC_FUNC_STATE_INACTIVE
-ignore define CEC_OP_HEC_FUNC_STATE_ACTIVE
-ignore define CEC_OP_HEC_FUNC_STATE_ACTIVATION_FIELD
-
-ignore define CEC_OP_HOST_FUNC_STATE_NOT_SUPPORTED
-ignore define CEC_OP_HOST_FUNC_STATE_INACTIVE
-ignore define CEC_OP_HOST_FUNC_STATE_ACTIVE
-
-ignore define CEC_OP_ENC_FUNC_STATE_EXT_CON_NOT_SUPPORTED
-ignore define CEC_OP_ENC_FUNC_STATE_EXT_CON_INACTIVE
-ignore define CEC_OP_ENC_FUNC_STATE_EXT_CON_ACTIVE
-
-ignore define CEC_OP_CDC_ERROR_CODE_NONE
-ignore define CEC_OP_CDC_ERROR_CODE_CAP_UNSUPPORTED
-ignore define CEC_OP_CDC_ERROR_CODE_WRONG_STATE
-ignore define CEC_OP_CDC_ERROR_CODE_OTHER
-
-ignore define CEC_OP_HEC_SUPPORT_NO
-ignore define CEC_OP_HEC_SUPPORT_YES
-
-ignore define CEC_OP_HEC_ACTIVATION_ON
-ignore define CEC_OP_HEC_ACTIVATION_OFF
-
-ignore define CEC_MSG_CDC_HEC_SET_STATE_ADJACENT
-ignore define CEC_MSG_CDC_HEC_SET_STATE
-
-ignore define CEC_OP_HEC_SET_STATE_DEACTIVATE
-ignore define CEC_OP_HEC_SET_STATE_ACTIVATE
-
-ignore define CEC_MSG_CDC_HEC_REQUEST_DEACTIVATION
-ignore define CEC_MSG_CDC_HEC_NOTIFY_ALIVE
-ignore define CEC_MSG_CDC_HEC_DISCOVER
-
-ignore define CEC_MSG_CDC_HPD_SET_STATE
-
-ignore define CEC_OP_HPD_STATE_CP_EDID_DISABLE
-ignore define CEC_OP_HPD_STATE_CP_EDID_ENABLE
-ignore define CEC_OP_HPD_STATE_CP_EDID_DISABLE_ENABLE
-ignore define CEC_OP_HPD_STATE_EDID_DISABLE
-ignore define CEC_OP_HPD_STATE_EDID_ENABLE
-ignore define CEC_OP_HPD_STATE_EDID_DISABLE_ENABLE
-ignore define CEC_MSG_CDC_HPD_REPORT_STATE
-
-ignore define CEC_OP_HPD_ERROR_NONE
-ignore define CEC_OP_HPD_ERROR_INITIATOR_NOT_CAPABLE
-ignore define CEC_OP_HPD_ERROR_INITIATOR_WRONG_STATE
-ignore define CEC_OP_HPD_ERROR_OTHER
-ignore define CEC_OP_HPD_ERROR_NONE_NO_VIDEO
diff --git a/Documentation/media/conf_nitpick.py b/Documentation/media/conf_nitpick.py
deleted file mode 100644
index d0c50d75f518..000000000000
--- a/Documentation/media/conf_nitpick.py
+++ /dev/null
@@ -1,111 +0,0 @@
-# -*- coding: utf-8; mode: python -*-
-
-# SPDX-License-Identifier: GPL-2.0
-
-project = 'Linux Media Subsystem Documentation'
-
-# It is possible to run Sphinx in nickpick mode with:
-nitpicky = True
-
-# within nit-picking build, do not refer to any intersphinx object
-intersphinx_mapping = {}
-
-# In nickpick mode, it will complain about lots of missing references that
-#
-# 1) are just typedefs like: bool, __u32, etc;
-# 2) It will complain for things like: enum, NULL;
-# 3) It will complain for symbols that should be on different
-#    books (but currently aren't ported to ReST)
-#
-# The list below has a list of such symbols to be ignored in nitpick mode
-#
-nitpick_ignore = [
-    ("c:func", "clock_gettime"),
-    ("c:func", "close"),
-    ("c:func", "container_of"),
-    ("c:func", "copy_from_user"),
-    ("c:func", "copy_to_user"),
-    ("c:func", "determine_valid_ioctls"),
-    ("c:func", "ERR_PTR"),
-    ("c:func", "i2c_new_device"),
-    ("c:func", "ioctl"),
-    ("c:func", "IS_ERR"),
-    ("c:func", "KERNEL_VERSION"),
-    ("c:func", "mmap"),
-    ("c:func", "open"),
-    ("c:func", "pci_name"),
-    ("c:func", "poll"),
-    ("c:func", "PTR_ERR"),
-    ("c:func", "read"),
-    ("c:func", "release"),
-    ("c:func", "set"),
-    ("c:func", "struct fd_set"),
-    ("c:func", "struct pollfd"),
-    ("c:func", "usb_make_path"),
-    ("c:func", "wait_finish"),
-    ("c:func", "wait_prepare"),
-    ("c:func", "write"),
-
-    ("c:type", "atomic_t"),
-    ("c:type", "bool"),
-    ("c:type", "boolean"),
-    ("c:type", "buf_queue"),
-    ("c:type", "device"),
-    ("c:type", "device_driver"),
-    ("c:type", "device_node"),
-    ("c:type", "enum"),
-    ("c:type", "fd"),
-    ("c:type", "fd_set"),
-    ("c:type", "file"),
-    ("c:type", "i2c_adapter"),
-    ("c:type", "i2c_board_info"),
-    ("c:type", "i2c_client"),
-    ("c:type", "int16_t"),
-    ("c:type", "ktime_t"),
-    ("c:type", "led_classdev_flash"),
-    ("c:type", "list_head"),
-    ("c:type", "lock_class_key"),
-    ("c:type", "module"),
-    ("c:type", "mutex"),
-    ("c:type", "NULL"),
-    ("c:type", "off_t"),
-    ("c:type", "pci_dev"),
-    ("c:type", "pdvbdev"),
-    ("c:type", "poll_table"),
-    ("c:type", "platform_device"),
-    ("c:type", "pollfd"),
-    ("c:type", "poll_table_struct"),
-    ("c:type", "s32"),
-    ("c:type", "s64"),
-    ("c:type", "sd"),
-    ("c:type", "size_t"),
-    ("c:type", "spi_board_info"),
-    ("c:type", "spi_device"),
-    ("c:type", "spi_master"),
-    ("c:type", "ssize_t"),
-    ("c:type", "fb_fix_screeninfo"),
-    ("c:type", "pollfd"),
-    ("c:type", "timeval"),
-    ("c:type", "video_capability"),
-    ("c:type", "timeval"),
-    ("c:type", "__u16"),
-    ("c:type", "u16"),
-    ("c:type", "__u32"),
-    ("c:type", "u32"),
-    ("c:type", "__u64"),
-    ("c:type", "u64"),
-    ("c:type", "u8"),
-    ("c:type", "uint16_t"),
-    ("c:type", "uint32_t"),
-    ("c:type", "union"),
-    ("c:type", "__user"),
-    ("c:type", "usb_device"),
-    ("c:type", "usb_interface"),
-    ("c:type", "v4l2_std_id"),
-    ("c:type", "video_system_t"),
-    ("c:type", "vm_area_struct"),
-
-    # Opaque structures
-
-    ("c:type", "v4l2_m2m_dev"),
-]
diff --git a/Documentation/media/dmx.h.rst.exceptions b/Documentation/media/dmx.h.rst.exceptions
deleted file mode 100644
index afc14d384b83..000000000000
--- a/Documentation/media/dmx.h.rst.exceptions
+++ /dev/null
@@ -1,66 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-# Ignore header name
-ignore define _UAPI_DVBDMX_H_
-
-# Ignore limit constants
-ignore define DMX_FILTER_SIZE
-
-# dmx_pes_type_t enum symbols
-replace enum dmx_ts_pes :c:type:`dmx_pes_type`
-replace symbol DMX_PES_AUDIO0 :c:type:`dmx_pes_type`
-replace symbol DMX_PES_VIDEO0 :c:type:`dmx_pes_type`
-replace symbol DMX_PES_TELETEXT0 :c:type:`dmx_pes_type`
-replace symbol DMX_PES_SUBTITLE0 :c:type:`dmx_pes_type`
-replace symbol DMX_PES_PCR0 :c:type:`dmx_pes_type`
-replace symbol DMX_PES_AUDIO1 :c:type:`dmx_pes_type`
-replace symbol DMX_PES_VIDEO1 :c:type:`dmx_pes_type`
-replace symbol DMX_PES_TELETEXT1 :c:type:`dmx_pes_type`
-replace symbol DMX_PES_SUBTITLE1 :c:type:`dmx_pes_type`
-replace symbol DMX_PES_PCR1 :c:type:`dmx_pes_type`
-replace symbol DMX_PES_AUDIO2 :c:type:`dmx_pes_type`
-replace symbol DMX_PES_VIDEO2 :c:type:`dmx_pes_type`
-replace symbol DMX_PES_TELETEXT2 :c:type:`dmx_pes_type`
-replace symbol DMX_PES_SUBTITLE2 :c:type:`dmx_pes_type`
-replace symbol DMX_PES_PCR2 :c:type:`dmx_pes_type`
-replace symbol DMX_PES_AUDIO3 :c:type:`dmx_pes_type`
-replace symbol DMX_PES_VIDEO3 :c:type:`dmx_pes_type`
-replace symbol DMX_PES_TELETEXT3 :c:type:`dmx_pes_type`
-replace symbol DMX_PES_SUBTITLE3 :c:type:`dmx_pes_type`
-replace symbol DMX_PES_PCR3 :c:type:`dmx_pes_type`
-replace symbol DMX_PES_OTHER :c:type:`dmx_pes_type`
-
-# Ignore obsolete symbols
-ignore define DMX_PES_AUDIO
-ignore define DMX_PES_VIDEO
-ignore define DMX_PES_TELETEXT
-ignore define DMX_PES_SUBTITLE
-ignore define DMX_PES_PCR
-
-# dmx_input_t symbols
-replace enum dmx_input :c:type:`dmx_input`
-replace symbol DMX_IN_FRONTEND :c:type:`dmx_input`
-replace symbol DMX_IN_DVR :c:type:`dmx_input`
-
-# Flags for struct dmx_sct_filter_params
-replace define DMX_CHECK_CRC :c:type:`dmx_sct_filter_params`
-replace define DMX_ONESHOT :c:type:`dmx_sct_filter_params`
-replace define DMX_IMMEDIATE_START :c:type:`dmx_sct_filter_params`
-
-# some typedefs should point to struct/enums
-replace typedef dmx_filter_t :c:type:`dmx_filter`
-replace typedef dmx_pes_type_t :c:type:`dmx_pes_type`
-replace typedef dmx_input_t :c:type:`dmx_input`
-
-replace symbol DMX_BUFFER_FLAG_HAD_CRC32_DISCARD :c:type:`dmx_buffer_flags`
-replace	symbol DMX_BUFFER_FLAG_TEI :c:type:`dmx_buffer_flags`
-replace	symbol DMX_BUFFER_PKT_COUNTER_MISMATCH :c:type:`dmx_buffer_flags`
-replace	symbol DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED :c:type:`dmx_buffer_flags`
-replace	symbol DMX_BUFFER_FLAG_DISCONTINUITY_INDICATOR :c:type:`dmx_buffer_flags`
-
-replace symbol DMX_OUT_DECODER :c:type:`dmx_output`
-replace symbol DMX_OUT_TAP :c:type:`dmx_output`
-replace symbol DMX_OUT_TS_TAP :c:type:`dmx_output`
-replace symbol DMX_OUT_TSDEMUX_TAP :c:type:`dmx_output`
-
-replace ioctl DMX_DQBUF dmx_qbuf
diff --git a/Documentation/media/dvb-drivers/avermedia.rst b/Documentation/media/dvb-drivers/avermedia.rst
deleted file mode 100644
index 14f437ca38d3..000000000000
--- a/Documentation/media/dvb-drivers/avermedia.rst
+++ /dev/null
@@ -1,269 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-HOWTO: Get An Avermedia DVB-T working under Linux
--------------------------------------------------
-
-February 14th 2006
-
-.. note::
-
-   This documentation is outdated. Please check at the DVB wiki
-   at https://linuxtv.org/wiki for more updated info.
-
-   There's a section there specific for Avermedia boards at:
-   https://linuxtv.org/wiki/index.php/AVerMedia
-
-
-Assumptions and Introduction
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-It  is assumed that the reader understands the basic structure
-of  the Linux Kernel DVB drivers and the general principles of
-Digital TV.
-
-One  significant difference between Digital TV and Analogue TV
-that  the  unwary  (like  myself)  should  consider  is  that,
-although  the  component  structure  of budget DVB-T cards are
-substantially  similar  to Analogue TV cards, they function in
-substantially different ways.
-
-The  purpose  of  an  Analogue TV is to receive and display an
-Analogue  Television  signal. An Analogue TV signal (otherwise
-known  as  composite  video)  is  an  analogue  encoding  of a
-sequence  of  image frames (25 per second) rasterised using an
-interlacing   technique.   Interlacing  takes  two  fields  to
-represent  one  frame.  Computers today are at their best when
-dealing  with  digital  signals,  not  analogue  signals and a
-composite  video signal is about as far removed from a digital
-data stream as you can get. Therefore, an Analogue TV card for
-a PC has the following purpose:
-
-* Tune the receiver to receive a broadcast signal
-* demodulate the broadcast signal
-* demultiplex  the  analogue video signal and analogue audio
-  signal. **NOTE:** some countries employ a digital audio signal
-  embedded  within the modulated composite analogue signal -
-  NICAM.)
-* digitize  the analogue video signal and make the resulting
-  datastream available to the data bus.
-
-The  digital  datastream from an Analogue TV card is generated
-by  circuitry on the card and is often presented uncompressed.
-For  a PAL TV signal encoded at a resolution of 768x576 24-bit
-color pixels over 25 frames per second - a fair amount of data
-is  generated and must be processed by the PC before it can be
-displayed  on the video monitor screen. Some Analogue TV cards
-for  PCs  have  onboard  MPEG2  encoders  which permit the raw
-digital  data  stream  to be presented to the PC in an encoded
-and  compressed  form  -  similar  to the form that is used in
-Digital TV.
-
-The  purpose of a simple budget digital TV card (DVB-T,C or S)
-is to simply:
-
-* Tune the received to receive a broadcast signal.
-* Extract  the encoded digital datastream from the broadcast
-  signal.
-* Make  the  encoded digital datastream (MPEG2) available to
-  the data bus.
-
-The  significant  difference between the two is that the tuner
-on  the analogue TV card spits out an Analogue signal, whereas
-the  tuner  on  the  digital  TV  card  spits out a compressed
-encoded   digital   datastream.   As  the  signal  is  already
-digitised,  it  is  trivial  to pass this datastream to the PC
-databus  with  minimal  additional processing and then extract
-the  digital  video  and audio datastreams passing them to the
-appropriate software or hardware for decoding and viewing.
-
-The Avermedia DVB-T
-~~~~~~~~~~~~~~~~~~~
-
-The Avermedia DVB-T is a budget PCI DVB card. It has 3 inputs:
-
-* RF Tuner Input
-* Composite Video Input (RCA Jack)
-* SVIDEO Input (Mini-DIN)
-
-The  RF  Tuner  Input  is the input to the tuner module of the
-card.  The  Tuner  is  otherwise known as the "Frontend" . The
-Frontend of the Avermedia DVB-T is a Microtune 7202D. A timely
-post  to  the  linux-dvb  mailing  list  ascertained  that the
-Microtune  7202D  is  supported  by the sp887x driver which is
-found in the dvb-hw CVS module.
-
-The  DVB-T card is based around the BT878 chip which is a very
-common multimedia bridge and often found on Analogue TV cards.
-There is no on-board MPEG2 decoder, which means that all MPEG2
-decoding  must  be done in software, or if you have one, on an
-MPEG2 hardware decoding card or chipset.
-
-
-Getting the card going
-~~~~~~~~~~~~~~~~~~~~~~
-
-In order to fire up the card, it is necessary to load a number
-of modules from the DVB driver set. Prior to this it will have
-been  necessary to download these drivers from the linuxtv CVS
-server and compile them successfully.
-
-Depending on the card's feature set, the Device Driver API for
-DVB under Linux will expose some of the following device files
-in the /dev tree:
-
-* /dev/dvb/adapter0/audio0
-* /dev/dvb/adapter0/ca0
-* /dev/dvb/adapter0/demux0
-* /dev/dvb/adapter0/dvr0
-* /dev/dvb/adapter0/frontend0
-* /dev/dvb/adapter0/net0
-* /dev/dvb/adapter0/osd0
-* /dev/dvb/adapter0/video0
-
-The  primary  device  nodes that we are interested in (at this
-stage) for the Avermedia DVB-T are:
-
-* /dev/dvb/adapter0/dvr0
-* /dev/dvb/adapter0/frontend0
-
-The dvr0 device node is used to read the MPEG2 Data Stream and
-the frontend0 node is used to tune the frontend tuner module.
-
-At  this  stage,  it  has  not  been  able  to  ascertain  the
-functionality  of the remaining device nodes in respect of the
-Avermedia  DVBT.  However,  full  functionality  in respect of
-tuning,  receiving  and  supplying  the  MPEG2  data stream is
-possible  with the currently available versions of the driver.
-It  may be possible that additional functionality is available
-from  the  card  (i.e.  viewing the additional analogue inputs
-that  the card presents), but this has not been tested yet. If
-I get around to this, I'll update the document with whatever I
-find.
-
-To  power  up  the  card,  load  the  following modules in the
-following order:
-
-* modprobe bttv (normally loaded automatically)
-* modprobe dvb-bt8xx (or place dvb-bt8xx in /etc/modules)
-
-Insertion  of  these  modules  into  the  running  kernel will
-activate the appropriate DVB device nodes. It is then possible
-to start accessing the card with utilities such as scan, tzap,
-dvbstream etc.
-
-The frontend module sp887x.o, requires an external   firmware.
-Please use  the  command "get_dvb_firmware sp887x" to download
-it. Then copy it to /usr/lib/hotplug/firmware or /lib/firmware/
-(depending on configuration of firmware hotplug).
-
-Receiving DVB-T in Australia
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-I  have  no  experience of DVB-T in other countries other than
-Australia,  so  I will attempt to explain how it works here in
-Melbourne  and how this affects the configuration of the DVB-T
-card.
-
-The  Digital  Broadcasting  Australia  website has a Reception
-locatortool which provides information on transponder channels
-and  frequencies.  My  local  transmitter  happens to be Mount
-Dandenong.
-
-The frequencies broadcast by Mount Dandenong are:
-
-Table 1. Transponder Frequencies Mount Dandenong, Vic, Aus.
-Broadcaster Channel Frequency
-ABC         VHF 12  226.5 MHz
-TEN         VHF 11  219.5 MHz
-NINE        VHF 8   191.625 MHz
-SEVEN       VHF 6   177.5 MHz
-SBS         UHF 29  536.5 MHz
-
-The Scan utility has a set of compiled-in defaults for various
-countries and regions, but if they do not suit, or if you have
-a pre-compiled scan binary, you can specify a data file on the
-command  line which contains the transponder frequencies. Here
-is a sample file for the above channel transponders:
-
-::
-
-	# Data file for DVB scan program
-	#
-	# C Frequency SymbolRate FEC QAM
-	# S Frequency Polarisation SymbolRate FEC
-	# T Frequency Bandwidth FEC FEC2 QAM Mode Guard Hier
-	T 226500000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
-	T 191625000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
-	T 219500000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
-	T 177500000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
-	T 536500000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
-
-The   defaults   for   the  transponder  frequency  and  other
-modulation parameters were obtained from www.dba.org.au.
-
-When  Scan  runs, it will output channels.conf information for
-any  channel's transponders which the card's frontend can lock
-onto.  (i.e.  any  whose  signal  is  strong  enough  at  your
-antenna).
-
-Here's my channels.conf file for anyone who's interested:
-
-::
-
-	ABC HDTV:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:2307:0:560
-	ABC TV Melbourne:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:561
-	ABC TV 2:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:562
-	ABC TV 3:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:563
-	ABC TV 4:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:564
-	ABC DiG Radio:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:0:2311:566
-	TEN Digital:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1585
-	TEN Digital 1:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1586
-	TEN Digital 2:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1587
-	TEN Digital 3:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1588
-	TEN Digital:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1589
-	TEN Digital 4:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1590
-	TEN Digital:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1591
-	TEN HD:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:514:0:1592
-	TEN Digital:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1593
-	Nine Digital:191625000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:513:660:1072
-	Nine Digital HD:191625000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:0:1073
-	Nine Guide:191625000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:514:670:1074
-	7 Digital:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:769:770:1328
-	7 Digital 1:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:769:770:1329
-	7 Digital 2:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:769:770:1330
-	7 Digital 3:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:769:770:1331
-	7 HD Digital:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:833:834:1332
-	7 Program Guide:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:865:866:1334
-	SBS HD:536500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:102:103:784
-	SBS DIGITAL 1:536500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:161:81:785
-	SBS DIGITAL 2:536500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:162:83:786
-	SBS EPG:536500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:163:85:787
-	SBS RADIO 1:536500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:201:798
-	SBS RADIO 2:536500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:202:799
-
-Known Limitations
-~~~~~~~~~~~~~~~~~
-
-At  present  I can say with confidence that the frontend tunes
-via /dev/dvb/adapter{x}/frontend0 and supplies an MPEG2 stream
-via   /dev/dvb/adapter{x}/dvr0.   I   have   not   tested  the
-functionality  of any other part of the card yet. I will do so
-over time and update this document.
-
-There  are some limitations in the i2c layer due to a returned
-error message inconsistency. Although this generates errors in
-dmesg  and  the  system logs, it does not appear to affect the
-ability of the frontend to function correctly.
-
-Further Update
-~~~~~~~~~~~~~~
-
-dvbstream  and  VideoLAN  Client on windows works a treat with
-DVB,  in  fact  this  is  currently  serving as my main way of
-viewing  DVB-T  at  the  moment.  Additionally, VLC is happily
-decoding  HDTV  signals,  although  the PC is dropping the odd
-frame here and there - I assume due to processing capability -
-as all the decoding is being done under windows in software.
-
-Many  thanks to Nigel Pearson for the updates to this document
-since the recent revision of the driver.
diff --git a/Documentation/media/dvb-drivers/bt8xx.rst b/Documentation/media/dvb-drivers/bt8xx.rst
deleted file mode 100644
index 7936cd96fc8f..000000000000
--- a/Documentation/media/dvb-drivers/bt8xx.rst
+++ /dev/null
@@ -1,124 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-How to get the bt8xx cards working
-==================================
-
-Authors: Richard Walker,
-	 Jamie Honan,
-	 Michael Hunold,
-	 Manu Abraham,
-	 Uwe Bugla,
-	 Michael Krufky
-
-.. note::
-
-   This documentation is outdated. Please check at the DVB wiki
-   at https://linuxtv.org/wiki for more updated info.
-
-General information
--------------------
-
-This class of cards has a bt878a as the PCI interface, and require the bttv driver
-for accessing the i2c bus and the gpio pins of the bt8xx chipset.
-Please see Documentation/media/dvb-drivers/cards.rst => o Cards based on the Conexant Bt8xx PCI bridge:
-
-Compiling kernel please enable:
-
-#) ``Device drivers`` => ``Multimedia devices`` => ``Video For Linux`` => ``Enable Video for Linux API 1 (DEPRECATED)``
-#) ``Device drivers`` => ``Multimedia devices`` => ``Video For Linux`` => ``Video Capture Adapters`` => ``BT848 Video For Linux``
-#) ``Device drivers`` => ``Multimedia devices`` => ``Digital Video Broadcasting Devices`` => ``DVB for Linux`` ``DVB Core Support`` ``Bt8xx based PCI Cards``
-
-  Please use the following options with care as deselection of drivers which are in fact necessary may result in DVB devices that cannot be tuned due to lack of driver support:
-  You can save RAM by deselecting every frontend module that your DVB card does not need.
-
-  First please remove the static dependency of DVB card drivers on all frontend modules for all possible card variants by enabling:
-
-#) ``Device drivers`` => ``Multimedia devices`` => ``Digital Video Broadcasting Devices`` => ``DVB for Linux`` ``DVB Core Support`` ``Load and attach frontend modules as needed``
-
-  If you know the frontend driver that your card needs please enable:
-
-#) ``Device drivers`` => ``Multimedia devices`` => ``Digital Video Broadcasting Devices`` => ``DVB for Linux`` ``DVB Core Support`` ``Customise DVB Frontends`` => ``Customise the frontend modules to build``
-
- Then please select your card-specific frontend module.
-
-Loading Modules
----------------
-
-Regular case: If the bttv driver detects a bt8xx-based DVB card, all frontend and backend modules will be loaded automatically.
-Exceptions are:
-- Old TwinHan DST cards or clones with or without CA slot and not containing an Eeprom.
-People running udev please see Documentation/media/dvb-drivers/udev.rst.
-
-In the following cases overriding the PCI type detection for dvb-bt8xx might be necessary:
-
-Running TwinHan and Clones
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. code-block:: none
-
-	$ modprobe bttv card=113
-	$ modprobe dst
-
-Useful parameters for verbosity level and debugging the dst module:
-
-.. code-block:: none
-
-	verbose=0:		messages are disabled
-		1:		only error messages are displayed
-		2:		notifications are displayed
-		3:		other useful messages are displayed
-		4:		debug setting
-	dst_addons=0:		card is a free to air (FTA) card only
-		0x20:	card has a conditional access slot for scrambled channels
-
-The autodetected values are determined by the cards' "response string".
-In your logs see f. ex.: dst_get_device_id: Recognize [DSTMCI].
-For bug reports please send in a complete log with verbose=4 activated.
-Please also see Documentation/media/dvb-drivers/ci.rst.
-
-Running multiple cards
-~~~~~~~~~~~~~~~~~~~~~~
-
-Examples of card ID's:
-
-.. code-block:: none
-
-	Pinnacle PCTV Sat:		 94
-	Nebula Electronics Digi TV:	104
-	pcHDTV HD-2000 TV:		112
-	Twinhan DST and clones:		113
-	Avermedia AverTV DVB-T 771:	123
-	Avermedia AverTV DVB-T 761:	124
-	DViCO FusionHDTV DVB-T Lite:	128
-	DViCO FusionHDTV 5 Lite:	135
-
-.. note::
-
-   The order of the card ID should be uprising:
-
-   Example:
-
-   .. code-block:: none
-
-	$ modprobe bttv card=113 card=135
-
-For a full list of card ID's please see Documentation/media/v4l-drivers/bttv-cardlist.rst.
-In case of further problems please subscribe and send questions to the mailing list: linux-dvb@linuxtv.org.
-
-Probing the cards with broken PCI subsystem ID
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-There are some TwinHan cards that the EEPROM has become corrupted for some
-reason. The cards do not have correct PCI subsystem ID. But we can force
-probing the cards with broken PCI subsystem ID
-
-.. code-block:: none
-
-	$ echo 109e 0878 $subvendor $subdevice > \
-		/sys/bus/pci/drivers/bt878/new_id
-
-.. code-block:: none
-
-	109e: PCI_VENDOR_ID_BROOKTREE
-	0878: PCI_DEVICE_ID_BROOKTREE_878
-
diff --git a/Documentation/media/dvb-drivers/cards.rst b/Documentation/media/dvb-drivers/cards.rst
deleted file mode 100644
index e2e30a56b450..000000000000
--- a/Documentation/media/dvb-drivers/cards.rst
+++ /dev/null
@@ -1,146 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-Hardware supported by the linuxtv.org DVB drivers
-=================================================
-
-.. note::
-
-   This documentation is outdated. Please check at the DVB wiki
-   at https://linuxtv.org/wiki for more updated info.
-
-   Please look at
-   https://linuxtv.org/wiki/index.php/Hardware_Device_Information
-   for an updated list of supported cards.
-
-Generally, the DVB hardware manufacturers frequently change the
-frontends (i.e. tuner / demodulator units) used, usually without
-changing the product name, revision number or specs. Some cards
-are also available in versions with different frontends for
-DVB-S/DVB-C/DVB-T. Thus the frontend drivers are listed separately.
-
-.. note::
-
-  #) There is no guarantee that every frontend driver works
-     out of the box with every card, because of different wiring.
-
-  #) The demodulator chips can be used with a variety of
-     tuner/PLL chips, and not all combinations are supported. Often
-     the demodulator and tuner/PLL chip are inside a metal box for
-     shielding, and the whole metal box has its own part number.
-
-
-- Frontends drivers:
-
-  - dvb_dummy_fe: for testing...
-
-  DVB-S:
-   - ves1x93		: Alps BSRV2 (ves1893 demodulator) and dbox2 (ves1993)
-   - cx24110		: Conexant HM1221/HM1811 (cx24110 or cx24106 demod, cx24108 PLL)
-   - grundig_29504-491	: Grundig 29504-491 (Philips TDA8083 demodulator), tsa5522 PLL
-   - mt312		: Zarlink mt312 or Mitel vp310 demodulator, sl1935 or tsa5059 PLLi, Technisat Sky2Pc with bios Rev. 2.3
-   - stv0299		: Alps BSRU6 (tsa5059 PLL), LG TDQB-S00x (tsa5059 PLL),
-			  LG TDQF-S001F (sl1935 PLL), Philips SU1278 (tua6100 PLL),
-			  Philips SU1278SH (tsa5059 PLL), Samsung TBMU24112IMB, Technisat Sky2Pc with bios Rev. 2.6
-
-  DVB-C:
-   - ves1820		: various (ves1820 demodulator, sp5659c or spXXXX PLL)
-   - at76c651		: Atmel AT76c651(B) with DAT7021 PLL
-
-  DVB-T:
-   - alps_tdlb7		: Alps TDLB7 (sp8870 demodulator, sp5659 PLL)
-   - alps_tdmb7		: Alps TDMB7 (cx22700 demodulator)
-   - grundig_29504-401	: Grundig 29504-401 (LSI L64781 demodulator), tsa5060 PLL
-   - tda1004x		: Philips tda10045h (td1344 or tdm1316l PLL)
-   - nxt6000 		: Alps TDME7 (MITEL SP5659 PLL), Alps TDED4 (TI ALP510 PLL), Comtech DVBT-6k07 (SP5730 PLL), (NxtWave Communications NXT6000 demodulator)
-   - sp887x		: Microtune 7202D
-   - dib3000mb	: DiBcom 3000-MB demodulator
-
-  DVB-S/C/T:
-   - dst		: TwinHan DST Frontend
-
-  ATSC:
-   - nxt200x		: Nxtwave NXT2002 & NXT2004
-   - or51211		: or51211 based (pcHDTV HD2000 card)
-   - or51132		: or51132 based (pcHDTV HD3000 card)
-   - bcm3510		: Broadcom BCM3510
-   - lgdt330x		: LG Electronics DT3302 & DT3303
-
-
-- Cards based on the Phillips saa7146 multimedia PCI bridge chip:
-
-  - TI AV7110 based cards (i.e. with hardware MPEG decoder):
-    - Siemens/Technotrend/Hauppauge PCI DVB card revision 1.1, 1.3, 1.5, 1.6, 2.1 (aka Hauppauge Nexus)
-  - "budget" cards (i.e. without hardware MPEG decoder):
-    - Technotrend Budget / Hauppauge WinTV-Nova PCI Cards
-    - SATELCO Multimedia PCI
-    - KNC1 DVB-S, Typhoon DVB-S, Terratec Cinergy 1200 DVB-S (no CI support)
-    - Typhoon DVB-S budget
-    - Fujitsu-Siemens Activy DVB-S budget card
-
-- Cards based on the B2C2 Inc. FlexCopII/IIb/III:
-
-  - Technisat SkyStar2 PCI DVB card revision 2.3, 2.6B, 2.6C
-
-- Cards based on the Conexant Bt8xx PCI bridge:
-
-  - Pinnacle PCTV Sat DVB
-  - Nebula Electronics DigiTV
-  - TwinHan DST
-  - Avermedia DVB-T
-  - ChainTech digitop DST-1000 DVB-S
-  - pcHDTV HD-2000 TV
-  - DViCO FusionHDTV DVB-T Lite
-  - DViCO FusionHDTV5 Lite
-
-- Technotrend / Hauppauge DVB USB devices:
-
-  - Nova USB
-  - DEC 2000-T, 3000-S, 2540-T
-
-- DiBcom DVB-T USB based devices:
-
-  - Twinhan VisionPlus VisionDTV USB-Ter DVB-T Device
-  - HAMA DVB-T USB device
-  - CTS Portable (Chinese Television System)
-  - KWorld V-Stream XPERT DTV DVB-T USB
-  - JetWay DTV DVB-T USB
-  - ADSTech Instant TV DVB-T USB
-  - Ultima Electronic/Artec T1 USB TVBOX (AN2135 and AN2235)
-  - Compro Videomate DVB-U2000 - DVB-T USB
-  - Grandtec USB DVB-T
-  - Avermedia AverTV DVBT USB
-  - DiBcom USB DVB-T reference device (non-public)
-  - Yakumo DVB-T mobile USB2.0
-  - DiBcom USB2.0 DVB-T reference device (non-public)
-
-- Experimental support for the analog module of the Siemens DVB-C PCI card
-
-- Cards based on the Conexant cx2388x PCI bridge:
-
-  - ADS Tech Instant TV DVB-T PCI
-  - ATI HDTV Wonder
-  - digitalnow DNTV Live! DVB-T
-  - DViCO FusionHDTV DVB-T1
-  - DViCO FusionHDTV DVB-T Plus
-  - DViCO FusionHDTV3 Gold-Q
-  - DViCO FusionHDTV3 Gold-T
-  - DViCO FusionHDTV5 Gold
-  - Hauppauge Nova-T DVB-T
-  - KWorld/VStream XPert DVB-T
-  - pcHDTV HD3000 HDTV
-  - TerraTec Cinergy 1400 DVB-T
-  - WinFast DTV1000-T
-
-- Cards based on the Phillips saa7134 PCI bridge:
-
-  - Medion 7134
-  - Pinnacle PCTV 300i DVB-T + PAL
-  - LifeView FlyDVB-T DUO
-  - Typhoon DVB-T Duo Digital/Analog Cardbus
-  - Philips TOUGH DVB-T reference design
-  - Philips EUROPA V3 reference design
-  - Compro Videomate DVB-T300
-  - Compro Videomate DVB-T200
-  - AVerMedia AVerTVHD MCE A180
-  - KWorld PC150-U ATSC Hybrid
-
diff --git a/Documentation/media/dvb-drivers/ci.rst b/Documentation/media/dvb-drivers/ci.rst
deleted file mode 100644
index 35f33f1f9e2a..000000000000
--- a/Documentation/media/dvb-drivers/ci.rst
+++ /dev/null
@@ -1,231 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-Digital TV Conditional Access Interface (CI API)
-================================================
-
-
-.. note::
-
-   This documentation is outdated.
-
-This document describes the usage of the high level CI API as
-in accordance to the Linux DVB API. This is a not a documentation for the,
-existing low level CI API.
-
-.. note::
-
-   For the Twinhan/Twinhan clones, the dst_ca module handles the CI
-   hardware handling.This module is loaded automatically if a CI
-   (Common Interface, that holds the CAM (Conditional Access Module)
-   is detected.
-
-ca_zap
-~~~~~~
-
-A userspace application, like ``ca_zap`` is required to handle encrypted
-MPEG-TS streams.
-
-The ``ca_zap`` userland application is in charge of sending the
-descrambling related information to the Conditional Access Module (CAM).
-
-This application requires the following to function properly as of now.
-
-a) Tune to a valid channel, with szap.
-
-  eg: $ szap -c channels.conf -r "TMC" -x
-
-b) a channels.conf containing a valid PMT PID
-
-  eg: TMC:11996:h:0:27500:278:512:650:321
-
-  here 278 is a valid PMT PID. the rest of the values are the
-  same ones that szap uses.
-
-c) after running a szap, you have to run ca_zap, for the
-   descrambler to function,
-
-  eg: $ ca_zap channels.conf "TMC"
-
-d) Hopefully enjoy your favourite subscribed channel as you do with
-   a FTA card.
-
-.. note::
-
-  Currently ca_zap, and dst_test, both are meant for demonstration
-  purposes only, they can become full fledged applications if necessary.
-
-
-Cards that fall in this category
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-At present the cards that fall in this category are the Twinhan and its
-clones, these cards are available as VVMER, Tomato, Hercules, Orange and
-so on.
-
-CI modules that are supported
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The CI module support is largely dependent upon the firmware on the cards
-Some cards do support almost all of the available CI modules. There is
-nothing much that can be done in order to make additional CI modules
-working with these cards.
-
-Modules that have been tested by this driver at present are
-
-(1) Irdeto 1 and 2 from SCM
-(2) Viaccess from SCM
-(3) Dragoncam
-
-The High level CI API
-~~~~~~~~~~~~~~~~~~~~~
-
-For the programmer
-^^^^^^^^^^^^^^^^^^
-
-With the High Level CI approach any new card with almost any random
-architecture can be implemented with this style, the definitions
-inside the switch statement can be easily adapted for any card, thereby
-eliminating the need for any additional ioctls.
-
-The disadvantage is that the driver/hardware has to manage the rest. For
-the application programmer it would be as simple as sending/receiving an
-array to/from the CI ioctls as defined in the Linux DVB API. No changes
-have been made in the API to accommodate this feature.
-
-
-Why the need for another CI interface?
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-This is one of the most commonly asked question. Well a nice question.
-Strictly speaking this is not a new interface.
-
-The CI interface is defined in the DVB API in ca.h as:
-
-.. code-block:: c
-
-	typedef struct ca_slot_info {
-		int num;               /* slot number */
-
-		int type;              /* CA interface this slot supports */
-	#define CA_CI            1     /* CI high level interface */
-	#define CA_CI_LINK       2     /* CI link layer level interface */
-	#define CA_CI_PHYS       4     /* CI physical layer level interface */
-	#define CA_DESCR         8     /* built-in descrambler */
-	#define CA_SC          128     /* simple smart card interface */
-
-		unsigned int flags;
-	#define CA_CI_MODULE_PRESENT 1 /* module (or card) inserted */
-	#define CA_CI_MODULE_READY   2
-	} ca_slot_info_t;
-
-This CI interface follows the CI high level interface, which is not
-implemented by most applications. Hence this area is revisited.
-
-This CI interface is quite different in the case that it tries to
-accommodate all other CI based devices, that fall into the other categories.
-
-This means that this CI interface handles the EN50221 style tags in the
-Application layer only and no session management is taken care of by the
-application. The driver/hardware will take care of all that.
-
-This interface is purely an EN50221 interface exchanging APDU's. This
-means that no session management, link layer or a transport layer do
-exist in this case in the application to driver communication. It is
-as simple as that. The driver/hardware has to take care of that.
-
-With this High Level CI interface, the interface can be defined with the
-regular ioctls.
-
-All these ioctls are also valid for the High level CI interface
-
-#define CA_RESET          _IO('o', 128)
-#define CA_GET_CAP        _IOR('o', 129, ca_caps_t)
-#define CA_GET_SLOT_INFO  _IOR('o', 130, ca_slot_info_t)
-#define CA_GET_DESCR_INFO _IOR('o', 131, ca_descr_info_t)
-#define CA_GET_MSG        _IOR('o', 132, ca_msg_t)
-#define CA_SEND_MSG       _IOW('o', 133, ca_msg_t)
-#define CA_SET_DESCR      _IOW('o', 134, ca_descr_t)
-
-
-On querying the device, the device yields information thus:
-
-.. code-block:: none
-
-	CA_GET_SLOT_INFO
-	----------------------------
-	Command = [info]
-	APP: Number=[1]
-	APP: Type=[1]
-	APP: flags=[1]
-	APP: CI High level interface
-	APP: CA/CI Module Present
-
-	CA_GET_CAP
-	----------------------------
-	Command = [caps]
-	APP: Slots=[1]
-	APP: Type=[1]
-	APP: Descrambler keys=[16]
-	APP: Type=[1]
-
-	CA_SEND_MSG
-	----------------------------
-	Descriptors(Program Level)=[ 09 06 06 04 05 50 ff f1]
-	Found CA descriptor @ program level
-
-	(20) ES type=[2] ES pid=[201]  ES length =[0 (0x0)]
-	(25) ES type=[4] ES pid=[301]  ES length =[0 (0x0)]
-	ca_message length is 25 (0x19) bytes
-	EN50221 CA MSG=[ 9f 80 32 19 03 01 2d d1 f0 08 01 09 06 06 04 05 50 ff f1 02 e0 c9 00 00 04 e1 2d 00 00]
-
-
-Not all ioctl's are implemented in the driver from the API, the other
-features of the hardware that cannot be implemented by the API are achieved
-using the CA_GET_MSG and CA_SEND_MSG ioctls. An EN50221 style wrapper is
-used to exchange the data to maintain compatibility with other hardware.
-
-.. code-block:: c
-
-	/* a message to/from a CI-CAM */
-	typedef struct ca_msg {
-		unsigned int index;
-		unsigned int type;
-		unsigned int length;
-		unsigned char msg[256];
-	} ca_msg_t;
-
-
-The flow of data can be described thus,
-
-.. code-block:: none
-
-	App (User)
-	-----
-	parse
-	  |
-	  |
-	  v
-	en50221 APDU (package)
-   --------------------------------------
-   |	  |				| High Level CI driver
-   |	  |				|
-   |	  v				|
-   |	en50221 APDU (unpackage)	|
-   |	  |				|
-   |	  |				|
-   |	  v				|
-   |	sanity checks			|
-   |	  |				|
-   |	  |				|
-   |	  v				|
-   |	do (H/W dep)			|
-   --------------------------------------
-	  |    Hardware
-	  |
-	  v
-
-
-
-
-The High Level CI interface uses the EN50221 DVB standard, following a
-standard ensures futureproofness.
diff --git a/Documentation/media/dvb-drivers/contributors.rst b/Documentation/media/dvb-drivers/contributors.rst
deleted file mode 100644
index f23b6e6faf46..000000000000
--- a/Documentation/media/dvb-drivers/contributors.rst
+++ /dev/null
@@ -1,131 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-Contributors
-============
-
-.. note::
-
-   This documentation is outdated. There are several other DVB contributors
-   that aren't listed below.
-
-Thanks go to the following people for patches and contributions:
-
-- Michael Hunold <m.hunold@gmx.de>
-
-  - for the initial saa7146 driver and its recent overhaul
-
-- Christian Theiss
-
-  - for his work on the initial Linux DVB driver
-
-- Marcus Metzler <mocm@metzlerbros.de> and
-  Ralph Metzler <rjkm@metzlerbros.de>
-
-  - for their continuing work on the DVB driver
-
-- Michael Holzt <kju@debian.org>
-
-  - for his contributions to the dvb-net driver
-
-- Diego Picciani <d.picciani@novacomp.it>
-
-  - for CyberLogin for Linux which allows logging onto EON
-    (in case you are wondering where CyberLogin is, EON changed its login
-    procedure and CyberLogin is no longer used.)
-
-- Martin Schaller <martin@smurf.franken.de>
-
-  - for patching the cable card decoder driver
-
-- Klaus Schmidinger <Klaus.Schmidinger@cadsoft.de>
-
-  - for various fixes regarding tuning, OSD and CI stuff and his work on VDR
-
-- Steve Brown <sbrown@cortland.com>
-
-  - for his AFC kernel thread
-
-- Christoph Martin <martin@uni-mainz.de>
-
-  - for his LIRC infrared handler
-
-- Andreas Oberritter <obi@linuxtv.org>,
-  Dennis Noermann <dennis.noermann@noernet.de>,
-  Felix Domke <tmbinc@elitedvb.net>,
-  Florian Schirmer <jolt@tuxbox.org>,
-  Ronny Strutz <3des@elitedvb.de>,
-  Wolfram Joost <dbox2@frokaschwei.de>
-  and all the other dbox2 people
-
-  - for many bugfixes in the generic DVB Core, frontend drivers and
-    their work on the dbox2 port of the DVB driver
-
-- Oliver Endriss <o.endriss@gmx.de>
-
-  - for many bugfixes
-
-- Andrew de Quincey <adq_dvb@lidskialf.net>
-
-  - for the tda1004x frontend driver, and various bugfixes
-
-- Peter Schildmann <peter.schildmann@web.de>
-
-  - for the driver for the Technisat SkyStar2 PCI DVB card
-
-- Vadim Catana <skystar@moldova.cc>,
-  Roberto Ragusa <r.ragusa@libero.it> and
-  Augusto Cardoso <augusto@carhil.net>
-
-  - for all the work for the FlexCopII chipset by B2C2,Inc.
-
-- Davor Emard <emard@softhome.net>
-
-  - for his work on the budget drivers, the demux code,
-    the module unloading problems, ...
-
-- Hans-Frieder Vogt <hfvogt@arcor.de>
-
-  - for his work on calculating and checking the crc's for the
-    TechnoTrend/Hauppauge DEC driver firmware
-
-- Michael Dreher <michael@5dot1.de> and
-  Andreas 'randy' Weinberger
-
-  - for the support of the Fujitsu-Siemens Activy budget DVB-S
-
-- Kenneth Aafløy <ke-aa@frisurf.no>
-
-  - for adding support for Typhoon DVB-S budget card
-
-- Ernst Peinlich <e.peinlich@inode.at>
-
-  - for tuning/DiSEqC support for the DEC 3000-s
-
-- Peter Beutner <p.beutner@gmx.net>
-
-  - for the IR code for the ttusb-dec driver
-
-- Wilson Michaels <wilsonmichaels@earthlink.net>
-
-  - for the lgdt330x frontend driver, and various bugfixes
-
-- Michael Krufky <mkrufky@linuxtv.org>
-
-  - for maintaining v4l/dvb inter-tree dependencies
-
-- Taylor Jacob <rtjacob@earthlink.net>
-
-  - for the nxt2002 frontend driver
-
-- Jean-Francois Thibert <jeanfrancois@sagetv.com>
-
-  - for the nxt2004 frontend driver
-
-- Kirk Lapray <kirk.lapray@gmail.com>
-
-  - for the or51211 and or51132 frontend drivers, and
-    for merging the nxt2002 and nxt2004 modules into a
-    single nxt200x frontend driver.
-
-(If you think you should be in this list, but you are not, drop a
-line to the DVB mailing list)
diff --git a/Documentation/media/dvb-drivers/dvb-usb.rst b/Documentation/media/dvb-drivers/dvb-usb.rst
deleted file mode 100644
index b2d5d9e62b30..000000000000
--- a/Documentation/media/dvb-drivers/dvb-usb.rst
+++ /dev/null
@@ -1,357 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-Idea behind the dvb-usb-framework
-=================================
-
-.. note::
-
-   #) This documentation is outdated. Please check at the DVB wiki
-      at https://linuxtv.org/wiki for more updated info.
-
-   #) **deprecated:** Newer DVB USB drivers should use the dvb-usb-v2 framework.
-
-In March 2005 I got the new Twinhan USB2.0 DVB-T device. They provided specs
-and a firmware.
-
-Quite keen I wanted to put the driver (with some quirks of course) into dibusb.
-After reading some specs and doing some USB snooping, it realized, that the
-dibusb-driver would be a complete mess afterwards. So I decided to do it in a
-different way: With the help of a dvb-usb-framework.
-
-The framework provides generic functions (mostly kernel API calls), such as:
-
-- Transport Stream URB handling in conjunction with dvb-demux-feed-control
-  (bulk and isoc are supported)
-- registering the device for the DVB-API
-- registering an I2C-adapter if applicable
-- remote-control/input-device handling
-- firmware requesting and loading (currently just for the Cypress USB
-  controllers)
-- other functions/methods which can be shared by several drivers (such as
-  functions for bulk-control-commands)
-- TODO: a I2C-chunker. It creates device-specific chunks of register-accesses
-  depending on length of a register and the number of values that can be
-  multi-written and multi-read.
-
-The source code of the particular DVB USB devices does just the communication
-with the device via the bus. The connection between the DVB-API-functionality
-is done via callbacks, assigned in a static device-description (struct
-dvb_usb_device) each device-driver has to have.
-
-For an example have a look in drivers/media/usb/dvb-usb/vp7045*.
-
-Objective is to migrate all the usb-devices (dibusb, cinergyT2, maybe the
-ttusb; flexcop-usb already benefits from the generic flexcop-device) to use
-the dvb-usb-lib.
-
-TODO: dynamic enabling and disabling of the pid-filter in regard to number of
-feeds requested.
-
-Supported devices
------------------
-
-See the LinuxTV DVB Wiki at https://linuxtv.org for a complete list of
-cards/drivers/firmwares:
-https://linuxtv.org/wiki/index.php/DVB_USB
-
-0. History & News:
-
-  2005-06-30
-
-  - added support for WideView WT-220U (Thanks to Steve Chang)
-
-  2005-05-30
-
-  - added basic isochronous support to the dvb-usb-framework
-  - added support for Conexant Hybrid reference design and Nebula
-	       DigiTV USB
-
-  2005-04-17
-
-  - all dibusb devices ported to make use of the dvb-usb-framework
-
-  2005-04-02
-
-  - re-enabled and improved remote control code.
-
-  2005-03-31
-
-  - ported the Yakumo/Hama/Typhoon DVB-T USB2.0 device to dvb-usb.
-
-  2005-03-30
-
-  - first commit of the dvb-usb-module based on the dibusb-source.
-    First device is a new driver for the
-    TwinhanDTV Alpha / MagicBox II USB2.0-only DVB-T device.
-  - (change from dvb-dibusb to dvb-usb)
-
-  2005-03-28
-
-  - added support for the AVerMedia AverTV DVB-T USB2.0 device
-    (Thanks to Glen Harris and Jiun-Kuei Jung, AVerMedia)
-
-  2005-03-14
-
-  - added support for the Typhoon/Yakumo/HAMA DVB-T mobile USB2.0
-
-  2005-02-11
-
-  - added support for the KWorld/ADSTech Instant DVB-T USB2.0.
-    Thanks a lot to Joachim von Caron
-
-  2005-02-02
-  - added support for the Hauppauge Win-TV Nova-T USB2
-
-  2005-01-31
-  - distorted streaming is gone for USB1.1 devices
-
-  2005-01-13
-
-  - moved the mirrored pid_filter_table back to dvb-dibusb
-    first almost working version for HanfTek UMT-010
-    found out, that Yakumo/HAMA/Typhoon are predecessors of the HanfTek UMT-010
-
-  2005-01-10
-
-  - refactoring completed, now everything is very delightful
-
-  - tuner quirks for some weird devices (Artec T1 AN2235 device has sometimes a
-    Panasonic Tuner assembled). Tunerprobing implemented.
-    Thanks a lot to Gunnar Wittich.
-
-  2004-12-29
-
-  - after several days of struggling around bug of no returning URBs fixed.
-
-  2004-12-26
-
-  - refactored the dibusb-driver, split into separate files
-  - i2c-probing enabled
-
-  2004-12-06
-
-  - possibility for demod i2c-address probing
-  - new usb IDs (Compro, Artec)
-
-  2004-11-23
-
-  - merged changes from DiB3000MC_ver2.1
-  - revised the debugging
-  - possibility to deliver the complete TS for USB2.0
-
-  2004-11-21
-
-  - first working version of the dib3000mc/p frontend driver.
-
-  2004-11-12
-
-  - added additional remote control keys. Thanks to Uwe Hanke.
-
-  2004-11-07
-
-  - added remote control support. Thanks to David Matthews.
-
-  2004-11-05
-
-  - added support for a new devices (Grandtec/Avermedia/Artec)
-  - merged my changes (for dib3000mb/dibusb) to the FE_REFACTORING, because it became HEAD
-  - moved transfer control (pid filter, fifo control) from usb driver to frontend, it seems
-    better settled there (added xfer_ops-struct)
-  - created a common files for frontends (mc/p/mb)
-
-  2004-09-28
-
-  - added support for a new device (Unknown, vendor ID is Hyper-Paltek)
-
-  2004-09-20
-
-  - added support for a new device (Compro DVB-U2000), thanks
-    to Amaury Demol for reporting
-  - changed usb TS transfer method (several urbs, stopping transfer
-    before setting a new pid)
-
-  2004-09-13
-
-  - added support for a new device (Artec T1 USB TVBOX), thanks
-    to Christian Motschke for reporting
-
-  2004-09-05
-
-  - released the dibusb device and dib3000mb-frontend driver
-    (old news for vp7041.c)
-
-  2004-07-15
-
-  - found out, by accident, that the device has a TUA6010XS for PLL
-
-  2004-07-12
-
-  - figured out, that the driver should also work with the
-    CTS Portable (Chinese Television System)
-
-  2004-07-08
-
-  - firmware-extraction-2.422-problem solved, driver is now working
-    properly with firmware extracted from 2.422
-  - #if for 2.6.4 (dvb), compile issue
-  - changed firmware handling, see vp7041.txt sec 1.1
-
-  2004-07-02
-
-  - some tuner modifications, v0.1, cleanups, first public
-
-  2004-06-28
-
-  - now using the dvb_dmx_swfilter_packets, everything runs fine now
-
-  2004-06-27
-
-  - able to watch and switching channels (pre-alpha)
-  - no section filtering yet
-
-  2004-06-06
-
-  - first TS received, but kernel oops :/
-
-  2004-05-14
-
-  - firmware loader is working
-
-  2004-05-11
-
-  - start writing the driver
-
-How to use?
------------
-
-Firmware
-~~~~~~~~
-
-Most of the USB drivers need to download a firmware to the device before start
-working.
-
-Have a look at the Wikipage for the DVB-USB-drivers to find out, which firmware
-you need for your device:
-
-https://linuxtv.org/wiki/index.php/DVB_USB
-
-Compiling
-~~~~~~~~~
-
-Since the driver is in the linux kernel, activating the driver in
-your favorite config-environment should sufficient. I recommend
-to compile the driver as module. Hotplug does the rest.
-
-If you use dvb-kernel enter the build-2.6 directory run 'make' and 'insmod.sh
-load' afterwards.
-
-Loading the drivers
-~~~~~~~~~~~~~~~~~~~
-
-Hotplug is able to load the driver, when it is needed (because you plugged
-in the device).
-
-If you want to enable debug output, you have to load the driver manually and
-from within the dvb-kernel cvs repository.
-
-first have a look, which debug level are available:
-
-.. code-block:: none
-
-	# modinfo dvb-usb
-	# modinfo dvb-usb-vp7045
-
-	etc.
-
-.. code-block:: none
-
-	modprobe dvb-usb debug=<level>
-	modprobe dvb-usb-vp7045 debug=<level>
-	etc.
-
-should do the trick.
-
-When the driver is loaded successfully, the firmware file was in
-the right place and the device is connected, the "Power"-LED should be
-turned on.
-
-At this point you should be able to start a dvb-capable application. I'm use
-(t|s)zap, mplayer and dvbscan to test the basics. VDR-xine provides the
-long-term test scenario.
-
-Known problems and bugs
------------------------
-
-- Don't remove the USB device while running an DVB application, your system
-  will go crazy or die most likely.
-
-Adding support for devices
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-TODO
-
-USB1.1 Bandwidth limitation
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-A lot of the currently supported devices are USB1.1 and thus they have a
-maximum bandwidth of about 5-6 MBit/s when connected to a USB2.0 hub.
-This is not enough for receiving the complete transport stream of a
-DVB-T channel (which is about 16 MBit/s). Normally this is not a
-problem, if you only want to watch TV (this does not apply for HDTV),
-but watching a channel while recording another channel on the same
-frequency simply does not work very well. This applies to all USB1.1
-DVB-T devices, not just the dvb-usb-devices)
-
-The bug, where the TS is distorted by a heavy usage of the device is gone
-definitely. All dvb-usb-devices I was using (Twinhan, Kworld, DiBcom) are
-working like charm now with VDR. Sometimes I even was able to record a channel
-and watch another one.
-
-Comments
-~~~~~~~~
-
-Patches, comments and suggestions are very very welcome.
-
-3. Acknowledgements
--------------------
-
-   Amaury Demol (Amaury.Demol@parrot.com) and Francois Kanounnikoff from DiBcom for
-   providing specs, code and help, on which the dvb-dibusb, dib3000mb and
-   dib3000mc are based.
-
-   David Matthews for identifying a new device type (Artec T1 with AN2235)
-   and for extending dibusb with remote control event handling. Thank you.
-
-   Alex Woods for frequently answering question about usb and dvb
-   stuff, a big thank you.
-
-   Bernd Wagner for helping with huge bug reports and discussions.
-
-   Gunnar Wittich and Joachim von Caron for their trust for providing
-   root-shells on their machines to implement support for new devices.
-
-   Allan Third and Michael Hutchinson for their help to write the Nebula
-   digitv-driver.
-
-   Glen Harris for bringing up, that there is a new dibusb-device and Jiun-Kuei
-   Jung from AVerMedia who kindly provided a special firmware to get the device
-   up and running in Linux.
-
-   Jennifer Chen, Jeff and Jack from Twinhan for kindly supporting by
-   writing the vp7045-driver.
-
-   Steve Chang from WideView for providing information for new devices and
-   firmware files.
-
-   Michael Paxton for submitting remote control keymaps.
-
-   Some guys on the linux-dvb mailing list for encouraging me.
-
-   Peter Schildmann >peter.schildmann-nospam-at-web.de< for his
-   user-level firmware loader, which saves a lot of time
-   (when writing the vp7041 driver)
-
-   Ulf Hermenau for helping me out with traditional chinese.
-
-   André Smoktun and Christian Frömmel for supporting me with
-   hardware and listening to my problems very patiently.
diff --git a/Documentation/media/dvb-drivers/faq.rst b/Documentation/media/dvb-drivers/faq.rst
deleted file mode 100644
index 52f153d18278..000000000000
--- a/Documentation/media/dvb-drivers/faq.rst
+++ /dev/null
@@ -1,169 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-FAQ
-===
-
-.. note::
-
-   This documentation is outdated. Please check at the DVB wiki
-   at https://linuxtv.org/wiki for more updated info.
-
-Some very frequently asked questions about linuxtv-dvb
-
-1. The signal seems to die a few seconds after tuning.
-
-	It's not a bug, it's a feature. Because the frontends have
-	significant power requirements (and hence get very hot), they
-	are powered down if they are unused (i.e. if the frontend device
-	is closed). The dvb-core.o module parameter "dvb_shutdown_timeout"
-	allow you to change the timeout (default 5 seconds). Setting the
-	timeout to 0 disables the timeout feature.
-
-2. How can I watch TV?
-
-	The driver distribution includes some simple utilities which
-	are mainly intended for testing and to demonstrate how the
-	DVB API works.
-
-	Depending on whether you have a DVB-S, DVB-C or DVB-T card, use
-	apps/szap/szap, czap or tzap. You must supply a channel list
-	in ~/.[sct]zap/channels.conf. If you are lucky you can just copy
-	one of the supplied channel lists, or you can create a new one
-	by running apps/scan/scan. If you run scan on an unknown network
-	you might have to supply some start data in apps/scan/initial.h.
-
-	If you have a card with a built-in hardware MPEG-decoder the
-	drivers create a video4linux device (/dev/v4l/video0) which
-	you can use to watch TV with any v4l application. xawtv is known
-	to work. Note that you cannot change channels with xawtv, you
-	have to zap using [sct]zap. If you want a nice application for
-	TV watching and record/playback, have a look at VDR.
-
-	If your card does not have a hardware MPEG decoder you need
-	a software MPEG decoder. Mplayer or xine are known to work.
-	Newsflash: MythTV also has DVB support now.
-	Note: Only very recent versions of Mplayer and xine can decode.
-	MPEG2 transport streams (TS) directly. Then, run
-	'[sct]zap channelname -r' in one xterm, and keep it running,
-	and start 'mplayer - < /dev/dvb/adapter0/dvr0' or
-	'xine stdin://mpeg2 < /dev/dvb/adapter0/dvr0' in a second xterm.
-	That's all far from perfect, but it seems no one has written
-	a nice DVB application which includes a builtin software MPEG
-	decoder yet.
-
-	Newsflash: Newest xine directly supports DVB. Just copy your
-	channels.conf to ~/.xine and start 'xine dvb://', or select
-	the DVB button in the xine GUI. Channel switching works using the
-	numpad pgup/pgdown (NP9 / NP3) keys to scroll through the channel osd
-	menu and pressing numpad-enter to switch to the selected channel.
-
-	Note: Older versions of xine and mplayer understand MPEG program
-	streams (PS) only, and can be used in conjunction with the
-	ts2ps tool from the Metzler Brother's dvb-mpegtools package.
-
-3. Which other DVB applications exist?
-
-	http://www.cadsoft.de/people/kls/vdr/
-		Klaus Schmidinger's Video Disk Recorder
-
-	http://www.metzlerbros.org/dvb/
-		Metzler Bros. DVB development; alternate drivers and
-		DVB utilities, include dvb-mpegtools and tuxzap.
-
-	http://sourceforge.net/projects/dvbtools/
-		Dave Chapman's dvbtools package, including
-		dvbstream and dvbtune
-
-	http://www.linuxdvb.tv/
-		Henning Holtschneider's site with many interesting
-		links and docs
-
-	http://www.dbox2.info/
-		LinuxDVB on the dBox2
-
-	http://www.tuxbox.org/ and http://cvs.tuxbox.org/
-		the TuxBox CVS many interesting DVB applications and the dBox2
-		DVB source
-
-	https://linuxtv.org/downloads
-		DVB Swiss Army Knife library and utilities
-
-	http://www.nenie.org/misc/mpsys/
-		MPSYS: a MPEG2 system library and tools
-
-	http://mplayerhq.hu/
-		mplayer
-
-	http://xine.sourceforge.net/ and http://xinehq.de/
-		xine
-
-	http://www.mythtv.org/
-		MythTV - analog TV PVR, but now with DVB support, too
-		(with software MPEG decode)
-
-	http://dvbsnoop.sourceforge.net/
-		DVB sniffer program to monitor, analyze, debug, dump
-		or view dvb/mpeg/dsm-cc/mhp stream information (TS,
-		PES, SECTION)
-
-4. Can't get a signal tuned correctly
-
-	If you are using a Technotrend/Hauppauge DVB-C card *without* analog
-	module, you might have to use module parameter adac=-1 (dvb-ttpci.o).
-
-5. The dvb_net device doesn't give me any packets at all
-
-	Run tcpdump on the dvb0_0 interface. This sets the interface
-	into promiscuous mode so it accepts any packets from the PID
-	you have configured with the dvbnet utility. Check if there
-	are any packets with the IP addr and MAC addr you have
-	configured with ifconfig.
-
-	If tcpdump doesn't give you any output, check the statistics
-	which ifconfig outputs. (Note: If the MAC address is wrong,
-	dvb_net won't get any input; thus you have to run tcpdump
-	before checking the statistics.) If there are no packets at
-	all then maybe the PID is wrong. If there are error packets,
-	then either the PID is wrong or the stream does not conform to
-	the MPE standard (EN 301 192, http://www.etsi.org/). You can
-	use e.g. dvbsnoop for debugging.
-
-6. The dvb_net device doesn't give me any multicast packets
-
-	Check your routes if they include the multicast address range.
-	Additionally make sure that "source validation by reversed path
-	lookup" is disabled:
-
-.. code-block:: none
-
-	  $ "echo 0 > /proc/sys/net/ipv4/conf/dvb0/rp_filter"
-
-7. What the hell are all those modules that need to be loaded?
-
-	For a dvb-ttpci av7110 based full-featured card the following
-	modules are loaded:
-
-	- videodev: Video4Linux core module. This is the base module that
-	  gives you access to the "analog" tv picture of the av7110 mpeg2
-	  decoder.
-
-	- v4l2-common: common functions for Video4Linux-2 drivers
-
-	- v4l1-compat: backward compatibility layer for Video4Linux-1 legacy
-	  applications
-
-	- dvb-core: DVB core module. This provides you with the
-	  /dev/dvb/adapter entries
-
-	- saa7146: SAA7146 core driver. This is need to access any SAA7146
-	  based card in your system.
-
-	- saa7146_vv: SAA7146 video and vbi functions. These are only needed
-	  for full-featured cards.
-
-	- videobuf-dma-sg: capture helper module for the saa7146_vv driver. This
-	  one is responsible to handle capture buffers.
-
-	- dvb-ttpci: The main driver for AV7110 based, full-featured
-	  DVB-S/C/T cards
-
diff --git a/Documentation/media/dvb-drivers/frontends.rst b/Documentation/media/dvb-drivers/frontends.rst
deleted file mode 100644
index 7b8336ece681..000000000000
--- a/Documentation/media/dvb-drivers/frontends.rst
+++ /dev/null
@@ -1,32 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-****************
-Frontend drivers
-****************
-
-Frontend attach headers
-***********************
-
-.. Keep it on alphabetic order
-
-.. kernel-doc:: drivers/media/dvb-frontends/a8293.h
-.. kernel-doc:: drivers/media/dvb-frontends/af9013.h
-.. kernel-doc:: drivers/media/dvb-frontends/ascot2e.h
-.. kernel-doc:: drivers/media/dvb-frontends/cxd2820r.h
-.. kernel-doc:: drivers/media/dvb-frontends/drxk.h
-.. kernel-doc:: drivers/media/dvb-frontends/dvb-pll.h
-.. kernel-doc:: drivers/media/dvb-frontends/helene.h
-.. kernel-doc:: drivers/media/dvb-frontends/horus3a.h
-.. kernel-doc:: drivers/media/dvb-frontends/ix2505v.h
-.. kernel-doc:: drivers/media/dvb-frontends/m88ds3103.h
-.. kernel-doc:: drivers/media/dvb-frontends/mb86a20s.h
-.. kernel-doc:: drivers/media/dvb-frontends/mn88472.h
-.. kernel-doc:: drivers/media/dvb-frontends/rtl2830.h
-.. kernel-doc:: drivers/media/dvb-frontends/rtl2832.h
-.. kernel-doc:: drivers/media/dvb-frontends/rtl2832_sdr.h
-.. kernel-doc:: drivers/media/dvb-frontends/stb6000.h
-.. kernel-doc:: drivers/media/dvb-frontends/tda10071.h
-.. kernel-doc:: drivers/media/dvb-frontends/tda826x.h
-.. kernel-doc:: drivers/media/dvb-frontends/zd1301_demod.h
-.. kernel-doc:: drivers/media/dvb-frontends/zl10036.h
-
diff --git a/Documentation/media/dvb-drivers/index.rst b/Documentation/media/dvb-drivers/index.rst
deleted file mode 100644
index 9d3fce544f85..000000000000
--- a/Documentation/media/dvb-drivers/index.rst
+++ /dev/null
@@ -1,45 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-.. include:: <isonum.txt>
-
-##############################################
-Linux Digital TV driver-specific documentation
-##############################################
-
-**Copyright** |copy| 2001-2016 : LinuxTV Developers
-
-This documentation is free software; 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.
-
-For more details see the file COPYING in the source distribution of Linux.
-
-.. only:: html
-
-   .. class:: toc-title
-
-	Table of Contents
-
-.. toctree::
-	:maxdepth: 5
-	:numbered:
-
-	intro
-	avermedia
-	bt8xx
-	cards
-	ci
-	dvb-usb
-	faq
-	lmedm04
-	opera-firmware
-	technisat
-	ttusb-dec
-	udev
-	frontends
-	contributors
diff --git a/Documentation/media/dvb-drivers/intro.rst b/Documentation/media/dvb-drivers/intro.rst
deleted file mode 100644
index 4e361bcc3ad4..000000000000
--- a/Documentation/media/dvb-drivers/intro.rst
+++ /dev/null
@@ -1,23 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-Introduction
-============
-
-The main development site and GIT repository for these
-drivers is https://linuxtv.org.
-
-The DVB mailing list linux-dvb is hosted at vger. Please see
-http://vger.kernel.org/vger-lists.html#linux-media for details.
-
-There are also some other old lists hosted at https://linuxtv.org/lists.php. Please check the archive https://linuxtv.org/pipermail/linux-dvb/.
-
-The media subsystem Wiki is hosted at https://linuxtv.org/wiki/.
-Please check it before asking newbie questions on the list.
-
-API documentation is documented at the Kernel. You'll also find useful
-documentation at: https://linuxtv.org/docs.php.
-
-You may also find useful material at https://linuxtv.org/downloads/.
-
-In order to get firmware from proprietary drivers, there's a script at
-the kernel tree, at scripts/get_dvb_firmware.
diff --git a/Documentation/media/dvb-drivers/lmedm04.rst b/Documentation/media/dvb-drivers/lmedm04.rst
deleted file mode 100644
index a6ee33413748..000000000000
--- a/Documentation/media/dvb-drivers/lmedm04.rst
+++ /dev/null
@@ -1,107 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-Firmware files for lmedm04 cards
-================================
-
-To extract firmware for the DM04/QQBOX you need to copy the
-following file(s) to this directory.
-
-For DM04+/QQBOX LME2510C (Sharp 7395 Tuner)
--------------------------------------------
-
-The Sharp 7395 driver can be found in windows/system32/drivers
-
-US2A0D.sys (dated 17 Mar 2009)
-
-
-and run:
-
-.. code-block:: none
-
-	scripts/get_dvb_firmware lme2510c_s7395
-
-will produce dvb-usb-lme2510c-s7395.fw
-
-An alternative but older firmware can be found on the driver
-disk DVB-S_EN_3.5A in BDADriver/driver
-
-LMEBDA_DVBS7395C.sys (dated 18 Jan 2008)
-
-and run:
-
-.. code-block:: none
-
-	./get_dvb_firmware lme2510c_s7395_old
-
-will produce dvb-usb-lme2510c-s7395.fw
-
-The LG firmware can be found on the driver
-disk DM04+_5.1A[LG] in BDADriver/driver
-
-For DM04 LME2510 (LG Tuner)
----------------------------
-
-LMEBDA_DVBS.sys (dated 13 Nov 2007)
-
-and run:
-
-
-.. code-block:: none
-
-	./get_dvb_firmware lme2510_lg
-
-will produce dvb-usb-lme2510-lg.fw
-
-
-Other LG firmware can be extracted manually from US280D.sys
-only found in windows/system32/drivers
-
-dd if=US280D.sys ibs=1 skip=42360 count=3924 of=dvb-usb-lme2510-lg.fw
-
-For DM04 LME2510C (LG Tuner)
-----------------------------
-
-.. code-block:: none
-
-	dd if=US280D.sys ibs=1 skip=35200 count=3850 of=dvb-usb-lme2510c-lg.fw
-
-
-The Sharp 0194 tuner driver can be found in windows/system32/drivers
-
-US290D.sys (dated 09 Apr 2009)
-
-For LME2510
------------
-
-.. code-block:: none
-
-	dd if=US290D.sys ibs=1 skip=36856 count=3976 of=dvb-usb-lme2510-s0194.fw
-
-
-For LME2510C
-------------
-
-
-.. code-block:: none
-
-	dd if=US290D.sys ibs=1 skip=33152 count=3697 of=dvb-usb-lme2510c-s0194.fw
-
-
-The m88rs2000 tuner driver can be found in windows/system32/drivers
-
-US2B0D.sys (dated 29 Jun 2010)
-
-
-.. code-block:: none
-
-	dd if=US2B0D.sys ibs=1 skip=34432 count=3871 of=dvb-usb-lme2510c-rs2000.fw
-
-We need to modify id of rs2000 firmware or it will warm boot id 3344:1120.
-
-
-.. code-block:: none
-
-
-	echo -ne \\xF0\\x22 | dd conv=notrunc bs=1 count=2 seek=266 of=dvb-usb-lme2510c-rs2000.fw
-
-Copy the firmware file(s) to /lib/firmware
diff --git a/Documentation/media/dvb-drivers/opera-firmware.rst b/Documentation/media/dvb-drivers/opera-firmware.rst
deleted file mode 100644
index fab3581551de..000000000000
--- a/Documentation/media/dvb-drivers/opera-firmware.rst
+++ /dev/null
@@ -1,33 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-Opera firmware
-==============
-
-Author: Marco Gittler <g.marco@freenet.de>
-
-To extract the firmware for the Opera DVB-S1 USB-Box
-you need to copy the files:
-
-2830SCap2.sys
-2830SLoad2.sys
-
-from the windriver disk into this directory.
-
-Then run:
-
-.. code-block:: none
-
-	scripts/get_dvb_firmware opera1
-
-and after that you have 2 files:
-
-dvb-usb-opera-01.fw
-dvb-usb-opera1-fpga-01.fw
-
-in here.
-
-Copy them into /lib/firmware/ .
-
-After that the driver can load the firmware
-(if you have enabled firmware loading
-in kernel config and have hotplug running).
diff --git a/Documentation/media/dvb-drivers/technisat.rst b/Documentation/media/dvb-drivers/technisat.rst
deleted file mode 100644
index 9eaa12366bbf..000000000000
--- a/Documentation/media/dvb-drivers/technisat.rst
+++ /dev/null
@@ -1,100 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-How to set up the Technisat/B2C2 Flexcop devices
-================================================
-
-.. note::
-
-   This documentation is outdated.
-
-Author: Uwe Bugla <uwe.bugla@gmx.de> August 2009
-
-Find out what device you have
------------------------------
-
-Important Notice: The driver does NOT support Technisat USB 2 devices!
-
-First start your linux box with a shipped kernel:
-
-.. code-block:: none
-
-	lspci -vvv for a PCI device (lsusb -vvv for an USB device) will show you for example:
-	02:0b.0 Network controller: Techsan Electronics Co Ltd B2C2 FlexCopII DVB chip /
-	Technisat SkyStar2 DVB card (rev 02)
-
-	dmesg | grep frontend may show you for example:
-	DVB: registering frontend 0 (Conexant CX24123/CX24109)...
-
-Kernel compilation:
--------------------
-
-If the Flexcop / Technisat is the only DVB / TV / Radio device in your box
-get rid of unnecessary modules and check this one:
-
-``Multimedia support`` => ``Customise analog and hybrid tuner modules to build``
-
-In this directory uncheck every driver which is activated there
-(except ``Simple tuner support`` for ATSC 3rd generation only -> see case 9 please).
-
-Then please activate:
-
-- Main module part:
-
-  ``Multimedia support`` => ``DVB/ATSC adapters`` => ``Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters``
-
-  #) => ``Technisat/B2C2 Air/Sky/Cable2PC PCI`` (PCI card) or
-  #) => ``Technisat/B2C2 Air/Sky/Cable2PC USB`` (USB 1.1 adapter)
-     and for troubleshooting purposes:
-  #) => ``Enable debug for the B2C2 FlexCop drivers``
-
-- Frontend / Tuner / Demodulator module part:
-
-  ``Multimedia support`` => ``DVB/ATSC adapters``
-   => ``Customise the frontend modules to build`` ``Customise DVB frontends`` =>
-
-  - SkyStar DVB-S Revision 2.3:
-
-    #) => ``Zarlink VP310/MT312/ZL10313 based``
-    #) => ``Generic I2C PLL based tuners``
-
-  - SkyStar DVB-S Revision 2.6:
-
-    #) => ``ST STV0299 based``
-    #) => ``Generic I2C PLL based tuners``
-
-  - SkyStar DVB-S Revision 2.7:
-
-    #) => ``Samsung S5H1420 based``
-    #) => ``Integrant ITD1000 Zero IF tuner for DVB-S/DSS``
-    #) => ``ISL6421 SEC controller``
-
-  - SkyStar DVB-S Revision 2.8:
-
-    #) => ``Conexant CX24123 based``
-    #) => ``Conexant CX24113/CX24128 tuner for DVB-S/DSS``
-    #) => ``ISL6421 SEC controller``
-
-  - AirStar DVB-T card:
-
-    #) => ``Zarlink MT352 based``
-    #) => ``Generic I2C PLL based tuners``
-
-  - CableStar DVB-C card:
-
-    #) => ``ST STV0297 based``
-    #) => ``Generic I2C PLL based tuners``
-
-  - AirStar ATSC card 1st generation:
-
-    #) => ``Broadcom BCM3510``
-
-  - AirStar ATSC card 2nd generation:
-
-    #) => ``NxtWave Communications NXT2002/NXT2004 based``
-    #) => ``Generic I2C PLL based tuners``
-
-  - AirStar ATSC card 3rd generation:
-
-    #) => ``LG Electronics LGDT3302/LGDT3303 based``
-    #) ``Multimedia support`` => ``Customise analog and hybrid tuner modules to build`` => ``Simple tuner support``
-
diff --git a/Documentation/media/dvb-drivers/ttusb-dec.rst b/Documentation/media/dvb-drivers/ttusb-dec.rst
deleted file mode 100644
index 516bbab8a872..000000000000
--- a/Documentation/media/dvb-drivers/ttusb-dec.rst
+++ /dev/null
@@ -1,45 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-TechnoTrend/Hauppauge DEC USB Driver
-====================================
-
-Driver Status
--------------
-
-Supported:
-
-	- DEC2000-t
-	- DEC2450-t
-	- DEC3000-s
-	- Video Streaming
-	- Audio Streaming
-	- Section Filters
-	- Channel Zapping
-	- Hotplug firmware loader
-
-To Do:
-
-	- Tuner status information
-	- DVB network interface
-	- Streaming video PC->DEC
-	- Conax support for 2450-t
-
-Getting the Firmware
---------------------
-To download the firmware, use the following commands:
-
-.. code-block:: none
-
-	scripts/get_dvb_firmware dec2000t
-	scripts/get_dvb_firmware dec2540t
-	scripts/get_dvb_firmware dec3000s
-
-
-Hotplug Firmware Loading
-------------------------
-
-Since 2.6 kernels, the firmware is loaded at the point that the driver module
-is loaded.
-
-Copy the three files downloaded above into the /usr/lib/hotplug/firmware or
-/lib/firmware directory (depending on configuration of firmware hotplug).
diff --git a/Documentation/media/dvb-drivers/udev.rst b/Documentation/media/dvb-drivers/udev.rst
deleted file mode 100644
index ca6c9c226902..000000000000
--- a/Documentation/media/dvb-drivers/udev.rst
+++ /dev/null
@@ -1,63 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-UDEV rules for DVB
-==================
-
-.. note::
-
-   #) This documentation is outdated. Udev on modern distributions auto-detect
-      the DVB devices.
-
-   #) **TODO:** change this document to explain how to make DVB devices
-      persistent, as, when a machine has multiple devices, they may be detected
-      on different orders, which could cause apps that relies on the device
-      numbers to fail.
-
-The DVB subsystem currently registers to the sysfs subsystem using the
-"class_simple" interface.
-
-This means that only the basic information like module loading parameters
-are presented through sysfs. Other things that might be interesting are
-currently **not** available.
-
-Nevertheless it's now possible to add proper udev rules so that the
-DVB device nodes are created automatically.
-
-We assume that you have udev already up and running and that have been
-creating the DVB device nodes manually up to now due to the missing sysfs
-support.
-
-0. Don't forget to disable your current method of creating the
-device nodes manually.
-
-1. Unfortunately, you'll need a helper script to transform the kernel
-sysfs device name into the well known dvb adapter / device naming scheme.
-The script should be called "dvb.sh" and should be placed into a script
-dir where udev can execute it, most likely /etc/udev/scripts/
-
-So, create a new file /etc/udev/scripts/dvb.sh and add the following:
-
-.. code-block:: none
-
-	#!/bin/sh
-	/bin/echo $1 | /bin/sed -e 's,dvb\([0-9]\)\.\([^0-9]*\)\([0-9]\),dvb/adapter\1/\2\3,'
-
-Don't forget to make the script executable with "chmod".
-
-1. You need to create a proper udev rule that will create the device nodes
-like you know them. All real distributions out there scan the /etc/udev/rules.d
-directory for rule files. The main udev configuration file /etc/udev/udev.conf
-will tell you the directory where the rules are, most likely it's /etc/udev/rules.d/
-
-Create a new rule file in that directory called "dvb.rule" and add the following line:
-
-.. code-block:: none
-
-	KERNEL="dvb*", PROGRAM="/etc/udev/scripts/dvb.sh %k", NAME="%c"
-
-If you want more control over the device nodes (for example a special group membership)
-have a look at "man udev".
-
-For every device that registers to the sysfs subsystem with a "dvb" prefix,
-the helper script /etc/udev/scripts/dvb.sh is invoked, which will then
-create the proper device node in your /dev/ directory.
diff --git a/Documentation/media/frontend.h.rst.exceptions b/Documentation/media/frontend.h.rst.exceptions
deleted file mode 100644
index 6283702c08c8..000000000000
--- a/Documentation/media/frontend.h.rst.exceptions
+++ /dev/null
@@ -1,214 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-# Ignore header name
-ignore define _DVBFRONTEND_H_
-
-# Group layer A-C symbols together
-replace define DTV_ISDBT_LAYERA_FEC dtv-isdbt-layer-fec
-replace define DTV_ISDBT_LAYERB_FEC dtv-isdbt-layer-fec
-replace define DTV_ISDBT_LAYERC_FEC dtv-isdbt-layer-fec
-replace define DTV_ISDBT_LAYERA_MODULATION dtv-isdbt-layer-modulation
-replace define DTV_ISDBT_LAYERB_MODULATION dtv-isdbt-layer-modulation
-replace define DTV_ISDBT_LAYERC_MODULATION dtv-isdbt-layer-modulation
-replace define DTV_ISDBT_LAYERA_SEGMENT_COUNT dtv-isdbt-layer-segment-count
-replace define DTV_ISDBT_LAYERB_SEGMENT_COUNT dtv-isdbt-layer-segment-count
-replace define DTV_ISDBT_LAYERC_SEGMENT_COUNT dtv-isdbt-layer-segment-count
-replace define DTV_ISDBT_LAYERA_TIME_INTERLEAVING dtv-isdbt-layer-time-interleaving
-replace define DTV_ISDBT_LAYERB_TIME_INTERLEAVING dtv-isdbt-layer-time-interleaving
-replace define DTV_ISDBT_LAYERC_TIME_INTERLEAVING dtv-isdbt-layer-time-interleaving
-
-# Ignore legacy defines
-ignore define DTV_ISDBS_TS_ID_LEGACY
-ignore define SYS_DVBC_ANNEX_AC
-ignore define SYS_DMBTH
-
-# Ignore limits
-ignore define DTV_MAX_COMMAND
-ignore define MAX_DTV_STATS
-ignore define DTV_IOCTL_MAX_MSGS
-
-# the same reference is used for both get and set ioctls
-replace ioctl FE_SET_PROPERTY :c:type:`FE_GET_PROPERTY`
-
-# Typedefs that use the enum reference
-replace typedef fe_sec_voltage_t :c:type:`fe_sec_voltage`
-
-# Replaces for flag constants
-replace define FE_TUNE_MODE_ONESHOT :c:func:`FE_SET_FRONTEND_TUNE_MODE`
-replace define LNA_AUTO dtv-lna
-replace define NO_STREAM_ID_FILTER dtv-stream-id
-
-# Those enums are defined at the frontend.h header, and not externally
-
-ignore symbol FE_IS_STUPID
-ignore symbol FE_CAN_INVERSION_AUTO
-ignore symbol FE_CAN_FEC_1_2
-ignore symbol FE_CAN_FEC_2_3
-ignore symbol FE_CAN_FEC_3_4
-ignore symbol FE_CAN_FEC_4_5
-ignore symbol FE_CAN_FEC_5_6
-ignore symbol FE_CAN_FEC_6_7
-ignore symbol FE_CAN_FEC_7_8
-ignore symbol FE_CAN_FEC_8_9
-ignore symbol FE_CAN_FEC_AUTO
-ignore symbol FE_CAN_QPSK
-ignore symbol FE_CAN_QAM_16
-ignore symbol FE_CAN_QAM_32
-ignore symbol FE_CAN_QAM_64
-ignore symbol FE_CAN_QAM_128
-ignore symbol FE_CAN_QAM_256
-ignore symbol FE_CAN_QAM_AUTO
-ignore symbol FE_CAN_TRANSMISSION_MODE_AUTO
-ignore symbol FE_CAN_BANDWIDTH_AUTO
-ignore symbol FE_CAN_GUARD_INTERVAL_AUTO
-ignore symbol FE_CAN_HIERARCHY_AUTO
-ignore symbol FE_CAN_8VSB
-ignore symbol FE_CAN_16VSB
-ignore symbol FE_HAS_EXTENDED_CAPS
-ignore symbol FE_CAN_MULTISTREAM
-ignore symbol FE_CAN_TURBO_FEC
-ignore symbol FE_CAN_2G_MODULATION
-ignore symbol FE_NEEDS_BENDING
-ignore symbol FE_CAN_RECOVER
-ignore symbol FE_CAN_MUTE_TS
-
-ignore symbol QPSK
-ignore symbol QAM_16
-ignore symbol QAM_32
-ignore symbol QAM_64
-ignore symbol QAM_128
-ignore symbol QAM_256
-ignore symbol QAM_AUTO
-ignore symbol VSB_8
-ignore symbol VSB_16
-ignore symbol PSK_8
-ignore symbol APSK_16
-ignore symbol APSK_32
-ignore symbol DQPSK
-ignore symbol QAM_4_NR
-
-ignore symbol SEC_VOLTAGE_13
-ignore symbol SEC_VOLTAGE_18
-ignore symbol SEC_VOLTAGE_OFF
-
-ignore symbol SEC_TONE_ON
-ignore symbol SEC_TONE_OFF
-
-ignore symbol SEC_MINI_A
-ignore symbol SEC_MINI_B
-
-ignore symbol FE_NONE
-ignore symbol FE_HAS_SIGNAL
-ignore symbol FE_HAS_CARRIER
-ignore symbol FE_HAS_VITERBI
-ignore symbol FE_HAS_SYNC
-ignore symbol FE_HAS_LOCK
-ignore symbol FE_REINIT
-ignore symbol FE_TIMEDOUT
-
-ignore symbol FEC_NONE
-ignore symbol FEC_1_2
-ignore symbol FEC_2_3
-ignore symbol FEC_3_4
-ignore symbol FEC_4_5
-ignore symbol FEC_5_6
-ignore symbol FEC_6_7
-ignore symbol FEC_7_8
-ignore symbol FEC_8_9
-ignore symbol FEC_AUTO
-ignore symbol FEC_3_5
-ignore symbol FEC_9_10
-ignore symbol FEC_2_5
-
-ignore symbol TRANSMISSION_MODE_AUTO
-ignore symbol TRANSMISSION_MODE_1K
-ignore symbol TRANSMISSION_MODE_2K
-ignore symbol TRANSMISSION_MODE_8K
-ignore symbol TRANSMISSION_MODE_4K
-ignore symbol TRANSMISSION_MODE_16K
-ignore symbol TRANSMISSION_MODE_32K
-ignore symbol TRANSMISSION_MODE_C1
-ignore symbol TRANSMISSION_MODE_C3780
-ignore symbol TRANSMISSION_MODE_2K
-ignore symbol TRANSMISSION_MODE_8K
-
-ignore symbol GUARD_INTERVAL_AUTO
-ignore symbol GUARD_INTERVAL_1_128
-ignore symbol GUARD_INTERVAL_1_32
-ignore symbol GUARD_INTERVAL_1_16
-ignore symbol GUARD_INTERVAL_1_8
-ignore symbol GUARD_INTERVAL_1_4
-ignore symbol GUARD_INTERVAL_19_128
-ignore symbol GUARD_INTERVAL_19_256
-ignore symbol GUARD_INTERVAL_PN420
-ignore symbol GUARD_INTERVAL_PN595
-ignore symbol GUARD_INTERVAL_PN945
-
-ignore symbol HIERARCHY_NONE
-ignore symbol HIERARCHY_AUTO
-ignore symbol HIERARCHY_1
-ignore symbol HIERARCHY_2
-ignore symbol HIERARCHY_4
-
-ignore symbol INTERLEAVING_NONE
-ignore symbol INTERLEAVING_AUTO
-ignore symbol INTERLEAVING_240
-ignore symbol INTERLEAVING_720
-
-ignore symbol PILOT_ON
-ignore symbol PILOT_OFF
-ignore symbol PILOT_AUTO
-
-ignore symbol ROLLOFF_35
-ignore symbol ROLLOFF_20
-ignore symbol ROLLOFF_25
-ignore symbol ROLLOFF_AUTO
-
-ignore symbol INVERSION_ON
-ignore symbol INVERSION_OFF
-ignore symbol INVERSION_AUTO
-
-ignore symbol SYS_UNDEFINED
-ignore symbol SYS_DVBC_ANNEX_A
-ignore symbol SYS_DVBC_ANNEX_B
-ignore symbol SYS_DVBC_ANNEX_C
-ignore symbol SYS_ISDBC
-ignore symbol SYS_DVBT
-ignore symbol SYS_DVBT2
-ignore symbol SYS_ISDBT
-ignore symbol SYS_ATSC
-ignore symbol SYS_ATSCMH
-ignore symbol SYS_DTMB
-ignore symbol SYS_DVBS
-ignore symbol SYS_DVBS2
-ignore symbol SYS_TURBO
-ignore symbol SYS_ISDBS
-ignore symbol SYS_DAB
-ignore symbol SYS_DSS
-ignore symbol SYS_CMMB
-ignore symbol SYS_DVBH
-
-ignore symbol ATSCMH_SCCC_BLK_SEP
-ignore symbol ATSCMH_SCCC_BLK_COMB
-ignore symbol ATSCMH_SCCC_BLK_RES
-
-ignore symbol ATSCMH_SCCC_CODE_HLF
-ignore symbol ATSCMH_SCCC_CODE_QTR
-ignore symbol ATSCMH_SCCC_CODE_RES
-
-ignore symbol ATSCMH_RSFRAME_ENS_PRI
-ignore symbol ATSCMH_RSFRAME_ENS_SEC
-
-ignore symbol ATSCMH_RSFRAME_PRI_ONLY
-ignore symbol ATSCMH_RSFRAME_PRI_SEC
-ignore symbol ATSCMH_RSFRAME_RES
-
-ignore symbol ATSCMH_RSCODE_211_187
-ignore symbol ATSCMH_RSCODE_223_187
-ignore symbol ATSCMH_RSCODE_235_187
-ignore symbol ATSCMH_RSCODE_RES
-
-ignore symbol FE_SCALE_NOT_AVAILABLE
-ignore symbol FE_SCALE_DECIBEL
-ignore symbol FE_SCALE_RELATIVE
-ignore symbol FE_SCALE_COUNTER
diff --git a/Documentation/media/index.rst b/Documentation/media/index.rst
deleted file mode 100644
index 0301c25ff887..000000000000
--- a/Documentation/media/index.rst
+++ /dev/null
@@ -1,26 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-Linux Media Subsystem Documentation
-===================================
-
-.. only:: html
-
-   .. class:: toc-title
-
-        Table of Contents
-
-.. toctree::
-   :maxdepth: 2
-
-   media_uapi
-   media_kapi
-   dvb-drivers/index
-   v4l-drivers/index
-   cec-drivers/index
-
-.. only:: html and subproject
-
-   Indices
-   =======
-
-   * :ref:`genindex`
diff --git a/Documentation/media/intro.rst b/Documentation/media/intro.rst
deleted file mode 100644
index 4a6bd665b884..000000000000
--- a/Documentation/media/intro.rst
+++ /dev/null
@@ -1,46 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-============
-Introduction
-============
-
-This document covers the Linux Kernel to Userspace API's used by video
-and radio streaming devices, including video cameras, analog and digital
-TV receiver cards, AM/FM receiver cards, Software Defined Radio (SDR),
-streaming capture and output devices, codec devices and remote controllers.
-
-A typical media device hardware is shown at :ref:`typical_media_device`.
-
-.. _typical_media_device:
-
-.. kernel-figure:: typical_media_device.svg
-    :alt:   typical_media_device.svg
-    :align: center
-
-    Typical Media Device
-
-The media infrastructure API was designed to control such devices. It is
-divided into five parts.
-
-1. The :ref:`first part <v4l2spec>` covers radio, video capture and output,
-   cameras, analog TV devices and codecs.
-
-2. The :ref:`second part <dvbapi>` covers the API used for digital TV and
-   Internet reception via one of the several digital tv standards. While it is
-   called as DVB API, in fact it covers several different video standards
-   including DVB-T/T2, DVB-S/S2, DVB-C, ATSC, ISDB-T, ISDB-S, DTMB, etc. The
-   complete list of supported standards can be found at
-   :c:type:`fe_delivery_system`.
-
-3. The :ref:`third part <remote_controllers>` covers the Remote Controller API.
-
-4. The :ref:`fourth part <media_controller>` covers the Media Controller API.
-
-5. The :ref:`fifth part <cec>` covers the CEC (Consumer Electronics Control) API.
-
-It should also be noted that a media device may also have audio components, like
-mixers, PCM capture, PCM playback, etc, which are controlled via ALSA API.  For
-additional information and for the latest development code, see:
-`https://linuxtv.org <https://linuxtv.org>`__.  For discussing improvements,
-reporting troubles, sending new drivers, etc, please mail to: `Linux Media
-Mailing List (LMML) <http://vger.kernel.org/vger-lists.html#linux-media>`__.
diff --git a/Documentation/media/kapi/cec-core.rst b/Documentation/media/kapi/cec-core.rst
deleted file mode 100644
index 3ce26b7c2b2b..000000000000
--- a/Documentation/media/kapi/cec-core.rst
+++ /dev/null
@@ -1,474 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-CEC Kernel Support
-==================
-
-The CEC framework provides a unified kernel interface for use with HDMI CEC
-hardware. It is designed to handle a multiple types of hardware (receivers,
-transmitters, USB dongles). The framework also gives the option to decide
-what to do in the kernel driver and what should be handled by userspace
-applications. In addition it integrates the remote control passthrough
-feature into the kernel's remote control framework.
-
-
-The CEC Protocol
-----------------
-
-The CEC protocol enables consumer electronic devices to communicate with each
-other through the HDMI connection. The protocol uses logical addresses in the
-communication. The logical address is strictly connected with the functionality
-provided by the device. The TV acting as the communication hub is always
-assigned address 0. The physical address is determined by the physical
-connection between devices.
-
-The CEC framework described here is up to date with the CEC 2.0 specification.
-It is documented in the HDMI 1.4 specification with the new 2.0 bits documented
-in the HDMI 2.0 specification. But for most of the features the freely available
-HDMI 1.3a specification is sufficient:
-
-http://www.microprocessor.org/HDMISpecification13a.pdf
-
-
-CEC Adapter Interface
----------------------
-
-The struct cec_adapter represents the CEC adapter hardware. It is created by
-calling cec_allocate_adapter() and deleted by calling cec_delete_adapter():
-
-.. c:function::
-   struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, void *priv,
-   const char *name, u32 caps, u8 available_las);
-
-.. c:function::
-   void cec_delete_adapter(struct cec_adapter *adap);
-
-To create an adapter you need to pass the following information:
-
-ops:
-	adapter operations which are called by the CEC framework and that you
-	have to implement.
-
-priv:
-	will be stored in adap->priv and can be used by the adapter ops.
-	Use cec_get_drvdata(adap) to get the priv pointer.
-
-name:
-	the name of the CEC adapter. Note: this name will be copied.
-
-caps:
-	capabilities of the CEC adapter. These capabilities determine the
-	capabilities of the hardware and which parts are to be handled
-	by userspace and which parts are handled by kernelspace. The
-	capabilities are returned by CEC_ADAP_G_CAPS.
-
-available_las:
-	the number of simultaneous logical addresses that this
-	adapter can handle. Must be 1 <= available_las <= CEC_MAX_LOG_ADDRS.
-
-To obtain the priv pointer use this helper function:
-
-.. c:function::
-	void *cec_get_drvdata(const struct cec_adapter *adap);
-
-To register the /dev/cecX device node and the remote control device (if
-CEC_CAP_RC is set) you call:
-
-.. c:function::
-	int cec_register_adapter(struct cec_adapter *adap, struct device *parent);
-
-where parent is the parent device.
-
-To unregister the devices call:
-
-.. c:function::
-	void cec_unregister_adapter(struct cec_adapter *adap);
-
-Note: if cec_register_adapter() fails, then call cec_delete_adapter() to
-clean up. But if cec_register_adapter() succeeded, then only call
-cec_unregister_adapter() to clean up, never cec_delete_adapter(). The
-unregister function will delete the adapter automatically once the last user
-of that /dev/cecX device has closed its file handle.
-
-
-Implementing the Low-Level CEC Adapter
---------------------------------------
-
-The following low-level adapter operations have to be implemented in
-your driver:
-
-.. c:type:: struct cec_adap_ops
-
-.. code-block:: none
-
-	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);
-		void (*adap_status)(struct cec_adapter *adap, struct seq_file *file);
-		void (*adap_free)(struct cec_adapter *adap);
-
-		/* Error injection callbacks */
-		...
-
-		/* High-level callbacks */
-		...
-	};
-
-The seven low-level ops deal with various aspects of controlling the CEC adapter
-hardware:
-
-
-To enable/disable the hardware:
-
-.. c:function::
-	int (*adap_enable)(struct cec_adapter *adap, bool enable);
-
-This callback enables or disables the CEC hardware. Enabling the CEC hardware
-means powering it up in a state where no logical addresses are claimed. This
-op assumes that the physical address (adap->phys_addr) is valid when enable is
-true and will not change while the CEC adapter remains enabled. The initial
-state of the CEC adapter after calling cec_allocate_adapter() is disabled.
-
-Note that adap_enable must return 0 if enable is false.
-
-
-To enable/disable the 'monitor all' mode:
-
-.. c:function::
-	int (*adap_monitor_all_enable)(struct cec_adapter *adap, bool enable);
-
-If enabled, then the adapter should be put in a mode to also monitor messages
-that not for us. Not all hardware supports this and this function is only
-called if the CEC_CAP_MONITOR_ALL capability is set. This callback is optional
-(some hardware may always be in 'monitor all' mode).
-
-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::
-	int (*adap_log_addr)(struct cec_adapter *adap, u8 logical_addr);
-
-If logical_addr == CEC_LOG_ADDR_INVALID then all programmed logical addresses
-are to be erased. Otherwise the given logical address should be programmed.
-If the maximum number of available logical addresses is exceeded, then it
-should return -ENXIO. Once a logical address is programmed the CEC hardware
-can receive directed messages to that address.
-
-Note that adap_log_addr must return 0 if logical_addr is CEC_LOG_ADDR_INVALID.
-
-
-To transmit a new message:
-
-.. c:function::
-	int (*adap_transmit)(struct cec_adapter *adap, u8 attempts,
-			     u32 signal_free_time, struct cec_msg *msg);
-
-This transmits a new message. The attempts argument is the suggested number of
-attempts for the transmit.
-
-The signal_free_time is the number of data bit periods that the adapter should
-wait when the line is free before attempting to send a message. This value
-depends on whether this transmit is a retry, a message from a new initiator or
-a new message for the same initiator. Most hardware will handle this
-automatically, but in some cases this information is needed.
-
-The CEC_FREE_TIME_TO_USEC macro can be used to convert signal_free_time to
-microseconds (one data bit period is 2.4 ms).
-
-
-To log the current CEC hardware status:
-
-.. c:function::
-	void (*adap_status)(struct cec_adapter *adap, struct seq_file *file);
-
-This optional callback can be used to show the status of the CEC hardware.
-The status is available through debugfs: cat /sys/kernel/debug/cec/cecX/status
-
-To free any resources when the adapter is deleted:
-
-.. c:function::
-	void (*adap_free)(struct cec_adapter *adap);
-
-This optional callback can be used to free any resources that might have been
-allocated by the driver. It's called from cec_delete_adapter.
-
-
-Your adapter driver will also have to react to events (typically interrupt
-driven) by calling into the framework in the following situations:
-
-When a transmit finished (successfully or otherwise):
-
-.. c:function::
-	void cec_transmit_done(struct cec_adapter *adap, u8 status, u8 arb_lost_cnt,
-		       u8 nack_cnt, u8 low_drive_cnt, u8 error_cnt);
-
-or:
-
-.. c:function::
-	void cec_transmit_attempt_done(struct cec_adapter *adap, u8 status);
-
-The status can be one of:
-
-CEC_TX_STATUS_OK:
-	the transmit was successful.
-
-CEC_TX_STATUS_ARB_LOST:
-	arbitration was lost: another CEC initiator
-	took control of the CEC line and you lost the arbitration.
-
-CEC_TX_STATUS_NACK:
-	the message was nacked (for a directed message) or
-	acked (for a broadcast message). A retransmission is needed.
-
-CEC_TX_STATUS_LOW_DRIVE:
-	low drive was detected on the CEC bus. This indicates that
-	a follower detected an error on the bus and requested a
-	retransmission.
-
-CEC_TX_STATUS_ERROR:
-	some unspecified error occurred: this can be one of ARB_LOST
-	or LOW_DRIVE if the hardware cannot differentiate or something
-	else entirely. Some hardware only supports OK and FAIL as the
-	result of a transmit, i.e. there is no way to differentiate
-	between the different possible errors. In that case map FAIL
-	to CEC_TX_STATUS_NACK and not to CEC_TX_STATUS_ERROR.
-
-CEC_TX_STATUS_MAX_RETRIES:
-	could not transmit the message after trying multiple times.
-	Should only be set by the driver if it has hardware support for
-	retrying messages. If set, then the framework assumes that it
-	doesn't have to make another attempt to transmit the message
-	since the hardware did that already.
-
-The hardware must be able to differentiate between OK, NACK and 'something
-else'.
-
-The \*_cnt arguments are the number of error conditions that were seen.
-This may be 0 if no information is available. Drivers that do not support
-hardware retry can just set the counter corresponding to the transmit error
-to 1, if the hardware does support retry then either set these counters to
-0 if the hardware provides no feedback of which errors occurred and how many
-times, or fill in the correct values as reported by the hardware.
-
-Be aware that calling these functions can immediately start a new transmit
-if there is one pending in the queue. So make sure that the hardware is in
-a state where new transmits can be started *before* calling these functions.
-
-The cec_transmit_attempt_done() function is a helper for cases where the
-hardware never retries, so the transmit is always for just a single
-attempt. It will call cec_transmit_done() in turn, filling in 1 for the
-count argument corresponding to the status. Or all 0 if the status was OK.
-
-When a CEC message was received:
-
-.. c:function::
-	void cec_received_msg(struct cec_adapter *adap, struct cec_msg *msg);
-
-Speaks for itself.
-
-Implementing the interrupt handler
-----------------------------------
-
-Typically the CEC hardware provides interrupts that signal when a transmit
-finished and whether it was successful or not, and it provides and interrupt
-when a CEC message was received.
-
-The CEC driver should always process the transmit interrupts first before
-handling the receive interrupt. The framework expects to see the cec_transmit_done
-call before the cec_received_msg call, otherwise it can get confused if the
-received message was in reply to the transmitted message.
-
-Optional: Implementing Error Injection Support
-----------------------------------------------
-
-If the CEC adapter supports Error Injection functionality, then that can
-be exposed through the Error Injection callbacks:
-
-.. code-block:: none
-
-	struct cec_adap_ops {
-		/* Low-level callbacks */
-		...
-
-		/* Error injection callbacks */
-		int (*error_inj_show)(struct cec_adapter *adap, struct seq_file *sf);
-		bool (*error_inj_parse_line)(struct cec_adapter *adap, char *line);
-
-		/* High-level CEC message callback */
-		...
-	};
-
-If both callbacks are set, then an ``error-inj`` file will appear in debugfs.
-The basic syntax is as follows:
-
-Leading spaces/tabs are ignored. If the next character is a ``#`` or the end of the
-line was reached, then the whole line is ignored. Otherwise a command is expected.
-
-This basic parsing is done in the CEC Framework. It is up to the driver to decide
-what commands to implement. The only requirement is that the command ``clear`` without
-any arguments must be implemented and that it will remove all current error injection
-commands.
-
-This ensures that you can always do ``echo clear >error-inj`` to clear any error
-injections without having to know the details of the driver-specific commands.
-
-Note that the output of ``error-inj`` shall be valid as input to ``error-inj``.
-So this must work:
-
-.. code-block:: none
-
-	$ cat error-inj >einj.txt
-	$ cat einj.txt >error-inj
-
-The first callback is called when this file is read and it should show the
-the current error injection state:
-
-.. c:function::
-	int (*error_inj_show)(struct cec_adapter *adap, struct seq_file *sf);
-
-It is recommended that it starts with a comment block with basic usage
-information. It returns 0 for success and an error otherwise.
-
-The second callback will parse commands written to the ``error-inj`` file:
-
-.. c:function::
-	bool (*error_inj_parse_line)(struct cec_adapter *adap, char *line);
-
-The ``line`` argument points to the start of the command. Any leading
-spaces or tabs have already been skipped. It is a single line only (so there
-are no embedded newlines) and it is 0-terminated. The callback is free to
-modify the contents of the buffer. It is only called for lines containing a
-command, so this callback is never called for empty lines or comment lines.
-
-Return true if the command was valid or false if there were syntax errors.
-
-Implementing the High-Level CEC Adapter
----------------------------------------
-
-The low-level operations drive the hardware, the high-level operations are
-CEC protocol driven. The following high-level callbacks are available:
-
-.. code-block:: none
-
-	struct cec_adap_ops {
-		/* Low-level callbacks */
-		...
-
-		/* Error injection callbacks */
-		...
-
-		/* High-level CEC message callback */
-		int (*received)(struct cec_adapter *adap, struct cec_msg *msg);
-	};
-
-The received() callback allows the driver to optionally handle a newly
-received CEC message
-
-.. c:function::
-	int (*received)(struct cec_adapter *adap, struct cec_msg *msg);
-
-If the driver wants to process a CEC message, then it can implement this
-callback. If it doesn't want to handle this message, then it should return
--ENOMSG, otherwise the CEC framework assumes it processed this message and
-it will not do anything with it.
-
-
-CEC framework functions
------------------------
-
-CEC Adapter drivers can call the following CEC framework functions:
-
-.. c:function::
-	int cec_transmit_msg(struct cec_adapter *adap, struct cec_msg *msg,
-			     bool block);
-
-Transmit a CEC message. If block is true, then wait until the message has been
-transmitted, otherwise just queue it and return.
-
-.. c:function::
-	void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr,
-			     bool block);
-
-Change the physical address. This function will set adap->phys_addr and
-send an event if it has changed. If cec_s_log_addrs() has been called and
-the physical address has become valid, then the CEC framework will start
-claiming the logical addresses. If block is true, then this function won't
-return until this process has finished.
-
-When the physical address is set to a valid value the CEC adapter will
-be enabled (see the adap_enable op). When it is set to CEC_PHYS_ADDR_INVALID,
-then the CEC adapter will be disabled. If you change a valid physical address
-to another valid physical address, then this function will first set the
-address to CEC_PHYS_ADDR_INVALID before enabling the new physical address.
-
-.. c:function::
-	void cec_s_phys_addr_from_edid(struct cec_adapter *adap,
-				       const struct edid *edid);
-
-A helper function that extracts the physical address from the edid struct
-and calls cec_s_phys_addr() with that address, or CEC_PHYS_ADDR_INVALID
-if the EDID did not contain a physical address or edid was a NULL pointer.
-
-.. c:function::
-	int cec_s_log_addrs(struct cec_adapter *adap,
-			    struct cec_log_addrs *log_addrs, bool block);
-
-Claim the CEC logical addresses. Should never be called if CEC_CAP_LOG_ADDRS
-is set. If block is true, then wait until the logical addresses have been
-claimed, otherwise just queue it and return. To unconfigure all logical
-addresses call this function with log_addrs set to NULL or with
-log_addrs->num_log_addrs set to 0. The block argument is ignored when
-unconfiguring. This function will just return if the physical address is
-invalid. Once the physical address becomes valid, then the framework will
-attempt to claim these logical addresses.
-
-CEC Pin framework
------------------
-
-Most CEC hardware operates on full CEC messages where the software provides
-the message and the hardware handles the low-level CEC protocol. But some
-hardware only drives the CEC pin and software has to handle the low-level
-CEC protocol. The CEC pin framework was created to handle such devices.
-
-Note that due to the close-to-realtime requirements it can never be guaranteed
-to work 100%. This framework uses highres timers internally, but if a
-timer goes off too late by more than 300 microseconds wrong results can
-occur. In reality it appears to be fairly reliable.
-
-One advantage of this low-level implementation is that it can be used as
-a cheap CEC analyser, especially if interrupts can be used to detect
-CEC pin transitions from low to high or vice versa.
-
-.. kernel-doc:: include/media/cec-pin.h
-
-CEC Notifier framework
-----------------------
-
-Most drm HDMI implementations have an integrated CEC implementation and no
-notifier support is needed. But some have independent CEC implementations
-that have their own driver. This could be an IP block for an SoC or a
-completely separate chip that deals with the CEC pin. For those cases a
-drm driver can install a notifier and use the notifier to inform the
-CEC driver about changes in the physical address.
-
-.. kernel-doc:: include/media/cec-notifier.h
diff --git a/Documentation/media/kapi/csi2.rst b/Documentation/media/kapi/csi2.rst
deleted file mode 100644
index e111ff7bfd3d..000000000000
--- a/Documentation/media/kapi/csi2.rst
+++ /dev/null
@@ -1,85 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-MIPI CSI-2
-==========
-
-CSI-2 is a data bus intended for transferring images from cameras to
-the host SoC. It is defined by the `MIPI alliance`_.
-
-.. _`MIPI alliance`: http://www.mipi.org/
-
-Transmitter drivers
--------------------
-
-CSI-2 transmitter, such as a sensor or a TV tuner, drivers need to
-provide the CSI-2 receiver with information on the CSI-2 bus
-configuration. These include the V4L2_CID_LINK_FREQ and
-V4L2_CID_PIXEL_RATE controls and
-(:c:type:`v4l2_subdev_video_ops`->s_stream() callback). These
-interface elements must be present on the sub-device represents the
-CSI-2 transmitter.
-
-The V4L2_CID_LINK_FREQ control is used to tell the receiver driver the
-frequency (and not the symbol rate) of the link. The
-V4L2_CID_PIXEL_RATE is may be used by the receiver to obtain the pixel
-rate the transmitter uses. The
-:c:type:`v4l2_subdev_video_ops`->s_stream() callback provides an
-ability to start and stop the stream.
-
-The value of the V4L2_CID_PIXEL_RATE is calculated as follows::
-
-	pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample
-
-where
-
-.. list-table:: variables in pixel rate calculation
-   :header-rows: 1
-
-   * - variable or constant
-     - description
-   * - link_freq
-     - The value of the V4L2_CID_LINK_FREQ integer64 menu item.
-   * - nr_of_lanes
-     - Number of data lanes used on the CSI-2 link. This can
-       be obtained from the OF endpoint configuration.
-   * - 2
-     - Two bits are transferred per clock cycle per lane.
-   * - bits_per_sample
-     - Number of bits per sample.
-
-The transmitter drivers must, if possible, configure the CSI-2
-transmitter to *LP-11 mode* whenever the transmitter is powered on but
-not active, and maintain *LP-11 mode* until stream on. Only at stream
-on should the transmitter activate the clock on the clock lane and
-transition to *HS mode*.
-
-Some transmitters do this automatically but some have to be explicitly
-programmed to do so, and some are unable to do so altogether due to
-hardware constraints.
-
-Stopping the transmitter
-^^^^^^^^^^^^^^^^^^^^^^^^
-
-A transmitter stops sending the stream of images as a result of
-calling the ``.s_stream()`` callback. Some transmitters may stop the
-stream at a frame boundary whereas others stop immediately,
-effectively leaving the current frame unfinished. The receiver driver
-should not make assumptions either way, but function properly in both
-cases.
-
-Receiver drivers
-----------------
-
-Before the receiver driver may enable the CSI-2 transmitter by using
-the :c:type:`v4l2_subdev_video_ops`->s_stream(), it must have powered
-the transmitter up by using the
-:c:type:`v4l2_subdev_core_ops`->s_power() callback. This may take
-place either indirectly by using :c:func:`v4l2_pipeline_pm_get` or
-directly.
-
-Formats
--------
-
-The media bus pixel codes document parallel formats. Should the pixel data be
-transported over a serial bus, the media bus pixel code that describes a
-parallel format that transfers a sample on a single clock cycle is used.
diff --git a/Documentation/media/kapi/dtv-ca.rst b/Documentation/media/kapi/dtv-ca.rst
deleted file mode 100644
index 8a09862b428b..000000000000
--- a/Documentation/media/kapi/dtv-ca.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-Digital TV Conditional Access kABI
-----------------------------------
-
-.. kernel-doc:: include/media/dvb_ca_en50221.h
diff --git a/Documentation/media/kapi/dtv-common.rst b/Documentation/media/kapi/dtv-common.rst
deleted file mode 100644
index f8b2c4dc8170..000000000000
--- a/Documentation/media/kapi/dtv-common.rst
+++ /dev/null
@@ -1,62 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-Digital TV Common functions
----------------------------
-
-Math functions
-~~~~~~~~~~~~~~
-
-Provide some commonly-used math functions, usually required in order to
-estimate signal strength and signal to noise measurements in dB.
-
-.. kernel-doc:: include/media/dvb_math.h
-
-
-DVB devices
-~~~~~~~~~~~
-
-Those functions are responsible for handling the DVB device nodes.
-
-.. kernel-doc:: include/media/dvbdev.h
-
-Digital TV Ring buffer
-~~~~~~~~~~~~~~~~~~~~~~
-
-Those routines implement ring buffers used to handle digital TV data and
-copy it from/to userspace.
-
-.. note::
-
-  1) For performance reasons read and write routines don't check buffer sizes
-     and/or number of bytes free/available. This has to be done before these
-     routines are called. For example:
-
-   .. code-block:: c
-
-        /* write @buflen: bytes */
-        free = dvb_ringbuffer_free(rbuf);
-        if (free >= buflen)
-                count = dvb_ringbuffer_write(rbuf, buffer, buflen);
-        else
-                /* do something */
-
-        /* read min. 1000, max. @bufsize: bytes */
-        avail = dvb_ringbuffer_avail(rbuf);
-        if (avail >= 1000)
-                count = dvb_ringbuffer_read(rbuf, buffer, min(avail, bufsize));
-        else
-                /* do something */
-
-  2) If there is exactly one reader and one writer, there is no need
-     to lock read or write operations.
-     Two or more readers must be locked against each other.
-     Flushing the buffer counts as a read operation.
-     Resetting the buffer counts as a read and write operation.
-     Two or more writers must be locked against each other.
-
-.. 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-core.rst b/Documentation/media/kapi/dtv-core.rst
deleted file mode 100644
index 82c5b85ed9b1..000000000000
--- a/Documentation/media/kapi/dtv-core.rst
+++ /dev/null
@@ -1,39 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-Digital TV (DVB) devices
-------------------------
-
-Digital TV devices are implemented by several different drivers:
-
-- A bridge driver that is responsible to talk with the bus where the other
-  devices are connected (PCI, USB, SPI), bind to the other drivers and
-  implement the digital demux logic (either in software or in hardware);
-
-- Frontend drivers that are usually implemented as two separate drivers:
-
-  - A tuner driver that implements the logic which commands the part of
-    the hardware responsible for tuning into a digital TV transponder or
-    physical channel. The output of a tuner is usually a baseband or
-    Intermediate Frequency (IF) signal;
-
-  - A demodulator driver (a.k.a "demod") that implements the logic which
-    commands the digital TV decoding hardware. The output of a demod is
-    a digital stream, with multiple audio, video and data channels typically
-    multiplexed using MPEG Transport Stream [#f1]_.
-
-On most hardware, the frontend drivers talk with the bridge driver using an
-I2C bus.
-
-.. [#f1] Some standards use TCP/IP for multiplexing data, like DVB-H (an
-   abandoned standard, not used anymore) and ATSC version 3.0 current
-   proposals. Currently, the DVB subsystem doesn't implement those standards.
-
-
-.. toctree::
-    :maxdepth: 1
-
-    dtv-common
-    dtv-frontend
-    dtv-demux
-    dtv-ca
-    dtv-net
diff --git a/Documentation/media/kapi/dtv-demux.rst b/Documentation/media/kapi/dtv-demux.rst
deleted file mode 100644
index c0ae5dec5328..000000000000
--- a/Documentation/media/kapi/dtv-demux.rst
+++ /dev/null
@@ -1,84 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-Digital TV Demux kABI
----------------------
-
-Digital TV Demux
-~~~~~~~~~~~~~~~~
-
-The Kernel Digital TV Demux kABI defines a driver-internal interface for
-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
-``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.
-When the demux client allocates a resource via the demux kABI, it receives
-a pointer to the kABI of that resource.
-
-Each demux receives its TS input from a DVB front-end or from memory, as
-set via this demux kABI. In a system with more than one front-end, the kABI
-can be used to select one of the DVB front-ends as a TS source for a demux,
-unless this is fixed in the HW platform.
-
-The demux kABI only controls front-ends regarding to their connections with
-demuxes; the kABI used to set the other front-end parameters, such as
-tuning, are devined via the Digital TV Frontend kABI.
-
-The functions that implement the abstract interface demux should be defined
-static or module private and registered to the Demux core for external
-access. It is not necessary to implement every function in the struct
-:c:type:`dmx_demux`. For example, a demux interface might support Section filtering,
-but not PES filtering. The kABI client is expected to check the value of any
-function pointer before calling the function: the value of ``NULL`` means
-that the function is not available.
-
-Whenever the functions of the demux API modify shared data, the
-possibilities of lost update and race condition problems should be
-addressed, e.g. by protecting parts of code with mutexes.
-
-Note that functions called from a bottom half context must not sleep.
-Even a simple memory allocation without using ``GFP_ATOMIC`` can result in a
-kernel thread being put to sleep if swapping is needed. For example, the
-Linux Kernel calls the functions of a network device interface from a
-bottom half context. Thus, if a demux kABI function is called from network
-device code, the function must not sleep.
-
-Demux Callback API
-~~~~~~~~~~~~~~~~~~
-
-This kernel-space API comprises the callback functions that deliver filtered
-data to the demux client. Unlike the other DVB kABIs, these functions are
-provided by the client and called from the demux code.
-
-The function pointers of this abstract interface are not packed into a
-structure as in the other demux APIs, because the callback functions are
-registered and used independent of each other. As an example, it is possible
-for the API client to provide several callback functions for receiving TS
-packets and no callbacks for PES packets or sections.
-
-The functions that implement the callback API need not be re-entrant: when
-a demux driver calls one of these functions, the driver is not allowed to
-call the function again before the original call returns. If a callback is
-triggered by a hardware interrupt, it is recommended to use the Linux
-bottom half mechanism or start a tasklet instead of making the callback
-function call directly from a hardware interrupt.
-
-This mechanism is implemented by :c:func:`dmx_ts_cb()` and :c:func:`dmx_section_cb()`
-callbacks.
-
-Digital TV Demux device registration functions and data structures
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. kernel-doc:: include/media/dmxdev.h
-
-High-level Digital TV demux interface
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. kernel-doc:: include/media/dvb_demux.h
-
-Driver-internal low-level hardware specific driver demux interface
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. kernel-doc:: include/media/demux.h
diff --git a/Documentation/media/kapi/dtv-frontend.rst b/Documentation/media/kapi/dtv-frontend.rst
deleted file mode 100644
index b362109bb131..000000000000
--- a/Documentation/media/kapi/dtv-frontend.rst
+++ /dev/null
@@ -1,445 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-Digital TV Frontend kABI
-------------------------
-
-Digital TV Frontend
-~~~~~~~~~~~~~~~~~~~
-
-The Digital TV Frontend kABI defines a driver-internal interface for
-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
-``include/media/``.
-
-Demodulator driver
-^^^^^^^^^^^^^^^^^^
-
-The demodulator driver is responsible for talking with the decoding part of the
-hardware. Such driver should implement :c:type:`dvb_frontend_ops`, which
-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 ``include/media/dvb_frontend.c``.
-
-A typical example of such struct in a driver ``foo`` is::
-
-	static struct dvb_frontend_ops foo_ops = {
-		.delsys = { SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A },
-		.info = {
-			.name	= "foo DVB-T/T2/C driver",
-			.caps = FE_CAN_FEC_1_2 |
-				FE_CAN_FEC_2_3 |
-				FE_CAN_FEC_3_4 |
-				FE_CAN_FEC_5_6 |
-				FE_CAN_FEC_7_8 |
-				FE_CAN_FEC_AUTO |
-				FE_CAN_QPSK |
-				FE_CAN_QAM_16 |
-				FE_CAN_QAM_32 |
-				FE_CAN_QAM_64 |
-				FE_CAN_QAM_128 |
-				FE_CAN_QAM_256 |
-				FE_CAN_QAM_AUTO |
-				FE_CAN_TRANSMISSION_MODE_AUTO |
-				FE_CAN_GUARD_INTERVAL_AUTO |
-				FE_CAN_HIERARCHY_AUTO |
-				FE_CAN_MUTE_TS |
-				FE_CAN_2G_MODULATION,
-			.frequency_min = 42000000, /* Hz */
-			.frequency_max = 1002000000, /* Hz */
-			.symbol_rate_min = 870000,
-			.symbol_rate_max = 11700000
-		},
-		.init = foo_init,
-		.sleep = foo_sleep,
-		.release = foo_release,
-		.set_frontend = foo_set_frontend,
-		.get_frontend = foo_get_frontend,
-		.read_status = foo_get_status_and_stats,
-		.tune = foo_tune,
-		.i2c_gate_ctrl = foo_i2c_gate_ctrl,
-		.get_frontend_algo = foo_get_algo,
-	};
-
-A typical example of such struct in a driver ``bar`` meant to be used on
-Satellite TV reception is::
-
-	static const struct dvb_frontend_ops bar_ops = {
-		.delsys = { SYS_DVBS, SYS_DVBS2 },
-		.info = {
-			.name		= "Bar DVB-S/S2 demodulator",
-			.frequency_min	= 500000, /* KHz */
-			.frequency_max	= 2500000, /* KHz */
-			.frequency_stepsize	= 0,
-			.symbol_rate_min = 1000000,
-			.symbol_rate_max = 45000000,
-			.symbol_rate_tolerance = 500,
-			.caps = FE_CAN_INVERSION_AUTO |
-				FE_CAN_FEC_AUTO |
-				FE_CAN_QPSK,
-		},
-		.init = bar_init,
-		.sleep = bar_sleep,
-		.release = bar_release,
-		.set_frontend = bar_set_frontend,
-		.get_frontend = bar_get_frontend,
-		.read_status = bar_get_status_and_stats,
-		.i2c_gate_ctrl = bar_i2c_gate_ctrl,
-		.get_frontend_algo = bar_get_algo,
-		.tune = bar_tune,
-
-		/* Satellite-specific */
-		.diseqc_send_master_cmd = bar_send_diseqc_msg,
-		.diseqc_send_burst = bar_send_burst,
-		.set_tone = bar_set_tone,
-		.set_voltage = bar_set_voltage,
-	};
-
-.. note::
-
-   #) For satellite digital TV standards (DVB-S, DVB-S2, ISDB-S), the
-      frequencies are specified in kHz, while, for terrestrial and cable
-      standards, they're specified in Hz. Due to that, if the same frontend
-      supports both types, you'll need to have two separate
-      :c:type:`dvb_frontend_ops` structures, one for each standard.
-   #) The ``.i2c_gate_ctrl`` field is present only when the hardware has
-      allows controlling an I2C gate (either directly of via some GPIO pin),
-      in order to remove the tuner from the I2C bus after a channel is
-      tuned.
-   #) All new drivers should implement the
-      :ref:`DVBv5 statistics <dvbv5_stats>` via ``.read_status``.
-      Yet, there are a number of callbacks meant to get statistics for
-      signal strength, S/N and UCB. Those are there to provide backward
-      compatibility with legacy applications that don't support the DVBv5
-      API. Implementing those callbacks are optional. Those callbacks may be
-      removed in the future, after we have all existing drivers supporting
-      DVBv5 stats.
-   #) Other callbacks are required for satellite TV standards, in order to
-      control LNBf and DiSEqC: ``.diseqc_send_master_cmd``,
-      ``.diseqc_send_burst``, ``.set_tone``, ``.set_voltage``.
-
-.. |delta|   unicode:: U+00394
-
-The ``include/media/dvb_frontend.c`` has a kernel thread which is
-responsible for tuning the device. It supports multiple algorithms to
-detect a channel, as defined at enum :c:func:`dvbfe_algo`.
-
-The algorithm to be used is obtained via ``.get_frontend_algo``. If the driver
-doesn't fill its field at struct :c:type:`dvb_frontend_ops`, it will default to
-``DVBFE_ALGO_SW``, meaning that the dvb-core will do a zigzag when tuning,
-e. g. it will try first to use the specified center frequency ``f``,
-then, it will do ``f`` + |delta|, ``f`` - |delta|, ``f`` + 2 x |delta|,
-``f`` - 2 x |delta| and so on.
-
-If the hardware has internally a some sort of zigzag algorithm, you should
-define a ``.get_frontend_algo`` function that would return ``DVBFE_ALGO_HW``.
-
-.. note::
-
-   The core frontend support also supports
-   a third type (``DVBFE_ALGO_CUSTOM``), in order to allow the driver to
-   define its own hardware-assisted algorithm. Very few hardware need to
-   use it nowadays. Using ``DVBFE_ALGO_CUSTOM`` require to provide other
-   function callbacks at struct :c:type:`dvb_frontend_ops`.
-
-Attaching frontend driver to the bridge driver
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Before using the Digital TV frontend core, the bridge driver should attach
-the frontend demod, tuner and SEC devices and call
-:c:func:`dvb_register_frontend()`,
-in order to register the new frontend at the subsystem. At device
-detach/removal, the bridge driver should call
-:c:func:`dvb_unregister_frontend()` to
-remove the frontend from the core and then :c:func:`dvb_frontend_detach()`
-to free the memory allocated by the frontend drivers.
-
-The drivers should also call :c:func:`dvb_frontend_suspend()` as part of
-their handler for the :c:type:`device_driver`.\ ``suspend()``, and
-:c:func:`dvb_frontend_resume()` as
-part of their handler for :c:type:`device_driver`.\ ``resume()``.
-
-A few other optional functions are provided to handle some special cases.
-
-.. _dvbv5_stats:
-
-Digital TV Frontend statistics
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Introduction
-^^^^^^^^^^^^
-
-Digital TV frontends provide a range of
-:ref:`statistics <frontend-stat-properties>` meant to help tuning the device
-and measuring the quality of service.
-
-For each statistics measurement, the driver should set the type of scale used,
-or ``FE_SCALE_NOT_AVAILABLE`` if the statistics is not available on a given
-time. Drivers should also provide the number of statistics for each type.
-that's usually 1 for most video standards [#f2]_.
-
-Drivers should initialize each statistic counters with length and
-scale at its init code. For example, if the frontend provides signal
-strength, it should have, on its init code::
-
-	struct dtv_frontend_properties *c = &state->fe.dtv_property_cache;
-
-	c->strength.len = 1;
-	c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
-
-And, when the statistics got updated, set the scale::
-
-	c->strength.stat[0].scale = FE_SCALE_DECIBEL;
-	c->strength.stat[0].uvalue = strength;
-
-.. [#f2] For ISDB-T, it may provide both a global statistics and a per-layer
-   set of statistics. On such cases, len should be equal to 4. The first
-   value corresponds to the global stat; the other ones to each layer, e. g.:
-
-   - c->cnr.stat[0] for global S/N carrier ratio,
-   - c->cnr.stat[1] for Layer A S/N carrier ratio,
-   - c->cnr.stat[2] for layer B S/N carrier ratio,
-   - c->cnr.stat[3] for layer C S/N carrier ratio.
-
-.. note:: Please prefer to use ``FE_SCALE_DECIBEL`` instead of
-   ``FE_SCALE_RELATIVE`` for signal strength and CNR measurements.
-
-Groups of statistics
-^^^^^^^^^^^^^^^^^^^^
-
-There are several groups of statistics currently supported:
-
-Signal strength (:ref:`DTV-STAT-SIGNAL-STRENGTH`)
-  - Measures the signal strength level at the analog part of the tuner or
-    demod.
-
-  - Typically obtained from the gain applied to the tuner and/or frontend
-    in order to detect the carrier. When no carrier is detected, the gain is
-    at the maximum value (so, strength is on its minimal).
-
-  - As the gain is visible through the set of registers that adjust the gain,
-    typically, this statistics is always available [#f3]_.
-
-  - Drivers should try to make it available all the times, as these statistics
-    can be used when adjusting an antenna position and to check for troubles
-    at the cabling.
-
-  .. [#f3] On a few devices, the gain keeps floating if there is no carrier.
-     On such devices, strength report should check first if carrier is
-     detected at the tuner (``FE_HAS_CARRIER``, see :c:type:`fe_status`),
-     and otherwise return the lowest possible value.
-
-Carrier Signal to Noise ratio (:ref:`DTV-STAT-CNR`)
-  - Signal to Noise ratio for the main carrier.
-
-  - Signal to Noise measurement depends on the device. On some hardware, it is
-    available when the main carrier is detected. On those hardware, CNR
-    measurement usually comes from the tuner (e. g. after ``FE_HAS_CARRIER``,
-    see :c:type:`fe_status`).
-
-    On other devices, it requires inner FEC decoding,
-    as the frontend measures it indirectly from other parameters (e. g. after
-    ``FE_HAS_VITERBI``, see :c:type:`fe_status`).
-
-    Having it available after inner FEC is more common.
-
-Bit counts post-FEC (:ref:`DTV-STAT-POST-ERROR-BIT-COUNT` and :ref:`DTV-STAT-POST-TOTAL-BIT-COUNT`)
-  - Those counters measure the number of bits and bit errors errors after
-    the forward error correction (FEC) on the inner coding block
-    (after Viterbi, LDPC or other inner code).
-
-  - Due to its nature, those statistics depend on full coding lock
-    (e. g. after ``FE_HAS_SYNC`` or after ``FE_HAS_LOCK``,
-    see :c:type:`fe_status`).
-
-Bit counts pre-FEC (:ref:`DTV-STAT-PRE-ERROR-BIT-COUNT` and :ref:`DTV-STAT-PRE-TOTAL-BIT-COUNT`)
-  - Those counters measure the number of bits and bit errors errors before
-    the forward error correction (FEC) on the inner coding block
-    (before Viterbi, LDPC or other inner code).
-
-  - Not all frontends provide this kind of statistics.
-
-  - Due to its nature, those statistics depend on inner coding lock (e. g.
-    after ``FE_HAS_VITERBI``, see :c:type:`fe_status`).
-
-Block counts (:ref:`DTV-STAT-ERROR-BLOCK-COUNT` and :ref:`DTV-STAT-TOTAL-BLOCK-COUNT`)
-  - Those counters measure the number of blocks and block errors errors after
-    the forward error correction (FEC) on the inner coding block
-    (before Viterbi, LDPC or other inner code).
-
-  - Due to its nature, those statistics depend on full coding lock
-    (e. g. after ``FE_HAS_SYNC`` or after
-    ``FE_HAS_LOCK``, see :c:type:`fe_status`).
-
-.. note:: All counters should be monotonically increased as they're
-   collected from the hardware.
-
-A typical example of the logic that handle status and statistics is::
-
-	static int foo_get_status_and_stats(struct dvb_frontend *fe)
-	{
-		struct foo_state *state = fe->demodulator_priv;
-		struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-
-		int rc;
-		enum fe_status *status;
-
-		/* Both status and strength are always available */
-		rc = foo_read_status(fe, &status);
-		if (rc < 0)
-			return rc;
-
-		rc = foo_read_strength(fe);
-		if (rc < 0)
-			return rc;
-
-		/* Check if CNR is available */
-		if (!(fe->status & FE_HAS_CARRIER))
-			return 0;
-
-		rc = foo_read_cnr(fe);
-		if (rc < 0)
-			return rc;
-
-		/* Check if pre-BER stats are available */
-		if (!(fe->status & FE_HAS_VITERBI))
-			return 0;
-
-		rc = foo_get_pre_ber(fe);
-		if (rc < 0)
-			return rc;
-
-		/* Check if post-BER stats are available */
-		if (!(fe->status & FE_HAS_SYNC))
-			return 0;
-
-		rc = foo_get_post_ber(fe);
-		if (rc < 0)
-			return rc;
-	}
-
-	static const struct dvb_frontend_ops ops = {
-		/* ... */
-		.read_status = foo_get_status_and_stats,
-	};
-
-Statistics collection
-^^^^^^^^^^^^^^^^^^^^^
-
-On almost all frontend hardware, the bit and byte counts are stored by
-the hardware after a certain amount of time or after the total bit/block
-counter reaches a certain value (usually programmable), for example, on
-every 1000 ms or after receiving 1,000,000 bits.
-
-So, if you read the registers too soon, you'll end by reading the same
-value as in the previous reading, causing the monotonic value to be
-incremented too often.
-
-Drivers should take the responsibility to avoid too often reads. That
-can be done using two approaches:
-
-if the driver have a bit that indicates when a collected data is ready
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-Driver should check such bit before making the statistics available.
-
-An example of such behavior can be found at this code snippet (adapted
-from mb86a20s driver's logic)::
-
-	static int foo_get_pre_ber(struct dvb_frontend *fe)
-	{
-		struct foo_state *state = fe->demodulator_priv;
-		struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-		int rc, bit_error;
-
-		/* Check if the BER measures are already available */
-		rc = foo_read_u8(state, 0x54);
-		if (rc < 0)
-			return rc;
-
-		if (!rc)
-			return 0;
-
-		/* Read Bit Error Count */
-		bit_error = foo_read_u32(state, 0x55);
-		if (bit_error < 0)
-			return bit_error;
-
-		/* Read Total Bit Count */
-		rc = foo_read_u32(state, 0x51);
-		if (rc < 0)
-			return rc;
-
-		c->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
-		c->pre_bit_error.stat[0].uvalue += bit_error;
-		c->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
-		c->pre_bit_count.stat[0].uvalue += rc;
-
-		return 0;
-	}
-
-If the driver doesn't provide a statistics available check bit
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-A few devices, however, may not provide a way to check if the stats are
-available (or the way to check it is unknown). They may not even provide
-a way to directly read the total number of bits or blocks.
-
-On those devices, the driver need to ensure that it won't be reading from
-the register too often and/or estimate the total number of bits/blocks.
-
-On such drivers, a typical routine to get statistics would be like
-(adapted from dib8000 driver's logic)::
-
-	struct foo_state {
-		/* ... */
-
-		unsigned long per_jiffies_stats;
-	}
-
-	static int foo_get_pre_ber(struct dvb_frontend *fe)
-	{
-		struct foo_state *state = fe->demodulator_priv;
-		struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-		int rc, bit_error;
-		u64 bits;
-
-		/* Check if time for stats was elapsed */
-		if (!time_after(jiffies, state->per_jiffies_stats))
-			return 0;
-
-		/* Next stat should be collected in 1000 ms */
-		state->per_jiffies_stats = jiffies + msecs_to_jiffies(1000);
-
-		/* Read Bit Error Count */
-		bit_error = foo_read_u32(state, 0x55);
-		if (bit_error < 0)
-			return bit_error;
-
-		/*
-		 * On this particular frontend, there's no register that
-		 * would provide the number of bits per 1000ms sample. So,
-		 * some function would calculate it based on DTV properties
-		 */
-		bits = get_number_of_bits_per_1000ms(fe);
-
-		c->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
-		c->pre_bit_error.stat[0].uvalue += bit_error;
-		c->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
-		c->pre_bit_count.stat[0].uvalue += bits;
-
-		return 0;
-	}
-
-Please notice that, on both cases, we're getting the statistics using the
-:c:type:`dvb_frontend_ops` ``.read_status`` callback. The rationale is that
-the frontend core will automatically call this function periodically
-(usually, 3 times per second, when the frontend is locked).
-
-That warrants that we won't miss to collect a counter and increment the
-monotonic stats at the right time.
-
-Digital TV Frontend functions and types
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. kernel-doc:: include/media/dvb_frontend.h
diff --git a/Documentation/media/kapi/dtv-net.rst b/Documentation/media/kapi/dtv-net.rst
deleted file mode 100644
index deb6bffe96bb..000000000000
--- a/Documentation/media/kapi/dtv-net.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-Digital TV Network kABI
------------------------
-
-.. kernel-doc:: include/media/dvb_net.h
diff --git a/Documentation/media/kapi/mc-core.rst b/Documentation/media/kapi/mc-core.rst
deleted file mode 100644
index 05bba0b61748..000000000000
--- a/Documentation/media/kapi/mc-core.rst
+++ /dev/null
@@ -1,309 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-Media Controller devices
-------------------------
-
-Media Controller
-~~~~~~~~~~~~~~~~
-
-The media controller userspace API is documented in
-:ref:`the Media Controller uAPI book <media_controller>`. This document focus
-on the kernel-side implementation of the media framework.
-
-Abstract media device model
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Discovering a device internal topology, and configuring it at runtime, is one
-of the goals of the media framework. To achieve this, hardware devices are
-modelled as an oriented graph of building blocks called entities connected
-through pads.
-
-An entity is a basic media hardware building block. It can correspond to
-a large variety of logical blocks such as physical hardware devices
-(CMOS sensor for instance), logical hardware devices (a building block
-in a System-on-Chip image processing pipeline), DMA channels or physical
-connectors.
-
-A pad is a connection endpoint through which an entity can interact with
-other entities. Data (not restricted to video) produced by an entity
-flows from the entity's output to one or more entity inputs. Pads should
-not be confused with physical pins at chip boundaries.
-
-A link is a point-to-point oriented connection between two pads, either
-on the same entity or on different entities. Data flows from a source
-pad to a sink pad.
-
-Media device
-^^^^^^^^^^^^
-
-A media device is represented by a struct :c:type:`media_device`
-instance, defined in ``include/media/media-device.h``.
-Allocation of the structure is handled by the media device driver, usually by
-embedding the :c:type:`media_device` instance in a larger driver-specific
-structure.
-
-Drivers register media device instances by calling
-:c:func:`__media_device_register()` via the macro ``media_device_register()``
-and unregistered by calling :c:func:`media_device_unregister()`.
-
-Entities
-^^^^^^^^
-
-Entities are represented by a struct :c:type:`media_entity`
-instance, defined in ``include/media/media-entity.h``. The structure is usually
-embedded into a higher-level structure, such as
-:c:type:`v4l2_subdev` or :c:type:`video_device`
-instances, although drivers can allocate entities directly.
-
-Drivers initialize entity pads by calling
-:c:func:`media_entity_pads_init()`.
-
-Drivers register entities with a media device by calling
-:c:func:`media_device_register_entity()`
-and unregistered by calling
-:c:func:`media_device_unregister_entity()`.
-
-Interfaces
-^^^^^^^^^^
-
-Interfaces are represented by a
-struct :c:type:`media_interface` instance, defined in
-``include/media/media-entity.h``. Currently, only one type of interface is
-defined: a device node. Such interfaces are represented by a
-struct :c:type:`media_intf_devnode`.
-
-Drivers initialize and create device node interfaces by calling
-:c:func:`media_devnode_create()`
-and remove them by calling:
-:c:func:`media_devnode_remove()`.
-
-Pads
-^^^^
-Pads are represented by a struct :c:type:`media_pad` instance,
-defined in ``include/media/media-entity.h``. Each entity stores its pads in
-a pads array managed by the entity driver. Drivers usually embed the array in
-a driver-specific structure.
-
-Pads are identified by their entity and their 0-based index in the pads
-array.
-
-Both information are stored in the struct :c:type:`media_pad`,
-making the struct :c:type:`media_pad` pointer the canonical way
-to store and pass link references.
-
-Pads have flags that describe the pad capabilities and state.
-
-``MEDIA_PAD_FL_SINK`` indicates that the pad supports sinking data.
-``MEDIA_PAD_FL_SOURCE`` indicates that the pad supports sourcing data.
-
-.. note::
-
-  One and only one of ``MEDIA_PAD_FL_SINK`` or ``MEDIA_PAD_FL_SOURCE`` must
-  be set for each pad.
-
-Links
-^^^^^
-
-Links are represented by a struct :c:type:`media_link` instance,
-defined in ``include/media/media-entity.h``. There are two types of links:
-
-**1. pad to pad links**:
-
-Associate two entities via their PADs. Each entity has a list that points
-to all links originating at or targeting any of its pads.
-A given link is thus stored twice, once in the source entity and once in
-the target entity.
-
-Drivers create pad to pad links by calling:
-:c:func:`media_create_pad_link()` and remove with
-:c:func:`media_entity_remove_links()`.
-
-**2. interface to entity links**:
-
-Associate one interface to a Link.
-
-Drivers create interface to entity links by calling:
-:c:func:`media_create_intf_link()` and remove with
-:c:func:`media_remove_intf_links()`.
-
-.. note::
-
-   Links can only be created after having both ends already created.
-
-Links have flags that describe the link capabilities and state. The
-valid values are described at :c:func:`media_create_pad_link()` and
-:c:func:`media_create_intf_link()`.
-
-Graph traversal
-^^^^^^^^^^^^^^^
-
-The media framework provides APIs to iterate over entities in a graph.
-
-To iterate over all entities belonging to a media device, drivers can use
-the media_device_for_each_entity macro, defined in
-``include/media/media-device.h``.
-
-..  code-block:: c
-
-    struct media_entity *entity;
-
-    media_device_for_each_entity(entity, mdev) {
-    // entity will point to each entity in turn
-    ...
-    }
-
-Drivers might also need to iterate over all entities in a graph that can be
-reached only through enabled links starting at a given entity. The media
-framework provides a depth-first graph traversal API for that purpose.
-
-.. note::
-
-   Graphs with cycles (whether directed or undirected) are **NOT**
-   supported by the graph traversal API. To prevent infinite loops, the graph
-   traversal code limits the maximum depth to ``MEDIA_ENTITY_ENUM_MAX_DEPTH``,
-   currently defined as 16.
-
-Drivers initiate a graph traversal by calling
-:c:func:`media_graph_walk_start()`
-
-The graph structure, provided by the caller, is initialized to start graph
-traversal at the given entity.
-
-Drivers can then retrieve the next entity by calling
-:c:func:`media_graph_walk_next()`
-
-When the graph traversal is complete the function will return ``NULL``.
-
-Graph traversal can be interrupted at any moment. No cleanup function call
-is required and the graph structure can be freed normally.
-
-Helper functions can be used to find a link between two given pads, or a pad
-connected to another pad through an enabled link
-:c:func:`media_entity_find_link()` and
-:c:func:`media_entity_remote_pad()`.
-
-Use count and power handling
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Due to the wide differences between drivers regarding power management
-needs, the media controller does not implement power management. However,
-the struct :c:type:`media_entity` includes a ``use_count``
-field that media drivers
-can use to track the number of users of every entity for power management
-needs.
-
-The :c:type:`media_entity<media_entity>`.\ ``use_count`` field is owned by
-media drivers and must not be
-touched by entity drivers. Access to the field must be protected by the
-:c:type:`media_device`.\ ``graph_mutex`` lock.
-
-Links setup
-^^^^^^^^^^^
-
-Link properties can be modified at runtime by calling
-:c:func:`media_entity_setup_link()`.
-
-Pipelines and media streams
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-When starting streaming, drivers must notify all entities in the pipeline to
-prevent link states from being modified during streaming by calling
-:c:func:`media_pipeline_start()`.
-
-The function will mark all entities connected to the given entity through
-enabled links, either directly or indirectly, as streaming.
-
-The struct :c:type:`media_pipeline` instance pointed to by
-the pipe argument will be stored in every entity in the pipeline.
-Drivers should embed the struct :c:type:`media_pipeline`
-in higher-level pipeline structures and can then access the
-pipeline through the struct :c:type:`media_entity`
-pipe field.
-
-Calls to :c:func:`media_pipeline_start()` can be nested.
-The pipeline pointer must be identical for all nested calls to the function.
-
-:c:func:`media_pipeline_start()` may return an error. In that case,
-it will clean up any of the changes it did by itself.
-
-When stopping the stream, drivers must notify the entities with
-:c:func:`media_pipeline_stop()`.
-
-If multiple calls to :c:func:`media_pipeline_start()` have been
-made the same number of :c:func:`media_pipeline_stop()` calls
-are required to stop streaming.
-The :c:type:`media_entity`.\ ``pipe`` field is reset to ``NULL`` on the last
-nested stop call.
-
-Link configuration will fail with ``-EBUSY`` by default if either end of the
-link is a streaming entity. Links that can be modified while streaming must
-be marked with the ``MEDIA_LNK_FL_DYNAMIC`` flag.
-
-If other operations need to be disallowed on streaming entities (such as
-changing entities configuration parameters) drivers can explicitly check the
-media_entity stream_count field to find out if an entity is streaming. This
-operation must be done with the media_device graph_mutex held.
-
-Link validation
-^^^^^^^^^^^^^^^
-
-Link validation is performed by :c:func:`media_pipeline_start()`
-for any entity which has sink pads in the pipeline. The
-:c:type:`media_entity`.\ ``link_validate()`` callback is used for that
-purpose. In ``link_validate()`` callback, entity driver should check
-that the properties of the source pad of the connected entity and its own
-sink pad match. It is up to the type of the entity (and in the end, the
-properties of the hardware) what matching actually means.
-
-Subsystems should facilitate link validation by providing subsystem specific
-helper functions to provide easy access for commonly needed information, and
-in the end provide a way to use driver-specific callbacks.
-
-Media Controller Device Allocator API
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-When the media device belongs to more than one driver, the shared media
-device is allocated with the shared struct device as the key for look ups.
-
-The shared media device should stay in registered state until the last
-driver unregisters it. In addition, the media device should be released when
-all the references are released. Each driver gets a reference to the media
-device during probe, when it allocates the media device. If media device is
-already allocated, the allocate API bumps up the refcount and returns the
-existing media device. The driver puts the reference back in its disconnect
-routine when it calls :c:func:`media_device_delete()`.
-
-The media device is unregistered and cleaned up from the kref put handler to
-ensure that the media device stays in registered state until the last driver
-unregisters the media device.
-
-**Driver Usage**
-
-Drivers should use the appropriate media-core routines to manage the shared
-media device life-time handling the two states:
-1. allocate -> register -> delete
-2. get reference to already registered device -> delete
-
-call :c:func:`media_device_delete()` routine to make sure the shared media
-device delete is handled correctly.
-
-**driver probe:**
-Call :c:func:`media_device_usb_allocate()` to allocate or get a reference
-Call :c:func:`media_device_register()`, if media devnode isn't registered
-
-**driver disconnect:**
-Call :c:func:`media_device_delete()` to free the media_device. Freeing is
-handled by the kref put handler.
-
-API Definitions
-^^^^^^^^^^^^^^^
-
-.. kernel-doc:: include/media/media-device.h
-
-.. kernel-doc:: include/media/media-devnode.h
-
-.. kernel-doc:: include/media/media-entity.h
-
-.. kernel-doc:: include/media/media-request.h
-
-.. kernel-doc:: include/media/media-dev-allocator.h
diff --git a/Documentation/media/kapi/rc-core.rst b/Documentation/media/kapi/rc-core.rst
deleted file mode 100644
index 53f5e643b6e9..000000000000
--- a/Documentation/media/kapi/rc-core.rst
+++ /dev/null
@@ -1,88 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-Remote Controller devices
--------------------------
-
-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
diff --git a/Documentation/media/kapi/v4l2-async.rst b/Documentation/media/kapi/v4l2-async.rst
deleted file mode 100644
index 3422330b3b1f..000000000000
--- a/Documentation/media/kapi/v4l2-async.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-V4L2 async kAPI
-^^^^^^^^^^^^^^^
-.. kernel-doc:: include/media/v4l2-async.h
diff --git a/Documentation/media/kapi/v4l2-clocks.rst b/Documentation/media/kapi/v4l2-clocks.rst
deleted file mode 100644
index 5c22eecab7ba..000000000000
--- a/Documentation/media/kapi/v4l2-clocks.rst
+++ /dev/null
@@ -1,31 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-V4L2 clocks
------------
-
-.. attention::
-
-	This is a temporary API and it shall be replaced by the generic
-	clock API, when the latter becomes widely available.
-
-Many subdevices, like camera sensors, TV decoders and encoders, need a clock
-signal to be supplied by the system. Often this clock is supplied by the
-respective bridge device. The Linux kernel provides a Common Clock Framework for
-this purpose. However, it is not (yet) available on all architectures. Besides,
-the nature of the multi-functional (clock, data + synchronisation, I2C control)
-connection of subdevices to the system might impose special requirements on the
-clock API usage. E.g. V4L2 has to support clock provider driver unregistration
-while a subdevice driver is holding a reference to the clock. For these reasons
-a V4L2 clock helper API has been developed and is provided to bridge and
-subdevice drivers.
-
-The API consists of two parts: two functions to register and unregister a V4L2
-clock source: v4l2_clk_register() and v4l2_clk_unregister() and calls to control
-a clock object, similar to the respective generic clock API calls:
-v4l2_clk_get(), v4l2_clk_put(), v4l2_clk_enable(), v4l2_clk_disable(),
-v4l2_clk_get_rate(), and v4l2_clk_set_rate(). Clock suppliers have to provide
-clock operations that will be called when clock users invoke respective API
-methods.
-
-It is expected that once the CCF becomes available on all relevant
-architectures this API will be removed.
diff --git a/Documentation/media/kapi/v4l2-common.rst b/Documentation/media/kapi/v4l2-common.rst
deleted file mode 100644
index b1e70eb56aa4..000000000000
--- a/Documentation/media/kapi/v4l2-common.rst
+++ /dev/null
@@ -1,8 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-V4L2 common functions and data structures
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-.. kernel-doc:: include/media/v4l2-common.h
-
-.. kernel-doc:: include/media/v4l2-ioctl.h
diff --git a/Documentation/media/kapi/v4l2-controls.rst b/Documentation/media/kapi/v4l2-controls.rst
deleted file mode 100644
index 5129019afb49..000000000000
--- a/Documentation/media/kapi/v4l2-controls.rst
+++ /dev/null
@@ -1,823 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-V4L2 Controls
-=============
-
-Introduction
-------------
-
-The V4L2 control API seems simple enough, but quickly becomes very hard to
-implement correctly in drivers. But much of the code needed to handle controls
-is actually not driver specific and can be moved to the V4L core framework.
-
-After all, the only part that a driver developer is interested in is:
-
-1) How do I add a control?
-2) How do I set the control's value? (i.e. s_ctrl)
-
-And occasionally:
-
-3) How do I get the control's value? (i.e. g_volatile_ctrl)
-4) How do I validate the user's proposed control value? (i.e. try_ctrl)
-
-All the rest is something that can be done centrally.
-
-The control framework was created in order to implement all the rules of the
-V4L2 specification with respect to controls in a central place. And to make
-life as easy as possible for the driver developer.
-
-Note that the control framework relies on the presence of a struct
-:c:type:`v4l2_device` for V4L2 drivers and struct :c:type:`v4l2_subdev` for
-sub-device drivers.
-
-
-Objects in the framework
-------------------------
-
-There are two main objects:
-
-The :c:type:`v4l2_ctrl` object describes the control properties and keeps
-track of the control's value (both the current value and the proposed new
-value).
-
-:c:type:`v4l2_ctrl_handler` is the object that keeps track of controls. It
-maintains a list of v4l2_ctrl objects that it owns and another list of
-references to controls, possibly to controls owned by other handlers.
-
-
-Basic usage for V4L2 and sub-device drivers
--------------------------------------------
-
-1) Prepare the driver:
-
-.. code-block:: c
-
-	#include <media/v4l2-ctrls.h>
-
-1.1) Add the handler to your driver's top-level struct:
-
-For V4L2 drivers:
-
-.. code-block:: c
-
-	struct foo_dev {
-		...
-		struct v4l2_device v4l2_dev;
-		...
-		struct v4l2_ctrl_handler ctrl_handler;
-		...
-	};
-
-For sub-device drivers:
-
-.. code-block:: c
-
-	struct foo_dev {
-		...
-		struct v4l2_subdev sd;
-		...
-		struct v4l2_ctrl_handler ctrl_handler;
-		...
-	};
-
-1.2) Initialize the handler:
-
-.. code-block:: c
-
-	v4l2_ctrl_handler_init(&foo->ctrl_handler, nr_of_controls);
-
-The second argument is a hint telling the function how many controls this
-handler is expected to handle. It will allocate a hashtable based on this
-information. It is a hint only.
-
-1.3) Hook the control handler into the driver:
-
-For V4L2 drivers:
-
-.. code-block:: c
-
-	foo->v4l2_dev.ctrl_handler = &foo->ctrl_handler;
-
-For sub-device drivers:
-
-.. code-block:: c
-
-	foo->sd.ctrl_handler = &foo->ctrl_handler;
-
-1.4) Clean up the handler at the end:
-
-.. code-block:: c
-
-	v4l2_ctrl_handler_free(&foo->ctrl_handler);
-
-
-2) Add controls:
-
-You add non-menu controls by calling :c:func:`v4l2_ctrl_new_std`:
-
-.. code-block:: c
-
-	struct v4l2_ctrl *v4l2_ctrl_new_std(struct v4l2_ctrl_handler *hdl,
-			const struct v4l2_ctrl_ops *ops,
-			u32 id, s32 min, s32 max, u32 step, s32 def);
-
-Menu and integer menu controls are added by calling
-:c:func:`v4l2_ctrl_new_std_menu`:
-
-.. code-block:: c
-
-	struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl,
-			const struct v4l2_ctrl_ops *ops,
-			u32 id, s32 max, s32 skip_mask, s32 def);
-
-Menu controls with a driver specific menu are added by calling
-:c:func:`v4l2_ctrl_new_std_menu_items`:
-
-.. code-block:: c
-
-       struct v4l2_ctrl *v4l2_ctrl_new_std_menu_items(
-                       struct v4l2_ctrl_handler *hdl,
-                       const struct v4l2_ctrl_ops *ops, u32 id, s32 max,
-                       s32 skip_mask, s32 def, const char * const *qmenu);
-
-Standard compound controls can be added by calling
-:c:func:`v4l2_ctrl_new_std_compound`:
-
-.. code-block:: c
-
-       struct v4l2_ctrl *v4l2_ctrl_new_std_compound(struct v4l2_ctrl_handler *hdl,
-                       const struct v4l2_ctrl_ops *ops, u32 id,
-                       const union v4l2_ctrl_ptr p_def);
-
-Integer menu controls with a driver specific menu can be added by calling
-:c:func:`v4l2_ctrl_new_int_menu`:
-
-.. code-block:: c
-
-	struct v4l2_ctrl *v4l2_ctrl_new_int_menu(struct v4l2_ctrl_handler *hdl,
-			const struct v4l2_ctrl_ops *ops,
-			u32 id, s32 max, s32 def, const s64 *qmenu_int);
-
-These functions are typically called right after the
-:c:func:`v4l2_ctrl_handler_init`:
-
-.. code-block:: c
-
-	static const s64 exp_bias_qmenu[] = {
-	       -2, -1, 0, 1, 2
-	};
-	static const char * const test_pattern[] = {
-		"Disabled",
-		"Vertical Bars",
-		"Solid Black",
-		"Solid White",
-	};
-
-	v4l2_ctrl_handler_init(&foo->ctrl_handler, nr_of_controls);
-	v4l2_ctrl_new_std(&foo->ctrl_handler, &foo_ctrl_ops,
-			V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
-	v4l2_ctrl_new_std(&foo->ctrl_handler, &foo_ctrl_ops,
-			V4L2_CID_CONTRAST, 0, 255, 1, 128);
-	v4l2_ctrl_new_std_menu(&foo->ctrl_handler, &foo_ctrl_ops,
-			V4L2_CID_POWER_LINE_FREQUENCY,
-			V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0,
-			V4L2_CID_POWER_LINE_FREQUENCY_DISABLED);
-	v4l2_ctrl_new_int_menu(&foo->ctrl_handler, &foo_ctrl_ops,
-			V4L2_CID_EXPOSURE_BIAS,
-			ARRAY_SIZE(exp_bias_qmenu) - 1,
-			ARRAY_SIZE(exp_bias_qmenu) / 2 - 1,
-			exp_bias_qmenu);
-	v4l2_ctrl_new_std_menu_items(&foo->ctrl_handler, &foo_ctrl_ops,
-			V4L2_CID_TEST_PATTERN, ARRAY_SIZE(test_pattern) - 1, 0,
-			0, test_pattern);
-	...
-	if (foo->ctrl_handler.error) {
-		int err = foo->ctrl_handler.error;
-
-		v4l2_ctrl_handler_free(&foo->ctrl_handler);
-		return err;
-	}
-
-The :c:func:`v4l2_ctrl_new_std` function returns the v4l2_ctrl pointer to
-the new control, but if you do not need to access the pointer outside the
-control ops, then there is no need to store it.
-
-The :c:func:`v4l2_ctrl_new_std` function will fill in most fields based on
-the control ID except for the min, max, step and default values. These are
-passed in the last four arguments. These values are driver specific while
-control attributes like type, name, flags are all global. The control's
-current value will be set to the default value.
-
-The :c:func:`v4l2_ctrl_new_std_menu` function is very similar but it is
-used for menu controls. There is no min argument since that is always 0 for
-menu controls, and instead of a step there is a skip_mask argument: if bit
-X is 1, then menu item X is skipped.
-
-The :c:func:`v4l2_ctrl_new_int_menu` function creates a new standard
-integer menu control with driver-specific items in the menu. It differs
-from v4l2_ctrl_new_std_menu in that it doesn't have the mask argument and
-takes as the last argument an array of signed 64-bit integers that form an
-exact menu item list.
-
-The :c:func:`v4l2_ctrl_new_std_menu_items` function is very similar to
-v4l2_ctrl_new_std_menu but takes an extra parameter qmenu, which is the
-driver specific menu for an otherwise standard menu control. A good example
-for this control is the test pattern control for capture/display/sensors
-devices that have the capability to generate test patterns. These test
-patterns are hardware specific, so the contents of the menu will vary from
-device to device.
-
-Note that if something fails, the function will return NULL or an error and
-set ctrl_handler->error to the error code. If ctrl_handler->error was already
-set, then it will just return and do nothing. This is also true for
-v4l2_ctrl_handler_init if it cannot allocate the internal data structure.
-
-This makes it easy to init the handler and just add all controls and only check
-the error code at the end. Saves a lot of repetitive error checking.
-
-It is recommended to add controls in ascending control ID order: it will be
-a bit faster that way.
-
-3) Optionally force initial control setup:
-
-.. code-block:: c
-
-	v4l2_ctrl_handler_setup(&foo->ctrl_handler);
-
-This will call s_ctrl for all controls unconditionally. Effectively this
-initializes the hardware to the default control values. It is recommended
-that you do this as this ensures that both the internal data structures and
-the hardware are in sync.
-
-4) Finally: implement the :c:type:`v4l2_ctrl_ops`
-
-.. code-block:: c
-
-	static const struct v4l2_ctrl_ops foo_ctrl_ops = {
-		.s_ctrl = foo_s_ctrl,
-	};
-
-Usually all you need is s_ctrl:
-
-.. code-block:: c
-
-	static int foo_s_ctrl(struct v4l2_ctrl *ctrl)
-	{
-		struct foo *state = container_of(ctrl->handler, struct foo, ctrl_handler);
-
-		switch (ctrl->id) {
-		case V4L2_CID_BRIGHTNESS:
-			write_reg(0x123, ctrl->val);
-			break;
-		case V4L2_CID_CONTRAST:
-			write_reg(0x456, ctrl->val);
-			break;
-		}
-		return 0;
-	}
-
-The control ops are called with the v4l2_ctrl pointer as argument.
-The new control value has already been validated, so all you need to do is
-to actually update the hardware registers.
-
-You're done! And this is sufficient for most of the drivers we have. No need
-to do any validation of control values, or implement QUERYCTRL, QUERY_EXT_CTRL
-and QUERYMENU. And G/S_CTRL as well as G/TRY/S_EXT_CTRLS are automatically supported.
-
-
-.. note::
-
-   The remainder sections deal with more advanced controls topics and scenarios.
-   In practice the basic usage as described above is sufficient for most drivers.
-
-
-Inheriting Sub-device Controls
-------------------------------
-
-When a sub-device is registered with a V4L2 driver by calling
-v4l2_device_register_subdev() and the ctrl_handler fields of both v4l2_subdev
-and v4l2_device are set, then the controls of the subdev will become
-automatically available in the V4L2 driver as well. If the subdev driver
-contains controls that already exist in the V4L2 driver, then those will be
-skipped (so a V4L2 driver can always override a subdev control).
-
-What happens here is that v4l2_device_register_subdev() calls
-v4l2_ctrl_add_handler() adding the controls of the subdev to the controls
-of v4l2_device.
-
-
-Accessing Control Values
-------------------------
-
-The following union is used inside the control framework to access control
-values:
-
-.. code-block:: c
-
-	union v4l2_ctrl_ptr {
-		s32 *p_s32;
-		s64 *p_s64;
-		char *p_char;
-		void *p;
-	};
-
-The v4l2_ctrl struct contains these fields that can be used to access both
-current and new values:
-
-.. code-block:: c
-
-	s32 val;
-	struct {
-		s32 val;
-	} cur;
-
-
-	union v4l2_ctrl_ptr p_new;
-	union v4l2_ctrl_ptr p_cur;
-
-If the control has a simple s32 type type, then:
-
-.. code-block:: c
-
-	&ctrl->val == ctrl->p_new.p_s32
-	&ctrl->cur.val == ctrl->p_cur.p_s32
-
-For all other types use ctrl->p_cur.p<something>. Basically the val
-and cur.val fields can be considered an alias since these are used so often.
-
-Within the control ops you can freely use these. The val and cur.val speak for
-themselves. The p_char pointers point to character buffers of length
-ctrl->maximum + 1, and are always 0-terminated.
-
-Unless the control is marked volatile the p_cur field points to the the
-current cached control value. When you create a new control this value is made
-identical to the default value. After calling v4l2_ctrl_handler_setup() this
-value is passed to the hardware. It is generally a good idea to call this
-function.
-
-Whenever a new value is set that new value is automatically cached. This means
-that most drivers do not need to implement the g_volatile_ctrl() op. The
-exception is for controls that return a volatile register such as a signal
-strength read-out that changes continuously. In that case you will need to
-implement g_volatile_ctrl like this:
-
-.. code-block:: c
-
-	static int foo_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
-	{
-		switch (ctrl->id) {
-		case V4L2_CID_BRIGHTNESS:
-			ctrl->val = read_reg(0x123);
-			break;
-		}
-	}
-
-Note that you use the 'new value' union as well in g_volatile_ctrl. In general
-controls that need to implement g_volatile_ctrl are read-only controls. If they
-are not, a V4L2_EVENT_CTRL_CH_VALUE will not be generated when the control
-changes.
-
-To mark a control as volatile you have to set V4L2_CTRL_FLAG_VOLATILE:
-
-.. code-block:: c
-
-	ctrl = v4l2_ctrl_new_std(&sd->ctrl_handler, ...);
-	if (ctrl)
-		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
-
-For try/s_ctrl the new values (i.e. as passed by the user) are filled in and
-you can modify them in try_ctrl or set them in s_ctrl. The 'cur' union
-contains the current value, which you can use (but not change!) as well.
-
-If s_ctrl returns 0 (OK), then the control framework will copy the new final
-values to the 'cur' union.
-
-While in g_volatile/s/try_ctrl you can access the value of all controls owned
-by the same handler since the handler's lock is held. If you need to access
-the value of controls owned by other handlers, then you have to be very careful
-not to introduce deadlocks.
-
-Outside of the control ops you have to go through to helper functions to get
-or set a single control value safely in your driver:
-
-.. code-block:: c
-
-	s32 v4l2_ctrl_g_ctrl(struct v4l2_ctrl *ctrl);
-	int v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val);
-
-These functions go through the control framework just as VIDIOC_G/S_CTRL ioctls
-do. Don't use these inside the control ops g_volatile/s/try_ctrl, though, that
-will result in a deadlock since these helpers lock the handler as well.
-
-You can also take the handler lock yourself:
-
-.. code-block:: c
-
-	mutex_lock(&state->ctrl_handler.lock);
-	pr_info("String value is '%s'\n", ctrl1->p_cur.p_char);
-	pr_info("Integer value is '%s'\n", ctrl2->cur.val);
-	mutex_unlock(&state->ctrl_handler.lock);
-
-
-Menu Controls
--------------
-
-The v4l2_ctrl struct contains this union:
-
-.. code-block:: c
-
-	union {
-		u32 step;
-		u32 menu_skip_mask;
-	};
-
-For menu controls menu_skip_mask is used. What it does is that it allows you
-to easily exclude certain menu items. This is used in the VIDIOC_QUERYMENU
-implementation where you can return -EINVAL if a certain menu item is not
-present. Note that VIDIOC_QUERYCTRL always returns a step value of 1 for
-menu controls.
-
-A good example is the MPEG Audio Layer II Bitrate menu control where the
-menu is a list of standardized possible bitrates. But in practice hardware
-implementations will only support a subset of those. By setting the skip
-mask you can tell the framework which menu items should be skipped. Setting
-it to 0 means that all menu items are supported.
-
-You set this mask either through the v4l2_ctrl_config struct for a custom
-control, or by calling v4l2_ctrl_new_std_menu().
-
-
-Custom Controls
----------------
-
-Driver specific controls can be created using v4l2_ctrl_new_custom():
-
-.. code-block:: c
-
-	static const struct v4l2_ctrl_config ctrl_filter = {
-		.ops = &ctrl_custom_ops,
-		.id = V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER,
-		.name = "Spatial Filter",
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.flags = V4L2_CTRL_FLAG_SLIDER,
-		.max = 15,
-		.step = 1,
-	};
-
-	ctrl = v4l2_ctrl_new_custom(&foo->ctrl_handler, &ctrl_filter, NULL);
-
-The last argument is the priv pointer which can be set to driver-specific
-private data.
-
-The v4l2_ctrl_config struct also has a field to set the is_private flag.
-
-If the name field is not set, then the framework will assume this is a standard
-control and will fill in the name, type and flags fields accordingly.
-
-
-Active and Grabbed Controls
----------------------------
-
-If you get more complex relationships between controls, then you may have to
-activate and deactivate controls. For example, if the Chroma AGC control is
-on, then the Chroma Gain control is inactive. That is, you may set it, but
-the value will not be used by the hardware as long as the automatic gain
-control is on. Typically user interfaces can disable such input fields.
-
-You can set the 'active' status using v4l2_ctrl_activate(). By default all
-controls are active. Note that the framework does not check for this flag.
-It is meant purely for GUIs. The function is typically called from within
-s_ctrl.
-
-The other flag is the 'grabbed' flag. A grabbed control means that you cannot
-change it because it is in use by some resource. Typical examples are MPEG
-bitrate controls that cannot be changed while capturing is in progress.
-
-If a control is set to 'grabbed' using v4l2_ctrl_grab(), then the framework
-will return -EBUSY if an attempt is made to set this control. The
-v4l2_ctrl_grab() function is typically called from the driver when it
-starts or stops streaming.
-
-
-Control Clusters
-----------------
-
-By default all controls are independent from the others. But in more
-complex scenarios you can get dependencies from one control to another.
-In that case you need to 'cluster' them:
-
-.. code-block:: c
-
-	struct foo {
-		struct v4l2_ctrl_handler ctrl_handler;
-	#define AUDIO_CL_VOLUME (0)
-	#define AUDIO_CL_MUTE   (1)
-		struct v4l2_ctrl *audio_cluster[2];
-		...
-	};
-
-	state->audio_cluster[AUDIO_CL_VOLUME] =
-		v4l2_ctrl_new_std(&state->ctrl_handler, ...);
-	state->audio_cluster[AUDIO_CL_MUTE] =
-		v4l2_ctrl_new_std(&state->ctrl_handler, ...);
-	v4l2_ctrl_cluster(ARRAY_SIZE(state->audio_cluster), state->audio_cluster);
-
-From now on whenever one or more of the controls belonging to the same
-cluster is set (or 'gotten', or 'tried'), only the control ops of the first
-control ('volume' in this example) is called. You effectively create a new
-composite control. Similar to how a 'struct' works in C.
-
-So when s_ctrl is called with V4L2_CID_AUDIO_VOLUME as argument, you should set
-all two controls belonging to the audio_cluster:
-
-.. code-block:: c
-
-	static int foo_s_ctrl(struct v4l2_ctrl *ctrl)
-	{
-		struct foo *state = container_of(ctrl->handler, struct foo, ctrl_handler);
-
-		switch (ctrl->id) {
-		case V4L2_CID_AUDIO_VOLUME: {
-			struct v4l2_ctrl *mute = ctrl->cluster[AUDIO_CL_MUTE];
-
-			write_reg(0x123, mute->val ? 0 : ctrl->val);
-			break;
-		}
-		case V4L2_CID_CONTRAST:
-			write_reg(0x456, ctrl->val);
-			break;
-		}
-		return 0;
-	}
-
-In the example above the following are equivalent for the VOLUME case:
-
-.. code-block:: c
-
-	ctrl == ctrl->cluster[AUDIO_CL_VOLUME] == state->audio_cluster[AUDIO_CL_VOLUME]
-	ctrl->cluster[AUDIO_CL_MUTE] == state->audio_cluster[AUDIO_CL_MUTE]
-
-In practice using cluster arrays like this becomes very tiresome. So instead
-the following equivalent method is used:
-
-.. code-block:: c
-
-	struct {
-		/* audio cluster */
-		struct v4l2_ctrl *volume;
-		struct v4l2_ctrl *mute;
-	};
-
-The anonymous struct is used to clearly 'cluster' these two control pointers,
-but it serves no other purpose. The effect is the same as creating an
-array with two control pointers. So you can just do:
-
-.. code-block:: c
-
-	state->volume = v4l2_ctrl_new_std(&state->ctrl_handler, ...);
-	state->mute = v4l2_ctrl_new_std(&state->ctrl_handler, ...);
-	v4l2_ctrl_cluster(2, &state->volume);
-
-And in foo_s_ctrl you can use these pointers directly: state->mute->val.
-
-Note that controls in a cluster may be NULL. For example, if for some
-reason mute was never added (because the hardware doesn't support that
-particular feature), then mute will be NULL. So in that case we have a
-cluster of 2 controls, of which only 1 is actually instantiated. The
-only restriction is that the first control of the cluster must always be
-present, since that is the 'master' control of the cluster. The master
-control is the one that identifies the cluster and that provides the
-pointer to the v4l2_ctrl_ops struct that is used for that cluster.
-
-Obviously, all controls in the cluster array must be initialized to either
-a valid control or to NULL.
-
-In rare cases you might want to know which controls of a cluster actually
-were set explicitly by the user. For this you can check the 'is_new' flag of
-each control. For example, in the case of a volume/mute cluster the 'is_new'
-flag of the mute control would be set if the user called VIDIOC_S_CTRL for
-mute only. If the user would call VIDIOC_S_EXT_CTRLS for both mute and volume
-controls, then the 'is_new' flag would be 1 for both controls.
-
-The 'is_new' flag is always 1 when called from v4l2_ctrl_handler_setup().
-
-
-Handling autogain/gain-type Controls with Auto Clusters
--------------------------------------------------------
-
-A common type of control cluster is one that handles 'auto-foo/foo'-type
-controls. Typical examples are autogain/gain, autoexposure/exposure,
-autowhitebalance/red balance/blue balance. In all cases you have one control
-that determines whether another control is handled automatically by the hardware,
-or whether it is under manual control from the user.
-
-If the cluster is in automatic mode, then the manual controls should be
-marked inactive and volatile. When the volatile controls are read the
-g_volatile_ctrl operation should return the value that the hardware's automatic
-mode set up automatically.
-
-If the cluster is put in manual mode, then the manual controls should become
-active again and the volatile flag is cleared (so g_volatile_ctrl is no longer
-called while in manual mode). In addition just before switching to manual mode
-the current values as determined by the auto mode are copied as the new manual
-values.
-
-Finally the V4L2_CTRL_FLAG_UPDATE should be set for the auto control since
-changing that control affects the control flags of the manual controls.
-
-In order to simplify this a special variation of v4l2_ctrl_cluster was
-introduced:
-
-.. code-block:: c
-
-	void v4l2_ctrl_auto_cluster(unsigned ncontrols, struct v4l2_ctrl **controls,
-				    u8 manual_val, bool set_volatile);
-
-The first two arguments are identical to v4l2_ctrl_cluster. The third argument
-tells the framework which value switches the cluster into manual mode. The
-last argument will optionally set V4L2_CTRL_FLAG_VOLATILE for the non-auto controls.
-If it is false, then the manual controls are never volatile. You would typically
-use that if the hardware does not give you the option to read back to values as
-determined by the auto mode (e.g. if autogain is on, the hardware doesn't allow
-you to obtain the current gain value).
-
-The first control of the cluster is assumed to be the 'auto' control.
-
-Using this function will ensure that you don't need to handle all the complex
-flag and volatile handling.
-
-
-VIDIOC_LOG_STATUS Support
--------------------------
-
-This ioctl allow you to dump the current status of a driver to the kernel log.
-The v4l2_ctrl_handler_log_status(ctrl_handler, prefix) can be used to dump the
-value of the controls owned by the given handler to the log. You can supply a
-prefix as well. If the prefix didn't end with a space, then ': ' will be added
-for you.
-
-
-Different Handlers for Different Video Nodes
---------------------------------------------
-
-Usually the V4L2 driver has just one control handler that is global for
-all video nodes. But you can also specify different control handlers for
-different video nodes. You can do that by manually setting the ctrl_handler
-field of struct video_device.
-
-That is no problem if there are no subdevs involved but if there are, then
-you need to block the automatic merging of subdev controls to the global
-control handler. You do that by simply setting the ctrl_handler field in
-struct v4l2_device to NULL. Now v4l2_device_register_subdev() will no longer
-merge subdev controls.
-
-After each subdev was added, you will then have to call v4l2_ctrl_add_handler
-manually to add the subdev's control handler (sd->ctrl_handler) to the desired
-control handler. This control handler may be specific to the video_device or
-for a subset of video_device's. For example: the radio device nodes only have
-audio controls, while the video and vbi device nodes share the same control
-handler for the audio and video controls.
-
-If you want to have one handler (e.g. for a radio device node) have a subset
-of another handler (e.g. for a video device node), then you should first add
-the controls to the first handler, add the other controls to the second
-handler and finally add the first handler to the second. For example:
-
-.. code-block:: c
-
-	v4l2_ctrl_new_std(&radio_ctrl_handler, &radio_ops, V4L2_CID_AUDIO_VOLUME, ...);
-	v4l2_ctrl_new_std(&radio_ctrl_handler, &radio_ops, V4L2_CID_AUDIO_MUTE, ...);
-	v4l2_ctrl_new_std(&video_ctrl_handler, &video_ops, V4L2_CID_BRIGHTNESS, ...);
-	v4l2_ctrl_new_std(&video_ctrl_handler, &video_ops, V4L2_CID_CONTRAST, ...);
-	v4l2_ctrl_add_handler(&video_ctrl_handler, &radio_ctrl_handler, NULL);
-
-The last argument to v4l2_ctrl_add_handler() is a filter function that allows
-you to filter which controls will be added. Set it to NULL if you want to add
-all controls.
-
-Or you can add specific controls to a handler:
-
-.. code-block:: c
-
-	volume = v4l2_ctrl_new_std(&video_ctrl_handler, &ops, V4L2_CID_AUDIO_VOLUME, ...);
-	v4l2_ctrl_new_std(&video_ctrl_handler, &ops, V4L2_CID_BRIGHTNESS, ...);
-	v4l2_ctrl_new_std(&video_ctrl_handler, &ops, V4L2_CID_CONTRAST, ...);
-
-What you should not do is make two identical controls for two handlers.
-For example:
-
-.. code-block:: c
-
-	v4l2_ctrl_new_std(&radio_ctrl_handler, &radio_ops, V4L2_CID_AUDIO_MUTE, ...);
-	v4l2_ctrl_new_std(&video_ctrl_handler, &video_ops, V4L2_CID_AUDIO_MUTE, ...);
-
-This would be bad since muting the radio would not change the video mute
-control. The rule is to have one control for each hardware 'knob' that you
-can twiddle.
-
-
-Finding Controls
-----------------
-
-Normally you have created the controls yourself and you can store the struct
-v4l2_ctrl pointer into your own struct.
-
-But sometimes you need to find a control from another handler that you do
-not own. For example, if you have to find a volume control from a subdev.
-
-You can do that by calling v4l2_ctrl_find:
-
-.. code-block:: c
-
-	struct v4l2_ctrl *volume;
-
-	volume = v4l2_ctrl_find(sd->ctrl_handler, V4L2_CID_AUDIO_VOLUME);
-
-Since v4l2_ctrl_find will lock the handler you have to be careful where you
-use it. For example, this is not a good idea:
-
-.. code-block:: c
-
-	struct v4l2_ctrl_handler ctrl_handler;
-
-	v4l2_ctrl_new_std(&ctrl_handler, &video_ops, V4L2_CID_BRIGHTNESS, ...);
-	v4l2_ctrl_new_std(&ctrl_handler, &video_ops, V4L2_CID_CONTRAST, ...);
-
-...and in video_ops.s_ctrl:
-
-.. code-block:: c
-
-	case V4L2_CID_BRIGHTNESS:
-		contrast = v4l2_find_ctrl(&ctrl_handler, V4L2_CID_CONTRAST);
-		...
-
-When s_ctrl is called by the framework the ctrl_handler.lock is already taken, so
-attempting to find another control from the same handler will deadlock.
-
-It is recommended not to use this function from inside the control ops.
-
-
-Preventing Controls inheritance
--------------------------------
-
-When one control handler is added to another using v4l2_ctrl_add_handler, then
-by default all controls from one are merged to the other. But a subdev might
-have low-level controls that make sense for some advanced embedded system, but
-not when it is used in consumer-level hardware. In that case you want to keep
-those low-level controls local to the subdev. You can do this by simply
-setting the 'is_private' flag of the control to 1:
-
-.. code-block:: c
-
-	static const struct v4l2_ctrl_config ctrl_private = {
-		.ops = &ctrl_custom_ops,
-		.id = V4L2_CID_...,
-		.name = "Some Private Control",
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.max = 15,
-		.step = 1,
-		.is_private = 1,
-	};
-
-	ctrl = v4l2_ctrl_new_custom(&foo->ctrl_handler, &ctrl_private, NULL);
-
-These controls will now be skipped when v4l2_ctrl_add_handler is called.
-
-
-V4L2_CTRL_TYPE_CTRL_CLASS Controls
-----------------------------------
-
-Controls of this type can be used by GUIs to get the name of the control class.
-A fully featured GUI can make a dialog with multiple tabs with each tab
-containing the controls belonging to a particular control class. The name of
-each tab can be found by querying a special control with ID <control class | 1>.
-
-Drivers do not have to care about this. The framework will automatically add
-a control of this type whenever the first control belonging to a new control
-class is added.
-
-
-Adding Notify Callbacks
------------------------
-
-Sometimes the platform or bridge driver needs to be notified when a control
-from a sub-device driver changes. You can set a notify callback by calling
-this function:
-
-.. code-block:: c
-
-	void v4l2_ctrl_notify(struct v4l2_ctrl *ctrl,
-		void (*notify)(struct v4l2_ctrl *ctrl, void *priv), void *priv);
-
-Whenever the give control changes value the notify callback will be called
-with a pointer to the control and the priv pointer that was passed with
-v4l2_ctrl_notify. Note that the control's handler lock is held when the
-notify function is called.
-
-There can be only one notify function per control handler. Any attempt
-to set another notify function will cause a WARN_ON.
-
-v4l2_ctrl functions and data structures
----------------------------------------
-
-.. kernel-doc:: include/media/v4l2-ctrls.h
diff --git a/Documentation/media/kapi/v4l2-core.rst b/Documentation/media/kapi/v4l2-core.rst
deleted file mode 100644
index 0dcad7a23141..000000000000
--- a/Documentation/media/kapi/v4l2-core.rst
+++ /dev/null
@@ -1,29 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-Video4Linux devices
--------------------
-
-.. toctree::
-    :maxdepth: 1
-
-    v4l2-intro
-    v4l2-dev
-    v4l2-device
-    v4l2-fh
-    v4l2-subdev
-    v4l2-event
-    v4l2-controls
-    v4l2-videobuf
-    v4l2-videobuf2
-    v4l2-clocks
-    v4l2-dv-timings
-    v4l2-flash-led-class
-    v4l2-mc
-    v4l2-mediabus
-    v4l2-mem2mem
-    v4l2-async
-    v4l2-fwnode
-    v4l2-rect
-    v4l2-tuner
-    v4l2-common
-    v4l2-tveeprom
diff --git a/Documentation/media/kapi/v4l2-dev.rst b/Documentation/media/kapi/v4l2-dev.rst
deleted file mode 100644
index 63c064837c00..000000000000
--- a/Documentation/media/kapi/v4l2-dev.rst
+++ /dev/null
@@ -1,375 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-Video device' s internal representation
-=======================================
-
-The actual device nodes in the ``/dev`` directory are created using the
-:c:type:`video_device` struct (``v4l2-dev.h``). This struct can either be
-allocated dynamically or embedded in a larger struct.
-
-To allocate it dynamically use :c:func:`video_device_alloc`:
-
-.. code-block:: c
-
-	struct video_device *vdev = video_device_alloc();
-
-	if (vdev == NULL)
-		return -ENOMEM;
-
-	vdev->release = video_device_release;
-
-If you embed it in a larger struct, then you must set the ``release()``
-callback to your own function:
-
-.. code-block:: c
-
-	struct video_device *vdev = &my_vdev->vdev;
-
-	vdev->release = my_vdev_release;
-
-The ``release()`` callback must be set and it is called when the last user
-of the video device exits.
-
-The default :c:func:`video_device_release` callback currently
-just calls ``kfree`` to free the allocated memory.
-
-There is also a :c:func:`video_device_release_empty` function that does
-nothing (is empty) and should be used if the struct is embedded and there
-is nothing to do when it is released.
-
-You should also set these fields of :c:type:`video_device`:
-
-- :c:type:`video_device`->v4l2_dev: must be set to the :c:type:`v4l2_device`
-  parent device.
-
-- :c:type:`video_device`->name: set to something descriptive and unique.
-
-- :c:type:`video_device`->vfl_dir: set this to ``VFL_DIR_RX`` for capture
-  devices (``VFL_DIR_RX`` has value 0, so this is normally already the
-  default), set to ``VFL_DIR_TX`` for output devices and ``VFL_DIR_M2M`` for mem2mem (codec) devices.
-
-- :c:type:`video_device`->fops: set to the :c:type:`v4l2_file_operations`
-  struct.
-
-- :c:type:`video_device`->ioctl_ops: if you use the :c:type:`v4l2_ioctl_ops`
-  to simplify ioctl maintenance (highly recommended to use this and it might
-  become compulsory in the future!), then set this to your
-  :c:type:`v4l2_ioctl_ops` struct. The :c:type:`video_device`->vfl_type and
-  :c:type:`video_device`->vfl_dir fields are used to disable ops that do not
-  match the type/dir combination. E.g. VBI ops are disabled for non-VBI nodes,
-  and output ops  are disabled for a capture device. This makes it possible to
-  provide just one :c:type:`v4l2_ioctl_ops` struct for both vbi and
-  video nodes.
-
-- :c:type:`video_device`->lock: leave to ``NULL`` if you want to do all the
-  locking  in the driver. Otherwise you give it a pointer to a struct
-  ``mutex_lock`` and before the :c:type:`video_device`->unlocked_ioctl
-  file operation is called this lock will be taken by the core and released
-  afterwards. See the next section for more details.
-
-- :c:type:`video_device`->queue: a pointer to the struct :c:type:`vb2_queue`
-  associated with this device node.
-  If queue is not ``NULL``, and queue->lock is not ``NULL``, then queue->lock
-  is used for the queuing ioctls (``VIDIOC_REQBUFS``, ``CREATE_BUFS``,
-  ``QBUF``, ``DQBUF``,  ``QUERYBUF``, ``PREPARE_BUF``, ``STREAMON`` and
-  ``STREAMOFF``) instead of the lock above.
-  That way the :ref:`vb2 <vb2_framework>` queuing framework does not have
-  to wait for other ioctls.   This queue pointer is also used by the
-  :ref:`vb2 <vb2_framework>` helper functions to check for
-  queuing ownership (i.e. is the filehandle calling it allowed to do the
-  operation).
-
-- :c:type:`video_device`->prio: keeps track of the priorities. Used to
-  implement ``VIDIOC_G_PRIORITY`` and ``VIDIOC_S_PRIORITY``.
-  If left to ``NULL``, then it will use the struct :c:type:`v4l2_prio_state`
-  in :c:type:`v4l2_device`. If you want to have a separate priority state per
-  (group of) device node(s),   then you can point it to your own struct
-  :c:type:`v4l2_prio_state`.
-
-- :c:type:`video_device`->dev_parent: you only set this if v4l2_device was
-  registered with ``NULL`` as the parent ``device`` struct. This only happens
-  in cases where one hardware device has multiple PCI devices that all share
-  the same :c:type:`v4l2_device` core.
-
-  The cx88 driver is an example of this: one core :c:type:`v4l2_device` struct,
-  but   it is used by both a raw video PCI device (cx8800) and a MPEG PCI device
-  (cx8802). Since the :c:type:`v4l2_device` cannot be associated with two PCI
-  devices at the same time it is setup without a parent device. But when the
-  struct :c:type:`video_device` is initialized you **do** know which parent
-  PCI device to use and so you set ``dev_device`` to the correct PCI device.
-
-If you use :c:type:`v4l2_ioctl_ops`, then you should set
-:c:type:`video_device`->unlocked_ioctl to :c:func:`video_ioctl2` in your
-:c:type:`v4l2_file_operations` struct.
-
-In some cases you want to tell the core that a function you had specified in
-your :c:type:`v4l2_ioctl_ops` should be ignored. You can mark such ioctls by
-calling this function before :c:func:`video_register_device` is called:
-
-	:c:func:`v4l2_disable_ioctl <v4l2_disable_ioctl>`
-	(:c:type:`vdev <video_device>`, cmd).
-
-This tends to be needed if based on external factors (e.g. which card is
-being used) you want to turns off certain features in :c:type:`v4l2_ioctl_ops`
-without having to make a new struct.
-
-The :c:type:`v4l2_file_operations` struct is a subset of file_operations.
-The main difference is that the inode argument is omitted since it is never
-used.
-
-If integration with the media framework is needed, you must initialize the
-:c:type:`media_entity` struct embedded in the :c:type:`video_device` struct
-(entity field) by calling :c:func:`media_entity_pads_init`:
-
-.. code-block:: c
-
-	struct media_pad *pad = &my_vdev->pad;
-	int err;
-
-	err = media_entity_pads_init(&vdev->entity, 1, pad);
-
-The pads array must have been previously initialized. There is no need to
-manually set the struct media_entity type and name fields.
-
-A reference to the entity will be automatically acquired/released when the
-video device is opened/closed.
-
-ioctls and locking
-------------------
-
-The V4L core provides optional locking services. The main service is the
-lock field in struct :c:type:`video_device`, which is a pointer to a mutex.
-If you set this pointer, then that will be used by unlocked_ioctl to
-serialize all ioctls.
-
-If you are using the :ref:`videobuf2 framework <vb2_framework>`, then there
-is a second lock that you can set: :c:type:`video_device`->queue->lock. If
-set, then this lock will be used instead of :c:type:`video_device`->lock
-to serialize all queuing ioctls (see the previous section
-for the full list of those ioctls).
-
-The advantage of using a different lock for the queuing ioctls is that for some
-drivers (particularly USB drivers) certain commands such as setting controls
-can take a long time, so you want to use a separate lock for the buffer queuing
-ioctls. That way your ``VIDIOC_DQBUF`` doesn't stall because the driver is busy
-changing the e.g. exposure of the webcam.
-
-Of course, you can always do all the locking yourself by leaving both lock
-pointers at ``NULL``.
-
-If you use the old :ref:`videobuf framework <vb_framework>` then you must
-pass the :c:type:`video_device`->lock to the videobuf queue initialize
-function: if videobuf has to wait for a frame to arrive, then it will
-temporarily unlock the lock and relock it afterwards. If your driver also
-waits in the code, then you should do the same to allow other
-processes to access the device node while the first process is waiting for
-something.
-
-In the case of :ref:`videobuf2 <vb2_framework>` you will need to implement the
-``wait_prepare()`` and ``wait_finish()`` callbacks to unlock/lock if applicable.
-If you use the ``queue->lock`` pointer, then you can use the helper functions
-:c:func:`vb2_ops_wait_prepare` and :c:func:`vb2_ops_wait_finish`.
-
-The implementation of a hotplug disconnect should also take the lock from
-:c:type:`video_device` before calling v4l2_device_disconnect. If you are also
-using :c:type:`video_device`->queue->lock, then you have to first lock
-:c:type:`video_device`->queue->lock followed by :c:type:`video_device`->lock.
-That way you can be sure no ioctl is running when you call
-:c:func:`v4l2_device_disconnect`.
-
-Video device registration
--------------------------
-
-Next you register the video device with :c:func:`video_register_device`.
-This will create the character device for you.
-
-.. code-block:: c
-
-	err = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
-	if (err) {
-		video_device_release(vdev); /* or kfree(my_vdev); */
-		return err;
-	}
-
-If the :c:type:`v4l2_device` parent device has a not ``NULL`` mdev field,
-the video device entity will be automatically registered with the media
-device.
-
-Which device is registered depends on the type argument. The following
-types exist:
-
-========================== ====================	 ==============================
-:c:type:`vfl_devnode_type` Device name		 Usage
-========================== ====================	 ==============================
-``VFL_TYPE_VIDEO``         ``/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
-to let the v4l2 framework pick the first free number. But sometimes users
-want to select a specific node number. It is common that drivers allow
-the user to select a specific device node number through a driver module
-option. That number is then passed to this function and video_register_device
-will attempt to select that device node number. If that number was already
-in use, then the next free device node number will be selected and it
-will send a warning to the kernel log.
-
-Another use-case is if a driver creates many devices. In that case it can
-be useful to place different video devices in separate ranges. For example,
-video capture devices start at 0, video output devices start at 16.
-So you can use the last argument to specify a minimum device node number
-and the v4l2 framework will try to pick the first free number that is equal
-or higher to what you passed. If that fails, then it will just pick the
-first free number.
-
-Since in this case you do not care about a warning about not being able
-to select the specified device node number, you can call the function
-:c:func:`video_register_device_no_warn` instead.
-
-Whenever a device node is created some attributes are also created for you.
-If you look in ``/sys/class/video4linux`` you see the devices. Go into e.g.
-``video0`` and you will see 'name', 'dev_debug' and 'index' attributes. The
-'name' attribute is the 'name' field of the video_device struct. The
-'dev_debug' attribute can be used to enable core debugging. See the next
-section for more detailed information on this.
-
-The 'index' attribute is the index of the device node: for each call to
-:c:func:`video_register_device()` the index is just increased by 1. The
-first video device node you register always starts with index 0.
-
-Users can setup udev rules that utilize the index attribute to make fancy
-device names (e.g. '``mpegX``' for MPEG video capture device nodes).
-
-After the device was successfully registered, then you can use these fields:
-
-- :c:type:`video_device`->vfl_type: the device type passed to
-  :c:func:`video_register_device`.
-- :c:type:`video_device`->minor: the assigned device minor number.
-- :c:type:`video_device`->num: the device node number (i.e. the X in
-  ``videoX``).
-- :c:type:`video_device`->index: the device index number.
-
-If the registration failed, then you need to call
-:c:func:`video_device_release` to free the allocated :c:type:`video_device`
-struct, or free your own struct if the :c:type:`video_device` was embedded in
-it. The ``vdev->release()`` callback will never be called if the registration
-failed, nor should you ever attempt to unregister the device if the
-registration failed.
-
-video device debugging
-----------------------
-
-The 'dev_debug' attribute that is created for each video, vbi, radio or swradio
-device in ``/sys/class/video4linux/<devX>/`` allows you to enable logging of
-file operations.
-
-It is a bitmask and the following bits can be set:
-
-.. tabularcolumns:: |p{5ex}|L|
-
-===== ================================================================
-Mask  Description
-===== ================================================================
-0x01  Log the ioctl name and error code. VIDIOC_(D)QBUF ioctls are
-      only logged if bit 0x08 is also set.
-0x02  Log the ioctl name arguments and error code. VIDIOC_(D)QBUF
-      ioctls are
-      only logged if bit 0x08 is also set.
-0x04  Log the file operations open, release, read, write, mmap and
-      get_unmapped_area. The read and write operations are only
-      logged if bit 0x08 is also set.
-0x08  Log the read and write file operations and the VIDIOC_QBUF and
-      VIDIOC_DQBUF ioctls.
-0x10  Log the poll file operation.
-0x20  Log error and messages in the control operations.
-===== ================================================================
-
-Video device cleanup
---------------------
-
-When the video device nodes have to be removed, either during the unload
-of the driver or because the USB device was disconnected, then you should
-unregister them with:
-
-	:c:func:`video_unregister_device`
-	(:c:type:`vdev <video_device>`);
-
-This will remove the device nodes from sysfs (causing udev to remove them
-from ``/dev``).
-
-After :c:func:`video_unregister_device` returns no new opens can be done.
-However, in the case of USB devices some application might still have one of
-these device nodes open. So after the unregister all file operations (except
-release, of course) will return an error as well.
-
-When the last user of the video device node exits, then the ``vdev->release()``
-callback is called and you can do the final cleanup there.
-
-Don't forget to cleanup the media entity associated with the video device if
-it has been initialized:
-
-	:c:func:`media_entity_cleanup <media_entity_cleanup>`
-	(&vdev->entity);
-
-This can be done from the release callback.
-
-
-helper functions
-----------------
-
-There are a few useful helper functions:
-
-- file and :c:type:`video_device` private data
-
-You can set/get driver private data in the video_device struct using:
-
-	:c:func:`video_get_drvdata <video_get_drvdata>`
-	(:c:type:`vdev <video_device>`);
-
-	:c:func:`video_set_drvdata <video_set_drvdata>`
-	(:c:type:`vdev <video_device>`);
-
-Note that you can safely call :c:func:`video_set_drvdata` before calling
-:c:func:`video_register_device`.
-
-And this function:
-
-	:c:func:`video_devdata <video_devdata>`
-	(struct file \*file);
-
-returns the video_device belonging to the file struct.
-
-The :c:func:`video_devdata` function combines :c:func:`video_get_drvdata`
-with :c:func:`video_devdata`:
-
-	:c:func:`video_drvdata <video_drvdata>`
-	(struct file \*file);
-
-You can go from a :c:type:`video_device` struct to the v4l2_device struct using:
-
-.. code-block:: c
-
-	struct v4l2_device *v4l2_dev = vdev->v4l2_dev;
-
-- Device node name
-
-The :c:type:`video_device` node kernel name can be retrieved using:
-
-	:c:func:`video_device_node_name <video_device_node_name>`
-	(:c:type:`vdev <video_device>`);
-
-The name is used as a hint by userspace tools such as udev. The function
-should be used where possible instead of accessing the video_device::num and
-video_device::minor fields.
-
-video_device functions and data structures
-------------------------------------------
-
-.. kernel-doc:: include/media/v4l2-dev.h
diff --git a/Documentation/media/kapi/v4l2-device.rst b/Documentation/media/kapi/v4l2-device.rst
deleted file mode 100644
index 5e25bf182c18..000000000000
--- a/Documentation/media/kapi/v4l2-device.rst
+++ /dev/null
@@ -1,146 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-V4L2 device instance
---------------------
-
-Each device instance is represented by a struct :c:type:`v4l2_device`.
-Very simple devices can just allocate this struct, but most of the time you
-would embed this struct inside a larger struct.
-
-You must register the device instance by calling:
-
-	:c:func:`v4l2_device_register <v4l2_device_register>`
-	(dev, :c:type:`v4l2_dev <v4l2_device>`).
-
-Registration will initialize the :c:type:`v4l2_device` struct. If the
-dev->driver_data field is ``NULL``, it will be linked to
-:c:type:`v4l2_dev <v4l2_device>` argument.
-
-Drivers that want integration with the media device framework need to set
-dev->driver_data manually to point to the driver-specific device structure
-that embed the struct :c:type:`v4l2_device` instance. This is achieved by a
-``dev_set_drvdata()`` call before registering the V4L2 device instance.
-They must also set the struct :c:type:`v4l2_device` mdev field to point to a
-properly initialized and registered :c:type:`media_device` instance.
-
-If :c:type:`v4l2_dev <v4l2_device>`\ ->name is empty then it will be set to a
-value derived from dev (driver name followed by the bus_id, to be precise).
-If you set it up before  calling :c:func:`v4l2_device_register` then it will
-be untouched. If dev is ``NULL``, then you **must** setup
-:c:type:`v4l2_dev <v4l2_device>`\ ->name before calling
-:c:func:`v4l2_device_register`.
-
-You can use :c:func:`v4l2_device_set_name` to set the name based on a driver
-name and a driver-global atomic_t instance. This will generate names like
-``ivtv0``, ``ivtv1``, etc. If the name ends with a digit, then it will insert
-a dash: ``cx18-0``, ``cx18-1``, etc. This function returns the instance number.
-
-The first ``dev`` argument is normally the ``struct device`` pointer of a
-``pci_dev``, ``usb_interface`` or ``platform_device``. It is rare for dev to
-be ``NULL``, but it happens with ISA devices or when one device creates
-multiple PCI devices, thus making it impossible to associate
-:c:type:`v4l2_dev <v4l2_device>` with a particular parent.
-
-You can also supply a ``notify()`` callback that can be called by sub-devices
-to notify you of events. Whether you need to set this depends on the
-sub-device. Any notifications a sub-device supports must be defined in a header
-in ``include/media/subdevice.h``.
-
-V4L2 devices are unregistered by calling:
-
-	:c:func:`v4l2_device_unregister`
-	(:c:type:`v4l2_dev <v4l2_device>`).
-
-If the dev->driver_data field points to :c:type:`v4l2_dev <v4l2_device>`,
-it will be reset to ``NULL``. Unregistering will also automatically unregister
-all subdevs from the device.
-
-If you have a hotpluggable device (e.g. a USB device), then when a disconnect
-happens the parent device becomes invalid. Since :c:type:`v4l2_device` has a
-pointer to that parent device it has to be cleared as well to mark that the
-parent is gone. To do this call:
-
-	:c:func:`v4l2_device_disconnect`
-	(:c:type:`v4l2_dev <v4l2_device>`).
-
-This does *not* unregister the subdevs, so you still need to call the
-:c:func:`v4l2_device_unregister` function for that. If your driver is not
-hotpluggable, then there is no need to call :c:func:`v4l2_device_disconnect`.
-
-Sometimes you need to iterate over all devices registered by a specific
-driver. This is usually the case if multiple device drivers use the same
-hardware. E.g. the ivtvfb driver is a framebuffer driver that uses the ivtv
-hardware. The same is true for alsa drivers for example.
-
-You can iterate over all registered devices as follows:
-
-.. code-block:: c
-
-	static int callback(struct device *dev, void *p)
-	{
-		struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
-
-		/* test if this device was inited */
-		if (v4l2_dev == NULL)
-			return 0;
-		...
-		return 0;
-	}
-
-	int iterate(void *p)
-	{
-		struct device_driver *drv;
-		int err;
-
-		/* Find driver 'ivtv' on the PCI bus.
-		pci_bus_type is a global. For USB buses use usb_bus_type. */
-		drv = driver_find("ivtv", &pci_bus_type);
-		/* iterate over all ivtv device instances */
-		err = driver_for_each_device(drv, NULL, p, callback);
-		put_driver(drv);
-		return err;
-	}
-
-Sometimes you need to keep a running counter of the device instance. This is
-commonly used to map a device instance to an index of a module option array.
-
-The recommended approach is as follows:
-
-.. code-block:: c
-
-	static atomic_t drv_instance = ATOMIC_INIT(0);
-
-	static int drv_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
-	{
-		...
-		state->instance = atomic_inc_return(&drv_instance) - 1;
-	}
-
-If you have multiple device nodes then it can be difficult to know when it is
-safe to unregister :c:type:`v4l2_device` for hotpluggable devices. For this
-purpose :c:type:`v4l2_device` has refcounting support. The refcount is
-increased whenever :c:func:`video_register_device` is called and it is
-decreased whenever that device node is released. When the refcount reaches
-zero, then the :c:type:`v4l2_device` release() callback is called. You can
-do your final cleanup there.
-
-If other device nodes (e.g. ALSA) are created, then you can increase and
-decrease the refcount manually as well by calling:
-
-	:c:func:`v4l2_device_get`
-	(:c:type:`v4l2_dev <v4l2_device>`).
-
-or:
-
-	:c:func:`v4l2_device_put`
-	(:c:type:`v4l2_dev <v4l2_device>`).
-
-Since the initial refcount is 1 you also need to call
-:c:func:`v4l2_device_put` in the ``disconnect()`` callback (for USB devices)
-or in the ``remove()`` callback (for e.g. PCI devices), otherwise the refcount
-will never reach 0.
-
-v4l2_device functions and data structures
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-.. kernel-doc:: include/media/v4l2-device.h
diff --git a/Documentation/media/kapi/v4l2-dv-timings.rst b/Documentation/media/kapi/v4l2-dv-timings.rst
deleted file mode 100644
index b178f931518b..000000000000
--- a/Documentation/media/kapi/v4l2-dv-timings.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-V4L2 DV Timings functions
-^^^^^^^^^^^^^^^^^^^^^^^^^
-
-.. kernel-doc:: include/media/v4l2-dv-timings.h
diff --git a/Documentation/media/kapi/v4l2-event.rst b/Documentation/media/kapi/v4l2-event.rst
deleted file mode 100644
index a4b7ae2b94d8..000000000000
--- a/Documentation/media/kapi/v4l2-event.rst
+++ /dev/null
@@ -1,181 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-V4L2 events
------------
-
-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 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.
-
-The :c:type:`v4l2_fh` struct has a list of subscribed events on its
-``subscribed`` field.
-
-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
-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.
-
-A good example of these ``replace``/``merge`` callbacks is in v4l2-event.c:
-``ctrls_replace()`` and ``ctrls_merge()`` callbacks for the control event.
-
-.. note::
-	these callbacks can be called from interrupt context, so they must
-	be fast.
-
-In order to queue events to video device, drivers should call:
-
-	:c:func:`v4l2_event_queue <v4l2_event_queue>`
-	(:c:type:`vdev <video_device>`, :c:type:`ev <v4l2_event>`)
-
-The driver's only responsibility is to fill in the type and the data fields.
-The other fields will be filled in by V4L2.
-
-Event subscription
-~~~~~~~~~~~~~~~~~~
-
-Subscribing to an event is via:
-
-	:c:func:`v4l2_event_subscribe <v4l2_event_subscribe>`
-	(:c:type:`fh <v4l2_fh>`, :c:type:`sub <v4l2_event_subscription>` ,
-	elems, :c:type:`ops <v4l2_subscribed_event_ops>`)
-
-
-This function is used to implement :c:type:`video_device`->
-:c:type:`ioctl_ops <v4l2_ioctl_ops>`-> ``vidioc_subscribe_event``,
-but the driver must check first if the driver is able to produce events
-with specified event id, and then should call
-:c:func:`v4l2_event_subscribe` to subscribe the event.
-
-The elems argument is the size of the event queue for this event. If it is 0,
-then the framework will fill in a default value (this depends on the event
-type).
-
-The ops argument allows the driver to specify a number of callbacks:
-
-.. tabularcolumns:: |p{1.5cm}|p{16.0cm}|
-
-======== ==============================================================
-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)
-del      called when a listener stops listening
-replace  replace event 'old' with event 'new'.
-merge    merge event 'old' into event 'new'.
-======== ==============================================================
-
-All 4 callbacks are optional, if you don't want to specify any callbacks
-the ops argument itself maybe ``NULL``.
-
-Unsubscribing an event
-~~~~~~~~~~~~~~~~~~~~~~
-
-Unsubscribing to an event is via:
-
-	:c:func:`v4l2_event_unsubscribe <v4l2_event_unsubscribe>`
-	(:c:type:`fh <v4l2_fh>`, :c:type:`sub <v4l2_event_subscription>`)
-
-This function is used to implement :c:type:`video_device`->
-:c:type:`ioctl_ops <v4l2_ioctl_ops>`-> ``vidioc_unsubscribe_event``.
-A driver may call :c:func:`v4l2_event_unsubscribe` directly unless it
-wants to be involved in unsubscription process.
-
-The special type ``V4L2_EVENT_ALL`` may be used to unsubscribe all events. The
-drivers may want to handle this in a special way.
-
-Check if there's a pending event
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Checking if there's a pending event is via:
-
-	:c:func:`v4l2_event_pending <v4l2_event_pending>`
-	(:c:type:`fh <v4l2_fh>`)
-
-
-This function returns the number of pending events. Useful when implementing
-poll.
-
-How events work
-~~~~~~~~~~~~~~~
-
-Events are delivered to user space through the poll system call. The driver
-can use :c:type:`v4l2_fh`->wait (a wait_queue_head_t) as the argument for
-``poll_wait()``.
-
-There are standard and private events. New standard events must use the
-smallest available event type. The drivers must allocate their events from
-their own class starting from class base. Class base is
-``V4L2_EVENT_PRIVATE_START`` + n * 1000 where n is the lowest available number.
-The first event type in the class is reserved for future use, so the first
-available event type is 'class base + 1'.
-
-An example on how the V4L2 events may be used can be found in the OMAP
-3 ISP driver (``drivers/media/platform/omap3isp``).
-
-A subdev can directly send an event to the :c:type:`v4l2_device` notify
-function with ``V4L2_DEVICE_NOTIFY_EVENT``. This allows the bridge to map
-the subdev that sends the event to the video node(s) associated with the
-subdev that need to be informed about such an event.
-
-V4L2 event functions and data structures
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-.. kernel-doc:: include/media/v4l2-event.h
-
diff --git a/Documentation/media/kapi/v4l2-fh.rst b/Documentation/media/kapi/v4l2-fh.rst
deleted file mode 100644
index 4c62b19af744..000000000000
--- a/Documentation/media/kapi/v4l2-fh.rst
+++ /dev/null
@@ -1,141 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-V4L2 File handlers
-------------------
-
-struct :c:type:`v4l2_fh` provides a way to easily keep file handle specific
-data that is used by the V4L2 framework.
-
-.. attention::
-	New drivers must use struct :c:type:`v4l2_fh`
-	since it is also used to implement priority handling
-	(:ref:`VIDIOC_G_PRIORITY`).
-
-The users of :c:type:`v4l2_fh` (in the V4L2 framework, not the driver) know
-whether a driver uses :c:type:`v4l2_fh` as its ``file->private_data`` pointer
-by testing the ``V4L2_FL_USES_V4L2_FH`` bit in :c:type:`video_device`->flags.
-This bit is set whenever :c:func:`v4l2_fh_init` is called.
-
-struct :c:type:`v4l2_fh` is allocated as a part of the driver's own file handle
-structure and ``file->private_data`` is set to it in the driver's ``open()``
-function by the driver.
-
-In many cases the struct :c:type:`v4l2_fh` will be embedded in a larger
-structure. In that case you should call:
-
-#) :c:func:`v4l2_fh_init` and :c:func:`v4l2_fh_add` in ``open()``
-#) :c:func:`v4l2_fh_del` and :c:func:`v4l2_fh_exit` in ``release()``
-
-Drivers can extract their own file handle structure by using the container_of
-macro.
-
-Example:
-
-.. code-block:: c
-
-	struct my_fh {
-		int blah;
-		struct v4l2_fh fh;
-	};
-
-	...
-
-	int my_open(struct file *file)
-	{
-		struct my_fh *my_fh;
-		struct video_device *vfd;
-		int ret;
-
-		...
-
-		my_fh = kzalloc(sizeof(*my_fh), GFP_KERNEL);
-
-		...
-
-		v4l2_fh_init(&my_fh->fh, vfd);
-
-		...
-
-		file->private_data = &my_fh->fh;
-		v4l2_fh_add(&my_fh->fh);
-		return 0;
-	}
-
-	int my_release(struct file *file)
-	{
-		struct v4l2_fh *fh = file->private_data;
-		struct my_fh *my_fh = container_of(fh, struct my_fh, fh);
-
-		...
-		v4l2_fh_del(&my_fh->fh);
-		v4l2_fh_exit(&my_fh->fh);
-		kfree(my_fh);
-		return 0;
-	}
-
-Below is a short description of the :c:type:`v4l2_fh` functions used:
-
-:c:func:`v4l2_fh_init <v4l2_fh_init>`
-(:c:type:`fh <v4l2_fh>`, :c:type:`vdev <video_device>`)
-
-
-- Initialise the file handle. This **MUST** be performed in the driver's
-  :c:type:`v4l2_file_operations`->open() handler.
-
-
-:c:func:`v4l2_fh_add <v4l2_fh_add>`
-(:c:type:`fh <v4l2_fh>`)
-
-- Add a :c:type:`v4l2_fh` to :c:type:`video_device` file handle list.
-  Must be called once the file handle is completely initialized.
-
-:c:func:`v4l2_fh_del <v4l2_fh_del>`
-(:c:type:`fh <v4l2_fh>`)
-
-- Unassociate the file handle from :c:type:`video_device`. The file handle
-  exit function may now be called.
-
-:c:func:`v4l2_fh_exit <v4l2_fh_exit>`
-(:c:type:`fh <v4l2_fh>`)
-
-- Uninitialise the file handle. After uninitialisation the :c:type:`v4l2_fh`
-  memory can be freed.
-
-
-If struct :c:type:`v4l2_fh` is not embedded, then you can use these helper functions:
-
-:c:func:`v4l2_fh_open <v4l2_fh_open>`
-(struct file \*filp)
-
-- This allocates a struct :c:type:`v4l2_fh`, initializes it and adds it to
-  the struct :c:type:`video_device` associated with the file struct.
-
-:c:func:`v4l2_fh_release <v4l2_fh_release>`
-(struct file \*filp)
-
-- This deletes it from the struct :c:type:`video_device` associated with the
-  file struct, uninitialised the :c:type:`v4l2_fh` and frees it.
-
-These two functions can be plugged into the v4l2_file_operation's ``open()``
-and ``release()`` ops.
-
-Several drivers need to do something when the first file handle is opened and
-when the last file handle closes. Two helper functions were added to check
-whether the :c:type:`v4l2_fh` struct is the only open filehandle of the
-associated device node:
-
-:c:func:`v4l2_fh_is_singular <v4l2_fh_is_singular>`
-(:c:type:`fh <v4l2_fh>`)
-
--  Returns 1 if the file handle is the only open file handle, else 0.
-
-:c:func:`v4l2_fh_is_singular_file <v4l2_fh_is_singular_file>`
-(struct file \*filp)
-
-- Same, but it calls v4l2_fh_is_singular with filp->private_data.
-
-
-V4L2 fh functions and data structures
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-.. kernel-doc:: include/media/v4l2-fh.h
diff --git a/Documentation/media/kapi/v4l2-flash-led-class.rst b/Documentation/media/kapi/v4l2-flash-led-class.rst
deleted file mode 100644
index 2aa6bed9b8db..000000000000
--- a/Documentation/media/kapi/v4l2-flash-led-class.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-V4L2 flash functions and data structures
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-.. kernel-doc:: include/media/v4l2-flash-led-class.h
diff --git a/Documentation/media/kapi/v4l2-fwnode.rst b/Documentation/media/kapi/v4l2-fwnode.rst
deleted file mode 100644
index e313b6cddcd0..000000000000
--- a/Documentation/media/kapi/v4l2-fwnode.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-V4L2 fwnode kAPI
-^^^^^^^^^^^^^^^^
-.. kernel-doc:: include/media/v4l2-fwnode.h
diff --git a/Documentation/media/kapi/v4l2-intro.rst b/Documentation/media/kapi/v4l2-intro.rst
deleted file mode 100644
index 4d54fa9d7a12..000000000000
--- a/Documentation/media/kapi/v4l2-intro.rst
+++ /dev/null
@@ -1,76 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-Introduction
-------------
-
-The V4L2 drivers tend to be very complex due to the complexity of the
-hardware: most devices have multiple ICs, export multiple device nodes in
-/dev, and create also non-V4L2 devices such as DVB, ALSA, FB, I2C and input
-(IR) devices.
-
-Especially the fact that V4L2 drivers have to setup supporting ICs to
-do audio/video muxing/encoding/decoding makes it more complex than most.
-Usually these ICs are connected to the main bridge driver through one or
-more I2C buses, but other buses can also be used. Such devices are
-called 'sub-devices'.
-
-For a long time the framework was limited to the video_device struct for
-creating V4L device nodes and video_buf for handling the video buffers
-(note that this document does not discuss the video_buf framework).
-
-This meant that all drivers had to do the setup of device instances and
-connecting to sub-devices themselves. Some of this is quite complicated
-to do right and many drivers never did do it correctly.
-
-There is also a lot of common code that could never be refactored due to
-the lack of a framework.
-
-So this framework sets up the basic building blocks that all drivers
-need and this same framework should make it much easier to refactor
-common code into utility functions shared by all drivers.
-
-A good example to look at as a reference is the v4l2-pci-skeleton.c
-source that is available in samples/v4l/. It is a skeleton driver for
-a PCI capture card, and demonstrates how to use the V4L2 driver
-framework. It can be used as a template for real PCI video capture driver.
-
-Structure of a V4L driver
--------------------------
-
-All drivers have the following structure:
-
-1) A struct for each device instance containing the device state.
-
-2) A way of initializing and commanding sub-devices (if any).
-
-3) Creating V4L2 device nodes (/dev/videoX, /dev/vbiX and /dev/radioX)
-   and keeping track of device-node specific data.
-
-4) Filehandle-specific structs containing per-filehandle data;
-
-5) video buffer handling.
-
-This is a rough schematic of how it all relates:
-
-.. code-block:: none
-
-    device instances
-      |
-      +-sub-device instances
-      |
-      \-V4L2 device nodes
-	  |
-	  \-filehandle instances
-
-
-Structure of the V4L2 framework
--------------------------------
-
-The framework closely resembles the driver structure: it has a v4l2_device
-struct for the device instance data, a v4l2_subdev struct to refer to
-sub-device instances, the video_device struct stores V4L2 device node data
-and the v4l2_fh struct keeps track of filehandle instances.
-
-The V4L2 framework also optionally integrates with the media framework. If a
-driver sets the struct v4l2_device mdev field, sub-devices and video nodes
-will automatically appear in the media framework as entities.
diff --git a/Documentation/media/kapi/v4l2-mc.rst b/Documentation/media/kapi/v4l2-mc.rst
deleted file mode 100644
index 0c352ac588b2..000000000000
--- a/Documentation/media/kapi/v4l2-mc.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-V4L2 Media Controller functions and data structures
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-.. kernel-doc:: include/media/v4l2-mc.h
diff --git a/Documentation/media/kapi/v4l2-mediabus.rst b/Documentation/media/kapi/v4l2-mediabus.rst
deleted file mode 100644
index 1f2254cba92d..000000000000
--- a/Documentation/media/kapi/v4l2-mediabus.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-V4L2 Media Bus functions and data structures
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-.. kernel-doc:: include/media/v4l2-mediabus.h
diff --git a/Documentation/media/kapi/v4l2-mem2mem.rst b/Documentation/media/kapi/v4l2-mem2mem.rst
deleted file mode 100644
index a43b31cc8261..000000000000
--- a/Documentation/media/kapi/v4l2-mem2mem.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-V4L2 Memory to Memory functions and data structures
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-.. kernel-doc:: include/media/v4l2-mem2mem.h
diff --git a/Documentation/media/kapi/v4l2-rect.rst b/Documentation/media/kapi/v4l2-rect.rst
deleted file mode 100644
index fc315cd84156..000000000000
--- a/Documentation/media/kapi/v4l2-rect.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-V4L2 rect helper functions
-^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-.. kernel-doc:: include/media/v4l2-rect.h
diff --git a/Documentation/media/kapi/v4l2-subdev.rst b/Documentation/media/kapi/v4l2-subdev.rst
deleted file mode 100644
index 29e07e23f888..000000000000
--- a/Documentation/media/kapi/v4l2-subdev.rst
+++ /dev/null
@@ -1,444 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-V4L2 sub-devices
-----------------
-
-Many drivers need to communicate with sub-devices. These devices can do all
-sort of tasks, but most commonly they handle audio and/or video muxing,
-encoding or decoding. For webcams common sub-devices are sensors and camera
-controllers.
-
-Usually these are I2C devices, but not necessarily. In order to provide the
-driver with a consistent interface to these sub-devices the
-:c:type:`v4l2_subdev` struct (v4l2-subdev.h) was created.
-
-Each sub-device driver must have a :c:type:`v4l2_subdev` struct. This struct
-can be stand-alone for simple sub-devices or it might be embedded in a larger
-struct if more state information needs to be stored. Usually there is a
-low-level device struct (e.g. ``i2c_client``) that contains the device data as
-setup by the kernel. It is recommended to store that pointer in the private
-data of :c:type:`v4l2_subdev` using :c:func:`v4l2_set_subdevdata`. That makes
-it easy to go from a :c:type:`v4l2_subdev` to the actual low-level bus-specific
-device data.
-
-You also need a way to go from the low-level struct to :c:type:`v4l2_subdev`.
-For the common i2c_client struct the i2c_set_clientdata() call is used to store
-a :c:type:`v4l2_subdev` pointer, for other buses you may have to use other
-methods.
-
-Bridges might also need to store per-subdev private data, such as a pointer to
-bridge-specific per-subdev private data. The :c:type:`v4l2_subdev` structure
-provides host private data for that purpose that can be accessed with
-:c:func:`v4l2_get_subdev_hostdata` and :c:func:`v4l2_set_subdev_hostdata`.
-
-From the bridge driver perspective, you load the sub-device module and somehow
-obtain the :c:type:`v4l2_subdev` pointer. For i2c devices this is easy: you call
-``i2c_get_clientdata()``. For other buses something similar needs to be done.
-Helper functions exists for sub-devices on an I2C bus that do most of this
-tricky work for you.
-
-Each :c:type:`v4l2_subdev` contains function pointers that sub-device drivers
-can implement (or leave ``NULL`` if it is not applicable). Since sub-devices can
-do so many different things and you do not want to end up with a huge ops struct
-of which only a handful of ops are commonly implemented, the function pointers
-are sorted according to category and each category has its own ops struct.
-
-The top-level ops struct contains pointers to the category ops structs, which
-may be NULL if the subdev driver does not support anything from that category.
-
-It looks like this:
-
-.. code-block:: c
-
-	struct v4l2_subdev_core_ops {
-		int (*log_status)(struct v4l2_subdev *sd);
-		int (*init)(struct v4l2_subdev *sd, u32 val);
-		...
-	};
-
-	struct v4l2_subdev_tuner_ops {
-		...
-	};
-
-	struct v4l2_subdev_audio_ops {
-		...
-	};
-
-	struct v4l2_subdev_video_ops {
-		...
-	};
-
-	struct v4l2_subdev_pad_ops {
-		...
-	};
-
-	struct v4l2_subdev_ops {
-		const struct v4l2_subdev_core_ops  *core;
-		const struct v4l2_subdev_tuner_ops *tuner;
-		const struct v4l2_subdev_audio_ops *audio;
-		const struct v4l2_subdev_video_ops *video;
-		const struct v4l2_subdev_pad_ops *video;
-	};
-
-The core ops are common to all subdevs, the other categories are implemented
-depending on the sub-device. E.g. a video device is unlikely to support the
-audio ops and vice versa.
-
-This setup limits the number of function pointers while still making it easy
-to add new ops and categories.
-
-A sub-device driver initializes the :c:type:`v4l2_subdev` struct using:
-
-	:c:func:`v4l2_subdev_init <v4l2_subdev_init>`
-	(:c:type:`sd <v4l2_subdev>`, &\ :c:type:`ops <v4l2_subdev_ops>`).
-
-
-Afterwards you need to initialize :c:type:`sd <v4l2_subdev>`->name with a
-unique name and set the module owner. This is done for you if you use the
-i2c helper functions.
-
-If integration with the media framework is needed, you must initialize the
-:c:type:`media_entity` struct embedded in the :c:type:`v4l2_subdev` struct
-(entity field) by calling :c:func:`media_entity_pads_init`, if the entity has
-pads:
-
-.. code-block:: c
-
-	struct media_pad *pads = &my_sd->pads;
-	int err;
-
-	err = media_entity_pads_init(&sd->entity, npads, pads);
-
-The pads array must have been previously initialized. There is no need to
-manually set the struct :c:type:`media_entity` function and name fields, but the
-revision field must be initialized if needed.
-
-A reference to the entity will be automatically acquired/released when the
-subdev device node (if any) is opened/closed.
-
-Don't forget to cleanup the media entity before the sub-device is destroyed:
-
-.. code-block:: c
-
-	media_entity_cleanup(&sd->entity);
-
-If the subdev driver intends to process video and integrate with the media
-framework, it must implement format related functionality using
-:c:type:`v4l2_subdev_pad_ops` instead of :c:type:`v4l2_subdev_video_ops`.
-
-In that case, the subdev driver may set the link_validate field to provide
-its own link validation function. The link validation function is called for
-every link in the pipeline where both of the ends of the links are V4L2
-sub-devices. The driver is still responsible for validating the correctness
-of the format configuration between sub-devices and video nodes.
-
-If link_validate op is not set, the default function
-:c:func:`v4l2_subdev_link_validate_default` is used instead. This function
-ensures that width, height and the media bus pixel code are equal on both source
-and sink of the link. Subdev drivers are also free to use this function to
-perform the checks mentioned above in addition to their own checks.
-
-There are currently two ways to register subdevices with the V4L2 core. The
-first (traditional) possibility is to have subdevices registered by bridge
-drivers. This can be done when the bridge driver has the complete information
-about subdevices connected to it and knows exactly when to register them. This
-is typically the case for internal subdevices, like video data processing units
-within SoCs or complex PCI(e) boards, camera sensors in USB cameras or connected
-to SoCs, which pass information about them to bridge drivers, usually in their
-platform data.
-
-There are however also situations where subdevices have to be registered
-asynchronously to bridge devices. An example of such a configuration is a Device
-Tree based system where information about subdevices is made available to the
-system independently from the bridge devices, e.g. when subdevices are defined
-in DT as I2C device nodes. The API used in this second case is described further
-below.
-
-Using one or the other registration method only affects the probing process, the
-run-time bridge-subdevice interaction is in both cases the same.
-
-In the synchronous case a device (bridge) driver needs to register the
-:c:type:`v4l2_subdev` with the v4l2_device:
-
-	:c:func:`v4l2_device_register_subdev <v4l2_device_register_subdev>`
-	(:c:type:`v4l2_dev <v4l2_device>`, :c:type:`sd <v4l2_subdev>`).
-
-This can fail if the subdev module disappeared before it could be registered.
-After this function was called successfully the subdev->dev field points to
-the :c:type:`v4l2_device`.
-
-If the v4l2_device parent device has a non-NULL mdev field, the sub-device
-entity will be automatically registered with the media device.
-
-You can unregister a sub-device using:
-
-	:c:func:`v4l2_device_unregister_subdev <v4l2_device_unregister_subdev>`
-	(:c:type:`sd <v4l2_subdev>`).
-
-
-Afterwards the subdev module can be unloaded and
-:c:type:`sd <v4l2_subdev>`->dev == ``NULL``.
-
-You can call an ops function either directly:
-
-.. code-block:: c
-
-	err = sd->ops->core->g_std(sd, &norm);
-
-but it is better and easier to use this macro:
-
-.. code-block:: c
-
-	err = v4l2_subdev_call(sd, core, g_std, &norm);
-
-The macro will to the right ``NULL`` pointer checks and returns ``-ENODEV``
-if :c:type:`sd <v4l2_subdev>` is ``NULL``, ``-ENOIOCTLCMD`` if either
-:c:type:`sd <v4l2_subdev>`->core or :c:type:`sd <v4l2_subdev>`->core->g_std is ``NULL``, or the actual result of the
-:c:type:`sd <v4l2_subdev>`->ops->core->g_std ops.
-
-It is also possible to call all or a subset of the sub-devices:
-
-.. code-block:: c
-
-	v4l2_device_call_all(v4l2_dev, 0, core, g_std, &norm);
-
-Any subdev that does not support this ops is skipped and error results are
-ignored. If you want to check for errors use this:
-
-.. code-block:: c
-
-	err = v4l2_device_call_until_err(v4l2_dev, 0, core, g_std, &norm);
-
-Any error except ``-ENOIOCTLCMD`` will exit the loop with that error. If no
-errors (except ``-ENOIOCTLCMD``) occurred, then 0 is returned.
-
-The second argument to both calls is a group ID. If 0, then all subdevs are
-called. If non-zero, then only those whose group ID match that value will
-be called. Before a bridge driver registers a subdev it can set
-:c:type:`sd <v4l2_subdev>`->grp_id to whatever value it wants (it's 0 by
-default). This value is owned by the bridge driver and the sub-device driver
-will never modify or use it.
-
-The group ID gives the bridge driver more control how callbacks are called.
-For example, there may be multiple audio chips on a board, each capable of
-changing the volume. But usually only one will actually be used when the
-user want to change the volume. You can set the group ID for that subdev to
-e.g. AUDIO_CONTROLLER and specify that as the group ID value when calling
-``v4l2_device_call_all()``. That ensures that it will only go to the subdev
-that needs it.
-
-If the sub-device needs to notify its v4l2_device parent of an event, then
-it can call ``v4l2_subdev_notify(sd, notification, arg)``. This macro checks
-whether there is a ``notify()`` callback defined and returns ``-ENODEV`` if not.
-Otherwise the result of the ``notify()`` call is returned.
-
-The advantage of using :c:type:`v4l2_subdev` is that it is a generic struct and
-does not contain any knowledge about the underlying hardware. So a driver might
-contain several subdevs that use an I2C bus, but also a subdev that is
-controlled through GPIO pins. This distinction is only relevant when setting
-up the device, but once the subdev is registered it is completely transparent.
-
-In the asynchronous case subdevice probing can be invoked independently of the
-bridge driver availability. The subdevice driver then has to verify whether all
-the requirements for a successful probing are satisfied. This can include a
-check for a master clock availability. If any of the conditions aren't satisfied
-the driver might decide to return ``-EPROBE_DEFER`` to request further reprobing
-attempts. Once all conditions are met the subdevice shall be registered using
-the :c:func:`v4l2_async_register_subdev` function. Unregistration is
-performed using the :c:func:`v4l2_async_unregister_subdev` call. Subdevices
-registered this way are stored in a global list of subdevices, ready to be
-picked up by bridge drivers.
-
-Bridge drivers in turn have to register a notifier object. This is
-performed using the :c:func:`v4l2_async_notifier_register` call. To
-unregister the notifier the driver has to call
-:c:func:`v4l2_async_notifier_unregister`. The former of the two functions
-takes two arguments: a pointer to struct :c:type:`v4l2_device` and a
-pointer to struct :c:type:`v4l2_async_notifier`.
-
-Before registering the notifier, bridge drivers must do two things:
-first, the notifier must be initialized using the
-:c:func:`v4l2_async_notifier_init`. Second, bridge drivers can then
-begin to form a list of subdevice descriptors that the bridge device
-needs for its operation. Subdevice descriptors are added to the notifier
-using the :c:func:`v4l2_async_notifier_add_subdev` call. This function
-takes two arguments: a pointer to struct :c:type:`v4l2_async_notifier`,
-and a pointer to the subdevice descripter, which is of type struct
-:c:type:`v4l2_async_subdev`.
-
-The V4L2 core will then use these descriptors to match asynchronously
-registered subdevices to them. If a match is detected the ``.bound()``
-notifier callback is called. After all subdevices have been located the
-.complete() callback is called. When a subdevice is removed from the
-system the .unbind() method is called. All three callbacks are optional.
-
-V4L2 sub-device userspace API
------------------------------
-
-Beside exposing a kernel API through the :c:type:`v4l2_subdev_ops` structure,
-V4L2 sub-devices can also be controlled directly by userspace applications.
-
-Device nodes named ``v4l-subdev``\ *X* can be created in ``/dev`` to access
-sub-devices directly. If a sub-device supports direct userspace configuration
-it must set the ``V4L2_SUBDEV_FL_HAS_DEVNODE`` flag before being registered.
-
-After registering sub-devices, the :c:type:`v4l2_device` driver can create
-device nodes for all registered sub-devices marked with
-``V4L2_SUBDEV_FL_HAS_DEVNODE`` by calling
-:c:func:`v4l2_device_register_subdev_nodes`. Those device nodes will be
-automatically removed when sub-devices are unregistered.
-
-The device node handles a subset of the V4L2 API.
-
-``VIDIOC_QUERYCTRL``,
-``VIDIOC_QUERYMENU``,
-``VIDIOC_G_CTRL``,
-``VIDIOC_S_CTRL``,
-``VIDIOC_G_EXT_CTRLS``,
-``VIDIOC_S_EXT_CTRLS`` and
-``VIDIOC_TRY_EXT_CTRLS``:
-
-	The controls ioctls are identical to the ones defined in V4L2. They
-	behave identically, with the only exception that they deal only with
-	controls implemented in the sub-device. Depending on the driver, those
-	controls can be also be accessed through one (or several) V4L2 device
-	nodes.
-
-``VIDIOC_DQEVENT``,
-``VIDIOC_SUBSCRIBE_EVENT`` and
-``VIDIOC_UNSUBSCRIBE_EVENT``
-
-	The events ioctls are identical to the ones defined in V4L2. They
-	behave identically, with the only exception that they deal only with
-	events generated by the sub-device. Depending on the driver, those
-	events can also be reported by one (or several) V4L2 device nodes.
-
-	Sub-device drivers that want to use events need to set the
-	``V4L2_SUBDEV_USES_EVENTS`` :c:type:`v4l2_subdev`.flags and initialize
-	:c:type:`v4l2_subdev`.nevents to events queue depth before registering
-	the sub-device. After registration events can be queued as usual on the
-	:c:type:`v4l2_subdev`.devnode device node.
-
-	To properly support events, the ``poll()`` file operation is also
-	implemented.
-
-Private ioctls
-
-	All ioctls not in the above list are passed directly to the sub-device
-	driver through the core::ioctl operation.
-
-
-I2C sub-device drivers
-----------------------
-
-Since these drivers are so common, special helper functions are available to
-ease the use of these drivers (``v4l2-common.h``).
-
-The recommended method of adding :c:type:`v4l2_subdev` support to an I2C driver
-is to embed the :c:type:`v4l2_subdev` struct into the state struct that is
-created for each I2C device instance. Very simple devices have no state
-struct and in that case you can just create a :c:type:`v4l2_subdev` directly.
-
-A typical state struct would look like this (where 'chipname' is replaced by
-the name of the chip):
-
-.. code-block:: c
-
-	struct chipname_state {
-		struct v4l2_subdev sd;
-		...  /* additional state fields */
-	};
-
-Initialize the :c:type:`v4l2_subdev` struct as follows:
-
-.. code-block:: c
-
-	v4l2_i2c_subdev_init(&state->sd, client, subdev_ops);
-
-This function will fill in all the fields of :c:type:`v4l2_subdev` ensure that
-the :c:type:`v4l2_subdev` and i2c_client both point to one another.
-
-You should also add a helper inline function to go from a :c:type:`v4l2_subdev`
-pointer to a chipname_state struct:
-
-.. code-block:: c
-
-	static inline struct chipname_state *to_state(struct v4l2_subdev *sd)
-	{
-		return container_of(sd, struct chipname_state, sd);
-	}
-
-Use this to go from the :c:type:`v4l2_subdev` struct to the ``i2c_client``
-struct:
-
-.. code-block:: c
-
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-And this to go from an ``i2c_client`` to a :c:type:`v4l2_subdev` struct:
-
-.. code-block:: c
-
-	struct v4l2_subdev *sd = i2c_get_clientdata(client);
-
-Make sure to call
-:c:func:`v4l2_device_unregister_subdev`\ (:c:type:`sd <v4l2_subdev>`)
-when the ``remove()`` callback is called. This will unregister the sub-device
-from the bridge driver. It is safe to call this even if the sub-device was
-never registered.
-
-You need to do this because when the bridge driver destroys the i2c adapter
-the ``remove()`` callbacks are called of the i2c devices on that adapter.
-After that the corresponding v4l2_subdev structures are invalid, so they
-have to be unregistered first. Calling
-:c:func:`v4l2_device_unregister_subdev`\ (:c:type:`sd <v4l2_subdev>`)
-from the ``remove()`` callback ensures that this is always done correctly.
-
-
-The bridge driver also has some helper functions it can use:
-
-.. code-block:: c
-
-	struct v4l2_subdev *sd = v4l2_i2c_new_subdev(v4l2_dev, adapter,
-					"module_foo", "chipid", 0x36, NULL);
-
-This loads the given module (can be ``NULL`` if no module needs to be loaded)
-and calls :c:func:`i2c_new_device` with the given ``i2c_adapter`` and
-chip/address arguments. If all goes well, then it registers the subdev with
-the v4l2_device.
-
-You can also use the last argument of :c:func:`v4l2_i2c_new_subdev` to pass
-an array of possible I2C addresses that it should probe. These probe addresses
-are only used if the previous argument is 0. A non-zero argument means that you
-know the exact i2c address so in that case no probing will take place.
-
-Both functions return ``NULL`` if something went wrong.
-
-Note that the chipid you pass to :c:func:`v4l2_i2c_new_subdev` is usually
-the same as the module name. It allows you to specify a chip variant, e.g.
-"saa7114" or "saa7115". In general though the i2c driver autodetects this.
-The use of chipid is something that needs to be looked at more closely at a
-later date. It differs between i2c drivers and as such can be confusing.
-To see which chip variants are supported you can look in the i2c driver code
-for the i2c_device_id table. This lists all the possibilities.
-
-There are one more helper function:
-
-:c:func:`v4l2_i2c_new_subdev_board` uses an :c:type:`i2c_board_info` struct
-which is passed to the i2c driver and replaces the irq, platform_data and addr
-arguments.
-
-If the subdev supports the s_config core ops, then that op is called with
-the irq and platform_data arguments after the subdev was setup.
-
-The :c:func:`v4l2_i2c_new_subdev` function will call
-:c:func:`v4l2_i2c_new_subdev_board`, internally filling a
-:c:type:`i2c_board_info` structure using the ``client_type`` and the
-``addr`` to fill it.
-
-V4L2 sub-device functions and data structures
----------------------------------------------
-
-.. kernel-doc:: include/media/v4l2-subdev.h
-
-.. kernel-doc:: include/media/v4l2-async.h
diff --git a/Documentation/media/kapi/v4l2-tuner.rst b/Documentation/media/kapi/v4l2-tuner.rst
deleted file mode 100644
index e6caa3321566..000000000000
--- a/Documentation/media/kapi/v4l2-tuner.rst
+++ /dev/null
@@ -1,8 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-Tuner functions and data structures
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-.. kernel-doc:: include/media/tuner.h
-
-.. kernel-doc:: include/media/tuner-types.h
diff --git a/Documentation/media/kapi/v4l2-tveeprom.rst b/Documentation/media/kapi/v4l2-tveeprom.rst
deleted file mode 100644
index 43fb391edaba..000000000000
--- a/Documentation/media/kapi/v4l2-tveeprom.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-Hauppauge TV EEPROM functions and data structures
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-.. kernel-doc:: include/media/tveeprom.h
diff --git a/Documentation/media/kapi/v4l2-videobuf.rst b/Documentation/media/kapi/v4l2-videobuf.rst
deleted file mode 100644
index 1a7756397b1a..000000000000
--- a/Documentation/media/kapi/v4l2-videobuf.rst
+++ /dev/null
@@ -1,406 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-.. _vb_framework:
-
-Videobuf Framework
-==================
-
-Author: Jonathan Corbet <corbet@lwn.net>
-
-Current as of 2.6.33
-
-.. note::
-
-   The videobuf framework was deprecated in favor of videobuf2. Shouldn't
-   be used on new drivers.
-
-Introduction
-------------
-
-The videobuf layer functions as a sort of glue layer between a V4L2 driver
-and user space.  It handles the allocation and management of buffers for
-the storage of video frames.  There is a set of functions which can be used
-to implement many of the standard POSIX I/O system calls, including read(),
-poll(), and, happily, mmap().  Another set of functions can be used to
-implement the bulk of the V4L2 ioctl() calls related to streaming I/O,
-including buffer allocation, queueing and dequeueing, and streaming
-control.  Using videobuf imposes a few design decisions on the driver
-author, but the payback comes in the form of reduced code in the driver and
-a consistent implementation of the V4L2 user-space API.
-
-Buffer types
-------------
-
-Not all video devices use the same kind of buffers.  In fact, there are (at
-least) three common variations:
-
- - Buffers which are scattered in both the physical and (kernel) virtual
-   address spaces.  (Almost) all user-space buffers are like this, but it
-   makes great sense to allocate kernel-space buffers this way as well when
-   it is possible.  Unfortunately, it is not always possible; working with
-   this kind of buffer normally requires hardware which can do
-   scatter/gather DMA operations.
-
- - Buffers which are physically scattered, but which are virtually
-   contiguous; buffers allocated with vmalloc(), in other words.  These
-   buffers are just as hard to use for DMA operations, but they can be
-   useful in situations where DMA is not available but virtually-contiguous
-   buffers are convenient.
-
- - Buffers which are physically contiguous.  Allocation of this kind of
-   buffer can be unreliable on fragmented systems, but simpler DMA
-   controllers cannot deal with anything else.
-
-Videobuf can work with all three types of buffers, but the driver author
-must pick one at the outset and design the driver around that decision.
-
-[It's worth noting that there's a fourth kind of buffer: "overlay" buffers
-which are located within the system's video memory.  The overlay
-functionality is considered to be deprecated for most use, but it still
-shows up occasionally in system-on-chip drivers where the performance
-benefits merit the use of this technique.  Overlay buffers can be handled
-as a form of scattered buffer, but there are very few implementations in
-the kernel and a description of this technique is currently beyond the
-scope of this document.]
-
-Data structures, callbacks, and initialization
-----------------------------------------------
-
-Depending on which type of buffers are being used, the driver should
-include one of the following files:
-
-.. code-block:: none
-
-    <media/videobuf-dma-sg.h>		/* Physically scattered */
-    <media/videobuf-vmalloc.h>		/* vmalloc() buffers	*/
-    <media/videobuf-dma-contig.h>	/* Physically contiguous */
-
-The driver's data structure describing a V4L2 device should include a
-struct videobuf_queue instance for the management of the buffer queue,
-along with a list_head for the queue of available buffers.  There will also
-need to be an interrupt-safe spinlock which is used to protect (at least)
-the queue.
-
-The next step is to write four simple callbacks to help videobuf deal with
-the management of buffers:
-
-.. code-block:: none
-
-    struct videobuf_queue_ops {
-	int (*buf_setup)(struct videobuf_queue *q,
-			 unsigned int *count, unsigned int *size);
-	int (*buf_prepare)(struct videobuf_queue *q,
-			   struct videobuf_buffer *vb,
-			   enum v4l2_field field);
-	void (*buf_queue)(struct videobuf_queue *q,
-			  struct videobuf_buffer *vb);
-	void (*buf_release)(struct videobuf_queue *q,
-			    struct videobuf_buffer *vb);
-    };
-
-buf_setup() is called early in the I/O process, when streaming is being
-initiated; its purpose is to tell videobuf about the I/O stream.  The count
-parameter will be a suggested number of buffers to use; the driver should
-check it for rationality and adjust it if need be.  As a practical rule, a
-minimum of two buffers are needed for proper streaming, and there is
-usually a maximum (which cannot exceed 32) which makes sense for each
-device.  The size parameter should be set to the expected (maximum) size
-for each frame of data.
-
-Each buffer (in the form of a struct videobuf_buffer pointer) will be
-passed to buf_prepare(), which should set the buffer's size, width, height,
-and field fields properly.  If the buffer's state field is
-VIDEOBUF_NEEDS_INIT, the driver should pass it to:
-
-.. code-block:: none
-
-    int videobuf_iolock(struct videobuf_queue* q, struct videobuf_buffer *vb,
-			struct v4l2_framebuffer *fbuf);
-
-Among other things, this call will usually allocate memory for the buffer.
-Finally, the buf_prepare() function should set the buffer's state to
-VIDEOBUF_PREPARED.
-
-When a buffer is queued for I/O, it is passed to buf_queue(), which should
-put it onto the driver's list of available buffers and set its state to
-VIDEOBUF_QUEUED.  Note that this function is called with the queue spinlock
-held; if it tries to acquire it as well things will come to a screeching
-halt.  Yes, this is the voice of experience.  Note also that videobuf may
-wait on the first buffer in the queue; placing other buffers in front of it
-could again gum up the works.  So use list_add_tail() to enqueue buffers.
-
-Finally, buf_release() is called when a buffer is no longer intended to be
-used.  The driver should ensure that there is no I/O active on the buffer,
-then pass it to the appropriate free routine(s):
-
-.. code-block:: none
-
-    /* Scatter/gather drivers */
-    int videobuf_dma_unmap(struct videobuf_queue *q,
-			   struct videobuf_dmabuf *dma);
-    int videobuf_dma_free(struct videobuf_dmabuf *dma);
-
-    /* vmalloc drivers */
-    void videobuf_vmalloc_free (struct videobuf_buffer *buf);
-
-    /* Contiguous drivers */
-    void videobuf_dma_contig_free(struct videobuf_queue *q,
-				  struct videobuf_buffer *buf);
-
-One way to ensure that a buffer is no longer under I/O is to pass it to:
-
-.. code-block:: none
-
-    int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr);
-
-Here, vb is the buffer, non_blocking indicates whether non-blocking I/O
-should be used (it should be zero in the buf_release() case), and intr
-controls whether an interruptible wait is used.
-
-File operations
----------------
-
-At this point, much of the work is done; much of the rest is slipping
-videobuf calls into the implementation of the other driver callbacks.  The
-first step is in the open() function, which must initialize the
-videobuf queue.  The function to use depends on the type of buffer used:
-
-.. code-block:: none
-
-    void videobuf_queue_sg_init(struct videobuf_queue *q,
-				struct videobuf_queue_ops *ops,
-				struct device *dev,
-				spinlock_t *irqlock,
-				enum v4l2_buf_type type,
-				enum v4l2_field field,
-				unsigned int msize,
-				void *priv);
-
-    void videobuf_queue_vmalloc_init(struct videobuf_queue *q,
-				struct videobuf_queue_ops *ops,
-				struct device *dev,
-				spinlock_t *irqlock,
-				enum v4l2_buf_type type,
-				enum v4l2_field field,
-				unsigned int msize,
-				void *priv);
-
-    void videobuf_queue_dma_contig_init(struct videobuf_queue *q,
-				       struct videobuf_queue_ops *ops,
-				       struct device *dev,
-				       spinlock_t *irqlock,
-				       enum v4l2_buf_type type,
-				       enum v4l2_field field,
-				       unsigned int msize,
-				       void *priv);
-
-In each case, the parameters are the same: q is the queue structure for the
-device, ops is the set of callbacks as described above, dev is the device
-structure for this video device, irqlock is an interrupt-safe spinlock to
-protect access to the data structures, type is the buffer type used by the
-device (cameras will use V4L2_BUF_TYPE_VIDEO_CAPTURE, for example), field
-describes which field is being captured (often V4L2_FIELD_NONE for
-progressive devices), msize is the size of any containing structure used
-around struct videobuf_buffer, and priv is a private data pointer which
-shows up in the priv_data field of struct videobuf_queue.  Note that these
-are void functions which, evidently, are immune to failure.
-
-V4L2 capture drivers can be written to support either of two APIs: the
-read() system call and the rather more complicated streaming mechanism.  As
-a general rule, it is necessary to support both to ensure that all
-applications have a chance of working with the device.  Videobuf makes it
-easy to do that with the same code.  To implement read(), the driver need
-only make a call to one of:
-
-.. code-block:: none
-
-    ssize_t videobuf_read_one(struct videobuf_queue *q,
-			      char __user *data, size_t count,
-			      loff_t *ppos, int nonblocking);
-
-    ssize_t videobuf_read_stream(struct videobuf_queue *q,
-				 char __user *data, size_t count,
-				 loff_t *ppos, int vbihack, int nonblocking);
-
-Either one of these functions will read frame data into data, returning the
-amount actually read; the difference is that videobuf_read_one() will only
-read a single frame, while videobuf_read_stream() will read multiple frames
-if they are needed to satisfy the count requested by the application.  A
-typical driver read() implementation will start the capture engine, call
-one of the above functions, then stop the engine before returning (though a
-smarter implementation might leave the engine running for a little while in
-anticipation of another read() call happening in the near future).
-
-The poll() function can usually be implemented with a direct call to:
-
-.. code-block:: none
-
-    unsigned int videobuf_poll_stream(struct file *file,
-				      struct videobuf_queue *q,
-				      poll_table *wait);
-
-Note that the actual wait queue eventually used will be the one associated
-with the first available buffer.
-
-When streaming I/O is done to kernel-space buffers, the driver must support
-the mmap() system call to enable user space to access the data.  In many
-V4L2 drivers, the often-complex mmap() implementation simplifies to a
-single call to:
-
-.. code-block:: none
-
-    int videobuf_mmap_mapper(struct videobuf_queue *q,
-			     struct vm_area_struct *vma);
-
-Everything else is handled by the videobuf code.
-
-The release() function requires two separate videobuf calls:
-
-.. code-block:: none
-
-    void videobuf_stop(struct videobuf_queue *q);
-    int videobuf_mmap_free(struct videobuf_queue *q);
-
-The call to videobuf_stop() terminates any I/O in progress - though it is
-still up to the driver to stop the capture engine.  The call to
-videobuf_mmap_free() will ensure that all buffers have been unmapped; if
-so, they will all be passed to the buf_release() callback.  If buffers
-remain mapped, videobuf_mmap_free() returns an error code instead.  The
-purpose is clearly to cause the closing of the file descriptor to fail if
-buffers are still mapped, but every driver in the 2.6.32 kernel cheerfully
-ignores its return value.
-
-ioctl() operations
-------------------
-
-The V4L2 API includes a very long list of driver callbacks to respond to
-the many ioctl() commands made available to user space.  A number of these
-- those associated with streaming I/O - turn almost directly into videobuf
-calls.  The relevant helper functions are:
-
-.. code-block:: none
-
-    int videobuf_reqbufs(struct videobuf_queue *q,
-			 struct v4l2_requestbuffers *req);
-    int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b);
-    int videobuf_qbuf(struct videobuf_queue *q, struct v4l2_buffer *b);
-    int videobuf_dqbuf(struct videobuf_queue *q, struct v4l2_buffer *b,
-		       int nonblocking);
-    int videobuf_streamon(struct videobuf_queue *q);
-    int videobuf_streamoff(struct videobuf_queue *q);
-
-So, for example, a VIDIOC_REQBUFS call turns into a call to the driver's
-vidioc_reqbufs() callback which, in turn, usually only needs to locate the
-proper struct videobuf_queue pointer and pass it to videobuf_reqbufs().
-These support functions can replace a great deal of buffer management
-boilerplate in a lot of V4L2 drivers.
-
-The vidioc_streamon() and vidioc_streamoff() functions will be a bit more
-complex, of course, since they will also need to deal with starting and
-stopping the capture engine.
-
-Buffer allocation
------------------
-
-Thus far, we have talked about buffers, but have not looked at how they are
-allocated.  The scatter/gather case is the most complex on this front.  For
-allocation, the driver can leave buffer allocation entirely up to the
-videobuf layer; in this case, buffers will be allocated as anonymous
-user-space pages and will be very scattered indeed.  If the application is
-using user-space buffers, no allocation is needed; the videobuf layer will
-take care of calling get_user_pages() and filling in the scatterlist array.
-
-If the driver needs to do its own memory allocation, it should be done in
-the vidioc_reqbufs() function, *after* calling videobuf_reqbufs().  The
-first step is a call to:
-
-.. code-block:: none
-
-    struct videobuf_dmabuf *videobuf_to_dma(struct videobuf_buffer *buf);
-
-The returned videobuf_dmabuf structure (defined in
-<media/videobuf-dma-sg.h>) includes a couple of relevant fields:
-
-.. code-block:: none
-
-    struct scatterlist  *sglist;
-    int                 sglen;
-
-The driver must allocate an appropriately-sized scatterlist array and
-populate it with pointers to the pieces of the allocated buffer; sglen
-should be set to the length of the array.
-
-Drivers using the vmalloc() method need not (and cannot) concern themselves
-with buffer allocation at all; videobuf will handle those details.  The
-same is normally true of contiguous-DMA drivers as well; videobuf will
-allocate the buffers (with dma_alloc_coherent()) when it sees fit.  That
-means that these drivers may be trying to do high-order allocations at any
-time, an operation which is not always guaranteed to work.  Some drivers
-play tricks by allocating DMA space at system boot time; videobuf does not
-currently play well with those drivers.
-
-As of 2.6.31, contiguous-DMA drivers can work with a user-supplied buffer,
-as long as that buffer is physically contiguous.  Normal user-space
-allocations will not meet that criterion, but buffers obtained from other
-kernel drivers, or those contained within huge pages, will work with these
-drivers.
-
-Filling the buffers
--------------------
-
-The final part of a videobuf implementation has no direct callback - it's
-the portion of the code which actually puts frame data into the buffers,
-usually in response to interrupts from the device.  For all types of
-drivers, this process works approximately as follows:
-
- - Obtain the next available buffer and make sure that somebody is actually
-   waiting for it.
-
- - Get a pointer to the memory and put video data there.
-
- - Mark the buffer as done and wake up the process waiting for it.
-
-Step (1) above is done by looking at the driver-managed list_head structure
-- the one which is filled in the buf_queue() callback.  Because starting
-the engine and enqueueing buffers are done in separate steps, it's possible
-for the engine to be running without any buffers available - in the
-vmalloc() case especially.  So the driver should be prepared for the list
-to be empty.  It is equally possible that nobody is yet interested in the
-buffer; the driver should not remove it from the list or fill it until a
-process is waiting on it.  That test can be done by examining the buffer's
-done field (a wait_queue_head_t structure) with waitqueue_active().
-
-A buffer's state should be set to VIDEOBUF_ACTIVE before being mapped for
-DMA; that ensures that the videobuf layer will not try to do anything with
-it while the device is transferring data.
-
-For scatter/gather drivers, the needed memory pointers will be found in the
-scatterlist structure described above.  Drivers using the vmalloc() method
-can get a memory pointer with:
-
-.. code-block:: none
-
-    void *videobuf_to_vmalloc(struct videobuf_buffer *buf);
-
-For contiguous DMA drivers, the function to use is:
-
-.. code-block:: none
-
-    dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf);
-
-The contiguous DMA API goes out of its way to hide the kernel-space address
-of the DMA buffer from drivers.
-
-The final step is to set the size field of the relevant videobuf_buffer
-structure to the actual size of the captured image, set state to
-VIDEOBUF_DONE, then call wake_up() on the done queue.  At this point, the
-buffer is owned by the videobuf layer and the driver should not touch it
-again.
-
-Developers who are interested in more information can go into the relevant
-header files; there are a few low-level functions declared there which have
-not been talked about here.  Also worthwhile is the vivi driver
-(drivers/media/platform/vivi.c), which is maintained as an example of how V4L2
-drivers should be written.  Vivi only uses the vmalloc() API, but it's good
-enough to get started with.  Note also that all of these calls are exported
-GPL-only, so they will not be available to non-GPL kernel modules.
diff --git a/Documentation/media/kapi/v4l2-videobuf2.rst b/Documentation/media/kapi/v4l2-videobuf2.rst
deleted file mode 100644
index 1044f64ff168..000000000000
--- a/Documentation/media/kapi/v4l2-videobuf2.rst
+++ /dev/null
@@ -1,12 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-.. _vb2_framework:
-
-V4L2 videobuf2 functions and data structures
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-.. kernel-doc:: include/media/videobuf2-core.h
-
-.. kernel-doc:: include/media/videobuf2-v4l2.h
-
-.. kernel-doc:: include/media/videobuf2-memops.h
diff --git a/Documentation/media/lirc.h.rst.exceptions b/Documentation/media/lirc.h.rst.exceptions
deleted file mode 100644
index ac768d769113..000000000000
--- a/Documentation/media/lirc.h.rst.exceptions
+++ /dev/null
@@ -1,80 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-# Ignore header name
-ignore define _LINUX_LIRC_H
-
-# Ignore helper macros
-
-ignore define lirc_t
-
-ignore define LIRC_SPACE
-ignore define LIRC_PULSE
-ignore define LIRC_FREQUENCY
-ignore define LIRC_TIMEOUT
-ignore define LIRC_VALUE
-ignore define LIRC_MODE2
-ignore define LIRC_IS_SPACE
-ignore define LIRC_IS_PULSE
-ignore define LIRC_IS_FREQUENCY
-ignore define LIRC_IS_TIMEOUT
-
-ignore define LIRC_MODE2SEND
-ignore define LIRC_SEND2MODE
-ignore define LIRC_MODE2REC
-ignore define LIRC_REC2MODE
-
-ignore define LIRC_CAN_SEND
-ignore define LIRC_CAN_REC
-
-ignore define LIRC_CAN_SEND_MASK
-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
-ignore symbol RC_PROTO_IMON
-ignore symbol RC_PROTO_RCMM12
-ignore symbol RC_PROTO_RCMM24
-ignore symbol RC_PROTO_RCMM32
-ignore symbol RC_PROTO_XBOX_DVD
-
-# Undocumented macros
-
-ignore define PULSE_BIT
-ignore define PULSE_MASK
-
-ignore define LIRC_MODE2_SPACE
-ignore define LIRC_MODE2_PULSE
-
-ignore define LIRC_VALUE_MASK
-ignore define LIRC_MODE2_MASK
-
-ignore define LIRC_MODE_RAW
-ignore define LIRC_MODE_LIRCCODE
diff --git a/Documentation/media/media.h.rst.exceptions b/Documentation/media/media.h.rst.exceptions
deleted file mode 100644
index 9b4c26502d95..000000000000
--- a/Documentation/media/media.h.rst.exceptions
+++ /dev/null
@@ -1,32 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-# Ignore header name
-ignore define __LINUX_MEDIA_H
-
-# Ignore macros
-ignore define MEDIA_API_VERSION
-ignore define MEDIA_ENT_F_BASE
-ignore define MEDIA_ENT_F_OLD_BASE
-ignore define MEDIA_ENT_F_OLD_SUBDEV_BASE
-ignore define MEDIA_ENT_F_DTV_DECODER
-ignore define MEDIA_INTF_T_DVB_BASE
-ignore define MEDIA_INTF_T_V4L_BASE
-ignore define MEDIA_INTF_T_ALSA_BASE
-#ignore legacy entity type macros
-ignore define MEDIA_ENT_TYPE_SHIFT
-ignore define MEDIA_ENT_TYPE_MASK
-ignore define MEDIA_ENT_SUBTYPE_MASK
-ignore define MEDIA_ENT_T_DEVNODE_UNKNOWN
-ignore define MEDIA_ENT_T_DEVNODE
-ignore define MEDIA_ENT_T_DEVNODE_V4L
-ignore define MEDIA_ENT_T_DEVNODE_FB
-ignore define MEDIA_ENT_T_DEVNODE_ALSA
-ignore define MEDIA_ENT_T_DEVNODE_DVB
-ignore define MEDIA_ENT_T_UNKNOWN
-ignore define MEDIA_ENT_T_V4L2_VIDEO
-ignore define MEDIA_ENT_T_V4L2_SUBDEV
-ignore define MEDIA_ENT_T_V4L2_SUBDEV_SENSOR
-ignore define MEDIA_ENT_T_V4L2_SUBDEV_FLASH
-ignore define MEDIA_ENT_T_V4L2_SUBDEV_LENS
-ignore define MEDIA_ENT_T_V4L2_SUBDEV_DECODER
-ignore define MEDIA_ENT_T_V4L2_SUBDEV_TUNER
diff --git a/Documentation/media/media_kapi.rst b/Documentation/media/media_kapi.rst
deleted file mode 100644
index 1389998c90f7..000000000000
--- a/Documentation/media/media_kapi.rst
+++ /dev/null
@@ -1,38 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-.. include:: <isonum.txt>
-
-===================================
-Media subsystem kernel internal API
-===================================
-
-**Copyright** |copy| 2009-2016 : LinuxTV Developers
-
-This documentation is free software; you can redistribute it and/or modify it
-under the terms of the 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.
-
-For more details see the file COPYING in the source distribution of Linux.
-
-.. only:: html
-
-   .. class:: toc-title
-
-        Table of Contents
-
-.. toctree::
-    :maxdepth: 5
-    :numbered:
-
-    kapi/v4l2-core
-    kapi/dtv-core
-    kapi/rc-core
-    kapi/mc-core
-    kapi/cec-core
-    kapi/csi2
diff --git a/Documentation/media/media_uapi.rst b/Documentation/media/media_uapi.rst
deleted file mode 100644
index 0753005c7bb4..000000000000
--- a/Documentation/media/media_uapi.rst
+++ /dev/null
@@ -1,33 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-.. include:: <isonum.txt>
-
-########################################
-Linux Media Infrastructure userspace API
-########################################
-
-**Copyright** |copy| 2009-2016 : LinuxTV Developers
-
-Permission is granted to copy, distribute and/or modify this document
-under the terms of the GNU Free Documentation License, Version 1.1 or
-any later version published by the Free Software Foundation, with no
-Invariant Sections. A copy of the license is included in the chapter
-entitled "GNU Free Documentation License".
-
-.. only:: html
-
-   .. class:: toc-title
-
-        Table of Contents
-
-.. toctree::
-    :maxdepth: 1
-
-    intro
-    uapi/v4l/v4l2
-    uapi/dvb/dvbapi
-    uapi/rc/remote_controllers
-    uapi/mediactl/media-controller
-    uapi/cec/cec-api
-    uapi/gen-errors
-    uapi/fdl-appendix
diff --git a/Documentation/media/net.h.rst.exceptions b/Documentation/media/net.h.rst.exceptions
deleted file mode 100644
index 5159aa4bbbb9..000000000000
--- a/Documentation/media/net.h.rst.exceptions
+++ /dev/null
@@ -1,13 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-# Ignore header name
-ignore define _DVBNET_H_
-
-# Ignore old ioctls/structs
-ignore ioctl __NET_ADD_IF_OLD
-ignore ioctl __NET_GET_IF_OLD
-ignore struct __dvb_net_if_old
-
-# Macros used at struct dvb_net_if
-replace define DVB_NET_FEEDTYPE_MPE :c:type:`dvb_net_if`
-replace define DVB_NET_FEEDTYPE_ULE :c:type:`dvb_net_if`
diff --git a/Documentation/media/typical_media_device.svg b/Documentation/media/typical_media_device.svg
deleted file mode 100644
index bfd5c7db3b00..000000000000
--- a/Documentation/media/typical_media_device.svg
+++ /dev/null
@@ -1,116 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-    Permission is granted to copy, distribute and/or modify this
-    document under the terms of the GNU Free Documentation License,
-    Version 1.1 or any later version published by the Free Software
-    Foundation, with no Invariant Sections, no Front-Cover Texts
-    and no Back-Cover Texts. A copy of the license is included at
-    Documentation/media/uapi/fdl-appendix.rst.
-
-    TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
--->
-<svg id="svg2" width="235mm" height="179mm" clip-path="url(#a)" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" preserveAspectRatio="xMidYMid" version="1.2" viewBox="0 0 22648.239 17899.829" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><metadata id="metadata1533"><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title/></cc:Work></rdf:RDF></metadata><defs id="defs4"><clipPath id="a"><rect id="rect7" width="28000" height="21000"/></clipPath></defs><path id="path11" d="m10146 2636c-518.06 0-1035.1 515-1035.1 1031v4124c0 516 517.06 1032 1035.1 1032h8572.2c518.06 0 1036.1-516 1036.1-1032v-4124c0-516-518.06-1031-1036.1-1031h-8572.2z"
-fill="#fcf" style=""/><path id="path15" d="m1505.5 13443c-293 0-585 292-585 585v2340c0 293 292 586 585 586h3275c293 0 586-293 586-586v-2340c0-293-293-585-586-585h-3275z" fill="#ffc" style=""/><path id="path19" d="m517.15 22.013c-461 0-922 461-922 922v11169c0 461 461 923 922 923h3692c461 0 922-462 922-923v-11169c0-461-461-922-922-922h-3692z" fill="#e6e6e6" style=""/><path id="path23" d="m2371.5 6438h-2260v-1086h4520v1086h-2260z" fill="#ff8080" style=""/><path id="path25" d="m2371.5 6438h-2260v-1086h4520v1086h-2260z" fill="none" stroke="#3465af" style=""/><text id="text27" class="TextShape" x="-2089.4541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan29" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan31" class="TextPosition" x="489.5459" y="6111.0132" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan33"
-fill="#000000" font-family="Serif, serif" font-size="493.88px">Audio decoder</tspan></tspan></tspan></text>
-<path id="path37" d="m2371.5 9608h-2260v-1270h4520v1270h-2260z" fill="#ff8080" style=""/><path id="path39" d="m2371.5 9608h-2260v-1270h4520v1270h-2260z" fill="none" stroke="#3465af" style=""/><text id="text41" class="TextShape" x="-2089.4541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan43" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan45" class="TextPosition" x="527.5459" y="9189.0127" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan47" fill="#000000" font-family="Serif, serif" font-size="493.88px">Video decoder</tspan></tspan></tspan></text>
-<path id="path51" d="m2363.5 8053h-2269v-1224h4537v1224h-2268z" fill="#ff8080" style=""/><path id="path53" d="m2363.5 8053h-2269v-1224h4537v1224h-2268z" fill="none" stroke="#3465af" style=""/><text id="text55" class="TextShape" x="-2089.4541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan57" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan59" class="TextPosition" x="481.5459" y="7657.0132" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan61" fill="#000000" font-family="Serif, serif" font-size="493.88px">Audio encoder</tspan></tspan></tspan></text>
-<path id="path65" d="m13622 10386h-3810v-1281h7620v1281h-3810z" fill="#cfc" style=""/><path id="path67" d="m13622 10386h-3810v-1281h7620v1281h-3810z" fill="none" stroke="#3465af" style=""/><text id="text69" class="TextShape" x="-2089.4541" y="-2446.187" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan71" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan73" class="TextPosition" x="10287.546" y="9960.8135" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan75" fill="#000000" font-family="Serif, serif" font-size="493.88px">Button Key/IR input logic</tspan></tspan></tspan></text>
-<path id="path79" d="m12080 12182h-2268v-1412h4536v1412h-2268z" fill="#cfe7f5" style=""/><path id="path81" d="m12080 12182h-2268v-1412h4536v1412h-2268z" fill="none" stroke="#3465af" style=""/><text id="text83" class="TextShape" x="-2089.4541" y="-2389.7871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan85" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan87" class="TextPosition" x="10792.546" y="11692.213" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan89" fill="#000000" font-family="Serif, serif" font-size="493.88px">EEPROM</tspan></tspan></tspan></text>
-<path id="path93" d="m3050.5 15498h-1563v-1715h3126v1715h-1563z" fill="#fc9" style=""/><path id="path95" d="m3050.5 15498h-1563v-1715h3126v1715h-1563z" fill="none" stroke="#3465af" style=""/><text id="text97" class="TextShape" x="-2089.4541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan99" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan101" class="TextPosition" x="2186.5459" y="14856.013" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan103" fill="#000000" font-family="Serif, serif" font-size="493.88px">Sensor</tspan></tspan></tspan></text>
-<path id="path107" d="m4629.5 5866 385-353v176h1167v-176l386 353-386 354v-177h-1167v177l-385-354z" fill="#729fcf" style=""/><path id="path109" d="m4629.5 5866 385-353v176h1167v-176l386 353-386 354v-177h-1167v177l-385-354z" fill="none" stroke="#3465af" style=""/><path id="path113" d="m4629.5 7448 385-353v176h1167v-176l386 353-386 354v-177h-1167v177l-385-354z" fill="#729fcf" style=""/><path id="path115" d="m4629.5 7448 385-353v176h1167v-176l386 353-386 354v-177h-1167v177l-385-354z" fill="none" stroke="#3465af" style=""/><path id="path119" d="m4631.5 8936 385-353v176h1166v-176l386 353-386 354v-177h-1166v177l-385-354z" fill="#729fcf" style=""/><path id="path121" d="m4631.5 8936 385-353v176h1166v-176l386 353-386 354v-177h-1166v177l-385-354z" fill="none" stroke="#3465af" style=""/><path id="path125" d="m7872.5 11464 385-353v176h1166v-176l386 353-386 354v-177h-1166v177l-385-354z"
-fill="#729fcf" style=""/><path id="path127" d="m7872.5 11464 385-353v176h1166v-176l386 353-386 354v-177h-1166v177l-385-354z" fill="none" stroke="#3465af" style=""/><path id="path131" d="m7872.5 9716.8 385-353v176h1166v-176l386 353-386 354v-177h-1166v177l-385-354z" fill="#729fcf" style=""/><path id="path133" d="m7872.5 9716.8 385-353v176h1166v-176l386 353-386 354v-177h-1166v177l-385-354z" fill="none" stroke="#3465af" style=""/><path id="path137" d="m7872.5 14994 670-353v176h2028v-176l671 353-671 354v-177h-2028v177l-670-354z" fill="#729fcf" style=""/><path id="path139" d="m7872.5 14994 670-353v176h2028v-176l671 353-671 354v-177h-2028v177l-670-354z" fill="none" stroke="#3465af" style=""/><path id="path143" d="m17534 14105 978.49 840.89-978.49 840.89v-420.86h-2960.5v420.86l-979.49-840.89 979.49-840.89v420.03h2960.5v-420.03z" fill="#729fcf" style=""/><path id="path145" d="m17534 14105 978.49
-840.89-978.49 840.89v-420.86h-2960.5v420.86l-979.49-840.89 979.49-840.89v420.03h2960.5v-420.03z" fill="none" stroke="#3465af" stroke-width="25.77" style=""/><text id="text149" class="TextShape" x="-9922.1533" y="-644.58704" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan151" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan153" class="TextPosition" transform="matrix(0,-1,1,0,8509,40173)" x="14418.847" y="15187.413" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan155" fill="#000000" font-family="Serif, serif" font-size="493.88px">System Bus</tspan></tspan></tspan></text>
-<path id="path159" d="m11062 7098h-1250v-875h2499v875h-1249z" fill="#cff" style=""/><path id="path161" d="m11062 7098h-1250v-875h2499v875h-1249z" fill="none" stroke="#3465af" style=""/><text id="text163" class="TextShape" x="-2089.4541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan165" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan167" class="TextPosition" x="10125.546" y="6876.0132" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan169" fill="#000000" font-family="Serif, serif" font-size="493.88px">Demux</tspan></tspan></tspan></text>
-<path id="path173" d="m7906.5 6601 373-357v178h1130v-178l374 357-374 358v-179h-1130v179l-373-358z" fill="#729fcf" style=""/><path id="path175" d="m7906.5 6601 373-357v178h1130v-178l374 357-374 358v-179h-1130v179l-373-358z" fill="none" stroke="#3465af" style=""/><path id="path179" d="m7906.5 5214 373-358v179h1130v-179l374 358-374 358v-179h-1130v179l-373-358z" fill="#729fcf" style=""/><path id="path181" d="m7906.5 5214 373-358v179h1130v-179l374 358-374 358v-179h-1130v179l-373-358z" fill="none" stroke="#3465af" style=""/><path id="path185" d="m14233 5828h-4421v-1270h8841v1270h-4420z" fill="#cff" style=""/><path id="path187" d="m14233 5828h-4421v-1270h8841v1270h-4420z" fill="none" stroke="#3465af" style=""/><text id="text189" class="TextShape" x="-2089.4541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan191" class="TextParagraph" font-family="Serif, serif"
-font-size="493.88px"><tspan id="tspan193" class="TextPosition" x="10696.546" y="5409.0132" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan195" fill="#000000" font-family="Serif, serif" font-size="493.88px">Conditional Access Module</tspan></tspan></tspan></text>
-<path id="path199" d="m2355.5 11123h-2269v-1224h4537v1224h-2268z" fill="#ff8080" style=""/><path id="path201" d="m2355.5 11123h-2269v-1224h4537v1224h-2268z" fill="none" stroke="#3465af" style=""/><text id="text203" class="TextShape" x="-2089.4541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan205" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan207" class="TextPosition" x="511.5459" y="10727.013" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan209" fill="#000000" font-family="Serif, serif" font-size="493.88px">Video encoder</tspan></tspan></tspan></text>
-<path id="path213" d="m4631.5 10470 385-353v176h1166v-176l386 353-386 354v-177h-1166v177l-385-354z" fill="#729fcf" style=""/><path id="path215" d="m4631.5 10470 385-353v176h1166v-176l386 353-386 354v-177h-1166v177l-385-354z" fill="none" stroke="#3465af" style=""/><path id="path219" d="m18702 5381 385-353v176h1166v-176l386 353-386 354v-177h-1166v177l-385-354z" fill="#729fcf" style=""/><path id="path221" d="m18702 5381 385-353v176h1166v-176l386 353-386 354v-177h-1166v177l-385-354z" fill="none" stroke="#3465af" style=""/><text id="text225" class="TextShape" x="-1976.5541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan227" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan229" class="TextPosition" x="13.4459" y="12314.013" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan231" fill="#000000"
-font-family="Serif, serif" font-size="493.88px">Radio / Analog TV</tspan></tspan></tspan></text>
-<text id="text235" class="TextShape" x="-2089.4541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan237" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan239" class="TextPosition" x="12866.546" y="8560.0127" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan241" fill="#000000" font-family="Serif, serif" font-size="493.88px">Digital TV</tspan></tspan></tspan></text>
-<text id="text245" class="TextShape" x="-8919.0537" y="-1373.787" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan247" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan249" class="TextPosition" x="5804.9458" y="17793.213" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan251" fill="#000000" font-family="Serif, serif" font-size="493.88px">PS.: picture is not complete: other blocks may be present</tspan></tspan></tspan></text>
-<text id="text255" class="TextShape" x="-2089.4541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan257" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan259" class="TextPosition" x="2109.5459" y="16397.014" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan261" fill="#000000" font-family="Serif, serif" font-size="493.88px">Webcam</tspan></tspan></tspan></text>
-<path id="path265" d="m12463 13926h-2650v-1412h5299v1412h-2649z" fill="#f90" style=""/><path id="path267" d="m12463 13926h-2650v-1412h5299v1412h-2649z" fill="none" stroke="#3465af" style=""/><text id="text269" class="TextShape" x="-2089.4541" y="-2446.187" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan271" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan273" class="TextPosition" x="10175.546" y="13435.813" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan275" fill="#000000" font-family="Serif, serif" font-size="493.88px">Processing blocks</tspan></tspan></tspan></text>
-<path id="path279" d="m7872.5 13208 385-353v176h1166v-176l386 353-386 354v-177h-1166v177l-385-354z" fill="#729fcf" style=""/><path id="path281" d="m7872.5 13208 385-353v176h1166v-176l386 353-386 354v-177h-1166v177l-385-354z" fill="none" stroke="#3465af" style=""/><path id="path285" d="m4612.5 14790 397-353v176h1201v-176l398 353-398 354v-177h-1201v177l-397-354z" fill="#729fcf" style=""/><path id="path287" d="m4612.5 14790 397-353v176h1201v-176l398 353-398 354v-177h-1201v177l-397-354z" fill="none" stroke="#3465af" style=""/><text id="text291" class="TextShape" x="-2428.0542" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan293" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan295" class="TextPosition" x="20421.945" y="6628.0132" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan297" fill="#000000"
-font-family="Serif, serif" font-size="493.88px">Smartcard</tspan></tspan></tspan></text>
-<path id="path301" d="m623.32 436.01c-334.6 0-669.2 333-669.2 666v2668c0 333 334.6 666 669.2 666h18456c334.6 0 670.2-333 670.2-666v-2668c0-333-335.6-666-670.2-666h-18456z" fill="#fcf" style=""/><path id="path305" d="m3031.5 2991h-1614v-1816h3227v1816h-1613z" fill="#ff8080" style=""/><path id="path307" d="m3031.5 2991h-1614v-1816h3227v1816h-1613z" fill="none" stroke="#3465af" style=""/><text id="text309" class="TextShape" x="-2089.4541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan311" class="TextParagraph"><tspan id="tspan313" class="TextPosition" x="2284.5459" y="1947.0129" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan315" fill="#000000" font-family="Serif, serif" font-size="493.88px">Tuner</tspan></tspan></tspan><tspan id="tspan317" class="TextParagraph"><tspan id="tspan319" class="TextPosition" x="2061.5459" y="2650.0129"
-font-family="Serif, serif" font-size="493.88px"><tspan id="tspan321" fill="#000000" font-family="Serif, serif" font-size="493.88px">FM/TV</tspan></tspan></tspan></text>
-<path id="path325" d="m812.55 1538c0 111 40 202 88 202h530c48 0 89-91 89-202 0-110-41-202-89-202h-530c-48 0-88 92-88 202z" fill="#ff8080" style=""/><path id="path327" d="m812.55 1538c0 111 40 202 88 202h530c48 0 89-91 89-202 0-110-41-202-89-202h-530c-48 0-88 92-88 202z" fill="none" stroke="#3465af" style=""/><path id="path329" d="m812.55 1538c0 111 40 202 88 202s88-91 88-202c0-110-40-202-88-202s-88 92-88 202z" fill="#ffb3b3" style=""/><path id="path331" d="m812.55 1538c0 111 40 202 88 202s88-91 88-202c0-110-40-202-88-202s-88 92-88 202z" fill="none" stroke="#3465af" style=""/><path id="path335" d="m813.55 2103c0 110 40 202 88 202h530c48 0 89-92 89-202s-41-203-89-203h-530c-48 0-88 93-88 203z" fill="#ff8080" style=""/><path id="path337" d="m813.55 2103c0 110 40 202 88 202h530c48 0 89-92 89-202s-41-203-89-203h-530c-48 0-88 93-88 203z" fill="none" stroke="#3465af" style=""/><path
-id="path339" d="m813.55 2103c0 110 40 202 88 202s88-92 88-202-40-203-88-203-88 93-88 203z" fill="#ffb3b3" style=""/><path id="path341" d="m813.55 2103c0 110 40 202 88 202s88-92 88-202-40-203-88-203-88 93-88 203z" fill="none" stroke="#3465af" style=""/><path id="path345" d="m4629.5 2032 385-353v176h1167v-176l386 353-386 354v-177h-1167v177l-385-354z" fill="#729fcf" style=""/><path id="path347" d="m4629.5 2032 385-353v176h1167v-176l386 353-386 354v-177h-1167v177l-385-354z" fill="none" stroke="#3465af" style=""/><path id="path351" d="m7889.5 1986 402-368v184h1217v-184l403 368-403 369v-185h-1217v185l-402-369z" fill="#729fcf" style=""/><path id="path353" d="m7889.5 1986 402-368v184h1217v-184l403 368-403 369v-185h-1217v185l-402-369z" fill="none" stroke="#3465af" style=""/><path id="path357" d="m14411 4025h-4500v-1389h9e3v1389h-4500z" fill="#cff" style=""/><path id="path359" d="m14411
-4025h-4500v-1389h9e3v1389h-4500z" fill="none" stroke="#3465af" style=""/><text id="text361" class="TextShape" x="-2089.4541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan363" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan365" class="TextPosition" x="9961.5459" y="3546.0129" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan367" fill="#000000" font-family="Serif, serif" font-size="493.88px">Satellite Equipment Control (SEC)</tspan></tspan></tspan></text>
-<path id="path371" d="m11311 2436h-1400v-1e3h2800v1e3h-1400z" fill="#cff" style=""/><path id="path373" d="m11311 2436h-1400v-1e3h2800v1e3h-1400z" fill="none" stroke="#3465af" style=""/><text id="text375" class="TextShape" x="-2089.4541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan377" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan379" class="TextPosition" x="10375.546" y="2152.0129" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan381" fill="#000000" font-family="Serif, serif" font-size="493.88px">Demod</tspan></tspan></tspan></text>
-<path id="path385" d="m7889.5 3287 402-368v184h1217v-184l403 368-403 369v-185h-1217v185l-402-369z" fill="#729fcf" style=""/><path id="path387" d="m7889.5 3287 402-368v184h1217v-184l403 368-403 369v-185h-1217v185l-402-369z" fill="none" stroke="#3465af" style=""/><path id="path389" d="m7906.5 9121v7302h-1270v-14605h1270v7303z" fill="#ff9" style=""/><path id="path391" d="m7906.5 9121v7302h-1270v-14605h1270v7303z" fill="none" stroke="#3465af" style=""/><text id="text393" class="TextShape" transform="rotate(-90)" x="-20792.584" y="-6589.021" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan395" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan397" class="TextPosition" transform="matrix(0,-1,1,0,-4473,23627)" x="-11215.646" y="7460.9849" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan399" fill="#000000" font-family="Serif,
-serif" font-size="493.88px">I2C Bus (control bus)</tspan></tspan></tspan></text>
-<text id="text403" class="TextShape" x="-2145.854" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan405" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan407" class="TextPosition" x="7245.146" y="1114.0129" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan409" fill="#000000" font-family="Serif, serif" font-size="493.88px">Digital TV Frontend</tspan></tspan></tspan></text>
-<path id="path415" d="m863.15 636.14c-18.27 0-35.525 0.99994-53.795 2.9998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path417" d="m776.87 644.14c-17.255 2.9998-35.525 6.9996-52.78 11.999" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path419" d="m692.63 666.14c-16.24 5.9996-33.495 11.999-49.735 19.999" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path421" d="m613.46 700.14c-15.225 7.9995-31.465 16.999-46.69 26.998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path423" d="m539.36 745.14c-14.21 9.9994-28.42 20.999-42.63 31.998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path425" d="m471.36 798.14c-13.195 11.999-26.39 23.999-38.57 36.998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path427" d="m410.46 859.13c-11.165 12.999-22.33
-26.998-33.495 40.998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path429" d="m357.68 927.13c-10.15 13.999-19.285 28.998-28.42 44.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path431" d="m314.03 1000.1c-8.12 15.999-15.225 31.998-22.33 48.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path433" d="m280.54 1079.1c-5.075 16.999-10.15 33.998-14.21 50.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path435" d="m260.24 1162.1c-3.045 17.999-5.075 34.998-6.09 52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path437" d="m254.15 1247.1v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path439" d="m254.15 1333.1v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path441" d="m254.15 1418.1v52.997"
-fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path443" d="m254.15 1504.1v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path445" d="m254.15 1589.1v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path447" d="m254.15 1675.1v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path449" d="m254.15 1760.1v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path451" d="m254.15 1845.1v53.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path453" d="m254.15 1931.1v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path455" d="m254.15 2016.1v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path457" d="m254.15 2102.1v52.997" fill="none" stroke="#3465af" stroke-width="28.432"
-style=""/><path id="path459" d="m254.15 2187.1v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path461" d="m254.15 2273v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path463" d="m254.15 2358v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path465" d="m254.15 2443v53.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path467" d="m254.15 2529v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path469" d="m254.15 2614v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path471" d="m254.15 2700v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path473" d="m254.15 2785v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path475" d="m254.15 2871v52.997" fill="none"
-stroke="#3465af" stroke-width="28.432" style=""/><path id="path477" d="m254.15 2956v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path479" d="m254.15 3041v53.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path481" d="m254.15 3127v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path483" d="m254.15 3212v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path485" d="m254.15 3298v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path487" d="m254.15 3383v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path489" d="m254.15 3469v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path491" d="m254.15 3554v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path493"
-d="m254.15 3639c0 17.999 1.015 35.998 3.045 52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path495" d="m262.27 3724c4.06 17.999 8.12 34.998 13.195 51.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path497" d="m285.61 3807c6.09 15.999 13.195 32.998 20.3 48.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path499" d="m321.14 3885c8.12 14.999 17.255 30.998 27.405 45.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path501" d="m366.81 3957.9c10.15 13.999 21.315 27.998 32.48 41.998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path503" d="m420.61 4023.9c12.18 12.999 25.375 25.998 38.57 37.998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path505" d="m483.54 4083.9c13.195 10.999 27.405 22.999 41.615 32.998" fill="none"
-stroke="#3465af" stroke-width="28.432" style=""/><path id="path507" d="m552.56 4135.9c14.21 9.9994 29.435 18.999 45.675 26.998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path509" d="m627.67 4178.9c15.225 6.9996 32.48 14.999 48.72 20.999" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path511" d="m707.85 4210.9c17.255 4.9997 34.51 9.9994 51.765 13.999" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path513" d="m792.1 4230.9c17.255 1.9999 35.525 3.9998 53.795 4.9997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path515" d="m878.37 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path517" d="m964.65 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path519" d="m1051.9 4235.9h53.795" fill="none" stroke="#3465af"
-stroke-width="28.432" style=""/><path id="path521" d="m1138.2 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path523" d="m1225.5 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path525" d="m1311.8 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path527" d="m1398.1 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path529" d="m1485.3 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path531" d="m1571.6 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path533" d="m1658.9 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path535" d="m1745.2 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path537"
-d="m1832.5 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path539" d="m1918.7 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path541" d="m2005 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path543" d="m2092.3 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path545" d="m2178.6 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path547" d="m2265.9 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path549" d="m2352.2 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path551" d="m2439.4 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path553" d="m2525.7 4235.9h53.795" fill="none" stroke="#3465af"
-stroke-width="28.432" style=""/><path id="path555" d="m2612 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path557" d="m2699.3 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path559" d="m2785.6 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path561" d="m2872.8 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path563" d="m2959.1 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path565" d="m3046.4 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path567" d="m3132.7 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path569" d="m3220 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path571"
-d="m3306.3 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path573" d="m3392.5 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path575" d="m3479.8 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path577" d="m3566.1 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path579" d="m3653.4 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path581" d="m3739.7 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path583" d="m3826.9 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path585" d="m3913.2 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path587" d="m3999.5 4235.9h53.795" fill="none"
-stroke="#3465af" stroke-width="28.432" style=""/><path id="path589" d="m4086.8 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path591" d="m4173.1 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path593" d="m4260.4 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path595" d="m4346.6 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path597" d="m4433.9 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path599" d="m4520.2 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path601" d="m4606.5 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path603" d="m4693.8 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432"
-style=""/><path id="path605" d="m4780 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path607" d="m4867.3 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path609" d="m4953.6 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path611" d="m5040.9 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path613" d="m5127.2 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path615" d="m5213.4 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path617" d="m5300.7 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path619" d="m5387 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path621" d="m5474.3 4235.9h53.795"
-fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path623" d="m5560.6 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path625" d="m5647.9 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path627" d="m5734.1 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path629" d="m5820.4 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path631" d="m5907.7 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path633" d="m5994 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path635" d="m6081.3 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path637" d="m6167.5 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432"
-style=""/><path id="path639" d="m6254.8 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path641" d="m6341.1 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path643" d="m6427.4 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path645" d="m6514.7 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path647" d="m6600.9 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path649" d="m6688.2 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path651" d="m6774.5 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path653" d="m6861.8 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path655" d="m6948.1
-4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path657" d="m7035.4 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path659" d="m7121.6 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path661" d="m7207.9 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path663" d="m7295.2 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path665" d="m7381.5 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path667" d="m7468.8 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path669" d="m7555 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path671" d="m7642.3 4235.9h53.795" fill="none" stroke="#3465af"
-stroke-width="28.432" style=""/><path id="path673" d="m7728.6 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path675" d="m7814.9 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path677" d="m7902.2 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path679" d="m7988.4 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path681" d="m8075.7 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path683" d="m8162 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path685" d="m8249.3 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path687" d="m8335.6 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path689"
-d="m8421.9 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path691" d="m8509.1 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path693" d="m8595.4 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path695" d="m8682.7 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path697" d="m8769 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path699" d="m8856.3 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path701" d="m8942.5 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path703" d="m9028.8 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path705" d="m9116.1 4235.9h53.795" fill="none" stroke="#3465af"
-stroke-width="28.432" style=""/><path id="path707" d="m9202.4 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path709" d="m9289.7 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path711" d="m9376 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path713" d="m9463.2 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path715" d="m9549.5 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path717" d="m9635.8 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path719" d="m9723.1 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path721" d="m9809.4 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path723"
-d="m9896.6 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path725" d="m9982.9 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path727" d="m10070 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path729" d="m10156 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path731" d="m10243 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path733" d="m10330 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path735" d="m10416 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path737" d="m10504 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path739" d="m10590 4235.9h53.795" fill="none" stroke="#3465af"
-stroke-width="28.432" style=""/><path id="path741" d="m10677 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path743" d="m10763 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path745" d="m10850 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path747" d="m10937 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path749" d="m11023 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path751" d="m11111 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path753" d="m11197 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path755" d="m11284 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path757" d="m11370
-4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path759" d="m11458 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path761" d="m11544 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path763" d="m11630 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path765" d="m11718 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path767" d="m11804 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path769" d="m11891 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path771" d="m11977 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path773" d="m12065 4235.9h53.795" fill="none" stroke="#3465af"
-stroke-width="28.432" style=""/><path id="path775" d="m12151 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path777" d="m12237 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path779" d="m12325 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path781" d="m12411 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path783" d="m12498 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path785" d="m12584 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path787" d="m12672 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path789" d="m12758 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path791"
-d="m12844 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path793" d="m12931 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path795" d="m13018 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path797" d="m13105 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path799" d="m13191 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path801" d="m13279 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path803" d="m13365 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path805" d="m13451 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path807" d="m13538 4235.9h53.795" fill="none" stroke="#3465af"
-stroke-width="28.432" style=""/><path id="path809" d="m13625 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path811" d="m13712 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path813" d="m13798 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path815" d="m13886 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path817" d="m13972 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path819" d="m14058 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path821" d="m14145 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path823" d="m14232 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path825" d="m14319
-4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path827" d="m14405 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path829" d="m14493 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path831" d="m14579 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path833" d="m14665 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path835" d="m14752 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path837" d="m14839 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path839" d="m14926 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path841" d="m15012 4235.9h53.795" fill="none" stroke="#3465af"
-stroke-width="28.432" style=""/><path id="path843" d="m15100 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path845" d="m15186 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path847" d="m15272 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path849" d="m15359 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path851" d="m15446 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path853" d="m15533 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path855" d="m15619 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path857" d="m15707 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path859" d="m15793
-4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path861" d="m15880 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path863" d="m15966 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path865" d="m16053 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path867" d="m16140 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path869" d="m16226 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path871" d="m16313 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path873" d="m16400 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path875" d="m16487 4235.9h53.795" fill="none" stroke="#3465af"
-stroke-width="28.432" style=""/><path id="path877" d="m16573 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path879" d="m16660 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path881" d="m16747 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path883" d="m16833 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path885" d="m16920 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path887" d="m17007 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path889" d="m17094 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path891" d="m17180 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path893"
-d="m17267 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path895" d="m17354 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path897" d="m17440 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path899" d="m17527 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path901" d="m17614 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path903" d="m17701 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path905" d="m17787 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path907" d="m17874 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path909" d="m17961 4235.9h53.795" fill="none" stroke="#3465af"
-stroke-width="28.432" style=""/><path id="path911" d="m18047 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path913" d="m18134 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path915" d="m18221 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path917" d="m18308 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path919" d="m18394 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path921" d="m18481 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path923" d="m18568 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path925" d="m18654 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path927" d="m18741
-4235.9c17.255-0.9999 35.525-1.9999 53.795-4.9997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path929" d="m18828 4225.9c17.255-3.9998 34.51-8.9995 51.765-13.999" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path931" d="m18911 4200.9c16.24-5.9996 32.48-12.999 48.72-20.999" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path933" d="m18989 4164.9c15.225-7.9996 31.465-16.999 45.675-26.998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path935" d="m19062 4118.9c14.21-9.9994 28.42-20.999 42.63-31.998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path937" d="m19129 4064.9c13.195-11.999 25.375-24.998 37.555-37.998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path939" d="m19189 4002.9c11.165-13.999 22.33-27.998 33.495-41.998" fill="none"
-stroke="#3465af" stroke-width="28.432" style=""/><path id="path941" d="m19241 3933.9c10.15-14.999 19.285-29.998 27.405-44.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path943" d="m19283 3860c7.105-15.999 14.21-32.998 20.3-48.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path945" d="m19315 3780c5.075-16.999 9.135-33.998 13.195-50.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path947" d="m19333 3697c2.03-17.999 4.06-34.998 4.06-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path949" d="m19337 3612v-53.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path951" d="m19337 3526v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path953" d="m19337 3441v-52.997" fill="none" stroke="#3465af" stroke-width="28.432"
-style=""/><path id="path955" d="m19337 3355v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path957" d="m19337 3270v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path959" d="m19337 3184v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path961" d="m19337 3099v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path963" d="m19337 3014v-53.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path965" d="m19337 2928v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path967" d="m19337 2843v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path969" d="m19337 2757v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path971" d="m19337 2672v-52.997" fill="none"
-stroke="#3465af" stroke-width="28.432" style=""/><path id="path973" d="m19337 2586v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path975" d="m19337 2501v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path977" d="m19337 2415v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path979" d="m19337 2330v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path981" d="m19337 2245v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path983" d="m19337 2159.1v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path985" d="m19337 2074.1v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path987" d="m19337 1988.1v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path
-id="path989" d="m19337 1903.1v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path991" d="m19337 1817.1v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path993" d="m19337 1732.1v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path995" d="m19337 1647.1v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path997" d="m19337 1561.1v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path999" d="m19337 1476.1v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1001" d="m19337 1390.1v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1003" d="m19337 1305.1v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1005" d="m19337
-1219.1c-1.015-16.999-3.045-34.998-5.075-51.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1007" d="m19326 1135.1c-4.06-16.999-8.12-34.998-14.21-50.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1009" d="m19301 1053.1c-6.09-15.999-13.195-32.998-21.315-48.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1011" d="m19264 976.12c-9.135-15.999-18.27-30.998-28.42-45.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1013" d="m19216 904.13c-10.15-13.999-21.315-27.998-33.495-41.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1015" d="m19161 838.13c-12.18-12.999-24.36-24.998-37.555-36.998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1017" d="m19098 780.14c-14.21-11.999-28.42-21.999-42.63-32.998" fill="none"
-stroke="#3465af" stroke-width="28.432" style=""/><path id="path1019" d="m19028 729.14c-15.225-8.9995-30.45-17.999-46.69-26.998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1021" d="m18951 688.14c-16.24-7.9995-32.48-13.999-49.735-19.999" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1023" d="m18870 657.14c-17.255-4.9997-34.51-8.9995-51.765-11.999" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1025" d="m18786 640.14c-18.27-2.9998-35.525-3.9998-53.795-3.9998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1027" d="m18700 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1029" d="m18612 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1031" d="m18526 636.14h-53.795" fill="none" stroke="#3465af"
-stroke-width="28.432" style=""/><path id="path1033" d="m18439 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1035" d="m18353 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1037" d="m18266 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1039" d="m18179 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1041" d="m18093 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1043" d="m18005 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1045" d="m17919 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1047" d="m17832 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path
-id="path1049" d="m17746 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1051" d="m17659 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1053" d="m17572 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1055" d="m17486 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1057" d="m17399 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1059" d="m17312 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1061" d="m17225 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1063" d="m17139 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1065" d="m17052 636.14h-54.81"
-fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1067" d="m16965 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1069" d="m16879 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1071" d="m16792 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1073" d="m16705 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1075" d="m16618 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1077" d="m16532 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1079" d="m16445 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1081" d="m16358 636.14h-53.795" fill="none" stroke="#3465af"
-stroke-width="28.432" style=""/><path id="path1083" d="m16272 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1085" d="m16185 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1087" d="m16098 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1089" d="m16011 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1091" d="m15925 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1093" d="m15837 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1095" d="m15751 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1097" d="m15665 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path
-id="path1099" d="m15578 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1101" d="m15491 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1103" d="m15404 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1105" d="m15318 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1107" d="m15230 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1109" d="m15144 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1111" d="m15058 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1113" d="m14971 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1115" d="m14884 636.14h-53.795"
-fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1117" d="m14797 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1119" d="m14711 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1121" d="m14624 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1123" d="m14537 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1125" d="m14451 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1127" d="m14364 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1129" d="m14277 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1131" d="m14190 636.14h-53.795" fill="none" stroke="#3465af"
-stroke-width="28.432" style=""/><path id="path1133" d="m14104 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1135" d="m14017 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1137" d="m13930 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1139" d="m13844 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1141" d="m13757 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1143" d="m13670 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1145" d="m13583 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1147" d="m13497 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path
-id="path1149" d="m13410 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1151" d="m13323 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1153" d="m13237 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1155" d="m13150 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1157" d="m13063 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1159" d="m12976 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1161" d="m12890 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1163" d="m12803 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1165" d="m12716 636.14h-53.795"
-fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1167" d="m12630 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1169" d="m12543 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1171" d="m12456 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1173" d="m12369 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1175" d="m12283 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1177" d="m12196 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1179" d="m12109 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1181" d="m12022 636.14h-53.795" fill="none" stroke="#3465af"
-stroke-width="28.432" style=""/><path id="path1183" d="m11936 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1185" d="m11850 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1187" d="m11762 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1189" d="m11676 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1191" d="m11589 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1193" d="m11502 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1195" d="m11415 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1197" d="m11329 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path
-id="path1199" d="m11243 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1201" d="m11155 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1203" d="m11069 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1205" d="m10982 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1207" d="m10895 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1209" d="m10808 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1211" d="m10722 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1213" d="m10636 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1215" d="m10548 636.14h-53.795"
-fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1217" d="m10462 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1219" d="m10375 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1221" d="m10288 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1223" d="m10201 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1225" d="m10115 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1227" d="m10029 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1229" d="m9941.3 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1231" d="m9855 636.14h-53.795" fill="none" stroke="#3465af"
-stroke-width="28.432" style=""/><path id="path1233" d="m9767.7 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1235" d="m9681.5 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1237" d="m9594.2 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1239" d="m9507.9 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1241" d="m9421.6 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1243" d="m9334.3 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1245" d="m9248.1 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1247" d="m9160.8 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432"
-style=""/><path id="path1249" d="m9074.5 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1251" d="m8987.2 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1253" d="m8900.9 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1255" d="m8814.7 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1257" d="m8727.4 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1259" d="m8641.1 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1261" d="m8553.8 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1263" d="m8467.5 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1265"
-d="m8380.2 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1267" d="m8294 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1269" d="m8207.7 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1271" d="m8120.4 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1273" d="m8034.1 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1275" d="m7946.8 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1277" d="m7860.6 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1279" d="m7773.3 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1281" d="m7687 636.14h-53.795" fill="none"
-stroke="#3465af" stroke-width="28.432" style=""/><path id="path1283" d="m7599.7 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1285" d="m7513.4 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1287" d="m7427.2 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1289" d="m7339.9 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1291" d="m7253.6 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1293" d="m7166.3 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1295" d="m7080 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1297" d="m6992.7 636.14h-53.795" fill="none" stroke="#3465af"
-stroke-width="28.432" style=""/><path id="path1299" d="m6906.5 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1301" d="m6820.2 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1303" d="m6732.9 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1305" d="m6646.6 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1307" d="m6559.3 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1309" d="m6473.1 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1311" d="m6385.8 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1313" d="m6299.5 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432"
-style=""/><path id="path1315" d="m6213.2 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1317" d="m6125.9 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1319" d="m6039.6 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1321" d="m5952.4 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1323" d="m5866.1 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1325" d="m5778.8 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1327" d="m5692.5 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1329" d="m5606.2 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1331"
-d="m5519 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1333" d="m5432.7 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1335" d="m5345.4 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1337" d="m5259.1 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1339" d="m5171.8 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1341" d="m5085.5 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1343" d="m4999.3 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1345" d="m4912 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1347" d="m4825.7 636.14h-53.795" fill="none"
-stroke="#3465af" stroke-width="28.432" style=""/><path id="path1349" d="m4738.4 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1351" d="m4652.1 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1353" d="m4564.9 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1355" d="m4478.6 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1357" d="m4392.3 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1359" d="m4305 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1361" d="m4218.7 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1363" d="m4131.4 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432"
-style=""/><path id="path1365" d="m4045.2 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1367" d="m3957.9 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1369" d="m3871.6 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1371" d="m3785.3 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1373" d="m3698 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1375" d="m3611.8 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1377" d="m3524.5 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1379" d="m3438.2 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1381"
-d="m3350.9 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1383" d="m3264.6 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1385" d="m3177.3 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1387" d="m3091.1 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1389" d="m3004.8 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1391" d="m2917.5 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1393" d="m2831.2 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1395" d="m2743.9 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1397" d="m2657.7 636.14h-53.795"
-fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1399" d="m2570.4 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1401" d="m2484.1 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1403" d="m2397.8 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1405" d="m2310.5 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1407" d="m2224.3 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1409" d="m2137 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1411" d="m2050.7 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1413" d="m1963.4 636.14h-53.795" fill="none" stroke="#3465af"
-stroke-width="28.432" style=""/><path id="path1415" d="m1877.1 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1417" d="m1790.9 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1419" d="m1703.6 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1421" d="m1617.3 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1423" d="m1530 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1425" d="m1443.7 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1427" d="m1356.4 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1429" d="m1270.2 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path
-id="path1431" d="m1183.9 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1433" d="m1096.6 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1435" d="m1010.3 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1437" d="m923.03 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><g id="g4044" style=""><rect id="rect1441" x="21109" y="4753.1" width="1213.6" height="1100.7" fill="#f3e777" style=""/><path id="path1443" d="m20656 5536.4v-405.46l150.7-169.16c82.886-93.039 170.53-186.62 194.77-207.96l44.069-38.798 783.23-0.086 783.23-0.086v1227h-1956v-405.46zm1027.7 136.98v-78.372l-169.91 4.925-169.91 4.9249-5.09 45.854c-8.249 74.303 46.711 101.04 207.69 101.04h137.21v-78.372zm235.86-262.94 4.495-341.31 207.2-8.6408 207.2-8.6408
-5.144-46.443c9.596-86.615-41.863-102.05-322.02-96.607l-246.71 4.7956-4.438 419.08-4.439 419.08h149.08l4.494-341.31zm391.3 313.72c26.41-19.286 36.255-41.399 32.697-73.447l-5.09-45.854h-348.1l-5.38 48.984c-9.97 90.771 0.993 97.91 150.36 97.91 99.305 0 148.27-7.6982 175.52-27.594zm-627.16-274.84v-77.768h-348.1v66.246c0 36.436 4.973 71.431 11.051 77.768 6.078 6.3366 84.401 11.521 174.05 11.521h163v-77.768zm659.89-4.9154 5.125-74.042-179.18 4.9155-179.18 4.9155-5.38 48.984c-10.473 95.348-2.259 99.57 183.28 94.197l170.2-4.9284 5.125-74.042zm-659.89-237.63v-78.372l-169.91 4.925-169.91 4.925-5.097 73.447-5.097 73.447h350v-78.372zm659.86 4.925-5.097-73.447h-348.1l-5.38 48.984c-10.289 93.673-2.146 97.91 188.15 97.91h175.52l-5.097-73.447zm-659.86-228.98v-77.768h-137.21c-97.358 0-147.91 7.8138-174.05 26.902-34.952 25.523-49.645 92.242-25.79 117.11 6.078 6.3366 84.401 11.521 174.05
-11.521h163v-77.768z" fill="#ca4677" style=""/></g><text id="text1489" class="TextShape" transform="scale(1.1036 .90616)" x="171.41566" y="9913.7109" fill-rule="evenodd" font-family="Serif, serif" font-size="493.87px" stroke-linejoin="round" stroke-width="28.222"><tspan id="tspan1491" class="TextParagraph" font-family="Serif, serif" font-size="493.87px"/></text>
-<g id="g4048" style=""><rect id="rect1447" x="18797" y="13737" width="2320.7" height="2342.4" fill="#6076b3" style=""/><rect id="rect1451" x="18532" y="13817" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1453" x="18532" y="14076" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1455" x="18532" y="14334" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1457" x="18532" y="14593" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1459" x="18532" y="14851" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round"
-stroke-width="28.222" style=""/><rect id="rect1461" x="18532" y="15110" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1463" x="18532" y="15368" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1465" x="18532" y="15626" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1467" x="18532" y="15884" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1469" x="21080" y="13783" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1471" x="21080" y="14041" width="302.7"
-height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1473" x="21080" y="14299" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1475" x="21080" y="14558" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1477" x="21080" y="14816" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1479" x="21080" y="15075" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1481" x="21080" y="15333" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round"
-stroke-width="28.222" style=""/><rect id="rect1483" x="21080" y="15592" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1485" x="21080" y="15850" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><text id="text1493" transform="scale(1.1036 .90616)" x="17205.688" y="16777.641" fill="#000000" fill-rule="evenodd" font-family="Sans" font-size="856.96px" letter-spacing="0px" stroke-linejoin="round" stroke-width="28.222" word-spacing="0px" style="line-height:125%" line-height="125%" xml:space="preserve"><tspan id="tspan1495" x="17205.688" y="16777.641" style="">CPU</tspan></text>
-</g><text id="text1499" class="TextShape" x="-11700.553" y="565.61298" fill-rule="evenodd" font-family="Serif, serif" font-size="493.88px" stroke-linejoin="round" stroke-width="28.222"><tspan id="tspan1501" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan1503" class="TextPosition" transform="matrix(0,-1,1,0,8509,40173)" x="12640.447" y="16397.613" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan1505" fill="#000000" font-family="Serif, serif" font-size="493.88px">PCI, USB, SPI, I2C, ...</tspan></tspan></tspan></text>
-<path id="path1511" d="m12408 15562h-1115.1v-1420.3h2230.2v1420.3h-1115.1z" fill="#cfe7f5" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><path id="path1513" d="m12408 15562h-1115.1v-1420.3h2230.2v1420.3h-1115.1z" fill="none" stroke="#3465af" stroke-linejoin="round" stroke-width="19.847" style=""/><text id="text1515" class="TextShape" x="-1394.0863" y="590.73016" fill-rule="evenodd" font-family="Serif, serif" font-size="493.88px" stroke-linejoin="round" stroke-width="28.222"><tspan id="tspan1517" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan1519" class="TextPosition" x="11487.915" y="14672.743" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan1521" fill="#000000" font-family="Serif, serif" font-size="493.88px">Bridge</tspan></tspan></tspan></text>
-<text id="text1523" class="TextShape" x="-1450.5308" y="1324.5078" fill-rule="evenodd" font-family="Serif, serif" font-size="493.88px" stroke-linejoin="round" stroke-width="28.222"><tspan id="tspan1525" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan1527" class="TextPosition" x="11431.471" y="15406.52" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan1529" fill="#000000" font-family="Serif, serif" font-size="493.88px"> DMA</tspan></tspan></tspan></text>
-</svg>
diff --git a/Documentation/media/uapi/cec/cec-api.rst b/Documentation/media/uapi/cec/cec-api.rst
deleted file mode 100644
index 0780ba07995a..000000000000
--- a/Documentation/media/uapi/cec/cec-api.rst
+++ /dev/null
@@ -1,54 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. include:: <isonum.txt>
-
-.. _cec:
-
-#########################################
-Part V - Consumer Electronics Control API
-#########################################
-
-This part describes the CEC: Consumer Electronics Control
-
-
-.. only:: html
-
-   .. class:: toc-title
-
-        Table of Contents
-
-.. toctree::
-    :maxdepth: 5
-    :numbered:
-
-    cec-intro
-    cec-funcs
-    cec-pin-error-inj
-    cec-header
-
-
-**********************
-Revision and Copyright
-**********************
-Authors:
-
-- Verkuil, Hans <hverkuil-cisco@xs4all.nl>
-
- - Initial version.
-
-**Copyright** |copy| 2016 : Hans Verkuil
-
-****************
-Revision History
-****************
-
-:revision: 1.0.0 / 2016-03-17 (*hv*)
-
-Initial revision
diff --git a/Documentation/media/uapi/cec/cec-func-close.rst b/Documentation/media/uapi/cec/cec-func-close.rst
deleted file mode 100644
index e10d675546f8..000000000000
--- a/Documentation/media/uapi/cec/cec-func-close.rst
+++ /dev/null
@@ -1,54 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _cec-func-close:
-
-***********
-cec close()
-***********
-
-Name
-====
-
-cec-close - Close a cec device
-
-
-Synopsis
-========
-
-.. code-block:: c
-
-    #include <unistd.h>
-
-
-.. c:function:: int close( int fd )
-    :name: cec-close
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :c:func:`open() <cec-open>`.
-
-
-Description
-===========
-
-Closes the cec device. Resources associated with the file descriptor are
-freed. The device configuration remain unchanged.
-
-
-Return Value
-============
-
-:c:func:`close() <cec-close>` returns 0 on success. On error, -1 is returned, and
-``errno`` is set appropriately. Possible error codes are:
-
-``EBADF``
-    ``fd`` is not a valid open file descriptor.
diff --git a/Documentation/media/uapi/cec/cec-func-ioctl.rst b/Documentation/media/uapi/cec/cec-func-ioctl.rst
deleted file mode 100644
index c18d4ba5eb37..000000000000
--- a/Documentation/media/uapi/cec/cec-func-ioctl.rst
+++ /dev/null
@@ -1,73 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _cec-func-ioctl:
-
-***********
-cec ioctl()
-***********
-
-Name
-====
-
-cec-ioctl - Control a cec device
-
-Synopsis
-========
-
-.. code-block:: c
-
-    #include <sys/ioctl.h>
-
-
-.. c:function:: int ioctl( int fd, int request, void *argp )
-   :name: cec-ioctl
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :c:func:`open() <cec-open>`.
-
-``request``
-    CEC ioctl request code as defined in the cec.h header file, for
-    example :ref:`CEC_ADAP_G_CAPS <CEC_ADAP_G_CAPS>`.
-
-``argp``
-    Pointer to a request-specific structure.
-
-
-Description
-===========
-
-The :c:func:`ioctl() <cec-ioctl>` function manipulates cec device parameters. The
-argument ``fd`` must be an open file descriptor.
-
-The ioctl ``request`` code specifies the cec function to be called. It
-has encoded in it whether the argument is an input, output or read/write
-parameter, and the size of the argument ``argp`` in bytes.
-
-Macros and structures definitions specifying cec ioctl requests and
-their parameters are located in the cec.h header file. All cec ioctl
-requests, their respective function and parameters are specified in
-:ref:`cec-user-func`.
-
-
-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.
-
-Request-specific error codes are listed in the individual requests
-descriptions.
-
-When an ioctl that takes an output or read/write parameter fails, the
-parameter remains unmodified.
diff --git a/Documentation/media/uapi/cec/cec-func-open.rst b/Documentation/media/uapi/cec/cec-func-open.rst
deleted file mode 100644
index f235aa80155c..000000000000
--- a/Documentation/media/uapi/cec/cec-func-open.rst
+++ /dev/null
@@ -1,85 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _cec-func-open:
-
-**********
-cec open()
-**********
-
-Name
-====
-
-cec-open - Open a cec device
-
-Synopsis
-========
-
-.. code-block:: c
-
-    #include <fcntl.h>
-
-
-.. c:function:: int open( const char *device_name, int flags )
-   :name: cec-open
-
-
-Arguments
-=========
-
-``device_name``
-    Device to be opened.
-
-``flags``
-    Open flags. Access mode must be ``O_RDWR``.
-
-    When the ``O_NONBLOCK`` flag is given, the
-    :ref:`CEC_RECEIVE <CEC_RECEIVE>` and :ref:`CEC_DQEVENT <CEC_DQEVENT>` ioctls
-    will return the ``EAGAIN`` error code when no message or event is available, and
-    ioctls :ref:`CEC_TRANSMIT <CEC_TRANSMIT>`,
-    :ref:`CEC_ADAP_S_PHYS_ADDR <CEC_ADAP_S_PHYS_ADDR>` and
-    :ref:`CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`
-    all return 0.
-
-    Other flags have no effect.
-
-
-Description
-===========
-
-To open a cec device applications call :c:func:`open() <cec-open>` with the
-desired device name. The function has no side effects; the device
-configuration remain unchanged.
-
-When the device is opened in read-only mode, attempts to modify its
-configuration will result in an error, and ``errno`` will be set to
-EBADF.
-
-
-Return Value
-============
-
-:c:func:`open() <cec-open>` returns the new file descriptor on success. On error,
--1 is returned, and ``errno`` is set appropriately. Possible error codes
-include:
-
-``EACCES``
-    The requested access to the file is not allowed.
-
-``EMFILE``
-    The process already has the maximum number of files open.
-
-``ENFILE``
-    The system limit on the total number of open files has been reached.
-
-``ENOMEM``
-    Insufficient kernel memory was available.
-
-``ENXIO``
-    No device corresponding to this device special file exists.
diff --git a/Documentation/media/uapi/cec/cec-func-poll.rst b/Documentation/media/uapi/cec/cec-func-poll.rst
deleted file mode 100644
index 3f6c5b0effa3..000000000000
--- a/Documentation/media/uapi/cec/cec-func-poll.rst
+++ /dev/null
@@ -1,85 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _cec-func-poll:
-
-**********
-cec poll()
-**********
-
-Name
-====
-
-cec-poll - Wait for some event on a file descriptor
-
-
-Synopsis
-========
-
-.. code-block:: c
-
-    #include <sys/poll.h>
-
-
-.. c:function:: int poll( struct pollfd *ufds, unsigned int nfds, int timeout )
-   :name: cec-poll
-
-Arguments
-=========
-
-``ufds``
-   List of FD events to be watched
-
-``nfds``
-   Number of FD events at the \*ufds array
-
-``timeout``
-   Timeout to wait for events
-
-
-Description
-===========
-
-With the :c:func:`poll() <cec-poll>` function applications can wait for CEC
-events.
-
-On success :c:func:`poll() <cec-poll>` returns the number of file descriptors
-that have been selected (that is, file descriptors for which the
-``revents`` field of the respective struct :c:type:`pollfd`
-is non-zero). CEC devices set the ``POLLIN`` and ``POLLRDNORM`` flags in
-the ``revents`` field if there are messages in the receive queue. If the
-transmit queue has room for new messages, the ``POLLOUT`` and
-``POLLWRNORM`` flags are set. If there are events in the event queue,
-then the ``POLLPRI`` flag is set. When the function times out it returns
-a value of zero, on failure it returns -1 and the ``errno`` variable is
-set appropriately.
-
-For more details see the :c:func:`poll() <cec-poll>` manual page.
-
-
-Return Value
-============
-
-On success, :c:func:`poll() <cec-poll>` returns the number structures which have
-non-zero ``revents`` fields, or zero if the call timed out. On error -1
-is returned, and the ``errno`` variable is set appropriately:
-
-``EBADF``
-    One or more of the ``ufds`` members specify an invalid file
-    descriptor.
-
-``EFAULT``
-    ``ufds`` references an inaccessible memory area.
-
-``EINTR``
-    The call was interrupted by a signal.
-
-``EINVAL``
-    The ``nfds`` value exceeds the ``RLIMIT_NOFILE`` value. Use
-    ``getrlimit()`` to obtain this value.
diff --git a/Documentation/media/uapi/cec/cec-funcs.rst b/Documentation/media/uapi/cec/cec-funcs.rst
deleted file mode 100644
index dc6da9c639a8..000000000000
--- a/Documentation/media/uapi/cec/cec-funcs.rst
+++ /dev/null
@@ -1,30 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _cec-user-func:
-
-******************
-Function Reference
-******************
-
-
-.. toctree::
-    :maxdepth: 1
-
-    cec-func-open
-    cec-func-close
-    cec-func-ioctl
-    cec-func-poll
-    cec-ioc-adap-g-caps
-    cec-ioc-adap-g-log-addrs
-    cec-ioc-adap-g-phys-addr
-    cec-ioc-adap-g-conn-info
-    cec-ioc-dqevent
-    cec-ioc-g-mode
-    cec-ioc-receive
diff --git a/Documentation/media/uapi/cec/cec-header.rst b/Documentation/media/uapi/cec/cec-header.rst
deleted file mode 100644
index 726f9766a130..000000000000
--- a/Documentation/media/uapi/cec/cec-header.rst
+++ /dev/null
@@ -1,17 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _cec_header:
-
-***************
-CEC Header File
-***************
-
-.. kernel-include:: $BUILDDIR/cec.h.rst
-
diff --git a/Documentation/media/uapi/cec/cec-intro.rst b/Documentation/media/uapi/cec/cec-intro.rst
deleted file mode 100644
index 05088fcefe81..000000000000
--- a/Documentation/media/uapi/cec/cec-intro.rst
+++ /dev/null
@@ -1,49 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _cec-intro:
-
-Introduction
-============
-
-HDMI connectors provide a single pin for use by the Consumer Electronics
-Control protocol. This protocol allows different devices connected by an
-HDMI cable to communicate. The protocol for CEC version 1.4 is defined
-in supplements 1 (CEC) and 2 (HEAC or HDMI Ethernet and Audio Return
-Channel) of the HDMI 1.4a (:ref:`hdmi`) specification and the
-extensions added to CEC version 2.0 are defined in chapter 11 of the
-HDMI 2.0 (:ref:`hdmi2`) specification.
-
-The bitrate is very slow (effectively no more than 36 bytes per second)
-and is based on the ancient AV.link protocol used in old SCART
-connectors. The protocol closely resembles a crazy Rube Goldberg
-contraption and is an unholy mix of low and high level messages. Some
-messages, especially those part of the HEAC protocol layered on top of
-CEC, need to be handled by the kernel, others can be handled either by
-the kernel or by userspace.
-
-In addition, CEC can be implemented in HDMI receivers, transmitters and
-in USB devices that have an HDMI input and an HDMI output and that
-control just the CEC pin.
-
-Drivers that support CEC will create a CEC device node (/dev/cecX) to
-give userspace access to the CEC adapter. The
-:ref:`CEC_ADAP_G_CAPS` ioctl will tell userspace what it is allowed to do.
-
-In order to check the support and test it, it is suggested to download
-the `v4l-utils <https://git.linuxtv.org/v4l-utils.git/>`_ package. It
-provides three tools to handle CEC:
-
-- cec-ctl: the Swiss army knife of CEC. Allows you to configure, transmit
-  and monitor CEC messages.
-
-- cec-compliance: does a CEC compliance test of a remote CEC device to
-  determine how compliant the CEC implementation is.
-
-- cec-follower: emulates a CEC follower.
diff --git a/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst b/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst
deleted file mode 100644
index 76761a98c312..000000000000
--- a/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst
+++ /dev/null
@@ -1,150 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _CEC_ADAP_G_CAPS:
-
-*********************
-ioctl CEC_ADAP_G_CAPS
-*********************
-
-Name
-====
-
-CEC_ADAP_G_CAPS - Query device capabilities
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, CEC_ADAP_G_CAPS, struct cec_caps *argp )
-    :name: CEC_ADAP_G_CAPS
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :c:func:`open() <cec-open>`.
-
-``argp``
-
-
-Description
-===========
-
-All cec devices must support :ref:`ioctl CEC_ADAP_G_CAPS <CEC_ADAP_G_CAPS>`. To query
-device information, applications call the ioctl with a pointer to a
-struct :c:type:`cec_caps`. The driver fills the structure and
-returns the information to the application. The ioctl never fails.
-
-.. tabularcolumns:: |p{1.2cm}|p{2.5cm}|p{13.8cm}|
-
-.. c:type:: cec_caps
-
-.. flat-table:: struct cec_caps
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 16
-
-    * - char
-      - ``driver[32]``
-      - The name of the cec adapter driver.
-    * - char
-      - ``name[32]``
-      - The name of this CEC adapter. The combination ``driver`` and
-	``name`` must be unique.
-    * - __u32
-      - ``capabilities``
-      - The capabilities of the CEC adapter, see
-	:ref:`cec-capabilities`.
-    * - __u32
-      - ``version``
-      - CEC Framework API version, formatted with the ``KERNEL_VERSION()``
-	macro.
-
-
-.. tabularcolumns:: |p{4.4cm}|p{2.5cm}|p{10.6cm}|
-
-.. _cec-capabilities:
-
-.. flat-table:: CEC Capabilities Flags
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 8
-
-    * .. _`CEC-CAP-PHYS-ADDR`:
-
-      - ``CEC_CAP_PHYS_ADDR``
-      - 0x00000001
-      - Userspace has to configure the physical address by calling
-	:ref:`ioctl CEC_ADAP_S_PHYS_ADDR <CEC_ADAP_S_PHYS_ADDR>`. If
-	this capability isn't set, then setting the physical address is
-	handled by the kernel whenever the EDID is set (for an HDMI
-	receiver) or read (for an HDMI transmitter).
-    * .. _`CEC-CAP-LOG-ADDRS`:
-
-      - ``CEC_CAP_LOG_ADDRS``
-      - 0x00000002
-      - Userspace has to configure the logical addresses by calling
-	:ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`. If
-	this capability isn't set, then the kernel will have configured
-	this.
-    * .. _`CEC-CAP-TRANSMIT`:
-
-      - ``CEC_CAP_TRANSMIT``
-      - 0x00000004
-      - Userspace can transmit CEC messages by calling
-	:ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>`. This implies that
-	userspace can be a follower as well, since being able to transmit
-	messages is a prerequisite of becoming a follower. If this
-	capability isn't set, then the kernel will handle all CEC
-	transmits and process all CEC messages it receives.
-    * .. _`CEC-CAP-PASSTHROUGH`:
-
-      - ``CEC_CAP_PASSTHROUGH``
-      - 0x00000008
-      - Userspace can use the passthrough mode by calling
-	:ref:`ioctl CEC_S_MODE <CEC_S_MODE>`.
-    * .. _`CEC-CAP-RC`:
-
-      - ``CEC_CAP_RC``
-      - 0x00000010
-      - This adapter supports the remote control protocol.
-    * .. _`CEC-CAP-MONITOR-ALL`:
-
-      - ``CEC_CAP_MONITOR_ALL``
-      - 0x00000020
-      - The CEC hardware can monitor all messages, not just directed and
-	broadcast messages.
-    * .. _`CEC-CAP-NEEDS-HPD`:
-
-      - ``CEC_CAP_NEEDS_HPD``
-      - 0x00000040
-      - The CEC hardware is only active if the HDMI Hotplug Detect pin is
-        high. This makes it impossible to use CEC to wake up displays that
-	set the HPD pin low when in standby mode, but keep the CEC bus
-	alive.
-    * .. _`CEC-CAP-MONITOR-PIN`:
-
-      - ``CEC_CAP_MONITOR_PIN``
-      - 0x00000080
-      - The CEC hardware can monitor CEC pin changes from low to high voltage
-        and vice versa. When in pin monitoring mode the application will
-	receive ``CEC_EVENT_PIN_CEC_LOW`` and ``CEC_EVENT_PIN_CEC_HIGH`` events.
-    * .. _`CEC-CAP-CONNECTOR-INFO`:
-
-      - ``CEC_CAP_CONNECTOR_INFO``
-      - 0x00000100
-      - If this capability is set, then :ref:`CEC_ADAP_G_CONNECTOR_INFO` can
-        be used.
-
-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/cec/cec-ioc-adap-g-conn-info.rst b/Documentation/media/uapi/cec/cec-ioc-adap-g-conn-info.rst
deleted file mode 100644
index 6818ddf1495c..000000000000
--- a/Documentation/media/uapi/cec/cec-ioc-adap-g-conn-info.rst
+++ /dev/null
@@ -1,105 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-..
-.. Copyright 2019 Google LLC
-..
-.. _CEC_ADAP_G_CONNECTOR_INFO:
-
-*******************************
-ioctl CEC_ADAP_G_CONNECTOR_INFO
-*******************************
-
-Name
-====
-
-CEC_ADAP_G_CONNECTOR_INFO - Query HDMI connector information
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, CEC_ADAP_G_CONNECTOR_INFO, struct cec_connector_info *argp )
-    :name: CEC_ADAP_G_CONNECTOR_INFO
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :c:func:`open() <cec-open>`.
-
-``argp``
-
-
-Description
-===========
-
-Using this ioctl an application can learn which HDMI connector this CEC
-device corresponds to. While calling this ioctl the application should
-provide a pointer to a cec_connector_info struct which will be populated
-by the kernel with the info provided by the adapter's driver. This ioctl
-is only available if the ``CEC_CAP_CONNECTOR_INFO`` capability is set.
-
-.. tabularcolumns:: |p{1.0cm}|p{4.4cm}|p{2.5cm}|p{9.6cm}|
-
-.. c:type:: cec_connector_info
-
-.. flat-table:: struct cec_connector_info
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 8
-
-    * - __u32
-      - ``type``
-      - The type of connector this adapter is associated with.
-    * - union {
-      - ``(anonymous)``
-    * - ``struct cec_drm_connector_info``
-      - drm
-      - :ref:`cec-drm-connector-info`
-    * - }
-      -
-
-
-.. tabularcolumns:: |p{4.4cm}|p{2.5cm}|p{10.6cm}|
-
-.. _connector-type:
-
-.. flat-table:: Connector types
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 8
-
-    * .. _`CEC-CONNECTOR-TYPE-NO-CONNECTOR`:
-
-      - ``CEC_CONNECTOR_TYPE_NO_CONNECTOR``
-      - 0
-      - No connector is associated with the adapter/the information is not
-        provided by the driver.
-    * .. _`CEC-CONNECTOR-TYPE-DRM`:
-
-      - ``CEC_CONNECTOR_TYPE_DRM``
-      - 1
-      - Indicates that a DRM connector is associated with this adapter.
-        Information about the connector can be found in
-	:ref:`cec-drm-connector-info`.
-
-.. tabularcolumns:: |p{4.4cm}|p{2.5cm}|p{10.6cm}|
-
-.. c:type:: cec_drm_connector_info
-
-.. _cec-drm-connector-info:
-
-.. flat-table:: struct cec_drm_connector_info
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 8
-
-    * .. _`CEC-DRM-CONNECTOR-TYPE-CARD-NO`:
-
-      - __u32
-      - ``card_no``
-      - DRM card number: the number from a card's path, e.g. 0 in case of
-        /dev/card0.
-    * .. _`CEC-DRM-CONNECTOR-TYPE-CONNECTOR_ID`:
-
-      - __u32
-      - ``connector_id``
-      - DRM connector ID.
diff --git a/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst b/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst
deleted file mode 100644
index 26465094e3f1..000000000000
--- a/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst
+++ /dev/null
@@ -1,378 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _CEC_ADAP_LOG_ADDRS:
-.. _CEC_ADAP_G_LOG_ADDRS:
-.. _CEC_ADAP_S_LOG_ADDRS:
-
-****************************************************
-ioctls CEC_ADAP_G_LOG_ADDRS and CEC_ADAP_S_LOG_ADDRS
-****************************************************
-
-Name
-====
-
-CEC_ADAP_G_LOG_ADDRS, CEC_ADAP_S_LOG_ADDRS - Get or set the logical addresses
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, CEC_ADAP_G_LOG_ADDRS, struct cec_log_addrs *argp )
-   :name: CEC_ADAP_G_LOG_ADDRS
-
-.. c:function:: int ioctl( int fd, CEC_ADAP_S_LOG_ADDRS, struct cec_log_addrs *argp )
-   :name: CEC_ADAP_S_LOG_ADDRS
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :c:func:`open() <cec-open>`.
-
-``argp``
-    Pointer to struct :c:type:`cec_log_addrs`.
-
-Description
-===========
-
-To query the current CEC logical addresses, applications call
-:ref:`ioctl CEC_ADAP_G_LOG_ADDRS <CEC_ADAP_G_LOG_ADDRS>` with a pointer to a
-struct :c:type:`cec_log_addrs` where the driver stores the logical addresses.
-
-To set new logical addresses, applications fill in
-struct :c:type:`cec_log_addrs` and call :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`
-with a pointer to this struct. The :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`
-is only available if ``CEC_CAP_LOG_ADDRS`` is set (the ``ENOTTY`` error code is
-returned otherwise). The :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`
-can only be called by a file descriptor in initiator mode (see :ref:`CEC_S_MODE`), if not
-the ``EBUSY`` error code will be returned.
-
-To clear existing logical addresses set ``num_log_addrs`` to 0. All other fields
-will be ignored in that case. The adapter will go to the unconfigured state and the
-``cec_version``, ``vendor_id`` and ``osd_name`` fields are all reset to their default
-values (CEC version 2.0, no vendor ID and an empty OSD name).
-
-If the physical address is valid (see :ref:`ioctl CEC_ADAP_S_PHYS_ADDR <CEC_ADAP_S_PHYS_ADDR>`),
-then this ioctl will block until all requested logical
-addresses have been claimed. If the file descriptor is in non-blocking mode then it will
-not wait for the logical addresses to be claimed, instead it just returns 0.
-
-A :ref:`CEC_EVENT_STATE_CHANGE <CEC-EVENT-STATE-CHANGE>` event is sent when the
-logical addresses are claimed or cleared.
-
-Attempting to call :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>` when
-logical address types are already defined will return with error ``EBUSY``.
-
-.. c:type:: cec_log_addrs
-
-.. tabularcolumns:: |p{1.0cm}|p{8.0cm}|p{7.5cm}|
-
-.. cssclass:: longtable
-
-.. flat-table:: struct cec_log_addrs
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 16
-
-    * - __u8
-      - ``log_addr[CEC_MAX_LOG_ADDRS]``
-      - The actual logical addresses that were claimed. This is set by the
-	driver. If no logical address could be claimed, then it is set to
-	``CEC_LOG_ADDR_INVALID``. If this adapter is Unregistered, then
-	``log_addr[0]`` is set to 0xf and all others to
-	``CEC_LOG_ADDR_INVALID``.
-    * - __u16
-      - ``log_addr_mask``
-      - The bitmask of all logical addresses this adapter has claimed. If
-	this adapter is Unregistered then ``log_addr_mask`` sets bit 15
-	and clears all other bits. If this adapter is not configured at
-	all, then ``log_addr_mask`` is set to 0. Set by the driver.
-    * - __u8
-      - ``cec_version``
-      - The CEC version that this adapter shall use. See
-	:ref:`cec-versions`. Used to implement the
-	``CEC_MSG_CEC_VERSION`` and ``CEC_MSG_REPORT_FEATURES`` messages.
-	Note that :ref:`CEC_OP_CEC_VERSION_1_3A <CEC-OP-CEC-VERSION-1-3A>` is not allowed by the CEC
-	framework.
-    * - __u8
-      - ``num_log_addrs``
-      - Number of logical addresses to set up. Must be ≤
-	``available_log_addrs`` as returned by
-	:ref:`CEC_ADAP_G_CAPS`. All arrays in
-	this structure are only filled up to index
-	``available_log_addrs``-1. The remaining array elements will be
-	ignored. Note that the CEC 2.0 standard allows for a maximum of 2
-	logical addresses, although some hardware has support for more.
-	``CEC_MAX_LOG_ADDRS`` is 4. The driver will return the actual
-	number of logical addresses it could claim, which may be less than
-	what was requested. If this field is set to 0, then the CEC
-	adapter shall clear all claimed logical addresses and all other
-	fields will be ignored.
-    * - __u32
-      - ``vendor_id``
-      - The vendor ID is a 24-bit number that identifies the specific
-	vendor or entity. Based on this ID vendor specific commands may be
-	defined. If you do not want a vendor ID then set it to
-	``CEC_VENDOR_ID_NONE``.
-    * - __u32
-      - ``flags``
-      - Flags. See :ref:`cec-log-addrs-flags` for a list of available flags.
-    * - char
-      - ``osd_name[15]``
-      - The On-Screen Display name as is returned by the
-	``CEC_MSG_SET_OSD_NAME`` message.
-    * - __u8
-      - ``primary_device_type[CEC_MAX_LOG_ADDRS]``
-      - Primary device type for each logical address. See
-	:ref:`cec-prim-dev-types` for possible types.
-    * - __u8
-      - ``log_addr_type[CEC_MAX_LOG_ADDRS]``
-      - Logical address types. See :ref:`cec-log-addr-types` for
-	possible types. The driver will update this with the actual
-	logical address type that it claimed (e.g. it may have to fallback
-	to :ref:`CEC_LOG_ADDR_TYPE_UNREGISTERED <CEC-LOG-ADDR-TYPE-UNREGISTERED>`).
-    * - __u8
-      - ``all_device_types[CEC_MAX_LOG_ADDRS]``
-      - CEC 2.0 specific: the bit mask of all device types. See
-	:ref:`cec-all-dev-types-flags`. It is used in the CEC 2.0
-	``CEC_MSG_REPORT_FEATURES`` message. For CEC 1.4 you can either leave
-	this field to 0, or fill it in according to the CEC 2.0 guidelines to
-	give the CEC framework more information about the device type, even
-	though the framework won't use it directly in the CEC message.
-    * - __u8
-      - ``features[CEC_MAX_LOG_ADDRS][12]``
-      - Features for each logical address. It is used in the CEC 2.0
-	``CEC_MSG_REPORT_FEATURES`` message. The 12 bytes include both the
-	RC Profile and the Device Features. For CEC 1.4 you can either leave
-        this field to all 0, or fill it in according to the CEC 2.0 guidelines to
-        give the CEC framework more information about the device type, even
-        though the framework won't use it directly in the CEC message.
-
-
-.. tabularcolumns:: |p{7.8cm}|p{1.0cm}|p{8.7cm}|
-
-.. _cec-log-addrs-flags:
-
-.. flat-table:: Flags for struct cec_log_addrs
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * .. _`CEC-LOG-ADDRS-FL-ALLOW-UNREG-FALLBACK`:
-
-      - ``CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK``
-      - 1
-      - By default if no logical address of the requested type can be claimed, then
-	it will go back to the unconfigured state. If this flag is set, then it will
-	fallback to the Unregistered logical address. Note that if the Unregistered
-	logical address was explicitly requested, then this flag has no effect.
-    * .. _`CEC-LOG-ADDRS-FL-ALLOW-RC-PASSTHRU`:
-
-      - ``CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU``
-      - 2
-      - By default the ``CEC_MSG_USER_CONTROL_PRESSED`` and ``CEC_MSG_USER_CONTROL_RELEASED``
-        messages are only passed on to the follower(s), if any. If this flag is set,
-	then these messages are also passed on to the remote control input subsystem
-	and will appear as keystrokes. This features needs to be enabled explicitly.
-	If CEC is used to enter e.g. passwords, then you may not want to enable this
-	to avoid trivial snooping of the keystrokes.
-    * .. _`CEC-LOG-ADDRS-FL-CDC-ONLY`:
-
-      - ``CEC_LOG_ADDRS_FL_CDC_ONLY``
-      - 4
-      - If this flag is set, then the device is CDC-Only. CDC-Only CEC devices
-	are CEC devices that can only handle CDC messages.
-
-	All other messages are ignored.
-
-
-.. tabularcolumns:: |p{7.8cm}|p{1.0cm}|p{8.7cm}|
-
-.. _cec-versions:
-
-.. flat-table:: CEC Versions
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * .. _`CEC-OP-CEC-VERSION-1-3A`:
-
-      - ``CEC_OP_CEC_VERSION_1_3A``
-      - 4
-      - CEC version according to the HDMI 1.3a standard.
-    * .. _`CEC-OP-CEC-VERSION-1-4B`:
-
-      - ``CEC_OP_CEC_VERSION_1_4B``
-      - 5
-      - CEC version according to the HDMI 1.4b standard.
-    * .. _`CEC-OP-CEC-VERSION-2-0`:
-
-      - ``CEC_OP_CEC_VERSION_2_0``
-      - 6
-      - CEC version according to the HDMI 2.0 standard.
-
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. _cec-prim-dev-types:
-
-.. flat-table:: CEC Primary Device Types
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * .. _`CEC-OP-PRIM-DEVTYPE-TV`:
-
-      - ``CEC_OP_PRIM_DEVTYPE_TV``
-      - 0
-      - Use for a TV.
-    * .. _`CEC-OP-PRIM-DEVTYPE-RECORD`:
-
-      - ``CEC_OP_PRIM_DEVTYPE_RECORD``
-      - 1
-      - Use for a recording device.
-    * .. _`CEC-OP-PRIM-DEVTYPE-TUNER`:
-
-      - ``CEC_OP_PRIM_DEVTYPE_TUNER``
-      - 3
-      - Use for a device with a tuner.
-    * .. _`CEC-OP-PRIM-DEVTYPE-PLAYBACK`:
-
-      - ``CEC_OP_PRIM_DEVTYPE_PLAYBACK``
-      - 4
-      - Use for a playback device.
-    * .. _`CEC-OP-PRIM-DEVTYPE-AUDIOSYSTEM`:
-
-      - ``CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM``
-      - 5
-      - Use for an audio system (e.g. an audio/video receiver).
-    * .. _`CEC-OP-PRIM-DEVTYPE-SWITCH`:
-
-      - ``CEC_OP_PRIM_DEVTYPE_SWITCH``
-      - 6
-      - Use for a CEC switch.
-    * .. _`CEC-OP-PRIM-DEVTYPE-VIDEOPROC`:
-
-      - ``CEC_OP_PRIM_DEVTYPE_VIDEOPROC``
-      - 7
-      - Use for a video processor device.
-
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. _cec-log-addr-types:
-
-.. flat-table:: CEC Logical Address Types
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 16
-
-    * .. _`CEC-LOG-ADDR-TYPE-TV`:
-
-      - ``CEC_LOG_ADDR_TYPE_TV``
-      - 0
-      - Use for a TV.
-    * .. _`CEC-LOG-ADDR-TYPE-RECORD`:
-
-      - ``CEC_LOG_ADDR_TYPE_RECORD``
-      - 1
-      - Use for a recording device.
-    * .. _`CEC-LOG-ADDR-TYPE-TUNER`:
-
-      - ``CEC_LOG_ADDR_TYPE_TUNER``
-      - 2
-      - Use for a tuner device.
-    * .. _`CEC-LOG-ADDR-TYPE-PLAYBACK`:
-
-      - ``CEC_LOG_ADDR_TYPE_PLAYBACK``
-      - 3
-      - Use for a playback device.
-    * .. _`CEC-LOG-ADDR-TYPE-AUDIOSYSTEM`:
-
-      - ``CEC_LOG_ADDR_TYPE_AUDIOSYSTEM``
-      - 4
-      - Use for an audio system device.
-    * .. _`CEC-LOG-ADDR-TYPE-SPECIFIC`:
-
-      - ``CEC_LOG_ADDR_TYPE_SPECIFIC``
-      - 5
-      - Use for a second TV or for a video processor device.
-    * .. _`CEC-LOG-ADDR-TYPE-UNREGISTERED`:
-
-      - ``CEC_LOG_ADDR_TYPE_UNREGISTERED``
-      - 6
-      - Use this if you just want to remain unregistered. Used for pure
-	CEC switches or CDC-only devices (CDC: Capability Discovery and
-	Control).
-
-
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. _cec-all-dev-types-flags:
-
-.. flat-table:: CEC All Device Types Flags
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * .. _`CEC-OP-ALL-DEVTYPE-TV`:
-
-      - ``CEC_OP_ALL_DEVTYPE_TV``
-      - 0x80
-      - This supports the TV type.
-    * .. _`CEC-OP-ALL-DEVTYPE-RECORD`:
-
-      - ``CEC_OP_ALL_DEVTYPE_RECORD``
-      - 0x40
-      - This supports the Recording type.
-    * .. _`CEC-OP-ALL-DEVTYPE-TUNER`:
-
-      - ``CEC_OP_ALL_DEVTYPE_TUNER``
-      - 0x20
-      - This supports the Tuner type.
-    * .. _`CEC-OP-ALL-DEVTYPE-PLAYBACK`:
-
-      - ``CEC_OP_ALL_DEVTYPE_PLAYBACK``
-      - 0x10
-      - This supports the Playback type.
-    * .. _`CEC-OP-ALL-DEVTYPE-AUDIOSYSTEM`:
-
-      - ``CEC_OP_ALL_DEVTYPE_AUDIOSYSTEM``
-      - 0x08
-      - This supports the Audio System type.
-    * .. _`CEC-OP-ALL-DEVTYPE-SWITCH`:
-
-      - ``CEC_OP_ALL_DEVTYPE_SWITCH``
-      - 0x04
-      - This supports the CEC Switch or Video Processing type.
-
-
-
-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.
-
-The :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>` can return the following
-error codes:
-
-ENOTTY
-    The ``CEC_CAP_LOG_ADDRS`` capability wasn't set, so this ioctl is not supported.
-
-EBUSY
-    The CEC adapter is currently configuring itself, or it is already configured and
-    ``num_log_addrs`` is non-zero, or another filehandle is in exclusive follower or
-    initiator mode, or the filehandle is in mode ``CEC_MODE_NO_INITIATOR``.
-
-EINVAL
-    The contents of struct :c:type:`cec_log_addrs` is invalid.
diff --git a/Documentation/media/uapi/cec/cec-ioc-adap-g-phys-addr.rst b/Documentation/media/uapi/cec/cec-ioc-adap-g-phys-addr.rst
deleted file mode 100644
index 693be2f9bf2e..000000000000
--- a/Documentation/media/uapi/cec/cec-ioc-adap-g-phys-addr.rst
+++ /dev/null
@@ -1,100 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _CEC_ADAP_PHYS_ADDR:
-.. _CEC_ADAP_G_PHYS_ADDR:
-.. _CEC_ADAP_S_PHYS_ADDR:
-
-****************************************************
-ioctls CEC_ADAP_G_PHYS_ADDR and CEC_ADAP_S_PHYS_ADDR
-****************************************************
-
-Name
-====
-
-CEC_ADAP_G_PHYS_ADDR, CEC_ADAP_S_PHYS_ADDR - Get or set the physical address
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, CEC_ADAP_G_PHYS_ADDR, __u16 *argp )
-    :name: CEC_ADAP_G_PHYS_ADDR
-
-.. c:function:: int ioctl( int fd, CEC_ADAP_S_PHYS_ADDR, __u16 *argp )
-    :name: CEC_ADAP_S_PHYS_ADDR
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :c:func:`open() <cec-open>`.
-
-``argp``
-    Pointer to the CEC address.
-
-Description
-===========
-
-To query the current physical address applications call
-:ref:`ioctl CEC_ADAP_G_PHYS_ADDR <CEC_ADAP_G_PHYS_ADDR>` with a pointer to a __u16 where the
-driver stores the physical address.
-
-To set a new physical address applications store the physical address in
-a __u16 and call :ref:`ioctl CEC_ADAP_S_PHYS_ADDR <CEC_ADAP_S_PHYS_ADDR>` with a pointer to
-this integer. The :ref:`ioctl CEC_ADAP_S_PHYS_ADDR <CEC_ADAP_S_PHYS_ADDR>` is only available if
-``CEC_CAP_PHYS_ADDR`` is set (the ``ENOTTY`` error code will be returned
-otherwise). The :ref:`ioctl CEC_ADAP_S_PHYS_ADDR <CEC_ADAP_S_PHYS_ADDR>` can only be called
-by a file descriptor in initiator mode (see :ref:`CEC_S_MODE`), if not
-the ``EBUSY`` error code will be returned.
-
-To clear an existing physical address use ``CEC_PHYS_ADDR_INVALID``.
-The adapter will go to the unconfigured state.
-
-If logical address types have been defined (see :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`),
-then this ioctl will block until all
-requested logical addresses have been claimed. If the file descriptor is in non-blocking mode
-then it will not wait for the logical addresses to be claimed, instead it just returns 0.
-
-A :ref:`CEC_EVENT_STATE_CHANGE <CEC-EVENT-STATE-CHANGE>` event is sent when the physical address
-changes.
-
-The physical address is a 16-bit number where each group of 4 bits
-represent a digit of the physical address a.b.c.d where the most
-significant 4 bits represent 'a'. The CEC root device (usually the TV)
-has address 0.0.0.0. Every device that is hooked up to an input of the
-TV has address a.0.0.0 (where 'a' is ≥ 1), devices hooked up to those in
-turn have addresses a.b.0.0, etc. So a topology of up to 5 devices deep
-is supported. The physical address a device shall use is stored in the
-EDID of the sink.
-
-For example, the EDID for each HDMI input of the TV will have a
-different physical address of the form a.0.0.0 that the sources will
-read out and use as their physical address.
-
-
-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.
-
-The :ref:`ioctl CEC_ADAP_S_PHYS_ADDR <CEC_ADAP_S_PHYS_ADDR>` can return the following
-error codes:
-
-ENOTTY
-    The ``CEC_CAP_PHYS_ADDR`` capability wasn't set, so this ioctl is not supported.
-
-EBUSY
-    Another filehandle is in exclusive follower or initiator mode, or the filehandle
-    is in mode ``CEC_MODE_NO_INITIATOR``.
-
-EINVAL
-    The physical address is malformed.
diff --git a/Documentation/media/uapi/cec/cec-ioc-dqevent.rst b/Documentation/media/uapi/cec/cec-ioc-dqevent.rst
deleted file mode 100644
index d16b226b1bef..000000000000
--- a/Documentation/media/uapi/cec/cec-ioc-dqevent.rst
+++ /dev/null
@@ -1,257 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _CEC_DQEVENT:
-
-*****************
-ioctl CEC_DQEVENT
-*****************
-
-Name
-====
-
-CEC_DQEVENT - Dequeue a CEC event
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, CEC_DQEVENT, struct cec_event *argp )
-    :name: CEC_DQEVENT
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :c:func:`open() <cec-open>`.
-
-``argp``
-
-
-Description
-===========
-
-CEC devices can send asynchronous events. These can be retrieved by
-calling :c:func:`CEC_DQEVENT`. If the file descriptor is in
-non-blocking mode and no event is pending, then it will return -1 and
-set errno to the ``EAGAIN`` error code.
-
-The internal event queues are per-filehandle and per-event type. If
-there is no more room in a queue then the last event is overwritten with
-the new one. This means that intermediate results can be thrown away but
-that the latest event is always available. This also means that is it
-possible to read two successive events that have the same value (e.g.
-two :ref:`CEC_EVENT_STATE_CHANGE <CEC-EVENT-STATE-CHANGE>` events with
-the same state). In that case the intermediate state changes were lost but
-it is guaranteed that the state did change in between the two events.
-
-.. tabularcolumns:: |p{1.2cm}|p{2.9cm}|p{13.4cm}|
-
-.. c:type:: cec_event_state_change
-
-.. flat-table:: struct cec_event_state_change
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 8
-
-    * - __u16
-      - ``phys_addr``
-      - The current physical address. This is ``CEC_PHYS_ADDR_INVALID`` if no
-        valid physical address is set.
-    * - __u16
-      - ``log_addr_mask``
-      - The current set of claimed logical addresses. This is 0 if no logical
-        addresses are claimed or if ``phys_addr`` is ``CEC_PHYS_ADDR_INVALID``.
-	If bit 15 is set (``1 << CEC_LOG_ADDR_UNREGISTERED``) then this device
-	has the unregistered logical address. In that case all other bits are 0.
-    * - __u16
-      - ``have_conn_info``
-      - If non-zero, then HDMI connector information is available.
-        This field is only valid if ``CEC_CAP_CONNECTOR_INFO`` is set. If that
-        capability is set and ``have_conn_info`` is zero, then that indicates
-        that the HDMI connector device is not instantiated, either because
-        the HDMI driver is still configuring the device or because the HDMI
-        device was unbound.
-
-
-.. c:type:: cec_event_lost_msgs
-
-.. tabularcolumns:: |p{1.0cm}|p{2.0cm}|p{14.5cm}|
-
-.. flat-table:: struct cec_event_lost_msgs
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 16
-
-    * - __u32
-      - ``lost_msgs``
-      - Set to the number of lost messages since the filehandle was opened
-	or since the last time this event was dequeued for this
-	filehandle. The messages lost are the oldest messages. So when a
-	new message arrives and there is no more room, then the oldest
-	message is discarded to make room for the new one. The internal
-	size of the message queue guarantees that all messages received in
-	the last two seconds will be stored. Since messages should be
-	replied to within a second according to the CEC specification,
-	this is more than enough.
-
-
-.. tabularcolumns:: |p{1.0cm}|p{4.4cm}|p{2.5cm}|p{9.6cm}|
-
-.. c:type:: cec_event
-
-.. flat-table:: struct cec_event
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 8
-
-    * - __u64
-      - ``ts``
-      - Timestamp of the event in ns.
-
-	The timestamp has been taken from the ``CLOCK_MONOTONIC`` clock.
-
-	To access the same clock from userspace use :c:func:`clock_gettime`.
-    * - __u32
-      - ``event``
-      - The CEC event type, see :ref:`cec-events`.
-    * - __u32
-      - ``flags``
-      - Event flags, see :ref:`cec-event-flags`.
-    * - union {
-      - (anonymous)
-    * - struct cec_event_state_change
-      - ``state_change``
-      - The new adapter state as sent by the :ref:`CEC_EVENT_STATE_CHANGE <CEC-EVENT-STATE-CHANGE>`
-	event.
-    * - struct cec_event_lost_msgs
-      - ``lost_msgs``
-      - The number of lost messages as sent by the :ref:`CEC_EVENT_LOST_MSGS <CEC-EVENT-LOST-MSGS>`
-	event.
-    * - }
-      -
-
-
-.. tabularcolumns:: |p{5.6cm}|p{0.9cm}|p{11.0cm}|
-
-.. _cec-events:
-
-.. flat-table:: CEC Events Types
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 16
-
-    * .. _`CEC-EVENT-STATE-CHANGE`:
-
-      - ``CEC_EVENT_STATE_CHANGE``
-      - 1
-      - Generated when the CEC Adapter's state changes. When open() is
-	called an initial event will be generated for that filehandle with
-	the CEC Adapter's state at that time.
-    * .. _`CEC-EVENT-LOST-MSGS`:
-
-      - ``CEC_EVENT_LOST_MSGS``
-      - 2
-      - Generated if one or more CEC messages were lost because the
-	application didn't dequeue CEC messages fast enough.
-    * .. _`CEC-EVENT-PIN-CEC-LOW`:
-
-      - ``CEC_EVENT_PIN_CEC_LOW``
-      - 3
-      - Generated if the CEC pin goes from a high voltage to a low voltage.
-        Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN``
-	capability set.
-    * .. _`CEC-EVENT-PIN-CEC-HIGH`:
-
-      - ``CEC_EVENT_PIN_CEC_HIGH``
-      - 4
-      - Generated if the CEC pin goes from a low voltage to a high voltage.
-        Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN``
-	capability set.
-    * .. _`CEC-EVENT-PIN-HPD-LOW`:
-
-      - ``CEC_EVENT_PIN_HPD_LOW``
-      - 5
-      - Generated if the HPD pin goes from a high voltage to a low voltage.
-	Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN``
-	capability set. When open() is called, the HPD pin can be read and
-	if the HPD is low, then an initial event will be generated for that
-	filehandle.
-    * .. _`CEC-EVENT-PIN-HPD-HIGH`:
-
-      - ``CEC_EVENT_PIN_HPD_HIGH``
-      - 6
-      - Generated if the HPD pin goes from a low voltage to a high voltage.
-	Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN``
-	capability set. When open() is called, the HPD pin can be read and
-	if the HPD is high, then an initial event will be generated for that
-	filehandle.
-    * .. _`CEC-EVENT-PIN-5V-LOW`:
-
-      - ``CEC_EVENT_PIN_5V_LOW``
-      - 6
-      - Generated if the 5V pin goes from a high voltage to a low voltage.
-	Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN``
-	capability set. When open() is called, the 5V pin can be read and
-	if the 5V is low, then an initial event will be generated for that
-	filehandle.
-    * .. _`CEC-EVENT-PIN-5V-HIGH`:
-
-      - ``CEC_EVENT_PIN_5V_HIGH``
-      - 7
-      - Generated if the 5V pin goes from a low voltage to a high voltage.
-	Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN``
-	capability set. When open() is called, the 5V pin can be read and
-	if the 5V is high, then an initial event will be generated for that
-	filehandle.
-
-
-.. tabularcolumns:: |p{6.0cm}|p{0.6cm}|p{10.9cm}|
-
-.. _cec-event-flags:
-
-.. flat-table:: CEC Event Flags
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 8
-
-    * .. _`CEC-EVENT-FL-INITIAL-STATE`:
-
-      - ``CEC_EVENT_FL_INITIAL_STATE``
-      - 1
-      - Set for the initial events that are generated when the device is
-	opened. See the table above for which events do this. This allows
-	applications to learn the initial state of the CEC adapter at
-	open() time.
-    * .. _`CEC-EVENT-FL-DROPPED-EVENTS`:
-
-      - ``CEC_EVENT_FL_DROPPED_EVENTS``
-      - 2
-      - Set if one or more events of the given event type have been dropped.
-        This is an indication that the application cannot keep up.
-
-
-
-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.
-
-The :ref:`ioctl CEC_DQEVENT <CEC_DQEVENT>` can return the following
-error codes:
-
-EAGAIN
-    This is returned when the filehandle is in non-blocking mode and there
-    are no pending events.
-
-ERESTARTSYS
-    An interrupt (e.g. Ctrl-C) arrived while in blocking mode waiting for
-    events to arrive.
diff --git a/Documentation/media/uapi/cec/cec-ioc-g-mode.rst b/Documentation/media/uapi/cec/cec-ioc-g-mode.rst
deleted file mode 100644
index 2535b77e3459..000000000000
--- a/Documentation/media/uapi/cec/cec-ioc-g-mode.rst
+++ /dev/null
@@ -1,301 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _CEC_MODE:
-.. _CEC_G_MODE:
-.. _CEC_S_MODE:
-
-********************************
-ioctls CEC_G_MODE and CEC_S_MODE
-********************************
-
-CEC_G_MODE, CEC_S_MODE - Get or set exclusive use of the CEC adapter
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, CEC_G_MODE, __u32 *argp )
-   :name: CEC_G_MODE
-
-.. c:function:: int ioctl( int fd, CEC_S_MODE, __u32 *argp )
-   :name: CEC_S_MODE
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :c:func:`open() <cec-open>`.
-
-``argp``
-    Pointer to CEC mode.
-
-Description
-===========
-
-By default any filehandle can use :ref:`CEC_TRANSMIT`, but in order to prevent
-applications from stepping on each others toes it must be possible to
-obtain exclusive access to the CEC adapter. This ioctl sets the
-filehandle to initiator and/or follower mode which can be exclusive
-depending on the chosen mode. The initiator is the filehandle that is
-used to initiate messages, i.e. it commands other CEC devices. The
-follower is the filehandle that receives messages sent to the CEC
-adapter and processes them. The same filehandle can be both initiator
-and follower, or this role can be taken by two different filehandles.
-
-When a CEC message is received, then the CEC framework will decide how
-it will be processed. If the message is a reply to an earlier
-transmitted message, then the reply is sent back to the filehandle that
-is waiting for it. In addition the CEC framework will process it.
-
-If the message is not a reply, then the CEC framework will process it
-first. If there is no follower, then the message is just discarded and a
-feature abort is sent back to the initiator if the framework couldn't
-process it. If there is a follower, then the message is passed on to the
-follower who will use :ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>` to dequeue
-the new message. The framework expects the follower to make the right
-decisions.
-
-The CEC framework will process core messages unless requested otherwise
-by the follower. The follower can enable the passthrough mode. In that
-case, the CEC framework will pass on most core messages without
-processing them and the follower will have to implement those messages.
-There are some messages that the core will always process, regardless of
-the passthrough mode. See :ref:`cec-core-processing` for details.
-
-If there is no initiator, then any CEC filehandle can use
-:ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>`. If there is an exclusive
-initiator then only that initiator can call
-:ref:`CEC_TRANSMIT`. The follower can of course
-always call :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>`.
-
-Available initiator modes are:
-
-.. tabularcolumns:: |p{5.6cm}|p{0.9cm}|p{11.0cm}|
-
-.. _cec-mode-initiator_e:
-
-.. flat-table:: Initiator Modes
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 16
-
-    * .. _`CEC-MODE-NO-INITIATOR`:
-
-      - ``CEC_MODE_NO_INITIATOR``
-      - 0x0
-      - This is not an initiator, i.e. it cannot transmit CEC messages or
-	make any other changes to the CEC adapter.
-    * .. _`CEC-MODE-INITIATOR`:
-
-      - ``CEC_MODE_INITIATOR``
-      - 0x1
-      - This is an initiator (the default when the device is opened) and
-	it can transmit CEC messages and make changes to the CEC adapter,
-	unless there is an exclusive initiator.
-    * .. _`CEC-MODE-EXCL-INITIATOR`:
-
-      - ``CEC_MODE_EXCL_INITIATOR``
-      - 0x2
-      - This is an exclusive initiator and this file descriptor is the
-	only one that can transmit CEC messages and make changes to the
-	CEC adapter. If someone else is already the exclusive initiator
-	then an attempt to become one will return the ``EBUSY`` error code
-	error.
-
-
-Available follower modes are:
-
-.. tabularcolumns:: |p{6.6cm}|p{0.9cm}|p{10.0cm}|
-
-.. _cec-mode-follower_e:
-
-.. cssclass:: longtable
-
-.. flat-table:: Follower Modes
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 16
-
-    * .. _`CEC-MODE-NO-FOLLOWER`:
-
-      - ``CEC_MODE_NO_FOLLOWER``
-      - 0x00
-      - This is not a follower (the default when the device is opened).
-    * .. _`CEC-MODE-FOLLOWER`:
-
-      - ``CEC_MODE_FOLLOWER``
-      - 0x10
-      - This is a follower and it will receive CEC messages unless there
-	is an exclusive follower. You cannot become a follower if
-	:ref:`CEC_CAP_TRANSMIT <CEC-CAP-TRANSMIT>` is not set or if :ref:`CEC_MODE_NO_INITIATOR <CEC-MODE-NO-INITIATOR>`
-	was specified, the ``EINVAL`` error code is returned in that case.
-    * .. _`CEC-MODE-EXCL-FOLLOWER`:
-
-      - ``CEC_MODE_EXCL_FOLLOWER``
-      - 0x20
-      - This is an exclusive follower and only this file descriptor will
-	receive CEC messages for processing. If someone else is already
-	the exclusive follower then an attempt to become one will return
-	the ``EBUSY`` error code. You cannot become a follower if
-	:ref:`CEC_CAP_TRANSMIT <CEC-CAP-TRANSMIT>` is not set or if :ref:`CEC_MODE_NO_INITIATOR <CEC-MODE-NO-INITIATOR>`
-	was specified, the ``EINVAL`` error code is returned in that case.
-    * .. _`CEC-MODE-EXCL-FOLLOWER-PASSTHRU`:
-
-      - ``CEC_MODE_EXCL_FOLLOWER_PASSTHRU``
-      - 0x30
-      - This is an exclusive follower and only this file descriptor will
-	receive CEC messages for processing. In addition it will put the
-	CEC device into passthrough mode, allowing the exclusive follower
-	to handle most core messages instead of relying on the CEC
-	framework for that. If someone else is already the exclusive
-	follower then an attempt to become one will return the ``EBUSY`` error
-	code. You cannot become a follower if :ref:`CEC_CAP_TRANSMIT <CEC-CAP-TRANSMIT>`
-	is not set or if :ref:`CEC_MODE_NO_INITIATOR <CEC-MODE-NO-INITIATOR>` was specified,
-	the ``EINVAL`` error code is returned in that case.
-    * .. _`CEC-MODE-MONITOR-PIN`:
-
-      - ``CEC_MODE_MONITOR_PIN``
-      - 0xd0
-      - Put the file descriptor into pin monitoring mode. Can only be used in
-	combination with :ref:`CEC_MODE_NO_INITIATOR <CEC-MODE-NO-INITIATOR>`,
-	otherwise the ``EINVAL`` error code will be returned.
-	This mode requires that the :ref:`CEC_CAP_MONITOR_PIN <CEC-CAP-MONITOR-PIN>`
-	capability is set, otherwise the ``EINVAL`` error code is returned.
-	While in pin monitoring mode this file descriptor can receive the
-	``CEC_EVENT_PIN_CEC_LOW`` and ``CEC_EVENT_PIN_CEC_HIGH`` events to see the
-	low-level CEC pin transitions. This is very useful for debugging.
-	This mode is only allowed if the process has the ``CAP_NET_ADMIN``
-	capability. If that is not set, then the ``EPERM`` error code is returned.
-    * .. _`CEC-MODE-MONITOR`:
-
-      - ``CEC_MODE_MONITOR``
-      - 0xe0
-      - Put the file descriptor into monitor mode. Can only be used in
-	combination with :ref:`CEC_MODE_NO_INITIATOR <CEC-MODE-NO-INITIATOR>`,
-	otherwise the ``EINVAL`` error code will be returned.
-	In monitor mode all messages this CEC
-	device transmits and all messages it receives (both broadcast
-	messages and directed messages for one its logical addresses) will
-	be reported. This is very useful for debugging. This is only
-	allowed if the process has the ``CAP_NET_ADMIN`` capability. If
-	that is not set, then the ``EPERM`` error code is returned.
-    * .. _`CEC-MODE-MONITOR-ALL`:
-
-      - ``CEC_MODE_MONITOR_ALL``
-      - 0xf0
-      - Put the file descriptor into 'monitor all' mode. Can only be used
-	in combination with :ref:`CEC_MODE_NO_INITIATOR <CEC-MODE-NO-INITIATOR>`, otherwise
-	the ``EINVAL`` error code will be returned. In 'monitor all' mode all messages
-	this CEC device transmits and all messages it receives, including
-	directed messages for other CEC devices will be reported. This is
-	very useful for debugging, but not all devices support this. This
-	mode requires that the :ref:`CEC_CAP_MONITOR_ALL <CEC-CAP-MONITOR-ALL>` capability is set,
-	otherwise the ``EINVAL`` error code is returned. This is only allowed if
-	the process has the ``CAP_NET_ADMIN`` capability. If that is not
-	set, then the ``EPERM`` error code is returned.
-
-
-Core message processing details:
-
-.. tabularcolumns:: |p{6.6cm}|p{10.9cm}|
-
-.. _cec-core-processing:
-
-.. flat-table:: Core Message Processing
-    :header-rows:  0
-    :stub-columns: 0
-    :widths: 1 8
-
-    * .. _`CEC-MSG-GET-CEC-VERSION`:
-
-      - ``CEC_MSG_GET_CEC_VERSION``
-      - The core will return the CEC version that was set with
-	:ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`,
-	except when in passthrough mode. In passthrough mode the core
-	does nothing and this message has to be handled by a follower
-	instead.
-    * .. _`CEC-MSG-GIVE-DEVICE-VENDOR-ID`:
-
-      - ``CEC_MSG_GIVE_DEVICE_VENDOR_ID``
-      - The core will return the vendor ID that was set with
-	:ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`,
-	except when in passthrough mode. In passthrough mode the core
-	does nothing and this message has to be handled by a follower
-	instead.
-    * .. _`CEC-MSG-ABORT`:
-
-      - ``CEC_MSG_ABORT``
-      - The core will return a Feature Abort message with reason
-        'Feature Refused' as per the specification, except when in
-	passthrough mode. In passthrough mode the core does nothing
-	and this message has to be handled by a follower instead.
-    * .. _`CEC-MSG-GIVE-PHYSICAL-ADDR`:
-
-      - ``CEC_MSG_GIVE_PHYSICAL_ADDR``
-      - The core will report the current physical address, except when
-        in passthrough mode. In passthrough mode the core does nothing
-	and this message has to be handled by a follower instead.
-    * .. _`CEC-MSG-GIVE-OSD-NAME`:
-
-      - ``CEC_MSG_GIVE_OSD_NAME``
-      - The core will report the current OSD name that was set with
-	:ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`,
-	except when in passthrough mode. In passthrough mode the core
-	does nothing and this message has to be handled by a follower
-	instead.
-    * .. _`CEC-MSG-GIVE-FEATURES`:
-
-      - ``CEC_MSG_GIVE_FEATURES``
-      - The core will do nothing if the CEC version is older than 2.0,
-        otherwise it will report the current features that were set with
-	:ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`,
-	except when in passthrough mode. In passthrough mode the core
-	does nothing (for any CEC version) and this message has to be handled
-	by a follower instead.
-    * .. _`CEC-MSG-USER-CONTROL-PRESSED`:
-
-      - ``CEC_MSG_USER_CONTROL_PRESSED``
-      - If :ref:`CEC_CAP_RC <CEC-CAP-RC>` is set and if
-        :ref:`CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU <CEC-LOG-ADDRS-FL-ALLOW-RC-PASSTHRU>`
-	is set, then generate a remote control key
-	press. This message is always passed on to the follower(s).
-    * .. _`CEC-MSG-USER-CONTROL-RELEASED`:
-
-      - ``CEC_MSG_USER_CONTROL_RELEASED``
-      - If :ref:`CEC_CAP_RC <CEC-CAP-RC>` is set and if
-        :ref:`CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU <CEC-LOG-ADDRS-FL-ALLOW-RC-PASSTHRU>`
-        is set, then generate a remote control key
-	release. This message is always passed on to the follower(s).
-    * .. _`CEC-MSG-REPORT-PHYSICAL-ADDR`:
-
-      - ``CEC_MSG_REPORT_PHYSICAL_ADDR``
-      - The CEC framework will make note of the reported physical address
-	and then just pass the message on to the follower(s).
-
-
-
-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.
-
-The :ref:`ioctl CEC_S_MODE <CEC_S_MODE>` can return the following
-error codes:
-
-EINVAL
-    The requested mode is invalid.
-
-EPERM
-    Monitor mode is requested, but the process does have the ``CAP_NET_ADMIN``
-    capability.
-
-EBUSY
-    Someone else is already an exclusive follower or initiator.
diff --git a/Documentation/media/uapi/cec/cec-ioc-receive.rst b/Documentation/media/uapi/cec/cec-ioc-receive.rst
deleted file mode 100644
index 4137903d672e..000000000000
--- a/Documentation/media/uapi/cec/cec-ioc-receive.rst
+++ /dev/null
@@ -1,391 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _CEC_TRANSMIT:
-.. _CEC_RECEIVE:
-
-***********************************
-ioctls CEC_RECEIVE and CEC_TRANSMIT
-***********************************
-
-Name
-====
-
-CEC_RECEIVE, CEC_TRANSMIT - Receive or transmit a CEC message
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, CEC_RECEIVE, struct cec_msg \*argp )
-    :name: CEC_RECEIVE
-
-.. c:function:: int ioctl( int fd, CEC_TRANSMIT, struct cec_msg \*argp )
-    :name: CEC_TRANSMIT
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :c:func:`open() <cec-open>`.
-
-``argp``
-    Pointer to struct cec_msg.
-
-Description
-===========
-
-To receive a CEC message the application has to fill in the
-``timeout`` field of struct :c:type:`cec_msg` and pass it to
-:ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>`.
-If the file descriptor is in non-blocking mode and there are no received
-messages pending, then it will return -1 and set errno to the ``EAGAIN``
-error code. If the file descriptor is in blocking mode and ``timeout``
-is non-zero and no message arrived within ``timeout`` milliseconds, then
-it will return -1 and set errno to the ``ETIMEDOUT`` error code.
-
-A received message can be:
-
-1. a message received from another CEC device (the ``sequence`` field will
-   be 0).
-2. the result of an earlier non-blocking transmit (the ``sequence`` field will
-   be non-zero).
-
-To send a CEC message the application has to fill in the struct
-:c:type:`cec_msg` and pass it to :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>`.
-The :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` is only available if
-``CEC_CAP_TRANSMIT`` is set. If there is no more room in the transmit
-queue, then it will return -1 and set errno to the ``EBUSY`` error code.
-The transmit queue has enough room for 18 messages (about 1 second worth
-of 2-byte messages). Note that the CEC kernel framework will also reply
-to core messages (see :ref:`cec-core-processing`), so it is not a good
-idea to fully fill up the transmit queue.
-
-If the file descriptor is in non-blocking mode then the transmit will
-return 0 and the result of the transmit will be available via
-:ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>` once the transmit has finished
-(including waiting for a reply, if requested).
-
-The ``sequence`` field is filled in for every transmit and this can be
-checked against the received messages to find the corresponding transmit
-result.
-
-Normally calling :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` when the physical
-address is invalid (due to e.g. a disconnect) will return ``ENONET``.
-
-However, the CEC specification allows sending messages from 'Unregistered' to
-'TV' when the physical address is invalid since some TVs pull the hotplug detect
-pin of the HDMI connector low when they go into standby, or when switching to
-another input.
-
-When the hotplug detect pin goes low the EDID disappears, and thus the
-physical address, but the cable is still connected and CEC still works.
-In order to detect/wake up the device it is allowed to send poll and 'Image/Text
-View On' messages from initiator 0xf ('Unregistered') to destination 0 ('TV').
-
-.. tabularcolumns:: |p{1.0cm}|p{3.5cm}|p{13.0cm}|
-
-.. c:type:: cec_msg
-
-.. cssclass:: longtable
-
-.. flat-table:: struct cec_msg
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 16
-
-    * - __u64
-      - ``tx_ts``
-      - Timestamp in ns of when the last byte of the message was transmitted.
-	The timestamp has been taken from the ``CLOCK_MONOTONIC`` clock. To access
-	the same clock from userspace use :c:func:`clock_gettime`.
-    * - __u64
-      - ``rx_ts``
-      - Timestamp in ns of when the last byte of the message was received.
-	The timestamp has been taken from the ``CLOCK_MONOTONIC`` clock. To access
-	the same clock from userspace use :c:func:`clock_gettime`.
-    * - __u32
-      - ``len``
-      - The length of the message. For :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` this is filled in
-	by the application. The driver will fill this in for
-	:ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>`. For :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` it will be
-	filled in by the driver with the length of the reply message if ``reply`` was set.
-    * - __u32
-      - ``timeout``
-      - The timeout in milliseconds. This is the time the device will wait
-	for a message to be received before timing out. If it is set to 0,
-	then it will wait indefinitely when it is called by :ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>`.
-	If it is 0 and it is called by :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>`,
-	then it will be replaced by 1000 if the ``reply`` is non-zero or
-	ignored if ``reply`` is 0.
-    * - __u32
-      - ``sequence``
-      - A non-zero sequence number is automatically assigned by the CEC framework
-	for all transmitted messages. It is used by the CEC framework when it queues
-	the transmit result (when transmit was called in non-blocking mode). This
-	allows the application to associate the received message with the original
-	transmit.
-    * - __u32
-      - ``flags``
-      - Flags. See :ref:`cec-msg-flags` for a list of available flags.
-    * - __u8
-      - ``tx_status``
-      - The status bits of the transmitted message. See
-	:ref:`cec-tx-status` for the possible status values. It is 0 if
-	this message was received, not transmitted.
-    * - __u8
-      - ``msg[16]``
-      - The message payload. For :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` this is filled in by the
-	application. The driver will fill this in for :ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>`.
-	For :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` it will be filled in by the driver with
-	the payload of the reply message if ``timeout`` was set.
-    * - __u8
-      - ``reply``
-      - Wait until this message is replied. If ``reply`` is 0 and the
-	``timeout`` is 0, then don't wait for a reply but return after
-	transmitting the message. Ignored by :ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>`.
-	The case where ``reply`` is 0 (this is the opcode for the Feature Abort
-	message) and ``timeout`` is non-zero is specifically allowed to make it
-	possible to send a message and wait up to ``timeout`` milliseconds for a
-	Feature Abort reply. In this case ``rx_status`` will either be set
-	to :ref:`CEC_RX_STATUS_TIMEOUT <CEC-RX-STATUS-TIMEOUT>` or
-	:ref:`CEC_RX_STATUS_FEATURE_ABORT <CEC-RX-STATUS-FEATURE-ABORT>`.
-
-	If the transmitter message is ``CEC_MSG_INITIATE_ARC`` then the ``reply``
-	values ``CEC_MSG_REPORT_ARC_INITIATED`` and ``CEC_MSG_REPORT_ARC_TERMINATED``
-	are processed differently: either value will match both possible replies.
-	The reason is that the ``CEC_MSG_INITIATE_ARC`` message is the only CEC
-	message that has two possible replies other than Feature Abort. The
-	``reply`` field will be updated with the actual reply so that it is
-	synchronized with the contents of the received message.
-    * - __u8
-      - ``rx_status``
-      - The status bits of the received message. See
-	:ref:`cec-rx-status` for the possible status values. It is 0 if
-	this message was transmitted, not received, unless this is the
-	reply to a transmitted message. In that case both ``rx_status``
-	and ``tx_status`` are set.
-    * - __u8
-      - ``tx_status``
-      - The status bits of the transmitted message. See
-	:ref:`cec-tx-status` for the possible status values. It is 0 if
-	this message was received, not transmitted.
-    * - __u8
-      - ``tx_arb_lost_cnt``
-      - A counter of the number of transmit attempts that resulted in the
-	Arbitration Lost error. This is only set if the hardware supports
-	this, otherwise it is always 0. This counter is only valid if the
-	:ref:`CEC_TX_STATUS_ARB_LOST <CEC-TX-STATUS-ARB-LOST>` status bit is set.
-    * - __u8
-      - ``tx_nack_cnt``
-      - A counter of the number of transmit attempts that resulted in the
-	Not Acknowledged error. This is only set if the hardware supports
-	this, otherwise it is always 0. This counter is only valid if the
-	:ref:`CEC_TX_STATUS_NACK <CEC-TX-STATUS-NACK>` status bit is set.
-    * - __u8
-      - ``tx_low_drive_cnt``
-      - A counter of the number of transmit attempts that resulted in the
-	Arbitration Lost error. This is only set if the hardware supports
-	this, otherwise it is always 0. This counter is only valid if the
-	:ref:`CEC_TX_STATUS_LOW_DRIVE <CEC-TX-STATUS-LOW-DRIVE>` status bit is set.
-    * - __u8
-      - ``tx_error_cnt``
-      - A counter of the number of transmit errors other than Arbitration
-	Lost or Not Acknowledged. This is only set if the hardware
-	supports this, otherwise it is always 0. This counter is only
-	valid if the :ref:`CEC_TX_STATUS_ERROR <CEC-TX-STATUS-ERROR>` status bit is set.
-
-
-.. tabularcolumns:: |p{6.2cm}|p{1.0cm}|p{10.3cm}|
-
-.. _cec-msg-flags:
-
-.. flat-table:: Flags for struct cec_msg
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * .. _`CEC-MSG-FL-REPLY-TO-FOLLOWERS`:
-
-      - ``CEC_MSG_FL_REPLY_TO_FOLLOWERS``
-      - 1
-      - If a CEC transmit expects a reply, then by default that reply is only sent to
-	the filehandle that called :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>`. If this
-	flag is set, then the reply is also sent to all followers, if any. If the
-	filehandle that called :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` is also a
-	follower, then that filehandle will receive the reply twice: once as the
-	result of the :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>`, and once via
-	:ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>`.
-
-    * .. _`CEC-MSG-FL-RAW`:
-
-      - ``CEC_MSG_FL_RAW``
-      - 2
-      - Normally CEC messages are validated before transmitting them. If this
-        flag is set when :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` is called,
-	then no validation takes place and the message is transmitted as-is.
-	This is useful when debugging CEC issues.
-	This flag is only allowed if the process has the ``CAP_SYS_RAWIO``
-	capability. If that is not set, then the ``EPERM`` error code is
-	returned.
-
-
-.. tabularcolumns:: |p{5.6cm}|p{0.9cm}|p{11.0cm}|
-
-.. _cec-tx-status:
-
-.. flat-table:: CEC Transmit Status
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 16
-
-    * .. _`CEC-TX-STATUS-OK`:
-
-      - ``CEC_TX_STATUS_OK``
-      - 0x01
-      - The message was transmitted successfully. This is mutually
-	exclusive with :ref:`CEC_TX_STATUS_MAX_RETRIES <CEC-TX-STATUS-MAX-RETRIES>`.
-	Other bits can still be set if earlier attempts met with failure before
-	the transmit was eventually successful.
-    * .. _`CEC-TX-STATUS-ARB-LOST`:
-
-      - ``CEC_TX_STATUS_ARB_LOST``
-      - 0x02
-      - CEC line arbitration was lost, i.e. another transmit started at the
-        same time with a higher priority. Optional status, not all hardware
-	can detect this error condition.
-    * .. _`CEC-TX-STATUS-NACK`:
-
-      - ``CEC_TX_STATUS_NACK``
-      - 0x04
-      - Message was not acknowledged. Note that some hardware cannot tell apart
-        a 'Not Acknowledged' status from other error conditions, i.e. the result
-	of a transmit is just OK or FAIL. In that case this status will be
-	returned when the transmit failed.
-    * .. _`CEC-TX-STATUS-LOW-DRIVE`:
-
-      - ``CEC_TX_STATUS_LOW_DRIVE``
-      - 0x08
-      - Low drive was detected on the CEC bus. This indicates that a
-	follower detected an error on the bus and requests a
-	retransmission. Optional status, not all hardware can detect this
-	error condition.
-    * .. _`CEC-TX-STATUS-ERROR`:
-
-      - ``CEC_TX_STATUS_ERROR``
-      - 0x10
-      - Some error occurred. This is used for any errors that do not fit
-	``CEC_TX_STATUS_ARB_LOST`` or ``CEC_TX_STATUS_LOW_DRIVE``, either because
-	the hardware could not tell which error occurred, or because the hardware
-	tested for other conditions besides those two. Optional status.
-    * .. _`CEC-TX-STATUS-MAX-RETRIES`:
-
-      - ``CEC_TX_STATUS_MAX_RETRIES``
-      - 0x20
-      - The transmit failed after one or more retries. This status bit is
-	mutually exclusive with :ref:`CEC_TX_STATUS_OK <CEC-TX-STATUS-OK>`.
-	Other bits can still be set to explain which failures were seen.
-    * .. _`CEC-TX-STATUS-ABORTED`:
-
-      - ``CEC_TX_STATUS_ABORTED``
-      - 0x40
-      - The transmit was aborted due to an HDMI disconnect, or the adapter
-        was unconfigured, or a transmit was interrupted, or the driver
-	returned an error when attempting to start a transmit.
-    * .. _`CEC-TX-STATUS-TIMEOUT`:
-
-      - ``CEC_TX_STATUS_TIMEOUT``
-      - 0x80
-      - The transmit timed out. This should not normally happen and this
-	indicates a driver problem.
-
-
-.. tabularcolumns:: |p{5.6cm}|p{0.9cm}|p{11.0cm}|
-
-.. _cec-rx-status:
-
-.. flat-table:: CEC Receive Status
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 16
-
-    * .. _`CEC-RX-STATUS-OK`:
-
-      - ``CEC_RX_STATUS_OK``
-      - 0x01
-      - The message was received successfully.
-    * .. _`CEC-RX-STATUS-TIMEOUT`:
-
-      - ``CEC_RX_STATUS_TIMEOUT``
-      - 0x02
-      - The reply to an earlier transmitted message timed out.
-    * .. _`CEC-RX-STATUS-FEATURE-ABORT`:
-
-      - ``CEC_RX_STATUS_FEATURE_ABORT``
-      - 0x04
-      - The message was received successfully but the reply was
-	``CEC_MSG_FEATURE_ABORT``. This status is only set if this message
-	was the reply to an earlier transmitted message.
-    * .. _`CEC-RX-STATUS-ABORTED`:
-
-      - ``CEC_RX_STATUS_ABORTED``
-      - 0x08
-      - The wait for a reply to an earlier transmitted message was aborted
-        because the HDMI cable was disconnected, the adapter was unconfigured
-	or the :ref:`CEC_TRANSMIT <CEC_RECEIVE>` that waited for a
-	reply was interrupted.
-
-
-
-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.
-
-The :ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>` can return the following
-error codes:
-
-EAGAIN
-    No messages are in the receive queue, and the filehandle is in non-blocking mode.
-
-ETIMEDOUT
-    The ``timeout`` was reached while waiting for a message.
-
-ERESTARTSYS
-    The wait for a message was interrupted (e.g. by Ctrl-C).
-
-The :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` can return the following
-error codes:
-
-ENOTTY
-    The ``CEC_CAP_TRANSMIT`` capability wasn't set, so this ioctl is not supported.
-
-EPERM
-    The CEC adapter is not configured, i.e. :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`
-    has never been called, or ``CEC_MSG_FL_RAW`` was used from a process that
-    did not have the ``CAP_SYS_RAWIO`` capability.
-
-ENONET
-    The CEC adapter is not configured, i.e. :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`
-    was called, but the physical address is invalid so no logical address was claimed.
-    An exception is made in this case for transmits from initiator 0xf ('Unregistered')
-    to destination 0 ('TV'). In that case the transmit will proceed as usual.
-
-EBUSY
-    Another filehandle is in exclusive follower or initiator mode, or the filehandle
-    is in mode ``CEC_MODE_NO_INITIATOR``. This is also returned if the transmit
-    queue is full.
-
-EINVAL
-    The contents of struct :c:type:`cec_msg` is invalid.
-
-ERESTARTSYS
-    The wait for a successful transmit was interrupted (e.g. by Ctrl-C).
diff --git a/Documentation/media/uapi/cec/cec-pin-error-inj.rst b/Documentation/media/uapi/cec/cec-pin-error-inj.rst
deleted file mode 100644
index 725f8b1c9965..000000000000
--- a/Documentation/media/uapi/cec/cec-pin-error-inj.rst
+++ /dev/null
@@ -1,334 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-CEC Pin Framework Error Injection
-=================================
-
-The CEC Pin Framework is a core CEC framework for CEC hardware that only
-has low-level support for the CEC bus. Most hardware today will have
-high-level CEC support where the hardware deals with driving the CEC bus,
-but some older devices aren't that fancy. However, this framework also
-allows you to connect the CEC pin to a GPIO on e.g. a Raspberry Pi and
-you have now made a CEC adapter.
-
-What makes doing this so interesting is that since we have full control
-over the bus it is easy to support error injection. This is ideal to
-test how well CEC adapters can handle error conditions.
-
-Currently only the cec-gpio driver (when the CEC line is directly
-connected to a pull-up GPIO line) and the AllWinner A10/A20 drm driver
-support this framework.
-
-If ``CONFIG_CEC_PIN_ERROR_INJ`` is enabled, then error injection is available
-through debugfs. Specifically, in ``/sys/kernel/debug/cec/cecX/`` there is
-now an ``error-inj`` file.
-
-.. note::
-
-    The error injection commands are not a stable ABI and may change in the
-    future.
-
-With ``cat error-inj`` you can see both the possible commands and the current
-error injection status::
-
-	$ cat /sys/kernel/debug/cec/cec0/error-inj
-	# Clear error injections:
-	#   clear          clear all rx and tx error injections
-	#   rx-clear       clear all rx error injections
-	#   tx-clear       clear all tx error injections
-	#   <op> clear     clear all rx and tx error injections for <op>
-	#   <op> rx-clear  clear all rx error injections for <op>
-	#   <op> tx-clear  clear all tx error injections for <op>
-	#
-	# RX error injection:
-	#   <op>[,<mode>] rx-nack              NACK the message instead of sending an ACK
-	#   <op>[,<mode>] rx-low-drive <bit>   force a low-drive condition at this bit position
-	#   <op>[,<mode>] rx-add-byte          add a spurious byte to the received CEC message
-	#   <op>[,<mode>] rx-remove-byte       remove the last byte from the received CEC message
-	#   <op>[,<mode>] rx-arb-lost <poll>   generate a POLL message to trigger an arbitration lost
-	#
-	# TX error injection settings:
-	#   tx-ignore-nack-until-eom           ignore early NACKs until EOM
-	#   tx-custom-low-usecs <usecs>        define the 'low' time for the custom pulse
-	#   tx-custom-high-usecs <usecs>       define the 'high' time for the custom pulse
-	#   tx-custom-pulse                    transmit the custom pulse once the bus is idle
-	#
-	# TX error injection:
-	#   <op>[,<mode>] tx-no-eom            don't set the EOM bit
-	#   <op>[,<mode>] tx-early-eom         set the EOM bit one byte too soon
-	#   <op>[,<mode>] tx-add-bytes <num>   append <num> (1-255) spurious bytes to the message
-	#   <op>[,<mode>] tx-remove-byte       drop the last byte from the message
-	#   <op>[,<mode>] tx-short-bit <bit>   make this bit shorter than allowed
-	#   <op>[,<mode>] tx-long-bit <bit>    make this bit longer than allowed
-	#   <op>[,<mode>] tx-custom-bit <bit>  send the custom pulse instead of this bit
-	#   <op>[,<mode>] tx-short-start       send a start pulse that's too short
-	#   <op>[,<mode>] tx-long-start        send a start pulse that's too long
-	#   <op>[,<mode>] tx-custom-start      send the custom pulse instead of the start pulse
-	#   <op>[,<mode>] tx-last-bit <bit>    stop sending after this bit
-	#   <op>[,<mode>] tx-low-drive <bit>   force a low-drive condition at this bit position
-	#
-	# <op>       CEC message opcode (0-255) or 'any'
-	# <mode>     'once' (default), 'always', 'toggle' or 'off'
-	# <bit>      CEC message bit (0-159)
-	#            10 bits per 'byte': bits 0-7: data, bit 8: EOM, bit 9: ACK
-	# <poll>     CEC poll message used to test arbitration lost (0x00-0xff, default 0x0f)
-	# <usecs>    microseconds (0-10000000, default 1000)
-
-	clear
-
-You can write error injection commands to ``error-inj`` using
-``echo 'cmd' >error-inj`` or ``cat cmd.txt >error-inj``. The ``cat error-inj``
-output contains the current error commands. You can save the output to a file
-and use it as an input to ``error-inj`` later.
-
-Basic Syntax
-------------
-
-Leading spaces/tabs are ignored. If the next character is a ``#`` or the end
-of the line was reached, then the whole line is ignored. Otherwise a command
-is expected.
-
-The error injection commands fall in two main groups: those relating to
-receiving CEC messages and those relating to transmitting CEC messages. In
-addition, there are commands to clear existing error injection commands and
-to create custom pulses on the CEC bus.
-
-Most error injection commands can be executed for specific CEC opcodes or for
-all opcodes (``any``). Each command also has a 'mode' which can be ``off``
-(can be used to turn off an existing error injection command), ``once``
-(the default) which will trigger the error injection only once for the next
-received or transmitted message, ``always`` to always trigger the error
-injection and ``toggle`` to toggle the error injection on or off for every
-transmit or receive.
-
-So '``any rx-nack``' will NACK the next received CEC message,
-'``any,always rx-nack``' will NACK all received CEC messages and
-'``0x82,toggle rx-nack``' will only NACK if an Active Source message was
-received and do that only for every other received message.
-
-After an error was injected with mode ``once`` the error injection command
-is cleared automatically, so ``once`` is a one-time deal.
-
-All combinations of ``<op>`` and error injection commands can co-exist. So
-this is fine::
-
-	0x9e tx-add-bytes 1
-	0x9e tx-early-eom
-	0x9f tx-add-bytes 2
-	any rx-nack
-
-All four error injection commands will be active simultaneously.
-
-However, if the same ``<op>`` and command combination is specified,
-but with different arguments::
-
-	0x9e tx-add-bytes 1
-	0x9e tx-add-bytes 2
-
-Then the second will overwrite the first.
-
-Clear Error Injections
-----------------------
-
-``clear``
-    Clear all error injections.
-
-``rx-clear``
-    Clear all receive error injections
-
-``tx-clear``
-    Clear all transmit error injections
-
-``<op> clear``
-    Clear all error injections for the given opcode.
-
-``<op> rx-clear``
-    Clear all receive error injections for the given opcode.
-
-``<op> tx-clear``
-    Clear all transmit error injections for the given opcode.
-
-Receive Messages
-----------------
-
-``<op>[,<mode>] rx-nack``
-    NACK broadcast messages and messages directed to this CEC adapter.
-    Every byte of the message will be NACKed in case the transmitter
-    keeps transmitting after the first byte was NACKed.
-
-``<op>[,<mode>] rx-low-drive <bit>``
-    Force a Low Drive condition at this bit position. If <op> specifies
-    a specific CEC opcode then the bit position must be at least 18,
-    otherwise the opcode hasn't been received yet. This tests if the
-    transmitter can handle the Low Drive condition correctly and reports
-    the error correctly. Note that a Low Drive in the first 4 bits can also
-    be interpreted as an Arbitration Lost condition by the transmitter.
-    This is implementation dependent.
-
-``<op>[,<mode>] rx-add-byte``
-    Add a spurious 0x55 byte to the received CEC message, provided
-    the message was 15 bytes long or less. This is useful to test
-    the high-level protocol since spurious bytes should be ignored.
-
-``<op>[,<mode>] rx-remove-byte``
-    Remove the last byte from the received CEC message, provided it
-    was at least 2 bytes long. This is useful to test the high-level
-    protocol since messages that are too short should be ignored.
-
-``<op>[,<mode>] rx-arb-lost <poll>``
-    Generate a POLL message to trigger an Arbitration Lost condition.
-    This command is only allowed for ``<op>`` values of ``next`` or ``all``.
-    As soon as a start bit has been received the CEC adapter will switch
-    to transmit mode and it will transmit a POLL message. By default this is
-    0x0f, but it can also be specified explicitly via the ``<poll>`` argument.
-
-    This command can be used to test the Arbitration Lost condition in
-    the remote CEC transmitter. Arbitration happens when two CEC adapters
-    start sending a message at the same time. In that case the initiator
-    with the most leading zeroes wins and the other transmitter has to
-    stop transmitting ('Arbitration Lost'). This is very hard to test,
-    except by using this error injection command.
-
-    This does not work if the remote CEC transmitter has logical address
-    0 ('TV') since that will always win.
-
-Transmit Messages
------------------
-
-``tx-ignore-nack-until-eom``
-    This setting changes the behavior of transmitting CEC messages. Normally
-    as soon as the receiver NACKs a byte the transmit will stop, but the
-    specification also allows that the full message is transmitted and only
-    at the end will the transmitter look at the ACK bit. This is not
-    recommended behavior since there is no point in keeping the CEC bus busy
-    for longer than is strictly needed. Especially given how slow the bus is.
-
-    This setting can be used to test how well a receiver deals with
-    transmitters that ignore NACKs until the very end of the message.
-
-``<op>[,<mode>] tx-no-eom``
-    Don't set the EOM bit. Normally the last byte of the message has the EOM
-    (End-Of-Message) bit set. With this command the transmit will just stop
-    without ever sending an EOM. This can be used to test how a receiver
-    handles this case. Normally receivers have a time-out after which
-    they will go back to the Idle state.
-
-``<op>[,<mode>] tx-early-eom``
-    Set the EOM bit one byte too soon. This obviously only works for messages
-    of two bytes or more. The EOM bit will be set for the second-to-last byte
-    and not for the final byte. The receiver should ignore the last byte in
-    this case. Since the resulting message is likely to be too short for this
-    same reason the whole message is typically ignored. The receiver should be
-    in Idle state after the last byte was transmitted.
-
-``<op>[,<mode>] tx-add-bytes <num>``
-    Append ``<num>`` (1-255) spurious bytes to the message. The extra bytes
-    have the value of the byte position in the message. So if you transmit a
-    two byte message (e.g. a Get CEC Version message) and add 2 bytes, then
-    the full message received by the remote CEC adapter is
-    ``0x40 0x9f 0x02 0x03``.
-
-    This command can be used to test buffer overflows in the receiver. E.g.
-    what does it do when it receives more than the maximum message size of 16
-    bytes.
-
-``<op>[,<mode>] tx-remove-byte``
-    Drop the last byte from the message, provided the message is at least
-    two bytes long. The receiver should ignore messages that are too short.
-
-``<op>[,<mode>] tx-short-bit <bit>``
-    Make this bit period shorter than allowed. The bit position cannot be
-    an Ack bit.  If <op> specifies a specific CEC opcode then the bit position
-    must be at least 18, otherwise the opcode hasn't been received yet.
-    Normally the period of a data bit is between 2.05 and 2.75 milliseconds.
-    With this command the period of this bit is 1.8 milliseconds, this is
-    done by reducing the time the CEC bus is high. This bit period is less
-    than is allowed and the receiver should respond with a Low Drive
-    condition.
-
-    This command is ignored for 0 bits in bit positions 0 to 3. This is
-    because the receiver also looks for an Arbitration Lost condition in
-    those first four bits and it is undefined what will happen if it
-    sees a too-short 0 bit.
-
-``<op>[,<mode>] tx-long-bit <bit>``
-    Make this bit period longer than is valid. The bit position cannot be
-    an Ack bit.  If <op> specifies a specific CEC opcode then the bit position
-    must be at least 18, otherwise the opcode hasn't been received yet.
-    Normally the period of a data bit is between 2.05 and 2.75 milliseconds.
-    With this command the period of this bit is 2.9 milliseconds, this is
-    done by increasing the time the CEC bus is high.
-
-    Even though this bit period is longer than is valid it is undefined what
-    a receiver will do. It might just accept it, or it might time out and
-    return to Idle state. Unfortunately the CEC specification is silent about
-    this.
-
-    This command is ignored for 0 bits in bit positions 0 to 3. This is
-    because the receiver also looks for an Arbitration Lost condition in
-    those first four bits and it is undefined what will happen if it
-    sees a too-long 0 bit.
-
-``<op>[,<mode>] tx-short-start``
-    Make this start bit period shorter than allowed. Normally the period of
-    a start bit is between 4.3 and 4.7 milliseconds. With this command the
-    period of the start bit is 4.1 milliseconds, this is done by reducing
-    the time the CEC bus is high. This start bit period is less than is
-    allowed and the receiver should return to Idle state when this is detected.
-
-``<op>[,<mode>] tx-long-start``
-    Make this start bit period longer than is valid. Normally the period of
-    a start bit is between 4.3 and 4.7 milliseconds. With this command the
-    period of the start bit is 5 milliseconds, this is done by increasing
-    the time the CEC bus is high. This start bit period is more than is
-    valid and the receiver should return to Idle state when this is detected.
-
-    Even though this start bit period is longer than is valid it is undefined
-    what a receiver will do. It might just accept it, or it might time out and
-    return to Idle state. Unfortunately the CEC specification is silent about
-    this.
-
-``<op>[,<mode>] tx-last-bit <bit>``
-    Just stop transmitting after this bit.  If <op> specifies a specific CEC
-    opcode then the bit position must be at least 18, otherwise the opcode
-    hasn't been received yet. This command can be used to test how the receiver
-    reacts when a message just suddenly stops. It should time out and go back
-    to Idle state.
-
-``<op>[,<mode>] tx-low-drive <bit>``
-    Force a Low Drive condition at this bit position. If <op> specifies a
-    specific CEC opcode then the bit position must be at least 18, otherwise
-    the opcode hasn't been received yet. This can be used to test how the
-    receiver handles Low Drive conditions. Note that if this happens at bit
-    positions 0-3 the receiver can interpret this as an Arbitration Lost
-    condition. This is implementation dependent.
-
-Custom Pulses
--------------
-
-``tx-custom-low-usecs <usecs>``
-    This defines the duration in microseconds that the custom pulse pulls
-    the CEC line low. The default is 1000 microseconds.
-
-``tx-custom-high-usecs <usecs>``
-    This defines the duration in microseconds that the custom pulse keeps the
-    CEC line high (unless another CEC adapter pulls it low in that time).
-    The default is 1000 microseconds. The total period of the custom pulse is
-    ``tx-custom-low-usecs + tx-custom-high-usecs``.
-
-``<op>[,<mode>] tx-custom-bit <bit>``
-    Send the custom bit instead of a regular data bit. The bit position cannot
-    be an Ack bit.  If <op> specifies a specific CEC opcode then the bit
-    position must be at least 18, otherwise the opcode hasn't been received yet.
-
-``<op>[,<mode>] tx-custom-start``
-    Send the custom bit instead of a regular start bit.
-
-``tx-custom-pulse``
-    Transmit a single custom pulse as soon as the CEC bus is idle.
diff --git a/Documentation/media/uapi/dvb/audio-bilingual-channel-select.rst b/Documentation/media/uapi/dvb/audio-bilingual-channel-select.rst
deleted file mode 100644
index ee2ee74dafa3..000000000000
--- a/Documentation/media/uapi/dvb/audio-bilingual-channel-select.rst
+++ /dev/null
@@ -1,66 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _AUDIO_BILINGUAL_CHANNEL_SELECT:
-
-==============================
-AUDIO_BILINGUAL_CHANNEL_SELECT
-==============================
-
-Name
-----
-
-AUDIO_BILINGUAL_CHANNEL_SELECT
-
-.. attention:: This ioctl is deprecated
-
-Synopsis
---------
-
-.. c:function:: int ioctl(int fd, AUDIO_BILINGUAL_CHANNEL_SELECT, struct *audio_channel_select)
-    :name: AUDIO_BILINGUAL_CHANNEL_SELECT
-
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    -
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-    -
-
-       -  audio_channel_select_t ch
-
-       -  Select the output format of the audio (mono left/right, stereo).
-
-
-Description
------------
-
-This ioctl is obsolete. Do not use in new drivers. It has been replaced
-by the V4L2 ``V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK`` control
-for MPEG decoders controlled through V4L2.
-
-This ioctl call asks the Audio Device to select the requested channel
-for bilingual streams if possible.
-
-
-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/dvb/audio-channel-select.rst b/Documentation/media/uapi/dvb/audio-channel-select.rst
deleted file mode 100644
index ebb2f121c4c8..000000000000
--- a/Documentation/media/uapi/dvb/audio-channel-select.rst
+++ /dev/null
@@ -1,66 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _AUDIO_CHANNEL_SELECT:
-
-====================
-AUDIO_CHANNEL_SELECT
-====================
-
-Name
-----
-
-AUDIO_CHANNEL_SELECT
-
-.. attention:: This ioctl is deprecated
-
-Synopsis
---------
-
-.. c:function:: int ioctl(int fd, AUDIO_CHANNEL_SELECT, struct *audio_channel_select)
-    :name: AUDIO_CHANNEL_SELECT
-
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-    -
-
-       -  audio_channel_select_t ch
-
-       -  Select the output format of the audio (mono left/right, stereo).
-
-
-Description
------------
-
-This ioctl is for Digital TV devices only. To control a V4L2 decoder use the
-V4L2 ``V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK`` control instead.
-
-This ioctl call asks the Audio Device to select the requested channel if
-possible.
-
-
-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/dvb/audio-clear-buffer.rst b/Documentation/media/uapi/dvb/audio-clear-buffer.rst
deleted file mode 100644
index c5b62cde18c8..000000000000
--- a/Documentation/media/uapi/dvb/audio-clear-buffer.rst
+++ /dev/null
@@ -1,55 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _AUDIO_CLEAR_BUFFER:
-
-==================
-AUDIO_CLEAR_BUFFER
-==================
-
-Name
-----
-
-AUDIO_CLEAR_BUFFER
-
-.. attention:: This ioctl is deprecated
-
-Synopsis
---------
-
-.. c:function:: int  ioctl(int fd, AUDIO_CLEAR_BUFFER)
-    :name: AUDIO_CLEAR_BUFFER
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-Description
------------
-
-This ioctl call asks the Audio Device to clear all software and hardware
-buffers of the audio decoder device.
-
-
-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/dvb/audio-continue.rst b/Documentation/media/uapi/dvb/audio-continue.rst
deleted file mode 100644
index 6bdc99e39e20..000000000000
--- a/Documentation/media/uapi/dvb/audio-continue.rst
+++ /dev/null
@@ -1,56 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _AUDIO_CONTINUE:
-
-==============
-AUDIO_CONTINUE
-==============
-
-Name
-----
-
-AUDIO_CONTINUE
-
-.. attention:: This ioctl is deprecated
-
-Synopsis
---------
-
-.. c:function:: int  ioctl(int fd, AUDIO_CONTINUE)
-    :name: AUDIO_CONTINUE
-
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-Description
------------
-
-This ioctl restarts the decoding and playing process previously paused
-with AUDIO_PAUSE command.
-
-
-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/dvb/audio-fclose.rst b/Documentation/media/uapi/dvb/audio-fclose.rst
deleted file mode 100644
index 1e4ad7a0325d..000000000000
--- a/Documentation/media/uapi/dvb/audio-fclose.rst
+++ /dev/null
@@ -1,63 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _audio_fclose:
-
-========================
-Digital TV audio close()
-========================
-
-Name
-----
-
-Digital TV audio close()
-
-.. attention:: This ioctl is deprecated
-
-Synopsis
---------
-
-.. c:function:: int close(int fd)
-    :name: dvb-audio-close
-
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-
-Description
------------
-
-This system call closes a previously opened audio device.
-
-
-Return Value
-------------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  ``EBADF``
-
-       -  fd is not a valid open file descriptor.
diff --git a/Documentation/media/uapi/dvb/audio-fopen.rst b/Documentation/media/uapi/dvb/audio-fopen.rst
deleted file mode 100644
index 2cf4d83661f4..000000000000
--- a/Documentation/media/uapi/dvb/audio-fopen.rst
+++ /dev/null
@@ -1,115 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _audio_fopen:
-
-=======================
-Digital TV audio open()
-=======================
-
-Name
-----
-
-Digital TV audio open()
-
-.. attention:: This ioctl is deprecated
-
-Synopsis
---------
-
-.. c:function:: int open(const char *deviceName, int flags)
-    :name: dvb-audio-open
-
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  const char \*deviceName
-
-       -  Name of specific audio device.
-
-    -  .. row 2
-
-       -  int flags
-
-       -  A bit-wise OR of the following flags:
-
-    -  .. row 3
-
-       -
-       -  O_RDONLY read-only access
-
-    -  .. row 4
-
-       -
-       -  O_RDWR read/write access
-
-    -  .. row 5
-
-       -
-       -  O_NONBLOCK open in non-blocking mode
-
-    -  .. row 6
-
-       -
-       -  (blocking mode is the default)
-
-
-Description
------------
-
-This system call opens a named audio device (e.g.
-/dev/dvb/adapter0/audio0) for subsequent use. When an open() call has
-succeeded, the device will be ready for use. The significance of
-blocking or non-blocking mode is described in the documentation for
-functions where there is a difference. It does not affect the semantics
-of the open() call itself. A device opened in blocking mode can later be
-put into non-blocking mode (and vice versa) using the F_SETFL command
-of the fcntl system call. This is a standard system call, documented in
-the Linux manual page for fcntl. Only one user can open the Audio Device
-in O_RDWR mode. All other attempts to open the device in this mode will
-fail, and an error code will be returned. If the Audio Device is opened
-in O_RDONLY mode, the only ioctl call that can be used is
-AUDIO_GET_STATUS. All other call will return with an error code.
-
-
-Return Value
-------------
-
-.. tabularcolumns:: |p{2.5cm}|p{15.0cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  ``ENODEV``
-
-       -  Device driver not loaded/available.
-
-    -  .. row 2
-
-       -  ``EBUSY``
-
-       -  Device or resource busy.
-
-    -  .. row 3
-
-       -  ``EINVAL``
-
-       -  Invalid argument.
diff --git a/Documentation/media/uapi/dvb/audio-fwrite.rst b/Documentation/media/uapi/dvb/audio-fwrite.rst
deleted file mode 100644
index 6dc6bf6cbbc7..000000000000
--- a/Documentation/media/uapi/dvb/audio-fwrite.rst
+++ /dev/null
@@ -1,91 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _audio_fwrite:
-
-=========================
-Digital TV audio write()
-=========================
-
-Name
-----
-
-Digital TV audio write()
-
-.. attention:: This ioctl is deprecated
-
-Synopsis
---------
-
-.. c:function:: size_t write(int fd, const void *buf, size_t count)
-    :name: dvb-audio-write
-
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-    -  .. row 2
-
-       -  void \*buf
-
-       -  Pointer to the buffer containing the PES data.
-
-    -  .. row 3
-
-       -  size_t count
-
-       -  Size of buf.
-
-
-Description
------------
-
-This system call can only be used if AUDIO_SOURCE_MEMORY is selected
-in the ioctl call AUDIO_SELECT_SOURCE. The data provided shall be in
-PES format. If O_NONBLOCK is not specified the function will block
-until buffer space is available. The amount of data to be transferred is
-implied by count.
-
-
-Return Value
-------------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  ``EPERM``
-
-       -  Mode AUDIO_SOURCE_MEMORY not selected.
-
-    -  .. row 2
-
-       -  ``ENOMEM``
-
-       -  Attempted to write more data than the internal buffer can hold.
-
-    -  .. row 3
-
-       -  ``EBADF``
-
-       -  fd is not a valid open file descriptor.
diff --git a/Documentation/media/uapi/dvb/audio-get-capabilities.rst b/Documentation/media/uapi/dvb/audio-get-capabilities.rst
deleted file mode 100644
index 4f1ec47e8ac2..000000000000
--- a/Documentation/media/uapi/dvb/audio-get-capabilities.rst
+++ /dev/null
@@ -1,63 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _AUDIO_GET_CAPABILITIES:
-
-======================
-AUDIO_GET_CAPABILITIES
-======================
-
-Name
-----
-
-AUDIO_GET_CAPABILITIES
-
-.. attention:: This ioctl is deprecated
-
-Synopsis
---------
-
-.. c:function:: int ioctl(int fd, AUDIO_GET_CAPABILITIES, unsigned int *cap)
-    :name: AUDIO_GET_CAPABILITIES
-
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-    -
-
-       -  unsigned int \*cap
-
-       -  Returns a bit array of supported sound formats.
-
-
-Description
------------
-
-This ioctl call asks the Audio Device to tell us about the decoding
-capabilities of the audio hardware.
-
-
-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/dvb/audio-get-status.rst b/Documentation/media/uapi/dvb/audio-get-status.rst
deleted file mode 100644
index 30e4dd7fce6d..000000000000
--- a/Documentation/media/uapi/dvb/audio-get-status.rst
+++ /dev/null
@@ -1,63 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _AUDIO_GET_STATUS:
-
-================
-AUDIO_GET_STATUS
-================
-
-Name
-----
-
-AUDIO_GET_STATUS
-
-.. attention:: This ioctl is deprecated
-
-Synopsis
---------
-
-.. c:function:: int ioctl(int fd, AUDIO_GET_STATUS, struct audio_status *status)
-    :name: AUDIO_GET_STATUS
-
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-    -
-
-       -  struct audio_status \*status
-
-       -  Returns the current state of Audio Device.
-
-
-Description
------------
-
-This ioctl call asks the Audio Device to return the current state of the
-Audio Device.
-
-
-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/dvb/audio-pause.rst b/Documentation/media/uapi/dvb/audio-pause.rst
deleted file mode 100644
index 4567ecd9e0a3..000000000000
--- a/Documentation/media/uapi/dvb/audio-pause.rst
+++ /dev/null
@@ -1,57 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _AUDIO_PAUSE:
-
-===========
-AUDIO_PAUSE
-===========
-
-Name
-----
-
-AUDIO_PAUSE
-
-.. attention:: This ioctl is deprecated
-
-Synopsis
---------
-
-.. c:function:: int  ioctl(int fd, AUDIO_PAUSE)
-    :name: AUDIO_PAUSE
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-
-Description
------------
-
-This ioctl call suspends the audio stream being played. Decoding and
-playing are paused. It is then possible to restart again decoding and
-playing process of the audio stream using AUDIO_CONTINUE command.
-
-
-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/dvb/audio-play.rst b/Documentation/media/uapi/dvb/audio-play.rst
deleted file mode 100644
index 17acd4c411b8..000000000000
--- a/Documentation/media/uapi/dvb/audio-play.rst
+++ /dev/null
@@ -1,56 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _AUDIO_PLAY:
-
-==========
-AUDIO_PLAY
-==========
-
-Name
-----
-
-AUDIO_PLAY
-
-.. attention:: This ioctl is deprecated
-
-Synopsis
---------
-
-.. c:function:: int  ioctl(int fd, AUDIO_PLAY)
-    :name: AUDIO_PLAY
-
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-Description
------------
-
-This ioctl call asks the Audio Device to start playing an audio stream
-from the selected source.
-
-
-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/dvb/audio-select-source.rst b/Documentation/media/uapi/dvb/audio-select-source.rst
deleted file mode 100644
index c5ed6243b11c..000000000000
--- a/Documentation/media/uapi/dvb/audio-select-source.rst
+++ /dev/null
@@ -1,65 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _AUDIO_SELECT_SOURCE:
-
-===================
-AUDIO_SELECT_SOURCE
-===================
-
-Name
-----
-
-AUDIO_SELECT_SOURCE
-
-.. attention:: This ioctl is deprecated
-
-Synopsis
---------
-
-.. c:function:: int ioctl(int fd, AUDIO_SELECT_SOURCE, struct audio_stream_source *source)
-    :name: AUDIO_SELECT_SOURCE
-
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-    -
-
-       -  audio_stream_source_t source
-
-       -  Indicates the source that shall be used for the Audio stream.
-
-
-Description
------------
-
-This ioctl call informs the audio device which source shall be used for
-the input data. The possible sources are demux or memory. If
-AUDIO_SOURCE_MEMORY is selected, the data is fed to the Audio Device
-through the write command.
-
-
-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/dvb/audio-set-av-sync.rst b/Documentation/media/uapi/dvb/audio-set-av-sync.rst
deleted file mode 100644
index c116d105fdea..000000000000
--- a/Documentation/media/uapi/dvb/audio-set-av-sync.rst
+++ /dev/null
@@ -1,67 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _AUDIO_SET_AV_SYNC:
-
-=================
-AUDIO_SET_AV_SYNC
-=================
-
-Name
-----
-
-AUDIO_SET_AV_SYNC
-
-.. attention:: This ioctl is deprecated
-
-Synopsis
---------
-
-.. c:function:: int  ioctl(int fd, AUDIO_SET_AV_SYNC, boolean state)
-    :name: AUDIO_SET_AV_SYNC
-
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-    -
-
-       -  boolean state
-
-       -  Tells the Digital TV subsystem if A/V synchronization shall be ON or OFF.
-
-          TRUE: AV-sync ON
-
-          FALSE: AV-sync OFF
-
-
-Description
------------
-
-This ioctl call asks the Audio Device to turn ON or OFF A/V
-synchronization.
-
-
-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/dvb/audio-set-bypass-mode.rst b/Documentation/media/uapi/dvb/audio-set-bypass-mode.rst
deleted file mode 100644
index d68f05d48d12..000000000000
--- a/Documentation/media/uapi/dvb/audio-set-bypass-mode.rst
+++ /dev/null
@@ -1,70 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _AUDIO_SET_BYPASS_MODE:
-
-=====================
-AUDIO_SET_BYPASS_MODE
-=====================
-
-Name
-----
-
-AUDIO_SET_BYPASS_MODE
-
-.. attention:: This ioctl is deprecated
-
-Synopsis
---------
-
-.. c:function:: int ioctl(int fd, AUDIO_SET_BYPASS_MODE, boolean mode)
-    :name: AUDIO_SET_BYPASS_MODE
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-    -
-
-       -  boolean mode
-
-       -  Enables or disables the decoding of the current Audio stream in
-	  the Digital TV subsystem.
-
-          TRUE: Bypass is disabled
-
-          FALSE: Bypass is enabled
-
-
-Description
------------
-
-This ioctl call asks the Audio Device to bypass the Audio decoder and
-forward the stream without decoding. This mode shall be used if streams
-that can’t be handled by the Digital TV system shall be decoded. Dolby
-DigitalTM streams are automatically forwarded by the Digital TV subsystem if
-the hardware can handle it.
-
-
-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/dvb/audio-set-id.rst b/Documentation/media/uapi/dvb/audio-set-id.rst
deleted file mode 100644
index aeb6ace6cd1e..000000000000
--- a/Documentation/media/uapi/dvb/audio-set-id.rst
+++ /dev/null
@@ -1,67 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _AUDIO_SET_ID:
-
-============
-AUDIO_SET_ID
-============
-
-Name
-----
-
-AUDIO_SET_ID
-
-.. attention:: This ioctl is deprecated
-
-Synopsis
---------
-
-.. c:function:: int  ioctl(int fd, AUDIO_SET_ID, int id)
-    :name: AUDIO_SET_ID
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-    -
-
-       -  int id
-
-       -  audio sub-stream id
-
-
-Description
------------
-
-This ioctl selects which sub-stream is to be decoded if a program or
-system stream is sent to the video device. If no audio stream type is
-set the id has to be in [0xC0,0xDF] for MPEG sound, in [0x80,0x87] for
-AC3 and in [0xA0,0xA7] for LPCM. More specifications may follow for
-other stream types. If the stream type is set the id just specifies the
-substream id of the audio stream and only the first 5 bits are
-recognized.
-
-
-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/dvb/audio-set-mixer.rst b/Documentation/media/uapi/dvb/audio-set-mixer.rst
deleted file mode 100644
index 60781aa88202..000000000000
--- a/Documentation/media/uapi/dvb/audio-set-mixer.rst
+++ /dev/null
@@ -1,61 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _AUDIO_SET_MIXER:
-
-===============
-AUDIO_SET_MIXER
-===============
-
-Name
-----
-
-AUDIO_SET_MIXER
-
-.. attention:: This ioctl is deprecated
-
-Synopsis
---------
-
-.. c:function:: int ioctl(int fd, AUDIO_SET_MIXER, struct audio_mixer *mix)
-    :name: AUDIO_SET_MIXER
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-    -
-
-       -  audio_mixer_t \*mix
-
-       -  mixer settings.
-
-
-Description
------------
-
-This ioctl lets you adjust the mixer settings of the audio decoder.
-
-
-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/dvb/audio-set-mute.rst b/Documentation/media/uapi/dvb/audio-set-mute.rst
deleted file mode 100644
index 4449f225e48c..000000000000
--- a/Documentation/media/uapi/dvb/audio-set-mute.rst
+++ /dev/null
@@ -1,71 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _AUDIO_SET_MUTE:
-
-==============
-AUDIO_SET_MUTE
-==============
-
-Name
-----
-
-AUDIO_SET_MUTE
-
-.. attention:: This ioctl is deprecated
-
-Synopsis
---------
-
-.. c:function:: int  ioctl(int fd, AUDIO_SET_MUTE, boolean state)
-    :name: AUDIO_SET_MUTE
-
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-    -
-
-       -  boolean state
-
-       -  Indicates if audio device shall mute or not.
-
-          TRUE: Audio Mute
-
-          FALSE: Audio Un-mute
-
-
-Description
------------
-
-This ioctl is for Digital TV devices only. To control a V4L2 decoder use the
-V4L2 :ref:`VIDIOC_DECODER_CMD` with the
-``V4L2_DEC_CMD_START_MUTE_AUDIO`` flag instead.
-
-This ioctl call asks the audio device to mute the stream that is
-currently being played.
-
-
-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/dvb/audio-set-streamtype.rst b/Documentation/media/uapi/dvb/audio-set-streamtype.rst
deleted file mode 100644
index d20c34fc7128..000000000000
--- a/Documentation/media/uapi/dvb/audio-set-streamtype.rst
+++ /dev/null
@@ -1,77 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _AUDIO_SET_STREAMTYPE:
-
-====================
-AUDIO_SET_STREAMTYPE
-====================
-
-Name
-----
-
-AUDIO_SET_STREAMTYPE
-
-.. attention:: This ioctl is deprecated
-
-Synopsis
---------
-
-.. c:function:: int  ioctl(fd, AUDIO_SET_STREAMTYPE, int type)
-    :name: AUDIO_SET_STREAMTYPE
-
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-    -
-
-       -  int type
-
-       -  stream type
-
-
-Description
------------
-
-This ioctl tells the driver which kind of audio stream to expect. This
-is useful if the stream offers several audio sub-streams like LPCM and
-AC3.
-
-
-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.
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  ``EINVAL``
-
-       -  type is not a valid or supported stream type.
diff --git a/Documentation/media/uapi/dvb/audio-stop.rst b/Documentation/media/uapi/dvb/audio-stop.rst
deleted file mode 100644
index 1bba2e50c364..000000000000
--- a/Documentation/media/uapi/dvb/audio-stop.rst
+++ /dev/null
@@ -1,56 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _AUDIO_STOP:
-
-==========
-AUDIO_STOP
-==========
-
-Name
-----
-
-AUDIO_STOP
-
-.. attention:: This ioctl is deprecated
-
-Synopsis
---------
-
-.. c:function:: int ioctl(int fd, AUDIO_STOP)
-    :name: AUDIO_STOP
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-
-Description
------------
-
-This ioctl call asks the Audio Device to stop playing the current
-stream.
-
-
-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/dvb/audio.rst b/Documentation/media/uapi/dvb/audio.rst
deleted file mode 100644
index ebc18fca76a4..000000000000
--- a/Documentation/media/uapi/dvb/audio.rst
+++ /dev/null
@@ -1,34 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _dvb_audio:
-
-#######################
-Digital TV Audio Device
-#######################
-
-The Digital TV audio device controls the MPEG2 audio decoder of the Digital
-TV hardware. It can be accessed through ``/dev/dvb/adapter?/audio?``. Data
-types and and ioctl definitions can be accessed by including
-``linux/dvb/audio.h`` in your application.
-
-Please note that some Digital TV cards don’t have their own MPEG decoder, which
-results in the omission of the audio and video device.
-
-These ioctls were also used by V4L2 to control MPEG decoders implemented
-in V4L2. The use of these ioctls for that purpose has been made obsolete
-and proper V4L2 ioctls or controls have been created to replace that
-functionality.
-
-
-.. toctree::
-    :maxdepth: 1
-
-    audio_data_types
-    audio_function_calls
diff --git a/Documentation/media/uapi/dvb/audio_data_types.rst b/Documentation/media/uapi/dvb/audio_data_types.rst
deleted file mode 100644
index 5b032fe13b9d..000000000000
--- a/Documentation/media/uapi/dvb/audio_data_types.rst
+++ /dev/null
@@ -1,123 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _audio_data_types:
-
-****************
-Audio Data Types
-****************
-
-This section describes the structures, data types and defines used when
-talking to the audio device.
-
-.. c:type:: audio_stream_source
-
-The audio stream source is set through the AUDIO_SELECT_SOURCE call
-and can take the following values, depending on whether we are replaying
-from an internal (demux) or external (user write) source.
-
-
-.. code-block:: c
-
-    typedef enum {
-	AUDIO_SOURCE_DEMUX,
-	AUDIO_SOURCE_MEMORY
-    } audio_stream_source_t;
-
-AUDIO_SOURCE_DEMUX selects the demultiplexer (fed either by the
-frontend or the DVR device) as the source of the video stream. If
-AUDIO_SOURCE_MEMORY is selected the stream comes from the application
-through the ``write()`` system call.
-
-
-.. c:type:: audio_play_state
-
-The following values can be returned by the AUDIO_GET_STATUS call
-representing the state of audio playback.
-
-
-.. code-block:: c
-
-    typedef enum {
-	AUDIO_STOPPED,
-	AUDIO_PLAYING,
-	AUDIO_PAUSED
-    } audio_play_state_t;
-
-
-.. c:type:: audio_channel_select
-
-The audio channel selected via AUDIO_CHANNEL_SELECT is determined by
-the following values.
-
-
-.. code-block:: c
-
-    typedef enum {
-	AUDIO_STEREO,
-	AUDIO_MONO_LEFT,
-	AUDIO_MONO_RIGHT,
-	AUDIO_MONO,
-	AUDIO_STEREO_SWAPPED
-    } audio_channel_select_t;
-
-
-.. c:type:: audio_status
-
-The AUDIO_GET_STATUS call returns the following structure informing
-about various states of the playback operation.
-
-
-.. code-block:: c
-
-    typedef struct audio_status {
-	boolean AV_sync_state;
-	boolean mute_state;
-	audio_play_state_t play_state;
-	audio_stream_source_t stream_source;
-	audio_channel_select_t channel_select;
-	boolean bypass_mode;
-	audio_mixer_t mixer_state;
-    } audio_status_t;
-
-
-.. c:type:: audio_mixer
-
-The following structure is used by the AUDIO_SET_MIXER call to set the
-audio volume.
-
-
-.. code-block:: c
-
-    typedef struct audio_mixer {
-	unsigned int volume_left;
-	unsigned int volume_right;
-    } audio_mixer_t;
-
-
-.. _audio_encodings:
-
-audio encodings
-===============
-
-A call to AUDIO_GET_CAPABILITIES returns an unsigned integer with the
-following bits set according to the hardwares capabilities.
-
-
-.. code-block:: c
-
-     #define AUDIO_CAP_DTS    1
-     #define AUDIO_CAP_LPCM   2
-     #define AUDIO_CAP_MP1    4
-     #define AUDIO_CAP_MP2    8
-     #define AUDIO_CAP_MP3   16
-     #define AUDIO_CAP_AAC   32
-     #define AUDIO_CAP_OGG   64
-     #define AUDIO_CAP_SDDS 128
-     #define AUDIO_CAP_AC3  256
diff --git a/Documentation/media/uapi/dvb/audio_function_calls.rst b/Documentation/media/uapi/dvb/audio_function_calls.rst
deleted file mode 100644
index 5478e78b085e..000000000000
--- a/Documentation/media/uapi/dvb/audio_function_calls.rst
+++ /dev/null
@@ -1,37 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _audio_function_calls:
-
-********************
-Audio Function Calls
-********************
-
-.. toctree::
-    :maxdepth: 1
-
-    audio-fopen
-    audio-fclose
-    audio-fwrite
-    audio-stop
-    audio-play
-    audio-pause
-    audio-continue
-    audio-select-source
-    audio-set-mute
-    audio-set-av-sync
-    audio-set-bypass-mode
-    audio-channel-select
-    audio-bilingual-channel-select
-    audio-get-status
-    audio-get-capabilities
-    audio-clear-buffer
-    audio-set-id
-    audio-set-mixer
-    audio-set-streamtype
diff --git a/Documentation/media/uapi/dvb/ca-fclose.rst b/Documentation/media/uapi/dvb/ca-fclose.rst
deleted file mode 100644
index e273444ccc67..000000000000
--- a/Documentation/media/uapi/dvb/ca-fclose.rst
+++ /dev/null
@@ -1,50 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _ca_fclose:
-
-=====================
-Digital TV CA close()
-=====================
-
-Name
-----
-
-Digital TV CA close()
-
-
-Synopsis
---------
-
-.. c:function:: int close(int fd)
-    :name: dvb-ca-close
-
-
-Arguments
----------
-
-``fd``
-  File descriptor returned by a previous call to :c:func:`open() <dvb-ca-open>`.
-
-Description
------------
-
-This system call closes a previously opened CA device.
-
-
-Return Value
-------------
-
-On success 0 is returned.
-
-On error -1 is returned, and the ``errno`` variable is set
-appropriately.
-
-Generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/media/uapi/dvb/ca-fopen.rst b/Documentation/media/uapi/dvb/ca-fopen.rst
deleted file mode 100644
index e11ebeae5693..000000000000
--- a/Documentation/media/uapi/dvb/ca-fopen.rst
+++ /dev/null
@@ -1,84 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _ca_fopen:
-
-====================
-Digital TV CA open()
-====================
-
-Name
-----
-
-Digital TV CA open()
-
-
-Synopsis
---------
-
-.. c:function:: int open(const char *name, int flags)
-    :name: dvb-ca-open
-
-
-Arguments
----------
-
-``name``
-  Name of specific Digital TV CA device.
-
-``flags``
-  A bit-wise OR of the following flags:
-
-.. tabularcolumns:: |p{2.5cm}|p{15.0cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths: 1 16
-
-    -  - ``O_RDONLY``
-       - read-only access
-
-    -  - ``O_RDWR``
-       - read/write access
-
-    -  - ``O_NONBLOCK``
-       - open in non-blocking mode
-         (blocking mode is the default)
-
-
-Description
------------
-
-This system call opens a named ca device (e.g. ``/dev/dvb/adapter?/ca?``)
-for subsequent use.
-
-When an ``open()`` call has succeeded, the device will be ready for use. The
-significance of blocking or non-blocking mode is described in the
-documentation for functions where there is a difference. It does not
-affect the semantics of the ``open()`` call itself. A device opened in
-blocking mode can later be put into non-blocking mode (and vice versa)
-using the ``F_SETFL`` command of the ``fcntl`` system call. This is a
-standard system call, documented in the Linux manual page for fcntl.
-Only one user can open the CA Device in ``O_RDWR`` mode. All other
-attempts to open the device in this mode will fail, and an error code
-will be returned.
-
-
-Return Value
-------------
-
-
-On success 0 is returned.
-
-On error -1 is returned, and the ``errno`` variable is set
-appropriately.
-
-Generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/media/uapi/dvb/ca-get-cap.rst b/Documentation/media/uapi/dvb/ca-get-cap.rst
deleted file mode 100644
index 9e4fb5186373..000000000000
--- a/Documentation/media/uapi/dvb/ca-get-cap.rst
+++ /dev/null
@@ -1,53 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _CA_GET_CAP:
-
-==========
-CA_GET_CAP
-==========
-
-Name
-----
-
-CA_GET_CAP
-
-
-Synopsis
---------
-
-.. c:function:: int ioctl(fd, CA_GET_CAP, struct ca_caps *caps)
-    :name: CA_GET_CAP
-
-
-Arguments
----------
-
-``fd``
-  File descriptor returned by a previous call to :c:func:`open() <dvb-ca-open>`.
-
-``caps``
-  Pointer to struct :c:type:`ca_caps`.
-
-Description
------------
-
-Queries the Kernel for information about the available CA and descrambler
-slots, and their types.
-
-Return Value
-------------
-
-On success 0 is returned and :c:type:`ca_caps` is filled.
-
-On error, -1 is returned 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/dvb/ca-get-descr-info.rst b/Documentation/media/uapi/dvb/ca-get-descr-info.rst
deleted file mode 100644
index 80ef43a339df..000000000000
--- a/Documentation/media/uapi/dvb/ca-get-descr-info.rst
+++ /dev/null
@@ -1,49 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _CA_GET_DESCR_INFO:
-
-=================
-CA_GET_DESCR_INFO
-=================
-
-Name
-----
-
-CA_GET_DESCR_INFO
-
-
-Synopsis
---------
-
-.. c:function:: int  ioctl(fd, CA_GET_DESCR_INFO, struct ca_descr_info *desc)
-    :name: CA_GET_DESCR_INFO
-
-Arguments
----------
-
-``fd``
-  File descriptor returned by a previous call to :c:func:`open() <dvb-ca-open>`.
-
-``desc``
-  Pointer to struct :c:type:`ca_descr_info`.
-
-Description
------------
-
-Returns information about all descrambler slots.
-
-Return Value
-------------
-
-On success 0 is returned, and :c:type:`ca_descr_info` is filled.
-
-On error -1 is returned, 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/dvb/ca-get-msg.rst b/Documentation/media/uapi/dvb/ca-get-msg.rst
deleted file mode 100644
index bcb7955a0ddc..000000000000
--- a/Documentation/media/uapi/dvb/ca-get-msg.rst
+++ /dev/null
@@ -1,59 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _CA_GET_MSG:
-
-==========
-CA_GET_MSG
-==========
-
-Name
-----
-
-CA_GET_MSG
-
-
-Synopsis
---------
-
-.. c:function:: int ioctl(fd, CA_GET_MSG, struct ca_msg *msg)
-    :name: CA_GET_MSG
-
-
-Arguments
----------
-
-``fd``
-  File descriptor returned by a previous call to :c:func:`open() <dvb-ca-open>`.
-
-``msg``
-  Pointer to struct :c:type:`ca_msg`.
-
-Description
------------
-
-Receives a message via a CI CA module.
-
-.. note::
-
-   Please notice that, on most drivers, this is done by reading from
-   the /dev/adapter?/ca? device node.
-
-
-Return Value
-------------
-
-
-On success 0 is returned.
-
-On error -1 is returned, and the ``errno`` variable is set
-appropriately.
-
-Generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/media/uapi/dvb/ca-get-slot-info.rst b/Documentation/media/uapi/dvb/ca-get-slot-info.rst
deleted file mode 100644
index 1ea5c497f2ea..000000000000
--- a/Documentation/media/uapi/dvb/ca-get-slot-info.rst
+++ /dev/null
@@ -1,64 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _CA_GET_SLOT_INFO:
-
-================
-CA_GET_SLOT_INFO
-================
-
-Name
-----
-
-CA_GET_SLOT_INFO
-
-
-Synopsis
---------
-
-.. c:function:: int ioctl(fd, CA_GET_SLOT_INFO, struct ca_slot_info *info)
-    :name: CA_GET_SLOT_INFO
-
-
-Arguments
----------
-
-``fd``
-  File descriptor returned by a previous call to :c:func:`open() <cec-open>`.
-
-``info``
-  Pointer to struct :c:type:`ca_slot_info`.
-
-Description
------------
-
-Returns information about a CA slot identified by
-:c:type:`ca_slot_info`.slot_num.
-
-
-Return Value
-------------
-
-On success 0 is returned, and :c:type:`ca_slot_info` is filled.
-
-On error -1 is returned, and the ``errno`` variable is set
-appropriately.
-
-.. tabularcolumns:: |p{2.5cm}|p{15.0cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths: 1 16
-
-    -  -  ``ENODEV``
-       -  the slot is not available.
-
-The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/media/uapi/dvb/ca-reset.rst b/Documentation/media/uapi/dvb/ca-reset.rst
deleted file mode 100644
index 29fda19984be..000000000000
--- a/Documentation/media/uapi/dvb/ca-reset.rst
+++ /dev/null
@@ -1,51 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _CA_RESET:
-
-========
-CA_RESET
-========
-
-Name
-----
-
-CA_RESET
-
-
-Synopsis
---------
-
-.. c:function:: int ioctl(fd, CA_RESET)
-    :name: CA_RESET
-
-
-Arguments
----------
-
-``fd``
-  File descriptor returned by a previous call to :c:func:`open() <cec-open>`.
-
-Description
------------
-
-Puts the Conditional Access hardware on its initial state. It should
-be called before start using the CA hardware.
-
-
-Return Value
-------------
-
-On success 0 is returned.
-
-On error -1 is returned, and the ``errno`` variable is set
-appropriately.
-
-Generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/media/uapi/dvb/ca-send-msg.rst b/Documentation/media/uapi/dvb/ca-send-msg.rst
deleted file mode 100644
index 5a3c4e8120c4..000000000000
--- a/Documentation/media/uapi/dvb/ca-send-msg.rst
+++ /dev/null
@@ -1,58 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _CA_SEND_MSG:
-
-===========
-CA_SEND_MSG
-===========
-
-Name
-----
-
-CA_SEND_MSG
-
-
-Synopsis
---------
-
-.. c:function:: int ioctl(fd, CA_SEND_MSG, struct ca_msg *msg)
-    :name: CA_SEND_MSG
-
-
-Arguments
----------
-
-``fd``
-  File descriptor returned by a previous call to :c:func:`open() <cec-open>`.
-
-``msg``
-  Pointer to struct :c:type:`ca_msg`.
-
-
-Description
------------
-
-Sends a message via a CI CA module.
-
-.. note::
-
-   Please notice that, on most drivers, this is done by writing
-   to the /dev/adapter?/ca? device node.
-
-Return Value
-------------
-
-On success 0 is returned.
-
-On error -1 is returned, and the ``errno`` variable is set
-appropriately.
-
-Generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/media/uapi/dvb/ca-set-descr.rst b/Documentation/media/uapi/dvb/ca-set-descr.rst
deleted file mode 100644
index d36464ba2317..000000000000
--- a/Documentation/media/uapi/dvb/ca-set-descr.rst
+++ /dev/null
@@ -1,53 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _CA_SET_DESCR:
-
-============
-CA_SET_DESCR
-============
-
-Name
-----
-
-CA_SET_DESCR
-
-
-Synopsis
---------
-
-.. c:function:: int ioctl(fd, CA_SET_DESCR, struct ca_descr *desc)
-    :name: CA_SET_DESCR
-
-
-Arguments
----------
-
-``fd``
-  File descriptor returned by a previous call to :c:func:`open() <cec-open>`.
-
-``msg``
-  Pointer to struct :c:type:`ca_descr`.
-
-Description
------------
-
-CA_SET_DESCR is used for feeding descrambler CA slots with descrambling
-keys (referred as control words).
-
-Return Value
-------------
-
-On success 0 is returned.
-
-On error -1 is returned, and the ``errno`` variable is set
-appropriately.
-
-Generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/media/uapi/dvb/ca.rst b/Documentation/media/uapi/dvb/ca.rst
deleted file mode 100644
index 8796512c1378..000000000000
--- a/Documentation/media/uapi/dvb/ca.rst
+++ /dev/null
@@ -1,31 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _dvb_ca:
-
-####################
-Digital TV CA Device
-####################
-
-The Digital TV CA device controls the conditional access hardware. It
-can be accessed through ``/dev/dvb/adapter?/ca?``. Data types and and ioctl
-definitions can be accessed by including ``linux/dvb/ca.h`` in your
-application.
-
-.. note::
-
-   There are three ioctls at this API that aren't documented:
-   :ref:`CA_GET_MSG`, :ref:`CA_SEND_MSG` and :ref:`CA_SET_DESCR`.
-   Documentation for them are welcome.
-
-.. toctree::
-    :maxdepth: 1
-
-    ca_data_types
-    ca_function_calls
diff --git a/Documentation/media/uapi/dvb/ca_data_types.rst b/Documentation/media/uapi/dvb/ca_data_types.rst
deleted file mode 100644
index 834c8ab4c300..000000000000
--- a/Documentation/media/uapi/dvb/ca_data_types.rst
+++ /dev/null
@@ -1,16 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _ca_data_types:
-
-*************
-CA Data Types
-*************
-
-.. kernel-doc:: include/uapi/linux/dvb/ca.h
diff --git a/Documentation/media/uapi/dvb/ca_function_calls.rst b/Documentation/media/uapi/dvb/ca_function_calls.rst
deleted file mode 100644
index 6985bebd0661..000000000000
--- a/Documentation/media/uapi/dvb/ca_function_calls.rst
+++ /dev/null
@@ -1,27 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _ca_function_calls:
-
-*****************
-CA Function Calls
-*****************
-
-.. toctree::
-    :maxdepth: 1
-
-    ca-fopen
-    ca-fclose
-    ca-reset
-    ca-get-cap
-    ca-get-slot-info
-    ca-get-descr-info
-    ca-get-msg
-    ca-send-msg
-    ca-set-descr
diff --git a/Documentation/media/uapi/dvb/demux.rst b/Documentation/media/uapi/dvb/demux.rst
deleted file mode 100644
index d8c0ff4015fe..000000000000
--- a/Documentation/media/uapi/dvb/demux.rst
+++ /dev/null
@@ -1,30 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _dvb_demux:
-
-#######################
-Digital TV Demux Device
-#######################
-
-The Digital TV demux device controls the MPEG-TS filters for the
-digital TV. If the driver and hardware supports, those filters are
-implemented at the hardware. Otherwise, the Kernel provides a software
-emulation.
-
-It can be accessed through ``/dev/adapter?/demux?``. Data types and and
-ioctl definitions can be accessed by including ``linux/dvb/dmx.h`` in
-your application.
-
-
-.. toctree::
-    :maxdepth: 1
-
-    dmx_types
-    dmx_fcalls
diff --git a/Documentation/media/uapi/dvb/dmx-add-pid.rst b/Documentation/media/uapi/dvb/dmx-add-pid.rst
deleted file mode 100644
index f483268e4ede..000000000000
--- a/Documentation/media/uapi/dvb/dmx-add-pid.rst
+++ /dev/null
@@ -1,56 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _DMX_ADD_PID:
-
-===========
-DMX_ADD_PID
-===========
-
-Name
-----
-
-DMX_ADD_PID
-
-
-Synopsis
---------
-
-.. c:function:: int ioctl(fd, DMX_ADD_PID, __u16 *pid)
-    :name: DMX_ADD_PID
-
-
-Arguments
----------
-
-``fd``
-    File descriptor returned by :c:func:`open() <dvb-dmx-open>`.
-
-``pid``
-   PID number to be filtered.
-
-
-Description
------------
-
-This ioctl call allows to add multiple PIDs to a transport stream filter
-previously set up with :ref:`DMX_SET_PES_FILTER` and output equal to
-:c:type:`DMX_OUT_TSDEMUX_TAP <dmx_output>`.
-
-
-Return Value
-------------
-
-On success 0 is returned.
-
-On error -1 is returned, and the ``errno`` variable is set
-appropriately.
-
-Generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/media/uapi/dvb/dmx-expbuf.rst b/Documentation/media/uapi/dvb/dmx-expbuf.rst
deleted file mode 100644
index d7f0658f3db3..000000000000
--- a/Documentation/media/uapi/dvb/dmx-expbuf.rst
+++ /dev/null
@@ -1,97 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _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-fclose.rst b/Documentation/media/uapi/dvb/dmx-fclose.rst
deleted file mode 100644
index 05ff32270274..000000000000
--- a/Documentation/media/uapi/dvb/dmx-fclose.rst
+++ /dev/null
@@ -1,52 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _dmx_fclose:
-
-========================
-Digital TV demux close()
-========================
-
-Name
-----
-
-Digital TV demux close()
-
-
-Synopsis
---------
-
-.. c:function:: int close(int fd)
-    :name: dvb-dmx-close
-
-
-Arguments
----------
-
-``fd``
-  File descriptor returned by a previous call to
-  :c:func:`open() <dvb-dmx-open>`.
-
-Description
------------
-
-This system call deactivates and deallocates a filter that was
-previously allocated via the :c:func:`open() <dvb-dmx-open>` call.
-
-
-Return Value
-------------
-
-On success 0 is returned.
-
-On error, -1 is returned 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/dvb/dmx-fopen.rst b/Documentation/media/uapi/dvb/dmx-fopen.rst
deleted file mode 100644
index 2700a2fad68b..000000000000
--- a/Documentation/media/uapi/dvb/dmx-fopen.rst
+++ /dev/null
@@ -1,98 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _dmx_fopen:
-
-=======================
-Digital TV demux open()
-=======================
-
-Name
-----
-
-Digital TV demux open()
-
-
-Synopsis
---------
-
-.. c:function:: int open(const char *deviceName, int flags)
-    :name: dvb-dmx-open
-
-Arguments
----------
-
-``name``
-  Name of specific Digital TV demux device.
-
-``flags``
-  A bit-wise OR of the following flags:
-
-.. tabularcolumns:: |p{2.5cm}|p{15.0cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths: 1 16
-
-    -
-       - ``O_RDONLY``
-       - read-only access
-
-    -
-       - ``O_RDWR``
-       - read/write access
-
-    -
-       - ``O_NONBLOCK``
-       - open in non-blocking mode
-         (blocking mode is the default)
-
-
-Description
------------
-
-This system call, used with a device name of ``/dev/dvb/adapter?/demux?``,
-allocates a new filter and returns a handle which can be used for
-subsequent control of that filter. This call has to be made for each
-filter to be used, i.e. every returned file descriptor is a reference to
-a single filter. ``/dev/dvb/adapter?/dvr?`` is a logical device to be used
-for retrieving Transport Streams for digital video recording. When
-reading from this device a transport stream containing the packets from
-all PES filters set in the corresponding demux device
-(``/dev/dvb/adapter?/demux?``) having the output set to ``DMX_OUT_TS_TAP``.
-A recorded Transport Stream is replayed by writing to this device.
-
-The significance of blocking or non-blocking mode is described in the
-documentation for functions where there is a difference. It does not
-affect the semantics of the ``open()`` call itself. A device opened
-in blocking mode can later be put into non-blocking mode (and vice versa)
-using the ``F_SETFL`` command of the fcntl system call.
-
-
-Return Value
-------------
-
-On success 0 is returned.
-
-On error -1 is returned, and the ``errno`` variable is set
-appropriately.
-
-.. tabularcolumns:: |p{2.5cm}|p{15.0cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths: 1 16
-
-    -  -  ``EMFILE``
-       -  “Too many open files”, i.e. no more filters available.
-
-The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/media/uapi/dvb/dmx-fread.rst b/Documentation/media/uapi/dvb/dmx-fread.rst
deleted file mode 100644
index 292fa98f39ff..000000000000
--- a/Documentation/media/uapi/dvb/dmx-fread.rst
+++ /dev/null
@@ -1,87 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _dmx_fread:
-
-=======================
-Digital TV demux read()
-=======================
-
-Name
-----
-
-Digital TV demux read()
-
-
-Synopsis
---------
-
-.. c:function:: size_t read(int fd, void *buf, size_t count)
-    :name: dvb-dmx-read
-
-Arguments
----------
-
-``fd``
-  File descriptor returned by a previous call to :c:func:`open() <dvb-ca-open>`.
-
- ``buf``
-   Buffer to be filled
-
-``count``
-   Max number of bytes to read
-
-Description
------------
-
-This system call returns filtered data, which might be section or Packetized
-Elementary Stream (PES) data. The filtered data is transferred from
-the driver’s internal circular buffer to ``buf``. The maximum amount of data
-to be transferred is implied by count.
-
-.. note::
-
-   if a section filter created with
-   :c:type:`DMX_CHECK_CRC <dmx_sct_filter_params>` flag set,
-   data that fails on CRC check will be silently ignored.
-
-
-Return Value
-------------
-
-On success 0 is returned.
-
-On error -1 is returned, and the ``errno`` variable is set
-appropriately.
-
-.. tabularcolumns:: |p{2.5cm}|p{15.0cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths: 1 16
-
-    -  -  ``EWOULDBLOCK``
-       -  No data to return and ``O_NONBLOCK`` was specified.
-
-    -  -  ``EOVERFLOW``
-       -  The filtered data was not read from the buffer in due time,
-	  resulting in non-read data being lost. The buffer is flushed.
-
-    -  -  ``ETIMEDOUT``
-       -  The section was not loaded within the stated timeout period.
-          See ioctl :ref:`DMX_SET_FILTER` for how to set a timeout.
-
-    -  -  ``EFAULT``
-       -  The driver failed to write to the callers buffer due to an
-          invalid \*buf pointer.
-
-
-The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/media/uapi/dvb/dmx-fwrite.rst b/Documentation/media/uapi/dvb/dmx-fwrite.rst
deleted file mode 100644
index bdd4d4743bd5..000000000000
--- a/Documentation/media/uapi/dvb/dmx-fwrite.rst
+++ /dev/null
@@ -1,79 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _dmx_fwrite:
-
-========================
-Digital TV demux write()
-========================
-
-Name
-----
-
-Digital TV demux write()
-
-
-Synopsis
---------
-
-.. c:function:: ssize_t write(int fd, const void *buf, size_t count)
-    :name: dvb-dmx-write
-
-Arguments
----------
-
-``fd``
-  File descriptor returned by a previous call to :c:func:`open() <dvb-ca-open>`.
-
-``buf``
-     Buffer with data to be written
-
-``count``
-    Number of bytes at the buffer
-
-Description
------------
-
-This system call is only provided by the logical device
-``/dev/dvb/adapter?/dvr?``, associated with the physical demux device that
-provides the actual DVR functionality. It is used for replay of a
-digitally recorded Transport Stream. Matching filters have to be defined
-in the corresponding physical demux device, ``/dev/dvb/adapter?/demux?``.
-The amount of data to be transferred is implied by count.
-
-
-Return Value
-------------
-
-On success 0 is returned.
-
-On error -1 is returned, and the ``errno`` variable is set
-appropriately.
-
-.. tabularcolumns:: |p{2.5cm}|p{15.0cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths: 1 16
-
-    -  -  ``EWOULDBLOCK``
-       -  No data was written. This might happen if ``O_NONBLOCK`` was
-	  specified and there is no more buffer space available (if
-	  ``O_NONBLOCK`` is not specified the function will block until buffer
-	  space is available).
-
-    -  -  ``EBUSY``
-       -  This error code indicates that there are conflicting requests. The
-	  corresponding demux device is setup to receive data from the
-	  front- end. Make sure that these filters are stopped and that the
-	  filters with input set to ``DMX_IN_DVR`` are started.
-
-The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/media/uapi/dvb/dmx-get-pes-pids.rst b/Documentation/media/uapi/dvb/dmx-get-pes-pids.rst
deleted file mode 100644
index fcd3dc06c095..000000000000
--- a/Documentation/media/uapi/dvb/dmx-get-pes-pids.rst
+++ /dev/null
@@ -1,71 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _DMX_GET_PES_PIDS:
-
-================
-DMX_GET_PES_PIDS
-================
-
-Name
-----
-
-DMX_GET_PES_PIDS
-
-
-Synopsis
---------
-
-.. c:function:: int ioctl(fd, DMX_GET_PES_PIDS, __u16 pids[5])
-    :name: DMX_GET_PES_PIDS
-
-Arguments
----------
-
-``fd``
-    File descriptor returned by :c:func:`open() <dvb-dmx-open>`.
-
-``pids``
-    Array used to store 5 Program IDs.
-
-
-Description
------------
-
-This ioctl allows to query a DVB device to return the first PID used
-by audio, video, textext, subtitle and PCR programs on a given service.
-They're stored as:
-
-=======================	========	=======================================
-PID  element		position	content
-=======================	========	=======================================
-pids[DMX_PES_AUDIO]	0		first audio PID
-pids[DMX_PES_VIDEO]	1		first video PID
-pids[DMX_PES_TELETEXT]	2		first teletext PID
-pids[DMX_PES_SUBTITLE]	3		first subtitle PID
-pids[DMX_PES_PCR]	4		first Program Clock Reference PID
-=======================	========	=======================================
-
-
-.. note::
-
-	A value equal to 0xffff means that the PID was not filled by the
-	Kernel.
-
-
-Return Value
-------------
-
-On success 0 is returned.
-
-On error -1 is returned, 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/dvb/dmx-get-stc.rst b/Documentation/media/uapi/dvb/dmx-get-stc.rst
deleted file mode 100644
index 2c81595f470a..000000000000
--- a/Documentation/media/uapi/dvb/dmx-get-stc.rst
+++ /dev/null
@@ -1,73 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _DMX_GET_STC:
-
-===========
-DMX_GET_STC
-===========
-
-Name
-----
-
-DMX_GET_STC
-
-
-Synopsis
---------
-
-.. c:function:: int ioctl( int fd, DMX_GET_STC, struct dmx_stc *stc)
-    :name: DMX_GET_STC
-
-Arguments
----------
-
-``fd``
-    File descriptor returned by :c:func:`open() <dvb-dmx-open>`.
-
-``stc``
-    Pointer to :c:type:`dmx_stc` where the stc data is to be stored.
-
-
-Description
------------
-
-This ioctl call returns the current value of the system time counter
-(which is driven by a PES filter of type :c:type:`DMX_PES_PCR <dmx_ts_pes>`).
-Some hardware supports more than one STC, so you must specify which one by
-setting the :c:type:`num <dmx_stc>` field of stc before the ioctl (range 0...n).
-The result is returned in form of a ratio with a 64 bit numerator
-and a 32 bit denominator, so the real 90kHz STC value is
-``stc->stc / stc->base``.
-
-
-Return Value
-------------
-
-On success 0 is returned.
-
-On error -1 is returned, and the ``errno`` variable is set
-appropriately.
-
-.. tabularcolumns:: |p{2.5cm}|p{15.0cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths: 1 16
-
-    -  .. row 1
-
-       -  ``EINVAL``
-
-       -  Invalid stc number.
-
-
-The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/media/uapi/dvb/dmx-mmap.rst b/Documentation/media/uapi/dvb/dmx-mmap.rst
deleted file mode 100644
index 34bb7766718f..000000000000
--- a/Documentation/media/uapi/dvb/dmx-mmap.rst
+++ /dev/null
@@ -1,125 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _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
deleted file mode 100644
index ef26b6f2b12b..000000000000
--- a/Documentation/media/uapi/dvb/dmx-munmap.rst
+++ /dev/null
@@ -1,63 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _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
deleted file mode 100644
index 9dc845daa59d..000000000000
--- a/Documentation/media/uapi/dvb/dmx-qbuf.rst
+++ /dev/null
@@ -1,93 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _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 ``index`` field with the buffer ID to be queued.
-When ``DMX_DQBUF`` is called with a pointer to struct :c:type:`dmx_buffer`,
-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
deleted file mode 100644
index 4cf36e821696..000000000000
--- a/Documentation/media/uapi/dvb/dmx-querybuf.rst
+++ /dev/null
@@ -1,72 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _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-remove-pid.rst b/Documentation/media/uapi/dvb/dmx-remove-pid.rst
deleted file mode 100644
index be992f44f306..000000000000
--- a/Documentation/media/uapi/dvb/dmx-remove-pid.rst
+++ /dev/null
@@ -1,57 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _DMX_REMOVE_PID:
-
-==============
-DMX_REMOVE_PID
-==============
-
-Name
-----
-
-DMX_REMOVE_PID
-
-
-Synopsis
---------
-
-.. c:function:: int ioctl(fd, DMX_REMOVE_PID, __u16 *pid)
-    :name: DMX_REMOVE_PID
-
-
-Arguments
----------
-
-``fd``
-    File descriptor returned by :c:func:`open() <dvb-dmx-open>`.
-
-``pid``
-    PID of the PES filter to be removed.
-
-
-Description
------------
-
-This ioctl call allows to remove a PID when multiple PIDs are set on a
-transport stream filter, e. g. a filter previously set up with output
-equal to :c:type:`DMX_OUT_TSDEMUX_TAP <dmx_output>`, created via either
-:ref:`DMX_SET_PES_FILTER` or :ref:`DMX_ADD_PID`.
-
-
-Return Value
-------------
-
-On success 0 is returned.
-
-On error -1 is returned, 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/dvb/dmx-reqbufs.rst b/Documentation/media/uapi/dvb/dmx-reqbufs.rst
deleted file mode 100644
index b302785bf678..000000000000
--- a/Documentation/media/uapi/dvb/dmx-reqbufs.rst
+++ /dev/null
@@ -1,83 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _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-set-buffer-size.rst b/Documentation/media/uapi/dvb/dmx-set-buffer-size.rst
deleted file mode 100644
index 2dee0fb11f62..000000000000
--- a/Documentation/media/uapi/dvb/dmx-set-buffer-size.rst
+++ /dev/null
@@ -1,57 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _DMX_SET_BUFFER_SIZE:
-
-===================
-DMX_SET_BUFFER_SIZE
-===================
-
-Name
-----
-
-DMX_SET_BUFFER_SIZE
-
-
-Synopsis
---------
-
-.. c:function:: int ioctl( int fd, DMX_SET_BUFFER_SIZE, unsigned long size)
-    :name: DMX_SET_BUFFER_SIZE
-
-
-Arguments
----------
-
-``fd``
-    File descriptor returned by :c:func:`open() <dvb-dmx-open>`.
-
-``size``
-    Unsigned long size
-
-Description
------------
-
-This ioctl call is used to set the size of the circular buffer used for
-filtered data. The default size is two maximum sized sections, i.e. if
-this function is not called a buffer size of ``2 * 4096`` bytes will be
-used.
-
-
-Return Value
-------------
-
-
-On success 0 is returned.
-
-On error -1 is returned, 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/dvb/dmx-set-filter.rst b/Documentation/media/uapi/dvb/dmx-set-filter.rst
deleted file mode 100644
index 66afbb9f2fe4..000000000000
--- a/Documentation/media/uapi/dvb/dmx-set-filter.rst
+++ /dev/null
@@ -1,64 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _DMX_SET_FILTER:
-
-==============
-DMX_SET_FILTER
-==============
-
-Name
-----
-
-DMX_SET_FILTER
-
-
-Synopsis
---------
-
-.. c:function:: int ioctl( int fd, DMX_SET_FILTER, struct dmx_sct_filter_params *params)
-    :name: DMX_SET_FILTER
-
-Arguments
----------
-
-``fd``
-    File descriptor returned by :c:func:`open() <dvb-dmx-open>`.
-
-``params``
-
-    Pointer to structure containing filter parameters.
-
-
-Description
------------
-
-This ioctl call sets up a filter according to the filter and mask
-parameters provided. A timeout may be defined stating number of seconds
-to wait for a section to be loaded. A value of 0 means that no timeout
-should be applied. Finally there is a flag field where it is possible to
-state whether a section should be CRC-checked, whether the filter should
-be a ”one-shot” filter, i.e. if the filtering operation should be
-stopped after the first section is received, and whether the filtering
-operation should be started immediately (without waiting for a
-:ref:`DMX_START` ioctl call). If a filter was previously set-up, this
-filter will be canceled, and the receive buffer will be flushed.
-
-
-Return Value
-------------
-
-
-On success 0 is returned.
-
-On error -1 is returned, 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/dvb/dmx-set-pes-filter.rst b/Documentation/media/uapi/dvb/dmx-set-pes-filter.rst
deleted file mode 100644
index dae5ab7878e5..000000000000
--- a/Documentation/media/uapi/dvb/dmx-set-pes-filter.rst
+++ /dev/null
@@ -1,76 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _DMX_SET_PES_FILTER:
-
-==================
-DMX_SET_PES_FILTER
-==================
-
-Name
-----
-
-DMX_SET_PES_FILTER
-
-
-Synopsis
---------
-
-.. c:function:: int ioctl( int fd, DMX_SET_PES_FILTER, struct dmx_pes_filter_params *params)
-    :name: DMX_SET_PES_FILTER
-
-
-Arguments
----------
-
-
-``fd``
-    File descriptor returned by :c:func:`open() <dvb-dmx-open>`.
-
-``params``
-    Pointer to structure containing filter parameters.
-
-
-Description
------------
-
-This ioctl call sets up a PES filter according to the parameters
-provided. By a PES filter is meant a filter that is based just on the
-packet identifier (PID), i.e. no PES header or payload filtering
-capability is supported.
-
-
-Return Value
-------------
-
-On success 0 is returned.
-
-On error -1 is returned, and the ``errno`` variable is set
-appropriately.
-
-.. tabularcolumns:: |p{2.5cm}|p{15.0cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths: 1 16
-
-
-    -  .. row 1
-
-       -  ``EBUSY``
-
-       -  This error code indicates that there are conflicting requests.
-	  There are active filters filtering data from another input source.
-	  Make sure that these filters are stopped before starting this
-	  filter.
-
-
-The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/media/uapi/dvb/dmx-start.rst b/Documentation/media/uapi/dvb/dmx-start.rst
deleted file mode 100644
index 488289d02504..000000000000
--- a/Documentation/media/uapi/dvb/dmx-start.rst
+++ /dev/null
@@ -1,75 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _DMX_START:
-
-=========
-DMX_START
-=========
-
-Name
-----
-
-DMX_START
-
-
-Synopsis
---------
-
-.. c:function:: int ioctl( int fd, DMX_START)
-    :name: DMX_START
-
-
-Arguments
----------
-
-``fd``
-    File descriptor returned by :c:func:`open() <dvb-dmx-open>`.
-
-Description
------------
-
-This ioctl call is used to start the actual filtering operation defined
-via the ioctl calls :ref:`DMX_SET_FILTER` or :ref:`DMX_SET_PES_FILTER`.
-
-
-Return Value
-------------
-
-On success 0 is returned.
-
-On error -1 is returned, and the ``errno`` variable is set
-appropriately.
-
-.. tabularcolumns:: |p{2.5cm}|p{15.0cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  ``EINVAL``
-
-       -  Invalid argument, i.e. no filtering parameters provided via the
-	  :ref:`DMX_SET_FILTER` or :ref:`DMX_SET_PES_FILTER` ioctls.
-
-    -  .. row 2
-
-       -  ``EBUSY``
-
-       -  This error code indicates that there are conflicting requests.
-	  There are active filters filtering data from another input source.
-	  Make sure that these filters are stopped before starting this
-	  filter.
-
-
-The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/media/uapi/dvb/dmx-stop.rst b/Documentation/media/uapi/dvb/dmx-stop.rst
deleted file mode 100644
index 982384d12923..000000000000
--- a/Documentation/media/uapi/dvb/dmx-stop.rst
+++ /dev/null
@@ -1,52 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _DMX_STOP:
-
-========
-DMX_STOP
-========
-
-Name
-----
-
-DMX_STOP
-
-
-Synopsis
---------
-
-.. c:function:: int ioctl( int fd, DMX_STOP)
-    :name: DMX_STOP
-
-
-Arguments
----------
-
-``fd``
-    File descriptor returned by :c:func:`open() <dvb-dmx-open>`.
-
-Description
------------
-
-This ioctl call is used to stop the actual filtering operation defined
-via the ioctl calls :ref:`DMX_SET_FILTER` or :ref:`DMX_SET_PES_FILTER` and
-started via the :ref:`DMX_START` command.
-
-
-Return Value
-------------
-
-On success 0 is returned.
-
-On error -1 is returned, 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/dvb/dmx_fcalls.rst b/Documentation/media/uapi/dvb/dmx_fcalls.rst
deleted file mode 100644
index 67312ab65f94..000000000000
--- a/Documentation/media/uapi/dvb/dmx_fcalls.rst
+++ /dev/null
@@ -1,37 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _dmx_fcalls:
-
-********************
-Demux Function Calls
-********************
-
-.. toctree::
-    :maxdepth: 1
-
-    dmx-fopen
-    dmx-fclose
-    dmx-fread
-    dmx-fwrite
-    dmx-mmap
-    dmx-munmap
-    dmx-start
-    dmx-stop
-    dmx-set-filter
-    dmx-set-pes-filter
-    dmx-set-buffer-size
-    dmx-get-stc
-    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/dmx_types.rst b/Documentation/media/uapi/dvb/dmx_types.rst
deleted file mode 100644
index b5cf704199e5..000000000000
--- a/Documentation/media/uapi/dvb/dmx_types.rst
+++ /dev/null
@@ -1,16 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _dmx_types:
-
-****************
-Demux Data Types
-****************
-
-.. kernel-doc:: include/uapi/linux/dvb/dmx.h
diff --git a/Documentation/media/uapi/dvb/dvb-fe-read-status.rst b/Documentation/media/uapi/dvb/dvb-fe-read-status.rst
deleted file mode 100644
index 172783b75fb7..000000000000
--- a/Documentation/media/uapi/dvb/dvb-fe-read-status.rst
+++ /dev/null
@@ -1,32 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _dvb-fe-read-status:
-
-***************************************
-Querying frontend status and statistics
-***************************************
-
-Once :ref:`FE_SET_PROPERTY <FE_GET_PROPERTY>` is called, the
-frontend will run a kernel thread that will periodically check for the
-tuner lock status and provide statistics about the quality of the
-signal.
-
-The information about the frontend tuner locking status can be queried
-using :ref:`FE_READ_STATUS`.
-
-Signal statistics are provided via
-:ref:`FE_GET_PROPERTY`.
-
-.. note::
-
-   Most statistics require the demodulator to be fully locked
-   (e. g. with :c:type:`FE_HAS_LOCK <fe_status>` bit set). See
-   :ref:`Frontend statistics indicators <frontend-stat-properties>` for
-   more details.
diff --git a/Documentation/media/uapi/dvb/dvb-frontend-event.rst b/Documentation/media/uapi/dvb/dvb-frontend-event.rst
deleted file mode 100644
index ad4af66040c7..000000000000
--- a/Documentation/media/uapi/dvb/dvb-frontend-event.rst
+++ /dev/null
@@ -1,22 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. c:type:: dvb_frontend_event
-
-***************
-frontend events
-***************
-
-
-.. code-block:: c
-
-     struct dvb_frontend_event {
-	 fe_status_t status;
-	 struct dvb_frontend_parameters parameters;
-     };
diff --git a/Documentation/media/uapi/dvb/dvb-frontend-parameters.rst b/Documentation/media/uapi/dvb/dvb-frontend-parameters.rst
deleted file mode 100644
index 67c2a316019f..000000000000
--- a/Documentation/media/uapi/dvb/dvb-frontend-parameters.rst
+++ /dev/null
@@ -1,126 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. c:type:: dvb_frontend_parameters
-
-*******************
-frontend parameters
-*******************
-
-The kind of parameters passed to the frontend device for tuning depend
-on the kind of hardware you are using.
-
-The struct ``dvb_frontend_parameters`` uses a union with specific
-per-system parameters. However, as newer delivery systems required more
-data, the structure size weren't enough to fit, and just extending its
-size would break the existing applications. So, those parameters were
-replaced by the usage of
-:ref:`FE_GET_PROPERTY/FE_SET_PROPERTY <FE_GET_PROPERTY>`
-ioctl's. The new API is flexible enough to add new parameters to
-existing delivery systems, and to add newer delivery systems.
-
-So, newer applications should use
-:ref:`FE_GET_PROPERTY/FE_SET_PROPERTY <FE_GET_PROPERTY>`
-instead, in order to be able to support the newer System Delivery like
-DVB-S2, DVB-T2, DVB-C2, ISDB, etc.
-
-All kinds of parameters are combined as a union in the
-``dvb_frontend_parameters`` structure:
-
-
-.. code-block:: c
-
-    struct dvb_frontend_parameters {
-	uint32_t frequency;     /* (absolute) frequency in Hz for QAM/OFDM */
-		    /* intermediate frequency in kHz for QPSK */
-	fe_spectral_inversion_t inversion;
-	union {
-	    struct dvb_qpsk_parameters qpsk;
-	    struct dvb_qam_parameters  qam;
-	    struct dvb_ofdm_parameters ofdm;
-	    struct dvb_vsb_parameters  vsb;
-	} u;
-    };
-
-In the case of QPSK frontends the ``frequency`` field specifies the
-intermediate frequency, i.e. the offset which is effectively added to
-the local oscillator frequency (LOF) of the LNB. The intermediate
-frequency has to be specified in units of kHz. For QAM and OFDM
-frontends the ``frequency`` specifies the absolute frequency and is
-given in Hz.
-
-
-.. c:type:: dvb_qpsk_parameters
-
-QPSK parameters
-===============
-
-For satellite QPSK frontends you have to use the ``dvb_qpsk_parameters``
-structure:
-
-
-.. code-block:: c
-
-     struct dvb_qpsk_parameters {
-	 uint32_t        symbol_rate;  /* symbol rate in Symbols per second */
-	 fe_code_rate_t  fec_inner;    /* forward error correction (see above) */
-     };
-
-
-.. c:type:: dvb_qam_parameters
-
-QAM parameters
-==============
-
-for cable QAM frontend you use the ``dvb_qam_parameters`` structure:
-
-
-.. code-block:: c
-
-     struct dvb_qam_parameters {
-	 uint32_t         symbol_rate; /* symbol rate in Symbols per second */
-	 fe_code_rate_t   fec_inner;   /* forward error correction (see above) */
-	 fe_modulation_t  modulation;  /* modulation type (see above) */
-     };
-
-
-.. c:type:: dvb_vsb_parameters
-
-VSB parameters
-==============
-
-ATSC frontends are supported by the ``dvb_vsb_parameters`` structure:
-
-
-.. code-block:: c
-
-    struct dvb_vsb_parameters {
-	fe_modulation_t modulation; /* modulation type (see above) */
-    };
-
-
-.. c:type:: dvb_ofdm_parameters
-
-OFDM parameters
-===============
-
-DVB-T frontends are supported by the ``dvb_ofdm_parameters`` structure:
-
-
-.. code-block:: c
-
-     struct dvb_ofdm_parameters {
-	 fe_bandwidth_t      bandwidth;
-	 fe_code_rate_t      code_rate_HP;  /* high priority stream code rate */
-	 fe_code_rate_t      code_rate_LP;  /* low priority stream code rate */
-	 fe_modulation_t     constellation; /* modulation type (see above) */
-	 fe_transmit_mode_t  transmission_mode;
-	 fe_guard_interval_t guard_interval;
-	 fe_hierarchy_t      hierarchy_information;
-     };
diff --git a/Documentation/media/uapi/dvb/dvbapi.rst b/Documentation/media/uapi/dvb/dvbapi.rst
deleted file mode 100644
index 0fcc01f182f9..000000000000
--- a/Documentation/media/uapi/dvb/dvbapi.rst
+++ /dev/null
@@ -1,126 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. include:: <isonum.txt>
-
-.. _dvbapi:
-
-########################
-Part II - Digital TV API
-########################
-
-.. note::
-
-   This API is also known as Linux **DVB API**.
-
-   It it was originally written to support the European digital TV
-   standard (DVB), and later extended to support all digital TV standards.
-
-   In order to avoid confusion, within this document, it was opted to refer to
-   it, and to associated hardware as **Digital TV**.
-
-   The word **DVB** is reserved to be used for:
-
-     - the Digital TV API version
-       (e. g. DVB API version 3 or DVB API version 5);
-     - digital TV data types (enums, structs, defines, etc);
-     - digital TV device nodes (``/dev/dvb/...``);
-     - the European DVB standard.
-
-**Version 5.10**
-
-.. only:: html
-
-   .. class:: toc-title
-
-        Table of Contents
-
-.. toctree::
-    :maxdepth: 5
-    :numbered:
-
-    intro
-    frontend
-    demux
-    ca
-    net
-    legacy_dvb_apis
-    examples
-    headers
-
-
-**********************
-Revision and Copyright
-**********************
-
-Authors:
-
-- J. K. Metzler, Ralph <rjkm@metzlerbros.de>
-
- - Original author of the Digital TV API documentation.
-
-- O. C. Metzler, Marcus <rjkm@metzlerbros.de>
-
- - Original author of the Digital TV API documentation.
-
-- Carvalho Chehab, Mauro <mchehab+samsung@kernel.org>
-
- - Ported document to Docbook XML, addition of DVBv5 API, documentation gaps fix.
-
-**Copyright** |copy| 2002-2003 : Convergence GmbH
-
-**Copyright** |copy| 2009-2017 : Mauro Carvalho Chehab
-
-****************
-Revision History
-****************
-
-:revision: 2.2.0 / 2017-09-01 (*mcc*)
-
-Most gaps between the uAPI document and the Kernel implementation
-got fixed for the non-legacy API.
-
-:revision: 2.1.0 / 2015-05-29 (*mcc*)
-
-DocBook improvements and cleanups, in order to document the system calls
-on a more standard way and provide more description about the current
-Digital TV API.
-
-:revision: 2.0.4 / 2011-05-06 (*mcc*)
-
-Add more information about DVBv5 API, better describing the frontend
-GET/SET props ioctl's.
-
-
-:revision: 2.0.3 / 2010-07-03 (*mcc*)
-
-Add some frontend capabilities flags, present on kernel, but missing at
-the specs.
-
-
-:revision: 2.0.2 / 2009-10-25 (*mcc*)
-
-documents FE_SET_FRONTEND_TUNE_MODE and
-FE_DISHETWORK_SEND_LEGACY_CMD ioctls.
-
-
-:revision: 2.0.1 / 2009-09-16 (*mcc*)
-
-Added ISDB-T test originally written by Patrick Boettcher
-
-
-:revision: 2.0.0 / 2009-09-06 (*mcc*)
-
-Conversion from LaTex to DocBook XML. The contents is the same as the
-original LaTex version.
-
-
-:revision: 1.0.0 / 2003-07-24 (*rjkm*)
-
-Initial revision on LaTEX.
diff --git a/Documentation/media/uapi/dvb/dvbproperty.rst b/Documentation/media/uapi/dvb/dvbproperty.rst
deleted file mode 100644
index 0c4f5598f2be..000000000000
--- a/Documentation/media/uapi/dvb/dvbproperty.rst
+++ /dev/null
@@ -1,133 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _frontend-properties:
-
-**************
-Property types
-**************
-
-Tuning into a Digital TV physical channel and starting decoding it
-requires changing a set of parameters, in order to control the tuner,
-the demodulator, the Linear Low-noise Amplifier (LNA) and to set the
-antenna subsystem via Satellite Equipment Control - SEC (on satellite
-systems). The actual parameters are specific to each particular digital
-TV standards, and may change as the digital TV specs evolves.
-
-In the past (up to DVB API version 3 - DVBv3), the strategy used was to have a
-union with the parameters needed to tune for DVB-S, DVB-C, DVB-T and
-ATSC delivery systems grouped there. The problem is that, as the second
-generation standards appeared, the size of such union was not big
-enough to group the structs that would be required for those new
-standards. Also, extending it would break userspace.
-
-So, the legacy union/struct based approach was deprecated, in favor
-of a properties set approach. On such approach,
-:ref:`FE_GET_PROPERTY and FE_SET_PROPERTY <FE_GET_PROPERTY>` are used
-to setup the frontend and read its status.
-
-The actual action is determined by a set of dtv_property cmd/data pairs.
-With one single ioctl, is possible to get/set up to 64 properties.
-
-This section describes the new and recommended way to set the frontend,
-with supports all digital TV delivery systems.
-
-.. note::
-
-   1. On Linux DVB API version 3, setting a frontend was done via
-      struct :c:type:`dvb_frontend_parameters`.
-
-   2. Don't use DVB API version 3 calls on hardware with supports
-      newer standards. Such API provides no support or a very limited
-      support to new standards and/or new hardware.
-
-   3. Nowadays, most frontends support multiple delivery systems.
-      Only with DVB API version 5 calls it is possible to switch between
-      the multiple delivery systems supported by a frontend.
-
-   4. DVB API version 5 is also called *S2API*, as the first
-      new standard added to it was DVB-S2.
-
-**Example**: in order to set the hardware to tune into a DVB-C channel
-at 651 kHz, modulated with 256-QAM, FEC 3/4 and symbol rate of 5.217
-Mbauds, those properties should be sent to
-:ref:`FE_SET_PROPERTY <FE_GET_PROPERTY>` ioctl:
-
-  :ref:`DTV_DELIVERY_SYSTEM <DTV-DELIVERY-SYSTEM>` = SYS_DVBC_ANNEX_A
-
-  :ref:`DTV_FREQUENCY <DTV-FREQUENCY>` = 651000000
-
-  :ref:`DTV_MODULATION <DTV-MODULATION>` = QAM_256
-
-  :ref:`DTV_INVERSION <DTV-INVERSION>` = INVERSION_AUTO
-
-  :ref:`DTV_SYMBOL_RATE <DTV-SYMBOL-RATE>` = 5217000
-
-  :ref:`DTV_INNER_FEC <DTV-INNER-FEC>` = FEC_3_4
-
-  :ref:`DTV_TUNE <DTV-TUNE>`
-
-The code that would that would do the above is show in
-:ref:`dtv-prop-example`.
-
-.. code-block:: c
-    :caption: Example: Setting digital TV frontend properties
-    :name: dtv-prop-example
-
-    #include <stdio.h>
-    #include <fcntl.h>
-    #include <sys/ioctl.h>
-    #include <linux/dvb/frontend.h>
-
-    static struct dtv_property props[] = {
-	{ .cmd = DTV_DELIVERY_SYSTEM, .u.data = SYS_DVBC_ANNEX_A },
-	{ .cmd = DTV_FREQUENCY,       .u.data = 651000000 },
-	{ .cmd = DTV_MODULATION,      .u.data = QAM_256 },
-	{ .cmd = DTV_INVERSION,       .u.data = INVERSION_AUTO },
-	{ .cmd = DTV_SYMBOL_RATE,     .u.data = 5217000 },
-	{ .cmd = DTV_INNER_FEC,       .u.data = FEC_3_4 },
-	{ .cmd = DTV_TUNE }
-    };
-
-    static struct dtv_properties dtv_prop = {
-	.num = 6, .props = props
-    };
-
-    int main(void)
-    {
-	int fd = open("/dev/dvb/adapter0/frontend0", O_RDWR);
-
-	if (!fd) {
-	    perror ("open");
-	    return -1;
-	}
-	if (ioctl(fd, FE_SET_PROPERTY, &dtv_prop) == -1) {
-	    perror("ioctl");
-	    return -1;
-	}
-	printf("Frontend set\\n");
-	return 0;
-    }
-
-.. attention:: While it is possible to directly call the Kernel code like the
-   above example, it is strongly recommended to use
-   `libdvbv5 <https://linuxtv.org/docs/libdvbv5/index.html>`__, as it
-   provides abstraction to work with the supported digital TV standards and
-   provides methods for usual operations like program scanning and to
-   read/write channel descriptor files.
-
-.. toctree::
-    :maxdepth: 1
-
-    fe_property_parameters
-    frontend-stat-properties
-    frontend-property-terrestrial-systems
-    frontend-property-cable-systems
-    frontend-property-satellite-systems
-    frontend-header
diff --git a/Documentation/media/uapi/dvb/dvbstb.svg b/Documentation/media/uapi/dvb/dvbstb.svg
deleted file mode 100644
index c7672148d6ff..000000000000
--- a/Documentation/media/uapi/dvb/dvbstb.svg
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-    This file is dual-licensed: you can use it either under the terms
-    of the GPL 2.0 or the GFDL 1.1+ license, at your option. Note that this
-    dual licensing only applies to this file, and not this project as a
-    whole.
-
-    a) This file is free software; you can redistribute it and/or
-       modify it under the terms of the GNU General Public License as
-       published by the Free Software Foundation version 2 of
-       the License.
-
-       This file is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-    Or, alternatively,
-
-    b) Permission is granted to copy, distribute and/or modify this
-       document under the terms of the GNU Free Documentation License,
-       Version 1.1 or any later version published by the Free Software
-       Foundation, with no Invariant Sections, no Front-Cover Texts
-       and no Back-Cover Texts. A copy of the license is included at
-       Documentation/media/uapi/fdl-appendix.rst.
-
-    TODO: replace it to GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
--->
-<svg id="svg2" width="15.847cm" height="8.4187cm" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" preserveAspectRatio="xMidYMid" version="1.2" viewBox="0 0 23770.123 12628.122" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><defs id="defs142"><marker id="Arrow1Lend" overflow="visible" orient="auto"><path id="path954" transform="matrix(-.8 0 0 -.8 -10 0)" d="m0 0 5-5-17.5 5 17.5 5z" fill-rule="evenodd" stroke="#000" stroke-width="1pt"/></marker><marker id="marker1243" overflow="visible" orient="auto"><path id="path1241" transform="matrix(-.8 0 0 -.8 -10 0)" d="m0 0 5-5-17.5 5 17.5 5z" fill-rule="evenodd" stroke="#000" stroke-width="1pt"/></marker></defs><metadata id="metadata519"><rdf:RDF><cc:Work
-rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title/></cc:Work></rdf:RDF></metadata><rect id="rect197" class="BoundingBox" x="5355.1" y="13.122" width="18403" height="9603" fill="none"/><path id="path199" d="m14556 9614.1h-9200v-9600h18400v9600z" fill="#fff"/><path id="path201" d="m14556 9614.1h-9200v-9600h18400v9600z" fill="none" stroke="#000"/><rect id="rect206" class="BoundingBox" x="13.122" y="4013.1" width="4544" height="2403" fill="none"/><path id="path208" d="m2285.1 6414.1h-2271v-2400h4541v2400z" fill="#fff"/><path id="path210" d="m2285.1 6414.1h-2271v-2400h4541v2400z" fill="none" stroke="#000"/><text id="text212" class="TextShape" x="-2443.8779" y="-4585.8779"><tspan id="tspan214" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan216" class="TextPosition"
-x="1281.1219" y="5435.1221"><tspan id="tspan218" fill="#000000">Antena</tspan></tspan></tspan></text>
-<rect id="rect223" class="BoundingBox" x="6213.1" y="1813.1" width="4544" height="2403" fill="none"/><path id="path225" d="m8485.1 4214.1h-2271v-2400h4541v2400z" fill="#fff"/><path id="path227" d="m8485.1 4214.1h-2271v-2400h4541v2400z" fill="none" stroke="#000"/><text id="text229" class="TextShape" x="-2443.8779" y="-4585.8779"><tspan id="tspan231" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan233" class="TextPosition" x="7217.1221" y="3235.1221"><tspan id="tspan235" fill="#000000">Frontend</tspan></tspan></tspan></text>
-<rect id="rect240" class="BoundingBox" x="12113" y="1813.1" width="4544" height="2403" fill="none"/><path id="path242" d="m14385 4214.1h-2271v-2400h4541v2400z" fill="#fff"/><path id="path244" d="m14385 4214.1h-2271v-2400h4541v2400z" fill="none" stroke="#000"/><text id="text246" class="TextShape" x="-2443.8779" y="-4585.8779"><tspan id="tspan248" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan250" class="TextPosition" x="13944.122" y="3235.1221"><tspan id="tspan252" fill="#000000">CA</tspan></tspan></tspan></text>
-<rect id="rect257" class="BoundingBox" x="18113" y="1813.1" width="4544" height="2403" fill="none"/><path id="path259" d="m20385 4214.1h-2271v-2400h4541v2400z" fill="#fff"/><path id="path261" d="m20385 4214.1h-2271v-2400h4541v2400z" fill="none" stroke="#000"/><text id="text263" class="TextShape" x="-2443.8779" y="-4585.8779"><tspan id="tspan265" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan267" class="TextPosition" x="19384.123" y="3235.1221"><tspan id="tspan269" fill="#000000">Demux</tspan></tspan></tspan></text>
-<rect id="rect274" class="BoundingBox" x="6113.1" y="5813.1" width="4544" height="2403" fill="none"/><path id="path276" d="m8385.1 8214.1h-2271v-2400h4541v2400z" fill="#fff"/><path id="path278" d="m8385.1 8214.1h-2271v-2400h4541v2400z" fill="none" stroke="#000"/><text id="text280" class="TextShape" x="-2443.8779" y="-4585.8779"><tspan id="tspan282" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan284" class="TextPosition" x="7733.1221" y="7235.1221"><tspan id="tspan286" fill="#000000">SEC</tspan></tspan></tspan></text>
-<rect id="rect291" class="BoundingBox" x="12213" y="5813.1" width="4544" height="2403" fill="none"/><path id="path293" d="m14485 8214.1h-2271v-2400h4541v2400z" fill="#fff"/><path id="path295" d="m14485 8214.1h-2271v-2400h4541v2400z" fill="none" stroke="#000" stroke-dasharray="28.22200113,56.44400226" stroke-width="28.222"/><text id="text297" class="TextShape" x="-2443.8779" y="-4903.3779"><tspan id="tspan299" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan301" class="TextPosition" x="13676.122" y="6917.6221"><tspan id="tspan303" fill="#000000">Audio</tspan></tspan></tspan></text>
-<rect id="rect308" class="BoundingBox" x="18113" y="5813.1" width="4544" height="2403" fill="none"/><path id="path310" d="m20385 8214.1h-2271v-2400h4541v2400z" fill="#fff"/><path id="path312" d="m20385 8214.1h-2271v-2400h4541v2400z" fill="none" stroke="#000" stroke-dasharray="28.22200113,56.44400226" stroke-width="28.222"/><text id="text314" class="TextShape" x="-2443.8779" y="-4903.3779"><tspan id="tspan316" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan318" class="TextPosition" x="19583.123" y="6917.6221"><tspan id="tspan320" fill="#000000">Video</tspan></tspan></tspan></text>
-<rect id="rect325" class="BoundingBox" x="15213" y="10213" width="4544" height="2403" fill="none"/><path id="path327" d="m17485 12614h-2271v-2400h4541v2400z" fill="#fff"/><path id="path329" d="m17485 12614h-2271v-2400h4541v2400z" fill="none" stroke="#000" stroke-dasharray="28.22200113,56.44400226" stroke-width="28.222"/><text id="text331" class="TextShape" x="-2443.8779" y="-4585.8779"><tspan id="tspan333" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan335" class="TextPosition" x="17076.123" y="11635.122"><tspan id="tspan337" fill="#000000">TV</tspan></tspan></tspan></text>
-<rect id="rect342" class="BoundingBox" x="4555.1" y="3014.1" width="1661" height="2202" fill="none"/><path id="path344" d="m4556.1 5214.1 1400-1857" fill="none" stroke="#000"/><path id="path346" d="m6215.1 3014.1-391 269 240 181z"/><rect id="rect351" class="BoundingBox" x="4555.1" y="5213.1" width="1561" height="1802" fill="none"/><path id="path353" d="m4556.1 5214.1 1277 1475" fill="none" stroke="#000"/><path id="path355" d="m6115.1 7014.1-181-438-227 196z"/><rect id="rect360" class="BoundingBox" x="10755" y="2864.1" width="1361" height="301" fill="none"/><path id="path362" d="m10756 3014.1h929" fill="none" stroke="#000"/><path id="path364" d="m12115 3014.1-450-150v300z"/><rect id="rect369" class="BoundingBox" x="16655" y="2864.1" width="1461" height="301" fill="none"/><path id="path371" d="m16656 3014.1h1029" fill="none" stroke="#000"/><path id="path373" d="m18115
-3014.1-450-150v300z"/><rect id="rect378" class="BoundingBox" x="20235" y="4213.1" width="301" height="1602" fill="none"/><rect id="rect387" class="BoundingBox" x="17485" y="8213.1" width="2902" height="2002" fill="none"/><path id="path389" d="m20385 8214.1-2546 1756" fill="none" stroke="#000" stroke-dasharray="28.22200113,56.44400226" stroke-width="28.222"/><path id="path391" d="m17485 10214 456-132-171-247z"/><rect id="rect396" class="BoundingBox" x="14484" y="8213.1" width="3002" height="2002" fill="none"/><path id="path398" d="m14485 8214.1 2642 1761" fill="none" stroke="#000" stroke-dasharray="28.22200113,56.44400226" stroke-width="28.222"/><path id="path400" d="m17485 10214-291-374-167 249z"/><rect id="rect405" class="BoundingBox" x="14485" y="4213.1" width="5902" height="1629" fill="none"/><path id="path949" d="m20387 4213.1v1629" fill="none" marker-end="url(#Arrow1Lend)"
-stroke="#000" stroke-dasharray="26.45879596, 52.91759192999999328" stroke-linejoin="miter" stroke-width="26.459"/><path id="path1233" d="m20385 4214.1-3628 1599" fill="none" marker-end="url(#marker1243)" stroke="#000" stroke-dasharray="26.45879596, 52.91759193" stroke-linejoin="miter" stroke-width="26.459"/><text id="text297-3" class="TextShape" x="-2911.9202" y="-4257.2061" font-size="12px" stroke-width="1"><tspan id="tspan299-6" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400" stroke-width="1"><tspan id="tspan301-7" class="TextPosition" x="13208.079" y="7563.793" stroke-width="1"><tspan id="tspan303-5" fill="#000000" stroke-width="1">Decoder</tspan></tspan></tspan></text>
-<text id="text297-3-3" class="TextShape" x="2950.9287" y="-4259.5928" font-size="12px" stroke-width="1"><tspan id="tspan299-6-5" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400" stroke-width="1"><tspan id="tspan301-7-6" class="TextPosition" x="19070.928" y="7561.4053" stroke-width="1"><tspan id="tspan303-5-2" fill="#000000" stroke-width="1">Decoder</tspan></tspan></tspan></text>
-</svg>
diff --git a/Documentation/media/uapi/dvb/examples.rst b/Documentation/media/uapi/dvb/examples.rst
deleted file mode 100644
index eaa41bc8d173..000000000000
--- a/Documentation/media/uapi/dvb/examples.rst
+++ /dev/null
@@ -1,23 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _dvb_examples:
-
-********
-Examples
-********
-
-In the past, we used to have a set of examples here. However, those
-examples got out of date and doesn't even compile nowadays.
-
-Also, nowadays, the best is to use the libdvbv5 DVB API nowadays,
-with is fully documented.
-
-Please refer to the `libdvbv5 <https://linuxtv.org/docs/libdvbv5/index.html>`__
-for updated/recommended examples.
diff --git a/Documentation/media/uapi/dvb/fe-bandwidth-t.rst b/Documentation/media/uapi/dvb/fe-bandwidth-t.rst
deleted file mode 100644
index c3d7837b5f87..000000000000
--- a/Documentation/media/uapi/dvb/fe-bandwidth-t.rst
+++ /dev/null
@@ -1,81 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-******************
-Frontend bandwidth
-******************
-
-.. c:type:: fe_bandwidth
-
-.. flat-table:: enum fe_bandwidth
-    :header-rows:  1
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  ID
-
-       -  Description
-
-    -  .. row 2
-
-       -  .. _BANDWIDTH-AUTO:
-
-	  ``BANDWIDTH_AUTO``
-
-       -  Autodetect bandwidth (if supported)
-
-    -  .. row 3
-
-       -  .. _BANDWIDTH-1-712-MHZ:
-
-	  ``BANDWIDTH_1_712_MHZ``
-
-       -  1.712 MHz
-
-    -  .. row 4
-
-       -  .. _BANDWIDTH-5-MHZ:
-
-	  ``BANDWIDTH_5_MHZ``
-
-       -  5 MHz
-
-    -  .. row 5
-
-       -  .. _BANDWIDTH-6-MHZ:
-
-	  ``BANDWIDTH_6_MHZ``
-
-       -  6 MHz
-
-    -  .. row 6
-
-       -  .. _BANDWIDTH-7-MHZ:
-
-	  ``BANDWIDTH_7_MHZ``
-
-       -  7 MHz
-
-    -  .. row 7
-
-       -  .. _BANDWIDTH-8-MHZ:
-
-	  ``BANDWIDTH_8_MHZ``
-
-       -  8 MHz
-
-    -  .. row 8
-
-       -  .. _BANDWIDTH-10-MHZ:
-
-	  ``BANDWIDTH_10_MHZ``
-
-       -  10 MHz
diff --git a/Documentation/media/uapi/dvb/fe-diseqc-recv-slave-reply.rst b/Documentation/media/uapi/dvb/fe-diseqc-recv-slave-reply.rst
deleted file mode 100644
index 88fd2186ca4d..000000000000
--- a/Documentation/media/uapi/dvb/fe-diseqc-recv-slave-reply.rst
+++ /dev/null
@@ -1,55 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _FE_DISEQC_RECV_SLAVE_REPLY:
-
-********************************
-ioctl FE_DISEQC_RECV_SLAVE_REPLY
-********************************
-
-Name
-====
-
-FE_DISEQC_RECV_SLAVE_REPLY - Receives reply from a DiSEqC 2.0 command
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, FE_DISEQC_RECV_SLAVE_REPLY, struct dvb_diseqc_slave_reply *argp )
-    :name: FE_DISEQC_RECV_SLAVE_REPLY
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <frontend_f_open>`.
-
-``argp``
-    pointer to struct :c:type:`dvb_diseqc_slave_reply`.
-
-
-Description
-===========
-
-Receives reply from a DiSEqC 2.0 command.
-
-The received message is stored at the buffer pointed by ``argp``.
-
-Return Value
-============
-
-On success 0 is returned.
-
-On error -1 is returned, and the ``errno`` variable is set
-appropriately.
-
-Generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/media/uapi/dvb/fe-diseqc-reset-overload.rst b/Documentation/media/uapi/dvb/fe-diseqc-reset-overload.rst
deleted file mode 100644
index 92929c2e75db..000000000000
--- a/Documentation/media/uapi/dvb/fe-diseqc-reset-overload.rst
+++ /dev/null
@@ -1,53 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _FE_DISEQC_RESET_OVERLOAD:
-
-******************************
-ioctl FE_DISEQC_RESET_OVERLOAD
-******************************
-
-Name
-====
-
-FE_DISEQC_RESET_OVERLOAD - Restores the power to the antenna subsystem, if it was powered off due - to power overload.
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, FE_DISEQC_RESET_OVERLOAD, NULL )
-    :name: FE_DISEQC_RESET_OVERLOAD
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <frontend_f_open>`.
-
-Description
-===========
-
-If the bus has been automatically powered off due to power overload,
-this ioctl call restores the power to the bus. The call requires
-read/write access to the device. This call has no effect if the device
-is manually powered off. Not all Digital TV adapters support this ioctl.
-
-
-Return Value
-============
-
-On success 0 is returned.
-
-On error -1 is returned, and the ``errno`` variable is set
-appropriately.
-
-Generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/media/uapi/dvb/fe-diseqc-send-burst.rst b/Documentation/media/uapi/dvb/fe-diseqc-send-burst.rst
deleted file mode 100644
index 8af872d306aa..000000000000
--- a/Documentation/media/uapi/dvb/fe-diseqc-send-burst.rst
+++ /dev/null
@@ -1,59 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _FE_DISEQC_SEND_BURST:
-
-**************************
-ioctl FE_DISEQC_SEND_BURST
-**************************
-
-Name
-====
-
-FE_DISEQC_SEND_BURST - Sends a 22KHz tone burst for 2x1 mini DiSEqC satellite selection.
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, FE_DISEQC_SEND_BURST, enum fe_sec_mini_cmd tone )
-    :name: FE_DISEQC_SEND_BURST
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <frontend_f_open>`.
-
-``tone``
-    An integer enumered value described at :c:type:`fe_sec_mini_cmd`.
-
-
-Description
-===========
-
-This ioctl is used to set the generation of a 22kHz tone burst for mini
-DiSEqC satellite selection for 2x1 switches. This call requires
-read/write permissions.
-
-It provides support for what's specified at
-`Digital Satellite Equipment Control (DiSEqC) - Simple "ToneBurst" Detection Circuit specification. <http://www.eutelsat.com/files/contributed/satellites/pdf/Diseqc/associated%20docs/simple_tone_burst_detec.pdf>`__
-
-
-Return Value
-============
-
-On success 0 is returned.
-
-On error -1 is returned, and the ``errno`` variable is set
-appropriately.
-
-Generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/media/uapi/dvb/fe-diseqc-send-master-cmd.rst b/Documentation/media/uapi/dvb/fe-diseqc-send-master-cmd.rst
deleted file mode 100644
index 30a48114153c..000000000000
--- a/Documentation/media/uapi/dvb/fe-diseqc-send-master-cmd.rst
+++ /dev/null
@@ -1,56 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _FE_DISEQC_SEND_MASTER_CMD:
-
-*******************************
-ioctl FE_DISEQC_SEND_MASTER_CMD
-*******************************
-
-Name
-====
-
-FE_DISEQC_SEND_MASTER_CMD - Sends a DiSEqC command
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, FE_DISEQC_SEND_MASTER_CMD, struct dvb_diseqc_master_cmd *argp )
-    :name: FE_DISEQC_SEND_MASTER_CMD
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <frontend_f_open>`.
-
-``argp``
-    pointer to struct
-    :c:type:`dvb_diseqc_master_cmd`
-
-
-Description
-===========
-
-Sends the DiSEqC command pointed by :c:type:`dvb_diseqc_master_cmd`
-to the antenna subsystem.
-
-Return Value
-============
-
-On success 0 is returned.
-
-On error -1 is returned, and the ``errno`` variable is set
-appropriately.
-
-Generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
-
diff --git a/Documentation/media/uapi/dvb/fe-dishnetwork-send-legacy-cmd.rst b/Documentation/media/uapi/dvb/fe-dishnetwork-send-legacy-cmd.rst
deleted file mode 100644
index 13811289971b..000000000000
--- a/Documentation/media/uapi/dvb/fe-dishnetwork-send-legacy-cmd.rst
+++ /dev/null
@@ -1,62 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _FE_DISHNETWORK_SEND_LEGACY_CMD:
-
-******************************
-FE_DISHNETWORK_SEND_LEGACY_CMD
-******************************
-
-Name
-====
-
-FE_DISHNETWORK_SEND_LEGACY_CMD
-
-
-Synopsis
-========
-
-.. c:function:: int  ioctl(int fd, FE_DISHNETWORK_SEND_LEGACY_CMD, unsigned long cmd)
-    :name: FE_DISHNETWORK_SEND_LEGACY_CMD
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :c:func:`open() <dvb-fe-open>`.
-
-``cmd``
-    Sends the specified raw cmd to the dish via DISEqC.
-
-
-Description
-===========
-
-.. warning::
-   This is a very obscure legacy command, used only at stv0299
-   driver. Should not be used on newer drivers.
-
-It provides a non-standard method for selecting Diseqc voltage on the
-frontend, for Dish Network legacy switches.
-
-As support for this ioctl were added in 2004, this means that such
-dishes were already legacy in 2004.
-
-
-Return Value
-============
-
-On success 0 is returned.
-
-On error -1 is returned, and the ``errno`` variable is set
-appropriately.
-
-Generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/media/uapi/dvb/fe-enable-high-lnb-voltage.rst b/Documentation/media/uapi/dvb/fe-enable-high-lnb-voltage.rst
deleted file mode 100644
index 32b7d140d80b..000000000000
--- a/Documentation/media/uapi/dvb/fe-enable-high-lnb-voltage.rst
+++ /dev/null
@@ -1,61 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _FE_ENABLE_HIGH_LNB_VOLTAGE:
-
-********************************
-ioctl FE_ENABLE_HIGH_LNB_VOLTAGE
-********************************
-
-Name
-====
-
-FE_ENABLE_HIGH_LNB_VOLTAGE - Select output DC level between normal LNBf voltages or higher LNBf - voltages.
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, FE_ENABLE_HIGH_LNB_VOLTAGE, unsigned int high )
-    :name: FE_ENABLE_HIGH_LNB_VOLTAGE
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <frontend_f_open>`.
-
-``high``
-    Valid flags:
-
-    -  0 - normal 13V and 18V.
-
-    -  >0 - enables slightly higher voltages instead of 13/18V, in order
-       to compensate for long antenna cables.
-
-
-Description
-===========
-
-Select output DC level between normal LNBf voltages or higher LNBf
-voltages between 0 (normal) or a value grater than 0 for higher
-voltages.
-
-
-Return Value
-============
-
-On success 0 is returned.
-
-On error -1 is returned, and the ``errno`` variable is set
-appropriately.
-
-Generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/media/uapi/dvb/fe-get-event.rst b/Documentation/media/uapi/dvb/fe-get-event.rst
deleted file mode 100644
index 2573d5b9b636..000000000000
--- a/Documentation/media/uapi/dvb/fe-get-event.rst
+++ /dev/null
@@ -1,78 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _FE_GET_EVENT:
-
-************
-FE_GET_EVENT
-************
-
-Name
-====
-
-FE_GET_EVENT
-
-.. attention:: This ioctl is deprecated.
-
-
-Synopsis
-========
-
-.. c:function:: int  ioctl(int fd, FE_GET_EVENT, struct dvb_frontend_event *ev)
-    :name: FE_GET_EVENT
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :c:func:`open() <dvb-fe-open>`.
-
-``ev``
-    Points to the location where the event, if any, is to be stored.
-
-
-Description
-===========
-
-This ioctl call returns a frontend event if available. If an event is
-not available, the behavior depends on whether the device is in blocking
-or non-blocking mode. In the latter case, the call fails immediately
-with errno set to ``EWOULDBLOCK``. In the former case, the call blocks until
-an event becomes available.
-
-
-Return Value
-============
-
-On success 0 is returned.
-
-On error -1 is returned, and the ``errno`` variable is set
-appropriately.
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  ``EWOULDBLOCK``
-
-       -  There is no event pending, and the device is in non-blocking mode.
-
-    -  .. row 2
-
-       -  ``EOVERFLOW``
-
-       -  Overflow in event queue - one or more events were lost.
-
-Generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/media/uapi/dvb/fe-get-frontend.rst b/Documentation/media/uapi/dvb/fe-get-frontend.rst
deleted file mode 100644
index 6cd5250d1832..000000000000
--- a/Documentation/media/uapi/dvb/fe-get-frontend.rst
+++ /dev/null
@@ -1,69 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _FE_GET_FRONTEND:
-
-***************
-FE_GET_FRONTEND
-***************
-
-Name
-====
-
-FE_GET_FRONTEND
-
-.. attention:: This ioctl is deprecated.
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl(int fd, FE_GET_FRONTEND, struct dvb_frontend_parameters *p)
-    :name: FE_GET_FRONTEND
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :c:func:`open() <dvb-fe-open>`.
-
-
-``p``
-    Points to parameters for tuning operation.
-
-
-Description
-===========
-
-This ioctl call queries the currently effective frontend parameters. For
-this command, read-only access to the device is sufficient.
-
-
-Return Value
-============
-
-On success 0 is returned.
-
-On error -1 is returned, and the ``errno`` variable is set
-appropriately.
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  ``EINVAL``
-
-       -  Maximum supported symbol rate reached.
-
-Generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/media/uapi/dvb/fe-get-info.rst b/Documentation/media/uapi/dvb/fe-get-info.rst
deleted file mode 100644
index 551e68b11528..000000000000
--- a/Documentation/media/uapi/dvb/fe-get-info.rst
+++ /dev/null
@@ -1,70 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _FE_GET_INFO:
-
-*****************
-ioctl FE_GET_INFO
-*****************
-
-Name
-====
-
-FE_GET_INFO - Query Digital TV frontend capabilities and returns information
-about the - front-end. This call only requires read-only access to the device.
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, FE_GET_INFO, struct dvb_frontend_info *argp )
-    :name: FE_GET_INFO
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <frontend_f_open>`.
-
-``argp``
-    pointer to struct struct
-    :c:type:`dvb_frontend_info`
-
-
-Description
-===========
-
-All Digital TV frontend devices support the :ref:`FE_GET_INFO` ioctl. It is
-used to identify kernel devices compatible with this specification and to
-obtain information about driver and hardware capabilities. The ioctl
-takes a pointer to dvb_frontend_info which is filled by the driver.
-When the driver is not compatible with this specification the ioctl
-returns an error.
-
-
-frontend capabilities
-=====================
-
-Capabilities describe what a frontend can do. Some capabilities are
-supported only on some specific frontend types.
-
-The frontend capabilities are described at :c:type:`fe_caps`.
-
-
-Return Value
-============
-
-On success 0 is returned.
-
-On error -1 is returned, and the ``errno`` variable is set
-appropriately.
-
-Generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/media/uapi/dvb/fe-get-property.rst b/Documentation/media/uapi/dvb/fe-get-property.rst
deleted file mode 100644
index 99386c7461b3..000000000000
--- a/Documentation/media/uapi/dvb/fe-get-property.rst
+++ /dev/null
@@ -1,83 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _FE_GET_PROPERTY:
-
-**************************************
-ioctl FE_SET_PROPERTY, FE_GET_PROPERTY
-**************************************
-
-Name
-====
-
-FE_SET_PROPERTY - FE_GET_PROPERTY - FE_SET_PROPERTY sets one or more frontend properties. - FE_GET_PROPERTY returns one or more frontend properties.
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, FE_GET_PROPERTY, struct dtv_properties *argp )
-    :name: FE_GET_PROPERTY
-
-.. c:function:: int ioctl( int fd, FE_SET_PROPERTY, struct dtv_properties *argp )
-    :name: FE_SET_PROPERTY
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <frontend_f_open>`.
-
-``argp``
-    Pointer to struct :c:type:`dtv_properties`.
-
-
-Description
-===========
-
-All Digital TV frontend devices support the ``FE_SET_PROPERTY`` and
-``FE_GET_PROPERTY`` ioctls. The supported properties and statistics
-depends on the delivery system and on the device:
-
--  ``FE_SET_PROPERTY:``
-
-   -  This ioctl is used to set one or more frontend properties.
-
-   -  This is the basic command to request the frontend to tune into
-      some frequency and to start decoding the digital TV signal.
-
-   -  This call requires read/write access to the device.
-
-.. note::
-
-   At return, the values aren't updated to reflect the actual
-   parameters used. If the actual parameters are needed, an explicit
-   call to ``FE_GET_PROPERTY`` is needed.
-
--  ``FE_GET_PROPERTY:``
-
-   -  This ioctl is used to get properties and statistics from the
-      frontend.
-
-   -  No properties are changed, and statistics aren't reset.
-
-   -  This call only requires read-only access to the device.
-
-
-Return Value
-============
-
-On success 0 is returned.
-
-On error -1 is returned, and the ``errno`` variable is set
-appropriately.
-
-Generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/media/uapi/dvb/fe-read-ber.rst b/Documentation/media/uapi/dvb/fe-read-ber.rst
deleted file mode 100644
index e579d648687e..000000000000
--- a/Documentation/media/uapi/dvb/fe-read-ber.rst
+++ /dev/null
@@ -1,57 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _FE_READ_BER:
-
-***********
-FE_READ_BER
-***********
-
-Name
-====
-
-FE_READ_BER
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
-========
-
-.. c:function:: int  ioctl(int fd, FE_READ_BER, uint32_t *ber)
-    :name: FE_READ_BER
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :c:func:`open() <dvb-fe-open>`.
-
-``ber``
-    The bit error rate is stored into \*ber.
-
-
-Description
-===========
-
-This ioctl call returns the bit error rate for the signal currently
-received/demodulated by the front-end. For this command, read-only
-access to the device is sufficient.
-
-
-Return Value
-============
-
-On success 0 is returned.
-
-On error -1 is returned, and the ``errno`` variable is set
-appropriately.
-
-Generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/media/uapi/dvb/fe-read-signal-strength.rst b/Documentation/media/uapi/dvb/fe-read-signal-strength.rst
deleted file mode 100644
index 0a0c0c2ff207..000000000000
--- a/Documentation/media/uapi/dvb/fe-read-signal-strength.rst
+++ /dev/null
@@ -1,57 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _FE_READ_SIGNAL_STRENGTH:
-
-***********************
-FE_READ_SIGNAL_STRENGTH
-***********************
-
-Name
-====
-
-FE_READ_SIGNAL_STRENGTH
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, FE_READ_SIGNAL_STRENGTH, uint16_t *strength)
-    :name: FE_READ_SIGNAL_STRENGTH
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :c:func:`open() <dvb-fe-open>`.
-
-``strength``
-    The signal strength value is stored into \*strength.
-
-
-Description
-===========
-
-This ioctl call returns the signal strength value for the signal
-currently received by the front-end. For this command, read-only access
-to the device is sufficient.
-
-
-Return Value
-============
-
-On success 0 is returned.
-
-On error -1 is returned, and the ``errno`` variable is set
-appropriately.
-
-Generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/media/uapi/dvb/fe-read-snr.rst b/Documentation/media/uapi/dvb/fe-read-snr.rst
deleted file mode 100644
index 2a7a0d8f1fd5..000000000000
--- a/Documentation/media/uapi/dvb/fe-read-snr.rst
+++ /dev/null
@@ -1,57 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _FE_READ_SNR:
-
-***********
-FE_READ_SNR
-***********
-
-Name
-====
-
-FE_READ_SNR
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
-========
-
-.. c:function:: int  ioctl(int fd, FE_READ_SNR, int16_t *snr)
-    :name: FE_READ_SNR
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :c:func:`open() <dvb-fe-open>`.
-
-``snr``
-    The signal-to-noise ratio is stored into \*snr.
-
-
-Description
-===========
-
-This ioctl call returns the signal-to-noise ratio for the signal
-currently received by the front-end. For this command, read-only access
-to the device is sufficient.
-
-
-Return Value
-============
-
-On success 0 is returned.
-
-On error -1 is returned, and the ``errno`` variable is set
-appropriately.
-
-Generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/media/uapi/dvb/fe-read-status.rst b/Documentation/media/uapi/dvb/fe-read-status.rst
deleted file mode 100644
index 0dfc9fdf568f..000000000000
--- a/Documentation/media/uapi/dvb/fe-read-status.rst
+++ /dev/null
@@ -1,72 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _FE_READ_STATUS:
-
-********************
-ioctl FE_READ_STATUS
-********************
-
-Name
-====
-
-FE_READ_STATUS - Returns status information about the front-end. This call only requires - read-only access to the device
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, FE_READ_STATUS, unsigned int *status )
-    :name: FE_READ_STATUS
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <frontend_f_open>`.
-
-``status``
-    pointer to a bitmask integer filled with the values defined by enum
-    :c:type:`fe_status`.
-
-
-Description
-===========
-
-All Digital TV frontend devices support the ``FE_READ_STATUS`` ioctl. It is
-used to check about the locking status of the frontend after being
-tuned. The ioctl takes a pointer to an integer where the status will be
-written.
-
-.. note::
-
-   The size of status is actually sizeof(enum fe_status), with
-   varies according with the architecture. This needs to be fixed in the
-   future.
-
-
-int fe_status
-=============
-
-The fe_status parameter is used to indicate the current state and/or
-state changes of the frontend hardware. It is produced using the enum
-:c:type:`fe_status` values on a bitmask
-
-
-Return Value
-============
-
-On success 0 is returned.
-
-On error -1 is returned, and the ``errno`` variable is set
-appropriately.
-
-Generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/media/uapi/dvb/fe-read-uncorrected-blocks.rst b/Documentation/media/uapi/dvb/fe-read-uncorrected-blocks.rst
deleted file mode 100644
index 19c532f750aa..000000000000
--- a/Documentation/media/uapi/dvb/fe-read-uncorrected-blocks.rst
+++ /dev/null
@@ -1,59 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _FE_READ_UNCORRECTED_BLOCKS:
-
-**************************
-FE_READ_UNCORRECTED_BLOCKS
-**************************
-
-Name
-====
-
-FE_READ_UNCORRECTED_BLOCKS
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, FE_READ_UNCORRECTED_BLOCKS, uint32_t *ublocks)
-    :name: FE_READ_UNCORRECTED_BLOCKS
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :c:func:`open() <dvb-fe-open>`.
-
-``ublocks``
-    The total number of uncorrected blocks seen by the driver so far.
-
-
-Description
-===========
-
-This ioctl call returns the number of uncorrected blocks detected by the
-device driver during its lifetime. For meaningful measurements, the
-increment in block count during a specific time interval should be
-calculated. For this command, read-only access to the device is
-sufficient.
-
-
-Return Value
-============
-
-On success 0 is returned.
-
-On error -1 is returned, and the ``errno`` variable is set
-appropriately.
-
-Generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/media/uapi/dvb/fe-set-frontend-tune-mode.rst b/Documentation/media/uapi/dvb/fe-set-frontend-tune-mode.rst
deleted file mode 100644
index 36e8913170e1..000000000000
--- a/Documentation/media/uapi/dvb/fe-set-frontend-tune-mode.rst
+++ /dev/null
@@ -1,64 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _FE_SET_FRONTEND_TUNE_MODE:
-
-*******************************
-ioctl FE_SET_FRONTEND_TUNE_MODE
-*******************************
-
-Name
-====
-
-FE_SET_FRONTEND_TUNE_MODE - Allow setting tuner mode flags to the frontend.
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, FE_SET_FRONTEND_TUNE_MODE, unsigned int flags )
-    :name: FE_SET_FRONTEND_TUNE_MODE
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <frontend_f_open>`.
-
-``flags``
-    Valid flags:
-
-    -  0 - normal tune mode
-
-    -  ``FE_TUNE_MODE_ONESHOT`` - When set, this flag will disable any
-       zigzagging or other "normal" tuning behaviour. Additionally,
-       there will be no automatic monitoring of the lock status, and
-       hence no frontend events will be generated. If a frontend device
-       is closed, this flag will be automatically turned off when the
-       device is reopened read-write.
-
-
-Description
-===========
-
-Allow setting tuner mode flags to the frontend, between 0 (normal) or
-``FE_TUNE_MODE_ONESHOT`` mode
-
-
-Return Value
-============
-
-On success 0 is returned.
-
-On error -1 is returned, and the ``errno`` variable is set
-appropriately.
-
-Generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/media/uapi/dvb/fe-set-frontend.rst b/Documentation/media/uapi/dvb/fe-set-frontend.rst
deleted file mode 100644
index 23caae2588d2..000000000000
--- a/Documentation/media/uapi/dvb/fe-set-frontend.rst
+++ /dev/null
@@ -1,78 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _FE_SET_FRONTEND:
-
-***************
-FE_SET_FRONTEND
-***************
-
-.. attention:: This ioctl is deprecated.
-
-Name
-====
-
-FE_SET_FRONTEND
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl(int fd, FE_SET_FRONTEND, struct dvb_frontend_parameters *p)
-    :name: FE_SET_FRONTEND
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :c:func:`open() <dvb-fe-open>`.
-
-``p``
-    Points to parameters for tuning operation.
-
-
-Description
-===========
-
-This ioctl call starts a tuning operation using specified parameters.
-The result of this call will be successful if the parameters were valid
-and the tuning could be initiated. The result of the tuning operation in
-itself, however, will arrive asynchronously as an event (see
-documentation for :ref:`FE_GET_EVENT` and
-FrontendEvent.) If a new :ref:`FE_SET_FRONTEND`
-operation is initiated before the previous one was completed, the
-previous operation will be aborted in favor of the new one. This command
-requires read/write access to the device.
-
-
-Return Value
-============
-
-On success 0 is returned.
-
-On error -1 is returned, and the ``errno`` variable is set
-appropriately.
-
-.. tabularcolumns:: |p{2.5cm}|p{15.0cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths: 1 16
-
-    -  .. row 1
-
-       -  ``EINVAL``
-
-       -  Maximum supported symbol rate reached.
-
-
-Generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/media/uapi/dvb/fe-set-tone.rst b/Documentation/media/uapi/dvb/fe-set-tone.rst
deleted file mode 100644
index fb605e8c9fc4..000000000000
--- a/Documentation/media/uapi/dvb/fe-set-tone.rst
+++ /dev/null
@@ -1,65 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _FE_SET_TONE:
-
-*****************
-ioctl FE_SET_TONE
-*****************
-
-Name
-====
-
-FE_SET_TONE - Sets/resets the generation of the continuous 22kHz tone.
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, FE_SET_TONE, enum fe_sec_tone_mode tone )
-    :name: FE_SET_TONE
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <frontend_f_open>`.
-
-``tone``
-    an integer enumered value described at :c:type:`fe_sec_tone_mode`
-
-
-Description
-===========
-
-This ioctl is used to set the generation of the continuous 22kHz tone.
-This call requires read/write permissions.
-
-Usually, satellite antenna subsystems require that the digital TV device
-to send a 22kHz tone in order to select between high/low band on some
-dual-band LNBf. It is also used to send signals to DiSEqC equipment, but
-this is done using the DiSEqC ioctls.
-
-.. attention:: If more than one device is connected to the same antenna,
-   setting a tone may interfere on other devices, as they may lose the
-   capability of selecting the band. So, it is recommended that applications
-   would change to SEC_TONE_OFF when the device is not used.
-
-
-Return Value
-============
-
-On success 0 is returned.
-
-On error -1 is returned, and the ``errno`` variable is set
-appropriately.
-
-Generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/media/uapi/dvb/fe-set-voltage.rst b/Documentation/media/uapi/dvb/fe-set-voltage.rst
deleted file mode 100644
index c81a8e6a59aa..000000000000
--- a/Documentation/media/uapi/dvb/fe-set-voltage.rst
+++ /dev/null
@@ -1,69 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _FE_SET_VOLTAGE:
-
-********************
-ioctl FE_SET_VOLTAGE
-********************
-
-Name
-====
-
-FE_SET_VOLTAGE - Allow setting the DC level sent to the antenna subsystem.
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, FE_SET_VOLTAGE, enum fe_sec_voltage voltage )
-    :name: FE_SET_VOLTAGE
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <frontend_f_open>`.
-
-``voltage``
-    an integer enumered value described at :c:type:`fe_sec_voltage`
-
-
-Description
-===========
-
-This ioctl allows to set the DC voltage level sent through the antenna
-cable to 13V, 18V or off.
-
-Usually, a satellite antenna subsystems require that the digital TV
-device to send a DC voltage to feed power to the LNBf. Depending on the
-LNBf type, the polarization or the intermediate frequency (IF) of the
-LNBf can controlled by the voltage level. Other devices (for example,
-the ones that implement DISEqC and multipoint LNBf's don't need to
-control the voltage level, provided that either 13V or 18V is sent to
-power up the LNBf.
-
-.. attention:: if more than one device is connected to the same antenna,
-   setting a voltage level may interfere on other devices, as they may lose
-   the capability of setting polarization or IF. So, on those cases, setting
-   the voltage to SEC_VOLTAGE_OFF while the device is not is used is
-   recommended.
-
-
-Return Value
-============
-
-On success 0 is returned.
-
-On error -1 is returned, and the ``errno`` variable is set
-appropriately.
-
-Generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/media/uapi/dvb/fe-type-t.rst b/Documentation/media/uapi/dvb/fe-type-t.rst
deleted file mode 100644
index 9720d2f7ba35..000000000000
--- a/Documentation/media/uapi/dvb/fe-type-t.rst
+++ /dev/null
@@ -1,98 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-*************
-Frontend type
-*************
-
-For historical reasons, frontend types are named by the type of
-modulation used in transmission. The fontend types are given by
-fe_type_t type, defined as:
-
-
-.. c:type:: fe_type
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. flat-table:: Frontend types
-    :header-rows:  1
-    :stub-columns: 0
-    :widths:       3 1 4
-
-
-    -  .. row 1
-
-       -  fe_type
-
-       -  Description
-
-       -  :ref:`DTV_DELIVERY_SYSTEM <DTV-DELIVERY-SYSTEM>` equivalent
-	  type
-
-    -  .. row 2
-
-       -  .. _FE-QPSK:
-
-	  ``FE_QPSK``
-
-       -  For DVB-S standard
-
-       -  ``SYS_DVBS``
-
-    -  .. row 3
-
-       -  .. _FE-QAM:
-
-	  ``FE_QAM``
-
-       -  For DVB-C annex A standard
-
-       -  ``SYS_DVBC_ANNEX_A``
-
-    -  .. row 4
-
-       -  .. _FE-OFDM:
-
-	  ``FE_OFDM``
-
-       -  For DVB-T standard
-
-       -  ``SYS_DVBT``
-
-    -  .. row 5
-
-       -  .. _FE-ATSC:
-
-	  ``FE_ATSC``
-
-       -  For ATSC standard (terrestrial) or for DVB-C Annex B (cable) used
-	  in US.
-
-       -  ``SYS_ATSC`` (terrestrial) or ``SYS_DVBC_ANNEX_B`` (cable)
-
-
-Newer formats like DVB-S2, ISDB-T, ISDB-S and DVB-T2 are not described
-at the above, as they're supported via the new
-:ref:`FE_GET_PROPERTY/FE_GET_SET_PROPERTY <FE_GET_PROPERTY>`
-ioctl's, using the :ref:`DTV_DELIVERY_SYSTEM <DTV-DELIVERY-SYSTEM>`
-parameter.
-
-In the old days, struct :c:type:`dvb_frontend_info`
-used to contain ``fe_type_t`` field to indicate the delivery systems,
-filled with either ``FE_QPSK, FE_QAM, FE_OFDM`` or ``FE_ATSC``. While this
-is still filled to keep backward compatibility, the usage of this field
-is deprecated, as it can report just one delivery system, but some
-devices support multiple delivery systems. Please use
-:ref:`DTV_ENUM_DELSYS <DTV-ENUM-DELSYS>` instead.
-
-On devices that support multiple delivery systems, struct
-:c:type:`dvb_frontend_info`::``fe_type_t`` is
-filled with the currently standard, as selected by the last call to
-:ref:`FE_SET_PROPERTY <FE_GET_PROPERTY>` using the
-:ref:`DTV_DELIVERY_SYSTEM <DTV-DELIVERY-SYSTEM>` property.
diff --git a/Documentation/media/uapi/dvb/fe_property_parameters.rst b/Documentation/media/uapi/dvb/fe_property_parameters.rst
deleted file mode 100644
index 2fd2954d8dae..000000000000
--- a/Documentation/media/uapi/dvb/fe_property_parameters.rst
+++ /dev/null
@@ -1,1014 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _fe_property_parameters:
-
-******************************
-Digital TV property parameters
-******************************
-
-There are several different Digital TV parameters that can be used by
-:ref:`FE_SET_PROPERTY and FE_GET_PROPERTY ioctls<FE_GET_PROPERTY>`.
-This section describes each of them. Please notice, however, that only
-a subset of them are needed to setup a frontend.
-
-
-.. _DTV-UNDEFINED:
-
-DTV_UNDEFINED
-=============
-
-Used internally. A GET/SET operation for it won't change or return
-anything.
-
-
-.. _DTV-TUNE:
-
-DTV_TUNE
-========
-
-Interpret the cache of data, build either a traditional frontend
-tunerequest so we can pass validation in the ``FE_SET_FRONTEND`` ioctl.
-
-
-.. _DTV-CLEAR:
-
-DTV_CLEAR
-=========
-
-Reset a cache of data specific to the frontend here. This does not
-effect hardware.
-
-
-.. _DTV-FREQUENCY:
-
-DTV_FREQUENCY
-=============
-
-Frequency of the digital TV transponder/channel.
-
-.. note::
-
-  #. For satellite delivery systems, the frequency is in kHz.
-
-  #. For cable and terrestrial delivery systems, the frequency is in
-     Hz.
-
-  #. On most delivery systems, the frequency is the center frequency
-     of the transponder/channel. The exception is for ISDB-T, where
-     the main carrier has a 1/7 offset from the center.
-
-  #. For ISDB-T, the channels are usually transmitted with an offset of
-     about 143kHz. E.g. a valid frequency could be 474,143 kHz. The
-     stepping is  bound to the bandwidth of the channel which is
-     typically 6MHz.
-
-  #. In ISDB-Tsb, the channel consists of only one or three segments the
-     frequency step is 429kHz, 3*429 respectively.
-
-
-.. _DTV-MODULATION:
-
-DTV_MODULATION
-==============
-
-Specifies the frontend modulation type for delivery systems that
-supports more multiple modulations.
-
-The modulation can be one of the types defined by enum :c:type:`fe_modulation`.
-
-Most of the digital TV standards offers more than one possible
-modulation type.
-
-The table below presents a summary of the types of modulation types
-supported by each delivery system, as currently defined by specs.
-
-======================= =======================================================
-Standard		Modulation types
-======================= =======================================================
-ATSC (version 1)	8-VSB and 16-VSB.
-DMTB			4-QAM, 16-QAM, 32-QAM, 64-QAM and 4-QAM-NR.
-DVB-C Annex A/C		16-QAM, 32-QAM, 64-QAM and 256-QAM.
-DVB-C Annex B		64-QAM.
-DVB-T			QPSK, 16-QAM and 64-QAM.
-DVB-T2			QPSK, 16-QAM, 64-QAM and 256-QAM.
-DVB-S			No need to set. It supports only QPSK.
-DVB-S2			QPSK, 8-PSK, 16-APSK and 32-APSK.
-ISDB-T			QPSK, DQPSK, 16-QAM and 64-QAM.
-ISDB-S			8-PSK, QPSK and BPSK.
-======================= =======================================================
-
-.. note::
-
-   Please notice that some of the above modulation types may not be
-   defined currently at the Kernel. The reason is simple: no driver
-   needed such definition yet.
-
-
-.. _DTV-BANDWIDTH-HZ:
-
-DTV_BANDWIDTH_HZ
-================
-
-Bandwidth for the channel, in HZ.
-
-Should be set only for terrestrial delivery systems.
-
-Possible values: ``1712000``, ``5000000``, ``6000000``, ``7000000``,
-``8000000``, ``10000000``.
-
-======================= =======================================================
-Terrestrial Standard	Possible values for bandwidth
-======================= =======================================================
-ATSC (version 1)	No need to set. It is always 6MHz.
-DMTB			No need to set. It is always 8MHz.
-DVB-T			6MHz, 7MHz and 8MHz.
-DVB-T2			1.172 MHz, 5MHz, 6MHz, 7MHz, 8MHz and 10MHz
-ISDB-T			5MHz, 6MHz, 7MHz and 8MHz, although most places
-			use 6MHz.
-======================= =======================================================
-
-
-.. note::
-
-
-  #. For ISDB-Tsb, the bandwidth can vary depending on the number of
-     connected segments.
-
-     It can be easily derived from other parameters
-     (DTV_ISDBT_SB_SEGMENT_IDX, DTV_ISDBT_SB_SEGMENT_COUNT).
-
-  #. On Satellite and Cable delivery systems, the bandwidth depends on
-     the symbol rate. So, the Kernel will silently ignore any setting
-     :ref:`DTV-BANDWIDTH-HZ`. I will however fill it back with a
-     bandwidth estimation.
-
-     Such bandwidth estimation takes into account the symbol rate set with
-     :ref:`DTV-SYMBOL-RATE`, and the rolloff factor, with is fixed for
-     DVB-C and DVB-S.
-
-     For DVB-S2, the rolloff should also be set via :ref:`DTV-ROLLOFF`.
-
-
-.. _DTV-INVERSION:
-
-DTV_INVERSION
-=============
-
-Specifies if the frontend should do spectral inversion or not.
-
-The acceptable values are defined by :c:type:`fe_spectral_inversion`.
-
-
-.. _DTV-DISEQC-MASTER:
-
-DTV_DISEQC_MASTER
-=================
-
-Currently not implemented.
-
-
-.. _DTV-SYMBOL-RATE:
-
-DTV_SYMBOL_RATE
-===============
-
-Used on cable and satellite delivery systems.
-
-Digital TV symbol rate, in bauds (symbols/second).
-
-
-.. _DTV-INNER-FEC:
-
-DTV_INNER_FEC
-=============
-
-Used on cable and satellite delivery systems.
-
-The acceptable values are defined by :c:type:`fe_code_rate`.
-
-
-.. _DTV-VOLTAGE:
-
-DTV_VOLTAGE
-===========
-
-Used on satellite delivery systems.
-
-The voltage is usually used with non-DiSEqC capable LNBs to switch the
-polarzation (horizontal/vertical). When using DiSEqC epuipment this
-voltage has to be switched consistently to the DiSEqC commands as
-described in the DiSEqC spec.
-
-The acceptable values are defined by :c:type:`fe_sec_voltage`.
-
-
-.. _DTV-TONE:
-
-DTV_TONE
-========
-
-Currently not used.
-
-
-.. _DTV-PILOT:
-
-DTV_PILOT
-=========
-
-Used on DVB-S2.
-
-Sets DVB-S2 pilot.
-
-The acceptable values are defined by :c:type:`fe_pilot`.
-
-
-.. _DTV-ROLLOFF:
-
-DTV_ROLLOFF
-===========
-
-Used on DVB-S2.
-
-Sets DVB-S2 rolloff.
-
-The acceptable values are defined by :c:type:`fe_rolloff`.
-
-
-.. _DTV-DISEQC-SLAVE-REPLY:
-
-DTV_DISEQC_SLAVE_REPLY
-======================
-
-Currently not implemented.
-
-
-.. _DTV-FE-CAPABILITY-COUNT:
-
-DTV_FE_CAPABILITY_COUNT
-=======================
-
-Currently not implemented.
-
-
-.. _DTV-FE-CAPABILITY:
-
-DTV_FE_CAPABILITY
-=================
-
-Currently not implemented.
-
-
-.. _DTV-DELIVERY-SYSTEM:
-
-DTV_DELIVERY_SYSTEM
-===================
-
-Specifies the type of the delivery system.
-
-The acceptable values are defined by :c:type:`fe_delivery_system`.
-
-
-.. _DTV-ISDBT-PARTIAL-RECEPTION:
-
-DTV_ISDBT_PARTIAL_RECEPTION
-===========================
-
-Used only on ISDB.
-
-If ``DTV_ISDBT_SOUND_BROADCASTING`` is '0' this bit-field represents
-whether the channel is in partial reception mode or not.
-
-If '1' ``DTV_ISDBT_LAYERA_*`` values are assigned to the center segment
-and ``DTV_ISDBT_LAYERA_SEGMENT_COUNT`` has to be '1'.
-
-If in addition ``DTV_ISDBT_SOUND_BROADCASTING`` is '1'
-``DTV_ISDBT_PARTIAL_RECEPTION`` represents whether this ISDB-Tsb channel
-is consisting of one segment and layer or three segments and two layers.
-
-Possible values: 0, 1, -1 (AUTO)
-
-
-.. _DTV-ISDBT-SOUND-BROADCASTING:
-
-DTV_ISDBT_SOUND_BROADCASTING
-============================
-
-Used only on ISDB.
-
-This field represents whether the other DTV_ISDBT_*-parameters are
-referring to an ISDB-T and an ISDB-Tsb channel. (See also
-``DTV_ISDBT_PARTIAL_RECEPTION``).
-
-Possible values: 0, 1, -1 (AUTO)
-
-
-.. _DTV-ISDBT-SB-SUBCHANNEL-ID:
-
-DTV_ISDBT_SB_SUBCHANNEL_ID
-==========================
-
-Used only on ISDB.
-
-This field only applies if ``DTV_ISDBT_SOUND_BROADCASTING`` is '1'.
-
-(Note of the author: This might not be the correct description of the
-``SUBCHANNEL-ID`` in all details, but it is my understanding of the
-technical background needed to program a device)
-
-An ISDB-Tsb channel (1 or 3 segments) can be broadcasted alone or in a
-set of connected ISDB-Tsb channels. In this set of channels every
-channel can be received independently. The number of connected ISDB-Tsb
-segment can vary, e.g. depending on the frequency spectrum bandwidth
-available.
-
-Example: Assume 8 ISDB-Tsb connected segments are broadcasted. The
-broadcaster has several possibilities to put those channels in the air:
-Assuming a normal 13-segment ISDB-T spectrum he can align the 8 segments
-from position 1-8 to 5-13 or anything in between.
-
-The underlying layer of segments are subchannels: each segment is
-consisting of several subchannels with a predefined IDs. A sub-channel
-is used to help the demodulator to synchronize on the channel.
-
-An ISDB-T channel is always centered over all sub-channels. As for the
-example above, in ISDB-Tsb it is no longer as simple as that.
-
-``The DTV_ISDBT_SB_SUBCHANNEL_ID`` parameter is used to give the
-sub-channel ID of the segment to be demodulated.
-
-Possible values: 0 .. 41, -1 (AUTO)
-
-
-.. _DTV-ISDBT-SB-SEGMENT-IDX:
-
-DTV_ISDBT_SB_SEGMENT_IDX
-========================
-
-Used only on ISDB.
-
-This field only applies if ``DTV_ISDBT_SOUND_BROADCASTING`` is '1'.
-
-``DTV_ISDBT_SB_SEGMENT_IDX`` gives the index of the segment to be
-demodulated for an ISDB-Tsb channel where several of them are
-transmitted in the connected manner.
-
-Possible values: 0 .. ``DTV_ISDBT_SB_SEGMENT_COUNT`` - 1
-
-Note: This value cannot be determined by an automatic channel search.
-
-
-.. _DTV-ISDBT-SB-SEGMENT-COUNT:
-
-DTV_ISDBT_SB_SEGMENT_COUNT
-==========================
-
-Used only on ISDB.
-
-This field only applies if ``DTV_ISDBT_SOUND_BROADCASTING`` is '1'.
-
-``DTV_ISDBT_SB_SEGMENT_COUNT`` gives the total count of connected
-ISDB-Tsb channels.
-
-Possible values: 1 .. 13
-
-Note: This value cannot be determined by an automatic channel search.
-
-
-.. _isdb-hierq-layers:
-
-DTV-ISDBT-LAYER[A-C] parameters
-===============================
-
-Used only on ISDB.
-
-ISDB-T channels can be coded hierarchically. As opposed to DVB-T in
-ISDB-T hierarchical layers can be decoded simultaneously. For that
-reason a ISDB-T demodulator has 3 Viterbi and 3 Reed-Solomon decoders.
-
-ISDB-T has 3 hierarchical layers which each can use a part of the
-available segments. The total number of segments over all layers has to
-13 in ISDB-T.
-
-There are 3 parameter sets, for Layers A, B and C.
-
-
-.. _DTV-ISDBT-LAYER-ENABLED:
-
-DTV_ISDBT_LAYER_ENABLED
------------------------
-
-Used only on ISDB.
-
-Hierarchical reception in ISDB-T is achieved by enabling or disabling
-layers in the decoding process. Setting all bits of
-``DTV_ISDBT_LAYER_ENABLED`` to '1' forces all layers (if applicable) to
-be demodulated. This is the default.
-
-If the channel is in the partial reception mode
-(``DTV_ISDBT_PARTIAL_RECEPTION`` = 1) the central segment can be decoded
-independently of the other 12 segments. In that mode layer A has to have
-a ``SEGMENT_COUNT`` of 1.
-
-In ISDB-Tsb only layer A is used, it can be 1 or 3 in ISDB-Tsb according
-to ``DTV_ISDBT_PARTIAL_RECEPTION``. ``SEGMENT_COUNT`` must be filled
-accordingly.
-
-Only the values of the first 3 bits are used. Other bits will be silently ignored:
-
-``DTV_ISDBT_LAYER_ENABLED`` bit 0: layer A enabled
-
-``DTV_ISDBT_LAYER_ENABLED`` bit 1: layer B enabled
-
-``DTV_ISDBT_LAYER_ENABLED`` bit 2: layer C enabled
-
-``DTV_ISDBT_LAYER_ENABLED`` bits 3-31: unused
-
-
-.. _DTV-ISDBT-LAYER-FEC:
-
-DTV_ISDBT_LAYER[A-C]_FEC
-------------------------
-
-Used only on ISDB.
-
-The Forward Error Correction mechanism used by a given ISDB Layer, as
-defined by :c:type:`fe_code_rate`.
-
-
-Possible values are: ``FEC_AUTO``, ``FEC_1_2``, ``FEC_2_3``, ``FEC_3_4``,
-``FEC_5_6``, ``FEC_7_8``
-
-
-.. _DTV-ISDBT-LAYER-MODULATION:
-
-DTV_ISDBT_LAYER[A-C]_MODULATION
--------------------------------
-
-Used only on ISDB.
-
-The modulation used by a given ISDB Layer, as defined by
-:c:type:`fe_modulation`.
-
-Possible values are: ``QAM_AUTO``, ``QPSK``, ``QAM_16``, ``QAM_64``, ``DQPSK``
-
-.. note::
-
-   #. If layer C is ``DQPSK``, then layer B has to be ``DQPSK``.
-
-   #. If layer B is ``DQPSK`` and ``DTV_ISDBT_PARTIAL_RECEPTION``\ = 0,
-      then layer has to be ``DQPSK``.
-
-
-.. _DTV-ISDBT-LAYER-SEGMENT-COUNT:
-
-DTV_ISDBT_LAYER[A-C]_SEGMENT_COUNT
-----------------------------------
-
-Used only on ISDB.
-
-Possible values: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -1 (AUTO)
-
-Note: Truth table for ``DTV_ISDBT_SOUND_BROADCASTING`` and
-``DTV_ISDBT_PARTIAL_RECEPTION`` and ``LAYER[A-C]_SEGMENT_COUNT``
-
-.. _isdbt-layer_seg-cnt-table:
-
-.. flat-table:: Truth table for ISDB-T Sound Broadcasting
-    :header-rows:  1
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  Partial Reception
-
-       -  Sound Broadcasting
-
-       -  Layer A width
-
-       -  Layer B width
-
-       -  Layer C width
-
-       -  total width
-
-    -  .. row 2
-
-       -  0
-
-       -  0
-
-       -  1 .. 13
-
-       -  1 .. 13
-
-       -  1 .. 13
-
-       -  13
-
-    -  .. row 3
-
-       -  1
-
-       -  0
-
-       -  1
-
-       -  1 .. 13
-
-       -  1 .. 13
-
-       -  13
-
-    -  .. row 4
-
-       -  0
-
-       -  1
-
-       -  1
-
-       -  0
-
-       -  0
-
-       -  1
-
-    -  .. row 5
-
-       -  1
-
-       -  1
-
-       -  1
-
-       -  2
-
-       -  0
-
-       -  13
-
-
-
-.. _DTV-ISDBT-LAYER-TIME-INTERLEAVING:
-
-DTV_ISDBT_LAYER[A-C]_TIME_INTERLEAVING
---------------------------------------
-
-Used only on ISDB.
-
-Valid values: 0, 1, 2, 4, -1 (AUTO)
-
-when DTV_ISDBT_SOUND_BROADCASTING is active, value 8 is also valid.
-
-Note: The real time interleaving length depends on the mode (fft-size).
-The values here are referring to what can be found in the
-TMCC-structure, as shown in the table below.
-
-
-.. c:type:: isdbt_layer_interleaving_table
-
-.. flat-table:: ISDB-T time interleaving modes
-    :header-rows:  1
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  ``DTV_ISDBT_LAYER[A-C]_TIME_INTERLEAVING``
-
-       -  Mode 1 (2K FFT)
-
-       -  Mode 2 (4K FFT)
-
-       -  Mode 3 (8K FFT)
-
-    -  .. row 2
-
-       -  0
-
-       -  0
-
-       -  0
-
-       -  0
-
-    -  .. row 3
-
-       -  1
-
-       -  4
-
-       -  2
-
-       -  1
-
-    -  .. row 4
-
-       -  2
-
-       -  8
-
-       -  4
-
-       -  2
-
-    -  .. row 5
-
-       -  4
-
-       -  16
-
-       -  8
-
-       -  4
-
-
-
-.. _DTV-ATSCMH-FIC-VER:
-
-DTV_ATSCMH_FIC_VER
-------------------
-
-Used only on ATSC-MH.
-
-Version number of the FIC (Fast Information Channel) signaling data.
-
-FIC is used for relaying information to allow rapid service acquisition
-by the receiver.
-
-Possible values: 0, 1, 2, 3, ..., 30, 31
-
-
-.. _DTV-ATSCMH-PARADE-ID:
-
-DTV_ATSCMH_PARADE_ID
---------------------
-
-Used only on ATSC-MH.
-
-Parade identification number
-
-A parade is a collection of up to eight MH groups, conveying one or two
-ensembles.
-
-Possible values: 0, 1, 2, 3, ..., 126, 127
-
-
-.. _DTV-ATSCMH-NOG:
-
-DTV_ATSCMH_NOG
---------------
-
-Used only on ATSC-MH.
-
-Number of MH groups per MH subframe for a designated parade.
-
-Possible values: 1, 2, 3, 4, 5, 6, 7, 8
-
-
-.. _DTV-ATSCMH-TNOG:
-
-DTV_ATSCMH_TNOG
----------------
-
-Used only on ATSC-MH.
-
-Total number of MH groups including all MH groups belonging to all MH
-parades in one MH subframe.
-
-Possible values: 0, 1, 2, 3, ..., 30, 31
-
-
-.. _DTV-ATSCMH-SGN:
-
-DTV_ATSCMH_SGN
---------------
-
-Used only on ATSC-MH.
-
-Start group number.
-
-Possible values: 0, 1, 2, 3, ..., 14, 15
-
-
-.. _DTV-ATSCMH-PRC:
-
-DTV_ATSCMH_PRC
---------------
-
-Used only on ATSC-MH.
-
-Parade repetition cycle.
-
-Possible values: 1, 2, 3, 4, 5, 6, 7, 8
-
-
-.. _DTV-ATSCMH-RS-FRAME-MODE:
-
-DTV_ATSCMH_RS_FRAME_MODE
-------------------------
-
-Used only on ATSC-MH.
-
-Reed Solomon (RS) frame mode.
-
-The acceptable values are defined by :c:type:`atscmh_rs_frame_mode`.
-
-
-.. _DTV-ATSCMH-RS-FRAME-ENSEMBLE:
-
-DTV_ATSCMH_RS_FRAME_ENSEMBLE
-----------------------------
-
-Used only on ATSC-MH.
-
-Reed Solomon(RS) frame ensemble.
-
-The acceptable values are defined by :c:type:`atscmh_rs_frame_ensemble`.
-
-
-.. _DTV-ATSCMH-RS-CODE-MODE-PRI:
-
-DTV_ATSCMH_RS_CODE_MODE_PRI
----------------------------
-
-Used only on ATSC-MH.
-
-Reed Solomon (RS) code mode (primary).
-
-The acceptable values are defined by :c:type:`atscmh_rs_code_mode`.
-
-
-.. _DTV-ATSCMH-RS-CODE-MODE-SEC:
-
-DTV_ATSCMH_RS_CODE_MODE_SEC
----------------------------
-
-Used only on ATSC-MH.
-
-Reed Solomon (RS) code mode (secondary).
-
-The acceptable values are defined by :c:type:`atscmh_rs_code_mode`.
-
-
-.. _DTV-ATSCMH-SCCC-BLOCK-MODE:
-
-DTV_ATSCMH_SCCC_BLOCK_MODE
---------------------------
-
-Used only on ATSC-MH.
-
-Series Concatenated Convolutional Code Block Mode.
-
-The acceptable values are defined by :c:type:`atscmh_sccc_block_mode`.
-
-
-.. _DTV-ATSCMH-SCCC-CODE-MODE-A:
-
-DTV_ATSCMH_SCCC_CODE_MODE_A
----------------------------
-
-Used only on ATSC-MH.
-
-Series Concatenated Convolutional Code Rate.
-
-The acceptable values are defined by :c:type:`atscmh_sccc_code_mode`.
-
-.. _DTV-ATSCMH-SCCC-CODE-MODE-B:
-
-DTV_ATSCMH_SCCC_CODE_MODE_B
----------------------------
-
-Used only on ATSC-MH.
-
-Series Concatenated Convolutional Code Rate.
-
-Possible values are the same as documented on enum
-:c:type:`atscmh_sccc_code_mode`.
-
-
-.. _DTV-ATSCMH-SCCC-CODE-MODE-C:
-
-DTV_ATSCMH_SCCC_CODE_MODE_C
----------------------------
-
-Used only on ATSC-MH.
-
-Series Concatenated Convolutional Code Rate.
-
-Possible values are the same as documented on enum
-:c:type:`atscmh_sccc_code_mode`.
-
-
-.. _DTV-ATSCMH-SCCC-CODE-MODE-D:
-
-DTV_ATSCMH_SCCC_CODE_MODE_D
----------------------------
-
-Used only on ATSC-MH.
-
-Series Concatenated Convolutional Code Rate.
-
-Possible values are the same as documented on enum
-:c:type:`atscmh_sccc_code_mode`.
-
-
-.. _DTV-API-VERSION:
-
-DTV_API_VERSION
-===============
-
-Returns the major/minor version of the Digital TV API
-
-
-.. _DTV-CODE-RATE-HP:
-
-DTV_CODE_RATE_HP
-================
-
-Used on terrestrial transmissions.
-
-The acceptable values are defined by :c:type:`fe_transmit_mode`.
-
-
-.. _DTV-CODE-RATE-LP:
-
-DTV_CODE_RATE_LP
-================
-
-Used on terrestrial transmissions.
-
-The acceptable values are defined by :c:type:`fe_transmit_mode`.
-
-
-.. _DTV-GUARD-INTERVAL:
-
-DTV_GUARD_INTERVAL
-==================
-
-The acceptable values are defined by :c:type:`fe_guard_interval`.
-
-.. note::
-
-   #. If ``DTV_GUARD_INTERVAL`` is set the ``GUARD_INTERVAL_AUTO`` the
-      hardware will try to find the correct guard interval (if capable) and
-      will use TMCC to fill in the missing parameters.
-   #. Intervals ``GUARD_INTERVAL_1_128``, ``GUARD_INTERVAL_19_128``
-      and ``GUARD_INTERVAL_19_256`` are used only for DVB-T2 at
-      present.
-   #. Intervals ``GUARD_INTERVAL_PN420``, ``GUARD_INTERVAL_PN595`` and
-      ``GUARD_INTERVAL_PN945`` are used only for DMTB at the present.
-      On such standard, only those intervals and ``GUARD_INTERVAL_AUTO``
-      are valid.
-
-.. _DTV-TRANSMISSION-MODE:
-
-DTV_TRANSMISSION_MODE
-=====================
-
-
-Used only on OFTM-based standards, e. g. DVB-T/T2, ISDB-T, DTMB.
-
-Specifies the FFT size (with corresponds to the approximate number of
-carriers) used by the standard.
-
-The acceptable values are defined by :c:type:`fe_transmit_mode`.
-
-.. note::
-
-   #. ISDB-T supports three carrier/symbol-size: 8K, 4K, 2K. It is called
-      **mode** on such standard, and are numbered from 1 to 3:
-
-      ====	========	========================
-      Mode	FFT size	Transmission mode
-      ====	========	========================
-      1		2K		``TRANSMISSION_MODE_2K``
-      2		4K		``TRANSMISSION_MODE_4K``
-      3		8K		``TRANSMISSION_MODE_8K``
-      ====	========	========================
-
-   #. If ``DTV_TRANSMISSION_MODE`` is set the ``TRANSMISSION_MODE_AUTO``
-      the hardware will try to find the correct FFT-size (if capable) and
-      will use TMCC to fill in the missing parameters.
-
-   #. DVB-T specifies 2K and 8K as valid sizes.
-
-   #. DVB-T2 specifies 1K, 2K, 4K, 8K, 16K and 32K.
-
-   #. DTMB specifies C1 and C3780.
-
-
-.. _DTV-HIERARCHY:
-
-DTV_HIERARCHY
-=============
-
-Used only on DVB-T and DVB-T2.
-
-Frontend hierarchy.
-
-The acceptable values are defined by :c:type:`fe_hierarchy`.
-
-
-.. _DTV-STREAM-ID:
-
-DTV_STREAM_ID
-=============
-
-Used on DVB-S2, DVB-T2 and ISDB-S.
-
-DVB-S2, DVB-T2 and ISDB-S support the transmission of several streams on
-a single transport stream. This property enables the digital TV driver to
-handle substream filtering, when supported by the hardware. By default,
-substream filtering is disabled.
-
-For DVB-S2 and DVB-T2, the valid substream id range is from 0 to 255.
-
-For ISDB, the valid substream id range is from 1 to 65535.
-
-To disable it, you should use the special macro NO_STREAM_ID_FILTER.
-
-Note: any value outside the id range also disables filtering.
-
-
-.. _DTV-DVBT2-PLP-ID-LEGACY:
-
-DTV_DVBT2_PLP_ID_LEGACY
-=======================
-
-Obsolete, replaced with DTV_STREAM_ID.
-
-
-.. _DTV-ENUM-DELSYS:
-
-DTV_ENUM_DELSYS
-===============
-
-A Multi standard frontend needs to advertise the delivery systems
-provided. Applications need to enumerate the provided delivery systems,
-before using any other operation with the frontend. Prior to it's
-introduction, FE_GET_INFO was used to determine a frontend type. A
-frontend which provides more than a single delivery system,
-FE_GET_INFO doesn't help much. Applications which intends to use a
-multistandard frontend must enumerate the delivery systems associated
-with it, rather than trying to use FE_GET_INFO. In the case of a
-legacy frontend, the result is just the same as with FE_GET_INFO, but
-in a more structured format
-
-The acceptable values are defined by :c:type:`fe_delivery_system`.
-
-
-.. _DTV-INTERLEAVING:
-
-DTV_INTERLEAVING
-================
-
-Time interleaving to be used.
-
-The acceptable values are defined by :c:type:`fe_interleaving`.
-
-
-.. _DTV-LNA:
-
-DTV_LNA
-=======
-
-Low-noise amplifier.
-
-Hardware might offer controllable LNA which can be set manually using
-that parameter. Usually LNA could be found only from terrestrial devices
-if at all.
-
-Possible values: 0, 1, LNA_AUTO
-
-0, LNA off
-
-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-header.rst b/Documentation/media/uapi/dvb/frontend-header.rst
deleted file mode 100644
index 635fb4251214..000000000000
--- a/Documentation/media/uapi/dvb/frontend-header.rst
+++ /dev/null
@@ -1,13 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-Frontend uAPI data types
-========================
-
-.. kernel-doc:: include/uapi/linux/dvb/frontend.h
diff --git a/Documentation/media/uapi/dvb/frontend-property-cable-systems.rst b/Documentation/media/uapi/dvb/frontend-property-cable-systems.rst
deleted file mode 100644
index 97fbfc228c10..000000000000
--- a/Documentation/media/uapi/dvb/frontend-property-cable-systems.rst
+++ /dev/null
@@ -1,82 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _frontend-property-cable-systems:
-
-*****************************************
-Properties used on cable delivery systems
-*****************************************
-
-
-.. _dvbc-params:
-
-DVB-C delivery system
-=====================
-
-The DVB-C Annex-A is the widely used cable standard. Transmission uses
-QAM modulation.
-
-The DVB-C Annex-C is optimized for 6MHz, and is used in Japan. It
-supports a subset of the Annex A modulation types, and a roll-off of
-0.13, instead of 0.15
-
-The following parameters are valid for DVB-C Annex A/C:
-
--  :ref:`DTV_API_VERSION <DTV-API-VERSION>`
-
--  :ref:`DTV_DELIVERY_SYSTEM <DTV-DELIVERY-SYSTEM>`
-
--  :ref:`DTV_TUNE <DTV-TUNE>`
-
--  :ref:`DTV_CLEAR <DTV-CLEAR>`
-
--  :ref:`DTV_FREQUENCY <DTV-FREQUENCY>`
-
--  :ref:`DTV_MODULATION <DTV-MODULATION>`
-
--  :ref:`DTV_INVERSION <DTV-INVERSION>`
-
--  :ref:`DTV_SYMBOL_RATE <DTV-SYMBOL-RATE>`
-
--  :ref:`DTV_INNER_FEC <DTV-INNER-FEC>`
-
--  :ref:`DTV_LNA <DTV-LNA>`
-
-In addition, the :ref:`DTV QoS statistics <frontend-stat-properties>`
-are also valid.
-
-
-.. _dvbc-annex-b-params:
-
-DVB-C Annex B delivery system
-=============================
-
-The DVB-C Annex-B is only used on a few Countries like the United
-States.
-
-The following parameters are valid for DVB-C Annex B:
-
--  :ref:`DTV_API_VERSION <DTV-API-VERSION>`
-
--  :ref:`DTV_DELIVERY_SYSTEM <DTV-DELIVERY-SYSTEM>`
-
--  :ref:`DTV_TUNE <DTV-TUNE>`
-
--  :ref:`DTV_CLEAR <DTV-CLEAR>`
-
--  :ref:`DTV_FREQUENCY <DTV-FREQUENCY>`
-
--  :ref:`DTV_MODULATION <DTV-MODULATION>`
-
--  :ref:`DTV_INVERSION <DTV-INVERSION>`
-
--  :ref:`DTV_LNA <DTV-LNA>`
-
-In addition, the :ref:`DTV QoS statistics <frontend-stat-properties>`
-are also valid.
diff --git a/Documentation/media/uapi/dvb/frontend-property-satellite-systems.rst b/Documentation/media/uapi/dvb/frontend-property-satellite-systems.rst
deleted file mode 100644
index 2bc880a3c826..000000000000
--- a/Documentation/media/uapi/dvb/frontend-property-satellite-systems.rst
+++ /dev/null
@@ -1,112 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _frontend-property-satellite-systems:
-
-*********************************************
-Properties used on satellite delivery systems
-*********************************************
-
-
-.. _dvbs-params:
-
-DVB-S delivery system
-=====================
-
-The following parameters are valid for DVB-S:
-
--  :ref:`DTV_API_VERSION <DTV-API-VERSION>`
-
--  :ref:`DTV_DELIVERY_SYSTEM <DTV-DELIVERY-SYSTEM>`
-
--  :ref:`DTV_TUNE <DTV-TUNE>`
-
--  :ref:`DTV_CLEAR <DTV-CLEAR>`
-
--  :ref:`DTV_FREQUENCY <DTV-FREQUENCY>`
-
--  :ref:`DTV_INVERSION <DTV-INVERSION>`
-
--  :ref:`DTV_SYMBOL_RATE <DTV-SYMBOL-RATE>`
-
--  :ref:`DTV_INNER_FEC <DTV-INNER-FEC>`
-
--  :ref:`DTV_VOLTAGE <DTV-VOLTAGE>`
-
--  :ref:`DTV_TONE <DTV-TONE>`
-
-In addition, the :ref:`DTV QoS statistics <frontend-stat-properties>`
-are also valid.
-
-Future implementations might add those two missing parameters:
-
--  :ref:`DTV_DISEQC_MASTER <DTV-DISEQC-MASTER>`
-
--  :ref:`DTV_DISEQC_SLAVE_REPLY <DTV-DISEQC-SLAVE-REPLY>`
-
-
-.. _dvbs2-params:
-
-DVB-S2 delivery system
-======================
-
-In addition to all parameters valid for DVB-S, DVB-S2 supports the
-following parameters:
-
--  :ref:`DTV_MODULATION <DTV-MODULATION>`
-
--  :ref:`DTV_PILOT <DTV-PILOT>`
-
--  :ref:`DTV_ROLLOFF <DTV-ROLLOFF>`
-
--  :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.
-
-
-.. _turbo-params:
-
-Turbo code delivery system
-==========================
-
-In addition to all parameters valid for DVB-S, turbo code supports the
-following parameters:
-
--  :ref:`DTV_MODULATION <DTV-MODULATION>`
-
-
-.. _isdbs-params:
-
-ISDB-S delivery system
-======================
-
-The following parameters are valid for ISDB-S:
-
--  :ref:`DTV_API_VERSION <DTV-API-VERSION>`
-
--  :ref:`DTV_DELIVERY_SYSTEM <DTV-DELIVERY-SYSTEM>`
-
--  :ref:`DTV_TUNE <DTV-TUNE>`
-
--  :ref:`DTV_CLEAR <DTV-CLEAR>`
-
--  :ref:`DTV_FREQUENCY <DTV-FREQUENCY>`
-
--  :ref:`DTV_INVERSION <DTV-INVERSION>`
-
--  :ref:`DTV_SYMBOL_RATE <DTV-SYMBOL-RATE>`
-
--  :ref:`DTV_INNER_FEC <DTV-INNER-FEC>`
-
--  :ref:`DTV_VOLTAGE <DTV-VOLTAGE>`
-
--  :ref:`DTV_STREAM_ID <DTV-STREAM-ID>`
diff --git a/Documentation/media/uapi/dvb/frontend-property-terrestrial-systems.rst b/Documentation/media/uapi/dvb/frontend-property-terrestrial-systems.rst
deleted file mode 100644
index c20af13297e5..000000000000
--- a/Documentation/media/uapi/dvb/frontend-property-terrestrial-systems.rst
+++ /dev/null
@@ -1,301 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _frontend-property-terrestrial-systems:
-
-***********************************************
-Properties used on terrestrial delivery systems
-***********************************************
-
-
-.. _dvbt-params:
-
-DVB-T delivery system
-=====================
-
-The following parameters are valid for DVB-T:
-
--  :ref:`DTV_API_VERSION <DTV-API-VERSION>`
-
--  :ref:`DTV_DELIVERY_SYSTEM <DTV-DELIVERY-SYSTEM>`
-
--  :ref:`DTV_TUNE <DTV-TUNE>`
-
--  :ref:`DTV_CLEAR <DTV-CLEAR>`
-
--  :ref:`DTV_FREQUENCY <DTV-FREQUENCY>`
-
--  :ref:`DTV_MODULATION <DTV-MODULATION>`
-
--  :ref:`DTV_BANDWIDTH_HZ <DTV-BANDWIDTH-HZ>`
-
--  :ref:`DTV_INVERSION <DTV-INVERSION>`
-
--  :ref:`DTV_CODE_RATE_HP <DTV-CODE-RATE-HP>`
-
--  :ref:`DTV_CODE_RATE_LP <DTV-CODE-RATE-LP>`
-
--  :ref:`DTV_GUARD_INTERVAL <DTV-GUARD-INTERVAL>`
-
--  :ref:`DTV_TRANSMISSION_MODE <DTV-TRANSMISSION-MODE>`
-
--  :ref:`DTV_HIERARCHY <DTV-HIERARCHY>`
-
--  :ref:`DTV_LNA <DTV-LNA>`
-
-In addition, the :ref:`DTV QoS statistics <frontend-stat-properties>`
-are also valid.
-
-
-.. _dvbt2-params:
-
-DVB-T2 delivery system
-======================
-
-DVB-T2 support is currently in the early stages of development, so
-expect that this section maygrow and become more detailed with time.
-
-The following parameters are valid for DVB-T2:
-
--  :ref:`DTV_API_VERSION <DTV-API-VERSION>`
-
--  :ref:`DTV_DELIVERY_SYSTEM <DTV-DELIVERY-SYSTEM>`
-
--  :ref:`DTV_TUNE <DTV-TUNE>`
-
--  :ref:`DTV_CLEAR <DTV-CLEAR>`
-
--  :ref:`DTV_FREQUENCY <DTV-FREQUENCY>`
-
--  :ref:`DTV_MODULATION <DTV-MODULATION>`
-
--  :ref:`DTV_BANDWIDTH_HZ <DTV-BANDWIDTH-HZ>`
-
--  :ref:`DTV_INVERSION <DTV-INVERSION>`
-
--  :ref:`DTV_CODE_RATE_HP <DTV-CODE-RATE-HP>`
-
--  :ref:`DTV_CODE_RATE_LP <DTV-CODE-RATE-LP>`
-
--  :ref:`DTV_GUARD_INTERVAL <DTV-GUARD-INTERVAL>`
-
--  :ref:`DTV_TRANSMISSION_MODE <DTV-TRANSMISSION-MODE>`
-
--  :ref:`DTV_HIERARCHY <DTV-HIERARCHY>`
-
--  :ref:`DTV_STREAM_ID <DTV-STREAM-ID>`
-
--  :ref:`DTV_LNA <DTV-LNA>`
-
-In addition, the :ref:`DTV QoS statistics <frontend-stat-properties>`
-are also valid.
-
-
-.. _isdbt:
-
-ISDB-T delivery system
-======================
-
-This ISDB-T/ISDB-Tsb API extension should reflect all information needed
-to tune any ISDB-T/ISDB-Tsb hardware. Of course it is possible that some
-very sophisticated devices won't need certain parameters to tune.
-
-The information given here should help application writers to know how
-to handle ISDB-T and ISDB-Tsb hardware using the Linux Digital TV API.
-
-The details given here about ISDB-T and ISDB-Tsb are just enough to
-basically show the dependencies between the needed parameter values, but
-surely some information is left out. For more detailed information see
-the following documents:
-
-ARIB STD-B31 - "Transmission System for Digital Terrestrial Television
-Broadcasting" and
-
-ARIB TR-B14 - "Operational Guidelines for Digital Terrestrial Television
-Broadcasting".
-
-In order to understand the ISDB specific parameters, one has to have
-some knowledge the channel structure in ISDB-T and ISDB-Tsb. I.e. it has
-to be known to the reader that an ISDB-T channel consists of 13
-segments, that it can have up to 3 layer sharing those segments, and
-things like that.
-
-The following parameters are valid for ISDB-T:
-
--  :ref:`DTV_API_VERSION <DTV-API-VERSION>`
-
--  :ref:`DTV_DELIVERY_SYSTEM <DTV-DELIVERY-SYSTEM>`
-
--  :ref:`DTV_TUNE <DTV-TUNE>`
-
--  :ref:`DTV_CLEAR <DTV-CLEAR>`
-
--  :ref:`DTV_FREQUENCY <DTV-FREQUENCY>`
-
--  :ref:`DTV_BANDWIDTH_HZ <DTV-BANDWIDTH-HZ>`
-
--  :ref:`DTV_INVERSION <DTV-INVERSION>`
-
--  :ref:`DTV_GUARD_INTERVAL <DTV-GUARD-INTERVAL>`
-
--  :ref:`DTV_TRANSMISSION_MODE <DTV-TRANSMISSION-MODE>`
-
--  :ref:`DTV_ISDBT_LAYER_ENABLED <DTV-ISDBT-LAYER-ENABLED>`
-
--  :ref:`DTV_ISDBT_PARTIAL_RECEPTION <DTV-ISDBT-PARTIAL-RECEPTION>`
-
--  :ref:`DTV_ISDBT_SOUND_BROADCASTING <DTV-ISDBT-SOUND-BROADCASTING>`
-
--  :ref:`DTV_ISDBT_SB_SUBCHANNEL_ID <DTV-ISDBT-SB-SUBCHANNEL-ID>`
-
--  :ref:`DTV_ISDBT_SB_SEGMENT_IDX <DTV-ISDBT-SB-SEGMENT-IDX>`
-
--  :ref:`DTV_ISDBT_SB_SEGMENT_COUNT <DTV-ISDBT-SB-SEGMENT-COUNT>`
-
--  :ref:`DTV_ISDBT_LAYERA_FEC <DTV-ISDBT-LAYER-FEC>`
-
--  :ref:`DTV_ISDBT_LAYERA_MODULATION <DTV-ISDBT-LAYER-MODULATION>`
-
--  :ref:`DTV_ISDBT_LAYERA_SEGMENT_COUNT <DTV-ISDBT-LAYER-SEGMENT-COUNT>`
-
--  :ref:`DTV_ISDBT_LAYERA_TIME_INTERLEAVING <DTV-ISDBT-LAYER-TIME-INTERLEAVING>`
-
--  :ref:`DTV_ISDBT_LAYERB_FEC <DTV-ISDBT-LAYER-FEC>`
-
--  :ref:`DTV_ISDBT_LAYERB_MODULATION <DTV-ISDBT-LAYER-MODULATION>`
-
--  :ref:`DTV_ISDBT_LAYERB_SEGMENT_COUNT <DTV-ISDBT-LAYER-SEGMENT-COUNT>`
-
--  :ref:`DTV_ISDBT_LAYERB_TIME_INTERLEAVING <DTV-ISDBT-LAYER-TIME-INTERLEAVING>`
-
--  :ref:`DTV_ISDBT_LAYERC_FEC <DTV-ISDBT-LAYER-FEC>`
-
--  :ref:`DTV_ISDBT_LAYERC_MODULATION <DTV-ISDBT-LAYER-MODULATION>`
-
--  :ref:`DTV_ISDBT_LAYERC_SEGMENT_COUNT <DTV-ISDBT-LAYER-SEGMENT-COUNT>`
-
--  :ref:`DTV_ISDBT_LAYERC_TIME_INTERLEAVING <DTV-ISDBT-LAYER-TIME-INTERLEAVING>`
-
-In addition, the :ref:`DTV QoS statistics <frontend-stat-properties>`
-are also valid.
-
-
-.. _atsc-params:
-
-ATSC delivery system
-====================
-
-The following parameters are valid for ATSC:
-
--  :ref:`DTV_API_VERSION <DTV-API-VERSION>`
-
--  :ref:`DTV_DELIVERY_SYSTEM <DTV-DELIVERY-SYSTEM>`
-
--  :ref:`DTV_TUNE <DTV-TUNE>`
-
--  :ref:`DTV_CLEAR <DTV-CLEAR>`
-
--  :ref:`DTV_FREQUENCY <DTV-FREQUENCY>`
-
--  :ref:`DTV_MODULATION <DTV-MODULATION>`
-
--  :ref:`DTV_BANDWIDTH_HZ <DTV-BANDWIDTH-HZ>`
-
-In addition, the :ref:`DTV QoS statistics <frontend-stat-properties>`
-are also valid.
-
-
-.. _atscmh-params:
-
-ATSC-MH delivery system
-=======================
-
-The following parameters are valid for ATSC-MH:
-
--  :ref:`DTV_API_VERSION <DTV-API-VERSION>`
-
--  :ref:`DTV_DELIVERY_SYSTEM <DTV-DELIVERY-SYSTEM>`
-
--  :ref:`DTV_TUNE <DTV-TUNE>`
-
--  :ref:`DTV_CLEAR <DTV-CLEAR>`
-
--  :ref:`DTV_FREQUENCY <DTV-FREQUENCY>`
-
--  :ref:`DTV_BANDWIDTH_HZ <DTV-BANDWIDTH-HZ>`
-
--  :ref:`DTV_ATSCMH_FIC_VER <DTV-ATSCMH-FIC-VER>`
-
--  :ref:`DTV_ATSCMH_PARADE_ID <DTV-ATSCMH-PARADE-ID>`
-
--  :ref:`DTV_ATSCMH_NOG <DTV-ATSCMH-NOG>`
-
--  :ref:`DTV_ATSCMH_TNOG <DTV-ATSCMH-TNOG>`
-
--  :ref:`DTV_ATSCMH_SGN <DTV-ATSCMH-SGN>`
-
--  :ref:`DTV_ATSCMH_PRC <DTV-ATSCMH-PRC>`
-
--  :ref:`DTV_ATSCMH_RS_FRAME_MODE <DTV-ATSCMH-RS-FRAME-MODE>`
-
--  :ref:`DTV_ATSCMH_RS_FRAME_ENSEMBLE <DTV-ATSCMH-RS-FRAME-ENSEMBLE>`
-
--  :ref:`DTV_ATSCMH_RS_CODE_MODE_PRI <DTV-ATSCMH-RS-CODE-MODE-PRI>`
-
--  :ref:`DTV_ATSCMH_RS_CODE_MODE_SEC <DTV-ATSCMH-RS-CODE-MODE-SEC>`
-
--  :ref:`DTV_ATSCMH_SCCC_BLOCK_MODE <DTV-ATSCMH-SCCC-BLOCK-MODE>`
-
--  :ref:`DTV_ATSCMH_SCCC_CODE_MODE_A <DTV-ATSCMH-SCCC-CODE-MODE-A>`
-
--  :ref:`DTV_ATSCMH_SCCC_CODE_MODE_B <DTV-ATSCMH-SCCC-CODE-MODE-B>`
-
--  :ref:`DTV_ATSCMH_SCCC_CODE_MODE_C <DTV-ATSCMH-SCCC-CODE-MODE-C>`
-
--  :ref:`DTV_ATSCMH_SCCC_CODE_MODE_D <DTV-ATSCMH-SCCC-CODE-MODE-D>`
-
-In addition, the :ref:`DTV QoS statistics <frontend-stat-properties>`
-are also valid.
-
-
-.. _dtmb-params:
-
-DTMB delivery system
-====================
-
-The following parameters are valid for DTMB:
-
--  :ref:`DTV_API_VERSION <DTV-API-VERSION>`
-
--  :ref:`DTV_DELIVERY_SYSTEM <DTV-DELIVERY-SYSTEM>`
-
--  :ref:`DTV_TUNE <DTV-TUNE>`
-
--  :ref:`DTV_CLEAR <DTV-CLEAR>`
-
--  :ref:`DTV_FREQUENCY <DTV-FREQUENCY>`
-
--  :ref:`DTV_MODULATION <DTV-MODULATION>`
-
--  :ref:`DTV_BANDWIDTH_HZ <DTV-BANDWIDTH-HZ>`
-
--  :ref:`DTV_INVERSION <DTV-INVERSION>`
-
--  :ref:`DTV_INNER_FEC <DTV-INNER-FEC>`
-
--  :ref:`DTV_GUARD_INTERVAL <DTV-GUARD-INTERVAL>`
-
--  :ref:`DTV_TRANSMISSION_MODE <DTV-TRANSMISSION-MODE>`
-
--  :ref:`DTV_INTERLEAVING <DTV-INTERLEAVING>`
-
--  :ref:`DTV_LNA <DTV-LNA>`
-
-In addition, the :ref:`DTV QoS statistics <frontend-stat-properties>`
-are also valid.
diff --git a/Documentation/media/uapi/dvb/frontend-stat-properties.rst b/Documentation/media/uapi/dvb/frontend-stat-properties.rst
deleted file mode 100644
index 546464db04b5..000000000000
--- a/Documentation/media/uapi/dvb/frontend-stat-properties.rst
+++ /dev/null
@@ -1,252 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _frontend-stat-properties:
-
-******************************
-Frontend statistics indicators
-******************************
-
-The values are returned via ``dtv_property.stat``. If the property is
-supported, ``dtv_property.stat.len`` is bigger than zero.
-
-For most delivery systems, ``dtv_property.stat.len`` will be 1 if the
-stats is supported, and the properties will return a single value for
-each parameter.
-
-It should be noted, however, that new OFDM delivery systems like ISDB
-can use different modulation types for each group of carriers. On such
-standards, up to 3 groups of statistics can be provided, and
-``dtv_property.stat.len`` is updated to reflect the "global" metrics,
-plus one metric per each carrier group (called "layer" on ISDB).
-
-So, in order to be consistent with other delivery systems, the first
-value at :c:type:`dtv_property.stat.dtv_stats <dtv_stats>` array refers
-to the global metric. The other elements of the array represent each
-layer, starting from layer A(index 1), layer B (index 2) and so on.
-
-The number of filled elements are stored at ``dtv_property.stat.len``.
-
-Each element of the ``dtv_property.stat.dtv_stats`` array consists on
-two elements:
-
--  ``svalue`` or ``uvalue``, where ``svalue`` is for signed values of
-   the measure (dB measures) and ``uvalue`` is for unsigned values
-   (counters, relative scale)
-
--  ``scale`` - Scale for the value. It can be:
-
-   -  ``FE_SCALE_NOT_AVAILABLE`` - The parameter is supported by the
-      frontend, but it was not possible to collect it (could be a
-      transitory or permanent condition)
-
-   -  ``FE_SCALE_DECIBEL`` - parameter is a signed value, measured in
-      1/1000 dB
-
-   -  ``FE_SCALE_RELATIVE`` - parameter is a unsigned value, where 0
-      means 0% and 65535 means 100%.
-
-   -  ``FE_SCALE_COUNTER`` - parameter is a unsigned value that counts
-      the occurrence of an event, like bit error, block error, or lapsed
-      time.
-
-
-.. _DTV-STAT-SIGNAL-STRENGTH:
-
-DTV_STAT_SIGNAL_STRENGTH
-========================
-
-Indicates the signal strength level at the analog part of the tuner or
-of the demod.
-
-Possible scales for this metric are:
-
--  ``FE_SCALE_NOT_AVAILABLE`` - it failed to measure it, or the
-   measurement was not complete yet.
-
--  ``FE_SCALE_DECIBEL`` - signal strength is in 0.001 dBm units, power
-   measured in miliwatts. This value is generally negative.
-
--  ``FE_SCALE_RELATIVE`` - The frontend provides a 0% to 100%
-   measurement for power (actually, 0 to 65535).
-
-
-.. _DTV-STAT-CNR:
-
-DTV_STAT_CNR
-============
-
-Indicates the Signal to Noise ratio for the main carrier.
-
-Possible scales for this metric are:
-
--  ``FE_SCALE_NOT_AVAILABLE`` - it failed to measure it, or the
-   measurement was not complete yet.
-
--  ``FE_SCALE_DECIBEL`` - Signal/Noise ratio is in 0.001 dB units.
-
--  ``FE_SCALE_RELATIVE`` - The frontend provides a 0% to 100%
-   measurement for Signal/Noise (actually, 0 to 65535).
-
-
-.. _DTV-STAT-PRE-ERROR-BIT-COUNT:
-
-DTV_STAT_PRE_ERROR_BIT_COUNT
-============================
-
-Measures the number of bit errors before the forward error correction
-(FEC) on the inner coding block (before Viterbi, LDPC or other inner
-code).
-
-This measure is taken during the same interval as
-``DTV_STAT_PRE_TOTAL_BIT_COUNT``.
-
-In order to get the BER (Bit Error Rate) measurement, it should be
-divided by
-:ref:`DTV_STAT_PRE_TOTAL_BIT_COUNT <DTV-STAT-PRE-TOTAL-BIT-COUNT>`.
-
-This measurement is monotonically increased, as the frontend gets more
-bit count measurements. The frontend may reset it when a
-channel/transponder is tuned.
-
-Possible scales for this metric are:
-
--  ``FE_SCALE_NOT_AVAILABLE`` - it failed to measure it, or the
-   measurement was not complete yet.
-
--  ``FE_SCALE_COUNTER`` - Number of error bits counted before the inner
-   coding.
-
-
-.. _DTV-STAT-PRE-TOTAL-BIT-COUNT:
-
-DTV_STAT_PRE_TOTAL_BIT_COUNT
-============================
-
-Measures the amount of bits received before the inner code block, during
-the same period as
-:ref:`DTV_STAT_PRE_ERROR_BIT_COUNT <DTV-STAT-PRE-ERROR-BIT-COUNT>`
-measurement was taken.
-
-It should be noted that this measurement can be smaller than the total
-amount of bits on the transport stream, as the frontend may need to
-manually restart the measurement, losing some data between each
-measurement interval.
-
-This measurement is monotonically increased, as the frontend gets more
-bit count measurements. The frontend may reset it when a
-channel/transponder is tuned.
-
-Possible scales for this metric are:
-
--  ``FE_SCALE_NOT_AVAILABLE`` - it failed to measure it, or the
-   measurement was not complete yet.
-
--  ``FE_SCALE_COUNTER`` - Number of bits counted while measuring
-   :ref:`DTV_STAT_PRE_ERROR_BIT_COUNT <DTV-STAT-PRE-ERROR-BIT-COUNT>`.
-
-
-.. _DTV-STAT-POST-ERROR-BIT-COUNT:
-
-DTV_STAT_POST_ERROR_BIT_COUNT
-=============================
-
-Measures the number of bit errors after the forward error correction
-(FEC) done by inner code block (after Viterbi, LDPC or other inner
-code).
-
-This measure is taken during the same interval as
-``DTV_STAT_POST_TOTAL_BIT_COUNT``.
-
-In order to get the BER (Bit Error Rate) measurement, it should be
-divided by
-:ref:`DTV_STAT_POST_TOTAL_BIT_COUNT <DTV-STAT-POST-TOTAL-BIT-COUNT>`.
-
-This measurement is monotonically increased, as the frontend gets more
-bit count measurements. The frontend may reset it when a
-channel/transponder is tuned.
-
-Possible scales for this metric are:
-
--  ``FE_SCALE_NOT_AVAILABLE`` - it failed to measure it, or the
-   measurement was not complete yet.
-
--  ``FE_SCALE_COUNTER`` - Number of error bits counted after the inner
-   coding.
-
-
-.. _DTV-STAT-POST-TOTAL-BIT-COUNT:
-
-DTV_STAT_POST_TOTAL_BIT_COUNT
-=============================
-
-Measures the amount of bits received after the inner coding, during the
-same period as
-:ref:`DTV_STAT_POST_ERROR_BIT_COUNT <DTV-STAT-POST-ERROR-BIT-COUNT>`
-measurement was taken.
-
-It should be noted that this measurement can be smaller than the total
-amount of bits on the transport stream, as the frontend may need to
-manually restart the measurement, losing some data between each
-measurement interval.
-
-This measurement is monotonically increased, as the frontend gets more
-bit count measurements. The frontend may reset it when a
-channel/transponder is tuned.
-
-Possible scales for this metric are:
-
--  ``FE_SCALE_NOT_AVAILABLE`` - it failed to measure it, or the
-   measurement was not complete yet.
-
--  ``FE_SCALE_COUNTER`` - Number of bits counted while measuring
-   :ref:`DTV_STAT_POST_ERROR_BIT_COUNT <DTV-STAT-POST-ERROR-BIT-COUNT>`.
-
-
-.. _DTV-STAT-ERROR-BLOCK-COUNT:
-
-DTV_STAT_ERROR_BLOCK_COUNT
-==========================
-
-Measures the number of block errors after the outer forward error
-correction coding (after Reed-Solomon or other outer code).
-
-This measurement is monotonically increased, as the frontend gets more
-bit count measurements. The frontend may reset it when a
-channel/transponder is tuned.
-
-Possible scales for this metric are:
-
--  ``FE_SCALE_NOT_AVAILABLE`` - it failed to measure it, or the
-   measurement was not complete yet.
-
--  ``FE_SCALE_COUNTER`` - Number of error blocks counted after the outer
-   coding.
-
-
-.. _DTV-STAT-TOTAL-BLOCK-COUNT:
-
-DTV-STAT_TOTAL_BLOCK_COUNT
-==========================
-
-Measures the total number of blocks received during the same period as
-:ref:`DTV_STAT_ERROR_BLOCK_COUNT <DTV-STAT-ERROR-BLOCK-COUNT>`
-measurement was taken.
-
-It can be used to calculate the PER indicator, by dividing
-:ref:`DTV_STAT_ERROR_BLOCK_COUNT <DTV-STAT-ERROR-BLOCK-COUNT>` by
-:ref:`DTV-STAT-TOTAL-BLOCK-COUNT`.
-
-Possible scales for this metric are:
-
--  ``FE_SCALE_NOT_AVAILABLE`` - it failed to measure it, or the
-   measurement was not complete yet.
-
--  ``FE_SCALE_COUNTER`` - Number of blocks counted while measuring
-   :ref:`DTV_STAT_ERROR_BLOCK_COUNT <DTV-STAT-ERROR-BLOCK-COUNT>`.
diff --git a/Documentation/media/uapi/dvb/frontend.rst b/Documentation/media/uapi/dvb/frontend.rst
deleted file mode 100644
index 7ff225dfe11c..000000000000
--- a/Documentation/media/uapi/dvb/frontend.rst
+++ /dev/null
@@ -1,63 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _dvb_frontend:
-
-#######################
-Digital TV Frontend API
-#######################
-
-The Digital TV frontend API was designed to support three groups of delivery
-systems: Terrestrial, cable and Satellite. Currently, the following
-delivery systems are supported:
-
--  Terrestrial systems: DVB-T, DVB-T2, ATSC, ATSC M/H, ISDB-T, DVB-H,
-   DTMB, CMMB
-
--  Cable systems: DVB-C Annex A/C, ClearQAM (DVB-C Annex B)
-
--  Satellite systems: DVB-S, DVB-S2, DVB Turbo, ISDB-S, DSS
-
-The Digital TV frontend controls several sub-devices including:
-
--  Tuner
-
--  Digital TV demodulator
-
--  Low noise amplifier (LNA)
-
--  Satellite Equipment Control (SEC) [#f1]_.
-
-The frontend can be accessed through ``/dev/dvb/adapter?/frontend?``.
-Data types and ioctl definitions can be accessed by including
-``linux/dvb/frontend.h`` in your application.
-
-.. note::
-
-   Transmission via the internet (DVB-IP) and MMT (MPEG Media Transport)
-   is not yet handled by this API but a future extension is possible.
-
-.. [#f1]
-
-   On Satellite systems, the API support for the Satellite Equipment
-   Control (SEC) allows to power control and to send/receive signals to
-   control the antenna subsystem, selecting the polarization and choosing
-   the Intermediate Frequency IF) of the Low Noise Block Converter Feed
-   Horn (LNBf). It supports the DiSEqC and V-SEC protocols. The DiSEqC
-   (digital SEC) specification is available at
-   `Eutelsat <http://www.eutelsat.com/satellites/4_5_5.html>`__.
-
-
-.. toctree::
-    :maxdepth: 1
-
-    query-dvb-frontend-info
-    dvb-fe-read-status
-    dvbproperty
-    frontend_fcalls
diff --git a/Documentation/media/uapi/dvb/frontend_f_close.rst b/Documentation/media/uapi/dvb/frontend_f_close.rst
deleted file mode 100644
index af87c2a83719..000000000000
--- a/Documentation/media/uapi/dvb/frontend_f_close.rst
+++ /dev/null
@@ -1,57 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _frontend_f_close:
-
-***************************
-Digital TV frontend close()
-***************************
-
-Name
-====
-
-fe-close - Close a frontend device
-
-
-Synopsis
-========
-
-.. code-block:: c
-
-    #include <unistd.h>
-
-
-.. c:function:: int close( int fd )
-    :name: dvb-fe-close
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :c:func:`open() <dvb-fe-open>`.
-
-
-Description
-===========
-
-This system call closes a previously opened front-end device. After
-closing a front-end device, its corresponding hardware might be powered
-down automatically.
-
-
-Return Value
-============
-
-On success 0 is returned.
-
-On error -1 is returned, and the ``errno`` variable is set
-appropriately.
-
-Generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/media/uapi/dvb/frontend_f_open.rst b/Documentation/media/uapi/dvb/frontend_f_open.rst
deleted file mode 100644
index 6a46ec5acf7b..000000000000
--- a/Documentation/media/uapi/dvb/frontend_f_open.rst
+++ /dev/null
@@ -1,117 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _frontend_f_open:
-
-***************************
-Digital TV frontend open()
-***************************
-
-Name
-====
-
-fe-open - Open a frontend device
-
-
-Synopsis
-========
-
-.. code-block:: c
-
-    #include <fcntl.h>
-
-
-.. c:function:: int open( const char *device_name, int flags )
-    :name: dvb-fe-open
-
-Arguments
-=========
-
-``device_name``
-    Device to be opened.
-
-``flags``
-    Open flags. Access can either be ``O_RDWR`` or ``O_RDONLY``.
-
-    Multiple opens are allowed with ``O_RDONLY``. In this mode, only
-    query and read ioctls are allowed.
-
-    Only one open is allowed in ``O_RDWR``. In this mode, all ioctls are
-    allowed.
-
-    When the ``O_NONBLOCK`` flag is given, the system calls may return
-    ``EAGAIN`` error code when no data is available or when the device
-    driver is temporarily busy.
-
-    Other flags have no effect.
-
-
-Description
-===========
-
-This system call opens a named frontend device
-(``/dev/dvb/adapter?/frontend?``) for subsequent use. Usually the first
-thing to do after a successful open is to find out the frontend type
-with :ref:`FE_GET_INFO`.
-
-The device can be opened in read-only mode, which only allows monitoring
-of device status and statistics, or read/write mode, which allows any
-kind of use (e.g. performing tuning operations.)
-
-In a system with multiple front-ends, it is usually the case that
-multiple devices cannot be open in read/write mode simultaneously. As
-long as a front-end device is opened in read/write mode, other open()
-calls in read/write mode will either fail or block, depending on whether
-non-blocking or blocking mode was specified. A front-end device opened
-in blocking mode can later be put into non-blocking mode (and vice
-versa) using the F_SETFL command of the fcntl system call. This is a
-standard system call, documented in the Linux manual page for fcntl.
-When an open() call has succeeded, the device will be ready for use in
-the specified mode. This implies that the corresponding hardware is
-powered up, and that other front-ends may have been powered down to make
-that possible.
-
-
-Return Value
-============
-
-On success :ref:`open() <frontend_f_open>` returns the new file descriptor.
-On error, -1 is returned, and the ``errno`` variable is set appropriately.
-
-Possible error codes are:
-
-
-On success 0 is returned, and :c:type:`ca_slot_info` is filled.
-
-On error -1 is returned, and the ``errno`` variable is set
-appropriately.
-
-.. tabularcolumns:: |p{2.5cm}|p{15.0cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths: 1 16
-
-    -  - ``EPERM``
-       -  The caller has no permission to access the device.
-
-    -  - ``EBUSY``
-       -  The the device driver is already in use.
-
-    -  - ``EMFILE``
-       -  The process already has the maximum number of files open.
-
-    -  - ``ENFILE``
-       -  The limit on the total number of files open on the system has been
-	  reached.
-
-
-The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/media/uapi/dvb/frontend_fcalls.rst b/Documentation/media/uapi/dvb/frontend_fcalls.rst
deleted file mode 100644
index 9b3586f538ea..000000000000
--- a/Documentation/media/uapi/dvb/frontend_fcalls.rst
+++ /dev/null
@@ -1,31 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _frontend_fcalls:
-
-#######################
-Frontend Function Calls
-#######################
-
-.. toctree::
-    :maxdepth: 1
-
-    frontend_f_open
-    frontend_f_close
-    fe-get-info
-    fe-read-status
-    fe-get-property
-    fe-diseqc-reset-overload
-    fe-diseqc-send-master-cmd
-    fe-diseqc-recv-slave-reply
-    fe-diseqc-send-burst
-    fe-set-tone
-    fe-set-voltage
-    fe-enable-high-lnb-voltage
-    fe-set-frontend-tune-mode
diff --git a/Documentation/media/uapi/dvb/frontend_legacy_api.rst b/Documentation/media/uapi/dvb/frontend_legacy_api.rst
deleted file mode 100644
index 1ea749d09ca2..000000000000
--- a/Documentation/media/uapi/dvb/frontend_legacy_api.rst
+++ /dev/null
@@ -1,45 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _frontend_legacy_types:
-
-Frontend Legacy Data Types
-==========================
-
-
-.. toctree::
-    :maxdepth: 1
-
-    fe-type-t
-    fe-bandwidth-t
-    dvb-frontend-parameters
-    dvb-frontend-event
-
-
-.. _frontend_legacy_fcalls:
-
-Frontend Legacy Function Calls
-==============================
-
-Those functions are defined at DVB version 3. The support is kept in the
-kernel due to compatibility issues only. Their usage is strongly not
-recommended
-
-
-.. toctree::
-    :maxdepth: 1
-
-    fe-read-ber
-    fe-read-snr
-    fe-read-signal-strength
-    fe-read-uncorrected-blocks
-    fe-set-frontend
-    fe-get-frontend
-    fe-get-event
-    fe-dishnetwork-send-legacy-cmd
diff --git a/Documentation/media/uapi/dvb/frontend_legacy_dvbv3_api.rst b/Documentation/media/uapi/dvb/frontend_legacy_dvbv3_api.rst
deleted file mode 100644
index 1567bc73855a..000000000000
--- a/Documentation/media/uapi/dvb/frontend_legacy_dvbv3_api.rst
+++ /dev/null
@@ -1,25 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _frontend_legacy_dvbv3_api:
-
-***********************************************
-Digital TV Frontend legacy API (a. k. a. DVBv3)
-***********************************************
-
-The usage of this API is deprecated, as it doesn't support all digital
-TV standards, doesn't provide good statistics measurements and provides
-incomplete information. This is kept only to support legacy
-applications.
-
-
-.. toctree::
-    :maxdepth: 1
-
-    frontend_legacy_api
diff --git a/Documentation/media/uapi/dvb/headers.rst b/Documentation/media/uapi/dvb/headers.rst
deleted file mode 100644
index edeabd9e8e90..000000000000
--- a/Documentation/media/uapi/dvb/headers.rst
+++ /dev/null
@@ -1,30 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-****************************
-Digital TV uAPI header files
-****************************
-
-Digital TV uAPI headers
-***********************
-
-.. kernel-include:: $BUILDDIR/frontend.h.rst
-
-.. kernel-include:: $BUILDDIR/dmx.h.rst
-
-.. kernel-include:: $BUILDDIR/ca.h.rst
-
-.. kernel-include:: $BUILDDIR/net.h.rst
-
-Legacy uAPI
-***********
-
-.. kernel-include:: $BUILDDIR/audio.h.rst
-
-.. kernel-include:: $BUILDDIR/video.h.rst
diff --git a/Documentation/media/uapi/dvb/intro.rst b/Documentation/media/uapi/dvb/intro.rst
deleted file mode 100644
index f1384616ac4e..000000000000
--- a/Documentation/media/uapi/dvb/intro.rst
+++ /dev/null
@@ -1,190 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _dvb_introdution:
-
-************
-Introduction
-************
-
-
-.. _requisites:
-
-What you need to know
-=====================
-
-The reader of this document is required to have some knowledge in the
-area of digital video broadcasting (Digital TV) and should be familiar with
-part I of the MPEG2 specification ISO/IEC 13818 (aka ITU-T H.222), i.e
-you should know what a program/transport stream (PS/TS) is and what is
-meant by a packetized elementary stream (PES) or an I-frame.
-
-Various Digital TV standards documents are available for download at:
-
-- European standards (DVB): http://www.dvb.org and/or http://www.etsi.org.
-- American standards (ATSC): https://www.atsc.org/standards/
-- Japanese standards (ISDB): http://www.dibeg.org/
-
-It is also necessary to know how to access Linux devices and how to
-use ioctl calls. This also includes the knowledge of C or C++.
-
-
-.. _history:
-
-History
-=======
-
-The first API for Digital TV cards we used at Convergence in late 1999 was an
-extension of the Video4Linux API which was primarily developed for frame
-grabber cards. As such it was not really well suited to be used for Digital
-TV cards and their new features like recording MPEG streams and filtering
-several section and PES data streams at the same time.
-
-In early 2000, Convergence was approached by Nokia with a proposal for a new
-standard Linux Digital TV API. As a commitment to the development of terminals
-based on open standards, Nokia and Convergence made it available to all
-Linux developers and published it on https://linuxtv.org in September
-2000. With the Linux driver for the Siemens/Hauppauge DVB PCI card,
-Convergence provided a first implementation of the Linux Digital TV API.
-Convergence was the maintainer of the Linux Digital TV API in the early
-days.
-
-Now, the API is maintained by the LinuxTV community (i.e. you, the reader
-of this document). The Linux  Digital TV API is constantly reviewed and
-improved together with the improvements at the subsystem's core at the
-Kernel.
-
-
-.. _overview:
-
-Overview
-========
-
-
-.. _stb_components:
-
-.. kernel-figure:: dvbstb.svg
-    :alt:   dvbstb.svg
-    :align: center
-
-    Components of a Digital TV card/STB
-
-A Digital TV card or set-top-box (STB) usually consists of the
-following main hardware components:
-
-Frontend consisting of tuner and digital TV demodulator
-   Here the raw signal reaches the digital TV hardware from a satellite dish or
-   antenna or directly from cable. The frontend down-converts and
-   demodulates this signal into an MPEG transport stream (TS). In case
-   of a satellite frontend, this includes a facility for satellite
-   equipment control (SEC), which allows control of LNB polarization,
-   multi feed switches or dish rotors.
-
-Conditional Access (CA) hardware like CI adapters and smartcard slots
-   The complete TS is passed through the CA hardware. Programs to which
-   the user has access (controlled by the smart card) are decoded in
-   real time and re-inserted into the TS.
-
-   .. note::
-
-      Not every digital TV hardware provides conditional access hardware.
-
-Demultiplexer which filters the incoming Digital TV MPEG-TS stream
-   The demultiplexer splits the TS into its components like audio and
-   video streams. Besides usually several of such audio and video
-   streams it also contains data streams with information about the
-   programs offered in this or other streams of the same provider.
-
-Audio and video decoder
-   The main targets of the demultiplexer are audio and video
-   decoders. After decoding, they pass on the uncompressed audio and
-   video to the computer screen or to a TV set.
-
-   .. note::
-
-      Modern hardware usually doesn't have a separate decoder hardware, as
-      such functionality can be provided by the main CPU, by the graphics
-      adapter of the system or by a signal processing hardware embedded on
-      a Systems on a Chip (SoC) integrated circuit.
-
-      It may also not be needed for certain usages (e.g. for data-only
-      uses like “internet over satellite”).
-
-:ref:`stb_components` shows a crude schematic of the control and data
-flow between those components.
-
-
-
-.. _dvb_devices:
-
-Linux Digital TV Devices
-========================
-
-The Linux Digital TV API lets you control these hardware components through
-currently six Unix-style character devices for video, audio, frontend,
-demux, CA and IP-over-DVB networking. The video and audio devices
-control the MPEG2 decoder hardware, the frontend device the tuner and
-the Digital TV demodulator. The demux device gives you control over the PES
-and section filters of the hardware. If the hardware does not support
-filtering these filters can be implemented in software. Finally, the CA
-device controls all the conditional access capabilities of the hardware.
-It can depend on the individual security requirements of the platform,
-if and how many of the CA functions are made available to the
-application through this device.
-
-All devices can be found in the ``/dev`` tree under ``/dev/dvb``. The
-individual devices are called:
-
--  ``/dev/dvb/adapterN/audioM``,
-
--  ``/dev/dvb/adapterN/videoM``,
-
--  ``/dev/dvb/adapterN/frontendM``,
-
--  ``/dev/dvb/adapterN/netM``,
-
--  ``/dev/dvb/adapterN/demuxM``,
-
--  ``/dev/dvb/adapterN/dvrM``,
-
--  ``/dev/dvb/adapterN/caM``,
-
-where ``N`` enumerates the Digital TV cards in a system starting from 0, and
-``M`` enumerates the devices of each type within each adapter, starting
-from 0, too. We will omit the “``/dev/dvb/adapterN/``\ ” in the further
-discussion of these devices.
-
-More details about the data structures and function calls of all the
-devices are described in the following chapters.
-
-
-.. _include_files:
-
-API include files
-=================
-
-For each of the Digital TV devices a corresponding include file exists. The
-Digital TV API include files should be included in application sources with a
-partial path like:
-
-
-.. code-block:: c
-
-	#include <linux/dvb/ca.h>
-
-	#include <linux/dvb/dmx.h>
-
-	#include <linux/dvb/frontend.h>
-
-	#include <linux/dvb/net.h>
-
-
-To enable applications to support different API version, an additional
-include file ``linux/dvb/version.h`` exists, which defines the constant
-``DVB_API_VERSION``. This document describes ``DVB_API_VERSION 5.10``.
diff --git a/Documentation/media/uapi/dvb/legacy_dvb_apis.rst b/Documentation/media/uapi/dvb/legacy_dvb_apis.rst
deleted file mode 100644
index a43b4c36d935..000000000000
--- a/Documentation/media/uapi/dvb/legacy_dvb_apis.rst
+++ /dev/null
@@ -1,39 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _legacy_dvb_apis:
-
-***************************
-Digital TV Deprecated APIs
-***************************
-
-The APIs described here **should not** be used on new drivers or applications.
-
-The DVBv3 frontend API has issues with new delivery systems, including
-DVB-S2, DVB-T2, ISDB, etc.
-
-There's just one driver for a very legacy hardware using the Digital TV
-audio and video APIs. No modern drivers should use it. Instead, audio and
-video should be using the V4L2 and ALSA APIs, and the pipelines should
-be set via the Media Controller API.
-
-.. attention::
-
-   The APIs described here doesn't necessarily reflect the current
-   code implementation, as this section of the document was written
-   for DVB version 1, while the code reflects DVB version 3
-   implementation.
-
-
-.. toctree::
-    :maxdepth: 1
-
-    frontend_legacy_dvbv3_api
-    video
-    audio
diff --git a/Documentation/media/uapi/dvb/net-add-if.rst b/Documentation/media/uapi/dvb/net-add-if.rst
deleted file mode 100644
index 1188641b453e..000000000000
--- a/Documentation/media/uapi/dvb/net-add-if.rst
+++ /dev/null
@@ -1,60 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _NET_ADD_IF:
-
-****************
-ioctl NET_ADD_IF
-****************
-
-Name
-====
-
-NET_ADD_IF - Creates a new network interface for a given Packet ID.
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, NET_ADD_IF, struct dvb_net_if *net_if )
-    :name: NET_ADD_IF
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <frontend_f_open>`.
-
-``net_if``
-    pointer to struct :c:type:`dvb_net_if`
-
-
-Description
-===========
-
-The NET_ADD_IF ioctl system call selects the Packet ID (PID) that
-contains a TCP/IP traffic, the type of encapsulation to be used (MPE or
-ULE) and the interface number for the new interface to be created. When
-the system call successfully returns, a new virtual network interface is
-created.
-
-The struct :c:type:`dvb_net_if`::ifnum field will be
-filled with the number of the created interface.
-
-Return Value
-============
-
-On success 0 is returned, and :c:type:`ca_slot_info` is filled.
-
-On error -1 is returned, 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/dvb/net-get-if.rst b/Documentation/media/uapi/dvb/net-get-if.rst
deleted file mode 100644
index 7c4ef4b9d6cc..000000000000
--- a/Documentation/media/uapi/dvb/net-get-if.rst
+++ /dev/null
@@ -1,59 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _NET_GET_IF:
-
-****************
-ioctl NET_GET_IF
-****************
-
-Name
-====
-
-NET_GET_IF - Read the configuration data of an interface created via - :ref:`NET_ADD_IF <net>`.
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, NET_GET_IF, struct dvb_net_if *net_if )
-    :name: NET_GET_IF
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <frontend_f_open>`.
-
-``net_if``
-    pointer to struct :c:type:`dvb_net_if`
-
-
-Description
-===========
-
-The NET_GET_IF ioctl uses the interface number given by the struct
-:c:type:`dvb_net_if`::ifnum field and fills the content of
-struct :c:type:`dvb_net_if` with the packet ID and
-encapsulation type used on such interface. If the interface was not
-created yet with :ref:`NET_ADD_IF <net>`, it will return -1 and fill
-the ``errno`` with ``EINVAL`` error code.
-
-
-Return Value
-============
-
-On success 0 is returned, and :c:type:`ca_slot_info` is filled.
-
-On error -1 is returned, 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/dvb/net-remove-if.rst b/Documentation/media/uapi/dvb/net-remove-if.rst
deleted file mode 100644
index bf9a1602eeec..000000000000
--- a/Documentation/media/uapi/dvb/net-remove-if.rst
+++ /dev/null
@@ -1,55 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _NET_REMOVE_IF:
-
-*******************
-ioctl NET_REMOVE_IF
-*******************
-
-Name
-====
-
-NET_REMOVE_IF - Removes a network interface.
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, NET_REMOVE_IF, int ifnum )
-    :name: NET_REMOVE_IF
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <frontend_f_open>`.
-
-``net_if``
-    number of the interface to be removed
-
-
-Description
-===========
-
-The NET_REMOVE_IF ioctl deletes an interface previously created via
-:ref:`NET_ADD_IF <net>`.
-
-
-Return Value
-============
-
-On success 0 is returned, and :c:type:`ca_slot_info` is filled.
-
-On error -1 is returned, 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/dvb/net-types.rst b/Documentation/media/uapi/dvb/net-types.rst
deleted file mode 100644
index 9e16462a1ef4..000000000000
--- a/Documentation/media/uapi/dvb/net-types.rst
+++ /dev/null
@@ -1,16 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _net_types:
-
-**************
-Net Data Types
-**************
-
-.. kernel-doc:: include/uapi/linux/dvb/net.h
diff --git a/Documentation/media/uapi/dvb/net.rst b/Documentation/media/uapi/dvb/net.rst
deleted file mode 100644
index 833daa381968..000000000000
--- a/Documentation/media/uapi/dvb/net.rst
+++ /dev/null
@@ -1,48 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _net:
-
-######################
-Digital TV Network API
-######################
-
-The Digital TV net device controls the mapping of data packages that are part
-of a transport stream to be mapped into a virtual network interface,
-visible through the standard Linux network protocol stack.
-
-Currently, two encapsulations are supported:
-
--  `Multi Protocol Encapsulation (MPE) <http://en.wikipedia.org/wiki/Multiprotocol_Encapsulation>`__
-
--  `Ultra Lightweight Encapsulation (ULE) <http://en.wikipedia.org/wiki/Unidirectional_Lightweight_Encapsulation>`__
-
-In order to create the Linux virtual network interfaces, an application
-needs to tell to the Kernel what are the PIDs and the encapsulation
-types that are present on the transport stream. This is done through
-``/dev/dvb/adapter?/net?`` device node. The data will be available via
-virtual ``dvb?_?`` network interfaces, and will be controlled/routed via
-the standard ip tools (like ip, route, netstat, ifconfig, etc).
-
-Data types and and ioctl definitions are defined via ``linux/dvb/net.h``
-header.
-
-
-.. _net_fcalls:
-
-Digital TV net Function Calls
-#############################
-
-.. toctree::
-    :maxdepth: 1
-
-    net-types
-    net-add-if
-    net-remove-if
-    net-get-if
diff --git a/Documentation/media/uapi/dvb/query-dvb-frontend-info.rst b/Documentation/media/uapi/dvb/query-dvb-frontend-info.rst
deleted file mode 100644
index 9a6badc1d295..000000000000
--- a/Documentation/media/uapi/dvb/query-dvb-frontend-info.rst
+++ /dev/null
@@ -1,20 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _query-dvb-frontend-info:
-
-*****************************
-Querying frontend information
-*****************************
-
-Usually, the first thing to do when the frontend is opened is to check
-the frontend capabilities. This is done using
-:ref:`FE_GET_INFO`. This ioctl will enumerate the
-Digital TV API version and other characteristics about the frontend, and can
-be opened either in read only or read/write mode.
diff --git a/Documentation/media/uapi/dvb/video-clear-buffer.rst b/Documentation/media/uapi/dvb/video-clear-buffer.rst
deleted file mode 100644
index 5eb5546e8ce4..000000000000
--- a/Documentation/media/uapi/dvb/video-clear-buffer.rst
+++ /dev/null
@@ -1,63 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDEO_CLEAR_BUFFER:
-
-==================
-VIDEO_CLEAR_BUFFER
-==================
-
-Name
-----
-
-VIDEO_CLEAR_BUFFER
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:function:: int ioctl(fd, VIDEO_CLEAR_BUFFER)
-    :name: VIDEO_CLEAR_BUFFER
-
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-    -  .. row 2
-
-       -  int request
-
-       -  Equals VIDEO_CLEAR_BUFFER for this command.
-
-
-Description
------------
-
-This ioctl call clears all video buffers in the driver and in the
-decoder hardware.
-
-
-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/dvb/video-command.rst b/Documentation/media/uapi/dvb/video-command.rst
deleted file mode 100644
index 020b49645c6b..000000000000
--- a/Documentation/media/uapi/dvb/video-command.rst
+++ /dev/null
@@ -1,105 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDEO_COMMAND:
-
-=============
-VIDEO_COMMAND
-=============
-
-Name
-----
-
-VIDEO_COMMAND
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:function:: int ioctl(int fd, VIDEO_COMMAND, struct video_command *cmd)
-    :name: VIDEO_COMMAND
-
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-    -  .. row 2
-
-       -  int request
-
-       -  Equals VIDEO_COMMAND for this command.
-
-    -  .. row 3
-
-       -  struct video_command \*cmd
-
-       -  Commands the decoder.
-
-
-Description
------------
-
-This ioctl is obsolete. Do not use in new drivers. For V4L2 decoders
-this ioctl has been replaced by the
-:ref:`VIDIOC_DECODER_CMD` ioctl.
-
-This ioctl commands the decoder. The ``video_command`` struct is a
-subset of the ``v4l2_decoder_cmd`` struct, so refer to the
-:ref:`VIDIOC_DECODER_CMD` documentation for
-more information.
-
-.. c:type:: struct video_command
-
-.. code-block:: c
-
-	/* The structure must be zeroed before use by the application
-	This ensures it can be extended safely in the future. */
-	struct video_command {
-		__u32 cmd;
-		__u32 flags;
-		union {
-			struct {
-				__u64 pts;
-			} stop;
-
-			struct {
-				/* 0 or 1000 specifies normal speed,
-				1 specifies forward single stepping,
-				-1 specifies backward single stepping,
-				>1: playback at speed/1000 of the normal speed,
-				<-1: reverse playback at (-speed/1000) of the normal speed. */
-				__s32 speed;
-				__u32 format;
-			} play;
-
-			struct {
-				__u32 data[16];
-			} raw;
-		};
-	};
-
-
-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/dvb/video-continue.rst b/Documentation/media/uapi/dvb/video-continue.rst
deleted file mode 100644
index 2ae2067dfba8..000000000000
--- a/Documentation/media/uapi/dvb/video-continue.rst
+++ /dev/null
@@ -1,66 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDEO_CONTINUE:
-
-==============
-VIDEO_CONTINUE
-==============
-
-Name
-----
-
-VIDEO_CONTINUE
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:function:: int ioctl(fd, VIDEO_CONTINUE)
-    :name: VIDEO_CONTINUE
-
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-    -  .. row 2
-
-       -  int request
-
-       -  Equals VIDEO_CONTINUE for this command.
-
-
-Description
------------
-
-This ioctl is for Digital TV devices only. To control a V4L2 decoder use the
-V4L2 :ref:`VIDIOC_DECODER_CMD` instead.
-
-This ioctl call restarts decoding and playing processes of the video
-stream which was played before a call to VIDEO_FREEZE was made.
-
-
-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/dvb/video-fast-forward.rst b/Documentation/media/uapi/dvb/video-fast-forward.rst
deleted file mode 100644
index 3f805f334ae1..000000000000
--- a/Documentation/media/uapi/dvb/video-fast-forward.rst
+++ /dev/null
@@ -1,83 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDEO_FAST_FORWARD:
-
-==================
-VIDEO_FAST_FORWARD
-==================
-
-Name
-----
-
-VIDEO_FAST_FORWARD
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:function:: int ioctl(fd, VIDEO_FAST_FORWARD, int nFrames)
-    :name: VIDEO_FAST_FORWARD
-
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-    -  .. row 2
-
-       -  int request
-
-       -  Equals VIDEO_FAST_FORWARD for this command.
-
-    -  .. row 3
-
-       -  int nFrames
-
-       -  The number of frames to skip.
-
-
-Description
------------
-
-This ioctl call asks the Video Device to skip decoding of N number of
-I-frames. This call can only be used if VIDEO_SOURCE_MEMORY is
-selected.
-
-
-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.
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  ``EPERM``
-
-       -  Mode VIDEO_SOURCE_MEMORY not selected.
diff --git a/Documentation/media/uapi/dvb/video-fclose.rst b/Documentation/media/uapi/dvb/video-fclose.rst
deleted file mode 100644
index 3b0285b96a3c..000000000000
--- a/Documentation/media/uapi/dvb/video-fclose.rst
+++ /dev/null
@@ -1,62 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _video_fclose:
-
-=================
-dvb video close()
-=================
-
-Name
-----
-
-dvb video close()
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:function:: int close(int fd)
-
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-
-Description
------------
-
-This system call closes a previously opened video device.
-
-
-Return Value
-------------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  ``EBADF``
-
-       -  fd is not a valid open file descriptor.
diff --git a/Documentation/media/uapi/dvb/video-fopen.rst b/Documentation/media/uapi/dvb/video-fopen.rst
deleted file mode 100644
index 7b2a8c750e6a..000000000000
--- a/Documentation/media/uapi/dvb/video-fopen.rst
+++ /dev/null
@@ -1,122 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _video_fopen:
-
-================
-dvb video open()
-================
-
-Name
-----
-
-dvb video open()
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:function:: int open(const char *deviceName, int flags)
-
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  const char \*deviceName
-
-       -  Name of specific video device.
-
-    -  .. row 2
-
-       -  int flags
-
-       -  A bit-wise OR of the following flags:
-
-    -  .. row 3
-
-       -
-       -  O_RDONLY read-only access
-
-    -  .. row 4
-
-       -
-       -  O_RDWR read/write access
-
-    -  .. row 5
-
-       -
-       -  O_NONBLOCK open in non-blocking mode
-
-    -  .. row 6
-
-       -
-       -  (blocking mode is the default)
-
-
-Description
------------
-
-This system call opens a named video device (e.g.
-/dev/dvb/adapter0/video0) for subsequent use.
-
-When an open() call has succeeded, the device will be ready for use. The
-significance of blocking or non-blocking mode is described in the
-documentation for functions where there is a difference. It does not
-affect the semantics of the open() call itself. A device opened in
-blocking mode can later be put into non-blocking mode (and vice versa)
-using the F_SETFL command of the fcntl system call. This is a standard
-system call, documented in the Linux manual page for fcntl. Only one
-user can open the Video Device in O_RDWR mode. All other attempts to
-open the device in this mode will fail, and an error-code will be
-returned. If the Video Device is opened in O_RDONLY mode, the only
-ioctl call that can be used is VIDEO_GET_STATUS. All other call will
-return an error code.
-
-
-Return Value
-------------
-
-.. tabularcolumns:: |p{2.5cm}|p{15.0cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  ``ENODEV``
-
-       -  Device driver not loaded/available.
-
-    -  .. row 2
-
-       -  ``EINTERNAL``
-
-       -  Internal error.
-
-    -  .. row 3
-
-       -  ``EBUSY``
-
-       -  Device or resource busy.
-
-    -  .. row 4
-
-       -  ``EINVAL``
-
-       -  Invalid argument.
diff --git a/Documentation/media/uapi/dvb/video-freeze.rst b/Documentation/media/uapi/dvb/video-freeze.rst
deleted file mode 100644
index 6b31a4755d2c..000000000000
--- a/Documentation/media/uapi/dvb/video-freeze.rst
+++ /dev/null
@@ -1,70 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDEO_FREEZE:
-
-============
-VIDEO_FREEZE
-============
-
-Name
-----
-
-VIDEO_FREEZE
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:function:: int ioctl(fd, VIDEO_FREEZE)
-    :name: VIDEO_FREEZE
-
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-    -  .. row 2
-
-       -  int request
-
-       -  Equals VIDEO_FREEZE for this command.
-
-
-Description
------------
-
-This ioctl is for Digital TV devices only. To control a V4L2 decoder use the
-V4L2 :ref:`VIDIOC_DECODER_CMD` instead.
-
-This ioctl call suspends the live video stream being played. Decoding
-and playing are frozen. It is then possible to restart the decoding and
-playing process of the video stream using the VIDEO_CONTINUE command.
-If VIDEO_SOURCE_MEMORY is selected in the ioctl call
-VIDEO_SELECT_SOURCE, the Digital TV subsystem will not decode any more data
-until the ioctl call VIDEO_CONTINUE or VIDEO_PLAY is performed.
-
-
-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/dvb/video-fwrite.rst b/Documentation/media/uapi/dvb/video-fwrite.rst
deleted file mode 100644
index eb35b79eb85c..000000000000
--- a/Documentation/media/uapi/dvb/video-fwrite.rst
+++ /dev/null
@@ -1,90 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _video_fwrite:
-
-=================
-dvb video write()
-=================
-
-Name
-----
-
-dvb video write()
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:function:: size_t write(int fd, const void *buf, size_t count)
-
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-    -  .. row 2
-
-       -  void \*buf
-
-       -  Pointer to the buffer containing the PES data.
-
-    -  .. row 3
-
-       -  size_t count
-
-       -  Size of buf.
-
-
-Description
------------
-
-This system call can only be used if VIDEO_SOURCE_MEMORY is selected
-in the ioctl call VIDEO_SELECT_SOURCE. The data provided shall be in
-PES format, unless the capability allows other formats. If O_NONBLOCK
-is not specified the function will block until buffer space is
-available. The amount of data to be transferred is implied by count.
-
-
-Return Value
-------------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  ``EPERM``
-
-       -  Mode VIDEO_SOURCE_MEMORY not selected.
-
-    -  .. row 2
-
-       -  ``ENOMEM``
-
-       -  Attempted to write more data than the internal buffer can hold.
-
-    -  .. row 3
-
-       -  ``EBADF``
-
-       -  fd is not a valid open file descriptor.
diff --git a/Documentation/media/uapi/dvb/video-get-capabilities.rst b/Documentation/media/uapi/dvb/video-get-capabilities.rst
deleted file mode 100644
index 971fdab70e15..000000000000
--- a/Documentation/media/uapi/dvb/video-get-capabilities.rst
+++ /dev/null
@@ -1,70 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDEO_GET_CAPABILITIES:
-
-======================
-VIDEO_GET_CAPABILITIES
-======================
-
-Name
-----
-
-VIDEO_GET_CAPABILITIES
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:function:: int ioctl(fd, VIDEO_GET_CAPABILITIES, unsigned int *cap)
-    :name: VIDEO_GET_CAPABILITIES
-
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-    -  .. row 2
-
-       -  int request
-
-       -  Equals VIDEO_GET_CAPABILITIES for this command.
-
-    -  .. row 3
-
-       -  unsigned int \*cap
-
-       -  Pointer to a location where to store the capability information.
-
-
-Description
------------
-
-This ioctl call asks the video device about its decoding capabilities.
-On success it returns and integer which has bits set according to the
-defines in section ??.
-
-
-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/dvb/video-get-event.rst b/Documentation/media/uapi/dvb/video-get-event.rst
deleted file mode 100644
index 7f03fbe3d3b0..000000000000
--- a/Documentation/media/uapi/dvb/video-get-event.rst
+++ /dev/null
@@ -1,114 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDEO_GET_EVENT:
-
-===============
-VIDEO_GET_EVENT
-===============
-
-Name
-----
-
-VIDEO_GET_EVENT
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:function:: int ioctl(fd, VIDEO_GET_EVENT, struct video_event *ev)
-    :name: VIDEO_GET_EVENT
-
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-    -  .. row 2
-
-       -  int request
-
-       -  Equals VIDEO_GET_EVENT for this command.
-
-    -  .. row 3
-
-       -  struct video_event \*ev
-
-       -  Points to the location where the event, if any, is to be stored.
-
-
-Description
------------
-
-This ioctl is for Digital TV devices only. To get events from a V4L2 decoder
-use the V4L2 :ref:`VIDIOC_DQEVENT` ioctl instead.
-
-This ioctl call returns an event of type video_event if available. If
-an event is not available, the behavior depends on whether the device is
-in blocking or non-blocking mode. In the latter case, the call fails
-immediately with errno set to ``EWOULDBLOCK``. In the former case, the call
-blocks until an event becomes available. The standard Linux poll()
-and/or select() system calls can be used with the device file descriptor
-to watch for new events. For select(), the file descriptor should be
-included in the exceptfds argument, and for poll(), POLLPRI should be
-specified as the wake-up condition. Read-only permissions are sufficient
-for this ioctl call.
-
-.. c:type:: video_event
-
-.. code-block:: c
-
-	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
-		long timestamp;
-		union {
-			video_size_t size;
-			unsigned int frame_rate;	/* in frames per 1000sec */
-			unsigned char vsync_field;	/* unknown/odd/even/progressive */
-		} u;
-	};
-
-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.
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  ``EWOULDBLOCK``
-
-       -  There is no event pending, and the device is in non-blocking mode.
-
-    -  .. row 2
-
-       -  ``EOVERFLOW``
-
-       -  Overflow in event queue - one or more events were lost.
diff --git a/Documentation/media/uapi/dvb/video-get-frame-count.rst b/Documentation/media/uapi/dvb/video-get-frame-count.rst
deleted file mode 100644
index ef35da7d4861..000000000000
--- a/Documentation/media/uapi/dvb/video-get-frame-count.rst
+++ /dev/null
@@ -1,74 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDEO_GET_FRAME_COUNT:
-
-=====================
-VIDEO_GET_FRAME_COUNT
-=====================
-
-Name
-----
-
-VIDEO_GET_FRAME_COUNT
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:function:: int ioctl(int fd, VIDEO_GET_FRAME_COUNT, __u64 *pts)
-    :name: VIDEO_GET_FRAME_COUNT
-
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-    -  .. row 2
-
-       -  int request
-
-       -  Equals VIDEO_GET_FRAME_COUNT for this command.
-
-    -  .. row 3
-
-       -  __u64 \*pts
-
-       -  Returns the number of frames displayed since the decoder was
-	  started.
-
-
-Description
------------
-
-This ioctl is obsolete. Do not use in new drivers. For V4L2 decoders
-this ioctl has been replaced by the ``V4L2_CID_MPEG_VIDEO_DEC_FRAME``
-control.
-
-This ioctl call asks the Video Device to return the number of displayed
-frames since the decoder was started.
-
-
-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/dvb/video-get-pts.rst b/Documentation/media/uapi/dvb/video-get-pts.rst
deleted file mode 100644
index 86ceefff7834..000000000000
--- a/Documentation/media/uapi/dvb/video-get-pts.rst
+++ /dev/null
@@ -1,78 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDEO_GET_PTS:
-
-=============
-VIDEO_GET_PTS
-=============
-
-Name
-----
-
-VIDEO_GET_PTS
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:function:: int ioctl(int fd, VIDEO_GET_PTS, __u64 *pts)
-    :name: VIDEO_GET_PTS
-
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-    -  .. row 2
-
-       -  int request
-
-       -  Equals VIDEO_GET_PTS for this command.
-
-    -  .. row 3
-
-       -  __u64 \*pts
-
-       -  Returns the 33-bit timestamp as defined in ITU T-REC-H.222.0 /
-	  ISO/IEC 13818-1.
-
-	  The PTS should belong to the currently played frame if possible,
-	  but may also be a value close to it like the PTS of the last
-	  decoded frame or the last PTS extracted by the PES parser.
-
-
-Description
------------
-
-This ioctl is obsolete. Do not use in new drivers. For V4L2 decoders
-this ioctl has been replaced by the ``V4L2_CID_MPEG_VIDEO_DEC_PTS``
-control.
-
-This ioctl call asks the Video Device to return the current PTS
-timestamp.
-
-
-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/dvb/video-get-size.rst b/Documentation/media/uapi/dvb/video-get-size.rst
deleted file mode 100644
index cc92189d31fd..000000000000
--- a/Documentation/media/uapi/dvb/video-get-size.rst
+++ /dev/null
@@ -1,78 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDEO_GET_SIZE:
-
-==============
-VIDEO_GET_SIZE
-==============
-
-Name
-----
-
-VIDEO_GET_SIZE
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:function:: int ioctl(int fd, VIDEO_GET_SIZE, video_size_t *size)
-    :name: VIDEO_GET_SIZE
-
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-    -  .. row 2
-
-       -  int request
-
-       -  Equals VIDEO_GET_SIZE for this command.
-
-    -  .. row 3
-
-       -  video_size_t \*size
-
-       -  Returns the size and aspect ratio.
-
-
-Description
------------
-
-This ioctl returns the size and aspect ratio.
-
-.. c:type:: video_size_t
-
-.. code-block::c
-
-	typedef struct {
-		int w;
-		int h;
-		video_format_t aspect_ratio;
-	} video_size_t;
-
-
-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/dvb/video-get-status.rst b/Documentation/media/uapi/dvb/video-get-status.rst
deleted file mode 100644
index 8bfcf8fc3e19..000000000000
--- a/Documentation/media/uapi/dvb/video-get-status.rst
+++ /dev/null
@@ -1,80 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDEO_GET_STATUS:
-
-================
-VIDEO_GET_STATUS
-================
-
-Name
-----
-
-VIDEO_GET_STATUS
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:function:: int ioctl(fd, VIDEO_GET_STATUS, struct video_status *status)
-    :name: VIDEO_GET_STATUS
-
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-    -  .. row 2
-
-       -  int request
-
-       -  Equals VIDEO_GET_STATUS for this command.
-
-    -  .. row 3
-
-       -  struct video_status \*status
-
-       -  Returns the current status of the Video Device.
-
-
-Description
------------
-
-This ioctl call asks the Video Device to return the current status of
-the device.
-
-.. c:type:: video_status
-
-.. code-block:: c
-
-	struct video_status {
-		int                   video_blank;   /* blank video on freeze? */
-		video_play_state_t    play_state;    /* current state of playback */
-		video_stream_source_t stream_source; /* current source (demux/memory) */
-		video_format_t        video_format;  /* current aspect ratio of stream*/
-		video_displayformat_t display_format;/* selected cropping mode */
-	};
-
-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/dvb/video-play.rst b/Documentation/media/uapi/dvb/video-play.rst
deleted file mode 100644
index fb3f4f168814..000000000000
--- a/Documentation/media/uapi/dvb/video-play.rst
+++ /dev/null
@@ -1,66 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDEO_PLAY:
-
-==========
-VIDEO_PLAY
-==========
-
-Name
-----
-
-VIDEO_PLAY
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:function:: int ioctl(fd, VIDEO_PLAY)
-    :name: VIDEO_PLAY
-
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-    -  .. row 2
-
-       -  int request
-
-       -  Equals VIDEO_PLAY for this command.
-
-
-Description
------------
-
-This ioctl is for Digital TV devices only. To control a V4L2 decoder use the
-V4L2 :ref:`VIDIOC_DECODER_CMD` instead.
-
-This ioctl call asks the Video Device to start playing a video stream
-from the selected source.
-
-
-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/dvb/video-select-source.rst b/Documentation/media/uapi/dvb/video-select-source.rst
deleted file mode 100644
index 32cf025356dc..000000000000
--- a/Documentation/media/uapi/dvb/video-select-source.rst
+++ /dev/null
@@ -1,84 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDEO_SELECT_SOURCE:
-
-===================
-VIDEO_SELECT_SOURCE
-===================
-
-Name
-----
-
-VIDEO_SELECT_SOURCE
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:function:: int ioctl(fd, VIDEO_SELECT_SOURCE, video_stream_source_t source)
-    :name: VIDEO_SELECT_SOURCE
-
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-    -  .. row 2
-
-       -  int request
-
-       -  Equals VIDEO_SELECT_SOURCE for this command.
-
-    -  .. row 3
-
-       -  video_stream_source_t source
-
-       -  Indicates which source shall be used for the Video stream.
-
-
-Description
------------
-
-This ioctl is for Digital TV devices only. This ioctl was also supported by the
-V4L2 ivtv driver, but that has been replaced by the ivtv-specific
-``IVTV_IOC_PASSTHROUGH_MODE`` ioctl.
-
-This ioctl call informs the video device which source shall be used for
-the input data. The possible sources are demux or memory. If memory is
-selected, the data is fed to the video device through the write command.
-
-.. c:type:: video_stream_source_t
-
-.. code-block:: c
-
-	typedef enum {
-		VIDEO_SOURCE_DEMUX, /* Select the demux as the main source */
-		VIDEO_SOURCE_MEMORY /* If this source is selected, the stream
-				comes from the user through the write
-				system call */
-	} video_stream_source_t;
-
-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/dvb/video-set-blank.rst b/Documentation/media/uapi/dvb/video-set-blank.rst
deleted file mode 100644
index 901c3c80f167..000000000000
--- a/Documentation/media/uapi/dvb/video-set-blank.rst
+++ /dev/null
@@ -1,73 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDEO_SET_BLANK:
-
-===============
-VIDEO_SET_BLANK
-===============
-
-Name
-----
-
-VIDEO_SET_BLANK
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:function:: int ioctl(fd, VIDEO_SET_BLANK, boolean mode)
-    :name: VIDEO_SET_BLANK
-
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-    -  .. row 2
-
-       -  int request
-
-       -  Equals VIDEO_SET_BLANK for this command.
-
-    -  .. row 3
-
-       -  boolean mode
-
-       -  TRUE: Blank screen when stop.
-
-    -  .. row 4
-
-       -
-       -  FALSE: Show last decoded frame.
-
-
-Description
------------
-
-This ioctl call asks the Video Device to blank out the picture.
-
-
-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/dvb/video-set-display-format.rst b/Documentation/media/uapi/dvb/video-set-display-format.rst
deleted file mode 100644
index ffdefa341207..000000000000
--- a/Documentation/media/uapi/dvb/video-set-display-format.rst
+++ /dev/null
@@ -1,69 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDEO_SET_DISPLAY_FORMAT:
-
-========================
-VIDEO_SET_DISPLAY_FORMAT
-========================
-
-Name
-----
-
-VIDEO_SET_DISPLAY_FORMAT
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:function:: int ioctl(fd, VIDEO_SET_DISPLAY_FORMAT)
-    :name: VIDEO_SET_DISPLAY_FORMAT
-
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-    -  .. row 2
-
-       -  int request
-
-       -  Equals VIDEO_SET_DISPLAY_FORMAT for this command.
-
-    -  .. row 3
-
-       -  video_display_format_t format
-
-       -  Selects the video format to be used.
-
-
-Description
------------
-
-This ioctl call asks the Video Device to select the video format to be
-applied by the MPEG chip on the video.
-
-
-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/dvb/video-set-format.rst b/Documentation/media/uapi/dvb/video-set-format.rst
deleted file mode 100644
index 63e60214ab37..000000000000
--- a/Documentation/media/uapi/dvb/video-set-format.rst
+++ /dev/null
@@ -1,92 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDEO_SET_FORMAT:
-
-================
-VIDEO_SET_FORMAT
-================
-
-Name
-----
-
-VIDEO_SET_FORMAT
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:function:: int ioctl(fd, VIDEO_SET_FORMAT, video_format_t format)
-    :name: VIDEO_SET_FORMAT
-
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-    -  .. row 2
-
-       -  int request
-
-       -  Equals VIDEO_SET_FORMAT for this command.
-
-    -  .. row 3
-
-       -  video_format_t format
-
-       -  video format of TV as defined in section ??.
-
-
-Description
------------
-
-This ioctl sets the screen format (aspect ratio) of the connected output
-device (TV) so that the output of the decoder can be adjusted
-accordingly.
-
-.. c:type:: video_format_t
-
-.. code-block:: c
-
-	typedef enum {
-		VIDEO_FORMAT_4_3,     /* Select 4:3 format */
-		VIDEO_FORMAT_16_9,    /* Select 16:9 format. */
-		VIDEO_FORMAT_221_1    /* 2.21:1 */
-	} video_format_t;
-
-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.
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  ``EINVAL``
-
-       -  format is not a valid video format.
diff --git a/Documentation/media/uapi/dvb/video-set-streamtype.rst b/Documentation/media/uapi/dvb/video-set-streamtype.rst
deleted file mode 100644
index 845486a6e049..000000000000
--- a/Documentation/media/uapi/dvb/video-set-streamtype.rst
+++ /dev/null
@@ -1,70 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDEO_SET_STREAMTYPE:
-
-====================
-VIDEO_SET_STREAMTYPE
-====================
-
-Name
-----
-
-VIDEO_SET_STREAMTYPE
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:function:: int ioctl(fd, VIDEO_SET_STREAMTYPE, int type)
-    :name: VIDEO_SET_STREAMTYPE
-
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-    -  .. row 2
-
-       -  int request
-
-       -  Equals VIDEO_SET_STREAMTYPE for this command.
-
-    -  .. row 3
-
-       -  int type
-
-       -  stream type
-
-
-Description
------------
-
-This ioctl tells the driver which kind of stream to expect being written
-to it. If this call is not used the default of video PES is used. Some
-drivers might not support this call and always expect PES.
-
-
-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/dvb/video-slowmotion.rst b/Documentation/media/uapi/dvb/video-slowmotion.rst
deleted file mode 100644
index 32c934aaf2ba..000000000000
--- a/Documentation/media/uapi/dvb/video-slowmotion.rst
+++ /dev/null
@@ -1,83 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDEO_SLOWMOTION:
-
-================
-VIDEO_SLOWMOTION
-================
-
-Name
-----
-
-VIDEO_SLOWMOTION
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:function:: int ioctl(fd, VIDEO_SLOWMOTION, int nFrames)
-    :name: VIDEO_SLOWMOTION
-
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-    -  .. row 2
-
-       -  int request
-
-       -  Equals VIDEO_SLOWMOTION for this command.
-
-    -  .. row 3
-
-       -  int nFrames
-
-       -  The number of times to repeat each frame.
-
-
-Description
------------
-
-This ioctl call asks the video device to repeat decoding frames N number
-of times. This call can only be used if VIDEO_SOURCE_MEMORY is
-selected.
-
-
-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.
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  ``EPERM``
-
-       -  Mode VIDEO_SOURCE_MEMORY not selected.
diff --git a/Documentation/media/uapi/dvb/video-stillpicture.rst b/Documentation/media/uapi/dvb/video-stillpicture.rst
deleted file mode 100644
index 58035a7630e6..000000000000
--- a/Documentation/media/uapi/dvb/video-stillpicture.rst
+++ /dev/null
@@ -1,70 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDEO_STILLPICTURE:
-
-==================
-VIDEO_STILLPICTURE
-==================
-
-Name
-----
-
-VIDEO_STILLPICTURE
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:function:: int ioctl(fd, VIDEO_STILLPICTURE, struct video_still_picture *sp)
-    :name: VIDEO_STILLPICTURE
-
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-    -  .. row 2
-
-       -  int request
-
-       -  Equals VIDEO_STILLPICTURE for this command.
-
-    -  .. row 3
-
-       -  struct video_still_picture \*sp
-
-       -  Pointer to a location where an I-frame and size is stored.
-
-
-Description
------------
-
-This ioctl call asks the Video Device to display a still picture
-(I-frame). The input data shall contain an I-frame. If the pointer is
-NULL, then the current displayed still picture is blanked.
-
-
-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/dvb/video-stop.rst b/Documentation/media/uapi/dvb/video-stop.rst
deleted file mode 100644
index 732ace05e34b..000000000000
--- a/Documentation/media/uapi/dvb/video-stop.rst
+++ /dev/null
@@ -1,83 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDEO_STOP:
-
-==========
-VIDEO_STOP
-==========
-
-Name
-----
-
-VIDEO_STOP
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:function:: int ioctl(fd, VIDEO_STOP, boolean mode)
-    :name: VIDEO_STOP
-
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-    -  .. row 2
-
-       -  int request
-
-       -  Equals VIDEO_STOP for this command.
-
-    -  .. row 3
-
-       -  Boolean mode
-
-       -  Indicates how the screen shall be handled.
-
-    -  .. row 4
-
-       -
-       -  TRUE: Blank screen when stop.
-
-    -  .. row 5
-
-       -
-       -  FALSE: Show last decoded frame.
-
-
-Description
------------
-
-This ioctl is for Digital TV devices only. To control a V4L2 decoder use the
-V4L2 :ref:`VIDIOC_DECODER_CMD` instead.
-
-This ioctl call asks the Video Device to stop playing the current
-stream. Depending on the input parameter, the screen can be blanked out
-or displaying the last decoded frame.
-
-
-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/dvb/video-try-command.rst b/Documentation/media/uapi/dvb/video-try-command.rst
deleted file mode 100644
index 37ecf8e91eb8..000000000000
--- a/Documentation/media/uapi/dvb/video-try-command.rst
+++ /dev/null
@@ -1,75 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDEO_TRY_COMMAND:
-
-=================
-VIDEO_TRY_COMMAND
-=================
-
-Name
-----
-
-VIDEO_TRY_COMMAND
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:function:: int ioctl(int fd, VIDEO_TRY_COMMAND, struct video_command *cmd)
-    :name: VIDEO_TRY_COMMAND
-
-
-Arguments
----------
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  int fd
-
-       -  File descriptor returned by a previous call to open().
-
-    -  .. row 2
-
-       -  int request
-
-       -  Equals VIDEO_TRY_COMMAND for this command.
-
-    -  .. row 3
-
-       -  struct video_command \*cmd
-
-       -  Try a decoder command.
-
-
-Description
------------
-
-This ioctl is obsolete. Do not use in new drivers. For V4L2 decoders
-this ioctl has been replaced by the
-:ref:`VIDIOC_TRY_DECODER_CMD <VIDIOC_DECODER_CMD>` ioctl.
-
-This ioctl tries a decoder command. The ``video_command`` struct is a
-subset of the ``v4l2_decoder_cmd`` struct, so refer to the
-:ref:`VIDIOC_TRY_DECODER_CMD <VIDIOC_DECODER_CMD>` documentation
-for more information.
-
-
-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/dvb/video.rst b/Documentation/media/uapi/dvb/video.rst
deleted file mode 100644
index 6d72ed0e2b2d..000000000000
--- a/Documentation/media/uapi/dvb/video.rst
+++ /dev/null
@@ -1,43 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _dvb_video:
-
-#######################
-Digital TV Video Device
-#######################
-
-The Digital TV video device controls the MPEG2 video decoder of the Digital
-TV hardware. It can be accessed through **/dev/dvb/adapter0/video0**. Data
-types and and ioctl definitions can be accessed by including
-**linux/dvb/video.h** in your application.
-
-Note that the Digital TV video device only controls decoding of the MPEG video
-stream, not its presentation on the TV or computer screen. On PCs this
-is typically handled by an associated video4linux device, e.g.
-**/dev/video**, which allows scaling and defining output windows.
-
-Some Digital TV cards don’t have their own MPEG decoder, which results in the
-omission of the audio and video device as well as the video4linux
-device.
-
-The ioctls that deal with SPUs (sub picture units) and navigation
-packets are only supported on some MPEG decoders made for DVD playback.
-
-These ioctls were also used by V4L2 to control MPEG decoders implemented
-in V4L2. The use of these ioctls for that purpose has been made obsolete
-and proper V4L2 ioctls or controls have been created to replace that
-functionality.
-
-
-.. toctree::
-    :maxdepth: 1
-
-    video_types
-    video_function_calls
diff --git a/Documentation/media/uapi/dvb/video_function_calls.rst b/Documentation/media/uapi/dvb/video_function_calls.rst
deleted file mode 100644
index 9e8e49e52b19..000000000000
--- a/Documentation/media/uapi/dvb/video_function_calls.rst
+++ /dev/null
@@ -1,42 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _video_function_calls:
-
-********************
-Video Function Calls
-********************
-
-.. toctree::
-    :maxdepth: 1
-
-    video-fopen
-    video-fclose
-    video-fwrite
-    video-stop
-    video-play
-    video-freeze
-    video-continue
-    video-select-source
-    video-set-blank
-    video-get-status
-    video-get-frame-count
-    video-get-pts
-    video-get-event
-    video-command
-    video-try-command
-    video-get-size
-    video-set-display-format
-    video-stillpicture
-    video-fast-forward
-    video-slowmotion
-    video-get-capabilities
-    video-clear-buffer
-    video-set-streamtype
-    video-set-format
diff --git a/Documentation/media/uapi/dvb/video_types.rst b/Documentation/media/uapi/dvb/video_types.rst
deleted file mode 100644
index 2697400ccf62..000000000000
--- a/Documentation/media/uapi/dvb/video_types.rst
+++ /dev/null
@@ -1,255 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _video_types:
-
-****************
-Video Data Types
-****************
-
-
-.. _video-format-t:
-
-video_format_t
-==============
-
-The ``video_format_t`` data type defined by
-
-
-.. code-block:: c
-
-    typedef enum {
-	VIDEO_FORMAT_4_3,     /* Select 4:3 format */
-	VIDEO_FORMAT_16_9,    /* Select 16:9 format. */
-	VIDEO_FORMAT_221_1    /* 2.21:1 */
-    } video_format_t;
-
-is used in the VIDEO_SET_FORMAT function (??) to tell the driver which
-aspect ratio the output hardware (e.g. TV) has. It is also used in the
-data structures video_status (??) returned by VIDEO_GET_STATUS (??)
-and video_event (??) returned by VIDEO_GET_EVENT (??) which report
-about the display format of the current video stream.
-
-
-.. _video-displayformat-t:
-
-video_displayformat_t
-=====================
-
-In case the display format of the video stream and of the display
-hardware differ the application has to specify how to handle the
-cropping of the picture. This can be done using the
-VIDEO_SET_DISPLAY_FORMAT call (??) which accepts
-
-
-.. code-block:: c
-
-    typedef enum {
-	VIDEO_PAN_SCAN,       /* use pan and scan format */
-	VIDEO_LETTER_BOX,     /* use letterbox format */
-	VIDEO_CENTER_CUT_OUT  /* use center cut out format */
-    } video_displayformat_t;
-
-as argument.
-
-
-.. _video-stream-source-t:
-
-video_stream_source_t
-=====================
-
-The video stream source is set through the VIDEO_SELECT_SOURCE call
-and can take the following values, depending on whether we are replaying
-from an internal (demuxer) or external (user write) source.
-
-
-.. code-block:: c
-
-    typedef enum {
-	VIDEO_SOURCE_DEMUX, /* Select the demux as the main source */
-	VIDEO_SOURCE_MEMORY /* If this source is selected, the stream
-		       comes from the user through the write
-		       system call */
-    } video_stream_source_t;
-
-VIDEO_SOURCE_DEMUX selects the demultiplexer (fed either by the
-frontend or the DVR device) as the source of the video stream. If
-VIDEO_SOURCE_MEMORY is selected the stream comes from the application
-through the **write()** system call.
-
-
-.. _video-play-state-t:
-
-video_play_state_t
-==================
-
-The following values can be returned by the VIDEO_GET_STATUS call
-representing the state of video playback.
-
-
-.. code-block:: c
-
-    typedef enum {
-	VIDEO_STOPPED, /* Video is stopped */
-	VIDEO_PLAYING, /* Video is currently playing */
-	VIDEO_FREEZED  /* Video is freezed */
-    } video_play_state_t;
-
-
-.. c:type:: video_command
-
-struct video_command
-====================
-
-The structure must be zeroed before use by the application This ensures
-it can be extended safely in the future.
-
-
-.. code-block:: c
-
-    struct video_command {
-	__u32 cmd;
-	__u32 flags;
-	union {
-	    struct {
-		__u64 pts;
-	    } stop;
-
-	    struct {
-		/* 0 or 1000 specifies normal speed,
-		   1 specifies forward single stepping,
-		   -1 specifies backward single stepping,
-		   >>1: playback at speed/1000 of the normal speed,
-		   <-1: reverse playback at (-speed/1000) of the normal speed. */
-		__s32 speed;
-		__u32 format;
-	    } play;
-
-	    struct {
-		__u32 data[16];
-	    } raw;
-	};
-    };
-
-
-.. _video-size-t:
-
-video_size_t
-============
-
-
-.. code-block:: c
-
-    typedef struct {
-	int w;
-	int h;
-	video_format_t aspect_ratio;
-    } video_size_t;
-
-
-.. c:type:: video_event
-
-struct video_event
-==================
-
-The following is the structure of a video event as it is returned by the
-VIDEO_GET_EVENT call.
-
-
-.. code-block:: c
-
-    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
-	long timestamp;
-	union {
-	    video_size_t size;
-	    unsigned int frame_rate;    /* in frames per 1000sec */
-	    unsigned char vsync_field;  /* unknown/odd/even/progressive */
-	} u;
-    };
-
-
-.. c:type:: video_status
-
-struct video_status
-===================
-
-The VIDEO_GET_STATUS call returns the following structure informing
-about various states of the playback operation.
-
-
-.. code-block:: c
-
-    struct video_status {
-	int                   video_blank;   /* blank video on freeze? */
-	video_play_state_t    play_state;    /* current state of playback */
-	video_stream_source_t stream_source; /* current source (demux/memory) */
-	video_format_t        video_format;  /* current aspect ratio of stream */
-	video_displayformat_t display_format;/* selected cropping mode */
-    };
-
-If video_blank is set video will be blanked out if the channel is
-changed or if playback is stopped. Otherwise, the last picture will be
-displayed. play_state indicates if the video is currently frozen,
-stopped, or being played back. The stream_source corresponds to the
-selected source for the video stream. It can come either from the
-demultiplexer or from memory. The video_format indicates the aspect
-ratio (one of 4:3 or 16:9) of the currently played video stream.
-Finally, display_format corresponds to the selected cropping mode in
-case the source video format is not the same as the format of the output
-device.
-
-
-.. c:type:: video_still_picture
-
-struct video_still_picture
-==========================
-
-An I-frame displayed via the VIDEO_STILLPICTURE call is passed on
-within the following structure.
-
-
-.. code-block:: c
-
-    /* pointer to and size of a single iframe in memory */
-    struct video_still_picture {
-	char *iFrame;        /* pointer to a single iframe in memory */
-	int32_t size;
-    };
-
-
-.. _video_caps:
-
-video capabilities
-==================
-
-A call to VIDEO_GET_CAPABILITIES returns an unsigned integer with the
-following bits set according to the hardwares capabilities.
-
-
-.. code-block:: c
-
-     /* bit definitions for capabilities: */
-     /* can the hardware decode MPEG1 and/or MPEG2? */
-     #define VIDEO_CAP_MPEG1   1
-     #define VIDEO_CAP_MPEG2   2
-     /* can you send a system and/or program stream to video device?
-	(you still have to open the video and the audio device but only
-	 send the stream to the video device) */
-     #define VIDEO_CAP_SYS     4
-     #define VIDEO_CAP_PROG    8
-     /* can the driver also handle SPU, NAVI and CSS encoded data?
-	(CSS API is not present yet) */
-     #define VIDEO_CAP_SPU    16
-     #define VIDEO_CAP_NAVI   32
-     #define VIDEO_CAP_CSS    64
diff --git a/Documentation/media/uapi/fdl-appendix.rst b/Documentation/media/uapi/fdl-appendix.rst
deleted file mode 100644
index 9316b8617502..000000000000
--- a/Documentation/media/uapi/fdl-appendix.rst
+++ /dev/null
@@ -1,478 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _fdl:
-
-******************************
-GNU Free Documentation License
-******************************
-
-
-.. _fdl-preamble:
-
-0. PREAMBLE
-===========
-
-The purpose of this License is to make a manual, textbook, or other
-written document “free” in the sense of freedom: to assure everyone the
-effective freedom to copy and redistribute it, with or without modifying
-it, either commercially or noncommercially. Secondarily, this License
-preserves for the author and publisher a way to get credit for their
-work, while not being considered responsible for modifications made by
-others.
-
-This License is a kind of “copyleft”, which means that derivative works
-of the document must themselves be free in the same sense. It
-complements the GNU General Public License, which is a copyleft license
-designed for free software.
-
-We have designed this License in order to use it for manuals for free
-software, because free software needs free documentation: a free program
-should come with manuals providing the same freedoms that the software
-does. But this License is not limited to software manuals; it can be
-used for any textual work, regardless of subject matter or whether it is
-published as a printed book. We recommend this License principally for
-works whose purpose is instruction or reference.
-
-
-.. _fdl-section1:
-
-1. APPLICABILITY AND DEFINITIONS
-================================
-
-
-.. _fdl-document:
-
-This License applies to any manual or other work that contains a notice
-placed by the copyright holder saying it can be distributed under the
-terms of this License. The “Document”, below, refers to any such manual
-or work. Any member of the public is a licensee, and is addressed as
-“you”.
-
-
-.. _fdl-modified:
-
-A “Modified Version” of the Document means any work containing the
-Document or a portion of it, either copied verbatim, or with
-modifications and/or translated into another language.
-
-
-.. _fdl-secondary:
-
-A “Secondary Section” is a named appendix or a front-matter section of
-the :ref:`Document <fdl-document>` that deals exclusively with the
-relationship of the publishers or authors of the Document to the
-Document's overall subject (or to related matters) and contains nothing
-that could fall directly within that overall subject. (For example, if
-the Document is in part a textbook of mathematics, a Secondary Section
-may not explain any mathematics.) The relationship could be a matter of
-historical connection with the subject or with related matters, or of
-legal, commercial, philosophical, ethical or political position
-regarding them.
-
-
-.. _fdl-invariant:
-
-The “Invariant Sections” are certain
-:ref:`Secondary Sections <fdl-secondary>` whose titles are designated,
-as being those of Invariant Sections, in the notice that says that the
-:ref:`Document <fdl-document>` is released under this License.
-
-
-.. _fdl-cover-texts:
-
-The “Cover Texts” are certain short passages of text that are listed, as
-Front-Cover Texts or Back-Cover Texts, in the notice that says that the
-:ref:`Document <fdl-document>` is released under this License.
-
-
-.. _fdl-transparent:
-
-A “Transparent” copy of the :ref:`Document <fdl-document>` means a
-machine-readable copy, represented in a format whose specification is
-available to the general public, whose contents can be viewed and edited
-directly and straightforwardly with generic text editors or (for images
-composed of pixels) generic paint programs or (for drawings) some widely
-available drawing editor, and that is suitable for input to text
-formatters or for automatic translation to a variety of formats suitable
-for input to text formatters. A copy made in an otherwise Transparent
-file format whose markup has been designed to thwart or discourage
-subsequent modification by readers is not Transparent. A copy that is
-not “Transparent” is called “Opaque”.
-
-Examples of suitable formats for Transparent copies include plain ASCII
-without markup, Texinfo input format, LaTeX input format, SGML or XML
-using a publicly available DTD, and standard-conforming simple HTML
-designed for human modification. Opaque formats include PostScript, PDF,
-proprietary formats that can be read and edited only by proprietary word
-processors, SGML or XML for which the DTD and/or processing tools are
-not generally available, and the machine-generated HTML produced by some
-word processors for output purposes only.
-
-
-.. _fdl-title-page:
-
-The “Title Page” means, for a printed book, the title page itself, plus
-such following pages as are needed to hold, legibly, the material this
-License requires to appear in the title page. For works in formats which
-do not have any title page as such, “Title Page” means the text near the
-most prominent appearance of the work's title, preceding the beginning
-of the body of the text.
-
-
-.. _fdl-section2:
-
-2. VERBATIM COPYING
-===================
-
-You may copy and distribute the :ref:`Document <fdl-document>` in any
-medium, either commercially or noncommercially, provided that this
-License, the copyright notices, and the license notice saying this
-License applies to the Document are reproduced in all copies, and that
-you add no other conditions whatsoever to those of this License. You may
-not use technical measures to obstruct or control the reading or further
-copying of the copies you make or distribute. However, you may accept
-compensation in exchange for copies. If you distribute a large enough
-number of copies you must also follow the conditions in
-:ref:`section 3 <fdl-section3>`.
-
-You may also lend copies, under the same conditions stated above, and
-you may publicly display copies.
-
-
-.. _fdl-section3:
-
-3. COPYING IN QUANTITY
-======================
-
-If you publish printed copies of the :ref:`Document <fdl-document>`
-numbering more than 100, and the Document's license notice requires
-:ref:`Cover Texts <fdl-cover-texts>`, you must enclose the copies in
-covers that carry, clearly and legibly, all these Cover Texts:
-Front-Cover Texts on the front cover, and Back-Cover Texts on the back
-cover. Both covers must also clearly and legibly identify you as the
-publisher of these copies. The front cover must present the full title
-with all words of the title equally prominent and visible. You may add
-other material on the covers in addition. Copying with changes limited
-to the covers, as long as they preserve the title of the
-:ref:`Document <fdl-document>` and satisfy these conditions, can be
-treated as verbatim copying in other respects.
-
-If the required texts for either cover are too voluminous to fit
-legibly, you should put the first ones listed (as many as fit
-reasonably) on the actual cover, and continue the rest onto adjacent
-pages.
-
-If you publish or distribute :ref:`Opaque <fdl-transparent>` copies of
-the :ref:`Document <fdl-document>` numbering more than 100, you must
-either include a machine-readable :ref:`Transparent <fdl-transparent>`
-copy along with each Opaque copy, or state in or with each Opaque copy a
-publicly-accessible computer-network location containing a complete
-Transparent copy of the Document, free of added material, which the
-general network-using public has access to download anonymously at no
-charge using public-standard network protocols. If you use the latter
-option, you must take reasonably prudent steps, when you begin
-distribution of Opaque copies in quantity, to ensure that this
-Transparent copy will remain thus accessible at the stated location
-until at least one year after the last time you distribute an Opaque
-copy (directly or through your agents or retailers) of that edition to
-the public.
-
-It is requested, but not required, that you contact the authors of the
-:ref:`Document <fdl-document>` well before redistributing any large
-number of copies, to give them a chance to provide you with an updated
-version of the Document.
-
-
-.. _fdl-section4:
-
-4. MODIFICATIONS
-================
-
-You may copy and distribute a :ref:`Modified Version <fdl-modified>`
-of the :ref:`Document <fdl-document>` under the conditions of sections
-:ref:`2 <fdl-section2>` and :ref:`3 <fdl-section3>` above, provided
-that you release the Modified Version under precisely this License, with
-the Modified Version filling the role of the Document, thus licensing
-distribution and modification of the Modified Version to whoever
-possesses a copy of it. In addition, you must do these things in the
-Modified Version:
-
--  **A.**
-   Use in the :ref:`Title Page <fdl-title-page>` (and on the covers,
-   if any) a title distinct from that of the
-   :ref:`Document <fdl-document>`, and from those of previous versions
-   (which should, if there were any, be listed in the History section of
-   the Document). You may use the same title as a previous version if
-   the original publisher of that version gives permission.
-
--  **B.**
-   List on the :ref:`Title Page <fdl-title-page>`, as authors, one or
-   more persons or entities responsible for authorship of the
-   modifications in the :ref:`Modified Version <fdl-modified>`,
-   together with at least five of the principal authors of the
-   :ref:`Document <fdl-document>` (all of its principal authors, if it
-   has less than five).
-
--  **C.**
-   State on the :ref:`Title Page <fdl-title-page>` the name of the
-   publisher of the :ref:`Modified Version <fdl-modified>`, as the
-   publisher.
-
--  **D.**
-   Preserve all the copyright notices of the
-   :ref:`Document <fdl-document>`.
-
--  **E.**
-   Add an appropriate copyright notice for your modifications adjacent
-   to the other copyright notices.
-
--  **F.**
-   Include, immediately after the copyright notices, a license notice
-   giving the public permission to use the
-   :ref:`Modified Version <fdl-modified>` under the terms of this
-   License, in the form shown in the Addendum below.
-
--  **G.**
-   Preserve in that license notice the full lists of
-   :ref:`Invariant Sections <fdl-invariant>` and required
-   :ref:`Cover Texts <fdl-cover-texts>` given in the
-   :ref:`Document's <fdl-document>` license notice.
-
--  **H.**
-   Include an unaltered copy of this License.
-
--  **I.**
-   Preserve the section entitled “History”, and its title, and add to it
-   an item stating at least the title, year, new authors, and publisher
-   of the :ref:`Modified Version <fdl-modified>` as given on the
-   :ref:`Title Page <fdl-title-page>`. If there is no section entitled
-   “History” in the :ref:`Document <fdl-document>`, create one stating
-   the title, year, authors, and publisher of the Document as given on
-   its Title Page, then add an item describing the Modified Version as
-   stated in the previous sentence.
-
--  **J.**
-   Preserve the network location, if any, given in the
-   :ref:`Document <fdl-document>` for public access to a
-   :ref:`Transparent <fdl-transparent>` copy of the Document, and
-   likewise the network locations given in the Document for previous
-   versions it was based on. These may be placed in the “History”
-   section. You may omit a network location for a work that was
-   published at least four years before the Document itself, or if the
-   original publisher of the version it refers to gives permission.
-
--  **K.**
-   In any section entitled “Acknowledgements” or “Dedications”, preserve
-   the section's title, and preserve in the section all the substance
-   and tone of each of the contributor acknowledgements and/or
-   dedications given therein.
-
--  **L.**
-   Preserve all the :ref:`Invariant Sections <fdl-invariant>` of the
-   :ref:`Document <fdl-document>`, unaltered in their text and in
-   their titles. Section numbers or the equivalent are not considered
-   part of the section titles.
-
--  **M.**
-   Delete any section entitled “Endorsements”. Such a section may not be
-   included in the :ref:`Modified Version <fdl-modified>`.
-
--  **N.**
-   Do not retitle any existing section as “Endorsements” or to conflict
-   in title with any :ref:`Invariant Section <fdl-invariant>`.
-
-If the :ref:`Modified Version <fdl-modified>` includes new
-front-matter sections or appendices that qualify as
-:ref:`Secondary Sections <fdl-secondary>` and contain no material
-copied from the Document, you may at your option designate some or all
-of these sections as invariant. To do this, add their titles to the list
-of :ref:`Invariant Sections <fdl-invariant>` in the Modified Version's
-license notice. These titles must be distinct from any other section
-titles.
-
-You may add a section entitled “Endorsements”, provided it contains
-nothing but endorsements of your
-:ref:`Modified Version <fdl-modified>` by various parties--for
-example, statements of peer review or that the text has been approved by
-an organization as the authoritative definition of a standard.
-
-You may add a passage of up to five words as a
-:ref:`Front-Cover Text <fdl-cover-texts>`, and a passage of up to 25
-words as a :ref:`Back-Cover Text <fdl-cover-texts>`, to the end of the
-list of :ref:`Cover Texts <fdl-cover-texts>` in the
-:ref:`Modified Version <fdl-modified>`. Only one passage of
-Front-Cover Text and one of Back-Cover Text may be added by (or through
-arrangements made by) any one entity. If the
-:ref:`Document <fdl-document>` already includes a cover text for the
-same cover, previously added by you or by arrangement made by the same
-entity you are acting on behalf of, you may not add another; but you may
-replace the old one, on explicit permission from the previous publisher
-that added the old one.
-
-The author(s) and publisher(s) of the :ref:`Document <fdl-document>`
-do not by this License give permission to use their names for publicity
-for or to assert or imply endorsement of any
-:ref:`Modified Version <fdl-modified>`.
-
-
-.. _fdl-section5:
-
-5. COMBINING DOCUMENTS
-======================
-
-You may combine the :ref:`Document <fdl-document>` with other
-documents released under this License, under the terms defined in
-:ref:`section 4 <fdl-section4>` above for modified versions, provided
-that you include in the combination all of the
-:ref:`Invariant Sections <fdl-invariant>` of all of the original
-documents, unmodified, and list them all as Invariant Sections of your
-combined work in its license notice.
-
-The combined work need only contain one copy of this License, and
-multiple identical :ref:`Invariant Sections <fdl-invariant>` may be
-replaced with a single copy. If there are multiple Invariant Sections
-with the same name but different contents, make the title of each such
-section unique by adding at the end of it, in parentheses, the name of
-the original author or publisher of that section if known, or else a
-unique number. Make the same adjustment to the section titles in the
-list of Invariant Sections in the license notice of the combined work.
-
-In the combination, you must combine any sections entitled “History” in
-the various original documents, forming one section entitled “History”;
-likewise combine any sections entitled “Acknowledgements”, and any
-sections entitled “Dedications”. You must delete all sections entitled
-“Endorsements.”
-
-
-.. _fdl-section6:
-
-6. COLLECTIONS OF DOCUMENTS
-===========================
-
-You may make a collection consisting of the
-:ref:`Document <fdl-document>` and other documents released under this
-License, and replace the individual copies of this License in the
-various documents with a single copy that is included in the collection,
-provided that you follow the rules of this License for verbatim copying
-of each of the documents in all other respects.
-
-You may extract a single document from such a collection, and distribute
-it individually under this License, provided you insert a copy of this
-License into the extracted document, and follow this License in all
-other respects regarding verbatim copying of that document.
-
-
-.. _fdl-section7:
-
-7. AGGREGATION WITH INDEPENDENT WORKS
-=====================================
-
-A compilation of the :ref:`Document <fdl-document>` or its derivatives
-with other separate and independent documents or works, in or on a
-volume of a storage or distribution medium, does not as a whole count as
-a :ref:`Modified Version <fdl-modified>` of the Document, provided no
-compilation copyright is claimed for the compilation. Such a compilation
-is called an “aggregate”, and this License does not apply to the other
-self-contained works thus compiled with the Document , on account of
-their being thus compiled, if they are not themselves derivative works
-of the Document. If the :ref:`Cover Text <fdl-cover-texts>`
-requirement of :ref:`section 3 <fdl-section3>` is applicable to these
-copies of the Document, then if the Document is less than one quarter of
-the entire aggregate, the Document's Cover Texts may be placed on covers
-that surround only the Document within the aggregate. Otherwise they
-must appear on covers around the whole aggregate.
-
-
-.. _fdl-section8:
-
-8. TRANSLATION
-==============
-
-Translation is considered a kind of modification, so you may distribute
-translations of the :ref:`Document <fdl-document>` under the terms of
-:ref:`section 4 <fdl-section4>`. Replacing
-:ref:`Invariant Sections <fdl-invariant>` with translations requires
-special permission from their copyright holders, but you may include
-translations of some or all Invariant Sections in addition to the
-original versions of these Invariant Sections. You may include a
-translation of this License provided that you also include the original
-English version of this License. In case of a disagreement between the
-translation and the original English version of this License, the
-original English version will prevail.
-
-
-.. _fdl-section9:
-
-9. TERMINATION
-==============
-
-You may not copy, modify, sublicense, or distribute the
-:ref:`Document <fdl-document>` except as expressly provided for under
-this License. Any other attempt to copy, modify, sublicense or
-distribute the Document is void, and will automatically terminate your
-rights under this License. However, parties who have received copies, or
-rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
-
-.. _fdl-section10:
-
-10. FUTURE REVISIONS OF THIS LICENSE
-====================================
-
-The `Free Software Foundation <http://www.gnu.org/fsf/fsf.html>`__
-may publish new, revised versions of the GNU Free Documentation License
-from time to time. Such new versions will be similar in spirit to the
-present version, but may differ in detail to address new problems or
-concerns. See
-`http://www.gnu.org/copyleft/ <http://www.gnu.org/copyleft>`__.
-
-Each version of the License is given a distinguishing version number. If
-the :ref:`Document <fdl-document>` specifies that a particular
-numbered version of this License “or any later version” applies to it,
-you have the option of following the terms and conditions either of that
-specified version or of any later version that has been published (not
-as a draft) by the Free Software Foundation. If the Document does not
-specify a version number of this License, you may choose any version
-ever published (not as a draft) by the Free Software Foundation.
-
-
-.. _fdl-using:
-
-Addendum
-========
-
-To use this License in a document you have written, include a copy of
-the License in the document and put the following copyright and license
-notices just after the title page:
-
-    Copyright © YEAR YOUR NAME.
-
-    Permission is granted to copy, distribute and/or modify this
-    document under the terms of the GNU Free Documentation License,
-    Version 1.1 or any later version published by the Free Software
-    Foundation; with the :ref:`Invariant Sections <fdl-invariant>`
-    being LIST THEIR TITLES, with the
-    :ref:`Front-Cover Texts <fdl-cover-texts>` being LIST, and with
-    the :ref:`Back-Cover Texts <fdl-cover-texts>` being LIST. A copy
-    of the license is included in the section entitled “GNU Free
-    Documentation License”.
-
-If you have no :ref:`Invariant Sections <fdl-invariant>`, write “with
-no Invariant Sections” instead of saying which ones are invariant. If
-you have no :ref:`Front-Cover Texts <fdl-cover-texts>`, write “no
-Front-Cover Texts” instead of “Front-Cover Texts being LIST”; likewise
-for :ref:`Back-Cover Texts <fdl-cover-texts>`.
-
-If your document contains nontrivial examples of program code, we
-recommend releasing these examples in parallel under your choice of free
-software license, such as the
-`GNU General Public License <http://www.gnu.org/copyleft/gpl.html>`__,
-to permit their use in free software.
diff --git a/Documentation/media/uapi/gen-errors.rst b/Documentation/media/uapi/gen-errors.rst
deleted file mode 100644
index 043c312dc06d..000000000000
--- a/Documentation/media/uapi/gen-errors.rst
+++ /dev/null
@@ -1,103 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _gen_errors:
-
-*******************
-Generic Error Codes
-*******************
-
-
-.. _gen-errors:
-
-.. tabularcolumns:: |p{2.5cm}|p{15.0cm}|
-
-.. flat-table:: Generic error codes
-    :header-rows:  0
-    :stub-columns: 0
-    :widths: 1 16
-
-
-    -  -  ``EAGAIN`` (aka ``EWOULDBLOCK``)
-
-       -  The ioctl can't be handled because the device is in state where it
-	  can't perform it. This could happen for example in case where
-	  device is sleeping and ioctl is performed to query statistics. It
-	  is also returned when the ioctl would need to wait for an event,
-	  but the device was opened in non-blocking mode.
-
-    -  -  ``EBADF``
-
-       -  The file descriptor is not a valid.
-
-    -  -  ``EBUSY``
-
-       -  The ioctl can't be handled because the device is busy. This is
-	  typically return while device is streaming, and an ioctl tried to
-	  change something that would affect the stream, or would require
-	  the usage of a hardware resource that was already allocated. The
-	  ioctl must not be retried without performing another action to fix
-	  the problem first (typically: stop the stream before retrying).
-
-    -  -  ``EFAULT``
-
-       -  There was a failure while copying data from/to userspace, probably
-	  caused by an invalid pointer reference.
-
-    -  -  ``EINVAL``
-
-       -  One or more of the ioctl parameters are invalid or out of the
-	  allowed range. This is a widely used error code. See the
-	  individual ioctl requests for specific causes.
-
-    -  -  ``ENODEV``
-
-       -  Device not found or was removed.
-
-    -  -  ``ENOMEM``
-
-       -  There's not enough memory to handle the desired operation.
-
-    -  -  ``ENOTTY``
-
-       -  The ioctl is not supported by the driver, actually meaning that
-	  the required functionality is not available, or the file
-	  descriptor is not for a media device.
-
-    -  -  ``ENOSPC``
-
-       -  On USB devices, the stream ioctl's can return this error, meaning
-	  that this request would overcommit the usb bandwidth reserved for
-	  periodic transfers (up to 80% of the USB bandwidth).
-
-    -  -  ``EPERM``
-
-       -  Permission denied. Can be returned if the device needs write
-	  permission, or some special capabilities is needed (e. g. root)
-
-    -  -  ``EIO``
-
-       -  I/O error. Typically used when there are problems communicating with
-          a hardware device. This could indicate broken or flaky hardware.
-	  It's a 'Something is wrong, I give up!' type of error.
-
-    -  - ``ENXIO``
-
-       -  No device corresponding to this device special file exists.
-
-
-.. note::
-
-  #. This list is not exhaustive; ioctls may return other error codes.
-     Since errors may have side effects such as a driver reset,
-     applications should abort on unexpected errors, or otherwise
-     assume that the device is in a bad state.
-
-  #. Request-specific error codes are listed in the individual
-     requests descriptions.
diff --git a/Documentation/media/uapi/mediactl/media-controller-intro.rst b/Documentation/media/uapi/mediactl/media-controller-intro.rst
deleted file mode 100644
index 281c559c2f3c..000000000000
--- a/Documentation/media/uapi/mediactl/media-controller-intro.rst
+++ /dev/null
@@ -1,40 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _media-controller-intro:
-
-Introduction
-============
-
-Media devices increasingly handle multiple related functions. Many USB
-cameras include microphones, video capture hardware can also output
-video, or SoC camera interfaces also perform memory-to-memory operations
-similar to video codecs.
-
-Independent functions, even when implemented in the same hardware, can
-be modelled as separate devices. A USB camera with a microphone will be
-presented to userspace applications as V4L2 and ALSA capture devices.
-The devices' relationships (when using a webcam, end-users shouldn't
-have to manually select the associated USB microphone), while not made
-available directly to applications by the drivers, can usually be
-retrieved from sysfs.
-
-With more and more advanced SoC devices being introduced, the current
-approach will not scale. Device topologies are getting increasingly
-complex and can't always be represented by a tree structure. Hardware
-blocks are shared between different functions, creating dependencies
-between seemingly unrelated devices.
-
-Kernel abstraction APIs such as V4L2 and ALSA provide means for
-applications to access hardware parameters. As newer hardware expose an
-increasingly high number of those parameters, drivers need to guess what
-applications really require based on limited information, thereby
-implementing policies that belong to userspace.
-
-The media controller API aims at solving those problems.
diff --git a/Documentation/media/uapi/mediactl/media-controller-model.rst b/Documentation/media/uapi/mediactl/media-controller-model.rst
deleted file mode 100644
index b6d5902b556d..000000000000
--- a/Documentation/media/uapi/mediactl/media-controller-model.rst
+++ /dev/null
@@ -1,42 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _media-controller-model:
-
-Media device model
-==================
-
-Discovering a device internal topology, and configuring it at runtime,
-is one of the goals of the media controller API. To achieve this,
-hardware devices and Linux Kernel interfaces are modelled as graph
-objects on an oriented graph. The object types that constitute the graph
-are:
-
--  An **entity** is a basic media hardware or software building block.
-   It can correspond to a large variety of logical blocks such as
-   physical hardware devices (CMOS sensor for instance), logical
-   hardware devices (a building block in a System-on-Chip image
-   processing pipeline), DMA channels or physical connectors.
-
--  An **interface** is a graph representation of a Linux Kernel
-   userspace API interface, like a device node or a sysfs file that
-   controls one or more entities in the graph.
-
--  A **pad** is a data connection endpoint through which an entity can
-   interact with other entities. Data (not restricted to video) produced
-   by an entity flows from the entity's output to one or more entity
-   inputs. Pads should not be confused with physical pins at chip
-   boundaries.
-
--  A **data link** is a point-to-point oriented connection between two
-   pads, either on the same entity or on different entities. Data flows
-   from a source pad to a sink pad.
-
--  An **interface link** is a point-to-point bidirectional control
-   connection between a Linux Kernel interface and an entity.
diff --git a/Documentation/media/uapi/mediactl/media-controller.rst b/Documentation/media/uapi/mediactl/media-controller.rst
deleted file mode 100644
index 6e624f690331..000000000000
--- a/Documentation/media/uapi/mediactl/media-controller.rst
+++ /dev/null
@@ -1,62 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. include:: <isonum.txt>
-
-.. _media_controller:
-
-##############################
-Part IV - Media Controller API
-##############################
-
-.. only:: html
-
-   .. class:: toc-title
-
-        Table of Contents
-
-.. toctree::
-    :maxdepth: 5
-    :numbered:
-
-    media-controller-intro
-    media-controller-model
-    media-types
-    request-api
-    media-funcs
-    media-header
-
-
-**********************
-Revision and Copyright
-**********************
-
-Authors:
-
-- Pinchart, Laurent <laurent.pinchart@ideasonboard.com>
-
- - Initial version.
-
-- Carvalho Chehab, Mauro <mchehab@kernel.org>
-
- - MEDIA_IOC_G_TOPOLOGY documentation and documentation improvements.
-
-**Copyright** |copy| 2010 : Laurent Pinchart
-
-**Copyright** |copy| 2015-2016 : Mauro Carvalho Chehab
-
-****************
-Revision History
-****************
-
-:revision: 1.1.0 / 2015-12-12 (*mcc*)
-
-:revision: 1.0.0 / 2010-11-10 (*lp*)
-
-Initial revision
diff --git a/Documentation/media/uapi/mediactl/media-func-close.rst b/Documentation/media/uapi/mediactl/media-func-close.rst
deleted file mode 100644
index 369ccd4dee56..000000000000
--- a/Documentation/media/uapi/mediactl/media-func-close.rst
+++ /dev/null
@@ -1,54 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _media-func-close:
-
-*************
-media close()
-*************
-
-Name
-====
-
-media-close - Close a media device
-
-
-Synopsis
-========
-
-.. code-block:: c
-
-    #include <unistd.h>
-
-
-.. c:function:: int close( int fd )
-    :name: mc-close
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :c:func:`open() <mc-open>`.
-
-
-Description
-===========
-
-Closes the media device. Resources associated with the file descriptor
-are freed. The device configuration remain unchanged.
-
-
-Return Value
-============
-
-:ref:`close() <media-func-close>` returns 0 on success. On error, -1 is returned, and
-``errno`` is set appropriately. Possible error codes are:
-
-EBADF
-    ``fd`` is not a valid open file descriptor.
diff --git a/Documentation/media/uapi/mediactl/media-func-ioctl.rst b/Documentation/media/uapi/mediactl/media-func-ioctl.rst
deleted file mode 100644
index 9a990d6480f5..000000000000
--- a/Documentation/media/uapi/mediactl/media-func-ioctl.rst
+++ /dev/null
@@ -1,74 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _media-func-ioctl:
-
-*************
-media ioctl()
-*************
-
-Name
-====
-
-media-ioctl - Control a media device
-
-
-Synopsis
-========
-
-.. code-block:: c
-
-    #include <sys/ioctl.h>
-
-
-.. c:function:: int ioctl( int fd, int request, void *argp )
-    :name: mc-ioctl
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :c:func:`open() <mc-open>`.
-
-``request``
-    Media ioctl request code as defined in the media.h header file, for
-    example MEDIA_IOC_SETUP_LINK.
-
-``argp``
-    Pointer to a request-specific structure.
-
-
-Description
-===========
-
-The :ref:`ioctl() <media-func-ioctl>` function manipulates media device
-parameters. The argument ``fd`` must be an open file descriptor.
-
-The ioctl ``request`` code specifies the media function to be called. It
-has encoded in it whether the argument is an input, output or read/write
-parameter, and the size of the argument ``argp`` in bytes.
-
-Macros and structures definitions specifying media ioctl requests and
-their parameters are located in the media.h header file. All media ioctl
-requests, their respective function and parameters are specified in
-:ref:`media-user-func`.
-
-
-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.
-
-Request-specific error codes are listed in the individual requests
-descriptions.
-
-When an ioctl that takes an output or read/write parameter fails, the
-parameter remains unmodified.
diff --git a/Documentation/media/uapi/mediactl/media-func-open.rst b/Documentation/media/uapi/mediactl/media-func-open.rst
deleted file mode 100644
index cd2f840ddf73..000000000000
--- a/Documentation/media/uapi/mediactl/media-func-open.rst
+++ /dev/null
@@ -1,76 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _media-func-open:
-
-************
-media open()
-************
-
-Name
-====
-
-media-open - Open a media device
-
-
-Synopsis
-========
-
-.. code-block:: c
-
-    #include <fcntl.h>
-
-
-.. c:function:: int open( const char *device_name, int flags )
-    :name: mc-open
-
-Arguments
-=========
-
-``device_name``
-    Device to be opened.
-
-``flags``
-    Open flags. Access mode must be either ``O_RDONLY`` or ``O_RDWR``.
-    Other flags have no effect.
-
-
-Description
-===========
-
-To open a media device applications call :ref:`open() <media-func-open>` with the
-desired device name. The function has no side effects; the device
-configuration remain unchanged.
-
-When the device is opened in read-only mode, attempts to modify its
-configuration will result in an error, and ``errno`` will be set to
-EBADF.
-
-
-Return Value
-============
-
-:ref:`open() <func-open>` returns the new file descriptor on success. On error,
--1 is returned, and ``errno`` is set appropriately. Possible error codes
-are:
-
-EACCES
-    The requested access to the file is not allowed.
-
-EMFILE
-    The process already has the maximum number of files open.
-
-ENFILE
-    The system limit on the total number of open files has been reached.
-
-ENOMEM
-    Insufficient kernel memory was available.
-
-ENXIO
-    No device corresponding to this device special file exists.
diff --git a/Documentation/media/uapi/mediactl/media-funcs.rst b/Documentation/media/uapi/mediactl/media-funcs.rst
deleted file mode 100644
index 87b65df8252a..000000000000
--- a/Documentation/media/uapi/mediactl/media-funcs.rst
+++ /dev/null
@@ -1,33 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _media-user-func:
-
-******************
-Function Reference
-******************
-
-
-.. toctree::
-    :maxdepth: 1
-
-    media-func-open
-    media-func-close
-    media-func-ioctl
-    media-ioc-device-info
-    media-ioc-g-topology
-    media-ioc-enum-entities
-    media-ioc-enum-links
-    media-ioc-setup-link
-    media-ioc-request-alloc
-    request-func-close
-    request-func-ioctl
-    request-func-poll
-    media-request-ioc-queue
-    media-request-ioc-reinit
diff --git a/Documentation/media/uapi/mediactl/media-header.rst b/Documentation/media/uapi/mediactl/media-header.rst
deleted file mode 100644
index 1cb7c88aeff0..000000000000
--- a/Documentation/media/uapi/mediactl/media-header.rst
+++ /dev/null
@@ -1,17 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _media_header:
-
-****************************
-Media Controller Header File
-****************************
-
-.. kernel-include:: $BUILDDIR/media.h.rst
-
diff --git a/Documentation/media/uapi/mediactl/media-ioc-device-info.rst b/Documentation/media/uapi/mediactl/media-ioc-device-info.rst
deleted file mode 100644
index f8038cfb708c..000000000000
--- a/Documentation/media/uapi/mediactl/media-ioc-device-info.rst
+++ /dev/null
@@ -1,118 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _media_ioc_device_info:
-
-***************************
-ioctl MEDIA_IOC_DEVICE_INFO
-***************************
-
-Name
-====
-
-MEDIA_IOC_DEVICE_INFO - Query device information
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, MEDIA_IOC_DEVICE_INFO, struct media_device_info *argp )
-    :name: MEDIA_IOC_DEVICE_INFO
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <media-func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`media_device_info`.
-
-
-Description
-===========
-
-All media devices must support the ``MEDIA_IOC_DEVICE_INFO`` ioctl. To
-query device information, applications call the ioctl with a pointer to
-a struct :c:type:`media_device_info`. The driver
-fills the structure and returns the information to the application. The
-ioctl never fails.
-
-
-.. c:type:: media_device_info
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. flat-table:: struct media_device_info
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-
-    *  -  char
-       -  ``driver``\ [16]
-       -  Name of the driver implementing the media API as a NUL-terminated
-	  ASCII string. The driver version is stored in the
-	  ``driver_version`` field.
-
-	  Driver specific applications can use this information to verify
-	  the driver identity. It is also useful to work around known bugs,
-	  or to identify drivers in error reports.
-
-    *  -  char
-       -  ``model``\ [32]
-       -  Device model name as a NUL-terminated UTF-8 string. The device
-	  version is stored in the ``device_version`` field and is not be
-	  appended to the model name.
-
-    *  -  char
-       -  ``serial``\ [40]
-       -  Serial number as a NUL-terminated ASCII string.
-
-    *  -  char
-       -  ``bus_info``\ [32]
-       -  Location of the device in the system as a NUL-terminated ASCII
-	  string. This includes the bus type name (PCI, USB, ...) and a
-	  bus-specific identifier.
-
-    *  -  __u32
-       -  ``media_version``
-       -  Media API version, formatted with the ``KERNEL_VERSION()`` macro.
-
-    *  -  __u32
-       -  ``hw_revision``
-       -  Hardware device revision in a driver-specific format.
-
-    *  -  __u32
-       -  ``driver_version``
-       -  Media device driver version, formatted with the
-	  ``KERNEL_VERSION()`` macro. Together with the ``driver`` field
-	  this identifies a particular driver.
-
-    *  -  __u32
-       -  ``reserved``\ [31]
-       -  Reserved for future extensions. Drivers and applications must set
-	  this array to zero.
-
-
-The ``serial`` and ``bus_info`` fields can be used to distinguish
-between multiple instances of otherwise identical hardware. The serial
-number takes precedence when provided and can be assumed to be unique.
-If the serial number is an empty string, the ``bus_info`` field can be
-used instead. The ``bus_info`` field is guaranteed to be unique, but can
-vary across reboots or device unplug/replug.
-
-
-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/mediactl/media-ioc-enum-entities.rst b/Documentation/media/uapi/mediactl/media-ioc-enum-entities.rst
deleted file mode 100644
index 33e2b110145c..000000000000
--- a/Documentation/media/uapi/mediactl/media-ioc-enum-entities.rst
+++ /dev/null
@@ -1,156 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _media_ioc_enum_entities:
-
-*****************************
-ioctl MEDIA_IOC_ENUM_ENTITIES
-*****************************
-
-Name
-====
-
-MEDIA_IOC_ENUM_ENTITIES - Enumerate entities and their properties
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, MEDIA_IOC_ENUM_ENTITIES, struct media_entity_desc *argp )
-    :name: MEDIA_IOC_ENUM_ENTITIES
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <media-func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`media_entity_desc`.
-
-
-Description
-===========
-
-To query the attributes of an entity, applications set the id field of a
-struct :c:type:`media_entity_desc` structure and
-call the MEDIA_IOC_ENUM_ENTITIES ioctl with a pointer to this
-structure. The driver fills the rest of the structure or returns an
-EINVAL error code when the id is invalid.
-
-.. _media-ent-id-flag-next:
-
-Entities can be enumerated by or'ing the id with the
-``MEDIA_ENT_ID_FLAG_NEXT`` flag. The driver will return information
-about the entity with the smallest id strictly larger than the requested
-one ('next entity'), or the ``EINVAL`` error code if there is none.
-
-Entity IDs can be non-contiguous. Applications must *not* try to
-enumerate entities by calling MEDIA_IOC_ENUM_ENTITIES with increasing
-id's until they get an error.
-
-
-.. c:type:: media_entity_desc
-
-.. tabularcolumns:: |p{1.5cm}|p{1.7cm}|p{1.6cm}|p{1.5cm}|p{11.2cm}|
-
-.. flat-table:: struct media_entity_desc
-    :header-rows:  0
-    :stub-columns: 0
-    :widths: 2 2 1 8
-
-    *  -  __u32
-       -  ``id``
-       -
-       -  Entity ID, set by the application. When the ID is or'ed with
-	  ``MEDIA_ENT_ID_FLAG_NEXT``, the driver clears the flag and returns
-	  the first entity with a larger ID. Do not expect that the ID will
-	  always be the same for each instance of the device. In other words,
-	  do not hardcode entity IDs in an application.
-
-    *  -  char
-       -  ``name``\ [32]
-       -
-       -  Entity name as an UTF-8 NULL-terminated string. This name must be unique
-          within the media topology.
-
-    *  -  __u32
-       -  ``type``
-       -
-       -  Entity type, see :ref:`media-entity-functions` for details.
-
-    *  -  __u32
-       -  ``revision``
-       -
-       -  Entity revision. Always zero (obsolete)
-
-    *  -  __u32
-       -  ``flags``
-       -
-       -  Entity flags, see :ref:`media-entity-flag` for details.
-
-    *  -  __u32
-       -  ``group_id``
-       -
-       -  Entity group ID. Always zero (obsolete)
-
-    *  -  __u16
-       -  ``pads``
-       -
-       -  Number of pads
-
-    *  -  __u16
-       -  ``links``
-       -
-       -  Total number of outbound links. Inbound links are not counted in
-	  this field.
-
-    *  -  __u32
-       -  ``reserved[4]``
-       -
-       -  Reserved for future extensions. Drivers and applications must set
-          the array to zero.
-
-    *  -  union {
-       -  (anonymous)
-
-    *  -  struct
-       -  ``dev``
-       -
-       -  Valid for (sub-)devices that create a single device node.
-
-    *  -
-       -  __u32
-       -  ``major``
-       -  Device node major number.
-
-    *  -
-       -  __u32
-       -  ``minor``
-       -  Device node minor number.
-
-    *  -  __u8
-       -  ``raw``\ [184]
-       -
-       -
-    *  - }
-       -
-
-
-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
-    The struct :c:type:`media_entity_desc` ``id``
-    references a non-existing entity.
diff --git a/Documentation/media/uapi/mediactl/media-ioc-enum-links.rst b/Documentation/media/uapi/mediactl/media-ioc-enum-links.rst
deleted file mode 100644
index b827ebc398f8..000000000000
--- a/Documentation/media/uapi/mediactl/media-ioc-enum-links.rst
+++ /dev/null
@@ -1,157 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _media_ioc_enum_links:
-
-**************************
-ioctl MEDIA_IOC_ENUM_LINKS
-**************************
-
-Name
-====
-
-MEDIA_IOC_ENUM_LINKS - Enumerate all pads and links for a given entity
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, MEDIA_IOC_ENUM_LINKS, struct media_links_enum *argp )
-    :name: MEDIA_IOC_ENUM_LINKS
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <media-func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`media_links_enum`.
-
-
-Description
-===========
-
-To enumerate pads and/or links for a given entity, applications set the
-entity field of a struct :c:type:`media_links_enum`
-structure and initialize the struct
-:c:type:`media_pad_desc` and struct
-:c:type:`media_link_desc` structure arrays pointed by
-the ``pads`` and ``links`` fields. They then call the
-MEDIA_IOC_ENUM_LINKS ioctl with a pointer to this structure.
-
-If the ``pads`` field is not NULL, the driver fills the ``pads`` array
-with information about the entity's pads. The array must have enough
-room to store all the entity's pads. The number of pads can be retrieved
-with :ref:`MEDIA_IOC_ENUM_ENTITIES`.
-
-If the ``links`` field is not NULL, the driver fills the ``links`` array
-with information about the entity's outbound links. The array must have
-enough room to store all the entity's outbound links. The number of
-outbound links can be retrieved with :ref:`MEDIA_IOC_ENUM_ENTITIES`.
-
-Only forward links that originate at one of the entity's source pads are
-returned during the enumeration process.
-
-
-.. c:type:: media_links_enum
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. flat-table:: struct media_links_enum
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    *  -  __u32
-       -  ``entity``
-       -  Entity id, set by the application.
-
-    *  -  struct :c:type:`media_pad_desc`
-       -  \*\ ``pads``
-       -  Pointer to a pads array allocated by the application. Ignored if
-	  NULL.
-
-    *  -  struct :c:type:`media_link_desc`
-       -  \*\ ``links``
-       -  Pointer to a links array allocated by the application. Ignored if
-	  NULL.
-
-    *  -  __u32
-       -  ``reserved[4]``
-       -  Reserved for future extensions. Drivers and applications must set
-          the array to zero.
-
-
-.. c:type:: media_pad_desc
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. flat-table:: struct media_pad_desc
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    *  -  __u32
-       -  ``entity``
-       -  ID of the entity this pad belongs to.
-
-    *  -  __u16
-       -  ``index``
-       -  Pad index, starts at 0.
-
-    *  -  __u32
-       -  ``flags``
-       -  Pad flags, see :ref:`media-pad-flag` for more details.
-
-    *  -  __u32
-       -  ``reserved[2]``
-       -  Reserved for future extensions. Drivers and applications must set
-          the array to zero.
-
-
-
-.. c:type:: media_link_desc
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. flat-table:: struct media_link_desc
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    *  -  struct :c:type:`media_pad_desc`
-       -  ``source``
-       -  Pad at the origin of this link.
-
-    *  -  struct :c:type:`media_pad_desc`
-       -  ``sink``
-       -  Pad at the target of this link.
-
-    *  -  __u32
-       -  ``flags``
-       -  Link flags, see :ref:`media-link-flag` for more details.
-
-    *  -  __u32
-       -  ``reserved[2]``
-       -  Reserved for future extensions. Drivers and applications must set
-          the array to zero.
-
-
-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
-    The struct :c:type:`media_links_enum` ``id``
-    references a non-existing entity.
diff --git a/Documentation/media/uapi/mediactl/media-ioc-g-topology.rst b/Documentation/media/uapi/mediactl/media-ioc-g-topology.rst
deleted file mode 100644
index 0a7d76ac8ded..000000000000
--- a/Documentation/media/uapi/mediactl/media-ioc-g-topology.rst
+++ /dev/null
@@ -1,307 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _media_ioc_g_topology:
-
-**************************
-ioctl MEDIA_IOC_G_TOPOLOGY
-**************************
-
-Name
-====
-
-MEDIA_IOC_G_TOPOLOGY - Enumerate the graph topology and graph element properties
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, MEDIA_IOC_G_TOPOLOGY, struct media_v2_topology *argp )
-    :name: MEDIA_IOC_G_TOPOLOGY
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <media-func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`media_v2_topology`.
-
-
-Description
-===========
-
-The typical usage of this ioctl is to call it twice. On the first call,
-the structure defined at struct
-:c:type:`media_v2_topology` should be zeroed. At
-return, if no errors happen, this ioctl will return the
-``topology_version`` and the total number of entities, interfaces, pads
-and links.
-
-Before the second call, the userspace should allocate arrays to store
-the graph elements that are desired, putting the pointers to them at the
-ptr_entities, ptr_interfaces, ptr_links and/or ptr_pads, keeping the
-other values untouched.
-
-If the ``topology_version`` remains the same, the ioctl should fill the
-desired arrays with the media graph elements.
-
-.. tabularcolumns:: |p{1.6cm}|p{3.4cm}|p{12.5cm}|
-
-.. c:type:: media_v2_topology
-
-.. flat-table:: struct media_v2_topology
-    :header-rows:  0
-    :stub-columns: 0
-    :widths: 1 2 8
-
-    *  -  __u64
-       -  ``topology_version``
-       -  Version of the media graph topology. When the graph is created,
-	  this field starts with zero. Every time a graph element is added
-	  or removed, this field is incremented.
-
-    *  -  __u32
-       -  ``num_entities``
-       -  Number of entities in the graph
-
-    *  -  __u32
-       -  ``reserved1``
-       -  Applications and drivers shall set this to 0.
-
-    *  -  __u64
-       -  ``ptr_entities``
-       -  A pointer to a memory area where the entities array will be
-	  stored, converted to a 64-bits integer. It can be zero. if zero,
-	  the ioctl won't store the entities. It will just update
-	  ``num_entities``
-
-    *  -  __u32
-       -  ``num_interfaces``
-       -  Number of interfaces in the graph
-
-    *  -  __u32
-       -  ``reserved2``
-       -  Applications and drivers shall set this to 0.
-
-    *  -  __u64
-       -  ``ptr_interfaces``
-       -  A pointer to a memory area where the interfaces array will be
-	  stored, converted to a 64-bits integer. It can be zero. if zero,
-	  the ioctl won't store the interfaces. It will just update
-	  ``num_interfaces``
-
-    *  -  __u32
-       -  ``num_pads``
-       -  Total number of pads in the graph
-
-    *  -  __u32
-       -  ``reserved3``
-       -  Applications and drivers shall set this to 0.
-
-    *  -  __u64
-       -  ``ptr_pads``
-       -  A pointer to a memory area where the pads array will be stored,
-	  converted to a 64-bits integer. It can be zero. if zero, the ioctl
-	  won't store the pads. It will just update ``num_pads``
-
-    *  -  __u32
-       -  ``num_links``
-       -  Total number of data and interface links in the graph
-
-    *  -  __u32
-       -  ``reserved4``
-       -  Applications and drivers shall set this to 0.
-
-    *  -  __u64
-       -  ``ptr_links``
-       -  A pointer to a memory area where the links array will be stored,
-	  converted to a 64-bits integer. It can be zero. if zero, the ioctl
-	  won't store the links. It will just update ``num_links``
-
-
-.. tabularcolumns:: |p{1.6cm}|p{3.2cm}|p{12.7cm}|
-
-.. c:type:: media_v2_entity
-
-.. flat-table:: struct media_v2_entity
-    :header-rows:  0
-    :stub-columns: 0
-    :widths: 1 2 8
-
-    *  -  __u32
-       -  ``id``
-       -  Unique ID for the entity. Do not expect that the ID will
-	  always be the same for each instance of the device. In other words,
-	  do not hardcode entity IDs in an application.
-
-    *  -  char
-       -  ``name``\ [64]
-       -  Entity name as an UTF-8 NULL-terminated string. This name must be unique
-          within the media topology.
-
-    *  -  __u32
-       -  ``function``
-       -  Entity main function, see :ref:`media-entity-functions` for details.
-
-    *  -  __u32
-       -  ``flags``
-       -  Entity flags, see :ref:`media-entity-flag` for details.
-	  Only valid if ``MEDIA_V2_ENTITY_HAS_FLAGS(media_version)``
-	  returns true. The ``media_version`` is defined in struct
-	  :c:type:`media_device_info` and can be retrieved using
-	  :ref:`MEDIA_IOC_DEVICE_INFO`.
-
-    *  -  __u32
-       -  ``reserved``\ [5]
-       -  Reserved for future extensions. Drivers and applications must set
-	  this array to zero.
-
-
-.. tabularcolumns:: |p{1.6cm}|p{3.2cm}|p{12.7cm}|
-
-.. c:type:: media_v2_interface
-
-.. flat-table:: struct media_v2_interface
-    :header-rows:  0
-    :stub-columns: 0
-    :widths: 1 2 8
-
-    *  -  __u32
-       -  ``id``
-       -  Unique ID for the interface. Do not expect that the ID will
-	  always be the same for each instance of the device. In other words,
-	  do not hardcode interface IDs in an application.
-
-    *  -  __u32
-       -  ``intf_type``
-       -  Interface type, see :ref:`media-intf-type` for details.
-
-    *  -  __u32
-       -  ``flags``
-       -  Interface flags. Currently unused.
-
-    *  -  __u32
-       -  ``reserved``\ [9]
-       -  Reserved for future extensions. Drivers and applications must set
-	  this array to zero.
-
-    *  -  struct media_v2_intf_devnode
-       -  ``devnode``
-       -  Used only for device node interfaces. See
-	  :c:type:`media_v2_intf_devnode` for details.
-
-
-.. tabularcolumns:: |p{1.6cm}|p{3.2cm}|p{12.7cm}|
-
-.. c:type:: media_v2_intf_devnode
-
-.. flat-table:: struct media_v2_intf_devnode
-    :header-rows:  0
-    :stub-columns: 0
-    :widths: 1 2 8
-
-    *  -  __u32
-       -  ``major``
-       -  Device node major number.
-
-    *  -  __u32
-       -  ``minor``
-       -  Device node minor number.
-
-.. tabularcolumns:: |p{1.6cm}|p{3.2cm}|p{12.7cm}|
-
-.. c:type:: media_v2_pad
-
-.. flat-table:: struct media_v2_pad
-    :header-rows:  0
-    :stub-columns: 0
-    :widths: 1 2 8
-
-    *  -  __u32
-       -  ``id``
-       -  Unique ID for the pad. Do not expect that the ID will
-	  always be the same for each instance of the device. In other words,
-	  do not hardcode pad IDs in an application.
-
-    *  -  __u32
-       -  ``entity_id``
-       -  Unique ID for the entity where this pad belongs.
-
-    *  -  __u32
-       -  ``flags``
-       -  Pad flags, see :ref:`media-pad-flag` for more details.
-
-    *  -  __u32
-       -  ``index``
-       -  Pad index, starts at 0. Only valid if ``MEDIA_V2_PAD_HAS_INDEX(media_version)``
-	  returns true. The ``media_version`` is defined in struct
-	  :c:type:`media_device_info` and can be retrieved using
-	  :ref:`MEDIA_IOC_DEVICE_INFO`.
-
-    *  -  __u32
-       -  ``reserved``\ [4]
-       -  Reserved for future extensions. Drivers and applications must set
-	  this array to zero.
-
-
-.. tabularcolumns:: |p{1.6cm}|p{3.2cm}|p{12.7cm}|
-
-.. c:type:: media_v2_link
-
-.. flat-table:: struct media_v2_link
-    :header-rows:  0
-    :stub-columns: 0
-    :widths: 1 2 8
-
-    *  -  __u32
-       -  ``id``
-       -  Unique ID for the link. Do not expect that the ID will
-	  always be the same for each instance of the device. In other words,
-	  do not hardcode link IDs in an application.
-
-    *  -  __u32
-       -  ``source_id``
-       -  On pad to pad links: unique ID for the source pad.
-
-	  On interface to entity links: unique ID for the interface.
-
-    *  -  __u32
-       -  ``sink_id``
-       -  On pad to pad links: unique ID for the sink pad.
-
-	  On interface to entity links: unique ID for the entity.
-
-    *  -  __u32
-       -  ``flags``
-       -  Link flags, see :ref:`media-link-flag` for more details.
-
-    *  -  __u32
-       -  ``reserved``\ [6]
-       -  Reserved for future extensions. Drivers and applications must set
-	  this array to zero.
-
-
-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.
-
-ENOSPC
-    This is returned when either one or more of the num_entities,
-    num_interfaces, num_links or num_pads are non-zero and are
-    smaller than the actual number of elements inside the graph. This
-    may happen if the ``topology_version`` changed when compared to the
-    last time this ioctl was called. Userspace should usually free the
-    area for the pointers, zero the struct elements and call this ioctl
-    again.
diff --git a/Documentation/media/uapi/mediactl/media-ioc-request-alloc.rst b/Documentation/media/uapi/mediactl/media-ioc-request-alloc.rst
deleted file mode 100644
index 6d4ca4ada2e0..000000000000
--- a/Documentation/media/uapi/mediactl/media-ioc-request-alloc.rst
+++ /dev/null
@@ -1,90 +0,0 @@
-.. This file is dual-licensed: you can use it either under the terms
-.. of the GPL 2.0 or the GFDL 1.1+ license, at your option. Note that this
-.. dual licensing only applies to this file, and not this project as a
-.. whole.
-..
-.. a) This file is free software; you can redistribute it and/or
-..    modify it under the terms of the GNU General Public License as
-..    published by the Free Software Foundation version 2 of
-..    the License.
-..
-..    This file is distributed in the hope that it will be useful,
-..    but WITHOUT ANY WARRANTY; without even the implied warranty of
-..    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-..    GNU General Public License for more details.
-..
-.. Or, alternatively,
-..
-.. b) Permission is granted to copy, distribute and/or modify this
-..    document under the terms of the GNU Free Documentation License,
-..    Version 1.1 or any later version published by the Free Software
-..    Foundation, with no Invariant Sections, no Front-Cover Texts
-..    and no Back-Cover Texts. A copy of the license is included at
-..    Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _media_ioc_request_alloc:
-
-*****************************
-ioctl MEDIA_IOC_REQUEST_ALLOC
-*****************************
-
-Name
-====
-
-MEDIA_IOC_REQUEST_ALLOC - Allocate a request
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, MEDIA_IOC_REQUEST_ALLOC, int *argp )
-    :name: MEDIA_IOC_REQUEST_ALLOC
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <media-func-open>`.
-
-``argp``
-    Pointer to an integer.
-
-
-Description
-===========
-
-If the media device supports :ref:`requests <media-request-api>`, then
-this ioctl can be used to allocate a request. If it is not supported, then
-``errno`` is set to ``ENOTTY``. A request is accessed through a file descriptor
-that is returned in ``*argp``.
-
-If the request was successfully allocated, then the request file descriptor
-can be passed to the :ref:`VIDIOC_QBUF <VIDIOC_QBUF>`,
-:ref:`VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>`,
-:ref:`VIDIOC_S_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` and
-:ref:`VIDIOC_TRY_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` ioctls.
-
-In addition, the request can be queued by calling
-:ref:`MEDIA_REQUEST_IOC_QUEUE` and re-initialized by calling
-:ref:`MEDIA_REQUEST_IOC_REINIT`.
-
-Finally, the file descriptor can be :ref:`polled <request-func-poll>` to wait
-for the request to complete.
-
-The request will remain allocated until all the file descriptors associated
-with it are closed by :ref:`close() <request-func-close>` and the driver no
-longer uses the request internally. See also
-:ref:`here <media-request-life-time>` for more information.
-
-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.
-
-ENOTTY
-    The driver has no support for requests.
diff --git a/Documentation/media/uapi/mediactl/media-ioc-setup-link.rst b/Documentation/media/uapi/mediactl/media-ioc-setup-link.rst
deleted file mode 100644
index ae39dbbe48a0..000000000000
--- a/Documentation/media/uapi/mediactl/media-ioc-setup-link.rst
+++ /dev/null
@@ -1,74 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _media_ioc_setup_link:
-
-**************************
-ioctl MEDIA_IOC_SETUP_LINK
-**************************
-
-Name
-====
-
-MEDIA_IOC_SETUP_LINK - Modify the properties of a link
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, MEDIA_IOC_SETUP_LINK, struct media_link_desc *argp )
-    :name: MEDIA_IOC_SETUP_LINK
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <media-func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`media_link_desc`.
-
-
-Description
-===========
-
-To change link properties applications fill a struct
-:c:type:`media_link_desc` with link identification
-information (source and sink pad) and the new requested link flags. They
-then call the MEDIA_IOC_SETUP_LINK ioctl with a pointer to that
-structure.
-
-The only configurable property is the ``ENABLED`` link flag to
-enable/disable a link. Links marked with the ``IMMUTABLE`` link flag can
-not be enabled or disabled.
-
-Link configuration has no side effect on other links. If an enabled link
-at the sink pad prevents the link from being enabled, the driver returns
-with an ``EBUSY`` error code.
-
-Only links marked with the ``DYNAMIC`` link flag can be enabled/disabled
-while streaming media data. Attempting to enable or disable a streaming
-non-dynamic link will return an ``EBUSY`` error code.
-
-If the specified link can't be found the driver returns with an ``EINVAL``
-error code.
-
-
-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
-    The struct :c:type:`media_link_desc` references a
-    non-existing link, or the link is immutable and an attempt to modify
-    its configuration was made.
diff --git a/Documentation/media/uapi/mediactl/media-request-ioc-queue.rst b/Documentation/media/uapi/mediactl/media-request-ioc-queue.rst
deleted file mode 100644
index fc8458746d51..000000000000
--- a/Documentation/media/uapi/mediactl/media-request-ioc-queue.rst
+++ /dev/null
@@ -1,102 +0,0 @@
-.. This file is dual-licensed: you can use it either under the terms
-.. of the GPL 2.0 or the GFDL 1.1+ license, at your option. Note that this
-.. dual licensing only applies to this file, and not this project as a
-.. whole.
-..
-.. a) This file is free software; you can redistribute it and/or
-..    modify it under the terms of the GNU General Public License as
-..    published by the Free Software Foundation version 2 of
-..    the License.
-..
-..    This file is distributed in the hope that it will be useful,
-..    but WITHOUT ANY WARRANTY; without even the implied warranty of
-..    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-..    GNU General Public License for more details.
-..
-.. Or, alternatively,
-..
-.. b) Permission is granted to copy, distribute and/or modify this
-..    document under the terms of the GNU Free Documentation License,
-..    Version 1.1 or any later version published by the Free Software
-..    Foundation, with no Invariant Sections, no Front-Cover Texts
-..    and no Back-Cover Texts. A copy of the license is included at
-..    Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _media_request_ioc_queue:
-
-*****************************
-ioctl MEDIA_REQUEST_IOC_QUEUE
-*****************************
-
-Name
-====
-
-MEDIA_REQUEST_IOC_QUEUE - Queue a request
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int request_fd, MEDIA_REQUEST_IOC_QUEUE )
-    :name: MEDIA_REQUEST_IOC_QUEUE
-
-
-Arguments
-=========
-
-``request_fd``
-    File descriptor returned by :ref:`MEDIA_IOC_REQUEST_ALLOC`.
-
-
-Description
-===========
-
-If the media device supports :ref:`requests <media-request-api>`, then
-this request ioctl can be used to queue a previously allocated request.
-
-If the request was successfully queued, then the file descriptor can be
-:ref:`polled <request-func-poll>` to wait for the request to complete.
-
-If the request was already queued before, then ``EBUSY`` is returned.
-Other errors can be returned if the contents of the request contained
-invalid or inconsistent data, see the next section for a list of
-common error codes. On error both the request and driver state are unchanged.
-
-Once a request is queued, then the driver is required to gracefully handle
-errors that occur when the request is applied to the hardware. The
-exception is the ``EIO`` error which signals a fatal error that requires
-the application to stop streaming to reset the hardware state.
-
-It is not allowed to mix queuing requests with queuing buffers directly
-(without a request). ``EBUSY`` will be returned if the first buffer was
-queued directly and you next try to queue a request, or vice versa.
-
-A request must contain at least one buffer, otherwise this ioctl will
-return an ``ENOENT`` error.
-
-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.
-
-EBUSY
-    The request was already queued or the application queued the first
-    buffer directly, but later attempted to use a request. It is not permitted
-    to mix the two APIs.
-ENOENT
-    The request did not contain any buffers. All requests are required
-    to have at least one buffer. This can also be returned if some required
-    configuration is missing in the request.
-ENOMEM
-    Out of memory when allocating internal data structures for this
-    request.
-EINVAL
-    The request has invalid data.
-EIO
-    The hardware is in a bad state. To recover, the application needs to
-    stop streaming to reset the hardware state and then try to restart
-    streaming.
diff --git a/Documentation/media/uapi/mediactl/media-request-ioc-reinit.rst b/Documentation/media/uapi/mediactl/media-request-ioc-reinit.rst
deleted file mode 100644
index 61381e87665a..000000000000
--- a/Documentation/media/uapi/mediactl/media-request-ioc-reinit.rst
+++ /dev/null
@@ -1,75 +0,0 @@
-.. This file is dual-licensed: you can use it either under the terms
-.. of the GPL 2.0 or the GFDL 1.1+ license, at your option. Note that this
-.. dual licensing only applies to this file, and not this project as a
-.. whole.
-..
-.. a) This file is free software; you can redistribute it and/or
-..    modify it under the terms of the GNU General Public License as
-..    published by the Free Software Foundation version 2 of
-..    the License.
-..
-..    This file is distributed in the hope that it will be useful,
-..    but WITHOUT ANY WARRANTY; without even the implied warranty of
-..    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-..    GNU General Public License for more details.
-..
-.. Or, alternatively,
-..
-.. b) Permission is granted to copy, distribute and/or modify this
-..    document under the terms of the GNU Free Documentation License,
-..    Version 1.1 or any later version published by the Free Software
-..    Foundation, with no Invariant Sections, no Front-Cover Texts
-..    and no Back-Cover Texts. A copy of the license is included at
-..    Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _media_request_ioc_reinit:
-
-******************************
-ioctl MEDIA_REQUEST_IOC_REINIT
-******************************
-
-Name
-====
-
-MEDIA_REQUEST_IOC_REINIT - Re-initialize a request
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int request_fd, MEDIA_REQUEST_IOC_REINIT )
-    :name: MEDIA_REQUEST_IOC_REINIT
-
-
-Arguments
-=========
-
-``request_fd``
-    File descriptor returned by :ref:`MEDIA_IOC_REQUEST_ALLOC`.
-
-Description
-===========
-
-If the media device supports :ref:`requests <media-request-api>`, then
-this request ioctl can be used to re-initialize a previously allocated
-request.
-
-Re-initializing a request will clear any existing data from the request.
-This avoids having to :ref:`close() <request-func-close>` a completed
-request and allocate a new request. Instead the completed request can just
-be re-initialized and it is ready to be used again.
-
-A request can only be re-initialized if it either has not been queued
-yet, or if it was queued and completed. Otherwise it will set ``errno``
-to ``EBUSY``. No other error codes can be returned.
-
-Return Value
-============
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately.
-
-EBUSY
-    The request is queued but not yet completed.
diff --git a/Documentation/media/uapi/mediactl/media-types.rst b/Documentation/media/uapi/mediactl/media-types.rst
deleted file mode 100644
index 3af6a414b501..000000000000
--- a/Documentation/media/uapi/mediactl/media-types.rst
+++ /dev/null
@@ -1,425 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _media-controller-types:
-
-Types and flags used to represent the media graph elements
-==========================================================
-
-..  tabularcolumns:: |p{8.2cm}|p{10.3cm}|
-
-.. _media-entity-functions:
-.. _MEDIA-ENT-F-UNKNOWN:
-.. _MEDIA-ENT-F-V4L2-SUBDEV-UNKNOWN:
-.. _MEDIA-ENT-F-IO-V4L:
-.. _MEDIA-ENT-F-IO-VBI:
-.. _MEDIA-ENT-F-IO-SWRADIO:
-.. _MEDIA-ENT-F-IO-DTV:
-.. _MEDIA-ENT-F-DTV-DEMOD:
-.. _MEDIA-ENT-F-TS-DEMUX:
-.. _MEDIA-ENT-F-DTV-CA:
-.. _MEDIA-ENT-F-DTV-NET-DECAP:
-.. _MEDIA-ENT-F-CONN-RF:
-.. _MEDIA-ENT-F-CONN-SVIDEO:
-.. _MEDIA-ENT-F-CONN-COMPOSITE:
-.. _MEDIA-ENT-F-CAM-SENSOR:
-.. _MEDIA-ENT-F-FLASH:
-.. _MEDIA-ENT-F-LENS:
-.. _MEDIA-ENT-F-ATV-DECODER:
-.. _MEDIA-ENT-F-TUNER:
-.. _MEDIA-ENT-F-IF-VID-DECODER:
-.. _MEDIA-ENT-F-IF-AUD-DECODER:
-.. _MEDIA-ENT-F-AUDIO-CAPTURE:
-.. _MEDIA-ENT-F-AUDIO-PLAYBACK:
-.. _MEDIA-ENT-F-AUDIO-MIXER:
-.. _MEDIA-ENT-F-PROC-VIDEO-COMPOSER:
-.. _MEDIA-ENT-F-PROC-VIDEO-PIXEL-FORMATTER:
-.. _MEDIA-ENT-F-PROC-VIDEO-PIXEL-ENC-CONV:
-.. _MEDIA-ENT-F-PROC-VIDEO-LUT:
-.. _MEDIA-ENT-F-PROC-VIDEO-SCALER:
-.. _MEDIA-ENT-F-PROC-VIDEO-STATISTICS:
-.. _MEDIA-ENT-F-PROC-VIDEO-ENCODER:
-.. _MEDIA-ENT-F-PROC-VIDEO-DECODER:
-.. _MEDIA-ENT-F-VID-MUX:
-.. _MEDIA-ENT-F-VID-IF-BRIDGE:
-.. _MEDIA-ENT-F-DV-DECODER:
-.. _MEDIA-ENT-F-DV-ENCODER:
-
-.. cssclass:: longtable
-
-.. flat-table:: Media entity functions
-    :header-rows:  0
-    :stub-columns: 0
-
-    *  -  ``MEDIA_ENT_F_UNKNOWN`` and
-	  ``MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN``
-       -  Unknown entity. That generally indicates that a driver didn't
-	  initialize properly the entity, which is a Kernel bug
-
-    *  -  ``MEDIA_ENT_F_IO_V4L``
-       -  Data streaming input and/or output entity.
-
-    *  -  ``MEDIA_ENT_F_IO_VBI``
-       -  V4L VBI streaming input or output entity
-
-    *  -  ``MEDIA_ENT_F_IO_SWRADIO``
-       -  V4L Software Digital Radio (SDR) streaming input or output entity
-
-    *  -  ``MEDIA_ENT_F_IO_DTV``
-       -  DVB Digital TV streaming input or output entity
-
-    *  -  ``MEDIA_ENT_F_DTV_DEMOD``
-       -  Digital TV demodulator entity.
-
-    *  -  ``MEDIA_ENT_F_TS_DEMUX``
-       -  MPEG Transport stream demux entity. Could be implemented on
-	  hardware or in Kernelspace by the Linux DVB subsystem.
-
-    *  -  ``MEDIA_ENT_F_DTV_CA``
-       -  Digital TV Conditional Access module (CAM) entity
-
-    *  -  ``MEDIA_ENT_F_DTV_NET_DECAP``
-       -  Digital TV network ULE/MLE desencapsulation entity. Could be
-	  implemented on hardware or in Kernelspace
-
-    *  -  ``MEDIA_ENT_F_CONN_RF``
-       -  Connector for a Radio Frequency (RF) signal.
-
-    *  -  ``MEDIA_ENT_F_CONN_SVIDEO``
-       -  Connector for a S-Video signal.
-
-    *  -  ``MEDIA_ENT_F_CONN_COMPOSITE``
-       -  Connector for a RGB composite signal.
-
-    *  -  ``MEDIA_ENT_F_CAM_SENSOR``
-       -  Camera video sensor entity.
-
-    *  -  ``MEDIA_ENT_F_FLASH``
-       -  Flash controller entity.
-
-    *  -  ``MEDIA_ENT_F_LENS``
-       -  Lens controller entity.
-
-    *  -  ``MEDIA_ENT_F_ATV_DECODER``
-       -  Analog video decoder, the basic function of the video decoder is
-	  to accept analogue video from a wide variety of sources such as
-	  broadcast, DVD players, cameras and video cassette recorders, in
-	  either NTSC, PAL, SECAM or HD format, separating the stream into
-	  its component parts, luminance and chrominance, and output it in
-	  some digital video standard, with appropriate timing signals.
-
-    *  -  ``MEDIA_ENT_F_TUNER``
-       -  Digital TV, analog TV, radio and/or software radio tuner, with
-	  consists on a PLL tuning stage that converts radio frequency (RF)
-	  signal into an Intermediate Frequency (IF). Modern tuners have
-	  internally IF-PLL decoders for audio and video, but older models
-	  have those stages implemented on separate entities.
-
-    *  -  ``MEDIA_ENT_F_IF_VID_DECODER``
-       -  IF-PLL video decoder. It receives the IF from a PLL and decodes
-	  the analog TV video signal. This is commonly found on some very
-	  old analog tuners, like Philips MK3 designs. They all contain a
-	  tda9887 (or some software compatible similar chip, like tda9885).
-	  Those devices use a different I2C address than the tuner PLL.
-
-    *  -  ``MEDIA_ENT_F_IF_AUD_DECODER``
-       -  IF-PLL sound decoder. It receives the IF from a PLL and decodes
-	  the analog TV audio signal. This is commonly found on some very
-	  old analog hardware, like Micronas msp3400, Philips tda9840,
-	  tda985x, etc. Those devices use a different I2C address than the
-	  tuner PLL and should be controlled together with the IF-PLL video
-	  decoder.
-
-    *  -  ``MEDIA_ENT_F_AUDIO_CAPTURE``
-       -  Audio Capture Function Entity.
-
-    *  -  ``MEDIA_ENT_F_AUDIO_PLAYBACK``
-       -  Audio Playback Function Entity.
-
-    *  -  ``MEDIA_ENT_F_AUDIO_MIXER``
-       -  Audio Mixer Function Entity.
-
-    *  -  ``MEDIA_ENT_F_PROC_VIDEO_COMPOSER``
-       -  Video composer (blender). An entity capable of video
-	  composing must have at least two sink pads and one source
-	  pad, and composes input video frames onto output video
-	  frames. Composition can be performed using alpha blending,
-	  color keying, raster operations (ROP), stitching or any other
-	  means.
-
-    *  -  ``MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER``
-       -  Video pixel formatter. An entity capable of pixel formatting
-	  must have at least one sink pad and one source pad. Read
-	  pixel formatters read pixels from memory and perform a subset
-	  of unpacking, cropping, color keying, alpha multiplication
-	  and pixel encoding conversion. Write pixel formatters perform
-	  a subset of dithering, pixel encoding conversion and packing
-	  and write pixels to memory.
-
-    *  -  ``MEDIA_ENT_F_PROC_VIDEO_PIXEL_ENC_CONV``
-       -  Video pixel encoding converter. An entity capable of pixel
-	  encoding conversion must have at least one sink pad and one
-	  source pad, and convert the encoding of pixels received on
-	  its sink pad(s) to a different encoding output on its source
-	  pad(s). Pixel encoding conversion includes but isn't limited
-	  to RGB to/from HSV, RGB to/from YUV and CFA (Bayer) to RGB
-	  conversions.
-
-    *  -  ``MEDIA_ENT_F_PROC_VIDEO_LUT``
-       -  Video look-up table. An entity capable of video lookup table
-	  processing must have one sink pad and one source pad. It uses
-	  the values of the pixels received on its sink pad to look up
-	  entries in internal tables and output them on its source pad.
-	  The lookup processing can be performed on all components
-	  separately or combine them for multi-dimensional table
-	  lookups.
-
-    *  -  ``MEDIA_ENT_F_PROC_VIDEO_SCALER``
-       -  Video scaler. An entity capable of video scaling must have
-	  at least one sink pad and one source pad, and scale the
-	  video frame(s) received on its sink pad(s) to a different
-	  resolution output on its source pad(s). The range of
-	  supported scaling ratios is entity-specific and can differ
-	  between the horizontal and vertical directions (in particular
-	  scaling can be supported in one direction only). Binning and
-	  sub-sampling (occasionally also referred to as skipping) are
-	  considered as scaling.
-
-    *  -  ``MEDIA_ENT_F_PROC_VIDEO_STATISTICS``
-       -  Video statistics computation (histogram, 3A, etc.). An entity
-	  capable of statistics computation must have one sink pad and
-	  one source pad. It computes statistics over the frames
-	  received on its sink pad and outputs the statistics data on
-	  its source pad.
-
-    *  -  ``MEDIA_ENT_F_PROC_VIDEO_ENCODER``
-       -  Video (MPEG, HEVC, VPx, etc.) encoder. An entity capable of
-          compressing video frames. Must have one sink pad and at least
-	  one source pad.
-
-    *  -  ``MEDIA_ENT_F_PROC_VIDEO_DECODER``
-       -  Video (MPEG, HEVC, VPx, etc.) decoder. An entity capable of
-          decompressing a compressed video stream into uncompressed video
-	  frames. Must have one sink pad and at least one source pad.
-
-    *  -  ``MEDIA_ENT_F_VID_MUX``
-       - Video multiplexer. An entity capable of multiplexing must have at
-         least two sink pads and one source pad, and must pass the video
-         frame(s) received from the active sink pad to the source pad.
-
-    *  -  ``MEDIA_ENT_F_VID_IF_BRIDGE``
-       - Video interface bridge. A video interface bridge entity must have at
-         least one sink pad and at least one source pad. It receives video
-         frames on its sink pad from an input video bus of one type (HDMI, eDP,
-         MIPI CSI-2, etc.), and outputs them on its source pad to an output
-         video bus of another type (eDP, MIPI CSI-2, parallel, etc.).
-
-    *  -  ``MEDIA_ENT_F_DV_DECODER``
-       -  Digital video decoder. The basic function of the video decoder is
-	  to accept digital video from a wide variety of sources
-	  and output it in some digital video standard, with appropriate
-	  timing signals.
-
-    *  -  ``MEDIA_ENT_F_DV_ENCODER``
-       -  Digital video encoder. The basic function of the video encoder is
-	  to accept digital video from some digital video standard with
-	  appropriate timing signals (usually a parallel video bus with sync
-	  signals) and output this to a digital video output connector such
-	  as HDMI or DisplayPort.
-
-..  tabularcolumns:: |p{5.5cm}|p{12.0cm}|
-
-.. _media-entity-flag:
-.. _MEDIA-ENT-FL-DEFAULT:
-.. _MEDIA-ENT-FL-CONNECTOR:
-
-.. flat-table:: Media entity flags
-    :header-rows:  0
-    :stub-columns: 0
-
-    *  -  ``MEDIA_ENT_FL_DEFAULT``
-       -  Default entity for its type. Used to discover the default audio,
-	  VBI and video devices, the default camera sensor, etc.
-
-    *  -  ``MEDIA_ENT_FL_CONNECTOR``
-       -  The entity represents a connector.
-
-
-..  tabularcolumns:: |p{6.5cm}|p{6.0cm}|p{5.0cm}|
-
-.. _media-intf-type:
-.. _MEDIA-INTF-T-DVB-FE:
-.. _MEDIA-INTF-T-DVB-DEMUX:
-.. _MEDIA-INTF-T-DVB-DVR:
-.. _MEDIA-INTF-T-DVB-CA:
-.. _MEDIA-INTF-T-DVB-NET:
-.. _MEDIA-INTF-T-V4L-VIDEO:
-.. _MEDIA-INTF-T-V4L-VBI:
-.. _MEDIA-INTF-T-V4L-RADIO:
-.. _MEDIA-INTF-T-V4L-SUBDEV:
-.. _MEDIA-INTF-T-V4L-SWRADIO:
-.. _MEDIA-INTF-T-V4L-TOUCH:
-.. _MEDIA-INTF-T-ALSA-PCM-CAPTURE:
-.. _MEDIA-INTF-T-ALSA-PCM-PLAYBACK:
-.. _MEDIA-INTF-T-ALSA-CONTROL:
-.. _MEDIA-INTF-T-ALSA-COMPRESS:
-.. _MEDIA-INTF-T-ALSA-RAWMIDI:
-.. _MEDIA-INTF-T-ALSA-HWDEP:
-.. _MEDIA-INTF-T-ALSA-SEQUENCER:
-.. _MEDIA-INTF-T-ALSA-TIMER:
-
-.. flat-table:: Media interface types
-    :header-rows:  0
-    :stub-columns: 0
-
-    *  -  ``MEDIA_INTF_T_DVB_FE``
-       -  Device node interface for the Digital TV frontend
-       -  typically, /dev/dvb/adapter?/frontend?
-
-    *  -  ``MEDIA_INTF_T_DVB_DEMUX``
-       -  Device node interface for the Digital TV demux
-       -  typically, /dev/dvb/adapter?/demux?
-
-    *  -  ``MEDIA_INTF_T_DVB_DVR``
-       -  Device node interface for the Digital TV DVR
-       -  typically, /dev/dvb/adapter?/dvr?
-
-    *  -  ``MEDIA_INTF_T_DVB_CA``
-       -  Device node interface for the Digital TV Conditional Access
-       -  typically, /dev/dvb/adapter?/ca?
-
-    *  -  ``MEDIA_INTF_T_DVB_NET``
-       -  Device node interface for the Digital TV network control
-       -  typically, /dev/dvb/adapter?/net?
-
-    *  -  ``MEDIA_INTF_T_V4L_VIDEO``
-       -  Device node interface for video (V4L)
-       -  typically, /dev/video?
-
-    *  -  ``MEDIA_INTF_T_V4L_VBI``
-       -  Device node interface for VBI (V4L)
-       -  typically, /dev/vbi?
-
-    *  -  ``MEDIA_INTF_T_V4L_RADIO``
-       -  Device node interface for radio (V4L)
-       -  typically, /dev/radio?
-
-    *  -  ``MEDIA_INTF_T_V4L_SUBDEV``
-       -  Device node interface for a V4L subdevice
-       -  typically, /dev/v4l-subdev?
-
-    *  -  ``MEDIA_INTF_T_V4L_SWRADIO``
-       -  Device node interface for Software Defined Radio (V4L)
-       -  typically, /dev/swradio?
-
-    *  -  ``MEDIA_INTF_T_V4L_TOUCH``
-       -  Device node interface for Touch device (V4L)
-       -  typically, /dev/v4l-touch?
-
-    *  -  ``MEDIA_INTF_T_ALSA_PCM_CAPTURE``
-       -  Device node interface for ALSA PCM Capture
-       -  typically, /dev/snd/pcmC?D?c
-
-    *  -  ``MEDIA_INTF_T_ALSA_PCM_PLAYBACK``
-       -  Device node interface for ALSA PCM Playback
-       -  typically, /dev/snd/pcmC?D?p
-
-    *  -  ``MEDIA_INTF_T_ALSA_CONTROL``
-       -  Device node interface for ALSA Control
-       -  typically, /dev/snd/controlC?
-
-    *  -  ``MEDIA_INTF_T_ALSA_COMPRESS``
-       -  Device node interface for ALSA Compress
-       -  typically, /dev/snd/compr?
-
-    *  -  ``MEDIA_INTF_T_ALSA_RAWMIDI``
-       -  Device node interface for ALSA Raw MIDI
-       -  typically, /dev/snd/midi?
-
-    *  -  ``MEDIA_INTF_T_ALSA_HWDEP``
-       -  Device node interface for ALSA Hardware Dependent
-       -  typically, /dev/snd/hwC?D?
-
-    *  -  ``MEDIA_INTF_T_ALSA_SEQUENCER``
-       -  Device node interface for ALSA Sequencer
-       -  typically, /dev/snd/seq
-
-    *  -  ``MEDIA_INTF_T_ALSA_TIMER``
-       -  Device node interface for ALSA Timer
-       -  typically, /dev/snd/timer
-
-
-.. tabularcolumns:: |p{5.5cm}|p{12.0cm}|
-
-.. _media-pad-flag:
-.. _MEDIA-PAD-FL-SINK:
-.. _MEDIA-PAD-FL-SOURCE:
-.. _MEDIA-PAD-FL-MUST-CONNECT:
-
-.. flat-table:: Media pad flags
-    :header-rows:  0
-    :stub-columns: 0
-
-    *  -  ``MEDIA_PAD_FL_SINK``
-       -  Input pad, relative to the entity. Input pads sink data and are
-	  targets of links.
-
-    *  -  ``MEDIA_PAD_FL_SOURCE``
-       -  Output pad, relative to the entity. Output pads source data and
-	  are origins of links.
-
-    *  -  ``MEDIA_PAD_FL_MUST_CONNECT``
-       -  If this flag is set and the pad is linked to any other pad, then
-	  at least one of those links must be enabled for the entity to be
-	  able to stream. There could be temporary reasons (e.g. device
-	  configuration dependent) for the pad to need enabled links even
-	  when this flag isn't set; the absence of the flag doesn't imply
-	  there is none.
-
-
-One and only one of ``MEDIA_PAD_FL_SINK`` and ``MEDIA_PAD_FL_SOURCE``
-must be set for every pad.
-
-.. tabularcolumns:: |p{5.5cm}|p{12.0cm}|
-
-.. _media-link-flag:
-.. _MEDIA-LNK-FL-ENABLED:
-.. _MEDIA-LNK-FL-IMMUTABLE:
-.. _MEDIA-LNK-FL-DYNAMIC:
-.. _MEDIA-LNK-FL-LINK-TYPE:
-
-.. flat-table:: Media link flags
-    :header-rows:  0
-    :stub-columns: 0
-
-    *  -  ``MEDIA_LNK_FL_ENABLED``
-       -  The link is enabled and can be used to transfer media data. When
-	  two or more links target a sink pad, only one of them can be
-	  enabled at a time.
-
-    *  -  ``MEDIA_LNK_FL_IMMUTABLE``
-       -  The link enabled state can't be modified at runtime. An immutable
-	  link is always enabled.
-
-    *  -  ``MEDIA_LNK_FL_DYNAMIC``
-       -  The link enabled state can be modified during streaming. This flag
-	  is set by drivers and is read-only for applications.
-
-    *  -  ``MEDIA_LNK_FL_LINK_TYPE``
-       -  This is a bitmask that defines the type of the link. Currently,
-	  two types of links are supported:
-
-	  .. _MEDIA-LNK-FL-DATA-LINK:
-
-	  ``MEDIA_LNK_FL_DATA_LINK`` if the link is between two pads
-
-	  .. _MEDIA-LNK-FL-INTERFACE-LINK:
-
-	  ``MEDIA_LNK_FL_INTERFACE_LINK`` if the link is between an
-	  interface and an entity
diff --git a/Documentation/media/uapi/mediactl/request-api.rst b/Documentation/media/uapi/mediactl/request-api.rst
deleted file mode 100644
index 01abe8103bdd..000000000000
--- a/Documentation/media/uapi/mediactl/request-api.rst
+++ /dev/null
@@ -1,276 +0,0 @@
-.. This file is dual-licensed: you can use it either under the terms
-.. of the GPL 2.0 or the GFDL 1.1+ license, at your option. Note that this
-.. dual licensing only applies to this file, and not this project as a
-.. whole.
-..
-.. a) This file is free software; you can redistribute it and/or
-..    modify it under the terms of the GNU General Public License as
-..    published by the Free Software Foundation version 2 of
-..    the License.
-..
-..    This file is distributed in the hope that it will be useful,
-..    but WITHOUT ANY WARRANTY; without even the implied warranty of
-..    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-..    GNU General Public License for more details.
-..
-.. Or, alternatively,
-..
-.. b) Permission is granted to copy, distribute and/or modify this
-..    document under the terms of the GNU Free Documentation License,
-..    Version 1.1 or any later version published by the Free Software
-..    Foundation, with no Invariant Sections, no Front-Cover Texts
-..    and no Back-Cover Texts. A copy of the license is included at
-..    Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _media-request-api:
-
-Request API
-===========
-
-The Request API has been designed to allow V4L2 to deal with requirements of
-modern devices (stateless codecs, complex camera pipelines, ...) and APIs
-(Android Codec v2). One such requirement is the ability for devices belonging to
-the same pipeline to reconfigure and collaborate closely on a per-frame basis.
-Another is support of stateless codecs, which require controls to be applied
-to specific frames (aka 'per-frame controls') in order to be used efficiently.
-
-While the initial use-case was V4L2, it can be extended to other subsystems
-as well, as long as they use the media controller.
-
-Supporting these features without the Request API is not always possible and if
-it is, it is terribly inefficient: user-space would have to flush all activity
-on the media pipeline, reconfigure it for the next frame, queue the buffers to
-be processed with that configuration, and wait until they are all available for
-dequeuing before considering the next frame. This defeats the purpose of having
-buffer queues since in practice only one buffer would be queued at a time.
-
-The Request API allows a specific configuration of the pipeline (media
-controller topology + configuration for each media entity) to be associated with
-specific buffers. This allows user-space to schedule several tasks ("requests")
-with different configurations in advance, knowing that the configuration will be
-applied when needed to get the expected result. Configuration values at the time
-of request completion are also available for reading.
-
-General Usage
--------------
-
-The Request API extends the Media Controller API and cooperates with
-subsystem-specific APIs to support request usage. At the Media Controller
-level, requests are allocated from the supporting Media Controller device
-node. Their life cycle is then managed through the request file descriptors in
-an opaque way. Configuration data, buffer handles and processing results
-stored in requests are accessed through subsystem-specific APIs extended for
-request support, such as V4L2 APIs that take an explicit ``request_fd``
-parameter.
-
-Request Allocation
-------------------
-
-User-space allocates requests using :ref:`MEDIA_IOC_REQUEST_ALLOC`
-for the media device node. This returns a file descriptor representing the
-request. Typically, several such requests will be allocated.
-
-Request Preparation
--------------------
-
-Standard V4L2 ioctls can then receive a request file descriptor to express the
-fact that the ioctl is part of said request, and is not to be applied
-immediately. See :ref:`MEDIA_IOC_REQUEST_ALLOC` for a list of ioctls that
-support this. Configurations set with a ``request_fd`` parameter are stored
-instead of being immediately applied, and buffers queued to a request do not
-enter the regular buffer queue until the request itself is queued.
-
-Request Submission
-------------------
-
-Once the configuration and buffers of the request are specified, it can be
-queued by calling :ref:`MEDIA_REQUEST_IOC_QUEUE` on the request file descriptor.
-A request must contain at least one buffer, otherwise ``ENOENT`` is returned.
-A queued request cannot be modified anymore.
-
-.. caution::
-   For :ref:`memory-to-memory devices <mem2mem>` you can use requests only for
-   output buffers, not for capture buffers. Attempting to add a capture buffer
-   to a request will result in an ``EBADR`` error.
-
-If the request contains configurations for multiple entities, individual drivers
-may synchronize so the requested pipeline's topology is applied before the
-buffers are processed. Media controller drivers do a best effort implementation
-since perfect atomicity may not be possible due to hardware limitations.
-
-.. caution::
-
-   It is not allowed to mix queuing requests with directly queuing buffers:
-   whichever method is used first locks this in place until
-   :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` is called or the device is
-   :ref:`closed <func-close>`. Attempts to directly queue a buffer when earlier
-   a buffer was queued via a request or vice versa will result in an ``EBUSY``
-   error.
-
-Controls can still be set without a request and are applied immediately,
-regardless of whether a request is in use or not.
-
-.. caution::
-
-   Setting the same control through a request and also directly can lead to
-   undefined behavior!
-
-User-space can :ref:`poll() <request-func-poll>` a request file descriptor in
-order to wait until the request completes. A request is considered complete
-once all its associated buffers are available for dequeuing and all the
-associated controls have been updated with the values at the time of completion.
-Note that user-space does not need to wait for the request to complete to
-dequeue its buffers: buffers that are available halfway through a request can
-be dequeued independently of the request's state.
-
-A completed request contains the state of the device after the request was
-executed. User-space can query that state by calling
-:ref:`ioctl VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` with the request file
-descriptor. Calling :ref:`ioctl VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` for a
-request that has been queued but not yet completed will return ``EBUSY``
-since the control values might be changed at any time by the driver while the
-request is in flight.
-
-.. _media-request-life-time:
-
-Recycling and Destruction
--------------------------
-
-Finally, a completed request can either be discarded or be reused. Calling
-:ref:`close() <request-func-close>` on a request file descriptor will make
-that file descriptor unusable and the request will be freed once it is no
-longer in use by the kernel. That is, if the request is queued and then the
-file descriptor is closed, then it won't be freed until the driver completed
-the request.
-
-The :ref:`MEDIA_REQUEST_IOC_REINIT` will clear a request's state and make it
-available again. No state is retained by this operation: the request is as
-if it had just been allocated.
-
-Example for a Codec Device
---------------------------
-
-For use-cases such as :ref:`codecs <mem2mem>`, the request API can be used
-to associate specific controls to
-be applied by the driver for the OUTPUT buffer, allowing user-space
-to queue many such buffers in advance. It can also take advantage of requests'
-ability to capture the state of controls when the request completes to read back
-information that may be subject to change.
-
-Put into code, after obtaining a request, user-space can assign controls and one
-OUTPUT buffer to it:
-
-.. code-block:: c
-
-	struct v4l2_buffer buf;
-	struct v4l2_ext_controls ctrls;
-	int req_fd;
-	...
-	if (ioctl(media_fd, MEDIA_IOC_REQUEST_ALLOC, &req_fd))
-		return errno;
-	...
-	ctrls.which = V4L2_CTRL_WHICH_REQUEST_VAL;
-	ctrls.request_fd = req_fd;
-	if (ioctl(codec_fd, VIDIOC_S_EXT_CTRLS, &ctrls))
-		return errno;
-	...
-	buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
-	buf.flags |= V4L2_BUF_FLAG_REQUEST_FD;
-	buf.request_fd = req_fd;
-	if (ioctl(codec_fd, VIDIOC_QBUF, &buf))
-		return errno;
-
-Note that it is not allowed to use the Request API for CAPTURE buffers
-since there are no per-frame settings to report there.
-
-Once the request is fully prepared, it can be queued to the driver:
-
-.. code-block:: c
-
-	if (ioctl(req_fd, MEDIA_REQUEST_IOC_QUEUE))
-		return errno;
-
-User-space can then either wait for the request to complete by calling poll() on
-its file descriptor, or start dequeuing CAPTURE buffers. Most likely, it will
-want to get CAPTURE buffers as soon as possible and this can be done using a
-regular :ref:`VIDIOC_DQBUF <VIDIOC_QBUF>`:
-
-.. code-block:: c
-
-	struct v4l2_buffer buf;
-
-	memset(&buf, 0, sizeof(buf));
-	buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	if (ioctl(codec_fd, VIDIOC_DQBUF, &buf))
-		return errno;
-
-Note that this example assumes for simplicity that for every OUTPUT buffer
-there will be one CAPTURE buffer, but this does not have to be the case.
-
-We can then, after ensuring that the request is completed via polling the
-request file descriptor, query control values at the time of its completion via
-a call to :ref:`VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>`.
-This is particularly useful for volatile controls for which we want to
-query values as soon as the capture buffer is produced.
-
-.. code-block:: c
-
-	struct pollfd pfd = { .events = POLLPRI, .fd = req_fd };
-	poll(&pfd, 1, -1);
-	...
-	ctrls.which = V4L2_CTRL_WHICH_REQUEST_VAL;
-	ctrls.request_fd = req_fd;
-	if (ioctl(codec_fd, VIDIOC_G_EXT_CTRLS, &ctrls))
-		return errno;
-
-Once we don't need the request anymore, we can either recycle it for reuse with
-:ref:`MEDIA_REQUEST_IOC_REINIT`...
-
-.. code-block:: c
-
-	if (ioctl(req_fd, MEDIA_REQUEST_IOC_REINIT))
-		return errno;
-
-... or close its file descriptor to completely dispose of it.
-
-.. code-block:: c
-
-	close(req_fd);
-
-Example for a Simple Capture Device
------------------------------------
-
-With a simple capture device, requests can be used to specify controls to apply
-for a given CAPTURE buffer.
-
-.. code-block:: c
-
-	struct v4l2_buffer buf;
-	struct v4l2_ext_controls ctrls;
-	int req_fd;
-	...
-	if (ioctl(media_fd, MEDIA_IOC_REQUEST_ALLOC, &req_fd))
-		return errno;
-	...
-	ctrls.which = V4L2_CTRL_WHICH_REQUEST_VAL;
-	ctrls.request_fd = req_fd;
-	if (ioctl(camera_fd, VIDIOC_S_EXT_CTRLS, &ctrls))
-		return errno;
-	...
-	buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	buf.flags |= V4L2_BUF_FLAG_REQUEST_FD;
-	buf.request_fd = req_fd;
-	if (ioctl(camera_fd, VIDIOC_QBUF, &buf))
-		return errno;
-
-Once the request is fully prepared, it can be queued to the driver:
-
-.. code-block:: c
-
-	if (ioctl(req_fd, MEDIA_REQUEST_IOC_QUEUE))
-		return errno;
-
-User-space can then dequeue buffers, wait for the request completion, query
-controls and recycle the request as in the M2M example above.
diff --git a/Documentation/media/uapi/mediactl/request-func-close.rst b/Documentation/media/uapi/mediactl/request-func-close.rst
deleted file mode 100644
index 2cff7770558e..000000000000
--- a/Documentation/media/uapi/mediactl/request-func-close.rst
+++ /dev/null
@@ -1,73 +0,0 @@
-.. This file is dual-licensed: you can use it either under the terms
-.. of the GPL 2.0 or the GFDL 1.1+ license, at your option. Note that this
-.. dual licensing only applies to this file, and not this project as a
-.. whole.
-..
-.. a) This file is free software; you can redistribute it and/or
-..    modify it under the terms of the GNU General Public License as
-..    published by the Free Software Foundation version 2 of
-..    the License.
-..
-..    This file is distributed in the hope that it will be useful,
-..    but WITHOUT ANY WARRANTY; without even the implied warranty of
-..    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-..    GNU General Public License for more details.
-..
-.. Or, alternatively,
-..
-.. b) Permission is granted to copy, distribute and/or modify this
-..    document under the terms of the GNU Free Documentation License,
-..    Version 1.1 or any later version published by the Free Software
-..    Foundation, with no Invariant Sections, no Front-Cover Texts
-..    and no Back-Cover Texts. A copy of the license is included at
-..    Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _request-func-close:
-
-***************
-request close()
-***************
-
-Name
-====
-
-request-close - Close a request file descriptor
-
-
-Synopsis
-========
-
-.. code-block:: c
-
-    #include <unistd.h>
-
-
-.. c:function:: int close( int fd )
-    :name: req-close
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`MEDIA_IOC_REQUEST_ALLOC`.
-
-
-Description
-===========
-
-Closes the request file descriptor. Resources associated with the request
-are freed once all file descriptors associated with the request are closed
-and the driver has completed the request.
-See :ref:`here <media-request-life-time>` for more information.
-
-
-Return Value
-============
-
-:ref:`close() <request-func-close>` returns 0 on success. On error, -1 is
-returned, and ``errno`` is set appropriately. Possible error codes are:
-
-EBADF
-    ``fd`` is not a valid open file descriptor.
diff --git a/Documentation/media/uapi/mediactl/request-func-ioctl.rst b/Documentation/media/uapi/mediactl/request-func-ioctl.rst
deleted file mode 100644
index de0781c61873..000000000000
--- a/Documentation/media/uapi/mediactl/request-func-ioctl.rst
+++ /dev/null
@@ -1,91 +0,0 @@
-.. This file is dual-licensed: you can use it either under the terms
-.. of the GPL 2.0 or the GFDL 1.1+ license, at your option. Note that this
-.. dual licensing only applies to this file, and not this project as a
-.. whole.
-..
-.. a) This file is free software; you can redistribute it and/or
-..    modify it under the terms of the GNU General Public License as
-..    published by the Free Software Foundation version 2 of
-..    the License.
-..
-..    This file is distributed in the hope that it will be useful,
-..    but WITHOUT ANY WARRANTY; without even the implied warranty of
-..    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-..    GNU General Public License for more details.
-..
-.. Or, alternatively,
-..
-.. b) Permission is granted to copy, distribute and/or modify this
-..    document under the terms of the GNU Free Documentation License,
-..    Version 1.1 or any later version published by the Free Software
-..    Foundation, with no Invariant Sections, no Front-Cover Texts
-..    and no Back-Cover Texts. A copy of the license is included at
-..    Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _request-func-ioctl:
-
-***************
-request ioctl()
-***************
-
-Name
-====
-
-request-ioctl - Control a request file descriptor
-
-
-Synopsis
-========
-
-.. code-block:: c
-
-    #include <sys/ioctl.h>
-
-
-.. c:function:: int ioctl( int fd, int cmd, void *argp )
-    :name: req-ioctl
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`MEDIA_IOC_REQUEST_ALLOC`.
-
-``cmd``
-    The request ioctl command code as defined in the media.h header file, for
-    example :ref:`MEDIA_REQUEST_IOC_QUEUE`.
-
-``argp``
-    Pointer to a request-specific structure.
-
-
-Description
-===========
-
-The :ref:`ioctl() <request-func-ioctl>` function manipulates request
-parameters. The argument ``fd`` must be an open file descriptor.
-
-The ioctl ``cmd`` code specifies the request function to be called. It
-has encoded in it whether the argument is an input, output or read/write
-parameter, and the size of the argument ``argp`` in bytes.
-
-Macros and structures definitions specifying request ioctl commands and
-their parameters are located in the media.h header file. All request ioctl
-commands, their respective function and parameters are specified in
-:ref:`media-user-func`.
-
-
-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.
-
-Command-specific error codes are listed in the individual command
-descriptions.
-
-When an ioctl that takes an output or read/write parameter fails, the
-parameter remains unmodified.
diff --git a/Documentation/media/uapi/mediactl/request-func-poll.rst b/Documentation/media/uapi/mediactl/request-func-poll.rst
deleted file mode 100644
index ebaf33e21873..000000000000
--- a/Documentation/media/uapi/mediactl/request-func-poll.rst
+++ /dev/null
@@ -1,101 +0,0 @@
-.. This file is dual-licensed: you can use it either under the terms
-.. of the GPL 2.0 or the GFDL 1.1+ license, at your option. Note that this
-.. dual licensing only applies to this file, and not this project as a
-.. whole.
-..
-.. a) This file is free software; you can redistribute it and/or
-..    modify it under the terms of the GNU General Public License as
-..    published by the Free Software Foundation version 2 of
-..    the License.
-..
-..    This file is distributed in the hope that it will be useful,
-..    but WITHOUT ANY WARRANTY; without even the implied warranty of
-..    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-..    GNU General Public License for more details.
-..
-.. Or, alternatively,
-..
-.. b) Permission is granted to copy, distribute and/or modify this
-..    document under the terms of the GNU Free Documentation License,
-..    Version 1.1 or any later version published by the Free Software
-..    Foundation, with no Invariant Sections, no Front-Cover Texts
-..    and no Back-Cover Texts. A copy of the license is included at
-..    Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _request-func-poll:
-
-**************
-request poll()
-**************
-
-Name
-====
-
-request-poll - Wait for some event on a file descriptor
-
-
-Synopsis
-========
-
-.. code-block:: c
-
-    #include <sys/poll.h>
-
-
-.. c:function:: int poll( struct pollfd *ufds, unsigned int nfds, int timeout )
-   :name: request-poll
-
-Arguments
-=========
-
-``ufds``
-   List of file descriptor events to be watched
-
-``nfds``
-   Number of file descriptor events at the \*ufds array
-
-``timeout``
-   Timeout to wait for events
-
-
-Description
-===========
-
-With the :c:func:`poll() <request-func-poll>` function applications can wait
-for a request to complete.
-
-On success :c:func:`poll() <request-func-poll>` returns the number of file
-descriptors that have been selected (that is, file descriptors for which the
-``revents`` field of the respective struct :c:type:`pollfd`
-is non-zero). Request file descriptor set the ``POLLPRI`` flag in ``revents``
-when the request was completed.  When the function times out it returns
-a value of zero, on failure it returns -1 and the ``errno`` variable is
-set appropriately.
-
-Attempting to poll for a request that is not yet queued will
-set the ``POLLERR`` flag in ``revents``.
-
-
-Return Value
-============
-
-On success, :c:func:`poll() <request-func-poll>` returns the number of
-structures which have non-zero ``revents`` fields, or zero if the call
-timed out. On error -1 is returned, and the ``errno`` variable is set
-appropriately:
-
-``EBADF``
-    One or more of the ``ufds`` members specify an invalid file
-    descriptor.
-
-``EFAULT``
-    ``ufds`` references an inaccessible memory area.
-
-``EINTR``
-    The call was interrupted by a signal.
-
-``EINVAL``
-    The ``nfds`` value exceeds the ``RLIMIT_NOFILE`` value. Use
-    ``getrlimit()`` to obtain this value.
diff --git a/Documentation/media/uapi/rc/keytable.c.rst b/Documentation/media/uapi/rc/keytable.c.rst
deleted file mode 100644
index 46f98569e999..000000000000
--- a/Documentation/media/uapi/rc/keytable.c.rst
+++ /dev/null
@@ -1,183 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-file: uapi/v4l/keytable.c
-=========================
-
-.. code-block:: c
-
-    /* keytable.c - This program allows checking/replacing keys at IR
-
-       Copyright (C) 2006-2009 Mauro Carvalho Chehab <mchehab@kernel.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 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 <ctype.h>
-    #include <errno.h>
-    #include <fcntl.h>
-    #include <stdio.h>
-    #include <stdlib.h>
-    #include <string.h>
-    #include <linux/input.h>
-    #include <sys/ioctl.h>
-
-    #include "parse.h"
-
-    void prtcode (int *codes)
-    {
-	    struct parse_key *p;
-
-	    for (p=keynames;p->name!=NULL;p++) {
-		    if (p->value == (unsigned)codes[1]) {
-			    printf("scancode 0x%04x = %s (0x%02x)\\n", codes[0], p->name, codes[1]);
-			    return;
-		    }
-	    }
-
-	    if (isprint (codes[1]))
-		    printf("scancode %d = '%c' (0x%02x)\\n", codes[0], codes[1], codes[1]);
-	    else
-		    printf("scancode %d = 0x%02x\\n", codes[0], codes[1]);
-    }
-
-    int parse_code(char *string)
-    {
-	    struct parse_key *p;
-
-	    for (p=keynames;p->name!=NULL;p++) {
-		    if (!strcasecmp(p->name, string)) {
-			    return p->value;
-		    }
-	    }
-	    return -1;
-    }
-
-    int main (int argc, char *argv[])
-    {
-	    int fd;
-	    unsigned int i, j;
-	    int codes[2];
-
-	    if (argc<2 || argc>4) {
-		    printf ("usage: %s <device> to get table; or\\n"
-			    "       %s <device> <scancode> <keycode>\\n"
-			    "       %s <device> <keycode_file>n",*argv,*argv,*argv);
-		    return -1;
-	    }
-
-	    if ((fd = open(argv[1], O_RDONLY)) < 0) {
-		    perror("Couldn't open input device");
-		    return(-1);
-	    }
-
-	    if (argc==4) {
-		    int value;
-
-		    value=parse_code(argv[3]);
-
-		    if (value==-1) {
-			    value = strtol(argv[3], NULL, 0);
-			    if (errno)
-				    perror("value");
-		    }
-
-		    codes [0] = (unsigned) strtol(argv[2], NULL, 0);
-		    codes [1] = (unsigned) value;
-
-		    if(ioctl(fd, EVIOCSKEYCODE, codes))
-			    perror ("EVIOCSKEYCODE");
-
-		    if(ioctl(fd, EVIOCGKEYCODE, codes)==0)
-			    prtcode(codes);
-		    return 0;
-	    }
-
-	    if (argc==3) {
-		    FILE *fin;
-		    int value;
-		    char *scancode, *keycode, s[2048];
-
-		    fin=fopen(argv[2],"r");
-		    if (fin==NULL) {
-			    perror ("opening keycode file");
-			    return -1;
-		    }
-
-		    /* Clears old table */
-		    for (j = 0; j < 256; j++) {
-			    for (i = 0; i < 256; i++) {
-				    codes[0] = (j << 8) | i;
-				    codes[1] = KEY_RESERVED;
-				    ioctl(fd, EVIOCSKEYCODE, codes);
-			    }
-		    }
-
-		    while (fgets(s,sizeof(s),fin)) {
-			    scancode=strtok(s,"\\n\\t =:");
-			    if (!scancode) {
-				    perror ("parsing input file scancode");
-				    return -1;
-			    }
-			    if (!strcasecmp(scancode, "scancode")) {
-				    scancode = strtok(NULL,"\\n\\t =:");
-				    if (!scancode) {
-					    perror ("parsing input file scancode");
-					    return -1;
-				    }
-			    }
-
-			    keycode=strtok(NULL,"\\n\\t =:(");
-			    if (!keycode) {
-				    perror ("parsing input file keycode");
-				    return -1;
-			    }
-
-			    // printf ("parsing %s=%s:", scancode, keycode);
-			    value=parse_code(keycode);
-			    // printf ("\\tvalue=%d\\n",value);
-
-			    if (value==-1) {
-				    value = strtol(keycode, NULL, 0);
-				    if (errno)
-					    perror("value");
-			    }
-
-			    codes [0] = (unsigned) strtol(scancode, NULL, 0);
-			    codes [1] = (unsigned) value;
-
-			    // printf("\\t%04x=%04x\\n",codes[0], codes[1]);
-			    if(ioctl(fd, EVIOCSKEYCODE, codes)) {
-				    fprintf(stderr, "Setting scancode 0x%04x with 0x%04x via ",codes[0], codes[1]);
-				    perror ("EVIOCSKEYCODE");
-			    }
-
-			    if(ioctl(fd, EVIOCGKEYCODE, codes)==0)
-				    prtcode(codes);
-		    }
-		    return 0;
-	    }
-
-	    /* Get scancode table */
-	    for (j = 0; j < 256; j++) {
-		    for (i = 0; i < 256; i++) {
-			    codes[0] = (j << 8) | i;
-			    if (!ioctl(fd, EVIOCGKEYCODE, codes) && codes[1] != KEY_RESERVED)
-				    prtcode(codes);
-		    }
-	    }
-	    return 0;
-    }
diff --git a/Documentation/media/uapi/rc/lirc-dev-intro.rst b/Documentation/media/uapi/rc/lirc-dev-intro.rst
deleted file mode 100644
index b68c01693939..000000000000
--- a/Documentation/media/uapi/rc/lirc-dev-intro.rst
+++ /dev/null
@@ -1,171 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _lirc_dev_intro:
-
-************
-Introduction
-************
-
-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.
-
-It is also possible to attach a BPF program to a LIRC device for decoding
-raw IR into scancodes.
-
-Example dmesg output upon a driver registering w/LIRC:
-
-.. code-block:: none
-
-    $ dmesg |grep lirc_dev
-    rc rc0: lirc_dev: driver mceusb registered at minor = 0, raw IR receiver, raw IR transmitter
-
-What you should see for a chardev:
-
-.. code-block:: none
-
-    $ ls -l /dev/lirc*
-    crw-rw---- 1 root root 248, 0 Jul 2 22:20 /dev/lirc0
-
-Note that the package `v4l-utils <https://git.linuxtv.org/v4l-utils.git/>`_
-contains tools for working with LIRC devices:
-
- - ir-ctl: can receive raw IR and transmit IR, as well as query LIRC
-   device features.
-
- - ir-keytable: can load keymaps; allows you to set IR kernel protocols; load
-   BPF IR decoders and test IR decoding. Some BPF IR decoders are also
-   provided.
-
-.. _lirc_modes:
-
-**********
-LIRC modes
-**********
-
-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 to the :ref:`IR protocol <Remote_controllers_Protocols>`, and all other
-    members set to 0. Write this struct to the lirc device.
-
-    For receiving, you read ``struct lirc_scancode`` from the LIRC device.
-    The ``scancode`` field is set to the received scancode and the
-    :ref:`IR protocol <Remote_controllers_Protocols>` is set in
-    :c:type:`rc_proto`. If the scancode maps to a valid key code, this is set
-    in the ``keycode`` field, else it is set to ``KEY_RESERVED``.
-
-    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``
-
-    The driver returns a sequence of pulse and space codes to userspace,
-    as a series of u32 values.
-
-    This mode is used only for IR receive.
-
-    The upper 8 bits determine the packet type, and the lower 24 bits
-    the payload. Use ``LIRC_VALUE()`` macro to get the payload, and
-    the macro ``LIRC_MODE2()`` will give you the type, which
-    is one of:
-
-    ``LIRC_MODE2_PULSE``
-
-        Signifies the presence of IR in microseconds.
-
-    ``LIRC_MODE2_SPACE``
-
-        Signifies absence of IR in microseconds.
-
-    ``LIRC_MODE2_FREQUENCY``
-
-        If measurement of the carrier frequency was enabled with
-        :ref:`lirc_set_measure_carrier_mode` then this packet gives you
-        the carrier frequency in Hertz.
-
-    ``LIRC_MODE2_TIMEOUT``
-
-        If timeout reports are enabled with
-        :ref:`lirc_set_rec_timeout_reports`, when the timeout set with
-        :ref:`lirc_set_rec_timeout` expires due to no IR being detected,
-        this packet will be sent, with the number of microseconds with
-        no IR.
-
-.. _lirc-mode-pulse:
-
-``LIRC_MODE_PULSE``
-
-    In pulse mode, a sequence of pulse/space integer values are written to the
-    lirc device using :ref:`lirc-write`.
-
-    The values are alternating pulse and space lengths, in microseconds. The
-    first and last entry must be a pulse, so there must be an odd number
-    of entries.
-
-    This mode is used only for IR send.
-
-********************
-BPF based IR decoder
-********************
-
-The kernel has support for decoding the most common
-:ref:`IR protocols <Remote_controllers_Protocols>`, but there
-are many protocols which are not supported. To support these, it is possible
-to load an BPF program which does the decoding. This can only be done on
-LIRC devices which support reading raw IR.
-
-First, using the `bpf(2)`_ syscall with the ``BPF_LOAD_PROG`` argument,
-program must be loaded of type ``BPF_PROG_TYPE_LIRC_MODE2``. Once attached
-to the LIRC device, this program will be called for each pulse, space or
-timeout event on the LIRC device. The context for the BPF program is a
-pointer to a unsigned int, which is a :ref:`LIRC_MODE_MODE2 <lirc-mode-mode2>`
-value. When the program has decoded the scancode, it can be submitted using
-the BPF functions ``bpf_rc_keydown()`` or ``bpf_rc_repeat()``. Mouse or pointer
-movements can be reported using ``bpf_rc_pointer_rel()``.
-
-Once you have the file descriptor for the ``BPF_PROG_TYPE_LIRC_MODE2`` BPF
-program, it can be attached to the LIRC device using the `bpf(2)`_ syscall.
-The target must be the file descriptor for the LIRC device, and the
-attach type must be ``BPF_LIRC_MODE2``. No more than 64 BPF programs can be
-attached to a single LIRC device at a time.
-
-.. _bpf(2): http://man7.org/linux/man-pages/man2/bpf.2.html
diff --git a/Documentation/media/uapi/rc/lirc-dev.rst b/Documentation/media/uapi/rc/lirc-dev.rst
deleted file mode 100644
index 7058e0b2296a..000000000000
--- a/Documentation/media/uapi/rc/lirc-dev.rst
+++ /dev/null
@@ -1,21 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _lirc_dev:
-
-LIRC Device Interface
-=====================
-
-
-.. toctree::
-    :maxdepth: 1
-
-    lirc-dev-intro
-    lirc-func
-    lirc-header
diff --git a/Documentation/media/uapi/rc/lirc-func.rst b/Documentation/media/uapi/rc/lirc-func.rst
deleted file mode 100644
index 25058369f724..000000000000
--- a/Documentation/media/uapi/rc/lirc-func.rst
+++ /dev/null
@@ -1,34 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _lirc_func:
-
-LIRC Function Reference
-=======================
-
-
-.. toctree::
-    :maxdepth: 1
-
-    lirc-read
-    lirc-write
-    lirc-get-features
-    lirc-get-send-mode
-    lirc-get-rec-mode
-    lirc-get-rec-resolution
-    lirc-set-send-duty-cycle
-    lirc-get-timeout
-    lirc-set-rec-timeout
-    lirc-set-rec-carrier
-    lirc-set-rec-carrier-range
-    lirc-set-send-carrier
-    lirc-set-transmitter-mask
-    lirc-set-rec-timeout-reports
-    lirc-set-measure-carrier-mode
-    lirc-set-wideband-receiver
diff --git a/Documentation/media/uapi/rc/lirc-get-features.rst b/Documentation/media/uapi/rc/lirc-get-features.rst
deleted file mode 100644
index 1d590df8164a..000000000000
--- a/Documentation/media/uapi/rc/lirc-get-features.rst
+++ /dev/null
@@ -1,200 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _lirc_get_features:
-
-***********************
-ioctl LIRC_GET_FEATURES
-***********************
-
-Name
-====
-
-LIRC_GET_FEATURES - Get the underlying hardware device's features
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, LIRC_GET_FEATURES, __u32 *features)
-    :name: LIRC_GET_FEATURES
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by open().
-
-``features``
-    Bitmask with the LIRC features.
-
-
-Description
-===========
-
-
-Get the underlying hardware device's features. If a driver does not
-announce support of certain features, calling of the corresponding ioctls
-is undefined.
-
-LIRC features
-=============
-
-.. _LIRC-CAN-REC-RAW:
-
-``LIRC_CAN_REC_RAW``
-
-    Unused. Kept just to avoid breaking uAPI.
-
-.. _LIRC-CAN-REC-PULSE:
-
-``LIRC_CAN_REC_PULSE``
-
-    Unused. Kept just to avoid breaking uAPI.
-    :ref:`LIRC_MODE_PULSE <lirc-mode-pulse>` can only be used for transmitting.
-
-.. _LIRC-CAN-REC-MODE2:
-
-``LIRC_CAN_REC_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``
-
-    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:
-
-``LIRC_CAN_SET_SEND_CARRIER``
-
-    The driver supports changing the modulation frequency via
-    :ref:`ioctl LIRC_SET_SEND_CARRIER <LIRC_SET_SEND_CARRIER>`.
-
-.. _LIRC-CAN-SET-SEND-DUTY-CYCLE:
-
-``LIRC_CAN_SET_SEND_DUTY_CYCLE``
-
-    The driver supports changing the duty cycle using
-    :ref:`ioctl LIRC_SET_SEND_DUTY_CYCLE <LIRC_SET_SEND_DUTY_CYCLE>`.
-
-.. _LIRC-CAN-SET-TRANSMITTER-MASK:
-
-``LIRC_CAN_SET_TRANSMITTER_MASK``
-
-    The driver supports changing the active transmitter(s) using
-    :ref:`ioctl LIRC_SET_TRANSMITTER_MASK <LIRC_SET_TRANSMITTER_MASK>`.
-
-.. _LIRC-CAN-SET-REC-CARRIER:
-
-``LIRC_CAN_SET_REC_CARRIER``
-
-    The driver supports setting the receive carrier frequency using
-    :ref:`ioctl LIRC_SET_REC_CARRIER <LIRC_SET_REC_CARRIER>`.
-
-.. _LIRC-CAN-SET-REC-DUTY-CYCLE-RANGE:
-
-``LIRC_CAN_SET_REC_DUTY_CYCLE_RANGE``
-
-    Unused. Kept just to avoid breaking uAPI.
-
-.. _LIRC-CAN-SET-REC-CARRIER-RANGE:
-
-``LIRC_CAN_SET_REC_CARRIER_RANGE``
-
-    The driver supports
-    :ref:`ioctl LIRC_SET_REC_CARRIER_RANGE <LIRC_SET_REC_CARRIER_RANGE>`.
-
-.. _LIRC-CAN-GET-REC-RESOLUTION:
-
-``LIRC_CAN_GET_REC_RESOLUTION``
-
-    The driver supports
-    :ref:`ioctl LIRC_GET_REC_RESOLUTION <LIRC_GET_REC_RESOLUTION>`.
-
-.. _LIRC-CAN-SET-REC-TIMEOUT:
-
-``LIRC_CAN_SET_REC_TIMEOUT``
-
-    The driver supports
-    :ref:`ioctl LIRC_SET_REC_TIMEOUT <LIRC_SET_REC_TIMEOUT>`.
-
-.. _LIRC-CAN-SET-REC-FILTER:
-
-``LIRC_CAN_SET_REC_FILTER``
-
-    Unused. Kept just to avoid breaking uAPI.
-
-.. _LIRC-CAN-MEASURE-CARRIER:
-
-``LIRC_CAN_MEASURE_CARRIER``
-
-    The driver supports measuring of the modulation frequency using
-    :ref:`ioctl LIRC_SET_MEASURE_CARRIER_MODE <LIRC_SET_MEASURE_CARRIER_MODE>`.
-
-.. _LIRC-CAN-USE-WIDEBAND-RECEIVER:
-
-``LIRC_CAN_USE_WIDEBAND_RECEIVER``
-
-    The driver supports learning mode using
-    :ref:`ioctl LIRC_SET_WIDEBAND_RECEIVER <LIRC_SET_WIDEBAND_RECEIVER>`.
-
-.. _LIRC-CAN-NOTIFY-DECODE:
-
-``LIRC_CAN_NOTIFY_DECODE``
-
-    Unused. Kept just to avoid breaking uAPI.
-
-.. _LIRC-CAN-SEND-RAW:
-
-``LIRC_CAN_SEND_RAW``
-
-    Unused. Kept just to avoid breaking uAPI.
-
-.. _LIRC-CAN-SEND-PULSE:
-
-``LIRC_CAN_SEND_PULSE``
-
-    The driver supports sending (also called as IR blasting or IR TX) using
-    :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:
-
-``LIRC_CAN_SEND_MODE2``
-
-    Unused. Kept just to avoid breaking uAPI.
-    :ref:`LIRC_MODE_MODE2 <lirc-mode-mode2>` can only be used for receiving.
-
-.. _LIRC-CAN-SEND-LIRCCODE:
-
-``LIRC_CAN_SEND_LIRCCODE``
-
-    Unused. Kept just to avoid breaking uAPI.
-
-
-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
deleted file mode 100644
index 0a3e02aca80e..000000000000
--- a/Documentation/media/uapi/rc/lirc-get-rec-mode.rst
+++ /dev/null
@@ -1,74 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _lirc_get_rec_mode:
-.. _lirc_set_rec_mode:
-
-**********************************************
-ioctls LIRC_GET_REC_MODE and LIRC_SET_REC_MODE
-**********************************************
-
-Name
-====
-
-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 *mode)
-	:name: LIRC_GET_REC_MODE
-
-.. c:function:: int ioctl( int fd, LIRC_SET_REC_MODE, __u32 *mode)
-	:name: LIRC_SET_REC_MODE
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by open().
-
-``mode``
-    Mode used for receive.
-
-Description
-===========
-
-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
-============
-
-.. 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-rec-resolution.rst b/Documentation/media/uapi/rc/lirc-get-rec-resolution.rst
deleted file mode 100644
index f560b694ccf2..000000000000
--- a/Documentation/media/uapi/rc/lirc-get-rec-resolution.rst
+++ /dev/null
@@ -1,54 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _lirc_get_rec_resolution:
-
-*****************************
-ioctl LIRC_GET_REC_RESOLUTION
-*****************************
-
-Name
-====
-
-LIRC_GET_REC_RESOLUTION - Obtain the value of receive resolution, in microseconds.
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, LIRC_GET_REC_RESOLUTION, __u32 *microseconds)
-    :name: LIRC_GET_REC_RESOLUTION
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by open().
-
-``microseconds``
-    Resolution, in microseconds.
-
-
-Description
-===========
-
-Some receivers have maximum resolution which is defined by internal
-sample rate or data format limitations. E.g. it's common that
-signals can only be reported in 50 microsecond steps.
-
-This ioctl returns the integer value with such resolution, with can be
-used by userspace applications like lircd to automatically adjust the
-tolerance value.
-
-
-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-send-mode.rst b/Documentation/media/uapi/rc/lirc-get-send-mode.rst
deleted file mode 100644
index 4f440c697052..000000000000
--- a/Documentation/media/uapi/rc/lirc-get-send-mode.rst
+++ /dev/null
@@ -1,78 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _lirc_get_send_mode:
-.. _lirc_set_send_mode:
-
-************************************************
-ioctls LIRC_GET_SEND_MODE and LIRC_SET_SEND_MODE
-************************************************
-
-Name
-====
-
-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 *mode )
-    :name: LIRC_GET_SEND_MODE
-
-.. c:function:: int ioctl( int fd, LIRC_SET_SEND_MODE, __u32 *mode )
-    :name: LIRC_SET_SEND_MODE
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by open().
-
-``mode``
-    The mode used for transmitting.
-
-
-Description
-===========
-
-Get/set current transmit mode.
-
-Only :ref:`LIRC_MODE_PULSE <lirc-mode-pulse>` and
-: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
-============
-
-
-.. 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-get-timeout.rst b/Documentation/media/uapi/rc/lirc-get-timeout.rst
deleted file mode 100644
index 1de214529f27..000000000000
--- a/Documentation/media/uapi/rc/lirc-get-timeout.rst
+++ /dev/null
@@ -1,63 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _lirc_get_min_timeout:
-.. _lirc_get_max_timeout:
-
-****************************************************
-ioctls LIRC_GET_MIN_TIMEOUT and LIRC_GET_MAX_TIMEOUT
-****************************************************
-
-Name
-====
-
-LIRC_GET_MIN_TIMEOUT / LIRC_GET_MAX_TIMEOUT - Obtain the possible timeout
-range for IR receive.
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, LIRC_GET_MIN_TIMEOUT, __u32 *timeout)
-    :name: LIRC_GET_MIN_TIMEOUT
-
-.. c:function:: int ioctl( int fd, LIRC_GET_MAX_TIMEOUT, __u32 *timeout)
-    :name: LIRC_GET_MAX_TIMEOUT
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by open().
-
-``timeout``
-    Timeout, in microseconds.
-
-
-Description
-===========
-
-Some devices have internal timers that can be used to detect when
-there's no IR activity for a long time. This can help lircd in
-detecting that a IR signal is finished and can speed up the decoding
-process. Returns an integer value with the minimum/maximum timeout
-that can be set.
-
-.. note::
-
-   Some devices have a fixed timeout, in that case
-   both ioctls will return the same value even though the timeout
-   cannot be changed via :ref:`LIRC_SET_REC_TIMEOUT`.
-
-
-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-header.rst b/Documentation/media/uapi/rc/lirc-header.rst
deleted file mode 100644
index c9b4f33e1031..000000000000
--- a/Documentation/media/uapi/rc/lirc-header.rst
+++ /dev/null
@@ -1,17 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _lirc_header:
-
-****************
-LIRC Header File
-****************
-
-.. kernel-include:: $BUILDDIR/lirc.h.rst
-
diff --git a/Documentation/media/uapi/rc/lirc-read.rst b/Documentation/media/uapi/rc/lirc-read.rst
deleted file mode 100644
index 256e520bc27e..000000000000
--- a/Documentation/media/uapi/rc/lirc-read.rst
+++ /dev/null
@@ -1,76 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _lirc-read:
-
-***********
-LIRC read()
-***********
-
-Name
-====
-
-lirc-read - Read from a LIRC device
-
-
-Synopsis
-========
-
-.. code-block:: c
-
-    #include <unistd.h>
-
-
-.. c:function:: ssize_t read( int fd, void *buf, size_t count )
-    :name: lirc-read
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by ``open()``.
-
-``buf``
-   Buffer to be filled
-
-``count``
-   Max number of bytes to read
-
-Description
-===========
-
-:ref:`read() <lirc-read>` attempts to read up to ``count`` bytes from file
-descriptor ``fd`` into the buffer starting at ``buf``.  If ``count`` is zero,
-:ref:`read() <lirc-read>` returns zero and has no other results. If ``count``
-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, and use
-:ref:`lirc_set_rec_mode` set the current active mode.
-
-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
-:ref:`IR protocol <Remote_controllers_Protocols>`
-used for transmission, and ``scancode`` to the decoded scancode,
-and the ``keycode`` set to the keycode or ``KEY_RESERVED``.
-
-
-Return Value
-============
-
-On success, the number of bytes read 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.
diff --git a/Documentation/media/uapi/rc/lirc-set-measure-carrier-mode.rst b/Documentation/media/uapi/rc/lirc-set-measure-carrier-mode.rst
deleted file mode 100644
index c80acd85e369..000000000000
--- a/Documentation/media/uapi/rc/lirc-set-measure-carrier-mode.rst
+++ /dev/null
@@ -1,53 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _lirc_set_measure_carrier_mode:
-
-***********************************
-ioctl LIRC_SET_MEASURE_CARRIER_MODE
-***********************************
-
-Name
-====
-
-LIRC_SET_MEASURE_CARRIER_MODE - enable or disable measure mode
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, LIRC_SET_MEASURE_CARRIER_MODE, __u32 *enable )
-    :name: LIRC_SET_MEASURE_CARRIER_MODE
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by open().
-
-``enable``
-    enable = 1 means enable measure mode, enable = 0 means disable measure
-    mode.
-
-
-Description
-===========
-
-.. _lirc-mode2-frequency:
-
-Enable or disable measure mode. If enabled, from the next key
-press on, the driver will send ``LIRC_MODE2_FREQUENCY`` packets. By
-default this should be turned off.
-
-
-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-set-rec-carrier-range.rst b/Documentation/media/uapi/rc/lirc-set-rec-carrier-range.rst
deleted file mode 100644
index 443681d5cc10..000000000000
--- a/Documentation/media/uapi/rc/lirc-set-rec-carrier-range.rst
+++ /dev/null
@@ -1,54 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _lirc_set_rec_carrier_range:
-
-********************************
-ioctl LIRC_SET_REC_CARRIER_RANGE
-********************************
-
-Name
-====
-
-LIRC_SET_REC_CARRIER_RANGE - Set lower bound of the carrier used to modulate
-IR receive.
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, LIRC_SET_REC_CARRIER_RANGE, __u32 *frequency )
-    :name: LIRC_SET_REC_CARRIER_RANGE
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by open().
-
-``frequency``
-    Frequency of the carrier that modulates PWM data, in Hz.
-
-Description
-===========
-
-This ioctl sets the upper range of carrier frequency that will be recognized
-by the IR receiver.
-
-.. note::
-
-   To set a range use :ref:`LIRC_SET_REC_CARRIER_RANGE
-   <LIRC_SET_REC_CARRIER_RANGE>` with the lower bound first and later call
-   :ref:`LIRC_SET_REC_CARRIER <LIRC_SET_REC_CARRIER>` with the upper bound.
-
-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-set-rec-carrier.rst b/Documentation/media/uapi/rc/lirc-set-rec-carrier.rst
deleted file mode 100644
index cbe1e48b2a4a..000000000000
--- a/Documentation/media/uapi/rc/lirc-set-rec-carrier.rst
+++ /dev/null
@@ -1,53 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _lirc_set_rec_carrier:
-
-**************************
-ioctl LIRC_SET_REC_CARRIER
-**************************
-
-Name
-====
-
-LIRC_SET_REC_CARRIER - Set carrier used to modulate IR receive.
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, LIRC_SET_REC_CARRIER, __u32 *frequency )
-    :name: LIRC_SET_REC_CARRIER
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by open().
-
-``frequency``
-    Frequency of the carrier that modulates PWM data, in Hz.
-
-Description
-===========
-
-Set receive carrier used to modulate IR PWM pulses and spaces.
-
-.. note::
-
-   If called together with :ref:`LIRC_SET_REC_CARRIER_RANGE`, this ioctl
-   sets the upper bound frequency that will be recognized by the device.
-
-
-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-set-rec-timeout-reports.rst b/Documentation/media/uapi/rc/lirc-set-rec-timeout-reports.rst
deleted file mode 100644
index d06d69414c1e..000000000000
--- a/Documentation/media/uapi/rc/lirc-set-rec-timeout-reports.rst
+++ /dev/null
@@ -1,56 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _lirc_set_rec_timeout_reports:
-
-**********************************
-ioctl LIRC_SET_REC_TIMEOUT_REPORTS
-**********************************
-
-Name
-====
-
-LIRC_SET_REC_TIMEOUT_REPORTS - enable or disable timeout reports for IR receive
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, LIRC_SET_REC_TIMEOUT_REPORTS, __u32 *enable )
-    :name: LIRC_SET_REC_TIMEOUT_REPORTS
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by open().
-
-``enable``
-    enable = 1 means enable timeout report, enable = 0 means disable timeout
-    reports.
-
-
-Description
-===========
-
-.. _lirc-mode2-timeout:
-
-Enable or disable timeout reports for IR receive. By default, timeout reports
-should be turned off.
-
-.. note::
-
-   This ioctl is only valid for :ref:`LIRC_MODE_MODE2 <lirc-mode-mode2>`.
-
-
-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-set-rec-timeout.rst b/Documentation/media/uapi/rc/lirc-set-rec-timeout.rst
deleted file mode 100644
index 163ac6065737..000000000000
--- a/Documentation/media/uapi/rc/lirc-set-rec-timeout.rst
+++ /dev/null
@@ -1,61 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _lirc_set_rec_timeout:
-.. _lirc_get_rec_timeout:
-
-***************************************************
-ioctl LIRC_GET_REC_TIMEOUT and LIRC_SET_REC_TIMEOUT
-***************************************************
-
-Name
-====
-
-LIRC_GET_REC_TIMEOUT/LIRC_SET_REC_TIMEOUT - Get/set the integer value for IR inactivity timeout.
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, LIRC_GET_REC_TIMEOUT, __u32 *timeout )
-    :name: LIRC_GET_REC_TIMEOUT
-
-.. c:function:: int ioctl( int fd, LIRC_SET_REC_TIMEOUT, __u32 *timeout )
-    :name: LIRC_SET_REC_TIMEOUT
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by open().
-
-``timeout``
-    Timeout, in microseconds.
-
-
-Description
-===========
-
-Get and set the integer value for IR inactivity timeout.
-
-If supported by the hardware, setting it to 0  disables all hardware timeouts
-and data should be reported as soon as possible. If the exact value
-cannot be set, then the next possible value _greater_ than the
-given value should be set.
-
-.. note::
-
-   The range of supported timeout is given by :ref:`LIRC_GET_MIN_TIMEOUT`.
-
-
-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-set-send-carrier.rst b/Documentation/media/uapi/rc/lirc-set-send-carrier.rst
deleted file mode 100644
index cffc6c1e15cc..000000000000
--- a/Documentation/media/uapi/rc/lirc-set-send-carrier.rst
+++ /dev/null
@@ -1,48 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _lirc_set_send_carrier:
-
-***************************
-ioctl LIRC_SET_SEND_CARRIER
-***************************
-
-Name
-====
-
-LIRC_SET_SEND_CARRIER - Set send carrier used to modulate IR TX.
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, LIRC_SET_SEND_CARRIER, __u32 *frequency )
-    :name: LIRC_SET_SEND_CARRIER
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by open().
-
-``frequency``
-    Frequency of the carrier to be modulated, in Hz.
-
-Description
-===========
-
-Set send carrier used to modulate IR PWM pulses and spaces.
-
-
-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-set-send-duty-cycle.rst b/Documentation/media/uapi/rc/lirc-set-send-duty-cycle.rst
deleted file mode 100644
index 08ab3d1a96cd..000000000000
--- a/Documentation/media/uapi/rc/lirc-set-send-duty-cycle.rst
+++ /dev/null
@@ -1,54 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _lirc_set_send_duty_cycle:
-
-******************************
-ioctl LIRC_SET_SEND_DUTY_CYCLE
-******************************
-
-Name
-====
-
-LIRC_SET_SEND_DUTY_CYCLE - Set the duty cycle of the carrier signal for
-IR transmit.
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, LIRC_SET_SEND_DUTY_CYCLE, __u32 *duty_cycle)
-    :name: LIRC_SET_SEND_DUTY_CYCLE
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by open().
-
-``duty_cycle``
-    Duty cicle, describing the pulse width in percent (from 1 to 99) of
-    the total cycle. Values 0 and 100 are reserved.
-
-
-Description
-===========
-
-Get/set the duty cycle of the carrier signal for IR transmit.
-
-Currently, no special meaning is defined for 0 or 100, but this
-could be used to switch off carrier generation in the future, so
-these values should be reserved.
-
-
-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-set-transmitter-mask.rst b/Documentation/media/uapi/rc/lirc-set-transmitter-mask.rst
deleted file mode 100644
index 889a739eaf0d..000000000000
--- a/Documentation/media/uapi/rc/lirc-set-transmitter-mask.rst
+++ /dev/null
@@ -1,58 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _lirc_set_transmitter_mask:
-
-*******************************
-ioctl LIRC_SET_TRANSMITTER_MASK
-*******************************
-
-Name
-====
-
-LIRC_SET_TRANSMITTER_MASK - Enables send codes on a given set of transmitters
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, LIRC_SET_TRANSMITTER_MASK, __u32 *mask )
-    :name: LIRC_SET_TRANSMITTER_MASK
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by open().
-
-``mask``
-    Mask with channels to enable tx. Channel 0 is the least significant bit.
-
-
-Description
-===========
-
-Some IR TX devices have multiple output channels, in such case,
-:ref:`LIRC_CAN_SET_TRANSMITTER_MASK <LIRC-CAN-SET-TRANSMITTER-MASK>` is
-returned via :ref:`LIRC_GET_FEATURES` and this ioctl sets what channels will
-send IR codes.
-
-This ioctl enables the given set of transmitters. The first transmitter is
-encoded by the least significant bit and so on.
-
-When an invalid bit mask is given, i.e. a bit is set, even though the device
-does not have so many transitters, then this ioctl returns the number of
-available transitters and does nothing otherwise.
-
-
-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-set-wideband-receiver.rst b/Documentation/media/uapi/rc/lirc-set-wideband-receiver.rst
deleted file mode 100644
index 592715452fce..000000000000
--- a/Documentation/media/uapi/rc/lirc-set-wideband-receiver.rst
+++ /dev/null
@@ -1,63 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _lirc_set_wideband_receiver:
-
-********************************
-ioctl LIRC_SET_WIDEBAND_RECEIVER
-********************************
-
-Name
-====
-
-LIRC_SET_WIDEBAND_RECEIVER - enable wide band receiver.
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, LIRC_SET_WIDEBAND_RECEIVER, __u32 *enable )
-    :name: LIRC_SET_WIDEBAND_RECEIVER
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by open().
-
-``enable``
-    enable = 1 means enable wideband receiver, enable = 0 means disable
-    wideband receiver.
-
-
-Description
-===========
-
-Some receivers are equipped with special wide band receiver which is
-intended to be used to learn output of existing remote. This ioctl
-allows enabling or disabling it.
-
-This might be useful of receivers that have otherwise narrow band receiver
-that prevents them to be used with some remotes. Wide band receiver might
-also be more precise. On the other hand its disadvantage it usually
-reduced range of reception.
-
-.. note::
-
-    Wide band receiver might be implictly enabled if you enable
-    carrier reports. In that case it will be disabled as soon as you disable
-    carrier reports. Trying to disable wide band receiver while carrier
-    reports are active will do nothing.
-
-
-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-write.rst b/Documentation/media/uapi/rc/lirc-write.rst
deleted file mode 100644
index eafe13203ea3..000000000000
--- a/Documentation/media/uapi/rc/lirc-write.rst
+++ /dev/null
@@ -1,82 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _lirc-write:
-
-************
-LIRC write()
-************
-
-Name
-====
-
-lirc-write - Write to a LIRC device
-
-
-Synopsis
-========
-
-.. code-block:: c
-
-    #include <unistd.h>
-
-
-.. c:function:: ssize_t write( int fd, void *buf, size_t count )
-    :name: lirc-write
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by ``open()``.
-
-``buf``
-    Buffer with data to be written
-
-``count``
-    Number of bytes at the buffer
-
-Description
-===========
-
-:ref:`write() <lirc-write>` writes up to ``count`` bytes to the device
-referenced by the file descriptor ``fd`` from the buffer starting at
-``buf``.
-
-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 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 :ref:`IR protocol <Remote_controllers_Protocols>` in the
-:c:type:`rc_proto`: member. All other members must be
-set to 0, else ``EINVAL`` is returned. If there is no protocol encoder
-for the protocol or the scancode is not valid for the specified protocol,
-``EINVAL`` is returned. The write function blocks until the scancode
-is transmitted by the hardware.
-
-
-Return Value
-============
-
-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
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/media/uapi/rc/rc-intro.rst b/Documentation/media/uapi/rc/rc-intro.rst
deleted file mode 100644
index 37c5f90c76e7..000000000000
--- a/Documentation/media/uapi/rc/rc-intro.rst
+++ /dev/null
@@ -1,31 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _Remote_controllers_Intro:
-
-************
-Introduction
-************
-
-Currently, most analog and digital devices have a Infrared input for
-remote controllers. Each manufacturer has their own type of control. It
-is not rare for the same manufacturer to ship different types of
-controls, depending on the device.
-
-A Remote Controller interface is mapped as a normal evdev/input
-interface, just like a keyboard or a mouse. So, it uses all ioctls
-already defined for any other input devices.
-
-However, remove controllers are more flexible than a normal input
-device, as the IR receiver (and/or transmitter) can be used in
-conjunction with a wide variety of different IR remotes.
-
-In order to allow flexibility, the Remote Controller subsystem allows
-controlling the RC-specific attributes via
-:ref:`the sysfs class nodes <remote_controllers_sysfs_nodes>`.
diff --git a/Documentation/media/uapi/rc/rc-protos.rst b/Documentation/media/uapi/rc/rc-protos.rst
deleted file mode 100644
index b250ebe301d5..000000000000
--- a/Documentation/media/uapi/rc/rc-protos.rst
+++ /dev/null
@@ -1,456 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _Remote_controllers_Protocols:
-
-*****************************************
-Remote Controller Protocols and Scancodes
-*****************************************
-
-IR is encoded as a series of pulses and spaces, using a protocol. These
-protocols can encode e.g. an address (which device should respond) and a
-command: what it should do. The values for these are not always consistent
-across different devices for a given protocol.
-
-Therefore out the output of the IR decoder is a scancode; a single u32
-value. Using keymap tables this can be mapped to linux key codes.
-
-Other things can be encoded too. Some IR protocols encode a toggle bit; this
-is to distinguish whether the same button is being held down, or has been
-released and pressed again. If has been released and pressed again, the
-toggle bit will invert from one IR message to the next.
-
-Some remotes have a pointer-type device which can used to control the
-mouse; some air conditioning systems can have their target temperature
-target set in IR.
-
-The following are the protocols the kernel knows about and also lists
-how scancodes are encoded for each protocol.
-
-rc-5 (RC_PROTO_RC5)
--------------------
-
-This IR protocol uses manchester encoding to encode 14 bits. There is a
-detailed description here https://www.sbprojects.net/knowledge/ir/rc5.php.
-
-The scancode encoding is *not* consistent with the lirc daemon (lircd) rc5
-protocol, or the manchester BPF decoder.
-
-.. flat-table:: rc5 bits scancode mapping
-   :widths:       1 1 2
-
-   * - rc-5 bit
-
-     - scancode bit
-
-     - description
-
-   * - 1
-
-     - none
-
-     - Start bit, always set
-
-   * - 1
-
-     - 6 (inverted)
-
-     - 2nd start bit in rc5,  re-used as 6th command bit
-
-   * - 1
-
-     - none
-
-     - Toggle bit
-
-   * - 5
-
-     - 8 to 13
-
-     - Address
-
-   * - 6
-
-     - 0 to 5
-
-     - Command
-
-There is a variant of rc5 called either rc5x or extended rc5
-where there the second stop bit is the 6th commmand bit, but inverted.
-This is done so it the scancodes and encoding is compatible with existing
-schemes. This bit is stored in bit 6 of the scancode, inverted. This is
-done to keep it compatible with plain rc-5 where there are two start bits.
-
-rc-5-sz (RC_PROTO_RC5_SZ)
--------------------------
-This is much like rc-5 but one bit longer. The scancode is encoded
-differently.
-
-.. flat-table:: rc-5-sz bits scancode mapping
-   :widths:       1 1 2
-
-   * - rc-5-sz bits
-
-     - scancode bit
-
-     - description
-
-   * - 1
-
-     - none
-
-     - Start bit, always set
-
-   * - 1
-
-     - 13
-
-     - Address bit
-
-   * - 1
-
-     - none
-
-     - Toggle bit
-
-   * - 6
-
-     - 6 to 11
-
-     - Address
-
-   * - 6
-
-     - 0 to 5
-
-     - Command
-
-rc-5x-20 (RC_PROTO_RC5X_20)
----------------------------
-
-This rc-5 extended to encoded 20 bits. The is a 3555 microseconds space
-after the 8th bit.
-
-.. flat-table:: rc-5x-20 bits scancode mapping
-   :widths:       1 1 2
-
-   * - rc-5-sz bits
-
-     - scancode bit
-
-     - description
-
-   * - 1
-
-     - none
-
-     - Start bit, always set
-
-   * - 1
-
-     - 14
-
-     - Address bit
-
-   * - 1
-
-     - none
-
-     - Toggle bit
-
-   * - 5
-
-     - 16 to 20
-
-     - Address
-
-   * - 6
-
-     - 8 to 13
-
-     - Address
-
-   * - 6
-
-     - 0 to 5
-
-     - Command
-
-
-jvc (RC_PROTO_JVC)
-------------------
-
-The jvc protocol is much like nec, without the inverted values. It is
-described here https://www.sbprojects.net/knowledge/ir/jvc.php.
-
-The scancode is a 16 bits value, where the address is the lower 8 bits
-and the command the higher 8 bits; this is reversed from IR order.
-
-sony-12 (RC_PROTO_SONY12)
--------------------------
-
-The sony protocol is a pulse-width encoding. There are three variants,
-which just differ in number of bits and scancode encoding.
-
-.. flat-table:: sony-12 bits scancode mapping
-   :widths:       1 1 2
-
-   * - sony-12 bits
-
-     - scancode bit
-
-     - description
-
-   * - 5
-
-     - 16 to 20
-
-     - device
-
-   * - 7
-
-     - 0 to 6
-
-     - function
-
-sony-15 (RC_PROTO_SONY15)
--------------------------
-
-The sony protocol is a pulse-width encoding. There are three variants,
-which just differ in number of bits and scancode encoding.
-
-.. flat-table:: sony-12 bits scancode mapping
-   :widths:       1 1 2
-
-   * - sony-12 bits
-
-     - scancode bit
-
-     - description
-
-   * - 8
-
-     - 16 to 23
-
-     - device
-
-   * - 7
-
-     - 0 to 6
-
-     - function
-
-sony-20 (RC_PROTO_SONY20)
--------------------------
-
-The sony protocol is a pulse-width encoding. There are three variants,
-which just differ in number of bits and scancode encoding.
-
-.. flat-table:: sony-20 bits scancode mapping
-   :widths:       1 1 2
-
-   * - sony-20 bits
-
-     - scancode bit
-
-     - description
-
-   * - 5
-
-     - 16 to 20
-
-     - device
-
-   * - 7
-
-     - 0 to 7
-
-     - device
-
-   * - 8
-
-     - 8 to 15
-
-     - extended bits
-
-nec (RC_PROTO_NEC)
-------------------
-
-The nec protocol encodes an 8 bit address and an 8 bit command. It is
-described here https://www.sbprojects.net/knowledge/ir/nec.php. Note
-that the protocol sends least significant bit first.
-
-As a check, the nec protocol sends the address and command twice; the
-second time it is inverted. This is done for verification.
-
-A plain nec IR message has 16 bits; the high 8 bits are the address
-and the low 8 bits are the command.
-
-nec-x (RC_PROTO_NECX)
----------------------
-
-Extended nec has a 16 bit address and a 8 bit command. This is encoded
-as a 24 bit value as you would expect, with the lower 8 bits the command
-and the upper 16 bits the address.
-
-nec-32 (RC_PROTO_NEC32)
------------------------
-
-nec-32 does not send an inverted address or an inverted command; the
-entire message, all 32 bits, are used.
-
-For this to be decoded correctly, the second 8 bits must not be the
-inverted value of the first, and also the last 8 bits must not be the
-inverted value of the third 8 bit value.
-
-The scancode has a somewhat unusual encoding.
-
-.. flat-table:: nec-32 bits scancode mapping
-
-   * - nec-32 bits
-
-     - scancode bit
-
-   * - First 8 bits
-
-     - 16 to 23
-
-   * - Second 8 bits
-
-     - 24 to 31
-
-   * - Third 8 bits
-
-     - 0 to 7
-
-   * - Fourth 8 bits
-
-     - 8 to 15
-
-sanyo (RC_PROTO_SANYO)
-----------------------
-
-The sanyo protocol is like the nec protocol, but with 13 bits address
-rather than 8 bits. Both the address and the command are followed by
-their inverted versions, but these are not present in the scancodes.
-
-Bis 8 to 20 of the scancode is the 13 bits address, and the lower 8
-bits are the command.
-
-mcir2-kbd (RC_PROTO_MCIR2_KBD)
-------------------------------
-
-This protocol is generated by the Microsoft MCE keyboard for keyboard
-events. Refer to the ir-mce_kbd-decoder.c to see how it is encoded.
-
-mcir2-mse (RC_PROTO_MCIR2_MSE)
-------------------------------
-
-This protocol is generated by the Microsoft MCE keyboard for pointer
-events. Refer to the ir-mce_kbd-decoder.c to see how it is encoded.
-
-rc-6-0 (RC_PROTO_RC6_0)
------------------------
-
-This is the rc-6 in mode 0. rc-6 is described here
-https://www.sbprojects.net/knowledge/ir/rc6.php.
-The scancode is the exact 16 bits as in the protocol. There is also a
-toggle bit.
-
-rc-6-6a-20 (RC_PROTO_RC6_6A_20)
--------------------------------
-
-This is the rc-6 in mode 6a, 20 bits. rc-6 is described here
-https://www.sbprojects.net/knowledge/ir/rc6.php.
-The scancode is the exact 20 bits
-as in the protocol. There is also a toggle bit.
-
-rc-6-6a-24 (RC_PROTO_RC6_6A_24)
--------------------------------
-
-This is the rc-6 in mode 6a, 24 bits. rc-6 is described here
-https://www.sbprojects.net/knowledge/ir/rc6.php.
-The scancode is the exact 24 bits
-as in the protocol. There is also a toggle bit.
-
-rc-6-6a-32 (RC_PROTO_RC6_6A_32)
--------------------------------
-
-This is the rc-6 in mode 6a, 32 bits. rc-6 is described here
-https://www.sbprojects.net/knowledge/ir/rc6.php.
-The upper 16 bits are the vendor,
-and the lower 16 bits are the vendor-specific bits. This protocol is
-for the non-Microsoft MCE variant (vendor != 0x800f).
-
-
-rc-6-mce (RC_PROTO_RC6_MCE)
----------------------------
-
-This is the rc-6 in mode 6a, 32 bits. The upper 16 bits are the vendor,
-and the lower 16 bits are the vendor-specific bits. This protocol is
-for the Microsoft MCE variant (vendor = 0x800f). The toggle bit in the
-protocol itself is ignored, and the 16th bit should be takes as the toggle
-bit.
-
-sharp (RC_PROTO_SHARP)
-----------------------
-
-This is a protocol used by Sharp VCRs, is described here
-https://www.sbprojects.net/knowledge/ir/sharp.php. There is a very long
-(40ms) space between the normal and inverted values, and some IR receivers
-cannot decode this.
-
-There is a 5 bit address and a 8 bit command. In the scancode the address is
-in bits 8 to 12, and the command in bits 0 to 7.
-
-xmp (RC_PROTO_XMP)
-------------------
-
-This protocol has several versions and only version 1 is supported. Refer
-to the decoder (ir-xmp-decoder.c) to see how it is encoded.
-
-
-cec (RC_PROTO_CEC)
-------------------
-
-This is not an IR protocol, this is a protocol over CEC. The CEC
-infrastructure uses rc-core for handling CEC commands, so that they
-can easily be remapped.
-
-imon (RC_PROTO_IMON)
---------------------
-
-This protocol is used by Antec Veris/SoundGraph iMON remotes.
-
-The protocol
-describes both button presses and pointer movements. The protocol encodes
-31 bits, and the scancode is simply the 31 bits with the top bit always 0.
-
-rc-mm-12 (RC_PROTO_RCMM12)
---------------------------
-
-The rc-mm protocol is described here
-https://www.sbprojects.net/knowledge/ir/rcmm.php. The scancode is simply
-the 12 bits.
-
-rc-mm-24 (RC_PROTO_RCMM24)
---------------------------
-
-The rc-mm protocol is described here
-https://www.sbprojects.net/knowledge/ir/rcmm.php. The scancode is simply
-the 24 bits.
-
-rc-mm-32 (RC_PROTO_RCMM32)
---------------------------
-
-The rc-mm protocol is described here
-https://www.sbprojects.net/knowledge/ir/rcmm.php. The scancode is simply
-the 32 bits.
-
-xbox-dvd (RC_PROTO_XBOX_DVD)
-----------------------------
-
-This protocol is used by XBox DVD Remote, which was made for the original
-XBox. There is no in-kernel decoder or encoder for this protocol. The usb
-device decodes the protocol. There is a BPF decoder available in v4l-utils.
diff --git a/Documentation/media/uapi/rc/rc-sysfs-nodes.rst b/Documentation/media/uapi/rc/rc-sysfs-nodes.rst
deleted file mode 100644
index b8e8319e3317..000000000000
--- a/Documentation/media/uapi/rc/rc-sysfs-nodes.rst
+++ /dev/null
@@ -1,151 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _remote_controllers_sysfs_nodes:
-
-*******************************
-Remote Controller's sysfs nodes
-*******************************
-
-As defined at ``Documentation/ABI/testing/sysfs-class-rc``, those are
-the sysfs nodes that control the Remote Controllers:
-
-
-.. _sys_class_rc:
-
-/sys/class/rc/
-==============
-
-The ``/sys/class/rc/`` class sub-directory belongs to the Remote
-Controller core and provides a sysfs interface for configuring infrared
-remote controller receivers.
-
-
-.. _sys_class_rc_rcN:
-
-/sys/class/rc/rcN/
-==================
-
-A ``/sys/class/rc/rcN`` directory is created for each remote control
-receiver device where N is the number of the receiver.
-
-
-.. _sys_class_rc_rcN_protocols:
-
-/sys/class/rc/rcN/protocols
-===========================
-
-Reading this file returns a list of available protocols, something like::
-
-	rc5 [rc6] nec jvc [sony]
-
-Enabled protocols are shown in [] brackets.
-
-Writing "+proto" will add a protocol to the list of enabled protocols.
-
-Writing "-proto" will remove a protocol from the list of enabled
-protocols.
-
-Writing "proto" will enable only "proto".
-
-Writing "none" will disable all protocols.
-
-Write fails with ``EINVAL`` if an invalid protocol combination or unknown
-protocol name is used.
-
-
-.. _sys_class_rc_rcN_filter:
-
-/sys/class/rc/rcN/filter
-========================
-
-Sets the scancode filter expected value.
-
-Use in combination with ``/sys/class/rc/rcN/filter_mask`` to set the
-expected value of the bits set in the filter mask. If the hardware
-supports it then scancodes which do not match the filter will be
-ignored. Otherwise the write will fail with an error.
-
-This value may be reset to 0 if the current protocol is altered.
-
-
-.. _sys_class_rc_rcN_filter_mask:
-
-/sys/class/rc/rcN/filter_mask
-=============================
-
-Sets the scancode filter mask of bits to compare. Use in combination
-with ``/sys/class/rc/rcN/filter`` to set the bits of the scancode which
-should be compared against the expected value. A value of 0 disables the
-filter to allow all valid scancodes to be processed.
-
-If the hardware supports it then scancodes which do not match the filter
-will be ignored. Otherwise the write will fail with an error.
-
-This value may be reset to 0 if the current protocol is altered.
-
-
-.. _sys_class_rc_rcN_wakeup_protocols:
-
-/sys/class/rc/rcN/wakeup_protocols
-==================================
-
-Reading this file returns a list of available protocols to use for the
-wakeup filter, something like::
-
-	rc-5 nec nec-x rc-6-0 rc-6-6a-24 [rc-6-6a-32] rc-6-mce
-
-Note that protocol variants are listed, so ``nec``, ``sony``, ``rc-5``, ``rc-6``
-have their different bit length encodings listed if available.
-
-Note that all protocol variants are listed.
-
-The enabled wakeup protocol is shown in [] brackets.
-
-Only one protocol can be selected at a time.
-
-Writing "proto" will use "proto" for wakeup events.
-
-Writing "none" will disable wakeup.
-
-Write fails with ``EINVAL`` if an invalid protocol combination or unknown
-protocol name is used, or if wakeup is not supported by the hardware.
-
-
-.. _sys_class_rc_rcN_wakeup_filter:
-
-/sys/class/rc/rcN/wakeup_filter
-===============================
-
-Sets the scancode wakeup filter expected value. Use in combination with
-``/sys/class/rc/rcN/wakeup_filter_mask`` to set the expected value of
-the bits set in the wakeup filter mask to trigger a system wake event.
-
-If the hardware supports it and wakeup_filter_mask is not 0 then
-scancodes which match the filter will wake the system from e.g. suspend
-to RAM or power off. Otherwise the write will fail with an error.
-
-This value may be reset to 0 if the wakeup protocol is altered.
-
-
-.. _sys_class_rc_rcN_wakeup_filter_mask:
-
-/sys/class/rc/rcN/wakeup_filter_mask
-====================================
-
-Sets the scancode wakeup filter mask of bits to compare. Use in
-combination with ``/sys/class/rc/rcN/wakeup_filter`` to set the bits of
-the scancode which should be compared against the expected value to
-trigger a system wake event.
-
-If the hardware supports it and wakeup_filter_mask is not 0 then
-scancodes which match the filter will wake the system from e.g. suspend
-to RAM or power off. Otherwise the write will fail with an error.
-
-This value may be reset to 0 if the wakeup protocol is altered.
diff --git a/Documentation/media/uapi/rc/rc-table-change.rst b/Documentation/media/uapi/rc/rc-table-change.rst
deleted file mode 100644
index 4a2e601b89fb..000000000000
--- a/Documentation/media/uapi/rc/rc-table-change.rst
+++ /dev/null
@@ -1,25 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _Remote_controllers_table_change:
-
-*******************************************
-Changing default Remote Controller mappings
-*******************************************
-
-The event interface provides two ioctls to be used against the
-/dev/input/event device, to allow changing the default keymapping.
-
-This program demonstrates how to replace the keymap tables.
-
-
-.. toctree::
-    :maxdepth: 1
-
-    keytable.c
diff --git a/Documentation/media/uapi/rc/rc-tables.rst b/Documentation/media/uapi/rc/rc-tables.rst
deleted file mode 100644
index 20d7c686922b..000000000000
--- a/Documentation/media/uapi/rc/rc-tables.rst
+++ /dev/null
@@ -1,766 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _Remote_controllers_tables:
-
-************************
-Remote controller tables
-************************
-
-Unfortunately, for several years, there was no effort to create uniform
-IR keycodes for different devices. This caused the same IR keyname to be
-mapped completely differently on different IR devices. This resulted
-that the same IR keyname to be mapped completely different on different
-IR's. Due to that, V4L2 API now specifies a standard for mapping Media
-keys on IR.
-
-This standard should be used by both V4L/DVB drivers and userspace
-applications
-
-The modules register the remote as keyboard within the linux input
-layer. This means that the IR key strokes will look like normal keyboard
-key strokes (if CONFIG_INPUT_KEYBOARD is enabled). Using the event
-devices (CONFIG_INPUT_EVDEV) it is possible for applications to access
-the remote via /dev/input/event devices.
-
-
-.. _rc_standard_keymap:
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. flat-table:: IR default keymapping
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-
-    -  .. row 1
-
-       -  Key code
-
-       -  Meaning
-
-       -  Key examples on IR
-
-    -  .. row 2
-
-       -  **Numeric keys**
-
-    -  .. row 3
-
-       -  ``KEY_NUMERIC_0``
-
-       -  Keyboard digit 0
-
-       -  0
-
-    -  .. row 4
-
-       -  ``KEY_NUMERIC_1``
-
-       -  Keyboard digit 1
-
-       -  1
-
-    -  .. row 5
-
-       -  ``KEY_NUMERIC_2``
-
-       -  Keyboard digit 2
-
-       -  2
-
-    -  .. row 6
-
-       -  ``KEY_NUMERIC_3``
-
-       -  Keyboard digit 3
-
-       -  3
-
-    -  .. row 7
-
-       -  ``KEY_NUMERIC_4``
-
-       -  Keyboard digit 4
-
-       -  4
-
-    -  .. row 8
-
-       -  ``KEY_NUMERIC_5``
-
-       -  Keyboard digit 5
-
-       -  5
-
-    -  .. row 9
-
-       -  ``KEY_NUMERIC_6``
-
-       -  Keyboard digit 6
-
-       -  6
-
-    -  .. row 10
-
-       -  ``KEY_NUMERIC_7``
-
-       -  Keyboard digit 7
-
-       -  7
-
-    -  .. row 11
-
-       -  ``KEY_NUMERIC_8``
-
-       -  Keyboard digit 8
-
-       -  8
-
-    -  .. row 12
-
-       -  ``KEY_NUMERIC_9``
-
-       -  Keyboard digit 9
-
-       -  9
-
-    -  .. row 13
-
-       -  **Movie play control**
-
-    -  .. row 14
-
-       -  ``KEY_FORWARD``
-
-       -  Instantly advance in time
-
-       -  >> / FORWARD
-
-    -  .. row 15
-
-       -  ``KEY_BACK``
-
-       -  Instantly go back in time
-
-       -  <<< / BACK
-
-    -  .. row 16
-
-       -  ``KEY_FASTFORWARD``
-
-       -  Play movie faster
-
-       -  >>> / FORWARD
-
-    -  .. row 17
-
-       -  ``KEY_REWIND``
-
-       -  Play movie back
-
-       -  REWIND / BACKWARD
-
-    -  .. row 18
-
-       -  ``KEY_NEXT``
-
-       -  Select next chapter / sub-chapter / interval
-
-       -  NEXT / SKIP
-
-    -  .. row 19
-
-       -  ``KEY_PREVIOUS``
-
-       -  Select previous chapter / sub-chapter / interval
-
-       -  << / PREV / PREVIOUS
-
-    -  .. row 20
-
-       -  ``KEY_AGAIN``
-
-       -  Repeat the video or a video interval
-
-       -  REPEAT / LOOP / RECALL
-
-    -  .. row 21
-
-       -  ``KEY_PAUSE``
-
-       -  Pause stream
-
-       -  PAUSE / FREEZE
-
-    -  .. row 22
-
-       -  ``KEY_PLAY``
-
-       -  Play movie at the normal timeshift
-
-       -  NORMAL TIMESHIFT / LIVE / >
-
-    -  .. row 23
-
-       -  ``KEY_PLAYPAUSE``
-
-       -  Alternate between play and pause
-
-       -  PLAY / PAUSE
-
-    -  .. row 24
-
-       -  ``KEY_STOP``
-
-       -  Stop stream
-
-       -  STOP
-
-    -  .. row 25
-
-       -  ``KEY_RECORD``
-
-       -  Start/stop recording stream
-
-       -  CAPTURE / REC / RECORD/PAUSE
-
-    -  .. row 26
-
-       -  ``KEY_CAMERA``
-
-       -  Take a picture of the image
-
-       -  CAMERA ICON / CAPTURE / SNAPSHOT
-
-    -  .. row 27
-
-       -  ``KEY_SHUFFLE``
-
-       -  Enable shuffle mode
-
-       -  SHUFFLE
-
-    -  .. row 28
-
-       -  ``KEY_TIME``
-
-       -  Activate time shift mode
-
-       -  TIME SHIFT
-
-    -  .. row 29
-
-       -  ``KEY_TITLE``
-
-       -  Allow changing the chapter
-
-       -  CHAPTER
-
-    -  .. row 30
-
-       -  ``KEY_SUBTITLE``
-
-       -  Allow changing the subtitle
-
-       -  SUBTITLE
-
-    -  .. row 31
-
-       -  **Image control**
-
-    -  .. row 32
-
-       -  ``KEY_BRIGHTNESSDOWN``
-
-       -  Decrease Brightness
-
-       -  BRIGHTNESS DECREASE
-
-    -  .. row 33
-
-       -  ``KEY_BRIGHTNESSUP``
-
-       -  Increase Brightness
-
-       -  BRIGHTNESS INCREASE
-
-    -  .. row 34
-
-       -  ``KEY_ANGLE``
-
-       -  Switch video camera angle (on videos with more than one angle
-	  stored)
-
-       -  ANGLE / SWAP
-
-    -  .. row 35
-
-       -  ``KEY_EPG``
-
-       -  Open the Elecrowonic Play Guide (EPG)
-
-       -  EPG / GUIDE
-
-    -  .. row 36
-
-       -  ``KEY_TEXT``
-
-       -  Activate/change closed caption mode
-
-       -  CLOSED CAPTION/TELETEXT / DVD TEXT / TELETEXT / TTX
-
-    -  .. row 37
-
-       -  **Audio control**
-
-    -  .. row 38
-
-       -  ``KEY_AUDIO``
-
-       -  Change audio source
-
-       -  AUDIO SOURCE / AUDIO / MUSIC
-
-    -  .. row 39
-
-       -  ``KEY_MUTE``
-
-       -  Mute/unmute audio
-
-       -  MUTE / DEMUTE / UNMUTE
-
-    -  .. row 40
-
-       -  ``KEY_VOLUMEDOWN``
-
-       -  Decrease volume
-
-       -  VOLUME- / VOLUME DOWN
-
-    -  .. row 41
-
-       -  ``KEY_VOLUMEUP``
-
-       -  Increase volume
-
-       -  VOLUME+ / VOLUME UP
-
-    -  .. row 42
-
-       -  ``KEY_MODE``
-
-       -  Change sound mode
-
-       -  MONO/STEREO
-
-    -  .. row 43
-
-       -  ``KEY_LANGUAGE``
-
-       -  Select Language
-
-       -  1ST / 2ND LANGUAGE / DVD LANG / MTS/SAP / MTS SEL
-
-    -  .. row 44
-
-       -  **Channel control**
-
-    -  .. row 45
-
-       -  ``KEY_CHANNEL``
-
-       -  Go to the next favorite channel
-
-       -  ALT / CHANNEL / CH SURFING / SURF / FAV
-
-    -  .. row 46
-
-       -  ``KEY_CHANNELDOWN``
-
-       -  Decrease channel sequentially
-
-       -  CHANNEL - / CHANNEL DOWN / DOWN
-
-    -  .. row 47
-
-       -  ``KEY_CHANNELUP``
-
-       -  Increase channel sequentially
-
-       -  CHANNEL + / CHANNEL UP / UP
-
-    -  .. row 48
-
-       -  ``KEY_DIGITS``
-
-       -  Use more than one digit for channel
-
-       -  PLUS / 100/ 1xx / xxx / -/-- / Single Double Triple Digit
-
-    -  .. row 49
-
-       -  ``KEY_SEARCH``
-
-       -  Start channel autoscan
-
-       -  SCAN / AUTOSCAN
-
-    -  .. row 50
-
-       -  **Colored keys**
-
-    -  .. row 51
-
-       -  ``KEY_BLUE``
-
-       -  IR Blue key
-
-       -  BLUE
-
-    -  .. row 52
-
-       -  ``KEY_GREEN``
-
-       -  IR Green Key
-
-       -  GREEN
-
-    -  .. row 53
-
-       -  ``KEY_RED``
-
-       -  IR Red key
-
-       -  RED
-
-    -  .. row 54
-
-       -  ``KEY_YELLOW``
-
-       -  IR Yellow key
-
-       -  YELLOW
-
-    -  .. row 55
-
-       -  **Media selection**
-
-    -  .. row 56
-
-       -  ``KEY_CD``
-
-       -  Change input source to Compact Disc
-
-       -  CD
-
-    -  .. row 57
-
-       -  ``KEY_DVD``
-
-       -  Change input to DVD
-
-       -  DVD / DVD MENU
-
-    -  .. row 58
-
-       -  ``KEY_EJECTCLOSECD``
-
-       -  Open/close the CD/DVD player
-
-       -  -> ) / CLOSE / OPEN
-
-    -  .. row 59
-
-       -  ``KEY_MEDIA``
-
-       -  Turn on/off Media application
-
-       -  PC/TV / TURN ON/OFF APP
-
-    -  .. row 60
-
-       -  ``KEY_PC``
-
-       -  Selects from TV to PC
-
-       -  PC
-
-    -  .. row 61
-
-       -  ``KEY_RADIO``
-
-       -  Put into AM/FM radio mode
-
-       -  RADIO / TV/FM / TV/RADIO / FM / FM/RADIO
-
-    -  .. row 62
-
-       -  ``KEY_TV``
-
-       -  Select tv mode
-
-       -  TV / LIVE TV
-
-    -  .. row 63
-
-       -  ``KEY_TV2``
-
-       -  Select Cable mode
-
-       -  AIR/CBL
-
-    -  .. row 64
-
-       -  ``KEY_VCR``
-
-       -  Select VCR mode
-
-       -  VCR MODE / DTR
-
-    -  .. row 65
-
-       -  ``KEY_VIDEO``
-
-       -  Alternate between input modes
-
-       -  SOURCE / SELECT / DISPLAY / SWITCH INPUTS / VIDEO
-
-    -  .. row 66
-
-       -  **Power control**
-
-    -  .. row 67
-
-       -  ``KEY_POWER``
-
-       -  Turn on/off computer
-
-       -  SYSTEM POWER / COMPUTER POWER
-
-    -  .. row 68
-
-       -  ``KEY_POWER2``
-
-       -  Turn on/off application
-
-       -  TV ON/OFF / POWER
-
-    -  .. row 69
-
-       -  ``KEY_SLEEP``
-
-       -  Activate sleep timer
-
-       -  SLEEP / SLEEP TIMER
-
-    -  .. row 70
-
-       -  ``KEY_SUSPEND``
-
-       -  Put computer into suspend mode
-
-       -  STANDBY / SUSPEND
-
-    -  .. row 71
-
-       -  **Window control**
-
-    -  .. row 72
-
-       -  ``KEY_CLEAR``
-
-       -  Stop stream and return to default input video/audio
-
-       -  CLEAR / RESET / BOSS KEY
-
-    -  .. row 73
-
-       -  ``KEY_CYCLEWINDOWS``
-
-       -  Minimize windows and move to the next one
-
-       -  ALT-TAB / MINIMIZE / DESKTOP
-
-    -  .. row 74
-
-       -  ``KEY_FAVORITES``
-
-       -  Open the favorites stream window
-
-       -  TV WALL / Favorites
-
-    -  .. row 75
-
-       -  ``KEY_MENU``
-
-       -  Call application menu
-
-       -  2ND CONTROLS (USA: MENU) / DVD/MENU / SHOW/HIDE CTRL
-
-    -  .. row 76
-
-       -  ``KEY_NEW``
-
-       -  Open/Close Picture in Picture
-
-       -  PIP
-
-    -  .. row 77
-
-       -  ``KEY_OK``
-
-       -  Send a confirmation code to application
-
-       -  OK / ENTER / RETURN
-
-    -  .. row 78
-
-       -  ``KEY_ASPECT_RATIO``
-
-       -  Select screen aspect ratio
-
-       -  4:3 16:9 SELECT
-
-    -  .. row 79
-
-       -  ``KEY_FULL_SCREEN``
-
-       -  Put device into zoom/full screen mode
-
-       -  ZOOM / FULL SCREEN / ZOOM+ / HIDE PANNEL / SWITCH
-
-    -  .. row 80
-
-       -  **Navigation keys**
-
-    -  .. row 81
-
-       -  ``KEY_ESC``
-
-       -  Cancel current operation
-
-       -  CANCEL / BACK
-
-    -  .. row 82
-
-       -  ``KEY_HELP``
-
-       -  Open a Help window
-
-       -  HELP
-
-    -  .. row 83
-
-       -  ``KEY_HOMEPAGE``
-
-       -  Navigate to Homepage
-
-       -  HOME
-
-    -  .. row 84
-
-       -  ``KEY_INFO``
-
-       -  Open On Screen Display
-
-       -  DISPLAY INFORMATION / OSD
-
-    -  .. row 85
-
-       -  ``KEY_WWW``
-
-       -  Open the default browser
-
-       -  WEB
-
-    -  .. row 86
-
-       -  ``KEY_UP``
-
-       -  Up key
-
-       -  UP
-
-    -  .. row 87
-
-       -  ``KEY_DOWN``
-
-       -  Down key
-
-       -  DOWN
-
-    -  .. row 88
-
-       -  ``KEY_LEFT``
-
-       -  Left key
-
-       -  LEFT
-
-    -  .. row 89
-
-       -  ``KEY_RIGHT``
-
-       -  Right key
-
-       -  RIGHT
-
-    -  .. row 90
-
-       -  **Miscellaneous keys**
-
-    -  .. row 91
-
-       -  ``KEY_DOT``
-
-       -  Return a dot
-
-       -  .
-
-    -  .. row 92
-
-       -  ``KEY_FN``
-
-       -  Select a function
-
-       -  FUNCTION
-
-
-It should be noted that, sometimes, there some fundamental missing keys
-at some cheaper IR's. Due to that, it is recommended to:
-
-
-.. _rc_keymap_notes:
-
-.. flat-table:: Notes
-    :header-rows:  0
-    :stub-columns: 0
-
-
-    -  .. row 1
-
-       -  On simpler IR's, without separate channel keys, you need to map UP
-	  as ``KEY_CHANNELUP``
-
-    -  .. row 2
-
-       -  On simpler IR's, without separate channel keys, you need to map
-	  DOWN as ``KEY_CHANNELDOWN``
-
-    -  .. row 3
-
-       -  On simpler IR's, without separate volume keys, you need to map
-	  LEFT as ``KEY_VOLUMEDOWN``
-
-    -  .. row 4
-
-       -  On simpler IR's, without separate volume keys, you need to map
-	  RIGHT as ``KEY_VOLUMEUP``
diff --git a/Documentation/media/uapi/rc/remote_controllers.rst b/Documentation/media/uapi/rc/remote_controllers.rst
deleted file mode 100644
index 20e0f986df49..000000000000
--- a/Documentation/media/uapi/rc/remote_controllers.rst
+++ /dev/null
@@ -1,59 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. include:: <isonum.txt>
-
-.. _remote_controllers:
-
-################################
-Part III - Remote Controller API
-################################
-
-.. only:: html
-
-   .. class:: toc-title
-
-        Table of Contents
-
-.. toctree::
-    :maxdepth: 5
-    :numbered:
-
-    rc-intro
-    rc-sysfs-nodes
-    rc-protos
-    rc-tables
-    rc-table-change
-    lirc-dev
-
-
-**********************
-Revision and Copyright
-**********************
-
-Authors:
-
-- Carvalho Chehab, Mauro <mchehab@kernel.org>
-
- - Initial version.
-
-**Copyright** |copy| 2009-2016 : Mauro Carvalho Chehab
-
-****************
-Revision History
-****************
-
-:revision: 3.15 / 2014-02-06 (*mcc*)
-
-Added the interface description and the RC sysfs class description.
-
-
-:revision: 1.0 / 2009-09-06 (*mcc*)
-
-Initial revision
diff --git a/Documentation/media/uapi/v4l/app-pri.rst b/Documentation/media/uapi/v4l/app-pri.rst
deleted file mode 100644
index c25c1271b4f6..000000000000
--- a/Documentation/media/uapi/v4l/app-pri.rst
+++ /dev/null
@@ -1,37 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _app-pri:
-
-********************
-Application Priority
-********************
-
-When multiple applications share a device it may be desirable to assign
-them different priorities. Contrary to the traditional "rm -rf /" school
-of thought, a video recording application could for example block other
-applications from changing video controls or switching the current TV
-channel. Another objective is to permit low priority applications
-working in background, which can be preempted by user controlled
-applications and automatically regain control of the device at a later
-time.
-
-Since these features cannot be implemented entirely in user space V4L2
-defines the :ref:`VIDIOC_G_PRIORITY <VIDIOC_G_PRIORITY>` and
-:ref:`VIDIOC_S_PRIORITY <VIDIOC_G_PRIORITY>` ioctls to request and
-query the access priority associate with a file descriptor. Opening a
-device assigns a medium priority, compatible with earlier versions of
-V4L2 and drivers not supporting these ioctls. Applications requiring a
-different priority will usually call :ref:`VIDIOC_S_PRIORITY
-<VIDIOC_G_PRIORITY>` after verifying the device with the
-:ref:`VIDIOC_QUERYCAP` ioctl.
-
-Ioctls changing driver properties, such as
-:ref:`VIDIOC_S_INPUT <VIDIOC_G_INPUT>`, return an ``EBUSY`` error code
-after another application obtained higher priority.
diff --git a/Documentation/media/uapi/v4l/async.rst b/Documentation/media/uapi/v4l/async.rst
deleted file mode 100644
index be9539313f60..000000000000
--- a/Documentation/media/uapi/v4l/async.rst
+++ /dev/null
@@ -1,16 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _async:
-
-****************
-Asynchronous I/O
-****************
-
-This method is not defined yet.
diff --git a/Documentation/media/uapi/v4l/audio.rst b/Documentation/media/uapi/v4l/audio.rst
deleted file mode 100644
index 4c7fdbc8a860..000000000000
--- a/Documentation/media/uapi/v4l/audio.rst
+++ /dev/null
@@ -1,104 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _audio:
-
-************************
-Audio Inputs and Outputs
-************************
-
-Audio inputs and outputs are physical connectors of a device. Video
-capture devices have inputs, output devices have outputs, zero or more
-each. Radio devices have no audio inputs or outputs. They have exactly
-one tuner which in fact *is* an audio source, but this API associates
-tuners with video inputs or outputs only, and radio devices have none of
-these. [#f1]_ A connector on a TV card to loop back the received audio
-signal to a sound card is not considered an audio output.
-
-Audio and video inputs and outputs are associated. Selecting a video
-source also selects an audio source. This is most evident when the video
-and audio source is a tuner. Further audio connectors can combine with
-more than one video input or output. Assumed two composite video inputs
-and two audio inputs exist, there may be up to four valid combinations.
-The relation of video and audio connectors is defined in the
-``audioset`` field of the respective struct
-:c:type:`v4l2_input` or struct
-:c:type:`v4l2_output`, where each bit represents the index
-number, starting at zero, of one audio input or output.
-
-To learn about the number and attributes of the available inputs and
-outputs applications can enumerate them with the
-:ref:`VIDIOC_ENUMAUDIO` and
-:ref:`VIDIOC_ENUMAUDOUT <VIDIOC_ENUMAUDOUT>` ioctl, respectively.
-The struct :c:type:`v4l2_audio` returned by the
-:ref:`VIDIOC_ENUMAUDIO` ioctl also contains signal
-status information applicable when the current audio input is queried.
-
-The :ref:`VIDIOC_G_AUDIO <VIDIOC_G_AUDIO>` and
-:ref:`VIDIOC_G_AUDOUT <VIDIOC_G_AUDOUT>` ioctls report the current
-audio input and output, respectively.
-
-.. note::
-
-   Note that, unlike :ref:`VIDIOC_G_INPUT <VIDIOC_G_INPUT>` and
-   :ref:`VIDIOC_G_OUTPUT <VIDIOC_G_OUTPUT>` these ioctls return a
-   structure as :ref:`VIDIOC_ENUMAUDIO` and
-   :ref:`VIDIOC_ENUMAUDOUT <VIDIOC_ENUMAUDOUT>` do, not just an index.
-
-To select an audio input and change its properties applications call the
-:ref:`VIDIOC_S_AUDIO <VIDIOC_G_AUDIO>` ioctl. To select an audio
-output (which presently has no changeable properties) applications call
-the :ref:`VIDIOC_S_AUDOUT <VIDIOC_G_AUDOUT>` ioctl.
-
-Drivers must implement all audio input ioctls when the device has
-multiple selectable audio inputs, all audio output ioctls when the
-device has multiple selectable audio outputs. When the device has any
-audio inputs or outputs the driver must set the ``V4L2_CAP_AUDIO`` flag
-in the struct :c:type:`v4l2_capability` returned by
-the :ref:`VIDIOC_QUERYCAP` ioctl.
-
-
-Example: Information about the current audio input
-==================================================
-
-.. code-block:: c
-
-    struct v4l2_audio audio;
-
-    memset(&audio, 0, sizeof(audio));
-
-    if (-1 == ioctl(fd, VIDIOC_G_AUDIO, &audio)) {
-	perror("VIDIOC_G_AUDIO");
-	exit(EXIT_FAILURE);
-    }
-
-    printf("Current input: %s\\n", audio.name);
-
-
-Example: Switching to the first audio input
-===========================================
-
-.. code-block:: c
-
-    struct v4l2_audio audio;
-
-    memset(&audio, 0, sizeof(audio)); /* clear audio.mode, audio.reserved */
-
-    audio.index = 0;
-
-    if (-1 == ioctl(fd, VIDIOC_S_AUDIO, &audio)) {
-	perror("VIDIOC_S_AUDIO");
-	exit(EXIT_FAILURE);
-    }
-
-.. [#f1]
-   Actually struct :c:type:`v4l2_audio` ought to have a
-   ``tuner`` field like struct :c:type:`v4l2_input`, not
-   only making the API more consistent but also permitting radio devices
-   with multiple tuners.
diff --git a/Documentation/media/uapi/v4l/bayer.svg b/Documentation/media/uapi/v4l/bayer.svg
deleted file mode 100644
index c5bf85103901..000000000000
--- a/Documentation/media/uapi/v4l/bayer.svg
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-    This file is dual-licensed: you can use it either under the terms
-    of the GPL 2.0 or the GFDL 1.1+ license, at your option. Note that this
-    dual licensing only applies to this file, and not this project as a
-    whole.
-
-    a) This file is free software; you can redistribute it and/or
-       modify it under the terms of the GNU General Public License as
-       published by the Free Software Foundation version 2 of
-       the License.
-
-       This file is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-    Or, alternatively,
-
-    b) Permission is granted to copy, distribute and/or modify this
-       document under the terms of the GNU Free Documentation License,
-       Version 1.1 or any later version published by the Free Software
-       Foundation, with no Invariant Sections, no Front-Cover Texts
-       and no Back-Cover Texts. A copy of the license is included at
-       Documentation/media/uapi/fdl-appendix.rst.
-
-    TODO: replace it to GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
--->
-<svg id="svg2" width="164.15mm" height="46.771mm" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" preserveAspectRatio="xMidYMid" version="1.2" viewBox="0 0 16415.333 4677.1107" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><metadata id="metadata652"><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title/></cc:Work></rdf:RDF></metadata><g id="g186" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id6"><rect id="rect189" class="BoundingBox" x="3299" y="3199" width="1303" height="1203" fill="none"/><path id="path191" d="m3950 4400h-650v-1200h1300v1200h-650z" fill="#00f"/><path id="path193" d="m3950
-4400h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text195" class="TextShape"><tspan id="tspan197" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan199" class="TextPosition" x="3739" y="4021"><tspan id="tspan201" fill="#ffffff">B</tspan></tspan></tspan></text>
-</g></g><g id="g203" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id7"><rect id="rect206" class="BoundingBox" x="4599" y="3199" width="1303" height="1203" fill="none"/><path id="path208" d="m5250 4400h-650v-1200h1300v1200h-650z" fill="#0c0"/><path id="path210" d="m5250 4400h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text212" class="TextShape"><tspan id="tspan214" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan216" class="TextPosition" x="5003" y="4021"><tspan id="tspan218" fill="#ffffff">G</tspan></tspan></tspan></text>
-</g></g><g id="g220" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id8"><rect id="rect223" class="BoundingBox" x="3299" y="4399" width="1303" height="1203" fill="none"/><path id="path225" d="m3950 5600h-650v-1200h1300v1200h-650z" fill="#0c0"/><path id="path227" d="m3950 5600h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text229" class="TextShape"><tspan id="tspan231" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan233" class="TextPosition" x="3703" y="5221"><tspan id="tspan235" fill="#ffffff">G</tspan></tspan></tspan></text>
-</g></g><g id="g237" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id9"><rect id="rect240" class="BoundingBox" x="4599" y="4399" width="1303" height="1203" fill="none"/><path id="path242" d="m5250 5600h-650v-1200h1300v1200h-650z" fill="#f00"/><path id="path244" d="m5250 5600h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text246" class="TextShape"><tspan id="tspan248" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan250" class="TextPosition" x="5022" y="5221"><tspan id="tspan252" fill="#ffffff">R</tspan></tspan></tspan></text>
-</g></g><g id="g254" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id10" fill="none"><rect id="rect257" class="BoundingBox" x="5999" y="3299" width="1003" height="1003"/><path id="path259" d="m6500 4300h-500v-1e3h1e3v1e3h-500z" stroke="#00f"/></g></g><g id="g261" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id11" fill="none"><rect id="rect264" class="BoundingBox" x="4699" y="5699" width="1003" height="1003"/><path id="path266" d="m5200 6700h-500v-1e3h1e3v1e3h-500z" stroke="#0c0"/></g></g><g id="g268" class="com.sun.star.drawing.TextShape" transform="translate(-3285.9 -3185.9)"><g id="id12"><rect id="rect271" class="BoundingBox" x="4e3" y="6900" width="2374" height="963" fill="none"/><text id="text273" class="TextShape"><tspan id="tspan275" class="TextParagraph" font-family="sans-serif" font-size="635px"
-font-weight="400"><tspan id="tspan277" class="TextPosition" x="4250" y="7601"><tspan id="tspan279" fill="#000000">BGGR</tspan></tspan></tspan></text>
-</g></g><g id="g281" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id13"><rect id="rect284" class="BoundingBox" x="8799" y="3199" width="1303" height="1203" fill="none"/><path id="path286" d="m9450 4400h-650v-1200h1300v1200h-650z" fill="#00f"/><path id="path288" d="m9450 4400h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text290" class="TextShape"><tspan id="tspan292" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan294" class="TextPosition" x="9239" y="4021"><tspan id="tspan296" fill="#ffffff">B</tspan></tspan></tspan></text>
-</g></g><g id="g298" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id14"><rect id="rect301" class="BoundingBox" x="7499" y="3199" width="1303" height="1203" fill="none"/><path id="path303" d="m8150 4400h-650v-1200h1300v1200h-650z" fill="#0c0"/><path id="path305" d="m8150 4400h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text307" class="TextShape"><tspan id="tspan309" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan311" class="TextPosition" x="7903" y="4021"><tspan id="tspan313" fill="#ffffff">G</tspan></tspan></tspan></text>
-</g></g><g id="g315" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id15"><rect id="rect318" class="BoundingBox" x="8799" y="4399" width="1303" height="1203" fill="none"/><path id="path320" d="m9450 5600h-650v-1200h1300v1200h-650z" fill="#0c0"/><path id="path322" d="m9450 5600h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text324" class="TextShape"><tspan id="tspan326" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan328" class="TextPosition" x="9203" y="5221"><tspan id="tspan330" fill="#ffffff">G</tspan></tspan></tspan></text>
-</g></g><g id="g332" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id16"><rect id="rect335" class="BoundingBox" x="7499" y="4399" width="1303" height="1203" fill="none"/><path id="path337" d="m8150 5600h-650v-1200h1300v1200h-650z" fill="#f00"/><path id="path339" d="m8150 5600h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text341" class="TextShape"><tspan id="tspan343" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan345" class="TextPosition" x="7922" y="5221"><tspan id="tspan347" fill="#ffffff">R</tspan></tspan></tspan></text>
-</g></g><g id="g349" class="com.sun.star.drawing.TextShape" transform="translate(-3285.9 -3185.9)"><g id="id17"><rect id="rect352" class="BoundingBox" x="8200" y="6900" width="2374" height="963" fill="none"/><text id="text354" class="TextShape"><tspan id="tspan356" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan358" class="TextPosition" x="8450" y="7601"><tspan id="tspan360" fill="#000000">GBRG</tspan></tspan></tspan></text>
-</g></g><g id="g362" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id18"><rect id="rect365" class="BoundingBox" x="17299" y="4399" width="1303" height="1203" fill="none"/><path id="path367" d="m17950 5600h-650v-1200h1300v1200h-650z" fill="#00f"/><path id="path369" d="m17950 5600h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text371" class="TextShape"><tspan id="tspan373" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan375" class="TextPosition" x="17739" y="5221"><tspan id="tspan377" fill="#ffffff">B</tspan></tspan></tspan></text>
-</g></g><g id="g379" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id19"><rect id="rect382" class="BoundingBox" x="17299" y="3199" width="1303" height="1203" fill="none"/><path id="path384" d="m17950 4400h-650v-1200h1300v1200h-650z" fill="#0c0"/><path id="path386" d="m17950 4400h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text388" class="TextShape"><tspan id="tspan390" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan392" class="TextPosition" x="17703" y="4021"><tspan id="tspan394" fill="#ffffff">G</tspan></tspan></tspan></text>
-</g></g><g id="g396" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id20"><rect id="rect399" class="BoundingBox" x="15999" y="4399" width="1303" height="1203" fill="none"/><path id="path401" d="m16650 5600h-650v-1200h1300v1200h-650z" fill="#0c0"/><path id="path403" d="m16650 5600h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text405" class="TextShape"><tspan id="tspan407" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan409" class="TextPosition" x="16403" y="5221"><tspan id="tspan411" fill="#ffffff">G</tspan></tspan></tspan></text>
-</g></g><g id="g413" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id21"><rect id="rect416" class="BoundingBox" x="15999" y="3199" width="1303" height="1203" fill="none"/><path id="path418" d="m16650 4400h-650v-1200h1300v1200h-650z" fill="#f00"/><path id="path420" d="m16650 4400h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text422" class="TextShape"><tspan id="tspan424" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan426" class="TextPosition" x="16422" y="4021"><tspan id="tspan428" fill="#ffffff">R</tspan></tspan></tspan></text>
-</g></g><g id="g430" class="com.sun.star.drawing.TextShape" transform="translate(-3285.9 -3185.9)"><g id="id22"><rect id="rect433" class="BoundingBox" x="16700" y="6900" width="2374" height="963" fill="none"/><text id="text435" class="TextShape"><tspan id="tspan437" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan439" class="TextPosition" x="16950" y="7601"><tspan id="tspan441" fill="#000000">RGGB</tspan></tspan></tspan></text>
-</g></g><g id="g443" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id23"><rect id="rect446" class="BoundingBox" x="11699" y="4399" width="1303" height="1203" fill="none"/><path id="path448" d="m12350 5600h-650v-1200h1300v1200h-650z" fill="#00f"/><path id="path450" d="m12350 5600h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text452" class="TextShape"><tspan id="tspan454" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan456" class="TextPosition" x="12139" y="5221"><tspan id="tspan458" fill="#ffffff">B</tspan></tspan></tspan></text>
-</g></g><g id="g460" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id24"><rect id="rect463" class="BoundingBox" x="11699" y="3199" width="1303" height="1203" fill="none"/><path id="path465" d="m12350 4400h-650v-1200h1300v1200h-650z" fill="#0c0"/><path id="path467" d="m12350 4400h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text469" class="TextShape"><tspan id="tspan471" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan473" class="TextPosition" x="12103" y="4021"><tspan id="tspan475" fill="#ffffff">G</tspan></tspan></tspan></text>
-</g></g><g id="g477" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id25"><rect id="rect480" class="BoundingBox" x="12999" y="4399" width="1303" height="1203" fill="none"/><path id="path482" d="m13650 5600h-650v-1200h1300v1200h-650z" fill="#0c0"/><path id="path484" d="m13650 5600h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text486" class="TextShape"><tspan id="tspan488" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan490" class="TextPosition" x="13403" y="5221"><tspan id="tspan492" fill="#ffffff">G</tspan></tspan></tspan></text>
-</g></g><g id="g494" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id26"><rect id="rect497" class="BoundingBox" x="12999" y="3199" width="1303" height="1203" fill="none"/><path id="path499" d="m13650 4400h-650v-1200h1300v1200h-650z" fill="#f00"/><path id="path501" d="m13650 4400h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text503" class="TextShape"><tspan id="tspan505" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan507" class="TextPosition" x="13422" y="4021"><tspan id="tspan509" fill="#ffffff">R</tspan></tspan></tspan></text>
-</g></g><g id="g511" class="com.sun.star.drawing.TextShape" transform="translate(-3285.9 -3185.9)"><g id="id27"><rect id="rect514" class="BoundingBox" x="12400" y="6900" width="2374" height="963" fill="none"/><text id="text516" class="TextShape"><tspan id="tspan518" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan520" class="TextPosition" x="12650" y="7601"><tspan id="tspan522" fill="#000000">GRBG</tspan></tspan></tspan></text>
-</g></g><g id="g524" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id28" fill="none"><rect id="rect527" class="BoundingBox" x="5999" y="5699" width="1003" height="1003"/><path id="path529" d="m6500 6700h-500v-1e3h1e3v1e3h-500z" stroke="#00f"/></g></g><g id="g531" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id29" fill="none"><rect id="rect534" class="BoundingBox" x="3399" y="5699" width="1003" height="1003"/><path id="path536" d="m3900 6700h-500v-1e3h1e3v1e3h-500z" stroke="#00f"/></g></g><g id="g538" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id30" fill="none"><rect id="rect541" class="BoundingBox" x="5999" y="4499" width="1003" height="1003"/><path id="path543" d="m6500 5500h-500v-1e3h1e3v1e3h-500z" stroke="#0c0"/></g></g><g id="g545"
-class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id31" fill="none"><rect id="rect548" class="BoundingBox" x="7599" y="5799" width="1003" height="1003"/><path id="path550" d="m8100 6800h-500v-1e3h1e3v1e3h-500z" stroke="#0c0"/></g></g><g id="g552" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id32" fill="none"><rect id="rect555" class="BoundingBox" x="10199" y="5799" width="1003" height="1003"/><path id="path557" d="m10700 6800h-500v-1e3h1e3v1e3h-500z" stroke="#0c0"/></g></g><g id="g559" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id33" fill="none"><rect id="rect562" class="BoundingBox" x="8899" y="5799" width="1003" height="1003"/><path id="path564" d="m9400 6800h-500v-1e3h1e3v1e3h-500z" stroke="#00f"/></g></g><g id="g566" class="com.sun.star.drawing.CustomShape"
-transform="translate(-3285.9 -3185.9)"><g id="id34" fill="none"><rect id="rect569" class="BoundingBox" x="10199" y="4499" width="1003" height="1003"/><path id="path571" d="m10700 5500h-500v-1e3h1e3v1e3h-500z" stroke="#f00"/></g></g><g id="g573" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id35" fill="none"><rect id="rect576" class="BoundingBox" x="10199" y="3299" width="1003" height="1003"/><path id="path578" d="m10700 4300h-500v-1e3h1e3v1e3h-500z" stroke="#0c0"/></g></g><g id="g580" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id36" fill="none"><rect id="rect583" class="BoundingBox" x="14399" y="3299" width="1003" height="1003"/><path id="path585" d="m14900 4300h-500v-1e3h1e3v1e3h-500z" stroke="#0c0"/></g></g><g id="g587" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g
-id="id37" fill="none"><rect id="rect590" class="BoundingBox" x="14399" y="5799" width="1003" height="1003"/><path id="path592" d="m14900 6800h-500v-1e3h1e3v1e3h-500z" stroke="#0c0"/></g></g><g id="g594" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id38" fill="none"><rect id="rect597" class="BoundingBox" x="11799" y="5799" width="1003" height="1003"/><path id="path599" d="m12300 6800h-500v-1e3h1e3v1e3h-500z" stroke="#0c0"/></g></g><g id="g601" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id39" fill="none"><rect id="rect604" class="BoundingBox" x="14399" y="4499" width="1003" height="1003"/><path id="path606" d="m14900 5500h-500v-1e3h1e3v1e3h-500z" stroke="#00f"/></g></g><g id="g608" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id40" fill="none"><rect id="rect611"
-class="BoundingBox" x="13099" y="5799" width="1003" height="1003"/><path id="path613" d="m13600 6800h-500v-1e3h1e3v1e3h-500z" stroke="#f00"/></g></g><g id="g615" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id41" fill="none"><rect id="rect618" class="BoundingBox" x="16099" y="5799" width="1003" height="1003"/><path id="path620" d="m16600 6800h-500v-1e3h1e3v1e3h-500z" stroke="#f00"/></g></g><g id="g622" class="com.sun.star.drawing.CustomShape" transform="translate(-3398.8 -3185.9)"><g id="id42" fill="none"><rect id="rect625" class="BoundingBox" x="18799" y="5799" width="1003" height="1003"/><path id="path627" d="m19300 6800h-500v-1e3h1e3v1e3h-500z" stroke="#f00"/></g></g><g id="g629" class="com.sun.star.drawing.CustomShape" transform="translate(-3398.8 -3185.9)"><g id="id43" fill="none"><rect id="rect632" class="BoundingBox" x="18799" y="3299"
-width="1003" height="1003"/><path id="path634" d="m19300 4300h-500v-1e3h1e3v1e3h-500z" stroke="#f00"/></g></g><g id="g636" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id44" fill="none"><rect id="rect639" class="BoundingBox" x="17399" y="5799" width="1003" height="1003"/><path id="path641" d="m17900 6800h-500v-1e3h1e3v1e3h-500z" stroke="#0c0"/></g></g><g id="g643" class="com.sun.star.drawing.CustomShape" transform="translate(-3398.8 -3185.9)"><g id="id45" fill="none"><rect id="rect646" class="BoundingBox" x="18799" y="4499" width="1003" height="1003"/><path id="path648" d="m19300 5500h-500v-1e3h1e3v1e3h-500z" stroke="#0c0"/></g></g></svg>
diff --git a/Documentation/media/uapi/v4l/biblio.rst b/Documentation/media/uapi/v4l/biblio.rst
deleted file mode 100644
index 8095f57d3d75..000000000000
--- a/Documentation/media/uapi/v4l/biblio.rst
+++ /dev/null
@@ -1,416 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-**********
-References
-**********
-
-
-.. _cea608:
-
-CEA 608-E
-=========
-
-
-:title:     CEA-608-E R-2014 "Line 21 Data Services"
-
-:author:    Consumer Electronics Association (http://www.ce.org)
-
-.. _en300294:
-
-EN 300 294
-==========
-
-
-:title:     EN 300 294 "625-line television Wide Screen Signalling (WSS)"
-
-:author:    European Telecommunication Standards Institute (http://www.etsi.org)
-
-.. _ets300231:
-
-ETS 300 231
-===========
-
-
-:title:     ETS 300 231 "Specification of the domestic video Programme Delivery Control system (PDC)"
-
-:author:    European Telecommunication Standards Institute (http://www.etsi.org)
-
-.. _ets300706:
-
-ETS 300 706
-===========
-
-
-:title:     ETS 300 706 "Enhanced Teletext specification"
-
-:author:    European Telecommunication Standards Institute (http://www.etsi.org)
-
-.. _mpeg2part1:
-
-ISO 13818-1
-===========
-
-
-:title:     ITU-T Rec. H.222.0 | ISO/IEC 13818-1 "Information technology — Generic coding of moving pictures and associated audio information: Systems"
-
-:author:    International Telecommunication Union (http://www.itu.ch), International Organisation for Standardisation (http://www.iso.ch)
-
-.. _mpeg2part2:
-
-ISO 13818-2
-===========
-
-
-:title:     ITU-T Rec. H.262 | ISO/IEC 13818-2 "Information technology — Generic coding of moving pictures and associated audio information: Video"
-
-:author:    International Telecommunication Union (http://www.itu.ch), International Organisation for Standardisation (http://www.iso.ch)
-
-.. _itu470:
-
-ITU BT.470
-==========
-
-
-:title:     ITU-R Recommendation BT.470-6 "Conventional Television Systems"
-
-:author:    International Telecommunication Union (http://www.itu.ch)
-
-.. _itu601:
-
-ITU BT.601
-==========
-
-
-:title:     ITU-R Recommendation BT.601-5 "Studio Encoding Parameters of Digital Television for Standard 4:3 and Wide-Screen 16:9 Aspect Ratios"
-
-:author:    International Telecommunication Union (http://www.itu.ch)
-
-.. _itu653:
-
-ITU BT.653
-==========
-
-
-:title:     ITU-R Recommendation BT.653-3 "Teletext systems"
-
-:author:    International Telecommunication Union (http://www.itu.ch)
-
-.. _itu709:
-
-ITU BT.709
-==========
-
-
-:title:     ITU-R Recommendation BT.709-5 "Parameter values for the HDTV standards for production and international programme exchange"
-
-:author:    International Telecommunication Union (http://www.itu.ch)
-
-.. _itu1119:
-
-ITU BT.1119
-===========
-
-
-:title:     ITU-R Recommendation BT.1119 "625-line television Wide Screen Signalling (WSS)"
-
-:author:    International Telecommunication Union (http://www.itu.ch)
-
-.. _h264:
-
-ITU-T Rec. H.264 Specification (04/2017 Edition)
-================================================
-
-:title:     ITU-T Recommendation H.264 "Advanced Video Coding for Generic Audiovisual Services"
-
-:author:    International Telecommunication Union (http://www.itu.ch)
-
-.. _hevc:
-
-ITU H.265/HEVC
-==============
-
-:title:     ITU-T Rec. H.265 | ISO/IEC 23008-2 "High Efficiency Video Coding"
-
-:author:    International Telecommunication Union (http://www.itu.ch), International Organisation for Standardisation (http://www.iso.ch)
-
-.. _jfif:
-
-JFIF
-====
-
-
-:title:     JPEG File Interchange Format
-:subtitle:  Version 1.02
-
-:author:    Independent JPEG Group (http://www.ijg.org)
-
-.. _itu-t81:
-
-ITU-T.81
-========
-
-
-:title:     ITU-T Recommendation T.81 "Information Technology — Digital Compression and Coding of Continous-Tone Still Images — Requirements and Guidelines"
-
-:author:    International Telecommunication Union (http://www.itu.int)
-
-.. _w3c-jpeg-jfif:
-
-W3C JPEG JFIF
-=============
-
-
-:title:     JPEG JFIF
-
-:author:    The World Wide Web Consortium (http://www.w3.org)
-
-.. _smpte12m:
-
-SMPTE 12M
-=========
-
-
-:title:     SMPTE 12M-1999 "Television, Audio and Film - Time and Control Code"
-
-:author:    Society of Motion Picture and Television Engineers (http://www.smpte.org)
-
-.. _smpte170m:
-
-SMPTE 170M
-==========
-
-
-:title:     SMPTE 170M-1999 "Television - Composite Analog Video Signal - NTSC for Studio Applications"
-
-:author:    Society of Motion Picture and Television Engineers (http://www.smpte.org)
-
-.. _smpte240m:
-
-SMPTE 240M
-==========
-
-
-:title:     SMPTE 240M-1999 "Television - Signal Parameters - 1125-Line High-Definition Production"
-
-:author:    Society of Motion Picture and Television Engineers (http://www.smpte.org)
-
-.. _smpte431:
-
-SMPTE RP 431-2
-==============
-
-
-:title:     SMPTE RP 431-2:2011 "D-Cinema Quality - Reference Projector and Environment"
-
-:author:    Society of Motion Picture and Television Engineers (http://www.smpte.org)
-
-.. _smpte2084:
-
-SMPTE ST 2084
-=============
-
-
-:title:     SMPTE ST 2084:2014 "High Dynamic Range Electro-Optical Transfer Function of Master Reference Displays"
-
-:author:    Society of Motion Picture and Television Engineers (http://www.smpte.org)
-
-.. _srgb:
-
-sRGB
-====
-
-
-:title:     IEC 61966-2-1 ed1.0 "Multimedia systems and equipment - Colour measurement and management - Part 2-1: Colour management - Default RGB colour space - sRGB"
-
-:author:    International Electrotechnical Commission (http://www.iec.ch)
-
-.. _sycc:
-
-sYCC
-====
-
-
-:title:     IEC 61966-2-1-am1 ed1.0 "Amendment 1 - Multimedia systems and equipment - Colour measurement and management - Part 2-1: Colour management - Default RGB colour space - sRGB"
-
-:author:    International Electrotechnical Commission (http://www.iec.ch)
-
-.. _xvycc:
-
-xvYCC
-=====
-
-
-:title:     IEC 61966-2-4 ed1.0 "Multimedia systems and equipment - Colour measurement and management - Part 2-4: Colour management - Extended-gamut YCC colour space for video applications - xvYCC"
-
-:author:    International Electrotechnical Commission (http://www.iec.ch)
-
-.. _oprgb:
-
-opRGB
-=====
-
-
-:title:     IEC 61966-2-5 "Multimedia systems and equipment - Colour measurement and management - Part 2-5: Colour management - Optional RGB colour space - opRGB"
-
-:author:    International Electrotechnical Commission (http://www.iec.ch)
-
-.. _itu2020:
-
-ITU BT.2020
-===========
-
-
-:title:     ITU-R Recommendation BT.2020 (08/2012) "Parameter values for ultra-high definition television systems for production and international programme exchange"
-
-:author:    International Telecommunication Union (http://www.itu.ch)
-
-.. _tech3213:
-
-EBU Tech 3213
-=============
-
-
-:title:     E.B.U. Standard for Chromaticity Tolerances for Studio Monitors"
-
-:author:    European Broadcast Union (http://www.ebu.ch)
-
-.. _iec62106:
-
-IEC 62106
-=========
-
-
-:title:     Specification of the radio data system (RDS) for VHF/FM sound broadcasting in the frequency range from 87,5 to 108,0 MHz
-
-:author:    International Electrotechnical Commission (http://www.iec.ch)
-
-.. _nrsc4:
-
-NRSC-4-B
-========
-
-
-:title:     NRSC-4-B: United States RBDS Standard
-
-:author:    National Radio Systems Committee (http://www.nrscstandards.org)
-
-.. _iso12232:
-
-ISO 12232:2006
-==============
-
-
-:title:     Photography — Digital still cameras — Determination of exposure index, ISO speed ratings, standard output sensitivity, and recommended exposure index
-
-:author:    International Organization for Standardization (http://www.iso.org)
-
-.. _cea861:
-
-CEA-861-E
-=========
-
-
-:title:     A DTV Profile for Uncompressed High Speed Digital Interfaces
-
-:author:    Consumer Electronics Association (http://www.ce.org)
-
-.. _vesadmt:
-
-VESA DMT
-========
-
-
-:title:     VESA and Industry Standards and Guidelines for Computer Display Monitor Timing (DMT)
-
-:author:    Video Electronics Standards Association (http://www.vesa.org)
-
-.. _vesaedid:
-
-EDID
-====
-
-
-:title:     VESA Enhanced Extended Display Identification Data Standard
-:subtitle:  Release A, Revision 2
-
-:author:    Video Electronics Standards Association (http://www.vesa.org)
-
-.. _hdcp:
-
-HDCP
-====
-
-
-:title:     High-bandwidth Digital Content Protection System
-:subtitle:  Revision 1.3
-
-:author:    Digital Content Protection LLC (http://www.digital-cp.com)
-
-.. _hdmi:
-
-HDMI
-====
-
-
-:title:     High-Definition Multimedia Interface
-:subtitle:  Specification Version 1.4a
-
-:author:    HDMI Licensing LLC (http://www.hdmi.org)
-
-.. _hdmi2:
-
-HDMI2
-=====
-
-:title:     High-Definition Multimedia Interface
-:subtitle:  Specification Version 2.0
-
-:author:    HDMI Licensing LLC (http://www.hdmi.org)
-
-.. _dp:
-
-DP
-==
-
-
-:title:     VESA DisplayPort Standard
-:subtitle:  Version 1, Revision 2
-
-:author:    Video Electronics Standards Association (http://www.vesa.org)
-
-.. _poynton:
-
-poynton
-=======
-
-
-:title:     Digital Video and HDTV, Algorithms and Interfaces
-
-:author:    Charles Poynton
-
-.. _colimg:
-
-colimg
-======
-
-
-:title:     Color Imaging: Fundamentals and Applications
-
-:author:    Erik Reinhard et al.
-
-.. _vp8:
-
-VP8
-===
-
-
-:title:     RFC 6386: "VP8 Data Format and Decoding Guide"
-
-:author:    J. Bankoski et al.
diff --git a/Documentation/media/uapi/v4l/buffer.rst b/Documentation/media/uapi/v4l/buffer.rst
deleted file mode 100644
index 3112300c2fa0..000000000000
--- a/Documentation/media/uapi/v4l/buffer.rst
+++ /dev/null
@@ -1,817 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _buffer:
-
-*******
-Buffers
-*******
-
-A buffer contains data exchanged by application and driver using one of
-the Streaming I/O methods. In the multi-planar API, the data is held in
-planes, while the buffer structure acts as a container for the planes.
-Only pointers to buffers (planes) are exchanged, the data itself is not
-copied. These pointers, together with meta-information like timestamps
-or field parity, are stored in a struct :c:type:`v4l2_buffer`,
-argument to the :ref:`VIDIOC_QUERYBUF`,
-:ref:`VIDIOC_QBUF <VIDIOC_QBUF>` and
-:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl. In the multi-planar API,
-some plane-specific members of struct :c:type:`v4l2_buffer`,
-such as pointers and sizes for each plane, are stored in struct
-struct :c:type:`v4l2_plane` instead. In that case, struct
-struct :c:type:`v4l2_buffer` contains an array of plane structures.
-
-Dequeued video buffers come with timestamps. The driver decides at which
-part of the frame and with which clock the timestamp is taken. Please
-see flags in the masks ``V4L2_BUF_FLAG_TIMESTAMP_MASK`` and
-``V4L2_BUF_FLAG_TSTAMP_SRC_MASK`` in :ref:`buffer-flags`. These flags
-are always valid and constant across all buffers during the whole video
-stream. Changes in these flags may take place as a side effect of
-:ref:`VIDIOC_S_INPUT <VIDIOC_G_INPUT>` or
-:ref:`VIDIOC_S_OUTPUT <VIDIOC_G_OUTPUT>` however. The
-``V4L2_BUF_FLAG_TIMESTAMP_COPY`` timestamp type which is used by e.g. on
-mem-to-mem devices is an exception to the rule: the timestamp source
-flags are copied from the OUTPUT video buffer to the CAPTURE video
-buffer.
-
-
-Interactions between formats, controls and buffers
-==================================================
-
-V4L2 exposes parameters that influence the buffer size, or the way data is
-laid out in the buffer. Those parameters are exposed through both formats and
-controls. One example of such a control is the ``V4L2_CID_ROTATE`` control
-that modifies the direction in which pixels are stored in the buffer, as well
-as the buffer size when the selected format includes padding at the end of
-lines.
-
-The set of information needed to interpret the content of a buffer (e.g. the
-pixel format, the line stride, the tiling orientation or the rotation) is
-collectively referred to in the rest of this section as the buffer layout.
-
-Controls that can modify the buffer layout shall set the
-``V4L2_CTRL_FLAG_MODIFY_LAYOUT`` flag.
-
-Modifying formats or controls that influence the buffer size or layout require
-the stream to be stopped. Any attempt at such a modification while the stream
-is active shall cause the ioctl setting the format or the control to return
-the ``EBUSY`` error code. In that case drivers shall also set the
-``V4L2_CTRL_FLAG_GRABBED`` flag when calling
-:c:func:`VIDIOC_QUERYCTRL` or :c:func:`VIDIOC_QUERY_EXT_CTRL` for such a
-control while the stream is active.
-
-.. note::
-
-   The :c:func:`VIDIOC_S_SELECTION` ioctl can, depending on the hardware (for
-   instance if the device doesn't include a scaler), modify the format in
-   addition to the selection rectangle. Similarly, the
-   :c:func:`VIDIOC_S_INPUT`, :c:func:`VIDIOC_S_OUTPUT`, :c:func:`VIDIOC_S_STD`
-   and :c:func:`VIDIOC_S_DV_TIMINGS` ioctls can also modify the format and
-   selection rectangles. When those ioctls result in a buffer size or layout
-   change, drivers shall handle that condition as they would handle it in the
-   :c:func:`VIDIOC_S_FMT` ioctl in all cases described in this section.
-
-Controls that only influence the buffer layout can be modified at any time
-when the stream is stopped. As they don't influence the buffer size, no
-special handling is needed to synchronize those controls with buffer
-allocation and the ``V4L2_CTRL_FLAG_GRABBED`` flag is cleared once the
-stream is stopped.
-
-Formats and controls that influence the buffer size interact with buffer
-allocation. The simplest way to handle this is for drivers to always require
-buffers to be reallocated in order to change those formats or controls. In
-that case, to perform such changes, userspace applications shall first stop
-the video stream with the :c:func:`VIDIOC_STREAMOFF` ioctl if it is running
-and free all buffers with the :c:func:`VIDIOC_REQBUFS` ioctl if they are
-allocated. After freeing all buffers the ``V4L2_CTRL_FLAG_GRABBED`` flag
-for controls is cleared. The format or controls can then be modified, and
-buffers shall then be reallocated and the stream restarted. A typical ioctl
-sequence is
-
- #. VIDIOC_STREAMOFF
- #. VIDIOC_REQBUFS(0)
- #. VIDIOC_S_EXT_CTRLS
- #. VIDIOC_S_FMT
- #. VIDIOC_REQBUFS(n)
- #. VIDIOC_QBUF
- #. VIDIOC_STREAMON
-
-The second :c:func:`VIDIOC_REQBUFS` call will take the new format and control
-value into account to compute the buffer size to allocate. Applications can
-also retrieve the size by calling the :c:func:`VIDIOC_G_FMT` ioctl if needed.
-
-.. note::
-
-   The API doesn't mandate the above order for control (3.) and format (4.)
-   changes. Format and controls can be set in a different order, or even
-   interleaved, depending on the device and use case. For instance some
-   controls might behave differently for different pixel formats, in which
-   case the format might need to be set first.
-
-When reallocation is required, any attempt to modify format or controls that
-influences the buffer size while buffers are allocated shall cause the format
-or control set ioctl to return the ``EBUSY`` error. Any attempt to queue a
-buffer too small for the current format or controls shall cause the
-:c:func:`VIDIOC_QBUF` ioctl to return a ``EINVAL`` error.
-
-Buffer reallocation is an expensive operation. To avoid that cost, drivers can
-(and are encouraged to) allow format or controls that influence the buffer
-size to be changed with buffers allocated. In that case, a typical ioctl
-sequence to modify format and controls is
-
- #. VIDIOC_STREAMOFF
- #. VIDIOC_S_EXT_CTRLS
- #. VIDIOC_S_FMT
- #. VIDIOC_QBUF
- #. VIDIOC_STREAMON
-
-For this sequence to operate correctly, queued buffers need to be large enough
-for the new format or controls. Drivers shall return a ``ENOSPC`` error in
-response to format change (:c:func:`VIDIOC_S_FMT`) or control changes
-(:c:func:`VIDIOC_S_CTRL` or :c:func:`VIDIOC_S_EXT_CTRLS`) if buffers too small
-for the new format are currently queued. As a simplification, drivers are
-allowed to return a ``EBUSY`` error from these ioctls if any buffer is
-currently queued, without checking the queued buffers sizes.
-
-Additionally, drivers shall return a ``EINVAL`` error from the
-:c:func:`VIDIOC_QBUF` ioctl if the buffer being queued is too small for the
-current format or controls. Together, these requirements ensure that queued
-buffers will always be large enough for the configured format and controls.
-
-Userspace applications can query the buffer size required for a given format
-and controls by first setting the desired control values and then trying the
-desired format. The :c:func:`VIDIOC_TRY_FMT` ioctl will return the required
-buffer size.
-
- #. VIDIOC_S_EXT_CTRLS(x)
- #. VIDIOC_TRY_FMT()
- #. VIDIOC_S_EXT_CTRLS(y)
- #. VIDIOC_TRY_FMT()
-
-The :c:func:`VIDIOC_CREATE_BUFS` ioctl can then be used to allocate buffers
-based on the queried sizes (for instance by allocating a set of buffers large
-enough for all the desired formats and controls, or by allocating separate set
-of appropriately sized buffers for each use case).
-
-
-.. c:type:: v4l2_buffer
-
-struct v4l2_buffer
-==================
-
-.. tabularcolumns:: |p{2.8cm}|p{2.5cm}|p{1.6cm}|p{10.2cm}|
-
-.. cssclass:: longtable
-
-.. flat-table:: struct v4l2_buffer
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 2 10
-
-    * - __u32
-      - ``index``
-      - Number of the buffer, set by the application except when calling
-	:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>`, then it is set by the
-	driver. This field can range from zero to the number of buffers
-	allocated with the :ref:`VIDIOC_REQBUFS` ioctl
-	(struct :c:type:`v4l2_requestbuffers`
-	``count``), plus any buffers allocated with
-	:ref:`VIDIOC_CREATE_BUFS` minus one.
-    * - __u32
-      - ``type``
-      - Type of the buffer, same as struct
-	:c:type:`v4l2_format` ``type`` or struct
-	:c:type:`v4l2_requestbuffers` ``type``, set
-	by the application. See :c:type:`v4l2_buf_type`
-    * - __u32
-      - ``bytesused``
-      - The number of bytes occupied by the data in the buffer. It depends
-	on the negotiated data format and may change with each buffer for
-	compressed variable size data like JPEG images. Drivers must set
-	this field when ``type`` refers to a capture stream, applications
-	when it refers to an output stream. If the application sets this
-	to 0 for an output stream, then ``bytesused`` will be set to the
-	size of the buffer (see the ``length`` field of this struct) by
-	the driver. For multiplanar formats this field is ignored and the
-	``planes`` pointer is used instead.
-    * - __u32
-      - ``flags``
-      - Flags set by the application or driver, see :ref:`buffer-flags`.
-    * - __u32
-      - ``field``
-      - Indicates the field order of the image in the buffer, see
-	:c:type:`v4l2_field`. This field is not used when the buffer
-	contains VBI data. Drivers must set it when ``type`` refers to a
-	capture stream, applications when it refers to an output stream.
-    * - struct timeval
-      - ``timestamp``
-      - For capture streams this is time when the first data byte was
-	captured, as returned by the :c:func:`clock_gettime()` function
-	for the relevant clock id; see ``V4L2_BUF_FLAG_TIMESTAMP_*`` in
-	:ref:`buffer-flags`. For output streams the driver stores the
-	time at which the last data byte was actually sent out in the
-	``timestamp`` field. This permits applications to monitor the
-	drift between the video and system clock. For output streams that
-	use ``V4L2_BUF_FLAG_TIMESTAMP_COPY`` the application has to fill
-	in the timestamp which will be copied by the driver to the capture
-	stream.
-    * - struct :c:type:`v4l2_timecode`
-      - ``timecode``
-      - When the ``V4L2_BUF_FLAG_TIMECODE`` flag is set in ``flags``, this
-	structure contains a frame timecode. In
-	:c:type:`V4L2_FIELD_ALTERNATE <v4l2_field>` mode the top and
-	bottom field contain the same timecode. Timecodes are intended to
-	help video editing and are typically recorded on video tapes, but
-	also embedded in compressed formats like MPEG. This field is
-	independent of the ``timestamp`` and ``sequence`` fields.
-    * - __u32
-      - ``sequence``
-      - Set by the driver, counting the frames (not fields!) in sequence.
-	This field is set for both input and output devices.
-    * - :cspan:`2`
-
-	In :c:type:`V4L2_FIELD_ALTERNATE <v4l2_field>` mode the top and
-	bottom field have the same sequence number. The count starts at
-	zero and includes dropped or repeated frames. A dropped frame was
-	received by an input device but could not be stored due to lack of
-	free buffer space. A repeated frame was displayed again by an
-	output device because the application did not pass new data in
-	time.
-
-	.. note::
-
-	   This may count the frames received e.g. over USB, without
-	   taking into account the frames dropped by the remote hardware due
-	   to limited compression throughput or bus bandwidth. These devices
-	   identify by not enumerating any video standards, see
-	   :ref:`standard`.
-
-    * - __u32
-      - ``memory``
-      - This field must be set by applications and/or drivers in
-	accordance with the selected I/O method. See :c:type:`v4l2_memory`
-    * - union {
-      - ``m``
-    * - __u32
-      - ``offset``
-      - For the single-planar API and when ``memory`` is
-	``V4L2_MEMORY_MMAP`` this is the offset of the buffer from the
-	start of the device memory. The value is returned by the driver
-	and apart of serving as parameter to the
-	:ref:`mmap() <func-mmap>` function not useful for applications.
-	See :ref:`mmap` for details
-    * - unsigned long
-      - ``userptr``
-      - For the single-planar API and when ``memory`` is
-	``V4L2_MEMORY_USERPTR`` this is a pointer to the buffer (casted to
-	unsigned long type) in virtual memory, set by the application. See
-	:ref:`userp` for details.
-    * - struct v4l2_plane
-      - ``*planes``
-      - When using the multi-planar API, contains a userspace pointer to
-	an array of struct :c:type:`v4l2_plane`. The size of
-	the array should be put in the ``length`` field of this
-	struct :c:type:`v4l2_buffer` structure.
-    * - int
-      - ``fd``
-      - For the single-plane API and when ``memory`` is
-	``V4L2_MEMORY_DMABUF`` this is the file descriptor associated with
-	a DMABUF buffer.
-    * - }
-      -
-    * - __u32
-      - ``length``
-      - Size of the buffer (not the payload) in bytes for the
-	single-planar API. This is set by the driver based on the calls to
-	:ref:`VIDIOC_REQBUFS` and/or
-	:ref:`VIDIOC_CREATE_BUFS`. For the
-	multi-planar API the application sets this to the number of
-	elements in the ``planes`` array. The driver will fill in the
-	actual number of valid elements in that array.
-    * - __u32
-      - ``reserved2``
-      - A place holder for future extensions. Drivers and applications
-	must set this to 0.
-    * - __u32
-      - ``request_fd``
-      - The file descriptor of the request to queue the buffer to. If the flag
-        ``V4L2_BUF_FLAG_REQUEST_FD`` is set, then the buffer will be
-	queued to this request. If the flag is not set, then this field will
-	be ignored.
-
-	The ``V4L2_BUF_FLAG_REQUEST_FD`` flag and this field are only used by
-	:ref:`ioctl VIDIOC_QBUF <VIDIOC_QBUF>` and ignored by other ioctls that
-	take a :c:type:`v4l2_buffer` as argument.
-
-	Applications should not set ``V4L2_BUF_FLAG_REQUEST_FD`` for any ioctls
-	other than :ref:`VIDIOC_QBUF <VIDIOC_QBUF>`.
-
-	If the device does not support requests, then ``EBADR`` will be returned.
-	If requests are supported but an invalid request file descriptor is
-	given, then ``EINVAL`` will be returned.
-
-
-
-.. c:type:: v4l2_plane
-
-struct v4l2_plane
-=================
-
-.. tabularcolumns:: |p{3.5cm}|p{3.5cm}|p{3.5cm}|p{7.0cm}|
-
-.. cssclass:: longtable
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``bytesused``
-      - The number of bytes occupied by data in the plane (its payload).
-	Drivers must set this field when ``type`` refers to a capture
-	stream, applications when it refers to an output stream. If the
-	application sets this to 0 for an output stream, then
-	``bytesused`` will be set to the size of the plane (see the
-	``length`` field of this struct) by the driver.
-
-	.. note::
-
-	   Note that the actual image data starts at ``data_offset``
-	   which may not be 0.
-    * - __u32
-      - ``length``
-      - Size in bytes of the plane (not its payload). This is set by the
-	driver based on the calls to
-	:ref:`VIDIOC_REQBUFS` and/or
-	:ref:`VIDIOC_CREATE_BUFS`.
-    * - union {
-      - ``m``
-    * - __u32
-      - ``mem_offset``
-      - When the memory type in the containing struct
-	:c:type:`v4l2_buffer` is ``V4L2_MEMORY_MMAP``, this
-	is the value that should be passed to :ref:`mmap() <func-mmap>`,
-	similar to the ``offset`` field in struct
-	:c:type:`v4l2_buffer`.
-    * - unsigned long
-      - ``userptr``
-      - When the memory type in the containing struct
-	:c:type:`v4l2_buffer` is ``V4L2_MEMORY_USERPTR``,
-	this is a userspace pointer to the memory allocated for this plane
-	by an application.
-    * - int
-      - ``fd``
-      - When the memory type in the containing struct
-	:c:type:`v4l2_buffer` is ``V4L2_MEMORY_DMABUF``,
-	this is a file descriptor associated with a DMABUF buffer, similar
-	to the ``fd`` field in struct :c:type:`v4l2_buffer`.
-    * - }
-      -
-    * - __u32
-      - ``data_offset``
-      - Offset in bytes to video data in the plane. Drivers must set this
-	field when ``type`` refers to a capture stream, applications when
-	it refers to an output stream.
-
-	.. note::
-
-	   That data_offset is included  in ``bytesused``. So the
-	   size of the image in the plane is ``bytesused``-``data_offset``
-	   at offset ``data_offset`` from the start of the plane.
-    * - __u32
-      - ``reserved[11]``
-      - Reserved for future use. Should be zeroed by drivers and
-	applications.
-
-
-
-.. c:type:: v4l2_buf_type
-
-enum v4l2_buf_type
-==================
-
-.. cssclass:: longtable
-
-.. tabularcolumns:: |p{7.8cm}|p{0.6cm}|p{9.1cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       4 1 9
-
-    * - ``V4L2_BUF_TYPE_VIDEO_CAPTURE``
-      - 1
-      - Buffer of a single-planar video capture stream, see
-	:ref:`capture`.
-    * - ``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE``
-      - 9
-      - Buffer of a multi-planar video capture stream, see
-	:ref:`capture`.
-    * - ``V4L2_BUF_TYPE_VIDEO_OUTPUT``
-      - 2
-      - Buffer of a single-planar video output stream, see
-	:ref:`output`.
-    * - ``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE``
-      - 10
-      - Buffer of a multi-planar video output stream, see :ref:`output`.
-    * - ``V4L2_BUF_TYPE_VIDEO_OVERLAY``
-      - 3
-      - Buffer for video overlay, see :ref:`overlay`.
-    * - ``V4L2_BUF_TYPE_VBI_CAPTURE``
-      - 4
-      - Buffer of a raw VBI capture stream, see :ref:`raw-vbi`.
-    * - ``V4L2_BUF_TYPE_VBI_OUTPUT``
-      - 5
-      - Buffer of a raw VBI output stream, see :ref:`raw-vbi`.
-    * - ``V4L2_BUF_TYPE_SLICED_VBI_CAPTURE``
-      - 6
-      - Buffer of a sliced VBI capture stream, see :ref:`sliced`.
-    * - ``V4L2_BUF_TYPE_SLICED_VBI_OUTPUT``
-      - 7
-      - Buffer of a sliced VBI output stream, see :ref:`sliced`.
-    * - ``V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY``
-      - 8
-      - Buffer for video output overlay (OSD), see :ref:`osd`.
-    * - ``V4L2_BUF_TYPE_SDR_CAPTURE``
-      - 11
-      - Buffer for Software Defined Radio (SDR) capture stream, see
-	:ref:`sdr`.
-    * - ``V4L2_BUF_TYPE_SDR_OUTPUT``
-      - 12
-      - Buffer for Software Defined Radio (SDR) output stream, see
-	:ref:`sdr`.
-    * - ``V4L2_BUF_TYPE_META_CAPTURE``
-      - 13
-      - Buffer for metadata capture, see :ref:`metadata`.
-    * - ``V4L2_BUF_TYPE_META_OUTPUT``
-      - 14
-      - Buffer for metadata output, see :ref:`metadata`.
-
-
-
-.. _buffer-flags:
-
-Buffer Flags
-============
-
-.. raw:: latex
-
-    \small
-
-.. tabularcolumns:: |p{7.0cm}|p{2.1cm}|p{8.4cm}|
-
-.. cssclass:: longtable
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * .. _`V4L2-BUF-FLAG-MAPPED`:
-
-      - ``V4L2_BUF_FLAG_MAPPED``
-      - 0x00000001
-      - The buffer resides in device memory and has been mapped into the
-	application's address space, see :ref:`mmap` for details.
-	Drivers set or clear this flag when the
-	:ref:`VIDIOC_QUERYBUF`,
-	:ref:`VIDIOC_QBUF` or
-	:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl is called. Set by the
-	driver.
-    * .. _`V4L2-BUF-FLAG-QUEUED`:
-
-      - ``V4L2_BUF_FLAG_QUEUED``
-      - 0x00000002
-      - Internally drivers maintain two buffer queues, an incoming and
-	outgoing queue. When this flag is set, the buffer is currently on
-	the incoming queue. It automatically moves to the outgoing queue
-	after the buffer has been filled (capture devices) or displayed
-	(output devices). Drivers set or clear this flag when the
-	``VIDIOC_QUERYBUF`` ioctl is called. After (successful) calling
-	the ``VIDIOC_QBUF``\ ioctl it is always set and after
-	``VIDIOC_DQBUF`` always cleared.
-    * .. _`V4L2-BUF-FLAG-DONE`:
-
-      - ``V4L2_BUF_FLAG_DONE``
-      - 0x00000004
-      - When this flag is set, the buffer is currently on the outgoing
-	queue, ready to be dequeued from the driver. Drivers set or clear
-	this flag when the ``VIDIOC_QUERYBUF`` ioctl is called. After
-	calling the ``VIDIOC_QBUF`` or ``VIDIOC_DQBUF`` it is always
-	cleared. Of course a buffer cannot be on both queues at the same
-	time, the ``V4L2_BUF_FLAG_QUEUED`` and ``V4L2_BUF_FLAG_DONE`` flag
-	are mutually exclusive. They can be both cleared however, then the
-	buffer is in "dequeued" state, in the application domain so to
-	say.
-    * .. _`V4L2-BUF-FLAG-ERROR`:
-
-      - ``V4L2_BUF_FLAG_ERROR``
-      - 0x00000040
-      - When this flag is set, the buffer has been dequeued successfully,
-	although the data might have been corrupted. This is recoverable,
-	streaming may continue as normal and the buffer may be reused
-	normally. Drivers set this flag when the ``VIDIOC_DQBUF`` ioctl is
-	called.
-    * .. _`V4L2-BUF-FLAG-IN-REQUEST`:
-
-      - ``V4L2_BUF_FLAG_IN_REQUEST``
-      - 0x00000080
-      - This buffer is part of a request that hasn't been queued yet.
-    * .. _`V4L2-BUF-FLAG-KEYFRAME`:
-
-      - ``V4L2_BUF_FLAG_KEYFRAME``
-      - 0x00000008
-      - Drivers set or clear this flag when calling the ``VIDIOC_DQBUF``
-	ioctl. It may be set by video capture devices when the buffer
-	contains a compressed image which is a key frame (or field), i. e.
-	can be decompressed on its own. Also known as an I-frame.
-	Applications can set this bit when ``type`` refers to an output
-	stream.
-    * .. _`V4L2-BUF-FLAG-PFRAME`:
-
-      - ``V4L2_BUF_FLAG_PFRAME``
-      - 0x00000010
-      - Similar to ``V4L2_BUF_FLAG_KEYFRAME`` this flags predicted frames
-	or fields which contain only differences to a previous key frame.
-	Applications can set this bit when ``type`` refers to an output
-	stream.
-    * .. _`V4L2-BUF-FLAG-BFRAME`:
-
-      - ``V4L2_BUF_FLAG_BFRAME``
-      - 0x00000020
-      - Similar to ``V4L2_BUF_FLAG_KEYFRAME`` this flags a bi-directional
-	predicted frame or field which contains only the differences
-	between the current frame and both the preceding and following key
-	frames to specify its content. Applications can set this bit when
-	``type`` refers to an output stream.
-    * .. _`V4L2-BUF-FLAG-TIMECODE`:
-
-      - ``V4L2_BUF_FLAG_TIMECODE``
-      - 0x00000100
-      - The ``timecode`` field is valid. Drivers set or clear this flag
-	when the ``VIDIOC_DQBUF`` ioctl is called. Applications can set
-	this bit and the corresponding ``timecode`` structure when
-	``type`` refers to an output stream.
-    * .. _`V4L2-BUF-FLAG-PREPARED`:
-
-      - ``V4L2_BUF_FLAG_PREPARED``
-      - 0x00000400
-      - The buffer has been prepared for I/O and can be queued by the
-	application. Drivers set or clear this flag when the
-	:ref:`VIDIOC_QUERYBUF`,
-	:ref:`VIDIOC_PREPARE_BUF <VIDIOC_QBUF>`,
-	:ref:`VIDIOC_QBUF` or
-	:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl is called.
-    * .. _`V4L2-BUF-FLAG-NO-CACHE-INVALIDATE`:
-
-      - ``V4L2_BUF_FLAG_NO_CACHE_INVALIDATE``
-      - 0x00000800
-      - Caches do not have to be invalidated for this buffer. Typically
-	applications shall use this flag if the data captured in the
-	buffer is not going to be touched by the CPU, instead the buffer
-	will, probably, be passed on to a DMA-capable hardware unit for
-	further processing or output.
-    * .. _`V4L2-BUF-FLAG-NO-CACHE-CLEAN`:
-
-      - ``V4L2_BUF_FLAG_NO_CACHE_CLEAN``
-      - 0x00001000
-      - Caches do not have to be cleaned for this buffer. Typically
-	applications shall use this flag for output buffers if the data in
-	this buffer has not been created by the CPU but by some
-	DMA-capable unit, in which case caches have not been used.
-    * .. _`V4L2-BUF-FLAG-M2M-HOLD-CAPTURE-BUF`:
-
-      - ``V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF``
-      - 0x00000200
-      - Only valid if ``V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF`` is
-	set. It is typically used with stateless decoders where multiple
-	output buffers each decode to a slice of the decoded frame.
-	Applications can set this flag when queueing the output buffer
-	to prevent the driver from dequeueing the capture buffer after
-	the output buffer has been decoded (i.e. the capture buffer is
-	'held'). If the timestamp of this output buffer differs from that
-	of the previous output buffer, then that indicates the start of a
-	new frame and the previously held capture buffer is dequeued.
-    * .. _`V4L2-BUF-FLAG-LAST`:
-
-      - ``V4L2_BUF_FLAG_LAST``
-      - 0x00100000
-      - Last buffer produced by the hardware. mem2mem codec drivers set
-	this flag on the capture queue for the last buffer when the
-	:ref:`VIDIOC_QUERYBUF` or
-	:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl is called. Due to
-	hardware limitations, the last buffer may be empty. In this case
-	the driver will set the ``bytesused`` field to 0, regardless of
-	the format. Any Any subsequent call to the
-	:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl will not block anymore,
-	but return an ``EPIPE`` error code.
-    * .. _`V4L2-BUF-FLAG-REQUEST-FD`:
-
-      - ``V4L2_BUF_FLAG_REQUEST_FD``
-      - 0x00800000
-      - The ``request_fd`` field contains a valid file descriptor.
-    * .. _`V4L2-BUF-FLAG-TIMESTAMP-MASK`:
-
-      - ``V4L2_BUF_FLAG_TIMESTAMP_MASK``
-      - 0x0000e000
-      - Mask for timestamp types below. To test the timestamp type, mask
-	out bits not belonging to timestamp type by performing a logical
-	and operation with buffer flags and timestamp mask.
-    * .. _`V4L2-BUF-FLAG-TIMESTAMP-UNKNOWN`:
-
-      - ``V4L2_BUF_FLAG_TIMESTAMP_UNKNOWN``
-      - 0x00000000
-      - Unknown timestamp type. This type is used by drivers before Linux
-	3.9 and may be either monotonic (see below) or realtime (wall
-	clock). Monotonic clock has been favoured in embedded systems
-	whereas most of the drivers use the realtime clock. Either kinds
-	of timestamps are available in user space via
-	:c:func:`clock_gettime` using clock IDs ``CLOCK_MONOTONIC``
-	and ``CLOCK_REALTIME``, respectively.
-    * .. _`V4L2-BUF-FLAG-TIMESTAMP-MONOTONIC`:
-
-      - ``V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC``
-      - 0x00002000
-      - The buffer timestamp has been taken from the ``CLOCK_MONOTONIC``
-	clock. To access the same clock outside V4L2, use
-	:c:func:`clock_gettime`.
-    * .. _`V4L2-BUF-FLAG-TIMESTAMP-COPY`:
-
-      - ``V4L2_BUF_FLAG_TIMESTAMP_COPY``
-      - 0x00004000
-      - The CAPTURE buffer timestamp has been taken from the corresponding
-	OUTPUT buffer. This flag applies only to mem2mem devices.
-    * .. _`V4L2-BUF-FLAG-TSTAMP-SRC-MASK`:
-
-      - ``V4L2_BUF_FLAG_TSTAMP_SRC_MASK``
-      - 0x00070000
-      - Mask for timestamp sources below. The timestamp source defines the
-	point of time the timestamp is taken in relation to the frame.
-	Logical 'and' operation between the ``flags`` field and
-	``V4L2_BUF_FLAG_TSTAMP_SRC_MASK`` produces the value of the
-	timestamp source. Applications must set the timestamp source when
-	``type`` refers to an output stream and
-	``V4L2_BUF_FLAG_TIMESTAMP_COPY`` is set.
-    * .. _`V4L2-BUF-FLAG-TSTAMP-SRC-EOF`:
-
-      - ``V4L2_BUF_FLAG_TSTAMP_SRC_EOF``
-      - 0x00000000
-      - End Of Frame. The buffer timestamp has been taken when the last
-	pixel of the frame has been received or the last pixel of the
-	frame has been transmitted. In practice, software generated
-	timestamps will typically be read from the clock a small amount of
-	time after the last pixel has been received or transmitten,
-	depending on the system and other activity in it.
-    * .. _`V4L2-BUF-FLAG-TSTAMP-SRC-SOE`:
-
-      - ``V4L2_BUF_FLAG_TSTAMP_SRC_SOE``
-      - 0x00010000
-      - Start Of Exposure. The buffer timestamp has been taken when the
-	exposure of the frame has begun. This is only valid for the
-	``V4L2_BUF_TYPE_VIDEO_CAPTURE`` buffer type.
-
-.. raw:: latex
-
-    \normalsize
-
-
-.. c:type:: v4l2_memory
-
-enum v4l2_memory
-================
-
-.. tabularcolumns:: |p{5.0cm}|p{0.8cm}|p{11.7cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_MEMORY_MMAP``
-      - 1
-      - The buffer is used for :ref:`memory mapping <mmap>` I/O.
-    * - ``V4L2_MEMORY_USERPTR``
-      - 2
-      - The buffer is used for :ref:`user pointer <userp>` I/O.
-    * - ``V4L2_MEMORY_OVERLAY``
-      - 3
-      - [to do]
-    * - ``V4L2_MEMORY_DMABUF``
-      - 4
-      - The buffer is used for :ref:`DMA shared buffer <dmabuf>` I/O.
-
-
-
-Timecodes
-=========
-
-The :c:type:`v4l2_buffer_timecode` structure is designed to hold a
-:ref:`smpte12m` or similar timecode.
-(struct :c:type:`timeval` timestamps are stored in the struct
-:c:type:`v4l2_buffer` ``timestamp`` field.)
-
-
-.. c:type:: v4l2_timecode
-
-struct v4l2_timecode
---------------------
-
-.. tabularcolumns:: |p{1.4cm}|p{2.8cm}|p{12.3cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``type``
-      - Frame rate the timecodes are based on, see :ref:`timecode-type`.
-    * - __u32
-      - ``flags``
-      - Timecode flags, see :ref:`timecode-flags`.
-    * - __u8
-      - ``frames``
-      - Frame count, 0 ... 23/24/29/49/59, depending on the type of
-	timecode.
-    * - __u8
-      - ``seconds``
-      - Seconds count, 0 ... 59. This is a binary, not BCD number.
-    * - __u8
-      - ``minutes``
-      - Minutes count, 0 ... 59. This is a binary, not BCD number.
-    * - __u8
-      - ``hours``
-      - Hours count, 0 ... 29. This is a binary, not BCD number.
-    * - __u8
-      - ``userbits``\ [4]
-      - The "user group" bits from the timecode.
-
-
-
-.. _timecode-type:
-
-Timecode Types
---------------
-
-.. tabularcolumns:: |p{5.6cm}|p{0.8cm}|p{11.1cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_TC_TYPE_24FPS``
-      - 1
-      - 24 frames per second, i. e. film.
-    * - ``V4L2_TC_TYPE_25FPS``
-      - 2
-      - 25 frames per second, i. e. PAL or SECAM video.
-    * - ``V4L2_TC_TYPE_30FPS``
-      - 3
-      - 30 frames per second, i. e. NTSC video.
-    * - ``V4L2_TC_TYPE_50FPS``
-      - 4
-      -
-    * - ``V4L2_TC_TYPE_60FPS``
-      - 5
-      -
-
-
-
-.. _timecode-flags:
-
-Timecode Flags
---------------
-
-.. tabularcolumns:: |p{6.6cm}|p{1.4cm}|p{9.5cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_TC_FLAG_DROPFRAME``
-      - 0x0001
-      - Indicates "drop frame" semantics for counting frames in 29.97 fps
-	material. When set, frame numbers 0 and 1 at the start of each
-	minute, except minutes 0, 10, 20, 30, 40, 50 are omitted from the
-	count.
-    * - ``V4L2_TC_FLAG_COLORFRAME``
-      - 0x0002
-      - The "color frame" flag.
-    * - ``V4L2_TC_USERBITS_field``
-      - 0x000C
-      - Field mask for the "binary group flags".
-    * - ``V4L2_TC_USERBITS_USERDEFINED``
-      - 0x0000
-      - Unspecified format.
-    * - ``V4L2_TC_USERBITS_8BITCHARS``
-      - 0x0008
-      - 8-bit ISO characters.
diff --git a/Documentation/media/uapi/v4l/capture-example.rst b/Documentation/media/uapi/v4l/capture-example.rst
deleted file mode 100644
index 130ca47ef796..000000000000
--- a/Documentation/media/uapi/v4l/capture-example.rst
+++ /dev/null
@@ -1,20 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _capture-example:
-
-*********************
-Video Capture Example
-*********************
-
-
-.. toctree::
-    :maxdepth: 1
-
-    capture.c
diff --git a/Documentation/media/uapi/v4l/capture.c.rst b/Documentation/media/uapi/v4l/capture.c.rst
deleted file mode 100644
index b4652c2351f2..000000000000
--- a/Documentation/media/uapi/v4l/capture.c.rst
+++ /dev/null
@@ -1,671 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-file: media/v4l/capture.c
-=========================
-
-.. code-block:: c
-
-    /*
-     *  V4L2 video capture example
-     *
-     *  This program can be used and distributed without restrictions.
-     *
-     *      This program is provided with the V4L2 API
-     * see https://linuxtv.org/docs.php for more information
-     */
-
-    #include <stdio.h>
-    #include <stdlib.h>
-    #include <string.h>
-    #include <assert.h>
-
-    #include <getopt.h>             /* getopt_long() */
-
-    #include <fcntl.h>              /* low-level i/o */
-    #include <unistd.h>
-    #include <errno.h>
-    #include <sys/stat.h>
-    #include <sys/types.h>
-    #include <sys/time.h>
-    #include <sys/mman.h>
-    #include <sys/ioctl.h>
-
-    #include <linux/videodev2.h>
-
-    #define CLEAR(x) memset(&(x), 0, sizeof(x))
-
-    enum io_method {
-	    IO_METHOD_READ,
-	    IO_METHOD_MMAP,
-	    IO_METHOD_USERPTR,
-    };
-
-    struct buffer {
-	    void   *start;
-	    size_t  length;
-    };
-
-    static char            *dev_name;
-    static enum io_method   io = IO_METHOD_MMAP;
-    static int              fd = -1;
-    struct buffer          *buffers;
-    static unsigned int     n_buffers;
-    static int              out_buf;
-    static int              force_format;
-    static int              frame_count = 70;
-
-    static void errno_exit(const char *s)
-    {
-	    fprintf(stderr, "%s error %d, %s\\n", s, errno, strerror(errno));
-	    exit(EXIT_FAILURE);
-    }
-
-    static int xioctl(int fh, int request, void *arg)
-    {
-	    int r;
-
-	    do {
-		    r = ioctl(fh, request, arg);
-	    } while (-1 == r && EINTR == errno);
-
-	    return r;
-    }
-
-    static void process_image(const void *p, int size)
-    {
-	    if (out_buf)
-		    fwrite(p, size, 1, stdout);
-
-	    fflush(stderr);
-	    fprintf(stderr, ".");
-	    fflush(stdout);
-    }
-
-    static int read_frame(void)
-    {
-	    struct v4l2_buffer buf;
-	    unsigned int i;
-
-	    switch (io) {
-	    case IO_METHOD_READ:
-		    if (-1 == read(fd, buffers[0].start, buffers[0].length)) {
-			    switch (errno) {
-			    case EAGAIN:
-				    return 0;
-
-			    case EIO:
-				    /* Could ignore EIO, see spec. */
-
-				    /* fall through */
-
-			    default:
-				    errno_exit("read");
-			    }
-		    }
-
-		    process_image(buffers[0].start, buffers[0].length);
-		    break;
-
-	    case IO_METHOD_MMAP:
-		    CLEAR(buf);
-
-		    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-		    buf.memory = V4L2_MEMORY_MMAP;
-
-		    if (-1 == xioctl(fd, VIDIOC_DQBUF, &buf)) {
-			    switch (errno) {
-			    case EAGAIN:
-				    return 0;
-
-			    case EIO:
-				    /* Could ignore EIO, see spec. */
-
-				    /* fall through */
-
-			    default:
-				    errno_exit("VIDIOC_DQBUF");
-			    }
-		    }
-
-		    assert(buf.index < n_buffers);
-
-		    process_image(buffers[buf.index].start, buf.bytesused);
-
-		    if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))
-			    errno_exit("VIDIOC_QBUF");
-		    break;
-
-	    case IO_METHOD_USERPTR:
-		    CLEAR(buf);
-
-		    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-		    buf.memory = V4L2_MEMORY_USERPTR;
-
-		    if (-1 == xioctl(fd, VIDIOC_DQBUF, &buf)) {
-			    switch (errno) {
-			    case EAGAIN:
-				    return 0;
-
-			    case EIO:
-				    /* Could ignore EIO, see spec. */
-
-				    /* fall through */
-
-			    default:
-				    errno_exit("VIDIOC_DQBUF");
-			    }
-		    }
-
-		    for (i = 0; i < n_buffers; ++i)
-			    if (buf.m.userptr == (unsigned long)buffers[i].start
-				&& buf.length == buffers[i].length)
-				    break;
-
-		    assert(i < n_buffers);
-
-		    process_image((void *)buf.m.userptr, buf.bytesused);
-
-		    if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))
-			    errno_exit("VIDIOC_QBUF");
-		    break;
-	    }
-
-	    return 1;
-    }
-
-    static void mainloop(void)
-    {
-	    unsigned int count;
-
-	    count = frame_count;
-
-	    while (count-- > 0) {
-		    for (;;) {
-			    fd_set fds;
-			    struct timeval tv;
-			    int r;
-
-			    FD_ZERO(&fds);
-			    FD_SET(fd, &fds);
-
-			    /* Timeout. */
-			    tv.tv_sec = 2;
-			    tv.tv_usec = 0;
-
-			    r = select(fd + 1, &fds, NULL, NULL, &tv);
-
-			    if (-1 == r) {
-				    if (EINTR == errno)
-					    continue;
-				    errno_exit("select");
-			    }
-
-			    if (0 == r) {
-				    fprintf(stderr, "select timeout\\n");
-				    exit(EXIT_FAILURE);
-			    }
-
-			    if (read_frame())
-				    break;
-			    /* EAGAIN - continue select loop. */
-		    }
-	    }
-    }
-
-    static void stop_capturing(void)
-    {
-	    enum v4l2_buf_type type;
-
-	    switch (io) {
-	    case IO_METHOD_READ:
-		    /* Nothing to do. */
-		    break;
-
-	    case IO_METHOD_MMAP:
-	    case IO_METHOD_USERPTR:
-		    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-		    if (-1 == xioctl(fd, VIDIOC_STREAMOFF, &type))
-			    errno_exit("VIDIOC_STREAMOFF");
-		    break;
-	    }
-    }
-
-    static void start_capturing(void)
-    {
-	    unsigned int i;
-	    enum v4l2_buf_type type;
-
-	    switch (io) {
-	    case IO_METHOD_READ:
-		    /* Nothing to do. */
-		    break;
-
-	    case IO_METHOD_MMAP:
-		    for (i = 0; i < n_buffers; ++i) {
-			    struct v4l2_buffer buf;
-
-			    CLEAR(buf);
-			    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-			    buf.memory = V4L2_MEMORY_MMAP;
-			    buf.index = i;
-
-			    if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))
-				    errno_exit("VIDIOC_QBUF");
-		    }
-		    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-		    if (-1 == xioctl(fd, VIDIOC_STREAMON, &type))
-			    errno_exit("VIDIOC_STREAMON");
-		    break;
-
-	    case IO_METHOD_USERPTR:
-		    for (i = 0; i < n_buffers; ++i) {
-			    struct v4l2_buffer buf;
-
-			    CLEAR(buf);
-			    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-			    buf.memory = V4L2_MEMORY_USERPTR;
-			    buf.index = i;
-			    buf.m.userptr = (unsigned long)buffers[i].start;
-			    buf.length = buffers[i].length;
-
-			    if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))
-				    errno_exit("VIDIOC_QBUF");
-		    }
-		    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-		    if (-1 == xioctl(fd, VIDIOC_STREAMON, &type))
-			    errno_exit("VIDIOC_STREAMON");
-		    break;
-	    }
-    }
-
-    static void uninit_device(void)
-    {
-	    unsigned int i;
-
-	    switch (io) {
-	    case IO_METHOD_READ:
-		    free(buffers[0].start);
-		    break;
-
-	    case IO_METHOD_MMAP:
-		    for (i = 0; i < n_buffers; ++i)
-			    if (-1 == munmap(buffers[i].start, buffers[i].length))
-				    errno_exit("munmap");
-		    break;
-
-	    case IO_METHOD_USERPTR:
-		    for (i = 0; i < n_buffers; ++i)
-			    free(buffers[i].start);
-		    break;
-	    }
-
-	    free(buffers);
-    }
-
-    static void init_read(unsigned int buffer_size)
-    {
-	    buffers = calloc(1, sizeof(*buffers));
-
-	    if (!buffers) {
-		    fprintf(stderr, "Out of memory\\n");
-		    exit(EXIT_FAILURE);
-	    }
-
-	    buffers[0].length = buffer_size;
-	    buffers[0].start = malloc(buffer_size);
-
-	    if (!buffers[0].start) {
-		    fprintf(stderr, "Out of memory\\n");
-		    exit(EXIT_FAILURE);
-	    }
-    }
-
-    static void init_mmap(void)
-    {
-	    struct v4l2_requestbuffers req;
-
-	    CLEAR(req);
-
-	    req.count = 4;
-	    req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	    req.memory = V4L2_MEMORY_MMAP;
-
-	    if (-1 == xioctl(fd, VIDIOC_REQBUFS, &req)) {
-		    if (EINVAL == errno) {
-			    fprintf(stderr, "%s does not support "
-				     "memory mappingn", dev_name);
-			    exit(EXIT_FAILURE);
-		    } else {
-			    errno_exit("VIDIOC_REQBUFS");
-		    }
-	    }
-
-	    if (req.count < 2) {
-		    fprintf(stderr, "Insufficient buffer memory on %s\\n",
-			     dev_name);
-		    exit(EXIT_FAILURE);
-	    }
-
-	    buffers = calloc(req.count, sizeof(*buffers));
-
-	    if (!buffers) {
-		    fprintf(stderr, "Out of memory\\n");
-		    exit(EXIT_FAILURE);
-	    }
-
-	    for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {
-		    struct v4l2_buffer buf;
-
-		    CLEAR(buf);
-
-		    buf.type        = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-		    buf.memory      = V4L2_MEMORY_MMAP;
-		    buf.index       = n_buffers;
-
-		    if (-1 == xioctl(fd, VIDIOC_QUERYBUF, &buf))
-			    errno_exit("VIDIOC_QUERYBUF");
-
-		    buffers[n_buffers].length = buf.length;
-		    buffers[n_buffers].start =
-			    mmap(NULL /* start anywhere */,
-				  buf.length,
-				  PROT_READ | PROT_WRITE /* required */,
-				  MAP_SHARED /* recommended */,
-				  fd, buf.m.offset);
-
-		    if (MAP_FAILED == buffers[n_buffers].start)
-			    errno_exit("mmap");
-	    }
-    }
-
-    static void init_userp(unsigned int buffer_size)
-    {
-	    struct v4l2_requestbuffers req;
-
-	    CLEAR(req);
-
-	    req.count  = 4;
-	    req.type   = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	    req.memory = V4L2_MEMORY_USERPTR;
-
-	    if (-1 == xioctl(fd, VIDIOC_REQBUFS, &req)) {
-		    if (EINVAL == errno) {
-			    fprintf(stderr, "%s does not support "
-				     "user pointer i/on", dev_name);
-			    exit(EXIT_FAILURE);
-		    } else {
-			    errno_exit("VIDIOC_REQBUFS");
-		    }
-	    }
-
-	    buffers = calloc(4, sizeof(*buffers));
-
-	    if (!buffers) {
-		    fprintf(stderr, "Out of memory\\n");
-		    exit(EXIT_FAILURE);
-	    }
-
-	    for (n_buffers = 0; n_buffers < 4; ++n_buffers) {
-		    buffers[n_buffers].length = buffer_size;
-		    buffers[n_buffers].start = malloc(buffer_size);
-
-		    if (!buffers[n_buffers].start) {
-			    fprintf(stderr, "Out of memory\\n");
-			    exit(EXIT_FAILURE);
-		    }
-	    }
-    }
-
-    static void init_device(void)
-    {
-	    struct v4l2_capability cap;
-	    struct v4l2_cropcap cropcap;
-	    struct v4l2_crop crop;
-	    struct v4l2_format fmt;
-	    unsigned int min;
-
-	    if (-1 == xioctl(fd, VIDIOC_QUERYCAP, &cap)) {
-		    if (EINVAL == errno) {
-			    fprintf(stderr, "%s is no V4L2 device\\n",
-				     dev_name);
-			    exit(EXIT_FAILURE);
-		    } else {
-			    errno_exit("VIDIOC_QUERYCAP");
-		    }
-	    }
-
-	    if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
-		    fprintf(stderr, "%s is no video capture device\\n",
-			     dev_name);
-		    exit(EXIT_FAILURE);
-	    }
-
-	    switch (io) {
-	    case IO_METHOD_READ:
-		    if (!(cap.capabilities & V4L2_CAP_READWRITE)) {
-			    fprintf(stderr, "%s does not support read i/o\\n",
-				     dev_name);
-			    exit(EXIT_FAILURE);
-		    }
-		    break;
-
-	    case IO_METHOD_MMAP:
-	    case IO_METHOD_USERPTR:
-		    if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
-			    fprintf(stderr, "%s does not support streaming i/o\\n",
-				     dev_name);
-			    exit(EXIT_FAILURE);
-		    }
-		    break;
-	    }
-
-
-	    /* Select video input, video standard and tune here. */
-
-
-	    CLEAR(cropcap);
-
-	    cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
-	    if (0 == xioctl(fd, VIDIOC_CROPCAP, &cropcap)) {
-		    crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-		    crop.c = cropcap.defrect; /* reset to default */
-
-		    if (-1 == xioctl(fd, VIDIOC_S_CROP, &crop)) {
-			    switch (errno) {
-			    case EINVAL:
-				    /* Cropping not supported. */
-				    break;
-			    default:
-				    /* Errors ignored. */
-				    break;
-			    }
-		    }
-	    } else {
-		    /* Errors ignored. */
-	    }
-
-
-	    CLEAR(fmt);
-
-	    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	    if (force_format) {
-		    fmt.fmt.pix.width       = 640;
-		    fmt.fmt.pix.height      = 480;
-		    fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
-		    fmt.fmt.pix.field       = V4L2_FIELD_INTERLACED;
-
-		    if (-1 == xioctl(fd, VIDIOC_S_FMT, &fmt))
-			    errno_exit("VIDIOC_S_FMT");
-
-		    /* Note VIDIOC_S_FMT may change width and height. */
-	    } else {
-		    /* Preserve original settings as set by v4l2-ctl for example */
-		    if (-1 == xioctl(fd, VIDIOC_G_FMT, &fmt))
-			    errno_exit("VIDIOC_G_FMT");
-	    }
-
-	    /* Buggy driver paranoia. */
-	    min = fmt.fmt.pix.width * 2;
-	    if (fmt.fmt.pix.bytesperline < min)
-		    fmt.fmt.pix.bytesperline = min;
-	    min = fmt.fmt.pix.bytesperline * fmt.fmt.pix.height;
-	    if (fmt.fmt.pix.sizeimage < min)
-		    fmt.fmt.pix.sizeimage = min;
-
-	    switch (io) {
-	    case IO_METHOD_READ:
-		    init_read(fmt.fmt.pix.sizeimage);
-		    break;
-
-	    case IO_METHOD_MMAP:
-		    init_mmap();
-		    break;
-
-	    case IO_METHOD_USERPTR:
-		    init_userp(fmt.fmt.pix.sizeimage);
-		    break;
-	    }
-    }
-
-    static void close_device(void)
-    {
-	    if (-1 == close(fd))
-		    errno_exit("close");
-
-	    fd = -1;
-    }
-
-    static void open_device(void)
-    {
-	    struct stat st;
-
-	    if (-1 == stat(dev_name, &st)) {
-		    fprintf(stderr, "Cannot identify '%s': %d, %s\\n",
-			     dev_name, errno, strerror(errno));
-		    exit(EXIT_FAILURE);
-	    }
-
-	    if (!S_ISCHR(st.st_mode)) {
-		    fprintf(stderr, "%s is no devicen", dev_name);
-		    exit(EXIT_FAILURE);
-	    }
-
-	    fd = open(dev_name, O_RDWR /* required */ | O_NONBLOCK, 0);
-
-	    if (-1 == fd) {
-		    fprintf(stderr, "Cannot open '%s': %d, %s\\n",
-			     dev_name, errno, strerror(errno));
-		    exit(EXIT_FAILURE);
-	    }
-    }
-
-    static void usage(FILE *fp, int argc, char **argv)
-    {
-	    fprintf(fp,
-		     "Usage: %s [options]\\n\\n"
-		     "Version 1.3\\n"
-		     "Options:\\n"
-		     "-d | --device name   Video device name [%s]n"
-		     "-h | --help          Print this messagen"
-		     "-m | --mmap          Use memory mapped buffers [default]n"
-		     "-r | --read          Use read() callsn"
-		     "-u | --userp         Use application allocated buffersn"
-		     "-o | --output        Outputs stream to stdoutn"
-		     "-f | --format        Force format to 640x480 YUYVn"
-		     "-c | --count         Number of frames to grab [%i]n"
-		     "",
-		     argv[0], dev_name, frame_count);
-    }
-
-    static const char short_options[] = "d:hmruofc:";
-
-    static const struct option
-    long_options[] = {
-	    { "device", required_argument, NULL, 'd' },
-	    { "help",   no_argument,       NULL, 'h' },
-	    { "mmap",   no_argument,       NULL, 'm' },
-	    { "read",   no_argument,       NULL, 'r' },
-	    { "userp",  no_argument,       NULL, 'u' },
-	    { "output", no_argument,       NULL, 'o' },
-	    { "format", no_argument,       NULL, 'f' },
-	    { "count",  required_argument, NULL, 'c' },
-	    { 0, 0, 0, 0 }
-    };
-
-    int main(int argc, char **argv)
-    {
-	    dev_name = "/dev/video0";
-
-	    for (;;) {
-		    int idx;
-		    int c;
-
-		    c = getopt_long(argc, argv,
-				    short_options, long_options, &idx);
-
-		    if (-1 == c)
-			    break;
-
-		    switch (c) {
-		    case 0: /* getopt_long() flag */
-			    break;
-
-		    case 'd':
-			    dev_name = optarg;
-			    break;
-
-		    case 'h':
-			    usage(stdout, argc, argv);
-			    exit(EXIT_SUCCESS);
-
-		    case 'm':
-			    io = IO_METHOD_MMAP;
-			    break;
-
-		    case 'r':
-			    io = IO_METHOD_READ;
-			    break;
-
-		    case 'u':
-			    io = IO_METHOD_USERPTR;
-			    break;
-
-		    case 'o':
-			    out_buf++;
-			    break;
-
-		    case 'f':
-			    force_format++;
-			    break;
-
-		    case 'c':
-			    errno = 0;
-			    frame_count = strtol(optarg, NULL, 0);
-			    if (errno)
-				    errno_exit(optarg);
-			    break;
-
-		    default:
-			    usage(stderr, argc, argv);
-			    exit(EXIT_FAILURE);
-		    }
-	    }
-
-	    open_device();
-	    init_device();
-	    start_capturing();
-	    mainloop();
-	    stop_capturing();
-	    uninit_device();
-	    close_device();
-	    fprintf(stderr, "\\n");
-	    return 0;
-    }
diff --git a/Documentation/media/uapi/v4l/colorspaces-defs.rst b/Documentation/media/uapi/v4l/colorspaces-defs.rst
deleted file mode 100644
index e122bbe3d799..000000000000
--- a/Documentation/media/uapi/v4l/colorspaces-defs.rst
+++ /dev/null
@@ -1,183 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-****************************
-Defining Colorspaces in V4L2
-****************************
-
-In V4L2 colorspaces are defined by four values. The first is the
-colorspace identifier (enum :c:type:`v4l2_colorspace`)
-which defines the chromaticities, the default transfer function, the
-default Y'CbCr encoding and the default quantization method. The second
-is the transfer function identifier (enum
-:c:type:`v4l2_xfer_func`) to specify non-standard
-transfer functions. The third is the Y'CbCr encoding identifier (enum
-:c:type:`v4l2_ycbcr_encoding`) to specify
-non-standard Y'CbCr encodings and the fourth is the quantization
-identifier (enum :c:type:`v4l2_quantization`) to
-specify non-standard quantization methods. Most of the time only the
-colorspace field of struct :c:type:`v4l2_pix_format`
-or struct :c:type:`v4l2_pix_format_mplane`
-needs to be filled in.
-
-.. _hsv-colorspace:
-
-On :ref:`HSV formats <hsv-formats>` the *Hue* is defined as the angle on
-the cylindrical color representation. Usually this angle is measured in
-degrees, i.e. 0-360. When we map this angle value into 8 bits, there are
-two basic ways to do it: Divide the angular value by 2 (0-179), or use the
-whole range, 0-255, dividing the angular value by 1.41. The enum
-:c:type:`v4l2_hsv_encoding` specifies which encoding is used.
-
-.. note:: The default R'G'B' quantization is full range for all
-   colorspaces except for BT.2020 which uses limited range R'G'B'
-   quantization.
-
-.. tabularcolumns:: |p{6.7cm}|p{10.8cm}|
-
-.. c:type:: v4l2_colorspace
-
-.. flat-table:: V4L2 Colorspaces
-    :header-rows:  1
-    :stub-columns: 0
-
-    * - Identifier
-      - Details
-    * - ``V4L2_COLORSPACE_DEFAULT``
-      - The default colorspace. This can be used by applications to let
-	the driver fill in the colorspace.
-    * - ``V4L2_COLORSPACE_SMPTE170M``
-      - See :ref:`col-smpte-170m`.
-    * - ``V4L2_COLORSPACE_REC709``
-      - See :ref:`col-rec709`.
-    * - ``V4L2_COLORSPACE_SRGB``
-      - See :ref:`col-srgb`.
-    * - ``V4L2_COLORSPACE_OPRGB``
-      - See :ref:`col-oprgb`.
-    * - ``V4L2_COLORSPACE_BT2020``
-      - See :ref:`col-bt2020`.
-    * - ``V4L2_COLORSPACE_DCI_P3``
-      - See :ref:`col-dcip3`.
-    * - ``V4L2_COLORSPACE_SMPTE240M``
-      - See :ref:`col-smpte-240m`.
-    * - ``V4L2_COLORSPACE_470_SYSTEM_M``
-      - See :ref:`col-sysm`.
-    * - ``V4L2_COLORSPACE_470_SYSTEM_BG``
-      - See :ref:`col-sysbg`.
-    * - ``V4L2_COLORSPACE_JPEG``
-      - See :ref:`col-jpeg`.
-    * - ``V4L2_COLORSPACE_RAW``
-      - The raw colorspace. This is used for raw image capture where the
-	image is minimally processed and is using the internal colorspace
-	of the device. The software that processes an image using this
-	'colorspace' will have to know the internals of the capture
-	device.
-
-
-
-.. c:type:: v4l2_xfer_func
-
-.. tabularcolumns:: |p{5.5cm}|p{12.0cm}|
-
-.. flat-table:: V4L2 Transfer Function
-    :header-rows:  1
-    :stub-columns: 0
-
-    * - Identifier
-      - Details
-    * - ``V4L2_XFER_FUNC_DEFAULT``
-      - Use the default transfer function as defined by the colorspace.
-    * - ``V4L2_XFER_FUNC_709``
-      - Use the Rec. 709 transfer function.
-    * - ``V4L2_XFER_FUNC_SRGB``
-      - Use the sRGB transfer function.
-    * - ``V4L2_XFER_FUNC_OPRGB``
-      - Use the opRGB transfer function.
-    * - ``V4L2_XFER_FUNC_SMPTE240M``
-      - Use the SMPTE 240M transfer function.
-    * - ``V4L2_XFER_FUNC_NONE``
-      - Do not use a transfer function (i.e. use linear RGB values).
-    * - ``V4L2_XFER_FUNC_DCI_P3``
-      - Use the DCI-P3 transfer function.
-    * - ``V4L2_XFER_FUNC_SMPTE2084``
-      - Use the SMPTE 2084 transfer function. See :ref:`xf-smpte-2084`.
-
-
-
-.. c:type:: v4l2_ycbcr_encoding
-
-.. tabularcolumns:: |p{7.2cm}|p{10.3cm}|
-
-.. flat-table:: V4L2 Y'CbCr Encodings
-    :header-rows:  1
-    :stub-columns: 0
-
-    * - Identifier
-      - Details
-    * - ``V4L2_YCBCR_ENC_DEFAULT``
-      - Use the default Y'CbCr encoding as defined by the colorspace.
-    * - ``V4L2_YCBCR_ENC_601``
-      - Use the BT.601 Y'CbCr encoding.
-    * - ``V4L2_YCBCR_ENC_709``
-      - Use the Rec. 709 Y'CbCr encoding.
-    * - ``V4L2_YCBCR_ENC_XV601``
-      - Use the extended gamut xvYCC BT.601 encoding.
-    * - ``V4L2_YCBCR_ENC_XV709``
-      - Use the extended gamut xvYCC Rec. 709 encoding.
-    * - ``V4L2_YCBCR_ENC_BT2020``
-      - Use the default non-constant luminance BT.2020 Y'CbCr encoding.
-    * - ``V4L2_YCBCR_ENC_BT2020_CONST_LUM``
-      - Use the constant luminance BT.2020 Yc'CbcCrc encoding.
-    * - ``V4L2_YCBCR_ENC_SMPTE_240M``
-      - Use the SMPTE 240M Y'CbCr encoding.
-
-
-
-.. c:type:: v4l2_hsv_encoding
-
-.. tabularcolumns:: |p{6.5cm}|p{11.0cm}|
-
-.. flat-table:: V4L2 HSV Encodings
-    :header-rows:  1
-    :stub-columns: 0
-
-    * - Identifier
-      - Details
-    * - ``V4L2_HSV_ENC_180``
-      - For the Hue, each LSB is two degrees.
-    * - ``V4L2_HSV_ENC_256``
-      - For the Hue, the 360 degrees are mapped into 8 bits, i.e. each
-	LSB is roughly 1.41 degrees.
-
-
-
-.. c:type:: v4l2_quantization
-
-.. tabularcolumns:: |p{6.5cm}|p{11.0cm}|
-
-.. flat-table:: V4L2 Quantization Methods
-    :header-rows:  1
-    :stub-columns: 0
-
-    * - Identifier
-      - Details
-    * - ``V4L2_QUANTIZATION_DEFAULT``
-      - Use the default quantization encoding as defined by the
-	colorspace. This is always full range for R'G'B' (except for the
-	BT.2020 colorspace) and HSV. It is usually limited range for Y'CbCr.
-    * - ``V4L2_QUANTIZATION_FULL_RANGE``
-      - Use the full range quantization encoding. I.e. the range [0…1] is
-	mapped to [0…255] (with possible clipping to [1…254] to avoid the
-	0x00 and 0xff values). Cb and Cr are mapped from [-0.5…0.5] to
-	[0…255] (with possible clipping to [1…254] to avoid the 0x00 and
-	0xff values).
-    * - ``V4L2_QUANTIZATION_LIM_RANGE``
-      - Use the limited range quantization encoding. I.e. the range [0…1]
-	is mapped to [16…235]. Cb and Cr are mapped from [-0.5…0.5] to
-	[16…240].
diff --git a/Documentation/media/uapi/v4l/colorspaces-details.rst b/Documentation/media/uapi/v4l/colorspaces-details.rst
deleted file mode 100644
index 8b0ba3668101..000000000000
--- a/Documentation/media/uapi/v4l/colorspaces-details.rst
+++ /dev/null
@@ -1,813 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-********************************
-Detailed Colorspace Descriptions
-********************************
-
-
-.. _col-smpte-170m:
-
-Colorspace SMPTE 170M (V4L2_COLORSPACE_SMPTE170M)
-=================================================
-
-The :ref:`smpte170m` standard defines the colorspace used by NTSC and
-PAL and by SDTV in general. The default transfer function is
-``V4L2_XFER_FUNC_709``. The default Y'CbCr encoding is
-``V4L2_YCBCR_ENC_601``. The default Y'CbCr quantization is limited
-range. The chromaticities of the primary colors and the white reference
-are:
-
-
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. flat-table:: SMPTE 170M Chromaticities
-    :header-rows:  1
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - Color
-      - x
-      - y
-    * - Red
-      - 0.630
-      - 0.340
-    * - Green
-      - 0.310
-      - 0.595
-    * - Blue
-      - 0.155
-      - 0.070
-    * - White Reference (D65)
-      - 0.3127
-      - 0.3290
-
-
-The red, green and blue chromaticities are also often referred to as the
-SMPTE C set, so this colorspace is sometimes called SMPTE C as well.
-
-The transfer function defined for SMPTE 170M is the same as the one
-defined in Rec. 709.
-
-.. math::
-
-    L' = -1.099(-L)^{0.45} + 0.099 \text{, for } L \le-0.018
-
-    L' = 4.5L \text{, for } -0.018 < L < 0.018
-
-    L' = 1.099L^{0.45} - 0.099 \text{, for } L \ge 0.018
-
-Inverse Transfer function:
-
-.. math::
-
-    L = -\left( \frac{L' - 0.099}{-1.099} \right) ^{\frac{1}{0.45}} \text{, for } L' \le -0.081
-
-    L = \frac{L'}{4.5} \text{, for } -0.081 < L' < 0.081
-
-    L = \left(\frac{L' + 0.099}{1.099}\right)^{\frac{1}{0.45} } \text{, for } L' \ge 0.081
-
-The luminance (Y') and color difference (Cb and Cr) are obtained with
-the following ``V4L2_YCBCR_ENC_601`` encoding:
-
-.. math::
-
-    Y' = 0.2990R' + 0.5870G' + 0.1140B'
-
-    Cb = -0.1687R' - 0.3313G' + 0.5B'
-
-    Cr = 0.5R' - 0.4187G' - 0.0813B'
-
-Y' is clamped to the range [0…1] and Cb and Cr are clamped to the range
-[-0.5…0.5]. This conversion to Y'CbCr is identical to the one defined in
-the :ref:`itu601` standard and this colorspace is sometimes called
-BT.601 as well, even though BT.601 does not mention any color primaries.
-
-The default quantization is limited range, but full range is possible
-although rarely seen.
-
-
-.. _col-rec709:
-
-Colorspace Rec. 709 (V4L2_COLORSPACE_REC709)
-============================================
-
-The :ref:`itu709` standard defines the colorspace used by HDTV in
-general. The default transfer function is ``V4L2_XFER_FUNC_709``. The
-default Y'CbCr encoding is ``V4L2_YCBCR_ENC_709``. The default Y'CbCr
-quantization is limited range. The chromaticities of the primary colors
-and the white reference are:
-
-
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. flat-table:: Rec. 709 Chromaticities
-    :header-rows:  1
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - Color
-      - x
-      - y
-    * - Red
-      - 0.640
-      - 0.330
-    * - Green
-      - 0.300
-      - 0.600
-    * - Blue
-      - 0.150
-      - 0.060
-    * - White Reference (D65)
-      - 0.3127
-      - 0.3290
-
-
-The full name of this standard is Rec. ITU-R BT.709-5.
-
-Transfer function. Normally L is in the range [0…1], but for the
-extended gamut xvYCC encoding values outside that range are allowed.
-
-.. math::
-
-    L' = -1.099(-L)^{0.45} + 0.099 \text{, for } L \le -0.018
-
-    L' = 4.5L \text{, for } -0.018 < L < 0.018
-
-    L' = 1.099L^{0.45} - 0.099 \text{, for } L \ge 0.018
-
-Inverse Transfer function:
-
-.. math::
-
-    L = -\left( \frac{L' - 0.099}{-1.099} \right)^\frac{1}{0.45} \text{, for } L' \le -0.081
-
-    L = \frac{L'}{4.5}\text{, for } -0.081 < L' < 0.081
-
-    L = \left(\frac{L' + 0.099}{1.099}\right)^{\frac{1}{0.45} } \text{, for } L' \ge 0.081
-
-The luminance (Y') and color difference (Cb and Cr) are obtained with
-the following ``V4L2_YCBCR_ENC_709`` encoding:
-
-.. math::
-
-    Y' = 0.2126R' + 0.7152G' + 0.0722B'
-
-    Cb = -0.1146R' - 0.3854G' + 0.5B'
-
-    Cr = 0.5R' - 0.4542G' - 0.0458B'
-
-Y' is clamped to the range [0…1] and Cb and Cr are clamped to the range
-[-0.5…0.5].
-
-The default quantization is limited range, but full range is possible
-although rarely seen.
-
-The ``V4L2_YCBCR_ENC_709`` encoding described above is the default for
-this colorspace, but it can be overridden with ``V4L2_YCBCR_ENC_601``,
-in which case the BT.601 Y'CbCr encoding is used.
-
-Two additional extended gamut Y'CbCr encodings are also possible with
-this colorspace:
-
-The xvYCC 709 encoding (``V4L2_YCBCR_ENC_XV709``, :ref:`xvycc`) is
-similar to the Rec. 709 encoding, but it allows for R', G' and B' values
-that are outside the range [0…1]. The resulting Y', Cb and Cr values are
-scaled and offset according to the limited range formula:
-
-.. math::
-
-    Y' = \frac{219}{256} * (0.2126R' + 0.7152G' + 0.0722B') + \frac{16}{256}
-
-    Cb = \frac{224}{256} * (-0.1146R' - 0.3854G' + 0.5B')
-
-    Cr = \frac{224}{256} * (0.5R' - 0.4542G' - 0.0458B')
-
-The xvYCC 601 encoding (``V4L2_YCBCR_ENC_XV601``, :ref:`xvycc`) is
-similar to the BT.601 encoding, but it allows for R', G' and B' values
-that are outside the range [0…1]. The resulting Y', Cb and Cr values are
-scaled and offset according to the limited range formula:
-
-.. math::
-
-    Y' = \frac{219}{256} * (0.2990R' + 0.5870G' + 0.1140B') + \frac{16}{256}
-
-    Cb = \frac{224}{256} * (-0.1687R' - 0.3313G' + 0.5B')
-
-    Cr = \frac{224}{256} * (0.5R' - 0.4187G' - 0.0813B')
-
-Y' is clamped to the range [0…1] and Cb and Cr are clamped to the range
-[-0.5…0.5] and quantized without further scaling or offsets.
-The non-standard xvYCC 709 or xvYCC 601 encodings can be
-used by selecting ``V4L2_YCBCR_ENC_XV709`` or ``V4L2_YCBCR_ENC_XV601``.
-As seen by the xvYCC formulas these encodings always use limited range quantization,
-there is no full range variant. The whole point of these extended gamut encodings
-is that values outside the limited range are still valid, although they
-map to R', G' and B' values outside the [0…1] range and are therefore outside
-the Rec. 709 colorspace gamut.
-
-
-.. _col-srgb:
-
-Colorspace sRGB (V4L2_COLORSPACE_SRGB)
-======================================
-
-The :ref:`srgb` standard defines the colorspace used by most webcams
-and computer graphics. The default transfer function is
-``V4L2_XFER_FUNC_SRGB``. The default Y'CbCr encoding is
-``V4L2_YCBCR_ENC_601``. The default Y'CbCr quantization is limited range.
-
-Note that the :ref:`sycc` standard specifies full range quantization,
-however all current capture hardware supported by the kernel convert
-R'G'B' to limited range Y'CbCr. So choosing full range as the default
-would break how applications interpret the quantization range.
-
-The chromaticities of the primary colors and the white reference are:
-
-
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. flat-table:: sRGB Chromaticities
-    :header-rows:  1
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - Color
-      - x
-      - y
-    * - Red
-      - 0.640
-      - 0.330
-    * - Green
-      - 0.300
-      - 0.600
-    * - Blue
-      - 0.150
-      - 0.060
-    * - White Reference (D65)
-      - 0.3127
-      - 0.3290
-
-
-These chromaticities are identical to the Rec. 709 colorspace.
-
-Transfer function. Note that negative values for L are only used by the
-Y'CbCr conversion.
-
-.. math::
-
-    L' = -1.055(-L)^{\frac{1}{2.4} } + 0.055\text{, for }L < -0.0031308
-
-    L' = 12.92L\text{, for }-0.0031308 \le L \le 0.0031308
-
-    L' = 1.055L ^{\frac{1}{2.4} } - 0.055\text{, for }0.0031308 < L \le 1
-
-Inverse Transfer function:
-
-.. math::
-
-    L = -((-L' + 0.055) / 1.055) ^{2.4}\text{, for }L' < -0.04045
-
-    L = L' / 12.92\text{, for }-0.04045 \le L' \le 0.04045
-
-    L = ((L' + 0.055) / 1.055) ^{2.4}\text{, for }L' > 0.04045
-
-The luminance (Y') and color difference (Cb and Cr) are obtained with
-the following ``V4L2_YCBCR_ENC_601`` encoding as defined by :ref:`sycc`:
-
-.. math::
-
-    Y' = 0.2990R' + 0.5870G' + 0.1140B'
-
-    Cb = -0.1687R' - 0.3313G' + 0.5B'
-
-    Cr = 0.5R' - 0.4187G' - 0.0813B'
-
-Y' is clamped to the range [0…1] and Cb and Cr are clamped to the range
-[-0.5…0.5]. This transform is identical to one defined in SMPTE
-170M/BT.601. The Y'CbCr quantization is limited range.
-
-
-.. _col-oprgb:
-
-Colorspace opRGB (V4L2_COLORSPACE_OPRGB)
-===============================================
-
-The :ref:`oprgb` standard defines the colorspace used by computer
-graphics that use the opRGB colorspace. The default transfer function is
-``V4L2_XFER_FUNC_OPRGB``. The default Y'CbCr encoding is
-``V4L2_YCBCR_ENC_601``. The default Y'CbCr quantization is limited
-range.
-
-Note that the :ref:`oprgb` standard specifies full range quantization,
-however all current capture hardware supported by the kernel convert
-R'G'B' to limited range Y'CbCr. So choosing full range as the default
-would break how applications interpret the quantization range.
-
-The chromaticities of the primary colors and the white reference are:
-
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. flat-table:: opRGB Chromaticities
-    :header-rows:  1
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - Color
-      - x
-      - y
-    * - Red
-      - 0.6400
-      - 0.3300
-    * - Green
-      - 0.2100
-      - 0.7100
-    * - Blue
-      - 0.1500
-      - 0.0600
-    * - White Reference (D65)
-      - 0.3127
-      - 0.3290
-
-
-
-Transfer function:
-
-.. math::
-
-    L' = L ^{\frac{1}{2.19921875}}
-
-Inverse Transfer function:
-
-.. math::
-
-    L = L'^{(2.19921875)}
-
-The luminance (Y') and color difference (Cb and Cr) are obtained with
-the following ``V4L2_YCBCR_ENC_601`` encoding:
-
-.. math::
-
-    Y' = 0.2990R' + 0.5870G' + 0.1140B'
-
-    Cb = -0.1687R' - 0.3313G' + 0.5B'
-
-    Cr = 0.5R' - 0.4187G' - 0.0813B'
-
-Y' is clamped to the range [0…1] and Cb and Cr are clamped to the range
-[-0.5…0.5]. This transform is identical to one defined in SMPTE
-170M/BT.601. The Y'CbCr quantization is limited range.
-
-
-.. _col-bt2020:
-
-Colorspace BT.2020 (V4L2_COLORSPACE_BT2020)
-===========================================
-
-The :ref:`itu2020` standard defines the colorspace used by Ultra-high
-definition television (UHDTV). The default transfer function is
-``V4L2_XFER_FUNC_709``. The default Y'CbCr encoding is
-``V4L2_YCBCR_ENC_BT2020``. The default R'G'B' quantization is limited
-range (!), and so is the default Y'CbCr quantization. The chromaticities
-of the primary colors and the white reference are:
-
-
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. flat-table:: BT.2020 Chromaticities
-    :header-rows:  1
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - Color
-      - x
-      - y
-    * - Red
-      - 0.708
-      - 0.292
-    * - Green
-      - 0.170
-      - 0.797
-    * - Blue
-      - 0.131
-      - 0.046
-    * - White Reference (D65)
-      - 0.3127
-      - 0.3290
-
-
-
-Transfer function (same as Rec. 709):
-
-.. math::
-
-    L' = 4.5L\text{, for }0 \le L < 0.018
-
-    L' = 1.099L ^{0.45} - 0.099\text{, for } 0.018 \le L \le 1
-
-Inverse Transfer function:
-
-.. math::
-
-    L = L' / 4.5\text{, for } L' < 0.081
-
-    L = \left( \frac{L' + 0.099}{1.099}\right) ^{\frac{1}{0.45} }\text{, for } L' \ge 0.081
-
-Please note that while Rec. 709 is defined as the default transfer function
-by the :ref:`itu2020` standard, in practice this colorspace is often used
-with the :ref:`xf-smpte-2084`. In particular Ultra HD Blu-ray discs use
-this combination.
-
-The luminance (Y') and color difference (Cb and Cr) are obtained with
-the following ``V4L2_YCBCR_ENC_BT2020`` encoding:
-
-.. math::
-
-    Y' = 0.2627R' + 0.6780G' + 0.0593B'
-
-    Cb = -0.1396R' - 0.3604G' + 0.5B'
-
-    Cr = 0.5R' - 0.4598G' - 0.0402B'
-
-Y' is clamped to the range [0…1] and Cb and Cr are clamped to the range
-[-0.5…0.5]. The Y'CbCr quantization is limited range.
-
-There is also an alternate constant luminance R'G'B' to Yc'CbcCrc
-(``V4L2_YCBCR_ENC_BT2020_CONST_LUM``) encoding:
-
-Luma:
-
-.. math::
-    :nowrap:
-
-    \begin{align*}
-    Yc' = (0.2627R + 0.6780G + 0.0593B)'& \\
-    B' - Yc' \le 0:& \\
-        &Cbc = (B' - Yc') / 1.9404 \\
-    B' - Yc' > 0: & \\
-        &Cbc = (B' - Yc') / 1.5816 \\
-    R' - Yc' \le 0:& \\
-        &Crc = (R' - Y') / 1.7184 \\
-    R' - Yc' > 0:& \\
-        &Crc = (R' - Y') / 0.9936
-    \end{align*}
-
-Yc' is clamped to the range [0…1] and Cbc and Crc are clamped to the
-range [-0.5…0.5]. The Yc'CbcCrc quantization is limited range.
-
-
-.. _col-dcip3:
-
-Colorspace DCI-P3 (V4L2_COLORSPACE_DCI_P3)
-==========================================
-
-The :ref:`smpte431` standard defines the colorspace used by cinema
-projectors that use the DCI-P3 colorspace. The default transfer function
-is ``V4L2_XFER_FUNC_DCI_P3``. The default Y'CbCr encoding is
-``V4L2_YCBCR_ENC_709``. The default Y'CbCr quantization is limited range.
-
-.. note::
-
-   Note that this colorspace standard does not specify a
-   Y'CbCr encoding since it is not meant to be encoded to Y'CbCr. So this
-   default Y'CbCr encoding was picked because it is the HDTV encoding.
-
-The chromaticities of the primary colors and the white reference are:
-
-
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. flat-table:: DCI-P3 Chromaticities
-    :header-rows:  1
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - Color
-      - x
-      - y
-    * - Red
-      - 0.6800
-      - 0.3200
-    * - Green
-      - 0.2650
-      - 0.6900
-    * - Blue
-      - 0.1500
-      - 0.0600
-    * - White Reference
-      - 0.3140
-      - 0.3510
-
-
-
-Transfer function:
-
-.. math::
-
-    L' = L^{\frac{1}{2.6}}
-
-Inverse Transfer function:
-
-.. math::
-
-    L = L'^{(2.6)}
-
-Y'CbCr encoding is not specified. V4L2 defaults to Rec. 709.
-
-
-.. _col-smpte-240m:
-
-Colorspace SMPTE 240M (V4L2_COLORSPACE_SMPTE240M)
-=================================================
-
-The :ref:`smpte240m` standard was an interim standard used during the
-early days of HDTV (1988-1998). It has been superseded by Rec. 709. The
-default transfer function is ``V4L2_XFER_FUNC_SMPTE240M``. The default
-Y'CbCr encoding is ``V4L2_YCBCR_ENC_SMPTE240M``. The default Y'CbCr
-quantization is limited range. The chromaticities of the primary colors
-and the white reference are:
-
-
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. flat-table:: SMPTE 240M Chromaticities
-    :header-rows:  1
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - Color
-      - x
-      - y
-    * - Red
-      - 0.630
-      - 0.340
-    * - Green
-      - 0.310
-      - 0.595
-    * - Blue
-      - 0.155
-      - 0.070
-    * - White Reference (D65)
-      - 0.3127
-      - 0.3290
-
-
-These chromaticities are identical to the SMPTE 170M colorspace.
-
-Transfer function:
-
-.. math::
-
-    L' = 4L\text{, for } 0 \le L < 0.0228
-
-    L' = 1.1115L ^{0.45} - 0.1115\text{, for } 0.0228 \le L \le 1
-
-Inverse Transfer function:
-
-.. math::
-
-    L = \frac{L'}{4}\text{, for } 0 \le L' < 0.0913
-
-    L = \left( \frac{L' + 0.1115}{1.1115}\right) ^{\frac{1}{0.45} }\text{, for } L' \ge 0.0913
-
-The luminance (Y') and color difference (Cb and Cr) are obtained with
-the following ``V4L2_YCBCR_ENC_SMPTE240M`` encoding:
-
-.. math::
-
-    Y' = 0.2122R' + 0.7013G' + 0.0865B'
-
-    Cb = -0.1161R' - 0.3839G' + 0.5B'
-
-    Cr = 0.5R' - 0.4451G' - 0.0549B'
-
-Y' is clamped to the range [0…1] and Cb and Cr are clamped to the
-range [-0.5…0.5]. The Y'CbCr quantization is limited range.
-
-
-.. _col-sysm:
-
-Colorspace NTSC 1953 (V4L2_COLORSPACE_470_SYSTEM_M)
-===================================================
-
-This standard defines the colorspace used by NTSC in 1953. In practice
-this colorspace is obsolete and SMPTE 170M should be used instead. The
-default transfer function is ``V4L2_XFER_FUNC_709``. The default Y'CbCr
-encoding is ``V4L2_YCBCR_ENC_601``. The default Y'CbCr quantization is
-limited range. The chromaticities of the primary colors and the white
-reference are:
-
-
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. flat-table:: NTSC 1953 Chromaticities
-    :header-rows:  1
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - Color
-      - x
-      - y
-    * - Red
-      - 0.67
-      - 0.33
-    * - Green
-      - 0.21
-      - 0.71
-    * - Blue
-      - 0.14
-      - 0.08
-    * - White Reference (C)
-      - 0.310
-      - 0.316
-
-
-.. note::
-
-   This colorspace uses Illuminant C instead of D65 as the white
-   reference. To correctly convert an image in this colorspace to another
-   that uses D65 you need to apply a chromatic adaptation algorithm such as
-   the Bradford method.
-
-The transfer function was never properly defined for NTSC 1953. The Rec.
-709 transfer function is recommended in the literature:
-
-.. math::
-
-    L' = 4.5L\text{, for } 0 \le L < 0.018
-
-    L' = 1.099L ^{0.45} - 0.099\text{, for } 0.018 \le L \le 1
-
-Inverse Transfer function:
-
-.. math::
-
-    L = \frac{L'}{4.5} \text{, for } L' < 0.081
-
-    L = \left( \frac{L' + 0.099}{1.099}\right) ^{\frac{1}{0.45} }\text{, for } L' \ge 0.081
-
-The luminance (Y') and color difference (Cb and Cr) are obtained with
-the following ``V4L2_YCBCR_ENC_601`` encoding:
-
-.. math::
-
-    Y' = 0.2990R' + 0.5870G' + 0.1140B'
-
-    Cb = -0.1687R' - 0.3313G' + 0.5B'
-
-    Cr = 0.5R' - 0.4187G' - 0.0813B'
-
-Y' is clamped to the range [0…1] and Cb and Cr are clamped to the range
-[-0.5…0.5]. The Y'CbCr quantization is limited range. This transform is
-identical to one defined in SMPTE 170M/BT.601.
-
-
-.. _col-sysbg:
-
-Colorspace EBU Tech. 3213 (V4L2_COLORSPACE_470_SYSTEM_BG)
-=========================================================
-
-The :ref:`tech3213` standard defines the colorspace used by PAL/SECAM
-in 1975. In practice this colorspace is obsolete and SMPTE 170M should
-be used instead. The default transfer function is
-``V4L2_XFER_FUNC_709``. The default Y'CbCr encoding is
-``V4L2_YCBCR_ENC_601``. The default Y'CbCr quantization is limited
-range. The chromaticities of the primary colors and the white reference
-are:
-
-
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. flat-table:: EBU Tech. 3213 Chromaticities
-    :header-rows:  1
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - Color
-      - x
-      - y
-    * - Red
-      - 0.64
-      - 0.33
-    * - Green
-      - 0.29
-      - 0.60
-    * - Blue
-      - 0.15
-      - 0.06
-    * - White Reference (D65)
-      - 0.3127
-      - 0.3290
-
-
-
-The transfer function was never properly defined for this colorspace.
-The Rec. 709 transfer function is recommended in the literature:
-
-.. math::
-
-    L' = 4.5L\text{, for } 0 \le L < 0.018
-
-    L' = 1.099L ^{0.45} - 0.099\text{, for } 0.018 \le L \le 1
-
-Inverse Transfer function:
-
-.. math::
-
-    L = \frac{L'}{4.5} \text{, for } L' < 0.081
-
-    L = \left(\frac{L' + 0.099}{1.099} \right) ^{\frac{1}{0.45} }\text{, for } L' \ge 0.081
-
-The luminance (Y') and color difference (Cb and Cr) are obtained with
-the following ``V4L2_YCBCR_ENC_601`` encoding:
-
-.. math::
-
-    Y' = 0.2990R' + 0.5870G' + 0.1140B'
-
-    Cb = -0.1687R' - 0.3313G' + 0.5B'
-
-    Cr = 0.5R' - 0.4187G' - 0.0813B'
-
-Y' is clamped to the range [0…1] and Cb and Cr are clamped to the range
-[-0.5…0.5]. The Y'CbCr quantization is limited range. This transform is
-identical to one defined in SMPTE 170M/BT.601.
-
-
-.. _col-jpeg:
-
-Colorspace JPEG (V4L2_COLORSPACE_JPEG)
-======================================
-
-This colorspace defines the colorspace used by most (Motion-)JPEG
-formats. The chromaticities of the primary colors and the white
-reference are identical to sRGB. The transfer function use is
-``V4L2_XFER_FUNC_SRGB``. The Y'CbCr encoding is ``V4L2_YCBCR_ENC_601``
-with full range quantization where Y' is scaled to [0…255] and Cb/Cr are
-scaled to [-128…128] and then clipped to [-128…127].
-
-.. note::
-
-   The JPEG standard does not actually store colorspace
-   information. So if something other than sRGB is used, then the driver
-   will have to set that information explicitly. Effectively
-   ``V4L2_COLORSPACE_JPEG`` can be considered to be an abbreviation for
-   ``V4L2_COLORSPACE_SRGB``, ``V4L2_YCBCR_ENC_601`` and
-   ``V4L2_QUANTIZATION_FULL_RANGE``.
-
-***************************************
-Detailed Transfer Function Descriptions
-***************************************
-
-.. _xf-smpte-2084:
-
-Transfer Function SMPTE 2084 (V4L2_XFER_FUNC_SMPTE2084)
-=======================================================
-
-The :ref:`smpte2084` standard defines the transfer function used by
-High Dynamic Range content.
-
-Constants:
-    m1 = (2610 / 4096) / 4
-
-    m2 = (2523 / 4096) * 128
-
-    c1 = 3424 / 4096
-
-    c2 = (2413 / 4096) * 32
-
-    c3 = (2392 / 4096) * 32
-
-Transfer function:
-    L' = ((c1 + c2 * L\ :sup:`m1`) / (1 + c3 * L\ :sup:`m1`))\ :sup:`m2`
-
-Inverse Transfer function:
-    L = (max(L':sup:`1/m2` - c1, 0) / (c2 - c3 *
-    L'\ :sup:`1/m2`))\ :sup:`1/m1`
-
-Take care when converting between this transfer function and non-HDR transfer
-functions: the linear RGB values [0…1] of HDR content map to a luminance range
-of 0 to 10000 cd/m\ :sup:`2` whereas the linear RGB values of non-HDR (aka
-Standard Dynamic Range or SDR) map to a luminance range of 0 to 100 cd/m\ :sup:`2`.
-
-To go from SDR to HDR you will have to divide L by 100 first. To go in the other
-direction you will have to multiply L by 100. Of course, this clamps all
-luminance values over 100 cd/m\ :sup:`2` to 100 cd/m\ :sup:`2`.
-
-There are better methods, see e.g. :ref:`colimg` for more in-depth information
-about this.
diff --git a/Documentation/media/uapi/v4l/colorspaces.rst b/Documentation/media/uapi/v4l/colorspaces.rst
deleted file mode 100644
index 4f6c82fa057f..000000000000
--- a/Documentation/media/uapi/v4l/colorspaces.rst
+++ /dev/null
@@ -1,170 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _colorspaces:
-
-***********
-Colorspaces
-***********
-
-'Color' is a very complex concept and depends on physics, chemistry and
-biology. Just because you have three numbers that describe the 'red',
-'green' and 'blue' components of the color of a pixel does not mean that
-you can accurately display that color. A colorspace defines what it
-actually *means* to have an RGB value of e.g. (255, 0, 0). That is,
-which color should be reproduced on the screen in a perfectly calibrated
-environment.
-
-In order to do that we first need to have a good definition of color,
-i.e. some way to uniquely and unambiguously define a color so that
-someone else can reproduce it. Human color vision is trichromatic since
-the human eye has color receptors that are sensitive to three different
-wavelengths of light. Hence the need to use three numbers to describe
-color. Be glad you are not a mantis shrimp as those are sensitive to 12
-different wavelengths, so instead of RGB we would be using the
-ABCDEFGHIJKL colorspace...
-
-Color exists only in the eye and brain and is the result of how strongly
-color receptors are stimulated. This is based on the Spectral Power
-Distribution (SPD) which is a graph showing the intensity (radiant
-power) of the light at wavelengths covering the visible spectrum as it
-enters the eye. The science of colorimetry is about the relationship
-between the SPD and color as perceived by the human brain.
-
-Since the human eye has only three color receptors it is perfectly
-possible that different SPDs will result in the same stimulation of
-those receptors and are perceived as the same color, even though the SPD
-of the light is different.
-
-In the 1920s experiments were devised to determine the relationship
-between SPDs and the perceived color and that resulted in the CIE 1931
-standard that defines spectral weighting functions that model the
-perception of color. Specifically that standard defines functions that
-can take an SPD and calculate the stimulus for each color receptor.
-After some further mathematical transforms these stimuli are known as
-the *CIE XYZ tristimulus* values and these X, Y and Z values describe a
-color as perceived by a human unambiguously. These X, Y and Z values are
-all in the range [0…1].
-
-The Y value in the CIE XYZ colorspace corresponds to luminance. Often
-the CIE XYZ colorspace is transformed to the normalized CIE xyY
-colorspace:
-
-	x = X / (X + Y + Z)
-
-	y = Y / (X + Y + Z)
-
-The x and y values are the chromaticity coordinates and can be used to
-define a color without the luminance component Y. It is very confusing
-to have such similar names for these colorspaces. Just be aware that if
-colors are specified with lower case 'x' and 'y', then the CIE xyY
-colorspace is used. Upper case 'X' and 'Y' refer to the CIE XYZ
-colorspace. Also, y has nothing to do with luminance. Together x and y
-specify a color, and Y the luminance. That is really all you need to
-remember from a practical point of view. At the end of this section you
-will find reading resources that go into much more detail if you are
-interested.
-
-A monitor or TV will reproduce colors by emitting light at three
-different wavelengths, the combination of which will stimulate the color
-receptors in the eye and thus cause the perception of color.
-Historically these wavelengths were defined by the red, green and blue
-phosphors used in the displays. These *color primaries* are part of what
-defines a colorspace.
-
-Different display devices will have different primaries and some
-primaries are more suitable for some display technologies than others.
-This has resulted in a variety of colorspaces that are used for
-different display technologies or uses. To define a colorspace you need
-to define the three color primaries (these are typically defined as x, y
-chromaticity coordinates from the CIE xyY colorspace) but also the white
-reference: that is the color obtained when all three primaries are at
-maximum power. This determines the relative power or energy of the
-primaries. This is usually chosen to be close to daylight which has been
-defined as the CIE D65 Illuminant.
-
-To recapitulate: the CIE XYZ colorspace uniquely identifies colors.
-Other colorspaces are defined by three chromaticity coordinates defined
-in the CIE xyY colorspace. Based on those a 3x3 matrix can be
-constructed that transforms CIE XYZ colors to colors in the new
-colorspace.
-
-Both the CIE XYZ and the RGB colorspace that are derived from the
-specific chromaticity primaries are linear colorspaces. But neither the
-eye, nor display technology is linear. Doubling the values of all
-components in the linear colorspace will not be perceived as twice the
-intensity of the color. So each colorspace also defines a transfer
-function that takes a linear color component value and transforms it to
-the non-linear component value, which is a closer match to the
-non-linear performance of both the eye and displays. Linear component
-values are denoted RGB, non-linear are denoted as R'G'B'. In general
-colors used in graphics are all R'G'B', except in openGL which uses
-linear RGB. Special care should be taken when dealing with openGL to
-provide linear RGB colors or to use the built-in openGL support to apply
-the inverse transfer function.
-
-The final piece that defines a colorspace is a function that transforms
-non-linear R'G'B' to non-linear Y'CbCr. This function is determined by
-the so-called luma coefficients. There may be multiple possible Y'CbCr
-encodings allowed for the same colorspace. Many encodings of color
-prefer to use luma (Y') and chroma (CbCr) instead of R'G'B'. Since the
-human eye is more sensitive to differences in luminance than in color
-this encoding allows one to reduce the amount of color information
-compared to the luma data. Note that the luma (Y') is unrelated to the Y
-in the CIE XYZ colorspace. Also note that Y'CbCr is often called YCbCr
-or YUV even though these are strictly speaking wrong.
-
-Sometimes people confuse Y'CbCr as being a colorspace. This is not
-correct, it is just an encoding of an R'G'B' color into luma and chroma
-values. The underlying colorspace that is associated with the R'G'B'
-color is also associated with the Y'CbCr color.
-
-The final step is how the RGB, R'G'B' or Y'CbCr values are quantized.
-The CIE XYZ colorspace where X, Y and Z are in the range [0…1] describes
-all colors that humans can perceive, but the transform to another
-colorspace will produce colors that are outside the [0…1] range. Once
-clamped to the [0…1] range those colors can no longer be reproduced in
-that colorspace. This clamping is what reduces the extent or gamut of
-the colorspace. How the range of [0…1] is translated to integer values
-in the range of [0…255] (or higher, depending on the color depth) is
-called the quantization. This is *not* part of the colorspace
-definition. In practice RGB or R'G'B' values are full range, i.e. they
-use the full [0…255] range. Y'CbCr values on the other hand are limited
-range with Y' using [16…235] and Cb and Cr using [16…240].
-
-Unfortunately, in some cases limited range RGB is also used where the
-components use the range [16…235]. And full range Y'CbCr also exists
-using the [0…255] range.
-
-In order to correctly interpret a color you need to know the
-quantization range, whether it is R'G'B' or Y'CbCr, the used Y'CbCr
-encoding and the colorspace. From that information you can calculate the
-corresponding CIE XYZ color and map that again to whatever colorspace
-your display device uses.
-
-The colorspace definition itself consists of the three chromaticity
-primaries, the white reference chromaticity, a transfer function and the
-luma coefficients needed to transform R'G'B' to Y'CbCr. While some
-colorspace standards correctly define all four, quite often the
-colorspace standard only defines some, and you have to rely on other
-standards for the missing pieces. The fact that colorspaces are often a
-mix of different standards also led to very confusing naming conventions
-where the name of a standard was used to name a colorspace when in fact
-that standard was part of various other colorspaces as well.
-
-If you want to read more about colors and colorspaces, then the
-following resources are useful: :ref:`poynton` is a good practical
-book for video engineers, :ref:`colimg` has a much broader scope and
-describes many more aspects of color (physics, chemistry, biology,
-etc.). The
-`http://www.brucelindbloom.com <http://www.brucelindbloom.com>`__
-website is an excellent resource, especially with respect to the
-mathematics behind colorspace conversions. The wikipedia
-`CIE 1931 colorspace <http://en.wikipedia.org/wiki/CIE_1931_color_space#CIE_xy_chromaticity_diagram_and_the_CIE_xyY_color_space>`__
-article is also very useful.
diff --git a/Documentation/media/uapi/v4l/common-defs.rst b/Documentation/media/uapi/v4l/common-defs.rst
deleted file mode 100644
index 504c6c93c9b0..000000000000
--- a/Documentation/media/uapi/v4l/common-defs.rst
+++ /dev/null
@@ -1,20 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _common-defs:
-
-******************************************************
-Common definitions for V4L2 and V4L2 subdev interfaces
-******************************************************
-
-
-.. toctree::
-    :maxdepth: 1
-
-    selections-common
diff --git a/Documentation/media/uapi/v4l/common.rst b/Documentation/media/uapi/v4l/common.rst
deleted file mode 100644
index 5e87ae24e4b4..000000000000
--- a/Documentation/media/uapi/v4l/common.rst
+++ /dev/null
@@ -1,64 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _common:
-
-###################
-Common API Elements
-###################
-Programming a V4L2 device consists of these steps:
-
--  Opening the device
-
--  Changing device properties, selecting a video and audio input, video
-   standard, picture brightness a. o.
-
--  Negotiating a data format
-
--  Negotiating an input/output method
-
--  The actual input/output loop
-
--  Closing the device
-
-In practice most steps are optional and can be executed out of order. It
-depends on the V4L2 device type, you can read about the details in
-:ref:`devices`. In this chapter we will discuss the basic concepts
-applicable to all devices.
-
-
-.. toctree::
-    :maxdepth: 1
-
-    open
-    querycap
-    app-pri
-    video
-    audio
-    tuner
-    standard
-    dv-timings
-    control
-    extended-controls
-    ext-ctrls-camera
-    ext-ctrls-flash
-    ext-ctrls-image-source
-    ext-ctrls-image-process
-    ext-ctrls-codec
-    ext-ctrls-jpeg
-    ext-ctrls-dv
-    ext-ctrls-rf-tuner
-    ext-ctrls-fm-tx
-    ext-ctrls-fm-rx
-    ext-ctrls-detect
-    format
-    planar-apis
-    selection-api
-    crop
-    streaming-par
diff --git a/Documentation/media/uapi/v4l/compat.rst b/Documentation/media/uapi/v4l/compat.rst
deleted file mode 100644
index f35575a300b4..000000000000
--- a/Documentation/media/uapi/v4l/compat.rst
+++ /dev/null
@@ -1,25 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _compat:
-
-*******
-Changes
-*******
-
-The following chapters document the evolution of the V4L2 API, errata or
-extensions. They are also intended to help application and driver
-writers to port or update their code.
-
-
-.. toctree::
-    :maxdepth: 1
-
-    diff-v4l
-    hist-v4l2
diff --git a/Documentation/media/uapi/v4l/constraints.svg b/Documentation/media/uapi/v4l/constraints.svg
deleted file mode 100644
index 08f9f8b0985e..000000000000
--- a/Documentation/media/uapi/v4l/constraints.svg
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-    This file is dual-licensed: you can use it either under the terms
-    of the GPL 2.0 or the GFDL 1.1+ license, at your option. Note that this
-    dual licensing only applies to this file, and not this project as a
-    whole.
-
-    a) This file is free software; you can redistribute it and/or
-       modify it under the terms of the GNU General Public License as
-       published by the Free Software Foundation version 2 of
-       the License.
-
-       This file is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-    Or, alternatively,
-
-    b) Permission is granted to copy, distribute and/or modify this
-       document under the terms of the GNU Free Documentation License,
-       Version 1.1 or any later version published by the Free Software
-       Foundation, with no Invariant Sections, no Front-Cover Texts
-       and no Back-Cover Texts. A copy of the license is included at
-       Documentation/media/uapi/fdl-appendix.rst.
-
-    TODO: replace it to GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
--->
-<svg id="svg2" width="249.01mm" height="143.01mm" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" preserveAspectRatio="xMidYMid" version="1.2" viewBox="0 0 24900.998 14300.999" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><metadata id="metadata325"><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title/></cc:Work></rdf:RDF></metadata><defs id="defs4" class="ClipPathGroup"><marker id="marker6261" overflow="visible" orient="auto"><path id="path6263" transform="matrix(-.4 0 0 -.4 -4 0)" d="m0 0 5-5-17.5 5 17.5 5-5-5z" fill="#f00" fill-rule="evenodd" stroke="#f00" stroke-width="1pt"/></marker><marker id="marker6125" overflow="visible"
-orient="auto"><path id="path6127" transform="matrix(-.4 0 0 -.4 -4 0)" d="m0 0 5-5-17.5 5 17.5 5-5-5z" fill="#f00" fill-rule="evenodd" stroke="#f00" stroke-width="1pt"/></marker><marker id="marker6001" overflow="visible" orient="auto"><path id="path6003" transform="matrix(-.4 0 0 -.4 -4 0)" d="m0 0 5-5-17.5 5 17.5 5-5-5z" fill="#f00" fill-rule="evenodd" stroke="#f00" stroke-width="1pt"/></marker><marker id="marker5693" overflow="visible" orient="auto"><path id="path5695" transform="matrix(-.4 0 0 -.4 -4 0)" d="m0 0 5-5-17.5 5 17.5 5-5-5z" fill="#f00" fill-rule="evenodd" stroke="#f00" stroke-width="1pt"/></marker><marker id="marker5575" overflow="visible" orient="auto"><path id="path5577" transform="matrix(-.4 0 0 -.4 -4 0)" d="m0 0 5-5-17.5 5 17.5 5-5-5z" fill="#000080" fill-rule="evenodd" stroke="#000080" stroke-width="1pt"/></marker><marker id="marker5469" overflow="visible"
-orient="auto"><path id="path5471" transform="matrix(-.4 0 0 -.4 -4 0)" d="m0 0 5-5-17.5 5 17.5 5-5-5z" fill="#000080" fill-rule="evenodd" stroke="#000080" stroke-width="1pt"/></marker><marker id="marker5259" overflow="visible" orient="auto"><path id="path5261" transform="matrix(-.4 0 0 -.4 -4 0)" d="m0 0 5-5-17.5 5 17.5 5-5-5z" fill="#000080" fill-rule="evenodd" stroke="#000080" stroke-width="1pt"/></marker><marker id="Arrow2Mend" overflow="visible" orient="auto"><path id="path4241" transform="scale(-.6)" d="m8.7186 4.0337-10.926-4.0177 10.926-4.0177c-1.7455 2.3721-1.7354 5.6175-6e-7 8.0354z" fill="#000080" fill-rule="evenodd" stroke="#000080" stroke-linejoin="round" stroke-width=".625"/></marker></defs><g id="g204" class="com.sun.star.drawing.CustomShape" transform="translate(-1350,-3250)"><g id="id6"><rect id="rect207" class="BoundingBox" x="1350" y="3250" width="24901" height="14301"
-fill="none"/><path id="path209" d="m13800 17500h-12400v-14200h24800v14200h-12400z" fill="#fff"/><path id="path211" d="m13800 17500h-12400v-14200h24800v14200h-12400z" fill="none" stroke="#f00" stroke-linejoin="round" stroke-width="100"/><text id="text213" class="TextShape"><tspan id="tspan215" class="TextParagraph" font-family="sans-serif" font-size="846px" font-weight="400"><tspan id="tspan217" class="TextPosition" x="1652" y="17093" fill="#ff0000"><tspan id="tspan219"/><tspan id="tspan221">V4L2_SEL_FLAG_GE</tspan></tspan></tspan></text>
-</g></g><rect id="rect226" class="BoundingBox" x="3e3" y="2200" width="18101" height="10101" fill="none"/><path id="path228" d="m12050 12250h-9e3v-1e4h18000v1e4h-9e3z" fill="#fff"/><path id="path230" d="m12050 12250h-9e3v-1e4h18000v1e4h-9e3z" fill="none" stroke="#000" stroke-linejoin="round" stroke-width="100"/><text id="text232" class="TextShape" x="-1350" y="-3250"><tspan id="tspan234" class="TextParagraph" font-family="sans-serif" font-size="987px" font-weight="400"><tspan id="tspan236" class="TextPosition" x="3227" y="11503" fill="#000000"><tspan id="tspan238"/><tspan id="tspan240">ORIGINAL</tspan></tspan></tspan></text>
-<g id="g242" class="com.sun.star.drawing.CustomShape" transform="translate(-1350,-3250)"><g id="id8"><rect id="rect245" class="BoundingBox" x="7050" y="7950" width="7901" height="5501" fill="none"/><path id="path247" d="m11000 13400h-3900v-5400h7800v5400h-3900z" fill="#fff"/><path id="path249" d="m11000 13400h-3900v-5400h7800v5400h-3900z" fill="none" stroke="#3465a4" stroke-linejoin="round" stroke-width="100"/><text id="text251" class="TextShape"><tspan id="tspan253" class="TextParagraph" font-family="sans-serif" font-size="776px" font-weight="400"><tspan id="tspan255" class="TextPosition" x="7228" y="10969"><tspan id="tspan257" fill="#000080">V4L2_SEL_FLAG_LE</tspan></tspan></tspan></text>
-</g></g><rect id="rect262" class="BoundingBox" x="13700" y="7100" width="7101" height="101" fill="none"/><path id="path264" d="m20750 7150h-7e3" fill="none" marker-end="url(#Arrow2Mend)" stroke="#000080" stroke-linejoin="round" stroke-width="99.991"/><rect id="rect269" class="BoundingBox" x="3400" y="7100" width="2101" height="101" fill="none"/><path id="path271" d="m3450 7150h2e3" fill="none" marker-end="url(#marker5575)" stroke="#000080" stroke-linejoin="round" stroke-width="100"/><rect id="rect276" class="BoundingBox" x="9800" y="2900" width="101" height="1501" fill="none"/><path id="path278" d="m9850 2950v1400" fill="none" marker-end="url(#marker5259)" stroke="#000080" stroke-linejoin="round" stroke-width="100"/><rect id="rect283" class="BoundingBox" x="9600" y="10600" width="101" height="1301" fill="none"/><path id="path285" d="m9650 11850v-1200" fill="none"
-marker-end="url(#marker5469)" stroke="#000080" stroke-linejoin="round" stroke-width="100"/><rect id="rect290" class="BoundingBox" x="450" y="6850" width="2051" height="601" fill="none"/><path id="path292" d="m2450 7150h-2000.9" fill="none" marker-end="url(#marker6125)" stroke="#f00" stroke-linejoin="round" stroke-width="132.48"/><rect id="rect299" class="BoundingBox" x="21600" y="6750" width="2651" height="601" fill="none"/><path id="path301" d="m21650 7050h2522.6" fill="none" marker-end="url(#marker6001)" stroke="#f00" stroke-linejoin="round" stroke-width="120.41"/><rect id="rect308" class="BoundingBox" x="9550" y="550" width="601" height="1451" fill="none"/><path id="path310" d="m9837 1950v-1453" fill="none" marker-end="url(#marker6261)" stroke="#f00" stroke-linejoin="round" stroke-width="164.04"/><rect id="rect317" class="BoundingBox" x="9350" y="12500" width="601" height="1451"
-fill="none"/><path id="path319" d="m9650 12550v1505.2" fill="none" marker-end="url(#marker5693)" stroke="#f00" stroke-linejoin="round" stroke-width="166.96"/></svg>
diff --git a/Documentation/media/uapi/v4l/control.rst b/Documentation/media/uapi/v4l/control.rst
deleted file mode 100644
index ef62e088ff7a..000000000000
--- a/Documentation/media/uapi/v4l/control.rst
+++ /dev/null
@@ -1,512 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _control:
-
-*************
-User Controls
-*************
-
-Devices typically have a number of user-settable controls such as
-brightness, saturation and so on, which would be presented to the user
-on a graphical user interface. But, different devices will have
-different controls available, and furthermore, the range of possible
-values, and the default value will vary from device to device. The
-control ioctls provide the information and a mechanism to create a nice
-user interface for these controls that will work correctly with any
-device.
-
-All controls are accessed using an ID value. V4L2 defines several IDs
-for specific purposes. Drivers can also implement their own custom
-controls using ``V4L2_CID_PRIVATE_BASE``  [#f1]_ and higher values. The
-pre-defined control IDs have the prefix ``V4L2_CID_``, and are listed in
-:ref:`control-id`. The ID is used when querying the attributes of a
-control, and when getting or setting the current value.
-
-Generally applications should present controls to the user without
-assumptions about their purpose. Each control comes with a name string
-the user is supposed to understand. When the purpose is non-intuitive
-the driver writer should provide a user manual, a user interface plug-in
-or a driver specific panel application. Predefined IDs were introduced
-to change a few controls programmatically, for example to mute a device
-during a channel switch.
-
-Drivers may enumerate different controls after switching the current
-video input or output, tuner or modulator, or audio input or output.
-Different in the sense of other bounds, another default and current
-value, step size or other menu items. A control with a certain *custom*
-ID can also change name and type.
-
-If a control is not applicable to the current configuration of the
-device (for example, it doesn't apply to the current video input)
-drivers set the ``V4L2_CTRL_FLAG_INACTIVE`` flag.
-
-Control values are stored globally, they do not change when switching
-except to stay within the reported bounds. They also do not change e. g.
-when the device is opened or closed, when the tuner radio frequency is
-changed or generally never without application request.
-
-V4L2 specifies an event mechanism to notify applications when controls
-change value (see
-:ref:`VIDIOC_SUBSCRIBE_EVENT`, event
-``V4L2_EVENT_CTRL``), panel applications might want to make use of that
-in order to always reflect the correct control value.
-
-All controls use machine endianness.
-
-
-.. _control-id:
-
-Control IDs
-===========
-
-``V4L2_CID_BASE``
-    First predefined ID, equal to ``V4L2_CID_BRIGHTNESS``.
-
-``V4L2_CID_USER_BASE``
-    Synonym of ``V4L2_CID_BASE``.
-
-``V4L2_CID_BRIGHTNESS`` ``(integer)``
-    Picture brightness, or more precisely, the black level.
-
-``V4L2_CID_CONTRAST`` ``(integer)``
-    Picture contrast or luma gain.
-
-``V4L2_CID_SATURATION`` ``(integer)``
-    Picture color saturation or chroma gain.
-
-``V4L2_CID_HUE`` ``(integer)``
-    Hue or color balance.
-
-``V4L2_CID_AUDIO_VOLUME`` ``(integer)``
-    Overall audio volume. Note some drivers also provide an OSS or ALSA
-    mixer interface.
-
-``V4L2_CID_AUDIO_BALANCE`` ``(integer)``
-    Audio stereo balance. Minimum corresponds to all the way left,
-    maximum to right.
-
-``V4L2_CID_AUDIO_BASS`` ``(integer)``
-    Audio bass adjustment.
-
-``V4L2_CID_AUDIO_TREBLE`` ``(integer)``
-    Audio treble adjustment.
-
-``V4L2_CID_AUDIO_MUTE`` ``(boolean)``
-    Mute audio, i. e. set the volume to zero, however without affecting
-    ``V4L2_CID_AUDIO_VOLUME``. Like ALSA drivers, V4L2 drivers must mute
-    at load time to avoid excessive noise. Actually the entire device
-    should be reset to a low power consumption state.
-
-``V4L2_CID_AUDIO_LOUDNESS`` ``(boolean)``
-    Loudness mode (bass boost).
-
-``V4L2_CID_BLACK_LEVEL`` ``(integer)``
-    Another name for brightness (not a synonym of
-    ``V4L2_CID_BRIGHTNESS``). This control is deprecated and should not
-    be used in new drivers and applications.
-
-``V4L2_CID_AUTO_WHITE_BALANCE`` ``(boolean)``
-    Automatic white balance (cameras).
-
-``V4L2_CID_DO_WHITE_BALANCE`` ``(button)``
-    This is an action control. When set (the value is ignored), the
-    device will do a white balance and then hold the current setting.
-    Contrast this with the boolean ``V4L2_CID_AUTO_WHITE_BALANCE``,
-    which, when activated, keeps adjusting the white balance.
-
-``V4L2_CID_RED_BALANCE`` ``(integer)``
-    Red chroma balance.
-
-``V4L2_CID_BLUE_BALANCE`` ``(integer)``
-    Blue chroma balance.
-
-``V4L2_CID_GAMMA`` ``(integer)``
-    Gamma adjust.
-
-``V4L2_CID_WHITENESS`` ``(integer)``
-    Whiteness for grey-scale devices. This is a synonym for
-    ``V4L2_CID_GAMMA``. This control is deprecated and should not be
-    used in new drivers and applications.
-
-``V4L2_CID_EXPOSURE`` ``(integer)``
-    Exposure (cameras). [Unit?]
-
-``V4L2_CID_AUTOGAIN`` ``(boolean)``
-    Automatic gain/exposure control.
-
-``V4L2_CID_GAIN`` ``(integer)``
-    Gain control.
-
-    Primarily used to control gain on e.g. TV tuners but also on
-    webcams. Most devices control only digital gain with this control
-    but on some this could include analogue gain as well. Devices that
-    recognise the difference between digital and analogue gain use
-    controls ``V4L2_CID_DIGITAL_GAIN`` and ``V4L2_CID_ANALOGUE_GAIN``.
-
-``V4L2_CID_HFLIP`` ``(boolean)``
-    Mirror the picture horizontally.
-
-``V4L2_CID_VFLIP`` ``(boolean)``
-    Mirror the picture vertically.
-
-.. _v4l2-power-line-frequency:
-
-``V4L2_CID_POWER_LINE_FREQUENCY`` ``(enum)``
-    Enables a power line frequency filter to avoid flicker. Possible
-    values for ``enum v4l2_power_line_frequency`` are:
-    ``V4L2_CID_POWER_LINE_FREQUENCY_DISABLED`` (0),
-    ``V4L2_CID_POWER_LINE_FREQUENCY_50HZ`` (1),
-    ``V4L2_CID_POWER_LINE_FREQUENCY_60HZ`` (2) and
-    ``V4L2_CID_POWER_LINE_FREQUENCY_AUTO`` (3).
-
-``V4L2_CID_HUE_AUTO`` ``(boolean)``
-    Enables automatic hue control by the device. The effect of setting
-    ``V4L2_CID_HUE`` while automatic hue control is enabled is
-    undefined, drivers should ignore such request.
-
-``V4L2_CID_WHITE_BALANCE_TEMPERATURE`` ``(integer)``
-    This control specifies the white balance settings as a color
-    temperature in Kelvin. A driver should have a minimum of 2800
-    (incandescent) to 6500 (daylight). For more information about color
-    temperature see
-    `Wikipedia <http://en.wikipedia.org/wiki/Color_temperature>`__.
-
-``V4L2_CID_SHARPNESS`` ``(integer)``
-    Adjusts the sharpness filters in a camera. The minimum value
-    disables the filters, higher values give a sharper picture.
-
-``V4L2_CID_BACKLIGHT_COMPENSATION`` ``(integer)``
-    Adjusts the backlight compensation in a camera. The minimum value
-    disables backlight compensation.
-
-``V4L2_CID_CHROMA_AGC`` ``(boolean)``
-    Chroma automatic gain control.
-
-``V4L2_CID_CHROMA_GAIN`` ``(integer)``
-    Adjusts the Chroma gain control (for use when chroma AGC is
-    disabled).
-
-``V4L2_CID_COLOR_KILLER`` ``(boolean)``
-    Enable the color killer (i. e. force a black & white image in case
-    of a weak video signal).
-
-.. _v4l2-colorfx:
-
-``V4L2_CID_COLORFX`` ``(enum)``
-    Selects a color effect. The following values are defined:
-
-
-
-.. tabularcolumns:: |p{5.5cm}|p{12cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths: 11 24
-
-    * - ``V4L2_COLORFX_NONE``
-      - Color effect is disabled.
-    * - ``V4L2_COLORFX_ANTIQUE``
-      - An aging (old photo) effect.
-    * - ``V4L2_COLORFX_ART_FREEZE``
-      - Frost color effect.
-    * - ``V4L2_COLORFX_AQUA``
-      - Water color, cool tone.
-    * - ``V4L2_COLORFX_BW``
-      - Black and white.
-    * - ``V4L2_COLORFX_EMBOSS``
-      - Emboss, the highlights and shadows replace light/dark boundaries
-	and low contrast areas are set to a gray background.
-    * - ``V4L2_COLORFX_GRASS_GREEN``
-      - Grass green.
-    * - ``V4L2_COLORFX_NEGATIVE``
-      - Negative.
-    * - ``V4L2_COLORFX_SEPIA``
-      - Sepia tone.
-    * - ``V4L2_COLORFX_SKETCH``
-      - Sketch.
-    * - ``V4L2_COLORFX_SKIN_WHITEN``
-      - Skin whiten.
-    * - ``V4L2_COLORFX_SKY_BLUE``
-      - Sky blue.
-    * - ``V4L2_COLORFX_SOLARIZATION``
-      - Solarization, the image is partially reversed in tone, only color
-	values above or below a certain threshold are inverted.
-    * - ``V4L2_COLORFX_SILHOUETTE``
-      - Silhouette (outline).
-    * - ``V4L2_COLORFX_VIVID``
-      - Vivid colors.
-    * - ``V4L2_COLORFX_SET_CBCR``
-      - The Cb and Cr chroma components are replaced by fixed coefficients
-	determined by ``V4L2_CID_COLORFX_CBCR`` control.
-
-
-
-``V4L2_CID_COLORFX_CBCR`` ``(integer)``
-    Determines the Cb and Cr coefficients for ``V4L2_COLORFX_SET_CBCR``
-    color effect. Bits [7:0] of the supplied 32 bit value are
-    interpreted as Cr component, bits [15:8] as Cb component and bits
-    [31:16] must be zero.
-
-``V4L2_CID_AUTOBRIGHTNESS`` ``(boolean)``
-    Enable Automatic Brightness.
-
-``V4L2_CID_ROTATE`` ``(integer)``
-    Rotates the image by specified angle. Common angles are 90, 270 and
-    180. Rotating the image to 90 and 270 will reverse the height and
-    width of the display window. It is necessary to set the new height
-    and width of the picture using the
-    :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl according to the
-    rotation angle selected.
-
-``V4L2_CID_BG_COLOR`` ``(integer)``
-    Sets the background color on the current output device. Background
-    color needs to be specified in the RGB24 format. The supplied 32 bit
-    value is interpreted as bits 0-7 Red color information, bits 8-15
-    Green color information, bits 16-23 Blue color information and bits
-    24-31 must be zero.
-
-``V4L2_CID_ILLUMINATORS_1 V4L2_CID_ILLUMINATORS_2`` ``(boolean)``
-    Switch on or off the illuminator 1 or 2 of the device (usually a
-    microscope).
-
-``V4L2_CID_MIN_BUFFERS_FOR_CAPTURE`` ``(integer)``
-    This is a read-only control that can be read by the application and
-    used as a hint to determine the number of CAPTURE buffers to pass to
-    REQBUFS. The value is the minimum number of CAPTURE buffers that is
-    necessary for hardware to work.
-
-``V4L2_CID_MIN_BUFFERS_FOR_OUTPUT`` ``(integer)``
-    This is a read-only control that can be read by the application and
-    used as a hint to determine the number of OUTPUT buffers to pass to
-    REQBUFS. The value is the minimum number of OUTPUT buffers that is
-    necessary for hardware to work.
-
-.. _v4l2-alpha-component:
-
-``V4L2_CID_ALPHA_COMPONENT`` ``(integer)``
-    Sets the alpha color component. When a capture device (or capture
-    queue of a mem-to-mem device) produces a frame format that includes
-    an alpha component (e.g.
-    :ref:`packed RGB image formats <pixfmt-rgb>`) and the alpha value
-    is not defined by the device or the mem-to-mem input data this
-    control lets you select the alpha component value of all pixels.
-    When an output device (or output queue of a mem-to-mem device)
-    consumes a frame format that doesn't include an alpha component and
-    the device supports alpha channel processing this control lets you
-    set the alpha component value of all pixels for further processing
-    in the device.
-
-``V4L2_CID_LASTP1``
-    End of the predefined control IDs (currently
-    ``V4L2_CID_ALPHA_COMPONENT`` + 1).
-
-``V4L2_CID_PRIVATE_BASE``
-    ID of the first custom (driver specific) control. Applications
-    depending on particular custom controls should check the driver name
-    and version, see :ref:`querycap`.
-
-Applications can enumerate the available controls with the
-:ref:`VIDIOC_QUERYCTRL` and
-:ref:`VIDIOC_QUERYMENU <VIDIOC_QUERYCTRL>` ioctls, get and set a
-control value with the :ref:`VIDIOC_G_CTRL <VIDIOC_G_CTRL>` and
-:ref:`VIDIOC_S_CTRL <VIDIOC_G_CTRL>` ioctls. Drivers must implement
-``VIDIOC_QUERYCTRL``, ``VIDIOC_G_CTRL`` and ``VIDIOC_S_CTRL`` when the
-device has one or more controls, ``VIDIOC_QUERYMENU`` when it has one or
-more menu type controls.
-
-
-.. _enum_all_controls:
-
-Example: Enumerating all controls
-=================================
-
-.. code-block:: c
-
-    struct v4l2_queryctrl queryctrl;
-    struct v4l2_querymenu querymenu;
-
-    static void enumerate_menu(__u32 id)
-    {
-	printf("  Menu items:\\n");
-
-	memset(&querymenu, 0, sizeof(querymenu));
-	querymenu.id = id;
-
-	for (querymenu.index = queryctrl.minimum;
-	     querymenu.index <= queryctrl.maximum;
-	     querymenu.index++) {
-	    if (0 == ioctl(fd, VIDIOC_QUERYMENU, &querymenu)) {
-		printf("  %s\\n", querymenu.name);
-	    }
-	}
-    }
-
-    memset(&queryctrl, 0, sizeof(queryctrl));
-
-    queryctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL;
-    while (0 == ioctl(fd, VIDIOC_QUERYCTRL, &queryctrl)) {
-	if (!(queryctrl.flags & V4L2_CTRL_FLAG_DISABLED)) {
-	    printf("Control %s\\n", queryctrl.name);
-
-	    if (queryctrl.type == V4L2_CTRL_TYPE_MENU)
-	        enumerate_menu(queryctrl.id);
-        }
-
-	queryctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
-    }
-    if (errno != EINVAL) {
-	perror("VIDIOC_QUERYCTRL");
-	exit(EXIT_FAILURE);
-    }
-
-Example: Enumerating all controls including compound controls
-=============================================================
-
-.. code-block:: c
-
-    struct v4l2_query_ext_ctrl query_ext_ctrl;
-
-    memset(&query_ext_ctrl, 0, sizeof(query_ext_ctrl));
-
-    query_ext_ctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL | V4L2_CTRL_FLAG_NEXT_COMPOUND;
-    while (0 == ioctl(fd, VIDIOC_QUERY_EXT_CTRL, &query_ext_ctrl)) {
-	if (!(query_ext_ctrl.flags & V4L2_CTRL_FLAG_DISABLED)) {
-	    printf("Control %s\\n", query_ext_ctrl.name);
-
-	    if (query_ext_ctrl.type == V4L2_CTRL_TYPE_MENU)
-	        enumerate_menu(query_ext_ctrl.id);
-        }
-
-	query_ext_ctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL | V4L2_CTRL_FLAG_NEXT_COMPOUND;
-    }
-    if (errno != EINVAL) {
-	perror("VIDIOC_QUERY_EXT_CTRL");
-	exit(EXIT_FAILURE);
-    }
-
-Example: Enumerating all user controls (old style)
-==================================================
-
-.. code-block:: c
-
-
-    memset(&queryctrl, 0, sizeof(queryctrl));
-
-    for (queryctrl.id = V4L2_CID_BASE;
-	 queryctrl.id < V4L2_CID_LASTP1;
-	 queryctrl.id++) {
-	if (0 == ioctl(fd, VIDIOC_QUERYCTRL, &queryctrl)) {
-	    if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED)
-		continue;
-
-	    printf("Control %s\\n", queryctrl.name);
-
-	    if (queryctrl.type == V4L2_CTRL_TYPE_MENU)
-		enumerate_menu(queryctrl.id);
-	} else {
-	    if (errno == EINVAL)
-		continue;
-
-	    perror("VIDIOC_QUERYCTRL");
-	    exit(EXIT_FAILURE);
-	}
-    }
-
-    for (queryctrl.id = V4L2_CID_PRIVATE_BASE;;
-	 queryctrl.id++) {
-	if (0 == ioctl(fd, VIDIOC_QUERYCTRL, &queryctrl)) {
-	    if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED)
-		continue;
-
-	    printf("Control %s\\n", queryctrl.name);
-
-	    if (queryctrl.type == V4L2_CTRL_TYPE_MENU)
-		enumerate_menu(queryctrl.id);
-	} else {
-	    if (errno == EINVAL)
-		break;
-
-	    perror("VIDIOC_QUERYCTRL");
-	    exit(EXIT_FAILURE);
-	}
-    }
-
-
-Example: Changing controls
-==========================
-
-.. code-block:: c
-
-    struct v4l2_queryctrl queryctrl;
-    struct v4l2_control control;
-
-    memset(&queryctrl, 0, sizeof(queryctrl));
-    queryctrl.id = V4L2_CID_BRIGHTNESS;
-
-    if (-1 == ioctl(fd, VIDIOC_QUERYCTRL, &queryctrl)) {
-	if (errno != EINVAL) {
-	    perror("VIDIOC_QUERYCTRL");
-	    exit(EXIT_FAILURE);
-	} else {
-	    printf("V4L2_CID_BRIGHTNESS is not supportedn");
-	}
-    } else if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) {
-	printf("V4L2_CID_BRIGHTNESS is not supportedn");
-    } else {
-	memset(&control, 0, sizeof (control));
-	control.id = V4L2_CID_BRIGHTNESS;
-	control.value = queryctrl.default_value;
-
-	if (-1 == ioctl(fd, VIDIOC_S_CTRL, &control)) {
-	    perror("VIDIOC_S_CTRL");
-	    exit(EXIT_FAILURE);
-	}
-    }
-
-    memset(&control, 0, sizeof(control));
-    control.id = V4L2_CID_CONTRAST;
-
-    if (0 == ioctl(fd, VIDIOC_G_CTRL, &control)) {
-	control.value += 1;
-
-	/* The driver may clamp the value or return ERANGE, ignored here */
-
-	if (-1 == ioctl(fd, VIDIOC_S_CTRL, &control)
-	    && errno != ERANGE) {
-	    perror("VIDIOC_S_CTRL");
-	    exit(EXIT_FAILURE);
-	}
-    /* Ignore if V4L2_CID_CONTRAST is unsupported */
-    } else if (errno != EINVAL) {
-	perror("VIDIOC_G_CTRL");
-	exit(EXIT_FAILURE);
-    }
-
-    control.id = V4L2_CID_AUDIO_MUTE;
-    control.value = 1; /* silence */
-
-    /* Errors ignored */
-    ioctl(fd, VIDIOC_S_CTRL, &control);
-
-.. [#f1]
-   The use of ``V4L2_CID_PRIVATE_BASE`` is problematic because different
-   drivers may use the same ``V4L2_CID_PRIVATE_BASE`` ID for different
-   controls. This makes it hard to programmatically set such controls
-   since the meaning of the control with that ID is driver dependent. In
-   order to resolve this drivers use unique IDs and the
-   ``V4L2_CID_PRIVATE_BASE`` IDs are mapped to those unique IDs by the
-   kernel. Consider these ``V4L2_CID_PRIVATE_BASE`` IDs as aliases to
-   the real IDs.
-
-   Many applications today still use the ``V4L2_CID_PRIVATE_BASE`` IDs
-   instead of using :ref:`VIDIOC_QUERYCTRL` with
-   the ``V4L2_CTRL_FLAG_NEXT_CTRL`` flag to enumerate all IDs, so
-   support for ``V4L2_CID_PRIVATE_BASE`` is still around.
diff --git a/Documentation/media/uapi/v4l/crop.rst b/Documentation/media/uapi/v4l/crop.rst
deleted file mode 100644
index ada7c22e6291..000000000000
--- a/Documentation/media/uapi/v4l/crop.rst
+++ /dev/null
@@ -1,324 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _crop:
-
-*****************************************************
-Image Cropping, Insertion and Scaling -- the CROP API
-*****************************************************
-
-.. note::
-
-   The CROP API is mostly superseded by the newer :ref:`SELECTION API
-   <selection-api>`. The new API should be preferred in most cases,
-   with the exception of pixel aspect ratio detection, which is
-   implemented by :ref:`VIDIOC_CROPCAP <VIDIOC_CROPCAP>` and has no
-   equivalent in the SELECTION API. See :ref:`selection-vs-crop` for a
-   comparison of the two APIs.
-
-Some video capture devices can sample a subsection of the picture and
-shrink or enlarge it to an image of arbitrary size. We call these
-abilities cropping and scaling. Some video output devices can scale an
-image up or down and insert it at an arbitrary scan line and horizontal
-offset into a video signal.
-
-Applications can use the following API to select an area in the video
-signal, query the default area and the hardware limits.
-
-.. note::
-
-   Despite their name, the :ref:`VIDIOC_CROPCAP <VIDIOC_CROPCAP>`,
-   :ref:`VIDIOC_G_CROP <VIDIOC_G_CROP>` and :ref:`VIDIOC_S_CROP
-   <VIDIOC_G_CROP>` ioctls apply to input as well as output devices.
-
-Scaling requires a source and a target. On a video capture or overlay
-device the source is the video signal, and the cropping ioctls determine
-the area actually sampled. The target are images read by the application
-or overlaid onto the graphics screen. Their size (and position for an
-overlay) is negotiated with the :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>`
-and :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctls.
-
-On a video output device the source are the images passed in by the
-application, and their size is again negotiated with the
-:ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` and :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`
-ioctls, or may be encoded in a compressed video stream. The target is
-the video signal, and the cropping ioctls determine the area where the
-images are inserted.
-
-Source and target rectangles are defined even if the device does not
-support scaling or the :ref:`VIDIOC_G_CROP <VIDIOC_G_CROP>` and
-:ref:`VIDIOC_S_CROP <VIDIOC_G_CROP>` ioctls. Their size (and position
-where applicable) will be fixed in this case.
-
-.. note::
-
-   All capture and output devices that support the CROP or SELECTION
-   API will also support the :ref:`VIDIOC_CROPCAP <VIDIOC_CROPCAP>`
-   ioctl.
-
-Cropping Structures
-===================
-
-
-.. _crop-scale:
-
-.. kernel-figure:: crop.svg
-    :alt:    crop.svg
-    :align:  center
-
-    Image Cropping, Insertion and Scaling
-
-    The cropping, insertion and scaling process
-
-
-
-For capture devices the coordinates of the top left corner, width and
-height of the area which can be sampled is given by the ``bounds``
-substructure of the struct :c:type:`v4l2_cropcap` returned
-by the :ref:`VIDIOC_CROPCAP <VIDIOC_CROPCAP>` ioctl. To support a wide
-range of hardware this specification does not define an origin or units.
-However by convention drivers should horizontally count unscaled samples
-relative to 0H (the leading edge of the horizontal sync pulse, see
-:ref:`vbi-hsync`). Vertically ITU-R line numbers of the first field
-(see ITU R-525 line numbering for :ref:`525 lines <vbi-525>` and for
-:ref:`625 lines <vbi-625>`), multiplied by two if the driver
-can capture both fields.
-
-The top left corner, width and height of the source rectangle, that is
-the area actually sampled, is given by struct
-:c:type:`v4l2_crop` using the same coordinate system as
-struct :c:type:`v4l2_cropcap`. Applications can use the
-:ref:`VIDIOC_G_CROP <VIDIOC_G_CROP>` and :ref:`VIDIOC_S_CROP <VIDIOC_G_CROP>`
-ioctls to get and set this rectangle. It must lie completely within the
-capture boundaries and the driver may further adjust the requested size
-and/or position according to hardware limitations.
-
-Each capture device has a default source rectangle, given by the
-``defrect`` substructure of struct
-:c:type:`v4l2_cropcap`. The center of this rectangle
-shall align with the center of the active picture area of the video
-signal, and cover what the driver writer considers the complete picture.
-Drivers shall reset the source rectangle to the default when the driver
-is first loaded, but not later.
-
-For output devices these structures and ioctls are used accordingly,
-defining the *target* rectangle where the images will be inserted into
-the video signal.
-
-
-Scaling Adjustments
-===================
-
-Video hardware can have various cropping, insertion and scaling
-limitations. It may only scale up or down, support only discrete scaling
-factors, or have different scaling abilities in horizontal and vertical
-direction. Also it may not support scaling at all. At the same time the
-struct :c:type:`v4l2_crop` rectangle may have to be aligned,
-and both the source and target rectangles may have arbitrary upper and
-lower size limits. In particular the maximum ``width`` and ``height`` in
-struct :c:type:`v4l2_crop` may be smaller than the struct
-:c:type:`v4l2_cropcap`. ``bounds`` area. Therefore, as
-usual, drivers are expected to adjust the requested parameters and
-return the actual values selected.
-
-Applications can change the source or the target rectangle first, as
-they may prefer a particular image size or a certain area in the video
-signal. If the driver has to adjust both to satisfy hardware
-limitations, the last requested rectangle shall take priority, and the
-driver should preferably adjust the opposite one. The
-:ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` ioctl however shall not change
-the driver state and therefore only adjust the requested rectangle.
-
-Suppose scaling on a video capture device is restricted to a factor 1:1
-or 2:1 in either direction and the target image size must be a multiple
-of 16 × 16 pixels. The source cropping rectangle is set to defaults,
-which are also the upper limit in this example, of 640 × 400 pixels at
-offset 0, 0. An application requests an image size of 300 × 225 pixels,
-assuming video will be scaled down from the "full picture" accordingly.
-The driver sets the image size to the closest possible values 304 × 224,
-then chooses the cropping rectangle closest to the requested size, that
-is 608 × 224 (224 × 2:1 would exceed the limit 400). The offset 0, 0 is
-still valid, thus unmodified. Given the default cropping rectangle
-reported by :ref:`VIDIOC_CROPCAP <VIDIOC_CROPCAP>` the application can
-easily propose another offset to center the cropping rectangle.
-
-Now the application may insist on covering an area using a picture
-aspect ratio closer to the original request, so it asks for a cropping
-rectangle of 608 × 456 pixels. The present scaling factors limit
-cropping to 640 × 384, so the driver returns the cropping size 608 × 384
-and adjusts the image size to closest possible 304 × 192.
-
-
-Examples
-========
-
-Source and target rectangles shall remain unchanged across closing and
-reopening a device, such that piping data into or out of a device will
-work without special preparations. More advanced applications should
-ensure the parameters are suitable before starting I/O.
-
-.. note::
-
-   On the next two examples, a video capture device is assumed;
-   change ``V4L2_BUF_TYPE_VIDEO_CAPTURE`` for other types of device.
-
-Example: Resetting the cropping parameters
-==========================================
-
-.. code-block:: c
-
-    struct v4l2_cropcap cropcap;
-    struct v4l2_crop crop;
-
-    memset (&cropcap, 0, sizeof (cropcap));
-    cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
-    if (-1 == ioctl (fd, VIDIOC_CROPCAP, &cropcap)) {
-	perror ("VIDIOC_CROPCAP");
-	exit (EXIT_FAILURE);
-    }
-
-    memset (&crop, 0, sizeof (crop));
-    crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-    crop.c = cropcap.defrect;
-
-    /* Ignore if cropping is not supported (EINVAL). */
-
-    if (-1 == ioctl (fd, VIDIOC_S_CROP, &crop)
-	&& errno != EINVAL) {
-	perror ("VIDIOC_S_CROP");
-	exit (EXIT_FAILURE);
-    }
-
-
-Example: Simple downscaling
-===========================
-
-.. code-block:: c
-
-    struct v4l2_cropcap cropcap;
-    struct v4l2_format format;
-
-    reset_cropping_parameters ();
-
-    /* Scale down to 1/4 size of full picture. */
-
-    memset (&format, 0, sizeof (format)); /* defaults */
-
-    format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
-    format.fmt.pix.width = cropcap.defrect.width >> 1;
-    format.fmt.pix.height = cropcap.defrect.height >> 1;
-    format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
-
-    if (-1 == ioctl (fd, VIDIOC_S_FMT, &format)) {
-	perror ("VIDIOC_S_FORMAT");
-	exit (EXIT_FAILURE);
-    }
-
-    /* We could check the actual image size now, the actual scaling factor
-       or if the driver can scale at all. */
-
-Example: Selecting an output area
-=================================
-
-.. note:: This example assumes an output device.
-
-.. code-block:: c
-
-    struct v4l2_cropcap cropcap;
-    struct v4l2_crop crop;
-
-    memset (&cropcap, 0, sizeof (cropcap));
-    cropcap.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
-
-    if (-1 == ioctl (fd, VIDIOC_CROPCAP;, &cropcap)) {
-	perror ("VIDIOC_CROPCAP");
-	exit (EXIT_FAILURE);
-    }
-
-    memset (&crop, 0, sizeof (crop));
-
-    crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
-    crop.c = cropcap.defrect;
-
-    /* Scale the width and height to 50 % of their original size
-       and center the output. */
-
-    crop.c.width /= 2;
-    crop.c.height /= 2;
-    crop.c.left += crop.c.width / 2;
-    crop.c.top += crop.c.height / 2;
-
-    /* Ignore if cropping is not supported (EINVAL). */
-
-    if (-1 == ioctl (fd, VIDIOC_S_CROP, &crop)
-	&& errno != EINVAL) {
-	perror ("VIDIOC_S_CROP");
-	exit (EXIT_FAILURE);
-    }
-
-Example: Current scaling factor and pixel aspect
-================================================
-
-.. note:: This example assumes a video capture device.
-
-.. code-block:: c
-
-    struct v4l2_cropcap cropcap;
-    struct v4l2_crop crop;
-    struct v4l2_format format;
-    double hscale, vscale;
-    double aspect;
-    int dwidth, dheight;
-
-    memset (&cropcap, 0, sizeof (cropcap));
-    cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
-    if (-1 == ioctl (fd, VIDIOC_CROPCAP, &cropcap)) {
-	perror ("VIDIOC_CROPCAP");
-	exit (EXIT_FAILURE);
-    }
-
-    memset (&crop, 0, sizeof (crop));
-    crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
-    if (-1 == ioctl (fd, VIDIOC_G_CROP, &crop)) {
-	if (errno != EINVAL) {
-	    perror ("VIDIOC_G_CROP");
-	    exit (EXIT_FAILURE);
-	}
-
-	/* Cropping not supported. */
-	crop.c = cropcap.defrect;
-    }
-
-    memset (&format, 0, sizeof (format));
-    format.fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
-    if (-1 == ioctl (fd, VIDIOC_G_FMT, &format)) {
-	perror ("VIDIOC_G_FMT");
-	exit (EXIT_FAILURE);
-    }
-
-    /* The scaling applied by the driver. */
-
-    hscale = format.fmt.pix.width / (double) crop.c.width;
-    vscale = format.fmt.pix.height / (double) crop.c.height;
-
-    aspect = cropcap.pixelaspect.numerator /
-	 (double) cropcap.pixelaspect.denominator;
-    aspect = aspect * hscale / vscale;
-
-    /* Devices following ITU-R BT.601 do not capture
-       square pixels. For playback on a computer monitor
-       we should scale the images to this size. */
-
-    dwidth = format.fmt.pix.width / aspect;
-    dheight = format.fmt.pix.height;
diff --git a/Documentation/media/uapi/v4l/crop.svg b/Documentation/media/uapi/v4l/crop.svg
deleted file mode 100644
index 32d72598d135..000000000000
--- a/Documentation/media/uapi/v4l/crop.svg
+++ /dev/null
@@ -1,290 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!--
-    Permission is granted to copy, distribute and/or modify this
-    document under the terms of the GNU Free Documentation License,
-    Version 1.1 or any later version published by the Free Software
-    Foundation, with no Invariant Sections, no Front-Cover Texts
-    and no Back-Cover Texts. A copy of the license is included at
-    Documentation/media/uapi/fdl-appendix.rst.
-
-    TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
--->
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   id="svg2"
-   version="1.1"
-   inkscape:version="0.91 r13725"
-   xml:space="preserve"
-   width="208.59436mm"
-   height="95.859146mm"
-   viewBox="0 0 739.11388 339.6584"
-   sodipodi:docname="crop.svg"><metadata
-     id="metadata8"><rdf:RDF><cc:Work
-	 rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
-	   rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
-     id="defs6"><clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath44"><path
-	 d="m 0,0 0,1895 4118,0 L 4118,0 0,0 Z m 3051.62,250.48 8.19,17.01 -46.93,23.31 29.61,-25.515 -38.12,8.505 47.25,-23.31 z m -1559.25,800.73 -8.5,-17.01 46.93,-23.31 -29.29,25.2 37.8,-8.19 -46.94,23.31 z"
-	 id="path46"
-	 inkscape:connector-curvature="0"
-	 style="clip-rule:evenodd" /></clipPath><clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath64"><path
-	 d="m 0,0 0,1895 4118,0 0,-1626 -1,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -1,0 0,-1 1,0 0,-1 1,0 0,-1 2,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 2,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 2,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 -4,0 0,1 -5,0 0,1 -4,0 0,1 -5,0 0,1 -4,0 0,1 -4,0 0,1 -4,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 1,0 0,3 1,0 0,2 1,0 0,2 1,0 L 4118,0 0,0 Z m 4074,272 0,-1 1,0 0,1 -1,0 z m -1486,743 0,-1 1,0 0,1 -1,0 z m -2,1 0,-1 1,0 0,1 -1,0 0,1 -1,0 0,1 -1,0 0,1 -1,0 0,1 -1,0 0,1 -1,0 0,1 -2,0 0,1 -1,0 0,1 -1,0 0,1 -1,0 0,1 -1,0 0,1 -1,0 0,1 -2,0 0,1 -1,0 0,1 -1,0 0,1
--1,0 0,1 -1,0 0,1 -1,0 0,1 -2,0 0,1 -1,0 0,2 2,0 0,-1 4,0 0,-1 5,0 0,-1 4,0 0,-1 5,0 0,-1 5,0 0,-1 4,0 0,-1 3,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -3,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,-2 -1,0 0,-2 -1,0 0,-2 -1,0 0,-2 -1,0 0,-2 -1,0 0,-2 -1,0 0,-2 -1,0 0,-2 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 z"
-	 id="path66"
-	 inkscape:connector-curvature="0"
-	 style="clip-rule:evenodd" /></clipPath><clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath84"><path
-	 d="m 0,0 0,1895 4118,0 0,-136 -3,0 0,-1 -11,0 0,-1 -11,0 0,-1 -11,0 0,-1 -11,0 0,-1 5,0 0,-1 6,0 0,-1 7,0 0,-1 6,0 0,-1 6,0 0,-1 4,0 0,-1 -1,0 0,-1 -3,0 0,-1 -3,0 0,-1 -2,0 0,-1 -3,0 0,-1 -3,0 0,-1 -3,0 0,-1 -3,0 0,-1 -3,0 0,-1 -3,0 0,-1 -3,0 0,-1 7,0 0,1 11,0 0,1 11,0 0,1 11,0 0,1 3,0 L 4118,0 0,0 Z m 2552,1599 0,-1 2,0 0,1 11,0 0,1 11,0 0,1 11,0 0,1 11,0 0,1 -4,0 0,1 -7,0 0,1 -6,0 0,1 -7,0 0,1 -6,0 0,1 -3,0 0,1 2,0 0,1 2,0 0,1 3,0 0,1 3,0 0,1 3,0 0,1 3,0 0,1 3,0 0,1 2,0 0,1 3,0 0,1 3,0 0,1 3,0 0,1 -7,0 0,-1 -12,0 0,-1 -11,0 0,-1 -11,0 0,-1 -4,0 0,-1 1,0 0,-12 1,0 0,-4 z"
-	 id="path86"
-	 inkscape:connector-curvature="0"
-	 style="clip-rule:evenodd" /></clipPath><clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath104"><path
-	 d="m 0,0 0,1895 4118,0 L 4118,0 0,0 Z m 3056.98,1740.43 -1.58,18.9 -52.6,-4.72 38.74,-6.3 -36.85,-12.6 52.29,4.72 z m -1570.28,-123.79 1.58,-18.9 52.6,4.72 -38.43,5.99 36.54,12.91 -52.29,-4.72 z"
-	 id="path106"
-	 inkscape:connector-curvature="0"
-	 style="clip-rule:evenodd" /></clipPath></defs><sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="1920"
-     inkscape:window-height="997"
-     id="namedview4"
-     showgrid="false"
-     inkscape:zoom="0.99625351"
-     inkscape:cx="-73.227122"
-     inkscape:cy="114.17568"
-     inkscape:window-x="1920"
-     inkscape:window-y="30"
-     inkscape:window-maximized="1"
-     inkscape:current-layer="g10"
-     units="mm"
-     fit-margin-top="0"
-     fit-margin-left="0"
-     fit-margin-right="0"
-     fit-margin-bottom="0" /><g
-     id="g10"
-     inkscape:groupmode="layer"
-     inkscape:label="crop"
-     transform="matrix(1.25,0,0,-1.25,-0.35237428,339.91141)"><path
-       d="m 411.08474,0.37218832 0,271.38551168 -37.17867,0 0,-1.94649 -205.3611,1.94649 0,-2.58046 -155.911966,0 0,-1.90192 17.977663,-264.3219406 -17.977663,0 0,-2.58119108 193.135216,0 0,2.58119108 -137.934309,0 0,264.3219406 333.650679,0 0,-264.3219406 -177.10547,0 0,-1.947197 149.52695,0 0,-0.63399408"
-       style="fill:#7f7f7f;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path16"
-       inkscape:connector-curvature="0" /><path
-       d="m 411.08474,0.37218832 0,271.38551168 -37.17867,0 0,-1.94649 -205.3611,1.94649 0,-2.58046 -155.911966,0 0,-1.90192 17.977663,-264.3219406 -17.977663,0 0,-2.58119108 193.135216,0 0,2.58119108 -137.934309,0 0,264.3219406 333.650679,0 0,-264.3219406 -177.10547,0 0,-1.947197 149.52695,0 0,-0.63399408 37.17867,0 z"
-       style="fill:none;stroke:#000000;stroke-width:0.33962813;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path18"
-       inkscape:connector-curvature="0" /><path
-       d="m 40.256106,6.8024838 366.979524,0 0,253.4078762 -366.979524,0 0,-253.4078762 z"
-       style="fill:none;stroke:#ff0000;stroke-width:0.33962813;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path20"
-       inkscape:connector-curvature="0" /><path
-       d="m 77.434066,7.4364707 316.352284,0 0,244.4416893 -316.352284,0 0,-244.4416893 z"
-       style="fill:none;stroke:#0000ff;stroke-width:0.33962813;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path22"
-       inkscape:connector-curvature="0" /><path
-       d="m 214.41669,149.49157 152.83195,0 0,81.51075 -152.83195,0 0,-81.51075 z"
-       style="fill:none;stroke:#00b000;stroke-width:0.33962813;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path24"
-       inkscape:connector-curvature="0" /><path
-       d="m 438.57126,37.414285 152.83194,0 0,213.966445 -152.83194,0 0,-213.966445 z"
-       style="fill:none;stroke:#d100d1;stroke-width:0.33962813;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path26"
-       inkscape:connector-curvature="0" /><path
-       d="m 0.45168907,271.7577 168.09328093,0 0,-2.58046 -155.911966,0 0,-1.90192 17.977663,0 0,-264.3219406 -17.977663,0 0,-2.58119108 -12.18131493,0"
-       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path28"
-       inkscape:connector-curvature="0" /><path
-       d="m 0.45168907,271.7577 168.09328093,0 0,-2.58046 -155.911966,0 0,-1.90192 17.977663,0 0,-264.3219406 -17.977663,0 0,-2.58119108 -12.18131493,0 0,271.38551168 z"
-       style="fill:none;stroke:#000000;stroke-width:0.33962813;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path30"
-       inkscape:connector-curvature="0" /><path
-       d="m 373.90607,0.37218832 0,0.63399408 -149.52695,0 0,1.947197 -18.6109,0 0,-2.58119108"
-       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path32"
-       inkscape:connector-curvature="0" /><path
-       d="m 373.90607,0.37218832 0,0.63399408 -149.52695,0 0,1.947197 -18.6109,0 0,-2.58119108 168.13785,0 z"
-       style="fill:none;stroke:#000000;stroke-width:0.33962813;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path34"
-       inkscape:connector-curvature="0" /><path
-       d="m 205.76822,271.7577 168.13785,0 0,-1.94649 -149.52695,0 0,-2.53589 -18.6109,0"
-       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path36"
-       inkscape:connector-curvature="0" /><path
-       d="m 205.76822,271.7577 168.13785,0 0,-1.94649 -149.52695,0 0,-2.53589 -18.6109,0 0,4.48238 z"
-       style="fill:none;stroke:#000000;stroke-width:0.33962813;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path38"
-       inkscape:connector-curvature="0" /><g
-       id="g40"
-       transform="matrix(0.14375794,0,0,0.14375794,-0.12334269,-0.08856738)"><g
-	 clip-path="url(#clipPath44)"
-	 id="g42"><path
-	   inkscape:connector-curvature="0"
-	   id="path48"
-	   style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	   d="M 1492.37,1040.5 3051.62,260.875" /></g></g><g
-       id="g50"
-       transform="matrix(0.14375794,0,0,0.14375794,-0.12334269,-0.08856738)"><path
-	 inkscape:connector-curvature="0"
-	 id="path52"
-	 style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-	 d="m 1539.31,1027.9 -37.8,8.19 29.29,-25.2 8.51,17.01" /><path
-	 inkscape:connector-curvature="0"
-	 id="path54"
-	 style="fill:none;stroke:#000000;stroke-width:4.7249999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 1539.31,1027.9 -37.8,8.19 29.29,-25.2 8.51,17.01 z" /><path
-	 inkscape:connector-curvature="0"
-	 id="path56"
-	 style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-	 d="m 3004.37,273.79 38.12,-8.505 -29.61,25.515 -8.51,-17.01" /><path
-	 inkscape:connector-curvature="0"
-	 id="path58"
-	 style="fill:none;stroke:#000000;stroke-width:4.7249999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 3004.37,273.79 38.12,-8.505 -29.61,25.515 -8.51,-17.01 z" /></g><g
-       id="g60"
-       transform="matrix(0.14375794,0,0,0.14375794,-0.12334269,-0.08856738)"><g
-	 clip-path="url(#clipPath64)"
-	 id="g62"><path
-	   inkscape:connector-curvature="0"
-	   id="path68"
-	   style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	   d="M 2555.5,1040.5 4114.75,260.875" /></g></g><g
-       id="g70"
-       transform="matrix(0.14375794,0,0,0.14375794,-0.12334269,-0.08856738)"><path
-	 inkscape:connector-curvature="0"
-	 id="path72"
-	 style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-	 d="m 2602.43,1027.9 -37.8,8.19 29.3,-25.2 8.5,17.01" /><path
-	 inkscape:connector-curvature="0"
-	 id="path74"
-	 style="fill:none;stroke:#000000;stroke-width:4.7249999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 2602.43,1027.9 -37.8,8.19 29.3,-25.2 8.5,17.01 z" /><path
-	 inkscape:connector-curvature="0"
-	 id="path76"
-	 style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-	 d="m 4067.5,273.79 38.11,-8.505 -29.61,25.515 -8.5,-17.01" /><path
-	 inkscape:connector-curvature="0"
-	 id="path78"
-	 style="fill:none;stroke:#000000;stroke-width:4.7249999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 4067.5,273.79 38.11,-8.505 -29.61,25.515 -8.5,-17.01 z" /></g><g
-       id="g80"
-       transform="matrix(0.14375794,0,0,0.14375794,-0.12334269,-0.08856738)"><g
-	 clip-path="url(#clipPath84)"
-	 id="g82"><path
-	   inkscape:connector-curvature="0"
-	   id="path88"
-	   style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	   d="m 2555.5,1607.5 1559.25,141.75" /></g></g><g
-       id="g90"
-       transform="matrix(0.14375794,0,0,0.14375794,-0.12334269,-0.08856738)"><path
-	 inkscape:connector-curvature="0"
-	 id="path92"
-	 style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-	 d="m 2602.12,1621.36 -36.54,-12.91 38.43,-5.99 -1.89,18.9" /><path
-	 inkscape:connector-curvature="0"
-	 id="path94"
-	 style="fill:none;stroke:#000000;stroke-width:4.7249999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 2602.12,1621.36 -36.54,-12.91 38.43,-5.99 -1.89,18.9 z" /><path
-	 inkscape:connector-curvature="0"
-	 id="path96"
-	 style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-	 d="m 4067.81,1735.71 36.86,12.6 -38.75,6.3 1.89,-18.9" /><path
-	 inkscape:connector-curvature="0"
-	 id="path98"
-	 style="fill:none;stroke:#000000;stroke-width:4.7249999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 4067.81,1735.71 36.86,12.6 -38.75,6.3 1.89,-18.9 z" /></g><g
-       id="g100"
-       transform="matrix(0.14375794,0,0,0.14375794,-0.12334269,-0.08856738)"><g
-	 clip-path="url(#clipPath104)"
-	 id="g102"><path
-	   inkscape:connector-curvature="0"
-	   id="path108"
-	   style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	   d="m 1492.37,1607.5 1559.25,141.75" /></g></g><path
-       d="m 221.11869,232.99481 -5.25292,-1.85592 5.52462,-0.86111 -0.2717,2.71703"
-       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path112"
-       inkscape:connector-curvature="0" /><path
-       d="m 221.11869,232.99481 -5.25292,-1.85592 5.52462,-0.86111 -0.2717,2.71703 z"
-       style="fill:none;stroke:#000000;stroke-width:0.67925626;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path114"
-       inkscape:connector-curvature="0" /><path
-       d="m 431.8247,249.43353 5.29748,1.81135 -5.56918,0.90567 0.2717,-2.71702"
-       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path116"
-       inkscape:connector-curvature="0" /><path
-       d="m 431.8247,249.43353 5.29748,1.81135 -5.56918,0.90567 0.2717,-2.71702 z"
-       style="fill:none;stroke:#000000;stroke-width:0.67925626;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path118"
-       inkscape:connector-curvature="0" /><g
-       id="g120"
-       transform="matrix(1.4375794,0,0,1.4375794,-0.12334269,-0.08856738)"><text
-	 transform="matrix(1,0,0,-1,204.52,9.07751)"
-	 style="font-variant:normal;font-weight:normal;font-size:6.61499977px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#d10000;fill-opacity:1;fill-rule:nonzero;stroke:none"
-	 id="text122"><tspan
-	   x="0 3.3074999 6.9854398 8.45397 12.13191 15.80985 19.11735 21.320145 24.998085 28.676025 31.983524 35.661465 39.339405 41.178375 44.856316 48.534256 52.212196 55.890137 59.568073"
-	   y="0"
-	   sodipodi:role="line"
-	   id="tspan124">v4l2_cropcap.bounds</tspan></text>
-</g><g
-       id="g126"
-       transform="matrix(1.4375794,0,0,1.4375794,-0.12334269,-0.08856738)"><text
-	 transform="matrix(1,0,0,-1,58.5175,166.42)"
-	 style="font-variant:normal;font-weight:normal;font-size:6.61499977px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#0000d1;fill-opacity:1;fill-rule:nonzero;stroke:none"
-	 id="text128"><tspan
-	   x="0 3.3074999 6.9854398 8.45397 12.13191 15.80985 19.11735 21.320145 24.998085 28.676025 31.983524 35.661465 39.339405 41.178375 44.856316 48.534256 50.373226 52.576019 56.25396 59.561459"
-	   y="0"
-	   sodipodi:role="line"
-	   id="tspan130">v4l2_cropcap.defrect</tspan></text>
-</g><g
-       id="g132"
-       transform="matrix(1.4375794,0,0,1.4375794,-0.12334269,-0.08856738)"><text
-	 transform="matrix(1,0,0,-1,153.49,152.245)"
-	 style="font-variant:normal;font-weight:normal;font-size:6.61499977px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#008f00;fill-opacity:1;fill-rule:nonzero;stroke:none"
-	 id="text134"><tspan
-	   x="0 3.3074999 6.9854398 8.45397 12.13191 15.80985 19.11735 21.320145 24.998085 28.676025 30.514996"
-	   y="0"
-	   sodipodi:role="line"
-	   id="tspan136">v4l2_crop.c</tspan></text>
-</g><g
-       id="g138"
-       transform="matrix(1.4375794,0,0,1.4375794,-0.12334269,-0.08856738)"><text
-	 transform="matrix(1,0,0,-1,309.415,30.34)"
-	 style="font-variant:normal;font-weight:normal;font-size:6.61499977px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#b000b0;fill-opacity:1;fill-rule:nonzero;stroke:none"
-	 id="text140"><tspan
-	   x="0 3.3074999 6.9854398 8.45397 12.13191 15.80985 17.648821 21.326759 23.529554 29.03985 32.717789"
-	   y="0"
-	   sodipodi:role="line"
-	   id="tspan142">v4l2_format</tspan></text>
-</g><text
-       xml:space="preserve"
-       style="font-style:normal;font-weight:normal;font-size:32px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
-       x="-99.291145"
-       y="-239.49893"
-       id="text3396"
-       sodipodi:linespacing="125%"
-       transform="scale(1,-1)"><tspan
-	 sodipodi:role="line"
-	 id="tspan3398"
-	 x="-99.291145"
-	 y="-239.49893"></tspan><tspan
-	 sodipodi:role="line"
-	 x="-99.291145"
-	 y="-199.49893"
-	 id="tspan3400" /></text>
-</g></svg>
diff --git a/Documentation/media/uapi/v4l/depth-formats.rst b/Documentation/media/uapi/v4l/depth-formats.rst
deleted file mode 100644
index 1bfd0b82cb85..000000000000
--- a/Documentation/media/uapi/v4l/depth-formats.rst
+++ /dev/null
@@ -1,24 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _depth-formats:
-
-*************
-Depth Formats
-*************
-
-Depth data provides distance to points, mapped onto the image plane
-
-
-.. toctree::
-    :maxdepth: 1
-
-    pixfmt-inzi
-    pixfmt-z16
-    pixfmt-cnf4
diff --git a/Documentation/media/uapi/v4l/dev-capture.rst b/Documentation/media/uapi/v4l/dev-capture.rst
deleted file mode 100644
index 134e22b32338..000000000000
--- a/Documentation/media/uapi/v4l/dev-capture.rst
+++ /dev/null
@@ -1,111 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _capture:
-
-***********************
-Video Capture Interface
-***********************
-
-Video capture devices sample an analog video signal and store the
-digitized images in memory. Today nearly all devices can capture at full
-25 or 30 frames/second. With this interface applications can control the
-capture process and move images from the driver into user space.
-
-Conventionally V4L2 video capture devices are accessed through character
-device special files named ``/dev/video`` and ``/dev/video0`` to
-``/dev/video63`` with major number 81 and minor numbers 0 to 63.
-``/dev/video`` is typically a symbolic link to the preferred video
-device.
-
-.. note:: The same device file names are used for video output devices.
-
-
-Querying Capabilities
-=====================
-
-Devices supporting the video capture interface set the
-``V4L2_CAP_VIDEO_CAPTURE`` or ``V4L2_CAP_VIDEO_CAPTURE_MPLANE`` flag in
-the ``capabilities`` field of struct
-:c:type:`v4l2_capability` returned by the
-:ref:`VIDIOC_QUERYCAP` ioctl. As secondary device
-functions they may also support the :ref:`video overlay <overlay>`
-(``V4L2_CAP_VIDEO_OVERLAY``) and the :ref:`raw VBI capture <raw-vbi>`
-(``V4L2_CAP_VBI_CAPTURE``) interface. At least one of the read/write or
-streaming I/O methods must be supported. Tuners and audio inputs are
-optional.
-
-
-Supplemental Functions
-======================
-
-Video capture devices shall support :ref:`audio input <audio>`,
-:ref:`tuner`, :ref:`controls <control>`,
-:ref:`cropping and scaling <crop>` and
-:ref:`streaming parameter <streaming-par>` ioctls as needed. The
-:ref:`video input <video>` ioctls must be supported by all video
-capture devices.
-
-
-Image Format Negotiation
-========================
-
-The result of a capture operation is determined by cropping and image
-format parameters. The former select an area of the video picture to
-capture, the latter how images are stored in memory, i. e. in RGB or YUV
-format, the number of bits per pixel or width and height. Together they
-also define how images are scaled in the process.
-
-As usual these parameters are *not* reset at :ref:`open() <func-open>`
-time to permit Unix tool chains, programming a device and then reading
-from it as if it was a plain file. Well written V4L2 applications ensure
-they really get what they want, including cropping and scaling.
-
-Cropping initialization at minimum requires to reset the parameters to
-defaults. An example is given in :ref:`crop`.
-
-To query the current image format applications set the ``type`` field of
-a struct :c:type:`v4l2_format` to
-``V4L2_BUF_TYPE_VIDEO_CAPTURE`` or
-``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE`` and call the
-:ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` ioctl with a pointer to this
-structure. Drivers fill the struct
-:c:type:`v4l2_pix_format` ``pix`` or the struct
-:c:type:`v4l2_pix_format_mplane` ``pix_mp``
-member of the ``fmt`` union.
-
-To request different parameters applications set the ``type`` field of a
-struct :c:type:`v4l2_format` as above and initialize all
-fields of the struct :c:type:`v4l2_pix_format`
-``vbi`` member of the ``fmt`` union, or better just modify the results
-of :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>`, and call the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`
-ioctl with a pointer to this structure. Drivers may adjust the
-parameters and finally return the actual parameters as :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>`
-does.
-
-Like :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` the :ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` ioctl
-can be used to learn about hardware limitations without disabling I/O or
-possibly time consuming hardware preparations.
-
-The contents of struct :c:type:`v4l2_pix_format` and
-struct :c:type:`v4l2_pix_format_mplane` are
-discussed in :ref:`pixfmt`. See also the specification of the
-:ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>`, :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` and :ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` ioctls for
-details. Video capture devices must implement both the :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>`
-and :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl, even if :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ignores all
-requests and always returns default parameters as :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` does.
-:ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` is optional.
-
-
-Reading Images
-==============
-
-A video capture device may support the :ref:`read() function <func-read>`
-and/or streaming (:ref:`memory mapping <func-mmap>` or
-:ref:`user pointer <userp>`) I/O. See :ref:`io` for details.
diff --git a/Documentation/media/uapi/v4l/dev-decoder.rst b/Documentation/media/uapi/v4l/dev-decoder.rst
deleted file mode 100644
index 606b54947e10..000000000000
--- a/Documentation/media/uapi/v4l/dev-decoder.rst
+++ /dev/null
@@ -1,1101 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-.. _decoder:
-
-*************************************************
-Memory-to-Memory Stateful Video Decoder Interface
-*************************************************
-
-A stateful video decoder takes complete chunks of the bytestream (e.g. Annex-B
-H.264/HEVC stream, raw VP8/9 stream) and decodes them into raw video frames in
-display order. The decoder is expected not to require any additional information
-from the client to process these buffers.
-
-Performing software parsing, processing etc. of the stream in the driver in
-order to support this interface is strongly discouraged. In case such
-operations are needed, use of the Stateless Video Decoder Interface (in
-development) is strongly advised.
-
-Conventions and Notations Used in This Document
-===============================================
-
-1. The general V4L2 API rules apply if not specified in this document
-   otherwise.
-
-2. The meaning of words "must", "may", "should", etc. is as per `RFC
-   2119 <https://tools.ietf.org/html/rfc2119>`_.
-
-3. All steps not marked "optional" are required.
-
-4. :c:func:`VIDIOC_G_EXT_CTRLS` and :c:func:`VIDIOC_S_EXT_CTRLS` may be used
-   interchangeably with :c:func:`VIDIOC_G_CTRL` and :c:func:`VIDIOC_S_CTRL`,
-   unless specified otherwise.
-
-5. Single-planar API (see :ref:`planar-apis`) and applicable structures may be
-   used interchangeably with multi-planar API, unless specified otherwise,
-   depending on decoder capabilities and following the general V4L2 guidelines.
-
-6. i = [a..b]: sequence of integers from a to b, inclusive, i.e. i =
-   [0..2]: i = 0, 1, 2.
-
-7. Given an ``OUTPUT`` buffer A, then A’ represents a buffer on the ``CAPTURE``
-   queue containing data that resulted from processing buffer A.
-
-.. _decoder-glossary:
-
-Glossary
-========
-
-CAPTURE
-   the destination buffer queue; for decoders, the queue of buffers containing
-   decoded frames; for encoders, the queue of buffers containing an encoded
-   bytestream; ``V4L2_BUF_TYPE_VIDEO_CAPTURE`` or
-   ``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE``; data is captured from the hardware
-   into ``CAPTURE`` buffers.
-
-client
-   the application communicating with the decoder or encoder implementing
-   this interface.
-
-coded format
-   encoded/compressed video bytestream format (e.g. H.264, VP8, etc.); see
-   also: raw format.
-
-coded height
-   height for given coded resolution.
-
-coded resolution
-   stream resolution in pixels aligned to codec and hardware requirements;
-   typically visible resolution rounded up to full macroblocks;
-   see also: visible resolution.
-
-coded width
-   width for given coded resolution.
-
-decode order
-   the order in which frames are decoded; may differ from display order if the
-   coded format includes a feature of frame reordering; for decoders,
-   ``OUTPUT`` buffers must be queued by the client in decode order; for
-   encoders ``CAPTURE`` buffers must be returned by the encoder in decode order.
-
-destination
-   data resulting from the decode process; see ``CAPTURE``.
-
-display order
-   the order in which frames must be displayed; for encoders, ``OUTPUT``
-   buffers must be queued by the client in display order; for decoders,
-   ``CAPTURE`` buffers must be returned by the decoder in display order.
-
-DPB
-   Decoded Picture Buffer; an H.264/HEVC term for a buffer that stores a decoded
-   raw frame available for reference in further decoding steps.
-
-EOS
-   end of stream.
-
-IDR
-   Instantaneous Decoder Refresh; a type of a keyframe in an H.264/HEVC-encoded
-   stream, which clears the list of earlier reference frames (DPBs).
-
-keyframe
-   an encoded frame that does not reference frames decoded earlier, i.e.
-   can be decoded fully on its own.
-
-macroblock
-   a processing unit in image and video compression formats based on linear
-   block transforms (e.g. H.264, VP8, VP9); codec-specific, but for most of
-   popular codecs the size is 16x16 samples (pixels).
-
-OUTPUT
-   the source buffer queue; for decoders, the queue of buffers containing
-   an encoded bytestream; for encoders, the queue of buffers containing raw
-   frames; ``V4L2_BUF_TYPE_VIDEO_OUTPUT`` or
-   ``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE``; the hardware is fed with data
-   from ``OUTPUT`` buffers.
-
-PPS
-   Picture Parameter Set; a type of metadata entity in an H.264/HEVC bytestream.
-
-raw format
-   uncompressed format containing raw pixel data (e.g. YUV, RGB formats).
-
-resume point
-   a point in the bytestream from which decoding may start/continue, without
-   any previous state/data present, e.g.: a keyframe (VP8/VP9) or
-   SPS/PPS/IDR sequence (H.264/HEVC); a resume point is required to start decode
-   of a new stream, or to resume decoding after a seek.
-
-source
-   data fed to the decoder or encoder; see ``OUTPUT``.
-
-source height
-   height in pixels for given source resolution; relevant to encoders only.
-
-source resolution
-   resolution in pixels of source frames being source to the encoder and
-   subject to further cropping to the bounds of visible resolution; relevant to
-   encoders only.
-
-source width
-   width in pixels for given source resolution; relevant to encoders only.
-
-SPS
-   Sequence Parameter Set; a type of metadata entity in an H.264/HEVC bytestream.
-
-stream metadata
-   additional (non-visual) information contained inside encoded bytestream;
-   for example: coded resolution, visible resolution, codec profile.
-
-visible height
-   height for given visible resolution; display height.
-
-visible resolution
-   stream resolution of the visible picture, in pixels, to be used for
-   display purposes; must be smaller or equal to coded resolution;
-   display resolution.
-
-visible width
-   width for given visible resolution; display width.
-
-State Machine
-=============
-
-.. kernel-render:: DOT
-   :alt: DOT digraph of decoder state machine
-   :caption: Decoder State Machine
-
-   digraph decoder_state_machine {
-       node [shape = doublecircle, label="Decoding"] Decoding;
-
-       node [shape = circle, label="Initialization"] Initialization;
-       node [shape = circle, label="Capture\nsetup"] CaptureSetup;
-       node [shape = circle, label="Dynamic\nResolution\nChange"] ResChange;
-       node [shape = circle, label="Stopped"] Stopped;
-       node [shape = circle, label="Drain"] Drain;
-       node [shape = circle, label="Seek"] Seek;
-       node [shape = circle, label="End of Stream"] EoS;
-
-       node [shape = point]; qi
-       qi -> Initialization [ label = "open()" ];
-
-       Initialization -> CaptureSetup [ label = "CAPTURE\nformat\nestablished" ];
-
-       CaptureSetup -> Stopped [ label = "CAPTURE\nbuffers\nready" ];
-
-       Decoding -> ResChange [ label = "Stream\nresolution\nchange" ];
-       Decoding -> Drain [ label = "V4L2_DEC_CMD_STOP" ];
-       Decoding -> EoS [ label = "EoS mark\nin the stream" ];
-       Decoding -> Seek [ label = "VIDIOC_STREAMOFF(OUTPUT)" ];
-       Decoding -> Stopped [ label = "VIDIOC_STREAMOFF(CAPTURE)" ];
-       Decoding -> Decoding;
-
-       ResChange -> CaptureSetup [ label = "CAPTURE\nformat\nestablished" ];
-       ResChange -> Seek [ label = "VIDIOC_STREAMOFF(OUTPUT)" ];
-
-       EoS -> Drain [ label = "Implicit\ndrain" ];
-
-       Drain -> Stopped [ label = "All CAPTURE\nbuffers dequeued\nor\nVIDIOC_STREAMOFF(CAPTURE)" ];
-       Drain -> Seek [ label = "VIDIOC_STREAMOFF(OUTPUT)" ];
-
-       Seek -> Decoding [ label = "VIDIOC_STREAMON(OUTPUT)" ];
-       Seek -> Initialization [ label = "VIDIOC_REQBUFS(OUTPUT, 0)" ];
-
-       Stopped -> Decoding [ label = "V4L2_DEC_CMD_START\nor\nVIDIOC_STREAMON(CAPTURE)" ];
-       Stopped -> Seek [ label = "VIDIOC_STREAMOFF(OUTPUT)" ];
-   }
-
-Querying Capabilities
-=====================
-
-1. To enumerate the set of coded formats supported by the decoder, the
-   client may call :c:func:`VIDIOC_ENUM_FMT` on ``OUTPUT``.
-
-   * The full set of supported formats will be returned, regardless of the
-     format set on ``CAPTURE``.
-   * Check the flags field of :c:type:`v4l2_fmtdesc` for more information
-     about the decoder's capabilities with respect to each coded format.
-     In particular whether or not the decoder has a full-fledged bytestream
-     parser and if the decoder supports dynamic resolution changes.
-
-2. To enumerate the set of supported raw formats, the client may call
-   :c:func:`VIDIOC_ENUM_FMT` on ``CAPTURE``.
-
-   * Only the formats supported for the format currently active on ``OUTPUT``
-     will be returned.
-
-   * In order to enumerate raw formats supported by a given coded format,
-     the client must first set that coded format on ``OUTPUT`` and then
-     enumerate formats on ``CAPTURE``.
-
-3. The client may use :c:func:`VIDIOC_ENUM_FRAMESIZES` to detect supported
-   resolutions for a given format, passing desired pixel format in
-   :c:type:`v4l2_frmsizeenum` ``pixel_format``.
-
-   * Values returned by :c:func:`VIDIOC_ENUM_FRAMESIZES` for a coded pixel
-     format will include all possible coded resolutions supported by the
-     decoder for given coded pixel format.
-
-   * Values returned by :c:func:`VIDIOC_ENUM_FRAMESIZES` for a raw pixel format
-     will include all possible frame buffer resolutions supported by the
-     decoder for given raw pixel format and the coded format currently set on
-     ``OUTPUT``.
-
-4. Supported profiles and levels for the coded format currently set on
-   ``OUTPUT``, if applicable, may be queried using their respective controls
-   via :c:func:`VIDIOC_QUERYCTRL`.
-
-Initialization
-==============
-
-1. Set the coded format on ``OUTPUT`` via :c:func:`VIDIOC_S_FMT`
-
-   * **Required fields:**
-
-     ``type``
-         a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.
-
-     ``pixelformat``
-         a coded pixel format.
-
-     ``width``, ``height``
-         coded resolution of the stream; required only if it cannot be parsed
-         from the stream for the given coded format; otherwise the decoder will
-         use this resolution as a placeholder resolution that will likely change
-         as soon as it can parse the actual coded resolution from the stream.
-
-     ``sizeimage``
-         desired size of ``OUTPUT`` buffers; the decoder may adjust it to
-         match hardware requirements.
-
-     other fields
-         follow standard semantics.
-
-   * **Return fields:**
-
-     ``sizeimage``
-         adjusted size of ``OUTPUT`` buffers.
-
-   * The ``CAPTURE`` format will be updated with an appropriate frame buffer
-     resolution instantly based on the width and height returned by
-     :c:func:`VIDIOC_S_FMT`.
-     However, for coded formats that include stream resolution information,
-     after the decoder is done parsing the information from the stream, it will
-     update the ``CAPTURE`` format with new values and signal a source change
-     event, regardless of whether they match the values set by the client or
-     not.
-
-   .. important::
-
-      Changing the ``OUTPUT`` format may change the currently set ``CAPTURE``
-      format. How the new ``CAPTURE`` format is determined is up to the decoder
-      and the client must ensure it matches its needs afterwards.
-
-2.  Allocate source (bytestream) buffers via :c:func:`VIDIOC_REQBUFS` on
-    ``OUTPUT``.
-
-    * **Required fields:**
-
-      ``count``
-          requested number of buffers to allocate; greater than zero.
-
-      ``type``
-          a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.
-
-      ``memory``
-          follows standard semantics.
-
-    * **Return fields:**
-
-      ``count``
-          the actual number of buffers allocated.
-
-    .. warning::
-
-       The actual number of allocated buffers may differ from the ``count``
-       given. The client must check the updated value of ``count`` after the
-       call returns.
-
-    Alternatively, :c:func:`VIDIOC_CREATE_BUFS` on the ``OUTPUT`` queue can be
-    used to have more control over buffer allocation.
-
-    * **Required fields:**
-
-      ``count``
-          requested number of buffers to allocate; greater than zero.
-
-      ``type``
-          a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.
-
-      ``memory``
-          follows standard semantics.
-
-      ``format``
-          follows standard semantics.
-
-    * **Return fields:**
-
-      ``count``
-          adjusted to the number of allocated buffers.
-
-    .. warning::
-
-       The actual number of allocated buffers may differ from the ``count``
-       given. The client must check the updated value of ``count`` after the
-       call returns.
-
-3.  Start streaming on the ``OUTPUT`` queue via :c:func:`VIDIOC_STREAMON`.
-
-4.  **This step only applies to coded formats that contain resolution information
-    in the stream.** Continue queuing/dequeuing bytestream buffers to/from the
-    ``OUTPUT`` queue via :c:func:`VIDIOC_QBUF` and :c:func:`VIDIOC_DQBUF`. The
-    buffers will be processed and returned to the client in order, until
-    required metadata to configure the ``CAPTURE`` queue are found. This is
-    indicated by the decoder sending a ``V4L2_EVENT_SOURCE_CHANGE`` event with
-    ``changes`` set to ``V4L2_EVENT_SRC_CH_RESOLUTION``.
-
-    * It is not an error if the first buffer does not contain enough data for
-      this to occur. Processing of the buffers will continue as long as more
-      data is needed.
-
-    * If data in a buffer that triggers the event is required to decode the
-      first frame, it will not be returned to the client, until the
-      initialization sequence completes and the frame is decoded.
-
-    * If the client has not set the coded resolution of the stream on its own,
-      calling :c:func:`VIDIOC_G_FMT`, :c:func:`VIDIOC_S_FMT`,
-      :c:func:`VIDIOC_TRY_FMT` or :c:func:`VIDIOC_REQBUFS` on the ``CAPTURE``
-      queue will not return the real values for the stream until a
-      ``V4L2_EVENT_SOURCE_CHANGE`` event with ``changes`` set to
-      ``V4L2_EVENT_SRC_CH_RESOLUTION`` is signaled.
-
-    .. important::
-
-       Any client query issued after the decoder queues the event will return
-       values applying to the just parsed stream, including queue formats,
-       selection rectangles and controls.
-
-    .. note::
-
-       A client capable of acquiring stream parameters from the bytestream on
-       its own may attempt to set the width and height of the ``OUTPUT`` format
-       to non-zero values matching the coded size of the stream, skip this step
-       and continue with the `Capture Setup` sequence. However, it must not
-       rely on any driver queries regarding stream parameters, such as
-       selection rectangles and controls, since the decoder has not parsed them
-       from the stream yet. If the values configured by the client do not match
-       those parsed by the decoder, a `Dynamic Resolution Change` will be
-       triggered to reconfigure them.
-
-    .. note::
-
-       No decoded frames are produced during this phase.
-
-5.  Continue with the `Capture Setup` sequence.
-
-Capture Setup
-=============
-
-1.  Call :c:func:`VIDIOC_G_FMT` on the ``CAPTURE`` queue to get format for the
-    destination buffers parsed/decoded from the bytestream.
-
-    * **Required fields:**
-
-      ``type``
-          a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
-
-    * **Return fields:**
-
-      ``width``, ``height``
-          frame buffer resolution for the decoded frames.
-
-      ``pixelformat``
-          pixel format for decoded frames.
-
-      ``num_planes`` (for _MPLANE ``type`` only)
-          number of planes for pixelformat.
-
-      ``sizeimage``, ``bytesperline``
-          as per standard semantics; matching frame buffer format.
-
-    .. note::
-
-       The value of ``pixelformat`` may be any pixel format supported by the
-       decoder for the current stream. The decoder should choose a
-       preferred/optimal format for the default configuration. For example, a
-       YUV format may be preferred over an RGB format if an additional
-       conversion step would be required for the latter.
-
-2.  **Optional.** Acquire the visible resolution via
-    :c:func:`VIDIOC_G_SELECTION`.
-
-    * **Required fields:**
-
-      ``type``
-          a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
-
-      ``target``
-          set to ``V4L2_SEL_TGT_COMPOSE``.
-
-    * **Return fields:**
-
-      ``r.left``, ``r.top``, ``r.width``, ``r.height``
-          the visible rectangle; it must fit within the frame buffer resolution
-          returned by :c:func:`VIDIOC_G_FMT` on ``CAPTURE``.
-
-    * The following selection targets are supported on ``CAPTURE``:
-
-      ``V4L2_SEL_TGT_CROP_BOUNDS``
-          corresponds to the coded resolution of the stream.
-
-      ``V4L2_SEL_TGT_CROP_DEFAULT``
-          the rectangle covering the part of the ``CAPTURE`` buffer that
-          contains meaningful picture data (visible area); width and height
-          will be equal to the visible resolution of the stream.
-
-      ``V4L2_SEL_TGT_CROP``
-          the rectangle within the coded resolution to be output to
-          ``CAPTURE``; defaults to ``V4L2_SEL_TGT_CROP_DEFAULT``; read-only on
-          hardware without additional compose/scaling capabilities.
-
-      ``V4L2_SEL_TGT_COMPOSE_BOUNDS``
-          the maximum rectangle within a ``CAPTURE`` buffer, which the cropped
-          frame can be composed into; equal to ``V4L2_SEL_TGT_CROP`` if the
-          hardware does not support compose/scaling.
-
-      ``V4L2_SEL_TGT_COMPOSE_DEFAULT``
-          equal to ``V4L2_SEL_TGT_CROP``.
-
-      ``V4L2_SEL_TGT_COMPOSE``
-          the rectangle inside a ``CAPTURE`` buffer into which the cropped
-          frame is written; defaults to ``V4L2_SEL_TGT_COMPOSE_DEFAULT``;
-          read-only on hardware without additional compose/scaling capabilities.
-
-      ``V4L2_SEL_TGT_COMPOSE_PADDED``
-          the rectangle inside a ``CAPTURE`` buffer which is overwritten by the
-          hardware; equal to ``V4L2_SEL_TGT_COMPOSE`` if the hardware does not
-          write padding pixels.
-
-    .. warning::
-
-       The values are guaranteed to be meaningful only after the decoder
-       successfully parses the stream metadata. The client must not rely on the
-       query before that happens.
-
-3.  **Optional.** Enumerate ``CAPTURE`` formats via :c:func:`VIDIOC_ENUM_FMT` on
-    the ``CAPTURE`` queue. Once the stream information is parsed and known, the
-    client may use this ioctl to discover which raw formats are supported for
-    given stream and select one of them via :c:func:`VIDIOC_S_FMT`.
-
-    .. important::
-
-       The decoder will return only formats supported for the currently
-       established coded format, as per the ``OUTPUT`` format and/or stream
-       metadata parsed in this initialization sequence, even if more formats
-       may be supported by the decoder in general. In other words, the set
-       returned will be a subset of the initial query mentioned in the
-       `Querying Capabilities` section.
-
-       For example, a decoder may support YUV and RGB formats for resolutions
-       1920x1088 and lower, but only YUV for higher resolutions (due to
-       hardware limitations). After parsing a resolution of 1920x1088 or lower,
-       :c:func:`VIDIOC_ENUM_FMT` may return a set of YUV and RGB pixel formats,
-       but after parsing resolution higher than 1920x1088, the decoder will not
-       return RGB, unsupported for this resolution.
-
-       However, subsequent resolution change event triggered after
-       discovering a resolution change within the same stream may switch
-       the stream into a lower resolution and :c:func:`VIDIOC_ENUM_FMT`
-       would return RGB formats again in that case.
-
-4.  **Optional.** Set the ``CAPTURE`` format via :c:func:`VIDIOC_S_FMT` on the
-    ``CAPTURE`` queue. The client may choose a different format than
-    selected/suggested by the decoder in :c:func:`VIDIOC_G_FMT`.
-
-    * **Required fields:**
-
-      ``type``
-          a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
-
-      ``pixelformat``
-          a raw pixel format.
-
-      ``width``, ``height``
-         frame buffer resolution of the decoded stream; typically unchanged from
-	 what was returned with :c:func:`VIDIOC_G_FMT`, but it may be different
-	 if the hardware supports composition and/or scaling.
-
-   * Setting the ``CAPTURE`` format will reset the compose selection rectangles
-     to their default values, based on the new resolution, as described in the
-     previous step.
-
-5. **Optional.** Set the compose rectangle via :c:func:`VIDIOC_S_SELECTION` on
-   the ``CAPTURE`` queue if it is desired and if the decoder has compose and/or
-   scaling capabilities.
-
-   * **Required fields:**
-
-     ``type``
-         a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
-
-     ``target``
-         set to ``V4L2_SEL_TGT_COMPOSE``.
-
-     ``r.left``, ``r.top``, ``r.width``, ``r.height``
-         the rectangle inside a ``CAPTURE`` buffer into which the cropped
-         frame is written; defaults to ``V4L2_SEL_TGT_COMPOSE_DEFAULT``;
-         read-only on hardware without additional compose/scaling capabilities.
-
-   * **Return fields:**
-
-     ``r.left``, ``r.top``, ``r.width``, ``r.height``
-         the visible rectangle; it must fit within the frame buffer resolution
-         returned by :c:func:`VIDIOC_G_FMT` on ``CAPTURE``.
-
-   .. warning::
-
-      The decoder may adjust the compose rectangle to the nearest
-      supported one to meet codec and hardware requirements. The client needs
-      to check the adjusted rectangle returned by :c:func:`VIDIOC_S_SELECTION`.
-
-6.  If all the following conditions are met, the client may resume the decoding
-    instantly:
-
-    * ``sizeimage`` of the new format (determined in previous steps) is less
-      than or equal to the size of currently allocated buffers,
-
-    * the number of buffers currently allocated is greater than or equal to the
-      minimum number of buffers acquired in previous steps. To fulfill this
-      requirement, the client may use :c:func:`VIDIOC_CREATE_BUFS` to add new
-      buffers.
-
-    In that case, the remaining steps do not apply and the client may resume
-    the decoding by one of the following actions:
-
-    * if the ``CAPTURE`` queue is streaming, call :c:func:`VIDIOC_DECODER_CMD`
-      with the ``V4L2_DEC_CMD_START`` command,
-
-    * if the ``CAPTURE`` queue is not streaming, call :c:func:`VIDIOC_STREAMON`
-      on the ``CAPTURE`` queue.
-
-    However, if the client intends to change the buffer set, to lower
-    memory usage or for any other reasons, it may be achieved by following
-    the steps below.
-
-7.  **If the** ``CAPTURE`` **queue is streaming,** keep queuing and dequeuing
-    buffers on the ``CAPTURE`` queue until a buffer marked with the
-    ``V4L2_BUF_FLAG_LAST`` flag is dequeued.
-
-8.  **If the** ``CAPTURE`` **queue is streaming,** call :c:func:`VIDIOC_STREAMOFF`
-    on the ``CAPTURE`` queue to stop streaming.
-
-    .. warning::
-
-       The ``OUTPUT`` queue must remain streaming. Calling
-       :c:func:`VIDIOC_STREAMOFF` on it would abort the sequence and trigger a
-       seek.
-
-9.  **If the** ``CAPTURE`` **queue has buffers allocated,** free the ``CAPTURE``
-    buffers using :c:func:`VIDIOC_REQBUFS`.
-
-    * **Required fields:**
-
-      ``count``
-          set to 0.
-
-      ``type``
-          a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
-
-      ``memory``
-          follows standard semantics.
-
-10. Allocate ``CAPTURE`` buffers via :c:func:`VIDIOC_REQBUFS` on the
-    ``CAPTURE`` queue.
-
-    * **Required fields:**
-
-      ``count``
-          requested number of buffers to allocate; greater than zero.
-
-      ``type``
-          a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
-
-      ``memory``
-          follows standard semantics.
-
-    * **Return fields:**
-
-      ``count``
-          actual number of buffers allocated.
-
-    .. warning::
-
-       The actual number of allocated buffers may differ from the ``count``
-       given. The client must check the updated value of ``count`` after the
-       call returns.
-
-    .. note::
-
-       To allocate more than the minimum number of buffers (for pipeline
-       depth), the client may query the ``V4L2_CID_MIN_BUFFERS_FOR_CAPTURE``
-       control to get the minimum number of buffers required, and pass the
-       obtained value plus the number of additional buffers needed in the
-       ``count`` field to :c:func:`VIDIOC_REQBUFS`.
-
-    Alternatively, :c:func:`VIDIOC_CREATE_BUFS` on the ``CAPTURE`` queue can be
-    used to have more control over buffer allocation. For example, by
-    allocating buffers larger than the current ``CAPTURE`` format, future
-    resolution changes can be accommodated.
-
-    * **Required fields:**
-
-      ``count``
-          requested number of buffers to allocate; greater than zero.
-
-      ``type``
-          a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
-
-      ``memory``
-          follows standard semantics.
-
-      ``format``
-          a format representing the maximum framebuffer resolution to be
-          accommodated by newly allocated buffers.
-
-    * **Return fields:**
-
-      ``count``
-          adjusted to the number of allocated buffers.
-
-    .. warning::
-
-        The actual number of allocated buffers may differ from the ``count``
-        given. The client must check the updated value of ``count`` after the
-        call returns.
-
-    .. note::
-
-       To allocate buffers for a format different than parsed from the stream
-       metadata, the client must proceed as follows, before the metadata
-       parsing is initiated:
-
-       * set width and height of the ``OUTPUT`` format to desired coded resolution to
-         let the decoder configure the ``CAPTURE`` format appropriately,
-
-       * query the ``CAPTURE`` format using :c:func:`VIDIOC_G_FMT` and save it
-         until this step.
-
-       The format obtained in the query may be then used with
-       :c:func:`VIDIOC_CREATE_BUFS` in this step to allocate the buffers.
-
-11. Call :c:func:`VIDIOC_STREAMON` on the ``CAPTURE`` queue to start decoding
-    frames.
-
-Decoding
-========
-
-This state is reached after the `Capture Setup` sequence finishes successfully.
-In this state, the client queues and dequeues buffers to both queues via
-:c:func:`VIDIOC_QBUF` and :c:func:`VIDIOC_DQBUF`, following the standard
-semantics.
-
-The content of the source ``OUTPUT`` buffers depends on the active coded pixel
-format and may be affected by codec-specific extended controls, as stated in
-the documentation of each format.
-
-Both queues operate independently, following the standard behavior of V4L2
-buffer queues and memory-to-memory devices. In addition, the order of decoded
-frames dequeued from the ``CAPTURE`` queue may differ from the order of queuing
-coded frames to the ``OUTPUT`` queue, due to properties of the selected coded
-format, e.g. frame reordering.
-
-The client must not assume any direct relationship between ``CAPTURE``
-and ``OUTPUT`` buffers and any specific timing of buffers becoming
-available to dequeue. Specifically:
-
-* a buffer queued to ``OUTPUT`` may result in no buffers being produced
-  on ``CAPTURE`` (e.g. if it does not contain encoded data, or if only
-  metadata syntax structures are present in it),
-
-* a buffer queued to ``OUTPUT`` may result in more than one buffer produced
-  on ``CAPTURE`` (if the encoded data contained more than one frame, or if
-  returning a decoded frame allowed the decoder to return a frame that
-  preceded it in decode, but succeeded it in the display order),
-
-* a buffer queued to ``OUTPUT`` may result in a buffer being produced on
-  ``CAPTURE`` later into decode process, and/or after processing further
-  ``OUTPUT`` buffers, or be returned out of order, e.g. if display
-  reordering is used,
-
-* buffers may become available on the ``CAPTURE`` queue without additional
-  buffers queued to ``OUTPUT`` (e.g. during drain or ``EOS``), because of the
-  ``OUTPUT`` buffers queued in the past whose decoding results are only
-  available at later time, due to specifics of the decoding process.
-
-.. note::
-
-   To allow matching decoded ``CAPTURE`` buffers with ``OUTPUT`` buffers they
-   originated from, the client can set the ``timestamp`` field of the
-   :c:type:`v4l2_buffer` struct when queuing an ``OUTPUT`` buffer. The
-   ``CAPTURE`` buffer(s), which resulted from decoding that ``OUTPUT`` buffer
-   will have their ``timestamp`` field set to the same value when dequeued.
-
-   In addition to the straightforward case of one ``OUTPUT`` buffer producing
-   one ``CAPTURE`` buffer, the following cases are defined:
-
-   * one ``OUTPUT`` buffer generates multiple ``CAPTURE`` buffers: the same
-     ``OUTPUT`` timestamp will be copied to multiple ``CAPTURE`` buffers.
-
-   * multiple ``OUTPUT`` buffers generate one ``CAPTURE`` buffer: timestamp of
-     the ``OUTPUT`` buffer queued first will be copied.
-
-   * the decoding order differs from the display order (i.e. the ``CAPTURE``
-     buffers are out-of-order compared to the ``OUTPUT`` buffers): ``CAPTURE``
-     timestamps will not retain the order of ``OUTPUT`` timestamps.
-
-During the decoding, the decoder may initiate one of the special sequences, as
-listed below. The sequences will result in the decoder returning all the
-``CAPTURE`` buffers that originated from all the ``OUTPUT`` buffers processed
-before the sequence started. Last of the buffers will have the
-``V4L2_BUF_FLAG_LAST`` flag set. To determine the sequence to follow, the client
-must check if there is any pending event and:
-
-* if a ``V4L2_EVENT_SOURCE_CHANGE`` event with ``changes`` set to
-  ``V4L2_EVENT_SRC_CH_RESOLUTION`` is pending, the `Dynamic Resolution
-  Change` sequence needs to be followed,
-
-* if a ``V4L2_EVENT_EOS`` event is pending, the `End of Stream` sequence needs
-  to be followed.
-
-Some of the sequences can be intermixed with each other and need to be handled
-as they happen. The exact operation is documented for each sequence.
-
-Should a decoding error occur, it will be reported to the client with the level
-of details depending on the decoder capabilities. Specifically:
-
-* the CAPTURE buffer that contains the results of the failed decode operation
-  will be returned with the V4L2_BUF_FLAG_ERROR flag set,
-
-* if the decoder is able to precisely report the OUTPUT buffer that triggered
-  the error, such buffer will be returned with the V4L2_BUF_FLAG_ERROR flag
-  set.
-
-In case of a fatal failure that does not allow the decoding to continue, any
-further operations on corresponding decoder file handle will return the -EIO
-error code. The client may close the file handle and open a new one, or
-alternatively reinitialize the instance by stopping streaming on both queues,
-releasing all buffers and performing the Initialization sequence again.
-
-Seek
-====
-
-Seek is controlled by the ``OUTPUT`` queue, as it is the source of coded data.
-The seek does not require any specific operation on the ``CAPTURE`` queue, but
-it may be affected as per normal decoder operation.
-
-1. Stop the ``OUTPUT`` queue to begin the seek sequence via
-   :c:func:`VIDIOC_STREAMOFF`.
-
-   * **Required fields:**
-
-     ``type``
-         a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.
-
-   * The decoder will drop all the pending ``OUTPUT`` buffers and they must be
-     treated as returned to the client (following standard semantics).
-
-2. Restart the ``OUTPUT`` queue via :c:func:`VIDIOC_STREAMON`
-
-   * **Required fields:**
-
-     ``type``
-         a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.
-
-   * The decoder will start accepting new source bytestream buffers after the
-     call returns.
-
-3. Start queuing buffers containing coded data after the seek to the ``OUTPUT``
-   queue until a suitable resume point is found.
-
-   .. note::
-
-      There is no requirement to begin queuing coded data starting exactly
-      from a resume point (e.g. SPS or a keyframe). Any queued ``OUTPUT``
-      buffers will be processed and returned to the client until a suitable
-      resume point is found.  While looking for a resume point, the decoder
-      should not produce any decoded frames into ``CAPTURE`` buffers.
-
-      Some hardware is known to mishandle seeks to a non-resume point. Such an
-      operation may result in an unspecified number of corrupted decoded frames
-      being made available on the ``CAPTURE`` queue. Drivers must ensure that
-      no fatal decoding errors or crashes occur, and implement any necessary
-      handling and workarounds for hardware issues related to seek operations.
-
-   .. warning::
-
-      In case of the H.264/HEVC codec, the client must take care not to seek
-      over a change of SPS/PPS. Even though the target frame could be a
-      keyframe, the stale SPS/PPS inside decoder state would lead to undefined
-      results when decoding. Although the decoder must handle that case without
-      a crash or a fatal decode error, the client must not expect a sensible
-      decode output.
-
-      If the hardware can detect such corrupted decoded frames, then
-      corresponding buffers will be returned to the client with the
-      V4L2_BUF_FLAG_ERROR set. See the `Decoding` section for further
-      description of decode error reporting.
-
-4. After a resume point is found, the decoder will start returning ``CAPTURE``
-   buffers containing decoded frames.
-
-.. important::
-
-   A seek may result in the `Dynamic Resolution Change` sequence being
-   initiated, due to the seek target having decoding parameters different from
-   the part of the stream decoded before the seek. The sequence must be handled
-   as per normal decoder operation.
-
-.. warning::
-
-   It is not specified when the ``CAPTURE`` queue starts producing buffers
-   containing decoded data from the ``OUTPUT`` buffers queued after the seek,
-   as it operates independently from the ``OUTPUT`` queue.
-
-   The decoder may return a number of remaining ``CAPTURE`` buffers containing
-   decoded frames originating from the ``OUTPUT`` buffers queued before the
-   seek sequence is performed.
-
-   The ``VIDIOC_STREAMOFF`` operation discards any remaining queued
-   ``OUTPUT`` buffers, which means that not all of the ``OUTPUT`` buffers
-   queued before the seek sequence may have matching ``CAPTURE`` buffers
-   produced.  For example, given the sequence of operations on the
-   ``OUTPUT`` queue:
-
-     QBUF(A), QBUF(B), STREAMOFF(), STREAMON(), QBUF(G), QBUF(H),
-
-   any of the following results on the ``CAPTURE`` queue is allowed:
-
-     {A’, B’, G’, H’}, {A’, G’, H’}, {G’, H’}.
-
-   To determine the CAPTURE buffer containing the first decoded frame after the
-   seek, the client may observe the timestamps to match the CAPTURE and OUTPUT
-   buffers or use V4L2_DEC_CMD_STOP and V4L2_DEC_CMD_START to drain the
-   decoder.
-
-.. note::
-
-   To achieve instantaneous seek, the client may restart streaming on the
-   ``CAPTURE`` queue too to discard decoded, but not yet dequeued buffers.
-
-Dynamic Resolution Change
-=========================
-
-Streams that include resolution metadata in the bytestream may require switching
-to a different resolution during the decoding.
-
-.. note::
-
-   Not all decoders can detect resolution changes. Those that do set the
-   ``V4L2_FMT_FLAG_DYN_RESOLUTION`` flag for the coded format when
-   :c:func:`VIDIOC_ENUM_FMT` is called.
-
-The sequence starts when the decoder detects a coded frame with one or more of
-the following parameters different from those previously established (and
-reflected by corresponding queries):
-
-* coded resolution (``OUTPUT`` width and height),
-
-* visible resolution (selection rectangles),
-
-* the minimum number of buffers needed for decoding.
-
-Whenever that happens, the decoder must proceed as follows:
-
-1.  After encountering a resolution change in the stream, the decoder sends a
-    ``V4L2_EVENT_SOURCE_CHANGE`` event with ``changes`` set to
-    ``V4L2_EVENT_SRC_CH_RESOLUTION``.
-
-    .. important::
-
-       Any client query issued after the decoder queues the event will return
-       values applying to the stream after the resolution change, including
-       queue formats, selection rectangles and controls.
-
-2.  The decoder will then process and decode all remaining buffers from before
-    the resolution change point.
-
-    * The last buffer from before the change must be marked with the
-      ``V4L2_BUF_FLAG_LAST`` flag, similarly to the `Drain` sequence above.
-
-    .. warning::
-
-       The last buffer may be empty (with :c:type:`v4l2_buffer` ``bytesused``
-       = 0) and in that case it must be ignored by the client, as it does not
-       contain a decoded frame.
-
-    .. note::
-
-       Any attempt to dequeue more ``CAPTURE`` buffers beyond the buffer marked
-       with ``V4L2_BUF_FLAG_LAST`` will result in a -EPIPE error from
-       :c:func:`VIDIOC_DQBUF`.
-
-The client must continue the sequence as described below to continue the
-decoding process.
-
-1.  Dequeue the source change event.
-
-    .. important::
-
-       A source change triggers an implicit decoder drain, similar to the
-       explicit `Drain` sequence. The decoder is stopped after it completes.
-       The decoding process must be resumed with either a pair of calls to
-       :c:func:`VIDIOC_STREAMOFF` and :c:func:`VIDIOC_STREAMON` on the
-       ``CAPTURE`` queue, or a call to :c:func:`VIDIOC_DECODER_CMD` with the
-       ``V4L2_DEC_CMD_START`` command.
-
-2.  Continue with the `Capture Setup` sequence.
-
-.. note::
-
-   During the resolution change sequence, the ``OUTPUT`` queue must remain
-   streaming. Calling :c:func:`VIDIOC_STREAMOFF` on the ``OUTPUT`` queue would
-   abort the sequence and initiate a seek.
-
-   In principle, the ``OUTPUT`` queue operates separately from the ``CAPTURE``
-   queue and this remains true for the duration of the entire resolution change
-   sequence as well.
-
-   The client should, for best performance and simplicity, keep queuing/dequeuing
-   buffers to/from the ``OUTPUT`` queue even while processing this sequence.
-
-Drain
-=====
-
-To ensure that all queued ``OUTPUT`` buffers have been processed and related
-``CAPTURE`` buffers are given to the client, the client must follow the drain
-sequence described below. After the drain sequence ends, the client has
-received all decoded frames for all ``OUTPUT`` buffers queued before the
-sequence was started.
-
-1. Begin drain by issuing :c:func:`VIDIOC_DECODER_CMD`.
-
-   * **Required fields:**
-
-     ``cmd``
-         set to ``V4L2_DEC_CMD_STOP``.
-
-     ``flags``
-         set to 0.
-
-     ``pts``
-         set to 0.
-
-   .. warning::
-
-      The sequence can be only initiated if both ``OUTPUT`` and ``CAPTURE``
-      queues are streaming. For compatibility reasons, the call to
-      :c:func:`VIDIOC_DECODER_CMD` will not fail even if any of the queues is
-      not streaming, but at the same time it will not initiate the `Drain`
-      sequence and so the steps described below would not be applicable.
-
-2. Any ``OUTPUT`` buffers queued by the client before the
-   :c:func:`VIDIOC_DECODER_CMD` was issued will be processed and decoded as
-   normal. The client must continue to handle both queues independently,
-   similarly to normal decode operation. This includes:
-
-   * handling any operations triggered as a result of processing those buffers,
-     such as the `Dynamic Resolution Change` sequence, before continuing with
-     the drain sequence,
-
-   * queuing and dequeuing ``CAPTURE`` buffers, until a buffer marked with the
-     ``V4L2_BUF_FLAG_LAST`` flag is dequeued,
-
-     .. warning::
-
-        The last buffer may be empty (with :c:type:`v4l2_buffer`
-        ``bytesused`` = 0) and in that case it must be ignored by the client,
-        as it does not contain a decoded frame.
-
-     .. note::
-
-        Any attempt to dequeue more ``CAPTURE`` buffers beyond the buffer
-        marked with ``V4L2_BUF_FLAG_LAST`` will result in a -EPIPE error from
-        :c:func:`VIDIOC_DQBUF`.
-
-   * dequeuing processed ``OUTPUT`` buffers, until all the buffers queued
-     before the ``V4L2_DEC_CMD_STOP`` command are dequeued,
-
-   * dequeuing the ``V4L2_EVENT_EOS`` event, if the client subscribed to it.
-
-   .. note::
-
-      For backwards compatibility, the decoder will signal a ``V4L2_EVENT_EOS``
-      event when the last frame has been decoded and all frames are ready to be
-      dequeued. It is a deprecated behavior and the client must not rely on it.
-      The ``V4L2_BUF_FLAG_LAST`` buffer flag should be used instead.
-
-3. Once all the ``OUTPUT`` buffers queued before the ``V4L2_DEC_CMD_STOP`` call
-   are dequeued and the last ``CAPTURE`` buffer is dequeued, the decoder is
-   stopped and it will accept, but not process, any newly queued ``OUTPUT``
-   buffers until the client issues any of the following operations:
-
-   * ``V4L2_DEC_CMD_START`` - the decoder will not be reset and will resume
-     operation normally, with all the state from before the drain,
-
-   * a pair of :c:func:`VIDIOC_STREAMOFF` and :c:func:`VIDIOC_STREAMON` on the
-     ``CAPTURE`` queue - the decoder will resume the operation normally,
-     however any ``CAPTURE`` buffers still in the queue will be returned to the
-     client,
-
-   * a pair of :c:func:`VIDIOC_STREAMOFF` and :c:func:`VIDIOC_STREAMON` on the
-     ``OUTPUT`` queue - any pending source buffers will be returned to the
-     client and the `Seek` sequence will be triggered.
-
-.. note::
-
-   Once the drain sequence is initiated, the client needs to drive it to
-   completion, as described by the steps above, unless it aborts the process by
-   issuing :c:func:`VIDIOC_STREAMOFF` on any of the ``OUTPUT`` or ``CAPTURE``
-   queues.  The client is not allowed to issue ``V4L2_DEC_CMD_START`` or
-   ``V4L2_DEC_CMD_STOP`` again while the drain sequence is in progress and they
-   will fail with -EBUSY error code if attempted.
-
-   Although mandatory, the availability of decoder commands may be queried
-   using :c:func:`VIDIOC_TRY_DECODER_CMD`.
-
-End of Stream
-=============
-
-If the decoder encounters an end of stream marking in the stream, the decoder
-will initiate the `Drain` sequence, which the client must handle as described
-above, skipping the initial :c:func:`VIDIOC_DECODER_CMD`.
-
-Commit Points
-=============
-
-Setting formats and allocating buffers trigger changes in the behavior of the
-decoder.
-
-1. Setting the format on the ``OUTPUT`` queue may change the set of formats
-   supported/advertised on the ``CAPTURE`` queue. In particular, it also means
-   that the ``CAPTURE`` format may be reset and the client must not rely on the
-   previously set format being preserved.
-
-2. Enumerating formats on the ``CAPTURE`` queue always returns only formats
-   supported for the current ``OUTPUT`` format.
-
-3. Setting the format on the ``CAPTURE`` queue does not change the list of
-   formats available on the ``OUTPUT`` queue. An attempt to set a ``CAPTURE``
-   format that is not supported for the currently selected ``OUTPUT`` format
-   will result in the decoder adjusting the requested ``CAPTURE`` format to a
-   supported one.
-
-4. Enumerating formats on the ``OUTPUT`` queue always returns the full set of
-   supported coded formats, irrespectively of the current ``CAPTURE`` format.
-
-5. While buffers are allocated on any of the ``OUTPUT`` or ``CAPTURE`` queues,
-   the client must not change the format on the ``OUTPUT`` queue. Drivers will
-   return the -EBUSY error code for any such format change attempt.
-
-To summarize, setting formats and allocation must always start with the
-``OUTPUT`` queue and the ``OUTPUT`` queue is the master that governs the
-set of supported formats for the ``CAPTURE`` queue.
diff --git a/Documentation/media/uapi/v4l/dev-event.rst b/Documentation/media/uapi/v4l/dev-event.rst
deleted file mode 100644
index 6029101fe1d7..000000000000
--- a/Documentation/media/uapi/v4l/dev-event.rst
+++ /dev/null
@@ -1,54 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _event:
-
-***************
-Event Interface
-***************
-
-The V4L2 event interface provides a means for a user to get immediately
-notified on certain conditions taking place on a device. This might
-include start of frame or loss of signal events, for example. Changes in
-the value or state of a V4L2 control can also be reported through
-events.
-
-To receive events, the events the user is interested in first must be
-subscribed using the
-:ref:`VIDIOC_SUBSCRIBE_EVENT` ioctl. Once
-an event is subscribed, the events of subscribed types are dequeueable
-using the :ref:`VIDIOC_DQEVENT` ioctl. Events may be
-unsubscribed using VIDIOC_UNSUBSCRIBE_EVENT ioctl. The special event
-type V4L2_EVENT_ALL may be used to unsubscribe all the events the
-driver supports.
-
-The event subscriptions and event queues are specific to file handles.
-Subscribing an event on one file handle does not affect other file
-handles.
-
-The information on dequeueable events is obtained by using select or
-poll system calls on video devices. The V4L2 events use POLLPRI events
-on poll system call and exceptions on select system call.
-
-Starting with kernel 3.1 certain guarantees can be given with regards to
-events:
-
-1. Each subscribed event has its own internal dedicated event queue.
-   This means that flooding of one event type will not interfere with
-   other event types.
-
-2. If the internal event queue for a particular subscribed event becomes
-   full, then the oldest event in that queue will be dropped.
-
-3. Where applicable, certain event types can ensure that the payload of
-   the oldest event that is about to be dropped will be merged with the
-   payload of the next oldest event. Thus ensuring that no information
-   is lost, but only an intermediate step leading up to that
-   information. See the documentation for the event you want to
-   subscribe to whether this is applicable for that event or not.
diff --git a/Documentation/media/uapi/v4l/dev-mem2mem.rst b/Documentation/media/uapi/v4l/dev-mem2mem.rst
deleted file mode 100644
index 70953958cee6..000000000000
--- a/Documentation/media/uapi/v4l/dev-mem2mem.rst
+++ /dev/null
@@ -1,49 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _mem2mem:
-
-********************************
-Video Memory-To-Memory Interface
-********************************
-
-A V4L2 memory-to-memory device can compress, decompress, transform, or
-otherwise convert video data from one format into another format, in memory.
-Such memory-to-memory devices set the ``V4L2_CAP_VIDEO_M2M`` or
-``V4L2_CAP_VIDEO_M2M_MPLANE`` capability. Examples of memory-to-memory
-devices are codecs, scalers, deinterlacers or format converters (i.e.
-converting from YUV to RGB).
-
-A memory-to-memory video node acts just like a normal video node, but it
-supports both output (sending frames from memory to the hardware)
-and capture (receiving the processed frames from the hardware into
-memory) stream I/O. An application will have to setup the stream I/O for
-both sides and finally call :ref:`VIDIOC_STREAMON <VIDIOC_STREAMON>`
-for both capture and output to start the hardware.
-
-Memory-to-memory devices function as a shared resource: you can
-open the video node multiple times, each application setting up their
-own properties that are local to the file handle, and each can use
-it independently from the others. The driver will arbitrate access to
-the hardware and reprogram it whenever another file handler gets access.
-This is different from the usual video node behavior where the video
-properties are global to the device (i.e. changing something through one
-file handle is visible through another file handle).
-
-One of the most common memory-to-memory device is the codec. Codecs
-are more complicated than most and require additional setup for
-their codec parameters. This is done through codec controls.
-See :ref:`mpeg-controls`. More details on how to use codec memory-to-memory
-devices are given in the following sections.
-
-.. toctree::
-    :maxdepth: 1
-
-    dev-decoder
-    dev-stateless-decoder
diff --git a/Documentation/media/uapi/v4l/dev-meta.rst b/Documentation/media/uapi/v4l/dev-meta.rst
deleted file mode 100644
index c5dbe882be65..000000000000
--- a/Documentation/media/uapi/v4l/dev-meta.rst
+++ /dev/null
@@ -1,74 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _metadata:
-
-******************
-Metadata Interface
-******************
-
-Metadata refers to any non-image data that supplements video frames with
-additional information. This may include statistics computed over the image,
-frame capture parameters supplied by the image source or device specific
-parameters for specifying how the device processes images. This interface is
-intended for transfer of metadata between the userspace and the hardware and
-control of that operation.
-
-The metadata interface is implemented on video device nodes. The device can be
-dedicated to metadata or can support both video and metadata as specified in its
-reported capabilities.
-
-Querying Capabilities
-=====================
-
-Device nodes supporting the metadata capture interface set the
-``V4L2_CAP_META_CAPTURE`` flag in the ``device_caps`` field of the
-:c:type:`v4l2_capability` structure returned by the :c:func:`VIDIOC_QUERYCAP`
-ioctl. That flag means the device can capture metadata to memory. Similarly,
-device nodes supporting metadata output interface set the
-``V4L2_CAP_META_OUTPUT`` flag in the ``device_caps`` field of
-:c:type:`v4l2_capability` structure. That flag means the device can read
-metadata from memory.
-
-At least one of the read/write or streaming I/O methods must be supported.
-
-
-Data Format Negotiation
-=======================
-
-The metadata device uses the :ref:`format` ioctls to select the capture format.
-The metadata buffer content format is bound to that selected format. In addition
-to the basic :ref:`format` ioctls, the :c:func:`VIDIOC_ENUM_FMT` ioctl must be
-supported as well.
-
-To use the :ref:`format` ioctls applications set the ``type`` field of the
-:c:type:`v4l2_format` structure to ``V4L2_BUF_TYPE_META_CAPTURE`` or to
-``V4L2_BUF_TYPE_META_OUTPUT`` and use the :c:type:`v4l2_meta_format` ``meta``
-member of the ``fmt`` union as needed per the desired operation. Both drivers
-and applications must set the remainder of the :c:type:`v4l2_format` structure
-to 0.
-
-.. c:type:: v4l2_meta_format
-
-.. tabularcolumns:: |p{1.4cm}|p{2.2cm}|p{13.9cm}|
-
-.. flat-table:: struct v4l2_meta_format
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``dataformat``
-      - The data format, set by the application. This is a little endian
-        :ref:`four character code <v4l2-fourcc>`. V4L2 defines metadata formats
-        in :ref:`meta-formats`.
-    * - __u32
-      - ``buffersize``
-      - Maximum buffer size in bytes required for data. The value is set by the
-        driver.
diff --git a/Documentation/media/uapi/v4l/dev-osd.rst b/Documentation/media/uapi/v4l/dev-osd.rst
deleted file mode 100644
index d3ad67da6386..000000000000
--- a/Documentation/media/uapi/v4l/dev-osd.rst
+++ /dev/null
@@ -1,157 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _osd:
-
-******************************
-Video Output Overlay Interface
-******************************
-
-**Also known as On-Screen Display (OSD)**
-
-Some video output devices can overlay a framebuffer image onto the
-outgoing video signal. Applications can set up such an overlay using
-this interface, which borrows structures and ioctls of the
-:ref:`Video Overlay <overlay>` interface.
-
-The OSD function is accessible through the same character special file
-as the :ref:`Video Output <capture>` function.
-
-.. note::
-
-   The default function of such a ``/dev/video`` device is video
-   capturing or output. The OSD function is only available after calling
-   the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl.
-
-
-Querying Capabilities
-=====================
-
-Devices supporting the *Video Output Overlay* interface set the
-``V4L2_CAP_VIDEO_OUTPUT_OVERLAY`` flag in the ``capabilities`` field of
-struct :c:type:`v4l2_capability` returned by the
-:ref:`VIDIOC_QUERYCAP` ioctl.
-
-
-Framebuffer
-===========
-
-Contrary to the *Video Overlay* interface the framebuffer is normally
-implemented on the TV card and not the graphics card. On Linux it is
-accessible as a framebuffer device (``/dev/fbN``). Given a V4L2 device,
-applications can find the corresponding framebuffer device by calling
-the :ref:`VIDIOC_G_FBUF <VIDIOC_G_FBUF>` ioctl. It returns, amongst
-other information, the physical address of the framebuffer in the
-``base`` field of struct :c:type:`v4l2_framebuffer`.
-The framebuffer device ioctl ``FBIOGET_FSCREENINFO`` returns the same
-address in the ``smem_start`` field of struct
-struct :c:type:`fb_fix_screeninfo`. The ``FBIOGET_FSCREENINFO``
-ioctl and struct :c:type:`fb_fix_screeninfo` are defined in
-the ``linux/fb.h`` header file.
-
-The width and height of the framebuffer depends on the current video
-standard. A V4L2 driver may reject attempts to change the video standard
-(or any other ioctl which would imply a framebuffer size change) with an
-``EBUSY`` error code until all applications closed the framebuffer device.
-
-Example: Finding a framebuffer device for OSD
----------------------------------------------
-
-.. code-block:: c
-
-    #include <linux/fb.h>
-
-    struct v4l2_framebuffer fbuf;
-    unsigned int i;
-    int fb_fd;
-
-    if (-1 == ioctl(fd, VIDIOC_G_FBUF, &fbuf)) {
-	perror("VIDIOC_G_FBUF");
-	exit(EXIT_FAILURE);
-    }
-
-    for (i = 0; i < 30; i++) {
-	char dev_name[16];
-	struct fb_fix_screeninfo si;
-
-	snprintf(dev_name, sizeof(dev_name), "/dev/fb%u", i);
-
-	fb_fd = open(dev_name, O_RDWR);
-	if (-1 == fb_fd) {
-	    switch (errno) {
-	    case ENOENT: /* no such file */
-	    case ENXIO:  /* no driver */
-		continue;
-
-	    default:
-		perror("open");
-		exit(EXIT_FAILURE);
-	    }
-	}
-
-	if (0 == ioctl(fb_fd, FBIOGET_FSCREENINFO, &si)) {
-	    if (si.smem_start == (unsigned long)fbuf.base)
-		break;
-	} else {
-	    /* Apparently not a framebuffer device. */
-	}
-
-	close(fb_fd);
-	fb_fd = -1;
-    }
-
-    /* fb_fd is the file descriptor of the framebuffer device
-       for the video output overlay, or -1 if no device was found. */
-
-
-Overlay Window and Scaling
-==========================
-
-The overlay is controlled by source and target rectangles. The source
-rectangle selects a subsection of the framebuffer image to be overlaid,
-the target rectangle an area in the outgoing video signal where the
-image will appear. Drivers may or may not support scaling, and arbitrary
-sizes and positions of these rectangles. Further drivers may support any
-(or none) of the clipping/blending methods defined for the
-:ref:`Video Overlay <overlay>` interface.
-
-A struct :c:type:`v4l2_window` defines the size of the
-source rectangle, its position in the framebuffer and the
-clipping/blending method to be used for the overlay. To get the current
-parameters applications set the ``type`` field of a struct
-:c:type:`v4l2_format` to
-``V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY`` and call the
-:ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` ioctl. The driver fills the
-struct :c:type:`v4l2_window` substructure named ``win``. It is not
-possible to retrieve a previously programmed clipping list or bitmap.
-
-To program the source rectangle applications set the ``type`` field of a
-struct :c:type:`v4l2_format` to
-``V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY``, initialize the ``win``
-substructure and call the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl.
-The driver adjusts the parameters against hardware limits and returns
-the actual parameters as :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` does. Like :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`,
-the :ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` ioctl can be used to learn
-about driver capabilities without actually changing driver state. Unlike
-:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` this also works after the overlay has been enabled.
-
-A struct :c:type:`v4l2_crop` defines the size and position
-of the target rectangle. The scaling factor of the overlay is implied by
-the width and height given in struct :c:type:`v4l2_window`
-and struct :c:type:`v4l2_crop`. The cropping API applies to
-*Video Output* and *Video Output Overlay* devices in the same way as to
-*Video Capture* and *Video Overlay* devices, merely reversing the
-direction of the data flow. For more information see :ref:`crop`.
-
-
-Enabling Overlay
-================
-
-There is no V4L2 ioctl to enable or disable the overlay, however the
-framebuffer interface of the driver may support the ``FBIOBLANK`` ioctl.
diff --git a/Documentation/media/uapi/v4l/dev-output.rst b/Documentation/media/uapi/v4l/dev-output.rst
deleted file mode 100644
index 3fe1b39696ed..000000000000
--- a/Documentation/media/uapi/v4l/dev-output.rst
+++ /dev/null
@@ -1,108 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _output:
-
-**********************
-Video Output Interface
-**********************
-
-Video output devices encode stills or image sequences as analog video
-signal. With this interface applications can control the encoding
-process and move images from user space to the driver.
-
-Conventionally V4L2 video output devices are accessed through character
-device special files named ``/dev/video`` and ``/dev/video0`` to
-``/dev/video63`` with major number 81 and minor numbers 0 to 63.
-``/dev/video`` is typically a symbolic link to the preferred video
-device.
-
-.. note:: The same device file names are used also for video capture devices.
-
-
-Querying Capabilities
-=====================
-
-Devices supporting the video output interface set the
-``V4L2_CAP_VIDEO_OUTPUT`` or ``V4L2_CAP_VIDEO_OUTPUT_MPLANE`` flag in
-the ``capabilities`` field of struct
-:c:type:`v4l2_capability` returned by the
-:ref:`VIDIOC_QUERYCAP` ioctl. As secondary device
-functions they may also support the :ref:`raw VBI output <raw-vbi>`
-(``V4L2_CAP_VBI_OUTPUT``) interface. At least one of the read/write or
-streaming I/O methods must be supported. Modulators and audio outputs
-are optional.
-
-
-Supplemental Functions
-======================
-
-Video output devices shall support :ref:`audio output <audio>`,
-:ref:`modulator <tuner>`, :ref:`controls <control>`,
-:ref:`cropping and scaling <crop>` and
-:ref:`streaming parameter <streaming-par>` ioctls as needed. The
-:ref:`video output <video>` ioctls must be supported by all video
-output devices.
-
-
-Image Format Negotiation
-========================
-
-The output is determined by cropping and image format parameters. The
-former select an area of the video picture where the image will appear,
-the latter how images are stored in memory, i. e. in RGB or YUV format,
-the number of bits per pixel or width and height. Together they also
-define how images are scaled in the process.
-
-As usual these parameters are *not* reset at :ref:`open() <func-open>`
-time to permit Unix tool chains, programming a device and then writing
-to it as if it was a plain file. Well written V4L2 applications ensure
-they really get what they want, including cropping and scaling.
-
-Cropping initialization at minimum requires to reset the parameters to
-defaults. An example is given in :ref:`crop`.
-
-To query the current image format applications set the ``type`` field of
-a struct :c:type:`v4l2_format` to
-``V4L2_BUF_TYPE_VIDEO_OUTPUT`` or ``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE``
-and call the :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` ioctl with a pointer
-to this structure. Drivers fill the struct
-:c:type:`v4l2_pix_format` ``pix`` or the struct
-:c:type:`v4l2_pix_format_mplane` ``pix_mp``
-member of the ``fmt`` union.
-
-To request different parameters applications set the ``type`` field of a
-struct :c:type:`v4l2_format` as above and initialize all
-fields of the struct :c:type:`v4l2_pix_format`
-``vbi`` member of the ``fmt`` union, or better just modify the results
-of :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>`, and call the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`
-ioctl with a pointer to this structure. Drivers may adjust the
-parameters and finally return the actual parameters as :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>`
-does.
-
-Like :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` the :ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` ioctl
-can be used to learn about hardware limitations without disabling I/O or
-possibly time consuming hardware preparations.
-
-The contents of struct :c:type:`v4l2_pix_format` and
-struct :c:type:`v4l2_pix_format_mplane` are
-discussed in :ref:`pixfmt`. See also the specification of the
-:ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>`, :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` and :ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` ioctls for
-details. Video output devices must implement both the :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>`
-and :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl, even if :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ignores all
-requests and always returns default parameters as :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` does.
-:ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` is optional.
-
-
-Writing Images
-==============
-
-A video output device may support the :ref:`write() function <rw>`
-and/or streaming (:ref:`memory mapping <mmap>` or
-:ref:`user pointer <userp>`) I/O. See :ref:`io` for details.
diff --git a/Documentation/media/uapi/v4l/dev-overlay.rst b/Documentation/media/uapi/v4l/dev-overlay.rst
deleted file mode 100644
index b91b3837d4e7..000000000000
--- a/Documentation/media/uapi/v4l/dev-overlay.rst
+++ /dev/null
@@ -1,328 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _overlay:
-
-***********************
-Video Overlay Interface
-***********************
-
-**Also known as Framebuffer Overlay or Previewing.**
-
-Video overlay devices have the ability to genlock (TV-)video into the
-(VGA-)video signal of a graphics card, or to store captured images
-directly in video memory of a graphics card, typically with clipping.
-This can be considerable more efficient than capturing images and
-displaying them by other means. In the old days when only nuclear power
-plants needed cooling towers this used to be the only way to put live
-video into a window.
-
-Video overlay devices are accessed through the same character special
-files as :ref:`video capture <capture>` devices.
-
-.. note::
-
-   The default function of a ``/dev/video`` device is video
-   capturing. The overlay function is only available after calling
-   the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl.
-
-The driver may support simultaneous overlay and capturing using the
-read/write and streaming I/O methods. If so, operation at the nominal
-frame rate of the video standard is not guaranteed. Frames may be
-directed away from overlay to capture, or one field may be used for
-overlay and the other for capture if the capture parameters permit this.
-
-Applications should use different file descriptors for capturing and
-overlay. This must be supported by all drivers capable of simultaneous
-capturing and overlay. Optionally these drivers may also permit
-capturing and overlay with a single file descriptor for compatibility
-with V4L and earlier versions of V4L2. [#f1]_
-
-
-Querying Capabilities
-=====================
-
-Devices supporting the video overlay interface set the
-``V4L2_CAP_VIDEO_OVERLAY`` flag in the ``capabilities`` field of struct
-:c:type:`v4l2_capability` returned by the
-:ref:`VIDIOC_QUERYCAP` ioctl. The overlay I/O
-method specified below must be supported. Tuners and audio inputs are
-optional.
-
-
-Supplemental Functions
-======================
-
-Video overlay devices shall support :ref:`audio input <audio>`,
-:ref:`tuner`, :ref:`controls <control>`,
-:ref:`cropping and scaling <crop>` and
-:ref:`streaming parameter <streaming-par>` ioctls as needed. The
-:ref:`video input <video>` and :ref:`video standard <standard>`
-ioctls must be supported by all video overlay devices.
-
-
-Setup
-=====
-
-Before overlay can commence applications must program the driver with
-frame buffer parameters, namely the address and size of the frame buffer
-and the image format, for example RGB 5:6:5. The
-:ref:`VIDIOC_G_FBUF <VIDIOC_G_FBUF>` and
-:ref:`VIDIOC_S_FBUF <VIDIOC_G_FBUF>` ioctls are available to get and
-set these parameters, respectively. The :ref:`VIDIOC_S_FBUF <VIDIOC_G_FBUF>` ioctl is
-privileged because it allows to set up DMA into physical memory,
-bypassing the memory protection mechanisms of the kernel. Only the
-superuser can change the frame buffer address and size. Users are not
-supposed to run TV applications as root or with SUID bit set. A small
-helper application with suitable privileges should query the graphics
-system and program the V4L2 driver at the appropriate time.
-
-Some devices add the video overlay to the output signal of the graphics
-card. In this case the frame buffer is not modified by the video device,
-and the frame buffer address and pixel format are not needed by the
-driver. The :ref:`VIDIOC_S_FBUF <VIDIOC_G_FBUF>` ioctl is not privileged. An application
-can check for this type of device by calling the :ref:`VIDIOC_G_FBUF <VIDIOC_G_FBUF>`
-ioctl.
-
-A driver may support any (or none) of five clipping/blending methods:
-
-1. Chroma-keying displays the overlaid image only where pixels in the
-   primary graphics surface assume a certain color.
-
-2. A bitmap can be specified where each bit corresponds to a pixel in
-   the overlaid image. When the bit is set, the corresponding video
-   pixel is displayed, otherwise a pixel of the graphics surface.
-
-3. A list of clipping rectangles can be specified. In these regions *no*
-   video is displayed, so the graphics surface can be seen here.
-
-4. The framebuffer has an alpha channel that can be used to clip or
-   blend the framebuffer with the video.
-
-5. A global alpha value can be specified to blend the framebuffer
-   contents with video images.
-
-When simultaneous capturing and overlay is supported and the hardware
-prohibits different image and frame buffer formats, the format requested
-first takes precedence. The attempt to capture
-(:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`) or overlay
-(:ref:`VIDIOC_S_FBUF <VIDIOC_G_FBUF>`) may fail with an ``EBUSY`` error
-code or return accordingly modified parameters..
-
-
-Overlay Window
-==============
-
-The overlaid image is determined by cropping and overlay window
-parameters. The former select an area of the video picture to capture,
-the latter how images are overlaid and clipped. Cropping initialization
-at minimum requires to reset the parameters to defaults. An example is
-given in :ref:`crop`.
-
-The overlay window is described by a struct
-:c:type:`v4l2_window`. It defines the size of the image,
-its position over the graphics surface and the clipping to be applied.
-To get the current parameters applications set the ``type`` field of a
-struct :c:type:`v4l2_format` to
-``V4L2_BUF_TYPE_VIDEO_OVERLAY`` and call the
-:ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` ioctl. The driver fills the
-struct :c:type:`v4l2_window` substructure named ``win``. It is not
-possible to retrieve a previously programmed clipping list or bitmap.
-
-To program the overlay window applications set the ``type`` field of a
-struct :c:type:`v4l2_format` to
-``V4L2_BUF_TYPE_VIDEO_OVERLAY``, initialize the ``win`` substructure and
-call the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl. The driver
-adjusts the parameters against hardware limits and returns the actual
-parameters as :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` does. Like :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`, the
-:ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` ioctl can be used to learn
-about driver capabilities without actually changing driver state. Unlike
-:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` this also works after the overlay has been enabled.
-
-The scaling factor of the overlaid image is implied by the width and
-height given in struct :c:type:`v4l2_window` and the size
-of the cropping rectangle. For more information see :ref:`crop`.
-
-When simultaneous capturing and overlay is supported and the hardware
-prohibits different image and window sizes, the size requested first
-takes precedence. The attempt to capture or overlay as well
-(:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`) may fail with an ``EBUSY`` error
-code or return accordingly modified parameters.
-
-
-.. c:type:: v4l2_window
-
-struct v4l2_window
-------------------
-
-``struct v4l2_rect w``
-    Size and position of the window relative to the top, left corner of
-    the frame buffer defined with
-    :ref:`VIDIOC_S_FBUF <VIDIOC_G_FBUF>`. The window can extend the
-    frame buffer width and height, the ``x`` and ``y`` coordinates can
-    be negative, and it can lie completely outside the frame buffer. The
-    driver clips the window accordingly, or if that is not possible,
-    modifies its size and/or position.
-
-``enum v4l2_field field``
-    Applications set this field to determine which video field shall be
-    overlaid, typically one of ``V4L2_FIELD_ANY`` (0),
-    ``V4L2_FIELD_TOP``, ``V4L2_FIELD_BOTTOM`` or
-    ``V4L2_FIELD_INTERLACED``. Drivers may have to choose a different
-    field order and return the actual setting here.
-
-``__u32 chromakey``
-    When chroma-keying has been negotiated with
-    :ref:`VIDIOC_S_FBUF <VIDIOC_G_FBUF>` applications set this field
-    to the desired pixel value for the chroma key. The format is the
-    same as the pixel format of the framebuffer (struct
-    :c:type:`v4l2_framebuffer` ``fmt.pixelformat``
-    field), with bytes in host order. E. g. for
-    :ref:`V4L2_PIX_FMT_BGR24 <V4L2-PIX-FMT-BGR32>` the value should
-    be 0xRRGGBB on a little endian, 0xBBGGRR on a big endian host.
-
-``struct v4l2_clip * clips``
-    When chroma-keying has *not* been negotiated and
-    :ref:`VIDIOC_G_FBUF <VIDIOC_G_FBUF>` indicated this capability,
-    applications can set this field to point to an array of clipping
-    rectangles.
-
-    Like the window coordinates w, clipping rectangles are defined
-    relative to the top, left corner of the frame buffer. However
-    clipping rectangles must not extend the frame buffer width and
-    height, and they must not overlap. If possible applications
-    should merge adjacent rectangles. Whether this must create
-    x-y or y-x bands, or the order of rectangles, is not defined. When
-    clip lists are not supported the driver ignores this field. Its
-    contents after calling :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`
-    are undefined.
-
-``__u32 clipcount``
-    When the application set the ``clips`` field, this field must
-    contain the number of clipping rectangles in the list. When clip
-    lists are not supported the driver ignores this field, its contents
-    after calling :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` are undefined. When clip lists are
-    supported but no clipping is desired this field must be set to zero.
-
-``void * bitmap``
-    When chroma-keying has *not* been negotiated and
-    :ref:`VIDIOC_G_FBUF <VIDIOC_G_FBUF>` indicated this capability,
-    applications can set this field to point to a clipping bit mask.
-
-It must be of the same size as the window, ``w.width`` and ``w.height``.
-Each bit corresponds to a pixel in the overlaid image, which is
-displayed only when the bit is *set*. Pixel coordinates translate to
-bits like:
-
-
-.. code-block:: c
-
-    ((__u8 *) bitmap)[w.width * y + x / 8] & (1 << (x & 7))
-
-where ``0`` ≤ x < ``w.width`` and ``0`` ≤ y <``w.height``. [#f2]_
-
-When a clipping bit mask is not supported the driver ignores this field,
-its contents after calling :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` are
-undefined. When a bit mask is supported but no clipping is desired this
-field must be set to ``NULL``.
-
-Applications need not create a clip list or bit mask. When they pass
-both, or despite negotiating chroma-keying, the results are undefined.
-Regardless of the chosen method, the clipping abilities of the hardware
-may be limited in quantity or quality. The results when these limits are
-exceeded are undefined. [#f3]_
-
-``__u8 global_alpha``
-    The global alpha value used to blend the framebuffer with video
-    images, if global alpha blending has been negotiated
-    (``V4L2_FBUF_FLAG_GLOBAL_ALPHA``, see
-    :ref:`VIDIOC_S_FBUF <VIDIOC_G_FBUF>`,
-    :ref:`framebuffer-flags`).
-
-.. note::
-
-   This field was added in Linux 2.6.23, extending the
-   structure. However the :ref:`VIDIOC_[G|S|TRY]_FMT <VIDIOC_G_FMT>`
-   ioctls, which take a pointer to a :c:type:`v4l2_format`
-   parent structure with padding bytes at the end, are not affected.
-
-
-.. c:type:: v4l2_clip
-
-struct v4l2_clip [#f4]_
------------------------
-
-``struct v4l2_rect c``
-    Coordinates of the clipping rectangle, relative to the top, left
-    corner of the frame buffer. Only window pixels *outside* all
-    clipping rectangles are displayed.
-
-``struct v4l2_clip * next``
-    Pointer to the next clipping rectangle, ``NULL`` when this is the last
-    rectangle. Drivers ignore this field, it cannot be used to pass a
-    linked list of clipping rectangles.
-
-
-.. c:type:: v4l2_rect
-
-struct v4l2_rect
-----------------
-
-``__s32 left``
-    Horizontal offset of the top, left corner of the rectangle, in
-    pixels.
-
-``__s32 top``
-    Vertical offset of the top, left corner of the rectangle, in pixels.
-    Offsets increase to the right and down.
-
-``__u32 width``
-    Width of the rectangle, in pixels.
-
-``__u32 height``
-    Height of the rectangle, in pixels.
-
-
-Enabling Overlay
-================
-
-To start or stop the frame buffer overlay applications call the
-:ref:`VIDIOC_OVERLAY` ioctl.
-
-.. [#f1]
-   A common application of two file descriptors is the XFree86
-   :ref:`Xv/V4L <xvideo>` interface driver and a V4L2 application.
-   While the X server controls video overlay, the application can take
-   advantage of memory mapping and DMA.
-
-   In the opinion of the designers of this API, no driver writer taking
-   the efforts to support simultaneous capturing and overlay will
-   restrict this ability by requiring a single file descriptor, as in
-   V4L and earlier versions of V4L2. Making this optional means
-   applications depending on two file descriptors need backup routines
-   to be compatible with all drivers, which is considerable more work
-   than using two fds in applications which do not. Also two fd's fit
-   the general concept of one file descriptor for each logical stream.
-   Hence as a complexity trade-off drivers *must* support two file
-   descriptors and *may* support single fd operation.
-
-.. [#f2]
-   Should we require ``w.width`` to be a multiple of eight?
-
-.. [#f3]
-   When the image is written into frame buffer memory it will be
-   undesirable if the driver clips out less pixels than expected,
-   because the application and graphics system are not aware these
-   regions need to be refreshed. The driver should clip out more pixels
-   or not write the image at all.
-
-.. [#f4]
-   The X Window system defines "regions" which are vectors of ``struct
-   BoxRec { short x1, y1, x2, y2; }`` with ``width = x2 - x1`` and
-   ``height = y2 - y1``, so one cannot pass X11 clip lists directly.
diff --git a/Documentation/media/uapi/v4l/dev-radio.rst b/Documentation/media/uapi/v4l/dev-radio.rst
deleted file mode 100644
index 133eb0e788c2..000000000000
--- a/Documentation/media/uapi/v4l/dev-radio.rst
+++ /dev/null
@@ -1,59 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _radio:
-
-***************
-Radio Interface
-***************
-
-This interface is intended for AM and FM (analog) radio receivers and
-transmitters.
-
-Conventionally V4L2 radio devices are accessed through character device
-special files named ``/dev/radio`` and ``/dev/radio0`` to
-``/dev/radio63`` with major number 81 and minor numbers 64 to 127.
-
-
-Querying Capabilities
-=====================
-
-Devices supporting the radio interface set the ``V4L2_CAP_RADIO`` and
-``V4L2_CAP_TUNER`` or ``V4L2_CAP_MODULATOR`` flag in the
-``capabilities`` field of struct
-:c:type:`v4l2_capability` returned by the
-:ref:`VIDIOC_QUERYCAP` ioctl. Other combinations of
-capability flags are reserved for future extensions.
-
-
-Supplemental Functions
-======================
-
-Radio devices can support :ref:`controls <control>`, and must support
-the :ref:`tuner or modulator <tuner>` ioctls.
-
-They do not support the video input or output, audio input or output,
-video standard, cropping and scaling, compression and streaming
-parameter, or overlay ioctls. All other ioctls and I/O methods are
-reserved for future extensions.
-
-
-Programming
-===========
-
-Radio devices may have a couple audio controls (as discussed in
-:ref:`control`) such as a volume control, possibly custom controls.
-Further all radio devices have one tuner or modulator (these are
-discussed in :ref:`tuner`) with index number zero to select the radio
-frequency and to determine if a monaural or FM stereo program is
-received/emitted. Drivers switch automatically between AM and FM
-depending on the selected frequency. The
-:ref:`VIDIOC_G_TUNER <VIDIOC_G_TUNER>` or
-:ref:`VIDIOC_G_MODULATOR <VIDIOC_G_MODULATOR>` ioctl reports the
-supported frequency range.
diff --git a/Documentation/media/uapi/v4l/dev-raw-vbi.rst b/Documentation/media/uapi/v4l/dev-raw-vbi.rst
deleted file mode 100644
index e06b03ca2ab2..000000000000
--- a/Documentation/media/uapi/v4l/dev-raw-vbi.rst
+++ /dev/null
@@ -1,306 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _raw-vbi:
-
-**********************
-Raw VBI Data Interface
-**********************
-
-VBI is an abbreviation of Vertical Blanking Interval, a gap in the
-sequence of lines of an analog video signal. During VBI no picture
-information is transmitted, allowing some time while the electron beam
-of a cathode ray tube TV returns to the top of the screen. Using an
-oscilloscope you will find here the vertical synchronization pulses and
-short data packages ASK modulated [#f1]_ onto the video signal. These are
-transmissions of services such as Teletext or Closed Caption.
-
-Subject of this interface type is raw VBI data, as sampled off a video
-signal, or to be added to a signal for output. The data format is
-similar to uncompressed video images, a number of lines times a number
-of samples per line, we call this a VBI image.
-
-Conventionally V4L2 VBI devices are accessed through character device
-special files named ``/dev/vbi`` and ``/dev/vbi0`` to ``/dev/vbi31``
-with major number 81 and minor numbers 224 to 255. ``/dev/vbi`` is
-typically a symbolic link to the preferred VBI device. This convention
-applies to both input and output devices.
-
-To address the problems of finding related video and VBI devices VBI
-capturing and output is also available as device function under
-``/dev/video``. To capture or output raw VBI data with these devices
-applications must call the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl.
-Accessed as ``/dev/vbi``, raw VBI capturing or output is the default
-device function.
-
-
-Querying Capabilities
-=====================
-
-Devices supporting the raw VBI capturing or output API set the
-``V4L2_CAP_VBI_CAPTURE`` or ``V4L2_CAP_VBI_OUTPUT`` flags, respectively,
-in the ``capabilities`` field of struct
-:c:type:`v4l2_capability` returned by the
-:ref:`VIDIOC_QUERYCAP` ioctl. At least one of the
-read/write, streaming or asynchronous I/O methods must be supported. VBI
-devices may or may not have a tuner or modulator.
-
-
-Supplemental Functions
-======================
-
-VBI devices shall support :ref:`video input or output <video>`,
-:ref:`tuner or modulator <tuner>`, and :ref:`controls <control>`
-ioctls as needed. The :ref:`video standard <standard>` ioctls provide
-information vital to program a VBI device, therefore must be supported.
-
-
-Raw VBI Format Negotiation
-==========================
-
-Raw VBI sampling abilities can vary, in particular the sampling
-frequency. To properly interpret the data V4L2 specifies an ioctl to
-query the sampling parameters. Moreover, to allow for some flexibility
-applications can also suggest different parameters.
-
-As usual these parameters are *not* reset at :ref:`open() <func-open>`
-time to permit Unix tool chains, programming a device and then reading
-from it as if it was a plain file. Well written V4L2 applications should
-always ensure they really get what they want, requesting reasonable
-parameters and then checking if the actual parameters are suitable.
-
-To query the current raw VBI capture parameters applications set the
-``type`` field of a struct :c:type:`v4l2_format` to
-``V4L2_BUF_TYPE_VBI_CAPTURE`` or ``V4L2_BUF_TYPE_VBI_OUTPUT``, and call
-the :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` ioctl with a pointer to this
-structure. Drivers fill the struct
-:c:type:`v4l2_vbi_format` ``vbi`` member of the
-``fmt`` union.
-
-To request different parameters applications set the ``type`` field of a
-struct :c:type:`v4l2_format` as above and initialize all
-fields of the struct :c:type:`v4l2_vbi_format`
-``vbi`` member of the ``fmt`` union, or better just modify the results
-of :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>`, and call the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`
-ioctl with a pointer to this structure. Drivers return an ``EINVAL`` error
-code only when the given parameters are ambiguous, otherwise they modify
-the parameters according to the hardware capabilities and return the
-actual parameters. When the driver allocates resources at this point, it
-may return an ``EBUSY`` error code to indicate the returned parameters are
-valid but the required resources are currently not available. That may
-happen for instance when the video and VBI areas to capture would
-overlap, or when the driver supports multiple opens and another process
-already requested VBI capturing or output. Anyway, applications must
-expect other resource allocation points which may return ``EBUSY``, at the
-:ref:`VIDIOC_STREAMON` ioctl and the first :ref:`read() <func-read>`
-, :ref:`write() <func-write>` and :ref:`select() <func-select>` calls.
-
-VBI devices must implement both the :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` and
-:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl, even if :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ignores all requests
-and always returns default parameters as :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` does.
-:ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` is optional.
-
-.. tabularcolumns:: |p{1.6cm}|p{4.2cm}|p{11.7cm}|
-
-.. c:type:: v4l2_vbi_format
-
-.. cssclass:: longtable
-
-.. flat-table:: struct v4l2_vbi_format
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``sampling_rate``
-      - Samples per second, i. e. unit 1 Hz.
-    * - __u32
-      - ``offset``
-      - Horizontal offset of the VBI image, relative to the leading edge
-	of the line synchronization pulse and counted in samples: The
-	first sample in the VBI image will be located ``offset`` /
-	``sampling_rate`` seconds following the leading edge. See also
-	:ref:`vbi-hsync`.
-    * - __u32
-      - ``samples_per_line``
-      -
-    * - __u32
-      - ``sample_format``
-      - Defines the sample format as in :ref:`pixfmt`, a
-	four-character-code. [#f2]_ Usually this is ``V4L2_PIX_FMT_GREY``,
-	i. e. each sample consists of 8 bits with lower values oriented
-	towards the black level. Do not assume any other correlation of
-	values with the signal level. For example, the MSB does not
-	necessarily indicate if the signal is 'high' or 'low' because 128
-	may not be the mean value of the signal. Drivers shall not convert
-	the sample format by software.
-    * - __u32
-      - ``start``\ [#f2]_
-      - This is the scanning system line number associated with the first
-	line of the VBI image, of the first and the second field
-	respectively. See :ref:`vbi-525` and :ref:`vbi-625` for valid
-	values. The ``V4L2_VBI_ITU_525_F1_START``,
-	``V4L2_VBI_ITU_525_F2_START``, ``V4L2_VBI_ITU_625_F1_START`` and
-	``V4L2_VBI_ITU_625_F2_START`` defines give the start line numbers
-	for each field for each 525 or 625 line format as a convenience.
-	Don't forget that ITU line numbering starts at 1, not 0. VBI input
-	drivers can return start values 0 if the hardware cannot reliable
-	identify scanning lines, VBI acquisition may not require this
-	information.
-    * - __u32
-      - ``count``\ [#f2]_
-      - The number of lines in the first and second field image,
-	respectively.
-    * - :cspan:`2`
-
-	Drivers should be as flexibility as possible. For example, it may
-	be possible to extend or move the VBI capture window down to the
-	picture area, implementing a 'full field mode' to capture data
-	service transmissions embedded in the picture.
-
-	An application can set the first or second ``count`` value to zero
-	if no data is required from the respective field; ``count``\ [1]
-	if the scanning system is progressive, i. e. not interlaced. The
-	corresponding start value shall be ignored by the application and
-	driver. Anyway, drivers may not support single field capturing and
-	return both count values non-zero.
-
-	Both ``count`` values set to zero, or line numbers are outside the
-	bounds depicted\ [#f4]_, or a field image covering lines of two
-	fields, are invalid and shall not be returned by the driver.
-
-	To initialize the ``start`` and ``count`` fields, applications
-	must first determine the current video standard selection. The
-	:ref:`v4l2_std_id <v4l2-std-id>` or the ``framelines`` field
-	of struct :c:type:`v4l2_standard` can be evaluated
-	for this purpose.
-    * - __u32
-      - ``flags``
-      - See :ref:`vbifmt-flags` below. Currently only drivers set flags,
-	applications must set this field to zero.
-    * - __u32
-      - ``reserved``\ [#f2]_
-      - This array is reserved for future extensions. Drivers and
-	applications must set it to zero.
-
-
-.. tabularcolumns:: |p{4.4cm}|p{1.5cm}|p{11.6cm}|
-
-.. _vbifmt-flags:
-
-.. flat-table:: Raw VBI Format Flags
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_VBI_UNSYNC``
-      - 0x0001
-      - This flag indicates hardware which does not properly distinguish
-	between fields. Normally the VBI image stores the first field
-	(lower scanning line numbers) first in memory. This may be a top
-	or bottom field depending on the video standard. When this flag is
-	set the first or second field may be stored first, however the
-	fields are still in correct temporal order with the older field
-	first in memory. [#f3]_
-    * - ``V4L2_VBI_INTERLACED``
-      - 0x0002
-      - By default the two field images will be passed sequentially; all
-	lines of the first field followed by all lines of the second field
-	(compare :ref:`field-order` ``V4L2_FIELD_SEQ_TB`` and
-	``V4L2_FIELD_SEQ_BT``, whether the top or bottom field is first in
-	memory depends on the video standard). When this flag is set, the
-	two fields are interlaced (cf. ``V4L2_FIELD_INTERLACED``). The
-	first line of the first field followed by the first line of the
-	second field, then the two second lines, and so on. Such a layout
-	may be necessary when the hardware has been programmed to capture
-	or output interlaced video images and is unable to separate the
-	fields for VBI capturing at the same time. For simplicity setting
-	this flag implies that both ``count`` values are equal and
-	non-zero.
-
-
-
-.. _vbi-hsync:
-
-.. kernel-figure:: vbi_hsync.svg
-    :alt:   vbi_hsync.svg
-    :align: center
-
-    **Figure 4.1. Line synchronization**
-
-
-.. _vbi-525:
-
-.. kernel-figure:: vbi_525.svg
-    :alt:   vbi_525.svg
-    :align: center
-
-    **Figure 4.2. ITU-R 525 line numbering (M/NTSC and M/PAL)**
-
-.. _vbi-625:
-
-.. kernel-figure:: vbi_625.svg
-    :alt:   vbi_625.svg
-    :align: center
-
-    **Figure 4.3. ITU-R 625 line numbering**
-
-Remember the VBI image format depends on the selected video standard,
-therefore the application must choose a new standard or query the
-current standard first. Attempts to read or write data ahead of format
-negotiation, or after switching the video standard which may invalidate
-the negotiated VBI parameters, should be refused by the driver. A format
-change during active I/O is not permitted.
-
-
-Reading and writing VBI images
-==============================
-
-To assure synchronization with the field number and easier
-implementation, the smallest unit of data passed at a time is one frame,
-consisting of two fields of VBI images immediately following in memory.
-
-The total size of a frame computes as follows:
-
-
-.. code-block:: c
-
-    (count[0] + count[1]) * samples_per_line * sample size in bytes
-
-The sample size is most likely always one byte, applications must check
-the ``sample_format`` field though, to function properly with other
-drivers.
-
-A VBI device may support :ref:`read/write <rw>` and/or streaming
-(:ref:`memory mapping <mmap>` or :ref:`user pointer <userp>`) I/O.
-The latter bears the possibility of synchronizing video and VBI data by
-using buffer timestamps.
-
-Remember the :ref:`VIDIOC_STREAMON <VIDIOC_STREAMON>` ioctl and the
-first :ref:`read() <func-read>`, :ref:`write() <func-write>` and
-:ref:`select() <func-select>` call can be resource allocation
-points returning an ``EBUSY`` error code if the required hardware resources
-are temporarily unavailable, for example the device is already in use by
-another process.
-
-.. [#f1]
-   ASK: Amplitude-Shift Keying. A high signal level represents a '1'
-   bit, a low level a '0' bit.
-
-.. [#f2]
-   A few devices may be unable to sample VBI data at all but can extend
-   the video capture window to the VBI region.
-
-.. [#f3]
-   Most VBI services transmit on both fields, but some have different
-   semantics depending on the field number. These cannot be reliable
-   decoded or encoded when ``V4L2_VBI_UNSYNC`` is set.
-
-.. [#f4]
-   The valid values ar shown at :ref:`vbi-525` and :ref:`vbi-625`.
diff --git a/Documentation/media/uapi/v4l/dev-rds.rst b/Documentation/media/uapi/v4l/dev-rds.rst
deleted file mode 100644
index 64a724ef58f5..000000000000
--- a/Documentation/media/uapi/v4l/dev-rds.rst
+++ /dev/null
@@ -1,191 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _rds:
-
-*************
-RDS Interface
-*************
-
-The Radio Data System transmits supplementary information in binary
-format, for example the station name or travel information, on an
-inaudible audio subcarrier of a radio program. This interface is aimed
-at devices capable of receiving and/or transmitting RDS information.
-
-For more information see the core RDS standard :ref:`iec62106` and the
-RBDS standard :ref:`nrsc4`.
-
-.. note::
-
-   Note that the RBDS standard as is used in the USA is almost
-   identical to the RDS standard. Any RDS decoder/encoder can also handle
-   RBDS. Only some of the fields have slightly different meanings. See the
-   RBDS standard for more information.
-
-The RBDS standard also specifies support for MMBS (Modified Mobile
-Search). This is a proprietary format which seems to be discontinued.
-The RDS interface does not support this format. Should support for MMBS
-(or the so-called 'E blocks' in general) be needed, then please contact
-the linux-media mailing list:
-`https://linuxtv.org/lists.php <https://linuxtv.org/lists.php>`__.
-
-
-Querying Capabilities
-=====================
-
-Devices supporting the RDS capturing API set the
-``V4L2_CAP_RDS_CAPTURE`` flag in the ``capabilities`` field of struct
-:c:type:`v4l2_capability` returned by the
-:ref:`VIDIOC_QUERYCAP` ioctl. Any tuner that
-supports RDS will set the ``V4L2_TUNER_CAP_RDS`` flag in the
-``capability`` field of struct :c:type:`v4l2_tuner`. If the
-driver only passes RDS blocks without interpreting the data the
-``V4L2_TUNER_CAP_RDS_BLOCK_IO`` flag has to be set, see
-:ref:`Reading RDS data <reading-rds-data>`. For future use the flag
-``V4L2_TUNER_CAP_RDS_CONTROLS`` has also been defined. However, a driver
-for a radio tuner with this capability does not yet exist, so if you are
-planning to write such a driver you should discuss this on the
-linux-media mailing list:
-`https://linuxtv.org/lists.php <https://linuxtv.org/lists.php>`__.
-
-Whether an RDS signal is present can be detected by looking at the
-``rxsubchans`` field of struct :c:type:`v4l2_tuner`: the
-``V4L2_TUNER_SUB_RDS`` will be set if RDS data was detected.
-
-Devices supporting the RDS output API set the ``V4L2_CAP_RDS_OUTPUT``
-flag in the ``capabilities`` field of struct
-:c:type:`v4l2_capability` returned by the
-:ref:`VIDIOC_QUERYCAP` ioctl. Any modulator that
-supports RDS will set the ``V4L2_TUNER_CAP_RDS`` flag in the
-``capability`` field of struct
-:c:type:`v4l2_modulator`. In order to enable the RDS
-transmission one must set the ``V4L2_TUNER_SUB_RDS`` bit in the
-``txsubchans`` field of struct
-:c:type:`v4l2_modulator`. If the driver only passes RDS
-blocks without interpreting the data the ``V4L2_TUNER_CAP_RDS_BLOCK_IO``
-flag has to be set. If the tuner is capable of handling RDS entities
-like program identification codes and radio text, the flag
-``V4L2_TUNER_CAP_RDS_CONTROLS`` should be set, see
-:ref:`Writing RDS data <writing-rds-data>` and
-:ref:`FM Transmitter Control Reference <fm-tx-controls>`.
-
-
-.. _reading-rds-data:
-
-Reading RDS data
-================
-
-RDS data can be read from the radio device with the
-:ref:`read() <func-read>` function. The data is packed in groups of
-three bytes.
-
-
-.. _writing-rds-data:
-
-Writing RDS data
-================
-
-RDS data can be written to the radio device with the
-:ref:`write() <func-write>` function. The data is packed in groups of
-three bytes, as follows:
-
-
-RDS datastructures
-==================
-
-
-.. c:type:: v4l2_rds_data
-
-.. tabularcolumns:: |p{2.5cm}|p{2.5cm}|p{12.5cm}|
-
-.. flat-table:: struct v4l2_rds_data
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 5
-
-    * - __u8
-      - ``lsb``
-      - Least Significant Byte of RDS Block
-    * - __u8
-      - ``msb``
-      - Most Significant Byte of RDS Block
-    * - __u8
-      - ``block``
-      - Block description
-
-
-
-.. _v4l2-rds-block:
-
-.. tabularcolumns:: |p{2.9cm}|p{14.6cm}|
-
-.. flat-table:: Block description
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 5
-
-    * - Bits 0-2
-      - Block (aka offset) of the received data.
-    * - Bits 3-5
-      - Deprecated. Currently identical to bits 0-2. Do not use these
-	bits.
-    * - Bit 6
-      - Corrected bit. Indicates that an error was corrected for this data
-	block.
-    * - Bit 7
-      - Error bit. Indicates that an uncorrectable error occurred during
-	reception of this block.
-
-
-
-.. _v4l2-rds-block-codes:
-
-.. tabularcolumns:: |p{6.4cm}|p{2.0cm}|p{1.2cm}|p{7.9cm}|
-
-.. flat-table:: Block defines
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 1 5
-
-    * - V4L2_RDS_BLOCK_MSK
-      -
-      - 7
-      - Mask for bits 0-2 to get the block ID.
-    * - V4L2_RDS_BLOCK_A
-      -
-      - 0
-      - Block A.
-    * - V4L2_RDS_BLOCK_B
-      -
-      - 1
-      - Block B.
-    * - V4L2_RDS_BLOCK_C
-      -
-      - 2
-      - Block C.
-    * - V4L2_RDS_BLOCK_D
-      -
-      - 3
-      - Block D.
-    * - V4L2_RDS_BLOCK_C_ALT
-      -
-      - 4
-      - Block C'.
-    * - V4L2_RDS_BLOCK_INVALID
-      - read-only
-      - 7
-      - An invalid block.
-    * - V4L2_RDS_BLOCK_CORRECTED
-      - read-only
-      - 0x40
-      - A bit error was detected but corrected.
-    * - V4L2_RDS_BLOCK_ERROR
-      - read-only
-      - 0x80
-      - An uncorrectable error occurred.
diff --git a/Documentation/media/uapi/v4l/dev-sdr.rst b/Documentation/media/uapi/v4l/dev-sdr.rst
deleted file mode 100644
index 75595c58cb5b..000000000000
--- a/Documentation/media/uapi/v4l/dev-sdr.rst
+++ /dev/null
@@ -1,114 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _sdr:
-
-**************************************
-Software Defined Radio Interface (SDR)
-**************************************
-
-SDR is an abbreviation of Software Defined Radio, the radio device which
-uses application software for modulation or demodulation. This interface
-is intended for controlling and data streaming of such devices.
-
-SDR devices are accessed through character device special files named
-``/dev/swradio0`` to ``/dev/swradio255`` with major number 81 and
-dynamically allocated minor numbers 0 to 255.
-
-
-Querying Capabilities
-=====================
-
-Devices supporting the SDR receiver interface set the
-``V4L2_CAP_SDR_CAPTURE`` and ``V4L2_CAP_TUNER`` flag in the
-``capabilities`` field of struct
-:c:type:`v4l2_capability` returned by the
-:ref:`VIDIOC_QUERYCAP` ioctl. That flag means the
-device has an Analog to Digital Converter (ADC), which is a mandatory
-element for the SDR receiver.
-
-Devices supporting the SDR transmitter interface set the
-``V4L2_CAP_SDR_OUTPUT`` and ``V4L2_CAP_MODULATOR`` flag in the
-``capabilities`` field of struct
-:c:type:`v4l2_capability` returned by the
-:ref:`VIDIOC_QUERYCAP` ioctl. That flag means the
-device has an Digital to Analog Converter (DAC), which is a mandatory
-element for the SDR transmitter.
-
-At least one of the read/write, streaming or asynchronous I/O methods
-must be supported.
-
-
-Supplemental Functions
-======================
-
-SDR devices can support :ref:`controls <control>`, and must support
-the :ref:`tuner` ioctls. Tuner ioctls are used for setting the
-ADC/DAC sampling rate (sampling frequency) and the possible radio
-frequency (RF).
-
-The ``V4L2_TUNER_SDR`` tuner type is used for setting SDR device ADC/DAC
-frequency, and the ``V4L2_TUNER_RF`` tuner type is used for setting
-radio frequency. The tuner index of the RF tuner (if any) must always
-follow the SDR tuner index. Normally the SDR tuner is #0 and the RF
-tuner is #1.
-
-The :ref:`VIDIOC_S_HW_FREQ_SEEK` ioctl is
-not supported.
-
-
-Data Format Negotiation
-=======================
-
-The SDR device uses the :ref:`format` ioctls to select the
-capture and output format. Both the sampling resolution and the data
-streaming format are bound to that selectable format. In addition to the
-basic :ref:`format` ioctls, the
-:ref:`VIDIOC_ENUM_FMT` ioctl must be supported as
-well.
-
-To use the :ref:`format` ioctls applications set the ``type``
-field of a struct :c:type:`v4l2_format` to
-``V4L2_BUF_TYPE_SDR_CAPTURE`` or ``V4L2_BUF_TYPE_SDR_OUTPUT`` and use
-the struct :c:type:`v4l2_sdr_format` ``sdr`` member
-of the ``fmt`` union as needed per the desired operation. Currently
-there is two fields, ``pixelformat`` and ``buffersize``, of struct
-struct :c:type:`v4l2_sdr_format` which are used.
-Content of the ``pixelformat`` is V4L2 FourCC code of the data format.
-The ``buffersize`` field is maximum buffer size in bytes required for
-data transfer, set by the driver in order to inform application.
-
-
-.. c:type:: v4l2_sdr_format
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. flat-table:: struct v4l2_sdr_format
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``pixelformat``
-      - The data format or type of compression, set by the application.
-	This is a little endian
-	:ref:`four character code <v4l2-fourcc>`. V4L2 defines SDR
-	formats in :ref:`sdr-formats`.
-    * - __u32
-      - ``buffersize``
-      - Maximum size in bytes required for data. Value is set by the
-	driver.
-    * - __u8
-      - ``reserved[24]``
-      - This array is reserved for future extensions. Drivers and
-	applications must set it to zero.
-
-
-An SDR device may support :ref:`read/write <rw>` and/or streaming
-(:ref:`memory mapping <mmap>` or :ref:`user pointer <userp>`) I/O.
diff --git a/Documentation/media/uapi/v4l/dev-sliced-vbi.rst b/Documentation/media/uapi/v4l/dev-sliced-vbi.rst
deleted file mode 100644
index 7b2d38dd402a..000000000000
--- a/Documentation/media/uapi/v4l/dev-sliced-vbi.rst
+++ /dev/null
@@ -1,669 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _sliced:
-
-*************************
-Sliced VBI Data Interface
-*************************
-
-VBI stands for Vertical Blanking Interval, a gap in the sequence of
-lines of an analog video signal. During VBI no picture information is
-transmitted, allowing some time while the electron beam of a cathode ray
-tube TV returns to the top of the screen.
-
-Sliced VBI devices use hardware to demodulate data transmitted in the
-VBI. V4L2 drivers shall *not* do this by software, see also the
-:ref:`raw VBI interface <raw-vbi>`. The data is passed as short
-packets of fixed size, covering one scan line each. The number of
-packets per video frame is variable.
-
-Sliced VBI capture and output devices are accessed through the same
-character special files as raw VBI devices. When a driver supports both
-interfaces, the default function of a ``/dev/vbi`` device is *raw* VBI
-capturing or output, and the sliced VBI function is only available after
-calling the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl as defined
-below. Likewise a ``/dev/video`` device may support the sliced VBI API,
-however the default function here is video capturing or output.
-Different file descriptors must be used to pass raw and sliced VBI data
-simultaneously, if this is supported by the driver.
-
-
-Querying Capabilities
-=====================
-
-Devices supporting the sliced VBI capturing or output API set the
-``V4L2_CAP_SLICED_VBI_CAPTURE`` or ``V4L2_CAP_SLICED_VBI_OUTPUT`` flag
-respectively, in the ``capabilities`` field of struct
-:c:type:`v4l2_capability` returned by the
-:ref:`VIDIOC_QUERYCAP` ioctl. At least one of the
-read/write, streaming or asynchronous :ref:`I/O methods <io>` must be
-supported. Sliced VBI devices may have a tuner or modulator.
-
-
-Supplemental Functions
-======================
-
-Sliced VBI devices shall support :ref:`video input or output <video>`
-and :ref:`tuner or modulator <tuner>` ioctls if they have these
-capabilities, and they may support :ref:`control` ioctls.
-The :ref:`video standard <standard>` ioctls provide information vital
-to program a sliced VBI device, therefore must be supported.
-
-
-.. _sliced-vbi-format-negotitation:
-
-Sliced VBI Format Negotiation
-=============================
-
-To find out which data services are supported by the hardware
-applications can call the
-:ref:`VIDIOC_G_SLICED_VBI_CAP <VIDIOC_G_SLICED_VBI_CAP>` ioctl.
-All drivers implementing the sliced VBI interface must support this
-ioctl. The results may differ from those of the
-:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl when the number of VBI
-lines the hardware can capture or output per frame, or the number of
-services it can identify on a given line are limited. For example on PAL
-line 16 the hardware may be able to look for a VPS or Teletext signal,
-but not both at the same time.
-
-To determine the currently selected services applications set the
-``type`` field of struct :c:type:`v4l2_format` to
-``V4L2_BUF_TYPE_SLICED_VBI_CAPTURE`` or
-``V4L2_BUF_TYPE_SLICED_VBI_OUTPUT``, and the
-:ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` ioctl fills the ``fmt.sliced``
-member, a struct
-:c:type:`v4l2_sliced_vbi_format`.
-
-Applications can request different parameters by initializing or
-modifying the ``fmt.sliced`` member and calling the
-:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl with a pointer to the
-struct :c:type:`v4l2_format` structure.
-
-The sliced VBI API is more complicated than the raw VBI API because the
-hardware must be told which VBI service to expect on each scan line. Not
-all services may be supported by the hardware on all lines (this is
-especially true for VBI output where Teletext is often unsupported and
-other services can only be inserted in one specific line). In many
-cases, however, it is sufficient to just set the ``service_set`` field
-to the required services and let the driver fill the ``service_lines``
-array according to hardware capabilities. Only if more precise control
-is needed should the programmer set the ``service_lines`` array
-explicitly.
-
-The :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl modifies the parameters
-according to hardware capabilities. When the driver allocates resources
-at this point, it may return an ``EBUSY`` error code if the required
-resources are temporarily unavailable. Other resource allocation points
-which may return ``EBUSY`` can be the
-:ref:`VIDIOC_STREAMON` ioctl and the first
-:ref:`read() <func-read>`, :ref:`write() <func-write>` and
-:ref:`select() <func-select>` call.
-
-
-.. c:type:: v4l2_sliced_vbi_format
-
-struct v4l2_sliced_vbi_format
------------------------------
-
-.. raw:: latex
-
-    \begingroup
-    \scriptsize
-    \setlength{\tabcolsep}{2pt}
-
-.. tabularcolumns:: |p{.85cm}|p{3.3cm}|p{4.4cm}|p{4.4cm}|p{4.4cm}|
-
-.. cssclass:: longtable
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 3 2 2 2
-
-    * - __u32
-      - ``service_set``
-      - :cspan:`2`
-
-	If ``service_set`` is non-zero when passed with
-	:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` or
-	:ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>`, the ``service_lines``
-	array will be filled by the driver according to the services
-	specified in this field. For example, if ``service_set`` is
-	initialized with ``V4L2_SLICED_TELETEXT_B | V4L2_SLICED_WSS_625``,
-	a driver for the cx25840 video decoder sets lines 7-22 of both
-	fields [#f1]_ to ``V4L2_SLICED_TELETEXT_B`` and line 23 of the first
-	field to ``V4L2_SLICED_WSS_625``. If ``service_set`` is set to
-	zero, then the values of ``service_lines`` will be used instead.
-
-	On return the driver sets this field to the union of all elements
-	of the returned ``service_lines`` array. It may contain less
-	services than requested, perhaps just one, if the hardware cannot
-	handle more services simultaneously. It may be empty (zero) if
-	none of the requested services are supported by the hardware.
-    * - __u16
-      - ``service_lines``\ [2][24]
-      - :cspan:`2`
-
-	Applications initialize this array with sets of data services the
-	driver shall look for or insert on the respective scan line.
-	Subject to hardware capabilities drivers return the requested set,
-	a subset, which may be just a single service, or an empty set.
-	When the hardware cannot handle multiple services on the same line
-	the driver shall choose one. No assumptions can be made on which
-	service the driver chooses.
-
-	Data services are defined in :ref:`vbi-services2`. Array indices
-	map to ITU-R line numbers\ [#f2]_ as follows:
-    * -
-      -
-      - Element
-      - 525 line systems
-      - 625 line systems
-    * -
-      -
-      - ``service_lines``\ [0][1]
-      - 1
-      - 1
-    * -
-      -
-      - ``service_lines``\ [0][23]
-      - 23
-      - 23
-    * -
-      -
-      - ``service_lines``\ [1][1]
-      - 264
-      - 314
-    * -
-      -
-      - ``service_lines``\ [1][23]
-      - 286
-      - 336
-    * -
-      -
-      - :cspan:`2` Drivers must set ``service_lines`` [0][0] and
-	``service_lines``\ [1][0] to zero. The
-	``V4L2_VBI_ITU_525_F1_START``, ``V4L2_VBI_ITU_525_F2_START``,
-	``V4L2_VBI_ITU_625_F1_START`` and ``V4L2_VBI_ITU_625_F2_START``
-	defines give the start line numbers for each field for each 525 or
-	625 line format as a convenience. Don't forget that ITU line
-	numbering starts at 1, not 0.
-    * - __u32
-      - ``io_size``
-      - :cspan:`2` Maximum number of bytes passed by one
-	:ref:`read() <func-read>` or :ref:`write() <func-write>` call,
-	and the buffer size in bytes for the
-	:ref:`VIDIOC_QBUF` and
-	:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl. Drivers set this field
-	to the size of struct
-	:c:type:`v4l2_sliced_vbi_data` times the
-	number of non-zero elements in the returned ``service_lines``
-	array (that is the number of lines potentially carrying data).
-    * - __u32
-      - ``reserved``\ [2]
-      - :cspan:`2` This array is reserved for future extensions.
-
-	Applications and drivers must set it to zero.
-
-.. raw:: latex
-
-    \endgroup
-
-.. _vbi-services2:
-
-Sliced VBI services
--------------------
-
-.. raw:: latex
-
-    \scriptsize
-
-.. tabularcolumns:: |p{4.1cm}|p{1.1cm}|p{2.4cm}|p{2.0cm}|p{7.3cm}|
-
-.. flat-table::
-    :header-rows:  1
-    :stub-columns: 0
-    :widths:       2 1 1 2 2
-
-    * - Symbol
-      - Value
-      - Reference
-      - Lines, usually
-      - Payload
-    * - ``V4L2_SLICED_TELETEXT_B`` (Teletext System B)
-      - 0x0001
-      - :ref:`ets300706`,
-
-	:ref:`itu653`
-      - PAL/SECAM line 7-22, 320-335 (second field 7-22)
-      - Last 42 of the 45 byte Teletext packet, that is without clock
-	run-in and framing code, lsb first transmitted.
-    * - ``V4L2_SLICED_VPS``
-      - 0x0400
-      - :ref:`ets300231`
-      - PAL line 16
-      - Byte number 3 to 15 according to Figure 9 of ETS 300 231, lsb
-	first transmitted.
-    * - ``V4L2_SLICED_CAPTION_525``
-      - 0x1000
-      - :ref:`cea608`
-      - NTSC line 21, 284 (second field 21)
-      - Two bytes in transmission order, including parity bit, lsb first
-	transmitted.
-    * - ``V4L2_SLICED_WSS_625``
-      - 0x4000
-      - :ref:`itu1119`,
-
-	:ref:`en300294`
-      - PAL/SECAM line 23
-      -
-
-	::
-
-	    Byte         0                 1
-		  msb         lsb  msb           lsb
-	     Bit  7 6 5 4 3 2 1 0  x x 13 12 11 10 9
-    * - ``V4L2_SLICED_VBI_525``
-      - 0x1000
-      - :cspan:`2` Set of services applicable to 525 line systems.
-    * - ``V4L2_SLICED_VBI_625``
-      - 0x4401
-      - :cspan:`2` Set of services applicable to 625 line systems.
-
-.. raw:: latex
-
-    \normalsize
-
-
-Drivers may return an ``EINVAL`` error code when applications attempt to
-read or write data without prior format negotiation, after switching the
-video standard (which may invalidate the negotiated VBI parameters) and
-after switching the video input (which may change the video standard as
-a side effect). The :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl may
-return an ``EBUSY`` error code when applications attempt to change the
-format while i/o is in progress (between a
-:ref:`VIDIOC_STREAMON` and
-:ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` call, and after the first
-:ref:`read() <func-read>` or :ref:`write() <func-write>` call).
-
-
-Reading and writing sliced VBI data
-===================================
-
-A single :ref:`read() <func-read>` or :ref:`write() <func-write>`
-call must pass all data belonging to one video frame. That is an array
-of struct :c:type:`v4l2_sliced_vbi_data` structures with one or
-more elements and a total size not exceeding ``io_size`` bytes. Likewise
-in streaming I/O mode one buffer of ``io_size`` bytes must contain data
-of one video frame. The ``id`` of unused
-struct :c:type:`v4l2_sliced_vbi_data` elements must be zero.
-
-
-.. c:type:: v4l2_sliced_vbi_data
-
-struct v4l2_sliced_vbi_data
----------------------------
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - __u32
-      - ``id``
-      - A flag from :ref:`vbi-services` identifying the type of data in
-	this packet. Only a single bit must be set. When the ``id`` of a
-	captured packet is zero, the packet is empty and the contents of
-	other fields are undefined. Applications shall ignore empty
-	packets. When the ``id`` of a packet for output is zero the
-	contents of the ``data`` field are undefined and the driver must
-	no longer insert data on the requested ``field`` and ``line``.
-    * - __u32
-      - ``field``
-      - The video field number this data has been captured from, or shall
-	be inserted at. ``0`` for the first field, ``1`` for the second
-	field.
-    * - __u32
-      - ``line``
-      - The field (as opposed to frame) line number this data has been
-	captured from, or shall be inserted at. See :ref:`vbi-525` and
-	:ref:`vbi-625` for valid values. Sliced VBI capture devices can
-	set the line number of all packets to ``0`` if the hardware cannot
-	reliably identify scan lines. The field number must always be
-	valid.
-    * - __u32
-      - ``reserved``
-      - This field is reserved for future extensions. Applications and
-	drivers must set it to zero.
-    * - __u8
-      - ``data``\ [48]
-      - The packet payload. See :ref:`vbi-services` for the contents and
-	number of bytes passed for each data type. The contents of padding
-	bytes at the end of this array are undefined, drivers and
-	applications shall ignore them.
-
-
-Packets are always passed in ascending line number order, without
-duplicate line numbers. The :ref:`write() <func-write>` function and
-the :ref:`VIDIOC_QBUF` ioctl must return an ``EINVAL``
-error code when applications violate this rule. They must also return an
-EINVAL error code when applications pass an incorrect field or line
-number, or a combination of ``field``, ``line`` and ``id`` which has not
-been negotiated with the :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` or
-:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl. When the line numbers are
-unknown the driver must pass the packets in transmitted order. The
-driver can insert empty packets with ``id`` set to zero anywhere in the
-packet array.
-
-To assure synchronization and to distinguish from frame dropping, when a
-captured frame does not carry any of the requested data services drivers
-must pass one or more empty packets. When an application fails to pass
-VBI data in time for output, the driver must output the last VPS and WSS
-packet again, and disable the output of Closed Caption and Teletext
-data, or output data which is ignored by Closed Caption and Teletext
-decoders.
-
-A sliced VBI device may support :ref:`read/write <rw>` and/or
-streaming (:ref:`memory mapping <mmap>` and/or
-:ref:`user pointer <userp>`) I/O. The latter bears the possibility of
-synchronizing video and VBI data by using buffer timestamps.
-
-
-Sliced VBI Data in MPEG Streams
-===============================
-
-If a device can produce an MPEG output stream, it may be capable of
-providing
-:ref:`negotiated sliced VBI services <sliced-vbi-format-negotitation>`
-as data embedded in the MPEG stream. Users or applications control this
-sliced VBI data insertion with the
-:ref:`V4L2_CID_MPEG_STREAM_VBI_FMT <v4l2-mpeg-stream-vbi-fmt>`
-control.
-
-If the driver does not provide the
-:ref:`V4L2_CID_MPEG_STREAM_VBI_FMT <v4l2-mpeg-stream-vbi-fmt>`
-control, or only allows that control to be set to
-:ref:`V4L2_MPEG_STREAM_VBI_FMT_NONE <v4l2-mpeg-stream-vbi-fmt>`,
-then the device cannot embed sliced VBI data in the MPEG stream.
-
-The
-:ref:`V4L2_CID_MPEG_STREAM_VBI_FMT <v4l2-mpeg-stream-vbi-fmt>`
-control does not implicitly set the device driver to capture nor cease
-capturing sliced VBI data. The control only indicates to embed sliced
-VBI data in the MPEG stream, if an application has negotiated sliced VBI
-service be captured.
-
-It may also be the case that a device can embed sliced VBI data in only
-certain types of MPEG streams: for example in an MPEG-2 PS but not an
-MPEG-2 TS. In this situation, if sliced VBI data insertion is requested,
-the sliced VBI data will be embedded in MPEG stream types when
-supported, and silently omitted from MPEG stream types where sliced VBI
-data insertion is not supported by the device.
-
-The following subsections specify the format of the embedded sliced VBI
-data.
-
-
-MPEG Stream Embedded, Sliced VBI Data Format: NONE
---------------------------------------------------
-
-The
-:ref:`V4L2_MPEG_STREAM_VBI_FMT_NONE <v4l2-mpeg-stream-vbi-fmt>`
-embedded sliced VBI format shall be interpreted by drivers as a control
-to cease embedding sliced VBI data in MPEG streams. Neither the device
-nor driver shall insert "empty" embedded sliced VBI data packets in the
-MPEG stream when this format is set. No MPEG stream data structures are
-specified for this format.
-
-
-MPEG Stream Embedded, Sliced VBI Data Format: IVTV
---------------------------------------------------
-
-The
-:ref:`V4L2_MPEG_STREAM_VBI_FMT_IVTV <v4l2-mpeg-stream-vbi-fmt>`
-embedded sliced VBI format, when supported, indicates to the driver to
-embed up to 36 lines of sliced VBI data per frame in an MPEG-2 *Private
-Stream 1 PES* packet encapsulated in an MPEG-2 *Program Pack* in the
-MPEG stream.
-
-*Historical context*: This format specification originates from a
-custom, embedded, sliced VBI data format used by the ``ivtv`` driver.
-This format has already been informally specified in the kernel sources
-in the file ``Documentation/media/v4l-drivers/cx2341x.rst`` . The
-maximum size of the payload and other aspects of this format are driven
-by the CX23415 MPEG decoder's capabilities and limitations with respect
-to extracting, decoding, and displaying sliced VBI data embedded within
-an MPEG stream.
-
-This format's use is *not* exclusive to the ``ivtv`` driver *nor*
-exclusive to CX2341x devices, as the sliced VBI data packet insertion
-into the MPEG stream is implemented in driver software. At least the
-``cx18`` driver provides sliced VBI data insertion into an MPEG-2 PS in
-this format as well.
-
-The following definitions specify the payload of the MPEG-2 *Private
-Stream 1 PES* packets that contain sliced VBI data when
-:ref:`V4L2_MPEG_STREAM_VBI_FMT_IVTV <v4l2-mpeg-stream-vbi-fmt>`
-is set. (The MPEG-2 *Private Stream 1 PES* packet header and
-encapsulating MPEG-2 *Program Pack* header are not detailed here. Please
-refer to the MPEG-2 specifications for details on those packet headers.)
-
-The payload of the MPEG-2 *Private Stream 1 PES* packets that contain
-sliced VBI data is specified by struct
-:c:type:`v4l2_mpeg_vbi_fmt_ivtv`. The
-payload is variable length, depending on the actual number of lines of
-sliced VBI data present in a video frame. The payload may be padded at
-the end with unspecified fill bytes to align the end of the payload to a
-4-byte boundary. The payload shall never exceed 1552 bytes (2 fields
-with 18 lines/field with 43 bytes of data/line and a 4 byte magic
-number).
-
-
-.. c:type:: v4l2_mpeg_vbi_fmt_ivtv
-
-struct v4l2_mpeg_vbi_fmt_ivtv
------------------------------
-
-.. tabularcolumns:: |p{1.0cm}|p{3.8cm}|p{1.0cm}|p{11.2cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u8
-      - ``magic``\ [4]
-      - A "magic" constant from :ref:`v4l2-mpeg-vbi-fmt-ivtv-magic` that
-	indicates this is a valid sliced VBI data payload and also
-	indicates which member of the anonymous union, ``itv0`` or
-	``ITV0``, to use for the payload data.
-    * - union {
-      - (anonymous)
-    * - struct :c:type:`v4l2_mpeg_vbi_itv0`
-      - ``itv0``
-      - The primary form of the sliced VBI data payload that contains
-	anywhere from 1 to 35 lines of sliced VBI data. Line masks are
-	provided in this form of the payload indicating which VBI lines
-	are provided.
-    * - struct :ref:`v4l2_mpeg_vbi_ITV0 <v4l2-mpeg-vbi-itv0-1>`
-      - ``ITV0``
-      - An alternate form of the sliced VBI data payload used when 36
-	lines of sliced VBI data are present. No line masks are provided
-	in this form of the payload; all valid line mask bits are
-	implcitly set.
-    * - }
-      -
-
-.. _v4l2-mpeg-vbi-fmt-ivtv-magic:
-
-Magic Constants for struct v4l2_mpeg_vbi_fmt_ivtv magic field
--------------------------------------------------------------
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. flat-table::
-    :header-rows:  1
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - Defined Symbol
-      - Value
-      - Description
-    * - ``V4L2_MPEG_VBI_IVTV_MAGIC0``
-      - "itv0"
-      - Indicates the ``itv0`` member of the union in struct
-	:c:type:`v4l2_mpeg_vbi_fmt_ivtv` is
-	valid.
-    * - ``V4L2_MPEG_VBI_IVTV_MAGIC1``
-      - "ITV0"
-      - Indicates the ``ITV0`` member of the union in struct
-	:c:type:`v4l2_mpeg_vbi_fmt_ivtv` is
-	valid and that 36 lines of sliced VBI data are present.
-
-
-
-.. c:type:: v4l2_mpeg_vbi_itv0
-
-.. c:type:: v4l2_mpeg_vbi_ITV0
-
-structs v4l2_mpeg_vbi_itv0 and v4l2_mpeg_vbi_ITV0
--------------------------------------------------
-
-.. tabularcolumns:: |p{5.2cm}|p{2.4cm}|p{9.9cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __le32
-      - ``linemask``\ [2]
-      - Bitmasks indicating the VBI service lines present. These
-	``linemask`` values are stored in little endian byte order in the
-	MPEG stream. Some reference ``linemask`` bit positions with their
-	corresponding VBI line number and video field are given below.
-	b\ :sub:`0` indicates the least significant bit of a ``linemask``
-	value:
-
-
-
-	::
-
-	    linemask[0] b0:     line  6  first field
-	    linemask[0] b17:    line 23  first field
-	    linemask[0] b18:    line  6  second field
-	    linemask[0] b31:    line 19  second field
-	    linemask[1] b0:     line 20  second field
-	    linemask[1] b3:     line 23  second field
-	    linemask[1] b4-b31: unused and set to 0
-    * - struct
-	:c:type:`v4l2_mpeg_vbi_itv0_line`
-      - ``line``\ [35]
-      - This is a variable length array that holds from 1 to 35 lines of
-	sliced VBI data. The sliced VBI data lines present correspond to
-	the bits set in the ``linemask`` array, starting from b\ :sub:`0`
-	of ``linemask``\ [0] up through b\ :sub:`31` of ``linemask``\ [0],
-	and from b\ :sub:`0` of ``linemask``\ [1] up through b\ :sub:`3` of
-	``linemask``\ [1]. ``line``\ [0] corresponds to the first bit
-	found set in the ``linemask`` array, ``line``\ [1] corresponds to
-	the second bit found set in the ``linemask`` array, etc. If no
-	``linemask`` array bits are set, then ``line``\ [0] may contain
-	one line of unspecified data that should be ignored by
-	applications.
-
-
-
-.. _v4l2-mpeg-vbi-itv0-1:
-
-struct v4l2_mpeg_vbi_ITV0
--------------------------
-
-.. tabularcolumns:: |p{5.2cm}|p{2.4cm}|p{9.9cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - struct
-	:c:type:`v4l2_mpeg_vbi_itv0_line`
-      - ``line``\ [36]
-      - A fixed length array of 36 lines of sliced VBI data. ``line``\ [0]
-	through ``line``\ [17] correspond to lines 6 through 23 of the
-	first field. ``line``\ [18] through ``line``\ [35] corresponds to
-	lines 6 through 23 of the second field.
-
-
-
-.. c:type:: v4l2_mpeg_vbi_itv0_line
-
-struct v4l2_mpeg_vbi_itv0_line
-------------------------------
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u8
-      - ``id``
-      - A line identifier value from
-	:ref:`ITV0-Line-Identifier-Constants` that indicates the type of
-	sliced VBI data stored on this line.
-    * - __u8
-      - ``data``\ [42]
-      - The sliced VBI data for the line.
-
-
-
-.. _ITV0-Line-Identifier-Constants:
-
-Line Identifiers for struct v4l2_mpeg_vbi_itv0_line id field
-------------------------------------------------------------
-
-.. tabularcolumns:: |p{7.0cm}|p{1.8cm}|p{8.7cm}|
-
-.. flat-table::
-    :header-rows:  1
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - Defined Symbol
-      - Value
-      - Description
-    * - ``V4L2_MPEG_VBI_IVTV_TELETEXT_B``
-      - 1
-      - Refer to :ref:`Sliced VBI services <vbi-services2>` for a
-	description of the line payload.
-    * - ``V4L2_MPEG_VBI_IVTV_CAPTION_525``
-      - 4
-      - Refer to :ref:`Sliced VBI services <vbi-services2>` for a
-	description of the line payload.
-    * - ``V4L2_MPEG_VBI_IVTV_WSS_625``
-      - 5
-      - Refer to :ref:`Sliced VBI services <vbi-services2>` for a
-	description of the line payload.
-    * - ``V4L2_MPEG_VBI_IVTV_VPS``
-      - 7
-      - Refer to :ref:`Sliced VBI services <vbi-services2>` for a
-	description of the line payload.
-
-
-
-.. [#f1]
-   According to :ref:`ETS 300 706 <ets300706>` lines 6-22 of the first
-   field and lines 5-22 of the second field may carry Teletext data.
-
-.. [#f2]
-   See also :ref:`vbi-525` and :ref:`vbi-625`.
diff --git a/Documentation/media/uapi/v4l/dev-stateless-decoder.rst b/Documentation/media/uapi/v4l/dev-stateless-decoder.rst
deleted file mode 100644
index 4a26646eeec5..000000000000
--- a/Documentation/media/uapi/v4l/dev-stateless-decoder.rst
+++ /dev/null
@@ -1,424 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-.. _stateless_decoder:
-
-**************************************************
-Memory-to-memory Stateless Video Decoder Interface
-**************************************************
-
-A stateless decoder is a decoder that works without retaining any kind of state
-between processed frames. This means that each frame is decoded independently
-of any previous and future frames, and that the client is responsible for
-maintaining the decoding state and providing it to the decoder with each
-decoding request. This is in contrast to the stateful video decoder interface,
-where the hardware and driver maintain the decoding state and all the client
-has to do is to provide the raw encoded stream and dequeue decoded frames in
-display order.
-
-This section describes how user-space ("the client") is expected to communicate
-with stateless decoders in order to successfully decode an encoded stream.
-Compared to stateful codecs, the decoder/client sequence is simpler, but the
-cost of this simplicity is extra complexity in the client which is responsible
-for maintaining a consistent decoding state.
-
-Stateless decoders make use of the :ref:`media-request-api`. A stateless
-decoder must expose the ``V4L2_BUF_CAP_SUPPORTS_REQUESTS`` capability on its
-``OUTPUT`` queue when :c:func:`VIDIOC_REQBUFS` or :c:func:`VIDIOC_CREATE_BUFS`
-are invoked.
-
-Depending on the encoded formats supported by the decoder, a single decoded
-frame may be the result of several decode requests (for instance, H.264 streams
-with multiple slices per frame). Decoders that support such formats must also
-expose the ``V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF`` capability on their
-``OUTPUT`` queue.
-
-Querying capabilities
-=====================
-
-1. To enumerate the set of coded formats supported by the decoder, the client
-   calls :c:func:`VIDIOC_ENUM_FMT` on the ``OUTPUT`` queue.
-
-   * The driver must always return the full set of supported ``OUTPUT`` formats,
-     irrespective of the format currently set on the ``CAPTURE`` queue.
-
-   * Simultaneously, the driver must restrain the set of values returned by
-     codec-specific capability controls (such as H.264 profiles) to the set
-     actually supported by the hardware.
-
-2. To enumerate the set of supported raw formats, the client calls
-   :c:func:`VIDIOC_ENUM_FMT` on the ``CAPTURE`` queue.
-
-   * The driver must return only the formats supported for the format currently
-     active on the ``OUTPUT`` queue.
-
-   * Depending on the currently set ``OUTPUT`` format, the set of supported raw
-     formats may depend on the value of some codec-dependent controls.
-     The client is responsible for making sure that these controls are set
-     before querying the ``CAPTURE`` queue. Failure to do so will result in the
-     default values for these controls being used, and a returned set of formats
-     that may not be usable for the media the client is trying to decode.
-
-3. The client may use :c:func:`VIDIOC_ENUM_FRAMESIZES` to detect supported
-   resolutions for a given format, passing desired pixel format in
-   :c:type:`v4l2_frmsizeenum`'s ``pixel_format``.
-
-4. Supported profiles and levels for the current ``OUTPUT`` format, if
-   applicable, may be queried using their respective controls via
-   :c:func:`VIDIOC_QUERYCTRL`.
-
-Initialization
-==============
-
-1. Set the coded format on the ``OUTPUT`` queue via :c:func:`VIDIOC_S_FMT`.
-
-   * **Required fields:**
-
-     ``type``
-         a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.
-
-     ``pixelformat``
-         a coded pixel format.
-
-     ``width``, ``height``
-         coded width and height parsed from the stream.
-
-     other fields
-         follow standard semantics.
-
-   .. note::
-
-      Changing the ``OUTPUT`` format may change the currently set ``CAPTURE``
-      format. The driver will derive a new ``CAPTURE`` format from the
-      ``OUTPUT`` format being set, including resolution, colorimetry
-      parameters, etc. If the client needs a specific ``CAPTURE`` format,
-      it must adjust it afterwards.
-
-2. Call :c:func:`VIDIOC_S_EXT_CTRLS` to set all the controls (parsed headers,
-   etc.) required by the ``OUTPUT`` format to enumerate the ``CAPTURE`` formats.
-
-3. Call :c:func:`VIDIOC_G_FMT` for ``CAPTURE`` queue to get the format for the
-   destination buffers parsed/decoded from the bytestream.
-
-   * **Required fields:**
-
-     ``type``
-         a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
-
-   * **Returned fields:**
-
-     ``width``, ``height``
-         frame buffer resolution for the decoded frames.
-
-     ``pixelformat``
-         pixel format for decoded frames.
-
-     ``num_planes`` (for _MPLANE ``type`` only)
-         number of planes for pixelformat.
-
-     ``sizeimage``, ``bytesperline``
-         as per standard semantics; matching frame buffer format.
-
-   .. note::
-
-      The value of ``pixelformat`` may be any pixel format supported for the
-      ``OUTPUT`` format, based on the hardware capabilities. It is suggested
-      that the driver chooses the preferred/optimal format for the current
-      configuration. For example, a YUV format may be preferred over an RGB
-      format, if an additional conversion step would be required for RGB.
-
-4. *[optional]* Enumerate ``CAPTURE`` formats via :c:func:`VIDIOC_ENUM_FMT` on
-   the ``CAPTURE`` queue. The client may use this ioctl to discover which
-   alternative raw formats are supported for the current ``OUTPUT`` format and
-   select one of them via :c:func:`VIDIOC_S_FMT`.
-
-   .. note::
-
-      The driver will return only formats supported for the currently selected
-      ``OUTPUT`` format and currently set controls, even if more formats may be
-      supported by the decoder in general.
-
-      For example, a decoder may support YUV and RGB formats for
-      resolutions 1920x1088 and lower, but only YUV for higher resolutions (due
-      to hardware limitations). After setting a resolution of 1920x1088 or lower
-      as the ``OUTPUT`` format, :c:func:`VIDIOC_ENUM_FMT` may return a set of
-      YUV and RGB pixel formats, but after setting a resolution higher than
-      1920x1088, the driver will not return RGB pixel formats, since they are
-      unsupported for this resolution.
-
-5. *[optional]* Choose a different ``CAPTURE`` format than suggested via
-   :c:func:`VIDIOC_S_FMT` on ``CAPTURE`` queue. It is possible for the client to
-   choose a different format than selected/suggested by the driver in
-   :c:func:`VIDIOC_G_FMT`.
-
-    * **Required fields:**
-
-      ``type``
-          a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
-
-      ``pixelformat``
-          a raw pixel format.
-
-      ``width``, ``height``
-         frame buffer resolution of the decoded stream; typically unchanged from
-         what was returned with :c:func:`VIDIOC_G_FMT`, but it may be different
-         if the hardware supports composition and/or scaling.
-
-   After performing this step, the client must perform step 3 again in order
-   to obtain up-to-date information about the buffers size and layout.
-
-6. Allocate source (bytestream) buffers via :c:func:`VIDIOC_REQBUFS` on
-   ``OUTPUT`` queue.
-
-    * **Required fields:**
-
-      ``count``
-          requested number of buffers to allocate; greater than zero.
-
-      ``type``
-          a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.
-
-      ``memory``
-          follows standard semantics.
-
-    * **Return fields:**
-
-      ``count``
-          actual number of buffers allocated.
-
-    * If required, the driver will adjust ``count`` to be equal or bigger to the
-      minimum of required number of ``OUTPUT`` buffers for the given format and
-      requested count. The client must check this value after the ioctl returns
-      to get the actual number of buffers allocated.
-
-7. Allocate destination (raw format) buffers via :c:func:`VIDIOC_REQBUFS` on the
-   ``CAPTURE`` queue.
-
-    * **Required fields:**
-
-      ``count``
-          requested number of buffers to allocate; greater than zero. The client
-          is responsible for deducing the minimum number of buffers required
-          for the stream to be properly decoded (taking e.g. reference frames
-          into account) and pass an equal or bigger number.
-
-      ``type``
-          a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
-
-      ``memory``
-          follows standard semantics. ``V4L2_MEMORY_USERPTR`` is not supported
-          for ``CAPTURE`` buffers.
-
-    * **Return fields:**
-
-      ``count``
-          adjusted to allocated number of buffers, in case the codec requires
-          more buffers than requested.
-
-    * The driver must adjust count to the minimum of required number of
-      ``CAPTURE`` buffers for the current format, stream configuration and
-      requested count. The client must check this value after the ioctl
-      returns to get the number of buffers allocated.
-
-8. Allocate requests (likely one per ``OUTPUT`` buffer) via
-    :c:func:`MEDIA_IOC_REQUEST_ALLOC` on the media device.
-
-9. Start streaming on both ``OUTPUT`` and ``CAPTURE`` queues via
-    :c:func:`VIDIOC_STREAMON`.
-
-Decoding
-========
-
-For each frame, the client is responsible for submitting at least one request to
-which the following is attached:
-
-* The amount of encoded data expected by the codec for its current
-  configuration, as a buffer submitted to the ``OUTPUT`` queue. Typically, this
-  corresponds to one frame worth of encoded data, but some formats may allow (or
-  require) different amounts per unit.
-* All the metadata needed to decode the submitted encoded data, in the form of
-  controls relevant to the format being decoded.
-
-The amount of data and contents of the source ``OUTPUT`` buffer, as well as the
-controls that must be set on the request, depend on the active coded pixel
-format and might be affected by codec-specific extended controls, as stated in
-documentation of each format.
-
-If there is a possibility that the decoded frame will require one or more
-decode requests after the current one in order to be produced, then the client
-must set the ``V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF`` flag on the ``OUTPUT``
-buffer. This will result in the (potentially partially) decoded ``CAPTURE``
-buffer not being made available for dequeueing, and reused for the next decode
-request if the timestamp of the next ``OUTPUT`` buffer has not changed.
-
-A typical frame would thus be decoded using the following sequence:
-
-1. Queue an ``OUTPUT`` buffer containing one unit of encoded bytestream data for
-   the decoding request, using :c:func:`VIDIOC_QBUF`.
-
-    * **Required fields:**
-
-      ``index``
-          index of the buffer being queued.
-
-      ``type``
-          type of the buffer.
-
-      ``bytesused``
-          number of bytes taken by the encoded data frame in the buffer.
-
-      ``flags``
-          the ``V4L2_BUF_FLAG_REQUEST_FD`` flag must be set. Additionally, if
-          we are not sure that the current decode request is the last one needed
-          to produce a fully decoded frame, then
-          ``V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF`` must also be set.
-
-      ``request_fd``
-          must be set to the file descriptor of the decoding request.
-
-      ``timestamp``
-          must be set to a unique value per frame. This value will be propagated
-          into the decoded frame's buffer and can also be used to use this frame
-          as the reference of another. If using multiple decode requests per
-          frame, then the timestamps of all the ``OUTPUT`` buffers for a given
-          frame must be identical. If the timestamp changes, then the currently
-          held ``CAPTURE`` buffer will be made available for dequeuing and the
-          current request will work on a new ``CAPTURE`` buffer.
-
-2. Set the codec-specific controls for the decoding request, using
-   :c:func:`VIDIOC_S_EXT_CTRLS`.
-
-    * **Required fields:**
-
-      ``which``
-          must be ``V4L2_CTRL_WHICH_REQUEST_VAL``.
-
-      ``request_fd``
-          must be set to the file descriptor of the decoding request.
-
-      other fields
-          other fields are set as usual when setting controls. The ``controls``
-          array must contain all the codec-specific controls required to decode
-          a frame.
-
-   .. note::
-
-      It is possible to specify the controls in different invocations of
-      :c:func:`VIDIOC_S_EXT_CTRLS`, or to overwrite a previously set control, as
-      long as ``request_fd`` and ``which`` are properly set. The controls state
-      at the moment of request submission is the one that will be considered.
-
-   .. note::
-
-      The order in which steps 1 and 2 take place is interchangeable.
-
-3. Submit the request by invoking :c:func:`MEDIA_REQUEST_IOC_QUEUE` on the
-   request FD.
-
-    If the request is submitted without an ``OUTPUT`` buffer, or if some of the
-    required controls are missing from the request, then
-    :c:func:`MEDIA_REQUEST_IOC_QUEUE` will return ``-ENOENT``. If more than one
-    ``OUTPUT`` buffer is queued, then it will return ``-EINVAL``.
-    :c:func:`MEDIA_REQUEST_IOC_QUEUE` returning non-zero means that no
-    ``CAPTURE`` buffer will be produced for this request.
-
-``CAPTURE`` buffers must not be part of the request, and are queued
-independently. They are returned in decode order (i.e. the same order as coded
-frames were submitted to the ``OUTPUT`` queue).
-
-Runtime decoding errors are signaled by the dequeued ``CAPTURE`` buffers
-carrying the ``V4L2_BUF_FLAG_ERROR`` flag. If a decoded reference frame has an
-error, then all following decoded frames that refer to it also have the
-``V4L2_BUF_FLAG_ERROR`` flag set, although the decoder will still try to
-produce (likely corrupted) frames.
-
-Buffer management while decoding
-================================
-Contrary to stateful decoders, a stateless decoder does not perform any kind of
-buffer management: it only guarantees that dequeued ``CAPTURE`` buffers can be
-used by the client for as long as they are not queued again. "Used" here
-encompasses using the buffer for compositing or display.
-
-A dequeued capture buffer can also be used as the reference frame of another
-buffer.
-
-A frame is specified as reference by converting its timestamp into nanoseconds,
-and storing it into the relevant member of a codec-dependent control structure.
-The :c:func:`v4l2_timeval_to_ns` function must be used to perform that
-conversion. The timestamp of a frame can be used to reference it as soon as all
-its units of encoded data are successfully submitted to the ``OUTPUT`` queue.
-
-A decoded buffer containing a reference frame must not be reused as a decoding
-target until all the frames referencing it have been decoded. The safest way to
-achieve this is to refrain from queueing a reference buffer until all the
-decoded frames referencing it have been dequeued. However, if the driver can
-guarantee that buffers queued to the ``CAPTURE`` queue are processed in queued
-order, then user-space can take advantage of this guarantee and queue a
-reference buffer when the following conditions are met:
-
-1. All the requests for frames affected by the reference frame have been
-   queued, and
-
-2. A sufficient number of ``CAPTURE`` buffers to cover all the decoded
-   referencing frames have been queued.
-
-When queuing a decoding request, the driver will increase the reference count of
-all the resources associated with reference frames. This means that the client
-can e.g. close the DMABUF file descriptors of reference frame buffers if it
-won't need them afterwards.
-
-Seeking
-=======
-In order to seek, the client just needs to submit requests using input buffers
-corresponding to the new stream position. It must however be aware that
-resolution may have changed and follow the dynamic resolution change sequence in
-that case. Also depending on the codec used, picture parameters (e.g. SPS/PPS
-for H.264) may have changed and the client is responsible for making sure that a
-valid state is sent to the decoder.
-
-The client is then free to ignore any returned ``CAPTURE`` buffer that comes
-from the pre-seek position.
-
-Pausing
-=======
-
-In order to pause, the client can just cease queuing buffers onto the ``OUTPUT``
-queue. Without source bytestream data, there is no data to process and the codec
-will remain idle.
-
-Dynamic resolution change
-=========================
-
-If the client detects a resolution change in the stream, it will need to perform
-the initialization sequence again with the new resolution:
-
-1. If the last submitted request resulted in a ``CAPTURE`` buffer being
-   held by the use of the ``V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF`` flag, then the
-   last frame is not available on the ``CAPTURE`` queue. In this case, a
-   ``V4L2_DEC_CMD_FLUSH`` command shall be sent. This will make the driver
-   dequeue the held ``CAPTURE`` buffer.
-
-2. Wait until all submitted requests have completed and dequeue the
-   corresponding output buffers.
-
-3. Call :c:func:`VIDIOC_STREAMOFF` on both the ``OUTPUT`` and ``CAPTURE``
-   queues.
-
-4. Free all ``CAPTURE`` buffers by calling :c:func:`VIDIOC_REQBUFS` on the
-   ``CAPTURE`` queue with a buffer count of zero.
-
-5. Perform the initialization sequence again (minus the allocation of
-   ``OUTPUT`` buffers), with the new resolution set on the ``OUTPUT`` queue.
-   Note that due to resolution constraints, a different format may need to be
-   picked on the ``CAPTURE`` queue.
-
-Drain
-=====
-
-If the last submitted request resulted in a ``CAPTURE`` buffer being
-held by the use of the ``V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF`` flag, then the
-last frame is not available on the ``CAPTURE`` queue. In this case, a
-``V4L2_DEC_CMD_FLUSH`` command shall be sent. This will make the driver
-dequeue the held ``CAPTURE`` buffer.
-
-After that, in order to drain the stream on a stateless decoder, the client
-just needs to wait until all the submitted requests are completed.
diff --git a/Documentation/media/uapi/v4l/dev-subdev.rst b/Documentation/media/uapi/v4l/dev-subdev.rst
deleted file mode 100644
index 029bb2d9928a..000000000000
--- a/Documentation/media/uapi/v4l/dev-subdev.rst
+++ /dev/null
@@ -1,503 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _subdev:
-
-********************
-Sub-device Interface
-********************
-
-The complex nature of V4L2 devices, where hardware is often made of
-several integrated circuits that need to interact with each other in a
-controlled way, leads to complex V4L2 drivers. The drivers usually
-reflect the hardware model in software, and model the different hardware
-components as software blocks called sub-devices.
-
-V4L2 sub-devices are usually kernel-only objects. If the V4L2 driver
-implements the media device API, they will automatically inherit from
-media entities. Applications will be able to enumerate the sub-devices
-and discover the hardware topology using the media entities, pads and
-links enumeration API.
-
-In addition to make sub-devices discoverable, drivers can also choose to
-make them directly configurable by applications. When both the
-sub-device driver and the V4L2 device driver support this, sub-devices
-will feature a character device node on which ioctls can be called to
-
--  query, read and write sub-devices controls
-
--  subscribe and unsubscribe to events and retrieve them
-
--  negotiate image formats on individual pads
-
-Sub-device character device nodes, conventionally named
-``/dev/v4l-subdev*``, use major number 81.
-
-
-Controls
-========
-
-Most V4L2 controls are implemented by sub-device hardware. Drivers
-usually merge all controls and expose them through video device nodes.
-Applications can control all sub-devices through a single interface.
-
-Complex devices sometimes implement the same control in different pieces
-of hardware. This situation is common in embedded platforms, where both
-sensors and image processing hardware implement identical functions,
-such as contrast adjustment, white balance or faulty pixels correction.
-As the V4L2 controls API doesn't support several identical controls in a
-single device, all but one of the identical controls are hidden.
-
-Applications can access those hidden controls through the sub-device
-node with the V4L2 control API described in :ref:`control`. The ioctls
-behave identically as when issued on V4L2 device nodes, with the
-exception that they deal only with controls implemented in the
-sub-device.
-
-Depending on the driver, those controls might also be exposed through
-one (or several) V4L2 device nodes.
-
-
-Events
-======
-
-V4L2 sub-devices can notify applications of events as described in
-:ref:`event`. The API behaves identically as when used on V4L2 device
-nodes, with the exception that it only deals with events generated by
-the sub-device. Depending on the driver, those events might also be
-reported on one (or several) V4L2 device nodes.
-
-
-.. _pad-level-formats:
-
-Pad-level Formats
-=================
-
-.. warning::
-
-    Pad-level formats are only applicable to very complex devices that
-    need to expose low-level format configuration to user space. Generic
-    V4L2 applications do *not* need to use the API described in this
-    section.
-
-.. note::
-
-    For the purpose of this section, the term *format* means the
-    combination of media bus data format, frame width and frame height.
-
-Image formats are typically negotiated on video capture and output
-devices using the format and
-:ref:`selection <VIDIOC_SUBDEV_G_SELECTION>` ioctls. The driver is
-responsible for configuring every block in the video pipeline according
-to the requested format at the pipeline input and/or output.
-
-For complex devices, such as often found in embedded systems, identical
-image sizes at the output of a pipeline can be achieved using different
-hardware configurations. One such example is shown on
-:ref:`pipeline-scaling`, where image scaling can be performed on both
-the video sensor and the host image processing hardware.
-
-
-.. _pipeline-scaling:
-
-.. kernel-figure:: pipeline.dot
-    :alt:   pipeline.dot
-    :align: center
-
-    Image Format Negotiation on Pipelines
-
-    High quality and high speed pipeline configuration
-
-
-
-The sensor scaler is usually of less quality than the host scaler, but
-scaling on the sensor is required to achieve higher frame rates.
-Depending on the use case (quality vs. speed), the pipeline must be
-configured differently. Applications need to configure the formats at
-every point in the pipeline explicitly.
-
-Drivers that implement the :ref:`media API <media-controller-intro>`
-can expose pad-level image format configuration to applications. When
-they do, applications can use the
-:ref:`VIDIOC_SUBDEV_G_FMT <VIDIOC_SUBDEV_G_FMT>` and
-:ref:`VIDIOC_SUBDEV_S_FMT <VIDIOC_SUBDEV_G_FMT>` ioctls. to
-negotiate formats on a per-pad basis.
-
-Applications are responsible for configuring coherent parameters on the
-whole pipeline and making sure that connected pads have compatible
-formats. The pipeline is checked for formats mismatch at
-:ref:`VIDIOC_STREAMON <VIDIOC_STREAMON>` time, and an ``EPIPE`` error
-code is then returned if the configuration is invalid.
-
-Pad-level image format configuration support can be tested by calling
-the :ref:`VIDIOC_SUBDEV_G_FMT` ioctl on pad
-0. If the driver returns an ``EINVAL`` error code pad-level format
-configuration is not supported by the sub-device.
-
-
-Format Negotiation
-------------------
-
-Acceptable formats on pads can (and usually do) depend on a number of
-external parameters, such as formats on other pads, active links, or
-even controls. Finding a combination of formats on all pads in a video
-pipeline, acceptable to both application and driver, can't rely on
-formats enumeration only. A format negotiation mechanism is required.
-
-Central to the format negotiation mechanism are the get/set format
-operations. When called with the ``which`` argument set to
-:ref:`V4L2_SUBDEV_FORMAT_TRY <VIDIOC_SUBDEV_G_FMT>`, the
-:ref:`VIDIOC_SUBDEV_G_FMT <VIDIOC_SUBDEV_G_FMT>` and
-:ref:`VIDIOC_SUBDEV_S_FMT <VIDIOC_SUBDEV_G_FMT>` ioctls operate on
-a set of formats parameters that are not connected to the hardware
-configuration. Modifying those 'try' formats leaves the device state
-untouched (this applies to both the software state stored in the driver
-and the hardware state stored in the device itself).
-
-While not kept as part of the device state, try formats are stored in
-the sub-device file handles. A
-:ref:`VIDIOC_SUBDEV_G_FMT <VIDIOC_SUBDEV_G_FMT>` call will return
-the last try format set *on the same sub-device file handle*. Several
-applications querying the same sub-device at the same time will thus not
-interact with each other.
-
-To find out whether a particular format is supported by the device,
-applications use the
-:ref:`VIDIOC_SUBDEV_S_FMT <VIDIOC_SUBDEV_G_FMT>` ioctl. Drivers
-verify and, if needed, change the requested ``format`` based on device
-requirements and return the possibly modified value. Applications can
-then choose to try a different format or accept the returned value and
-continue.
-
-Formats returned by the driver during a negotiation iteration are
-guaranteed to be supported by the device. In particular, drivers
-guarantee that a returned format will not be further changed if passed
-to an :ref:`VIDIOC_SUBDEV_S_FMT <VIDIOC_SUBDEV_G_FMT>` call as-is
-(as long as external parameters, such as formats on other pads or links'
-configuration are not changed).
-
-Drivers automatically propagate formats inside sub-devices. When a try
-or active format is set on a pad, corresponding formats on other pads of
-the same sub-device can be modified by the driver. Drivers are free to
-modify formats as required by the device. However, they should comply
-with the following rules when possible:
-
--  Formats should be propagated from sink pads to source pads. Modifying
-   a format on a source pad should not modify the format on any sink
-   pad.
-
--  Sub-devices that scale frames using variable scaling factors should
-   reset the scale factors to default values when sink pads formats are
-   modified. If the 1:1 scaling ratio is supported, this means that
-   source pads formats should be reset to the sink pads formats.
-
-Formats are not propagated across links, as that would involve
-propagating them from one sub-device file handle to another.
-Applications must then take care to configure both ends of every link
-explicitly with compatible formats. Identical formats on the two ends of
-a link are guaranteed to be compatible. Drivers are free to accept
-different formats matching device requirements as being compatible.
-
-:ref:`sample-pipeline-config` shows a sample configuration sequence
-for the pipeline described in :ref:`pipeline-scaling` (table columns
-list entity names and pad numbers).
-
-
-.. raw:: latex
-
-    \scriptsize
-
-.. tabularcolumns:: |p{2.0cm}|p{2.3cm}|p{2.3cm}|p{2.3cm}|p{2.3cm}|p{2.3cm}|p{2.3cm}|
-
-.. _sample-pipeline-config:
-
-.. flat-table:: Sample Pipeline Configuration
-    :header-rows:  1
-    :stub-columns: 0
-    :widths: 5 5 5 5 5 5 5
-
-    * -
-      - Sensor/0
-
-        format
-      - Frontend/0
-
-        format
-      - Frontend/1
-
-        format
-      - Scaler/0
-
-        format
-      - Scaler/0
-
-        compose selection rectangle
-      - Scaler/1
-
-        format
-    * - Initial state
-      - 2048x1536
-
-        SGRBG8_1X8
-      - (default)
-      - (default)
-      - (default)
-      - (default)
-      - (default)
-    * - Configure frontend sink format
-      - 2048x1536
-
-        SGRBG8_1X8
-      - *2048x1536*
-
-        *SGRBG8_1X8*
-      - *2046x1534*
-
-        *SGRBG8_1X8*
-      - (default)
-      - (default)
-      - (default)
-    * - Configure scaler sink format
-      - 2048x1536
-
-        SGRBG8_1X8
-      - 2048x1536
-
-        SGRBG8_1X8
-      - 2046x1534
-
-        SGRBG8_1X8
-      - *2046x1534*
-
-        *SGRBG8_1X8*
-      - *0,0/2046x1534*
-      - *2046x1534*
-
-        *SGRBG8_1X8*
-    * - Configure scaler sink compose selection
-      - 2048x1536
-
-        SGRBG8_1X8
-      - 2048x1536
-
-        SGRBG8_1X8
-      - 2046x1534
-
-        SGRBG8_1X8
-      - 2046x1534
-
-        SGRBG8_1X8
-      - *0,0/1280x960*
-      - *1280x960*
-
-        *SGRBG8_1X8*
-
-.. raw:: latex
-
-    \normalsize
-
-1. Initial state. The sensor source pad format is set to its native 3MP
-   size and V4L2_MBUS_FMT_SGRBG8_1X8 media bus code. Formats on the
-   host frontend and scaler sink and source pads have the default
-   values, as well as the compose rectangle on the scaler's sink pad.
-
-2. The application configures the frontend sink pad format's size to
-   2048x1536 and its media bus code to V4L2_MBUS_FMT_SGRBG_1X8. The
-   driver propagates the format to the frontend source pad.
-
-3. The application configures the scaler sink pad format's size to
-   2046x1534 and the media bus code to V4L2_MBUS_FMT_SGRBG_1X8 to
-   match the frontend source size and media bus code. The media bus code
-   on the sink pad is set to V4L2_MBUS_FMT_SGRBG_1X8. The driver
-   propagates the size to the compose selection rectangle on the
-   scaler's sink pad, and the format to the scaler source pad.
-
-4. The application configures the size of the compose selection
-   rectangle of the scaler's sink pad 1280x960. The driver propagates
-   the size to the scaler's source pad format.
-
-When satisfied with the try results, applications can set the active
-formats by setting the ``which`` argument to
-``V4L2_SUBDEV_FORMAT_ACTIVE``. Active formats are changed exactly as try
-formats by drivers. To avoid modifying the hardware state during format
-negotiation, applications should negotiate try formats first and then
-modify the active settings using the try formats returned during the
-last negotiation iteration. This guarantees that the active format will
-be applied as-is by the driver without being modified.
-
-
-.. _v4l2-subdev-selections:
-
-Selections: cropping, scaling and composition
----------------------------------------------
-
-Many sub-devices support cropping frames on their input or output pads
-(or possible even on both). Cropping is used to select the area of
-interest in an image, typically on an image sensor or a video decoder.
-It can also be used as part of digital zoom implementations to select
-the area of the image that will be scaled up.
-
-Crop settings are defined by a crop rectangle and represented in a
-struct :c:type:`v4l2_rect` by the coordinates of the top
-left corner and the rectangle size. Both the coordinates and sizes are
-expressed in pixels.
-
-As for pad formats, drivers store try and active rectangles for the
-selection targets :ref:`v4l2-selections-common`.
-
-On sink pads, cropping is applied relative to the current pad format.
-The pad format represents the image size as received by the sub-device
-from the previous block in the pipeline, and the crop rectangle
-represents the sub-image that will be transmitted further inside the
-sub-device for processing.
-
-The scaling operation changes the size of the image by scaling it to new
-dimensions. The scaling ratio isn't specified explicitly, but is implied
-from the original and scaled image sizes. Both sizes are represented by
-struct :c:type:`v4l2_rect`.
-
-Scaling support is optional. When supported by a subdev, the crop
-rectangle on the subdev's sink pad is scaled to the size configured
-using the
-:ref:`VIDIOC_SUBDEV_S_SELECTION <VIDIOC_SUBDEV_G_SELECTION>` IOCTL
-using ``V4L2_SEL_TGT_COMPOSE`` selection target on the same pad. If the
-subdev supports scaling but not composing, the top and left values are
-not used and must always be set to zero.
-
-On source pads, cropping is similar to sink pads, with the exception
-that the source size from which the cropping is performed, is the
-COMPOSE rectangle on the sink pad. In both sink and source pads, the
-crop rectangle must be entirely contained inside the source image size
-for the crop operation.
-
-The drivers should always use the closest possible rectangle the user
-requests on all selection targets, unless specifically told otherwise.
-``V4L2_SEL_FLAG_GE`` and ``V4L2_SEL_FLAG_LE`` flags may be used to round
-the image size either up or down. :ref:`v4l2-selection-flags`
-
-
-Types of selection targets
---------------------------
-
-
-Actual targets
-^^^^^^^^^^^^^^
-
-Actual targets (without a postfix) reflect the actual hardware
-configuration at any point of time. There is a BOUNDS target
-corresponding to every actual target.
-
-
-BOUNDS targets
-^^^^^^^^^^^^^^
-
-BOUNDS targets is the smallest rectangle that contains all valid actual
-rectangles. It may not be possible to set the actual rectangle as large
-as the BOUNDS rectangle, however. This may be because e.g. a sensor's
-pixel array is not rectangular but cross-shaped or round. The maximum
-size may also be smaller than the BOUNDS rectangle.
-
-
-Order of configuration and format propagation
----------------------------------------------
-
-Inside subdevs, the order of image processing steps will always be from
-the sink pad towards the source pad. This is also reflected in the order
-in which the configuration must be performed by the user: the changes
-made will be propagated to any subsequent stages. If this behaviour is
-not desired, the user must set ``V4L2_SEL_FLAG_KEEP_CONFIG`` flag. This
-flag causes no propagation of the changes are allowed in any
-circumstances. This may also cause the accessed rectangle to be adjusted
-by the driver, depending on the properties of the underlying hardware.
-
-The coordinates to a step always refer to the actual size of the
-previous step. The exception to this rule is the sink compose
-rectangle, which refers to the sink compose bounds rectangle --- if it
-is supported by the hardware.
-
-1. Sink pad format. The user configures the sink pad format. This format
-   defines the parameters of the image the entity receives through the
-   pad for further processing.
-
-2. Sink pad actual crop selection. The sink pad crop defines the crop
-   performed to the sink pad format.
-
-3. Sink pad actual compose selection. The size of the sink pad compose
-   rectangle defines the scaling ratio compared to the size of the sink
-   pad crop rectangle. The location of the compose rectangle specifies
-   the location of the actual sink compose rectangle in the sink compose
-   bounds rectangle.
-
-4. Source pad actual crop selection. Crop on the source pad defines crop
-   performed to the image in the sink compose bounds rectangle.
-
-5. Source pad format. The source pad format defines the output pixel
-   format of the subdev, as well as the other parameters with the
-   exception of the image width and height. Width and height are defined
-   by the size of the source pad actual crop selection.
-
-Accessing any of the above rectangles not supported by the subdev will
-return ``EINVAL``. Any rectangle referring to a previous unsupported
-rectangle coordinates will instead refer to the previous supported
-rectangle. For example, if sink crop is not supported, the compose
-selection will refer to the sink pad format dimensions instead.
-
-
-.. _subdev-image-processing-crop:
-
-.. kernel-figure:: subdev-image-processing-crop.svg
-    :alt:   subdev-image-processing-crop.svg
-    :align: center
-
-    **Figure 4.5. Image processing in subdevs: simple crop example**
-
-In the above example, the subdev supports cropping on its sink pad. To
-configure it, the user sets the media bus format on the subdev's sink
-pad. Now the actual crop rectangle can be set on the sink pad --- the
-location and size of this rectangle reflect the location and size of a
-rectangle to be cropped from the sink format. The size of the sink crop
-rectangle will also be the size of the format of the subdev's source
-pad.
-
-
-.. _subdev-image-processing-scaling-multi-source:
-
-.. kernel-figure:: subdev-image-processing-scaling-multi-source.svg
-    :alt:   subdev-image-processing-scaling-multi-source.svg
-    :align: center
-
-    **Figure 4.6. Image processing in subdevs: scaling with multiple sources**
-
-In this example, the subdev is capable of first cropping, then scaling
-and finally cropping for two source pads individually from the resulting
-scaled image. The location of the scaled image in the cropped image is
-ignored in sink compose target. Both of the locations of the source crop
-rectangles refer to the sink scaling rectangle, independently cropping
-an area at location specified by the source crop rectangle from it.
-
-
-.. _subdev-image-processing-full:
-
-.. kernel-figure:: subdev-image-processing-full.svg
-    :alt:    subdev-image-processing-full.svg
-    :align:  center
-
-    **Figure 4.7. Image processing in subdevs: scaling and composition with multiple sinks and sources**
-
-The subdev driver supports two sink pads and two source pads. The images
-from both of the sink pads are individually cropped, then scaled and
-further composed on the composition bounds rectangle. From that, two
-independent streams are cropped and sent out of the subdev from the
-source pads.
-
-
-.. toctree::
-    :maxdepth: 1
-
-    subdev-formats
diff --git a/Documentation/media/uapi/v4l/dev-touch.rst b/Documentation/media/uapi/v4l/dev-touch.rst
deleted file mode 100644
index 356f01385221..000000000000
--- a/Documentation/media/uapi/v4l/dev-touch.rst
+++ /dev/null
@@ -1,63 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _touch:
-
-*************
-Touch Devices
-*************
-
-Touch devices are accessed through character device special files named
-``/dev/v4l-touch0`` to ``/dev/v4l-touch255`` with major number 81 and
-dynamically allocated minor numbers 0 to 255.
-
-Overview
-========
-
-Sensors may be Optical, or Projected Capacitive touch (PCT).
-
-Processing is required to analyse the raw data and produce input events. In
-some systems, this may be performed on the ASIC and the raw data is purely a
-side-channel for diagnostics or tuning. In other systems, the ASIC is a simple
-analogue front end device which delivers touch data at high rate, and any touch
-processing must be done on the host.
-
-For capacitive touch sensing, the touchscreen is composed of an array of
-horizontal and vertical conductors (alternatively called rows/columns, X/Y
-lines, or tx/rx). Mutual Capacitance measured is at the nodes where the
-conductors cross. Alternatively, Self Capacitance measures the signal from each
-column and row independently.
-
-A touch input may be determined by comparing the raw capacitance measurement to
-a no-touch reference (or "baseline") measurement:
-
-Delta = Raw - Reference
-
-The reference measurement takes account of variations in the capacitance across
-the touch sensor matrix, for example manufacturing irregularities,
-environmental or edge effects.
-
-Querying Capabilities
-=====================
-
-Devices supporting the touch interface set the ``V4L2_CAP_VIDEO_CAPTURE`` flag
-and the ``V4L2_CAP_TOUCH`` flag in the ``capabilities`` field of
-:c:type:`v4l2_capability` returned by the
-:ref:`VIDIOC_QUERYCAP` ioctl.
-
-At least one of the read/write or streaming I/O methods must be
-supported.
-
-The formats supported by touch devices are documented in
-:ref:`Touch Formats <tch-formats>`.
-
-Data Format Negotiation
-=======================
-
-A touch device may support any I/O method.
diff --git a/Documentation/media/uapi/v4l/devices.rst b/Documentation/media/uapi/v4l/devices.rst
deleted file mode 100644
index 07f8d047662b..000000000000
--- a/Documentation/media/uapi/v4l/devices.rst
+++ /dev/null
@@ -1,33 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _devices:
-
-**********
-Interfaces
-**********
-
-
-.. toctree::
-    :maxdepth: 1
-
-    dev-capture
-    dev-overlay
-    dev-output
-    dev-osd
-    dev-mem2mem
-    dev-raw-vbi
-    dev-sliced-vbi
-    dev-radio
-    dev-rds
-    dev-sdr
-    dev-touch
-    dev-event
-    dev-subdev
-    dev-meta
diff --git a/Documentation/media/uapi/v4l/diff-v4l.rst b/Documentation/media/uapi/v4l/diff-v4l.rst
deleted file mode 100644
index dd6739e8a5b2..000000000000
--- a/Documentation/media/uapi/v4l/diff-v4l.rst
+++ /dev/null
@@ -1,693 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _diff-v4l:
-
-********************************
-Differences between V4L and V4L2
-********************************
-
-The Video For Linux API was first introduced in Linux 2.1 to unify and
-replace various TV and radio device related interfaces, developed
-independently by driver writers in prior years. Starting with Linux 2.5
-the much improved V4L2 API replaces the V4L API. The support for the old
-V4L calls were removed from Kernel, but the library :ref:`libv4l`
-supports the conversion of a V4L API system call into a V4L2 one.
-
-
-Opening and Closing Devices
-===========================
-
-For compatibility reasons the character device file names recommended
-for V4L2 video capture, overlay, radio and raw vbi capture devices did
-not change from those used by V4L. They are listed in :ref:`devices`
-and below in :ref:`v4l-dev`.
-
-The teletext devices (minor range 192-223) have been removed in V4L2 and
-no longer exist. There is no hardware available anymore for handling
-pure teletext. Instead raw or sliced VBI is used.
-
-The V4L ``videodev`` module automatically assigns minor numbers to
-drivers in load order, depending on the registered device type. We
-recommend that V4L2 drivers by default register devices with the same
-numbers, but the system administrator can assign arbitrary minor numbers
-using driver module options. The major device number remains 81.
-
-
-.. _v4l-dev:
-
-.. flat-table:: V4L Device Types, Names and Numbers
-    :header-rows:  1
-    :stub-columns: 0
-
-    * - Device Type
-      - File Name
-      - Minor Numbers
-    * - Video capture and overlay
-      - ``/dev/video`` and ``/dev/bttv0``\  [#f1]_, ``/dev/video0`` to
-	``/dev/video63``
-      - 0-63
-    * - Radio receiver
-      - ``/dev/radio``\  [#f2]_, ``/dev/radio0`` to ``/dev/radio63``
-      - 64-127
-    * - Raw VBI capture
-      - ``/dev/vbi``, ``/dev/vbi0`` to ``/dev/vbi31``
-      - 224-255
-
-
-V4L prohibits (or used to prohibit) multiple opens of a device file.
-V4L2 drivers *may* support multiple opens, see :ref:`open` for details
-and consequences.
-
-V4L drivers respond to V4L2 ioctls with an ``EINVAL`` error code.
-
-
-Querying Capabilities
-=====================
-
-The V4L ``VIDIOCGCAP`` ioctl is equivalent to V4L2's
-:ref:`VIDIOC_QUERYCAP`.
-
-The ``name`` field in struct ``video_capability`` became
-``card`` in struct :c:type:`v4l2_capability`, ``type``
-was replaced by ``capabilities``. Note V4L2 does not distinguish between
-device types like this, better think of basic video input, video output
-and radio devices supporting a set of related functions like video
-capturing, video overlay and VBI capturing. See :ref:`open` for an
-introduction.
-
-.. tabularcolumns:: |p{5.5cm}|p{6.5cm}|p{5.5cm}
-
-.. cssclass:: longtable
-
-.. flat-table::
-    :header-rows:  1
-    :stub-columns: 0
-
-    * - ``struct video_capability`` ``type``
-      - struct :c:type:`v4l2_capability`
-	``capabilities`` flags
-      - Purpose
-    * - ``VID_TYPE_CAPTURE``
-      - ``V4L2_CAP_VIDEO_CAPTURE``
-      - The :ref:`video capture <capture>` interface is supported.
-    * - ``VID_TYPE_TUNER``
-      - ``V4L2_CAP_TUNER``
-      - The device has a :ref:`tuner or modulator <tuner>`.
-    * - ``VID_TYPE_TELETEXT``
-      - ``V4L2_CAP_VBI_CAPTURE``
-      - The :ref:`raw VBI capture <raw-vbi>` interface is supported.
-    * - ``VID_TYPE_OVERLAY``
-      - ``V4L2_CAP_VIDEO_OVERLAY``
-      - The :ref:`video overlay <overlay>` interface is supported.
-    * - ``VID_TYPE_CHROMAKEY``
-      - ``V4L2_FBUF_CAP_CHROMAKEY`` in field ``capability`` of struct
-	:c:type:`v4l2_framebuffer`
-      - Whether chromakey overlay is supported. For more information on
-	overlay see :ref:`overlay`.
-    * - ``VID_TYPE_CLIPPING``
-      - ``V4L2_FBUF_CAP_LIST_CLIPPING`` and
-	``V4L2_FBUF_CAP_BITMAP_CLIPPING`` in field ``capability`` of
-	struct :c:type:`v4l2_framebuffer`
-      - Whether clipping the overlaid image is supported, see
-	:ref:`overlay`.
-    * - ``VID_TYPE_FRAMERAM``
-      - ``V4L2_FBUF_CAP_EXTERNOVERLAY`` *not set* in field ``capability``
-	of struct :c:type:`v4l2_framebuffer`
-      - Whether overlay overwrites frame buffer memory, see
-	:ref:`overlay`.
-    * - ``VID_TYPE_SCALES``
-      - ``-``
-      - This flag indicates if the hardware can scale images. The V4L2 API
-	implies the scale factor by setting the cropping dimensions and
-	image size with the :ref:`VIDIOC_S_CROP <VIDIOC_G_CROP>` and
-	:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl, respectively. The
-	driver returns the closest sizes possible. For more information on
-	cropping and scaling see :ref:`crop`.
-    * - ``VID_TYPE_MONOCHROME``
-      - ``-``
-      - Applications can enumerate the supported image formats with the
-	:ref:`VIDIOC_ENUM_FMT` ioctl to determine if
-	the device supports grey scale capturing only. For more
-	information on image formats see :ref:`pixfmt`.
-    * - ``VID_TYPE_SUBCAPTURE``
-      - ``-``
-      - Applications can call the :ref:`VIDIOC_G_CROP <VIDIOC_G_CROP>`
-	ioctl to determine if the device supports capturing a subsection
-	of the full picture ("cropping" in V4L2). If not, the ioctl
-	returns the ``EINVAL`` error code. For more information on cropping
-	and scaling see :ref:`crop`.
-    * - ``VID_TYPE_MPEG_DECODER``
-      - ``-``
-      - Applications can enumerate the supported image formats with the
-	:ref:`VIDIOC_ENUM_FMT` ioctl to determine if
-	the device supports MPEG streams.
-    * - ``VID_TYPE_MPEG_ENCODER``
-      - ``-``
-      - See above.
-    * - ``VID_TYPE_MJPEG_DECODER``
-      - ``-``
-      - See above.
-    * - ``VID_TYPE_MJPEG_ENCODER``
-      - ``-``
-      - See above.
-
-
-The ``audios`` field was replaced by ``capabilities`` flag
-``V4L2_CAP_AUDIO``, indicating *if* the device has any audio inputs or
-outputs. To determine their number applications can enumerate audio
-inputs with the :ref:`VIDIOC_G_AUDIO <VIDIOC_G_AUDIO>` ioctl. The
-audio ioctls are described in :ref:`audio`.
-
-The ``maxwidth``, ``maxheight``, ``minwidth`` and ``minheight`` fields
-were removed. Calling the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` or
-:ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` ioctl with the desired
-dimensions returns the closest size possible, taking into account the
-current video standard, cropping and scaling limitations.
-
-
-Video Sources
-=============
-
-V4L provides the ``VIDIOCGCHAN`` and ``VIDIOCSCHAN`` ioctl using struct
-``video_channel`` to enumerate the video inputs of a V4L
-device. The equivalent V4L2 ioctls are
-:ref:`VIDIOC_ENUMINPUT`,
-:ref:`VIDIOC_G_INPUT <VIDIOC_G_INPUT>` and
-:ref:`VIDIOC_S_INPUT <VIDIOC_G_INPUT>` using struct
-:c:type:`v4l2_input` as discussed in :ref:`video`.
-
-The ``channel`` field counting inputs was renamed to ``index``, the
-video input types were renamed as follows:
-
-
-
-.. flat-table::
-    :header-rows:  1
-    :stub-columns: 0
-
-    * - struct ``video_channel`` ``type``
-      - struct :c:type:`v4l2_input` ``type``
-    * - ``VIDEO_TYPE_TV``
-      - ``V4L2_INPUT_TYPE_TUNER``
-    * - ``VIDEO_TYPE_CAMERA``
-      - ``V4L2_INPUT_TYPE_CAMERA``
-
-
-Unlike the ``tuners`` field expressing the number of tuners of this
-input, V4L2 assumes each video input is connected to at most one tuner.
-However a tuner can have more than one input, i. e. RF connectors, and a
-device can have multiple tuners. The index number of the tuner
-associated with the input, if any, is stored in field ``tuner`` of
-struct :c:type:`v4l2_input`. Enumeration of tuners is
-discussed in :ref:`tuner`.
-
-The redundant ``VIDEO_VC_TUNER`` flag was dropped. Video inputs
-associated with a tuner are of type ``V4L2_INPUT_TYPE_TUNER``. The
-``VIDEO_VC_AUDIO`` flag was replaced by the ``audioset`` field. V4L2
-considers devices with up to 32 audio inputs. Each set bit in the
-``audioset`` field represents one audio input this video input combines
-with. For information about audio inputs and how to switch between them
-see :ref:`audio`.
-
-The ``norm`` field describing the supported video standards was replaced
-by ``std``. The V4L specification mentions a flag ``VIDEO_VC_NORM``
-indicating whether the standard can be changed. This flag was a later
-addition together with the ``norm`` field and has been removed in the
-meantime. V4L2 has a similar, albeit more comprehensive approach to
-video standards, see :ref:`standard` for more information.
-
-
-Tuning
-======
-
-The V4L ``VIDIOCGTUNER`` and ``VIDIOCSTUNER`` ioctl and struct
-``video_tuner`` can be used to enumerate the tuners of a
-V4L TV or radio device. The equivalent V4L2 ioctls are
-:ref:`VIDIOC_G_TUNER <VIDIOC_G_TUNER>` and
-:ref:`VIDIOC_S_TUNER <VIDIOC_G_TUNER>` using struct
-:c:type:`v4l2_tuner`. Tuners are covered in :ref:`tuner`.
-
-The ``tuner`` field counting tuners was renamed to ``index``. The fields
-``name``, ``rangelow`` and ``rangehigh`` remained unchanged.
-
-The ``VIDEO_TUNER_PAL``, ``VIDEO_TUNER_NTSC`` and ``VIDEO_TUNER_SECAM``
-flags indicating the supported video standards were dropped. This
-information is now contained in the associated struct
-:c:type:`v4l2_input`. No replacement exists for the
-``VIDEO_TUNER_NORM`` flag indicating whether the video standard can be
-switched. The ``mode`` field to select a different video standard was
-replaced by a whole new set of ioctls and structures described in
-:ref:`standard`. Due to its ubiquity it should be mentioned the BTTV
-driver supports several standards in addition to the regular
-``VIDEO_MODE_PAL`` (0), ``VIDEO_MODE_NTSC``, ``VIDEO_MODE_SECAM`` and
-``VIDEO_MODE_AUTO`` (3). Namely N/PAL Argentina, M/PAL, N/PAL, and NTSC
-Japan with numbers 3-6 (sic).
-
-The ``VIDEO_TUNER_STEREO_ON`` flag indicating stereo reception became
-``V4L2_TUNER_SUB_STEREO`` in field ``rxsubchans``. This field also
-permits the detection of monaural and bilingual audio, see the
-definition of struct :c:type:`v4l2_tuner` for details.
-Presently no replacement exists for the ``VIDEO_TUNER_RDS_ON`` and
-``VIDEO_TUNER_MBS_ON`` flags.
-
-The ``VIDEO_TUNER_LOW`` flag was renamed to ``V4L2_TUNER_CAP_LOW`` in
-the struct :c:type:`v4l2_tuner` ``capability`` field.
-
-The ``VIDIOCGFREQ`` and ``VIDIOCSFREQ`` ioctl to change the tuner
-frequency where renamed to
-:ref:`VIDIOC_G_FREQUENCY <VIDIOC_G_FREQUENCY>` and
-:ref:`VIDIOC_S_FREQUENCY <VIDIOC_G_FREQUENCY>`. They take a pointer
-to a struct :c:type:`v4l2_frequency` instead of an
-unsigned long integer.
-
-
-.. _v4l-image-properties:
-
-Image Properties
-================
-
-V4L2 has no equivalent of the ``VIDIOCGPICT`` and ``VIDIOCSPICT`` ioctl
-and struct ``video_picture``. The following fields where
-replaced by V4L2 controls accessible with the
-:ref:`VIDIOC_QUERYCTRL`,
-:ref:`VIDIOC_G_CTRL <VIDIOC_G_CTRL>` and
-:ref:`VIDIOC_S_CTRL <VIDIOC_G_CTRL>` ioctls:
-
-
-
-.. flat-table::
-    :header-rows:  1
-    :stub-columns: 0
-
-    * - struct ``video_picture``
-      - V4L2 Control ID
-    * - ``brightness``
-      - ``V4L2_CID_BRIGHTNESS``
-    * - ``hue``
-      - ``V4L2_CID_HUE``
-    * - ``colour``
-      - ``V4L2_CID_SATURATION``
-    * - ``contrast``
-      - ``V4L2_CID_CONTRAST``
-    * - ``whiteness``
-      - ``V4L2_CID_WHITENESS``
-
-
-The V4L picture controls are assumed to range from 0 to 65535 with no
-particular reset value. The V4L2 API permits arbitrary limits and
-defaults which can be queried with the
-:ref:`VIDIOC_QUERYCTRL` ioctl. For general
-information about controls see :ref:`control`.
-
-The ``depth`` (average number of bits per pixel) of a video image is
-implied by the selected image format. V4L2 does not explicitly provide
-such information assuming applications recognizing the format are aware
-of the image depth and others need not know. The ``palette`` field moved
-into the struct :c:type:`v4l2_pix_format`:
-
-
-
-.. flat-table::
-    :header-rows:  1
-    :stub-columns: 0
-
-    * - struct ``video_picture`` ``palette``
-      - struct :c:type:`v4l2_pix_format` ``pixfmt``
-    * - ``VIDEO_PALETTE_GREY``
-      - :ref:`V4L2_PIX_FMT_GREY <V4L2-PIX-FMT-GREY>`
-    * - ``VIDEO_PALETTE_HI240``
-      - :ref:`V4L2_PIX_FMT_HI240 <pixfmt-reserved>` [#f3]_
-    * - ``VIDEO_PALETTE_RGB565``
-      - :ref:`V4L2_PIX_FMT_RGB565 <pixfmt-rgb>`
-    * - ``VIDEO_PALETTE_RGB555``
-      - :ref:`V4L2_PIX_FMT_RGB555 <pixfmt-rgb>`
-    * - ``VIDEO_PALETTE_RGB24``
-      - :ref:`V4L2_PIX_FMT_BGR24 <pixfmt-rgb>`
-    * - ``VIDEO_PALETTE_RGB32``
-      - :ref:`V4L2_PIX_FMT_BGR32 <pixfmt-rgb>` [#f4]_
-    * - ``VIDEO_PALETTE_YUV422``
-      - :ref:`V4L2_PIX_FMT_YUYV <V4L2-PIX-FMT-YUYV>`
-    * - ``VIDEO_PALETTE_YUYV``\  [#f5]_
-      - :ref:`V4L2_PIX_FMT_YUYV <V4L2-PIX-FMT-YUYV>`
-    * - ``VIDEO_PALETTE_UYVY``
-      - :ref:`V4L2_PIX_FMT_UYVY <V4L2-PIX-FMT-UYVY>`
-    * - ``VIDEO_PALETTE_YUV420``
-      - None
-    * - ``VIDEO_PALETTE_YUV411``
-      - :ref:`V4L2_PIX_FMT_Y41P <V4L2-PIX-FMT-Y41P>` [#f6]_
-    * - ``VIDEO_PALETTE_RAW``
-      - None [#f7]_
-    * - ``VIDEO_PALETTE_YUV422P``
-      - :ref:`V4L2_PIX_FMT_YUV422P <V4L2-PIX-FMT-YUV422P>`
-    * - ``VIDEO_PALETTE_YUV411P``
-      - :ref:`V4L2_PIX_FMT_YUV411P <V4L2-PIX-FMT-YUV411P>` [#f8]_
-    * - ``VIDEO_PALETTE_YUV420P``
-      - :ref:`V4L2_PIX_FMT_YVU420 <V4L2-PIX-FMT-YVU420>`
-    * - ``VIDEO_PALETTE_YUV410P``
-      - :ref:`V4L2_PIX_FMT_YVU410 <V4L2-PIX-FMT-YVU410>`
-
-
-V4L2 image formats are defined in :ref:`pixfmt`. The image format can
-be selected with the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl.
-
-
-Audio
-=====
-
-The ``VIDIOCGAUDIO`` and ``VIDIOCSAUDIO`` ioctl and struct
-``video_audio`` are used to enumerate the audio inputs
-of a V4L device. The equivalent V4L2 ioctls are
-:ref:`VIDIOC_G_AUDIO <VIDIOC_G_AUDIO>` and
-:ref:`VIDIOC_S_AUDIO <VIDIOC_G_AUDIO>` using struct
-:c:type:`v4l2_audio` as discussed in :ref:`audio`.
-
-The ``audio`` "channel number" field counting audio inputs was renamed
-to ``index``.
-
-On ``VIDIOCSAUDIO`` the ``mode`` field selects *one* of the
-``VIDEO_SOUND_MONO``, ``VIDEO_SOUND_STEREO``, ``VIDEO_SOUND_LANG1`` or
-``VIDEO_SOUND_LANG2`` audio demodulation modes. When the current audio
-standard is BTSC ``VIDEO_SOUND_LANG2`` refers to SAP and
-``VIDEO_SOUND_LANG1`` is meaningless. Also undocumented in the V4L
-specification, there is no way to query the selected mode. On
-``VIDIOCGAUDIO`` the driver returns the *actually received* audio
-programmes in this field. In the V4L2 API this information is stored in
-the struct :c:type:`v4l2_tuner` ``rxsubchans`` and
-``audmode`` fields, respectively. See :ref:`tuner` for more
-information on tuners. Related to audio modes struct
-:c:type:`v4l2_audio` also reports if this is a mono or
-stereo input, regardless if the source is a tuner.
-
-The following fields where replaced by V4L2 controls accessible with the
-:ref:`VIDIOC_QUERYCTRL`,
-:ref:`VIDIOC_G_CTRL <VIDIOC_G_CTRL>` and
-:ref:`VIDIOC_S_CTRL <VIDIOC_G_CTRL>` ioctls:
-
-
-
-.. flat-table::
-    :header-rows:  1
-    :stub-columns: 0
-
-    * - struct ``video_audio``
-      - V4L2 Control ID
-    * - ``volume``
-      - ``V4L2_CID_AUDIO_VOLUME``
-    * - ``bass``
-      - ``V4L2_CID_AUDIO_BASS``
-    * - ``treble``
-      - ``V4L2_CID_AUDIO_TREBLE``
-    * - ``balance``
-      - ``V4L2_CID_AUDIO_BALANCE``
-
-
-To determine which of these controls are supported by a driver V4L
-provides the ``flags`` ``VIDEO_AUDIO_VOLUME``, ``VIDEO_AUDIO_BASS``,
-``VIDEO_AUDIO_TREBLE`` and ``VIDEO_AUDIO_BALANCE``. In the V4L2 API the
-:ref:`VIDIOC_QUERYCTRL` ioctl reports if the
-respective control is supported. Accordingly the ``VIDEO_AUDIO_MUTABLE``
-and ``VIDEO_AUDIO_MUTE`` flags where replaced by the boolean
-``V4L2_CID_AUDIO_MUTE`` control.
-
-All V4L2 controls have a ``step`` attribute replacing the struct
-``video_audio`` ``step`` field. The V4L audio controls
-are assumed to range from 0 to 65535 with no particular reset value. The
-V4L2 API permits arbitrary limits and defaults which can be queried with
-the :ref:`VIDIOC_QUERYCTRL` ioctl. For general
-information about controls see :ref:`control`.
-
-
-Frame Buffer Overlay
-====================
-
-The V4L2 ioctls equivalent to ``VIDIOCGFBUF`` and ``VIDIOCSFBUF`` are
-:ref:`VIDIOC_G_FBUF <VIDIOC_G_FBUF>` and
-:ref:`VIDIOC_S_FBUF <VIDIOC_G_FBUF>`. The ``base`` field of struct
-``video_buffer`` remained unchanged, except V4L2 defines
-a flag to indicate non-destructive overlays instead of a ``NULL``
-pointer. All other fields moved into the struct
-:c:type:`v4l2_pix_format` ``fmt`` substructure of
-struct :c:type:`v4l2_framebuffer`. The ``depth``
-field was replaced by ``pixelformat``. See :ref:`pixfmt-rgb` for a
-list of RGB formats and their respective color depths.
-
-Instead of the special ioctls ``VIDIOCGWIN`` and ``VIDIOCSWIN`` V4L2
-uses the general-purpose data format negotiation ioctls
-:ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` and
-:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`. They take a pointer to a struct
-:c:type:`v4l2_format` as argument. Here the ``win`` member
-of the ``fmt`` union is used, a struct
-:c:type:`v4l2_window`.
-
-The ``x``, ``y``, ``width`` and ``height`` fields of struct
-``video_window`` moved into struct
-:c:type:`v4l2_rect` substructure ``w`` of struct
-:c:type:`v4l2_window`. The ``chromakey``, ``clips``, and
-``clipcount`` fields remained unchanged. Struct
-``video_clip`` was renamed to struct
-:c:type:`v4l2_clip`, also containing a struct
-:c:type:`v4l2_rect`, but the semantics are still the same.
-
-The ``VIDEO_WINDOW_INTERLACE`` flag was dropped. Instead applications
-must set the ``field`` field to ``V4L2_FIELD_ANY`` or
-``V4L2_FIELD_INTERLACED``. The ``VIDEO_WINDOW_CHROMAKEY`` flag moved
-into struct :c:type:`v4l2_framebuffer`, under the new
-name ``V4L2_FBUF_FLAG_CHROMAKEY``.
-
-In V4L, storing a bitmap pointer in ``clips`` and setting ``clipcount``
-to ``VIDEO_CLIP_BITMAP`` (-1) requests bitmap clipping, using a fixed
-size bitmap of 1024 × 625 bits. Struct :c:type:`v4l2_window`
-has a separate ``bitmap`` pointer field for this purpose and the bitmap
-size is determined by ``w.width`` and ``w.height``.
-
-The ``VIDIOCCAPTURE`` ioctl to enable or disable overlay was renamed to
-:ref:`VIDIOC_OVERLAY`.
-
-
-Cropping
-========
-
-To capture only a subsection of the full picture V4L defines the
-``VIDIOCGCAPTURE`` and ``VIDIOCSCAPTURE`` ioctls using struct
-``video_capture``. The equivalent V4L2 ioctls are
-:ref:`VIDIOC_G_CROP <VIDIOC_G_CROP>` and
-:ref:`VIDIOC_S_CROP <VIDIOC_G_CROP>` using struct
-:c:type:`v4l2_crop`, and the related
-:ref:`VIDIOC_CROPCAP` ioctl. This is a rather
-complex matter, see :ref:`crop` for details.
-
-The ``x``, ``y``, ``width`` and ``height`` fields moved into struct
-:c:type:`v4l2_rect` substructure ``c`` of struct
-:c:type:`v4l2_crop`. The ``decimation`` field was dropped. In
-the V4L2 API the scaling factor is implied by the size of the cropping
-rectangle and the size of the captured or overlaid image.
-
-The ``VIDEO_CAPTURE_ODD`` and ``VIDEO_CAPTURE_EVEN`` flags to capture
-only the odd or even field, respectively, were replaced by
-``V4L2_FIELD_TOP`` and ``V4L2_FIELD_BOTTOM`` in the field named
-``field`` of struct :c:type:`v4l2_pix_format` and
-struct :c:type:`v4l2_window`. These structures are used to
-select a capture or overlay format with the
-:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl.
-
-
-Reading Images, Memory Mapping
-==============================
-
-
-Capturing using the read method
--------------------------------
-
-There is no essential difference between reading images from a V4L or
-V4L2 device using the :ref:`read() <func-read>` function, however V4L2
-drivers are not required to support this I/O method. Applications can
-determine if the function is available with the
-:ref:`VIDIOC_QUERYCAP` ioctl. All V4L2 devices
-exchanging data with applications must support the
-:ref:`select() <func-select>` and :ref:`poll() <func-poll>`
-functions.
-
-To select an image format and size, V4L provides the ``VIDIOCSPICT`` and
-``VIDIOCSWIN`` ioctls. V4L2 uses the general-purpose data format
-negotiation ioctls :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` and
-:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`. They take a pointer to a struct
-:c:type:`v4l2_format` as argument, here the struct
-:c:type:`v4l2_pix_format` named ``pix`` of its
-``fmt`` union is used.
-
-For more information about the V4L2 read interface see :ref:`rw`.
-
-
-Capturing using memory mapping
-------------------------------
-
-Applications can read from V4L devices by mapping buffers in device
-memory, or more often just buffers allocated in DMA-able system memory,
-into their address space. This avoids the data copying overhead of the
-read method. V4L2 supports memory mapping as well, with a few
-differences.
-
-
-
-.. flat-table::
-    :header-rows:  1
-    :stub-columns: 0
-
-    * - V4L
-      - V4L2
-    * -
-      - The image format must be selected before buffers are allocated,
-	with the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl. When no
-	format is selected the driver may use the last, possibly by
-	another application requested format.
-    * - Applications cannot change the number of buffers. The it is built
-	into the driver, unless it has a module option to change the
-	number when the driver module is loaded.
-      - The :ref:`VIDIOC_REQBUFS` ioctl allocates the
-	desired number of buffers, this is a required step in the
-	initialization sequence.
-    * - Drivers map all buffers as one contiguous range of memory. The
-	``VIDIOCGMBUF`` ioctl is available to query the number of buffers,
-	the offset of each buffer from the start of the virtual file, and
-	the overall amount of memory used, which can be used as arguments
-	for the :ref:`mmap() <func-mmap>` function.
-      - Buffers are individually mapped. The offset and size of each
-	buffer can be determined with the
-	:ref:`VIDIOC_QUERYBUF` ioctl.
-    * - The ``VIDIOCMCAPTURE`` ioctl prepares a buffer for capturing. It
-	also determines the image format for this buffer. The ioctl
-	returns immediately, eventually with an ``EAGAIN`` error code if no
-	video signal had been detected. When the driver supports more than
-	one buffer applications can call the ioctl multiple times and thus
-	have multiple outstanding capture requests.
-
-	The ``VIDIOCSYNC`` ioctl suspends execution until a particular
-	buffer has been filled.
-      - Drivers maintain an incoming and outgoing queue.
-	:ref:`VIDIOC_QBUF` enqueues any empty buffer into
-	the incoming queue. Filled buffers are dequeued from the outgoing
-	queue with the :ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl. To wait
-	until filled buffers become available this function,
-	:ref:`select() <func-select>` or :ref:`poll() <func-poll>` can
-	be used. The :ref:`VIDIOC_STREAMON` ioctl
-	must be called once after enqueuing one or more buffers to start
-	capturing. Its counterpart
-	:ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` stops capturing and
-	dequeues all buffers from both queues. Applications can query the
-	signal status, if known, with the
-	:ref:`VIDIOC_ENUMINPUT` ioctl.
-
-
-For a more in-depth discussion of memory mapping and examples, see
-:ref:`mmap`.
-
-
-Reading Raw VBI Data
-====================
-
-Originally the V4L API did not specify a raw VBI capture interface, only
-the device file ``/dev/vbi`` was reserved for this purpose. The only
-driver supporting this interface was the BTTV driver, de-facto defining
-the V4L VBI interface. Reading from the device yields a raw VBI image
-with the following parameters:
-
-
-
-.. flat-table::
-    :header-rows:  1
-    :stub-columns: 0
-
-    * - struct :c:type:`v4l2_vbi_format`
-      - V4L, BTTV driver
-    * - sampling_rate
-      - 28636363 Hz NTSC (or any other 525-line standard); 35468950 Hz PAL
-	and SECAM (625-line standards)
-    * - offset
-      - ?
-    * - samples_per_line
-      - 2048
-    * - sample_format
-      - V4L2_PIX_FMT_GREY. The last four bytes (a machine endianness
-	integer) contain a frame counter.
-    * - start[]
-      - 10, 273 NTSC; 22, 335 PAL and SECAM
-    * - count[]
-      - 16, 16 [#f9]_
-    * - flags
-      - 0
-
-
-Undocumented in the V4L specification, in Linux 2.3 the
-``VIDIOCGVBIFMT`` and ``VIDIOCSVBIFMT`` ioctls using struct
-``vbi_format`` were added to determine the VBI image
-parameters. These ioctls are only partially compatible with the V4L2 VBI
-interface specified in :ref:`raw-vbi`.
-
-An ``offset`` field does not exist, ``sample_format`` is supposed to be
-``VIDEO_PALETTE_RAW``, equivalent to ``V4L2_PIX_FMT_GREY``. The
-remaining fields are probably equivalent to struct
-:c:type:`v4l2_vbi_format`.
-
-Apparently only the Zoran (ZR 36120) driver implements these ioctls. The
-semantics differ from those specified for V4L2 in two ways. The
-parameters are reset on :ref:`open() <func-open>` and
-``VIDIOCSVBIFMT`` always returns an ``EINVAL`` error code if the parameters
-are invalid.
-
-
-Miscellaneous
-=============
-
-V4L2 has no equivalent of the ``VIDIOCGUNIT`` ioctl. Applications can
-find the VBI device associated with a video capture device (or vice
-versa) by reopening the device and requesting VBI data. For details see
-:ref:`open`.
-
-No replacement exists for ``VIDIOCKEY``, and the V4L functions for
-microcode programming. A new interface for MPEG compression and playback
-devices is documented in :ref:`extended-controls`.
-
-.. [#f1]
-   According to Documentation/admin-guide/devices.rst these should be symbolic links
-   to ``/dev/video0``. Note the original bttv interface is not
-   compatible with V4L or V4L2.
-
-.. [#f2]
-   According to ``Documentation/admin-guide/devices.rst`` a symbolic link to
-   ``/dev/radio0``.
-
-.. [#f3]
-   This is a custom format used by the BTTV driver, not one of the V4L2
-   standard formats.
-
-.. [#f4]
-   Presumably all V4L RGB formats are little-endian, although some
-   drivers might interpret them according to machine endianness. V4L2
-   defines little-endian, big-endian and red/blue swapped variants. For
-   details see :ref:`pixfmt-rgb`.
-
-.. [#f5]
-   ``VIDEO_PALETTE_YUV422`` and ``VIDEO_PALETTE_YUYV`` are the same
-   formats. Some V4L drivers respond to one, some to the other.
-
-.. [#f6]
-   Not to be confused with ``V4L2_PIX_FMT_YUV411P``, which is a planar
-   format.
-
-.. [#f7]
-   V4L explains this as: "RAW capture (BT848)"
-
-.. [#f8]
-   Not to be confused with ``V4L2_PIX_FMT_Y41P``, which is a packed
-   format.
-
-.. [#f9]
-   Old driver versions used different values, eventually the custom
-   ``BTTV_VBISIZE`` ioctl was added to query the correct values.
diff --git a/Documentation/media/uapi/v4l/dmabuf.rst b/Documentation/media/uapi/v4l/dmabuf.rst
deleted file mode 100644
index bb8fd943b14e..000000000000
--- a/Documentation/media/uapi/v4l/dmabuf.rst
+++ /dev/null
@@ -1,169 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _dmabuf:
-
-************************************
-Streaming I/O (DMA buffer importing)
-************************************
-
-The DMABUF framework provides a generic method for sharing buffers
-between multiple devices. Device drivers that support DMABUF can export
-a DMA buffer to userspace as a file descriptor (known as the exporter
-role), import a DMA buffer from userspace using a file descriptor
-previously exported for a different or the same device (known as the
-importer role), or both. This section describes the DMABUF importer role
-API in V4L2.
-
-Refer to :ref:`DMABUF exporting <VIDIOC_EXPBUF>` for details about
-exporting V4L2 buffers as DMABUF file descriptors.
-
-Input and output devices support the streaming I/O method when the
-``V4L2_CAP_STREAMING`` flag in the ``capabilities`` field of struct
-:c:type:`v4l2_capability` returned by the
-:ref:`VIDIOC_QUERYCAP <VIDIOC_QUERYCAP>` ioctl is set. Whether
-importing DMA buffers through DMABUF file descriptors is supported is
-determined by calling the :ref:`VIDIOC_REQBUFS <VIDIOC_REQBUFS>`
-ioctl with the memory type set to ``V4L2_MEMORY_DMABUF``.
-
-This I/O method is dedicated to sharing DMA buffers between different
-devices, which may be V4L devices or other video-related devices (e.g.
-DRM). Buffers (planes) are allocated by a driver on behalf of an
-application. Next, these buffers are exported to the application as file
-descriptors using an API which is specific for an allocator driver. Only
-such file descriptor are exchanged. The descriptors and meta-information
-are passed in struct :c:type:`v4l2_buffer` (or in struct
-:c:type:`v4l2_plane` in the multi-planar API case). The
-driver must be switched into DMABUF I/O mode by calling the
-:ref:`VIDIOC_REQBUFS <VIDIOC_REQBUFS>` with the desired buffer type.
-
-
-Example: Initiating streaming I/O with DMABUF file descriptors
-==============================================================
-
-.. code-block:: c
-
-    struct v4l2_requestbuffers reqbuf;
-
-    memset(&reqbuf, 0, sizeof (reqbuf));
-    reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-    reqbuf.memory = V4L2_MEMORY_DMABUF;
-    reqbuf.count = 1;
-
-    if (ioctl(fd, VIDIOC_REQBUFS, &reqbuf) == -1) {
-	if (errno == EINVAL)
-	    printf("Video capturing or DMABUF streaming is not supported\\n");
-	else
-	    perror("VIDIOC_REQBUFS");
-
-	exit(EXIT_FAILURE);
-    }
-
-The buffer (plane) file descriptor is passed on the fly with the
-:ref:`VIDIOC_QBUF <VIDIOC_QBUF>` ioctl. In case of multiplanar
-buffers, every plane can be associated with a different DMABUF
-descriptor. Although buffers are commonly cycled, applications can pass
-a different DMABUF descriptor at each :ref:`VIDIOC_QBUF <VIDIOC_QBUF>` call.
-
-Example: Queueing DMABUF using single plane API
-===============================================
-
-.. code-block:: c
-
-    int buffer_queue(int v4lfd, int index, int dmafd)
-    {
-	struct v4l2_buffer buf;
-
-	memset(&buf, 0, sizeof buf);
-	buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	buf.memory = V4L2_MEMORY_DMABUF;
-	buf.index = index;
-	buf.m.fd = dmafd;
-
-	if (ioctl(v4lfd, VIDIOC_QBUF, &buf) == -1) {
-	    perror("VIDIOC_QBUF");
-	    return -1;
-	}
-
-	return 0;
-    }
-
-Example 3.6. Queueing DMABUF using multi plane API
-==================================================
-
-.. code-block:: c
-
-    int buffer_queue_mp(int v4lfd, int index, int dmafd[], int n_planes)
-    {
-	struct v4l2_buffer buf;
-	struct v4l2_plane planes[VIDEO_MAX_PLANES];
-	int i;
-
-	memset(&buf, 0, sizeof buf);
-	buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-	buf.memory = V4L2_MEMORY_DMABUF;
-	buf.index = index;
-	buf.m.planes = planes;
-	buf.length = n_planes;
-
-	memset(&planes, 0, sizeof planes);
-
-	for (i = 0; i < n_planes; ++i)
-	    buf.m.planes[i].m.fd = dmafd[i];
-
-	if (ioctl(v4lfd, VIDIOC_QBUF, &buf) == -1) {
-	    perror("VIDIOC_QBUF");
-	    return -1;
-	}
-
-	return 0;
-    }
-
-Captured or displayed buffers are dequeued with the
-:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl. The driver can unlock the
-buffer at any time between the completion of the DMA and this ioctl. The
-memory is also unlocked when
-:ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` is called,
-:ref:`VIDIOC_REQBUFS <VIDIOC_REQBUFS>`, or when the device is closed.
-
-For capturing applications it is customary to enqueue a number of empty
-buffers, to start capturing and enter the read loop. Here the
-application waits until a filled buffer can be dequeued, and re-enqueues
-the buffer when the data is no longer needed. Output applications fill
-and enqueue buffers, when enough buffers are stacked up output is
-started. In the write loop, when the application runs out of free
-buffers it must wait until an empty buffer can be dequeued and reused.
-Two methods exist to suspend execution of the application until one or
-more buffers can be dequeued. By default :ref:`VIDIOC_DQBUF
-<VIDIOC_QBUF>` blocks when no buffer is in the outgoing queue. When the
-``O_NONBLOCK`` flag was given to the :ref:`open() <func-open>` function,
-:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` returns immediately with an ``EAGAIN``
-error code when no buffer is available. The
-:ref:`select() <func-select>` and :ref:`poll() <func-poll>`
-functions are always available.
-
-To start and stop capturing or displaying applications call the
-:ref:`VIDIOC_STREAMON <VIDIOC_STREAMON>` and
-:ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` ioctls.
-
-.. note::
-
-   :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` removes all buffers from
-   both queues and unlocks all buffers as a side effect. Since there is no
-   notion of doing anything "now" on a multitasking system, if an
-   application needs to synchronize with another event it should examine
-   the struct :c:type:`v4l2_buffer` ``timestamp`` of captured or
-   outputted buffers.
-
-Drivers implementing DMABUF importing I/O must support the
-:ref:`VIDIOC_REQBUFS <VIDIOC_REQBUFS>`, :ref:`VIDIOC_QBUF <VIDIOC_QBUF>`,
-:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>`, :ref:`VIDIOC_STREAMON
-<VIDIOC_STREAMON>` and :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` ioctls,
-and the :ref:`select() <func-select>` and :ref:`poll() <func-poll>`
-functions.
diff --git a/Documentation/media/uapi/v4l/dv-timings.rst b/Documentation/media/uapi/v4l/dv-timings.rst
deleted file mode 100644
index b3c69ca559e2..000000000000
--- a/Documentation/media/uapi/v4l/dv-timings.rst
+++ /dev/null
@@ -1,45 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _dv-timings:
-
-**************************
-Digital Video (DV) Timings
-**************************
-
-The video standards discussed so far have been dealing with Analog TV
-and the corresponding video timings. Today there are many more different
-hardware interfaces such as High Definition TV interfaces (HDMI), VGA,
-DVI connectors etc., that carry video signals and there is a need to
-extend the API to select the video timings for these interfaces. Since
-it is not possible to extend the :ref:`v4l2_std_id <v4l2-std-id>`
-due to the limited bits available, a new set of ioctls was added to
-set/get video timings at the input and output.
-
-These ioctls deal with the detailed digital video timings that define
-each video format. This includes parameters such as the active video
-width and height, signal polarities, frontporches, backporches, sync
-widths etc. The ``linux/v4l2-dv-timings.h`` header can be used to get
-the timings of the formats in the :ref:`cea861` and :ref:`vesadmt`
-standards.
-
-To enumerate and query the attributes of the DV timings supported by a
-device applications use the
-:ref:`VIDIOC_ENUM_DV_TIMINGS` and
-:ref:`VIDIOC_DV_TIMINGS_CAP` ioctls. To set
-DV timings for the device applications use the
-:ref:`VIDIOC_S_DV_TIMINGS <VIDIOC_G_DV_TIMINGS>` ioctl and to get
-current DV timings they use the
-:ref:`VIDIOC_G_DV_TIMINGS <VIDIOC_G_DV_TIMINGS>` ioctl. To detect
-the DV timings as seen by the video receiver applications use the
-:ref:`VIDIOC_QUERY_DV_TIMINGS` ioctl.
-
-Applications can make use of the :ref:`input-capabilities` and
-:ref:`output-capabilities` flags to determine whether the digital
-video ioctls can be used with the given input or output.
diff --git a/Documentation/media/uapi/v4l/ext-ctrls-camera.rst b/Documentation/media/uapi/v4l/ext-ctrls-camera.rst
deleted file mode 100644
index 51c1d5c9eb00..000000000000
--- a/Documentation/media/uapi/v4l/ext-ctrls-camera.rst
+++ /dev/null
@@ -1,515 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _camera-controls:
-
-************************
-Camera Control Reference
-************************
-
-The Camera class includes controls for mechanical (or equivalent
-digital) features of a device such as controllable lenses or sensors.
-
-
-.. _camera-control-id:
-
-Camera Control IDs
-==================
-
-``V4L2_CID_CAMERA_CLASS (class)``
-    The Camera class descriptor. Calling
-    :ref:`VIDIOC_QUERYCTRL` for this control will
-    return a description of this control class.
-
-.. _v4l2-exposure-auto-type:
-
-``V4L2_CID_EXPOSURE_AUTO``
-    (enum)
-
-enum v4l2_exposure_auto_type -
-    Enables automatic adjustments of the exposure time and/or iris
-    aperture. The effect of manual changes of the exposure time or iris
-    aperture while these features are enabled is undefined, drivers
-    should ignore such requests. Possible values are:
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_EXPOSURE_AUTO``
-      - Automatic exposure time, automatic iris aperture.
-    * - ``V4L2_EXPOSURE_MANUAL``
-      - Manual exposure time, manual iris.
-    * - ``V4L2_EXPOSURE_SHUTTER_PRIORITY``
-      - Manual exposure time, auto iris.
-    * - ``V4L2_EXPOSURE_APERTURE_PRIORITY``
-      - Auto exposure time, manual iris.
-
-
-
-``V4L2_CID_EXPOSURE_ABSOLUTE (integer)``
-    Determines the exposure time of the camera sensor. The exposure time
-    is limited by the frame interval. Drivers should interpret the
-    values as 100 µs units, where the value 1 stands for 1/10000th of a
-    second, 10000 for 1 second and 100000 for 10 seconds.
-
-``V4L2_CID_EXPOSURE_AUTO_PRIORITY (boolean)``
-    When ``V4L2_CID_EXPOSURE_AUTO`` is set to ``AUTO`` or
-    ``APERTURE_PRIORITY``, this control determines if the device may
-    dynamically vary the frame rate. By default this feature is disabled
-    (0) and the frame rate must remain constant.
-
-``V4L2_CID_AUTO_EXPOSURE_BIAS (integer menu)``
-    Determines the automatic exposure compensation, it is effective only
-    when ``V4L2_CID_EXPOSURE_AUTO`` control is set to ``AUTO``,
-    ``SHUTTER_PRIORITY`` or ``APERTURE_PRIORITY``. It is expressed in
-    terms of EV, drivers should interpret the values as 0.001 EV units,
-    where the value 1000 stands for +1 EV.
-
-    Increasing the exposure compensation value is equivalent to
-    decreasing the exposure value (EV) and will increase the amount of
-    light at the image sensor. The camera performs the exposure
-    compensation by adjusting absolute exposure time and/or aperture.
-
-.. _v4l2-exposure-metering:
-
-``V4L2_CID_EXPOSURE_METERING``
-    (enum)
-
-enum v4l2_exposure_metering -
-    Determines how the camera measures the amount of light available for
-    the frame exposure. Possible values are:
-
-.. tabularcolumns:: |p{8.7cm}|p{8.8cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_EXPOSURE_METERING_AVERAGE``
-      - Use the light information coming from the entire frame and average
-	giving no weighting to any particular portion of the metered area.
-    * - ``V4L2_EXPOSURE_METERING_CENTER_WEIGHTED``
-      - Average the light information coming from the entire frame giving
-	priority to the center of the metered area.
-    * - ``V4L2_EXPOSURE_METERING_SPOT``
-      - Measure only very small area at the center of the frame.
-    * - ``V4L2_EXPOSURE_METERING_MATRIX``
-      - A multi-zone metering. The light intensity is measured in several
-	points of the frame and the results are combined. The algorithm of
-	the zones selection and their significance in calculating the
-	final value is device dependent.
-
-
-
-``V4L2_CID_PAN_RELATIVE (integer)``
-    This control turns the camera horizontally by the specified amount.
-    The unit is undefined. A positive value moves the camera to the
-    right (clockwise when viewed from above), a negative value to the
-    left. A value of zero does not cause motion. This is a write-only
-    control.
-
-``V4L2_CID_TILT_RELATIVE (integer)``
-    This control turns the camera vertically by the specified amount.
-    The unit is undefined. A positive value moves the camera up, a
-    negative value down. A value of zero does not cause motion. This is
-    a write-only control.
-
-``V4L2_CID_PAN_RESET (button)``
-    When this control is set, the camera moves horizontally to the
-    default position.
-
-``V4L2_CID_TILT_RESET (button)``
-    When this control is set, the camera moves vertically to the default
-    position.
-
-``V4L2_CID_PAN_ABSOLUTE (integer)``
-    This control turns the camera horizontally to the specified
-    position. Positive values move the camera to the right (clockwise
-    when viewed from above), negative values to the left. Drivers should
-    interpret the values as arc seconds, with valid values between -180
-    * 3600 and +180 * 3600 inclusive.
-
-``V4L2_CID_TILT_ABSOLUTE (integer)``
-    This control turns the camera vertically to the specified position.
-    Positive values move the camera up, negative values down. Drivers
-    should interpret the values as arc seconds, with valid values
-    between -180 * 3600 and +180 * 3600 inclusive.
-
-``V4L2_CID_FOCUS_ABSOLUTE (integer)``
-    This control sets the focal point of the camera to the specified
-    position. The unit is undefined. Positive values set the focus
-    closer to the camera, negative values towards infinity.
-
-``V4L2_CID_FOCUS_RELATIVE (integer)``
-    This control moves the focal point of the camera by the specified
-    amount. The unit is undefined. Positive values move the focus closer
-    to the camera, negative values towards infinity. This is a
-    write-only control.
-
-``V4L2_CID_FOCUS_AUTO (boolean)``
-    Enables continuous automatic focus adjustments. The effect of manual
-    focus adjustments while this feature is enabled is undefined,
-    drivers should ignore such requests.
-
-``V4L2_CID_AUTO_FOCUS_START (button)``
-    Starts single auto focus process. The effect of setting this control
-    when ``V4L2_CID_FOCUS_AUTO`` is set to ``TRUE`` (1) is undefined,
-    drivers should ignore such requests.
-
-``V4L2_CID_AUTO_FOCUS_STOP (button)``
-    Aborts automatic focusing started with ``V4L2_CID_AUTO_FOCUS_START``
-    control. It is effective only when the continuous autofocus is
-    disabled, that is when ``V4L2_CID_FOCUS_AUTO`` control is set to
-    ``FALSE`` (0).
-
-.. _v4l2-auto-focus-status:
-
-``V4L2_CID_AUTO_FOCUS_STATUS (bitmask)``
-    The automatic focus status. This is a read-only control.
-
-    Setting ``V4L2_LOCK_FOCUS`` lock bit of the ``V4L2_CID_3A_LOCK``
-    control may stop updates of the ``V4L2_CID_AUTO_FOCUS_STATUS``
-    control value.
-
-.. tabularcolumns:: |p{6.7cm}|p{10.8cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_AUTO_FOCUS_STATUS_IDLE``
-      - Automatic focus is not active.
-    * - ``V4L2_AUTO_FOCUS_STATUS_BUSY``
-      - Automatic focusing is in progress.
-    * - ``V4L2_AUTO_FOCUS_STATUS_REACHED``
-      - Focus has been reached.
-    * - ``V4L2_AUTO_FOCUS_STATUS_FAILED``
-      - Automatic focus has failed, the driver will not transition from
-	this state until another action is performed by an application.
-
-
-
-.. _v4l2-auto-focus-range:
-
-``V4L2_CID_AUTO_FOCUS_RANGE``
-    (enum)
-
-enum v4l2_auto_focus_range -
-    Determines auto focus distance range for which lens may be adjusted.
-
-.. tabularcolumns:: |p{6.8cm}|p{10.7cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_AUTO_FOCUS_RANGE_AUTO``
-      - The camera automatically selects the focus range.
-    * - ``V4L2_AUTO_FOCUS_RANGE_NORMAL``
-      - Normal distance range, limited for best automatic focus
-	performance.
-    * - ``V4L2_AUTO_FOCUS_RANGE_MACRO``
-      - Macro (close-up) auto focus. The camera will use its minimum
-	possible distance for auto focus.
-    * - ``V4L2_AUTO_FOCUS_RANGE_INFINITY``
-      - The lens is set to focus on an object at infinite distance.
-
-
-
-``V4L2_CID_ZOOM_ABSOLUTE (integer)``
-    Specify the objective lens focal length as an absolute value. The
-    zoom unit is driver-specific and its value should be a positive
-    integer.
-
-``V4L2_CID_ZOOM_RELATIVE (integer)``
-    Specify the objective lens focal length relatively to the current
-    value. Positive values move the zoom lens group towards the
-    telephoto direction, negative values towards the wide-angle
-    direction. The zoom unit is driver-specific. This is a write-only
-    control.
-
-``V4L2_CID_ZOOM_CONTINUOUS (integer)``
-    Move the objective lens group at the specified speed until it
-    reaches physical device limits or until an explicit request to stop
-    the movement. A positive value moves the zoom lens group towards the
-    telephoto direction. A value of zero stops the zoom lens group
-    movement. A negative value moves the zoom lens group towards the
-    wide-angle direction. The zoom speed unit is driver-specific.
-
-``V4L2_CID_IRIS_ABSOLUTE (integer)``
-    This control sets the camera's aperture to the specified value. The
-    unit is undefined. Larger values open the iris wider, smaller values
-    close it.
-
-``V4L2_CID_IRIS_RELATIVE (integer)``
-    This control modifies the camera's aperture by the specified amount.
-    The unit is undefined. Positive values open the iris one step
-    further, negative values close it one step further. This is a
-    write-only control.
-
-``V4L2_CID_PRIVACY (boolean)``
-    Prevent video from being acquired by the camera. When this control
-    is set to ``TRUE`` (1), no image can be captured by the camera.
-    Common means to enforce privacy are mechanical obturation of the
-    sensor and firmware image processing, but the device is not
-    restricted to these methods. Devices that implement the privacy
-    control must support read access and may support write access.
-
-``V4L2_CID_BAND_STOP_FILTER (integer)``
-    Switch the band-stop filter of a camera sensor on or off, or specify
-    its strength. Such band-stop filters can be used, for example, to
-    filter out the fluorescent light component.
-
-.. _v4l2-auto-n-preset-white-balance:
-
-``V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE``
-    (enum)
-
-enum v4l2_auto_n_preset_white_balance -
-    Sets white balance to automatic, manual or a preset. The presets
-    determine color temperature of the light as a hint to the camera for
-    white balance adjustments resulting in most accurate color
-    representation. The following white balance presets are listed in
-    order of increasing color temperature.
-
-.. tabularcolumns:: |p{7.2 cm}|p{10.3cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_WHITE_BALANCE_MANUAL``
-      - Manual white balance.
-    * - ``V4L2_WHITE_BALANCE_AUTO``
-      - Automatic white balance adjustments.
-    * - ``V4L2_WHITE_BALANCE_INCANDESCENT``
-      - White balance setting for incandescent (tungsten) lighting. It
-	generally cools down the colors and corresponds approximately to
-	2500...3500 K color temperature range.
-    * - ``V4L2_WHITE_BALANCE_FLUORESCENT``
-      - White balance preset for fluorescent lighting. It corresponds
-	approximately to 4000...5000 K color temperature.
-    * - ``V4L2_WHITE_BALANCE_FLUORESCENT_H``
-      - With this setting the camera will compensate for fluorescent H
-	lighting.
-    * - ``V4L2_WHITE_BALANCE_HORIZON``
-      - White balance setting for horizon daylight. It corresponds
-	approximately to 5000 K color temperature.
-    * - ``V4L2_WHITE_BALANCE_DAYLIGHT``
-      - White balance preset for daylight (with clear sky). It corresponds
-	approximately to 5000...6500 K color temperature.
-    * - ``V4L2_WHITE_BALANCE_FLASH``
-      - With this setting the camera will compensate for the flash light.
-	It slightly warms up the colors and corresponds roughly to
-	5000...5500 K color temperature.
-    * - ``V4L2_WHITE_BALANCE_CLOUDY``
-      - White balance preset for moderately overcast sky. This option
-	corresponds approximately to 6500...8000 K color temperature
-	range.
-    * - ``V4L2_WHITE_BALANCE_SHADE``
-      - White balance preset for shade or heavily overcast sky. It
-	corresponds approximately to 9000...10000 K color temperature.
-
-
-
-.. _v4l2-wide-dynamic-range:
-
-``V4L2_CID_WIDE_DYNAMIC_RANGE (boolean)``
-    Enables or disables the camera's wide dynamic range feature. This
-    feature allows to obtain clear images in situations where intensity
-    of the illumination varies significantly throughout the scene, i.e.
-    there are simultaneously very dark and very bright areas. It is most
-    commonly realized in cameras by combining two subsequent frames with
-    different exposure times.  [#f1]_
-
-.. _v4l2-image-stabilization:
-
-``V4L2_CID_IMAGE_STABILIZATION (boolean)``
-    Enables or disables image stabilization.
-
-``V4L2_CID_ISO_SENSITIVITY (integer menu)``
-    Determines ISO equivalent of an image sensor indicating the sensor's
-    sensitivity to light. The numbers are expressed in arithmetic scale,
-    as per :ref:`iso12232` standard, where doubling the sensor
-    sensitivity is represented by doubling the numerical ISO value.
-    Applications should interpret the values as standard ISO values
-    multiplied by 1000, e.g. control value 800 stands for ISO 0.8.
-    Drivers will usually support only a subset of standard ISO values.
-    The effect of setting this control while the
-    ``V4L2_CID_ISO_SENSITIVITY_AUTO`` control is set to a value other
-    than ``V4L2_CID_ISO_SENSITIVITY_MANUAL`` is undefined, drivers
-    should ignore such requests.
-
-.. _v4l2-iso-sensitivity-auto-type:
-
-``V4L2_CID_ISO_SENSITIVITY_AUTO``
-    (enum)
-
-enum v4l2_iso_sensitivity_type -
-    Enables or disables automatic ISO sensitivity adjustments.
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_CID_ISO_SENSITIVITY_MANUAL``
-      - Manual ISO sensitivity.
-    * - ``V4L2_CID_ISO_SENSITIVITY_AUTO``
-      - Automatic ISO sensitivity adjustments.
-
-
-
-.. _v4l2-scene-mode:
-
-``V4L2_CID_SCENE_MODE``
-    (enum)
-
-enum v4l2_scene_mode -
-    This control allows to select scene programs as the camera automatic
-    modes optimized for common shooting scenes. Within these modes the
-    camera determines best exposure, aperture, focusing, light metering,
-    white balance and equivalent sensitivity. The controls of those
-    parameters are influenced by the scene mode control. An exact
-    behavior in each mode is subject to the camera specification.
-
-    When the scene mode feature is not used, this control should be set
-    to ``V4L2_SCENE_MODE_NONE`` to make sure the other possibly related
-    controls are accessible. The following scene programs are defined:
-
-.. raw:: latex
-
-    \small
-
-.. tabularcolumns:: |p{5.9cm}|p{11.5cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_SCENE_MODE_NONE``
-      - The scene mode feature is disabled.
-    * - ``V4L2_SCENE_MODE_BACKLIGHT``
-      - Backlight. Compensates for dark shadows when light is coming from
-	behind a subject, also by automatically turning on the flash.
-    * - ``V4L2_SCENE_MODE_BEACH_SNOW``
-      - Beach and snow. This mode compensates for all-white or bright
-	scenes, which tend to look gray and low contrast, when camera's
-	automatic exposure is based on an average scene brightness. To
-	compensate, this mode automatically slightly overexposes the
-	frames. The white balance may also be adjusted to compensate for
-	the fact that reflected snow looks bluish rather than white.
-    * - ``V4L2_SCENE_MODE_CANDLELIGHT``
-      - Candle light. The camera generally raises the ISO sensitivity and
-	lowers the shutter speed. This mode compensates for relatively
-	close subject in the scene. The flash is disabled in order to
-	preserve the ambiance of the light.
-    * - ``V4L2_SCENE_MODE_DAWN_DUSK``
-      - Dawn and dusk. Preserves the colors seen in low natural light
-	before dusk and after down. The camera may turn off the flash, and
-	automatically focus at infinity. It will usually boost saturation
-	and lower the shutter speed.
-    * - ``V4L2_SCENE_MODE_FALL_COLORS``
-      - Fall colors. Increases saturation and adjusts white balance for
-	color enhancement. Pictures of autumn leaves get saturated reds
-	and yellows.
-    * - ``V4L2_SCENE_MODE_FIREWORKS``
-      - Fireworks. Long exposure times are used to capture the expanding
-	burst of light from a firework. The camera may invoke image
-	stabilization.
-    * - ``V4L2_SCENE_MODE_LANDSCAPE``
-      - Landscape. The camera may choose a small aperture to provide deep
-	depth of field and long exposure duration to help capture detail
-	in dim light conditions. The focus is fixed at infinity. Suitable
-	for distant and wide scenery.
-    * - ``V4L2_SCENE_MODE_NIGHT``
-      - Night, also known as Night Landscape. Designed for low light
-	conditions, it preserves detail in the dark areas without blowing
-	out bright objects. The camera generally sets itself to a
-	medium-to-high ISO sensitivity, with a relatively long exposure
-	time, and turns flash off. As such, there will be increased image
-	noise and the possibility of blurred image.
-    * - ``V4L2_SCENE_MODE_PARTY_INDOOR``
-      - Party and indoor. Designed to capture indoor scenes that are lit
-	by indoor background lighting as well as the flash. The camera
-	usually increases ISO sensitivity, and adjusts exposure for the
-	low light conditions.
-    * - ``V4L2_SCENE_MODE_PORTRAIT``
-      - Portrait. The camera adjusts the aperture so that the depth of
-	field is reduced, which helps to isolate the subject against a
-	smooth background. Most cameras recognize the presence of faces in
-	the scene and focus on them. The color hue is adjusted to enhance
-	skin tones. The intensity of the flash is often reduced.
-    * - ``V4L2_SCENE_MODE_SPORTS``
-      - Sports. Significantly increases ISO and uses a fast shutter speed
-	to freeze motion of rapidly-moving subjects. Increased image noise
-	may be seen in this mode.
-    * - ``V4L2_SCENE_MODE_SUNSET``
-      - Sunset. Preserves deep hues seen in sunsets and sunrises. It bumps
-	up the saturation.
-    * - ``V4L2_SCENE_MODE_TEXT``
-      - Text. It applies extra contrast and sharpness, it is typically a
-	black-and-white mode optimized for readability. Automatic focus
-	may be switched to close-up mode and this setting may also involve
-	some lens-distortion correction.
-
-.. raw:: latex
-
-    \normalsize
-
-
-``V4L2_CID_3A_LOCK (bitmask)``
-    This control locks or unlocks the automatic focus, exposure and
-    white balance. The automatic adjustments can be paused independently
-    by setting the corresponding lock bit to 1. The camera then retains
-    the settings until the lock bit is cleared. The following lock bits
-    are defined:
-
-    When a given algorithm is not enabled, drivers should ignore
-    requests to lock it and should return no error. An example might be
-    an application setting bit ``V4L2_LOCK_WHITE_BALANCE`` when the
-    ``V4L2_CID_AUTO_WHITE_BALANCE`` control is set to ``FALSE``. The
-    value of this control may be changed by exposure, white balance or
-    focus controls.
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_LOCK_EXPOSURE``
-      - Automatic exposure adjustments lock.
-    * - ``V4L2_LOCK_WHITE_BALANCE``
-      - Automatic white balance adjustments lock.
-    * - ``V4L2_LOCK_FOCUS``
-      - Automatic focus lock.
-
-
-
-``V4L2_CID_PAN_SPEED (integer)``
-    This control turns the camera horizontally at the specific speed.
-    The unit is undefined. A positive value moves the camera to the
-    right (clockwise when viewed from above), a negative value to the
-    left. A value of zero stops the motion if one is in progress and has
-    no effect otherwise.
-
-``V4L2_CID_TILT_SPEED (integer)``
-    This control turns the camera vertically at the specified speed. The
-    unit is undefined. A positive value moves the camera up, a negative
-    value down. A value of zero stops the motion if one is in progress
-    and has no effect otherwise.
-
-.. [#f1]
-   This control may be changed to a menu control in the future, if more
-   options are required.
diff --git a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
deleted file mode 100644
index d4fc5f25aa14..000000000000
--- a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
+++ /dev/null
@@ -1,4264 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _mpeg-controls:
-
-***********************
-Codec Control Reference
-***********************
-
-Below all controls within the Codec control class are described. First
-the generic controls, then controls specific for certain hardware.
-
-.. note::
-
-   These controls are applicable to all codecs and not just MPEG. The
-   defines are prefixed with V4L2_CID_MPEG/V4L2_MPEG as the controls
-   were originally made for MPEG codecs and later extended to cover all
-   encoding formats.
-
-
-Generic Codec Controls
-======================
-
-
-.. _mpeg-control-id:
-
-Codec Control IDs
------------------
-
-``V4L2_CID_MPEG_CLASS (class)``
-    The Codec class descriptor. Calling
-    :ref:`VIDIOC_QUERYCTRL` for this control will
-    return a description of this control class. This description can be
-    used as the caption of a Tab page in a GUI, for example.
-
-.. _v4l2-mpeg-stream-type:
-
-``V4L2_CID_MPEG_STREAM_TYPE``
-    (enum)
-
-enum v4l2_mpeg_stream_type -
-    The MPEG-1, -2 or -4 output stream type. One cannot assume anything
-    here. Each hardware MPEG encoder tends to support different subsets
-    of the available MPEG stream types. This control is specific to
-    multiplexed MPEG streams. The currently defined stream types are:
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_STREAM_TYPE_MPEG2_PS``
-      - MPEG-2 program stream
-    * - ``V4L2_MPEG_STREAM_TYPE_MPEG2_TS``
-      - MPEG-2 transport stream
-    * - ``V4L2_MPEG_STREAM_TYPE_MPEG1_SS``
-      - MPEG-1 system stream
-    * - ``V4L2_MPEG_STREAM_TYPE_MPEG2_DVD``
-      - MPEG-2 DVD-compatible stream
-    * - ``V4L2_MPEG_STREAM_TYPE_MPEG1_VCD``
-      - MPEG-1 VCD-compatible stream
-    * - ``V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD``
-      - MPEG-2 SVCD-compatible stream
-
-
-
-``V4L2_CID_MPEG_STREAM_PID_PMT (integer)``
-    Program Map Table Packet ID for the MPEG transport stream (default
-    16)
-
-``V4L2_CID_MPEG_STREAM_PID_AUDIO (integer)``
-    Audio Packet ID for the MPEG transport stream (default 256)
-
-``V4L2_CID_MPEG_STREAM_PID_VIDEO (integer)``
-    Video Packet ID for the MPEG transport stream (default 260)
-
-``V4L2_CID_MPEG_STREAM_PID_PCR (integer)``
-    Packet ID for the MPEG transport stream carrying PCR fields (default
-    259)
-
-``V4L2_CID_MPEG_STREAM_PES_ID_AUDIO (integer)``
-    Audio ID for MPEG PES
-
-``V4L2_CID_MPEG_STREAM_PES_ID_VIDEO (integer)``
-    Video ID for MPEG PES
-
-.. _v4l2-mpeg-stream-vbi-fmt:
-
-``V4L2_CID_MPEG_STREAM_VBI_FMT``
-    (enum)
-
-enum v4l2_mpeg_stream_vbi_fmt -
-    Some cards can embed VBI data (e. g. Closed Caption, Teletext) into
-    the MPEG stream. This control selects whether VBI data should be
-    embedded, and if so, what embedding method should be used. The list
-    of possible VBI formats depends on the driver. The currently defined
-    VBI format types are:
-
-
-
-.. tabularcolumns:: |p{6.6 cm}|p{10.9cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_STREAM_VBI_FMT_NONE``
-      - No VBI in the MPEG stream
-    * - ``V4L2_MPEG_STREAM_VBI_FMT_IVTV``
-      - VBI in private packets, IVTV format (documented in the kernel
-	sources in the file
-	``Documentation/media/v4l-drivers/cx2341x.rst``)
-
-
-
-.. _v4l2-mpeg-audio-sampling-freq:
-
-``V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ``
-    (enum)
-
-enum v4l2_mpeg_audio_sampling_freq -
-    MPEG Audio sampling frequency. Possible values are:
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100``
-      - 44.1 kHz
-    * - ``V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000``
-      - 48 kHz
-    * - ``V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000``
-      - 32 kHz
-
-
-
-.. _v4l2-mpeg-audio-encoding:
-
-``V4L2_CID_MPEG_AUDIO_ENCODING``
-    (enum)
-
-enum v4l2_mpeg_audio_encoding -
-    MPEG Audio encoding. This control is specific to multiplexed MPEG
-    streams. Possible values are:
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_AUDIO_ENCODING_LAYER_1``
-      - MPEG-1/2 Layer I encoding
-    * - ``V4L2_MPEG_AUDIO_ENCODING_LAYER_2``
-      - MPEG-1/2 Layer II encoding
-    * - ``V4L2_MPEG_AUDIO_ENCODING_LAYER_3``
-      - MPEG-1/2 Layer III encoding
-    * - ``V4L2_MPEG_AUDIO_ENCODING_AAC``
-      - MPEG-2/4 AAC (Advanced Audio Coding)
-    * - ``V4L2_MPEG_AUDIO_ENCODING_AC3``
-      - AC-3 aka ATSC A/52 encoding
-
-
-
-.. _v4l2-mpeg-audio-l1-bitrate:
-
-``V4L2_CID_MPEG_AUDIO_L1_BITRATE``
-    (enum)
-
-enum v4l2_mpeg_audio_l1_bitrate -
-    MPEG-1/2 Layer I bitrate. Possible values are:
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_AUDIO_L1_BITRATE_32K``
-      - 32 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L1_BITRATE_64K``
-      - 64 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L1_BITRATE_96K``
-      - 96 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L1_BITRATE_128K``
-      - 128 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L1_BITRATE_160K``
-      - 160 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L1_BITRATE_192K``
-      - 192 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L1_BITRATE_224K``
-      - 224 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L1_BITRATE_256K``
-      - 256 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L1_BITRATE_288K``
-      - 288 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L1_BITRATE_320K``
-      - 320 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L1_BITRATE_352K``
-      - 352 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L1_BITRATE_384K``
-      - 384 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L1_BITRATE_416K``
-      - 416 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L1_BITRATE_448K``
-      - 448 kbit/s
-
-
-
-.. _v4l2-mpeg-audio-l2-bitrate:
-
-``V4L2_CID_MPEG_AUDIO_L2_BITRATE``
-    (enum)
-
-enum v4l2_mpeg_audio_l2_bitrate -
-    MPEG-1/2 Layer II bitrate. Possible values are:
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_AUDIO_L2_BITRATE_32K``
-      - 32 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L2_BITRATE_48K``
-      - 48 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L2_BITRATE_56K``
-      - 56 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L2_BITRATE_64K``
-      - 64 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L2_BITRATE_80K``
-      - 80 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L2_BITRATE_96K``
-      - 96 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L2_BITRATE_112K``
-      - 112 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L2_BITRATE_128K``
-      - 128 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L2_BITRATE_160K``
-      - 160 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L2_BITRATE_192K``
-      - 192 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L2_BITRATE_224K``
-      - 224 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L2_BITRATE_256K``
-      - 256 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L2_BITRATE_320K``
-      - 320 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L2_BITRATE_384K``
-      - 384 kbit/s
-
-
-
-.. _v4l2-mpeg-audio-l3-bitrate:
-
-``V4L2_CID_MPEG_AUDIO_L3_BITRATE``
-    (enum)
-
-enum v4l2_mpeg_audio_l3_bitrate -
-    MPEG-1/2 Layer III bitrate. Possible values are:
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_AUDIO_L3_BITRATE_32K``
-      - 32 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L3_BITRATE_40K``
-      - 40 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L3_BITRATE_48K``
-      - 48 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L3_BITRATE_56K``
-      - 56 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L3_BITRATE_64K``
-      - 64 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L3_BITRATE_80K``
-      - 80 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L3_BITRATE_96K``
-      - 96 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L3_BITRATE_112K``
-      - 112 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L3_BITRATE_128K``
-      - 128 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L3_BITRATE_160K``
-      - 160 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L3_BITRATE_192K``
-      - 192 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L3_BITRATE_224K``
-      - 224 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L3_BITRATE_256K``
-      - 256 kbit/s
-    * - ``V4L2_MPEG_AUDIO_L3_BITRATE_320K``
-      - 320 kbit/s
-
-
-
-``V4L2_CID_MPEG_AUDIO_AAC_BITRATE (integer)``
-    AAC bitrate in bits per second.
-
-.. _v4l2-mpeg-audio-ac3-bitrate:
-
-``V4L2_CID_MPEG_AUDIO_AC3_BITRATE``
-    (enum)
-
-enum v4l2_mpeg_audio_ac3_bitrate -
-    AC-3 bitrate. Possible values are:
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_AUDIO_AC3_BITRATE_32K``
-      - 32 kbit/s
-    * - ``V4L2_MPEG_AUDIO_AC3_BITRATE_40K``
-      - 40 kbit/s
-    * - ``V4L2_MPEG_AUDIO_AC3_BITRATE_48K``
-      - 48 kbit/s
-    * - ``V4L2_MPEG_AUDIO_AC3_BITRATE_56K``
-      - 56 kbit/s
-    * - ``V4L2_MPEG_AUDIO_AC3_BITRATE_64K``
-      - 64 kbit/s
-    * - ``V4L2_MPEG_AUDIO_AC3_BITRATE_80K``
-      - 80 kbit/s
-    * - ``V4L2_MPEG_AUDIO_AC3_BITRATE_96K``
-      - 96 kbit/s
-    * - ``V4L2_MPEG_AUDIO_AC3_BITRATE_112K``
-      - 112 kbit/s
-    * - ``V4L2_MPEG_AUDIO_AC3_BITRATE_128K``
-      - 128 kbit/s
-    * - ``V4L2_MPEG_AUDIO_AC3_BITRATE_160K``
-      - 160 kbit/s
-    * - ``V4L2_MPEG_AUDIO_AC3_BITRATE_192K``
-      - 192 kbit/s
-    * - ``V4L2_MPEG_AUDIO_AC3_BITRATE_224K``
-      - 224 kbit/s
-    * - ``V4L2_MPEG_AUDIO_AC3_BITRATE_256K``
-      - 256 kbit/s
-    * - ``V4L2_MPEG_AUDIO_AC3_BITRATE_320K``
-      - 320 kbit/s
-    * - ``V4L2_MPEG_AUDIO_AC3_BITRATE_384K``
-      - 384 kbit/s
-    * - ``V4L2_MPEG_AUDIO_AC3_BITRATE_448K``
-      - 448 kbit/s
-    * - ``V4L2_MPEG_AUDIO_AC3_BITRATE_512K``
-      - 512 kbit/s
-    * - ``V4L2_MPEG_AUDIO_AC3_BITRATE_576K``
-      - 576 kbit/s
-    * - ``V4L2_MPEG_AUDIO_AC3_BITRATE_640K``
-      - 640 kbit/s
-
-
-
-.. _v4l2-mpeg-audio-mode:
-
-``V4L2_CID_MPEG_AUDIO_MODE``
-    (enum)
-
-enum v4l2_mpeg_audio_mode -
-    MPEG Audio mode. Possible values are:
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_AUDIO_MODE_STEREO``
-      - Stereo
-    * - ``V4L2_MPEG_AUDIO_MODE_JOINT_STEREO``
-      - Joint Stereo
-    * - ``V4L2_MPEG_AUDIO_MODE_DUAL``
-      - Bilingual
-    * - ``V4L2_MPEG_AUDIO_MODE_MONO``
-      - Mono
-
-
-
-.. _v4l2-mpeg-audio-mode-extension:
-
-``V4L2_CID_MPEG_AUDIO_MODE_EXTENSION``
-    (enum)
-
-enum v4l2_mpeg_audio_mode_extension -
-    Joint Stereo audio mode extension. In Layer I and II they indicate
-    which subbands are in intensity stereo. All other subbands are coded
-    in stereo. Layer III is not (yet) supported. Possible values are:
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4``
-      - Subbands 4-31 in intensity stereo
-    * - ``V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_8``
-      - Subbands 8-31 in intensity stereo
-    * - ``V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_12``
-      - Subbands 12-31 in intensity stereo
-    * - ``V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16``
-      - Subbands 16-31 in intensity stereo
-
-
-
-.. _v4l2-mpeg-audio-emphasis:
-
-``V4L2_CID_MPEG_AUDIO_EMPHASIS``
-    (enum)
-
-enum v4l2_mpeg_audio_emphasis -
-    Audio Emphasis. Possible values are:
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_AUDIO_EMPHASIS_NONE``
-      - None
-    * - ``V4L2_MPEG_AUDIO_EMPHASIS_50_DIV_15_uS``
-      - 50/15 microsecond emphasis
-    * - ``V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17``
-      - CCITT J.17
-
-
-
-.. _v4l2-mpeg-audio-crc:
-
-``V4L2_CID_MPEG_AUDIO_CRC``
-    (enum)
-
-enum v4l2_mpeg_audio_crc -
-    CRC method. Possible values are:
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_AUDIO_CRC_NONE``
-      - None
-    * - ``V4L2_MPEG_AUDIO_CRC_CRC16``
-      - 16 bit parity check
-
-
-
-``V4L2_CID_MPEG_AUDIO_MUTE (boolean)``
-    Mutes the audio when capturing. This is not done by muting audio
-    hardware, which can still produce a slight hiss, but in the encoder
-    itself, guaranteeing a fixed and reproducible audio bitstream. 0 =
-    unmuted, 1 = muted.
-
-.. _v4l2-mpeg-audio-dec-playback:
-
-``V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK``
-    (enum)
-
-enum v4l2_mpeg_audio_dec_playback -
-    Determines how monolingual audio should be played back. Possible
-    values are:
-
-
-
-.. tabularcolumns:: |p{9.8cm}|p{7.7cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_AUDIO_DEC_PLAYBACK_AUTO``
-      - Automatically determines the best playback mode.
-    * - ``V4L2_MPEG_AUDIO_DEC_PLAYBACK_STEREO``
-      - Stereo playback.
-    * - ``V4L2_MPEG_AUDIO_DEC_PLAYBACK_LEFT``
-      - Left channel playback.
-    * - ``V4L2_MPEG_AUDIO_DEC_PLAYBACK_RIGHT``
-      - Right channel playback.
-    * - ``V4L2_MPEG_AUDIO_DEC_PLAYBACK_MONO``
-      - Mono playback.
-    * - ``V4L2_MPEG_AUDIO_DEC_PLAYBACK_SWAPPED_STEREO``
-      - Stereo playback with swapped left and right channels.
-
-
-
-.. _v4l2-mpeg-audio-dec-multilingual-playback:
-
-``V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK``
-    (enum)
-
-enum v4l2_mpeg_audio_dec_playback -
-    Determines how multilingual audio should be played back.
-
-.. _v4l2-mpeg-video-encoding:
-
-``V4L2_CID_MPEG_VIDEO_ENCODING``
-    (enum)
-
-enum v4l2_mpeg_video_encoding -
-    MPEG Video encoding method. This control is specific to multiplexed
-    MPEG streams. Possible values are:
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_VIDEO_ENCODING_MPEG_1``
-      - MPEG-1 Video encoding
-    * - ``V4L2_MPEG_VIDEO_ENCODING_MPEG_2``
-      - MPEG-2 Video encoding
-    * - ``V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC``
-      - MPEG-4 AVC (H.264) Video encoding
-
-
-
-.. _v4l2-mpeg-video-aspect:
-
-``V4L2_CID_MPEG_VIDEO_ASPECT``
-    (enum)
-
-enum v4l2_mpeg_video_aspect -
-    Video aspect. Possible values are:
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_VIDEO_ASPECT_1x1``
-    * - ``V4L2_MPEG_VIDEO_ASPECT_4x3``
-    * - ``V4L2_MPEG_VIDEO_ASPECT_16x9``
-    * - ``V4L2_MPEG_VIDEO_ASPECT_221x100``
-
-
-
-``V4L2_CID_MPEG_VIDEO_B_FRAMES (integer)``
-    Number of B-Frames (default 2)
-
-``V4L2_CID_MPEG_VIDEO_GOP_SIZE (integer)``
-    GOP size (default 12)
-
-``V4L2_CID_MPEG_VIDEO_GOP_CLOSURE (boolean)``
-    GOP closure (default 1)
-
-``V4L2_CID_MPEG_VIDEO_PULLDOWN (boolean)``
-    Enable 3:2 pulldown (default 0)
-
-.. _v4l2-mpeg-video-bitrate-mode:
-
-``V4L2_CID_MPEG_VIDEO_BITRATE_MODE``
-    (enum)
-
-enum v4l2_mpeg_video_bitrate_mode -
-    Video bitrate mode. Possible values are:
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_VIDEO_BITRATE_MODE_VBR``
-      - Variable bitrate
-    * - ``V4L2_MPEG_VIDEO_BITRATE_MODE_CBR``
-      - Constant bitrate
-
-
-
-``V4L2_CID_MPEG_VIDEO_BITRATE (integer)``
-    Video bitrate in bits per second.
-
-``V4L2_CID_MPEG_VIDEO_BITRATE_PEAK (integer)``
-    Peak video bitrate in bits per second. Must be larger or equal to
-    the average video bitrate. It is ignored if the video bitrate mode
-    is set to constant bitrate.
-
-``V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION (integer)``
-    For every captured frame, skip this many subsequent frames (default
-    0).
-
-``V4L2_CID_MPEG_VIDEO_MUTE (boolean)``
-    "Mutes" the video to a fixed color when capturing. This is useful
-    for testing, to produce a fixed video bitstream. 0 = unmuted, 1 =
-    muted.
-
-``V4L2_CID_MPEG_VIDEO_MUTE_YUV (integer)``
-    Sets the "mute" color of the video. The supplied 32-bit integer is
-    interpreted as follows (bit 0 = least significant bit):
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - Bit 0:7
-      - V chrominance information
-    * - Bit 8:15
-      - U chrominance information
-    * - Bit 16:23
-      - Y luminance information
-    * - Bit 24:31
-      - Must be zero.
-
-
-
-.. _v4l2-mpeg-video-dec-pts:
-
-``V4L2_CID_MPEG_VIDEO_DEC_PTS (integer64)``
-    This read-only control returns the 33-bit video Presentation Time
-    Stamp as defined in ITU T-REC-H.222.0 and ISO/IEC 13818-1 of the
-    currently displayed frame. This is the same PTS as is used in
-    :ref:`VIDIOC_DECODER_CMD`.
-
-.. _v4l2-mpeg-video-dec-frame:
-
-``V4L2_CID_MPEG_VIDEO_DEC_FRAME (integer64)``
-    This read-only control returns the frame counter of the frame that
-    is currently displayed (decoded). This value is reset to 0 whenever
-    the decoder is started.
-
-``V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE (boolean)``
-    If enabled the decoder expects to receive a single slice per buffer,
-    otherwise the decoder expects a single frame in per buffer.
-    Applicable to the decoder, all codecs.
-
-``V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE (boolean)``
-    Enable writing sample aspect ratio in the Video Usability
-    Information. Applicable to the H264 encoder.
-
-.. _v4l2-mpeg-video-h264-vui-sar-idc:
-
-``V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC``
-    (enum)
-
-enum v4l2_mpeg_video_h264_vui_sar_idc -
-    VUI sample aspect ratio indicator for H.264 encoding. The value is
-    defined in the table E-1 in the standard. Applicable to the H264
-    encoder.
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED``
-      - Unspecified
-    * - ``V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_1x1``
-      - 1x1
-    * - ``V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_12x11``
-      - 12x11
-    * - ``V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_10x11``
-      - 10x11
-    * - ``V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_16x11``
-      - 16x11
-    * - ``V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_40x33``
-      - 40x33
-    * - ``V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_24x11``
-      - 24x11
-    * - ``V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_20x11``
-      - 20x11
-    * - ``V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_32x11``
-      - 32x11
-    * - ``V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_80x33``
-      - 80x33
-    * - ``V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_18x11``
-      - 18x11
-    * - ``V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_15x11``
-      - 15x11
-    * - ``V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_64x33``
-      - 64x33
-    * - ``V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_160x99``
-      - 160x99
-    * - ``V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_4x3``
-      - 4x3
-    * - ``V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_3x2``
-      - 3x2
-    * - ``V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_2x1``
-      - 2x1
-    * - ``V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED``
-      - Extended SAR
-
-
-
-``V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH (integer)``
-    Extended sample aspect ratio width for H.264 VUI encoding.
-    Applicable to the H264 encoder.
-
-``V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT (integer)``
-    Extended sample aspect ratio height for H.264 VUI encoding.
-    Applicable to the H264 encoder.
-
-.. _v4l2-mpeg-video-h264-level:
-
-``V4L2_CID_MPEG_VIDEO_H264_LEVEL``
-    (enum)
-
-enum v4l2_mpeg_video_h264_level -
-    The level information for the H264 video elementary stream.
-    Applicable to the H264 encoder. Possible values are:
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_VIDEO_H264_LEVEL_1_0``
-      - Level 1.0
-    * - ``V4L2_MPEG_VIDEO_H264_LEVEL_1B``
-      - Level 1B
-    * - ``V4L2_MPEG_VIDEO_H264_LEVEL_1_1``
-      - Level 1.1
-    * - ``V4L2_MPEG_VIDEO_H264_LEVEL_1_2``
-      - Level 1.2
-    * - ``V4L2_MPEG_VIDEO_H264_LEVEL_1_3``
-      - Level 1.3
-    * - ``V4L2_MPEG_VIDEO_H264_LEVEL_2_0``
-      - Level 2.0
-    * - ``V4L2_MPEG_VIDEO_H264_LEVEL_2_1``
-      - Level 2.1
-    * - ``V4L2_MPEG_VIDEO_H264_LEVEL_2_2``
-      - Level 2.2
-    * - ``V4L2_MPEG_VIDEO_H264_LEVEL_3_0``
-      - Level 3.0
-    * - ``V4L2_MPEG_VIDEO_H264_LEVEL_3_1``
-      - Level 3.1
-    * - ``V4L2_MPEG_VIDEO_H264_LEVEL_3_2``
-      - Level 3.2
-    * - ``V4L2_MPEG_VIDEO_H264_LEVEL_4_0``
-      - Level 4.0
-    * - ``V4L2_MPEG_VIDEO_H264_LEVEL_4_1``
-      - Level 4.1
-    * - ``V4L2_MPEG_VIDEO_H264_LEVEL_4_2``
-      - Level 4.2
-    * - ``V4L2_MPEG_VIDEO_H264_LEVEL_5_0``
-      - Level 5.0
-    * - ``V4L2_MPEG_VIDEO_H264_LEVEL_5_1``
-      - Level 5.1
-
-
-
-.. _v4l2-mpeg-video-mpeg2-level:
-
-``V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL``
-    (enum)
-
-enum v4l2_mpeg_video_mpeg2_level -
-    The level information for the MPEG2 elementary stream. Applicable to
-    MPEG2 codecs. Possible values are:
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_VIDEO_MPEG2_LEVEL_LOW``
-      - Low Level (LL)
-    * - ``V4L2_MPEG_VIDEO_MPEG2_LEVEL_MAIN``
-      - Main Level (ML)
-    * - ``V4L2_MPEG_VIDEO_MPEG2_LEVEL_HIGH_1440``
-      - High-1440 Level (H-14)
-    * - ``V4L2_MPEG_VIDEO_MPEG2_LEVEL_HIGH``
-      - High Level (HL)
-
-
-
-.. _v4l2-mpeg-video-mpeg4-level:
-
-``V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL``
-    (enum)
-
-enum v4l2_mpeg_video_mpeg4_level -
-    The level information for the MPEG4 elementary stream. Applicable to
-    the MPEG4 encoder. Possible values are:
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_VIDEO_MPEG4_LEVEL_0``
-      - Level 0
-    * - ``V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B``
-      - Level 0b
-    * - ``V4L2_MPEG_VIDEO_MPEG4_LEVEL_1``
-      - Level 1
-    * - ``V4L2_MPEG_VIDEO_MPEG4_LEVEL_2``
-      - Level 2
-    * - ``V4L2_MPEG_VIDEO_MPEG4_LEVEL_3``
-      - Level 3
-    * - ``V4L2_MPEG_VIDEO_MPEG4_LEVEL_3B``
-      - Level 3b
-    * - ``V4L2_MPEG_VIDEO_MPEG4_LEVEL_4``
-      - Level 4
-    * - ``V4L2_MPEG_VIDEO_MPEG4_LEVEL_5``
-      - Level 5
-
-
-
-.. _v4l2-mpeg-video-h264-profile:
-
-``V4L2_CID_MPEG_VIDEO_H264_PROFILE``
-    (enum)
-
-enum v4l2_mpeg_video_h264_profile -
-    The profile information for H264. Applicable to the H264 encoder.
-    Possible values are:
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE``
-      - Baseline profile
-    * - ``V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE``
-      - Constrained Baseline profile
-    * - ``V4L2_MPEG_VIDEO_H264_PROFILE_MAIN``
-      - Main profile
-    * - ``V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED``
-      - Extended profile
-    * - ``V4L2_MPEG_VIDEO_H264_PROFILE_HIGH``
-      - High profile
-    * - ``V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10``
-      - High 10 profile
-    * - ``V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422``
-      - High 422 profile
-    * - ``V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE``
-      - High 444 Predictive profile
-    * - ``V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10_INTRA``
-      - High 10 Intra profile
-    * - ``V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422_INTRA``
-      - High 422 Intra profile
-    * - ``V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_INTRA``
-      - High 444 Intra profile
-    * - ``V4L2_MPEG_VIDEO_H264_PROFILE_CAVLC_444_INTRA``
-      - CAVLC 444 Intra profile
-    * - ``V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_BASELINE``
-      - Scalable Baseline profile
-    * - ``V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH``
-      - Scalable High profile
-    * - ``V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH_INTRA``
-      - Scalable High Intra profile
-    * - ``V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH``
-      - Stereo High profile
-    * - ``V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH``
-      - Multiview High profile
-
-
-
-.. _v4l2-mpeg-video-mpeg2-profile:
-
-``V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE``
-    (enum)
-
-enum v4l2_mpeg_video_mpeg2_profile -
-    The profile information for MPEG2. Applicable to MPEG2 codecs.
-    Possible values are:
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_VIDEO_MPEG2_PROFILE_SIMPLE``
-      - Simple profile (SP)
-    * - ``V4L2_MPEG_VIDEO_MPEG2_PROFILE_MAIN``
-      - Main profile (MP)
-    * - ``V4L2_MPEG_VIDEO_MPEG2_PROFILE_SNR_SCALABLE``
-      - SNR Scalable profile (SNR)
-    * - ``V4L2_MPEG_VIDEO_MPEG2_PROFILE_SPATIALLY_SCALABLE``
-      - Spatially Scalable profile (Spt)
-    * - ``V4L2_MPEG_VIDEO_MPEG2_PROFILE_HIGH``
-      - High profile (HP)
-    * - ``V4L2_MPEG_VIDEO_MPEG2_PROFILE_MULTIVIEW``
-      - Multi-view profile (MVP)
-
-
-
-.. _v4l2-mpeg-video-mpeg4-profile:
-
-``V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE``
-    (enum)
-
-enum v4l2_mpeg_video_mpeg4_profile -
-    The profile information for MPEG4. Applicable to the MPEG4 encoder.
-    Possible values are:
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE``
-      - Simple profile
-    * - ``V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE``
-      - Advanced Simple profile
-    * - ``V4L2_MPEG_VIDEO_MPEG4_PROFILE_CORE``
-      - Core profile
-    * - ``V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE_SCALABLE``
-      - Simple Scalable profile
-    * - ``V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY``
-      -
-
-
-
-``V4L2_CID_MPEG_VIDEO_MAX_REF_PIC (integer)``
-    The maximum number of reference pictures used for encoding.
-    Applicable to the encoder.
-
-.. _v4l2-mpeg-video-multi-slice-mode:
-
-``V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE``
-    (enum)
-
-enum v4l2_mpeg_video_multi_slice_mode -
-    Determines how the encoder should handle division of frame into
-    slices. Applicable to the encoder. Possible values are:
-
-
-
-.. tabularcolumns:: |p{9.6cm}|p{7.9cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE``
-      - Single slice per frame.
-    * - ``V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB``
-      - Multiple slices with set maximum number of macroblocks per slice.
-    * - ``V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES``
-      - Multiple slice with set maximum size in bytes per slice.
-
-
-
-``V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB (integer)``
-    The maximum number of macroblocks in a slice. Used when
-    ``V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE`` is set to
-    ``V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB``. Applicable to the
-    encoder.
-
-``V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES (integer)``
-    The maximum size of a slice in bytes. Used when
-    ``V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE`` is set to
-    ``V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES``. Applicable to the
-    encoder.
-
-.. _v4l2-mpeg-video-h264-loop-filter-mode:
-
-``V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE``
-    (enum)
-
-enum v4l2_mpeg_video_h264_loop_filter_mode -
-    Loop filter mode for H264 encoder. Possible values are:
-
-.. raw:: latex
-
-    \small
-
-.. tabularcolumns:: |p{13.6cm}|p{3.9cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED``
-      - Loop filter is enabled.
-    * - ``V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED``
-      - Loop filter is disabled.
-    * - ``V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY``
-      - Loop filter is disabled at the slice boundary.
-
-.. raw:: latex
-
-    \normalsize
-
-
-``V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA (integer)``
-    Loop filter alpha coefficient, defined in the H264 standard.
-    This value corresponds to the slice_alpha_c0_offset_div2 slice header
-    field, and should be in the range of -6 to +6, inclusive. The actual alpha
-    offset FilterOffsetA is twice this value.
-    Applicable to the H264 encoder.
-
-``V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA (integer)``
-    Loop filter beta coefficient, defined in the H264 standard.
-    This corresponds to the slice_beta_offset_div2 slice header field, and
-    should be in the range of -6 to +6, inclusive. The actual beta offset
-    FilterOffsetB is twice this value.
-    Applicable to the H264 encoder.
-
-.. _v4l2-mpeg-video-h264-entropy-mode:
-
-``V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE``
-    (enum)
-
-enum v4l2_mpeg_video_h264_entropy_mode -
-    Entropy coding mode for H264 - CABAC/CAVALC. Applicable to the H264
-    encoder. Possible values are:
-
-
-.. tabularcolumns:: |p{9.0cm}|p{8.5cm}|
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC``
-      - Use CAVLC entropy coding.
-    * - ``V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC``
-      - Use CABAC entropy coding.
-
-
-
-``V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM (boolean)``
-    Enable 8X8 transform for H264. Applicable to the H264 encoder.
-
-``V4L2_CID_MPEG_VIDEO_H264_CONSTRAINED_INTRA_PREDICTION (boolean)``
-    Enable constrained intra prediction for H264. Applicable to the H264
-    encoder.
-
-``V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET (integer)``
-    Specify the offset that should be added to the luma quantization
-    parameter to determine the chroma quantization parameter. Applicable
-    to the H264 encoder.
-
-``V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB (integer)``
-    Cyclic intra macroblock refresh. This is the number of continuous
-    macroblocks refreshed every frame. Each frame a successive set of
-    macroblocks is refreshed until the cycle completes and starts from
-    the top of the frame. Applicable to H264, H263 and MPEG4 encoder.
-
-``V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE (boolean)``
-    Frame level rate control enable. If this control is disabled then
-    the quantization parameter for each frame type is constant and set
-    with appropriate controls (e.g.
-    ``V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP``). If frame rate control is
-    enabled then quantization parameter is adjusted to meet the chosen
-    bitrate. Minimum and maximum value for the quantization parameter
-    can be set with appropriate controls (e.g.
-    ``V4L2_CID_MPEG_VIDEO_H263_MIN_QP``). Applicable to encoders.
-
-``V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE (boolean)``
-    Macroblock level rate control enable. Applicable to the MPEG4 and
-    H264 encoders.
-
-``V4L2_CID_MPEG_VIDEO_MPEG4_QPEL (boolean)``
-    Quarter pixel motion estimation for MPEG4. Applicable to the MPEG4
-    encoder.
-
-``V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP (integer)``
-    Quantization parameter for an I frame for H263. Valid range: from 1
-    to 31.
-
-``V4L2_CID_MPEG_VIDEO_H263_MIN_QP (integer)``
-    Minimum quantization parameter for H263. Valid range: from 1 to 31.
-
-``V4L2_CID_MPEG_VIDEO_H263_MAX_QP (integer)``
-    Maximum quantization parameter for H263. Valid range: from 1 to 31.
-
-``V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP (integer)``
-    Quantization parameter for an P frame for H263. Valid range: from 1
-    to 31.
-
-``V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP (integer)``
-    Quantization parameter for an B frame for H263. Valid range: from 1
-    to 31.
-
-``V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP (integer)``
-    Quantization parameter for an I frame for H264. Valid range: from 0
-    to 51.
-
-``V4L2_CID_MPEG_VIDEO_H264_MIN_QP (integer)``
-    Minimum quantization parameter for H264. Valid range: from 0 to 51.
-
-``V4L2_CID_MPEG_VIDEO_H264_MAX_QP (integer)``
-    Maximum quantization parameter for H264. Valid range: from 0 to 51.
-
-``V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP (integer)``
-    Quantization parameter for an P frame for H264. Valid range: from 0
-    to 51.
-
-``V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP (integer)``
-    Quantization parameter for an B frame for H264. Valid range: from 0
-    to 51.
-
-``V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MIN_QP (integer)``
-    Minimum quantization parameter for the H264 I frame to limit I frame
-    quality to a range. Valid range: from 0 to 51. If
-    V4L2_CID_MPEG_VIDEO_H264_MIN_QP is also set, the quantization parameter
-    should be chosen to meet both requirements.
-
-``V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MAX_QP (integer)``
-    Maximum quantization parameter for the H264 I frame to limit I frame
-    quality to a range. Valid range: from 0 to 51. If
-    V4L2_CID_MPEG_VIDEO_H264_MAX_QP is also set, the quantization parameter
-    should be chosen to meet both requirements.
-
-``V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP (integer)``
-    Minimum quantization parameter for the H264 P frame to limit P frame
-    quality to a range. Valid range: from 0 to 51. If
-    V4L2_CID_MPEG_VIDEO_H264_MIN_QP is also set, the quantization parameter
-    should be chosen to meet both requirements.
-
-``V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP (integer)``
-    Maximum quantization parameter for the H264 P frame to limit P frame
-    quality to a range. Valid range: from 0 to 51. If
-    V4L2_CID_MPEG_VIDEO_H264_MAX_QP is also set, the quantization parameter
-    should be chosen to meet both requirements.
-
-``V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP (integer)``
-    Quantization parameter for an I frame for MPEG4. Valid range: from 1
-    to 31.
-
-``V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP (integer)``
-    Minimum quantization parameter for MPEG4. Valid range: from 1 to 31.
-
-``V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP (integer)``
-    Maximum quantization parameter for MPEG4. Valid range: from 1 to 31.
-
-``V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP (integer)``
-    Quantization parameter for an P frame for MPEG4. Valid range: from 1
-    to 31.
-
-``V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP (integer)``
-    Quantization parameter for an B frame for MPEG4. Valid range: from 1
-    to 31.
-
-``V4L2_CID_MPEG_VIDEO_VBV_SIZE (integer)``
-    The Video Buffer Verifier size in kilobytes, it is used as a
-    limitation of frame skip. The VBV is defined in the standard as a
-    mean to verify that the produced stream will be successfully
-    decoded. The standard describes it as "Part of a hypothetical
-    decoder that is conceptually connected to the output of the encoder.
-    Its purpose is to provide a constraint on the variability of the
-    data rate that an encoder or editing process may produce.".
-    Applicable to the MPEG1, MPEG2, MPEG4 encoders.
-
-.. _v4l2-mpeg-video-vbv-delay:
-
-``V4L2_CID_MPEG_VIDEO_VBV_DELAY (integer)``
-    Sets the initial delay in milliseconds for VBV buffer control.
-
-.. _v4l2-mpeg-video-hor-search-range:
-
-``V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE (integer)``
-    Horizontal search range defines maximum horizontal search area in
-    pixels to search and match for the present Macroblock (MB) in the
-    reference picture. This V4L2 control macro is used to set horizontal
-    search range for motion estimation module in video encoder.
-
-.. _v4l2-mpeg-video-vert-search-range:
-
-``V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE (integer)``
-    Vertical search range defines maximum vertical search area in pixels
-    to search and match for the present Macroblock (MB) in the reference
-    picture. This V4L2 control macro is used to set vertical search
-    range for motion estimation module in video encoder.
-
-.. _v4l2-mpeg-video-force-key-frame:
-
-``V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME (button)``
-    Force a key frame for the next queued buffer. Applicable to
-    encoders. This is a general, codec-agnostic keyframe control.
-
-``V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE (integer)``
-    The Coded Picture Buffer size in kilobytes, it is used as a
-    limitation of frame skip. The CPB is defined in the H264 standard as
-    a mean to verify that the produced stream will be successfully
-    decoded. Applicable to the H264 encoder.
-
-``V4L2_CID_MPEG_VIDEO_H264_I_PERIOD (integer)``
-    Period between I-frames in the open GOP for H264. In case of an open
-    GOP this is the period between two I-frames. The period between IDR
-    (Instantaneous Decoding Refresh) frames is taken from the GOP_SIZE
-    control. An IDR frame, which stands for Instantaneous Decoding
-    Refresh is an I-frame after which no prior frames are referenced.
-    This means that a stream can be restarted from an IDR frame without
-    the need to store or decode any previous frames. Applicable to the
-    H264 encoder.
-
-.. _v4l2-mpeg-video-header-mode:
-
-``V4L2_CID_MPEG_VIDEO_HEADER_MODE``
-    (enum)
-
-enum v4l2_mpeg_video_header_mode -
-    Determines whether the header is returned as the first buffer or is
-    it returned together with the first frame. Applicable to encoders.
-    Possible values are:
-
-.. raw:: latex
-
-    \small
-
-.. tabularcolumns:: |p{10.3cm}|p{7.2cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE``
-      - The stream header is returned separately in the first buffer.
-    * - ``V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME``
-      - The stream header is returned together with the first encoded
-	frame.
-
-.. raw:: latex
-
-    \normalsize
-
-
-``V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER (boolean)``
-    Repeat the video sequence headers. Repeating these headers makes
-    random access to the video stream easier. Applicable to the MPEG1, 2
-    and 4 encoder.
-
-``V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER (boolean)``
-    Enabled the deblocking post processing filter for MPEG4 decoder.
-    Applicable to the MPEG4 decoder.
-
-``V4L2_CID_MPEG_VIDEO_MPEG4_VOP_TIME_RES (integer)``
-    vop_time_increment_resolution value for MPEG4. Applicable to the
-    MPEG4 encoder.
-
-``V4L2_CID_MPEG_VIDEO_MPEG4_VOP_TIME_INC (integer)``
-    vop_time_increment value for MPEG4. Applicable to the MPEG4
-    encoder.
-
-``V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING (boolean)``
-    Enable generation of frame packing supplemental enhancement
-    information in the encoded bitstream. The frame packing SEI message
-    contains the arrangement of L and R planes for 3D viewing.
-    Applicable to the H264 encoder.
-
-``V4L2_CID_MPEG_VIDEO_H264_SEI_FP_CURRENT_FRAME_0 (boolean)``
-    Sets current frame as frame0 in frame packing SEI. Applicable to the
-    H264 encoder.
-
-.. _v4l2-mpeg-video-h264-sei-fp-arrangement-type:
-
-``V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE``
-    (enum)
-
-enum v4l2_mpeg_video_h264_sei_fp_arrangement_type -
-    Frame packing arrangement type for H264 SEI. Applicable to the H264
-    encoder. Possible values are:
-
-.. raw:: latex
-
-    \small
-
-.. tabularcolumns:: |p{12cm}|p{5.5cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_CHEKERBOARD``
-      - Pixels are alternatively from L and R.
-    * - ``V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_COLUMN``
-      - L and R are interlaced by column.
-    * - ``V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_ROW``
-      - L and R are interlaced by row.
-    * - ``V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_SIDE_BY_SIDE``
-      - L is on the left, R on the right.
-    * - ``V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_TOP_BOTTOM``
-      - L is on top, R on bottom.
-    * - ``V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_TEMPORAL``
-      - One view per frame.
-
-.. raw:: latex
-
-    \normalsize
-
-
-
-``V4L2_CID_MPEG_VIDEO_H264_FMO (boolean)``
-    Enables flexible macroblock ordering in the encoded bitstream. It is
-    a technique used for restructuring the ordering of macroblocks in
-    pictures. Applicable to the H264 encoder.
-
-.. _v4l2-mpeg-video-h264-fmo-map-type:
-
-``V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE``
-   (enum)
-
-enum v4l2_mpeg_video_h264_fmo_map_type -
-    When using FMO, the map type divides the image in different scan
-    patterns of macroblocks. Applicable to the H264 encoder. Possible
-    values are:
-
-.. raw:: latex
-
-    \small
-
-.. tabularcolumns:: |p{12.5cm}|p{5.0cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_INTERLEAVED_SLICES``
-      - Slices are interleaved one after other with macroblocks in run
-	length order.
-    * - ``V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_SCATTERED_SLICES``
-      - Scatters the macroblocks based on a mathematical function known to
-	both encoder and decoder.
-    * - ``V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_FOREGROUND_WITH_LEFT_OVER``
-      - Macroblocks arranged in rectangular areas or regions of interest.
-    * - ``V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_BOX_OUT``
-      - Slice groups grow in a cyclic way from centre to outwards.
-    * - ``V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_RASTER_SCAN``
-      - Slice groups grow in raster scan pattern from left to right.
-    * - ``V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_WIPE_SCAN``
-      - Slice groups grow in wipe scan pattern from top to bottom.
-    * - ``V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_EXPLICIT``
-      - User defined map type.
-
-.. raw:: latex
-
-    \normalsize
-
-
-
-``V4L2_CID_MPEG_VIDEO_H264_FMO_SLICE_GROUP (integer)``
-    Number of slice groups in FMO. Applicable to the H264 encoder.
-
-.. _v4l2-mpeg-video-h264-fmo-change-direction:
-
-``V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_DIRECTION``
-    (enum)
-
-enum v4l2_mpeg_video_h264_fmo_change_dir -
-    Specifies a direction of the slice group change for raster and wipe
-    maps. Applicable to the H264 encoder. Possible values are:
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_VIDEO_H264_FMO_CHANGE_DIR_RIGHT``
-      - Raster scan or wipe right.
-    * - ``V4L2_MPEG_VIDEO_H264_FMO_CHANGE_DIR_LEFT``
-      - Reverse raster scan or wipe left.
-
-
-
-``V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_RATE (integer)``
-    Specifies the size of the first slice group for raster and wipe map.
-    Applicable to the H264 encoder.
-
-``V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH (integer)``
-    Specifies the number of consecutive macroblocks for the interleaved
-    map. Applicable to the H264 encoder.
-
-``V4L2_CID_MPEG_VIDEO_H264_ASO (boolean)``
-    Enables arbitrary slice ordering in encoded bitstream. Applicable to
-    the H264 encoder.
-
-``V4L2_CID_MPEG_VIDEO_H264_ASO_SLICE_ORDER (integer)``
-    Specifies the slice order in ASO. Applicable to the H264 encoder.
-    The supplied 32-bit integer is interpreted as follows (bit 0 = least
-    significant bit):
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - Bit 0:15
-      - Slice ID
-    * - Bit 16:32
-      - Slice position or order
-
-
-
-``V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING (boolean)``
-    Enables H264 hierarchical coding. Applicable to the H264 encoder.
-
-.. _v4l2-mpeg-video-h264-hierarchical-coding-type:
-
-``V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE``
-    (enum)
-
-enum v4l2_mpeg_video_h264_hierarchical_coding_type -
-    Specifies the hierarchical coding type. Applicable to the H264
-    encoder. Possible values are:
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B``
-      - Hierarchical B coding.
-    * - ``V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P``
-      - Hierarchical P coding.
-
-
-
-``V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER (integer)``
-    Specifies the number of hierarchical coding layers. Applicable to
-    the H264 encoder.
-
-``V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP (integer)``
-    Specifies a user defined QP for each layer. Applicable to the H264
-    encoder. The supplied 32-bit integer is interpreted as follows (bit
-    0 = least significant bit):
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - Bit 0:15
-      - QP value
-    * - Bit 16:32
-      - Layer number
-
-
-.. _v4l2-mpeg-h264:
-
-``V4L2_CID_MPEG_VIDEO_H264_SPS (struct)``
-    Specifies the sequence parameter set (as extracted from the
-    bitstream) for the associated H264 slice data. This includes the
-    necessary parameters for configuring a stateless hardware decoding
-    pipeline for H264. The bitstream parameters are defined according
-    to :ref:`h264`, section 7.4.2.1.1 "Sequence Parameter Set Data
-    Semantics". For further documentation, refer to the above
-    specification, unless there is an explicit comment stating
-    otherwise.
-
-    .. note::
-
-       This compound control is not yet part of the public kernel API and
-       it is expected to change.
-
-.. c:type:: v4l2_ctrl_h264_sps
-
-.. cssclass:: longtable
-
-.. flat-table:: struct v4l2_ctrl_h264_sps
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u8
-      - ``profile_idc``
-      -
-    * - __u8
-      - ``constraint_set_flags``
-      - See :ref:`Sequence Parameter Set Constraints Set Flags <h264_sps_constraints_set_flags>`
-    * - __u8
-      - ``level_idc``
-      -
-    * - __u8
-      - ``seq_parameter_set_id``
-      -
-    * - __u8
-      - ``chroma_format_idc``
-      -
-    * - __u8
-      - ``bit_depth_luma_minus8``
-      -
-    * - __u8
-      - ``bit_depth_chroma_minus8``
-      -
-    * - __u8
-      - ``log2_max_frame_num_minus4``
-      -
-    * - __u8
-      - ``pic_order_cnt_type``
-      -
-    * - __u8
-      - ``log2_max_pic_order_cnt_lsb_minus4``
-      -
-    * - __u8
-      - ``max_num_ref_frames``
-      -
-    * - __u8
-      - ``num_ref_frames_in_pic_order_cnt_cycle``
-      -
-    * - __s32
-      - ``offset_for_ref_frame[255]``
-      -
-    * - __s32
-      - ``offset_for_non_ref_pic``
-      -
-    * - __s32
-      - ``offset_for_top_to_bottom_field``
-      -
-    * - __u16
-      - ``pic_width_in_mbs_minus1``
-      -
-    * - __u16
-      - ``pic_height_in_map_units_minus1``
-      -
-    * - __u32
-      - ``flags``
-      - See :ref:`Sequence Parameter Set Flags <h264_sps_flags>`
-
-.. _h264_sps_constraints_set_flags:
-
-``Sequence Parameter Set Constraints Set Flags``
-
-.. cssclass:: longtable
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - ``V4L2_H264_SPS_CONSTRAINT_SET0_FLAG``
-      - 0x00000001
-      -
-    * - ``V4L2_H264_SPS_CONSTRAINT_SET1_FLAG``
-      - 0x00000002
-      -
-    * - ``V4L2_H264_SPS_CONSTRAINT_SET2_FLAG``
-      - 0x00000004
-      -
-    * - ``V4L2_H264_SPS_CONSTRAINT_SET3_FLAG``
-      - 0x00000008
-      -
-    * - ``V4L2_H264_SPS_CONSTRAINT_SET4_FLAG``
-      - 0x00000010
-      -
-    * - ``V4L2_H264_SPS_CONSTRAINT_SET5_FLAG``
-      - 0x00000020
-      -
-
-.. _h264_sps_flags:
-
-``Sequence Parameter Set Flags``
-
-.. cssclass:: longtable
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - ``V4L2_H264_SPS_FLAG_SEPARATE_COLOUR_PLANE``
-      - 0x00000001
-      -
-    * - ``V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS``
-      - 0x00000002
-      -
-    * - ``V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO``
-      - 0x00000004
-      -
-    * - ``V4L2_H264_SPS_FLAG_GAPS_IN_FRAME_NUM_VALUE_ALLOWED``
-      - 0x00000008
-      -
-    * - ``V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY``
-      - 0x00000010
-      -
-    * - ``V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD``
-      - 0x00000020
-      -
-    * - ``V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE``
-      - 0x00000040
-      -
-
-``V4L2_CID_MPEG_VIDEO_H264_PPS (struct)``
-    Specifies the picture parameter set (as extracted from the
-    bitstream) for the associated H264 slice data. This includes the
-    necessary parameters for configuring a stateless hardware decoding
-    pipeline for H264.  The bitstream parameters are defined according
-    to :ref:`h264`, section 7.4.2.2 "Picture Parameter Set RBSP
-    Semantics". For further documentation, refer to the above
-    specification, unless there is an explicit comment stating
-    otherwise.
-
-    .. note::
-
-       This compound control is not yet part of the public kernel API and
-       it is expected to change.
-
-.. c:type:: v4l2_ctrl_h264_pps
-
-.. cssclass:: longtable
-
-.. flat-table:: struct v4l2_ctrl_h264_pps
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u8
-      - ``pic_parameter_set_id``
-      -
-    * - __u8
-      - ``seq_parameter_set_id``
-      -
-    * - __u8
-      - ``num_slice_groups_minus1``
-      -
-    * - __u8
-      - ``num_ref_idx_l0_default_active_minus1``
-      -
-    * - __u8
-      - ``num_ref_idx_l1_default_active_minus1``
-      -
-    * - __u8
-      - ``weighted_bipred_idc``
-      -
-    * - __s8
-      - ``pic_init_qp_minus26``
-      -
-    * - __s8
-      - ``pic_init_qs_minus26``
-      -
-    * - __s8
-      - ``chroma_qp_index_offset``
-      -
-    * - __s8
-      - ``second_chroma_qp_index_offset``
-      -
-    * - __u16
-      - ``flags``
-      - See :ref:`Picture Parameter Set Flags <h264_pps_flags>`
-
-.. _h264_pps_flags:
-
-``Picture Parameter Set Flags``
-
-.. cssclass:: longtable
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - ``V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE``
-      - 0x00000001
-      -
-    * - ``V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT``
-      - 0x00000002
-      -
-    * - ``V4L2_H264_PPS_FLAG_WEIGHTED_PRED``
-      - 0x00000004
-      -
-    * - ``V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT``
-      - 0x00000008
-      -
-    * - ``V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED``
-      - 0x00000010
-      -
-    * - ``V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT``
-      - 0x00000020
-      -
-    * - ``V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE``
-      - 0x00000040
-      -
-    * - ``V4L2_H264_PPS_FLAG_PIC_SCALING_MATRIX_PRESENT``
-      - 0x00000080
-      -
-
-``V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX (struct)``
-    Specifies the scaling matrix (as extracted from the bitstream) for
-    the associated H264 slice data. The bitstream parameters are
-    defined according to :ref:`h264`, section 7.4.2.1.1.1 "Scaling
-    List Semantics". For further documentation, refer to the above
-    specification, unless there is an explicit comment stating
-    otherwise.
-
-    .. note::
-
-       This compound control is not yet part of the public kernel API and
-       it is expected to change.
-
-.. c:type:: v4l2_ctrl_h264_scaling_matrix
-
-.. cssclass:: longtable
-
-.. flat-table:: struct v4l2_ctrl_h264_scaling_matrix
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u8
-      - ``scaling_list_4x4[6][16]``
-      - Scaling matrix after applying the inverse scanning process.
-        Expected list order is Intra Y, Intra Cb, Intra Cr, Inter Y,
-        Inter Cb, Inter Cr.
-    * - __u8
-      - ``scaling_list_8x8[6][64]``
-      - Scaling matrix after applying the inverse scanning process.
-        Expected list order is Intra Y, Inter Y, Intra Cb, Inter Cb,
-        Intra Cr, Inter Cr.
-
-``V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS (struct)``
-    Specifies the slice parameters (as extracted from the bitstream)
-    for the associated H264 slice data. This includes the necessary
-    parameters for configuring a stateless hardware decoding pipeline
-    for H264.  The bitstream parameters are defined according to
-    :ref:`h264`, section 7.4.3 "Slice Header Semantics". For further
-    documentation, refer to the above specification, unless there is
-    an explicit comment stating otherwise.
-
-    .. note::
-
-       This compound control is not yet part of the public kernel API
-       and it is expected to change.
-
-       This structure is expected to be passed as an array, with one
-       entry for each slice included in the bitstream buffer.
-
-.. c:type:: v4l2_ctrl_h264_slice_params
-
-.. cssclass:: longtable
-
-.. flat-table:: struct v4l2_ctrl_h264_slice_params
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``size``
-      -
-    * - __u32
-      - ``start_byte_offset``
-        Offset (in bytes) from the beginning of the OUTPUT buffer to the start
-        of the slice. If the slice starts with a start code, then this is the
-        offset to such start code. When operating in slice-based decoding mode
-        (see :c:type:`v4l2_mpeg_video_h264_decode_mode`), this field should
-        be set to 0. When operating in frame-based decoding mode, this field
-        should be 0 for the first slice.
-    * - __u32
-      - ``header_bit_size``
-      -
-    * - __u16
-      - ``first_mb_in_slice``
-      -
-    * - __u8
-      - ``slice_type``
-      -
-    * - __u8
-      - ``pic_parameter_set_id``
-      -
-    * - __u8
-      - ``colour_plane_id``
-      -
-    * - __u8
-      - ``redundant_pic_cnt``
-      -
-    * - __u16
-      - ``frame_num``
-      -
-    * - __u16
-      - ``idr_pic_id``
-      -
-    * - __u16
-      - ``pic_order_cnt_lsb``
-      -
-    * - __s32
-      - ``delta_pic_order_cnt_bottom``
-      -
-    * - __s32
-      - ``delta_pic_order_cnt0``
-      -
-    * - __s32
-      - ``delta_pic_order_cnt1``
-      -
-    * - struct :c:type:`v4l2_h264_pred_weight_table`
-      - ``pred_weight_table``
-      -
-    * - __u32
-      - ``dec_ref_pic_marking_bit_size``
-      - Size in bits of the dec_ref_pic_marking() syntax element.
-    * - __u32
-      - ``pic_order_cnt_bit_size``
-      -
-    * - __u8
-      - ``cabac_init_idc``
-      -
-    * - __s8
-      - ``slice_qp_delta``
-      -
-    * - __s8
-      - ``slice_qs_delta``
-      -
-    * - __u8
-      - ``disable_deblocking_filter_idc``
-      -
-    * - __s8
-      - ``slice_alpha_c0_offset_div2``
-      -
-    * - __s8
-      - ``slice_beta_offset_div2``
-      -
-    * - __u8
-      - ``num_ref_idx_l0_active_minus1``
-      - If num_ref_idx_active_override_flag is not set, this field must be
-        set to the value of num_ref_idx_l0_default_active_minus1.
-    * - __u8
-      - ``num_ref_idx_l1_active_minus1``
-      - If num_ref_idx_active_override_flag is not set, this field must be
-        set to the value of num_ref_idx_l1_default_active_minus1.
-    * - __u32
-      - ``slice_group_change_cycle``
-      -
-    * - __u8
-      - ``ref_pic_list0[32]``
-      - Reference picture list after applying the per-slice modifications
-    * - __u8
-      - ``ref_pic_list1[32]``
-      - Reference picture list after applying the per-slice modifications
-    * - __u32
-      - ``flags``
-      - See :ref:`Slice Parameter Flags <h264_slice_flags>`
-
-.. _h264_slice_flags:
-
-``Slice Parameter Set Flags``
-
-.. cssclass:: longtable
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - ``V4L2_H264_SLICE_FLAG_FIELD_PIC``
-      - 0x00000001
-      -
-    * - ``V4L2_H264_SLICE_FLAG_BOTTOM_FIELD``
-      - 0x00000002
-      -
-    * - ``V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED``
-      - 0x00000004
-      -
-    * - ``V4L2_H264_SLICE_FLAG_SP_FOR_SWITCH``
-      - 0x00000008
-      -
-
-``Prediction Weight Table``
-
-    The bitstream parameters are defined according to :ref:`h264`,
-    section 7.4.3.2 "Prediction Weight Table Semantics". For further
-    documentation, refer to the above specification, unless there is
-    an explicit comment stating otherwise.
-
-.. c:type:: v4l2_h264_pred_weight_table
-
-.. cssclass:: longtable
-
-.. flat-table:: struct v4l2_h264_pred_weight_table
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u16
-      - ``luma_log2_weight_denom``
-      -
-    * - __u16
-      - ``chroma_log2_weight_denom``
-      -
-    * - struct :c:type:`v4l2_h264_weight_factors`
-      - ``weight_factors[2]``
-      - The weight factors at index 0 are the weight factors for the reference
-        list 0, the one at index 1 for the reference list 1.
-
-.. c:type:: v4l2_h264_weight_factors
-
-.. cssclass:: longtable
-
-.. flat-table:: struct v4l2_h264_weight_factors
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __s16
-      - ``luma_weight[32]``
-      -
-    * - __s16
-      - ``luma_offset[32]``
-      -
-    * - __s16
-      - ``chroma_weight[32][2]``
-      -
-    * - __s16
-      - ``chroma_offset[32][2]``
-      -
-
-``V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS (struct)``
-    Specifies the decode parameters (as extracted from the bitstream)
-    for the associated H264 slice data. This includes the necessary
-    parameters for configuring a stateless hardware decoding pipeline
-    for H264. The bitstream parameters are defined according to
-    :ref:`h264`. For further documentation, refer to the above
-    specification, unless there is an explicit comment stating
-    otherwise.
-
-    .. note::
-
-       This compound control is not yet part of the public kernel API and
-       it is expected to change.
-
-.. c:type:: v4l2_ctrl_h264_decode_params
-
-.. cssclass:: longtable
-
-.. flat-table:: struct v4l2_ctrl_h264_decode_params
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - struct :c:type:`v4l2_h264_dpb_entry`
-      - ``dpb[16]``
-      -
-    * - __u16
-      - ``num_slices``
-      - Number of slices needed to decode the current frame/field. When
-        operating in slice-based decoding mode (see
-        :c:type:`v4l2_mpeg_video_h264_decode_mode`), this field
-        should always be set to one.
-    * - __u16
-      - ``nal_ref_idc``
-      - NAL reference ID value coming from the NAL Unit header
-    * - __s32
-      - ``top_field_order_cnt``
-      - Picture Order Count for the coded top field
-    * - __s32
-      - ``bottom_field_order_cnt``
-      - Picture Order Count for the coded bottom field
-    * - __u32
-      - ``flags``
-      - See :ref:`Decode Parameters Flags <h264_decode_params_flags>`
-
-.. _h264_decode_params_flags:
-
-``Decode Parameters Flags``
-
-.. cssclass:: longtable
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - ``V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC``
-      - 0x00000001
-      - That picture is an IDR picture
-
-.. c:type:: v4l2_h264_dpb_entry
-
-.. cssclass:: longtable
-
-.. flat-table:: struct v4l2_h264_dpb_entry
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u64
-      - ``reference_ts``
-      - Timestamp of the V4L2 capture buffer to use as reference, used
-        with B-coded and P-coded frames. The timestamp refers to the
-        ``timestamp`` field in struct :c:type:`v4l2_buffer`. Use the
-        :c:func:`v4l2_timeval_to_ns()` function to convert the struct
-        :c:type:`timeval` in struct :c:type:`v4l2_buffer` to a __u64.
-    * - __u16
-      - ``frame_num``
-      -
-    * - __u16
-      - ``pic_num``
-      -
-    * - __s32
-      - ``top_field_order_cnt``
-      -
-    * - __s32
-      - ``bottom_field_order_cnt``
-      -
-    * - __u32
-      - ``flags``
-      - See :ref:`DPB Entry Flags <h264_dpb_flags>`
-
-.. _h264_dpb_flags:
-
-``DPB Entries Flags``
-
-.. cssclass:: longtable
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - ``V4L2_H264_DPB_ENTRY_FLAG_VALID``
-      - 0x00000001
-      - The DPB entry is valid and should be considered
-    * - ``V4L2_H264_DPB_ENTRY_FLAG_ACTIVE``
-      - 0x00000002
-      - The DPB entry is currently being used as a reference frame
-    * - ``V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM``
-      - 0x00000004
-      - The DPB entry is a long term reference frame
-    * - ``V4L2_H264_DPB_ENTRY_FLAG_FIELD``
-      - 0x00000008
-      - The DPB entry is a field reference, which means only one of the field
-        will be used when decoding the new frame/field. When not set the DPB
-        entry is a frame reference (both fields will be used). Note that this
-        flag does not say anything about the number of fields contained in the
-        reference frame, it just describes the one used to decode the new
-        field/frame
-    * - ``V4L2_H264_DPB_ENTRY_FLAG_BOTTOM_FIELD``
-      - 0x00000010
-      - The DPB entry is a bottom field reference (only the bottom field of the
-        reference frame is needed to decode the new frame/field). Only valid if
-        V4L2_H264_DPB_ENTRY_FLAG_FIELD is set. When
-        V4L2_H264_DPB_ENTRY_FLAG_FIELD is set but
-        V4L2_H264_DPB_ENTRY_FLAG_BOTTOM_FIELD is not, that means the
-        DPB entry is a top field reference
-
-``V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE (enum)``
-    Specifies the decoding mode to use. Currently exposes slice-based and
-    frame-based decoding but new modes might be added later on.
-    This control is used as a modifier for V4L2_PIX_FMT_H264_SLICE
-    pixel format. Applications that support V4L2_PIX_FMT_H264_SLICE
-    are required to set this control in order to specify the decoding mode
-    that is expected for the buffer.
-    Drivers may expose a single or multiple decoding modes, depending
-    on what they can support.
-
-    .. note::
-
-       This menu control is not yet part of the public kernel API and
-       it is expected to change.
-
-.. c:type:: v4l2_mpeg_video_h264_decode_mode
-
-.. cssclass:: longtable
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - ``V4L2_MPEG_VIDEO_H264_DECODE_MODE_SLICE_BASED``
-      - 0
-      - Decoding is done at the slice granularity.
-        In this mode, ``num_slices`` field in struct
-        :c:type:`v4l2_ctrl_h264_decode_params` should be set to 1,
-        and ``start_byte_offset`` in struct
-        :c:type:`v4l2_ctrl_h264_slice_params` should be set to 0.
-        The OUTPUT buffer must contain a single slice.
-    * - ``V4L2_MPEG_VIDEO_H264_DECODE_MODE_FRAME_BASED``
-      - 1
-      - Decoding is done at the frame granularity.
-        In this mode, ``num_slices`` field in struct
-        :c:type:`v4l2_ctrl_h264_decode_params` should be set to the number
-        of slices in the frame, and ``start_byte_offset`` in struct
-        :c:type:`v4l2_ctrl_h264_slice_params` should be set accordingly
-        for each slice. For the first slice, ``start_byte_offset`` should
-        be zero.
-        The OUTPUT buffer must contain all slices needed to decode the
-        frame. The OUTPUT buffer must also contain both fields.
-
-``V4L2_CID_MPEG_VIDEO_H264_START_CODE (enum)``
-    Specifies the H264 slice start code expected for each slice.
-    This control is used as a modifier for V4L2_PIX_FMT_H264_SLICE
-    pixel format. Applications that support V4L2_PIX_FMT_H264_SLICE
-    are required to set this control in order to specify the start code
-    that is expected for the buffer.
-    Drivers may expose a single or multiple start codes, depending
-    on what they can support.
-
-    .. note::
-
-       This menu control is not yet part of the public kernel API and
-       it is expected to change.
-
-.. c:type:: v4l2_mpeg_video_h264_start_code
-
-.. cssclass:: longtable
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - ``V4L2_MPEG_VIDEO_H264_START_CODE_NONE``
-      - 0
-      - Selecting this value specifies that H264 slices are passed
-        to the driver without any start code.
-    * - ``V4L2_MPEG_VIDEO_H264_START_CODE_ANNEX_B``
-      - 1
-      - Selecting this value specifies that H264 slices are expected
-        to be prefixed by Annex B start codes. According to :ref:`h264`
-        valid start codes can be 3-bytes 0x000001 or 4-bytes 0x00000001.
-
-.. _v4l2-mpeg-mpeg2:
-
-``V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS (struct)``
-    Specifies the slice parameters (as extracted from the bitstream) for the
-    associated MPEG-2 slice data. This includes the necessary parameters for
-    configuring a stateless hardware decoding pipeline for MPEG-2.
-    The bitstream parameters are defined according to :ref:`mpeg2part2`.
-
-    .. note::
-
-       This compound control is not yet part of the public kernel API and
-       it is expected to change.
-
-.. c:type:: v4l2_ctrl_mpeg2_slice_params
-
-.. cssclass:: longtable
-
-.. tabularcolumns:: |p{5.8cm}|p{4.8cm}|p{6.6cm}|
-
-.. flat-table:: struct v4l2_ctrl_mpeg2_slice_params
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``bit_size``
-      - Size (in bits) of the current slice data.
-    * - __u32
-      - ``data_bit_offset``
-      - Offset (in bits) to the video data in the current slice data.
-    * - struct :c:type:`v4l2_mpeg2_sequence`
-      - ``sequence``
-      - Structure with MPEG-2 sequence metadata, merging relevant fields from
-	the sequence header and sequence extension parts of the bitstream.
-    * - struct :c:type:`v4l2_mpeg2_picture`
-      - ``picture``
-      - Structure with MPEG-2 picture metadata, merging relevant fields from
-	the picture header and picture coding extension parts of the bitstream.
-    * - __u64
-      - ``backward_ref_ts``
-      - Timestamp of the V4L2 capture buffer to use as backward reference, used
-        with B-coded and P-coded frames. The timestamp refers to the
-	``timestamp`` field in struct :c:type:`v4l2_buffer`. Use the
-	:c:func:`v4l2_timeval_to_ns()` function to convert the struct
-	:c:type:`timeval` in struct :c:type:`v4l2_buffer` to a __u64.
-    * - __u64
-      - ``forward_ref_ts``
-      - Timestamp for the V4L2 capture buffer to use as forward reference, used
-        with B-coded frames. The timestamp refers to the ``timestamp`` field in
-	struct :c:type:`v4l2_buffer`. Use the :c:func:`v4l2_timeval_to_ns()`
-	function to convert the struct :c:type:`timeval` in struct
-	:c:type:`v4l2_buffer` to a __u64.
-    * - __u32
-      - ``quantiser_scale_code``
-      - Code used to determine the quantization scale to use for the IDCT.
-
-.. c:type:: v4l2_mpeg2_sequence
-
-.. cssclass:: longtable
-
-.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
-
-.. flat-table:: struct v4l2_mpeg2_sequence
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u16
-      - ``horizontal_size``
-      - The width of the displayable part of the frame's luminance component.
-    * - __u16
-      - ``vertical_size``
-      - The height of the displayable part of the frame's luminance component.
-    * - __u32
-      - ``vbv_buffer_size``
-      - Used to calculate the required size of the video buffering verifier,
-	defined (in bits) as: 16 * 1024 * vbv_buffer_size.
-    * - __u16
-      - ``profile_and_level_indication``
-      - The current profile and level indication as extracted from the
-	bitstream.
-    * - __u8
-      - ``progressive_sequence``
-      - Indication that all the frames for the sequence are progressive instead
-	of interlaced.
-    * - __u8
-      - ``chroma_format``
-      - The chrominance sub-sampling format (1: 4:2:0, 2: 4:2:2, 3: 4:4:4).
-
-.. c:type:: v4l2_mpeg2_picture
-
-.. cssclass:: longtable
-
-.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
-
-.. flat-table:: struct v4l2_mpeg2_picture
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u8
-      - ``picture_coding_type``
-      - Picture coding type for the frame covered by the current slice
-	(V4L2_MPEG2_PICTURE_CODING_TYPE_I, V4L2_MPEG2_PICTURE_CODING_TYPE_P or
-	V4L2_MPEG2_PICTURE_CODING_TYPE_B).
-    * - __u8
-      - ``f_code[2][2]``
-      - Motion vector codes.
-    * - __u8
-      - ``intra_dc_precision``
-      - Precision of Discrete Cosine transform (0: 8 bits precision,
-	1: 9 bits precision, 2: 10 bits precision, 3: 11 bits precision).
-    * - __u8
-      - ``picture_structure``
-      - Picture structure (1: interlaced top field, 2: interlaced bottom field,
-	3: progressive frame).
-    * - __u8
-      - ``top_field_first``
-      - If set to 1 and interlaced stream, top field is output first.
-    * - __u8
-      - ``frame_pred_frame_dct``
-      - If set to 1, only frame-DCT and frame prediction are used.
-    * - __u8
-      - ``concealment_motion_vectors``
-      -  If set to 1, motion vectors are coded for intra macroblocks.
-    * - __u8
-      - ``q_scale_type``
-      - This flag affects the inverse quantization process.
-    * - __u8
-      - ``intra_vlc_format``
-      - This flag affects the decoding of transform coefficient data.
-    * - __u8
-      - ``alternate_scan``
-      - This flag affects the decoding of transform coefficient data.
-    * - __u8
-      - ``repeat_first_field``
-      - This flag affects the decoding process of progressive frames.
-    * - __u16
-      - ``progressive_frame``
-      - Indicates whether the current frame is progressive.
-
-``V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION (struct)``
-    Specifies quantization matrices (as extracted from the bitstream) for the
-    associated MPEG-2 slice data.
-
-    .. note::
-
-       This compound control is not yet part of the public kernel API and
-       it is expected to change.
-
-.. c:type:: v4l2_ctrl_mpeg2_quantization
-
-.. cssclass:: longtable
-
-.. tabularcolumns:: |p{1.2cm}|p{8.0cm}|p{7.4cm}|
-
-.. raw:: latex
-
-    \small
-
-.. flat-table:: struct v4l2_ctrl_mpeg2_quantization
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u8
-      - ``load_intra_quantiser_matrix``
-      - One bit to indicate whether to load the ``intra_quantiser_matrix`` data.
-    * - __u8
-      - ``load_non_intra_quantiser_matrix``
-      - One bit to indicate whether to load the ``non_intra_quantiser_matrix``
-	data.
-    * - __u8
-      - ``load_chroma_intra_quantiser_matrix``
-      - One bit to indicate whether to load the
-	``chroma_intra_quantiser_matrix`` data, only relevant for non-4:2:0 YUV
-	formats.
-    * - __u8
-      - ``load_chroma_non_intra_quantiser_matrix``
-      - One bit to indicate whether to load the
-	``chroma_non_intra_quantiser_matrix`` data, only relevant for non-4:2:0
-	YUV formats.
-    * - __u8
-      - ``intra_quantiser_matrix[64]``
-      - The quantization matrix coefficients for intra-coded frames, in zigzag
-	scanning order. It is relevant for both luma and chroma components,
-	although it can be superseded by the chroma-specific matrix for
-	non-4:2:0 YUV formats.
-    * - __u8
-      - ``non_intra_quantiser_matrix[64]``
-      - The quantization matrix coefficients for non-intra-coded frames, in
-	zigzag scanning order. It is relevant for both luma and chroma
-	components, although it can be superseded by the chroma-specific matrix
-	for non-4:2:0 YUV formats.
-    * - __u8
-      - ``chroma_intra_quantiser_matrix[64]``
-      - The quantization matrix coefficients for the chominance component of
-	intra-coded frames, in zigzag scanning order. Only relevant for
-	non-4:2:0 YUV formats.
-    * - __u8
-      - ``chroma_non_intra_quantiser_matrix[64]``
-      - The quantization matrix coefficients for the chrominance component of
-	non-intra-coded frames, in zigzag scanning order. Only relevant for
-	non-4:2:0 YUV formats.
-
-``V4L2_CID_FWHT_I_FRAME_QP (integer)``
-    Quantization parameter for an I frame for FWHT. Valid range: from 1
-    to 31.
-
-``V4L2_CID_FWHT_P_FRAME_QP (integer)``
-    Quantization parameter for a P frame for FWHT. Valid range: from 1
-    to 31.
-
-.. _v4l2-mpeg-vp8:
-
-``V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER (struct)``
-    Specifies the frame parameters for the associated VP8 parsed frame data.
-    This includes the necessary parameters for
-    configuring a stateless hardware decoding pipeline for VP8.
-    The bitstream parameters are defined according to :ref:`vp8`.
-
-    .. note::
-
-       This compound control is not yet part of the public kernel API and
-       it is expected to change.
-
-.. c:type:: v4l2_ctrl_vp8_frame_header
-
-.. cssclass:: longtable
-
-.. tabularcolumns:: |p{5.8cm}|p{4.8cm}|p{6.6cm}|
-
-.. flat-table:: struct v4l2_ctrl_vp8_frame_header
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - struct :c:type:`v4l2_vp8_segment_header`
-      - ``segment_header``
-      - Structure with segment-based adjustments metadata.
-    * - struct :c:type:`v4l2_vp8_loopfilter_header`
-      - ``loopfilter_header``
-      - Structure with loop filter level adjustments metadata.
-    * - struct :c:type:`v4l2_vp8_quantization_header`
-      - ``quant_header``
-      - Structure with VP8 dequantization indices metadata.
-    * - struct :c:type:`v4l2_vp8_entropy_header`
-      - ``entropy_header``
-      - Structure with VP8 entropy coder probabilities metadata.
-    * - struct :c:type:`v4l2_vp8_entropy_coder_state`
-      - ``coder_state``
-      - Structure with VP8 entropy coder state.
-    * - __u16
-      - ``width``
-      - The width of the frame. Must be set for all frames.
-    * - __u16
-      - ``height``
-      - The height of the frame. Must be set for all frames.
-    * - __u8
-      - ``horizontal_scale``
-      - Horizontal scaling factor.
-    * - __u8
-      - ``vertical_scaling factor``
-      - Vertical scale.
-    * - __u8
-      - ``version``
-      - Bitstream version.
-    * - __u8
-      - ``prob_skip_false``
-      - Indicates the probability that the macroblock is not skipped.
-    * - __u8
-      - ``prob_intra``
-      - Indicates the probability that a macroblock is intra-predicted.
-    * - __u8
-      - ``prob_last``
-      - Indicates the probability that the last reference frame is used
-        for inter-prediction
-    * - __u8
-      - ``prob_gf``
-      - Indicates the probability that the golden reference frame is used
-        for inter-prediction
-    * - __u8
-      - ``num_dct_parts``
-      - Number of DCT coefficients partitions. Must be one of: 1, 2, 4, or 8.
-    * - __u32
-      - ``first_part_size``
-      - Size of the first partition, i.e. the control partition.
-    * - __u32
-      - ``first_part_header_bits``
-      - Size in bits of the first partition header portion.
-    * - __u32
-      - ``dct_part_sizes[8]``
-      - DCT coefficients sizes.
-    * - __u64
-      - ``last_frame_ts``
-      - Timestamp for the V4L2 capture buffer to use as last reference frame, used
-        with inter-coded frames. The timestamp refers to the ``timestamp`` field in
-	struct :c:type:`v4l2_buffer`. Use the :c:func:`v4l2_timeval_to_ns()`
-	function to convert the struct :c:type:`timeval` in struct
-	:c:type:`v4l2_buffer` to a __u64.
-    * - __u64
-      - ``golden_frame_ts``
-      - Timestamp for the V4L2 capture buffer to use as last reference frame, used
-        with inter-coded frames. The timestamp refers to the ``timestamp`` field in
-	struct :c:type:`v4l2_buffer`. Use the :c:func:`v4l2_timeval_to_ns()`
-	function to convert the struct :c:type:`timeval` in struct
-	:c:type:`v4l2_buffer` to a __u64.
-    * - __u64
-      - ``alt_frame_ts``
-      - Timestamp for the V4L2 capture buffer to use as alternate reference frame, used
-        with inter-coded frames. The timestamp refers to the ``timestamp`` field in
-	struct :c:type:`v4l2_buffer`. Use the :c:func:`v4l2_timeval_to_ns()`
-	function to convert the struct :c:type:`timeval` in struct
-	:c:type:`v4l2_buffer` to a __u64.
-    * - __u64
-      - ``flags``
-      - See :ref:`Frame Header Flags <vp8_frame_header_flags>`
-
-.. _vp8_frame_header_flags:
-
-``Frame Header Flags``
-
-.. cssclass:: longtable
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - ``V4L2_VP8_FRAME_HEADER_FLAG_KEY_FRAME``
-      - 0x01
-      - Indicates if the frame is a key frame.
-    * - ``V4L2_VP8_FRAME_HEADER_FLAG_EXPERIMENTAL``
-      - 0x02
-      - Experimental bitstream.
-    * - ``V4L2_VP8_FRAME_HEADER_FLAG_SHOW_FRAME``
-      - 0x04
-      - Show frame flag, indicates if the frame is for display.
-    * - ``V4L2_VP8_FRAME_HEADER_FLAG_MB_NO_SKIP_COEFF``
-      - 0x08
-      - Enable/disable skipping of macroblocks with no non-zero coefficients.
-    * - ``V4L2_VP8_FRAME_HEADER_FLAG_SIGN_BIAS_GOLDEN``
-      - 0x10
-      - Sign of motion vectors when the golden frame is referenced.
-    * - ``V4L2_VP8_FRAME_HEADER_FLAG_SIGN_BIAS_ALT``
-      - 0x20
-      - Sign of motion vectors when the alt frame is referenced.
-
-.. c:type:: v4l2_vp8_entropy_coder_state
-
-.. cssclass:: longtable
-
-.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
-
-.. flat-table:: struct v4l2_vp8_entropy_coder_state
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u8
-      - ``range``
-      -
-    * - __u8
-      - ``value``
-      -
-    * - __u8
-      - ``bit_count``
-      -
-    * - __u8
-      - ``padding``
-      - Applications and drivers must set this to zero.
-
-.. c:type:: v4l2_vp8_segment_header
-
-.. cssclass:: longtable
-
-.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
-
-.. flat-table:: struct v4l2_vp8_segment_header
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __s8
-      - ``quant_update[4]``
-      - Signed quantizer value update.
-    * - __s8
-      - ``lf_update[4]``
-      - Signed loop filter level value update.
-    * - __u8
-      - ``segment_probs[3]``
-      - Segment probabilities.
-    * - __u8
-      - ``padding``
-      - Applications and drivers must set this to zero.
-    * - __u32
-      - ``flags``
-      - See :ref:`Segment Header Flags <vp8_segment_header_flags>`
-
-.. _vp8_segment_header_flags:
-
-``Segment Header Flags``
-
-.. cssclass:: longtable
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - ``V4L2_VP8_SEGMENT_HEADER_FLAG_ENABLED``
-      - 0x01
-      - Enable/disable segment-based adjustments.
-    * - ``V4L2_VP8_SEGMENT_HEADER_FLAG_UPDATE_MAP``
-      - 0x02
-      - Indicates if the macroblock segmentation map is updated in this frame.
-    * - ``V4L2_VP8_SEGMENT_HEADER_FLAG_UPDATE_FEATURE_DATA``
-      - 0x04
-      - Indicates if the segment feature data is updated in this frame.
-    * - ``V4L2_VP8_SEGMENT_HEADER_FLAG_DELTA_VALUE_MODE``
-      - 0x08
-      - If is set, the segment feature data mode is delta-value.
-        If cleared, it's absolute-value.
-
-.. c:type:: v4l2_vp8_loopfilter_header
-
-.. cssclass:: longtable
-
-.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
-
-.. flat-table:: struct v4l2_vp8_loopfilter_header
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __s8
-      - ``ref_frm_delta[4]``
-      - Reference adjustment (signed) delta value.
-    * - __s8
-      - ``mb_mode_delta[4]``
-      - Macroblock prediction mode adjustment (signed) delta value.
-    * - __u8
-      - ``sharpness_level``
-      - Sharpness level
-    * - __u8
-      - ``level``
-      - Filter level
-    * - __u16
-      - ``padding``
-      - Applications and drivers must set this to zero.
-    * - __u32
-      - ``flags``
-      - See :ref:`Loopfilter Header Flags <vp8_loopfilter_header_flags>`
-
-.. _vp8_loopfilter_header_flags:
-
-``Loopfilter Header Flags``
-
-.. cssclass:: longtable
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - ``V4L2_VP8_LF_HEADER_ADJ_ENABLE``
-      - 0x01
-      - Enable/disable macroblock-level loop filter adjustment.
-    * - ``V4L2_VP8_LF_HEADER_DELTA_UPDATE``
-      - 0x02
-      - Indicates if the delta values used in an adjustment are updated.
-    * - ``V4L2_VP8_LF_FILTER_TYPE_SIMPLE``
-      - 0x04
-      - If set, indicates the filter type is simple.
-        If cleared, the filter type is normal.
-
-.. c:type:: v4l2_vp8_quantization_header
-
-.. cssclass:: longtable
-
-.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
-
-.. flat-table:: struct v4l2_vp8_quantization_header
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u8
-      - ``y_ac_qi``
-      - Luma AC coefficient table index.
-    * - __s8
-      - ``y_dc_delta``
-      - Luma DC delta vaue.
-    * - __s8
-      - ``y2_dc_delta``
-      - Y2 block DC delta value.
-    * - __s8
-      - ``y2_ac_delta``
-      - Y2 block AC delta value.
-    * - __s8
-      - ``uv_dc_delta``
-      - Chroma DC delta value.
-    * - __s8
-      - ``uv_ac_delta``
-      - Chroma AC delta value.
-    * - __u16
-      - ``padding``
-      - Applications and drivers must set this to zero.
-
-.. c:type:: v4l2_vp8_entropy_header
-
-.. cssclass:: longtable
-
-.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
-
-.. flat-table:: struct v4l2_vp8_entropy_header
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u8
-      - ``coeff_probs[4][8][3][11]``
-      - Coefficient update probabilities.
-    * - __u8
-      - ``y_mode_probs[4]``
-      - Luma mode update probabilities.
-    * - __u8
-      - ``uv_mode_probs[3]``
-      - Chroma mode update probabilities.
-    * - __u8
-      - ``mv_probs[2][19]``
-      - MV decoding update probabilities.
-    * - __u8
-      - ``padding[3]``
-      - Applications and drivers must set this to zero.
-
-.. raw:: latex
-
-    \normalsize
-
-
-MFC 5.1 MPEG Controls
-=====================
-
-The following MPEG class controls deal with MPEG decoding and encoding
-settings that are specific to the Multi Format Codec 5.1 device present
-in the S5P family of SoCs by Samsung.
-
-
-.. _mfc51-control-id:
-
-MFC 5.1 Control IDs
--------------------
-
-``V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY_ENABLE (boolean)``
-    If the display delay is enabled then the decoder is forced to return
-    a CAPTURE buffer (decoded frame) after processing a certain number
-    of OUTPUT buffers. The delay can be set through
-    ``V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY``. This
-    feature can be used for example for generating thumbnails of videos.
-    Applicable to the H264 decoder.
-
-``V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY (integer)``
-    Display delay value for H264 decoder. The decoder is forced to
-    return a decoded frame after the set 'display delay' number of
-    frames. If this number is low it may result in frames returned out
-    of display order, in addition the hardware may still be using the
-    returned buffer as a reference picture for subsequent frames.
-
-``V4L2_CID_MPEG_MFC51_VIDEO_H264_NUM_REF_PIC_FOR_P (integer)``
-    The number of reference pictures used for encoding a P picture.
-    Applicable to the H264 encoder.
-
-``V4L2_CID_MPEG_MFC51_VIDEO_PADDING (boolean)``
-    Padding enable in the encoder - use a color instead of repeating
-    border pixels. Applicable to encoders.
-
-``V4L2_CID_MPEG_MFC51_VIDEO_PADDING_YUV (integer)``
-    Padding color in the encoder. Applicable to encoders. The supplied
-    32-bit integer is interpreted as follows (bit 0 = least significant
-    bit):
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - Bit 0:7
-      - V chrominance information
-    * - Bit 8:15
-      - U chrominance information
-    * - Bit 16:23
-      - Y luminance information
-    * - Bit 24:31
-      - Must be zero.
-
-
-
-``V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF (integer)``
-    Reaction coefficient for MFC rate control. Applicable to encoders.
-
-    .. note::
-
-       #. Valid only when the frame level RC is enabled.
-
-       #. For tight CBR, this field must be small (ex. 2 ~ 10). For
-	  VBR, this field must be large (ex. 100 ~ 1000).
-
-       #. It is not recommended to use the greater number than
-	  FRAME_RATE * (10^9 / BIT_RATE).
-
-``V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_DARK (boolean)``
-    Adaptive rate control for dark region. Valid only when H.264 and
-    macroblock level RC is enabled
-    (``V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE``). Applicable to the H264
-    encoder.
-
-``V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_SMOOTH (boolean)``
-    Adaptive rate control for smooth region. Valid only when H.264 and
-    macroblock level RC is enabled
-    (``V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE``). Applicable to the H264
-    encoder.
-
-``V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_STATIC (boolean)``
-    Adaptive rate control for static region. Valid only when H.264 and
-    macroblock level RC is enabled
-    (``V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE``). Applicable to the H264
-    encoder.
-
-``V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_ACTIVITY (boolean)``
-    Adaptive rate control for activity region. Valid only when H.264 and
-    macroblock level RC is enabled
-    (``V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE``). Applicable to the H264
-    encoder.
-
-.. _v4l2-mpeg-mfc51-video-frame-skip-mode:
-
-``V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE``
-    (enum)
-
-enum v4l2_mpeg_mfc51_video_frame_skip_mode -
-    Indicates in what conditions the encoder should skip frames. If
-    encoding a frame would cause the encoded stream to be larger then a
-    chosen data limit then the frame will be skipped. Possible values
-    are:
-
-
-.. tabularcolumns:: |p{9.2cm}|p{8.3cm}|
-
-.. raw:: latex
-
-    \small
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_MFC51_FRAME_SKIP_MODE_DISABLED``
-      - Frame skip mode is disabled.
-    * - ``V4L2_MPEG_MFC51_FRAME_SKIP_MODE_LEVEL_LIMIT``
-      - Frame skip mode enabled and buffer limit is set by the chosen
-	level and is defined by the standard.
-    * - ``V4L2_MPEG_MFC51_FRAME_SKIP_MODE_BUF_LIMIT``
-      - Frame skip mode enabled and buffer limit is set by the VBV
-	(MPEG1/2/4) or CPB (H264) buffer size control.
-
-.. raw:: latex
-
-    \normalsize
-
-``V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT (integer)``
-    Enable rate-control with fixed target bit. If this setting is
-    enabled, then the rate control logic of the encoder will calculate
-    the average bitrate for a GOP and keep it below or equal the set
-    bitrate target. Otherwise the rate control logic calculates the
-    overall average bitrate for the stream and keeps it below or equal
-    to the set bitrate. In the first case the average bitrate for the
-    whole stream will be smaller then the set bitrate. This is caused
-    because the average is calculated for smaller number of frames, on
-    the other hand enabling this setting will ensure that the stream
-    will meet tight bandwidth constraints. Applicable to encoders.
-
-.. _v4l2-mpeg-mfc51-video-force-frame-type:
-
-``V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE``
-    (enum)
-
-enum v4l2_mpeg_mfc51_video_force_frame_type -
-    Force a frame type for the next queued buffer. Applicable to
-    encoders. Possible values are:
-
-.. tabularcolumns:: |p{9.5cm}|p{8.0cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_MFC51_FORCE_FRAME_TYPE_DISABLED``
-      - Forcing a specific frame type disabled.
-    * - ``V4L2_MPEG_MFC51_FORCE_FRAME_TYPE_I_FRAME``
-      - Force an I-frame.
-    * - ``V4L2_MPEG_MFC51_FORCE_FRAME_TYPE_NOT_CODED``
-      - Force a non-coded frame.
-
-
-.. _v4l2-mpeg-fwht:
-
-``V4L2_CID_MPEG_VIDEO_FWHT_PARAMS (struct)``
-    Specifies the fwht parameters (as extracted from the bitstream) for the
-    associated FWHT data. This includes the necessary parameters for
-    configuring a stateless hardware decoding pipeline for FWHT.
-
-    .. note::
-
-       This compound control is not yet part of the public kernel API and
-       it is expected to change.
-
-.. c:type:: v4l2_ctrl_fwht_params
-
-.. cssclass:: longtable
-
-.. tabularcolumns:: |p{1.4cm}|p{4.3cm}|p{11.8cm}|
-
-.. flat-table:: struct v4l2_ctrl_fwht_params
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u64
-      - ``backward_ref_ts``
-      - Timestamp of the V4L2 capture buffer to use as backward reference, used
-        with P-coded frames. The timestamp refers to the
-	``timestamp`` field in struct :c:type:`v4l2_buffer`. Use the
-	:c:func:`v4l2_timeval_to_ns()` function to convert the struct
-	:c:type:`timeval` in struct :c:type:`v4l2_buffer` to a __u64.
-    * - __u32
-      - ``version``
-      - The version of the codec
-    * - __u32
-      - ``width``
-      - The width of the frame
-    * - __u32
-      - ``height``
-      - The height of the frame
-    * - __u32
-      - ``flags``
-      - The flags of the frame, see :ref:`fwht-flags`.
-    * - __u32
-      - ``colorspace``
-      - The colorspace of the frame, from enum :c:type:`v4l2_colorspace`.
-    * - __u32
-      - ``xfer_func``
-      - The transfer function, from enum :c:type:`v4l2_xfer_func`.
-    * - __u32
-      - ``ycbcr_enc``
-      - The Y'CbCr encoding, from enum :c:type:`v4l2_ycbcr_encoding`.
-    * - __u32
-      - ``quantization``
-      - The quantization range, from enum :c:type:`v4l2_quantization`.
-
-
-
-.. _fwht-flags:
-
-FWHT Flags
-============
-
-.. cssclass:: longtable
-
-.. tabularcolumns:: |p{6.8cm}|p{2.4cm}|p{8.3cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``FWHT_FL_IS_INTERLACED``
-      - 0x00000001
-      - Set if this is an interlaced format
-    * - ``FWHT_FL_IS_BOTTOM_FIRST``
-      - 0x00000002
-      - Set if this is a bottom-first (NTSC) interlaced format
-    * - ``FWHT_FL_IS_ALTERNATE``
-      - 0x00000004
-      - Set if each 'frame' contains just one field
-    * - ``FWHT_FL_IS_BOTTOM_FIELD``
-      - 0x00000008
-      - If FWHT_FL_IS_ALTERNATE was set, then this is set if this 'frame' is the
-	bottom field, else it is the top field.
-    * - ``FWHT_FL_LUMA_IS_UNCOMPRESSED``
-      - 0x00000010
-      - Set if the luma plane is uncompressed
-    * - ``FWHT_FL_CB_IS_UNCOMPRESSED``
-      - 0x00000020
-      - Set if the cb plane is uncompressed
-    * - ``FWHT_FL_CR_IS_UNCOMPRESSED``
-      - 0x00000040
-      - Set if the cr plane is uncompressed
-    * - ``FWHT_FL_CHROMA_FULL_HEIGHT``
-      - 0x00000080
-      - Set if the chroma plane has the same height as the luma plane,
-	else the chroma plane is half the height of the luma plane
-    * - ``FWHT_FL_CHROMA_FULL_WIDTH``
-      - 0x00000100
-      - Set if the chroma plane has the same width as the luma plane,
-	else the chroma plane is half the width of the luma plane
-    * - ``FWHT_FL_ALPHA_IS_UNCOMPRESSED``
-      - 0x00000200
-      - Set if the alpha plane is uncompressed
-    * - ``FWHT_FL_I_FRAME``
-      - 0x00000400
-      - Set if this is an I-frame
-    * - ``FWHT_FL_COMPONENTS_NUM_MSK``
-      - 0x00070000
-      - A 4-values flag - the number of components - 1
-    * - ``FWHT_FL_PIXENC_YUV``
-      - 0x00080000
-      - Set if the pixel encoding is YUV
-    * - ``FWHT_FL_PIXENC_RGB``
-      - 0x00100000
-      - Set if the pixel encoding is RGB
-    * - ``FWHT_FL_PIXENC_HSV``
-      - 0x00180000
-      - Set if the pixel encoding is HSV
-
-
-CX2341x MPEG Controls
-=====================
-
-The following MPEG class controls deal with MPEG encoding settings that
-are specific to the Conexant CX23415 and CX23416 MPEG encoding chips.
-
-
-.. _cx2341x-control-id:
-
-CX2341x Control IDs
--------------------
-
-.. _v4l2-mpeg-cx2341x-video-spatial-filter-mode:
-
-``V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE``
-    (enum)
-
-enum v4l2_mpeg_cx2341x_video_spatial_filter_mode -
-    Sets the Spatial Filter mode (default ``MANUAL``). Possible values
-    are:
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL``
-      - Choose the filter manually
-    * - ``V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO``
-      - Choose the filter automatically
-
-
-
-``V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER (integer (0-15))``
-    The setting for the Spatial Filter. 0 = off, 15 = maximum. (Default
-    is 0.)
-
-.. _luma-spatial-filter-type:
-
-``V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE``
-    (enum)
-
-enum v4l2_mpeg_cx2341x_video_luma_spatial_filter_type -
-    Select the algorithm to use for the Luma Spatial Filter (default
-    ``1D_HOR``). Possible values:
-
-.. tabularcolumns:: |p{14.5cm}|p{3.0cm}|
-
-.. raw:: latex
-
-    \small
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF``
-      - No filter
-    * - ``V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR``
-      - One-dimensional horizontal
-    * - ``V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_VERT``
-      - One-dimensional vertical
-    * - ``V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_HV_SEPARABLE``
-      - Two-dimensional separable
-    * - ``V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE``
-      - Two-dimensional symmetrical non-separable
-
-.. raw:: latex
-
-    \normalsize
-
-
-
-.. _chroma-spatial-filter-type:
-
-``V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE``
-    (enum)
-
-enum v4l2_mpeg_cx2341x_video_chroma_spatial_filter_type -
-    Select the algorithm for the Chroma Spatial Filter (default
-    ``1D_HOR``). Possible values are:
-
-
-.. tabularcolumns:: |p{14.0cm}|p{3.5cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF``
-      - No filter
-    * - ``V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR``
-      - One-dimensional horizontal
-
-
-
-.. _v4l2-mpeg-cx2341x-video-temporal-filter-mode:
-
-``V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE``
-    (enum)
-
-enum v4l2_mpeg_cx2341x_video_temporal_filter_mode -
-    Sets the Temporal Filter mode (default ``MANUAL``). Possible values
-    are:
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL``
-      - Choose the filter manually
-    * - ``V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO``
-      - Choose the filter automatically
-
-
-
-``V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER (integer (0-31))``
-    The setting for the Temporal Filter. 0 = off, 31 = maximum. (Default
-    is 8 for full-scale capturing and 0 for scaled capturing.)
-
-.. _v4l2-mpeg-cx2341x-video-median-filter-type:
-
-``V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE``
-    (enum)
-
-enum v4l2_mpeg_cx2341x_video_median_filter_type -
-    Median Filter Type (default ``OFF``). Possible values are:
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF``
-      - No filter
-    * - ``V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR``
-      - Horizontal filter
-    * - ``V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_VERT``
-      - Vertical filter
-    * - ``V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR_VERT``
-      - Horizontal and vertical filter
-    * - ``V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG``
-      - Diagonal filter
-
-
-
-``V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM (integer (0-255))``
-    Threshold above which the luminance median filter is enabled
-    (default 0)
-
-``V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP (integer (0-255))``
-    Threshold below which the luminance median filter is enabled
-    (default 255)
-
-``V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM (integer (0-255))``
-    Threshold above which the chroma median filter is enabled (default
-    0)
-
-``V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP (integer (0-255))``
-    Threshold below which the chroma median filter is enabled (default
-    255)
-
-``V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS (boolean)``
-    The CX2341X MPEG encoder can insert one empty MPEG-2 PES packet into
-    the stream between every four video frames. The packet size is 2048
-    bytes, including the packet_start_code_prefix and stream_id
-    fields. The stream_id is 0xBF (private stream 2). The payload
-    consists of 0x00 bytes, to be filled in by the application. 0 = do
-    not insert, 1 = insert packets.
-
-
-VPX Control Reference
-=====================
-
-The VPX controls include controls for encoding parameters of VPx video
-codec.
-
-
-.. _vpx-control-id:
-
-VPX Control IDs
----------------
-
-.. _v4l2-vpx-num-partitions:
-
-``V4L2_CID_MPEG_VIDEO_VPX_NUM_PARTITIONS``
-    (enum)
-
-enum v4l2_vp8_num_partitions -
-    The number of token partitions to use in VP8 encoder. Possible
-    values are:
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_CID_MPEG_VIDEO_VPX_1_PARTITION``
-      - 1 coefficient partition
-    * - ``V4L2_CID_MPEG_VIDEO_VPX_2_PARTITIONS``
-      - 2 coefficient partitions
-    * - ``V4L2_CID_MPEG_VIDEO_VPX_4_PARTITIONS``
-      - 4 coefficient partitions
-    * - ``V4L2_CID_MPEG_VIDEO_VPX_8_PARTITIONS``
-      - 8 coefficient partitions
-
-
-
-``V4L2_CID_MPEG_VIDEO_VPX_IMD_DISABLE_4X4 (boolean)``
-    Setting this prevents intra 4x4 mode in the intra mode decision.
-
-.. _v4l2-vpx-num-ref-frames:
-
-``V4L2_CID_MPEG_VIDEO_VPX_NUM_REF_FRAMES``
-    (enum)
-
-enum v4l2_vp8_num_ref_frames -
-    The number of reference pictures for encoding P frames. Possible
-    values are:
-
-.. tabularcolumns:: |p{7.9cm}|p{9.6cm}|
-
-.. raw:: latex
-
-    \small
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_CID_MPEG_VIDEO_VPX_1_REF_FRAME``
-      - Last encoded frame will be searched
-    * - ``V4L2_CID_MPEG_VIDEO_VPX_2_REF_FRAME``
-      - Two frames will be searched among the last encoded frame, the
-	golden frame and the alternate reference (altref) frame. The
-	encoder implementation will decide which two are chosen.
-    * - ``V4L2_CID_MPEG_VIDEO_VPX_3_REF_FRAME``
-      - The last encoded frame, the golden frame and the altref frame will
-	be searched.
-
-.. raw:: latex
-
-    \normalsize
-
-
-
-``V4L2_CID_MPEG_VIDEO_VPX_FILTER_LEVEL (integer)``
-    Indicates the loop filter level. The adjustment of the loop filter
-    level is done via a delta value against a baseline loop filter
-    value.
-
-``V4L2_CID_MPEG_VIDEO_VPX_FILTER_SHARPNESS (integer)``
-    This parameter affects the loop filter. Anything above zero weakens
-    the deblocking effect on the loop filter.
-
-``V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_REF_PERIOD (integer)``
-    Sets the refresh period for the golden frame. The period is defined
-    in number of frames. For a value of 'n', every nth frame starting
-    from the first key frame will be taken as a golden frame. For eg.
-    for encoding sequence of 0, 1, 2, 3, 4, 5, 6, 7 where the golden
-    frame refresh period is set as 4, the frames 0, 4, 8 etc will be
-    taken as the golden frames as frame 0 is always a key frame.
-
-.. _v4l2-vpx-golden-frame-sel:
-
-``V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_SEL``
-    (enum)
-
-enum v4l2_vp8_golden_frame_sel -
-    Selects the golden frame for encoding. Possible values are:
-
-.. raw:: latex
-
-    \scriptsize
-
-.. tabularcolumns:: |p{9.0cm}|p{8.0cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_USE_PREV``
-      - Use the (n-2)th frame as a golden frame, current frame index being
-	'n'.
-    * - ``V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_USE_REF_PERIOD``
-      - Use the previous specific frame indicated by
-	``V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_REF_PERIOD`` as a
-	golden frame.
-
-.. raw:: latex
-
-    \normalsize
-
-
-``V4L2_CID_MPEG_VIDEO_VPX_MIN_QP (integer)``
-    Minimum quantization parameter for VP8.
-
-``V4L2_CID_MPEG_VIDEO_VPX_MAX_QP (integer)``
-    Maximum quantization parameter for VP8.
-
-``V4L2_CID_MPEG_VIDEO_VPX_I_FRAME_QP (integer)``
-    Quantization parameter for an I frame for VP8.
-
-``V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP (integer)``
-    Quantization parameter for a P frame for VP8.
-
-.. _v4l2-mpeg-video-vp8-profile:
-
-``V4L2_CID_MPEG_VIDEO_VP8_PROFILE``
-    (enum)
-
-enum v4l2_mpeg_video_vp8_profile -
-    This control allows selecting the profile for VP8 encoder.
-    This is also used to enumerate supported profiles by VP8 encoder or decoder.
-    Possible values are:
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_VIDEO_VP8_PROFILE_0``
-      - Profile 0
-    * - ``V4L2_MPEG_VIDEO_VP8_PROFILE_1``
-      - Profile 1
-    * - ``V4L2_MPEG_VIDEO_VP8_PROFILE_2``
-      - Profile 2
-    * - ``V4L2_MPEG_VIDEO_VP8_PROFILE_3``
-      - Profile 3
-
-.. _v4l2-mpeg-video-vp9-profile:
-
-``V4L2_CID_MPEG_VIDEO_VP9_PROFILE``
-    (enum)
-
-enum v4l2_mpeg_video_vp9_profile -
-    This control allows selecting the profile for VP9 encoder.
-    This is also used to enumerate supported profiles by VP9 encoder or decoder.
-    Possible values are:
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_VIDEO_VP9_PROFILE_0``
-      - Profile 0
-    * - ``V4L2_MPEG_VIDEO_VP9_PROFILE_1``
-      - Profile 1
-    * - ``V4L2_MPEG_VIDEO_VP9_PROFILE_2``
-      - Profile 2
-    * - ``V4L2_MPEG_VIDEO_VP9_PROFILE_3``
-      - Profile 3
-
-
-High Efficiency Video Coding (HEVC/H.265) Control Reference
-===========================================================
-
-The HEVC/H.265 controls include controls for encoding parameters of HEVC/H.265
-video codec.
-
-
-.. _hevc-control-id:
-
-HEVC/H.265 Control IDs
-----------------------
-
-``V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP (integer)``
-    Minimum quantization parameter for HEVC.
-    Valid range: from 0 to 51.
-
-``V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP (integer)``
-    Maximum quantization parameter for HEVC.
-    Valid range: from 0 to 51.
-
-``V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP (integer)``
-    Quantization parameter for an I frame for HEVC.
-    Valid range: [V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP,
-    V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP].
-
-``V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP (integer)``
-    Quantization parameter for a P frame for HEVC.
-    Valid range: [V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP,
-    V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP].
-
-``V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP (integer)``
-    Quantization parameter for a B frame for HEVC.
-    Valid range: [V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP,
-    V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP].
-
-``V4L2_CID_MPEG_VIDEO_HEVC_HIER_QP (boolean)``
-    HIERARCHICAL_QP allows the host to specify the quantization parameter
-    values for each temporal layer through HIERARCHICAL_QP_LAYER. This is
-    valid only if HIERARCHICAL_CODING_LAYER is greater than 1. Setting the
-    control value to 1 enables setting of the QP values for the layers.
-
-.. _v4l2-hevc-hier-coding-type:
-
-``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE``
-    (enum)
-
-enum v4l2_mpeg_video_hevc_hier_coding_type -
-    Selects the hierarchical coding type for encoding. Possible values are:
-
-.. raw:: latex
-
-    \footnotesize
-
-.. tabularcolumns:: |p{9.0cm}|p{8.0cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B``
-      - Use the B frame for hierarchical coding.
-    * - ``V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P``
-      - Use the P frame for hierarchical coding.
-
-.. raw:: latex
-
-    \normalsize
-
-
-``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER (integer)``
-    Selects the hierarchical coding layer. In normal encoding
-    (non-hierarchial coding), it should be zero. Possible values are [0, 6].
-    0 indicates HIERARCHICAL CODING LAYER 0, 1 indicates HIERARCHICAL CODING
-    LAYER 1 and so on.
-
-``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_QP (integer)``
-    Indicates quantization parameter for hierarchical coding layer 0.
-    Valid range: [V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP,
-    V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP].
-
-``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_QP (integer)``
-    Indicates quantization parameter for hierarchical coding layer 1.
-    Valid range: [V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP,
-    V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP].
-
-``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_QP (integer)``
-    Indicates quantization parameter for hierarchical coding layer 2.
-    Valid range: [V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP,
-    V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP].
-
-``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_QP (integer)``
-    Indicates quantization parameter for hierarchical coding layer 3.
-    Valid range: [V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP,
-    V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP].
-
-``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_QP (integer)``
-    Indicates quantization parameter for hierarchical coding layer 4.
-    Valid range: [V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP,
-    V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP].
-
-``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_QP (integer)``
-    Indicates quantization parameter for hierarchical coding layer 5.
-    Valid range: [V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP,
-    V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP].
-
-``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_QP (integer)``
-    Indicates quantization parameter for hierarchical coding layer 6.
-    Valid range: [V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP,
-    V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP].
-
-.. _v4l2-hevc-profile:
-
-``V4L2_CID_MPEG_VIDEO_HEVC_PROFILE``
-    (enum)
-
-enum v4l2_mpeg_video_hevc_profile -
-    Select the desired profile for HEVC encoder.
-
-.. raw:: latex
-
-    \footnotesize
-
-.. tabularcolumns:: |p{9.0cm}|p{8.0cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN``
-      - Main profile.
-    * - ``V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE``
-      - Main still picture profile.
-    * - ``V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10``
-      - Main 10 profile.
-
-.. raw:: latex
-
-    \normalsize
-
-
-.. _v4l2-hevc-level:
-
-``V4L2_CID_MPEG_VIDEO_HEVC_LEVEL``
-    (enum)
-
-enum v4l2_mpeg_video_hevc_level -
-    Selects the desired level for HEVC encoder.
-
-.. raw:: latex
-
-    \footnotesize
-
-.. tabularcolumns:: |p{9.0cm}|p{8.0cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_1``
-      - Level 1.0
-    * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_2``
-      - Level 2.0
-    * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1``
-      - Level 2.1
-    * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_3``
-      - Level 3.0
-    * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1``
-      - Level 3.1
-    * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_4``
-      - Level 4.0
-    * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1``
-      - Level 4.1
-    * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_5``
-      - Level 5.0
-    * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1``
-      - Level 5.1
-    * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2``
-      - Level 5.2
-    * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_6``
-      - Level 6.0
-    * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1``
-      - Level 6.1
-    * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2``
-      - Level 6.2
-
-.. raw:: latex
-
-    \normalsize
-
-
-``V4L2_CID_MPEG_VIDEO_HEVC_FRAME_RATE_RESOLUTION (integer)``
-    Indicates the number of evenly spaced subintervals, called ticks, within
-    one second. This is a 16 bit unsigned integer and has a maximum value up to
-    0xffff and a minimum value of 1.
-
-.. _v4l2-hevc-tier:
-
-``V4L2_CID_MPEG_VIDEO_HEVC_TIER``
-    (enum)
-
-enum v4l2_mpeg_video_hevc_tier -
-    TIER_FLAG specifies tiers information of the HEVC encoded picture. Tier
-    were made to deal with applications that differ in terms of maximum bit
-    rate. Setting the flag to 0 selects HEVC tier as Main tier and setting
-    this flag to 1 indicates High tier. High tier is for applications requiring
-    high bit rates.
-
-.. raw:: latex
-
-    \footnotesize
-
-.. tabularcolumns:: |p{9.0cm}|p{8.0cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_VIDEO_HEVC_TIER_MAIN``
-      - Main tier.
-    * - ``V4L2_MPEG_VIDEO_HEVC_TIER_HIGH``
-      - High tier.
-
-.. raw:: latex
-
-    \normalsize
-
-
-``V4L2_CID_MPEG_VIDEO_HEVC_MAX_PARTITION_DEPTH (integer)``
-    Selects HEVC maximum coding unit depth.
-
-.. _v4l2-hevc-loop-filter-mode:
-
-``V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE``
-    (enum)
-
-enum v4l2_mpeg_video_hevc_loop_filter_mode -
-    Loop filter mode for HEVC encoder. Possible values are:
-
-.. raw:: latex
-
-    \footnotesize
-
-.. tabularcolumns:: |p{12.1cm}|p{5.4cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_DISABLED``
-      - Loop filter is disabled.
-    * - ``V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_ENABLED``
-      - Loop filter is enabled.
-    * - ``V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY``
-      - Loop filter is disabled at the slice boundary.
-
-.. raw:: latex
-
-    \normalsize
-
-
-``V4L2_CID_MPEG_VIDEO_HEVC_LF_BETA_OFFSET_DIV2 (integer)``
-    Selects HEVC loop filter beta offset. The valid range is [-6, +6].
-
-``V4L2_CID_MPEG_VIDEO_HEVC_LF_TC_OFFSET_DIV2 (integer)``
-    Selects HEVC loop filter tc offset. The valid range is [-6, +6].
-
-.. _v4l2-hevc-refresh-type:
-
-``V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE``
-    (enum)
-
-enum v4l2_mpeg_video_hevc_hier_refresh_type -
-    Selects refresh type for HEVC encoder.
-    Host has to specify the period into
-    V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_PERIOD.
-
-.. raw:: latex
-
-    \footnotesize
-
-.. tabularcolumns:: |p{8.0cm}|p{9.0cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_VIDEO_HEVC_REFRESH_NONE``
-      - Use the B frame for hierarchical coding.
-    * - ``V4L2_MPEG_VIDEO_HEVC_REFRESH_CRA``
-      - Use CRA (Clean Random Access Unit) picture encoding.
-    * - ``V4L2_MPEG_VIDEO_HEVC_REFRESH_IDR``
-      - Use IDR (Instantaneous Decoding Refresh) picture encoding.
-
-.. raw:: latex
-
-    \normalsize
-
-
-``V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_PERIOD (integer)``
-    Selects the refresh period for HEVC encoder.
-    This specifies the number of I pictures between two CRA/IDR pictures.
-    This is valid only if REFRESH_TYPE is not 0.
-
-``V4L2_CID_MPEG_VIDEO_HEVC_LOSSLESS_CU (boolean)``
-    Indicates HEVC lossless encoding. Setting it to 0 disables lossless
-    encoding. Setting it to 1 enables lossless encoding.
-
-``V4L2_CID_MPEG_VIDEO_HEVC_CONST_INTRA_PRED (boolean)``
-    Indicates constant intra prediction for HEVC encoder. Specifies the
-    constrained intra prediction in which intra largest coding unit (LCU)
-    prediction is performed by using residual data and decoded samples of
-    neighboring intra LCU only. Setting the value to 1 enables constant intra
-    prediction and setting the value to 0 disables constant intra prediction.
-
-``V4L2_CID_MPEG_VIDEO_HEVC_WAVEFRONT (boolean)``
-    Indicates wavefront parallel processing for HEVC encoder. Setting it to 0
-    disables the feature and setting it to 1 enables the wavefront parallel
-    processing.
-
-``V4L2_CID_MPEG_VIDEO_HEVC_GENERAL_PB (boolean)``
-    Setting the value to 1 enables combination of P and B frame for HEVC
-    encoder.
-
-``V4L2_CID_MPEG_VIDEO_HEVC_TEMPORAL_ID (boolean)``
-    Indicates temporal identifier for HEVC encoder which is enabled by
-    setting the value to 1.
-
-``V4L2_CID_MPEG_VIDEO_HEVC_STRONG_SMOOTHING (boolean)``
-    Indicates bi-linear interpolation is conditionally used in the intra
-    prediction filtering process in the CVS when set to 1. Indicates bi-linear
-    interpolation is not used in the CVS when set to 0.
-
-``V4L2_CID_MPEG_VIDEO_HEVC_MAX_NUM_MERGE_MV_MINUS1 (integer)``
-    Indicates maximum number of merge candidate motion vectors.
-    Values are from 0 to 4.
-
-``V4L2_CID_MPEG_VIDEO_HEVC_TMV_PREDICTION (boolean)``
-    Indicates temporal motion vector prediction for HEVC encoder. Setting it to
-    1 enables the prediction. Setting it to 0 disables the prediction.
-
-``V4L2_CID_MPEG_VIDEO_HEVC_WITHOUT_STARTCODE (boolean)``
-    Specifies if HEVC generates a stream with a size of the length field
-    instead of start code pattern. The size of the length field is configurable
-    through the V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD control. Setting
-    the value to 0 disables encoding without startcode pattern. Setting the
-    value to 1 will enables encoding without startcode pattern.
-
-.. _v4l2-hevc-size-of-length-field:
-
-``V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD``
-(enum)
-
-enum v4l2_mpeg_video_hevc_size_of_length_field -
-    Indicates the size of length field.
-    This is valid when encoding WITHOUT_STARTCODE_ENABLE is enabled.
-
-.. raw:: latex
-
-    \footnotesize
-
-.. tabularcolumns:: |p{6.0cm}|p{11.0cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_MPEG_VIDEO_HEVC_SIZE_0``
-      - Generate start code pattern (Normal).
-    * - ``V4L2_MPEG_VIDEO_HEVC_SIZE_1``
-      - Generate size of length field instead of start code pattern and length is 1.
-    * - ``V4L2_MPEG_VIDEO_HEVC_SIZE_2``
-      - Generate size of length field instead of start code pattern and length is 2.
-    * - ``V4L2_MPEG_VIDEO_HEVC_SIZE_4``
-      - Generate size of length field instead of start code pattern and length is 4.
-
-.. raw:: latex
-
-    \normalsize
-
-``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_BR (integer)``
-    Indicates bit rate for hierarchical coding layer 0 for HEVC encoder.
-
-``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_BR (integer)``
-    Indicates bit rate for hierarchical coding layer 1 for HEVC encoder.
-
-``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_BR (integer)``
-    Indicates bit rate for hierarchical coding layer 2 for HEVC encoder.
-
-``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_BR (integer)``
-    Indicates bit rate for hierarchical coding layer 3 for HEVC encoder.
-
-``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_BR (integer)``
-    Indicates bit rate for hierarchical coding layer 4 for HEVC encoder.
-
-``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_BR (integer)``
-    Indicates bit rate for hierarchical coding layer 5 for HEVC encoder.
-
-``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_BR (integer)``
-    Indicates bit rate for hierarchical coding layer 6 for HEVC encoder.
-
-``V4L2_CID_MPEG_VIDEO_REF_NUMBER_FOR_PFRAMES (integer)``
-    Selects number of P reference pictures required for HEVC encoder.
-    P-Frame can use 1 or 2 frames for reference.
-
-``V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR (integer)``
-    Indicates whether to generate SPS and PPS at every IDR. Setting it to 0
-    disables generating SPS and PPS at every IDR. Setting it to one enables
-    generating SPS and PPS at every IDR.
-
-.. _v4l2-mpeg-hevc:
-
-``V4L2_CID_MPEG_VIDEO_HEVC_SPS (struct)``
-    Specifies the Sequence Parameter Set fields (as extracted from the
-    bitstream) for the associated HEVC slice data.
-    These bitstream parameters are defined according to :ref:`hevc`.
-    They are described in section 7.4.3.2 "Sequence parameter set RBSP
-    semantics" of the specification.
-
-.. c:type:: v4l2_ctrl_hevc_sps
-
-.. cssclass:: longtable
-
-.. flat-table:: struct v4l2_ctrl_hevc_sps
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u16
-      - ``pic_width_in_luma_samples``
-      -
-    * - __u16
-      - ``pic_height_in_luma_samples``
-      -
-    * - __u8
-      - ``bit_depth_luma_minus8``
-      -
-    * - __u8
-      - ``bit_depth_chroma_minus8``
-      -
-    * - __u8
-      - ``log2_max_pic_order_cnt_lsb_minus4``
-      -
-    * - __u8
-      - ``sps_max_dec_pic_buffering_minus1``
-      -
-    * - __u8
-      - ``sps_max_num_reorder_pics``
-      -
-    * - __u8
-      - ``sps_max_latency_increase_plus1``
-      -
-    * - __u8
-      - ``log2_min_luma_coding_block_size_minus3``
-      -
-    * - __u8
-      - ``log2_diff_max_min_luma_coding_block_size``
-      -
-    * - __u8
-      - ``log2_min_luma_transform_block_size_minus2``
-      -
-    * - __u8
-      - ``log2_diff_max_min_luma_transform_block_size``
-      -
-    * - __u8
-      - ``max_transform_hierarchy_depth_inter``
-      -
-    * - __u8
-      - ``max_transform_hierarchy_depth_intra``
-      -
-    * - __u8
-      - ``pcm_sample_bit_depth_luma_minus1``
-      -
-    * - __u8
-      - ``pcm_sample_bit_depth_chroma_minus1``
-      -
-    * - __u8
-      - ``log2_min_pcm_luma_coding_block_size_minus3``
-      -
-    * - __u8
-      - ``log2_diff_max_min_pcm_luma_coding_block_size``
-      -
-    * - __u8
-      - ``num_short_term_ref_pic_sets``
-      -
-    * - __u8
-      - ``num_long_term_ref_pics_sps``
-      -
-    * - __u8
-      - ``chroma_format_idc``
-      -
-    * - __u64
-      - ``flags``
-      - See :ref:`Sequence Parameter Set Flags <hevc_sps_flags>`
-
-.. _hevc_sps_flags:
-
-``Sequence Parameter Set Flags``
-
-.. cssclass:: longtable
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - ``V4L2_HEVC_SPS_FLAG_SEPARATE_COLOUR_PLANE``
-      - 0x00000001
-      -
-    * - ``V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED``
-      - 0x00000002
-      -
-    * - ``V4L2_HEVC_SPS_FLAG_AMP_ENABLED``
-      - 0x00000004
-      -
-    * - ``V4L2_HEVC_SPS_FLAG_SAMPLE_ADAPTIVE_OFFSET``
-      - 0x00000008
-      -
-    * - ``V4L2_HEVC_SPS_FLAG_PCM_ENABLED``
-      - 0x00000010
-      -
-    * - ``V4L2_HEVC_SPS_FLAG_PCM_LOOP_FILTER_DISABLED``
-      - 0x00000020
-      -
-    * - ``V4L2_HEVC_SPS_FLAG_LONG_TERM_REF_PICS_PRESENT``
-      - 0x00000040
-      -
-    * - ``V4L2_HEVC_SPS_FLAG_SPS_TEMPORAL_MVP_ENABLED``
-      - 0x00000080
-      -
-    * - ``V4L2_HEVC_SPS_FLAG_STRONG_INTRA_SMOOTHING_ENABLED``
-      - 0x00000100
-      -
-
-``V4L2_CID_MPEG_VIDEO_HEVC_PPS (struct)``
-    Specifies the Picture Parameter Set fields (as extracted from the
-    bitstream) for the associated HEVC slice data.
-    These bitstream parameters are defined according to :ref:`hevc`.
-    They are described in section 7.4.3.3 "Picture parameter set RBSP
-    semantics" of the specification.
-
-.. c:type:: v4l2_ctrl_hevc_pps
-
-.. cssclass:: longtable
-
-.. flat-table:: struct v4l2_ctrl_hevc_pps
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u8
-      - ``num_extra_slice_header_bits``
-      -
-    * - __s8
-      - ``init_qp_minus26``
-      -
-    * - __u8
-      - ``diff_cu_qp_delta_depth``
-      -
-    * - __s8
-      - ``pps_cb_qp_offset``
-      -
-    * - __s8
-      - ``pps_cr_qp_offset``
-      -
-    * - __u8
-      - ``num_tile_columns_minus1``
-      -
-    * - __u8
-      - ``num_tile_rows_minus1``
-      -
-    * - __u8
-      - ``column_width_minus1[20]``
-      -
-    * - __u8
-      - ``row_height_minus1[22]``
-      -
-    * - __s8
-      - ``pps_beta_offset_div2``
-      -
-    * - __s8
-      - ``pps_tc_offset_div2``
-      -
-    * - __u8
-      - ``log2_parallel_merge_level_minus2``
-      -
-    * - __u8
-      - ``padding[4]``
-      - Applications and drivers must set this to zero.
-    * - __u64
-      - ``flags``
-      - See :ref:`Picture Parameter Set Flags <hevc_pps_flags>`
-
-.. _hevc_pps_flags:
-
-``Picture Parameter Set Flags``
-
-.. cssclass:: longtable
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - ``V4L2_HEVC_PPS_FLAG_DEPENDENT_SLICE_SEGMENT``
-      - 0x00000001
-      -
-    * - ``V4L2_HEVC_PPS_FLAG_OUTPUT_FLAG_PRESENT``
-      - 0x00000002
-      -
-    * - ``V4L2_HEVC_PPS_FLAG_SIGN_DATA_HIDING_ENABLED``
-      - 0x00000004
-      -
-    * - ``V4L2_HEVC_PPS_FLAG_CABAC_INIT_PRESENT``
-      - 0x00000008
-      -
-    * - ``V4L2_HEVC_PPS_FLAG_CONSTRAINED_INTRA_PRED``
-      - 0x00000010
-      -
-    * - ``V4L2_HEVC_PPS_FLAG_TRANSFORM_SKIP_ENABLED``
-      - 0x00000020
-      -
-    * - ``V4L2_HEVC_PPS_FLAG_CU_QP_DELTA_ENABLED``
-      - 0x00000040
-      -
-    * - ``V4L2_HEVC_PPS_FLAG_PPS_SLICE_CHROMA_QP_OFFSETS_PRESENT``
-      - 0x00000080
-      -
-    * - ``V4L2_HEVC_PPS_FLAG_WEIGHTED_PRED``
-      - 0x00000100
-      -
-    * - ``V4L2_HEVC_PPS_FLAG_WEIGHTED_BIPRED``
-      - 0x00000200
-      -
-    * - ``V4L2_HEVC_PPS_FLAG_TRANSQUANT_BYPASS_ENABLED``
-      - 0x00000400
-      -
-    * - ``V4L2_HEVC_PPS_FLAG_TILES_ENABLED``
-      - 0x00000800
-      -
-    * - ``V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED``
-      - 0x00001000
-      -
-    * - ``V4L2_HEVC_PPS_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED``
-      - 0x00002000
-      -
-    * - ``V4L2_HEVC_PPS_FLAG_PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED``
-      - 0x00004000
-      -
-    * - ``V4L2_HEVC_PPS_FLAG_DEBLOCKING_FILTER_OVERRIDE_ENABLED``
-      - 0x00008000
-      -
-    * - ``V4L2_HEVC_PPS_FLAG_PPS_DISABLE_DEBLOCKING_FILTER``
-      - 0x00010000
-      -
-    * - ``V4L2_HEVC_PPS_FLAG_LISTS_MODIFICATION_PRESENT``
-      - 0x00020000
-      -
-    * - ``V4L2_HEVC_PPS_FLAG_SLICE_SEGMENT_HEADER_EXTENSION_PRESENT``
-      - 0x00040000
-      -
-
-``V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS (struct)``
-    Specifies various slice-specific parameters, especially from the NAL unit
-    header, general slice segment header and weighted prediction parameter
-    parts of the bitstream.
-    These bitstream parameters are defined according to :ref:`hevc`.
-    They are described in section 7.4.7 "General slice segment header
-    semantics" of the specification.
-
-.. c:type:: v4l2_ctrl_hevc_slice_params
-
-.. cssclass:: longtable
-
-.. flat-table:: struct v4l2_ctrl_hevc_slice_params
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``bit_size``
-      - Size (in bits) of the current slice data.
-    * - __u32
-      - ``data_bit_offset``
-      - Offset (in bits) to the video data in the current slice data.
-    * - __u8
-      - ``nal_unit_type``
-      -
-    * - __u8
-      - ``nuh_temporal_id_plus1``
-      -
-    * - __u8
-      - ``slice_type``
-      -
-	(V4L2_HEVC_SLICE_TYPE_I, V4L2_HEVC_SLICE_TYPE_P or
-	V4L2_HEVC_SLICE_TYPE_B).
-    * - __u8
-      - ``colour_plane_id``
-      -
-    * - __u16
-      - ``slice_pic_order_cnt``
-      -
-    * - __u8
-      - ``num_ref_idx_l0_active_minus1``
-      -
-    * - __u8
-      - ``num_ref_idx_l1_active_minus1``
-      -
-    * - __u8
-      - ``collocated_ref_idx``
-      -
-    * - __u8
-      - ``five_minus_max_num_merge_cand``
-      -
-    * - __s8
-      - ``slice_qp_delta``
-      -
-    * - __s8
-      - ``slice_cb_qp_offset``
-      -
-    * - __s8
-      - ``slice_cr_qp_offset``
-      -
-    * - __s8
-      - ``slice_act_y_qp_offset``
-      -
-    * - __s8
-      - ``slice_act_cb_qp_offset``
-      -
-    * - __s8
-      - ``slice_act_cr_qp_offset``
-      -
-    * - __s8
-      - ``slice_beta_offset_div2``
-      -
-    * - __s8
-      - ``slice_tc_offset_div2``
-      -
-    * - __u8
-      - ``pic_struct``
-      -
-    * - __u8
-      - ``num_active_dpb_entries``
-      - The number of entries in ``dpb``.
-    * - __u8
-      - ``ref_idx_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
-      - The list of L0 reference elements as indices in the DPB.
-    * - __u8
-      - ``ref_idx_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
-      - The list of L1 reference elements as indices in the DPB.
-    * - __u8
-      - ``num_rps_poc_st_curr_before``
-      - The number of reference pictures in the short-term set that come before
-        the current frame.
-    * - __u8
-      - ``num_rps_poc_st_curr_after``
-      - The number of reference pictures in the short-term set that come after
-        the current frame.
-    * - __u8
-      - ``num_rps_poc_lt_curr``
-      - The number of reference pictures in the long-term set.
-    * - __u8
-      - ``padding[7]``
-      - Applications and drivers must set this to zero.
-    * - struct :c:type:`v4l2_hevc_dpb_entry`
-      - ``dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
-      - The decoded picture buffer, for meta-data about reference frames.
-    * - struct :c:type:`v4l2_hevc_pred_weight_table`
-      - ``pred_weight_table``
-      - The prediction weight coefficients for inter-picture prediction.
-    * - __u64
-      - ``flags``
-      - See :ref:`Slice Parameters Flags <hevc_slice_params_flags>`
-
-.. _hevc_slice_params_flags:
-
-``Slice Parameters Flags``
-
-.. cssclass:: longtable
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - ``V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_SAO_LUMA``
-      - 0x00000001
-      -
-    * - ``V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_SAO_CHROMA``
-      - 0x00000002
-      -
-    * - ``V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_TEMPORAL_MVP_ENABLED``
-      - 0x00000004
-      -
-    * - ``V4L2_HEVC_SLICE_PARAMS_FLAG_MVD_L1_ZERO``
-      - 0x00000008
-      -
-    * - ``V4L2_HEVC_SLICE_PARAMS_FLAG_CABAC_INIT``
-      - 0x00000010
-      -
-    * - ``V4L2_HEVC_SLICE_PARAMS_FLAG_COLLOCATED_FROM_L0``
-      - 0x00000020
-      -
-    * - ``V4L2_HEVC_SLICE_PARAMS_FLAG_USE_INTEGER_MV``
-      - 0x00000040
-      -
-    * - ``V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_DEBLOCKING_FILTER_DISABLED``
-      - 0x00000080
-      -
-    * - ``V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED``
-      - 0x00000100
-      -
-
-.. c:type:: v4l2_hevc_dpb_entry
-
-.. cssclass:: longtable
-
-.. flat-table:: struct v4l2_hevc_dpb_entry
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u64
-      - ``timestamp``
-      - Timestamp of the V4L2 capture buffer to use as reference, used
-        with B-coded and P-coded frames. The timestamp refers to the
-	``timestamp`` field in struct :c:type:`v4l2_buffer`. Use the
-	:c:func:`v4l2_timeval_to_ns()` function to convert the struct
-	:c:type:`timeval` in struct :c:type:`v4l2_buffer` to a __u64.
-    * - __u8
-      - ``rps``
-      - The reference set for the reference frame
-        (V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_BEFORE,
-        V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_AFTER or
-        V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR)
-    * - __u8
-      - ``field_pic``
-      - Whether the reference is a field picture or a frame.
-    * - __u16
-      - ``pic_order_cnt[2]``
-      - The picture order count of the reference. Only the first element of the
-        array is used for frame pictures, while the first element identifies the
-        top field and the second the bottom field in field-coded pictures.
-    * - __u8
-      - ``padding[2]``
-      - Applications and drivers must set this to zero.
-
-.. c:type:: v4l2_hevc_pred_weight_table
-
-.. cssclass:: longtable
-
-.. flat-table:: struct v4l2_hevc_pred_weight_table
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u8
-      - ``luma_log2_weight_denom``
-      -
-    * - __s8
-      - ``delta_chroma_log2_weight_denom``
-      -
-    * - __s8
-      - ``delta_luma_weight_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
-      -
-    * - __s8
-      - ``luma_offset_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
-      -
-    * - __s8
-      - ``delta_chroma_weight_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2]``
-      -
-    * - __s8
-      - ``chroma_offset_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2]``
-      -
-    * - __s8
-      - ``delta_luma_weight_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
-      -
-    * - __s8
-      - ``luma_offset_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
-      -
-    * - __s8
-      - ``delta_chroma_weight_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2]``
-      -
-    * - __s8
-      - ``chroma_offset_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2]``
-      -
-    * - __u8
-      - ``padding[6]``
-      - Applications and drivers must set this to zero.
-
-``V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE (enum)``
-    Specifies the decoding mode to use. Currently exposes slice-based and
-    frame-based decoding but new modes might be added later on.
-    This control is used as a modifier for V4L2_PIX_FMT_HEVC_SLICE
-    pixel format. Applications that support V4L2_PIX_FMT_HEVC_SLICE
-    are required to set this control in order to specify the decoding mode
-    that is expected for the buffer.
-    Drivers may expose a single or multiple decoding modes, depending
-    on what they can support.
-
-    .. note::
-
-       This menu control is not yet part of the public kernel API and
-       it is expected to change.
-
-.. c:type:: v4l2_mpeg_video_hevc_decode_mode
-
-.. cssclass:: longtable
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - ``V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_SLICE_BASED``
-      - 0
-      - Decoding is done at the slice granularity.
-        The OUTPUT buffer must contain a single slice.
-    * - ``V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_FRAME_BASED``
-      - 1
-      - Decoding is done at the frame granularity.
-        The OUTPUT buffer must contain all slices needed to decode the
-        frame. The OUTPUT buffer must also contain both fields.
-
-``V4L2_CID_MPEG_VIDEO_HEVC_START_CODE (enum)``
-    Specifies the HEVC slice start code expected for each slice.
-    This control is used as a modifier for V4L2_PIX_FMT_HEVC_SLICE
-    pixel format. Applications that support V4L2_PIX_FMT_HEVC_SLICE
-    are required to set this control in order to specify the start code
-    that is expected for the buffer.
-    Drivers may expose a single or multiple start codes, depending
-    on what they can support.
-
-    .. note::
-
-       This menu control is not yet part of the public kernel API and
-       it is expected to change.
-
-.. c:type:: v4l2_mpeg_video_hevc_start_code
-
-.. cssclass:: longtable
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - ``V4L2_MPEG_VIDEO_HEVC_START_CODE_NONE``
-      - 0
-      - Selecting this value specifies that HEVC slices are passed
-        to the driver without any start code.
-    * - ``V4L2_MPEG_VIDEO_HEVC_START_CODE_ANNEX_B``
-      - 1
-      - Selecting this value specifies that HEVC slices are expected
-        to be prefixed by Annex B start codes. According to :ref:`hevc`
-        valid start codes can be 3-bytes 0x000001 or 4-bytes 0x00000001.
diff --git a/Documentation/media/uapi/v4l/ext-ctrls-detect.rst b/Documentation/media/uapi/v4l/ext-ctrls-detect.rst
deleted file mode 100644
index 80981d0cff42..000000000000
--- a/Documentation/media/uapi/v4l/ext-ctrls-detect.rst
+++ /dev/null
@@ -1,71 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _detect-controls:
-
-************************
-Detect Control Reference
-************************
-
-The Detect class includes controls for common features of various motion
-or object detection capable devices.
-
-
-.. _detect-control-id:
-
-Detect Control IDs
-==================
-
-``V4L2_CID_DETECT_CLASS (class)``
-    The Detect class descriptor. Calling
-    :ref:`VIDIOC_QUERYCTRL` for this control will
-    return a description of this control class.
-
-``V4L2_CID_DETECT_MD_MODE (menu)``
-    Sets the motion detection mode.
-
-.. tabularcolumns:: |p{7.7cm}|p{9.8cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_DETECT_MD_MODE_DISABLED``
-      - Disable motion detection.
-    * - ``V4L2_DETECT_MD_MODE_GLOBAL``
-      - Use a single motion detection threshold.
-    * - ``V4L2_DETECT_MD_MODE_THRESHOLD_GRID``
-      - The image is divided into a grid, each cell with its own motion
-	detection threshold. These thresholds are set through the
-	``V4L2_CID_DETECT_MD_THRESHOLD_GRID`` matrix control.
-    * - ``V4L2_DETECT_MD_MODE_REGION_GRID``
-      - The image is divided into a grid, each cell with its own region
-	value that specifies which per-region motion detection thresholds
-	should be used. Each region has its own thresholds. How these
-	per-region thresholds are set up is driver-specific. The region
-	values for the grid are set through the
-	``V4L2_CID_DETECT_MD_REGION_GRID`` matrix control.
-
-
-
-``V4L2_CID_DETECT_MD_GLOBAL_THRESHOLD (integer)``
-    Sets the global motion detection threshold to be used with the
-    ``V4L2_DETECT_MD_MODE_GLOBAL`` motion detection mode.
-
-``V4L2_CID_DETECT_MD_THRESHOLD_GRID (__u16 matrix)``
-    Sets the motion detection thresholds for each cell in the grid. To
-    be used with the ``V4L2_DETECT_MD_MODE_THRESHOLD_GRID`` motion
-    detection mode. Matrix element (0, 0) represents the cell at the
-    top-left of the grid.
-
-``V4L2_CID_DETECT_MD_REGION_GRID (__u8 matrix)``
-    Sets the motion detection region value for each cell in the grid. To
-    be used with the ``V4L2_DETECT_MD_MODE_REGION_GRID`` motion
-    detection mode. Matrix element (0, 0) represents the cell at the
-    top-left of the grid.
diff --git a/Documentation/media/uapi/v4l/ext-ctrls-dv.rst b/Documentation/media/uapi/v4l/ext-ctrls-dv.rst
deleted file mode 100644
index 5c70ac98f710..000000000000
--- a/Documentation/media/uapi/v4l/ext-ctrls-dv.rst
+++ /dev/null
@@ -1,166 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _dv-controls:
-
-*******************************
-Digital Video Control Reference
-*******************************
-
-The Digital Video control class is intended to control receivers and
-transmitters for `VGA <http://en.wikipedia.org/wiki/Vga>`__,
-`DVI <http://en.wikipedia.org/wiki/Digital_Visual_Interface>`__
-(Digital Visual Interface), HDMI (:ref:`hdmi`) and DisplayPort
-(:ref:`dp`). These controls are generally expected to be private to
-the receiver or transmitter subdevice that implements them, so they are
-only exposed on the ``/dev/v4l-subdev*`` device node.
-
-.. note::
-
-   Note that these devices can have multiple input or output pads which are
-   hooked up to e.g. HDMI connectors. Even though the subdevice will
-   receive or transmit video from/to only one of those pads, the other pads
-   can still be active when it comes to EDID (Extended Display
-   Identification Data, :ref:`vesaedid`) and HDCP (High-bandwidth Digital
-   Content Protection System, :ref:`hdcp`) processing, allowing the
-   device to do the fairly slow EDID/HDCP handling in advance. This allows
-   for quick switching between connectors.
-
-These pads appear in several of the controls in this section as
-bitmasks, one bit for each pad. Bit 0 corresponds to pad 0, bit 1 to pad
-1, etc. The maximum value of the control is the set of valid pads.
-
-
-.. _dv-control-id:
-
-Digital Video Control IDs
-=========================
-
-``V4L2_CID_DV_CLASS (class)``
-    The Digital Video class descriptor.
-
-``V4L2_CID_DV_TX_HOTPLUG (bitmask)``
-    Many connectors have a hotplug pin which is high if EDID information
-    is available from the source. This control shows the state of the
-    hotplug pin as seen by the transmitter. Each bit corresponds to an
-    output pad on the transmitter. If an output pad does not have an
-    associated hotplug pin, then the bit for that pad will be 0. This
-    read-only control is applicable to DVI-D, HDMI and DisplayPort
-    connectors.
-
-``V4L2_CID_DV_TX_RXSENSE (bitmask)``
-    Rx Sense is the detection of pull-ups on the TMDS clock lines. This
-    normally means that the sink has left/entered standby (i.e. the
-    transmitter can sense that the receiver is ready to receive video).
-    Each bit corresponds to an output pad on the transmitter. If an
-    output pad does not have an associated Rx Sense, then the bit for
-    that pad will be 0. This read-only control is applicable to DVI-D
-    and HDMI devices.
-
-``V4L2_CID_DV_TX_EDID_PRESENT (bitmask)``
-    When the transmitter sees the hotplug signal from the receiver it
-    will attempt to read the EDID. If set, then the transmitter has read
-    at least the first block (= 128 bytes). Each bit corresponds to an
-    output pad on the transmitter. If an output pad does not support
-    EDIDs, then the bit for that pad will be 0. This read-only control
-    is applicable to VGA, DVI-A/D, HDMI and DisplayPort connectors.
-
-``V4L2_CID_DV_TX_MODE``
-    (enum)
-
-enum v4l2_dv_tx_mode -
-    HDMI transmitters can transmit in DVI-D mode (just video) or in HDMI
-    mode (video + audio + auxiliary data). This control selects which
-    mode to use: V4L2_DV_TX_MODE_DVI_D or V4L2_DV_TX_MODE_HDMI.
-    This control is applicable to HDMI connectors.
-
-``V4L2_CID_DV_TX_RGB_RANGE``
-    (enum)
-
-enum v4l2_dv_rgb_range -
-    Select the quantization range for RGB output. V4L2_DV_RANGE_AUTO
-    follows the RGB quantization range specified in the standard for the
-    video interface (ie. :ref:`cea861` for HDMI).
-    V4L2_DV_RANGE_LIMITED and V4L2_DV_RANGE_FULL override the
-    standard to be compatible with sinks that have not implemented the
-    standard correctly (unfortunately quite common for HDMI and DVI-D).
-    Full range allows all possible values to be used whereas limited
-    range sets the range to (16 << (N-8)) - (235 << (N-8)) where N is
-    the number of bits per component. This control is applicable to VGA,
-    DVI-A/D, HDMI and DisplayPort connectors.
-
-``V4L2_CID_DV_TX_IT_CONTENT_TYPE``
-    (enum)
-
-enum v4l2_dv_it_content_type -
-    Configures the IT Content Type of the transmitted video. This
-    information is sent over HDMI and DisplayPort connectors as part of
-    the AVI InfoFrame. The term 'IT Content' is used for content that
-    originates from a computer as opposed to content from a TV broadcast
-    or an analog source. The enum v4l2_dv_it_content_type defines
-    the possible content types:
-
-.. tabularcolumns:: |p{7.3cm}|p{10.4cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_DV_IT_CONTENT_TYPE_GRAPHICS``
-      - Graphics content. Pixel data should be passed unfiltered and
-	without analog reconstruction.
-    * - ``V4L2_DV_IT_CONTENT_TYPE_PHOTO``
-      - Photo content. The content is derived from digital still pictures.
-	The content should be passed through with minimal scaling and
-	picture enhancements.
-    * - ``V4L2_DV_IT_CONTENT_TYPE_CINEMA``
-      - Cinema content.
-    * - ``V4L2_DV_IT_CONTENT_TYPE_GAME``
-      - Game content. Audio and video latency should be minimized.
-    * - ``V4L2_DV_IT_CONTENT_TYPE_NO_ITC``
-      - No IT Content information is available and the ITC bit in the AVI
-	InfoFrame is set to 0.
-
-
-
-``V4L2_CID_DV_RX_POWER_PRESENT (bitmask)``
-    Detects whether the receiver receives power from the source (e.g.
-    HDMI carries 5V on one of the pins). This is often used to power an
-    eeprom which contains EDID information, such that the source can
-    read the EDID even if the sink is in standby/power off. Each bit
-    corresponds to an input pad on the receiver. If an input pad
-    cannot detect whether power is present, then the bit for that pad
-    will be 0. This read-only control is applicable to DVI-D, HDMI and
-    DisplayPort connectors.
-
-``V4L2_CID_DV_RX_RGB_RANGE``
-    (enum)
-
-enum v4l2_dv_rgb_range -
-    Select the quantization range for RGB input. V4L2_DV_RANGE_AUTO
-    follows the RGB quantization range specified in the standard for the
-    video interface (ie. :ref:`cea861` for HDMI).
-    V4L2_DV_RANGE_LIMITED and V4L2_DV_RANGE_FULL override the
-    standard to be compatible with sources that have not implemented the
-    standard correctly (unfortunately quite common for HDMI and DVI-D).
-    Full range allows all possible values to be used whereas limited
-    range sets the range to (16 << (N-8)) - (235 << (N-8)) where N is
-    the number of bits per component. This control is applicable to VGA,
-    DVI-A/D, HDMI and DisplayPort connectors.
-
-``V4L2_CID_DV_RX_IT_CONTENT_TYPE``
-    (enum)
-
-enum v4l2_dv_it_content_type -
-    Reads the IT Content Type of the received video. This information is
-    sent over HDMI and DisplayPort connectors as part of the AVI
-    InfoFrame. The term 'IT Content' is used for content that originates
-    from a computer as opposed to content from a TV broadcast or an
-    analog source. See ``V4L2_CID_DV_TX_IT_CONTENT_TYPE`` for the
-    available content types.
diff --git a/Documentation/media/uapi/v4l/ext-ctrls-flash.rst b/Documentation/media/uapi/v4l/ext-ctrls-flash.rst
deleted file mode 100644
index b9a6b08fbf32..000000000000
--- a/Documentation/media/uapi/v4l/ext-ctrls-flash.rst
+++ /dev/null
@@ -1,192 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _flash-controls:
-
-***********************
-Flash Control Reference
-***********************
-
-The V4L2 flash controls are intended to provide generic access to flash
-controller devices. Flash controller devices are typically used in
-digital cameras.
-
-The interface can support both LED and xenon flash devices. As of
-writing this, there is no xenon flash driver using this interface.
-
-
-.. _flash-controls-use-cases:
-
-Supported use cases
-===================
-
-
-Unsynchronised LED flash (software strobe)
-------------------------------------------
-
-Unsynchronised LED flash is controlled directly by the host as the
-sensor. The flash must be enabled by the host before the exposure of the
-image starts and disabled once it ends. The host is fully responsible
-for the timing of the flash.
-
-Example of such device: Nokia N900.
-
-
-Synchronised LED flash (hardware strobe)
-----------------------------------------
-
-The synchronised LED flash is pre-programmed by the host (power and
-timeout) but controlled by the sensor through a strobe signal from the
-sensor to the flash.
-
-The sensor controls the flash duration and timing. This information
-typically must be made available to the sensor.
-
-
-LED flash as torch
-------------------
-
-LED flash may be used as torch in conjunction with another use case
-involving camera or individually.
-
-
-.. _flash-control-id:
-
-Flash Control IDs
------------------
-
-``V4L2_CID_FLASH_CLASS (class)``
-    The FLASH class descriptor.
-
-``V4L2_CID_FLASH_LED_MODE (menu)``
-    Defines the mode of the flash LED, the high-power white LED attached
-    to the flash controller. Setting this control may not be possible in
-    presence of some faults. See V4L2_CID_FLASH_FAULT.
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_FLASH_LED_MODE_NONE``
-      - Off.
-    * - ``V4L2_FLASH_LED_MODE_FLASH``
-      - Flash mode.
-    * - ``V4L2_FLASH_LED_MODE_TORCH``
-      - Torch mode. See V4L2_CID_FLASH_TORCH_INTENSITY.
-
-
-
-``V4L2_CID_FLASH_STROBE_SOURCE (menu)``
-    Defines the source of the flash LED strobe.
-
-.. tabularcolumns:: |p{7.5cm}|p{10.0cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_FLASH_STROBE_SOURCE_SOFTWARE``
-      - The flash strobe is triggered by using the
-	V4L2_CID_FLASH_STROBE control.
-    * - ``V4L2_FLASH_STROBE_SOURCE_EXTERNAL``
-      - The flash strobe is triggered by an external source. Typically
-	this is a sensor, which makes it possible to synchronise the
-	flash strobe start to exposure start.
-
-
-
-``V4L2_CID_FLASH_STROBE (button)``
-    Strobe flash. Valid when V4L2_CID_FLASH_LED_MODE is set to
-    V4L2_FLASH_LED_MODE_FLASH and V4L2_CID_FLASH_STROBE_SOURCE
-    is set to V4L2_FLASH_STROBE_SOURCE_SOFTWARE. Setting this
-    control may not be possible in presence of some faults. See
-    V4L2_CID_FLASH_FAULT.
-
-``V4L2_CID_FLASH_STROBE_STOP (button)``
-    Stop flash strobe immediately.
-
-``V4L2_CID_FLASH_STROBE_STATUS (boolean)``
-    Strobe status: whether the flash is strobing at the moment or not.
-    This is a read-only control.
-
-``V4L2_CID_FLASH_TIMEOUT (integer)``
-    Hardware timeout for flash. The flash strobe is stopped after this
-    period of time has passed from the start of the strobe.
-
-``V4L2_CID_FLASH_INTENSITY (integer)``
-    Intensity of the flash strobe when the flash LED is in flash mode
-    (V4L2_FLASH_LED_MODE_FLASH). The unit should be milliamps (mA)
-    if possible.
-
-``V4L2_CID_FLASH_TORCH_INTENSITY (integer)``
-    Intensity of the flash LED in torch mode
-    (V4L2_FLASH_LED_MODE_TORCH). The unit should be milliamps (mA)
-    if possible. Setting this control may not be possible in presence of
-    some faults. See V4L2_CID_FLASH_FAULT.
-
-``V4L2_CID_FLASH_INDICATOR_INTENSITY (integer)``
-    Intensity of the indicator LED. The indicator LED may be fully
-    independent of the flash LED. The unit should be microamps (uA) if
-    possible.
-
-``V4L2_CID_FLASH_FAULT (bitmask)``
-    Faults related to the flash. The faults tell about specific problems
-    in the flash chip itself or the LEDs attached to it. Faults may
-    prevent further use of some of the flash controls. In particular,
-    V4L2_CID_FLASH_LED_MODE is set to V4L2_FLASH_LED_MODE_NONE
-    if the fault affects the flash LED. Exactly which faults have such
-    an effect is chip dependent. Reading the faults resets the control
-    and returns the chip to a usable state if possible.
-
-.. tabularcolumns:: |p{8.4cm}|p{9.1cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_FLASH_FAULT_OVER_VOLTAGE``
-      - Flash controller voltage to the flash LED has exceeded the limit
-	specific to the flash controller.
-    * - ``V4L2_FLASH_FAULT_TIMEOUT``
-      - The flash strobe was still on when the timeout set by the user ---
-	V4L2_CID_FLASH_TIMEOUT control --- has expired. Not all flash
-	controllers may set this in all such conditions.
-    * - ``V4L2_FLASH_FAULT_OVER_TEMPERATURE``
-      - The flash controller has overheated.
-    * - ``V4L2_FLASH_FAULT_SHORT_CIRCUIT``
-      - The short circuit protection of the flash controller has been
-	triggered.
-    * - ``V4L2_FLASH_FAULT_OVER_CURRENT``
-      - Current in the LED power supply has exceeded the limit specific to
-	the flash controller.
-    * - ``V4L2_FLASH_FAULT_INDICATOR``
-      - The flash controller has detected a short or open circuit
-	condition on the indicator LED.
-    * - ``V4L2_FLASH_FAULT_UNDER_VOLTAGE``
-      - Flash controller voltage to the flash LED has been below the
-	minimum limit specific to the flash controller.
-    * - ``V4L2_FLASH_FAULT_INPUT_VOLTAGE``
-      - The input voltage of the flash controller is below the limit under
-	which strobing the flash at full current will not be possible.The
-	condition persists until this flag is no longer set.
-    * - ``V4L2_FLASH_FAULT_LED_OVER_TEMPERATURE``
-      - The temperature of the LED has exceeded its allowed upper limit.
-
-
-
-``V4L2_CID_FLASH_CHARGE (boolean)``
-    Enable or disable charging of the xenon flash capacitor.
-
-``V4L2_CID_FLASH_READY (boolean)``
-    Is the flash ready to strobe? Xenon flashes require their capacitors
-    charged before strobing. LED flashes often require a cooldown period
-    after strobe during which another strobe will not be possible. This
-    is a read-only control.
diff --git a/Documentation/media/uapi/v4l/ext-ctrls-fm-rx.rst b/Documentation/media/uapi/v4l/ext-ctrls-fm-rx.rst
deleted file mode 100644
index 3ed6dd7f586d..000000000000
--- a/Documentation/media/uapi/v4l/ext-ctrls-fm-rx.rst
+++ /dev/null
@@ -1,95 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _fm-rx-controls:
-
-*****************************
-FM Receiver Control Reference
-*****************************
-
-The FM Receiver (FM_RX) class includes controls for common features of
-FM Reception capable devices.
-
-
-.. _fm-rx-control-id:
-
-FM_RX Control IDs
-=================
-
-``V4L2_CID_FM_RX_CLASS (class)``
-    The FM_RX class descriptor. Calling
-    :ref:`VIDIOC_QUERYCTRL` for this control will
-    return a description of this control class.
-
-``V4L2_CID_RDS_RECEPTION (boolean)``
-    Enables/disables RDS reception by the radio tuner
-
-``V4L2_CID_RDS_RX_PTY (integer)``
-    Gets RDS Programme Type field. This encodes up to 31 pre-defined
-    programme types.
-
-``V4L2_CID_RDS_RX_PS_NAME (string)``
-    Gets the Programme Service name (PS_NAME). It is intended for
-    static display on a receiver. It is the primary aid to listeners in
-    programme service identification and selection. In Annex E of
-    :ref:`iec62106`, the RDS specification, there is a full
-    description of the correct character encoding for Programme Service
-    name strings. Also from RDS specification, PS is usually a single
-    eight character text. However, it is also possible to find receivers
-    which can scroll strings sized as 8 x N characters. So, this control
-    must be configured with steps of 8 characters. The result is it must
-    always contain a string with size multiple of 8.
-
-``V4L2_CID_RDS_RX_RADIO_TEXT (string)``
-    Gets the Radio Text info. It is a textual description of what is
-    being broadcasted. RDS Radio Text can be applied when broadcaster
-    wishes to transmit longer PS names, programme-related information or
-    any other text. In these cases, RadioText can be used in addition to
-    ``V4L2_CID_RDS_RX_PS_NAME``. The encoding for Radio Text strings is
-    also fully described in Annex E of :ref:`iec62106`. The length of
-    Radio Text strings depends on which RDS Block is being used to
-    transmit it, either 32 (2A block) or 64 (2B block). However, it is
-    also possible to find receivers which can scroll strings sized as 32
-    x N or 64 x N characters. So, this control must be configured with
-    steps of 32 or 64 characters. The result is it must always contain a
-    string with size multiple of 32 or 64.
-
-``V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT (boolean)``
-    If set, then a traffic announcement is in progress.
-
-``V4L2_CID_RDS_RX_TRAFFIC_PROGRAM (boolean)``
-    If set, then the tuned programme carries traffic announcements.
-
-``V4L2_CID_RDS_RX_MUSIC_SPEECH (boolean)``
-    If set, then this channel broadcasts music. If cleared, then it
-    broadcasts speech. If the transmitter doesn't make this distinction,
-    then it will be set.
-
-``V4L2_CID_TUNE_DEEMPHASIS``
-    (enum)
-
-enum v4l2_deemphasis -
-    Configures the de-emphasis value for reception. A de-emphasis filter
-    is applied to the broadcast to accentuate the high audio
-    frequencies. Depending on the region, a time constant of either 50
-    or 75 useconds is used. The enum v4l2_deemphasis defines possible
-    values for de-emphasis. Here they are:
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_DEEMPHASIS_DISABLED``
-      - No de-emphasis is applied.
-    * - ``V4L2_DEEMPHASIS_50_uS``
-      - A de-emphasis of 50 uS is used.
-    * - ``V4L2_DEEMPHASIS_75_uS``
-      - A de-emphasis of 75 uS is used.
diff --git a/Documentation/media/uapi/v4l/ext-ctrls-fm-tx.rst b/Documentation/media/uapi/v4l/ext-ctrls-fm-tx.rst
deleted file mode 100644
index db88346d99fd..000000000000
--- a/Documentation/media/uapi/v4l/ext-ctrls-fm-tx.rst
+++ /dev/null
@@ -1,188 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _fm-tx-controls:
-
-********************************
-FM Transmitter Control Reference
-********************************
-
-The FM Transmitter (FM_TX) class includes controls for common features
-of FM transmissions capable devices. Currently this class includes
-parameters for audio compression, pilot tone generation, audio deviation
-limiter, RDS transmission and tuning power features.
-
-
-.. _fm-tx-control-id:
-
-FM_TX Control IDs
-=================
-
-``V4L2_CID_FM_TX_CLASS (class)``
-    The FM_TX class descriptor. Calling
-    :ref:`VIDIOC_QUERYCTRL` for this control will
-    return a description of this control class.
-
-``V4L2_CID_RDS_TX_DEVIATION (integer)``
-    Configures RDS signal frequency deviation level in Hz. The range and
-    step are driver-specific.
-
-``V4L2_CID_RDS_TX_PI (integer)``
-    Sets the RDS Programme Identification field for transmission.
-
-``V4L2_CID_RDS_TX_PTY (integer)``
-    Sets the RDS Programme Type field for transmission. This encodes up
-    to 31 pre-defined programme types.
-
-``V4L2_CID_RDS_TX_PS_NAME (string)``
-    Sets the Programme Service name (PS_NAME) for transmission. It is
-    intended for static display on a receiver. It is the primary aid to
-    listeners in programme service identification and selection. In
-    Annex E of :ref:`iec62106`, the RDS specification, there is a full
-    description of the correct character encoding for Programme Service
-    name strings. Also from RDS specification, PS is usually a single
-    eight character text. However, it is also possible to find receivers
-    which can scroll strings sized as 8 x N characters. So, this control
-    must be configured with steps of 8 characters. The result is it must
-    always contain a string with size multiple of 8.
-
-``V4L2_CID_RDS_TX_RADIO_TEXT (string)``
-    Sets the Radio Text info for transmission. It is a textual
-    description of what is being broadcasted. RDS Radio Text can be
-    applied when broadcaster wishes to transmit longer PS names,
-    programme-related information or any other text. In these cases,
-    RadioText should be used in addition to ``V4L2_CID_RDS_TX_PS_NAME``.
-    The encoding for Radio Text strings is also fully described in Annex
-    E of :ref:`iec62106`. The length of Radio Text strings depends on
-    which RDS Block is being used to transmit it, either 32 (2A block)
-    or 64 (2B block). However, it is also possible to find receivers
-    which can scroll strings sized as 32 x N or 64 x N characters. So,
-    this control must be configured with steps of 32 or 64 characters.
-    The result is it must always contain a string with size multiple of
-    32 or 64.
-
-``V4L2_CID_RDS_TX_MONO_STEREO (boolean)``
-    Sets the Mono/Stereo bit of the Decoder Identification code. If set,
-    then the audio was recorded as stereo.
-
-``V4L2_CID_RDS_TX_ARTIFICIAL_HEAD (boolean)``
-    Sets the
-    `Artificial Head <http://en.wikipedia.org/wiki/Artificial_head>`__
-    bit of the Decoder Identification code. If set, then the audio was
-    recorded using an artificial head.
-
-``V4L2_CID_RDS_TX_COMPRESSED (boolean)``
-    Sets the Compressed bit of the Decoder Identification code. If set,
-    then the audio is compressed.
-
-``V4L2_CID_RDS_TX_DYNAMIC_PTY (boolean)``
-    Sets the Dynamic PTY bit of the Decoder Identification code. If set,
-    then the PTY code is dynamically switched.
-
-``V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT (boolean)``
-    If set, then a traffic announcement is in progress.
-
-``V4L2_CID_RDS_TX_TRAFFIC_PROGRAM (boolean)``
-    If set, then the tuned programme carries traffic announcements.
-
-``V4L2_CID_RDS_TX_MUSIC_SPEECH (boolean)``
-    If set, then this channel broadcasts music. If cleared, then it
-    broadcasts speech. If the transmitter doesn't make this distinction,
-    then it should be set.
-
-``V4L2_CID_RDS_TX_ALT_FREQS_ENABLE (boolean)``
-    If set, then transmit alternate frequencies.
-
-``V4L2_CID_RDS_TX_ALT_FREQS (__u32 array)``
-    The alternate frequencies in kHz units. The RDS standard allows for
-    up to 25 frequencies to be defined. Drivers may support fewer
-    frequencies so check the array size.
-
-``V4L2_CID_AUDIO_LIMITER_ENABLED (boolean)``
-    Enables or disables the audio deviation limiter feature. The limiter
-    is useful when trying to maximize the audio volume, minimize
-    receiver-generated distortion and prevent overmodulation.
-
-``V4L2_CID_AUDIO_LIMITER_RELEASE_TIME (integer)``
-    Sets the audio deviation limiter feature release time. Unit is in
-    useconds. Step and range are driver-specific.
-
-``V4L2_CID_AUDIO_LIMITER_DEVIATION (integer)``
-    Configures audio frequency deviation level in Hz. The range and step
-    are driver-specific.
-
-``V4L2_CID_AUDIO_COMPRESSION_ENABLED (boolean)``
-    Enables or disables the audio compression feature. This feature
-    amplifies signals below the threshold by a fixed gain and compresses
-    audio signals above the threshold by the ratio of Threshold/(Gain +
-    Threshold).
-
-``V4L2_CID_AUDIO_COMPRESSION_GAIN (integer)``
-    Sets the gain for audio compression feature. It is a dB value. The
-    range and step are driver-specific.
-
-``V4L2_CID_AUDIO_COMPRESSION_THRESHOLD (integer)``
-    Sets the threshold level for audio compression freature. It is a dB
-    value. The range and step are driver-specific.
-
-``V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME (integer)``
-    Sets the attack time for audio compression feature. It is a useconds
-    value. The range and step are driver-specific.
-
-``V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME (integer)``
-    Sets the release time for audio compression feature. It is a
-    useconds value. The range and step are driver-specific.
-
-``V4L2_CID_PILOT_TONE_ENABLED (boolean)``
-    Enables or disables the pilot tone generation feature.
-
-``V4L2_CID_PILOT_TONE_DEVIATION (integer)``
-    Configures pilot tone frequency deviation level. Unit is in Hz. The
-    range and step are driver-specific.
-
-``V4L2_CID_PILOT_TONE_FREQUENCY (integer)``
-    Configures pilot tone frequency value. Unit is in Hz. The range and
-    step are driver-specific.
-
-``V4L2_CID_TUNE_PREEMPHASIS``
-    (enum)
-
-enum v4l2_preemphasis -
-    Configures the pre-emphasis value for broadcasting. A pre-emphasis
-    filter is applied to the broadcast to accentuate the high audio
-    frequencies. Depending on the region, a time constant of either 50
-    or 75 useconds is used. The enum v4l2_preemphasis defines possible
-    values for pre-emphasis. Here they are:
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_PREEMPHASIS_DISABLED``
-      - No pre-emphasis is applied.
-    * - ``V4L2_PREEMPHASIS_50_uS``
-      - A pre-emphasis of 50 uS is used.
-    * - ``V4L2_PREEMPHASIS_75_uS``
-      - A pre-emphasis of 75 uS is used.
-
-
-
-``V4L2_CID_TUNE_POWER_LEVEL (integer)``
-    Sets the output power level for signal transmission. Unit is in
-    dBuV. Range and step are driver-specific.
-
-``V4L2_CID_TUNE_ANTENNA_CAPACITOR (integer)``
-    This selects the value of antenna tuning capacitor manually or
-    automatically if set to zero. Unit, range and step are
-    driver-specific.
-
-For more details about RDS specification, refer to :ref:`iec62106`
-document, from CENELEC.
diff --git a/Documentation/media/uapi/v4l/ext-ctrls-image-process.rst b/Documentation/media/uapi/v4l/ext-ctrls-image-process.rst
deleted file mode 100644
index 22fc2d3e433d..000000000000
--- a/Documentation/media/uapi/v4l/ext-ctrls-image-process.rst
+++ /dev/null
@@ -1,63 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _image-process-controls:
-
-*******************************
-Image Process Control Reference
-*******************************
-
-The Image Process control class is intended for low-level control of
-image processing functions. Unlike ``V4L2_CID_IMAGE_SOURCE_CLASS``, the
-controls in this class affect processing the image, and do not control
-capturing of it.
-
-
-.. _image-process-control-id:
-
-Image Process Control IDs
-=========================
-
-``V4L2_CID_IMAGE_PROC_CLASS (class)``
-    The IMAGE_PROC class descriptor.
-
-``V4L2_CID_LINK_FREQ (integer menu)``
-    Data bus frequency. Together with the media bus pixel code, bus type
-    (clock cycles per sample), the data bus frequency defines the pixel
-    rate (``V4L2_CID_PIXEL_RATE``) in the pixel array (or possibly
-    elsewhere, if the device is not an image sensor). The frame rate can
-    be calculated from the pixel clock, image width and height and
-    horizontal and vertical blanking. While the pixel rate control may
-    be defined elsewhere than in the subdev containing the pixel array,
-    the frame rate cannot be obtained from that information. This is
-    because only on the pixel array it can be assumed that the vertical
-    and horizontal blanking information is exact: no other blanking is
-    allowed in the pixel array. The selection of frame rate is performed
-    by selecting the desired horizontal and vertical blanking. The unit
-    of this control is Hz.
-
-``V4L2_CID_PIXEL_RATE (64-bit integer)``
-    Pixel rate in the source pads of the subdev. This control is
-    read-only and its unit is pixels / second.
-
-``V4L2_CID_TEST_PATTERN (menu)``
-    Some capture/display/sensor devices have the capability to generate
-    test pattern images. These hardware specific test patterns can be
-    used to test if a device is working properly.
-
-``V4L2_CID_DEINTERLACING_MODE (menu)``
-    The video deinterlacing mode (such as Bob, Weave, ...). The menu items are
-    driver specific and are documented in :ref:`v4l-drivers`.
-
-``V4L2_CID_DIGITAL_GAIN (integer)``
-    Digital gain is the value by which all colour components
-    are multiplied by. Typically the digital gain applied is the
-    control value divided by e.g. 0x100, meaning that to get no
-    digital gain the control value needs to be 0x100. The no-gain
-    configuration is also typically the default.
diff --git a/Documentation/media/uapi/v4l/ext-ctrls-image-source.rst b/Documentation/media/uapi/v4l/ext-ctrls-image-source.rst
deleted file mode 100644
index 2d3e2b83d6dd..000000000000
--- a/Documentation/media/uapi/v4l/ext-ctrls-image-source.rst
+++ /dev/null
@@ -1,67 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _image-source-controls:
-
-******************************
-Image Source Control Reference
-******************************
-
-The Image Source control class is intended for low-level control of
-image source devices such as image sensors. The devices feature an
-analogue to digital converter and a bus transmitter to transmit the
-image data out of the device.
-
-
-.. _image-source-control-id:
-
-Image Source Control IDs
-========================
-
-``V4L2_CID_IMAGE_SOURCE_CLASS (class)``
-    The IMAGE_SOURCE class descriptor.
-
-``V4L2_CID_VBLANK (integer)``
-    Vertical blanking. The idle period after every frame during which no
-    image data is produced. The unit of vertical blanking is a line.
-    Every line has length of the image width plus horizontal blanking at
-    the pixel rate defined by ``V4L2_CID_PIXEL_RATE`` control in the
-    same sub-device.
-
-``V4L2_CID_HBLANK (integer)``
-    Horizontal blanking. The idle period after every line of image data
-    during which no image data is produced. The unit of horizontal
-    blanking is pixels.
-
-``V4L2_CID_ANALOGUE_GAIN (integer)``
-    Analogue gain is gain affecting all colour components in the pixel
-    matrix. The gain operation is performed in the analogue domain
-    before A/D conversion.
-
-``V4L2_CID_TEST_PATTERN_RED (integer)``
-    Test pattern red colour component.
-
-``V4L2_CID_TEST_PATTERN_GREENR (integer)``
-    Test pattern green (next to red) colour component.
-
-``V4L2_CID_TEST_PATTERN_BLUE (integer)``
-    Test pattern blue colour component.
-
-``V4L2_CID_TEST_PATTERN_GREENB (integer)``
-    Test pattern green (next to blue) colour component.
-
-``V4L2_CID_UNIT_CELL_SIZE (struct)``
-    This control returns the unit cell size in nanometers. The struct
-    :c:type:`v4l2_area` provides the width and the height in separate
-    fields to take into consideration asymmetric pixels.
-    This control does not take into consideration any possible hardware
-    binning.
-    The unit cell consists of the whole area of the pixel, sensitive and
-    non-sensitive.
-    This control is required for automatic calibration of sensors/cameras.
diff --git a/Documentation/media/uapi/v4l/ext-ctrls-jpeg.rst b/Documentation/media/uapi/v4l/ext-ctrls-jpeg.rst
deleted file mode 100644
index 60ce3f949319..000000000000
--- a/Documentation/media/uapi/v4l/ext-ctrls-jpeg.rst
+++ /dev/null
@@ -1,113 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _jpeg-controls:
-
-**********************
-JPEG Control Reference
-**********************
-
-The JPEG class includes controls for common features of JPEG encoders
-and decoders. Currently it includes features for codecs implementing
-progressive baseline DCT compression process with Huffman entrophy
-coding.
-
-
-.. _jpeg-control-id:
-
-JPEG Control IDs
-================
-
-``V4L2_CID_JPEG_CLASS (class)``
-    The JPEG class descriptor. Calling
-    :ref:`VIDIOC_QUERYCTRL` for this control will
-    return a description of this control class.
-
-``V4L2_CID_JPEG_CHROMA_SUBSAMPLING (menu)``
-    The chroma subsampling factors describe how each component of an
-    input image is sampled, in respect to maximum sample rate in each
-    spatial dimension. See :ref:`itu-t81`, clause A.1.1. for more
-    details. The ``V4L2_CID_JPEG_CHROMA_SUBSAMPLING`` control determines
-    how Cb and Cr components are downsampled after converting an input
-    image from RGB to Y'CbCr color space.
-
-.. tabularcolumns:: |p{7.5cm}|p{10.0cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_JPEG_CHROMA_SUBSAMPLING_444``
-      - No chroma subsampling, each pixel has Y, Cr and Cb values.
-    * - ``V4L2_JPEG_CHROMA_SUBSAMPLING_422``
-      - Horizontally subsample Cr, Cb components by a factor of 2.
-    * - ``V4L2_JPEG_CHROMA_SUBSAMPLING_420``
-      - Subsample Cr, Cb components horizontally and vertically by 2.
-    * - ``V4L2_JPEG_CHROMA_SUBSAMPLING_411``
-      - Horizontally subsample Cr, Cb components by a factor of 4.
-    * - ``V4L2_JPEG_CHROMA_SUBSAMPLING_410``
-      - Subsample Cr, Cb components horizontally by 4 and vertically by 2.
-    * - ``V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY``
-      - Use only luminance component.
-
-
-
-``V4L2_CID_JPEG_RESTART_INTERVAL (integer)``
-    The restart interval determines an interval of inserting RSTm
-    markers (m = 0..7). The purpose of these markers is to additionally
-    reinitialize the encoder process, in order to process blocks of an
-    image independently. For the lossy compression processes the restart
-    interval unit is MCU (Minimum Coded Unit) and its value is contained
-    in DRI (Define Restart Interval) marker. If
-    ``V4L2_CID_JPEG_RESTART_INTERVAL`` control is set to 0, DRI and RSTm
-    markers will not be inserted.
-
-.. _jpeg-quality-control:
-
-``V4L2_CID_JPEG_COMPRESSION_QUALITY (integer)``
-    ``V4L2_CID_JPEG_COMPRESSION_QUALITY`` control determines trade-off
-    between image quality and size. It provides simpler method for
-    applications to control image quality, without a need for direct
-    reconfiguration of luminance and chrominance quantization tables. In
-    cases where a driver uses quantization tables configured directly by
-    an application, using interfaces defined elsewhere,
-    ``V4L2_CID_JPEG_COMPRESSION_QUALITY`` control should be set by
-    driver to 0.
-
-    The value range of this control is driver-specific. Only positive,
-    non-zero values are meaningful. The recommended range is 1 - 100,
-    where larger values correspond to better image quality.
-
-.. _jpeg-active-marker-control:
-
-``V4L2_CID_JPEG_ACTIVE_MARKER (bitmask)``
-    Specify which JPEG markers are included in compressed stream. This
-    control is valid only for encoders.
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - ``V4L2_JPEG_ACTIVE_MARKER_APP0``
-      - Application data segment APP\ :sub:`0`.
-    * - ``V4L2_JPEG_ACTIVE_MARKER_APP1``
-      - Application data segment APP\ :sub:`1`.
-    * - ``V4L2_JPEG_ACTIVE_MARKER_COM``
-      - Comment segment.
-    * - ``V4L2_JPEG_ACTIVE_MARKER_DQT``
-      - Quantization tables segment.
-    * - ``V4L2_JPEG_ACTIVE_MARKER_DHT``
-      - Huffman tables segment.
-
-
-
-For more details about JPEG specification, refer to :ref:`itu-t81`,
-:ref:`jfif`, :ref:`w3c-jpeg-jfif`.
diff --git a/Documentation/media/uapi/v4l/ext-ctrls-rf-tuner.rst b/Documentation/media/uapi/v4l/ext-ctrls-rf-tuner.rst
deleted file mode 100644
index 0fb85ba878dd..000000000000
--- a/Documentation/media/uapi/v4l/ext-ctrls-rf-tuner.rst
+++ /dev/null
@@ -1,96 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _rf-tuner-controls:
-
-**************************
-RF Tuner Control Reference
-**************************
-
-The RF Tuner (RF_TUNER) class includes controls for common features of
-devices having RF tuner.
-
-In this context, RF tuner is radio receiver circuit between antenna and
-demodulator. It receives radio frequency (RF) from the antenna and
-converts that received signal to lower intermediate frequency (IF) or
-baseband frequency (BB). Tuners that could do baseband output are often
-called Zero-IF tuners. Older tuners were typically simple PLL tuners
-inside a metal box, while newer ones are highly integrated chips
-without a metal box "silicon tuners". These controls are mostly
-applicable for new feature rich silicon tuners, just because older
-tuners does not have much adjustable features.
-
-For more information about RF tuners see
-`Tuner (radio) <http://en.wikipedia.org/wiki/Tuner_%28radio%29>`__
-and `RF front end <http://en.wikipedia.org/wiki/RF_front_end>`__
-from Wikipedia.
-
-
-.. _rf-tuner-control-id:
-
-RF_TUNER Control IDs
-====================
-
-``V4L2_CID_RF_TUNER_CLASS (class)``
-    The RF_TUNER class descriptor. Calling
-    :ref:`VIDIOC_QUERYCTRL` for this control will
-    return a description of this control class.
-
-``V4L2_CID_RF_TUNER_BANDWIDTH_AUTO (boolean)``
-    Enables/disables tuner radio channel bandwidth configuration. In
-    automatic mode bandwidth configuration is performed by the driver.
-
-``V4L2_CID_RF_TUNER_BANDWIDTH (integer)``
-    Filter(s) on tuner signal path are used to filter signal according
-    to receiving party needs. Driver configures filters to fulfill
-    desired bandwidth requirement. Used when
-    V4L2_CID_RF_TUNER_BANDWIDTH_AUTO is not set. Unit is in Hz. The
-    range and step are driver-specific.
-
-``V4L2_CID_RF_TUNER_LNA_GAIN_AUTO (boolean)``
-    Enables/disables LNA automatic gain control (AGC)
-
-``V4L2_CID_RF_TUNER_MIXER_GAIN_AUTO (boolean)``
-    Enables/disables mixer automatic gain control (AGC)
-
-``V4L2_CID_RF_TUNER_IF_GAIN_AUTO (boolean)``
-    Enables/disables IF automatic gain control (AGC)
-
-``V4L2_CID_RF_TUNER_RF_GAIN (integer)``
-    The RF amplifier is the very first amplifier on the receiver signal
-    path, just right after the antenna input. The difference between the
-    LNA gain and the RF gain in this document is that the LNA gain is
-    integrated in the tuner chip while the RF gain is a separate chip.
-    There may be both RF and LNA gain controls in the same device. The
-    range and step are driver-specific.
-
-``V4L2_CID_RF_TUNER_LNA_GAIN (integer)``
-    LNA (low noise amplifier) gain is first gain stage on the RF tuner
-    signal path. It is located very close to tuner antenna input. Used
-    when ``V4L2_CID_RF_TUNER_LNA_GAIN_AUTO`` is not set. See
-    ``V4L2_CID_RF_TUNER_RF_GAIN`` to understand how RF gain and LNA gain
-    differs from the each others. The range and step are
-    driver-specific.
-
-``V4L2_CID_RF_TUNER_MIXER_GAIN (integer)``
-    Mixer gain is second gain stage on the RF tuner signal path. It is
-    located inside mixer block, where RF signal is down-converted by the
-    mixer. Used when ``V4L2_CID_RF_TUNER_MIXER_GAIN_AUTO`` is not set.
-    The range and step are driver-specific.
-
-``V4L2_CID_RF_TUNER_IF_GAIN (integer)``
-    IF gain is last gain stage on the RF tuner signal path. It is
-    located on output of RF tuner. It controls signal level of
-    intermediate frequency output or baseband output. Used when
-    ``V4L2_CID_RF_TUNER_IF_GAIN_AUTO`` is not set. The range and step
-    are driver-specific.
-
-``V4L2_CID_RF_TUNER_PLL_LOCK (boolean)``
-    Is synthesizer PLL locked? RF tuner is receiving given frequency
-    when that control is set. This is a read-only control.
diff --git a/Documentation/media/uapi/v4l/extended-controls.rst b/Documentation/media/uapi/v4l/extended-controls.rst
deleted file mode 100644
index 655362483730..000000000000
--- a/Documentation/media/uapi/v4l/extended-controls.rst
+++ /dev/null
@@ -1,180 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _extended-controls:
-
-*********************
-Extended Controls API
-*********************
-
-
-Introduction
-============
-
-The control mechanism as originally designed was meant to be used for
-user settings (brightness, saturation, etc). However, it turned out to
-be a very useful model for implementing more complicated driver APIs
-where each driver implements only a subset of a larger API.
-
-The MPEG encoding API was the driving force behind designing and
-implementing this extended control mechanism: the MPEG standard is quite
-large and the currently supported hardware MPEG encoders each only
-implement a subset of this standard. Further more, many parameters
-relating to how the video is encoded into an MPEG stream are specific to
-the MPEG encoding chip since the MPEG standard only defines the format
-of the resulting MPEG stream, not how the video is actually encoded into
-that format.
-
-Unfortunately, the original control API lacked some features needed for
-these new uses and so it was extended into the (not terribly originally
-named) extended control API.
-
-Even though the MPEG encoding API was the first effort to use the
-Extended Control API, nowadays there are also other classes of Extended
-Controls, such as Camera Controls and FM Transmitter Controls. The
-Extended Controls API as well as all Extended Controls classes are
-described in the following text.
-
-
-The Extended Control API
-========================
-
-Three new ioctls are available:
-:ref:`VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>`,
-:ref:`VIDIOC_S_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` and
-:ref:`VIDIOC_TRY_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>`. These ioctls act
-on arrays of controls (as opposed to the
-:ref:`VIDIOC_G_CTRL <VIDIOC_G_CTRL>` and
-:ref:`VIDIOC_S_CTRL <VIDIOC_G_CTRL>` ioctls that act on a single
-control). This is needed since it is often required to atomically change
-several controls at once.
-
-Each of the new ioctls expects a pointer to a struct
-:c:type:`v4l2_ext_controls`. This structure
-contains a pointer to the control array, a count of the number of
-controls in that array and a control class. Control classes are used to
-group similar controls into a single class. For example, control class
-``V4L2_CTRL_CLASS_USER`` contains all user controls (i. e. all controls
-that can also be set using the old :ref:`VIDIOC_S_CTRL <VIDIOC_G_CTRL>`
-ioctl). Control class ``V4L2_CTRL_CLASS_MPEG`` contains all controls
-relating to MPEG encoding, etc.
-
-All controls in the control array must belong to the specified control
-class. An error is returned if this is not the case.
-
-It is also possible to use an empty control array (``count`` == 0) to check
-whether the specified control class is supported.
-
-The control array is a struct
-:c:type:`v4l2_ext_control` array. The
-struct :c:type:`v4l2_ext_control` is very similar to
-struct :c:type:`v4l2_control`, except for the fact that
-it also allows for 64-bit values and pointers to be passed.
-
-Since the struct :c:type:`v4l2_ext_control` supports
-pointers it is now also possible to have controls with compound types
-such as N-dimensional arrays and/or structures. You need to specify the
-``V4L2_CTRL_FLAG_NEXT_COMPOUND`` when enumerating controls to actually
-be able to see such compound controls. In other words, these controls
-with compound types should only be used programmatically.
-
-Since such compound controls need to expose more information about
-themselves than is possible with :ref:`VIDIOC_QUERYCTRL <VIDIOC_QUERYCTRL>`
-the :ref:`VIDIOC_QUERY_EXT_CTRL <VIDIOC_QUERYCTRL>` ioctl was added. In
-particular, this ioctl gives the dimensions of the N-dimensional array if
-this control consists of more than one element.
-
-.. note::
-
-   #. It is important to realize that due to the flexibility of controls it is
-      necessary to check whether the control you want to set actually is
-      supported in the driver and what the valid range of values is. So use
-      :ref:`VIDIOC_QUERYCTRL` to check this.
-
-   #. It is possible that some of the menu indices in a control of
-      type ``V4L2_CTRL_TYPE_MENU`` may not be supported (``VIDIOC_QUERYMENU``
-      will return an error). A good example is the list of supported MPEG
-      audio bitrates. Some drivers only support one or two bitrates, others
-      support a wider range.
-
-All controls use machine endianness.
-
-
-Enumerating Extended Controls
-=============================
-
-The recommended way to enumerate over the extended controls is by using
-:ref:`VIDIOC_QUERYCTRL` in combination with the
-``V4L2_CTRL_FLAG_NEXT_CTRL`` flag:
-
-
-.. code-block:: c
-
-    struct v4l2_queryctrl qctrl;
-
-    qctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL;
-    while (0 == ioctl (fd, VIDIOC_QUERYCTRL, &qctrl)) {
-	/* ... */
-	qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
-    }
-
-The initial control ID is set to 0 ORed with the
-``V4L2_CTRL_FLAG_NEXT_CTRL`` flag. The ``VIDIOC_QUERYCTRL`` ioctl will
-return the first control with a higher ID than the specified one. When
-no such controls are found an error is returned.
-
-If you want to get all controls within a specific control class, then
-you can set the initial ``qctrl.id`` value to the control class and add
-an extra check to break out of the loop when a control of another
-control class is found:
-
-
-.. code-block:: c
-
-    qctrl.id = V4L2_CTRL_CLASS_MPEG | V4L2_CTRL_FLAG_NEXT_CTRL;
-    while (0 == ioctl(fd, VIDIOC_QUERYCTRL, &qctrl)) {
-	if (V4L2_CTRL_ID2CLASS(qctrl.id) != V4L2_CTRL_CLASS_MPEG)
-	    break;
-	/* ... */
-	qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
-    }
-
-The 32-bit ``qctrl.id`` value is subdivided into three bit ranges: the
-top 4 bits are reserved for flags (e. g. ``V4L2_CTRL_FLAG_NEXT_CTRL``)
-and are not actually part of the ID. The remaining 28 bits form the
-control ID, of which the most significant 12 bits define the control
-class and the least significant 16 bits identify the control within the
-control class. It is guaranteed that these last 16 bits are always
-non-zero for controls. The range of 0x1000 and up are reserved for
-driver-specific controls. The macro ``V4L2_CTRL_ID2CLASS(id)`` returns
-the control class ID based on a control ID.
-
-If the driver does not support extended controls, then
-``VIDIOC_QUERYCTRL`` will fail when used in combination with
-``V4L2_CTRL_FLAG_NEXT_CTRL``. In that case the old method of enumerating
-control should be used (see :ref:`enum_all_controls`). But if it is
-supported, then it is guaranteed to enumerate over all controls,
-including driver-private controls.
-
-
-Creating Control Panels
-=======================
-
-It is possible to create control panels for a graphical user interface
-where the user can select the various controls. Basically you will have
-to iterate over all controls using the method described above. Each
-control class starts with a control of type
-``V4L2_CTRL_TYPE_CTRL_CLASS``. ``VIDIOC_QUERYCTRL`` will return the name
-of this control class which can be used as the title of a tab page
-within a control panel.
-
-The flags field of struct :ref:`v4l2_queryctrl <v4l2-queryctrl>` also
-contains hints on the behavior of the control. See the
-:ref:`VIDIOC_QUERYCTRL` documentation for more
-details.
diff --git a/Documentation/media/uapi/v4l/field-order.rst b/Documentation/media/uapi/v4l/field-order.rst
deleted file mode 100644
index c422bebe4314..000000000000
--- a/Documentation/media/uapi/v4l/field-order.rst
+++ /dev/null
@@ -1,172 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _field-order:
-
-***********
-Field Order
-***********
-
-We have to distinguish between progressive and interlaced video.
-Progressive video transmits all lines of a video image sequentially.
-Interlaced video divides an image into two fields, containing only the
-odd and even lines of the image, respectively. Alternating the so called
-odd and even field are transmitted, and due to a small delay between
-fields a cathode ray TV displays the lines interleaved, yielding the
-original frame. This curious technique was invented because at refresh
-rates similar to film the image would fade out too quickly. Transmitting
-fields reduces the flicker without the necessity of doubling the frame
-rate and with it the bandwidth required for each channel.
-
-It is important to understand a video camera does not expose one frame
-at a time, merely transmitting the frames separated into fields. The
-fields are in fact captured at two different instances in time. An
-object on screen may well move between one field and the next. For
-applications analysing motion it is of paramount importance to recognize
-which field of a frame is older, the *temporal order*.
-
-When the driver provides or accepts images field by field rather than
-interleaved, it is also important applications understand how the fields
-combine to frames. We distinguish between top (aka odd) and bottom (aka
-even) fields, the *spatial order*: The first line of the top field is
-the first line of an interlaced frame, the first line of the bottom
-field is the second line of that frame.
-
-However because fields were captured one after the other, arguing
-whether a frame commences with the top or bottom field is pointless. Any
-two successive top and bottom, or bottom and top fields yield a valid
-frame. Only when the source was progressive to begin with, e. g. when
-transferring film to video, two fields may come from the same frame,
-creating a natural order.
-
-Counter to intuition the top field is not necessarily the older field.
-Whether the older field contains the top or bottom lines is a convention
-determined by the video standard. Hence the distinction between temporal
-and spatial order of fields. The diagrams below should make this
-clearer.
-
-In V4L it is assumed that all video cameras transmit fields on the media
-bus in the same order they were captured, so if the top field was
-captured first (is the older field), the top field is also transmitted
-first on the bus.
-
-All video capture and output devices must report the current field
-order. Some drivers may permit the selection of a different order, to
-this end applications initialize the ``field`` field of struct
-:c:type:`v4l2_pix_format` before calling the
-:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl. If this is not desired it
-should have the value ``V4L2_FIELD_ANY`` (0).
-
-
-enum v4l2_field
-===============
-
-.. c:type:: v4l2_field
-
-.. tabularcolumns:: |p{5.8cm}|p{0.6cm}|p{11.1cm}|
-
-.. cssclass:: longtable
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_FIELD_ANY``
-      - 0
-      - Applications request this field order when any field format
-	is acceptable. Drivers choose depending on hardware capabilities or
-	e.g. the requested image size, and return the actual field order.
-	Drivers must never return ``V4L2_FIELD_ANY``.
-	If multiple field orders are possible the
-	driver must choose one of the possible field orders during
-	:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` or
-	:ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>`. struct
-	:c:type:`v4l2_buffer` ``field`` can never be
-	``V4L2_FIELD_ANY``.
-    * - ``V4L2_FIELD_NONE``
-      - 1
-      - Images are in progressive (frame-based) format, not interlaced
-        (field-based).
-    * - ``V4L2_FIELD_TOP``
-      - 2
-      - Images consist of the top (aka odd) field only.
-    * - ``V4L2_FIELD_BOTTOM``
-      - 3
-      - Images consist of the bottom (aka even) field only. Applications
-	may wish to prevent a device from capturing interlaced images
-	because they will have "comb" or "feathering" artefacts around
-	moving objects.
-    * - ``V4L2_FIELD_INTERLACED``
-      - 4
-      - Images contain both fields, interleaved line by line. The temporal
-	order of the fields (whether the top or bottom field is older)
-	depends on the current video standard. In M/NTSC the bottom
-	field is the older field. In all other standards the top field
-	is the older field.
-    * - ``V4L2_FIELD_SEQ_TB``
-      - 5
-      - Images contain both fields, the top field lines are stored first
-	in memory, immediately followed by the bottom field lines. Fields
-	are always stored in temporal order, the older one first in
-	memory. Image sizes refer to the frame, not fields.
-    * - ``V4L2_FIELD_SEQ_BT``
-      - 6
-      - Images contain both fields, the bottom field lines are stored
-	first in memory, immediately followed by the top field lines.
-	Fields are always stored in temporal order, the older one first in
-	memory. Image sizes refer to the frame, not fields.
-    * - ``V4L2_FIELD_ALTERNATE``
-      - 7
-      - The two fields of a frame are passed in separate buffers, in
-	temporal order, i. e. the older one first. To indicate the field
-	parity (whether the current field is a top or bottom field) the
-	driver or application, depending on data direction, must set
-	struct :c:type:`v4l2_buffer` ``field`` to
-	``V4L2_FIELD_TOP`` or ``V4L2_FIELD_BOTTOM``. Any two successive
-	fields pair to build a frame. If fields are successive, without
-	any dropped fields between them (fields can drop individually),
-	can be determined from the struct
-	:c:type:`v4l2_buffer` ``sequence`` field. This
-	format cannot be selected when using the read/write I/O method
-	since there is no way to communicate if a field was a top or
-	bottom field.
-    * - ``V4L2_FIELD_INTERLACED_TB``
-      - 8
-      - Images contain both fields, interleaved line by line, top field
-	first. The top field is the older field.
-    * - ``V4L2_FIELD_INTERLACED_BT``
-      - 9
-      - Images contain both fields, interleaved line by line, top field
-	first. The bottom field is the older field.
-
-
-
-.. _fieldseq-tb:
-
-Field Order, Top Field First Transmitted
-========================================
-
-.. kernel-figure:: fieldseq_tb.svg
-    :alt:    fieldseq_tb.svg
-    :align:  center
-
-    Field Order, Top Field First Transmitted
-
-
-.. _fieldseq-bt:
-
-Field Order, Bottom Field First Transmitted
-===========================================
-
-.. kernel-figure:: fieldseq_bt.svg
-    :alt:    fieldseq_bt.svg
-    :align:  center
-
-    Field Order, Bottom Field First Transmitted
diff --git a/Documentation/media/uapi/v4l/fieldseq_bt.svg b/Documentation/media/uapi/v4l/fieldseq_bt.svg
deleted file mode 100644
index 1dab1cd1b6de..000000000000
--- a/Documentation/media/uapi/v4l/fieldseq_bt.svg
+++ /dev/null
@@ -1,2621 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!--
-    Permission is granted to copy, distribute and/or modify this
-    document under the terms of the GNU Free Documentation License,
-    Version 1.1 or any later version published by the Free Software
-    Foundation, with no Invariant Sections, no Front-Cover Texts
-    and no Back-Cover Texts. A copy of the license is included at
-    Documentation/media/uapi/fdl-appendix.rst.
-
-    TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
--->
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   id="svg3619"
-   version="1.1"
-   inkscape:version="0.91 r13725"
-   xml:space="preserve"
-   width="198.48296mm"
-   height="211.89406mm"
-   viewBox="0 0 703.28606 750.80571"
-   sodipodi:docname="fieldseq_bt.svg"><sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="1920"
-     inkscape:window-height="997"
-     id="namedview3621"
-     showgrid="false"
-     units="mm"
-     fit-margin-top="0"
-     fit-margin-left="0"
-     fit-margin-right="0"
-     fit-margin-bottom="0"
-     inkscape:zoom="1.0721815"
-     inkscape:cx="8.4175633"
-     inkscape:cy="371.67214"
-     inkscape:window-x="1920"
-     inkscape:window-y="30"
-     inkscape:window-maximized="1"
-     inkscape:current-layer="g3627" /><metadata
-     id="metadata3625"><rdf:RDF><cc:Work
-	 rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
-	   rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
-     id="defs3623"><clipPath
-       id="clipPath4301"
-       clipPathUnits="userSpaceOnUse"><path
-	 style="clip-rule:evenodd"
-	 inkscape:connector-curvature="0"
-	 id="path4303"
-	 d="M 0,6040 0,0 l 5650,0 0,6040 -5650,0 z m 4786.76,-99.89 103.92,0 0,56.69 -103.92,0 0,0 85.03,-28.35 -85.03,-28.34 z" /></clipPath></defs><g
-     transform="matrix(1.25,0,0,-1.25,-1.0537,751.94632)"
-     inkscape:label="fieldseq_bt"
-     inkscape:groupmode="layer"
-     id="g3627"><path
-       d="m 188.622,346.001 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3631"
-       inkscape:connector-curvature="0" /><path
-       d="m 375.693,346.001 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3633"
-       inkscape:connector-curvature="0" /><path
-       d="m 282.157,346.001 93.5355,0 0,42.516 -93.5355,0 0,-42.516 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3635"
-       inkscape:connector-curvature="0" /><path
-       d="m 469.228,346.001 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3637"
-       inkscape:connector-curvature="0" /><path
-       d="m 95.0867,346.001 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3639"
-       inkscape:connector-curvature="0" /><path
-       d="m 1.55156,346.001 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3641"
-       inkscape:connector-curvature="0" /><path
-       d="m 95.0867,482.052 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3643"
-       inkscape:connector-curvature="0" /><path
-       d="m 469.228,482.052 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3645"
-       inkscape:connector-curvature="0" /><path
-       d="m 1.55156,414.027 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3647"
-       inkscape:connector-curvature="0" /><path
-       d="m 188.622,414.027 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3649"
-       inkscape:connector-curvature="0" /><path
-       d="m 375.693,414.027 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3651"
-       inkscape:connector-curvature="0" /><path
-       d="m 469.228,214.201 93.5352,0 0,76.5289 -93.5352,0 0,-76.5289 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3653"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,579.839 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3655"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,579.839 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3657"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,571.336 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3659"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,571.336 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3661"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,562.832 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3663"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,562.832 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3665"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,554.329 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3667"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,554.329 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3669"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,575.587 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3671"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,575.587 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3673"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,567.084 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3675"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,567.084 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3677"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,558.581 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3679"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,558.581 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3681"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,550.078 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3683"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,550.078 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3685"
-       inkscape:connector-curvature="0" /><path
-       d="m 282.157,482.052 93.5355,0 0,42.516 -93.5355,0 0,-42.516 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3687"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,222.704 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3689"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,222.704 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3691"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,231.207 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3693"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,231.207 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3695"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,226.956 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3697"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,226.956 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3699"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,239.711 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3701"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,239.711 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3703"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,235.459 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3705"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,235.459 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3707"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,248.214 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3709"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,248.214 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3711"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,243.962 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3713"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,243.962 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3715"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,256.717 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3717"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,256.717 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3719"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,252.466 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3721"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,252.466 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3723"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,265.22 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3725"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,265.22 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3727"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,260.969 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3729"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,260.969 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3731"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,273.723 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3733"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,273.723 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3735"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,269.472 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3737"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,269.472 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3739"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,277.975 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3741"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,277.975 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3743"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,218.453 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3745"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,218.453 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3747"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,282.227 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3749"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,282.227 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3751"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,380.014 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3753"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,380.014 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3755"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,371.511 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3757"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,371.511 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3759"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,363.007 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3761"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,363.007 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3763"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,354.504 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3765"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,354.504 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3767"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,375.762 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3769"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,375.762 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3771"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,367.259 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3773"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,367.259 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3775"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,358.755 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3777"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,358.755 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3779"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,350.252 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3781"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,350.252 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3783"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,375.762 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3785"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,375.762 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3787"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,367.259 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3789"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,367.259 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3791"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,358.755 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3793"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,358.755 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3795"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,350.252 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3797"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,350.252 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3799"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,380.014 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3801"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,380.014 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3803"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,371.511 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3805"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,371.511 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3807"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,363.007 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3809"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,363.007 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3811"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,354.504 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3813"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,354.504 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3815"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,363.007 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3817"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,363.007 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3819"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,371.511 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3821"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,371.511 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3823"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,354.504 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3825"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,354.504 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3827"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,375.762 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3829"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,375.762 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3831"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,367.259 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3833"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,367.259 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3835"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,358.755 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3837"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,358.755 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3839"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,350.252 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3841"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,350.252 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3843"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,380.014 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3845"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,380.014 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3847"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,380.014 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3849"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,380.014 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3851"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,371.511 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3853"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,371.511 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3855"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,363.007 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3857"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,363.007 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3859"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,354.504 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3861"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,354.504 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3863"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,358.755 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3865"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,358.755 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3867"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,350.252 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3869"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,350.252 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3871"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,367.259 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3873"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,367.259 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3875"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,375.762 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3877"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,375.762 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3879"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,380.014 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3881"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,380.014 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3883"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,371.511 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3885"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,371.511 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3887"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,363.007 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3889"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,363.007 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3891"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,354.504 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3893"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,354.504 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3895"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,375.762 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3897"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,375.762 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3899"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,367.259 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3901"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,367.259 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3903"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,358.755 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3905"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,358.755 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3907"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,350.252 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3909"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,350.252 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3911"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,375.762 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3913"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,375.762 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3915"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,367.259 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3917"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,367.259 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3919"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,358.755 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3921"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,358.755 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3923"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,350.252 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3925"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,350.252 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3927"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,380.014 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3929"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,380.014 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3931"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,371.511 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3933"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,371.511 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3935"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,363.007 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3937"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,363.007 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3939"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,354.504 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3941"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,354.504 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3943"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,448.039 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3945"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,448.039 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3947"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,439.536 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3949"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,439.536 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3951"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,431.033 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3953"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,431.033 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3955"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,422.53 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3957"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,422.53 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3959"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,443.788 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3961"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,443.788 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3963"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,435.284 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3965"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,435.284 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3967"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,426.781 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3969"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,426.781 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3971"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,418.278 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3973"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,418.278 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3975"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,431.033 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3977"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,431.033 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3979"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,439.536 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3981"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,439.536 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3983"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,422.53 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3985"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,422.53 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3987"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,443.788 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3989"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,443.788 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3991"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,435.284 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3993"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,435.284 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3995"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,426.781 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path3997"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,426.781 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path3999"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,418.278 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4001"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,418.278 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4003"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,448.039 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4005"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,448.039 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4007"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,448.039 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4009"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,448.039 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4011"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,439.536 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4013"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,439.536 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4015"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,431.033 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4017"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,431.033 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4019"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,422.53 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4021"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,422.53 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4023"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,443.788 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4025"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,443.788 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4027"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,435.284 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4029"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,435.284 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4031"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,426.781 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4033"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,426.781 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4035"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,418.278 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4037"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,418.278 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4039"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,511.813 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4041"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,511.813 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4043"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,503.31 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4045"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,503.31 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4047"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,494.807 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4049"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,494.807 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4051"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,486.304 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4053"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,486.304 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4055"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,516.065 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4057"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,516.065 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4059"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,507.562 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4061"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,507.562 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4063"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,499.059 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4065"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,499.059 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4067"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,490.555 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4069"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,490.555 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4071"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,516.065 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4073"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,516.065 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4075"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,507.562 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4077"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,507.562 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4079"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,499.059 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4081"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,499.059 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4083"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,490.555 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4085"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,490.555 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4087"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,494.807 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4089"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,494.807 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4091"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,486.304 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4093"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,486.304 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4095"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,503.31 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4097"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,503.31 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4099"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,511.813 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4101"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,511.813 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4103"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,511.813 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4105"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,511.813 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4107"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,503.31 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4109"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,503.31 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4111"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,494.807 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4113"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,494.807 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4115"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,486.304 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4117"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,486.304 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4119"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,516.065 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4121"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,516.065 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4123"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,507.562 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4125"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,507.562 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4127"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,499.059 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4129"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,499.059 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4131"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,490.555 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4133"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,490.555 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4135"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,575.587 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4137"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,575.587 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4139"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,567.084 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4141"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,567.084 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4143"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,558.581 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4145"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,558.581 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4147"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,550.078 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4149"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,550.078 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4151"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,579.839 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4153"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,579.839 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4155"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,571.336 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4157"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,571.336 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4159"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,562.832 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4161"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,562.832 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4163"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,554.329 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4165"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,554.329 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4167"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,579.839 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4169"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,579.839 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4171"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,571.336 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4173"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,571.336 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4175"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,562.832 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4177"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,562.832 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4179"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,554.329 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4181"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,554.329 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4183"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,558.581 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4185"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,558.581 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4187"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,550.078 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4189"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,550.078 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4191"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,567.084 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4193"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,567.084 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4195"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,575.587 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4197"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,575.587 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4199"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,562.832 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4201"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,562.832 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4203"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,571.336 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4205"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,571.336 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4207"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,554.329 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4209"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,554.329 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4211"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,575.587 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4213"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,575.587 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4215"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,567.084 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4217"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,567.084 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4219"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,558.581 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4221"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,558.581 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4223"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,550.078 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4225"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,550.078 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4227"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,579.839 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4229"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,579.839 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4231"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,575.587 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4233"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,575.587 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4235"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,567.084 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4237"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,567.084 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4239"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,558.581 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4241"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,558.581 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4243"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,550.078 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4245"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,550.078 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4247"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,579.839 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4249"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,579.839 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4251"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,571.336 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4253"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,571.336 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4255"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,562.832 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4257"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,562.832 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4259"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,554.329 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4261"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,554.329 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4263"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,579.839 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4265"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,579.839 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4267"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,571.336 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4269"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,571.336 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4271"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,562.832 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4273"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,562.832 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4275"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,554.329 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4277"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,554.329 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4279"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,575.587 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4281"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,575.587 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4283"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,567.084 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4285"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,567.084 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4287"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,558.581 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4289"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,558.581 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4291"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,550.078 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4293"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,550.078 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4295"
-       inkscape:connector-curvature="0" /><g
-       transform="scale(0.1,0.1)"
-       id="g4297"
-       style=""><g
-	 id="g4299"
-	 clip-path="url(#clipPath4301)"
-	 style=""><path
-	   d="m 3778.18,5968.45 1105.42,0"
-	   style="fill:none;stroke:#000000;stroke-width:14.17199993;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	   id="path4305"
-	   inkscape:connector-curvature="0" /></g></g><path
-       d="m 478.676,594.011 8.503,2.834 -8.503,2.835 0,-5.669"
-       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4307"
-       inkscape:connector-curvature="0" /><path
-       d="m 478.676,594.011 8.503,2.834 -8.503,2.835 0,-5.669 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4309"
-       inkscape:connector-curvature="0" /><path
-       d="m 95.0867,1.62109 93.5352,0 0,76.5289 -93.5352,0 0,-76.5289 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4311"
-       inkscape:connector-curvature="0" /><path
-       d="m 282.157,1.62109 93.5355,0 0,76.5289 -93.5355,0 0,-76.5289 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4313"
-       inkscape:connector-curvature="0" /><path
-       d="m 469.228,1.62109 93.5352,0 0,76.5289 -93.5352,0 0,-76.5289 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4315"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,10.1242 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4317"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,10.1242 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4319"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,18.6277 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4321"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,18.6277 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4323"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,27.1309 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4325"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,27.1309 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4327"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,35.634 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4329"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,35.634 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4331"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,5.87266 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4333"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,5.87266 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4335"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,14.3762 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4337"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,14.3762 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4339"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,22.8793 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4341"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,22.8793 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4343"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,31.3824 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4345"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,31.3824 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4347"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,10.1242 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4349"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,10.1242 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4351"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,18.6277 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4353"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,18.6277 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4355"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,27.1309 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4357"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,27.1309 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4359"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,35.634 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4361"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,35.634 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4363"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,5.87266 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4365"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,5.87266 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4367"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,14.3762 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4369"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,14.3762 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4371"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,22.8793 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4373"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,22.8793 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4375"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,31.3824 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4377"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,31.3824 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4379"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,69.6469 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4381"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,69.6469 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4383"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,65.3953 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4385"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,65.3953 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4387"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,61.1438 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4389"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,61.1438 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4391"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,56.8922 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4393"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,56.8922 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4395"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,52.6402 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4397"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,52.6402 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4399"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,48.3887 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4401"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,48.3887 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4403"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,44.1371 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4405"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,44.1371 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4407"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,5.87266 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4409"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,5.87266 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4411"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,10.1242 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4413"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,10.1242 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4415"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,14.3762 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4417"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,14.3762 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4419"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,18.6277 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4421"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,18.6277 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4423"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,22.8793 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4425"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,22.8793 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4427"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,27.1309 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4429"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,27.1309 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4431"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,31.3824 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4433"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,31.3824 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4435"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,39.8855 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4437"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,39.8855 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4439"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,35.634 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4441"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,35.634 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4443"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,39.8855 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4445"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,39.8855 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4447"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,48.3887 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4449"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,48.3887 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4451"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,56.8922 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4453"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,56.8922 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4455"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,65.3953 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4457"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,65.3953 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4459"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,44.1371 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4461"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,44.1371 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4463"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,52.6402 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4465"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,52.6402 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4467"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,61.1438 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4469"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,61.1438 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4471"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,69.6469 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4473"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,69.6469 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4475"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,39.8855 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4477"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,39.8855 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4479"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,48.3887 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4481"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,48.3887 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4483"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,56.8922 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4485"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,56.8922 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4487"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,65.3953 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4489"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,65.3953 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4491"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,44.1371 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4493"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,44.1371 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4495"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,52.6402 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4497"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,52.6402 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4499"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,61.1438 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4501"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,61.1438 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4503"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,69.6469 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4505"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,69.6469 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4507"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,116.414 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4509"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,116.414 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4511"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,112.163 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4513"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,112.163 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4515"
-       inkscape:connector-curvature="0" /><path
-       d="m 188.622,107.911 93.5352,0 0,76.5285 -93.5352,0 0,-76.5285 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4517"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,116.414 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4519"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,116.414 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4521"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,112.163 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4523"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,112.163 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4525"
-       inkscape:connector-curvature="0" /><path
-       d="m 375.693,107.911 93.5352,0 0,76.5285 -93.5352,0 0,-76.5285 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4527"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,116.414 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4529"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,116.414 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4531"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,112.163 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4533"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,112.163 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4535"
-       inkscape:connector-curvature="0" /><path
-       d="m 1.55156,107.911 93.5352,0 0,76.5285 -93.5352,0 0,-76.5285 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4537"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,175.937 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4539"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,175.937 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4541"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,167.434 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4543"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,167.434 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4545"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,158.93 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4547"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,158.93 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4549"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,150.427 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4551"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,150.427 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4553"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,141.924 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4555"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,141.924 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4557"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,133.421 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4559"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,133.421 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4561"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,124.918 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4563"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,124.918 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4565"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,171.685 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4567"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,171.685 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4569"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,163.182 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4571"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,163.182 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4573"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,154.679 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4575"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,154.679 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4577"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,146.176 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4579"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,146.176 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4581"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,137.672 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4583"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,137.672 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4585"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,129.169 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4587"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,129.169 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4589"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,120.666 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4591"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,120.666 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4593"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,175.937 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4595"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,175.937 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4597"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,167.434 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4599"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,167.434 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4601"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,158.93 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4603"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,158.93 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4605"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,150.427 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4607"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,150.427 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4609"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,141.924 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4611"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,141.924 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4613"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,133.421 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4615"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,133.421 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4617"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,124.918 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4619"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,124.918 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4621"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,171.685 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4623"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,171.685 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4625"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,163.182 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4627"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,163.182 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4629"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,154.679 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4631"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,154.679 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4633"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,146.176 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4635"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,146.176 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4637"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,137.672 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4639"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,137.672 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4641"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,129.169 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4643"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,129.169 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4645"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,120.666 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4647"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,120.666 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4649"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,175.937 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4651"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,175.937 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4653"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,167.434 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4655"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,167.434 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4657"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,158.93 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4659"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,158.93 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4661"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,150.427 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4663"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,150.427 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4665"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,141.924 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4667"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,141.924 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4669"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,133.421 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4671"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,133.421 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4673"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,124.918 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4675"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,124.918 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4677"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,171.685 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4679"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,171.685 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4681"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,163.182 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4683"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,163.182 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4685"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,154.679 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4687"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,154.679 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4689"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,146.176 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4691"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,146.176 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4693"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,137.672 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4695"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,137.672 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4697"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,129.169 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4699"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,129.169 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4701"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,120.666 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4703"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,120.666 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4705"
-       inkscape:connector-curvature="0" /><path
-       d="m 95.0867,214.201 93.5352,0 0,76.5289 -93.5352,0 0,-76.5289 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4707"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,222.704 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4709"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,222.704 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4711"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,231.207 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4713"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,231.207 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4715"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,226.956 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4717"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,226.956 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4719"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,239.711 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4721"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,239.711 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4723"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,235.459 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4725"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,235.459 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4727"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,248.214 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4729"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,248.214 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4731"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,243.962 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4733"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,243.962 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4735"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,256.717 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4737"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,256.717 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4739"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,252.466 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4741"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,252.466 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4743"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,265.22 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4745"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,265.22 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4747"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,260.969 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4749"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,260.969 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4751"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,273.723 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4753"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,273.723 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4755"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,269.472 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4757"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,269.472 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4759"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,277.975 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4761"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,277.975 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4763"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,218.453 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4765"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,218.453 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4767"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,282.227 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4769"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,282.227 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4771"
-       inkscape:connector-curvature="0" /><path
-       d="m 282.157,214.201 93.5355,0 0,76.5289 -93.5355,0 0,-76.5289 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4773"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,277.975 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4775"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,277.975 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4777"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,282.227 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4779"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,282.227 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4781"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,273.723 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4783"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,273.723 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4785"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,248.214 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4787"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,248.214 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4789"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,239.711 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4791"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,239.711 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4793"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,231.207 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4795"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,231.207 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4797"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,222.704 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4799"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,222.704 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4801"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,269.472 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4803"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,269.472 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4805"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,256.717 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4807"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,256.717 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4809"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,265.22 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4811"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,265.22 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4813"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,260.969 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4815"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,260.969 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4817"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,252.466 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4819"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,252.466 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4821"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,243.962 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4823"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,243.962 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4825"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,235.459 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4827"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,235.459 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4829"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,226.956 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4831"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,226.956 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4833"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,218.453 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path4835"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,218.453 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path4837"
-       inkscape:connector-curvature="0" /><text
-       y="-533.07098"
-       x="5.8031301"
-       id="text4841"
-       style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan4843"
-	 sodipodi:role="line"
-	 y="-533.07098"
-	 x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 88.500237 97.835464">V4L2_FIELD_TOP</tspan><tspan
-	 id="tspan4845"
-	 sodipodi:role="line"
-	 y="-465.04559"
-	 x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 98.507408 105.83879 113.17018 122.5054">V4L2_FIELD_BOTTOM</tspan><tspan
-	 id="tspan4847"
-	 sodipodi:role="line"
-	 y="-397.0202"
-	 x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 95.843628 103.17502 111.17835 119.84163 128.5049 136.50824 143.83963">V4L2_FIELD_ALTERNATE</tspan></text>
-<text
-       y="-316.23969"
-       x="103.58983"
-       id="text4849"
-       style="font-variant:normal;font-weight:normal;font-size:8.2495203px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan4851"
-	 sodipodi:role="line"
-	 y="-316.23969"
-	 x="103.58983 109.09226 113.67899 118.26572 122.85246 127.43919 132.47964 134.77301 140.27545 144.86218 150.81833 155.40506 160.44553 166.86365 188.62184 194.12427 198.711 203.29774 207.88448 212.47121 217.51166 219.80502 225.30746 229.8942 235.85034 240.43707 245.9395 252.35764 257.3981 262.43854 268.85669 375.69293 381.19534 385.78207 390.3688 394.95554 399.54227 404.58273 406.8761 412.37854 416.96527 422.92142 427.50815 433.01059 439.42871 444.46918 449.50961 455.92776 1.551828 7.0542617 11.640993 16.227724 20.814463 25.401194 30.441652 32.735016 38.237442 42.824177 48.780331 53.367065 58.869492 65.287621 70.328079 75.368538 81.786659">V4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_BOTTOMV4L2_FIELD_BOTTOM</tspan><tspan
-	 id="tspan4853"
-	 sodipodi:role="line"
-	 y="-328.99481"
-	 x="10.054964 14.17972 18.766451 20.597849 25.18458 29.771311 34.358047 38.944778 41.238144 43.531509 48.118244 50.865334 53.158699 55.452068 57.283459 61.870193 63.701588 68.288322">v4l2_buffer.field:</tspan></text>
-<text
-       y="-592.59381"
-       x="5.8034"
-       id="text4855"
-       style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan4857"
-	 sodipodi:role="line"
-	 y="-592.59381"
-	 x="5.8034 13.134789 19.806232 29.801399 36.472843 43.144287 47.139954 53.811398 56.475174 59.810898 66.482346 70.478004 77.149452 83.820892 87.816566 91.152283 94.488007 101.15945 107.83089 111.16662 114.50233 121.17377 131.16895 134.50468 137.84041 140.50418 147.17563 149.8394 156.51085 159.84657 163.1823 165.84607 169.84174 175.84123 179.17696 182.51268 185.8484 189.84407 196.51552 203.18695 209.18646 219.18163 221.8454 225.18112 228.51685 235.18829 241.85973 245.19545 249.19112 255.86256 259.19827 265.86972 269.20544 272.54117 282.53635 285.87207 294.53534 301.86673 309.87006 318.53336">Temporal order, bottom field first transmitted (e.g. M/NTSC)</tspan></text>
-<text
-       y="-316.23981"
-       x="290.6604"
-       id="text4859"
-       style="font-variant:normal;font-weight:normal;font-size:8.2495203px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan4861"
-	 sodipodi:role="line"
-	 y="-316.23981"
-	 x="290.6604 296.16284 300.74957 305.3363 309.92303 314.50977 319.55023 321.8436 327.34601 331.93274 337.88889 342.47565 347.51608 353.9342 477.73062 483.23306 487.81979 492.40652 496.99326 501.57999 506.62045 508.91382 514.41626 519.00299 524.95911 529.5459 534.5863 541.00446">V4L2_FIELD_TOPV4L2_FIELD_TOP</tspan></text>
-<text
-       y="-299.23349"
-       x="5.8034"
-       id="text4863"
-       style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan4865"
-	 sodipodi:role="line"
-	 y="-299.23349"
-	 x="5.8034 13.806733 20.478176 27.149622 33.821064 40.492508 47.823895 51.159618 59.162952 65.834396 74.497673 81.169121 84.504837 93.168114 100.4995 108.50284 117.16611 123.83755 131.8409 140.50418 148.50751 157.17079 160.50652 163.84224 167.17796 175.18129 181.85274 188.52419 195.19562 201.86707 209.19846 212.53418 220.53751 227.20895 235.87224 242.54367 245.87939 254.54268 261.87405 269.87741 278.54068 285.21213 293.21545 301.87872 309.88205 318.54535 325.2168 333.22012">V4L2_FIELD_INTERLACED / V4L2_FIELD_INTERLACED_BT</tspan><tspan
-	 id="tspan4867"
-	 sodipodi:role="line"
-	 y="-192.9435"
-	 x="1.5518398 9.5551729 16.226616 22.898062 29.569506 36.240948 43.572334 46.908058 54.911392 61.582836 70.246117 76.917557 80.253281 88.916557 96.247948 104.25128 112.91456 119.586 127.58932 136.25262 144.25595 152.91924 159.59067 166.92206 174.9254 178.26112 182.25679 192.25195 194.91573 200.91524 207.58667 210.25046 212.91423 219.58568 226.25713 232.92856 239.60001">V4L2_FIELD_INTERLACED_TB (misaligned)</tspan><tspan
-	 id="tspan4869"
-	 sodipodi:role="line"
-	 y="-86.653496"
-	 x="5.8034 13.806733 20.478176 27.149622 33.821064 40.492508 47.823895 51.159618 59.162952 65.834396 74.497673 81.169121 89.172447 97.175781 106.511 113.18245 121.18579">V4L2_FIELD_SEQ_BT</tspan></text>
-<text
-       y="-533.07098"
-       x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 88.500237 97.835464"
-       id="text4592"
-       style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan4594"
-	 sodipodi:role="line"
-	 y="-533.07098"
-	 x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 88.500237 97.835464">V4L2_FIELD_TOP</tspan></text>
-<text
-       y="-465.04559"
-       x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 98.507408 105.83879 113.17018 122.5054"
-       id="text4596"
-       style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan4598"
-	 sodipodi:role="line"
-	 y="-465.04559"
-	 x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 98.507408 105.83879 113.17018 122.5054">V4L2_FIELD_BOTTOM</tspan></text>
-<text
-       y="-397.0202"
-       x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 95.843628 103.17502 111.17835 119.84163 128.5049 136.50824 143.83963"
-       id="text4600"
-       style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan4602"
-	 sodipodi:role="line"
-	 y="-397.0202"
-	 x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 95.843628 103.17502 111.17835 119.84163 128.5049 136.50824 143.83963">V4L2_FIELD_ALTERNATE</tspan></text>
-<text
-       y="-299.23349"
-       x="5.8034 13.806733 20.478176 27.149622 33.821064 40.492508 47.823895 51.159618 59.162952 65.834396 74.497673 81.169121 84.504837 93.168114 100.4995 108.50284 117.16611 123.83755 131.8409 140.50418 148.50751 157.17079 160.50652 163.84224 167.17796 175.18129 181.85274 188.52419 195.19562 201.86707 209.19846 212.53418 220.53751 227.20895 235.87224 242.54367 245.87939 254.54268 261.87405 269.87741 278.54068 285.21213 293.21545 301.87872 309.88205 318.54535 325.2168 333.22012"
-       id="text5862"
-       style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan5864"
-	 sodipodi:role="line"
-	 y="-299.23349"
-	 x="5.8034 13.806733 20.478176 27.149622 33.821064 40.492508 47.823895 51.159618 59.162952 65.834396 74.497673 81.169121 84.504837 93.168114 100.4995 108.50284 117.16611 123.83755 131.8409 140.50418 148.50751 157.17079 160.50652 163.84224 167.17796 175.18129 181.85274 188.52419 195.19562 201.86707 209.19846 212.53418 220.53751 227.20895 235.87224 242.54367 245.87939 254.54268 261.87405 269.87741 278.54068 285.21213 293.21545 301.87872 309.88205 318.54535 325.2168 333.22012">V4L2_FIELD_INTERLACED / V4L2_FIELD_INTERLACED_BT</tspan></text>
-<text
-       y="-192.9435"
-       x="1.5518398 9.5551729 16.226616 22.898062 29.569506 36.240948 43.572334 46.908058 54.911392 61.582836 70.246117 76.917557 80.253281 88.916557 96.247948 104.25128 112.91456 119.586 127.58932 136.25262 144.25595 152.91924 159.59067 166.92206 174.9254 178.26112 182.25679 192.25195 194.91573 200.91524 207.58667 210.25046 212.91423 219.58568 226.25713 232.92856 239.60001"
-       id="text5866"
-       style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan5868"
-	 sodipodi:role="line"
-	 y="-192.9435"
-	 x="1.5518398 9.5551729 16.226616 22.898062 29.569506 36.240948 43.572334 46.908058 54.911392 61.582836 70.246117 76.917557 80.253281 88.916557 96.247948 104.25128 112.91456 119.586 127.58932 136.25262 144.25595 152.91924 159.59067 166.92206 174.9254 178.26112 182.25679 192.25195 194.91573 200.91524 207.58667 210.25046 212.91423 219.58568 226.25713 232.92856 239.60001">V4L2_FIELD_INTERLACED_TB (misaligned)</tspan></text>
-<text
-       y="-86.653496"
-       x="5.8034 13.806733 20.478176 27.149622 33.821064 40.492508 47.823895 51.159618 59.162952 65.834396 74.497673 81.169121 89.172447 97.175781 106.511 113.18245 121.18579"
-       id="text5870"
-       style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan5872"
-	 sodipodi:role="line"
-	 y="-86.653496"
-	 x="5.8034 13.806733 20.478176 27.149622 33.821064 40.492508 47.823895 51.159618 59.162952 65.834396 74.497673 81.169121 89.172447 97.175781 106.511 113.18245 121.18579">V4L2_FIELD_SEQ_BT</tspan></text>
-<text
-       y="-316.23969"
-       x="103.58983 109.09226 113.67899 118.26572 122.85246 127.43919 132.47964 134.77301 140.27545 144.86218 150.81833 155.40506 160.44553 166.86365 188.62184 194.12427 198.711 203.29774 207.88448 212.47121 217.51166 219.80502 225.30746 229.8942 235.85034 240.43707 245.9395 252.35764 257.3981 262.43854 268.85669 375.69293 381.19534 385.78207 390.3688 394.95554 399.54227 404.58273 406.8761 412.37854 416.96527 422.92142 427.50815 433.01059 439.42871 444.46918 449.50961 455.92776 1.551828 7.0542617 11.640993 16.227724 20.814463 25.401194 30.441652 32.735016 38.237442 42.824177 48.780331 53.367065 58.869492 65.287621 70.328079 75.368538 81.786659"
-       id="text7144"
-       style="font-variant:normal;font-weight:normal;font-size:8.2495203px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan7146"
-	 sodipodi:role="line"
-	 y="-316.23969"
-	 x="103.58983 109.09226 113.67899 118.26572 122.85246 127.43919 132.47964 134.77301 140.27545 144.86218 150.81833 155.40506 160.44553 166.86365 188.62184 194.12427 198.711 203.29774 207.88448 212.47121 217.51166 219.80502 225.30746 229.8942 235.85034 240.43707 245.9395 252.35764 257.3981 262.43854 268.85669 375.69293 381.19534 385.78207 390.3688 394.95554 399.54227 404.58273 406.8761 412.37854 416.96527 422.92142 427.50815 433.01059 439.42871 444.46918 449.50961 455.92776 1.551828 7.0542617 11.640993 16.227724 20.814463 25.401194 30.441652 32.735016 38.237442 42.824177 48.780331 53.367065 58.869492 65.287621 70.328079 75.368538 81.786659">V4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_BOTTOMV4L2_FIELD_BOTTOM</tspan></text>
-<text
-       y="-328.99481"
-       x="10.054964 14.17972 18.766451 20.597849 25.18458 29.771311 34.358047 38.944778 41.238144 43.531509 48.118244 50.865334 53.158699 55.452068 57.283459 61.870193 63.701588 68.288322"
-       id="text7148"
-       style="font-variant:normal;font-weight:normal;font-size:8.2495203px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan7150"
-	 sodipodi:role="line"
-	 y="-328.99481"
-	 x="10.054964 14.17972 18.766451 20.597849 25.18458 29.771311 34.358047 38.944778 41.238144 43.531509 48.118244 50.865334 53.158699 55.452068 57.283459 61.870193 63.701588 68.288322">v4l2_buffer.field:</tspan></text>
-</g></svg>
diff --git a/Documentation/media/uapi/v4l/fieldseq_tb.svg b/Documentation/media/uapi/v4l/fieldseq_tb.svg
deleted file mode 100644
index 041071e43f9b..000000000000
--- a/Documentation/media/uapi/v4l/fieldseq_tb.svg
+++ /dev/null
@@ -1,2618 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!--
-    Permission is granted to copy, distribute and/or modify this
-    document under the terms of the GNU Free Documentation License,
-    Version 1.1 or any later version published by the Free Software
-    Foundation, with no Invariant Sections, no Front-Cover Texts
-    and no Back-Cover Texts. A copy of the license is included at
-    Documentation/media/uapi/fdl-appendix.rst.
-
-    TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
--->
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   id="svg5543"
-   version="1.1"
-   inkscape:version="0.91 r13725"
-   xml:space="preserve"
-   width="198.48296mm"
-   height="210.39415mm"
-   viewBox="0 0 703.28607 745.49109"
-   sodipodi:docname="fieldseq_tb.svg"><sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="1920"
-     inkscape:window-height="997"
-     id="namedview5545"
-     showgrid="false"
-     fit-margin-top="0"
-     fit-margin-left="0"
-     fit-margin-right="0"
-     fit-margin-bottom="0"
-     units="mm"
-     inkscape:zoom="1.0733333"
-     inkscape:cx="9.8391479"
-     inkscape:cy="370.19322"
-     inkscape:window-x="1920"
-     inkscape:window-y="30"
-     inkscape:window-maximized="1"
-     inkscape:current-layer="g5551" /><metadata
-     id="metadata5549"><rdf:RDF><cc:Work
-	 rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
-	   rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
-     id="defs5547"><clipPath
-       id="clipPath6753"
-       clipPathUnits="userSpaceOnUse"><path
-	 style="clip-rule:evenodd"
-	 inkscape:connector-curvature="0"
-	 id="path6755"
-	 d="M 0,6000 0,0 l 5660,0 0,6000 -5660,0 z m 4786.76,-102.89 103.92,0 0,56.69 -103.92,0 0,0 85.03,-28.35 -85.03,-28.34 z" /></clipPath></defs><g
-     transform="matrix(1.25,0,0,-1.25,-1.0537,746.57119)"
-     inkscape:label="fieldseq_tb"
-     inkscape:groupmode="layer"
-     id="g5551"><path
-       d="m 379.944,571.287 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5555"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,571.287 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5557"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,562.784 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5559"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,562.784 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5561"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,554.281 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5563"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,554.281 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5565"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,545.778 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5567"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,545.778 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5569"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,575.539 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5571"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,575.539 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5573"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,567.036 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5575"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,567.036 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5577"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,558.532 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5579"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,558.532 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5581"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,550.029 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5583"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,550.029 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5585"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,575.539 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5587"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,575.539 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5589"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,567.036 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5591"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,567.036 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5593"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,558.532 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5595"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,558.532 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5597"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,550.029 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5599"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,550.029 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5601"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,571.287 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5603"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,571.287 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5605"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,562.784 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5607"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,562.784 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5609"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,554.281 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5611"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,554.281 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5613"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,545.778 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5615"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,545.778 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5617"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,507.513 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5619"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,507.513 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5621"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,499.01 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5623"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,499.01 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5625"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,490.507 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5627"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,490.507 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5629"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,482.004 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5631"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,482.004 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5633"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,511.765 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5635"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,511.765 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5637"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,503.262 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5639"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,503.262 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5641"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,494.759 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5643"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,494.759 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5645"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,486.255 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5647"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,486.255 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5649"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,443.739 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5651"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,443.739 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5653"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,435.236 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5655"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,435.236 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5657"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,426.733 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5659"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,426.733 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5661"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,418.23 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5663"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,418.23 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5665"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,439.488 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5667"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,439.488 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5669"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,430.984 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5671"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,430.984 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5673"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,422.481 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5675"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,422.481 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5677"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,413.978 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5679"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,413.978 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5681"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,218.404 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5683"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,218.404 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5685"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,226.907 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5687"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,226.907 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5689"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,222.656 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5691"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,222.656 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5693"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,235.411 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5695"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,235.411 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5697"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,231.159 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5699"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,231.159 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5701"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,243.914 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5703"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,243.914 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5705"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,239.662 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5707"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,239.662 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5709"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,252.417 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5711"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,252.417 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5713"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,248.166 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5715"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,248.166 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5717"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,260.92 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5719"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,260.92 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5721"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,256.669 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5723"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,256.669 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5725"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,269.423 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5727"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,269.423 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5729"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,265.172 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5731"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,265.172 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5733"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,273.675 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5735"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,273.675 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5737"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,214.153 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5739"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,214.153 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5741"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,277.927 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5743"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,277.927 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5745"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,218.404 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5747"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,218.404 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5749"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,226.907 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5751"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,226.907 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5753"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,222.656 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5755"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,222.656 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5757"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,235.411 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5759"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,235.411 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5761"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,231.159 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5763"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,231.159 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5765"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,243.914 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5767"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,243.914 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5769"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,239.662 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5771"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,239.662 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5773"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,252.417 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5775"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,252.417 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5777"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,248.166 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5779"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,248.166 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5781"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,260.92 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5783"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,260.92 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5785"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,256.669 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5787"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,256.669 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5789"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,269.423 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5791"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,269.423 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5793"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,265.172 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5795"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,265.172 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5797"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,273.675 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5799"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,273.675 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5801"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,214.153 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5803"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,214.153 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5805"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,277.927 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5807"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,277.927 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5809"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,375.714 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5811"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,375.714 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5813"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,367.211 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5815"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,367.211 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5817"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,358.707 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5819"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,358.707 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5821"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,350.204 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5823"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,350.204 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5825"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,371.462 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5827"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,371.462 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5829"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,362.959 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5831"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,362.959 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5833"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,354.455 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5835"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,354.455 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5837"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,345.952 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5839"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,345.952 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5841"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,371.462 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5843"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,371.462 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5845"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,362.959 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5847"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,362.959 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5849"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,354.455 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5851"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,354.455 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5853"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,345.952 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5855"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,345.952 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5857"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,375.714 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5859"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,375.714 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5861"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,367.211 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5863"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,367.211 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5865"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,358.707 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5867"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,358.707 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5869"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,350.204 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5871"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,350.204 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5873"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,35.5855 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5875"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,35.5855 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5877"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,27.0824 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5879"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,27.0824 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5881"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,18.5793 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5883"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,18.5793 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5885"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,10.0762 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5887"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,10.0762 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5889"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,31.334 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5891"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,31.334 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5893"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,22.8309 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5895"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,22.8309 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5897"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,14.3277 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5899"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,14.3277 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5901"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,5.82422 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5903"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,5.82422 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5905"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,35.5855 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5907"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,35.5855 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5909"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,27.0824 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5911"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,27.0824 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5913"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,18.5793 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5915"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,18.5793 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5917"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,10.0762 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5919"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,10.0762 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5921"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,31.334 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5923"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,31.334 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5925"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,22.8309 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5927"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,22.8309 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5929"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,14.3277 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5931"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,14.3277 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5933"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,5.82422 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5935"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,5.82422 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5937"
-       inkscape:connector-curvature="0" /><path
-       d="m 95.0867,409.727 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5939"
-       inkscape:connector-curvature="0" /><path
-       d="m 282.157,409.727 93.5355,0 0,42.516 -93.5355,0 0,-42.516 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5941"
-       inkscape:connector-curvature="0" /><path
-       d="m 469.228,409.727 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5943"
-       inkscape:connector-curvature="0" /><path
-       d="m 469.228,209.901 93.5352,0 0,76.5289 -93.5352,0 0,-76.5289 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5945"
-       inkscape:connector-curvature="0" /><path
-       d="m 282.157,209.901 93.5355,0 0,76.5289 -93.5355,0 0,-76.5289 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5947"
-       inkscape:connector-curvature="0" /><path
-       d="m 95.0867,209.901 93.5352,0 0,76.5289 -93.5352,0 0,-76.5289 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5949"
-       inkscape:connector-curvature="0" /><path
-       d="m 95.0867,341.701 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5951"
-       inkscape:connector-curvature="0" /><path
-       d="m 282.157,341.701 93.5355,0 0,42.516 -93.5355,0 0,-42.516 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5953"
-       inkscape:connector-curvature="0" /><path
-       d="m 469.228,341.701 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5955"
-       inkscape:connector-curvature="0" /><path
-       d="m 1.55156,341.701 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5957"
-       inkscape:connector-curvature="0" /><path
-       d="m 188.622,341.701 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5959"
-       inkscape:connector-curvature="0" /><path
-       d="m 375.693,341.701 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5961"
-       inkscape:connector-curvature="0" /><path
-       d="m 1.55156,477.752 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5963"
-       inkscape:connector-curvature="0" /><path
-       d="m 188.622,477.752 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5965"
-       inkscape:connector-curvature="0" /><path
-       d="m 375.693,477.752 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5967"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,571.287 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5969"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,571.287 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5971"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,562.784 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5973"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,562.784 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5975"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,554.281 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5977"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,554.281 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5979"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,545.778 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5981"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,545.778 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5983"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,575.539 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5985"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,575.539 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5987"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,567.036 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5989"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,567.036 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5991"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,558.532 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5993"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,558.532 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5995"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,550.029 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path5997"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,550.029 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path5999"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,575.539 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6001"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,575.539 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6003"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,567.036 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6005"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,567.036 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6007"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,558.532 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6009"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,558.532 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6011"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,550.029 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6013"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,550.029 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6015"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,571.287 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6017"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,571.287 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6019"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,562.784 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6021"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,562.784 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6023"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,554.281 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6025"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,554.281 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6027"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,545.778 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6029"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,545.778 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6031"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,507.513 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6033"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,507.513 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6035"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,499.01 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6037"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,499.01 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6039"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,490.507 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6041"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,490.507 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6043"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,482.004 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6045"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,482.004 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6047"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,511.765 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6049"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,511.765 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6051"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,503.262 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6053"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,503.262 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6055"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,494.759 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6057"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,494.759 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6059"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,486.255 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6061"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,486.255 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6063"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,443.739 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6065"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,443.739 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6067"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,435.236 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6069"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,435.236 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6071"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,426.733 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6073"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,426.733 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6075"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,418.23 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6077"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,418.23 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6079"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,439.488 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6081"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,439.488 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6083"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,430.984 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6085"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,430.984 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6087"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,422.481 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6089"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,422.481 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6091"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,413.978 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6093"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,413.978 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6095"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,575.539 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6097"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,575.539 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6099"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,575.539 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6101"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,575.539 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6103"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,571.287 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6105"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,571.287 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6107"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,567.036 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6109"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,567.036 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6111"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,562.784 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6113"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,562.784 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6115"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,558.532 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6117"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,558.532 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6119"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,554.281 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6121"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,554.281 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6123"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,550.029 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6125"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,550.029 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6127"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,545.778 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6129"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,545.778 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6131"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,511.765 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6133"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,511.765 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6135"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,507.513 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6137"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,507.513 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6139"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,503.262 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6141"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,503.262 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6143"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,499.01 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6145"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,499.01 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6147"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,494.759 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6149"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,494.759 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6151"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,490.507 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6153"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,490.507 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6155"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,486.255 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6157"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,486.255 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6159"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,482.004 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6161"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,482.004 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6163"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,375.714 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6165"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,375.714 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6167"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,371.462 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6169"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,371.462 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6171"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,367.211 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6173"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,367.211 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6175"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,362.959 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6177"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,362.959 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6179"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,358.707 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6181"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,358.707 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6183"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,354.455 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6185"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,354.455 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6187"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,350.204 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6189"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,350.204 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6191"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,345.952 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6193"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,345.952 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6195"
-       inkscape:connector-curvature="0" /><path
-       d="m 1.55156,107.863 93.5352,0 0,76.5289 -93.5352,0 0,-76.5289 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6197"
-       inkscape:connector-curvature="0" /><path
-       d="m 188.622,107.863 93.5352,0 0,76.5289 -93.5352,0 0,-76.5289 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6199"
-       inkscape:connector-curvature="0" /><path
-       d="m 375.693,107.863 93.5352,0 0,76.5289 -93.5352,0 0,-76.5289 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6201"
-       inkscape:connector-curvature="0" /><path
-       d="m 95.0867,1.57266 93.5352,0 0,76.5289 -93.5352,0 0,-76.5289 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6203"
-       inkscape:connector-curvature="0" /><path
-       d="m 282.157,1.57266 93.5355,0 0,76.5289 -93.5355,0 0,-76.5289 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6205"
-       inkscape:connector-curvature="0" /><path
-       d="m 469.228,1.57266 93.5352,0 0,76.5289 -93.5352,0 0,-76.5289 z"
-       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6207"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,65.3469 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6209"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,65.3469 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6211"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,56.8438 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6213"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,56.8438 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6215"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,48.3402 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6217"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,48.3402 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6219"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,39.8371 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6221"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,39.8371 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6223"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,69.5984 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6225"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,69.5984 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6227"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,61.0953 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6229"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,61.0953 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6231"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,52.5922 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6233"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,52.5922 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6235"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,44.0887 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6237"
-       inkscape:connector-curvature="0" /><path
-       d="m 473.479,44.0887 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6239"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,65.3469 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6241"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,65.3469 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6243"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,56.8438 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6245"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,56.8438 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6247"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,48.3402 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6249"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,48.3402 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6251"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,39.8371 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6253"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,39.8371 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6255"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,69.5984 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6257"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,69.5984 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6259"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,61.0953 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6261"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,61.0953 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6263"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,52.5922 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6265"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,52.5922 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6267"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,44.0887 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6269"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,44.0887 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6271"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,277.927 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6273"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,277.927 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6275"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,269.423 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6277"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,269.423 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6279"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,260.92 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6281"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,260.92 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6283"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,252.417 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6285"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,252.417 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6287"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,243.914 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6289"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,243.914 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6291"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,235.411 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6293"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,235.411 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6295"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,226.907 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6297"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,226.907 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6299"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,218.404 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6301"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,218.404 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6303"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,69.5984 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6305"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,69.5984 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6307"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,65.3469 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6309"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,65.3469 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6311"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,61.0953 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6313"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,61.0953 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6315"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,56.8438 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6317"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,56.8438 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6319"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,52.5922 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6321"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,52.5922 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6323"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,48.3402 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6325"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,48.3402 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6327"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,44.0887 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6329"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,44.0887 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6331"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,39.8371 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6333"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,39.8371 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6335"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,571.287 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6337"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,571.287 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6339"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,567.036 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6341"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,567.036 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6343"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,562.784 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6345"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,562.784 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6347"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,558.532 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6349"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,558.532 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6351"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,554.281 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6353"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,554.281 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6355"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,550.029 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6357"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,550.029 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6359"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,545.778 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6361"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,545.778 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6363"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,443.739 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6365"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,443.739 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6367"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,439.488 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6369"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,439.488 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6371"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,435.236 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6373"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,435.236 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6375"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,430.984 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6377"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,430.984 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6379"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,426.733 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6381"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,426.733 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6383"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,422.481 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6385"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,422.481 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6387"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,418.23 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6389"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,418.23 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6391"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,413.978 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6393"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,413.978 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6395"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,375.714 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6397"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,375.714 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6399"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,371.462 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6401"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,371.462 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6403"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,367.211 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6405"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,367.211 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6407"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,362.959 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6409"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,362.959 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6411"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,358.707 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6413"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,358.707 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6415"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,354.455 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6417"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,354.455 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6419"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,350.204 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6421"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,350.204 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6423"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,345.952 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6425"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,345.952 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6427"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,273.675 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6429"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,273.675 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6431"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,265.172 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6433"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,265.172 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6435"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,256.669 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6437"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,256.669 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6439"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,248.166 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6441"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,248.166 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6443"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,239.662 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6445"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,239.662 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6447"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,231.159 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6449"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,231.159 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6451"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,222.656 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6453"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,222.656 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6455"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,214.153 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6457"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,214.153 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6459"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,35.5855 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6461"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,35.5855 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6463"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,31.334 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6465"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,31.334 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6467"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,27.0824 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6469"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,27.0824 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6471"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,22.8309 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6473"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,22.8309 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6475"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,18.5793 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6477"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,18.5793 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6479"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,14.3277 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6481"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,14.3277 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6483"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,10.0762 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6485"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,10.0762 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6487"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,5.82422 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6489"
-       inkscape:connector-curvature="0" /><path
-       d="m 286.409,5.82422 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6491"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,175.888 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6493"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,175.888 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6495"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,167.385 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6497"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,167.385 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6499"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,158.882 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6501"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,158.882 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6503"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,150.379 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6505"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,150.379 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6507"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,141.876 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6509"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,141.876 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6511"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,133.372 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6513"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,133.372 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6515"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,124.869 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6517"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,124.869 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6519"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,116.366 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6521"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,116.366 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6523"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,371.462 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6525"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,371.462 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6527"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,362.959 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6529"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,362.959 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6531"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,354.455 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6533"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,354.455 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6535"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,345.952 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6537"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,345.952 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6539"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,375.714 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6541"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,375.714 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6543"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,367.211 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6545"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,367.211 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6547"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,358.707 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6549"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,358.707 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6551"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,350.204 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6553"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,350.204 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6555"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,175.888 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6557"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,175.888 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6559"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,167.385 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6561"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,167.385 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6563"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,158.882 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6565"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,158.882 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6567"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,150.379 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6569"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,150.379 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6571"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,141.876 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6573"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,141.876 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6575"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,133.372 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6577"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,133.372 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6579"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,124.869 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6581"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,124.869 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6583"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,116.366 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6585"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,116.366 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6587"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,175.888 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6589"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,175.888 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6591"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,167.385 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6593"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,167.385 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6595"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,158.882 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6597"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,158.882 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6599"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,150.379 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6601"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,150.379 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6603"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,141.876 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6605"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,141.876 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6607"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,133.372 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6609"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,133.372 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6611"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,124.869 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6613"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,124.869 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6615"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,116.366 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6617"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,116.366 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6619"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,375.714 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6621"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,375.714 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6623"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,367.211 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6625"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,367.211 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6627"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,358.707 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6629"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,358.707 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6631"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,350.204 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6633"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,350.204 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6635"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,371.462 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6637"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,371.462 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6639"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,362.959 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6641"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,362.959 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6643"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,354.455 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6645"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,354.455 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6647"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,345.952 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6649"
-       inkscape:connector-curvature="0" /><path
-       d="m 99.3383,345.952 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6651"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,171.637 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6653"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,171.637 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6655"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,163.134 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6657"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,163.134 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6659"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,154.63 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6661"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,154.63 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6663"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,146.127 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6665"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,146.127 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6667"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,137.624 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6669"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,137.624 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6671"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,129.121 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6673"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,129.121 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6675"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,120.618 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6677"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,120.618 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6679"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,112.114 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6681"
-       inkscape:connector-curvature="0" /><path
-       d="m 192.873,112.114 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6683"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,171.637 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6685"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,171.637 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6687"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,163.134 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6689"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,163.134 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6691"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,154.63 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6693"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,154.63 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6695"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,146.127 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6697"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,146.127 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6699"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,137.624 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6701"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,137.624 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6703"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,129.121 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6705"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,129.121 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6707"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,120.618 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6709"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,120.618 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6711"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,112.114 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6713"
-       inkscape:connector-curvature="0" /><path
-       d="m 379.944,112.114 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6715"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,171.637 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6717"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,171.637 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6719"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,163.134 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6721"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,163.134 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6723"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,154.63 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6725"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,154.63 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6727"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,146.127 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6729"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,146.127 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6731"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,137.624 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6733"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,137.624 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6735"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,129.121 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6737"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,129.121 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6739"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,120.618 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6741"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,120.618 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6743"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,112.114 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6745"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.80312,112.114 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6747"
-       inkscape:connector-curvature="0" /><g
-       transform="scale(0.1,0.1)"
-       id="g6749"
-       style=""><g
-	 id="g6751"
-	 clip-path="url(#clipPath6753)"
-	 style=""><path
-	   d="m 3778.18,5925.45 1105.42,0"
-	   style="fill:none;stroke:#000000;stroke-width:14.17199993;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	   id="path6757"
-	   inkscape:connector-curvature="0" /></g></g><path
-       d="m 478.676,589.711 8.503,2.834 -8.503,2.835 0,-5.669"
-       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path6759"
-       inkscape:connector-curvature="0" /><path
-       d="m 478.676,589.711 8.503,2.834 -8.503,2.835 0,-5.669 z"
-       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path6761"
-       inkscape:connector-curvature="0" /><text
-       y="-528.771"
-       x="5.8031301"
-       id="text6765"
-       style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan6767"
-	 sodipodi:role="line"
-	 y="-528.771"
-	 x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 88.500237 97.835464">V4L2_FIELD_TOP</tspan><tspan
-	 id="tspan6769"
-	 sodipodi:role="line"
-	 y="-460.74561"
-	 x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 98.507408 105.83879 113.17018 122.5054">V4L2_FIELD_BOTTOM</tspan><tspan
-	 id="tspan6771"
-	 sodipodi:role="line"
-	 y="-392.72021"
-	 x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 95.843628 103.17502 111.17835 119.84163 128.5049 136.50824 143.83963">V4L2_FIELD_ALTERNATE</tspan></text>
-<text
-       y="-324.69479"
-       x="10.05469"
-       id="text6773"
-       style="font-variant:normal;font-weight:normal;font-size:8.2495203px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan6775"
-	 sodipodi:role="line"
-	 y="-324.69479"
-	 x="10.05469 14.17945 18.766184 20.597576 25.184309 29.771042 34.357777 38.944508 41.237877 43.531242 48.117977 50.865067 53.158432 55.451801 57.283192 61.869926 63.701321 68.288048">v4l2_buffer.field:</tspan><tspan
-	 id="tspan6777"
-	 sodipodi:role="line"
-	 y="-311.9397"
-	 x="10.05469 15.55712 20.143852 24.730585 29.317318 33.904053 38.944508 41.237877 46.740307 51.327042 57.283192 61.869926 66.910378 73.328506 95.0867 100.58913 105.17586 109.7626 114.34933 118.93606 123.97652 126.26987 131.77232 136.35905 142.3152 146.90193 152.40436 158.82249 163.86295 168.9034 175.32153 197.12534 202.62778 207.21451 211.80124 216.38797 220.9747 226.01515 228.30853 233.81096 238.39769 244.35384 248.94058 253.98103 260.39917 282.15695 287.65936 292.24609 296.83282 301.41956 306.00629 311.04675 313.34012 318.84256 323.42929 329.38544 333.97217 339.47461 345.89273 350.9332 355.97363 362.39175 384.19559 389.698 394.28473 398.87149 403.45822 408.04495 413.08539 415.37875 420.8812 425.46793 431.42407 436.0108 441.05127 447.46939 469.2276 474.73001 479.31674 483.90347 488.49023 493.07697 498.1174 500.41077 505.91321 510.49994 516.45612 521.04285 526.54523 532.96338
-538.00385 543.04431 549.4624">V4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_TOPV4L2_FIELD_BOTTOM</tspan></text>
-<text
-       y="-588.2937"
-       x="5.8031301"
-       id="text6779"
-       style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan6781"
-	 sodipodi:role="line"
-	 y="-588.2937"
-	 x="5.8031301 13.134519 19.805964 29.801128 36.472572 43.14402 47.139687 53.811131 56.474907 59.810631 66.482071 70.477737 77.149185 83.820625 87.816299 91.152016 94.48774 97.823463 104.4949 111.16635 114.50207 117.83779 120.50157 127.17302 129.83679 136.50824 139.84396 143.17969 145.84346 149.83913 155.83862 159.17435 162.51007 165.84579 169.84146 176.51291 183.18434 189.18385 199.17902 201.84279 205.17851 208.51424 215.18568 221.85713 225.19284 229.18851 235.85995 239.19568 245.86713 249.20285 252.53857 260.5419 269.87714 273.21286 281.21619 289.21951 295.89096">Temporal order, top field first transmitted (e.g. BG/PAL)</tspan><tspan
-	 id="tspan6783"
-	 sodipodi:role="line"
-	 y="-86.604706"
-	 x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 97.175514 106.51073 113.18218 120.51357">V4L2_FIELD_SEQ_TB</tspan><tspan
-	 id="tspan6785"
-	 sodipodi:role="line"
-	 y="-192.89471"
-	 x="10.05469 18.058023 24.729465 31.400909 38.072357 44.743801 52.075188 55.410912 63.414246 70.085686 78.748962 85.42041 88.756134 97.419411 104.7508 112.75413 121.41741 128.08885 136.09219 144.75546 152.7588 161.42207 168.09352 176.09685 183.42824 186.76396 190.75963 200.75479 203.41858 209.41808 216.08952 218.7533 221.41707 228.08852 234.75996 241.43141 248.10286">V4L2_FIELD_INTERLACED_BT (misaligned)</tspan><tspan
-	 id="tspan6787"
-	 sodipodi:role="line"
-	 y="-294.93271"
-	 x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 84.50457 93.167847 100.49924 108.50257 117.16585 123.83729 131.84062 140.50391 148.50723 157.17052 160.50624 163.84196 167.17769 175.18102 181.85246 188.52391 195.19534 201.86679 209.19818 212.53391 220.53723 227.20868 235.87196 242.5434 245.87912 254.5424 261.87378 269.87714 278.54041 285.21185 293.21518 301.87845 309.88177 318.54507 325.21652 332.54791">V4L2_FIELD_INTERLACED / V4L2_FIELD_INTERLACED_TB</tspan></text>
-<text
-       y="-528.771"
-       x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 88.500237 97.835464"
-       id="text4583"
-       style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan4585"
-	 sodipodi:role="line"
-	 y="-528.771"
-	 x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 88.500237 97.835464">V4L2_FIELD_TOP</tspan></text>
-<text
-       y="-460.74561"
-       x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 98.507408 105.83879 113.17018 122.5054"
-       id="text4587"
-       style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan4589"
-	 sodipodi:role="line"
-	 y="-460.74561"
-	 x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 98.507408 105.83879 113.17018 122.5054">V4L2_FIELD_BOTTOM</tspan></text>
-<text
-       y="-392.72021"
-       x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 95.843628 103.17502 111.17835 119.84163 128.5049 136.50824 143.83963"
-       id="text4591"
-       style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan4593"
-	 sodipodi:role="line"
-	 y="-392.72021"
-	 x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 95.843628 103.17502 111.17835 119.84163 128.5049 136.50824 143.83963">V4L2_FIELD_ALTERNATE</tspan></text>
-<text
-       y="-588.2937"
-       x="5.8031301 13.134519 19.805964 29.801128 36.472572 43.14402 47.139687 53.811131 56.474907 59.810631 66.482071 70.477737 77.149185 83.820625 87.816299 91.152016 94.48774 97.823463 104.4949 111.16635 114.50207 117.83779 120.50157 127.17302 129.83679 136.50824 139.84396 143.17969 145.84346 149.83913 155.83862 159.17435 162.51007 165.84579 169.84146 176.51291 183.18434 189.18385 199.17902 201.84279 205.17851 208.51424 215.18568 221.85713 225.19284 229.18851 235.85995 239.19568 245.86713 249.20285 252.53857 260.5419 269.87714 273.21286 281.21619 289.21951 295.89096"
-       id="text5847"
-       style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan5849"
-	 sodipodi:role="line"
-	 y="-588.2937"
-	 x="5.8031301 13.134519 19.805964 29.801128 36.472572 43.14402 47.139687 53.811131 56.474907 59.810631 66.482071 70.477737 77.149185 83.820625 87.816299 91.152016 94.48774 97.823463 104.4949 111.16635 114.50207 117.83779 120.50157 127.17302 129.83679 136.50824 139.84396 143.17969 145.84346 149.83913 155.83862 159.17435 162.51007 165.84579 169.84146 176.51291 183.18434 189.18385 199.17902 201.84279 205.17851 208.51424 215.18568 221.85713 225.19284 229.18851 235.85995 239.19568 245.86713 249.20285 252.53857 260.5419 269.87714 273.21286 281.21619 289.21951 295.89096">Temporal order, top field first transmitted (e.g. BG/PAL)</tspan></text>
-<text
-       y="-86.604706"
-       x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 97.175514 106.51073 113.18218 120.51357"
-       id="text5851"
-       style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan5853"
-	 sodipodi:role="line"
-	 y="-86.604706"
-	 x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 97.175514 106.51073 113.18218 120.51357">V4L2_FIELD_SEQ_TB</tspan></text>
-<text
-       y="-192.89471"
-       x="10.05469 18.058023 24.729465 31.400909 38.072357 44.743801 52.075188 55.410912 63.414246 70.085686 78.748962 85.42041 88.756134 97.419411 104.7508 112.75413 121.41741 128.08885 136.09219 144.75546 152.7588 161.42207 168.09352 176.09685 183.42824 186.76396 190.75963 200.75479 203.41858 209.41808 216.08952 218.7533 221.41707 228.08852 234.75996 241.43141 248.10286"
-       id="text5855"
-       style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan5857"
-	 sodipodi:role="line"
-	 y="-192.89471"
-	 x="10.05469 18.058023 24.729465 31.400909 38.072357 44.743801 52.075188 55.410912 63.414246 70.085686 78.748962 85.42041 88.756134 97.419411 104.7508 112.75413 121.41741 128.08885 136.09219 144.75546 152.7588 161.42207 168.09352 176.09685 183.42824 186.76396 190.75963 200.75479 203.41858 209.41808 216.08952 218.7533 221.41707 228.08852 234.75996 241.43141 248.10286">V4L2_FIELD_INTERLACED_BT (misaligned)</tspan></text>
-<text
-       y="-294.93271"
-       x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 84.50457 93.167847 100.49924 108.50257 117.16585 123.83729 131.84062 140.50391 148.50723 157.17052 160.50624 163.84196 167.17769 175.18102 181.85246 188.52391 195.19534 201.86679 209.19818 212.53391 220.53723 227.20868 235.87196 242.5434 245.87912 254.5424 261.87378 269.87714 278.54041 285.21185 293.21518 301.87845 309.88177 318.54507 325.21652 332.54791"
-       id="text5859"
-       style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan5861"
-	 sodipodi:role="line"
-	 y="-294.93271"
-	 x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 84.50457 93.167847 100.49924 108.50257 117.16585 123.83729 131.84062 140.50391 148.50723 157.17052 160.50624 163.84196 167.17769 175.18102 181.85246 188.52391 195.19534 201.86679 209.19818 212.53391 220.53723 227.20868 235.87196 242.5434 245.87912 254.5424 261.87378 269.87714 278.54041 285.21185 293.21518 301.87845 309.88177 318.54507 325.21652 332.54791">V4L2_FIELD_INTERLACED / V4L2_FIELD_INTERLACED_TB</tspan></text>
-<text
-       y="-324.69479"
-       x="10.05469 14.17945 18.766184 20.597576 25.184309 29.771042 34.357777 38.944508 41.237877 43.531242 48.117977 50.865067 53.158432 55.451801 57.283192 61.869926 63.701321 68.288048"
-       id="text7131"
-       style="font-variant:normal;font-weight:normal;font-size:8.2495203px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan7133"
-	 sodipodi:role="line"
-	 y="-324.69479"
-	 x="10.05469 14.17945 18.766184 20.597576 25.184309 29.771042 34.357777 38.944508 41.237877 43.531242 48.117977 50.865067 53.158432 55.451801 57.283192 61.869926 63.701321 68.288048">v4l2_buffer.field:</tspan></text>
-<text
-       y="-311.9397"
-       x="10.05469 15.55712 20.143852 24.730585 29.317318 33.904053 38.944508 41.237877 46.740307 51.327042 57.283192 61.869926 66.910378 73.328506 95.0867 100.58913 105.17586 109.7626 114.34933 118.93606 123.97652 126.26987 131.77232 136.35905 142.3152 146.90193 152.40436 158.82249 163.86295 168.9034 175.32153 197.12534 202.62778 207.21451 211.80124 216.38797 220.9747 226.01515 228.30853 233.81096 238.39769 244.35384 248.94058 253.98103 260.39917 282.15695 287.65936 292.24609 296.83282 301.41956 306.00629 311.04675 313.34012 318.84256 323.42929 329.38544 333.97217 339.47461 345.89273 350.9332 355.97363 362.39175 384.19559 389.698 394.28473 398.87149 403.45822 408.04495 413.08539 415.37875 420.8812 425.46793 431.42407 436.0108 441.05127 447.46939 469.2276 474.73001 479.31674 483.90347 488.49023 493.07697 498.1174 500.41077 505.91321 510.49994 516.45612 521.04285 526.54523 532.96338
-538.00385 543.04431 549.4624"
-       id="text7135"
-       style="font-variant:normal;font-weight:normal;font-size:8.2495203px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan7137"
-	 sodipodi:role="line"
-	 y="-311.9397"
-	 x="10.05469 15.55712 20.143852 24.730585 29.317318 33.904053 38.944508 41.237877 46.740307 51.327042 57.283192 61.869926 66.910378 73.328506 95.0867 100.58913 105.17586 109.7626 114.34933 118.93606 123.97652 126.26987 131.77232 136.35905 142.3152 146.90193 152.40436 158.82249 163.86295 168.9034 175.32153 197.12534 202.62778 207.21451 211.80124 216.38797 220.9747 226.01515 228.30853 233.81096 238.39769 244.35384 248.94058 253.98103 260.39917 282.15695 287.65936 292.24609 296.83282 301.41956 306.00629 311.04675 313.34012 318.84256 323.42929 329.38544 333.97217 339.47461 345.89273 350.9332 355.97363 362.39175 384.19559 389.698 394.28473 398.87149 403.45822 408.04495 413.08539 415.37875 420.8812 425.46793 431.42407 436.0108 441.05127 447.46939 469.2276 474.73001 479.31674 483.90347 488.49023 493.07697 498.1174 500.41077 505.91321 510.49994 516.45612 521.04285 526.54523 532.96338
-538.00385 543.04431 549.4624">V4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_TOPV4L2_FIELD_BOTTOM</tspan></text>
-</g></svg>
diff --git a/Documentation/media/uapi/v4l/format.rst b/Documentation/media/uapi/v4l/format.rst
deleted file mode 100644
index 9cdb296333b8..000000000000
--- a/Documentation/media/uapi/v4l/format.rst
+++ /dev/null
@@ -1,99 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _format:
-
-************
-Data Formats
-************
-
-
-Data Format Negotiation
-=======================
-
-Different devices exchange different kinds of data with applications,
-for example video images, raw or sliced VBI data, RDS datagrams. Even
-within one kind many different formats are possible, in particular there is an
-abundance of image formats. Although drivers must provide a default and
-the selection persists across closing and reopening a device,
-applications should always negotiate a data format before engaging in
-data exchange. Negotiation means the application asks for a particular
-format and the driver selects and reports the best the hardware can do
-to satisfy the request. Of course applications can also just query the
-current selection.
-
-A single mechanism exists to negotiate all data formats using the
-aggregate struct :c:type:`v4l2_format` and the
-:ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` and
-:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctls. Additionally the
-:ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` ioctl can be used to examine
-what the hardware *could* do, without actually selecting a new data
-format. The data formats supported by the V4L2 API are covered in the
-respective device section in :ref:`devices`. For a closer look at
-image formats see :ref:`pixfmt`.
-
-The :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl is a major turning-point in the
-initialization sequence. Prior to this point multiple panel applications
-can access the same device concurrently to select the current input,
-change controls or modify other properties. The first :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`
-assigns a logical stream (video data, VBI data etc.) exclusively to one
-file descriptor.
-
-Exclusive means no other application, more precisely no other file
-descriptor, can grab this stream or change device properties
-inconsistent with the negotiated parameters. A video standard change for
-example, when the new standard uses a different number of scan lines,
-can invalidate the selected image format. Therefore only the file
-descriptor owning the stream can make invalidating changes. Accordingly
-multiple file descriptors which grabbed different logical streams
-prevent each other from interfering with their settings. When for
-example video overlay is about to start or already in progress,
-simultaneous video capturing may be restricted to the same cropping and
-image size.
-
-When applications omit the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl its locking side
-effects are implied by the next step, the selection of an I/O method
-with the :ref:`VIDIOC_REQBUFS` ioctl or implicit
-with the first :ref:`read() <func-read>` or
-:ref:`write() <func-write>` call.
-
-Generally only one logical stream can be assigned to a file descriptor,
-the exception being drivers permitting simultaneous video capturing and
-overlay using the same file descriptor for compatibility with V4L and
-earlier versions of V4L2. Switching the logical stream or returning into
-"panel mode" is possible by closing and reopening the device. Drivers
-*may* support a switch using :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`.
-
-All drivers exchanging data with applications must support the
-:ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` and :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl. Implementation of the
-:ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` is highly recommended but optional.
-
-
-Image Format Enumeration
-========================
-
-Apart of the generic format negotiation functions a special ioctl to
-enumerate all image formats supported by video capture, overlay or
-output devices is available. [#f1]_
-
-The :ref:`VIDIOC_ENUM_FMT` ioctl must be supported
-by all drivers exchanging image data with applications.
-
-.. important::
-
-    Drivers are not supposed to convert image formats in kernel space.
-    They must enumerate only formats directly supported by the hardware.
-    If necessary driver writers should publish an example conversion
-    routine or library for integration into applications.
-
-.. [#f1]
-   Enumerating formats an application has no a-priori knowledge of
-   (otherwise it could explicitly ask for them and need not enumerate)
-   seems useless, but there are applications serving as proxy between
-   drivers and the actual video applications for which this is useful.
diff --git a/Documentation/media/uapi/v4l/func-close.rst b/Documentation/media/uapi/v4l/func-close.rst
deleted file mode 100644
index 1a56811b827e..000000000000
--- a/Documentation/media/uapi/v4l/func-close.rst
+++ /dev/null
@@ -1,56 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _func-close:
-
-************
-V4L2 close()
-************
-
-Name
-====
-
-v4l2-close - Close a V4L2 device
-
-
-Synopsis
-========
-
-.. code-block:: c
-
-    #include <unistd.h>
-
-
-.. c:function:: int close( int fd )
-    :name: v4l2-close
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-
-Description
-===========
-
-Closes the device. Any I/O in progress is terminated and resources
-associated with the file descriptor are freed. However data format
-parameters, current input or output, control values or other properties
-remain unchanged.
-
-
-Return Value
-============
-
-The function returns 0 on success, -1 on failure and the ``errno`` is
-set appropriately. Possible error codes:
-
-EBADF
-    ``fd`` is not a valid open file descriptor.
diff --git a/Documentation/media/uapi/v4l/func-ioctl.rst b/Documentation/media/uapi/v4l/func-ioctl.rst
deleted file mode 100644
index e7a8cf62752e..000000000000
--- a/Documentation/media/uapi/v4l/func-ioctl.rst
+++ /dev/null
@@ -1,69 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _func-ioctl:
-
-************
-V4L2 ioctl()
-************
-
-Name
-====
-
-v4l2-ioctl - Program a V4L2 device
-
-
-Synopsis
-========
-
-.. code-block:: c
-
-    #include <sys/ioctl.h>
-
-
-.. c:function:: int ioctl( int fd, int request, void *argp )
-    :name: v4l2-ioctl
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``request``
-    V4L2 ioctl request code as defined in the ``videodev2.h`` header
-    file, for example VIDIOC_QUERYCAP.
-
-``argp``
-    Pointer to a function parameter, usually a structure.
-
-
-Description
-===========
-
-The :ref:`ioctl() <func-ioctl>` function is used to program V4L2 devices. The
-argument ``fd`` must be an open file descriptor. An ioctl ``request``
-has encoded in it whether the argument is an input, output or read/write
-parameter, and the size of the argument ``argp`` in bytes. Macros and
-defines specifying V4L2 ioctl requests are located in the
-``videodev2.h`` header file. Applications should use their own copy, not
-include the version in the kernel sources on the system they compile on.
-All V4L2 ioctl requests, their respective function and parameters are
-specified in :ref:`user-func`.
-
-
-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.
-
-When an ioctl that takes an output or read/write parameter fails, the
-parameter remains unmodified.
diff --git a/Documentation/media/uapi/v4l/func-mmap.rst b/Documentation/media/uapi/v4l/func-mmap.rst
deleted file mode 100644
index 75985d80788a..000000000000
--- a/Documentation/media/uapi/v4l/func-mmap.rst
+++ /dev/null
@@ -1,148 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _func-mmap:
-
-***********
-V4L2 mmap()
-***********
-
-Name
-====
-
-v4l2-mmap - Map device memory into application address space
-
-
-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: v4l2-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 the same value as
-    returned by the driver in the struct
-    :c:type:`v4l2_buffer` ``length`` field for the
-    single-planar API, and the same value as returned by the driver in
-    the struct :c:type:`v4l2_plane` ``length`` field for
-    the multi-planar API.
-
-``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.
-
-    .. note::
-
-      #. The Linux ``videobuf`` kernel module, which is used by some
-	 drivers supports only ``PROT_READ`` | ``PROT_WRITE``. When the
-	 driver does not support the desired protection, the
-	 :ref:`mmap() <func-mmap>` function fails.
-
-      #. Device memory accesses (e. g. the memory on a graphics card
-	 with video capturing hardware) may incur a performance penalty
-	 compared to main memory accesses, or reads may be significantly
-	 slower than writes or vice versa. Other I/O methods may be more
-	 efficient in such case.
-
-``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() <func-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 ``videobuf`` module  which is used by some
-       drivers supports only ``MAP_SHARED``. ``MAP_PRIVATE`` requests
-       copy-on-write semantics. V4L2 applications should not set the
-       ``MAP_PRIVATE``, ``MAP_DENYWRITE``, ``MAP_EXECUTABLE`` or ``MAP_ANON``
-       flags.
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``offset``
-    Offset of the buffer in device memory. This must be the same value
-    as returned by the driver in the struct
-    :c:type:`v4l2_buffer` ``m`` union ``offset`` field for
-    the single-planar API, and the same value as returned by the driver
-    in the struct :c:type:`v4l2_plane` ``m`` union
-    ``mem_offset`` field for the multi-planar API.
-
-
-Description
-===========
-
-The :ref:`mmap() <func-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:`VIDIOC_QUERYBUF` ioctl. Buffers must be
-allocated with the :ref:`VIDIOC_REQBUFS` ioctl
-before they can be queried.
-
-To unmap buffers the :ref:`munmap() <func-munmap>` function is used.
-
-
-Return Value
-============
-
-On success :ref:`mmap() <func-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:`VIDIOC_REQBUFS` ioctl.
-
-ENOMEM
-    Not enough physical or virtual memory was available to complete the
-    request.
diff --git a/Documentation/media/uapi/v4l/func-munmap.rst b/Documentation/media/uapi/v4l/func-munmap.rst
deleted file mode 100644
index 0d472d86a036..000000000000
--- a/Documentation/media/uapi/v4l/func-munmap.rst
+++ /dev/null
@@ -1,65 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _func-munmap:
-
-*************
-V4L2 munmap()
-*************
-
-Name
-====
-
-v4l2-munmap - Unmap device memory
-
-
-Synopsis
-========
-
-.. code-block:: c
-
-    #include <unistd.h>
-    #include <sys/mman.h>
-
-
-.. c:function:: int munmap( void *start, size_t length )
-    :name: v4l2-munmap
-
-Arguments
-=========
-
-``start``
-    Address of the mapped buffer as returned by the
-    :ref:`mmap() <func-mmap>` function.
-
-``length``
-    Length of the mapped buffer. This must be the same value as given to
-    :ref:`mmap() <func-mmap>` and returned by the driver in the struct
-    :c:type:`v4l2_buffer` ``length`` field for the
-    single-planar API and in the struct
-    :c:type:`v4l2_plane` ``length`` field for the
-    multi-planar API.
-
-
-Description
-===========
-
-Unmaps a previously with the :ref:`mmap() <func-mmap>` function mapped
-buffer and frees it, if possible.
-
-
-Return Value
-============
-
-On success :ref:`munmap() <func-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/v4l/func-open.rst b/Documentation/media/uapi/v4l/func-open.rst
deleted file mode 100644
index a3d149ce6635..000000000000
--- a/Documentation/media/uapi/v4l/func-open.rst
+++ /dev/null
@@ -1,90 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _func-open:
-
-***********
-V4L2 open()
-***********
-
-Name
-====
-
-v4l2-open - Open a V4L2 device
-
-
-Synopsis
-========
-
-.. code-block:: c
-
-    #include <fcntl.h>
-
-
-.. c:function:: int open( const char *device_name, int flags )
-    :name: v4l2-open
-
-Arguments
-=========
-
-``device_name``
-    Device to be opened.
-
-``flags``
-    Open flags. Access mode must be ``O_RDWR``. This is just a
-    technicality, input devices still support only reading and output
-    devices only writing.
-
-    When the ``O_NONBLOCK`` flag is given, the :ref:`read() <func-read>`
-    function and the :ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl will
-    return the ``EAGAIN`` error code when no data is available or no
-    buffer is in the driver outgoing queue, otherwise these functions
-    block until data becomes available. All V4L2 drivers exchanging data
-    with applications must support the ``O_NONBLOCK`` flag.
-
-    Other flags have no effect.
-
-
-Description
-===========
-
-To open a V4L2 device applications call :ref:`open() <func-open>` with the
-desired device name. This function has no side effects; all data format
-parameters, current input or output, control values or other properties
-remain unchanged. At the first :ref:`open() <func-open>` call after loading the
-driver they will be reset to default values, drivers are never in an
-undefined state.
-
-
-Return Value
-============
-
-On success :ref:`open() <func-open>` returns the new file descriptor. On error
--1 is returned, and the ``errno`` variable is set appropriately.
-Possible error codes are:
-
-EACCES
-    The caller has no permission to access the device.
-
-EBUSY
-    The driver does not support multiple opens and the device is already
-    in use.
-
-ENXIO
-    No device corresponding to this device special file exists.
-
-ENOMEM
-    Not enough kernel memory was available to complete the request.
-
-EMFILE
-    The process already has the maximum number of files open.
-
-ENFILE
-    The limit on the total number of files open on the system has been
-    reached.
diff --git a/Documentation/media/uapi/v4l/func-poll.rst b/Documentation/media/uapi/v4l/func-poll.rst
deleted file mode 100644
index 4c579ed31358..000000000000
--- a/Documentation/media/uapi/v4l/func-poll.rst
+++ /dev/null
@@ -1,124 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _func-poll:
-
-***********
-V4L2 poll()
-***********
-
-Name
-====
-
-v4l2-poll - Wait for some event on a file descriptor
-
-
-Synopsis
-========
-
-.. code-block:: c
-
-    #include <sys/poll.h>
-
-
-.. c:function:: int poll( struct pollfd *ufds, unsigned int nfds, int timeout )
-    :name: v4l2-poll
-
-Arguments
-=========
-
-
-
-Description
-===========
-
-With the :ref:`poll() <func-poll>` function applications can suspend execution
-until the driver has captured data or is ready to accept data for
-output.
-
-When streaming I/O has been negotiated this function waits until a
-buffer has been filled by the capture device and can be dequeued with
-the :ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl. For output devices this
-function waits until the device is ready to accept a new buffer to be
-queued up with the :ref:`VIDIOC_QBUF <VIDIOC_QBUF>` ioctl for
-display. When buffers are already in the outgoing queue of the driver
-(capture) or the incoming queue isn't full (display) the function
-returns immediately.
-
-On success :ref:`poll() <func-poll>` returns the number of file descriptors
-that have been selected (that is, file descriptors for which the
-``revents`` field of the respective :c:func:`struct pollfd` structure
-is non-zero). Capture devices set the ``POLLIN`` and ``POLLRDNORM``
-flags in the ``revents`` field, output devices the ``POLLOUT`` and
-``POLLWRNORM`` flags. When the function timed out it returns a value of
-zero, on failure it returns -1 and the ``errno`` variable is set
-appropriately. When the application did not call
-:ref:`VIDIOC_STREAMON <VIDIOC_STREAMON>` the :ref:`poll() <func-poll>`
-function succeeds, but sets the ``POLLERR`` flag in the ``revents``
-field. When the application has called
-:ref:`VIDIOC_STREAMON <VIDIOC_STREAMON>` for a capture device but
-hasn't yet called :ref:`VIDIOC_QBUF <VIDIOC_QBUF>`, the
-:ref:`poll() <func-poll>` function succeeds and sets the ``POLLERR`` flag in
-the ``revents`` field. For output devices this same situation will cause
-:ref:`poll() <func-poll>` to succeed as well, but it sets the ``POLLOUT`` and
-``POLLWRNORM`` flags in the ``revents`` field.
-
-If an event occurred (see :ref:`VIDIOC_DQEVENT`)
-then ``POLLPRI`` will be set in the ``revents`` field and
-:ref:`poll() <func-poll>` will return.
-
-When use of the :ref:`read() <func-read>` function has been negotiated and the
-driver does not capture yet, the :ref:`poll() <func-poll>` function starts
-capturing. When that fails it returns a ``POLLERR`` as above. Otherwise
-it waits until data has been captured and can be read. When the driver
-captures continuously (as opposed to, for example, still images) the
-function may return immediately.
-
-When use of the :ref:`write() <func-write>` function has been negotiated and the
-driver does not stream yet, the :ref:`poll() <func-poll>` function starts
-streaming. When that fails it returns a ``POLLERR`` as above. Otherwise
-it waits until the driver is ready for a non-blocking
-:ref:`write() <func-write>` call.
-
-If the caller is only interested in events (just ``POLLPRI`` is set in
-the ``events`` field), then :ref:`poll() <func-poll>` will *not* start
-streaming if the driver does not stream yet. This makes it possible to
-just poll for events and not for buffers.
-
-All drivers implementing the :ref:`read() <func-read>` or :ref:`write() <func-write>`
-function or streaming I/O must also support the :ref:`poll() <func-poll>`
-function.
-
-For more details see the :ref:`poll() <func-poll>` manual page.
-
-
-Return Value
-============
-
-On success, :ref:`poll() <func-poll>` returns the number structures which have
-non-zero ``revents`` fields, or zero if the call timed out. On error -1
-is returned, and the ``errno`` variable is set appropriately:
-
-EBADF
-    One or more of the ``ufds`` members specify an invalid file
-    descriptor.
-
-EBUSY
-    The driver does not support multiple read or write streams and the
-    device is already in use.
-
-EFAULT
-    ``ufds`` references an inaccessible memory area.
-
-EINTR
-    The call was interrupted by a signal.
-
-EINVAL
-    The ``nfds`` value exceeds the ``RLIMIT_NOFILE`` value. Use
-    ``getrlimit()`` to obtain this value.
diff --git a/Documentation/media/uapi/v4l/func-read.rst b/Documentation/media/uapi/v4l/func-read.rst
deleted file mode 100644
index 14aca4d5e8fd..000000000000
--- a/Documentation/media/uapi/v4l/func-read.rst
+++ /dev/null
@@ -1,140 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _func-read:
-
-***********
-V4L2 read()
-***********
-
-Name
-====
-
-v4l2-read - Read from a V4L2 device
-
-
-Synopsis
-========
-
-.. code-block:: c
-
-    #include <unistd.h>
-
-
-.. c:function:: ssize_t read( int fd, void *buf, size_t count )
-    :name: v4l2-read
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``buf``
-   Buffer to be filled
-
-``count``
-  Max number of bytes to read
-
-Description
-===========
-
-:ref:`read() <func-read>` attempts to read up to ``count`` bytes from file
-descriptor ``fd`` into the buffer starting at ``buf``. The layout of the
-data in the buffer is discussed in the respective device interface
-section, see ##. If ``count`` is zero, :ref:`read() <func-read>` returns zero
-and has no other results. If ``count`` is greater than ``SSIZE_MAX``,
-the result is unspecified. Regardless of the ``count`` value each
-:ref:`read() <func-read>` call will provide at most one frame (two fields)
-worth of data.
-
-By default :ref:`read() <func-read>` blocks until data becomes available. When
-the ``O_NONBLOCK`` flag was given to the :ref:`open() <func-open>`
-function it returns immediately with an ``EAGAIN`` error code when no data
-is available. The :ref:`select() <func-select>` or
-:ref:`poll() <func-poll>` functions can always be used to suspend
-execution until data becomes available. All drivers supporting the
-:ref:`read() <func-read>` function must also support :ref:`select() <func-select>` and
-:ref:`poll() <func-poll>`.
-
-Drivers can implement read functionality in different ways, using a
-single or multiple buffers and discarding the oldest or newest frames
-once the internal buffers are filled.
-
-:ref:`read() <func-read>` never returns a "snapshot" of a buffer being filled.
-Using a single buffer the driver will stop capturing when the
-application starts reading the buffer until the read is finished. Thus
-only the period of the vertical blanking interval is available for
-reading, or the capture rate must fall below the nominal frame rate of
-the video standard.
-
-The behavior of :ref:`read() <func-read>` when called during the active picture
-period or the vertical blanking separating the top and bottom field
-depends on the discarding policy. A driver discarding the oldest frames
-keeps capturing into an internal buffer, continuously overwriting the
-previously, not read frame, and returns the frame being received at the
-time of the :ref:`read() <func-read>` call as soon as it is complete.
-
-A driver discarding the newest frames stops capturing until the next
-:ref:`read() <func-read>` call. The frame being received at :ref:`read() <func-read>`
-time is discarded, returning the following frame instead. Again this
-implies a reduction of the capture rate to one half or less of the
-nominal frame rate. An example of this model is the video read mode of
-the bttv driver, initiating a DMA to user memory when :ref:`read() <func-read>`
-is called and returning when the DMA finished.
-
-In the multiple buffer model drivers maintain a ring of internal
-buffers, automatically advancing to the next free buffer. This allows
-continuous capturing when the application can empty the buffers fast
-enough. Again, the behavior when the driver runs out of free buffers
-depends on the discarding policy.
-
-Applications can get and set the number of buffers used internally by
-the driver with the :ref:`VIDIOC_G_PARM <VIDIOC_G_PARM>` and
-:ref:`VIDIOC_S_PARM <VIDIOC_G_PARM>` ioctls. They are optional,
-however. The discarding policy is not reported and cannot be changed.
-For minimum requirements see :ref:`devices`.
-
-
-Return Value
-============
-
-On success, the number of bytes read 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. This may happen for example because
-:ref:`read() <func-read>` was interrupted by a signal. On error, -1 is
-returned, and the ``errno`` variable is set appropriately. In this case
-the next read will start at the beginning of a new frame. Possible error
-codes are:
-
-EAGAIN
-    Non-blocking I/O has been selected using O_NONBLOCK and no data was
-    immediately available for reading.
-
-EBADF
-    ``fd`` is not a valid file descriptor or is not open for reading, or
-    the process already has the maximum number of files open.
-
-EBUSY
-    The driver does not support multiple read streams and the device is
-    already in use.
-
-EFAULT
-    ``buf`` references an inaccessible memory area.
-
-EINTR
-    The call was interrupted by a signal before any data was read.
-
-EIO
-    I/O error. This indicates some hardware problem or a failure to
-    communicate with a remote device (USB camera etc.).
-
-EINVAL
-    The :ref:`read() <func-read>` function is not supported by this driver, not
-    on this device, or generally not on this type of device.
diff --git a/Documentation/media/uapi/v4l/func-select.rst b/Documentation/media/uapi/v4l/func-select.rst
deleted file mode 100644
index af5f1e31c0fb..000000000000
--- a/Documentation/media/uapi/v4l/func-select.rst
+++ /dev/null
@@ -1,127 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _func-select:
-
-*************
-V4L2 select()
-*************
-
-Name
-====
-
-v4l2-select - Synchronous I/O multiplexing
-
-
-Synopsis
-========
-
-.. code-block:: c
-
-    #include <sys/time.h>
-    #include <sys/types.h>
-    #include <unistd.h>
-
-
-.. c:function:: int select( int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout )
-    :name: v4l2-select
-
-Arguments
-=========
-
-``nfds``
-  The highest-numbered file descriptor in any of the three sets, plus 1.
-
-``readfds``
-  File descriptions to be watched if a read() call won't block.
-
-``writefds``
-  File descriptions to be watched if a write() won't block.
-
-``exceptfds``
-  File descriptions to be watched for V4L2 events.
-
-``timeout``
-  Maximum time to wait.
-
-
-Description
-===========
-
-With the :ref:`select() <func-select>` function applications can suspend
-execution until the driver has captured data or is ready to accept data
-for output.
-
-When streaming I/O has been negotiated this function waits until a
-buffer has been filled or displayed and can be dequeued with the
-:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl. When buffers are already in
-the outgoing queue of the driver the function returns immediately.
-
-On success :ref:`select() <func-select>` returns the total number of bits set in
-:c:func:`struct fd_set`. When the function timed out it returns
-a value of zero. On failure it returns -1 and the ``errno`` variable is
-set appropriately. When the application did not call
-:ref:`VIDIOC_QBUF` or
-:ref:`VIDIOC_STREAMON` yet the :ref:`select() <func-select>`
-function succeeds, setting the bit of the file descriptor in ``readfds``
-or ``writefds``, but subsequent :ref:`VIDIOC_DQBUF <VIDIOC_QBUF>`
-calls will fail. [#f1]_
-
-When use of the :ref:`read() <func-read>` function has been negotiated and the
-driver does not capture yet, the :ref:`select() <func-select>` function starts
-capturing. When that fails, :ref:`select() <func-select>` returns successful and
-a subsequent :ref:`read() <func-read>` call, which also attempts to start
-capturing, will return an appropriate error code. When the driver
-captures continuously (as opposed to, for example, still images) and
-data is already available the :ref:`select() <func-select>` function returns
-immediately.
-
-When use of the :ref:`write() <func-write>` function has been negotiated the
-:ref:`select() <func-select>` function just waits until the driver is ready for a
-non-blocking :ref:`write() <func-write>` call.
-
-All drivers implementing the :ref:`read() <func-read>` or :ref:`write() <func-write>`
-function or streaming I/O must also support the :ref:`select() <func-select>`
-function.
-
-For more details see the :ref:`select() <func-select>` manual page.
-
-
-Return Value
-============
-
-On success, :ref:`select() <func-select>` returns the number of descriptors
-contained in the three returned descriptor sets, which will be zero if
-the timeout expired. On error -1 is returned, and the ``errno`` variable
-is set appropriately; the sets and ``timeout`` are undefined. Possible
-error codes are:
-
-EBADF
-    One or more of the file descriptor sets specified a file descriptor
-    that is not open.
-
-EBUSY
-    The driver does not support multiple read or write streams and the
-    device is already in use.
-
-EFAULT
-    The ``readfds``, ``writefds``, ``exceptfds`` or ``timeout`` pointer
-    references an inaccessible memory area.
-
-EINTR
-    The call was interrupted by a signal.
-
-EINVAL
-    The ``nfds`` argument is less than zero or greater than
-    ``FD_SETSIZE``.
-
-.. [#f1]
-   The Linux kernel implements :ref:`select() <func-select>` like the
-   :ref:`poll() <func-poll>` function, but :ref:`select() <func-select>` cannot
-   return a ``POLLERR``.
diff --git a/Documentation/media/uapi/v4l/func-write.rst b/Documentation/media/uapi/v4l/func-write.rst
deleted file mode 100644
index 865129c726ad..000000000000
--- a/Documentation/media/uapi/v4l/func-write.rst
+++ /dev/null
@@ -1,91 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _func-write:
-
-************
-V4L2 write()
-************
-
-Name
-====
-
-v4l2-write - Write to a V4L2 device
-
-
-Synopsis
-========
-
-.. code-block:: c
-
-    #include <unistd.h>
-
-
-.. c:function:: ssize_t write( int fd, void *buf, size_t count )
-    :name: v4l2-write
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``buf``
-     Buffer with data to be written
-
-``count``
-    Number of bytes at the buffer
-
-Description
-===========
-
-:ref:`write() <func-write>` writes up to ``count`` bytes to the device
-referenced by the file descriptor ``fd`` from the buffer starting at
-``buf``. When the hardware outputs are not active yet, this function
-enables them. When ``count`` is zero, :ref:`write() <func-write>` returns 0
-without any other effect.
-
-When the application does not provide more data in time, the previous
-video frame, raw VBI image, sliced VPS or WSS data is displayed again.
-Sliced Teletext or Closed Caption data is not repeated, the driver
-inserts a blank line instead.
-
-
-Return Value
-============
-
-On success, the number of bytes written are returned. Zero indicates
-nothing was written. On error, -1 is returned, and the ``errno``
-variable is set appropriately. In this case the next write will start at
-the beginning of a new frame. Possible error codes are:
-
-EAGAIN
-    Non-blocking I/O has been selected using the
-    :ref:`O_NONBLOCK <func-open>` flag and no buffer space was
-    available to write the data immediately.
-
-EBADF
-    ``fd`` is not a valid file descriptor or is not open for writing.
-
-EBUSY
-    The driver does not support multiple write streams and the device is
-    already in use.
-
-EFAULT
-    ``buf`` references an inaccessible memory area.
-
-EINTR
-    The call was interrupted by a signal before any data was written.
-
-EIO
-    I/O error. This indicates some hardware problem.
-
-EINVAL
-    The :ref:`write() <func-write>` function is not supported by this driver,
-    not on this device, or generally not on this type of device.
diff --git a/Documentation/media/uapi/v4l/hist-v4l2.rst b/Documentation/media/uapi/v4l/hist-v4l2.rst
deleted file mode 100644
index 9e097f34cb74..000000000000
--- a/Documentation/media/uapi/v4l/hist-v4l2.rst
+++ /dev/null
@@ -1,1374 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _hist-v4l2:
-
-***********************
-Changes of the V4L2 API
-***********************
-
-Soon after the V4L API was added to the kernel it was criticised as too
-inflexible. In August 1998 Bill Dirks proposed a number of improvements
-and began to work on documentation, example drivers and applications.
-With the help of other volunteers this eventually became the V4L2 API,
-not just an extension but a replacement for the V4L API. However it took
-another four years and two stable kernel releases until the new API was
-finally accepted for inclusion into the kernel in its present form.
-
-
-Early Versions
-==============
-
-1998-08-20: First version.
-
-1998-08-27: The :ref:`select() <func-select>` function was introduced.
-
-1998-09-10: New video standard interface.
-
-1998-09-18: The ``VIDIOC_NONCAP`` ioctl was replaced by the otherwise
-meaningless ``O_TRUNC`` :ref:`open() <func-open>` flag, and the
-aliases ``O_NONCAP`` and ``O_NOIO`` were defined. Applications can set
-this flag if they intend to access controls only, as opposed to capture
-applications which need exclusive access. The ``VIDEO_STD_XXX``
-identifiers are now ordinals instead of flags, and the
-``video_std_construct()`` helper function takes id and
-transmission arguments.
-
-1998-09-28: Revamped video standard. Made video controls individually
-enumerable.
-
-1998-10-02: The ``id`` field was removed from struct
-struct ``video_standard`` and the color subcarrier fields were
-renamed. The :ref:`VIDIOC_QUERYSTD` ioctl was
-renamed to :ref:`VIDIOC_ENUMSTD`,
-:ref:`VIDIOC_G_INPUT <VIDIOC_G_INPUT>` to
-:ref:`VIDIOC_ENUMINPUT`. A first draft of the
-Codec API was released.
-
-1998-11-08: Many minor changes. Most symbols have been renamed. Some
-material changes to struct :c:type:`v4l2_capability`.
-
-1998-11-12: The read/write directon of some ioctls was misdefined.
-
-1998-11-14: ``V4L2_PIX_FMT_RGB24`` changed to ``V4L2_PIX_FMT_BGR24``,
-and ``V4L2_PIX_FMT_RGB32`` changed to ``V4L2_PIX_FMT_BGR32``. Audio
-controls are now accessible with the
-:ref:`VIDIOC_G_CTRL <VIDIOC_G_CTRL>` and
-:ref:`VIDIOC_S_CTRL <VIDIOC_G_CTRL>` ioctls under names starting
-with ``V4L2_CID_AUDIO``. The ``V4L2_MAJOR`` define was removed from
-``videodev.h`` since it was only used once in the ``videodev`` kernel
-module. The ``YUV422`` and ``YUV411`` planar image formats were added.
-
-1998-11-28: A few ioctl symbols changed. Interfaces for codecs and video
-output devices were added.
-
-1999-01-14: A raw VBI capture interface was added.
-
-1999-01-19: The ``VIDIOC_NEXTBUF`` ioctl was removed.
-
-
-V4L2 Version 0.16 1999-01-31
-============================
-
-1999-01-27: There is now one QBUF ioctl, VIDIOC_QWBUF and VIDIOC_QRBUF
-are gone. VIDIOC_QBUF takes a v4l2_buffer as a parameter. Added
-digital zoom (cropping) controls.
-
-
-V4L2 Version 0.18 1999-03-16
-============================
-
-Added a v4l to V4L2 ioctl compatibility layer to videodev.c. Driver
-writers, this changes how you implement your ioctl handler. See the
-Driver Writer's Guide. Added some more control id codes.
-
-
-V4L2 Version 0.19 1999-06-05
-============================
-
-1999-03-18: Fill in the category and catname fields of v4l2_queryctrl
-objects before passing them to the driver. Required a minor change to
-the VIDIOC_QUERYCTRL handlers in the sample drivers.
-
-1999-03-31: Better compatibility for v4l memory capture ioctls. Requires
-changes to drivers to fully support new compatibility features, see
-Driver Writer's Guide and v4l2cap.c. Added new control IDs:
-V4L2_CID_HFLIP, _VFLIP. Changed V4L2_PIX_FMT_YUV422P to _YUV422P,
-and _YUV411P to _YUV411P.
-
-1999-04-04: Added a few more control IDs.
-
-1999-04-07: Added the button control type.
-
-1999-05-02: Fixed a typo in videodev.h, and added the
-V4L2_CTRL_FLAG_GRAYED (later V4L2_CTRL_FLAG_GRABBED) flag.
-
-1999-05-20: Definition of VIDIOC_G_CTRL was wrong causing a
-malfunction of this ioctl.
-
-1999-06-05: Changed the value of V4L2_CID_WHITENESS.
-
-
-V4L2 Version 0.20 (1999-09-10)
-==============================
-
-Version 0.20 introduced a number of changes which were *not backward
-compatible* with 0.19 and earlier versions. Purpose of these changes was
-to simplify the API, while making it more extensible and following
-common Linux driver API conventions.
-
-1. Some typos in ``V4L2_FMT_FLAG`` symbols were fixed. struct
-   :c:type:`v4l2_clip` was changed for compatibility with
-   v4l. (1999-08-30)
-
-2. ``V4L2_TUNER_SUB_LANG1`` was added. (1999-09-05)
-
-3. All ioctl() commands that used an integer argument now take a pointer
-   to an integer. Where it makes sense, ioctls will return the actual
-   new value in the integer pointed to by the argument, a common
-   convention in the V4L2 API. The affected ioctls are: VIDIOC_PREVIEW,
-   VIDIOC_STREAMON, VIDIOC_STREAMOFF, VIDIOC_S_FREQ,
-   VIDIOC_S_INPUT, VIDIOC_S_OUTPUT, VIDIOC_S_EFFECT. For example
-
-
-   .. code-block:: c
-
-       err = ioctl (fd, VIDIOC_XXX, V4L2_XXX);
-
-   becomes
-
-
-   .. code-block:: c
-
-       int a = V4L2_XXX; err = ioctl(fd, VIDIOC_XXX, &a);
-
-4. All the different get- and set-format commands were swept into one
-   :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` and
-   :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl taking a union and a
-   type field selecting the union member as parameter. Purpose is to
-   simplify the API by eliminating several ioctls and to allow new and
-   driver private data streams without adding new ioctls.
-
-   This change obsoletes the following ioctls: ``VIDIOC_S_INFMT``,
-   ``VIDIOC_G_INFMT``, ``VIDIOC_S_OUTFMT``, ``VIDIOC_G_OUTFMT``,
-   ``VIDIOC_S_VBIFMT`` and ``VIDIOC_G_VBIFMT``. The image format
-   structure struct :c:type:`v4l2_format` was renamed to struct
-   :c:type:`v4l2_pix_format`, while struct
-   :c:type:`v4l2_format` is now the envelopping structure
-   for all format negotiations.
-
-5. Similar to the changes above, the ``VIDIOC_G_PARM`` and
-   ``VIDIOC_S_PARM`` ioctls were merged with ``VIDIOC_G_OUTPARM`` and
-   ``VIDIOC_S_OUTPARM``. A ``type`` field in the new struct
-   :c:type:`v4l2_streamparm` selects the respective
-   union member.
-
-   This change obsoletes the ``VIDIOC_G_OUTPARM`` and
-   ``VIDIOC_S_OUTPARM`` ioctls.
-
-6. Control enumeration was simplified, and two new control flags were
-   introduced and one dropped. The ``catname`` field was replaced by a
-   ``group`` field.
-
-   Drivers can now flag unsupported and temporarily unavailable controls
-   with ``V4L2_CTRL_FLAG_DISABLED`` and ``V4L2_CTRL_FLAG_GRABBED``
-   respectively. The ``group`` name indicates a possibly narrower
-   classification than the ``category``. In other words, there may be
-   multiple groups within a category. Controls within a group would
-   typically be drawn within a group box. Controls in different
-   categories might have a greater separation, or may even appear in
-   separate windows.
-
-7. The struct :c:type:`v4l2_buffer` ``timestamp`` was
-   changed to a 64 bit integer, containing the sampling or output time
-   of the frame in nanoseconds. Additionally timestamps will be in
-   absolute system time, not starting from zero at the beginning of a
-   stream. The data type name for timestamps is stamp_t, defined as a
-   signed 64-bit integer. Output devices should not send a buffer out
-   until the time in the timestamp field has arrived. I would like to
-   follow SGI's lead, and adopt a multimedia timestamping system like
-   their UST (Unadjusted System Time). See
-   http://web.archive.org/web/\*/http://reality.sgi.com
-   /cpirazzi_engr/lg/time/intro.html. UST uses timestamps that are
-   64-bit signed integers (not struct timeval's) and given in nanosecond
-   units. The UST clock starts at zero when the system is booted and
-   runs continuously and uniformly. It takes a little over 292 years for
-   UST to overflow. There is no way to set the UST clock. The regular
-   Linux time-of-day clock can be changed periodically, which would
-   cause errors if it were being used for timestamping a multimedia
-   stream. A real UST style clock will require some support in the
-   kernel that is not there yet. But in anticipation, I will change the
-   timestamp field to a 64-bit integer, and I will change the
-   v4l2_masterclock_gettime() function (used only by drivers) to
-   return a 64-bit integer.
-
-8. A ``sequence`` field was added to struct
-   :c:type:`v4l2_buffer`. The ``sequence`` field counts
-   captured frames, it is ignored by output devices. When a capture
-   driver drops a frame, the sequence number of that frame is skipped.
-
-
-V4L2 Version 0.20 incremental changes
-=====================================
-
-1999-12-23: In struct :c:type:`v4l2_vbi_format` the
-``reserved1`` field became ``offset``. Previously drivers were required
-to clear the ``reserved1`` field.
-
-2000-01-13: The ``V4L2_FMT_FLAG_NOT_INTERLACED`` flag was added.
-
-2000-07-31: The ``linux/poll.h`` header is now included by
-``videodev.h`` for compatibility with the original ``videodev.h`` file.
-
-2000-11-20: ``V4L2_TYPE_VBI_OUTPUT`` and ``V4L2_PIX_FMT_Y41P`` were
-added.
-
-2000-11-25: ``V4L2_TYPE_VBI_INPUT`` was added.
-
-2000-12-04: A couple typos in symbol names were fixed.
-
-2001-01-18: To avoid namespace conflicts the ``fourcc`` macro defined in
-the ``videodev.h`` header file was renamed to ``v4l2_fourcc``.
-
-2001-01-25: A possible driver-level compatibility problem between the
-``videodev.h`` file in Linux 2.4.0 and the ``videodev.h`` file included
-in the ``videodevX`` patch was fixed. Users of an earlier version of
-``videodevX`` on Linux 2.4.0 should recompile their V4L and V4L2
-drivers.
-
-2001-01-26: A possible kernel-level incompatibility between the
-``videodev.h`` file in the ``videodevX`` patch and the ``videodev.h``
-file in Linux 2.2.x with devfs patches applied was fixed.
-
-2001-03-02: Certain V4L ioctls which pass data in both direction
-although they are defined with read-only parameter, did not work
-correctly through the backward compatibility layer. [Solution?]
-
-2001-04-13: Big endian 16-bit RGB formats were added.
-
-2001-09-17: New YUV formats and the
-:ref:`VIDIOC_G_FREQUENCY <VIDIOC_G_FREQUENCY>` and
-:ref:`VIDIOC_S_FREQUENCY <VIDIOC_G_FREQUENCY>` ioctls were added.
-(The old ``VIDIOC_G_FREQ`` and ``VIDIOC_S_FREQ`` ioctls did not take
-multiple tuners into account.)
-
-2000-09-18: ``V4L2_BUF_TYPE_VBI`` was added. This may *break
-compatibility* as the :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` and
-:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctls may fail now if the struct
-struct ``v4l2_fmt`` ``type`` field does not contain
-``V4L2_BUF_TYPE_VBI``. In the documentation of the struct
-:c:type:`v4l2_vbi_format` ``offset`` field the
-ambiguous phrase "rising edge" was changed to "leading edge".
-
-
-V4L2 Version 0.20 2000-11-23
-============================
-
-A number of changes were made to the raw VBI interface.
-
-1. Figures clarifying the line numbering scheme were added to the V4L2
-   API specification. The ``start``\ [0] and ``start``\ [1] fields no
-   longer count line numbers beginning at zero. Rationale: a) The
-   previous definition was unclear. b) The ``start``\ [] values are
-   ordinal numbers. c) There is no point in inventing a new line
-   numbering scheme. We now use line number as defined by ITU-R, period.
-   Compatibility: Add one to the start values. Applications depending on
-   the previous semantics may not function correctly.
-
-2. The restriction "count[0] > 0 and count[1] > 0" has been relaxed to
-   "(count[0] + count[1]) > 0". Rationale: Drivers may allocate
-   resources at scan line granularity and some data services are
-   transmitted only on the first field. The comment that both ``count``
-   values will usually be equal is misleading and pointless and has been
-   removed. This change *breaks compatibility* with earlier versions:
-   Drivers may return ``EINVAL``, applications may not function correctly.
-
-3. Drivers are again permitted to return negative (unknown) start values
-   as proposed earlier. Why this feature was dropped is unclear. This
-   change may *break compatibility* with applications depending on the
-   start values being positive. The use of ``EBUSY`` and ``EINVAL``
-   error codes with the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl was
-   clarified. The ``EBUSY`` error code was finally documented, and the
-   ``reserved2`` field which was previously mentioned only in the
-   ``videodev.h`` header file.
-
-4. New buffer types ``V4L2_TYPE_VBI_INPUT`` and ``V4L2_TYPE_VBI_OUTPUT``
-   were added. The former is an alias for the old ``V4L2_TYPE_VBI``, the
-   latter was missing in the ``videodev.h`` file.
-
-
-V4L2 Version 0.20 2002-07-25
-============================
-
-Added sliced VBI interface proposal.
-
-
-V4L2 in Linux 2.5.46, 2002-10
-=============================
-
-Around October-November 2002, prior to an announced feature freeze of
-Linux 2.5, the API was revised, drawing from experience with V4L2 0.20.
-This unnamed version was finally merged into Linux 2.5.46.
-
-1.  As specified in :ref:`related`, drivers must make related device
-    functions available under all minor device numbers.
-
-2.  The :ref:`open() <func-open>` function requires access mode
-    ``O_RDWR`` regardless of the device type. All V4L2 drivers
-    exchanging data with applications must support the ``O_NONBLOCK``
-    flag. The ``O_NOIO`` flag, a V4L2 symbol which aliased the
-    meaningless ``O_TRUNC`` to indicate accesses without data exchange
-    (panel applications) was dropped. Drivers must stay in "panel mode"
-    until the application attempts to initiate a data exchange, see
-    :ref:`open`.
-
-3.  The struct :c:type:`v4l2_capability` changed
-    dramatically. Note that also the size of the structure changed,
-    which is encoded in the ioctl request code, thus older V4L2 devices
-    will respond with an ``EINVAL`` error code to the new
-    :ref:`VIDIOC_QUERYCAP` ioctl.
-
-    There are new fields to identify the driver, a new RDS device
-    function ``V4L2_CAP_RDS_CAPTURE``, the ``V4L2_CAP_AUDIO`` flag
-    indicates if the device has any audio connectors, another I/O
-    capability ``V4L2_CAP_ASYNCIO`` can be flagged. In response to these
-    changes the ``type`` field became a bit set and was merged into the
-    ``flags`` field. ``V4L2_FLAG_TUNER`` was renamed to
-    ``V4L2_CAP_TUNER``, ``V4L2_CAP_VIDEO_OVERLAY`` replaced
-    ``V4L2_FLAG_PREVIEW`` and ``V4L2_CAP_VBI_CAPTURE`` and
-    ``V4L2_CAP_VBI_OUTPUT`` replaced ``V4L2_FLAG_DATA_SERVICE``.
-    ``V4L2_FLAG_READ`` and ``V4L2_FLAG_WRITE`` were merged into
-    ``V4L2_CAP_READWRITE``.
-
-    The redundant fields ``inputs``, ``outputs`` and ``audios`` were
-    removed. These properties can be determined as described in
-    :ref:`video` and :ref:`audio`.
-
-    The somewhat volatile and therefore barely useful fields
-    ``maxwidth``, ``maxheight``, ``minwidth``, ``minheight``,
-    ``maxframerate`` were removed. This information is available as
-    described in :ref:`format` and :ref:`standard`.
-
-    ``V4L2_FLAG_SELECT`` was removed. We believe the select() function
-    is important enough to require support of it in all V4L2 drivers
-    exchanging data with applications. The redundant
-    ``V4L2_FLAG_MONOCHROME`` flag was removed, this information is
-    available as described in :ref:`format`.
-
-4.  In struct :c:type:`v4l2_input` the ``assoc_audio``
-    field and the ``capability`` field and its only flag
-    ``V4L2_INPUT_CAP_AUDIO`` was replaced by the new ``audioset`` field.
-    Instead of linking one video input to one audio input this field
-    reports all audio inputs this video input combines with.
-
-    New fields are ``tuner`` (reversing the former link from tuners to
-    video inputs), ``std`` and ``status``.
-
-    Accordingly struct :c:type:`v4l2_output` lost its
-    ``capability`` and ``assoc_audio`` fields. ``audioset``,
-    ``modulator`` and ``std`` where added instead.
-
-5.  The struct :c:type:`v4l2_audio` field ``audio`` was
-    renamed to ``index``, for consistency with other structures. A new
-    capability flag ``V4L2_AUDCAP_STEREO`` was added to indicated if the
-    audio input in question supports stereo sound.
-    ``V4L2_AUDCAP_EFFECTS`` and the corresponding ``V4L2_AUDMODE`` flags
-    where removed. This can be easily implemented using controls.
-    (However the same applies to AVL which is still there.)
-
-    Again for consistency the struct
-    :c:type:`v4l2_audioout` field ``audio`` was renamed
-    to ``index``.
-
-6.  The struct :c:type:`v4l2_tuner` ``input`` field was
-    replaced by an ``index`` field, permitting devices with multiple
-    tuners. The link between video inputs and tuners is now reversed,
-    inputs point to their tuner. The ``std`` substructure became a
-    simple set (more about this below) and moved into struct
-    :c:type:`v4l2_input`. A ``type`` field was added.
-
-    Accordingly in struct :c:type:`v4l2_modulator` the
-    ``output`` was replaced by an ``index`` field.
-
-    In struct :c:type:`v4l2_frequency` the ``port``
-    field was replaced by a ``tuner`` field containing the respective
-    tuner or modulator index number. A tuner ``type`` field was added
-    and the ``reserved`` field became larger for future extensions
-    (satellite tuners in particular).
-
-7.  The idea of completely transparent video standards was dropped.
-    Experience showed that applications must be able to work with video
-    standards beyond presenting the user a menu. Instead of enumerating
-    supported standards with an ioctl applications can now refer to
-    standards by :ref:`v4l2_std_id <v4l2-std-id>` and symbols
-    defined in the ``videodev2.h`` header file. For details see
-    :ref:`standard`. The :ref:`VIDIOC_G_STD <VIDIOC_G_STD>` and
-    :ref:`VIDIOC_S_STD <VIDIOC_G_STD>` now take a pointer to this
-    type as argument. :ref:`VIDIOC_QUERYSTD` was
-    added to autodetect the received standard, if the hardware has this
-    capability. In struct :c:type:`v4l2_standard` an
-    ``index`` field was added for
-    :ref:`VIDIOC_ENUMSTD`. A
-    :ref:`v4l2_std_id <v4l2-std-id>` field named ``id`` was added as
-    machine readable identifier, also replacing the ``transmission``
-    field. The misleading ``framerate`` field was renamed to
-    ``frameperiod``. The now obsolete ``colorstandard`` information,
-    originally needed to distguish between variations of standards, were
-    removed.
-
-    Struct ``v4l2_enumstd`` ceased to be.
-    :ref:`VIDIOC_ENUMSTD` now takes a pointer to a
-    struct :c:type:`v4l2_standard` directly. The
-    information which standards are supported by a particular video
-    input or output moved into struct :c:type:`v4l2_input`
-    and struct :c:type:`v4l2_output` fields named ``std``,
-    respectively.
-
-8.  The struct :ref:`v4l2_queryctrl <v4l2-queryctrl>` fields
-    ``category`` and ``group`` did not catch on and/or were not
-    implemented as expected and therefore removed.
-
-9.  The :ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` ioctl was added to
-    negotiate data formats as with
-    :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`, but without the overhead of
-    programming the hardware and regardless of I/O in progress.
-
-    In struct :c:type:`v4l2_format` the ``fmt`` union was
-    extended to contain struct :c:type:`v4l2_window`. All
-    image format negotiations are now possible with ``VIDIOC_G_FMT``,
-    ``VIDIOC_S_FMT`` and ``VIDIOC_TRY_FMT``; ioctl. The ``VIDIOC_G_WIN``
-    and ``VIDIOC_S_WIN`` ioctls to prepare for a video overlay were
-    removed. The ``type`` field changed to type enum
-    :c:type:`v4l2_buf_type` and the buffer type names
-    changed as follows.
-
-
-
-    .. flat-table::
-	:header-rows:  1
-	:stub-columns: 0
-
-	* - Old defines
-	  - enum :c:type:`v4l2_buf_type`
-	* - ``V4L2_BUF_TYPE_CAPTURE``
-	  - ``V4L2_BUF_TYPE_VIDEO_CAPTURE``
-	* - ``V4L2_BUF_TYPE_CODECIN``
-	  - Omitted for now
-	* - ``V4L2_BUF_TYPE_CODECOUT``
-	  - Omitted for now
-	* - ``V4L2_BUF_TYPE_EFFECTSIN``
-	  - Omitted for now
-	* - ``V4L2_BUF_TYPE_EFFECTSIN2``
-	  - Omitted for now
-	* - ``V4L2_BUF_TYPE_EFFECTSOUT``
-	  - Omitted for now
-	* - ``V4L2_BUF_TYPE_VIDEOOUT``
-	  - ``V4L2_BUF_TYPE_VIDEO_OUTPUT``
-	* - ``-``
-	  - ``V4L2_BUF_TYPE_VIDEO_OVERLAY``
-	* - ``-``
-	  - ``V4L2_BUF_TYPE_VBI_CAPTURE``
-	* - ``-``
-	  - ``V4L2_BUF_TYPE_VBI_OUTPUT``
-	* - ``-``
-	  - ``V4L2_BUF_TYPE_SLICED_VBI_CAPTURE``
-	* - ``-``
-	  - ``V4L2_BUF_TYPE_SLICED_VBI_OUTPUT``
-	* - ``V4L2_BUF_TYPE_PRIVATE_BASE``
-	  - ``V4L2_BUF_TYPE_PRIVATE`` (but this is deprecated)
-
-
-10. In struct :c:type:`v4l2_fmtdesc` a enum
-    :c:type:`v4l2_buf_type` field named ``type`` was
-    added as in struct :c:type:`v4l2_format`. The
-    ``VIDIOC_ENUM_FBUFFMT`` ioctl is no longer needed and was removed.
-    These calls can be replaced by
-    :ref:`VIDIOC_ENUM_FMT` with type
-    ``V4L2_BUF_TYPE_VIDEO_OVERLAY``.
-
-11. In struct :c:type:`v4l2_pix_format` the ``depth``
-    field was removed, assuming applications which recognize the format
-    by its four-character-code already know the color depth, and others
-    do not care about it. The same rationale lead to the removal of the
-    ``V4L2_FMT_FLAG_COMPRESSED`` flag. The
-    ``V4L2_FMT_FLAG_SWCONVECOMPRESSED`` flag was removed because drivers
-    are not supposed to convert images in kernel space. A user library
-    of conversion functions should be provided instead. The
-    ``V4L2_FMT_FLAG_BYTESPERLINE`` flag was redundant. Applications can
-    set the ``bytesperline`` field to zero to get a reasonable default.
-    Since the remaining flags were replaced as well, the ``flags`` field
-    itself was removed.
-
-    The interlace flags were replaced by a enum
-    :c:type:`v4l2_field` value in a newly added ``field``
-    field.
-
-
-
-    .. flat-table::
-	:header-rows:  1
-	:stub-columns: 0
-
-	* - Old flag
-	  - enum :c:type:`v4l2_field`
-	* - ``V4L2_FMT_FLAG_NOT_INTERLACED``
-	  - ?
-	* - ``V4L2_FMT_FLAG_INTERLACED`` = ``V4L2_FMT_FLAG_COMBINED``
-	  - ``V4L2_FIELD_INTERLACED``
-	* - ``V4L2_FMT_FLAG_TOPFIELD`` = ``V4L2_FMT_FLAG_ODDFIELD``
-	  - ``V4L2_FIELD_TOP``
-	* - ``V4L2_FMT_FLAG_BOTFIELD`` = ``V4L2_FMT_FLAG_EVENFIELD``
-	  - ``V4L2_FIELD_BOTTOM``
-	* - ``-``
-	  - ``V4L2_FIELD_SEQ_TB``
-	* - ``-``
-	  - ``V4L2_FIELD_SEQ_BT``
-	* - ``-``
-	  - ``V4L2_FIELD_ALTERNATE``
-
-
-    The color space flags were replaced by a enum
-    :c:type:`v4l2_colorspace` value in a newly added
-    ``colorspace`` field, where one of ``V4L2_COLORSPACE_SMPTE170M``,
-    ``V4L2_COLORSPACE_BT878``, ``V4L2_COLORSPACE_470_SYSTEM_M`` or
-    ``V4L2_COLORSPACE_470_SYSTEM_BG`` replaces ``V4L2_FMT_CS_601YUV``.
-
-12. In struct :c:type:`v4l2_requestbuffers` the
-    ``type`` field was properly defined as enum
-    :c:type:`v4l2_buf_type`. Buffer types changed as
-    mentioned above. A new ``memory`` field of type enum
-    :c:type:`v4l2_memory` was added to distinguish between
-    I/O methods using buffers allocated by the driver or the
-    application. See :ref:`io` for details.
-
-13. In struct :c:type:`v4l2_buffer` the ``type`` field was
-    properly defined as enum :c:type:`v4l2_buf_type`.
-    Buffer types changed as mentioned above. A ``field`` field of type
-    enum :c:type:`v4l2_field` was added to indicate if a
-    buffer contains a top or bottom field. The old field flags were
-    removed. Since no unadjusted system time clock was added to the
-    kernel as planned, the ``timestamp`` field changed back from type
-    stamp_t, an unsigned 64 bit integer expressing the sample time in
-    nanoseconds, to struct :c:type:`timeval`. With the addition
-    of a second memory mapping method the ``offset`` field moved into
-    union ``m``, and a new ``memory`` field of type enum
-    :c:type:`v4l2_memory` was added to distinguish between
-    I/O methods. See :ref:`io` for details.
-
-    The ``V4L2_BUF_REQ_CONTIG`` flag was used by the V4L compatibility
-    layer, after changes to this code it was no longer needed. The
-    ``V4L2_BUF_ATTR_DEVICEMEM`` flag would indicate if the buffer was
-    indeed allocated in device memory rather than DMA-able system
-    memory. It was barely useful and so was removed.
-
-14. In struct :c:type:`v4l2_framebuffer` the
-    ``base[3]`` array anticipating double- and triple-buffering in
-    off-screen video memory, however without defining a synchronization
-    mechanism, was replaced by a single pointer. The
-    ``V4L2_FBUF_CAP_SCALEUP`` and ``V4L2_FBUF_CAP_SCALEDOWN`` flags were
-    removed. Applications can determine this capability more accurately
-    using the new cropping and scaling interface. The
-    ``V4L2_FBUF_CAP_CLIPPING`` flag was replaced by
-    ``V4L2_FBUF_CAP_LIST_CLIPPING`` and
-    ``V4L2_FBUF_CAP_BITMAP_CLIPPING``.
-
-15. In struct :c:type:`v4l2_clip` the ``x``, ``y``,
-    ``width`` and ``height`` field moved into a ``c`` substructure of
-    type struct :c:type:`v4l2_rect`. The ``x`` and ``y``
-    fields were renamed to ``left`` and ``top``, i. e. offsets to a
-    context dependent origin.
-
-16. In struct :c:type:`v4l2_window` the ``x``, ``y``,
-    ``width`` and ``height`` field moved into a ``w`` substructure as
-    above. A ``field`` field of type :c:type:`v4l2_field` was added to
-    distinguish between field and frame (interlaced) overlay.
-
-17. The digital zoom interface, including struct
-    struct ``v4l2_zoomcap``, struct
-    struct ``v4l2_zoom``, ``V4L2_ZOOM_NONCAP`` and
-    ``V4L2_ZOOM_WHILESTREAMING`` was replaced by a new cropping and
-    scaling interface. The previously unused struct
-    struct :c:type:`v4l2_cropcap` and struct :c:type:`v4l2_crop`
-    where redefined for this purpose. See :ref:`crop` for details.
-
-18. In struct :c:type:`v4l2_vbi_format` the
-    ``SAMPLE_FORMAT`` field now contains a four-character-code as used
-    to identify video image formats and ``V4L2_PIX_FMT_GREY`` replaces
-    the ``V4L2_VBI_SF_UBYTE`` define. The ``reserved`` field was
-    extended.
-
-19. In struct :c:type:`v4l2_captureparm` the type of
-    the ``timeperframe`` field changed from unsigned long to struct
-    :c:type:`v4l2_fract`. This allows the accurate
-    expression of multiples of the NTSC-M frame rate 30000 / 1001. A new
-    field ``readbuffers`` was added to control the driver behaviour in
-    read I/O mode.
-
-    Similar changes were made to struct
-    :c:type:`v4l2_outputparm`.
-
-20. The struct ``v4l2_performance`` and
-    ``VIDIOC_G_PERF`` ioctl were dropped. Except when using the
-    :ref:`read/write I/O method <rw>`, which is limited anyway, this
-    information is already available to applications.
-
-21. The example transformation from RGB to YCbCr color space in the old
-    V4L2 documentation was inaccurate, this has been corrected in
-    :ref:`pixfmt`.
-
-
-V4L2 2003-06-19
-===============
-
-1. A new capability flag ``V4L2_CAP_RADIO`` was added for radio devices.
-   Prior to this change radio devices would identify solely by having
-   exactly one tuner whose type field reads ``V4L2_TUNER_RADIO``.
-
-2. An optional driver access priority mechanism was added, see
-   :ref:`app-pri` for details.
-
-3. The audio input and output interface was found to be incomplete.
-
-   Previously the :ref:`VIDIOC_G_AUDIO <VIDIOC_G_AUDIO>` ioctl would
-   enumerate the available audio inputs. An ioctl to determine the
-   current audio input, if more than one combines with the current video
-   input, did not exist. So ``VIDIOC_G_AUDIO`` was renamed to
-   ``VIDIOC_G_AUDIO_OLD``, this ioctl was removed on Kernel 2.6.39. The
-   :ref:`VIDIOC_ENUMAUDIO` ioctl was added to
-   enumerate audio inputs, while
-   :ref:`VIDIOC_G_AUDIO <VIDIOC_G_AUDIO>` now reports the current
-   audio input.
-
-   The same changes were made to
-   :ref:`VIDIOC_G_AUDOUT <VIDIOC_G_AUDOUT>` and
-   :ref:`VIDIOC_ENUMAUDOUT <VIDIOC_ENUMAUDOUT>`.
-
-   Until further the "videodev" module will automatically translate
-   between the old and new ioctls, but drivers and applications must be
-   updated to successfully compile again.
-
-4. The :ref:`VIDIOC_OVERLAY` ioctl was incorrectly
-   defined with write-read parameter. It was changed to write-only,
-   while the write-read version was renamed to ``VIDIOC_OVERLAY_OLD``.
-   The old ioctl was removed on Kernel 2.6.39. Until further the
-   "videodev" kernel module will automatically translate to the new
-   version, so drivers must be recompiled, but not applications.
-
-5. :ref:`overlay` incorrectly stated that clipping rectangles define
-   regions where the video can be seen. Correct is that clipping
-   rectangles define regions where *no* video shall be displayed and so
-   the graphics surface can be seen.
-
-6. The :ref:`VIDIOC_S_PARM <VIDIOC_G_PARM>` and
-   :ref:`VIDIOC_S_CTRL <VIDIOC_G_CTRL>` ioctls were defined with
-   write-only parameter, inconsistent with other ioctls modifying their
-   argument. They were changed to write-read, while a ``_OLD`` suffix
-   was added to the write-only versions. The old ioctls were removed on
-   Kernel 2.6.39. Drivers and applications assuming a constant parameter
-   need an update.
-
-
-V4L2 2003-11-05
-===============
-
-1. In :ref:`pixfmt-rgb` the following pixel formats were incorrectly
-   transferred from Bill Dirks' V4L2 specification. Descriptions below
-   refer to bytes in memory, in ascending address order.
-
-
-
-   .. flat-table::
-       :header-rows:  1
-       :stub-columns: 0
-
-       * - Symbol
-	 - In this document prior to revision 0.5
-	 - Corrected
-       * - ``V4L2_PIX_FMT_RGB24``
-	 - B, G, R
-	 - R, G, B
-       * - ``V4L2_PIX_FMT_BGR24``
-	 - R, G, B
-	 - B, G, R
-       * - ``V4L2_PIX_FMT_RGB32``
-	 - B, G, R, X
-	 - R, G, B, X
-       * - ``V4L2_PIX_FMT_BGR32``
-	 - R, G, B, X
-	 - B, G, R, X
-
-
-   The ``V4L2_PIX_FMT_BGR24`` example was always correct.
-
-   In :ref:`v4l-image-properties` the mapping of the V4L
-   ``VIDEO_PALETTE_RGB24`` and ``VIDEO_PALETTE_RGB32`` formats to V4L2
-   pixel formats was accordingly corrected.
-
-2. Unrelated to the fixes above, drivers may still interpret some V4L2
-   RGB pixel formats differently. These issues have yet to be addressed,
-   for details see :ref:`pixfmt-rgb`.
-
-
-V4L2 in Linux 2.6.6, 2004-05-09
-===============================
-
-1. The :ref:`VIDIOC_CROPCAP` ioctl was incorrectly
-   defined with read-only parameter. It is now defined as write-read
-   ioctl, while the read-only version was renamed to
-   ``VIDIOC_CROPCAP_OLD``. The old ioctl was removed on Kernel 2.6.39.
-
-
-V4L2 in Linux 2.6.8
-===================
-
-1. A new field ``input`` (former ``reserved[0]``) was added to the
-   struct :c:type:`v4l2_buffer` structure. Purpose of this
-   field is to alternate between video inputs (e. g. cameras) in step
-   with the video capturing process. This function must be enabled with
-   the new ``V4L2_BUF_FLAG_INPUT`` flag. The ``flags`` field is no
-   longer read-only.
-
-
-V4L2 spec erratum 2004-08-01
-============================
-
-1. The return value of the :ref:`func-open` function was incorrectly
-   documented.
-
-2. Audio output ioctls end in -AUDOUT, not -AUDIOOUT.
-
-3. In the Current Audio Input example the ``VIDIOC_G_AUDIO`` ioctl took
-   the wrong argument.
-
-4. The documentation of the :ref:`VIDIOC_QBUF` and
-   :ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctls did not mention the
-   struct :c:type:`v4l2_buffer` ``memory`` field. It was
-   also missing from examples. Also on the ``VIDIOC_DQBUF`` page the ``EIO``
-   error code was not documented.
-
-
-V4L2 in Linux 2.6.14
-====================
-
-1. A new sliced VBI interface was added. It is documented in
-   :ref:`sliced` and replaces the interface first proposed in V4L2
-   specification 0.8.
-
-
-V4L2 in Linux 2.6.15
-====================
-
-1. The :ref:`VIDIOC_LOG_STATUS` ioctl was added.
-
-2. New video standards ``V4L2_STD_NTSC_443``, ``V4L2_STD_SECAM_LC``,
-   ``V4L2_STD_SECAM_DK`` (a set of SECAM D, K and K1), and
-   ``V4L2_STD_ATSC`` (a set of ``V4L2_STD_ATSC_8_VSB`` and
-   ``V4L2_STD_ATSC_16_VSB``) were defined. Note the ``V4L2_STD_525_60``
-   set now includes ``V4L2_STD_NTSC_443``. See also
-   :ref:`v4l2-std-id`.
-
-3. The ``VIDIOC_G_COMP`` and ``VIDIOC_S_COMP`` ioctl were renamed to
-   ``VIDIOC_G_MPEGCOMP`` and ``VIDIOC_S_MPEGCOMP`` respectively. Their
-   argument was replaced by a struct
-   ``v4l2_mpeg_compression`` pointer. (The
-   ``VIDIOC_G_MPEGCOMP`` and ``VIDIOC_S_MPEGCOMP`` ioctls where removed
-   in Linux 2.6.25.)
-
-
-V4L2 spec erratum 2005-11-27
-============================
-
-The capture example in :ref:`capture-example` called the
-:ref:`VIDIOC_S_CROP <VIDIOC_G_CROP>` ioctl without checking if
-cropping is supported. In the video standard selection example in
-:ref:`standard` the :ref:`VIDIOC_S_STD <VIDIOC_G_STD>` call used
-the wrong argument type.
-
-
-V4L2 spec erratum 2006-01-10
-============================
-
-1. The ``V4L2_IN_ST_COLOR_KILL`` flag in struct
-   :c:type:`v4l2_input` not only indicates if the color
-   killer is enabled, but also if it is active. (The color killer
-   disables color decoding when it detects no color in the video signal
-   to improve the image quality.)
-
-2. :ref:`VIDIOC_S_PARM <VIDIOC_G_PARM>` is a write-read ioctl, not
-   write-only as stated on its reference page. The ioctl changed in 2003
-   as noted above.
-
-
-V4L2 spec erratum 2006-02-03
-============================
-
-1. In struct :c:type:`v4l2_captureparm` and struct
-   :c:type:`v4l2_outputparm` the ``timeperframe``
-   field gives the time in seconds, not microseconds.
-
-
-V4L2 spec erratum 2006-02-04
-============================
-
-1. The ``clips`` field in struct :c:type:`v4l2_window`
-   must point to an array of struct :c:type:`v4l2_clip`, not
-   a linked list, because drivers ignore the struct
-   struct :c:type:`v4l2_clip`. ``next`` pointer.
-
-
-V4L2 in Linux 2.6.17
-====================
-
-1. New video standard macros were added: ``V4L2_STD_NTSC_M_KR`` (NTSC M
-   South Korea), and the sets ``V4L2_STD_MN``, ``V4L2_STD_B``,
-   ``V4L2_STD_GH`` and ``V4L2_STD_DK``. The ``V4L2_STD_NTSC`` and
-   ``V4L2_STD_SECAM`` sets now include ``V4L2_STD_NTSC_M_KR`` and
-   ``V4L2_STD_SECAM_LC`` respectively.
-
-2. A new ``V4L2_TUNER_MODE_LANG1_LANG2`` was defined to record both
-   languages of a bilingual program. The use of
-   ``V4L2_TUNER_MODE_STEREO`` for this purpose is deprecated now. See
-   the :ref:`VIDIOC_G_TUNER <VIDIOC_G_TUNER>` section for details.
-
-
-V4L2 spec erratum 2006-09-23 (Draft 0.15)
-=========================================
-
-1. In various places ``V4L2_BUF_TYPE_SLICED_VBI_CAPTURE`` and
-   ``V4L2_BUF_TYPE_SLICED_VBI_OUTPUT`` of the sliced VBI interface were
-   not mentioned along with other buffer types.
-
-2. In :ref:`VIDIOC_G_AUDIO <VIDIOC_G_AUDIO>` it was clarified that the struct
-   :c:type:`v4l2_audio` ``mode`` field is a flags field.
-
-3. :ref:`VIDIOC_QUERYCAP` did not mention the sliced VBI and radio
-   capability flags.
-
-4. In :ref:`VIDIOC_G_FREQUENCY <VIDIOC_G_FREQUENCY>` it was clarified that applications
-   must initialize the tuner ``type`` field of struct
-   :c:type:`v4l2_frequency` before calling
-   :ref:`VIDIOC_S_FREQUENCY <VIDIOC_G_FREQUENCY>`.
-
-5. The ``reserved`` array in struct
-   :c:type:`v4l2_requestbuffers` has 2 elements,
-   not 32.
-
-6. In :ref:`output` and :ref:`raw-vbi` the device file names
-   ``/dev/vout`` which never caught on were replaced by ``/dev/video``.
-
-7. With Linux 2.6.15 the possible range for VBI device minor numbers was
-   extended from 224-239 to 224-255. Accordingly device file names
-   ``/dev/vbi0`` to ``/dev/vbi31`` are possible now.
-
-
-V4L2 in Linux 2.6.18
-====================
-
-1. New ioctls :ref:`VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>`,
-   :ref:`VIDIOC_S_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` and
-   :ref:`VIDIOC_TRY_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` were added, a
-   flag to skip unsupported controls with
-   :ref:`VIDIOC_QUERYCTRL`, new control types
-   ``V4L2_CTRL_TYPE_INTEGER64`` and ``V4L2_CTRL_TYPE_CTRL_CLASS``
-   (:c:type:`v4l2_ctrl_type`), and new control flags
-   ``V4L2_CTRL_FLAG_READ_ONLY``, ``V4L2_CTRL_FLAG_UPDATE``,
-   ``V4L2_CTRL_FLAG_INACTIVE`` and ``V4L2_CTRL_FLAG_SLIDER``
-   (:ref:`control-flags`). See :ref:`extended-controls` for details.
-
-
-V4L2 in Linux 2.6.19
-====================
-
-1. In struct :c:type:`v4l2_sliced_vbi_cap` a
-   buffer type field was added replacing a reserved field. Note on
-   architectures where the size of enum types differs from int types the
-   size of the structure changed. The
-   :ref:`VIDIOC_G_SLICED_VBI_CAP <VIDIOC_G_SLICED_VBI_CAP>` ioctl
-   was redefined from being read-only to write-read. Applications must
-   initialize the type field and clear the reserved fields now. These
-   changes may *break the compatibility* with older drivers and
-   applications.
-
-2. The ioctls :ref:`VIDIOC_ENUM_FRAMESIZES`
-   and
-   :ref:`VIDIOC_ENUM_FRAMEINTERVALS`
-   were added.
-
-3. A new pixel format ``V4L2_PIX_FMT_RGB444`` (:ref:`pixfmt-rgb`) was
-   added.
-
-
-V4L2 spec erratum 2006-10-12 (Draft 0.17)
-=========================================
-
-1. ``V4L2_PIX_FMT_HM12`` (:ref:`reserved-formats`) is a YUV 4:2:0, not
-   4:2:2 format.
-
-
-V4L2 in Linux 2.6.21
-====================
-
-1. The ``videodev2.h`` header file is now dual licensed under GNU
-   General Public License version two or later, and under a 3-clause
-   BSD-style license.
-
-
-V4L2 in Linux 2.6.22
-====================
-
-1. Two new field orders ``V4L2_FIELD_INTERLACED_TB`` and
-   ``V4L2_FIELD_INTERLACED_BT`` were added. See :c:type:`v4l2_field` for
-   details.
-
-2. Three new clipping/blending methods with a global or straight or
-   inverted local alpha value were added to the video overlay interface.
-   See the description of the :ref:`VIDIOC_G_FBUF <VIDIOC_G_FBUF>`
-   and :ref:`VIDIOC_S_FBUF <VIDIOC_G_FBUF>` ioctls for details.
-
-   A new ``global_alpha`` field was added to
-   :c:type:`v4l2_window`, extending the structure. This
-   may *break compatibility* with applications using a struct
-   struct :c:type:`v4l2_window` directly. However the
-   :ref:`VIDIOC_G/S/TRY_FMT <VIDIOC_G_FMT>` ioctls, which take a
-   pointer to a :c:type:`v4l2_format` parent structure
-   with padding bytes at the end, are not affected.
-
-3. The format of the ``chromakey`` field in struct
-   :c:type:`v4l2_window` changed from "host order RGB32"
-   to a pixel value in the same format as the framebuffer. This may
-   *break compatibility* with existing applications. Drivers supporting
-   the "host order RGB32" format are not known.
-
-
-V4L2 in Linux 2.6.24
-====================
-
-1. The pixel formats ``V4L2_PIX_FMT_PAL8``, ``V4L2_PIX_FMT_YUV444``,
-   ``V4L2_PIX_FMT_YUV555``, ``V4L2_PIX_FMT_YUV565`` and
-   ``V4L2_PIX_FMT_YUV32`` were added.
-
-
-V4L2 in Linux 2.6.25
-====================
-
-1. The pixel formats :ref:`V4L2_PIX_FMT_Y16 <V4L2-PIX-FMT-Y16>` and
-   :ref:`V4L2_PIX_FMT_SBGGR16 <V4L2-PIX-FMT-SBGGR16>` were added.
-
-2. New :ref:`controls <control>` ``V4L2_CID_POWER_LINE_FREQUENCY``,
-   ``V4L2_CID_HUE_AUTO``, ``V4L2_CID_WHITE_BALANCE_TEMPERATURE``,
-   ``V4L2_CID_SHARPNESS`` and ``V4L2_CID_BACKLIGHT_COMPENSATION`` were
-   added. The controls ``V4L2_CID_BLACK_LEVEL``, ``V4L2_CID_WHITENESS``,
-   ``V4L2_CID_HCENTER`` and ``V4L2_CID_VCENTER`` were deprecated.
-
-3. A :ref:`Camera controls class <camera-controls>` was added, with
-   the new controls ``V4L2_CID_EXPOSURE_AUTO``,
-   ``V4L2_CID_EXPOSURE_ABSOLUTE``, ``V4L2_CID_EXPOSURE_AUTO_PRIORITY``,
-   ``V4L2_CID_PAN_RELATIVE``, ``V4L2_CID_TILT_RELATIVE``,
-   ``V4L2_CID_PAN_RESET``, ``V4L2_CID_TILT_RESET``,
-   ``V4L2_CID_PAN_ABSOLUTE``, ``V4L2_CID_TILT_ABSOLUTE``,
-   ``V4L2_CID_FOCUS_ABSOLUTE``, ``V4L2_CID_FOCUS_RELATIVE`` and
-   ``V4L2_CID_FOCUS_AUTO``.
-
-4. The ``VIDIOC_G_MPEGCOMP`` and ``VIDIOC_S_MPEGCOMP`` ioctls, which
-   were superseded by the :ref:`extended controls <extended-controls>`
-   interface in Linux 2.6.18, where finally removed from the
-   ``videodev2.h`` header file.
-
-
-V4L2 in Linux 2.6.26
-====================
-
-1. The pixel formats ``V4L2_PIX_FMT_Y16`` and ``V4L2_PIX_FMT_SBGGR16``
-   were added.
-
-2. Added user controls ``V4L2_CID_CHROMA_AGC`` and
-   ``V4L2_CID_COLOR_KILLER``.
-
-
-V4L2 in Linux 2.6.27
-====================
-
-1. The :ref:`VIDIOC_S_HW_FREQ_SEEK` ioctl
-   and the ``V4L2_CAP_HW_FREQ_SEEK`` capability were added.
-
-2. The pixel formats ``V4L2_PIX_FMT_YVYU``, ``V4L2_PIX_FMT_PCA501``,
-   ``V4L2_PIX_FMT_PCA505``, ``V4L2_PIX_FMT_PCA508``,
-   ``V4L2_PIX_FMT_PCA561``, ``V4L2_PIX_FMT_SGBRG8``,
-   ``V4L2_PIX_FMT_PAC207`` and ``V4L2_PIX_FMT_PJPG`` were added.
-
-
-V4L2 in Linux 2.6.28
-====================
-
-1. Added ``V4L2_MPEG_AUDIO_ENCODING_AAC`` and
-   ``V4L2_MPEG_AUDIO_ENCODING_AC3`` MPEG audio encodings.
-
-2. Added ``V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC`` MPEG video encoding.
-
-3. The pixel formats ``V4L2_PIX_FMT_SGRBG10`` and
-   ``V4L2_PIX_FMT_SGRBG10DPCM8`` were added.
-
-
-V4L2 in Linux 2.6.29
-====================
-
-1. The ``VIDIOC_G_CHIP_IDENT`` ioctl was renamed to
-   ``VIDIOC_G_CHIP_IDENT_OLD`` and ``VIDIOC_DBG_G_CHIP_IDENT`` was
-   introduced in its place. The old struct
-   struct ``v4l2_chip_ident`` was renamed to
-   struct ``v4l2_chip_ident_old``.
-
-2. The pixel formats ``V4L2_PIX_FMT_VYUY``, ``V4L2_PIX_FMT_NV16`` and
-   ``V4L2_PIX_FMT_NV61`` were added.
-
-3. Added camera controls ``V4L2_CID_ZOOM_ABSOLUTE``,
-   ``V4L2_CID_ZOOM_RELATIVE``, ``V4L2_CID_ZOOM_CONTINUOUS`` and
-   ``V4L2_CID_PRIVACY``.
-
-
-V4L2 in Linux 2.6.30
-====================
-
-1. New control flag ``V4L2_CTRL_FLAG_WRITE_ONLY`` was added.
-
-2. New control ``V4L2_CID_COLORFX`` was added.
-
-
-V4L2 in Linux 2.6.32
-====================
-
-1. In order to be easier to compare a V4L2 API and a kernel version, now
-   V4L2 API is numbered using the Linux Kernel version numeration.
-
-2. Finalized the RDS capture API. See :ref:`rds` for more information.
-
-3. Added new capabilities for modulators and RDS encoders.
-
-4. Add description for libv4l API.
-
-5. Added support for string controls via new type
-   ``V4L2_CTRL_TYPE_STRING``.
-
-6. Added ``V4L2_CID_BAND_STOP_FILTER`` documentation.
-
-7. Added FM Modulator (FM TX) Extended Control Class:
-   ``V4L2_CTRL_CLASS_FM_TX`` and their Control IDs.
-
-8. Added FM Receiver (FM RX) Extended Control Class:
-   ``V4L2_CTRL_CLASS_FM_RX`` and their Control IDs.
-
-9. Added Remote Controller chapter, describing the default Remote
-   Controller mapping for media devices.
-
-
-V4L2 in Linux 2.6.33
-====================
-
-1. Added support for Digital Video timings in order to support HDTV
-   receivers and transmitters.
-
-
-V4L2 in Linux 2.6.34
-====================
-
-1. Added ``V4L2_CID_IRIS_ABSOLUTE`` and ``V4L2_CID_IRIS_RELATIVE``
-   controls to the :ref:`Camera controls class <camera-controls>`.
-
-
-V4L2 in Linux 2.6.37
-====================
-
-1. Remove the vtx (videotext/teletext) API. This API was no longer used
-   and no hardware exists to verify the API. Nor were any userspace
-   applications found that used it. It was originally scheduled for
-   removal in 2.6.35.
-
-
-V4L2 in Linux 2.6.39
-====================
-
-1. The old VIDIOC_*_OLD symbols and V4L1 support were removed.
-
-2. Multi-planar API added. Does not affect the compatibility of current
-   drivers and applications. See :ref:`multi-planar API <planar-apis>`
-   for details.
-
-
-V4L2 in Linux 3.1
-=================
-
-1. VIDIOC_QUERYCAP now returns a per-subsystem version instead of a
-   per-driver one.
-
-   Standardize an error code for invalid ioctl.
-
-   Added V4L2_CTRL_TYPE_BITMASK.
-
-
-V4L2 in Linux 3.2
-=================
-
-1. V4L2_CTRL_FLAG_VOLATILE was added to signal volatile controls to
-   userspace.
-
-2. Add selection API for extended control over cropping and composing.
-   Does not affect the compatibility of current drivers and
-   applications. See :ref:`selection API <selection-api>` for details.
-
-
-V4L2 in Linux 3.3
-=================
-
-1. Added ``V4L2_CID_ALPHA_COMPONENT`` control to the
-   :ref:`User controls class <control>`.
-
-2. Added the device_caps field to struct v4l2_capabilities and added
-   the new V4L2_CAP_DEVICE_CAPS capability.
-
-
-V4L2 in Linux 3.4
-=================
-
-1. Added :ref:`JPEG compression control class <jpeg-controls>`.
-
-2. Extended the DV Timings API:
-   :ref:`VIDIOC_ENUM_DV_TIMINGS`,
-   :ref:`VIDIOC_QUERY_DV_TIMINGS` and
-   :ref:`VIDIOC_DV_TIMINGS_CAP`.
-
-
-V4L2 in Linux 3.5
-=================
-
-1. Added integer menus, the new type will be
-   V4L2_CTRL_TYPE_INTEGER_MENU.
-
-2. Added selection API for V4L2 subdev interface:
-   :ref:`VIDIOC_SUBDEV_G_SELECTION` and
-   :ref:`VIDIOC_SUBDEV_S_SELECTION <VIDIOC_SUBDEV_G_SELECTION>`.
-
-3. Added ``V4L2_COLORFX_ANTIQUE``, ``V4L2_COLORFX_ART_FREEZE``,
-   ``V4L2_COLORFX_AQUA``, ``V4L2_COLORFX_SILHOUETTE``,
-   ``V4L2_COLORFX_SOLARIZATION``, ``V4L2_COLORFX_VIVID`` and
-   ``V4L2_COLORFX_ARBITRARY_CBCR`` menu items to the
-   ``V4L2_CID_COLORFX`` control.
-
-4. Added ``V4L2_CID_COLORFX_CBCR`` control.
-
-5. Added camera controls ``V4L2_CID_AUTO_EXPOSURE_BIAS``,
-   ``V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE``,
-   ``V4L2_CID_IMAGE_STABILIZATION``, ``V4L2_CID_ISO_SENSITIVITY``,
-   ``V4L2_CID_ISO_SENSITIVITY_AUTO``, ``V4L2_CID_EXPOSURE_METERING``,
-   ``V4L2_CID_SCENE_MODE``, ``V4L2_CID_3A_LOCK``,
-   ``V4L2_CID_AUTO_FOCUS_START``, ``V4L2_CID_AUTO_FOCUS_STOP``,
-   ``V4L2_CID_AUTO_FOCUS_STATUS`` and ``V4L2_CID_AUTO_FOCUS_RANGE``.
-
-
-V4L2 in Linux 3.6
-=================
-
-1. Replaced ``input`` in struct :c:type:`v4l2_buffer` by
-   ``reserved2`` and removed ``V4L2_BUF_FLAG_INPUT``.
-
-2. Added V4L2_CAP_VIDEO_M2M and V4L2_CAP_VIDEO_M2M_MPLANE
-   capabilities.
-
-3. Added support for frequency band enumerations:
-   :ref:`VIDIOC_ENUM_FREQ_BANDS`.
-
-
-V4L2 in Linux 3.9
-=================
-
-1. Added timestamp types to ``flags`` field in
-   struct :c:type:`v4l2_buffer`. See :ref:`buffer-flags`.
-
-2. Added ``V4L2_EVENT_CTRL_CH_RANGE`` control event changes flag. See
-   :ref:`ctrl-changes-flags`.
-
-
-V4L2 in Linux 3.10
-==================
-
-1. Removed obsolete and unused DV_PRESET ioctls VIDIOC_G_DV_PRESET,
-   VIDIOC_S_DV_PRESET, VIDIOC_QUERY_DV_PRESET and
-   VIDIOC_ENUM_DV_PRESET. Remove the related v4l2_input/output
-   capability flags V4L2_IN_CAP_PRESETS and V4L2_OUT_CAP_PRESETS.
-
-2. Added new debugging ioctl
-   :ref:`VIDIOC_DBG_G_CHIP_INFO`.
-
-
-V4L2 in Linux 3.11
-==================
-
-1. Remove obsolete ``VIDIOC_DBG_G_CHIP_IDENT`` ioctl.
-
-
-V4L2 in Linux 3.14
-==================
-
-1. In struct :c:type:`v4l2_rect`, the type of ``width`` and
-   ``height`` fields changed from _s32 to _u32.
-
-
-V4L2 in Linux 3.15
-==================
-
-1. Added Software Defined Radio (SDR) Interface.
-
-
-V4L2 in Linux 3.16
-==================
-
-1. Added event V4L2_EVENT_SOURCE_CHANGE.
-
-
-V4L2 in Linux 3.17
-==================
-
-1. Extended struct :c:type:`v4l2_pix_format`. Added
-   format flags.
-
-2. Added compound control types and
-   :ref:`VIDIOC_QUERY_EXT_CTRL <VIDIOC_QUERYCTRL>`.
-
-
-V4L2 in Linux 3.18
-==================
-
-1. Added ``V4L2_CID_PAN_SPEED`` and ``V4L2_CID_TILT_SPEED`` camera
-   controls.
-
-
-V4L2 in Linux 3.19
-==================
-
-1. Rewrote Colorspace chapter, added new enum
-   :c:type:`v4l2_ycbcr_encoding` and enum
-   :c:type:`v4l2_quantization` fields to struct
-   :c:type:`v4l2_pix_format`, struct
-   :c:type:`v4l2_pix_format_mplane` and
-   struct :c:type:`v4l2_mbus_framefmt`.
-
-
-V4L2 in Linux 4.4
-=================
-
-1. Renamed ``V4L2_TUNER_ADC`` to ``V4L2_TUNER_SDR``. The use of
-   ``V4L2_TUNER_ADC`` is deprecated now.
-
-2. Added ``V4L2_CID_RF_TUNER_RF_GAIN`` RF Tuner control.
-
-3. Added transmitter support for Software Defined Radio (SDR) Interface.
-
-
-.. _other:
-
-Relation of V4L2 to other Linux multimedia APIs
-===============================================
-
-
-.. _xvideo:
-
-X Video Extension
------------------
-
-The X Video Extension (abbreviated XVideo or just Xv) is an extension of
-the X Window system, implemented for example by the XFree86 project. Its
-scope is similar to V4L2, an API to video capture and output devices for
-X clients. Xv allows applications to display live video in a window,
-send window contents to a TV output, and capture or output still images
-in XPixmaps [#f1]_. With their implementation XFree86 makes the extension
-available across many operating systems and architectures.
-
-Because the driver is embedded into the X server Xv has a number of
-advantages over the V4L2 :ref:`video overlay interface <overlay>`. The
-driver can easily determine the overlay target, i. e. visible graphics
-memory or off-screen buffers for a destructive overlay. It can program
-the RAMDAC for a non-destructive overlay, scaling or color-keying, or
-the clipping functions of the video capture hardware, always in sync
-with drawing operations or windows moving or changing their stacking
-order.
-
-To combine the advantages of Xv and V4L a special Xv driver exists in
-XFree86 and XOrg, just programming any overlay capable Video4Linux
-device it finds. To enable it ``/etc/X11/XF86Config`` must contain these
-lines:
-
-::
-
-    Section "Module"
-	Load "v4l"
-    EndSection
-
-As of XFree86 4.2 this driver still supports only V4L ioctls, however it
-should work just fine with all V4L2 devices through the V4L2
-backward-compatibility layer. Since V4L2 permits multiple opens it is
-possible (if supported by the V4L2 driver) to capture video while an X
-client requested video overlay. Restrictions of simultaneous capturing
-and overlay are discussed in :ref:`overlay` apply.
-
-Only marginally related to V4L2, XFree86 extended Xv to support hardware
-YUV to RGB conversion and scaling for faster video playback, and added
-an interface to MPEG-2 decoding hardware. This API is useful to display
-images captured with V4L2 devices.
-
-
-Digital Video
--------------
-
-V4L2 does not support digital terrestrial, cable or satellite broadcast.
-A separate project aiming at digital receivers exists. You can find its
-homepage at `https://linuxtv.org <https://linuxtv.org>`__. The Linux
-DVB API has no connection to the V4L2 API except that drivers for hybrid
-hardware may support both.
-
-
-Audio Interfaces
-----------------
-
-[to do - OSS/ALSA]
-
-
-.. _experimental:
-
-Experimental API Elements
-=========================
-
-The following V4L2 API elements are currently experimental and may
-change in the future.
-
--  :ref:`VIDIOC_DBG_G_REGISTER` and
-   :ref:`VIDIOC_DBG_S_REGISTER <VIDIOC_DBG_G_REGISTER>` ioctls.
-
--  :ref:`VIDIOC_DBG_G_CHIP_INFO` ioctl.
-
-
-.. _obsolete:
-
-Obsolete API Elements
-=====================
-
-The following V4L2 API elements were superseded by new interfaces and
-should not be implemented in new drivers.
-
--  ``VIDIOC_G_MPEGCOMP`` and ``VIDIOC_S_MPEGCOMP`` ioctls. Use Extended
-   Controls, :ref:`extended-controls`.
-
--  VIDIOC_G_DV_PRESET, VIDIOC_S_DV_PRESET,
-   VIDIOC_ENUM_DV_PRESETS and VIDIOC_QUERY_DV_PRESET ioctls. Use
-   the DV Timings API (:ref:`dv-timings`).
-
--  ``VIDIOC_SUBDEV_G_CROP`` and ``VIDIOC_SUBDEV_S_CROP`` ioctls. Use
-   ``VIDIOC_SUBDEV_G_SELECTION`` and ``VIDIOC_SUBDEV_S_SELECTION``,
-   :ref:`VIDIOC_SUBDEV_G_SELECTION`.
-
-.. [#f1]
-   This is not implemented in XFree86.
diff --git a/Documentation/media/uapi/v4l/hsv-formats.rst b/Documentation/media/uapi/v4l/hsv-formats.rst
deleted file mode 100644
index f52f8ba131f0..000000000000
--- a/Documentation/media/uapi/v4l/hsv-formats.rst
+++ /dev/null
@@ -1,26 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _hsv-formats:
-
-***********
-HSV Formats
-***********
-
-These formats store the color information of the image
-in a geometrical representation. The colors are mapped into a
-cylinder, where the angle is the HUE, the height is the VALUE
-and the distance to the center is the SATURATION. This is a very
-useful format for image segmentation algorithms.
-
-
-.. toctree::
-    :maxdepth: 1
-
-    pixfmt-packed-hsv
diff --git a/Documentation/media/uapi/v4l/io.rst b/Documentation/media/uapi/v4l/io.rst
deleted file mode 100644
index 049a2530d3a2..000000000000
--- a/Documentation/media/uapi/v4l/io.rst
+++ /dev/null
@@ -1,58 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _io:
-
-############
-Input/Output
-############
-The V4L2 API defines several different methods to read from or write to
-a device. All drivers exchanging data with applications must support at
-least one of them.
-
-The classic I/O method using the :ref:`read() <func-read>` and
-:ref:`write() <func-write>` function is automatically selected after opening a
-V4L2 device. When the driver does not support this method attempts to
-read or write will fail at any time.
-
-Other methods must be negotiated. To select the streaming I/O method
-with memory mapped or user buffers applications call the
-:ref:`VIDIOC_REQBUFS` ioctl. The asynchronous I/O
-method is not defined yet.
-
-Video overlay can be considered another I/O method, although the
-application does not directly receive the image data. It is selected by
-initiating video overlay with the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`
-ioctl. For more information see :ref:`overlay`.
-
-Generally exactly one I/O method, including overlay, is associated with
-each file descriptor. The only exceptions are applications not
-exchanging data with a driver ("panel applications", see :ref:`open`)
-and drivers permitting simultaneous video capturing and overlay using
-the same file descriptor, for compatibility with V4L and earlier
-versions of V4L2.
-
-:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` and :ref:`VIDIOC_REQBUFS` would permit this to some
-degree, but for simplicity drivers need not support switching the I/O
-method (after first switching away from read/write) other than by
-closing and reopening the device.
-
-The following sections describe the various I/O methods in more detail.
-
-
-.. toctree::
-    :maxdepth: 1
-
-    rw
-    mmap
-    userp
-    dmabuf
-    async
-    buffer
-    field-order
diff --git a/Documentation/media/uapi/v4l/libv4l-introduction.rst b/Documentation/media/uapi/v4l/libv4l-introduction.rst
deleted file mode 100644
index 1b206d380d4b..000000000000
--- a/Documentation/media/uapi/v4l/libv4l-introduction.rst
+++ /dev/null
@@ -1,191 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _libv4l-introduction:
-
-************
-Introduction
-************
-
-libv4l is a collection of libraries which adds a thin abstraction layer
-on top of video4linux2 devices. The purpose of this (thin) layer is to
-make it easy for application writers to support a wide variety of
-devices without having to write separate code for different devices in
-the same class.
-
-An example of using libv4l is provided by
-:ref:`v4l2grab <v4l2grab-example>`.
-
-libv4l consists of 3 different libraries:
-
-
-libv4lconvert
-=============
-
-libv4lconvert is a library that converts several different pixelformats
-found in V4L2 drivers into a few common RGB and YUY formats.
-
-It currently accepts the following V4L2 driver formats:
-:ref:`V4L2_PIX_FMT_BGR24 <V4L2-PIX-FMT-BGR24>`,
-:ref:`V4L2_PIX_FMT_HM12 <V4L2-PIX-FMT-HM12>`,
-:ref:`V4L2_PIX_FMT_JPEG <V4L2-PIX-FMT-JPEG>`,
-:ref:`V4L2_PIX_FMT_MJPEG <V4L2-PIX-FMT-MJPEG>`,
-:ref:`V4L2_PIX_FMT_MR97310A <V4L2-PIX-FMT-MR97310A>`,
-:ref:`V4L2_PIX_FMT_OV511 <V4L2-PIX-FMT-OV511>`,
-:ref:`V4L2_PIX_FMT_OV518 <V4L2-PIX-FMT-OV518>`,
-:ref:`V4L2_PIX_FMT_PAC207 <V4L2-PIX-FMT-PAC207>`,
-:ref:`V4L2_PIX_FMT_PJPG <V4L2-PIX-FMT-PJPG>`,
-:ref:`V4L2_PIX_FMT_RGB24 <V4L2-PIX-FMT-RGB24>`,
-:ref:`V4L2_PIX_FMT_SBGGR8 <V4L2-PIX-FMT-SBGGR8>`,
-:ref:`V4L2_PIX_FMT_SGBRG8 <V4L2-PIX-FMT-SGBRG8>`,
-:ref:`V4L2_PIX_FMT_SGRBG8 <V4L2-PIX-FMT-SGRBG8>`,
-:ref:`V4L2_PIX_FMT_SN9C10X <V4L2-PIX-FMT-SN9C10X>`,
-:ref:`V4L2_PIX_FMT_SN9C20X_I420 <V4L2-PIX-FMT-SN9C20X-I420>`,
-:ref:`V4L2_PIX_FMT_SPCA501 <V4L2-PIX-FMT-SPCA501>`,
-:ref:`V4L2_PIX_FMT_SPCA505 <V4L2-PIX-FMT-SPCA505>`,
-:ref:`V4L2_PIX_FMT_SPCA508 <V4L2-PIX-FMT-SPCA508>`,
-:ref:`V4L2_PIX_FMT_SPCA561 <V4L2-PIX-FMT-SPCA561>`,
-:ref:`V4L2_PIX_FMT_SQ905C <V4L2-PIX-FMT-SQ905C>`,
-:ref:`V4L2_PIX_FMT_SRGGB8 <V4L2-PIX-FMT-SRGGB8>`,
-:ref:`V4L2_PIX_FMT_UYVY <V4L2-PIX-FMT-UYVY>`,
-:ref:`V4L2_PIX_FMT_YUV420 <V4L2-PIX-FMT-YUV420>`,
-:ref:`V4L2_PIX_FMT_YUYV <V4L2-PIX-FMT-YUYV>`,
-:ref:`V4L2_PIX_FMT_YVU420 <V4L2-PIX-FMT-YVU420>`, and
-:ref:`V4L2_PIX_FMT_YVYU <V4L2-PIX-FMT-YVYU>`.
-
-Later on libv4lconvert was expanded to also be able to do various video
-processing functions to improve webcam video quality. The video
-processing is split in to 2 parts: libv4lconvert/control and
-libv4lconvert/processing.
-
-The control part is used to offer video controls which can be used to
-control the video processing functions made available by
-libv4lconvert/processing. These controls are stored application wide
-(until reboot) by using a persistent shared memory object.
-
-libv4lconvert/processing offers the actual video processing
-functionality.
-
-
-libv4l1
-=======
-
-This library offers functions that can be used to quickly make v4l1
-applications work with v4l2 devices. These functions work exactly like
-the normal open/close/etc, except that libv4l1 does full emulation of
-the v4l1 api on top of v4l2 drivers, in case of v4l1 drivers it will
-just pass calls through.
-
-Since those functions are emulations of the old V4L1 API, it shouldn't
-be used for new applications.
-
-
-libv4l2
-=======
-
-This library should be used for all modern V4L2 applications.
-
-It provides handles to call V4L2 open/ioctl/close/poll methods. Instead
-of just providing the raw output of the device, it enhances the calls in
-the sense that it will use libv4lconvert to provide more video formats
-and to enhance the image quality.
-
-In most cases, libv4l2 just passes the calls directly through to the
-v4l2 driver, intercepting the calls to
-:ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>`,
-:ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>`,
-:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`,
-:ref:`VIDIOC_ENUM_FRAMESIZES <VIDIOC_ENUM_FRAMESIZES>` and
-:ref:`VIDIOC_ENUM_FRAMEINTERVALS <VIDIOC_ENUM_FRAMEINTERVALS>` in
-order to emulate the formats
-:ref:`V4L2_PIX_FMT_BGR24 <V4L2-PIX-FMT-BGR24>`,
-:ref:`V4L2_PIX_FMT_RGB24 <V4L2-PIX-FMT-RGB24>`,
-:ref:`V4L2_PIX_FMT_YUV420 <V4L2-PIX-FMT-YUV420>`, and
-:ref:`V4L2_PIX_FMT_YVU420 <V4L2-PIX-FMT-YVU420>`, if they aren't
-available in the driver. :ref:`VIDIOC_ENUM_FMT <VIDIOC_ENUM_FMT>`
-keeps enumerating the hardware supported formats, plus the emulated
-formats offered by libv4l at the end.
-
-
-.. _libv4l-ops:
-
-Libv4l device control functions
--------------------------------
-
-The common file operation methods are provided by libv4l.
-
-Those functions operate just like the gcc function ``dup()`` and
-V4L2 functions
-:c:func:`open() <v4l2-open>`, :c:func:`close() <v4l2-close>`,
-:c:func:`ioctl() <v4l2-ioctl>`, :c:func:`read() <v4l2-read>`,
-:c:func:`mmap() <v4l2-mmap>` and :c:func:`munmap() <v4l2-munmap>`:
-
-.. c:function:: int v4l2_open(const char *file, int oflag, ...)
-
-   operates like the :c:func:`open() <v4l2-open>` function.
-
-.. c:function:: int v4l2_close(int fd)
-
-   operates like the :c:func:`close() <v4l2-close>` function.
-
-.. c:function:: int v4l2_dup(int fd)
-
-   operates like the libc ``dup()`` function, duplicating a file handler.
-
-.. c:function:: int v4l2_ioctl (int fd, unsigned long int request, ...)
-
-   operates like the :c:func:`ioctl() <v4l2-ioctl>` function.
-
-.. c:function:: int v4l2_read (int fd, void* buffer, size_t n)
-
-   operates like the :c:func:`read() <v4l2-read>` function.
-
-.. c:function:: void v4l2_mmap(void *start, size_t length, int prot, int flags, int fd, int64_t offset);
-
-   operates like the :c:func:`munmap() <v4l2-munmap>` function.
-
-.. c:function:: int v4l2_munmap(void *_start, size_t length);
-
-   operates like the :c:func:`munmap() <v4l2-munmap>` function.
-
-Those functions provide additional control:
-
-.. c:function:: int v4l2_fd_open(int fd, int v4l2_flags)
-
-   opens an already opened fd for further use through v4l2lib and possibly
-   modify libv4l2's default behavior through the ``v4l2_flags`` argument.
-   Currently, ``v4l2_flags`` can be ``V4L2_DISABLE_CONVERSION``, to disable
-   format conversion.
-
-.. c:function:: int v4l2_set_control(int fd, int cid, int value)
-
-   This function takes a value of 0 - 65535, and then scales that range to the
-   actual range of the given v4l control id, and then if the cid exists and is
-   not locked sets the cid to the scaled value.
-
-.. c:function:: int v4l2_get_control(int fd, int cid)
-
-   This function returns a value of 0 - 65535, scaled to from the actual range
-   of the given v4l control id. when the cid does not exist, could not be
-   accessed for some reason, or some error occurred 0 is returned.
-
-
-v4l1compat.so wrapper library
-=============================
-
-This library intercepts calls to
-:c:func:`open() <v4l2-open>`, :c:func:`close() <v4l2-close>`,
-:c:func:`ioctl() <v4l2-ioctl>`, :c:func:`mmap() <v4l2-mmap>` and
-:c:func:`munmap() <v4l2-munmap>`
-operations and redirects them to the libv4l counterparts, by using
-``LD_PRELOAD=/usr/lib/v4l1compat.so``. It also emulates V4L1 calls via V4L2
-API.
-
-It allows usage of binary legacy applications that still don't use
-libv4l.
diff --git a/Documentation/media/uapi/v4l/libv4l.rst b/Documentation/media/uapi/v4l/libv4l.rst
deleted file mode 100644
index d114fbf1ffa6..000000000000
--- a/Documentation/media/uapi/v4l/libv4l.rst
+++ /dev/null
@@ -1,20 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _libv4l:
-
-************************
-Libv4l Userspace Library
-************************
-
-
-.. toctree::
-    :maxdepth: 1
-
-    libv4l-introduction
diff --git a/Documentation/media/uapi/v4l/meta-formats.rst b/Documentation/media/uapi/v4l/meta-formats.rst
deleted file mode 100644
index 74c8659ee9d6..000000000000
--- a/Documentation/media/uapi/v4l/meta-formats.rst
+++ /dev/null
@@ -1,27 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _meta-formats:
-
-****************
-Metadata Formats
-****************
-
-These formats are used for the :ref:`metadata` interface only.
-
-
-.. toctree::
-    :maxdepth: 1
-
-    pixfmt-meta-d4xx
-    pixfmt-meta-intel-ipu3
-    pixfmt-meta-uvc
-    pixfmt-meta-vsp1-hgo
-    pixfmt-meta-vsp1-hgt
-    pixfmt-meta-vivid
diff --git a/Documentation/media/uapi/v4l/mmap.rst b/Documentation/media/uapi/v4l/mmap.rst
deleted file mode 100644
index c47708bf2c87..000000000000
--- a/Documentation/media/uapi/v4l/mmap.rst
+++ /dev/null
@@ -1,292 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _mmap:
-
-******************************
-Streaming I/O (Memory Mapping)
-******************************
-
-Input and output devices support this I/O method when the
-``V4L2_CAP_STREAMING`` flag in the ``capabilities`` field of struct
-:c:type:`v4l2_capability` returned by the
-:ref:`VIDIOC_QUERYCAP` ioctl is set. There are two
-streaming methods, to determine if the memory mapping flavor is
-supported applications must call the :ref:`VIDIOC_REQBUFS` ioctl
-with the memory type set to ``V4L2_MEMORY_MMAP``.
-
-Streaming is an I/O method where only pointers to buffers are exchanged
-between application and driver, the data itself is not copied. Memory
-mapping is primarily intended to map buffers in device memory into the
-application's address space. Device memory can be for example the video
-memory on a graphics card with a video capture add-on. However, being
-the most efficient I/O method available for a long time, many other
-drivers support streaming as well, allocating buffers in DMA-able main
-memory.
-
-A driver can support many sets of buffers. Each set is identified by a
-unique buffer type value. The sets are independent and each set can hold
-a different type of data. To access different sets at the same time
-different file descriptors must be used. [#f1]_
-
-To allocate device buffers applications call the
-:ref:`VIDIOC_REQBUFS` ioctl with the desired number
-of buffers and buffer type, for example ``V4L2_BUF_TYPE_VIDEO_CAPTURE``.
-This ioctl can also be used to change the number of buffers or to free
-the allocated memory, provided none of the buffers are still mapped.
-
-Before applications can access the buffers they must map them into their
-address space with the :ref:`mmap() <func-mmap>` function. The
-location of the buffers in device memory can be determined with the
-:ref:`VIDIOC_QUERYBUF` ioctl. In the single-planar
-API case, the ``m.offset`` and ``length`` returned in a struct
-:c:type:`v4l2_buffer` are passed as sixth and second
-parameter to the :ref:`mmap() <func-mmap>` function. When using the
-multi-planar API, struct :c:type:`v4l2_buffer` contains an
-array of struct :c:type:`v4l2_plane` structures, each
-containing its own ``m.offset`` and ``length``. When using the
-multi-planar API, every plane of every buffer has to be mapped
-separately, so the number of calls to :ref:`mmap() <func-mmap>` should
-be equal to number of buffers times number of planes in each buffer. The
-offset and length values must not be modified. Remember, the buffers are
-allocated in physical memory, as opposed to virtual memory, which can be
-swapped out to disk. Applications should free the buffers as soon as
-possible with the :ref:`munmap() <func-munmap>` function.
-
-Example: Mapping buffers in the single-planar API
-=================================================
-
-.. code-block:: c
-
-    struct v4l2_requestbuffers reqbuf;
-    struct {
-	void *start;
-	size_t length;
-    } *buffers;
-    unsigned int i;
-
-    memset(&reqbuf, 0, sizeof(reqbuf));
-    reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-    reqbuf.memory = V4L2_MEMORY_MMAP;
-    reqbuf.count = 20;
-
-    if (-1 == ioctl (fd, VIDIOC_REQBUFS, &reqbuf)) {
-	if (errno == EINVAL)
-	    printf("Video capturing or mmap-streaming is not supported\\n");
-	else
-	    perror("VIDIOC_REQBUFS");
-
-	exit(EXIT_FAILURE);
-    }
-
-    /* We want at least five buffers. */
-
-    if (reqbuf.count < 5) {
-	/* You may need to free the buffers here. */
-	printf("Not enough buffer memory\\n");
-	exit(EXIT_FAILURE);
-    }
-
-    buffers = calloc(reqbuf.count, sizeof(*buffers));
-    assert(buffers != NULL);
-
-    for (i = 0; i < reqbuf.count; i++) {
-	struct v4l2_buffer buffer;
-
-	memset(&buffer, 0, sizeof(buffer));
-	buffer.type = reqbuf.type;
-	buffer.memory = V4L2_MEMORY_MMAP;
-	buffer.index = i;
-
-	if (-1 == ioctl (fd, VIDIOC_QUERYBUF, &buffer)) {
-	    perror("VIDIOC_QUERYBUF");
-	    exit(EXIT_FAILURE);
-	}
-
-	buffers[i].length = buffer.length; /* remember for munmap() */
-
-	buffers[i].start = mmap(NULL, buffer.length,
-		    PROT_READ | PROT_WRITE, /* recommended */
-		    MAP_SHARED,             /* recommended */
-		    fd, buffer.m.offset);
-
-	if (MAP_FAILED == buffers[i].start) {
-	    /* If you do not exit here you should unmap() and free()
-	       the buffers mapped so far. */
-	    perror("mmap");
-	    exit(EXIT_FAILURE);
-	}
-    }
-
-    /* Cleanup. */
-
-    for (i = 0; i < reqbuf.count; i++)
-	munmap(buffers[i].start, buffers[i].length);
-
-
-Example: Mapping buffers in the multi-planar API
-================================================
-
-.. code-block:: c
-
-    struct v4l2_requestbuffers reqbuf;
-    /* Our current format uses 3 planes per buffer */
-    #define FMT_NUM_PLANES = 3
-
-    struct {
-	void *start[FMT_NUM_PLANES];
-	size_t length[FMT_NUM_PLANES];
-    } *buffers;
-    unsigned int i, j;
-
-    memset(&reqbuf, 0, sizeof(reqbuf));
-    reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-    reqbuf.memory = V4L2_MEMORY_MMAP;
-    reqbuf.count = 20;
-
-    if (ioctl(fd, VIDIOC_REQBUFS, &reqbuf) < 0) {
-	if (errno == EINVAL)
-	    printf("Video capturing or mmap-streaming is not supported\\n");
-	else
-	    perror("VIDIOC_REQBUFS");
-
-	exit(EXIT_FAILURE);
-    }
-
-    /* We want at least five buffers. */
-
-    if (reqbuf.count < 5) {
-	/* You may need to free the buffers here. */
-	printf("Not enough buffer memory\\n");
-	exit(EXIT_FAILURE);
-    }
-
-    buffers = calloc(reqbuf.count, sizeof(*buffers));
-    assert(buffers != NULL);
-
-    for (i = 0; i < reqbuf.count; i++) {
-	struct v4l2_buffer buffer;
-	struct v4l2_plane planes[FMT_NUM_PLANES];
-
-	memset(&buffer, 0, sizeof(buffer));
-	buffer.type = reqbuf.type;
-	buffer.memory = V4L2_MEMORY_MMAP;
-	buffer.index = i;
-	/* length in struct v4l2_buffer in multi-planar API stores the size
-	 * of planes array. */
-	buffer.length = FMT_NUM_PLANES;
-	buffer.m.planes = planes;
-
-	if (ioctl(fd, VIDIOC_QUERYBUF, &buffer) < 0) {
-	    perror("VIDIOC_QUERYBUF");
-	    exit(EXIT_FAILURE);
-	}
-
-	/* Every plane has to be mapped separately */
-	for (j = 0; j < FMT_NUM_PLANES; j++) {
-	    buffers[i].length[j] = buffer.m.planes[j].length; /* remember for munmap() */
-
-	    buffers[i].start[j] = mmap(NULL, buffer.m.planes[j].length,
-		     PROT_READ | PROT_WRITE, /* recommended */
-		     MAP_SHARED,             /* recommended */
-		     fd, buffer.m.planes[j].m.offset);
-
-	    if (MAP_FAILED == buffers[i].start[j]) {
-		/* If you do not exit here you should unmap() and free()
-		   the buffers and planes mapped so far. */
-		perror("mmap");
-		exit(EXIT_FAILURE);
-	    }
-	}
-    }
-
-    /* Cleanup. */
-
-    for (i = 0; i < reqbuf.count; i++)
-	for (j = 0; j < FMT_NUM_PLANES; j++)
-	    munmap(buffers[i].start[j], buffers[i].length[j]);
-
-Conceptually streaming drivers maintain two buffer queues, an incoming
-and an outgoing queue. They separate the synchronous capture or output
-operation locked to a video clock from the application which is subject
-to random disk or network delays and preemption by other processes,
-thereby reducing the probability of data loss. The queues are organized
-as FIFOs, buffers will be output in the order enqueued in the incoming
-FIFO, and were captured in the order dequeued from the outgoing FIFO.
-
-The driver may require a minimum number of buffers enqueued at all times
-to function, apart of this no limit exists on the number of buffers
-applications can enqueue in advance, or dequeue and process. They can
-also enqueue in a different order than buffers have been dequeued, and
-the driver can *fill* enqueued *empty* buffers in any order.  [#f2]_ The
-index number of a buffer (struct :c:type:`v4l2_buffer`
-``index``) plays no role here, it only identifies the buffer.
-
-Initially all mapped buffers are in dequeued state, inaccessible by the
-driver. For capturing applications it is customary to first enqueue all
-mapped buffers, then to start capturing and enter the read loop. Here
-the application waits until a filled buffer can be dequeued, and
-re-enqueues the buffer when the data is no longer needed. Output
-applications fill and enqueue buffers, when enough buffers are stacked
-up the output is started with :ref:`VIDIOC_STREAMON <VIDIOC_STREAMON>`.
-In the write loop, when the application runs out of free buffers, it
-must wait until an empty buffer can be dequeued and reused.
-
-To enqueue and dequeue a buffer applications use the
-:ref:`VIVIOC_QBUF <VIDIOC_QBUF>` and :ref:`VIDIOC_DQBUF <VIDIOC_QBUF>`
-ioctl. The status of a buffer being mapped, enqueued, full or empty can
-be determined at any time using the :ref:`VIDIOC_QUERYBUF` ioctl. Two
-methods exist to suspend execution of the application until one or more
-buffers can be dequeued.  By default :ref:`VIDIOC_DQBUF <VIDIOC_QBUF>`
-blocks when no buffer is in the outgoing queue. When the ``O_NONBLOCK``
-flag was given to the :ref:`open() <func-open>` function,
-:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` returns immediately with an ``EAGAIN``
-error code when no buffer is available. The :ref:`select() <func-select>`
-or :ref:`poll() <func-poll>` functions are always available.
-
-To start and stop capturing or output applications call the
-:ref:`VIDIOC_STREAMON <VIDIOC_STREAMON>` and :ref:`VIDIOC_STREAMOFF
-<VIDIOC_STREAMON>` ioctl.
-
-.. note:::ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>`
-   removes all buffers from both queues as a side effect. Since there is
-   no notion of doing anything "now" on a multitasking system, if an
-   application needs to synchronize with another event it should examine
-   the struct ::c:type:`v4l2_buffer` ``timestamp`` of captured
-   or outputted buffers.
-
-Drivers implementing memory mapping I/O must support the
-:ref:`VIDIOC_REQBUFS <VIDIOC_REQBUFS>`, :ref:`VIDIOC_QUERYBUF
-<VIDIOC_QUERYBUF>`, :ref:`VIDIOC_QBUF <VIDIOC_QBUF>`, :ref:`VIDIOC_DQBUF
-<VIDIOC_QBUF>`, :ref:`VIDIOC_STREAMON <VIDIOC_STREAMON>`
-and :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` ioctls, the :ref:`mmap()
-<func-mmap>`, :ref:`munmap() <func-munmap>`, :ref:`select()
-<func-select>` and :ref:`poll() <func-poll>` function. [#f3]_
-
-[capture example]
-
-.. [#f1]
-   One could use one file descriptor and set the buffer type field
-   accordingly when calling :ref:`VIDIOC_QBUF` etc.,
-   but it makes the :ref:`select() <func-select>` function ambiguous. We also
-   like the clean approach of one file descriptor per logical stream.
-   Video overlay for example is also a logical stream, although the CPU
-   is not needed for continuous operation.
-
-.. [#f2]
-   Random enqueue order permits applications processing images out of
-   order (such as video codecs) to return buffers earlier, reducing the
-   probability of data loss. Random fill order allows drivers to reuse
-   buffers on a LIFO-basis, taking advantage of caches holding
-   scatter-gather lists and the like.
-
-.. [#f3]
-   At the driver level :ref:`select() <func-select>` and :ref:`poll() <func-poll>` are
-   the same, and :ref:`select() <func-select>` is too important to be optional.
-   The rest should be evident.
diff --git a/Documentation/media/uapi/v4l/nv12mt.svg b/Documentation/media/uapi/v4l/nv12mt.svg
deleted file mode 100644
index 067d8fb34ba2..000000000000
--- a/Documentation/media/uapi/v4l/nv12mt.svg
+++ /dev/null
@@ -1,477 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!--
-    This file is dual-licensed: you can use it either under the terms
-    of the GPL 2.0 or the GFDL 1.1+ license, at your option. Note that this
-    dual licensing only applies to this file, and not this project as a
-    whole.
-
-    a) This file is free software; you can redistribute it and/or
-       modify it under the terms of the GNU General Public License as
-       published by the Free Software Foundation version 2 of
-       the License.
-
-       This file is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-    Or, alternatively,
-
-    b) Permission is granted to copy, distribute and/or modify this
-       document under the terms of the GNU Free Documentation License,
-       Version 1.1 or any later version published by the Free Software
-       Foundation, with no Invariant Sections, no Front-Cover Texts
-       and no Back-Cover Texts. A copy of the license is included at
-       Documentation/media/uapi/fdl-appendix.rst.
-
-    TODO: replace it to GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
--->
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   version="1.2"
-   width="96.282211mm"
-   height="28.282219mm"
-   viewBox="0 0 9628.2211 2828.2219"
-   preserveAspectRatio="xMidYMid"
-   xml:space="preserve"
-   id="svg2"
-   inkscape:version="0.91 r13725"
-   sodipodi:docname="nv12mt.svg"
-   style="fill-rule:evenodd;stroke-width:28.22200012;stroke-linejoin:round"><metadata
-     id="metadata383"><rdf:RDF><cc:Work
-	 rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
-	   rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="1920"
-     inkscape:window-height="997"
-     id="namedview381"
-     showgrid="false"
-     fit-margin-top="0"
-     fit-margin-left="0"
-     fit-margin-right="0"
-     fit-margin-bottom="0"
-     inkscape:zoom="4.0919524"
-     inkscape:cx="170.57872"
-     inkscape:cy="50.106293"
-     inkscape:window-x="1920"
-     inkscape:window-y="30"
-     inkscape:window-maximized="1"
-     inkscape:current-layer="svg2" /><defs
-     class="ClipPathGroup"
-     id="defs4"><clipPath
-       id="presentation_clip_path"
-       clipPathUnits="userSpaceOnUse"><rect
-	 x="0"
-	 y="0"
-	 width="28000"
-	 height="21000"
-	 id="rect7" /></clipPath></defs><defs
-     id="defs9" /><defs
-     id="defs80" /><defs
-     id="defs103" /><defs
-     class="TextShapeIndex"
-     id="defs114" /><defs
-     class="EmbeddedBulletChars"
-     id="defs118" /><defs
-     class="TextEmbeddedBitmaps"
-     id="defs147" /><g
-     class="SlideGroup"
-     id="g177"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="g179"><g
-	 id="id1"
-	 class="Slide"
-	 clip-path="url(#presentation_clip_path)"><g
-	   class="Page"
-	   id="g182"><g
-	     class="com.sun.star.drawing.CustomShape"
-	     id="g184"><g
-	       id="id6"><rect
-		 class="BoundingBox"
-		 x="3299"
-		 y="3199"
-		 width="2403"
-		 height="1403"
-		 id="rect187"
-		 style="fill:none;stroke:none" /><path
-		 d="m 4500,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-		 id="path189"
-		 inkscape:connector-curvature="0"
-		 style="fill:none;stroke:#3465a4" /><text
-		 class="TextShape"
-		 id="text191"><tspan
-		   class="TextParagraph"
-		   font-size="635px"
-		   font-weight="400"
-		   id="tspan193"
-		   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
-		     class="TextPosition"
-		     x="4325"
-		     y="4121"
-		     id="tspan195"><tspan
-		       id="tspan197"
-		       style="fill:#000000;stroke:none">0</tspan></tspan></tspan></text>
-</g></g><g
-	     class="com.sun.star.drawing.CustomShape"
-	     id="g199"><g
-	       id="id7"><rect
-		 class="BoundingBox"
-		 x="5699"
-		 y="3199"
-		 width="2403"
-		 height="1403"
-		 id="rect202"
-		 style="fill:none;stroke:none" /><path
-		 d="m 6900,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-		 id="path204"
-		 inkscape:connector-curvature="0"
-		 style="fill:none;stroke:#3465a4" /></g></g><g
-	     class="com.sun.star.drawing.CustomShape"
-	     id="g206"><g
-	       id="id8"><rect
-		 class="BoundingBox"
-		 x="8099"
-		 y="3199"
-		 width="2403"
-		 height="1403"
-		 id="rect209"
-		 style="fill:none;stroke:none" /><path
-		 d="m 9300,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-		 id="path211"
-		 inkscape:connector-curvature="0"
-		 style="fill:none;stroke:#3465a4" /><text
-		 class="TextShape"
-		 id="text213"><tspan
-		   class="TextParagraph"
-		   font-size="635px"
-		   font-weight="400"
-		   id="tspan215"
-		   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
-		     class="TextPosition"
-		     x="9125"
-		     y="4121"
-		     id="tspan217"><tspan
-		       id="tspan219"
-		       style="fill:#000000;stroke:none">6</tspan></tspan></tspan></text>
-</g></g><g
-	     class="com.sun.star.drawing.CustomShape"
-	     id="g221"><g
-	       id="id9"><rect
-		 class="BoundingBox"
-		 x="5699"
-		 y="3199"
-		 width="2403"
-		 height="1403"
-		 id="rect224"
-		 style="fill:none;stroke:none" /><path
-		 d="m 6900,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-		 id="path226"
-		 inkscape:connector-curvature="0"
-		 style="fill:none;stroke:#3465a4" /><text
-		 class="TextShape"
-		 id="text228"><tspan
-		   class="TextParagraph"
-		   font-size="635px"
-		   font-weight="400"
-		   id="tspan230"
-		   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
-		     class="TextPosition"
-		     x="6725"
-		     y="4121"
-		     id="tspan232"><tspan
-		       id="tspan234"
-		       style="fill:#000000;stroke:none">1</tspan></tspan></tspan></text>
-</g></g><g
-	     class="com.sun.star.drawing.CustomShape"
-	     id="g236"><g
-	       id="id10"><rect
-		 class="BoundingBox"
-		 x="10499"
-		 y="3199"
-		 width="2403"
-		 height="1403"
-		 id="rect239"
-		 style="fill:none;stroke:none" /><path
-		 d="m 11700,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-		 id="path241"
-		 inkscape:connector-curvature="0"
-		 style="fill:none;stroke:#3465a4" /><text
-		 class="TextShape"
-		 id="text243"><tspan
-		   class="TextParagraph"
-		   font-size="635px"
-		   font-weight="400"
-		   id="tspan245"
-		   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
-		     class="TextPosition"
-		     x="11525"
-		     y="4121"
-		     id="tspan247"><tspan
-		       id="tspan249"
-		       style="fill:#000000;stroke:none">7</tspan></tspan></tspan></text>
-</g></g><g
-	     class="com.sun.star.drawing.CustomShape"
-	     id="g251"><g
-	       id="id11"><rect
-		 class="BoundingBox"
-		 x="3299"
-		 y="4599"
-		 width="2403"
-		 height="1403"
-		 id="rect254"
-		 style="fill:none;stroke:none" /><path
-		 d="m 4500,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-		 id="path256"
-		 inkscape:connector-curvature="0"
-		 style="fill:none;stroke:#3465a4" /><text
-		 class="TextShape"
-		 id="text258"><tspan
-		   class="TextParagraph"
-		   font-size="635px"
-		   font-weight="400"
-		   id="tspan260"
-		   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
-		     class="TextPosition"
-		     x="4325"
-		     y="5521"
-		     id="tspan262"><tspan
-		       id="tspan264"
-		       style="fill:#000000;stroke:none">2</tspan></tspan></tspan></text>
-</g></g><g
-	     class="com.sun.star.drawing.CustomShape"
-	     id="g266"><g
-	       id="id12"><rect
-		 class="BoundingBox"
-		 x="5699"
-		 y="4599"
-		 width="2403"
-		 height="1403"
-		 id="rect269"
-		 style="fill:none;stroke:none" /><path
-		 d="m 6900,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-		 id="path271"
-		 inkscape:connector-curvature="0"
-		 style="fill:none;stroke:#3465a4" /></g></g><g
-	     class="com.sun.star.drawing.CustomShape"
-	     id="g273"><g
-	       id="id13"><rect
-		 class="BoundingBox"
-		 x="8099"
-		 y="4599"
-		 width="2403"
-		 height="1403"
-		 id="rect276"
-		 style="fill:none;stroke:none" /><path
-		 d="m 9300,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-		 id="path278"
-		 inkscape:connector-curvature="0"
-		 style="fill:none;stroke:#3465a4" /><text
-		 class="TextShape"
-		 id="text280"><tspan
-		   class="TextParagraph"
-		   font-size="635px"
-		   font-weight="400"
-		   id="tspan282"
-		   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
-		     class="TextPosition"
-		     x="9125"
-		     y="5521"
-		     id="tspan284"><tspan
-		       id="tspan286"
-		       style="fill:#000000;stroke:none">4</tspan></tspan></tspan></text>
-</g></g><g
-	     class="com.sun.star.drawing.CustomShape"
-	     id="g288"><g
-	       id="id14"><rect
-		 class="BoundingBox"
-		 x="5699"
-		 y="4599"
-		 width="2403"
-		 height="1403"
-		 id="rect291"
-		 style="fill:none;stroke:none" /><path
-		 d="m 6900,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-		 id="path293"
-		 inkscape:connector-curvature="0"
-		 style="fill:none;stroke:#3465a4" /><text
-		 class="TextShape"
-		 id="text295"><tspan
-		   class="TextParagraph"
-		   font-size="635px"
-		   font-weight="400"
-		   id="tspan297"
-		   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
-		     class="TextPosition"
-		     x="6725"
-		     y="5521"
-		     id="tspan299"><tspan
-		       id="tspan301"
-		       style="fill:#000000;stroke:none">3</tspan></tspan></tspan></text>
-</g></g><g
-	     class="com.sun.star.drawing.CustomShape"
-	     id="g303"><g
-	       id="id15"><rect
-		 class="BoundingBox"
-		 x="10499"
-		 y="4599"
-		 width="2403"
-		 height="1403"
-		 id="rect306"
-		 style="fill:none;stroke:none" /><path
-		 d="m 11700,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-		 id="path308"
-		 inkscape:connector-curvature="0"
-		 style="fill:none;stroke:#3465a4" /><text
-		 class="TextShape"
-		 id="text310"><tspan
-		   class="TextParagraph"
-		   font-size="635px"
-		   font-weight="400"
-		   id="tspan312"
-		   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
-		     class="TextPosition"
-		     x="11525"
-		     y="5521"
-		     id="tspan314"><tspan
-		       id="tspan316"
-		       style="fill:#000000;stroke:none">5</tspan></tspan></tspan></text>
-</g></g><g
-	     class="com.sun.star.drawing.LineShape"
-	     id="g318"><g
-	       id="id16"><rect
-		 class="BoundingBox"
-		 x="5199"
-		 y="3850"
-		 width="1402"
-		 height="301"
-		 id="rect321"
-		 style="fill:none;stroke:none" /><path
-		 d="m 5200,4000 970,0"
-		 id="path323"
-		 inkscape:connector-curvature="0"
-		 style="fill:none;stroke:#ff3333" /><path
-		 d="m 6600,4000 -450,-150 0,300 450,-150 z"
-		 id="path325"
-		 inkscape:connector-curvature="0"
-		 style="fill:#ff3333;stroke:none" /></g></g><g
-	     class="com.sun.star.drawing.LineShape"
-	     id="g327"><g
-	       id="id17"><rect
-		 class="BoundingBox"
-		 x="5000"
-		 y="4299"
-		 width="1202"
-		 height="802"
-		 id="rect330"
-		 style="fill:none;stroke:none" /><path
-		 d="m 6200,4300 -842,561"
-		 id="path332"
-		 inkscape:connector-curvature="0"
-		 style="fill:none;stroke:#ff3333" /><path
-		 d="m 5000,5100 458,-125 -167,-249 -291,374 z"
-		 id="path334"
-		 inkscape:connector-curvature="0"
-		 style="fill:#ff3333;stroke:none" /></g></g><g
-	     class="com.sun.star.drawing.LineShape"
-	     id="g336"><g
-	       id="id18"><rect
-		 class="BoundingBox"
-		 x="5399"
-		 y="5250"
-		 width="1202"
-		 height="301"
-		 id="rect339"
-		 style="fill:none;stroke:none" /><path
-		 d="m 5400,5400 770,0"
-		 id="path341"
-		 inkscape:connector-curvature="0"
-		 style="fill:none;stroke:#ff3333" /><path
-		 d="m 6600,5400 -450,-150 0,300 450,-150 z"
-		 id="path343"
-		 inkscape:connector-curvature="0"
-		 style="fill:#ff3333;stroke:none" /></g></g><g
-	     class="com.sun.star.drawing.LineShape"
-	     id="g345"><g
-	       id="id19"><rect
-		 class="BoundingBox"
-		 x="7599"
-		 y="5250"
-		 width="1202"
-		 height="301"
-		 id="rect348"
-		 style="fill:none;stroke:none" /><path
-		 d="m 7600,5400 770,0"
-		 id="path350"
-		 inkscape:connector-curvature="0"
-		 style="fill:none;stroke:#ff3333" /><path
-		 d="m 8800,5400 -450,-150 0,300 450,-150 z"
-		 id="path352"
-		 inkscape:connector-curvature="0"
-		 style="fill:#ff3333;stroke:none" /></g></g><g
-	     class="com.sun.star.drawing.LineShape"
-	     id="g354"><g
-	       id="id20"><rect
-		 class="BoundingBox"
-		 x="9799"
-		 y="5250"
-		 width="1402"
-		 height="301"
-		 id="rect357"
-		 style="fill:none;stroke:none" /><path
-		 d="m 9800,5400 970,0"
-		 id="path359"
-		 inkscape:connector-curvature="0"
-		 style="fill:none;stroke:#ff3333" /><path
-		 d="m 11200,5400 -450,-150 0,300 450,-150 z"
-		 id="path361"
-		 inkscape:connector-curvature="0"
-		 style="fill:#ff3333;stroke:none" /></g></g><g
-	     class="com.sun.star.drawing.LineShape"
-	     id="g363"><g
-	       id="id21"><rect
-		 class="BoundingBox"
-		 x="9900"
-		 y="4200"
-		 width="1202"
-		 height="802"
-		 id="rect366"
-		 style="fill:none;stroke:none" /><path
-		 d="m 11100,5000 -842,-561"
-		 id="path368"
-		 inkscape:connector-curvature="0"
-		 style="fill:none;stroke:#ff3333" /><path
-		 d="m 9900,4200 291,374 167,-249 -458,-125 z"
-		 id="path370"
-		 inkscape:connector-curvature="0"
-		 style="fill:#ff3333;stroke:none" /></g></g><g
-	     class="com.sun.star.drawing.LineShape"
-	     id="g372"><g
-	       id="id22"><rect
-		 class="BoundingBox"
-		 x="9999"
-		 y="3850"
-		 width="1402"
-		 height="301"
-		 id="rect375"
-		 style="fill:none;stroke:none" /><path
-		 d="m 10000,4000 970,0"
-		 id="path377"
-		 inkscape:connector-curvature="0"
-		 style="fill:none;stroke:#ff3333" /><path
-		 d="m 11400,4000 -450,-150 0,300 450,-150 z"
-		 id="path379"
-		 inkscape:connector-curvature="0"
-		 style="fill:#ff3333;stroke:none" /></g></g></g></g></g></g></svg>
diff --git a/Documentation/media/uapi/v4l/nv12mt_example.svg b/Documentation/media/uapi/v4l/nv12mt_example.svg
deleted file mode 100644
index 70c3200fdb32..000000000000
--- a/Documentation/media/uapi/v4l/nv12mt_example.svg
+++ /dev/null
@@ -1,1616 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!--
-    This file is dual-licensed: you can use it either under the terms
-    of the GPL 2.0 or the GFDL 1.1+ license, at your option. Note that this
-    dual licensing only applies to this file, and not this project as a
-    whole.
-
-    a) This file is free software; you can redistribute it and/or
-       modify it under the terms of the GNU General Public License as
-       published by the Free Software Foundation version 2 of
-       the License.
-
-       This file is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-    Or, alternatively,
-
-    b) Permission is granted to copy, distribute and/or modify this
-       document under the terms of the GNU Free Documentation License,
-       Version 1.1 or any later version published by the Free Software
-       Foundation, with no Invariant Sections, no Front-Cover Texts
-       and no Back-Cover Texts. A copy of the license is included at
-       Documentation/media/uapi/fdl-appendix.rst.
-
-    TODO: replace it to GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
--->
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   version="1.2"
-   width="144.28223mm"
-   height="70.282227mm"
-   viewBox="0 0 14428.222 7028.2226"
-   preserveAspectRatio="xMidYMid"
-   xml:space="preserve"
-   id="svg2"
-   inkscape:version="0.91 r13725"
-   sodipodi:docname="nv12mt_example.svg"
-   style="fill-rule:evenodd;stroke-width:28.22200012;stroke-linejoin:round"><metadata
-     id="metadata953"><rdf:RDF><cc:Work
-	 rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
-	   rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="1920"
-     inkscape:window-height="997"
-     id="namedview951"
-     showgrid="false"
-     fit-margin-top="0"
-     fit-margin-left="0"
-     fit-margin-right="0"
-     fit-margin-bottom="0"
-     inkscape:zoom="2.7306359"
-     inkscape:cx="255.61812"
-     inkscape:cy="124.51576"
-     inkscape:window-x="1920"
-     inkscape:window-y="30"
-     inkscape:window-maximized="1"
-     inkscape:current-layer="svg2" /><defs
-     class="ClipPathGroup"
-     id="defs4" /><defs
-     id="defs9" /><defs
-     id="defs84" /><defs
-     id="defs107" /><defs
-     class="TextShapeIndex"
-     id="defs118" /><defs
-     class="EmbeddedBulletChars"
-     id="defs122" /><defs
-     class="TextEmbeddedBitmaps"
-     id="defs151" /><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g188"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id6"><rect
-	 class="BoundingBox"
-	 x="3299"
-	 y="3199"
-	 width="2403"
-	 height="1403"
-	 id="rect191"
-	 style="fill:none;stroke:none" /><path
-	 d="m 4500,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path193"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /><text
-	 class="TextShape"
-	 id="text195"><tspan
-	   class="TextParagraph"
-	   font-size="635px"
-	   font-weight="400"
-	   id="tspan197"
-	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
-	     class="TextPosition"
-	     x="4325"
-	     y="4121"
-	     id="tspan199"><tspan
-	       id="tspan201"
-	       style="fill:#000000;stroke:none">0</tspan></tspan></tspan></text>
-</g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g203"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id7"><rect
-	 class="BoundingBox"
-	 x="5699"
-	 y="3199"
-	 width="2403"
-	 height="1403"
-	 id="rect206"
-	 style="fill:none;stroke:none" /><path
-	 d="m 6900,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path208"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /></g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g210"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id8"><rect
-	 class="BoundingBox"
-	 x="8099"
-	 y="3199"
-	 width="2403"
-	 height="1403"
-	 id="rect213"
-	 style="fill:none;stroke:none" /><path
-	 d="m 9300,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path215"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /><text
-	 class="TextShape"
-	 id="text217"><tspan
-	   class="TextParagraph"
-	   font-size="635px"
-	   font-weight="400"
-	   id="tspan219"
-	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
-	     class="TextPosition"
-	     x="9125"
-	     y="4121"
-	     id="tspan221"><tspan
-	       id="tspan223"
-	       style="fill:#000000;stroke:none">6</tspan></tspan></tspan></text>
-</g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g225"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id9"><rect
-	 class="BoundingBox"
-	 x="5699"
-	 y="3199"
-	 width="2403"
-	 height="1403"
-	 id="rect228"
-	 style="fill:none;stroke:none" /><path
-	 d="m 6900,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path230"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /><text
-	 class="TextShape"
-	 id="text232"><tspan
-	   class="TextParagraph"
-	   font-size="635px"
-	   font-weight="400"
-	   id="tspan234"
-	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
-	     class="TextPosition"
-	     x="6725"
-	     y="4121"
-	     id="tspan236"><tspan
-	       id="tspan238"
-	       style="fill:#000000;stroke:none">1</tspan></tspan></tspan></text>
-</g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g240"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id10"><rect
-	 class="BoundingBox"
-	 x="10499"
-	 y="3199"
-	 width="2403"
-	 height="1403"
-	 id="rect243"
-	 style="fill:none;stroke:none" /><path
-	 d="m 11700,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path245"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /><text
-	 class="TextShape"
-	 id="text247"><tspan
-	   class="TextParagraph"
-	   font-size="635px"
-	   font-weight="400"
-	   id="tspan249"
-	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
-	     class="TextPosition"
-	     x="11525"
-	     y="4121"
-	     id="tspan251"><tspan
-	       id="tspan253"
-	       style="fill:#000000;stroke:none">7</tspan></tspan></tspan></text>
-</g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g255"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id11"><rect
-	 class="BoundingBox"
-	 x="12899"
-	 y="3199"
-	 width="2403"
-	 height="1403"
-	 id="rect258"
-	 style="fill:none;stroke:none" /><path
-	 d="m 14100,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path260"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /></g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g262"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id12"><rect
-	 class="BoundingBox"
-	 x="15299"
-	 y="3199"
-	 width="2403"
-	 height="1403"
-	 id="rect265"
-	 style="fill:none;stroke:none" /><path
-	 d="m 16500,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path267"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /><text
-	 class="TextShape"
-	 id="text269"><tspan
-	   class="TextParagraph"
-	   font-size="635px"
-	   font-weight="400"
-	   id="tspan271"
-	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
-	     class="TextPosition"
-	     x="16325"
-	     y="4121"
-	     id="tspan273"><tspan
-	       id="tspan275"
-	       style="fill:#000000;stroke:none">9</tspan></tspan></tspan></text>
-</g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g277"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id13"><rect
-	 class="BoundingBox"
-	 x="12899"
-	 y="3199"
-	 width="2403"
-	 height="1403"
-	 id="rect280"
-	 style="fill:none;stroke:none" /><path
-	 d="m 14100,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path282"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /><text
-	 class="TextShape"
-	 id="text284"><tspan
-	   class="TextParagraph"
-	   font-size="635px"
-	   font-weight="400"
-	   id="tspan286"
-	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
-	     class="TextPosition"
-	     x="13925"
-	     y="4121"
-	     id="tspan288"><tspan
-	       id="tspan290"
-	       style="fill:#000000;stroke:none">8</tspan></tspan></tspan></text>
-</g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g292"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id14"><rect
-	 class="BoundingBox"
-	 x="3299"
-	 y="4599"
-	 width="2403"
-	 height="1403"
-	 id="rect295"
-	 style="fill:none;stroke:none" /><path
-	 d="m 4500,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path297"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /><text
-	 class="TextShape"
-	 id="text299"><tspan
-	   class="TextParagraph"
-	   font-size="635px"
-	   font-weight="400"
-	   id="tspan301"
-	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
-	     class="TextPosition"
-	     x="4325"
-	     y="5521"
-	     id="tspan303"><tspan
-	       id="tspan305"
-	       style="fill:#000000;stroke:none">2</tspan></tspan></tspan></text>
-</g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g307"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id15"><rect
-	 class="BoundingBox"
-	 x="5699"
-	 y="4599"
-	 width="2403"
-	 height="1403"
-	 id="rect310"
-	 style="fill:none;stroke:none" /><path
-	 d="m 6900,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path312"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /></g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g314"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id16"><rect
-	 class="BoundingBox"
-	 x="8099"
-	 y="4599"
-	 width="2403"
-	 height="1403"
-	 id="rect317"
-	 style="fill:none;stroke:none" /><path
-	 d="m 9300,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path319"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /><text
-	 class="TextShape"
-	 id="text321"><tspan
-	   class="TextParagraph"
-	   font-size="635px"
-	   font-weight="400"
-	   id="tspan323"
-	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
-	     class="TextPosition"
-	     x="9125"
-	     y="5521"
-	     id="tspan325"><tspan
-	       id="tspan327"
-	       style="fill:#000000;stroke:none">4</tspan></tspan></tspan></text>
-</g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g329"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id17"><rect
-	 class="BoundingBox"
-	 x="5699"
-	 y="4599"
-	 width="2403"
-	 height="1403"
-	 id="rect332"
-	 style="fill:none;stroke:none" /><path
-	 d="m 6900,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path334"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /><text
-	 class="TextShape"
-	 id="text336"><tspan
-	   class="TextParagraph"
-	   font-size="635px"
-	   font-weight="400"
-	   id="tspan338"
-	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
-	     class="TextPosition"
-	     x="6725"
-	     y="5521"
-	     id="tspan340"><tspan
-	       id="tspan342"
-	       style="fill:#000000;stroke:none">3</tspan></tspan></tspan></text>
-</g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g344"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id18"><rect
-	 class="BoundingBox"
-	 x="10499"
-	 y="4599"
-	 width="2403"
-	 height="1403"
-	 id="rect347"
-	 style="fill:none;stroke:none" /><path
-	 d="m 11700,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path349"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /><text
-	 class="TextShape"
-	 id="text351"><tspan
-	   class="TextParagraph"
-	   font-size="635px"
-	   font-weight="400"
-	   id="tspan353"
-	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
-	     class="TextPosition"
-	     x="11525"
-	     y="5521"
-	     id="tspan355"><tspan
-	       id="tspan357"
-	       style="fill:#000000;stroke:none">5</tspan></tspan></tspan></text>
-</g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g359"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id19"><rect
-	 class="BoundingBox"
-	 x="12899"
-	 y="4599"
-	 width="2403"
-	 height="1403"
-	 id="rect362"
-	 style="fill:none;stroke:none" /><path
-	 d="m 14100,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path364"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /></g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g366"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id20"><rect
-	 class="BoundingBox"
-	 x="15299"
-	 y="4599"
-	 width="2403"
-	 height="1403"
-	 id="rect369"
-	 style="fill:none;stroke:none" /><path
-	 d="m 16500,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path371"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /><text
-	 class="TextShape"
-	 id="text373"><tspan
-	   class="TextParagraph"
-	   font-size="635px"
-	   font-weight="400"
-	   id="tspan375"
-	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
-	     class="TextPosition"
-	     x="16149"
-	     y="5521"
-	     id="tspan377"><tspan
-	       id="tspan379"
-	       style="fill:#000000;stroke:none">11</tspan></tspan></tspan></text>
-</g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g381"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id21"><rect
-	 class="BoundingBox"
-	 x="12899"
-	 y="4599"
-	 width="2403"
-	 height="1403"
-	 id="rect384"
-	 style="fill:none;stroke:none" /><path
-	 d="m 14100,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path386"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /><text
-	 class="TextShape"
-	 id="text388"><tspan
-	   class="TextParagraph"
-	   font-size="635px"
-	   font-weight="400"
-	   id="tspan390"
-	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
-	     class="TextPosition"
-	     x="13749"
-	     y="5521"
-	     id="tspan392"><tspan
-	       id="tspan394"
-	       style="fill:#000000;stroke:none">10</tspan></tspan></tspan></text>
-</g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g396"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id22"><rect
-	 class="BoundingBox"
-	 x="3299"
-	 y="5999"
-	 width="2403"
-	 height="1403"
-	 id="rect399"
-	 style="fill:none;stroke:none" /><path
-	 d="m 4500,7400 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path401"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /><text
-	 class="TextShape"
-	 id="text403"><tspan
-	   class="TextParagraph"
-	   font-size="635px"
-	   font-weight="400"
-	   id="tspan405"
-	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
-	     class="TextPosition"
-	     x="4149"
-	     y="6921"
-	     id="tspan407"><tspan
-	       id="tspan409"
-	       style="fill:#000000;stroke:none">12</tspan></tspan></tspan></text>
-</g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g411"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id23"><rect
-	 class="BoundingBox"
-	 x="5699"
-	 y="5999"
-	 width="2403"
-	 height="1403"
-	 id="rect414"
-	 style="fill:none;stroke:none" /><path
-	 d="m 6900,7400 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path416"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /></g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g418"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id24"><rect
-	 class="BoundingBox"
-	 x="8099"
-	 y="5999"
-	 width="2403"
-	 height="1403"
-	 id="rect421"
-	 style="fill:none;stroke:none" /><path
-	 d="m 9300,7400 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path423"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /><text
-	 class="TextShape"
-	 id="text425"><tspan
-	   class="TextParagraph"
-	   font-size="635px"
-	   font-weight="400"
-	   id="tspan427"
-	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
-	     class="TextPosition"
-	     x="8949"
-	     y="6921"
-	     id="tspan429"><tspan
-	       id="tspan431"
-	       style="fill:#000000;stroke:none">18</tspan></tspan></tspan></text>
-</g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g433"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id25"><rect
-	 class="BoundingBox"
-	 x="5699"
-	 y="5999"
-	 width="2403"
-	 height="1403"
-	 id="rect436"
-	 style="fill:none;stroke:none" /><path
-	 d="m 6900,7400 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path438"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /><text
-	 class="TextShape"
-	 id="text440"><tspan
-	   class="TextParagraph"
-	   font-size="635px"
-	   font-weight="400"
-	   id="tspan442"
-	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
-	     class="TextPosition"
-	     x="6549"
-	     y="6921"
-	     id="tspan444"><tspan
-	       id="tspan446"
-	       style="fill:#000000;stroke:none">13</tspan></tspan></tspan></text>
-</g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g448"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id26"><rect
-	 class="BoundingBox"
-	 x="10499"
-	 y="5999"
-	 width="2403"
-	 height="1403"
-	 id="rect451"
-	 style="fill:none;stroke:none" /><path
-	 d="m 11700,7400 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path453"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /><text
-	 class="TextShape"
-	 id="text455"><tspan
-	   class="TextParagraph"
-	   font-size="635px"
-	   font-weight="400"
-	   id="tspan457"
-	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
-	     class="TextPosition"
-	     x="11349"
-	     y="6921"
-	     id="tspan459"><tspan
-	       id="tspan461"
-	       style="fill:#000000;stroke:none">19</tspan></tspan></tspan></text>
-</g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g463"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id27"><rect
-	 class="BoundingBox"
-	 x="12899"
-	 y="5999"
-	 width="2403"
-	 height="1403"
-	 id="rect466"
-	 style="fill:none;stroke:none" /><path
-	 d="m 14100,7400 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path468"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /></g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g470"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id28"><rect
-	 class="BoundingBox"
-	 x="15299"
-	 y="5999"
-	 width="2403"
-	 height="1403"
-	 id="rect473"
-	 style="fill:none;stroke:none" /><path
-	 d="m 16500,7400 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path475"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /><text
-	 class="TextShape"
-	 id="text477"><tspan
-	   class="TextParagraph"
-	   font-size="635px"
-	   font-weight="400"
-	   id="tspan479"
-	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
-	     class="TextPosition"
-	     x="16149"
-	     y="6921"
-	     id="tspan481"><tspan
-	       id="tspan483"
-	       style="fill:#000000;stroke:none">21</tspan></tspan></tspan></text>
-</g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g485"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id29"><rect
-	 class="BoundingBox"
-	 x="12899"
-	 y="5999"
-	 width="2403"
-	 height="1403"
-	 id="rect488"
-	 style="fill:none;stroke:none" /><path
-	 d="m 14100,7400 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path490"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /><text
-	 class="TextShape"
-	 id="text492"><tspan
-	   class="TextParagraph"
-	   font-size="635px"
-	   font-weight="400"
-	   id="tspan494"
-	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
-	     class="TextPosition"
-	     x="13749"
-	     y="6921"
-	     id="tspan496"><tspan
-	       id="tspan498"
-	       style="fill:#000000;stroke:none">20</tspan></tspan></tspan></text>
-</g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g500"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id30"><rect
-	 class="BoundingBox"
-	 x="3299"
-	 y="7399"
-	 width="2403"
-	 height="1403"
-	 id="rect503"
-	 style="fill:none;stroke:none" /><path
-	 d="m 4500,8800 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path505"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /><text
-	 class="TextShape"
-	 id="text507"><tspan
-	   class="TextParagraph"
-	   font-size="635px"
-	   font-weight="400"
-	   id="tspan509"
-	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
-	     class="TextPosition"
-	     x="4149"
-	     y="8321"
-	     id="tspan511"><tspan
-	       id="tspan513"
-	       style="fill:#000000;stroke:none">14</tspan></tspan></tspan></text>
-</g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g515"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id31"><rect
-	 class="BoundingBox"
-	 x="5699"
-	 y="7399"
-	 width="2403"
-	 height="1403"
-	 id="rect518"
-	 style="fill:none;stroke:none" /><path
-	 d="m 6900,8800 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path520"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /></g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g522"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id32"><rect
-	 class="BoundingBox"
-	 x="8099"
-	 y="7399"
-	 width="2403"
-	 height="1403"
-	 id="rect525"
-	 style="fill:none;stroke:none" /><path
-	 d="m 9300,8800 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path527"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /><text
-	 class="TextShape"
-	 id="text529"><tspan
-	   class="TextParagraph"
-	   font-size="635px"
-	   font-weight="400"
-	   id="tspan531"
-	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
-	     class="TextPosition"
-	     x="8949"
-	     y="8321"
-	     id="tspan533"><tspan
-	       id="tspan535"
-	       style="fill:#000000;stroke:none">16</tspan></tspan></tspan></text>
-</g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g537"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id33"><rect
-	 class="BoundingBox"
-	 x="5699"
-	 y="7399"
-	 width="2403"
-	 height="1403"
-	 id="rect540"
-	 style="fill:none;stroke:none" /><path
-	 d="m 6900,8800 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path542"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /><text
-	 class="TextShape"
-	 id="text544"><tspan
-	   class="TextParagraph"
-	   font-size="635px"
-	   font-weight="400"
-	   id="tspan546"
-	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
-	     class="TextPosition"
-	     x="6549"
-	     y="8321"
-	     id="tspan548"><tspan
-	       id="tspan550"
-	       style="fill:#000000;stroke:none">15</tspan></tspan></tspan></text>
-</g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g552"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id34"><rect
-	 class="BoundingBox"
-	 x="10499"
-	 y="7399"
-	 width="2403"
-	 height="1403"
-	 id="rect555"
-	 style="fill:none;stroke:none" /><path
-	 d="m 11700,8800 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path557"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /><text
-	 class="TextShape"
-	 id="text559"><tspan
-	   class="TextParagraph"
-	   font-size="635px"
-	   font-weight="400"
-	   id="tspan561"
-	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
-	     class="TextPosition"
-	     x="11349"
-	     y="8321"
-	     id="tspan563"><tspan
-	       id="tspan565"
-	       style="fill:#000000;stroke:none">17</tspan></tspan></tspan></text>
-</g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g567"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id35"><rect
-	 class="BoundingBox"
-	 x="12899"
-	 y="7399"
-	 width="2403"
-	 height="1403"
-	 id="rect570"
-	 style="fill:none;stroke:none" /><path
-	 d="m 14100,8800 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path572"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /></g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g574"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id36"><rect
-	 class="BoundingBox"
-	 x="15299"
-	 y="7399"
-	 width="2403"
-	 height="1403"
-	 id="rect577"
-	 style="fill:none;stroke:none" /><path
-	 d="m 16500,8800 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path579"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /><text
-	 class="TextShape"
-	 id="text581"><tspan
-	   class="TextParagraph"
-	   font-size="635px"
-	   font-weight="400"
-	   id="tspan583"
-	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
-	     class="TextPosition"
-	     x="16149"
-	     y="8321"
-	     id="tspan585"><tspan
-	       id="tspan587"
-	       style="fill:#000000;stroke:none">23</tspan></tspan></tspan></text>
-</g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g589"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id37"><rect
-	 class="BoundingBox"
-	 x="12899"
-	 y="7399"
-	 width="2403"
-	 height="1403"
-	 id="rect592"
-	 style="fill:none;stroke:none" /><path
-	 d="m 14100,8800 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path594"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /><text
-	 class="TextShape"
-	 id="text596"><tspan
-	   class="TextParagraph"
-	   font-size="635px"
-	   font-weight="400"
-	   id="tspan598"
-	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
-	     class="TextPosition"
-	     x="13749"
-	     y="8321"
-	     id="tspan600"><tspan
-	       id="tspan602"
-	       style="fill:#000000;stroke:none">22</tspan></tspan></tspan></text>
-</g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g604"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id38"><rect
-	 class="BoundingBox"
-	 x="3299"
-	 y="8799"
-	 width="2403"
-	 height="1403"
-	 id="rect607"
-	 style="fill:none;stroke:none" /><path
-	 d="m 4500,10200 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path609"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /><text
-	 class="TextShape"
-	 id="text611"><tspan
-	   class="TextParagraph"
-	   font-size="635px"
-	   font-weight="400"
-	   id="tspan613"
-	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
-	     class="TextPosition"
-	     x="4149"
-	     y="9721"
-	     id="tspan615"><tspan
-	       id="tspan617"
-	       style="fill:#000000;stroke:none">24</tspan></tspan></tspan></text>
-</g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g619"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id39"><rect
-	 class="BoundingBox"
-	 x="5699"
-	 y="8799"
-	 width="2403"
-	 height="1403"
-	 id="rect622"
-	 style="fill:none;stroke:none" /><path
-	 d="m 6900,10200 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path624"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /></g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g626"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id40"><rect
-	 class="BoundingBox"
-	 x="8099"
-	 y="8799"
-	 width="2403"
-	 height="1403"
-	 id="rect629"
-	 style="fill:none;stroke:none" /><path
-	 d="m 9300,10200 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path631"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /><text
-	 class="TextShape"
-	 id="text633"><tspan
-	   class="TextParagraph"
-	   font-size="635px"
-	   font-weight="400"
-	   id="tspan635"
-	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
-	     class="TextPosition"
-	     x="8949"
-	     y="9721"
-	     id="tspan637"><tspan
-	       id="tspan639"
-	       style="fill:#000000;stroke:none">26</tspan></tspan></tspan></text>
-</g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g641"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id41"><rect
-	 class="BoundingBox"
-	 x="5699"
-	 y="8799"
-	 width="2403"
-	 height="1403"
-	 id="rect644"
-	 style="fill:none;stroke:none" /><path
-	 d="m 6900,10200 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path646"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /><text
-	 class="TextShape"
-	 id="text648"><tspan
-	   class="TextParagraph"
-	   font-size="635px"
-	   font-weight="400"
-	   id="tspan650"
-	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
-	     class="TextPosition"
-	     x="6549"
-	     y="9721"
-	     id="tspan652"><tspan
-	       id="tspan654"
-	       style="fill:#000000;stroke:none">25</tspan></tspan></tspan></text>
-</g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g656"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id42"><rect
-	 class="BoundingBox"
-	 x="10499"
-	 y="8799"
-	 width="2403"
-	 height="1403"
-	 id="rect659"
-	 style="fill:none;stroke:none" /><path
-	 d="m 11700,10200 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path661"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /><text
-	 class="TextShape"
-	 id="text663"><tspan
-	   class="TextParagraph"
-	   font-size="635px"
-	   font-weight="400"
-	   id="tspan665"
-	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
-	     class="TextPosition"
-	     x="11349"
-	     y="9721"
-	     id="tspan667"><tspan
-	       id="tspan669"
-	       style="fill:#000000;stroke:none">27</tspan></tspan></tspan></text>
-</g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g671"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id43"><rect
-	 class="BoundingBox"
-	 x="12899"
-	 y="8799"
-	 width="2403"
-	 height="1403"
-	 id="rect674"
-	 style="fill:none;stroke:none" /><path
-	 d="m 14100,10200 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path676"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /></g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g678"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id44"><rect
-	 class="BoundingBox"
-	 x="15299"
-	 y="8799"
-	 width="2403"
-	 height="1403"
-	 id="rect681"
-	 style="fill:none;stroke:none" /><path
-	 d="m 16500,10200 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path683"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /><text
-	 class="TextShape"
-	 id="text685"><tspan
-	   class="TextParagraph"
-	   font-size="635px"
-	   font-weight="400"
-	   id="tspan687"
-	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
-	     class="TextPosition"
-	     x="16149"
-	     y="9721"
-	     id="tspan689"><tspan
-	       id="tspan691"
-	       style="fill:#000000;stroke:none">29</tspan></tspan></tspan></text>
-</g></g><g
-     class="com.sun.star.drawing.CustomShape"
-     id="g693"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id45"><rect
-	 class="BoundingBox"
-	 x="12899"
-	 y="8799"
-	 width="2403"
-	 height="1403"
-	 id="rect696"
-	 style="fill:none;stroke:none" /><path
-	 d="m 14100,10200 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
-	 id="path698"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#3465a4" /><text
-	 class="TextShape"
-	 id="text700"><tspan
-	   class="TextParagraph"
-	   font-size="635px"
-	   font-weight="400"
-	   id="tspan702"
-	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
-	     class="TextPosition"
-	     x="13749"
-	     y="9721"
-	     id="tspan704"><tspan
-	       id="tspan706"
-	       style="fill:#000000;stroke:none">28</tspan></tspan></tspan></text>
-</g></g><g
-     class="com.sun.star.drawing.LineShape"
-     id="g708"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id46"><rect
-	 class="BoundingBox"
-	 x="5199"
-	 y="3850"
-	 width="1402"
-	 height="301"
-	 id="rect711"
-	 style="fill:none;stroke:none" /><path
-	 d="m 5200,4000 970,0"
-	 id="path713"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#ff3333" /><path
-	 d="m 6600,4000 -450,-150 0,300 450,-150 z"
-	 id="path715"
-	 inkscape:connector-curvature="0"
-	 style="fill:#ff3333;stroke:none" /></g></g><g
-     class="com.sun.star.drawing.LineShape"
-     id="g717"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id47"><rect
-	 class="BoundingBox"
-	 x="5000"
-	 y="4299"
-	 width="1202"
-	 height="802"
-	 id="rect720"
-	 style="fill:none;stroke:none" /><path
-	 d="m 6200,4300 -842,561"
-	 id="path722"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#ff3333" /><path
-	 d="m 5000,5100 458,-125 -167,-249 -291,374 z"
-	 id="path724"
-	 inkscape:connector-curvature="0"
-	 style="fill:#ff3333;stroke:none" /></g></g><g
-     class="com.sun.star.drawing.LineShape"
-     id="g726"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id48"><rect
-	 class="BoundingBox"
-	 x="5399"
-	 y="5250"
-	 width="1202"
-	 height="301"
-	 id="rect729"
-	 style="fill:none;stroke:none" /><path
-	 d="m 5400,5400 770,0"
-	 id="path731"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#ff3333" /><path
-	 d="m 6600,5400 -450,-150 0,300 450,-150 z"
-	 id="path733"
-	 inkscape:connector-curvature="0"
-	 style="fill:#ff3333;stroke:none" /></g></g><g
-     class="com.sun.star.drawing.LineShape"
-     id="g735"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id49"><rect
-	 class="BoundingBox"
-	 x="7599"
-	 y="5250"
-	 width="1202"
-	 height="301"
-	 id="rect738"
-	 style="fill:none;stroke:none" /><path
-	 d="m 7600,5400 770,0"
-	 id="path740"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#ff3333" /><path
-	 d="m 8800,5400 -450,-150 0,300 450,-150 z"
-	 id="path742"
-	 inkscape:connector-curvature="0"
-	 style="fill:#ff3333;stroke:none" /></g></g><g
-     class="com.sun.star.drawing.LineShape"
-     id="g744"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id50"><rect
-	 class="BoundingBox"
-	 x="9799"
-	 y="5250"
-	 width="1402"
-	 height="301"
-	 id="rect747"
-	 style="fill:none;stroke:none" /><path
-	 d="m 9800,5400 970,0"
-	 id="path749"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#ff3333" /><path
-	 d="m 11200,5400 -450,-150 0,300 450,-150 z"
-	 id="path751"
-	 inkscape:connector-curvature="0"
-	 style="fill:#ff3333;stroke:none" /></g></g><g
-     class="com.sun.star.drawing.LineShape"
-     id="g753"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id51"><rect
-	 class="BoundingBox"
-	 x="9900"
-	 y="4200"
-	 width="1202"
-	 height="802"
-	 id="rect756"
-	 style="fill:none;stroke:none" /><path
-	 d="m 11100,5000 -842,-561"
-	 id="path758"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#ff3333" /><path
-	 d="m 9900,4200 291,374 167,-249 -458,-125 z"
-	 id="path760"
-	 inkscape:connector-curvature="0"
-	 style="fill:#ff3333;stroke:none" /></g></g><g
-     class="com.sun.star.drawing.LineShape"
-     id="g762"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id52"><rect
-	 class="BoundingBox"
-	 x="9999"
-	 y="3850"
-	 width="1402"
-	 height="301"
-	 id="rect765"
-	 style="fill:none;stroke:none" /><path
-	 d="m 10000,4000 970,0"
-	 id="path767"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#ff3333" /><path
-	 d="m 11400,4000 -450,-150 0,300 450,-150 z"
-	 id="path769"
-	 inkscape:connector-curvature="0"
-	 style="fill:#ff3333;stroke:none" /></g></g><g
-     class="com.sun.star.drawing.LineShape"
-     id="g771"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id53"><rect
-	 class="BoundingBox"
-	 x="12399"
-	 y="3850"
-	 width="1202"
-	 height="301"
-	 id="rect774"
-	 style="fill:none;stroke:none" /><path
-	 d="m 12400,4000 770,0"
-	 id="path776"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#ff3333" /><path
-	 d="m 13600,4000 -450,-150 0,300 450,-150 z"
-	 id="path778"
-	 inkscape:connector-curvature="0"
-	 style="fill:#ff3333;stroke:none" /></g></g><g
-     class="com.sun.star.drawing.LineShape"
-     id="g780"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id54"><rect
-	 class="BoundingBox"
-	 x="14799"
-	 y="3850"
-	 width="1202"
-	 height="301"
-	 id="rect783"
-	 style="fill:none;stroke:none" /><path
-	 d="m 14800,4000 770,0"
-	 id="path785"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#ff3333" /><path
-	 d="m 16000,4000 -450,-150 0,300 450,-150 z"
-	 id="path787"
-	 inkscape:connector-curvature="0"
-	 style="fill:#ff3333;stroke:none" /></g></g><g
-     class="com.sun.star.drawing.LineShape"
-     id="g789"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id55"><rect
-	 class="BoundingBox"
-	 x="14400"
-	 y="4399"
-	 width="1402"
-	 height="602"
-	 id="rect792"
-	 style="fill:none;stroke:none" /><path
-	 d="m 15800,4400 -1005,431"
-	 id="path794"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#ff3333" /><path
-	 d="m 14400,5000 473,-39 -118,-276 -355,315 z"
-	 id="path796"
-	 inkscape:connector-curvature="0"
-	 style="fill:#ff3333;stroke:none" /></g></g><g
-     class="com.sun.star.drawing.LineShape"
-     id="g798"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id56"><rect
-	 class="BoundingBox"
-	 x="14599"
-	 y="5250"
-	 width="1402"
-	 height="301"
-	 id="rect801"
-	 style="fill:none;stroke:none" /><path
-	 d="m 14600,5400 970,0"
-	 id="path803"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#ff3333" /><path
-	 d="m 16000,5400 -450,-150 0,300 450,-150 z"
-	 id="path805"
-	 inkscape:connector-curvature="0"
-	 style="fill:#ff3333;stroke:none" /></g></g><g
-     class="com.sun.star.drawing.LineShape"
-     id="g807"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id57"><rect
-	 class="BoundingBox"
-	 x="5199"
-	 y="6550"
-	 width="1402"
-	 height="301"
-	 id="rect810"
-	 style="fill:none;stroke:none" /><path
-	 d="m 5200,6700 970,0"
-	 id="path812"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#ff3333" /><path
-	 d="m 6600,6700 -450,-150 0,300 450,-150 z"
-	 id="path814"
-	 inkscape:connector-curvature="0"
-	 style="fill:#ff3333;stroke:none" /></g></g><g
-     class="com.sun.star.drawing.LineShape"
-     id="g816"
-     transform="translate(-3285.889,-3129.4446)"><g
-       id="id58"><rect
-	 class="BoundingBox"
-	 x="5000"
-	 y="6999"
-	 width="1202"
-	 height="802"
-	 id="rect819"
-	 style="fill:none;stroke:none" /><path
-	 d="m 6200,7000 -842,561"
-	 id="path821"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#ff3333" /><path
-	 d="m 5000,7800 458,-125 -167,-249 -291,374 z"
-	 id="path823"
-	 inkscape:connector-curvature="0"
-	 style="fill:#ff3333;stroke:none" /></g></g><g
-     class="com.sun.star.drawing.LineShape"
-     id="g825"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id59"><rect
-	 class="BoundingBox"
-	 x="5399"
-	 y="7950"
-	 width="1202"
-	 height="301"
-	 id="rect828"
-	 style="fill:none;stroke:none" /><path
-	 d="m 5400,8100 770,0"
-	 id="path830"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#ff3333" /><path
-	 d="m 6600,8100 -450,-150 0,300 450,-150 z"
-	 id="path832"
-	 inkscape:connector-curvature="0"
-	 style="fill:#ff3333;stroke:none" /></g></g><g
-     class="com.sun.star.drawing.LineShape"
-     id="g834"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id60"><rect
-	 class="BoundingBox"
-	 x="7599"
-	 y="7950"
-	 width="1202"
-	 height="301"
-	 id="rect837"
-	 style="fill:none;stroke:none" /><path
-	 d="m 7600,8100 770,0"
-	 id="path839"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#ff3333" /><path
-	 d="m 8800,8100 -450,-150 0,300 450,-150 z"
-	 id="path841"
-	 inkscape:connector-curvature="0"
-	 style="fill:#ff3333;stroke:none" /></g></g><g
-     class="com.sun.star.drawing.LineShape"
-     id="g843"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id61"><rect
-	 class="BoundingBox"
-	 x="9799"
-	 y="7950"
-	 width="1402"
-	 height="301"
-	 id="rect846"
-	 style="fill:none;stroke:none" /><path
-	 d="m 9800,8100 970,0"
-	 id="path848"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#ff3333" /><path
-	 d="m 11200,8100 -450,-150 0,300 450,-150 z"
-	 id="path850"
-	 inkscape:connector-curvature="0"
-	 style="fill:#ff3333;stroke:none" /></g></g><g
-     class="com.sun.star.drawing.LineShape"
-     id="g852"
-     transform="translate(-3285.889,-3129.4446)"><g
-       id="id62"><rect
-	 class="BoundingBox"
-	 x="9900"
-	 y="6900"
-	 width="1202"
-	 height="802"
-	 id="rect855"
-	 style="fill:none;stroke:none" /><path
-	 d="m 11100,7700 -842,-561"
-	 id="path857"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#ff3333" /><path
-	 d="m 9900,6900 291,374 167,-249 -458,-125 z"
-	 id="path859"
-	 inkscape:connector-curvature="0"
-	 style="fill:#ff3333;stroke:none" /></g></g><g
-     class="com.sun.star.drawing.LineShape"
-     id="g861"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id63"><rect
-	 class="BoundingBox"
-	 x="9999"
-	 y="6550"
-	 width="1402"
-	 height="301"
-	 id="rect864"
-	 style="fill:none;stroke:none" /><path
-	 d="m 10000,6700 970,0"
-	 id="path866"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#ff3333" /><path
-	 d="m 11400,6700 -450,-150 0,300 450,-150 z"
-	 id="path868"
-	 inkscape:connector-curvature="0"
-	 style="fill:#ff3333;stroke:none" /></g></g><g
-     class="com.sun.star.drawing.LineShape"
-     id="g870"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id64"><rect
-	 class="BoundingBox"
-	 x="12399"
-	 y="6550"
-	 width="1202"
-	 height="301"
-	 id="rect873"
-	 style="fill:none;stroke:none" /><path
-	 d="m 12400,6700 770,0"
-	 id="path875"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#ff3333" /><path
-	 d="m 13600,6700 -450,-150 0,300 450,-150 z"
-	 id="path877"
-	 inkscape:connector-curvature="0"
-	 style="fill:#ff3333;stroke:none" /></g></g><g
-     class="com.sun.star.drawing.LineShape"
-     id="g879"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id65"><rect
-	 class="BoundingBox"
-	 x="14799"
-	 y="6550"
-	 width="1202"
-	 height="301"
-	 id="rect882"
-	 style="fill:none;stroke:none" /><path
-	 d="m 14800,6700 770,0"
-	 id="path884"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#ff3333" /><path
-	 d="m 16000,6700 -450,-150 0,300 450,-150 z"
-	 id="path886"
-	 inkscape:connector-curvature="0"
-	 style="fill:#ff3333;stroke:none" /></g></g><g
-     class="com.sun.star.drawing.LineShape"
-     id="g888"
-     transform="translate(-3285.889,-3129.4446)"><g
-       id="id66"><rect
-	 class="BoundingBox"
-	 x="14400"
-	 y="7099"
-	 width="1402"
-	 height="602"
-	 id="rect891"
-	 style="fill:none;stroke:none" /><path
-	 d="m 15800,7100 -1005,431"
-	 id="path893"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#ff3333" /><path
-	 d="m 14400,7700 473,-39 -118,-276 -355,315 z"
-	 id="path895"
-	 inkscape:connector-curvature="0"
-	 style="fill:#ff3333;stroke:none" /></g></g><g
-     class="com.sun.star.drawing.LineShape"
-     id="g897"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id67"><rect
-	 class="BoundingBox"
-	 x="14599"
-	 y="7950"
-	 width="1402"
-	 height="301"
-	 id="rect900"
-	 style="fill:none;stroke:none" /><path
-	 d="m 14600,8100 970,0"
-	 id="path902"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#ff3333" /><path
-	 d="m 16000,8100 -450,-150 0,300 450,-150 z"
-	 id="path904"
-	 inkscape:connector-curvature="0"
-	 style="fill:#ff3333;stroke:none" /></g></g><g
-     class="com.sun.star.drawing.LineShape"
-     id="g906"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id68"><rect
-	 class="BoundingBox"
-	 x="5399"
-	 y="9450"
-	 width="1202"
-	 height="301"
-	 id="rect909"
-	 style="fill:none;stroke:none" /><path
-	 d="m 5400,9600 770,0"
-	 id="path911"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#ff3333" /><path
-	 d="m 6600,9600 -450,-150 0,300 450,-150 z"
-	 id="path913"
-	 inkscape:connector-curvature="0"
-	 style="fill:#ff3333;stroke:none" /></g></g><g
-     class="com.sun.star.drawing.LineShape"
-     id="g915"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id69"><rect
-	 class="BoundingBox"
-	 x="7599"
-	 y="9450"
-	 width="1202"
-	 height="301"
-	 id="rect918"
-	 style="fill:none;stroke:none" /><path
-	 d="m 7600,9600 770,0"
-	 id="path920"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#ff3333" /><path
-	 d="m 8800,9600 -450,-150 0,300 450,-150 z"
-	 id="path922"
-	 inkscape:connector-curvature="0"
-	 style="fill:#ff3333;stroke:none" /></g></g><g
-     class="com.sun.star.drawing.LineShape"
-     id="g924"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id70"><rect
-	 class="BoundingBox"
-	 x="9999"
-	 y="9450"
-	 width="1202"
-	 height="301"
-	 id="rect927"
-	 style="fill:none;stroke:none" /><path
-	 d="m 10000,9600 770,0"
-	 id="path929"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#ff3333" /><path
-	 d="m 11200,9600 -450,-150 0,300 450,-150 z"
-	 id="path931"
-	 inkscape:connector-curvature="0"
-	 style="fill:#ff3333;stroke:none" /></g></g><g
-     class="com.sun.star.drawing.LineShape"
-     id="g933"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id71"><rect
-	 class="BoundingBox"
-	 x="12399"
-	 y="9450"
-	 width="1202"
-	 height="301"
-	 id="rect936"
-	 style="fill:none;stroke:none" /><path
-	 d="m 12400,9600 770,0"
-	 id="path938"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#ff3333" /><path
-	 d="m 13600,9600 -450,-150 0,300 450,-150 z"
-	 id="path940"
-	 inkscape:connector-curvature="0"
-	 style="fill:#ff3333;stroke:none" /></g></g><g
-     class="com.sun.star.drawing.LineShape"
-     id="g942"
-     transform="translate(-3285.889,-3185.889)"><g
-       id="id72"><rect
-	 class="BoundingBox"
-	 x="14799"
-	 y="9450"
-	 width="1202"
-	 height="301"
-	 id="rect945"
-	 style="fill:none;stroke:none" /><path
-	 d="m 14800,9600 770,0"
-	 id="path947"
-	 inkscape:connector-curvature="0"
-	 style="fill:none;stroke:#ff3333" /><path
-	 d="m 16000,9600 -450,-150 0,300 450,-150 z"
-	 id="path949"
-	 inkscape:connector-curvature="0"
-	 style="fill:#ff3333;stroke:none" /></g></g></svg>
diff --git a/Documentation/media/uapi/v4l/open.rst b/Documentation/media/uapi/v4l/open.rst
deleted file mode 100644
index 42fad5001c5c..000000000000
--- a/Documentation/media/uapi/v4l/open.rst
+++ /dev/null
@@ -1,165 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _open:
-
-***************************
-Opening and Closing Devices
-***************************
-
-
-Device Naming
-=============
-
-V4L2 drivers are implemented as kernel modules, loaded manually by the
-system administrator or automatically when a device is first discovered.
-The driver modules plug into the "videodev" kernel module. It provides
-helper functions and a common application interface specified in this
-document.
-
-Each driver thus loaded registers one or more device nodes with major
-number 81 and a minor number between 0 and 255. Minor numbers are
-allocated dynamically unless the kernel is compiled with the kernel
-option CONFIG_VIDEO_FIXED_MINOR_RANGES. In that case minor numbers
-are allocated in ranges depending on the device node type (video, radio,
-etc.).
-
-Many drivers support "video_nr", "radio_nr" or "vbi_nr" module
-options to select specific video/radio/vbi node numbers. This allows the
-user to request that the device node is named e.g. /dev/video5 instead
-of leaving it to chance. When the driver supports multiple devices of
-the same type more than one device node number can be assigned,
-separated by commas:
-
-.. code-block:: none
-
-   # modprobe mydriver video_nr=0,1 radio_nr=0,1
-
-In ``/etc/modules.conf`` this may be written as:
-
-::
-
-    options mydriver video_nr=0,1 radio_nr=0,1
-
-When no device node number is given as module option the driver supplies
-a default.
-
-Normally udev will create the device nodes in /dev automatically for
-you. If udev is not installed, then you need to enable the
-CONFIG_VIDEO_FIXED_MINOR_RANGES kernel option in order to be able to
-correctly relate a minor number to a device node number. I.e., you need
-to be certain that minor number 5 maps to device node name video5. With
-this kernel option different device types have different minor number
-ranges. These ranges are listed in :ref:`devices`.
-
-The creation of character special files (with mknod) is a privileged
-operation and devices cannot be opened by major and minor number. That
-means applications cannot *reliably* scan for loaded or installed
-drivers. The user must enter a device name, or the application can try
-the conventional device names.
-
-
-.. _related:
-
-Related Devices
-===============
-
-Devices can support several functions. For example video capturing, VBI
-capturing and radio support.
-
-The V4L2 API creates different nodes for each of these functions.
-
-The V4L2 API was designed with the idea that one device node could
-support all functions. However, in practice this never worked: this
-'feature' was never used by applications and many drivers did not
-support it and if they did it was certainly never tested. In addition,
-switching a device node between different functions only works when
-using the streaming I/O API, not with the
-:ref:`read() <func-read>`/\ :ref:`write() <func-write>` API.
-
-Today each device node supports just one function.
-
-Besides video input or output the hardware may also support audio
-sampling or playback. If so, these functions are implemented as ALSA PCM
-devices with optional ALSA audio mixer devices.
-
-One problem with all these devices is that the V4L2 API makes no
-provisions to find these related devices. Some really complex devices
-use the Media Controller (see :ref:`media_controller`) which can be
-used for this purpose. But most drivers do not use it, and while some
-code exists that uses sysfs to discover related devices (see
-libmedia_dev in the
-`v4l-utils <http://git.linuxtv.org/cgit.cgi/v4l-utils.git/>`__ git
-repository), there is no library yet that can provide a single API
-towards both Media Controller-based devices and devices that do not use
-the Media Controller. If you want to work on this please write to the
-linux-media mailing list:
-`https://linuxtv.org/lists.php <https://linuxtv.org/lists.php>`__.
-
-
-Multiple Opens
-==============
-
-V4L2 devices can be opened more than once. [#f1]_ When this is supported
-by the driver, users can for example start a "panel" application to
-change controls like brightness or audio volume, while another
-application captures video and audio. In other words, panel applications
-are comparable to an ALSA audio mixer application. Just opening a V4L2
-device should not change the state of the device. [#f2]_
-
-Once an application has allocated the memory buffers needed for
-streaming data (by calling the :ref:`VIDIOC_REQBUFS`
-or :ref:`VIDIOC_CREATE_BUFS` ioctls, or
-implicitly by calling the :ref:`read() <func-read>` or
-:ref:`write() <func-write>` functions) that application (filehandle)
-becomes the owner of the device. It is no longer allowed to make changes
-that would affect the buffer sizes (e.g. by calling the
-:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl) and other applications are
-no longer allowed to allocate buffers or start or stop streaming. The
-EBUSY error code will be returned instead.
-
-Merely opening a V4L2 device does not grant exclusive access. [#f3]_
-Initiating data exchange however assigns the right to read or write the
-requested type of data, and to change related properties, to this file
-descriptor. Applications can request additional access privileges using
-the priority mechanism described in :ref:`app-pri`.
-
-
-Shared Data Streams
-===================
-
-V4L2 drivers should not support multiple applications reading or writing
-the same data stream on a device by copying buffers, time multiplexing
-or similar means. This is better handled by a proxy application in user
-space.
-
-
-Functions
-=========
-
-To open and close V4L2 devices applications use the
-:ref:`open() <func-open>` and :ref:`close() <func-close>` function,
-respectively. Devices are programmed using the
-:ref:`ioctl() <func-ioctl>` function as explained in the following
-sections.
-
-.. [#f1]
-   There are still some old and obscure drivers that have not been
-   updated to allow for multiple opens. This implies that for such
-   drivers :ref:`open() <func-open>` can return an ``EBUSY`` error code
-   when the device is already in use.
-
-.. [#f2]
-   Unfortunately, opening a radio device often switches the state of the
-   device to radio mode in many drivers. This behavior should be fixed
-   eventually as it violates the V4L2 specification.
-
-.. [#f3]
-   Drivers could recognize the ``O_EXCL`` open flag. Presently this is
-   not required, so applications cannot know if it really works.
diff --git a/Documentation/media/uapi/v4l/pipeline.dot b/Documentation/media/uapi/v4l/pipeline.dot
deleted file mode 100644
index 8c53ce719a14..000000000000
--- a/Documentation/media/uapi/v4l/pipeline.dot
+++ /dev/null
@@ -1,14 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-digraph board {
-	rankdir=TB
-	colorscheme=x11
-	scaler [label="{<scaler_0> 0} | Host\nScaler | {<scaler_1> 1} ", shape=Mrecord, style=filled, fillcolor=lightblue]
-	frontend [label="{<frontend_0> 0} | Host\nFrontend | {<frontend_1> 1}", shape=Mrecord, style=filled, fillcolor=lightblue]
-	sensor [label="Sensor | {<sensor_0> 0}", shape=Mrecord, style=filled, fillcolor=aquamarine]
-	io [label="{<io_0> 0} | V4L I/O", shape=Mrecord, style=filled, fillcolor=aquamarine]
-
-	sensor:sensor_0 -> frontend:frontend_0 [color=blue, label="HQ: 2592x1968\nHS: 1296x984"]
-	frontend:frontend_1 -> scaler:scaler_0 [color=blue, label="HQ: 2592x1968\nHS: 1296x984"]
-	scaler:scaler_1 -> io:io_0 [color=blue, label="HQ: 1280x720\nHS: 1280x720"]
-}
diff --git a/Documentation/media/uapi/v4l/pixfmt-bayer.rst b/Documentation/media/uapi/v4l/pixfmt-bayer.rst
deleted file mode 100644
index 807ab34ba93b..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-bayer.rst
+++ /dev/null
@@ -1,39 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _pixfmt-bayer:
-
-*****************
-Raw Bayer Formats
-*****************
-
-Description
-===========
-
-The raw Bayer formats are used by image sensors before much if any processing is
-performed on the image. The formats contain green, red and blue components, with
-alternating lines of red and green, and blue and green pixels in different
-orders. See also `the Wikipedia article on Bayer filter
-<https://en.wikipedia.org/wiki/Bayer_filter>`__.
-
-
-.. toctree::
-    :maxdepth: 1
-
-    pixfmt-srggb8
-    pixfmt-srggb10
-    pixfmt-srggb10p
-    pixfmt-srggb10alaw8
-    pixfmt-srggb10dpcm8
-    pixfmt-srggb10-ipu3
-    pixfmt-srggb12
-    pixfmt-srggb12p
-    pixfmt-srggb14
-    pixfmt-srggb14p
-    pixfmt-srggb16
diff --git a/Documentation/media/uapi/v4l/pixfmt-cnf4.rst b/Documentation/media/uapi/v4l/pixfmt-cnf4.rst
deleted file mode 100644
index 8f469290c304..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-cnf4.rst
+++ /dev/null
@@ -1,31 +0,0 @@
-.. -*- coding: utf-8; mode: rst -*-
-
-.. _V4L2-PIX-FMT-CNF4:
-
-******************************
-V4L2_PIX_FMT_CNF4 ('CNF4')
-******************************
-
-Depth sensor confidence information as a 4 bits per pixel packed array
-
-Description
-===========
-
-Proprietary format used by Intel RealSense Depth cameras containing depth
-confidence information in range 0-15 with 0 indicating that the sensor was
-unable to resolve any signal and 15 indicating maximum level of confidence for
-the specific sensor (actual error margins might change from sensor to sensor).
-
-Every two consecutive pixels are packed into a single byte.
-Bits 0-3 of byte n refer to confidence value of depth pixel 2*n,
-bits 4-7 to confidence value of depth pixel 2*n+1.
-
-**Bit-packed representation.**
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths: 64 64
-
-    * - Y'\ :sub:`01[3:0]`\ (bits 7--4) Y'\ :sub:`00[3:0]`\ (bits 3--0)
-      - Y'\ :sub:`03[3:0]`\ (bits 7--4) Y'\ :sub:`02[3:0]`\ (bits 3--0)
diff --git a/Documentation/media/uapi/v4l/pixfmt-compressed.rst b/Documentation/media/uapi/v4l/pixfmt-compressed.rst
deleted file mode 100644
index 561bda112809..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-compressed.rst
+++ /dev/null
@@ -1,232 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-******************
-Compressed Formats
-******************
-
-
-.. _compressed-formats:
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. flat-table:: Compressed Image Formats
-    :header-rows:  1
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - Identifier
-      - Code
-      - Details
-    * .. _V4L2-PIX-FMT-JPEG:
-
-      - ``V4L2_PIX_FMT_JPEG``
-      - 'JPEG'
-      - TBD. See also :ref:`VIDIOC_G_JPEGCOMP <VIDIOC_G_JPEGCOMP>`,
-	:ref:`VIDIOC_S_JPEGCOMP <VIDIOC_G_JPEGCOMP>`.
-    * .. _V4L2-PIX-FMT-MPEG:
-
-      - ``V4L2_PIX_FMT_MPEG``
-      - 'MPEG'
-      - MPEG multiplexed stream. The actual format is determined by
-	extended control ``V4L2_CID_MPEG_STREAM_TYPE``, see
-	:ref:`mpeg-control-id`.
-    * .. _V4L2-PIX-FMT-H264:
-
-      - ``V4L2_PIX_FMT_H264``
-      - 'H264'
-      - H264 Access Unit.
-	The decoder expects one Access Unit per buffer.
-	The encoder generates one Access Unit per buffer.
-	If :ref:`VIDIOC_ENUM_FMT` reports ``V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM``
-	then the decoder has no requirements since it can parse all the
-	information from the raw bytestream.
-    * .. _V4L2-PIX-FMT-H264-NO-SC:
-
-      - ``V4L2_PIX_FMT_H264_NO_SC``
-      - 'AVC1'
-      - H264 video elementary stream without start codes.
-    * .. _V4L2-PIX-FMT-H264-MVC:
-
-      - ``V4L2_PIX_FMT_H264_MVC``
-      - 'M264'
-      - H264 MVC video elementary stream.
-    * .. _V4L2-PIX-FMT-H264-SLICE:
-
-      - ``V4L2_PIX_FMT_H264_SLICE``
-      - 'S264'
-      - H264 parsed slice data, including slice headers, either with or
-	without the start code, as extracted from the H264 bitstream.
-	This format is adapted for stateless video decoders that implement an
-	H264 pipeline (using the :ref:`mem2mem` and :ref:`media-request-api`).
-	This pixelformat has two modifiers that must be set at least once
-	through the ``V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE``
-        and ``V4L2_CID_MPEG_VIDEO_H264_START_CODE`` controls.
-	In addition, metadata associated with the frame to decode are
-	required to be passed through the ``V4L2_CID_MPEG_VIDEO_H264_SPS``,
-	``V4L2_CID_MPEG_VIDEO_H264_PPS``,
-	``V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX``,
-	``V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS`` and
-	``V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS`` controls.  See the
-	:ref:`associated Codec Control IDs <v4l2-mpeg-h264>`.  Exactly
-	one output and one capture buffer must be provided for use
-	with this pixel format. The output buffer must contain the
-	appropriate number of macroblocks to decode a full
-	corresponding frame to the matching capture buffer.
-
-	The syntax for this format is documented in :ref:`h264`, section
-	7.3.2.8 "Slice layer without partitioning RBSP syntax" and the following
-	sections.
-
-	.. note::
-
-	   This format is not yet part of the public kernel API and it
-	   is expected to change.
-
-    * .. _V4L2-PIX-FMT-H263:
-
-      - ``V4L2_PIX_FMT_H263``
-      - 'H263'
-      - H263 video elementary stream.
-    * .. _V4L2-PIX-FMT-MPEG1:
-
-      - ``V4L2_PIX_FMT_MPEG1``
-      - 'MPG1'
-      - MPEG1 Picture. Each buffer starts with a Picture header, followed
-	by other headers as needed and ending with the Picture data.
-	If :ref:`VIDIOC_ENUM_FMT` reports ``V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM``
-	then the decoder has no requirements since it can parse all the
-	information from the raw bytestream.
-    * .. _V4L2-PIX-FMT-MPEG2:
-
-      - ``V4L2_PIX_FMT_MPEG2``
-      - 'MPG2'
-      - MPEG2 Picture. Each buffer starts with a Picture header, followed
-	by other headers as needed and ending with the Picture data.
-	If :ref:`VIDIOC_ENUM_FMT` reports ``V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM``
-	then the decoder has no requirements since it can parse all the
-	information from the raw bytestream.
-    * .. _V4L2-PIX-FMT-MPEG2-SLICE:
-
-      - ``V4L2_PIX_FMT_MPEG2_SLICE``
-      - 'MG2S'
-      - MPEG-2 parsed slice data, as extracted from the MPEG-2 bitstream.
-	This format is adapted for stateless video decoders that implement a
-	MPEG-2 pipeline (using the :ref:`mem2mem` and :ref:`media-request-api`).
-	Metadata associated with the frame to decode is required to be passed
-	through the ``V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS`` control and
-	quantization matrices can optionally be specified through the
-	``V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION`` control.
-	See the :ref:`associated Codec Control IDs <v4l2-mpeg-mpeg2>`.
-	Exactly one output and one capture buffer must be provided for use with
-	this pixel format. The output buffer must contain the appropriate number
-	of macroblocks to decode a full corresponding frame to the matching
-	capture buffer.
-    * .. _V4L2-PIX-FMT-MPEG4:
-
-      - ``V4L2_PIX_FMT_MPEG4``
-      - 'MPG4'
-      - MPEG4 video elementary stream.
-    * .. _V4L2-PIX-FMT-XVID:
-
-      - ``V4L2_PIX_FMT_XVID``
-      - 'XVID'
-      - Xvid video elementary stream.
-    * .. _V4L2-PIX-FMT-VC1-ANNEX-G:
-
-      - ``V4L2_PIX_FMT_VC1_ANNEX_G``
-      - 'VC1G'
-      - VC1, SMPTE 421M Annex G compliant stream.
-    * .. _V4L2-PIX-FMT-VC1-ANNEX-L:
-
-      - ``V4L2_PIX_FMT_VC1_ANNEX_L``
-      - 'VC1L'
-      - VC1, SMPTE 421M Annex L compliant stream.
-    * .. _V4L2-PIX-FMT-VP8:
-
-      - ``V4L2_PIX_FMT_VP8``
-      - 'VP80'
-      - VP8 compressed video frame. The encoder generates one
-	compressed frame per buffer, and the decoder requires one
-	compressed frame per buffer.
-    * .. _V4L2-PIX-FMT-VP8-FRAME:
-
-      - ``V4L2_PIX_FMT_VP8_FRAME``
-      - 'VP8F'
-      - VP8 parsed frame, as extracted from the container.
-	This format is adapted for stateless video decoders that implement a
-	VP8 pipeline (using the :ref:`mem2mem` and :ref:`media-request-api`).
-	Metadata associated with the frame to decode is required to be passed
-	through the ``V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER`` control.
-	See the :ref:`associated Codec Control IDs <v4l2-mpeg-vp8>`.
-	Exactly one output and one capture buffer must be provided for use with
-	this pixel format. The output buffer must contain the appropriate number
-	of macroblocks to decode a full corresponding frame to the matching
-	capture buffer.
-
-	.. note::
-
-	   This format is not yet part of the public kernel API and it
-	   is expected to change.
-
-    * .. _V4L2-PIX-FMT-VP9:
-
-      - ``V4L2_PIX_FMT_VP9``
-      - 'VP90'
-      - VP9 compressed video frame. The encoder generates one
-	compressed frame per buffer, and the decoder requires one
-	compressed frame per buffer.
-    * .. _V4L2-PIX-FMT-HEVC:
-
-      - ``V4L2_PIX_FMT_HEVC``
-      - 'HEVC'
-      - HEVC/H.265 Access Unit.
-	The decoder expects one Access Unit per buffer.
-	The encoder generates one Access Unit per buffer.
-	If :ref:`VIDIOC_ENUM_FMT` reports ``V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM``
-	then the decoder has no	requirements since it can parse all the
-	information from the raw bytestream.
-    * .. _V4L2-PIX-FMT-HEVC-SLICE:
-
-      - ``V4L2_PIX_FMT_HEVC_SLICE``
-      - 'S265'
-      - HEVC parsed slice data, as extracted from the HEVC bitstream.
-	This format is adapted for stateless video decoders that implement a
-	HEVC pipeline (using the :ref:`mem2mem` and :ref:`media-request-api`).
-	This pixelformat has two modifiers that must be set at least once
-	through the ``V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE``
-        and ``V4L2_CID_MPEG_VIDEO_HEVC_START_CODE`` controls.
-	Metadata associated with the frame to decode is required to be passed
-	through the following controls :
-        * ``V4L2_CID_MPEG_VIDEO_HEVC_SPS``
-        * ``V4L2_CID_MPEG_VIDEO_HEVC_PPS``
-        * ``V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS``
-	See the :ref:`associated Codec Control IDs <v4l2-mpeg-hevc>`.
-	Buffers associated with this pixel format must contain the appropriate
-	number of macroblocks to decode a full corresponding frame.
-
-	.. note::
-
-	   This format is not yet part of the public kernel API and it
-	   is expected to change.
-    * .. _V4L2-PIX-FMT-FWHT:
-
-      - ``V4L2_PIX_FMT_FWHT``
-      - 'FWHT'
-      - Video elementary stream using a codec based on the Fast Walsh Hadamard
-        Transform. This codec is implemented by the vicodec ('Virtual Codec')
-	driver. See the codec-fwht.h header for more details.
-	:ref:`VIDIOC_ENUM_FMT` reports ``V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM``
-	since the decoder can parse all the information from the raw bytestream.
-    * .. _V4L2-PIX-FMT-FWHT-STATELESS:
-
-      - ``V4L2_PIX_FMT_FWHT_STATELESS``
-      - 'SFWH'
-      - Same format as V4L2_PIX_FMT_FWHT but requires stateless codec implementation.
-	See the :ref:`associated Codec Control IDs <v4l2-mpeg-fwht>`.
diff --git a/Documentation/media/uapi/v4l/pixfmt-grey.rst b/Documentation/media/uapi/v4l/pixfmt-grey.rst
deleted file mode 100644
index 3a8156164d39..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-grey.rst
+++ /dev/null
@@ -1,51 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-GREY:
-
-**************************
-V4L2_PIX_FMT_GREY ('GREY')
-**************************
-
-Grey-scale image
-
-
-Description
-===========
-
-This is a grey-scale image. It is really a degenerate Y'CbCr format
-which simply contains no Cb or Cr data.
-
-**Byte Order.**
-Each cell is one byte.
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - start + 0:
-      - Y'\ :sub:`00`
-      - Y'\ :sub:`01`
-      - Y'\ :sub:`02`
-      - Y'\ :sub:`03`
-    * - start + 4:
-      - Y'\ :sub:`10`
-      - Y'\ :sub:`11`
-      - Y'\ :sub:`12`
-      - Y'\ :sub:`13`
-    * - start + 8:
-      - Y'\ :sub:`20`
-      - Y'\ :sub:`21`
-      - Y'\ :sub:`22`
-      - Y'\ :sub:`23`
-    * - start + 12:
-      - Y'\ :sub:`30`
-      - Y'\ :sub:`31`
-      - Y'\ :sub:`32`
-      - Y'\ :sub:`33`
diff --git a/Documentation/media/uapi/v4l/pixfmt-indexed.rst b/Documentation/media/uapi/v4l/pixfmt-indexed.rst
deleted file mode 100644
index 4538b425a046..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-indexed.rst
+++ /dev/null
@@ -1,54 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _pixfmt-indexed:
-
-**************
-Indexed Format
-**************
-
-In this format each pixel is represented by an 8 bit index into a 256
-entry ARGB palette. It is intended for
-:ref:`Video Output Overlays <osd>` only. There are no ioctls to access
-the palette, this must be done with ioctls of the Linux framebuffer API.
-
-
-
-.. flat-table:: Indexed Image Format
-    :header-rows:  2
-    :stub-columns: 0
-
-    * - Identifier
-      - Code
-      -
-      - :cspan:`7` Byte 0
-    * -
-      -
-      - Bit
-      - 7
-      - 6
-      - 5
-      - 4
-      - 3
-      - 2
-      - 1
-      - 0
-    * .. _V4L2-PIX-FMT-PAL8:
-
-      - ``V4L2_PIX_FMT_PAL8``
-      - 'PAL8'
-      -
-      - i\ :sub:`7`
-      - i\ :sub:`6`
-      - i\ :sub:`5`
-      - i\ :sub:`4`
-      - i\ :sub:`3`
-      - i\ :sub:`2`
-      - i\ :sub:`1`
-      - i\ :sub:`0`
diff --git a/Documentation/media/uapi/v4l/pixfmt-intro.rst b/Documentation/media/uapi/v4l/pixfmt-intro.rst
deleted file mode 100644
index ca0a6e0d8959..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-intro.rst
+++ /dev/null
@@ -1,58 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-**********************
-Standard Image Formats
-**********************
-
-In order to exchange images between drivers and applications, it is
-necessary to have standard image data formats which both sides will
-interpret the same way. V4L2 includes several such formats, and this
-section is intended to be an unambiguous specification of the standard
-image data formats in V4L2.
-
-V4L2 drivers are not limited to these formats, however. Driver-specific
-formats are possible. In that case the application may depend on a codec
-to convert images to one of the standard formats when needed. But the
-data can still be stored and retrieved in the proprietary format. For
-example, a device may support a proprietary compressed format.
-Applications can still capture and save the data in the compressed
-format, saving much disk space, and later use a codec to convert the
-images to the X Windows screen format when the video is to be displayed.
-
-Even so, ultimately, some standard formats are needed, so the V4L2
-specification would not be complete without well-defined standard
-formats.
-
-The V4L2 standard formats are mainly uncompressed formats. The pixels
-are always arranged in memory from left to right, and from top to
-bottom. The first byte of data in the image buffer is always for the
-leftmost pixel of the topmost row. Following that is the pixel
-immediately to its right, and so on until the end of the top row of
-pixels. Following the rightmost pixel of the row there may be zero or
-more bytes of padding to guarantee that each row of pixel data has a
-certain alignment. Following the pad bytes, if any, is data for the
-leftmost pixel of the second row from the top, and so on. The last row
-has just as many pad bytes after it as the other rows.
-
-In V4L2 each format has an identifier which looks like ``PIX_FMT_XXX``,
-defined in the :ref:`videodev2.h <videodev>` header file. These
-identifiers represent
-:ref:`four character (FourCC) codes <v4l2-fourcc>` which are also
-listed below, however they are not the same as those used in the Windows
-world.
-
-For some formats, data is stored in separate, discontiguous memory
-buffers. Those formats are identified by a separate set of FourCC codes
-and are referred to as "multi-planar formats". For example, a
-:ref:`YUV422 <V4L2-PIX-FMT-YUV422M>` frame is normally stored in one
-memory buffer, but it can also be placed in two or three separate
-buffers, with Y component in one buffer and CbCr components in another
-in the 2-planar version or with each component in its own buffer in the
-3-planar case. Those sub-buffers are referred to as "*planes*".
diff --git a/Documentation/media/uapi/v4l/pixfmt-inzi.rst b/Documentation/media/uapi/v4l/pixfmt-inzi.rst
deleted file mode 100644
index af2940d844ff..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-inzi.rst
+++ /dev/null
@@ -1,89 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-INZI:
-
-**************************
-V4L2_PIX_FMT_INZI ('INZI')
-**************************
-
-Infrared 10-bit linked with Depth 16-bit images
-
-
-Description
-===========
-
-Proprietary multi-planar format used by Intel SR300 Depth cameras, comprise of
-Infrared image followed by Depth data. The pixel definition is 32-bpp,
-with the Depth and Infrared Data split into separate continuous planes of
-identical dimensions.
-
-
-
-The first plane - Infrared data - is stored according to
-:ref:`V4L2_PIX_FMT_Y10 <V4L2-PIX-FMT-Y10>` greyscale format.
-Each pixel is 16-bit cell, with actual data stored in the 10 LSBs
-with values in range 0 to 1023.
-The six remaining MSBs are padded with zeros.
-
-
-The second plane provides 16-bit per-pixel Depth data arranged in
-:ref:`V4L2-PIX-FMT-Z16 <V4L2-PIX-FMT-Z16>` format.
-
-
-**Frame Structure.**
-Each cell is a 16-bit word with more significant data stored at higher
-memory address (byte order is little-endian).
-
-
-.. raw:: latex
-
-    \small
-
-.. tabularcolumns:: |p{2.5cm}|p{2.5cm}|p{2.5cm}|p{2.5cm}|p{2.5cm}|p{2.5cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 1
-    :widths:    1 1 1 1 1 1
-
-    * - Ir\ :sub:`0,0`
-      - Ir\ :sub:`0,1`
-      - Ir\ :sub:`0,2`
-      - ...
-      - ...
-      - ...
-    * - :cspan:`5` ...
-    * - :cspan:`5` Infrared Data
-    * - :cspan:`5` ...
-    * - ...
-      - ...
-      - ...
-      - Ir\ :sub:`n-1,n-3`
-      - Ir\ :sub:`n-1,n-2`
-      - Ir\ :sub:`n-1,n-1`
-    * - Depth\ :sub:`0,0`
-      - Depth\ :sub:`0,1`
-      - Depth\ :sub:`0,2`
-      - ...
-      - ...
-      - ...
-    * - :cspan:`5` ...
-    * - :cspan:`5` Depth Data
-    * - :cspan:`5` ...
-    * - ...
-      - ...
-      - ...
-      - Depth\ :sub:`n-1,n-3`
-      - Depth\ :sub:`n-1,n-2`
-      - Depth\ :sub:`n-1,n-1`
-
-.. raw:: latex
-
-    \normalsize
diff --git a/Documentation/media/uapi/v4l/pixfmt-m420.rst b/Documentation/media/uapi/v4l/pixfmt-m420.rst
deleted file mode 100644
index c2bae959bf51..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-m420.rst
+++ /dev/null
@@ -1,133 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-M420:
-
-**************************
-V4L2_PIX_FMT_M420 ('M420')
-**************************
-
-Format with ½ horizontal and vertical chroma resolution, also known as
-YUV 4:2:0. Hybrid plane line-interleaved layout.
-
-
-Description
-===========
-
-M420 is a YUV format with ½ horizontal and vertical chroma subsampling
-(YUV 4:2:0). Pixels are organized as interleaved luma and chroma planes.
-Two lines of luma data are followed by one line of chroma data.
-
-The luma plane has one byte per pixel. The chroma plane contains
-interleaved CbCr pixels subsampled by ½ in the horizontal and vertical
-directions. Each CbCr pair belongs to four pixels. For example,
-Cb\ :sub:`0`/Cr\ :sub:`0` belongs to Y'\ :sub:`00`, Y'\ :sub:`01`,
-Y'\ :sub:`10`, Y'\ :sub:`11`.
-
-All line lengths are identical: if the Y lines include pad bytes so do
-the CbCr lines.
-
-**Byte Order.**
-Each cell is one byte.
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - start + 0:
-      - Y'\ :sub:`00`
-      - Y'\ :sub:`01`
-      - Y'\ :sub:`02`
-      - Y'\ :sub:`03`
-    * - start + 4:
-      - Y'\ :sub:`10`
-      - Y'\ :sub:`11`
-      - Y'\ :sub:`12`
-      - Y'\ :sub:`13`
-    * - start + 8:
-      - Cb\ :sub:`00`
-      - Cr\ :sub:`00`
-      - Cb\ :sub:`01`
-      - Cr\ :sub:`01`
-    * - start + 16:
-      - Y'\ :sub:`20`
-      - Y'\ :sub:`21`
-      - Y'\ :sub:`22`
-      - Y'\ :sub:`23`
-    * - start + 20:
-      - Y'\ :sub:`30`
-      - Y'\ :sub:`31`
-      - Y'\ :sub:`32`
-      - Y'\ :sub:`33`
-    * - start + 24:
-      - Cb\ :sub:`10`
-      - Cr\ :sub:`10`
-      - Cb\ :sub:`11`
-      - Cr\ :sub:`11`
-
-
-**Color Sample Location:**
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * -
-      - 0
-      -
-      - 1
-      - 2
-      -
-      - 3
-    * - 0
-      - Y
-      -
-      - Y
-      - Y
-      -
-      - Y
-    * -
-      -
-      - C
-      -
-      -
-      - C
-      -
-    * - 1
-      - Y
-      -
-      - Y
-      - Y
-      -
-      - Y
-    * -
-    * - 2
-      - Y
-      -
-      - Y
-      - Y
-      -
-      - Y
-    * -
-      -
-      - C
-      -
-      -
-      - C
-      -
-    * - 3
-      - Y
-      -
-      - Y
-      - Y
-      -
-      - Y
diff --git a/Documentation/media/uapi/v4l/pixfmt-meta-d4xx.rst b/Documentation/media/uapi/v4l/pixfmt-meta-d4xx.rst
deleted file mode 100644
index 87e8fd7d5d02..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-meta-d4xx.rst
+++ /dev/null
@@ -1,220 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _v4l2-meta-fmt-d4xx:
-
-*******************************
-V4L2_META_FMT_D4XX ('D4XX')
-*******************************
-
-Intel D4xx UVC Cameras Metadata
-
-
-Description
-===========
-
-Intel D4xx (D435 and other) cameras include per-frame metadata in their UVC
-payload headers, following the Microsoft(R) UVC extension proposal [1_]. That
-means, that the private D4XX metadata, following the standard UVC header, is
-organised in blocks. D4XX cameras implement several standard block types,
-proposed by Microsoft, and several proprietary ones. Supported standard metadata
-types are MetadataId_CaptureStats (ID 3), MetadataId_CameraExtrinsics (ID 4),
-and MetadataId_CameraIntrinsics (ID 5). For their description see [1_]. This
-document describes proprietary metadata types, used by D4xx cameras.
-
-V4L2_META_FMT_D4XX buffers follow the metadata buffer layout of
-V4L2_META_FMT_UVC with the only difference, that it also includes proprietary
-payload header data. D4xx cameras use bulk transfers and only send one payload
-per frame, therefore their headers cannot be larger than 255 bytes.
-
-Below are proprietary Microsoft style metadata types, used by D4xx cameras,
-where all fields are in little endian order:
-
-.. tabularcolumns:: |p{5.0cm}|p{12.5cm}|
-
-
-.. flat-table:: D4xx metadata
-    :widths: 1 2
-    :header-rows:  1
-    :stub-columns: 0
-
-    * - **Field**
-      - **Description**
-    * - :cspan:`1` *Depth Control*
-    * - __u32 ID
-      - 0x80000000
-    * - __u32 Size
-      - Size in bytes (currently 56)
-    * - __u32 Version
-      - Version of this structure. The documentation herein corresponds to
-        version xxx. The version number will be incremented when new fields are
-        added.
-    * - __u32 Flags
-      - A bitmask of flags: see [2_] below
-    * - __u32 Gain
-      - Gain value in internal units, same as the V4L2_CID_GAIN control, used to
-	capture the frame
-    * - __u32 Exposure
-      - Exposure time (in microseconds) used to capture the frame
-    * - __u32 Laser power
-      - Power of the laser LED 0-360, used for depth measurement
-    * - __u32 AE mode
-      - 0: manual; 1: automatic exposure
-    * - __u32 Exposure priority
-      - Exposure priority value: 0 - constant frame rate
-    * - __u32 AE ROI left
-      - Left border of the AE Region of Interest (all ROI values are in pixels
-	and lie between 0 and maximum width or height respectively)
-    * - __u32 AE ROI right
-      - Right border of the AE Region of Interest
-    * - __u32 AE ROI top
-      - Top border of the AE Region of Interest
-    * - __u32 AE ROI bottom
-      - Bottom border of the AE Region of Interest
-    * - __u32 Preset
-      - Preset selector value, default: 0, unless changed by the user
-    * - __u32 Laser mode
-      - 0: off, 1: on
-    * - :cspan:`1` *Capture Timing*
-    * - __u32 ID
-      - 0x80000001
-    * - __u32 Size
-      - Size in bytes (currently 40)
-    * - __u32 Version
-      - Version of this structure. The documentation herein corresponds to
-        version xxx. The version number will be incremented when new fields are
-        added.
-    * - __u32 Flags
-      - A bitmask of flags: see [3_] below
-    * - __u32 Frame counter
-      - Monotonically increasing counter
-    * - __u32 Optical time
-      - Time in microseconds from the beginning of a frame till its middle
-    * - __u32 Readout time
-      - Time, used to read out a frame in microseconds
-    * - __u32 Exposure time
-      - Frame exposure time in microseconds
-    * - __u32 Frame interval
-      - In microseconds = 1000000 / framerate
-    * - __u32 Pipe latency
-      - Time in microseconds from start of frame to data in USB buffer
-    * - :cspan:`1` *Configuration*
-    * - __u32 ID
-      - 0x80000002
-    * - __u32 Size
-      - Size in bytes (currently 40)
-    * - __u32 Version
-      - Version of this structure. The documentation herein corresponds to
-        version xxx. The version number will be incremented when new fields are
-        added.
-    * - __u32 Flags
-      - A bitmask of flags: see [4_] below
-    * - __u8 Hardware type
-      - Camera hardware version [5_]
-    * - __u8 SKU ID
-      - Camera hardware configuration [6_]
-    * - __u32 Cookie
-      - Internal synchronisation
-    * - __u16 Format
-      - Image format code [7_]
-    * - __u16 Width
-      - Width in pixels
-    * - __u16 Height
-      - Height in pixels
-    * - __u16 Framerate
-      - Requested frame rate per second
-    * - __u16 Trigger
-      - Byte 0: bit 0: depth and RGB are synchronised, bit 1: external trigger
-
-.. _1:
-
-[1] https://docs.microsoft.com/en-us/windows-hardware/drivers/stream/uvc-extensions-1-5
-
-.. _2:
-
-[2] Depth Control flags specify which fields are valid: ::
-
-  0x00000001 Gain
-  0x00000002 Exposure
-  0x00000004 Laser power
-  0x00000008 AE mode
-  0x00000010 Exposure priority
-  0x00000020 AE ROI
-  0x00000040 Preset
-
-.. _3:
-
-[3] Capture Timing flags specify which fields are valid: ::
-
-  0x00000001 Frame counter
-  0x00000002 Optical time
-  0x00000004 Readout time
-  0x00000008 Exposure time
-  0x00000010 Frame interval
-  0x00000020 Pipe latency
-
-.. _4:
-
-[4] Configuration flags specify which fields are valid: ::
-
-  0x00000001 Hardware type
-  0x00000002 SKU ID
-  0x00000004 Cookie
-  0x00000008 Format
-  0x00000010 Width
-  0x00000020 Height
-  0x00000040 Framerate
-  0x00000080 Trigger
-  0x00000100 Cal count
-
-.. _5:
-
-[5] Camera model: ::
-
-  0 DS5
-  1 IVCAM2
-
-.. _6:
-
-[6] 8-bit camera hardware configuration bitfield: ::
-
-  [1:0] depthCamera
-	00: no depth
-	01: standard depth
-	10: wide depth
-	11: reserved
-  [2]   depthIsActive - has a laser projector
-  [3]   RGB presence
-  [4]   Inertial Measurement Unit (IMU) presence
-  [5]   projectorType
-	0: HPTG
-	1: Princeton
-  [6]   0: a projector, 1: an LED
-  [7]   reserved
-
-.. _7:
-
-[7] Image format codes per video streaming interface:
-
-Depth: ::
-
-  1 Z16
-  2 Z
-
-Left sensor: ::
-
-  1 Y8
-  2 UYVY
-  3 R8L8
-  4 Calibration
-  5 W10
-
-Fish Eye sensor: ::
-
-  1 RAW8
diff --git a/Documentation/media/uapi/v4l/pixfmt-meta-intel-ipu3.rst b/Documentation/media/uapi/v4l/pixfmt-meta-intel-ipu3.rst
deleted file mode 100644
index 7fb54339f4a7..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-meta-intel-ipu3.rst
+++ /dev/null
@@ -1,104 +0,0 @@
-.. This file is dual-licensed: you can use it either under the terms
-.. of the GPL 2.0 or the GFDL 1.1+ license, at your option. Note that this
-.. dual licensing only applies to this file, and not this project as a
-.. whole.
-..
-.. a) This file is free software; you can redistribute it and/or
-..    modify it under the terms of the GNU General Public License version
-..    2.0 as published by the Free Software Foundation.
-..
-..    This file is distributed in the hope that it will be useful,
-..    but WITHOUT ANY WARRANTY; without even the implied warranty of
-..    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-..    GNU General Public License version 2.0 for more details.
-..
-.. Or, alternatively,
-..
-.. b) Permission is granted to copy, distribute and/or modify this
-..    document under the terms of the GNU Free Documentation License,
-..    Version 1.1 or any later version published by the Free Software
-..    Foundation, with no Invariant Sections, no Front-Cover Texts
-..    and no Back-Cover Texts. A copy of the license is included at
-..    Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _v4l2-meta-fmt-params:
-.. _v4l2-meta-fmt-stat-3a:
-
-******************************************************************
-V4L2_META_FMT_IPU3_PARAMS ('ip3p'), V4L2_META_FMT_IPU3_3A ('ip3s')
-******************************************************************
-
-.. ipu3_uapi_stats_3a
-
-3A statistics
-=============
-
-The IPU3 ImgU 3A statistics accelerators collect different statistics over
-an input Bayer frame. Those statistics are obtained from the "ipu3-imgu [01] 3a
-stat" metadata capture video nodes, using the :c:type:`v4l2_meta_format`
-interface. They are formatted as described by the :c:type:`ipu3_uapi_stats_3a`
-structure.
-
-The statistics collected are AWB (Auto-white balance) RGBS (Red, Green, Blue and
-Saturation measure) cells, AWB filter response, AF (Auto-focus) filter response,
-and AE (Auto-exposure) histogram.
-
-The struct :c:type:`ipu3_uapi_4a_config` saves all configurable parameters.
-
-.. code-block:: c
-
-	struct ipu3_uapi_stats_3a {
-		struct ipu3_uapi_awb_raw_buffer awb_raw_buffer;
-		struct ipu3_uapi_ae_raw_buffer_aligned ae_raw_buffer[IPU3_UAPI_MAX_STRIPES];
-		struct ipu3_uapi_af_raw_buffer af_raw_buffer;
-		struct ipu3_uapi_awb_fr_raw_buffer awb_fr_raw_buffer;
-		struct ipu3_uapi_4a_config stats_4a_config;
-		__u32 ae_join_buffers;
-		__u8 padding[28];
-		struct ipu3_uapi_stats_3a_bubble_info_per_stripe stats_3a_bubble_per_stripe;
-		struct ipu3_uapi_ff_status stats_3a_status;
-	};
-
-.. ipu3_uapi_params
-
-Pipeline parameters
-===================
-
-The pipeline parameters are passed to the "ipu3-imgu [01] parameters" metadata
-output video nodes, using the :c:type:`v4l2_meta_format` interface. They are
-formatted as described by the :c:type:`ipu3_uapi_params` structure.
-
-Both 3A statistics and pipeline parameters described here are closely tied to
-the underlying camera sub-system (CSS) APIs. They are usually consumed and
-produced by dedicated user space libraries that comprise the important tuning
-tools, thus freeing the developers from being bothered with the low level
-hardware and algorithm details.
-
-.. code-block:: c
-
-	struct ipu3_uapi_params {
-		/* Flags which of the settings below are to be applied */
-		struct ipu3_uapi_flags use;
-
-		/* Accelerator cluster parameters */
-		struct ipu3_uapi_acc_param acc_param;
-
-		/* ISP vector address space parameters */
-		struct ipu3_uapi_isp_lin_vmem_params lin_vmem_params;
-		struct ipu3_uapi_isp_tnr3_vmem_params tnr3_vmem_params;
-		struct ipu3_uapi_isp_xnr3_vmem_params xnr3_vmem_params;
-
-		/* ISP data memory (DMEM) parameters */
-		struct ipu3_uapi_isp_tnr3_params tnr3_dmem_params;
-		struct ipu3_uapi_isp_xnr3_params xnr3_dmem_params;
-
-		/* Optical black level compensation */
-		struct ipu3_uapi_obgrid_param obgrid_param;
-	};
-
-Intel IPU3 ImgU uAPI data types
-===============================
-
-.. kernel-doc:: drivers/staging/media/ipu3/include/intel-ipu3.h
diff --git a/Documentation/media/uapi/v4l/pixfmt-meta-uvc.rst b/Documentation/media/uapi/v4l/pixfmt-meta-uvc.rst
deleted file mode 100644
index 481e4e0e6e1d..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-meta-uvc.rst
+++ /dev/null
@@ -1,58 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _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-meta-vivid.rst b/Documentation/media/uapi/v4l/pixfmt-meta-vivid.rst
deleted file mode 100644
index eed20eaefe24..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-meta-vivid.rst
+++ /dev/null
@@ -1,60 +0,0 @@
-.. This file is dual-licensed: you can use it either under the terms
-.. of the GPL 2.0 or the GFDL 1.1+ license, at your option. Note that this
-.. dual licensing only applies to this file, and not this project as a
-.. whole.
-..
-.. a) This file is free software; you can redistribute it and/or
-..    modify it under the terms of the GNU General Public License as
-..    published by the Free Software Foundation version 2 of
-..    the License.
-..
-..    This file is distributed in the hope that it will be useful,
-..    but WITHOUT ANY WARRANTY; without even the implied warranty of
-..    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-..    GNU General Public License for more details.
-..
-.. Or, alternatively,
-..
-.. b) Permission is granted to copy, distribute and/or modify this
-..    document under the terms of the GNU Free Documentation License,
-..    Version 1.1 or any later version published by the Free Software
-..    Foundation, with no Invariant Sections, no Front-Cover Texts
-..    and no Back-Cover Texts. A copy of the license is included at
-..    Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _v4l2-meta-fmt-vivid:
-
-*******************************
-V4L2_META_FMT_VIVID ('VIVD')
-*******************************
-
-VIVID Metadata Format
-
-
-Description
-===========
-
-This describes metadata format used by the vivid driver.
-
-It sets Brightness, Saturation, Contrast and Hue, each of which maps to
-corresponding controls of the vivid driver with respect to the range and default values.
-
-It contains the following fields:
-
-.. flat-table:: VIVID Metadata
-    :widths: 1 4
-    :header-rows:  1
-    :stub-columns: 0
-
-    * - Field
-      - Description
-    * - u16 brightness;
-      - Image brightness, the value is in the range 0 to 255, with the default value as 128.
-    * - u16 contrast;
-      - Image contrast, the value is in the range 0 to 255, with the default value as 128.
-    * - u16 saturation;
-      - Image color saturation, the value is in the range 0 to 255, with the default value as 128.
-    * - s16 hue;
-      - Image color balance, the value is in the range -128 to 128, with the default value as 0.
diff --git a/Documentation/media/uapi/v4l/pixfmt-meta-vsp1-hgo.rst b/Documentation/media/uapi/v4l/pixfmt-meta-vsp1-hgo.rst
deleted file mode 100644
index f7a861696281..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-meta-vsp1-hgo.rst
+++ /dev/null
@@ -1,175 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _v4l2-meta-fmt-vsp1-hgo:
-
-*******************************
-V4L2_META_FMT_VSP1_HGO ('VSPH')
-*******************************
-
-Renesas R-Car VSP1 1-D Histogram Data
-
-
-Description
-===========
-
-This format describes histogram data generated by the Renesas R-Car VSP1 1-D
-Histogram (HGO) engine.
-
-The VSP1 HGO is a histogram computation engine that can operate on RGB, YCrCb
-or HSV data. It operates on a possibly cropped and subsampled input image and
-computes the minimum, maximum and sum of all pixels as well as per-channel
-histograms.
-
-The HGO can compute histograms independently per channel, on the maximum of the
-three channels (RGB data only) or on the Y channel only (YCbCr only). It can
-additionally output the histogram with 64 or 256 bins, resulting in four
-possible modes of operation.
-
-- In *64 bins normal mode*, the HGO operates on the three channels independently
-  to compute three 64-bins histograms. RGB, YCbCr and HSV image formats are
-  supported.
-- In *64 bins maximum mode*, the HGO operates on the maximum of the (R, G, B)
-  channels to compute a single 64-bins histogram. Only the RGB image format is
-  supported.
-- In *256 bins normal mode*, the HGO operates on the Y channel to compute a
-  single 256-bins histogram. Only the YCbCr image format is supported.
-- In *256 bins maximum mode*, the HGO operates on the maximum of the (R, G, B)
-  channels to compute a single 256-bins histogram. Only the RGB image format is
-  supported.
-
-**Byte Order.**
-All data is stored in memory in little endian format. Each cell in the tables
-contains one byte.
-
-.. flat-table:: VSP1 HGO Data - 64 Bins, Normal Mode (792 bytes)
-    :header-rows:  2
-    :stub-columns: 0
-
-    * - Offset
-      - :cspan:`4` Memory
-    * -
-      - [31:24]
-      - [23:16]
-      - [15:8]
-      - [7:0]
-    * - 0
-      -
-      - R/Cr/H max [7:0]
-      -
-      - R/Cr/H min [7:0]
-    * - 4
-      -
-      - G/Y/S max [7:0]
-      -
-      - G/Y/S min [7:0]
-    * - 8
-      -
-      - B/Cb/V max [7:0]
-      -
-      - B/Cb/V min [7:0]
-    * - 12
-      - :cspan:`4` R/Cr/H sum [31:0]
-    * - 16
-      - :cspan:`4` G/Y/S sum [31:0]
-    * - 20
-      - :cspan:`4` B/Cb/V sum [31:0]
-    * - 24
-      - :cspan:`4` R/Cr/H bin 0 [31:0]
-    * -
-      - :cspan:`4` ...
-    * - 276
-      - :cspan:`4` R/Cr/H bin 63 [31:0]
-    * - 280
-      - :cspan:`4` G/Y/S bin 0 [31:0]
-    * -
-      - :cspan:`4` ...
-    * - 532
-      - :cspan:`4` G/Y/S bin 63 [31:0]
-    * - 536
-      - :cspan:`4` B/Cb/V bin 0 [31:0]
-    * -
-      - :cspan:`4` ...
-    * - 788
-      - :cspan:`4` B/Cb/V bin 63 [31:0]
-
-.. flat-table:: VSP1 HGO Data - 64 Bins, Max Mode (264 bytes)
-    :header-rows:  2
-    :stub-columns: 0
-
-    * - Offset
-      - :cspan:`4` Memory
-    * -
-      - [31:24]
-      - [23:16]
-      - [15:8]
-      - [7:0]
-    * - 0
-      -
-      - max(R,G,B) max [7:0]
-      -
-      - max(R,G,B) min [7:0]
-    * - 4
-      - :cspan:`4` max(R,G,B) sum [31:0]
-    * - 8
-      - :cspan:`4` max(R,G,B) bin 0 [31:0]
-    * -
-      - :cspan:`4` ...
-    * - 260
-      - :cspan:`4` max(R,G,B) bin 63 [31:0]
-
-.. flat-table:: VSP1 HGO Data - 256 Bins, Normal Mode (1032 bytes)
-    :header-rows:  2
-    :stub-columns: 0
-
-    * - Offset
-      - :cspan:`4` Memory
-    * -
-      - [31:24]
-      - [23:16]
-      - [15:8]
-      - [7:0]
-    * - 0
-      -
-      - Y max [7:0]
-      -
-      - Y min [7:0]
-    * - 4
-      - :cspan:`4` Y sum [31:0]
-    * - 8
-      - :cspan:`4` Y bin 0 [31:0]
-    * -
-      - :cspan:`4` ...
-    * - 1028
-      - :cspan:`4` Y bin 255 [31:0]
-
-.. flat-table:: VSP1 HGO Data - 256 Bins, Max Mode (1032 bytes)
-    :header-rows:  2
-    :stub-columns: 0
-
-    * - Offset
-      - :cspan:`4` Memory
-    * -
-      - [31:24]
-      - [23:16]
-      - [15:8]
-      - [7:0]
-    * - 0
-      -
-      - max(R,G,B) max [7:0]
-      -
-      - max(R,G,B) min [7:0]
-    * - 4
-      - :cspan:`4` max(R,G,B) sum [31:0]
-    * - 8
-      - :cspan:`4` max(R,G,B) bin 0 [31:0]
-    * -
-      - :cspan:`4` ...
-    * - 1028
-      - :cspan:`4` max(R,G,B) bin 255 [31:0]
diff --git a/Documentation/media/uapi/v4l/pixfmt-meta-vsp1-hgt.rst b/Documentation/media/uapi/v4l/pixfmt-meta-vsp1-hgt.rst
deleted file mode 100644
index d1a341af9c48..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-meta-vsp1-hgt.rst
+++ /dev/null
@@ -1,136 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _v4l2-meta-fmt-vsp1-hgt:
-
-*******************************
-V4L2_META_FMT_VSP1_HGT ('VSPT')
-*******************************
-
-Renesas R-Car VSP1 2-D Histogram Data
-
-
-Description
-===========
-
-This format describes histogram data generated by the Renesas R-Car VSP1
-2-D Histogram (HGT) engine.
-
-The VSP1 HGT is a histogram computation engine that operates on HSV
-data. It operates on a possibly cropped and subsampled input image and
-computes the sum, maximum and minimum of the S component as well as a
-weighted frequency histogram based on the H and S components.
-
-The histogram is a matrix of 6 Hue and 32 Saturation buckets, 192 in
-total. Each HSV value is added to one or more buckets with a weight
-between 1 and 16 depending on the Hue areas configuration. Finding the
-corresponding buckets is done by inspecting the H and S value independently.
-
-The Saturation position **n** (0 - 31) of the bucket in the matrix is
-found by the expression:
-
-    n = S / 8
-
-The Hue position **m** (0 - 5) of the bucket in the matrix depends on
-how the HGT Hue areas are configured. There are 6 user configurable Hue
-Areas which can be configured to cover overlapping Hue values:
-
-.. raw:: latex
-
-    \small
-
-::
-
-         Area 0       Area 1       Area 2       Area 3       Area 4       Area 5
-        ________     ________     ________     ________     ________     ________
-   \   /|      |\   /|      |\   /|      |\   /|      |\   /|      |\   /|      |\   /
-    \ / |      | \ / |      | \ / |      | \ / |      | \ / |      | \ / |      | \ /
-     X  |      |  X  |      |  X  |      |  X  |      |  X  |      |  X  |      |  X
-    / \ |      | / \ |      | / \ |      | / \ |      | / \ |      | / \ |      | / \
-   /   \|      |/   \|      |/   \|      |/   \|      |/   \|      |/   \|      |/   \
-  5U   0L      0U   1L      1U   2L      2U   3L      3U   4L      4U   5L      5U   0L
-        <0..............................Hue Value............................255>
-
-
-.. raw:: latex
-
-    \normalsize
-
-When two consecutive areas don't overlap (n+1L is equal to nU) the boundary
-value is considered as part of the lower area.
-
-Pixels with a hue value included in the centre of an area (between nL and nU
-included) are attributed to that single area and given a weight of 16. Pixels
-with a hue value included in the overlapping region between two areas (between
-n+1L and nU excluded) are attributed to both areas and given a weight for each
-of these areas proportional to their position along the diagonal lines
-(rounded down).
-
-The Hue area setup must match one of the following constrains:
-
-::
-
-    0L <= 0U <= 1L <= 1U <= 2L <= 2U <= 3L <= 3U <= 4L <= 4U <= 5L <= 5U
-
-::
-
-    0U <= 1L <= 1U <= 2L <= 2U <= 3L <= 3U <= 4L <= 4U <= 5L <= 5U <= 0L
-
-**Byte Order.**
-All data is stored in memory in little endian format. Each cell in the tables
-contains one byte.
-
-.. flat-table:: VSP1 HGT Data - (776 bytes)
-    :header-rows:  2
-    :stub-columns: 0
-
-    * - Offset
-      - :cspan:`4` Memory
-    * -
-      - [31:24]
-      - [23:16]
-      - [15:8]
-      - [7:0]
-    * - 0
-      - -
-      - S max [7:0]
-      - -
-      - S min [7:0]
-    * - 4
-      - :cspan:`4` S sum [31:0]
-    * - 8
-      - :cspan:`4` Histogram bucket (m=0, n=0) [31:0]
-    * - 12
-      - :cspan:`4` Histogram bucket (m=0, n=1) [31:0]
-    * -
-      - :cspan:`4` ...
-    * - 132
-      - :cspan:`4` Histogram bucket (m=0, n=31) [31:0]
-    * - 136
-      - :cspan:`4` Histogram bucket (m=1, n=0) [31:0]
-    * -
-      - :cspan:`4` ...
-    * - 264
-      - :cspan:`4` Histogram bucket (m=2, n=0) [31:0]
-    * -
-      - :cspan:`4` ...
-    * - 392
-      - :cspan:`4` Histogram bucket (m=3, n=0) [31:0]
-    * -
-      - :cspan:`4` ...
-    * - 520
-      - :cspan:`4` Histogram bucket (m=4, n=0) [31:0]
-    * -
-      - :cspan:`4` ...
-    * - 648
-      - :cspan:`4` Histogram bucket (m=5, n=0) [31:0]
-    * -
-      - :cspan:`4` ...
-    * - 772
-      - :cspan:`4` Histogram bucket (m=5, n=31) [31:0]
diff --git a/Documentation/media/uapi/v4l/pixfmt-nv12.rst b/Documentation/media/uapi/v4l/pixfmt-nv12.rst
deleted file mode 100644
index b8c021b07fd2..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-nv12.rst
+++ /dev/null
@@ -1,136 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-NV12:
-.. _V4L2-PIX-FMT-NV21:
-
-******************************************************
-V4L2_PIX_FMT_NV12 ('NV12'), V4L2_PIX_FMT_NV21 ('NV21')
-******************************************************
-
-
-V4L2_PIX_FMT_NV21
-Formats with ½ horizontal and vertical chroma resolution, also known as
-YUV 4:2:0. One luminance and one chrominance plane with alternating
-chroma samples as opposed to ``V4L2_PIX_FMT_YVU420``
-
-
-Description
-===========
-
-These are two-plane versions of the YUV 4:2:0 format. The three
-components are separated into two sub-images or planes. The Y plane is
-first. The Y plane has one byte per pixel. For ``V4L2_PIX_FMT_NV12``, a
-combined CbCr plane immediately follows the Y plane in memory. The CbCr
-plane is the same width, in bytes, as the Y plane (and of the image),
-but is half as tall in pixels. Each CbCr pair belongs to four pixels.
-For example, Cb\ :sub:`0`/Cr\ :sub:`0` belongs to Y'\ :sub:`00`,
-Y'\ :sub:`01`, Y'\ :sub:`10`, Y'\ :sub:`11`. ``V4L2_PIX_FMT_NV21`` is
-the same except the Cb and Cr bytes are swapped, the CrCb plane starts
-with a Cr byte.
-
-If the Y plane has pad bytes after each row, then the CbCr plane has as
-many pad bytes after its rows.
-
-**Byte Order.**
-Each cell is one byte.
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - start + 0:
-      - Y'\ :sub:`00`
-      - Y'\ :sub:`01`
-      - Y'\ :sub:`02`
-      - Y'\ :sub:`03`
-    * - start + 4:
-      - Y'\ :sub:`10`
-      - Y'\ :sub:`11`
-      - Y'\ :sub:`12`
-      - Y'\ :sub:`13`
-    * - start + 8:
-      - Y'\ :sub:`20`
-      - Y'\ :sub:`21`
-      - Y'\ :sub:`22`
-      - Y'\ :sub:`23`
-    * - start + 12:
-      - Y'\ :sub:`30`
-      - Y'\ :sub:`31`
-      - Y'\ :sub:`32`
-      - Y'\ :sub:`33`
-    * - start + 16:
-      - Cb\ :sub:`00`
-      - Cr\ :sub:`00`
-      - Cb\ :sub:`01`
-      - Cr\ :sub:`01`
-    * - start + 20:
-      - Cb\ :sub:`10`
-      - Cr\ :sub:`10`
-      - Cb\ :sub:`11`
-      - Cr\ :sub:`11`
-
-
-**Color Sample Location:**
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * -
-      - 0
-      -
-      - 1
-      - 2
-      -
-      - 3
-    * - 0
-      - Y
-      -
-      - Y
-      - Y
-      -
-      - Y
-    * -
-      -
-      - C
-      -
-      -
-      - C
-      -
-    * - 1
-      - Y
-      -
-      - Y
-      - Y
-      -
-      - Y
-    * -
-    * - 2
-      - Y
-      -
-      - Y
-      - Y
-      -
-      - Y
-    * -
-      -
-      - C
-      -
-      -
-      - C
-      -
-    * - 3
-      - Y
-      -
-      - Y
-      - Y
-      -
-      - Y
diff --git a/Documentation/media/uapi/v4l/pixfmt-nv12m.rst b/Documentation/media/uapi/v4l/pixfmt-nv12m.rst
deleted file mode 100644
index 9b2c5c21280a..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-nv12m.rst
+++ /dev/null
@@ -1,151 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-NV12M:
-.. _v4l2-pix-fmt-nv12mt-16x16:
-.. _V4L2-PIX-FMT-NV21M:
-
-***********************************************************************************
-V4L2_PIX_FMT_NV12M ('NM12'), V4L2_PIX_FMT_NV21M ('NM21'), V4L2_PIX_FMT_NV12MT_16X16
-***********************************************************************************
-
-
-V4L2_PIX_FMT_NV21M
-V4L2_PIX_FMT_NV12MT_16X16
-Variation of ``V4L2_PIX_FMT_NV12`` and ``V4L2_PIX_FMT_NV21`` with planes
-non contiguous in memory.
-
-
-Description
-===========
-
-This is a multi-planar, two-plane version of the YUV 4:2:0 format. The
-three components are separated into two sub-images or planes.
-``V4L2_PIX_FMT_NV12M`` differs from ``V4L2_PIX_FMT_NV12`` in that the
-two planes are non-contiguous in memory, i.e. the chroma plane do not
-necessarily immediately follows the luma plane. The luminance data
-occupies the first plane. The Y plane has one byte per pixel. In the
-second plane there is a chrominance data with alternating chroma
-samples. The CbCr plane is the same width, in bytes, as the Y plane (and
-of the image), but is half as tall in pixels. Each CbCr pair belongs to
-four pixels. For example, Cb\ :sub:`0`/Cr\ :sub:`0` belongs to
-Y'\ :sub:`00`, Y'\ :sub:`01`, Y'\ :sub:`10`, Y'\ :sub:`11`.
-``V4L2_PIX_FMT_NV12MT_16X16`` is the tiled version of
-``V4L2_PIX_FMT_NV12M`` with 16x16 macroblock tiles. Here pixels are
-arranged in 16x16 2D tiles and tiles are arranged in linear order in
-memory. ``V4L2_PIX_FMT_NV21M`` is the same as ``V4L2_PIX_FMT_NV12M``
-except the Cb and Cr bytes are swapped, the CrCb plane starts with a Cr
-byte.
-
-``V4L2_PIX_FMT_NV12M`` is intended to be used only in drivers and
-applications that support the multi-planar API, described in
-:ref:`planar-apis`.
-
-If the Y plane has pad bytes after each row, then the CbCr plane has as
-many pad bytes after its rows.
-
-**Byte Order.**
-Each cell is one byte.
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - start0 + 0:
-      - Y'\ :sub:`00`
-      - Y'\ :sub:`01`
-      - Y'\ :sub:`02`
-      - Y'\ :sub:`03`
-    * - start0 + 4:
-      - Y'\ :sub:`10`
-      - Y'\ :sub:`11`
-      - Y'\ :sub:`12`
-      - Y'\ :sub:`13`
-    * - start0 + 8:
-      - Y'\ :sub:`20`
-      - Y'\ :sub:`21`
-      - Y'\ :sub:`22`
-      - Y'\ :sub:`23`
-    * - start0 + 12:
-      - Y'\ :sub:`30`
-      - Y'\ :sub:`31`
-      - Y'\ :sub:`32`
-      - Y'\ :sub:`33`
-    * -
-    * - start1 + 0:
-      - Cb\ :sub:`00`
-      - Cr\ :sub:`00`
-      - Cb\ :sub:`01`
-      - Cr\ :sub:`01`
-    * - start1 + 4:
-      - Cb\ :sub:`10`
-      - Cr\ :sub:`10`
-      - Cb\ :sub:`11`
-      - Cr\ :sub:`11`
-
-
-**Color Sample Location:**
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * -
-      - 0
-      -
-      - 1
-      - 2
-      -
-      - 3
-    * - 0
-      - Y
-      -
-      - Y
-      - Y
-      -
-      - Y
-    * -
-      -
-      - C
-      -
-      -
-      - C
-      -
-    * - 1
-      - Y
-      -
-      - Y
-      - Y
-      -
-      - Y
-    * -
-    * - 2
-      - Y
-      -
-      - Y
-      - Y
-      -
-      - Y
-    * -
-      -
-      - C
-      -
-      -
-      -
-      - C
-      -
-    * - 3
-      - Y
-      -
-      - Y
-      - Y
-      -
-      - Y
diff --git a/Documentation/media/uapi/v4l/pixfmt-nv12mt.rst b/Documentation/media/uapi/v4l/pixfmt-nv12mt.rst
deleted file mode 100644
index 2092725de33c..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-nv12mt.rst
+++ /dev/null
@@ -1,67 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-NV12MT:
-
-****************************
-V4L2_PIX_FMT_NV12MT ('TM12')
-****************************
-
-Formats with ½ horizontal and vertical chroma resolution. This format
-has two planes - one for luminance and one for chrominance. Chroma
-samples are interleaved. The difference to ``V4L2_PIX_FMT_NV12`` is the
-memory layout. Pixels are grouped in macroblocks of 64x32 size. The
-order of macroblocks in memory is also not standard.
-
-
-Description
-===========
-
-This is the two-plane versions of the YUV 4:2:0 format where data is
-grouped into 64x32 macroblocks. The three components are separated into
-two sub-images or planes. The Y plane has one byte per pixel and pixels
-are grouped into 64x32 macroblocks. The CbCr plane has the same width,
-in bytes, as the Y plane (and the image), but is half as tall in pixels.
-The chroma plane is also grouped into 64x32 macroblocks.
-
-Width of the buffer has to be aligned to the multiple of 128, and height
-alignment is 32. Every four adjacent buffers - two horizontally and two
-vertically are grouped together and are located in memory in Z or
-flipped Z order.
-
-Layout of macroblocks in memory is presented in the following figure.
-
-
-.. _nv12mt:
-
-.. kernel-figure:: nv12mt.svg
-    :alt:    nv12mt.svg
-    :align:  center
-
-    V4L2_PIX_FMT_NV12MT macroblock Z shape memory layout
-
-The requirement that width is multiple of 128 is implemented because,
-the Z shape cannot be cut in half horizontally. In case the vertical
-resolution of macroblocks is odd then the last row of macroblocks is
-arranged in a linear order.
-
-In case of chroma the layout is identical. Cb and Cr samples are
-interleaved. Height of the buffer is aligned to 32.
-
-
-.. _nv12mt_ex:
-
-.. kernel-figure:: nv12mt_example.svg
-    :alt:    nv12mt_example.svg
-    :align:  center
-
-    Example V4L2_PIX_FMT_NV12MT memory layout of macroblocks
-
-Memory layout of macroblocks of ``V4L2_PIX_FMT_NV12MT`` format in most
-extreme case.
diff --git a/Documentation/media/uapi/v4l/pixfmt-nv16.rst b/Documentation/media/uapi/v4l/pixfmt-nv16.rst
deleted file mode 100644
index 5ec4b7fa8f04..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-nv16.rst
+++ /dev/null
@@ -1,160 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-NV16:
-.. _V4L2-PIX-FMT-NV61:
-
-******************************************************
-V4L2_PIX_FMT_NV16 ('NV16'), V4L2_PIX_FMT_NV61 ('NV61')
-******************************************************
-
-V4L2_PIX_FMT_NV61
-Formats with ½ horizontal chroma resolution, also known as YUV 4:2:2.
-One luminance and one chrominance plane with alternating chroma samples
-as opposed to ``V4L2_PIX_FMT_YVU420``
-
-
-Description
-===========
-
-These are two-plane versions of the YUV 4:2:2 format. The three
-components are separated into two sub-images or planes. The Y plane is
-first. The Y plane has one byte per pixel. For ``V4L2_PIX_FMT_NV16``, a
-combined CbCr plane immediately follows the Y plane in memory. The CbCr
-plane is the same width and height, in bytes, as the Y plane (and of the
-image). Each CbCr pair belongs to two pixels. For example,
-Cb\ :sub:`0`/Cr\ :sub:`0` belongs to Y'\ :sub:`00`, Y'\ :sub:`01`.
-``V4L2_PIX_FMT_NV61`` is the same except the Cb and Cr bytes are
-swapped, the CrCb plane starts with a Cr byte.
-
-If the Y plane has pad bytes after each row, then the CbCr plane has as
-many pad bytes after its rows.
-
-**Byte Order.**
-Each cell is one byte.
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - start + 0:
-      - Y'\ :sub:`00`
-      - Y'\ :sub:`01`
-      - Y'\ :sub:`02`
-      - Y'\ :sub:`03`
-    * - start + 4:
-      - Y'\ :sub:`10`
-      - Y'\ :sub:`11`
-      - Y'\ :sub:`12`
-      - Y'\ :sub:`13`
-    * - start + 8:
-      - Y'\ :sub:`20`
-      - Y'\ :sub:`21`
-      - Y'\ :sub:`22`
-      - Y'\ :sub:`23`
-    * - start + 12:
-      - Y'\ :sub:`30`
-      - Y'\ :sub:`31`
-      - Y'\ :sub:`32`
-      - Y'\ :sub:`33`
-    * - start + 16:
-      - Cb\ :sub:`00`
-      - Cr\ :sub:`00`
-      - Cb\ :sub:`01`
-      - Cr\ :sub:`01`
-    * - start + 20:
-      - Cb\ :sub:`10`
-      - Cr\ :sub:`10`
-      - Cb\ :sub:`11`
-      - Cr\ :sub:`11`
-    * - start + 24:
-      - Cb\ :sub:`20`
-      - Cr\ :sub:`20`
-      - Cb\ :sub:`21`
-      - Cr\ :sub:`21`
-    * - start + 28:
-      - Cb\ :sub:`30`
-      - Cr\ :sub:`30`
-      - Cb\ :sub:`31`
-      - Cr\ :sub:`31`
-
-
-**Color Sample Location:**
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * -
-      - 0
-      -
-      - 1
-      - 2
-      -
-      - 3
-    * - 0
-      - Y
-      -
-      - Y
-      - Y
-      -
-      - Y
-    * -
-      -
-      - C
-      -
-      -
-      - C
-      -
-    * - 1
-      - Y
-      -
-      - Y
-      - Y
-      -
-      - Y
-    * -
-      -
-      - C
-      -
-      -
-      - C
-      -
-    * -
-    * - 2
-      - Y
-      -
-      - Y
-      - Y
-      -
-      - Y
-    * -
-      -
-      - C
-      -
-      -
-      - C
-      -
-    * - 3
-      - Y
-      -
-      - Y
-      - Y
-      -
-      - Y
-    * -
-      -
-      - C
-      -
-      -
-      - C
-      -
diff --git a/Documentation/media/uapi/v4l/pixfmt-nv16m.rst b/Documentation/media/uapi/v4l/pixfmt-nv16m.rst
deleted file mode 100644
index 4a63bcf18b70..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-nv16m.rst
+++ /dev/null
@@ -1,164 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-NV16M:
-.. _v4l2-pix-fmt-nv61m:
-
-********************************************************
-V4L2_PIX_FMT_NV16M ('NM16'), V4L2_PIX_FMT_NV61M ('NM61')
-********************************************************
-
-V4L2_PIX_FMT_NV61M
-Variation of ``V4L2_PIX_FMT_NV16`` and ``V4L2_PIX_FMT_NV61`` with planes
-non contiguous in memory.
-
-
-Description
-===========
-
-This is a multi-planar, two-plane version of the YUV 4:2:2 format. The
-three components are separated into two sub-images or planes.
-``V4L2_PIX_FMT_NV16M`` differs from ``V4L2_PIX_FMT_NV16`` in that the
-two planes are non-contiguous in memory, i.e. the chroma plane does not
-necessarily immediately follow the luma plane. The luminance data
-occupies the first plane. The Y plane has one byte per pixel. In the
-second plane there is chrominance data with alternating chroma samples.
-The CbCr plane is the same width and height, in bytes, as the Y plane.
-Each CbCr pair belongs to two pixels. For example,
-Cb\ :sub:`0`/Cr\ :sub:`0` belongs to Y'\ :sub:`00`, Y'\ :sub:`01`.
-``V4L2_PIX_FMT_NV61M`` is the same as ``V4L2_PIX_FMT_NV16M`` except the
-Cb and Cr bytes are swapped, the CrCb plane starts with a Cr byte.
-
-``V4L2_PIX_FMT_NV16M`` and ``V4L2_PIX_FMT_NV61M`` are intended to be
-used only in drivers and applications that support the multi-planar API,
-described in :ref:`planar-apis`.
-
-**Byte Order.**
-Each cell is one byte.
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - start0 + 0:
-      - Y'\ :sub:`00`
-      - Y'\ :sub:`01`
-      - Y'\ :sub:`02`
-      - Y'\ :sub:`03`
-    * - start0 + 4:
-      - Y'\ :sub:`10`
-      - Y'\ :sub:`11`
-      - Y'\ :sub:`12`
-      - Y'\ :sub:`13`
-    * - start0 + 8:
-      - Y'\ :sub:`20`
-      - Y'\ :sub:`21`
-      - Y'\ :sub:`22`
-      - Y'\ :sub:`23`
-    * - start0 + 12:
-      - Y'\ :sub:`30`
-      - Y'\ :sub:`31`
-      - Y'\ :sub:`32`
-      - Y'\ :sub:`33`
-    * -
-    * - start1 + 0:
-      - Cb\ :sub:`00`
-      - Cr\ :sub:`00`
-      - Cb\ :sub:`02`
-      - Cr\ :sub:`02`
-    * - start1 + 4:
-      - Cb\ :sub:`10`
-      - Cr\ :sub:`10`
-      - Cb\ :sub:`12`
-      - Cr\ :sub:`12`
-    * - start1 + 8:
-      - Cb\ :sub:`20`
-      - Cr\ :sub:`20`
-      - Cb\ :sub:`22`
-      - Cr\ :sub:`22`
-    * - start1 + 12:
-      - Cb\ :sub:`30`
-      - Cr\ :sub:`30`
-      - Cb\ :sub:`32`
-      - Cr\ :sub:`32`
-
-
-**Color Sample Location:**
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * -
-      - 0
-      -
-      - 1
-      - 2
-      -
-      - 3
-    * - 0
-      - Y
-      -
-      - Y
-      - Y
-      -
-      - Y
-    * -
-      -
-      - C
-      -
-      -
-      - C
-      -
-    * - 1
-      - Y
-      -
-      - Y
-      - Y
-      -
-      - Y
-    * -
-      -
-      - C
-      -
-      -
-      - C
-      -
-    * -
-    * - 2
-      - Y
-      -
-      - Y
-      - Y
-      -
-      - Y
-    * -
-      -
-      - C
-      -
-      -
-      - C
-      -
-    * - 3
-      - Y
-      -
-      - Y
-      - Y
-      -
-      - Y
-    * -
-      -
-      - C
-      -
-      -
-      - C
-      -
diff --git a/Documentation/media/uapi/v4l/pixfmt-nv24.rst b/Documentation/media/uapi/v4l/pixfmt-nv24.rst
deleted file mode 100644
index 13fc6fe1a3d6..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-nv24.rst
+++ /dev/null
@@ -1,102 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-NV24:
-.. _V4L2-PIX-FMT-NV42:
-
-******************************************************
-V4L2_PIX_FMT_NV24 ('NV24'), V4L2_PIX_FMT_NV42 ('NV42')
-******************************************************
-
-V4L2_PIX_FMT_NV42
-Formats with full horizontal and vertical chroma resolutions, also known
-as YUV 4:4:4. One luminance and one chrominance plane with alternating
-chroma samples as opposed to ``V4L2_PIX_FMT_YVU420``
-
-
-Description
-===========
-
-These are two-plane versions of the YUV 4:4:4 format. The three
-components are separated into two sub-images or planes. The Y plane is
-first, with each Y sample stored in one byte per pixel. For
-``V4L2_PIX_FMT_NV24``, a combined CbCr plane immediately follows the Y
-plane in memory. The CbCr plane has the same width and height, in
-pixels, as the Y plane (and the image). Each line contains one CbCr pair
-per pixel, with each Cb and Cr sample stored in one byte.
-``V4L2_PIX_FMT_NV42`` is the same except that the Cb and Cr samples are
-swapped, the CrCb plane starts with a Cr sample.
-
-If the Y plane has pad bytes after each row, then the CbCr plane has
-twice as many pad bytes after its rows.
-
-**Byte Order.**
-Each cell is one byte.
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - start + 0:
-      - Y'\ :sub:`00`
-      - Y'\ :sub:`01`
-      - Y'\ :sub:`02`
-      - Y'\ :sub:`03`
-    * - start + 4:
-      - Y'\ :sub:`10`
-      - Y'\ :sub:`11`
-      - Y'\ :sub:`12`
-      - Y'\ :sub:`13`
-    * - start + 8:
-      - Y'\ :sub:`20`
-      - Y'\ :sub:`21`
-      - Y'\ :sub:`22`
-      - Y'\ :sub:`23`
-    * - start + 12:
-      - Y'\ :sub:`30`
-      - Y'\ :sub:`31`
-      - Y'\ :sub:`32`
-      - Y'\ :sub:`33`
-    * - start + 16:
-      - Cb\ :sub:`00`
-      - Cr\ :sub:`00`
-      - Cb\ :sub:`01`
-      - Cr\ :sub:`01`
-      - Cb\ :sub:`02`
-      - Cr\ :sub:`02`
-      - Cb\ :sub:`03`
-      - Cr\ :sub:`03`
-    * - start + 24:
-      - Cb\ :sub:`10`
-      - Cr\ :sub:`10`
-      - Cb\ :sub:`11`
-      - Cr\ :sub:`11`
-      - Cb\ :sub:`12`
-      - Cr\ :sub:`12`
-      - Cb\ :sub:`13`
-      - Cr\ :sub:`13`
-    * - start + 32:
-      - Cb\ :sub:`20`
-      - Cr\ :sub:`20`
-      - Cb\ :sub:`21`
-      - Cr\ :sub:`21`
-      - Cb\ :sub:`22`
-      - Cr\ :sub:`22`
-      - Cb\ :sub:`23`
-      - Cr\ :sub:`23`
-    * - start + 40:
-      - Cb\ :sub:`30`
-      - Cr\ :sub:`30`
-      - Cb\ :sub:`31`
-      - Cr\ :sub:`31`
-      - Cb\ :sub:`32`
-      - Cr\ :sub:`32`
-      - Cb\ :sub:`33`
-      - Cr\ :sub:`33`
diff --git a/Documentation/media/uapi/v4l/pixfmt-packed-hsv.rst b/Documentation/media/uapi/v4l/pixfmt-packed-hsv.rst
deleted file mode 100644
index dfc4a8367b3d..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-packed-hsv.rst
+++ /dev/null
@@ -1,164 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _packed-hsv:
-
-******************
-Packed HSV formats
-******************
-
-Description
-===========
-
-The *hue* (h) is measured in degrees, the equivalence between degrees and LSBs
-depends on the hsv-encoding used, see :ref:`colorspaces`.
-The *saturation* (s) and the *value* (v) are measured in percentage of the
-cylinder: 0 being the smallest value and 255 the maximum.
-
-
-The values are packed in 24 or 32 bit formats.
-
-
-.. raw:: latex
-
-    \begingroup
-    \tiny
-    \setlength{\tabcolsep}{2pt}
-
-.. tabularcolumns:: |p{2.6cm}|p{0.8cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|
-
-.. _packed-hsv-formats:
-
-.. flat-table:: Packed HSV Image Formats
-    :header-rows:  2
-    :stub-columns: 0
-
-    * - Identifier
-      - Code
-      -
-      - :cspan:`7` Byte 0 in memory
-      - :cspan:`7` Byte 1
-      - :cspan:`7` Byte 2
-      - :cspan:`7` Byte 3
-    * -
-      -
-      - Bit
-      - 7
-      - 6
-      - 5
-      - 4
-      - 3
-      - 2
-      - 1
-      - 0
-
-      - 7
-      - 6
-      - 5
-      - 4
-      - 3
-      - 2
-      - 1
-      - 0
-
-      - 7
-      - 6
-      - 5
-      - 4
-      - 3
-      - 2
-      - 1
-      - 0
-
-      - 7
-      - 6
-      - 5
-      - 4
-      - 3
-      - 2
-      - 1
-      - 0
-    * .. _V4L2-PIX-FMT-HSV32:
-
-      - ``V4L2_PIX_FMT_HSV32``
-      - 'HSV4'
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-
-      - h\ :sub:`7`
-      - h\ :sub:`6`
-      - h\ :sub:`5`
-      - h\ :sub:`4`
-      - h\ :sub:`3`
-      - h\ :sub:`2`
-      - h\ :sub:`1`
-      - h\ :sub:`0`
-
-      - s\ :sub:`7`
-      - s\ :sub:`6`
-      - s\ :sub:`5`
-      - s\ :sub:`4`
-      - s\ :sub:`3`
-      - s\ :sub:`2`
-      - s\ :sub:`1`
-      - s\ :sub:`0`
-
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-    * .. _V4L2-PIX-FMT-HSV24:
-
-      - ``V4L2_PIX_FMT_HSV24``
-      - 'HSV3'
-      -
-      - h\ :sub:`7`
-      - h\ :sub:`6`
-      - h\ :sub:`5`
-      - h\ :sub:`4`
-      - h\ :sub:`3`
-      - h\ :sub:`2`
-      - h\ :sub:`1`
-      - h\ :sub:`0`
-
-      - s\ :sub:`7`
-      - s\ :sub:`6`
-      - s\ :sub:`5`
-      - s\ :sub:`4`
-      - s\ :sub:`3`
-      - s\ :sub:`2`
-      - s\ :sub:`1`
-      - s\ :sub:`0`
-
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-      -
-
-.. raw:: latex
-
-    \endgroup
-
-Bit 7 is the most significant bit.
diff --git a/Documentation/media/uapi/v4l/pixfmt-packed-yuv.rst b/Documentation/media/uapi/v4l/pixfmt-packed-yuv.rst
deleted file mode 100644
index 41b60fae703a..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-packed-yuv.rst
+++ /dev/null
@@ -1,380 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _packed-yuv:
-
-******************
-Packed YUV formats
-******************
-
-Description
-===========
-
-Similar to the packed RGB formats these formats store the Y, Cb and Cr
-component of each pixel in one 16 or 32 bit word.
-
-
-.. raw:: latex
-
-    \begingroup
-    \tiny
-    \setlength{\tabcolsep}{2pt}
-
-.. _packed-yuv-formats:
-
-.. tabularcolumns:: |p{2.5cm}|p{0.69cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|
-
-.. flat-table:: Packed YUV Image Formats
-    :header-rows:  2
-    :stub-columns: 0
-
-    * - Identifier
-      - Code
-
-      - :cspan:`7` Byte 0 in memory
-
-      - :cspan:`7` Byte 1
-
-      - :cspan:`7` Byte 2
-
-      - :cspan:`7` Byte 3
-
-    * -
-      -
-      - 7
-      - 6
-      - 5
-      - 4
-      - 3
-      - 2
-      - 1
-      - 0
-
-      - 7
-      - 6
-      - 5
-      - 4
-      - 3
-      - 2
-      - 1
-      - 0
-
-      - 7
-      - 6
-      - 5
-      - 4
-      - 3
-      - 2
-      - 1
-      - 0
-
-      - 7
-      - 6
-      - 5
-      - 4
-      - 3
-      - 2
-      - 1
-      - 0
-
-    * .. _V4L2-PIX-FMT-YUV444:
-
-      - ``V4L2_PIX_FMT_YUV444``
-      - 'Y444'
-
-      - Cb\ :sub:`3`
-      - Cb\ :sub:`2`
-      - Cb\ :sub:`1`
-      - Cb\ :sub:`0`
-      - Cr\ :sub:`3`
-      - Cr\ :sub:`2`
-      - Cr\ :sub:`1`
-      - Cr\ :sub:`0`
-
-      - a\ :sub:`3`
-      - a\ :sub:`2`
-      - a\ :sub:`1`
-      - a\ :sub:`0`
-      - Y'\ :sub:`3`
-      - Y'\ :sub:`2`
-      - Y'\ :sub:`1`
-      - Y'\ :sub:`0`
-
-      -  :cspan:`15`
-
-    * .. _V4L2-PIX-FMT-YUV555:
-
-      - ``V4L2_PIX_FMT_YUV555``
-      - 'YUVO'
-
-      - Cb\ :sub:`2`
-      - Cb\ :sub:`1`
-      - Cb\ :sub:`0`
-      - Cr\ :sub:`4`
-      - Cr\ :sub:`3`
-      - Cr\ :sub:`2`
-      - Cr\ :sub:`1`
-      - Cr\ :sub:`0`
-
-      - a
-      - Y'\ :sub:`4`
-      - Y'\ :sub:`3`
-      - Y'\ :sub:`2`
-      - Y'\ :sub:`1`
-      - Y'\ :sub:`0`
-      - Cb\ :sub:`4`
-      - Cb\ :sub:`3`
-
-      -  :cspan:`15`
-    * .. _V4L2-PIX-FMT-YUV565:
-
-      - ``V4L2_PIX_FMT_YUV565``
-      - 'YUVP'
-
-      - Cb\ :sub:`2`
-      - Cb\ :sub:`1`
-      - Cb\ :sub:`0`
-      - Cr\ :sub:`4`
-      - Cr\ :sub:`3`
-      - Cr\ :sub:`2`
-      - Cr\ :sub:`1`
-      - Cr\ :sub:`0`
-
-      - Y'\ :sub:`4`
-      - Y'\ :sub:`3`
-      - Y'\ :sub:`2`
-      - Y'\ :sub:`1`
-      - Y'\ :sub:`0`
-      - Cb\ :sub:`5`
-      - Cb\ :sub:`4`
-      - Cb\ :sub:`3`
-
-      -  :cspan:`15`
-
-    * .. _V4L2-PIX-FMT-YUV32:
-
-      - ``V4L2_PIX_FMT_YUV32``
-      - 'YUV4'
-
-      - a\ :sub:`7`
-      - a\ :sub:`6`
-      - a\ :sub:`5`
-      - a\ :sub:`4`
-      - a\ :sub:`3`
-      - a\ :sub:`2`
-      - a\ :sub:`1`
-      - a\ :sub:`0`
-
-      - Y'\ :sub:`7`
-      - Y'\ :sub:`6`
-      - Y'\ :sub:`5`
-      - Y'\ :sub:`4`
-      - Y'\ :sub:`3`
-      - Y'\ :sub:`2`
-      - Y'\ :sub:`1`
-      - Y'\ :sub:`0`
-
-      - Cb\ :sub:`7`
-      - Cb\ :sub:`6`
-      - Cb\ :sub:`5`
-      - Cb\ :sub:`4`
-      - Cb\ :sub:`3`
-      - Cb\ :sub:`2`
-      - Cb\ :sub:`1`
-      - Cb\ :sub:`0`
-
-      - Cr\ :sub:`7`
-      - Cr\ :sub:`6`
-      - Cr\ :sub:`5`
-      - Cr\ :sub:`4`
-      - Cr\ :sub:`3`
-      - Cr\ :sub:`2`
-      - Cr\ :sub:`1`
-      - Cr\ :sub:`0`
-
-    * .. _V4L2-PIX-FMT-AYUV32:
-
-      - ``V4L2_PIX_FMT_AYUV32``
-      - 'AYUV'
-
-      - a\ :sub:`7`
-      - a\ :sub:`6`
-      - a\ :sub:`5`
-      - a\ :sub:`4`
-      - a\ :sub:`3`
-      - a\ :sub:`2`
-      - a\ :sub:`1`
-      - a\ :sub:`0`
-
-      - Y'\ :sub:`7`
-      - Y'\ :sub:`6`
-      - Y'\ :sub:`5`
-      - Y'\ :sub:`4`
-      - Y'\ :sub:`3`
-      - Y'\ :sub:`2`
-      - Y'\ :sub:`1`
-      - Y'\ :sub:`0`
-
-      - Cb\ :sub:`7`
-      - Cb\ :sub:`6`
-      - Cb\ :sub:`5`
-      - Cb\ :sub:`4`
-      - Cb\ :sub:`3`
-      - Cb\ :sub:`2`
-      - Cb\ :sub:`1`
-      - Cb\ :sub:`0`
-
-      - Cr\ :sub:`7`
-      - Cr\ :sub:`6`
-      - Cr\ :sub:`5`
-      - Cr\ :sub:`4`
-      - Cr\ :sub:`3`
-      - Cr\ :sub:`2`
-      - Cr\ :sub:`1`
-      - Cr\ :sub:`0`
-
-    * .. _V4L2-PIX-FMT-XYUV32:
-
-      - ``V4L2_PIX_FMT_XYUV32``
-      - 'XYUV'
-
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-
-      - Y'\ :sub:`7`
-      - Y'\ :sub:`6`
-      - Y'\ :sub:`5`
-      - Y'\ :sub:`4`
-      - Y'\ :sub:`3`
-      - Y'\ :sub:`2`
-      - Y'\ :sub:`1`
-      - Y'\ :sub:`0`
-
-      - Cb\ :sub:`7`
-      - Cb\ :sub:`6`
-      - Cb\ :sub:`5`
-      - Cb\ :sub:`4`
-      - Cb\ :sub:`3`
-      - Cb\ :sub:`2`
-      - Cb\ :sub:`1`
-      - Cb\ :sub:`0`
-
-      - Cr\ :sub:`7`
-      - Cr\ :sub:`6`
-      - Cr\ :sub:`5`
-      - Cr\ :sub:`4`
-      - Cr\ :sub:`3`
-      - Cr\ :sub:`2`
-      - Cr\ :sub:`1`
-      - Cr\ :sub:`0`
-
-    * .. _V4L2-PIX-FMT-VUYA32:
-
-      - ``V4L2_PIX_FMT_VUYA32``
-      - 'VUYA'
-
-      - Cr\ :sub:`7`
-      - Cr\ :sub:`6`
-      - Cr\ :sub:`5`
-      - Cr\ :sub:`4`
-      - Cr\ :sub:`3`
-      - Cr\ :sub:`2`
-      - Cr\ :sub:`1`
-      - Cr\ :sub:`0`
-
-      - Cb\ :sub:`7`
-      - Cb\ :sub:`6`
-      - Cb\ :sub:`5`
-      - Cb\ :sub:`4`
-      - Cb\ :sub:`3`
-      - Cb\ :sub:`2`
-      - Cb\ :sub:`1`
-      - Cb\ :sub:`0`
-
-      - Y'\ :sub:`7`
-      - Y'\ :sub:`6`
-      - Y'\ :sub:`5`
-      - Y'\ :sub:`4`
-      - Y'\ :sub:`3`
-      - Y'\ :sub:`2`
-      - Y'\ :sub:`1`
-      - Y'\ :sub:`0`
-
-      - a\ :sub:`7`
-      - a\ :sub:`6`
-      - a\ :sub:`5`
-      - a\ :sub:`4`
-      - a\ :sub:`3`
-      - a\ :sub:`2`
-      - a\ :sub:`1`
-      - a\ :sub:`0`
-
-    * .. _V4L2-PIX-FMT-VUYX32:
-
-      - ``V4L2_PIX_FMT_VUYX32``
-      - 'VUYX'
-
-      - Cr\ :sub:`7`
-      - Cr\ :sub:`6`
-      - Cr\ :sub:`5`
-      - Cr\ :sub:`4`
-      - Cr\ :sub:`3`
-      - Cr\ :sub:`2`
-      - Cr\ :sub:`1`
-      - Cr\ :sub:`0`
-
-      - Cb\ :sub:`7`
-      - Cb\ :sub:`6`
-      - Cb\ :sub:`5`
-      - Cb\ :sub:`4`
-      - Cb\ :sub:`3`
-      - Cb\ :sub:`2`
-      - Cb\ :sub:`1`
-      - Cb\ :sub:`0`
-
-      - Y'\ :sub:`7`
-      - Y'\ :sub:`6`
-      - Y'\ :sub:`5`
-      - Y'\ :sub:`4`
-      - Y'\ :sub:`3`
-      - Y'\ :sub:`2`
-      - Y'\ :sub:`1`
-      - Y'\ :sub:`0`
-
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-
-.. raw:: latex
-
-    \endgroup
-
-.. note::
-
-    #) Bit 7 is the most significant bit;
-
-    #) The value of a = alpha bits is undefined when reading from the driver,
-       ignored when writing to the driver, except when alpha blending has
-       been negotiated for a :ref:`Video Overlay <overlay>` or
-       :ref:`Video Output Overlay <osd>` for the formats Y444, YUV555 and
-       YUV4. However, for formats AYUV32 and VUYA32, the alpha component is
-       expected to contain a meaningful value that can be used by drivers
-       and applications. And, the formats XYUV32 and VUYX32 contain undefined
-       alpha values that must be ignored by all applications and drivers.
diff --git a/Documentation/media/uapi/v4l/pixfmt-reserved.rst b/Documentation/media/uapi/v4l/pixfmt-reserved.rst
deleted file mode 100644
index 7d98a7bf9f1f..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-reserved.rst
+++ /dev/null
@@ -1,282 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _pixfmt-reserved:
-
-***************************
-Reserved Format Identifiers
-***************************
-
-These formats are not defined by this specification, they are just
-listed for reference and to avoid naming conflicts. If you want to
-register your own format, send an e-mail to the linux-media mailing list
-`https://linuxtv.org/lists.php <https://linuxtv.org/lists.php>`__
-for inclusion in the ``videodev2.h`` file. If you want to share your
-format with other developers add a link to your documentation and send a
-copy to the linux-media mailing list for inclusion in this section. If
-you think your format should be listed in a standard format section
-please make a proposal on the linux-media mailing list.
-
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. _reserved-formats:
-
-.. flat-table:: Reserved Image Formats
-    :header-rows:  1
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - Identifier
-      - Code
-      - Details
-    * .. _V4L2-PIX-FMT-DV:
-
-      - ``V4L2_PIX_FMT_DV``
-      - 'dvsd'
-      - unknown
-    * .. _V4L2-PIX-FMT-ET61X251:
-
-      - ``V4L2_PIX_FMT_ET61X251``
-      - 'E625'
-      - Compressed format of the ET61X251 driver.
-    * .. _V4L2-PIX-FMT-HI240:
-
-      - ``V4L2_PIX_FMT_HI240``
-      - 'HI24'
-      - 8 bit RGB format used by the BTTV driver.
-    * .. _V4L2-PIX-FMT-HM12:
-
-      - ``V4L2_PIX_FMT_HM12``
-      - 'HM12'
-      - YUV 4:2:0 format used by the IVTV driver.
-
-	The format is documented in the kernel sources in the file
-	``Documentation/media/v4l-drivers/cx2341x.rst``
-    * .. _V4L2-PIX-FMT-CPIA1:
-
-      - ``V4L2_PIX_FMT_CPIA1``
-      - 'CPIA'
-      - YUV format used by the gspca cpia1 driver.
-    * .. _V4L2-PIX-FMT-JPGL:
-
-      - ``V4L2_PIX_FMT_JPGL``
-      - 'JPGL'
-      - JPEG-Light format (Pegasus Lossless JPEG) used in Divio webcams NW
-	80x.
-    * .. _V4L2-PIX-FMT-SPCA501:
-
-      - ``V4L2_PIX_FMT_SPCA501``
-      - 'S501'
-      - YUYV per line used by the gspca driver.
-    * .. _V4L2-PIX-FMT-SPCA505:
-
-      - ``V4L2_PIX_FMT_SPCA505``
-      - 'S505'
-      - YYUV per line used by the gspca driver.
-    * .. _V4L2-PIX-FMT-SPCA508:
-
-      - ``V4L2_PIX_FMT_SPCA508``
-      - 'S508'
-      - YUVY per line used by the gspca driver.
-    * .. _V4L2-PIX-FMT-SPCA561:
-
-      - ``V4L2_PIX_FMT_SPCA561``
-      - 'S561'
-      - Compressed GBRG Bayer format used by the gspca driver.
-    * .. _V4L2-PIX-FMT-PAC207:
-
-      - ``V4L2_PIX_FMT_PAC207``
-      - 'P207'
-      - Compressed BGGR Bayer format used by the gspca driver.
-    * .. _V4L2-PIX-FMT-MR97310A:
-
-      - ``V4L2_PIX_FMT_MR97310A``
-      - 'M310'
-      - Compressed BGGR Bayer format used by the gspca driver.
-    * .. _V4L2-PIX-FMT-JL2005BCD:
-
-      - ``V4L2_PIX_FMT_JL2005BCD``
-      - 'JL20'
-      - JPEG compressed RGGB Bayer format used by the gspca driver.
-    * .. _V4L2-PIX-FMT-OV511:
-
-      - ``V4L2_PIX_FMT_OV511``
-      - 'O511'
-      - OV511 JPEG format used by the gspca driver.
-    * .. _V4L2-PIX-FMT-OV518:
-
-      - ``V4L2_PIX_FMT_OV518``
-      - 'O518'
-      - OV518 JPEG format used by the gspca driver.
-    * .. _V4L2-PIX-FMT-PJPG:
-
-      - ``V4L2_PIX_FMT_PJPG``
-      - 'PJPG'
-      - Pixart 73xx JPEG format used by the gspca driver.
-    * .. _V4L2-PIX-FMT-SE401:
-
-      - ``V4L2_PIX_FMT_SE401``
-      - 'S401'
-      - Compressed RGB format used by the gspca se401 driver
-    * .. _V4L2-PIX-FMT-SQ905C:
-
-      - ``V4L2_PIX_FMT_SQ905C``
-      - '905C'
-      - Compressed RGGB bayer format used by the gspca driver.
-    * .. _V4L2-PIX-FMT-MJPEG:
-
-      - ``V4L2_PIX_FMT_MJPEG``
-      - 'MJPG'
-      - Compressed format used by the Zoran driver
-    * .. _V4L2-PIX-FMT-PWC1:
-
-      - ``V4L2_PIX_FMT_PWC1``
-      - 'PWC1'
-      - Compressed format of the PWC driver.
-    * .. _V4L2-PIX-FMT-PWC2:
-
-      - ``V4L2_PIX_FMT_PWC2``
-      - 'PWC2'
-      - Compressed format of the PWC driver.
-    * .. _V4L2-PIX-FMT-SN9C10X:
-
-      - ``V4L2_PIX_FMT_SN9C10X``
-      - 'S910'
-      - Compressed format of the SN9C102 driver.
-    * .. _V4L2-PIX-FMT-SN9C20X-I420:
-
-      - ``V4L2_PIX_FMT_SN9C20X_I420``
-      - 'S920'
-      - YUV 4:2:0 format of the gspca sn9c20x driver.
-    * .. _V4L2-PIX-FMT-SN9C2028:
-
-      - ``V4L2_PIX_FMT_SN9C2028``
-      - 'SONX'
-      - Compressed GBRG bayer format of the gspca sn9c2028 driver.
-    * .. _V4L2-PIX-FMT-STV0680:
-
-      - ``V4L2_PIX_FMT_STV0680``
-      - 'S680'
-      - Bayer format of the gspca stv0680 driver.
-    * .. _V4L2-PIX-FMT-WNVA:
-
-      - ``V4L2_PIX_FMT_WNVA``
-      - 'WNVA'
-      - Used by the Winnov Videum driver,
-	`http://www.thedirks.org/winnov/ <http://www.thedirks.org/winnov/>`__
-    * .. _V4L2-PIX-FMT-TM6000:
-
-      - ``V4L2_PIX_FMT_TM6000``
-      - 'TM60'
-      - Used by Trident tm6000
-    * .. _V4L2-PIX-FMT-CIT-YYVYUY:
-
-      - ``V4L2_PIX_FMT_CIT_YYVYUY``
-      - 'CITV'
-      - Used by xirlink CIT, found at IBM webcams.
-
-	Uses one line of Y then 1 line of VYUY
-    * .. _V4L2-PIX-FMT-KONICA420:
-
-      - ``V4L2_PIX_FMT_KONICA420``
-      - 'KONI'
-      - Used by Konica webcams.
-
-	YUV420 planar in blocks of 256 pixels.
-    * .. _V4L2-PIX-FMT-YYUV:
-
-      - ``V4L2_PIX_FMT_YYUV``
-      - 'YYUV'
-      - unknown
-    * .. _V4L2-PIX-FMT-Y4:
-
-      - ``V4L2_PIX_FMT_Y4``
-      - 'Y04 '
-      - Old 4-bit greyscale format. Only the most significant 4 bits of
-	each byte are used, the other bits are set to 0.
-    * .. _V4L2-PIX-FMT-Y6:
-
-      - ``V4L2_PIX_FMT_Y6``
-      - 'Y06 '
-      - Old 6-bit greyscale format. Only the most significant 6 bits of
-	each byte are used, the other bits are set to 0.
-    * .. _V4L2-PIX-FMT-S5C-UYVY-JPG:
-
-      - ``V4L2_PIX_FMT_S5C_UYVY_JPG``
-      - 'S5CI'
-      - Two-planar format used by Samsung S5C73MX cameras. The first plane
-	contains interleaved JPEG and UYVY image data, followed by meta
-	data in form of an array of offsets to the UYVY data blocks. The
-	actual pointer array follows immediately the interleaved JPEG/UYVY
-	data, the number of entries in this array equals the height of the
-	UYVY image. Each entry is a 4-byte unsigned integer in big endian
-	order and it's an offset to a single pixel line of the UYVY image.
-	The first plane can start either with JPEG or UYVY data chunk. The
-	size of a single UYVY block equals the UYVY image's width
-	multiplied by 2. The size of a JPEG chunk depends on the image and
-	can vary with each line.
-
-	The second plane, at an offset of 4084 bytes, contains a 4-byte
-	offset to the pointer array in the first plane. This offset is
-	followed by a 4-byte value indicating size of the pointer array.
-	All numbers in the second plane are also in big endian order.
-	Remaining data in the second plane is undefined. The information
-	in the second plane allows to easily find location of the pointer
-	array, which can be different for each frame. The size of the
-	pointer array is constant for given UYVY image height.
-
-	In order to extract UYVY and JPEG frames an application can
-	initially set a data pointer to the start of first plane and then
-	add an offset from the first entry of the pointers table. Such a
-	pointer indicates start of an UYVY image pixel line. Whole UYVY
-	line can be copied to a separate buffer. These steps should be
-	repeated for each line, i.e. the number of entries in the pointer
-	array. Anything what's in between the UYVY lines is JPEG data and
-	should be concatenated to form the JPEG stream.
-    * .. _V4L2-PIX-FMT-MT21C:
-
-      - ``V4L2_PIX_FMT_MT21C``
-      - 'MT21'
-      - Compressed two-planar YVU420 format used by Mediatek MT8173.
-	The compression is lossless.
-	It is an opaque intermediate format and the MDP hardware must be
-	used to convert ``V4L2_PIX_FMT_MT21C`` to ``V4L2_PIX_FMT_NV12M``,
-	``V4L2_PIX_FMT_YUV420M`` or ``V4L2_PIX_FMT_YVU420``.
-    * .. _V4L2-PIX-FMT-SUNXI-TILED-NV12:
-
-      - ``V4L2_PIX_FMT_SUNXI_TILED_NV12``
-      - 'ST12'
-      - Two-planar NV12-based format used by the video engine found on Allwinner
-	(codenamed sunxi) platforms, with 32x32 tiles for the luminance plane
-	and 32x64 tiles for the chrominance plane. The data in each tile is
-	stored in linear order, within the tile bounds. Each tile follows the
-	previous one linearly in memory (from left to right, top to bottom).
-
-	The associated buffer dimensions are aligned to match an integer number
-	of tiles, resulting in 32-aligned resolutions for the luminance plane
-	and 16-aligned resolutions for the chrominance plane (with 2x2
-	subsampling).
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. _format-flags:
-
-.. flat-table:: Format Flags
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_PIX_FMT_FLAG_PREMUL_ALPHA``
-      - 0x00000001
-      - The color values are premultiplied by the alpha channel value. For
-	example, if a light blue pixel with 50% transparency was described
-	by RGBA values (128, 192, 255, 128), the same pixel described with
-	premultiplied colors would be described by RGBA values (64, 96,
-	128, 128)
diff --git a/Documentation/media/uapi/v4l/pixfmt-rgb.rst b/Documentation/media/uapi/v4l/pixfmt-rgb.rst
deleted file mode 100644
index 4ce305cc45da..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-rgb.rst
+++ /dev/null
@@ -1,1304 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _pixfmt-rgb:
-
-***********
-RGB Formats
-***********
-
-Description
-===========
-
-These formats are designed to match the pixel formats of typical PC
-graphics frame buffers. They occupy 8, 16, 24 or 32 bits per pixel.
-These are all packed-pixel formats, meaning all the data for a pixel lie
-next to each other in memory.
-
-.. raw:: latex
-
-    \begingroup
-    \tiny
-    \setlength{\tabcolsep}{2pt}
-
-.. tabularcolumns:: |p{2.8cm}|p{2.0cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|
-
-
-.. flat-table:: RGB Image Formats
-    :header-rows:  2
-    :stub-columns: 0
-
-    * - Identifier
-      - Code
-      - :cspan:`7` Byte 0 in memory
-      - :cspan:`7` Byte 1
-      - :cspan:`7` Byte 2
-      - :cspan:`7` Byte 3
-    * -
-      -
-      - 7
-      - 6
-      - 5
-      - 4
-      - 3
-      - 2
-      - 1
-      - 0
-
-      - 7
-      - 6
-      - 5
-      - 4
-      - 3
-      - 2
-      - 1
-      - 0
-
-      - 7
-      - 6
-      - 5
-      - 4
-      - 3
-      - 2
-      - 1
-      - 0
-
-      - 7
-      - 6
-      - 5
-      - 4
-      - 3
-      - 2
-      - 1
-      - 0
-    * .. _V4L2-PIX-FMT-RGB332:
-
-      - ``V4L2_PIX_FMT_RGB332``
-      - 'RGB1'
-
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      -
-    * .. _V4L2-PIX-FMT-ARGB444:
-
-      - ``V4L2_PIX_FMT_ARGB444``
-      - 'AR12'
-
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-
-      - a\ :sub:`3`
-      - a\ :sub:`2`
-      - a\ :sub:`1`
-      - a\ :sub:`0`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      -
-    * .. _V4L2-PIX-FMT-XRGB444:
-
-      - ``V4L2_PIX_FMT_XRGB444``
-      - 'XR12'
-
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-
-      -
-      -
-      -
-      -
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      -
-    * .. _V4L2-PIX-FMT-RGBA444:
-
-      - ``V4L2_PIX_FMT_RGBA444``
-      - 'RA12'
-
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      - a\ :sub:`3`
-      - a\ :sub:`2`
-      - a\ :sub:`1`
-      - a\ :sub:`0`
-
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      -
-    * .. _V4L2-PIX-FMT-RGBX444:
-
-      - ``V4L2_PIX_FMT_RGBX444``
-      - 'RX12'
-
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      -
-      -
-      -
-      -
-
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      -
-    * .. _V4L2-PIX-FMT-ABGR444:
-
-      - ``V4L2_PIX_FMT_ABGR444``
-      - 'AB12'
-
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-
-      - a\ :sub:`3`
-      - a\ :sub:`2`
-      - a\ :sub:`1`
-      - a\ :sub:`0`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      -
-    * .. _V4L2-PIX-FMT-XBGR444:
-
-      - ``V4L2_PIX_FMT_XBGR444``
-      - 'XB12'
-
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-
-      -
-      -
-      -
-      -
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      -
-    * .. _V4L2-PIX-FMT-BGRA444:
-
-      - ``V4L2_PIX_FMT_BGRA444``
-      - 'BA12'
-
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - a\ :sub:`3`
-      - a\ :sub:`2`
-      - a\ :sub:`1`
-      - a\ :sub:`0`
-
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      -
-    * .. _V4L2-PIX-FMT-BGRX444:
-
-      - ``V4L2_PIX_FMT_BGRX444``
-      - 'BX12'
-
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      -
-      -
-      -
-      -
-
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      -
-    * .. _V4L2-PIX-FMT-ARGB555:
-
-      - ``V4L2_PIX_FMT_ARGB555``
-      - 'AR15'
-
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-
-      - a
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      -
-    * .. _V4L2-PIX-FMT-XRGB555:
-
-      - ``V4L2_PIX_FMT_XRGB555``
-      - 'XR15'
-
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-
-      -
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      -
-    * .. _V4L2-PIX-FMT-RGBA555:
-
-      - ``V4L2_PIX_FMT_RGBA555``
-      - 'RA15'
-
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      - a
-
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      -
-    * .. _V4L2-PIX-FMT-RGBX555:
-
-      - ``V4L2_PIX_FMT_RGBX555``
-      - 'RX15'
-
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      -
-
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      -
-    * .. _V4L2-PIX-FMT-ABGR555:
-
-      - ``V4L2_PIX_FMT_ABGR555``
-      - 'AB15'
-
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-
-      - a
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      -
-    * .. _V4L2-PIX-FMT-XBGR555:
-
-      - ``V4L2_PIX_FMT_XBGR555``
-      - 'XB15'
-
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-
-      -
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      -
-    * .. _V4L2-PIX-FMT-BGRA555:
-
-      - ``V4L2_PIX_FMT_BGRA555``
-      - 'BA15'
-
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - a
-
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      -
-    * .. _V4L2-PIX-FMT-BGRX555:
-
-      - ``V4L2_PIX_FMT_BGRX555``
-      - 'BX15'
-
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      -
-
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      -
-    * .. _V4L2-PIX-FMT-RGB565:
-
-      - ``V4L2_PIX_FMT_RGB565``
-      - 'RGBP'
-
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      -
-    * .. _V4L2-PIX-FMT-ARGB555X:
-
-      - ``V4L2_PIX_FMT_ARGB555X``
-      - 'AR15' | (1 << 31)
-
-      - a
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      -
-    * .. _V4L2-PIX-FMT-XRGB555X:
-
-      - ``V4L2_PIX_FMT_XRGB555X``
-      - 'XR15' | (1 << 31)
-
-      -
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      -
-    * .. _V4L2-PIX-FMT-RGB565X:
-
-      - ``V4L2_PIX_FMT_RGB565X``
-      - 'RGBR'
-
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      -
-    * .. _V4L2-PIX-FMT-BGR24:
-
-      - ``V4L2_PIX_FMT_BGR24``
-      - 'BGR3'
-
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      -
-    * .. _V4L2-PIX-FMT-RGB24:
-
-      - ``V4L2_PIX_FMT_RGB24``
-      - 'RGB3'
-
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      -
-    * .. _V4L2-PIX-FMT-BGR666:
-
-      - ``V4L2_PIX_FMT_BGR666``
-      - 'BGRH'
-
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      -
-      -
-      -
-      -
-      -
-      -
-
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-    * .. _V4L2-PIX-FMT-ABGR32:
-
-      - ``V4L2_PIX_FMT_ABGR32``
-      - 'AR24'
-
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-
-      - a\ :sub:`7`
-      - a\ :sub:`6`
-      - a\ :sub:`5`
-      - a\ :sub:`4`
-      - a\ :sub:`3`
-      - a\ :sub:`2`
-      - a\ :sub:`1`
-      - a\ :sub:`0`
-    * .. _V4L2-PIX-FMT-XBGR32:
-
-      - ``V4L2_PIX_FMT_XBGR32``
-      - 'XR24'
-
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-    * .. _V4L2-PIX-FMT-BGRA32:
-
-      - ``V4L2_PIX_FMT_BGRA32``
-      - 'RA24'
-
-      - a\ :sub:`7`
-      - a\ :sub:`6`
-      - a\ :sub:`5`
-      - a\ :sub:`4`
-      - a\ :sub:`3`
-      - a\ :sub:`2`
-      - a\ :sub:`1`
-      - a\ :sub:`0`
-
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-    * .. _V4L2-PIX-FMT-BGRX32:
-
-      - ``V4L2_PIX_FMT_BGRX32``
-      - 'RX24'
-
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-    * .. _V4L2-PIX-FMT-RGBA32:
-
-      - ``V4L2_PIX_FMT_RGBA32``
-      - 'AB24'
-
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-
-      - a\ :sub:`7`
-      - a\ :sub:`6`
-      - a\ :sub:`5`
-      - a\ :sub:`4`
-      - a\ :sub:`3`
-      - a\ :sub:`2`
-      - a\ :sub:`1`
-      - a\ :sub:`0`
-    * .. _V4L2-PIX-FMT-RGBX32:
-
-      - ``V4L2_PIX_FMT_RGBX32``
-      - 'XB24'
-
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-    * .. _V4L2-PIX-FMT-ARGB32:
-
-      - ``V4L2_PIX_FMT_ARGB32``
-      - 'BA24'
-
-      - a\ :sub:`7`
-      - a\ :sub:`6`
-      - a\ :sub:`5`
-      - a\ :sub:`4`
-      - a\ :sub:`3`
-      - a\ :sub:`2`
-      - a\ :sub:`1`
-      - a\ :sub:`0`
-
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-    * .. _V4L2-PIX-FMT-XRGB32:
-
-      - ``V4L2_PIX_FMT_XRGB32``
-      - 'BX24'
-
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-
-.. raw:: latex
-
-    \endgroup
-
-.. note:: Bit 7 is the most significant bit.
-
-The usage and value of the alpha bits (a) in the ARGB and ABGR formats
-(collectively referred to as alpha formats) depend on the device type
-and hardware operation. :ref:`Capture <capture>` devices (including
-capture queues of mem-to-mem devices) fill the alpha component in
-memory. When the device outputs an alpha channel the alpha component
-will have a meaningful value. Otherwise, when the device doesn't output
-an alpha channel but can set the alpha bit to a user-configurable value,
-the :ref:`V4L2_CID_ALPHA_COMPONENT <v4l2-alpha-component>` control
-is used to specify that alpha value, and the alpha component of all
-pixels will be set to the value specified by that control. Otherwise a
-corresponding format without an alpha component (XRGB or XBGR) must be
-used instead of an alpha format.
-
-:ref:`Output <output>` devices (including output queues of mem-to-mem
-devices and :ref:`video output overlay <osd>` devices) read the alpha
-component from memory. When the device processes the alpha channel the
-alpha component must be filled with meaningful values by applications.
-Otherwise a corresponding format without an alpha component (XRGB or
-XBGR) must be used instead of an alpha format.
-
-The XRGB and XBGR formats contain undefined bits (-). Applications,
-devices and drivers must ignore those bits, for both
-:ref:`capture` and :ref:`output` devices.
-
-**Byte Order.**
-Each cell is one byte.
-
-
-.. raw:: latex
-
-    \small
-
-.. tabularcolumns:: |p{3.1cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|
-
-.. flat-table:: RGB byte order
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       11 3 3 3 3 3 3 3 3 3 3 3 3
-
-    * - start + 0:
-      - B\ :sub:`00`
-      - G\ :sub:`00`
-      - R\ :sub:`00`
-      - B\ :sub:`01`
-      - G\ :sub:`01`
-      - R\ :sub:`01`
-      - B\ :sub:`02`
-      - G\ :sub:`02`
-      - R\ :sub:`02`
-      - B\ :sub:`03`
-      - G\ :sub:`03`
-      - R\ :sub:`03`
-    * - start + 12:
-      - B\ :sub:`10`
-      - G\ :sub:`10`
-      - R\ :sub:`10`
-      - B\ :sub:`11`
-      - G\ :sub:`11`
-      - R\ :sub:`11`
-      - B\ :sub:`12`
-      - G\ :sub:`12`
-      - R\ :sub:`12`
-      - B\ :sub:`13`
-      - G\ :sub:`13`
-      - R\ :sub:`13`
-    * - start + 24:
-      - B\ :sub:`20`
-      - G\ :sub:`20`
-      - R\ :sub:`20`
-      - B\ :sub:`21`
-      - G\ :sub:`21`
-      - R\ :sub:`21`
-      - B\ :sub:`22`
-      - G\ :sub:`22`
-      - R\ :sub:`22`
-      - B\ :sub:`23`
-      - G\ :sub:`23`
-      - R\ :sub:`23`
-    * - start + 36:
-      - B\ :sub:`30`
-      - G\ :sub:`30`
-      - R\ :sub:`30`
-      - B\ :sub:`31`
-      - G\ :sub:`31`
-      - R\ :sub:`31`
-      - B\ :sub:`32`
-      - G\ :sub:`32`
-      - R\ :sub:`32`
-      - B\ :sub:`33`
-      - G\ :sub:`33`
-      - R\ :sub:`33`
-
-.. raw:: latex
-
-    \normalsize
-
-Formats defined in :ref:`pixfmt-rgb-deprecated` are deprecated and
-must not be used by new drivers. They are documented here for reference.
-The meaning of their alpha bits ``(a)`` are ill-defined and interpreted as in
-either the corresponding ARGB or XRGB format, depending on the driver.
-
-
-.. raw:: latex
-
-    \begingroup
-    \tiny
-    \setlength{\tabcolsep}{2pt}
-
-.. tabularcolumns:: |p{2.6cm}|p{0.70cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|
-
-.. _pixfmt-rgb-deprecated:
-
-.. flat-table:: Deprecated Packed RGB Image Formats
-    :header-rows:  2
-    :stub-columns: 0
-
-    * - Identifier
-      - Code
-      - :cspan:`7` Byte 0 in memory
-
-      - :cspan:`7` Byte 1
-
-      - :cspan:`7` Byte 2
-
-      - :cspan:`7` Byte 3
-    * -
-      -
-      - 7
-      - 6
-      - 5
-      - 4
-      - 3
-      - 2
-      - 1
-      - 0
-
-      - 7
-      - 6
-      - 5
-      - 4
-      - 3
-      - 2
-      - 1
-      - 0
-
-      - 7
-      - 6
-      - 5
-      - 4
-      - 3
-      - 2
-      - 1
-      - 0
-
-      - 7
-      - 6
-      - 5
-      - 4
-      - 3
-      - 2
-      - 1
-      - 0
-    * .. _V4L2-PIX-FMT-RGB444:
-
-      - ``V4L2_PIX_FMT_RGB444``
-      - 'R444'
-
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-
-      - a\ :sub:`3`
-      - a\ :sub:`2`
-      - a\ :sub:`1`
-      - a\ :sub:`0`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      -
-    * .. _V4L2-PIX-FMT-RGB555:
-
-      - ``V4L2_PIX_FMT_RGB555``
-      - 'RGBO'
-
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-
-      - a
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      -
-    * .. _V4L2-PIX-FMT-RGB555X:
-
-      - ``V4L2_PIX_FMT_RGB555X``
-      - 'RGBQ'
-
-      - a
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      -
-    * .. _V4L2-PIX-FMT-BGR32:
-
-      - ``V4L2_PIX_FMT_BGR32``
-      - 'BGR4'
-
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-
-      - a\ :sub:`7`
-      - a\ :sub:`6`
-      - a\ :sub:`5`
-      - a\ :sub:`4`
-      - a\ :sub:`3`
-      - a\ :sub:`2`
-      - a\ :sub:`1`
-      - a\ :sub:`0`
-    * .. _V4L2-PIX-FMT-RGB32:
-
-      - ``V4L2_PIX_FMT_RGB32``
-      - 'RGB4'
-
-      - a\ :sub:`7`
-      - a\ :sub:`6`
-      - a\ :sub:`5`
-      - a\ :sub:`4`
-      - a\ :sub:`3`
-      - a\ :sub:`2`
-      - a\ :sub:`1`
-      - a\ :sub:`0`
-
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-
-.. raw:: latex
-
-    \endgroup
-
-A test utility to determine which RGB formats a driver actually supports
-is available from the LinuxTV v4l-dvb repository. See
-`https://linuxtv.org/repo/ <https://linuxtv.org/repo/>`__ for access
-instructions.
diff --git a/Documentation/media/uapi/v4l/pixfmt-sdr-cs08.rst b/Documentation/media/uapi/v4l/pixfmt-sdr-cs08.rst
deleted file mode 100644
index e7a89fe7e117..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-sdr-cs08.rst
+++ /dev/null
@@ -1,37 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _v4l2-sdr-fmt-cs8:
-
-*************************
-V4L2_SDR_FMT_CS8 ('CS08')
-*************************
-
-Complex signed 8-bit IQ sample
-
-
-Description
-===========
-
-This format contains sequence of complex number samples. Each complex
-number consist two parts, called In-phase and Quadrature (IQ). Both I
-and Q are represented as a 8 bit signed number. I value comes first and
-Q value after that.
-
-**Byte Order.**
-Each cell is one byte.
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - start + 0:
-      - I'\ :sub:`0`
-    * - start + 1:
-      - Q'\ :sub:`0`
diff --git a/Documentation/media/uapi/v4l/pixfmt-sdr-cs14le.rst b/Documentation/media/uapi/v4l/pixfmt-sdr-cs14le.rst
deleted file mode 100644
index d10d56f0e63a..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-sdr-cs14le.rst
+++ /dev/null
@@ -1,41 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-SDR-FMT-CS14LE:
-
-****************************
-V4L2_SDR_FMT_CS14LE ('CS14')
-****************************
-
-Complex signed 14-bit little endian IQ sample
-
-
-Description
-===========
-
-This format contains sequence of complex number samples. Each complex
-number consist two parts, called In-phase and Quadrature (IQ). Both I
-and Q are represented as a 14 bit signed little endian number. I value
-comes first and Q value after that. 14 bit value is stored in 16 bit
-space with unused high bits padded with 0.
-
-**Byte Order.**
-Each cell is one byte.
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - start + 0:
-      - I'\ :sub:`0[7:0]`
-      - I'\ :sub:`0[13:8]`
-    * - start + 2:
-      - Q'\ :sub:`0[7:0]`
-      - Q'\ :sub:`0[13:8]`
diff --git a/Documentation/media/uapi/v4l/pixfmt-sdr-cu08.rst b/Documentation/media/uapi/v4l/pixfmt-sdr-cu08.rst
deleted file mode 100644
index f37df90f5a21..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-sdr-cu08.rst
+++ /dev/null
@@ -1,37 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _v4l2-sdr-fmt-cu8:
-
-*************************
-V4L2_SDR_FMT_CU8 ('CU08')
-*************************
-
-Complex unsigned 8-bit IQ sample
-
-
-Description
-===========
-
-This format contains sequence of complex number samples. Each complex
-number consist two parts, called In-phase and Quadrature (IQ). Both I
-and Q are represented as a 8 bit unsigned number. I value comes first
-and Q value after that.
-
-**Byte Order.**
-Each cell is one byte.
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - start + 0:
-      - I'\ :sub:`0`
-    * - start + 1:
-      - Q'\ :sub:`0`
diff --git a/Documentation/media/uapi/v4l/pixfmt-sdr-cu16le.rst b/Documentation/media/uapi/v4l/pixfmt-sdr-cu16le.rst
deleted file mode 100644
index 237998fb5f9f..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-sdr-cu16le.rst
+++ /dev/null
@@ -1,41 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-SDR-FMT-CU16LE:
-
-****************************
-V4L2_SDR_FMT_CU16LE ('CU16')
-****************************
-
-
-Complex unsigned 16-bit little endian IQ sample
-
-
-Description
-===========
-
-This format contains sequence of complex number samples. Each complex
-number consist two parts, called In-phase and Quadrature (IQ). Both I
-and Q are represented as a 16 bit unsigned little endian number. I value
-comes first and Q value after that.
-
-**Byte Order.**
-Each cell is one byte.
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - start + 0:
-      - I'\ :sub:`0[7:0]`
-      - I'\ :sub:`0[15:8]`
-    * - start + 2:
-      - Q'\ :sub:`0[7:0]`
-      - Q'\ :sub:`0[15:8]`
diff --git a/Documentation/media/uapi/v4l/pixfmt-sdr-pcu16be.rst b/Documentation/media/uapi/v4l/pixfmt-sdr-pcu16be.rst
deleted file mode 100644
index df078dcfd18d..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-sdr-pcu16be.rst
+++ /dev/null
@@ -1,62 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-SDR-FMT-PCU16BE:
-
-******************************
-V4L2_SDR_FMT_PCU16BE ('PC16')
-******************************
-
-Planar complex unsigned 16-bit big endian IQ sample
-
-Description
-===========
-
-This format contains a sequence of complex number samples. Each complex
-number consist of two parts called In-phase and Quadrature (IQ). Both I
-and Q are represented as a 16 bit unsigned big endian number stored in
-32 bit space. The remaining unused bits within the 32 bit space will be
-padded with 0. I value starts first and Q value starts at an offset
-equalling half of the buffer size (i.e.) offset = buffersize/2. Out of
-the 16 bits, bit 15:2 (14 bit) is data and bit 1:0 (2 bit) can be any
-value.
-
-**Byte Order.**
-Each cell is one byte.
-
-.. flat-table::
-    :header-rows:  1
-    :stub-columns: 0
-
-    * -  Offset:
-      -  Byte B0
-      -  Byte B1
-      -  Byte B2
-      -  Byte B3
-    * -  start + 0:
-      -  I'\ :sub:`0[13:6]`
-      -  I'\ :sub:`0[5:0]; B1[1:0]=pad`
-      -  pad
-      -  pad
-    * -  start + 4:
-      -  I'\ :sub:`1[13:6]`
-      -  I'\ :sub:`1[5:0]; B1[1:0]=pad`
-      -  pad
-      -  pad
-    * -  ...
-    * - start + offset:
-      -  Q'\ :sub:`0[13:6]`
-      -  Q'\ :sub:`0[5:0]; B1[1:0]=pad`
-      -  pad
-      -  pad
-    * - start + offset + 4:
-      -  Q'\ :sub:`1[13:6]`
-      -  Q'\ :sub:`1[5:0]; B1[1:0]=pad`
-      -  pad
-      -  pad
diff --git a/Documentation/media/uapi/v4l/pixfmt-sdr-pcu18be.rst b/Documentation/media/uapi/v4l/pixfmt-sdr-pcu18be.rst
deleted file mode 100644
index a1ea63db9230..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-sdr-pcu18be.rst
+++ /dev/null
@@ -1,62 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-SDR-FMT-PCU18BE:
-
-******************************
-V4L2_SDR_FMT_PCU18BE ('PC18')
-******************************
-
-Planar complex unsigned 18-bit big endian IQ sample
-
-Description
-===========
-
-This format contains a sequence of complex number samples. Each complex
-number consist of two parts called In-phase and Quadrature (IQ). Both I
-and Q are represented as a 18 bit unsigned big endian number stored in
-32 bit space. The remaining unused bits within the 32 bit space will be
-padded with 0. I value starts first and Q value starts at an offset
-equalling half of the buffer size (i.e.) offset = buffersize/2. Out of
-the 18 bits, bit 17:2 (16 bit) is data and bit 1:0 (2 bit) can be any
-value.
-
-**Byte Order.**
-Each cell is one byte.
-
-.. flat-table::
-    :header-rows:  1
-    :stub-columns: 0
-
-    * -  Offset:
-      -  Byte B0
-      -  Byte B1
-      -  Byte B2
-      -  Byte B3
-    * -  start + 0:
-      -  I'\ :sub:`0[17:10]`
-      -  I'\ :sub:`0[9:2]`
-      -  I'\ :sub:`0[1:0]; B2[5:0]=pad`
-      -  pad
-    * -  start + 4:
-      -  I'\ :sub:`1[17:10]`
-      -  I'\ :sub:`1[9:2]`
-      -  I'\ :sub:`1[1:0]; B2[5:0]=pad`
-      -  pad
-    * -  ...
-    * - start + offset:
-      -  Q'\ :sub:`0[17:10]`
-      -  Q'\ :sub:`0[9:2]`
-      -  Q'\ :sub:`0[1:0]; B2[5:0]=pad`
-      -  pad
-    * - start + offset + 4:
-      -  Q'\ :sub:`1[17:10]`
-      -  Q'\ :sub:`1[9:2]`
-      -  Q'\ :sub:`1[1:0]; B2[5:0]=pad`
-      -  pad
diff --git a/Documentation/media/uapi/v4l/pixfmt-sdr-pcu20be.rst b/Documentation/media/uapi/v4l/pixfmt-sdr-pcu20be.rst
deleted file mode 100644
index 11a05ea60e26..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-sdr-pcu20be.rst
+++ /dev/null
@@ -1,62 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-SDR-FMT-PCU20BE:
-
-******************************
-V4L2_SDR_FMT_PCU20BE ('PC20')
-******************************
-
-Planar complex unsigned 20-bit big endian IQ sample
-
-Description
-===========
-
-This format contains a sequence of complex number samples. Each complex
-number consist of two parts called In-phase and Quadrature (IQ). Both I
-and Q are represented as a 20 bit unsigned big endian number stored in
-32 bit space. The remaining unused bits within the 32 bit space will be
-padded with 0. I value starts first and Q value starts at an offset
-equalling half of the buffer size (i.e.) offset = buffersize/2. Out of
-the 20 bits, bit 19:2 (18 bit) is data and bit 1:0 (2 bit) can be any
-value.
-
-**Byte Order.**
-Each cell is one byte.
-
-.. flat-table::
-    :header-rows:  1
-    :stub-columns: 0
-
-    * -  Offset:
-      -  Byte B0
-      -  Byte B1
-      -  Byte B2
-      -  Byte B3
-    * -  start + 0:
-      -  I'\ :sub:`0[19:12]`
-      -  I'\ :sub:`0[11:4]`
-      -  I'\ :sub:`0[3:0]; B2[3:0]=pad`
-      -  pad
-    * -  start + 4:
-      -  I'\ :sub:`1[19:12]`
-      -  I'\ :sub:`1[11:4]`
-      -  I'\ :sub:`1[3:0]; B2[3:0]=pad`
-      -  pad
-    * -  ...
-    * - start + offset:
-      -  Q'\ :sub:`0[19:12]`
-      -  Q'\ :sub:`0[11:4]`
-      -  Q'\ :sub:`0[3:0]; B2[3:0]=pad`
-      -  pad
-    * - start + offset + 4:
-      -  Q'\ :sub:`1[19:12]`
-      -  Q'\ :sub:`1[11:4]`
-      -  Q'\ :sub:`1[3:0]; B2[3:0]=pad`
-      -  pad
diff --git a/Documentation/media/uapi/v4l/pixfmt-sdr-ru12le.rst b/Documentation/media/uapi/v4l/pixfmt-sdr-ru12le.rst
deleted file mode 100644
index 3c2c9f75fc5e..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-sdr-ru12le.rst
+++ /dev/null
@@ -1,39 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-SDR-FMT-RU12LE:
-
-****************************
-V4L2_SDR_FMT_RU12LE ('RU12')
-****************************
-
-
-Real unsigned 12-bit little endian sample
-
-
-Description
-===========
-
-This format contains sequence of real number samples. Each sample is
-represented as a 12 bit unsigned little endian number. Sample is stored
-in 16 bit space with unused high bits padded with 0.
-
-**Byte Order.**
-Each cell is one byte.
-
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - start + 0:
-      - I'\ :sub:`0[7:0]`
-      - I'\ :sub:`0[11:8]`
diff --git a/Documentation/media/uapi/v4l/pixfmt-srggb10-ipu3.rst b/Documentation/media/uapi/v4l/pixfmt-srggb10-ipu3.rst
deleted file mode 100644
index 75279f0fdad8..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-srggb10-ipu3.rst
+++ /dev/null
@@ -1,342 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _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/pixfmt-srggb10.rst b/Documentation/media/uapi/v4l/pixfmt-srggb10.rst
deleted file mode 100644
index cab7fbb1f2fe..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-srggb10.rst
+++ /dev/null
@@ -1,83 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-SRGGB10:
-.. _v4l2-pix-fmt-sbggr10:
-.. _v4l2-pix-fmt-sgbrg10:
-.. _v4l2-pix-fmt-sgrbg10:
-
-***************************************************************************************************************************
-V4L2_PIX_FMT_SRGGB10 ('RG10'), V4L2_PIX_FMT_SGRBG10 ('BA10'), V4L2_PIX_FMT_SGBRG10 ('GB10'), V4L2_PIX_FMT_SBGGR10 ('BG10'),
-***************************************************************************************************************************
-
-
-V4L2_PIX_FMT_SGRBG10
-V4L2_PIX_FMT_SGBRG10
-V4L2_PIX_FMT_SBGGR10
-10-bit Bayer formats expanded to 16 bits
-
-
-Description
-===========
-
-These four pixel formats are raw sRGB / Bayer formats with 10 bits per
-sample. Each sample is stored in a 16-bit word, with 6 unused
-high bits filled with zeros. Each n-pixel row contains n/2 green samples and
-n/2 blue or red samples, with alternating red and blue rows. Bytes are
-stored in memory in little endian order. They are conventionally described
-as GRGR... BGBG..., RGRG... GBGB..., etc. Below is an example of one of
-these formats:
-
-**Byte Order.**
-Each cell is one byte, the 6 most significant bits in the high bytes
-are 0.
-
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - start + 0:
-      - B\ :sub:`00low`
-      - B\ :sub:`00high`
-      - G\ :sub:`01low`
-      - G\ :sub:`01high`
-      - B\ :sub:`02low`
-      - B\ :sub:`02high`
-      - G\ :sub:`03low`
-      - G\ :sub:`03high`
-    * - start + 8:
-      - G\ :sub:`10low`
-      - G\ :sub:`10high`
-      - R\ :sub:`11low`
-      - R\ :sub:`11high`
-      - G\ :sub:`12low`
-      - G\ :sub:`12high`
-      - R\ :sub:`13low`
-      - R\ :sub:`13high`
-    * - start + 16:
-      - B\ :sub:`20low`
-      - B\ :sub:`20high`
-      - G\ :sub:`21low`
-      - G\ :sub:`21high`
-      - B\ :sub:`22low`
-      - B\ :sub:`22high`
-      - G\ :sub:`23low`
-      - G\ :sub:`23high`
-    * - start + 24:
-      - G\ :sub:`30low`
-      - G\ :sub:`30high`
-      - R\ :sub:`31low`
-      - R\ :sub:`31high`
-      - G\ :sub:`32low`
-      - G\ :sub:`32high`
-      - R\ :sub:`33low`
-      - R\ :sub:`33high`
diff --git a/Documentation/media/uapi/v4l/pixfmt-srggb10alaw8.rst b/Documentation/media/uapi/v4l/pixfmt-srggb10alaw8.rst
deleted file mode 100644
index 5bb58764b532..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-srggb10alaw8.rst
+++ /dev/null
@@ -1,31 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-SBGGR10ALAW8:
-.. _v4l2-pix-fmt-sgbrg10alaw8:
-.. _v4l2-pix-fmt-sgrbg10alaw8:
-.. _v4l2-pix-fmt-srggb10alaw8:
-
-***********************************************************************************************************************************************
-V4L2_PIX_FMT_SBGGR10ALAW8 ('aBA8'), V4L2_PIX_FMT_SGBRG10ALAW8 ('aGA8'), V4L2_PIX_FMT_SGRBG10ALAW8 ('agA8'), V4L2_PIX_FMT_SRGGB10ALAW8 ('aRA8'),
-***********************************************************************************************************************************************
-
-V4L2_PIX_FMT_SGBRG10ALAW8
-V4L2_PIX_FMT_SGRBG10ALAW8
-V4L2_PIX_FMT_SRGGB10ALAW8
-10-bit Bayer formats compressed to 8 bits
-
-
-Description
-===========
-
-These four pixel formats are raw sRGB / Bayer formats with 10 bits per
-color compressed to 8 bits each, using the A-LAW algorithm. Each color
-component consumes 8 bits of memory. In other respects this format is
-similar to :ref:`V4L2-PIX-FMT-SRGGB8`.
diff --git a/Documentation/media/uapi/v4l/pixfmt-srggb10dpcm8.rst b/Documentation/media/uapi/v4l/pixfmt-srggb10dpcm8.rst
deleted file mode 100644
index cbc9c0a52ab4..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-srggb10dpcm8.rst
+++ /dev/null
@@ -1,35 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-SBGGR10DPCM8:
-.. _v4l2-pix-fmt-sgbrg10dpcm8:
-.. _v4l2-pix-fmt-sgrbg10dpcm8:
-.. _v4l2-pix-fmt-srggb10dpcm8:
-
-
-***********************************************************************************************************************************************
-V4L2_PIX_FMT_SBGGR10DPCM8 ('bBA8'), V4L2_PIX_FMT_SGBRG10DPCM8 ('bGA8'), V4L2_PIX_FMT_SGRBG10DPCM8 ('BD10'), V4L2_PIX_FMT_SRGGB10DPCM8 ('bRA8'),
-***********************************************************************************************************************************************
-
-*man V4L2_PIX_FMT_SBGGR10DPCM8(2)*
-
-V4L2_PIX_FMT_SGBRG10DPCM8
-V4L2_PIX_FMT_SGRBG10DPCM8
-V4L2_PIX_FMT_SRGGB10DPCM8
-10-bit Bayer formats compressed to 8 bits
-
-
-Description
-===========
-
-These four pixel formats are raw sRGB / Bayer formats with 10 bits per
-colour compressed to 8 bits each, using DPCM compression. DPCM,
-differential pulse-code modulation, is lossy. Each colour component
-consumes 8 bits of memory. In other respects this format is similar to
-:ref:`V4L2-PIX-FMT-SRGGB10`.
diff --git a/Documentation/media/uapi/v4l/pixfmt-srggb10p.rst b/Documentation/media/uapi/v4l/pixfmt-srggb10p.rst
deleted file mode 100644
index fd32660a3766..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-srggb10p.rst
+++ /dev/null
@@ -1,81 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-SRGGB10P:
-.. _v4l2-pix-fmt-sbggr10p:
-.. _v4l2-pix-fmt-sgbrg10p:
-.. _v4l2-pix-fmt-sgrbg10p:
-
-*******************************************************************************************************************************
-V4L2_PIX_FMT_SRGGB10P ('pRAA'), V4L2_PIX_FMT_SGRBG10P ('pgAA'), V4L2_PIX_FMT_SGBRG10P ('pGAA'), V4L2_PIX_FMT_SBGGR10P ('pBAA'),
-*******************************************************************************************************************************
-
-
-V4L2_PIX_FMT_SGRBG10P
-V4L2_PIX_FMT_SGBRG10P
-V4L2_PIX_FMT_SBGGR10P
-10-bit packed Bayer formats
-
-
-Description
-===========
-
-These four pixel formats are packed raw sRGB / Bayer formats with 10
-bits per sample. Every four consecutive samples are packed into 5
-bytes. Each of the first 4 bytes contain the 8 high order bits
-of the pixels, and the 5th byte contains the 2 least significants
-bits of each pixel, in the same order.
-
-Each n-pixel row contains n/2 green samples and n/2 blue or red samples,
-with alternating green-red and green-blue rows. They are conventionally
-described as GRGR... BGBG..., RGRG... GBGB..., etc. Below is an example
-of a small V4L2_PIX_FMT_SBGGR10P image:
-
-**Byte Order.**
-Each cell is one byte.
-
-.. tabularcolumns:: |p{2.4cm}|p{1.4cm}|p{1.2cm}|p{1.2cm}|p{1.2cm}|p{6.4cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths: 12 8 8 8 8 68
-
-    * - start + 0:
-      - B\ :sub:`00high`
-      - G\ :sub:`01high`
-      - B\ :sub:`02high`
-      - G\ :sub:`03high`
-      - G\ :sub:`03low`\ (bits 7--6) B\ :sub:`02low`\ (bits 5--4)
-
-	G\ :sub:`01low`\ (bits 3--2) B\ :sub:`00low`\ (bits 1--0)
-    * - start + 5:
-      - G\ :sub:`10high`
-      - R\ :sub:`11high`
-      - G\ :sub:`12high`
-      - R\ :sub:`13high`
-      - R\ :sub:`13low`\ (bits 7--6) G\ :sub:`12low`\ (bits 5--4)
-
-	R\ :sub:`11low`\ (bits 3--2) G\ :sub:`10low`\ (bits 1--0)
-    * - start + 10:
-      - B\ :sub:`20high`
-      - G\ :sub:`21high`
-      - B\ :sub:`22high`
-      - G\ :sub:`23high`
-      - G\ :sub:`23low`\ (bits 7--6) B\ :sub:`22low`\ (bits 5--4)
-
-	G\ :sub:`21low`\ (bits 3--2) B\ :sub:`20low`\ (bits 1--0)
-    * - start + 15:
-      - G\ :sub:`30high`
-      - R\ :sub:`31high`
-      - G\ :sub:`32high`
-      - R\ :sub:`33high`
-      - R\ :sub:`33low`\ (bits 7--6) G\ :sub:`32low`\ (bits 5--4)
-
-	R\ :sub:`31low`\ (bits 3--2) G\ :sub:`30low`\ (bits 1--0)
diff --git a/Documentation/media/uapi/v4l/pixfmt-srggb12.rst b/Documentation/media/uapi/v4l/pixfmt-srggb12.rst
deleted file mode 100644
index 6fb6a937e6ad..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-srggb12.rst
+++ /dev/null
@@ -1,84 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-SRGGB12:
-.. _v4l2-pix-fmt-sbggr12:
-.. _v4l2-pix-fmt-sgbrg12:
-.. _v4l2-pix-fmt-sgrbg12:
-
-
-***************************************************************************************************************************
-V4L2_PIX_FMT_SRGGB12 ('RG12'), V4L2_PIX_FMT_SGRBG12 ('BA12'), V4L2_PIX_FMT_SGBRG12 ('GB12'), V4L2_PIX_FMT_SBGGR12 ('BG12'),
-***************************************************************************************************************************
-
-
-V4L2_PIX_FMT_SGRBG12
-V4L2_PIX_FMT_SGBRG12
-V4L2_PIX_FMT_SBGGR12
-12-bit Bayer formats expanded to 16 bits
-
-
-Description
-===========
-
-These four pixel formats are raw sRGB / Bayer formats with 12 bits per
-colour. Each colour component is stored in a 16-bit word, with 4 unused
-high bits filled with zeros. Each n-pixel row contains n/2 green samples
-and n/2 blue or red samples, with alternating red and blue rows. Bytes
-are stored in memory in little endian order. They are conventionally
-described as GRGR... BGBG..., RGRG... GBGB..., etc. Below is an example
-of a small V4L2_PIX_FMT_SBGGR12 image:
-
-**Byte Order.**
-Each cell is one byte, the 4 most significant bits in the high bytes are
-0.
-
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - start + 0:
-      - B\ :sub:`00low`
-      - B\ :sub:`00high`
-      - G\ :sub:`01low`
-      - G\ :sub:`01high`
-      - B\ :sub:`02low`
-      - B\ :sub:`02high`
-      - G\ :sub:`03low`
-      - G\ :sub:`03high`
-    * - start + 8:
-      - G\ :sub:`10low`
-      - G\ :sub:`10high`
-      - R\ :sub:`11low`
-      - R\ :sub:`11high`
-      - G\ :sub:`12low`
-      - G\ :sub:`12high`
-      - R\ :sub:`13low`
-      - R\ :sub:`13high`
-    * - start + 16:
-      - B\ :sub:`20low`
-      - B\ :sub:`20high`
-      - G\ :sub:`21low`
-      - G\ :sub:`21high`
-      - B\ :sub:`22low`
-      - B\ :sub:`22high`
-      - G\ :sub:`23low`
-      - G\ :sub:`23high`
-    * - start + 24:
-      - G\ :sub:`30low`
-      - G\ :sub:`30high`
-      - R\ :sub:`31low`
-      - R\ :sub:`31high`
-      - G\ :sub:`32low`
-      - G\ :sub:`32high`
-      - R\ :sub:`33low`
-      - R\ :sub:`33high`
diff --git a/Documentation/media/uapi/v4l/pixfmt-srggb12p.rst b/Documentation/media/uapi/v4l/pixfmt-srggb12p.rst
deleted file mode 100644
index 045540bc0d86..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-srggb12p.rst
+++ /dev/null
@@ -1,94 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-SRGGB12P:
-.. _v4l2-pix-fmt-sbggr12p:
-.. _v4l2-pix-fmt-sgbrg12p:
-.. _v4l2-pix-fmt-sgrbg12p:
-
-*******************************************************************************************************************************
-V4L2_PIX_FMT_SRGGB12P ('pRCC'), V4L2_PIX_FMT_SGRBG12P ('pgCC'), V4L2_PIX_FMT_SGBRG12P ('pGCC'), V4L2_PIX_FMT_SBGGR12P ('pBCC'),
-*******************************************************************************************************************************
-
-
-12-bit packed Bayer formats
----------------------------
-
-
-Description
-===========
-
-These four pixel formats are packed raw sRGB / Bayer formats with 12
-bits per colour. Every two consecutive samples are packed into three
-bytes. Each of the first two bytes contain the 8 high order bits of
-the pixels, and the third byte contains the four least significants
-bits of each pixel, in the same order.
-
-Each n-pixel row contains n/2 green samples and n/2 blue or red
-samples, with alternating green-red and green-blue rows. They are
-conventionally described as GRGR... BGBG..., RGRG... GBGB..., etc.
-Below is an example of a small V4L2_PIX_FMT_SBGGR12P image:
-
-**Byte Order.**
-Each cell is one byte.
-
-.. tabularcolumns:: |p{2.2cm}|p{1.2cm}|p{1.2cm}|p{3.1cm}|p{1.2cm}|p{1.2cm}|p{3.1cm}|
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       2 1 1 1 1 1 1
-
-
-    -  -  start + 0:
-       -  B\ :sub:`00high`
-       -  G\ :sub:`01high`
-       -  G\ :sub:`01low`\ (bits 7--4)
-
-          B\ :sub:`00low`\ (bits 3--0)
-       -  B\ :sub:`02high`
-       -  G\ :sub:`03high`
-       -  G\ :sub:`03low`\ (bits 7--4)
-
-          B\ :sub:`02low`\ (bits 3--0)
-
-    -  -  start + 6:
-       -  G\ :sub:`10high`
-       -  R\ :sub:`11high`
-       -  R\ :sub:`11low`\ (bits 7--4)
-
-          G\ :sub:`10low`\ (bits 3--0)
-       -  G\ :sub:`12high`
-       -  R\ :sub:`13high`
-       -  R\ :sub:`13low`\ (bits 3--2)
-
-          G\ :sub:`12low`\ (bits 3--0)
-    -  -  start + 12:
-       -  B\ :sub:`20high`
-       -  G\ :sub:`21high`
-       -  G\ :sub:`21low`\ (bits 7--4)
-
-          B\ :sub:`20low`\ (bits 3--0)
-       -  B\ :sub:`22high`
-       -  G\ :sub:`23high`
-       -  G\ :sub:`23low`\ (bits 7--4)
-
-          B\ :sub:`22low`\ (bits 3--0)
-    -  -  start + 18:
-       -  G\ :sub:`30high`
-       -  R\ :sub:`31high`
-       -  R\ :sub:`31low`\ (bits 7--4)
-
-          G\ :sub:`30low`\ (bits 3--0)
-       -  G\ :sub:`32high`
-       -  R\ :sub:`33high`
-       -  R\ :sub:`33low`\ (bits 3--2)
-
-          G\ :sub:`32low`\ (bits 3--0)
diff --git a/Documentation/media/uapi/v4l/pixfmt-srggb14.rst b/Documentation/media/uapi/v4l/pixfmt-srggb14.rst
deleted file mode 100644
index 3420d4d1825e..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-srggb14.rst
+++ /dev/null
@@ -1,82 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-SRGGB14:
-.. _v4l2-pix-fmt-sbggr14:
-.. _v4l2-pix-fmt-sgbrg14:
-.. _v4l2-pix-fmt-sgrbg14:
-
-
-***************************************************************************************************************************
-V4L2_PIX_FMT_SRGGB14 ('RG14'), V4L2_PIX_FMT_SGRBG14 ('GR14'), V4L2_PIX_FMT_SGBRG14 ('GB14'), V4L2_PIX_FMT_SBGGR14 ('BG14'),
-***************************************************************************************************************************
-
-
-14-bit Bayer formats expanded to 16 bits
-
-
-Description
-===========
-
-These four pixel formats are raw sRGB / Bayer formats with 14 bits per
-colour. Each sample is stored in a 16-bit word, with two unused high
-bits filled with zeros. Each n-pixel row contains n/2 green samples
-and n/2 blue or red samples, with alternating red and blue rows. Bytes
-are stored in memory in little endian order. They are conventionally
-described as GRGR... BGBG..., RGRG... GBGB..., etc. Below is an
-example of a small V4L2_PIX_FMT_SBGGR14 image:
-
-**Byte Order.**
-Each cell is one byte, the two most significant bits in the high bytes are
-zero.
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       2 1 1 1 1 1 1 1 1
-
-
-    * - start + 0:
-      - B\ :sub:`00low`
-      - B\ :sub:`00high`
-      - G\ :sub:`01low`
-      - G\ :sub:`01high`
-      - B\ :sub:`02low`
-      - B\ :sub:`02high`
-      - G\ :sub:`03low`
-      - G\ :sub:`03high`
-    * - start + 8:
-      - G\ :sub:`10low`
-      - G\ :sub:`10high`
-      - R\ :sub:`11low`
-      - R\ :sub:`11high`
-      - G\ :sub:`12low`
-      - G\ :sub:`12high`
-      - R\ :sub:`13low`
-      - R\ :sub:`13high`
-    * - start + 16:
-      - B\ :sub:`20low`
-      - B\ :sub:`20high`
-      - G\ :sub:`21low`
-      - G\ :sub:`21high`
-      - B\ :sub:`22low`
-      - B\ :sub:`22high`
-      - G\ :sub:`23low`
-      - G\ :sub:`23high`
-    * - start + 24:
-      - G\ :sub:`30low`
-      - G\ :sub:`30high`
-      - R\ :sub:`31low`
-      - R\ :sub:`31high`
-      - G\ :sub:`32low`
-      - G\ :sub:`32high`
-      - R\ :sub:`33low`
-      - R\ :sub:`33high`
diff --git a/Documentation/media/uapi/v4l/pixfmt-srggb14p.rst b/Documentation/media/uapi/v4l/pixfmt-srggb14p.rst
deleted file mode 100644
index 051ae3d05bc3..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-srggb14p.rst
+++ /dev/null
@@ -1,152 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-SRGGB14P:
-.. _v4l2-pix-fmt-sbggr14p:
-.. _v4l2-pix-fmt-sgbrg14p:
-.. _v4l2-pix-fmt-sgrbg14p:
-
-*******************************************************************************************************************************
-V4L2_PIX_FMT_SRGGB14P ('pREE'), V4L2_PIX_FMT_SGRBG14P ('pgEE'), V4L2_PIX_FMT_SGBRG14P ('pGEE'), V4L2_PIX_FMT_SBGGR14P ('pBEE'),
-*******************************************************************************************************************************
-
-*man V4L2_PIX_FMT_SRGGB14P(2)*
-
-V4L2_PIX_FMT_SGRBG14P
-V4L2_PIX_FMT_SGBRG14P
-V4L2_PIX_FMT_SBGGR14P
-14-bit packed Bayer formats
-
-
-Description
-===========
-
-These four pixel formats are packed raw sRGB / Bayer formats with 14
-bits per colour. Every four consecutive samples are packed into seven
-bytes. Each of the first four bytes contain the eight high order bits
-of the pixels, and the three following bytes contains the six least
-significants bits of each pixel, in the same order.
-
-Each n-pixel row contains n/2 green samples and n/2 blue or red samples,
-with alternating green-red and green-blue rows. They are conventionally
-described as GRGR... BGBG..., RGRG... GBGB..., etc. Below is an example
-of one of these formats:
-
-**Byte Order.**
-Each cell is one byte.
-
-.. raw:: latex
-
-    \footnotesize
-
-.. tabularcolumns:: |p{1.8cm}|p{1.0cm}|p{1.0cm}|p{1.0cm}|p{1.1cm}|p{3.3cm}|p{3.3cm}|p{3.3cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       2 1 1 1 1 3 3 3
-
-
-    -  .. row 1
-
-       -  start + 0
-
-       -  B\ :sub:`00high`
-
-       -  G\ :sub:`01high`
-
-       -  B\ :sub:`02high`
-
-       -  G\ :sub:`03high`
-
-       -  G\ :sub:`01low bits 1--0`\ (bits 7--6)
-
-	  B\ :sub:`00low bits 5--0`\ (bits 5--0)
-
-       -  R\ :sub:`02low bits 3--0`\ (bits 7--4)
-
-	  G\ :sub:`01low bits 5--2`\ (bits 3--0)
-
-       -  G\ :sub:`03low bits 5--0`\ (bits 7--2)
-
-	  R\ :sub:`02low bits 5--4`\ (bits 1--0)
-
-    -  .. row 2
-
-       -  start + 7
-
-       -  G\ :sub:`00high`
-
-       -  R\ :sub:`01high`
-
-       -  G\ :sub:`02high`
-
-       -  R\ :sub:`03high`
-
-       -  R\ :sub:`01low bits 1--0`\ (bits 7--6)
-
-	  G\ :sub:`00low bits 5--0`\ (bits 5--0)
-
-       -  G\ :sub:`02low bits 3--0`\ (bits 7--4)
-
-	  R\ :sub:`01low bits 5--2`\ (bits 3--0)
-
-       -  R\ :sub:`03low bits 5--0`\ (bits 7--2)
-
-	  G\ :sub:`02low bits 5--4`\ (bits 1--0)
-
-    -  .. row 3
-
-       -  start + 14
-
-       -  B\ :sub:`20high`
-
-       -  G\ :sub:`21high`
-
-       -  B\ :sub:`22high`
-
-       -  G\ :sub:`23high`
-
-       -  G\ :sub:`21low bits 1--0`\ (bits 7--6)
-
-	  B\ :sub:`20low bits 5--0`\ (bits 5--0)
-
-       -  R\ :sub:`22low bits 3--0`\ (bits 7--4)
-
-	  G\ :sub:`21low bits 5--2`\ (bits 3--0)
-
-       -  G\ :sub:`23low bits 5--0`\ (bits 7--2)
-
-	  R\ :sub:`22low bits 5--4`\ (bits 1--0)
-
-    -  .. row 4
-
-       -  start + 21
-
-       -  G\ :sub:`30high`
-
-       -  R\ :sub:`31high`
-
-       -  G\ :sub:`32high`
-
-       -  R\ :sub:`33high`
-
-       -  R\ :sub:`31low bits 1--0`\ (bits 7--6)
-	  G\ :sub:`30low bits 5--0`\ (bits 5--0)
-
-       -  G\ :sub:`32low bits 3--0`\ (bits 7--4)
-	  R\ :sub:`31low bits 5--2`\ (bits 3--0)
-
-       -  R\ :sub:`33low bits 5--0`\ (bits 7--2)
-	  G\ :sub:`32low bits 5--4`\ (bits 1--0)
-
-.. raw:: latex
-
-    \normalsize
-
diff --git a/Documentation/media/uapi/v4l/pixfmt-srggb16.rst b/Documentation/media/uapi/v4l/pixfmt-srggb16.rst
deleted file mode 100644
index 36527c49eaf7..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-srggb16.rst
+++ /dev/null
@@ -1,76 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-SRGGB16:
-.. _v4l2-pix-fmt-sbggr16:
-.. _v4l2-pix-fmt-sgbrg16:
-.. _v4l2-pix-fmt-sgrbg16:
-
-
-***************************************************************************************************************************
-V4L2_PIX_FMT_SRGGB16 ('RG16'), V4L2_PIX_FMT_SGRBG16 ('GR16'), V4L2_PIX_FMT_SGBRG16 ('GB16'), V4L2_PIX_FMT_SBGGR16 ('BYR2'),
-***************************************************************************************************************************
-
-
-16-bit Bayer formats
-
-
-Description
-===========
-
-These four pixel formats are raw sRGB / Bayer formats with 16 bits per
-sample. Each sample is stored in a 16-bit word. Each n-pixel row contains
-n/2 green samples and n/2 blue or red samples, with alternating red and blue
-rows. Bytes are stored in memory in little endian order. They are
-conventionally described as GRGR... BGBG..., RGRG... GBGB..., etc. Below is
-an example of a small V4L2_PIX_FMT_SBGGR16 image:
-
-**Byte Order.**
-Each cell is one byte.
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - start + 0:
-      - B\ :sub:`00low`
-      - B\ :sub:`00high`
-      - G\ :sub:`01low`
-      - G\ :sub:`01high`
-      - B\ :sub:`02low`
-      - B\ :sub:`02high`
-      - G\ :sub:`03low`
-      - G\ :sub:`03high`
-    * - start + 8:
-      - G\ :sub:`10low`
-      - G\ :sub:`10high`
-      - R\ :sub:`11low`
-      - R\ :sub:`11high`
-      - G\ :sub:`12low`
-      - G\ :sub:`12high`
-      - R\ :sub:`13low`
-      - R\ :sub:`13high`
-    * - start + 16:
-      - B\ :sub:`20low`
-      - B\ :sub:`20high`
-      - G\ :sub:`21low`
-      - G\ :sub:`21high`
-      - B\ :sub:`22low`
-      - B\ :sub:`22high`
-      - G\ :sub:`23low`
-      - G\ :sub:`23high`
-    * - start + 24:
-      - G\ :sub:`30low`
-      - G\ :sub:`30high`
-      - R\ :sub:`31low`
-      - R\ :sub:`31high`
-      - G\ :sub:`32low`
-      - G\ :sub:`32high`
-      - R\ :sub:`33low`
-      - R\ :sub:`33high`
diff --git a/Documentation/media/uapi/v4l/pixfmt-srggb8.rst b/Documentation/media/uapi/v4l/pixfmt-srggb8.rst
deleted file mode 100644
index f5233c1e2314..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-srggb8.rst
+++ /dev/null
@@ -1,61 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-SRGGB8:
-.. _v4l2-pix-fmt-sbggr8:
-.. _v4l2-pix-fmt-sgbrg8:
-.. _v4l2-pix-fmt-sgrbg8:
-
-***************************************************************************************************************************
-V4L2_PIX_FMT_SRGGB8 ('RGGB'), V4L2_PIX_FMT_SGRBG8 ('GRBG'), V4L2_PIX_FMT_SGBRG8 ('GBRG'), V4L2_PIX_FMT_SBGGR8 ('BA81'),
-***************************************************************************************************************************
-
-
-8-bit Bayer formats
-
-
-Description
-===========
-
-These four pixel formats are raw sRGB / Bayer formats with 8 bits per
-sample. Each sample is stored in a byte. Each n-pixel row contains n/2
-green samples and n/2 blue or red samples, with alternating red and
-blue rows. They are conventionally described as GRGR... BGBG...,
-RGRG... GBGB..., etc. Below is an example of a small V4L2_PIX_FMT_SBGGR8 image:
-
-**Byte Order.**
-Each cell is one byte.
-
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - start + 0:
-      - B\ :sub:`00`
-      - G\ :sub:`01`
-      - B\ :sub:`02`
-      - G\ :sub:`03`
-    * - start + 4:
-      - G\ :sub:`10`
-      - R\ :sub:`11`
-      - G\ :sub:`12`
-      - R\ :sub:`13`
-    * - start + 8:
-      - B\ :sub:`20`
-      - G\ :sub:`21`
-      - B\ :sub:`22`
-      - G\ :sub:`23`
-    * - start + 12:
-      - G\ :sub:`30`
-      - R\ :sub:`31`
-      - G\ :sub:`32`
-      - R\ :sub:`33`
diff --git a/Documentation/media/uapi/v4l/pixfmt-tch-td08.rst b/Documentation/media/uapi/v4l/pixfmt-tch-td08.rst
deleted file mode 100644
index b7d3d6ccebc5..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-tch-td08.rst
+++ /dev/null
@@ -1,59 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-TCH-FMT-DELTA-TD08:
-
-********************************
-V4L2_TCH_FMT_DELTA_TD08 ('TD08')
-********************************
-
-*man V4L2_TCH_FMT_DELTA_TD08(2)*
-
-8-bit signed Touch Delta
-
-Description
-===========
-
-This format represents delta data from a touch controller.
-
-Delta values may range from -128 to 127. Typically the values will vary through
-a small range depending on whether the sensor is touched or not. The full value
-may be seen if one of the touchscreen nodes has a fault or the line is not
-connected.
-
-**Byte Order.**
-Each cell is one byte.
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       2 1 1 1 1
-
-    * - start + 0:
-      - D'\ :sub:`00`
-      - D'\ :sub:`01`
-      - D'\ :sub:`02`
-      - D'\ :sub:`03`
-    * - start + 4:
-      - D'\ :sub:`10`
-      - D'\ :sub:`11`
-      - D'\ :sub:`12`
-      - D'\ :sub:`13`
-    * - start + 8:
-      - D'\ :sub:`20`
-      - D'\ :sub:`21`
-      - D'\ :sub:`22`
-      - D'\ :sub:`23`
-    * - start + 12:
-      - D'\ :sub:`30`
-      - D'\ :sub:`31`
-      - D'\ :sub:`32`
-      - D'\ :sub:`33`
diff --git a/Documentation/media/uapi/v4l/pixfmt-tch-td16.rst b/Documentation/media/uapi/v4l/pixfmt-tch-td16.rst
deleted file mode 100644
index 6f1be873bec1..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-tch-td16.rst
+++ /dev/null
@@ -1,74 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-TCH-FMT-DELTA-TD16:
-
-********************************
-V4L2_TCH_FMT_DELTA_TD16 ('TD16')
-********************************
-
-*man V4L2_TCH_FMT_DELTA_TD16(2)*
-
-16-bit signed little endian Touch Delta
-
-
-Description
-===========
-
-This format represents delta data from a touch controller.
-
-Delta values may range from -32768 to 32767. Typically the values will vary
-through a small range depending on whether the sensor is touched or not. The
-full value may be seen if one of the touchscreen nodes has a fault or the line
-is not connected.
-
-**Byte Order.**
-Each cell is one byte.
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       2 1 1 1 1 1 1 1 1
-
-    * - start + 0:
-      - D'\ :sub:`00low`
-      - D'\ :sub:`00high`
-      - D'\ :sub:`01low`
-      - D'\ :sub:`01high`
-      - D'\ :sub:`02low`
-      - D'\ :sub:`02high`
-      - D'\ :sub:`03low`
-      - D'\ :sub:`03high`
-    * - start + 8:
-      - D'\ :sub:`10low`
-      - D'\ :sub:`10high`
-      - D'\ :sub:`11low`
-      - D'\ :sub:`11high`
-      - D'\ :sub:`12low`
-      - D'\ :sub:`12high`
-      - D'\ :sub:`13low`
-      - D'\ :sub:`13high`
-    * - start + 16:
-      - D'\ :sub:`20low`
-      - D'\ :sub:`20high`
-      - D'\ :sub:`21low`
-      - D'\ :sub:`21high`
-      - D'\ :sub:`22low`
-      - D'\ :sub:`22high`
-      - D'\ :sub:`23low`
-      - D'\ :sub:`23high`
-    * - start + 24:
-      - D'\ :sub:`30low`
-      - D'\ :sub:`30high`
-      - D'\ :sub:`31low`
-      - D'\ :sub:`31high`
-      - D'\ :sub:`32low`
-      - D'\ :sub:`32high`
-      - D'\ :sub:`33low`
-      - D'\ :sub:`33high`
diff --git a/Documentation/media/uapi/v4l/pixfmt-tch-tu08.rst b/Documentation/media/uapi/v4l/pixfmt-tch-tu08.rst
deleted file mode 100644
index 2d447475aaa7..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-tch-tu08.rst
+++ /dev/null
@@ -1,57 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-TCH-FMT-TU08:
-
-**************************
-V4L2_TCH_FMT_TU08 ('TU08')
-**************************
-
-*man V4L2_TCH_FMT_TU08(2)*
-
-8-bit unsigned raw touch data
-
-Description
-===========
-
-This format represents unsigned 8-bit data from a touch controller.
-
-This may be used for output for raw and reference data. Values may range from
-0 to 255.
-
-**Byte Order.**
-Each cell is one byte.
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       2 1 1 1 1
-
-    * - start + 0:
-      - R'\ :sub:`00`
-      - R'\ :sub:`01`
-      - R'\ :sub:`02`
-      - R'\ :sub:`03`
-    * - start + 4:
-      - R'\ :sub:`10`
-      - R'\ :sub:`11`
-      - R'\ :sub:`12`
-      - R'\ :sub:`13`
-    * - start + 8:
-      - R'\ :sub:`20`
-      - R'\ :sub:`21`
-      - R'\ :sub:`22`
-      - R'\ :sub:`23`
-    * - start + 12:
-      - R'\ :sub:`30`
-      - R'\ :sub:`31`
-      - R'\ :sub:`32`
-      - R'\ :sub:`33`
diff --git a/Documentation/media/uapi/v4l/pixfmt-tch-tu16.rst b/Documentation/media/uapi/v4l/pixfmt-tch-tu16.rst
deleted file mode 100644
index cb3da6687a58..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-tch-tu16.rst
+++ /dev/null
@@ -1,73 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-TCH-FMT-TU16:
-
-********************************
-V4L2_TCH_FMT_TU16 ('TU16')
-********************************
-
-*man V4L2_TCH_FMT_TU16(2)*
-
-16-bit unsigned little endian raw touch data
-
-
-Description
-===========
-
-This format represents unsigned 16-bit data from a touch controller.
-
-This may be used for output for raw and reference data. Values may range from
-0 to 65535.
-
-**Byte Order.**
-Each cell is one byte.
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       2 1 1 1 1 1 1 1 1
-
-    * - start + 0:
-      - R'\ :sub:`00low`
-      - R'\ :sub:`00high`
-      - R'\ :sub:`01low`
-      - R'\ :sub:`01high`
-      - R'\ :sub:`02low`
-      - R'\ :sub:`02high`
-      - R'\ :sub:`03low`
-      - R'\ :sub:`03high`
-    * - start + 8:
-      - R'\ :sub:`10low`
-      - R'\ :sub:`10high`
-      - R'\ :sub:`11low`
-      - R'\ :sub:`11high`
-      - R'\ :sub:`12low`
-      - R'\ :sub:`12high`
-      - R'\ :sub:`13low`
-      - R'\ :sub:`13high`
-    * - start + 16:
-      - R'\ :sub:`20low`
-      - R'\ :sub:`20high`
-      - R'\ :sub:`21low`
-      - R'\ :sub:`21high`
-      - R'\ :sub:`22low`
-      - R'\ :sub:`22high`
-      - R'\ :sub:`23low`
-      - R'\ :sub:`23high`
-    * - start + 24:
-      - R'\ :sub:`30low`
-      - R'\ :sub:`30high`
-      - R'\ :sub:`31low`
-      - R'\ :sub:`31high`
-      - R'\ :sub:`32low`
-      - R'\ :sub:`32high`
-      - R'\ :sub:`33low`
-      - R'\ :sub:`33high`
diff --git a/Documentation/media/uapi/v4l/pixfmt-uv8.rst b/Documentation/media/uapi/v4l/pixfmt-uv8.rst
deleted file mode 100644
index 6008c898305d..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-uv8.rst
+++ /dev/null
@@ -1,54 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-UV8:
-
-************************
-V4L2_PIX_FMT_UV8 ('UV8')
-************************
-
-
-UV plane interleaved
-
-
-Description
-===========
-
-In this format there is no Y plane, Only CbCr plane. ie (UV interleaved)
-
-**Byte Order.**
-Each cell is one byte.
-
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - start + 0:
-      - Cb\ :sub:`00`
-      - Cr\ :sub:`00`
-      - Cb\ :sub:`01`
-      - Cr\ :sub:`01`
-    * - start + 4:
-      - Cb\ :sub:`10`
-      - Cr\ :sub:`10`
-      - Cb\ :sub:`11`
-      - Cr\ :sub:`11`
-    * - start + 8:
-      - Cb\ :sub:`20`
-      - Cr\ :sub:`20`
-      - Cb\ :sub:`21`
-      - Cr\ :sub:`21`
-    * - start + 12:
-      - Cb\ :sub:`30`
-      - Cr\ :sub:`30`
-      - Cb\ :sub:`31`
-      - Cr\ :sub:`31`
diff --git a/Documentation/media/uapi/v4l/pixfmt-uyvy.rst b/Documentation/media/uapi/v4l/pixfmt-uyvy.rst
deleted file mode 100644
index 72da2639d37e..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-uyvy.rst
+++ /dev/null
@@ -1,117 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-UYVY:
-
-**************************
-V4L2_PIX_FMT_UYVY ('UYVY')
-**************************
-
-
-Variation of ``V4L2_PIX_FMT_YUYV`` with different order of samples in
-memory
-
-
-Description
-===========
-
-In this format each four bytes is two pixels. Each four bytes is two
-Y's, a Cb and a Cr. Each Y goes to one of the pixels, and the Cb and Cr
-belong to both pixels. As you can see, the Cr and Cb components have
-half the horizontal resolution of the Y component.
-
-**Byte Order.**
-Each cell is one byte.
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - start + 0:
-      - Cb\ :sub:`00`
-      - Y'\ :sub:`00`
-      - Cr\ :sub:`00`
-      - Y'\ :sub:`01`
-      - Cb\ :sub:`01`
-      - Y'\ :sub:`02`
-      - Cr\ :sub:`01`
-      - Y'\ :sub:`03`
-    * - start + 8:
-      - Cb\ :sub:`10`
-      - Y'\ :sub:`10`
-      - Cr\ :sub:`10`
-      - Y'\ :sub:`11`
-      - Cb\ :sub:`11`
-      - Y'\ :sub:`12`
-      - Cr\ :sub:`11`
-      - Y'\ :sub:`13`
-    * - start + 16:
-      - Cb\ :sub:`20`
-      - Y'\ :sub:`20`
-      - Cr\ :sub:`20`
-      - Y'\ :sub:`21`
-      - Cb\ :sub:`21`
-      - Y'\ :sub:`22`
-      - Cr\ :sub:`21`
-      - Y'\ :sub:`23`
-    * - start + 24:
-      - Cb\ :sub:`30`
-      - Y'\ :sub:`30`
-      - Cr\ :sub:`30`
-      - Y'\ :sub:`31`
-      - Cb\ :sub:`31`
-      - Y'\ :sub:`32`
-      - Cr\ :sub:`31`
-      - Y'\ :sub:`33`
-
-
-**Color Sample Location:**
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * -
-      - 0
-      -
-      - 1
-      - 2
-      -
-      - 3
-    * - 0
-      - Y
-      - C
-      - Y
-      - Y
-      - C
-      - Y
-    * - 1
-      - Y
-      - C
-      - Y
-      - Y
-      - C
-      - Y
-    * - 2
-      - Y
-      - C
-      - Y
-      - Y
-      - C
-      - Y
-    * - 3
-      - Y
-      - C
-      - Y
-      - Y
-      - C
-      - Y
diff --git a/Documentation/media/uapi/v4l/pixfmt-v4l2-mplane.rst b/Documentation/media/uapi/v4l/pixfmt-v4l2-mplane.rst
deleted file mode 100644
index 054275c0dfc1..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-v4l2-mplane.rst
+++ /dev/null
@@ -1,138 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-******************************
-Multi-planar format structures
-******************************
-
-The struct :c:type:`v4l2_plane_pix_format` structures define size
-and layout for each of the planes in a multi-planar format. The
-struct :c:type:`v4l2_pix_format_mplane` structure contains
-information common to all planes (such as image width and height) and an
-array of struct :c:type:`v4l2_plane_pix_format` structures,
-describing all planes of that format.
-
-
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. c:type:: v4l2_plane_pix_format
-
-.. flat-table:: struct v4l2_plane_pix_format
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``sizeimage``
-      - Maximum size in bytes required for image data in this plane,
-	set by the driver. When the image consists of variable length
-	compressed data this is the number of bytes required by the
-	codec to support the worst-case compression scenario.
-
-	The driver will set the value for uncompressed images.
-
-	Clients are allowed to set the sizeimage field for variable length
-	compressed data flagged with ``V4L2_FMT_FLAG_COMPRESSED`` at
-	:ref:`VIDIOC_ENUM_FMT`, but the driver may ignore it and set the
-	value itself, or it may modify the provided value based on
-	alignment requirements or minimum/maximum size requirements.
-	If the client wants to leave this to the driver, then it should
-	set sizeimage to 0.
-    * - __u32
-      - ``bytesperline``
-      - Distance in bytes between the leftmost pixels in two adjacent
-	lines. See struct :c:type:`v4l2_pix_format`.
-    * - __u16
-      - ``reserved[6]``
-      - Reserved for future extensions. Should be zeroed by drivers and
-	applications.
-
-
-.. raw:: latex
-
-    \small
-
-.. tabularcolumns:: |p{4.4cm}|p{5.6cm}|p{7.5cm}|
-
-.. c:type:: v4l2_pix_format_mplane
-
-.. flat-table:: struct v4l2_pix_format_mplane
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``width``
-      - Image width in pixels. See struct
-	:c:type:`v4l2_pix_format`.
-    * - __u32
-      - ``height``
-      - Image height in pixels. See struct
-	:c:type:`v4l2_pix_format`.
-    * - __u32
-      - ``pixelformat``
-      - The pixel format. Both single- and multi-planar four character
-	codes can be used.
-    * - __u32
-      - ``field``
-      - Field order, from enum :c:type:`v4l2_field`.
-        See struct :c:type:`v4l2_pix_format`.
-    * - __u32
-      - ``colorspace``
-      - Colorspace encoding, from enum :c:type:`v4l2_colorspace`.
-        See struct :c:type:`v4l2_pix_format`.
-    * - struct :c:type:`v4l2_plane_pix_format`
-      - ``plane_fmt[VIDEO_MAX_PLANES]``
-      - An array of structures describing format of each plane this pixel
-	format consists of. The number of valid entries in this array has
-	to be put in the ``num_planes`` field.
-    * - __u8
-      - ``num_planes``
-      - Number of planes (i.e. separate memory buffers) for this format
-	and the number of valid entries in the ``plane_fmt`` array.
-    * - __u8
-      - ``flags``
-      - Flags set by the application or driver, see :ref:`format-flags`.
-    * - union {
-      - (anonymous)
-    * - __u8
-      - ``ycbcr_enc``
-      - Y'CbCr encoding, from enum :c:type:`v4l2_ycbcr_encoding`.
-        This information supplements the ``colorspace`` and must be set by
-	the driver for capture streams and by the application for output
-	streams, see :ref:`colorspaces`.
-    * - __u8
-      - ``hsv_enc``
-      - HSV encoding, from enum :c:type:`v4l2_hsv_encoding`.
-        This information supplements the ``colorspace`` and must be set by
-	the driver for capture streams and by the application for output
-	streams, see :ref:`colorspaces`.
-    * - }
-      -
-    * - __u8
-      - ``quantization``
-      - Quantization range, from enum :c:type:`v4l2_quantization`.
-        This information supplements the ``colorspace`` and must be set by
-	the driver for capture streams and by the application for output
-	streams, see :ref:`colorspaces`.
-    * - __u8
-      - ``xfer_func``
-      - Transfer function, from enum :c:type:`v4l2_xfer_func`.
-        This information supplements the ``colorspace`` and must be set by
-	the driver for capture streams and by the application for output
-	streams, see :ref:`colorspaces`.
-    * - __u8
-      - ``reserved[7]``
-      - Reserved for future extensions. Should be zeroed by drivers and
-	applications.
-
-.. raw:: latex
-
-    \normalsize
diff --git a/Documentation/media/uapi/v4l/pixfmt-v4l2.rst b/Documentation/media/uapi/v4l/pixfmt-v4l2.rst
deleted file mode 100644
index a993b861bf75..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-v4l2.rst
+++ /dev/null
@@ -1,171 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-******************************
-Single-planar format structure
-******************************
-
-.. tabularcolumns:: |p{4.0cm}|p{2.5cm}|p{11.0cm}|
-
-.. c:type:: v4l2_pix_format
-
-.. cssclass:: longtable
-
-.. flat-table:: struct v4l2_pix_format
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``width``
-      - Image width in pixels.
-    * - __u32
-      - ``height``
-      - Image height in pixels. If ``field`` is one of ``V4L2_FIELD_TOP``,
-	``V4L2_FIELD_BOTTOM`` or ``V4L2_FIELD_ALTERNATE`` then height
-	refers to the number of lines in the field, otherwise it refers to
-	the number of lines in the frame (which is twice the field height
-	for interlaced formats).
-    * - :cspan:`2` Applications set these fields to request an image
-	size, drivers return the closest possible values. In case of
-	planar formats the ``width`` and ``height`` applies to the largest
-	plane. To avoid ambiguities drivers must return values rounded up
-	to a multiple of the scale factor of any smaller planes. For
-	example when the image format is YUV 4:2:0, ``width`` and
-	``height`` must be multiples of two.
-
-	For compressed formats that contain the resolution information encoded
-	inside the stream, when fed to a stateful mem2mem decoder, the fields
-	may be zero to rely on the decoder to detect the right values. For more
-	details see :ref:`decoder` and format descriptions.
-    * - __u32
-      - ``pixelformat``
-      - The pixel format or type of compression, set by the application.
-	This is a little endian
-	:ref:`four character code <v4l2-fourcc>`. V4L2 defines standard
-	RGB formats in :ref:`pixfmt-rgb`, YUV formats in
-	:ref:`yuv-formats`, and reserved codes in
-	:ref:`reserved-formats`
-    * - __u32
-      - ``field``
-      - Field order, from enum :c:type:`v4l2_field`.
-        Video images are typically interlaced. Applications can request to
-	capture or output only the top or bottom field, or both fields
-	interlaced or sequentially stored in one buffer or alternating in
-	separate buffers. Drivers return the actual field order selected.
-	For more details on fields see :ref:`field-order`.
-    * - __u32
-      - ``bytesperline``
-      - Distance in bytes between the leftmost pixels in two adjacent
-	lines.
-    * - :cspan:`2`
-
-	Both applications and drivers can set this field to request
-	padding bytes at the end of each line. Drivers however may ignore
-	the value requested by the application, returning ``width`` times
-	bytes per pixel or a larger value required by the hardware. That
-	implies applications can just set this field to zero to get a
-	reasonable default.
-
-	Video hardware may access padding bytes, therefore they must
-	reside in accessible memory. Consider cases where padding bytes
-	after the last line of an image cross a system page boundary.
-	Input devices may write padding bytes, the value is undefined.
-	Output devices ignore the contents of padding bytes.
-
-	When the image format is planar the ``bytesperline`` value applies
-	to the first plane and is divided by the same factor as the
-	``width`` field for the other planes. For example the Cb and Cr
-	planes of a YUV 4:2:0 image have half as many padding bytes
-	following each line as the Y plane. To avoid ambiguities drivers
-	must return a ``bytesperline`` value rounded up to a multiple of
-	the scale factor.
-
-	For compressed formats the ``bytesperline`` value makes no sense.
-	Applications and drivers must set this to 0 in that case.
-    * - __u32
-      - ``sizeimage``
-      - Size in bytes of the buffer to hold a complete image, set by the
-	driver. Usually this is ``bytesperline`` times ``height``. When
-	the image consists of variable length compressed data this is the
-	number of bytes required by the codec to support the worst-case
-	compression scenario.
-
-	The driver will set the value for uncompressed images.
-
-	Clients are allowed to set the sizeimage field for variable length
-	compressed data flagged with ``V4L2_FMT_FLAG_COMPRESSED`` at
-	:ref:`VIDIOC_ENUM_FMT`, but the driver may ignore it and set the
-	value itself, or it may modify the provided value based on
-	alignment requirements or minimum/maximum size requirements.
-	If the client wants to leave this to the driver, then it should
-	set sizeimage to 0.
-    * - __u32
-      - ``colorspace``
-      - Image colorspace, from enum :c:type:`v4l2_colorspace`.
-        This information supplements the ``pixelformat`` and must be set
-	by the driver for capture streams and by the application for
-	output streams, see :ref:`colorspaces`.
-    * - __u32
-      - ``priv``
-      - This field indicates whether the remaining fields of the
-	struct :c:type:`v4l2_pix_format`, also called the
-	extended fields, are valid. When set to
-	``V4L2_PIX_FMT_PRIV_MAGIC``, it indicates that the extended fields
-	have been correctly initialized. When set to any other value it
-	indicates that the extended fields contain undefined values.
-
-	Applications that wish to use the pixel format extended fields
-	must first ensure that the feature is supported by querying the
-	device for the :ref:`V4L2_CAP_EXT_PIX_FORMAT <querycap>`
-	capability. If the capability isn't set the pixel format extended
-	fields are not supported and using the extended fields will lead
-	to undefined results.
-
-	To use the extended fields, applications must set the ``priv``
-	field to ``V4L2_PIX_FMT_PRIV_MAGIC``, initialize all the extended
-	fields and zero the unused bytes of the
-	struct :c:type:`v4l2_format` ``raw_data`` field.
-
-	When the ``priv`` field isn't set to ``V4L2_PIX_FMT_PRIV_MAGIC``
-	drivers must act as if all the extended fields were set to zero.
-	On return drivers must set the ``priv`` field to
-	``V4L2_PIX_FMT_PRIV_MAGIC`` and all the extended fields to
-	applicable values.
-    * - __u32
-      - ``flags``
-      - Flags set by the application or driver, see :ref:`format-flags`.
-    * - union {
-      - (anonymous)
-    * - __u32
-      - ``ycbcr_enc``
-      - Y'CbCr encoding, from enum :c:type:`v4l2_ycbcr_encoding`.
-        This information supplements the ``colorspace`` and must be set by
-	the driver for capture streams and by the application for output
-	streams, see :ref:`colorspaces`.
-    * - __u32
-      - ``hsv_enc``
-      - HSV encoding, from enum :c:type:`v4l2_hsv_encoding`.
-        This information supplements the ``colorspace`` and must be set by
-	the driver for capture streams and by the application for output
-	streams, see :ref:`colorspaces`.
-    * - }
-      -
-    * - __u32
-      - ``quantization``
-      - Quantization range, from enum :c:type:`v4l2_quantization`.
-        This information supplements the ``colorspace`` and must be set by
-	the driver for capture streams and by the application for output
-	streams, see :ref:`colorspaces`.
-    * - __u32
-      - ``xfer_func``
-      - Transfer function, from enum :c:type:`v4l2_xfer_func`.
-        This information supplements the ``colorspace`` and must be set by
-	the driver for capture streams and by the application for output
-	streams, see :ref:`colorspaces`.
diff --git a/Documentation/media/uapi/v4l/pixfmt-vyuy.rst b/Documentation/media/uapi/v4l/pixfmt-vyuy.rst
deleted file mode 100644
index 39b99707cd99..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-vyuy.rst
+++ /dev/null
@@ -1,115 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-VYUY:
-
-**************************
-V4L2_PIX_FMT_VYUY ('VYUY')
-**************************
-
-
-Variation of ``V4L2_PIX_FMT_YUYV`` with different order of samples in
-memory
-
-
-Description
-===========
-
-In this format each four bytes is two pixels. Each four bytes is two
-Y's, a Cb and a Cr. Each Y goes to one of the pixels, and the Cb and Cr
-belong to both pixels. As you can see, the Cr and Cb components have
-half the horizontal resolution of the Y component.
-
-**Byte Order.**
-Each cell is one byte.
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - start + 0:
-      - Cr\ :sub:`00`
-      - Y'\ :sub:`00`
-      - Cb\ :sub:`00`
-      - Y'\ :sub:`01`
-      - Cr\ :sub:`01`
-      - Y'\ :sub:`02`
-      - Cb\ :sub:`01`
-      - Y'\ :sub:`03`
-    * - start + 8:
-      - Cr\ :sub:`10`
-      - Y'\ :sub:`10`
-      - Cb\ :sub:`10`
-      - Y'\ :sub:`11`
-      - Cr\ :sub:`11`
-      - Y'\ :sub:`12`
-      - Cb\ :sub:`11`
-      - Y'\ :sub:`13`
-    * - start + 16:
-      - Cr\ :sub:`20`
-      - Y'\ :sub:`20`
-      - Cb\ :sub:`20`
-      - Y'\ :sub:`21`
-      - Cr\ :sub:`21`
-      - Y'\ :sub:`22`
-      - Cb\ :sub:`21`
-      - Y'\ :sub:`23`
-    * - start + 24:
-      - Cr\ :sub:`30`
-      - Y'\ :sub:`30`
-      - Cb\ :sub:`30`
-      - Y'\ :sub:`31`
-      - Cr\ :sub:`31`
-      - Y'\ :sub:`32`
-      - Cb\ :sub:`31`
-      - Y'\ :sub:`33`
-
-
-**Color Sample Location:**
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * -
-      - 0
-      -
-      - 1
-      -
-      - 2
-      - 3
-    * - 0
-      - Y
-      - C
-      - Y
-      - Y
-      - C
-      - Y
-    * - 1
-      - Y
-      - C
-      - Y
-      - Y
-      - C
-      - Y
-    * - 2
-      - Y
-      - C
-      - Y
-      - Y
-      - C
-      - Y
-    * - 3
-      - Y
-      - C
-      - Y
-      - Y
-      - C
-      - Y
diff --git a/Documentation/media/uapi/v4l/pixfmt-y10.rst b/Documentation/media/uapi/v4l/pixfmt-y10.rst
deleted file mode 100644
index 63277686764a..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-y10.rst
+++ /dev/null
@@ -1,72 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-Y10:
-
-*************************
-V4L2_PIX_FMT_Y10 ('Y10 ')
-*************************
-
-
-Grey-scale image
-
-
-Description
-===========
-
-This is a grey-scale image with a depth of 10 bits per pixel. Pixels are
-stored in 16-bit words with unused high bits padded with 0. The least
-significant byte is stored at lower memory addresses (little-endian).
-
-**Byte Order.**
-Each cell is one byte.
-
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - start + 0:
-      - Y'\ :sub:`00low`
-      - Y'\ :sub:`00high`
-      - Y'\ :sub:`01low`
-      - Y'\ :sub:`01high`
-      - Y'\ :sub:`02low`
-      - Y'\ :sub:`02high`
-      - Y'\ :sub:`03low`
-      - Y'\ :sub:`03high`
-    * - start + 8:
-      - Y'\ :sub:`10low`
-      - Y'\ :sub:`10high`
-      - Y'\ :sub:`11low`
-      - Y'\ :sub:`11high`
-      - Y'\ :sub:`12low`
-      - Y'\ :sub:`12high`
-      - Y'\ :sub:`13low`
-      - Y'\ :sub:`13high`
-    * - start + 16:
-      - Y'\ :sub:`20low`
-      - Y'\ :sub:`20high`
-      - Y'\ :sub:`21low`
-      - Y'\ :sub:`21high`
-      - Y'\ :sub:`22low`
-      - Y'\ :sub:`22high`
-      - Y'\ :sub:`23low`
-      - Y'\ :sub:`23high`
-    * - start + 24:
-      - Y'\ :sub:`30low`
-      - Y'\ :sub:`30high`
-      - Y'\ :sub:`31low`
-      - Y'\ :sub:`31high`
-      - Y'\ :sub:`32low`
-      - Y'\ :sub:`32high`
-      - Y'\ :sub:`33low`
-      - Y'\ :sub:`33high`
diff --git a/Documentation/media/uapi/v4l/pixfmt-y10b.rst b/Documentation/media/uapi/v4l/pixfmt-y10b.rst
deleted file mode 100644
index 49c4dd432413..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-y10b.rst
+++ /dev/null
@@ -1,40 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-Y10BPACK:
-
-******************************
-V4L2_PIX_FMT_Y10BPACK ('Y10B')
-******************************
-
-Grey-scale image as a bit-packed array
-
-
-Description
-===========
-
-This is a packed grey-scale image format with a depth of 10 bits per
-pixel. Pixels are stored in a bit-packed array of 10bit bits per pixel,
-with no padding between them and with the most significant bits coming
-first from the left.
-
-**Bit-packed representation.**
-
-pixels cross the byte boundary and have a ratio of 5 bytes for each 4
-pixels.
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - Y'\ :sub:`00[9:2]`
-      - Y'\ :sub:`00[1:0]`\ Y'\ :sub:`01[9:4]`
-      - Y'\ :sub:`01[3:0]`\ Y'\ :sub:`02[9:6]`
-      - Y'\ :sub:`02[5:0]`\ Y'\ :sub:`03[9:8]`
-      - Y'\ :sub:`03[7:0]`
diff --git a/Documentation/media/uapi/v4l/pixfmt-y10p.rst b/Documentation/media/uapi/v4l/pixfmt-y10p.rst
deleted file mode 100644
index 39cd789dcb59..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-y10p.rst
+++ /dev/null
@@ -1,50 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-Y10P:
-
-******************************
-V4L2_PIX_FMT_Y10P ('Y10P')
-******************************
-
-Grey-scale image as a MIPI RAW10 packed array
-
-
-Description
-===========
-
-This is a packed grey-scale image format with a depth of 10 bits per
-pixel. Every four consecutive pixels are packed into 5 bytes. Each of
-the first 4 bytes contain the 8 high order bits of the pixels, and
-the 5th byte contains the 2 least significants bits of each pixel,
-in the same order.
-
-**Bit-packed representation.**
-
-.. raw:: latex
-
-    \small
-
-.. tabularcolumns:: |p{1.2cm}||p{1.2cm}||p{1.2cm}||p{1.2cm}|p{3.2cm}|p{3.2cm}|
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths: 8 8 8 8 64
-
-    * - Y'\ :sub:`00[9:2]`
-      - Y'\ :sub:`01[9:2]`
-      - Y'\ :sub:`02[9:2]`
-      - Y'\ :sub:`03[9:2]`
-      - Y'\ :sub:`03[1:0]`\ (bits 7--6) Y'\ :sub:`02[1:0]`\ (bits 5--4)
-	Y'\ :sub:`01[1:0]`\ (bits 3--2) Y'\ :sub:`00[1:0]`\ (bits 1--0)
-
-.. raw:: latex
-
-    \normalsize
diff --git a/Documentation/media/uapi/v4l/pixfmt-y12.rst b/Documentation/media/uapi/v4l/pixfmt-y12.rst
deleted file mode 100644
index 33a943b4996a..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-y12.rst
+++ /dev/null
@@ -1,72 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-Y12:
-
-*************************
-V4L2_PIX_FMT_Y12 ('Y12 ')
-*************************
-
-
-Grey-scale image
-
-
-Description
-===========
-
-This is a grey-scale image with a depth of 12 bits per pixel. Pixels are
-stored in 16-bit words with unused high bits padded with 0. The least
-significant byte is stored at lower memory addresses (little-endian).
-
-**Byte Order.**
-Each cell is one byte.
-
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - start + 0:
-      - Y'\ :sub:`00low`
-      - Y'\ :sub:`00high`
-      - Y'\ :sub:`01low`
-      - Y'\ :sub:`01high`
-      - Y'\ :sub:`02low`
-      - Y'\ :sub:`02high`
-      - Y'\ :sub:`03low`
-      - Y'\ :sub:`03high`
-    * - start + 8:
-      - Y'\ :sub:`10low`
-      - Y'\ :sub:`10high`
-      - Y'\ :sub:`11low`
-      - Y'\ :sub:`11high`
-      - Y'\ :sub:`12low`
-      - Y'\ :sub:`12high`
-      - Y'\ :sub:`13low`
-      - Y'\ :sub:`13high`
-    * - start + 16:
-      - Y'\ :sub:`20low`
-      - Y'\ :sub:`20high`
-      - Y'\ :sub:`21low`
-      - Y'\ :sub:`21high`
-      - Y'\ :sub:`22low`
-      - Y'\ :sub:`22high`
-      - Y'\ :sub:`23low`
-      - Y'\ :sub:`23high`
-    * - start + 24:
-      - Y'\ :sub:`30low`
-      - Y'\ :sub:`30high`
-      - Y'\ :sub:`31low`
-      - Y'\ :sub:`31high`
-      - Y'\ :sub:`32low`
-      - Y'\ :sub:`32high`
-      - Y'\ :sub:`33low`
-      - Y'\ :sub:`33high`
diff --git a/Documentation/media/uapi/v4l/pixfmt-y12i.rst b/Documentation/media/uapi/v4l/pixfmt-y12i.rst
deleted file mode 100644
index 1d4a14e1ec6e..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-y12i.rst
+++ /dev/null
@@ -1,43 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-Y12I:
-
-**************************
-V4L2_PIX_FMT_Y12I ('Y12I')
-**************************
-
-Interleaved grey-scale image, e.g. from a stereo-pair
-
-
-Description
-===========
-
-This is a grey-scale image with a depth of 12 bits per pixel, but with
-pixels from 2 sources interleaved and bit-packed. Each pixel is stored
-in a 24-bit word in the little-endian order. On a little-endian machine
-these pixels can be deinterlaced using
-
-.. code-block:: c
-
-    __u8 *buf;
-    left0 = 0xfff & *(__u16 *)buf;
-    right0 = *(__u16 *)(buf + 1) >> 4;
-
-**Bit-packed representation.**
-pixels cross the byte boundary and have a ratio of 3 bytes for each
-interleaved pixel.
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - Y'\ :sub:`0left[7:0]`
-      - Y'\ :sub:`0right[3:0]`\ Y'\ :sub:`0left[11:8]`
-      - Y'\ :sub:`0right[11:4]`
diff --git a/Documentation/media/uapi/v4l/pixfmt-y14.rst b/Documentation/media/uapi/v4l/pixfmt-y14.rst
deleted file mode 100644
index 5c260f8da088..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-y14.rst
+++ /dev/null
@@ -1,72 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-Y14:
-
-*************************
-V4L2_PIX_FMT_Y14 ('Y14 ')
-*************************
-
-
-Grey-scale image
-
-
-Description
-===========
-
-This is a grey-scale image with a depth of 14 bits per pixel. Pixels are
-stored in 16-bit words with unused high bits padded with 0. The least
-significant byte is stored at lower memory addresses (little-endian).
-
-**Byte Order.**
-Each cell is one byte.
-
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - start + 0:
-      - Y'\ :sub:`00low`
-      - Y'\ :sub:`00high`
-      - Y'\ :sub:`01low`
-      - Y'\ :sub:`01high`
-      - Y'\ :sub:`02low`
-      - Y'\ :sub:`02high`
-      - Y'\ :sub:`03low`
-      - Y'\ :sub:`03high`
-    * - start + 8:
-      - Y'\ :sub:`10low`
-      - Y'\ :sub:`10high`
-      - Y'\ :sub:`11low`
-      - Y'\ :sub:`11high`
-      - Y'\ :sub:`12low`
-      - Y'\ :sub:`12high`
-      - Y'\ :sub:`13low`
-      - Y'\ :sub:`13high`
-    * - start + 16:
-      - Y'\ :sub:`20low`
-      - Y'\ :sub:`20high`
-      - Y'\ :sub:`21low`
-      - Y'\ :sub:`21high`
-      - Y'\ :sub:`22low`
-      - Y'\ :sub:`22high`
-      - Y'\ :sub:`23low`
-      - Y'\ :sub:`23high`
-    * - start + 24:
-      - Y'\ :sub:`30low`
-      - Y'\ :sub:`30high`
-      - Y'\ :sub:`31low`
-      - Y'\ :sub:`31high`
-      - Y'\ :sub:`32low`
-      - Y'\ :sub:`32high`
-      - Y'\ :sub:`33low`
-      - Y'\ :sub:`33high`
diff --git a/Documentation/media/uapi/v4l/pixfmt-y16-be.rst b/Documentation/media/uapi/v4l/pixfmt-y16-be.rst
deleted file mode 100644
index 1e72bfe2d557..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-y16-be.rst
+++ /dev/null
@@ -1,76 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-Y16-BE:
-
-****************************************
-V4L2_PIX_FMT_Y16_BE ('Y16 ' | (1 << 31))
-****************************************
-
-
-Grey-scale image
-
-
-Description
-===========
-
-This is a grey-scale image with a depth of 16 bits per pixel. The most
-significant byte is stored at lower memory addresses (big-endian).
-
-.. note::
-
-   The actual sampling precision may be lower than 16 bits, for
-   example 10 bits per pixel with values in range 0 to 1023.
-
-**Byte Order.**
-Each cell is one byte.
-
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - start + 0:
-      - Y'\ :sub:`00high`
-      - Y'\ :sub:`00low`
-      - Y'\ :sub:`01high`
-      - Y'\ :sub:`01low`
-      - Y'\ :sub:`02high`
-      - Y'\ :sub:`02low`
-      - Y'\ :sub:`03high`
-      - Y'\ :sub:`03low`
-    * - start + 8:
-      - Y'\ :sub:`10high`
-      - Y'\ :sub:`10low`
-      - Y'\ :sub:`11high`
-      - Y'\ :sub:`11low`
-      - Y'\ :sub:`12high`
-      - Y'\ :sub:`12low`
-      - Y'\ :sub:`13high`
-      - Y'\ :sub:`13low`
-    * - start + 16:
-      - Y'\ :sub:`20high`
-      - Y'\ :sub:`20low`
-      - Y'\ :sub:`21high`
-      - Y'\ :sub:`21low`
-      - Y'\ :sub:`22high`
-      - Y'\ :sub:`22low`
-      - Y'\ :sub:`23high`
-      - Y'\ :sub:`23low`
-    * - start + 24:
-      - Y'\ :sub:`30high`
-      - Y'\ :sub:`30low`
-      - Y'\ :sub:`31high`
-      - Y'\ :sub:`31low`
-      - Y'\ :sub:`32high`
-      - Y'\ :sub:`32low`
-      - Y'\ :sub:`33high`
-      - Y'\ :sub:`33low`
diff --git a/Documentation/media/uapi/v4l/pixfmt-y16.rst b/Documentation/media/uapi/v4l/pixfmt-y16.rst
deleted file mode 100644
index f77d900db131..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-y16.rst
+++ /dev/null
@@ -1,76 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-Y16:
-
-*************************
-V4L2_PIX_FMT_Y16 ('Y16 ')
-*************************
-
-
-Grey-scale image
-
-
-Description
-===========
-
-This is a grey-scale image with a depth of 16 bits per pixel. The least
-significant byte is stored at lower memory addresses (little-endian).
-
-.. note::
-
-   The actual sampling precision may be lower than 16 bits, for
-   example 10 bits per pixel with values in range 0 to 1023.
-
-**Byte Order.**
-Each cell is one byte.
-
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - start + 0:
-      - Y'\ :sub:`00low`
-      - Y'\ :sub:`00high`
-      - Y'\ :sub:`01low`
-      - Y'\ :sub:`01high`
-      - Y'\ :sub:`02low`
-      - Y'\ :sub:`02high`
-      - Y'\ :sub:`03low`
-      - Y'\ :sub:`03high`
-    * - start + 8:
-      - Y'\ :sub:`10low`
-      - Y'\ :sub:`10high`
-      - Y'\ :sub:`11low`
-      - Y'\ :sub:`11high`
-      - Y'\ :sub:`12low`
-      - Y'\ :sub:`12high`
-      - Y'\ :sub:`13low`
-      - Y'\ :sub:`13high`
-    * - start + 16:
-      - Y'\ :sub:`20low`
-      - Y'\ :sub:`20high`
-      - Y'\ :sub:`21low`
-      - Y'\ :sub:`21high`
-      - Y'\ :sub:`22low`
-      - Y'\ :sub:`22high`
-      - Y'\ :sub:`23low`
-      - Y'\ :sub:`23high`
-    * - start + 24:
-      - Y'\ :sub:`30low`
-      - Y'\ :sub:`30high`
-      - Y'\ :sub:`31low`
-      - Y'\ :sub:`31high`
-      - Y'\ :sub:`32low`
-      - Y'\ :sub:`32high`
-      - Y'\ :sub:`33low`
-      - Y'\ :sub:`33high`
diff --git a/Documentation/media/uapi/v4l/pixfmt-y41p.rst b/Documentation/media/uapi/v4l/pixfmt-y41p.rst
deleted file mode 100644
index 829c68afd8d7..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-y41p.rst
+++ /dev/null
@@ -1,158 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-Y41P:
-
-**************************
-V4L2_PIX_FMT_Y41P ('Y41P')
-**************************
-
-
-Format with ¼ horizontal chroma resolution, also known as YUV 4:1:1
-
-
-Description
-===========
-
-In this format each 12 bytes is eight pixels. In the twelve bytes are
-two CbCr pairs and eight Y's. The first CbCr pair goes with the first
-four Y's, and the second CbCr pair goes with the other four Y's. The Cb
-and Cr components have one fourth the horizontal resolution of the Y
-component.
-
-Do not confuse this format with
-:ref:`V4L2_PIX_FMT_YUV411P <V4L2-PIX-FMT-YUV411P>`. Y41P is derived
-from "YUV 4:1:1 *packed*", while YUV411P stands for "YUV 4:1:1
-*planar*".
-
-**Byte Order.**
-Each cell is one byte.
-
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - start + 0:
-      - Cb\ :sub:`00`
-      - Y'\ :sub:`00`
-      - Cr\ :sub:`00`
-      - Y'\ :sub:`01`
-      - Cb\ :sub:`01`
-      - Y'\ :sub:`02`
-      - Cr\ :sub:`01`
-      - Y'\ :sub:`03`
-      - Y'\ :sub:`04`
-      - Y'\ :sub:`05`
-      - Y'\ :sub:`06`
-      - Y'\ :sub:`07`
-    * - start + 12:
-      - Cb\ :sub:`10`
-      - Y'\ :sub:`10`
-      - Cr\ :sub:`10`
-      - Y'\ :sub:`11`
-      - Cb\ :sub:`11`
-      - Y'\ :sub:`12`
-      - Cr\ :sub:`11`
-      - Y'\ :sub:`13`
-      - Y'\ :sub:`14`
-      - Y'\ :sub:`15`
-      - Y'\ :sub:`16`
-      - Y'\ :sub:`17`
-    * - start + 24:
-      - Cb\ :sub:`20`
-      - Y'\ :sub:`20`
-      - Cr\ :sub:`20`
-      - Y'\ :sub:`21`
-      - Cb\ :sub:`21`
-      - Y'\ :sub:`22`
-      - Cr\ :sub:`21`
-      - Y'\ :sub:`23`
-      - Y'\ :sub:`24`
-      - Y'\ :sub:`25`
-      - Y'\ :sub:`26`
-      - Y'\ :sub:`27`
-    * - start + 36:
-      - Cb\ :sub:`30`
-      - Y'\ :sub:`30`
-      - Cr\ :sub:`30`
-      - Y'\ :sub:`31`
-      - Cb\ :sub:`31`
-      - Y'\ :sub:`32`
-      - Cr\ :sub:`31`
-      - Y'\ :sub:`33`
-      - Y'\ :sub:`34`
-      - Y'\ :sub:`35`
-      - Y'\ :sub:`36`
-      - Y'\ :sub:`37`
-
-
-**Color Sample Location:**
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * -
-      - 0
-      - 1
-      -
-      - 2
-      - 3
-      - 4
-      - 5
-      -
-      - 6
-      - 7
-    * - 0
-      - Y
-      - Y
-      - C
-      - Y
-      - Y
-      - Y
-      - Y
-      - C
-      - Y
-      - Y
-    * - 1
-      - Y
-      - Y
-      - C
-      - Y
-      - Y
-      - Y
-      - Y
-      - C
-      - Y
-      - Y
-    * - 2
-      - Y
-      - Y
-      - C
-      - Y
-      - Y
-      - Y
-      - Y
-      - C
-      - Y
-      - Y
-    * - 3
-      - Y
-      - Y
-      - C
-      - Y
-      - Y
-      - Y
-      - Y
-      - C
-      - Y
-      - Y
diff --git a/Documentation/media/uapi/v4l/pixfmt-y8i.rst b/Documentation/media/uapi/v4l/pixfmt-y8i.rst
deleted file mode 100644
index 2c88ed90522d..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-y8i.rst
+++ /dev/null
@@ -1,73 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-Y8I:
-
-*************************
-V4L2_PIX_FMT_Y8I ('Y8I ')
-*************************
-
-
-Interleaved grey-scale image, e.g. from a stereo-pair
-
-
-Description
-===========
-
-This is a grey-scale image with a depth of 8 bits per pixel, but with
-pixels from 2 sources interleaved. Each pixel is stored in a 16-bit
-word. E.g. the R200 RealSense camera stores pixel from the left sensor
-in lower and from the right sensor in the higher 8 bits.
-
-**Byte Order.**
-Each cell is one byte.
-
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - start + 0:
-      - Y'\ :sub:`00left`
-      - Y'\ :sub:`00right`
-      - Y'\ :sub:`01left`
-      - Y'\ :sub:`01right`
-      - Y'\ :sub:`02left`
-      - Y'\ :sub:`02right`
-      - Y'\ :sub:`03left`
-      - Y'\ :sub:`03right`
-    * - start + 8:
-      - Y'\ :sub:`10left`
-      - Y'\ :sub:`10right`
-      - Y'\ :sub:`11left`
-      - Y'\ :sub:`11right`
-      - Y'\ :sub:`12left`
-      - Y'\ :sub:`12right`
-      - Y'\ :sub:`13left`
-      - Y'\ :sub:`13right`
-    * - start + 16:
-      - Y'\ :sub:`20left`
-      - Y'\ :sub:`20right`
-      - Y'\ :sub:`21left`
-      - Y'\ :sub:`21right`
-      - Y'\ :sub:`22left`
-      - Y'\ :sub:`22right`
-      - Y'\ :sub:`23left`
-      - Y'\ :sub:`23right`
-    * - start + 24:
-      - Y'\ :sub:`30left`
-      - Y'\ :sub:`30right`
-      - Y'\ :sub:`31left`
-      - Y'\ :sub:`31right`
-      - Y'\ :sub:`32left`
-      - Y'\ :sub:`32right`
-      - Y'\ :sub:`33left`
-      - Y'\ :sub:`33right`
diff --git a/Documentation/media/uapi/v4l/pixfmt-yuv410.rst b/Documentation/media/uapi/v4l/pixfmt-yuv410.rst
deleted file mode 100644
index ebb72a5c7ceb..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-yuv410.rst
+++ /dev/null
@@ -1,134 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-YVU410:
-.. _v4l2-pix-fmt-yuv410:
-
-**********************************************************
-V4L2_PIX_FMT_YVU410 ('YVU9'), V4L2_PIX_FMT_YUV410 ('YUV9')
-**********************************************************
-
-
-V4L2_PIX_FMT_YUV410
-Planar formats with ¼ horizontal and vertical chroma resolution, also
-known as YUV 4:1:0
-
-
-Description
-===========
-
-These are planar formats, as opposed to a packed format. The three
-components are separated into three sub-images or planes. The Y plane is
-first. The Y plane has one byte per pixel. For ``V4L2_PIX_FMT_YVU410``,
-the Cr plane immediately follows the Y plane in memory. The Cr plane is
-¼ the width and ¼ the height of the Y plane (and of the image). Each Cr
-belongs to 16 pixels, a four-by-four square of the image. Following the
-Cr plane is the Cb plane, just like the Cr plane.
-``V4L2_PIX_FMT_YUV410`` is the same, except the Cb plane comes first,
-then the Cr plane.
-
-If the Y plane has pad bytes after each row, then the Cr and Cb planes
-have ¼ as many pad bytes after their rows. In other words, four Cx rows
-(including padding) are exactly as long as one Y row (including
-padding).
-
-**Byte Order.**
-Each cell is one byte.
-
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - start + 0:
-      - Y'\ :sub:`00`
-      - Y'\ :sub:`01`
-      - Y'\ :sub:`02`
-      - Y'\ :sub:`03`
-    * - start + 4:
-      - Y'\ :sub:`10`
-      - Y'\ :sub:`11`
-      - Y'\ :sub:`12`
-      - Y'\ :sub:`13`
-    * - start + 8:
-      - Y'\ :sub:`20`
-      - Y'\ :sub:`21`
-      - Y'\ :sub:`22`
-      - Y'\ :sub:`23`
-    * - start + 12:
-      - Y'\ :sub:`30`
-      - Y'\ :sub:`31`
-      - Y'\ :sub:`32`
-      - Y'\ :sub:`33`
-    * - start + 16:
-      - Cr\ :sub:`00`
-    * - start + 17:
-      - Cb\ :sub:`00`
-
-
-**Color Sample Location:**
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * -
-      - 0
-      -
-      - 1
-      -
-      - 2
-      -
-      - 3
-    * - 0
-      - Y
-      -
-      - Y
-      -
-      - Y
-      -
-      - Y
-    * -
-    * - 1
-      - Y
-      -
-      - Y
-      -
-      - Y
-      -
-      - Y
-    * -
-      -
-      -
-      -
-      - C
-      -
-      -
-      -
-    * - 2
-      - Y
-      -
-      - Y
-      -
-      - Y
-      -
-      - Y
-    * -
-    * - 3
-      - Y
-      -
-      - Y
-      -
-      - Y
-      -
-      - Y
diff --git a/Documentation/media/uapi/v4l/pixfmt-yuv411p.rst b/Documentation/media/uapi/v4l/pixfmt-yuv411p.rst
deleted file mode 100644
index 83ddaa3f8dfb..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-yuv411p.rst
+++ /dev/null
@@ -1,122 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-YUV411P:
-
-*****************************
-V4L2_PIX_FMT_YUV411P ('411P')
-*****************************
-
-
-Format with ¼ horizontal chroma resolution, also known as YUV 4:1:1.
-Planar layout as opposed to ``V4L2_PIX_FMT_Y41P``
-
-
-Description
-===========
-
-This format is not commonly used. This is a planar format similar to the
-4:2:2 planar format except with half as many chroma. The three
-components are separated into three sub-images or planes. The Y plane is
-first. The Y plane has one byte per pixel. The Cb plane immediately
-follows the Y plane in memory. The Cb plane is ¼ the width of the Y
-plane (and of the image). Each Cb belongs to 4 pixels all on the same
-row. For example, Cb\ :sub:`0` belongs to Y'\ :sub:`00`, Y'\ :sub:`01`,
-Y'\ :sub:`02` and Y'\ :sub:`03`. Following the Cb plane is the Cr plane,
-just like the Cb plane.
-
-If the Y plane has pad bytes after each row, then the Cr and Cb planes
-have ¼ as many pad bytes after their rows. In other words, four C x rows
-(including padding) is exactly as long as one Y row (including padding).
-
-**Byte Order.**
-Each cell is one byte.
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - start + 0:
-      - Y'\ :sub:`00`
-      - Y'\ :sub:`01`
-      - Y'\ :sub:`02`
-      - Y'\ :sub:`03`
-    * - start + 4:
-      - Y'\ :sub:`10`
-      - Y'\ :sub:`11`
-      - Y'\ :sub:`12`
-      - Y'\ :sub:`13`
-    * - start + 8:
-      - Y'\ :sub:`20`
-      - Y'\ :sub:`21`
-      - Y'\ :sub:`22`
-      - Y'\ :sub:`23`
-    * - start + 12:
-      - Y'\ :sub:`30`
-      - Y'\ :sub:`31`
-      - Y'\ :sub:`32`
-      - Y'\ :sub:`33`
-    * - start + 16:
-      - Cb\ :sub:`00`
-    * - start + 17:
-      - Cb\ :sub:`10`
-    * - start + 18:
-      - Cb\ :sub:`20`
-    * - start + 19:
-      - Cb\ :sub:`30`
-    * - start + 20:
-      - Cr\ :sub:`00`
-    * - start + 21:
-      - Cr\ :sub:`10`
-    * - start + 22:
-      - Cr\ :sub:`20`
-    * - start + 23:
-      - Cr\ :sub:`30`
-
-
-**Color Sample Location:**
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * -
-      - 0
-      - 1
-      -
-      - 2
-      - 3
-    * - 0
-      - Y
-      - Y
-      - C
-      - Y
-      - Y
-    * - 1
-      - Y
-      - Y
-      - C
-      - Y
-      - Y
-    * - 2
-      - Y
-      - Y
-      - C
-      - Y
-      - Y
-    * - 3
-      - Y
-      - Y
-      - C
-      - Y
-      - Y
diff --git a/Documentation/media/uapi/v4l/pixfmt-yuv420.rst b/Documentation/media/uapi/v4l/pixfmt-yuv420.rst
deleted file mode 100644
index f4f6f792a23e..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-yuv420.rst
+++ /dev/null
@@ -1,150 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-YVU420:
-.. _V4L2-PIX-FMT-YUV420:
-
-**********************************************************
-V4L2_PIX_FMT_YVU420 ('YV12'), V4L2_PIX_FMT_YUV420 ('YU12')
-**********************************************************
-
-
-V4L2_PIX_FMT_YUV420
-Planar formats with ½ horizontal and vertical chroma resolution, also
-known as YUV 4:2:0
-
-
-Description
-===========
-
-These are planar formats, as opposed to a packed format. The three
-components are separated into three sub- images or planes. The Y plane
-is first. The Y plane has one byte per pixel. For
-``V4L2_PIX_FMT_YVU420``, the Cr plane immediately follows the Y plane in
-memory. The Cr plane is half the width and half the height of the Y
-plane (and of the image). Each Cr belongs to four pixels, a two-by-two
-square of the image. For example, Cr\ :sub:`0` belongs to Y'\ :sub:`00`,
-Y'\ :sub:`01`, Y'\ :sub:`10`, and Y'\ :sub:`11`. Following the Cr plane
-is the Cb plane, just like the Cr plane. ``V4L2_PIX_FMT_YUV420`` is the
-same except the Cb plane comes first, then the Cr plane.
-
-If the Y plane has pad bytes after each row, then the Cr and Cb planes
-have half as many pad bytes after their rows. In other words, two Cx
-rows (including padding) is exactly as long as one Y row (including
-padding).
-
-**Byte Order.**
-Each cell is one byte.
-
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - start + 0:
-      - Y'\ :sub:`00`
-      - Y'\ :sub:`01`
-      - Y'\ :sub:`02`
-      - Y'\ :sub:`03`
-    * - start + 4:
-      - Y'\ :sub:`10`
-      - Y'\ :sub:`11`
-      - Y'\ :sub:`12`
-      - Y'\ :sub:`13`
-    * - start + 8:
-      - Y'\ :sub:`20`
-      - Y'\ :sub:`21`
-      - Y'\ :sub:`22`
-      - Y'\ :sub:`23`
-    * - start + 12:
-      - Y'\ :sub:`30`
-      - Y'\ :sub:`31`
-      - Y'\ :sub:`32`
-      - Y'\ :sub:`33`
-    * - start + 16:
-      - Cr\ :sub:`00`
-      - Cr\ :sub:`01`
-    * - start + 18:
-      - Cr\ :sub:`10`
-      - Cr\ :sub:`11`
-    * - start + 20:
-      - Cb\ :sub:`00`
-      - Cb\ :sub:`01`
-    * - start + 22:
-      - Cb\ :sub:`10`
-      - Cb\ :sub:`11`
-
-
-**Color Sample Location:**
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * -
-      - 0
-      -
-      - 1
-      -
-      - 2
-      -
-      - 3
-    * - 0
-      - Y
-      -
-      - Y
-      -
-      - Y
-      -
-      - Y
-    * -
-      -
-      - C
-      -
-      -
-      -
-      - C
-      -
-    * - 1
-      - Y
-      -
-      - Y
-      -
-      - Y
-      -
-      - Y
-    * -
-    * - 2
-      - Y
-      -
-      - Y
-      -
-      - Y
-      -
-      - Y
-    * -
-      -
-      - C
-      -
-      -
-      -
-      - C
-      -
-    * - 3
-      - Y
-      -
-      - Y
-      -
-      - Y
-      -
-      - Y
diff --git a/Documentation/media/uapi/v4l/pixfmt-yuv420m.rst b/Documentation/media/uapi/v4l/pixfmt-yuv420m.rst
deleted file mode 100644
index c29b30c6445a..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-yuv420m.rst
+++ /dev/null
@@ -1,159 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-YUV420M:
-.. _v4l2-pix-fmt-yvu420m:
-
-************************************************************
-V4L2_PIX_FMT_YUV420M ('YM12'), V4L2_PIX_FMT_YVU420M ('YM21')
-************************************************************
-
-
-V4L2_PIX_FMT_YVU420M
-Variation of ``V4L2_PIX_FMT_YUV420`` and ``V4L2_PIX_FMT_YVU420`` with
-planes non contiguous in memory.
-
-
-Description
-===========
-
-This is a multi-planar format, as opposed to a packed format. The three
-components are separated into three sub-images or planes.
-
-The Y plane is first. The Y plane has one byte per pixel. For
-``V4L2_PIX_FMT_YUV420M`` the Cb data constitutes the second plane which
-is half the width and half the height of the Y plane (and of the image).
-Each Cb belongs to four pixels, a two-by-two square of the image. For
-example, Cb\ :sub:`0` belongs to Y'\ :sub:`00`, Y'\ :sub:`01`,
-Y'\ :sub:`10`, and Y'\ :sub:`11`. The Cr data, just like the Cb plane,
-is in the third plane.
-
-``V4L2_PIX_FMT_YVU420M`` is the same except the Cr data is stored in the
-second plane and the Cb data in the third plane.
-
-If the Y plane has pad bytes after each row, then the Cb and Cr planes
-have half as many pad bytes after their rows. In other words, two Cx
-rows (including padding) is exactly as long as one Y row (including
-padding).
-
-``V4L2_PIX_FMT_YUV420M`` and ``V4L2_PIX_FMT_YVU420M`` are intended to be
-used only in drivers and applications that support the multi-planar API,
-described in :ref:`planar-apis`.
-
-**Byte Order.**
-Each cell is one byte.
-
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - start0 + 0:
-      - Y'\ :sub:`00`
-      - Y'\ :sub:`01`
-      - Y'\ :sub:`02`
-      - Y'\ :sub:`03`
-    * - start0 + 4:
-      - Y'\ :sub:`10`
-      - Y'\ :sub:`11`
-      - Y'\ :sub:`12`
-      - Y'\ :sub:`13`
-    * - start0 + 8:
-      - Y'\ :sub:`20`
-      - Y'\ :sub:`21`
-      - Y'\ :sub:`22`
-      - Y'\ :sub:`23`
-    * - start0 + 12:
-      - Y'\ :sub:`30`
-      - Y'\ :sub:`31`
-      - Y'\ :sub:`32`
-      - Y'\ :sub:`33`
-    * -
-    * - start1 + 0:
-      - Cb\ :sub:`00`
-      - Cb\ :sub:`01`
-    * - start1 + 2:
-      - Cb\ :sub:`10`
-      - Cb\ :sub:`11`
-    * -
-    * - start2 + 0:
-      - Cr\ :sub:`00`
-      - Cr\ :sub:`01`
-    * - start2 + 2:
-      - Cr\ :sub:`10`
-      - Cr\ :sub:`11`
-
-
-**Color Sample Location:**
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * -
-      - 0
-      -
-      - 1
-      -
-      - 2
-      -
-      - 3
-    * - 0
-      - Y
-      -
-      - Y
-      -
-      - Y
-      -
-      - Y
-    * -
-      -
-      - C
-      -
-      -
-      -
-      - C
-      -
-    * - 1
-      - Y
-      -
-      - Y
-      -
-      - Y
-      -
-      - Y
-    * -
-    * - 2
-      - Y
-      -
-      - Y
-      -
-      - Y
-      -
-      - Y
-    * -
-      -
-      - C
-      -
-      -
-      -
-      - C
-      -
-    * - 3
-      - Y
-      -
-      - Y
-      -
-      - Y
-      -
-      - Y
diff --git a/Documentation/media/uapi/v4l/pixfmt-yuv422m.rst b/Documentation/media/uapi/v4l/pixfmt-yuv422m.rst
deleted file mode 100644
index 737fd94a9ae9..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-yuv422m.rst
+++ /dev/null
@@ -1,148 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-YUV422M:
-.. _v4l2-pix-fmt-yvu422m:
-
-************************************************************
-V4L2_PIX_FMT_YUV422M ('YM16'), V4L2_PIX_FMT_YVU422M ('YM61')
-************************************************************
-
-
-V4L2_PIX_FMT_YVU422M
-Planar formats with ½ horizontal resolution, also known as YUV and YVU
-4:2:2
-
-
-Description
-===========
-
-This is a multi-planar format, as opposed to a packed format. The three
-components are separated into three sub-images or planes.
-
-The Y plane is first. The Y plane has one byte per pixel. For
-``V4L2_PIX_FMT_YUV422M`` the Cb data constitutes the second plane which
-is half the width of the Y plane (and of the image). Each Cb belongs to
-two pixels. For example, Cb\ :sub:`0` belongs to Y'\ :sub:`00`,
-Y'\ :sub:`01`. The Cr data, just like the Cb plane, is in the third
-plane.
-
-``V4L2_PIX_FMT_YVU422M`` is the same except the Cr data is stored in the
-second plane and the Cb data in the third plane.
-
-If the Y plane has pad bytes after each row, then the Cb and Cr planes
-have half as many pad bytes after their rows. In other words, two Cx
-rows (including padding) is exactly as long as one Y row (including
-padding).
-
-``V4L2_PIX_FMT_YUV422M`` and ``V4L2_PIX_FMT_YVU422M`` are intended to be
-used only in drivers and applications that support the multi-planar API,
-described in :ref:`planar-apis`.
-
-**Byte Order.**
-Each cell is one byte.
-
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - start0 + 0:
-      - Y'\ :sub:`00`
-      - Y'\ :sub:`01`
-      - Y'\ :sub:`02`
-      - Y'\ :sub:`03`
-    * - start0 + 4:
-      - Y'\ :sub:`10`
-      - Y'\ :sub:`11`
-      - Y'\ :sub:`12`
-      - Y'\ :sub:`13`
-    * - start0 + 8:
-      - Y'\ :sub:`20`
-      - Y'\ :sub:`21`
-      - Y'\ :sub:`22`
-      - Y'\ :sub:`23`
-    * - start0 + 12:
-      - Y'\ :sub:`30`
-      - Y'\ :sub:`31`
-      - Y'\ :sub:`32`
-      - Y'\ :sub:`33`
-    * -
-    * - start1 + 0:
-      - Cb\ :sub:`00`
-      - Cb\ :sub:`01`
-    * - start1 + 2:
-      - Cb\ :sub:`10`
-      - Cb\ :sub:`11`
-    * - start1 + 4:
-      - Cb\ :sub:`20`
-      - Cb\ :sub:`21`
-    * - start1 + 6:
-      - Cb\ :sub:`30`
-      - Cb\ :sub:`31`
-    * -
-    * - start2 + 0:
-      - Cr\ :sub:`00`
-      - Cr\ :sub:`01`
-    * - start2 + 2:
-      - Cr\ :sub:`10`
-      - Cr\ :sub:`11`
-    * - start2 + 4:
-      - Cr\ :sub:`20`
-      - Cr\ :sub:`21`
-    * - start2 + 6:
-      - Cr\ :sub:`30`
-      - Cr\ :sub:`31`
-
-
-**Color Sample Location:**
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * -
-      - 0
-      -
-      - 1
-      - 2
-      -
-      - 3
-    * - 0
-      - Y
-      - C
-      - Y
-      - Y
-      - C
-      - Y
-    * - 1
-      - Y
-      - C
-      - Y
-      - Y
-      - C
-      - Y
-    * - 2
-      - Y
-      - C
-      - Y
-      - Y
-      - C
-      - Y
-    * - 3
-      - Y
-      - C
-      - Y
-      - Y
-      - C
-      - Y
diff --git a/Documentation/media/uapi/v4l/pixfmt-yuv422p.rst b/Documentation/media/uapi/v4l/pixfmt-yuv422p.rst
deleted file mode 100644
index 7cebb6ebb621..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-yuv422p.rst
+++ /dev/null
@@ -1,136 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-YUV422P:
-
-*****************************
-V4L2_PIX_FMT_YUV422P ('422P')
-*****************************
-
-
-Format with ½ horizontal chroma resolution, also known as YUV 4:2:2.
-Planar layout as opposed to ``V4L2_PIX_FMT_YUYV``
-
-
-Description
-===========
-
-This format is not commonly used. This is a planar version of the YUYV
-format. The three components are separated into three sub-images or
-planes. The Y plane is first. The Y plane has one byte per pixel. The Cb
-plane immediately follows the Y plane in memory. The Cb plane is half
-the width of the Y plane (and of the image). Each Cb belongs to two
-pixels. For example, Cb\ :sub:`0` belongs to Y'\ :sub:`00`,
-Y'\ :sub:`01`. Following the Cb plane is the Cr plane, just like the Cb
-plane.
-
-If the Y plane has pad bytes after each row, then the Cr and Cb planes
-have half as many pad bytes after their rows. In other words, two Cx
-rows (including padding) is exactly as long as one Y row (including
-padding).
-
-**Byte Order.**
-Each cell is one byte.
-
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - start + 0:
-      - Y'\ :sub:`00`
-      - Y'\ :sub:`01`
-      - Y'\ :sub:`02`
-      - Y'\ :sub:`03`
-    * - start + 4:
-      - Y'\ :sub:`10`
-      - Y'\ :sub:`11`
-      - Y'\ :sub:`12`
-      - Y'\ :sub:`13`
-    * - start + 8:
-      - Y'\ :sub:`20`
-      - Y'\ :sub:`21`
-      - Y'\ :sub:`22`
-      - Y'\ :sub:`23`
-    * - start + 12:
-      - Y'\ :sub:`30`
-      - Y'\ :sub:`31`
-      - Y'\ :sub:`32`
-      - Y'\ :sub:`33`
-    * - start + 16:
-      - Cb\ :sub:`00`
-      - Cb\ :sub:`01`
-    * - start + 18:
-      - Cb\ :sub:`10`
-      - Cb\ :sub:`11`
-    * - start + 20:
-      - Cb\ :sub:`20`
-      - Cb\ :sub:`21`
-    * - start + 22:
-      - Cb\ :sub:`30`
-      - Cb\ :sub:`31`
-    * - start + 24:
-      - Cr\ :sub:`00`
-      - Cr\ :sub:`01`
-    * - start + 26:
-      - Cr\ :sub:`10`
-      - Cr\ :sub:`11`
-    * - start + 28:
-      - Cr\ :sub:`20`
-      - Cr\ :sub:`21`
-    * - start + 30:
-      - Cr\ :sub:`30`
-      - Cr\ :sub:`31`
-
-
-**Color Sample Location:**
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * -
-      - 0
-      -
-      - 1
-      - 2
-      -
-      - 3
-    * - 0
-      - Y
-      - C
-      - Y
-      - Y
-      - C
-      - Y
-    * - 1
-      - Y
-      - C
-      - Y
-      - Y
-      - C
-      - Y
-    * - 2
-      - Y
-      - C
-      - Y
-      - Y
-      - C
-      - Y
-    * - 3
-      - Y
-      - C
-      - Y
-      - Y
-      - C
-      - Y
diff --git a/Documentation/media/uapi/v4l/pixfmt-yuv444m.rst b/Documentation/media/uapi/v4l/pixfmt-yuv444m.rst
deleted file mode 100644
index 8f14ca378816..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-yuv444m.rst
+++ /dev/null
@@ -1,148 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-YUV444M:
-.. _v4l2-pix-fmt-yvu444m:
-
-************************************************************
-V4L2_PIX_FMT_YUV444M ('YM24'), V4L2_PIX_FMT_YVU444M ('YM42')
-************************************************************
-
-
-V4L2_PIX_FMT_YVU444M
-Planar formats with full horizontal resolution, also known as YUV and
-YVU 4:4:4
-
-
-Description
-===========
-
-This is a multi-planar format, as opposed to a packed format. The three
-components are separated into three sub-images or planes.
-
-The Y plane is first. The Y plane has one byte per pixel. For
-``V4L2_PIX_FMT_YUV444M`` the Cb data constitutes the second plane which
-is the same width and height as the Y plane (and as the image). The Cr
-data, just like the Cb plane, is in the third plane.
-
-``V4L2_PIX_FMT_YVU444M`` is the same except the Cr data is stored in the
-second plane and the Cb data in the third plane.
-
-If the Y plane has pad bytes after each row, then the Cb and Cr planes
-have the same number of pad bytes after their rows.
-
-``V4L2_PIX_FMT_YUV444M`` and ``V4L2_PIX_FMT_YUV444M`` are intended to be
-used only in drivers and applications that support the multi-planar API,
-described in :ref:`planar-apis`.
-
-**Byte Order.**
-Each cell is one byte.
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - start0 + 0:
-      - Y'\ :sub:`00`
-      - Y'\ :sub:`01`
-      - Y'\ :sub:`02`
-      - Y'\ :sub:`03`
-    * - start0 + 4:
-      - Y'\ :sub:`10`
-      - Y'\ :sub:`11`
-      - Y'\ :sub:`12`
-      - Y'\ :sub:`13`
-    * - start0 + 8:
-      - Y'\ :sub:`20`
-      - Y'\ :sub:`21`
-      - Y'\ :sub:`22`
-      - Y'\ :sub:`23`
-    * - start0 + 12:
-      - Y'\ :sub:`30`
-      - Y'\ :sub:`31`
-      - Y'\ :sub:`32`
-      - Y'\ :sub:`33`
-    * -
-    * - start1 + 0:
-      - Cb\ :sub:`00`
-      - Cb\ :sub:`01`
-      - Cb\ :sub:`02`
-      - Cb\ :sub:`03`
-    * - start1 + 4:
-      - Cb\ :sub:`10`
-      - Cb\ :sub:`11`
-      - Cb\ :sub:`12`
-      - Cb\ :sub:`13`
-    * - start1 + 8:
-      - Cb\ :sub:`20`
-      - Cb\ :sub:`21`
-      - Cb\ :sub:`22`
-      - Cb\ :sub:`23`
-    * - start1 + 12:
-      - Cb\ :sub:`20`
-      - Cb\ :sub:`21`
-      - Cb\ :sub:`32`
-      - Cb\ :sub:`33`
-    * -
-    * - start2 + 0:
-      - Cr\ :sub:`00`
-      - Cr\ :sub:`01`
-      - Cr\ :sub:`02`
-      - Cr\ :sub:`03`
-    * - start2 + 4:
-      - Cr\ :sub:`10`
-      - Cr\ :sub:`11`
-      - Cr\ :sub:`12`
-      - Cr\ :sub:`13`
-    * - start2 + 8:
-      - Cr\ :sub:`20`
-      - Cr\ :sub:`21`
-      - Cr\ :sub:`22`
-      - Cr\ :sub:`23`
-    * - start2 + 12:
-      - Cr\ :sub:`30`
-      - Cr\ :sub:`31`
-      - Cr\ :sub:`32`
-      - Cr\ :sub:`33`
-
-
-**Color Sample Location:**
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * -
-      - 0
-      - 1
-      - 2
-      - 3
-    * - 0
-      - YC
-      - YC
-      - YC
-      - YC
-    * - 1
-      - YC
-      - YC
-      - YC
-      - YC
-    * - 2
-      - YC
-      - YC
-      - YC
-      - YC
-    * - 3
-      - YC
-      - YC
-      - YC
-      - YC
diff --git a/Documentation/media/uapi/v4l/pixfmt-yuyv.rst b/Documentation/media/uapi/v4l/pixfmt-yuyv.rst
deleted file mode 100644
index d86d7f086c41..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-yuyv.rst
+++ /dev/null
@@ -1,125 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-YUYV:
-
-**************************
-V4L2_PIX_FMT_YUYV ('YUYV')
-**************************
-
-
-Packed format with ½ horizontal chroma resolution, also known as YUV
-4:2:2
-
-
-Description
-===========
-
-In this format each four bytes is two pixels. Each four bytes is two
-Y's, a Cb and a Cr. Each Y goes to one of the pixels, and the Cb and Cr
-belong to both pixels. As you can see, the Cr and Cb components have
-half the horizontal resolution of the Y component. ``V4L2_PIX_FMT_YUYV``
-is known in the Windows environment as YUY2.
-
-**Byte Order.**
-Each cell is one byte.
-
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - start + 0:
-      - Y'\ :sub:`00`
-      - Cb\ :sub:`00`
-      - Y'\ :sub:`01`
-      - Cr\ :sub:`00`
-      - Y'\ :sub:`02`
-      - Cb\ :sub:`01`
-      - Y'\ :sub:`03`
-      - Cr\ :sub:`01`
-    * - start + 8:
-      - Y'\ :sub:`10`
-      - Cb\ :sub:`10`
-      - Y'\ :sub:`11`
-      - Cr\ :sub:`10`
-      - Y'\ :sub:`12`
-      - Cb\ :sub:`11`
-      - Y'\ :sub:`13`
-      - Cr\ :sub:`11`
-    * - start + 16:
-      - Y'\ :sub:`20`
-      - Cb\ :sub:`20`
-      - Y'\ :sub:`21`
-      - Cr\ :sub:`20`
-      - Y'\ :sub:`22`
-      - Cb\ :sub:`21`
-      - Y'\ :sub:`23`
-      - Cr\ :sub:`21`
-    * - start + 24:
-      - Y'\ :sub:`30`
-      - Cb\ :sub:`30`
-      - Y'\ :sub:`31`
-      - Cr\ :sub:`30`
-      - Y'\ :sub:`32`
-      - Cb\ :sub:`31`
-      - Y'\ :sub:`33`
-      - Cr\ :sub:`31`
-
-
-**Color Sample Location:**
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * -
-      - 0
-      -
-      - 1
-      -
-      - 2
-      -
-      - 3
-    * - 0
-      - Y
-      - C
-      - Y
-      -
-      - Y
-      - C
-      - Y
-    * - 1
-      - Y
-      - C
-      - Y
-      -
-      - Y
-      - C
-      - Y
-    * - 2
-      - Y
-      - C
-      - Y
-      -
-      - Y
-      - C
-      - Y
-    * - 3
-      - Y
-      - C
-      - Y
-      -
-      - Y
-      - C
-      - Y
diff --git a/Documentation/media/uapi/v4l/pixfmt-yvyu.rst b/Documentation/media/uapi/v4l/pixfmt-yvyu.rst
deleted file mode 100644
index 656a830fed02..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-yvyu.rst
+++ /dev/null
@@ -1,115 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-YVYU:
-
-**************************
-V4L2_PIX_FMT_YVYU ('YVYU')
-**************************
-
-
-Variation of ``V4L2_PIX_FMT_YUYV`` with different order of samples in
-memory
-
-
-Description
-===========
-
-In this format each four bytes is two pixels. Each four bytes is two
-Y's, a Cb and a Cr. Each Y goes to one of the pixels, and the Cb and Cr
-belong to both pixels. As you can see, the Cr and Cb components have
-half the horizontal resolution of the Y component.
-
-**Byte Order.**
-Each cell is one byte.
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - start + 0:
-      - Y'\ :sub:`00`
-      - Cr\ :sub:`00`
-      - Y'\ :sub:`01`
-      - Cb\ :sub:`00`
-      - Y'\ :sub:`02`
-      - Cr\ :sub:`01`
-      - Y'\ :sub:`03`
-      - Cb\ :sub:`01`
-    * - start + 8:
-      - Y'\ :sub:`10`
-      - Cr\ :sub:`10`
-      - Y'\ :sub:`11`
-      - Cb\ :sub:`10`
-      - Y'\ :sub:`12`
-      - Cr\ :sub:`11`
-      - Y'\ :sub:`13`
-      - Cb\ :sub:`11`
-    * - start + 16:
-      - Y'\ :sub:`20`
-      - Cr\ :sub:`20`
-      - Y'\ :sub:`21`
-      - Cb\ :sub:`20`
-      - Y'\ :sub:`22`
-      - Cr\ :sub:`21`
-      - Y'\ :sub:`23`
-      - Cb\ :sub:`21`
-    * - start + 24:
-      - Y'\ :sub:`30`
-      - Cr\ :sub:`30`
-      - Y'\ :sub:`31`
-      - Cb\ :sub:`30`
-      - Y'\ :sub:`32`
-      - Cr\ :sub:`31`
-      - Y'\ :sub:`33`
-      - Cb\ :sub:`31`
-
-
-**Color Sample Location:**
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * -
-      - 0
-      -
-      - 1
-      - 2
-      -
-      - 3
-    * - 0
-      - Y
-      - C
-      - Y
-      - Y
-      - C
-      - Y
-    * - 1
-      - Y
-      - C
-      - Y
-      - Y
-      - C
-      - Y
-    * - 2
-      - Y
-      - C
-      - Y
-      - Y
-      - C
-      - Y
-    * - 3
-      - Y
-      - C
-      - Y
-      - Y
-      - C
-      - Y
diff --git a/Documentation/media/uapi/v4l/pixfmt-z16.rst b/Documentation/media/uapi/v4l/pixfmt-z16.rst
deleted file mode 100644
index eccf235bf02d..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt-z16.rst
+++ /dev/null
@@ -1,73 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _V4L2-PIX-FMT-Z16:
-
-*************************
-V4L2_PIX_FMT_Z16 ('Z16 ')
-*************************
-
-
-16-bit depth data with distance values at each pixel
-
-
-Description
-===========
-
-This is a 16-bit format, representing depth data. Each pixel is a
-distance to the respective point in the image coordinates. Distance unit
-can vary and has to be negotiated with the device separately. Each pixel
-is stored in a 16-bit word in the little endian byte order.
-
-**Byte Order.**
-Each cell is one byte.
-
-
-
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - start + 0:
-      - Z\ :sub:`00low`
-      - Z\ :sub:`00high`
-      - Z\ :sub:`01low`
-      - Z\ :sub:`01high`
-      - Z\ :sub:`02low`
-      - Z\ :sub:`02high`
-      - Z\ :sub:`03low`
-      - Z\ :sub:`03high`
-    * - start + 8:
-      - Z\ :sub:`10low`
-      - Z\ :sub:`10high`
-      - Z\ :sub:`11low`
-      - Z\ :sub:`11high`
-      - Z\ :sub:`12low`
-      - Z\ :sub:`12high`
-      - Z\ :sub:`13low`
-      - Z\ :sub:`13high`
-    * - start + 16:
-      - Z\ :sub:`20low`
-      - Z\ :sub:`20high`
-      - Z\ :sub:`21low`
-      - Z\ :sub:`21high`
-      - Z\ :sub:`22low`
-      - Z\ :sub:`22high`
-      - Z\ :sub:`23low`
-      - Z\ :sub:`23high`
-    * - start + 24:
-      - Z\ :sub:`30low`
-      - Z\ :sub:`30high`
-      - Z\ :sub:`31low`
-      - Z\ :sub:`31high`
-      - Z\ :sub:`32low`
-      - Z\ :sub:`32high`
-      - Z\ :sub:`33low`
-      - Z\ :sub:`33high`
diff --git a/Documentation/media/uapi/v4l/pixfmt.rst b/Documentation/media/uapi/v4l/pixfmt.rst
deleted file mode 100644
index a7d4cd43a298..000000000000
--- a/Documentation/media/uapi/v4l/pixfmt.rst
+++ /dev/null
@@ -1,45 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _pixfmt:
-
-#############
-Image Formats
-#############
-The V4L2 API was primarily designed for devices exchanging image data
-with applications. The struct :c:type:`v4l2_pix_format` and
-struct :c:type:`v4l2_pix_format_mplane` structures define the
-format and layout of an image in memory. The former is used with the
-single-planar API, while the latter is used with the multi-planar
-version (see :ref:`planar-apis`). Image formats are negotiated with
-the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl. (The explanations here
-focus on video capturing and output, for overlay frame buffer formats
-see also :ref:`VIDIOC_G_FBUF <VIDIOC_G_FBUF>`.)
-
-
-.. toctree::
-    :maxdepth: 1
-
-    pixfmt-v4l2
-    pixfmt-v4l2-mplane
-    pixfmt-intro
-    pixfmt-indexed
-    pixfmt-rgb
-    pixfmt-bayer
-    yuv-formats
-    hsv-formats
-    depth-formats
-    pixfmt-compressed
-    sdr-formats
-    tch-formats
-    meta-formats
-    pixfmt-reserved
-    colorspaces
-    colorspaces-defs
-    colorspaces-details
diff --git a/Documentation/media/uapi/v4l/planar-apis.rst b/Documentation/media/uapi/v4l/planar-apis.rst
deleted file mode 100644
index a422dc9d592c..000000000000
--- a/Documentation/media/uapi/v4l/planar-apis.rst
+++ /dev/null
@@ -1,68 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _planar-apis:
-
-*****************************
-Single- and multi-planar APIs
-*****************************
-
-Some devices require data for each input or output video frame to be
-placed in discontiguous memory buffers. In such cases, one video frame
-has to be addressed using more than one memory address, i.e. one pointer
-per "plane". A plane is a sub-buffer of the current frame. For examples
-of such formats see :ref:`pixfmt`.
-
-Initially, V4L2 API did not support multi-planar buffers and a set of
-extensions has been introduced to handle them. Those extensions
-constitute what is being referred to as the "multi-planar API".
-
-Some of the V4L2 API calls and structures are interpreted differently,
-depending on whether single- or multi-planar API is being used. An
-application can choose whether to use one or the other by passing a
-corresponding buffer type to its ioctl calls. Multi-planar versions of
-buffer types are suffixed with an ``_MPLANE`` string. For a list of
-available multi-planar buffer types see enum
-:c:type:`v4l2_buf_type`.
-
-
-Multi-planar formats
-====================
-
-Multi-planar API introduces new multi-planar formats. Those formats use
-a separate set of FourCC codes. It is important to distinguish between
-the multi-planar API and a multi-planar format. Multi-planar API calls
-can handle all single-planar formats as well (as long as they are passed
-in multi-planar API structures), while the single-planar API cannot
-handle multi-planar formats.
-
-
-Calls that distinguish between single and multi-planar APIs
-===========================================================
-
-:ref:`VIDIOC_QUERYCAP <VIDIOC_QUERYCAP>`
-    Two additional multi-planar capabilities are added. They can be set
-    together with non-multi-planar ones for devices that handle both
-    single- and multi-planar formats.
-
-:ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>`, :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`, :ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>`
-    New structures for describing multi-planar formats are added: struct
-    :c:type:`v4l2_pix_format_mplane` and
-    struct :c:type:`v4l2_plane_pix_format`.
-    Drivers may define new multi-planar formats, which have distinct
-    FourCC codes from the existing single-planar ones.
-
-:ref:`VIDIOC_QBUF <VIDIOC_QBUF>`, :ref:`VIDIOC_DQBUF <VIDIOC_QBUF>`, :ref:`VIDIOC_QUERYBUF <VIDIOC_QUERYBUF>`
-    A new struct :c:type:`v4l2_plane` structure for
-    describing planes is added. Arrays of this structure are passed in
-    the new ``m.planes`` field of struct
-    :c:type:`v4l2_buffer`.
-
-:ref:`VIDIOC_REQBUFS <VIDIOC_REQBUFS>`
-    Will allocate multi-planar buffers as requested.
diff --git a/Documentation/media/uapi/v4l/querycap.rst b/Documentation/media/uapi/v4l/querycap.rst
deleted file mode 100644
index 8d01ef52f780..000000000000
--- a/Documentation/media/uapi/v4l/querycap.rst
+++ /dev/null
@@ -1,41 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _querycap:
-
-*********************
-Querying Capabilities
-*********************
-
-Because V4L2 covers a wide variety of devices not all aspects of the API
-are equally applicable to all types of devices. Furthermore devices of
-the same type have different capabilities and this specification permits
-the omission of a few complicated and less important parts of the API.
-
-The :ref:`VIDIOC_QUERYCAP` ioctl is available to
-check if the kernel device is compatible with this specification, and to
-query the :ref:`functions <devices>` and :ref:`I/O methods <io>`
-supported by the device.
-
-Starting with kernel version 3.1, :ref:`VIDIOC_QUERYCAP`
-will return the V4L2 API version used by the driver, with generally
-matches the Kernel version. There's no need of using
-:ref:`VIDIOC_QUERYCAP` to check if a specific ioctl
-is supported, the V4L2 core now returns ``ENOTTY`` if a driver doesn't
-provide support for an ioctl.
-
-Other features can be queried by calling the respective ioctl, for
-example :ref:`VIDIOC_ENUMINPUT` to learn about the
-number, types and names of video connectors on the device. Although
-abstraction is a major objective of this API, the
-:ref:`VIDIOC_QUERYCAP` ioctl also allows driver
-specific applications to reliably identify the driver.
-
-All V4L2 drivers must support :ref:`VIDIOC_QUERYCAP`.
-Applications should always call this ioctl after opening the device.
diff --git a/Documentation/media/uapi/v4l/rw.rst b/Documentation/media/uapi/v4l/rw.rst
deleted file mode 100644
index 6e498fcf32c4..000000000000
--- a/Documentation/media/uapi/v4l/rw.rst
+++ /dev/null
@@ -1,54 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _rw:
-
-**********
-Read/Write
-**********
-
-Input and output devices support the :ref:`read() <func-read>` and
-:ref:`write() <func-write>` function, respectively, when the
-``V4L2_CAP_READWRITE`` flag in the ``capabilities`` field of struct
-:c:type:`v4l2_capability` returned by the
-:ref:`VIDIOC_QUERYCAP` ioctl is set.
-
-Drivers may need the CPU to copy the data, but they may also support DMA
-to or from user memory, so this I/O method is not necessarily less
-efficient than other methods merely exchanging buffer pointers. It is
-considered inferior though because no meta-information like frame
-counters or timestamps are passed. This information is necessary to
-recognize frame dropping and to synchronize with other data streams.
-However this is also the simplest I/O method, requiring little or no
-setup to exchange data. It permits command line stunts like this (the
-vidctrl tool is fictitious):
-
-
-.. code-block:: none
-
-    $ vidctrl /dev/video --input=0 --format=YUYV --size=352x288
-    $ dd if=/dev/video of=myimage.422 bs=202752 count=1
-
-To read from the device applications use the :ref:`read() <func-read>`
-function, to write the :ref:`write() <func-write>` function. Drivers
-must implement one I/O method if they exchange data with applications,
-but it need not be this. [#f1]_ When reading or writing is supported, the
-driver must also support the :ref:`select() <func-select>` and
-:ref:`poll() <func-poll>` function. [#f2]_
-
-.. [#f1]
-   It would be desirable if applications could depend on drivers
-   supporting all I/O interfaces, but as much as the complex memory
-   mapping I/O can be inadequate for some devices we have no reason to
-   require this interface, which is most useful for simple applications
-   capturing still images.
-
-.. [#f2]
-   At the driver level :ref:`select() <func-select>` and :ref:`poll() <func-poll>` are
-   the same, and :ref:`select() <func-select>` is too important to be optional.
diff --git a/Documentation/media/uapi/v4l/sdr-formats.rst b/Documentation/media/uapi/v4l/sdr-formats.rst
deleted file mode 100644
index f452f5574ebb..000000000000
--- a/Documentation/media/uapi/v4l/sdr-formats.rst
+++ /dev/null
@@ -1,29 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _sdr-formats:
-
-***********
-SDR Formats
-***********
-
-These formats are used for :ref:`SDR <sdr>` interface only.
-
-
-.. toctree::
-    :maxdepth: 1
-
-    pixfmt-sdr-cu08
-    pixfmt-sdr-cu16le
-    pixfmt-sdr-cs08
-    pixfmt-sdr-cs14le
-    pixfmt-sdr-ru12le
-    pixfmt-sdr-pcu16be
-    pixfmt-sdr-pcu18be
-    pixfmt-sdr-pcu20be
diff --git a/Documentation/media/uapi/v4l/selection-api-configuration.rst b/Documentation/media/uapi/v4l/selection-api-configuration.rst
deleted file mode 100644
index 6e0c98c37067..000000000000
--- a/Documentation/media/uapi/v4l/selection-api-configuration.rst
+++ /dev/null
@@ -1,144 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-*************
-Configuration
-*************
-
-Applications can use the :ref:`selection API <VIDIOC_G_SELECTION>` to
-select an area in a video signal or a buffer, and to query for default
-settings and hardware limits.
-
-Video hardware can have various cropping, composing and scaling
-limitations. It may only scale up or down, support only discrete scaling
-factors, or have different scaling abilities in the horizontal and
-vertical directions. Also it may not support scaling at all. At the same
-time the cropping/composing rectangles may have to be aligned, and both
-the source and the sink may have arbitrary upper and lower size limits.
-Therefore, as usual, drivers are expected to adjust the requested
-parameters and return the actual values selected. An application can
-control the rounding behaviour using
-:ref:`constraint flags <v4l2-selection-flags>`.
-
-
-Configuration of video capture
-==============================
-
-See figure :ref:`sel-targets-capture` for examples of the selection
-targets available for a video capture device. It is recommended to
-configure the cropping targets before to the composing targets.
-
-The range of coordinates of the top left corner, width and height of
-areas that can be sampled is given by the ``V4L2_SEL_TGT_CROP_BOUNDS``
-target. It is recommended for the driver developers to put the top/left
-corner at position ``(0,0)``. The rectangle's coordinates are expressed
-in pixels.
-
-The top left corner, width and height of the source rectangle, that is
-the area actually sampled, is given by the ``V4L2_SEL_TGT_CROP`` target.
-It uses the same coordinate system as ``V4L2_SEL_TGT_CROP_BOUNDS``. The
-active cropping area must lie completely inside the capture boundaries.
-The driver may further adjust the requested size and/or position
-according to hardware limitations.
-
-Each capture device has a default source rectangle, given by the
-``V4L2_SEL_TGT_CROP_DEFAULT`` target. This rectangle shall cover what the
-driver writer considers the complete picture. Drivers shall set the
-active crop rectangle to the default when the driver is first loaded,
-but not later.
-
-The composing targets refer to a memory buffer. The limits of composing
-coordinates are obtained using ``V4L2_SEL_TGT_COMPOSE_BOUNDS``. All
-coordinates are expressed in pixels. The rectangle's top/left corner
-must be located at position ``(0,0)``. The width and height are equal to
-the image size set by :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`.
-
-The part of a buffer into which the image is inserted by the hardware is
-controlled by the ``V4L2_SEL_TGT_COMPOSE`` target. The rectangle's
-coordinates are also expressed in the same coordinate system as the
-bounds rectangle. The composing rectangle must lie completely inside
-bounds rectangle. The driver must adjust the composing rectangle to fit
-to the bounding limits. Moreover, the driver can perform other
-adjustments according to hardware limitations. The application can
-control rounding behaviour using
-:ref:`constraint flags <v4l2-selection-flags>`.
-
-For capture devices the default composing rectangle is queried using
-``V4L2_SEL_TGT_COMPOSE_DEFAULT``. It is usually equal to the bounding
-rectangle.
-
-The part of a buffer that is modified by the hardware is given by
-``V4L2_SEL_TGT_COMPOSE_PADDED``. It contains all pixels defined using
-``V4L2_SEL_TGT_COMPOSE`` plus all padding data modified by hardware
-during insertion process. All pixels outside this rectangle *must not*
-be changed by the hardware. The content of pixels that lie inside the
-padded area but outside active area is undefined. The application can
-use the padded and active rectangles to detect where the rubbish pixels
-are located and remove them if needed.
-
-
-Configuration of video output
-=============================
-
-For output devices targets and ioctls are used similarly to the video
-capture case. The *composing* rectangle refers to the insertion of an
-image into a video signal. The cropping rectangles refer to a memory
-buffer. It is recommended to configure the composing targets before to
-the cropping targets.
-
-The cropping targets refer to the memory buffer that contains an image
-to be inserted into a video signal or graphical screen. The limits of
-cropping coordinates are obtained using ``V4L2_SEL_TGT_CROP_BOUNDS``.
-All coordinates are expressed in pixels. The top/left corner is always
-point ``(0,0)``. The width and height is equal to the image size
-specified using :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl.
-
-The top left corner, width and height of the source rectangle, that is
-the area from which image date are processed by the hardware, is given
-by the ``V4L2_SEL_TGT_CROP``. Its coordinates are expressed in in the
-same coordinate system as the bounds rectangle. The active cropping area
-must lie completely inside the crop boundaries and the driver may
-further adjust the requested size and/or position according to hardware
-limitations.
-
-For output devices the default cropping rectangle is queried using
-``V4L2_SEL_TGT_CROP_DEFAULT``. It is usually equal to the bounding
-rectangle.
-
-The part of a video signal or graphics display where the image is
-inserted by the hardware is controlled by ``V4L2_SEL_TGT_COMPOSE``
-target. The rectangle's coordinates are expressed in pixels. The
-composing rectangle must lie completely inside the bounds rectangle. The
-driver must adjust the area to fit to the bounding limits. Moreover, the
-driver can perform other adjustments according to hardware limitations.
-
-The device has a default composing rectangle, given by the
-``V4L2_SEL_TGT_COMPOSE_DEFAULT`` target. This rectangle shall cover what
-the driver writer considers the complete picture. It is recommended for
-the driver developers to put the top/left corner at position ``(0,0)``.
-Drivers shall set the active composing rectangle to the default one when
-the driver is first loaded.
-
-The devices may introduce additional content to video signal other than
-an image from memory buffers. It includes borders around an image.
-However, such a padded area is driver-dependent feature not covered by
-this document. Driver developers are encouraged to keep padded rectangle
-equal to active one. The padded target is accessed by the
-``V4L2_SEL_TGT_COMPOSE_PADDED`` identifier. It must contain all pixels
-from the ``V4L2_SEL_TGT_COMPOSE`` target.
-
-
-Scaling control
-===============
-
-An application can detect if scaling is performed by comparing the width
-and the height of rectangles obtained using ``V4L2_SEL_TGT_CROP`` and
-``V4L2_SEL_TGT_COMPOSE`` targets. If these are not equal then the
-scaling is applied. The application can compute the scaling ratios using
-these values.
diff --git a/Documentation/media/uapi/v4l/selection-api-examples.rst b/Documentation/media/uapi/v4l/selection-api-examples.rst
deleted file mode 100644
index bb288b06cc17..000000000000
--- a/Documentation/media/uapi/v4l/selection-api-examples.rst
+++ /dev/null
@@ -1,91 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-********
-Examples
-********
-
-(A video capture device is assumed; change
-``V4L2_BUF_TYPE_VIDEO_CAPTURE`` for other devices; change target to
-``V4L2_SEL_TGT_COMPOSE_*`` family to configure composing area)
-
-Example: Resetting the cropping parameters
-==========================================
-
-.. code-block:: c
-
-	struct v4l2_selection sel = {
-	    .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
-	    .target = V4L2_SEL_TGT_CROP_DEFAULT,
-	};
-	ret = ioctl(fd, VIDIOC_G_SELECTION, &sel);
-	if (ret)
-	    exit(-1);
-	sel.target = V4L2_SEL_TGT_CROP;
-	ret = ioctl(fd, VIDIOC_S_SELECTION, &sel);
-	if (ret)
-	    exit(-1);
-
-Setting a composing area on output of size of *at most* half of limit
-placed at a center of a display.
-
-Example: Simple downscaling
-===========================
-
-.. code-block:: c
-
-	struct v4l2_selection sel = {
-	    .type = V4L2_BUF_TYPE_VIDEO_OUTPUT,
-	    .target = V4L2_SEL_TGT_COMPOSE_BOUNDS,
-	};
-	struct v4l2_rect r;
-
-	ret = ioctl(fd, VIDIOC_G_SELECTION, &sel);
-	if (ret)
-	    exit(-1);
-	/* setting smaller compose rectangle */
-	r.width = sel.r.width / 2;
-	r.height = sel.r.height / 2;
-	r.left = sel.r.width / 4;
-	r.top = sel.r.height / 4;
-	sel.r = r;
-	sel.target = V4L2_SEL_TGT_COMPOSE;
-	sel.flags = V4L2_SEL_FLAG_LE;
-	ret = ioctl(fd, VIDIOC_S_SELECTION, &sel);
-	if (ret)
-	    exit(-1);
-
-A video output device is assumed; change ``V4L2_BUF_TYPE_VIDEO_OUTPUT``
-for other devices
-
-Example: Querying for scaling factors
-=====================================
-
-.. code-block:: c
-
-	struct v4l2_selection compose = {
-	    .type = V4L2_BUF_TYPE_VIDEO_OUTPUT,
-	    .target = V4L2_SEL_TGT_COMPOSE,
-	};
-	struct v4l2_selection crop = {
-	    .type = V4L2_BUF_TYPE_VIDEO_OUTPUT,
-	    .target = V4L2_SEL_TGT_CROP,
-	};
-	double hscale, vscale;
-
-	ret = ioctl(fd, VIDIOC_G_SELECTION, &compose);
-	if (ret)
-	    exit(-1);
-	ret = ioctl(fd, VIDIOC_G_SELECTION, &crop);
-	if (ret)
-	    exit(-1);
-
-	/* computing scaling factors */
-	hscale = (double)compose.r.width / crop.r.width;
-	vscale = (double)compose.r.height / crop.r.height;
diff --git a/Documentation/media/uapi/v4l/selection-api-intro.rst b/Documentation/media/uapi/v4l/selection-api-intro.rst
deleted file mode 100644
index 0faed02d0226..000000000000
--- a/Documentation/media/uapi/v4l/selection-api-intro.rst
+++ /dev/null
@@ -1,35 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-************
-Introduction
-************
-
-Some video capture devices can sample a subsection of a picture and
-shrink or enlarge it to an image of arbitrary size. Next, the devices
-can insert the image into larger one. Some video output devices can crop
-part of an input image, scale it up or down and insert it at an
-arbitrary scan line and horizontal offset into a video signal. We call
-these abilities cropping, scaling and composing.
-
-On a video *capture* device the source is a video signal, and the
-cropping target determine the area actually sampled. The sink is an
-image stored in a memory buffer. The composing area specifies which part
-of the buffer is actually written to by the hardware.
-
-On a video *output* device the source is an image in a memory buffer,
-and the cropping target is a part of an image to be shown on a display.
-The sink is the display or the graphics screen. The application may
-select the part of display where the image should be displayed. The size
-and position of such a window is controlled by the compose target.
-
-Rectangles for all cropping and composing targets are defined even if
-the device does supports neither cropping nor composing. Their size and
-position will be fixed in such a case. If the device does not support
-scaling then the cropping and composing rectangles have the same size.
diff --git a/Documentation/media/uapi/v4l/selection-api-targets.rst b/Documentation/media/uapi/v4l/selection-api-targets.rst
deleted file mode 100644
index 83d633bcbd6f..000000000000
--- a/Documentation/media/uapi/v4l/selection-api-targets.rst
+++ /dev/null
@@ -1,27 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-*****************
-Selection targets
-*****************
-
-
-.. _sel-targets-capture:
-
-.. kernel-figure:: selection.svg
-    :alt:   selection.svg
-    :align: center
-
-    Cropping and composing targets
-
-    Targets used by a cropping, composing and scaling process
-
-
-
-See :ref:`v4l2-selection-targets` for more information.
diff --git a/Documentation/media/uapi/v4l/selection-api-vs-crop-api.rst b/Documentation/media/uapi/v4l/selection-api-vs-crop-api.rst
deleted file mode 100644
index 79b3abca341a..000000000000
--- a/Documentation/media/uapi/v4l/selection-api-vs-crop-api.rst
+++ /dev/null
@@ -1,46 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _selection-vs-crop:
-
-********************************
-Comparison with old cropping API
-********************************
-
-The selection API was introduced to cope with deficiencies of the
-older :ref:`CROP API <crop>`, that was designed to control simple
-capture devices. Later the cropping API was adopted by video output
-drivers. The ioctls are used to select a part of the display were the
-video signal is inserted. It should be considered as an API abuse
-because the described operation is actually the composing. The
-selection API makes a clear distinction between composing and cropping
-operations by setting the appropriate targets.
-
-The CROP API lacks any support for composing to and cropping from an
-image inside a memory buffer. The application could configure a
-capture device to fill only a part of an image by abusing V4L2
-API. Cropping a smaller image from a larger one is achieved by setting
-the field ``bytesperline`` at struct :c:type:`v4l2_pix_format`.
-Introducing an image offsets could be done by modifying field
-``m_userptr`` at struct :c:type:`v4l2_buffer` before calling
-:ref:`VIDIOC_QBUF <VIDIOC_QBUF>`. Those operations should be avoided
-because they are not portable (endianness), and do not work for
-macroblock and Bayer formats and mmap buffers.
-
-The selection API deals with configuration of buffer
-cropping/composing in a clear, intuitive and portable way. Next, with
-the selection API the concepts of the padded target and constraints
-flags are introduced. Finally, struct :c:type:`v4l2_crop` and struct
-:c:type:`v4l2_cropcap` have no reserved fields. Therefore there is no
-way to extend their functionality. The new struct
-:c:type:`v4l2_selection` provides a lot of place for future
-extensions.
-
-Driver developers are encouraged to implement only selection API. The
-former cropping API would be simulated using the new one.
diff --git a/Documentation/media/uapi/v4l/selection-api.rst b/Documentation/media/uapi/v4l/selection-api.rst
deleted file mode 100644
index 5386004e87cf..000000000000
--- a/Documentation/media/uapi/v4l/selection-api.rst
+++ /dev/null
@@ -1,23 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _selection-api:
-
-Cropping, composing and scaling -- the SELECTION API
-====================================================
-
-
-.. toctree::
-    :maxdepth: 1
-
-    selection-api-intro.rst
-    selection-api-targets.rst
-    selection-api-configuration.rst
-    selection-api-vs-crop-api.rst
-    selection-api-examples.rst
diff --git a/Documentation/media/uapi/v4l/selection.svg b/Documentation/media/uapi/v4l/selection.svg
deleted file mode 100644
index 59d2bec9b278..000000000000
--- a/Documentation/media/uapi/v4l/selection.svg
+++ /dev/null
@@ -1,1178 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-    This file is dual-licensed: you can use it either under the terms
-    of the GPL 2.0 or the GFDL 1.1+ license, at your option. Note that this
-    dual licensing only applies to this file, and not this project as a
-    whole.
-
-    a) This file is free software; you can redistribute it and/or
-       modify it under the terms of the GNU General Public License as
-       published by the Free Software Foundation version 2 of
-       the License.
-
-       This file is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-    Or, alternatively,
-
-    b) Permission is granted to copy, distribute and/or modify this
-       document under the terms of the GNU Free Documentation License,
-       Version 1.1 or any later version published by the Free Software
-       Foundation, with no Invariant Sections, no Front-Cover Texts
-       and no Back-Cover Texts. A copy of the license is included at
-       Documentation/media/uapi/fdl-appendix.rst.
-
-    TODO: replace it to GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
--->
-<svg enable-background="new" version="1" viewBox="0 0 4226.3 1686.8" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
- <defs>
-  <pattern id="ig" xlink:href="#ka" patternTransform="matrix(5.4432 0 0 10.1 1722.4 161.06)"/>
-  <marker id="er" overflow="visible" orient="auto">
-   <path d="m-1.2 0l-1 1 3.5-1-3.5-1 1 1z" fill="#f8d615" fill-rule="evenodd" stroke="#f8d615" stroke-width=".2pt"/>
-  </marker>
-  <pattern id="ka" width="2" height="1" patternTransform="scale(10)" patternUnits="userSpaceOnUse">
-   <path d="M0-.5h1v2H0z" fill="#f815bb"/>
-  </pattern>
-  <filter id="ep" x="-.085" y="-.366" width="1.169" height="1.732">
-   <feGaussianBlur stdDeviation="4.574"/>
-  </filter>
-  <linearGradient id="n">
-   <stop stop-color="#fff" offset="0"/>
-   <stop stop-color="#fff" stop-opacity="0" offset="1"/>
-  </linearGradient>
-  <linearGradient id="j">
-   <stop stop-color="#f9eed3" offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
-  <linearGradient id="s">
-   <stop stop-color="#283131" stop-opacity="0" offset="0"/>
-   <stop stop-color="#1e2424" offset=".5"/>
-   <stop offset="1"/>
-  </linearGradient>
-  <linearGradient id="u">
-   <stop stop-color="#cfc690" offset="0"/>
-   <stop stop-color="#afa775" offset=".212"/>
-   <stop stop-color="#615c3a" offset=".534"/>
-   <stop offset=".765"/>
-   <stop stop-color="#403518" offset="1"/>
-  </linearGradient>
-  <radialGradient id="jd" cx="418.3" cy="342.48" r="131.45" gradientTransform="matrix(1.3957 .62111 -.42441 .95372 -15.062 -227.97)" gradientUnits="userSpaceOnUse">
-   <stop stop-color="#283131" offset="0"/>
-   <stop stop-color="#1e2424" offset=".5"/>
-   <stop offset="1"/>
-  </radialGradient>
-  <filter id="iz" x="-.3" y="-.3" width="1.6" height="1.6">
-   <feGaussianBlur stdDeviation="2"/>
-  </filter>
-  <clipPath id="ea">
-   <path d="M179.64 267.36c-22.41 39.703-60.616 115.78-69.286 149.64-8.647 33.775-8.772 66.417-.357 86.429 8.36 19.882 26.164 35.633 40.714 41.429-.597-14.376 14.373-43.286 72.857-72.5 58.626-29.285 78.382-27.131 103.57-47.143 25.63-20.362 12.61-67.045 3.214-93.929-9.434-26.993-34.967-59.124-66.429-69.643-31.033-10.375-65.018-4.848-84.286 5.714z" fill="#f5ff04" fill-rule="evenodd"/>
-  </clipPath>
-  <radialGradient id="iy" cx="275.44" cy="335.35" r="36.75" gradientTransform="matrix(.05911 2.687 -.72343 .01591 408.73 -424.56)" gradientUnits="userSpaceOnUse">
-   <stop stop-color="#fff" offset="0"/>
-   <stop stop-color="#fff" stop-opacity="0" offset="1"/>
-  </radialGradient>
-  <clipPath id="kb">
-   <path d="m265.94 126.68l-18.767 168.86 174.11-73.121 61.954 88.659 57.884-31.99-37.534-180.06-237.64 27.649z" fill-rule="evenodd" stroke="#000" stroke-width=".9"/>
-  </clipPath>
-  <clipPath id="jz">
-   <path d="M352.25 211.99c-3.804-25.264-16.81-50.638-17.157-75.525-.186-13.356 3.273-26.571 13.756-39.554 36.347-65.296 116.94-84.695 185.93-91.465 86.922-11.017 184.91 17.94 233.37 95.401 54.124 75.733 56.675 172.54 80.612 259.53 29.438 127.13 54.779 256.21 60.392 386.85-3.063 78.182-8.426 165.18-60.503 228.13-48.027 50.357-122.79 50.053-187.07 59.002-90.555 4.655-184.35-16.146-261.78-64.198-64.776-37.94-95.73-113.48-97.279-186.02-8.39-79.875 26.392-153.81 51.62-227.16 7.47-82.761 9.413-166.25 9.653-249.38-.837-32.195-7.09-63.817-11.546-95.609z" enable-background="accumulate" fill="#262f2f" fill-rule="evenodd" stroke="#000"/>
-  </clipPath>
-  <clipPath id="kd">
-   <path d="M352.25 211.99c-3.804-25.264-16.81-50.638-17.157-75.525-.186-13.356 3.273-26.571 13.756-39.554 36.347-65.296 116.94-84.695 185.93-91.465 86.922-11.017 184.91 17.94 233.37 95.401 54.124 75.733 56.675 172.54 80.612 259.53 29.438 127.13 54.779 256.21 60.392 386.85-3.063 78.182-8.426 165.18-60.503 228.13-48.027 50.357-122.79 50.053-187.07 59.002-90.555 4.655-184.35-16.146-261.78-64.198-64.776-37.94-95.73-113.48-97.279-186.02-8.39-79.875 26.392-153.81 51.62-227.16 7.47-82.761 9.413-166.25 9.653-249.38-.837-32.195-7.09-63.817-11.546-95.609z" enable-background="accumulate" fill="#262f2f" fill-rule="evenodd" stroke="#000"/>
-  </clipPath>
-  <clipPath id="jx">
-   <path d="M352.25 211.99c-3.804-25.264-16.81-50.638-17.157-75.525-.186-13.356 3.273-26.571 13.756-39.554 36.347-65.296 116.94-84.695 185.93-91.465 86.922-11.017 184.91 17.94 233.37 95.401 54.124 75.733 56.675 172.54 80.612 259.53 29.438 127.13 54.779 256.21 60.392 386.85-3.063 78.182-8.426 165.18-60.503 228.13-48.027 50.357-122.79 50.053-187.07 59.002-90.555 4.655-184.35-16.146-261.78-64.198-64.776-37.94-95.73-113.48-97.279-186.02-8.39-79.875 26.392-153.81 51.62-227.16 7.47-82.761 9.413-166.25 9.653-249.38-.837-32.195-7.09-63.817-11.546-95.609z" enable-background="accumulate" fill="#262f2f" fill-rule="evenodd" stroke="#000"/>
-  </clipPath>
-  <clipPath id="en">
-   <path d="M352.25 211.99c-3.804-25.264-16.81-50.638-17.157-75.525-.186-13.356 3.273-26.571 13.756-39.554 36.347-65.296 116.94-84.695 185.93-91.465 86.922-11.017 184.91 17.94 233.37 95.401 54.124 75.733 56.675 172.54 80.612 259.53 29.438 127.13 54.779 256.21 60.392 386.85-3.063 78.182-8.426 165.18-60.503 228.13-48.027 50.357-122.79 50.053-187.07 59.002-90.555 4.655-184.35-16.146-261.78-64.198-64.776-37.94-95.73-113.48-97.279-186.02-8.39-79.875 26.392-153.81 51.62-227.16 7.47-82.761 9.413-166.25 9.653-249.38-.837-32.195-7.09-63.817-11.546-95.609z" enable-background="accumulate" fill="#262f2f" fill-rule="evenodd" stroke="#000"/>
-  </clipPath>
-  <clipPath id="jw">
-   <path d="M821.64 477.89s22.619-6.507 35.743-5.873c13.123.634 30.642 1.939 43.709 12.186 13.067 10.248 25.068 27.14 34.112 58.37s1.698 99.252-6.176 143.35-28.265 106.11-45 140-49.798 77.495-60.569 89.876c-11.364 13.062-56.206 36.426-79.431 42.267 5.303-10.607 48.9-50.589 35-60.714-14.019-10.212-45.76 45.982-84.293 29.033 21.382-13.132 41.779-51.186 34.041-66.594-7.84-15.61-30.705 48.758-93.536 37.013 30.052-27.527 55.407-70.904 41.263-82.98-14.415-12.307-60.462 54.293-60.462 54.293s-2.822-41.7 13.773-68.607c16.639-26.978 79.653-81.615 99.553-111.7 19.9-30.088 33.613-66.009 42.135-92.518s15.801-77.1 15.801-77.1" enable-background="new" fill="#202020" fill-rule="evenodd" stroke="#000"/>
-  </clipPath>
-  <clipPath id="kp">
-   <path d="m366.89 504.13s-29.554 40.573-47.857 74.286-58.621 126.36-70.357 171.07c-11.759 44.803-62.5 123.57-62.5 123.57l76.071 18.214s11.807-12.823 31.071-46.071 60.357-138.57 60.357-138.57l13.214-202.5z" enable-background="accumulate" fill="#0f0f0f" fill-rule="evenodd" stroke="#000"/>
-  </clipPath>
-  <clipPath id="eo">
-   <path d="M569.03 1018.8c-4.286.714-27.628 3.618-57.857 10s-99.775 25.962-142.86 35.714-117.26 34.816-156.91 27.265c-39.648-7.55-89.516-64.408-89.516-64.408l4.286-94.286s85.886-16.201 112.14-33.571c26.257-17.37 45.582-49.666 59.286-71.429s32.857-71.429 32.857-71.429l238.57 262.14z" enable-background="accumulate" fill="#0b0b0b" fill-rule="evenodd" stroke="#000"/>
-  </clipPath>
-  <filter id="kc" x="-.353" y="-.182" width="1.706" height="1.363">
-   <feGaussianBlur stdDeviation="48.038"/>
-  </filter>
-  <filter id="jb" x="-.611" y="-.149" width="2.223" height="1.299">
-   <feGaussianBlur stdDeviation="37.83"/>
-  </filter>
-  <filter id="eg" x="-.235" y="-.245" width="1.47" height="1.49">
-   <feGaussianBlur stdDeviation="58.328"/>
-  </filter>
-  <filter id="jy" x="-.205" y="-.29" width="1.409" height="1.58">
-   <feGaussianBlur stdDeviation="22.3"/>
-  </filter>
-  <filter id="jv" x="-.344" y="-.184" width="1.688" height="1.369">
-   <feGaussianBlur stdDeviation="34.542"/>
-  </filter>
-  <filter id="kf" x="-.274" y="-.213" width="1.549" height="1.427">
-   <feGaussianBlur stdDeviation="11.314"/>
-  </filter>
-  <filter id="ja" x="-.259" y="-.224" width="1.518" height="1.447">
-   <feGaussianBlur stdDeviation="19.632"/>
-  </filter>
-  <filter id="kq" x="-.325" y="-.19" width="1.651" height="1.38">
-   <feGaussianBlur stdDeviation="28.713"/>
-  </filter>
-  <filter id="ko" x="-.381" y="-.175" width="1.762" height="1.35">
-   <feGaussianBlur stdDeviation="19.304"/>
-  </filter>
-  <filter id="kv" x="-.211" y="-.168" width="1.422" height="1.336">
-   <feGaussianBlur stdDeviation="8.369"/>
-  </filter>
-  <filter id="ks" x="-.187" y="-.236" width="1.374" height="1.473">
-   <feGaussianBlur stdDeviation="31.212"/>
-  </filter>
-  <clipPath id="ju">
-   <path d="M352.25 211.99c-3.804-25.264-16.81-50.638-17.157-75.525-.186-13.356 3.273-26.571 13.756-39.554 36.347-65.296 116.94-84.695 185.93-91.465 86.922-11.017 184.91 17.94 233.37 95.401 54.124 75.733 56.675 172.54 80.612 259.53 29.438 127.13 54.779 256.21 60.392 386.85-3.063 78.182-8.426 165.18-60.503 228.13-48.027 50.357-122.79 50.053-187.07 59.002-90.555 4.655-184.35-16.146-261.78-64.198-64.776-37.94-95.73-113.48-97.279-186.02-8.39-79.875 26.392-153.81 51.62-227.16 7.47-82.761 9.413-166.25 9.653-249.38-.837-32.195-7.09-63.817-11.546-95.609z" enable-background="accumulate" fill="#262f2f" fill-rule="evenodd" stroke="#000"/>
-  </clipPath>
-  <filter id="ki" x="-.252" y="-.053" width="1.503" height="1.106">
-   <feGaussianBlur stdDeviation="13.025"/>
-  </filter>
-  <linearGradient id="t" x1="603.84" x2="616.24" y1="627.85" y2="585.43" gradientTransform="translate(450.03 73.844)" gradientUnits="userSpaceOnUse">
-   <stop stop-color="#1a1a1a" offset="0"/>
-   <stop stop-color="#1a1a1a" stop-opacity="0" offset="1"/>
-  </linearGradient>
-  <filter id="dq" x="-.329" y="-.182" width="1.657" height="1.364">
-   <feGaussianBlur stdDeviation="20.913"/>
-  </filter>
-  <filter id="dr" x="-.555" y="-.514" width="2.109" height="2.029">
-   <feGaussianBlur stdDeviation="20.913"/>
-  </filter>
-  <filter id="cy" x="-.326" y="-.845" width="1.653" height="2.691">
-   <feGaussianBlur stdDeviation="21.92"/>
-  </filter>
-  <filter id="he" x="-.409" y="-.715" width="1.818" height="2.431">
-   <feGaussianBlur stdDeviation="21.92"/>
-  </filter>
-  <filter id="o">
-   <feGaussianBlur stdDeviation="8.881"/>
-  </filter>
-  <clipPath id="jt">
-   <path d="M647.61 540.05s22.619-6.507 35.743-5.873c13.123.634 30.642 1.939 43.709 12.186 13.067 10.248 25.068 27.14 34.112 58.37s1.698 99.252-6.176 143.35-28.265 106.11-45 140-49.798 77.495-60.569 89.876c-11.364 13.062-56.206 36.426-79.431 42.267 5.303-10.607 48.9-50.589 35-60.714-14.019-10.212-45.76 45.982-84.293 29.033 21.382-13.132 41.779-51.186 34.041-66.594-7.84-15.61-30.705 48.758-93.536 37.013 30.052-27.527 55.407-70.904 41.263-82.98-14.415-12.307-60.462 54.293-60.462 54.293s-2.822-41.7 13.773-68.607c16.639-26.978 79.653-81.615 99.553-111.7 19.9-30.088 33.613-66.009 42.135-92.518s15.801-77.1 15.801-77.1" enable-background="new" fill="#202020" fill-rule="evenodd"/>
-  </clipPath>
-  <filter id="je" x="-.277" y="-.325" width="1.554" height="1.65">
-   <feGaussianBlur stdDeviation="19.956"/>
-  </filter>
-  <clipPath id="e">
-   <path d="M760.16 935.83c6.794 18.903 10.494 33.3 11.89 51.212 1.397 17.912-3.783 51.801-2.9 70.656.881 18.845 8.133 40.099 27.345 48.969 19.419 8.966 49.319 10.211 74.12-3.146 24.8-13.357 57.4-70.326 70.974-97.309 13.624-27.084 38.76-114.5 44.66-149.77 5.9-35.27 2.551-41.3-4.617-49.055 2.64-27.84-1.5-54.935 13.11-87.186-30.249 11.826-37.382 40.161-48.319 65.505-8-50.933.21-71.273 3.319-101.22-29.065 14.778-42.862 47.114-45 92.857-10.924-1.304-21.391-4.434-33.571-.714-.264-46.023-1.464-76.889 8.91-114.21-53.254 21.027-62.946 106.59-56.052 112.78-10.883.535-21.371-1.297-32.857 2.857.638-42.57-.261-84.909-30-122.86 0 0-30.958 80.922-31.43 103.57s9.452 40.166 9.452 40.166-8.568 36.741-6.298 58.232c2.295 21.741 20.443 59.676 27.265 78.658z" enable-background="new" fill="#ada469" fill-rule="evenodd"/>
-  </clipPath>
-  <clipPath id="kr">
-   <path d="m366.89 504.13s-29.554 40.573-47.857 74.286-58.621 126.36-70.357 171.07c-11.759 44.803-62.5 123.57-62.5 123.57l76.071 18.214s11.807-12.823 31.071-46.071 60.357-138.57 60.357-138.57l13.214-202.5z" enable-background="accumulate" fill="#0f0f0f" fill-rule="evenodd"/>
-  </clipPath>
-  <clipPath id="am">
-   <path d="M586.13 997.99c6.794 18.903 10.494 33.3 11.89 51.212 1.397 17.912-3.783 51.801-2.9 70.656.881 18.845 8.133 40.099 27.345 48.969 19.419 8.966 49.319 10.211 74.12-3.146 24.8-13.357 57.4-70.326 70.974-97.309 13.624-27.084 38.76-114.5 44.66-149.77 5.9-35.27 2.551-41.3-4.617-49.055 2.64-27.84-1.5-54.935 13.11-87.186-30.249 11.826-37.382 40.161-48.319 65.505-8-50.933.21-71.273 3.319-101.22-29.065 14.778-42.862 47.114-45 92.857-10.924-1.304-21.391-4.434-33.571-.714-.264-46.023-1.464-76.889 8.91-114.21-53.254 21.027-62.946 106.59-56.052 112.78-10.883.535-21.371-1.297-32.857 2.857.638-42.57-.261-84.909-30-122.86 0 0-30.958 80.922-31.43 103.57s9.452 40.166 9.452 40.166-8.568 36.741-6.298 58.232c2.295 21.741 20.443 59.676 27.265 78.658z" enable-background="new" fill="#ada469" fill-rule="evenodd"/>
-  </clipPath>
-  <filter id="ds">
-   <feGaussianBlur stdDeviation="10.893"/>
-  </filter>
-  <filter id="bz" x="-.495" y="-.267" width="1.99" height="1.534">
-   <feGaussianBlur stdDeviation="10.731"/>
-  </filter>
-  <filter id="by" x="-.406" y="-.303" width="1.812" height="1.605">
-   <feGaussianBlur stdDeviation="9.859"/>
-  </filter>
-  <clipPath id="cj">
-   <path d="M586.13 997.99c6.794 18.903 10.494 33.3 11.89 51.212 1.397 17.912-3.783 51.801-2.9 70.656.881 18.845 8.133 40.099 27.345 48.969 19.419 8.966 49.319 10.211 74.12-3.146 24.8-13.357 57.4-70.326 70.974-97.309 13.624-27.084 38.76-114.5 44.66-149.77 5.9-35.27 2.551-41.3-4.617-49.055 2.64-27.84-1.5-54.935 13.11-87.186-30.249 11.826-37.382 40.161-48.319 65.505-8-50.933.21-71.273 3.319-101.22-29.065 14.778-42.862 47.114-45 92.857-10.924-1.304-21.391-4.434-33.571-.714-.264-46.023-1.464-76.889 8.91-114.21-53.254 21.027-62.946 106.59-56.052 112.78-10.883.535-21.371-1.297-32.857 2.857.638-42.57-.261-84.909-30-122.86 0 0-30.958 80.922-31.43 103.57s9.452 40.166 9.452 40.166-8.568 36.741-6.298 58.232c2.295 21.741 20.443 59.676 27.265 78.658z" enable-background="new" fill="#ada469" fill-rule="evenodd"/>
-  </clipPath>
-  <filter id="il">
-   <feGaussianBlur stdDeviation="3.616"/>
-  </filter>
-  <filter id="ir">
-   <feGaussianBlur stdDeviation="3.864"/>
-  </filter>
-  <clipPath id="ku">
-   <path d="M569.03 1018.8c-4.286.714-27.628 3.618-57.857 10s-57.314 4.966-135.79 17.33c-79.852 12.581-94.064 42.542-108.12 47.064-14.7 4.729-145.38-65.822-145.38-65.822l4.286-94.286s85.886-16.201 112.14-33.571c26.257-17.37 45.582-49.666 59.286-71.429s32.857-71.429 32.857-71.429l238.57 262.14z" enable-background="accumulate" fill="#292929" fill-rule="evenodd" stroke="#000"/>
-  </clipPath>
-  <linearGradient id="dt" x1="699.33" x2="698.98" y1="269.77" y2="346.14" gradientUnits="userSpaceOnUse">
-   <stop stop-color="#fff" offset="0"/>
-   <stop offset="1"/>
-  </linearGradient>
-  <mask id="jc" maskUnits="userSpaceOnUse">
-   <ellipse transform="translate(-174.03 62.156)" cx="579.47" cy="260.58" rx="192.69" ry="164.05" enable-background="accumulate" fill="url(#dt)"/>
-  </mask>
-  <clipPath id="is">
-   <path d="m266.27 924.57c-1.407 18.801-1.145 32.751 2.082 49.303s16.406 45.907 20.334 63.184c3.926 17.267 2.694 38.31-12.46 51.148-15.317 12.977-42.05 21.599-67.831 15.734s-69.55-49.223-88.59-70.228c-19.112-21.083-63.761-93.851-77.94-124.28-14.177-30.425-12.66-36.719-8.119-45.53-9.367-24.52-12.414-50.067-33.712-75.577 30.325 3.114 43.88 26.956 60.126 47.14-5.53-48.076-18.055-64.416-28.374-90.724 29.994 6.082 50.579 31.872 63.98 72.712 9.554-3.918 18.238-9.373 30.187-9.061-11.298-41.696-17.949-69.916-36.687-101.07 53.442 5.67 83.657 80.639 78.971 87.96 9.978-2.243 19.006-6.53 30.437-5.65-11.249-38.348-21.048-76.869-3.66-118.65 0 0 48.287 65.436 54.39 85.805 6.103 20.37 1.52 38.701 1.52 38.701s16.96 31.085 20.293 51.094c3.373 20.241-3.533 59.103-4.946 77.983z" enable-background="new" fill="#ada469" fill-rule="evenodd"/>
-  </clipPath>
-  <clipPath id="im">
-   <path d="M760.16 935.83c6.794 18.903 10.494 33.3 11.89 51.212 1.397 17.912-3.783 51.801-2.9 70.656.881 18.845 8.133 40.099 27.345 48.969 19.419 8.966 49.319 10.211 74.12-3.146 24.8-13.357 57.4-70.326 70.974-97.309 13.624-27.084 38.76-114.5 44.66-149.77 5.9-35.27 2.551-41.3-4.617-49.055 2.64-27.84-1.5-54.935 13.11-87.186-30.249 11.826-37.382 40.161-48.319 65.505-8-50.933.21-71.273 3.319-101.22-29.065 14.778-42.862 47.114-45 92.857-10.924-1.304-21.391-4.434-33.571-.714-.264-46.023-1.464-76.889 8.91-114.21-53.254 21.027-62.946 106.59-56.052 112.78-10.883.535-21.371-1.297-32.857 2.857.638-42.57-.261-84.909-30-122.86 0 0-30.958 80.922-31.43 103.57s9.452 40.166 9.452 40.166-8.568 36.741-6.298 58.232c2.295 21.741 20.443 59.676 27.265 78.658z" enable-background="new" fill="#ada469" fill-rule="evenodd" stroke="#000"/>
-  </clipPath>
-  <filter id="jq" x="-.088" y="-.177" width="1.176" height="1.355">
-   <feGaussianBlur stdDeviation="16.34"/>
-  </filter>
-  <filter id="i">
-   <feTurbulence baseFrequency=".24" numOctaves="10" result="result0" seed="655" type="fractalNoise"/>
-   <feDisplacementMap in="SourceGraphic" in2="result0" scale="62" xChannelSelector="B" yChannelSelector="G"/>
-  </filter>
-  <filter id="em">
-   <feGaussianBlur stdDeviation="2.04"/>
-  </filter>
-  <clipPath id="jo">
-   <path d="m709.29 844.51c54.286-1.429 126.04-15.052 170-26.786 44.053-11.757 125.89-36.347 175.36-57.857 49.339-21.453 113.6-59.282 154.29-92.143 40.508-32.721 52.39-55.82 60.714-33.571 8.37 22.368-16.407 56.326-37.857 81.071-21.604 24.923-52.731 52.705-98.929 89.286s-156.08 101.58-212.86 128.57c-57.066 27.125-128.2 58.238-172.14 72.5s-131.43 31.071-131.43 31.071l92.857-192.14z" enable-background="accumulate" fill="#121212" fill-rule="evenodd"/>
-  </clipPath>
-  <clipPath id="jp">
-   <path d="m709.29 844.51c54.286-1.429 126.04-15.052 170-26.786 44.053-11.757 125.89-36.347 175.36-57.857 49.339-21.453 113.6-59.282 154.29-92.143 40.508-32.721 52.39-55.82 60.714-33.571 8.37 22.368-16.407 56.326-37.857 81.071-21.604 24.923-52.731 52.705-98.929 89.286s-156.08 101.58-212.86 128.57c-57.066 27.125-128.2 58.238-172.14 72.5s-131.43 31.071-131.43 31.071l92.857-192.14z" enable-background="accumulate" fill="#121212" fill-rule="evenodd"/>
-  </clipPath>
-  <clipPath id="js">
-   <path d="m709.29 844.51c54.286-1.429 126.04-15.052 170-26.786 44.053-11.757 125.89-36.347 175.36-57.857 49.339-21.453 113.6-59.282 154.29-92.143 40.508-32.721 52.39-55.82 60.714-33.571 8.37 22.368-16.407 56.326-37.857 81.071-21.604 24.923-52.731 52.705-98.929 89.286s-156.08 101.58-212.86 128.57c-57.066 27.125-128.2 58.238-172.14 72.5s-131.43 31.071-131.43 31.071l92.857-192.14z" enable-background="accumulate" fill="#121212" fill-rule="evenodd"/>
-  </clipPath>
-  <clipPath id="ke">
-   <path d="M178.21 274.15c-3.804-25.264-16.81-50.638-17.157-75.525-.186-13.356 3.273-26.571 13.756-39.554 36.347-65.296 116.94-84.695 185.93-91.465 86.922-11.017 184.91 17.94 233.37 95.401 54.124 75.733 56.675 172.54 80.612 259.53 29.438 127.13 54.779 256.21 60.392 386.85-3.063 78.182-8.426 165.18-60.503 228.13-48.027 50.357-122.79 50.053-187.07 59.002-90.555 4.655-184.35-16.146-261.78-64.198-64.776-37.94-95.73-113.48-97.279-186.02-8.39-79.875 26.392-153.81 51.62-227.16 7.47-82.761 9.413-166.25 9.653-249.38-.837-32.195-7.09-63.817-11.546-95.609z" enable-background="accumulate" fill="#262f2f" fill-rule="evenodd"/>
-  </clipPath>
-  <filter id="iv" x="-.243" y="-.391" width="1.487" height="1.782">
-   <feGaussianBlur stdDeviation="14.59"/>
-  </filter>
-  <filter id="iu" x="-.146" y="-.235" width="1.292" height="1.47">
-   <feGaussianBlur stdDeviation="4.444"/>
-  </filter>
-  <filter id="it">
-   <feGaussianBlur stdDeviation=".606"/>
-  </filter>
-  <filter id="ix">
-   <feGaussianBlur stdDeviation="6.589"/>
-  </filter>
-  <filter id="iw">
-   <feGaussianBlur stdDeviation="1.505"/>
-  </filter>
-  <filter id="jj" x="-.103" y="-.342" width="1.206" height="1.685">
-   <feGaussianBlur stdDeviation="1.168"/>
-  </filter>
-  <filter id="jf" x="-.098" y="-.198" width="1.197" height="1.395">
-   <feGaussianBlur stdDeviation="1.168"/>
-  </filter>
-  <filter id="jh" x="-.098" y="-.198" width="1.196" height="1.397">
-   <feGaussianBlur stdDeviation="1.168"/>
-  </filter>
-  <filter id="ji" x="-.099" y="-.226" width="1.198" height="1.453">
-   <feGaussianBlur stdDeviation="1.168"/>
-  </filter>
-  <filter id="hy" x="-.099" y="-.225" width="1.198" height="1.451">
-   <feGaussianBlur stdDeviation="1.168"/>
-  </filter>
-  <filter id="hu" x="-.105" y="-.405" width="1.209" height="1.809">
-   <feGaussianBlur stdDeviation="1.168"/>
-  </filter>
-  <filter id="hv" x="-.103" y="-.364" width="1.207" height="1.729">
-   <feGaussianBlur stdDeviation="1.168"/>
-  </filter>
-  <filter id="hw" x="-.102" y="-.324" width="1.204" height="1.647">
-   <feGaussianBlur stdDeviation="1.168"/>
-  </filter>
-  <filter id="hx" x="-.101" y="-.274" width="1.201" height="1.548">
-   <feGaussianBlur stdDeviation="1.168"/>
-  </filter>
-  <filter id="hz" x="-.098" y="-.209" width="1.197" height="1.417">
-   <feGaussianBlur stdDeviation="1.168"/>
-  </filter>
-  <filter id="ia" x="-.098" y="-.203" width="1.197" height="1.406">
-   <feGaussianBlur stdDeviation="1.168"/>
-  </filter>
-  <filter id="ib" x="-.098" y="-.198" width="1.196" height="1.397">
-   <feGaussianBlur stdDeviation="1.168"/>
-  </filter>
-  <filter id="jg">
-   <feGaussianBlur stdDeviation="1.168"/>
-  </filter>
-  <filter id="jk">
-   <feGaussianBlur stdDeviation="1.168"/>
-  </filter>
-  <filter id="hr" x="-.031" y="-.103" width="1.062" height="1.205">
-   <feGaussianBlur stdDeviation=".35"/>
-  </filter>
-  <filter id="hq">
-   <feGaussianBlur stdDeviation=".35"/>
-  </filter>
-  <filter id="hp">
-   <feGaussianBlur stdDeviation=".35"/>
-  </filter>
-  <filter id="hn">
-   <feGaussianBlur stdDeviation=".35"/>
-  </filter>
-  <filter id="hm">
-   <feGaussianBlur stdDeviation=".35"/>
-  </filter>
-  <filter id="hl">
-   <feGaussianBlur stdDeviation=".35"/>
-  </filter>
-  <filter id="hk">
-   <feGaussianBlur stdDeviation=".35"/>
-  </filter>
-  <filter id="hj">
-   <feGaussianBlur stdDeviation=".35"/>
-  </filter>
-  <filter id="hi">
-   <feGaussianBlur stdDeviation=".35"/>
-  </filter>
-  <filter id="hh">
-   <feGaussianBlur stdDeviation=".35"/>
-  </filter>
-  <filter id="hf" x="-.031" y="-.121" width="1.063" height="1.243">
-   <feGaussianBlur stdDeviation=".35"/>
-  </filter>
-  <filter id="hg" x="-.031" y="-.109" width="1.062" height="1.219">
-   <feGaussianBlur stdDeviation=".35"/>
-  </filter>
-  <filter id="hs">
-   <feGaussianBlur stdDeviation=".35"/>
-  </filter>
-  <filter id="ho">
-   <feGaussianBlur stdDeviation=".35"/>
-  </filter>
-  <filter id="ht">
-   <feGaussianBlur stdDeviation="1.723"/>
-  </filter>
-  <clipPath id="jl">
-   <path transform="translate(.08 -.031)" d="M1111.4-285.94l-3.937 1.875c-.041.01-.1.02-.125.031-.42.213-.165.1-.657.313-.486.21-1.737.584-4.093 1.469-3.332 1.25-5.805 2.15-7 3.062-1.537.021-3.72.233-5.657.719a227.677 227.677 0 0 1-6.75 1.594c-1.895.42-1.675.642-2.875.875-1.296.251-1.721-.01-5.437.78-3.49.743-8.895 1.932-10.156 2.688-1.584-.18-3.868-.321-5.844-.03-3.04.446-4.916.672-6.844.905-.655.08-1.04.201-1.344.282-.426.131-.685.26-1.375.343-1.311.16-1.762-.156-5.53.282-3.555.413-9.006 1.272-10.25 1.937-1.6-.297-3.859-.534-5.845-.344-3.058.294-4.972.484-6.906.657-1.934.172-1.688.422-2.906.53-1.316.119-1.76-.163-5.531.25-3.542.39-9.008 1.21-10.281 1.876-1.6-.295-3.887-.507-5.875-.313-3.059.3-4.941.48-6.875.657-.658.06-1.04.178-1.344.25-.428.119-.683.218-1.375.28-1.316.121-1.76-.194-5.531.22-3.556.39-9.006 1.239-10.25
-1.906-1.599-.294-3.86-.524-5.844-.313-3.056.326-4.974.527-6.906.719s-1.69.44-2.906.563c-1.315.131-1.763-.165-5.532.28-3.539.42-8.977 1.293-10.25 1.97-1.597-.281-3.86-.42-5.843-.188-3.052.358-4.945.568-6.875.781-.657.073-1.041.173-1.344.25-.427.128-.685.268-1.375.344-1.314.146-1.768-.174-5.531.313-3.55.458-8.979 1.419-10.22 2.125-1.593-.245-3.833-.382-5.812-.125-3.048.394-4.95.648-6.875.906-1.924.258-1.726.493-2.937.656-1.31.176-1.748-.104-5.5.469-3.525.538-8.924 1.699-10.188 2.437-1.588-.203-3.846-.254-5.813.094-3.026.536-4.899.862-6.812 1.188-.651.11-1.014.27-1.313.375-.42.164-.663.33-1.344.468-1.294.262-1.727-.006-5.437.813-3.499.772-8.846 2.383-10.062 3.219-1.563-.078-3.758.085-5.688.593-2.972.783-4.817 1.232-6.687 1.75s-1.667.768-2.844 1.094c-1.273.353-1.697.107-5.344 1.188-3.425 1.014-8.65 2.933-9.875 3.843-1.539.013-3.72.273-5.625.875-2.93.928-4.75 1.459-6.594
-2.063-.626.205-.991.393-1.28.531-.408.214-.654.409-1.313.625-1.255.412-1.687.19-5.282 1.438-3.39 1.177-8.595 3.213-9.78 4.156-1.525.06-3.65.395-5.532 1.062-2.897 1.029-4.699 1.676-6.531 2.313-1.832.637-1.628.848-2.781 1.25-1.247.434-1.664.2-5.22 1.562-3.338 1.28-8.486 3.483-9.687 4.47-1.507.107-3.635.498-5.5 1.218a1047.26 1047.26 0 0 1-6.437 2.469c-.617.233-.997.442-1.281.594v.03l-8 3.188 1.812 14.72c-.258-.062 6.188 3.312 6.188 3.312.226-.145.449-.273.718-.375 1.08-.41 2.172-.216 6-1.688 3.829-1.471 5.224-2.005 5.907-2.406.68-.4 1.611-.88 2.218-1.531 1.827-.138 3.571-.493 4.938-1 2.968-1.1 4.875-1.806 6.781-2.469 1.906-.662 2.354-1.415 3.406-1.781 1.092-.38 2.195-.166 6.063-1.531 3.867-1.366 5.283-1.827 5.969-2.22.7-.4 1.7-.932 2.312-1.593 1.97-.055 3.817-.385 5.281-.875 3.002-1.005 4.927-1.622 6.844-2.25 1.539-.504 2.174-1.047 2.906-1.437.23-.135.476-.254.75-.344 1.099-.36 2.182-.082
-6.094-1.313 3.912-1.23 5.366-1.673 6.063-2.03.694-.358 1.63-.794 2.25-1.407 1.865-.023 3.635-.267 5.03-.688 3.031-.913 4.993-1.43 6.938-1.968 1.945-.539 2.427-1.265 3.5-1.563 1.114-.31 2.22.007 6.188-1.031 3.967-1.039 5.417-1.433 6.125-1.75.735-.33 1.814-.754 2.437-1.375 1.998.116 3.858-.02 5.344-.375 3.078-.735 5.084-1.101 7.063-1.5 1.588-.32 2.244-.79 3-1.094a3.4 3.4 0 0 1 .75-.25c1.133-.23 2.304.209 6.343-.5 4.04-.709 5.5-.927 6.22-1.187.715-.26 1.704-.568 2.343-1.094 1.924.24 3.748.224 5.188 0 3.126-.488 5.154-.7 7.156-.969 2.001-.268 2.489-.945 3.594-1.094 1.146-.154 2.275.302 6.343-.219 4.068-.52 5.56-.695 6.282-.937.737-.247 1.798-.586 2.437-1.125 2.05.336 3.974.398 5.5.219 3.142-.37 5.18-.56 7.188-.782 1.61-.178 2.264-.608 3.03-.843.242-.086.495-.156.782-.188 1.15-.127 2.301.347 6.375-.125s5.559-.61 6.281-.844c.72-.232 1.7-.473 2.344-.968 1.936.333 3.77.404 5.219.25 3.146-.335
-5.177-.519 7.187-.719 2.01-.2 2.484-.826 3.594-.938 1.151-.115 2.297.366 6.375-.062s5.589-.562 6.313-.781c.739-.224 1.795-.514 2.437-1.031 2.057.398 4.002.493 5.531.343 3.149-.308 5.176-.473 7.188-.656 1.614-.147 2.263-.56 3.031-.781.241-.081.494-.13.781-.156 1.152-.106 2.293.392 6.375 0s5.59-.531 6.313-.75c.72-.219 1.7-.448 2.343-.938 1.939.35 3.77.454 5.22.313 3.148-.309 5.175-.474 7.187-.657 2.011-.183 2.514-.838 3.625-.937 1.152-.103 2.292.385 6.375 0s5.588-.501 6.312-.719c.74-.222 1.796-.514 2.438-1.031 2.057.402 4.003.503 5.531.344 3.147-.329 5.177-.523 7.187-.72 1.613-.156 2.266-.63 3.032-.874.24-.088.463-.122.75-.156 1.148-.14 2.316.34 6.375-.25 4.058-.59 5.562-.778 6.281-1.032.717-.253 1.675-.558 2.312-1.093 1.92.212 3.72.151 5.157-.094 3.119-.533 5.111-.929 7.093-1.313 1.983-.383 2.475-1.04 3.563-1.28 1.129-.251 2.27.115 6.25-.876s5.43-1.42 6.125-1.781c.722-.376 1.762-.87
-2.375-1.531 1.963-.012 3.794-.291 5.219-.844 2.95-1.145 4.873-1.87 6.687-2.75 1.456-.706 2.32-1.702 2.531-2 .213-.298.1-.729.125-.75.043-.035.34-.094.5-.437.86-1.848 2.324-5.628 2.438-6.313.114-.682.168-1.353.219-1.75.029-.23-.147-.879-.125-.937.03-.082.288-.251.343-.5.267-1.199.09-2.208-.125-3.625-.213-1.418-.971-4.615-1.625-5.47-.658-.861-1.224-1.01-1.75-1z" enable-background="new" fill="#bcb786" fill-rule="evenodd"/>
-  </clipPath>
-  <filter id="kk" x="-.082" y="-.227" width="1.163" height="1.453">
-   <feGaussianBlur stdDeviation="2.437"/>
-  </filter>
-  <filter id="kj" x="-.041" y="-.113" width="1.082" height="1.227">
-   <feGaussianBlur stdDeviation="1.219"/>
-  </filter>
-  <clipPath id="kl">
-   <path d="M1049.2-282.27l-.09.008c-1.387.884-6.603 1.607-6.629 9.523-.024 7.426 15.013 17.091 17.156 18.094 1.73.81 3.592 1.41 5.406 1.72l1.438.218c1.92.212 3.72.151 5.156-.094 3.12-.532 5.112-.928 7.094-1.312 1.982-.384 2.474-1.04 3.562-1.281 1.129-.251 2.27.116 6.25-.875 3.98-.992 5.43-1.42 6.125-1.782.723-.376 1.762-.87 2.375-1.53 1.963-.013 3.794-.292 5.219-.845 2.951-1.144 4.873-1.869 6.688-2.75 1.455-.706 2.319-1.702 2.53-2 .213-.298.1-.728.126-.75.043-.035.34-.094.5-.437.859-1.847 2.323-5.628 2.437-6.313.114-.682.168-1.352.219-1.75.029-.23-.147-.879-.125-.937.031-.082.288-.25.344-.5.266-1.198.089-2.208-.125-3.625-.214-1.418-.972-4.615-1.625-5.469-.42-.548-.8-.792-1.157-.906-.067-.017-.123-.047-.187-.063-.021-.004-.042.003-.062 0-.312-.075-.609-.158-1.156-.218-.986-.109-2.425-.26-3.969-.25-.515.003-1.037.047-1.563.093-3.558.313-9.01.991-10.218
-1.625-1.634-.334-3.949-.612-5.938-.468-3.064.22-4.968.342-6.906.468-1.939.127-1.686.389-2.906.469-1.32.087-1.787-.223-5.563.094-3.546.297-8.98.993-10.22 1.625-1.632-.335-3.945-.613-5.937-.469-3.064.221-4.967.373-6.906.5-.659.043-1.042.124-1.344.187z" enable-background="new" fill="#bcb786" fill-rule="evenodd" opacity=".824"/>
-  </clipPath>
-  <filter id="km" x="-.022" width="1.044">
-   <feGaussianBlur stdDeviation=".575"/>
-  </filter>
-  <clipPath id="kn">
-   <path d="M205.47-408.97l-.09.002c-1.446.786-6.7 1.143-7.276 9.039-.542 7.405 13.786 18.096 15.854 19.245 1.67.927 3.484 1.655 5.273 2.09l1.419.32c1.9.344 3.7.41 5.15.265 3.149-.314 5.164-.57 7.168-.815 2.004-.245 2.54-.865 3.643-1.03 1.144-.172 2.257.274 6.296-.438s5.515-1.038 6.234-1.35c.747-.325 1.818-.746 2.476-1.362 1.96.124 3.805-.026 5.265-.479 3.024-.936 4.991-1.525 6.863-2.277 1.501-.603 2.432-1.536 2.664-1.819.233-.282.15-.72.177-.74.045-.032.346-.07.53-.4.985-1.784 2.709-5.453 2.87-6.128.162-.673.263-1.338.34-1.73.046-.228-.085-.888-.059-.945.037-.08.305-.23.378-.475.35-1.177.243-2.195.128-3.625-.115-1.429-.648-4.67-1.24-5.568-.38-.577-.742-.846-1.09-.985-.066-.022-.12-.055-.183-.075-.02-.005-.042 0-.063-.004-.305-.097-.596-.2-1.138-.299-.975-.176-2.4-.428-3.942-.526a19.346 19.346 0 0
-0-1.565-.015c-3.572.064-9.057.361-10.307.91-1.606-.448-3.896-.886-5.89-.882-3.072.007-4.98-.005-6.922-.013-1.943-.01-1.71.27-2.932.265-1.322-.005-1.767-.347-5.556-.294-3.558.05-9.028.365-10.307.91-1.606-.448-3.893-.887-5.89-.882-3.072.007-4.982.027-6.924.018-.661-.003-1.049.05-1.354.093z" enable-background="new" fill="#bcb786" fill-rule="evenodd" opacity=".824"/>
-  </clipPath>
-  <linearGradient id="w" x1="774.98" x2="755.12" y1="-211.87" y2="-202.68" gradientTransform="translate(-19.092 4.243)" gradientUnits="userSpaceOnUse" xlink:href="#n"/>
-  <mask id="jm" maskUnits="userSpaceOnUse">
-   <path d="m718.41-224.31l33.25 56 276-24 159.5-48.25-66.5-82.75-402.25 99z" fill="url(#w)" fill-rule="evenodd"/>
-  </mask>
-  <clipPath id="kg">
-   <path d="M734.03 519.49s16.755 37.018 28.701 53.954 52.727 56.046 52.727 56.046l.597-138.59" enable-background="accumulate" fill="#1a1a1a" fill-rule="evenodd" stroke="#000"/>
-  </clipPath>
-  <filter id="jn">
-   <feGaussianBlur stdDeviation="10.662"/>
-  </filter>
-  <filter id="ip">
-   <feGaussianBlur stdDeviation="7.18"/>
-  </filter>
-  <clipPath id="iq">
-   <path d="m266.27 924.57c-1.407 18.801-1.145 32.751 2.082 49.303 3.226 16.552 16.406 45.907 20.334 63.184 3.926 17.267 2.694 38.31-12.46 51.148-15.317 12.978-42.05 21.599-67.831 15.734s-69.55-49.223-88.59-70.228c-19.112-21.083-63.761-93.851-77.94-124.28-14.177-30.425-12.66-36.719-8.119-45.53-9.367-24.52-12.414-50.067-33.712-75.577 30.325 3.114 43.88 26.956 60.126 47.14-5.53-48.076-18.055-64.417-28.374-90.724 29.994 6.082 50.579 31.872 63.98 72.712 9.554-3.918 18.238-9.373 30.187-9.061-11.298-41.696-17.949-69.916-36.687-101.07 53.442 5.67 83.657 80.639 78.971 87.96 9.978-2.243 19.006-6.53 30.437-5.65-11.249-38.348-21.048-76.869-3.66-118.65 0 0 48.287 65.436 54.39 85.805 6.103 20.37 1.52 38.701 1.52 38.701s16.96 31.085 20.293 51.094c3.373 20.241-3.533 59.103-4.946 77.983z" enable-background="new" fill="#ada469" fill-rule="evenodd"/>
-  </clipPath>
-  <filter id="in">
-   <feGaussianBlur stdDeviation="6.82"/>
-  </filter>
-  <clipPath id="io">
-   <path d="m266.27 924.57c-1.407 18.801-1.145 32.751 2.082 49.303 3.226 16.552 16.406 45.907 20.334 63.184 3.926 17.267 2.694 38.31-12.46 51.148-15.317 12.978-42.05 21.599-67.831 15.734s-69.55-49.223-88.59-70.228c-19.112-21.083-63.761-93.851-77.94-124.28-14.177-30.425-12.66-36.719-8.119-45.53-9.367-24.52-12.414-50.067-33.712-75.577 30.325 3.114 43.88 26.956 60.126 47.14-5.53-48.076-18.055-64.417-28.374-90.724 29.994 6.082 50.579 31.872 63.98 72.712 9.554-3.918 18.238-9.373 30.187-9.061-11.298-41.696-17.949-69.916-36.687-101.07 53.442 5.67 83.657 80.639 78.971 87.96 9.978-2.243 19.006-6.53 30.437-5.65-11.249-38.348-21.048-76.869-3.66-118.65 0 0 48.287 65.436 54.39 85.805 6.103 20.37 1.52 38.701 1.52 38.701s16.96 31.085 20.293 51.094c3.373 20.241-3.533 59.103-4.946 77.983z" enable-background="new" fill="#ada469" fill-rule="evenodd"/>
-  </clipPath>
-  <filter id="ij" x="-.144" y="-.103" width="1.288" height="1.206">
-   <feGaussianBlur stdDeviation="7.389"/>
-  </filter>
-  <clipPath id="ik">
-   <path d="M760.16 935.83c6.794 18.903 10.494 33.3 11.89 51.212 1.397 17.912-3.783 51.801-2.9 70.656.881 18.845 8.133 40.099 27.345 48.969 19.419 8.966 49.319 10.211 74.12-3.146 24.8-13.357 57.4-70.326 70.974-97.309 13.624-27.084 38.76-114.5 44.66-149.77 5.9-35.27 2.551-41.3-4.617-49.055 2.64-27.84-1.5-54.935 13.11-87.186-30.249 11.826-37.382 40.161-48.319 65.505-8-50.933.21-71.273 3.319-101.22-29.065 14.778-42.862 47.114-45 92.857-10.924-1.304-21.391-4.434-33.571-.714-.264-46.023-1.464-76.889 8.91-114.21-53.254 21.027-62.946 106.59-56.052 112.78-10.883.535-21.371-1.297-32.857 2.857.638-42.57-.261-84.909-30-122.86 0 0-30.958 80.922-31.43 103.57s9.452 40.166 9.452 40.166-8.568 36.741-6.298 58.232c2.295 21.741 20.443 59.676 27.265 78.658z" enable-background="new" fill="#ada469" fill-rule="evenodd"/>
-  </clipPath>
-  <filter id="ih" x="-.09" y="-.103" width="1.181" height="1.205">
-   <feGaussianBlur stdDeviation="5.346"/>
-  </filter>
-  <clipPath id="ii">
-   <path d="M760.16 935.83c6.794 18.903 10.494 33.3 11.89 51.212 1.397 17.912-3.783 51.801-2.9 70.656.881 18.845 8.133 40.099 27.345 48.969 19.419 8.966 49.319 10.211 74.12-3.146 24.8-13.357 57.4-70.326 70.974-97.309 13.624-27.084 38.76-114.5 44.66-149.77 5.9-35.27 2.551-41.3-4.617-49.055 2.64-27.84-1.5-54.935 13.11-87.186-30.249 11.826-37.382 40.161-48.319 65.505-8-50.933.21-71.273 3.319-101.22-29.065 14.778-42.862 47.114-45 92.857-10.924-1.304-21.391-4.434-33.571-.714-.264-46.023-1.464-76.889 8.91-114.21-53.254 21.027-62.946 106.59-56.052 112.78-10.883.535-21.371-1.297-32.857 2.857.638-42.57-.261-84.909-30-122.86 0 0-30.958 80.922-31.43 103.57s9.452 40.166 9.452 40.166-8.568 36.741-6.298 58.232c2.295 21.741 20.443 59.676 27.265 78.658z" enable-background="new" fill="#ada469" fill-rule="evenodd"/>
-  </clipPath>
-  <clipPath id="gc">
-   <path d="M569.03 1018.8c-4.286.714-27.628 3.618-57.857 10s-99.775 25.962-142.86 35.714-117.26 34.816-156.91 27.265c-39.648-7.55-89.516-64.408-89.516-64.408l4.286-94.286s85.886-16.201 112.14-33.571c26.257-17.37 45.582-49.666 59.286-71.429s32.857-71.429 32.857-71.429l238.57 262.14z" enable-background="accumulate" fill="#0b0b0b" fill-rule="evenodd" stroke="#000"/>
-  </clipPath>
-  <filter id="gb" x="-.211" y="-.168" width="1.422" height="1.336">
-   <feGaussianBlur stdDeviation="8.369"/>
-  </filter>
-  <clipPath id="fz">
-   <path d="M205.47-408.97l-.09.002c-1.446.786-6.7 1.143-7.276 9.039-.542 7.405 13.786 18.096 15.854 19.245 1.67.927 3.484 1.655 5.273 2.09l1.419.32c1.9.344 3.7.41 5.15.265 3.149-.314 5.164-.57 7.168-.815 2.004-.245 2.54-.865 3.643-1.03 1.144-.172 2.257.274 6.296-.438s5.515-1.038 6.234-1.35c.747-.325 1.818-.746 2.476-1.362 1.96.124 3.805-.026 5.265-.479 3.024-.936 4.991-1.525 6.863-2.277 1.501-.603 2.432-1.536 2.664-1.819.233-.282.15-.72.177-.74.045-.032.346-.07.53-.4.985-1.784 2.709-5.453 2.87-6.128.162-.673.263-1.338.34-1.73.046-.228-.085-.888-.059-.945.037-.08.305-.23.378-.475.35-1.177.243-2.195.128-3.625-.115-1.429-.648-4.67-1.24-5.568-.38-.577-.742-.846-1.09-.985-.066-.022-.12-.055-.183-.075-.02-.005-.042 0-.063-.004-.305-.097-.596-.2-1.138-.299-.975-.176-2.4-.428-3.942-.526a19.346 19.346 0 0
-0-1.565-.015c-3.572.064-9.057.361-10.307.91-1.606-.448-3.896-.886-5.89-.882-3.072.007-4.98-.005-6.922-.013-1.943-.01-1.71.27-2.932.265-1.322-.005-1.767-.347-5.556-.294-3.558.05-9.028.365-10.307.91-1.606-.448-3.893-.887-5.89-.882-3.072.007-4.982.027-6.924.018-.661-.003-1.049.05-1.354.093z" enable-background="new" fill="#bcb786" fill-rule="evenodd" opacity=".824"/>
-  </clipPath>
-  <filter id="fy" x="-.022" width="1.044">
-   <feGaussianBlur stdDeviation=".575"/>
-  </filter>
-  <clipPath id="fx">
-   <path d="M1049.2-282.27l-.09.008c-1.387.884-6.603 1.607-6.629 9.523-.024 7.426 15.013 17.091 17.156 18.094 1.73.81 3.592 1.41 5.406 1.72l1.438.218c1.92.212 3.72.151 5.156-.094 3.12-.532 5.112-.928 7.094-1.312 1.982-.384 2.474-1.04 3.562-1.281 1.129-.251 2.27.116 6.25-.875 3.98-.992 5.43-1.42 6.125-1.782.723-.376 1.762-.87 2.375-1.53 1.963-.013 3.794-.292 5.219-.845 2.951-1.144 4.873-1.869 6.688-2.75 1.455-.706 2.319-1.702 2.53-2 .213-.298.1-.728.126-.75.043-.035.34-.094.5-.437.859-1.847 2.323-5.628 2.437-6.313.114-.682.168-1.352.219-1.75.029-.23-.147-.879-.125-.937.031-.082.288-.25.344-.5.266-1.198.089-2.208-.125-3.625-.214-1.418-.972-4.615-1.625-5.469-.42-.548-.8-.792-1.157-.906-.067-.017-.123-.047-.187-.063-.021-.004-.042.003-.062 0-.312-.075-.609-.158-1.156-.218-.986-.109-2.425-.26-3.969-.25-.515.003-1.037.047-1.563.093-3.558.313-9.01.991-10.218
-1.625-1.634-.334-3.949-.612-5.938-.468-3.064.22-4.968.342-6.906.468-1.939.127-1.686.389-2.906.469-1.32.087-1.787-.223-5.563.094-3.546.297-8.98.993-10.22 1.625-1.632-.335-3.945-.613-5.937-.469-3.064.221-4.967.373-6.906.5-.659.043-1.042.124-1.344.187z" enable-background="new" fill="#bcb786" fill-rule="evenodd" opacity=".824"/>
-  </clipPath>
-  <filter id="fw" x="-.082" y="-.227" width="1.163" height="1.453">
-   <feGaussianBlur stdDeviation="2.437"/>
-  </filter>
-  <filter id="fv" x="-.041" y="-.113" width="1.082" height="1.227">
-   <feGaussianBlur stdDeviation="1.219"/>
-  </filter>
-  <clipPath id="y">
-   <path d="M352.25 211.99c-3.804-25.264-16.81-50.638-17.157-75.525-.186-13.356 3.273-26.571 13.756-39.554 36.347-65.296 116.94-84.695 185.93-91.465 86.922-11.017 184.91 17.94 233.37 95.401 54.124 75.733 56.675 172.54 80.612 259.53 29.438 127.13 54.779 256.21 60.392 386.85-3.063 78.182-8.426 165.18-60.503 228.13-48.027 50.357-122.79 50.053-187.07 59.002-90.555 4.655-184.35-16.146-261.78-64.198-64.776-37.94-95.73-113.48-97.279-186.02-8.39-79.875 26.392-153.81 51.62-227.16 7.47-82.761 9.413-166.25 9.653-249.38-.837-32.195-7.09-63.817-11.546-95.609z" enable-background="accumulate" fill="#262f2f" fill-rule="evenodd" stroke="#000"/>
-  </clipPath>
-  <filter id="fu" x="-.252" y="-.053" width="1.503" height="1.106">
-   <feGaussianBlur stdDeviation="13.025"/>
-  </filter>
-  <clipPath id="fs">
-   <path d="M734.03 519.49s16.755 37.018 28.701 53.954 52.727 56.046 52.727 56.046l.597-138.59" enable-background="accumulate" fill="#1a1a1a" fill-rule="evenodd" stroke="#000"/>
-  </clipPath>
-  <filter id="fr" x="-.274" y="-.213" width="1.549" height="1.427">
-   <feGaussianBlur stdDeviation="11.314"/>
-  </filter>
-  <clipPath id="fq">
-   <path d="M178.21 274.15c-3.804-25.264-16.81-50.638-17.157-75.525-.186-13.356 3.273-26.571 13.756-39.554 36.347-65.296 116.94-84.695 185.93-91.465 86.922-11.017 184.91 17.94 233.37 95.401 54.124 75.733 56.675 172.54 80.612 259.53 29.438 127.13 54.779 256.21 60.392 386.85-3.063 78.182-8.426 165.18-60.503 228.13-48.027 50.357-122.79 50.053-187.07 59.002-90.555 4.655-184.35-16.146-261.78-64.198-64.776-37.94-95.73-113.48-97.279-186.02-8.39-79.875 26.392-153.81 51.62-227.16 7.47-82.761 9.413-166.25 9.653-249.38-.837-32.195-7.09-63.817-11.546-95.609z" enable-background="accumulate" fill="#262f2f" fill-rule="evenodd"/>
-  </clipPath>
-  <filter id="aq">
-   <feGaussianBlur stdDeviation="2.04"/>
-  </filter>
-  <filter id="g">
-   <feTurbulence baseFrequency=".24" numOctaves="10" result="result0" seed="655" type="fractalNoise"/>
-   <feDisplacementMap in="SourceGraphic" in2="result0" scale="62" xChannelSelector="B" yChannelSelector="G"/>
-  </filter>
-  <clipPath id="fp">
-   <path d="M352.25 211.99c-3.804-25.264-16.81-50.638-17.157-75.525-.186-13.356 3.273-26.571 13.756-39.554 36.347-65.296 116.94-84.695 185.93-91.465 86.922-11.017 184.91 17.94 233.37 95.401 54.124 75.733 56.675 172.54 80.612 259.53 29.438 127.13 54.779 256.21 60.392 386.85-3.063 78.182-8.426 165.18-60.503 228.13-48.027 50.357-122.79 50.053-187.07 59.002-90.555 4.655-184.35-16.146-261.78-64.198-64.776-37.94-95.73-113.48-97.279-186.02-8.39-79.875 26.392-153.81 51.62-227.16 7.47-82.761 9.413-166.25 9.653-249.38-.837-32.195-7.09-63.817-11.546-95.609z" enable-background="accumulate" fill="#262f2f" fill-rule="evenodd" stroke="#000"/>
-  </clipPath>
-  <filter id="fo" x="-.353" y="-.182" width="1.706" height="1.363">
-   <feGaussianBlur stdDeviation="48.038"/>
-  </filter>
-  <clipPath id="fn">
-   <path d="m265.94 126.68l-18.767 168.86 174.11-73.121 61.954 88.659 57.884-31.99-37.534-180.06-237.64 27.649z" fill-rule="evenodd" stroke="#000" stroke-width=".9"/>
-  </clipPath>
-  <filter id="fm" x="-.277" y="-.325" width="1.554" height="1.65">
-   <feGaussianBlur stdDeviation="19.956"/>
-  </filter>
-  <mask id="fk" maskUnits="userSpaceOnUse">
-   <ellipse transform="translate(-174.03 62.156)" cx="579.47" cy="260.58" rx="192.69" ry="164.05" enable-background="accumulate" fill="url(#dt)"/>
-  </mask>
-  <filter id="fj" x="-.611" y="-.149" width="2.223" height="1.299">
-   <feGaussianBlur stdDeviation="37.83"/>
-  </filter>
-  <filter id="fi" x="-.259" y="-.224" width="1.518" height="1.447">
-   <feGaussianBlur stdDeviation="19.632"/>
-  </filter>
-  <filter id="fh" x="-.3" y="-.3" width="1.6" height="1.6">
-   <feGaussianBlur stdDeviation="2"/>
-  </filter>
-  <clipPath id="x">
-   <path d="M179.64 267.36c-22.41 39.703-60.616 115.78-69.286 149.64-8.647 33.775-8.772 66.417-.357 86.429 8.36 19.882 26.164 35.633 40.714 41.429-.597-14.376 14.373-43.286 72.857-72.5 58.626-29.285 78.382-27.131 103.57-47.143 25.63-20.362 12.61-67.045 3.214-93.929-9.434-26.993-34.967-59.124-66.429-69.643-31.033-10.375-65.018-4.848-84.286 5.714z" fill="#f5ff04" fill-rule="evenodd"/>
-  </clipPath>
-  <filter id="hd">
-   <feGaussianBlur stdDeviation="6.589"/>
-  </filter>
-  <filter id="hc">
-   <feGaussianBlur stdDeviation="1.505"/>
-  </filter>
-  <filter id="hb" x="-.243" y="-.391" width="1.487" height="1.782">
-   <feGaussianBlur stdDeviation="14.59"/>
-  </filter>
-  <filter id="ha" x="-.146" y="-.235" width="1.292" height="1.47">
-   <feGaussianBlur stdDeviation="4.444"/>
-  </filter>
-  <filter id="gz">
-   <feGaussianBlur stdDeviation=".606"/>
-  </filter>
-  <clipPath id="if">
-   <path d="m709.29 844.51c54.286-1.429 126.04-15.052 170-26.786 44.053-11.757 125.89-36.347 175.36-57.857 49.339-21.453 113.6-59.282 154.29-92.143 40.508-32.721 52.39-55.82 60.714-33.571 8.37 22.368-16.407 56.326-37.857 81.071-21.604 24.923-52.731 52.705-98.929 89.286s-156.08 101.58-212.86 128.57c-57.066 27.125-128.2 58.238-172.14 72.5s-131.43 31.071-131.43 31.071l92.857-192.14z" enable-background="accumulate" fill="#121212" fill-rule="evenodd"/>
-  </clipPath>
-  <mask id="gy" maskUnits="userSpaceOnUse">
-   <path d="m718.41-224.31l33.25 56 276-24 159.5-48.25-66.5-82.75-402.25 99z" fill="url(#w)" fill-rule="evenodd"/>
-  </mask>
-  <clipPath id="gx">
-   <path transform="translate(.08 -.031)" d="M1111.4-285.94l-3.937 1.875c-.041.01-.1.02-.125.031-.42.213-.165.1-.657.313-.486.21-1.737.584-4.093 1.469-3.332 1.25-5.805 2.15-7 3.062-1.537.021-3.72.233-5.657.719a227.677 227.677 0 0 1-6.75 1.594c-1.895.42-1.675.642-2.875.875-1.296.251-1.721-.01-5.437.78-3.49.743-8.895 1.932-10.156 2.688-1.584-.18-3.868-.321-5.844-.03-3.04.446-4.916.672-6.844.905-.655.08-1.04.201-1.344.282-.426.131-.685.26-1.375.343-1.311.16-1.762-.156-5.53.282-3.555.413-9.006 1.272-10.25 1.937-1.6-.297-3.859-.534-5.845-.344-3.058.294-4.972.484-6.906.657-1.934.172-1.688.422-2.906.53-1.316.119-1.76-.163-5.531.25-3.542.39-9.008 1.21-10.281 1.876-1.6-.295-3.887-.507-5.875-.313-3.059.3-4.941.48-6.875.657-.658.06-1.04.178-1.344.25-.428.119-.683.218-1.375.28-1.316.121-1.76-.194-5.531.22-3.556.39-9.006 1.239-10.25
-1.906-1.599-.294-3.86-.524-5.844-.313-3.056.326-4.974.527-6.906.719s-1.69.44-2.906.563c-1.315.131-1.763-.165-5.532.28-3.539.42-8.977 1.293-10.25 1.97-1.597-.281-3.86-.42-5.843-.188-3.052.358-4.945.568-6.875.781-.657.073-1.041.173-1.344.25-.427.128-.685.268-1.375.344-1.314.146-1.768-.174-5.531.313-3.55.458-8.979 1.419-10.22 2.125-1.593-.245-3.833-.382-5.812-.125-3.048.394-4.95.648-6.875.906-1.924.258-1.726.493-2.937.656-1.31.176-1.748-.104-5.5.469-3.525.538-8.924 1.699-10.188 2.437-1.588-.203-3.846-.254-5.813.094-3.026.536-4.899.862-6.812 1.188-.651.11-1.014.27-1.313.375-.42.164-.663.33-1.344.468-1.294.262-1.727-.006-5.437.813-3.499.772-8.846 2.383-10.062 3.219-1.563-.078-3.758.085-5.688.593-2.972.783-4.817 1.232-6.687 1.75s-1.667.768-2.844 1.094c-1.273.353-1.697.107-5.344 1.188-3.425 1.014-8.65 2.933-9.875 3.843-1.539.013-3.72.273-5.625.875-2.93.928-4.75 1.459-6.594
-2.063-.626.205-.991.393-1.28.531-.408.214-.654.409-1.313.625-1.255.412-1.687.19-5.282 1.438-3.39 1.177-8.595 3.213-9.78 4.156-1.525.06-3.65.395-5.532 1.062-2.897 1.029-4.699 1.676-6.531 2.313-1.832.637-1.628.848-2.781 1.25-1.247.434-1.664.2-5.22 1.562-3.338 1.28-8.486 3.483-9.687 4.47-1.507.107-3.635.498-5.5 1.218a1047.26 1047.26 0 0 1-6.437 2.469c-.617.233-.997.442-1.281.594v.03l-8 3.188 1.812 14.72c-.258-.062 6.188 3.312 6.188 3.312.226-.145.449-.273.718-.375 1.08-.41 2.172-.216 6-1.688 3.829-1.471 5.224-2.005 5.907-2.406.68-.4 1.611-.88 2.218-1.531 1.827-.138 3.571-.493 4.938-1 2.968-1.1 4.875-1.806 6.781-2.469 1.906-.662 2.354-1.415 3.406-1.781 1.092-.38 2.195-.166 6.063-1.531 3.867-1.366 5.283-1.827 5.969-2.22.7-.4 1.7-.932 2.312-1.593 1.97-.055 3.817-.385 5.281-.875 3.002-1.005 4.927-1.622 6.844-2.25 1.539-.504 2.174-1.047 2.906-1.437.23-.135.476-.254.75-.344 1.099-.36 2.182-.082
-6.094-1.313 3.912-1.23 5.366-1.673 6.063-2.03.694-.358 1.63-.794 2.25-1.407 1.865-.023 3.635-.267 5.03-.688 3.031-.913 4.993-1.43 6.938-1.968 1.945-.539 2.427-1.265 3.5-1.563 1.114-.31 2.22.007 6.188-1.031 3.967-1.039 5.417-1.433 6.125-1.75.735-.33 1.814-.754 2.437-1.375 1.998.116 3.858-.02 5.344-.375 3.078-.735 5.084-1.101 7.063-1.5 1.588-.32 2.244-.79 3-1.094a3.4 3.4 0 0 1 .75-.25c1.133-.23 2.304.209 6.343-.5 4.04-.709 5.5-.927 6.22-1.187.715-.26 1.704-.568 2.343-1.094 1.924.24 3.748.224 5.188 0 3.126-.488 5.154-.7 7.156-.969 2.001-.268 2.489-.945 3.594-1.094 1.146-.154 2.275.302 6.343-.219 4.068-.52 5.56-.695 6.282-.937.737-.247 1.798-.586 2.437-1.125 2.05.336 3.974.398 5.5.219 3.142-.37 5.18-.56 7.188-.782 1.61-.178 2.264-.608 3.03-.843.242-.086.495-.156.782-.188 1.15-.127 2.301.347 6.375-.125s5.559-.61 6.281-.844c.72-.232 1.7-.473 2.344-.968 1.936.333 3.77.404 5.219.25 3.146-.335
-5.177-.519 7.187-.719 2.01-.2 2.484-.826 3.594-.938 1.151-.115 2.297.366 6.375-.062s5.589-.562 6.313-.781c.739-.224 1.795-.514 2.437-1.031 2.057.398 4.002.493 5.531.343 3.149-.308 5.176-.473 7.188-.656 1.614-.147 2.263-.56 3.031-.781.241-.081.494-.13.781-.156 1.152-.106 2.293.392 6.375 0s5.59-.531 6.313-.75c.72-.219 1.7-.448 2.343-.938 1.939.35 3.77.454 5.22.313 3.148-.309 5.175-.474 7.187-.657 2.011-.183 2.514-.838 3.625-.937 1.152-.103 2.292.385 6.375 0s5.588-.501 6.312-.719c.74-.222 1.796-.514 2.438-1.031 2.057.402 4.003.503 5.531.344 3.147-.329 5.177-.523 7.187-.72 1.613-.156 2.266-.63 3.032-.874.24-.088.463-.122.75-.156 1.148-.14 2.316.34 6.375-.25 4.058-.59 5.562-.778 6.281-1.032.717-.253 1.675-.558 2.312-1.093 1.92.212 3.72.151 5.157-.094 3.119-.533 5.111-.929 7.093-1.313 1.983-.383 2.475-1.04 3.563-1.28 1.129-.251 2.27.115 6.25-.876s5.43-1.42 6.125-1.781c.722-.376 1.762-.87
-2.375-1.531 1.963-.012 3.794-.291 5.219-.844 2.95-1.145 4.873-1.87 6.687-2.75 1.456-.706 2.32-1.702 2.531-2 .213-.298.1-.729.125-.75.043-.035.34-.094.5-.437.86-1.848 2.324-5.628 2.438-6.313.114-.682.168-1.353.219-1.75.029-.23-.147-.879-.125-.937.03-.082.288-.251.343-.5.267-1.199.09-2.208-.125-3.625-.213-1.418-.971-4.615-1.625-5.47-.658-.861-1.224-1.01-1.75-1z" enable-background="new" fill="#bcb786" fill-rule="evenodd"/>
-  </clipPath>
-  <filter id="gw">
-   <feGaussianBlur stdDeviation="1.168"/>
-  </filter>
-  <filter id="gv" x="-.103" y="-.342" width="1.206" height="1.685">
-   <feGaussianBlur stdDeviation="1.168"/>
-  </filter>
-  <filter id="gu" x="-.099" y="-.226" width="1.198" height="1.453">
-   <feGaussianBlur stdDeviation="1.168"/>
-  </filter>
-  <filter id="gt" x="-.098" y="-.198" width="1.196" height="1.397">
-   <feGaussianBlur stdDeviation="1.168"/>
-  </filter>
-  <filter id="gs">
-   <feGaussianBlur stdDeviation="1.168"/>
-  </filter>
-  <filter id="gr" x="-.098" y="-.198" width="1.197" height="1.395">
-   <feGaussianBlur stdDeviation="1.168"/>
-  </filter>
-  <filter id="gq" x="-.098" y="-.198" width="1.196" height="1.397">
-   <feGaussianBlur stdDeviation="1.168"/>
-  </filter>
-  <filter id="gp" x="-.098" y="-.203" width="1.197" height="1.406">
-   <feGaussianBlur stdDeviation="1.168"/>
-  </filter>
-  <filter id="go" x="-.098" y="-.209" width="1.197" height="1.417">
-   <feGaussianBlur stdDeviation="1.168"/>
-  </filter>
-  <filter id="gn" x="-.099" y="-.225" width="1.198" height="1.451">
-   <feGaussianBlur stdDeviation="1.168"/>
-  </filter>
-  <filter id="gm" x="-.101" y="-.274" width="1.201" height="1.548">
-   <feGaussianBlur stdDeviation="1.168"/>
-  </filter>
-  <filter id="gl" x="-.102" y="-.324" width="1.204" height="1.647">
-   <feGaussianBlur stdDeviation="1.168"/>
-  </filter>
-  <filter id="gk" x="-.103" y="-.364" width="1.207" height="1.729">
-   <feGaussianBlur stdDeviation="1.168"/>
-  </filter>
-  <filter id="gj" x="-.105" y="-.405" width="1.209" height="1.809">
-   <feGaussianBlur stdDeviation="1.168"/>
-  </filter>
-  <filter id="gi">
-   <feGaussianBlur stdDeviation="1.723"/>
-  </filter>
-  <filter id="gh">
-   <feGaussianBlur stdDeviation=".35"/>
-  </filter>
-  <filter id="gg" x="-.031" y="-.103" width="1.062" height="1.205">
-   <feGaussianBlur stdDeviation=".35"/>
-  </filter>
-  <filter id="gf">
-   <feGaussianBlur stdDeviation=".35"/>
-  </filter>
-  <filter id="ge">
-   <feGaussianBlur stdDeviation=".35"/>
-  </filter>
-  <filter id="ff">
-   <feGaussianBlur stdDeviation=".35"/>
-  </filter>
-  <filter id="fe">
-   <feGaussianBlur stdDeviation=".35"/>
-  </filter>
-  <filter id="fd">
-   <feGaussianBlur stdDeviation=".35"/>
-  </filter>
-  <filter id="fc">
-   <feGaussianBlur stdDeviation=".35"/>
-  </filter>
-  <filter id="fb">
-   <feGaussianBlur stdDeviation=".35"/>
-  </filter>
-  <filter id="fa">
-   <feGaussianBlur stdDeviation=".35"/>
-  </filter>
-  <filter id="ez">
-   <feGaussianBlur stdDeviation=".35"/>
-  </filter>
-  <filter id="ey">
-   <feGaussianBlur stdDeviation=".35"/>
-  </filter>
-  <filter id="ex" x="-.031" y="-.109" width="1.062" height="1.219">
-   <feGaussianBlur stdDeviation=".35"/>
-  </filter>
-  <filter id="ew" x="-.031" y="-.121" width="1.063" height="1.243">
-   <feGaussianBlur stdDeviation=".35"/>
-  </filter>
-  <clipPath id="ie">
-   <path d="m266.27 924.57c-1.407 18.801-1.145 32.751 2.082 49.303 3.226 16.552 16.406 45.907 20.334 63.184 3.926 17.267 2.694 38.31-12.46 51.148-15.317 12.978-42.05 21.599-67.831 15.734s-69.55-49.223-88.59-70.228c-19.112-21.083-63.761-93.851-77.94-124.28-14.177-30.425-12.66-36.719-8.119-45.53-9.367-24.52-12.414-50.067-33.712-75.577 30.325 3.114 43.88 26.956 60.126 47.14-5.53-48.076-18.055-64.417-28.374-90.724 29.994 6.082 50.579 31.872 63.98 72.712 9.554-3.918 18.238-9.373 30.187-9.061-11.298-41.696-17.949-69.916-36.687-101.07 53.442 5.67 83.657 80.639 78.971 87.96 9.978-2.243 19.006-6.53 30.437-5.65-11.249-38.348-21.048-76.869-3.66-118.65 0 0 48.287 65.436 54.39 85.805 6.103 20.37 1.52 38.701 1.52 38.701s16.96 31.085 20.293 51.094c3.373 20.241-3.533 59.103-4.946 77.983z" enable-background="new" fill="#ada469" fill-rule="evenodd"/>
-  </clipPath>
-  <filter id="id">
-   <feGaussianBlur stdDeviation="7.18"/>
-  </filter>
-  <clipPath id="ic">
-   <path d="m266.27 924.57c-1.407 18.801-1.145 32.751 2.082 49.303 3.226 16.552 16.406 45.907 20.334 63.184 3.926 17.267 2.694 38.31-12.46 51.148-15.317 12.978-42.05 21.599-67.831 15.734s-69.55-49.223-88.59-70.228c-19.112-21.083-63.761-93.851-77.94-124.28-14.177-30.425-12.66-36.719-8.119-45.53-9.367-24.52-12.414-50.067-33.712-75.577 30.325 3.114 43.88 26.956 60.126 47.14-5.53-48.076-18.055-64.417-28.374-90.724 29.994 6.082 50.579 31.872 63.98 72.712 9.554-3.918 18.238-9.373 30.187-9.061-11.298-41.696-17.949-69.916-36.687-101.07 53.442 5.67 83.657 80.639 78.971 87.96 9.978-2.243 19.006-6.53 30.437-5.65-11.249-38.348-21.048-76.869-3.66-118.65 0 0 48.287 65.436 54.39 85.805 6.103 20.37 1.52 38.701 1.52 38.701s16.96 31.085 20.293 51.094c3.373 20.241-3.533 59.103-4.946 77.983z" enable-background="new" fill="#ada469" fill-rule="evenodd"/>
-  </clipPath>
-  <filter id="gd">
-   <feGaussianBlur stdDeviation="6.82"/>
-  </filter>
-  <clipPath id="ev">
-   <path d="M760.16 935.83c6.794 18.903 10.494 33.3 11.89 51.212 1.397 17.912-3.783 51.801-2.9 70.656.881 18.845 8.133 40.099 27.345 48.969 19.419 8.966 49.319 10.211 74.12-3.146 24.8-13.357 57.4-70.326 70.974-97.309 13.624-27.084 38.76-114.5 44.66-149.77 5.9-35.27 2.551-41.3-4.617-49.055 2.64-27.84-1.5-54.935 13.11-87.186-30.249 11.826-37.382 40.161-48.319 65.505-8-50.933.21-71.273 3.319-101.22-29.065 14.778-42.862 47.114-45 92.857-10.924-1.304-21.391-4.434-33.571-.714-.264-46.023-1.464-76.889 8.91-114.21-53.254 21.027-62.946 106.59-56.052 112.78-10.883.535-21.371-1.297-32.857 2.857.638-42.57-.261-84.909-30-122.86 0 0-30.958 80.922-31.43 103.57s9.452 40.166 9.452 40.166-8.568 36.741-6.298 58.232c2.295 21.741 20.443 59.676 27.265 78.658z" enable-background="new" fill="#ada469" fill-rule="evenodd"/>
-  </clipPath>
-  <filter id="eu" x="-.144" y="-.103" width="1.288" height="1.206">
-   <feGaussianBlur stdDeviation="7.389"/>
-  </filter>
-  <clipPath id="et">
-   <path d="M760.16 935.83c6.794 18.903 10.494 33.3 11.89 51.212 1.397 17.912-3.783 51.801-2.9 70.656.881 18.845 8.133 40.099 27.345 48.969 19.419 8.966 49.319 10.211 74.12-3.146 24.8-13.357 57.4-70.326 70.974-97.309 13.624-27.084 38.76-114.5 44.66-149.77 5.9-35.27 2.551-41.3-4.617-49.055 2.64-27.84-1.5-54.935 13.11-87.186-30.249 11.826-37.382 40.161-48.319 65.505-8-50.933.21-71.273 3.319-101.22-29.065 14.778-42.862 47.114-45 92.857-10.924-1.304-21.391-4.434-33.571-.714-.264-46.023-1.464-76.889 8.91-114.21-53.254 21.027-62.946 106.59-56.052 112.78-10.883.535-21.371-1.297-32.857 2.857.638-42.57-.261-84.909-30-122.86 0 0-30.958 80.922-31.43 103.57s9.452 40.166 9.452 40.166-8.568 36.741-6.298 58.232c2.295 21.741 20.443 59.676 27.265 78.658z" enable-background="new" fill="#ada469" fill-rule="evenodd"/>
-  </clipPath>
-  <filter id="es" x="-.09" y="-.103" width="1.181" height="1.205">
-   <feGaussianBlur stdDeviation="5.346"/>
-  </filter>
-  <marker id="eq" overflow="visible" orient="auto">
-   <path d="m-1.2 0l-1 1 3.5-1-3.5-1 1 1z" fill="#f8d615" fill-rule="evenodd" stroke="#f8d615" stroke-width=".2pt"/>
-  </marker>
-  <radialGradient id="r" cx="142.96" cy="107.09" r="66.982" gradientTransform="matrix(-.33248 .90223 -.95824 -.35312 305.29 19.909)" gradientUnits="userSpaceOnUse">
-   <stop stop-color="#1e2323" offset="0"/>
-   <stop stop-color="#181d1d" offset=".56"/>
-   <stop offset="1"/>
-  </radialGradient>
-  <radialGradient id="q" cx="317.79" cy="129.65" r="47.863" gradientTransform="matrix(1.0036 0 0 1.6613 -160.53 -96.205)" gradientUnits="userSpaceOnUse" xlink:href="#u"/>
-  <radialGradient id="p" cx="325.31" cy="80.91" r="26.938" gradientTransform="matrix(2.0748 -.1578 .23824 3.1325 -550.77 -65.729)" gradientUnits="userSpaceOnUse">
-   <stop stop-color="#283131" stop-opacity="0" offset="0"/>
-   <stop stop-color="#1e2424" stop-opacity="0" offset=".513"/>
-   <stop offset="1"/>
-  </radialGradient>
-  <linearGradient id="kt" x1="347.9" x2="275.58" y1="1070.2" y2="867.98" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop offset=".022"/>
-   <stop offset=".759"/>
-   <stop stop-color="#232323" offset=".885"/>
-   <stop stop-color="#595959" offset="1"/>
-  </linearGradient>
-  <linearGradient id="kh" x1="603.84" x2="616.24" y1="627.85" y2="585.43" gradientTransform="translate(450.03 73.844)" gradientUnits="userSpaceOnUse" xlink:href="#t"/>
-  <linearGradient id="el" x1="609.31" x2="560.83" y1="239.47" y2="262.86" gradientTransform="translate(450.03 73.844)" gradientUnits="userSpaceOnUse">
-   <stop stop-color="#0a0c0c" offset="0"/>
-   <stop stop-color="#1f2727" stop-opacity="0" offset="1"/>
-  </linearGradient>
-  <radialGradient id="ek" cx="543.67" cy="147.31" r="47.863" gradientTransform="matrix(2.1382 0 0 2.3383 -77.038 -101.69)" gradientUnits="userSpaceOnUse" xlink:href="#u"/>
-  <radialGradient id="ef" cx="385" cy="237.01" r="86.929" gradientTransform="matrix(1 0 0 .8562 0 34.08)" gradientUnits="userSpaceOnUse">
-   <stop stop-color="#ada469" offset="0"/>
-   <stop stop-color="#ada469" offset=".811"/>
-   <stop stop-color="#fff" offset="1"/>
-  </radialGradient>
-  <linearGradient id="ee" x1="398.21" x2="379.29" y1="343.52" y2="265.31" gradientTransform="translate(450.03 73.844)" gradientUnits="userSpaceOnUse" xlink:href="#s"/>
-  <radialGradient id="ed" cx="397.16" cy="336.95" r="36.75" gradientTransform="translate(-375.32 -318.42) scale(1.945)" gradientUnits="userSpaceOnUse">
-   <stop stop-color="#344040" offset="0"/>
-   <stop stop-color="#222929" offset=".5"/>
-   <stop offset="1"/>
-  </radialGradient>
-  <radialGradient id="ec" cx="402.49" cy="317.24" r="23.714" gradientTransform="translate(-1358.3 -1070.7) scale(4.3777)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-color="#1d1d1d" offset="1"/>
-  </radialGradient>
-  <radialGradient id="eb" cx="250.23" cy="475.1" r="95.989" gradientTransform="matrix(1.2259 -.70777 .1414 .24491 322.22 608.92)" gradientUnits="userSpaceOnUse">
-   <stop stop-color="#d9e002" offset="0"/>
-   <stop stop-color="#a9ae01" offset=".5"/>
-   <stop stop-color="#717501" offset="1"/>
-  </radialGradient>
-  <radialGradient id="m" cx="228.81" cy="440.27" r="119.18" gradientTransform="matrix(1.1323 .76595 -1.455 2.151 588.75 -711.8)" gradientUnits="userSpaceOnUse">
-   <stop stop-color="#ff0" offset="0"/>
-   <stop stop-color="#b2b200" offset="1"/>
-  </radialGradient>
-  <radialGradient id="dz" cx="275.44" cy="335.35" r="36.75" gradientTransform="matrix(.05911 2.687 -.72343 .01591 408.73 -424.56)" gradientUnits="userSpaceOnUse">
-   <stop stop-color="#ff0" offset="0"/>
-   <stop stop-color="#ff0" stop-opacity="0" offset="1"/>
-  </radialGradient>
-  <linearGradient id="l" x1="182.35" x2="145.53" y1="256.11" y2="542.21" gradientUnits="userSpaceOnUse">
-   <stop stop-color="#7d7d00" offset="0"/>
-   <stop stop-color="#c6c700" offset=".364"/>
-   <stop stop-color="#f6f800" offset="1"/>
-  </linearGradient>
-  <radialGradient id="dy" cx="296.34" cy="427.18" r="19.704" gradientTransform="translate(-599.29 -827.09) scale(2.9797)" gradientUnits="userSpaceOnUse">
-   <stop stop-opacity="0" offset="0"/>
-   <stop offset="1"/>
-  </radialGradient>
-  <radialGradient id="dx" cx="429.57" cy="377.43" r="72.08" gradientTransform="matrix(1 0 0 .61803 0 144.16)" gradientUnits="userSpaceOnUse">
-   <stop stop-color="#e2e2e2" offset="0"/>
-   <stop stop-color="#e2e2e2" stop-opacity="0" offset="1"/>
-  </radialGradient>
-  <radialGradient id="dw" cx="437.7" cy="391.22" r="36.612" gradientTransform="matrix(1 0 0 .61803 0 149.43)" gradientUnits="userSpaceOnUse">
-   <stop stop-color="#c7bd80" offset="0"/>
-   <stop stop-color="#c7bd80" stop-opacity="0" offset="1"/>
-  </radialGradient>
-  <linearGradient id="dv" x1="412.09" x2="417.38" y1="404.92" y2="401.83" gradientUnits="userSpaceOnUse" xlink:href="#j"/>
-  <linearGradient id="du" x1="411.91" x2="417.38" y1="404.92" y2="401.83" gradientUnits="userSpaceOnUse" xlink:href="#j"/>
-  <linearGradient id="ej" x1="411.91" x2="417.38" y1="405.54" y2="401.83" gradientUnits="userSpaceOnUse" xlink:href="#j"/>
-  <linearGradient id="ei" x1="412.09" x2="417.38" y1="405.54" y2="401.83" gradientUnits="userSpaceOnUse" xlink:href="#j"/>
-  <linearGradient id="eh" x1="411.73" x2="417.38" y1="405.54" y2="401.83" gradientUnits="userSpaceOnUse" xlink:href="#j"/>
-  <linearGradient id="jr" x1="1255.7" x2="893.7" y1="667.09" y2="858.01" gradientUnits="userSpaceOnUse" xlink:href="#n"/>
-  <linearGradient id="ft" x1="603.84" x2="616.24" y1="627.85" y2="585.43" gradientTransform="matrix(1.0057 0 0 2.3995 3424.4 -24.137)" gradientUnits="userSpaceOnUse" xlink:href="#t"/>
-  <radialGradient id="fl" cx="418.3" cy="342.48" r="131.45" gradientTransform="matrix(1.3957 .62111 -.42441 .95372 -15.062 -227.97)" gradientUnits="userSpaceOnUse" xlink:href="#s"/>
-  <radialGradient id="fg" cx="275.44" cy="335.35" r="36.75" gradientTransform="matrix(.05911 2.687 -.72343 .01591 408.73 -424.56)" gradientUnits="userSpaceOnUse" xlink:href="#n"/>
-  <clipPath id="ga">
-   <path d="M3492.3 296.46H3930v902.66h-437.7z" fill="#fff"/>
-  </clipPath>
- </defs>
- <g stroke-miterlimit="1">
-  <path d="M10.45 109.38h1876.7v1563H10.45z" enable-background="new" fill="#a8a8a8" stroke="#000" stroke-width="20.9"/>
-  <path d="M2337.1 111.42h1878.8v1565H2337.1z" enable-background="new" fill="none" stroke="#000" stroke-width="20.925"/>
-  <path d="M2358.4 132.96h1833.4v1522.9H2358.4z" enable-background="new" fill="#a8a8a8" stroke="#f83615" stroke-width="20.391"/>
- </g>
- <g fill-rule="evenodd">
-  <path transform="translate(-2833.5 -4370) scale(10.727)" d="M304.64 526.65c-10 .357-18.214 2.857-18.214 2.857l7.5 6.071 10.357 3.572 16.071.357 22.5-5.357 7.857 1.071 20.357-2.143-10.357 6.786c5.46-1.023 17.393 3.57 9.643 5.357-1.74.402 13.929-4.643 13.929-4.643l2.5-4.642 3.571-9.286h11.43l18.213-4.643 3.572-5-16.071 1.071-12.143 2.143-14.643-5-70.692 16.708-5.38-5.279z" enable-background="new" filter="url(#ep)" opacity=".5"/>
-  <g enable-background="new">
-   <path transform="matrix(.71084 -.19374 .26296 .96481 552.25 332.01)" d="m245.12 100.05s-47.128-31.647-67.215-35.801c-20.038-4.144-38.473-3.318-51.934 13.607s-12.077 61.265-13.536 86.97 2.55 70.177 17.605 88.666c15.055 18.488 45.886 13.585 49.927 21.414 2.213 4.287 65.152-174.86 65.152-174.86z" enable-background="accumulate" fill="url(#r)"/>
-   <path transform="matrix(.71084 -.19374 .26296 .96481 552.25 332.01)" d="M135.38 82.018s26.344 1.939 37.633 13.903c11.415 12.097 13.735 21.332 15.296 37.735 1.563 16.425-.85 28.418-7.814 36.037s-1.004 19.583-25.916 12.071-27.032-27.783-26.515-46.305c.517-18.529 7.316-53.441 7.316-53.441z" enable-background="accumulate" fill="url(#q)"/>
-   <path transform="matrix(.71084 -.19374 .26296 .96481 552.25 332.01)" d="M135.65 81.927s-4.645 16.365.588 28.563c5.488 12.793 27.224 44.26 27.224 54.656l22.656-5c2.542-6.966 3.21-15.752 2.188-26.5-1.562-16.403-3.867-25.621-15.281-37.719-9.655-10.232-31.593-13.375-37.375-14z" enable-background="new" fill="url(#p)"/>
-  </g>
-  <path d="m893.6 1350.3c-4.286 0.714-27.628 3.618-57.857 10s-57.314 4.966-135.79 17.33c-79.852 12.581-94.064 42.542-108.12 47.064-14.7 4.729-145.38-65.822-145.38-65.822l4.286-94.286s85.886-16.201 112.14-33.571c26.257-17.37 45.582-49.666 59.286-71.429s32.857-71.429 32.857-71.429l238.57 262.14z" enable-background="accumulate" stroke="#000"/>
-  <path transform="translate(324.57 331.53)" d="m332.34 898.39l-32.732-61.3-37.617 45.106c2.177 1.317 5.774-20.856 45.6-64.417l24.749 80.61z" clip-path="url(#eo)" enable-background="accumulate" fill="#fff" filter="url(#kv)" opacity=".5"/>
-  <path transform="translate(324.57 331.53)" d="m200.82 863.03l146.37-51.619 243.95 226.27-241.83 140.01-181.02-87.681 32.527-226.98z" clip-path="url(#ku)" enable-background="accumulate" fill="url(#kt)" filter="url(#ks)"/>
-  <path d="m691.46 835.66s-29.554 40.573-47.857 74.286-58.621 126.36-70.357 171.07c-11.759 44.803-62.5 123.57-62.5 123.57l76.071 18.214s11.807-12.823 31.071-46.071 60.357-138.57 60.357-138.57l13.214-202.5z" enable-background="accumulate" fill="#0f0f0f"/>
-  <path transform="translate(324.57 331.53)" d="m430.28 381.94c-7.071 2.828-236.18 32.152-236.18 32.152l-39.64 359.83 90.198 92.64 52.326-114.55 100.47-186.39 32.828-183.68z" clip-path="url(#kr)" enable-background="accumulate" fill="#fff" filter="url(#kq)" opacity=".4"/>
-  <path d="m1018.2 1359.5s23.256 11.394 36.068 20.476c12.697 9.001 29.472 24.649 41.692 37.36 12.306 12.8 20.113 22.599 41.533 24.161 21.432 1.563 53.282-8.788 73.296-24.664 20.014-15.877 45.647-69.233 45.647-69.233l-127.16-143.07" enable-background="accumulate" stroke="#000"/>
-  <path transform="translate(324.57 331.53)" d="M331.34 641.5L216.17 835.36l44.042 90.598 97.581-193.75-26.456-90.711z" clip-path="url(#kp)" enable-background="accumulate" filter="url(#ko)" opacity=".75"/>
-  <g enable-background="new">
-   <path d="M1113.913 623.101l-.09-.002c-1.48.72-6.744.842-7.674 8.704-.872 7.373 12.962 18.694 14.976 19.936 1.626 1.001 3.407 1.81 5.174 2.325l1.403.382c1.883.43 3.679.575 5.134.496 3.16-.173 5.184-.339 7.197-.493 2.013-.155 2.577-.75 3.686-.866 1.15-.12 2.242.375 6.309-.155 4.066-.53 5.556-.79 6.288-1.07.76-.29 1.85-.663 2.534-1.25 1.952.213 3.803.145 5.281-.241 3.063-.8 5.055-1.3 6.958-1.968 1.527-.536 2.499-1.426 2.744-1.698.245-.271.181-.712.21-.73.046-.03.348-.055.546-.378 1.065-1.737 2.951-5.325 3.143-5.993.191-.664.322-1.324.417-1.713.056-.225-.045-.89-.017-.946.04-.078.315-.216.399-.457.402-1.16.34-2.183.29-3.616-.05-1.433-.438-4.695-.99-5.618-.353-.593-.703-.88-1.044-1.033-.065-.025-.118-.06-.18-.083-.02-.007-.042-.002-.061-.007-.301-.111-.586-.228-1.124-.35-.966-.22-2.379-.535-3.914-.702a19.278 19.278 0 0
-0-1.563-.085c-3.571-.097-9.064-.045-10.338.446-1.584-.518-3.852-1.06-5.845-1.144-3.069-.13-4.974-.228-6.914-.324-1.94-.095-1.72.194-2.941.134-1.32-.065-1.75-.426-5.537-.543-3.556-.11-9.035-.04-10.338.447-1.584-.52-3.85-1.06-5.845-1.144-3.07-.131-4.978-.197-6.918-.293-.66-.032-1.05.004-1.356.033z" enable-background="new" fill="#bcb786"/>
-   <g transform="rotate(2.568 -22364 20373)" clip-path="url(#kn)" enable-background="new" filter="url(#km)">
-    <path d="M229.94-409.12c-3.558.05-9.024.36-10.303.904-1.606-.447-3.903-.881-5.9-.877a979.03 979.03 0 0 1-6.907 0c-.66-.003-1.048.068-1.353.11v1.096c.12-.18.393-.69.95-.767.747-.103 5.17-.151 7.31-.11 1.775.035 4.455.274 6.39.96.32.113.618.273.891.41 1.964.987 7.944 4.302 7.944 4.302s-6.633-3.948-7.483-4.439c-.203-.117-.575-.258-1.036-.41 1.22-.449 5.076-.62 7.828-.713 3.024-.102 3.348-.09 5.41.192 2.13.29 3.34.602 3.34.602s-.08-.64 1.035-.794c.748-.103 5.17-.152 7.31-.11 2.07.04 5.366.407 7.282 1.37 1.003.504 3.035 1.569 4.795 2.536l.096-.02s-3.58-2.162-4.43-2.653c-.204-.117-.575-.258-1.037-.411 1.22-.448 5.047-.62 7.8-.712 3.024-.102 3.347-.09 5.41.191 1.954.267 3.013.53 3.195.576l-.027-.312a8.503 8.503 0 0 0-1.4-.357c-1.301-.235-3.4-.602-5.51-.564-3.571.064-9.052.356-10.302.904-1.606-.447-3.877-.881-5.871-.877-3.072.007-4.994.01-6.936
-0-1.943-.009-1.713.28-2.936.274-1.322-.005-1.766-.354-5.555-.301M206.2-407.48c1.92.817 4.577 2.193 6.159 3.397s2.908 1.774 5.555 3.918c.885.718 1.748 1.35 2.591 1.922l.541-.19a57.511 57.511 0 0 1-2.269-1.622c-2.822-2.12-3.627-2.81-6.015-4.274s-4.1-2.366-6.562-3.15" enable-background="new"/>
-    <path d="M237.8-407.48c1.92.817 4.606 2.193 6.188 3.397.813.62 1.558 1.07 2.45 1.654l.65-.116a40.414 40.414 0 0 0-2.697-1.784c-2.389-1.465-4.128-2.366-6.59-3.151" enable-background="new"/>
-   </g>
-   <g transform="rotate(6.561 -6814.9 734.73)" clip-path="url(#kl)">
-    <path d="M1056.2-278.8c4.145-1.479 10 3.125 10 3.125.899.28 2.725-.894 2.624-1.686 0 0-1.55-1.86-.374-2.939s5.296 1.507 7.5 1.625 5.562-.23 7-.75 1.113-1.425 2.625-1.75 5.119 1.038 7.06 1.169 4.649.334 5.815-.169.178-1.16 1.875-1.875 7.76-.957 9.625-.125 1.81.52 2.625 3 7.44 5.163-1.125 13.375-59.378 13.786-65.625 2.75 6.23-14.271 10.375-15.75z" enable-background="new" filter="url(#kk)" opacity=".75"/>
-    <path d="M1058.5-275.43c4.145-1.479 10 3.125 10 3.125.899.28 2.725-.894 2.624-1.686 0 0-1.55-1.86-.374-2.939s5.296 1.507 7.5 1.625 5.562-.23 7-.75 1.113-1.425 2.625-1.75 5.119 1.038 7.06 1.169 4.649.334 5.815-.169.178-1.16 1.875-1.875 7.76-.957 9.625-.125 1.81.52 2.625 3 7.44 5.163-1.125 13.375-59.378 13.786-65.625 2.75 6.23-14.271 10.375-15.75z" enable-background="new" filter="url(#kj)" opacity=".75"/>
-   </g>
-  </g>
-  <path d="M676.821 543.52c-3.804-25.264-16.81-50.638-17.157-75.525-.186-13.356 3.273-26.571 13.756-39.554 36.347-65.296 116.94-84.695 185.93-91.465 86.922-11.017 184.91 17.94 233.37 95.401 54.124 75.733 56.675 172.54 80.612 259.53 29.438 127.13 54.779 256.21 60.392 386.85-3.063 78.182-8.426 165.18-60.503 228.13-48.026 50.357-122.79 50.053-187.07 59.002-90.555 4.655-184.35-16.146-261.78-64.198-64.776-37.94-95.73-113.48-97.279-186.02-8.39-79.875 26.392-153.81 51.62-227.16 7.47-82.761 9.413-166.25 9.653-249.38-.837-32.195-7.09-63.817-11.546-95.609z" enable-background="accumulate" fill="#101414"/>
-  <path transform="translate(324.57 331.53)" d="M311.83 415.43l9.9 121.62-60.105 136.47 15.556 174.66c15.613 61.879 32.185 98.669 74.376 117.05 4.32-36.24-38.612-142.96-39.243-189.12-.631-46.184 10.83-108.61 30.678-158.3 20.048-50.192 36.897-44.846 42.125-92.593s-17.426-149.39-17.426-149.39l-55.86 39.598z" clip-path="url(#en)" enable-background="accumulate" fill="#fff" filter="url(#ki)" opacity=".25"/>
-  <path transform="translate(48.571 195.53)" d="m1010 655.49s16.755 37.018 28.702 53.954c11.946 16.936 52.727 56.046 52.727 56.046l52.597-127.59" enable-background="accumulate" fill="url(#kh)"/>
-  <path transform="translate(324.57 331.53)" d="m730.32 536.57c0 8.485 42.548 58.468 42.548 58.468l12.607-28.77-55.154-29.698z" clip-path="url(#kg)" enable-background="accumulate" fill="#fff" filter="url(#kf)" opacity=".08"/>
- </g>
- <g transform="translate(498.6 269.37)" clip-path="url(#ke)" enable-background="new">
-  <g transform="translate(-174.03 62.156)" filter="url(#em)">
-   <g filter="url(#i)">
-    <path d="M425.88 476.99c10.805-1.479 24.744 3.354 44.643 3.214s57.453-16.91 82.143-17.143 62.752 12.284 79.286 15 22.848-.158 27.5 7.857 1.927 10.747-10.357 20.714-40.79 12.636-66.071 12.857c-25.282.221-70.381 7.079-95.357 3.93s-56.938-7.824-68.929-17.858-19.851-16.732-17.5-23.929 13.837-3.164 24.643-4.643z" enable-background="new" fill="#fff" fill-rule="evenodd"/>
-    <path d="M343.65 412.6h381.84v181.02H343.65z" enable-background="accumulate" fill="none"/>
-   </g>
-   <g filter="url(#i)">
-    <path d="m861.17 390.2c-10.462 9.714-86.98 19.005-100.71 29.286s-14.753 12.888-12.143 20 6.545 9.406 25.714 8.571 98.571-27.622 98.571-21.429l-11.429-36.429z" enable-background="new" fill="#fff" fill-rule="evenodd"/>
-    <path d="M702.86 344.82h207.89v162.63H702.86z" enable-background="accumulate" fill="none"/>
-   </g>
-  </g>
-  <g enable-background="new" opacity=".18">
-   <g transform="translate(-174.03 62.156)" filter="url(#i)">
-    <path d="M425.88 476.99c10.805-1.479 24.744 3.354 44.643 3.214s57.453-16.91 82.143-17.143 62.752 12.284 79.286 15 22.848-.158 27.5 7.857 1.927 10.747-10.357 20.714-40.79 12.636-66.071 12.857c-25.282.221-70.381 7.079-95.357 3.93s-56.938-7.824-68.929-17.858-19.851-16.732-17.5-23.929 13.837-3.164 24.643-4.643z" enable-background="new" fill="#fff" fill-rule="evenodd"/>
-    <path d="M343.65 412.6h381.84v181.02H343.65z" enable-background="accumulate" fill="none"/>
-   </g>
-   <g transform="translate(-174.03 62.156)" filter="url(#i)">
-    <path d="m861.17 390.2c-10.462 9.714-86.98 19.005-100.71 29.286s-14.753 12.888-12.143 20 6.545 9.406 25.714 8.571 98.571-27.622 98.571-21.429l-11.429-36.429z" enable-background="new" fill="#fff" fill-rule="evenodd"/>
-    <path d="M702.86 344.82h207.89v162.63H702.86z" enable-background="accumulate" fill="none"/>
-   </g>
-  </g>
- </g>
- <g transform="translate(48.571 195.53)" fill-rule="evenodd">
-  <path transform="translate(276 136)" d="m582.66-7.418l113.14 86.267 108.89 258.8 38.184 207.89 120.21 91.924s-12.728-287.09-19.799-313.96-149.91-393.15-149.91-393.15l-210.72 62.225z" clip-path="url(#kd)" enable-background="accumulate" filter="url(#kc)" opacity=".75"/>
-  <path d="m964.14 239.6s8.677 10.897 24.107 11.964c15.43 1.068 49.722-39.953 70.179-52.143 20.479-12.204 47.046-26.602 63.929-20.357 16.882 6.245 22.158 26.436 27.857 48.036 5.7 21.6 6.719 61.814-2.679 92.857-9.397 31.043-50.502 73.104-65.356 103.39s-11.607 39.821-11.607 39.821" enable-background="accumulate" fill="url(#el)"/>
-  <path d="m1124.5 207.63c-15.893-0.893-49.719 12.106-66.071 24.286-16.439 12.244-29.221 24.114-29.286 52.143-0.065 28.206 13.119 39.076 29.107 46.964s33.686 7.12 51.964-11.786c18.278-18.905 14.286-111.61 14.286-111.61z" enable-background="new" fill="url(#ek)"/>
-  <ellipse transform="matrix(.94347 -.12399 .14401 1.0958 451.95 134.6)" cx="385" cy="237.01" rx="86.429" ry="73.929" clip-path="url(#kb)" enable-background="accumulate" fill="url(#ef)" filter="url(#je)" opacity=".75"/>
-  <path transform="translate(450.03 73.844)" d="m527.61 407.45s-122.04 38.403-187.51 9.632c-65.473-28.772-74.377-124.72-74.377-124.72s73.382-80.504 129.92-83.615c55.827-3.072 90.574 20.143 114.87 65.852 24.352 45.813 17.101 132.85 17.101 132.85z" enable-background="accumulate" fill="url(#jd)" mask="url(#jc)"/>
-  <path d="m772.17 393.35s36.218-27.382 51.607-35.893c15.177-8.393 25.714-11.607 35.893-11.607l-15.536 66.964" enable-background="accumulate" fill="url(#ee)"/>
-  <circle transform="translate(449.5 74.915)" cx="409.29" cy="306.65" r="36.25" enable-background="accumulate" fill="url(#ed)"/>
-  <path transform="translate(276 136)" d="m311.83 415.43l9.9 121.62-60.105 136.47 15.556 174.66c15.613 61.879 32.185 98.669 74.376 117.05 4.32-36.24 8.682-72.368-31.243-223.12l17.678-69.296 72.125-138.59-42.426-158.39-55.86 39.598z" clip-path="url(#en)" enable-background="accumulate" fill="#fff" filter="url(#jb)" opacity=".3"/>
-  <path d="m635.21 581.13c-14.142 12.728 39.233 34.58 76.368 24.042s104.64-35.564 103.24-79.196c-1.407-43.632-76.368-128.69-76.368-128.69l-103.24 183.85z" enable-background="accumulate" filter="url(#ja)" opacity=".5"/>
-  <circle transform="translate(449.67 74.915)" cx="410" cy="306.65" r="23.214" enable-background="accumulate" fill="url(#ec)"/>
-  <circle transform="translate(452 73.487)" cx="414.29" cy="303.08" r="7.5" enable-background="accumulate" fill="#fff" filter="url(#iz)" stroke="#000" stroke-linejoin="bevel"/>
-  <path d="m789.32 478.35s7.023 19.569-1.071 35-42.323 38.988-67.5 50c-25.31 11.07-85.473 32.964-101.79 41.964-16.461 9.082-18.214 12.679-18.214 12.679s-7.147-19.064 28.75-51.786c36.172-32.972 142.03-48.05 159.82-87.857z" enable-background="accumulate" fill="url(#eb)"/>
- </g>
- <g enable-background="new">
-  <g transform="translate(829.32 270.09)" fill-rule="evenodd">
-   <path transform="translate(-329.81)" d="M179.64 267.36c-22.41 39.703-60.616 115.78-69.286 149.64-8.647 33.775-8.772 66.417-.357 86.429 8.36 19.882 26.164 35.633 40.714 41.429-.597-14.376 14.373-43.286 72.857-72.5 58.626-29.285 78.382-27.131 103.57-47.143 25.63-20.362 8.206-79.647 3.214-93.929s-1.236-3.38-1.946-5.093c-10.689-25.816-34.214-54.43-64.483-64.55s-65.018-4.848-84.286 5.714z" clip-path="url(#ea)" fill="url(#m)"/>
-   <ellipse transform="rotate(28.068 -88.085 -332.1)" cx="183.57" cy="338.08" rx="64.716" ry="134.01" enable-background="accumulate" fill="url(#dz)"/>
-   <ellipse transform="rotate(28.068 -43.578 -333.81)" cx="183.57" cy="338.08" rx="64.716" ry="134.01" enable-background="accumulate" fill="url(#iy)"/>
-  </g>
-  <path transform="translate(499.51 270.09)" d="M179.64 267.36c-22.41 39.703-60.616 115.78-69.286 149.64-8.647 33.775-8.772 66.417-.357 86.429 8.36 19.882 26.164 35.633 40.714 41.429-.597-14.376 14.373-43.286 72.857-72.5 58.626-29.285 78.382-27.131 103.57-47.143 25.63-20.362 8.206-79.647 3.214-93.929s-1.236-3.38-1.946-5.093c-10.689-25.816-34.214-54.43-64.483-64.55s-65.018-4.848-84.286 5.714z" clip-path="url(#ea)" enable-background="new" fill="none" filter="url(#ix)" stroke="url(#l)" stroke-width="20.8"/>
- </g>
- <g transform="translate(48.571 195.53)" fill-rule="evenodd">
-  <circle transform="translate(452.56 72.581)" cx="310.71" cy="398.08" r="19.704" enable-background="accumulate" stroke="#000" stroke-linejoin="bevel"/>
-  <circle transform="translate(450.56 72.581)" cx="310.71" cy="398.08" r="19.704" enable-background="accumulate" fill="url(#m)" filter="url(#iw)" stroke="url(#l)" stroke-width="20.8"/>
-  <circle transform="translate(450.56 72.581)" cx="310.71" cy="398.08" r="19.704" enable-background="accumulate" fill="url(#dy)"/>
-  <ellipse transform="rotate(-4.471 1823.1 -5529.2)" cx="429.57" cy="377.43" rx="72.08" ry="44.548" enable-background="accumulate" fill="url(#dx)" filter="url(#iv)"/>
-  <ellipse transform="matrix(1.4358 -.07 .07 1.4358 235.18 -63.865)" cx="437.7" cy="391.22" rx="36.612" ry="22.627" enable-background="accumulate" fill="url(#dw)" filter="url(#iu)"/>
-  <g transform="translate(450.03 73.844)" enable-background="new" filter="url(#it)">
-   <circle cx="413.66" cy="401.83" r="3.214" enable-background="accumulate" stroke="url(#dv)"/>
-   <circle transform="translate(13.125 8.125)" cx="413.66" cy="401.83" r="3.214" enable-background="accumulate" stroke="url(#du)"/>
-   <circle transform="translate(32.946 7.5)" cx="413.66" cy="401.83" r="3.214" enable-background="accumulate" stroke="url(#ej)"/>
-   <circle transform="translate(24.911 -10.268)" cx="413.66" cy="401.83" r="3.214" enable-background="accumulate" stroke="url(#ei)"/>
-   <circle transform="translate(47.589 -.625)" cx="413.66" cy="401.83" r="3.214" enable-background="accumulate" stroke="url(#eh)"/>
-  </g>
- </g>
- <g fill="none" stroke="#000">
-  <path d="M944.771 678.46c.985 4.35 4.537 6.18 7.387 7.892 4.46 2.513 6.52 1.522 9.154-.758 1.602-1.921 10.683-4.698 15.594-7.07 4.33-1.46 8.904-5.36 13.385-8.335 3.395-1.627 5.347.355 7.829 1.01 2.944.717 4.411 2.172 6.06 3.536 2.397 1.175-.927 3.143 3.284 4.293 1.19.218 2.417.577 3.283-.505" enable-background="new"/>
-  <path d="M959.421 670.88c2.315-.032 3.178.643 5.493-.82 3.455-3.082 5.402-3.146 7.955-4.42 3.026-1.315 6.535 8.152 10.102 9.849 2.395-.822 1.289 1.794 1.452 2.651.057 2.647 2.807 3.679 4.356 5.43 3.316 2.256 7.375 6.296 11.112 5.303 6.445-2.93 10.28-1.281 16.29-7.386.703-1.182-.585-6.895 3.093-7.198 2.524.254 4.166.05 6.06.569 5.442 2.117 7.738 6.45 14.71 7.955 6.184.966 7.613 3.794 13.89 5.05M925.551 679.05c2.399-.794 6.106 4.192 8.173 7.046.593 2.68 1.154 5.486.758 12.122.785 2.417 2.68 3.03 4.798 3.283 3.117-.537 5.877-1.325 7.324-3.03 1.871-1.943 5.312 2.393 8.08 4.04 3.61 1.912 7.775 1.979 11.87 2.273 1.703-.231 2.37 4.515 3.283 8.08.384 4.379-.886 6.896-1.768 9.85-.294 2.496 2.988 3.53 6.313 4.545 3.183.742 6.545 1.662 9.092 1.768 5.142.875 8.088 2.69 12.122 4.04 2.239.817 3.26 2.243 4.545 3.536" enable-background="new"/>
- </g>
- <g fill-rule="evenodd">
-  <path transform="translate(324.57 331.53)" d="m332 187.7s57.5-25.5 57.5-28 5.5-52 5.5-52 91-48.5 91.5-50.5 86-62 86-62l-186 22-75.5 106z" clip-path="url(#jz)" enable-background="new" fill="#fff" filter="url(#jy)" opacity=".25"/>
-  <path d="m1745.9 918.08s-115.97 73.539-123.04 77.782c-7.071 4.243-230.52 137.18-230.52 137.18l4.243 39.598 216.37-100.41 117.38-101.82 15.556-52.326z" enable-background="accumulate" fill="#fff" opacity=".25"/>
-  <path transform="translate(324.57 331.53)" d="m528.92 556.85c-5.657-1.414-181.02 74.953-181.02 74.953l-33.941 181.02 51.095 193.95 257.2 67.681s206.48 152.74 212.13 148.49c5.657-4.243 168.29-193.75 168.29-193.75l-159.81-183.85-46.669-178.19-267.29-110.31z" clip-path="url(#jx)" enable-background="accumulate" filter="url(#eg)" opacity=".5"/>
-  <path d="m1146.2 809.42s22.62-6.507 35.743-5.873 30.642 1.939 43.709 12.186c13.067 10.248 25.068 27.14 34.112 58.37 9.045 31.23 1.698 99.252-6.176 143.35-7.874 44.095-28.265 106.11-45 140-16.735 33.887-49.798 77.495-60.57 89.876-11.363 13.062-56.205 36.426-79.43 42.267 5.303-10.607 48.9-50.589 35-60.714-14.02-10.212-45.76 45.982-84.293 29.033 21.382-13.132 41.779-51.186 34.04-66.594-7.84-15.61-30.704 48.758-93.535 37.013 30.052-27.527 55.407-70.904 41.263-82.98-14.415-12.307-60.462 54.293-60.462 54.293s-2.822-41.7 13.773-68.607c16.639-26.978 79.653-81.615 99.553-111.7 19.9-30.088 33.613-66.009 42.136-92.518s15.8-77.1 15.8-77.1" enable-background="new" fill="#0c0c0c"/>
-  <path transform="translate(324.57 331.53)" d="m770.75 609.18l-50.912 97.581-79.903 111.02 34.648 71.418 42.426 79.196 72.125-45.255 14.142-192.33 21.213-138.59-14.142-90.156-39.598 107.13z" clip-path="url(#jw)" enable-background="accumulate" fill="#fff" filter="url(#jv)" opacity=".25"/>
-  <path transform="translate(324.57 331.53)" d="m295 846.2l6.645-68.923s90.32 89.005 162.36 122.92 308 62 308 62l154-26-36 162-286 26-298-89-11-189z" clip-path="url(#ju)" enable-background="accumulate" filter="url(#eg)"/>
-  <path transform="translate(498.6 269.37)" d="m405.8 845.99l74.953 65.054 2.5 16.88 19.403 10.159 6.492 23.051 31.709-8.371 14.849 48.083c12.257 12.728 89.793-113.11 55.86 38.184l-60.81 16.264-89.203-94.693-62.825-53.8 7.07-60.811z" clip-path="url(#jt)" enable-background="new" fill="#fff" filter="url(#o)"/>
-  <path d="m1207.9 1113.9c54.286-1.429 126.04-15.052 170-26.786 44.053-11.757 125.89-36.347 175.36-57.857 49.339-21.453 113.6-59.282 154.29-92.143 40.508-32.721 52.39-55.82 60.714-33.571 8.37 22.368-16.407 56.326-37.857 81.071-21.604 24.923-52.731 52.705-98.929 89.286s-156.08 101.58-212.86 128.57c-57.066 27.125-128.2 58.238-172.14 72.5s-131.43 31.071-131.43 31.071l92.857-192.14z" enable-background="accumulate" fill="#121212"/>
-  <path transform="translate(498.6 269.37)" d="m1241.6 652.95s-64.722 54.337-145.66 98.995c-82.024 45.255-284.26 93.338-284.26 93.338s-15.101 21.052 45.255 28.284 224.08-53.301 278.6-96.167 120.21-111.72 120.21-111.72l-14.142-12.728z" clip-path="url(#js)" enable-background="accumulate" fill="url(#jr)" filter="url(#jq)" opacity=".5"/>
- </g>
- <g transform="translate(498.6 269.37)" clip-path="url(#jp)" enable-background="new">
-  <g filter="url(#em)">
-   <g transform="translate(-174.03 62.156)" filter="url(#i)">
-    <path d="m1268.3 663.77s-0.296 26.161 4.643 37.857 20.038 26.487 28.572 31.429 18.929 8.571 18.929 8.571l117.86-115 17.857-75.714-96.43 38.571-91.428 74.286z" enable-background="new" fill="#fff" fill-rule="evenodd"/>
-    <path d="M1197.8 486.14h333.75v309.71H1197.8z" enable-background="accumulate" fill="none"/>
-   </g>
-  </g>
-  <g transform="translate(-174.03 62.156)" enable-background="new" filter="url(#i)" opacity=".18">
-   <path d="m1268.3 663.77s-0.296 26.161 4.643 37.857 20.038 26.487 28.572 31.429 18.929 8.571 18.929 8.571l117.86-115 17.857-75.714-96.43 38.571-91.428 74.286z" enable-background="new" fill="#fff" fill-rule="evenodd"/>
-   <path d="M1197.8 486.14h333.75v309.71H1197.8z" enable-background="accumulate" fill="none"/>
-  </g>
- </g>
- <path transform="translate(498.6 269.37)" d="M1264.2 605c-4.491.733-8.157 3.455-11.938 6.406-10.081 7.87-28.17 34.425-48.031 50.47-39.867 32.202-104 69.976-152.56 91.093-48.614 21.137-130.54 45.818-174.31 57.5-43.398 11.582-115.04 25.131-168.25 26.531l-4.562.125-2 4.125-92.844 192.12-6.5 13.47 14.656-2.845s87.27-16.65 132.34-31.28c44.725-14.518 115.79-45.668 173.03-72.876 57.603-27.38 166.94-91.98 214.28-129.47 46.36-36.71 77.805-64.717 99.938-90.25 10.9-12.576 22.745-27.53 31.03-42.75 8.287-15.219 19.16-44.218 13.688-58.844-1.218-3.254-2.552-6.06-4.594-8.5s-8.475-1.572-8.563-5.03c-.21-8.266-3.315-.245-4.812 0zm2.156 15.219c.415.586 1.031 1.558 1.782 3.563 2.896 7.742-1.441 31.899-8.813 45.438s-22.638 28.924-33.188 41.094c-21.075 24.314-51.904 51.862-97.938 88.312-45.05 35.672-155.46 101.09-211.41 127.69-56.892 27.042-128.1 58.118-171.25 72.125-36.365 11.803-95.845 23.834-115.72
-27.78l84.281-174.47c54.707-2.049 123.79-15.215 167.12-26.78 44.334-11.832 126.08-36.336 176.41-58.22 50.112-21.788 112.53-61.167 154.03-94.687 20.646-16.677 41.745-42.546 49.813-48.844 2.437-1.903 4.08-2.636 4.875-3z" clip-path="url(#jo)" enable-background="accumulate" fill="#050505" fill-rule="evenodd" filter="url(#jn)" opacity=".833"/>
- <g transform="rotate(6.561 -6814.9 734.74)" enable-background="new" fill-rule="evenodd" mask="url(#jm)">
-  <path d="M1111.48-285.971l-3.937 1.875c-.041.01-.1.02-.125.031-.42.213-.165.1-.657.312-.486.21-1.737.585-4.093 1.47-3.332 1.25-5.805 2.15-7 3.062-1.537.021-3.72.233-5.657.719a227.677 227.677 0 0 1-6.75 1.593c-1.894.42-1.675.642-2.875.875-1.296.252-1.721-.009-5.437.782-3.49.742-8.895 1.93-10.156 2.687-1.584-.18-3.868-.322-5.844-.031-3.04.447-4.916.673-6.844.906-.655.08-1.04.2-1.343.281-.427.132-.686.26-1.375.344-1.312.16-1.763-.157-5.532.281-3.554.413-9.005 1.273-10.25 1.938-1.599-.297-3.857-.534-5.843-.344-3.06.293-4.972.484-6.907.656-1.934.173-1.688.423-2.906.532-1.316.117-1.76-.164-5.531.25-3.542.388-9.008 1.209-10.281 1.875-1.6-.295-3.887-.507-5.875-.313-3.058.3-4.941.48-6.875.656-.658.06-1.04.179-1.344.25-.428.12-.683.218-1.375.282-1.316.12-1.76-.195-5.531.218-3.556.39-9.006 1.24-10.25
-1.907-1.599-.295-3.86-.524-5.844-.313-3.056.325-4.974.526-6.906.719s-1.69.44-2.906.562c-1.315.132-1.763-.164-5.532.282-3.538.418-8.977 1.292-10.25 1.968-1.597-.28-3.86-.42-5.843-.187-3.052.358-4.945.568-6.875.781-.657.073-1.041.173-1.344.25-.427.127-.685.267-1.375.344-1.314.146-1.768-.174-5.531.312-3.55.46-8.979 1.42-10.22 2.125-1.592-.244-3.833-.381-5.812-.125-3.047.395-4.95.649-6.875.907-1.924.257-1.726.493-2.937.656-1.31.176-1.748-.105-5.5.469-3.525.538-8.924 1.699-10.188 2.437-1.588-.203-3.846-.255-5.813.094-3.026.536-4.899.861-6.812 1.187-.65.111-1.014.271-1.313.375-.42.165-.663.332-1.344.469-1.294.262-1.727-.006-5.437.813-3.499.771-8.846 2.382-10.062 3.218-1.563-.077-3.758.086-5.688.594-2.972.783-4.817 1.232-6.687 1.75s-1.667.767-2.844 1.094c-1.272.353-1.697.107-5.344 1.187-3.424 1.015-8.65 2.934-9.875 3.844-1.539.013-3.72.272-5.625.875-2.93.928-4.75 1.459-6.594
-2.063-.626.205-.991.392-1.28.53-.408.215-.654.41-1.313.626-1.255.411-1.686.189-5.281 1.437-3.39 1.178-8.595 3.214-9.782 4.157-1.524.06-3.65.395-5.53 1.062-2.898 1.028-4.7 1.676-6.532 2.313-1.832.637-1.628.848-2.781 1.25-1.247.434-1.664.2-5.22 1.562-3.338 1.28-8.486 3.483-9.687 4.469-1.507.108-3.635.499-5.5 1.219a1047.26 1047.26 0 0 1-6.437 2.469c-.617.233-.997.442-1.281.593v.031l-8 3.188-12.476 3.492 7.93 19.278c-.592 1.973 12.545-4.739 12.545-4.739.227-.144.45-.272.72-.375 1.08-.41 2.17-.215 6-1.687 3.828-1.472 5.223-2.005 5.905-2.406.68-.4 1.612-.88 2.22-1.531 1.826-.138 3.57-.494 4.937-1 2.968-1.1 4.875-1.807 6.78-2.47 1.907-.662 2.355-1.414 3.407-1.78 1.092-.38 2.195-.166 6.063-1.532 3.867-1.366 5.283-1.827 5.968-2.218.702-.4 1.701-.933 2.313-1.594 1.97-.055 3.817-.385 5.281-.875 3.002-1.005 4.926-1.622 6.844-2.25 1.538-.504 2.174-1.047 2.906-1.438.23-.134.476-.253.75-.343 1.098-.36
-2.181-.082 6.094-1.313 3.912-1.231 5.366-1.673 6.062-2.031.694-.357 1.63-.793 2.25-1.406 1.866-.023 3.636-.267 5.032-.688 3.03-.913 4.992-1.43 6.937-1.969 1.945-.538 2.426-1.264 3.5-1.562 1.114-.31 2.22.007 6.188-1.031 3.967-1.039 5.417-1.433 6.125-1.75.734-.33 1.813-.754 2.437-1.375 1.998.116 3.857-.02 5.344-.375 3.078-.735 5.083-1.101 7.062-1.5 1.588-.32 2.245-.79 3-1.094a3.4 3.4 0 0 1 .75-.25c1.134-.23 2.305.209 6.344-.5 4.04-.71 5.5-.927 6.219-1.188.716-.26 1.704-.567 2.344-1.093 1.924.239 3.748.224 5.187 0 3.127-.488 5.155-.701 7.156-.97 2.002-.267 2.49-.944 3.594-1.093 1.147-.154 2.276.302 6.344-.219 4.068-.52 5.56-.695 6.281-.937.737-.247 1.798-.586 2.438-1.125 2.05.335 3.973.398 5.5.218 3.142-.368 5.18-.559 7.187-.78 1.611-.179 2.265-.609 3.031-.845.241-.085.495-.155.782-.187 1.15-.128 2.301.347 6.375-.125s5.559-.61 6.28-.844c.72-.232 1.701-.473 2.345-.969 1.936.334 3.77.405
-5.219.25 3.146-.334 5.177-.518 7.187-.718 2.01-.2 2.484-.827 3.594-.938 1.15-.115 2.296.365 6.375-.062s5.589-.562 6.312-.782c.74-.223 1.796-.513 2.438-1.03 2.057.398 4.002.493 5.531.343 3.149-.308 5.176-.473 7.188-.656 1.614-.147 2.263-.56 3.03-.781.242-.081.494-.13.782-.157 1.152-.105 2.293.393 6.375 0s5.589-.53 6.312-.75c.721-.218 1.7-.447 2.344-.937 1.938.35 3.769.454 5.219.312 3.149-.308 5.176-.473 7.187-.656 2.012-.183 2.515-.838 3.625-.937 1.153-.104 2.293.384 6.375 0 4.083-.385 5.59-.501 6.313-.72.74-.222 1.796-.514 2.437-1.03 2.058.401 4.003.503 5.532.343 3.146-.328 5.177-.522 7.187-.718 1.613-.158 2.266-.632 3.031-.875.241-.088.464-.122.75-.157 1.149-.14 2.317.34 6.375-.25 4.059-.59 5.562-.777 6.282-1.03.716-.254 1.674-.559 2.312-1.095 1.92.212 3.72.152 5.156-.093 3.12-.533 5.112-.929 7.094-1.313 1.982-.384 2.474-1.04 3.563-1.281 1.128-.25 2.27.116 6.25-.875s5.43-1.42
-6.125-1.781c.722-.376 1.761-.87 2.375-1.531 1.963-.012 3.793-.292 5.218-.844 2.952-1.145 4.874-1.87 6.688-2.75 1.456-.707 2.32-1.702 2.531-2 .212-.298.1-.729.125-.75.043-.035.34-.094.5-.438.86-1.847 2.323-5.627 2.438-6.312.113-.682.168-1.353.218-1.75.03-.23-.147-.88-.125-.938.031-.082.289-.25.344-.5.266-1.198.09-2.207-.125-3.625-.214-1.417-.972-4.614-1.625-5.469-.659-.861-1.225-1.01-1.75-1z" enable-background="new" fill="#bcb786"/>
-  <g clip-path="url(#jl)">
-   <path d="M1107.4-284.05c-.419.213-.156.094-.647.306-.486.21-1.724.574-4.08 1.459-3.33 1.25-5.83 2.153-7.026 3.066-1.536.021-3.72.233-5.656.719a227.709 227.709 0 0 1-6.75 1.593c-1.895.42-1.676.643-2.875.875-1.297.252-1.721-.009-5.438.782-3.49.742-8.894 1.93-10.156 2.687-1.583-.18-3.867-.322-5.843-.031-3.04.447-4.917.673-6.844.906-.655.08-1.041.201-1.344.282-.426.131-.686.26-1.375.343-1.311.16-1.762-.157-5.531.282-3.554.413-9.005 1.272-10.25 1.937-1.599-.297-3.858-.534-5.844-.344-3.059.294-4.972.484-6.906.657-1.934.172-1.689.422-2.906.53-1.317.118-1.76-.163-5.532.25-3.541.39-9.007 1.21-10.28 1.876-1.6-.295-3.888-.507-5.876-.313-3.058.3-4.94.48-6.875.657-.657.06-1.04.178-1.343.25-.428.118-.684.218-1.375.28-1.316.121-1.76-.194-5.532.22-3.556.39-9.005 1.239-10.25
-1.906-1.598-.294-3.86-.524-5.843-.313-3.056.326-4.974.526-6.907.719-1.932.192-1.69.44-2.906.562-1.315.132-1.763-.164-5.53.282-3.54.418-8.979 1.292-10.25 1.969-1.599-.282-3.86-.42-5.845-.188-3.052.358-4.945.568-6.875.781-.656.073-1.04.173-1.344.25-.426.127-.684.267-1.375.344-1.313.146-1.767-.174-5.53.313-3.55.458-8.98 1.419-10.22 2.125-1.593-.245-3.834-.382-5.812-.125-3.048.394-4.95.648-6.875.906-1.925.258-1.726.493-2.938.656-1.31.176-1.747-.104-5.5.469-3.524.538-8.923 1.699-10.188 2.437-1.587-.203-3.845-.254-5.812.094-3.026.536-4.9.862-6.813 1.187-.65.111-1.013.271-1.312.375-.42.165-.664.332-1.344.47-1.295.26-1.727-.007-5.438.812-3.498.772-8.846 2.383-10.062 3.219-1.562-.078-3.757.085-5.687.593-2.972.783-4.818 1.232-6.688 1.75s-1.666.768-2.843 1.094c-1.273.353-1.697.107-5.344 1.188-3.425 1.014-8.65 2.933-9.875 3.843-1.539.013-3.72.273-5.625.875-2.931.928-4.75 1.459-6.594
-2.063-.627.205-.992.392-1.281.531-.408.214-.653.409-1.313.625-1.254.412-1.686.19-5.28 1.438-3.39 1.177-8.596 3.213-9.782 4.156-1.524.06-3.65.395-5.531 1.062-2.898 1.029-4.7 1.676-6.531 2.313-1.833.637-1.628.848-2.782 1.25-1.246.434-1.663.2-5.218 1.562-3.34 1.28-8.488 3.483-9.688 4.47-1.507.107-3.636.498-5.5 1.218a1044.752 1044.752 0 0 1-6.437 2.469c-.617.233-.997.442-1.282.593v1.094c.112-.222.386-.817.907-1.094.698-.37 4.813-1.993 6.812-2.718 1.657-.602 4.154-1.329 5.969-1.313.302.003.588.051.844.094 1.842.308 7.468 1.562 7.468 1.562s-6.233-1.646-7.03-1.843c-.191-.048-.536-.07-.97-.063 1.146-.87 4.762-2.393 7.344-3.437 2.839-1.148 3.117-1.252 5.063-1.657 2.008-.417 3.156-.5 3.156-.5s-.082-.6.969-1.125c.705-.351 4.887-1.892 6.906-2.562 1.952-.648 5.057-1.359 6.875-1 1.863.367 7.531 1.812 7.531 1.812s-6.287-1.87-7.094-2.093c-.193-.054-.53-.086-.968-.094 1.158-.833 4.794-2.195 7.406-3.156
-2.87-1.056 3.167-1.162 5.125-1.532 1.853-.35 2.859-.425 3.031-.437.114-.217.377-.81.906-1.063.71-.338 4.926-1.712 6.97-2.312 1.692-.497 4.24-1.037 6.093-.906.308.021.613.097.875.156 1.881.424 7.594 2.031 7.594 2.031s-6.342-2.065-7.157-2.312c-.194-.06-.557-.104-1-.125 1.17-.798 4.863-2.057 7.5-2.938 2.898-.968 3.233-1.003 5.22-1.281 2.049-.287 3.187-.313 3.187-.313s-.073-.607 1-1.062c.72-.306 4.99-1.5 7.062-2 2.003-.483 5.199-.928 7.063-.406 1.91.535 7.719 2.5 7.719 2.5s-6.423-2.424-7.25-2.72c-.198-.07-.583-.14-1.032-.187 1.188-.728 4.916-1.774 7.594-2.5 2.944-.797 3.292-.77 5.313-.906 1.913-.128 2.947-.07 3.125-.062.117-.204.391-.78.937-.97.732-.253 5.079-1.047 7.188-1.374 1.748-.271 4.4-.485 6.312-.094.318.065.605.186.875.281 1.94.69 7.844 3.094 7.844 3.094s-6.535-2.95-7.375-3.312c-.201-.087-.575-.167-1.031-.25 1.206-.633 5.03-1.396 7.75-1.906 2.99-.562 3.3-.53 5.344-.532 2.109-.002
-3.312.125 3.312.125s-.073-.63 1.031-.937c.74-.206 5.126-.834 7.25-1.063 2.053-.22 5.319-.252 7.22.47 1.947.738 7.843 3.374 7.843 3.374s-6.563-3.179-7.406-3.562c-.202-.092-.543-.187-1-.282 1.21-.602 4.984-1.248 7.718-1.656 3.005-.448 3.326-.452 5.375-.406 1.94.043 3.007.194 3.188.219.119-.194.384-.766.937-.907.743-.188 5.155-.734 7.282-.937 1.763-.169 4.42-.234 6.343.25.32.08.604.203.875.312 1.953.784 7.907 3.47 7.907 3.47s-6.592-3.254-7.438-3.657c-.202-.096-.572-.207-1.031-.313 1.214-.574 5.044-1.122 7.781-1.5 3.009-.415 3.323-.442 5.375-.375 2.118.07 3.313.25 3.313.25s-.078-.637 1.03-.906c.745-.18 5.153-.663 7.282-.844 2.059-.174 5.343-.124 7.25.657 1.955.8 7.875 3.53 7.875 3.53s-6.56-3.308-7.406-3.718c-.202-.098-.572-.203-1.031-.312 1.215-.564 5.01-1.115 7.75-1.47 3.01-.389 3.321-.397 5.375-.312 1.944.08 3.006.254 3.187.282.12-.191.383-.746.938-.875.744-.174 5.15-.65 7.28-.813
-1.767-.134 4.45-.126 6.376.375.32.083.603.201.875.313 1.954.8 7.906 3.562 7.906 3.562s-6.591-3.34-7.437-3.75c-.203-.098-.572-.203-1.032-.312 1.215-.564 5.042-1.084 7.782-1.438 3.01-.39 3.352-.429 5.406-.344 2.12.088 3.312.313 3.312.313s-.078-.65 1.032-.906c.744-.173 5.15-.624 7.28-.782 2.061-.152 5.344-.096 7.25.688 1.956.804 7.876 3.5 7.876 3.5s-6.56-3.276-7.406-3.688c-.203-.098-.572-.202-1.032-.312 1.216-.562 5.012-1.128 7.75-1.5 3.01-.41 3.323-.416 5.375-.344 1.943.068 3.008.165 3.188.188.119-.195.384-.73.937-.875.742-.197 5.131-.83 7.25-1.094 1.757-.22 4.406-.333 6.313.031.317.06.606.19.875.281 1.936.661 7.844 2.938 7.844 2.938s-6.537-2.807-7.375-3.156c-.2-.084-.577-.174-1.032-.25 1.204-.651 5.02-1.372 7.72-2 2.966-.69 3.288-.756 5.312-.875 2.088-.124 3.28-.032 3.28-.032s-.086-.632 1-1.03c.73-.269 5.048-1.339 7.126-1.813 2.008-.46 5.168-1.03 7-.625 1.878.414 13.578 3.015 13.578
-3.015s-12.328-3.022-13.141-3.265c-.195-.058-.559-.107-1-.125 1.167-.804 3.514-1.688 6.11-2.703 1.68-.659.923-.377 2.775-1.004 1.754-.594 2.486-1.01 2.63-1.113.347-.207-.355-.122-.544-.042z" enable-background="new" filter="url(#jk)"/>
-   <path d="m1082.6-275.12c1.873 0.393 4.496 1.146 6.031 1.969s2.822 1.056 5.375 2.5c2.527 1.43 4.796 2.007 6.969 2.531 2.348 0.566 5.435 0.715 8.844 1.188-1.09-0.84-6.608-1.173-8.406-1.563-1.8-0.39-3.895-1.016-6.594-2.313-2.7-1.296-3.495-1.799-5.813-2.687-2.318-0.889-4.004-1.383-6.406-1.625z" enable-background="new" filter="url(#jj)"/>
-   <path d="M1051.5-270c1.905.578 4.528 1.616 6.094 2.594 1.565.978 2.88 1.36 5.5 3.125 2.593 1.747 4.986 2.71 7.25 3.594 2.446.955 5.682 1.657 9.406 3.062-1.19-1.138-7.063-2.687-8.938-3.375-1.874-.688-4.081-1.566-6.874-3.281-2.794-1.715-3.574-2.284-5.938-3.406-2.364-1.123-4.057-1.835-6.5-2.313z" enable-background="new" filter="url(#ji)"/>
-   <path d="m1020.2-266.84c1.912 0.638 4.581 1.755 6.156 2.813 1.575 1.057 2.896 1.508 5.531 3.406 2.61 1.878 5.029 3.03 7.313 4.062 2.468 1.116 5.764 2.174 9.531 3.844-1.203-1.222-7.203-3.314-9.094-4.125-1.89-0.81-4.064-1.894-6.874-3.75s-3.622-2.477-6-3.719c-2.379-1.242-4.111-1.975-6.563-2.531z" enable-background="new" filter="url(#jh)"/>
-   <path d="M1110.2-266.89c.15.049.688.631.11 1.484-.81 1.195-5.705 3.325-8.563 4.125-2.845.798-6.29.978-10.562-.375-4.302-1.362-5.47-2.468-10.656-4.312 4.664 2.115 6.195 3.952 10.125 5.344 1.62.574 3.367.94 5.062 1.03-.445.327-1.53.984-3.562 1.595-2.796.84-6.65 1.534-8.25 1.625-1.515.086-3.142-.513-3.438-.625.167.103.374.377-.25 1.03-.899.945-6.147 1.924-9.125 2.25-2.964.326-6.521-.015-10.906-1.905-3.978-1.715-5.339-2.916-9.406-4.75v.156c3.643 2.095 5.284 3.883 8.875 5.562 1.73.81 3.592 1.41 5.406 1.72-.534.286-1.557.71-3.437 1.03-2.87.488-6.81.817-8.438.75-.85-.034-1.728-.184-2.406-.406-.685-.215-1.19-.444-1.312-.5.169.107.43.403-.22 1.031-.909.88-6.245 1.337-9.25 1.47-2.99.131-6.588-.451-11-2.563-4.44-2.127-5.64-3.402-10.905-5.782 4.734 2.597 6.286 4.63 10.344 6.72 1.673.861 3.485 1.493 5.25 1.937-.463.233-1.59.688-3.688.937-2.886.343-6.834.493-8.468.375-1.547-.111-3.232-.857-3.532-1
-.17.12.414.41-.218 1-.913.851-6.244 1.262-9.25 1.375-2.993.113-6.59-.49-11-2.594-4.002-1.908-5.388-3.137-9.47-5.093v.156c3.656 2.204 5.295 4.053 8.907 5.906 1.74.893 3.637 1.528 5.469 1.969-.54.248-1.578.615-3.469.844-2.886.348-6.866.52-8.5.406a9.446 9.446 0 0 1-2.406-.5 12.532 12.532 0 0 1-1.313-.531c.17.112.465.422-.187 1.03-.913.853-6.275 1.294-9.281 1.407-2.993.112-6.594-.528-11-2.594-4.437-2.08-5.647-3.331-10.906-5.656 4.729 2.548 6.29 4.578 10.344 6.625 1.671.844 3.485 1.467 5.25 1.906-.464.235-1.59.684-3.688.938-2.886.348-6.836.57-8.469.469-1.544-.096-3.2-.83-3.5-.97.17.12.382.405-.25 1-.912.861-6.246 1.331-9.25 1.47-2.99.138-6.567-.451-10.969-2.47-3.993-1.83-5.365-3.028-9.437-4.905v.156c3.647 2.133 5.27 3.935 8.875 5.719 1.737.86 3.607 1.45 5.437 1.875-.54.253-1.55.64-3.437.906-2.88.404-6.838.646-8.469.562a9.36 9.36 0 0 1-2.406-.437 12.971 12.971 0 0
-1-1.313-.5c.17.109.432.41-.218 1.031-.911.87-6.25 1.392-9.25 1.563-2.987.17-6.574-.316-10.97-2.282-4.424-1.978-5.605-3.228-10.843-5.375 4.71 2.388 6.27 4.39 10.312 6.344a23.73 23.73 0 0 0 5.218 1.781c-.461.25-1.597.713-3.687 1.032-2.876.438-6.78.733-8.406.687-1.539-.043-3.233-.745-3.532-.875.169.113.411.414-.218 1.031-.908.891-6.203 1.529-9.188 1.813-2.971.283-6.573-.176-10.938-1.938-3.96-1.598-5.329-2.795-9.344-4.312v.156c3.596 1.811 5.239 3.582 8.813 5.156 1.722.759 3.587 1.29 5.406 1.625-.536.28-1.566.688-3.437 1.063-2.856.572-6.79 1.02-8.407 1.031-.844.006-1.706-.08-2.375-.25-.676-.162-1.16-.33-1.28-.375.166.094.422.383-.22 1.062-.897.951-6.186 1.918-9.125 2.438-2.925.518-6.432.374-10.719-1.031-4.315-1.415-5.472-2.53-10.562-3.969 4.577 1.751 6.09 3.56 10.031 5 1.627.594 3.37.956 5.094 1.156-.453.297-1.555.884-3.594 1.469-2.804.805-6.638 1.576-8.218
-1.75-1.495.165-3.117-.317-3.407-.406.164.09.393.36-.218 1.062-.883 1.014-6.045 2.372-8.938 3.063-2.88.687-6.335.76-10.562-.438-3.835-1.086-5.172-2.072-9.062-3.125v.156c3.484 1.395 5.07 2.92 8.53 4.032 1.669.535 3.457.786 5.22.875-.52.352-1.5.914-3.313 1.53-2.765.942-6.59 1.936-8.156 2.157-.818.115-1.633.123-2.281.031-.655-.083-1.133-.218-1.25-.25.162.075.434.34-.188 1.094-.87 1.055-6.01 2.66-8.875 3.438-2.852.774-6.259.958-10.438-.094-4.206-1.06-5.356-2.042-10.344-3.156 4.485 1.46 5.97 3.135 9.813 4.25 1.585.46 3.287.638 4.969.687-.442.337-1.513 1.028-3.5 1.781-2.734 1.037-6.452 2.163-8 2.438-1.465.26-3.06-.117-3.344-.188.16.08.38.321-.219 1.063-.865 1.07-5.916 2.818-8.75 3.687-2.82.866-6.207 1.157-10.344.22-3.753-.852-5.048-1.717-8.875-2.595v.157c3.428 1.237 4.987 2.632 8.375 3.53 1.632.434 3.367.584 5.094.563-.51.384-1.477 1.022-3.25 1.75-2.706 1.112-6.436 2.308-7.969
-2.625-.8.166-1.612.219-2.25.157v1.406c.227-.145.449-.273.719-.375 1.08-.41 2.171-.216 6-1.688 3.828-1.471 5.224-2.005 5.906-2.406.68-.4 1.612-.88 2.219-1.531 1.827-.138 3.57-.493 4.937-1 2.968-1.1 4.876-1.806 6.782-2.469 1.905-.663 2.354-1.415 3.406-1.781 1.091-.38 2.195-.166 6.062-1.531 3.868-1.366 5.283-1.827 5.969-2.22.701-.4 1.7-.932 2.313-1.593 1.97-.055 3.816-.385 5.28-.875 3.002-1.005 4.927-1.622 6.845-2.25 1.538-.504 2.174-1.047 2.906-1.437.23-.135.475-.254.75-.344 1.098-.36 2.181-.082 6.094-1.313 3.912-1.23 5.366-1.673 6.062-2.03.694-.358 1.63-.794 2.25-1.407 1.865-.023 3.636-.267 5.031-.688 3.03-.913 4.993-1.43 6.938-1.968 1.945-.54 2.426-1.265 3.5-1.563 1.114-.31 2.22.007 6.187-1.031 3.968-1.039 5.418-1.433 6.125-1.75.735-.33 1.814-.754 2.438-1.375 1.997.116 3.857-.02 5.344-.375 3.078-.735 5.083-1.101 7.062-1.5 1.588-.32 2.244-.79 3-1.094.238-.107.467-.193.75-.25 1.134-.23
-2.305.209 6.344-.5s5.5-.927 6.219-1.187c.715-.26 1.704-.568 2.343-1.094 1.925.24 3.748.224 5.188 0 3.126-.488 5.155-.7 7.156-.969 2.002-.268 2.489-.945 3.594-1.094 1.146-.154 2.276.302 6.344-.219 4.068-.52 5.56-.695 6.28-.937.738-.247 1.799-.586 2.438-1.125 2.05.335 3.974.398 5.5.219 3.143-.37 5.18-.56 7.188-.782 1.61-.178 2.265-.608 3.031-.843a3.43 3.43 0 0 1 .781-.188c1.15-.128 2.302.347 6.375-.125s5.56-.61 6.282-.844c.719-.232 1.7-.473 2.343-.968 1.937.333 3.77.404 5.22.25 3.145-.335 5.177-.519 7.187-.719 2.01-.2 2.484-.826 3.593-.938 1.152-.115 2.297.366 6.375-.062s5.59-.562 6.313-.781c.74-.224 1.796-.514 2.437-1.031 2.058.398 4.002.493 5.532.343 3.148-.308 5.175-.473 7.187-.656 1.614-.147 2.263-.56 3.031-.781.242-.081.494-.13.782-.156 1.152-.106 2.293.392 6.375 0 4.082-.393 5.589-.531 6.312-.75.721-.219 1.7-.448 2.344-.938 1.938.35 3.769.454 5.219.313 3.148-.309 5.175-.474
-7.187-.657 2.012-.183 2.514-.838 3.625-.937 1.152-.103 2.292.385 6.375 0s5.589-.501 6.313-.719c.739-.222 1.795-.514 2.437-1.031 2.057.402 4.003.503 5.531.344 3.147-.329 5.178-.523 7.188-.72 1.613-.156 2.266-.63 3.031-.874.24-.088.463-.122.75-.156 1.148-.14 2.317.34 6.375-.25 4.058-.59 5.562-.778 6.281-1.032.717-.253 1.675-.558 2.313-1.093 1.92.211 3.72.151 5.156-.094 3.12-.533 5.112-.929 7.094-1.313 1.982-.384 2.474-1.04 3.562-1.28 1.13-.252 2.27.115 6.25-.876s5.43-1.42 6.125-1.781c.723-.376 1.762-.87 2.375-1.531 1.963-.012 3.794-.291 5.22-.844 2.95-1.145 4.872-1.87 6.687-2.75 1.455-.707 2.334-1.686 2.547-1.984.212-.298.111-.746.137-.767.043-.035.32-.085.48-.429.858-1.847 2.32-5.644
-2.435-6.329.113-.682.163-1.348.214-1.745.03-.23-.147-.865-.125-.924.031-.082.305-.265.36-.515.267-1.198.09-2.191-.125-3.609-.214-1.417-.983-4.622-1.637-5.476-.659-.862-1.223-1.011-1.748-1-.208.27.137.262.163.312.68.05.934.369 1.42.897s1.442 3.94 1.579 5.39.19 2.86-.088 3.468c-.278.609-.944.429-1.237.495.531.186.89.213.953 1.057.058.814-.134 1.64-.52 2.806-.391 1.18-1.845 4.35-2.286 4.599-.452.255-.952.182-1.288.05z" enable-background="new" filter="url(#jg)"/>
-   <path d="m988.75-263.84c1.912 0.634 4.55 1.758 6.125 2.813 1.575 1.054 2.896 1.482 5.531 3.375 2.609 1.873 5.027 3.015 7.313 4.062 2.47 1.132 5.752 2.155 9.531 3.938-1.207-1.259-7.139-3.365-9.031-4.188s-4.128-1.93-6.938-3.781-3.622-2.482-6-3.719c-2.377-1.237-4.08-1.95-6.53-2.5z" enable-background="new" filter="url(#jf)"/>
-   <path d="M957.5-260.78c1.91.618 4.583 1.71 6.156 2.75 1.574 1.04 2.896 1.482 5.531 3.375 2.609 1.873 5.027 3.015 7.313 4.063 2.47 1.131 5.752 2.154 9.531 3.937-1.207-1.258-7.201-3.396-9.094-4.219-1.892-.823-4.096-1.93-6.906-3.781-2.81-1.85-3.593-2.44-5.969-3.656s-4.113-1.939-6.562-2.469z" enable-background="new" filter="url(#ib)"/>
-   <path d="M926.09-257.38c1.908.597 4.553 1.664 6.125 2.688 1.571 1.023 2.87 1.44 5.5 3.28 2.603 1.823 5.029 2.973 7.313 4 2.467 1.111 5.755 2.094 9.53 3.845-1.205-1.249-7.171-3.319-9.062-4.125s-4.102-1.891-6.906-3.688c-2.804-1.796-3.627-2.402-6-3.594-2.373-1.191-4.054-1.903-6.5-2.406z" enable-background="new" filter="url(#ia)"/>
-   <path d="M894.91-253.56c1.902.554 4.587 1.589 6.156 2.594s2.874 1.408 5.5 3.219c2.6 1.791 5 2.871 7.281 3.875 2.465 1.083 5.76 2.04 9.532 3.75-1.205-1.236-7.175-3.245-9.063-4.032-1.888-.786-4.075-1.83-6.875-3.593s-3.6-2.369-5.969-3.532c-2.37-1.163-4.123-1.834-6.562-2.28z" enable-background="new" filter="url(#hz)"/>
-   <path d="M863.72-248.66c1.88.43 4.504 1.38 6.063 2.313 1.558.932 2.852 1.257 5.468 3 2.59 1.724 4.981 2.708 7.25 3.625 2.452.99 5.74 1.877 9.5 3.5-1.201-1.208-7.152-3.067-9.03-3.782-1.88-.715-4.086-1.684-6.876-3.375s-3.585-2.228-5.937-3.28-4.026-1.713-6.438-2z" enable-background="new" filter="url(#hy)"/>
-   <path d="m833.16-241.38c1.848 0.296 4.47 0.976 6 1.781s2.814 1.056 5.375 2.531c2.535 1.46 4.89 2.326 7.125 3.063 2.414 0.797 5.657 1.467 9.375 2.844-1.188-1.129-7.088-2.59-8.938-3.156-1.85-0.567-4.003-1.374-6.75-2.844-2.746-1.47-3.5-1.92-5.812-2.781-2.311-0.861-4.005-1.32-6.375-1.438z" enable-background="new" filter="url(#hx)"/>
-   <path d="m802.91-232.31c1.822 0.211 4.366 0.8 5.875 1.531 1.51 0.73 2.756 0.93 5.281 2.281 2.5 1.338 4.832 2.049 7.031 2.657 2.377 0.656 5.565 1.073 9.22 2.187-1.168-1.045-6.93-2.103-8.75-2.562-1.822-0.46-3.953-1.127-6.657-2.438s-3.471-1.72-5.75-2.469-3.913-1.179-6.25-1.187z" enable-background="new" filter="url(#hw)"/>
-   <path d="M773.19-222.19c1.811.179 4.32.665 5.813 1.344 1.491.678 2.753.798 5.25 2.062 2.47 1.252 4.79 1.896 6.968 2.438 2.354.585 5.492.897 9.094 1.844-1.15-.992-6.852-1.784-8.656-2.188s-3.916-1.021-6.594-2.25c-2.678-1.229-3.403-1.61-5.656-2.281-2.253-.67-3.896-1.002-6.219-.969z" enable-background="new" filter="url(#hv)"/>
-   <path d="M743.56-211.19c1.793.13 4.273.55 5.75 1.188s2.716.741 5.188 1.937c2.446 1.184 4.72 1.747 6.874 2.219 2.328.51 5.42.68 9 1.562-1.143-.97-6.747-1.59-8.53-1.937-1.784-.347-3.884-.888-6.532-2.031-2.648-1.144-3.395-1.517-5.625-2.125-2.23-.61-3.826-.91-6.125-.813z" enable-background="new" filter="url(#hu)"/>
-   <g fill="#fff" filter="url(#ht)">
-    <path d="M744.94-212.12s7.222-3.223 9.063-3.5 3.352-.003 6 .563c2.647.565 8.735 2.215 11.188 3.374s5.312 3.563 5.312 3.563-7.146-2.78-10.188-3.563-7.645-2.083-10.375-2.312-11 1.875-11 1.875z"/>
-    <path d="m735.47-206.95s3.66-2.223 5.5-2.5 3.665 0.247 6.313 0.813 8.735 2.215 11.188 3.375 6.562 2.125 6.562 2.125-8.396-1.343-11.438-2.125-7.957-2.334-10.688-2.563-7.438 0.875-7.438 0.875zm24.38-10.66s8.544-3.299 10.398-3.458c1.854-0.16 3.642 0.48 6.248 1.212s8.577 2.766 10.95 4.08 6.414 2.537 6.414 2.537-8.294-1.873-11.279-2.848c-2.985-0.974-7.792-2.834-10.503-3.236s-12.228 1.713-12.228 1.713zm15.35-5.62s7.771-2.782 9.628-2.904c1.857-0.12 3.631 0.555 6.222 1.341 2.59 0.787 8.519 2.942 10.864 4.304 2.346 1.362 6.36 2.67 6.36 2.67s-8.253-2.045-11.217-3.08c-2.965-1.035-7.733-2.995-10.434-3.452-2.702-0.458-11.422 1.121-11.422 1.121zm14.44-4.72s8.683-3.52 10.542-3.605 3.62 0.624 6.195 1.46c2.575 0.837 8.46 3.107 10.779 4.514 2.318 1.408 6.307 2.793 6.307 2.793s-8.212-2.204-11.156-3.297-7.673-3.144-10.365-3.654-12.3 1.789-12.3 1.789zm14.86-5.38s7.808-2.583 9.666-2.668c1.86-0.085 3.62
-0.625 6.195 1.461 2.575 0.837 8.46 3.107 10.78 4.514 2.318 1.407 6.307 2.792 6.307 2.792s-8.213-2.204-11.156-3.296-7.673-3.144-10.365-3.654-11.426 0.85-11.426 0.85zm15.06-4.25s8.558-2.583 10.417-2.668 3.62 0.625 6.195 1.461c2.575 0.837 8.46 3.107 10.779 4.514 2.318 1.407 6.307 2.792 6.307 2.792s-8.212-2.204-11.156-3.296-7.673-3.144-10.365-3.654-12.176 0.85-12.176 0.85zm16.67-5.02s6.967-1.987 8.828-1.968c1.86 0.02 3.579 0.827 6.102 1.807 2.524 0.98 8.272 3.578 10.508 5.113 2.236 1.536 6.14 3.143 6.14 3.143s-8.075-2.662-10.952-3.919c-2.878-1.256-7.484-3.57-10.143-4.231-2.66-0.66-10.482 0.055-10.482 0.055zm14.5-3.4s7.688-2.028 9.548-1.968 3.56 0.902 6.063 1.936c2.502 1.033 8.194 3.752 10.397 5.335 2.203 1.582 6.072 3.272 6.072 3.272s-8.017-2.833-10.868-4.15c-2.85-1.318-7.407-3.73-10.05-4.446s-11.162 0.021-11.162 0.021zm14.09-3.21s8.17-1.97 10.027-1.854c1.857 0.115 3.532 1.01 6.002
-2.118s8.077 3.997 10.23 5.645 5.972 3.454 5.972 3.454-7.928-3.074-10.738-4.476-7.291-3.95-9.913-4.746c-2.621-0.796-11.58-0.141-11.58-0.141zm16.56-2.39s8.085-1.908 9.938-1.737c1.853 0.172 3.5 1.117 5.935 2.3 2.436 1.182 7.952 4.24 10.055 5.953s5.864 3.633 5.864 3.633-7.832-3.312-10.597-4.8-7.168-4.169-9.764-5.044c-2.597-0.876-11.431-0.305-11.431-0.305zm15.2-2.75s7.642-1.428 9.495-1.265c1.854 0.162 3.505 1.1 5.946 2.27s7.973 4.203 10.084 5.905c2.112 1.703 5.881 3.605 5.881 3.605s-7.847-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.788-4.998-2.6-0.863-10.998-0.77-10.998-0.77zm14.87-1.64s8.642-1.553 10.495-1.39c1.854 0.162 3.505 1.1 5.946 2.27s7.972 4.203 10.084 5.905c2.111 1.703 5.88 3.605 5.88 3.605s-7.846-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.787-4.998-2.601-0.863-11.998-0.644-11.998-0.644zm16.25-2.31s7.642-0.865 9.495-0.703c1.854 0.163 3.505 1.1 5.946 2.27s7.973 4.203 10.084
-5.906c2.112 1.702 5.881 3.605 5.881 3.605s-7.847-3.275-10.62-4.749c-2.772-1.474-7.187-4.135-9.788-4.998-2.6-0.862-10.998-1.331-10.998-1.331zm15.13-1.19s8.58-1.49 10.433-1.328c1.854 0.163 3.505 1.1 5.946 2.27s7.972 4.203 10.084 5.906c2.111 1.702 5.88 3.605 5.88 3.605s-7.846-3.275-10.62-4.749c-2.772-1.474-7.187-4.135-9.787-4.998-2.601-0.862-11.935-0.706-11.935-0.706zm16.25-2.06s7.83-0.803 9.683-0.64c1.854 0.162 3.505 1.1 5.946 2.27s7.972 4.203 10.084 5.905c2.111 1.703 5.88 3.605 5.88 3.605s-7.846-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.787-4.998-2.601-0.863-11.185-1.394-11.185-1.394zm15.37-1.25s8.392-1.178 10.245-1.015c1.854 0.162 3.505 1.1 5.946 2.27s7.972 4.203 10.084 5.905c2.111 1.703 5.88 3.605 5.88 3.605s-7.847-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.788-4.998-2.6-0.863-11.748-1.02-11.748-1.02zm16.19-2.06s6.892-0.99 8.745-0.828c1.854 0.163 3.505 1.1 5.946 2.27s7.973 4.203
-10.084 5.906c2.112 1.702 5.881 3.605 5.881 3.605s-7.847-3.275-10.62-4.749-7.188-4.135-9.788-4.998c-2.6-0.862-10.248-1.206-10.248-1.206zm17.16-0.94s6.83-1.178 8.683-1.015c1.854 0.162 3.505 1.1 5.946 2.27 2.44 1.171 7.972 4.203 10.084 5.905 2.111 1.703 5.88 3.605 5.88 3.605s-7.847-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.788-4.998-2.6-0.863-10.185-1.02-10.185-1.02zm16.1-2s6.08-0.428 7.933-0.265c1.854 0.162 3.505 1.1 5.946 2.27 2.44 1.171 7.972 4.203 10.084 5.905 2.111 1.703 5.88 3.605 5.88 3.605s-7.847-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.788-4.998-2.6-0.863-9.435-1.77-9.435-1.77zm15.8-1.37s6.454-0.678 8.308-0.515c1.854 0.162 3.505 1.1 5.946 2.27 2.44 1.171 7.972 4.203 10.084 5.905 2.111 1.703 5.88 3.605 5.88 3.605s-7.847-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.788-4.998-2.6-0.863-9.81-1.52-9.81-1.52zm15.6-1.86s5.498-0.91 7.358-0.853c1.86 0.056 3.562 0.896 6.066 1.925
-2.504 1.03 8.2 3.739 10.406 5.318 2.205 1.578 6.078 3.261 6.078 3.261s-8.022-2.819-10.875-4.131c-2.853-1.313-7.413-3.716-10.06-4.429-2.645-0.712-8.973-1.091-8.973-1.091zm17.4-2.46s4.547-1.156 6.408-1.186c1.86-0.03 3.6 0.73 6.149 1.642 2.55 0.912 8.365 3.354 10.64 4.829 2.277 1.474 6.224 2.976 6.224 2.976s-8.145-2.444-11.055-3.623c-2.91-1.178-7.578-3.368-10.253-3.957-2.676-0.588-8.113-0.68-8.113-0.68zm14.5-3.03s5.96-1.774 7.82-1.83c1.86-0.057 3.61 0.68 6.172 1.555 2.562 0.876 2.522 0.857 5.333 1.49 2.797 0.63 7.077 1.513 7.077 1.513s-3.616-0.016-6.792-0.466c-3.116-0.441-7.375-1.698-10.058-2.249-2.684-0.55-9.552-0.013-9.552-0.013z" enable-background="new"/>
-    <path d="M1099.2-279.93c.161.269 11.208-4.6 12.188-4.688.98-.087 2 3.125 2 3.125s-.775-1.504-2.875-1.062-11.301 2.671-11.312 2.625z"/>
-   </g>
-   <path d="M1107.5-284.09c-.419.213-.156.094-.647.306-.486.21-1.724.574-4.08 1.459-3.33 1.25-5.83 2.153-7.026 3.066-1.536.021-3.72.233-5.656.719a227.709 227.709 0 0 1-6.75 1.593c-1.895.42-1.676.643-2.875.875-1.297.252-1.721-.009-5.438.782-3.49.742-8.894 1.93-10.156 2.687-1.583-.18-3.867-.322-5.843-.031-3.04.447-4.917.673-6.844.906-.655.08-1.041.201-1.344.282-.426.131-.686.26-1.375.343-1.311.16-1.762-.157-5.531.282-3.554.413-9.005 1.272-10.25 1.937-1.599-.297-3.858-.534-5.844-.344-3.059.294-4.972.484-6.906.657-1.934.172-1.689.422-2.906.53-1.317.118-1.76-.163-5.532.25-3.541.39-9.007 1.21-10.28 1.876-1.6-.295-3.888-.507-5.876-.313-3.058.3-4.94.48-6.875.657-.657.06-1.04.178-1.343.25-.428.118-.684.218-1.375.28-1.316.121-1.76-.194-5.532.22-3.556.39-9.005 1.239-10.25
-1.906-1.598-.294-3.86-.524-5.843-.313-3.056.326-4.974.526-6.907.719-1.932.192-1.69.44-2.906.562-1.315.132-1.763-.164-5.53.282-3.54.418-8.979 1.292-10.25 1.969-1.599-.282-3.86-.42-5.845-.188-3.052.358-4.945.568-6.875.781-.656.073-1.04.173-1.344.25-.426.127-.684.267-1.375.344-1.313.146-1.767-.174-5.53.313-3.55.458-8.98 1.419-10.22 2.125-1.593-.245-3.834-.382-5.812-.125-3.048.394-4.95.648-6.875.906-1.925.258-1.726.493-2.938.656-1.31.176-1.747-.104-5.5.469-3.524.538-8.923 1.699-10.188 2.437-1.587-.203-3.845-.254-5.812.094-3.026.536-4.9.862-6.813 1.187-.65.111-1.013.271-1.312.375-.42.165-.664.332-1.344.47-1.295.26-1.727-.007-5.438.812-3.498.772-8.846 2.383-10.062 3.219-1.562-.078-3.757.085-5.687.593-2.972.783-4.818 1.232-6.688 1.75s-1.666.768-2.843 1.094c-1.273.353-1.697.107-5.344 1.188-3.425 1.014-8.65 2.933-9.875 3.843-1.539.013-3.72.273-5.625.875-2.931.928-4.75 1.459-6.594
-2.063-.627.205-.992.392-1.281.531-.408.214-.653.409-1.313.625-1.254.412-1.686.19-5.28 1.438-3.39 1.177-8.596 3.213-9.782 4.156-1.524.06-3.65.395-5.531 1.062-2.898 1.029-4.7 1.676-6.531 2.313-1.833.637-1.628.848-2.782 1.25-1.246.434-1.663.2-5.218 1.562-3.34 1.28-8.488 3.483-9.688 4.47-1.507.107-3.636.498-5.5 1.218a1044.752 1044.752 0 0 1-6.437 2.469c-.617.233-.997.442-1.282.593v1.094c.112-.222.386-.817.907-1.094.698-.37 4.813-1.993 6.812-2.718 1.657-.602 4.154-1.329 5.969-1.313.302.003.588.051.844.094 1.842.308 7.468 1.562 7.468 1.562s-6.233-1.646-7.03-1.843c-.191-.048-.536-.07-.97-.063 1.146-.87 4.762-2.393 7.344-3.437 2.839-1.148 3.117-1.252 5.063-1.657 2.008-.417 3.156-.5 3.156-.5s-.082-.6.969-1.125c.705-.351 4.887-1.892 6.906-2.562 1.952-.648 5.057-1.359 6.875-1 1.863.367 7.531 1.812 7.531 1.812s-6.287-1.87-7.094-2.093c-.193-.054-.53-.086-.968-.094 1.158-.833 4.794-2.195 7.406-3.156
-2.87-1.056 3.167-1.162 5.125-1.532 1.853-.35 2.859-.425 3.031-.437.114-.217.377-.81.906-1.063.71-.338 4.926-1.712 6.97-2.312 1.692-.497 4.24-1.037 6.093-.906.308.021.613.097.875.156 1.881.424 7.594 2.031 7.594 2.031s-6.342-2.065-7.157-2.312c-.194-.06-.557-.104-1-.125 1.17-.798 4.863-2.057 7.5-2.938 2.898-.968 3.233-1.003 5.22-1.281 2.049-.287 3.187-.313 3.187-.313s-.073-.607 1-1.062c.72-.306 4.99-1.5 7.062-2 2.003-.483 5.199-.928 7.063-.406 1.91.535 7.719 2.5 7.719 2.5s-6.423-2.424-7.25-2.72c-.198-.07-.583-.14-1.032-.187 1.188-.728 4.916-1.774 7.594-2.5 2.944-.797 3.292-.77 5.313-.906 1.913-.128 2.947-.07 3.125-.062.117-.204.391-.78.937-.97.732-.253 5.079-1.047 7.188-1.374 1.748-.271 4.4-.485 6.312-.094.318.065.605.186.875.281 1.94.69 7.844 3.094 7.844 3.094s-6.535-2.95-7.375-3.312c-.201-.087-.575-.167-1.031-.25 1.206-.633 5.03-1.396 7.75-1.906 2.99-.562 3.3-.53 5.344-.532 2.109-.002
-3.312.125 3.312.125s-.073-.63 1.031-.937c.74-.206 5.126-.834 7.25-1.063 2.053-.22 5.319-.252 7.22.47 1.947.738 7.843 3.374 7.843 3.374s-6.563-3.179-7.406-3.562c-.202-.092-.543-.187-1-.282 1.21-.602 4.984-1.248 7.718-1.656 3.005-.448 3.326-.452 5.375-.406 1.94.043 3.007.194 3.188.219.119-.194.384-.766.937-.907.743-.188 5.155-.734 7.282-.937 1.763-.169 4.42-.234 6.343.25.32.08.604.203.875.312 1.953.784 7.907 3.47 7.907 3.47s-6.592-3.254-7.438-3.657c-.202-.096-.572-.207-1.031-.313 1.214-.574 5.044-1.122 7.781-1.5 3.009-.415 3.323-.442 5.375-.375 2.118.07 3.313.25 3.313.25s-.078-.637 1.03-.906c.745-.18 5.153-.663 7.282-.844 2.059-.174 5.343-.124 7.25.657 1.955.8 7.875 3.53 7.875 3.53s-6.56-3.308-7.406-3.718c-.202-.098-.572-.203-1.031-.312 1.215-.564 5.01-1.115 7.75-1.47 3.01-.389 3.321-.397 5.375-.312 1.944.08 3.006.254 3.187.282.12-.191.383-.746.938-.875.744-.174 5.15-.65 7.28-.813
-1.767-.134 4.45-.126 6.376.375.32.083.603.201.875.313 1.954.8 7.906 3.562 7.906 3.562s-6.591-3.34-7.437-3.75c-.203-.098-.572-.203-1.032-.312 1.215-.564 5.042-1.084 7.782-1.438 3.01-.39 3.352-.429 5.406-.344 2.12.088 3.312.313 3.312.313s-.078-.65 1.032-.906c.744-.173 5.15-.624 7.28-.782 2.061-.152 5.344-.096 7.25.688 1.956.804 7.876 3.5 7.876 3.5s-6.56-3.276-7.406-3.688c-.203-.098-.572-.202-1.032-.312 1.216-.562 5.012-1.128 7.75-1.5 3.01-.41 3.323-.416 5.375-.344 1.943.068 3.008.165 3.188.188.119-.195.384-.73.937-.875.742-.197 5.131-.83 7.25-1.094 1.757-.22 4.406-.333 6.313.031.317.06.606.19.875.281 1.936.661 7.844 2.938 7.844 2.938s-6.537-2.807-7.375-3.156c-.2-.084-.577-.174-1.032-.25 1.204-.651 5.02-1.372 7.72-2 2.966-.69 3.288-.756 5.312-.875 2.088-.124 3.28-.032 3.28-.032s-.086-.632 1-1.03c.73-.269 5.048-1.339 7.126-1.813 2.008-.46 5.168-1.03 7-.625 1.878.414 13.578 3.015 13.578
-3.015s-12.328-3.022-13.141-3.265c-.195-.058-.559-.107-1-.125 1.167-.804 3.514-1.688 6.11-2.703 1.68-.659.923-.377 2.775-1.004 1.754-.594 2.486-1.01 2.63-1.113.347-.207-.355-.122-.544-.042z" enable-background="new" filter="url(#hs)" opacity=".25"/>
-   <path d="m1082.6-275.12c1.873 0.393 4.496 1.146 6.031 1.969s2.822 1.056 5.375 2.5c2.527 1.43 4.796 2.007 6.969 2.531 2.348 0.566 5.435 0.715 8.844 1.188-1.09-0.84-6.608-1.173-8.406-1.563-1.8-0.39-3.895-1.016-6.594-2.313-2.7-1.296-3.495-1.799-5.813-2.687-2.318-0.889-4.004-1.383-6.406-1.625z" enable-background="new" filter="url(#hr)" opacity=".25"/>
-   <path d="M1051.5-270c1.905.578 4.528 1.616 6.094 2.594 1.565.978 2.88 1.36 5.5 3.125 2.593 1.747 4.986 2.71 7.25 3.594 2.446.955 5.682 1.657 9.406 3.062-1.19-1.138-7.063-2.687-8.938-3.375-1.874-.688-4.081-1.566-6.874-3.281-2.794-1.715-3.574-2.284-5.938-3.406-2.364-1.123-4.057-1.835-6.5-2.313z" enable-background="new" filter="url(#hq)" opacity=".25"/>
-   <path d="m1020.2-266.84c1.912 0.638 4.581 1.755 6.156 2.813 1.575 1.057 2.896 1.508 5.531 3.406 2.61 1.878 5.029 3.03 7.313 4.062 2.468 1.116 5.764 2.174 9.531 3.844-1.203-1.222-7.203-3.314-9.094-4.125-1.89-0.81-4.064-1.894-6.874-3.75s-3.622-2.477-6-3.719c-2.379-1.242-4.111-1.975-6.563-2.531z" enable-background="new" filter="url(#hp)" opacity=".25"/>
-   <path d="M1110.2-266.89c.15.049.688.631.11 1.484-.81 1.195-5.705 3.325-8.563 4.125-2.845.798-6.29.978-10.562-.375-4.302-1.362-5.47-2.468-10.656-4.312 4.664 2.115 6.195 3.952 10.125 5.344 1.62.574 3.367.94 5.062 1.03-.445.327-1.53.984-3.562 1.595-2.796.84-6.65 1.534-8.25 1.625-1.515.086-3.142-.513-3.438-.625.167.103.374.377-.25 1.03-.899.945-6.147 1.924-9.125 2.25-2.964.326-6.521-.015-10.906-1.905-3.978-1.715-5.339-2.916-9.406-4.75v.156c3.643 2.095 5.284 3.883 8.875 5.562 1.73.81 3.592 1.41 5.406 1.72-.534.286-1.557.71-3.437 1.03-2.87.488-6.81.817-8.438.75-.85-.034-1.728-.184-2.406-.406-.685-.215-1.19-.444-1.312-.5.169.107.43.403-.22 1.031-.909.88-6.245 1.337-9.25 1.47-2.99.131-6.588-.451-11-2.563-4.44-2.127-5.64-3.402-10.905-5.782 4.734 2.597 6.286 4.63 10.344 6.72 1.673.861 3.485 1.493 5.25 1.937-.463.233-1.59.688-3.688.937-2.886.343-6.834.493-8.468.375-1.547-.111-3.232-.857-3.532-1
-.17.12.414.41-.218 1-.913.851-6.244 1.262-9.25 1.375-2.993.113-6.59-.49-11-2.594-4.002-1.908-5.388-3.137-9.47-5.093v.156c3.656 2.204 5.295 4.053 8.907 5.906 1.74.893 3.637 1.528 5.469 1.969-.54.248-1.578.615-3.469.844-2.886.348-6.866.52-8.5.406a9.446 9.446 0 0 1-2.406-.5 12.532 12.532 0 0 1-1.313-.531c.17.112.465.422-.187 1.03-.913.853-6.275 1.294-9.281 1.407-2.993.112-6.594-.528-11-2.594-4.437-2.08-5.647-3.331-10.906-5.656 4.729 2.548 6.29 4.578 10.344 6.625 1.671.844 3.485 1.467 5.25 1.906-.464.235-1.59.684-3.688.938-2.886.348-6.836.57-8.469.469-1.544-.096-3.2-.83-3.5-.97.17.12.382.405-.25 1-.912.861-6.246 1.331-9.25 1.47-2.99.138-6.567-.451-10.969-2.47-3.993-1.83-5.365-3.028-9.437-4.905v.156c3.647 2.133 5.27 3.935 8.875 5.719 1.737.86 3.607 1.45 5.437 1.875-.54.253-1.55.64-3.437.906-2.88.404-6.838.646-8.469.562a9.36 9.36 0 0 1-2.406-.437 12.971 12.971 0 0
-1-1.313-.5c.17.109.432.41-.218 1.031-.911.87-6.25 1.392-9.25 1.563-2.987.17-6.574-.316-10.97-2.282-4.424-1.978-5.605-3.228-10.843-5.375 4.71 2.388 6.27 4.39 10.312 6.344a23.73 23.73 0 0 0 5.218 1.781c-.461.25-1.597.713-3.687 1.032-2.876.438-6.78.733-8.406.687-1.539-.043-3.233-.745-3.532-.875.169.113.411.414-.218 1.031-.908.891-6.203 1.529-9.188 1.813-2.971.283-6.573-.176-10.938-1.938-3.96-1.598-5.329-2.795-9.344-4.312v.156c3.596 1.811 5.239 3.582 8.813 5.156 1.722.759 3.587 1.29 5.406 1.625-.536.28-1.566.688-3.437 1.063-2.856.572-6.79 1.02-8.407 1.031-.844.006-1.706-.08-2.375-.25-.676-.162-1.16-.33-1.28-.375.166.094.422.383-.22 1.062-.897.951-6.186 1.918-9.125 2.438-2.925.518-6.432.374-10.719-1.031-4.315-1.415-5.472-2.53-10.562-3.969 4.577 1.751 6.09 3.56 10.031 5 1.627.594 3.37.956 5.094 1.156-.453.297-1.555.884-3.594 1.469-2.804.805-6.638 1.576-8.218
-1.75-1.495.165-3.117-.317-3.407-.406.164.09.393.36-.218 1.062-.883 1.014-6.045 2.372-8.938 3.063-2.88.687-6.335.76-10.562-.438-3.835-1.086-5.172-2.072-9.062-3.125v.156c3.484 1.395 5.07 2.92 8.53 4.032 1.669.535 3.457.786 5.22.875-.52.352-1.5.914-3.313 1.53-2.765.942-6.59 1.936-8.156 2.157-.818.115-1.633.123-2.281.031-.655-.083-1.133-.218-1.25-.25.162.075.434.34-.188 1.094-.87 1.055-6.01 2.66-8.875 3.438-2.852.774-6.259.958-10.438-.094-4.206-1.06-5.356-2.042-10.344-3.156 4.485 1.46 5.97 3.135 9.813 4.25 1.585.46 3.287.638 4.969.687-.442.337-1.513 1.028-3.5 1.781-2.734 1.037-6.452 2.163-8 2.438-1.465.26-3.06-.117-3.344-.188.16.08.38.321-.219 1.063-.865 1.07-5.916 2.818-8.75 3.687-2.82.866-6.207 1.157-10.344.22-3.753-.852-5.048-1.717-8.875-2.595v.157c3.428 1.237 4.987 2.632 8.375 3.53 1.632.434 3.367.584 5.094.563-.51.384-1.477 1.022-3.25 1.75-2.706 1.112-6.436 2.308-7.969
-2.625-.8.166-1.612.219-2.25.157v1.406c.227-.145.449-.273.719-.375 1.08-.41 2.171-.216 6-1.688 3.828-1.471 5.224-2.005 5.906-2.406.68-.4 1.612-.88 2.219-1.531 1.827-.138 3.57-.493 4.937-1 2.968-1.1 4.876-1.806 6.782-2.469 1.905-.663 2.354-1.415 3.406-1.781 1.091-.38 2.195-.166 6.062-1.531 3.868-1.366 5.283-1.827 5.969-2.22.701-.4 1.7-.932 2.313-1.593 1.97-.055 3.816-.385 5.28-.875 3.002-1.005 4.927-1.622 6.845-2.25 1.538-.504 2.174-1.047 2.906-1.437.23-.135.475-.254.75-.344 1.098-.36 2.181-.082 6.094-1.313 3.912-1.23 5.366-1.673 6.062-2.03.694-.358 1.63-.794 2.25-1.407 1.865-.023 3.636-.267 5.031-.688 3.03-.913 4.993-1.43 6.938-1.968 1.945-.54 2.426-1.265 3.5-1.563 1.114-.31 2.22.007 6.187-1.031 3.968-1.039 5.418-1.433 6.125-1.75.735-.33 1.814-.754 2.438-1.375 1.997.116 3.857-.02 5.344-.375 3.078-.735 5.083-1.101 7.062-1.5 1.588-.32 2.244-.79 3-1.094.238-.107.467-.193.75-.25 1.134-.23
-2.305.209 6.344-.5s5.5-.927 6.219-1.187c.715-.26 1.704-.568 2.343-1.094 1.925.24 3.748.224 5.188 0 3.126-.488 5.155-.7 7.156-.969 2.002-.268 2.489-.945 3.594-1.094 1.146-.154 2.276.302 6.344-.219 4.068-.52 5.56-.695 6.28-.937.738-.247 1.799-.586 2.438-1.125 2.05.335 3.974.398 5.5.219 3.143-.37 5.18-.56 7.188-.782 1.61-.178 2.265-.608 3.031-.843a3.43 3.43 0 0 1 .781-.188c1.15-.128 2.302.347 6.375-.125s5.56-.61 6.282-.844c.719-.232 1.7-.473 2.343-.968 1.937.333 3.77.404 5.22.25 3.145-.335 5.177-.519 7.187-.719 2.01-.2 2.484-.826 3.593-.938 1.152-.115 2.297.366 6.375-.062s5.59-.562 6.313-.781c.74-.224 1.796-.514 2.437-1.031 2.058.398 4.002.493 5.532.343 3.148-.308 5.175-.473 7.187-.656 1.614-.147 2.263-.56 3.031-.781.242-.081.494-.13.782-.156 1.152-.106 2.293.392 6.375 0 4.082-.393 5.589-.531 6.312-.75.721-.219 1.7-.448 2.344-.938 1.938.35 3.769.454 5.219.313 3.148-.309 5.175-.474
-7.187-.657 2.012-.183 2.514-.838 3.625-.937 1.152-.103 2.292.385 6.375 0s5.589-.501 6.313-.719c.739-.222 1.795-.514 2.437-1.031 2.057.402 4.003.503 5.531.344 3.147-.329 5.178-.523 7.188-.72 1.613-.156 2.266-.63 3.031-.874.24-.088.463-.122.75-.156 1.148-.14 2.317.34 6.375-.25 4.058-.59 5.562-.778 6.281-1.032.717-.253 1.675-.558 2.313-1.093 1.92.211 3.72.151 5.156-.094 3.12-.533 5.112-.929 7.094-1.313 1.982-.384 2.474-1.04 3.562-1.28 1.13-.252 2.27.115 6.25-.876s5.43-1.42 6.125-1.781c.723-.376 1.762-.87 2.375-1.531 1.963-.012 3.794-.291 5.22-.844 2.95-1.145 4.872-1.87 6.687-2.75 1.455-.707 2.334-1.686 2.547-1.984.212-.298.111-.746.137-.767.043-.035.32-.085.48-.429.858-1.847 2.32-5.644
-2.435-6.329.113-.682.163-1.348.214-1.745.03-.23-.147-.865-.125-.924.031-.082.305-.265.36-.515.267-1.198.09-2.191-.125-3.609-.214-1.417-.983-4.622-1.637-5.476-.659-.862-1.223-1.011-1.748-1-.208.27.137.262.163.312.68.05.934.369 1.42.897s1.221 3.85 1.358 5.301.19 2.86-.088 3.469c-.278.608-.723.517-1.016.583.531.186.67.125.732.969.058.813-.134 1.64-.52 2.806-.392 1.18-1.846 4.35-2.286 4.598-.452.256-.731.27-1.067.14z" enable-background="new" filter="url(#ho)" opacity=".25"/>
-   <path d="m988.75-263.84c1.912 0.634 4.55 1.758 6.125 2.813 1.575 1.054 2.896 1.482 5.531 3.375 2.609 1.873 5.027 3.015 7.313 4.062 2.47 1.132 5.752 2.155 9.531 3.938-1.207-1.259-7.139-3.365-9.031-4.188s-4.128-1.93-6.938-3.781-3.622-2.482-6-3.719c-2.377-1.237-4.08-1.95-6.53-2.5z" enable-background="new" filter="url(#hn)" opacity=".25"/>
-   <path d="M957.5-260.78c1.91.618 4.583 1.71 6.156 2.75 1.574 1.04 2.896 1.482 5.531 3.375 2.609 1.873 5.027 3.015 7.313 4.063 2.47 1.131 5.752 2.154 9.531 3.937-1.207-1.258-7.201-3.396-9.094-4.219-1.892-.823-4.096-1.93-6.906-3.781-2.81-1.85-3.593-2.44-5.969-3.656s-4.113-1.939-6.562-2.469z" enable-background="new" filter="url(#hm)" opacity=".25"/>
-   <path d="M926.09-257.38c1.908.597 4.553 1.664 6.125 2.688 1.571 1.023 2.87 1.44 5.5 3.28 2.603 1.823 5.029 2.973 7.313 4 2.467 1.111 5.755 2.094 9.53 3.845-1.205-1.249-7.171-3.319-9.062-4.125s-4.102-1.891-6.906-3.688c-2.804-1.796-3.627-2.402-6-3.594-2.373-1.191-4.054-1.903-6.5-2.406z" enable-background="new" filter="url(#hl)" opacity=".25"/>
-   <path d="M894.91-253.56c1.902.554 4.587 1.589 6.156 2.594s2.874 1.408 5.5 3.219c2.6 1.791 5 2.871 7.281 3.875 2.465 1.083 5.76 2.04 9.532 3.75-1.205-1.236-7.175-3.245-9.063-4.032-1.888-.786-4.075-1.83-6.875-3.593s-3.6-2.369-5.969-3.532c-2.37-1.163-4.123-1.834-6.562-2.28z" enable-background="new" filter="url(#hk)" opacity=".25"/>
-   <path d="M863.72-248.66c1.88.43 4.504 1.38 6.063 2.313 1.558.932 2.852 1.257 5.468 3 2.59 1.724 4.981 2.708 7.25 3.625 2.452.99 5.74 1.877 9.5 3.5-1.201-1.208-7.152-3.067-9.03-3.782-1.88-.715-4.086-1.684-6.876-3.375s-3.585-2.228-5.937-3.28-4.026-1.713-6.438-2z" enable-background="new" filter="url(#hj)" opacity=".25"/>
-   <path d="m833.16-241.38c1.848 0.296 4.47 0.976 6 1.781s2.814 1.056 5.375 2.531c2.535 1.46 4.89 2.326 7.125 3.063 2.414 0.797 5.657 1.467 9.375 2.844-1.188-1.129-7.088-2.59-8.938-3.156-1.85-0.567-4.003-1.374-6.75-2.844-2.746-1.47-3.5-1.92-5.812-2.781-2.311-0.861-4.005-1.32-6.375-1.438z" enable-background="new" filter="url(#hi)" opacity=".25"/>
-   <path d="m802.91-232.31c1.822 0.211 4.366 0.8 5.875 1.531 1.51 0.73 2.756 0.93 5.281 2.281 2.5 1.338 4.832 2.049 7.031 2.657 2.377 0.656 5.565 1.073 9.22 2.187-1.168-1.045-6.93-2.103-8.75-2.562-1.822-0.46-3.953-1.127-6.657-2.438s-3.471-1.72-5.75-2.469-3.913-1.179-6.25-1.187z" enable-background="new" filter="url(#hh)" opacity=".25"/>
-   <path d="M773.19-222.19c1.811.179 4.32.665 5.813 1.344 1.491.678 2.753.798 5.25 2.062 2.47 1.252 4.79 1.896 6.968 2.438 2.354.585 5.492.897 9.094 1.844-1.15-.992-6.852-1.784-8.656-2.188s-3.916-1.021-6.594-2.25c-2.678-1.229-3.403-1.61-5.656-2.281-2.253-.67-3.896-1.002-6.219-.969z" enable-background="new" filter="url(#hg)" opacity=".25"/>
-   <path d="M743.56-211.19c1.793.13 4.273.55 5.75 1.188s2.716.741 5.188 1.937c2.446 1.184 4.72 1.747 6.874 2.219 2.328.51 5.42.68 9 1.562-1.143-.97-6.747-1.59-8.53-1.937-1.784-.347-3.884-.888-6.532-2.031-2.648-1.144-3.395-1.517-5.625-2.125-2.23-.61-3.826-.91-6.125-.813z" enable-background="new" filter="url(#hf)" opacity=".25"/>
-  </g>
- </g>
- <path d="M912.45 671.2c1.642-3.218 3.518-5.735 4.861-9.849.8-3.658 3.312-2.03 7.26-8.397 1.403-2.24 5.477.391 8.966-2.399 1.27-.803 2.885-.404 4.483-.063 3.765 1.319 5.825 3.704 8.333 5.808 6.14 5.97 20.534 7.944 23.486 6.314 1.434-2.905 7.882-5.41 12.374-11.112.749-1.123 11.73-8.745 14.647-6.566" enable-background="new" fill="none" stroke="#000"/>
- <path d="M937.07 660.78c7.363-3.233 13.811-8.908 20.708-13.385 3.31-1.97 6.87 3.216 10.796 3.599 2.298-.218 3.713 1.202 5.682 1.641 5.157 1.318 2.398 3.865 9.975 6.44 6.156 1.72 8.908-6.799 14.9-7.324 4.878-.503 8.1-.316 11.617-.252 3.927.139 4.079-3.498 6.061-5.304 2.98-2.805 7.156-1.85 10.145-4.74 1.018-1.385 1.955-3.011 2.735-5.109.882-2 3.04.306 4.798 1.263" enable-background="new" fill="none" stroke="#000"/>
- <g fill-rule="evenodd">
-  <path transform="translate(48.571 195.53)" d="m403.28 1056.3l56.569-42.426 72.125 14.142-46.669 52.326-53.74 7.071-28.284-31.113z" enable-background="accumulate" filter="url(#he)" opacity=".25"/>
-  <path d="m590.84 1256.1c-1.407 18.801-1.145 32.751 2.082 49.303 3.226 16.552 16.406 45.907 20.334 63.184 3.926 17.267 2.694 38.31-12.46 51.148-15.317 12.977-42.05 21.599-67.831 15.734s-69.55-49.223-88.59-70.228c-19.112-21.083-63.761-93.851-77.94-124.28-14.177-30.425-12.66-36.719-8.119-45.53-9.367-24.52-12.414-50.067-33.712-75.577 30.325 3.114 43.88 26.956 60.126 47.14-5.53-48.076-18.055-64.416-28.374-90.724 29.994 6.082 50.579 31.872 63.98 72.712 9.554-3.918 18.238-9.373 30.187-9.061-11.298-41.696-17.949-69.916-36.687-101.07 53.442 5.67 83.657 80.639 78.971 87.96 9.978-2.243 19.006-6.53 30.437-5.65-11.249-38.348-21.048-76.869-3.66-118.65 0 0 48.287 65.436 54.39 85.805 6.103 20.37 1.52 38.701 1.52 38.701s16.96 31.085 20.293 51.094c3.373 20.241-3.533 59.103-4.946 77.983z" enable-background="new" fill="#ada469"/>
-  <path transform="matrix(-.90453 .25066 .25066 .90453 1043.9 219.06)" d="M719.5 738.7l18.312 15.432 44.411-15.388L805.5 713.2l11.464 19.221 30.672 12.784 25.097 5.728L892 723.2l16.023 23.826L947 752.2l10.245-6.198L964 754.7l25.5 11 2-40.5-35.551-14.538-32.493-21.527-40.452-11.466-21.307-15.533L840 685.2l-84.971-46.583-33.03 38.083-2.5 62z" clip-path="url(#e)" enable-background="accumulate" fill="#fff" filter="url(#o)"/>
-  <path transform="matrix(-.90453 .25066 .25066 .90453 870.86 206.47)" d="M584 696.5l-6.563 17.156s-7.811 20.365-15.688 43.656c-3.938 11.646-7.883 24.041-10.938 35.125s-5.335 20.38-5.5 28.281c-.398 19.162 5.747 34.888 8.938 41.75-.772 3.555-1.991 9.454-3.344 18.094-1.92 12.268-3.718 27.154-2.375 39.875 1.382 13.088 6.812 28.188 12.594 43.031s12.054 29.227 15.22 38.031c6.631 18.452 9.992 31.576 11.311 48.5.582 7.456-.242 20.336-1.25 33.375s-2.186 26.301-1.687 36.969c.989 21.14 9.328 46.835 33.375 57.937 22.775 10.515 55.327 11.702 83.438-3.437 16.16-8.704 30.076-27.098 43.375-46.906s24.969-41.053 31.938-54.906c15.353-30.521 39.394-115.46 45.625-152.72 3.018-18.047 3.921-29.066 2.625-38.031-.979-6.766-3.828-12.147-6.875-16.22 2.042-27.507-.732-51.368 11.969-79.405l10.562-23.281-23.812 9.312c-17.49 6.838-28.902 19.045-36.594 32.062-.323.546-.563 1.108-.875 1.656.222-22.515 4.408-37.638
-6.594-58.688l1.968-19-17.03 8.656c-30.595 15.556-45.696 48.193-49.72 90.22-4.245-.626-8.831-1.02-13.812-.844-.291-39.18-.396-67.037 8.594-99.375l5.594-20.125-19.438 7.656c-30.91 12.204-47.86 41.931-56.625 68.375-4.383 13.222-6.746 25.801-7.594 35.938a92.19 92.19 0 0 0-.312 7.719c-3.242-.037-6.42.136-10.062.5.041-39.005-3.485-79.754-32.281-116.5L584 696.498zm5.813 43.812c16.807 30.644 17.475 63.967 16.938 99.75l-.22 15.062 12.036-6.54c8.662-3.132 19.56-.227 31.934-.835l14.675 9.357-6.331-25.794c-.09-.23-.22-.417-.25-.72-.2-2.039-.222-5.472.125-9.624.694-8.304 2.79-19.585 6.625-31.156 5.155-15.553 13.488-31.192 25.125-42.531-4.684 28.638-3.216 60.259-3.012 95.805l-2.766 13.262 15.496-7.598c9.03-2.758 17.19-.35 29.281 1.094l13.246 9.444L741.094 840c1.448-30.972 8.222-53.678 20.719-68.875-2.987 19.779-5.43 41.785.313 78.344l1.065 6.373-2.938 11.517 10.617-8.168 9.19 10.222-1.549-10.464
-3.427-6.95c5.7-13.21 10.173-26.212 16.344-36.655.96-1.624 2.031-3.065 3.062-4.563-3.68 21.155-2.427 40.208-4.093 57.781l-4.68 7.807 7.398.225c3.22 3.483 3.868 3.85 4.563 8.656s.318 14.4-2.563 31.625c-5.568 33.288-31.846 77.84-43.74 101.49-6.605 13.13-18.528 57.486-31.123 76.246s-28.53 39.767-37.172 44.42c-21.49 11.575-44.556 25.507-60.619 18.09-14.375-6.636-23.04-21.192-23.814-37.742-.383-8.188.613-21.31 1.625-34.406 1.013-13.097 11.29-22.571 15.423-36.563 5.373-18.181-1.447-36.594-12.5-53.937-6.486-10.178-23.977-24.258-29.548-38.562s-10.368-29.003-11.28-37.656c-.927-8.771.422-23.025 2.218-34.5 1.796-11.475 3.844-20.281 3.844-20.281l9.423-3.615-10.485-3.885s-8.5-15.31-8.094-34.812c.071-3.423 1.836-12.728 4.719-23.188s6.764-22.553 10.625-33.97c3.044-9.002 5.78-16.602 8.344-23.687z" clip-path="url(#am)" enable-background="new" filter="url(#ds)" opacity=".588"/>
-  <g transform="translate(324.57 331.53)" clip-path="url(#is)" enable-background="new" fill="#fff">
-   <path transform="matrix(-.90453 .25066 .25066 .90453 -52.2 74.097)" d="m-15.668 843.49l-49.497-15.556-26.87 52.326 41.012 45.255 49.497-38.184z" enable-background="accumulate" filter="url(#dr)"/>
-   <path transform="matrix(-.90453 .25066 .25066 .90453 -46.928 75.511)" d="m118.71 859.93l-55.154-46.669-43.841 36.77 33.941 53.74-13.597 85.462-39.445 28.292-41.012 11.314-2.828 46.669 56.569 25.456 18.944-69.65 23.457-58.857 46.348-72.615 16.62-39.912z" enable-background="accumulate" filter="url(#dq)"/>
-  </g>
-  <path transform="matrix(-.90453 .25066 .25066 .90453 277.64 407.04)" d="m-70.822 932.58l60.811-26.87 100.41 31.113-63.64 31.113-82.024-16.971-15.556-18.385z" enable-background="accumulate" filter="url(#cy)" opacity=".25"/>
-  <path transform="matrix(-.90453 .25066 .25066 .90453 870.86 206.47)" d="M583.06 715.75c-12.106 34.45-26.714 68.533-31.75 104.84-.832 14.929 4.59 29.159 8.844 43.062-5.916 27.201-10.137 56.9 1.156 83.125 13.517 38.161 35.001 75.682 32.423 117.47-.948 29.294-9.014 60.994 5.39 88.282 10.199 19.335 33.14 27.312 53.968 27.668 27.862 1.174 56.463-11.622 72-35.261 22.596-29.372 41.802-61.497 55.24-96.06 16.89-45.506 29.672-92.561 37.934-140.4 1.824-12.941 3.1-27.47-4.58-38.823-3.43-7.336.043-15.56-.684-23.31.674-24.995 4.013-50.664 16.653-72.596-17.733 6.445-35.073 16.56-44.003 33.864-3.935 6.71-7.605 13.574-11.372 20.386-3.55-30.014 3.72-59.648 6.781-89.281-20.166 9.055-36.877 25.655-44.175 46.682-6.304 15.58-8.802 32.317-10.263 49.037-8.253-1.52-16.684-2.102-25.062-1.5-.963-38.698-.467-79.407 10.97-115.91-18.682 6.218-35.167 18.736-45.629 35.387-13.853 20.88-21.26 45.754-23.059 70.613.586
-4.325-.06 11.84-6.343 9.875-5.332.018-10.63.679-15.938 1.094 1.147-39.381-3.342-81.628-27.062-114.22-3.061-3.637-5.637-7.685-8.625-11.344l-2.813 7.312zm7.75 13.844c18.565 29.296 22.482 64.82 22.125 98.875.204 5.175-.517 11.829.125 16.062 12.319-6.103 26.739-2.44 39.781-2.187 2.317 1.223 3.192 1.652 1.906-1.407-4.164-13.953-1.848-28.613 1.805-42.408 6.367-26.29 20.628-51.088 42.82-67.03-8.617 37.237-5.716 76.562-6.094 113.97 12.253-6.91 27.28-3.446 40.031-.25 3.393 3.535 2.29-.73 2.188-3.812-.483-21.371 4.131-43.07 13.688-62.156 5.963-10.687 14.243-19.804 22.438-28.875-7.872 33.838-9.203 69.336-2.719 103.5 1.725-1.411 4.607-.454 5.656-.375 9.684-21.237 16.351-45.381 34.89-60.742 1.874-.371-1.448 8.525-1.484 11.898-3.535 21.846-7.175 44.142-8.784 66.219-8.784 2.342 2.849 2.323 3.469 4.062 7.923 10.566 4.663 24.405 3.632 36.353-7.064 45.034-22.142 87.362-35.954 130.68-12.075 32.95-27.374
-58.852-47.888 87.202-10.953 13.551-23.245 27.851-40.844 32.5-20.156 6.242-44.207 10.877-62.6.046-17.29-12.34-21.024-35.709-19.262-55.686.048-15.826 4.938-28.512 4.41-43.492-.538-15.263-2.291-30.565-6.542-46.866-4.252-16.302-9.044-24.918-16.12-41.573-7.24-17.045-15.07-36.749-18.204-56.288-1.75-18.627 2.891-37.123 5.78-55.25 3.297-2.837-1.597-5.196-2.312-8.187-7.6-17.015-8.407-36.775-2.742-54.56 7.13-25.072 15.761-49.632 24.68-74.128l2.125 3.906z" clip-path="url(#cj)" enable-background="new" filter="url(#ir)" opacity=".588"/>
-  <path transform="matrix(-.90453 .25066 .25066 .90453 1043.9 219.06)" d="m735.06 733.04l2.755 21.089 44.411-15.388 4.851-22.39-3.936-22.052-22.452-36.593-8.28 30.305-17.35 45.029z" clip-path="url(#e)" enable-background="accumulate" fill="#fff" filter="url(#bz)"/>
-  <path transform="matrix(-.90453 .25066 .25066 .90453 1043.9 219.06)" d="m831.81 730.29l15.822 14.905 20.855 2.9-1.59-39.926 8.325-30.508-7.165-6.341-21.697 20.942-14.55 38.028z" clip-path="url(#e)" enable-background="accumulate" fill="#fff" filter="url(#by)"/>
- </g>
- <g transform="translate(324.57 331.53)" clip-path="url(#iq)" enable-background="new" filter="url(#ip)">
-  <path d="M36.494 811.806l-14.799 11.372-17.47-31.162 14.663.65 17.606 19.14z" enable-background="accumulate" fill="#fff" fill-rule="evenodd"/>
-  <path d="M-55 757.2h182v177H-55z" enable-background="accumulate" fill="none"/>
- </g>
- <g transform="translate(324.57 331.53)" clip-path="url(#io)" enable-background="new" filter="url(#in)">
-  <path d="m83.111 790.72l-28.201 12.855-5.658-21.687-13.943-25.046 6.325-6.88 26.384 18.51 15.094 22.249z" enable-background="accumulate" fill="#fff" fill-rule="evenodd"/>
-  <path d="M-22 696.2h165v176H-22z" enable-background="accumulate" fill="none"/>
- </g>
- <g fill-rule="evenodd">
-  <path d="m1084.8 1267.3c6.794 18.903 10.494 33.3 11.89 51.212 1.397 17.912-3.783 51.801-2.9 70.656 0.881 18.845 8.133 40.099 27.345 48.969 19.419 8.966 49.319 10.211 74.12-3.146 24.8-13.357 57.4-70.326 70.973-97.309 13.624-27.084 38.761-114.5 44.661-149.77s2.551-41.3-4.617-49.055c2.64-27.84-1.5-54.935 13.11-87.186-30.249 11.826-37.382 40.161-48.319 65.505-8-50.933 0.21-71.273 3.319-101.22-29.065 14.778-42.862 47.114-45 92.857-10.924-1.304-21.391-4.434-33.571-0.714-0.264-46.023-1.464-76.889 8.91-114.21-53.254 21.027-62.946 106.59-56.053 112.78-10.883 0.535-21.371-1.297-32.857 2.857 0.638-42.57-0.26-84.909-30-122.86 0 0-30.958 80.922-31.43 103.57-0.47 22.65 9.452 40.166 9.452 40.166s-8.568 36.741-6.298 58.232c2.295 21.741 20.443 59.676 27.266 78.658z" enable-background="new" fill="#ada469"/>
-  <path transform="translate(324.57 331.53)" d="M719.5 738.7l18.312 15.432 44.411-15.388L805.5 713.2l11.464 19.221 30.672 12.784 25.097 5.728L892 723.2l16.023 23.826L947 752.2l10.245-6.198L964 754.7l25.5 11 2-40.5-35.551-14.538-32.493-21.527-40.452-11.466-21.307-15.533L840 685.2l-84.971-46.583-33.03 38.083-2.5 62z" clip-path="url(#e)" enable-background="accumulate" fill="#fff" filter="url(#o)"/>
-  <path transform="translate(498.6 269.37)" d="M584 696.5l-6.563 17.156s-7.811 20.365-15.688 43.656c-3.938 11.646-7.883 24.041-10.938 35.125s-5.335 20.38-5.5 28.281c-.398 19.162 5.747 34.888 8.938 41.75-.772 3.555-1.991 9.454-3.344 18.094-1.92 12.268-3.718 27.154-2.375 39.875 1.382 13.088 6.812 28.188 12.594 43.031s12.054 29.227 15.22 38.031c6.631 18.452 9.992 31.576 11.311 48.5.582 7.456-.242 20.336-1.25 33.375s-2.186 26.301-1.687 36.969c.989 21.14 9.328 46.835 33.375 57.937 22.775 10.515 55.327 11.702 83.438-3.437 16.16-8.704 30.076-27.098 43.375-46.906s24.969-41.053 31.938-54.906c15.353-30.521 39.394-115.46 45.625-152.72 3.018-18.047 3.921-29.066 2.625-38.031-.979-6.766-3.828-12.147-6.875-16.22 2.042-27.507-.732-51.368 11.969-79.405l10.562-23.281-23.812 9.312c-17.49 6.838-28.902 19.045-36.594 32.062-.323.546-.563 1.108-.875 1.656.222-22.515 4.408-37.638 6.594-58.688l1.968-19-17.03
-8.656c-30.595 15.556-45.696 48.193-49.72 90.22-4.245-.626-8.831-1.02-13.812-.844-.291-39.18-.396-67.037 8.594-99.375l5.594-20.125-19.438 7.656c-30.91 12.204-47.86 41.931-56.625 68.375-4.383 13.222-6.746 25.801-7.594 35.938a92.19 92.19 0 0 0-.312 7.719c-3.242-.037-6.42.136-10.062.5.041-39.005-3.485-79.754-32.281-116.5L584 696.498zm5.813 43.812c16.807 30.644 17.475 63.967 16.938 99.75l-.22 15.062 12.036-6.54c8.662-3.132 19.56-.227 31.934-.835l14.675 9.357-6.331-25.794c-.09-.23-.22-.417-.25-.72-.2-2.039-.222-5.472.125-9.624.694-8.304 2.79-19.585 6.625-31.156 5.155-15.553 13.488-31.192 25.125-42.531-4.684 28.638-3.216 60.259-3.012 95.805l-2.766 13.262 15.496-7.598c9.03-2.758 17.19-.35 29.281 1.094l13.246 9.444L741.094 840c1.448-30.972 8.222-53.678 20.719-68.875-2.987 19.779-5.43 41.785.313 78.344l1.065 6.373-2.938 11.517 10.617-8.168 9.19 10.222-1.549-10.464 3.427-6.95c5.7-13.21
-10.173-26.212 16.344-36.655.96-1.624 2.031-3.065 3.062-4.563-3.68 21.155-2.427 40.208-4.093 57.781l-4.68 7.807 7.398.225c3.22 3.483 3.868 3.85 4.563 8.656s.318 14.4-2.563 31.625c-5.568 33.288-31.793 123.17-43.688 146.81-6.605 13.13-18.03 33.896-30.625 52.656s-27.359 35.534-36 40.187c-21.49 11.574-48.78 10.26-64.844 2.844-14.375-6.637-20.538-23.45-21.312-40-.383-8.188.613-21.31 1.625-34.406 1.013-13.097 11.29-22.571 15.423-36.563 5.373-18.181-1.447-36.594-12.5-53.937-6.486-10.178-23.977-24.258-29.548-38.562s-10.368-29.003-11.28-37.656c-.927-8.771.422-23.025 2.218-34.5 1.796-11.475 3.844-20.281 3.844-20.281l9.423-3.616-10.485-3.884s-8.5-15.31-8.094-34.812c.071-3.424 1.836-12.728 4.719-23.188s6.764-22.553 10.625-33.97c3.044-9.002 5.78-16.602 8.344-23.687z" clip-path="url(#am)" enable-background="new" filter="url(#ds)" opacity=".588"/>
-  <g transform="translate(324.57 331.53)" clip-path="url(#im)" fill="#fff">
-   <path d="m824.49 818.48l-49.497-15.556-26.87 52.326 41.012 45.255 49.497-38.184z" enable-background="accumulate" filter="url(#dr)"/>
-   <path d="m964.49 855.25l-55.154-46.669-43.841 36.77 33.941 53.74 7.071 66.468-50.912 35.355-41.012 11.314-2.828 46.669 56.569 25.456 63.64-76.368 24.042-94.752 8.485-57.983z" enable-background="accumulate" filter="url(#dq)"/>
-  </g>
-  <path transform="translate(48.571 195.53)" d="m1045.3 1043.6l60.811-26.87 100.41 31.113-63.64 31.113-82.024-16.971-15.556-18.385z" enable-background="accumulate" filter="url(#cy)" opacity=".25"/>
-  <path transform="translate(498.6 269.37)" d="M583.06 715.75c-12.106 34.45-26.714 68.533-31.75 104.84-.832 14.929 4.59 29.159 8.844 43.062-5.916 27.201-10.137 56.9 1.156 83.125 13.517 38.161 35.001 75.682 32.423 117.47-.948 29.294-9.014 60.994 5.39 88.282 10.199 19.335 33.14 27.312 53.968 27.668 27.862 1.174 56.463-11.622 72-35.261 22.596-29.372 41.802-61.497 55.24-96.06 16.89-45.506 29.672-92.561 37.934-140.4 1.824-12.941 3.1-27.47-4.58-38.823-3.43-7.336.043-15.56-.684-23.31.674-24.995 4.013-50.664 16.653-72.596-17.733 6.445-35.073 16.56-44.003 33.864-3.935 6.71-7.605 13.574-11.372 20.386-3.55-30.014 3.72-59.648 6.781-89.281-20.166 9.055-36.877 25.655-44.175 46.682-6.304 15.58-8.802 32.317-10.263 49.037-8.253-1.52-16.684-2.102-25.062-1.5-.963-38.698-.467-79.407 10.97-115.91-18.682 6.218-35.167 18.736-45.629 35.387-13.853 20.88-21.26 45.754-23.059 70.613.586 4.325-.06 11.84-6.343
-9.875-5.332.018-10.63.679-15.938 1.094 1.147-39.381-3.342-81.628-27.062-114.22-3.061-3.637-5.637-7.685-8.625-11.344l-2.813 7.312zm7.75 13.844c18.565 29.296 22.482 64.82 22.125 98.875.204 5.175-.517 11.829.125 16.062 12.319-6.103 26.739-2.44 39.781-2.187 2.317 1.223 3.192 1.652 1.906-1.407-4.164-13.953-1.848-28.613 1.805-42.408 6.367-26.29 20.628-51.088 42.82-67.03-8.617 37.237-5.716 76.562-6.094 113.97 12.253-6.91 27.28-3.446 40.031-.25 3.393 3.535 2.29-.73 2.188-3.812-.483-21.371 4.131-43.07 13.688-62.156 5.963-10.687 14.243-19.804 22.438-28.875-7.872 33.838-9.203 69.336-2.719 103.5 1.725-1.411 4.607-.454 5.656-.375 9.684-21.237 16.351-45.381 34.89-60.742 1.874-.371-1.448 8.525-1.484 11.898-3.535 21.846-3.297 44.173-4.906 66.25-1.312 1.377 2.849 2.323 3.469 4.062 7.923 10.566 3.123 24.831 2.092 36.78-7.064 45.034-21.766 88.38-35.577 131.7-12.075 32.95-30.72 63.08-51.234 91.43-10.953
-13.55-23.245 27.85-40.844 32.5-20.156 6.24-43.576 5.174-61.97-5.657-17.29-12.34-21.023-35.709-19.261-55.686.048-15.826 2.372-27.8 7.917-42.805s2.471-31.332-1.78-47.633-12.18-26.26-21.822-42.204-17.637-36.037-20.772-55.577c-1.75-18.627 2.892-37.123 5.781-55.25 3.296-2.837-1.598-5.196-2.312-8.187-7.602-17.015-8.408-36.775-2.743-54.56 7.13-25.072 15.761-49.632 24.68-74.128l2.125 3.906z" clip-path="url(#cj)" enable-background="new" filter="url(#il)" opacity=".588"/>
-  <path transform="translate(324.57 331.53)" d="m735.06 733.04l2.755 21.089 44.411-15.388 4.851-22.39-3.936-22.052-22.452-36.593-8.28 30.305-17.35 45.029z" clip-path="url(#e)" enable-background="accumulate" fill="#fff" filter="url(#bz)"/>
-  <path transform="translate(324.57 331.53)" d="m831.81 730.29l15.822 14.905 20.855 2.9-1.59-39.926 8.325-30.508-7.165-6.341-21.697 20.942-14.55 38.028z" clip-path="url(#e)" enable-background="accumulate" fill="#fff" filter="url(#by)"/>
- </g>
- <g transform="translate(324.57 331.53)" clip-path="url(#ik)" filter="url(#ij)">
-  <path d="M910.14 746.31l32.613 5.174-.361-23.876 7.188-29.682-8.45-5.264-21.823 26.511-9.167 27.137z" enable-background="accumulate" fill="#fff" fill-rule="evenodd"/>
-  <path d="M877.52 650.19h123.04v172.53H877.52z" enable-background="accumulate" fill="none"/>
- </g>
- <g transform="translate(324.57 331.53)" clip-path="url(#ii)" filter="url(#ih)">
-  <path d="M964 754.69l18.429 7.465 9.071-36.964-14.87 4.839L964 754.69z" enable-background="accumulate" fill="#fff" fill-rule="evenodd"/>
-  <path d="M924.9 677.06h142.13v125.16H924.9z" enable-background="accumulate" fill="none"/>
- </g>
- <g stroke-miterlimit="1">
-  <path d="m596.57 400.85h440v376h-440z" fill="none" stroke="#f8d615" stroke-width="18"/>
-  <path d="m104.57 248.85h1684v1292h-1684z" fill="none" stroke="#f83615" stroke-width="18"/>
-  <path d="M3407.4 296.46h522.57v1182.5H3407.4z" fill="url(#ig)" stroke="#f815bb" stroke-width="13.347"/>
- </g>
- <g transform="matrix(1.0057 0 0 2.3995 3452.3 -18.515)" clip-path="url(#if)" enable-background="new">
-  <g filter="url(#aq)">
-   <g transform="translate(-174.03 62.156)" filter="url(#g)">
-    <path d="m1268.3 663.77s-0.296 26.161 4.643 37.857 20.038 26.487 28.572 31.429 18.929 8.571 18.929 8.571l117.86-115 17.857-75.714-96.43 38.571-91.428 74.286z" enable-background="new" fill="#fff" fill-rule="evenodd"/>
-    <path d="M1197.8 486.14h333.75v309.71H1197.8z" enable-background="accumulate" fill="none"/>
-   </g>
-  </g>
-  <g transform="translate(-174.03 62.156)" enable-background="new" filter="url(#g)" opacity=".18">
-   <path d="m1268.3 663.77s-0.296 26.161 4.643 37.857 20.038 26.487 28.572 31.429 18.929 8.571 18.929 8.571l117.86-115 17.857-75.714-96.43 38.571-91.428 74.286z" enable-background="new" fill="#fff" fill-rule="evenodd"/>
-   <path d="M1197.8 486.14h333.75v309.71H1197.8z" enable-background="accumulate" fill="none"/>
-  </g>
- </g>
- <path d="M3492.3 296.46H3930v902.66h-437.7z" fill="#fff" stroke="#f8d615" stroke-miterlimit="1" stroke-width="18"/>
- <g transform="matrix(1.0057 0 0 2.3995 3249.4 125.01)" clip-path="url(#ie)" enable-background="new" filter="url(#id)">
-  <path d="M36.494 811.806l-14.799 11.372-17.47-31.162 14.663.65 17.606 19.14z" enable-background="accumulate" fill="#fff" fill-rule="evenodd"/>
-  <path d="M-55 757.2h182v177H-55z" enable-background="accumulate" fill="none"/>
- </g>
- <g transform="matrix(1.0057 0 0 2.3995 3249.4 125.01)" clip-path="url(#ic)" enable-background="new" filter="url(#gd)">
-  <path d="m83.111 790.72l-28.201 12.855-5.658-21.687-13.943-25.046 6.325-6.88 26.384 18.51 15.094 22.249z" enable-background="accumulate" fill="#fff" fill-rule="evenodd"/>
-  <path d="M-22 696.2h165v176H-22z" enable-background="accumulate" fill="none"/>
- </g>
- <path transform="matrix(1.0057 0 0 2.3995 3249.4 125.01)" d="m332.34 898.39l-32.732-61.3-37.617 45.106c2.177 1.317 5.774-20.856 45.6-64.417l24.749 80.61z" clip-path="url(#gc)" enable-background="accumulate" fill="#fff" fill-rule="evenodd" filter="url(#gb)" opacity=".5"/>
- <g clip-path="url(#ga)">
-  <g fill-rule="evenodd">
-   <g enable-background="new">
-    <path transform="matrix(.71488 -.46488 .26446 2.3151 3478.4 126.16)" d="m245.12 100.05s-47.128-31.647-67.215-35.801c-20.038-4.144-38.473-3.318-51.934 13.607s-12.077 61.265-13.536 86.97 2.55 70.177 17.605 88.666c15.055 18.488 45.886 13.585 49.927 21.414 2.213 4.287 65.152-174.86 65.152-174.86z" enable-background="accumulate" fill="url(#r)"/>
-    <path transform="matrix(.71488 -.46488 .26446 2.3151 3478.4 126.16)" d="M135.38 82.018s26.344 1.939 37.633 13.903c11.415 12.097 13.735 21.332 15.296 37.735 1.563 16.425-.85 28.418-7.814 36.037s-1.004 19.583-25.916 12.071-27.032-27.783-26.515-46.305c.517-18.529 7.316-53.441 7.316-53.441z" enable-background="accumulate" fill="url(#q)"/>
-    <path transform="matrix(.71488 -.46488 .26446 2.3151 3478.4 126.16)" d="M135.65 81.927s-4.645 16.365.588 28.563c5.488 12.793 27.224 44.26 27.224 54.656l22.656-5c2.542-6.966 3.21-15.752 2.188-26.5-1.562-16.403-3.867-25.621-15.281-37.719-9.655-10.232-31.593-13.375-37.375-14z" enable-background="new" fill="url(#p)"/>
-   </g>
-   <g enable-background="new">
-    <path d="M4043.297 824.626l-.09-.006c-1.489 1.728-6.783 2.02-7.718 20.884-.878 17.694 13.035 44.859 15.06 47.837 1.636 2.403 3.427 4.343 5.205 5.58l1.41.916c1.894 1.031 3.7 1.38 5.163 1.19 3.177-.414 5.214-.812 7.238-1.183 2.025-.372 2.592-1.8 3.707-2.078 1.156-.288 2.255.9 6.345-.372 4.09-1.271 5.587-1.894 6.324-2.566.765-.698 1.86-1.592 2.549-2.999 1.962.51 3.823.346 5.31-.58 3.08-1.92 5.084-3.12 6.998-4.722 1.536-1.285 2.513-3.421 2.759-4.073.246-.653.183-1.71.211-1.754.047-.072.351-.13.55-.906 1.07-4.167 2.968-12.778
-3.16-14.38.193-1.594.324-3.178.42-4.11.056-.54-.046-2.136-.017-2.27.04-.187.317-.518.401-1.098.404-2.783.343-5.237.292-8.675-.05-3.438-.44-11.267-.995-13.482-.356-1.423-.708-2.109-1.051-2.478-.065-.06-.119-.145-.18-.2-.02-.015-.043-.004-.062-.017-.303-.265-.59-.545-1.13-.839-.972-.527-2.393-1.283-3.937-1.684-.514-.134-1.041-.17-1.572-.205-3.591-.231-9.115-.108-10.396 1.072-1.593-1.244-3.874-2.542-5.879-2.746-3.086-.313-5.002-.546-6.953-.776-1.952-.23-1.73.464-2.958.32-1.328-.155-1.76-1.022-5.568-1.302-3.577-.262-9.087-.095-10.397 1.072-1.593-1.245-3.872-2.542-5.878-2.746-3.087-.313-5.006-.472-6.958-.702-.663-.078-1.055.01-1.364.079z" enable-background="new" fill="#bcb786"/>
-    <g transform="matrix(1.0047 .1075 -.04506 2.3971 3818.4 1782.9)" clip-path="url(#fz)" enable-background="new" filter="url(#fy)">
-     <path d="M229.94-409.12c-3.558.05-9.024.36-10.303.904-1.606-.447-3.903-.881-5.9-.877a979.03 979.03 0 0 1-6.907 0c-.66-.003-1.048.068-1.353.11v1.096c.12-.18.393-.69.95-.767.747-.103 5.17-.151 7.31-.11 1.775.035 4.455.274 6.39.96.32.113.618.273.891.41 1.964.987 7.944 4.302 7.944 4.302s-6.633-3.948-7.483-4.439c-.203-.117-.575-.258-1.036-.41 1.22-.449 5.076-.62 7.828-.713 3.024-.102 3.348-.09 5.41.192 2.13.29 3.34.602 3.34.602s-.08-.64 1.035-.794c.748-.103 5.17-.152 7.31-.11 2.07.04 5.366.407 7.282 1.37 1.003.504 3.035 1.569 4.795 2.536l.096-.02s-3.58-2.162-4.43-2.653c-.204-.117-.575-.258-1.037-.411 1.22-.448 5.047-.62 7.8-.712 3.024-.102 3.347-.09 5.41.191 1.954.267 3.013.53 3.195.576l-.027-.312a8.503 8.503 0 0 0-1.4-.357c-1.301-.235-3.4-.602-5.51-.564-3.571.064-9.052.356-10.302.904-1.606-.447-3.877-.881-5.871-.877-3.072.007-4.994.01-6.936
-0-1.943-.009-1.713.28-2.936.274-1.322-.005-1.766-.354-5.555-.301M206.2-407.48c1.92.817 4.577 2.193 6.159 3.397s2.908 1.774 5.555 3.918c.885.718 1.748 1.35 2.591 1.922l.541-.19a57.511 57.511 0 0 1-2.269-1.622c-2.822-2.12-3.627-2.81-6.015-4.274s-4.1-2.366-6.562-3.15" enable-background="new"/>
-     <path d="M237.8-407.48c1.92.817 4.606 2.193 6.188 3.397.813.62 1.558 1.07 2.45 1.654l.65-.116a40.414 40.414 0 0 0-2.697-1.784c-2.389-1.465-4.128-2.366-6.59-3.151" enable-background="new"/>
-    </g>
-    <g transform="matrix(.9991 .27421 -.11493 2.3838 2962.6 1209.8)" clip-path="url(#fx)">
-     <path d="M1056.2-278.8c4.145-1.479 10 3.125 10 3.125.899.28 2.725-.894 2.624-1.686 0 0-1.55-1.86-.374-2.939s5.296 1.507 7.5 1.625 5.562-.23 7-.75 1.113-1.425 2.625-1.75 5.119 1.038 7.06 1.169 4.649.334 5.815-.169.178-1.16 1.875-1.875 7.76-.957 9.625-.125 1.81.52 2.625 3 7.44 5.163-1.125 13.375-59.378 13.786-65.625 2.75 6.23-14.271 10.375-15.75z" enable-background="new" filter="url(#fw)" opacity=".75"/>
-     <path d="M1058.5-275.43c4.145-1.479 10 3.125 10 3.125.899.28 2.725-.894 2.624-1.686 0 0-1.55-1.86-.374-2.939s5.296 1.507 7.5 1.625 5.562-.23 7-.75 1.113-1.425 2.625-1.75 5.119 1.038 7.06 1.169 4.649.334 5.815-.169.178-1.16 1.875-1.875 7.76-.957 9.625-.125 1.81.52 2.625 3 7.44 5.163-1.125 13.375-59.378 13.786-65.625 2.75 6.23-14.271 10.375-15.75z" enable-background="new" filter="url(#fv)" opacity=".75"/>
-    </g>
-   </g>
-   <path d="M3603.7 633.68c-3.826-60.621-16.906-121.51-17.254-181.22-.187-32.048 3.291-63.757 13.834-94.91 36.554-156.68 117.6-203.23 186.99-219.47 87.416-26.435 185.96 43.047 234.7 228.91 54.432 181.72 56.997 414.01 81.07 622.74 29.605 305.05 55.09 614.78 60.735 928.25-3.08 187.6-8.474 396.35-60.847 547.4-48.299 120.83-123.49 120.1-188.13 141.58-91.07 11.17-185.4-38.742-263.27-154.04-65.144-91.037-96.274-272.3-97.832-446.36-8.437-191.66 26.542-369.07 51.914-545.07 7.513-198.58 9.466-398.92 9.708-598.39-.841-77.252-7.13-153.13-11.612-229.41z" enable-background="accumulate" fill="#101414"/>
-   <path transform="matrix(1.0057 0 0 2.3995 3249.4 125.01)" d="M311.83 415.43l9.9 121.62-60.105 136.47 15.556 174.66c15.613 61.879 32.185 98.669 74.376 117.05 4.32-36.24-38.612-142.96-39.243-189.12-.631-46.184 10.83-108.61 30.678-158.3 20.048-50.192 36.897-44.846 42.125-92.593s-17.426-149.39-17.426-149.39l-55.86 39.598z" clip-path="url(#y)" enable-background="accumulate" fill="#fff" filter="url(#fu)" opacity=".25"/>
-   <path d="m3987.6 1371.5s16.85 88.825 28.865 129.46c12.014 40.638 53.027 134.48 53.027 134.48l52.896-306.15" enable-background="accumulate" fill="url(#ft)"/>
-   <path transform="matrix(1.0057 0 0 2.3995 3249.4 125.01)" d="m730.32 536.57c0 8.485 42.548 58.468 42.548 58.468l12.607-28.77-55.154-29.698z" clip-path="url(#fs)" enable-background="accumulate" fill="#fff" filter="url(#fr)" opacity=".08"/>
-  </g>
-  <g transform="matrix(1.0057 0 0 2.3995 3424.4 -24.137)" clip-path="url(#fq)" enable-background="new">
-   <g transform="translate(-174.03 62.156)" filter="url(#aq)">
-    <g filter="url(#g)">
-     <path d="M425.88 476.99c10.805-1.479 24.744 3.354 44.643 3.214s57.453-16.91 82.143-17.143 62.752 12.284 79.286 15 22.848-.158 27.5 7.857 1.927 10.747-10.357 20.714-40.79 12.636-66.071 12.857c-25.282.221-70.381 7.079-95.357 3.93s-56.938-7.824-68.929-17.858-19.851-16.732-17.5-23.929 13.837-3.164 24.643-4.643z" enable-background="new" fill="#fff" fill-rule="evenodd"/>
-     <path d="M343.65 412.6h381.84v181.02H343.65z" enable-background="accumulate" fill="none"/>
-    </g>
-    <g filter="url(#g)">
-     <path d="m861.17 390.2c-10.462 9.714-86.98 19.005-100.71 29.286s-14.753 12.888-12.143 20 6.545 9.406 25.714 8.571 98.571-27.622 98.571-21.429l-11.429-36.429z" enable-background="new" fill="#fff" fill-rule="evenodd"/>
-     <path d="M702.86 344.82h207.89v162.63H702.86z" enable-background="accumulate" fill="none"/>
-    </g>
-   </g>
-   <g enable-background="new" opacity=".18">
-    <g transform="translate(-174.03 62.156)" filter="url(#g)">
-     <path d="M425.88 476.99c10.805-1.479 24.744 3.354 44.643 3.214s57.453-16.91 82.143-17.143 62.752 12.284 79.286 15 22.848-.158 27.5 7.857 1.927 10.747-10.357 20.714-40.79 12.636-66.071 12.857c-25.282.221-70.381 7.079-95.357 3.93s-56.938-7.824-68.929-17.858-19.851-16.732-17.5-23.929 13.837-3.164 24.643-4.643z" enable-background="new" fill="#fff" fill-rule="evenodd"/>
-     <path d="M343.65 412.6h381.84v181.02H343.65z" enable-background="accumulate" fill="none"/>
-    </g>
-    <g transform="translate(-174.03 62.156)" filter="url(#g)">
-     <path d="m861.17 390.2c-10.462 9.714-86.98 19.005-100.71 29.286s-14.753 12.888-12.143 20 6.545 9.406 25.714 8.571 98.571-27.622 98.571-21.429l-11.429-36.429z" enable-background="new" fill="#fff" fill-rule="evenodd"/>
-     <path d="M702.86 344.82h207.89v162.63H702.86z" enable-background="accumulate" fill="none"/>
-    </g>
-   </g>
-  </g>
-  <g transform="matrix(1.0057 0 0 2.3995 2971.9 -201.33)" fill-rule="evenodd">
-   <path transform="translate(276 136)" d="m582.66-7.418l113.14 86.267 108.89 258.8 38.184 207.89 120.21 91.924s-12.728-287.09-19.799-313.96-149.91-393.15-149.91-393.15l-210.72 62.225z" clip-path="url(#fp)" enable-background="accumulate" filter="url(#fo)" opacity=".75"/>
-   <path d="m964.14 239.6s8.677 10.897 24.107 11.964c15.43 1.068 49.722-39.953 70.179-52.143 20.479-12.204 47.046-26.602 63.929-20.357 16.882 6.245 22.158 26.436 27.857 48.036 5.7 21.6 6.719 61.814-2.679 92.857-9.397 31.043-50.502 73.104-65.356 103.39s-11.607 39.821-11.607 39.821" enable-background="accumulate" fill="url(#el)"/>
-   <path d="m1124.5 207.63c-15.893-0.893-49.719 12.106-66.071 24.286-16.439 12.244-29.221 24.114-29.286 52.143-0.065 28.206 13.119 39.076 29.107 46.964s33.686 7.12 51.964-11.786c18.278-18.905 14.286-111.61 14.286-111.61z" enable-background="new" fill="url(#ek)"/>
-   <ellipse transform="matrix(.94347 -.12399 .14401 1.0958 451.95 134.6)" cx="385" cy="237.01" rx="86.429" ry="73.929" clip-path="url(#fn)" enable-background="accumulate" fill="url(#ef)" filter="url(#fm)" opacity=".75"/>
-   <path transform="translate(450.03 73.844)" d="m527.61 407.45s-122.04 38.403-187.51 9.632c-65.473-28.772-74.377-124.72-74.377-124.72s73.382-80.504 129.92-83.615c55.827-3.072 90.574 20.143 114.87 65.852 24.352 45.813 17.101 132.85 17.101 132.85z" enable-background="accumulate" fill="url(#fl)" mask="url(#fk)"/>
-   <path d="m772.17 393.35s36.218-27.382 51.607-35.893c15.177-8.393 25.714-11.607 35.893-11.607l-15.536 66.964" enable-background="accumulate" fill="url(#ee)"/>
-   <circle transform="translate(449.5 74.915)" cx="409.29" cy="306.65" r="36.25" enable-background="accumulate" fill="url(#ed)"/>
-   <path transform="translate(276 136)" d="m311.83 415.43l9.9 121.62-60.105 136.47 15.556 174.66c15.613 61.879 32.185 98.669 74.376 117.05 4.32-36.24 8.682-72.368-31.243-223.12l17.678-69.296 72.125-138.59-42.426-158.39-55.86 39.598z" clip-path="url(#y)" enable-background="accumulate" fill="#fff" filter="url(#fj)" opacity=".3"/>
-   <path d="m635.21 581.13c-14.142 12.728 39.233 34.58 76.368 24.042s104.64-35.564 103.24-79.196c-1.407-43.632-76.368-128.69-76.368-128.69l-103.24 183.85z" enable-background="accumulate" filter="url(#fi)" opacity=".5"/>
-   <circle transform="translate(449.67 74.915)" cx="410" cy="306.65" r="23.214" enable-background="accumulate" fill="url(#ec)"/>
-   <circle transform="translate(452 73.487)" cx="414.29" cy="303.08" r="7.5" enable-background="accumulate" fill="#fff" filter="url(#fh)" stroke="#000" stroke-linejoin="bevel"/>
-   <path d="m789.32 478.35s7.023 19.569-1.071 35-42.323 38.988-67.5 50c-25.31 11.07-85.473 32.964-101.79 41.964-16.461 9.082-18.214 12.679-18.214 12.679s-7.147-19.064 28.75-51.786c36.172-32.972 142.03-48.05 159.82-87.857z" enable-background="accumulate" fill="url(#eb)"/>
-  </g>
-  <g enable-background="new">
-   <g transform="matrix(1.0057 0 0 2.3995 3757 -22.424)" fill-rule="evenodd">
-    <path transform="translate(-329.81)" d="M179.64 267.36c-22.41 39.703-60.616 115.78-69.286 149.64-8.647 33.775-8.772 66.417-.357 86.429 8.36 19.882 26.164 35.633 40.714 41.429-.597-14.376 14.373-43.286 72.857-72.5 58.626-29.285 78.382-27.131 103.57-47.143 25.63-20.362 8.206-79.647 3.214-93.929s-1.236-3.38-1.946-5.093c-10.689-25.816-34.214-54.43-64.483-64.55s-65.018-4.848-84.286 5.714z" clip-path="url(#x)" fill="url(#m)"/>
-    <ellipse transform="rotate(28.068 -88.085 -332.1)" cx="183.57" cy="338.08" rx="64.716" ry="134.01" enable-background="accumulate" fill="url(#dz)"/>
-    <ellipse transform="rotate(28.068 -43.578 -333.81)" cx="183.57" cy="338.08" rx="64.716" ry="134.01" enable-background="accumulate" fill="url(#fg)"/>
-   </g>
-   <path transform="matrix(1.0057 0 0 2.3995 3425.3 -22.424)" d="M179.64 267.36c-22.41 39.703-60.616 115.78-69.286 149.64-8.647 33.775-8.772 66.417-.357 86.429 8.36 19.882 26.164 35.633 40.714 41.429-.597-14.376 14.373-43.286 72.857-72.5 58.626-29.285 78.382-27.131 103.57-47.143 25.63-20.362 8.206-79.647 3.214-93.929s-1.236-3.38-1.946-5.093c-10.689-25.816-34.214-54.43-64.483-64.55s-65.018-4.848-84.286 5.714z" clip-path="url(#x)" enable-background="new" fill="none" filter="url(#hd)" stroke="url(#l)" stroke-width="20.8"/>
-  </g>
-  <g transform="matrix(1.0057 0 0 2.3995 2971.9 -201.33)" fill-rule="evenodd">
-   <circle transform="translate(452.56 72.581)" cx="310.71" cy="398.08" r="19.704" enable-background="accumulate" stroke="#000" stroke-linejoin="bevel"/>
-   <circle transform="translate(450.56 72.581)" cx="310.71" cy="398.08" r="19.704" enable-background="accumulate" fill="url(#m)" filter="url(#hc)" stroke="url(#l)" stroke-width="20.8"/>
-   <circle transform="translate(450.56 72.581)" cx="310.71" cy="398.08" r="19.704" enable-background="accumulate" fill="url(#dy)"/>
-   <ellipse transform="rotate(-4.471 1823.1 -5529.2)" cx="429.57" cy="377.43" rx="72.08" ry="44.548" enable-background="accumulate" fill="url(#dx)" filter="url(#hb)"/>
-   <ellipse transform="matrix(1.4358 -.07 .07 1.4358 235.18 -63.865)" cx="437.7" cy="391.22" rx="36.612" ry="22.627" enable-background="accumulate" fill="url(#dw)" filter="url(#ha)"/>
-   <g transform="translate(450.03 73.844)" enable-background="new" filter="url(#gz)">
-    <circle cx="413.66" cy="401.83" r="3.214" enable-background="accumulate" stroke="url(#dv)"/>
-    <circle transform="translate(13.125 8.125)" cx="413.66" cy="401.83" r="3.214" enable-background="accumulate" stroke="url(#du)"/>
-    <circle transform="translate(32.946 7.5)" cx="413.66" cy="401.83" r="3.214" enable-background="accumulate" stroke="url(#ej)"/>
-    <circle transform="translate(24.911 -10.268)" cx="413.66" cy="401.83" r="3.214" enable-background="accumulate" stroke="url(#ei)"/>
-    <circle transform="translate(47.589 -.625)" cx="413.66" cy="401.83" r="3.214" enable-background="accumulate" stroke="url(#eh)"/>
-   </g>
-  </g>
-  <g fill="none" stroke="#000">
-   <path transform="matrix(1.0057 0 0 2.3995 2971.9 -201.33)" d="M896.2 482.93c.985 4.35 4.537 6.18 7.387 7.892 4.46 2.513 6.52 1.522 9.154-.758 1.602-1.921 10.683-4.698 15.594-7.07 4.33-1.46 8.904-5.36 13.385-8.335 3.395-1.627 5.347.355 7.829 1.01 2.944.717 4.411 2.172 6.06 3.536 2.397 1.175-.927 3.143 3.284 4.293 1.19.218 2.417.577 3.283-.505" enable-background="new"/>
-   <path transform="matrix(1.0057 0 0 2.3995 2971.9 -201.33)" d="M910.85 475.35c2.315-.032 3.178.643 5.493-.82 3.455-3.082 5.402-3.146 7.955-4.42 3.026-1.315 6.535 8.152 10.102 9.849 2.395-.822 1.289 1.794 1.452 2.651.057 2.647 2.807 3.679 4.356 5.43 3.316 2.256 7.375 6.296 11.112 5.303 6.445-2.93 10.28-1.281 16.29-7.386.703-1.182-.585-6.895 3.093-7.198 2.524.254 4.166.05 6.06.569 5.442 2.117 7.738 6.45 14.71 7.955 6.184.966 7.613 3.794 13.89 5.05M876.98 483.52c2.399-.794 6.106 4.192 8.173 7.046.593 2.68 1.154 5.486.758 12.122.785 2.417 2.68 3.03 4.798 3.283 3.117-.537 5.877-1.325 7.324-3.03 1.871-1.942 5.312 2.393 8.08 4.04 3.61 1.912 7.775 1.979 11.87 2.273 1.703-.231 2.37 4.515 3.283 8.08.384 4.379-.886 6.897-1.768 9.85-.294 2.496 2.988 3.53 6.313 4.546 3.183.74 6.545 1.661 9.092 1.767 5.142.875 8.088 2.69 12.122 4.04 2.239.817 3.26 2.243 4.545 3.536" enable-background="new"/>
-  </g>
-  <g transform="matrix(.9991 .27421 -.11493 2.3838 2962.6 1209.8)" enable-background="new" fill-rule="evenodd" mask="url(#gy)">
-   <path d="M1111.48-285.971l-3.937 1.875c-.041.01-.1.02-.125.031-.42.213-.165.1-.657.312-.486.21-1.737.585-4.093 1.47-3.332 1.25-5.805 2.15-7 3.062-1.537.021-3.72.233-5.657.719a227.677 227.677 0 0 1-6.75 1.593c-1.894.42-1.675.642-2.875.875-1.296.252-1.721-.009-5.437.782-3.49.742-8.895 1.93-10.156 2.687-1.584-.18-3.868-.322-5.844-.031-3.04.447-4.916.673-6.844.906-.655.08-1.04.2-1.343.281-.427.132-.686.26-1.375.344-1.312.16-1.763-.157-5.532.281-3.554.413-9.005 1.273-10.25 1.938-1.599-.297-3.857-.534-5.843-.344-3.06.293-4.972.484-6.907.656-1.934.173-1.688.423-2.906.532-1.316.117-1.76-.164-5.531.25-3.542.388-9.008 1.209-10.281 1.875-1.6-.295-3.887-.507-5.875-.313-3.058.3-4.941.48-6.875.656-.658.06-1.04.179-1.344.25-.428.12-.683.218-1.375.282-1.316.12-1.76-.195-5.531.218-3.556.39-9.006 1.24-10.25
-1.907-1.599-.295-3.86-.524-5.844-.313-3.056.325-4.974.526-6.906.719s-1.69.44-2.906.562c-1.315.132-1.763-.164-5.532.282-3.538.418-8.977 1.292-10.25 1.968-1.597-.28-3.86-.42-5.843-.187-3.052.358-4.945.568-6.875.781-.657.073-1.041.173-1.344.25-.427.127-.685.267-1.375.344-1.314.146-1.768-.174-5.531.312-3.55.46-8.979 1.42-10.22 2.125-1.592-.244-3.833-.381-5.812-.125-3.047.395-4.95.649-6.875.907-1.924.257-1.726.493-2.937.656-1.31.176-1.748-.105-5.5.469-3.525.538-8.924 1.699-10.188 2.437-1.588-.203-3.846-.255-5.813.094-3.026.536-4.899.861-6.812 1.187-.65.111-1.014.271-1.313.375-.42.165-.663.332-1.344.469-1.294.262-1.727-.006-5.437.813-3.499.771-8.846 2.382-10.062 3.218-1.563-.077-3.758.086-5.688.594-2.972.783-4.817 1.232-6.687 1.75s-1.667.767-2.844 1.094c-1.272.353-1.697.107-5.344 1.187-3.424 1.015-8.65 2.934-9.875 3.844-1.539.013-3.72.272-5.625.875-2.93.928-4.75 1.459-6.594
-2.063-.626.205-.991.392-1.28.53-.408.215-.654.41-1.313.626-1.255.411-1.686.189-5.281 1.437-3.39 1.178-8.595 3.214-9.782 4.157-1.524.06-3.65.395-5.53 1.062-2.898 1.028-4.7 1.676-6.532 2.313-1.832.637-1.628.848-2.781 1.25-1.247.434-1.664.2-5.22 1.562-3.338 1.28-8.486 3.483-9.687 4.469-1.507.108-3.635.499-5.5 1.219a1047.26 1047.26 0 0 1-6.437 2.469c-.617.233-.997.442-1.281.593v.031l-8 3.188-12.476 3.492 7.93 19.278c-.592 1.973 12.545-4.739 12.545-4.739.227-.144.45-.272.72-.375 1.08-.41 2.17-.215 6-1.687 3.828-1.472 5.223-2.005 5.905-2.406.68-.4 1.612-.88 2.22-1.531 1.826-.138 3.57-.494 4.937-1 2.968-1.1 4.875-1.807 6.78-2.47 1.907-.662 2.355-1.414 3.407-1.78 1.092-.38 2.195-.166 6.063-1.532 3.867-1.366 5.283-1.827 5.968-2.218.702-.4 1.701-.933 2.313-1.594 1.97-.055 3.817-.385 5.281-.875 3.002-1.005 4.926-1.622 6.844-2.25 1.538-.504 2.174-1.047 2.906-1.438.23-.134.476-.253.75-.343 1.098-.36
-2.181-.082 6.094-1.313 3.912-1.231 5.366-1.673 6.062-2.031.694-.357 1.63-.793 2.25-1.406 1.866-.023 3.636-.267 5.032-.688 3.03-.913 4.992-1.43 6.937-1.969 1.945-.538 2.426-1.264 3.5-1.562 1.114-.31 2.22.007 6.188-1.031 3.967-1.039 5.417-1.433 6.125-1.75.734-.33 1.813-.754 2.437-1.375 1.998.116 3.857-.02 5.344-.375 3.078-.735 5.083-1.101 7.062-1.5 1.588-.32 2.245-.79 3-1.094a3.4 3.4 0 0 1 .75-.25c1.134-.23 2.305.209 6.344-.5 4.04-.71 5.5-.927 6.219-1.188.716-.26 1.704-.567 2.344-1.093 1.924.239 3.748.224 5.187 0 3.127-.488 5.155-.701 7.156-.97 2.002-.267 2.49-.944 3.594-1.093 1.147-.154 2.276.302 6.344-.219 4.068-.52 5.56-.695 6.281-.937.737-.247 1.798-.586 2.438-1.125 2.05.335 3.973.398 5.5.218 3.142-.368 5.18-.559 7.187-.78 1.611-.179 2.265-.609 3.031-.845.241-.085.495-.155.782-.187 1.15-.128 2.301.347 6.375-.125s5.559-.61 6.28-.844c.72-.232 1.701-.473 2.345-.969 1.936.334 3.77.405
-5.219.25 3.146-.334 5.177-.518 7.187-.718 2.01-.2 2.484-.827 3.594-.938 1.15-.115 2.296.365 6.375-.062s5.589-.562 6.312-.782c.74-.223 1.796-.513 2.438-1.03 2.057.398 4.002.493 5.531.343 3.149-.308 5.176-.473 7.188-.656 1.614-.147 2.263-.56 3.03-.781.242-.081.494-.13.782-.157 1.152-.105 2.293.393 6.375 0s5.589-.53 6.312-.75c.721-.218 1.7-.447 2.344-.937 1.938.35 3.769.454 5.219.312 3.149-.308 5.176-.473 7.187-.656 2.012-.183 2.515-.838 3.625-.937 1.153-.104 2.293.384 6.375 0 4.083-.385 5.59-.501 6.313-.72.74-.222 1.796-.514 2.437-1.03 2.058.401 4.003.503 5.532.343 3.146-.328 5.177-.522 7.187-.718 1.613-.158 2.266-.632 3.031-.875.241-.088.464-.122.75-.157 1.149-.14 2.317.34 6.375-.25 4.059-.59 5.562-.777 6.282-1.03.716-.254 1.674-.559 2.312-1.095 1.92.212 3.72.152 5.156-.093 3.12-.533 5.112-.929 7.094-1.313 1.982-.384 2.474-1.04 3.563-1.281 1.128-.25 2.27.116 6.25-.875s5.43-1.42
-6.125-1.781c.722-.376 1.761-.87 2.375-1.531 1.963-.012 3.793-.292 5.218-.844 2.952-1.145 4.874-1.87 6.688-2.75 1.456-.707 2.32-1.702 2.531-2 .212-.298.1-.729.125-.75.043-.035.34-.094.5-.438.86-1.847 2.323-5.627 2.438-6.312.113-.682.168-1.353.218-1.75.03-.23-.147-.88-.125-.938.031-.082.289-.25.344-.5.266-1.198.09-2.207-.125-3.625-.214-1.417-.972-4.614-1.625-5.469-.659-.861-1.225-1.01-1.75-1z" enable-background="new" fill="#bcb786"/>
-   <g clip-path="url(#gx)">
-    <path d="M1107.4-284.05c-.419.213-.156.094-.647.306-.486.21-1.724.574-4.08 1.459-3.33 1.25-5.83 2.153-7.026 3.066-1.536.021-3.72.233-5.656.719a227.709 227.709 0 0 1-6.75 1.593c-1.895.42-1.676.643-2.875.875-1.297.252-1.721-.009-5.438.782-3.49.742-8.894 1.93-10.156 2.687-1.583-.18-3.867-.322-5.843-.031-3.04.447-4.917.673-6.844.906-.655.08-1.041.201-1.344.282-.426.131-.686.26-1.375.343-1.311.16-1.762-.157-5.531.282-3.554.413-9.005 1.272-10.25 1.937-1.599-.297-3.858-.534-5.844-.344-3.059.294-4.972.484-6.906.657-1.934.172-1.689.422-2.906.53-1.317.118-1.76-.163-5.532.25-3.541.39-9.007 1.21-10.28 1.876-1.6-.295-3.888-.507-5.876-.313-3.058.3-4.94.48-6.875.657-.657.06-1.04.178-1.343.25-.428.118-.684.218-1.375.28-1.316.121-1.76-.194-5.532.22-3.556.39-9.005 1.239-10.25
-1.906-1.598-.294-3.86-.524-5.843-.313-3.056.326-4.974.526-6.907.719-1.932.192-1.69.44-2.906.562-1.315.132-1.763-.164-5.53.282-3.54.418-8.979 1.292-10.25 1.969-1.599-.282-3.86-.42-5.845-.188-3.052.358-4.945.568-6.875.781-.656.073-1.04.173-1.344.25-.426.127-.684.267-1.375.344-1.313.146-1.767-.174-5.53.313-3.55.458-8.98 1.419-10.22 2.125-1.593-.245-3.834-.382-5.812-.125-3.048.394-4.95.648-6.875.906-1.925.258-1.726.493-2.938.656-1.31.176-1.747-.104-5.5.469-3.524.538-8.923 1.699-10.188 2.437-1.587-.203-3.845-.254-5.812.094-3.026.536-4.9.862-6.813 1.187-.65.111-1.013.271-1.312.375-.42.165-.664.332-1.344.47-1.295.26-1.727-.007-5.438.812-3.498.772-8.846 2.383-10.062 3.219-1.562-.078-3.757.085-5.687.593-2.972.783-4.818 1.232-6.688 1.75s-1.666.768-2.843 1.094c-1.273.353-1.697.107-5.344 1.188-3.425 1.014-8.65 2.933-9.875 3.843-1.539.013-3.72.273-5.625.875-2.931.928-4.75 1.459-6.594
-2.063-.627.205-.992.392-1.281.531-.408.214-.653.409-1.313.625-1.254.412-1.686.19-5.28 1.438-3.39 1.177-8.596 3.213-9.782 4.156-1.524.06-3.65.395-5.531 1.062-2.898 1.029-4.7 1.676-6.531 2.313-1.833.637-1.628.848-2.782 1.25-1.246.434-1.663.2-5.218 1.562-3.34 1.28-8.488 3.483-9.688 4.47-1.507.107-3.636.498-5.5 1.218a1044.752 1044.752 0 0 1-6.437 2.469c-.617.233-.997.442-1.282.593v1.094c.112-.222.386-.817.907-1.094.698-.37 4.813-1.993 6.812-2.718 1.657-.602 4.154-1.329 5.969-1.313.302.003.588.051.844.094 1.842.308 7.468 1.562 7.468 1.562s-6.233-1.646-7.03-1.843c-.191-.048-.536-.07-.97-.063 1.146-.87 4.762-2.393 7.344-3.437 2.839-1.148 3.117-1.252 5.063-1.657 2.008-.417 3.156-.5 3.156-.5s-.082-.6.969-1.125c.705-.351 4.887-1.892 6.906-2.562 1.952-.648 5.057-1.359 6.875-1 1.863.367 7.531 1.812 7.531 1.812s-6.287-1.87-7.094-2.093c-.193-.054-.53-.086-.968-.094 1.158-.833 4.794-2.195 7.406-3.156
-2.87-1.056 3.167-1.162 5.125-1.532 1.853-.35 2.859-.425 3.031-.437.114-.217.377-.81.906-1.063.71-.338 4.926-1.712 6.97-2.312 1.692-.497 4.24-1.037 6.093-.906.308.021.613.097.875.156 1.881.424 7.594 2.031 7.594 2.031s-6.342-2.065-7.157-2.312c-.194-.06-.557-.104-1-.125 1.17-.798 4.863-2.057 7.5-2.938 2.898-.968 3.233-1.003 5.22-1.281 2.049-.287 3.187-.313 3.187-.313s-.073-.607 1-1.062c.72-.306 4.99-1.5 7.062-2 2.003-.483 5.199-.928 7.063-.406 1.91.535 7.719 2.5 7.719 2.5s-6.423-2.424-7.25-2.72c-.198-.07-.583-.14-1.032-.187 1.188-.728 4.916-1.774 7.594-2.5 2.944-.797 3.292-.77 5.313-.906 1.913-.128 2.947-.07 3.125-.062.117-.204.391-.78.937-.97.732-.253 5.079-1.047 7.188-1.374 1.748-.271 4.4-.485 6.312-.094.318.065.605.186.875.281 1.94.69 7.844 3.094 7.844 3.094s-6.535-2.95-7.375-3.312c-.201-.087-.575-.167-1.031-.25 1.206-.633 5.03-1.396 7.75-1.906 2.99-.562 3.3-.53 5.344-.532 2.109-.002
-3.312.125 3.312.125s-.073-.63 1.031-.937c.74-.206 5.126-.834 7.25-1.063 2.053-.22 5.319-.252 7.22.47 1.947.738 7.843 3.374 7.843 3.374s-6.563-3.179-7.406-3.562c-.202-.092-.543-.187-1-.282 1.21-.602 4.984-1.248 7.718-1.656 3.005-.448 3.326-.452 5.375-.406 1.94.043 3.007.194 3.188.219.119-.194.384-.766.937-.907.743-.188 5.155-.734 7.282-.937 1.763-.169 4.42-.234 6.343.25.32.08.604.203.875.312 1.953.784 7.907 3.47 7.907 3.47s-6.592-3.254-7.438-3.657c-.202-.096-.572-.207-1.031-.313 1.214-.574 5.044-1.122 7.781-1.5 3.009-.415 3.323-.442 5.375-.375 2.118.07 3.313.25 3.313.25s-.078-.637 1.03-.906c.745-.18 5.153-.663 7.282-.844 2.059-.174 5.343-.124 7.25.657 1.955.8 7.875 3.53 7.875 3.53s-6.56-3.308-7.406-3.718c-.202-.098-.572-.203-1.031-.312 1.215-.564 5.01-1.115 7.75-1.47 3.01-.389 3.321-.397 5.375-.312 1.944.08 3.006.254 3.187.282.12-.191.383-.746.938-.875.744-.174 5.15-.65 7.28-.813
-1.767-.134 4.45-.126 6.376.375.32.083.603.201.875.313 1.954.8 7.906 3.562 7.906 3.562s-6.591-3.34-7.437-3.75c-.203-.098-.572-.203-1.032-.312 1.215-.564 5.042-1.084 7.782-1.438 3.01-.39 3.352-.429 5.406-.344 2.12.088 3.312.313 3.312.313s-.078-.65 1.032-.906c.744-.173 5.15-.624 7.28-.782 2.061-.152 5.344-.096 7.25.688 1.956.804 7.876 3.5 7.876 3.5s-6.56-3.276-7.406-3.688c-.203-.098-.572-.202-1.032-.312 1.216-.562 5.012-1.128 7.75-1.5 3.01-.41 3.323-.416 5.375-.344 1.943.068 3.008.165 3.188.188.119-.195.384-.73.937-.875.742-.197 5.131-.83 7.25-1.094 1.757-.22 4.406-.333 6.313.031.317.06.606.19.875.281 1.936.661 7.844 2.938 7.844 2.938s-6.537-2.807-7.375-3.156c-.2-.084-.577-.174-1.032-.25 1.204-.651 5.02-1.372 7.72-2 2.966-.69 3.288-.756 5.312-.875 2.088-.124 3.28-.032 3.28-.032s-.086-.632 1-1.03c.73-.269 5.048-1.339 7.126-1.813 2.008-.46 5.168-1.03 7-.625 1.878.414 13.578 3.015 13.578
-3.015s-12.328-3.022-13.141-3.265c-.195-.058-.559-.107-1-.125 1.167-.804 3.514-1.688 6.11-2.703 1.68-.659.923-.377 2.775-1.004 1.754-.594 2.486-1.01 2.63-1.113.347-.207-.355-.122-.544-.042z" enable-background="new" filter="url(#gw)"/>
-    <path d="m1082.6-275.12c1.873 0.393 4.496 1.146 6.031 1.969s2.822 1.056 5.375 2.5c2.527 1.43 4.796 2.007 6.969 2.531 2.348 0.566 5.435 0.715 8.844 1.188-1.09-0.84-6.608-1.173-8.406-1.563-1.8-0.39-3.895-1.016-6.594-2.313-2.7-1.296-3.495-1.799-5.813-2.687-2.318-0.889-4.004-1.383-6.406-1.625z" enable-background="new" filter="url(#gv)"/>
-    <path d="M1051.5-270c1.905.578 4.528 1.616 6.094 2.594 1.565.978 2.88 1.36 5.5 3.125 2.593 1.747 4.986 2.71 7.25 3.594 2.446.955 5.682 1.657 9.406 3.062-1.19-1.138-7.063-2.687-8.938-3.375-1.874-.688-4.081-1.566-6.874-3.281-2.794-1.715-3.574-2.284-5.938-3.406-2.364-1.123-4.057-1.835-6.5-2.313z" enable-background="new" filter="url(#gu)"/>
-    <path d="m1020.2-266.84c1.912 0.638 4.581 1.755 6.156 2.813 1.575 1.057 2.896 1.508 5.531 3.406 2.61 1.878 5.029 3.03 7.313 4.062 2.468 1.116 5.764 2.174 9.531 3.844-1.203-1.222-7.203-3.314-9.094-4.125-1.89-0.81-4.064-1.894-6.874-3.75s-3.622-2.477-6-3.719c-2.379-1.242-4.111-1.975-6.563-2.531z" enable-background="new" filter="url(#gt)"/>
-    <path d="M1110.2-266.89c.15.049.688.631.11 1.484-.81 1.195-5.705 3.325-8.563 4.125-2.845.798-6.29.978-10.562-.375-4.302-1.362-5.47-2.468-10.656-4.312 4.664 2.115 6.195 3.952 10.125 5.344 1.62.574 3.367.94 5.062 1.03-.445.327-1.53.984-3.562 1.595-2.796.84-6.65 1.534-8.25 1.625-1.515.086-3.142-.513-3.438-.625.167.103.374.377-.25 1.03-.899.945-6.147 1.924-9.125 2.25-2.964.326-6.521-.015-10.906-1.905-3.978-1.715-5.339-2.916-9.406-4.75v.156c3.643 2.095 5.284 3.883 8.875 5.562 1.73.81 3.592 1.41 5.406 1.72-.534.286-1.557.71-3.437 1.03-2.87.488-6.81.817-8.438.75-.85-.034-1.728-.184-2.406-.406-.685-.215-1.19-.444-1.312-.5.169.107.43.403-.22 1.031-.909.88-6.245 1.337-9.25 1.47-2.99.131-6.588-.451-11-2.563-4.44-2.127-5.64-3.402-10.905-5.782 4.734 2.597 6.286 4.63 10.344 6.72 1.673.861 3.485 1.493 5.25
-1.937-.463.233-1.59.688-3.688.937-2.886.343-6.834.493-8.468.375-1.547-.111-3.232-.857-3.532-1 .17.12.414.41-.218 1-.913.851-6.244 1.262-9.25 1.375-2.993.113-6.59-.49-11-2.594-4.002-1.908-5.388-3.137-9.47-5.093v.156c3.656 2.204 5.295 4.053 8.907 5.906 1.74.893 3.637 1.528 5.469 1.969-.54.248-1.578.615-3.469.844-2.886.348-6.866.52-8.5.406a9.446 9.446 0 0 1-2.406-.5 12.532 12.532 0 0 1-1.313-.531c.17.112.465.422-.187 1.03-.913.853-6.275 1.294-9.281 1.407-2.993.112-6.594-.528-11-2.594-4.437-2.08-5.647-3.331-10.906-5.656 4.729 2.548 6.29 4.578 10.344 6.625 1.671.844 3.485 1.467 5.25 1.906-.464.235-1.59.684-3.688.938-2.886.348-6.836.57-8.469.469-1.544-.096-3.2-.83-3.5-.97.17.12.382.405-.25 1-.912.861-6.246 1.331-9.25 1.47-2.99.138-6.567-.451-10.969-2.47-3.993-1.83-5.365-3.028-9.437-4.905v.156c3.647 2.133 5.27 3.935 8.875 5.719 1.737.86 3.607 1.45 5.437
-1.875-.54.253-1.55.64-3.437.906-2.88.404-6.838.646-8.469.562a9.36 9.36 0 0 1-2.406-.437 12.971 12.971 0 0 1-1.313-.5c.17.109.432.41-.218 1.031-.911.87-6.25 1.392-9.25 1.563-2.987.17-6.574-.316-10.97-2.282-4.424-1.978-5.605-3.228-10.843-5.375 4.71 2.388 6.27 4.39 10.312 6.344a23.73 23.73 0 0 0 5.218 1.781c-.461.25-1.597.713-3.687 1.032-2.876.438-6.78.733-8.406.687-1.539-.043-3.233-.745-3.532-.875.169.113.411.414-.218 1.031-.908.891-6.203 1.529-9.188 1.813-2.971.283-6.573-.176-10.938-1.938-3.96-1.598-5.329-2.795-9.344-4.312v.156c3.596 1.811 5.239 3.582 8.813 5.156 1.722.759 3.587 1.29 5.406 1.625-.536.28-1.566.688-3.437 1.063-2.856.572-6.79 1.02-8.407 1.031-.844.006-1.706-.08-2.375-.25-.676-.162-1.16-.33-1.28-.375.166.094.422.383-.22 1.062-.897.951-6.186 1.918-9.125 2.438-2.925.518-6.432.374-10.719-1.031-4.315-1.415-5.472-2.53-10.562-3.969 4.577 1.751 6.09 3.56 10.031 5 1.627.594 3.37.956
-5.094 1.156-.453.297-1.555.884-3.594 1.469-2.804.805-6.638 1.576-8.218 1.75-1.495.165-3.117-.317-3.407-.406.164.09.393.36-.218 1.062-.883 1.014-6.045 2.372-8.938 3.063-2.88.687-6.335.76-10.562-.438-3.835-1.086-5.172-2.072-9.062-3.125v.156c3.484 1.395 5.07 2.92 8.53 4.032 1.669.535 3.457.786 5.22.875-.52.352-1.5.914-3.313 1.53-2.765.942-6.59 1.936-8.156 2.157-.818.115-1.633.123-2.281.031-.655-.083-1.133-.218-1.25-.25.162.075.434.34-.188 1.094-.87 1.055-6.01 2.66-8.875 3.438-2.852.774-6.259.958-10.438-.094-4.206-1.06-5.356-2.042-10.344-3.156 4.485 1.46 5.97 3.135 9.813 4.25 1.585.46 3.287.638 4.969.687-.442.337-1.513 1.028-3.5 1.781-2.734 1.037-6.452 2.163-8 2.438-1.465.26-3.06-.117-3.344-.188.16.08.38.321-.219 1.063-.865 1.07-5.916 2.818-8.75 3.687-2.82.866-6.207 1.157-10.344.22-3.753-.852-5.048-1.717-8.875-2.595v.157c3.428 1.237 4.987 2.632 8.375 3.53 1.632.434 3.367.584
-5.094.563-.51.384-1.477 1.022-3.25 1.75-2.706 1.112-6.436 2.308-7.969 2.625-.8.166-1.612.219-2.25.157v1.406c.227-.145.449-.273.719-.375 1.08-.41 2.171-.216 6-1.688 3.828-1.471 5.224-2.005 5.906-2.406.68-.4 1.612-.88 2.219-1.531 1.827-.138 3.57-.493 4.937-1 2.968-1.1 4.876-1.806 6.782-2.469 1.905-.663 2.354-1.415 3.406-1.781 1.091-.38 2.195-.166 6.062-1.531 3.868-1.366 5.283-1.827 5.969-2.22.701-.4 1.7-.932 2.313-1.593 1.97-.055 3.816-.385 5.28-.875 3.002-1.005 4.927-1.622 6.845-2.25 1.538-.504 2.174-1.047 2.906-1.437.23-.135.475-.254.75-.344 1.098-.36 2.181-.082 6.094-1.313 3.912-1.23 5.366-1.673 6.062-2.03.694-.358 1.63-.794 2.25-1.407 1.865-.023 3.636-.267 5.031-.688 3.03-.913 4.993-1.43 6.938-1.968 1.945-.54 2.426-1.265 3.5-1.563 1.114-.31 2.22.007 6.187-1.031 3.968-1.039 5.418-1.433 6.125-1.75.735-.33 1.814-.754 2.438-1.375 1.997.116 3.857-.02 5.344-.375 3.078-.735 5.083-1.101
-7.062-1.5 1.588-.32 2.244-.79 3-1.094.238-.107.467-.193.75-.25 1.134-.23 2.305.209 6.344-.5s5.5-.927 6.219-1.187c.715-.26 1.704-.568 2.343-1.094 1.925.24 3.748.224 5.188 0 3.126-.488 5.155-.7 7.156-.969 2.002-.268 2.489-.945 3.594-1.094 1.146-.154 2.276.302 6.344-.219 4.068-.52 5.56-.695 6.28-.937.738-.247 1.799-.586 2.438-1.125 2.05.335 3.974.398 5.5.219 3.143-.37 5.18-.56 7.188-.782 1.61-.178 2.265-.608 3.031-.843a3.43 3.43 0 0 1 .781-.188c1.15-.128 2.302.347 6.375-.125s5.56-.61 6.282-.844c.719-.232 1.7-.473 2.343-.968 1.937.333 3.77.404 5.22.25 3.145-.335 5.177-.519 7.187-.719 2.01-.2 2.484-.826 3.593-.938 1.152-.115 2.297.366 6.375-.062s5.59-.562 6.313-.781c.74-.224 1.796-.514 2.437-1.031 2.058.398 4.002.493 5.532.343 3.148-.308 5.175-.473 7.187-.656 1.614-.147 2.263-.56 3.031-.781.242-.081.494-.13.782-.156 1.152-.106 2.293.392 6.375 0 4.082-.393 5.589-.531 6.312-.75.721-.219
-1.7-.448 2.344-.938 1.938.35 3.769.454 5.219.313 3.148-.309 5.175-.474 7.187-.657 2.012-.183 2.514-.838 3.625-.937 1.152-.103 2.292.385 6.375 0s5.589-.501 6.313-.719c.739-.222 1.795-.514 2.437-1.031 2.057.402 4.003.503 5.531.344 3.147-.329 5.178-.523 7.188-.72 1.613-.156 2.266-.63 3.031-.874.24-.088.463-.122.75-.156 1.148-.14 2.317.34 6.375-.25 4.058-.59 5.562-.778 6.281-1.032.717-.253 1.675-.558 2.313-1.093 1.92.211 3.72.151 5.156-.094 3.12-.533 5.112-.929 7.094-1.313 1.982-.384 2.474-1.04 3.562-1.28 1.13-.252 2.27.115 6.25-.876s5.43-1.42 6.125-1.781c.723-.376 1.762-.87 2.375-1.531 1.963-.012 3.794-.291 5.22-.844 2.95-1.145 4.872-1.87 6.687-2.75 1.455-.707 2.334-1.686 2.547-1.984.212-.298.111-.746.137-.767.043-.035.32-.085.48-.429.858-1.847 2.32-5.644
-2.435-6.329.113-.682.163-1.348.214-1.745.03-.23-.147-.865-.125-.924.031-.082.305-.265.36-.515.267-1.198.09-2.191-.125-3.609-.214-1.417-.983-4.622-1.637-5.476-.659-.862-1.223-1.011-1.748-1-.208.27.137.262.163.312.68.05.934.369 1.42.897s1.442 3.94 1.579 5.39.19 2.86-.088 3.468c-.278.609-.944.429-1.237.495.531.186.89.213.953 1.057.058.814-.134 1.64-.52 2.806-.391 1.18-1.845 4.35-2.286 4.599-.452.255-.952.182-1.288.05z" enable-background="new" filter="url(#gs)"/>
-    <path d="m988.75-263.84c1.912 0.634 4.55 1.758 6.125 2.813 1.575 1.054 2.896 1.482 5.531 3.375 2.609 1.873 5.027 3.015 7.313 4.062 2.47 1.132 5.752 2.155 9.531 3.938-1.207-1.259-7.139-3.365-9.031-4.188s-4.128-1.93-6.938-3.781-3.622-2.482-6-3.719c-2.377-1.237-4.08-1.95-6.53-2.5z" enable-background="new" filter="url(#gr)"/>
-    <path d="M957.5-260.78c1.91.618 4.583 1.71 6.156 2.75 1.574 1.04 2.896 1.482 5.531 3.375 2.609 1.873 5.027 3.015 7.313 4.063 2.47 1.131 5.752 2.154 9.531 3.937-1.207-1.258-7.201-3.396-9.094-4.219-1.892-.823-4.096-1.93-6.906-3.781-2.81-1.85-3.593-2.44-5.969-3.656s-4.113-1.939-6.562-2.469z" enable-background="new" filter="url(#gq)"/>
-    <path d="M926.09-257.38c1.908.597 4.553 1.664 6.125 2.688 1.571 1.023 2.87 1.44 5.5 3.28 2.603 1.823 5.029 2.973 7.313 4 2.467 1.111 5.755 2.094 9.53 3.845-1.205-1.249-7.171-3.319-9.062-4.125s-4.102-1.891-6.906-3.688c-2.804-1.796-3.627-2.402-6-3.594-2.373-1.191-4.054-1.903-6.5-2.406z" enable-background="new" filter="url(#gp)"/>
-    <path d="M894.91-253.56c1.902.554 4.587 1.589 6.156 2.594s2.874 1.408 5.5 3.219c2.6 1.791 5 2.871 7.281 3.875 2.465 1.083 5.76 2.04 9.532 3.75-1.205-1.236-7.175-3.245-9.063-4.032-1.888-.786-4.075-1.83-6.875-3.593s-3.6-2.369-5.969-3.532c-2.37-1.163-4.123-1.834-6.562-2.28z" enable-background="new" filter="url(#go)"/>
-    <path d="M863.72-248.66c1.88.43 4.504 1.38 6.063 2.313 1.558.932 2.852 1.257 5.468 3 2.59 1.724 4.981 2.708 7.25 3.625 2.452.99 5.74 1.877 9.5 3.5-1.201-1.208-7.152-3.067-9.03-3.782-1.88-.715-4.086-1.684-6.876-3.375s-3.585-2.228-5.937-3.28-4.026-1.713-6.438-2z" enable-background="new" filter="url(#gn)"/>
-    <path d="m833.16-241.38c1.848 0.296 4.47 0.976 6 1.781s2.814 1.056 5.375 2.531c2.535 1.46 4.89 2.326 7.125 3.063 2.414 0.797 5.657 1.467 9.375 2.844-1.188-1.129-7.088-2.59-8.938-3.156-1.85-0.567-4.003-1.374-6.75-2.844-2.746-1.47-3.5-1.92-5.812-2.781-2.311-0.861-4.005-1.32-6.375-1.438z" enable-background="new" filter="url(#gm)"/>
-    <path d="m802.91-232.31c1.822 0.211 4.366 0.8 5.875 1.531 1.51 0.73 2.756 0.93 5.281 2.281 2.5 1.338 4.832 2.049 7.031 2.657 2.377 0.656 5.565 1.073 9.22 2.187-1.168-1.045-6.93-2.103-8.75-2.562-1.822-0.46-3.953-1.127-6.657-2.438s-3.471-1.72-5.75-2.469-3.913-1.179-6.25-1.187z" enable-background="new" filter="url(#gl)"/>
-    <path d="M773.19-222.19c1.811.179 4.32.665 5.813 1.344 1.491.678 2.753.798 5.25 2.062 2.47 1.252 4.79 1.896 6.968 2.438 2.354.585 5.492.897 9.094 1.844-1.15-.992-6.852-1.784-8.656-2.188s-3.916-1.021-6.594-2.25c-2.678-1.229-3.403-1.61-5.656-2.281-2.253-.67-3.896-1.002-6.219-.969z" enable-background="new" filter="url(#gk)"/>
-    <path d="M743.56-211.19c1.793.13 4.273.55 5.75 1.188s2.716.741 5.188 1.937c2.446 1.184 4.72 1.747 6.874 2.219 2.328.51 5.42.68 9 1.562-1.143-.97-6.747-1.59-8.53-1.937-1.784-.347-3.884-.888-6.532-2.031-2.648-1.144-3.395-1.517-5.625-2.125-2.23-.61-3.826-.91-6.125-.813z" enable-background="new" filter="url(#gj)"/>
-    <g fill="#fff" filter="url(#gi)">
-     <path d="M744.94-212.12s7.222-3.223 9.063-3.5 3.352-.003 6 .563c2.647.565 8.735 2.215 11.188 3.374s5.312 3.563 5.312 3.563-7.146-2.78-10.188-3.563-7.645-2.083-10.375-2.312-11 1.875-11 1.875z"/>
-     <path d="m735.47-206.95s3.66-2.223 5.5-2.5 3.665 0.247 6.313 0.813 8.735 2.215 11.188 3.375 6.562 2.125 6.562 2.125-8.396-1.343-11.438-2.125-7.957-2.334-10.688-2.563-7.438 0.875-7.438 0.875zm24.38-10.66s8.544-3.299 10.398-3.458c1.854-0.16 3.642 0.48 6.248 1.212s8.577 2.766 10.95 4.08 6.414 2.537 6.414 2.537-8.294-1.873-11.279-2.848c-2.985-0.974-7.792-2.834-10.503-3.236s-12.228 1.713-12.228 1.713zm15.35-5.62s7.771-2.782 9.628-2.904c1.857-0.12 3.631 0.555 6.222 1.341 2.59 0.787 8.519 2.942 10.864 4.304 2.346 1.362 6.36 2.67 6.36 2.67s-8.253-2.045-11.217-3.08c-2.965-1.035-7.733-2.995-10.434-3.452-2.702-0.458-11.422 1.121-11.422 1.121zm14.44-4.72s8.683-3.52 10.542-3.605 3.62 0.624 6.195 1.46c2.575 0.837 8.46 3.107 10.779 4.514 2.318 1.408 6.307 2.793 6.307 2.793s-8.212-2.204-11.156-3.297-7.673-3.144-10.365-3.654-12.3 1.789-12.3 1.789zm14.86-5.38s7.808-2.583 9.666-2.668c1.86-0.085 3.62
-0.625 6.195 1.461 2.575 0.837 8.46 3.107 10.78 4.514 2.318 1.407 6.307 2.792 6.307 2.792s-8.213-2.204-11.156-3.296-7.673-3.144-10.365-3.654-11.426 0.85-11.426 0.85zm15.06-4.25s8.558-2.583 10.417-2.668 3.62 0.625 6.195 1.461c2.575 0.837 8.46 3.107 10.779 4.514 2.318 1.407 6.307 2.792 6.307 2.792s-8.212-2.204-11.156-3.296-7.673-3.144-10.365-3.654-12.176 0.85-12.176 0.85zm16.67-5.02s6.967-1.987 8.828-1.968c1.86 0.02 3.579 0.827 6.102 1.807 2.524 0.98 8.272 3.578 10.508 5.113 2.236 1.536 6.14 3.143 6.14 3.143s-8.075-2.662-10.952-3.919c-2.878-1.256-7.484-3.57-10.143-4.231-2.66-0.66-10.482 0.055-10.482 0.055zm14.5-3.4s7.688-2.028 9.548-1.968 3.56 0.902 6.063 1.936c2.502 1.033 8.194 3.752 10.397 5.335 2.203 1.582 6.072 3.272 6.072 3.272s-8.017-2.833-10.868-4.15c-2.85-1.318-7.407-3.73-10.05-4.446s-11.162 0.021-11.162 0.021zm14.09-3.21s8.17-1.97 10.027-1.854c1.857 0.115 3.532 1.01 6.002
-2.118s8.077 3.997 10.23 5.645 5.972 3.454 5.972 3.454-7.928-3.074-10.738-4.476-7.291-3.95-9.913-4.746c-2.621-0.796-11.58-0.141-11.58-0.141zm16.56-2.39s8.085-1.908 9.938-1.737c1.853 0.172 3.5 1.117 5.935 2.3 2.436 1.182 7.952 4.24 10.055 5.953s5.864 3.633 5.864 3.633-7.832-3.312-10.597-4.8-7.168-4.169-9.764-5.044c-2.597-0.876-11.431-0.305-11.431-0.305zm15.2-2.75s7.642-1.428 9.495-1.265c1.854 0.162 3.505 1.1 5.946 2.27s7.973 4.203 10.084 5.905c2.112 1.703 5.881 3.605 5.881 3.605s-7.847-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.788-4.998-2.6-0.863-10.998-0.77-10.998-0.77zm14.87-1.64s8.642-1.553 10.495-1.39c1.854 0.162 3.505 1.1 5.946 2.27s7.972 4.203 10.084 5.905c2.111 1.703 5.88 3.605 5.88 3.605s-7.846-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.787-4.998-2.601-0.863-11.998-0.644-11.998-0.644zm16.25-2.31s7.642-0.865 9.495-0.703c1.854 0.163 3.505 1.1 5.946 2.27s7.973 4.203 10.084
-5.906c2.112 1.702 5.881 3.605 5.881 3.605s-7.847-3.275-10.62-4.749c-2.772-1.474-7.187-4.135-9.788-4.998-2.6-0.862-10.998-1.331-10.998-1.331zm15.13-1.19s8.58-1.49 10.433-1.328c1.854 0.163 3.505 1.1 5.946 2.27s7.972 4.203 10.084 5.906c2.111 1.702 5.88 3.605 5.88 3.605s-7.846-3.275-10.62-4.749c-2.772-1.474-7.187-4.135-9.787-4.998-2.601-0.862-11.935-0.706-11.935-0.706zm16.25-2.06s7.83-0.803 9.683-0.64c1.854 0.162 3.505 1.1 5.946 2.27s7.972 4.203 10.084 5.905c2.111 1.703 5.88 3.605 5.88 3.605s-7.846-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.787-4.998-2.601-0.863-11.185-1.394-11.185-1.394zm15.37-1.25s8.392-1.178 10.245-1.015c1.854 0.162 3.505 1.1 5.946 2.27s7.972 4.203 10.084 5.905c2.111 1.703 5.88 3.605 5.88 3.605s-7.847-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.788-4.998-2.6-0.863-11.748-1.02-11.748-1.02zm16.19-2.06s6.892-0.99 8.745-0.828c1.854 0.163 3.505 1.1 5.946 2.27s7.973 4.203
-10.084 5.906c2.112 1.702 5.881 3.605 5.881 3.605s-7.847-3.275-10.62-4.749-7.188-4.135-9.788-4.998c-2.6-0.862-10.248-1.206-10.248-1.206zm17.16-0.94s6.83-1.178 8.683-1.015c1.854 0.162 3.505 1.1 5.946 2.27 2.44 1.171 7.972 4.203 10.084 5.905 2.111 1.703 5.88 3.605 5.88 3.605s-7.847-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.788-4.998-2.6-0.863-10.185-1.02-10.185-1.02zm16.1-2s6.08-0.428 7.933-0.265c1.854 0.162 3.505 1.1 5.946 2.27 2.44 1.171 7.972 4.203 10.084 5.905 2.111 1.703 5.88 3.605 5.88 3.605s-7.847-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.788-4.998-2.6-0.863-9.435-1.77-9.435-1.77zm15.8-1.37s6.454-0.678 8.308-0.515c1.854 0.162 3.505 1.1 5.946 2.27 2.44 1.171 7.972 4.203 10.084 5.905 2.111 1.703 5.88 3.605 5.88 3.605s-7.847-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.788-4.998-2.6-0.863-9.81-1.52-9.81-1.52zm15.6-1.86s5.498-0.91 7.358-0.853c1.86 0.056 3.562 0.896 6.066 1.925
-2.504 1.03 8.2 3.739 10.406 5.318 2.205 1.578 6.078 3.261 6.078 3.261s-8.022-2.819-10.875-4.131c-2.853-1.313-7.413-3.716-10.06-4.429-2.645-0.712-8.973-1.091-8.973-1.091zm17.4-2.46s4.547-1.156 6.408-1.186c1.86-0.03 3.6 0.73 6.149 1.642 2.55 0.912 8.365 3.354 10.64 4.829 2.277 1.474 6.224 2.976 6.224 2.976s-8.145-2.444-11.055-3.623c-2.91-1.178-7.578-3.368-10.253-3.957-2.676-0.588-8.113-0.68-8.113-0.68zm14.5-3.03s5.96-1.774 7.82-1.83c1.86-0.057 3.61 0.68 6.172 1.555 2.562 0.876 2.522 0.857 5.333 1.49 2.797 0.63 7.077 1.513 7.077 1.513s-3.616-0.016-6.792-0.466c-3.116-0.441-7.375-1.698-10.058-2.249-2.684-0.55-9.552-0.013-9.552-0.013z" enable-background="new"/>
-     <path d="M1099.2-279.93c.161.269 11.208-4.6 12.188-4.688.98-.087 2 3.125 2 3.125s-.775-1.504-2.875-1.062-11.301 2.671-11.312 2.625z"/>
-    </g>
-    <path d="M1107.5-284.09c-.419.213-.156.094-.647.306-.486.21-1.724.574-4.08 1.459-3.33 1.25-5.83 2.153-7.026 3.066-1.536.021-3.72.233-5.656.719a227.709 227.709 0 0 1-6.75 1.593c-1.895.42-1.676.643-2.875.875-1.297.252-1.721-.009-5.438.782-3.49.742-8.894 1.93-10.156 2.687-1.583-.18-3.867-.322-5.843-.031-3.04.447-4.917.673-6.844.906-.655.08-1.041.201-1.344.282-.426.131-.686.26-1.375.343-1.311.16-1.762-.157-5.531.282-3.554.413-9.005 1.272-10.25 1.937-1.599-.297-3.858-.534-5.844-.344-3.059.294-4.972.484-6.906.657-1.934.172-1.689.422-2.906.53-1.317.118-1.76-.163-5.532.25-3.541.39-9.007 1.21-10.28 1.876-1.6-.295-3.888-.507-5.876-.313-3.058.3-4.94.48-6.875.657-.657.06-1.04.178-1.343.25-.428.118-.684.218-1.375.28-1.316.121-1.76-.194-5.532.22-3.556.39-9.005 1.239-10.25
-1.906-1.598-.294-3.86-.524-5.843-.313-3.056.326-4.974.526-6.907.719-1.932.192-1.69.44-2.906.562-1.315.132-1.763-.164-5.53.282-3.54.418-8.979 1.292-10.25 1.969-1.599-.282-3.86-.42-5.845-.188-3.052.358-4.945.568-6.875.781-.656.073-1.04.173-1.344.25-.426.127-.684.267-1.375.344-1.313.146-1.767-.174-5.53.313-3.55.458-8.98 1.419-10.22 2.125-1.593-.245-3.834-.382-5.812-.125-3.048.394-4.95.648-6.875.906-1.925.258-1.726.493-2.938.656-1.31.176-1.747-.104-5.5.469-3.524.538-8.923 1.699-10.188 2.437-1.587-.203-3.845-.254-5.812.094-3.026.536-4.9.862-6.813 1.187-.65.111-1.013.271-1.312.375-.42.165-.664.332-1.344.47-1.295.26-1.727-.007-5.438.812-3.498.772-8.846 2.383-10.062 3.219-1.562-.078-3.757.085-5.687.593-2.972.783-4.818 1.232-6.688 1.75s-1.666.768-2.843 1.094c-1.273.353-1.697.107-5.344 1.188-3.425 1.014-8.65 2.933-9.875 3.843-1.539.013-3.72.273-5.625.875-2.931.928-4.75 1.459-6.594
-2.063-.627.205-.992.392-1.281.531-.408.214-.653.409-1.313.625-1.254.412-1.686.19-5.28 1.438-3.39 1.177-8.596 3.213-9.782 4.156-1.524.06-3.65.395-5.531 1.062-2.898 1.029-4.7 1.676-6.531 2.313-1.833.637-1.628.848-2.782 1.25-1.246.434-1.663.2-5.218 1.562-3.34 1.28-8.488 3.483-9.688 4.47-1.507.107-3.636.498-5.5 1.218a1044.752 1044.752 0 0 1-6.437 2.469c-.617.233-.997.442-1.282.593v1.094c.112-.222.386-.817.907-1.094.698-.37 4.813-1.993 6.812-2.718 1.657-.602 4.154-1.329 5.969-1.313.302.003.588.051.844.094 1.842.308 7.468 1.562 7.468 1.562s-6.233-1.646-7.03-1.843c-.191-.048-.536-.07-.97-.063 1.146-.87 4.762-2.393 7.344-3.437 2.839-1.148 3.117-1.252 5.063-1.657 2.008-.417 3.156-.5 3.156-.5s-.082-.6.969-1.125c.705-.351 4.887-1.892 6.906-2.562 1.952-.648 5.057-1.359 6.875-1 1.863.367 7.531 1.812 7.531 1.812s-6.287-1.87-7.094-2.093c-.193-.054-.53-.086-.968-.094 1.158-.833 4.794-2.195 7.406-3.156
-2.87-1.056 3.167-1.162 5.125-1.532 1.853-.35 2.859-.425 3.031-.437.114-.217.377-.81.906-1.063.71-.338 4.926-1.712 6.97-2.312 1.692-.497 4.24-1.037 6.093-.906.308.021.613.097.875.156 1.881.424 7.594 2.031 7.594 2.031s-6.342-2.065-7.157-2.312c-.194-.06-.557-.104-1-.125 1.17-.798 4.863-2.057 7.5-2.938 2.898-.968 3.233-1.003 5.22-1.281 2.049-.287 3.187-.313 3.187-.313s-.073-.607 1-1.062c.72-.306 4.99-1.5 7.062-2 2.003-.483 5.199-.928 7.063-.406 1.91.535 7.719 2.5 7.719 2.5s-6.423-2.424-7.25-2.72c-.198-.07-.583-.14-1.032-.187 1.188-.728 4.916-1.774 7.594-2.5 2.944-.797 3.292-.77 5.313-.906 1.913-.128 2.947-.07 3.125-.062.117-.204.391-.78.937-.97.732-.253 5.079-1.047 7.188-1.374 1.748-.271 4.4-.485 6.312-.094.318.065.605.186.875.281 1.94.69 7.844 3.094 7.844 3.094s-6.535-2.95-7.375-3.312c-.201-.087-.575-.167-1.031-.25 1.206-.633 5.03-1.396 7.75-1.906 2.99-.562 3.3-.53 5.344-.532 2.109-.002
-3.312.125 3.312.125s-.073-.63 1.031-.937c.74-.206 5.126-.834 7.25-1.063 2.053-.22 5.319-.252 7.22.47 1.947.738 7.843 3.374 7.843 3.374s-6.563-3.179-7.406-3.562c-.202-.092-.543-.187-1-.282 1.21-.602 4.984-1.248 7.718-1.656 3.005-.448 3.326-.452 5.375-.406 1.94.043 3.007.194 3.188.219.119-.194.384-.766.937-.907.743-.188 5.155-.734 7.282-.937 1.763-.169 4.42-.234 6.343.25.32.08.604.203.875.312 1.953.784 7.907 3.47 7.907 3.47s-6.592-3.254-7.438-3.657c-.202-.096-.572-.207-1.031-.313 1.214-.574 5.044-1.122 7.781-1.5 3.009-.415 3.323-.442 5.375-.375 2.118.07 3.313.25 3.313.25s-.078-.637 1.03-.906c.745-.18 5.153-.663 7.282-.844 2.059-.174 5.343-.124 7.25.657 1.955.8 7.875 3.53 7.875 3.53s-6.56-3.308-7.406-3.718c-.202-.098-.572-.203-1.031-.312 1.215-.564 5.01-1.115 7.75-1.47 3.01-.389 3.321-.397 5.375-.312 1.944.08 3.006.254 3.187.282.12-.191.383-.746.938-.875.744-.174 5.15-.65 7.28-.813
-1.767-.134 4.45-.126 6.376.375.32.083.603.201.875.313 1.954.8 7.906 3.562 7.906 3.562s-6.591-3.34-7.437-3.75c-.203-.098-.572-.203-1.032-.312 1.215-.564 5.042-1.084 7.782-1.438 3.01-.39 3.352-.429 5.406-.344 2.12.088 3.312.313 3.312.313s-.078-.65 1.032-.906c.744-.173 5.15-.624 7.28-.782 2.061-.152 5.344-.096 7.25.688 1.956.804 7.876 3.5 7.876 3.5s-6.56-3.276-7.406-3.688c-.203-.098-.572-.202-1.032-.312 1.216-.562 5.012-1.128 7.75-1.5 3.01-.41 3.323-.416 5.375-.344 1.943.068 3.008.165 3.188.188.119-.195.384-.73.937-.875.742-.197 5.131-.83 7.25-1.094 1.757-.22 4.406-.333 6.313.031.317.06.606.19.875.281 1.936.661 7.844 2.938 7.844 2.938s-6.537-2.807-7.375-3.156c-.2-.084-.577-.174-1.032-.25 1.204-.651 5.02-1.372 7.72-2 2.966-.69 3.288-.756 5.312-.875 2.088-.124 3.28-.032 3.28-.032s-.086-.632 1-1.03c.73-.269 5.048-1.339 7.126-1.813 2.008-.46 5.168-1.03 7-.625 1.878.414 13.578 3.015 13.578
-3.015s-12.328-3.022-13.141-3.265c-.195-.058-.559-.107-1-.125 1.167-.804 3.514-1.688 6.11-2.703 1.68-.659.923-.377 2.775-1.004 1.754-.594 2.486-1.01 2.63-1.113.347-.207-.355-.122-.544-.042z" enable-background="new" filter="url(#gh)" opacity=".25"/>
-    <path d="m1082.6-275.12c1.873 0.393 4.496 1.146 6.031 1.969s2.822 1.056 5.375 2.5c2.527 1.43 4.796 2.007 6.969 2.531 2.348 0.566 5.435 0.715 8.844 1.188-1.09-0.84-6.608-1.173-8.406-1.563-1.8-0.39-3.895-1.016-6.594-2.313-2.7-1.296-3.495-1.799-5.813-2.687-2.318-0.889-4.004-1.383-6.406-1.625z" enable-background="new" filter="url(#gg)" opacity=".25"/>
-    <path d="M1051.5-270c1.905.578 4.528 1.616 6.094 2.594 1.565.978 2.88 1.36 5.5 3.125 2.593 1.747 4.986 2.71 7.25 3.594 2.446.955 5.682 1.657 9.406 3.062-1.19-1.138-7.063-2.687-8.938-3.375-1.874-.688-4.081-1.566-6.874-3.281-2.794-1.715-3.574-2.284-5.938-3.406-2.364-1.123-4.057-1.835-6.5-2.313z" enable-background="new" filter="url(#gf)" opacity=".25"/>
-    <path d="m1020.2-266.84c1.912 0.638 4.581 1.755 6.156 2.813 1.575 1.057 2.896 1.508 5.531 3.406 2.61 1.878 5.029 3.03 7.313 4.062 2.468 1.116 5.764 2.174 9.531 3.844-1.203-1.222-7.203-3.314-9.094-4.125-1.89-0.81-4.064-1.894-6.874-3.75s-3.622-2.477-6-3.719c-2.379-1.242-4.111-1.975-6.563-2.531z" enable-background="new" filter="url(#ge)" opacity=".25"/>
-    <path d="M1110.2-266.89c.15.049.688.631.11 1.484-.81 1.195-5.705 3.325-8.563 4.125-2.845.798-6.29.978-10.562-.375-4.302-1.362-5.47-2.468-10.656-4.312 4.664 2.115 6.195 3.952 10.125 5.344 1.62.574 3.367.94 5.062 1.03-.445.327-1.53.984-3.562 1.595-2.796.84-6.65 1.534-8.25 1.625-1.515.086-3.142-.513-3.438-.625.167.103.374.377-.25 1.03-.899.945-6.147 1.924-9.125 2.25-2.964.326-6.521-.015-10.906-1.905-3.978-1.715-5.339-2.916-9.406-4.75v.156c3.643 2.095 5.284 3.883 8.875 5.562 1.73.81 3.592 1.41 5.406 1.72-.534.286-1.557.71-3.437 1.03-2.87.488-6.81.817-8.438.75-.85-.034-1.728-.184-2.406-.406-.685-.215-1.19-.444-1.312-.5.169.107.43.403-.22 1.031-.909.88-6.245 1.337-9.25 1.47-2.99.131-6.588-.451-11-2.563-4.44-2.127-5.64-3.402-10.905-5.782 4.734 2.597 6.286 4.63 10.344 6.72 1.673.861 3.485 1.493 5.25
-1.937-.463.233-1.59.688-3.688.937-2.886.343-6.834.493-8.468.375-1.547-.111-3.232-.857-3.532-1 .17.12.414.41-.218 1-.913.851-6.244 1.262-9.25 1.375-2.993.113-6.59-.49-11-2.594-4.002-1.908-5.388-3.137-9.47-5.093v.156c3.656 2.204 5.295 4.053 8.907 5.906 1.74.893 3.637 1.528 5.469 1.969-.54.248-1.578.615-3.469.844-2.886.348-6.866.52-8.5.406a9.446 9.446 0 0 1-2.406-.5 12.532 12.532 0 0 1-1.313-.531c.17.112.465.422-.187 1.03-.913.853-6.275 1.294-9.281 1.407-2.993.112-6.594-.528-11-2.594-4.437-2.08-5.647-3.331-10.906-5.656 4.729 2.548 6.29 4.578 10.344 6.625 1.671.844 3.485 1.467 5.25 1.906-.464.235-1.59.684-3.688.938-2.886.348-6.836.57-8.469.469-1.544-.096-3.2-.83-3.5-.97.17.12.382.405-.25 1-.912.861-6.246 1.331-9.25 1.47-2.99.138-6.567-.451-10.969-2.47-3.993-1.83-5.365-3.028-9.437-4.905v.156c3.647 2.133 5.27 3.935 8.875 5.719 1.737.86 3.607 1.45 5.437
-1.875-.54.253-1.55.64-3.437.906-2.88.404-6.838.646-8.469.562a9.36 9.36 0 0 1-2.406-.437 12.971 12.971 0 0 1-1.313-.5c.17.109.432.41-.218 1.031-.911.87-6.25 1.392-9.25 1.563-2.987.17-6.574-.316-10.97-2.282-4.424-1.978-5.605-3.228-10.843-5.375 4.71 2.388 6.27 4.39 10.312 6.344a23.73 23.73 0 0 0 5.218 1.781c-.461.25-1.597.713-3.687 1.032-2.876.438-6.78.733-8.406.687-1.539-.043-3.233-.745-3.532-.875.169.113.411.414-.218 1.031-.908.891-6.203 1.529-9.188 1.813-2.971.283-6.573-.176-10.938-1.938-3.96-1.598-5.329-2.795-9.344-4.312v.156c3.596 1.811 5.239 3.582 8.813 5.156 1.722.759 3.587 1.29 5.406 1.625-.536.28-1.566.688-3.437 1.063-2.856.572-6.79 1.02-8.407 1.031-.844.006-1.706-.08-2.375-.25-.676-.162-1.16-.33-1.28-.375.166.094.422.383-.22 1.062-.897.951-6.186 1.918-9.125 2.438-2.925.518-6.432.374-10.719-1.031-4.315-1.415-5.472-2.53-10.562-3.969 4.577 1.751 6.09 3.56 10.031 5 1.627.594 3.37.956
-5.094 1.156-.453.297-1.555.884-3.594 1.469-2.804.805-6.638 1.576-8.218 1.75-1.495.165-3.117-.317-3.407-.406.164.09.393.36-.218 1.062-.883 1.014-6.045 2.372-8.938 3.063-2.88.687-6.335.76-10.562-.438-3.835-1.086-5.172-2.072-9.062-3.125v.156c3.484 1.395 5.07 2.92 8.53 4.032 1.669.535 3.457.786 5.22.875-.52.352-1.5.914-3.313 1.53-2.765.942-6.59 1.936-8.156 2.157-.818.115-1.633.123-2.281.031-.655-.083-1.133-.218-1.25-.25.162.075.434.34-.188 1.094-.87 1.055-6.01 2.66-8.875 3.438-2.852.774-6.259.958-10.438-.094-4.206-1.06-5.356-2.042-10.344-3.156 4.485 1.46 5.97 3.135 9.813 4.25 1.585.46 3.287.638 4.969.687-.442.337-1.513 1.028-3.5 1.781-2.734 1.037-6.452 2.163-8 2.438-1.465.26-3.06-.117-3.344-.188.16.08.38.321-.219 1.063-.865 1.07-5.916 2.818-8.75 3.687-2.82.866-6.207 1.157-10.344.22-3.753-.852-5.048-1.717-8.875-2.595v.157c3.428 1.237 4.987 2.632 8.375 3.53 1.632.434 3.367.584
-5.094.563-.51.384-1.477 1.022-3.25 1.75-2.706 1.112-6.436 2.308-7.969 2.625-.8.166-1.612.219-2.25.157v1.406c.227-.145.449-.273.719-.375 1.08-.41 2.171-.216 6-1.688 3.828-1.471 5.224-2.005 5.906-2.406.68-.4 1.612-.88 2.219-1.531 1.827-.138 3.57-.493 4.937-1 2.968-1.1 4.876-1.806 6.782-2.469 1.905-.663 2.354-1.415 3.406-1.781 1.091-.38 2.195-.166 6.062-1.531 3.868-1.366 5.283-1.827 5.969-2.22.701-.4 1.7-.932 2.313-1.593 1.97-.055 3.816-.385 5.28-.875 3.002-1.005 4.927-1.622 6.845-2.25 1.538-.504 2.174-1.047 2.906-1.437.23-.135.475-.254.75-.344 1.098-.36 2.181-.082 6.094-1.313 3.912-1.23 5.366-1.673 6.062-2.03.694-.358 1.63-.794 2.25-1.407 1.865-.023 3.636-.267 5.031-.688 3.03-.913 4.993-1.43 6.938-1.968 1.945-.54 2.426-1.265 3.5-1.563 1.114-.31 2.22.007 6.187-1.031 3.968-1.039 5.418-1.433 6.125-1.75.735-.33 1.814-.754 2.438-1.375 1.997.116 3.857-.02 5.344-.375 3.078-.735 5.083-1.101
-7.062-1.5 1.588-.32 2.244-.79 3-1.094.238-.107.467-.193.75-.25 1.134-.23 2.305.209 6.344-.5s5.5-.927 6.219-1.187c.715-.26 1.704-.568 2.343-1.094 1.925.24 3.748.224 5.188 0 3.126-.488 5.155-.7 7.156-.969 2.002-.268 2.489-.945 3.594-1.094 1.146-.154 2.276.302 6.344-.219 4.068-.52 5.56-.695 6.28-.937.738-.247 1.799-.586 2.438-1.125 2.05.335 3.974.398 5.5.219 3.143-.37 5.18-.56 7.188-.782 1.61-.178 2.265-.608 3.031-.843a3.43 3.43 0 0 1 .781-.188c1.15-.128 2.302.347 6.375-.125s5.56-.61 6.282-.844c.719-.232 1.7-.473 2.343-.968 1.937.333 3.77.404 5.22.25 3.145-.335 5.177-.519 7.187-.719 2.01-.2 2.484-.826 3.593-.938 1.152-.115 2.297.366 6.375-.062s5.59-.562 6.313-.781c.74-.224 1.796-.514 2.437-1.031 2.058.398 4.002.493 5.532.343 3.148-.308 5.175-.473 7.187-.656 1.614-.147 2.263-.56 3.031-.781.242-.081.494-.13.782-.156 1.152-.106 2.293.392 6.375 0 4.082-.393 5.589-.531 6.312-.75.721-.219
-1.7-.448 2.344-.938 1.938.35 3.769.454 5.219.313 3.148-.309 5.175-.474 7.187-.657 2.012-.183 2.514-.838 3.625-.937 1.152-.103 2.292.385 6.375 0s5.589-.501 6.313-.719c.739-.222 1.795-.514 2.437-1.031 2.057.402 4.003.503 5.531.344 3.147-.329 5.178-.523 7.188-.72 1.613-.156 2.266-.63 3.031-.874.24-.088.463-.122.75-.156 1.148-.14 2.317.34 6.375-.25 4.058-.59 5.562-.778 6.281-1.032.717-.253 1.675-.558 2.313-1.093 1.92.211 3.72.151 5.156-.094 3.12-.533 5.112-.929 7.094-1.313 1.982-.384 2.474-1.04 3.562-1.28 1.13-.252 2.27.115 6.25-.876s5.43-1.42 6.125-1.781c.723-.376 1.762-.87 2.375-1.531 1.963-.012 3.794-.291 5.22-.844 2.95-1.145 4.872-1.87 6.687-2.75 1.455-.707 2.334-1.686 2.547-1.984.212-.298.111-.746.137-.767.043-.035.32-.085.48-.429.858-1.847 2.32-5.644
-2.435-6.329.113-.682.163-1.348.214-1.745.03-.23-.147-.865-.125-.924.031-.082.305-.265.36-.515.267-1.198.09-2.191-.125-3.609-.214-1.417-.983-4.622-1.637-5.476-.659-.862-1.223-1.011-1.748-1-.208.27.137.262.163.312.68.05.934.369 1.42.897s1.221 3.85 1.358 5.301.19 2.86-.088 3.469c-.278.608-.723.517-1.016.583.531.186.67.125.732.969.058.813-.134 1.64-.52 2.806-.392 1.18-1.846 4.35-2.286 4.598-.452.256-.731.27-1.067.14z" enable-background="new" filter="url(#ff)" opacity=".25"/>
-    <path d="m988.75-263.84c1.912 0.634 4.55 1.758 6.125 2.813 1.575 1.054 2.896 1.482 5.531 3.375 2.609 1.873 5.027 3.015 7.313 4.062 2.47 1.132 5.752 2.155 9.531 3.938-1.207-1.259-7.139-3.365-9.031-4.188s-4.128-1.93-6.938-3.781-3.622-2.482-6-3.719c-2.377-1.237-4.08-1.95-6.53-2.5z" enable-background="new" filter="url(#fe)" opacity=".25"/>
-    <path d="M957.5-260.78c1.91.618 4.583 1.71 6.156 2.75 1.574 1.04 2.896 1.482 5.531 3.375 2.609 1.873 5.027 3.015 7.313 4.063 2.47 1.131 5.752 2.154 9.531 3.937-1.207-1.258-7.201-3.396-9.094-4.219-1.892-.823-4.096-1.93-6.906-3.781-2.81-1.85-3.593-2.44-5.969-3.656s-4.113-1.939-6.562-2.469z" enable-background="new" filter="url(#fd)" opacity=".25"/>
-    <path d="M926.09-257.38c1.908.597 4.553 1.664 6.125 2.688 1.571 1.023 2.87 1.44 5.5 3.28 2.603 1.823 5.029 2.973 7.313 4 2.467 1.111 5.755 2.094 9.53 3.845-1.205-1.249-7.171-3.319-9.062-4.125s-4.102-1.891-6.906-3.688c-2.804-1.796-3.627-2.402-6-3.594-2.373-1.191-4.054-1.903-6.5-2.406z" enable-background="new" filter="url(#fc)" opacity=".25"/>
-    <path d="M894.91-253.56c1.902.554 4.587 1.589 6.156 2.594s2.874 1.408 5.5 3.219c2.6 1.791 5 2.871 7.281 3.875 2.465 1.083 5.76 2.04 9.532 3.75-1.205-1.236-7.175-3.245-9.063-4.032-1.888-.786-4.075-1.83-6.875-3.593s-3.6-2.369-5.969-3.532c-2.37-1.163-4.123-1.834-6.562-2.28z" enable-background="new" filter="url(#fb)" opacity=".25"/>
-    <path d="M863.72-248.66c1.88.43 4.504 1.38 6.063 2.313 1.558.932 2.852 1.257 5.468 3 2.59 1.724 4.981 2.708 7.25 3.625 2.452.99 5.74 1.877 9.5 3.5-1.201-1.208-7.152-3.067-9.03-3.782-1.88-.715-4.086-1.684-6.876-3.375s-3.585-2.228-5.937-3.28-4.026-1.713-6.438-2z" enable-background="new" filter="url(#fa)" opacity=".25"/>
-    <path d="m833.16-241.38c1.848 0.296 4.47 0.976 6 1.781s2.814 1.056 5.375 2.531c2.535 1.46 4.89 2.326 7.125 3.063 2.414 0.797 5.657 1.467 9.375 2.844-1.188-1.129-7.088-2.59-8.938-3.156-1.85-0.567-4.003-1.374-6.75-2.844-2.746-1.47-3.5-1.92-5.812-2.781-2.311-0.861-4.005-1.32-6.375-1.438z" enable-background="new" filter="url(#ez)" opacity=".25"/>
-    <path d="m802.91-232.31c1.822 0.211 4.366 0.8 5.875 1.531 1.51 0.73 2.756 0.93 5.281 2.281 2.5 1.338 4.832 2.049 7.031 2.657 2.377 0.656 5.565 1.073 9.22 2.187-1.168-1.045-6.93-2.103-8.75-2.562-1.822-0.46-3.953-1.127-6.657-2.438s-3.471-1.72-5.75-2.469-3.913-1.179-6.25-1.187z" enable-background="new" filter="url(#ey)" opacity=".25"/>
-    <path d="M773.19-222.19c1.811.179 4.32.665 5.813 1.344 1.491.678 2.753.798 5.25 2.062 2.47 1.252 4.79 1.896 6.968 2.438 2.354.585 5.492.897 9.094 1.844-1.15-.992-6.852-1.784-8.656-2.188s-3.916-1.021-6.594-2.25c-2.678-1.229-3.403-1.61-5.656-2.281-2.253-.67-3.896-1.002-6.219-.969z" enable-background="new" filter="url(#ex)" opacity=".25"/>
-    <path d="M743.56-211.19c1.793.13 4.273.55 5.75 1.188s2.716.741 5.188 1.937c2.446 1.184 4.72 1.747 6.874 2.219 2.328.51 5.42.68 9 1.562-1.143-.97-6.747-1.59-8.53-1.937-1.784-.347-3.884-.888-6.532-2.031-2.648-1.144-3.395-1.517-5.625-2.125-2.23-.61-3.826-.91-6.125-.813z" enable-background="new" filter="url(#ew)" opacity=".25"/>
-   </g>
-  </g>
-  <path d="M3840.7 940.04c1.651-7.722 3.538-13.762 4.889-23.633.803-8.777 3.33-4.873 7.302-20.148 1.41-5.374 5.507.94 9.016-5.757 1.278-1.927 2.901-.97 4.508-.151 3.787 3.165 5.859 8.887 8.381 13.937 6.174 14.326 20.651 19.06 23.62 15.149 1.442-6.97 7.926-12.979 12.444-26.663.752-2.694 11.796-20.982 14.73-15.755" enable-background="new" fill="none" stroke="#000"/>
-  <path d="M3865.4 915.04c7.405-7.758 13.89-21.376 20.826-32.117 3.33-4.726 6.909 7.717 10.857 8.635 2.31-.523 3.734 2.886 5.714 3.939 5.186 3.162 2.412 9.274 10.032 15.452 6.191 4.128 8.958-16.313 14.985-17.573 4.906-1.207 8.145-.758 11.683-.606 3.95.333 4.102-8.393 6.096-12.725 2.997-6.731 7.196-4.438 10.203-11.376 1.023-3.323 1.965-7.224 2.75-12.257.887-4.8 3.057.734 4.825 3.03" enable-background="new" fill="none" stroke="#000"/>
-  <g transform="matrix(1.0057 0 0 2.3995 3249.4 125.01)" clip-path="url(#ev)" filter="url(#eu)">
-   <path d="M910.14 746.31l32.613 5.174-.361-23.876 7.188-29.682-8.45-5.264-21.823 26.511-9.167 27.137z" enable-background="accumulate" fill="#fff" fill-rule="evenodd"/>
-   <path d="M877.52 650.19h123.04v172.53H877.52z" enable-background="accumulate" fill="none"/>
-  </g>
-  <g transform="matrix(1.0057 0 0 2.3995 3249.4 125.01)" clip-path="url(#et)" filter="url(#es)">
-   <path d="M964 754.69l18.429 7.465 9.071-36.964-14.87 4.839L964 754.69z" enable-background="accumulate" fill="#fff" fill-rule="evenodd"/>
-   <path d="M924.9 677.06h142.13v125.16H924.9z" enable-background="accumulate" fill="none"/>
-  </g>
- </g>
- <path d="m592.8 398.62l2899.5-102.16" fill="#f8d615" fill-rule="evenodd" marker-end="url(#er)" stroke="#f8d615" stroke-width="17.844"/>
- <path d="m576.48 779.92l2914.5 416.44" enable-background="new" fill="#f8d615" fill-rule="evenodd" marker-end="url(#eq)" stroke="#f8d615" stroke-width="18"/>
- <g font-family="sans-serif" letter-spacing="0" word-spacing="0">
-  <text transform="translate(48.571 195.53)" x="80.219" y="107.387" fill="#f83615" font-size="40" style="line-height:125%">
-   <tspan x="80.219" y="107.387" font-size="50">CROP_DEFAULT</tspan>
-  </text>
-  <g font-size="45.314">
-   <text transform="matrix(.96106 0 0 1.0405 48.571 195.53)" x="3861.367" y="1281.72" enable-background="new" fill="#f80000" fill-opacity="0" style="line-height:125%">
-    <tspan x="3861.367" y="1281.72" font-size="56.642">COMPOSE_PADDED</tspan>
-   </text>
-   <text transform="matrix(.96106 0 0 1.0405 48.571 195.53)" x="3615.155" y="49.157" enable-background="new" fill="#f8d615" style="line-height:125%">
-    <tspan x="3615.155" y="49.157" font-size="50">COMPOSE_ACTIVE</tspan>
-   </text>
-   <text transform="matrix(.96106 0 0 1.0405 48.571 195.53)" x="2429.153" y="-3.166" enable-background="new" fill="#f83615" style="line-height:125%">
-    <tspan x="2429.153" y="-3.166" font-size="50">COMPOSE_DEFAULT</tspan>
-   </text>
-   <text transform="matrix(.96106 0 0 1.0405 48.571 195.53)" x="3681.545" y="1289.954" enable-background="new" fill="#f815bb" style="line-height:125%">
-    <tspan x="3681.545" y="1289.954" font-size="50">COMPOSE_PADDED</tspan>
-   </text>
-  </g>
-  <text transform="matrix(.96106 0 0 1.0405 48.571 195.53)" x="2438.062" y="1368.429" enable-background="new" font-size="50" style="line-height:125%">
-   <tspan x="2438.062" y="1368.429">COMPOSE_BOUNDS</tspan>
-  </text>
-  <g font-size="40">
-   <text transform="translate(48.571 195.53)" x="8.082" y="1438.896" enable-background="new" style="line-height:125%">
-    <tspan x="8.082" y="1438.896" font-size="50">CROP_BOUNDS</tspan>
-   </text>
-   <text transform="translate(48.571 195.53)" x="1455.443" y="-26.808" enable-background="new" style="line-height:125%">
-    <tspan x="1455.443" y="-26.808" font-size="50">overscan area</tspan>
-   </text>
-   <text transform="translate(48.571 195.53)" x="179.631" y="385.388" enable-background="new" fill="#f8d615" style="line-height:125%">
-    <tspan x="179.631" y="385.388" font-size="50">CROP_ACTIVE</tspan>
-   </text>
-   <text transform="translate(48.571 195.53)" x="636.674" y="-138.845" enable-background="new" style="line-height:125%">
-    <tspan x="636.674" y="-138.845" font-size="70" font-weight="bold">DATA SOURCE</tspan>
-   </text>
-  </g>
-  <text transform="matrix(.96106 0 0 1.0405 48.571 195.53)" x="3178.715" y="-129.061" enable-background="new" font-size="45.314" style="line-height:125%">
-   <tspan x="3178.715" y="-129.061" font-size="70" font-weight="bold">DATA SINK</tspan>
-  </text>
- </g>
-</svg>
diff --git a/Documentation/media/uapi/v4l/selections-common.rst b/Documentation/media/uapi/v4l/selections-common.rst
deleted file mode 100644
index 28b32db280f2..000000000000
--- a/Documentation/media/uapi/v4l/selections-common.rst
+++ /dev/null
@@ -1,30 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _v4l2-selections-common:
-
-Common selection definitions
-============================
-
-While the :ref:`V4L2 selection API <selection-api>` and
-:ref:`V4L2 subdev selection APIs <v4l2-subdev-selections>` are very
-similar, there's one fundamental difference between the two. On
-sub-device API, the selection rectangle refers to the media bus format,
-and is bound to a sub-device's pad. On the V4L2 interface the selection
-rectangles refer to the in-memory pixel format.
-
-This section defines the common definitions of the selection interfaces
-on the two APIs.
-
-
-.. toctree::
-    :maxdepth: 1
-
-    v4l2-selection-targets
-    v4l2-selection-flags
diff --git a/Documentation/media/uapi/v4l/standard.rst b/Documentation/media/uapi/v4l/standard.rst
deleted file mode 100644
index bf8959b72988..000000000000
--- a/Documentation/media/uapi/v4l/standard.rst
+++ /dev/null
@@ -1,192 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _standard:
-
-***************
-Video Standards
-***************
-
-Video devices typically support one or more different video standards or
-variations of standards. Each video input and output may support another
-set of standards. This set is reported by the ``std`` field of struct
-:c:type:`v4l2_input` and struct
-:c:type:`v4l2_output` returned by the
-:ref:`VIDIOC_ENUMINPUT` and
-:ref:`VIDIOC_ENUMOUTPUT` ioctls, respectively.
-
-V4L2 defines one bit for each analog video standard currently in use
-worldwide, and sets aside bits for driver defined standards, e. g.
-hybrid standards to watch NTSC video tapes on PAL TVs and vice versa.
-Applications can use the predefined bits to select a particular
-standard, although presenting the user a menu of supported standards is
-preferred. To enumerate and query the attributes of the supported
-standards applications use the :ref:`VIDIOC_ENUMSTD`
-ioctl.
-
-Many of the defined standards are actually just variations of a few
-major standards. The hardware may in fact not distinguish between them,
-or do so internal and switch automatically. Therefore enumerated
-standards also contain sets of one or more standard bits.
-
-Assume a hypothetic tuner capable of demodulating B/PAL, G/PAL and I/PAL
-signals. The first enumerated standard is a set of B and G/PAL, switched
-automatically depending on the selected radio frequency in UHF or VHF
-band. Enumeration gives a "PAL-B/G" or "PAL-I" choice. Similar a
-Composite input may collapse standards, enumerating "PAL-B/G/H/I",
-"NTSC-M" and "SECAM-D/K". [#f1]_
-
-To query and select the standard used by the current video input or
-output applications call the :ref:`VIDIOC_G_STD <VIDIOC_G_STD>` and
-:ref:`VIDIOC_S_STD <VIDIOC_G_STD>` ioctl, respectively. The
-*received* standard can be sensed with the
-:ref:`VIDIOC_QUERYSTD` ioctl.
-
-.. note::
-
-   The parameter of all these ioctls is a pointer to a
-   :ref:`v4l2_std_id <v4l2-std-id>` type (a standard set), *not* an
-   index into the standard enumeration. Drivers must implement all video
-   standard ioctls when the device has one or more video inputs or outputs.
-
-Special rules apply to devices such as USB cameras where the notion of
-video standards makes little sense. More generally for any capture or
-output device which is:
-
--  incapable of capturing fields or frames at the nominal rate of the
-   video standard, or
-
--  that does not support the video standard formats at all.
-
-Here the driver shall set the ``std`` field of struct
-:c:type:`v4l2_input` and struct
-:c:type:`v4l2_output` to zero and the :ref:`VIDIOC_G_STD <VIDIOC_G_STD>`,
-:ref:`VIDIOC_S_STD <VIDIOC_G_STD>`, :ref:`VIDIOC_QUERYSTD` and :ref:`VIDIOC_ENUMSTD` ioctls
-shall return the ``ENOTTY`` error code or the ``EINVAL`` error code.
-
-Applications can make use of the :ref:`input-capabilities` and
-:ref:`output-capabilities` flags to determine whether the video
-standard ioctls can be used with the given input or output.
-
-Example: Information about the current video standard
-=====================================================
-
-.. code-block:: c
-
-    v4l2_std_id std_id;
-    struct v4l2_standard standard;
-
-    if (-1 == ioctl(fd, VIDIOC_G_STD, &std_id)) {
-	/* Note when VIDIOC_ENUMSTD always returns ENOTTY this
-	   is no video device or it falls under the USB exception,
-	   and VIDIOC_G_STD returning ENOTTY is no error. */
-
-	perror("VIDIOC_G_STD");
-	exit(EXIT_FAILURE);
-    }
-
-    memset(&standard, 0, sizeof(standard));
-    standard.index = 0;
-
-    while (0 == ioctl(fd, VIDIOC_ENUMSTD, &standard)) {
-	if (standard.id & std_id) {
-	       printf("Current video standard: %s\\n", standard.name);
-	       exit(EXIT_SUCCESS);
-	}
-
-	standard.index++;
-    }
-
-    /* EINVAL indicates the end of the enumeration, which cannot be
-       empty unless this device falls under the USB exception. */
-
-    if (errno == EINVAL || standard.index == 0) {
-	perror("VIDIOC_ENUMSTD");
-	exit(EXIT_FAILURE);
-    }
-
-Example: Listing the video standards supported by the current input
-===================================================================
-
-.. code-block:: c
-
-    struct v4l2_input input;
-    struct v4l2_standard standard;
-
-    memset(&input, 0, sizeof(input));
-
-    if (-1 == ioctl(fd, VIDIOC_G_INPUT, &input.index)) {
-	perror("VIDIOC_G_INPUT");
-	exit(EXIT_FAILURE);
-    }
-
-    if (-1 == ioctl(fd, VIDIOC_ENUMINPUT, &input)) {
-	perror("VIDIOC_ENUM_INPUT");
-	exit(EXIT_FAILURE);
-    }
-
-    printf("Current input %s supports:\\n", input.name);
-
-    memset(&standard, 0, sizeof(standard));
-    standard.index = 0;
-
-    while (0 == ioctl(fd, VIDIOC_ENUMSTD, &standard)) {
-	if (standard.id & input.std)
-	    printf("%s\\n", standard.name);
-
-	standard.index++;
-    }
-
-    /* EINVAL indicates the end of the enumeration, which cannot be
-       empty unless this device falls under the USB exception. */
-
-    if (errno != EINVAL || standard.index == 0) {
-	perror("VIDIOC_ENUMSTD");
-	exit(EXIT_FAILURE);
-    }
-
-Example: Selecting a new video standard
-=======================================
-
-.. code-block:: c
-
-    struct v4l2_input input;
-    v4l2_std_id std_id;
-
-    memset(&input, 0, sizeof(input));
-
-    if (-1 == ioctl(fd, VIDIOC_G_INPUT, &input.index)) {
-	perror("VIDIOC_G_INPUT");
-	exit(EXIT_FAILURE);
-    }
-
-    if (-1 == ioctl(fd, VIDIOC_ENUMINPUT, &input)) {
-	perror("VIDIOC_ENUM_INPUT");
-	exit(EXIT_FAILURE);
-    }
-
-    if (0 == (input.std & V4L2_STD_PAL_BG)) {
-	fprintf(stderr, "Oops. B/G PAL is not supported.\\n");
-	exit(EXIT_FAILURE);
-    }
-
-    /* Note this is also supposed to work when only B
-       or G/PAL is supported. */
-
-    std_id = V4L2_STD_PAL_BG;
-
-    if (-1 == ioctl(fd, VIDIOC_S_STD, &std_id)) {
-	perror("VIDIOC_S_STD");
-	exit(EXIT_FAILURE);
-    }
-
-.. [#f1]
-   Some users are already confused by technical terms PAL, NTSC and
-   SECAM. There is no point asking them to distinguish between B, G, D,
-   or K when the software or hardware can do that automatically.
diff --git a/Documentation/media/uapi/v4l/streaming-par.rst b/Documentation/media/uapi/v4l/streaming-par.rst
deleted file mode 100644
index 425bd0ff1477..000000000000
--- a/Documentation/media/uapi/v4l/streaming-par.rst
+++ /dev/null
@@ -1,40 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _streaming-par:
-
-********************
-Streaming Parameters
-********************
-
-Streaming parameters are intended to optimize the video capture process
-as well as I/O. Presently applications can request a high quality
-capture mode with the :ref:`VIDIOC_S_PARM <VIDIOC_G_PARM>` ioctl.
-
-The current video standard determines a nominal number of frames per
-second. If less than this number of frames is to be captured or output,
-applications can request frame skipping or duplicating on the driver
-side. This is especially useful when using the
-:ref:`read() <func-read>` or :ref:`write() <func-write>`, which are
-not augmented by timestamps or sequence counters, and to avoid
-unnecessary data copying.
-
-Finally these ioctls can be used to determine the number of buffers used
-internally by a driver in read/write mode. For implications see the
-section discussing the :ref:`read() <func-read>` function.
-
-To get and set the streaming parameters applications call the
-:ref:`VIDIOC_G_PARM <VIDIOC_G_PARM>` and
-:ref:`VIDIOC_S_PARM <VIDIOC_G_PARM>` ioctl, respectively. They take
-a pointer to a struct :c:type:`v4l2_streamparm`, which
-contains a union holding separate parameters for input and output
-devices.
-
-These ioctls are optional, drivers need not implement them. If so, they
-return the ``EINVAL`` error code.
diff --git a/Documentation/media/uapi/v4l/subdev-formats.rst b/Documentation/media/uapi/v4l/subdev-formats.rst
deleted file mode 100644
index 17bfb2beaa6a..000000000000
--- a/Documentation/media/uapi/v4l/subdev-formats.rst
+++ /dev/null
@@ -1,7833 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _v4l2-mbus-format:
-
-Media Bus Formats
-=================
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. c:type:: v4l2_mbus_framefmt
-
-.. flat-table:: struct v4l2_mbus_framefmt
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``width``
-      - Image width in pixels.
-    * - __u32
-      - ``height``
-      - Image height in pixels. If ``field`` is one of ``V4L2_FIELD_TOP``,
-	``V4L2_FIELD_BOTTOM`` or ``V4L2_FIELD_ALTERNATE`` then height
-	refers to the number of lines in the field, otherwise it refers to
-	the number of lines in the frame (which is twice the field height
-	for interlaced formats).
-    * - __u32
-      - ``code``
-      - Format code, from enum
-	:ref:`v4l2_mbus_pixelcode <v4l2-mbus-pixelcode>`.
-    * - __u32
-      - ``field``
-      - Field order, from enum :c:type:`v4l2_field`. See
-	:ref:`field-order` for details.
-    * - __u32
-      - ``colorspace``
-      - Image colorspace, from enum
-	:c:type:`v4l2_colorspace`. See
-	:ref:`colorspaces` for details.
-    * - __u16
-      - ``ycbcr_enc``
-      - Y'CbCr encoding, from enum :c:type:`v4l2_ycbcr_encoding`.
-        This information supplements the ``colorspace`` and must be set by
-	the driver for capture streams and by the application for output
-	streams, see :ref:`colorspaces`.
-    * - __u16
-      - ``quantization``
-      - Quantization range, from enum :c:type:`v4l2_quantization`.
-        This information supplements the ``colorspace`` and must be set by
-	the driver for capture streams and by the application for output
-	streams, see :ref:`colorspaces`.
-    * - __u16
-      - ``xfer_func``
-      - Transfer function, from enum :c:type:`v4l2_xfer_func`.
-        This information supplements the ``colorspace`` and must be set by
-	the driver for capture streams and by the application for output
-	streams, see :ref:`colorspaces`.
-    * - __u16
-      - ``reserved``\ [11]
-      - Reserved for future extensions. Applications and drivers must set
-	the array to zero.
-
-
-
-.. _v4l2-mbus-pixelcode:
-
-Media Bus Pixel Codes
----------------------
-
-The media bus pixel codes describe image formats as flowing over
-physical buses (both between separate physical components and inside
-SoC devices). This should not be confused with the V4L2 pixel formats
-that describe, using four character codes, image formats as stored in
-memory.
-
-While there is a relationship between image formats on buses and image
-formats in memory (a raw Bayer image won't be magically converted to
-JPEG just by storing it to memory), there is no one-to-one
-correspondence between them.
-
-The media bus pixel codes document parallel formats. Should the pixel data be
-transported over a serial bus, the media bus pixel code that describes a
-parallel format that transfers a sample on a single clock cycle is used. For
-instance, both MEDIA_BUS_FMT_BGR888_1X24 and MEDIA_BUS_FMT_BGR888_3X8 are used
-on parallel busses for transferring an 8 bits per sample BGR data, whereas on
-serial busses the data in this format is only referred to using
-MEDIA_BUS_FMT_BGR888_1X24. This is because there is effectively only a single
-way to transport that format on the serial busses.
-
-Packed RGB Formats
-^^^^^^^^^^^^^^^^^^
-
-Those formats transfer pixel data as red, green and blue components. The
-format code is made of the following information.
-
--  The red, green and blue components order code, as encoded in a pixel
-   sample. Possible values are RGB and BGR.
-
--  The number of bits per component, for each component. The values can
-   be different for all components. Common values are 555 and 565.
-
--  The number of bus samples per pixel. Pixels that are wider than the
-   bus width must be transferred in multiple samples. Common values are
-   1 and 2.
-
--  The bus width.
-
--  For formats where the total number of bits per pixel is smaller than
-   the number of bus samples per pixel times the bus width, a padding
-   value stating if the bytes are padded in their most high order bits
-   (PADHI) or low order bits (PADLO). A "C" prefix is used for
-   component-wise padding in the most high order bits (CPADHI) or low
-   order bits (CPADLO) of each separate component.
-
--  For formats where the number of bus samples per pixel is larger than
-   1, an endianness value stating if the pixel is transferred MSB first
-   (BE) or LSB first (LE).
-
-For instance, a format where pixels are encoded as 5-bits red, 5-bits
-green and 5-bit blue values padded on the high bit, transferred as 2
-8-bit samples per pixel with the most significant bits (padding, red and
-half of the green value) transferred first will be named
-``MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE``.
-
-The following tables list existing packed RGB formats.
-
-.. HACK: ideally, we would be using adjustbox here. However, Sphinx
-.. is a very bad behaviored guy: if the table has more than 30 cols,
-.. it switches to long table, and there's no way to override it.
-
-
-.. tabularcolumns:: |p{4.0cm}|p{0.7cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|
-
-.. _v4l2-mbus-pixelcode-rgb:
-
-.. raw:: latex
-
-    \begingroup
-    \tiny
-    \setlength{\tabcolsep}{2pt}
-
-.. flat-table:: RGB formats
-    :header-rows:  2
-    :stub-columns: 0
-    :widths: 36 7 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
-
-    * - Identifier
-      - Code
-      -
-      - :cspan:`31` Data organization
-    * -
-      -
-      - Bit
-      - 31
-      - 30
-      - 29
-      - 28
-      - 27
-      - 26
-      - 25
-      - 24
-      - 23
-      - 22
-      - 21
-      - 20
-      - 19
-      - 18
-      - 17
-      - 16
-      - 15
-      - 14
-      - 13
-      - 12
-      - 11
-      - 10
-      - 9
-      - 8
-      - 7
-      - 6
-      - 5
-      - 4
-      - 3
-      - 2
-      - 1
-      - 0
-    * .. _MEDIA-BUS-FMT-RGB444-1X12:
-
-      - MEDIA_BUS_FMT_RGB444_1X12
-      - 0x1016
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-RGB444-2X8-PADHI-BE:
-
-      - MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE
-      - 0x1001
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - 0
-      - 0
-      - 0
-      - 0
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-RGB444-2X8-PADHI-LE:
-
-      - MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE
-      - 0x1002
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - 0
-      - 0
-      - 0
-      - 0
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-RGB555-2X8-PADHI-BE:
-
-      - MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE
-      - 0x1003
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - 0
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-RGB555-2X8-PADHI-LE:
-
-      - MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE
-      - 0x1004
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - 0
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-    * .. _MEDIA-BUS-FMT-RGB565-1X16:
-
-      - MEDIA_BUS_FMT_RGB565_1X16
-      - 0x1017
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-BGR565-2X8-BE:
-
-      - MEDIA_BUS_FMT_BGR565_2X8_BE
-      - 0x1005
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-BGR565-2X8-LE:
-
-      - MEDIA_BUS_FMT_BGR565_2X8_LE
-      - 0x1006
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-    * .. _MEDIA-BUS-FMT-RGB565-2X8-BE:
-
-      - MEDIA_BUS_FMT_RGB565_2X8_BE
-      - 0x1007
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-RGB565-2X8-LE:
-
-      - MEDIA_BUS_FMT_RGB565_2X8_LE
-      - 0x1008
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-    * .. _MEDIA-BUS-FMT-RGB666-1X18:
-
-      - MEDIA_BUS_FMT_RGB666_1X18
-      - 0x1009
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-RBG888-1X24:
-
-      - MEDIA_BUS_FMT_RBG888_1X24
-      - 0x100e
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-RGB666-1X24_CPADHI:
-
-      - MEDIA_BUS_FMT_RGB666_1X24_CPADHI
-      - 0x1015
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - 0
-      - 0
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - 0
-      - 0
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - 0
-      - 0
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-BGR888-1X24:
-
-      - MEDIA_BUS_FMT_BGR888_1X24
-      - 0x1013
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-BGR888-3X8:
-
-      - MEDIA_BUS_FMT_BGR888_3X8
-      - 0x101b
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-GBR888-1X24:
-
-      - MEDIA_BUS_FMT_GBR888_1X24
-      - 0x1014
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-RGB888-1X24:
-
-      - MEDIA_BUS_FMT_RGB888_1X24
-      - 0x100a
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-RGB888-2X12-BE:
-
-      - MEDIA_BUS_FMT_RGB888_2X12_BE
-      - 0x100b
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-RGB888-2X12-LE:
-
-      - MEDIA_BUS_FMT_RGB888_2X12_LE
-      - 0x100c
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-    * .. _MEDIA-BUS-FMT-RGB888-3X8:
-
-      - MEDIA_BUS_FMT_RGB888_3X8
-      - 0x101c
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-ARGB888-1X32:
-
-      - MEDIA_BUS_FMT_ARGB888_1X32
-      - 0x100d
-      -
-      - a\ :sub:`7`
-      - a\ :sub:`6`
-      - a\ :sub:`5`
-      - a\ :sub:`4`
-      - a\ :sub:`3`
-      - a\ :sub:`2`
-      - a\ :sub:`1`
-      - a\ :sub:`0`
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-RGB888-1X32-PADHI:
-
-      - MEDIA_BUS_FMT_RGB888_1X32_PADHI
-      - 0x100f
-      -
-      - 0
-      - 0
-      - 0
-      - 0
-      - 0
-      - 0
-      - 0
-      - 0
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-RGB101010-1X30:
-
-      - MEDIA_BUS_FMT_RGB101010_1X30
-      - 0x1018
-      -
-      - 0
-      - 0
-      - r\ :sub:`9`
-      - r\ :sub:`8`
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`9`
-      - g\ :sub:`8`
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`9`
-      - b\ :sub:`8`
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-
-.. raw:: latex
-
-    \endgroup
-
-
-The following table list existing packed 36bit wide RGB formats.
-
-.. tabularcolumns:: |p{4.0cm}|p{0.7cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|
-
-.. _v4l2-mbus-pixelcode-rgb-36:
-
-.. raw:: latex
-
-    \begingroup
-    \tiny
-    \setlength{\tabcolsep}{2pt}
-
-.. flat-table:: 36bit RGB formats
-    :header-rows:  2
-    :stub-columns: 0
-    :widths: 36 7 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
-
-    * - Identifier
-      - Code
-      -
-      - :cspan:`35` Data organization
-    * -
-      -
-      - Bit
-      - 35
-      - 34
-      - 33
-      - 32
-      - 31
-      - 30
-      - 29
-      - 28
-      - 27
-      - 26
-      - 25
-      - 24
-      - 23
-      - 22
-      - 21
-      - 20
-      - 19
-      - 18
-      - 17
-      - 16
-      - 15
-      - 14
-      - 13
-      - 12
-      - 11
-      - 10
-      - 9
-      - 8
-      - 7
-      - 6
-      - 5
-      - 4
-      - 3
-      - 2
-      - 1
-      - 0
-    * .. _MEDIA-BUS-FMT-RGB121212-1X36:
-
-      - MEDIA_BUS_FMT_RGB121212_1X36
-      - 0x1019
-      -
-      - r\ :sub:`11`
-      - r\ :sub:`10`
-      - r\ :sub:`9`
-      - r\ :sub:`8`
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`11`
-      - g\ :sub:`10`
-      - g\ :sub:`9`
-      - g\ :sub:`8`
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`11`
-      - b\ :sub:`10`
-      - b\ :sub:`9`
-      - b\ :sub:`8`
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-
-.. raw:: latex
-
-    \endgroup
-
-
-The following table list existing packed 48bit wide RGB formats.
-
-.. tabularcolumns:: |p{4.0cm}|p{0.7cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|
-
-.. _v4l2-mbus-pixelcode-rgb-48:
-
-.. raw:: latex
-
-    \begingroup
-    \tiny
-    \setlength{\tabcolsep}{2pt}
-
-.. flat-table:: 48bit RGB formats
-    :header-rows:  3
-    :stub-columns: 0
-    :widths: 36 7 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
-
-    * - Identifier
-      - Code
-      -
-      - :cspan:`31` Data organization
-    * -
-      -
-      - Bit
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - 47
-      - 46
-      - 45
-      - 44
-      - 43
-      - 42
-      - 41
-      - 40
-      - 39
-      - 38
-      - 37
-      - 36
-      - 35
-      - 34
-      - 33
-      - 32
-    * -
-      -
-      -
-      - 31
-      - 30
-      - 29
-      - 28
-      - 27
-      - 26
-      - 25
-      - 24
-      - 23
-      - 22
-      - 21
-      - 20
-      - 19
-      - 18
-      - 17
-      - 16
-      - 15
-      - 14
-      - 13
-      - 12
-      - 11
-      - 10
-      - 9
-      - 8
-      - 7
-      - 6
-      - 5
-      - 4
-      - 3
-      - 2
-      - 1
-      - 0
-    * .. _MEDIA-BUS-FMT-RGB161616-1X48:
-
-      - MEDIA_BUS_FMT_RGB161616_1X48
-      - 0x101a
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - r\ :sub:`15`
-      - r\ :sub:`14`
-      - r\ :sub:`13`
-      - r\ :sub:`12`
-      - r\ :sub:`11`
-      - r\ :sub:`10`
-      - r\ :sub:`9`
-      - r\ :sub:`8`
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-    * -
-      -
-      -
-      - g\ :sub:`15`
-      - g\ :sub:`14`
-      - g\ :sub:`13`
-      - g\ :sub:`12`
-      - g\ :sub:`11`
-      - g\ :sub:`10`
-      - g\ :sub:`9`
-      - g\ :sub:`8`
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`15`
-      - b\ :sub:`14`
-      - b\ :sub:`13`
-      - b\ :sub:`12`
-      - b\ :sub:`11`
-      - b\ :sub:`10`
-      - b\ :sub:`9`
-      - b\ :sub:`8`
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-
-.. raw:: latex
-
-    \endgroup
-
-On LVDS buses, usually each sample is transferred serialized in seven
-time slots per pixel clock, on three (18-bit) or four (24-bit)
-differential data pairs at the same time. The remaining bits are used
-for control signals as defined by SPWG/PSWG/VESA or JEIDA standards. The
-24-bit RGB format serialized in seven time slots on four lanes using
-JEIDA defined bit mapping will be named
-``MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA``, for example.
-
-.. raw:: latex
-
-    \tiny
-
-.. _v4l2-mbus-pixelcode-rgb-lvds:
-
-.. flat-table:: LVDS RGB formats
-    :header-rows:  2
-    :stub-columns: 0
-
-    * - Identifier
-      - Code
-      -
-      -
-      - :cspan:`3` Data organization
-    * -
-      -
-      - Timeslot
-      - Lane
-      - 3
-      - 2
-      - 1
-      - 0
-    * .. _MEDIA-BUS-FMT-RGB666-1X7X3-SPWG:
-
-      - MEDIA_BUS_FMT_RGB666_1X7X3_SPWG
-      - 0x1010
-      - 0
-      -
-      -
-      - d
-      - b\ :sub:`1`
-      - g\ :sub:`0`
-    * -
-      -
-      - 1
-      -
-      -
-      - d
-      - b\ :sub:`0`
-      - r\ :sub:`5`
-    * -
-      -
-      - 2
-      -
-      -
-      - d
-      - g\ :sub:`5`
-      - r\ :sub:`4`
-    * -
-      -
-      - 3
-      -
-      -
-      - b\ :sub:`5`
-      - g\ :sub:`4`
-      - r\ :sub:`3`
-    * -
-      -
-      - 4
-      -
-      -
-      - b\ :sub:`4`
-      - g\ :sub:`3`
-      - r\ :sub:`2`
-    * -
-      -
-      - 5
-      -
-      -
-      - b\ :sub:`3`
-      - g\ :sub:`2`
-      - r\ :sub:`1`
-    * -
-      -
-      - 6
-      -
-      -
-      - b\ :sub:`2`
-      - g\ :sub:`1`
-      - r\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-RGB888-1X7X4-SPWG:
-
-      - MEDIA_BUS_FMT_RGB888_1X7X4_SPWG
-      - 0x1011
-      - 0
-      -
-      - d
-      - d
-      - b\ :sub:`1`
-      - g\ :sub:`0`
-    * -
-      -
-      - 1
-      -
-      - b\ :sub:`7`
-      - d
-      - b\ :sub:`0`
-      - r\ :sub:`5`
-    * -
-      -
-      - 2
-      -
-      - b\ :sub:`6`
-      - d
-      - g\ :sub:`5`
-      - r\ :sub:`4`
-    * -
-      -
-      - 3
-      -
-      - g\ :sub:`7`
-      - b\ :sub:`5`
-      - g\ :sub:`4`
-      - r\ :sub:`3`
-    * -
-      -
-      - 4
-      -
-      - g\ :sub:`6`
-      - b\ :sub:`4`
-      - g\ :sub:`3`
-      - r\ :sub:`2`
-    * -
-      -
-      - 5
-      -
-      - r\ :sub:`7`
-      - b\ :sub:`3`
-      - g\ :sub:`2`
-      - r\ :sub:`1`
-    * -
-      -
-      - 6
-      -
-      - r\ :sub:`6`
-      - b\ :sub:`2`
-      - g\ :sub:`1`
-      - r\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-RGB888-1X7X4-JEIDA:
-
-      - MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA
-      - 0x1012
-      - 0
-      -
-      - d
-      - d
-      - b\ :sub:`3`
-      - g\ :sub:`2`
-    * -
-      -
-      - 1
-      -
-      - b\ :sub:`1`
-      - d
-      - b\ :sub:`2`
-      - r\ :sub:`7`
-    * -
-      -
-      - 2
-      -
-      - b\ :sub:`0`
-      - d
-      - g\ :sub:`7`
-      - r\ :sub:`6`
-    * -
-      -
-      - 3
-      -
-      - g\ :sub:`1`
-      - b\ :sub:`7`
-      - g\ :sub:`6`
-      - r\ :sub:`5`
-    * -
-      -
-      - 4
-      -
-      - g\ :sub:`0`
-      - b\ :sub:`6`
-      - g\ :sub:`5`
-      - r\ :sub:`4`
-    * -
-      -
-      - 5
-      -
-      - r\ :sub:`1`
-      - b\ :sub:`5`
-      - g\ :sub:`4`
-      - r\ :sub:`3`
-    * -
-      -
-      - 6
-      -
-      - r\ :sub:`0`
-      - b\ :sub:`4`
-      - g\ :sub:`3`
-      - r\ :sub:`2`
-
-.. raw:: latex
-
-    \normalsize
-
-
-Bayer Formats
-^^^^^^^^^^^^^
-
-Those formats transfer pixel data as red, green and blue components. The
-format code is made of the following information.
-
--  The red, green and blue components order code, as encoded in a pixel
-   sample. The possible values are shown in :ref:`bayer-patterns`.
-
--  The number of bits per pixel component. All components are
-   transferred on the same number of bits. Common values are 8, 10 and
-   12.
-
--  The compression (optional). If the pixel components are ALAW- or
-   DPCM-compressed, a mention of the compression scheme and the number
-   of bits per compressed pixel component.
-
--  The number of bus samples per pixel. Pixels that are wider than the
-   bus width must be transferred in multiple samples. Common values are
-   1 and 2.
-
--  The bus width.
-
--  For formats where the total number of bits per pixel is smaller than
-   the number of bus samples per pixel times the bus width, a padding
-   value stating if the bytes are padded in their most high order bits
-   (PADHI) or low order bits (PADLO).
-
--  For formats where the number of bus samples per pixel is larger than
-   1, an endianness value stating if the pixel is transferred MSB first
-   (BE) or LSB first (LE).
-
-For instance, a format with uncompressed 10-bit Bayer components
-arranged in a red, green, green, blue pattern transferred as 2 8-bit
-samples per pixel with the least significant bits transferred first will
-be named ``MEDIA_BUS_FMT_SRGGB10_2X8_PADHI_LE``.
-
-
-.. _bayer-patterns:
-
-.. kernel-figure:: bayer.svg
-    :alt:    bayer.svg
-    :align:  center
-
-    **Figure 4.8 Bayer Patterns**
-
-The following table lists existing packed Bayer formats. The data
-organization is given as an example for the first pixel only.
-
-
-.. HACK: ideally, we would be using adjustbox here. However, Sphinx
-.. is a very bad behaviored guy: if the table has more than 30 cols,
-.. it switches to long table, and there's no way to override it.
-
-
-.. raw:: latex
-
-    \begingroup
-    \tiny
-    \setlength{\tabcolsep}{2pt}
-
-.. tabularcolumns:: |p{4.0cm}|p{0.7cm}|p{0.3cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|
-
-.. _v4l2-mbus-pixelcode-bayer:
-
-.. cssclass: longtable
-
-.. flat-table:: Bayer Formats
-    :header-rows:  2
-    :stub-columns: 0
-
-    * - Identifier
-      - Code
-      -
-      - :cspan:`15` Data organization
-    * -
-      -
-      - Bit
-      - 15
-      - 14
-      - 13
-      - 12
-      - 11
-      - 10
-      - 9
-      - 8
-      - 7
-      - 6
-      - 5
-      - 4
-      - 3
-      - 2
-      - 1
-      - 0
-    * .. _MEDIA-BUS-FMT-SBGGR8-1X8:
-
-      - MEDIA_BUS_FMT_SBGGR8_1X8
-      - 0x3001
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-SGBRG8-1X8:
-
-      - MEDIA_BUS_FMT_SGBRG8_1X8
-      - 0x3013
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-SGRBG8-1X8:
-
-      - MEDIA_BUS_FMT_SGRBG8_1X8
-      - 0x3002
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-SRGGB8-1X8:
-
-      - MEDIA_BUS_FMT_SRGGB8_1X8
-      - 0x3014
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-SBGGR10-ALAW8-1X8:
-
-      - MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8
-      - 0x3015
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-SGBRG10-ALAW8-1X8:
-
-      - MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8
-      - 0x3016
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-SGRBG10-ALAW8-1X8:
-
-      - MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8
-      - 0x3017
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-SRGGB10-ALAW8-1X8:
-
-      - MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8
-      - 0x3018
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-SBGGR10-DPCM8-1X8:
-
-      - MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8
-      - 0x300b
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-SGBRG10-DPCM8-1X8:
-
-      - MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8
-      - 0x300c
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-SGRBG10-DPCM8-1X8:
-
-      - MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8
-      - 0x3009
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-SRGGB10-DPCM8-1X8:
-
-      - MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8
-      - 0x300d
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-SBGGR10-2X8-PADHI-BE:
-
-      - MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE
-      - 0x3003
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - 0
-      - 0
-      - 0
-      - 0
-      - 0
-      - 0
-      - b\ :sub:`9`
-      - b\ :sub:`8`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-SBGGR10-2X8-PADHI-LE:
-
-      - MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE
-      - 0x3004
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - 0
-      - 0
-      - 0
-      - 0
-      - 0
-      - 0
-      - b\ :sub:`9`
-      - b\ :sub:`8`
-    * .. _MEDIA-BUS-FMT-SBGGR10-2X8-PADLO-BE:
-
-      - MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE
-      - 0x3005
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - b\ :sub:`9`
-      - b\ :sub:`8`
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      - 0
-      - 0
-      - 0
-      - 0
-      - 0
-      - 0
-    * .. _MEDIA-BUS-FMT-SBGGR10-2X8-PADLO-LE:
-
-      - MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE
-      - 0x3006
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      - 0
-      - 0
-      - 0
-      - 0
-      - 0
-      - 0
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - b\ :sub:`9`
-      - b\ :sub:`8`
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-    * .. _MEDIA-BUS-FMT-SBGGR10-1X10:
-
-      - MEDIA_BUS_FMT_SBGGR10_1X10
-      - 0x3007
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - b\ :sub:`9`
-      - b\ :sub:`8`
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-SGBRG10-1X10:
-
-      - MEDIA_BUS_FMT_SGBRG10_1X10
-      - 0x300e
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - g\ :sub:`9`
-      - g\ :sub:`8`
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-SGRBG10-1X10:
-
-      - MEDIA_BUS_FMT_SGRBG10_1X10
-      - 0x300a
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - g\ :sub:`9`
-      - g\ :sub:`8`
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-SRGGB10-1X10:
-
-      - MEDIA_BUS_FMT_SRGGB10_1X10
-      - 0x300f
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - r\ :sub:`9`
-      - r\ :sub:`8`
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-SBGGR12-1X12:
-
-      - MEDIA_BUS_FMT_SBGGR12_1X12
-      - 0x3008
-      -
-      -
-      -
-      -
-      -
-      - b\ :sub:`11`
-      - b\ :sub:`10`
-      - b\ :sub:`9`
-      - b\ :sub:`8`
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-SGBRG12-1X12:
-
-      - MEDIA_BUS_FMT_SGBRG12_1X12
-      - 0x3010
-      -
-      -
-      -
-      -
-      -
-      - g\ :sub:`11`
-      - g\ :sub:`10`
-      - g\ :sub:`9`
-      - g\ :sub:`8`
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-SGRBG12-1X12:
-
-      - MEDIA_BUS_FMT_SGRBG12_1X12
-      - 0x3011
-      -
-      -
-      -
-      -
-      -
-      - g\ :sub:`11`
-      - g\ :sub:`10`
-      - g\ :sub:`9`
-      - g\ :sub:`8`
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-SRGGB12-1X12:
-
-      - MEDIA_BUS_FMT_SRGGB12_1X12
-      - 0x3012
-      -
-      -
-      -
-      -
-      -
-      - r\ :sub:`11`
-      - r\ :sub:`10`
-      - r\ :sub:`9`
-      - r\ :sub:`8`
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-SBGGR14-1X14:
-
-      - MEDIA_BUS_FMT_SBGGR14_1X14
-      - 0x3019
-      -
-      -
-      -
-      - b\ :sub:`13`
-      - b\ :sub:`12`
-      - b\ :sub:`11`
-      - b\ :sub:`10`
-      - b\ :sub:`9`
-      - b\ :sub:`8`
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-SGBRG14-1X14:
-
-      - MEDIA_BUS_FMT_SGBRG14_1X14
-      - 0x301a
-      -
-      -
-      -
-      - g\ :sub:`13`
-      - g\ :sub:`12`
-      - g\ :sub:`11`
-      - g\ :sub:`10`
-      - g\ :sub:`9`
-      - g\ :sub:`8`
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-SGRBG14-1X14:
-
-      - MEDIA_BUS_FMT_SGRBG14_1X14
-      - 0x301b
-      -
-      -
-      -
-      - g\ :sub:`13`
-      - g\ :sub:`12`
-      - g\ :sub:`11`
-      - g\ :sub:`10`
-      - g\ :sub:`9`
-      - g\ :sub:`8`
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-SRGGB14-1X14:
-
-      - MEDIA_BUS_FMT_SRGGB14_1X14
-      - 0x301c
-      -
-      -
-      -
-      - r\ :sub:`13`
-      - r\ :sub:`12`
-      - r\ :sub:`11`
-      - r\ :sub:`10`
-      - r\ :sub:`9`
-      - r\ :sub:`8`
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-SBGGR16-1X16:
-
-      - MEDIA_BUS_FMT_SBGGR16_1X16
-      - 0x301d
-      -
-      - b\ :sub:`15`
-      - b\ :sub:`14`
-      - b\ :sub:`13`
-      - b\ :sub:`12`
-      - b\ :sub:`11`
-      - b\ :sub:`10`
-      - b\ :sub:`9`
-      - b\ :sub:`8`
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-SGBRG16-1X16:
-
-      - MEDIA_BUS_FMT_SGBRG16_1X16
-      - 0x301e
-      -
-      - g\ :sub:`15`
-      - g\ :sub:`14`
-      - g\ :sub:`13`
-      - g\ :sub:`12`
-      - g\ :sub:`11`
-      - g\ :sub:`10`
-      - g\ :sub:`9`
-      - g\ :sub:`8`
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-SGRBG16-1X16:
-
-      - MEDIA_BUS_FMT_SGRBG16_1X16
-      - 0x301f
-      -
-      - g\ :sub:`15`
-      - g\ :sub:`14`
-      - g\ :sub:`13`
-      - g\ :sub:`12`
-      - g\ :sub:`11`
-      - g\ :sub:`10`
-      - g\ :sub:`9`
-      - g\ :sub:`8`
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-SRGGB16-1X16:
-
-      - MEDIA_BUS_FMT_SRGGB16_1X16
-      - 0x3020
-      -
-      - r\ :sub:`15`
-      - r\ :sub:`14`
-      - r\ :sub:`13`
-      - r\ :sub:`12`
-      - r\ :sub:`11`
-      - r\ :sub:`10`
-      - r\ :sub:`9`
-      - r\ :sub:`8`
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-
-.. raw:: latex
-
-    \endgroup
-
-
-Packed YUV Formats
-^^^^^^^^^^^^^^^^^^
-
-Those data formats transfer pixel data as (possibly downsampled) Y, U
-and V components. Some formats include dummy bits in some of their
-samples and are collectively referred to as "YDYC" (Y-Dummy-Y-Chroma)
-formats. One cannot rely on the values of these dummy bits as those are
-undefined.
-
-The format code is made of the following information.
-
--  The Y, U and V components order code, as transferred on the bus.
-   Possible values are YUYV, UYVY, YVYU and VYUY for formats with no
-   dummy bit, and YDYUYDYV, YDYVYDYU, YUYDYVYD and YVYDYUYD for YDYC
-   formats.
-
--  The number of bits per pixel component. All components are
-   transferred on the same number of bits. Common values are 8, 10 and
-   12.
-
--  The number of bus samples per pixel. Pixels that are wider than the
-   bus width must be transferred in multiple samples. Common values are
-   0.5 (encoded as 0_5; in this case two pixels are transferred per bus
-   sample), 1, 1.5 (encoded as 1_5) and 2.
-
--  The bus width. When the bus width is larger than the number of bits
-   per pixel component, several components are packed in a single bus
-   sample. The components are ordered as specified by the order code,
-   with components on the left of the code transferred in the high order
-   bits. Common values are 8 and 16.
-
-For instance, a format where pixels are encoded as 8-bit YUV values
-downsampled to 4:2:2 and transferred as 2 8-bit bus samples per pixel in
-the U, Y, V, Y order will be named ``MEDIA_BUS_FMT_UYVY8_2X8``.
-
-:ref:`v4l2-mbus-pixelcode-yuv8` lists existing packed YUV formats and
-describes the organization of each pixel data in each sample. When a
-format pattern is split across multiple samples each of the samples in
-the pattern is described.
-
-The role of each bit transferred over the bus is identified by one of
-the following codes.
-
--  y\ :sub:`x` for luma component bit number x
-
--  u\ :sub:`x` for blue chroma component bit number x
-
--  v\ :sub:`x` for red chroma component bit number x
-
--  a\ :sub:`x` for alpha component bit number x
-
-- for non-available bits (for positions higher than the bus width)
-
--  d for dummy bits
-
-.. HACK: ideally, we would be using adjustbox here. However, this
-.. will never work for this table, as, even with tiny font, it is
-.. to big for a single page. So, we need to manually adjust the
-.. size.
-
-.. raw:: latex
-
-    \begingroup
-    \tiny
-    \setlength{\tabcolsep}{2pt}
-
-.. tabularcolumns:: |p{4.0cm}|p{0.7cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|
-
-.. _v4l2-mbus-pixelcode-yuv8:
-
-.. flat-table:: YUV Formats
-    :header-rows:  2
-    :stub-columns: 0
-    :widths: 36 7 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
-
-    * - Identifier
-      - Code
-      -
-      - :cspan:`31` Data organization
-    * -
-      -
-      - Bit
-      - 31
-      - 30
-      - 29
-      - 28
-      - 27
-      - 26
-      - 25
-      - 24
-      - 23
-      - 22
-      - 21
-      - 10
-      - 19
-      - 18
-      - 17
-      - 16
-      - 15
-      - 14
-      - 13
-      - 12
-      - 11
-      - 10
-      - 9
-      - 8
-      - 7
-      - 6
-      - 5
-      - 4
-      - 3
-      - 2
-      - 1
-      - 0
-    * .. _MEDIA-BUS-FMT-Y8-1X8:
-
-      - MEDIA_BUS_FMT_Y8_1X8
-      - 0x2001
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-UV8-1X8:
-
-      - MEDIA_BUS_FMT_UV8_1X8
-      - 0x2015
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-UYVY8-1_5X8:
-
-      - MEDIA_BUS_FMT_UYVY8_1_5X8
-      - 0x2002
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-VYUY8-1_5X8:
-
-      - MEDIA_BUS_FMT_VYUY8_1_5X8
-      - 0x2003
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-YUYV8-1_5X8:
-
-      - MEDIA_BUS_FMT_YUYV8_1_5X8
-      - 0x2004
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-YVYU8-1_5X8:
-
-      - MEDIA_BUS_FMT_YVYU8_1_5X8
-      - 0x2005
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-UYVY8-2X8:
-
-      - MEDIA_BUS_FMT_UYVY8_2X8
-      - 0x2006
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-VYUY8-2X8:
-
-      - MEDIA_BUS_FMT_VYUY8_2X8
-      - 0x2007
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-YUYV8-2X8:
-
-      - MEDIA_BUS_FMT_YUYV8_2X8
-      - 0x2008
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-YVYU8-2X8:
-
-      - MEDIA_BUS_FMT_YVYU8_2X8
-      - 0x2009
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-Y10-1X10:
-
-      - MEDIA_BUS_FMT_Y10_1X10
-      - 0x200a
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-Y10-2X8-PADHI_LE:
-
-      - MEDIA_BUS_FMT_Y10_2X8_PADHI_LE
-      - 0x202c
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - 0
-      - 0
-      - 0
-      - 0
-      - 0
-      - 0
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-    * .. _MEDIA-BUS-FMT-UYVY10-2X10:
-
-      - MEDIA_BUS_FMT_UYVY10_2X10
-      - 0x2018
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - u\ :sub:`9`
-      - u\ :sub:`8`
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - v\ :sub:`9`
-      - v\ :sub:`8`
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-VYUY10-2X10:
-
-      - MEDIA_BUS_FMT_VYUY10_2X10
-      - 0x2019
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - v\ :sub:`9`
-      - v\ :sub:`8`
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - u\ :sub:`9`
-      - u\ :sub:`8`
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-YUYV10-2X10:
-
-      - MEDIA_BUS_FMT_YUYV10_2X10
-      - 0x200b
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - u\ :sub:`9`
-      - u\ :sub:`8`
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - v\ :sub:`9`
-      - v\ :sub:`8`
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-YVYU10-2X10:
-
-      - MEDIA_BUS_FMT_YVYU10_2X10
-      - 0x200c
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - v\ :sub:`9`
-      - v\ :sub:`8`
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - u\ :sub:`9`
-      - u\ :sub:`8`
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-Y12-1X12:
-
-      - MEDIA_BUS_FMT_Y12_1X12
-      - 0x2013
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`11`
-      - y\ :sub:`10`
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-UYVY12-2X12:
-
-      - MEDIA_BUS_FMT_UYVY12_2X12
-      - 0x201c
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - u\ :sub:`11`
-      - u\ :sub:`10`
-      - u\ :sub:`9`
-      - u\ :sub:`8`
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`11`
-      - y\ :sub:`10`
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - v\ :sub:`11`
-      - v\ :sub:`10`
-      - v\ :sub:`9`
-      - v\ :sub:`8`
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`11`
-      - y\ :sub:`10`
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-VYUY12-2X12:
-
-      - MEDIA_BUS_FMT_VYUY12_2X12
-      - 0x201d
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - v\ :sub:`11`
-      - v\ :sub:`10`
-      - v\ :sub:`9`
-      - v\ :sub:`8`
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`11`
-      - y\ :sub:`10`
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - u\ :sub:`11`
-      - u\ :sub:`10`
-      - u\ :sub:`9`
-      - u\ :sub:`8`
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`11`
-      - y\ :sub:`10`
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-YUYV12-2X12:
-
-      - MEDIA_BUS_FMT_YUYV12_2X12
-      - 0x201e
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`11`
-      - y\ :sub:`10`
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - u\ :sub:`11`
-      - u\ :sub:`10`
-      - u\ :sub:`9`
-      - u\ :sub:`8`
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`11`
-      - y\ :sub:`10`
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - v\ :sub:`11`
-      - v\ :sub:`10`
-      - v\ :sub:`9`
-      - v\ :sub:`8`
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-YVYU12-2X12:
-
-      - MEDIA_BUS_FMT_YVYU12_2X12
-      - 0x201f
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`11`
-      - y\ :sub:`10`
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - v\ :sub:`11`
-      - v\ :sub:`10`
-      - v\ :sub:`9`
-      - v\ :sub:`8`
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`11`
-      - y\ :sub:`10`
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - u\ :sub:`11`
-      - u\ :sub:`10`
-      - u\ :sub:`9`
-      - u\ :sub:`8`
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-Y14-1X14:
-
-      - MEDIA_BUS_FMT_Y14_1X14
-      - 0x202d
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`13`
-      - y\ :sub:`12`
-      - y\ :sub:`11`
-      - y\ :sub:`10`
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-UYVY8-1X16:
-
-      - MEDIA_BUS_FMT_UYVY8_1X16
-      - 0x200f
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-VYUY8-1X16:
-
-      - MEDIA_BUS_FMT_VYUY8_1X16
-      - 0x2010
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-YUYV8-1X16:
-
-      - MEDIA_BUS_FMT_YUYV8_1X16
-      - 0x2011
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-YVYU8-1X16:
-
-      - MEDIA_BUS_FMT_YVYU8_1X16
-      - 0x2012
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-YDYUYDYV8-1X16:
-
-      - MEDIA_BUS_FMT_YDYUYDYV8_1X16
-      - 0x2014
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-      - d
-      - d
-      - d
-      - d
-      - d
-      - d
-      - d
-      - d
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-      - d
-      - d
-      - d
-      - d
-      - d
-      - d
-      - d
-      - d
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-UYVY10-1X20:
-
-      - MEDIA_BUS_FMT_UYVY10_1X20
-      - 0x201a
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - u\ :sub:`9`
-      - u\ :sub:`8`
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - v\ :sub:`9`
-      - v\ :sub:`8`
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-VYUY10-1X20:
-
-      - MEDIA_BUS_FMT_VYUY10_1X20
-      - 0x201b
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - v\ :sub:`9`
-      - v\ :sub:`8`
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - u\ :sub:`9`
-      - u\ :sub:`8`
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-YUYV10-1X20:
-
-      - MEDIA_BUS_FMT_YUYV10_1X20
-      - 0x200d
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-      - u\ :sub:`9`
-      - u\ :sub:`8`
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-      - v\ :sub:`9`
-      - v\ :sub:`8`
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-YVYU10-1X20:
-
-      - MEDIA_BUS_FMT_YVYU10_1X20
-      - 0x200e
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-      - v\ :sub:`9`
-      - v\ :sub:`8`
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-      - u\ :sub:`9`
-      - u\ :sub:`8`
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-VUY8-1X24:
-
-      - MEDIA_BUS_FMT_VUY8_1X24
-      - 0x201a
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-YUV8-1X24:
-
-      - MEDIA_BUS_FMT_YUV8_1X24
-      - 0x2025
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-UYYVYY8-0-5X24:
-
-      - MEDIA_BUS_FMT_UYYVYY8_0_5X24
-      - 0x2026
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-UYVY12-1X24:
-
-      - MEDIA_BUS_FMT_UYVY12_1X24
-      - 0x2020
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - u\ :sub:`11`
-      - u\ :sub:`10`
-      - u\ :sub:`9`
-      - u\ :sub:`8`
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-      - y\ :sub:`11`
-      - y\ :sub:`10`
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - v\ :sub:`11`
-      - v\ :sub:`10`
-      - v\ :sub:`9`
-      - v\ :sub:`8`
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-      - y\ :sub:`11`
-      - y\ :sub:`10`
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-VYUY12-1X24:
-
-      - MEDIA_BUS_FMT_VYUY12_1X24
-      - 0x2021
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - v\ :sub:`11`
-      - v\ :sub:`10`
-      - v\ :sub:`9`
-      - v\ :sub:`8`
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-      - y\ :sub:`11`
-      - y\ :sub:`10`
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - u\ :sub:`11`
-      - u\ :sub:`10`
-      - u\ :sub:`9`
-      - u\ :sub:`8`
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-      - y\ :sub:`11`
-      - y\ :sub:`10`
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-YUYV12-1X24:
-
-      - MEDIA_BUS_FMT_YUYV12_1X24
-      - 0x2022
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`11`
-      - y\ :sub:`10`
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-      - u\ :sub:`11`
-      - u\ :sub:`10`
-      - u\ :sub:`9`
-      - u\ :sub:`8`
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`11`
-      - y\ :sub:`10`
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-      - v\ :sub:`11`
-      - v\ :sub:`10`
-      - v\ :sub:`9`
-      - v\ :sub:`8`
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-YVYU12-1X24:
-
-      - MEDIA_BUS_FMT_YVYU12_1X24
-      - 0x2023
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`11`
-      - y\ :sub:`10`
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-      - v\ :sub:`11`
-      - v\ :sub:`10`
-      - v\ :sub:`9`
-      - v\ :sub:`8`
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`11`
-      - y\ :sub:`10`
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-      - u\ :sub:`11`
-      - u\ :sub:`10`
-      - u\ :sub:`9`
-      - u\ :sub:`8`
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-YUV10-1X30:
-
-      - MEDIA_BUS_FMT_YUV10_1X30
-      - 0x2016
-      -
-      -
-      -
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-      - u\ :sub:`9`
-      - u\ :sub:`8`
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-      - v\ :sub:`9`
-      - v\ :sub:`8`
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-UYYVYY10-0-5X30:
-
-      - MEDIA_BUS_FMT_UYYVYY10_0_5X30
-      - 0x2027
-      -
-      -
-      -
-      - u\ :sub:`9`
-      - u\ :sub:`8`
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      - v\ :sub:`9`
-      - v\ :sub:`8`
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-AYUV8-1X32:
-
-      - MEDIA_BUS_FMT_AYUV8_1X32
-      - 0x2017
-      -
-      - a\ :sub:`7`
-      - a\ :sub:`6`
-      - a\ :sub:`5`
-      - a\ :sub:`4`
-      - a\ :sub:`3`
-      - a\ :sub:`2`
-      - a\ :sub:`1`
-      - a\ :sub:`0`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-
-
-.. raw:: latex
-
-	\endgroup
-
-
-The following table list existing packed 36bit wide YUV formats.
-
-.. raw:: latex
-
-    \begingroup
-    \tiny
-    \setlength{\tabcolsep}{2pt}
-
-.. tabularcolumns:: |p{4.0cm}|p{0.7cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|
-
-.. _v4l2-mbus-pixelcode-yuv8-36bit:
-
-.. flat-table:: 36bit YUV Formats
-    :header-rows:  2
-    :stub-columns: 0
-    :widths: 36 7 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
-
-    * - Identifier
-      - Code
-      -
-      - :cspan:`35` Data organization
-    * -
-      -
-      - Bit
-      - 35
-      - 34
-      - 33
-      - 32
-      - 31
-      - 30
-      - 29
-      - 28
-      - 27
-      - 26
-      - 25
-      - 24
-      - 23
-      - 22
-      - 21
-      - 10
-      - 19
-      - 18
-      - 17
-      - 16
-      - 15
-      - 14
-      - 13
-      - 12
-      - 11
-      - 10
-      - 9
-      - 8
-      - 7
-      - 6
-      - 5
-      - 4
-      - 3
-      - 2
-      - 1
-      - 0
-    * .. _MEDIA-BUS-FMT-UYYVYY12-0-5X36:
-
-      - MEDIA_BUS_FMT_UYYVYY12_0_5X36
-      - 0x2028
-      -
-      - u\ :sub:`11`
-      - u\ :sub:`10`
-      - u\ :sub:`9`
-      - u\ :sub:`8`
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-      - y\ :sub:`11`
-      - y\ :sub:`10`
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-      - y\ :sub:`11`
-      - y\ :sub:`10`
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      - v\ :sub:`11`
-      - v\ :sub:`10`
-      - v\ :sub:`9`
-      - v\ :sub:`8`
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-      - y\ :sub:`11`
-      - y\ :sub:`10`
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-      - y\ :sub:`11`
-      - y\ :sub:`10`
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-YUV12-1X36:
-
-      - MEDIA_BUS_FMT_YUV12_1X36
-      - 0x2029
-      -
-      - y\ :sub:`11`
-      - y\ :sub:`10`
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-      - u\ :sub:`11`
-      - u\ :sub:`10`
-      - u\ :sub:`9`
-      - u\ :sub:`8`
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-      - v\ :sub:`11`
-      - v\ :sub:`10`
-      - v\ :sub:`9`
-      - v\ :sub:`8`
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-
-
-.. raw:: latex
-
-	\endgroup
-
-
-The following table list existing packed 48bit wide YUV formats.
-
-.. raw:: latex
-
-    \begingroup
-    \tiny
-    \setlength{\tabcolsep}{2pt}
-
-.. tabularcolumns:: |p{4.0cm}|p{0.7cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|
-
-.. _v4l2-mbus-pixelcode-yuv8-48bit:
-
-.. flat-table:: 48bit YUV Formats
-    :header-rows:  3
-    :stub-columns: 0
-    :widths: 36 7 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
-
-    * - Identifier
-      - Code
-      -
-      - :cspan:`31` Data organization
-    * -
-      -
-      - Bit
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - 47
-      - 46
-      - 45
-      - 44
-      - 43
-      - 42
-      - 41
-      - 40
-      - 39
-      - 38
-      - 37
-      - 36
-      - 35
-      - 34
-      - 33
-      - 32
-    * -
-      -
-      -
-      - 31
-      - 30
-      - 29
-      - 28
-      - 27
-      - 26
-      - 25
-      - 24
-      - 23
-      - 22
-      - 21
-      - 10
-      - 19
-      - 18
-      - 17
-      - 16
-      - 15
-      - 14
-      - 13
-      - 12
-      - 11
-      - 10
-      - 9
-      - 8
-      - 7
-      - 6
-      - 5
-      - 4
-      - 3
-      - 2
-      - 1
-      - 0
-    * .. _MEDIA-BUS-FMT-YUV16-1X48:
-
-      - MEDIA_BUS_FMT_YUV16_1X48
-      - 0x202a
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - y\ :sub:`15`
-      - y\ :sub:`14`
-      - y\ :sub:`13`
-      - y\ :sub:`12`
-      - y\ :sub:`11`
-      - y\ :sub:`10`
-      - y\ :sub:`8`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      - u\ :sub:`15`
-      - u\ :sub:`14`
-      - u\ :sub:`13`
-      - u\ :sub:`12`
-      - u\ :sub:`11`
-      - u\ :sub:`10`
-      - u\ :sub:`9`
-      - u\ :sub:`8`
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-      - v\ :sub:`15`
-      - v\ :sub:`14`
-      - v\ :sub:`13`
-      - v\ :sub:`12`
-      - v\ :sub:`11`
-      - v\ :sub:`10`
-      - v\ :sub:`9`
-      - v\ :sub:`8`
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-    * .. _MEDIA-BUS-FMT-UYYVYY16-0-5X48:
-
-      - MEDIA_BUS_FMT_UYYVYY16_0_5X48
-      - 0x202b
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - u\ :sub:`15`
-      - u\ :sub:`14`
-      - u\ :sub:`13`
-      - u\ :sub:`12`
-      - u\ :sub:`11`
-      - u\ :sub:`10`
-      - u\ :sub:`9`
-      - u\ :sub:`8`
-      - u\ :sub:`7`
-      - u\ :sub:`6`
-      - u\ :sub:`5`
-      - u\ :sub:`4`
-      - u\ :sub:`3`
-      - u\ :sub:`2`
-      - u\ :sub:`1`
-      - u\ :sub:`0`
-    * -
-      -
-      -
-      - y\ :sub:`15`
-      - y\ :sub:`14`
-      - y\ :sub:`13`
-      - y\ :sub:`12`
-      - y\ :sub:`11`
-      - y\ :sub:`10`
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-      - y\ :sub:`15`
-      - y\ :sub:`14`
-      - y\ :sub:`13`
-      - y\ :sub:`12`
-      - y\ :sub:`11`
-      - y\ :sub:`10`
-      - y\ :sub:`8`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-    * -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      - v\ :sub:`15`
-      - v\ :sub:`14`
-      - v\ :sub:`13`
-      - v\ :sub:`12`
-      - v\ :sub:`11`
-      - v\ :sub:`10`
-      - v\ :sub:`9`
-      - v\ :sub:`8`
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-    * -
-      -
-      -
-      - y\ :sub:`15`
-      - y\ :sub:`14`
-      - y\ :sub:`13`
-      - y\ :sub:`12`
-      - y\ :sub:`11`
-      - y\ :sub:`10`
-      - y\ :sub:`9`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-      - y\ :sub:`15`
-      - y\ :sub:`14`
-      - y\ :sub:`13`
-      - y\ :sub:`12`
-      - y\ :sub:`11`
-      - y\ :sub:`10`
-      - y\ :sub:`8`
-      - y\ :sub:`8`
-      - y\ :sub:`7`
-      - y\ :sub:`6`
-      - y\ :sub:`5`
-      - y\ :sub:`4`
-      - y\ :sub:`3`
-      - y\ :sub:`2`
-      - y\ :sub:`1`
-      - y\ :sub:`0`
-
-
-.. raw:: latex
-
-	\endgroup
-
-HSV/HSL Formats
-^^^^^^^^^^^^^^^
-
-Those formats transfer pixel data as RGB values in a
-cylindrical-coordinate system using Hue-Saturation-Value or
-Hue-Saturation-Lightness components. The format code is made of the
-following information.
-
--  The hue, saturation, value or lightness and optional alpha components
-   order code, as encoded in a pixel sample. The only currently
-   supported value is AHSV.
-
--  The number of bits per component, for each component. The values can
-   be different for all components. The only currently supported value
-   is 8888.
-
--  The number of bus samples per pixel. Pixels that are wider than the
-   bus width must be transferred in multiple samples. The only currently
-   supported value is 1.
-
--  The bus width.
-
--  For formats where the total number of bits per pixel is smaller than
-   the number of bus samples per pixel times the bus width, a padding
-   value stating if the bytes are padded in their most high order bits
-   (PADHI) or low order bits (PADLO).
-
--  For formats where the number of bus samples per pixel is larger than
-   1, an endianness value stating if the pixel is transferred MSB first
-   (BE) or LSB first (LE).
-
-The following table lists existing HSV/HSL formats.
-
-
-.. raw:: latex
-
-    \begingroup
-    \tiny
-    \setlength{\tabcolsep}{2pt}
-
-.. tabularcolumns:: |p{3.9cm}|p{0.73cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|
-
-.. _v4l2-mbus-pixelcode-hsv:
-
-.. flat-table:: HSV/HSL formats
-    :header-rows:  2
-    :stub-columns: 0
-    :widths: 28 7 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
-
-    * - Identifier
-      - Code
-      -
-      - :cspan:`31` Data organization
-    * -
-      -
-      - Bit
-      - 31
-      - 30
-      - 29
-      - 28
-      - 27
-      - 26
-      - 25
-      - 24
-      - 23
-      - 22
-      - 21
-      - 20
-      - 19
-      - 18
-      - 17
-      - 16
-      - 15
-      - 14
-      - 13
-      - 12
-      - 11
-      - 10
-      - 9
-      - 8
-      - 7
-      - 6
-      - 5
-      - 4
-      - 3
-      - 2
-      - 1
-      - 0
-    * .. _MEDIA-BUS-FMT-AHSV8888-1X32:
-
-      - MEDIA_BUS_FMT_AHSV8888_1X32
-      - 0x6001
-      -
-      - a\ :sub:`7`
-      - a\ :sub:`6`
-      - a\ :sub:`5`
-      - a\ :sub:`4`
-      - a\ :sub:`3`
-      - a\ :sub:`2`
-      - a\ :sub:`1`
-      - a\ :sub:`0`
-      - h\ :sub:`7`
-      - h\ :sub:`6`
-      - h\ :sub:`5`
-      - h\ :sub:`4`
-      - h\ :sub:`3`
-      - h\ :sub:`2`
-      - h\ :sub:`1`
-      - h\ :sub:`0`
-      - s\ :sub:`7`
-      - s\ :sub:`6`
-      - s\ :sub:`5`
-      - s\ :sub:`4`
-      - s\ :sub:`3`
-      - s\ :sub:`2`
-      - s\ :sub:`1`
-      - s\ :sub:`0`
-      - v\ :sub:`7`
-      - v\ :sub:`6`
-      - v\ :sub:`5`
-      - v\ :sub:`4`
-      - v\ :sub:`3`
-      - v\ :sub:`2`
-      - v\ :sub:`1`
-      - v\ :sub:`0`
-
-.. raw:: latex
-
-    \normalsize
-
-
-JPEG Compressed Formats
-^^^^^^^^^^^^^^^^^^^^^^^
-
-Those data formats consist of an ordered sequence of 8-bit bytes
-obtained from JPEG compression process. Additionally to the ``_JPEG``
-postfix the format code is made of the following information.
-
--  The number of bus samples per entropy encoded byte.
-
--  The bus width.
-
-For instance, for a JPEG baseline process and an 8-bit bus width the
-format will be named ``MEDIA_BUS_FMT_JPEG_1X8``.
-
-The following table lists existing JPEG compressed formats.
-
-
-.. _v4l2-mbus-pixelcode-jpeg:
-
-.. tabularcolumns:: |p{6.0cm}|p{1.4cm}|p{10.1cm}|
-
-.. flat-table:: JPEG Formats
-    :header-rows:  1
-    :stub-columns: 0
-
-    * - Identifier
-      - Code
-      - Remarks
-    * .. _MEDIA-BUS-FMT-JPEG-1X8:
-
-      - MEDIA_BUS_FMT_JPEG_1X8
-      - 0x4001
-      - Besides of its usage for the parallel bus this format is
-	recommended for transmission of JPEG data over MIPI CSI bus using
-	the User Defined 8-bit Data types.
-
-
-
-.. _v4l2-mbus-vendor-spec-fmts:
-
-Vendor and Device Specific Formats
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-This section lists complex data formats that are either vendor or device
-specific.
-
-The following table lists the existing vendor and device specific
-formats.
-
-
-.. _v4l2-mbus-pixelcode-vendor-specific:
-
-.. tabularcolumns:: |p{8.0cm}|p{1.4cm}|p{7.7cm}|
-
-.. flat-table:: Vendor and device specific formats
-    :header-rows:  1
-    :stub-columns: 0
-
-    * - Identifier
-      - Code
-      - Comments
-    * .. _MEDIA-BUS-FMT-S5C-UYVY-JPEG-1X8:
-
-      - MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8
-      - 0x5001
-      - Interleaved raw UYVY and JPEG image format with embedded meta-data
-	used by Samsung S3C73MX camera sensors.
diff --git a/Documentation/media/uapi/v4l/subdev-image-processing-crop.svg b/Documentation/media/uapi/v4l/subdev-image-processing-crop.svg
deleted file mode 100644
index 59321e09929d..000000000000
--- a/Documentation/media/uapi/v4l/subdev-image-processing-crop.svg
+++ /dev/null
@@ -1,312 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!--
-    Permission is granted to copy, distribute and/or modify this
-    document under the terms of the GNU Free Documentation License,
-    Version 1.1 or any later version published by the Free Software
-    Foundation, with no Invariant Sections, no Front-Cover Texts
-    and no Back-Cover Texts. A copy of the license is included at
-    Documentation/media/uapi/fdl-appendix.rst.
-
-    TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
--->
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="42.799767cm"
-   height="9.9348345cm"
-   viewBox="-194 128 840.06984 194.72276"
-   id="svg2"
-   version="1.1"
-   inkscape:version="0.91 r13725"
-   sodipodi:docname="subdev-image-processing-crop.svg">
-  <metadata
-     id="metadata100">
-    <rdf:RDF>
-      <cc:Work
-	 rdf:about="">
-	<dc:format>image/svg+xml</dc:format>
-	<dc:type
-	   rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-	<dc:title />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <defs
-     id="defs98" />
-  <sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="1920"
-     inkscape:window-height="997"
-     id="namedview96"
-     showgrid="false"
-     fit-margin-top="0"
-     fit-margin-left="0"
-     fit-margin-right="0"
-     fit-margin-bottom="0"
-     inkscape:zoom="0.3649199"
-     inkscape:cx="764.40286"
-     inkscape:cy="176.91347"
-     inkscape:window-x="1920"
-     inkscape:window-y="30"
-     inkscape:window-maximized="1"
-     inkscape:current-layer="svg2" />
-  <rect
-     style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-     x="-9.6002426"
-     y="128.86047"
-     width="469.77399"
-     height="193"
-     id="rect4" />
-  <g
-     id="g6"
-     transform="translate(-1.6002426,-1.1395339)">
-    <rect
-       style="fill:#ffffff"
-       x="4.5"
-       y="189"
-       width="159"
-       height="104"
-       id="rect8" />
-    <rect
-       style="fill:none;fill-opacity:0;stroke:#a52a2a;stroke-width:2"
-       x="4.5"
-       y="189"
-       width="159"
-       height="104"
-       id="rect10" />
-  </g>
-  <g
-     id="g12"
-     transform="translate(-1.6002426,-1.1395339)">
-    <rect
-       style="fill:#ffffff"
-       x="63.5"
-       y="211"
-       width="94"
-       height="77"
-       id="rect14" />
-    <rect
-       style="fill:none;fill-opacity:0;stroke:#0000ff;stroke-width:2"
-       x="63.5"
-       y="211"
-       width="94"
-       height="77"
-       id="rect16" />
-  </g>
-  <text
-     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#0000ff"
-     x="72.899757"
-     y="226.61047"
-     id="text18">
-    <tspan
-       x="72.899757"
-       y="226.61047"
-       id="tspan20">sink</tspan>
-    <tspan
-       x="72.899757"
-       y="242.61047"
-       id="tspan22">crop</tspan>
-    <tspan
-       x="72.899757"
-       y="258.61047"
-       id="tspan24">selection</tspan>
-  </text>
-  <text
-     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#000000"
-     x="27.899757"
-     y="156.86047"
-     id="text26">
-    <tspan
-       x="27.899757"
-       y="156.86047"
-       id="tspan28" />
-  </text>
-  <text
-     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#a52a2a"
-     x="6.938117"
-     y="156.77448"
-     id="text30">
-    <tspan
-       x="6.938117"
-       y="156.77448"
-       id="tspan32">sink media</tspan>
-    <tspan
-       x="6.938117"
-       y="172.77448"
-       id="tspan34">bus format</tspan>
-  </text>
-  <text
-     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#8b6914"
-     x="348.17374"
-     y="153.86047"
-     id="text36">
-    <tspan
-       x="348.17374"
-       y="153.86047"
-       id="tspan38">source media</tspan>
-    <tspan
-       x="348.17374"
-       y="169.86047"
-       id="tspan40">bus format</tspan>
-  </text>
-  <g
-     id="g42"
-     transform="translate(-1.6002426,-1.1395339)">
-    <rect
-       style="fill:#ffffff"
-       x="350.48801"
-       y="190.834"
-       width="93.286301"
-       height="75.166"
-       id="rect44" />
-    <rect
-       style="fill:none;fill-opacity:0;stroke:#8b6914;stroke-width:2"
-       x="350.48801"
-       y="190.834"
-       width="93.286301"
-       height="75.166"
-       id="rect46" />
-  </g>
-  <line
-     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
-     x1="348.88776"
-     y1="264.86047"
-     x2="61.899757"
-     y2="286.86047"
-     id="line48" />
-  <line
-     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
-     x1="348.88776"
-     y1="189.69447"
-     x2="61.899757"
-     y2="209.86047"
-     id="line50" />
-  <line
-     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
-     x1="442.17374"
-     y1="264.86047"
-     x2="155.89977"
-     y2="286.86047"
-     id="line52" />
-  <line
-     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
-     x1="442.17374"
-     y1="189.69447"
-     x2="155.89977"
-     y2="209.86047"
-     id="line54" />
-  <g
-     id="g56"
-     transform="translate(-1.6002426,-1.1395339)">
-    <circle
-       style="fill:#ffffff"
-       cx="473.10001"
-       cy="219.98399"
-       id="ellipse58"
-       r="8.5" />
-    <circle
-       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-       cx="473.10001"
-       cy="219.98399"
-       id="ellipse60"
-       r="8.5" />
-    <circle
-       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-       cx="473.10001"
-       cy="219.98399"
-       id="ellipse62"
-       r="8.5" />
-  </g>
-  <g
-     id="g64"
-     transform="translate(-1.6002426,-1.1395339)">
-    <line
-       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-       x1="481.60001"
-       y1="219.98399"
-       x2="637.93402"
-       y2="220.01199"
-       id="line66" />
-    <polygon
-       style="fill:#000000"
-       points="635.435,215.012 645.434,220.014 635.433,225.012 637.934,220.012 "
-       id="polygon68" />
-    <polygon
-       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-       points="635.435,215.012 645.434,220.014 635.433,225.012 637.934,220.012 "
-       id="polygon70" />
-  </g>
-  <text
-     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#000000"
-     x="505.30774"
-     y="208.66048"
-     id="text72">
-    <tspan
-       x="505.30774"
-       y="208.66048"
-       id="tspan74">pad 1 (source)</tspan>
-  </text>
-  <g
-     id="g76"
-     transform="translate(-1.6002426,-1.1395339)">
-    <circle
-       style="fill:#ffffff"
-       cx="-20.398199"
-       cy="241.51199"
-       id="ellipse78"
-       r="8.5" />
-    <circle
-       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-       cx="-20.398199"
-       cy="241.51199"
-       id="ellipse80"
-       r="8.5" />
-    <circle
-       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-       cx="-20.398199"
-       cy="241.51199"
-       id="ellipse82"
-       r="8.5" />
-  </g>
-  <g
-     id="g84"
-     transform="translate(-1.6002426,-1.1395339)">
-    <line
-       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-       x1="-192.39799"
-       y1="241.8"
-       x2="-38.6343"
-       y2="241.52901"
-       id="line86" />
-    <polygon
-       style="fill:#000000"
-       points="-41.1431,236.534 -31.1343,241.516 -41.1254,246.534 -38.6343,241.529 "
-       id="polygon88" />
-    <polygon
-       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-       points="-41.1431,236.534 -31.1343,241.516 -41.1254,246.534 -38.6343,241.529 "
-       id="polygon90" />
-  </g>
-  <text
-     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#000000"
-     x="-149.45824"
-     y="228.66048"
-     id="text92">
-    <tspan
-       x="-149.45824"
-       y="228.66048"
-       id="tspan94">pad 0 (sink)</tspan>
-  </text>
-</svg>
diff --git a/Documentation/media/uapi/v4l/subdev-image-processing-full.svg b/Documentation/media/uapi/v4l/subdev-image-processing-full.svg
deleted file mode 100644
index e739c54fbbfb..000000000000
--- a/Documentation/media/uapi/v4l/subdev-image-processing-full.svg
+++ /dev/null
@@ -1,752 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!--
-    Permission is granted to copy, distribute and/or modify this
-    document under the terms of the GNU Free Documentation License,
-    Version 1.1 or any later version published by the Free Software
-    Foundation, with no Invariant Sections, no Front-Cover Texts
-    and no Back-Cover Texts. A copy of the license is included at
-    Documentation/media/uapi/fdl-appendix.rst.
-
-    TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
--->
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="58.825298cm"
-   height="17.279287cm"
-   viewBox="-186 71 1174.5119 332.1463"
-   id="svg2"
-   version="1.1"
-   inkscape:version="0.91 r13725"
-   sodipodi:docname="subdev-image-processing-full.svg">
-  <metadata
-     id="metadata260">
-    <rdf:RDF>
-      <cc:Work
-	 rdf:about="">
-	<dc:format>image/svg+xml</dc:format>
-	<dc:type
-	   rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-	<dc:title />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <defs
-     id="defs258" />
-  <sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="1920"
-     inkscape:window-height="997"
-     id="namedview256"
-     showgrid="false"
-     fit-margin-top="0"
-     fit-margin-left="0"
-     fit-margin-right="0"
-     fit-margin-bottom="0"
-     inkscape:zoom="0.26595857"
-     inkscape:cx="1050.1367"
-     inkscape:cy="307.01645"
-     inkscape:window-x="1920"
-     inkscape:window-y="30"
-     inkscape:window-maximized="1"
-     inkscape:current-layer="svg2" />
-  <g
-     id="g4"
-     transform="translate(-1.4982376,-7.6949076)">
-    <rect
-       style="fill:#ffffff"
-       x="318.89999"
-       y="129"
-       width="208.10001"
-       height="249"
-       id="rect6" />
-    <rect
-       style="fill:none;fill-opacity:0;stroke:#ff765a;stroke-width:2"
-       x="318.89999"
-       y="129"
-       width="208.10001"
-       height="249"
-       id="rect8" />
-  </g>
-  <rect
-     style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-     x="-3.4982376"
-     y="65.305092"
-     width="806"
-     height="343"
-     id="rect10" />
-  <g
-     id="g12"
-     transform="translate(-1.4982376,-7.6949076)">
-    <circle
-       style="fill:#ffffff"
-       cx="-12.5"
-       cy="166.71201"
-       id="ellipse14"
-       r="8.5" />
-    <circle
-       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-       cx="-12.5"
-       cy="166.71201"
-       id="ellipse16"
-       r="8.5" />
-    <circle
-       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-       cx="-12.5"
-       cy="166.71201"
-       id="ellipse18"
-       r="8.5" />
-  </g>
-  <g
-     id="g20"
-     transform="translate(-1.4982376,-7.6949076)">
-    <circle
-       style="fill:#ffffff"
-       cx="815.23199"
-       cy="205.18401"
-       id="ellipse22"
-       r="8.5" />
-    <circle
-       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-       cx="815.23199"
-       cy="205.18401"
-       id="ellipse24"
-       r="8.5" />
-    <circle
-       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-       cx="815.23199"
-       cy="205.18401"
-       id="ellipse26"
-       r="8.5" />
-  </g>
-  <g
-     id="g28"
-     transform="translate(-1.4982376,-7.6949076)">
-    <line
-       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-       x1="-184.5"
-       y1="167"
-       x2="-30.736099"
-       y2="166.729"
-       id="line30" />
-    <polygon
-       style="fill:#000000"
-       points="-33.2449,161.734 -23.2361,166.716 -33.2272,171.734 -30.7361,166.729 "
-       id="polygon32" />
-    <polygon
-       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-       points="-33.2449,161.734 -23.2361,166.716 -33.2272,171.734 -30.7361,166.729 "
-       id="polygon34" />
-  </g>
-  <g
-     id="g36"
-     transform="translate(-1.4982376,-7.6949076)">
-    <line
-       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-       x1="823.73199"
-       y1="205.18401"
-       x2="980.06598"
-       y2="205.21201"
-       id="line38" />
-    <polygon
-       style="fill:#000000"
-       points="977.567,200.212 987.566,205.214 977.565,210.212 980.066,205.212 "
-       id="polygon40" />
-    <polygon
-       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-       points="977.567,200.212 987.566,205.214 977.565,210.212 980.066,205.212 "
-       id="polygon42" />
-  </g>
-  <text
-     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#000000"
-     x="-141.45824"
-     y="147.3051"
-     id="text44">
-    <tspan
-       x="-141.45824"
-       y="147.3051"
-       id="tspan46">pad 0 (sink)</tspan>
-  </text>
-  <text
-     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#000000"
-     x="847.54175"
-     y="187.3051"
-     id="text48">
-    <tspan
-       x="847.54175"
-       y="187.3051"
-       id="tspan50">pad 2 (source)</tspan>
-  </text>
-  <g
-     id="g52"
-     transform="translate(-1.4982376,-7.6949076)">
-    <rect
-       style="fill:#ffffff"
-       x="5.5"
-       y="120"
-       width="159"
-       height="104"
-       id="rect54" />
-    <rect
-       style="fill:none;fill-opacity:0;stroke:#a52a2a;stroke-width:2"
-       x="5.5"
-       y="120"
-       width="159"
-       height="104"
-       id="rect56" />
-  </g>
-  <g
-     id="g58"
-     transform="translate(-1.4982376,-7.6949076)">
-    <rect
-       style="fill:#ffffff"
-       x="62.5"
-       y="136"
-       width="94"
-       height="77"
-       id="rect60" />
-    <rect
-       style="fill:none;fill-opacity:0;stroke:#0000ff;stroke-width:2"
-       x="62.5"
-       y="136"
-       width="94"
-       height="77"
-       id="rect62" />
-  </g>
-  <text
-     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#000000"
-     x="29.001762"
-     y="81.305092"
-     id="text64">
-    <tspan
-       x="29.001762"
-       y="81.305092"
-       id="tspan66" />
-  </text>
-  <text
-     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#a52a2a"
-     x="8.040122"
-     y="81.218895"
-     id="text68">
-    <tspan
-       x="8.040122"
-       y="81.218895"
-       id="tspan70">sink media</tspan>
-    <tspan
-       x="8.040122"
-       y="97.219093"
-       id="tspan72">bus format</tspan>
-  </text>
-  <g
-     id="g74"
-     transform="translate(-1.4982376,-7.6949076)">
-    <rect
-       style="fill:#ffffff"
-       x="333.64401"
-       y="185.64999"
-       width="165.2"
-       height="172.478"
-       id="rect76" />
-    <rect
-       style="fill:none;fill-opacity:0;stroke:#00ff00;stroke-width:2"
-       x="333.64401"
-       y="185.64999"
-       width="165.2"
-       height="172.478"
-       id="rect78" />
-  </g>
-  <line
-     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
-     x1="332.14578"
-     y1="350.43307"
-     x2="61.001762"
-     y2="205.3051"
-     id="line80" />
-  <line
-     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
-     x1="332.14578"
-     y1="177.95509"
-     x2="61.001762"
-     y2="128.3051"
-     id="line82" />
-  <line
-     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
-     x1="497.34576"
-     y1="350.43307"
-     x2="155.00177"
-     y2="205.3051"
-     id="line84" />
-  <line
-     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
-     x1="497.34576"
-     y1="177.95509"
-     x2="155.00177"
-     y2="128.3051"
-     id="line86" />
-  <text
-     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#00ff00"
-     x="333.20578"
-     y="141.7471"
-     id="text88">
-    <tspan
-       x="333.20578"
-       y="141.7471"
-       id="tspan90">sink compose</tspan>
-    <tspan
-       x="333.20578"
-       y="157.7471"
-       id="tspan92">selection (scaling)</tspan>
-  </text>
-  <g
-     id="g94"
-     transform="translate(-1.4982376,-7.6949076)">
-    <rect
-       style="fill:#ffffff"
-       x="409.32199"
-       y="194.565"
-       width="100.186"
-       height="71.452301"
-       id="rect96" />
-    <rect
-       style="fill:none;fill-opacity:0;stroke:#a020f0;stroke-width:2"
-       x="409.32199"
-       y="194.565"
-       width="100.186"
-       height="71.452301"
-       id="rect98" />
-  </g>
-  <text
-     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#8b6914"
-     x="688.00177"
-     y="97.43309"
-     id="text100">
-    <tspan
-       x="688.00177"
-       y="97.43309"
-       id="tspan102">source media</tspan>
-    <tspan
-       x="688.00177"
-       y="113.43309"
-       id="tspan104">bus format</tspan>
-  </text>
-  <g
-     id="g106"
-     transform="translate(-1.4982376,-7.6949076)">
-    <rect
-       style="fill:#ffffff"
-       x="688.48798"
-       y="173.834"
-       width="100.186"
-       height="71.452301"
-       id="rect108" />
-    <rect
-       style="fill:none;fill-opacity:0;stroke:#8b6914;stroke-width:2"
-       x="688.48798"
-       y="173.834"
-       width="100.186"
-       height="71.452301"
-       id="rect110" />
-  </g>
-  <line
-     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
-     x1="686.98975"
-     y1="237.59109"
-     x2="407.82376"
-     y2="258.32309"
-     id="line112" />
-  <line
-     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
-     x1="686.98975"
-     y1="166.1391"
-     x2="407.82376"
-     y2="186.8701"
-     id="line114" />
-  <line
-     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
-     x1="787.17578"
-     y1="237.59109"
-     x2="508.00977"
-     y2="258.32309"
-     id="line116" />
-  <line
-     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
-     x1="787.17578"
-     y1="166.1391"
-     x2="508.00977"
-     y2="186.8701"
-     id="line118" />
-  <text
-     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#ff765a"
-     x="323.50177"
-     y="95.305092"
-     id="text120">
-    <tspan
-       x="323.50177"
-       y="95.305092"
-       id="tspan122">sink compose</tspan>
-    <tspan
-       x="323.50177"
-       y="111.30509"
-       id="tspan124">bounds selection</tspan>
-  </text>
-  <g
-     id="g126"
-     transform="translate(-1.4982376,-7.6949076)">
-    <circle
-       style="fill:#ffffff"
-       cx="-12.0982"
-       cy="341.51199"
-       id="ellipse128"
-       r="8.5" />
-    <circle
-       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-       cx="-12.0982"
-       cy="341.51199"
-       id="ellipse130"
-       r="8.5" />
-    <circle
-       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-       cx="-12.0982"
-       cy="341.51199"
-       id="ellipse132"
-       r="8.5" />
-  </g>
-  <g
-     id="g134"
-     transform="translate(-1.4982376,-7.6949076)">
-    <line
-       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-       x1="-184.09801"
-       y1="341.79999"
-       x2="-30.334299"
-       y2="341.52899"
-       id="line136" />
-    <polygon
-       style="fill:#000000"
-       points="-32.8431,336.534 -22.8343,341.516 -32.8254,346.534 -30.3343,341.529 "
-       id="polygon138" />
-    <polygon
-       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-       points="-32.8431,336.534 -22.8343,341.516 -32.8254,346.534 -30.3343,341.529 "
-       id="polygon140" />
-  </g>
-  <text
-     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#000000"
-     x="-140.49823"
-     y="321.30508"
-     id="text142">
-    <tspan
-       x="-140.49823"
-       y="321.30508"
-       id="tspan144">pad 1 (sink)</tspan>
-  </text>
-  <g
-     id="g146"
-     transform="translate(-1.4982376,-7.6949076)">
-    <rect
-       style="fill:#ffffff"
-       x="7.8082399"
-       y="292.79999"
-       width="112.092"
-       height="82.199997"
-       id="rect148" />
-    <rect
-       style="fill:none;fill-opacity:0;stroke:#a52a2a;stroke-width:2"
-       x="7.8082399"
-       y="292.79999"
-       width="112.092"
-       height="82.199997"
-       id="rect150" />
-  </g>
-  <g
-     id="g152"
-     transform="translate(-1.4982376,-7.6949076)">
-    <rect
-       style="fill:#ffffff"
-       x="52.900002"
-       y="314.79999"
-       width="58.099998"
-       height="50.200001"
-       id="rect154" />
-    <rect
-       style="fill:none;fill-opacity:0;stroke:#0000ff;stroke-width:2"
-       x="52.900002"
-       y="314.79999"
-       width="58.099998"
-       height="50.200001"
-       id="rect156" />
-  </g>
-  <text
-     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#000000"
-     x="30.401762"
-     y="252.10509"
-     id="text158">
-    <tspan
-       x="30.401762"
-       y="252.10509"
-       id="tspan160" />
-  </text>
-  <line
-     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
-     x1="357.40176"
-     y1="244.20509"
-     x2="51.401764"
-     y2="307.10507"
-     id="line162" />
-  <line
-     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
-     x1="357.40176"
-     y1="308.30508"
-     x2="51.401764"
-     y2="357.30508"
-     id="line164" />
-  <line
-     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
-     x1="432.50177"
-     y1="308.30508"
-     x2="109.50176"
-     y2="357.30508"
-     id="line166" />
-  <line
-     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
-     x1="432.50177"
-     y1="244.20509"
-     x2="109.50176"
-     y2="307.10507"
-     id="line168" />
-  <rect
-     style="fill:none;fill-opacity:0;stroke:#00ff00;stroke-width:2"
-     x="357.40176"
-     y="244.20509"
-     width="75.099998"
-     height="64.099998"
-     id="rect170" />
-  <rect
-     style="fill:none;fill-opacity:0;stroke:#a020f0;stroke-width:2"
-     x="441.76376"
-     y="276.77109"
-     width="64.737999"
-     height="48.534"
-     id="rect172" />
-  <g
-     id="g174"
-     transform="translate(-1.4982376,-7.6949076)">
-    <rect
-       style="fill:#ffffff"
-       x="693.42798"
-       y="324.73401"
-       width="63.571999"
-       height="49.265999"
-       id="rect176" />
-    <rect
-       style="fill:none;fill-opacity:0;stroke:#8b6914;stroke-width:2"
-       x="693.42798"
-       y="324.73401"
-       width="63.571999"
-       height="49.265999"
-       id="rect178" />
-  </g>
-  <line
-     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
-     x1="691.92975"
-     y1="366.30508"
-     x2="441.76376"
-     y2="325.30508"
-     id="line180" />
-  <line
-     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
-     x1="691.92975"
-     y1="317.03909"
-     x2="441.76376"
-     y2="276.77109"
-     id="line182" />
-  <line
-     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
-     x1="755.50177"
-     y1="366.30508"
-     x2="506.50177"
-     y2="325.30508"
-     id="line184" />
-  <line
-     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
-     x1="755.50177"
-     y1="317.03909"
-     x2="506.50177"
-     y2="276.77109"
-     id="line186" />
-  <g
-     id="g188"
-     transform="translate(-1.4982376,-7.6949076)">
-    <circle
-       style="fill:#ffffff"
-       cx="815.44"
-       cy="343.98401"
-       id="ellipse190"
-       r="8.5" />
-    <circle
-       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-       cx="815.44"
-       cy="343.98401"
-       id="ellipse192"
-       r="8.5" />
-    <circle
-       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-       cx="815.44"
-       cy="343.98401"
-       id="ellipse194"
-       r="8.5" />
-  </g>
-  <g
-     id="g196"
-     transform="translate(-1.4982376,-7.6949076)">
-    <line
-       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-       x1="823.94"
-       y1="343.98401"
-       x2="980.27399"
-       y2="344.01199"
-       id="line198" />
-    <polygon
-       style="fill:#000000"
-       points="977.775,339.012 987.774,344.014 977.773,349.012 980.274,344.012 "
-       id="polygon200" />
-    <polygon
-       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-       points="977.775,339.012 987.774,344.014 977.773,349.012 980.274,344.012 "
-       id="polygon202" />
-  </g>
-  <text
-     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#000000"
-     x="847.74976"
-     y="326.10507"
-     id="text204">
-    <tspan
-       x="847.74976"
-       y="326.10507"
-       id="tspan206">pad 3 (source)</tspan>
-  </text>
-  <text
-     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#0000ff"
-     x="195.50177"
-     y="83.305092"
-     id="text208">
-    <tspan
-       x="195.50177"
-       y="83.305092"
-       id="tspan210">sink</tspan>
-    <tspan
-       x="195.50177"
-       y="99.305092"
-       id="tspan212">crop</tspan>
-    <tspan
-       x="195.50177"
-       y="115.30509"
-       id="tspan214">selection</tspan>
-  </text>
-  <text
-     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#a020f0"
-     x="551.50177"
-     y="87.305092"
-     id="text216">
-    <tspan
-       x="551.50177"
-       y="87.305092"
-       id="tspan218">source</tspan>
-    <tspan
-       x="551.50177"
-       y="103.30509"
-       id="tspan220">crop</tspan>
-    <tspan
-       x="551.50177"
-       y="119.30509"
-       id="tspan222">selection</tspan>
-  </text>
-  <g
-     id="g224"
-     transform="translate(-1.4982376,-7.6949076)">
-    <line
-       style="fill:none;fill-opacity:0;stroke:#0000ff;stroke-width:2"
-       x1="211"
-       y1="132"
-       x2="166.21001"
-       y2="135.287"
-       id="line226" />
-    <polygon
-       style="fill:#0000ff"
-       points="169.069,140.091 158.73,135.836 168.337,130.118 166.21,135.287 "
-       id="polygon228" />
-    <polygon
-       style="fill:none;fill-opacity:0;stroke:#0000ff;stroke-width:2"
-       points="169.069,140.091 158.73,135.836 168.337,130.118 166.21,135.287 "
-       id="polygon230" />
-  </g>
-  <g
-     id="g232"
-     transform="translate(-1.4982376,-7.6949076)">
-    <line
-       style="fill:none;fill-opacity:0;stroke:#0000ff;stroke-width:2"
-       x1="209"
-       y1="131"
-       x2="115.581"
-       y2="306.20901"
-       id="line234" />
-    <polygon
-       style="fill:#0000ff"
-       points="121.169,306.355 112.052,312.827 112.345,301.65 115.581,306.209 "
-       id="polygon236" />
-    <polygon
-       style="fill:none;fill-opacity:0;stroke:#0000ff;stroke-width:2"
-       points="121.169,306.355 112.052,312.827 112.345,301.65 115.581,306.209 "
-       id="polygon238" />
-  </g>
-  <g
-     id="g240"
-     transform="translate(-1.4982376,-7.6949076)">
-    <line
-       style="fill:none;fill-opacity:0;stroke:#a020f0;stroke-width:2"
-       x1="550.492"
-       y1="133.214"
-       x2="514.91602"
-       y2="186.46899"
-       id="line242" />
-    <polygon
-       style="fill:#a020f0"
-       points="520.463,187.168 510.75,192.706 512.147,181.613 514.916,186.469 "
-       id="polygon244" />
-    <polygon
-       style="fill:none;fill-opacity:0;stroke:#a020f0;stroke-width:2"
-       points="520.463,187.168 510.75,192.706 512.147,181.613 514.916,186.469 "
-       id="polygon246" />
-  </g>
-  <g
-     id="g248"
-     transform="translate(-1.4982376,-7.6949076)">
-    <line
-       style="fill:none;fill-opacity:0;stroke:#a020f0;stroke-width:2"
-       x1="550.07202"
-       y1="133.787"
-       x2="510.61801"
-       y2="275.08899"
-       id="line250" />
-    <polygon
-       style="fill:#a020f0"
-       points="516.106,274.025 508.601,282.312 506.475,271.336 510.618,275.089 "
-       id="polygon252" />
-    <polygon
-       style="fill:none;fill-opacity:0;stroke:#a020f0;stroke-width:2"
-       points="516.106,274.025 508.601,282.312 506.475,271.336 510.618,275.089 "
-       id="polygon254" />
-  </g>
-</svg>
diff --git a/Documentation/media/uapi/v4l/subdev-image-processing-scaling-multi-source.svg b/Documentation/media/uapi/v4l/subdev-image-processing-scaling-multi-source.svg
deleted file mode 100644
index 401d1456958c..000000000000
--- a/Documentation/media/uapi/v4l/subdev-image-processing-scaling-multi-source.svg
+++ /dev/null
@@ -1,550 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!--
-    Permission is granted to copy, distribute and/or modify this
-    document under the terms of the GNU Free Documentation License,
-    Version 1.1 or any later version published by the Free Software
-    Foundation, with no Invariant Sections, no Front-Cover Texts
-    and no Back-Cover Texts. A copy of the license is included at
-    Documentation/media/uapi/fdl-appendix.rst.
-
-    TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
--->
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="58.803326cm"
-   height="16.463955cm"
-   viewBox="-194 128 1175.0698 319.59442"
-   id="svg2"
-   version="1.1"
-   inkscape:version="0.91 r13725"
-   sodipodi:docname="subdev-image-processing-scaling-multi-source.svg">
-  <metadata
-     id="metadata186">
-    <rdf:RDF>
-      <cc:Work
-	 rdf:about="">
-	<dc:format>image/svg+xml</dc:format>
-	<dc:type
-	   rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-	<dc:title />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <defs
-     id="defs184" />
-  <sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="1920"
-     inkscape:window-height="997"
-     id="namedview182"
-     showgrid="false"
-     fit-margin-top="0"
-     fit-margin-left="0"
-     fit-margin-right="0"
-     fit-margin-bottom="0"
-     inkscape:zoom="0.26595857"
-     inkscape:cx="1049.9581"
-     inkscape:cy="292.5708"
-     inkscape:window-x="1920"
-     inkscape:window-y="30"
-     inkscape:window-maximized="1"
-     inkscape:current-layer="svg2" />
-  <rect
-     style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-     x="-9.6002426"
-     y="124.14409"
-     width="806"
-     height="327"
-     id="rect4" />
-  <g
-     id="g6"
-     transform="translate(-1.6002426,-5.8559115)">
-    <rect
-       style="fill:#ffffff"
-       x="4.5"
-       y="189"
-       width="159"
-       height="104"
-       id="rect8" />
-    <rect
-       style="fill:none;fill-opacity:0;stroke:#a52a2a;stroke-width:2"
-       x="4.5"
-       y="189"
-       width="159"
-       height="104"
-       id="rect10" />
-  </g>
-  <g
-     id="g12"
-     transform="translate(-1.6002426,-5.8559115)">
-    <rect
-       style="fill:#ffffff"
-       x="49.5"
-       y="204"
-       width="94"
-       height="77"
-       id="rect14" />
-    <rect
-       style="fill:none;fill-opacity:0;stroke:#0000ff;stroke-width:2"
-       x="49.5"
-       y="204"
-       width="94"
-       height="77"
-       id="rect16" />
-  </g>
-  <text
-     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#0000ff"
-     x="58.399757"
-     y="218.14409"
-     id="text18">
-    <tspan
-       x="58.399757"
-       y="218.14409"
-       id="tspan20">sink</tspan>
-    <tspan
-       x="58.399757"
-       y="234.14409"
-       id="tspan22">crop</tspan>
-    <tspan
-       x="58.399757"
-       y="250.14409"
-       id="tspan24">selection</tspan>
-  </text>
-  <text
-     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#000000"
-     x="27.899757"
-     y="152.14409"
-     id="text26">
-    <tspan
-       x="27.899757"
-       y="152.14409"
-       id="tspan28" />
-  </text>
-  <text
-     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#a52a2a"
-     x="6.938117"
-     y="152.05809"
-     id="text30">
-    <tspan
-       x="6.938117"
-       y="152.05809"
-       id="tspan32">sink media</tspan>
-    <tspan
-       x="6.938117"
-       y="168.05809"
-       id="tspan34">bus format</tspan>
-  </text>
-  <g
-     id="g36"
-     transform="translate(-1.6002426,-5.8559115)">
-    <rect
-       style="fill:#ffffff"
-       x="333.64401"
-       y="185.64999"
-       width="165.2"
-       height="172.478"
-       id="rect38" />
-    <rect
-       style="fill:none;fill-opacity:0;stroke:#00ff00;stroke-width:2"
-       x="333.64401"
-       y="185.64999"
-       width="165.2"
-       height="172.478"
-       id="rect40" />
-  </g>
-  <line
-     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
-     x1="332.04376"
-     y1="352.27206"
-     x2="47.899757"
-     y2="275.14407"
-     id="line42" />
-  <line
-     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
-     x1="332.04376"
-     y1="179.79408"
-     x2="47.899757"
-     y2="198.14409"
-     id="line44" />
-  <line
-     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
-     x1="497.24374"
-     y1="352.27206"
-     x2="141.89977"
-     y2="275.14407"
-     id="line46" />
-  <line
-     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
-     x1="497.24374"
-     y1="179.79408"
-     x2="141.89977"
-     y2="198.14409"
-     id="line48" />
-  <text
-     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#00ff00"
-     x="333.10376"
-     y="143.58609"
-     id="text50">
-    <tspan
-       x="333.10376"
-       y="143.58609"
-       id="tspan52">sink compose</tspan>
-    <tspan
-       x="333.10376"
-       y="159.58609"
-       id="tspan54">selection (scaling)</tspan>
-  </text>
-  <g
-     id="g56"
-     transform="translate(-1.6002426,-5.8559115)">
-    <rect
-       style="fill:#ffffff"
-       x="382.32199"
-       y="199.565"
-       width="100.186"
-       height="71.452301"
-       id="rect58" />
-    <rect
-       style="fill:none;fill-opacity:0;stroke:#a020f0;stroke-width:2"
-       x="382.32199"
-       y="199.565"
-       width="100.186"
-       height="71.452301"
-       id="rect60" />
-  </g>
-  <text
-     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#a020f0"
-     x="541.7218"
-     y="143.58609"
-     id="text62">
-    <tspan
-       x="541.7218"
-       y="143.58609"
-       id="tspan64">source</tspan>
-    <tspan
-       x="541.7218"
-       y="159.58609"
-       id="tspan66">crop</tspan>
-    <tspan
-       x="541.7218"
-       y="175.58609"
-       id="tspan68">selection</tspan>
-  </text>
-  <text
-     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#8b6914"
-     x="689.89978"
-     y="151.27209"
-     id="text70">
-    <tspan
-       x="689.89978"
-       y="151.27209"
-       id="tspan72">source media</tspan>
-    <tspan
-       x="689.89978"
-       y="167.27209"
-       id="tspan74">bus format</tspan>
-  </text>
-  <g
-     id="g76"
-     transform="translate(-1.6002426,-5.8559115)">
-    <rect
-       style="fill:#ffffff"
-       x="690.48798"
-       y="225.834"
-       width="100.186"
-       height="71.452301"
-       id="rect78" />
-    <rect
-       style="fill:none;fill-opacity:0;stroke:#8b6914;stroke-width:2"
-       x="690.48798"
-       y="225.834"
-       width="100.186"
-       height="71.452301"
-       id="rect80" />
-  </g>
-  <line
-     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
-     x1="688.88776"
-     y1="291.43008"
-     x2="380.72174"
-     y2="265.16208"
-     id="line82" />
-  <line
-     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
-     x1="688.88776"
-     y1="219.97809"
-     x2="380.72174"
-     y2="193.70909"
-     id="line84" />
-  <line
-     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
-     x1="789.07379"
-     y1="291.43008"
-     x2="480.90775"
-     y2="265.16208"
-     id="line86" />
-  <line
-     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
-     x1="789.07379"
-     y1="219.97809"
-     x2="480.90775"
-     y2="193.70909"
-     id="line88" />
-  <g
-     id="g90"
-     transform="translate(-1.6002426,-5.8559115)">
-    <circle
-       style="fill:#ffffff"
-       cx="808.09998"
-       cy="249.98399"
-       id="ellipse92"
-       r="8.5" />
-    <circle
-       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-       cx="808.09998"
-       cy="249.98399"
-       id="ellipse94"
-       r="8.5" />
-    <circle
-       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-       cx="808.09998"
-       cy="249.98399"
-       id="ellipse96"
-       r="8.5" />
-  </g>
-  <g
-     id="g98"
-     transform="translate(-1.6002426,-5.8559115)">
-    <line
-       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-       x1="816.59998"
-       y1="249.98399"
-       x2="972.93402"
-       y2="250.01199"
-       id="line100" />
-    <polygon
-       style="fill:#000000"
-       points="970.435,245.012 980.434,250.014 970.433,255.012 972.934,250.012 "
-       id="polygon102" />
-    <polygon
-       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-       points="970.435,245.012 980.434,250.014 970.433,255.012 972.934,250.012 "
-       id="polygon104" />
-  </g>
-  <text
-     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#000000"
-     x="840.3078"
-     y="233.94409"
-     id="text106">
-    <tspan
-       x="840.3078"
-       y="233.94409"
-       id="tspan108">pad 1 (source)</tspan>
-  </text>
-  <g
-     id="g110"
-     transform="translate(-1.6002426,-5.8559115)">
-    <circle
-       style="fill:#ffffff"
-       cx="-20.398199"
-       cy="241.51199"
-       id="ellipse112"
-       r="8.5" />
-    <circle
-       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-       cx="-20.398199"
-       cy="241.51199"
-       id="ellipse114"
-       r="8.5" />
-    <circle
-       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-       cx="-20.398199"
-       cy="241.51199"
-       id="ellipse116"
-       r="8.5" />
-  </g>
-  <g
-     id="g118"
-     transform="translate(-1.6002426,-5.8559115)">
-    <line
-       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-       x1="-192.39799"
-       y1="241.8"
-       x2="-38.6343"
-       y2="241.52901"
-       id="line120" />
-    <polygon
-       style="fill:#000000"
-       points="-41.1431,236.534 -31.1343,241.516 -41.1254,246.534 -38.6343,241.529 "
-       id="polygon122" />
-    <polygon
-       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-       points="-41.1431,236.534 -31.1343,241.516 -41.1254,246.534 -38.6343,241.529 "
-       id="polygon124" />
-  </g>
-  <text
-     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#000000"
-     x="-149.45824"
-     y="223.94409"
-     id="text126">
-    <tspan
-       x="-149.45824"
-       y="223.94409"
-       id="tspan128">pad 0 (sink)</tspan>
-  </text>
-  <rect
-     style="fill:none;fill-opacity:0;stroke:#a020f0;stroke-width:2"
-     x="388.22174"
-     y="270.81006"
-     width="100.186"
-     height="71.452301"
-     id="rect130" />
-  <g
-     id="g132"
-     transform="translate(-1.6002426,-5.8559115)">
-    <rect
-       style="fill:#ffffff"
-       x="689.98798"
-       y="345.93399"
-       width="100.186"
-       height="71.452301"
-       id="rect134" />
-    <rect
-       style="fill:none;fill-opacity:0;stroke:#8b6914;stroke-width:2"
-       x="689.98798"
-       y="345.93399"
-       width="100.186"
-       height="71.452301"
-       id="rect136" />
-  </g>
-  <line
-     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
-     x1="688.38776"
-     y1="411.53006"
-     x2="388.22174"
-     y2="342.26208"
-     id="line138" />
-  <line
-     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
-     x1="688.38776"
-     y1="340.07806"
-     x2="388.22174"
-     y2="270.81006"
-     id="line140" />
-  <line
-     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
-     x1="788.57379"
-     y1="411.53006"
-     x2="488.40775"
-     y2="342.26208"
-     id="line142" />
-  <line
-     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
-     x1="788.57379"
-     y1="340.07806"
-     x2="488.40775"
-     y2="270.81006"
-     id="line144" />
-  <g
-     id="g146"
-     transform="translate(-1.6002426,-5.8559115)">
-    <circle
-       style="fill:#ffffff"
-       cx="805.59998"
-       cy="384.08401"
-       id="ellipse148"
-       r="8.5" />
-    <circle
-       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-       cx="805.59998"
-       cy="384.08401"
-       id="ellipse150"
-       r="8.5" />
-    <circle
-       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-       cx="805.59998"
-       cy="384.08401"
-       id="ellipse152"
-       r="8.5" />
-  </g>
-  <g
-     id="g154"
-     transform="translate(-1.6002426,-5.8559115)">
-    <line
-       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-       x1="814.09998"
-       y1="384.08401"
-       x2="970.43402"
-       y2="384.112"
-       id="line156" />
-    <polygon
-       style="fill:#000000"
-       points="967.935,379.112 977.934,384.114 967.933,389.112 970.434,384.112 "
-       id="polygon158" />
-    <polygon
-       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
-       points="967.935,379.112 977.934,384.114 967.933,389.112 970.434,384.112 "
-       id="polygon160" />
-  </g>
-  <text
-     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#000000"
-     x="837.8078"
-     y="368.04407"
-     id="text162">
-    <tspan
-       x="837.8078"
-       y="368.04407"
-       id="tspan164">pad 2 (source)</tspan>
-  </text>
-  <g
-     id="g166"
-     transform="translate(-1.6002426,-5.8559115)">
-    <line
-       style="fill:none;fill-opacity:0;stroke:#a020f0;stroke-width:2"
-       x1="546"
-       y1="191"
-       x2="492.15701"
-       y2="198.263"
-       id="line168" />
-    <polygon
-       style="fill:#a020f0"
-       points="495.303,202.884 484.724,199.266 493.966,192.974 492.157,198.263 "
-       id="polygon170" />
-    <polygon
-       style="fill:none;fill-opacity:0;stroke:#a020f0;stroke-width:2"
-       points="495.303,202.884 484.724,199.266 493.966,192.974 492.157,198.263 "
-       id="polygon172" />
-  </g>
-  <g
-     id="g174"
-     transform="translate(-1.6002426,-5.8559115)">
-    <line
-       style="fill:none;fill-opacity:0;stroke:#a020f0;stroke-width:2"
-       x1="546.90802"
-       y1="190.72501"
-       x2="495.383"
-       y2="268.548"
-       id="line176" />
-    <polygon
-       style="fill:#a020f0"
-       points="500.932,269.224 491.242,274.802 492.594,263.703 495.383,268.548 "
-       id="polygon178" />
-    <polygon
-       style="fill:none;fill-opacity:0;stroke:#a020f0;stroke-width:2"
-       points="500.932,269.224 491.242,274.802 492.594,263.703 495.383,268.548 "
-       id="polygon180" />
-  </g>
-</svg>
diff --git a/Documentation/media/uapi/v4l/tch-formats.rst b/Documentation/media/uapi/v4l/tch-formats.rst
deleted file mode 100644
index 429c1010149d..000000000000
--- a/Documentation/media/uapi/v4l/tch-formats.rst
+++ /dev/null
@@ -1,25 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _tch-formats:
-
-*************
-Touch Formats
-*************
-
-These formats are used for :ref:`touch` interface only.
-
-
-.. toctree::
-    :maxdepth: 1
-
-    pixfmt-tch-td16
-    pixfmt-tch-td08
-    pixfmt-tch-tu16
-    pixfmt-tch-tu08
diff --git a/Documentation/media/uapi/v4l/tuner.rst b/Documentation/media/uapi/v4l/tuner.rst
deleted file mode 100644
index 601dc535199c..000000000000
--- a/Documentation/media/uapi/v4l/tuner.rst
+++ /dev/null
@@ -1,92 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _tuner:
-
-*********************
-Tuners and Modulators
-*********************
-
-
-Tuners
-======
-
-Video input devices can have one or more tuners demodulating a RF
-signal. Each tuner is associated with one or more video inputs,
-depending on the number of RF connectors on the tuner. The ``type``
-field of the respective struct :c:type:`v4l2_input`
-returned by the :ref:`VIDIOC_ENUMINPUT` ioctl is
-set to ``V4L2_INPUT_TYPE_TUNER`` and its ``tuner`` field contains the
-index number of the tuner.
-
-Radio input devices have exactly one tuner with index zero, no video
-inputs.
-
-To query and change tuner properties applications use the
-:ref:`VIDIOC_G_TUNER <VIDIOC_G_TUNER>` and
-:ref:`VIDIOC_S_TUNER <VIDIOC_G_TUNER>` ioctls, respectively. The
-struct :c:type:`v4l2_tuner` returned by :ref:`VIDIOC_G_TUNER <VIDIOC_G_TUNER>`
-also contains signal status information applicable when the tuner of the
-current video or radio input is queried.
-
-.. note::
-
-   :ref:`VIDIOC_S_TUNER <VIDIOC_G_TUNER>` does not switch the
-   current tuner, when there is more than one. The tuner is solely
-   determined by the current video input. Drivers must support both ioctls
-   and set the ``V4L2_CAP_TUNER`` flag in the struct :c:type:`v4l2_capability`
-   returned by the :ref:`VIDIOC_QUERYCAP` ioctl when the
-   device has one or more tuners.
-
-
-Modulators
-==========
-
-Video output devices can have one or more modulators, that modulate a
-video signal for radiation or connection to the antenna input of a TV
-set or video recorder. Each modulator is associated with one or more
-video outputs, depending on the number of RF connectors on the
-modulator. The ``type`` field of the respective struct
-:c:type:`v4l2_output` returned by the
-:ref:`VIDIOC_ENUMOUTPUT` ioctl is set to
-``V4L2_OUTPUT_TYPE_MODULATOR`` and its ``modulator`` field contains the
-index number of the modulator.
-
-Radio output devices have exactly one modulator with index zero, no
-video outputs.
-
-A video or radio device cannot support both a tuner and a modulator. Two
-separate device nodes will have to be used for such hardware, one that
-supports the tuner functionality and one that supports the modulator
-functionality. The reason is a limitation with the
-:ref:`VIDIOC_S_FREQUENCY <VIDIOC_G_FREQUENCY>` ioctl where you
-cannot specify whether the frequency is for a tuner or a modulator.
-
-To query and change modulator properties applications use the
-:ref:`VIDIOC_G_MODULATOR <VIDIOC_G_MODULATOR>` and
-:ref:`VIDIOC_S_MODULATOR <VIDIOC_G_MODULATOR>` ioctl. Note that
-:ref:`VIDIOC_S_MODULATOR <VIDIOC_G_MODULATOR>` does not switch the current modulator, when there
-is more than one at all. The modulator is solely determined by the
-current video output. Drivers must support both ioctls and set the
-``V4L2_CAP_MODULATOR`` flag in the struct
-:c:type:`v4l2_capability` returned by the
-:ref:`VIDIOC_QUERYCAP` ioctl when the device has
-one or more modulators.
-
-
-Radio Frequency
-===============
-
-To get and set the tuner or modulator radio frequency applications use
-the :ref:`VIDIOC_G_FREQUENCY <VIDIOC_G_FREQUENCY>` and
-:ref:`VIDIOC_S_FREQUENCY <VIDIOC_G_FREQUENCY>` ioctl which both take
-a pointer to a struct :c:type:`v4l2_frequency`. These
-ioctls are used for TV and radio devices alike. Drivers must support
-both ioctls when the tuner or modulator ioctls are supported, or when
-the device is a radio device.
diff --git a/Documentation/media/uapi/v4l/user-func.rst b/Documentation/media/uapi/v4l/user-func.rst
deleted file mode 100644
index ca0ef21d77fe..000000000000
--- a/Documentation/media/uapi/v4l/user-func.rst
+++ /dev/null
@@ -1,88 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _user-func:
-
-******************
-Function Reference
-******************
-
-
-.. toctree::
-    :maxdepth: 1
-
-    func-close
-    func-ioctl
-    vidioc-create-bufs
-    vidioc-cropcap
-    vidioc-dbg-g-chip-info
-    vidioc-dbg-g-register
-    vidioc-decoder-cmd
-    vidioc-dqevent
-    vidioc-dv-timings-cap
-    vidioc-encoder-cmd
-    vidioc-enumaudio
-    vidioc-enumaudioout
-    vidioc-enum-dv-timings
-    vidioc-enum-fmt
-    vidioc-enum-framesizes
-    vidioc-enum-frameintervals
-    vidioc-enum-freq-bands
-    vidioc-enuminput
-    vidioc-enumoutput
-    vidioc-enumstd
-    vidioc-expbuf
-    vidioc-g-audio
-    vidioc-g-audioout
-    vidioc-g-crop
-    vidioc-g-ctrl
-    vidioc-g-dv-timings
-    vidioc-g-edid
-    vidioc-g-enc-index
-    vidioc-g-ext-ctrls
-    vidioc-g-fbuf
-    vidioc-g-fmt
-    vidioc-g-frequency
-    vidioc-g-input
-    vidioc-g-jpegcomp
-    vidioc-g-modulator
-    vidioc-g-output
-    vidioc-g-parm
-    vidioc-g-priority
-    vidioc-g-selection
-    vidioc-g-sliced-vbi-cap
-    vidioc-g-std
-    vidioc-g-tuner
-    vidioc-log-status
-    vidioc-overlay
-    vidioc-prepare-buf
-    vidioc-qbuf
-    vidioc-querybuf
-    vidioc-querycap
-    vidioc-queryctrl
-    vidioc-query-dv-timings
-    vidioc-querystd
-    vidioc-reqbufs
-    vidioc-s-hw-freq-seek
-    vidioc-streamon
-    vidioc-subdev-enum-frame-interval
-    vidioc-subdev-enum-frame-size
-    vidioc-subdev-enum-mbus-code
-    vidioc-subdev-g-crop
-    vidioc-subdev-g-fmt
-    vidioc-subdev-g-frame-interval
-    vidioc-subdev-g-selection
-    vidioc-subscribe-event
-    func-mmap
-    func-munmap
-    func-open
-    func-poll
-    func-read
-    func-select
-    func-write
diff --git a/Documentation/media/uapi/v4l/userp.rst b/Documentation/media/uapi/v4l/userp.rst
deleted file mode 100644
index b19da8655452..000000000000
--- a/Documentation/media/uapi/v4l/userp.rst
+++ /dev/null
@@ -1,128 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _userp:
-
-*****************************
-Streaming I/O (User Pointers)
-*****************************
-
-Input and output devices support this I/O method when the
-``V4L2_CAP_STREAMING`` flag in the ``capabilities`` field of struct
-:c:type:`v4l2_capability` returned by the
-:ref:`VIDIOC_QUERYCAP` ioctl is set. If the
-particular user pointer method (not only memory mapping) is supported
-must be determined by calling the :ref:`VIDIOC_REQBUFS` ioctl
-with the memory type set to ``V4L2_MEMORY_USERPTR``.
-
-This I/O method combines advantages of the read/write and memory mapping
-methods. Buffers (planes) are allocated by the application itself, and
-can reside for example in virtual or shared memory. Only pointers to
-data are exchanged, these pointers and meta-information are passed in
-struct :c:type:`v4l2_buffer` (or in struct
-:c:type:`v4l2_plane` in the multi-planar API case). The
-driver must be switched into user pointer I/O mode by calling the
-:ref:`VIDIOC_REQBUFS` with the desired buffer type.
-No buffers (planes) are allocated beforehand, consequently they are not
-indexed and cannot be queried like mapped buffers with the
-:ref:`VIDIOC_QUERYBUF <VIDIOC_QUERYBUF>` ioctl.
-
-Example: Initiating streaming I/O with user pointers
-====================================================
-
-.. code-block:: c
-
-    struct v4l2_requestbuffers reqbuf;
-
-    memset (&reqbuf, 0, sizeof (reqbuf));
-    reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-    reqbuf.memory = V4L2_MEMORY_USERPTR;
-
-    if (ioctl (fd, VIDIOC_REQBUFS, &reqbuf) == -1) {
-	if (errno == EINVAL)
-	    printf ("Video capturing or user pointer streaming is not supported\\n");
-	else
-	    perror ("VIDIOC_REQBUFS");
-
-	exit (EXIT_FAILURE);
-    }
-
-Buffer (plane) addresses and sizes are passed on the fly with the
-:ref:`VIDIOC_QBUF <VIDIOC_QBUF>` ioctl. Although buffers are commonly
-cycled, applications can pass different addresses and sizes at each
-:ref:`VIDIOC_QBUF <VIDIOC_QBUF>` call. If required by the hardware the
-driver swaps memory pages within physical memory to create a continuous
-area of memory. This happens transparently to the application in the
-virtual memory subsystem of the kernel. When buffer pages have been
-swapped out to disk they are brought back and finally locked in physical
-memory for DMA. [#f1]_
-
-Filled or displayed buffers are dequeued with the
-:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl. The driver can unlock the
-memory pages at any time between the completion of the DMA and this
-ioctl. The memory is also unlocked when
-:ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` is called,
-:ref:`VIDIOC_REQBUFS`, or when the device is closed.
-Applications must take care not to free buffers without dequeuing.
-Firstly, the buffers remain locked for longer, wasting physical memory.
-Secondly the driver will not be notified when the memory is returned to
-the application's free list and subsequently reused for other purposes,
-possibly completing the requested DMA and overwriting valuable data.
-
-For capturing applications it is customary to enqueue a number of empty
-buffers, to start capturing and enter the read loop. Here the
-application waits until a filled buffer can be dequeued, and re-enqueues
-the buffer when the data is no longer needed. Output applications fill
-and enqueue buffers, when enough buffers are stacked up output is
-started. In the write loop, when the application runs out of free
-buffers it must wait until an empty buffer can be dequeued and reused.
-Two methods exist to suspend execution of the application until one or
-more buffers can be dequeued. By default :ref:`VIDIOC_DQBUF
-<VIDIOC_QBUF>` blocks when no buffer is in the outgoing queue. When the
-``O_NONBLOCK`` flag was given to the :ref:`open() <func-open>` function,
-:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` returns immediately with an ``EAGAIN``
-error code when no buffer is available. The :ref:`select()
-<func-select>` or :ref:`poll() <func-poll>` function are always
-available.
-
-To start and stop capturing or output applications call the
-:ref:`VIDIOC_STREAMON <VIDIOC_STREAMON>` and
-:ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` ioctl.
-
-.. note::
-
-   :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` removes all buffers from
-   both queues and unlocks all buffers as a side effect. Since there is no
-   notion of doing anything "now" on a multitasking system, if an
-   application needs to synchronize with another event it should examine
-   the struct :c:type:`v4l2_buffer` ``timestamp`` of captured or
-   outputted buffers.
-
-Drivers implementing user pointer I/O must support the
-:ref:`VIDIOC_REQBUFS <VIDIOC_REQBUFS>`, :ref:`VIDIOC_QBUF <VIDIOC_QBUF>`,
-:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>`, :ref:`VIDIOC_STREAMON <VIDIOC_STREAMON>`
-and :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` ioctls, the
-:ref:`select() <func-select>` and :ref:`poll() <func-poll>` function. [#f2]_
-
-.. [#f1]
-   We expect that frequently used buffers are typically not swapped out.
-   Anyway, the process of swapping, locking or generating scatter-gather
-   lists may be time consuming. The delay can be masked by the depth of
-   the incoming buffer queue, and perhaps by maintaining caches assuming
-   a buffer will be soon enqueued again. On the other hand, to optimize
-   memory usage drivers can limit the number of buffers locked in
-   advance and recycle the most recently used buffers first. Of course,
-   the pages of empty buffers in the incoming queue need not be saved to
-   disk. Output buffers must be saved on the incoming and outgoing queue
-   because an application may share them with other processes.
-
-.. [#f2]
-   At the driver level :ref:`select() <func-select>` and :ref:`poll() <func-poll>` are
-   the same, and :ref:`select() <func-select>` is too important to be optional.
-   The rest should be evident.
diff --git a/Documentation/media/uapi/v4l/v4l2-selection-flags.rst b/Documentation/media/uapi/v4l/v4l2-selection-flags.rst
deleted file mode 100644
index cc8f2a2b7cba..000000000000
--- a/Documentation/media/uapi/v4l/v4l2-selection-flags.rst
+++ /dev/null
@@ -1,51 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _v4l2-selection-flags:
-
-***************
-Selection flags
-***************
-
-.. tabularcolumns:: |p{5.2cm}|p{2.0cm}|p{6.5cm}|p{1.2cm}|p{1.6cm}|
-
-.. _v4l2-selection-flags-table:
-
-.. flat-table:: Selection flag definitions
-    :header-rows:  1
-    :stub-columns: 0
-
-    * - Flag name
-      - id
-      - Definition
-      - Valid for V4L2
-      - Valid for V4L2 subdev
-    * - ``V4L2_SEL_FLAG_GE``
-      - (1 << 0)
-      - Suggest the driver it should choose greater or equal rectangle (in
-	size) than was requested. Albeit the driver may choose a lesser
-	size, it will only do so due to hardware limitations. Without this
-	flag (and ``V4L2_SEL_FLAG_LE``) the behaviour is to choose the
-	closest possible rectangle.
-      - Yes
-      - Yes
-    * - ``V4L2_SEL_FLAG_LE``
-      - (1 << 1)
-      - Suggest the driver it should choose lesser or equal rectangle (in
-	size) than was requested. Albeit the driver may choose a greater
-	size, it will only do so due to hardware limitations.
-      - Yes
-      - Yes
-    * - ``V4L2_SEL_FLAG_KEEP_CONFIG``
-      - (1 << 2)
-      - The configuration must not be propagated to any further processing
-	steps. If this flag is not given, the configuration is propagated
-	inside the subdevice to all further processing steps.
-      - No
-      - Yes
diff --git a/Documentation/media/uapi/v4l/v4l2-selection-targets.rst b/Documentation/media/uapi/v4l/v4l2-selection-targets.rst
deleted file mode 100644
index aae0c0013eb1..000000000000
--- a/Documentation/media/uapi/v4l/v4l2-selection-targets.rst
+++ /dev/null
@@ -1,78 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _v4l2-selection-targets:
-
-*****************
-Selection targets
-*****************
-
-The precise meaning of the selection targets may be dependent on which
-of the two interfaces they are used.
-
-
-.. _v4l2-selection-targets-table:
-
-.. tabularcolumns:: |p{6.0cm}|p{1.4cm}|p{7.4cm}|p{1.2cm}|p{1.4cm}|
-
-.. flat-table:: Selection target definitions
-    :header-rows:  1
-    :stub-columns: 0
-
-    * - Target name
-      - id
-      - Definition
-      - Valid for V4L2
-      - Valid for V4L2 subdev
-    * - ``V4L2_SEL_TGT_CROP``
-      - 0x0000
-      - Crop rectangle. Defines the cropped area.
-      - Yes
-      - Yes
-    * - ``V4L2_SEL_TGT_CROP_DEFAULT``
-      - 0x0001
-      - Suggested cropping rectangle that covers the "whole picture".
-        This includes only active pixels and excludes other non-active
-        pixels such as black pixels.
-      - Yes
-      - Yes
-    * - ``V4L2_SEL_TGT_CROP_BOUNDS``
-      - 0x0002
-      - Bounds of the crop rectangle. All valid crop rectangles fit inside
-	the crop bounds rectangle.
-      - Yes
-      - Yes
-    * - ``V4L2_SEL_TGT_NATIVE_SIZE``
-      - 0x0003
-      - The native size of the device, e.g. a sensor's pixel array.
-	``left`` and ``top`` fields are zero for this target.
-      - Yes
-      - Yes
-    * - ``V4L2_SEL_TGT_COMPOSE``
-      - 0x0100
-      - Compose rectangle. Used to configure scaling and composition.
-      - Yes
-      - Yes
-    * - ``V4L2_SEL_TGT_COMPOSE_DEFAULT``
-      - 0x0101
-      - Suggested composition rectangle that covers the "whole picture".
-      - Yes
-      - No
-    * - ``V4L2_SEL_TGT_COMPOSE_BOUNDS``
-      - 0x0102
-      - Bounds of the compose rectangle. All valid compose rectangles fit
-	inside the compose bounds rectangle.
-      - Yes
-      - Yes
-    * - ``V4L2_SEL_TGT_COMPOSE_PADDED``
-      - 0x0103
-      - The active area and all padding pixels that are inserted or
-	modified by hardware.
-      - Yes
-      - No
diff --git a/Documentation/media/uapi/v4l/v4l2.rst b/Documentation/media/uapi/v4l/v4l2.rst
deleted file mode 100644
index 97015b9b40b8..000000000000
--- a/Documentation/media/uapi/v4l/v4l2.rst
+++ /dev/null
@@ -1,423 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. include:: <isonum.txt>
-.. _v4l2spec:
-
-############################
-Part I - Video for Linux API
-############################
-
-This part describes the Video for Linux API version 2 (V4L2 API) specification.
-
-**Revision 4.5**
-
-.. only:: html
-
-   .. class:: toc-title
-
-        Table of Contents
-
-.. toctree::
-    :numbered:
-    :maxdepth: 5
-
-    common
-    pixfmt
-    io
-    devices
-    libv4l
-    compat
-    user-func
-    common-defs
-    videodev
-    capture-example
-    v4l2grab-example
-    biblio
-
-
-**********************
-Revision and Copyright
-**********************
-
-Authors, in alphabetical order:
-
-- Ailus, Sakari <sakari.ailus@iki.fi>
-
-  - Subdev selections API.
-
-- Carvalho Chehab, Mauro <mchehab+samsung@kernel.org>
-
-  - Documented libv4l, designed and added v4l2grab example, Remote Controller chapter.
-
-- Dirks, Bill
-
-  - Original author of the V4L2 API and documentation.
-
-- Figa, Tomasz <tfiga@chromium.org>
-
-  - Documented the memory-to-memory decoder interface.
-
-- H Schimek, Michael <mschimek@gmx.at>
-
-  - Original author of the V4L2 API and documentation.
-
-- Karicheri, Muralidharan <m-karicheri2@ti.com>
-
-  - Documented the Digital Video timings API.
-
-- Osciak, Pawel <posciak@chromium.org>
-
-  - Documented the memory-to-memory decoder interface.
-
-- Osciak, Pawel <pawel@osciak.com>
-
-  - Designed and documented the multi-planar API.
-
-- Palosaari, Antti <crope@iki.fi>
-
-  - SDR API.
-
-- Ribalda, Ricardo
-
-  - Introduce HSV formats and other minor changes.
-
-- Rubli, Martin
-
-  - Designed and documented the VIDIOC_ENUM_FRAMESIZES and VIDIOC_ENUM_FRAMEINTERVALS ioctls.
-
-- Walls, Andy <awalls@md.metrocast.net>
-
-  - Documented the fielded V4L2_MPEG_STREAM_VBI_FMT_IVTV MPEG stream embedded, sliced VBI data format in this specification.
-
-- Verkuil, Hans <hverkuil@xs4all.nl>
-
-  - Designed and documented the VIDIOC_LOG_STATUS ioctl, the extended control ioctls, major parts of the sliced VBI API, the MPEG encoder and decoder APIs and the DV Timings API.
-
-**Copyright** |copy| 1999-2018: Bill Dirks, Michael H. Schimek, Hans Verkuil, Martin Rubli, Andy Walls, Muralidharan Karicheri, Mauro Carvalho Chehab, Pawel Osciak, Sakari Ailus & Antti Palosaari, Tomasz Figa
-
-Except when explicitly stated as GPL, programming examples within this
-part can be used and distributed without restrictions.
-
-****************
-Revision History
-****************
-
-:revision: 4.10 / 2016-07-15 (*rr*)
-
-Introduce HSV formats.
-
-
-:revision: 4.5 / 2015-10-29 (*rr*)
-
-Extend VIDIOC_G_EXT_CTRLS;. Replace ctrl_class with a new union with
-ctrl_class and which. Which is used to select the current value of the
-control or the default value.
-
-
-:revision: 4.4 / 2015-05-26 (*ap*)
-
-Renamed V4L2_TUNER_ADC to V4L2_TUNER_SDR. Added
-V4L2_CID_RF_TUNER_RF_GAIN control. Added transmitter support for
-Software Defined Radio (SDR) Interface.
-
-
-:revision: 4.1 / 2015-02-13 (*mcc*)
-
-Fix documentation for media controller device nodes and add support for
-DVB device nodes. Add support for Tuner sub-device.
-
-
-:revision: 3.19 / 2014-12-05 (*hv*)
-
-Rewrote Colorspace chapter, added new enum
-:c:type:`v4l2_ycbcr_encoding` and enum
-:c:type:`v4l2_quantization` fields to struct
-:c:type:`v4l2_pix_format`, struct
-:c:type:`v4l2_pix_format_mplane` and struct
-:c:type:`v4l2_mbus_framefmt`.
-
-
-:revision: 3.17 / 2014-08-04 (*lp, hv*)
-
-Extended struct :c:type:`v4l2_pix_format`. Added
-format flags. Added compound control types and VIDIOC_QUERY_EXT_CTRL.
-
-
-:revision: 3.15 / 2014-02-03 (*hv, ap*)
-
-Update several sections of "Common API Elements": "Opening and Closing
-Devices" "Querying Capabilities", "Application Priority", "Video Inputs
-and Outputs", "Audio Inputs and Outputs" "Tuners and Modulators", "Video
-Standards" and "Digital Video (DV) Timings". Added SDR API.
-
-
-:revision: 3.14 / 2013-11-25 (*rr*)
-
-Set width and height as unsigned on v4l2_rect.
-
-
-:revision: 3.11 / 2013-05-26 (*hv*)
-
-Remove obsolete VIDIOC_DBG_G_CHIP_IDENT ioctl.
-
-
-:revision: 3.10 / 2013-03-25 (*hv*)
-
-Remove obsolete and unused DV_PRESET ioctls: VIDIOC_G_DV_PRESET,
-VIDIOC_S_DV_PRESET, VIDIOC_QUERY_DV_PRESET and
-VIDIOC_ENUM_DV_PRESET. Remove the related v4l2_input/output
-capability flags V4L2_IN_CAP_PRESETS and V4L2_OUT_CAP_PRESETS.
-Added VIDIOC_DBG_G_CHIP_INFO.
-
-
-:revision: 3.9 / 2012-12-03 (*sa, sn*)
-
-Added timestamp types to v4l2_buffer. Added
-V4L2_EVENT_CTRL_CH_RANGE control event changes flag.
-
-
-:revision: 3.6 / 2012-07-02 (*hv*)
-
-Added VIDIOC_ENUM_FREQ_BANDS.
-
-
-:revision: 3.5 / 2012-05-07 (*sa, sn, hv*)
-
-Added V4L2_CTRL_TYPE_INTEGER_MENU and V4L2 subdev selections API.
-Improved the description of V4L2_CID_COLORFX control, added
-V4L2_CID_COLORFX_CBCR control. Added camera controls
-V4L2_CID_AUTO_EXPOSURE_BIAS,
-V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE,
-V4L2_CID_IMAGE_STABILIZATION, V4L2_CID_ISO_SENSITIVITY,
-V4L2_CID_ISO_SENSITIVITY_AUTO, V4L2_CID_EXPOSURE_METERING,
-V4L2_CID_SCENE_MODE, V4L2_CID_3A_LOCK,
-V4L2_CID_AUTO_FOCUS_START, V4L2_CID_AUTO_FOCUS_STOP,
-V4L2_CID_AUTO_FOCUS_STATUS and V4L2_CID_AUTO_FOCUS_RANGE. Added
-VIDIOC_ENUM_DV_TIMINGS, VIDIOC_QUERY_DV_TIMINGS and
-VIDIOC_DV_TIMINGS_CAP.
-
-
-:revision: 3.4 / 2012-01-25 (*sn*)
-
-Added :ref:`JPEG compression control class. <jpeg-controls>`
-
-
-:revision: 3.3 / 2012-01-11 (*hv*)
-
-Added device_caps field to struct v4l2_capabilities.
-
-
-:revision: 3.2 / 2011-08-26 (*hv*)
-
-Added V4L2_CTRL_FLAG_VOLATILE.
-
-
-:revision: 3.1 / 2011-06-27 (*mcc, po, hv*)
-
-Documented that VIDIOC_QUERYCAP now returns a per-subsystem version
-instead of a per-driver one. Standardize an error code for invalid
-ioctl. Added V4L2_CTRL_TYPE_BITMASK.
-
-
-:revision: 2.6.39 / 2011-03-01 (*mcc, po*)
-
-Removed VIDIOC_*_OLD from videodev2.h header and update it to reflect
-latest changes. Added the :ref:`multi-planar API <planar-apis>`.
-
-
-:revision: 2.6.37 / 2010-08-06 (*hv*)
-
-Removed obsolete vtx (videotext) API.
-
-
-:revision: 2.6.33 / 2009-12-03 (*mk*)
-
-Added documentation for the Digital Video timings API.
-
-
-:revision: 2.6.32 / 2009-08-31 (*mcc*)
-
-Now, revisions will match the kernel version where the V4L2 API changes
-will be used by the Linux Kernel. Also added Remote Controller chapter.
-
-
-:revision: 0.29 / 2009-08-26 (*ev*)
-
-Added documentation for string controls and for FM Transmitter controls.
-
-
-:revision: 0.28 / 2009-08-26 (*gl*)
-
-Added V4L2_CID_BAND_STOP_FILTER documentation.
-
-
-:revision: 0.27 / 2009-08-15 (*mcc*)
-
-Added libv4l and Remote Controller documentation; added v4l2grab and
-keytable application examples.
-
-
-:revision: 0.26 / 2009-07-23 (*hv*)
-
-Finalized the RDS capture API. Added modulator and RDS encoder
-capabilities. Added support for string controls.
-
-
-:revision: 0.25 / 2009-01-18 (*hv*)
-
-Added pixel formats VYUY, NV16 and NV61, and changed the debug ioctls
-VIDIOC_DBG_G/S_REGISTER and VIDIOC_DBG_G_CHIP_IDENT. Added camera
-controls V4L2_CID_ZOOM_ABSOLUTE, V4L2_CID_ZOOM_RELATIVE,
-V4L2_CID_ZOOM_CONTINUOUS and V4L2_CID_PRIVACY.
-
-
-:revision: 0.24 / 2008-03-04 (*mhs*)
-
-Added pixel formats Y16 and SBGGR16, new controls and a camera controls
-class. Removed VIDIOC_G/S_MPEGCOMP.
-
-
-:revision: 0.23 / 2007-08-30 (*mhs*)
-
-Fixed a typo in VIDIOC_DBG_G/S_REGISTER. Clarified the byte order of
-packed pixel formats.
-
-
-:revision: 0.22 / 2007-08-29 (*mhs*)
-
-Added the Video Output Overlay interface, new MPEG controls,
-V4L2_FIELD_INTERLACED_TB and V4L2_FIELD_INTERLACED_BT,
-VIDIOC_DBG_G/S_REGISTER, VIDIOC\_(TRY\_)ENCODER_CMD,
-VIDIOC_G_CHIP_IDENT, VIDIOC_G_ENC_INDEX, new pixel formats.
-Clarifications in the cropping chapter, about RGB pixel formats, the
-mmap(), poll(), select(), read() and write() functions. Typographical
-fixes.
-
-
-:revision: 0.21 / 2006-12-19 (*mhs*)
-
-Fixed a link in the VIDIOC_G_EXT_CTRLS section.
-
-
-:revision: 0.20 / 2006-11-24 (*mhs*)
-
-Clarified the purpose of the audioset field in struct v4l2_input and
-v4l2_output.
-
-
-:revision: 0.19 / 2006-10-19 (*mhs*)
-
-Documented V4L2_PIX_FMT_RGB444.
-
-
-:revision: 0.18 / 2006-10-18 (*mhs*)
-
-Added the description of extended controls by Hans Verkuil. Linked
-V4L2_PIX_FMT_MPEG to V4L2_CID_MPEG_STREAM_TYPE.
-
-
-:revision: 0.17 / 2006-10-12 (*mhs*)
-
-Corrected V4L2_PIX_FMT_HM12 description.
-
-
-:revision: 0.16 / 2006-10-08 (*mhs*)
-
-VIDIOC_ENUM_FRAMESIZES and VIDIOC_ENUM_FRAMEINTERVALS are now part
-of the API.
-
-
-:revision: 0.15 / 2006-09-23 (*mhs*)
-
-Cleaned up the bibliography, added BT.653 and BT.1119.
-capture.c/start_capturing() for user pointer I/O did not initialize the
-buffer index. Documented the V4L MPEG and MJPEG VID_TYPEs and
-V4L2_PIX_FMT_SBGGR8. Updated the list of reserved pixel formats. See
-the history chapter for API changes.
-
-
-:revision: 0.14 / 2006-09-14 (*mr*)
-
-Added VIDIOC_ENUM_FRAMESIZES and VIDIOC_ENUM_FRAMEINTERVALS proposal
-for frame format enumeration of digital devices.
-
-
-:revision: 0.13 / 2006-04-07 (*mhs*)
-
-Corrected the description of struct v4l2_window clips. New V4L2_STD\_
-and V4L2_TUNER_MODE_LANG1_LANG2 defines.
-
-
-:revision: 0.12 / 2006-02-03 (*mhs*)
-
-Corrected the description of struct v4l2_captureparm and
-v4l2_outputparm.
-
-
-:revision: 0.11 / 2006-01-27 (*mhs*)
-
-Improved the description of struct v4l2_tuner.
-
-
-:revision: 0.10 / 2006-01-10 (*mhs*)
-
-VIDIOC_G_INPUT and VIDIOC_S_PARM clarifications.
-
-
-:revision: 0.9 / 2005-11-27 (*mhs*)
-
-Improved the 525 line numbering diagram. Hans Verkuil and I rewrote the
-sliced VBI section. He also contributed a VIDIOC_LOG_STATUS page.
-Fixed VIDIOC_S_STD call in the video standard selection example.
-Various updates.
-
-
-:revision: 0.8 / 2004-10-04 (*mhs*)
-
-Somehow a piece of junk slipped into the capture example, removed.
-
-
-:revision: 0.7 / 2004-09-19 (*mhs*)
-
-Fixed video standard selection, control enumeration, downscaling and
-aspect example. Added read and user pointer i/o to video capture
-example.
-
-
-:revision: 0.6 / 2004-08-01 (*mhs*)
-
-v4l2_buffer changes, added video capture example, various corrections.
-
-
-:revision: 0.5 / 2003-11-05 (*mhs*)
-
-Pixel format erratum.
-
-
-:revision: 0.4 / 2003-09-17 (*mhs*)
-
-Corrected source and Makefile to generate a PDF. SGML fixes. Added
-latest API changes. Closed gaps in the history chapter.
-
-
-:revision: 0.3 / 2003-02-05 (*mhs*)
-
-Another draft, more corrections.
-
-
-:revision: 0.2 / 2003-01-15 (*mhs*)
-
-Second draft, with corrections pointed out by Gerd Knorr.
-
-
-:revision: 0.1 / 2002-12-01 (*mhs*)
-
-First draft, based on documentation by Bill Dirks and discussions on the
-V4L mailing list.
diff --git a/Documentation/media/uapi/v4l/v4l2grab-example.rst b/Documentation/media/uapi/v4l/v4l2grab-example.rst
deleted file mode 100644
index 2a0cfd4429c1..000000000000
--- a/Documentation/media/uapi/v4l/v4l2grab-example.rst
+++ /dev/null
@@ -1,24 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _v4l2grab-example:
-
-**********************************
-Video Grabber example using libv4l
-**********************************
-
-This program demonstrates how to grab V4L2 images in ppm format by using
-libv4l handlers. The advantage is that this grabber can potentially work
-with any V4L2 driver.
-
-
-.. toctree::
-    :maxdepth: 1
-
-    v4l2grab.c
diff --git a/Documentation/media/uapi/v4l/v4l2grab.c.rst b/Documentation/media/uapi/v4l/v4l2grab.c.rst
deleted file mode 100644
index e76c5fb7bd19..000000000000
--- a/Documentation/media/uapi/v4l/v4l2grab.c.rst
+++ /dev/null
@@ -1,176 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-file: media/v4l/v4l2grab.c
-==========================
-
-.. code-block:: c
-
-    /* V4L2 video picture grabber
-       Copyright (C) 2009 Mauro Carvalho Chehab <mchehab@kernel.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 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 <stdio.h>
-    #include <stdlib.h>
-    #include <string.h>
-    #include <fcntl.h>
-    #include <errno.h>
-    #include <sys/ioctl.h>
-    #include <sys/types.h>
-    #include <sys/time.h>
-    #include <sys/mman.h>
-    #include <linux/videodev2.h>
-    #include "../libv4l/include/libv4l2.h"
-
-    #define CLEAR(x) memset(&(x), 0, sizeof(x))
-
-    struct buffer {
-	    void   *start;
-	    size_t length;
-    };
-
-    static void xioctl(int fh, int request, void *arg)
-    {
-	    int r;
-
-	    do {
-		    r = v4l2_ioctl(fh, request, arg);
-	    } while (r == -1 && ((errno == EINTR) || (errno == EAGAIN)));
-
-	    if (r == -1) {
-		    fprintf(stderr, "error %d, %s\\n", errno, strerror(errno));
-		    exit(EXIT_FAILURE);
-	    }
-    }
-
-    int main(int argc, char **argv)
-    {
-	    struct v4l2_format              fmt;
-	    struct v4l2_buffer              buf;
-	    struct v4l2_requestbuffers      req;
-	    enum v4l2_buf_type              type;
-	    fd_set                          fds;
-	    struct timeval                  tv;
-	    int                             r, fd = -1;
-	    unsigned int                    i, n_buffers;
-	    char                            *dev_name = "/dev/video0";
-	    char                            out_name[256];
-	    FILE                            *fout;
-	    struct buffer                   *buffers;
-
-	    fd = v4l2_open(dev_name, O_RDWR | O_NONBLOCK, 0);
-	    if (fd < 0) {
-		    perror("Cannot open device");
-		    exit(EXIT_FAILURE);
-	    }
-
-	    CLEAR(fmt);
-	    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	    fmt.fmt.pix.width       = 640;
-	    fmt.fmt.pix.height      = 480;
-	    fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24;
-	    fmt.fmt.pix.field       = V4L2_FIELD_INTERLACED;
-	    xioctl(fd, VIDIOC_S_FMT, &fmt);
-	    if (fmt.fmt.pix.pixelformat != V4L2_PIX_FMT_RGB24) {
-		    printf("Libv4l didn't accept RGB24 format. Can't proceed.\\n");
-		    exit(EXIT_FAILURE);
-	    }
-	    if ((fmt.fmt.pix.width != 640) || (fmt.fmt.pix.height != 480))
-		    printf("Warning: driver is sending image at %dx%d\\n",
-			    fmt.fmt.pix.width, fmt.fmt.pix.height);
-
-	    CLEAR(req);
-	    req.count = 2;
-	    req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	    req.memory = V4L2_MEMORY_MMAP;
-	    xioctl(fd, VIDIOC_REQBUFS, &req);
-
-	    buffers = calloc(req.count, sizeof(*buffers));
-	    for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {
-		    CLEAR(buf);
-
-		    buf.type        = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-		    buf.memory      = V4L2_MEMORY_MMAP;
-		    buf.index       = n_buffers;
-
-		    xioctl(fd, VIDIOC_QUERYBUF, &buf);
-
-		    buffers[n_buffers].length = buf.length;
-		    buffers[n_buffers].start = v4l2_mmap(NULL, buf.length,
-				  PROT_READ | PROT_WRITE, MAP_SHARED,
-				  fd, buf.m.offset);
-
-		    if (MAP_FAILED == buffers[n_buffers].start) {
-			    perror("mmap");
-			    exit(EXIT_FAILURE);
-		    }
-	    }
-
-	    for (i = 0; i < n_buffers; ++i) {
-		    CLEAR(buf);
-		    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-		    buf.memory = V4L2_MEMORY_MMAP;
-		    buf.index = i;
-		    xioctl(fd, VIDIOC_QBUF, &buf);
-	    }
-	    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
-	    xioctl(fd, VIDIOC_STREAMON, &type);
-	    for (i = 0; i < 20; i++) {
-		    do {
-			    FD_ZERO(&fds);
-			    FD_SET(fd, &fds);
-
-			    /* Timeout. */
-			    tv.tv_sec = 2;
-			    tv.tv_usec = 0;
-
-			    r = select(fd + 1, &fds, NULL, NULL, &tv);
-		    } while ((r == -1 && (errno = EINTR)));
-		    if (r == -1) {
-			    perror("select");
-			    return errno;
-		    }
-
-		    CLEAR(buf);
-		    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-		    buf.memory = V4L2_MEMORY_MMAP;
-		    xioctl(fd, VIDIOC_DQBUF, &buf);
-
-		    sprintf(out_name, "out%03d.ppm", i);
-		    fout = fopen(out_name, "w");
-		    if (!fout) {
-			    perror("Cannot open image");
-			    exit(EXIT_FAILURE);
-		    }
-		    fprintf(fout, "P6\\n%d %d 255\\n",
-			    fmt.fmt.pix.width, fmt.fmt.pix.height);
-		    fwrite(buffers[buf.index].start, buf.bytesused, 1, fout);
-		    fclose(fout);
-
-		    xioctl(fd, VIDIOC_QBUF, &buf);
-	    }
-
-	    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	    xioctl(fd, VIDIOC_STREAMOFF, &type);
-	    for (i = 0; i < n_buffers; ++i)
-		    v4l2_munmap(buffers[i].start, buffers[i].length);
-	    v4l2_close(fd);
-
-	    return 0;
-    }
diff --git a/Documentation/media/uapi/v4l/vbi_525.svg b/Documentation/media/uapi/v4l/vbi_525.svg
deleted file mode 100644
index 6cd5def22b1f..000000000000
--- a/Documentation/media/uapi/v4l/vbi_525.svg
+++ /dev/null
@@ -1,821 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!--
-    Permission is granted to copy, distribute and/or modify this
-    document under the terms of the GNU Free Documentation License,
-    Version 1.1 or any later version published by the Free Software
-    Foundation, with no Invariant Sections, no Front-Cover Texts
-    and no Back-Cover Texts. A copy of the license is included at
-    Documentation/media/uapi/fdl-appendix.rst.
-
-    TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
--->
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   id="svg2"
-   version="1.1"
-   inkscape:version="0.91 r13725"
-   xml:space="preserve"
-   width="208.73068mm"
-   height="51.395489mm"
-   viewBox="0 0 739.59691 182.11"
-   sodipodi:docname="vbi_525.svg"><sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="1920"
-     inkscape:window-height="997"
-     id="namedview4"
-     showgrid="false"
-     fit-margin-top="0"
-     fit-margin-left="0"
-     fit-margin-right="0"
-     fit-margin-bottom="0"
-     inkscape:zoom="1.5350601"
-     inkscape:cx="264.23387"
-     inkscape:cy="44.916942"
-     inkscape:window-x="1920"
-     inkscape:window-y="30"
-     inkscape:window-maximized="1"
-     inkscape:current-layer="g10"
-     units="mm" /><metadata
-     id="metadata8"><rdf:RDF><cc:Work
-	 rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
-	   rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
-     id="defs6"><clipPath
-       id="clipPath20"
-       clipPathUnits="userSpaceOnUse"><path
-	 inkscape:connector-curvature="0"
-	 id="path22"
-	 d="m 0,0 5950,0 0,3922 L 0,3922 0,0 Z m 0,3922 5950,0 0,1 -5950,0 0,-1 z m 0,1 1359,0 0,1 -1359,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1363,0 0,1 -1363,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1367,0 0,1 -1367,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1371,0 0,1 -1371,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1375,0 0,1 -1375,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1379,0 0,1 -1379,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1383,0 0,1 -1383,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1387,0 0,1 -1387,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1391,0 0,1 -1391,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1390,0 0,1 -1390,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1386,0 0,1 -1386,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1382,0 0,1 -1382,0 0,-1 z m
-1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1378,0 0,1 -1378,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1374,0 0,1 -1374,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1370,0 0,1 -1370,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1366,0 0,1 -1366,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1362,0 0,1 -1362,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1358,0 0,1 -1358,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 5950,0 0,1 -5950,0 0,-1 z m 0,1 5950,0 0,4478 -5950,0 0,-4478 z" /></clipPath><clipPath
-       id="clipPath98"
-       clipPathUnits="userSpaceOnUse"><path
-	 inkscape:connector-curvature="0"
-	 id="path100"
-	 d="m 0,0 5950,0 0,4546 L 0,4546 0,0 Z m 0,4546 5950,0 0,1 -5950,0 0,-1 z m 0,1 1360,0 0,1 -1360,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1364,0 0,1 -1364,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1368,0 0,1 -1368,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1372,0 0,1 -1372,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1376,0 0,1 -1376,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1380,0 0,1 -1380,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1384,0 0,1 -1384,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1388,0 0,1 -1388,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1391,0 0,1 -1391,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1389,0 0,1 -1389,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1385,0 0,1 -1385,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1381,0 0,1 -1381,0 0,-1 z m
-1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1377,0 0,1 -1377,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1373,0 0,1 -1373,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1369,0 0,1 -1369,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1365,0 0,1 -1365,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1361,0 0,1 -1361,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1357,0 0,1 -1357,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 5950,0 0,1 -5950,0 0,-1 z m 0,1 5950,0 0,3854 -5950,0 0,-3854 z" /></clipPath></defs><g
-     transform="matrix(0.125,0,0,-0.125,-87.571875,638.05691)"
-     inkscape:label="vbi_525"
-     inkscape:groupmode="layer"
-     id="g10"><g
-       transform="matrix(1.3000026,0,0,1.3000026,-210.17435,-1094.2823)"
-       id="g12"
-       style=""><path
-	 inkscape:connector-curvature="0"
-	 id="path14"
-	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 1281.75,3974.45 0,-85.05" /></g><g
-       transform="matrix(1.3000026,0,0,1.3000026,-210.17435,-1094.2823)"
-       id="g16"
-       style=""><g
-	 clip-path="url(#clipPath20)"
-	 id="g18"
-	 style=""><path
-	   inkscape:connector-curvature="0"
-	   id="path24"
-	   style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	   d="m 1281.75,3931.93 113.4,0" /></g></g><g
-       transform="matrix(1.3000026,0,0,1.3000026,-210.17435,-1094.2823)"
-       id="g26"
-       style=""><path
-	 inkscape:connector-curvature="0"
-	 id="path28"
-	 style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-	 d="m 1352.31,3922.48 37.8,9.45 -37.8,9.45 0,-18.9" /><path
-	 inkscape:connector-curvature="0"
-	 id="path30"
-	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 1352.31,3922.48 37.8,9.45 -37.8,9.45 0,-18.9 z" /><path
-	 inkscape:connector-curvature="0"
-	 id="path32"
-	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 4683.75,4059.5 0,-56.7" /><path
-	 inkscape:connector-curvature="0"
-	 id="path34"
-	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 4400.25,4059.5 0,-56.7" /><path
-	 inkscape:connector-curvature="0"
-	 id="path36"
-	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 4116.75,4059.5 0,-56.7" /><path
-	 inkscape:connector-curvature="0"
-	 id="path38"
-	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 3833.25,4059.5 0,-56.7" /><path
-	 inkscape:connector-curvature="0"
-	 id="path40"
-	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 3549.75,4059.5 0,-56.7" /><path
-	 inkscape:connector-curvature="0"
-	 id="path42"
-	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 3266.25,4059.5 0,-56.7" /><path
-	 inkscape:connector-curvature="0"
-	 id="path44"
-	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 2982.75,4059.5 0,-56.7" /><path
-	 inkscape:connector-curvature="0"
-	 id="path46"
-	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 2699.25,4059.5 0,-56.7" /><path
-	 inkscape:connector-curvature="0"
-	 id="path48"
-	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 2415.75,4059.5 0,-56.7" /><path
-	 inkscape:connector-curvature="0"
-	 id="path50"
-	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 2132.25,4059.5 0,-56.7" /><path
-	 inkscape:connector-curvature="0"
-	 id="path52"
-	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 1848.75,4059.5 0,-56.7" /><path
-	 inkscape:connector-curvature="0"
-	 id="path54"
-	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 1565.25,4059.5 0,-56.7" /><path
-	 inkscape:connector-curvature="0"
-	 id="path56"
-	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 1281.75,4059.5 0,-56.7" /><path
-	 inkscape:connector-curvature="0"
-	 id="path58"
-	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 998.25,4059.5 0,-56.7" /><path
-	 inkscape:connector-curvature="0"
-	 id="path60"
-	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 714.75,4059.5 0,-56.7" /><path
-	 inkscape:connector-curvature="0"
-	 id="path62"
-	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 4683.75,4144.55 0,-56.7" /><path
-	 inkscape:connector-curvature="0"
-	 id="path64"
-	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 4400.25,4144.55 0,-56.7" /><path
-	 inkscape:connector-curvature="0"
-	 id="path66"
-	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 4116.75,4144.55 0,-56.7" /><path
-	 inkscape:connector-curvature="0"
-	 id="path68"
-	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 3833.25,4144.55 0,-56.7" /><path
-	 inkscape:connector-curvature="0"
-	 id="path70"
-	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 3549.75,4144.55 0,-56.7" /><path
-	 inkscape:connector-curvature="0"
-	 id="path72"
-	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 3266.25,4144.55 0,-56.7" /><path
-	 inkscape:connector-curvature="0"
-	 id="path74"
-	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 2982.75,4144.55 0,-56.7" /><path
-	 inkscape:connector-curvature="0"
-	 id="path76"
-	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 2699.25,4144.55 0,-56.7" /><path
-	 inkscape:connector-curvature="0"
-	 id="path78"
-	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 2415.75,4144.55 0,-56.7" /><path
-	 inkscape:connector-curvature="0"
-	 id="path80"
-	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 2132.25,4144.55 0,-56.7" /><path
-	 inkscape:connector-curvature="0"
-	 id="path82"
-	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 1848.75,4144.55 0,-56.7" /><path
-	 inkscape:connector-curvature="0"
-	 id="path84"
-	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 1565.25,4144.55 0,-56.7" /><path
-	 inkscape:connector-curvature="0"
-	 id="path86"
-	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 1281.75,4144.55 0,-56.7" /><path
-	 inkscape:connector-curvature="0"
-	 id="path88"
-	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 998.25,4144.55 0,-56.7" /><path
-	 inkscape:connector-curvature="0"
-	 id="path90"
-	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 714.75,4144.55 0,-56.7" /><path
-	 inkscape:connector-curvature="0"
-	 id="path92"
-	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 1281.75,4598.15 0,-85.05" /></g><g
-       transform="matrix(1.3000026,0,0,1.3000026,-210.17435,-1094.2823)"
-       id="g94"
-       style=""><g
-	 clip-path="url(#clipPath98)"
-	 id="g96"
-	 style=""><path
-	   inkscape:connector-curvature="0"
-	   id="path102"
-	   style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	   d="m 1281.75,4555.63 113.4,0" /></g></g><path
-       d="m 1547.8322,4815.7637 49.1401,12.2851 -49.1401,12.285 0,-24.5701"
-       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path106"
-       inkscape:connector-curvature="0" /><path
-       d="m 1547.8322,4815.7637 49.1401,12.2851 -49.1401,12.285 0,-24.5701 z"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path108"
-       inkscape:connector-curvature="0" /><path
-       d="m 1456.104,5104.4553 0,-73.7101"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path110"
-       inkscape:connector-curvature="0" /><path
-       d="m 1824.6548,5030.7452 0,73.7101"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path112"
-       inkscape:connector-curvature="0" /><path
-       d="m 2193.2055,5104.4553 0,-73.7101"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path114"
-       inkscape:connector-curvature="0" /><path
-       d="m 2561.7563,5104.4553 0,-73.7101"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path116"
-       inkscape:connector-curvature="0" /><path
-       d="m 2930.307,5104.4553 0,-73.7101"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path118"
-       inkscape:connector-curvature="0" /><path
-       d="m 3298.8578,5104.4553 0,-73.7101"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path120"
-       inkscape:connector-curvature="0" /><path
-       d="m 3667.4085,5104.4553 0,-73.7101"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path122"
-       inkscape:connector-curvature="0" /><path
-       d="m 4035.9593,5104.4553 0,-73.7101"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path124"
-       inkscape:connector-curvature="0" /><path
-       d="m 4404.51,5104.4553 0,-73.7101"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path126"
-       inkscape:connector-curvature="0" /><path
-       d="m 4773.0608,5104.4553 0,-73.7101"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path128"
-       inkscape:connector-curvature="0" /><path
-       d="m 5141.6115,5104.4553 0,-73.7101"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path130"
-       inkscape:connector-curvature="0" /><path
-       d="m 5510.1623,5104.4553 0,-73.7101"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path132"
-       inkscape:connector-curvature="0" /><path
-       d="m 5878.713,5104.4553 0,-73.7101"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path134"
-       inkscape:connector-curvature="0" /><path
-       d="m 1456.104,4993.8901 0,-73.7102"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path136"
-       inkscape:connector-curvature="0" /><path
-       d="m 1824.6548,4920.1799 0,73.7102"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path138"
-       inkscape:connector-curvature="0" /><path
-       d="m 2193.2055,4993.8901 0,-73.7102"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path140"
-       inkscape:connector-curvature="0" /><path
-       d="m 2561.7563,4993.8901 0,-73.7102"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path142"
-       inkscape:connector-curvature="0" /><path
-       d="m 2930.307,4993.8901 0,-73.7102"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path144"
-       inkscape:connector-curvature="0" /><path
-       d="m 3298.8578,4993.8901 0,-73.7102"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path146"
-       inkscape:connector-curvature="0" /><path
-       d="m 3667.4085,4993.8901 0,-73.7102"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path148"
-       inkscape:connector-curvature="0" /><path
-       d="m 4035.9593,4993.8901 0,-73.7102"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path150"
-       inkscape:connector-curvature="0" /><path
-       d="m 4404.51,4993.8901 0,-73.7102"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path152"
-       inkscape:connector-curvature="0" /><path
-       d="m 4773.0608,4993.8901 0,-73.7102"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path154"
-       inkscape:connector-curvature="0" /><path
-       d="m 5141.6115,4993.8901 0,-73.7102"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path156"
-       inkscape:connector-curvature="0" /><path
-       d="m 5510.1623,4993.8901 0,-73.7102"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path158"
-       inkscape:connector-curvature="0" /><path
-       d="m 5878.713,4993.8901 0,-73.7102"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path160"
-       inkscape:connector-curvature="0" /><path
-       d="m 719.00254,5104.4553 0,-73.7101"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path162"
-       inkscape:connector-curvature="0" /><path
-       d="m 719.00254,4993.8901 0,-73.7102"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path164"
-       inkscape:connector-curvature="0" /><path
-       d="m 1087.5533,5104.4553 0,-73.7101"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path166"
-       inkscape:connector-curvature="0" /><path
-       d="m 1087.5533,4993.8901 0,-73.7102"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path168"
-       inkscape:connector-curvature="0" /><path
-       d="m 700.575,4735.9046 18.42754,0 0,-110.5653 36.85507,0 0,110.5653 18.42754,0"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path170"
-       inkscape:connector-curvature="0" /><path
-       d="m 774.28515,4680.6285 18.42754,0 0,110.5652 -18.42754,0 0,-110.5652 z"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path172"
-       inkscape:connector-curvature="0" /><path
-       d="m 792.71269,4735.9046 18.42753,0 0,92.1442 18.42754,-18.4341 18.42754,36.8551 18.42754,-36.8551 18.42753,36.8551 18.42754,-55.2761 18.42754,55.2761 18.42754,-18.421 18.42753,55.2761 18.42754,-55.2761 18.42754,18.421 18.4275,36.8551 18.4276,-92.1312 18.4275,55.2761 18.4275,-55.2761 0,-55.2891"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path174"
-       inkscape:connector-curvature="0" /><path
-       d="m 1069.1257,4735.9046 18.4276,0 0,-110.5653 36.8551,0 0,110.5653 18.421,0"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path176"
-       inkscape:connector-curvature="0" /><path
-       d="m 1142.8294,4680.6285 18.4275,0 0,110.5652 -18.4275,0 0,-110.5652 z"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path178"
-       inkscape:connector-curvature="0" /><path
-       d="m 1456.104,4735.9046 0,-110.5653 18.4211,0 0,110.5653 165.8543,0 0,-110.5653 18.421,0 0,110.5653 165.8544,0 0,-110.5653 18.421,0 0,110.5653 165.8544,0 0,-110.5653 18.421,0 0,110.5653 165.8543,0 0,-110.5653 18.4211,0 0,110.5653 165.8543,0 0,-110.5653 18.421,0 0,110.5653 165.8544,0 0,-110.5653 147.4203,0 0,110.5653 36.8551,0 0,-110.5653 147.4203,0 0,110.5653 36.855,0 0,-110.5653 147.4203,0 0,110.5653 36.8551,0 0,-110.5653 147.4203,0 0,110.5653 36.8551,0 0,-110.5653 147.4203,0 0,110.5653 36.855,0 0,-110.5653 147.4203,0 0,110.5653 36.8551,0 0,-110.5653 18.4211,0 0,110.5653 165.8543,0 0,-110.5653 18.421,0 0,110.5653 165.8544,0 0,-110.5653 18.421,0 0,110.5653 165.8543,0 0,-110.5653 18.4211,0 0,110.5653 165.8543,0 0,-110.5653 18.4211,0 0,110.5653 165.8543,0 0,-110.5653 18.421,0 0,110.5653 165.8544,0 0,-110.5653 36.855,0 0,110.5653 18.4211,0"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path180"
-       inkscape:connector-curvature="0" /><path
-       d="m 1161.2634,4735.9046 294.8406,0"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path182"
-       inkscape:connector-curvature="0" /><path
-       d="m 6320.9739,4735.9046 18.421,0 0,92.1442 18.4341,-18.4341 18.421,73.7102 18.4341,-55.2761 18.421,36.855 18.434,-18.434 18.4211,36.8551 18.434,-36.8551 18.421,36.8551 18.4341,-36.8551 18.421,18.434 18.4341,-36.855 18.421,36.855 18.434,-36.855 18.4211,-18.4341 0,-73.7101 18.434,0"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path184"
-       inkscape:connector-curvature="0" /><path
-       d="m 4828.3369,4680.6285 18.4275,0 0,110.5652 -18.4275,0 0,-110.5652 z"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path186"
-       inkscape:connector-curvature="0" /><path
-       d="m 4846.7709,4735.9046 294.8406,0 0,-110.5653 36.8551,0 0,110.5653 18.421,0"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path188"
-       inkscape:connector-curvature="0" /><path
-       d="m 5196.8876,4680.6285 18.4276,0 0,110.5652 -18.4276,0 0,-110.5652 z"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path190"
-       inkscape:connector-curvature="0" /><path
-       d="m 5565.4384,4680.6285 18.4275,0 0,110.5652 -18.4275,0 0,-110.5652 z"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path192"
-       inkscape:connector-curvature="0" /><path
-       d="m 5933.9891,4680.6285 18.4276,0 0,110.5652 -18.4276,0 0,-110.5652 z"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path194"
-       inkscape:connector-curvature="0" /><path
-       d="m 5952.4232,4735.9046 294.8406,0 0,-110.5653 36.855,0 0,110.5653 18.4211,0"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path196"
-       inkscape:connector-curvature="0" /><path
-       d="m 6302.5399,4680.6285 18.4275,0 0,110.5652 -18.4275,0 0,-110.5652 z"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path198"
-       inkscape:connector-curvature="0" /><path
-       d="m 5786.5688,4735.9046 92.1442,0 0,-110.5653 36.8551,0 0,110.5653 18.421,0"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path200"
-       inkscape:connector-curvature="0" /><path
-       d="m 5805.0029,4791.1937 -36.8551,-110.5652"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path202"
-       inkscape:connector-curvature="0" /><path
-       d="m 5583.8724,4735.9046 165.8414,0"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path204"
-       inkscape:connector-curvature="0" /><path
-       d="m 5768.1478,4791.1937 -36.8551,-110.5652"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path206"
-       inkscape:connector-curvature="0" /><path
-       d="m 5215.3217,4735.9046 294.8406,0 0,-110.5653 36.855,0 0,110.5653 18.4211,0"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path208"
-       inkscape:connector-curvature="0" /><path
-       d="m 6247.2638,5104.4553 0,-73.7101"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path210"
-       inkscape:connector-curvature="0" /><path
-       d="m 6247.2638,4993.8901 0,-73.7102"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path212"
-       inkscape:connector-curvature="0" /><path
-       d="m 6615.8145,5104.4553 0,-73.7101"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path214"
-       inkscape:connector-curvature="0" /><path
-       d="m 6615.8145,4993.8901 0,-73.7102"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path216"
-       inkscape:connector-curvature="0" /><path
-       d="m 700.575,3925.0929 18.42754,0 0,-110.5652 36.85507,0 0,110.5652 18.42754,0"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path218"
-       inkscape:connector-curvature="0" /><path
-       d="m 774.28515,3869.8168 18.42754,0 0,110.5652 -18.42754,0 0,-110.5652 z"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path220"
-       inkscape:connector-curvature="0" /><path
-       d="m 1142.8294,3869.8168 18.4275,0 0,110.5652 -18.4275,0 0,-110.5652 z"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path222"
-       inkscape:connector-curvature="0" /><path
-       d="m 792.71269,3925.0929 18.42753,0 0,110.5652 18.42754,-36.855 18.42754,18.434 18.42754,-36.8551 18.42753,36.8551 0,-92.1442 202.70293,0 0,-110.5652 36.8551,0 0,110.5652 18.421,0"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path224"
-       inkscape:connector-curvature="0" /><path
-       d="m 1161.2634,3925.0929 110.5653,0 0,-110.5652 18.421,0 0,110.5652 165.8543,0 0,-110.5652 18.4211,0 0,110.5652 165.8543,0 0,-110.5652 18.421,0 0,110.5652 165.8544,0 0,-110.5652 18.421,0 0,110.5652 165.8544,0 0,-110.5652 18.421,0 0,110.5652 165.8543,0 0,-110.5652 18.4211,0 0,110.5652 165.8543,0 0,-110.5652 147.4203,0 0,110.5652 36.8551,0 0,-110.5652 147.4203,0 0,110.5652 36.8551,0 0,-110.5652 147.4203,0 0,110.5652 36.855,0 0,-110.5652 147.4203,0 0,110.5652 36.8551,0 0,-110.5652 147.4203,0 0,110.5652 36.8551,0 0,-110.5652 147.4203,0 0,110.5652 36.855,0 0,-110.5652 18.4211,0 0,110.5652 165.8543,0 0,-110.5652 18.4211,0 0,110.5652 165.8543,0 0,-110.5652 18.421,0 0,110.5652 165.8544,0 0,-110.5652 18.421,0 0,110.5652 165.8543,0"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path226"
-       inkscape:connector-curvature="0" /><path
-       d="m 4220.2346,3925.0929 0,-110.5652 18.4211,0 0,110.5652 165.8543,0 0,-110.5652 18.4211,0 0,110.5652 55.2891,0"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path228"
-       inkscape:connector-curvature="0" /><path
-       d="m 4478.2202,3925.0929 294.8406,0 0,-110.5652 36.855,0 0,110.5652 18.4211,0"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path230"
-       inkscape:connector-curvature="0" /><path
-       d="m 5952.4232,3925.0929 128.9862,0 0,73.7102 18.4341,36.855 18.421,-18.421 18.434,36.8551 18.4211,-36.8551 18.434,18.421 18.421,-36.855 18.4341,18.434 18.421,-36.8551 0,-55.2891 18.4341,0 0,-110.5652 36.855,0 0,110.5652 18.4211,0"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path232"
-       inkscape:connector-curvature="0" /><path
-       d="m 6302.5399,3869.8168 18.4275,0 0,110.5652 -18.4275,0 0,-110.5652 z"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path234"
-       inkscape:connector-curvature="0" /><path
-       d="m 6320.9739,3925.0929 18.421,0 0,73.7102 18.4341,36.855 18.421,-36.855 18.4341,36.855 18.421,-18.421 18.434,0 18.4211,-36.8551 18.434,55.2761 18.421,-18.421 0,36.8551 18.4341,-18.4341 18.421,18.4341 18.4341,-36.8551 18.421,18.421 18.434,-55.2761 18.4211,18.4211 0,-73.7102 18.434,0"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path236"
-       inkscape:connector-curvature="0" /><path
-       d="m 5933.9891,3869.8168 18.4276,0 0,110.5652 -18.4276,0 0,-110.5652 z"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path238"
-       inkscape:connector-curvature="0" /><path
-       d="m 5786.5688,3925.0929 92.1442,0 0,-110.5652 36.8551,0 0,110.5652 18.421,0"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path240"
-       inkscape:connector-curvature="0" /><path
-       d="m 5805.0029,3980.382 -36.8551,-110.5652"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path242"
-       inkscape:connector-curvature="0" /><path
-       d="m 5768.1478,3980.382 -36.8551,-110.5652"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path244"
-       inkscape:connector-curvature="0" /><path
-       d="m 4828.3369,3869.8168 18.4275,0 0,110.5652 -18.4275,0 0,-110.5652 z"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path246"
-       inkscape:connector-curvature="0" /><path
-       d="m 5583.8724,3925.0929 165.8414,0"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path248"
-       inkscape:connector-curvature="0" /><path
-       d="m 4846.7709,3925.0929 294.8406,0 0,-110.5652 36.8551,0 0,110.5652 18.421,0"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path250"
-       inkscape:connector-curvature="0" /><path
-       d="m 5196.8876,3869.8168 18.4276,0 0,110.5652 -18.4276,0 0,-110.5652 z"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path252"
-       inkscape:connector-curvature="0" /><path
-       d="m 5215.3217,3925.0929 294.8406,0 0,-110.5652 36.855,0 0,110.5652 18.4211,0"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path254"
-       inkscape:connector-curvature="0" /><path
-       d="m 5565.4384,3869.8168 18.4275,0 0,110.5652 -18.4275,0 0,-110.5652 z"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path256"
-       inkscape:connector-curvature="0" /><path
-       d="m 6247.2638,4293.6437 0,-73.7102"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path258"
-       inkscape:connector-curvature="0" /><path
-       d="m 6247.2638,4183.0784 0,-73.7101"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path260"
-       inkscape:connector-curvature="0" /><path
-       d="m 6615.8145,4293.6437 0,-73.7102"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path262"
-       inkscape:connector-curvature="0" /><path
-       d="m 6615.8145,4183.0784 0,-73.7101"
-       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path264"
-       inkscape:connector-curvature="0" /><text
-       y="-4035.6582"
-       x="1621.9453"
-       id="text268"
-       style="font-variant:normal;font-weight:normal;font-size:61.42512512px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan270"
-	 sodipodi:role="line"
-	 y="-4035.6582"
-	 x="1621.9453 1642.3999 1676.5522">(1)</tspan></text>
-<text
-       y="-4127.7959"
-       x="4199.7334"
-       id="text272"
-       style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan274"
-	 sodipodi:role="line"
-	 y="-4127.7959"
-	 x="4199.7334 3831.1829 2725.5305 3112.509 3462.6321 4568.2842 4916.3442 4957.3271 5653.4458 5694.4287 5284.895 5325.8779 2356.9773 1988.4264 1210.3424 1251.3252 1292.3081 1619.8759 841.79163 882.77454 923.75732">874569101211322631262</tspan><tspan
-	 id="tspan276"
-	 sodipodi:role="line"
-	 y="-4238.3613"
-	 x="4158.748 4199.7314 4240.7144 3790.1975 3831.1807 3872.1633 2684.5457 2725.5283 2766.5112 3071.5237 3112.5063 3153.4895 3421.647 3462.6299 3503.6125 4527.2988 4568.2822 4609.2646 4895.8496 4936.833 4977.8154 5632.9517 5673.9341 5714.917 5264.4009 5305.3833 5346.3662 2315.9946 2356.9775 2397.9604 1947.444 1988.4269 2029.4097 1210.3424 1251.3252 1292.3081 1578.8931 1619.876 1660.8589 841.79163 882.77454 923.75732">271270267268269272273275274266265263264262</tspan><tspan
-	 id="tspan278"
-	 sodipodi:role="line"
-	 y="-5049.1729"
-	 x="2725.5347 4568.2881 1988.4331 2356.9839 1619.8822 3094.0852 3462.636 4916.3506 4957.334 5284.9019 5325.8843 5653.4526 5694.4351 3812.7656 4181.3164">492315610111278</tspan><tspan
-	 id="tspan280"
-	 sodipodi:role="line"
-	 y="-4938.6074"
-	 x="2725.5474 4568.3013 1988.446 2356.9966 1619.8953 3094.0981 3462.6489 4916.3638 4957.3472 5284.9146 5325.8975 5653.4653 5694.4482 3812.7788 4181.3296">492315610111278</tspan><tspan
-	 id="tspan282"
-	 sodipodi:role="line"
-	 y="-5049.1729"
-	 x="841.81781 882.8006 923.78326">524</tspan><tspan
-	 id="tspan284"
-	 sodipodi:role="line"
-	 y="-4938.6074"
-	 x="841.81781 882.8006 923.78326">261</tspan><tspan
-	 id="tspan286"
-	 sodipodi:role="line"
-	 y="-5049.1729"
-	 x="1210.3684 1251.3512 1292.3342">525</tspan><tspan
-	 id="tspan288"
-	 sodipodi:role="line"
-	 y="-4938.6074"
-	 x="1210.3684 1251.3512 1292.3342">262</tspan><tspan
-	 id="tspan290"
-	 sodipodi:role="line"
-	 y="-5049.1729"
-	 x="6022.0161 6062.999">22</tspan><tspan
-	 id="tspan292"
-	 sodipodi:role="line"
-	 y="-4938.6074"
-	 x="6022.0161 6062.999">22</tspan><tspan
-	 id="tspan294"
-	 sodipodi:role="line"
-	 y="-5049.1729"
-	 x="6390.5669 6431.5498">23</tspan><tspan
-	 id="tspan296"
-	 sodipodi:role="line"
-	 y="-4938.6074"
-	 x="6390.5669 6431.5498">23</tspan><tspan
-	 id="tspan298"
-	 sodipodi:role="line"
-	 y="-4238.3623"
-	 x="6001.5244 6042.5068 6083.4902">285</tspan><tspan
-	 id="tspan300"
-	 sodipodi:role="line"
-	 y="-4127.7964"
-	 x="6022.0156 6062.9985">22</tspan><tspan
-	 id="tspan302"
-	 sodipodi:role="line"
-	 y="-4238.3623"
-	 x="6370.0747 6411.0571 6452.04">286</tspan><tspan
-	 id="tspan304"
-	 sodipodi:role="line"
-	 y="-4127.7964"
-	 x="6390.5664 6431.5493">23</tspan><tspan
-	 id="tspan306"
-	 sodipodi:role="line"
-	 y="-4459.4922"
-	 x="3540.4146 3581.3972 3618.2522 3638.7437 3659.2354 3679.7266 3696.0901 3737.073 3753.4365">1st field</tspan><tspan
-	 id="tspan308"
-	 sodipodi:role="line"
-	 y="-3648.6809"
-	 x="3528.1047 3569.0876 3610.0703 3651.0532 3671.5447 3692.0361 3708.3999 3749.3826 3765.7463">2nd field</tspan></text>
-<text
-       y="-4127.7959"
-       x="4199.7334 3831.1829 2725.5305 3112.509 3462.6321 4568.2842 4916.3442 4957.3271 5653.4458 5694.4287 5284.895 5325.8779 2356.9773 1988.4264 1210.3424 1251.3252 1292.3081 1619.8759 841.79163 882.77454 923.75732"
-       id="text3632"
-       style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan3634"
-	 sodipodi:role="line"
-	 y="-4127.7959"
-	 x="4199.7334 3831.1829 2725.5305 3112.509 3462.6321 4568.2842 4916.3442 4957.3271 5653.4458 5694.4287 5284.895 5325.8779 2356.9773 1988.4264 1210.3424 1251.3252 1292.3081 1619.8759 841.79163 882.77454 923.75732">874569101211322631262</tspan></text>
-<text
-       y="-4238.3613"
-       x="4158.748 4199.7314 4240.7144 3790.1975 3831.1807 3872.1633 2684.5457 2725.5283 2766.5112 3071.5237 3112.5063 3153.4895 3421.647 3462.6299 3503.6125 4527.2988 4568.2822 4609.2646 4895.8496 4936.833 4977.8154 5632.9517 5673.9341 5714.917 5264.4009 5305.3833 5346.3662 2315.9946 2356.9775 2397.9604 1947.444 1988.4269 2029.4097 1210.3424 1251.3252 1292.3081 1578.8931 1619.876 1660.8589 841.79163 882.77454 923.75732"
-       id="text3636"
-       style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan3638"
-	 sodipodi:role="line"
-	 y="-4238.3613"
-	 x="4158.748 4199.7314 4240.7144 3790.1975 3831.1807 3872.1633 2684.5457 2725.5283 2766.5112 3071.5237 3112.5063 3153.4895 3421.647 3462.6299 3503.6125 4527.2988 4568.2822 4609.2646 4895.8496 4936.833 4977.8154 5632.9517 5673.9341 5714.917 5264.4009 5305.3833 5346.3662 2315.9946 2356.9775 2397.9604 1947.444 1988.4269 2029.4097 1210.3424 1251.3252 1292.3081 1578.8931 1619.876 1660.8589 841.79163 882.77454 923.75732">271270267268269272273275274266265263264262</tspan></text>
-<text
-       y="-5049.1729"
-       x="2725.5347 4568.2881 1988.4331 2356.9839 1619.8822 3094.0852 3462.636 4916.3506 4957.334 5284.9019 5325.8843 5653.4526 5694.4351 3812.7656 4181.3164"
-       id="text3640"
-       style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan3642"
-	 sodipodi:role="line"
-	 y="-5049.1729"
-	 x="2725.5347 4568.2881 1988.4331 2356.9839 1619.8822 3094.0852 3462.636 4916.3506 4957.334 5284.9019 5325.8843 5653.4526 5694.4351 3812.7656 4181.3164">492315610111278</tspan></text>
-<text
-       y="-4938.6074"
-       x="2725.5474 4568.3013 1988.446 2356.9966 1619.8953 3094.0981 3462.6489 4916.3638 4957.3472 5284.9146 5325.8975 5653.4653 5694.4482 3812.7788 4181.3296"
-       id="text3644"
-       style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan3646"
-	 sodipodi:role="line"
-	 y="-4938.6074"
-	 x="2725.5474 4568.3013 1988.446 2356.9966 1619.8953 3094.0981 3462.6489 4916.3638 4957.3472 5284.9146 5325.8975 5653.4653 5694.4482 3812.7788 4181.3296">492315610111278</tspan></text>
-<text
-       y="-5049.1729"
-       x="841.81781 882.8006 923.78326"
-       id="text3648"
-       style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan3650"
-	 sodipodi:role="line"
-	 y="-5049.1729"
-	 x="841.81781 882.8006 923.78326">524</tspan></text>
-<text
-       y="-4938.6074"
-       x="841.81781 882.8006 923.78326"
-       id="text3652"
-       style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan3654"
-	 sodipodi:role="line"
-	 y="-4938.6074"
-	 x="841.81781 882.8006 923.78326">261</tspan></text>
-<text
-       y="-5049.1729"
-       x="1210.3684 1251.3512 1292.3342"
-       id="text3656"
-       style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan3658"
-	 sodipodi:role="line"
-	 y="-5049.1729"
-	 x="1210.3684 1251.3512 1292.3342">525</tspan></text>
-<text
-       y="-4938.6074"
-       x="1210.3684 1251.3512 1292.3342"
-       id="text3660"
-       style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan3662"
-	 sodipodi:role="line"
-	 y="-4938.6074"
-	 x="1210.3684 1251.3512 1292.3342">262</tspan></text>
-<text
-       y="-5049.1729"
-       x="6022.0161 6062.999"
-       id="text3664"
-       style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan3666"
-	 sodipodi:role="line"
-	 y="-5049.1729"
-	 x="6022.0161 6062.999">22</tspan></text>
-<text
-       y="-4938.6074"
-       x="6022.0161 6062.999"
-       id="text3668"
-       style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan3670"
-	 sodipodi:role="line"
-	 y="-4938.6074"
-	 x="6022.0161 6062.999">22</tspan></text>
-<text
-       y="-5049.1729"
-       x="6390.5669 6431.5498"
-       id="text3672"
-       style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan3674"
-	 sodipodi:role="line"
-	 y="-5049.1729"
-	 x="6390.5669 6431.5498">23</tspan></text>
-<text
-       y="-4938.6074"
-       x="6390.5669 6431.5498"
-       id="text3676"
-       style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan3678"
-	 sodipodi:role="line"
-	 y="-4938.6074"
-	 x="6390.5669 6431.5498">23</tspan></text>
-<text
-       y="-4238.3623"
-       x="6001.5244 6042.5068 6083.4902"
-       id="text3680"
-       style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan3682"
-	 sodipodi:role="line"
-	 y="-4238.3623"
-	 x="6001.5244 6042.5068 6083.4902">285</tspan></text>
-<text
-       y="-4127.7964"
-       x="6022.0156 6062.9985"
-       id="text3684"
-       style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan3686"
-	 sodipodi:role="line"
-	 y="-4127.7964"
-	 x="6022.0156 6062.9985">22</tspan></text>
-<text
-       y="-4238.3623"
-       x="6370.0747 6411.0571 6452.04"
-       id="text3688"
-       style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan3690"
-	 sodipodi:role="line"
-	 y="-4238.3623"
-	 x="6370.0747 6411.0571 6452.04">286</tspan></text>
-<text
-       y="-4127.7964"
-       x="6390.5664 6431.5493"
-       id="text3692"
-       style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan3694"
-	 sodipodi:role="line"
-	 y="-4127.7964"
-	 x="6390.5664 6431.5493">23</tspan></text>
-<text
-       y="-4459.4922"
-       x="3540.4146 3581.3972 3618.2522 3638.7437 3659.2354 3679.7266 3696.0901 3737.073 3753.4365"
-       id="text3696"
-       style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan3698"
-	 sodipodi:role="line"
-	 y="-4459.4922"
-	 x="3540.4146 3581.3972 3618.2522 3638.7437 3659.2354 3679.7266 3696.0901 3737.073 3753.4365">1st field</tspan></text>
-<text
-       y="-3648.6809"
-       x="3528.1047 3569.0876 3610.0703 3651.0532 3671.5447 3692.0361 3708.3999 3749.3826 3765.7463"
-       id="text3700"
-       style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"><tspan
-	 id="tspan3702"
-	 sodipodi:role="line"
-	 y="-3648.6809"
-	 x="3528.1047 3569.0876 3610.0703 3651.0532 3671.5447 3692.0361 3708.3999 3749.3826 3765.7463">2nd field</tspan></text>
-</g></svg>
diff --git a/Documentation/media/uapi/v4l/vbi_625.svg b/Documentation/media/uapi/v4l/vbi_625.svg
deleted file mode 100644
index 7aaae5ec4878..000000000000
--- a/Documentation/media/uapi/v4l/vbi_625.svg
+++ /dev/null
@@ -1,870 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!--
-    Permission is granted to copy, distribute and/or modify this
-    document under the terms of the GNU Free Documentation License,
-    Version 1.1 or any later version published by the Free Software
-    Foundation, with no Invariant Sections, no Front-Cover Texts
-    and no Back-Cover Texts. A copy of the license is included at
-    Documentation/media/uapi/fdl-appendix.rst.
-
-    TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
--->
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   id="svg2"
-   version="1.1"
-   inkscape:version="0.91 r13725"
-   xml:space="preserve"
-   width="209.46608mm"
-   height="51.576824mm"
-   viewBox="0 0 742.20265 182.75252"
-   sodipodi:docname="vbi_625.svg"><sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="1920"
-     inkscape:window-height="997"
-     id="namedview4"
-     showgrid="false"
-     fit-margin-top="0"
-     fit-margin-left="0"
-     fit-margin-right="0"
-     fit-margin-bottom="0"
-     inkscape:zoom="1.5350601"
-     inkscape:cx="288.91482"
-     inkscape:cy="170.67667"
-     inkscape:window-x="1920"
-     inkscape:window-y="30"
-     inkscape:window-maximized="1"
-     inkscape:current-layer="g10"
-     units="mm" /><metadata
-     id="metadata8"><rdf:RDF><cc:Work
-	 rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
-	   rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
-     id="defs6"><clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath20"><path
-	 d="m 0,0 5950,0 0,4546 L 0,4546 0,0 Z m 0,4546 5950,0 0,1 -5950,0 0,-1 z m 0,1 2211,0 0,1 -2211,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2215,0 0,1 -2215,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2219,0 0,1 -2219,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2223,0 0,1 -2223,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2227,0 0,1 -2227,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2231,0 0,1 -2231,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2235,0 0,1 -2235,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2239,0 0,1 -2239,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2241,0 0,1 -2241,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2240,0 0,1 -2240,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2236,0 0,1 -2236,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2232,0 0,1 -2232,0 0,-1 z m
-2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2228,0 0,1 -2228,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2224,0 0,1 -2224,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2220,0 0,1 -2220,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2216,0 0,1 -2216,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2212,0 0,1 -2212,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2208,0 0,1 -2208,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 5950,0 0,1 -5950,0 0,-1 z m 0,1 5950,0 0,3854 -5950,0 0,-3854 z"
-	 id="path22"
-	 inkscape:connector-curvature="0" /></clipPath><clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath98"><path
-	 d="m 0,0 5950,0 0,3922 L 0,3922 0,0 Z m 0,3922 5950,0 0,1 -5950,0 0,-1 z m 0,1 2209,0 0,1 -2209,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2213,0 0,1 -2213,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2217,0 0,1 -2217,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2221,0 0,1 -2221,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2225,0 0,1 -2225,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2229,0 0,1 -2229,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2233,0 0,1 -2233,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2237,0 0,1 -2237,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2241,0 0,1 -2241,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2241,0 0,1 -2241,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2237,0 0,1 -2237,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2233,0 0,1 -2233,0 0,-1 z m
-2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2229,0 0,1 -2229,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2225,0 0,1 -2225,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2221,0 0,1 -2221,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2217,0 0,1 -2217,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2213,0 0,1 -2213,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2209,0 0,1 -2209,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 5950,0 0,1 -5950,0 0,-1 z m 0,1 5950,0 0,4478 -5950,0 0,-4478 z"
-	 id="path100"
-	 inkscape:connector-curvature="0" /></clipPath></defs><g
-     id="g10"
-     inkscape:groupmode="layer"
-     inkscape:label="vbi_625"
-     transform="matrix(0.125,0,0,-0.125,-87.571875,638.69874)"><g
-       id="g12"
-       transform="matrix(1.3045828,0,0,1.3045828,-213.38312,-1110.9872)"
-       style=""><path
-	 d="m 2132.25,4598.15 0,-85.05"
-	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 id="path14"
-	 inkscape:connector-curvature="0" /></g><g
-       id="g16"
-       transform="matrix(1.3045828,0,0,1.3045828,-213.38312,-1110.9872)"
-       style=""><g
-	 id="g18"
-	 clip-path="url(#clipPath20)"
-	 style=""><path
-	   d="m 2132.25,4555.63 113.4,0"
-	   style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	   id="path24"
-	   inkscape:connector-curvature="0" /></g></g><path
-       inkscape:connector-curvature="0"
-       id="path28"
-       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       d="m 2660.3649,4819.881 49.3132,12.3283 -49.3132,12.3283 0,-24.6566" /><path
-       inkscape:connector-curvature="0"
-       id="path30"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 2660.3649,4819.881 49.3132,12.3283 -49.3132,12.3283 0,-24.6566 z" /><path
-       inkscape:connector-curvature="0"
-       id="path32"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 1828.6151,4924.6651 0,73.9699" /><path
-       inkscape:connector-curvature="0"
-       id="path34"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 2198.4643,4998.635 0,-73.9699" /><path
-       inkscape:connector-curvature="0"
-       id="path36"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 2568.3136,4998.635 0,-73.9699" /><path
-       inkscape:connector-curvature="0"
-       id="path38"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 2938.1628,4998.635 0,-73.9699" /><path
-       inkscape:connector-curvature="0"
-       id="path40"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 3308.012,4998.635 0,-73.9699" /><path
-       inkscape:connector-curvature="0"
-       id="path42"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 3677.8612,4998.635 0,-73.9699" /><path
-       inkscape:connector-curvature="0"
-       id="path44"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 4047.7105,4998.635 0,-73.9699" /><path
-       inkscape:connector-curvature="0"
-       id="path46"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 4417.5597,4998.635 0,-73.9699" /><path
-       inkscape:connector-curvature="0"
-       id="path48"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 4787.4089,4998.635 0,-73.9699" /><path
-       inkscape:connector-curvature="0"
-       id="path50"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 5157.2581,4998.635 0,-73.9699" /><path
-       inkscape:connector-curvature="0"
-       id="path52"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 5527.1073,4998.635 0,-73.9699" /><path
-       inkscape:connector-curvature="0"
-       id="path54"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 5896.9566,4998.635 0,-73.9699" /><path
-       inkscape:connector-curvature="0"
-       id="path56"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 1458.7659,5109.5897 0,-73.9698" /><path
-       inkscape:connector-curvature="0"
-       id="path58"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 1828.6151,5035.6199 0,73.9698" /><path
-       inkscape:connector-curvature="0"
-       id="path60"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 2198.4643,5109.5897 0,-73.9698" /><path
-       inkscape:connector-curvature="0"
-       id="path62"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 2568.3136,5109.5897 0,-73.9698" /><path
-       inkscape:connector-curvature="0"
-       id="path64"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 2938.1628,5109.5897 0,-73.9698" /><path
-       inkscape:connector-curvature="0"
-       id="path66"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 3308.012,5109.5897 0,-73.9698" /><path
-       inkscape:connector-curvature="0"
-       id="path68"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 3677.8612,5109.5897 0,-73.9698" /><path
-       inkscape:connector-curvature="0"
-       id="path70"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 4047.7105,5109.5897 0,-73.9698" /><path
-       inkscape:connector-curvature="0"
-       id="path72"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 4417.5597,5109.5897 0,-73.9698" /><path
-       inkscape:connector-curvature="0"
-       id="path74"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 4787.4089,5109.5897 0,-73.9698" /><path
-       inkscape:connector-curvature="0"
-       id="path76"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 5157.2581,5109.5897 0,-73.9698" /><path
-       inkscape:connector-curvature="0"
-       id="path78"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 5527.1073,5109.5897 0,-73.9698" /><path
-       inkscape:connector-curvature="0"
-       id="path80"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 5896.9566,5109.5897 0,-73.9698" /><path
-       inkscape:connector-curvature="0"
-       id="path82"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 1458.7659,4998.635 0,-73.9699" /><path
-       inkscape:connector-curvature="0"
-       id="path84"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 719.06744,4998.635 0,-73.9699" /><path
-       inkscape:connector-curvature="0"
-       id="path86"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 719.06744,5109.5897 0,-73.9698" /><path
-       inkscape:connector-curvature="0"
-       id="path88"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 1088.9167,4998.635 0,-73.9699" /><path
-       inkscape:connector-curvature="0"
-       id="path90"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 1088.9167,5109.5897 0,-73.9698" /><path
-       inkscape:connector-curvature="0"
-       id="path92"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 2568.3136,4074.0119 0,-110.9548" /><g
-       id="g94"
-       transform="matrix(1.3045828,0,0,1.3045828,-213.38312,-1110.9872)"
-       style=""><g
-	 id="g96"
-	 clip-path="url(#clipPath98)"
-	 style=""><path
-	   d="m 2132.25,3931.93 113.4,0"
-	   style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	   id="path102"
-	   inkscape:connector-curvature="0" /></g></g><path
-       inkscape:connector-curvature="0"
-       id="path106"
-       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       d="m 2660.365,4006.2129 49.3132,12.3283 -49.3132,12.3283 0,-24.6566" /><path
-       inkscape:connector-curvature="0"
-       id="path108"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 2660.365,4006.2129 49.3132,12.3283 -49.3132,12.3283 0,-24.6566 z" /><path
-       inkscape:connector-curvature="0"
-       id="path110"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 6266.806,4184.9668 0,-73.9698" /><path
-       inkscape:connector-curvature="0"
-       id="path112"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 5896.9567,4184.9668 0,-73.9698" /><path
-       inkscape:connector-curvature="0"
-       id="path114"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 5527.1075,4184.9668 0,-73.9698" /><path
-       inkscape:connector-curvature="0"
-       id="path116"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 5157.2583,4184.9668 0,-73.9698" /><path
-       inkscape:connector-curvature="0"
-       id="path118"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 4787.409,4184.9668 0,-73.9698" /><path
-       inkscape:connector-curvature="0"
-       id="path120"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 4417.5598,4184.9668 0,-73.9698" /><path
-       inkscape:connector-curvature="0"
-       id="path122"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 4047.7106,4184.9668 0,-73.9698" /><path
-       inkscape:connector-curvature="0"
-       id="path124"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 3677.8613,4184.9668 0,-73.9698" /><path
-       inkscape:connector-curvature="0"
-       id="path126"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 3308.0121,4184.9668 0,-73.9698" /><path
-       inkscape:connector-curvature="0"
-       id="path128"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 2938.1629,4184.9668 0,-73.9698" /><path
-       inkscape:connector-curvature="0"
-       id="path130"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 2568.3136,4184.9668 0,-73.9698" /><path
-       inkscape:connector-curvature="0"
-       id="path132"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 2198.4644,4184.9668 0,-73.9698" /><path
-       inkscape:connector-curvature="0"
-       id="path134"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 1828.6152,4184.9668 0,-73.9698" /><path
-       inkscape:connector-curvature="0"
-       id="path136"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 1458.7659,4184.9668 0,-73.9698" /><path
-       inkscape:connector-curvature="0"
-       id="path138"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 6266.806,4295.9216 0,-73.9699" /><path
-       inkscape:connector-curvature="0"
-       id="path140"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 5896.9567,4295.9216 0,-73.9699" /><path
-       inkscape:connector-curvature="0"
-       id="path142"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 5527.1075,4295.9216 0,-73.9699" /><path
-       inkscape:connector-curvature="0"
-       id="path144"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 5157.2583,4295.9216 0,-73.9699" /><path
-       inkscape:connector-curvature="0"
-       id="path146"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 4787.409,4295.9216 0,-73.9699" /><path
-       inkscape:connector-curvature="0"
-       id="path148"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 4417.5598,4295.9216 0,-73.9699" /><path
-       inkscape:connector-curvature="0"
-       id="path150"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 4047.7106,4295.9216 0,-73.9699" /><path
-       inkscape:connector-curvature="0"
-       id="path152"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 3677.8613,4295.9216 0,-73.9699" /><path
-       inkscape:connector-curvature="0"
-       id="path154"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 3308.0121,4295.9216 0,-73.9699" /><path
-       inkscape:connector-curvature="0"
-       id="path156"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 2938.1629,4295.9216 0,-73.9699" /><path
-       inkscape:connector-curvature="0"
-       id="path158"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 2568.3136,4295.9216 0,-73.9699" /><path
-       inkscape:connector-curvature="0"
-       id="path160"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 2198.4644,4295.9216 0,-73.9699" /><path
-       inkscape:connector-curvature="0"
-       id="path162"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 1828.6152,4295.9216 0,-73.9699" /><path
-       inkscape:connector-curvature="0"
-       id="path164"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 1458.7659,4295.9216 0,-73.9699" /><path
-       inkscape:connector-curvature="0"
-       id="path166"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 719.06746,4295.9216 0,-73.9699" /><path
-       inkscape:connector-curvature="0"
-       id="path168"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 719.06746,4184.9668 0,-73.9698" /><path
-       inkscape:connector-curvature="0"
-       id="path170"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 1088.9167,4295.9216 0,-73.9699" /><path
-       inkscape:connector-curvature="0"
-       id="path172"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 1088.9167,4184.9668 0,-73.9698" /><path
-       inkscape:connector-curvature="0"
-       id="path174"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 1144.3876,4684.2698 18.4924,0 0,110.9548 -18.4924,0 0,-110.9548 z" /><path
-       inkscape:connector-curvature="0"
-       id="path176"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 1070.4242,4739.7407 18.4925,0 0,-110.9548 36.9849,0 0,110.9548 18.486,0" /><path
-       inkscape:connector-curvature="0"
-       id="path178"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 700.575,4739.7407 18.49246,0 0,-110.9548 36.98492,0 0,110.9548 18.49247,0" /><path
-       inkscape:connector-curvature="0"
-       id="path180"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 809.886,4739.7407 3.28754,0" /><path
-       inkscape:connector-curvature="0"
-       id="path182"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 809.886,4739.7407 3.28754,0" /><path
-       inkscape:connector-curvature="0"
-       id="path184"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 774.54485,4684.2698 18.49246,0 0,110.9548 -18.49246,0 0,-110.9548 z" /><path
-       inkscape:connector-curvature="0"
-       id="path186"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 793.03731,4739.7407 18.49246,0 18.49246,73.9698 18.49246,-36.9849 18.49246,92.4688 18.49247,-55.4839 18.49246,18.499 18.49246,-36.9849 18.49246,55.4708 18.49246,-73.9698 18.49246,55.4839 18.49247,-73.9699 18.49241,110.9548 18.4925,-92.4688 18.4925,55.4839 18.4924,-55.4839 0,-36.9849" /><path
-       inkscape:connector-curvature="0"
-       id="path188"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 1162.8865,4739.7407 18.486,0 0,92.4688 18.499,-18.499 18.4859,36.9849 18.499,-36.9849 18.4859,36.9849 18.499,-55.4708 18.4859,55.4708 18.499,-18.4859 18.486,55.4708 18.499,-55.4708 18.4859,18.4859 18.499,36.9849 18.4859,-73.9698 18.499,36.9849 18.4859,-55.4708 0,-55.4839 18.499,0 0,-110.9548 36.985,0 0,110.9548 18.4859,0 0,55.4839 18.499,36.9849 18.4859,-36.9849 18.499,55.4708 18.4859,-18.4859 18.499,55.4708 18.486,-18.4859 0,-129.4537 18.4989,0 0,-110.9548 18.486,0 0,110.9548 166.4387,0 0,-110.9548 18.4859,0 0,110.9548 166.4387,0 0,-110.9548 18.4859,0 0,110.9548 166.4387,0 0,-110.9548 18.4859,0 0,110.9548 166.4387,0 0,-110.9548 18.4859,0 0,110.9548 166.4387,0 0,-110.9548 147.9397,0 0,110.9548 36.9849,0 0,-110.9548 147.9397,0 0,110.9548 36.985,0 0,-110.9548 147.9397,0 0,110.9548 36.9849,0 0,-110.9548 147.9397,0 0,110.9548 36.9849,0 0,-110.9548 147.9397,0 0,110.9548 36.9849,0
-0,-110.9548 18.4859,0 0,110.9548 166.4387,0 0,-110.9548 18.486,0 0,110.9548 166.4386,0 0,-110.9548 18.486,0 0,110.9548 166.4387,0 0,-110.9548 18.4859,0 0,110.9548 166.4387,0 0,-110.9548 18.4859,0 0,110.9548 166.4387,0 0,-110.9548 36.9849,0 0,110.9548 332.8643,0 0,-110.9548 36.9849,0 0,110.9548 18.486,0" /><path
-       inkscape:connector-curvature="0"
-       id="path190"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 700.575,3926.0723 18.49246,0 0,-110.9547 36.98492,0 0,110.9547 18.49247,0" /><path
-       inkscape:connector-curvature="0"
-       id="path192"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 774.54485,3870.6015 18.49246,0 0,110.9547 -18.49246,0 0,-110.9547 z" /><path
-       inkscape:connector-curvature="0"
-       id="path194"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 793.03731,3926.0723 18.49246,0 0,92.4689 18.49246,-36.985 18.49246,73.9699 18.49246,-73.9699 18.49247,73.9699 18.49246,-36.9849 18.49246,18.4859 18.49246,-73.9698 18.49246,55.4839 18.49246,-18.499 18.49247,36.9849 18.49241,-73.9698 18.4925,92.4688 18.4925,-92.4688 18.4924,55.4839 0,-92.4689" /><path
-       inkscape:connector-curvature="0"
-       id="path196"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 1070.4242,3926.0723 18.4925,0 0,-110.9547 36.9849,0 0,110.9547 18.486,0" /><path
-       inkscape:connector-curvature="0"
-       id="path198"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 1144.3876,3870.6015 18.4924,0 0,110.9547 -18.4924,0 0,-110.9547 z" /><path
-       inkscape:connector-curvature="0"
-       id="path200"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 1162.8865,3926.0723 18.486,0 0,55.4839 18.499,92.4558 18.4859,-55.4708 36.9849,36.9849 18.499,-55.4839 18.4859,18.499 18.499,-36.985 18.486,55.4709 18.499,-18.4859 18.4859,-36.985 18.499,18.486 18.4859,36.9849 18.499,-36.9849 18.4859,36.9849 0,-110.9548 18.499,0 0,-110.9547 18.486,0 0,110.9547 166.4386,0 0,-110.9547 18.486,0 0,110.9547 166.4387,0 0,-110.9547 18.4859,0 0,110.9547 166.4387,0 0,-110.9547 18.4859,0 0,110.9547 166.4387,0 0,-110.9547 18.4859,0 0,110.9547 166.4387,0 0,-110.9547 147.9397,0 0,110.9547 36.9849,0 0,-110.9547 147.9397,0 0,110.9547 36.9849,0 0,-110.9547 147.9397,0 0,110.9547 36.985,0 0,-110.9547 147.9397,0 0,110.9547 36.9849,0 0,-110.9547 147.9397,0 0,110.9547 36.9849,0 0,-110.9547 18.4859,0 0,110.9547 166.4387,0 0,-110.9547 18.4859,0 0,110.9547 166.4387,0 0,-110.9547 18.486,0 0,110.9547 166.4386,0 0,-110.9547 18.486,0 0,110.9547 166.4387,0 0,-110.9547
-18.4859,0 0,110.9547 351.3633,0 0,-110.9547 36.9849,0 0,110.9547 18.486,0" /><path
-       inkscape:connector-curvature="0"
-       id="path202"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 5453.1376,4795.2246 -36.9849,-110.9548" /><path
-       inkscape:connector-curvature="0"
-       id="path204"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 5434.6387,4739.7407 92.4688,0 0,-110.9548 36.9849,0 0,110.9548 18.486,0" /><path
-       inkscape:connector-curvature="0"
-       id="path206"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 5582.5784,4684.2698 18.4924,0 0,110.9548 -18.4924,0 0,-110.9548 z" /><path
-       inkscape:connector-curvature="0"
-       id="path208"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 5601.0773,4739.7407 295.8794,0 0,-110.9548 36.9849,0 0,110.9548 18.486,0" /><path
-       inkscape:connector-curvature="0"
-       id="path210"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 5952.4276,4684.2698 18.4924,0 0,110.9548 -18.4924,0 0,-110.9548 z" /><path
-       inkscape:connector-curvature="0"
-       id="path212"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 5970.9266,4739.7407 129.4407,0 0,147.9396 18.499,-36.9849 18.4859,36.9849 18.499,-36.9849 18.4859,18.499 18.499,-36.9849 18.4859,36.9849 18.499,-36.9849 18.486,-18.499 0,-73.9698" /><path
-       inkscape:connector-curvature="0"
-       id="path214"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 4842.8799,4684.2698 18.4924,0 0,110.9548 -18.4924,0 0,-110.9548 z" /><path
-       inkscape:connector-curvature="0"
-       id="path216"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 4861.3789,4739.7407 295.8794,0 0,-110.9548 36.9849,0 0,110.9548 18.4859,0" /><path
-       inkscape:connector-curvature="0"
-       id="path218"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 5212.7291,4684.2698 18.4925,0 0,110.9548 -18.4925,0 0,-110.9548 z" /><path
-       inkscape:connector-curvature="0"
-       id="path220"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 5231.2281,4739.7407 166.4256,0" /><path
-       inkscape:connector-curvature="0"
-       id="path222"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 5416.1527,4795.2246 -36.9849,-110.9548" /><path
-       inkscape:connector-curvature="0"
-       id="path224"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 4473.0307,3870.6015 18.4924,0 0,110.9547 -18.4924,0 0,-110.9547 z" /><path
-       inkscape:connector-curvature="0"
-       id="path226"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 4491.5296,3926.0723 295.8794,0 0,-110.9547 36.9849,0 0,110.9547 18.486,0" /><path
-       inkscape:connector-curvature="0"
-       id="path228"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 4842.8799,3870.6015 18.4924,0 0,110.9547 -18.4924,0 0,-110.9547 z" /><path
-       inkscape:connector-curvature="0"
-       id="path230"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 4861.3789,3926.0723 295.8794,0 0,-110.9547 36.9849,0 0,110.9547 18.4859,0" /><path
-       inkscape:connector-curvature="0"
-       id="path232"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 5212.7291,3870.6015 18.4925,0 0,110.9547 -18.4925,0 0,-110.9547 z" /><path
-       inkscape:connector-curvature="0"
-       id="path234"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 5416.1527,3981.5562 -36.9849,-110.9547" /><path
-       inkscape:connector-curvature="0"
-       id="path236"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 5231.2281,3926.0723 166.4256,0" /><path
-       inkscape:connector-curvature="0"
-       id="path238"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 5453.1376,3981.5562 -36.9849,-110.9547" /><path
-       inkscape:connector-curvature="0"
-       id="path240"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 5434.6387,3926.0723 92.4688,0 0,-110.9547 36.9849,0 0,110.9547 18.486,0" /><path
-       inkscape:connector-curvature="0"
-       id="path242"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 5582.5784,3870.6015 18.4924,0 0,110.9547 -18.4924,0 0,-110.9547 z" /><path
-       inkscape:connector-curvature="0"
-       id="path244"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 5601.0773,3926.0723 295.8794,0 0,-110.9547 36.9849,0 0,110.9547 18.486,0" /><path
-       inkscape:connector-curvature="0"
-       id="path246"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 5952.4276,3870.6015 18.4924,0 0,110.9547 -18.4924,0 0,-110.9547 z" /><path
-       inkscape:connector-curvature="0"
-       id="path248"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 5970.9266,3926.0723 18.4859,0 0,73.9699 18.499,36.9849 18.4859,-36.9849 18.499,36.9849 18.486,-18.4859 18.4989,0 18.486,-36.985 18.499,55.4709 18.4859,-18.4859 0,36.9849 18.499,-18.499 18.4859,18.499 18.499,-36.9849 18.4859,18.4859 18.499,-55.4709 18.486,18.486 0,-73.9699" /><path
-       inkscape:connector-curvature="0"
-       id="path250"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 6248.307,4739.7407 18.499,0 0,-110.9548 36.9849,0 0,110.9548 18.4859,0" /><path
-       inkscape:connector-curvature="0"
-       id="path252"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 6248.307,3926.0723 18.499,0 0,-110.9547 36.9849,0 0,110.9547 18.4859,0" /><path
-       inkscape:connector-curvature="0"
-       id="path254"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 6322.2768,3870.6015 18.4925,0 0,110.9547 -18.4925,0 0,-110.9547 z" /><path
-       inkscape:connector-curvature="0"
-       id="path256"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 6322.2768,4684.2698 18.4925,0 0,110.9548 -18.4925,0 0,-110.9548 z" /><path
-       inkscape:connector-curvature="0"
-       id="path258"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 6340.7758,4739.7407 18.4859,0 0,55.4839 18.499,55.4708 18.486,-92.4558 18.4989,55.4709 18.486,0 18.499,55.4839 18.4859,-73.9698 18.499,36.9849 18.4859,-36.9849 36.985,73.9698 18.4989,-36.9849 18.486,36.9849 18.499,-55.4839 18.4859,36.9849 0,-110.9547 18.499,0" /><path
-       inkscape:connector-curvature="0"
-       id="path260"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 6340.7758,3926.0723 18.4859,0 0,129.4538 18.499,-18.499 18.486,18.499 18.4989,-36.9849 18.486,18.4859 18.499,-36.9849 18.4859,18.499 18.499,-18.499 18.4859,55.4839 18.499,-18.499 18.486,36.9849 18.4989,-73.9698 18.486,55.4839 18.499,-55.4839 18.4859,36.9849 0,-110.9548 18.499,0" /><path
-       inkscape:connector-curvature="0"
-       id="path262"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 6636.6552,4184.9668 0,-73.9698" /><path
-       inkscape:connector-curvature="0"
-       id="path264"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 6636.6552,4295.9216 0,-73.9699" /><path
-       inkscape:connector-curvature="0"
-       id="path266"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 6266.806,4998.6351 0,-73.9698" /><path
-       inkscape:connector-curvature="0"
-       id="path268"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 6266.806,5109.5899 0,-73.9699" /><path
-       inkscape:connector-curvature="0"
-       id="path270"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 6636.6552,4998.6351 0,-73.9698" /><path
-       inkscape:connector-curvature="0"
-       id="path272"
-       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       d="m 6636.6552,5109.5899 0,-73.9699" /><text
-       transform="scale(1,-1)"
-       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       id="text276"
-       x="3550.4165"
-       y="-4462.3472"><tspan
-	 x="3550.4165 3591.5437 3628.5286 3649.0923 3669.656 3690.2195 3706.6409 3747.7681 3764.1895"
-	 y="-4462.3472"
-	 sodipodi:role="line"
-	 id="tspan278">1st field</tspan><tspan
-	 x="2732.6792 3823.7344 4193.5835 4581.9253 4951.7744 5321.6235 3472.3777 3102.5283 2321.7029 2362.8303 2403.9575 1951.8538 1992.981 2034.1083 1582.0045 1623.132 1664.259 5670.9062 5712.0337"
-	 y="-4943.1509"
-	 sodipodi:role="line"
-	 id="tspan280">1456783231231131022</tspan><tspan
-	 x="2732.6726 3823.7278 4193.5771 4581.9189 4951.7681 5321.6172 3472.3711 3102.522 2321.6965 2362.8237 2403.9509 1951.8473 1992.9745 2034.1018 1581.998 1623.1254 1664.2524 5670.8999 5712.0269"
-	 y="-5054.1064"
-	 sodipodi:role="line"
-	 id="tspan282">1456783262562462322</tspan><tspan
-	 x="842.29962 883.42694 924.55408"
-	 y="-4943.1509"
-	 sodipodi:role="line"
-	 id="tspan284">308</tspan><tspan
-	 x="842.29962 883.42694 924.55408"
-	 y="-5054.1064"
-	 sodipodi:role="line"
-	 id="tspan286">621</tspan><tspan
-	 x="1212.1489 1253.276 1294.4033"
-	 y="-4943.1509"
-	 sodipodi:role="line"
-	 id="tspan288">309</tspan><tspan
-	 x="1212.1489 1253.276 1294.4033"
-	 y="-5054.1064"
-	 sodipodi:role="line"
-	 id="tspan290">622</tspan><tspan
-	 x="3538.0635 3579.1907 3620.3179 3661.4451 3682.0088 3702.5723 3718.9937 3760.1208 3776.5422"
-	 y="-3648.6792"
-	 sodipodi:role="line"
-	 id="tspan292">2nd field</tspan></text>
-<text
-       transform="scale(1,-1)"
-       style="font-variant:normal;font-weight:normal;font-size:61.64153671px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       id="text294"
-       x="2734.751"
-       y="-4037.021"><tspan
-	 x="2734.751 2755.2776 2789.5503"
-	 y="-4037.021"
-	 sodipodi:role="line"
-	 id="tspan296">(1)</tspan></text>
-<text
-       transform="scale(1,-1)"
-       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       id="text298"
-       x="4951.772"
-       y="-4129.4834"><tspan
-	 x="4951.772 4581.9229 4212.0737 3842.2244 3490.8677 3102.5259 2321.7004 2362.8276 2403.9551 1951.8512 1992.9785 2034.1057 1582.0022 1623.1293 1664.2563"
-	 y="-4129.4834"
-	 sodipodi:role="line"
-	 id="tspan300">765432313312311</tspan><tspan
-	 x="6020.1929 6061.3198 6102.4473 5650.3433 5691.4707 5732.5981 5280.4941 5321.6216 5362.7485 4910.645 4951.7725 4992.8994 4540.7959 4581.9229 4623.0503 4170.9468 4212.0737 4253.2012 3801.0974 3842.2246 3883.3518 3449.7405 3490.8677 3531.9951 3061.3989 3102.5261 3143.6533 2691.5496 2732.677 2773.8042 2321.7004 2362.8276 2403.9551 1951.8512 1992.9785 2034.1057 1582.0022 1623.1293 1664.2563"
-	 y="-4240.4385"
-	 sodipodi:role="line"
-	 id="tspan302">336335321320319318317316315314313312311</tspan><tspan
-	 x="2732.6765 5321.6211 5670.9062 5712.0337 6040.7554 6081.8828 842.30634 883.43323 924.56055"
-	 y="-4129.4834"
-	 sodipodi:role="line"
-	 id="tspan304">182223309</tspan><tspan
-	 x="842.30634 883.43323 924.56055"
-	 y="-4240.4385"
-	 sodipodi:role="line"
-	 id="tspan306">309</tspan><tspan
-	 x="1212.1553 1253.2826 1294.4099"
-	 y="-4129.4834"
-	 sodipodi:role="line"
-	 id="tspan308">310</tspan><tspan
-	 x="1212.1553 1253.2826 1294.4099"
-	 y="-4240.4385"
-	 sodipodi:role="line"
-	 id="tspan310">310</tspan><tspan
-	 x="6410.605 6451.7319"
-	 y="-4129.4834"
-	 sodipodi:role="line"
-	 id="tspan312">24</tspan><tspan
-	 x="6390.041 6431.1685 6472.2954"
-	 y="-4240.4385"
-	 sodipodi:role="line"
-	 id="tspan314">337</tspan><tspan
-	 x="6040.7559 6081.8833"
-	 y="-4943.1504"
-	 sodipodi:role="line"
-	 id="tspan316">23</tspan><tspan
-	 x="6040.7559 6081.8833"
-	 y="-5054.106"
-	 sodipodi:role="line"
-	 id="tspan318">23</tspan><tspan
-	 x="6410.605 6451.7324"
-	 y="-4943.1504"
-	 sodipodi:role="line"
-	 id="tspan320">24</tspan><tspan
-	 x="6410.605 6451.7324"
-	 y="-5054.106"
-	 sodipodi:role="line"
-	 id="tspan322">24</tspan></text>
-<text
-       transform="scale(1,-1)"
-       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       id="text3671"
-       x="3550.4165 3591.5437 3628.5286 3649.0923 3669.656 3690.2195 3706.6409 3747.7681 3764.1895"
-       y="-4462.3472"><tspan
-	 x="3550.4165 3591.5437 3628.5286 3649.0923 3669.656 3690.2195 3706.6409 3747.7681 3764.1895"
-	 y="-4462.3472"
-	 sodipodi:role="line"
-	 id="tspan3673">1st field</tspan></text>
-<text
-       transform="scale(1,-1)"
-       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       id="text3675"
-       x="2732.6792 3823.7344 4193.5835 4581.9253 4951.7744 5321.6235 3472.3777 3102.5283 2321.7029 2362.8303 2403.9575 1951.8538 1992.981 2034.1083 1582.0045 1623.132 1664.259 5670.9062 5712.0337"
-       y="-4943.1509"><tspan
-	 x="2732.6792 3823.7344 4193.5835 4581.9253 4951.7744 5321.6235 3472.3777 3102.5283 2321.7029 2362.8303 2403.9575 1951.8538 1992.981 2034.1083 1582.0045 1623.132 1664.259 5670.9062 5712.0337"
-	 y="-4943.1509"
-	 sodipodi:role="line"
-	 id="tspan3677">1456783231231131022</tspan></text>
-<text
-       transform="scale(1,-1)"
-       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       id="text3679"
-       x="2732.6726 3823.7278 4193.5771 4581.9189 4951.7681 5321.6172 3472.3711 3102.522 2321.6965 2362.8237 2403.9509 1951.8473 1992.9745 2034.1018 1581.998 1623.1254 1664.2524 5670.8999 5712.0269"
-       y="-5054.1064"><tspan
-	 x="2732.6726 3823.7278 4193.5771 4581.9189 4951.7681 5321.6172 3472.3711 3102.522 2321.6965 2362.8237 2403.9509 1951.8473 1992.9745 2034.1018 1581.998 1623.1254 1664.2524 5670.8999 5712.0269"
-	 y="-5054.1064"
-	 sodipodi:role="line"
-	 id="tspan3681">1456783262562462322</tspan></text>
-<text
-       transform="scale(1,-1)"
-       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       id="text3683"
-       x="842.29962 883.42694 924.55408"
-       y="-4943.1509"><tspan
-	 x="842.29962 883.42694 924.55408"
-	 y="-4943.1509"
-	 sodipodi:role="line"
-	 id="tspan3685">308</tspan></text>
-<text
-       transform="scale(1,-1)"
-       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       id="text3687"
-       x="842.29962 883.42694 924.55408"
-       y="-5054.1064"><tspan
-	 x="842.29962 883.42694 924.55408"
-	 y="-5054.1064"
-	 sodipodi:role="line"
-	 id="tspan3689">621</tspan></text>
-<text
-       transform="scale(1,-1)"
-       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       id="text3691"
-       x="1212.1489 1253.276 1294.4033"
-       y="-4943.1509"><tspan
-	 x="1212.1489 1253.276 1294.4033"
-	 y="-4943.1509"
-	 sodipodi:role="line"
-	 id="tspan3693">309</tspan></text>
-<text
-       transform="scale(1,-1)"
-       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       id="text3695"
-       x="1212.1489 1253.276 1294.4033"
-       y="-5054.1064"><tspan
-	 x="1212.1489 1253.276 1294.4033"
-	 y="-5054.1064"
-	 sodipodi:role="line"
-	 id="tspan3697">622</tspan></text>
-<text
-       transform="scale(1,-1)"
-       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       id="text3699"
-       x="3538.0635 3579.1907 3620.3179 3661.4451 3682.0088 3702.5723 3718.9937 3760.1208 3776.5422"
-       y="-3648.6792"><tspan
-	 x="3538.0635 3579.1907 3620.3179 3661.4451 3682.0088 3702.5723 3718.9937 3760.1208 3776.5422"
-	 y="-3648.6792"
-	 sodipodi:role="line"
-	 id="tspan3701">2nd field</tspan></text>
-<text
-       transform="scale(1,-1)"
-       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       id="text4083"
-       x="4951.772 4581.9229 4212.0737 3842.2244 3490.8677 3102.5259 2321.7004 2362.8276 2403.9551 1951.8512 1992.9785 2034.1057 1582.0022 1623.1293 1664.2563"
-       y="-4129.4834"><tspan
-	 x="4951.772 4581.9229 4212.0737 3842.2244 3490.8677 3102.5259 2321.7004 2362.8276 2403.9551 1951.8512 1992.9785 2034.1057 1582.0022 1623.1293 1664.2563"
-	 y="-4129.4834"
-	 sodipodi:role="line"
-	 id="tspan4085">765432313312311</tspan></text>
-<text
-       transform="scale(1,-1)"
-       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       id="text4087"
-       x="6020.1929 6061.3198 6102.4473 5650.3433 5691.4707 5732.5981 5280.4941 5321.6216 5362.7485 4910.645 4951.7725 4992.8994 4540.7959 4581.9229 4623.0503 4170.9468 4212.0737 4253.2012 3801.0974 3842.2246 3883.3518 3449.7405 3490.8677 3531.9951 3061.3989 3102.5261 3143.6533 2691.5496 2732.677 2773.8042 2321.7004 2362.8276 2403.9551 1951.8512 1992.9785 2034.1057 1582.0022 1623.1293 1664.2563"
-       y="-4240.4385"><tspan
-	 x="6020.1929 6061.3198 6102.4473 5650.3433 5691.4707 5732.5981 5280.4941 5321.6216 5362.7485 4910.645 4951.7725 4992.8994 4540.7959 4581.9229 4623.0503 4170.9468 4212.0737 4253.2012 3801.0974 3842.2246 3883.3518 3449.7405 3490.8677 3531.9951 3061.3989 3102.5261 3143.6533 2691.5496 2732.677 2773.8042 2321.7004 2362.8276 2403.9551 1951.8512 1992.9785 2034.1057 1582.0022 1623.1293 1664.2563"
-	 y="-4240.4385"
-	 sodipodi:role="line"
-	 id="tspan4089">336335321320319318317316315314313312311</tspan></text>
-<text
-       transform="scale(1,-1)"
-       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       id="text4091"
-       x="2732.6765 5321.6211 5670.9062 5712.0337 6040.7554 6081.8828 842.30634 883.43323 924.56055"
-       y="-4129.4834"><tspan
-	 x="2732.6765 5321.6211 5670.9062 5712.0337 6040.7554 6081.8828 842.30634 883.43323 924.56055"
-	 y="-4129.4834"
-	 sodipodi:role="line"
-	 id="tspan4093">182223309</tspan></text>
-<text
-       transform="scale(1,-1)"
-       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       id="text4095"
-       x="842.30634 883.43323 924.56055"
-       y="-4240.4385"><tspan
-	 x="842.30634 883.43323 924.56055"
-	 y="-4240.4385"
-	 sodipodi:role="line"
-	 id="tspan4097">309</tspan></text>
-<text
-       transform="scale(1,-1)"
-       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       id="text4099"
-       x="1212.1553 1253.2826 1294.4099"
-       y="-4129.4834"><tspan
-	 x="1212.1553 1253.2826 1294.4099"
-	 y="-4129.4834"
-	 sodipodi:role="line"
-	 id="tspan4101">310</tspan></text>
-<text
-       transform="scale(1,-1)"
-       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       id="text4103"
-       x="1212.1553 1253.2826 1294.4099"
-       y="-4240.4385"><tspan
-	 x="1212.1553 1253.2826 1294.4099"
-	 y="-4240.4385"
-	 sodipodi:role="line"
-	 id="tspan4105">310</tspan></text>
-<text
-       transform="scale(1,-1)"
-       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       id="text4107"
-       x="6410.605 6451.7319"
-       y="-4129.4834"><tspan
-	 x="6410.605 6451.7319"
-	 y="-4129.4834"
-	 sodipodi:role="line"
-	 id="tspan4109">24</tspan></text>
-<text
-       transform="scale(1,-1)"
-       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       id="text4111"
-       x="6390.041 6431.1685 6472.2954"
-       y="-4240.4385"><tspan
-	 x="6390.041 6431.1685 6472.2954"
-	 y="-4240.4385"
-	 sodipodi:role="line"
-	 id="tspan4113">337</tspan></text>
-<text
-       transform="scale(1,-1)"
-       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       id="text4115"
-       x="6040.7559 6081.8833"
-       y="-4943.1504"><tspan
-	 x="6040.7559 6081.8833"
-	 y="-4943.1504"
-	 sodipodi:role="line"
-	 id="tspan4117">23</tspan></text>
-<text
-       transform="scale(1,-1)"
-       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       id="text4119"
-       x="6040.7559 6081.8833"
-       y="-5054.106"><tspan
-	 x="6040.7559 6081.8833"
-	 y="-5054.106"
-	 sodipodi:role="line"
-	 id="tspan4121">23</tspan></text>
-<text
-       transform="scale(1,-1)"
-       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       id="text4123"
-       x="6410.605 6451.7324"
-       y="-4943.1504"><tspan
-	 x="6410.605 6451.7324"
-	 y="-4943.1504"
-	 sodipodi:role="line"
-	 id="tspan4125">24</tspan></text>
-<text
-       transform="scale(1,-1)"
-       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       id="text4127"
-       x="6410.605 6451.7324"
-       y="-5054.106"><tspan
-	 x="6410.605 6451.7324"
-	 y="-5054.106"
-	 sodipodi:role="line"
-	 id="tspan4129">24</tspan></text>
-</g></svg>
diff --git a/Documentation/media/uapi/v4l/vbi_hsync.svg b/Documentation/media/uapi/v4l/vbi_hsync.svg
deleted file mode 100644
index f8e979ada7e3..000000000000
--- a/Documentation/media/uapi/v4l/vbi_hsync.svg
+++ /dev/null
@@ -1,321 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!--
-    Permission is granted to copy, distribute and/or modify this
-    document under the terms of the GNU Free Documentation License,
-    Version 1.1 or any later version published by the Free Software
-    Foundation, with no Invariant Sections, no Front-Cover Texts
-    and no Back-Cover Texts. A copy of the license is included at
-    Documentation/media/uapi/fdl-appendix.rst.
-
-    TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
--->
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   id="svg2"
-   version="1.1"
-   inkscape:version="0.91 r13725"
-   xml:space="preserve"
-   width="192.39857mm"
-   height="146.83536mm"
-   viewBox="0 0 681.72724 520.28277"
-   sodipodi:docname="vbi_hsync.svg"><sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="1920"
-     inkscape:window-height="997"
-     id="namedview4"
-     showgrid="false"
-     inkscape:zoom="1.5350601"
-     inkscape:cx="131.95463"
-     inkscape:cy="428.88132"
-     inkscape:window-x="1920"
-     inkscape:window-y="30"
-     inkscape:window-maximized="1"
-     inkscape:current-layer="g10"
-     units="mm"
-     fit-margin-top="0"
-     fit-margin-left="0"
-     fit-margin-right="0"
-     fit-margin-bottom="0" /><metadata
-     id="metadata8"><rdf:RDF><cc:Work
-	 rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
-	   rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
-     id="defs6"><clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath30"><path
-	 d="m 0,0 0,1163 1544,0 L 1544,0 0,0 Z m 187.184,836.05 0,-19.278 48.517,0 -38.556,9.639 38.556,9.639 -48.517,0 z m 689.189,-19.278 0,19.278 -48.516,0 38.556,-9.639 -38.556,-9.639 48.516,0 z"
-	 id="path32"
-	 inkscape:connector-curvature="0"
-	 style="clip-rule:evenodd" /></clipPath><clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath52"><path
-	 d="m 0,0 0,1163 1544,0 L 1544,0 0,0 Z m 804.08,79.3887 0,19.2778 -48.516,0 38.556,-9.6389 -38.556,-9.6389 48.516,0 z m -703.647,19.2778 0,-19.2778 48.517,0 -38.556,9.6389 38.556,9.6389 -48.517,0 z"
-	 id="path54"
-	 inkscape:connector-curvature="0"
-	 style="clip-rule:evenodd" /></clipPath><clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath94"><path
-	 d="m 0,0 0,1163 1544,0 L 1544,0 0,0 Z m 471.535,195.057 0,19.278 -48.516,0 38.555,-9.639 -38.555,-9.639 48.516,0 z m -284.351,19.278 0,-19.278 48.517,0 -38.556,9.639 38.556,9.639 -48.517,0 z"
-	 id="path96"
-	 inkscape:connector-curvature="0"
-	 style="clip-rule:evenodd" /></clipPath></defs><g
-     id="g10"
-     inkscape:groupmode="layer"
-     inkscape:label="vbi_hsync"
-     transform="matrix(1.25,0,0,-1.25,-0.3625824,520.79867)"><g
-       id="g14"
-       transform="matrix(0.36030235,0,0,0.36030235,-0.75498483,-1.0743684)"
-       style=""><path
-	 inkscape:connector-curvature="0"
-	 id="path16"
-	 style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="M 32.9604,580.617 4.04346,493.866" /><path
-	 inkscape:connector-curvature="0"
-	 id="path18"
-	 style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 192.004,855.328 0,-665.091" /><path
-	 inkscape:connector-curvature="0"
-	 id="path20"
-	 style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 466.715,392.656 0,-202.419" /><path
-	 inkscape:connector-curvature="0"
-	 id="path22"
-	 style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 799.261,508.324 0,-433.7549" /><path
-	 inkscape:connector-curvature="0"
-	 id="path24"
-	 style="fill:none;stroke:#000000;stroke-width:4.81949997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 857.095,537.241 231.335,0" /></g><g
-       id="g26"
-       transform="matrix(0.36030235,0,0,0.36030235,-0.75498483,-1.0743684)"
-       style=""><g
-	 clip-path="url(#clipPath30)"
-	 id="g28"
-	 style=""><path
-	   inkscape:connector-curvature="0"
-	   id="path34"
-	   style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	   d="m 871.553,826.411 -679.549,0" /></g></g><g
-       id="g36"
-       transform="matrix(0.36030235,0,0,0.36030235,-0.75498483,-1.0743684)"
-       style=""><path
-	 inkscape:connector-curvature="0"
-	 id="path38"
-	 style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-	 d="m 827.857,816.772 38.556,9.639 -38.556,9.639 0,-19.278" /><path
-	 inkscape:connector-curvature="0"
-	 id="path40"
-	 style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 827.857,816.772 38.556,9.639 -38.556,9.639 0,-19.278 z" /><path
-	 inkscape:connector-curvature="0"
-	 id="path42"
-	 style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-	 d="m 235.701,836.05 -38.556,-9.639 38.556,-9.639 0,19.278" /><path
-	 inkscape:connector-curvature="0"
-	 id="path44"
-	 style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 235.701,836.05 -38.556,-9.639 38.556,-9.639 0,19.278 z" /><path
-	 inkscape:connector-curvature="0"
-	 id="path46"
-	 style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	 d="m 1073.97,493.866 28.92,86.751" /></g><g
-       id="g48"
-       transform="matrix(0.36030235,0,0,0.36030235,-0.75498483,-1.0743684)"
-       style=""><g
-	 clip-path="url(#clipPath52)"
-	 id="g50"
-	 style=""><path
-	   inkscape:connector-curvature="0"
-	   id="path56"
-	   style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	   d="m 105.253,89.0276 694.008,0" /></g></g><path
-       d="m 52.91205,34.475403 -13.891817,-3.472918 13.891817,-3.472918 0,6.945836"
-       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path60"
-       inkscape:connector-curvature="0" /><path
-       d="m 52.91205,34.475403 -13.891817,-3.472918 13.891817,-3.472918 0,6.945836 z"
-       style="fill:none;stroke:#000000;stroke-width:0.86823857;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path62"
-       inkscape:connector-curvature="0" /><path
-       d="m 271.4765,27.529567 13.89182,3.472918 -13.89182,3.472918 0,-6.945836"
-       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path64"
-       inkscape:connector-curvature="0" /><path
-       d="m 271.4765,27.529567 13.89182,3.472918 -13.89182,3.472918 0,-6.945836 z"
-       style="fill:none;stroke:#000000;stroke-width:0.86823857;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path66"
-       inkscape:connector-curvature="0" /><path
-       d="m 5.9113292,192.49483 31.2565888,0 0,-10.41887 26.046978,0 10.418863,-93.769765 88.560511,0 10.41887,93.769765 10.41886,0"
-       style="fill:none;stroke:#000000;stroke-width:1.73647714;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path68"
-       inkscape:connector-curvature="0" /><path
-       d="m 162.19427,88.306195 260.47086,0"
-       style="fill:none;stroke:#000000;stroke-width:0.86823857;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path70"
-       inkscape:connector-curvature="0" /><path
-       d="m 37.167918,182.07596 0,-156.282907"
-       style="fill:none;stroke:#000000;stroke-width:0.86823857;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path72"
-       inkscape:connector-curvature="0" /><path
-       d="m 235.12632,182.07596 52.09431,0 0,10.41887 20.83773,0 10.41886,208.3769 83.35162,0"
-       style="fill:none;stroke:#000000;stroke-width:1.73647714;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path74"
-       inkscape:connector-curvature="0" /><path
-       d="m 391.4089,192.49483 31.25623,0"
-       style="fill:none;stroke:#000000;stroke-width:0.86823857;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path76"
-       inkscape:connector-curvature="0" /><path
-       d="m 401.82884,400.87173 20.83629,0"
-       style="fill:none;stroke:#000000;stroke-width:0.86823857;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path78"
-       inkscape:connector-curvature="0" /><path
-       d="m 328.89608,192.49483 10.41887,208.3769"
-       style="fill:none;stroke:#000000;stroke-width:0.86823857;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path80"
-       inkscape:connector-curvature="0" /><path
-       d="m 349.73381,192.49483 10.41886,208.3769"
-       style="fill:none;stroke:#000000;stroke-width:0.86823857;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path82"
-       inkscape:connector-curvature="0" /><path
-       d="m 370.57262,192.49483 10.41634,208.3769"
-       style="fill:none;stroke:#000000;stroke-width:0.86823857;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path84"
-       inkscape:connector-curvature="0" /><path
-       d="m 396.61887,385.24541 10.41995,31.25623"
-       style="fill:none;stroke:#000000;stroke-width:0.86823857;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path86"
-       inkscape:connector-curvature="0" /><path
-       d="m 183.032,135.19126 52.09432,0 0,93.76977 -52.09432,0 0,-93.76977 z"
-       style="fill:none;stroke:#000000;stroke-width:1.73647714;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path88"
-       inkscape:connector-curvature="0" /><g
-       id="g90"
-       transform="matrix(0.36030235,0,0,0.36030235,-0.75498483,-1.0743684)"
-       style=""><g
-	 clip-path="url(#clipPath94)"
-	 id="g92"
-	 style=""><path
-	   inkscape:connector-curvature="0"
-	   id="path98"
-	   style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-	   d="m 192.004,204.696 274.711,0" /></g></g><path
-       d="m 84.168639,76.151036 -13.891817,-3.472955 13.891817,-3.472954 0,6.945909"
-       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path102"
-       inkscape:connector-curvature="0" /><path
-       d="m 84.168639,76.151036 -13.891817,-3.472955 13.891817,-3.472954 0,6.945909 z"
-       style="fill:none;stroke:#000000;stroke-width:0.86823857;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path104"
-       inkscape:connector-curvature="0" /><path
-       d="m 151.65975,69.205127 13.89146,3.472954 -13.89146,3.472955 0,-6.945909"
-       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="path106"
-       inkscape:connector-curvature="0" /><path
-       d="m 151.65975,69.205127 13.89146,3.472954 -13.89146,3.472955 0,-6.945909 z"
-       style="fill:none;stroke:#000000;stroke-width:0.86823857;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-       id="path108"
-       inkscape:connector-curvature="0" /><text
-       id="text112"
-       style="font-variant:normal;font-weight:normal;font-size:20.83772659px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"
-       x="438.29504"
-       y="-187.28558"><tspan
-	 id="tspan114"
-	 sodipodi:role="line"
-	 y="-187.28558"
-	 x="438.29504 452.19382 456.81979 468.40555 478.82443 489.24329 495.03619 506.62195 518.2077 528.62659 540.21234">Black Level</tspan><tspan
-	 id="tspan116"
-	 sodipodi:role="line"
-	 y="-83.096947"
-	 x="438.29504 452.19382 462.61267 474.19846 484.61731 490.41019 501.99597 513.58173 524.00061 535.58636">Sync Level</tspan><tspan
-	 id="tspan118"
-	 sodipodi:role="line"
-	 y="-395.66284"
-	 x="438.29504 457.96585 469.55164 474.17761 479.97049 491.55627 497.34915 508.93494 520.52069 530.93958 542.52533">White Level</tspan></text>
-<text
-       id="text120"
-       style="font-variant:normal;font-weight:normal;font-size:20.83772659px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"
-       x="159.88258"
-       y="-270.63647"><tspan
-	 id="tspan122"
-	 sodipodi:role="line"
-	 y="-270.63647"
-	 x="159.88258 172.61443 179.55339 186.49236 198.07812 209.66391">offset</tspan></text>
-<text
-       id="text124"
-       style="font-variant:normal;font-weight:normal;font-size:20.83772659px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"
-       x="46.973549"
-       y="-46.630745"><tspan
-	 id="tspan126"
-	 sodipodi:role="line"
-	 y="-46.630745"
-	 x="46.973549 58.559322 63.185299 74.771072 86.35685 92.149734 102.5686 112.98746 124.57324 134.9921 146.57788 153.51685 159.30972 165.10262 176.68839 188.27417 192.90015 203.319">Line synchr. pulse</tspan><tspan
-	 id="tspan128"
-	 sodipodi:role="line"
-	 y="-4.9552913"
-	 x="100.80776 112.39354 117.01952 128.60529 140.19107 145.98395 157.56973 162.19569 173.78148 185.36726 195.78612 200.41209 211.99788">Line blanking</tspan></text>
-<text
-       id="text3473"
-       style="font-variant:normal;font-weight:normal;font-size:20.83772659px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"
-       x="46.973549 58.559322 63.185299 74.771072 86.35685 92.149734 102.5686 112.98746 124.57324 134.9921 146.57788 153.51685 159.30972 165.10262 176.68839 188.27417 192.90015 203.319"
-       y="-46.630745"><tspan
-	 id="tspan3475"
-	 sodipodi:role="line"
-	 y="-46.630745"
-	 x="46.973549 58.559322 63.185299 74.771072 86.35685 92.149734 102.5686 112.98746 124.57324 134.9921 146.57788 153.51685 159.30972 165.10262 176.68839 188.27417 192.90015 203.319">Line synchr. pulse</tspan></text>
-<text
-       id="text3477"
-       style="font-variant:normal;font-weight:normal;font-size:20.83772659px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"
-       x="100.80776 112.39354 117.01952 128.60529 140.19107 145.98395 157.56973 162.19569 173.78148 185.36726 195.78612 200.41209 211.99788"
-       y="-4.9552913"><tspan
-	 id="tspan3479"
-	 sodipodi:role="line"
-	 y="-4.9552913"
-	 x="100.80776 112.39354 117.01952 128.60529 140.19107 145.98395 157.56973 162.19569 173.78148 185.36726 195.78612 200.41209 211.99788">Line blanking</tspan></text>
-<text
-       id="text3607"
-       style="font-variant:normal;font-weight:normal;font-size:20.83772659px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"
-       x="438.29504 452.19382 456.81979 468.40555 478.82443 489.24329 495.03619 506.62195 518.2077 528.62659 540.21234"
-       y="-187.28558"><tspan
-	 id="tspan3609"
-	 sodipodi:role="line"
-	 y="-187.28558"
-	 x="438.29504 452.19382 456.81979 468.40555 478.82443 489.24329 495.03619 506.62195 518.2077 528.62659 540.21234">Black Level</tspan></text>
-<text
-       id="text3611"
-       style="font-variant:normal;font-weight:normal;font-size:20.83772659px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"
-       x="438.29504 452.19382 462.61267 474.19846 484.61731 490.41019 501.99597 513.58173 524.00061 535.58636"
-       y="-83.096947"><tspan
-	 id="tspan3613"
-	 sodipodi:role="line"
-	 y="-83.096947"
-	 x="438.29504 452.19382 462.61267 474.19846 484.61731 490.41019 501.99597 513.58173 524.00061 535.58636">Sync Level</tspan></text>
-<text
-       id="text3615"
-       style="font-variant:normal;font-weight:normal;font-size:20.83772659px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
-       transform="scale(1,-1)"
-       x="438.29504 457.96585 469.55164 474.17761 479.97049 491.55627 497.34915 508.93494 520.52069 530.93958 542.52533"
-       y="-395.66284"><tspan
-	 id="tspan3617"
-	 sodipodi:role="line"
-	 y="-395.66284"
-	 x="438.29504 457.96585 469.55164 474.17761 479.97049 491.55627 497.34915 508.93494 520.52069 530.93958 542.52533">White Level</tspan></text>
-</g></svg>
diff --git a/Documentation/media/uapi/v4l/video.rst b/Documentation/media/uapi/v4l/video.rst
deleted file mode 100644
index 69603b5efbb5..000000000000
--- a/Documentation/media/uapi/v4l/video.rst
+++ /dev/null
@@ -1,75 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _video:
-
-************************
-Video Inputs and Outputs
-************************
-
-Video inputs and outputs are physical connectors of a device. These can
-be for example: RF connectors (antenna/cable), CVBS a.k.a. Composite
-Video, S-Video and RGB connectors. Camera sensors are also considered to
-be a video input. Video and VBI capture devices have inputs. Video and
-VBI output devices have outputs, at least one each. Radio devices have
-no video inputs or outputs.
-
-To learn about the number and attributes of the available inputs and
-outputs applications can enumerate them with the
-:ref:`VIDIOC_ENUMINPUT` and
-:ref:`VIDIOC_ENUMOUTPUT` ioctl, respectively. The
-struct :c:type:`v4l2_input` returned by the
-:ref:`VIDIOC_ENUMINPUT` ioctl also contains signal
-status information applicable when the current video input is queried.
-
-The :ref:`VIDIOC_G_INPUT <VIDIOC_G_INPUT>` and
-:ref:`VIDIOC_G_OUTPUT <VIDIOC_G_OUTPUT>` ioctls return the index of
-the current video input or output. To select a different input or output
-applications call the :ref:`VIDIOC_S_INPUT <VIDIOC_G_INPUT>` and
-:ref:`VIDIOC_S_OUTPUT <VIDIOC_G_OUTPUT>` ioctls. Drivers must
-implement all the input ioctls when the device has one or more inputs,
-all the output ioctls when the device has one or more outputs.
-
-Example: Information about the current video input
-==================================================
-
-.. code-block:: c
-
-    struct v4l2_input input;
-    int index;
-
-    if (-1 == ioctl(fd, VIDIOC_G_INPUT, &index)) {
-	perror("VIDIOC_G_INPUT");
-	exit(EXIT_FAILURE);
-    }
-
-    memset(&input, 0, sizeof(input));
-    input.index = index;
-
-    if (-1 == ioctl(fd, VIDIOC_ENUMINPUT, &input)) {
-	perror("VIDIOC_ENUMINPUT");
-	exit(EXIT_FAILURE);
-    }
-
-    printf("Current input: %s\\n", input.name);
-
-
-Example: Switching to the first video input
-===========================================
-
-.. code-block:: c
-
-    int index;
-
-    index = 0;
-
-    if (-1 == ioctl(fd, VIDIOC_S_INPUT, &index)) {
-	perror("VIDIOC_S_INPUT");
-	exit(EXIT_FAILURE);
-    }
diff --git a/Documentation/media/uapi/v4l/videodev.rst b/Documentation/media/uapi/v4l/videodev.rst
deleted file mode 100644
index fa3d3398930a..000000000000
--- a/Documentation/media/uapi/v4l/videodev.rst
+++ /dev/null
@@ -1,16 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _videodev:
-
-*******************************
-Video For Linux Two Header File
-*******************************
-
-.. kernel-include:: $BUILDDIR/videodev2.h.rst
diff --git a/Documentation/media/uapi/v4l/vidioc-create-bufs.rst b/Documentation/media/uapi/v4l/vidioc-create-bufs.rst
deleted file mode 100644
index bd08e4f77ae4..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-create-bufs.rst
+++ /dev/null
@@ -1,141 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_CREATE_BUFS:
-
-************************
-ioctl VIDIOC_CREATE_BUFS
-************************
-
-Name
-====
-
-VIDIOC_CREATE_BUFS - Create buffers for Memory Mapped or User Pointer or DMA Buffer I/O
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_CREATE_BUFS, struct v4l2_create_buffers *argp )
-    :name: VIDIOC_CREATE_BUFS
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_create_buffers`.
-
-
-Description
-===========
-
-This ioctl is used to create buffers for :ref:`memory mapped <mmap>`
-or :ref:`user pointer <userp>` or :ref:`DMA buffer <dmabuf>` I/O. It
-can be used as an alternative or in addition to the
-:ref:`VIDIOC_REQBUFS` ioctl, when a tighter control
-over buffers is required. This ioctl can be called multiple times to
-create buffers of different sizes.
-
-To allocate the device buffers applications must initialize the relevant
-fields of the struct :c:type:`v4l2_create_buffers` structure. The
-``count`` field must be set to the number of requested buffers, the
-``memory`` field specifies the requested I/O method and the ``reserved``
-array must be zeroed.
-
-The ``format`` field specifies the image format that the buffers must be
-able to handle. The application has to fill in this struct
-:c:type:`v4l2_format`. Usually this will be done using the
-:ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` or
-:ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` ioctls to ensure that the
-requested format is supported by the driver. Based on the format's
-``type`` field the requested buffer size (for single-planar) or plane
-sizes (for multi-planar formats) will be used for the allocated buffers.
-The driver may return an error if the size(s) are not supported by the
-hardware (usually because they are too small).
-
-The buffers created by this ioctl will have as minimum size the size
-defined by the ``format.pix.sizeimage`` field (or the corresponding
-fields for other format types). Usually if the ``format.pix.sizeimage``
-field is less than the minimum required for the given format, then an
-error will be returned since drivers will typically not allow this. If
-it is larger, then the value will be used as-is. In other words, the
-driver may reject the requested size, but if it is accepted the driver
-will use it unchanged.
-
-When the ioctl is called with a pointer to this structure the driver
-will attempt to allocate up to the requested number of buffers and store
-the actual number allocated and the starting index in the ``count`` and
-the ``index`` fields respectively. On return ``count`` can be smaller
-than the number requested.
-
-
-.. c:type:: v4l2_create_buffers
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. flat-table:: struct v4l2_create_buffers
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``index``
-      - The starting buffer index, returned by the driver.
-    * - __u32
-      - ``count``
-      - The number of buffers requested or granted. If count == 0, then
-	:ref:`VIDIOC_CREATE_BUFS` will set ``index`` to the current number of
-	created buffers, and it will check the validity of ``memory`` and
-	``format.type``. If those are invalid -1 is returned and errno is
-	set to ``EINVAL`` error code, otherwise :ref:`VIDIOC_CREATE_BUFS` returns
-	0. It will never set errno to ``EBUSY`` error code in this particular
-	case.
-    * - __u32
-      - ``memory``
-      - Applications set this field to ``V4L2_MEMORY_MMAP``,
-	``V4L2_MEMORY_DMABUF`` or ``V4L2_MEMORY_USERPTR``. See
-	:c:type:`v4l2_memory`
-    * - struct :c:type:`v4l2_format`
-      - ``format``
-      - Filled in by the application, preserved by the driver.
-    * - __u32
-      - ``capabilities``
-      - Set by the driver. If 0, then the driver doesn't support
-        capabilities. In that case all you know is that the driver is
-	guaranteed to support ``V4L2_MEMORY_MMAP`` and *might* support
-	other :c:type:`v4l2_memory` types. It will not support any others
-	capabilities. See :ref:`here <v4l2-buf-capabilities>` for a list of the
-	capabilities.
-
-	If you want to just query the capabilities without making any
-	other changes, then set ``count`` to 0, ``memory`` to
-	``V4L2_MEMORY_MMAP`` and ``format.type`` to the buffer type.
-    * - __u32
-      - ``reserved``\ [7]
-      - A place holder for future extensions. Drivers and applications
-	must set the array to zero.
-
-
-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.
-
-ENOMEM
-    No memory to allocate buffers for :ref:`memory mapped <mmap>` I/O.
-
-EINVAL
-    The buffer type (``format.type`` field), requested I/O method
-    (``memory``) or format (``format`` field) is not valid.
diff --git a/Documentation/media/uapi/v4l/vidioc-cropcap.rst b/Documentation/media/uapi/v4l/vidioc-cropcap.rst
deleted file mode 100644
index 019d3d3a0e0d..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-cropcap.rst
+++ /dev/null
@@ -1,143 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_CROPCAP:
-
-********************
-ioctl VIDIOC_CROPCAP
-********************
-
-Name
-====
-
-VIDIOC_CROPCAP - Information about the video cropping and scaling abilities
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_CROPCAP, struct v4l2_cropcap *argp )
-    :name: VIDIOC_CROPCAP
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_cropcap`.
-
-
-Description
-===========
-
-Applications use this function to query the cropping limits, the pixel
-aspect of images and to calculate scale factors. They set the ``type``
-field of a v4l2_cropcap structure to the respective buffer (stream)
-type and call the :ref:`VIDIOC_CROPCAP` ioctl with a pointer to this
-structure. Drivers fill the rest of the structure. The results are
-constant except when switching the video standard. Remember this switch
-can occur implicit when switching the video input or output.
-
-This ioctl must be implemented for video capture or output devices that
-support cropping and/or scaling and/or have non-square pixels, and for
-overlay devices.
-
-.. c:type:: v4l2_cropcap
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. flat-table:: struct v4l2_cropcap
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``type``
-      - Type of the data stream, set by the application. Only these types
-	are valid here: ``V4L2_BUF_TYPE_VIDEO_CAPTURE``, ``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE``,
-	``V4L2_BUF_TYPE_VIDEO_OUTPUT``, ``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE`` and
-	``V4L2_BUF_TYPE_VIDEO_OVERLAY``. See :c:type:`v4l2_buf_type` and the note below.
-    * - struct :ref:`v4l2_rect <v4l2-rect-crop>`
-      - ``bounds``
-      - Defines the window within capturing or output is possible, this
-	may exclude for example the horizontal and vertical blanking
-	areas. The cropping rectangle cannot exceed these limits. Width
-	and height are defined in pixels, the driver writer is free to
-	choose origin and units of the coordinate system in the analog
-	domain.
-    * - struct :ref:`v4l2_rect <v4l2-rect-crop>`
-      - ``defrect``
-      - Default cropping rectangle, it shall cover the "whole picture".
-	Assuming pixel aspect 1/1 this could be for example a 640 × 480
-	rectangle for NTSC, a 768 × 576 rectangle for PAL and SECAM
-	centered over the active picture area. The same co-ordinate system
-	as for ``bounds`` is used.
-    * - struct :c:type:`v4l2_fract`
-      - ``pixelaspect``
-      - This is the pixel aspect (y / x) when no scaling is applied, the
-	ratio of the actual sampling frequency and the frequency required
-	to get square pixels.
-
-	When cropping coordinates refer to square pixels, the driver sets
-	``pixelaspect`` to 1/1. Other common values are 54/59 for PAL and
-	SECAM, 11/10 for NTSC sampled according to [:ref:`itu601`].
-
-.. note::
-   Unfortunately in the case of multiplanar buffer types
-   (``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE`` and ``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE``)
-   this API was messed up with regards to how the :c:type:`v4l2_cropcap` ``type`` field
-   should be filled in. Some drivers only accepted the ``_MPLANE`` buffer type while
-   other drivers only accepted a non-multiplanar buffer type (i.e. without the
-   ``_MPLANE`` at the end).
-
-   Starting with kernel 4.13 both variations are allowed.
-
-
-
-.. _v4l2-rect-crop:
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. flat-table:: struct v4l2_rect
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __s32
-      - ``left``
-      - Horizontal offset of the top, left corner of the rectangle, in
-	pixels.
-    * - __s32
-      - ``top``
-      - Vertical offset of the top, left corner of the rectangle, in
-	pixels.
-    * - __u32
-      - ``width``
-      - Width of the rectangle, in pixels.
-    * - __u32
-      - ``height``
-      - Height of the rectangle, in pixels.
-
-
-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
-    The struct :c:type:`v4l2_cropcap` ``type`` is
-    invalid.
-
-ENODATA
-    Cropping is not supported for this input or output.
diff --git a/Documentation/media/uapi/v4l/vidioc-dbg-g-chip-info.rst b/Documentation/media/uapi/v4l/vidioc-dbg-g-chip-info.rst
deleted file mode 100644
index d38031dbe4e4..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-dbg-g-chip-info.rst
+++ /dev/null
@@ -1,167 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_DBG_G_CHIP_INFO:
-
-****************************
-ioctl VIDIOC_DBG_G_CHIP_INFO
-****************************
-
-Name
-====
-
-VIDIOC_DBG_G_CHIP_INFO - Identify the chips on a TV card
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_DBG_G_CHIP_INFO, struct v4l2_dbg_chip_info *argp )
-    :name: VIDIOC_DBG_G_CHIP_INFO
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_dbg_chip_info`.
-
-
-Description
-===========
-
-.. note::
-
-    This is an :ref:`experimental` interface and may
-    change in the future.
-
-For driver debugging purposes this ioctl allows test applications to
-query the driver about the chips present on the TV card. Regular
-applications must not use it. When you found a chip specific bug, please
-contact the linux-media mailing list
-(`https://linuxtv.org/lists.php <https://linuxtv.org/lists.php>`__)
-so it can be fixed.
-
-Additionally the Linux kernel must be compiled with the
-``CONFIG_VIDEO_ADV_DEBUG`` option to enable this ioctl.
-
-To query the driver applications must initialize the ``match.type`` and
-``match.addr`` or ``match.name`` fields of a struct
-:c:type:`v4l2_dbg_chip_info` and call
-:ref:`VIDIOC_DBG_G_CHIP_INFO` with a pointer to this structure. On success
-the driver stores information about the selected chip in the ``name``
-and ``flags`` fields.
-
-When ``match.type`` is ``V4L2_CHIP_MATCH_BRIDGE``, ``match.addr``
-selects the nth bridge 'chip' on the TV card. You can enumerate all
-chips by starting at zero and incrementing ``match.addr`` by one until
-:ref:`VIDIOC_DBG_G_CHIP_INFO` fails with an ``EINVAL`` error code. The number
-zero always selects the bridge chip itself, e. g. the chip connected to
-the PCI or USB bus. Non-zero numbers identify specific parts of the
-bridge chip such as an AC97 register block.
-
-When ``match.type`` is ``V4L2_CHIP_MATCH_SUBDEV``, ``match.addr``
-selects the nth sub-device. This allows you to enumerate over all
-sub-devices.
-
-On success, the ``name`` field will contain a chip name and the
-``flags`` field will contain ``V4L2_CHIP_FL_READABLE`` if the driver
-supports reading registers from the device or ``V4L2_CHIP_FL_WRITABLE``
-if the driver supports writing registers to the device.
-
-We recommended the v4l2-dbg utility over calling this ioctl directly. It
-is available from the LinuxTV v4l-dvb repository; see
-`https://linuxtv.org/repo/ <https://linuxtv.org/repo/>`__ for access
-instructions.
-
-
-.. tabularcolumns:: |p{3.5cm}|p{3.5cm}|p{3.5cm}|p{7.0cm}|
-
-.. _name-v4l2-dbg-match:
-
-.. flat-table:: struct v4l2_dbg_match
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``type``
-      - See :ref:`name-chip-match-types` for a list of possible types.
-    * - union {
-      - (anonymous)
-    * - __u32
-      - ``addr``
-      - Match a chip by this number, interpreted according to the ``type``
-	field.
-    * - char
-      - ``name[32]``
-      - Match a chip by this name, interpreted according to the ``type``
-	field. Currently unused.
-    * - }
-      -
-
-
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. c:type:: v4l2_dbg_chip_info
-
-.. flat-table:: struct v4l2_dbg_chip_info
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - struct v4l2_dbg_match
-      - ``match``
-      - How to match the chip, see :ref:`name-v4l2-dbg-match`.
-    * - char
-      - ``name[32]``
-      - The name of the chip.
-    * - __u32
-      - ``flags``
-      - Set by the driver. If ``V4L2_CHIP_FL_READABLE`` is set, then the
-	driver supports reading registers from the device. If
-	``V4L2_CHIP_FL_WRITABLE`` is set, then it supports writing
-	registers.
-    * - __u32
-      - ``reserved[8]``
-      - Reserved fields, both application and driver must set these to 0.
-
-
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. _name-chip-match-types:
-
-.. flat-table:: Chip Match Types
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_CHIP_MATCH_BRIDGE``
-      - 0
-      - Match the nth chip on the card, zero for the bridge chip. Does not
-	match sub-devices.
-    * - ``V4L2_CHIP_MATCH_SUBDEV``
-      - 4
-      - Match the nth sub-device.
-
-
-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
-    The ``match_type`` is invalid or no device could be matched.
diff --git a/Documentation/media/uapi/v4l/vidioc-dbg-g-register.rst b/Documentation/media/uapi/v4l/vidioc-dbg-g-register.rst
deleted file mode 100644
index 112597c6cad2..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-dbg-g-register.rst
+++ /dev/null
@@ -1,171 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_DBG_G_REGISTER:
-
-**************************************************
-ioctl VIDIOC_DBG_G_REGISTER, VIDIOC_DBG_S_REGISTER
-**************************************************
-
-Name
-====
-
-VIDIOC_DBG_G_REGISTER - VIDIOC_DBG_S_REGISTER - Read or write hardware registers
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_DBG_G_REGISTER, struct v4l2_dbg_register *argp )
-    :name: VIDIOC_DBG_G_REGISTER
-
-.. c:function:: int ioctl( int fd, VIDIOC_DBG_S_REGISTER, const struct v4l2_dbg_register *argp )
-    :name: VIDIOC_DBG_S_REGISTER
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_dbg_register`.
-
-
-Description
-===========
-
-.. note::
-
-    This is an :ref:`experimental` interface and may
-    change in the future.
-
-For driver debugging purposes these ioctls allow test applications to
-access hardware registers directly. Regular applications must not use
-them.
-
-Since writing or even reading registers can jeopardize the system
-security, its stability and damage the hardware, both ioctls require
-superuser privileges. Additionally the Linux kernel must be compiled
-with the ``CONFIG_VIDEO_ADV_DEBUG`` option to enable these ioctls.
-
-To write a register applications must initialize all fields of a struct
-:c:type:`v4l2_dbg_register` except for ``size`` and
-call ``VIDIOC_DBG_S_REGISTER`` with a pointer to this structure. The
-``match.type`` and ``match.addr`` or ``match.name`` fields select a chip
-on the TV card, the ``reg`` field specifies a register number and the
-``val`` field the value to be written into the register.
-
-To read a register applications must initialize the ``match.type``,
-``match.addr`` or ``match.name`` and ``reg`` fields, and call
-``VIDIOC_DBG_G_REGISTER`` with a pointer to this structure. On success
-the driver stores the register value in the ``val`` field and the size
-(in bytes) of the value in ``size``.
-
-When ``match.type`` is ``V4L2_CHIP_MATCH_BRIDGE``, ``match.addr``
-selects the nth non-sub-device chip on the TV card. The number zero
-always selects the host chip, e. g. the chip connected to the PCI or USB
-bus. You can find out which chips are present with the
-:ref:`VIDIOC_DBG_G_CHIP_INFO` ioctl.
-
-When ``match.type`` is ``V4L2_CHIP_MATCH_SUBDEV``, ``match.addr``
-selects the nth sub-device.
-
-These ioctls are optional, not all drivers may support them. However
-when a driver supports these ioctls it must also support
-:ref:`VIDIOC_DBG_G_CHIP_INFO`. Conversely
-it may support ``VIDIOC_DBG_G_CHIP_INFO`` but not these ioctls.
-
-``VIDIOC_DBG_G_REGISTER`` and ``VIDIOC_DBG_S_REGISTER`` were introduced
-in Linux 2.6.21, but their API was changed to the one described here in
-kernel 2.6.29.
-
-We recommended the v4l2-dbg utility over calling these ioctls directly.
-It is available from the LinuxTV v4l-dvb repository; see
-`https://linuxtv.org/repo/ <https://linuxtv.org/repo/>`__ for access
-instructions.
-
-
-.. tabularcolumns:: |p{3.5cm}|p{3.5cm}|p{3.5cm}|p{7.0cm}|
-
-.. c:type:: v4l2_dbg_match
-
-.. flat-table:: struct v4l2_dbg_match
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``type``
-      - See :ref:`chip-match-types` for a list of possible types.
-    * - union {
-      - (anonymous)
-    * - __u32
-      - ``addr``
-      - Match a chip by this number, interpreted according to the ``type``
-	field.
-    * - char
-      - ``name[32]``
-      - Match a chip by this name, interpreted according to the ``type``
-	field. Currently unused.
-    * - }
-      -
-
-
-
-.. c:type:: v4l2_dbg_register
-
-.. flat-table:: struct v4l2_dbg_register
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - struct v4l2_dbg_match
-      - ``match``
-      - How to match the chip, see :c:type:`v4l2_dbg_match`.
-    * - __u32
-      - ``size``
-      - The register size in bytes.
-    * - __u64
-      - ``reg``
-      - A register number.
-    * - __u64
-      - ``val``
-      - The value read from, or to be written into the register.
-
-
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. _chip-match-types:
-
-.. flat-table:: Chip Match Types
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_CHIP_MATCH_BRIDGE``
-      - 0
-      - Match the nth chip on the card, zero for the bridge chip. Does not
-	match sub-devices.
-    * - ``V4L2_CHIP_MATCH_SUBDEV``
-      - 4
-      - Match the nth sub-device.
-
-
-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.
-
-EPERM
-    Insufficient permissions. Root privileges are required to execute
-    these ioctls.
diff --git a/Documentation/media/uapi/v4l/vidioc-decoder-cmd.rst b/Documentation/media/uapi/v4l/vidioc-decoder-cmd.rst
deleted file mode 100644
index 784c5980da8d..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-decoder-cmd.rst
+++ /dev/null
@@ -1,226 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_DECODER_CMD:
-
-************************************************
-ioctl VIDIOC_DECODER_CMD, VIDIOC_TRY_DECODER_CMD
-************************************************
-
-Name
-====
-
-VIDIOC_DECODER_CMD - VIDIOC_TRY_DECODER_CMD - Execute an decoder command
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_DECODER_CMD, struct v4l2_decoder_cmd *argp )
-    :name: VIDIOC_DECODER_CMD
-
-
-.. c:function:: int ioctl( int fd, VIDIOC_TRY_DECODER_CMD, struct v4l2_decoder_cmd *argp )
-    :name: VIDIOC_TRY_DECODER_CMD
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    pointer to struct :c:type:`v4l2_decoder_cmd`.
-
-
-Description
-===========
-
-These ioctls control an audio/video (usually MPEG-) decoder.
-``VIDIOC_DECODER_CMD`` sends a command to the decoder,
-``VIDIOC_TRY_DECODER_CMD`` can be used to try a command without actually
-executing it. To send a command applications must initialize all fields
-of a struct :c:type:`v4l2_decoder_cmd` and call
-``VIDIOC_DECODER_CMD`` or ``VIDIOC_TRY_DECODER_CMD`` with a pointer to
-this structure.
-
-The ``cmd`` field must contain the command code. Some commands use the
-``flags`` field for additional information.
-
-A :ref:`write() <func-write>` or :ref:`VIDIOC_STREAMON`
-call sends an implicit START command to the decoder if it has not been
-started yet. Applies to both queues of mem2mem decoders.
-
-A :ref:`close() <func-close>` or :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>`
-call of a streaming file descriptor sends an implicit immediate STOP
-command to the decoder, and all buffered data is discarded. Applies to both
-queues of mem2mem decoders.
-
-In principle, these ioctls are optional, not all drivers may support them. They were
-introduced in Linux 3.3. They are, however, mandatory for stateful mem2mem decoders
-(as further documented in :ref:`decoder`).
-
-
-.. tabularcolumns:: |p{1.1cm}|p{2.4cm}|p{1.2cm}|p{1.6cm}|p{10.6cm}|
-
-.. c:type:: v4l2_decoder_cmd
-
-.. cssclass:: longtable
-
-.. flat-table:: struct v4l2_decoder_cmd
-    :header-rows:  0
-    :stub-columns: 0
-    :widths: 1 1 1 3
-
-    * - __u32
-      - ``cmd``
-      -
-      - The decoder command, see :ref:`decoder-cmds`.
-    * - __u32
-      - ``flags``
-      -
-      - Flags to go with the command. If no flags are defined for this
-	command, drivers and applications must set this field to zero.
-    * - union {
-      - (anonymous)
-    * - struct
-      - ``start``
-      -
-      - Structure containing additional data for the
-	``V4L2_DEC_CMD_START`` command.
-    * -
-      - __s32
-      - ``speed``
-      - Playback speed and direction. The playback speed is defined as
-	``speed``/1000 of the normal speed. So 1000 is normal playback.
-	Negative numbers denote reverse playback, so -1000 does reverse
-	playback at normal speed. Speeds -1, 0 and 1 have special
-	meanings: speed 0 is shorthand for 1000 (normal playback). A speed
-	of 1 steps just one frame forward, a speed of -1 steps just one
-	frame back.
-    * -
-      - __u32
-      - ``format``
-      - Format restrictions. This field is set by the driver, not the
-	application. Possible values are ``V4L2_DEC_START_FMT_NONE`` if
-	there are no format restrictions or ``V4L2_DEC_START_FMT_GOP`` if
-	the decoder operates on full GOPs (*Group Of Pictures*). This is
-	usually the case for reverse playback: the decoder needs full
-	GOPs, which it can then play in reverse order. So to implement
-	reverse playback the application must feed the decoder the last
-	GOP in the video file, then the GOP before that, etc. etc.
-    * - struct
-      - ``stop``
-      -
-      - Structure containing additional data for the ``V4L2_DEC_CMD_STOP``
-	command.
-    * -
-      - __u64
-      - ``pts``
-      - Stop playback at this ``pts`` or immediately if the playback is
-	already past that timestamp. Leave to 0 if you want to stop after
-	the last frame was decoded.
-    * - struct
-      - ``raw``
-    * -
-      - __u32
-      - ``data``\ [16]
-      - Reserved for future extensions. Drivers and applications must set
-	the array to zero.
-    * - }
-      -
-
-
-
-.. tabularcolumns:: |p{5.6cm}|p{0.6cm}|p{11.3cm}|
-
-.. _decoder-cmds:
-
-.. flat-table:: Decoder Commands
-    :header-rows:  0
-    :stub-columns: 0
-    :widths: 56 6 113
-
-    * - ``V4L2_DEC_CMD_START``
-      - 0
-      - Start the decoder. When the decoder is already running or paused,
-	this command will just change the playback speed. That means that
-	calling ``V4L2_DEC_CMD_START`` when the decoder was paused will
-	*not* resume the decoder. You have to explicitly call
-	``V4L2_DEC_CMD_RESUME`` for that. This command has one flag:
-	``V4L2_DEC_CMD_START_MUTE_AUDIO``. If set, then audio will be
-	muted when playing back at a non-standard speed.
-
-	For a device implementing the :ref:`decoder`, once the drain sequence
-	is initiated with the ``V4L2_DEC_CMD_STOP`` command, it must be driven
-	to completion before this command can be invoked.  Any attempt to
-	invoke the command while the drain sequence is in progress will trigger
-	an ``EBUSY`` error code.  The command may be also used to restart the
-	decoder in case of an implicit stop initiated by the decoder itself,
-	without the ``V4L2_DEC_CMD_STOP`` being called explicitly. See
-	:ref:`decoder` for more details.
-    * - ``V4L2_DEC_CMD_STOP``
-      - 1
-      - Stop the decoder. When the decoder is already stopped, this
-	command does nothing. This command has two flags: if
-	``V4L2_DEC_CMD_STOP_TO_BLACK`` is set, then the decoder will set
-	the picture to black after it stopped decoding. Otherwise the last
-	image will repeat. If
-	``V4L2_DEC_CMD_STOP_IMMEDIATELY`` is set, then the decoder stops
-	immediately (ignoring the ``pts`` value), otherwise it will keep
-	decoding until timestamp >= pts or until the last of the pending
-	data from its internal buffers was decoded.
-
-	For a device implementing the :ref:`decoder`, the command will initiate
-	the drain sequence as documented in :ref:`decoder`.  No flags or other
-	arguments are accepted in this case. Any attempt to invoke the command
-	again before the sequence completes will trigger an ``EBUSY`` error
-	code.
-    * - ``V4L2_DEC_CMD_PAUSE``
-      - 2
-      - Pause the decoder. When the decoder has not been started yet, the
-	driver will return an ``EPERM`` error code. When the decoder is
-	already paused, this command does nothing. This command has one
-	flag: if ``V4L2_DEC_CMD_PAUSE_TO_BLACK`` is set, then set the
-	decoder output to black when paused.
-    * - ``V4L2_DEC_CMD_RESUME``
-      - 3
-      - Resume decoding after a PAUSE command. When the decoder has not
-	been started yet, the driver will return an ``EPERM`` error code. When
-	the decoder is already running, this command does nothing. No
-	flags are defined for this command.
-    * - ``V4L2_DEC_CMD_FLUSH``
-      - 4
-      - Flush any held capture buffers. Only valid for stateless decoders.
-	This command is typically used when the application reached the
-	end of the stream and the last output buffer had the
-	``V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF`` flag set. This would prevent
-	dequeueing the capture buffer containing the last decoded frame.
-	So this command can be used to explicitly flush that final decoded
-	frame. This command does nothing if there are no held capture buffers.
-
-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.
-
-EBUSY
-    A drain sequence of a device implementing the :ref:`decoder` is still in
-    progress. It is not allowed to issue another decoder command until it
-    completes.
-
-EINVAL
-    The ``cmd`` field is invalid.
-
-EPERM
-    The application sent a PAUSE or RESUME command when the decoder was
-    not running.
diff --git a/Documentation/media/uapi/v4l/vidioc-dqevent.rst b/Documentation/media/uapi/v4l/vidioc-dqevent.rst
deleted file mode 100644
index 2f37d255352a..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-dqevent.rst
+++ /dev/null
@@ -1,391 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_DQEVENT:
-
-********************
-ioctl VIDIOC_DQEVENT
-********************
-
-Name
-====
-
-VIDIOC_DQEVENT - Dequeue event
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_DQEVENT, struct v4l2_event *argp )
-    :name: VIDIOC_DQEVENT
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_event`.
-
-
-Description
-===========
-
-Dequeue an event from a video device. No input is required for this
-ioctl. All the fields of the struct :c:type:`v4l2_event`
-structure are filled by the driver. The file handle will also receive
-exceptions which the application may get by e.g. using the select system
-call.
-
-
-.. tabularcolumns:: |p{3.0cm}|p{4.4cm}|p{2.4cm}|p{7.7cm}|
-
-.. c:type:: v4l2_event
-
-.. cssclass: longtable
-
-.. flat-table:: struct v4l2_event
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``type``
-      - Type of the event, see :ref:`event-type`.
-    * - union {
-      - ``u``
-    * - struct :c:type:`v4l2_event_vsync`
-      - ``vsync``
-      - Event data for event ``V4L2_EVENT_VSYNC``.
-    * - struct :c:type:`v4l2_event_ctrl`
-      - ``ctrl``
-      - Event data for event ``V4L2_EVENT_CTRL``.
-    * - struct :c:type:`v4l2_event_frame_sync`
-      - ``frame_sync``
-      - Event data for event ``V4L2_EVENT_FRAME_SYNC``.
-    * - struct :c:type:`v4l2_event_motion_det`
-      - ``motion_det``
-      - Event data for event V4L2_EVENT_MOTION_DET.
-    * - struct :c:type:`v4l2_event_src_change`
-      - ``src_change``
-      - Event data for event V4L2_EVENT_SOURCE_CHANGE.
-    * - __u8
-      - ``data``\ [64]
-      - Event data. Defined by the event type. The union should be used to
-	define easily accessible type for events.
-    * - }
-      -
-    * - __u32
-      - ``pending``
-      - Number of pending events excluding this one.
-    * - __u32
-      - ``sequence``
-      - Event sequence number. The sequence number is incremented for
-	every subscribed event that takes place. If sequence numbers are
-	not contiguous it means that events have been lost.
-    * - struct timespec
-      - ``timestamp``
-      - Event timestamp. The timestamp has been taken from the
-	``CLOCK_MONOTONIC`` clock. To access the same clock outside V4L2,
-	use :c:func:`clock_gettime`.
-    * - u32
-      - ``id``
-      - The ID associated with the event source. If the event does not
-	have an associated ID (this depends on the event type), then this
-	is 0.
-    * - __u32
-      - ``reserved``\ [8]
-      - Reserved for future extensions. Drivers must set the array to
-	zero.
-
-
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. cssclass:: longtable
-
-.. _event-type:
-
-.. flat-table:: Event Types
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_EVENT_ALL``
-      - 0
-      - All events. V4L2_EVENT_ALL is valid only for
-	VIDIOC_UNSUBSCRIBE_EVENT for unsubscribing all events at once.
-    * - ``V4L2_EVENT_VSYNC``
-      - 1
-      - This event is triggered on the vertical sync. This event has a
-	struct :c:type:`v4l2_event_vsync` associated
-	with it.
-    * - ``V4L2_EVENT_EOS``
-      - 2
-      - This event is triggered when the end of a stream is reached. This
-	is typically used with MPEG decoders to report to the application
-	when the last of the MPEG stream has been decoded.
-    * - ``V4L2_EVENT_CTRL``
-      - 3
-      - This event requires that the ``id`` matches the control ID from
-	which you want to receive events. This event is triggered if the
-	control's value changes, if a button control is pressed or if the
-	control's flags change. This event has a struct
-	:c:type:`v4l2_event_ctrl` associated with it.
-	This struct contains much of the same information as struct
-	:ref:`v4l2_queryctrl <v4l2-queryctrl>` and struct
-	:c:type:`v4l2_control`.
-
-	If the event is generated due to a call to
-	:ref:`VIDIOC_S_CTRL <VIDIOC_G_CTRL>` or
-	:ref:`VIDIOC_S_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>`, then the
-	event will *not* be sent to the file handle that called the ioctl
-	function. This prevents nasty feedback loops. If you *do* want to
-	get the event, then set the ``V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK``
-	flag.
-
-	This event type will ensure that no information is lost when more
-	events are raised than there is room internally. In that case the
-	struct :c:type:`v4l2_event_ctrl` of the
-	second-oldest event is kept, but the ``changes`` field of the
-	second-oldest event is ORed with the ``changes`` field of the
-	oldest event.
-    * - ``V4L2_EVENT_FRAME_SYNC``
-      - 4
-      - Triggered immediately when the reception of a frame has begun.
-	This event has a struct
-	:c:type:`v4l2_event_frame_sync`
-	associated with it.
-
-	If the hardware needs to be stopped in the case of a buffer
-	underrun it might not be able to generate this event. In such
-	cases the ``frame_sequence`` field in struct
-	:c:type:`v4l2_event_frame_sync` will not
-	be incremented. This causes two consecutive frame sequence numbers
-	to have n times frame interval in between them.
-    * - ``V4L2_EVENT_SOURCE_CHANGE``
-      - 5
-      - This event is triggered when a source parameter change is detected
-	during runtime by the video device. It can be a runtime resolution
-	change triggered by a video decoder or the format change happening
-	on an input connector. This event requires that the ``id`` matches
-	the input index (when used with a video device node) or the pad
-	index (when used with a subdevice node) from which you want to
-	receive events.
-
-	This event has a struct
-	:c:type:`v4l2_event_src_change`
-	associated with it. The ``changes`` bitfield denotes what has
-	changed for the subscribed pad. If multiple events occurred before
-	application could dequeue them, then the changes will have the
-	ORed value of all the events generated.
-    * - ``V4L2_EVENT_MOTION_DET``
-      - 6
-      - Triggered whenever the motion detection state for one or more of
-	the regions changes. This event has a struct
-	:c:type:`v4l2_event_motion_det`
-	associated with it.
-    * - ``V4L2_EVENT_PRIVATE_START``
-      - 0x08000000
-      - Base event number for driver-private events.
-
-
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. c:type:: v4l2_event_vsync
-
-.. flat-table:: struct v4l2_event_vsync
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u8
-      - ``field``
-      - The upcoming field. See enum :c:type:`v4l2_field`.
-
-
-
-.. tabularcolumns:: |p{3.5cm}|p{3.0cm}|p{1.8cm}|p{8.5cm}|
-
-.. c:type:: v4l2_event_ctrl
-
-.. flat-table:: struct v4l2_event_ctrl
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``changes``
-      - A bitmask that tells what has changed. See
-	:ref:`ctrl-changes-flags`.
-    * - __u32
-      - ``type``
-      - The type of the control. See enum
-	:c:type:`v4l2_ctrl_type`.
-    * - union {
-      - (anonymous)
-    * - __s32
-      - ``value``
-      - The 32-bit value of the control for 32-bit control types. This is
-	0 for string controls since the value of a string cannot be passed
-	using :ref:`VIDIOC_DQEVENT`.
-    * - __s64
-      - ``value64``
-      - The 64-bit value of the control for 64-bit control types.
-    * - }
-      -
-    * - __u32
-      - ``flags``
-      - The control flags. See :ref:`control-flags`.
-    * - __s32
-      - ``minimum``
-      - The minimum value of the control. See struct
-	:ref:`v4l2_queryctrl <v4l2-queryctrl>`.
-    * - __s32
-      - ``maximum``
-      - The maximum value of the control. See struct
-	:ref:`v4l2_queryctrl <v4l2-queryctrl>`.
-    * - __s32
-      - ``step``
-      - The step value of the control. See struct
-	:ref:`v4l2_queryctrl <v4l2-queryctrl>`.
-    * - __s32
-      - ``default_value``
-      - The default value value of the control. See struct
-	:ref:`v4l2_queryctrl <v4l2-queryctrl>`.
-
-
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. c:type:: v4l2_event_frame_sync
-
-.. flat-table:: struct v4l2_event_frame_sync
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``frame_sequence``
-      - The sequence number of the frame being received.
-
-
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. c:type:: v4l2_event_src_change
-
-.. flat-table:: struct v4l2_event_src_change
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``changes``
-      - A bitmask that tells what has changed. See
-	:ref:`src-changes-flags`.
-
-
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. c:type:: v4l2_event_motion_det
-
-.. flat-table:: struct v4l2_event_motion_det
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``flags``
-      - Currently only one flag is available: if
-	``V4L2_EVENT_MD_FL_HAVE_FRAME_SEQ`` is set, then the
-	``frame_sequence`` field is valid, otherwise that field should be
-	ignored.
-    * - __u32
-      - ``frame_sequence``
-      - The sequence number of the frame being received. Only valid if the
-	``V4L2_EVENT_MD_FL_HAVE_FRAME_SEQ`` flag was set.
-    * - __u32
-      - ``region_mask``
-      - The bitmask of the regions that reported motion. There is at least
-	one region. If this field is 0, then no motion was detected at
-	all. If there is no ``V4L2_CID_DETECT_MD_REGION_GRID`` control
-	(see :ref:`detect-controls`) to assign a different region to
-	each cell in the motion detection grid, then that all cells are
-	automatically assigned to the default region 0.
-
-
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. _ctrl-changes-flags:
-
-.. flat-table:: Control Changes
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_EVENT_CTRL_CH_VALUE``
-      - 0x0001
-      - This control event was triggered because the value of the control
-	changed. Special cases: Volatile controls do no generate this
-	event; If a control has the ``V4L2_CTRL_FLAG_EXECUTE_ON_WRITE``
-	flag set, then this event is sent as well, regardless its value.
-    * - ``V4L2_EVENT_CTRL_CH_FLAGS``
-      - 0x0002
-      - This control event was triggered because the control flags
-	changed.
-    * - ``V4L2_EVENT_CTRL_CH_RANGE``
-      - 0x0004
-      - This control event was triggered because the minimum, maximum,
-	step or the default value of the control changed.
-
-
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. _src-changes-flags:
-
-.. flat-table:: Source Changes
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_EVENT_SRC_CH_RESOLUTION``
-      - 0x0001
-      - This event gets triggered when a resolution change is detected at
-	an input. This can come from an input connector or from a video
-	decoder. Applications will have to query the new resolution (if
-	any, the signal may also have been lost).
-
-	For stateful decoders follow the guidelines in :ref:`decoder`.
-	Video Capture devices have to query the new timings using
-	:ref:`VIDIOC_QUERY_DV_TIMINGS` or
-	:ref:`VIDIOC_QUERYSTD <VIDIOC_QUERYSTD>`.
-
-	*Important*: even if the new video timings appear identical to the old
-	ones, receiving this event indicates that there was an issue with the
-	video signal and you must stop and restart streaming
-	(:ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>`
-	followed by :ref:`VIDIOC_STREAMON <VIDIOC_STREAMON>`). The reason is
-	that many Video Capture devices are not able to recover from a temporary
-	loss of signal and so restarting streaming I/O is required in order for
-	the hardware to synchronize to the video signal.
-
-
-Return Value
-============
-
-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/v4l/vidioc-dv-timings-cap.rst b/Documentation/media/uapi/v4l/vidioc-dv-timings-cap.rst
deleted file mode 100644
index 1d0acbf14c4f..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-dv-timings-cap.rst
+++ /dev/null
@@ -1,169 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_DV_TIMINGS_CAP:
-
-*********************************************************
-ioctl VIDIOC_DV_TIMINGS_CAP, VIDIOC_SUBDEV_DV_TIMINGS_CAP
-*********************************************************
-
-Name
-====
-
-VIDIOC_DV_TIMINGS_CAP - VIDIOC_SUBDEV_DV_TIMINGS_CAP - The capabilities of the Digital Video receiver/transmitter
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_DV_TIMINGS_CAP, struct v4l2_dv_timings_cap *argp )
-    :name: VIDIOC_DV_TIMINGS_CAP
-
-.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_DV_TIMINGS_CAP, struct v4l2_dv_timings_cap *argp )
-    :name: VIDIOC_SUBDEV_DV_TIMINGS_CAP
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_dv_timings_cap`.
-
-
-Description
-===========
-
-To query the capabilities of the DV receiver/transmitter applications
-initialize the ``pad`` field to 0, zero the reserved array of struct
-:c:type:`v4l2_dv_timings_cap` and call the
-``VIDIOC_DV_TIMINGS_CAP`` ioctl on a video node and the driver will fill
-in the structure.
-
-.. note::
-
-   Drivers may return different values after
-   switching the video input or output.
-
-When implemented by the driver DV capabilities of subdevices can be
-queried by calling the ``VIDIOC_SUBDEV_DV_TIMINGS_CAP`` ioctl directly
-on a subdevice node. The capabilities are specific to inputs (for DV
-receivers) or outputs (for DV transmitters), applications must specify
-the desired pad number in the struct
-:c:type:`v4l2_dv_timings_cap` ``pad`` field and
-zero the ``reserved`` array. Attempts to query capabilities on a pad
-that doesn't support them will return an ``EINVAL`` error code.
-
-
-.. tabularcolumns:: |p{1.2cm}|p{3.0cm}|p{13.3cm}|
-
-.. c:type:: v4l2_bt_timings_cap
-
-.. flat-table:: struct v4l2_bt_timings_cap
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``min_width``
-      - Minimum width of the active video in pixels.
-    * - __u32
-      - ``max_width``
-      - Maximum width of the active video in pixels.
-    * - __u32
-      - ``min_height``
-      - Minimum height of the active video in lines.
-    * - __u32
-      - ``max_height``
-      - Maximum height of the active video in lines.
-    * - __u64
-      - ``min_pixelclock``
-      - Minimum pixelclock frequency in Hz.
-    * - __u64
-      - ``max_pixelclock``
-      - Maximum pixelclock frequency in Hz.
-    * - __u32
-      - ``standards``
-      - The video standard(s) supported by the hardware. See
-	:ref:`dv-bt-standards` for a list of standards.
-    * - __u32
-      - ``capabilities``
-      - Several flags giving more information about the capabilities. See
-	:ref:`dv-bt-cap-capabilities` for a description of the flags.
-    * - __u32
-      - ``reserved``\ [16]
-      - Reserved for future extensions.
-	Drivers must set the array to zero.
-
-
-
-.. tabularcolumns:: |p{1.0cm}|p{4.0cm}|p{3.5cm}|p{9.2cm}|
-
-.. c:type:: v4l2_dv_timings_cap
-
-.. flat-table:: struct v4l2_dv_timings_cap
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``type``
-      - Type of DV timings as listed in :ref:`dv-timing-types`.
-    * - __u32
-      - ``pad``
-      - Pad number as reported by the media controller API. This field is
-	only used when operating on a subdevice node. When operating on a
-	video node applications must set this field to zero.
-    * - __u32
-      - ``reserved``\ [2]
-      - Reserved for future extensions.
-
-	Drivers and applications must set the array to zero.
-    * - union {
-      - (anonymous)
-    * - struct :c:type:`v4l2_bt_timings_cap`
-      - ``bt``
-      - BT.656/1120 timings capabilities of the hardware.
-    * - __u32
-      - ``raw_data``\ [32]
-    * - }
-      -
-
-.. tabularcolumns:: |p{7.0cm}|p{10.5cm}|
-
-.. _dv-bt-cap-capabilities:
-
-.. flat-table:: DV BT Timing capabilities
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - Flag
-      - Description
-    * -
-      -
-    * - ``V4L2_DV_BT_CAP_INTERLACED``
-      - Interlaced formats are supported.
-    * - ``V4L2_DV_BT_CAP_PROGRESSIVE``
-      - Progressive formats are supported.
-    * - ``V4L2_DV_BT_CAP_REDUCED_BLANKING``
-      - CVT/GTF specific: the timings can make use of reduced blanking
-	(CVT) or the 'Secondary GTF' curve (GTF).
-    * - ``V4L2_DV_BT_CAP_CUSTOM``
-      - Can support non-standard timings, i.e. timings not belonging to
-	the standards set in the ``standards`` field.
-
-
-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/v4l/vidioc-encoder-cmd.rst b/Documentation/media/uapi/v4l/vidioc-encoder-cmd.rst
deleted file mode 100644
index c313ca8b8cb5..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-encoder-cmd.rst
+++ /dev/null
@@ -1,168 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_ENCODER_CMD:
-
-************************************************
-ioctl VIDIOC_ENCODER_CMD, VIDIOC_TRY_ENCODER_CMD
-************************************************
-
-Name
-====
-
-VIDIOC_ENCODER_CMD - VIDIOC_TRY_ENCODER_CMD - Execute an encoder command
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_ENCODER_CMD, struct v4l2_encoder_cmd *argp )
-    :name: VIDIOC_ENCODER_CMD
-
-.. c:function:: int ioctl( int fd, VIDIOC_TRY_ENCODER_CMD, struct v4l2_encoder_cmd *argp )
-    :name: VIDIOC_TRY_ENCODER_CMD
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_encoder_cmd`.
-
-Description
-===========
-
-These ioctls control an audio/video (usually MPEG-) encoder.
-``VIDIOC_ENCODER_CMD`` sends a command to the encoder,
-``VIDIOC_TRY_ENCODER_CMD`` can be used to try a command without actually
-executing it.
-
-To send a command applications must initialize all fields of a struct
-:c:type:`v4l2_encoder_cmd` and call
-``VIDIOC_ENCODER_CMD`` or ``VIDIOC_TRY_ENCODER_CMD`` with a pointer to
-this structure.
-
-The ``cmd`` field must contain the command code. The ``flags`` field is
-currently only used by the STOP command and contains one bit: If the
-``V4L2_ENC_CMD_STOP_AT_GOP_END`` flag is set, encoding will continue
-until the end of the current *Group Of Pictures*, otherwise it will stop
-immediately.
-
-A :ref:`read() <func-read>` or :ref:`VIDIOC_STREAMON <VIDIOC_STREAMON>`
-call sends an implicit START command to the encoder if it has not been
-started yet. After a STOP command, :ref:`read() <func-read>` calls will read
-the remaining data buffered by the driver. When the buffer is empty,
-:ref:`read() <func-read>` will return zero and the next :ref:`read() <func-read>`
-call will restart the encoder.
-
-A :ref:`close() <func-close>` or :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>`
-call of a streaming file descriptor sends an implicit immediate STOP to
-the encoder, and all buffered data is discarded.
-
-These ioctls are optional, not all drivers may support them. They were
-introduced in Linux 2.6.21.
-
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. c:type:: v4l2_encoder_cmd
-
-.. flat-table:: struct v4l2_encoder_cmd
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``cmd``
-      - The encoder command, see :ref:`encoder-cmds`.
-    * - __u32
-      - ``flags``
-      - Flags to go with the command, see :ref:`encoder-flags`. If no
-	flags are defined for this command, drivers and applications must
-	set this field to zero.
-    * - __u32
-      - ``data``\ [8]
-      - Reserved for future extensions. Drivers and applications must set
-	the array to zero.
-
-
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. _encoder-cmds:
-
-.. flat-table:: Encoder Commands
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_ENC_CMD_START``
-      - 0
-      - Start the encoder. When the encoder is already running or paused,
-	this command does nothing. No flags are defined for this command.
-    * - ``V4L2_ENC_CMD_STOP``
-      - 1
-      - Stop the encoder. When the ``V4L2_ENC_CMD_STOP_AT_GOP_END`` flag
-	is set, encoding will continue until the end of the current *Group
-	Of Pictures*, otherwise encoding will stop immediately. When the
-	encoder is already stopped, this command does nothing. mem2mem
-	encoders will send a ``V4L2_EVENT_EOS`` event when the last frame
-	has been encoded and all frames are ready to be dequeued and will
-	set the ``V4L2_BUF_FLAG_LAST`` buffer flag on the last buffer of
-	the capture queue to indicate there will be no new buffers
-	produced to dequeue. This buffer may be empty, indicated by the
-	driver setting the ``bytesused`` field to 0. Once the
-	``V4L2_BUF_FLAG_LAST`` flag was set, the
-	:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl will not block anymore,
-	but return an ``EPIPE`` error code.
-    * - ``V4L2_ENC_CMD_PAUSE``
-      - 2
-      - Pause the encoder. When the encoder has not been started yet, the
-	driver will return an ``EPERM`` error code. When the encoder is
-	already paused, this command does nothing. No flags are defined
-	for this command.
-    * - ``V4L2_ENC_CMD_RESUME``
-      - 3
-      - Resume encoding after a PAUSE command. When the encoder has not
-	been started yet, the driver will return an ``EPERM`` error code. When
-	the encoder is already running, this command does nothing. No
-	flags are defined for this command.
-
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. _encoder-flags:
-
-.. flat-table:: Encoder Command Flags
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_ENC_CMD_STOP_AT_GOP_END``
-      - 0x0001
-      - Stop encoding at the end of the current *Group Of Pictures*,
-	rather than immediately.
-
-
-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
-    The ``cmd`` field is invalid.
-
-EPERM
-    The application sent a PAUSE or RESUME command when the encoder was
-    not running.
diff --git a/Documentation/media/uapi/v4l/vidioc-enum-dv-timings.rst b/Documentation/media/uapi/v4l/vidioc-enum-dv-timings.rst
deleted file mode 100644
index 0b286e19b46b..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-enum-dv-timings.rst
+++ /dev/null
@@ -1,114 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_ENUM_DV_TIMINGS:
-
-***********************************************************
-ioctl VIDIOC_ENUM_DV_TIMINGS, VIDIOC_SUBDEV_ENUM_DV_TIMINGS
-***********************************************************
-
-Name
-====
-
-VIDIOC_ENUM_DV_TIMINGS - VIDIOC_SUBDEV_ENUM_DV_TIMINGS - Enumerate supported Digital Video timings
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_ENUM_DV_TIMINGS, struct v4l2_enum_dv_timings *argp )
-    :name: VIDIOC_ENUM_DV_TIMINGS
-
-.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_ENUM_DV_TIMINGS, struct v4l2_enum_dv_timings *argp )
-    :name: VIDIOC_SUBDEV_ENUM_DV_TIMINGS
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_enum_dv_timings`.
-
-
-Description
-===========
-
-While some DV receivers or transmitters support a wide range of timings,
-others support only a limited number of timings. With this ioctl
-applications can enumerate a list of known supported timings. Call
-:ref:`VIDIOC_DV_TIMINGS_CAP` to check if it
-also supports other standards or even custom timings that are not in
-this list.
-
-To query the available timings, applications initialize the ``index``
-field, set the ``pad`` field to 0, zero the reserved array of struct
-:c:type:`v4l2_enum_dv_timings` and call the
-``VIDIOC_ENUM_DV_TIMINGS`` ioctl on a video node with a pointer to this
-structure. Drivers fill the rest of the structure or return an ``EINVAL``
-error code when the index is out of bounds. To enumerate all supported
-DV timings, applications shall begin at index zero, incrementing by one
-until the driver returns ``EINVAL``.
-
-.. note::
-
-   Drivers may enumerate a different set of DV timings after
-   switching the video input or output.
-
-When implemented by the driver DV timings of subdevices can be queried
-by calling the ``VIDIOC_SUBDEV_ENUM_DV_TIMINGS`` ioctl directly on a
-subdevice node. The DV timings are specific to inputs (for DV receivers)
-or outputs (for DV transmitters), applications must specify the desired
-pad number in the struct
-:c:type:`v4l2_enum_dv_timings` ``pad`` field.
-Attempts to enumerate timings on a pad that doesn't support them will
-return an ``EINVAL`` error code.
-
-
-.. c:type:: v4l2_enum_dv_timings
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. flat-table:: struct v4l2_enum_dv_timings
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``index``
-      - Number of the DV timings, set by the application.
-    * - __u32
-      - ``pad``
-      - Pad number as reported by the media controller API. This field is
-	only used when operating on a subdevice node. When operating on a
-	video node applications must set this field to zero.
-    * - __u32
-      - ``reserved``\ [2]
-      - Reserved for future extensions. Drivers and applications must set
-	the array to zero.
-    * - struct :c:type:`v4l2_dv_timings`
-      - ``timings``
-      - The timings.
-
-
-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
-    The struct :c:type:`v4l2_enum_dv_timings`
-    ``index`` is out of bounds or the ``pad`` number is invalid.
-
-ENODATA
-    Digital video presets are not supported for this input or output.
diff --git a/Documentation/media/uapi/v4l/vidioc-enum-fmt.rst b/Documentation/media/uapi/v4l/vidioc-enum-fmt.rst
deleted file mode 100644
index 8ca6ab701e4a..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-enum-fmt.rst
+++ /dev/null
@@ -1,159 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_ENUM_FMT:
-
-*********************
-ioctl VIDIOC_ENUM_FMT
-*********************
-
-Name
-====
-
-VIDIOC_ENUM_FMT - Enumerate image formats
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_ENUM_FMT, struct v4l2_fmtdesc *argp )
-    :name: VIDIOC_ENUM_FMT
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_fmtdesc`.
-
-
-Description
-===========
-
-To enumerate image formats applications initialize the ``type`` and
-``index`` field of struct :c:type:`v4l2_fmtdesc` and call
-the :ref:`VIDIOC_ENUM_FMT` ioctl with a pointer to this structure. Drivers
-fill the rest of the structure or return an ``EINVAL`` error code. All
-formats are enumerable by beginning at index zero and incrementing by
-one until ``EINVAL`` is returned. If applicable, drivers shall return
-formats in preference order, where preferred formats are returned before
-(that is, with lower ``index`` value) less-preferred formats.
-
-.. note::
-
-   After switching input or output the list of enumerated image
-   formats may be different.
-
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. c:type:: v4l2_fmtdesc
-
-.. flat-table:: struct v4l2_fmtdesc
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``index``
-      - Number of the format in the enumeration, set by the application.
-	This is in no way related to the ``pixelformat`` field.
-    * - __u32
-      - ``type``
-      - Type of the data stream, set by the application. Only these types
-	are valid here: ``V4L2_BUF_TYPE_VIDEO_CAPTURE``,
-	``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE``,
-	``V4L2_BUF_TYPE_VIDEO_OUTPUT``,
-	``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE``,
-	``V4L2_BUF_TYPE_VIDEO_OVERLAY``,
-	``V4L2_BUF_TYPE_SDR_CAPTURE``,
-	``V4L2_BUF_TYPE_SDR_OUTPUT`` and
-	``V4L2_BUF_TYPE_META_CAPTURE``.
-	See :c:type:`v4l2_buf_type`.
-    * - __u32
-      - ``flags``
-      - See :ref:`fmtdesc-flags`
-    * - __u8
-      - ``description``\ [32]
-      - Description of the format, a NUL-terminated ASCII string. This
-	information is intended for the user, for example: "YUV 4:2:2".
-    * - __u32
-      - ``pixelformat``
-      - The image format identifier. This is a four character code as
-	computed by the v4l2_fourcc() macro:
-    * - :cspan:`2`
-
-	.. _v4l2-fourcc:
-
-	``#define v4l2_fourcc(a,b,c,d)``
-
-	``(((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24))``
-
-	Several image formats are already defined by this specification in
-	:ref:`pixfmt`.
-
-	.. attention::
-
-	   These codes are not the same as those used
-	   in the Windows world.
-    * - __u32
-      - ``reserved``\ [4]
-      - Reserved for future extensions. Drivers must set the array to
-	zero.
-
-
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. _fmtdesc-flags:
-
-.. flat-table:: Image Format Description Flags
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_FMT_FLAG_COMPRESSED``
-      - 0x0001
-      - This is a compressed format.
-    * - ``V4L2_FMT_FLAG_EMULATED``
-      - 0x0002
-      - This format is not native to the device but emulated through
-	software (usually libv4l2), where possible try to use a native
-	format instead for better performance.
-    * - ``V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM``
-      - 0x0004
-      - The hardware decoder for this compressed bytestream format (aka coded
-	format) is capable of parsing a continuous bytestream. Applications do
-	not need to parse the bytestream themselves to find the boundaries
-	between frames/fields. This flag can only be used in combination with
-	the ``V4L2_FMT_FLAG_COMPRESSED`` flag, since this applies to compressed
-	formats only. This flag is valid for stateful decoders only.
-    * - ``V4L2_FMT_FLAG_DYN_RESOLUTION``
-      - 0x0008
-      - Dynamic resolution switching is supported by the device for this
-	compressed bytestream format (aka coded format). It will notify the user
-	via the event ``V4L2_EVENT_SOURCE_CHANGE`` when changes in the video
-	parameters are detected. This flag can only be used in combination
-	with the ``V4L2_FMT_FLAG_COMPRESSED`` flag, since this applies to
-	compressed formats only. It is also only applies to stateful codecs.
-
-
-Return Value
-============
-
-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
-    The struct :c:type:`v4l2_fmtdesc` ``type`` is not
-    supported or the ``index`` is out of bounds.
diff --git a/Documentation/media/uapi/v4l/vidioc-enum-frameintervals.rst b/Documentation/media/uapi/v4l/vidioc-enum-frameintervals.rst
deleted file mode 100644
index 563a67cddeca..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-enum-frameintervals.rst
+++ /dev/null
@@ -1,203 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_ENUM_FRAMEINTERVALS:
-
-********************************
-ioctl VIDIOC_ENUM_FRAMEINTERVALS
-********************************
-
-Name
-====
-
-VIDIOC_ENUM_FRAMEINTERVALS - Enumerate frame intervals
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_ENUM_FRAMEINTERVALS, struct v4l2_frmivalenum *argp )
-    :name: VIDIOC_ENUM_FRAMEINTERVALS
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_frmivalenum`
-    that contains a pixel format and size and receives a frame interval.
-
-
-Description
-===========
-
-This ioctl allows applications to enumerate all frame intervals that the
-device supports for the given pixel format and frame size.
-
-The supported pixel formats and frame sizes can be obtained by using the
-:ref:`VIDIOC_ENUM_FMT` and
-:ref:`VIDIOC_ENUM_FRAMESIZES` functions.
-
-The return value and the content of the ``v4l2_frmivalenum.type`` field
-depend on the type of frame intervals the device supports. Here are the
-semantics of the function for the different cases:
-
--  **Discrete:** The function returns success if the given index value
-   (zero-based) is valid. The application should increase the index by
-   one for each call until ``EINVAL`` is returned. The
-   `v4l2_frmivalenum.type` field is set to
-   `V4L2_FRMIVAL_TYPE_DISCRETE` by the driver. Of the union only
-   the `discrete` member is valid.
-
--  **Step-wise:** The function returns success if the given index value
-   is zero and ``EINVAL`` for any other index value. The
-   ``v4l2_frmivalenum.type`` field is set to
-   ``V4L2_FRMIVAL_TYPE_STEPWISE`` by the driver. Of the union only the
-   ``stepwise`` member is valid.
-
--  **Continuous:** This is a special case of the step-wise type above.
-   The function returns success if the given index value is zero and
-   ``EINVAL`` for any other index value. The ``v4l2_frmivalenum.type``
-   field is set to ``V4L2_FRMIVAL_TYPE_CONTINUOUS`` by the driver. Of
-   the union only the ``stepwise`` member is valid and the ``step``
-   value is set to 1.
-
-When the application calls the function with index zero, it must check
-the ``type`` field to determine the type of frame interval enumeration
-the device supports. Only for the ``V4L2_FRMIVAL_TYPE_DISCRETE`` type
-does it make sense to increase the index value to receive more frame
-intervals.
-
-.. note::
-
-   The order in which the frame intervals are returned has no
-   special meaning. In particular does it not say anything about potential
-   default frame intervals.
-
-Applications can assume that the enumeration data does not change
-without any interaction from the application itself. This means that the
-enumeration data is consistent if the application does not perform any
-other ioctl calls while it runs the frame interval enumeration.
-
-.. note::
-
-   **Frame intervals and frame rates:** The V4L2 API uses frame
-   intervals instead of frame rates. Given the frame interval the frame
-   rate can be computed as follows:
-
-   ::
-
-       frame_rate = 1 / frame_interval
-
-
-Structs
-=======
-
-In the structs below, *IN* denotes a value that has to be filled in by
-the application, *OUT* denotes values that the driver fills in. The
-application should zero out all members except for the *IN* fields.
-
-
-.. c:type:: v4l2_frmival_stepwise
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. flat-table:: struct v4l2_frmival_stepwise
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - struct :c:type:`v4l2_fract`
-      - ``min``
-      - Minimum frame interval [s].
-    * - struct :c:type:`v4l2_fract`
-      - ``max``
-      - Maximum frame interval [s].
-    * - struct :c:type:`v4l2_fract`
-      - ``step``
-      - Frame interval step size [s].
-
-
-
-.. c:type:: v4l2_frmivalenum
-
-.. tabularcolumns:: |p{1.8cm}|p{4.4cm}|p{2.4cm}|p{8.9cm}|
-
-.. flat-table:: struct v4l2_frmivalenum
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - __u32
-      - ``index``
-      - IN: Index of the given frame interval in the enumeration.
-    * - __u32
-      - ``pixel_format``
-      - IN: Pixel format for which the frame intervals are enumerated.
-    * - __u32
-      - ``width``
-      - IN: Frame width for which the frame intervals are enumerated.
-    * - __u32
-      - ``height``
-      - IN: Frame height for which the frame intervals are enumerated.
-    * - __u32
-      - ``type``
-      - OUT: Frame interval type the device supports.
-    * - union {
-      - (anonymous)
-      - OUT: Frame interval with the given index.
-    * - struct :c:type:`v4l2_fract`
-      - ``discrete``
-      - Frame interval [s].
-    * - struct :c:type:`v4l2_frmival_stepwise`
-      - ``stepwise``
-      -
-    * - }
-      -
-      -
-    * - __u32
-      - ``reserved[2]``
-      -
-      - Reserved space for future use. Must be zeroed by drivers and
-	applications.
-
-
-
-Enums
-=====
-
-
-.. c:type:: v4l2_frmivaltypes
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. flat-table:: enum v4l2_frmivaltypes
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_FRMIVAL_TYPE_DISCRETE``
-      - 1
-      - Discrete frame interval.
-    * - ``V4L2_FRMIVAL_TYPE_CONTINUOUS``
-      - 2
-      - Continuous frame interval.
-    * - ``V4L2_FRMIVAL_TYPE_STEPWISE``
-      - 3
-      - Step-wise defined frame interval.
-
-
-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/v4l/vidioc-enum-framesizes.rst b/Documentation/media/uapi/v4l/vidioc-enum-framesizes.rst
deleted file mode 100644
index cd97546a7122..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-enum-framesizes.rst
+++ /dev/null
@@ -1,213 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_ENUM_FRAMESIZES:
-
-****************************
-ioctl VIDIOC_ENUM_FRAMESIZES
-****************************
-
-Name
-====
-
-VIDIOC_ENUM_FRAMESIZES - Enumerate frame sizes
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_ENUM_FRAMESIZES, struct v4l2_frmsizeenum *argp )
-    :name: VIDIOC_ENUM_FRAMESIZES
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_frmsizeenum`
-    that contains an index and pixel format and receives a frame width
-    and height.
-
-
-Description
-===========
-
-This ioctl allows applications to enumerate all frame sizes (i. e. width
-and height in pixels) that the device supports for the given pixel
-format.
-
-The supported pixel formats can be obtained by using the
-:ref:`VIDIOC_ENUM_FMT` function.
-
-The return value and the content of the ``v4l2_frmsizeenum.type`` field
-depend on the type of frame sizes the device supports. Here are the
-semantics of the function for the different cases:
-
--  **Discrete:** The function returns success if the given index value
-   (zero-based) is valid. The application should increase the index by
-   one for each call until ``EINVAL`` is returned. The
-   ``v4l2_frmsizeenum.type`` field is set to
-   ``V4L2_FRMSIZE_TYPE_DISCRETE`` by the driver. Of the union only the
-   ``discrete`` member is valid.
-
--  **Step-wise:** The function returns success if the given index value
-   is zero and ``EINVAL`` for any other index value. The
-   ``v4l2_frmsizeenum.type`` field is set to
-   ``V4L2_FRMSIZE_TYPE_STEPWISE`` by the driver. Of the union only the
-   ``stepwise`` member is valid.
-
--  **Continuous:** This is a special case of the step-wise type above.
-   The function returns success if the given index value is zero and
-   ``EINVAL`` for any other index value. The ``v4l2_frmsizeenum.type``
-   field is set to ``V4L2_FRMSIZE_TYPE_CONTINUOUS`` by the driver. Of
-   the union only the ``stepwise`` member is valid and the
-   ``step_width`` and ``step_height`` values are set to 1.
-
-When the application calls the function with index zero, it must check
-the ``type`` field to determine the type of frame size enumeration the
-device supports. Only for the ``V4L2_FRMSIZE_TYPE_DISCRETE`` type does
-it make sense to increase the index value to receive more frame sizes.
-
-.. note::
-
-   The order in which the frame sizes are returned has no special
-   meaning. In particular does it not say anything about potential default
-   format sizes.
-
-Applications can assume that the enumeration data does not change
-without any interaction from the application itself. This means that the
-enumeration data is consistent if the application does not perform any
-other ioctl calls while it runs the frame size enumeration.
-
-
-Structs
-=======
-
-In the structs below, *IN* denotes a value that has to be filled in by
-the application, *OUT* denotes values that the driver fills in. The
-application should zero out all members except for the *IN* fields.
-
-
-.. c:type:: v4l2_frmsize_discrete
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. flat-table:: struct v4l2_frmsize_discrete
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``width``
-      - Width of the frame [pixel].
-    * - __u32
-      - ``height``
-      - Height of the frame [pixel].
-
-
-
-.. c:type:: v4l2_frmsize_stepwise
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. flat-table:: struct v4l2_frmsize_stepwise
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``min_width``
-      - Minimum frame width [pixel].
-    * - __u32
-      - ``max_width``
-      - Maximum frame width [pixel].
-    * - __u32
-      - ``step_width``
-      - Frame width step size [pixel].
-    * - __u32
-      - ``min_height``
-      - Minimum frame height [pixel].
-    * - __u32
-      - ``max_height``
-      - Maximum frame height [pixel].
-    * - __u32
-      - ``step_height``
-      - Frame height step size [pixel].
-
-
-
-.. c:type:: v4l2_frmsizeenum
-
-.. tabularcolumns:: |p{1.4cm}|p{5.9cm}|p{2.3cm}|p{8.0cm}|
-
-.. flat-table:: struct v4l2_frmsizeenum
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - __u32
-      - ``index``
-      - IN: Index of the given frame size in the enumeration.
-    * - __u32
-      - ``pixel_format``
-      - IN: Pixel format for which the frame sizes are enumerated.
-    * - __u32
-      - ``type``
-      - OUT: Frame size type the device supports.
-    * - union {
-      - (anonymous)
-      - OUT: Frame size with the given index.
-    * - struct :c:type:`v4l2_frmsize_discrete`
-      - ``discrete``
-      -
-    * - struct :c:type:`v4l2_frmsize_stepwise`
-      - ``stepwise``
-      -
-    * - }
-      -
-      -
-    * - __u32
-      - ``reserved[2]``
-      - Reserved space for future use. Must be zeroed by drivers and
-	applications.
-
-
-
-Enums
-=====
-
-
-.. c:type:: v4l2_frmsizetypes
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. flat-table:: enum v4l2_frmsizetypes
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_FRMSIZE_TYPE_DISCRETE``
-      - 1
-      - Discrete frame size.
-    * - ``V4L2_FRMSIZE_TYPE_CONTINUOUS``
-      - 2
-      - Continuous frame size.
-    * - ``V4L2_FRMSIZE_TYPE_STEPWISE``
-      - 3
-      - Step-wise defined frame size.
-
-
-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/v4l/vidioc-enum-freq-bands.rst b/Documentation/media/uapi/v4l/vidioc-enum-freq-bands.rst
deleted file mode 100644
index 0e97c09afe0e..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-enum-freq-bands.rst
+++ /dev/null
@@ -1,150 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_ENUM_FREQ_BANDS:
-
-****************************
-ioctl VIDIOC_ENUM_FREQ_BANDS
-****************************
-
-Name
-====
-
-VIDIOC_ENUM_FREQ_BANDS - Enumerate supported frequency bands
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_ENUM_FREQ_BANDS, struct v4l2_frequency_band *argp )
-    :name: VIDIOC_ENUM_FREQ_BANDS
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_frequency_band`.
-
-
-Description
-===========
-
-Enumerates the frequency bands that a tuner or modulator supports. To do
-this applications initialize the ``tuner``, ``type`` and ``index``
-fields, and zero out the ``reserved`` array of a struct
-:c:type:`v4l2_frequency_band` and call the
-:ref:`VIDIOC_ENUM_FREQ_BANDS` ioctl with a pointer to this structure.
-
-This ioctl is supported if the ``V4L2_TUNER_CAP_FREQ_BANDS`` capability
-of the corresponding tuner/modulator is set.
-
-
-.. tabularcolumns:: |p{2.9cm}|p{2.9cm}|p{5.8cm}|p{2.9cm}|p{3.0cm}|
-
-.. c:type:: v4l2_frequency_band
-
-.. flat-table:: struct v4l2_frequency_band
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2 1 1
-
-    * - __u32
-      - ``tuner``
-      - The tuner or modulator index number. This is the same value as in
-	the struct :c:type:`v4l2_input` ``tuner`` field and
-	the struct :c:type:`v4l2_tuner` ``index`` field, or
-	the struct :c:type:`v4l2_output` ``modulator`` field
-	and the struct :c:type:`v4l2_modulator` ``index``
-	field.
-    * - __u32
-      - ``type``
-      - The tuner type. This is the same value as in the struct
-	:c:type:`v4l2_tuner` ``type`` field. The type must be
-	set to ``V4L2_TUNER_RADIO`` for ``/dev/radioX`` device nodes, and
-	to ``V4L2_TUNER_ANALOG_TV`` for all others. Set this field to
-	``V4L2_TUNER_RADIO`` for modulators (currently only radio
-	modulators are supported). See :c:type:`v4l2_tuner_type`
-    * - __u32
-      - ``index``
-      - Identifies the frequency band, set by the application.
-    * - __u32
-      - ``capability``
-      - :cspan:`2` The tuner/modulator capability flags for this
-	frequency band, see :ref:`tuner-capability`. The
-	``V4L2_TUNER_CAP_LOW`` or ``V4L2_TUNER_CAP_1HZ`` capability must
-	be the same for all frequency bands of the selected
-	tuner/modulator. So either all bands have that capability set, or
-	none of them have that capability.
-    * - __u32
-      - ``rangelow``
-      - :cspan:`2` The lowest tunable frequency in units of 62.5 kHz, or
-	if the ``capability`` flag ``V4L2_TUNER_CAP_LOW`` is set, in units
-	of 62.5 Hz, for this frequency band. A 1 Hz unit is used when the
-	``capability`` flag ``V4L2_TUNER_CAP_1HZ`` is set.
-    * - __u32
-      - ``rangehigh``
-      - :cspan:`2` The highest tunable frequency in units of 62.5 kHz,
-	or if the ``capability`` flag ``V4L2_TUNER_CAP_LOW`` is set, in
-	units of 62.5 Hz, for this frequency band. A 1 Hz unit is used
-	when the ``capability`` flag ``V4L2_TUNER_CAP_1HZ`` is set.
-    * - __u32
-      - ``modulation``
-      - :cspan:`2` The supported modulation systems of this frequency
-	band. See :ref:`band-modulation`.
-
-	.. note::
-
-	   Currently only one modulation system per frequency band
-	   is supported. More work will need to be done if multiple
-	   modulation systems are possible. Contact the linux-media
-	   mailing list
-	   (`https://linuxtv.org/lists.php <https://linuxtv.org/lists.php>`__)
-	   if you need such functionality.
-    * - __u32
-      - ``reserved``\ [9]
-      - Reserved for future extensions.
-
-	Applications and drivers must set the array to zero.
-
-
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. _band-modulation:
-
-.. flat-table:: Band Modulation Systems
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_BAND_MODULATION_VSB``
-      - 0x02
-      - Vestigial Sideband modulation, used for analog TV.
-    * - ``V4L2_BAND_MODULATION_FM``
-      - 0x04
-      - Frequency Modulation, commonly used for analog radio.
-    * - ``V4L2_BAND_MODULATION_AM``
-      - 0x08
-      - Amplitude Modulation, commonly used for analog radio.
-
-
-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
-    The ``tuner`` or ``index`` is out of bounds or the ``type`` field is
-    wrong.
diff --git a/Documentation/media/uapi/v4l/vidioc-enumaudio.rst b/Documentation/media/uapi/v4l/vidioc-enumaudio.rst
deleted file mode 100644
index ee0c336c8721..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-enumaudio.rst
+++ /dev/null
@@ -1,62 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_ENUMAUDIO:
-
-**********************
-ioctl VIDIOC_ENUMAUDIO
-**********************
-
-Name
-====
-
-VIDIOC_ENUMAUDIO - Enumerate audio inputs
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_ENUMAUDIO, struct v4l2_audio *argp )
-    :name: VIDIOC_ENUMAUDIO
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_audio`.
-
-
-Description
-===========
-
-To query the attributes of an audio input applications initialize the
-``index`` field and zero out the ``reserved`` array of a struct
-:c:type:`v4l2_audio` and call the :ref:`VIDIOC_ENUMAUDIO`
-ioctl with a pointer to this structure. Drivers fill the rest of the
-structure or return an ``EINVAL`` error code when the index is out of
-bounds. To enumerate all audio inputs applications shall begin at index
-zero, incrementing by one until the driver returns ``EINVAL``.
-
-See :ref:`VIDIOC_G_AUDIO <VIDIOC_G_AUDIO>` for a description of struct
-:c:type:`v4l2_audio`.
-
-
-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
-    The number of the audio input is out of bounds.
diff --git a/Documentation/media/uapi/v4l/vidioc-enumaudioout.rst b/Documentation/media/uapi/v4l/vidioc-enumaudioout.rst
deleted file mode 100644
index 3a8882214d62..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-enumaudioout.rst
+++ /dev/null
@@ -1,67 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_ENUMAUDOUT:
-
-***********************
-ioctl VIDIOC_ENUMAUDOUT
-***********************
-
-Name
-====
-
-VIDIOC_ENUMAUDOUT - Enumerate audio outputs
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_ENUMAUDOUT, struct v4l2_audioout *argp )
-    :name: VIDIOC_ENUMAUDOUT
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_audioout`.
-
-
-Description
-===========
-
-To query the attributes of an audio output applications initialize the
-``index`` field and zero out the ``reserved`` array of a struct
-:c:type:`v4l2_audioout` and call the ``VIDIOC_G_AUDOUT``
-ioctl with a pointer to this structure. Drivers fill the rest of the
-structure or return an ``EINVAL`` error code when the index is out of
-bounds. To enumerate all audio outputs applications shall begin at index
-zero, incrementing by one until the driver returns ``EINVAL``.
-
-.. note::
-
-    Connectors on a TV card to loop back the received audio signal
-    to a sound card are not audio outputs in this sense.
-
-See :ref:`VIDIOC_G_AUDIOout <VIDIOC_G_AUDOUT>` for a description of struct
-:c:type:`v4l2_audioout`.
-
-
-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
-    The number of the audio output is out of bounds.
diff --git a/Documentation/media/uapi/v4l/vidioc-enuminput.rst b/Documentation/media/uapi/v4l/vidioc-enuminput.rst
deleted file mode 100644
index a0e4c4413121..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-enuminput.rst
+++ /dev/null
@@ -1,242 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_ENUMINPUT:
-
-**********************
-ioctl VIDIOC_ENUMINPUT
-**********************
-
-Name
-====
-
-VIDIOC_ENUMINPUT - Enumerate video inputs
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_ENUMINPUT, struct v4l2_input *argp )
-    :name: VIDIOC_ENUMINPUT
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_input`.
-
-
-Description
-===========
-
-To query the attributes of a video input applications initialize the
-``index`` field of struct :c:type:`v4l2_input` and call the
-:ref:`VIDIOC_ENUMINPUT` with a pointer to this structure. Drivers
-fill the rest of the structure or return an ``EINVAL`` error code when the
-index is out of bounds. To enumerate all inputs applications shall begin
-at index zero, incrementing by one until the driver returns ``EINVAL``.
-
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. c:type:: v4l2_input
-
-.. flat-table:: struct v4l2_input
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``index``
-      - Identifies the input, set by the application.
-    * - __u8
-      - ``name``\ [32]
-      - Name of the video input, a NUL-terminated ASCII string, for
-	example: "Vin (Composite 2)". This information is intended for the
-	user, preferably the connector label on the device itself.
-    * - __u32
-      - ``type``
-      - Type of the input, see :ref:`input-type`.
-    * - __u32
-      - ``audioset``
-      - Drivers can enumerate up to 32 video and audio inputs. This field
-	shows which audio inputs were selectable as audio source if this
-	was the currently selected video input. It is a bit mask. The LSB
-	corresponds to audio input 0, the MSB to input 31. Any number of
-	bits can be set, or none.
-
-	When the driver does not enumerate audio inputs no bits must be
-	set. Applications shall not interpret this as lack of audio
-	support. Some drivers automatically select audio sources and do
-	not enumerate them since there is no choice anyway.
-
-	For details on audio inputs and how to select the current input
-	see :ref:`audio`.
-    * - __u32
-      - ``tuner``
-      - Capture devices can have zero or more tuners (RF demodulators).
-	When the ``type`` is set to ``V4L2_INPUT_TYPE_TUNER`` this is an
-	RF connector and this field identifies the tuner. It corresponds
-	to struct :c:type:`v4l2_tuner` field ``index``. For
-	details on tuners see :ref:`tuner`.
-    * - :ref:`v4l2_std_id <v4l2-std-id>`
-      - ``std``
-      - Every video input supports one or more different video standards.
-	This field is a set of all supported standards. For details on
-	video standards and how to switch see :ref:`standard`.
-    * - __u32
-      - ``status``
-      - This field provides status information about the input. See
-	:ref:`input-status` for flags. With the exception of the sensor
-	orientation bits ``status`` is only valid when this is the current
-	input.
-    * - __u32
-      - ``capabilities``
-      - This field provides capabilities for the input. See
-	:ref:`input-capabilities` for flags.
-    * - __u32
-      - ``reserved``\ [3]
-      - Reserved for future extensions. Drivers must set the array to
-	zero.
-
-
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. _input-type:
-
-.. flat-table:: Input Types
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_INPUT_TYPE_TUNER``
-      - 1
-      - This input uses a tuner (RF demodulator).
-    * - ``V4L2_INPUT_TYPE_CAMERA``
-      - 2
-      - Any non-tuner video input, for example Composite Video,
-	S-Video, HDMI, camera sensor. The naming as ``_TYPE_CAMERA`` is historical,
-	today we would have called it ``_TYPE_VIDEO``.
-    * - ``V4L2_INPUT_TYPE_TOUCH``
-      - 3
-      - This input is a touch device for capturing raw touch data.
-
-
-
-.. tabularcolumns:: |p{4.8cm}|p{2.6cm}|p{10.1cm}|
-
-.. _input-status:
-
-.. flat-table:: Input Status Flags
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - :cspan:`2` General
-    * - ``V4L2_IN_ST_NO_POWER``
-      - 0x00000001
-      - Attached device is off.
-    * - ``V4L2_IN_ST_NO_SIGNAL``
-      - 0x00000002
-      -
-    * - ``V4L2_IN_ST_NO_COLOR``
-      - 0x00000004
-      - The hardware supports color decoding, but does not detect color
-	modulation in the signal.
-    * - :cspan:`2` Sensor Orientation
-    * - ``V4L2_IN_ST_HFLIP``
-      - 0x00000010
-      - The input is connected to a device that produces a signal that is
-	flipped horizontally and does not correct this before passing the
-	signal to userspace.
-    * - ``V4L2_IN_ST_VFLIP``
-      - 0x00000020
-      - The input is connected to a device that produces a signal that is
-	flipped vertically and does not correct this before passing the
-	signal to userspace.
-	.. note:: A 180 degree rotation is the same as HFLIP | VFLIP
-    * - :cspan:`2` Analog Video
-    * - ``V4L2_IN_ST_NO_H_LOCK``
-      - 0x00000100
-      - No horizontal sync lock.
-    * - ``V4L2_IN_ST_COLOR_KILL``
-      - 0x00000200
-      - A color killer circuit automatically disables color decoding when
-	it detects no color modulation. When this flag is set the color
-	killer is enabled *and* has shut off color decoding.
-    * - ``V4L2_IN_ST_NO_V_LOCK``
-      - 0x00000400
-      - No vertical sync lock.
-    * - ``V4L2_IN_ST_NO_STD_LOCK``
-      - 0x00000800
-      - No standard format lock in case of auto-detection format
-	by the component.
-    * - :cspan:`2` Digital Video
-    * - ``V4L2_IN_ST_NO_SYNC``
-      - 0x00010000
-      - No synchronization lock.
-    * - ``V4L2_IN_ST_NO_EQU``
-      - 0x00020000
-      - No equalizer lock.
-    * - ``V4L2_IN_ST_NO_CARRIER``
-      - 0x00040000
-      - Carrier recovery failed.
-    * - :cspan:`2` VCR and Set-Top Box
-    * - ``V4L2_IN_ST_MACROVISION``
-      - 0x01000000
-      - Macrovision is an analog copy prevention system mangling the video
-	signal to confuse video recorders. When this flag is set
-	Macrovision has been detected.
-    * - ``V4L2_IN_ST_NO_ACCESS``
-      - 0x02000000
-      - Conditional access denied.
-    * - ``V4L2_IN_ST_VTR``
-      - 0x04000000
-      - VTR time constant. [?]
-
-
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. _input-capabilities:
-
-.. flat-table:: Input capabilities
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_IN_CAP_DV_TIMINGS``
-      - 0x00000002
-      - This input supports setting video timings by using
-	``VIDIOC_S_DV_TIMINGS``.
-    * - ``V4L2_IN_CAP_STD``
-      - 0x00000004
-      - This input supports setting the TV standard by using
-	``VIDIOC_S_STD``.
-    * - ``V4L2_IN_CAP_NATIVE_SIZE``
-      - 0x00000008
-      - This input supports setting the native size using the
-	``V4L2_SEL_TGT_NATIVE_SIZE`` selection target, see
-	:ref:`v4l2-selections-common`.
-
-
-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
-    The struct :c:type:`v4l2_input` ``index`` is out of
-    bounds.
diff --git a/Documentation/media/uapi/v4l/vidioc-enumoutput.rst b/Documentation/media/uapi/v4l/vidioc-enumoutput.rst
deleted file mode 100644
index 0fea81f60541..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-enumoutput.rst
+++ /dev/null
@@ -1,165 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_ENUMOUTPUT:
-
-***********************
-ioctl VIDIOC_ENUMOUTPUT
-***********************
-
-Name
-====
-
-VIDIOC_ENUMOUTPUT - Enumerate video outputs
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_ENUMOUTPUT, struct v4l2_output *argp )
-    :name: VIDIOC_ENUMOUTPUT
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_output`.
-
-
-Description
-===========
-
-To query the attributes of a video outputs applications initialize the
-``index`` field of struct :c:type:`v4l2_output` and call
-the :ref:`VIDIOC_ENUMOUTPUT` with a pointer to this structure.
-Drivers fill the rest of the structure or return an ``EINVAL`` error code
-when the index is out of bounds. To enumerate all outputs applications
-shall begin at index zero, incrementing by one until the driver returns
-``EINVAL``.
-
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. c:type:: v4l2_output
-
-.. flat-table:: struct v4l2_output
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``index``
-      - Identifies the output, set by the application.
-    * - __u8
-      - ``name``\ [32]
-      - Name of the video output, a NUL-terminated ASCII string, for
-	example: "Vout". This information is intended for the user,
-	preferably the connector label on the device itself.
-    * - __u32
-      - ``type``
-      - Type of the output, see :ref:`output-type`.
-    * - __u32
-      - ``audioset``
-      - Drivers can enumerate up to 32 video and audio outputs. This field
-	shows which audio outputs were selectable as the current output if
-	this was the currently selected video output. It is a bit mask.
-	The LSB corresponds to audio output 0, the MSB to output 31. Any
-	number of bits can be set, or none.
-
-	When the driver does not enumerate audio outputs no bits must be
-	set. Applications shall not interpret this as lack of audio
-	support. Drivers may automatically select audio outputs without
-	enumerating them.
-
-	For details on audio outputs and how to select the current output
-	see :ref:`audio`.
-    * - __u32
-      - ``modulator``
-      - Output devices can have zero or more RF modulators. When the
-	``type`` is ``V4L2_OUTPUT_TYPE_MODULATOR`` this is an RF connector
-	and this field identifies the modulator. It corresponds to struct
-	:c:type:`v4l2_modulator` field ``index``. For
-	details on modulators see :ref:`tuner`.
-    * - :ref:`v4l2_std_id <v4l2-std-id>`
-      - ``std``
-      - Every video output supports one or more different video standards.
-	This field is a set of all supported standards. For details on
-	video standards and how to switch see :ref:`standard`.
-    * - __u32
-      - ``capabilities``
-      - This field provides capabilities for the output. See
-	:ref:`output-capabilities` for flags.
-    * - __u32
-      - ``reserved``\ [3]
-      - Reserved for future extensions. Drivers must set the array to
-	zero.
-
-
-
-.. tabularcolumns:: |p{7.0cm}|p{1.8cm}|p{8.7cm}|
-
-.. _output-type:
-
-.. flat-table:: Output Type
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_OUTPUT_TYPE_MODULATOR``
-      - 1
-      - This output is an analog TV modulator.
-    * - ``V4L2_OUTPUT_TYPE_ANALOG``
-      - 2
-      - Any non-modulator video output, for example Composite Video,
-	S-Video, HDMI. The naming as ``_TYPE_ANALOG`` is historical,
-	today we would have called it ``_TYPE_VIDEO``.
-    * - ``V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY``
-      - 3
-      - The video output will be copied to a :ref:`video overlay <overlay>`.
-
-
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. _output-capabilities:
-
-.. flat-table:: Output capabilities
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_OUT_CAP_DV_TIMINGS``
-      - 0x00000002
-      - This output supports setting video timings by using
-	``VIDIOC_S_DV_TIMINGS``.
-    * - ``V4L2_OUT_CAP_STD``
-      - 0x00000004
-      - This output supports setting the TV standard by using
-	``VIDIOC_S_STD``.
-    * - ``V4L2_OUT_CAP_NATIVE_SIZE``
-      - 0x00000008
-      - This output supports setting the native size using the
-	``V4L2_SEL_TGT_NATIVE_SIZE`` selection target, see
-	:ref:`v4l2-selections-common`.
-
-
-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
-    The struct :c:type:`v4l2_output` ``index`` is out of
-    bounds.
diff --git a/Documentation/media/uapi/v4l/vidioc-enumstd.rst b/Documentation/media/uapi/v4l/vidioc-enumstd.rst
deleted file mode 100644
index 1603b1b3b6e8..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-enumstd.rst
+++ /dev/null
@@ -1,367 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_ENUMSTD:
-
-*******************************************
-ioctl VIDIOC_ENUMSTD, VIDIOC_SUBDEV_ENUMSTD
-*******************************************
-
-Name
-====
-
-VIDIOC_ENUMSTD - VIDIOC_SUBDEV_ENUMSTD - Enumerate supported video standards
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_ENUMSTD, struct v4l2_standard *argp )
-    :name: VIDIOC_ENUMSTD
-
-.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_ENUMSTD, struct v4l2_standard *argp )
-    :name: VIDIOC_SUBDEV_ENUMSTD
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_standard`.
-
-
-Description
-===========
-
-To query the attributes of a video standard, especially a custom (driver
-defined) one, applications initialize the ``index`` field of struct
-:c:type:`v4l2_standard` and call the :ref:`VIDIOC_ENUMSTD`
-ioctl with a pointer to this structure. Drivers fill the rest of the
-structure or return an ``EINVAL`` error code when the index is out of
-bounds. To enumerate all standards applications shall begin at index
-zero, incrementing by one until the driver returns ``EINVAL``. Drivers may
-enumerate a different set of standards after switching the video input
-or output. [#f1]_
-
-
-.. c:type:: v4l2_standard
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. flat-table:: struct v4l2_standard
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``index``
-      - Number of the video standard, set by the application.
-    * - :ref:`v4l2_std_id <v4l2-std-id>`
-      - ``id``
-      - The bits in this field identify the standard as one of the common
-	standards listed in :ref:`v4l2-std-id`, or if bits 32 to 63 are
-	set as custom standards. Multiple bits can be set if the hardware
-	does not distinguish between these standards, however separate
-	indices do not indicate the opposite. The ``id`` must be unique.
-	No other enumerated struct :c:type:`v4l2_standard` structure,
-	for this input or output anyway, can contain the same set of bits.
-    * - __u8
-      - ``name``\ [24]
-      - Name of the standard, a NUL-terminated ASCII string, for example:
-	"PAL-B/G", "NTSC Japan". This information is intended for the
-	user.
-    * - struct :c:type:`v4l2_fract`
-      - ``frameperiod``
-      - The frame period (not field period) is numerator / denominator.
-	For example M/NTSC has a frame period of 1001 / 30000 seconds.
-    * - __u32
-      - ``framelines``
-      - Total lines per frame including blanking, e. g. 625 for B/PAL.
-    * - __u32
-      - ``reserved``\ [4]
-      - Reserved for future extensions. Drivers must set the array to
-	zero.
-
-
-
-.. c:type:: v4l2_fract
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. flat-table:: struct v4l2_fract
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``numerator``
-      -
-    * - __u32
-      - ``denominator``
-      -
-
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. _v4l2-std-id:
-
-.. flat-table:: typedef v4l2_std_id
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u64
-      - ``v4l2_std_id``
-      - This type is a set, each bit representing another video standard
-	as listed below and in :ref:`video-standards`. The 32 most
-	significant bits are reserved for custom (driver defined) video
-	standards.
-
-
-
-.. code-block:: c
-
-    #define V4L2_STD_PAL_B          ((v4l2_std_id)0x00000001)
-    #define V4L2_STD_PAL_B1         ((v4l2_std_id)0x00000002)
-    #define V4L2_STD_PAL_G          ((v4l2_std_id)0x00000004)
-    #define V4L2_STD_PAL_H          ((v4l2_std_id)0x00000008)
-    #define V4L2_STD_PAL_I          ((v4l2_std_id)0x00000010)
-    #define V4L2_STD_PAL_D          ((v4l2_std_id)0x00000020)
-    #define V4L2_STD_PAL_D1         ((v4l2_std_id)0x00000040)
-    #define V4L2_STD_PAL_K          ((v4l2_std_id)0x00000080)
-
-    #define V4L2_STD_PAL_M          ((v4l2_std_id)0x00000100)
-    #define V4L2_STD_PAL_N          ((v4l2_std_id)0x00000200)
-    #define V4L2_STD_PAL_Nc         ((v4l2_std_id)0x00000400)
-    #define V4L2_STD_PAL_60         ((v4l2_std_id)0x00000800)
-
-``V4L2_STD_PAL_60`` is a hybrid standard with 525 lines, 60 Hz refresh
-rate, and PAL color modulation with a 4.43 MHz color subcarrier. Some
-PAL video recorders can play back NTSC tapes in this mode for display on
-a 50/60 Hz agnostic PAL TV.
-
-
-.. code-block:: c
-
-    #define V4L2_STD_NTSC_M         ((v4l2_std_id)0x00001000)
-    #define V4L2_STD_NTSC_M_JP      ((v4l2_std_id)0x00002000)
-    #define V4L2_STD_NTSC_443       ((v4l2_std_id)0x00004000)
-
-``V4L2_STD_NTSC_443`` is a hybrid standard with 525 lines, 60 Hz refresh
-rate, and NTSC color modulation with a 4.43 MHz color subcarrier.
-
-
-.. code-block:: c
-
-    #define V4L2_STD_NTSC_M_KR      ((v4l2_std_id)0x00008000)
-
-    #define V4L2_STD_SECAM_B        ((v4l2_std_id)0x00010000)
-    #define V4L2_STD_SECAM_D        ((v4l2_std_id)0x00020000)
-    #define V4L2_STD_SECAM_G        ((v4l2_std_id)0x00040000)
-    #define V4L2_STD_SECAM_H        ((v4l2_std_id)0x00080000)
-    #define V4L2_STD_SECAM_K        ((v4l2_std_id)0x00100000)
-    #define V4L2_STD_SECAM_K1       ((v4l2_std_id)0x00200000)
-    #define V4L2_STD_SECAM_L        ((v4l2_std_id)0x00400000)
-    #define V4L2_STD_SECAM_LC       ((v4l2_std_id)0x00800000)
-
-    /* ATSC/HDTV */
-    #define V4L2_STD_ATSC_8_VSB     ((v4l2_std_id)0x01000000)
-    #define V4L2_STD_ATSC_16_VSB    ((v4l2_std_id)0x02000000)
-
-``V4L2_STD_ATSC_8_VSB`` and ``V4L2_STD_ATSC_16_VSB`` are U.S.
-terrestrial digital TV standards. Presently the V4L2 API does not
-support digital TV. See also the Linux DVB API at
-`https://linuxtv.org <https://linuxtv.org>`__.
-
-
-.. code-block:: c
-
-    #define V4L2_STD_PAL_BG         (V4L2_STD_PAL_B         |
-		     V4L2_STD_PAL_B1        |
-		     V4L2_STD_PAL_G)
-    #define V4L2_STD_B              (V4L2_STD_PAL_B         |
-		     V4L2_STD_PAL_B1        |
-		     V4L2_STD_SECAM_B)
-    #define V4L2_STD_GH             (V4L2_STD_PAL_G         |
-		     V4L2_STD_PAL_H         |
-		     V4L2_STD_SECAM_G       |
-		     V4L2_STD_SECAM_H)
-    #define V4L2_STD_PAL_DK         (V4L2_STD_PAL_D         |
-		     V4L2_STD_PAL_D1        |
-		     V4L2_STD_PAL_K)
-    #define V4L2_STD_PAL            (V4L2_STD_PAL_BG        |
-		     V4L2_STD_PAL_DK        |
-		     V4L2_STD_PAL_H         |
-		     V4L2_STD_PAL_I)
-    #define V4L2_STD_NTSC           (V4L2_STD_NTSC_M        |
-		     V4L2_STD_NTSC_M_JP     |
-		     V4L2_STD_NTSC_M_KR)
-    #define V4L2_STD_MN             (V4L2_STD_PAL_M         |
-		     V4L2_STD_PAL_N         |
-		     V4L2_STD_PAL_Nc        |
-		     V4L2_STD_NTSC)
-    #define V4L2_STD_SECAM_DK       (V4L2_STD_SECAM_D       |
-		     V4L2_STD_SECAM_K       |
-		     V4L2_STD_SECAM_K1)
-    #define V4L2_STD_DK             (V4L2_STD_PAL_DK        |
-		     V4L2_STD_SECAM_DK)
-
-    #define V4L2_STD_SECAM          (V4L2_STD_SECAM_B       |
-		     V4L2_STD_SECAM_G       |
-		     V4L2_STD_SECAM_H       |
-		     V4L2_STD_SECAM_DK      |
-		     V4L2_STD_SECAM_L       |
-		     V4L2_STD_SECAM_LC)
-
-    #define V4L2_STD_525_60         (V4L2_STD_PAL_M         |
-		     V4L2_STD_PAL_60        |
-		     V4L2_STD_NTSC          |
-		     V4L2_STD_NTSC_443)
-    #define V4L2_STD_625_50         (V4L2_STD_PAL           |
-		     V4L2_STD_PAL_N         |
-		     V4L2_STD_PAL_Nc        |
-		     V4L2_STD_SECAM)
-
-    #define V4L2_STD_UNKNOWN        0
-    #define V4L2_STD_ALL            (V4L2_STD_525_60        |
-		     V4L2_STD_625_50)
-
-
-.. raw:: latex
-
-    \begingroup
-    \tiny
-    \setlength{\tabcolsep}{2pt}
-
-..                            NTSC/M   PAL/M    /N       /B       /D       /H       /I        SECAM/B    /D       /K1     /L
-.. tabularcolumns:: |p{1.43cm}|p{1.38cm}|p{1.59cm}|p{1.7cm}|p{1.7cm}|p{1.17cm}|p{0.64cm}|p{1.71cm}|p{1.6cm}|p{1.07cm}|p{1.07cm}|p{1.07cm}|
-
-.. _video-standards:
-
-.. flat-table:: Video Standards (based on :ref:`itu470`)
-    :header-rows:  1
-    :stub-columns: 0
-
-    * - Characteristics
-      - M/NTSC [#f2]_
-      - M/PAL
-      - N/PAL [#f3]_
-      - B, B1, G/PAL
-      - D, D1, K/PAL
-      - H/PAL
-      - I/PAL
-      - B, G/SECAM
-      - D, K/SECAM
-      - K1/SECAM
-      - L/SECAM
-    * - Frame lines
-      - :cspan:`1` 525
-      - :cspan:`8` 625
-    * - Frame period (s)
-      - :cspan:`1` 1001/30000
-      - :cspan:`8` 1/25
-    * - Chrominance sub-carrier frequency (Hz)
-      - 3579545 ± 10
-      - 3579611.49 ± 10
-      - 4433618.75 ± 5
-
-	(3582056.25 ± 5)
-      - :cspan:`3` 4433618.75 ± 5
-      - 4433618.75 ± 1
-      - :cspan:`2` f\ :sub:`OR` = 4406250 ± 2000,
-
-	f\ :sub:`OB` = 4250000 ± 2000
-    * - Nominal radio-frequency channel bandwidth (MHz)
-      - 6
-      - 6
-      - 6
-      - B: 7; B1, G: 8
-      - 8
-      - 8
-      - 8
-      - 8
-      - 8
-      - 8
-      - 8
-    * - Sound carrier relative to vision carrier (MHz)
-      - 4.5
-      - 4.5
-      - 4.5
-      - 5.5 ± 0.001  [#f4]_  [#f5]_  [#f6]_  [#f7]_
-      - 6.5 ± 0.001
-      - 5.5
-      - 5.9996 ± 0.0005
-      - 5.5 ± 0.001
-      - 6.5 ± 0.001
-      - 6.5
-      - 6.5 [#f8]_
-
-.. raw:: latex
-
-    \endgroup
-
-
-
-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
-    The struct :c:type:`v4l2_standard` ``index`` is out
-    of bounds.
-
-ENODATA
-    Standard video timings are not supported for this input or output.
-
-.. [#f1]
-   The supported standards may overlap and we need an unambiguous set to
-   find the current standard returned by :ref:`VIDIOC_G_STD <VIDIOC_G_STD>`.
-
-.. [#f2]
-   Japan uses a standard similar to M/NTSC (V4L2_STD_NTSC_M_JP).
-
-.. [#f3]
-   The values in brackets apply to the combination N/PAL a.k.a.
-   N\ :sub:`C` used in Argentina (V4L2_STD_PAL_Nc).
-
-.. [#f4]
-   In the Federal Republic of Germany, Austria, Italy, the Netherlands,
-   Slovakia and Switzerland a system of two sound carriers is used, the
-   frequency of the second carrier being 242.1875 kHz above the
-   frequency of the first sound carrier. For stereophonic sound
-   transmissions a similar system is used in Australia.
-
-.. [#f5]
-   New Zealand uses a sound carrier displaced 5.4996 ± 0.0005 MHz from
-   the vision carrier.
-
-.. [#f6]
-   In Denmark, Finland, New Zealand, Sweden and Spain a system of two
-   sound carriers is used. In Iceland, Norway and Poland the same system
-   is being introduced. The second carrier is 5.85 MHz above the vision
-   carrier and is DQPSK modulated with 728 kbit/s sound and data
-   multiplex. (NICAM system)
-
-.. [#f7]
-   In the United Kingdom, a system of two sound carriers is used. The
-   second sound carrier is 6.552 MHz above the vision carrier and is
-   DQPSK modulated with a 728 kbit/s sound and data multiplex able to
-   carry two sound channels. (NICAM system)
-
-.. [#f8]
-   In France, a digital carrier 5.85 MHz away from the vision carrier
-   may be used in addition to the main sound carrier. It is modulated in
-   differentially encoded QPSK with a 728 kbit/s sound and data
-   multiplexer capable of carrying two sound channels. (NICAM system)
diff --git a/Documentation/media/uapi/v4l/vidioc-expbuf.rst b/Documentation/media/uapi/v4l/vidioc-expbuf.rst
deleted file mode 100644
index 4bd8cd79754c..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-expbuf.rst
+++ /dev/null
@@ -1,175 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_EXPBUF:
-
-*******************
-ioctl VIDIOC_EXPBUF
-*******************
-
-Name
-====
-
-VIDIOC_EXPBUF - Export a buffer as a DMABUF file descriptor.
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_EXPBUF, struct v4l2_exportbuffer *argp )
-    :name: VIDIOC_EXPBUF
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_exportbuffer`.
-
-
-Description
-===========
-
-This ioctl is an extension to the :ref:`memory mapping <mmap>` I/O
-method, therefore it is available only for ``V4L2_MEMORY_MMAP`` buffers.
-It can be used to export a buffer as a DMABUF file at any time after
-buffers have been allocated with the
-:ref:`VIDIOC_REQBUFS` ioctl.
-
-To export a buffer, applications fill struct
-:c:type:`v4l2_exportbuffer`. The ``type`` field is
-set to the same buffer type as was previously used with struct
-:c:type:`v4l2_requestbuffers` ``type``.
-Applications must also set the ``index`` field. Valid index numbers
-range from zero to the number of buffers allocated with
-:ref:`VIDIOC_REQBUFS` (struct
-:c:type:`v4l2_requestbuffers` ``count``) minus
-one. For the multi-planar API, applications set the ``plane`` field to
-the index of the plane to be exported. Valid planes range from zero to
-the maximal number of valid planes for the currently active format. For
-the single-planar API, applications must set ``plane`` to zero.
-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:`VIDIOC_EXPBUF` calls.
-
-After calling :ref:`VIDIOC_EXPBUF` the ``fd`` field will be set by a
-driver. This is a DMABUF file descriptor. The application may pass it to
-other DMABUF-aware devices. Refer to :ref:`DMABUF importing <dmabuf>`
-for details about importing DMABUF files into V4L2 nodes. 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 v4l2_buf_type bt, int index, int *dmafd)
-    {
-	struct v4l2_exportbuffer expbuf;
-
-	memset(&expbuf, 0, sizeof(expbuf));
-	expbuf.type = bt;
-	expbuf.index = index;
-	if (ioctl(v4lfd, VIDIOC_EXPBUF, &expbuf) == -1) {
-	    perror("VIDIOC_EXPBUF");
-	    return -1;
-	}
-
-	*dmafd = expbuf.fd;
-
-	return 0;
-    }
-
-
-.. code-block:: c
-
-    int buffer_export_mp(int v4lfd, enum v4l2_buf_type bt, int index,
-	int dmafd[], int n_planes)
-    {
-	int i;
-
-	for (i = 0; i < n_planes; ++i) {
-	    struct v4l2_exportbuffer expbuf;
-
-	    memset(&expbuf, 0, sizeof(expbuf));
-	    expbuf.type = bt;
-	    expbuf.index = index;
-	    expbuf.plane = i;
-	    if (ioctl(v4lfd, VIDIOC_EXPBUF, &expbuf) == -1) {
-		perror("VIDIOC_EXPBUF");
-		while (i)
-		    close(dmafd[--i]);
-		return -1;
-	    }
-	    dmafd[i] = expbuf.fd;
-	}
-
-	return 0;
-    }
-
-
-.. c:type:: v4l2_exportbuffer
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. flat-table:: struct v4l2_exportbuffer
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``type``
-      - Type of the buffer, same as struct
-	:c:type:`v4l2_format` ``type`` or struct
-	:c:type:`v4l2_requestbuffers` ``type``, set
-	by the application. See :c:type:`v4l2_buf_type`
-    * - __u32
-      - ``index``
-      - Number of the buffer, set by the application. This field is only
-	used for :ref:`memory mapping <mmap>` I/O and can range from
-	zero to the number of buffers allocated with the
-	:ref:`VIDIOC_REQBUFS` and/or
-	:ref:`VIDIOC_CREATE_BUFS` ioctls.
-    * - __u32
-      - ``plane``
-      - Index of the plane to be exported when using the multi-planar API.
-	Otherwise this value must be set to zero.
-    * - __u32
-      - ``flags``
-      - Flags for the newly created file, currently only ``O_CLOEXEC``,
-	``O_RDONLY``, ``O_WRONLY``, and ``O_RDWR`` are supported, refer to
-	the manual of open() for more details.
-    * - __s32
-      - ``fd``
-      - The DMABUF file descriptor associated with a buffer. Set by the
-	driver.
-    * - __u32
-      - ``reserved[11]``
-      - Reserved field for future use. Drivers and applications must set
-	the array to zero.
-
-
-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 ``type`` or ``index`` or ``plane`` fields are invalid.
diff --git a/Documentation/media/uapi/v4l/vidioc-g-audio.rst b/Documentation/media/uapi/v4l/vidioc-g-audio.rst
deleted file mode 100644
index 7af4fe478ba4..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-g-audio.rst
+++ /dev/null
@@ -1,135 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_G_AUDIO:
-
-************************************
-ioctl VIDIOC_G_AUDIO, VIDIOC_S_AUDIO
-************************************
-
-Name
-====
-
-VIDIOC_G_AUDIO - VIDIOC_S_AUDIO - Query or select the current audio input and its attributes
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_G_AUDIO, struct v4l2_audio *argp )
-    :name: VIDIOC_G_AUDIO
-
-.. c:function:: int ioctl( int fd, VIDIOC_S_AUDIO, const struct v4l2_audio *argp )
-    :name: VIDIOC_S_AUDIO
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_audio`.
-
-
-Description
-===========
-
-To query the current audio input applications zero out the ``reserved``
-array of a struct :c:type:`v4l2_audio` and call the
-:ref:`VIDIOC_G_AUDIO <VIDIOC_G_AUDIO>` ioctl with a pointer to this structure. Drivers fill
-the rest of the structure or return an ``EINVAL`` error code when the device
-has no audio inputs, or none which combine with the current video input.
-
-Audio inputs have one writable property, the audio mode. To select the
-current audio input *and* change the audio mode, applications initialize
-the ``index`` and ``mode`` fields, and the ``reserved`` array of a
-struct :c:type:`v4l2_audio` structure and call the :ref:`VIDIOC_S_AUDIO <VIDIOC_G_AUDIO>`
-ioctl. Drivers may switch to a different audio mode if the request
-cannot be satisfied. However, this is a write-only ioctl, it does not
-return the actual new audio mode.
-
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. c:type:: v4l2_audio
-
-.. flat-table:: struct v4l2_audio
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``index``
-      - Identifies the audio input, set by the driver or application.
-    * - __u8
-      - ``name``\ [32]
-      - Name of the audio input, a NUL-terminated ASCII string, for
-	example: "Line In". This information is intended for the user,
-	preferably the connector label on the device itself.
-    * - __u32
-      - ``capability``
-      - Audio capability flags, see :ref:`audio-capability`.
-    * - __u32
-      - ``mode``
-      - Audio mode flags set by drivers and applications (on
-	:ref:`VIDIOC_S_AUDIO <VIDIOC_G_AUDIO>` ioctl), see :ref:`audio-mode`.
-    * - __u32
-      - ``reserved``\ [2]
-      - Reserved for future extensions. Drivers and applications must set
-	the array to zero.
-
-
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. _audio-capability:
-
-.. flat-table:: Audio Capability Flags
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_AUDCAP_STEREO``
-      - 0x00001
-      - This is a stereo input. The flag is intended to automatically
-	disable stereo recording etc. when the signal is always monaural.
-	The API provides no means to detect if stereo is *received*,
-	unless the audio input belongs to a tuner.
-    * - ``V4L2_AUDCAP_AVL``
-      - 0x00002
-      - Automatic Volume Level mode is supported.
-
-
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. _audio-mode:
-
-.. flat-table:: Audio Mode Flags
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_AUDMODE_AVL``
-      - 0x00001
-      - AVL mode is on.
-
-
-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
-    No audio inputs combine with the current video input, or the number
-    of the selected audio input is out of bounds or it does not combine.
diff --git a/Documentation/media/uapi/v4l/vidioc-g-audioout.rst b/Documentation/media/uapi/v4l/vidioc-g-audioout.rst
deleted file mode 100644
index c6ea0396a96a..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-g-audioout.rst
+++ /dev/null
@@ -1,108 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_G_AUDOUT:
-
-**************************************
-ioctl VIDIOC_G_AUDOUT, VIDIOC_S_AUDOUT
-**************************************
-
-Name
-====
-
-VIDIOC_G_AUDOUT - VIDIOC_S_AUDOUT - Query or select the current audio output
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_G_AUDOUT, struct v4l2_audioout *argp )
-    :name: VIDIOC_G_AUDOUT
-
-.. c:function:: int ioctl( int fd, VIDIOC_S_AUDOUT, const struct v4l2_audioout *argp )
-    :name: VIDIOC_S_AUDOUT
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_audioout`.
-
-
-Description
-===========
-
-To query the current audio output applications zero out the ``reserved``
-array of a struct :c:type:`v4l2_audioout` and call the
-``VIDIOC_G_AUDOUT`` ioctl with a pointer to this structure. Drivers fill
-the rest of the structure or return an ``EINVAL`` error code when the device
-has no audio inputs, or none which combine with the current video
-output.
-
-Audio outputs have no writable properties. Nevertheless, to select the
-current audio output applications can initialize the ``index`` field and
-``reserved`` array (which in the future may contain writable properties)
-of a struct :c:type:`v4l2_audioout` structure and call the
-``VIDIOC_S_AUDOUT`` ioctl. Drivers switch to the requested output or
-return the ``EINVAL`` error code when the index is out of bounds. This is a
-write-only ioctl, it does not return the current audio output attributes
-as ``VIDIOC_G_AUDOUT`` does.
-
-.. note::
-
-   Connectors on a TV card to loop back the received audio signal
-   to a sound card are not audio outputs in this sense.
-
-
-.. c:type:: v4l2_audioout
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. flat-table:: struct v4l2_audioout
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``index``
-      - Identifies the audio output, set by the driver or application.
-    * - __u8
-      - ``name``\ [32]
-      - Name of the audio output, a NUL-terminated ASCII string, for
-	example: "Line Out". This information is intended for the user,
-	preferably the connector label on the device itself.
-    * - __u32
-      - ``capability``
-      - Audio capability flags, none defined yet. Drivers must set this
-	field to zero.
-    * - __u32
-      - ``mode``
-      - Audio mode, none defined yet. Drivers and applications (on
-	``VIDIOC_S_AUDOUT``) must set this field to zero.
-    * - __u32
-      - ``reserved``\ [2]
-      - Reserved for future extensions. Drivers and applications must set
-	the array to zero.
-
-
-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
-    No audio outputs combine with the current video output, or the
-    number of the selected audio output is out of bounds or it does not
-    combine.
diff --git a/Documentation/media/uapi/v4l/vidioc-g-crop.rst b/Documentation/media/uapi/v4l/vidioc-g-crop.rst
deleted file mode 100644
index 1eff59dc5f35..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-g-crop.rst
+++ /dev/null
@@ -1,119 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_G_CROP:
-
-**********************************
-ioctl VIDIOC_G_CROP, VIDIOC_S_CROP
-**********************************
-
-Name
-====
-
-VIDIOC_G_CROP - VIDIOC_S_CROP - Get or set the current cropping rectangle
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_G_CROP, struct v4l2_crop *argp )
-    :name: VIDIOC_G_CROP
-
-.. c:function:: int ioctl( int fd, VIDIOC_S_CROP, const struct v4l2_crop *argp )
-    :name: VIDIOC_S_CROP
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_crop`.
-
-
-Description
-===========
-
-To query the cropping rectangle size and position applications set the
-``type`` field of a struct :c:type:`v4l2_crop` structure to the
-respective buffer (stream) type and call the :ref:`VIDIOC_G_CROP <VIDIOC_G_CROP>` ioctl
-with a pointer to this structure. The driver fills the rest of the
-structure or returns the ``EINVAL`` error code if cropping is not supported.
-
-To change the cropping rectangle applications initialize the ``type``
-and struct :c:type:`v4l2_rect` substructure named ``c`` of a
-v4l2_crop structure and call the :ref:`VIDIOC_S_CROP <VIDIOC_G_CROP>` ioctl with a pointer
-to this structure.
-
-The driver first adjusts the requested dimensions against hardware
-limits, i. e. the bounds given by the capture/output window, and it
-rounds to the closest possible values of horizontal and vertical offset,
-width and height. In particular the driver must round the vertical
-offset of the cropping rectangle to frame lines modulo two, such that
-the field order cannot be confused.
-
-Second the driver adjusts the image size (the opposite rectangle of the
-scaling process, source or target depending on the data direction) to
-the closest size possible while maintaining the current horizontal and
-vertical scaling factor.
-
-Finally the driver programs the hardware with the actual cropping and
-image parameters. :ref:`VIDIOC_S_CROP <VIDIOC_G_CROP>` is a write-only ioctl, it does not
-return the actual parameters. To query them applications must call
-:ref:`VIDIOC_G_CROP <VIDIOC_G_CROP>` and :ref:`VIDIOC_G_FMT`. When the
-parameters are unsuitable the application may modify the cropping or
-image parameters and repeat the cycle until satisfactory parameters have
-been negotiated.
-
-When cropping is not supported then no parameters are changed and
-:ref:`VIDIOC_S_CROP <VIDIOC_G_CROP>` returns the ``EINVAL`` error code.
-
-
-.. c:type:: v4l2_crop
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. flat-table:: struct v4l2_crop
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``type``
-      - Type of the data stream, set by the application. Only these types
-	are valid here: ``V4L2_BUF_TYPE_VIDEO_CAPTURE``, ``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE``,
-	``V4L2_BUF_TYPE_VIDEO_OUTPUT``, ``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE`` and
-	``V4L2_BUF_TYPE_VIDEO_OVERLAY``. See :c:type:`v4l2_buf_type` and the note below.
-    * - struct :c:type:`v4l2_rect`
-      - ``c``
-      - Cropping rectangle. The same co-ordinate system as for struct
-	:c:type:`v4l2_cropcap` ``bounds`` is used.
-
-.. note::
-   Unfortunately in the case of multiplanar buffer types
-   (``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE`` and ``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE``)
-   this API was messed up with regards to how the :c:type:`v4l2_crop` ``type`` field
-   should be filled in. Some drivers only accepted the ``_MPLANE`` buffer type while
-   other drivers only accepted a non-multiplanar buffer type (i.e. without the
-   ``_MPLANE`` at the end).
-
-   Starting with kernel 4.13 both variations are allowed.
-
-
-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.
-
-ENODATA
-    Cropping is not supported for this input or output.
diff --git a/Documentation/media/uapi/v4l/vidioc-g-ctrl.rst b/Documentation/media/uapi/v4l/vidioc-g-ctrl.rst
deleted file mode 100644
index 8493b52adbb2..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-g-ctrl.rst
+++ /dev/null
@@ -1,106 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_G_CTRL:
-
-**********************************
-ioctl VIDIOC_G_CTRL, VIDIOC_S_CTRL
-**********************************
-
-Name
-====
-
-VIDIOC_G_CTRL - VIDIOC_S_CTRL - Get or set the value of a control
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_G_CTRL, struct v4l2_control *argp )
-    :name: VIDIOC_G_CTRL
-
-.. c:function:: int ioctl( int fd, VIDIOC_S_CTRL, struct v4l2_control *argp )
-    :name: VIDIOC_S_CTRL
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_control`.
-
-
-Description
-===========
-
-To get the current value of a control applications initialize the ``id``
-field of a struct :c:type:`v4l2_control` and call the
-:ref:`VIDIOC_G_CTRL <VIDIOC_G_CTRL>` ioctl with a pointer to this structure. To change the
-value of a control applications initialize the ``id`` and ``value``
-fields of a struct :c:type:`v4l2_control` and call the
-:ref:`VIDIOC_S_CTRL <VIDIOC_G_CTRL>` ioctl.
-
-When the ``id`` is invalid drivers return an ``EINVAL`` error code. When the
-``value`` is out of bounds drivers can choose to take the closest valid
-value or return an ``ERANGE`` error code, whatever seems more appropriate.
-However, :ref:`VIDIOC_S_CTRL <VIDIOC_G_CTRL>` is a write-only ioctl, it does not return the
-actual new value. If the ``value`` is inappropriate for the control
-(e.g. if it refers to an unsupported menu index of a menu control), then
-EINVAL error code is returned as well.
-
-These ioctls work only with user controls. For other control classes the
-:ref:`VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>`,
-:ref:`VIDIOC_S_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` or
-:ref:`VIDIOC_TRY_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` must be used.
-
-
-.. c:type:: v4l2_control
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. flat-table:: struct v4l2_control
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``id``
-      - Identifies the control, set by the application.
-    * - __s32
-      - ``value``
-      - New value or current value.
-
-
-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
-    The struct :c:type:`v4l2_control` ``id`` is invalid
-    or the ``value`` is inappropriate for the given control (i.e. if a
-    menu item is selected that is not supported by the driver according
-    to :ref:`VIDIOC_QUERYMENU <VIDIOC_QUERYCTRL>`).
-
-ERANGE
-    The struct :c:type:`v4l2_control` ``value`` is out of
-    bounds.
-
-EBUSY
-    The control is temporarily not changeable, possibly because another
-    applications took over control of the device function this control
-    belongs to.
-
-EACCES
-    Attempt to set a read-only control or to get a write-only control.
diff --git a/Documentation/media/uapi/v4l/vidioc-g-dv-timings.rst b/Documentation/media/uapi/v4l/vidioc-g-dv-timings.rst
deleted file mode 100644
index e36dd2622857..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-g-dv-timings.rst
+++ /dev/null
@@ -1,312 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_G_DV_TIMINGS:
-
-**********************************************
-ioctl VIDIOC_G_DV_TIMINGS, VIDIOC_S_DV_TIMINGS
-**********************************************
-
-Name
-====
-
-VIDIOC_G_DV_TIMINGS - VIDIOC_S_DV_TIMINGS - VIDIOC_SUBDEV_G_DV_TIMINGS - VIDIOC_SUBDEV_S_DV_TIMINGS - Get or set DV timings for input or output
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_G_DV_TIMINGS, struct v4l2_dv_timings *argp )
-    :name: VIDIOC_G_DV_TIMINGS
-
-.. c:function:: int ioctl( int fd, VIDIOC_S_DV_TIMINGS, struct v4l2_dv_timings *argp )
-    :name: VIDIOC_S_DV_TIMINGS
-
-.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_G_DV_TIMINGS, struct v4l2_dv_timings *argp )
-    :name: VIDIOC_SUBDEV_G_DV_TIMINGS
-
-.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_S_DV_TIMINGS, struct v4l2_dv_timings *argp )
-    :name: VIDIOC_SUBDEV_S_DV_TIMINGS
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_dv_timings`.
-
-
-Description
-===========
-
-To set DV timings for the input or output, applications use the
-:ref:`VIDIOC_S_DV_TIMINGS <VIDIOC_G_DV_TIMINGS>` ioctl and to get the current timings,
-applications use the :ref:`VIDIOC_G_DV_TIMINGS <VIDIOC_G_DV_TIMINGS>` ioctl. The detailed timing
-information is filled in using the structure struct
-:c:type:`v4l2_dv_timings`. These ioctls take a
-pointer to the struct :c:type:`v4l2_dv_timings`
-structure as argument. If the ioctl is not supported or the timing
-values are not correct, the driver returns ``EINVAL`` error code.
-
-The ``linux/v4l2-dv-timings.h`` header can be used to get the timings of
-the formats in the :ref:`cea861` and :ref:`vesadmt` standards. If
-the current input or output does not support DV timings (e.g. if
-:ref:`VIDIOC_ENUMINPUT` does not set the
-``V4L2_IN_CAP_DV_TIMINGS`` flag), then ``ENODATA`` error code is returned.
-
-
-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
-    This ioctl is not supported, or the :ref:`VIDIOC_S_DV_TIMINGS <VIDIOC_G_DV_TIMINGS>`
-    parameter was unsuitable.
-
-ENODATA
-    Digital video timings are not supported for this input or output.
-
-EBUSY
-    The device is busy and therefore can not change the timings.
-
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. c:type:: v4l2_bt_timings
-
-.. flat-table:: struct v4l2_bt_timings
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``width``
-      - Width of the active video in pixels.
-    * - __u32
-      - ``height``
-      - Height of the active video frame in lines. So for interlaced
-	formats the height of the active video in each field is
-	``height``/2.
-    * - __u32
-      - ``interlaced``
-      - Progressive (``V4L2_DV_PROGRESSIVE``) or interlaced (``V4L2_DV_INTERLACED``).
-    * - __u32
-      - ``polarities``
-      - This is a bit mask that defines polarities of sync signals. bit 0
-	(``V4L2_DV_VSYNC_POS_POL``) is for vertical sync polarity and bit
-	1 (``V4L2_DV_HSYNC_POS_POL``) is for horizontal sync polarity. If
-	the bit is set (1) it is positive polarity and if is cleared (0),
-	it is negative polarity.
-    * - __u64
-      - ``pixelclock``
-      - Pixel clock in Hz. Ex. 74.25MHz->74250000
-    * - __u32
-      - ``hfrontporch``
-      - Horizontal front porch in pixels
-    * - __u32
-      - ``hsync``
-      - Horizontal sync length in pixels
-    * - __u32
-      - ``hbackporch``
-      - Horizontal back porch in pixels
-    * - __u32
-      - ``vfrontporch``
-      - Vertical front porch in lines. For interlaced formats this refers
-	to the odd field (aka field 1).
-    * - __u32
-      - ``vsync``
-      - Vertical sync length in lines. For interlaced formats this refers
-	to the odd field (aka field 1).
-    * - __u32
-      - ``vbackporch``
-      - Vertical back porch in lines. For interlaced formats this refers
-	to the odd field (aka field 1).
-    * - __u32
-      - ``il_vfrontporch``
-      - Vertical front porch in lines for the even field (aka field 2) of
-	interlaced field formats. Must be 0 for progressive formats.
-    * - __u32
-      - ``il_vsync``
-      - Vertical sync length in lines for the even field (aka field 2) of
-	interlaced field formats. Must be 0 for progressive formats.
-    * - __u32
-      - ``il_vbackporch``
-      - Vertical back porch in lines for the even field (aka field 2) of
-	interlaced field formats. Must be 0 for progressive formats.
-    * - __u32
-      - ``standards``
-      - The video standard(s) this format belongs to. This will be filled
-	in by the driver. Applications must set this to 0. See
-	:ref:`dv-bt-standards` for a list of standards.
-    * - __u32
-      - ``flags``
-      - Several flags giving more information about the format. See
-	:ref:`dv-bt-flags` for a description of the flags.
-    * - struct :c:type:`v4l2_fract`
-      - ``picture_aspect``
-      - The picture aspect if the pixels are not square. Only valid if the
-        ``V4L2_DV_FL_HAS_PICTURE_ASPECT`` flag is set.
-    * - __u8
-      - ``cea861_vic``
-      - The Video Identification Code according to the CEA-861 standard.
-        Only valid if the ``V4L2_DV_FL_HAS_CEA861_VIC`` flag is set.
-    * - __u8
-      - ``hdmi_vic``
-      - The Video Identification Code according to the HDMI standard.
-        Only valid if the ``V4L2_DV_FL_HAS_HDMI_VIC`` flag is set.
-    * - __u8
-      - ``reserved[46]``
-      - Reserved for future extensions. Drivers and applications must set
-	the array to zero.
-
-
-.. tabularcolumns:: |p{3.5cm}|p{3.5cm}|p{7.0cm}|p{3.5cm}|
-
-.. c:type:: v4l2_dv_timings
-
-.. flat-table:: struct v4l2_dv_timings
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``type``
-      - Type of DV timings as listed in :ref:`dv-timing-types`.
-    * - union {
-      - (anonymous)
-    * - struct :c:type:`v4l2_bt_timings`
-      - ``bt``
-      - Timings defined by BT.656/1120 specifications
-    * - __u32
-      - ``reserved``\ [32]
-      -
-    * - }
-      -
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. _dv-timing-types:
-
-.. flat-table:: DV Timing types
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - Timing type
-      - value
-      - Description
-    * -
-      -
-      -
-    * - ``V4L2_DV_BT_656_1120``
-      - 0
-      - BT.656/1120 timings
-
-.. tabularcolumns:: |p{4.5cm}|p{12.8cm}|
-
-.. _dv-bt-standards:
-
-.. flat-table:: DV BT Timing standards
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - Timing standard
-      - Description
-    * - ``V4L2_DV_BT_STD_CEA861``
-      - The timings follow the CEA-861 Digital TV Profile standard
-    * - ``V4L2_DV_BT_STD_DMT``
-      - The timings follow the VESA Discrete Monitor Timings standard
-    * - ``V4L2_DV_BT_STD_CVT``
-      - The timings follow the VESA Coordinated Video Timings standard
-    * - ``V4L2_DV_BT_STD_GTF``
-      - The timings follow the VESA Generalized Timings Formula standard
-    * - ``V4L2_DV_BT_STD_SDI``
-      - The timings follow the SDI Timings standard.
-	There are no horizontal syncs/porches at all in this format.
-	Total blanking timings must be set in hsync or vsync fields only.
-
-.. tabularcolumns:: |p{7.0cm}|p{10.5cm}|
-
-.. _dv-bt-flags:
-
-.. flat-table:: DV BT Timing flags
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - Flag
-      - Description
-    * - ``V4L2_DV_FL_REDUCED_BLANKING``
-      - CVT/GTF specific: the timings use reduced blanking (CVT) or the
-	'Secondary GTF' curve (GTF). In both cases the horizontal and/or
-	vertical blanking intervals are reduced, allowing a higher
-	resolution over the same bandwidth. This is a read-only flag,
-	applications must not set this.
-    * - ``V4L2_DV_FL_CAN_REDUCE_FPS``
-      - CEA-861 specific: set for CEA-861 formats with a framerate that is
-	a multiple of six. These formats can be optionally played at 1 /
-	1.001 speed to be compatible with 60 Hz based standards such as
-	NTSC and PAL-M that use a framerate of 29.97 frames per second. If
-	the transmitter can't generate such frequencies, then the flag
-	will also be cleared. This is a read-only flag, applications must
-	not set this.
-    * - ``V4L2_DV_FL_REDUCED_FPS``
-      - CEA-861 specific: only valid for video transmitters or video
-        receivers that have the ``V4L2_DV_FL_CAN_DETECT_REDUCED_FPS``
-	set. This flag is cleared otherwise. It is also only valid for
-	formats with the ``V4L2_DV_FL_CAN_REDUCE_FPS`` flag set, for other
-	formats the flag will be cleared by the driver.
-
-	If the application sets this flag for a transmitter, then the
-	pixelclock used to set up the transmitter is divided by 1.001 to
-	make it compatible with NTSC framerates. If the transmitter can't
-	generate such frequencies, then the flag will be cleared.
-
-	If a video receiver detects that the format uses a reduced framerate,
-	then it will set this flag to signal this to the application.
-    * - ``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
-	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
-	used depends on the hardware.
-    * - ``V4L2_DV_FL_IS_CE_VIDEO``
-      - If set, then this is a Consumer Electronics (CE) video format.
-	Such formats differ from other formats (commonly called IT
-	formats) in that if R'G'B' encoding is used then by default the
-	R'G'B' values use limited range (i.e. 16-235) as opposed to full
-	range (i.e. 0-255). All formats defined in CEA-861 except for the
-	640x480p59.94 format are CE formats.
-    * - ``V4L2_DV_FL_FIRST_FIELD_EXTRA_LINE``
-      - Some formats like SMPTE-125M have an interlaced signal with a odd
-	total height. For these formats, if this flag is set, the first
-	field has the extra line. Else, it is the second field.
-    * - ``V4L2_DV_FL_HAS_PICTURE_ASPECT``
-      - If set, then the picture_aspect field is valid. Otherwise assume that
-        the pixels are square, so the picture aspect ratio is the same as the
-	width to height ratio.
-    * - ``V4L2_DV_FL_HAS_CEA861_VIC``
-      - If set, then the cea861_vic field is valid and contains the Video
-        Identification Code as per the CEA-861 standard.
-    * - ``V4L2_DV_FL_HAS_HDMI_VIC``
-      - If set, then the hdmi_vic field is valid and contains the Video
-        Identification Code as per the HDMI standard (HDMI Vendor Specific
-	InfoFrame).
-    * - ``V4L2_DV_FL_CAN_DETECT_REDUCED_FPS``
-      - CEA-861 specific: only valid for video receivers, the flag is
-        cleared by transmitters.
-        If set, then the hardware can detect the difference between
-	regular framerates and framerates reduced by 1000/1001. E.g.:
-	60 vs 59.94 Hz, 30 vs 29.97 Hz or 24 vs 23.976 Hz.
diff --git a/Documentation/media/uapi/v4l/vidioc-g-edid.rst b/Documentation/media/uapi/v4l/vidioc-g-edid.rst
deleted file mode 100644
index e55b349a0c7e..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-g-edid.rst
+++ /dev/null
@@ -1,154 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_G_EDID:
-
-******************************************************************************
-ioctl VIDIOC_G_EDID, VIDIOC_S_EDID, VIDIOC_SUBDEV_G_EDID, VIDIOC_SUBDEV_S_EDID
-******************************************************************************
-
-Name
-====
-
-VIDIOC_G_EDID - VIDIOC_S_EDID - VIDIOC_SUBDEV_G_EDID - VIDIOC_SUBDEV_S_EDID - Get or set the EDID of a video receiver/transmitter
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_G_EDID, struct v4l2_edid *argp )
-    :name: VIDIOC_G_EDID
-
-.. c:function:: int ioctl( int fd, VIDIOC_S_EDID, struct v4l2_edid *argp )
-    :name: VIDIOC_S_EDID
-
-
-.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_G_EDID, struct v4l2_edid *argp )
-    :name: VIDIOC_SUBDEV_G_EDID
-
-.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_S_EDID, struct v4l2_edid *argp )
-    :name: VIDIOC_SUBDEV_S_EDID
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-   Pointer to struct :c:type:`v4l2_edid`.
-
-
-Description
-===========
-
-These ioctls can be used to get or set an EDID associated with an input
-from a receiver or an output of a transmitter device. They can be used
-with subdevice nodes (/dev/v4l-subdevX) or with video nodes
-(/dev/videoX).
-
-When used with video nodes the ``pad`` field represents the input (for
-video capture devices) or output (for video output devices) index as is
-returned by :ref:`VIDIOC_ENUMINPUT` and
-:ref:`VIDIOC_ENUMOUTPUT` respectively. When used
-with subdevice nodes the ``pad`` field represents the input or output
-pad of the subdevice. If there is no EDID support for the given ``pad``
-value, then the ``EINVAL`` error code will be returned.
-
-To get the EDID data the application has to fill in the ``pad``,
-``start_block``, ``blocks`` and ``edid`` fields, zero the ``reserved``
-array and call :ref:`VIDIOC_G_EDID <VIDIOC_G_EDID>`. The current EDID from block
-``start_block`` and of size ``blocks`` will be placed in the memory
-``edid`` points to. The ``edid`` pointer must point to memory at least
-``blocks`` * 128 bytes large (the size of one block is 128 bytes).
-
-If there are fewer blocks than specified, then the driver will set
-``blocks`` to the actual number of blocks. If there are no EDID blocks
-available at all, then the error code ``ENODATA`` is set.
-
-If blocks have to be retrieved from the sink, then this call will block
-until they have been read.
-
-If ``start_block`` and ``blocks`` are both set to 0 when
-:ref:`VIDIOC_G_EDID <VIDIOC_G_EDID>` is called, then the driver will set ``blocks`` to the
-total number of available EDID blocks and it will return 0 without
-copying any data. This is an easy way to discover how many EDID blocks
-there are.
-
-.. note::
-
-   If there are no EDID blocks available at all, then
-   the driver will set ``blocks`` to 0 and it returns 0.
-
-To set the EDID blocks of a receiver the application has to fill in the
-``pad``, ``blocks`` and ``edid`` fields, set ``start_block`` to 0 and
-zero the ``reserved`` array. It is not possible to set part of an EDID,
-it is always all or nothing. Setting the EDID data is only valid for
-receivers as it makes no sense for a transmitter.
-
-The driver assumes that the full EDID is passed in. If there are more
-EDID blocks than the hardware can handle then the EDID is not written,
-but instead the error code ``E2BIG`` is set and ``blocks`` is set to the
-maximum that the hardware supports. If ``start_block`` is any value
-other than 0 then the error code ``EINVAL`` is set.
-
-To disable an EDID you set ``blocks`` to 0. Depending on the hardware
-this will drive the hotplug pin low and/or block the source from reading
-the EDID data in some way. In any case, the end result is the same: the
-EDID is no longer available.
-
-
-.. c:type:: v4l2_edid
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. flat-table:: struct v4l2_edid
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``pad``
-      - Pad for which to get/set the EDID blocks. When used with a video
-	device node the pad represents the input or output index as
-	returned by :ref:`VIDIOC_ENUMINPUT` and
-	:ref:`VIDIOC_ENUMOUTPUT` respectively.
-    * - __u32
-      - ``start_block``
-      - Read the EDID from starting with this block. Must be 0 when
-	setting the EDID.
-    * - __u32
-      - ``blocks``
-      - The number of blocks to get or set. Must be less or equal to 256
-	(the maximum number of blocks as defined by the standard). When
-	you set the EDID and ``blocks`` is 0, then the EDID is disabled or
-	erased.
-    * - __u32
-      - ``reserved``\ [5]
-      - Reserved for future extensions. Applications and drivers must set
-	the array to zero.
-    * - __u8 *
-      - ``edid``
-      - Pointer to memory that contains the EDID. The minimum size is
-	``blocks`` * 128.
-
-
-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.
-
-``ENODATA``
-    The EDID data is not available.
-
-``E2BIG``
-    The EDID data you provided is more than the hardware can handle.
diff --git a/Documentation/media/uapi/v4l/vidioc-g-enc-index.rst b/Documentation/media/uapi/v4l/vidioc-g-enc-index.rst
deleted file mode 100644
index e285a1f14cdf..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-g-enc-index.rst
+++ /dev/null
@@ -1,156 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_G_ENC_INDEX:
-
-************************
-ioctl VIDIOC_G_ENC_INDEX
-************************
-
-Name
-====
-
-VIDIOC_G_ENC_INDEX - Get meta data about a compressed video stream
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_G_ENC_INDEX, struct v4l2_enc_idx *argp )
-    :name: VIDIOC_G_ENC_INDEX
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_enc_idx`.
-
-
-Description
-===========
-
-The :ref:`VIDIOC_G_ENC_INDEX <VIDIOC_G_ENC_INDEX>` ioctl provides meta data about a compressed
-video stream the same or another application currently reads from the
-driver, which is useful for random access into the stream without
-decoding it.
-
-To read the data applications must call :ref:`VIDIOC_G_ENC_INDEX <VIDIOC_G_ENC_INDEX>` with a
-pointer to a struct :c:type:`v4l2_enc_idx`. On success
-the driver fills the ``entry`` array, stores the number of elements
-written in the ``entries`` field, and initializes the ``entries_cap``
-field.
-
-Each element of the ``entry`` array contains meta data about one
-picture. A :ref:`VIDIOC_G_ENC_INDEX <VIDIOC_G_ENC_INDEX>` call reads up to
-``V4L2_ENC_IDX_ENTRIES`` entries from a driver buffer, which can hold up
-to ``entries_cap`` entries. This number can be lower or higher than
-``V4L2_ENC_IDX_ENTRIES``, but not zero. When the application fails to
-read the meta data in time the oldest entries will be lost. When the
-buffer is empty or no capturing/encoding is in progress, ``entries``
-will be zero.
-
-Currently this ioctl is only defined for MPEG-2 program streams and
-video elementary streams.
-
-
-.. tabularcolumns:: |p{3.8cm}|p{5.6cm}|p{8.1cm}|
-
-.. c:type:: v4l2_enc_idx
-
-.. flat-table:: struct v4l2_enc_idx
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 3 8
-
-    * - __u32
-      - ``entries``
-      - The number of entries the driver stored in the ``entry`` array.
-    * - __u32
-      - ``entries_cap``
-      - The number of entries the driver can buffer. Must be greater than
-	zero.
-    * - __u32
-      - ``reserved``\ [4]
-      - Reserved for future extensions. Drivers must set the
-	array to zero.
-    * - struct :c:type:`v4l2_enc_idx_entry`
-      - ``entry``\ [``V4L2_ENC_IDX_ENTRIES``]
-      - Meta data about a compressed video stream. Each element of the
-	array corresponds to one picture, sorted in ascending order by
-	their ``offset``.
-
-
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. c:type:: v4l2_enc_idx_entry
-
-.. flat-table:: struct v4l2_enc_idx_entry
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u64
-      - ``offset``
-      - The offset in bytes from the beginning of the compressed video
-	stream to the beginning of this picture, that is a *PES packet
-	header* as defined in :ref:`mpeg2part1` or a *picture header* as
-	defined in :ref:`mpeg2part2`. When the encoder is stopped, the
-	driver resets the offset to zero.
-    * - __u64
-      - ``pts``
-      - The 33 bit *Presentation Time Stamp* of this picture as defined in
-	:ref:`mpeg2part1`.
-    * - __u32
-      - ``length``
-      - The length of this picture in bytes.
-    * - __u32
-      - ``flags``
-      - Flags containing the coding type of this picture, see
-	:ref:`enc-idx-flags`.
-    * - __u32
-      - ``reserved``\ [2]
-      - Reserved for future extensions. Drivers must set the array to
-	zero.
-
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. _enc-idx-flags:
-
-.. flat-table:: Index Entry Flags
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_ENC_IDX_FRAME_I``
-      - 0x00
-      - This is an Intra-coded picture.
-    * - ``V4L2_ENC_IDX_FRAME_P``
-      - 0x01
-      - This is a Predictive-coded picture.
-    * - ``V4L2_ENC_IDX_FRAME_B``
-      - 0x02
-      - This is a Bidirectionally predictive-coded picture.
-    * - ``V4L2_ENC_IDX_FRAME_MASK``
-      - 0x0F
-      - *AND* the flags field with this mask to obtain the picture coding
-	type.
-
-
-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/v4l/vidioc-g-ext-ctrls.rst b/Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst
deleted file mode 100644
index cdb2a2a512d6..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst
+++ /dev/null
@@ -1,416 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_G_EXT_CTRLS:
-
-******************************************************************
-ioctl VIDIOC_G_EXT_CTRLS, VIDIOC_S_EXT_CTRLS, VIDIOC_TRY_EXT_CTRLS
-******************************************************************
-
-Name
-====
-
-VIDIOC_G_EXT_CTRLS - VIDIOC_S_EXT_CTRLS - VIDIOC_TRY_EXT_CTRLS - Get or set the value of several controls, try control values
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_G_EXT_CTRLS, struct v4l2_ext_controls *argp )
-    :name: VIDIOC_G_EXT_CTRLS
-
-
-.. c:function:: int ioctl( int fd, VIDIOC_S_EXT_CTRLS, struct v4l2_ext_controls *argp )
-    :name: VIDIOC_S_EXT_CTRLS
-
-
-.. c:function:: int ioctl( int fd, VIDIOC_TRY_EXT_CTRLS, struct v4l2_ext_controls *argp )
-    :name: VIDIOC_TRY_EXT_CTRLS
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_ext_controls`.
-
-
-Description
-===========
-
-These ioctls allow the caller to get or set multiple controls
-atomically. Control IDs are grouped into control classes (see
-:ref:`ctrl-class`) and all controls in the control array must belong
-to the same control class.
-
-Applications must always fill in the ``count``, ``which``, ``controls``
-and ``reserved`` fields of struct
-:c:type:`v4l2_ext_controls`, and initialize the
-struct :c:type:`v4l2_ext_control` array pointed to
-by the ``controls`` fields.
-
-To get the current value of a set of controls applications initialize
-the ``id``, ``size`` and ``reserved2`` fields of each struct
-:c:type:`v4l2_ext_control` and call the
-:ref:`VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` ioctl. String controls controls must also set the
-``string`` field. Controls of compound types
-(``V4L2_CTRL_FLAG_HAS_PAYLOAD`` is set) must set the ``ptr`` field.
-
-If the ``size`` is too small to receive the control result (only
-relevant for pointer-type controls like strings), then the driver will
-set ``size`` to a valid value and return an ``ENOSPC`` error code. You
-should re-allocate the memory to this new size and try again. For the
-string type it is possible that the same issue occurs again if the
-string has grown in the meantime. It is recommended to call
-:ref:`VIDIOC_QUERYCTRL` first and use
-``maximum``\ +1 as the new ``size`` value. It is guaranteed that that is
-sufficient memory.
-
-N-dimensional arrays are set and retrieved row-by-row. You cannot set a
-partial array, all elements have to be set or retrieved. The total size
-is calculated as ``elems`` * ``elem_size``. These values can be obtained
-by calling :ref:`VIDIOC_QUERY_EXT_CTRL <VIDIOC_QUERYCTRL>`.
-
-To change the value of a set of controls applications initialize the
-``id``, ``size``, ``reserved2`` and ``value/value64/string/ptr`` fields
-of each struct :c:type:`v4l2_ext_control` and call
-the :ref:`VIDIOC_S_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` ioctl. The controls will only be set if *all*
-control values are valid.
-
-To check if a set of controls have correct values applications
-initialize the ``id``, ``size``, ``reserved2`` and
-``value/value64/string/ptr`` fields of each struct
-:c:type:`v4l2_ext_control` and call the
-:ref:`VIDIOC_TRY_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` ioctl. It is up to the driver whether wrong
-values are automatically adjusted to a valid value or if an error is
-returned.
-
-When the ``id`` or ``which`` is invalid drivers return an ``EINVAL`` error
-code. When the value is out of bounds drivers can choose to take the
-closest valid value or return an ``ERANGE`` error code, whatever seems more
-appropriate. In the first case the new value is set in struct
-:c:type:`v4l2_ext_control`. If the new control value
-is inappropriate (e.g. the given menu index is not supported by the menu
-control), then this will also result in an ``EINVAL`` error code error.
-
-If ``request_fd`` is set to a not-yet-queued :ref:`request <media-request-api>`
-file descriptor and ``which`` is set to ``V4L2_CTRL_WHICH_REQUEST_VAL``,
-then the controls are not applied immediately when calling
-:ref:`VIDIOC_S_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>`, but instead are applied by
-the driver for the buffer associated with the same request.
-If the device does not support requests, then ``EACCES`` will be returned.
-If requests are supported but an invalid request file descriptor is given,
-then ``EINVAL`` will be returned.
-
-An attempt to call :ref:`VIDIOC_S_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` for a
-request that has already been queued will result in an ``EBUSY`` error.
-
-If ``request_fd`` is specified and ``which`` is set to
-``V4L2_CTRL_WHICH_REQUEST_VAL`` during a call to
-:ref:`VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>`, then it will return the
-values of the controls at the time of request completion.
-If the request is not yet completed, then this will result in an
-``EACCES`` error.
-
-The driver will only set/get these controls if all control values are
-correct. This prevents the situation where only some of the controls
-were set/get. Only low-level errors (e. g. a failed i2c command) can
-still cause this situation.
-
-
-.. tabularcolumns:: |p{1.2cm}|p{3.0cm}|p{1.5cm}|p{11.8cm}|
-
-.. c:type:: v4l2_ext_control
-
-.. cssclass: longtable
-
-.. flat-table:: struct v4l2_ext_control
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``id``
-      - Identifies the control, set by the application.
-    * - __u32
-      - ``size``
-      - The total size in bytes of the payload of this control. This is
-	normally 0, but for pointer controls this should be set to the
-	size of the memory containing the payload, or that will receive
-	the payload. If :ref:`VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` finds that this value is
-	less than is required to store the payload result, then it is set
-	to a value large enough to store the payload result and ``ENOSPC`` is
-	returned.
-
-	.. note::
-
-	   For string controls, this ``size`` field should
-	   not be confused with the length of the string. This field refers
-	   to the size of the memory that contains the string. The actual
-	   *length* of the string may well be much smaller.
-    * - __u32
-      - ``reserved2``\ [1]
-      - Reserved for future extensions. Drivers and applications must set
-	the array to zero.
-    * - union {
-      - (anonymous)
-    * - __s32
-      - ``value``
-      - New value or current value. Valid if this control is not of type
-	``V4L2_CTRL_TYPE_INTEGER64`` and ``V4L2_CTRL_FLAG_HAS_PAYLOAD`` is
-	not set.
-    * - __s64
-      - ``value64``
-      - New value or current value. Valid if this control is of type
-	``V4L2_CTRL_TYPE_INTEGER64`` and ``V4L2_CTRL_FLAG_HAS_PAYLOAD`` is
-	not set.
-    * - char *
-      - ``string``
-      - A pointer to a string. Valid if this control is of type
-	``V4L2_CTRL_TYPE_STRING``.
-    * - __u8 *
-      - ``p_u8``
-      - A pointer to a matrix control of unsigned 8-bit values. Valid if
-	this control is of type ``V4L2_CTRL_TYPE_U8``.
-    * - __u16 *
-      - ``p_u16``
-      - A pointer to a matrix control of unsigned 16-bit values. Valid if
-	this control is of type ``V4L2_CTRL_TYPE_U16``.
-    * - __u32 *
-      - ``p_u32``
-      - A pointer to a matrix control of unsigned 32-bit values. Valid if
-	this control is of type ``V4L2_CTRL_TYPE_U32``.
-    * - :c:type:`v4l2_area` *
-      - ``p_area``
-      - A pointer to a struct :c:type:`v4l2_area`. Valid if this control is
-        of type ``V4L2_CTRL_TYPE_AREA``.
-    * - void *
-      - ``ptr``
-      - A pointer to a compound type which can be an N-dimensional array
-	and/or a compound type (the control's type is >=
-	``V4L2_CTRL_COMPOUND_TYPES``). Valid if
-	``V4L2_CTRL_FLAG_HAS_PAYLOAD`` is set for this control.
-    * - }
-      -
-
-
-.. tabularcolumns:: |p{4.0cm}|p{2.2cm}|p{2.1cm}|p{8.2cm}|
-
-.. c:type:: v4l2_ext_controls
-
-.. cssclass:: longtable
-
-.. flat-table:: struct v4l2_ext_controls
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - union {
-      - (anonymous)
-    * - __u32
-      - ``ctrl_class``
-      - The control class to which all controls belong, see
-	:ref:`ctrl-class`. Drivers that use a kernel framework for
-	handling controls will also accept a value of 0 here, meaning that
-	the controls can belong to any control class. Whether drivers
-	support this can be tested by setting ``ctrl_class`` to 0 and
-	calling :ref:`VIDIOC_TRY_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` with a ``count`` of 0. If that
-	succeeds, then the driver supports this feature.
-    * - __u32
-      - ``which``
-      - Which value of the control to get/set/try.
-	``V4L2_CTRL_WHICH_CUR_VAL`` will return the current value of the
-	control, ``V4L2_CTRL_WHICH_DEF_VAL`` will return the default
-	value of the control and ``V4L2_CTRL_WHICH_REQUEST_VAL`` indicates that
-	these controls have to be retrieved from a request or tried/set for
-	a request. In the latter case the ``request_fd`` field contains the
-	file descriptor of the request that should be used. If the device
-	does not support requests, then ``EACCES`` will be returned.
-
-	.. note::
-
-	   When using ``V4L2_CTRL_WHICH_DEF_VAL`` be aware that you can only
-	   get the default value of the control, you cannot set or try it.
-
-	For backwards compatibility you can also use a control class here
-	(see :ref:`ctrl-class`). In that case all controls have to
-	belong to that control class. This usage is deprecated, instead
-	just use ``V4L2_CTRL_WHICH_CUR_VAL``. There are some very old
-	drivers that do not yet support ``V4L2_CTRL_WHICH_CUR_VAL`` and
-	that require a control class here. You can test for such drivers
-	by setting ctrl_class to ``V4L2_CTRL_WHICH_CUR_VAL`` and calling
-	VIDIOC_TRY_EXT_CTRLS with a count of 0. If that fails, then the
-	driver does not support ``V4L2_CTRL_WHICH_CUR_VAL``.
-    * - }
-      -
-    * - __u32
-      - ``count``
-      - The number of controls in the controls array. May also be zero.
-    * - __u32
-      - ``error_idx``
-      - Set by the driver in case of an error. If the error is associated
-	with a particular control, then ``error_idx`` is set to the index
-	of that control. If the error is not related to a specific
-	control, or the validation step failed (see below), then
-	``error_idx`` is set to ``count``. The value is undefined if the
-	ioctl returned 0 (success).
-
-	Before controls are read from/written to hardware a validation
-	step takes place: this checks if all controls in the list are
-	valid controls, if no attempt is made to write to a read-only
-	control or read from a write-only control, and any other up-front
-	checks that can be done without accessing the hardware. The exact
-	validations done during this step are driver dependent since some
-	checks might require hardware access for some devices, thus making
-	it impossible to do those checks up-front. However, drivers should
-	make a best-effort to do as many up-front checks as possible.
-
-	This check is done to avoid leaving the hardware in an
-	inconsistent state due to easy-to-avoid problems. But it leads to
-	another problem: the application needs to know whether an error
-	came from the validation step (meaning that the hardware was not
-	touched) or from an error during the actual reading from/writing
-	to hardware.
-
-	The, in hindsight quite poor, solution for that is to set
-	``error_idx`` to ``count`` if the validation failed. This has the
-	unfortunate side-effect that it is not possible to see which
-	control failed the validation. If the validation was successful
-	and the error happened while accessing the hardware, then
-	``error_idx`` is less than ``count`` and only the controls up to
-	``error_idx-1`` were read or written correctly, and the state of
-	the remaining controls is undefined.
-
-	Since :ref:`VIDIOC_TRY_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` does not access hardware there is
-	also no need to handle the validation step in this special way, so
-	``error_idx`` will just be set to the control that failed the
-	validation step instead of to ``count``. This means that if
-	:ref:`VIDIOC_S_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` fails with ``error_idx`` set to ``count``,
-	then you can call :ref:`VIDIOC_TRY_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` to try to discover the
-	actual control that failed the validation step. Unfortunately,
-	there is no ``TRY`` equivalent for :ref:`VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>`.
-    * - __s32
-      - ``request_fd``
-      - File descriptor of the request to be used by this operation. Only
-	valid if ``which`` is set to ``V4L2_CTRL_WHICH_REQUEST_VAL``.
-	If the device does not support requests, then ``EACCES`` will be returned.
-	If requests are supported but an invalid request file descriptor is
-	given, then ``EINVAL`` will be returned.
-    * - __u32
-      - ``reserved``\ [1]
-      - Reserved for future extensions.
-
-	Drivers and applications must set the array to zero.
-    * - struct :c:type:`v4l2_ext_control` *
-      - ``controls``
-      - Pointer to an array of ``count`` v4l2_ext_control structures.
-
-	Ignored if ``count`` equals zero.
-
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. _ctrl-class:
-
-.. flat-table:: Control classes
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_CTRL_CLASS_USER``
-      - 0x980000
-      - The class containing user controls. These controls are described
-	in :ref:`control`. All controls that can be set using the
-	:ref:`VIDIOC_S_CTRL <VIDIOC_G_CTRL>` and
-	:ref:`VIDIOC_G_CTRL <VIDIOC_G_CTRL>` ioctl belong to this
-	class.
-    * - ``V4L2_CTRL_CLASS_MPEG``
-      - 0x990000
-      - The class containing MPEG compression controls. These controls are
-	described in :ref:`mpeg-controls`.
-    * - ``V4L2_CTRL_CLASS_CAMERA``
-      - 0x9a0000
-      - The class containing camera controls. These controls are described
-	in :ref:`camera-controls`.
-    * - ``V4L2_CTRL_CLASS_FM_TX``
-      - 0x9b0000
-      - The class containing FM Transmitter (FM TX) controls. These
-	controls are described in :ref:`fm-tx-controls`.
-    * - ``V4L2_CTRL_CLASS_FLASH``
-      - 0x9c0000
-      - The class containing flash device controls. These controls are
-	described in :ref:`flash-controls`.
-    * - ``V4L2_CTRL_CLASS_JPEG``
-      - 0x9d0000
-      - The class containing JPEG compression controls. These controls are
-	described in :ref:`jpeg-controls`.
-    * - ``V4L2_CTRL_CLASS_IMAGE_SOURCE``
-      - 0x9e0000
-      - The class containing image source controls. These controls are
-	described in :ref:`image-source-controls`.
-    * - ``V4L2_CTRL_CLASS_IMAGE_PROC``
-      - 0x9f0000
-      - The class containing image processing controls. These controls are
-	described in :ref:`image-process-controls`.
-    * - ``V4L2_CTRL_CLASS_FM_RX``
-      - 0xa10000
-      - The class containing FM Receiver (FM RX) controls. These controls
-	are described in :ref:`fm-rx-controls`.
-    * - ``V4L2_CTRL_CLASS_RF_TUNER``
-      - 0xa20000
-      - The class containing RF tuner controls. These controls are
-	described in :ref:`rf-tuner-controls`.
-
-
-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
-    The struct :c:type:`v4l2_ext_control` ``id`` is
-    invalid, or the struct :c:type:`v4l2_ext_controls`
-    ``which`` is invalid, or the struct
-    :c:type:`v4l2_ext_control` ``value`` was
-    inappropriate (e.g. the given menu index is not supported by the
-    driver), or the ``which`` field was set to ``V4L2_CTRL_WHICH_REQUEST_VAL``
-    but the given ``request_fd`` was invalid or ``V4L2_CTRL_WHICH_REQUEST_VAL``
-    is not supported by the kernel.
-    This error code is also returned by the
-    :ref:`VIDIOC_S_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` and :ref:`VIDIOC_TRY_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` ioctls if two or
-    more control values are in conflict.
-
-ERANGE
-    The struct :c:type:`v4l2_ext_control` ``value``
-    is out of bounds.
-
-EBUSY
-    The control is temporarily not changeable, possibly because another
-    applications took over control of the device function this control
-    belongs to, or (if the ``which`` field was set to
-    ``V4L2_CTRL_WHICH_REQUEST_VAL``) the request was queued but not yet
-    completed.
-
-ENOSPC
-    The space reserved for the control's payload is insufficient. The
-    field ``size`` is set to a value that is enough to store the payload
-    and this error code is returned.
-
-EACCES
-    Attempt to try or set a read-only control, or to get a write-only
-    control, or to get a control from a request that has not yet been
-    completed.
-
-    Or the ``which`` field was set to ``V4L2_CTRL_WHICH_REQUEST_VAL`` but the
-    device does not support requests.
diff --git a/Documentation/media/uapi/v4l/vidioc-g-fbuf.rst b/Documentation/media/uapi/v4l/vidioc-g-fbuf.rst
deleted file mode 100644
index 2d197e6bba8f..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-g-fbuf.rst
+++ /dev/null
@@ -1,362 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_G_FBUF:
-
-**********************************
-ioctl VIDIOC_G_FBUF, VIDIOC_S_FBUF
-**********************************
-
-Name
-====
-
-VIDIOC_G_FBUF - VIDIOC_S_FBUF - Get or set frame buffer overlay parameters
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_G_FBUF, struct v4l2_framebuffer *argp )
-    :name: VIDIOC_G_FBUF
-
-.. c:function:: int ioctl( int fd, VIDIOC_S_FBUF, const struct v4l2_framebuffer *argp )
-    :name: VIDIOC_S_FBUF
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_framebuffer`.
-
-
-Description
-===========
-
-Applications can use the :ref:`VIDIOC_G_FBUF <VIDIOC_G_FBUF>` and :ref:`VIDIOC_S_FBUF <VIDIOC_G_FBUF>` ioctl
-to get and set the framebuffer parameters for a
-:ref:`Video Overlay <overlay>` or :ref:`Video Output Overlay <osd>`
-(OSD). The type of overlay is implied by the device type (capture or
-output device) and can be determined with the
-:ref:`VIDIOC_QUERYCAP` ioctl. One ``/dev/videoN``
-device must not support both kinds of overlay.
-
-The V4L2 API distinguishes destructive and non-destructive overlays. A
-destructive overlay copies captured video images into the video memory
-of a graphics card. A non-destructive overlay blends video images into a
-VGA signal or graphics into a video signal. *Video Output Overlays* are
-always non-destructive.
-
-To get the current parameters applications call the :ref:`VIDIOC_G_FBUF <VIDIOC_G_FBUF>`
-ioctl with a pointer to a struct :c:type:`v4l2_framebuffer`
-structure. The driver fills all fields of the structure or returns an
-EINVAL error code when overlays are not supported.
-
-To set the parameters for a *Video Output Overlay*, applications must
-initialize the ``flags`` field of a struct
-:c:type:`v4l2_framebuffer`. Since the framebuffer is
-implemented on the TV card all other parameters are determined by the
-driver. When an application calls :ref:`VIDIOC_S_FBUF <VIDIOC_G_FBUF>` with a pointer to
-this structure, the driver prepares for the overlay and returns the
-framebuffer parameters as :ref:`VIDIOC_G_FBUF <VIDIOC_G_FBUF>` does, or it returns an error
-code.
-
-To set the parameters for a *non-destructive Video Overlay*,
-applications must initialize the ``flags`` field, the ``fmt``
-substructure, and call :ref:`VIDIOC_S_FBUF <VIDIOC_G_FBUF>`. Again the driver prepares for
-the overlay and returns the framebuffer parameters as :ref:`VIDIOC_G_FBUF <VIDIOC_G_FBUF>`
-does, or it returns an error code.
-
-For a *destructive Video Overlay* applications must additionally provide
-a ``base`` address. Setting up a DMA to a random memory location can
-jeopardize the system security, its stability or even damage the
-hardware, therefore only the superuser can set the parameters for a
-destructive video overlay.
-
-
-.. tabularcolumns:: |p{3.5cm}|p{3.5cm}|p{3.5cm}|p{7.0cm}|
-
-.. c:type:: v4l2_framebuffer
-
-.. cssclass:: longtable
-
-.. flat-table:: struct v4l2_framebuffer
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 1 2
-
-    * - __u32
-      - ``capability``
-      -
-      - Overlay capability flags set by the driver, see
-	:ref:`framebuffer-cap`.
-    * - __u32
-      - ``flags``
-      -
-      - Overlay control flags set by application and driver, see
-	:ref:`framebuffer-flags`
-    * - void *
-      - ``base``
-      -
-      - Physical base address of the framebuffer, that is the address of
-	the pixel in the top left corner of the framebuffer. [#f1]_
-    * -
-      -
-      -
-      - This field is irrelevant to *non-destructive Video Overlays*. For
-	*destructive Video Overlays* applications must provide a base
-	address. The driver may accept only base addresses which are a
-	multiple of two, four or eight bytes. For *Video Output Overlays*
-	the driver must return a valid base address, so applications can
-	find the corresponding Linux framebuffer device (see
-	:ref:`osd`).
-    * - struct
-      - ``fmt``
-      -
-      - Layout of the frame buffer.
-    * -
-      - __u32
-      - ``width``
-      - Width of the frame buffer in pixels.
-    * -
-      - __u32
-      - ``height``
-      - Height of the frame buffer in pixels.
-    * -
-      - __u32
-      - ``pixelformat``
-      - The pixel format of the framebuffer.
-    * -
-      -
-      -
-      - For *non-destructive Video Overlays* this field only defines a
-	format for the struct :c:type:`v4l2_window`
-	``chromakey`` field.
-    * -
-      -
-      -
-      - For *destructive Video Overlays* applications must initialize this
-	field. For *Video Output Overlays* the driver must return a valid
-	format.
-    * -
-      -
-      -
-      - Usually this is an RGB format (for example
-	:ref:`V4L2_PIX_FMT_RGB565 <V4L2-PIX-FMT-RGB565>`) but YUV
-	formats (only packed YUV formats when chroma keying is used, not
-	including ``V4L2_PIX_FMT_YUYV`` and ``V4L2_PIX_FMT_UYVY``) and the
-	``V4L2_PIX_FMT_PAL8`` format are also permitted. The behavior of
-	the driver when an application requests a compressed format is
-	undefined. See :ref:`pixfmt` for information on pixel formats.
-    * -
-      - enum :c:type:`v4l2_field`
-      - ``field``
-      - Drivers and applications shall ignore this field. If applicable,
-	the field order is selected with the
-	:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl, using the ``field``
-	field of struct :c:type:`v4l2_window`.
-    * -
-      - __u32
-      - ``bytesperline``
-      - Distance in bytes between the leftmost pixels in two adjacent
-	lines.
-    * - :cspan:`3`
-
-	This field is irrelevant to *non-destructive Video Overlays*.
-
-	For *destructive Video Overlays* both applications and drivers can
-	set this field to request padding bytes at the end of each line.
-	Drivers however may ignore the requested value, returning
-	``width`` times bytes-per-pixel or a larger value required by the
-	hardware. That implies applications can just set this field to
-	zero to get a reasonable default.
-
-	For *Video Output Overlays* the driver must return a valid value.
-
-	Video hardware may access padding bytes, therefore they must
-	reside in accessible memory. Consider for example the case where
-	padding bytes after the last line of an image cross a system page
-	boundary. Capture devices may write padding bytes, the value is
-	undefined. Output devices ignore the contents of padding bytes.
-
-	When the image format is planar the ``bytesperline`` value applies
-	to the first plane and is divided by the same factor as the
-	``width`` field for the other planes. For example the Cb and Cr
-	planes of a YUV 4:2:0 image have half as many padding bytes
-	following each line as the Y plane. To avoid ambiguities drivers
-	must return a ``bytesperline`` value rounded up to a multiple of
-	the scale factor.
-    * -
-      - __u32
-      - ``sizeimage``
-      - This field is irrelevant to *non-destructive Video Overlays*. For
-	*destructive Video Overlays* applications must initialize this
-	field. For *Video Output Overlays* the driver must return a valid
-	format.
-
-	Together with ``base`` it defines the framebuffer memory
-	accessible by the driver.
-    * -
-      - enum :c:type:`v4l2_colorspace`
-      - ``colorspace``
-      - This information supplements the ``pixelformat`` and must be set
-	by the driver, see :ref:`colorspaces`.
-    * -
-      - __u32
-      - ``priv``
-      - Reserved. Drivers and applications must set this field to zero.
-
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. _framebuffer-cap:
-
-.. flat-table:: Frame Buffer Capability Flags
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_FBUF_CAP_EXTERNOVERLAY``
-      - 0x0001
-      - The device is capable of non-destructive overlays. When the driver
-	clears this flag, only destructive overlays are supported. There
-	are no drivers yet which support both destructive and
-	non-destructive overlays. Video Output Overlays are in practice
-	always non-destructive.
-    * - ``V4L2_FBUF_CAP_CHROMAKEY``
-      - 0x0002
-      - The device supports clipping by chroma-keying the images. That is,
-	image pixels replace pixels in the VGA or video signal only where
-	the latter assume a certain color. Chroma-keying makes no sense
-	for destructive overlays.
-    * - ``V4L2_FBUF_CAP_LIST_CLIPPING``
-      - 0x0004
-      - The device supports clipping using a list of clip rectangles.
-    * - ``V4L2_FBUF_CAP_BITMAP_CLIPPING``
-      - 0x0008
-      - The device supports clipping using a bit mask.
-    * - ``V4L2_FBUF_CAP_LOCAL_ALPHA``
-      - 0x0010
-      - The device supports clipping/blending using the alpha channel of
-	the framebuffer or VGA signal. Alpha blending makes no sense for
-	destructive overlays.
-    * - ``V4L2_FBUF_CAP_GLOBAL_ALPHA``
-      - 0x0020
-      - The device supports alpha blending using a global alpha value.
-	Alpha blending makes no sense for destructive overlays.
-    * - ``V4L2_FBUF_CAP_LOCAL_INV_ALPHA``
-      - 0x0040
-      - The device supports clipping/blending using the inverted alpha
-	channel of the framebuffer or VGA signal. Alpha blending makes no
-	sense for destructive overlays.
-    * - ``V4L2_FBUF_CAP_SRC_CHROMAKEY``
-      - 0x0080
-      - The device supports Source Chroma-keying. Video pixels with the
-	chroma-key colors are replaced by framebuffer pixels, which is
-	exactly opposite of ``V4L2_FBUF_CAP_CHROMAKEY``
-
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. _framebuffer-flags:
-
-.. cssclass:: longtable
-
-.. flat-table:: Frame Buffer Flags
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_FBUF_FLAG_PRIMARY``
-      - 0x0001
-      - The framebuffer is the primary graphics surface. In other words,
-	the overlay is destructive. This flag is typically set by any
-	driver that doesn't have the ``V4L2_FBUF_CAP_EXTERNOVERLAY``
-	capability and it is cleared otherwise.
-    * - ``V4L2_FBUF_FLAG_OVERLAY``
-      - 0x0002
-      - If this flag is set for a video capture device, then the driver
-	will set the initial overlay size to cover the full framebuffer
-	size, otherwise the existing overlay size (as set by
-	:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`) will be used. Only one
-	video capture driver (bttv) supports this flag. The use of this
-	flag for capture devices is deprecated. There is no way to detect
-	which drivers support this flag, so the only reliable method of
-	setting the overlay size is through
-	:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`. If this flag is set for a
-	video output device, then the video output overlay window is
-	relative to the top-left corner of the framebuffer and restricted
-	to the size of the framebuffer. If it is cleared, then the video
-	output overlay window is relative to the video output display.
-    * - ``V4L2_FBUF_FLAG_CHROMAKEY``
-      - 0x0004
-      - Use chroma-keying. The chroma-key color is determined by the
-	``chromakey`` field of struct :c:type:`v4l2_window`
-	and negotiated with the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`
-	ioctl, see :ref:`overlay` and :ref:`osd`.
-    * - :cspan:`2` There are no flags to enable clipping using a list of
-	clip rectangles or a bitmap. These methods are negotiated with the
-	:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl, see :ref:`overlay`
-	and :ref:`osd`.
-    * - ``V4L2_FBUF_FLAG_LOCAL_ALPHA``
-      - 0x0008
-      - Use the alpha channel of the framebuffer to clip or blend
-	framebuffer pixels with video images. The blend function is:
-	output = framebuffer pixel * alpha + video pixel * (1 - alpha).
-	The actual alpha depth depends on the framebuffer pixel format.
-    * - ``V4L2_FBUF_FLAG_GLOBAL_ALPHA``
-      - 0x0010
-      - Use a global alpha value to blend the framebuffer with video
-	images. The blend function is: output = (framebuffer pixel * alpha
-	+ video pixel * (255 - alpha)) / 255. The alpha value is
-	determined by the ``global_alpha`` field of struct
-	:c:type:`v4l2_window` and negotiated with the
-	:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl, see :ref:`overlay`
-	and :ref:`osd`.
-    * - ``V4L2_FBUF_FLAG_LOCAL_INV_ALPHA``
-      - 0x0020
-      - Like ``V4L2_FBUF_FLAG_LOCAL_ALPHA``, use the alpha channel of the
-	framebuffer to clip or blend framebuffer pixels with video images,
-	but with an inverted alpha value. The blend function is: output =
-	framebuffer pixel * (1 - alpha) + video pixel * alpha. The actual
-	alpha depth depends on the framebuffer pixel format.
-    * - ``V4L2_FBUF_FLAG_SRC_CHROMAKEY``
-      - 0x0040
-      - Use source chroma-keying. The source chroma-key color is
-	determined by the ``chromakey`` field of struct
-	:c:type:`v4l2_window` and negotiated with the
-	:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl, see :ref:`overlay`
-	and :ref:`osd`. Both chroma-keying are mutual exclusive to each
-	other, so same ``chromakey`` field of struct
-	:c:type:`v4l2_window` is being used.
-
-
-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.
-
-EPERM
-    :ref:`VIDIOC_S_FBUF <VIDIOC_G_FBUF>` can only be called by a privileged user to
-    negotiate the parameters for a destructive overlay.
-
-EINVAL
-    The :ref:`VIDIOC_S_FBUF <VIDIOC_G_FBUF>` parameters are unsuitable.
-
-.. [#f1]
-   A physical base address may not suit all platforms. GK notes in
-   theory we should pass something like PCI device + memory region +
-   offset instead. If you encounter problems please discuss on the
-   linux-media mailing list:
-   `https://linuxtv.org/lists.php <https://linuxtv.org/lists.php>`__.
diff --git a/Documentation/media/uapi/v4l/vidioc-g-fmt.rst b/Documentation/media/uapi/v4l/vidioc-g-fmt.rst
deleted file mode 100644
index 1e69bfc46e8d..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-g-fmt.rst
+++ /dev/null
@@ -1,161 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_G_FMT:
-
-************************************************
-ioctl VIDIOC_G_FMT, VIDIOC_S_FMT, VIDIOC_TRY_FMT
-************************************************
-
-Name
-====
-
-VIDIOC_G_FMT - VIDIOC_S_FMT - VIDIOC_TRY_FMT - Get or set the data format, try a format
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_G_FMT, struct v4l2_format *argp )
-    :name: VIDIOC_G_FMT
-
-.. c:function:: int ioctl( int fd, VIDIOC_S_FMT, struct v4l2_format *argp )
-    :name: VIDIOC_S_FMT
-
-.. c:function:: int ioctl( int fd, VIDIOC_TRY_FMT, struct v4l2_format *argp )
-    :name: VIDIOC_TRY_FMT
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_format`.
-
-
-Description
-===========
-
-These ioctls are used to negotiate the format of data (typically image
-format) exchanged between driver and application.
-
-To query the current parameters applications set the ``type`` field of a
-struct :c:type:`v4l2_format` to the respective buffer (stream)
-type. For example video capture devices use
-``V4L2_BUF_TYPE_VIDEO_CAPTURE`` or
-``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE``. When the application calls the
-:ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` ioctl with a pointer to this structure the driver fills
-the respective member of the ``fmt`` union. In case of video capture
-devices that is either the struct
-:c:type:`v4l2_pix_format` ``pix`` or the struct
-:c:type:`v4l2_pix_format_mplane` ``pix_mp``
-member. When the requested buffer type is not supported drivers return
-an ``EINVAL`` error code.
-
-To change the current format parameters applications initialize the
-``type`` field and all fields of the respective ``fmt`` union member.
-For details see the documentation of the various devices types in
-:ref:`devices`. Good practice is to query the current parameters
-first, and to modify only those parameters not suitable for the
-application. When the application calls the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl with
-a pointer to a struct :c:type:`v4l2_format` structure the driver
-checks and adjusts the parameters against hardware abilities. Drivers
-should not return an error code unless the ``type`` field is invalid,
-this is a mechanism to fathom device capabilities and to approach
-parameters acceptable for both the application and driver. On success
-the driver may program the hardware, allocate resources and generally
-prepare for data exchange. Finally the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl returns
-the current format parameters as :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` does. Very simple,
-inflexible devices may even ignore all input and always return the
-default parameters. However all V4L2 devices exchanging data with the
-application must implement the :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` and :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`
-ioctl. When the requested buffer type is not supported drivers return an
-EINVAL error code on a :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` attempt. When I/O is already in
-progress or the resource is not available for other reasons drivers
-return the ``EBUSY`` error code.
-
-The :ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` ioctl is equivalent to :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` with one
-exception: it does not change driver state. It can also be called at any
-time, never returning ``EBUSY``. This function is provided to negotiate
-parameters, to learn about hardware limitations, without disabling I/O
-or possibly time consuming hardware preparations. Although strongly
-recommended drivers are not required to implement this ioctl.
-
-The format as returned by :ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` must be identical to what
-:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` returns for the same input or output.
-
-
-.. c:type:: v4l2_format
-
-.. tabularcolumns::  |p{1.2cm}|p{4.6cm}|p{3.0cm}|p{8.6cm}|
-
-.. flat-table:: struct v4l2_format
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - __u32
-      - ``type``
-      - Type of the data stream, see :c:type:`v4l2_buf_type`.
-    * - union {
-      - ``fmt``
-    * - struct :c:type:`v4l2_pix_format`
-      - ``pix``
-      - Definition of an image format, see :ref:`pixfmt`, used by video
-	capture and output devices.
-    * - struct :c:type:`v4l2_pix_format_mplane`
-      - ``pix_mp``
-      - Definition of an image format, see :ref:`pixfmt`, used by video
-	capture and output devices that support the
-	:ref:`multi-planar version of the API <planar-apis>`.
-    * - struct :c:type:`v4l2_window`
-      - ``win``
-      - Definition of an overlaid image, see :ref:`overlay`, used by
-	video overlay devices.
-    * - struct :c:type:`v4l2_vbi_format`
-      - ``vbi``
-      - Raw VBI capture or output parameters. This is discussed in more
-	detail in :ref:`raw-vbi`. Used by raw VBI capture and output
-	devices.
-    * - struct :c:type:`v4l2_sliced_vbi_format`
-      - ``sliced``
-      - Sliced VBI capture or output parameters. See :ref:`sliced` for
-	details. Used by sliced VBI capture and output devices.
-    * - struct :c:type:`v4l2_sdr_format`
-      - ``sdr``
-      - Definition of a data format, see :ref:`pixfmt`, used by SDR
-	capture and output devices.
-    * - struct :c:type:`v4l2_meta_format`
-      - ``meta``
-      - Definition of a metadata format, see :ref:`meta-formats`, used by
-	metadata capture devices.
-    * - __u8
-      - ``raw_data``\ [200]
-      - Place holder for future extensions.
-    * - }
-      -
-
-
-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
-    The struct :c:type:`v4l2_format` ``type`` field is
-    invalid or the requested buffer type not supported.
-
-EBUSY
-    The device is busy and cannot change the format. This could be
-    because or the device is streaming or buffers are allocated or
-    queued to the driver. Relevant for :ref:`VIDIOC_S_FMT
-    <VIDIOC_G_FMT>` only.
diff --git a/Documentation/media/uapi/v4l/vidioc-g-frequency.rst b/Documentation/media/uapi/v4l/vidioc-g-frequency.rst
deleted file mode 100644
index cc30bae3dd6e..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-g-frequency.rst
+++ /dev/null
@@ -1,112 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_G_FREQUENCY:
-
-********************************************
-ioctl VIDIOC_G_FREQUENCY, VIDIOC_S_FREQUENCY
-********************************************
-
-Name
-====
-
-VIDIOC_G_FREQUENCY - VIDIOC_S_FREQUENCY - Get or set tuner or modulator radio frequency
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_G_FREQUENCY, struct v4l2_frequency *argp )
-    :name: VIDIOC_G_FREQUENCY
-
-.. c:function:: int ioctl( int fd, VIDIOC_S_FREQUENCY, const struct v4l2_frequency *argp )
-    :name: VIDIOC_S_FREQUENCY
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_frequency`.
-
-
-Description
-===========
-
-To get the current tuner or modulator radio frequency applications set
-the ``tuner`` field of a struct
-:c:type:`v4l2_frequency` to the respective tuner or
-modulator number (only input devices have tuners, only output devices
-have modulators), zero out the ``reserved`` array and call the
-:ref:`VIDIOC_G_FREQUENCY <VIDIOC_G_FREQUENCY>` ioctl with a pointer to this structure. The
-driver stores the current frequency in the ``frequency`` field.
-
-To change the current tuner or modulator radio frequency applications
-initialize the ``tuner``, ``type`` and ``frequency`` fields, and the
-``reserved`` array of a struct :c:type:`v4l2_frequency`
-and call the :ref:`VIDIOC_S_FREQUENCY <VIDIOC_G_FREQUENCY>` ioctl with a pointer to this
-structure. When the requested frequency is not possible the driver
-assumes the closest possible value. However :ref:`VIDIOC_S_FREQUENCY <VIDIOC_G_FREQUENCY>` is a
-write-only ioctl, it does not return the actual new frequency.
-
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. c:type:: v4l2_frequency
-
-.. flat-table:: struct v4l2_frequency
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``tuner``
-      - The tuner or modulator index number. This is the same value as in
-	the struct :c:type:`v4l2_input` ``tuner`` field and
-	the struct :c:type:`v4l2_tuner` ``index`` field, or
-	the struct :c:type:`v4l2_output` ``modulator`` field
-	and the struct :c:type:`v4l2_modulator` ``index``
-	field.
-    * - __u32
-      - ``type``
-      - The tuner type. This is the same value as in the struct
-	:c:type:`v4l2_tuner` ``type`` field. The type must be
-	set to ``V4L2_TUNER_RADIO`` for ``/dev/radioX`` device nodes, and
-	to ``V4L2_TUNER_ANALOG_TV`` for all others. Set this field to
-	``V4L2_TUNER_RADIO`` for modulators (currently only radio
-	modulators are supported). See :c:type:`v4l2_tuner_type`
-    * - __u32
-      - ``frequency``
-      - Tuning frequency in units of 62.5 kHz, or if the struct
-	:c:type:`v4l2_tuner` or struct
-	:c:type:`v4l2_modulator` ``capability`` flag
-	``V4L2_TUNER_CAP_LOW`` is set, in units of 62.5 Hz. A 1 Hz unit is
-	used when the ``capability`` flag ``V4L2_TUNER_CAP_1HZ`` is set.
-    * - __u32
-      - ``reserved``\ [8]
-      - Reserved for future extensions. Drivers and applications must set
-	the array to zero.
-
-
-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
-    The ``tuner`` index is out of bounds or the value in the ``type``
-    field is wrong.
-
-EBUSY
-    A hardware seek is in progress.
diff --git a/Documentation/media/uapi/v4l/vidioc-g-input.rst b/Documentation/media/uapi/v4l/vidioc-g-input.rst
deleted file mode 100644
index 76b7d487466e..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-g-input.rst
+++ /dev/null
@@ -1,71 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_G_INPUT:
-
-************************************
-ioctl VIDIOC_G_INPUT, VIDIOC_S_INPUT
-************************************
-
-Name
-====
-
-VIDIOC_G_INPUT - VIDIOC_S_INPUT - Query or select the current video input
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_G_INPUT, int *argp )
-    :name: VIDIOC_G_INPUT
-
-.. c:function:: int ioctl( int fd, VIDIOC_S_INPUT, int *argp )
-    :name: VIDIOC_S_INPUT
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer an integer with input index.
-
-
-Description
-===========
-
-To query the current video input applications call the
-:ref:`VIDIOC_G_INPUT <VIDIOC_G_INPUT>` ioctl with a pointer to an integer where the driver
-stores the number of the input, as in the struct
-:c:type:`v4l2_input` ``index`` field. This ioctl will fail
-only when there are no video inputs, returning ``EINVAL``.
-
-To select a video input applications store the number of the desired
-input in an integer and call the :ref:`VIDIOC_S_INPUT <VIDIOC_G_INPUT>` ioctl with a pointer
-to this integer. Side effects are possible. For example inputs may
-support different video standards, so the driver may implicitly switch
-the current standard. Because of these possible side effects
-applications must select an input before querying or negotiating any
-other parameters.
-
-Information about video inputs is available using the
-:ref:`VIDIOC_ENUMINPUT` ioctl.
-
-
-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
-    The number of the video input is out of bounds.
diff --git a/Documentation/media/uapi/v4l/vidioc-g-jpegcomp.rst b/Documentation/media/uapi/v4l/vidioc-g-jpegcomp.rst
deleted file mode 100644
index 5480277ab327..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-g-jpegcomp.rst
+++ /dev/null
@@ -1,134 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_G_JPEGCOMP:
-
-******************************************
-ioctl VIDIOC_G_JPEGCOMP, VIDIOC_S_JPEGCOMP
-******************************************
-
-Name
-====
-
-VIDIOC_G_JPEGCOMP - VIDIOC_S_JPEGCOMP
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_G_JPEGCOMP, v4l2_jpegcompression *argp )
-    :name: VIDIOC_G_JPEGCOMP
-
-.. c:function:: int ioctl( int fd, VIDIOC_S_JPEGCOMP, const v4l2_jpegcompression *argp )
-    :name: VIDIOC_S_JPEGCOMP
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_jpegcompression`.
-
-
-Description
-===========
-
-These ioctls are **deprecated**. New drivers and applications should use
-:ref:`JPEG class controls <jpeg-controls>` for image quality and JPEG
-markers control.
-
-[to do]
-
-Ronald Bultje elaborates:
-
-APP is some application-specific information. The application can set it
-itself, and it'll be stored in the JPEG-encoded fields (eg; interlacing
-information for in an AVI or so). COM is the same, but it's comments,
-like 'encoded by me' or so.
-
-jpeg_markers describes whether the huffman tables, quantization tables
-and the restart interval information (all JPEG-specific stuff) should be
-stored in the JPEG-encoded fields. These define how the JPEG field is
-encoded. If you omit them, applications assume you've used standard
-encoding. You usually do want to add them.
-
-
-.. tabularcolumns:: |p{1.2cm}|p{3.0cm}|p{13.3cm}|
-
-.. c:type:: v4l2_jpegcompression
-
-.. flat-table:: struct v4l2_jpegcompression
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - int
-      - ``quality``
-      - Deprecated. If
-	:ref:`V4L2_CID_JPEG_COMPRESSION_QUALITY <jpeg-quality-control>`
-	control is exposed by a driver applications should use it instead
-	and ignore this field.
-    * - int
-      - ``APPn``
-      -
-    * - int
-      - ``APP_len``
-      -
-    * - char
-      - ``APP_data``\ [60]
-      -
-    * - int
-      - ``COM_len``
-      -
-    * - char
-      - ``COM_data``\ [60]
-      -
-    * - __u32
-      - ``jpeg_markers``
-      - See :ref:`jpeg-markers`. Deprecated. If
-	:ref:`V4L2_CID_JPEG_ACTIVE_MARKER <jpeg-active-marker-control>`
-	control is exposed by a driver applications should use it instead
-	and ignore this field.
-
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. _jpeg-markers:
-
-.. flat-table:: JPEG Markers Flags
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_JPEG_MARKER_DHT``
-      - (1<<3)
-      - Define Huffman Tables
-    * - ``V4L2_JPEG_MARKER_DQT``
-      - (1<<4)
-      - Define Quantization Tables
-    * - ``V4L2_JPEG_MARKER_DRI``
-      - (1<<5)
-      - Define Restart Interval
-    * - ``V4L2_JPEG_MARKER_COM``
-      - (1<<6)
-      - Comment segment
-    * - ``V4L2_JPEG_MARKER_APP``
-      - (1<<7)
-      - App segment, driver will always use APP0
-
-
-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/v4l/vidioc-g-modulator.rst b/Documentation/media/uapi/v4l/vidioc-g-modulator.rst
deleted file mode 100644
index 2c33a8bdcc47..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-g-modulator.rst
+++ /dev/null
@@ -1,202 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_G_MODULATOR:
-
-********************************************
-ioctl VIDIOC_G_MODULATOR, VIDIOC_S_MODULATOR
-********************************************
-
-Name
-====
-
-VIDIOC_G_MODULATOR - VIDIOC_S_MODULATOR - Get or set modulator attributes
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_G_MODULATOR, struct v4l2_modulator *argp )
-    :name: VIDIOC_G_MODULATOR
-
-.. c:function:: int ioctl( int fd, VIDIOC_S_MODULATOR, const struct v4l2_modulator *argp )
-    :name: VIDIOC_S_MODULATOR
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_modulator`.
-
-
-Description
-===========
-
-To query the attributes of a modulator applications initialize the
-``index`` field and zero out the ``reserved`` array of a struct
-:c:type:`v4l2_modulator` and call the
-:ref:`VIDIOC_G_MODULATOR <VIDIOC_G_MODULATOR>` ioctl with a pointer to this structure. Drivers
-fill the rest of the structure or return an ``EINVAL`` error code when the
-index is out of bounds. To enumerate all modulators applications shall
-begin at index zero, incrementing by one until the driver returns
-EINVAL.
-
-Modulators have two writable properties, an audio modulation set and the
-radio frequency. To change the modulated audio subprograms, applications
-initialize the ``index`` and ``txsubchans`` fields and the ``reserved``
-array and call the :ref:`VIDIOC_S_MODULATOR <VIDIOC_G_MODULATOR>` ioctl. Drivers may choose a
-different audio modulation if the request cannot be satisfied. However
-this is a write-only ioctl, it does not return the actual audio
-modulation selected.
-
-:ref:`SDR <sdr>` specific modulator types are ``V4L2_TUNER_SDR`` and
-``V4L2_TUNER_RF``. For SDR devices ``txsubchans`` field must be
-initialized to zero. The term 'modulator' means SDR transmitter in this
-context.
-
-To change the radio frequency the
-:ref:`VIDIOC_S_FREQUENCY <VIDIOC_G_FREQUENCY>` ioctl is available.
-
-
-.. tabularcolumns:: |p{2.9cm}|p{2.9cm}|p{5.8cm}|p{2.9cm}|p{3.0cm}|
-
-.. c:type:: v4l2_modulator
-
-.. flat-table:: struct v4l2_modulator
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2 1 1
-
-    * - __u32
-      - ``index``
-      - Identifies the modulator, set by the application.
-    * - __u8
-      - ``name``\ [32]
-      - Name of the modulator, a NUL-terminated ASCII string.
-
-	This information is intended for the user.
-    * - __u32
-      - ``capability``
-      - Modulator capability flags. No flags are defined for this field,
-	the tuner flags in struct :c:type:`v4l2_tuner` are
-	used accordingly. The audio flags indicate the ability to encode
-	audio subprograms. They will *not* change for example with the
-	current video standard.
-    * - __u32
-      - ``rangelow``
-      - The lowest tunable frequency in units of 62.5 KHz, or if the
-	``capability`` flag ``V4L2_TUNER_CAP_LOW`` is set, in units of
-	62.5 Hz, or if the ``capability`` flag ``V4L2_TUNER_CAP_1HZ`` is
-	set, in units of 1 Hz.
-    * - __u32
-      - ``rangehigh``
-      - The highest tunable frequency in units of 62.5 KHz, or if the
-	``capability`` flag ``V4L2_TUNER_CAP_LOW`` is set, in units of
-	62.5 Hz, or if the ``capability`` flag ``V4L2_TUNER_CAP_1HZ`` is
-	set, in units of 1 Hz.
-    * - __u32
-      - ``txsubchans``
-      - With this field applications can determine how audio sub-carriers
-	shall be modulated. It contains a set of flags as defined in
-	:ref:`modulator-txsubchans`.
-
-	.. note::
-
-	   The tuner ``rxsubchans`` flags  are reused, but the
-	   semantics are different. Video output devices
-	   are assumed to have an analog or PCM audio input with 1-3
-	   channels. The ``txsubchans`` flags select one or more channels
-	   for modulation, together with some audio subprogram indicator,
-	   for example, a stereo pilot tone.
-    * - __u32
-      - ``type``
-      - :cspan:`2` Type of the modulator, see :c:type:`v4l2_tuner_type`.
-    * - __u32
-      - ``reserved``\ [3]
-      - Reserved for future extensions.
-
-	Drivers and applications must set the array to zero.
-
-
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. _modulator-txsubchans:
-
-.. flat-table:: Modulator Audio Transmission Flags
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_TUNER_SUB_MONO``
-      - 0x0001
-      - Modulate channel 1 as mono audio, when the input has more
-	channels, a down-mix of channel 1 and 2. This flag does not
-	combine with ``V4L2_TUNER_SUB_STEREO`` or
-	``V4L2_TUNER_SUB_LANG1``.
-    * - ``V4L2_TUNER_SUB_STEREO``
-      - 0x0002
-      - Modulate channel 1 and 2 as left and right channel of a stereo
-	audio signal. When the input has only one channel or two channels
-	and ``V4L2_TUNER_SUB_SAP`` is also set, channel 1 is encoded as
-	left and right channel. This flag does not combine with
-	``V4L2_TUNER_SUB_MONO`` or ``V4L2_TUNER_SUB_LANG1``. When the
-	driver does not support stereo audio it shall fall back to mono.
-    * - ``V4L2_TUNER_SUB_LANG1``
-      - 0x0008
-      - Modulate channel 1 and 2 as primary and secondary language of a
-	bilingual audio signal. When the input has only one channel it is
-	used for both languages. It is not possible to encode the primary
-	or secondary language only. This flag does not combine with
-	``V4L2_TUNER_SUB_MONO``, ``V4L2_TUNER_SUB_STEREO`` or
-	``V4L2_TUNER_SUB_SAP``. If the hardware does not support the
-	respective audio matrix, or the current video standard does not
-	permit bilingual audio the :ref:`VIDIOC_S_MODULATOR <VIDIOC_G_MODULATOR>` ioctl shall
-	return an ``EINVAL`` error code and the driver shall fall back to mono
-	or stereo mode.
-    * - ``V4L2_TUNER_SUB_LANG2``
-      - 0x0004
-      - Same effect as ``V4L2_TUNER_SUB_SAP``.
-    * - ``V4L2_TUNER_SUB_SAP``
-      - 0x0004
-      - When combined with ``V4L2_TUNER_SUB_MONO`` the first channel is
-	encoded as mono audio, the last channel as Second Audio Program.
-	When the input has only one channel it is used for both audio
-	tracks. When the input has three channels the mono track is a
-	down-mix of channel 1 and 2. When combined with
-	``V4L2_TUNER_SUB_STEREO`` channel 1 and 2 are encoded as left and
-	right stereo audio, channel 3 as Second Audio Program. When the
-	input has only two channels, the first is encoded as left and
-	right channel and the second as SAP. When the input has only one
-	channel it is used for all audio tracks. It is not possible to
-	encode a Second Audio Program only. This flag must combine with
-	``V4L2_TUNER_SUB_MONO`` or ``V4L2_TUNER_SUB_STEREO``. If the
-	hardware does not support the respective audio matrix, or the
-	current video standard does not permit SAP the
-	:ref:`VIDIOC_S_MODULATOR <VIDIOC_G_MODULATOR>` ioctl shall return an ``EINVAL`` error code and
-	driver shall fall back to mono or stereo mode.
-    * - ``V4L2_TUNER_SUB_RDS``
-      - 0x0010
-      - Enable the RDS encoder for a radio FM transmitter.
-
-
-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
-    The struct :c:type:`v4l2_modulator` ``index`` is
-    out of bounds.
diff --git a/Documentation/media/uapi/v4l/vidioc-g-output.rst b/Documentation/media/uapi/v4l/vidioc-g-output.rst
deleted file mode 100644
index 69542d78977b..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-g-output.rst
+++ /dev/null
@@ -1,73 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_G_OUTPUT:
-
-**************************************
-ioctl VIDIOC_G_OUTPUT, VIDIOC_S_OUTPUT
-**************************************
-
-Name
-====
-
-VIDIOC_G_OUTPUT - VIDIOC_S_OUTPUT - Query or select the current video output
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_G_OUTPUT, int *argp )
-    :name: VIDIOC_G_OUTPUT
-
-.. c:function:: int ioctl( int fd, VIDIOC_S_OUTPUT, int *argp )
-    :name: VIDIOC_S_OUTPUT
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to an integer with output index.
-
-
-Description
-===========
-
-To query the current video output applications call the
-:ref:`VIDIOC_G_OUTPUT <VIDIOC_G_OUTPUT>` ioctl with a pointer to an integer where the driver
-stores the number of the output, as in the struct
-:c:type:`v4l2_output` ``index`` field. This ioctl will
-fail only when there are no video outputs, returning the ``EINVAL`` error
-code.
-
-To select a video output applications store the number of the desired
-output in an integer and call the :ref:`VIDIOC_S_OUTPUT <VIDIOC_G_OUTPUT>` ioctl with a
-pointer to this integer. Side effects are possible. For example outputs
-may support different video standards, so the driver may implicitly
-switch the current standard. standard. Because of these possible side
-effects applications must select an output before querying or
-negotiating any other parameters.
-
-Information about video outputs is available using the
-:ref:`VIDIOC_ENUMOUTPUT` ioctl.
-
-
-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
-    The number of the video output is out of bounds, or there are no
-    video outputs at all.
diff --git a/Documentation/media/uapi/v4l/vidioc-g-parm.rst b/Documentation/media/uapi/v4l/vidioc-g-parm.rst
deleted file mode 100644
index 044a459e073f..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-g-parm.rst
+++ /dev/null
@@ -1,270 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_G_PARM:
-
-**********************************
-ioctl VIDIOC_G_PARM, VIDIOC_S_PARM
-**********************************
-
-Name
-====
-
-VIDIOC_G_PARM - VIDIOC_S_PARM - Get or set streaming parameters
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_G_PARM, v4l2_streamparm *argp )
-    :name: VIDIOC_G_PARM
-
-.. c:function:: int ioctl( int fd, VIDIOC_S_PARM, v4l2_streamparm *argp )
-    :name: VIDIOC_S_PARM
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_streamparm`.
-
-
-Description
-===========
-
-The current video standard determines a nominal number of frames per
-second. If less than this number of frames is to be captured or output,
-applications can request frame skipping or duplicating on the driver
-side. This is especially useful when using the :ref:`read() <func-read>` or
-:ref:`write() <func-write>`, which are not augmented by timestamps or sequence
-counters, and to avoid unnecessary data copying.
-
-Changing the frame interval shall never change the format. Changing the
-format, on the other hand, may change the frame interval.
-
-Further these ioctls can be used to determine the number of buffers used
-internally by a driver in read/write mode. For implications see the
-section discussing the :ref:`read() <func-read>` function.
-
-To get and set the streaming parameters applications call the
-:ref:`VIDIOC_G_PARM <VIDIOC_G_PARM>` and :ref:`VIDIOC_S_PARM <VIDIOC_G_PARM>` ioctl, respectively. They take a
-pointer to a struct :c:type:`v4l2_streamparm` which contains a
-union holding separate parameters for input and output devices.
-
-
-.. tabularcolumns:: |p{3.5cm}|p{3.5cm}|p{3.5cm}|p{7.0cm}|
-
-.. c:type:: v4l2_streamparm
-
-.. flat-table:: struct v4l2_streamparm
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``type``
-      - The buffer (stream) type, same as struct
-	:c:type:`v4l2_format` ``type``, set by the
-	application. See :c:type:`v4l2_buf_type`.
-    * - union {
-      - ``parm``
-    * - struct :c:type:`v4l2_captureparm`
-      - ``capture``
-      - Parameters for capture devices, used when ``type`` is
-	``V4L2_BUF_TYPE_VIDEO_CAPTURE`` or
-	``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE``.
-    * - struct :c:type:`v4l2_outputparm`
-      - ``output``
-      - Parameters for output devices, used when ``type`` is
-	``V4L2_BUF_TYPE_VIDEO_OUTPUT`` or ``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE``.
-    * - __u8
-      - ``raw_data``\ [200]
-      - A place holder for future extensions.
-    * - }
-      -
-
-
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. c:type:: v4l2_captureparm
-
-.. flat-table:: struct v4l2_captureparm
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``capability``
-      - See :ref:`parm-caps`.
-    * - __u32
-      - ``capturemode``
-      - Set by drivers and applications, see :ref:`parm-flags`.
-    * - struct :c:type:`v4l2_fract`
-      - ``timeperframe``
-      - This is the desired period between successive frames captured by
-	the driver, in seconds. The field is intended to skip frames on
-	the driver side, saving I/O bandwidth.
-
-	Applications store here the desired frame period, drivers return
-	the actual frame period, which must be greater or equal to the
-	nominal frame period determined by the current video standard
-	(struct :c:type:`v4l2_standard` ``frameperiod``
-	field). Changing the video standard (also implicitly by switching
-	the video input) may reset this parameter to the nominal frame
-	period. To reset manually applications can just set this field to
-	zero.
-
-	Drivers support this function only when they set the
-	``V4L2_CAP_TIMEPERFRAME`` flag in the ``capability`` field.
-    * - __u32
-      - ``extendedmode``
-      - Custom (driver specific) streaming parameters. When unused,
-	applications and drivers must set this field to zero. Applications
-	using this field should check the driver name and version, see
-	:ref:`querycap`.
-    * - __u32
-      - ``readbuffers``
-      - Applications set this field to the desired number of buffers used
-	internally by the driver in :ref:`read() <func-read>` mode.
-	Drivers return the actual number of buffers. When an application
-	requests zero buffers, drivers should just return the current
-	setting rather than the minimum or an error code. For details see
-	:ref:`rw`.
-    * - __u32
-      - ``reserved``\ [4]
-      - Reserved for future extensions. Drivers and applications must set
-	the array to zero.
-
-
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. c:type:: v4l2_outputparm
-
-.. flat-table:: struct v4l2_outputparm
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``capability``
-      - See :ref:`parm-caps`.
-    * - __u32
-      - ``outputmode``
-      - Set by drivers and applications, see :ref:`parm-flags`.
-    * - struct :c:type:`v4l2_fract`
-      - ``timeperframe``
-      - This is the desired period between successive frames output by the
-	driver, in seconds.
-    * - :cspan:`2`
-
-	The field is intended to repeat frames on the driver side in
-	:ref:`write() <func-write>` mode (in streaming mode timestamps
-	can be used to throttle the output), saving I/O bandwidth.
-
-	Applications store here the desired frame period, drivers return
-	the actual frame period, which must be greater or equal to the
-	nominal frame period determined by the current video standard
-	(struct :c:type:`v4l2_standard` ``frameperiod``
-	field). Changing the video standard (also implicitly by switching
-	the video output) may reset this parameter to the nominal frame
-	period. To reset manually applications can just set this field to
-	zero.
-
-	Drivers support this function only when they set the
-	``V4L2_CAP_TIMEPERFRAME`` flag in the ``capability`` field.
-    * - __u32
-      - ``extendedmode``
-      - Custom (driver specific) streaming parameters. When unused,
-	applications and drivers must set this field to zero. Applications
-	using this field should check the driver name and version, see
-	:ref:`querycap`.
-    * - __u32
-      - ``writebuffers``
-      - Applications set this field to the desired number of buffers used
-	internally by the driver in :ref:`write() <func-write>` mode. Drivers
-	return the actual number of buffers. When an application requests
-	zero buffers, drivers should just return the current setting
-	rather than the minimum or an error code. For details see
-	:ref:`rw`.
-    * - __u32
-      - ``reserved``\ [4]
-      - Reserved for future extensions. Drivers and applications must set
-	the array to zero.
-
-
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. _parm-caps:
-
-.. flat-table:: Streaming Parameters Capabilities
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_CAP_TIMEPERFRAME``
-      - 0x1000
-      - The frame skipping/repeating controlled by the ``timeperframe``
-	field is supported.
-
-
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. _parm-flags:
-
-.. flat-table:: Capture Parameters Flags
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_MODE_HIGHQUALITY``
-      - 0x0001
-      - High quality imaging mode. High quality mode is intended for still
-	imaging applications. The idea is to get the best possible image
-	quality that the hardware can deliver. It is not defined how the
-	driver writer may achieve that; it will depend on the hardware and
-	the ingenuity of the driver writer. High quality mode is a
-	different mode from the regular motion video capture modes. In
-	high quality mode:
-
-	-  The driver may be able to capture higher resolutions than for
-	   motion capture.
-
-	-  The driver may support fewer pixel formats than motion capture
-	   (eg; true color).
-
-	-  The driver may capture and arithmetically combine multiple
-	   successive fields or frames to remove color edge artifacts and
-	   reduce the noise in the video data.
-
-	-  The driver may capture images in slices like a scanner in order
-	   to handle larger format images than would otherwise be
-	   possible.
-
-	-  An image capture operation may be significantly slower than
-	   motion capture.
-
-	-  Moving objects in the image might have excessive motion blur.
-
-	-  Capture might only work through the :ref:`read() <func-read>` call.
-
-
-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/v4l/vidioc-g-priority.rst b/Documentation/media/uapi/v4l/vidioc-g-priority.rst
deleted file mode 100644
index 244b4dbe9df3..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-g-priority.rst
+++ /dev/null
@@ -1,100 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_G_PRIORITY:
-
-******************************************
-ioctl VIDIOC_G_PRIORITY, VIDIOC_S_PRIORITY
-******************************************
-
-Name
-====
-
-VIDIOC_G_PRIORITY - VIDIOC_S_PRIORITY - Query or request the access priority associated with a file descriptor
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_G_PRIORITY, enum v4l2_priority *argp )
-    :name: VIDIOC_G_PRIORITY
-
-.. c:function:: int ioctl( int fd, VIDIOC_S_PRIORITY, const enum v4l2_priority *argp )
-    :name: VIDIOC_S_PRIORITY
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to an enum :c:type:`v4l2_priority` type.
-
-
-Description
-===========
-
-To query the current access priority applications call the
-:ref:`VIDIOC_G_PRIORITY <VIDIOC_G_PRIORITY>` ioctl with a pointer to an enum v4l2_priority
-variable where the driver stores the current priority.
-
-To request an access priority applications store the desired priority in
-an enum v4l2_priority variable and call :ref:`VIDIOC_S_PRIORITY <VIDIOC_G_PRIORITY>` ioctl
-with a pointer to this variable.
-
-
-.. c:type:: v4l2_priority
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. flat-table:: enum v4l2_priority
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_PRIORITY_UNSET``
-      - 0
-      -
-    * - ``V4L2_PRIORITY_BACKGROUND``
-      - 1
-      - Lowest priority, usually applications running in background, for
-	example monitoring VBI transmissions. A proxy application running
-	in user space will be necessary if multiple applications want to
-	read from a device at this priority.
-    * - ``V4L2_PRIORITY_INTERACTIVE``
-      - 2
-      -
-    * - ``V4L2_PRIORITY_DEFAULT``
-      - 2
-      - Medium priority, usually applications started and interactively
-	controlled by the user. For example TV viewers, Teletext browsers,
-	or just "panel" applications to change the channel or video
-	controls. This is the default priority unless an application
-	requests another.
-    * - ``V4L2_PRIORITY_RECORD``
-      - 3
-      - Highest priority. Only one file descriptor can have this priority,
-	it blocks any other fd from changing device properties. Usually
-	applications which must not be interrupted, like video recording.
-
-
-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
-    The requested priority value is invalid.
-
-EBUSY
-    Another application already requested higher priority.
diff --git a/Documentation/media/uapi/v4l/vidioc-g-selection.rst b/Documentation/media/uapi/v4l/vidioc-g-selection.rst
deleted file mode 100644
index 7d8ef7ac8e27..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-g-selection.rst
+++ /dev/null
@@ -1,200 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_G_SELECTION:
-
-********************************************
-ioctl VIDIOC_G_SELECTION, VIDIOC_S_SELECTION
-********************************************
-
-Name
-====
-
-VIDIOC_G_SELECTION - VIDIOC_S_SELECTION - Get or set one of the selection rectangles
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_G_SELECTION, struct v4l2_selection *argp )
-    :name: VIDIOC_G_SELECTION
-
-
-.. c:function:: int ioctl( int fd, VIDIOC_S_SELECTION, struct v4l2_selection *argp )
-    :name: VIDIOC_S_SELECTION
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_selection`.
-
-Description
-===========
-
-The ioctls are used to query and configure selection rectangles.
-
-To query the cropping (composing) rectangle set struct
-:c:type:`v4l2_selection` ``type`` field to the
-respective buffer type. The next step is setting the
-value of struct :c:type:`v4l2_selection` ``target``
-field to ``V4L2_SEL_TGT_CROP`` (``V4L2_SEL_TGT_COMPOSE``). Please refer
-to table :ref:`v4l2-selections-common` or :ref:`selection-api` for
-additional targets. The ``flags`` and ``reserved`` fields of struct
-:c:type:`v4l2_selection` are ignored and they must be
-filled with zeros. The driver fills the rest of the structure or returns
-EINVAL error code if incorrect buffer type or target was used. If
-cropping (composing) is not supported then the active rectangle is not
-mutable and it is always equal to the bounds rectangle. Finally, the
-struct :c:type:`v4l2_rect` ``r`` rectangle is filled with
-the current cropping (composing) coordinates. The coordinates are
-expressed in driver-dependent units. The only exception are rectangles
-for images in raw formats, whose coordinates are always expressed in
-pixels.
-
-To change the cropping (composing) rectangle set the struct
-:c:type:`v4l2_selection` ``type`` field to the
-respective buffer type. The next step is setting the
-value of struct :c:type:`v4l2_selection` ``target`` to
-``V4L2_SEL_TGT_CROP`` (``V4L2_SEL_TGT_COMPOSE``). Please refer to table
-:ref:`v4l2-selections-common` or :ref:`selection-api` for additional
-targets. The struct :c:type:`v4l2_rect` ``r`` rectangle need
-to be set to the desired active area. Field struct
-:c:type:`v4l2_selection` ``reserved`` is ignored and
-must be filled with zeros. The driver may adjust coordinates of the
-requested rectangle. An application may introduce constraints to control
-rounding behaviour. The struct :c:type:`v4l2_selection`
-``flags`` field must be set to one of the following:
-
--  ``0`` - The driver can adjust the rectangle size freely and shall
-   choose a crop/compose rectangle as close as possible to the requested
-   one.
-
--  ``V4L2_SEL_FLAG_GE`` - The driver is not allowed to shrink the
-   rectangle. The original rectangle must lay inside the adjusted one.
-
--  ``V4L2_SEL_FLAG_LE`` - The driver is not allowed to enlarge the
-   rectangle. The adjusted rectangle must lay inside the original one.
-
--  ``V4L2_SEL_FLAG_GE | V4L2_SEL_FLAG_LE`` - The driver must choose the
-   size exactly the same as in the requested rectangle.
-
-Please refer to :ref:`sel-const-adjust`.
-
-The driver may have to adjusts the requested dimensions against hardware
-limits and other parts as the pipeline, i.e. the bounds given by the
-capture/output window or TV display. The closest possible values of
-horizontal and vertical offset and sizes are chosen according to
-following priority:
-
-1. Satisfy constraints from struct
-   :c:type:`v4l2_selection` ``flags``.
-
-2. Adjust width, height, left, and top to hardware limits and
-   alignments.
-
-3. Keep center of adjusted rectangle as close as possible to the
-   original one.
-
-4. Keep width and height as close as possible to original ones.
-
-5. Keep horizontal and vertical offset as close as possible to original
-   ones.
-
-On success the struct :c:type:`v4l2_rect` ``r`` field
-contains the adjusted rectangle. When the parameters are unsuitable the
-application may modify the cropping (composing) or image parameters and
-repeat the cycle until satisfactory parameters have been negotiated. If
-constraints flags have to be violated at then ``ERANGE`` is returned. The
-error indicates that *there exist no rectangle* that satisfies the
-constraints.
-
-Selection targets and flags are documented in
-:ref:`v4l2-selections-common`.
-
-
-.. _sel-const-adjust:
-
-.. kernel-figure::  constraints.svg
-    :alt:    constraints.svg
-    :align:  center
-
-    Size adjustments with constraint flags.
-
-    Behaviour of rectangle adjustment for different constraint flags.
-
-
-
-
-.. c:type:: v4l2_selection
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. flat-table:: struct v4l2_selection
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``type``
-      - Type of the buffer (from enum
-	:c:type:`v4l2_buf_type`).
-    * - __u32
-      - ``target``
-      - Used to select between
-	:ref:`cropping and composing rectangles <v4l2-selections-common>`.
-    * - __u32
-      - ``flags``
-      - Flags controlling the selection rectangle adjustments, refer to
-	:ref:`selection flags <v4l2-selection-flags>`.
-    * - struct :c:type:`v4l2_rect`
-      - ``r``
-      - The selection rectangle.
-    * - __u32
-      - ``reserved[9]``
-      - Reserved fields for future use. Drivers and applications must zero
-	this array.
-
-.. note::
-   Unfortunately in the case of multiplanar buffer types
-   (``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE`` and ``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE``)
-   this API was messed up with regards to how the :c:type:`v4l2_selection` ``type`` field
-   should be filled in. Some drivers only accepted the ``_MPLANE`` buffer type while
-   other drivers only accepted a non-multiplanar buffer type (i.e. without the
-   ``_MPLANE`` at the end).
-
-   Starting with kernel 4.13 both variations are allowed.
-
-
-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
-    Given buffer type ``type`` or the selection target ``target`` is not
-    supported, or the ``flags`` argument is not valid.
-
-ERANGE
-    It is not possible to adjust struct :c:type:`v4l2_rect`
-    ``r`` rectangle to satisfy all constraints given in the ``flags``
-    argument.
-
-ENODATA
-    Selection is not supported for this input or output.
-
-EBUSY
-    It is not possible to apply change of the selection rectangle at the
-    moment. Usually because streaming is in progress.
diff --git a/Documentation/media/uapi/v4l/vidioc-g-sliced-vbi-cap.rst b/Documentation/media/uapi/v4l/vidioc-g-sliced-vbi-cap.rst
deleted file mode 100644
index 388b826d44b3..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-g-sliced-vbi-cap.rst
+++ /dev/null
@@ -1,202 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_G_SLICED_VBI_CAP:
-
-*****************************
-ioctl VIDIOC_G_SLICED_VBI_CAP
-*****************************
-
-Name
-====
-
-VIDIOC_G_SLICED_VBI_CAP - Query sliced VBI capabilities
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_G_SLICED_VBI_CAP, struct v4l2_sliced_vbi_cap *argp )
-    :name: VIDIOC_G_SLICED_VBI_CAP
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_sliced_vbi_cap`.
-
-
-Description
-===========
-
-To find out which data services are supported by a sliced VBI capture or
-output device, applications initialize the ``type`` field of a struct
-:c:type:`v4l2_sliced_vbi_cap`, clear the
-``reserved`` array and call the :ref:`VIDIOC_G_SLICED_VBI_CAP <VIDIOC_G_SLICED_VBI_CAP>` ioctl. The
-driver fills in the remaining fields or returns an ``EINVAL`` error code if
-the sliced VBI API is unsupported or ``type`` is invalid.
-
-.. note::
-
-   The ``type`` field was added, and the ioctl changed from read-only
-   to write-read, in Linux 2.6.19.
-
-
-.. c:type:: v4l2_sliced_vbi_cap
-
-.. tabularcolumns:: |p{1.2cm}|p{4.2cm}|p{4.1cm}|p{4.0cm}|p{4.0cm}|
-
-.. flat-table:: struct v4l2_sliced_vbi_cap
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 3 2 2 2
-
-    * - __u16
-      - ``service_set``
-      - :cspan:`2` A set of all data services supported by the driver.
-
-	Equal to the union of all elements of the ``service_lines`` array.
-    * - __u16
-      - ``service_lines``\ [2][24]
-      - :cspan:`2` Each element of this array contains a set of data
-	services the hardware can look for or insert into a particular
-	scan line. Data services are defined in :ref:`vbi-services`.
-	Array indices map to ITU-R line numbers\ [#f1]_ as follows:
-    * -
-      -
-      - Element
-      - 525 line systems
-      - 625 line systems
-    * -
-      -
-      - ``service_lines``\ [0][1]
-      - 1
-      - 1
-    * -
-      -
-      - ``service_lines``\ [0][23]
-      - 23
-      - 23
-    * -
-      -
-      - ``service_lines``\ [1][1]
-      - 264
-      - 314
-    * -
-      -
-      - ``service_lines``\ [1][23]
-      - 286
-      - 336
-    * -
-    * -
-      -
-      - :cspan:`2` The number of VBI lines the hardware can capture or
-	output per frame, or the number of services it can identify on a
-	given line may be limited. For example on PAL line 16 the hardware
-	may be able to look for a VPS or Teletext signal, but not both at
-	the same time. Applications can learn about these limits using the
-	:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl as described in
-	:ref:`sliced`.
-    * -
-    * -
-      -
-      - :cspan:`2` Drivers must set ``service_lines`` [0][0] and
-	``service_lines``\ [1][0] to zero.
-    * - __u32
-      - ``type``
-      - Type of the data stream, see :c:type:`v4l2_buf_type`. Should be
-	``V4L2_BUF_TYPE_SLICED_VBI_CAPTURE`` or
-	``V4L2_BUF_TYPE_SLICED_VBI_OUTPUT``.
-    * - __u32
-      - ``reserved``\ [3]
-      - :cspan:`2` This array is reserved for future extensions.
-
-	Applications and drivers must set it to zero.
-
-.. [#f1]
-
-   See also :ref:`vbi-525` and :ref:`vbi-625`.
-
-
-.. raw:: latex
-
-    \scriptsize
-
-.. tabularcolumns:: |p{3.5cm}|p{1.0cm}|p{2.0cm}|p{2.0cm}|p{8.0cm}|
-
-.. _vbi-services:
-
-.. flat-table:: Sliced VBI services
-    :header-rows:  1
-    :stub-columns: 0
-    :widths:       2 1 1 2 2
-
-    * - Symbol
-      - Value
-      - Reference
-      - Lines, usually
-      - Payload
-    * - ``V4L2_SLICED_TELETEXT_B`` (Teletext System B)
-      - 0x0001
-      - :ref:`ets300706`,
-
-	:ref:`itu653`
-      - PAL/SECAM line 7-22, 320-335 (second field 7-22)
-      - Last 42 of the 45 byte Teletext packet, that is without clock
-	run-in and framing code, lsb first transmitted.
-    * - ``V4L2_SLICED_VPS``
-      - 0x0400
-      - :ref:`ets300231`
-      - PAL line 16
-      - Byte number 3 to 15 according to Figure 9 of ETS 300 231, lsb
-	first transmitted.
-    * - ``V4L2_SLICED_CAPTION_525``
-      - 0x1000
-      - :ref:`cea608`
-      - NTSC line 21, 284 (second field 21)
-      - Two bytes in transmission order, including parity bit, lsb first
-	transmitted.
-    * - ``V4L2_SLICED_WSS_625``
-      - 0x4000
-      - :ref:`en300294`,
-
-	:ref:`itu1119`
-      - PAL/SECAM line 23
-      -
-
-	::
-
-	    Byte        0                 1
-		 msb         lsb  msb           lsb
-	    Bit  7 6 5 4 3 2 1 0  x x 13 12 11 10 9
-    * - ``V4L2_SLICED_VBI_525``
-      - 0x1000
-      - :cspan:`2` Set of services applicable to 525 line systems.
-    * - ``V4L2_SLICED_VBI_625``
-      - 0x4401
-      - :cspan:`2` Set of services applicable to 625 line systems.
-
-.. raw:: latex
-
-    \normalsize
-
-
-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
-    The value in the ``type`` field is wrong.
diff --git a/Documentation/media/uapi/v4l/vidioc-g-std.rst b/Documentation/media/uapi/v4l/vidioc-g-std.rst
deleted file mode 100644
index e633e42e3910..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-g-std.rst
+++ /dev/null
@@ -1,81 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_G_STD:
-
-**************************************************************************
-ioctl VIDIOC_G_STD, VIDIOC_S_STD, VIDIOC_SUBDEV_G_STD, VIDIOC_SUBDEV_S_STD
-**************************************************************************
-
-Name
-====
-
-VIDIOC_G_STD - VIDIOC_S_STD - VIDIOC_SUBDEV_G_STD - VIDIOC_SUBDEV_S_STD - Query or select the video standard of the current input
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_G_STD, v4l2_std_id *argp )
-    :name: VIDIOC_G_STD
-
-.. c:function:: int ioctl( int fd, VIDIOC_S_STD, const v4l2_std_id *argp )
-    :name: VIDIOC_S_STD
-
-.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_G_STD, v4l2_std_id *argp )
-    :name: VIDIOC_SUBDEV_G_STD
-
-.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_S_STD, const v4l2_std_id *argp )
-    :name: VIDIOC_SUBDEV_S_STD
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to :c:type:`v4l2_std_id`.
-
-
-Description
-===========
-
-To query and select the current video standard applications use the
-:ref:`VIDIOC_G_STD <VIDIOC_G_STD>` and :ref:`VIDIOC_S_STD <VIDIOC_G_STD>` ioctls which take a pointer to a
-:ref:`v4l2_std_id <v4l2-std-id>` type as argument. :ref:`VIDIOC_G_STD <VIDIOC_G_STD>`
-can return a single flag or a set of flags as in struct
-:c:type:`v4l2_standard` field ``id``. The flags must be
-unambiguous such that they appear in only one enumerated
-struct :c:type:`v4l2_standard` structure.
-
-:ref:`VIDIOC_S_STD <VIDIOC_G_STD>` accepts one or more flags, being a write-only ioctl it
-does not return the actual new standard as :ref:`VIDIOC_G_STD <VIDIOC_G_STD>` does. When
-no flags are given or the current input does not support the requested
-standard the driver returns an ``EINVAL`` error code. When the standard set
-is ambiguous drivers may return ``EINVAL`` or choose any of the requested
-standards. If the current input or output does not support standard
-video timings (e.g. if :ref:`VIDIOC_ENUMINPUT`
-does not set the ``V4L2_IN_CAP_STD`` flag), then ``ENODATA`` error code is
-returned.
-
-
-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
-    The :ref:`VIDIOC_S_STD <VIDIOC_G_STD>` parameter was unsuitable.
-
-ENODATA
-    Standard video timings are not supported for this input or output.
diff --git a/Documentation/media/uapi/v4l/vidioc-g-tuner.rst b/Documentation/media/uapi/v4l/vidioc-g-tuner.rst
deleted file mode 100644
index 82d23b8bd195..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-g-tuner.rst
+++ /dev/null
@@ -1,476 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_G_TUNER:
-
-************************************
-ioctl VIDIOC_G_TUNER, VIDIOC_S_TUNER
-************************************
-
-Name
-====
-
-VIDIOC_G_TUNER - VIDIOC_S_TUNER - Get or set tuner attributes
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_G_TUNER, struct v4l2_tuner *argp )
-    :name: VIDIOC_G_TUNER
-
-.. c:function:: int ioctl( int fd, VIDIOC_S_TUNER, const struct v4l2_tuner *argp )
-    :name: VIDIOC_S_TUNER
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_tuner`.
-
-
-Description
-===========
-
-To query the attributes of a tuner applications initialize the ``index``
-field and zero out the ``reserved`` array of a struct
-:c:type:`v4l2_tuner` and call the ``VIDIOC_G_TUNER`` ioctl
-with a pointer to this structure. Drivers fill the rest of the structure
-or return an ``EINVAL`` error code when the index is out of bounds. To
-enumerate all tuners applications shall begin at index zero,
-incrementing by one until the driver returns ``EINVAL``.
-
-Tuners have two writable properties, the audio mode and the radio
-frequency. To change the audio mode, applications initialize the
-``index``, ``audmode`` and ``reserved`` fields and call the
-``VIDIOC_S_TUNER`` ioctl. This will *not* change the current tuner,
-which is determined by the current video input. Drivers may choose a
-different audio mode if the requested mode is invalid or unsupported.
-Since this is a write-only ioctl, it does not return the actually
-selected audio mode.
-
-:ref:`SDR <sdr>` specific tuner types are ``V4L2_TUNER_SDR`` and
-``V4L2_TUNER_RF``. For SDR devices ``audmode`` field must be initialized
-to zero. The term 'tuner' means SDR receiver in this context.
-
-To change the radio frequency the
-:ref:`VIDIOC_S_FREQUENCY <VIDIOC_G_FREQUENCY>` ioctl is available.
-
-
- .. tabularcolumns:: |p{1.3cm}|p{3.0cm}|p{6.6cm}|p{6.6cm}|
-
-.. c:type:: v4l2_tuner
-
-.. cssclass:: longtable
-
-.. flat-table:: struct v4l2_tuner
-    :header-rows:  0
-    :stub-columns: 0
-
-    * - __u32
-      - ``index``
-      - :cspan:`1` Identifies the tuner, set by the application.
-    * - __u8
-      - ``name``\ [32]
-      - :cspan:`1`
-
-	Name of the tuner, a NUL-terminated ASCII string.
-
-	This information is intended for the user.
-    * - __u32
-      - ``type``
-      - :cspan:`1` Type of the tuner, see :c:type:`v4l2_tuner_type`.
-    * - __u32
-      - ``capability``
-      - :cspan:`1`
-
-	Tuner capability flags, see :ref:`tuner-capability`. Audio flags
-	indicate the ability to decode audio subprograms. They will *not*
-	change, for example with the current video standard.
-
-	When the structure refers to a radio tuner the
-	``V4L2_TUNER_CAP_LANG1``, ``V4L2_TUNER_CAP_LANG2`` and
-	``V4L2_TUNER_CAP_NORM`` flags can't be used.
-
-	If multiple frequency bands are supported, then ``capability`` is
-	the union of all ``capability`` fields of each struct
-	:c:type:`v4l2_frequency_band`.
-    * - __u32
-      - ``rangelow``
-      - :cspan:`1` The lowest tunable frequency in units of 62.5 kHz, or
-	if the ``capability`` flag ``V4L2_TUNER_CAP_LOW`` is set, in units
-	of 62.5 Hz, or if the ``capability`` flag ``V4L2_TUNER_CAP_1HZ``
-	is set, in units of 1 Hz. If multiple frequency bands are
-	supported, then ``rangelow`` is the lowest frequency of all the
-	frequency bands.
-    * - __u32
-      - ``rangehigh``
-      - :cspan:`1` The highest tunable frequency in units of 62.5 kHz,
-	or if the ``capability`` flag ``V4L2_TUNER_CAP_LOW`` is set, in
-	units of 62.5 Hz, or if the ``capability`` flag
-	``V4L2_TUNER_CAP_1HZ`` is set, in units of 1 Hz. If multiple
-	frequency bands are supported, then ``rangehigh`` is the highest
-	frequency of all the frequency bands.
-    * - __u32
-      - ``rxsubchans``
-      - :cspan:`1`
-
-	Some tuners or audio decoders can determine the received audio
-	subprograms by analyzing audio carriers, pilot tones or other
-	indicators. To pass this information drivers set flags defined in
-	:ref:`tuner-rxsubchans` in this field. For example:
-    * -
-      -
-      - ``V4L2_TUNER_SUB_MONO``
-      - receiving mono audio
-    * -
-      -
-      - ``STEREO | SAP``
-      - receiving stereo audio and a secondary audio program
-    * -
-      -
-      - ``MONO | STEREO``
-      - receiving mono or stereo audio, the hardware cannot distinguish
-    * -
-      -
-      - ``LANG1 | LANG2``
-      - receiving bilingual audio
-    * -
-      -
-      - ``MONO | STEREO | LANG1 | LANG2``
-      - receiving mono, stereo or bilingual audio
-    * -
-      -
-      - :cspan:`1`
-
-	When the ``V4L2_TUNER_CAP_STEREO``, ``_LANG1``, ``_LANG2`` or
-	``_SAP`` flag is cleared in the ``capability`` field, the
-	corresponding ``V4L2_TUNER_SUB_`` flag must not be set here.
-
-	This field is valid only if this is the tuner of the current video
-	input, or when the structure refers to a radio tuner.
-    * - __u32
-      - ``audmode``
-      - :cspan:`1`
-
-	The selected audio mode, see :ref:`tuner-audmode` for valid
-	values. The audio mode does not affect audio subprogram detection,
-	and like a :ref:`control` it does not automatically
-	change unless the requested mode is invalid or unsupported. See
-	:ref:`tuner-matrix` for possible results when the selected and
-	received audio programs do not match.
-
-	Currently this is the only field of struct
-	struct :c:type:`v4l2_tuner` applications can change.
-    * - __u32
-      - ``signal``
-      - :cspan:`1` The signal strength if known.
-
-	Ranging from 0 to 65535. Higher values indicate a better signal.
-    * - __s32
-      - ``afc``
-      - :cspan:`1` Automatic frequency control.
-
-	When the ``afc`` value is negative, the frequency is too
-	low, when positive too high.
-    * - __u32
-      - ``reserved``\ [4]
-      - :cspan:`1` Reserved for future extensions.
-
-	Drivers and applications must set the array to zero.
-
-
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. c:type:: v4l2_tuner_type
-
-.. flat-table:: enum v4l2_tuner_type
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 6
-
-    * - ``V4L2_TUNER_RADIO``
-      - 1
-      - Tuner supports radio
-    * - ``V4L2_TUNER_ANALOG_TV``
-      - 2
-      - Tuner supports analog TV
-    * - ``V4L2_TUNER_SDR``
-      - 4
-      - Tuner controls the A/D and/or D/A block of a
-	Software Digital Radio (SDR)
-    * - ``V4L2_TUNER_RF``
-      - 5
-      - Tuner controls the RF part of a Software Digital Radio (SDR)
-
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. _tuner-capability:
-
-.. cssclass:: longtable
-
-.. flat-table:: Tuner and Modulator Capability Flags
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_TUNER_CAP_LOW``
-      - 0x0001
-      - When set, tuning frequencies are expressed in units of 62.5 Hz
-	instead of 62.5 kHz.
-    * - ``V4L2_TUNER_CAP_NORM``
-      - 0x0002
-      - This is a multi-standard tuner; the video standard can or must be
-	switched. (B/G PAL tuners for example are typically not considered
-	multi-standard because the video standard is automatically
-	determined from the frequency band.) The set of supported video
-	standards is available from the struct
-	:c:type:`v4l2_input` pointing to this tuner, see the
-	description of ioctl :ref:`VIDIOC_ENUMINPUT`
-	for details. Only ``V4L2_TUNER_ANALOG_TV`` tuners can have this
-	capability.
-    * - ``V4L2_TUNER_CAP_HWSEEK_BOUNDED``
-      - 0x0004
-      - If set, then this tuner supports the hardware seek functionality
-	where the seek stops when it reaches the end of the frequency
-	range.
-    * - ``V4L2_TUNER_CAP_HWSEEK_WRAP``
-      - 0x0008
-      - If set, then this tuner supports the hardware seek functionality
-	where the seek wraps around when it reaches the end of the
-	frequency range.
-    * - ``V4L2_TUNER_CAP_STEREO``
-      - 0x0010
-      - Stereo audio reception is supported.
-    * - ``V4L2_TUNER_CAP_LANG1``
-      - 0x0040
-      - Reception of the primary language of a bilingual audio program is
-	supported. Bilingual audio is a feature of two-channel systems,
-	transmitting the primary language monaural on the main audio
-	carrier and a secondary language monaural on a second carrier.
-	Only ``V4L2_TUNER_ANALOG_TV`` tuners can have this capability.
-    * - ``V4L2_TUNER_CAP_LANG2``
-      - 0x0020
-      - Reception of the secondary language of a bilingual audio program
-	is supported. Only ``V4L2_TUNER_ANALOG_TV`` tuners can have this
-	capability.
-    * - ``V4L2_TUNER_CAP_SAP``
-      - 0x0020
-      - Reception of a secondary audio program is supported. This is a
-	feature of the BTSC system which accompanies the NTSC video
-	standard. Two audio carriers are available for mono or stereo
-	transmissions of a primary language, and an independent third
-	carrier for a monaural secondary language. Only
-	``V4L2_TUNER_ANALOG_TV`` tuners can have this capability.
-
-	.. note::
-
-	   The ``V4L2_TUNER_CAP_LANG2`` and ``V4L2_TUNER_CAP_SAP``
-	   flags are synonyms. ``V4L2_TUNER_CAP_SAP`` applies when the tuner
-	   supports the ``V4L2_STD_NTSC_M`` video standard.
-    * - ``V4L2_TUNER_CAP_RDS``
-      - 0x0080
-      - RDS capture is supported. This capability is only valid for radio
-	tuners.
-    * - ``V4L2_TUNER_CAP_RDS_BLOCK_IO``
-      - 0x0100
-      - The RDS data is passed as unparsed RDS blocks.
-    * - ``V4L2_TUNER_CAP_RDS_CONTROLS``
-      - 0x0200
-      - The RDS data is parsed by the hardware and set via controls.
-    * - ``V4L2_TUNER_CAP_FREQ_BANDS``
-      - 0x0400
-      - The :ref:`VIDIOC_ENUM_FREQ_BANDS`
-	ioctl can be used to enumerate the available frequency bands.
-    * - ``V4L2_TUNER_CAP_HWSEEK_PROG_LIM``
-      - 0x0800
-      - The range to search when using the hardware seek functionality is
-	programmable, see
-	:ref:`VIDIOC_S_HW_FREQ_SEEK` for
-	details.
-    * - ``V4L2_TUNER_CAP_1HZ``
-      - 0x1000
-      - When set, tuning frequencies are expressed in units of 1 Hz
-	instead of 62.5 kHz.
-
-
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. _tuner-rxsubchans:
-
-.. flat-table:: Tuner Audio Reception Flags
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_TUNER_SUB_MONO``
-      - 0x0001
-      - The tuner receives a mono audio signal.
-    * - ``V4L2_TUNER_SUB_STEREO``
-      - 0x0002
-      - The tuner receives a stereo audio signal.
-    * - ``V4L2_TUNER_SUB_LANG1``
-      - 0x0008
-      - The tuner receives the primary language of a bilingual audio
-	signal. Drivers must clear this flag when the current video
-	standard is ``V4L2_STD_NTSC_M``.
-    * - ``V4L2_TUNER_SUB_LANG2``
-      - 0x0004
-      - The tuner receives the secondary language of a bilingual audio
-	signal (or a second audio program).
-    * - ``V4L2_TUNER_SUB_SAP``
-      - 0x0004
-      - The tuner receives a Second Audio Program.
-
-	.. note::
-
-	   The ``V4L2_TUNER_SUB_LANG2`` and ``V4L2_TUNER_SUB_SAP``
-	   flags are synonyms. The ``V4L2_TUNER_SUB_SAP`` flag applies
-	   when the current video standard is ``V4L2_STD_NTSC_M``.
-    * - ``V4L2_TUNER_SUB_RDS``
-      - 0x0010
-      - The tuner receives an RDS channel.
-
-
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. _tuner-audmode:
-
-.. flat-table:: Tuner Audio Modes
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_TUNER_MODE_MONO``
-      - 0
-      - Play mono audio. When the tuner receives a stereo signal this a
-	down-mix of the left and right channel. When the tuner receives a
-	bilingual or SAP signal this mode selects the primary language.
-    * - ``V4L2_TUNER_MODE_STEREO``
-      - 1
-      - Play stereo audio. When the tuner receives bilingual audio it may
-	play different languages on the left and right channel or the
-	primary language is played on both channels.
-
-	Playing different languages in this mode is deprecated. New
-	drivers should do this only in ``MODE_LANG1_LANG2``.
-
-	When the tuner receives no stereo signal or does not support
-	stereo reception the driver shall fall back to ``MODE_MONO``.
-    * - ``V4L2_TUNER_MODE_LANG1``
-      - 3
-      - Play the primary language, mono or stereo. Only
-	``V4L2_TUNER_ANALOG_TV`` tuners support this mode.
-    * - ``V4L2_TUNER_MODE_LANG2``
-      - 2
-      - Play the secondary language, mono. When the tuner receives no
-	bilingual audio or SAP, or their reception is not supported the
-	driver shall fall back to mono or stereo mode. Only
-	``V4L2_TUNER_ANALOG_TV`` tuners support this mode.
-    * - ``V4L2_TUNER_MODE_SAP``
-      - 2
-      - Play the Second Audio Program. When the tuner receives no
-	bilingual audio or SAP, or their reception is not supported the
-	driver shall fall back to mono or stereo mode. Only
-	``V4L2_TUNER_ANALOG_TV`` tuners support this mode.
-
-	.. note:: The ``V4L2_TUNER_MODE_LANG2`` and ``V4L2_TUNER_MODE_SAP``
-	   are synonyms.
-    * - ``V4L2_TUNER_MODE_LANG1_LANG2``
-      - 4
-      - Play the primary language on the left channel, the secondary
-	language on the right channel. When the tuner receives no
-	bilingual audio or SAP, it shall fall back to ``MODE_LANG1`` or
-	``MODE_MONO``. Only ``V4L2_TUNER_ANALOG_TV`` tuners support this
-	mode.
-
-.. raw:: latex
-
-    \scriptsize
-
-.. tabularcolumns:: |p{1.5cm}|p{1.5cm}|p{2.9cm}|p{2.9cm}|p{2.9cm}|p{2.9cm}|
-
-.. _tuner-matrix:
-
-.. flat-table:: Tuner Audio Matrix
-    :header-rows:  2
-    :stub-columns: 0
-    :widths: 7 7 14 14 14 14
-
-    * -
-      - :cspan:`4` Selected ``V4L2_TUNER_MODE_``
-    * - Received ``V4L2_TUNER_SUB_``
-      - ``MONO``
-      - ``STEREO``
-      - ``LANG1``
-      - ``LANG2 = SAP``
-      - ``LANG1_LANG2``\ [#f1]_
-    * - ``MONO``
-      - Mono
-      - Mono/Mono
-      - Mono
-      - Mono
-      - Mono/Mono
-    * - ``MONO | SAP``
-      - Mono
-      - Mono/Mono
-      - Mono
-      - SAP
-      - Mono/SAP (preferred) or Mono/Mono
-    * - ``STEREO``
-      - L+R
-      - L/R
-      - Stereo L/R (preferred) or Mono L+R
-      - Stereo L/R (preferred) or Mono L+R
-      - L/R (preferred) or L+R/L+R
-    * - ``STEREO | SAP``
-      - L+R
-      - L/R
-      - Stereo L/R (preferred) or Mono L+R
-      - SAP
-      - L+R/SAP (preferred) or L/R or L+R/L+R
-    * - ``LANG1 | LANG2``
-      - Language 1
-      - Lang1/Lang2 (deprecated\ [#f2]_) or Lang1/Lang1
-      - Language 1
-      - Language 2
-      - Lang1/Lang2 (preferred) or Lang1/Lang1
-
-.. raw:: latex
-
-    \normalsize
-
-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
-    The struct :c:type:`v4l2_tuner` ``index`` is out of
-    bounds.
-
-.. [#f1]
-   This mode has been added in Linux 2.6.17 and may not be supported by
-   older drivers.
-
-.. [#f2]
-   Playback of both languages in ``MODE_STEREO`` is deprecated. In the
-   future drivers should produce only the primary language in this mode.
-   Applications should request ``MODE_LANG1_LANG2`` to record both
-   languages or a stereo signal.
diff --git a/Documentation/media/uapi/v4l/vidioc-log-status.rst b/Documentation/media/uapi/v4l/vidioc-log-status.rst
deleted file mode 100644
index 16bb5509ad66..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-log-status.rst
+++ /dev/null
@@ -1,56 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_LOG_STATUS:
-
-***********************
-ioctl VIDIOC_LOG_STATUS
-***********************
-
-Name
-====
-
-VIDIOC_LOG_STATUS - Log driver status information
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_LOG_STATUS)
-    :name: VIDIOC_LOG_STATUS
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-
-Description
-===========
-
-As the video/audio devices become more complicated it becomes harder to
-debug problems. When this ioctl is called the driver will output the
-current device status to the kernel log. This is particular useful when
-dealing with problems like no sound, no video and incorrectly tuned
-channels. Also many modern devices autodetect video and audio standards
-and this ioctl will report what the device thinks what the standard is.
-Mismatches may give an indication where the problem is.
-
-This ioctl is optional and not all drivers support it. It was introduced
-in Linux 2.6.15.
-
-
-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/v4l/vidioc-overlay.rst b/Documentation/media/uapi/v4l/vidioc-overlay.rst
deleted file mode 100644
index fc5a86e8c1f2..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-overlay.rst
+++ /dev/null
@@ -1,61 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_OVERLAY:
-
-********************
-ioctl VIDIOC_OVERLAY
-********************
-
-Name
-====
-
-VIDIOC_OVERLAY - Start or stop video overlay
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_OVERLAY, const int *argp )
-    :name: VIDIOC_OVERLAY
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to an integer.
-
-
-Description
-===========
-
-This ioctl is part of the :ref:`video overlay <overlay>` I/O method.
-Applications call :ref:`VIDIOC_OVERLAY` to start or stop the overlay. It
-takes a pointer to an integer which must be set to zero by the
-application to stop overlay, to one to start.
-
-Drivers do not support :ref:`VIDIOC_STREAMON` or
-:ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` with
-``V4L2_BUF_TYPE_VIDEO_OVERLAY``.
-
-
-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
-    The overlay parameters have not been set up. See :ref:`overlay`
-    for the necessary steps.
diff --git a/Documentation/media/uapi/v4l/vidioc-prepare-buf.rst b/Documentation/media/uapi/v4l/vidioc-prepare-buf.rst
deleted file mode 100644
index 7c6b5f4e1011..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-prepare-buf.rst
+++ /dev/null
@@ -1,65 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_PREPARE_BUF:
-
-************************
-ioctl VIDIOC_PREPARE_BUF
-************************
-
-Name
-====
-
-VIDIOC_PREPARE_BUF - Prepare a buffer for I/O
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_PREPARE_BUF, struct v4l2_buffer *argp )
-    :name: VIDIOC_PREPARE_BUF
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_buffer`.
-
-
-Description
-===========
-
-Applications can optionally call the :ref:`VIDIOC_PREPARE_BUF` ioctl to
-pass ownership of the buffer to the driver before actually enqueuing it,
-using the :ref:`VIDIOC_QBUF <VIDIOC_QBUF>` ioctl, and to prepare it for future I/O. Such
-preparations may include cache invalidation or cleaning. Performing them
-in advance saves time during the actual I/O.
-
-The struct :c:type:`v4l2_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.
-
-EBUSY
-    File I/O is in progress.
-
-EINVAL
-    The buffer ``type`` is not supported, or the ``index`` is out of
-    bounds, or no buffers have been allocated yet, or the ``userptr`` or
-    ``length`` are invalid.
diff --git a/Documentation/media/uapi/v4l/vidioc-qbuf.rst b/Documentation/media/uapi/v4l/vidioc-qbuf.rst
deleted file mode 100644
index 407302d80684..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-qbuf.rst
+++ /dev/null
@@ -1,205 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_QBUF:
-
-*******************************
-ioctl VIDIOC_QBUF, VIDIOC_DQBUF
-*******************************
-
-Name
-====
-
-VIDIOC_QBUF - VIDIOC_DQBUF - Exchange a buffer with the driver
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_QBUF, struct v4l2_buffer *argp )
-    :name: VIDIOC_QBUF
-
-.. c:function:: int ioctl( int fd, VIDIOC_DQBUF, struct v4l2_buffer *argp )
-    :name: VIDIOC_DQBUF
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_buffer`.
-
-
-Description
-===========
-
-Applications call the ``VIDIOC_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 ``type`` field of a struct
-:c:type:`v4l2_buffer` to the same buffer type as was
-previously used with struct :c:type:`v4l2_format` ``type``
-and struct :c:type:`v4l2_requestbuffers` ``type``.
-Applications must also set the ``index`` field. Valid index numbers
-range from zero to the number of buffers allocated with
-:ref:`VIDIOC_REQBUFS` (struct
-:c:type:`v4l2_requestbuffers` ``count``) minus
-one. The contents of the struct :c:type:`v4l2_buffer` returned
-by a :ref:`VIDIOC_QUERYBUF` ioctl will do as well.
-When the buffer is intended for output (``type`` is
-``V4L2_BUF_TYPE_VIDEO_OUTPUT``, ``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE``,
-or ``V4L2_BUF_TYPE_VBI_OUTPUT``) applications must also initialize the
-``bytesused``, ``field`` and ``timestamp`` fields, see :ref:`buffer`
-for details. Applications must also set ``flags`` to 0. The
-``reserved2`` and ``reserved`` fields must be set to 0. When using the
-:ref:`multi-planar API <planar-apis>`, the ``m.planes`` field must
-contain a userspace pointer to a filled-in array of struct
-:c:type:`v4l2_plane` and the ``length`` field must be set
-to the number of elements in that array.
-
-To enqueue a :ref:`memory mapped <mmap>` buffer applications set the
-``memory`` field to ``V4L2_MEMORY_MMAP``. When ``VIDIOC_QBUF`` is called
-with a pointer to this structure the driver sets the
-``V4L2_BUF_FLAG_MAPPED`` and ``V4L2_BUF_FLAG_QUEUED`` flags and clears
-the ``V4L2_BUF_FLAG_DONE`` flag in the ``flags`` field, or it returns an
-``EINVAL`` error code.
-
-To enqueue a :ref:`user pointer <userp>` buffer applications set the
-``memory`` field to ``V4L2_MEMORY_USERPTR``, the ``m.userptr`` field to
-the address of the buffer and ``length`` to its size. When the
-multi-planar API is used, ``m.userptr`` and ``length`` members of the
-passed array of struct :c:type:`v4l2_plane` have to be used
-instead. When ``VIDIOC_QBUF`` is called with a pointer to this structure
-the driver sets the ``V4L2_BUF_FLAG_QUEUED`` flag and clears the
-``V4L2_BUF_FLAG_MAPPED`` and ``V4L2_BUF_FLAG_DONE`` flags in the
-``flags`` field, or it returns an error code. This ioctl locks the
-memory pages of the buffer in physical memory, they cannot be swapped
-out to disk. Buffers remain locked until dequeued, until the
-:ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` or
-:ref:`VIDIOC_REQBUFS` ioctl is called, or until the
-device is closed.
-
-To enqueue a :ref:`DMABUF <dmabuf>` buffer applications set the
-``memory`` field to ``V4L2_MEMORY_DMABUF`` and the ``m.fd`` field to a
-file descriptor associated with a DMABUF buffer. When the multi-planar
-API is used the ``m.fd`` fields of the passed array of struct
-:c:type:`v4l2_plane` have to be used instead. When
-``VIDIOC_QBUF`` is called with a pointer to this structure the driver
-sets the ``V4L2_BUF_FLAG_QUEUED`` flag and clears the
-``V4L2_BUF_FLAG_MAPPED`` and ``V4L2_BUF_FLAG_DONE`` flags in the
-``flags`` field, or it returns an error code. This ioctl locks the
-buffer. Locking a buffer means passing it to a driver for a hardware
-access (usually DMA). If an application accesses (reads/writes) a locked
-buffer then the result is undefined. Buffers remain locked until
-dequeued, until the :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` or
-:ref:`VIDIOC_REQBUFS` ioctl is called, or until the
-device is closed.
-
-The ``request_fd`` field can be used with the ``VIDIOC_QBUF`` ioctl to specify
-the file descriptor of a :ref:`request <media-request-api>`, if requests are
-in use. Setting it means that the buffer will not be passed to the driver
-until the request itself is queued. Also, the driver will apply any
-settings associated with the request for this buffer. This field will
-be ignored unless the ``V4L2_BUF_FLAG_REQUEST_FD`` flag is set.
-If the device does not support requests, then ``EBADR`` will be returned.
-If requests are supported but an invalid request file descriptor is given,
-then ``EINVAL`` will be returned.
-
-.. caution::
-   It is not allowed to mix queuing requests with queuing buffers directly.
-   ``EBUSY`` will be returned if the first buffer was queued directly and
-   then the application tries to queue a request, or vice versa. After
-   closing the file descriptor, calling
-   :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` or calling :ref:`VIDIOC_REQBUFS`
-   the check for this will be reset.
-
-   For :ref:`memory-to-memory devices <mem2mem>` you can specify the
-   ``request_fd`` only for output buffers, not for capture buffers. Attempting
-   to specify this for a capture buffer will result in an ``EBADR`` error.
-
-Applications call the ``VIDIOC_DQBUF`` ioctl to dequeue a filled
-(capturing) or displayed (output) buffer from the driver's outgoing
-queue. They just set the ``type``, ``memory`` and ``reserved`` fields of
-a struct :c:type:`v4l2_buffer` as above, when
-``VIDIOC_DQBUF`` is called with a pointer to this structure the driver
-fills the remaining fields or returns an error code. The driver may also
-set ``V4L2_BUF_FLAG_ERROR`` in the ``flags`` field. It indicates a
-non-critical (recoverable) streaming error. In such case the application
-may continue as normal, but should be aware that data in the dequeued
-buffer might be corrupted. When using the multi-planar API, the planes
-array must be passed in as well.
-
-If the application sets the ``memory`` field to ``V4L2_MEMORY_DMABUF`` to
-dequeue a :ref:`DMABUF <dmabuf>` buffer, the driver fills the ``m.fd`` field
-with a file descriptor numerically the same as the one given to ``VIDIOC_QBUF``
-when the buffer was enqueued. No new file descriptor is created at dequeue time
-and the value is only for the application convenience. When the multi-planar
-API is used the ``m.fd`` fields of the passed array of struct
-:c:type:`v4l2_plane` are filled instead.
-
-By default ``VIDIOC_DQBUF`` blocks when no buffer is in the outgoing
-queue. When the ``O_NONBLOCK`` flag was given to the
-:ref:`open() <func-open>` function, ``VIDIOC_DQBUF`` returns
-immediately with an ``EAGAIN`` error code when no buffer is available.
-
-The struct :c:type:`v4l2_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 buffer ``type`` is not supported, or the ``index`` is out of
-    bounds, or no buffers have been allocated yet, or the ``userptr`` or
-    ``length`` are invalid, or the ``V4L2_BUF_FLAG_REQUEST_FD`` flag was
-    set but the the given ``request_fd`` was invalid, or ``m.fd`` was
-    an invalid DMABUF file descriptor.
-
-EIO
-    ``VIDIOC_DQBUF`` failed due to an internal error. Can also indicate
-    temporary problems like signal loss.
-
-    .. note::
-
-       The driver might dequeue an (empty) buffer despite returning
-       an error, or even stop capturing. Reusing such buffer may be unsafe
-       though and its details (e.g. ``index``) may not be returned either.
-       It is recommended that drivers indicate recoverable errors by setting
-       the ``V4L2_BUF_FLAG_ERROR`` and returning 0 instead. In that case the
-       application should be able to safely reuse the buffer and continue
-       streaming.
-
-EPIPE
-    ``VIDIOC_DQBUF`` returns this on an empty capture queue for mem2mem
-    codecs if a buffer with the ``V4L2_BUF_FLAG_LAST`` was already
-    dequeued and no new buffers are expected to become available.
-
-EBADR
-    The ``V4L2_BUF_FLAG_REQUEST_FD`` flag was set but the device does not
-    support requests for the given buffer type, or
-    the ``V4L2_BUF_FLAG_REQUEST_FD`` flag was not set but the device requires
-    that the buffer is part of a request.
-
-EBUSY
-    The first buffer was queued via a request, but the application now tries
-    to queue it directly, or vice versa (it is not permitted to mix the two
-    APIs).
diff --git a/Documentation/media/uapi/v4l/vidioc-query-dv-timings.rst b/Documentation/media/uapi/v4l/vidioc-query-dv-timings.rst
deleted file mode 100644
index e9b055395382..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-query-dv-timings.rst
+++ /dev/null
@@ -1,94 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_QUERY_DV_TIMINGS:
-
-*****************************
-ioctl VIDIOC_QUERY_DV_TIMINGS
-*****************************
-
-Name
-====
-
-VIDIOC_QUERY_DV_TIMINGS - VIDIOC_SUBDEV_QUERY_DV_TIMINGS - Sense the DV preset received by the current input
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_QUERY_DV_TIMINGS, struct v4l2_dv_timings *argp )
-    :name: VIDIOC_QUERY_DV_TIMINGS
-
-.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_QUERY_DV_TIMINGS, struct v4l2_dv_timings *argp )
-    :name: VIDIOC_SUBDEV_QUERY_DV_TIMINGS
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_dv_timings`.
-
-
-Description
-===========
-
-The hardware may be able to detect the current DV timings automatically,
-similar to sensing the video standard. To do so, applications call
-:ref:`VIDIOC_QUERY_DV_TIMINGS` with a pointer to a struct
-:c:type:`v4l2_dv_timings`. Once the hardware detects
-the timings, it will fill in the timings structure.
-
-.. note::
-
-   Drivers shall *not* switch timings automatically if new
-   timings are detected. Instead, drivers should send the
-   ``V4L2_EVENT_SOURCE_CHANGE`` event (if they support this) and expect
-   that userspace will take action by calling :ref:`VIDIOC_QUERY_DV_TIMINGS`.
-   The reason is that new timings usually mean different buffer sizes as
-   well, and you cannot change buffer sizes on the fly. In general,
-   applications that receive the Source Change event will have to call
-   :ref:`VIDIOC_QUERY_DV_TIMINGS`, and if the detected timings are valid they
-   will have to stop streaming, set the new timings, allocate new buffers
-   and start streaming again.
-
-If the timings could not be detected because there was no signal, then
-ENOLINK is returned. If a signal was detected, but it was unstable and
-the receiver could not lock to the signal, then ``ENOLCK`` is returned. If
-the receiver could lock to the signal, but the format is unsupported
-(e.g. because the pixelclock is out of range of the hardware
-capabilities), then the driver fills in whatever timings it could find
-and returns ``ERANGE``. In that case the application can call
-:ref:`VIDIOC_DV_TIMINGS_CAP` to compare the
-found timings with the hardware's capabilities in order to give more
-precise feedback to the user.
-
-
-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.
-
-ENODATA
-    Digital video timings are not supported for this input or output.
-
-ENOLINK
-    No timings could be detected because no signal was found.
-
-ENOLCK
-    The signal was unstable and the hardware could not lock on to it.
-
-ERANGE
-    Timings were found, but they are out of range of the hardware
-    capabilities.
diff --git a/Documentation/media/uapi/v4l/vidioc-querybuf.rst b/Documentation/media/uapi/v4l/vidioc-querybuf.rst
deleted file mode 100644
index 7da60b24e8b6..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-querybuf.rst
+++ /dev/null
@@ -1,87 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_QUERYBUF:
-
-*********************
-ioctl VIDIOC_QUERYBUF
-*********************
-
-Name
-====
-
-VIDIOC_QUERYBUF - Query the status of a buffer
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_QUERYBUF, struct v4l2_buffer *argp )
-    :name: VIDIOC_QUERYBUF
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_buffer`.
-
-
-Description
-===========
-
-This ioctl is part of the :ref:`streaming <mmap>` 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:`VIDIOC_REQBUFS` ioctl.
-
-Applications set the ``type`` field of a struct
-:c:type:`v4l2_buffer` to the same buffer type as was
-previously used with struct :c:type:`v4l2_format` ``type``
-and struct :c:type:`v4l2_requestbuffers` ``type``,
-and the ``index`` field. Valid index numbers range from zero to the
-number of buffers allocated with
-:ref:`VIDIOC_REQBUFS` (struct
-:c:type:`v4l2_requestbuffers` ``count``) minus
-one. The ``reserved`` and ``reserved2`` fields must be set to 0. When
-using the :ref:`multi-planar API <planar-apis>`, the ``m.planes``
-field must contain a userspace pointer to an array of struct
-:c:type:`v4l2_plane` and the ``length`` field has to be set
-to the number of elements in that array. After calling
-:ref:`VIDIOC_QUERYBUF` with a pointer to this structure drivers return an
-error code or fill the rest of the structure.
-
-In the ``flags`` field the ``V4L2_BUF_FLAG_MAPPED``,
-``V4L2_BUF_FLAG_PREPARED``, ``V4L2_BUF_FLAG_QUEUED`` and
-``V4L2_BUF_FLAG_DONE`` flags will be valid. The ``memory`` field will be
-set to the current I/O method. For the single-planar API, the
-``m.offset`` contains the offset of the buffer from the start of the
-device memory, the ``length`` field its size. For the multi-planar API,
-fields ``m.mem_offset`` and ``length`` in the ``m.planes`` array
-elements will be used instead and the ``length`` field of struct
-:c:type:`v4l2_buffer` is set to the number of filled-in
-array elements. The driver may or may not set the remaining fields and
-flags, they are meaningless in this context.
-
-The struct :c:type:`v4l2_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.
-
-EINVAL
-    The buffer ``type`` is not supported, or the ``index`` is out of
-    bounds.
diff --git a/Documentation/media/uapi/v4l/vidioc-querycap.rst b/Documentation/media/uapi/v4l/vidioc-querycap.rst
deleted file mode 100644
index 5f9930195d62..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-querycap.rst
+++ /dev/null
@@ -1,284 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_QUERYCAP:
-
-*********************
-ioctl VIDIOC_QUERYCAP
-*********************
-
-Name
-====
-
-VIDIOC_QUERYCAP - Query device capabilities
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_QUERYCAP, struct v4l2_capability *argp )
-    :name: VIDIOC_QUERYCAP
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_capability`.
-
-
-Description
-===========
-
-All V4L2 devices support the ``VIDIOC_QUERYCAP`` ioctl. It is used to
-identify kernel devices compatible with this specification and to obtain
-information about driver and hardware capabilities. The ioctl takes a
-pointer to a struct :c:type:`v4l2_capability` which is
-filled by the driver. When the driver is not compatible with this
-specification the ioctl returns an ``EINVAL`` error code.
-
-
-.. tabularcolumns:: |p{1.5cm}|p{2.5cm}|p{13cm}|
-
-.. c:type:: v4l2_capability
-
-.. flat-table:: struct v4l2_capability
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 4 20
-
-    * - __u8
-      - ``driver``\ [16]
-      - Name of the driver, a unique NUL-terminated ASCII string. For
-	example: "bttv". Driver specific applications can use this
-	information to verify the driver identity. It is also useful to
-	work around known bugs, or to identify drivers in error reports.
-
-	Storing strings in fixed sized arrays is bad practice but
-	unavoidable here. Drivers and applications should take precautions
-	to never read or write beyond the end of the array and to make
-	sure the strings are properly NUL-terminated.
-    * - __u8
-      - ``card``\ [32]
-      - Name of the device, a NUL-terminated UTF-8 string. For example:
-	"Yoyodyne TV/FM". One driver may support different brands or
-	models of video hardware. This information is intended for users,
-	for example in a menu of available devices. Since multiple TV
-	cards of the same brand may be installed which are supported by
-	the same driver, this name should be combined with the character
-	device file name (e. g. ``/dev/video2``) or the ``bus_info``
-	string to avoid ambiguities.
-    * - __u8
-      - ``bus_info``\ [32]
-      - Location of the device in the system, a NUL-terminated ASCII
-	string. For example: "PCI:0000:05:06.0". This information is
-	intended for users, to distinguish multiple identical devices. If
-	no such information is available the field must simply count the
-	devices controlled by the driver ("platform:vivi-000"). The
-	bus_info must start with "PCI:" for PCI boards, "PCIe:" for PCI
-	Express boards, "usb-" for USB devices, "I2C:" for i2c devices,
-	"ISA:" for ISA devices, "parport" for parallel port devices and
-	"platform:" for platform devices.
-    * - __u32
-      - ``version``
-      - Version number of the driver.
-
-	Starting with kernel 3.1, the version reported is provided by the
-	V4L2 subsystem following the kernel numbering scheme. However, it
-	may not always return the same version as the kernel if, for
-	example, a stable or distribution-modified kernel uses the V4L2
-	stack from a newer kernel.
-
-	The version number is formatted using the ``KERNEL_VERSION()``
-	macro. For example if the media stack corresponds to the V4L2
-	version shipped with Kernel 4.14, it would be equivalent to:
-    * - :cspan:`2`
-
-	``#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))``
-
-	``__u32 version = KERNEL_VERSION(4, 14, 0);``
-
-	``printf ("Version: %u.%u.%u\\n",``
-
-	``(version >> 16) & 0xFF, (version >> 8) & 0xFF, version & 0xFF);``
-    * - __u32
-      - ``capabilities``
-      - Available capabilities of the physical device as a whole, see
-	:ref:`device-capabilities`. The same physical device can export
-	multiple devices in /dev (e.g. /dev/videoX, /dev/vbiY and
-	/dev/radioZ). The ``capabilities`` field should contain a union of
-	all capabilities available around the several V4L2 devices
-	exported to userspace. For all those devices the ``capabilities``
-	field returns the same set of capabilities. This allows
-	applications to open just one of the devices (typically the video
-	device) and discover whether video, vbi and/or radio are also
-	supported.
-    * - __u32
-      - ``device_caps``
-      - Device capabilities of the opened device, see
-	:ref:`device-capabilities`. Should contain the available
-	capabilities of that specific device node. So, for example,
-	``device_caps`` of a radio device will only contain radio related
-	capabilities and no video or vbi capabilities. This field is only
-	set if the ``capabilities`` field contains the
-	``V4L2_CAP_DEVICE_CAPS`` capability. Only the ``capabilities``
-	field can have the ``V4L2_CAP_DEVICE_CAPS`` capability,
-	``device_caps`` will never set ``V4L2_CAP_DEVICE_CAPS``.
-    * - __u32
-      - ``reserved``\ [3]
-      - Reserved for future extensions. Drivers must set this array to
-	zero.
-
-
-
-.. tabularcolumns:: |p{6.1cm}|p{2.2cm}|p{8.7cm}|
-
-.. _device-capabilities:
-
-.. cssclass:: longtable
-
-.. flat-table:: Device Capabilities Flags
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_CAP_VIDEO_CAPTURE``
-      - 0x00000001
-      - The device supports the single-planar API through the
-	:ref:`Video Capture <capture>` interface.
-    * - ``V4L2_CAP_VIDEO_CAPTURE_MPLANE``
-      - 0x00001000
-      - The device supports the :ref:`multi-planar API <planar-apis>`
-	through the :ref:`Video Capture <capture>` interface.
-    * - ``V4L2_CAP_VIDEO_OUTPUT``
-      - 0x00000002
-      - The device supports the single-planar API through the
-	:ref:`Video Output <output>` interface.
-    * - ``V4L2_CAP_VIDEO_OUTPUT_MPLANE``
-      - 0x00002000
-      - The device supports the :ref:`multi-planar API <planar-apis>`
-	through the :ref:`Video Output <output>` interface.
-    * - ``V4L2_CAP_VIDEO_M2M``
-      - 0x00004000
-      - The device supports the single-planar API through the Video
-	Memory-To-Memory interface.
-    * - ``V4L2_CAP_VIDEO_M2M_MPLANE``
-      - 0x00008000
-      - The device supports the :ref:`multi-planar API <planar-apis>`
-	through the Video Memory-To-Memory interface.
-    * - ``V4L2_CAP_VIDEO_OVERLAY``
-      - 0x00000004
-      - The device supports the :ref:`Video Overlay <overlay>`
-	interface. A video overlay device typically stores captured images
-	directly in the video memory of a graphics card, with hardware
-	clipping and scaling.
-    * - ``V4L2_CAP_VBI_CAPTURE``
-      - 0x00000010
-      - The device supports the :ref:`Raw VBI Capture <raw-vbi>`
-	interface, providing Teletext and Closed Caption data.
-    * - ``V4L2_CAP_VBI_OUTPUT``
-      - 0x00000020
-      - The device supports the :ref:`Raw VBI Output <raw-vbi>`
-	interface.
-    * - ``V4L2_CAP_SLICED_VBI_CAPTURE``
-      - 0x00000040
-      - The device supports the :ref:`Sliced VBI Capture <sliced>`
-	interface.
-    * - ``V4L2_CAP_SLICED_VBI_OUTPUT``
-      - 0x00000080
-      - The device supports the :ref:`Sliced VBI Output <sliced>`
-	interface.
-    * - ``V4L2_CAP_RDS_CAPTURE``
-      - 0x00000100
-      - The device supports the :ref:`RDS <rds>` capture interface.
-    * - ``V4L2_CAP_VIDEO_OUTPUT_OVERLAY``
-      - 0x00000200
-      - The device supports the :ref:`Video Output Overlay <osd>` (OSD)
-	interface. Unlike the *Video Overlay* interface, this is a
-	secondary function of video output devices and overlays an image
-	onto an outgoing video signal. When the driver sets this flag, it
-	must clear the ``V4L2_CAP_VIDEO_OVERLAY`` flag and vice
-	versa. [#f1]_
-    * - ``V4L2_CAP_HW_FREQ_SEEK``
-      - 0x00000400
-      - The device supports the
-	:ref:`VIDIOC_S_HW_FREQ_SEEK` ioctl
-	for hardware frequency seeking.
-    * - ``V4L2_CAP_RDS_OUTPUT``
-      - 0x00000800
-      - The device supports the :ref:`RDS <rds>` output interface.
-    * - ``V4L2_CAP_TUNER``
-      - 0x00010000
-      - The device has some sort of tuner to receive RF-modulated video
-	signals. For more information about tuner programming see
-	:ref:`tuner`.
-    * - ``V4L2_CAP_AUDIO``
-      - 0x00020000
-      - The device has audio inputs or outputs. It may or may not support
-	audio recording or playback, in PCM or compressed formats. PCM
-	audio support must be implemented as ALSA or OSS interface. For
-	more information on audio inputs and outputs see :ref:`audio`.
-    * - ``V4L2_CAP_RADIO``
-      - 0x00040000
-      - This is a radio receiver.
-    * - ``V4L2_CAP_MODULATOR``
-      - 0x00080000
-      - The device has some sort of modulator to emit RF-modulated
-	video/audio signals. For more information about modulator
-	programming see :ref:`tuner`.
-    * - ``V4L2_CAP_SDR_CAPTURE``
-      - 0x00100000
-      - The device supports the :ref:`SDR Capture <sdr>` interface.
-    * - ``V4L2_CAP_EXT_PIX_FORMAT``
-      - 0x00200000
-      - The device supports the struct
-	:c:type:`v4l2_pix_format` extended fields.
-    * - ``V4L2_CAP_SDR_OUTPUT``
-      - 0x00400000
-      - The device supports the :ref:`SDR Output <sdr>` interface.
-    * - ``V4L2_CAP_META_CAPTURE``
-      - 0x00800000
-      - The device supports the :ref:`metadata` capture interface.
-    * - ``V4L2_CAP_READWRITE``
-      - 0x01000000
-      - The device supports the :ref:`read() <rw>` and/or
-	:ref:`write() <rw>` I/O methods.
-    * - ``V4L2_CAP_ASYNCIO``
-      - 0x02000000
-      - The device supports the :ref:`asynchronous <async>` I/O methods.
-    * - ``V4L2_CAP_STREAMING``
-      - 0x04000000
-      - The device supports the :ref:`streaming <mmap>` I/O method.
-    * - ``V4L2_CAP_META_OUTPUT``
-      - 0x08000000
-      - The device supports the :ref:`metadata` output interface.
-    * - ``V4L2_CAP_TOUCH``
-      - 0x10000000
-      - This is a touch device.
-    * - ``V4L2_CAP_DEVICE_CAPS``
-      - 0x80000000
-      - The driver fills the ``device_caps`` field. This capability can
-	only appear in the ``capabilities`` field and never in the
-	``device_caps`` field.
-
-
-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.
-
-.. [#f1]
-   The struct :c:type:`v4l2_framebuffer` lacks an
-   enum :c:type:`v4l2_buf_type` field, therefore the
-   type of overlay is implied by the driver capabilities.
diff --git a/Documentation/media/uapi/v4l/vidioc-queryctrl.rst b/Documentation/media/uapi/v4l/vidioc-queryctrl.rst
deleted file mode 100644
index 8971f4cfb16e..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-queryctrl.rst
+++ /dev/null
@@ -1,616 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_QUERYCTRL:
-
-*******************************************************************
-ioctls VIDIOC_QUERYCTRL, VIDIOC_QUERY_EXT_CTRL and VIDIOC_QUERYMENU
-*******************************************************************
-
-Name
-====
-
-VIDIOC_QUERYCTRL - VIDIOC_QUERY_EXT_CTRL - VIDIOC_QUERYMENU - Enumerate controls and menu control items
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, int VIDIOC_QUERYCTRL, struct v4l2_queryctrl *argp )
-    :name: VIDIOC_QUERYCTRL
-
-.. c:function:: int ioctl( int fd, VIDIOC_QUERY_EXT_CTRL, struct v4l2_query_ext_ctrl *argp )
-    :name: VIDIOC_QUERY_EXT_CTRL
-
-.. c:function:: int ioctl( int fd, VIDIOC_QUERYMENU, struct v4l2_querymenu *argp )
-    :name: VIDIOC_QUERYMENU
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_queryctrl`, :c:type:`v4l2_query_ext_ctrl`
-    or :c:type:`v4l2_querymenu` (depending on the ioctl).
-
-
-Description
-===========
-
-To query the attributes of a control applications set the ``id`` field
-of a struct :ref:`v4l2_queryctrl <v4l2-queryctrl>` and call the
-``VIDIOC_QUERYCTRL`` ioctl with a pointer to this structure. The driver
-fills the rest of the structure or returns an ``EINVAL`` error code when the
-``id`` is invalid.
-
-It is possible to enumerate controls by calling ``VIDIOC_QUERYCTRL``
-with successive ``id`` values starting from ``V4L2_CID_BASE`` up to and
-exclusive ``V4L2_CID_LASTP1``. Drivers may return ``EINVAL`` if a control in
-this range is not supported. Further applications can enumerate private
-controls, which are not defined in this specification, by starting at
-``V4L2_CID_PRIVATE_BASE`` and incrementing ``id`` until the driver
-returns ``EINVAL``.
-
-In both cases, when the driver sets the ``V4L2_CTRL_FLAG_DISABLED`` flag
-in the ``flags`` field this control is permanently disabled and should
-be ignored by the application. [#f1]_
-
-When the application ORs ``id`` with ``V4L2_CTRL_FLAG_NEXT_CTRL`` the
-driver returns the next supported non-compound control, or ``EINVAL`` if
-there is none. In addition, the ``V4L2_CTRL_FLAG_NEXT_COMPOUND`` flag
-can be specified to enumerate all compound controls (i.e. controls with
-type ≥ ``V4L2_CTRL_COMPOUND_TYPES`` and/or array control, in other words
-controls that contain more than one value). Specify both
-``V4L2_CTRL_FLAG_NEXT_CTRL`` and ``V4L2_CTRL_FLAG_NEXT_COMPOUND`` in
-order to enumerate all controls, compound or not. Drivers which do not
-support these flags yet always return ``EINVAL``.
-
-The ``VIDIOC_QUERY_EXT_CTRL`` ioctl was introduced in order to better
-support controls that can use compound types, and to expose additional
-control information that cannot be returned in struct
-:ref:`v4l2_queryctrl <v4l2-queryctrl>` since that structure is full.
-
-``VIDIOC_QUERY_EXT_CTRL`` is used in the same way as
-``VIDIOC_QUERYCTRL``, except that the ``reserved`` array must be zeroed
-as well.
-
-Additional information is required for menu controls: the names of the
-menu items. To query them applications set the ``id`` and ``index``
-fields of struct :ref:`v4l2_querymenu <v4l2-querymenu>` and call the
-``VIDIOC_QUERYMENU`` ioctl with a pointer to this structure. The driver
-fills the rest of the structure or returns an ``EINVAL`` error code when the
-``id`` or ``index`` is invalid. Menu items are enumerated by calling
-``VIDIOC_QUERYMENU`` with successive ``index`` values from struct
-:ref:`v4l2_queryctrl <v4l2-queryctrl>` ``minimum`` to ``maximum``,
-inclusive.
-
-.. note::
-
-   It is possible for ``VIDIOC_QUERYMENU`` to return
-   an ``EINVAL`` error code for some indices between ``minimum`` and
-   ``maximum``. In that case that particular menu item is not supported by
-   this driver. Also note that the ``minimum`` value is not necessarily 0.
-
-See also the examples in :ref:`control`.
-
-
-.. tabularcolumns:: |p{1.2cm}|p{3.6cm}|p{12.7cm}|
-
-.. _v4l2-queryctrl:
-
-.. cssclass:: longtable
-
-.. flat-table:: struct v4l2_queryctrl
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``id``
-      - Identifies the control, set by the application. See
-	:ref:`control-id` for predefined IDs. When the ID is ORed with
-	V4L2_CTRL_FLAG_NEXT_CTRL the driver clears the flag and
-	returns the first control with a higher ID. Drivers which do not
-	support this flag yet always return an ``EINVAL`` error code.
-    * - __u32
-      - ``type``
-      - Type of control, see :c:type:`v4l2_ctrl_type`.
-    * - __u8
-      - ``name``\ [32]
-      - Name of the control, a NUL-terminated ASCII string. This
-	information is intended for the user.
-    * - __s32
-      - ``minimum``
-      - Minimum value, inclusive. This field gives a lower bound for the
-	control. See enum :c:type:`v4l2_ctrl_type` how
-	the minimum value is to be used for each possible control type.
-	Note that this a signed 32-bit value.
-    * - __s32
-      - ``maximum``
-      - Maximum value, inclusive. This field gives an upper bound for the
-	control. See enum :c:type:`v4l2_ctrl_type` how
-	the maximum value is to be used for each possible control type.
-	Note that this a signed 32-bit value.
-    * - __s32
-      - ``step``
-      - This field gives a step size for the control. See enum
-	:c:type:`v4l2_ctrl_type` how the step value is
-	to be used for each possible control type. Note that this an
-	unsigned 32-bit value.
-
-	Generally drivers should not scale hardware control values. It may
-	be necessary for example when the ``name`` or ``id`` imply a
-	particular unit and the hardware actually accepts only multiples
-	of said unit. If so, drivers must take care values are properly
-	rounded when scaling, such that errors will not accumulate on
-	repeated read-write cycles.
-
-	This field gives the smallest change of an integer control
-	actually affecting hardware. Often the information is needed when
-	the user can change controls by keyboard or GUI buttons, rather
-	than a slider. When for example a hardware register accepts values
-	0-511 and the driver reports 0-65535, step should be 128.
-
-	Note that although signed, the step value is supposed to be always
-	positive.
-    * - __s32
-      - ``default_value``
-      - The default value of a ``V4L2_CTRL_TYPE_INTEGER``, ``_BOOLEAN``,
-	``_BITMASK``, ``_MENU`` or ``_INTEGER_MENU`` control. Not valid
-	for other types of controls.
-
-	.. note::
-
-	   Drivers reset controls to their default value only when
-	   the driver is first loaded, never afterwards.
-    * - __u32
-      - ``flags``
-      - Control flags, see :ref:`control-flags`.
-    * - __u32
-      - ``reserved``\ [2]
-      - Reserved for future extensions. Drivers must set the array to
-	zero.
-
-
-
-.. tabularcolumns:: |p{1.2cm}|p{5.0cm}|p{11.3cm}|
-
-.. _v4l2-query-ext-ctrl:
-
-.. cssclass:: longtable
-
-.. flat-table:: struct v4l2_query_ext_ctrl
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``id``
-      - Identifies the control, set by the application. See
-	:ref:`control-id` for predefined IDs. When the ID is ORed with
-	``V4L2_CTRL_FLAG_NEXT_CTRL`` the driver clears the flag and
-	returns the first non-compound control with a higher ID. When the
-	ID is ORed with ``V4L2_CTRL_FLAG_NEXT_COMPOUND`` the driver clears
-	the flag and returns the first compound control with a higher ID.
-	Set both to get the first control (compound or not) with a higher
-	ID.
-    * - __u32
-      - ``type``
-      - Type of control, see :c:type:`v4l2_ctrl_type`.
-    * - char
-      - ``name``\ [32]
-      - Name of the control, a NUL-terminated ASCII string. This
-	information is intended for the user.
-    * - __s64
-      - ``minimum``
-      - Minimum value, inclusive. This field gives a lower bound for the
-	control. See enum :c:type:`v4l2_ctrl_type` how
-	the minimum value is to be used for each possible control type.
-	Note that this a signed 64-bit value.
-    * - __s64
-      - ``maximum``
-      - Maximum value, inclusive. This field gives an upper bound for the
-	control. See enum :c:type:`v4l2_ctrl_type` how
-	the maximum value is to be used for each possible control type.
-	Note that this a signed 64-bit value.
-    * - __u64
-      - ``step``
-      - This field gives a step size for the control. See enum
-	:c:type:`v4l2_ctrl_type` how the step value is
-	to be used for each possible control type. Note that this an
-	unsigned 64-bit value.
-
-	Generally drivers should not scale hardware control values. It may
-	be necessary for example when the ``name`` or ``id`` imply a
-	particular unit and the hardware actually accepts only multiples
-	of said unit. If so, drivers must take care values are properly
-	rounded when scaling, such that errors will not accumulate on
-	repeated read-write cycles.
-
-	This field gives the smallest change of an integer control
-	actually affecting hardware. Often the information is needed when
-	the user can change controls by keyboard or GUI buttons, rather
-	than a slider. When for example a hardware register accepts values
-	0-511 and the driver reports 0-65535, step should be 128.
-    * - __s64
-      - ``default_value``
-      - The default value of a ``V4L2_CTRL_TYPE_INTEGER``, ``_INTEGER64``,
-	``_BOOLEAN``, ``_BITMASK``, ``_MENU``, ``_INTEGER_MENU``, ``_U8``
-	or ``_U16`` control. Not valid for other types of controls.
-
-	.. note::
-
-	   Drivers reset controls to their default value only when
-	   the driver is first loaded, never afterwards.
-    * - __u32
-      - ``flags``
-      - Control flags, see :ref:`control-flags`.
-    * - __u32
-      - ``elem_size``
-      - The size in bytes of a single element of the array. Given a char
-	pointer ``p`` to a 3-dimensional array you can find the position
-	of cell ``(z, y, x)`` as follows:
-	``p + ((z * dims[1] + y) * dims[0] + x) * elem_size``.
-	``elem_size`` is always valid, also when the control isn't an
-	array. For string controls ``elem_size`` is equal to
-	``maximum + 1``.
-    * - __u32
-      - ``elems``
-      - The number of elements in the N-dimensional array. If this control
-	is not an array, then ``elems`` is 1. The ``elems`` field can
-	never be 0.
-    * - __u32
-      - ``nr_of_dims``
-      - The number of dimension in the N-dimensional array. If this
-	control is not an array, then this field is 0.
-    * - __u32
-      - ``dims[V4L2_CTRL_MAX_DIMS]``
-      - The size of each dimension. The first ``nr_of_dims`` elements of
-	this array must be non-zero, all remaining elements must be zero.
-    * - __u32
-      - ``reserved``\ [32]
-      - Reserved for future extensions. Applications and drivers must set
-	the array to zero.
-
-
-
-.. tabularcolumns:: |p{1.2cm}|p{1.0cm}|p{1.7cm}|p{13.0cm}|
-
-.. _v4l2-querymenu:
-
-.. flat-table:: struct v4l2_querymenu
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``id``
-      - Identifies the control, set by the application from the respective
-	struct :ref:`v4l2_queryctrl <v4l2-queryctrl>` ``id``.
-    * - __u32
-      - ``index``
-      - Index of the menu item, starting at zero, set by the application.
-    * - union {
-      - (anonymous)
-    * - __u8
-      - ``name``\ [32]
-      - Name of the menu item, a NUL-terminated ASCII string. This
-	information is intended for the user. This field is valid for
-	``V4L2_CTRL_TYPE_MENU`` type controls.
-    * - __s64
-      - ``value``
-      - Value of the integer menu item. This field is valid for
-	``V4L2_CTRL_TYPE_INTEGER_MENU`` type controls.
-    * - }
-      -
-    * - __u32
-      - ``reserved``
-      - Reserved for future extensions. Drivers must set the array to
-	zero.
-
-
-
-.. tabularcolumns:: |p{5.8cm}|p{1.4cm}|p{1.0cm}|p{1.4cm}|p{6.9cm}|
-
-.. c:type:: v4l2_ctrl_type
-
-.. cssclass:: longtable
-
-.. flat-table:: enum v4l2_ctrl_type
-    :header-rows:  1
-    :stub-columns: 0
-    :widths:       30 5 5 5 55
-
-    * - Type
-      - ``minimum``
-      - ``step``
-      - ``maximum``
-      - Description
-    * - ``V4L2_CTRL_TYPE_INTEGER``
-      - any
-      - any
-      - any
-      - An integer-valued control ranging from minimum to maximum
-	inclusive. The step value indicates the increment between values.
-    * - ``V4L2_CTRL_TYPE_BOOLEAN``
-      - 0
-      - 1
-      - 1
-      - A boolean-valued control. Zero corresponds to "disabled", and one
-	means "enabled".
-    * - ``V4L2_CTRL_TYPE_MENU``
-      - ≥ 0
-      - 1
-      - N-1
-      - The control has a menu of N choices. The names of the menu items
-	can be enumerated with the ``VIDIOC_QUERYMENU`` ioctl.
-    * - ``V4L2_CTRL_TYPE_INTEGER_MENU``
-      - ≥ 0
-      - 1
-      - N-1
-      - The control has a menu of N choices. The values of the menu items
-	can be enumerated with the ``VIDIOC_QUERYMENU`` ioctl. This is
-	similar to ``V4L2_CTRL_TYPE_MENU`` except that instead of strings,
-	the menu items are signed 64-bit integers.
-    * - ``V4L2_CTRL_TYPE_BITMASK``
-      - 0
-      - n/a
-      - any
-      - A bitmask field. The maximum value is the set of bits that can be
-	used, all other bits are to be 0. The maximum value is interpreted
-	as a __u32, allowing the use of bit 31 in the bitmask.
-    * - ``V4L2_CTRL_TYPE_BUTTON``
-      - 0
-      - 0
-      - 0
-      - A control which performs an action when set. Drivers must ignore
-	the value passed with ``VIDIOC_S_CTRL`` and return an ``EACCES`` error
-	code on a ``VIDIOC_G_CTRL`` attempt.
-    * - ``V4L2_CTRL_TYPE_INTEGER64``
-      - any
-      - any
-      - any
-      - A 64-bit integer valued control. Minimum, maximum and step size
-	cannot be queried using ``VIDIOC_QUERYCTRL``. Only
-	``VIDIOC_QUERY_EXT_CTRL`` can retrieve the 64-bit min/max/step
-	values, they should be interpreted as n/a when using
-	``VIDIOC_QUERYCTRL``.
-    * - ``V4L2_CTRL_TYPE_STRING``
-      - ≥ 0
-      - ≥ 1
-      - ≥ 0
-      - The minimum and maximum string lengths. The step size means that
-	the string must be (minimum + N * step) characters long for N ≥ 0.
-	These lengths do not include the terminating zero, so in order to
-	pass a string of length 8 to
-	:ref:`VIDIOC_S_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` you need to
-	set the ``size`` field of struct
-	:c:type:`v4l2_ext_control` to 9. For
-	:ref:`VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` you can set
-	the ``size`` field to ``maximum`` + 1. Which character encoding is
-	used will depend on the string control itself and should be part
-	of the control documentation.
-    * - ``V4L2_CTRL_TYPE_CTRL_CLASS``
-      - n/a
-      - n/a
-      - n/a
-      - This is not a control. When ``VIDIOC_QUERYCTRL`` is called with a
-	control ID equal to a control class code (see :ref:`ctrl-class`)
-	+ 1, the ioctl returns the name of the control class and this
-	control type. Older drivers which do not support this feature
-	return an ``EINVAL`` error code.
-    * - ``V4L2_CTRL_TYPE_U8``
-      - any
-      - any
-      - any
-      - An unsigned 8-bit valued control ranging from minimum to maximum
-	inclusive. The step value indicates the increment between values.
-    * - ``V4L2_CTRL_TYPE_U16``
-      - any
-      - any
-      - any
-      - An unsigned 16-bit valued control ranging from minimum to maximum
-	inclusive. The step value indicates the increment between values.
-    * - ``V4L2_CTRL_TYPE_U32``
-      - any
-      - any
-      - any
-      - An unsigned 32-bit valued control ranging from minimum to maximum
-	inclusive. The step value indicates the increment between values.
-    * - ``V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS``
-      - n/a
-      - n/a
-      - n/a
-      - A struct :c:type:`v4l2_ctrl_mpeg2_slice_params`, containing MPEG-2
-	slice parameters for stateless video decoders.
-    * - ``V4L2_CTRL_TYPE_MPEG2_QUANTIZATION``
-      - n/a
-      - n/a
-      - n/a
-      - A struct :c:type:`v4l2_ctrl_mpeg2_quantization`, containing MPEG-2
-	quantization matrices for stateless video decoders.
-    * - ``V4L2_CTRL_TYPE_AREA``
-      - n/a
-      - n/a
-      - n/a
-      - A struct :c:type:`v4l2_area`, containing the width and the height
-        of a rectangular area. Units depend on the use case.
-    * - ``V4L2_CTRL_TYPE_H264_SPS``
-      - n/a
-      - n/a
-      - n/a
-      - A struct :c:type:`v4l2_ctrl_h264_sps`, containing H264
-	sequence parameters for stateless video decoders.
-    * - ``V4L2_CTRL_TYPE_H264_PPS``
-      - n/a
-      - n/a
-      - n/a
-      - A struct :c:type:`v4l2_ctrl_h264_pps`, containing H264
-	picture parameters for stateless video decoders.
-    * - ``V4L2_CTRL_TYPE_H264_SCALING_MATRIX``
-      - n/a
-      - n/a
-      - n/a
-      - A struct :c:type:`v4l2_ctrl_h264_scaling_matrix`, containing H264
-	scaling matrices for stateless video decoders.
-    * - ``V4L2_CTRL_TYPE_H264_SLICE_PARAMS``
-      - n/a
-      - n/a
-      - n/a
-      - A struct :c:type:`v4l2_ctrl_h264_slice_params`, containing H264
-	slice parameters for stateless video decoders.
-    * - ``V4L2_CTRL_TYPE_H264_DECODE_PARAMS``
-      - n/a
-      - n/a
-      - n/a
-      - A struct :c:type:`v4l2_ctrl_h264_decode_params`, containing H264
-	decode parameters for stateless video decoders.
-    * - ``V4L2_CTRL_TYPE_HEVC_SPS``
-      - n/a
-      - n/a
-      - n/a
-      - A struct :c:type:`v4l2_ctrl_hevc_sps`, containing HEVC Sequence
-	Parameter Set for stateless video decoders.
-    * - ``V4L2_CTRL_TYPE_HEVC_PPS``
-      - n/a
-      - n/a
-      - n/a
-      - A struct :c:type:`v4l2_ctrl_hevc_pps`, containing HEVC Picture
-	Parameter Set for stateless video decoders.
-    * - ``V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS``
-      - n/a
-      - n/a
-      - n/a
-      - A struct :c:type:`v4l2_ctrl_hevc_slice_params`, containing HEVC
-	slice parameters for stateless video decoders.
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. _control-flags:
-
-.. cssclass:: longtable
-
-.. flat-table:: Control Flags
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_CTRL_FLAG_DISABLED``
-      - 0x0001
-      - This control is permanently disabled and should be ignored by the
-	application. Any attempt to change the control will result in an
-	``EINVAL`` error code.
-    * - ``V4L2_CTRL_FLAG_GRABBED``
-      - 0x0002
-      - This control is temporarily unchangeable, for example because
-	another application took over control of the respective resource.
-	Such controls may be displayed specially in a user interface.
-	Attempts to change the control may result in an ``EBUSY`` error code.
-    * - ``V4L2_CTRL_FLAG_READ_ONLY``
-      - 0x0004
-      - This control is permanently readable only. Any attempt to change
-	the control will result in an ``EINVAL`` error code.
-    * - ``V4L2_CTRL_FLAG_UPDATE``
-      - 0x0008
-      - A hint that changing this control may affect the value of other
-	controls within the same control class. Applications should update
-	their user interface accordingly.
-    * - ``V4L2_CTRL_FLAG_INACTIVE``
-      - 0x0010
-      - This control is not applicable to the current configuration and
-	should be displayed accordingly in a user interface. For example
-	the flag may be set on a MPEG audio level 2 bitrate control when
-	MPEG audio encoding level 1 was selected with another control.
-    * - ``V4L2_CTRL_FLAG_SLIDER``
-      - 0x0020
-      - A hint that this control is best represented as a slider-like
-	element in a user interface.
-    * - ``V4L2_CTRL_FLAG_WRITE_ONLY``
-      - 0x0040
-      - This control is permanently writable only. Any attempt to read the
-	control will result in an ``EACCES`` error code error code. This flag
-	is typically present for relative controls or action controls
-	where writing a value will cause the device to carry out a given
-	action (e. g. motor control) but no meaningful value can be
-	returned.
-    * - ``V4L2_CTRL_FLAG_VOLATILE``
-      - 0x0080
-      - This control is volatile, which means that the value of the
-	control changes continuously. A typical example would be the
-	current gain value if the device is in auto-gain mode. In such a
-	case the hardware calculates the gain value based on the lighting
-	conditions which can change over time.
-
-	.. note::
-
-	   Setting a new value for a volatile control will be ignored
-	   unless
-	   :ref:`V4L2_CTRL_FLAG_EXECUTE_ON_WRITE <FLAG_EXECUTE_ON_WRITE>`
-	   is also set.
-	   Setting a new value for a volatile control will *never* trigger a
-	   :ref:`V4L2_EVENT_CTRL_CH_VALUE <ctrl-changes-flags>` event.
-    * - ``V4L2_CTRL_FLAG_HAS_PAYLOAD``
-      - 0x0100
-      - This control has a pointer type, so its value has to be accessed
-	using one of the pointer fields of struct
-	:c:type:`v4l2_ext_control`. This flag is set
-	for controls that are an array, string, or have a compound type.
-	In all cases you have to set a pointer to memory containing the
-	payload of the control.
-    * .. _FLAG_EXECUTE_ON_WRITE:
-
-      - ``V4L2_CTRL_FLAG_EXECUTE_ON_WRITE``
-      - 0x0200
-      - The value provided to the control will be propagated to the driver
-	even if it remains constant. This is required when the control
-	represents an action on the hardware. For example: clearing an
-	error flag or triggering the flash. All the controls of the type
-	``V4L2_CTRL_TYPE_BUTTON`` have this flag set.
-    * .. _FLAG_MODIFY_LAYOUT:
-
-      - ``V4L2_CTRL_FLAG_MODIFY_LAYOUT``
-      - 0x0400
-      - Changing this control value may modify the layout of the
-        buffer (for video devices) or the media bus format (for sub-devices).
-
-	A typical example would be the ``V4L2_CID_ROTATE`` control.
-
-	Note that typically controls with this flag will also set the
-	``V4L2_CTRL_FLAG_GRABBED`` flag when buffers are allocated or
-	streaming is in progress since most drivers do not support changing
-	the format in that case.
-
-
-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
-    The struct :ref:`v4l2_queryctrl <v4l2-queryctrl>` ``id`` is
-    invalid. The struct :ref:`v4l2_querymenu <v4l2-querymenu>` ``id``
-    is invalid or ``index`` is out of range (less than ``minimum`` or
-    greater than ``maximum``) or this particular menu item is not
-    supported by the driver.
-
-EACCES
-    An attempt was made to read a write-only control.
-
-.. [#f1]
-   ``V4L2_CTRL_FLAG_DISABLED`` was intended for two purposes: Drivers
-   can skip predefined controls not supported by the hardware (although
-   returning ``EINVAL`` would do as well), or disable predefined and private
-   controls after hardware detection without the trouble of reordering
-   control arrays and indices (``EINVAL`` cannot be used to skip private
-   controls because it would prematurely end the enumeration).
diff --git a/Documentation/media/uapi/v4l/vidioc-querystd.rst b/Documentation/media/uapi/v4l/vidioc-querystd.rst
deleted file mode 100644
index d8cf28274cfc..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-querystd.rst
+++ /dev/null
@@ -1,77 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_QUERYSTD:
-
-*********************************************
-ioctl VIDIOC_QUERYSTD, VIDIOC_SUBDEV_QUERYSTD
-*********************************************
-
-Name
-====
-
-VIDIOC_QUERYSTD - VIDIOC_SUBDEV_QUERYSTD - Sense the video standard received by the current input
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_QUERYSTD, v4l2_std_id *argp )
-    :name: VIDIOC_QUERYSTD
-
-.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_QUERYSTD, v4l2_std_id *argp )
-    :name: VIDIOC_SUBDEV_QUERYSTD
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to :c:type:`v4l2_std_id`.
-
-
-Description
-===========
-
-The hardware may be able to detect the current video standard
-automatically. To do so, applications call :ref:`VIDIOC_QUERYSTD` with a
-pointer to a :ref:`v4l2_std_id <v4l2-std-id>` type. The driver
-stores here a set of candidates, this can be a single flag or a set of
-supported standards if for example the hardware can only distinguish
-between 50 and 60 Hz systems. If no signal was detected, then the driver
-will return V4L2_STD_UNKNOWN. When detection is not possible or fails,
-the set must contain all standards supported by the current video input
-or output.
-
-.. note::
-
-   Drivers shall *not* switch the video standard
-   automatically if a new video standard is detected. Instead, drivers
-   should send the ``V4L2_EVENT_SOURCE_CHANGE`` event (if they support
-   this) and expect that userspace will take action by calling
-   :ref:`VIDIOC_QUERYSTD`. The reason is that a new video standard can mean
-   different buffer sizes as well, and you cannot change buffer sizes on
-   the fly. In general, applications that receive the Source Change event
-   will have to call :ref:`VIDIOC_QUERYSTD`, and if the detected video
-   standard is valid they will have to stop streaming, set the new
-   standard, allocate new buffers and start streaming again.
-
-
-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.
-
-ENODATA
-    Standard video timings are not supported for this input or output.
diff --git a/Documentation/media/uapi/v4l/vidioc-reqbufs.rst b/Documentation/media/uapi/v4l/vidioc-reqbufs.rst
deleted file mode 100644
index d0c643db477a..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-reqbufs.rst
+++ /dev/null
@@ -1,169 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_REQBUFS:
-
-********************
-ioctl VIDIOC_REQBUFS
-********************
-
-Name
-====
-
-VIDIOC_REQBUFS - Initiate Memory Mapping, User Pointer I/O or DMA buffer I/O
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_REQBUFS, struct v4l2_requestbuffers *argp )
-    :name: VIDIOC_REQBUFS
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_requestbuffers`.
-
-Description
-===========
-
-This ioctl is used to initiate :ref:`memory mapped <mmap>`,
-:ref:`user pointer <userp>` or :ref:`DMABUF <dmabuf>` based 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:`v4l2_requestbuffers` structure. They set the ``type``
-field to the respective stream or buffer type, the ``count`` field to
-the desired number of buffers, ``memory`` must be set to the requested
-I/O method and the ``reserved`` array must be zeroed. 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. It 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. For example video output requires at least two
-buffers, one displayed and one filled by the application.
-
-When the I/O method is not supported the ioctl returns an ``EINVAL`` error
-code.
-
-Applications can call :ref:`VIDIOC_REQBUFS` again to change the number of
-buffers. Note that if any buffers are still mapped or exported via DMABUF,
-then :ref:`VIDIOC_REQBUFS` can only succeed if the
-``V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS`` capability is set. Otherwise
-:ref:`VIDIOC_REQBUFS` will return the ``EBUSY`` error code.
-If ``V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS`` is set, then these buffers are
-orphaned and will be freed when they are unmapped or when the exported DMABUF
-fds are closed. A ``count`` value of zero frees or orphans all buffers, after
-aborting or finishing any DMA in progress, an implicit
-:ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>`.
-
-
-.. c:type:: v4l2_requestbuffers
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. flat-table:: struct v4l2_requestbuffers
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``count``
-      - The number of buffers requested or granted.
-    * - __u32
-      - ``type``
-      - Type of the stream or buffers, this is the same as the struct
-	:c:type:`v4l2_format` ``type`` field. See
-	:c:type:`v4l2_buf_type` for valid values.
-    * - __u32
-      - ``memory``
-      - Applications set this field to ``V4L2_MEMORY_MMAP``,
-	``V4L2_MEMORY_DMABUF`` or ``V4L2_MEMORY_USERPTR``. See
-	:c:type:`v4l2_memory`.
-    * - __u32
-      - ``capabilities``
-      - Set by the driver. If 0, then the driver doesn't support
-        capabilities. In that case all you know is that the driver is
-	guaranteed to support ``V4L2_MEMORY_MMAP`` and *might* support
-	other :c:type:`v4l2_memory` types. It will not support any others
-	capabilities.
-
-	If you want to query the capabilities with a minimum of side-effects,
-	then this can be called with ``count`` set to 0, ``memory`` set to
-	``V4L2_MEMORY_MMAP`` and ``type`` set to the buffer type. This will
-	free any previously allocated buffers, so this is typically something
-	that will be done at the start of the application.
-    * - __u32
-      - ``reserved``\ [1]
-      - A place holder for future extensions. Drivers and applications
-	must set the array to zero.
-
-.. tabularcolumns:: |p{6.1cm}|p{2.2cm}|p{8.7cm}|
-
-.. _v4l2-buf-capabilities:
-.. _V4L2-BUF-CAP-SUPPORTS-MMAP:
-.. _V4L2-BUF-CAP-SUPPORTS-USERPTR:
-.. _V4L2-BUF-CAP-SUPPORTS-DMABUF:
-.. _V4L2-BUF-CAP-SUPPORTS-REQUESTS:
-.. _V4L2-BUF-CAP-SUPPORTS-ORPHANED-BUFS:
-.. _V4L2-BUF-CAP-SUPPORTS-M2M-HOLD-CAPTURE-BUF:
-
-.. cssclass:: longtable
-
-.. flat-table:: V4L2 Buffer Capabilities Flags
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_BUF_CAP_SUPPORTS_MMAP``
-      - 0x00000001
-      - This buffer type supports the ``V4L2_MEMORY_MMAP`` streaming mode.
-    * - ``V4L2_BUF_CAP_SUPPORTS_USERPTR``
-      - 0x00000002
-      - This buffer type supports the ``V4L2_MEMORY_USERPTR`` streaming mode.
-    * - ``V4L2_BUF_CAP_SUPPORTS_DMABUF``
-      - 0x00000004
-      - This buffer type supports the ``V4L2_MEMORY_DMABUF`` streaming mode.
-    * - ``V4L2_BUF_CAP_SUPPORTS_REQUESTS``
-      - 0x00000008
-      - This buffer type supports :ref:`requests <media-request-api>`.
-    * - ``V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS``
-      - 0x00000010
-      - The kernel allows calling :ref:`VIDIOC_REQBUFS` while buffers are still
-        mapped or exported via DMABUF. These orphaned buffers will be freed
-        when they are unmapped or when the exported DMABUF fds are closed.
-    * - ``V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF``
-      - 0x00000020
-      - Only valid for stateless decoders. If set, then userspace can set the
-        ``V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF`` flag to hold off on returning the
-	capture buffer until the OUTPUT timestamp changes.
-
-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
-    The buffer type (``type`` field) or the requested I/O method
-    (``memory``) is not supported.
diff --git a/Documentation/media/uapi/v4l/vidioc-s-hw-freq-seek.rst b/Documentation/media/uapi/v4l/vidioc-s-hw-freq-seek.rst
deleted file mode 100644
index 4daec97651f2..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-s-hw-freq-seek.rst
+++ /dev/null
@@ -1,147 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_S_HW_FREQ_SEEK:
-
-***************************
-ioctl VIDIOC_S_HW_FREQ_SEEK
-***************************
-
-Name
-====
-
-VIDIOC_S_HW_FREQ_SEEK - Perform a hardware frequency seek
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_S_HW_FREQ_SEEK, struct v4l2_hw_freq_seek *argp )
-    :name: VIDIOC_S_HW_FREQ_SEEK
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_hw_freq_seek`.
-
-
-Description
-===========
-
-Start a hardware frequency seek from the current frequency. To do this
-applications initialize the ``tuner``, ``type``, ``seek_upward``,
-``wrap_around``, ``spacing``, ``rangelow`` and ``rangehigh`` fields, and
-zero out the ``reserved`` array of a struct
-:c:type:`v4l2_hw_freq_seek` and call the
-``VIDIOC_S_HW_FREQ_SEEK`` ioctl with a pointer to this structure.
-
-The ``rangelow`` and ``rangehigh`` fields can be set to a non-zero value
-to tell the driver to search a specific band. If the struct
-:c:type:`v4l2_tuner` ``capability`` field has the
-``V4L2_TUNER_CAP_HWSEEK_PROG_LIM`` flag set, these values must fall
-within one of the bands returned by
-:ref:`VIDIOC_ENUM_FREQ_BANDS`. If the
-``V4L2_TUNER_CAP_HWSEEK_PROG_LIM`` flag is not set, then these values
-must exactly match those of one of the bands returned by
-:ref:`VIDIOC_ENUM_FREQ_BANDS`. If the
-current frequency of the tuner does not fall within the selected band it
-will be clamped to fit in the band before the seek is started.
-
-If an error is returned, then the original frequency will be restored.
-
-This ioctl is supported if the ``V4L2_CAP_HW_FREQ_SEEK`` capability is
-set.
-
-If this ioctl is called from a non-blocking filehandle, then ``EAGAIN``
-error code is returned and no seek takes place.
-
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. c:type:: v4l2_hw_freq_seek
-
-.. flat-table:: struct v4l2_hw_freq_seek
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``tuner``
-      - The tuner index number. This is the same value as in the struct
-	:c:type:`v4l2_input` ``tuner`` field and the struct
-	:c:type:`v4l2_tuner` ``index`` field.
-    * - __u32
-      - ``type``
-      - The tuner type. This is the same value as in the struct
-	:c:type:`v4l2_tuner` ``type`` field. See
-	:c:type:`v4l2_tuner_type`
-    * - __u32
-      - ``seek_upward``
-      - If non-zero, seek upward from the current frequency, else seek
-	downward.
-    * - __u32
-      - ``wrap_around``
-      - If non-zero, wrap around when at the end of the frequency range,
-	else stop seeking. The struct :c:type:`v4l2_tuner`
-	``capability`` field will tell you what the hardware supports.
-    * - __u32
-      - ``spacing``
-      - If non-zero, defines the hardware seek resolution in Hz. The
-	driver selects the nearest value that is supported by the device.
-	If spacing is zero a reasonable default value is used.
-    * - __u32
-      - ``rangelow``
-      - If non-zero, the lowest tunable frequency of the band to search in
-	units of 62.5 kHz, or if the struct
-	:c:type:`v4l2_tuner` ``capability`` field has the
-	``V4L2_TUNER_CAP_LOW`` flag set, in units of 62.5 Hz or if the
-	struct :c:type:`v4l2_tuner` ``capability`` field has
-	the ``V4L2_TUNER_CAP_1HZ`` flag set, in units of 1 Hz. If
-	``rangelow`` is zero a reasonable default value is used.
-    * - __u32
-      - ``rangehigh``
-      - If non-zero, the highest tunable frequency of the band to search
-	in units of 62.5 kHz, or if the struct
-	:c:type:`v4l2_tuner` ``capability`` field has the
-	``V4L2_TUNER_CAP_LOW`` flag set, in units of 62.5 Hz or if the
-	struct :c:type:`v4l2_tuner` ``capability`` field has
-	the ``V4L2_TUNER_CAP_1HZ`` flag set, in units of 1 Hz. If
-	``rangehigh`` is zero a reasonable default value is used.
-    * - __u32
-      - ``reserved``\ [5]
-      - Reserved for future extensions. Applications must set the array to
-	zero.
-
-
-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
-    The ``tuner`` index is out of bounds, the ``wrap_around`` value is
-    not supported or one of the values in the ``type``, ``rangelow`` or
-    ``rangehigh`` fields is wrong.
-
-EAGAIN
-    Attempted to call ``VIDIOC_S_HW_FREQ_SEEK`` with the filehandle in
-    non-blocking mode.
-
-ENODATA
-    The hardware seek found no channels.
-
-EBUSY
-    Another hardware seek is already in progress.
diff --git a/Documentation/media/uapi/v4l/vidioc-streamon.rst b/Documentation/media/uapi/v4l/vidioc-streamon.rst
deleted file mode 100644
index 2b5528ec9f89..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-streamon.rst
+++ /dev/null
@@ -1,113 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_STREAMON:
-
-***************************************
-ioctl VIDIOC_STREAMON, VIDIOC_STREAMOFF
-***************************************
-
-Name
-====
-
-VIDIOC_STREAMON - VIDIOC_STREAMOFF - Start or stop streaming I/O
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_STREAMON, const int *argp )
-    :name: VIDIOC_STREAMON
-
-.. c:function:: int ioctl( int fd, VIDIOC_STREAMOFF, const int *argp )
-    :name: VIDIOC_STREAMOFF
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to an integer.
-
-Description
-===========
-
-The ``VIDIOC_STREAMON`` and ``VIDIOC_STREAMOFF`` ioctl start and stop
-the capture or output process during streaming
-(:ref:`memory mapping <mmap>`, :ref:`user pointer <userp>` or
-:ref:`DMABUF <dmabuf>`) I/O.
-
-Capture hardware is disabled and no input buffers are filled (if there
-are any empty buffers in the incoming queue) until ``VIDIOC_STREAMON``
-has been called. Output hardware is disabled and no video signal is
-produced until ``VIDIOC_STREAMON`` has been called. The ioctl will
-succeed when at least one output buffer is in the incoming queue.
-
-Memory-to-memory devices will not start until ``VIDIOC_STREAMON`` has
-been called for both the capture and output stream types.
-
-If ``VIDIOC_STREAMON`` fails then any already queued buffers will remain
-queued.
-
-The ``VIDIOC_STREAMOFF`` ioctl, apart of aborting or finishing any DMA
-in progress, unlocks any user pointer buffers locked in physical memory,
-and it removes all buffers from the incoming and outgoing queues. That
-means all images captured but not dequeued yet will be lost, likewise
-all images enqueued for output but not transmitted yet. I/O returns to
-the same state as after calling
-:ref:`VIDIOC_REQBUFS` and can be restarted
-accordingly.
-
-If buffers have been queued with :ref:`VIDIOC_QBUF` and
-``VIDIOC_STREAMOFF`` is called without ever having called
-``VIDIOC_STREAMON``, then those queued buffers will also be removed from
-the incoming queue and all are returned to the same state as after
-calling :ref:`VIDIOC_REQBUFS` and can be restarted
-accordingly.
-
-Both ioctls take a pointer to an integer, the desired buffer or stream
-type. This is the same as struct
-:c:type:`v4l2_requestbuffers` ``type``.
-
-If ``VIDIOC_STREAMON`` is called when streaming is already in progress,
-or if ``VIDIOC_STREAMOFF`` is called when streaming is already stopped,
-then 0 is returned. Nothing happens in the case of ``VIDIOC_STREAMON``,
-but ``VIDIOC_STREAMOFF`` will return queued buffers to their starting
-state as mentioned above.
-
-.. note::
-
-   Applications can be preempted for unknown periods right before
-   or after the ``VIDIOC_STREAMON`` or ``VIDIOC_STREAMOFF`` calls, there is
-   no notion of starting or stopping "now". Buffer timestamps can be used
-   to synchronize with other events.
-
-
-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
-    The buffer ``type`` is not supported, or no buffers have been
-    allocated (memory mapping) or enqueued (output) yet.
-
-EPIPE
-    The driver implements
-    :ref:`pad-level format configuration <pad-level-formats>` and the
-    pipeline configuration is invalid.
-
-ENOLINK
-    The driver implements Media Controller interface and the pipeline
-    link configuration is invalid.
diff --git a/Documentation/media/uapi/v4l/vidioc-subdev-enum-frame-interval.rst b/Documentation/media/uapi/v4l/vidioc-subdev-enum-frame-interval.rst
deleted file mode 100644
index 6b4bf9ef5606..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-subdev-enum-frame-interval.rst
+++ /dev/null
@@ -1,120 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL:
-
-***************************************
-ioctl VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL
-***************************************
-
-Name
-====
-
-VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL - Enumerate frame intervals
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL, struct v4l2_subdev_frame_interval_enum * argp )
-    :name: VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_subdev_frame_interval_enum`.
-
-
-Description
-===========
-
-This ioctl lets applications enumerate available frame intervals on a
-given sub-device pad. Frame intervals only makes sense for sub-devices
-that can control the frame period on their own. This includes, for
-instance, image sensors and TV tuners.
-
-For the common use case of image sensors, the frame intervals available
-on the sub-device output pad depend on the frame format and size on the
-same pad. Applications must thus specify the desired format and size
-when enumerating frame intervals.
-
-To enumerate frame intervals applications initialize the ``index``,
-``pad``, ``which``, ``code``, ``width`` and ``height`` fields of struct
-:c:type:`v4l2_subdev_frame_interval_enum`
-and call the :ref:`VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL` ioctl with a pointer
-to this structure. Drivers fill the rest of the structure or return an
-EINVAL error code if one of the input fields is invalid. All frame
-intervals are enumerable by beginning at index zero and incrementing by
-one until ``EINVAL`` is returned.
-
-Available frame intervals may depend on the current 'try' formats at
-other pads of the sub-device, as well as on the current active links.
-See :ref:`VIDIOC_SUBDEV_G_FMT` for more
-information about the try formats.
-
-Sub-devices that support the frame interval enumeration ioctl should
-implemented it on a single pad only. Its behaviour when supported on
-multiple pads of the same sub-device is not defined.
-
-.. c:type:: v4l2_subdev_frame_interval_enum
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. flat-table:: struct v4l2_subdev_frame_interval_enum
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``index``
-      - Number of the format in the enumeration, set by the application.
-    * - __u32
-      - ``pad``
-      - Pad number as reported by the media controller API.
-    * - __u32
-      - ``code``
-      - The media bus format code, as defined in
-	:ref:`v4l2-mbus-format`.
-    * - __u32
-      - ``width``
-      - Frame width, in pixels.
-    * - __u32
-      - ``height``
-      - Frame height, in pixels.
-    * - struct :c:type:`v4l2_fract`
-      - ``interval``
-      - Period, in seconds, between consecutive video frames.
-    * - __u32
-      - ``which``
-      - Frame intervals to be enumerated, from enum
-	:ref:`v4l2_subdev_format_whence <v4l2-subdev-format-whence>`.
-    * - __u32
-      - ``reserved``\ [8]
-      - Reserved for future extensions. Applications and drivers must set
-	the array to zero.
-
-
-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
-    The struct
-    :c:type:`v4l2_subdev_frame_interval_enum`
-    ``pad`` references a non-existing pad, one of the ``code``,
-    ``width`` or ``height`` fields are invalid for the given pad or the
-    ``index`` field is out of bounds.
diff --git a/Documentation/media/uapi/v4l/vidioc-subdev-enum-frame-size.rst b/Documentation/media/uapi/v4l/vidioc-subdev-enum-frame-size.rst
deleted file mode 100644
index 253b128b194e..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-subdev-enum-frame-size.rst
+++ /dev/null
@@ -1,125 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_SUBDEV_ENUM_FRAME_SIZE:
-
-***********************************
-ioctl VIDIOC_SUBDEV_ENUM_FRAME_SIZE
-***********************************
-
-Name
-====
-
-VIDIOC_SUBDEV_ENUM_FRAME_SIZE - Enumerate media bus frame sizes
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_ENUM_FRAME_SIZE, struct v4l2_subdev_frame_size_enum * argp )
-    :name: VIDIOC_SUBDEV_ENUM_FRAME_SIZE
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_subdev_frame_size_enum`.
-
-
-Description
-===========
-
-This ioctl allows applications to enumerate all frame sizes supported by
-a sub-device on the given pad for the given media bus format. Supported
-formats can be retrieved with the
-:ref:`VIDIOC_SUBDEV_ENUM_MBUS_CODE`
-ioctl.
-
-To enumerate frame sizes applications initialize the ``pad``, ``which``
-, ``code`` and ``index`` fields of the struct
-:c:type:`v4l2_subdev_mbus_code_enum` and
-call the :ref:`VIDIOC_SUBDEV_ENUM_FRAME_SIZE` ioctl with a pointer to the
-structure. Drivers fill the minimum and maximum frame sizes or return an
-EINVAL error code if one of the input parameters is invalid.
-
-Sub-devices that only support discrete frame sizes (such as most
-sensors) will return one or more frame sizes with identical minimum and
-maximum values.
-
-Not all possible sizes in given [minimum, maximum] ranges need to be
-supported. For instance, a scaler that uses a fixed-point scaling ratio
-might not be able to produce every frame size between the minimum and
-maximum values. Applications must use the
-:ref:`VIDIOC_SUBDEV_S_FMT <VIDIOC_SUBDEV_G_FMT>` ioctl to try the
-sub-device for an exact supported frame size.
-
-Available frame sizes may depend on the current 'try' formats at other
-pads of the sub-device, as well as on the current active links and the
-current values of V4L2 controls. See
-:ref:`VIDIOC_SUBDEV_G_FMT` for more
-information about try formats.
-
-
-.. c:type:: v4l2_subdev_frame_size_enum
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. flat-table:: struct v4l2_subdev_frame_size_enum
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``index``
-      - Number of the format in the enumeration, set by the application.
-    * - __u32
-      - ``pad``
-      - Pad number as reported by the media controller API.
-    * - __u32
-      - ``code``
-      - The media bus format code, as defined in
-	:ref:`v4l2-mbus-format`.
-    * - __u32
-      - ``min_width``
-      - Minimum frame width, in pixels.
-    * - __u32
-      - ``max_width``
-      - Maximum frame width, in pixels.
-    * - __u32
-      - ``min_height``
-      - Minimum frame height, in pixels.
-    * - __u32
-      - ``max_height``
-      - Maximum frame height, in pixels.
-    * - __u32
-      - ``which``
-      - Frame sizes to be enumerated, from enum
-	:ref:`v4l2_subdev_format_whence <v4l2-subdev-format-whence>`.
-    * - __u32
-      - ``reserved``\ [8]
-      - Reserved for future extensions. Applications and drivers must set
-	the array to zero.
-
-
-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
-    The struct
-    :c:type:`v4l2_subdev_frame_size_enum`
-    ``pad`` references a non-existing pad, the ``code`` is invalid for
-    the given pad or the ``index`` field is out of bounds.
diff --git a/Documentation/media/uapi/v4l/vidioc-subdev-enum-mbus-code.rst b/Documentation/media/uapi/v4l/vidioc-subdev-enum-mbus-code.rst
deleted file mode 100644
index fefe4d7349ee..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-subdev-enum-mbus-code.rst
+++ /dev/null
@@ -1,98 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_SUBDEV_ENUM_MBUS_CODE:
-
-**********************************
-ioctl VIDIOC_SUBDEV_ENUM_MBUS_CODE
-**********************************
-
-Name
-====
-
-VIDIOC_SUBDEV_ENUM_MBUS_CODE - Enumerate media bus formats
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_ENUM_MBUS_CODE, struct v4l2_subdev_mbus_code_enum * argp )
-    :name: VIDIOC_SUBDEV_ENUM_MBUS_CODE
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_subdev_mbus_code_enum`.
-
-
-Description
-===========
-
-To enumerate media bus formats available at a given sub-device pad
-applications initialize the ``pad``, ``which`` and ``index`` fields of
-struct
-:c:type:`v4l2_subdev_mbus_code_enum` and
-call the :ref:`VIDIOC_SUBDEV_ENUM_MBUS_CODE` ioctl with a pointer to this
-structure. Drivers fill the rest of the structure or return an ``EINVAL``
-error code if either the ``pad`` or ``index`` are invalid. All media bus
-formats are enumerable by beginning at index zero and incrementing by
-one until ``EINVAL`` is returned.
-
-Available media bus formats may depend on the current 'try' formats at
-other pads of the sub-device, as well as on the current active links.
-See :ref:`VIDIOC_SUBDEV_G_FMT` for more
-information about the try formats.
-
-
-.. c:type:: v4l2_subdev_mbus_code_enum
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. flat-table:: struct v4l2_subdev_mbus_code_enum
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``pad``
-      - Pad number as reported by the media controller API.
-    * - __u32
-      - ``index``
-      - Number of the format in the enumeration, set by the application.
-    * - __u32
-      - ``code``
-      - The media bus format code, as defined in
-	:ref:`v4l2-mbus-format`.
-    * - __u32
-      - ``which``
-      - Media bus format codes to be enumerated, from enum
-	:ref:`v4l2_subdev_format_whence <v4l2-subdev-format-whence>`.
-    * - __u32
-      - ``reserved``\ [8]
-      - Reserved for future extensions. Applications and drivers must set
-	the array to zero.
-
-
-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
-    The struct
-    :c:type:`v4l2_subdev_mbus_code_enum`
-    ``pad`` references a non-existing pad, or the ``index`` field is out
-    of bounds.
diff --git a/Documentation/media/uapi/v4l/vidioc-subdev-g-crop.rst b/Documentation/media/uapi/v4l/vidioc-subdev-g-crop.rst
deleted file mode 100644
index 632ee053accc..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-subdev-g-crop.rst
+++ /dev/null
@@ -1,125 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_SUBDEV_G_CROP:
-
-************************************************
-ioctl VIDIOC_SUBDEV_G_CROP, VIDIOC_SUBDEV_S_CROP
-************************************************
-
-Name
-====
-
-VIDIOC_SUBDEV_G_CROP - VIDIOC_SUBDEV_S_CROP - Get or set the crop rectangle on a subdev pad
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_G_CROP, struct v4l2_subdev_crop *argp )
-    :name: VIDIOC_SUBDEV_G_CROP
-
-.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_S_CROP, const struct v4l2_subdev_crop *argp )
-    :name: VIDIOC_SUBDEV_S_CROP
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_subdev_crop`.
-
-
-Description
-===========
-
-.. note::
-
-    This is an :ref:`obsolete` interface and may be removed
-    in the future. It is superseded by
-    :ref:`the selection API <VIDIOC_SUBDEV_G_SELECTION>`.
-
-To retrieve the current crop rectangle applications set the ``pad``
-field of a struct :c:type:`v4l2_subdev_crop` to the
-desired pad number as reported by the media API and the ``which`` field
-to ``V4L2_SUBDEV_FORMAT_ACTIVE``. They then call the
-``VIDIOC_SUBDEV_G_CROP`` ioctl with a pointer to this structure. The
-driver fills the members of the ``rect`` field or returns ``EINVAL`` error
-code if the input arguments are invalid, or if cropping is not supported
-on the given pad.
-
-To change the current crop rectangle applications set both the ``pad``
-and ``which`` fields and all members of the ``rect`` field. They then
-call the ``VIDIOC_SUBDEV_S_CROP`` ioctl with a pointer to this
-structure. The driver verifies the requested crop rectangle, adjusts it
-based on the hardware capabilities and configures the device. Upon
-return the struct :c:type:`v4l2_subdev_crop`
-contains the current format as would be returned by a
-``VIDIOC_SUBDEV_G_CROP`` call.
-
-Applications can query the device capabilities by setting the ``which``
-to ``V4L2_SUBDEV_FORMAT_TRY``. When set, 'try' crop rectangles are not
-applied to the device by the driver, but are mangled exactly as active
-crop rectangles and stored in the sub-device file handle. Two
-applications querying the same sub-device would thus not interact with
-each other.
-
-Drivers must not return an error solely because the requested crop
-rectangle doesn't match the device capabilities. They must instead
-modify the rectangle to match what the hardware can provide. The
-modified format should be as close as possible to the original request.
-
-
-.. c:type:: v4l2_subdev_crop
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. flat-table:: struct v4l2_subdev_crop
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``pad``
-      - Pad number as reported by the media framework.
-    * - __u32
-      - ``which``
-      - Crop rectangle to get or set, from enum
-	:ref:`v4l2_subdev_format_whence <v4l2-subdev-format-whence>`.
-    * - struct :c:type:`v4l2_rect`
-      - ``rect``
-      - Crop rectangle boundaries, in pixels.
-    * - __u32
-      - ``reserved``\ [8]
-      - Reserved for future extensions. Applications and drivers must set
-	the array to zero.
-
-
-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.
-
-EBUSY
-    The crop rectangle can't be changed because the pad is currently
-    busy. This can be caused, for instance, by an active video stream on
-    the pad. The ioctl must not be retried without performing another
-    action to fix the problem first. Only returned by
-    ``VIDIOC_SUBDEV_S_CROP``
-
-EINVAL
-    The struct :c:type:`v4l2_subdev_crop` ``pad``
-    references a non-existing pad, the ``which`` field references a
-    non-existing format, or cropping is not supported on the given
-    subdev pad.
diff --git a/Documentation/media/uapi/v4l/vidioc-subdev-g-fmt.rst b/Documentation/media/uapi/v4l/vidioc-subdev-g-fmt.rst
deleted file mode 100644
index 472577bd1745..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-subdev-g-fmt.rst
+++ /dev/null
@@ -1,154 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_SUBDEV_G_FMT:
-
-**********************************************
-ioctl VIDIOC_SUBDEV_G_FMT, VIDIOC_SUBDEV_S_FMT
-**********************************************
-
-Name
-====
-
-VIDIOC_SUBDEV_G_FMT - VIDIOC_SUBDEV_S_FMT - Get or set the data format on a subdev pad
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_G_FMT, struct v4l2_subdev_format *argp )
-    :name: VIDIOC_SUBDEV_G_FMT
-
-.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_S_FMT, struct v4l2_subdev_format *argp )
-    :name: VIDIOC_SUBDEV_S_FMT
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_subdev_format`.
-
-
-Description
-===========
-
-These ioctls are used to negotiate the frame format at specific subdev
-pads in the image pipeline.
-
-To retrieve the current format applications set the ``pad`` field of a
-struct :c:type:`v4l2_subdev_format` to the desired
-pad number as reported by the media API and the ``which`` field to
-``V4L2_SUBDEV_FORMAT_ACTIVE``. When they call the
-``VIDIOC_SUBDEV_G_FMT`` ioctl with a pointer to this structure the
-driver fills the members of the ``format`` field.
-
-To change the current format applications set both the ``pad`` and
-``which`` fields and all members of the ``format`` field. When they call
-the ``VIDIOC_SUBDEV_S_FMT`` ioctl with a pointer to this structure the
-driver verifies the requested format, adjusts it based on the hardware
-capabilities and configures the device. Upon return the struct
-:c:type:`v4l2_subdev_format` contains the current
-format as would be returned by a ``VIDIOC_SUBDEV_G_FMT`` call.
-
-Applications can query the device capabilities by setting the ``which``
-to ``V4L2_SUBDEV_FORMAT_TRY``. When set, 'try' formats are not applied
-to the device by the driver, but are changed exactly as active formats
-and stored in the sub-device file handle. Two applications querying the
-same sub-device would thus not interact with each other.
-
-For instance, to try a format at the output pad of a sub-device,
-applications would first set the try format at the sub-device input with
-the ``VIDIOC_SUBDEV_S_FMT`` ioctl. They would then either retrieve the
-default format at the output pad with the ``VIDIOC_SUBDEV_G_FMT`` ioctl,
-or set the desired output pad format with the ``VIDIOC_SUBDEV_S_FMT``
-ioctl and check the returned value.
-
-Try formats do not depend on active formats, but can depend on the
-current links configuration or sub-device controls value. For instance,
-a low-pass noise filter might crop pixels at the frame boundaries,
-modifying its output frame size.
-
-Drivers must not return an error solely because the requested format
-doesn't match the device capabilities. They must instead modify the
-format to match what the hardware can provide. The modified format
-should be as close as possible to the original request.
-
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. c:type:: v4l2_subdev_format
-
-.. flat-table:: struct v4l2_subdev_format
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``pad``
-      - Pad number as reported by the media controller API.
-    * - __u32
-      - ``which``
-      - Format to modified, from enum
-	:ref:`v4l2_subdev_format_whence <v4l2-subdev-format-whence>`.
-    * - struct :c:type:`v4l2_mbus_framefmt`
-      - ``format``
-      - Definition of an image format, see :c:type:`v4l2_mbus_framefmt` for
-	details.
-    * - __u32
-      - ``reserved``\ [8]
-      - Reserved for future extensions. Applications and drivers must set
-	the array to zero.
-
-
-
-.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
-
-.. _v4l2-subdev-format-whence:
-
-.. flat-table:: enum v4l2_subdev_format_whence
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - V4L2_SUBDEV_FORMAT_TRY
-      - 0
-      - Try formats, used for querying device capabilities.
-    * - V4L2_SUBDEV_FORMAT_ACTIVE
-      - 1
-      - Active formats, applied to the hardware.
-
-
-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.
-
-EBUSY
-    The format can't be changed because the pad is currently busy. This
-    can be caused, for instance, by an active video stream on the pad.
-    The ioctl must not be retried without performing another action to
-    fix the problem first. Only returned by ``VIDIOC_SUBDEV_S_FMT``
-
-EINVAL
-    The struct :c:type:`v4l2_subdev_format`
-    ``pad`` references a non-existing pad, or the ``which`` field
-    references a non-existing format.
-
-
-============
-
-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/v4l/vidioc-subdev-g-frame-interval.rst b/Documentation/media/uapi/v4l/vidioc-subdev-g-frame-interval.rst
deleted file mode 100644
index 4b1b4bc78bfe..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-subdev-g-frame-interval.rst
+++ /dev/null
@@ -1,120 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_SUBDEV_G_FRAME_INTERVAL:
-
-********************************************************************
-ioctl VIDIOC_SUBDEV_G_FRAME_INTERVAL, VIDIOC_SUBDEV_S_FRAME_INTERVAL
-********************************************************************
-
-Name
-====
-
-VIDIOC_SUBDEV_G_FRAME_INTERVAL - VIDIOC_SUBDEV_S_FRAME_INTERVAL - Get or set the frame interval on a subdev pad
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_G_FRAME_INTERVAL, struct v4l2_subdev_frame_interval *argp )
-    :name: VIDIOC_SUBDEV_G_FRAME_INTERVAL
-
-.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_S_FRAME_INTERVAL, struct v4l2_subdev_frame_interval *argp )
-    :name: VIDIOC_SUBDEV_S_FRAME_INTERVAL
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_subdev_frame_interval`.
-
-
-Description
-===========
-
-These ioctls are used to get and set the frame interval at specific
-subdev pads in the image pipeline. The frame interval only makes sense
-for sub-devices that can control the frame period on their own. This
-includes, for instance, image sensors and TV tuners. Sub-devices that
-don't support frame intervals must not implement these ioctls.
-
-To retrieve the current frame interval applications set the ``pad``
-field of a struct
-:c:type:`v4l2_subdev_frame_interval` to
-the desired pad number as reported by the media controller API. When
-they call the ``VIDIOC_SUBDEV_G_FRAME_INTERVAL`` ioctl with a pointer to
-this structure the driver fills the members of the ``interval`` field.
-
-To change the current frame interval applications set both the ``pad``
-field and all members of the ``interval`` field. When they call the
-``VIDIOC_SUBDEV_S_FRAME_INTERVAL`` ioctl with a pointer to this
-structure the driver verifies the requested interval, adjusts it based
-on the hardware capabilities and configures the device. Upon return the
-struct
-:c:type:`v4l2_subdev_frame_interval`
-contains the current frame interval as would be returned by a
-``VIDIOC_SUBDEV_G_FRAME_INTERVAL`` call.
-
-Drivers must not return an error solely because the requested interval
-doesn't match the device capabilities. They must instead modify the
-interval to match what the hardware can provide. The modified interval
-should be as close as possible to the original request.
-
-Changing the frame interval shall never change the format. Changing the
-format, on the other hand, may change the frame interval.
-
-Sub-devices that support the frame interval ioctls should implement them
-on a single pad only. Their behaviour when supported on multiple pads of
-the same sub-device is not defined.
-
-
-.. c:type:: v4l2_subdev_frame_interval
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. flat-table:: struct v4l2_subdev_frame_interval
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``pad``
-      - Pad number as reported by the media controller API.
-    * - struct :c:type:`v4l2_fract`
-      - ``interval``
-      - Period, in seconds, between consecutive video frames.
-    * - __u32
-      - ``reserved``\ [9]
-      - Reserved for future extensions. Applications and drivers must set
-	the array to zero.
-
-
-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.
-
-EBUSY
-    The frame interval can't be changed because the pad is currently
-    busy. This can be caused, for instance, by an active video stream on
-    the pad. The ioctl must not be retried without performing another
-    action to fix the problem first. Only returned by
-    ``VIDIOC_SUBDEV_S_FRAME_INTERVAL``
-
-EINVAL
-    The struct
-    :c:type:`v4l2_subdev_frame_interval`
-    ``pad`` references a non-existing pad, or the pad doesn't support
-    frame intervals.
diff --git a/Documentation/media/uapi/v4l/vidioc-subdev-g-selection.rst b/Documentation/media/uapi/v4l/vidioc-subdev-g-selection.rst
deleted file mode 100644
index fc73d27e6d74..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-subdev-g-selection.rst
+++ /dev/null
@@ -1,125 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_SUBDEV_G_SELECTION:
-
-**********************************************************
-ioctl VIDIOC_SUBDEV_G_SELECTION, VIDIOC_SUBDEV_S_SELECTION
-**********************************************************
-
-Name
-====
-
-VIDIOC_SUBDEV_G_SELECTION - VIDIOC_SUBDEV_S_SELECTION - Get or set selection rectangles on a subdev pad
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_G_SELECTION, struct v4l2_subdev_selection *argp )
-    :name: VIDIOC_SUBDEV_G_SELECTION
-
-.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_S_SELECTION, struct v4l2_subdev_selection *argp )
-    :name: VIDIOC_SUBDEV_S_SELECTION
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_subdev_selection`.
-
-
-Description
-===========
-
-The selections are used to configure various image processing
-functionality performed by the subdevs which affect the image size. This
-currently includes cropping, scaling and composition.
-
-The selection API replaces
-:ref:`the old subdev crop API <VIDIOC_SUBDEV_G_CROP>`. All the
-function of the crop API, and more, are supported by the selections API.
-
-See :ref:`subdev` for more information on how each selection target
-affects the image processing pipeline inside the subdevice.
-
-
-Types of selection targets
---------------------------
-
-There are two types of selection targets: actual and bounds. The actual
-targets are the targets which configure the hardware. The BOUNDS target
-will return a rectangle that contain all possible actual rectangles.
-
-
-Discovering supported features
-------------------------------
-
-To discover which targets are supported, the user can perform
-``VIDIOC_SUBDEV_G_SELECTION`` on them. Any unsupported target will
-return ``EINVAL``.
-
-Selection targets and flags are documented in
-:ref:`v4l2-selections-common`.
-
-
-.. c:type:: v4l2_subdev_selection
-
-.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
-
-.. flat-table:: struct v4l2_subdev_selection
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``which``
-      - Active or try selection, from enum
-	:ref:`v4l2_subdev_format_whence <v4l2-subdev-format-whence>`.
-    * - __u32
-      - ``pad``
-      - Pad number as reported by the media framework.
-    * - __u32
-      - ``target``
-      - Target selection rectangle. See :ref:`v4l2-selections-common`.
-    * - __u32
-      - ``flags``
-      - Flags. See :ref:`v4l2-selection-flags`.
-    * - struct :c:type:`v4l2_rect`
-      - ``r``
-      - Selection rectangle, in pixels.
-    * - __u32
-      - ``reserved``\ [8]
-      - Reserved for future extensions. Applications and drivers must set
-	the array to zero.
-
-
-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.
-
-EBUSY
-    The selection rectangle can't be changed because the pad is
-    currently busy. This can be caused, for instance, by an active video
-    stream on the pad. The ioctl must not be retried without performing
-    another action to fix the problem first. Only returned by
-    ``VIDIOC_SUBDEV_S_SELECTION``
-
-EINVAL
-    The struct :c:type:`v4l2_subdev_selection`
-    ``pad`` references a non-existing pad, the ``which`` field
-    references a non-existing format, or the selection target is not
-    supported on the given subdev pad.
diff --git a/Documentation/media/uapi/v4l/vidioc-subscribe-event.rst b/Documentation/media/uapi/v4l/vidioc-subscribe-event.rst
deleted file mode 100644
index a2d3454555ba..000000000000
--- a/Documentation/media/uapi/v4l/vidioc-subscribe-event.rst
+++ /dev/null
@@ -1,123 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _VIDIOC_SUBSCRIBE_EVENT:
-.. _VIDIOC_UNSUBSCRIBE_EVENT:
-
-******************************************************
-ioctl VIDIOC_SUBSCRIBE_EVENT, VIDIOC_UNSUBSCRIBE_EVENT
-******************************************************
-
-Name
-====
-
-VIDIOC_SUBSCRIBE_EVENT - VIDIOC_UNSUBSCRIBE_EVENT - Subscribe or unsubscribe event
-
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, VIDIOC_SUBSCRIBE_EVENT, struct v4l2_event_subscription *argp )
-    :name: VIDIOC_SUBSCRIBE_EVENT
-
-.. c:function:: int ioctl( int fd, VIDIOC_UNSUBSCRIBE_EVENT, struct v4l2_event_subscription *argp )
-    :name: VIDIOC_UNSUBSCRIBE_EVENT
-
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by :ref:`open() <func-open>`.
-
-``argp``
-    Pointer to struct :c:type:`v4l2_event_subscription`.
-
-
-Description
-===========
-
-Subscribe or unsubscribe V4L2 event. Subscribed events are dequeued by
-using the :ref:`VIDIOC_DQEVENT` ioctl.
-
-
-.. tabularcolumns:: |p{4.6cm}|p{4.4cm}|p{8.7cm}|
-
-.. c:type:: v4l2_event_subscription
-
-.. flat-table:: struct v4l2_event_subscription
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``type``
-      - Type of the event, see :ref:`event-type`.
-
-	.. note::
-
-	   ``V4L2_EVENT_ALL`` can be used with
-	   :ref:`VIDIOC_UNSUBSCRIBE_EVENT <VIDIOC_SUBSCRIBE_EVENT>` for
-	   unsubscribing all events at once.
-    * - __u32
-      - ``id``
-      - ID of the event source. If there is no ID associated with the
-	event source, then set this to 0. Whether or not an event needs an
-	ID depends on the event type.
-    * - __u32
-      - ``flags``
-      - Event flags, see :ref:`event-flags`.
-    * - __u32
-      - ``reserved``\ [5]
-      - Reserved for future extensions. Drivers and applications must set
-	the array to zero.
-
-
-
-.. tabularcolumns:: |p{6.8cm}|p{2.2cm}|p{8.5cm}|
-
-.. _event-flags:
-
-.. flat-table:: Event Flags
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       3 1 4
-
-    * - ``V4L2_EVENT_SUB_FL_SEND_INITIAL``
-      - 0x0001
-      - When this event is subscribed an initial event will be sent
-	containing the current status. This only makes sense for events
-	that are triggered by a status change such as ``V4L2_EVENT_CTRL``.
-	Other events will ignore this flag.
-    * - ``V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK``
-      - 0x0002
-      - If set, then events directly caused by an ioctl will also be sent
-	to the filehandle that called that ioctl. For example, changing a
-	control using :ref:`VIDIOC_S_CTRL <VIDIOC_G_CTRL>` will cause
-	a V4L2_EVENT_CTRL to be sent back to that same filehandle.
-	Normally such events are suppressed to prevent feedback loops
-	where an application changes a control to a one value and then
-	another, and then receives an event telling it that that control
-	has changed to the first value.
-
-	Since it can't tell whether that event was caused by another
-	application or by the :ref:`VIDIOC_S_CTRL <VIDIOC_G_CTRL>`
-	call it is hard to decide whether to set the control to the value
-	in the event, or ignore it.
-
-	Think carefully when you set this flag so you won't get into
-	situations like that.
-
-
-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/v4l/yuv-formats.rst b/Documentation/media/uapi/v4l/yuv-formats.rst
deleted file mode 100644
index 3b259e31b7a1..000000000000
--- a/Documentation/media/uapi/v4l/yuv-formats.rst
+++ /dev/null
@@ -1,64 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _yuv-formats:
-
-***********
-YUV Formats
-***********
-
-YUV is the format native to TV broadcast and composite video signals. It
-separates the brightness information (Y) from the color information (U
-and V or Cb and Cr). The color information consists of red and blue
-*color difference* signals, this way the green component can be
-reconstructed by subtracting from the brightness component. See
-:ref:`colorspaces` for conversion examples. YUV was chosen because
-early television would only transmit brightness information. To add
-color in a way compatible with existing receivers a new signal carrier
-was added to transmit the color difference signals. Secondary in the YUV
-format the U and V components usually have lower resolution than the Y
-component. This is an analog video compression technique taking
-advantage of a property of the human visual system, being more sensitive
-to brightness information.
-
-
-.. toctree::
-    :maxdepth: 1
-
-    pixfmt-packed-yuv
-    pixfmt-grey
-    pixfmt-y10
-    pixfmt-y12
-    pixfmt-y14
-    pixfmt-y10b
-    pixfmt-y10p
-    pixfmt-y16
-    pixfmt-y16-be
-    pixfmt-y8i
-    pixfmt-y12i
-    pixfmt-uv8
-    pixfmt-yuyv
-    pixfmt-uyvy
-    pixfmt-yvyu
-    pixfmt-vyuy
-    pixfmt-y41p
-    pixfmt-yuv420
-    pixfmt-yuv420m
-    pixfmt-yuv422m
-    pixfmt-yuv444m
-    pixfmt-yuv410
-    pixfmt-yuv422p
-    pixfmt-yuv411p
-    pixfmt-nv12
-    pixfmt-nv12m
-    pixfmt-nv12mt
-    pixfmt-nv16
-    pixfmt-nv16m
-    pixfmt-nv24
-    pixfmt-m420
diff --git a/Documentation/media/v4l-drivers/au0828-cardlist.rst b/Documentation/media/v4l-drivers/au0828-cardlist.rst
deleted file mode 100644
index aaaadc934e7a..000000000000
--- a/Documentation/media/v4l-drivers/au0828-cardlist.rst
+++ /dev/null
@@ -1,39 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-AU0828 cards list
-=================
-
-.. tabularcolumns:: |p{1.4cm}|p{6.5cm}|p{10.0cm}|
-
-.. flat-table::
-   :header-rows: 1
-   :widths: 2 19 18
-   :stub-columns: 0
-
-   * - Card number
-     - Card name
-     - USB IDs
-
-   * - 0
-     - Unknown board
-     -
-
-   * - 1
-     - Hauppauge HVR950Q
-     - 2040:7200, 2040:7210, 2040:7217, 2040:721b, 2040:721e, 2040:721f, 2040:7280, 0fd9:0008, 2040:7260, 2040:7213, 2040:7270
-
-   * - 2
-     - Hauppauge HVR850
-     - 2040:7240
-
-   * - 3
-     - DViCO FusionHDTV USB
-     - 0fe9:d620
-
-   * - 4
-     - Hauppauge HVR950Q rev xxF8
-     - 2040:7201, 2040:7211, 2040:7281
-
-   * - 5
-     - Hauppauge Woodbury
-     - 05e1:0480, 2040:8200
diff --git a/Documentation/media/v4l-drivers/bttv-cardlist.rst b/Documentation/media/v4l-drivers/bttv-cardlist.rst
deleted file mode 100644
index f5806856b5a1..000000000000
--- a/Documentation/media/v4l-drivers/bttv-cardlist.rst
+++ /dev/null
@@ -1,683 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-BTTV cards list
-===============
-
-.. tabularcolumns:: |p{1.4cm}|p{11.1cm}|p{4.2cm}|
-
-.. flat-table::
-   :header-rows: 1
-   :widths: 2 19 18
-   :stub-columns: 0
-
-   * - Card number
-     - Card name
-     - PCI IDs
-
-   * - 0
-     -  *** UNKNOWN/GENERIC ***
-     -
-
-   * - 1
-     - MIRO PCTV
-     -
-
-   * - 2
-     - Hauppauge (bt848)
-     -
-
-   * - 3
-     - STB, Gateway P/N 6000699 (bt848)
-     -
-
-   * - 4
-     - Intel Create and Share PCI/ Smart Video Recorder III
-     -
-
-   * - 5
-     - Diamond DTV2000
-     -
-
-   * - 6
-     - AVerMedia TVPhone
-     -
-
-   * - 7
-     - MATRIX-Vision MV-Delta
-     -
-
-   * - 8
-     - Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26
-     -
-
-   * - 9
-     - IMS/IXmicro TurboTV
-     -
-
-   * - 10
-     - Hauppauge (bt878)
-     - 0070:13eb, 0070:3900, 2636:10b4
-
-   * - 11
-     - MIRO PCTV pro
-     -
-
-   * - 12
-     - ADS Technologies Channel Surfer TV (bt848)
-     -
-
-   * - 13
-     - AVerMedia TVCapture 98
-     - 1461:0002, 1461:0004, 1461:0300
-
-   * - 14
-     - Aimslab Video Highway Xtreme (VHX)
-     -
-
-   * - 15
-     - Zoltrix TV-Max
-     - a1a0:a0fc
-
-   * - 16
-     - Prolink Pixelview PlayTV (bt878)
-     -
-
-   * - 17
-     - Leadtek WinView 601
-     -
-
-   * - 18
-     - AVEC Intercapture
-     -
-
-   * - 19
-     - Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)
-     -
-
-   * - 20
-     - CEI Raffles Card
-     -
-
-   * - 21
-     - Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50
-     -
-
-   * - 22
-     - Askey CPH050/ Phoebe Tv Master + FM
-     - 14ff:3002
-
-   * - 23
-     - Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878
-     - 14c7:0101
-
-   * - 24
-     - Askey CPH05X/06X (bt878) [many vendors]
-     - 144f:3002, 144f:3005, 144f:5000, 14ff:3000
-
-   * - 25
-     - Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar
-     -
-
-   * - 26
-     - Hauppauge WinCam newer (bt878)
-     -
-
-   * - 27
-     - Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50
-     -
-
-   * - 28
-     - Terratec TerraTV+ Version 1.1 (bt878)
-     - 153b:1127, 1852:1852
-
-   * - 29
-     - Imagenation PXC200
-     - 1295:200a
-
-   * - 30
-     - Lifeview FlyVideo 98 LR50
-     - 1f7f:1850
-
-   * - 31
-     - Formac iProTV, Formac ProTV I (bt848)
-     -
-
-   * - 32
-     - Intel Create and Share PCI/ Smart Video Recorder III
-     -
-
-   * - 33
-     - Terratec TerraTValue Version Bt878
-     - 153b:1117, 153b:1118, 153b:1119, 153b:111a, 153b:1134, 153b:5018
-
-   * - 34
-     - Leadtek WinFast 2000/ WinFast 2000 XP
-     - 107d:6606, 107d:6609, 6606:217d, f6ff:fff6
-
-   * - 35
-     - Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II
-     - 1851:1850, 1851:a050
-
-   * - 36
-     - Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner
-     - 1852:1852
-
-   * - 37
-     - Prolink PixelView PlayTV pro
-     -
-
-   * - 38
-     - Askey CPH06X TView99
-     - 144f:3000, 144f:a005, a04f:a0fc
-
-   * - 39
-     - Pinnacle PCTV Studio/Rave
-     - 11bd:0012, bd11:1200, bd11:ff00, 11bd:ff12
-
-   * - 40
-     - STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100
-     - 10b4:2636, 10b4:2645, 121a:3060
-
-   * - 41
-     - AVerMedia TVPhone 98
-     - 1461:0001, 1461:0003
-
-   * - 42
-     - ProVideo PV951
-     - aa0c:146c
-
-   * - 43
-     - Little OnAir TV
-     -
-
-   * - 44
-     - Sigma TVII-FM
-     -
-
-   * - 45
-     - MATRIX-Vision MV-Delta 2
-     -
-
-   * - 46
-     - Zoltrix Genie TV/FM
-     - 15b0:4000, 15b0:400a, 15b0:400d, 15b0:4010, 15b0:4016
-
-   * - 47
-     - Terratec TV/Radio+
-     - 153b:1123
-
-   * - 48
-     - Askey CPH03x/ Dynalink Magic TView
-     -
-
-   * - 49
-     - IODATA GV-BCTV3/PCI
-     - 10fc:4020
-
-   * - 50
-     - Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP
-     -
-
-   * - 51
-     - Eagle Wireless Capricorn2 (bt878A)
-     -
-
-   * - 52
-     - Pinnacle PCTV Studio Pro
-     -
-
-   * - 53
-     - Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS
-     -
-
-   * - 54
-     - Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90]
-     -
-
-   * - 55
-     - Askey CPH031/ BESTBUY Easy TV
-     -
-
-   * - 56
-     - Lifeview FlyVideo 98FM LR50
-     - a051:41a0
-
-   * - 57
-     - GrandTec 'Grand Video Capture' (Bt848)
-     - 4344:4142
-
-   * - 58
-     - Askey CPH060/ Phoebe TV Master Only (No FM)
-     -
-
-   * - 59
-     - Askey CPH03x TV Capturer
-     -
-
-   * - 60
-     - Modular Technology MM100PCTV
-     -
-
-   * - 61
-     - AG Electronics GMV1
-     - 15cb:0101
-
-   * - 62
-     - Askey CPH061/ BESTBUY Easy TV (bt878)
-     -
-
-   * - 63
-     - ATI TV-Wonder
-     - 1002:0001
-
-   * - 64
-     - ATI TV-Wonder VE
-     - 1002:0003
-
-   * - 65
-     - Lifeview FlyVideo 2000S LR90
-     -
-
-   * - 66
-     - Terratec TValueRadio
-     - 153b:1135, 153b:ff3b
-
-   * - 67
-     - IODATA GV-BCTV4/PCI
-     - 10fc:4050
-
-   * - 68
-     - 3Dfx VoodooTV FM (Euro)
-     - 10b4:2637
-
-   * - 69
-     - Active Imaging AIMMS
-     -
-
-   * - 70
-     - Prolink Pixelview PV-BT878P+ (Rev.4C,8E)
-     -
-
-   * - 71
-     - Lifeview FlyVideo 98EZ (capture only) LR51
-     - 1851:1851
-
-   * - 72
-     - Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)
-     - 1554:4011
-
-   * - 73
-     - Sensoray 311/611
-     - 6000:0311, 6000:0611
-
-   * - 74
-     - RemoteVision MX (RV605)
-     -
-
-   * - 75
-     - Powercolor MTV878/ MTV878R/ MTV878F
-     -
-
-   * - 76
-     - Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)
-     - 0e11:0079
-
-   * - 77
-     - GrandTec Multi Capture Card (Bt878)
-     -
-
-   * - 78
-     - Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF
-     - 0a01:17de
-
-   * - 79
-     - DSP Design TCVIDEO
-     -
-
-   * - 80
-     - Hauppauge WinTV PVR
-     - 0070:4500
-
-   * - 81
-     - IODATA GV-BCTV5/PCI
-     - 10fc:4070, 10fc:d018
-
-   * - 82
-     - Osprey 100/150 (878)
-     - 0070:ff00
-
-   * - 83
-     - Osprey 100/150 (848)
-     -
-
-   * - 84
-     - Osprey 101 (848)
-     -
-
-   * - 85
-     - Osprey 101/151
-     -
-
-   * - 86
-     - Osprey 101/151 w/ svid
-     -
-
-   * - 87
-     - Osprey 200/201/250/251
-     -
-
-   * - 88
-     - Osprey 200/250
-     - 0070:ff01
-
-   * - 89
-     - Osprey 210/220/230
-     -
-
-   * - 90
-     - Osprey 500
-     - 0070:ff02
-
-   * - 91
-     - Osprey 540
-     - 0070:ff04
-
-   * - 92
-     - Osprey 2000
-     - 0070:ff03
-
-   * - 93
-     - IDS Eagle
-     -
-
-   * - 94
-     - Pinnacle PCTV Sat
-     - 11bd:001c
-
-   * - 95
-     - Formac ProTV II (bt878)
-     -
-
-   * - 96
-     - MachTV
-     -
-
-   * - 97
-     - Euresys Picolo
-     -
-
-   * - 98
-     - ProVideo PV150
-     - aa00:1460, aa01:1461, aa02:1462, aa03:1463, aa04:1464, aa05:1465, aa06:1466, aa07:1467
-
-   * - 99
-     - AD-TVK503
-     -
-
-   * - 100
-     - Hercules Smart TV Stereo
-     -
-
-   * - 101
-     - Pace TV & Radio Card
-     -
-
-   * - 102
-     - IVC-200
-     - 0000:a155, 0001:a155, 0002:a155, 0003:a155, 0100:a155, 0101:a155, 0102:a155, 0103:a155, 0800:a155, 0801:a155, 0802:a155, 0803:a155
-
-   * - 103
-     - Grand X-Guard / Trust 814PCI
-     - 0304:0102
-
-   * - 104
-     - Nebula Electronics DigiTV
-     - 0071:0101
-
-   * - 105
-     - ProVideo PV143
-     - aa00:1430, aa00:1431, aa00:1432, aa00:1433, aa03:1433
-
-   * - 106
-     - PHYTEC VD-009-X1 VD-011 MiniDIN (bt878)
-     -
-
-   * - 107
-     - PHYTEC VD-009-X1 VD-011 Combi (bt878)
-     -
-
-   * - 108
-     - PHYTEC VD-009 MiniDIN (bt878)
-     -
-
-   * - 109
-     - PHYTEC VD-009 Combi (bt878)
-     -
-
-   * - 110
-     - IVC-100
-     - ff00:a132
-
-   * - 111
-     - IVC-120G
-     - ff00:a182, ff01:a182, ff02:a182, ff03:a182, ff04:a182, ff05:a182, ff06:a182, ff07:a182, ff08:a182, ff09:a182, ff0a:a182, ff0b:a182, ff0c:a182, ff0d:a182, ff0e:a182, ff0f:a182
-
-   * - 112
-     - pcHDTV HD-2000 TV
-     - 7063:2000
-
-   * - 113
-     - Twinhan DST + clones
-     - 11bd:0026, 1822:0001, 270f:fc00, 1822:0026
-
-   * - 114
-     - Winfast VC100
-     - 107d:6607
-
-   * - 115
-     - Teppro TEV-560/InterVision IV-560
-     -
-
-   * - 116
-     - SIMUS GVC1100
-     - aa6a:82b2
-
-   * - 117
-     - NGS NGSTV+
-     -
-
-   * - 118
-     - LMLBT4
-     -
-
-   * - 119
-     - Tekram M205 PRO
-     -
-
-   * - 120
-     - Conceptronic CONTVFMi
-     -
-
-   * - 121
-     - Euresys Picolo Tetra
-     - 1805:0105, 1805:0106, 1805:0107, 1805:0108
-
-   * - 122
-     - Spirit TV Tuner
-     -
-
-   * - 123
-     - AVerMedia AVerTV DVB-T 771
-     - 1461:0771
-
-   * - 124
-     - AverMedia AverTV DVB-T 761
-     - 1461:0761
-
-   * - 125
-     - MATRIX Vision Sigma-SQ
-     -
-
-   * - 126
-     - MATRIX Vision Sigma-SLC
-     -
-
-   * - 127
-     - APAC Viewcomp 878(AMAX)
-     -
-
-   * - 128
-     - DViCO FusionHDTV DVB-T Lite
-     - 18ac:db10, 18ac:db11
-
-   * - 129
-     - V-Gear MyVCD
-     -
-
-   * - 130
-     - Super TV Tuner
-     -
-
-   * - 131
-     - Tibet Systems 'Progress DVR' CS16
-     -
-
-   * - 132
-     - Kodicom 4400R (master)
-     -
-
-   * - 133
-     - Kodicom 4400R (slave)
-     -
-
-   * - 134
-     - Adlink RTV24
-     -
-
-   * - 135
-     - DViCO FusionHDTV 5 Lite
-     - 18ac:d500
-
-   * - 136
-     - Acorp Y878F
-     - 9511:1540
-
-   * - 137
-     - Conceptronic CTVFMi v2
-     - 036e:109e
-
-   * - 138
-     - Prolink Pixelview PV-BT878P+ (Rev.2E)
-     -
-
-   * - 139
-     - Prolink PixelView PlayTV MPEG2 PV-M4900
-     -
-
-   * - 140
-     - Osprey 440
-     - 0070:ff07
-
-   * - 141
-     - Asound Skyeye PCTV
-     -
-
-   * - 142
-     - Sabrent TV-FM (bttv version)
-     -
-
-   * - 143
-     - Hauppauge ImpactVCB (bt878)
-     - 0070:13eb
-
-   * - 144
-     - MagicTV
-     -
-
-   * - 145
-     - SSAI Security Video Interface
-     - 4149:5353
-
-   * - 146
-     - SSAI Ultrasound Video Interface
-     - 414a:5353
-
-   * - 147
-     - VoodooTV 200 (USA)
-     - 121a:3000
-
-   * - 148
-     - DViCO FusionHDTV 2
-     - dbc0:d200
-
-   * - 149
-     - Typhoon TV-Tuner PCI (50684)
-     -
-
-   * - 150
-     - Geovision GV-600
-     - 008a:763c
-
-   * - 151
-     - Kozumi KTV-01C
-     -
-
-   * - 152
-     - Encore ENL TV-FM-2
-     - 1000:1801
-
-   * - 153
-     - PHYTEC VD-012 (bt878)
-     -
-
-   * - 154
-     - PHYTEC VD-012-X1 (bt878)
-     -
-
-   * - 155
-     - PHYTEC VD-012-X2 (bt878)
-     -
-
-   * - 156
-     - IVCE-8784
-     - 0000:f050, 0001:f050, 0002:f050, 0003:f050
-
-   * - 157
-     - Geovision GV-800(S) (master)
-     - 800a:763d
-
-   * - 158
-     - Geovision GV-800(S) (slave)
-     - 800b:763d, 800c:763d, 800d:763d
-
-   * - 159
-     - ProVideo PV183
-     - 1830:1540, 1831:1540, 1832:1540, 1833:1540, 1834:1540, 1835:1540, 1836:1540, 1837:1540
-
-   * - 160
-     - Tongwei Video Technology TD-3116
-     - f200:3116
-
-   * - 161
-     - Aposonic W-DVR
-     - 0279:0228
-
-   * - 162
-     - Adlink MPG24
-     -
-
-   * - 163
-     - Bt848 Capture 14MHz
-     -
-
-   * - 164
-     - CyberVision CV06 (SV)
-     -
-
-   * - 165
-     - Kworld V-Stream Xpert TV PVR878
-     -
-
-   * - 166
-     - PCI-8604PW
-     -
diff --git a/Documentation/media/v4l-drivers/bttv.rst b/Documentation/media/v4l-drivers/bttv.rst
deleted file mode 100644
index f956ee264099..000000000000
--- a/Documentation/media/v4l-drivers/bttv.rst
+++ /dev/null
@@ -1,1926 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-The bttv driver
-===============
-
-Release notes for bttv
-----------------------
-
-You'll need at least these config options for bttv:
-
-.. code-block:: none
-
-	CONFIG_I2C=m
-	CONFIG_I2C_ALGOBIT=m
-	CONFIG_VIDEO_DEV=m
-
-The latest bttv version is available from http://bytesex.org/bttv/
-
-
-Make bttv work with your card
------------------------------
-
-Just try "modprobe bttv" and see if that works.
-
-If it doesn't bttv likely could not autodetect your card and needs some
-insmod options.  The most important insmod option for bttv is "card=n"
-to select the correct card type.  If you get video but no sound you've
-very likely specified the wrong (or no) card type.  A list of supported
-cards is in CARDLIST.bttv
-
-If bttv takes very long to load (happens sometimes with the cheap
-cards which have no tuner), try adding this to your modules.conf:
-
-.. code-block:: none
-
-	options i2c-algo-bit bit_test=1
-
-For the WinTV/PVR you need one firmware file from the driver CD:
-hcwamc.rbf.  The file is in the pvr45xxx.exe archive (self-extracting
-zip file, unzip can unpack it).  Put it into the /etc/pvr directory or
-use the firm_altera=<path> insmod option to point the driver to the
-location of the file.
-
-If your card isn't listed in CARDLIST.bttv or if you have trouble making
-audio work, you should read the Sound-FAQ.
-
-
-Autodetecting cards
--------------------
-
-bttv uses the PCI Subsystem ID to autodetect the card type.  lspci lists
-the Subsystem ID in the second line, looks like this:
-
-.. code-block:: none
-
-	00:0a.0 Multimedia video controller: Brooktree Corporation Bt878 (rev 02)
-		Subsystem: Hauppauge computer works Inc. WinTV/GO
-		Flags: bus master, medium devsel, latency 32, IRQ 5
-		Memory at e2000000 (32-bit, prefetchable) [size=4K]
-
-only bt878-based cards can have a subsystem ID (which does not mean
-that every card really has one).  bt848 cards can't have a Subsystem
-ID and therefore can't be autodetected.  There is a list with the ID's
-in bttv-cards.c (in case you are intrested or want to mail patches
-with updates).
-
-
-Still doesn't work?
--------------------
-
-I do NOT have a lab with 30+ different grabber boards and a
-PAL/NTSC/SECAM test signal generator at home, so I often can't
-reproduce your problems.  This makes debugging very difficult for me.
-If you have some knowledge and spare time, please try to fix this
-yourself (patches very welcome of course...)  You know: The linux
-slogan is "Do it yourself".
-
-There is a mailing list at
-http://vger.kernel.org/vger-lists.html#linux-media
-
-If you have trouble with some specific TV card, try to ask there
-instead of mailing me directly.  The chance that someone with the
-same card listens there is much higher...
-
-For problems with sound:  There are a lot of different systems used
-for TV sound all over the world.  And there are also different chips
-which decode the audio signal.  Reports about sound problems ("stereo
-doesn't work") are pretty useless unless you include some details
-about your hardware and the TV sound scheme used in your country (or
-at least the country you are living in).
-
-Modprobe options
-----------------
-
-Note: "modinfo <module>" prints various information about a kernel
-module, among them a complete and up-to-date list of insmod options.
-This list tends to be outdated because it is updated manually ...
-
-==========================================================================
-
-bttv.o
-
-.. code-block:: none
-
-	the bt848/878 (grabber chip) driver
-
-	insmod args:
-		card=n		card type, see CARDLIST for a list.
-		tuner=n		tuner type, see CARDLIST for a list.
-		radio=0/1	card supports radio
-		pll=0/1/2	pll settings
-			0: don't use PLL
-			1: 28 MHz crystal installed
-			2: 35 MHz crystal installed
-
-		triton1=0/1     for Triton1 (+others) compatibility
-		vsfx=0/1	yet another chipset bug compatibility bit
-				see README.quirks for details on these two.
-
-		bigendian=n	Set the endianness of the gfx framebuffer.
-				Default is native endian.
-		fieldnr=0/1	Count fields.  Some TV descrambling software
-				needs this, for others it only generates
-				50 useless IRQs/sec.  default is 0 (off).
-		autoload=0/1	autoload helper modules (tuner, audio).
-				default is 1 (on).
-		bttv_verbose=0/1/2  verbose level (at insmod time, while
-				looking at the hardware).  default is 1.
-		bttv_debug=0/1	debug messages (for capture).
-				default is 0 (off).
-		irq_debug=0/1	irq handler debug messages.
-				default is 0 (off).
-		gbuffers=2-32	number of capture buffers for mmap'ed capture.
-				default is 4.
-		gbufsize=	size of capture buffers. default and
-				maximum value is 0x208000 (~2MB)
-		no_overlay=0	Enable overlay on broken hardware.  There
-				are some chipsets (SIS for example) which
-				are known to have problems with the PCI DMA
-				push used by bttv.  bttv will disable overlay
-				by default on this hardware to avoid crashes.
-				With this insmod option you can override this.
-		no_overlay=1	Disable overlay. It should be used by broken
-				hardware that doesn't support PCI2PCI direct
-				transfers.
-		automute=0/1	Automatically mutes the sound if there is
-				no TV signal, on by default.  You might try
-				to disable this if you have bad input signal
-				quality which leading to unwanted sound
-				dropouts.
-		chroma_agc=0/1	AGC of chroma signal, off by default.
-		adc_crush=0/1	Luminance ADC crush, on by default.
-		i2c_udelay=     Allow reduce I2C speed. Default is 5 usecs
-				(meaning 66,67 Kbps). The default is the
-				maximum supported speed by kernel bitbang
-				algorithm. You may use lower numbers, if I2C
-				messages are lost (16 is known to work on
-				all supported cards).
-
-		bttv_gpio=0/1
-		gpiomask=
-		audioall=
-		audiomux=
-				See Sound-FAQ for a detailed description.
-
-	remap, card, radio and pll accept up to four comma-separated arguments
-	(for multiple boards).
-
-tuner.o
-
-.. code-block:: none
-
-	The tuner driver.  You need this unless you want to use only
-	with a camera or external tuner ...
-
-	insmod args:
-		debug=1		print some debug info to the syslog
-		type=n		type of the tuner chip. n as follows:
-				see CARDLIST for a complete list.
-		pal=[bdgil]	select PAL variant (used for some tuners
-				only, important for the audio carrier).
-
-tvaudio.o
-
-.. code-block:: none
-
-	new, experimental module which is supported to provide a single
-	driver for all simple i2c audio control chips (tda/tea*).
-
-	insmod args:
-		tda8425  = 1	enable/disable the support for the
-		tda9840  = 1	various chips.
-		tda9850  = 1	The tea6300 can't be autodetected and is
-		tda9855  = 1	therefore off by default, if you have
-		tda9873  = 1	this one on your card (STB uses these)
-		tda9874a = 1	you have to enable it explicitly.
-		tea6300  = 0	The two tda985x chips use the same i2c
-		tea6420  = 1	address and can't be disturgished from
-		pic16c54 = 1	each other, you might have to disable
-				the wrong one.
-		debug = 1	print debug messages
-
-	insmod args for tda9874a:
-		tda9874a_SIF=1/2	select sound IF input pin (1 or 2)
-					(default is pin 1)
-		tda9874a_AMSEL=0/1	auto-mute select for NICAM (default=0)
-					Please read note 3 below!
-		tda9874a_STD=n		select TV sound standard (0..8):
-					0 - A2, B/G
-					1 - A2, M (Korea)
-					2 - A2, D/K (1)
-					3 - A2, D/K (2)
-					4 - A2, D/K (3)
-					5 - NICAM, I
-					6 - NICAM, B/G
-					7 - NICAM, D/K (default)
-					8 - NICAM, L
-
-	Note 1: tda9874a supports both tda9874h (old) and tda9874a (new) chips.
-	Note 2: tda9874h/a and tda9875 (which is supported separately by
-	tda9875.o) use the same i2c address so both modules should not be
-	used at the same time.
-	Note 3: Using tda9874a_AMSEL option depends on your TV card design!
-		AMSEL=0: auto-mute will switch between NICAM sound
-			 and the sound on 1st carrier (i.e. FM mono or AM).
-		AMSEL=1: auto-mute will switch between NICAM sound
-			 and the analog mono input (MONOIN pin).
-	If tda9874a decoder on your card has MONOIN pin not connected, then
-	use only tda9874_AMSEL=0 or don't specify this option at all.
-	For example:
-	  card=65 (FlyVideo 2000S) - set AMSEL=1 or AMSEL=0
-	  card=72 (Prolink PV-BT878P rev.9B) - set AMSEL=0 only
-
-msp3400.o
-
-.. code-block:: none
-
-	The driver for the msp34xx sound processor chips. If you have a
-	stereo card, you probably want to insmod this one.
-
-	insmod args:
-		debug=1/2	print some debug info to the syslog,
-				2 is more verbose.
-		simple=1	Use the "short programming" method.  Newer
-				msp34xx versions support this.  You need this
-				for dbx stereo.  Default is on if supported by
-				the chip.
-		once=1		Don't check the TV-stations Audio mode
-				every few seconds, but only once after
-				channel switches.
-		amsound=1	Audio carrier is AM/NICAM at 6.5 Mhz.  This
-				should improve things for french people, the
-				carrier autoscan seems to work with FM only...
-
-tea6300.o - OBSOLETE (use tvaudio instead)
-
-.. code-block:: none
-
-	The driver for the tea6300 fader chip.  If you have a stereo
-	card and the msp3400.o doesn't work, you might want to try this
-	one.  This chip is seen on most STB TV/FM cards (usually from
-	Gateway OEM sold surplus on auction sites).
-
-	insmod args:
-		debug=1		print some debug info to the syslog.
-
-tda8425.o - OBSOLETE (use tvaudio instead)
-
-.. code-block:: none
-
-	The driver for the tda8425 fader chip.  This driver used to be
-	part of bttv.c, so if your sound used to work but does not
-	anymore, try loading this module.
-
-	insmod args:
-		debug=1		print some debug info to the syslog.
-
-tda985x.o - OBSOLETE (use tvaudio instead)
-
-.. code-block:: none
-
-	The driver for the tda9850/55 audio chips.
-
-	insmod args:
-		debug=1		print some debug info to the syslog.
-		chip=9850/9855	set the chip type.
-
-
-If the box freezes hard with bttv
----------------------------------
-
-It might be a bttv driver bug.  It also might be bad hardware.  It also
-might be something else ...
-
-Just mailing me "bttv freezes" isn't going to help much.  This README
-has a few hints how you can help to pin down the problem.
-
-
-bttv bugs
-~~~~~~~~~
-
-If some version works and another doesn't it is likely to be a driver
-bug.  It is very helpful if you can tell where exactly it broke
-(i.e. the last working and the first broken version).
-
-With a hard freeze you probably doesn't find anything in the logfiles.
-The only way to capture any kernel messages is to hook up a serial
-console and let some terminal application log the messages.  /me uses
-screen.  See Documentation/admin-guide/serial-console.rst for details on setting
-up a serial console.
-
-Read Documentation/admin-guide/bug-hunting.rst to learn how to get any useful
-information out of a register+stack dump printed by the kernel on
-protection faults (so-called "kernel oops").
-
-If you run into some kind of deadlock, you can try to dump a call trace
-for each process using sysrq-t (see Documentation/admin-guide/sysrq.rst).
-This way it is possible to figure where *exactly* some process in "D"
-state is stuck.
-
-I've seen reports that bttv 0.7.x crashes whereas 0.8.x works rock solid
-for some people.  Thus probably a small buglet left somewhere in bttv
-0.7.x.  I have no idea where exactly, it works stable for me and a lot of
-other people.  But in case you have problems with the 0.7.x versions you
-can give 0.8.x a try ...
-
-
-hardware bugs
-~~~~~~~~~~~~~
-
-Some hardware can't deal with PCI-PCI transfers (i.e. grabber => vga).
-Sometimes problems show up with bttv just because of the high load on
-the PCI bus. The bt848/878 chips have a few workarounds for known
-incompatibilities, see README.quirks.
-
-Some folks report that increasing the pci latency helps too,
-althrought I'm not sure whenever this really fixes the problems or
-only makes it less likely to happen.  Both bttv and btaudio have a
-insmod option to set the PCI latency of the device.
-
-Some mainboard have problems to deal correctly with multiple devices
-doing DMA at the same time.  bttv + ide seems to cause this sometimes,
-if this is the case you likely see freezes only with video and hard disk
-access at the same time.  Updating the IDE driver to get the latest and
-greatest workarounds for hardware bugs might fix these problems.
-
-
-other
-~~~~~
-
-If you use some binary-only yunk (like nvidia module) try to reproduce
-the problem without.
-
-IRQ sharing is known to cause problems in some cases.  It works just
-fine in theory and many configurations.  Neverless it might be worth a
-try to shuffle around the PCI cards to give bttv another IRQ or make
-it share the IRQ with some other piece of hardware.  IRQ sharing with
-VGA cards seems to cause trouble sometimes.  I've also seen funny
-effects with bttv sharing the IRQ with the ACPI bridge (and
-apci-enabled kernel).
-
-Bttv quirks
------------
-
-Below is what the bt878 data book says about the PCI bug compatibility
-modes of the bt878 chip.
-
-The triton1 insmod option sets the EN_TBFX bit in the control register.
-The vsfx insmod option does the same for EN_VSFX bit.  If you have
-stability problems you can try if one of these options makes your box
-work solid.
-
-drivers/pci/quirks.c knows about these issues, this way these bits are
-enabled automagically for known-buggy chipsets (look at the kernel
-messages, bttv tells you).
-
-Normal PCI Mode
-~~~~~~~~~~~~~~~
-
-The PCI REQ signal is the logical-or of the incoming function requests.
-The inter-nal GNT[0:1] signals are gated asynchronously with GNT and
-demultiplexed by the audio request signal. Thus the arbiter defaults to
-the video function at power-up and parks there during no requests for
-bus access. This is desirable since the video will request the bus more
-often. However, the audio will have highest bus access priority. Thus
-the audio will have first access to the bus even when issuing a request
-after the video request but before the PCI external arbiter has granted
-access to the Bt879. Neither function can preempt the other once on the
-bus. The duration to empty the entire video PCI FIFO onto the PCI bus is
-very short compared to the bus access latency the audio PCI FIFO can
-tolerate.
-
-
-430FX Compatibility Mode
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-When using the 430FX PCI, the following rules will ensure
-compatibility:
-
- (1) Deassert REQ at the same time as asserting FRAME.
- (2) Do not reassert REQ to request another bus transaction until after
-     finish-ing the previous transaction.
-
-Since the individual bus masters do not have direct control of REQ, a
-simple logical-or of video and audio requests would violate the rules.
-Thus, both the arbiter and the initiator contain 430FX compatibility
-mode logic. To enable 430FX mode, set the EN_TBFX bit as indicated in
-Device Control Register on page 104.
-
-When EN_TBFX is enabled, the arbiter ensures that the two compatibility
-rules are satisfied. Before GNT is asserted by the PCI arbiter, this
-internal arbiter may still logical-or the two requests. However, once
-the GNT is issued, this arbiter must lock in its decision and now route
-only the granted request to the REQ pin. The arbiter decision lock
-happens regardless of the state of FRAME because it does not know when
-FRAME will be asserted (typically - each initiator will assert FRAME on
-the cycle following GNT). When FRAME is asserted, it is the initiator s
-responsibility to remove its request at the same time. It is the
-arbiters responsibility to allow this request to flow through to REQ and
-not allow the other request to hold REQ asserted. The decision lock may
-be removed at the end of the transaction: for example, when the bus is
-idle (FRAME and IRDY). The arbiter decision may then continue
-asynchronously until GNT is again asserted.
-
-
-Interfacing with Non-PCI 2.1 Compliant Core Logic
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-A small percentage of core logic devices may start a bus transaction
-during the same cycle that GNT is de-asserted. This is non PCI 2.1
-compliant. To ensure compatibility when using PCs with these PCI
-controllers, the EN_VSFX bit must be enabled (refer to Device Control
-Register on page 104). When in this mode, the arbiter does not pass GNT
-to the internal functions unless REQ is asserted. This prevents a bus
-transaction from starting the same cycle as GNT is de-asserted. This
-also has the side effect of not being able to take advantage of bus
-parking, thus lowering arbitration performance. The Bt879 drivers must
-query for these non-compliant devices, and set the EN_VSFX bit only if
-required.
-
-bttv and sound mini howto
--------------------------
-
-There are a lot of different bt848/849/878/879 based boards available.
-Making video work often is not a big deal, because this is handled
-completely by the bt8xx chip, which is common on all boards.  But
-sound is handled in slightly different ways on each board.
-
-To handle the grabber boards correctly, there is a array tvcards[] in
-bttv-cards.c, which holds the information required for each board.
-Sound will work only, if the correct entry is used (for video it often
-makes no difference).  The bttv driver prints a line to the kernel
-log, telling which card type is used.  Like this one:
-
-.. code-block:: none
-
-	bttv0: model: BT848(Hauppauge old) [autodetected]
-
-You should verify this is correct.  If it isn't, you have to pass the
-correct board type as insmod argument, "insmod bttv card=2" for
-example.  The file CARDLIST has a list of valid arguments for card.
-If your card isn't listed there, you might check the source code for
-new entries which are not listed yet.  If there isn't one for your
-card, you can check if one of the existing entries does work for you
-(just trial and error...).
-
-Some boards have an extra processor for sound to do stereo decoding
-and other nice features.  The msp34xx chips are used by Hauppauge for
-example.  If your board has one, you might have to load a helper
-module like msp3400.o to make sound work.  If there isn't one for the
-chip used on your board:  Bad luck.  Start writing a new one.  Well,
-you might want to check the video4linux mailing list archive first...
-
-Of course you need a correctly installed soundcard unless you have the
-speakers connected directly to the grabber board.  Hint: check the
-mixer settings too.  ALSA for example has everything muted by default.
-
-
-How sound works in detail
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Still doesn't work?  Looks like some driver hacking is required.
-Below is a do-it-yourself description for you.
-
-The bt8xx chips have 32 general purpose pins, and registers to control
-these pins.  One register is the output enable register
-(BT848_GPIO_OUT_EN), it says which pins are actively driven by the
-bt848 chip.  Another one is the data register (BT848_GPIO_DATA), where
-you can get/set the status if these pins.  They can be used for input
-and output.
-
-Most grabber board vendors use these pins to control an external chip
-which does the sound routing.  But every board is a little different.
-These pins are also used by some companies to drive remote control
-receiver chips.  Some boards use the i2c bus instead of the gpio pins
-to connect the mux chip.
-
-As mentioned above, there is a array which holds the required
-information for each known board.  You basically have to create a new
-line for your board.  The important fields are these two:
-
-.. code-block:: c
-
-	struct tvcard
-	{
-		[ ... ]
-		u32 gpiomask;
-		u32 audiomux[6]; /* Tuner, Radio, external, internal, mute, stereo */
-	};
-
-gpiomask specifies which pins are used to control the audio mux chip.
-The corresponding bits in the output enable register
-(BT848_GPIO_OUT_EN) will be set as these pins must be driven by the
-bt848 chip.
-
-The audiomux\[\] array holds the data values for the different inputs
-(i.e. which pins must be high/low for tuner/mute/...).  This will be
-written to the data register (BT848_GPIO_DATA) to switch the audio
-mux.
-
-
-What you have to do is figure out the correct values for gpiomask and
-the audiomux array.  If you have Windows and the drivers four your
-card installed, you might to check out if you can read these registers
-values used by the windows driver.  A tool to do this is available
-from ftp://telepresence.dmem.strath.ac.uk/pub/bt848/winutil, but it
-doesn't work with bt878 boards according to some reports I received.
-Another one with bt878 support is available from
-http://btwincap.sourceforge.net/Files/btspy2.00.zip
-
-You might also dig around in the \*.ini files of the Windows applications.
-You can have a look at the board to see which of the gpio pins are
-connected at all and then start trial-and-error ...
-
-
-Starting with release 0.7.41 bttv has a number of insmod options to
-make the gpio debugging easier:
-
-.. code-block:: none
-
-	bttv_gpio=0/1		enable/disable gpio debug messages
-	gpiomask=n		set the gpiomask value
-	audiomux=i,j,...	set the values of the audiomux array
-	audioall=a		set the values of the audiomux array (one
-				value for all array elements, useful to check
-				out which effect the particular value has).
-
-The messages printed with bttv_gpio=1 look like this:
-
-.. code-block:: none
-
-	bttv0: gpio: en=00000027, out=00000024 in=00ffffd8 [audio: off]
-
-	en  =	output _en_able register (BT848_GPIO_OUT_EN)
-	out =	_out_put bits of the data register (BT848_GPIO_DATA),
-		i.e. BT848_GPIO_DATA & BT848_GPIO_OUT_EN
-	in  = 	_in_put bits of the data register,
-		i.e. BT848_GPIO_DATA & ~BT848_GPIO_OUT_EN
-
-
-
-Other elements of the tvcards array
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-If you are trying to make a new card work you might find it useful to
-know what the other elements in the tvcards array are good for:
-
-.. code-block:: none
-
-	video_inputs    - # of video inputs the card has
-	audio_inputs    - historical cruft, not used any more.
-	tuner           - which input is the tuner
-	svhs            - which input is svhs (all others are labeled composite)
-	muxsel          - video mux, input->registervalue mapping
-	pll             - same as pll= insmod option
-	tuner_type      - same as tuner= insmod option
-	*_modulename    - hint whenever some card needs this or that audio
-			module loaded to work properly.
-	has_radio	- whenever this TV card has a radio tuner.
-	no_msp34xx	- "1" disables loading of msp3400.o module
-	no_tda9875	- "1" disables loading of tda9875.o module
-	needs_tvaudio	- set to "1" to load tvaudio.o module
-
-If some config item is specified both from the tvcards array and as
-insmod option, the insmod option takes precedence.
-
-Cards
------
-
-.. note::
-
-   For a more updated list, please check
-   https://linuxtv.org/wiki/index.php/Hardware_Device_Information
-
-Supported cards: Bt848/Bt848a/Bt849/Bt878/Bt879 cards
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-All cards with Bt848/Bt848a/Bt849/Bt878/Bt879 and normal
-Composite/S-VHS inputs are supported.  Teletext and Intercast support
-(PAL only) for ALL cards via VBI sample decoding in software.
-
-Some cards with additional multiplexing of inputs or other additional
-fancy chips are only partially supported (unless specifications by the
-card manufacturer are given).  When a card is listed here it isn't
-necessarily fully supported.
-
-All other cards only differ by additional components as tuners, sound
-decoders, EEPROMs, teletext decoders ...
-
-
-MATRIX Vision
-~~~~~~~~~~~~~
-
-MV-Delta
-- Bt848A
-- 4 Composite inputs, 1 S-VHS input (shared with 4th composite)
-- EEPROM
-
-http://www.matrix-vision.de/
-
-This card has no tuner but supports all 4 composite (1 shared with an
-S-VHS input) of the Bt848A.
-Very nice card if you only have satellite TV but several tuners connected
-to the card via composite.
-
-Many thanks to Matrix-Vision for giving us 2 cards for free which made
-Bt848a/Bt849 single crystal operation support possible!!!
-
-
-
-Miro/Pinnacle PCTV
-~~~~~~~~~~~~~~~~~~
-
-- Bt848
-  some (all??) come with 2 crystals for PAL/SECAM and NTSC
-- PAL, SECAM or NTSC TV tuner (Philips or TEMIC)
-- MSP34xx sound decoder on add on board
-  decoder is supported but AFAIK does not yet work
-  (other sound MUX setting in GPIO port needed??? somebody who fixed this???)
-- 1 tuner, 1 composite and 1 S-VHS input
-- tuner type is autodetected
-
-http://www.miro.de/
-http://www.miro.com/
-
-
-Many thanks for the free card which made first NTSC support possible back
-in 1997!
-
-
-Hauppauge Win/TV pci
-~~~~~~~~~~~~~~~~~~~~
-
-There are many different versions of the Hauppauge cards with different
-tuners (TV+Radio ...), teletext decoders.
-Note that even cards with same model numbers have (depending on the revision)
-different chips on it.
-
-- Bt848 (and others but always in 2 crystal operation???)
-  newer cards have a Bt878
-
-- PAL, SECAM, NTSC or tuner with or without Radio support
-
-e.g.:
-
-- PAL:
-
-  - TDA5737: VHF, hyperband and UHF mixer/oscillator for TV and VCR 3-band tuners
-  - TSA5522: 1.4 GHz I2C-bus controlled synthesizer, I2C 0xc2-0xc3
-
-- NTSC:
-
-  - TDA5731: VHF, hyperband and UHF mixer/oscillator for TV and VCR 3-band tuners
-  - TSA5518: no datasheet available on Philips site
-
-- Philips SAA5246 or SAA5284 ( or no) Teletext decoder chip
-  with buffer RAM (e.g. Winbond W24257AS-35: 32Kx8 CMOS static RAM)
-  SAA5246 (I2C 0x22) is supported
-
-- 256 bytes EEPROM: Microchip 24LC02B or Philips 8582E2Y
-  with configuration information
-  I2C address 0xa0 (24LC02B also responds to 0xa2-0xaf)
-
-- 1 tuner, 1 composite and (depending on model) 1 S-VHS input
-
-- 14052B: mux for selection of sound source
-
-- sound decoder: TDA9800, MSP34xx (stereo cards)
-
-
-Askey CPH-Series
-~~~~~~~~~~~~~~~~
-Developed by TelSignal(?), OEMed by many vendors (Typhoon, Anubis, Dynalink)
-
-- Card series:
-  - CPH01x: BT848 capture only
-  - CPH03x: BT848
-  - CPH05x: BT878 with FM
-  - CPH06x: BT878 (w/o FM)
-  - CPH07x: BT878 capture only
-
-- TV standards:
-  - CPH0x0: NTSC-M/M
-  - CPH0x1: PAL-B/G
-  - CPH0x2: PAL-I/I
-  - CPH0x3: PAL-D/K
-  - CPH0x4: SECAM-L/L
-  - CPH0x5: SECAM-B/G
-  - CPH0x6: SECAM-D/K
-  - CPH0x7: PAL-N/N
-  - CPH0x8: PAL-B/H
-  - CPH0x9: PAL-M/M
-
-- CPH03x was often sold as "TV capturer".
-
-Identifying:
-
-  #) 878 cards can be identified by PCI Subsystem-ID:
-     - 144f:3000 = CPH06x
-     - 144F:3002 = CPH05x w/ FM
-     - 144F:3005 = CPH06x_LC (w/o remote control)
-  #) The cards have a sticker with "CPH"-model on the back.
-  #) These cards have a number printed on the PCB just above the tuner metal box:
-     - "80-CP2000300-x" = CPH03X
-     - "80-CP2000500-x" = CPH05X
-     - "80-CP2000600-x" = CPH06X / CPH06x_LC
-
-  Askey sells these cards as "Magic TView series", Brand "MagicXpress".
-  Other OEM often call these "Tview", "TView99" or else.
-
-Lifeview Flyvideo Series:
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The naming of these series differs in time and space.
-
-Identifying:
-  #) Some models can be identified by PCI subsystem ID:
-
-     - 1852:1852 = Flyvideo 98 FM
-     - 1851:1850 = Flyvideo 98
-     - 1851:1851 = Flyvideo 98 EZ (capture only)
-
-  #) There is a print on the PCB:
-
-     - LR25       = Flyvideo (Zoran ZR36120, SAA7110A)
-     - LR26 Rev.N = Flyvideo II (Bt848)
-     - LR26 Rev.O = Flyvideo II (Bt878)
-     - LR37 Rev.C = Flyvideo EZ (Capture only, ZR36120 + SAA7110)
-     - LR38 Rev.A1= Flyvideo II EZ (Bt848 capture only)
-     - LR50 Rev.Q = Flyvideo 98 (w/eeprom and PCI subsystem ID)
-     - LR50 Rev.W = Flyvideo 98 (no eeprom)
-     - LR51 Rev.E = Flyvideo 98 EZ (capture only)
-     - LR90       = Flyvideo 2000 (Bt878)
-     - LR90 Flyvideo 2000S (Bt878) w/Stereo TV (Package incl. LR91 daughterboard)
-     - LR91       = Stereo daughter card for LR90
-     - LR97       = Flyvideo DVBS
-     - LR99 Rev.E = Low profile card for OEM integration (only internal audio!) bt878
-     - LR136	 = Flyvideo 2100/3100 (Low profile, SAA7130/SAA7134)
-     - LR137      = Flyvideo DV2000/DV3000 (SAA7130/SAA7134 + IEEE1394)
-     - LR138 Rev.C= Flyvideo 2000 (SAA7130)
-     - LR138 Flyvideo 3000 (SAA7134) w/Stereo TV
-
-	- These exist in variations w/FM and w/Remote sometimes denoted
-	  by suffixes "FM" and "R".
-
-  #) You have a laptop (miniPCI card):
-
-      - Product    = FlyTV Platinum Mini
-      - Model/Chip = LR212/saa7135
-
-      - Lifeview.com.tw states (Feb. 2002):
-        "The FlyVideo2000 and FlyVideo2000s product name have renamed to FlyVideo98."
-        Their Bt8x8 cards are listed as discontinued.
-      - Flyvideo 2000S was probably sold as Flyvideo 3000 in some countries(Europe?).
-        The new Flyvideo 2000/3000 are SAA7130/SAA7134 based.
-
-"Flyvideo II" had been the name for the 848 cards, nowadays (in Germany)
-this name is re-used for LR50 Rev.W.
-
-The Lifeview website mentioned Flyvideo III at some time, but such a card
-has not yet been seen (perhaps it was the german name for LR90 [stereo]).
-These cards are sold by many OEMs too.
-
-FlyVideo A2 (Elta 8680)= LR90 Rev.F (w/Remote, w/o FM, stereo TV by tda9821) {Germany}
-
-Lifeview 3000 (Elta 8681) as sold by Plus(April 2002), Germany = LR138 w/ saa7134
-
-lifeview config coding on gpio pins 0-9
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-- LR50 rev. Q ("PARTS: 7031505116), Tuner wurde als Nr. 5 erkannt, Eingänge
-  SVideo, TV, Composite, Audio, Remote:
-
- - CP9..1=100001001 (1: 0-Ohm-Widerstand gegen GND unbestückt; 0: bestückt)
-
-
-Typhoon TV card series:
-~~~~~~~~~~~~~~~~~~~~~~~
-
-These can be CPH, Flyvideo, Pixelview or KNC1 series.
-Typhoon is the brand of Anubis.
-Model 50680 got re-used, some model no. had different contents over time.
-
-Models:
-
-  - 50680 "TV Tuner PCI Pal BG"(old,red package)=can be CPH03x(bt848) or CPH06x(bt878)
-  - 50680 "TV Tuner Pal BG" (blue package)= Pixelview PV-BT878P+ (Rev 9B)
-  - 50681 "TV Tuner PCI Pal I" (variant of 50680)
-  - 50682 "TView TV/FM Tuner Pal BG"       = Flyvideo 98FM (LR50 Rev.Q)
-
-  .. note::
-
-	 The package has a picture of CPH05x (which would be a real TView)
-
-  - 50683 "TV Tuner PCI SECAM" (variant of 50680)
-  - 50684 "TV Tuner Pal BG"                = Pixelview 878TV(Rev.3D)
-  - 50686 "TV Tuner"                       = KNC1 TV Station
-  - 50687 "TV Tuner stereo"                = KNC1 TV Station pro
-  - 50688 "TV Tuner RDS" (black package)   = KNC1 TV Station RDS
-  - 50689  TV SAT DVB-S CARD CI PCI (SAA7146AH, SU1278?) = "KNC1 TV Station DVB-S"
-  - 50692 "TV/FM Tuner" (small PCB)
-  - 50694  TV TUNER CARD RDS (PHILIPS CHIPSET SAA7134HL)
-  - 50696  TV TUNER STEREO (PHILIPS CHIPSET SAA7134HL, MK3ME Tuner)
-  - 50804  PC-SAT TV/Audio Karte = Techni-PC-Sat (ZORAN 36120PQC, Tuner:Alps)
-  - 50866  TVIEW SAT RECEIVER+ADR
-  - 50868 "TV/FM Tuner Pal I" (variant of 50682)
-  - 50999 "TV/FM Tuner Secam" (variant of 50682)
-
-Guillemot
-~~~~~~~~~
-
-Models:
-
-- Maxi-TV PCI (ZR36120)
-- Maxi TV Video 2 = LR50 Rev.Q (FI1216MF, PAL BG+SECAM)
-- Maxi TV Video 3 = CPH064 (PAL BG + SECAM)
-
-Mentor
-~~~~~~
-
-Mentor TV card ("55-878TV-U1") = Pixelview 878TV(Rev.3F) (w/FM w/Remote)
-
-Prolink
-~~~~~~~
-
-- TV cards:
-
-  - PixelView Play TV pro - (Model: PV-BT878P+ REV 8E)
-  - PixelView Play TV pro - (Model: PV-BT878P+ REV 9D)
-  - PixelView Play TV pro - (Model: PV-BT878P+ REV 4C / 8D / 10A )
-  - PixelView Play TV - (Model: PV-BT848P+)
-  - 878TV - (Model: PV-BT878TV)
-
-- Multimedia TV packages (card + software pack):
-
-  - PixelView Play TV Theater - (Model: PV-M4200) =  PixelView Play TV pro + Software
-  - PixelView Play TV PAK -     (Model: PV-BT878P+ REV 4E)
-  - PixelView Play TV/VCR -     (Model: PV-M3200 REV 4C / 8D / 10A )
-  - PixelView Studio PAK -      (Model:    M2200 REV 4C / 8D / 10A )
-  - PixelView PowerStudio PAK - (Model: PV-M3600 REV 4E)
-  - PixelView DigitalVCR PAK -  (Model: PV-M2400 REV 4C / 8D / 10A )
-  - PixelView PlayTV PAK II (TV/FM card + usb camera)  PV-M3800
-  - PixelView PlayTV XP PV-M4700,PV-M4700(w/FM)
-  - PixelView PlayTV DVR PV-M4600  package contents:PixelView PlayTV pro, windvr & videoMail s/w
-
-- Further Cards:
-
-  - PV-BT878P+rev.9B (Play TV Pro, opt. w/FM w/NICAM)
-  - PV-BT878P+rev.2F
-  - PV-BT878P Rev.1D (bt878, capture only)
-
-  - XCapture PV-CX881P (cx23881)
-  - PlayTV HD PV-CX881PL+, PV-CX881PL+(w/FM) (cx23881)
-
-  - DTV3000 PV-DTV3000P+ DVB-S CI = Twinhan VP-1030
-  - DTV2000 DVB-S = Twinhan VP-1020
-
-- Video Conferencing:
-
-  - PixelView Meeting PAK - (Model: PV-BT878P)
-  - PixelView Meeting PAK Lite - (Model: PV-BT878P)
-  - PixelView Meeting PAK plus - (Model: PV-BT878P+rev 4C/8D/10A)
-  - PixelView Capture - (Model: PV-BT848P)
-  - PixelView PlayTV USB pro
-  - Model No. PV-NT1004+, PV-NT1004+ (w/FM) = NT1004 USB decoder chip + SAA7113 video decoder chip
-
-Dynalink
-~~~~~~~~
-
-These are CPH series.
-
-Phoebemicro
-~~~~~~~~~~~
-
-- TV Master    = CPH030 or CPH060
-- TV Master FM = CPH050
-
-Genius/Kye
-~~~~~~~~~~
-
-- Video Wonder/Genius Internet Video Kit = LR37 Rev.C
-- Video Wonder Pro II (848 or 878) = LR26
-
-Tekram
-~~~~~~
-
-- VideoCap C205 (Bt848)
-- VideoCap C210 (zr36120 +Philips)
-- CaptureTV M200 (ISA)
-- CaptureTV M205 (Bt848)
-
-Lucky Star
-~~~~~~~~~~
-
-- Image World Conference TV = LR50 Rev. Q
-
-Leadtek
-~~~~~~~
-
-- WinView 601 (Bt848)
-- WinView 610 (Zoran)
-- WinFast2000
-- WinFast2000 XP
-
-Support for the Leadtek WinView 601 TV/FM
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Author of this section: Jon Tombs <jon@gte.esi.us.es>
-
-This card is basically the same as all the rest (Bt484A, Philips tuner),
-the main difference is that they have attached a programmable attenuator to 3
-GPIO lines in order to give some volume control. They have also stuck an
-infra-red remote control decoded on the board, I will add support for this
-when I get time (it simple generates an interrupt for each key press, with
-the key code is placed in the GPIO port).
-
-I don't yet have any application to test the radio support. The tuner
-frequency setting should work but it is possible that the audio multiplexer
-is wrong. If it doesn't work, send me email.
-
-
-- No Thanks to Leadtek they refused to answer any questions about their
-  hardware. The driver was written by visual inspection of the card. If you
-  use this driver, send an email insult to them, and tell them you won't
-  continue buying their hardware unless they support Linux.
-
-- Little thanks to Princeton Technology Corp (http://www.princeton.com.tw)
-  who make the audio attenuator. Their publicly available data-sheet available
-  on their web site doesn't include the chip programming information! Hidden
-  on their server are the full data-sheets, but don't ask how I found it.
-
-To use the driver I use the following options, the tuner and pll settings might
-be different in your country
-
-insmod videodev
-insmod i2c scan=1 i2c_debug=0 verbose=0
-insmod tuner type=1 debug=0
-insmod bttv  pll=1 radio=1 card=17
-
-
-KNC One
-~~~~~~~
-
-- TV-Station
-- TV-Station SE (+Software Bundle)
-- TV-Station pro (+TV stereo)
-- TV-Station FM (+Radio)
-- TV-Station RDS (+RDS)
-- TV Station SAT (analog satellite)
-- TV-Station DVB-S
-
-.. note:: newer Cards have saa7134, but model name stayed the same?
-
-Provideo
-~~~~~~~~
-
-- PV951 or PV-951 (also are sold as:
-   Boeder TV-FM Video Capture Card,
-   Titanmedia Supervision TV-2400,
-   Provideo PV951 TF,
-   3DeMon PV951,
-   MediaForte TV-Vision PV951,
-   Yoko PV951,
-   Vivanco Tuner Card PCI Art.-Nr.: 68404,
-   ) now named PV-951T
-
-- Surveillance Series:
-
- - PV-141
- - PV-143
- - PV-147
- - PV-148 (capture only)
- - PV-150
- - PV-151
-
-- TV-FM Tuner Series:
-
- - PV-951TDV (tv tuner + 1394)
- - PV-951T/TF
- - PV-951PT/TF
- - PV-956T/TF Low Profile
- - PV-911
-
-Highscreen
-~~~~~~~~~~
-
-Models:
-
-- TV Karte = LR50 Rev.S
-- TV-Boostar = Terratec Terra TV+ Version 1.0 (Bt848, tda9821) "ceb105.pcb"
-
-Zoltrix
-~~~~~~~
-
-Models:
-
-- Face to Face Capture (Bt848 capture only) (PCB "VP-2848")
-- Face To Face TV MAX (Bt848) (PCB "VP-8482 Rev1.3")
-- Genie TV (Bt878) (PCB "VP-8790 Rev 2.1")
-- Genie Wonder Pro
-
-AVerMedia
-~~~~~~~~~
-
-- AVer FunTV Lite (ISA, AV3001 chipset)  "M101.C"
-- AVerTV
-- AVerTV Stereo
-- AVerTV Studio (w/FM)
-- AVerMedia TV98 with Remote
-- AVerMedia TV/FM98 Stereo
-- AVerMedia TVCAM98
-- TVCapture (Bt848)
-- TVPhone (Bt848)
-- TVCapture98 (="AVerMedia TV98" in USA) (Bt878)
-- TVPhone98 (Bt878, w/FM)
-
-======== =========== =============== ======= ====== ======== =======================
-PCB      PCI-ID      Model-Name      Eeprom  Tuner  Sound    Country
-======== =========== =============== ======= ====== ======== =======================
-M101.C   ISA !
-M108-B      Bt848                     --     FR1236		 US   [#f2]_, [#f3]_
-M1A8-A      Bt848    AVer TV-Phone           FM1216  --
-M168-T   1461:0003   AVerTV Studio   48:17   FM1216 TDA9840T  D    [#f1]_ w/FM w/Remote
-M168-U   1461:0004   TVCapture98     40:11   FI1216   --      D    w/Remote
-M168II-B 1461:0003   Medion MD9592   48:16   FM1216 TDA9873H  D    w/FM
-======== =========== =============== ======= ====== ======== =======================
-
-.. [#f1] Daughterboard MB68-A with TDA9820T and TDA9840T
-.. [#f2] Sony NE41S soldered (stereo sound?)
-.. [#f3] Daughterboard M118-A w/ pic 16c54 and 4 MHz quartz
-
-- US site has different drivers for (as of 09/2002):
-
-  - EZ Capture/InterCam PCI (BT-848 chip)
-  - EZ Capture/InterCam PCI (BT-878 chip)
-  - TV-Phone (BT-848 chip)
-  - TV98 (BT-848 chip)
-  - TV98 With Remote (BT-848 chip)
-  - TV98 (BT-878 chip)
-  - TV98 With Remote (BT-878)
-  - TV/FM98 (BT-878 chip)
-  - AVerTV
-  - AverTV Stereo
-  - AVerTV Studio
-
-DE hat diverse Treiber fuer diese Modelle (Stand 09/2002):
-
-  - TVPhone (848) mit Philips tuner FR12X6 (w/ FM radio)
-  - TVPhone (848) mit Philips tuner FM12X6 (w/ FM radio)
-  - TVCapture (848) w/Philips tuner FI12X6
-  - TVCapture (848) non-Philips tuner
-  - TVCapture98 (Bt878)
-  - TVPhone98 (Bt878)
-  - AVerTV und TVCapture98 w/VCR (Bt 878)
-  - AVerTVStudio und TVPhone98 w/VCR (Bt878)
-  - AVerTV GO Serie (Kein SVideo Input)
-  - AVerTV98 (BT-878 chip)
-  - AVerTV98 mit Fernbedienung (BT-878 chip)
-  - AVerTV/FM98 (BT-878 chip)
-
-  - VDOmate (www.averm.com.cn) = M168U ?
-
-Aimslab
-~~~~~~~
-
-Models:
-
-- Video Highway or "Video Highway TR200" (ISA)
-- Video Highway Xtreme (aka "VHX") (Bt848, FM w/ TEA5757)
-
-IXMicro (former: IMS=Integrated Micro Solutions)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Models:
-
-- IXTV BT848 (=TurboTV)
-- IXTV BT878
-- IMS TurboTV (Bt848)
-
-Lifetec/Medion/Tevion/Aldi
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Models:
-
-- LT9306/MD9306 = CPH061
-- LT9415/MD9415 = LR90 Rev.F or Rev.G
-- MD9592 = Avermedia TVphone98 (PCI_ID=1461:0003), PCB-Rev=M168II-B (w/TDA9873H)
-- MD9717 = KNC One (Rev D4, saa7134, FM1216 MK2 tuner)
-- MD5044 = KNC One (Rev D4, saa7134, FM1216ME MK3 tuner)
-
-Modular Technologies (www.modulartech.com) UK
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Models:
-
-- MM100 PCTV (Bt848)
-- MM201 PCTV (Bt878, Bt832) w/ Quartzsight camera
-- MM202 PCTV (Bt878, Bt832, tda9874)
-- MM205 PCTV (Bt878)
-- MM210 PCTV (Bt878) (Galaxy TV, Galaxymedia ?)
-
-Terratec
-~~~~~~~~
-
-Models:
-
-- Terra TV+ Version 1.0 (Bt848), "ceb105.PCB" printed on the PCB, TDA9821
-- Terra TV+ Version 1.1 (Bt878), "LR74 Rev.E" printed on the PCB, TDA9821
-- Terra TValueRadio,             "LR102 Rev.C" printed on the PCB
-- Terra TV/Radio+ Version 1.0,   "80-CP2830100-0" TTTV3 printed on the PCB,
-  "CPH010-E83" on the back, SAA6588T, TDA9873H
-- Terra TValue Version BT878,    "80-CP2830110-0 TTTV4" printed on the PCB,
-  "CPH011-D83" on back
-- Terra TValue Version 1.0       "ceb105.PCB" (really identical to Terra TV+ Version 1.0)
-- Terra TValue New Revision	  "LR102 Rec.C"
-- Terra Active Radio Upgrade (tea5757h, saa6588t)
-
-- LR74 is a newer PCB revision of ceb105 (both incl. connector for Active Radio Upgrade)
-
-- Cinergy 400 (saa7134), "E877 11(S)", "PM820092D" printed on PCB
-- Cinergy 600 (saa7134)
-
-Technisat
-~~~~~~~~~
-
-Models:
-
-- Discos ADR PC-Karte ISA (no TV!)
-- Discos ADR PC-Karte PCI (probably no TV?)
-- Techni-PC-Sat (Sat. analog)
-  Rev 1.2 (zr36120, vpx3220, stv0030, saa5246, BSJE3-494A)
-- Mediafocus I (zr36120/zr36125, drp3510, Sat. analog + ADR Radio)
-- Mediafocus II (saa7146, Sat. analog)
-- SatADR Rev 2.1 (saa7146a, saa7113h, stv0056a, msp3400c, drp3510a, BSKE3-307A)
-- SkyStar 1 DVB  (AV7110) = Technotrend Premium
-- SkyStar 2 DVB  (B2C2) (=Sky2PC)
-
-Siemens
-~~~~~~~
-
-Multimedia eXtension Board (MXB) (SAA7146, SAA7111)
-
-Powercolor
-~~~~~~~~~~
-
-Models:
-
-- MTV878
-       Package comes with different contents:
-
-           a) pcb "MTV878" (CARD=75)
-           b) Pixelview Rev. 4\_
-
-- MTV878R w/Remote Control
-- MTV878F w/Remote Control w/FM radio
-
-Pinnacle
-~~~~~~~~
-
-PCTV models:
-
-- Mirovideo PCTV (Bt848)
-- Mirovideo PCTV SE (Bt848)
-- Mirovideo PCTV Pro (Bt848 + Daughterboard for TV Stereo and FM)
-- Studio PCTV Rave (Bt848 Version = Mirovideo PCTV)
-- Studio PCTV Rave (Bt878 package w/o infrared)
-- Studio PCTV      (Bt878)
-- Studio PCTV Pro  (Bt878 stereo w/ FM)
-- Pinnacle PCTV    (Bt878, MT2032)
-- Pinnacle PCTV Pro (Bt878, MT2032)
-- Pinncale PCTV Sat (bt878a, HM1821/1221) ["Conexant CX24110 with CX24108 tuner, aka HM1221/HM1811"]
-- Pinnacle PCTV Sat XE
-
-M(J)PEG capture and playback models:
-
-- DC1+ (ISA)
-- DC10  (zr36057,     zr36060,      saa7110, adv7176)
-- DC10+ (zr36067,     zr36060,      saa7110, adv7176)
-- DC20  (ql16x24b,zr36050, zr36016, saa7110, saa7187 ...)
-- DC30  (zr36057, zr36050, zr36016, vpx3220, adv7176, ad1843, tea6415, miro FST97A1)
-- DC30+ (zr36067, zr36050, zr36016, vpx3220, adv7176)
-- DC50  (zr36067, zr36050, zr36016, saa7112, adv7176 (2 pcs.?), ad1843, miro FST97A1, Lattice ???)
-
-Lenco
-~~~~~
-
-Models:
-
-- MXR-9565 (=Technisat Mediafocus?)
-- MXR-9571 (Bt848) (=CPH031?)
-- MXR-9575
-- MXR-9577 (Bt878) (=Prolink 878TV Rev.3x)
-- MXTV-9578CP (Bt878) (= Prolink PV-BT878P+4E)
-
-Iomega
-~~~~~~
-
-Buz (zr36067, zr36060, saa7111, saa7185)
-
-LML
-~~~
-   LML33 (zr36067, zr36060, bt819, bt856)
-
-Grandtec
-~~~~~~~~
-
-Models:
-
-- Grand Video Capture (Bt848)
-- Multi Capture Card  (Bt878)
-
-Koutech
-~~~~~~~
-
-Models:
-
-- KW-606 (Bt848)
-- KW-607 (Bt848 capture only)
-- KW-606RSF
-- KW-607A (capture only)
-- KW-608 (Zoran capture only)
-
-IODATA (jp)
-~~~~~~~~~~~
-
-Models:
-
-- GV-BCTV/PCI
-- GV-BCTV2/PCI
-- GV-BCTV3/PCI
-- GV-BCTV4/PCI
-- GV-VCP/PCI (capture only)
-- GV-VCP2/PCI (capture only)
-
-Canopus (jp)
-~~~~~~~~~~~~
-
-WinDVR	= Kworld "KW-TVL878RF"
-
-www.sigmacom.co.kr
-~~~~~~~~~~~~~~~~~~
-
-Sigma Cyber TV II
-
-www.sasem.co.kr
-~~~~~~~~~~~~~~~
-
-Litte OnAir TV
-
-hama
-~~~~
-
-TV/Radio-Tuner Card, PCI (Model 44677) = CPH051
-
-Sigma Designs
-~~~~~~~~~~~~~
-
-Hollywood plus (em8300, em9010, adv7175), (PCB "M340-10") MPEG DVD decoder
-
-Formac
-~~~~~~
-
-Models:
-
-- iProTV (Card for iMac Mezzanine slot, Bt848+SCSI)
-- ProTV (Bt848)
-- ProTV II = ProTV Stereo (Bt878) ["stereo" means FM stereo, tv is still mono]
-
-ATI
-~~~
-
-Models:
-
-- TV-Wonder
-- TV-Wonder VE
-
-Diamond Multimedia
-~~~~~~~~~~~~~~~~~~
-
-DTV2000 (Bt848, tda9875)
-
-Aopen
-~~~~~
-
-- VA1000 Plus (w/ Stereo)
-- VA1000 Lite
-- VA1000 (=LR90)
-
-Intel
-~~~~~
-
-Models:
-
-- Smart Video Recorder (ISA full-length)
-- Smart Video Recorder pro (ISA half-length)
-- Smart Video Recorder III (Bt848)
-
-STB
-~~~
-
-Models:
-
-- STB Gateway 6000704 (bt878)
-- STB Gateway 6000699 (bt848)
-- STB Gateway 6000402 (bt848)
-- STB TV130 PCI
-
-Videologic
-~~~~~~~~~~
-
-Models:
-
-- Captivator Pro/TV (ISA?)
-- Captivator PCI/VC (Bt848 bundled with camera) (capture only)
-
-Technotrend
-~~~~~~~~~~~~
-
-Models:
-
-- TT-SAT PCI (PCB "Sat-PCI Rev.:1.3.1"; zr36125, vpx3225d, stc0056a, Tuner:BSKE6-155A
-- TT-DVB-Sat
-   - revisions 1.1, 1.3, 1.5, 1.6 and 2.1
-   - This card is sold as OEM from:
-
-	- Siemens DVB-s Card
-	- Hauppauge WinTV DVB-S
-	- Technisat SkyStar 1 DVB
-	- Galaxis DVB Sat
-
-   - Now this card is called TT-PCline Premium Family
-   - TT-Budget (saa7146, bsru6-701a)
-     This card is sold as OEM from:
-
-	- Hauppauge WinTV Nova
-	- Satelco Standard PCI (DVB-S)
-   - TT-DVB-C PCI
-
-Teles
-~~~~~
-
- DVB-s (Rev. 2.2, BSRV2-301A, data only?)
-
-Remote Vision
-~~~~~~~~~~~~~
-
-MX RV605 (Bt848 capture only)
-
-Boeder
-~~~~~~
-
-Models:
-
-- PC ChatCam (Model 68252) (Bt848 capture only)
-- Tv/Fm Capture Card  (Model 68404) = PV951
-
-Media-Surfer  (esc-kathrein.de)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Models:
-
-- Sat-Surfer (ISA)
-- Sat-Surfer PCI = Techni-PC-Sat
-- Cable-Surfer 1
-- Cable-Surfer 2
-- Cable-Surfer PCI (zr36120)
-- Audio-Surfer (ISA Radio card)
-
-Jetway (www.jetway.com.tw)
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Models:
-
-- JW-TV 878M
-- JW-TV 878  = KWorld KW-TV878RF
-
-Galaxis
-~~~~~~~
-
-Models:
-
-- Galaxis DVB Card S CI
-- Galaxis DVB Card C CI
-- Galaxis DVB Card S
-- Galaxis DVB Card C
-- Galaxis plug.in S [neuer Name: Galaxis DVB Card S CI
-
-Hauppauge
-~~~~~~~~~
-
-Models:
-
-- many many WinTV models ...
-- WinTV DVBs = Technotrend Premium 1.3
-- WinTV NOVA = Technotrend Budget 1.1 "S-DVB DATA"
-- WinTV NOVA-CI "SDVBACI"
-- WinTV Nova USB (=Technotrend USB 1.0)
-- WinTV-Nexus-s (=Technotrend Premium 2.1 or 2.2)
-- WinTV PVR
-- WinTV PVR 250
-- WinTV PVR 450
-
-US models
-
--990 WinTV-PVR-350 (249USD) (iTVC15 chipset + radio)
--980 WinTV-PVR-250 (149USD) (iTVC15 chipset)
--880 WinTV-PVR-PCI (199USD) (KFIR chipset + bt878)
--881 WinTV-PVR-USB
--190 WinTV-GO
--191 WinTV-GO-FM
--404 WinTV
--401 WinTV-radio
--495 WinTV-Theater
--602 WinTV-USB
--621 WinTV-USB-FM
--600 USB-Live
--698 WinTV-HD
--697 WinTV-D
--564 WinTV-Nexus-S
-
-Deutsche Modelle:
-
--603 WinTV GO
--719 WinTV Primio-FM
--718 WinTV PCI-FM
--497 WinTV Theater
--569 WinTV USB
--568 WinTV USB-FM
--882 WinTV PVR
--981 WinTV PVR 250
--891 WinTV-PVR-USB
--541 WinTV Nova
--488 WinTV Nova-Ci
--564 WinTV-Nexus-s
--727 WinTV-DVB-c
--545 Common Interface
--898 WinTV-Nova-USB
-
-UK models:
-
--607 WinTV Go
--693,793 WinTV Primio FM
--647,747 WinTV PCI FM
--498 WinTV Theater
--883 WinTV PVR
--893 WinTV PVR USB  (Duplicate entry)
--566 WinTV USB (UK)
--573 WinTV USB FM
--429 Impact VCB (bt848)
--600 USB Live (Video-In 1x Comp, 1xSVHS)
--542 WinTV Nova
--717 WinTV DVB-S
--909 Nova-t PCI
--893 Nova-t USB   (Duplicate entry)
--802 MyTV
--804 MyView
--809 MyVideo
--872 MyTV2Go FM
--546 WinTV Nova-S CI
--543 WinTV Nova
--907 Nova-S USB
--908 Nova-T USB
--717 WinTV Nexus-S
--157 DEC3000-s Standalone + USB
-
-Spain:
-
--685 WinTV-Go
--690 WinTV-PrimioFM
--416 WinTV-PCI Nicam Estereo
--677 WinTV-PCI-FM
--699 WinTV-Theater
--683 WinTV-USB
--678 WinTV-USB-FM
--983 WinTV-PVR-250
--883 WinTV-PVR-PCI
--993 WinTV-PVR-350
--893 WinTV-PVR-USB
--728 WinTV-DVB-C PCI
--832 MyTV2Go
--869 MyTV2Go-FM
--805 MyVideo (USB)
-
-
-Matrix-Vision
-~~~~~~~~~~~~~
-
-Models:
-
-- MATRIX-Vision MV-Delta
-- MATRIX-Vision MV-Delta 2
-- MVsigma-SLC (Bt848)
-
-Conceptronic (.net)
-~~~~~~~~~~~~~~~~~~~
-
-Models:
-
-- TVCON FM,  TV card w/ FM = CPH05x
-- TVCON = CPH06x
-
-BestData
-~~~~~~~~
-
-Models:
-
-- HCC100 = VCC100rev1 + camera
-- VCC100 rev1 (bt848)
-- VCC100 rev2 (bt878)
-
-Gallant  (www.gallantcom.com) www.minton.com.tw
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Models:
-
-- Intervision IV-510 (capture only bt8x8)
-- Intervision IV-550 (bt8x8)
-- Intervision IV-100 (zoran)
-- Intervision IV-1000 (bt8x8)
-
-Asonic (www.asonic.com.cn) (website down)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-SkyEye tv 878
-
-Hoontech
-~~~~~~~~
-
-878TV/FM
-
-Teppro (www.itcteppro.com.tw)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Models:
-
-- ITC PCITV (Card Ver 1.0) "Teppro TV1/TVFM1 Card"
-- ITC PCITV (Card Ver 2.0)
-- ITC PCITV (Card Ver 3.0) = "PV-BT878P+ (REV.9D)"
-- ITC PCITV (Card Ver 4.0)
-- TEPPRO IV-550 (For BT848 Main Chip)
-- ITC DSTTV (bt878, satellite)
-- ITC VideoMaker (saa7146, StreamMachine sm2110, tvtuner) "PV-SM2210P+ (REV:1C)"
-
-Kworld (www.kworld.com.tw)
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-PC TV Station:
-
-- KWORLD KW-TV878R  TV (no radio)
-- KWORLD KW-TV878RF TV (w/ radio)
-- KWORLD KW-TVL878RF (low profile)
-- KWORLD KW-TV713XRF (saa7134)
-
-
- MPEG TV Station (same cards as above plus WinDVR Software MPEG en/decoder)
-
-- KWORLD KW-TV878R -Pro   TV (no Radio)
-- KWORLD KW-TV878RF-Pro   TV (w/ Radio)
-- KWORLD KW-TV878R -Ultra TV (no Radio)
-- KWORLD KW-TV878RF-Ultra TV (w/ Radio)
-
-JTT/ Justy Corp.(http://www.jtt.ne.jp/)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-JTT-02 (JTT TV) "TV watchmate pro" (bt848)
-
-ADS www.adstech.com
-~~~~~~~~~~~~~~~~~~~
-
-Models:
-
-- Channel Surfer TV ( CHX-950 )
-- Channel Surfer TV+FM ( CHX-960FM )
-
-AVEC www.prochips.com
-~~~~~~~~~~~~~~~~~~~~~
-
-AVEC Intercapture (bt848, tea6320)
-
-NoBrand
-~~~~~~~
-
-TV Excel = Australian Name for "PV-BT878P+ 8E" or "878TV Rev.3\_"
-
-Mach www.machspeed.com
-~~~~~~~~~~~~~~~~~~~~~~
-
-Mach TV 878
-
-Eline www.eline-net.com/
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-Models:
-
-- Eline Vision TVMaster / TVMaster FM (ELV-TVM/ ELV-TVM-FM) = LR26  (bt878)
-- Eline Vision TVMaster-2000 (ELV-TVM-2000, ELV-TVM-2000-FM)= LR138 (saa713x)
-
-Spirit
-~~~~~~
-
-- Spirit TV Tuner/Video Capture Card (bt848)
-
-Boser www.boser.com.tw
-~~~~~~~~~~~~~~~~~~~~~~
-
-Models:
-
-- HS-878 Mini PCI Capture Add-on Card
-- HS-879 Mini PCI 3D Audio and Capture Add-on Card (w/ ES1938 Solo-1)
-
-Satelco www.citycom-gmbh.de, www.satelco.de
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Models:
-
-- TV-FM =KNC1 saa7134
-- Standard PCI (DVB-S) = Technotrend Budget
-- Standard PCI (DVB-S) w/ CI
-- Satelco Highend PCI (DVB-S) = Technotrend Premium
-
-
-Sensoray www.sensoray.com
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Models:
-
-- Sensoray 311 (PC/104 bus)
-- Sensoray 611 (PCI)
-
-CEI (Chartered Electronics Industries Pte Ltd [CEI] [FCC ID HBY])
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Models:
-
-- TV Tuner  -  HBY-33A-RAFFLES  Brooktree Bt848KPF + Philips
-- TV Tuner MG9910  -  HBY33A-TVO  CEI + Philips SAA7110 + OKI M548262 + ST STV8438CV
-- Primetime TV (ISA)
-
-  - acquired by Singapore Technologies
-  - now operating as Chartered Semiconductor Manufacturing
-  - Manufacturer of video cards is listed as:
-
-    - Cogent Electronics Industries [CEI]
-
-AITech
-~~~~~~
-
-Models:
-
-- Wavewatcher TV (ISA)
-- AITech WaveWatcher TV-PCI = can be LR26 (Bt848) or LR50 (BT878)
-- WaveWatcher TVR-202 TV/FM Radio Card (ISA)
-
-MAXRON
-~~~~~~
-
-Maxron MaxTV/FM Radio (KW-TV878-FNT) = Kworld or JW-TV878-FBK
-
-www.ids-imaging.de
-~~~~~~~~~~~~~~~~~~
-
-Models:
-
-- Falcon Series (capture only)
-
-In USA: http://www.theimagingsource.com/
-- DFG/LC1
-
-www.sknet-web.co.jp
-~~~~~~~~~~~~~~~~~~~
-
-SKnet Monster TV (saa7134)
-
-A-Max www.amaxhk.com (Colormax, Amax, Napa)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-APAC Viewcomp 878
-
-Cybertainment
-~~~~~~~~~~~~~
-
-Models:
-
-- CyberMail AV Video Email Kit w/ PCI Capture Card (capture only)
-- CyberMail Xtreme
-
-These are Flyvideo
-
-VCR (http://www.vcrinc.com/)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Video Catcher 16
-
-Twinhan
-~~~~~~~
-
-Models:
-
-- DST Card/DST-IP (bt878, twinhan asic) VP-1020
-  - Sold as:
-
-    - KWorld DVBS Satellite TV-Card
-    - Powercolor DSTV Satellite Tuner Card
-    - Prolink Pixelview DTV2000
-    - Provideo PV-911 Digital Satellite TV Tuner Card With Common Interface ?
-
-- DST-CI Card (DVB Satellite) VP-1030
-- DCT Card (DVB cable)
-
-MSI
-~~~
-
-Models:
-
-- MSI TV@nywhere Tuner Card (MS-8876) (CX23881/883) Not Bt878 compatible.
-- MS-8401 DVB-S
-
-Focus www.focusinfo.com
-~~~~~~~~~~~~~~~~~~~~~~~
-
-InVideo PCI (bt878)
-
-Sdisilk www.sdisilk.com/
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-Models:
-
-- SDI Silk 100
-- SDI Silk 200 SDI Input Card
-
-www.euresys.com
-~~~~~~~~~~~~~~~
-
-PICOLO series
-
-PMC/Pace
-~~~~~~~~
-
-www.pacecom.co.uk website closed
-
-Mercury www.kobian.com (UK and FR)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Models:
-
-- LR50
-- LR138RBG-Rx  == LR138
-
-TEC sound
-~~~~~~~~~
-
-TV-Mate = Zoltrix VP-8482
-
-Though educated googling found: www.techmakers.com
-
-(package and manuals don't have any other manufacturer info) TecSound
-
-Lorenzen www.lorenzen.de
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-SL DVB-S PCI = Technotrend Budget PCI (su1278 or bsru version)
-
-Origo (.uk) www.origo2000.com
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-PC TV Card = LR50
-
-I/O Magic www.iomagic.com
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-PC PVR - Desktop TV Personal Video Recorder DR-PCTV100 = Pinnacle ROB2D-51009464 4.0 + Cyberlink PowerVCR II
-
-Arowana
-~~~~~~~
-
-TV-Karte / Poso Power TV (?) = Zoltrix VP-8482 (?)
-
-iTVC15 boards
-~~~~~~~~~~~~~
-
-kuroutoshikou.com ITVC15
-yuan.com MPG160 PCI TV (Internal PCI MPEG2 encoder card plus TV-tuner)
-
-Asus www.asuscom.com
-~~~~~~~~~~~~~~~~~~~~
-
-Models:
-
-- Asus TV Tuner Card 880 NTSC (low profile, cx23880)
-- Asus TV (saa7134)
-
-Hoontech
-~~~~~~~~
-
-http://www.hoontech.de/
-
-- HART Vision 848 (H-ART Vision 848)
-- HART Vision 878 (H-Art Vision 878)
-
-
-
-Chips used at bttv devices
---------------------------
-
-- all boards:
-
-  - Brooktree Bt848/848A/849/878/879: video capture chip
-
-- Board specific
-
-  - Miro PCTV:
-
-    - Philips or Temic Tuner
-
-  - Hauppauge Win/TV pci (version 405):
-
-    - Microchip 24LC02B or Philips 8582E2Y:
-
-       - 256 Byte EEPROM with configuration information
-       - I2C 0xa0-0xa1, (24LC02B also responds to 0xa2-0xaf)
-
-    - Philips SAA5246AGP/E: Videotext decoder chip, I2C 0x22-0x23
-
-    - TDA9800: sound decoder
-
-    - Winbond W24257AS-35: 32Kx8 CMOS static RAM (Videotext buffer mem)
-
-    - 14052B: analog switch for selection of sound source
-
-- PAL:
-
-  - TDA5737: VHF, hyperband and UHF mixer/oscillator for TV and VCR 3-band tuners
-  - TSA5522: 1.4 GHz I2C-bus controlled synthesizer, I2C 0xc2-0xc3
-
-- NTSC:
-
-  - TDA5731: VHF, hyperband and UHF mixer/oscillator for TV and VCR 3-band tuners
-  - TSA5518: no datasheet available on Philips site
-
-- STB TV pci:
-
-  - ???
-  - if you want better support for STB cards send me info!
-    Look at the board! What chips are on it?
-
-
-
-
-Specs
------
-
-Philips		http://www.Semiconductors.COM/pip/
-
-Conexant	http://www.conexant.com/
-
-Micronas	http://www.micronas.com/en/home/index.html
-
-Thanks
-------
-
-Many thanks to:
-
-- Markus Schroeder <schroedm@uni-duesseldorf.de> for information on the Bt848
-  and tuner programming and his control program xtvc.
-
-- Martin Buck <martin-2.buck@student.uni-ulm.de> for his great Videotext
-  package.
-
-- Gerd Hoffmann for the MSP3400 support and the modular
-  I2C, tuner, ... support.
-
-
-- MATRIX Vision for giving us 2 cards for free, which made support of
-  single crystal operation possible.
-
-- MIRO for providing a free PCTV card and detailed information about the
-  components on their cards. (E.g. how the tuner type is detected)
-  Without their card I could not have debugged the NTSC mode.
-
-- Hauppauge for telling how the sound input is selected and what components
-  they do and will use on their radio cards.
-  Also many thanks for faxing me the FM1216 data sheet.
-
-Contributors
-------------
-
-Michael Chu <mmchu@pobox.com>
-  AverMedia fix and more flexible card recognition
-
-Alan Cox <alan@lxorguk.ukuu.org.uk>
-  Video4Linux interface and 2.1.x kernel adaptation
-
-Chris Kleitsch
-  Hardware I2C
-
-Gerd Hoffmann
-  Radio card (ITT sound processor)
-
-bigfoot <bigfoot@net-way.net>
-
-Ragnar Hojland Espinosa <ragnar@macula.net>
-  ConferenceTV card
-
-
-+ many more (please mail me if you are missing in this list and would
-	     like to be mentioned)
diff --git a/Documentation/media/v4l-drivers/cafe_ccic.rst b/Documentation/media/v4l-drivers/cafe_ccic.rst
deleted file mode 100644
index ff7fbce1342a..000000000000
--- a/Documentation/media/v4l-drivers/cafe_ccic.rst
+++ /dev/null
@@ -1,62 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-The cafe_ccic driver
-====================
-
-Author: Jonathan Corbet <corbet@lwn.net>
-
-Introduction
-------------
-
-"cafe_ccic" is a driver for the Marvell 88ALP01 "cafe" CMOS camera
-controller.  This is the controller found in first-generation OLPC systems,
-and this driver was written with support from the OLPC project.
-
-Current status: the core driver works.  It can generate data in YUV422,
-RGB565, and RGB444 formats.  (Anybody looking at the code will see RGB32 as
-well, but that is a debugging aid which will be removed shortly).  VGA and
-QVGA modes work; CIF is there but the colors remain funky.  Only the OV7670
-sensor is known to work with this controller at this time.
-
-To try it out: either of these commands will work:
-
-.. code-block:: none
-
-     $ mplayer tv:// -tv driver=v4l2:width=640:height=480 -nosound
-     $ mplayer tv:// -tv driver=v4l2:width=640:height=480:outfmt=bgr16 -nosound
-
-The "xawtv" utility also works; gqcam does not, for unknown reasons.
-
-Load time options
------------------
-
-There are a few load-time options, most of which can be changed after
-loading via sysfs as well:
-
- - alloc_bufs_at_load:  Normally, the driver will not allocate any DMA
-   buffers until the time comes to transfer data.  If this option is set,
-   then worst-case-sized buffers will be allocated at module load time.
-   This option nails down the memory for the life of the module, but
-   perhaps decreases the chances of an allocation failure later on.
-
- - dma_buf_size: The size of DMA buffers to allocate.  Note that this
-   option is only consulted for load-time allocation; when buffers are
-   allocated at run time, they will be sized appropriately for the current
-   camera settings.
-
- - n_dma_bufs: The controller can cycle through either two or three DMA
-   buffers.  Normally, the driver tries to use three buffers; on faster
-   systems, however, it will work well with only two.
-
- - min_buffers: The minimum number of streaming I/O buffers that the driver
-   will consent to work with.  Default is one, but, on slower systems,
-   better behavior with mplayer can be achieved by setting to a higher
-   value (like six).
-
- - max_buffers: The maximum number of streaming I/O buffers; default is
-   ten.  That number was carefully picked out of a hat and should not be
-   assumed to actually mean much of anything.
-
- - flip: If this boolean parameter is set, the sensor will be instructed to
-   invert the video image.  Whether it makes sense is determined by how
-   your particular camera is mounted.
diff --git a/Documentation/media/v4l-drivers/cardlist.rst b/Documentation/media/v4l-drivers/cardlist.rst
deleted file mode 100644
index 14249f47fbc2..000000000000
--- a/Documentation/media/v4l-drivers/cardlist.rst
+++ /dev/null
@@ -1,20 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-Cards List
-==========
-
-.. toctree::
-	:maxdepth: 1
-
-	au0828-cardlist
-	bttv-cardlist
-	cx23885-cardlist
-	cx88-cardlist
-	em28xx-cardlist
-	ivtv-cardlist
-	saa7134-cardlist
-	saa7164-cardlist
-	tm6000-cardlist
-	tuner-cardlist
-	usbvision-cardlist
-	gspca-cardlist
diff --git a/Documentation/media/v4l-drivers/cpia2.rst b/Documentation/media/v4l-drivers/cpia2.rst
deleted file mode 100644
index a86baa1c83f1..000000000000
--- a/Documentation/media/v4l-drivers/cpia2.rst
+++ /dev/null
@@ -1,195 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-The cpia2 driver
-================
-
-Authors: Peter Pregler <Peter_Pregler@email.com>,
-Scott J. Bertin <scottbertin@yahoo.com>, and
-Jarl Totland <Jarl.Totland@bdc.no> for the original cpia driver, which
-this one was modelled from.
-
-Introduction
-------------
-
-This is a driver for STMicroelectronics's CPiA2 (second generation
-Colour Processor Interface ASIC) based cameras. This camera outputs an MJPEG
-stream at up to vga size. It implements the Video4Linux interface as much as
-possible.  Since the V4L interface does not support compressed formats, only
-an mjpeg enabled application can be used with the camera. We have modified the
-gqcam application to view this stream.
-
-The driver is implemented as two kernel modules. The cpia2 module
-contains the camera functions and the V4L interface.  The cpia2_usb module
-contains usb specific functions.  The main reason for this was the size of the
-module was getting out of hand, so I separated them.  It is not likely that
-there will be a parallel port version.
-
-Features
---------
-
-- Supports cameras with the Vision stv6410 (CIF) and stv6500 (VGA) cmos
-  sensors. I only have the vga sensor, so can't test the other.
-- Image formats: VGA, QVGA, CIF, QCIF, and a number of sizes in between.
-  VGA and QVGA are the native image sizes for the VGA camera. CIF is done
-  in the coprocessor by scaling QVGA.  All other sizes are done by clipping.
-- Palette: YCrCb, compressed with MJPEG.
-- Some compression parameters are settable.
-- Sensor framerate is adjustable (up to 30 fps CIF, 15 fps VGA).
-- Adjust brightness, color, contrast while streaming.
-- Flicker control settable for 50 or 60 Hz mains frequency.
-
-Making and installing the stv672 driver modules
------------------------------------------------
-
-Requirements
-~~~~~~~~~~~~
-
-Video4Linux must be either compiled into the kernel or
-available as a module.  Video4Linux2 is automatically detected and made
-available at compile time.
-
-Setup
-~~~~~
-
-Use 'modprobe cpia2' to load and 'modprobe -r cpia2' to unload. This
-may be done automatically by your distribution.
-
-Driver options
-~~~~~~~~~~~~~~
-
-.. tabularcolumns:: |p{13ex}|L|
-
-
-==============  ========================================================
-Option		Description
-==============  ========================================================
-video_nr	video device to register (0=/dev/video0, etc)
-		range -1 to 64.  default is -1 (first available)
-		If you have more than 1 camera, this MUST be -1.
-buffer_size	Size for each frame buffer in bytes (default 68k)
-num_buffers	Number of frame buffers (1-32, default 3)
-alternate	USB Alternate (2-7, default 7)
-flicker_freq	Frequency for flicker reduction(50 or 60, default 60)
-flicker_mode	0 to disable, or 1 to enable flicker reduction.
-		(default 0). This is only effective if the camera
-		uses a stv0672 coprocessor.
-==============  ========================================================
-
-Setting the options
-~~~~~~~~~~~~~~~~~~~
-
-If you are using modules, edit /etc/modules.conf and add an options
-line like this:
-
-.. code-block:: none
-
-	options cpia2 num_buffers=3 buffer_size=65535
-
-If the driver is compiled into the kernel, at boot time specify them
-like this:
-
-.. code-block:: none
-
-	cpia2.num_buffers=3 cpia2.buffer_size=65535
-
-What buffer size should I use?
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The maximum image size depends on the alternate you choose, and the
-frame rate achieved by the camera.  If the compression engine is able to
-keep up with the frame rate, the maximum image size is given by the table
-below.
-
-The compression engine starts out at maximum compression, and will
-increase image quality until it is close to the size in the table.  As long
-as the compression engine can keep up with the frame rate, after a short time
-the images will all be about the size in the table, regardless of resolution.
-
-At low alternate settings, the compression engine may not be able to
-compress the image enough and will reduce the frame rate by producing larger
-images.
-
-The default of 68k should be good for most users.  This will handle
-any alternate at frame rates down to 15fps.  For lower frame rates, it may
-be necessary to increase the buffer size to avoid having frames dropped due
-to insufficient space.
-
-========== ========== ======== =====
-Alternate  bytes/ms   15fps    30fps
-========== ========== ======== =====
-    2         128      8533     4267
-    3         384     25600    12800
-    4         640     42667    21333
-    5         768     51200    25600
-    6         896     59733    29867
-    7        1023     68200    34100
-========== ========== ======== =====
-
-Table: Image size(bytes)
-
-
-How many buffers should I use?
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-For normal streaming, 3 should give the best results.  With only 2,
-it is possible for the camera to finish sending one image just after a
-program has started reading the other.  If this happens, the driver must drop
-a frame.  The exception to this is if you have a heavily loaded machine.  In
-this case use 2 buffers.  You are probably not reading at the full frame rate.
-If the camera can send multiple images before a read finishes, it could
-overwrite the third buffer before the read finishes, leading to a corrupt
-image.  Single and double buffering have extra checks to avoid overwriting.
-
-Using the camera
-~~~~~~~~~~~~~~~~
-
-We are providing a modified gqcam application to view the output. In
-order to avoid confusion, here it is called mview.  There is also the qx5view
-program which can also control the lights on the qx5 microscope. MJPEG Tools
-(http://mjpeg.sourceforge.net) can also be used to record from the camera.
-
-Notes to developers
-~~~~~~~~~~~~~~~~~~~
-
-   - This is a driver version stripped of the 2.4 back compatibility
-     and old MJPEG ioctl API. See cpia2.sf.net for 2.4 support.
-
-Programmer's overview of cpia2 driver
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Cpia2 is the second generation video coprocessor from VLSI Vision Ltd (now a
-division of ST Microelectronics).  There are two versions.  The first is the
-STV0672, which is capable of up to 30 frames per second (fps) in frame sizes
-up to CIF, and 15 fps for VGA frames.  The STV0676 is an improved version,
-which can handle up to 30 fps VGA.  Both coprocessors can be attached to two
-CMOS sensors - the vvl6410 CIF sensor and the vvl6500 VGA sensor.  These will
-be referred to as the 410 and the 500 sensors, or the CIF and VGA sensors.
-
-The two chipsets operate almost identically.  The core is an 8051 processor,
-running two different versions of firmware.  The 672 runs the VP4 video
-processor code, the 676 runs VP5.  There are a few differences in register
-mappings for the two chips.  In these cases, the symbols defined in the
-header files are marked with VP4 or VP5 as part of the symbol name.
-
-The cameras appear externally as three sets of registers. Setting register
-values is the only way to control the camera.  Some settings are
-interdependant, such as the sequence required to power up the camera. I will
-try to make note of all of these cases.
-
-The register sets are called blocks.  Block 0 is the system block.  This
-section is always powered on when the camera is plugged in.  It contains
-registers that control housekeeping functions such as powering up the video
-processor.  The video processor is the VP block.  These registers control
-how the video from the sensor is processed.  Examples are timing registers,
-user mode (vga, qvga), scaling, cropping, framerates, and so on.  The last
-block is the video compressor (VC).  The video stream sent from the camera is
-compressed as Motion JPEG (JPEGA).  The VC controls all of the compression
-parameters.  Looking at the file cpia2_registers.h, you can get a full view
-of these registers and the possible values for most of them.
-
-One or more registers can be set or read by sending a usb control message to
-the camera.  There are three modes for this.  Block mode requests a number
-of contiguous registers.  Random mode reads or writes random registers with
-a tuple structure containing address/value pairs.  The repeat mode is only
-used by VP4 to load a firmware patch.  It contains a starting address and
-a sequence of bytes to be written into a gpio port.
diff --git a/Documentation/media/v4l-drivers/cx2341x.rst b/Documentation/media/v4l-drivers/cx2341x.rst
deleted file mode 100644
index 8ca37deb56b6..000000000000
--- a/Documentation/media/v4l-drivers/cx2341x.rst
+++ /dev/null
@@ -1,3860 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-The cx2341x driver
-==================
-
-Memory at cx2341x chips
------------------------
-
-This section describes the cx2341x memory map and documents some of the
-register space.
-
-.. note:: the memory long words are little-endian ('intel format').
-
-.. warning::
-
-	This information was figured out from searching through the memory
-	and registers, this information may not be correct and is certainly
-	not complete, and was not derived from anything more than searching
-	through the memory space with commands like:
-
-	.. code-block:: none
-
-		ivtvctl -O min=0x02000000,max=0x020000ff
-
-	So take this as is, I'm always searching for more stuff, it's a large
-	register space :-).
-
-Memory Map
-~~~~~~~~~~
-
-The cx2341x exposes its entire 64M memory space to the PCI host via the PCI BAR0
-(Base Address Register 0). The addresses here are offsets relative to the
-address held in BAR0.
-
-.. code-block:: none
-
-	0x00000000-0x00ffffff Encoder memory space
-	0x00000000-0x0003ffff Encode.rom
-	???-???         MPEG buffer(s)
-	???-???         Raw video capture buffer(s)
-	???-???         Raw audio capture buffer(s)
-	???-???         Display buffers (6 or 9)
-
-	0x01000000-0x01ffffff Decoder memory space
-	0x01000000-0x0103ffff Decode.rom
-	???-???         MPEG buffers(s)
-	0x0114b000-0x0115afff Audio.rom (deprecated?)
-
-	0x02000000-0x0200ffff Register Space
-
-Registers
-~~~~~~~~~
-
-The registers occupy the 64k space starting at the 0x02000000 offset from BAR0.
-All of these registers are 32 bits wide.
-
-.. code-block:: none
-
-	DMA Registers 0x000-0xff:
-
-	0x00 - Control:
-		0=reset/cancel, 1=read, 2=write, 4=stop
-	0x04 - DMA status:
-		1=read busy, 2=write busy, 4=read error, 8=write error, 16=link list error
-	0x08 - pci DMA pointer for read link list
-	0x0c - pci DMA pointer for write link list
-	0x10 - read/write DMA enable:
-		1=read enable, 2=write enable
-	0x14 - always 0xffffffff, if set any lower instability occurs, 0x00 crashes
-	0x18 - ??
-	0x1c - always 0x20 or 32, smaller values slow down DMA transactions
-	0x20 - always value of 0x780a010a
-	0x24-0x3c - usually just random values???
-	0x40 - Interrupt status
-	0x44 - Write a bit here and shows up in Interrupt status 0x40
-	0x48 - Interrupt Mask
-	0x4C - always value of 0xfffdffff,
-		if changed to 0xffffffff DMA write interrupts break.
-	0x50 - always 0xffffffff
-	0x54 - always 0xffffffff (0x4c, 0x50, 0x54 seem like interrupt masks, are
-		3 processors on chip, Java ones, VPU, SPU, APU, maybe these are the
-		interrupt masks???).
-	0x60-0x7C - random values
-	0x80 - first write linked list reg, for Encoder Memory addr
-	0x84 - first write linked list reg, for pci memory addr
-	0x88 - first write linked list reg, for length of buffer in memory addr
-		(|0x80000000 or this for last link)
-	0x8c-0xdc - rest of write linked list reg, 8 sets of 3 total, DMA goes here
-		from linked list addr in reg 0x0c, firmware must push through or
-		something.
-	0xe0 - first (and only) read linked list reg, for pci memory addr
-	0xe4 - first (and only) read linked list reg, for Decoder memory addr
-	0xe8 - first (and only) read linked list reg, for length of buffer
-	0xec-0xff - Nothing seems to be in these registers, 0xec-f4 are 0x00000000.
-
-Memory locations for Encoder Buffers 0x700-0x7ff:
-
-These registers show offsets of memory locations pertaining to each
-buffer area used for encoding, have to shift them by <<1 first.
-
-- 0x07F8: Encoder SDRAM refresh
-- 0x07FC: Encoder SDRAM pre-charge
-
-Memory locations for Decoder Buffers 0x800-0x8ff:
-
-These registers show offsets of memory locations pertaining to each
-buffer area used for decoding, have to shift them by <<1 first.
-
-- 0x08F8: Decoder SDRAM refresh
-- 0x08FC: Decoder SDRAM pre-charge
-
-Other memory locations:
-
-- 0x2800: Video Display Module control
-- 0x2D00: AO (audio output?) control
-- 0x2D24: Bytes Flushed
-- 0x7000: LSB I2C write clock bit (inverted)
-- 0x7004: LSB I2C write data bit (inverted)
-- 0x7008: LSB I2C read clock bit
-- 0x700c: LSB I2C read data bit
-- 0x9008: GPIO get input state
-- 0x900c: GPIO set output state
-- 0x9020: GPIO direction (Bit7 (GPIO 0..7) - 0:input, 1:output)
-- 0x9050: SPU control
-- 0x9054: Reset HW blocks
-- 0x9058: VPU control
-- 0xA018: Bit6: interrupt pending?
-- 0xA064: APU command
-
-
-Interrupt Status Register
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The definition of the bits in the interrupt status register 0x0040, and the
-interrupt mask 0x0048. If a bit is cleared in the mask, then we want our ISR to
-execute.
-
-- bit 31 Encoder Start Capture
-- bit 30 Encoder EOS
-- bit 29 Encoder VBI capture
-- bit 28 Encoder Video Input Module reset event
-- bit 27 Encoder DMA complete
-- bit 24 Decoder audio mode change detection event (through event notification)
-- bit 22 Decoder data request
-- bit 20 Decoder DMA complete
-- bit 19 Decoder VBI re-insertion
-- bit 18 Decoder DMA err (linked-list bad)
-
-Missing documentation
----------------------
-
-- Encoder API post(?)
-- Decoder API post(?)
-- Decoder VTRACE event
-
-
-The cx2341x firmware upload
----------------------------
-
-This document describes how to upload the cx2341x firmware to the card.
-
-How to find
-~~~~~~~~~~~
-
-See the web pages of the various projects that uses this chip for information
-on how to obtain the firmware.
-
-The firmware stored in a Windows driver can be detected as follows:
-
-- Each firmware image is 256k bytes.
-- The 1st 32-bit word of the Encoder image is 0x0000da7
-- The 1st 32-bit word of the Decoder image is 0x00003a7
-- The 2nd 32-bit word of both images is 0xaa55bb66
-
-How to load
-~~~~~~~~~~~
-
-- Issue the FWapi command to stop the encoder if it is running. Wait for the
-  command to complete.
-- Issue the FWapi command to stop the decoder if it is running. Wait for the
-  command to complete.
-- Issue the I2C command to the digitizer to stop emitting VSYNC events.
-- Issue the FWapi command to halt the encoder's firmware.
-- Sleep for 10ms.
-- Issue the FWapi command to halt the decoder's firmware.
-- Sleep for 10ms.
-- Write 0x00000000 to register 0x2800 to stop the Video Display Module.
-- Write 0x00000005 to register 0x2D00 to stop the AO (audio output?).
-- Write 0x00000000 to register 0xA064 to ping? the APU.
-- Write 0xFFFFFFFE to register 0x9058 to stop the VPU.
-- Write 0xFFFFFFFF to register 0x9054 to reset the HW blocks.
-- Write 0x00000001 to register 0x9050 to stop the SPU.
-- Sleep for 10ms.
-- Write 0x0000001A to register 0x07FC to init the Encoder SDRAM's pre-charge.
-- Write 0x80000640 to register 0x07F8 to init the Encoder SDRAM's refresh to 1us.
-- Write 0x0000001A to register 0x08FC to init the Decoder SDRAM's pre-charge.
-- Write 0x80000640 to register 0x08F8 to init the Decoder SDRAM's refresh to 1us.
-- Sleep for 512ms. (600ms is recommended)
-- Transfer the encoder's firmware image to offset 0 in Encoder memory space.
-- Transfer the decoder's firmware image to offset 0 in Decoder memory space.
-- Use a read-modify-write operation to Clear bit 0 of register 0x9050 to
-  re-enable the SPU.
-- Sleep for 1 second.
-- Use a read-modify-write operation to Clear bits 3 and 0 of register 0x9058
-  to re-enable the VPU.
-- Sleep for 1 second.
-- Issue status API commands to both firmware images to verify.
-
-
-How to call the firmware API
-----------------------------
-
-The preferred calling convention is known as the firmware mailbox. The
-mailboxes are basically a fixed length array that serves as the call-stack.
-
-Firmware mailboxes can be located by searching the encoder and decoder memory
-for a 16 byte signature. That signature will be located on a 256-byte boundary.
-
-Signature:
-
-.. code-block:: none
-
-	0x78, 0x56, 0x34, 0x12, 0x12, 0x78, 0x56, 0x34,
-	0x34, 0x12, 0x78, 0x56, 0x56, 0x34, 0x12, 0x78
-
-The firmware implements 20 mailboxes of 20 32-bit words. The first 10 are
-reserved for API calls. The second 10 are used by the firmware for event
-notification.
-
-  ====== =================
-  Index  Name
-  ====== =================
-  0      Flags
-  1      Command
-  2      Return value
-  3      Timeout
-  4-19   Parameter/Result
-  ====== =================
-
-
-The flags are defined in the following table. The direction is from the
-perspective of the firmware.
-
-  ==== ========== ============================================
-  Bit  Direction  Purpose
-  ==== ========== ============================================
-  2    O          Firmware has processed the command.
-  1    I          Driver has finished setting the parameters.
-  0    I          Driver is using this mailbox.
-  ==== ========== ============================================
-
-The command is a 32-bit enumerator. The API specifics may be found in this
-chapter.
-
-The return value is a 32-bit enumerator. Only two values are currently defined:
-
-- 0=success
-- -1=command undefined.
-
-There are 16 parameters/results 32-bit fields. The driver populates these fields
-with values for all the parameters required by the call. The driver overwrites
-these fields with result values returned by the call.
-
-The timeout value protects the card from a hung driver thread. If the driver
-doesn't handle the completed call within the timeout specified, the firmware
-will reset that mailbox.
-
-To make an API call, the driver iterates over each mailbox looking for the
-first one available (bit 0 has been cleared). The driver sets that bit, fills
-in the command enumerator, the timeout value and any required parameters. The
-driver then sets the parameter ready bit (bit 1). The firmware scans the
-mailboxes for pending commands, processes them, sets the result code, populates
-the result value array with that call's return values and sets the call
-complete bit (bit 2). Once bit 2 is set, the driver should retrieve the results
-and clear all the flags. If the driver does not perform this task within the
-time set in the timeout register, the firmware will reset that mailbox.
-
-Event notifications are sent from the firmware to the host. The host tells the
-firmware which events it is interested in via an API call. That call tells the
-firmware which notification mailbox to use. The firmware signals the host via
-an interrupt. Only the 16 Results fields are used, the Flags, Command, Return
-value and Timeout words are not used.
-
-
-OSD firmware API description
-----------------------------
-
-.. note:: this API is part of the decoder firmware, so it's cx23415 only.
-
-
-
-CX2341X_OSD_GET_FRAMEBUFFER
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 65/0x41
-
-Description
-^^^^^^^^^^^
-
-Return base and length of contiguous OSD memory.
-
-Result[0]
-^^^^^^^^^
-
-OSD base address
-
-Result[1]
-^^^^^^^^^
-
-OSD length
-
-
-
-CX2341X_OSD_GET_PIXEL_FORMAT
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 66/0x42
-
-Description
-^^^^^^^^^^^
-
-Query OSD format
-
-Result[0]
-^^^^^^^^^
-
-0=8bit index
-1=16bit RGB 5:6:5
-2=16bit ARGB 1:5:5:5
-3=16bit ARGB 1:4:4:4
-4=32bit ARGB 8:8:8:8
-
-
-
-CX2341X_OSD_SET_PIXEL_FORMAT
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 67/0x43
-
-Description
-^^^^^^^^^^^
-
-Assign pixel format
-
-Param[0]
-^^^^^^^^
-
-- 0=8bit index
-- 1=16bit RGB 5:6:5
-- 2=16bit ARGB 1:5:5:5
-- 3=16bit ARGB 1:4:4:4
-- 4=32bit ARGB 8:8:8:8
-
-
-
-CX2341X_OSD_GET_STATE
-~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 68/0x44
-
-Description
-^^^^^^^^^^^
-
-Query OSD state
-
-Result[0]
-^^^^^^^^^
-
-- Bit  0   0=off, 1=on
-- Bits 1:2 alpha control
-- Bits 3:5 pixel format
-
-
-
-CX2341X_OSD_SET_STATE
-~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 69/0x45
-
-Description
-^^^^^^^^^^^
-
-OSD switch
-
-Param[0]
-^^^^^^^^
-
-0=off, 1=on
-
-
-
-CX2341X_OSD_GET_OSD_COORDS
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 70/0x46
-
-Description
-^^^^^^^^^^^
-
-Retrieve coordinates of OSD area blended with video
-
-Result[0]
-^^^^^^^^^
-
-OSD buffer address
-
-Result[1]
-^^^^^^^^^
-
-Stride in pixels
-
-Result[2]
-^^^^^^^^^
-
-Lines in OSD buffer
-
-Result[3]
-^^^^^^^^^
-
-Horizontal offset in buffer
-
-Result[4]
-^^^^^^^^^
-
-Vertical offset in buffer
-
-
-
-CX2341X_OSD_SET_OSD_COORDS
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 71/0x47
-
-Description
-^^^^^^^^^^^
-
-Assign the coordinates of the OSD area to blend with video
-
-Param[0]
-^^^^^^^^
-
-buffer address
-
-Param[1]
-^^^^^^^^
-
-buffer stride in pixels
-
-Param[2]
-^^^^^^^^
-
-lines in buffer
-
-Param[3]
-^^^^^^^^
-
-horizontal offset
-
-Param[4]
-^^^^^^^^
-
-vertical offset
-
-
-
-CX2341X_OSD_GET_SCREEN_COORDS
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 72/0x48
-
-Description
-^^^^^^^^^^^
-
-Retrieve OSD screen area coordinates
-
-Result[0]
-^^^^^^^^^
-
-top left horizontal offset
-
-Result[1]
-^^^^^^^^^
-
-top left vertical offset
-
-Result[2]
-^^^^^^^^^
-
-bottom right horizontal offset
-
-Result[3]
-^^^^^^^^^
-
-bottom right vertical offset
-
-
-
-CX2341X_OSD_SET_SCREEN_COORDS
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 73/0x49
-
-Description
-^^^^^^^^^^^
-
-Assign the coordinates of the screen area to blend with video
-
-Param[0]
-^^^^^^^^
-
-top left horizontal offset
-
-Param[1]
-^^^^^^^^
-
-top left vertical offset
-
-Param[2]
-^^^^^^^^
-
-bottom left horizontal offset
-
-Param[3]
-^^^^^^^^
-
-bottom left vertical offset
-
-
-
-CX2341X_OSD_GET_GLOBAL_ALPHA
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 74/0x4A
-
-Description
-^^^^^^^^^^^
-
-Retrieve OSD global alpha
-
-Result[0]
-^^^^^^^^^
-
-global alpha: 0=off, 1=on
-
-Result[1]
-^^^^^^^^^
-
-bits 0:7 global alpha
-
-
-
-CX2341X_OSD_SET_GLOBAL_ALPHA
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 75/0x4B
-
-Description
-^^^^^^^^^^^
-
-Update global alpha
-
-Param[0]
-^^^^^^^^
-
-global alpha: 0=off, 1=on
-
-Param[1]
-^^^^^^^^
-
-global alpha (8 bits)
-
-Param[2]
-^^^^^^^^
-
-local alpha: 0=on, 1=off
-
-
-
-CX2341X_OSD_SET_BLEND_COORDS
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 78/0x4C
-
-Description
-^^^^^^^^^^^
-
-Move start of blending area within display buffer
-
-Param[0]
-^^^^^^^^
-
-horizontal offset in buffer
-
-Param[1]
-^^^^^^^^
-
-vertical offset in buffer
-
-
-
-CX2341X_OSD_GET_FLICKER_STATE
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 79/0x4F
-
-Description
-^^^^^^^^^^^
-
-Retrieve flicker reduction module state
-
-Result[0]
-^^^^^^^^^
-
-flicker state: 0=off, 1=on
-
-
-
-CX2341X_OSD_SET_FLICKER_STATE
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 80/0x50
-
-Description
-^^^^^^^^^^^
-
-Set flicker reduction module state
-
-Param[0]
-^^^^^^^^
-
-State: 0=off, 1=on
-
-
-
-CX2341X_OSD_BLT_COPY
-~~~~~~~~~~~~~~~~~~~~
-
-Enum: 82/0x52
-
-Description
-^^^^^^^^^^^
-
-BLT copy
-
-Param[0]
-^^^^^^^^
-
-.. code-block:: none
-
-	'0000'  zero
-	'0001' ~destination AND ~source
-	'0010' ~destination AND  source
-	'0011' ~destination
-	'0100'  destination AND ~source
-	'0101'                  ~source
-	'0110'  destination XOR  source
-	'0111' ~destination OR  ~source
-	'1000' ~destination AND ~source
-	'1001'  destination XNOR source
-	'1010'                   source
-	'1011' ~destination OR   source
-	'1100'  destination
-	'1101'  destination OR  ~source
-	'1110'  destination OR   source
-	'1111'  one
-
-
-Param[1]
-^^^^^^^^
-
-Resulting alpha blending
-
-- '01' source_alpha
-- '10' destination_alpha
-- '11' source_alpha*destination_alpha+1
-  (zero if both source and destination alpha are zero)
-
-Param[2]
-^^^^^^^^
-
-.. code-block:: none
-
-	'00' output_pixel = source_pixel
-
-	'01' if source_alpha=0:
-		 output_pixel = destination_pixel
-	     if 256 > source_alpha > 1:
-		 output_pixel = ((source_alpha + 1)*source_pixel +
-				 (255 - source_alpha)*destination_pixel)/256
-
-	'10' if destination_alpha=0:
-		 output_pixel = source_pixel
-	      if 255 > destination_alpha > 0:
-		 output_pixel = ((255 - destination_alpha)*source_pixel +
-				 (destination_alpha + 1)*destination_pixel)/256
-
-	'11' if source_alpha=0:
-		 source_temp = 0
-	     if source_alpha=255:
-		 source_temp = source_pixel*256
-	     if 255 > source_alpha > 0:
-		 source_temp = source_pixel*(source_alpha + 1)
-	     if destination_alpha=0:
-		 destination_temp = 0
-	     if destination_alpha=255:
-		 destination_temp = destination_pixel*256
-	     if 255 > destination_alpha > 0:
-		 destination_temp = destination_pixel*(destination_alpha + 1)
-	     output_pixel = (source_temp + destination_temp)/256
-
-Param[3]
-^^^^^^^^
-
-width
-
-Param[4]
-^^^^^^^^
-
-height
-
-Param[5]
-^^^^^^^^
-
-destination pixel mask
-
-Param[6]
-^^^^^^^^
-
-destination rectangle start address
-
-Param[7]
-^^^^^^^^
-
-destination stride in dwords
-
-Param[8]
-^^^^^^^^
-
-source stride in dwords
-
-Param[9]
-^^^^^^^^
-
-source rectangle start address
-
-
-
-CX2341X_OSD_BLT_FILL
-~~~~~~~~~~~~~~~~~~~~
-
-Enum: 83/0x53
-
-Description
-^^^^^^^^^^^
-
-BLT fill color
-
-Param[0]
-^^^^^^^^
-
-Same as Param[0] on API 0x52
-
-Param[1]
-^^^^^^^^
-
-Same as Param[1] on API 0x52
-
-Param[2]
-^^^^^^^^
-
-Same as Param[2] on API 0x52
-
-Param[3]
-^^^^^^^^
-
-width
-
-Param[4]
-^^^^^^^^
-
-height
-
-Param[5]
-^^^^^^^^
-
-destination pixel mask
-
-Param[6]
-^^^^^^^^
-
-destination rectangle start address
-
-Param[7]
-^^^^^^^^
-
-destination stride in dwords
-
-Param[8]
-^^^^^^^^
-
-color fill value
-
-
-
-CX2341X_OSD_BLT_TEXT
-~~~~~~~~~~~~~~~~~~~~
-
-Enum: 84/0x54
-
-Description
-^^^^^^^^^^^
-
-BLT for 8 bit alpha text source
-
-Param[0]
-^^^^^^^^
-
-Same as Param[0] on API 0x52
-
-Param[1]
-^^^^^^^^
-
-Same as Param[1] on API 0x52
-
-Param[2]
-^^^^^^^^
-
-Same as Param[2] on API 0x52
-
-Param[3]
-^^^^^^^^
-
-width
-
-Param[4]
-^^^^^^^^
-
-height
-
-Param[5]
-^^^^^^^^
-
-destination pixel mask
-
-Param[6]
-^^^^^^^^
-
-destination rectangle start address
-
-Param[7]
-^^^^^^^^
-
-destination stride in dwords
-
-Param[8]
-^^^^^^^^
-
-source stride in dwords
-
-Param[9]
-^^^^^^^^
-
-source rectangle start address
-
-Param[10]
-^^^^^^^^^
-
-color fill value
-
-
-
-CX2341X_OSD_SET_FRAMEBUFFER_WINDOW
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 86/0x56
-
-Description
-^^^^^^^^^^^
-
-Positions the main output window on the screen. The coordinates must be
-such that the entire window fits on the screen.
-
-Param[0]
-^^^^^^^^
-
-window width
-
-Param[1]
-^^^^^^^^
-
-window height
-
-Param[2]
-^^^^^^^^
-
-top left window corner horizontal offset
-
-Param[3]
-^^^^^^^^
-
-top left window corner vertical offset
-
-
-
-CX2341X_OSD_SET_CHROMA_KEY
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 96/0x60
-
-Description
-^^^^^^^^^^^
-
-Chroma key switch and color
-
-Param[0]
-^^^^^^^^
-
-state: 0=off, 1=on
-
-Param[1]
-^^^^^^^^
-
-color
-
-
-
-CX2341X_OSD_GET_ALPHA_CONTENT_INDEX
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 97/0x61
-
-Description
-^^^^^^^^^^^
-
-Retrieve alpha content index
-
-Result[0]
-^^^^^^^^^
-
-alpha content index, Range 0:15
-
-
-
-CX2341X_OSD_SET_ALPHA_CONTENT_INDEX
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 98/0x62
-
-Description
-^^^^^^^^^^^
-
-Assign alpha content index
-
-Param[0]
-^^^^^^^^
-
-alpha content index, range 0:15
-
-
-Encoder firmware API description
---------------------------------
-
-CX2341X_ENC_PING_FW
-~~~~~~~~~~~~~~~~~~~
-
-Enum: 128/0x80
-
-Description
-^^^^^^^^^^^
-
-Does nothing. Can be used to check if the firmware is responding.
-
-
-
-CX2341X_ENC_START_CAPTURE
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 129/0x81
-
-Description
-^^^^^^^^^^^
-
-Commences the capture of video, audio and/or VBI data. All encoding
-parameters must be initialized prior to this API call. Captures frames
-continuously or until a predefined number of frames have been captured.
-
-Param[0]
-^^^^^^^^
-
-Capture stream type:
-
-	- 0=MPEG
-	- 1=Raw
-	- 2=Raw passthrough
-	- 3=VBI
-
-
-Param[1]
-^^^^^^^^
-
-Bitmask:
-
-	- Bit 0 when set, captures YUV
-	- Bit 1 when set, captures PCM audio
-	- Bit 2 when set, captures VBI (same as param[0]=3)
-	- Bit 3 when set, the capture destination is the decoder
-	  (same as param[0]=2)
-	- Bit 4 when set, the capture destination is the host
-
-.. note:: this parameter is only meaningful for RAW capture type.
-
-
-
-CX2341X_ENC_STOP_CAPTURE
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 130/0x82
-
-Description
-^^^^^^^^^^^
-
-Ends a capture in progress
-
-Param[0]
-^^^^^^^^
-
-- 0=stop at end of GOP (generates IRQ)
-- 1=stop immediate (no IRQ)
-
-Param[1]
-^^^^^^^^
-
-Stream type to stop, see param[0] of API 0x81
-
-Param[2]
-^^^^^^^^
-
-Subtype, see param[1] of API 0x81
-
-
-
-CX2341X_ENC_SET_AUDIO_ID
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 137/0x89
-
-Description
-^^^^^^^^^^^
-
-Assigns the transport stream ID of the encoded audio stream
-
-Param[0]
-^^^^^^^^
-
-Audio Stream ID
-
-
-
-CX2341X_ENC_SET_VIDEO_ID
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 139/0x8B
-
-Description
-^^^^^^^^^^^
-
-Set video transport stream ID
-
-Param[0]
-^^^^^^^^
-
-Video stream ID
-
-
-
-CX2341X_ENC_SET_PCR_ID
-~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 141/0x8D
-
-Description
-^^^^^^^^^^^
-
-Assigns the transport stream ID for PCR packets
-
-Param[0]
-^^^^^^^^
-
-PCR Stream ID
-
-
-
-CX2341X_ENC_SET_FRAME_RATE
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 143/0x8F
-
-Description
-^^^^^^^^^^^
-
-Set video frames per second. Change occurs at start of new GOP.
-
-Param[0]
-^^^^^^^^
-
-- 0=30fps
-- 1=25fps
-
-
-
-CX2341X_ENC_SET_FRAME_SIZE
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 145/0x91
-
-Description
-^^^^^^^^^^^
-
-Select video stream encoding resolution.
-
-Param[0]
-^^^^^^^^
-
-Height in lines. Default 480
-
-Param[1]
-^^^^^^^^
-
-Width in pixels. Default 720
-
-
-
-CX2341X_ENC_SET_BIT_RATE
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 149/0x95
-
-Description
-^^^^^^^^^^^
-
-Assign average video stream bitrate.
-
-Param[0]
-^^^^^^^^
-
-0=variable bitrate, 1=constant bitrate
-
-Param[1]
-^^^^^^^^
-
-bitrate in bits per second
-
-Param[2]
-^^^^^^^^
-
-peak bitrate in bits per second, divided by 400
-
-Param[3]
-^^^^^^^^
-
-Mux bitrate in bits per second, divided by 400. May be 0 (default).
-
-Param[4]
-^^^^^^^^
-
-Rate Control VBR Padding
-
-Param[5]
-^^^^^^^^
-
-VBV Buffer used by encoder
-
-.. note::
-
-	#) Param\[3\] and Param\[4\] seem to be always 0
-	#) Param\[5\] doesn't seem to be used.
-
-
-
-CX2341X_ENC_SET_GOP_PROPERTIES
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 151/0x97
-
-Description
-^^^^^^^^^^^
-
-Setup the GOP structure
-
-Param[0]
-^^^^^^^^
-
-GOP size (maximum is 34)
-
-Param[1]
-^^^^^^^^
-
-Number of B frames between the I and P frame, plus 1.
-For example: IBBPBBPBBPBB --> GOP size: 12, number of B frames: 2+1 = 3
-
-.. note::
-
-	GOP size must be a multiple of (B-frames + 1).
-
-
-
-CX2341X_ENC_SET_ASPECT_RATIO
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 153/0x99
-
-Description
-^^^^^^^^^^^
-
-Sets the encoding aspect ratio. Changes in the aspect ratio take effect
-at the start of the next GOP.
-
-Param[0]
-^^^^^^^^
-
-- '0000' forbidden
-- '0001' 1:1 square
-- '0010' 4:3
-- '0011' 16:9
-- '0100' 2.21:1
-- '0101' to '1111' reserved
-
-
-
-CX2341X_ENC_SET_DNR_FILTER_MODE
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 155/0x9B
-
-Description
-^^^^^^^^^^^
-
-Assign Dynamic Noise Reduction operating mode
-
-Param[0]
-^^^^^^^^
-
-Bit0: Spatial filter, set=auto, clear=manual
-Bit1: Temporal filter, set=auto, clear=manual
-
-Param[1]
-^^^^^^^^
-
-Median filter:
-
-- 0=Disabled
-- 1=Horizontal
-- 2=Vertical
-- 3=Horiz/Vert
-- 4=Diagonal
-
-
-
-CX2341X_ENC_SET_DNR_FILTER_PROPS
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 157/0x9D
-
-Description
-^^^^^^^^^^^
-
-These Dynamic Noise Reduction filter values are only meaningful when
-the respective filter is set to "manual" (See API 0x9B)
-
-Param[0]
-^^^^^^^^
-
-Spatial filter: default 0, range 0:15
-
-Param[1]
-^^^^^^^^
-
-Temporal filter: default 0, range 0:31
-
-
-
-CX2341X_ENC_SET_CORING_LEVELS
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 159/0x9F
-
-Description
-^^^^^^^^^^^
-
-Assign Dynamic Noise Reduction median filter properties.
-
-Param[0]
-^^^^^^^^
-
-Threshold above which the luminance median filter is enabled.
-Default: 0, range 0:255
-
-Param[1]
-^^^^^^^^
-
-Threshold below which the luminance median filter is enabled.
-Default: 255, range 0:255
-
-Param[2]
-^^^^^^^^
-
-Threshold above which the chrominance median filter is enabled.
-Default: 0, range 0:255
-
-Param[3]
-^^^^^^^^
-
-Threshold below which the chrominance median filter is enabled.
-Default: 255, range 0:255
-
-
-
-CX2341X_ENC_SET_SPATIAL_FILTER_TYPE
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 161/0xA1
-
-Description
-^^^^^^^^^^^
-
-Assign spatial prefilter parameters
-
-Param[0]
-^^^^^^^^
-
-Luminance filter
-
-- 0=Off
-- 1=1D Horizontal
-- 2=1D Vertical
-- 3=2D H/V Separable (default)
-- 4=2D Symmetric non-separable
-
-Param[1]
-^^^^^^^^
-
-Chrominance filter
-
-- 0=Off
-- 1=1D Horizontal (default)
-
-
-
-CX2341X_ENC_SET_VBI_LINE
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 183/0xB7
-
-Description
-^^^^^^^^^^^
-
-Selects VBI line number.
-
-Param[0]
-^^^^^^^^
-
-- Bits 0:4 	line number
-- Bit  31		0=top_field, 1=bottom_field
-- Bits 0:31 	all set specifies "all lines"
-
-Param[1]
-^^^^^^^^
-
-VBI line information features: 0=disabled, 1=enabled
-
-Param[2]
-^^^^^^^^
-
-Slicing: 0=None, 1=Closed Caption
-Almost certainly not implemented. Set to 0.
-
-Param[3]
-^^^^^^^^
-
-Luminance samples in this line.
-Almost certainly not implemented. Set to 0.
-
-Param[4]
-^^^^^^^^
-
-Chrominance samples in this line
-Almost certainly not implemented. Set to 0.
-
-
-
-CX2341X_ENC_SET_STREAM_TYPE
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 185/0xB9
-
-Description
-^^^^^^^^^^^
-
-Assign stream type
-
-.. note::
-
-	Transport stream is not working in recent firmwares.
-	And in older firmwares the timestamps in the TS seem to be
-	unreliable.
-
-Param[0]
-^^^^^^^^
-
-- 0=Program stream
-- 1=Transport stream
-- 2=MPEG1 stream
-- 3=PES A/V stream
-- 5=PES Video stream
-- 7=PES Audio stream
-- 10=DVD stream
-- 11=VCD stream
-- 12=SVCD stream
-- 13=DVD_S1 stream
-- 14=DVD_S2 stream
-
-
-
-CX2341X_ENC_SET_OUTPUT_PORT
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 187/0xBB
-
-Description
-^^^^^^^^^^^
-
-Assign stream output port. Normally 0 when the data is copied through
-the PCI bus (DMA), and 1 when the data is streamed to another chip
-(pvrusb and cx88-blackbird).
-
-Param[0]
-^^^^^^^^
-
-- 0=Memory (default)
-- 1=Streaming
-- 2=Serial
-
-Param[1]
-^^^^^^^^
-
-Unknown, but leaving this to 0 seems to work best. Indications are that
-this might have to do with USB support, although passing anything but 0
-only breaks things.
-
-
-
-CX2341X_ENC_SET_AUDIO_PROPERTIES
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 189/0xBD
-
-Description
-^^^^^^^^^^^
-
-Set audio stream properties, may be called while encoding is in progress.
-
-.. note::
-
-	All bitfields are consistent with ISO11172 documentation except
-	bits 2:3 which ISO docs define as:
-
-	- '11' Layer I
-	- '10' Layer II
-	- '01' Layer III
-	- '00' Undefined
-
-	This discrepancy may indicate a possible error in the documentation.
-	Testing indicated that only Layer II is actually working, and that
-	the minimum bitrate should be 192 kbps.
-
-Param[0]
-^^^^^^^^
-
-Bitmask:
-
-.. code-block:: none
-
-	   0:1  '00' 44.1Khz
-		'01' 48Khz
-		'10' 32Khz
-		'11' reserved
-
-	   2:3  '01'=Layer I
-		'10'=Layer II
-
-	   4:7  Bitrate:
-		     Index | Layer I     | Layer II
-		     ------+-------------+------------
-		    '0000' | free format | free format
-		    '0001' |  32 kbit/s  |  32 kbit/s
-		    '0010' |  64 kbit/s  |  48 kbit/s
-		    '0011' |  96 kbit/s  |  56 kbit/s
-		    '0100' | 128 kbit/s  |  64 kbit/s
-		    '0101' | 160 kbit/s  |  80 kbit/s
-		    '0110' | 192 kbit/s  |  96 kbit/s
-		    '0111' | 224 kbit/s  | 112 kbit/s
-		    '1000' | 256 kbit/s  | 128 kbit/s
-		    '1001' | 288 kbit/s  | 160 kbit/s
-		    '1010' | 320 kbit/s  | 192 kbit/s
-		    '1011' | 352 kbit/s  | 224 kbit/s
-		    '1100' | 384 kbit/s  | 256 kbit/s
-		    '1101' | 416 kbit/s  | 320 kbit/s
-		    '1110' | 448 kbit/s  | 384 kbit/s
-
-		.. note::
-
-			For Layer II, not all combinations of total bitrate
-			and mode are allowed. See ISO11172-3 3-Annex B,
-			Table 3-B.2
-
-	   8:9  '00'=Stereo
-		'01'=JointStereo
-		'10'=Dual
-		'11'=Mono
-
-		.. note::
-
-			The cx23415 cannot decode Joint Stereo properly.
-
-	  10:11 Mode Extension used in joint_stereo mode.
-		In Layer I and II they indicate which subbands are in
-		intensity_stereo. All other subbands are coded in stereo.
-		    '00' subbands 4-31 in intensity_stereo, bound==4
-		    '01' subbands 8-31 in intensity_stereo, bound==8
-		    '10' subbands 12-31 in intensity_stereo, bound==12
-		    '11' subbands 16-31 in intensity_stereo, bound==16
-
-	  12:13 Emphasis:
-		    '00' None
-		    '01' 50/15uS
-		    '10' reserved
-		    '11' CCITT J.17
-
-	  14 	CRC:
-		    '0' off
-		    '1' on
-
-	  15    Copyright:
-		    '0' off
-		    '1' on
-
-	  16    Generation:
-		    '0' copy
-		    '1' original
-
-
-
-CX2341X_ENC_HALT_FW
-~~~~~~~~~~~~~~~~~~~
-
-Enum: 195/0xC3
-
-Description
-^^^^^^^^^^^
-
-The firmware is halted and no further API calls are serviced until the
-firmware is uploaded again.
-
-
-
-CX2341X_ENC_GET_VERSION
-~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 196/0xC4
-
-Description
-^^^^^^^^^^^
-
-Returns the version of the encoder firmware.
-
-Result[0]
-^^^^^^^^^
-
-Version bitmask:
-- Bits  0:15 build
-- Bits 16:23 minor
-- Bits 24:31 major
-
-
-
-CX2341X_ENC_SET_GOP_CLOSURE
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 197/0xC5
-
-Description
-^^^^^^^^^^^
-
-Assigns the GOP open/close property.
-
-Param[0]
-^^^^^^^^
-
-- 0=Open
-- 1=Closed
-
-
-
-CX2341X_ENC_GET_SEQ_END
-~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 198/0xC6
-
-Description
-^^^^^^^^^^^
-
-Obtains the sequence end code of the encoder's buffer. When a capture
-is started a number of interrupts are still generated, the last of
-which will have Result[0] set to 1 and Result[1] will contain the size
-of the buffer.
-
-Result[0]
-^^^^^^^^^
-
-State of the transfer (1 if last buffer)
-
-Result[1]
-^^^^^^^^^
-
-If Result[0] is 1, this contains the size of the last buffer, undefined
-otherwise.
-
-
-
-CX2341X_ENC_SET_PGM_INDEX_INFO
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 199/0xC7
-
-Description
-^^^^^^^^^^^
-
-Sets the Program Index Information.
-The information is stored as follows:
-
-.. code-block:: c
-
-	struct info {
-		u32 length;		// Length of this frame
-		u32 offset_low;		// Offset in the file of the
-		u32 offset_high;	// start of this frame
-		u32 mask1;		// Bits 0-2 are the type mask:
-					// 1=I, 2=P, 4=B
-					// 0=End of Program Index, other fields
-					//   are invalid.
-		u32 pts;		// The PTS of the frame
-		u32 mask2;		// Bit 0 is bit 32 of the pts.
-	};
-	u32 table_ptr;
-	struct info index[400];
-
-The table_ptr is the encoder memory address in the table were
-*new* entries will be written.
-
-.. note:: This is a ringbuffer, so the table_ptr will wraparound.
-
-Param[0]
-^^^^^^^^
-
-Picture Mask:
-- 0=No index capture
-- 1=I frames
-- 3=I,P frames
-- 7=I,P,B frames
-
-(Seems to be ignored, it always indexes I, P and B frames)
-
-Param[1]
-^^^^^^^^
-
-Elements requested (up to 400)
-
-Result[0]
-^^^^^^^^^
-
-Offset in the encoder memory of the start of the table.
-
-Result[1]
-^^^^^^^^^
-
-Number of allocated elements up to a maximum of Param[1]
-
-
-
-CX2341X_ENC_SET_VBI_CONFIG
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 200/0xC8
-
-Description
-^^^^^^^^^^^
-
-Configure VBI settings
-
-Param[0]
-^^^^^^^^
-
-Bitmap:
-
-.. code-block:: none
-
-	    0    Mode '0' Sliced, '1' Raw
-	    1:3  Insertion:
-		     '000' insert in extension & user data
-		     '001' insert in private packets
-		     '010' separate stream and user data
-		     '111' separate stream and private data
-	    8:15 Stream ID (normally 0xBD)
-
-Param[1]
-^^^^^^^^
-
-Frames per interrupt (max 8). Only valid in raw mode.
-
-Param[2]
-^^^^^^^^
-
-Total raw VBI frames. Only valid in raw mode.
-
-Param[3]
-^^^^^^^^
-
-Start codes
-
-Param[4]
-^^^^^^^^
-
-Stop codes
-
-Param[5]
-^^^^^^^^
-
-Lines per frame
-
-Param[6]
-^^^^^^^^
-
-Byte per line
-
-Result[0]
-^^^^^^^^^
-
-Observed frames per interrupt in raw mode only. Rage 1 to Param[1]
-
-Result[1]
-^^^^^^^^^
-
-Observed number of frames in raw mode. Range 1 to Param[2]
-
-Result[2]
-^^^^^^^^^
-
-Memory offset to start or raw VBI data
-
-
-
-CX2341X_ENC_SET_DMA_BLOCK_SIZE
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 201/0xC9
-
-Description
-^^^^^^^^^^^
-
-Set DMA transfer block size
-
-Param[0]
-^^^^^^^^
-
-DMA transfer block size in bytes or frames. When unit is bytes,
-supported block sizes are 2^7, 2^8 and 2^9 bytes.
-
-Param[1]
-^^^^^^^^
-
-Unit: 0=bytes, 1=frames
-
-
-
-CX2341X_ENC_GET_PREV_DMA_INFO_MB_10
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 202/0xCA
-
-Description
-^^^^^^^^^^^
-
-Returns information on the previous DMA transfer in conjunction with
-bit 27 of the interrupt mask. Uses mailbox 10.
-
-Result[0]
-^^^^^^^^^
-
-Type of stream
-
-Result[1]
-^^^^^^^^^
-
-Address Offset
-
-Result[2]
-^^^^^^^^^
-
-Maximum size of transfer
-
-
-
-CX2341X_ENC_GET_PREV_DMA_INFO_MB_9
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 203/0xCB
-
-Description
-^^^^^^^^^^^
-
-Returns information on the previous DMA transfer in conjunction with
-bit 27 or 18 of the interrupt mask. Uses mailbox 9.
-
-Result[0]
-^^^^^^^^^
-
-Status bits:
-- 0   read completed
-- 1   write completed
-- 2   DMA read error
-- 3   DMA write error
-- 4   Scatter-Gather array error
-
-Result[1]
-^^^^^^^^^
-
-DMA type
-
-Result[2]
-^^^^^^^^^
-
-Presentation Time Stamp bits 0..31
-
-Result[3]
-^^^^^^^^^
-
-Presentation Time Stamp bit 32
-
-
-
-CX2341X_ENC_SCHED_DMA_TO_HOST
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 204/0xCC
-
-Description
-^^^^^^^^^^^
-
-Setup DMA to host operation
-
-Param[0]
-^^^^^^^^
-
-Memory address of link list
-
-Param[1]
-^^^^^^^^
-
-Length of link list (wtf: what units ???)
-
-Param[2]
-^^^^^^^^
-
-DMA type (0=MPEG)
-
-
-
-CX2341X_ENC_INITIALIZE_INPUT
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 205/0xCD
-
-Description
-^^^^^^^^^^^
-
-Initializes the video input
-
-
-
-CX2341X_ENC_SET_FRAME_DROP_RATE
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 208/0xD0
-
-Description
-^^^^^^^^^^^
-
-For each frame captured, skip specified number of frames.
-
-Param[0]
-^^^^^^^^
-
-Number of frames to skip
-
-
-
-CX2341X_ENC_PAUSE_ENCODER
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 210/0xD2
-
-Description
-^^^^^^^^^^^
-
-During a pause condition, all frames are dropped instead of being encoded.
-
-Param[0]
-^^^^^^^^
-
-- 0=Pause encoding
-- 1=Continue encoding
-
-
-
-CX2341X_ENC_REFRESH_INPUT
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 211/0xD3
-
-Description
-^^^^^^^^^^^
-
-Refreshes the video input
-
-
-
-CX2341X_ENC_SET_COPYRIGHT
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 212/0xD4
-
-Description
-^^^^^^^^^^^
-
-Sets stream copyright property
-
-Param[0]
-^^^^^^^^
-
-
-- 0=Stream is not copyrighted
-- 1=Stream is copyrighted
-
-
-
-CX2341X_ENC_SET_EVENT_NOTIFICATION
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 213/0xD5
-
-Description
-^^^^^^^^^^^
-
-Setup firmware to notify the host about a particular event. Host must
-unmask the interrupt bit.
-
-Param[0]
-^^^^^^^^
-
-Event (0=refresh encoder input)
-
-Param[1]
-^^^^^^^^
-
-Notification 0=disabled 1=enabled
-
-Param[2]
-^^^^^^^^
-
-Interrupt bit
-
-Param[3]
-^^^^^^^^
-
-Mailbox slot, -1 if no mailbox required.
-
-
-
-CX2341X_ENC_SET_NUM_VSYNC_LINES
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 214/0xD6
-
-Description
-^^^^^^^^^^^
-
-Depending on the analog video decoder used, this assigns the number
-of lines for field 1 and 2.
-
-Param[0]
-^^^^^^^^
-
-Field 1 number of lines:
-- 0x00EF for SAA7114
-- 0x00F0 for SAA7115
-- 0x0105 for Micronas
-
-Param[1]
-^^^^^^^^
-
-Field 2 number of lines:
-- 0x00EF for SAA7114
-- 0x00F0 for SAA7115
-- 0x0106 for Micronas
-
-
-
-CX2341X_ENC_SET_PLACEHOLDER
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 215/0xD7
-
-Description
-^^^^^^^^^^^
-
-Provides a mechanism of inserting custom user data in the MPEG stream.
-
-Param[0]
-^^^^^^^^
-
-- 0=extension & user data
-- 1=private packet with stream ID 0xBD
-
-Param[1]
-^^^^^^^^
-
-Rate at which to insert data, in units of frames (for private packet)
-or GOPs (for ext. & user data)
-
-Param[2]
-^^^^^^^^
-
-Number of data DWORDs (below) to insert
-
-Param[3]
-^^^^^^^^
-
-Custom data 0
-
-Param[4]
-^^^^^^^^
-
-Custom data 1
-
-Param[5]
-^^^^^^^^
-
-Custom data 2
-
-Param[6]
-^^^^^^^^
-
-Custom data 3
-
-Param[7]
-^^^^^^^^
-
-Custom data 4
-
-Param[8]
-^^^^^^^^
-
-Custom data 5
-
-Param[9]
-^^^^^^^^
-
-Custom data 6
-
-Param[10]
-^^^^^^^^^
-
-Custom data 7
-
-Param[11]
-^^^^^^^^^
-
-Custom data 8
-
-
-
-CX2341X_ENC_MUTE_VIDEO
-~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 217/0xD9
-
-Description
-^^^^^^^^^^^
-
-Video muting
-
-Param[0]
-^^^^^^^^
-
-Bit usage:
-
-.. code-block:: none
-
-	 0    	'0'=video not muted
-		'1'=video muted, creates frames with the YUV color defined below
-	 1:7  	Unused
-	 8:15 	V chrominance information
-	16:23 	U chrominance information
-	24:31 	Y luminance information
-
-
-
-CX2341X_ENC_MUTE_AUDIO
-~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 218/0xDA
-
-Description
-^^^^^^^^^^^
-
-Audio muting
-
-Param[0]
-^^^^^^^^
-
-- 0=audio not muted
-- 1=audio muted (produces silent mpeg audio stream)
-
-
-
-CX2341X_ENC_SET_VERT_CROP_LINE
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 219/0xDB
-
-Description
-^^^^^^^^^^^
-
-Something to do with 'Vertical Crop Line'
-
-Param[0]
-^^^^^^^^
-
-If saa7114 and raw VBI capture and 60 Hz, then set to 10001.
-Else 0.
-
-
-
-CX2341X_ENC_MISC
-~~~~~~~~~~~~~~~~
-
-Enum: 220/0xDC
-
-Description
-^^^^^^^^^^^
-
-Miscellaneous actions. Not known for 100% what it does. It's really a
-sort of ioctl call. The first parameter is a command number, the second
-the value.
-
-Param[0]
-^^^^^^^^
-
-Command number:
-
-.. code-block:: none
-
-	 1=set initial SCR value when starting encoding (works).
-	 2=set quality mode (apparently some test setting).
-	 3=setup advanced VIM protection handling.
-	   Always 1 for the cx23416 and 0 for cx23415.
-	 4=generate DVD compatible PTS timestamps
-	 5=USB flush mode
-	 6=something to do with the quantization matrix
-	 7=set navigation pack insertion for DVD: adds 0xbf (private stream 2)
-	   packets to the MPEG. The size of these packets is 2048 bytes (including
-	   the header of 6 bytes: 0x000001bf + length). The payload is zeroed and
-	   it is up to the application to fill them in. These packets are apparently
-	   inserted every four frames.
-	 8=enable scene change detection (seems to be a failure)
-	 9=set history parameters of the video input module
-	10=set input field order of VIM
-	11=set quantization matrix
-	12=reset audio interface after channel change or input switch (has no argument).
-	   Needed for the cx2584x, not needed for the mspx4xx, but it doesn't seem to
-	   do any harm calling it regardless.
-	13=set audio volume delay
-	14=set audio delay
-
-
-Param[1]
-^^^^^^^^
-
-Command value.
-
-Decoder firmware API description
---------------------------------
-
-.. note:: this API is part of the decoder firmware, so it's cx23415 only.
-
-
-
-CX2341X_DEC_PING_FW
-~~~~~~~~~~~~~~~~~~~
-
-Enum: 0/0x00
-
-Description
-^^^^^^^^^^^
-
-This API call does nothing. It may be used to check if the firmware
-is responding.
-
-
-
-CX2341X_DEC_START_PLAYBACK
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 1/0x01
-
-Description
-^^^^^^^^^^^
-
-Begin or resume playback.
-
-Param[0]
-^^^^^^^^
-
-0 based frame number in GOP to begin playback from.
-
-Param[1]
-^^^^^^^^
-
-Specifies the number of muted audio frames to play before normal
-audio resumes. (This is not implemented in the firmware, leave at 0)
-
-
-
-CX2341X_DEC_STOP_PLAYBACK
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 2/0x02
-
-Description
-^^^^^^^^^^^
-
-Ends playback and clears all decoder buffers. If PTS is not zero,
-playback stops at specified PTS.
-
-Param[0]
-^^^^^^^^
-
-Display 0=last frame, 1=black
-
-.. note::
-
-	this takes effect immediately, so if you want to wait for a PTS,
-	then use '0', otherwise the screen goes to black at once.
-	You can call this later (even if there is no playback) with a 1 value
-	to set the screen to black.
-
-Param[1]
-^^^^^^^^
-
-PTS low
-
-Param[2]
-^^^^^^^^
-
-PTS high
-
-
-
-CX2341X_DEC_SET_PLAYBACK_SPEED
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 3/0x03
-
-Description
-^^^^^^^^^^^
-
-Playback stream at speed other than normal. There are two modes of
-operation:
-
-	- Smooth: host transfers entire stream and firmware drops unused
-	  frames.
-	- Coarse: host drops frames based on indexing as required to achieve
-	  desired speed.
-
-Param[0]
-^^^^^^^^
-
-.. code-block:: none
-
-	Bitmap:
-	    0:7  0 normal
-		 1 fast only "1.5 times"
-		 n nX fast, 1/nX slow
-	    30   Framedrop:
-		     '0' during 1.5 times play, every other B frame is dropped
-		     '1' during 1.5 times play, stream is unchanged (bitrate
-			 must not exceed 8mbps)
-	    31   Speed:
-		     '0' slow
-		     '1' fast
-
-.. note::
-
-	n is limited to 2. Anything higher does not result in
-	faster playback. Instead the host should start dropping frames.
-
-Param[1]
-^^^^^^^^
-
-Direction: 0=forward, 1=reverse
-
-.. note::
-
-	to make reverse playback work you have to write full GOPs in
-	reverse order.
-
-Param[2]
-^^^^^^^^
-
-.. code-block:: none
-
-	Picture mask:
-	    1=I frames
-	    3=I, P frames
-	    7=I, P, B frames
-
-Param[3]
-^^^^^^^^
-
-B frames per GOP (for reverse play only)
-
-.. note::
-
-	for reverse playback the Picture Mask should be set to I or I, P.
-	Adding B frames to the mask will result in corrupt video. This field
-	has to be set to the correct value in order to keep the timing correct.
-
-Param[4]
-^^^^^^^^
-
-Mute audio: 0=disable, 1=enable
-
-Param[5]
-^^^^^^^^
-
-Display 0=frame, 1=field
-
-Param[6]
-^^^^^^^^
-
-Specifies the number of muted audio frames to play before normal audio
-resumes. (Not implemented in the firmware, leave at 0)
-
-
-
-CX2341X_DEC_STEP_VIDEO
-~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 5/0x05
-
-Description
-^^^^^^^^^^^
-
-Each call to this API steps the playback to the next unit defined below
-in the current playback direction.
-
-Param[0]
-^^^^^^^^
-
-0=frame, 1=top field, 2=bottom field
-
-
-
-CX2341X_DEC_SET_DMA_BLOCK_SIZE
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 8/0x08
-
-Description
-^^^^^^^^^^^
-
-Set DMA transfer block size. Counterpart to API 0xC9
-
-Param[0]
-^^^^^^^^
-
-DMA transfer block size in bytes. A different size may be specified
-when issuing the DMA transfer command.
-
-
-
-CX2341X_DEC_GET_XFER_INFO
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 9/0x09
-
-Description
-^^^^^^^^^^^
-
-This API call may be used to detect an end of stream condition.
-
-Result[0]
-^^^^^^^^^
-
-Stream type
-
-Result[1]
-^^^^^^^^^
-
-Address offset
-
-Result[2]
-^^^^^^^^^
-
-Maximum bytes to transfer
-
-Result[3]
-^^^^^^^^^
-
-Buffer fullness
-
-
-
-CX2341X_DEC_GET_DMA_STATUS
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 10/0x0A
-
-Description
-^^^^^^^^^^^
-
-Status of the last DMA transfer
-
-Result[0]
-^^^^^^^^^
-
-Bit 1 set means transfer complete
-Bit 2 set means DMA error
-Bit 3 set means linked list error
-
-Result[1]
-^^^^^^^^^
-
-DMA type: 0=MPEG, 1=OSD, 2=YUV
-
-
-
-CX2341X_DEC_SCHED_DMA_FROM_HOST
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 11/0x0B
-
-Description
-^^^^^^^^^^^
-
-Setup DMA from host operation. Counterpart to API 0xCC
-
-Param[0]
-^^^^^^^^
-
-Memory address of link list
-
-Param[1]
-^^^^^^^^
-
-Total # of bytes to transfer
-
-Param[2]
-^^^^^^^^
-
-DMA type (0=MPEG, 1=OSD, 2=YUV)
-
-
-
-CX2341X_DEC_PAUSE_PLAYBACK
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 13/0x0D
-
-Description
-^^^^^^^^^^^
-
-Freeze playback immediately. In this mode, when internal buffers are
-full, no more data will be accepted and data request IRQs will be
-masked.
-
-Param[0]
-^^^^^^^^
-
-Display: 0=last frame, 1=black
-
-
-
-CX2341X_DEC_HALT_FW
-~~~~~~~~~~~~~~~~~~~
-
-Enum: 14/0x0E
-
-Description
-^^^^^^^^^^^
-
-The firmware is halted and no further API calls are serviced until
-the firmware is uploaded again.
-
-
-
-CX2341X_DEC_SET_STANDARD
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 16/0x10
-
-Description
-^^^^^^^^^^^
-
-Selects display standard
-
-Param[0]
-^^^^^^^^
-
-0=NTSC, 1=PAL
-
-
-
-CX2341X_DEC_GET_VERSION
-~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 17/0x11
-
-Description
-^^^^^^^^^^^
-
-Returns decoder firmware version information
-
-Result[0]
-^^^^^^^^^
-
-Version bitmask:
-	- Bits  0:15 build
-	- Bits 16:23 minor
-	- Bits 24:31 major
-
-
-
-CX2341X_DEC_SET_STREAM_INPUT
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 20/0x14
-
-Description
-^^^^^^^^^^^
-
-Select decoder stream input port
-
-Param[0]
-^^^^^^^^
-
-0=memory (default), 1=streaming
-
-
-
-CX2341X_DEC_GET_TIMING_INFO
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 21/0x15
-
-Description
-^^^^^^^^^^^
-
-Returns timing information from start of playback
-
-Result[0]
-^^^^^^^^^
-
-Frame count by decode order
-
-Result[1]
-^^^^^^^^^
-
-Video PTS bits 0:31 by display order
-
-Result[2]
-^^^^^^^^^
-
-Video PTS bit 32 by display order
-
-Result[3]
-^^^^^^^^^
-
-SCR bits 0:31 by display order
-
-Result[4]
-^^^^^^^^^
-
-SCR bit 32 by display order
-
-
-
-CX2341X_DEC_SET_AUDIO_MODE
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 22/0x16
-
-Description
-^^^^^^^^^^^
-
-Select audio mode
-
-Param[0]
-^^^^^^^^
-
-Dual mono mode action
-	0=Stereo, 1=Left, 2=Right, 3=Mono, 4=Swap, -1=Unchanged
-
-Param[1]
-^^^^^^^^
-
-Stereo mode action:
-	0=Stereo, 1=Left, 2=Right, 3=Mono, 4=Swap, -1=Unchanged
-
-
-
-CX2341X_DEC_SET_EVENT_NOTIFICATION
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 23/0x17
-
-Description
-^^^^^^^^^^^
-
-Setup firmware to notify the host about a particular event.
-Counterpart to API 0xD5
-
-Param[0]
-^^^^^^^^
-
-Event:
-	- 0=Audio mode change between mono, (joint) stereo and dual channel.
-	- 3=Decoder started
-	- 4=Unknown: goes off 10-15 times per second while decoding.
-	- 5=Some sync event: goes off once per frame.
-
-Param[1]
-^^^^^^^^
-
-Notification 0=disabled, 1=enabled
-
-Param[2]
-^^^^^^^^
-
-Interrupt bit
-
-Param[3]
-^^^^^^^^
-
-Mailbox slot, -1 if no mailbox required.
-
-
-
-CX2341X_DEC_SET_DISPLAY_BUFFERS
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 24/0x18
-
-Description
-^^^^^^^^^^^
-
-Number of display buffers. To decode all frames in reverse playback you
-must use nine buffers.
-
-Param[0]
-^^^^^^^^
-
-0=six buffers, 1=nine buffers
-
-
-
-CX2341X_DEC_EXTRACT_VBI
-~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 25/0x19
-
-Description
-^^^^^^^^^^^
-
-Extracts VBI data
-
-Param[0]
-^^^^^^^^
-
-0=extract from extension & user data, 1=extract from private packets
-
-Result[0]
-^^^^^^^^^
-
-VBI table location
-
-Result[1]
-^^^^^^^^^
-
-VBI table size
-
-
-
-CX2341X_DEC_SET_DECODER_SOURCE
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 26/0x1A
-
-Description
-^^^^^^^^^^^
-
-Selects decoder source. Ensure that the parameters passed to this
-API match the encoder settings.
-
-Param[0]
-^^^^^^^^
-
-Mode: 0=MPEG from host, 1=YUV from encoder, 2=YUV from host
-
-Param[1]
-^^^^^^^^
-
-YUV picture width
-
-Param[2]
-^^^^^^^^
-
-YUV picture height
-
-Param[3]
-^^^^^^^^
-
-Bitmap: see Param[0] of API 0xBD
-
-
-
-CX2341X_DEC_SET_PREBUFFERING
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Enum: 30/0x1E
-
-Description
-^^^^^^^^^^^
-
-Decoder prebuffering, when enabled up to 128KB are buffered for
-streams <8mpbs or 640KB for streams >8mbps
-
-Param[0]
-^^^^^^^^
-
-0=off, 1=on
-
-PVR350 Video decoder registers 0x02002800 -> 0x02002B00
--------------------------------------------------------
-
-Author: Ian Armstrong <ian@iarmst.demon.co.uk>
-
-Version: v0.4
-
-Date: 12 March 2007
-
-
-This list has been worked out through trial and error. There will be mistakes
-and omissions. Some registers have no obvious effect so it's hard to say what
-they do, while others interact with each other, or require a certain load
-sequence. Horizontal filter setup is one example, with six registers working
-in unison and requiring a certain load sequence to correctly configure. The
-indexed colour palette is much easier to set at just two registers, but again
-it requires a certain load sequence.
-
-Some registers are fussy about what they are set to. Load in a bad value & the
-decoder will fail. A firmware reload will often recover, but sometimes a reset
-is required. For registers containing size information, setting them to 0 is
-generally a bad idea. For other control registers i.e. 2878, you'll only find
-out what values are bad when it hangs.
-
-.. code-block:: none
-
-	--------------------------------------------------------------------------------
-	2800
-	bit 0
-		Decoder enable
-		0 = disable
-		1 = enable
-	--------------------------------------------------------------------------------
-	2804
-	bits 0:31
-		Decoder horizontal Y alias register 1
-	---------------
-	2808
-	bits 0:31
-		Decoder horizontal Y alias register 2
-	---------------
-	280C
-	bits 0:31
-		Decoder horizontal Y alias register 3
-	---------------
-	2810
-	bits 0:31
-		Decoder horizontal Y alias register 4
-	---------------
-	2814
-	bits 0:31
-		Decoder horizontal Y alias register 5
-	---------------
-	2818
-	bits 0:31
-		Decoder horizontal Y alias trigger
-
-	These six registers control the horizontal aliasing filter for the Y plane.
-	The first five registers must all be loaded before accessing the trigger
-	(2818), as this register actually clocks the data through for the first
-	five.
-
-	To correctly program set the filter, this whole procedure must be done 16
-	times. The actual register contents are copied from a lookup-table in the
-	firmware which contains 4 different filter settings.
-
-	--------------------------------------------------------------------------------
-	281C
-	bits 0:31
-		Decoder horizontal UV alias register 1
-	---------------
-	2820
-	bits 0:31
-		Decoder horizontal UV alias register 2
-	---------------
-	2824
-	bits 0:31
-		Decoder horizontal UV alias register 3
-	---------------
-	2828
-	bits 0:31
-		Decoder horizontal UV alias register 4
-	---------------
-	282C
-	bits 0:31
-		Decoder horizontal UV alias register 5
-	---------------
-	2830
-	bits 0:31
-		Decoder horizontal UV alias trigger
-
-	These six registers control the horizontal aliasing for the UV plane.
-	Operation is the same as the Y filter, with 2830 being the trigger
-	register.
-
-	--------------------------------------------------------------------------------
-	2834
-	bits 0:15
-		Decoder Y source width in pixels
-
-	bits 16:31
-		Decoder Y destination width in pixels
-	---------------
-	2838
-	bits 0:15
-		Decoder UV source width in pixels
-
-	bits 16:31
-		Decoder UV destination width in pixels
-
-	NOTE: For both registers, the resulting image must be fully visible on
-	screen. If the image exceeds the right edge both the source and destination
-	size must be adjusted to reflect the visible portion. For the source width,
-	you must take into account the scaling when calculating the new value.
-	--------------------------------------------------------------------------------
-
-	283C
-	bits 0:31
-		Decoder Y horizontal scaling
-			Normally = Reg 2854 >> 2
-	---------------
-	2840
-	bits 0:31
-		Decoder ?? unknown - horizontal scaling
-		Usually 0x00080514
-	---------------
-	2844
-	bits 0:31
-		Decoder UV horizontal scaling
-		Normally = Reg 2854 >> 2
-	---------------
-	2848
-	bits 0:31
-		Decoder ?? unknown - horizontal scaling
-		Usually 0x00100514
-	---------------
-	284C
-	bits 0:31
-		Decoder ?? unknown - Y plane
-		Usually 0x00200020
-	---------------
-	2850
-	bits 0:31
-		Decoder ?? unknown - UV plane
-		Usually 0x00200020
-	---------------
-	2854
-	bits 0:31
-		Decoder 'master' value for horizontal scaling
-	---------------
-	2858
-	bits 0:31
-		Decoder ?? unknown
-		Usually 0
-	---------------
-	285C
-	bits 0:31
-		Decoder ?? unknown
-		Normally = Reg 2854 >> 1
-	---------------
-	2860
-	bits 0:31
-		Decoder ?? unknown
-		Usually 0
-	---------------
-	2864
-	bits 0:31
-		Decoder ?? unknown
-		Normally = Reg 2854 >> 1
-	---------------
-	2868
-	bits 0:31
-		Decoder ?? unknown
-		Usually 0
-
-	Most of these registers either control horizontal scaling, or appear linked
-	to it in some way. Register 2854 contains the 'master' value & the other
-	registers can be calculated from that one. You must also remember to
-	correctly set the divider in Reg 2874.
-
-	To enlarge:
-		Reg 2854 = (source_width * 0x00200000) / destination_width
-		Reg 2874 = No divide
-
-	To reduce from full size down to half size:
-		Reg 2854 = (source_width/2 * 0x00200000) / destination width
-		Reg 2874 = Divide by 2
-
-	To reduce from half size down to quarter size:
-		Reg 2854 = (source_width/4 * 0x00200000) / destination width
-		Reg 2874 = Divide by 4
-
-	The result is always rounded up.
-
-	--------------------------------------------------------------------------------
-	286C
-	bits 0:15
-		Decoder horizontal Y buffer offset
-
-	bits 15:31
-		Decoder horizontal UV buffer offset
-
-	Offset into the video image buffer. If the offset is gradually incremented,
-	the on screen image will move left & wrap around higher up on the right.
-
-	--------------------------------------------------------------------------------
-	2870
-	bits 0:15
-		Decoder horizontal Y output offset
-
-	bits 16:31
-		Decoder horizontal UV output offset
-
-	Offsets the actual video output. Controls output alignment of the Y & UV
-	planes. The higher the value, the greater the shift to the left. Use
-	reg 2890 to move the image right.
-
-	--------------------------------------------------------------------------------
-	2874
-	bits 0:1
-		Decoder horizontal Y output size divider
-		00 = No divide
-		01 = Divide by 2
-		10 = Divide by 3
-
-	bits 4:5
-		Decoder horizontal UV output size divider
-		00 = No divide
-		01 = Divide by 2
-		10 = Divide by 3
-
-	bit 8
-		Decoder ?? unknown
-		0 = Normal
-		1 = Affects video output levels
-
-	bit 16
-		Decoder ?? unknown
-		0 = Normal
-		1 = Disable horizontal filter
-
-	--------------------------------------------------------------------------------
-	2878
-	bit 0
-		?? unknown
-
-	bit 1
-		osd on/off
-		0 = osd off
-		1 = osd on
-
-	bit 2
-		Decoder + osd video timing
-		0 = NTSC
-		1 = PAL
-
-	bits 3:4
-		?? unknown
-
-	bit 5
-		Decoder + osd
-		Swaps upper & lower fields
-
-	--------------------------------------------------------------------------------
-	287C
-	bits 0:10
-		Decoder & osd ?? unknown
-		Moves entire screen horizontally. Starts at 0x005 with the screen
-		shifted heavily to the right. Incrementing in steps of 0x004 will
-		gradually shift the screen to the left.
-
-	bits 11:31
-		?? unknown
-
-	Normally contents are 0x00101111 (NTSC) or 0x1010111d (PAL)
-
-	--------------------------------------------------------------------------------
-	2880  --------    ?? unknown
-	2884  --------    ?? unknown
-	--------------------------------------------------------------------------------
-	2888
-	bit 0
-		Decoder + osd ?? unknown
-		0 = Normal
-		1 = Misaligned fields (Correctable through 289C & 28A4)
-
-	bit 4
-		?? unknown
-
-	bit 8
-		?? unknown
-
-	Warning: Bad values will require a firmware reload to recover.
-			Known to be bad are 0x000,0x011,0x100,0x111
-	--------------------------------------------------------------------------------
-	288C
-	bits 0:15
-		osd ?? unknown
-		Appears to affect the osd position stability. The higher the value the
-		more unstable it becomes. Decoder output remains stable.
-
-	bits 16:31
-		osd ?? unknown
-		Same as bits 0:15
-
-	--------------------------------------------------------------------------------
-	2890
-	bits 0:11
-		Decoder output horizontal offset.
-
-	Horizontal offset moves the video image right. A small left shift is
-	possible, but it's better to use reg 2870 for that due to its greater
-	range.
-
-	NOTE: Video corruption will occur if video window is shifted off the right
-	edge. To avoid this read the notes for 2834 & 2838.
-	--------------------------------------------------------------------------------
-	2894
-	bits 0:23
-		Decoder output video surround colour.
-
-	Contains the colour (in yuv) used to fill the screen when the video is
-	running in a window.
-	--------------------------------------------------------------------------------
-	2898
-	bits 0:23
-		Decoder video window colour
-		Contains the colour (in yuv) used to fill the video window when the
-		video is turned off.
-
-	bit 24
-		Decoder video output
-		0 = Video on
-		1 = Video off
-
-	bit 28
-		Decoder plane order
-		0 = Y,UV
-		1 = UV,Y
-
-	bit 29
-		Decoder second plane byte order
-		0 = Normal (UV)
-		1 = Swapped (VU)
-
-	In normal usage, the first plane is Y & the second plane is UV. Though the
-	order of the planes can be swapped, only the byte order of the second plane
-	can be swapped. This isn't much use for the Y plane, but can be useful for
-	the UV plane.
-
-	--------------------------------------------------------------------------------
-	289C
-	bits 0:15
-		Decoder vertical field offset 1
-
-	bits 16:31
-		Decoder vertical field offset 2
-
-	Controls field output vertical alignment. The higher the number, the lower
-	the image on screen. Known starting values are 0x011E0017 (NTSC) &
-	0x01500017 (PAL)
-	--------------------------------------------------------------------------------
-	28A0
-	bits 0:15
-		Decoder & osd width in pixels
-
-	bits 16:31
-		Decoder & osd height in pixels
-
-	All output from the decoder & osd are disabled beyond this area. Decoder
-	output will simply go black outside of this region. If the osd tries to
-	exceed this area it will become corrupt.
-	--------------------------------------------------------------------------------
-	28A4
-	bits 0:11
-		osd left shift.
-
-	Has a range of 0x770->0x7FF. With the exception of 0, any value outside of
-	this range corrupts the osd.
-	--------------------------------------------------------------------------------
-	28A8
-	bits 0:15
-		osd vertical field offset 1
-
-	bits 16:31
-		osd vertical field offset 2
-
-	Controls field output vertical alignment. The higher the number, the lower
-	the image on screen. Known starting values are 0x011E0017 (NTSC) &
-	0x01500017 (PAL)
-	--------------------------------------------------------------------------------
-	28AC  --------    ?? unknown
-	|
-	V
-	28BC  --------    ?? unknown
-	--------------------------------------------------------------------------------
-	28C0
-	bit 0
-		Current output field
-		0 = first field
-		1 = second field
-
-	bits 16:31
-		Current scanline
-		The scanline counts from the top line of the first field
-		through to the last line of the second field.
-	--------------------------------------------------------------------------------
-	28C4  --------    ?? unknown
-	|
-	V
-	28F8  --------    ?? unknown
-	--------------------------------------------------------------------------------
-	28FC
-	bit 0
-		?? unknown
-		0 = Normal
-		1 = Breaks decoder & osd output
-	--------------------------------------------------------------------------------
-	2900
-	bits 0:31
-		Decoder vertical Y alias register 1
-	---------------
-	2904
-	bits 0:31
-		Decoder vertical Y alias register 2
-	---------------
-	2908
-	bits 0:31
-		Decoder vertical Y alias trigger
-
-	These three registers control the vertical aliasing filter for the Y plane.
-	Operation is similar to the horizontal Y filter (2804). The only real
-	difference is that there are only two registers to set before accessing
-	the trigger register (2908). As for the horizontal filter, the values are
-	taken from a lookup table in the firmware, and the procedure must be
-	repeated 16 times to fully program the filter.
-	--------------------------------------------------------------------------------
-	290C
-	bits 0:31
-		Decoder vertical UV alias register 1
-	---------------
-	2910
-	bits 0:31
-		Decoder vertical UV alias register 2
-	---------------
-	2914
-	bits 0:31
-		Decoder vertical UV alias trigger
-
-	These three registers control the vertical aliasing filter for the UV
-	plane. Operation is the same as the Y filter, with 2914 being the trigger.
-	--------------------------------------------------------------------------------
-	2918
-	bits 0:15
-		Decoder Y source height in pixels
-
-	bits 16:31
-		Decoder Y destination height in pixels
-	---------------
-	291C
-	bits 0:15
-		Decoder UV source height in pixels divided by 2
-
-	bits 16:31
-		Decoder UV destination height in pixels
-
-	NOTE: For both registers, the resulting image must be fully visible on
-	screen. If the image exceeds the bottom edge both the source and
-	destination size must be adjusted to reflect the visible portion. For the
-	source height, you must take into account the scaling when calculating the
-	new value.
-	--------------------------------------------------------------------------------
-	2920
-	bits 0:31
-		Decoder Y vertical scaling
-		Normally = Reg 2930 >> 2
-	---------------
-	2924
-	bits 0:31
-		Decoder Y vertical scaling
-		Normally = Reg 2920 + 0x514
-	---------------
-	2928
-	bits 0:31
-		Decoder UV vertical scaling
-		When enlarging = Reg 2930 >> 2
-		When reducing = Reg 2930 >> 3
-	---------------
-	292C
-	bits 0:31
-		Decoder UV vertical scaling
-		Normally = Reg 2928 + 0x514
-	---------------
-	2930
-	bits 0:31
-		Decoder 'master' value for vertical scaling
-	---------------
-	2934
-	bits 0:31
-		Decoder ?? unknown - Y vertical scaling
-	---------------
-	2938
-	bits 0:31
-		Decoder Y vertical scaling
-		Normally = Reg 2930
-	---------------
-	293C
-	bits 0:31
-		Decoder ?? unknown - Y vertical scaling
-	---------------
-	2940
-	bits 0:31
-		Decoder UV vertical scaling
-		When enlarging = Reg 2930 >> 1
-		When reducing = Reg 2930
-	---------------
-	2944
-	bits 0:31
-		Decoder ?? unknown - UV vertical scaling
-	---------------
-	2948
-	bits 0:31
-		Decoder UV vertical scaling
-		Normally = Reg 2940
-	---------------
-	294C
-	bits 0:31
-		Decoder ?? unknown - UV vertical scaling
-
-	Most of these registers either control vertical scaling, or appear linked
-	to it in some way. Register 2930 contains the 'master' value & all other
-	registers can be calculated from that one. You must also remember to
-	correctly set the divider in Reg 296C
-
-	To enlarge:
-		Reg 2930 = (source_height * 0x00200000) / destination_height
-		Reg 296C = No divide
-
-	To reduce from full size down to half size:
-		Reg 2930 = (source_height/2 * 0x00200000) / destination height
-		Reg 296C = Divide by 2
-
-	To reduce from half down to quarter.
-		Reg 2930 = (source_height/4 * 0x00200000) / destination height
-		Reg 296C = Divide by 4
-
-	--------------------------------------------------------------------------------
-	2950
-	bits 0:15
-		Decoder Y line index into display buffer, first field
-
-	bits 16:31
-		Decoder Y vertical line skip, first field
-	--------------------------------------------------------------------------------
-	2954
-	bits 0:15
-		Decoder Y line index into display buffer, second field
-
-	bits 16:31
-		Decoder Y vertical line skip, second field
-	--------------------------------------------------------------------------------
-	2958
-	bits 0:15
-		Decoder UV line index into display buffer, first field
-
-	bits 16:31
-		Decoder UV vertical line skip, first field
-	--------------------------------------------------------------------------------
-	295C
-	bits 0:15
-		Decoder UV line index into display buffer, second field
-
-	bits 16:31
-		Decoder UV vertical line skip, second field
-	--------------------------------------------------------------------------------
-	2960
-	bits 0:15
-		Decoder destination height minus 1
-
-	bits 16:31
-		Decoder destination height divided by 2
-	--------------------------------------------------------------------------------
-	2964
-	bits 0:15
-		Decoder Y vertical offset, second field
-
-	bits 16:31
-		Decoder Y vertical offset, first field
-
-	These two registers shift the Y plane up. The higher the number, the
-	greater the shift.
-	--------------------------------------------------------------------------------
-	2968
-	bits 0:15
-		Decoder UV vertical offset, second field
-
-	bits 16:31
-		Decoder UV vertical offset, first field
-
-	These two registers shift the UV plane up. The higher the number, the
-	greater the shift.
-	--------------------------------------------------------------------------------
-	296C
-	bits 0:1
-		Decoder vertical Y output size divider
-		00 = No divide
-		01 = Divide by 2
-		10 = Divide by 4
-
-	bits 8:9
-		Decoder vertical UV output size divider
-		00 = No divide
-		01 = Divide by 2
-		10 = Divide by 4
-	--------------------------------------------------------------------------------
-	2970
-	bit 0
-		Decoder ?? unknown
-		0 = Normal
-		1 = Affect video output levels
-
-	bit 16
-		Decoder ?? unknown
-		0 = Normal
-		1 = Disable vertical filter
-
-	--------------------------------------------------------------------------------
-	2974  --------   ?? unknown
-	|
-	V
-	29EF  --------   ?? unknown
-	--------------------------------------------------------------------------------
-	2A00
-	bits 0:2
-		osd colour mode
-		000 = 8 bit indexed
-		001 = 16 bit (565)
-		010 = 15 bit (555)
-		011 = 12 bit (444)
-		100 = 32 bit (8888)
-
-	bits 4:5
-		osd display bpp
-		01 = 8 bit
-		10 = 16 bit
-		11 = 32 bit
-
-	bit 8
-		osd global alpha
-		0 = Off
-		1 = On
-
-	bit 9
-		osd local alpha
-		0 = Off
-		1 = On
-
-	bit 10
-		osd colour key
-		0 = Off
-		1 = On
-
-	bit 11
-		osd ?? unknown
-		Must be 1
-
-	bit 13
-		osd colour space
-		0 = ARGB
-		1 = AYVU
-
-	bits 16:31
-		osd ?? unknown
-		Must be 0x001B (some kind of buffer pointer ?)
-
-	When the bits-per-pixel is set to 8, the colour mode is ignored and
-	assumed to be 8 bit indexed. For 16 & 32 bits-per-pixel the colour depth
-	is honoured, and when using a colour depth that requires fewer bytes than
-	allocated the extra bytes are used as padding. So for a 32 bpp with 8 bit
-	index colour, there are 3 padding bytes per pixel. It's also possible to
-	select 16bpp with a 32 bit colour mode. This results in the pixel width
-	being doubled, but the color key will not work as expected in this mode.
-
-	Colour key is as it suggests. You designate a colour which will become
-	completely transparent. When using 565, 555 or 444 colour modes, the
-	colour key is always 16 bits wide. The colour to key on is set in Reg 2A18.
-
-	Local alpha works differently depending on the colour mode. For 32bpp & 8
-	bit indexed, local alpha is a per-pixel 256 step transparency, with 0 being
-	transparent and 255 being solid. For the 16bpp modes 555 & 444, the unused
-	bit(s) act as a simple transparency switch, with 0 being solid & 1 being
-	fully transparent. There is no local alpha support for 16bit 565.
-
-	Global alpha is a 256 step transparency that applies to the entire osd,
-	with 0 being transparent & 255 being solid.
-
-	It's possible to combine colour key, local alpha & global alpha.
-	--------------------------------------------------------------------------------
-	2A04
-	bits 0:15
-		osd x coord for left edge
-
-	bits 16:31
-		osd y coord for top edge
-	---------------
-	2A08
-	bits 0:15
-		osd x coord for right edge
-
-	bits 16:31
-		osd y coord for bottom edge
-
-	For both registers, (0,0) = top left corner of the display area. These
-	registers do not control the osd size, only where it's positioned & how
-	much is visible. The visible osd area cannot exceed the right edge of the
-	display, otherwise the osd will become corrupt. See reg 2A10 for
-	setting osd width.
-	--------------------------------------------------------------------------------
-	2A0C
-	bits 0:31
-		osd buffer index
-
-	An index into the osd buffer. Slowly incrementing this moves the osd left,
-	wrapping around onto the right edge
-	--------------------------------------------------------------------------------
-	2A10
-	bits 0:11
-		osd buffer 32 bit word width
-
-	Contains the width of the osd measured in 32 bit words. This means that all
-	colour modes are restricted to a byte width which is divisible by 4.
-	--------------------------------------------------------------------------------
-	2A14
-	bits 0:15
-		osd height in pixels
-
-	bits 16:32
-		osd line index into buffer
-		osd will start displaying from this line.
-	--------------------------------------------------------------------------------
-	2A18
-	bits 0:31
-		osd colour key
-
-	Contains the colour value which will be transparent.
-	--------------------------------------------------------------------------------
-	2A1C
-	bits 0:7
-		osd global alpha
-
-	Contains the global alpha value (equiv ivtvfbctl --alpha XX)
-	--------------------------------------------------------------------------------
-	2A20  --------    ?? unknown
-	|
-	V
-	2A2C  --------    ?? unknown
-	--------------------------------------------------------------------------------
-	2A30
-	bits 0:7
-		osd colour to change in indexed palette
-	---------------
-	2A34
-	bits 0:31
-		osd colour for indexed palette
-
-	To set the new palette, first load the index of the colour to change into
-	2A30, then load the new colour into 2A34. The full palette is 256 colours,
-	so the index range is 0x00-0xFF
-	--------------------------------------------------------------------------------
-	2A38  --------    ?? unknown
-	2A3C  --------    ?? unknown
-	--------------------------------------------------------------------------------
-	2A40
-	bits 0:31
-		osd ?? unknown
-
-	Affects overall brightness, wrapping around to black
-	--------------------------------------------------------------------------------
-	2A44
-	bits 0:31
-		osd ?? unknown
-
-	Green tint
-	--------------------------------------------------------------------------------
-	2A48
-	bits 0:31
-		osd ?? unknown
-
-	Red tint
-	--------------------------------------------------------------------------------
-	2A4C
-	bits 0:31
-		osd ?? unknown
-
-	Affects overall brightness, wrapping around to black
-	--------------------------------------------------------------------------------
-	2A50
-	bits 0:31
-		osd ?? unknown
-
-	Colour shift
-	--------------------------------------------------------------------------------
-	2A54
-	bits 0:31
-		osd ?? unknown
-
-	Colour shift
-	--------------------------------------------------------------------------------
-	2A58  --------    ?? unknown
-	|
-	V
-	2AFC  --------    ?? unknown
-	--------------------------------------------------------------------------------
-	2B00
-	bit 0
-		osd filter control
-		0 = filter off
-		1 = filter on
-
-	bits 1:4
-		osd ?? unknown
-
-	--------------------------------------------------------------------------------
-
-The cx231xx DMA engine
-----------------------
-
-
-This page describes the structures and procedures used by the cx2341x DMA
-engine.
-
-Introduction
-~~~~~~~~~~~~
-
-The cx2341x PCI interface is busmaster capable. This means it has a DMA
-engine to efficiently transfer large volumes of data between the card and main
-memory without requiring help from a CPU. Like most hardware, it must operate
-on contiguous physical memory. This is difficult to come by in large quantities
-on virtual memory machines.
-
-Therefore, it also supports a technique called "scatter-gather". The card can
-transfer multiple buffers in one operation. Instead of allocating one large
-contiguous buffer, the driver can allocate several smaller buffers.
-
-In practice, I've seen the average transfer to be roughly 80K, but transfers
-above 128K were not uncommon, particularly at startup. The 128K figure is
-important, because that is the largest block that the kernel can normally
-allocate. Even still, 128K blocks are hard to come by, so the driver writer is
-urged to choose a smaller block size and learn the scatter-gather technique.
-
-Mailbox #10 is reserved for DMA transfer information.
-
-Note: the hardware expects little-endian data ('intel format').
-
-Flow
-~~~~
-
-This section describes, in general, the order of events when handling DMA
-transfers. Detailed information follows this section.
-
-- The card raises the Encoder interrupt.
-- The driver reads the transfer type, offset and size from Mailbox #10.
-- The driver constructs the scatter-gather array from enough free dma buffers
-  to cover the size.
-- The driver schedules the DMA transfer via the ScheduleDMAtoHost API call.
-- The card raises the DMA Complete interrupt.
-- The driver checks the DMA status register for any errors.
-- The driver post-processes the newly transferred buffers.
-
-NOTE! It is possible that the Encoder and DMA Complete interrupts get raised
-simultaneously. (End of the last, start of the next, etc.)
-
-Mailbox #10
-~~~~~~~~~~~
-
-The Flags, Command, Return Value and Timeout fields are ignored.
-
-- Name:       Mailbox #10
-- Results[0]: Type: 0: MPEG.
-- Results[1]: Offset: The position relative to the card's memory space.
-- Results[2]: Size: The exact number of bytes to transfer.
-
-My speculation is that since the StartCapture API has a capture type of "RAW"
-available, that the type field will have other values that correspond to YUV
-and PCM data.
-
-Scatter-Gather Array
-~~~~~~~~~~~~~~~~~~~~
-
-The scatter-gather array is a contiguously allocated block of memory that
-tells the card the source and destination of each data-block to transfer.
-Card "addresses" are derived from the offset supplied by Mailbox #10. Host
-addresses are the physical memory location of the target DMA buffer.
-
-Each S-G array element is a struct of three 32-bit words. The first word is
-the source address, the second is the destination address. Both take up the
-entire 32 bits. The lowest 18 bits of the third word is the transfer byte
-count. The high-bit of the third word is the "last" flag. The last-flag tells
-the card to raise the DMA_DONE interrupt. From hard personal experience, if
-you forget to set this bit, the card will still "work" but the stream will
-most likely get corrupted.
-
-The transfer count must be a multiple of 256. Therefore, the driver will need
-to track how much data in the target buffer is valid and deal with it
-accordingly.
-
-Array Element:
-
-- 32-bit Source Address
-- 32-bit Destination Address
-- 14-bit reserved (high bit is the last flag)
-- 18-bit byte count
-
-DMA Transfer Status
-~~~~~~~~~~~~~~~~~~~
-
-Register 0x0004 holds the DMA Transfer Status:
-
-- bit 0:   read completed
-- bit 1:   write completed
-- bit 2:   DMA read error
-- bit 3:   DMA write error
-- bit 4:   Scatter-Gather array error
-
-Non-compressed file format
---------------------------
-
-The cx23416 can produce (and the cx23415 can also read) raw YUV output. The
-format of a YUV frame is specific to this chip and is called HM12. 'HM' stands
-for 'Hauppauge Macroblock', which is a misnomer as 'Conexant Macroblock' would
-be more accurate.
-
-The format is YUV 4:2:0 which uses 1 Y byte per pixel and 1 U and V byte per
-four pixels.
-
-The data is encoded as two macroblock planes, the first containing the Y
-values, the second containing UV macroblocks.
-
-The Y plane is divided into blocks of 16x16 pixels from left to right
-and from top to bottom. Each block is transmitted in turn, line-by-line.
-
-So the first 16 bytes are the first line of the top-left block, the
-second 16 bytes are the second line of the top-left block, etc. After
-transmitting this block the first line of the block on the right to the
-first block is transmitted, etc.
-
-The UV plane is divided into blocks of 16x8 UV values going from left
-to right, top to bottom. Each block is transmitted in turn, line-by-line.
-
-So the first 16 bytes are the first line of the top-left block and
-contain 8 UV value pairs (16 bytes in total). The second 16 bytes are the
-second line of 8 UV pairs of the top-left block, etc. After transmitting
-this block the first line of the block on the right to the first block is
-transmitted, etc.
-
-The code below is given as an example on how to convert HM12 to separate
-Y, U and V planes. This code assumes frames of 720x576 (PAL) pixels.
-
-The width of a frame is always 720 pixels, regardless of the actual specified
-width.
-
-If the height is not a multiple of 32 lines, then the captured video is
-missing macroblocks at the end and is unusable. So the height must be a
-multiple of 32.
-
-Raw format c example
-~~~~~~~~~~~~~~~~~~~~
-
-.. code-block:: c
-
-	#include <stdio.h>
-	#include <stdlib.h>
-	#include <string.h>
-
-	static unsigned char frame[576*720*3/2];
-	static unsigned char framey[576*720];
-	static unsigned char frameu[576*720 / 4];
-	static unsigned char framev[576*720 / 4];
-
-	static void de_macro_y(unsigned char* dst, unsigned char *src, int dstride, int w, int h)
-	{
-	unsigned int y, x, i;
-
-	// descramble Y plane
-	// dstride = 720 = w
-	// The Y plane is divided into blocks of 16x16 pixels
-	// Each block in transmitted in turn, line-by-line.
-	for (y = 0; y < h; y += 16) {
-		for (x = 0; x < w; x += 16) {
-		for (i = 0; i < 16; i++) {
-			memcpy(dst + x + (y + i) * dstride, src, 16);
-			src += 16;
-		}
-		}
-	}
-	}
-
-	static void de_macro_uv(unsigned char *dstu, unsigned char *dstv, unsigned char *src, int dstride, int w, int h)
-	{
-	unsigned int y, x, i;
-
-	// descramble U/V plane
-	// dstride = 720 / 2 = w
-	// The U/V values are interlaced (UVUV...).
-	// Again, the UV plane is divided into blocks of 16x16 UV values.
-	// Each block in transmitted in turn, line-by-line.
-	for (y = 0; y < h; y += 16) {
-		for (x = 0; x < w; x += 8) {
-		for (i = 0; i < 16; i++) {
-			int idx = x + (y + i) * dstride;
-
-			dstu[idx+0] = src[0];  dstv[idx+0] = src[1];
-			dstu[idx+1] = src[2];  dstv[idx+1] = src[3];
-			dstu[idx+2] = src[4];  dstv[idx+2] = src[5];
-			dstu[idx+3] = src[6];  dstv[idx+3] = src[7];
-			dstu[idx+4] = src[8];  dstv[idx+4] = src[9];
-			dstu[idx+5] = src[10]; dstv[idx+5] = src[11];
-			dstu[idx+6] = src[12]; dstv[idx+6] = src[13];
-			dstu[idx+7] = src[14]; dstv[idx+7] = src[15];
-			src += 16;
-		}
-		}
-	}
-	}
-
-	/*************************************************************************/
-	int main(int argc, char **argv)
-	{
-	FILE *fin;
-	int i;
-
-	if (argc == 1) fin = stdin;
-	else fin = fopen(argv[1], "r");
-
-	if (fin == NULL) {
-		fprintf(stderr, "cannot open input\n");
-		exit(-1);
-	}
-	while (fread(frame, sizeof(frame), 1, fin) == 1) {
-		de_macro_y(framey, frame, 720, 720, 576);
-		de_macro_uv(frameu, framev, frame + 720 * 576, 720 / 2, 720 / 2, 576 / 2);
-		fwrite(framey, sizeof(framey), 1, stdout);
-		fwrite(framev, sizeof(framev), 1, stdout);
-		fwrite(frameu, sizeof(frameu), 1, stdout);
-	}
-	fclose(fin);
-	return 0;
-	}
-
-
-Format of embedded V4L2_MPEG_STREAM_VBI_FMT_IVTV VBI data
----------------------------------------------------------
-
-Author: Hans Verkuil <hverkuil@xs4all.nl>
-
-
-This section describes the V4L2_MPEG_STREAM_VBI_FMT_IVTV format of the VBI data
-embedded in an MPEG-2 program stream. This format is in part dictated by some
-hardware limitations of the ivtv driver (the driver for the Conexant cx23415/6
-chips), in particular a maximum size for the VBI data. Anything longer is cut
-off when the MPEG stream is played back through the cx23415.
-
-The advantage of this format is it is very compact and that all VBI data for
-all lines can be stored while still fitting within the maximum allowed size.
-
-The stream ID of the VBI data is 0xBD. The maximum size of the embedded data is
-4 + 43 * 36, which is 4 bytes for a header and 2 * 18 VBI lines with a 1 byte
-header and a 42 bytes payload each. Anything beyond this limit is cut off by
-the cx23415/6 firmware. Besides the data for the VBI lines we also need 36 bits
-for a bitmask determining which lines are captured and 4 bytes for a magic cookie,
-signifying that this data package contains V4L2_MPEG_STREAM_VBI_FMT_IVTV VBI data.
-If all lines are used, then there is no longer room for the bitmask. To solve this
-two different magic numbers were introduced:
-
-'itv0': After this magic number two unsigned longs follow. Bits 0-17 of the first
-unsigned long denote which lines of the first field are captured. Bits 18-31 of
-the first unsigned long and bits 0-3 of the second unsigned long are used for the
-second field.
-
-'ITV0': This magic number assumes all VBI lines are captured, i.e. it implicitly
-implies that the bitmasks are 0xffffffff and 0xf.
-
-After these magic cookies (and the 8 byte bitmask in case of cookie 'itv0') the
-captured VBI lines start:
-
-For each line the least significant 4 bits of the first byte contain the data type.
-Possible values are shown in the table below. The payload is in the following 42
-bytes.
-
-Here is the list of possible data types:
-
-.. code-block:: c
-
-	#define IVTV_SLICED_TYPE_TELETEXT       0x1     // Teletext (uses lines 6-22 for PAL)
-	#define IVTV_SLICED_TYPE_CC             0x4     // Closed Captions (line 21 NTSC)
-	#define IVTV_SLICED_TYPE_WSS            0x5     // Wide Screen Signal (line 23 PAL)
-	#define IVTV_SLICED_TYPE_VPS            0x7     // Video Programming System (PAL) (line 16)
-
diff --git a/Documentation/media/v4l-drivers/cx23885-cardlist.rst b/Documentation/media/v4l-drivers/cx23885-cardlist.rst
deleted file mode 100644
index ddff8da98eeb..000000000000
--- a/Documentation/media/v4l-drivers/cx23885-cardlist.rst
+++ /dev/null
@@ -1,263 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-cx23885 cards list
-==================
-
-.. tabularcolumns:: |p{1.4cm}|p{11.1cm}|p{4.2cm}|
-
-.. flat-table::
-   :header-rows: 1
-   :widths: 2 19 18
-   :stub-columns: 0
-
-   * - Card number
-     - Card name
-     - PCI IDs
-
-   * - 0
-     - UNKNOWN/GENERIC
-     - 0070:3400
-
-   * - 1
-     - Hauppauge WinTV-HVR1800lp
-     - 0070:7600
-
-   * - 2
-     - Hauppauge WinTV-HVR1800
-     - 0070:7800, 0070:7801, 0070:7809
-
-   * - 3
-     - Hauppauge WinTV-HVR1250
-     - 0070:7911
-
-   * - 4
-     - DViCO FusionHDTV5 Express
-     - 18ac:d500
-
-   * - 5
-     - Hauppauge WinTV-HVR1500Q
-     - 0070:7790, 0070:7797
-
-   * - 6
-     - Hauppauge WinTV-HVR1500
-     - 0070:7710, 0070:7717
-
-   * - 7
-     - Hauppauge WinTV-HVR1200
-     - 0070:71d1, 0070:71d3
-
-   * - 8
-     - Hauppauge WinTV-HVR1700
-     - 0070:8101
-
-   * - 9
-     - Hauppauge WinTV-HVR1400
-     - 0070:8010
-
-   * - 10
-     - DViCO FusionHDTV7 Dual Express
-     - 18ac:d618
-
-   * - 11
-     - DViCO FusionHDTV DVB-T Dual Express
-     - 18ac:db78
-
-   * - 12
-     - Leadtek Winfast PxDVR3200 H
-     - 107d:6681
-
-   * - 13
-     - Compro VideoMate E650F
-     - 185b:e800
-
-   * - 14
-     - TurboSight TBS 6920
-     - 6920:8888
-
-   * - 15
-     - TeVii S470
-     - d470:9022
-
-   * - 16
-     - DVBWorld DVB-S2 2005
-     - 0001:2005
-
-   * - 17
-     - NetUP Dual DVB-S2 CI
-     - 1b55:2a2c
-
-   * - 18
-     - Hauppauge WinTV-HVR1270
-     - 0070:2211
-
-   * - 19
-     - Hauppauge WinTV-HVR1275
-     - 0070:2215, 0070:221d, 0070:22f2
-
-   * - 20
-     - Hauppauge WinTV-HVR1255
-     - 0070:2251, 0070:22f1
-
-   * - 21
-     - Hauppauge WinTV-HVR1210
-     - 0070:2291, 0070:2295, 0070:2299, 0070:229d, 0070:22f0, 0070:22f3, 0070:22f4, 0070:22f5
-
-   * - 22
-     - Mygica X8506 DMB-TH
-     - 14f1:8651
-
-   * - 23
-     - Magic-Pro ProHDTV Extreme 2
-     - 14f1:8657
-
-   * - 24
-     - Hauppauge WinTV-HVR1850
-     - 0070:8541
-
-   * - 25
-     - Compro VideoMate E800
-     - 1858:e800
-
-   * - 26
-     - Hauppauge WinTV-HVR1290
-     - 0070:8551
-
-   * - 27
-     - Mygica X8558 PRO DMB-TH
-     - 14f1:8578
-
-   * - 28
-     - LEADTEK WinFast PxTV1200
-     - 107d:6f22
-
-   * - 29
-     - GoTView X5 3D Hybrid
-     - 5654:2390
-
-   * - 30
-     - NetUP Dual DVB-T/C-CI RF
-     - 1b55:e2e4
-
-   * - 31
-     - Leadtek Winfast PxDVR3200 H XC4000
-     - 107d:6f39
-
-   * - 32
-     - MPX-885
-     -
-
-   * - 33
-     - Mygica X8502/X8507 ISDB-T
-     - 14f1:8502
-
-   * - 34
-     - TerraTec Cinergy T PCIe Dual
-     - 153b:117e
-
-   * - 35
-     - TeVii S471
-     - d471:9022
-
-   * - 36
-     - Hauppauge WinTV-HVR1255
-     - 0070:2259
-
-   * - 37
-     - Prof Revolution DVB-S2 8000
-     - 8000:3034
-
-   * - 38
-     - Hauppauge WinTV-HVR4400/HVR5500
-     - 0070:c108, 0070:c138, 0070:c1f8
-
-   * - 39
-     - AVerTV Hybrid Express Slim HC81R
-     - 1461:d939
-
-   * - 40
-     - TurboSight TBS 6981
-     - 6981:8888
-
-   * - 41
-     - TurboSight TBS 6980
-     - 6980:8888
-
-   * - 42
-     - Leadtek Winfast PxPVR2200
-     - 107d:6f21
-
-   * - 43
-     - Hauppauge ImpactVCB-e
-     - 0070:7133, 0070:7137
-
-   * - 44
-     - DViCO FusionHDTV DVB-T Dual Express2
-     - 18ac:db98
-
-   * - 45
-     - DVBSky T9580
-     - 4254:9580
-
-   * - 46
-     - DVBSky T980C
-     - 4254:980c
-
-   * - 47
-     - DVBSky S950C
-     - 4254:950c
-
-   * - 48
-     - Technotrend TT-budget CT2-4500 CI
-     - 13c2:3013
-
-   * - 49
-     - DVBSky S950
-     - 4254:0950
-
-   * - 50
-     - DVBSky S952
-     - 4254:0952
-
-   * - 51
-     - DVBSky T982
-     - 4254:0982
-
-   * - 52
-     - Hauppauge WinTV-HVR5525
-     - 0070:f038
-
-   * - 53
-     - Hauppauge WinTV Starburst
-     - 0070:c12a
-
-   * - 54
-     - ViewCast 260e
-     - 1576:0260
-
-   * - 55
-     - ViewCast 460e
-     - 1576:0460
-
-   * - 56
-     - Hauppauge WinTV-QuadHD-DVB
-     - 0070:6a28, 0070:6b28
-
-   * - 57
-     - Hauppauge WinTV-QuadHD-ATSC
-     - 0070:6a18, 0070:6b18
-
-   * - 58
-     - Hauppauge WinTV-HVR-1265(161111)
-     - 0070:2a18
-
-   * - 59
-     - Hauppauge WinTV-Starburst2
-     - 0070:f02a
-
-   * - 60
-     - Hauppauge WinTV-QuadHD-DVB(885)
-     -
-
-   * - 61
-     - Hauppauge WinTV-QuadHD-ATSC(885)
-     -
diff --git a/Documentation/media/v4l-drivers/cx88-cardlist.rst b/Documentation/media/v4l-drivers/cx88-cardlist.rst
deleted file mode 100644
index 56ee08028106..000000000000
--- a/Documentation/media/v4l-drivers/cx88-cardlist.rst
+++ /dev/null
@@ -1,379 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-CX88 cards list
-===============
-
-.. tabularcolumns:: |p{1.4cm}|p{11.1cm}|p{4.2cm}|
-
-.. flat-table::
-   :header-rows: 1
-   :widths: 2 19 18
-   :stub-columns: 0
-
-   * - Card number
-     - Card name
-     - PCI IDs
-
-   * - 0
-     - UNKNOWN/GENERIC
-     -
-
-   * - 1
-     - Hauppauge WinTV 34xxx models
-     - 0070:3400, 0070:3401
-
-   * - 2
-     - GDI Black Gold
-     - 14c7:0106, 14c7:0107
-
-   * - 3
-     - PixelView
-     - 1554:4811
-
-   * - 4
-     - ATI TV Wonder Pro
-     - 1002:00f8, 1002:00f9
-
-   * - 5
-     - Leadtek Winfast 2000XP Expert
-     - 107d:6611, 107d:6613
-
-   * - 6
-     - AverTV Studio 303 (M126)
-     - 1461:000b
-
-   * - 7
-     - MSI TV-@nywhere Master
-     - 1462:8606
-
-   * - 8
-     - Leadtek Winfast DV2000
-     - 107d:6620, 107d:6621
-
-   * - 9
-     - Leadtek PVR 2000
-     - 107d:663b, 107d:663c, 107d:6632, 107d:6630, 107d:6638, 107d:6631, 107d:6637, 107d:663d
-
-   * - 10
-     - IODATA GV-VCP3/PCI
-     - 10fc:d003
-
-   * - 11
-     - Prolink PlayTV PVR
-     -
-
-   * - 12
-     - ASUS PVR-416
-     - 1043:4823, 1461:c111
-
-   * - 13
-     - MSI TV-@nywhere
-     -
-
-   * - 14
-     - KWorld/VStream XPert DVB-T
-     - 17de:08a6
-
-   * - 15
-     - DViCO FusionHDTV DVB-T1
-     - 18ac:db00
-
-   * - 16
-     - KWorld LTV883RF
-     -
-
-   * - 17
-     - DViCO FusionHDTV 3 Gold-Q
-     - 18ac:d810, 18ac:d800
-
-   * - 18
-     - Hauppauge Nova-T DVB-T
-     - 0070:9002, 0070:9001, 0070:9000
-
-   * - 19
-     - Conexant DVB-T reference design
-     - 14f1:0187
-
-   * - 20
-     - Provideo PV259
-     - 1540:2580
-
-   * - 21
-     - DViCO FusionHDTV DVB-T Plus
-     - 18ac:db10, 18ac:db11
-
-   * - 22
-     - pcHDTV HD3000 HDTV
-     - 7063:3000
-
-   * - 23
-     - digitalnow DNTV Live! DVB-T
-     - 17de:a8a6
-
-   * - 24
-     - Hauppauge WinTV 28xxx (Roslyn) models
-     - 0070:2801
-
-   * - 25
-     - Digital-Logic MICROSPACE Entertainment Center (MEC)
-     - 14f1:0342
-
-   * - 26
-     - IODATA GV/BCTV7E
-     - 10fc:d035
-
-   * - 27
-     - PixelView PlayTV Ultra Pro (Stereo)
-     -
-
-   * - 28
-     - DViCO FusionHDTV 3 Gold-T
-     - 18ac:d820
-
-   * - 29
-     - ADS Tech Instant TV DVB-T PCI
-     - 1421:0334
-
-   * - 30
-     - TerraTec Cinergy 1400 DVB-T
-     - 153b:1166
-
-   * - 31
-     - DViCO FusionHDTV 5 Gold
-     - 18ac:d500
-
-   * - 32
-     - AverMedia UltraTV Media Center PCI 550
-     - 1461:8011
-
-   * - 33
-     - Kworld V-Stream Xpert DVD
-     -
-
-   * - 34
-     - ATI HDTV Wonder
-     - 1002:a101
-
-   * - 35
-     - WinFast DTV1000-T
-     - 107d:665f
-
-   * - 36
-     - AVerTV 303 (M126)
-     - 1461:000a
-
-   * - 37
-     - Hauppauge Nova-S-Plus DVB-S
-     - 0070:9201, 0070:9202
-
-   * - 38
-     - Hauppauge Nova-SE2 DVB-S
-     - 0070:9200
-
-   * - 39
-     - KWorld DVB-S 100
-     - 17de:08b2, 1421:0341
-
-   * - 40
-     - Hauppauge WinTV-HVR1100 DVB-T/Hybrid
-     - 0070:9400, 0070:9402
-
-   * - 41
-     - Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profile)
-     - 0070:9800, 0070:9802
-
-   * - 42
-     - digitalnow DNTV Live! DVB-T Pro
-     - 1822:0025, 1822:0019
-
-   * - 43
-     - KWorld/VStream XPert DVB-T with cx22702
-     - 17de:08a1, 12ab:2300
-
-   * - 44
-     - DViCO FusionHDTV DVB-T Dual Digital
-     - 18ac:db50, 18ac:db54
-
-   * - 45
-     - KWorld HardwareMpegTV XPert
-     - 17de:0840, 1421:0305
-
-   * - 46
-     - DViCO FusionHDTV DVB-T Hybrid
-     - 18ac:db40, 18ac:db44
-
-   * - 47
-     - pcHDTV HD5500 HDTV
-     - 7063:5500
-
-   * - 48
-     - Kworld MCE 200 Deluxe
-     - 17de:0841
-
-   * - 49
-     - PixelView PlayTV P7000
-     - 1554:4813
-
-   * - 50
-     - NPG Tech Real TV FM Top 10
-     - 14f1:0842
-
-   * - 51
-     - WinFast DTV2000 H
-     - 107d:665e
-
-   * - 52
-     - Geniatech DVB-S
-     - 14f1:0084
-
-   * - 53
-     - Hauppauge WinTV-HVR3000 TriMode Analog/DVB-S/DVB-T
-     - 0070:1404, 0070:1400, 0070:1401, 0070:1402
-
-   * - 54
-     - Norwood Micro TV Tuner
-     -
-
-   * - 55
-     - Shenzhen Tungsten Ages Tech TE-DTV-250 / Swann OEM
-     - c180:c980
-
-   * - 56
-     - Hauppauge WinTV-HVR1300 DVB-T/Hybrid MPEG Encoder
-     - 0070:9600, 0070:9601, 0070:9602
-
-   * - 57
-     - ADS Tech Instant Video PCI
-     - 1421:0390
-
-   * - 58
-     - Pinnacle PCTV HD 800i
-     - 11bd:0051
-
-   * - 59
-     - DViCO FusionHDTV 5 PCI nano
-     - 18ac:d530
-
-   * - 60
-     - Pinnacle Hybrid PCTV
-     - 12ab:1788
-
-   * - 61
-     - Leadtek TV2000 XP Global
-     - 107d:6f18, 107d:6618, 107d:6619
-
-   * - 62
-     - PowerColor RA330
-     - 14f1:ea3d
-
-   * - 63
-     - Geniatech X8000-MT DVBT
-     - 14f1:8852
-
-   * - 64
-     - DViCO FusionHDTV DVB-T PRO
-     - 18ac:db30
-
-   * - 65
-     - DViCO FusionHDTV 7 Gold
-     - 18ac:d610
-
-   * - 66
-     - Prolink Pixelview MPEG 8000GT
-     - 1554:4935
-
-   * - 67
-     - Kworld PlusTV HD PCI 120 (ATSC 120)
-     - 17de:08c1
-
-   * - 68
-     - Hauppauge WinTV-HVR4000 DVB-S/S2/T/Hybrid
-     - 0070:6900, 0070:6904, 0070:6902
-
-   * - 69
-     - Hauppauge WinTV-HVR4000(Lite) DVB-S/S2
-     - 0070:6905, 0070:6906
-
-   * - 70
-     - TeVii S460 DVB-S/S2
-     - d460:9022
-
-   * - 71
-     - Omicom SS4 DVB-S/S2 PCI
-     - A044:2011
-
-   * - 72
-     - TBS 8920 DVB-S/S2
-     - 8920:8888
-
-   * - 73
-     - TeVii S420 DVB-S
-     - d420:9022
-
-   * - 74
-     - Prolink Pixelview Global Extreme
-     - 1554:4976
-
-   * - 75
-     - PROF 7300 DVB-S/S2
-     - B033:3033
-
-   * - 76
-     - SATTRADE ST4200 DVB-S/S2
-     - b200:4200
-
-   * - 77
-     - TBS 8910 DVB-S
-     - 8910:8888
-
-   * - 78
-     - Prof 6200 DVB-S
-     - b022:3022
-
-   * - 79
-     - Terratec Cinergy HT PCI MKII
-     - 153b:1177
-
-   * - 80
-     - Hauppauge WinTV-IR Only
-     - 0070:9290
-
-   * - 81
-     - Leadtek WinFast DTV1800 Hybrid
-     - 107d:6654
-
-   * - 82
-     - WinFast DTV2000 H rev. J
-     - 107d:6f2b
-
-   * - 83
-     - Prof 7301 DVB-S/S2
-     - b034:3034
-
-   * - 84
-     - Samsung SMT 7020 DVB-S
-     - 18ac:dc00, 18ac:dccd
-
-   * - 85
-     - Twinhan VP-1027 DVB-S
-     - 1822:0023
-
-   * - 86
-     - TeVii S464 DVB-S/S2
-     - d464:9022
-
-   * - 87
-     - Leadtek WinFast DTV2000 H PLUS
-     - 107d:6f42
-
-   * - 88
-     - Leadtek WinFast DTV1800 H (XC4000)
-     - 107d:6f38
-
-   * - 89
-     - Leadtek TV2000 XP Global (SC4100)
-     - 107d:6f36
-
-   * - 90
-     - Leadtek TV2000 XP Global (XC4100)
-     - 107d:6f43
diff --git a/Documentation/media/v4l-drivers/cx88.rst b/Documentation/media/v4l-drivers/cx88.rst
deleted file mode 100644
index 698c73ea2e36..000000000000
--- a/Documentation/media/v4l-drivers/cx88.rst
+++ /dev/null
@@ -1,165 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-The cx88 driver
-===============
-
-Author:  Gerd Hoffmann
-
-This is a v4l2 device driver for the cx2388x chip.
-
-
-Current status
---------------
-
-video
-	- Works.
-	- Overlay isn't supported.
-
-audio
-	- Works. The TV standard detection is made by the driver, as the
-	  hardware has bugs to auto-detect.
-	- audio data dma (i.e. recording without loopback cable to the
-	  sound card) is supported via cx88-alsa.
-
-vbi
-	- Works.
-
-
-How to add support for new cards
---------------------------------
-
-The driver needs some config info for the TV cards.  This stuff is in
-cx88-cards.c.  If the driver doesn't work well you likely need a new
-entry for your card in that file.  Check the kernel log (using dmesg)
-to see whenever the driver knows your card or not.  There is a line
-like this one:
-
-.. code-block:: none
-
-	cx8800[0]: subsystem: 0070:3400, board: Hauppauge WinTV \
-		34xxx models [card=1,autodetected]
-
-If your card is listed as "board: UNKNOWN/GENERIC" it is unknown to
-the driver.  What to do then?
-
-1) Try upgrading to the latest snapshot, maybe it has been added
-   meanwhile.
-2) You can try to create a new entry yourself, have a look at
-   cx88-cards.c.  If that worked, mail me your changes as unified
-   diff ("diff -u").
-3) Or you can mail me the config information.  We need at least the
-   following information to add the card:
-
-     - the PCI Subsystem ID ("0070:3400" from the line above,
-       "lspci -v" output is fine too).
-     - the tuner type used by the card.  You can try to find one by
-       trial-and-error using the tuner=<n> insmod option.  If you
-       know which one the card has you can also have a look at the
-       list in CARDLIST.tuner
-
-Documentation missing at the cx88 datasheet
--------------------------------------------
-
-MO_OUTPUT_FORMAT (0x310164)
-
-.. code-block:: none
-
-  Previous default from DScaler: 0x1c1f0008
-  Digit 8: 31-28
-  28: PREVREMOD = 1
-
-  Digit 7: 27-24 (0xc = 12 = b1100 )
-  27: COMBALT = 1
-  26: PAL_INV_PHASE
-    (DScaler apparently set this to 1, resulted in sucky picture)
-
-  Digits 6,5: 23-16
-  25-16: COMB_RANGE = 0x1f [default] (9 bits -> max 512)
-
-  Digit 4: 15-12
-  15: DISIFX = 0
-  14: INVCBF = 0
-  13: DISADAPT = 0
-  12: NARROWADAPT = 0
-
-  Digit 3: 11-8
-  11: FORCE2H
-  10: FORCEREMD
-  9: NCHROMAEN
-  8: NREMODEN
-
-  Digit 2: 7-4
-  7-6: YCORE
-  5-4: CCORE
-
-  Digit 1: 3-0
-  3: RANGE = 1
-  2: HACTEXT
-  1: HSFMT
-
-0x47 is the sync byte for MPEG-2 transport stream packets.
-Datasheet incorrectly states to use 47 decimal. 188 is the length.
-All DVB compliant frontends output packets with this start code.
-
-Hauppauge WinTV cx88 IR information
------------------------------------
-
-The controls for the mux are GPIO [0,1] for source, and GPIO 2 for muting.
-
-====== ======== =================================================
-GPIO0  GPIO1
-====== ======== =================================================
-  0        0    TV Audio
-  1        0    FM radio
-  0        1    Line-In
-  1        1    Mono tuner bypass or CD passthru (tuner specific)
-====== ======== =================================================
-
-GPIO 16(I believe) is tied to the IR port (if present).
-
-
-From the data sheet:
-
-- Register 24'h20004  PCI Interrupt Status
-
- - bit [18]  IR_SMP_INT Set when 32 input samples have been collected over
- - gpio[16] pin into GP_SAMPLE register.
-
-What's missing from the data sheet:
-
-- Setup 4KHz sampling rate (roughly 2x oversampled; good enough for our RC5
-  compat remote)
-- set register 0x35C050 to  0xa80a80
-- enable sampling
-- set register 0x35C054 to 0x5
-- enable the IRQ bit 18 in the interrupt mask register (and
-  provide for a handler)
-
-GP_SAMPLE register is at 0x35C058
-
-Bits are then right shifted into the GP_SAMPLE register at the specified
-rate; you get an interrupt when a full DWORD is received.
-You need to recover the actual RC5 bits out of the (oversampled) IR sensor
-bits. (Hint: look for the 0/1and 1/0 crossings of the RC5 bi-phase data)  An
-actual raw RC5 code will span 2-3 DWORDS, depending on the actual alignment.
-
-I'm pretty sure when no IR signal is present the receiver is always in a
-marking state(1); but stray light, etc can cause intermittent noise values
-as well.  Remember, this is a free running sample of the IR receiver state
-over time, so don't assume any sample starts at any particular place.
-
-Additional info
-~~~~~~~~~~~~~~~
-
-This data sheet (google search) seems to have a lovely description of the
-RC5 basics:
-http://www.atmel.com/dyn/resources/prod_documents/doc2817.pdf
-
-This document has more data:
-http://www.nenya.be/beor/electronics/rc5.htm
-
-This document has a  how to decode a bi-phase data stream:
-http://www.ee.washington.edu/circuit_archive/text/ir_decode.txt
-
-This document has still more info:
-http://www.xs4all.nl/~sbp/knowledge/ir/rc5.htm
diff --git a/Documentation/media/v4l-drivers/davinci-vpbe.rst b/Documentation/media/v4l-drivers/davinci-vpbe.rst
deleted file mode 100644
index 0fde433e5c71..000000000000
--- a/Documentation/media/v4l-drivers/davinci-vpbe.rst
+++ /dev/null
@@ -1,97 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-The VPBE V4L2 driver design
-===========================
-
-File partitioning
------------------
-
- V4L2 display device driver
-         drivers/media/platform/davinci/vpbe_display.c
-         drivers/media/platform/davinci/vpbe_display.h
-
- VPBE display controller
-         drivers/media/platform/davinci/vpbe.c
-         drivers/media/platform/davinci/vpbe.h
-
- VPBE venc sub device driver
-         drivers/media/platform/davinci/vpbe_venc.c
-         drivers/media/platform/davinci/vpbe_venc.h
-         drivers/media/platform/davinci/vpbe_venc_regs.h
-
- VPBE osd driver
-         drivers/media/platform/davinci/vpbe_osd.c
-         drivers/media/platform/davinci/vpbe_osd.h
-         drivers/media/platform/davinci/vpbe_osd_regs.h
-
-Functional partitioning
------------------------
-
-Consists of the following (in the same order as the list under file
-partitioning):
-
- 1. V4L2 display driver
-    Implements creation of video2 and video3 device nodes and
-    provides v4l2 device interface to manage VID0 and VID1 layers.
-
- 2. Display controller
-    Loads up VENC, OSD and external encoders such as ths8200. It provides
-    a set of API calls to V4L2 drivers to set the output/standards
-    in the VENC or external sub devices. It also provides
-    a device object to access the services from OSD subdevice
-    using sub device ops. The connection of external encoders to VENC LCD
-    controller port is done at init time based on default output and standard
-    selection or at run time when application change the output through
-    V4L2 IOCTLs.
-
-    When connected to an external encoder, vpbe controller is also responsible
-    for setting up the interface between VENC and external encoders based on
-    board specific settings (specified in board-xxx-evm.c). This allows
-    interfacing external encoders such as ths8200. The setup_if_config()
-    is implemented for this as well as configure_venc() (part of the next patch)
-    API to set timings in VENC for a specific display resolution. As of this
-    patch series, the interconnection and enabling and setting of the external
-    encoders is not present, and would be a part of the next patch series.
-
- 3. VENC subdevice module
-    Responsible for setting outputs provided through internal DACs and also
-    setting timings at LCD controller port when external encoders are connected
-    at the port or LCD panel timings required. When external encoder/LCD panel
-    is connected, the timings for a specific standard/preset is retrieved from
-    the board specific table and the values are used to set the timings in
-    venc using non-standard timing mode.
-
-    Support LCD Panel displays using the VENC. For example to support a Logic
-    PD display, it requires setting up the LCD controller port with a set of
-    timings for the resolution supported and setting the dot clock. So we could
-    add the available outputs as a board specific entry (i.e add the "LogicPD"
-    output name to board-xxx-evm.c). A table of timings for various LCDs
-    supported can be maintained in the board specific setup file to support
-    various LCD displays.As of this patch a basic driver is present, and this
-    support for external encoders and displays forms a part of the next
-    patch series.
-
- 4. OSD module
-    OSD module implements all OSD layer management and hardware specific
-    features. The VPBE module interacts with the OSD for enabling and
-    disabling appropriate features of the OSD.
-
-Current status
---------------
-
-A fully functional working version of the V4L2 driver is available. This
-driver has been tested with NTSC and PAL standards and buffer streaming.
-
-To be done
-----------
-
-vpbe display controller
-    - Add support for external encoders.
-    - add support for selecting external encoder as default at probe time.
-
-vpbe venc sub device
-    - add timings for supporting ths8200
-    - add support for LogicPD LCD.
-
-FB drivers
-    - Add support for fbdev drivers.- Ready and part of subsequent patches.
diff --git a/Documentation/media/v4l-drivers/em28xx-cardlist.rst b/Documentation/media/v4l-drivers/em28xx-cardlist.rst
deleted file mode 100644
index 2956cbdc28e0..000000000000
--- a/Documentation/media/v4l-drivers/em28xx-cardlist.rst
+++ /dev/null
@@ -1,428 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-EM28xx cards list
-=================
-
-.. tabularcolumns:: |p{1.4cm}|p{10.0cm}|p{1.9cm}|p{4.2cm}|
-
-.. flat-table::
-   :header-rows: 1
-   :widths: 2 12 3 16
-   :stub-columns: 0
-
-   * - Card number
-     - Card name
-     - Empia Chip
-     - USB IDs
-   * - 0
-     - Unknown EM2800 video grabber
-     - em2800
-     - eb1a:2800
-   * - 1
-     - Unknown EM2750/28xx video grabber
-     - em2820 or em2840
-     - eb1a:2710, eb1a:2820, eb1a:2821, eb1a:2860, eb1a:2861, eb1a:2862, eb1a:2863, eb1a:2870, eb1a:2881, eb1a:2883, eb1a:2868, eb1a:2875
-   * - 2
-     - Terratec Cinergy 250 USB
-     - em2820 or em2840
-     - 0ccd:0036
-   * - 3
-     - Pinnacle PCTV USB 2
-     - em2820 or em2840
-     - 2304:0208
-   * - 4
-     - Hauppauge WinTV USB 2
-     - em2820 or em2840
-     - 2040:4200, 2040:4201
-   * - 5
-     - MSI VOX USB 2.0
-     - em2820 or em2840
-     -
-   * - 6
-     - Terratec Cinergy 200 USB
-     - em2800
-     -
-   * - 7
-     - Leadtek Winfast USB II
-     - em2800
-     - 0413:6023
-   * - 8
-     - Kworld USB2800
-     - em2800
-     -
-   * - 9
-     - Pinnacle Dazzle DVC 90/100/101/107 / Kaiser Baas Video to DVD maker / Kworld DVD Maker 2 / Plextor ConvertX PX-AV100U
-     - em2820 or em2840
-     - 1b80:e302, 1b80:e304, 2304:0207, 2304:021a, 093b:a003
-   * - 10
-     - Hauppauge WinTV HVR 900
-     - em2880
-     - 2040:6500
-   * - 11
-     - Terratec Hybrid XS
-     - em2880
-     -
-   * - 12
-     - Kworld PVR TV 2800 RF
-     - em2820 or em2840
-     -
-   * - 13
-     - Terratec Prodigy XS
-     - em2880
-     -
-   * - 14
-     - SIIG AVTuner-PVR / Pixelview Prolink PlayTV USB 2.0
-     - em2820 or em2840
-     -
-   * - 15
-     - V-Gear PocketTV
-     - em2800
-     -
-   * - 16
-     - Hauppauge WinTV HVR 950
-     - em2883
-     - 2040:6513, 2040:6517, 2040:651b
-   * - 17
-     - Pinnacle PCTV HD Pro Stick
-     - em2880
-     - 2304:0227
-   * - 18
-     - Hauppauge WinTV HVR 900 (R2)
-     - em2880
-     - 2040:6502
-   * - 19
-     - EM2860/SAA711X Reference Design
-     - em2860
-     -
-   * - 20
-     - AMD ATI TV Wonder HD 600
-     - em2880
-     - 0438:b002
-   * - 21
-     - eMPIA Technology, Inc. GrabBeeX+ Video Encoder
-     - em2800
-     - eb1a:2801
-   * - 22
-     - EM2710/EM2750/EM2751 webcam grabber
-     - em2750
-     - eb1a:2750, eb1a:2751
-   * - 23
-     - Huaqi DLCW-130
-     - em2750
-     -
-   * - 24
-     - D-Link DUB-T210 TV Tuner
-     - em2820 or em2840
-     - 2001:f112
-   * - 25
-     - Gadmei UTV310
-     - em2820 or em2840
-     -
-   * - 26
-     - Hercules Smart TV USB 2.0
-     - em2820 or em2840
-     -
-   * - 27
-     - Pinnacle PCTV USB 2 (Philips FM1216ME)
-     - em2820 or em2840
-     -
-   * - 28
-     - Leadtek Winfast USB II Deluxe
-     - em2820 or em2840
-     -
-   * - 29
-     - EM2860/TVP5150 Reference Design
-     - em2860
-     - eb1a:5051
-   * - 30
-     - Videology 20K14XUSB USB2.0
-     - em2820 or em2840
-     -
-   * - 31
-     - Usbgear VD204v9
-     - em2821
-     -
-   * - 32
-     - Supercomp USB 2.0 TV
-     - em2821
-     -
-   * - 33
-     - Elgato Video Capture
-     - em2860
-     - 0fd9:0033
-   * - 34
-     - Terratec Cinergy A Hybrid XS
-     - em2860
-     - 0ccd:004f
-   * - 35
-     - Typhoon DVD Maker
-     - em2860
-     -
-   * - 36
-     - NetGMBH Cam
-     - em2860
-     -
-   * - 37
-     - Gadmei UTV330
-     - em2860
-     - eb1a:50a6
-   * - 38
-     - Yakumo MovieMixer
-     - em2861
-     -
-   * - 39
-     - KWorld PVRTV 300U
-     - em2861
-     - eb1a:e300
-   * - 40
-     - Plextor ConvertX PX-TV100U
-     - em2861
-     - 093b:a005
-   * - 41
-     - Kworld 350 U DVB-T
-     - em2870
-     - eb1a:e350
-   * - 42
-     - Kworld 355 U DVB-T
-     - em2870
-     - eb1a:e355, eb1a:e357, eb1a:e359
-   * - 43
-     - Terratec Cinergy T XS
-     - em2870
-     -
-   * - 44
-     - Terratec Cinergy T XS (MT2060)
-     - em2870
-     - 0ccd:0043
-   * - 45
-     - Pinnacle PCTV DVB-T
-     - em2870
-     -
-   * - 46
-     - Compro, VideoMate U3
-     - em2870
-     - 185b:2870
-   * - 47
-     - KWorld DVB-T 305U
-     - em2880
-     - eb1a:e305
-   * - 48
-     - KWorld DVB-T 310U
-     - em2880
-     -
-   * - 49
-     - MSI DigiVox A/D
-     - em2880
-     - eb1a:e310
-   * - 50
-     - MSI DigiVox A/D II
-     - em2880
-     - eb1a:e320
-   * - 51
-     - Terratec Hybrid XS Secam
-     - em2880
-     - 0ccd:004c
-   * - 52
-     - DNT DA2 Hybrid
-     - em2881
-     -
-   * - 53
-     - Pinnacle Hybrid Pro
-     - em2881
-     -
-   * - 54
-     - Kworld VS-DVB-T 323UR
-     - em2882
-     - eb1a:e323
-   * - 55
-     - Terratec Cinergy Hybrid T USB XS (em2882)
-     - em2882
-     - 0ccd:005e, 0ccd:0042
-   * - 56
-     - Pinnacle Hybrid Pro (330e)
-     - em2882
-     - 2304:0226
-   * - 57
-     - Kworld PlusTV HD Hybrid 330
-     - em2883
-     - eb1a:a316
-   * - 58
-     - Compro VideoMate ForYou/Stereo
-     - em2820 or em2840
-     - 185b:2041
-   * - 59
-     - Pinnacle PCTV HD Mini
-     - em2874
-     - 2304:023f
-   * - 60
-     - Hauppauge WinTV HVR 850
-     - em2883
-     - 2040:651f
-   * - 61
-     - Pixelview PlayTV Box 4 USB 2.0
-     - em2820 or em2840
-     -
-   * - 62
-     - Gadmei TVR200
-     - em2820 or em2840
-     -
-   * - 63
-     - Kaiomy TVnPC U2
-     - em2860
-     - eb1a:e303
-   * - 64
-     - Easy Cap Capture DC-60
-     - em2860
-     - 1b80:e309
-   * - 65
-     - IO-DATA GV-MVP/SZ
-     - em2820 or em2840
-     - 04bb:0515
-   * - 66
-     - Empire dual TV
-     - em2880
-     -
-   * - 67
-     - Terratec Grabby
-     - em2860
-     - 0ccd:0096, 0ccd:10AF
-   * - 68
-     - Terratec AV350
-     - em2860
-     - 0ccd:0084
-   * - 69
-     - KWorld ATSC 315U HDTV TV Box
-     - em2882
-     - eb1a:a313
-   * - 70
-     - Evga inDtube
-     - em2882
-     -
-   * - 71
-     - Silvercrest Webcam 1.3mpix
-     - em2820 or em2840
-     -
-   * - 72
-     - Gadmei UTV330+
-     - em2861
-     -
-   * - 73
-     - Reddo DVB-C USB TV Box
-     - em2870
-     -
-   * - 74
-     - Actionmaster/LinXcel/Digitus VC211A
-     - em2800
-     -
-   * - 75
-     - Dikom DK300
-     - em2882
-     -
-   * - 76
-     - KWorld PlusTV 340U or UB435-Q (ATSC)
-     - em2870
-     - 1b80:a340
-   * - 77
-     - EM2874 Leadership ISDBT
-     - em2874
-     -
-   * - 78
-     - PCTV nanoStick T2 290e
-     - em28174
-     - 2013:024f
-   * - 79
-     - Terratec Cinergy H5
-     - em2884
-     - eb1a:2885, 0ccd:10a2, 0ccd:10ad, 0ccd:10b6
-   * - 80
-     - PCTV DVB-S2 Stick (460e)
-     - em28174
-     - 2013:024c
-   * - 81
-     - Hauppauge WinTV HVR 930C
-     - em2884
-     - 2040:1605
-   * - 82
-     - Terratec Cinergy HTC Stick
-     - em2884
-     - 0ccd:00b2
-   * - 83
-     - Honestech Vidbox NW03
-     - em2860
-     - eb1a:5006
-   * - 84
-     - MaxMedia UB425-TC
-     - em2874
-     - 1b80:e425
-   * - 85
-     - PCTV QuatroStick (510e)
-     - em2884
-     - 2304:0242
-   * - 86
-     - PCTV QuatroStick nano (520e)
-     - em2884
-     - 2013:0251
-   * - 87
-     - Terratec Cinergy HTC USB XS
-     - em2884
-     - 0ccd:008e, 0ccd:00ac
-   * - 88
-     - C3 Tech Digital Duo HDTV/SDTV USB
-     - em2884
-     - 1b80:e755
-   * - 89
-     - Delock 61959
-     - em2874
-     - 1b80:e1cc
-   * - 90
-     - KWorld USB ATSC TV Stick UB435-Q V2
-     - em2874
-     - 1b80:e346
-   * - 91
-     - SpeedLink Vicious And Devine Laplace webcam
-     - em2765
-     - 1ae7:9003, 1ae7:9004
-   * - 92
-     - PCTV DVB-S2 Stick (461e)
-     - em28178
-     - 2013:0258
-   * - 93
-     - KWorld USB ATSC TV Stick UB435-Q V3
-     - em2874
-     - 1b80:e34c
-   * - 94
-     - PCTV tripleStick (292e)
-     - em28178
-     - 2013:025f, 2013:0264, 2040:0264, 2040:8264, 2040:8268, 2040:8268
-   * - 95
-     - Leadtek VC100
-     - em2861
-     - 0413:6f07
-   * - 96
-     - Terratec Cinergy T2 Stick HD
-     - em28178
-     - eb1a:8179
-   * - 97
-     - Elgato EyeTV Hybrid 2008 INT
-     - em2884
-     - 0fd9:0018
-   * - 98
-     - PLEX PX-BCUD
-     - em28178
-     - 3275:0085
-   * - 99
-     - Hauppauge WinTV-dualHD DVB
-     - em28174
-     - 2040:0265, 2040:8265
-   * - 100
-     - Hauppauge WinTV-dualHD 01595 ATSC/QAM
-     - em28174
-     - 2040:026d, 2040:826d
-   * - 101
-     - Terratec Cinergy H6 rev. 2
-     - em2884
-     - 0ccd:10b2
-   * - 102
-     - :ZOLID HYBRID TV STICK
-     - em2882
-     -
diff --git a/Documentation/media/v4l-drivers/fimc.rst b/Documentation/media/v4l-drivers/fimc.rst
deleted file mode 100644
index 74585ba48b7f..000000000000
--- a/Documentation/media/v4l-drivers/fimc.rst
+++ /dev/null
@@ -1,171 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-.. include:: <isonum.txt>
-
-The Samsung S5P/EXYNOS4 FIMC driver
-===================================
-
-Copyright |copy| 2012 - 2013 Samsung Electronics Co., Ltd.
-
-The FIMC (Fully Interactive Mobile Camera) device available in Samsung
-SoC Application Processors is an integrated camera host interface, color
-space converter, image resizer and rotator.  It's also capable of capturing
-data from LCD controller (FIMD) through the SoC internal writeback data
-path.  There are multiple FIMC instances in the SoCs (up to 4), having
-slightly different capabilities, like pixel alignment constraints, rotator
-availability, LCD writeback support, etc. The driver is located at
-drivers/media/platform/exynos4-is directory.
-
-Supported SoCs
---------------
-
-S5PC100 (mem-to-mem only), S5PV210, EXYNOS4210
-
-Supported features
-------------------
-
-- camera parallel interface capture (ITU-R.BT601/565);
-- camera serial interface capture (MIPI-CSI2);
-- memory-to-memory processing (color space conversion, scaling, mirror
-  and rotation);
-- dynamic pipeline re-configuration at runtime (re-attachment of any FIMC
-  instance to any parallel video input or any MIPI-CSI front-end);
-- runtime PM and system wide suspend/resume
-
-Not currently supported
------------------------
-
-- LCD writeback input
-- per frame clock gating (mem-to-mem)
-
-Files partitioning
-------------------
-
-- media device driver
-  drivers/media/platform/exynos4-is/media-dev.[ch]
-
-- camera capture video device driver
-  drivers/media/platform/exynos4-is/fimc-capture.c
-
-- MIPI-CSI2 receiver subdev
-  drivers/media/platform/exynos4-is/mipi-csis.[ch]
-
-- video post-processor (mem-to-mem)
-  drivers/media/platform/exynos4-is/fimc-core.c
-
-- common files
-  drivers/media/platform/exynos4-is/fimc-core.h
-  drivers/media/platform/exynos4-is/fimc-reg.h
-  drivers/media/platform/exynos4-is/regs-fimc.h
-
-User space interfaces
----------------------
-
-Media device interface
-~~~~~~~~~~~~~~~~~~~~~~
-
-The driver supports Media Controller API as defined at :ref:`media_controller`.
-The media device driver name is "SAMSUNG S5P FIMC".
-
-The purpose of this interface is to allow changing assignment of FIMC instances
-to the SoC peripheral camera input at runtime and optionally to control internal
-connections of the MIPI-CSIS device(s) to the FIMC entities.
-
-The media device interface allows to configure the SoC for capturing image
-data from the sensor through more than one FIMC instance (e.g. for simultaneous
-viewfinder and still capture setup).
-Reconfiguration is done by enabling/disabling media links created by the driver
-during initialization. The internal device topology can be easily discovered
-through media entity and links enumeration.
-
-Memory-to-memory video node
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-V4L2 memory-to-memory interface at /dev/video? device node.  This is standalone
-video device, it has no media pads. However please note the mem-to-mem and
-capture video node operation on same FIMC instance is not allowed.  The driver
-detects such cases but the applications should prevent them to avoid an
-undefined behaviour.
-
-Capture video node
-~~~~~~~~~~~~~~~~~~
-
-The driver supports V4L2 Video Capture Interface as defined at
-:ref:`devices`.
-
-At the capture and mem-to-mem video nodes only the multi-planar API is
-supported. For more details see: :ref:`planar-apis`.
-
-Camera capture subdevs
-~~~~~~~~~~~~~~~~~~~~~~
-
-Each FIMC instance exports a sub-device node (/dev/v4l-subdev?), a sub-device
-node is also created per each available and enabled at the platform level
-MIPI-CSI receiver device (currently up to two).
-
-sysfs
-~~~~~
-
-In order to enable more precise camera pipeline control through the sub-device
-API the driver creates a sysfs entry associated with "s5p-fimc-md" platform
-device. The entry path is: /sys/platform/devices/s5p-fimc-md/subdev_conf_mode.
-
-In typical use case there could be a following capture pipeline configuration:
-sensor subdev -> mipi-csi subdev -> fimc subdev -> video node
-
-When we configure these devices through sub-device API at user space, the
-configuration flow must be from left to right, and the video node is
-configured as last one.
-When we don't use sub-device user space API the whole configuration of all
-devices belonging to the pipeline is done at the video node driver.
-The sysfs entry allows to instruct the capture node driver not to configure
-the sub-devices (format, crop), to avoid resetting the subdevs' configuration
-when the last configuration steps at the video node is performed.
-
-For full sub-device control support (subdevs configured at user space before
-starting streaming):
-
-.. code-block:: none
-
-	# echo "sub-dev" > /sys/platform/devices/s5p-fimc-md/subdev_conf_mode
-
-For V4L2 video node control only (subdevs configured internally by the host
-driver):
-
-.. code-block:: none
-
-	# echo "vid-dev" > /sys/platform/devices/s5p-fimc-md/subdev_conf_mode
-
-This is a default option.
-
-5. Device mapping to video and subdev device nodes
---------------------------------------------------
-
-There are associated two video device nodes with each device instance in
-hardware - video capture and mem-to-mem and additionally a subdev node for
-more precise FIMC capture subsystem control. In addition a separate v4l2
-sub-device node is created per each MIPI-CSIS device.
-
-How to find out which /dev/video? or /dev/v4l-subdev? is assigned to which
-device?
-
-You can either grep through the kernel log to find relevant information, i.e.
-
-.. code-block:: none
-
-	# dmesg | grep -i fimc
-
-(note that udev, if present, might still have rearranged the video nodes),
-
-or retrieve the information from /dev/media? with help of the media-ctl tool:
-
-.. code-block:: none
-
-	# media-ctl -p
-
-7. Build
---------
-
-If the driver is built as a loadable kernel module (CONFIG_VIDEO_SAMSUNG_S5P_FIMC=m)
-two modules are created (in addition to the core v4l2 modules): s5p-fimc.ko and
-optional s5p-csis.ko (MIPI-CSI receiver subdev).
diff --git a/Documentation/media/v4l-drivers/fourcc.rst b/Documentation/media/v4l-drivers/fourcc.rst
deleted file mode 100644
index d3482c40da62..000000000000
--- a/Documentation/media/v4l-drivers/fourcc.rst
+++ /dev/null
@@ -1,32 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-Guidelines for Video4Linux pixel format 4CCs
-============================================
-
-Guidelines for Video4Linux 4CC codes defined using v4l2_fourcc() are
-specified in this document. First of the characters defines the nature of
-the pixel format, compression and colour space. The interpretation of the
-other three characters depends on the first one.
-
-Existing 4CCs may not obey these guidelines.
-
-Raw bayer
----------
-
-The following first characters are used by raw bayer formats:
-
-- B: raw bayer, uncompressed
-- b: raw bayer, DPCM compressed
-- a: A-law compressed
-- u: u-law compressed
-
-2nd character: pixel order
-
-- B: BGGR
-- G: GBRG
-- g: GRBG
-- R: RGGB
-
-3rd character: uncompressed bits-per-pixel 0--9, A--
-
-4th character: compressed bits-per-pixel 0--9, A--
diff --git a/Documentation/media/v4l-drivers/gspca-cardlist.rst b/Documentation/media/v4l-drivers/gspca-cardlist.rst
deleted file mode 100644
index adda933616f1..000000000000
--- a/Documentation/media/v4l-drivers/gspca-cardlist.rst
+++ /dev/null
@@ -1,451 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-The gspca cards list
-====================
-
-The modules for the gspca webcam drivers are:
-
-- gspca_main: main driver
-- gspca\_\ *driver*: subdriver module with *driver* as follows
-
-=========	=========	===================================================================
-*driver*	vend:prod	Device
-=========	=========	===================================================================
-spca501         0000:0000	MystFromOri Unknown Camera
-spca508         0130:0130	Clone Digital Webcam 11043
-se401           03e8:0004	Endpoints/AoxSE401
-zc3xx           03f0:1b07	HP Premium Starter Cam
-m5602           0402:5602	ALi Video Camera Controller
-spca501         040a:0002	Kodak DVC-325
-spca500         040a:0300	Kodak EZ200
-zc3xx           041e:041e	Creative WebCam Live!
-ov519           041e:4003	Video Blaster WebCam Go Plus
-stv0680         041e:4007	Go Mini
-spca500         041e:400a	Creative PC-CAM 300
-sunplus         041e:400b	Creative PC-CAM 600
-sunplus         041e:4012	PC-Cam350
-sunplus         041e:4013	Creative Pccam750
-zc3xx           041e:4017	Creative Webcam Mobile PD1090
-spca508         041e:4018	Creative Webcam Vista (PD1100)
-spca561         041e:401a	Creative Webcam Vista (PD1100)
-zc3xx           041e:401c	Creative NX
-spca505         041e:401d	Creative Webcam NX ULTRA
-zc3xx           041e:401e	Creative Nx Pro
-zc3xx           041e:401f	Creative Webcam Notebook PD1171
-zc3xx           041e:4022	Webcam NX Pro
-pac207          041e:4028	Creative Webcam Vista Plus
-zc3xx           041e:4029	Creative WebCam Vista Pro
-zc3xx           041e:4034	Creative Instant P0620
-zc3xx           041e:4035	Creative Instant P0620D
-zc3xx           041e:4036	Creative Live !
-sq930x          041e:4038	Creative Joy-IT
-zc3xx           041e:403a	Creative Nx Pro 2
-spca561         041e:403b	Creative Webcam Vista (VF0010)
-sq930x          041e:403c	Creative Live! Ultra
-sq930x          041e:403d	Creative Live! Ultra for Notebooks
-sq930x          041e:4041	Creative Live! Motion
-zc3xx           041e:4051	Creative Live!Cam Notebook Pro (VF0250)
-ov519           041e:4052	Creative Live! VISTA IM
-zc3xx           041e:4053	Creative Live!Cam Video IM
-vc032x          041e:405b	Creative Live! Cam Notebook Ultra (VC0130)
-ov519           041e:405f	Creative Live! VISTA VF0330
-ov519           041e:4060	Creative Live! VISTA VF0350
-ov519           041e:4061	Creative Live! VISTA VF0400
-ov519           041e:4064	Creative Live! VISTA VF0420
-ov519           041e:4067	Creative Live! Cam Video IM (VF0350)
-ov519           041e:4068	Creative Live! VISTA VF0470
-sn9c2028        0458:7003	GeniusVideocam Live v2
-spca561         0458:7004	Genius VideoCAM Express V2
-sn9c2028        0458:7005	Genius Smart 300, version 2
-sunplus         0458:7006	Genius Dsc 1.3 Smart
-zc3xx           0458:7007	Genius VideoCam V2
-zc3xx           0458:700c	Genius VideoCam V3
-zc3xx           0458:700f	Genius VideoCam Web V2
-sonixj          0458:7025	Genius Eye 311Q
-sn9c20x         0458:7029	Genius Look 320s
-sonixj          0458:702e	Genius Slim 310 NB
-sn9c20x         0458:7045	Genius Look 1320 V2
-sn9c20x         0458:704a	Genius Slim 1320
-sn9c20x         0458:704c	Genius i-Look 1321
-sn9c20x         045e:00f4	LifeCam VX-6000 (SN9C20x + OV9650)
-sonixj          045e:00f5	MicroSoft VX3000
-sonixj          045e:00f7	MicroSoft VX1000
-ov519           045e:028c	Micro$oft xbox cam
-kinect          045e:02ae	Xbox NUI Camera
-kinect          045e:02bf	Kinect for Windows NUI Camera
-spca561         0461:0815	Micro Innovations IC200 Webcam
-sunplus         0461:0821	Fujifilm MV-1
-zc3xx           0461:0a00	MicroInnovation WebCam320
-stv06xx         046D:08F0	QuickCamMessenger
-stv06xx         046D:08F5	QuickCamCommunicate
-stv06xx         046D:08F6	QuickCamMessenger (new)
-stv06xx         046d:0840	QuickCamExpress
-stv06xx         046d:0850	LEGOcam / QuickCam Web
-stv06xx         046d:0870	DexxaWebCam USB
-spca500         046d:0890	Logitech QuickCam traveler
-vc032x          046d:0892	Logitech Orbicam
-vc032x          046d:0896	Logitech Orbicam
-vc032x          046d:0897	Logitech QuickCam for Dell notebooks
-zc3xx           046d:089d	Logitech QuickCam E2500
-zc3xx           046d:08a0	Logitech QC IM
-zc3xx           046d:08a1	Logitech QC IM 0x08A1 +sound
-zc3xx           046d:08a2	Labtec Webcam Pro
-zc3xx           046d:08a3	Logitech QC Chat
-zc3xx           046d:08a6	Logitech QCim
-zc3xx           046d:08a7	Logitech QuickCam Image
-zc3xx           046d:08a9	Logitech Notebook Deluxe
-zc3xx           046d:08aa	Labtec Webcam Notebook
-zc3xx           046d:08ac	Logitech QuickCam Cool
-zc3xx           046d:08ad	Logitech QCCommunicate STX
-zc3xx           046d:08ae	Logitech QuickCam for Notebooks
-zc3xx           046d:08af	Logitech QuickCam Cool
-zc3xx           046d:08b9	Logitech QuickCam Express
-zc3xx           046d:08d7	Logitech QCam STX
-zc3xx           046d:08d8	Logitech Notebook Deluxe
-zc3xx           046d:08d9	Logitech QuickCam IM/Connect
-zc3xx           046d:08da	Logitech QuickCam Messenger
-zc3xx           046d:08dd	Logitech QuickCam for Notebooks
-spca500         046d:0900	Logitech Inc. ClickSmart 310
-spca500         046d:0901	Logitech Inc. ClickSmart 510
-sunplus         046d:0905	Logitech ClickSmart 820
-tv8532          046d:0920	Logitech QuickCam Express
-tv8532          046d:0921	Labtec Webcam
-spca561         046d:0928	Logitech QC Express Etch2
-spca561         046d:0929	Labtec Webcam Elch2
-spca561         046d:092a	Logitech QC for Notebook
-spca561         046d:092b	Labtec Webcam Plus
-spca561         046d:092c	Logitech QC chat Elch2
-spca561         046d:092d	Logitech QC Elch2
-spca561         046d:092e	Logitech QC Elch2
-spca561         046d:092f	Logitech QuickCam Express Plus
-sunplus         046d:0960	Logitech ClickSmart 420
-nw80x           046d:d001	Logitech QuickCam Pro (dark focus ring)
-se401           0471:030b	PhilipsPCVC665K
-sunplus         0471:0322	Philips DMVC1300K
-zc3xx           0471:0325	Philips SPC 200 NC
-zc3xx           0471:0326	Philips SPC 300 NC
-sonixj          0471:0327	Philips SPC 600 NC
-sonixj          0471:0328	Philips SPC 700 NC
-zc3xx           0471:032d	Philips SPC 210 NC
-zc3xx           0471:032e	Philips SPC 315 NC
-sonixj          0471:0330	Philips SPC 710 NC
-se401           047d:5001	Kensington67014
-se401           047d:5002	Kensington6701(5/7)
-se401           047d:5003	Kensington67016
-spca501         0497:c001	Smile International
-sunplus         04a5:3003	Benq DC 1300
-sunplus         04a5:3008	Benq DC 1500
-sunplus         04a5:300a	Benq DC 3410
-spca500         04a5:300c	Benq DC 1016
-benq            04a5:3035	Benq DC E300
-vicam           04c1:009d	HomeConnect Webcam [vicam]
-konica          04c8:0720	IntelYC 76
-finepix         04cb:0104	Fujifilm FinePix 4800
-finepix         04cb:0109	Fujifilm FinePix A202
-finepix         04cb:010b	Fujifilm FinePix A203
-finepix         04cb:010f	Fujifilm FinePix A204
-finepix         04cb:0111	Fujifilm FinePix A205
-finepix         04cb:0113	Fujifilm FinePix A210
-finepix         04cb:0115	Fujifilm FinePix A303
-finepix         04cb:0117	Fujifilm FinePix A310
-finepix         04cb:0119	Fujifilm FinePix F401
-finepix         04cb:011b	Fujifilm FinePix F402
-finepix         04cb:011d	Fujifilm FinePix F410
-finepix         04cb:0121	Fujifilm FinePix F601
-finepix         04cb:0123	Fujifilm FinePix F700
-finepix         04cb:0125	Fujifilm FinePix M603
-finepix         04cb:0127	Fujifilm FinePix S300
-finepix         04cb:0129	Fujifilm FinePix S304
-finepix         04cb:012b	Fujifilm FinePix S500
-finepix         04cb:012d	Fujifilm FinePix S602
-finepix         04cb:012f	Fujifilm FinePix S700
-finepix         04cb:0131	Fujifilm FinePix unknown model
-finepix         04cb:013b	Fujifilm FinePix unknown model
-finepix         04cb:013d	Fujifilm FinePix unknown model
-finepix         04cb:013f	Fujifilm FinePix F420
-sunplus         04f1:1001	JVC GC A50
-spca561         04fc:0561	Flexcam 100
-spca1528        04fc:1528	Sunplus MD80 clone
-sunplus         04fc:500c	Sunplus CA500C
-sunplus         04fc:504a	Aiptek Mini PenCam 1.3
-sunplus         04fc:504b	Maxell MaxPocket LE 1.3
-sunplus         04fc:5330	Digitrex 2110
-sunplus         04fc:5360	Sunplus Generic
-spca500         04fc:7333	PalmPixDC85
-sunplus         04fc:ffff	Pure DigitalDakota
-nw80x           0502:d001	DVC V6
-spca501         0506:00df	3Com HomeConnect Lite
-sunplus         052b:1507	Megapixel 5 Pretec DC-1007
-sunplus         052b:1513	Megapix V4
-sunplus         052b:1803	MegaImage VI
-nw80x           052b:d001	EZCam Pro p35u
-tv8532          0545:808b	Veo Stingray
-tv8532          0545:8333	Veo Stingray
-sunplus         0546:3155	Polaroid PDC3070
-sunplus         0546:3191	Polaroid Ion 80
-sunplus         0546:3273	Polaroid PDC2030
-touptek         0547:6801	TTUCMOS08000KPB, AS MU800
-dtcs033         0547:7303	Anchor Chips, Inc
-ov519           054c:0154	Sonny toy4
-ov519           054c:0155	Sonny toy5
-cpia1           0553:0002	CPIA CPiA (version1) based cameras
-stv0680         0553:0202	STV0680 Camera
-zc3xx           055f:c005	Mustek Wcam300A
-spca500         055f:c200	Mustek Gsmart 300
-sunplus         055f:c211	Kowa Bs888e Microcamera
-spca500         055f:c220	Gsmart Mini
-sunplus         055f:c230	Mustek Digicam 330K
-sunplus         055f:c232	Mustek MDC3500
-sunplus         055f:c360	Mustek DV4000 Mpeg4
-sunplus         055f:c420	Mustek gSmart Mini 2
-sunplus         055f:c430	Mustek Gsmart LCD 2
-sunplus         055f:c440	Mustek DV 3000
-sunplus         055f:c520	Mustek gSmart Mini 3
-sunplus         055f:c530	Mustek Gsmart LCD 3
-sunplus         055f:c540	Gsmart D30
-sunplus         055f:c630	Mustek MDC4000
-sunplus         055f:c650	Mustek MDC5500Z
-nw80x           055f:d001	Mustek Wcam 300 mini
-zc3xx           055f:d003	Mustek WCam300A
-zc3xx           055f:d004	Mustek WCam300 AN
-conex           0572:0041	Creative Notebook cx11646
-ov519           05a9:0511	Video Blaster WebCam 3/WebCam Plus, D-Link USB Digital Video Camera
-ov519           05a9:0518	Creative WebCam
-ov519           05a9:0519	OV519 Microphone
-ov519           05a9:0530	OmniVision
-ov534_9         05a9:1550	OmniVision VEHO Filmscanner
-ov519           05a9:2800	OmniVision SuperCAM
-ov519           05a9:4519	Webcam Classic
-ov534_9         05a9:8065	OmniVision test kit ov538+ov9712
-ov519           05a9:8519	OmniVision
-ov519           05a9:a511	D-Link USB Digital Video Camera
-ov519           05a9:a518	D-Link DSB-C310 Webcam
-sunplus         05da:1018	Digital Dream Enigma 1.3
-stk014          05e1:0893	Syntek DV4000
-gl860           05e3:0503	Genesys Logic PC Camera
-gl860           05e3:f191	Genesys Logic PC Camera
-vicam           0602:1001	ViCam Webcam
-spca561         060b:a001	Maxell Compact Pc PM3
-zc3xx           0698:2003	CTX M730V built in
-topro           06a2:0003	TP6800 PC Camera, CmoX CX0342 webcam
-topro           06a2:6810	Creative Qmax
-nw80x           06a5:0000	Typhoon Webcam 100 USB
-nw80x           06a5:d001	Divio based webcams
-nw80x           06a5:d800	Divio Chicony TwinkleCam, Trust SpaceCam
-spca500         06bd:0404	Agfa CL20
-spca500         06be:0800	Optimedia
-nw80x           06be:d001	EZCam Pro p35u
-sunplus         06d6:0031	Trust 610 LCD PowerC@m Zoom
-sunplus         06d6:0041	Aashima Technology B.V.
-spca506         06e1:a190	ADS Instant VCD
-ov534           06f8:3002	Hercules Blog Webcam
-ov534_9         06f8:3003	Hercules Dualpix HD Weblog
-sonixj          06f8:3004	Hercules Classic Silver
-sonixj          06f8:3008	Hercules Deluxe Optical Glass
-pac7302         06f8:3009	Hercules Classic Link
-pac7302         06f8:301b	Hercules Link
-nw80x           0728:d001	AVerMedia Camguard
-spca508         0733:0110	ViewQuest VQ110
-spca501         0733:0401	Intel Create and Share
-spca501         0733:0402	ViewQuest M318B
-spca505         0733:0430	Intel PC Camera Pro
-sunplus         0733:1311	Digital Dream Epsilon 1.3
-sunplus         0733:1314	Mercury 2.1MEG Deluxe Classic Cam
-sunplus         0733:2211	Jenoptik jdc 21 LCD
-sunplus         0733:2221	Mercury Digital Pro 3.1p
-sunplus         0733:3261	Concord 3045 spca536a
-sunplus         0733:3281	Cyberpix S550V
-spca506         0734:043b	3DeMon USB Capture aka
-cpia1           0813:0001	QX3 camera
-ov519           0813:0002	Dual Mode USB Camera Plus
-spca500         084d:0003	D-Link DSC-350
-spca500         08ca:0103	Aiptek PocketDV
-sunplus         08ca:0104	Aiptek PocketDVII 1.3
-sunplus         08ca:0106	Aiptek Pocket DV3100+
-mr97310a        08ca:0110	Trust Spyc@m 100
-mr97310a        08ca:0111	Aiptek PenCam VGA+
-sunplus         08ca:2008	Aiptek Mini PenCam 2 M
-sunplus         08ca:2010	Aiptek PocketCam 3M
-sunplus         08ca:2016	Aiptek PocketCam 2 Mega
-sunplus         08ca:2018	Aiptek Pencam SD 2M
-sunplus         08ca:2020	Aiptek Slim 3000F
-sunplus         08ca:2022	Aiptek Slim 3200
-sunplus         08ca:2024	Aiptek DV3500 Mpeg4
-sunplus         08ca:2028	Aiptek PocketCam4M
-sunplus         08ca:2040	Aiptek PocketDV4100M
-sunplus         08ca:2042	Aiptek PocketDV5100
-sunplus         08ca:2050	Medion MD 41437
-sunplus         08ca:2060	Aiptek PocketDV5300
-tv8532          0923:010f	ICM532 cams
-mr97310a        093a:010e	All known CIF cams with this ID
-mr97310a        093a:010f	All known VGA cams with this ID
-mars            093a:050f	Mars-Semi Pc-Camera
-pac207          093a:2460	Qtec Webcam 100
-pac207          093a:2461	HP Webcam
-pac207          093a:2463	Philips SPC 220 NC
-pac207          093a:2464	Labtec Webcam 1200
-pac207          093a:2468	Webcam WB-1400T
-pac207          093a:2470	Genius GF112
-pac207          093a:2471	Genius VideoCam ge111
-pac207          093a:2472	Genius VideoCam ge110
-pac207          093a:2474	Genius iLook 111
-pac207          093a:2476	Genius e-Messenger 112
-pac7311         093a:2600	PAC7311 Typhoon
-pac7311         093a:2601	Philips SPC 610 NC
-pac7311         093a:2603	Philips SPC 500 NC
-pac7311         093a:2608	Trust WB-3300p
-pac7311         093a:260e	Gigaware VGA PC Camera, Trust WB-3350p, SIGMA cam 2350
-pac7311         093a:260f	SnakeCam
-pac7302         093a:2620	Apollo AC-905
-pac7302         093a:2621	PAC731x
-pac7302         093a:2622	Genius Eye 312
-pac7302         093a:2623	Pixart Imaging, Inc.
-pac7302         093a:2624	PAC7302
-pac7302         093a:2625	Genius iSlim 310
-pac7302         093a:2626	Labtec 2200
-pac7302         093a:2627	Genius FaceCam 300
-pac7302         093a:2628	Genius iLook 300
-pac7302         093a:2629	Genious iSlim 300
-pac7302         093a:262a	Webcam 300k
-pac7302         093a:262c	Philips SPC 230 NC
-jl2005bcd       0979:0227	Various brands, 19 known cameras supported
-jeilinj         0979:0270	Sakar 57379
-jeilinj         0979:0280	Sportscam DV15, Sakar 57379
-zc3xx           0ac8:0301	Web Camera
-zc3xx           0ac8:0302	Z-star Vimicro zc0302
-vc032x          0ac8:0321	Vimicro generic vc0321
-vc032x          0ac8:0323	Vimicro Vc0323
-vc032x          0ac8:0328	A4Tech PK-130MG
-zc3xx           0ac8:301b	Z-Star zc301b
-zc3xx           0ac8:303b	Vimicro 0x303b
-zc3xx           0ac8:305b	Z-star Vimicro zc0305b
-zc3xx           0ac8:307b	PC Camera (ZS0211)
-vc032x          0ac8:c001	Sony embedded vimicro
-vc032x          0ac8:c002	Sony embedded vimicro
-vc032x          0ac8:c301	Samsung Q1 Ultra Premium
-spca508         0af9:0010	Hama USB Sightcam 100
-spca508         0af9:0011	Hama USB Sightcam 100
-ov519           0b62:0059	iBOT2 Webcam
-sonixb          0c45:6001	Genius VideoCAM NB
-sonixb          0c45:6005	Microdia Sweex Mini Webcam
-sonixb          0c45:6007	Sonix sn9c101 + Tas5110D
-sonixb          0c45:6009	spcaCam@120
-sonixb          0c45:600d	spcaCam@120
-sonixb          0c45:6011	Microdia PC Camera (SN9C102)
-sonixb          0c45:6019	Generic Sonix OV7630
-sonixb          0c45:6024	Generic Sonix Tas5130c
-sonixb          0c45:6025	Xcam Shanga
-sonixb          0c45:6027	GeniusEye 310
-sonixb          0c45:6028	Sonix Btc Pc380
-sonixb          0c45:6029	spcaCam@150
-sonixb          0c45:602a	Meade ETX-105EC Camera
-sonixb          0c45:602c	Generic Sonix OV7630
-sonixb          0c45:602d	LIC-200 LG
-sonixb          0c45:602e	Genius VideoCam Messenger
-sonixj          0c45:6040	Speed NVC 350K
-sonixj          0c45:607c	Sonix sn9c102p Hv7131R
-sonixb          0c45:6083	VideoCAM Look
-sonixb          0c45:608c	VideoCAM Look
-sonixb          0c45:608f	PC Camera (SN9C103 + OV7630)
-sonixb          0c45:60a8	VideoCAM Look
-sonixb          0c45:60aa	VideoCAM Look
-sonixb          0c45:60af	VideoCAM Look
-sonixb          0c45:60b0	Genius VideoCam Look
-sonixj          0c45:60c0	Sangha Sn535
-sonixj          0c45:60ce	USB-PC-Camera-168 (TALK-5067)
-sonixj          0c45:60ec	SN9C105+MO4000
-sonixj          0c45:60fb	Surfer NoName
-sonixj          0c45:60fc	LG-LIC300
-sonixj          0c45:60fe	Microdia Audio
-sonixj          0c45:6100	PC Camera (SN9C128)
-sonixj          0c45:6102	PC Camera (SN9C128)
-sonixj          0c45:610a	PC Camera (SN9C128)
-sonixj          0c45:610b	PC Camera (SN9C128)
-sonixj          0c45:610c	PC Camera (SN9C128)
-sonixj          0c45:610e	PC Camera (SN9C128)
-sonixj          0c45:6128	Microdia/Sonix SNP325
-sonixj          0c45:612a	Avant Camera
-sonixj          0c45:612b	Speed-Link REFLECT2
-sonixj          0c45:612c	Typhoon Rasy Cam 1.3MPix
-sonixj          0c45:612e	PC Camera (SN9C110)
-sonixj          0c45:6130	Sonix Pccam
-sonixj          0c45:6138	Sn9c120 Mo4000
-sonixj          0c45:613a	Microdia Sonix PC Camera
-sonixj          0c45:613b	Surfer SN-206
-sonixj          0c45:613c	Sonix Pccam168
-sonixj          0c45:613e	PC Camera (SN9C120)
-sonixj          0c45:6142	Hama PC-Webcam AC-150
-sonixj          0c45:6143	Sonix Pccam168
-sonixj          0c45:6148	Digitus DA-70811/ZSMC USB PC Camera ZS211/Microdia
-sonixj          0c45:614a	Frontech E-Ccam (JIL-2225)
-sn9c20x         0c45:6240	PC Camera (SN9C201 + MT9M001)
-sn9c20x         0c45:6242	PC Camera (SN9C201 + MT9M111)
-sn9c20x         0c45:6248	PC Camera (SN9C201 + OV9655)
-sn9c20x         0c45:624c	PC Camera (SN9C201 + MT9M112)
-sn9c20x         0c45:624e	PC Camera (SN9C201 + SOI968)
-sn9c20x         0c45:624f	PC Camera (SN9C201 + OV9650)
-sn9c20x         0c45:6251	PC Camera (SN9C201 + OV9650)
-sn9c20x         0c45:6253	PC Camera (SN9C201 + OV9650)
-sn9c20x         0c45:6260	PC Camera (SN9C201 + OV7670)
-sn9c20x         0c45:6270	PC Camera (SN9C201 + MT9V011/MT9V111/MT9V112)
-sn9c20x         0c45:627b	PC Camera (SN9C201 + OV7660)
-sn9c20x         0c45:627c	PC Camera (SN9C201 + HV7131R)
-sn9c20x         0c45:627f	PC Camera (SN9C201 + OV9650)
-sn9c20x         0c45:6280	PC Camera (SN9C202 + MT9M001)
-sn9c20x         0c45:6282	PC Camera (SN9C202 + MT9M111)
-sn9c20x         0c45:6288	PC Camera (SN9C202 + OV9655)
-sn9c20x         0c45:628c	PC Camera (SN9C201 + MT9M112)
-sn9c20x         0c45:628e	PC Camera (SN9C202 + SOI968)
-sn9c20x         0c45:628f	PC Camera (SN9C202 + OV9650)
-sn9c20x         0c45:62a0	PC Camera (SN9C202 + OV7670)
-sn9c20x         0c45:62b0	PC Camera (SN9C202 + MT9V011/MT9V111/MT9V112)
-sn9c20x         0c45:62b3	PC Camera (SN9C202 + OV9655)
-sn9c20x         0c45:62bb	PC Camera (SN9C202 + OV7660)
-sn9c20x         0c45:62bc	PC Camera (SN9C202 + HV7131R)
-sn9c2028        0c45:8001	Wild Planet Digital Spy Camera
-sn9c2028        0c45:8003	Sakar #11199, #6637x, #67480 keychain cams
-sn9c2028        0c45:8008	Mini-Shotz ms-350
-sn9c2028        0c45:800a	Vivitar Vivicam 3350B
-sunplus         0d64:0303	Sunplus FashionCam DXG
-ov519           0e96:c001	TRUST 380 USB2 SPACEC@M
-etoms           102c:6151	Qcam Sangha CIF
-etoms           102c:6251	Qcam xxxxxx VGA
-ov519           1046:9967	W9967CF/W9968CF WebCam IC, Video Blaster WebCam Go
-zc3xx           10fd:0128	Typhoon Webshot II USB 300k 0x0128
-spca561         10fd:7e50	FlyCam Usb 100
-zc3xx           10fd:804d	Typhoon Webshot II Webcam [zc0301]
-zc3xx           10fd:8050	Typhoon Webshot II USB 300k
-ov534           1415:2000	Sony HD Eye for PS3 (SLEH 00201)
-pac207          145f:013a	Trust WB-1300N
-pac7302         145f:013c	Trust
-sn9c20x         145f:013d	Trust WB-3600R
-vc032x          15b8:6001	HP 2.0 Megapixel
-vc032x          15b8:6002	HP 2.0 Megapixel rz406aa
-stk1135         174f:6a31	ASUSlaptop, MT9M112 sensor
-spca501         1776:501c	Arowana 300K CMOS Camera
-t613            17a1:0128	TASCORP JPEG Webcam, NGS Cyclops
-vc032x          17ef:4802	Lenovo Vc0323+MI1310_SOC
-pac7302         1ae7:2001	SpeedLinkSnappy Mic SL-6825-SBK
-pac207          2001:f115	D-Link DSB-C120
-sq905c          2770:9050	Disney pix micro (CIF)
-sq905c          2770:9051	Lego Bionicle
-sq905c          2770:9052	Disney pix micro 2 (VGA)
-sq905c          2770:905c	All 11 known cameras with this ID
-sq905           2770:9120	All 24 known cameras with this ID
-sq905c          2770:913d	All 4 known cameras with this ID
-sq930x          2770:930b	Sweex Motion Tracking / I-Tec iCam Tracer
-sq930x          2770:930c	Trust WB-3500T / NSG Robbie 2.0
-spca500         2899:012c	Toptro Industrial
-ov519           8020:ef04	ov519
-spca508         8086:0110	Intel Easy PC Camera
-spca500         8086:0630	Intel Pocket PC Camera
-spca506         99fa:8988	Grandtec V.cap
-sn9c20x         a168:0610	Dino-Lite Digital Microscope (SN9C201 + HV7131R)
-sn9c20x         a168:0611	Dino-Lite Digital Microscope (SN9C201 + HV7131R)
-sn9c20x         a168:0613	Dino-Lite Digital Microscope (SN9C201 + HV7131R)
-sn9c20x         a168:0614	Dino-Lite Digital Microscope (SN9C201 + MT9M111)
-sn9c20x         a168:0615	Dino-Lite Digital Microscope (SN9C201 + MT9M111)
-sn9c20x         a168:0617	Dino-Lite Digital Microscope (SN9C201 + MT9M111)
-sn9c20x         a168:0618	Dino-Lite Digital Microscope (SN9C201 + HV7131R)
-spca561         abcd:cdee	Petcam
-=========	=========	===================================================================
diff --git a/Documentation/media/v4l-drivers/imx.rst b/Documentation/media/v4l-drivers/imx.rst
deleted file mode 100644
index 1246573c1019..000000000000
--- a/Documentation/media/v4l-drivers/imx.rst
+++ /dev/null
@@ -1,705 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-i.MX Video Capture Driver
-=========================
-
-Introduction
-------------
-
-The Freescale i.MX5/6 contains an Image Processing Unit (IPU), which
-handles the flow of image frames to and from capture devices and
-display devices.
-
-For image capture, the IPU contains the following internal subunits:
-
-- Image DMA Controller (IDMAC)
-- Camera Serial Interface (CSI)
-- Image Converter (IC)
-- Sensor Multi-FIFO Controller (SMFC)
-- Image Rotator (IRT)
-- Video De-Interlacing or Combining Block (VDIC)
-
-The IDMAC is the DMA controller for transfer of image frames to and from
-memory. Various dedicated DMA channels exist for both video capture and
-display paths. During transfer, the IDMAC is also capable of vertical
-image flip, 8x8 block transfer (see IRT description), pixel component
-re-ordering (for example UYVY to YUYV) within the same colorspace, and
-packed <--> planar conversion. The IDMAC can also perform a simple
-de-interlacing by interweaving even and odd lines during transfer
-(without motion compensation which requires the VDIC).
-
-The CSI is the backend capture unit that interfaces directly with
-camera sensors over Parallel, BT.656/1120, and MIPI CSI-2 buses.
-
-The IC handles color-space conversion, resizing (downscaling and
-upscaling), horizontal flip, and 90/270 degree rotation operations.
-
-There are three independent "tasks" within the IC that can carry out
-conversions concurrently: pre-process encoding, pre-process viewfinder,
-and post-processing. Within each task, conversions are split into three
-sections: downsizing section, main section (upsizing, flip, colorspace
-conversion, and graphics plane combining), and rotation section.
-
-The IPU time-shares the IC task operations. The time-slice granularity
-is one burst of eight pixels in the downsizing section, one image line
-in the main processing section, one image frame in the rotation section.
-
-The SMFC is composed of four independent FIFOs that each can transfer
-captured frames from sensors directly to memory concurrently via four
-IDMAC channels.
-
-The IRT carries out 90 and 270 degree image rotation operations. The
-rotation operation is carried out on 8x8 pixel blocks at a time. This
-operation is supported by the IDMAC which handles the 8x8 block transfer
-along with block reordering, in coordination with vertical flip.
-
-The VDIC handles the conversion of interlaced video to progressive, with
-support for different motion compensation modes (low, medium, and high
-motion). The deinterlaced output frames from the VDIC can be sent to the
-IC pre-process viewfinder task for further conversions. The VDIC also
-contains a Combiner that combines two image planes, with alpha blending
-and color keying.
-
-In addition to the IPU internal subunits, there are also two units
-outside the IPU that are also involved in video capture on i.MX:
-
-- MIPI CSI-2 Receiver for camera sensors with the MIPI CSI-2 bus
-  interface. This is a Synopsys DesignWare core.
-- Two video multiplexers for selecting among multiple sensor inputs
-  to send to a CSI.
-
-For more info, refer to the latest versions of the i.MX5/6 reference
-manuals [#f1]_ and [#f2]_.
-
-
-Features
---------
-
-Some of the features of this driver include:
-
-- Many different pipelines can be configured via media controller API,
-  that correspond to the hardware video capture pipelines supported in
-  the i.MX.
-
-- Supports parallel, BT.565, and MIPI CSI-2 interfaces.
-
-- Concurrent independent streams, by configuring pipelines to multiple
-  video capture interfaces using independent entities.
-
-- Scaling, color-space conversion, horizontal and vertical flip, and
-  image rotation via IC task subdevs.
-
-- Many pixel formats supported (RGB, packed and planar YUV, partial
-  planar YUV).
-
-- The VDIC subdev supports motion compensated de-interlacing, with three
-  motion compensation modes: low, medium, and high motion. Pipelines are
-  defined that allow sending frames to the VDIC subdev directly from the
-  CSI. There is also support in the future for sending frames to the
-  VDIC from memory buffers via a output/mem2mem devices.
-
-- Includes a Frame Interval Monitor (FIM) that can correct vertical sync
-  problems with the ADV718x video decoders.
-
-
-Entities
---------
-
-imx6-mipi-csi2
---------------
-
-This is the MIPI CSI-2 receiver entity. It has one sink pad to receive
-the MIPI CSI-2 stream (usually from a MIPI CSI-2 camera sensor). It has
-four source pads, corresponding to the four MIPI CSI-2 demuxed virtual
-channel outputs. Multiple source pads can be enabled to independently
-stream from multiple virtual channels.
-
-This entity actually consists of two sub-blocks. One is the MIPI CSI-2
-core. This is a Synopsys Designware MIPI CSI-2 core. The other sub-block
-is a "CSI-2 to IPU gasket". The gasket acts as a demultiplexer of the
-four virtual channels streams, providing four separate parallel buses
-containing each virtual channel that are routed to CSIs or video
-multiplexers as described below.
-
-On i.MX6 solo/dual-lite, all four virtual channel buses are routed to
-two video multiplexers. Both CSI0 and CSI1 can receive any virtual
-channel, as selected by the video multiplexers.
-
-On i.MX6 Quad, virtual channel 0 is routed to IPU1-CSI0 (after selected
-by a video mux), virtual channels 1 and 2 are hard-wired to IPU1-CSI1
-and IPU2-CSI0, respectively, and virtual channel 3 is routed to
-IPU2-CSI1 (again selected by a video mux).
-
-ipuX_csiY_mux
--------------
-
-These are the video multiplexers. They have two or more sink pads to
-select from either camera sensors with a parallel interface, or from
-MIPI CSI-2 virtual channels from imx6-mipi-csi2 entity. They have a
-single source pad that routes to a CSI (ipuX_csiY entities).
-
-On i.MX6 solo/dual-lite, there are two video mux entities. One sits
-in front of IPU1-CSI0 to select between a parallel sensor and any of
-the four MIPI CSI-2 virtual channels (a total of five sink pads). The
-other mux sits in front of IPU1-CSI1, and again has five sink pads to
-select between a parallel sensor and any of the four MIPI CSI-2 virtual
-channels.
-
-On i.MX6 Quad, there are two video mux entities. One sits in front of
-IPU1-CSI0 to select between a parallel sensor and MIPI CSI-2 virtual
-channel 0 (two sink pads). The other mux sits in front of IPU2-CSI1 to
-select between a parallel sensor and MIPI CSI-2 virtual channel 3 (two
-sink pads).
-
-ipuX_csiY
----------
-
-These are the CSI entities. They have a single sink pad receiving from
-either a video mux or from a MIPI CSI-2 virtual channel as described
-above.
-
-This entity has two source pads. The first source pad can link directly
-to the ipuX_vdic entity or the ipuX_ic_prp entity, using hardware links
-that require no IDMAC memory buffer transfer.
-
-When the direct source pad is routed to the ipuX_ic_prp entity, frames
-from the CSI can be processed by one or both of the IC pre-processing
-tasks.
-
-When the direct source pad is routed to the ipuX_vdic entity, the VDIC
-will carry out motion-compensated de-interlace using "high motion" mode
-(see description of ipuX_vdic entity).
-
-The second source pad sends video frames directly to memory buffers
-via the SMFC and an IDMAC channel, bypassing IC pre-processing. This
-source pad is routed to a capture device node, with a node name of the
-format "ipuX_csiY capture".
-
-Note that since the IDMAC source pad makes use of an IDMAC channel,
-pixel reordering within the same colorspace can be carried out by the
-IDMAC channel. For example, if the CSI sink pad is receiving in UYVY
-order, the capture device linked to the IDMAC source pad can capture
-in YUYV order. Also, if the CSI sink pad is receiving a packed YUV
-format, the capture device can capture a planar YUV format such as
-YUV420.
-
-The IDMAC channel at the IDMAC source pad also supports simple
-interweave without motion compensation, which is activated if the source
-pad's field type is sequential top-bottom or bottom-top, and the
-requested capture interface field type is set to interlaced (t-b, b-t,
-or unqualified interlaced). The capture interface will enforce the same
-field order as the source pad field order (interlaced-bt if source pad
-is seq-bt, interlaced-tb if source pad is seq-tb).
-
-This subdev can generate the following event when enabling the second
-IDMAC source pad:
-
-- V4L2_EVENT_IMX_FRAME_INTERVAL_ERROR
-
-The user application can subscribe to this event from the ipuX_csiY
-subdev node. This event is generated by the Frame Interval Monitor
-(see below for more on the FIM).
-
-Cropping in ipuX_csiY
----------------------
-
-The CSI supports cropping the incoming raw sensor frames. This is
-implemented in the ipuX_csiY entities at the sink pad, using the
-crop selection subdev API.
-
-The CSI also supports fixed divide-by-two downscaling independently in
-width and height. This is implemented in the ipuX_csiY entities at
-the sink pad, using the compose selection subdev API.
-
-The output rectangle at the ipuX_csiY source pad is the same as
-the compose rectangle at the sink pad. So the source pad rectangle
-cannot be negotiated, it must be set using the compose selection
-API at sink pad (if /2 downscale is desired, otherwise source pad
-rectangle is equal to incoming rectangle).
-
-To give an example of crop and /2 downscale, this will crop a
-1280x960 input frame to 640x480, and then /2 downscale in both
-dimensions to 320x240 (assumes ipu1_csi0 is linked to ipu1_csi0_mux):
-
-.. code-block:: none
-
-   media-ctl -V "'ipu1_csi0_mux':2[fmt:UYVY2X8/1280x960]"
-   media-ctl -V "'ipu1_csi0':0[crop:(0,0)/640x480]"
-   media-ctl -V "'ipu1_csi0':0[compose:(0,0)/320x240]"
-
-Frame Skipping in ipuX_csiY
----------------------------
-
-The CSI supports frame rate decimation, via frame skipping. Frame
-rate decimation is specified by setting the frame intervals at
-sink and source pads. The ipuX_csiY entity then applies the best
-frame skip setting to the CSI to achieve the desired frame rate
-at the source pad.
-
-The following example reduces an assumed incoming 60 Hz frame
-rate by half at the IDMAC output source pad:
-
-.. code-block:: none
-
-   media-ctl -V "'ipu1_csi0':0[fmt:UYVY2X8/640x480@1/60]"
-   media-ctl -V "'ipu1_csi0':2[fmt:UYVY2X8/640x480@1/30]"
-
-Frame Interval Monitor in ipuX_csiY
------------------------------------
-
-The adv718x decoders can occasionally send corrupt fields during
-NTSC/PAL signal re-sync (too little or too many video lines). When
-this happens, the IPU triggers a mechanism to re-establish vertical
-sync by adding 1 dummy line every frame, which causes a rolling effect
-from image to image, and can last a long time before a stable image is
-recovered. Or sometimes the mechanism doesn't work at all, causing a
-permanent split image (one frame contains lines from two consecutive
-captured images).
-
-From experiment it was found that during image rolling, the frame
-intervals (elapsed time between two EOF's) drop below the nominal
-value for the current standard, by about one frame time (60 usec),
-and remain at that value until rolling stops.
-
-While the reason for this observation isn't known (the IPU dummy
-line mechanism should show an increase in the intervals by 1 line
-time every frame, not a fixed value), we can use it to detect the
-corrupt fields using a frame interval monitor. If the FIM detects a
-bad frame interval, the ipuX_csiY subdev will send the event
-V4L2_EVENT_IMX_FRAME_INTERVAL_ERROR. Userland can register with
-the FIM event notification on the ipuX_csiY subdev device node.
-Userland can issue a streaming restart when this event is received
-to correct the rolling/split image.
-
-The ipuX_csiY subdev includes custom controls to tweak some dials for
-FIM. If one of these controls is changed during streaming, the FIM will
-be reset and will continue at the new settings.
-
-- V4L2_CID_IMX_FIM_ENABLE
-
-Enable/disable the FIM.
-
-- V4L2_CID_IMX_FIM_NUM
-
-How many frame interval measurements to average before comparing against
-the nominal frame interval reported by the sensor. This can reduce noise
-caused by interrupt latency.
-
-- V4L2_CID_IMX_FIM_TOLERANCE_MIN
-
-If the averaged intervals fall outside nominal by this amount, in
-microseconds, the V4L2_EVENT_IMX_FRAME_INTERVAL_ERROR event is sent.
-
-- V4L2_CID_IMX_FIM_TOLERANCE_MAX
-
-If any intervals are higher than this value, those samples are
-discarded and do not enter into the average. This can be used to
-discard really high interval errors that might be due to interrupt
-latency from high system load.
-
-- V4L2_CID_IMX_FIM_NUM_SKIP
-
-How many frames to skip after a FIM reset or stream restart before
-FIM begins to average intervals.
-
-- V4L2_CID_IMX_FIM_ICAP_CHANNEL
-- V4L2_CID_IMX_FIM_ICAP_EDGE
-
-These controls will configure an input capture channel as the method
-for measuring frame intervals. This is superior to the default method
-of measuring frame intervals via EOF interrupt, since it is not subject
-to uncertainty errors introduced by interrupt latency.
-
-Input capture requires hardware support. A VSYNC signal must be routed
-to one of the i.MX6 input capture channel pads.
-
-V4L2_CID_IMX_FIM_ICAP_CHANNEL configures which i.MX6 input capture
-channel to use. This must be 0 or 1.
-
-V4L2_CID_IMX_FIM_ICAP_EDGE configures which signal edge will trigger
-input capture events. By default the input capture method is disabled
-with a value of IRQ_TYPE_NONE. Set this control to IRQ_TYPE_EDGE_RISING,
-IRQ_TYPE_EDGE_FALLING, or IRQ_TYPE_EDGE_BOTH to enable input capture,
-triggered on the given signal edge(s).
-
-When input capture is disabled, frame intervals will be measured via
-EOF interrupt.
-
-
-ipuX_vdic
----------
-
-The VDIC carries out motion compensated de-interlacing, with three
-motion compensation modes: low, medium, and high motion. The mode is
-specified with the menu control V4L2_CID_DEINTERLACING_MODE. The VDIC
-has two sink pads and a single source pad.
-
-The direct sink pad receives from an ipuX_csiY direct pad. With this
-link the VDIC can only operate in high motion mode.
-
-When the IDMAC sink pad is activated, it receives from an output
-or mem2mem device node. With this pipeline, the VDIC can also operate
-in low and medium modes, because these modes require receiving
-frames from memory buffers. Note that an output or mem2mem device
-is not implemented yet, so this sink pad currently has no links.
-
-The source pad routes to the IC pre-processing entity ipuX_ic_prp.
-
-ipuX_ic_prp
------------
-
-This is the IC pre-processing entity. It acts as a router, routing
-data from its sink pad to one or both of its source pads.
-
-This entity has a single sink pad. The sink pad can receive from the
-ipuX_csiY direct pad, or from ipuX_vdic.
-
-This entity has two source pads. One source pad routes to the
-pre-process encode task entity (ipuX_ic_prpenc), the other to the
-pre-process viewfinder task entity (ipuX_ic_prpvf). Both source pads
-can be activated at the same time if the sink pad is receiving from
-ipuX_csiY. Only the source pad to the pre-process viewfinder task entity
-can be activated if the sink pad is receiving from ipuX_vdic (frames
-from the VDIC can only be processed by the pre-process viewfinder task).
-
-ipuX_ic_prpenc
---------------
-
-This is the IC pre-processing encode entity. It has a single sink
-pad from ipuX_ic_prp, and a single source pad. The source pad is
-routed to a capture device node, with a node name of the format
-"ipuX_ic_prpenc capture".
-
-This entity performs the IC pre-process encode task operations:
-color-space conversion, resizing (downscaling and upscaling),
-horizontal and vertical flip, and 90/270 degree rotation. Flip
-and rotation are provided via standard V4L2 controls.
-
-Like the ipuX_csiY IDMAC source, this entity also supports simple
-de-interlace without motion compensation, and pixel reordering.
-
-ipuX_ic_prpvf
--------------
-
-This is the IC pre-processing viewfinder entity. It has a single sink
-pad from ipuX_ic_prp, and a single source pad. The source pad is routed
-to a capture device node, with a node name of the format
-"ipuX_ic_prpvf capture".
-
-This entity is identical in operation to ipuX_ic_prpenc, with the same
-resizing and CSC operations and flip/rotation controls. It will receive
-and process de-interlaced frames from the ipuX_vdic if ipuX_ic_prp is
-receiving from ipuX_vdic.
-
-Like the ipuX_csiY IDMAC source, this entity supports simple
-interweaving without motion compensation. However, note that if the
-ipuX_vdic is included in the pipeline (ipuX_ic_prp is receiving from
-ipuX_vdic), it's not possible to use interweave in ipuX_ic_prpvf,
-since the ipuX_vdic has already carried out de-interlacing (with
-motion compensation) and therefore the field type output from
-ipuX_vdic can only be none (progressive).
-
-Capture Pipelines
------------------
-
-The following describe the various use-cases supported by the pipelines.
-
-The links shown do not include the backend sensor, video mux, or mipi
-csi-2 receiver links. This depends on the type of sensor interface
-(parallel or mipi csi-2). So these pipelines begin with:
-
-sensor -> ipuX_csiY_mux -> ...
-
-for parallel sensors, or:
-
-sensor -> imx6-mipi-csi2 -> (ipuX_csiY_mux) -> ...
-
-for mipi csi-2 sensors. The imx6-mipi-csi2 receiver may need to route
-to the video mux (ipuX_csiY_mux) before sending to the CSI, depending
-on the mipi csi-2 virtual channel, hence ipuX_csiY_mux is shown in
-parenthesis.
-
-Unprocessed Video Capture:
---------------------------
-
-Send frames directly from sensor to camera device interface node, with
-no conversions, via ipuX_csiY IDMAC source pad:
-
--> ipuX_csiY:2 -> ipuX_csiY capture
-
-IC Direct Conversions:
-----------------------
-
-This pipeline uses the preprocess encode entity to route frames directly
-from the CSI to the IC, to carry out scaling up to 1024x1024 resolution,
-CSC, flipping, and image rotation:
-
--> ipuX_csiY:1 -> 0:ipuX_ic_prp:1 -> 0:ipuX_ic_prpenc:1 -> ipuX_ic_prpenc capture
-
-Motion Compensated De-interlace:
---------------------------------
-
-This pipeline routes frames from the CSI direct pad to the VDIC entity to
-support motion-compensated de-interlacing (high motion mode only),
-scaling up to 1024x1024, CSC, flip, and rotation:
-
--> ipuX_csiY:1 -> 0:ipuX_vdic:2 -> 0:ipuX_ic_prp:2 -> 0:ipuX_ic_prpvf:1 -> ipuX_ic_prpvf capture
-
-
-Usage Notes
------------
-
-To aid in configuration and for backward compatibility with V4L2
-applications that access controls only from video device nodes, the
-capture device interfaces inherit controls from the active entities
-in the current pipeline, so controls can be accessed either directly
-from the subdev or from the active capture device interface. For
-example, the FIM controls are available either from the ipuX_csiY
-subdevs or from the active capture device.
-
-The following are specific usage notes for the Sabre* reference
-boards:
-
-
-SabreLite with OV5642 and OV5640
---------------------------------
-
-This platform requires the OmniVision OV5642 module with a parallel
-camera interface, and the OV5640 module with a MIPI CSI-2
-interface. Both modules are available from Boundary Devices:
-
-- https://boundarydevices.com/product/nit6x_5mp
-- https://boundarydevices.com/product/nit6x_5mp_mipi
-
-Note that if only one camera module is available, the other sensor
-node can be disabled in the device tree.
-
-The OV5642 module is connected to the parallel bus input on the i.MX
-internal video mux to IPU1 CSI0. It's i2c bus connects to i2c bus 2.
-
-The MIPI CSI-2 OV5640 module is connected to the i.MX internal MIPI CSI-2
-receiver, and the four virtual channel outputs from the receiver are
-routed as follows: vc0 to the IPU1 CSI0 mux, vc1 directly to IPU1 CSI1,
-vc2 directly to IPU2 CSI0, and vc3 to the IPU2 CSI1 mux. The OV5640 is
-also connected to i2c bus 2 on the SabreLite, therefore the OV5642 and
-OV5640 must not share the same i2c slave address.
-
-The following basic example configures unprocessed video capture
-pipelines for both sensors. The OV5642 is routed to ipu1_csi0, and
-the OV5640, transmitting on MIPI CSI-2 virtual channel 1 (which is
-imx6-mipi-csi2 pad 2), is routed to ipu1_csi1. Both sensors are
-configured to output 640x480, and the OV5642 outputs YUYV2X8, the
-OV5640 UYVY2X8:
-
-.. code-block:: none
-
-   # Setup links for OV5642
-   media-ctl -l "'ov5642 1-0042':0 -> 'ipu1_csi0_mux':1[1]"
-   media-ctl -l "'ipu1_csi0_mux':2 -> 'ipu1_csi0':0[1]"
-   media-ctl -l "'ipu1_csi0':2 -> 'ipu1_csi0 capture':0[1]"
-   # Setup links for OV5640
-   media-ctl -l "'ov5640 1-0040':0 -> 'imx6-mipi-csi2':0[1]"
-   media-ctl -l "'imx6-mipi-csi2':2 -> 'ipu1_csi1':0[1]"
-   media-ctl -l "'ipu1_csi1':2 -> 'ipu1_csi1 capture':0[1]"
-   # Configure pads for OV5642 pipeline
-   media-ctl -V "'ov5642 1-0042':0 [fmt:YUYV2X8/640x480 field:none]"
-   media-ctl -V "'ipu1_csi0_mux':2 [fmt:YUYV2X8/640x480 field:none]"
-   media-ctl -V "'ipu1_csi0':2 [fmt:AYUV32/640x480 field:none]"
-   # Configure pads for OV5640 pipeline
-   media-ctl -V "'ov5640 1-0040':0 [fmt:UYVY2X8/640x480 field:none]"
-   media-ctl -V "'imx6-mipi-csi2':2 [fmt:UYVY2X8/640x480 field:none]"
-   media-ctl -V "'ipu1_csi1':2 [fmt:AYUV32/640x480 field:none]"
-
-Streaming can then begin independently on the capture device nodes
-"ipu1_csi0 capture" and "ipu1_csi1 capture". The v4l2-ctl tool can
-be used to select any supported YUV pixelformat on the capture device
-nodes, including planar.
-
-i.MX6Q SabreAuto with ADV7180 decoder
--------------------------------------
-
-On the i.MX6Q SabreAuto, an on-board ADV7180 SD decoder is connected to the
-parallel bus input on the internal video mux to IPU1 CSI0.
-
-The following example configures a pipeline to capture from the ADV7180
-video decoder, assuming NTSC 720x480 input signals, using simple
-interweave (unconverted and without motion compensation). The adv7180
-must output sequential or alternating fields (field type 'seq-bt' for
-NTSC, or 'alternate'):
-
-.. code-block:: none
-
-   # Setup links
-   media-ctl -l "'adv7180 3-0021':0 -> 'ipu1_csi0_mux':1[1]"
-   media-ctl -l "'ipu1_csi0_mux':2 -> 'ipu1_csi0':0[1]"
-   media-ctl -l "'ipu1_csi0':2 -> 'ipu1_csi0 capture':0[1]"
-   # Configure pads
-   media-ctl -V "'adv7180 3-0021':0 [fmt:UYVY2X8/720x480 field:seq-bt]"
-   media-ctl -V "'ipu1_csi0_mux':2 [fmt:UYVY2X8/720x480]"
-   media-ctl -V "'ipu1_csi0':2 [fmt:AYUV32/720x480]"
-   # Configure "ipu1_csi0 capture" interface (assumed at /dev/video4)
-   v4l2-ctl -d4 --set-fmt-video=field=interlaced_bt
-
-Streaming can then begin on /dev/video4. The v4l2-ctl tool can also be
-used to select any supported YUV pixelformat on /dev/video4.
-
-This example configures a pipeline to capture from the ADV7180
-video decoder, assuming PAL 720x576 input signals, with Motion
-Compensated de-interlacing. The adv7180 must output sequential or
-alternating fields (field type 'seq-tb' for PAL, or 'alternate').
-
-.. code-block:: none
-
-   # Setup links
-   media-ctl -l "'adv7180 3-0021':0 -> 'ipu1_csi0_mux':1[1]"
-   media-ctl -l "'ipu1_csi0_mux':2 -> 'ipu1_csi0':0[1]"
-   media-ctl -l "'ipu1_csi0':1 -> 'ipu1_vdic':0[1]"
-   media-ctl -l "'ipu1_vdic':2 -> 'ipu1_ic_prp':0[1]"
-   media-ctl -l "'ipu1_ic_prp':2 -> 'ipu1_ic_prpvf':0[1]"
-   media-ctl -l "'ipu1_ic_prpvf':1 -> 'ipu1_ic_prpvf capture':0[1]"
-   # Configure pads
-   media-ctl -V "'adv7180 3-0021':0 [fmt:UYVY2X8/720x576 field:seq-tb]"
-   media-ctl -V "'ipu1_csi0_mux':2 [fmt:UYVY2X8/720x576]"
-   media-ctl -V "'ipu1_csi0':1 [fmt:AYUV32/720x576]"
-   media-ctl -V "'ipu1_vdic':2 [fmt:AYUV32/720x576 field:none]"
-   media-ctl -V "'ipu1_ic_prp':2 [fmt:AYUV32/720x576 field:none]"
-   media-ctl -V "'ipu1_ic_prpvf':1 [fmt:AYUV32/720x576 field:none]"
-   # Configure "ipu1_ic_prpvf capture" interface (assumed at /dev/video2)
-   v4l2-ctl -d2 --set-fmt-video=field=none
-
-Streaming can then begin on /dev/video2. The v4l2-ctl tool can also be
-used to select any supported YUV pixelformat on /dev/video2.
-
-This platform accepts Composite Video analog inputs to the ADV7180 on
-Ain1 (connector J42).
-
-i.MX6DL SabreAuto with ADV7180 decoder
---------------------------------------
-
-On the i.MX6DL SabreAuto, an on-board ADV7180 SD decoder is connected to the
-parallel bus input on the internal video mux to IPU1 CSI0.
-
-The following example configures a pipeline to capture from the ADV7180
-video decoder, assuming NTSC 720x480 input signals, using simple
-interweave (unconverted and without motion compensation). The adv7180
-must output sequential or alternating fields (field type 'seq-bt' for
-NTSC, or 'alternate'):
-
-.. code-block:: none
-
-   # Setup links
-   media-ctl -l "'adv7180 4-0021':0 -> 'ipu1_csi0_mux':4[1]"
-   media-ctl -l "'ipu1_csi0_mux':5 -> 'ipu1_csi0':0[1]"
-   media-ctl -l "'ipu1_csi0':2 -> 'ipu1_csi0 capture':0[1]"
-   # Configure pads
-   media-ctl -V "'adv7180 4-0021':0 [fmt:UYVY2X8/720x480 field:seq-bt]"
-   media-ctl -V "'ipu1_csi0_mux':5 [fmt:UYVY2X8/720x480]"
-   media-ctl -V "'ipu1_csi0':2 [fmt:AYUV32/720x480]"
-   # Configure "ipu1_csi0 capture" interface (assumed at /dev/video0)
-   v4l2-ctl -d0 --set-fmt-video=field=interlaced_bt
-
-Streaming can then begin on /dev/video0. The v4l2-ctl tool can also be
-used to select any supported YUV pixelformat on /dev/video0.
-
-This example configures a pipeline to capture from the ADV7180
-video decoder, assuming PAL 720x576 input signals, with Motion
-Compensated de-interlacing. The adv7180 must output sequential or
-alternating fields (field type 'seq-tb' for PAL, or 'alternate').
-
-.. code-block:: none
-
-   # Setup links
-   media-ctl -l "'adv7180 4-0021':0 -> 'ipu1_csi0_mux':4[1]"
-   media-ctl -l "'ipu1_csi0_mux':5 -> 'ipu1_csi0':0[1]"
-   media-ctl -l "'ipu1_csi0':1 -> 'ipu1_vdic':0[1]"
-   media-ctl -l "'ipu1_vdic':2 -> 'ipu1_ic_prp':0[1]"
-   media-ctl -l "'ipu1_ic_prp':2 -> 'ipu1_ic_prpvf':0[1]"
-   media-ctl -l "'ipu1_ic_prpvf':1 -> 'ipu1_ic_prpvf capture':0[1]"
-   # Configure pads
-   media-ctl -V "'adv7180 4-0021':0 [fmt:UYVY2X8/720x576 field:seq-tb]"
-   media-ctl -V "'ipu1_csi0_mux':5 [fmt:UYVY2X8/720x576]"
-   media-ctl -V "'ipu1_csi0':1 [fmt:AYUV32/720x576]"
-   media-ctl -V "'ipu1_vdic':2 [fmt:AYUV32/720x576 field:none]"
-   media-ctl -V "'ipu1_ic_prp':2 [fmt:AYUV32/720x576 field:none]"
-   media-ctl -V "'ipu1_ic_prpvf':1 [fmt:AYUV32/720x576 field:none]"
-   # Configure "ipu1_ic_prpvf capture" interface (assumed at /dev/video2)
-   v4l2-ctl -d2 --set-fmt-video=field=none
-
-Streaming can then begin on /dev/video2. The v4l2-ctl tool can also be
-used to select any supported YUV pixelformat on /dev/video2.
-
-This platform accepts Composite Video analog inputs to the ADV7180 on
-Ain1 (connector J42).
-
-SabreSD with MIPI CSI-2 OV5640
-------------------------------
-
-Similarly to SabreLite, the SabreSD supports a parallel interface
-OV5642 module on IPU1 CSI0, and a MIPI CSI-2 OV5640 module. The OV5642
-connects to i2c bus 1 and the OV5640 to i2c bus 2.
-
-The device tree for SabreSD includes OF graphs for both the parallel
-OV5642 and the MIPI CSI-2 OV5640, but as of this writing only the MIPI
-CSI-2 OV5640 has been tested, so the OV5642 node is currently disabled.
-The OV5640 module connects to MIPI connector J5 (sorry I don't have the
-compatible module part number or URL).
-
-The following example configures a direct conversion pipeline to capture
-from the OV5640, transmitting on MIPI CSI-2 virtual channel 1. $sensorfmt
-can be any format supported by the OV5640. $sensordim is the frame
-dimension part of $sensorfmt (minus the mbus pixel code). $outputfmt can
-be any format supported by the ipu1_ic_prpenc entity at its output pad:
-
-.. code-block:: none
-
-   # Setup links
-   media-ctl -l "'ov5640 1-003c':0 -> 'imx6-mipi-csi2':0[1]"
-   media-ctl -l "'imx6-mipi-csi2':2 -> 'ipu1_csi1':0[1]"
-   media-ctl -l "'ipu1_csi1':1 -> 'ipu1_ic_prp':0[1]"
-   media-ctl -l "'ipu1_ic_prp':1 -> 'ipu1_ic_prpenc':0[1]"
-   media-ctl -l "'ipu1_ic_prpenc':1 -> 'ipu1_ic_prpenc capture':0[1]"
-   # Configure pads
-   media-ctl -V "'ov5640 1-003c':0 [fmt:$sensorfmt field:none]"
-   media-ctl -V "'imx6-mipi-csi2':2 [fmt:$sensorfmt field:none]"
-   media-ctl -V "'ipu1_csi1':1 [fmt:AYUV32/$sensordim field:none]"
-   media-ctl -V "'ipu1_ic_prp':1 [fmt:AYUV32/$sensordim field:none]"
-   media-ctl -V "'ipu1_ic_prpenc':1 [fmt:$outputfmt field:none]"
-
-Streaming can then begin on "ipu1_ic_prpenc capture" node. The v4l2-ctl
-tool can be used to select any supported YUV or RGB pixelformat on the
-capture device node.
-
-
-Known Issues
-------------
-
-1. When using 90 or 270 degree rotation control at capture resolutions
-   near the IC resizer limit of 1024x1024, and combined with planar
-   pixel formats (YUV420, YUV422p), frame capture will often fail with
-   no end-of-frame interrupts from the IDMAC channel. To work around
-   this, use lower resolution and/or packed formats (YUYV, RGB3, etc.)
-   when 90 or 270 rotations are needed.
-
-
-File list
----------
-
-drivers/staging/media/imx/
-include/media/imx.h
-include/linux/imx-media.h
-
-References
-----------
-
-.. [#f1] http://www.nxp.com/assets/documents/data/en/reference-manuals/IMX6DQRM.pdf
-.. [#f2] http://www.nxp.com/assets/documents/data/en/reference-manuals/IMX6SDLRM.pdf
-
-
-Authors
--------
-
-- Steve Longerbeam <steve_longerbeam@mentor.com>
-- Philipp Zabel <kernel@pengutronix.de>
-- Russell King <linux@armlinux.org.uk>
-
-Copyright (C) 2012-2017 Mentor Graphics Inc.
diff --git a/Documentation/media/v4l-drivers/imx7.rst b/Documentation/media/v4l-drivers/imx7.rst
deleted file mode 100644
index 1e442c97da47..000000000000
--- a/Documentation/media/v4l-drivers/imx7.rst
+++ /dev/null
@@ -1,161 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-i.MX7 Video Capture Driver
-==========================
-
-Introduction
-------------
-
-The i.MX7 contrary to the i.MX5/6 family does not contain an Image Processing
-Unit (IPU); because of that the capabilities to perform operations or
-manipulation of the capture frames are less feature rich.
-
-For image capture the i.MX7 has three units:
-- CMOS Sensor Interface (CSI)
-- Video Multiplexer
-- MIPI CSI-2 Receiver
-
-.. code-block:: none
-
-   MIPI Camera Input ---> MIPI CSI-2 --- > |\
-                                           | \
-                                           |  \
-                                           | M |
-                                           | U | ------>  CSI ---> Capture
-                                           | X |
-                                           |  /
-   Parallel Camera Input ----------------> | /
-                                           |/
-
-For additional information, please refer to the latest versions of the i.MX7
-reference manual [#f1]_.
-
-Entities
---------
-
-imx7-mipi-csi2
---------------
-
-This is the MIPI CSI-2 receiver entity. It has one sink pad to receive the pixel
-data from MIPI CSI-2 camera sensor. It has one source pad, corresponding to the
-virtual channel 0. This module is compliant to previous version of Samsung
-D-phy, and supports two D-PHY Rx Data lanes.
-
-csi-mux
--------
-
-This is the video multiplexer. It has two sink pads to select from either camera
-sensor with a parallel interface or from MIPI CSI-2 virtual channel 0.  It has
-a single source pad that routes to the CSI.
-
-csi
----
-
-The CSI enables the chip to connect directly to external CMOS image sensor. CSI
-can interface directly with Parallel and MIPI CSI-2 buses. It has 256 x 64 FIFO
-to store received image pixel data and embedded DMA controllers to transfer data
-from the FIFO through AHB bus.
-
-This entity has one sink pad that receives from the csi-mux entity and a single
-source pad that routes video frames directly to memory buffers. This pad is
-routed to a capture device node.
-
-Usage Notes
------------
-
-To aid in configuration and for backward compatibility with V4L2 applications
-that access controls only from video device nodes, the capture device interfaces
-inherit controls from the active entities in the current pipeline, so controls
-can be accessed either directly from the subdev or from the active capture
-device interface. For example, the sensor controls are available either from the
-sensor subdevs or from the active capture device.
-
-Warp7 with OV2680
------------------
-
-On this platform an OV2680 MIPI CSI-2 module is connected to the internal MIPI
-CSI-2 receiver. The following example configures a video capture pipeline with
-an output of 800x600, and BGGR 10 bit bayer format:
-
-.. code-block:: none
-
-   # Setup links
-   media-ctl -l "'ov2680 1-0036':0 -> 'imx7-mipi-csis.0':0[1]"
-   media-ctl -l "'imx7-mipi-csis.0':1 -> 'csi-mux':1[1]"
-   media-ctl -l "'csi-mux':2 -> 'csi':0[1]"
-   media-ctl -l "'csi':1 -> 'csi capture':0[1]"
-
-   # Configure pads for pipeline
-   media-ctl -V "'ov2680 1-0036':0 [fmt:SBGGR10_1X10/800x600 field:none]"
-   media-ctl -V "'csi-mux':1 [fmt:SBGGR10_1X10/800x600 field:none]"
-   media-ctl -V "'csi-mux':2 [fmt:SBGGR10_1X10/800x600 field:none]"
-   media-ctl -V "'imx7-mipi-csis.0':0 [fmt:SBGGR10_1X10/800x600 field:none]"
-   media-ctl -V "'csi':0 [fmt:SBGGR10_1X10/800x600 field:none]"
-
-After this streaming can start. The v4l2-ctl tool can be used to select any of
-the resolutions supported by the sensor.
-
-.. code-block:: none
-
-	# media-ctl -p
-	Media controller API version 5.2.0
-
-	Media device information
-	------------------------
-	driver          imx7-csi
-	model           imx-media
-	serial
-	bus info
-	hw revision     0x0
-	driver version  5.2.0
-
-	Device topology
-	- entity 1: csi (2 pads, 2 links)
-	            type V4L2 subdev subtype Unknown flags 0
-	            device node name /dev/v4l-subdev0
-	        pad0: Sink
-	                [fmt:SBGGR10_1X10/800x600 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:full-range]
-	                <- "csi-mux":2 [ENABLED]
-	        pad1: Source
-	                [fmt:SBGGR10_1X10/800x600 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:full-range]
-	                -> "csi capture":0 [ENABLED]
-
-	- entity 4: csi capture (1 pad, 1 link)
-	            type Node subtype V4L flags 0
-	            device node name /dev/video0
-	        pad0: Sink
-	                <- "csi":1 [ENABLED]
-
-	- entity 10: csi-mux (3 pads, 2 links)
-	             type V4L2 subdev subtype Unknown flags 0
-	             device node name /dev/v4l-subdev1
-	        pad0: Sink
-	                [fmt:Y8_1X8/1x1 field:none]
-	        pad1: Sink
-	               [fmt:SBGGR10_1X10/800x600 field:none]
-	                <- "imx7-mipi-csis.0":1 [ENABLED]
-	        pad2: Source
-	                [fmt:SBGGR10_1X10/800x600 field:none]
-	                -> "csi":0 [ENABLED]
-
-	- entity 14: imx7-mipi-csis.0 (2 pads, 2 links)
-	             type V4L2 subdev subtype Unknown flags 0
-	             device node name /dev/v4l-subdev2
-	        pad0: Sink
-	                [fmt:SBGGR10_1X10/800x600 field:none]
-	                <- "ov2680 1-0036":0 [ENABLED]
-	        pad1: Source
-	                [fmt:SBGGR10_1X10/800x600 field:none]
-	                -> "csi-mux":1 [ENABLED]
-
-	- entity 17: ov2680 1-0036 (1 pad, 1 link)
-	             type V4L2 subdev subtype Sensor flags 0
-	             device node name /dev/v4l-subdev3
-	        pad0: Source
-	                [fmt:SBGGR10_1X10/800x600@1/30 field:none colorspace:srgb]
-	                -> "imx7-mipi-csis.0":0 [ENABLED]
-
-References
-----------
-
-.. [#f1] https://www.nxp.com/docs/en/reference-manual/IMX7SRM.pdf
diff --git a/Documentation/media/v4l-drivers/index.rst b/Documentation/media/v4l-drivers/index.rst
deleted file mode 100644
index b41fea23fe5d..000000000000
--- a/Documentation/media/v4l-drivers/index.rst
+++ /dev/null
@@ -1,68 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-.. include:: <isonum.txt>
-
-.. _v4l-drivers:
-
-################################################
-Video4Linux (V4L)  driver-specific documentation
-################################################
-
-**Copyright** |copy| 1999-2016 : LinuxTV Developers
-
-This documentation is free software; 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.
-
-For more details see the file COPYING in the source distribution of Linux.
-
-.. only:: html
-
-   .. class:: toc-title
-
-        Table of Contents
-
-.. toctree::
-	:maxdepth: 5
-	:numbered:
-
-	fourcc
-	v4l-with-ir
-	tuners
-	cardlist
-	bttv
-	cafe_ccic
-	cpia2
-	cx2341x
-	cx88
-	davinci-vpbe
-	fimc
-	imx
-	imx7
-	ipu3
-	ivtv
-	max2175
-	meye
-	omap3isp
-	omap4_camera
-	philips
-	pvrusb2
-	pxa_camera
-	qcom_camss
-	radiotrack
-	rcar-fdp1
-	saa7134
-	sh_mobile_ceu_camera
-	si470x
-	si4713
-	si476x
-	soc-camera
-	uvcvideo
-	vimc
-	vivid
-	zr364xx
diff --git a/Documentation/media/v4l-drivers/ipu3.rst b/Documentation/media/v4l-drivers/ipu3.rst
deleted file mode 100644
index a694f49491f9..000000000000
--- a/Documentation/media/v4l-drivers/ipu3.rst
+++ /dev/null
@@ -1,558 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-.. include:: <isonum.txt>
-
-===============================================================
-Intel Image Processing Unit 3 (IPU3) Imaging Unit (ImgU) driver
-===============================================================
-
-Copyright |copy| 2018 Intel Corporation
-
-Introduction
-============
-
-This file documents the Intel IPU3 (3rd generation Image Processing Unit)
-Imaging Unit drivers located under drivers/media/pci/intel/ipu3 (CIO2) as well
-as under drivers/staging/media/ipu3 (ImgU).
-
-The Intel IPU3 found in certain Kaby Lake (as well as certain Sky Lake)
-platforms (U/Y processor lines) is made up of two parts namely the Imaging Unit
-(ImgU) and the CIO2 device (MIPI CSI2 receiver).
-
-The CIO2 device receives the raw Bayer data from the sensors and outputs the
-frames in a format that is specific to the IPU3 (for consumption by the IPU3
-ImgU). The CIO2 driver is available as drivers/media/pci/intel/ipu3/ipu3-cio2*
-and is enabled through the CONFIG_VIDEO_IPU3_CIO2 config option.
-
-The Imaging Unit (ImgU) is responsible for processing images captured
-by the IPU3 CIO2 device. The ImgU driver sources can be found under
-drivers/staging/media/ipu3 directory. The driver is enabled through the
-CONFIG_VIDEO_IPU3_IMGU config option.
-
-The two driver modules are named ipu3_csi2 and ipu3_imgu, respectively.
-
-The drivers has been tested on Kaby Lake platforms (U/Y processor lines).
-
-Both of the drivers implement V4L2, Media Controller and V4L2 sub-device
-interfaces. The IPU3 CIO2 driver supports camera sensors connected to the CIO2
-MIPI CSI-2 interfaces through V4L2 sub-device sensor drivers.
-
-CIO2
-====
-
-The CIO2 is represented as a single V4L2 subdev, which provides a V4L2 subdev
-interface to the user space. There is a video node for each CSI-2 receiver,
-with a single media controller interface for the entire device.
-
-The CIO2 contains four independent capture channel, each with its own MIPI CSI-2
-receiver and DMA engine. Each channel is modelled as a V4L2 sub-device exposed
-to userspace as a V4L2 sub-device node and has two pads:
-
-.. tabularcolumns:: |p{0.8cm}|p{4.0cm}|p{4.0cm}|
-
-.. flat-table::
-
-    * - pad
-      - direction
-      - purpose
-
-    * - 0
-      - sink
-      - MIPI CSI-2 input, connected to the sensor subdev
-
-    * - 1
-      - source
-      - Raw video capture, connected to the V4L2 video interface
-
-The V4L2 video interfaces model the DMA engines. They are exposed to userspace
-as V4L2 video device nodes.
-
-Capturing frames in raw Bayer format
-------------------------------------
-
-CIO2 MIPI CSI2 receiver is used to capture frames (in packed raw Bayer format)
-from the raw sensors connected to the CSI2 ports. The captured frames are used
-as input to the ImgU driver.
-
-Image processing using IPU3 ImgU requires tools such as raw2pnm [#f1]_, and
-yavta [#f2]_ due to the following unique requirements and / or features specific
-to IPU3.
-
--- The IPU3 CSI2 receiver outputs the captured frames from the sensor in packed
-raw Bayer format that is specific to IPU3.
-
--- Multiple video nodes have to be operated simultaneously.
-
-Let us take the example of ov5670 sensor connected to CSI2 port 0, for a
-2592x1944 image capture.
-
-Using the media contorller APIs, the ov5670 sensor is configured to send
-frames in packed raw Bayer format to IPU3 CSI2 receiver.
-
-# This example assumes /dev/media0 as the CIO2 media device
-
-export MDEV=/dev/media0
-
-# and that ov5670 sensor is connected to i2c bus 10 with address 0x36
-
-export SDEV=$(media-ctl -d $MDEV -e "ov5670 10-0036")
-
-# Establish the link for the media devices using media-ctl [#f3]_
-media-ctl -d $MDEV -l "ov5670:0 -> ipu3-csi2 0:0[1]"
-
-# Set the format for the media devices
-media-ctl -d $MDEV -V "ov5670:0 [fmt:SGRBG10/2592x1944]"
-
-media-ctl -d $MDEV -V "ipu3-csi2 0:0 [fmt:SGRBG10/2592x1944]"
-
-media-ctl -d $MDEV -V "ipu3-csi2 0:1 [fmt:SGRBG10/2592x1944]"
-
-Once the media pipeline is configured, desired sensor specific settings
-(such as exposure and gain settings) can be set, using the yavta tool.
-
-e.g
-
-yavta -w 0x009e0903 444 $SDEV
-
-yavta -w 0x009e0913 1024 $SDEV
-
-yavta -w 0x009e0911 2046 $SDEV
-
-Once the desired sensor settings are set, frame captures can be done as below.
-
-e.g
-
-yavta --data-prefix -u -c10 -n5 -I -s2592x1944 --file=/tmp/frame-#.bin \
-      -f IPU3_SGRBG10 $(media-ctl -d $MDEV -e "ipu3-cio2 0")
-
-With the above command, 10 frames are captured at 2592x1944 resolution, with
-sGRBG10 format and output as IPU3_SGRBG10 format.
-
-The captured frames are available as /tmp/frame-#.bin files.
-
-ImgU
-====
-
-The ImgU is represented as two V4L2 subdevs, each of which provides a V4L2
-subdev interface to the user space.
-
-Each V4L2 subdev represents a pipe, which can support a maximum of 2 streams.
-This helps to support advanced camera features like Continuous View Finder (CVF)
-and Snapshot During Video(SDV).
-
-The ImgU contains two independent pipes, each modelled as a V4L2 sub-device
-exposed to userspace as a V4L2 sub-device node.
-
-Each pipe has two sink pads and three source pads for the following purpose:
-
-.. tabularcolumns:: |p{0.8cm}|p{4.0cm}|p{4.0cm}|
-
-.. flat-table::
-
-    * - pad
-      - direction
-      - purpose
-
-    * - 0
-      - sink
-      - Input raw video stream
-
-    * - 1
-      - sink
-      - Processing parameters
-
-    * - 2
-      - source
-      - Output processed video stream
-
-    * - 3
-      - source
-      - Output viewfinder video stream
-
-    * - 4
-      - source
-      - 3A statistics
-
-Each pad is connected to a corresponding V4L2 video interface, exposed to 
-userspace as a V4L2 video device node.
-
-Device operation
-----------------
-
-With ImgU, once the input video node ("ipu3-imgu 0/1":0, in
-<entity>:<pad-number> format) is queued with buffer (in packed raw Bayer
-format), ImgU starts processing the buffer and produces the video output in YUV
-format and statistics output on respective output nodes. The driver is expected
-to have buffers ready for all of parameter, output and statistics nodes, when
-input video node is queued with buffer.
-
-At a minimum, all of input, main output, 3A statistics and viewfinder
-video nodes should be enabled for IPU3 to start image processing.
-
-Each ImgU V4L2 subdev has the following set of video nodes.
-
-input, output and viewfinder video nodes
-----------------------------------------
-
-The frames (in packed raw Bayer format specific to the IPU3) received by the
-input video node is processed by the IPU3 Imaging Unit and are output to 2 video
-nodes, with each targeting a different purpose (main output and viewfinder
-output).
-
-Details onand the Bayer format specific to the IPU3 can be found in
-:ref:`v4l2-pix-fmt-ipu3-sbggr10`.
-
-The driver supports V4L2 Video Capture Interface as defined at :ref:`devices`.
-
-Only the multi-planar API is supported. More details can be found at
-:ref:`planar-apis`.
-
-Parameters video node
----------------------
-
-The parameters video node receives the ImgU algorithm parameters that are used
-to configure how the ImgU algorithms process the image.
-
-Details on processing parameters specific to the IPU3 can be found in
-:ref:`v4l2-meta-fmt-params`.
-
-3A statistics video node
-------------------------
-
-3A statistics video node is used by the ImgU driver to output the 3A (auto
-focus, auto exposure and auto white balance) statistics for the frames that are
-being processed by the ImgU to user space applications. User space applications
-can use this statistics data to compute the desired algorithm parameters for
-the ImgU.
-
-Configuring the Intel IPU3
-==========================
-
-The IPU3 ImgU pipelines can be configured using the Media Controller, defined at
-:ref:`media_controller`.
-
-Firmware binary selection
--------------------------
-
-The firmware binary is selected using the V4L2_CID_INTEL_IPU3_MODE, currently
-defined in drivers/staging/media/ipu3/include/intel-ipu3.h . "VIDEO" and "STILL"
-modes are available.
-
-Processing the image in raw Bayer format
-----------------------------------------
-
-Configuring ImgU V4L2 subdev for image processing
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The ImgU V4L2 subdevs have to be configured with media controller APIs to have
-all the video nodes setup correctly.
-
-Let us take "ipu3-imgu 0" subdev as an example.
-
-media-ctl -d $MDEV -r
-
-media-ctl -d $MDEV -l "ipu3-imgu 0 input":0 -> "ipu3-imgu 0":0[1]
-
-media-ctl -d $MDEV -l "ipu3-imgu 0":2 -> "ipu3-imgu 0 output":0[1]
-
-media-ctl -d $MDEV -l "ipu3-imgu 0":3 -> "ipu3-imgu 0 viewfinder":0[1]
-
-media-ctl -d $MDEV -l "ipu3-imgu 0":4 -> "ipu3-imgu 0 3a stat":0[1]
-
-Also the pipe mode of the corresponding V4L2 subdev should be set as desired
-(e.g 0 for video mode or 1 for still mode) through the control id 0x009819a1 as
-below.
-
-yavta -w "0x009819A1 1" /dev/v4l-subdev7
-
-Certain hardware blocks in ImgU pipeline can change the frame resolution by
-cropping or scaling, these hardware blocks include Input Feeder(IF), Bayer Down
-Scaler (BDS) and Geometric Distortion Correction (GDC).
-There is also a block which can change the frame resolution - YUV Scaler, it is
-only applicable to the secondary output.
-
-RAW Bayer frames go through these ImgU pipeline hardware blocks and the final
-processed image output to the DDR memory.
-
-.. kernel-figure::  ipu3_rcb.svg
-   :alt: ipu3 resolution blocks image
-
-   IPU3 resolution change hardware blocks
-
-**Input Feeder**
-
-Input Feeder gets the Bayer frame data from the sensor, it can enable cropping
-of lines and columns from the frame and then store pixels into device's internal
-pixel buffer which are ready to readout by following blocks.
-
-**Bayer Down Scaler**
-
-Bayer Down Scaler is capable of performing image scaling in Bayer domain, the
-downscale factor can be configured from 1X to 1/4X in each axis with
-configuration steps of 0.03125 (1/32).
-
-**Geometric Distortion Correction**
-
-Geometric Distortion Correction is used to performe correction of distortions
-and image filtering. It needs some extra filter and envelop padding pixels to
-work, so the input resolution of GDC should be larger than the output
-resolution.
-
-**YUV Scaler**
-
-YUV Scaler which similar with BDS, but it is mainly do image down scaling in
-YUV domain, it can support up to 1/12X down scaling, but it can not be applied
-to the main output.
-
-The ImgU V4L2 subdev has to be configured with the supported resolutions in all
-the above hardware blocks, for a given input resolution.
-For a given supported resolution for an input frame, the Input Feeder, Bayer
-Down Scaler and GDC blocks should be configured with the supported resolutions
-as each hardware block has its own alignment requirement.
-
-You must configure the output resolution of the hardware blocks smartly to meet
-the hardware requirement along with keeping the maximum field of view. The
-intermediate resolutions can be generated by specific tool -
-
-https://github.com/intel/intel-ipu3-pipecfg
-
-This tool can be used to generate intermediate resolutions. More information can
-be obtained by looking at the following IPU3 ImgU configuration table.
-
-https://chromium.googlesource.com/chromiumos/overlays/board-overlays/+/master
-
-Under baseboard-poppy/media-libs/cros-camera-hal-configs-poppy/files/gcss
-directory, graph_settings_ov5670.xml can be used as an example.
-
-The following steps prepare the ImgU pipeline for the image processing.
-
-1. The ImgU V4L2 subdev data format should be set by using the
-VIDIOC_SUBDEV_S_FMT on pad 0, using the GDC width and height obtained above.
-
-2. The ImgU V4L2 subdev cropping should be set by using the
-VIDIOC_SUBDEV_S_SELECTION on pad 0, with V4L2_SEL_TGT_CROP as the target,
-using the input feeder height and width.
-
-3. The ImgU V4L2 subdev composing should be set by using the
-VIDIOC_SUBDEV_S_SELECTION on pad 0, with V4L2_SEL_TGT_COMPOSE as the target,
-using the BDS height and width.
-
-For the ov5670 example, for an input frame with a resolution of 2592x1944
-(which is input to the ImgU subdev pad 0), the corresponding resolutions
-for input feeder, BDS and GDC are 2592x1944, 2592x1944 and 2560x1920
-respectively.
-
-Once this is done, the received raw Bayer frames can be input to the ImgU
-V4L2 subdev as below, using the open source application v4l2n [#f1]_.
-
-For an image captured with 2592x1944 [#f4]_ resolution, with desired output
-resolution as 2560x1920 and viewfinder resolution as 2560x1920, the following
-v4l2n command can be used. This helps process the raw Bayer frames and produces
-the desired results for the main output image and the viewfinder output, in NV12
-format.
-
-v4l2n --pipe=4 --load=/tmp/frame-#.bin --open=/dev/video4
---fmt=type:VIDEO_OUTPUT_MPLANE,width=2592,height=1944,pixelformat=0X47337069
---reqbufs=type:VIDEO_OUTPUT_MPLANE,count:1 --pipe=1 --output=/tmp/frames.out
---open=/dev/video5
---fmt=type:VIDEO_CAPTURE_MPLANE,width=2560,height=1920,pixelformat=NV12
---reqbufs=type:VIDEO_CAPTURE_MPLANE,count:1 --pipe=2 --output=/tmp/frames.vf
---open=/dev/video6
---fmt=type:VIDEO_CAPTURE_MPLANE,width=2560,height=1920,pixelformat=NV12
---reqbufs=type:VIDEO_CAPTURE_MPLANE,count:1 --pipe=3 --open=/dev/video7
---output=/tmp/frames.3A --fmt=type:META_CAPTURE,?
---reqbufs=count:1,type:META_CAPTURE --pipe=1,2,3,4 --stream=5
-
-where /dev/video4, /dev/video5, /dev/video6 and /dev/video7 devices point to
-input, output, viewfinder and 3A statistics video nodes respectively.
-
-Converting the raw Bayer image into YUV domain
-----------------------------------------------
-
-The processed images after the above step, can be converted to YUV domain
-as below.
-
-Main output frames
-~~~~~~~~~~~~~~~~~~
-
-raw2pnm -x2560 -y1920 -fNV12 /tmp/frames.out /tmp/frames.out.ppm
-
-where 2560x1920 is output resolution, NV12 is the video format, followed
-by input frame and output PNM file.
-
-Viewfinder output frames
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-raw2pnm -x2560 -y1920 -fNV12 /tmp/frames.vf /tmp/frames.vf.ppm
-
-where 2560x1920 is output resolution, NV12 is the video format, followed
-by input frame and output PNM file.
-
-Example user space code for IPU3
-================================
-
-User space code that configures and uses IPU3 is available here.
-
-https://chromium.googlesource.com/chromiumos/platform/arc-camera/+/master/
-
-The source can be located under hal/intel directory.
-
-Overview of IPU3 pipeline
-=========================
-
-IPU3 pipeline has a number of image processing stages, each of which takes a
-set of parameters as input. The major stages of pipelines are shown here:
-
-.. kernel-render:: DOT
-   :alt: IPU3 ImgU Pipeline
-   :caption: IPU3 ImgU Pipeline Diagram
-
-   digraph "IPU3 ImgU" {
-       node [shape=box]
-       splines="ortho"
-       rankdir="LR"
-
-       a [label="Raw pixels"]
-       b [label="Bayer Downscaling"]
-       c [label="Optical Black Correction"]
-       d [label="Linearization"]
-       e [label="Lens Shading Correction"]
-       f [label="White Balance / Exposure / Focus Apply"]
-       g [label="Bayer Noise Reduction"]
-       h [label="ANR"]
-       i [label="Demosaicing"]
-       j [label="Color Correction Matrix"]
-       k [label="Gamma correction"]
-       l [label="Color Space Conversion"]
-       m [label="Chroma Down Scaling"]
-       n [label="Chromatic Noise Reduction"]
-       o [label="Total Color Correction"]
-       p [label="XNR3"]
-       q [label="TNR"]
-       r [label="DDR"]
-
-       { rank=same; a -> b -> c -> d -> e -> f }
-       { rank=same; g -> h -> i -> j -> k -> l }
-       { rank=same; m -> n -> o -> p -> q -> r }
-
-       a -> g -> m [style=invis, weight=10]
-
-       f -> g
-       l -> m
-   }
-
-The table below presents a description of the above algorithms.
-
-======================== =======================================================
-Name			 Description
-======================== =======================================================
-Optical Black Correction Optical Black Correction block subtracts a pre-defined
-			 value from the respective pixel values to obtain better
-			 image quality.
-			 Defined in :c:type:`ipu3_uapi_obgrid_param`.
-Linearization		 This algo block uses linearization parameters to
-			 address non-linearity sensor effects. The Lookup table
-			 table is defined in
-			 :c:type:`ipu3_uapi_isp_lin_vmem_params`.
-SHD			 Lens shading correction is used to correct spatial
-			 non-uniformity of the pixel response due to optical
-			 lens shading. This is done by applying a different gain
-			 for each pixel. The gain, black level etc are
-			 configured in :c:type:`ipu3_uapi_shd_config_static`.
-BNR			 Bayer noise reduction block removes image noise by
-			 applying a bilateral filter.
-			 See :c:type:`ipu3_uapi_bnr_static_config` for details.
-ANR			 Advanced Noise Reduction is a block based algorithm
-			 that performs noise reduction in the Bayer domain. The
-			 convolution matrix etc can be found in
-			 :c:type:`ipu3_uapi_anr_config`.
-DM			 Demosaicing converts raw sensor data in Bayer format
-			 into RGB (Red, Green, Blue) presentation. Then add
-			 outputs of estimation of Y channel for following stream
-			 processing by Firmware. The struct is defined as
-			 :c:type:`ipu3_uapi_dm_config`.
-Color Correction	 Color Correction algo transforms sensor specific color
-			 space to the standard "sRGB" color space. This is done
-			 by applying 3x3 matrix defined in
-			 :c:type:`ipu3_uapi_ccm_mat_config`.
-Gamma correction	 Gamma correction :c:type:`ipu3_uapi_gamma_config` is a
-			 basic non-linear tone mapping correction that is
-			 applied per pixel for each pixel component.
-CSC			 Color space conversion transforms each pixel from the
-			 RGB primary presentation to YUV (Y: brightness,
-			 UV: Luminance) presentation. This is done by applying
-			 a 3x3 matrix defined in
-			 :c:type:`ipu3_uapi_csc_mat_config`
-CDS			 Chroma down sampling
-			 After the CSC is performed, the Chroma Down Sampling
-			 is applied for a UV plane down sampling by a factor
-			 of 2 in each direction for YUV 4:2:0 using a 4x2
-			 configurable filter :c:type:`ipu3_uapi_cds_params`.
-CHNR			 Chroma noise reduction
-			 This block processes only the chrominance pixels and
-			 performs noise reduction by cleaning the high
-			 frequency noise.
-			 See struct :c:type:`ipu3_uapi_yuvp1_chnr_config`.
-TCC			 Total color correction as defined in struct
-			 :c:type:`ipu3_uapi_yuvp2_tcc_static_config`.
-XNR3			 eXtreme Noise Reduction V3 is the third revision of
-			 noise reduction algorithm used to improve image
-			 quality. This removes the low frequency noise in the
-			 captured image. Two related structs are  being defined,
-			 :c:type:`ipu3_uapi_isp_xnr3_params` for ISP data memory
-			 and :c:type:`ipu3_uapi_isp_xnr3_vmem_params` for vector
-			 memory.
-TNR			 Temporal Noise Reduction block compares successive
-			 frames in time to remove anomalies / noise in pixel
-			 values. :c:type:`ipu3_uapi_isp_tnr3_vmem_params` and
-			 :c:type:`ipu3_uapi_isp_tnr3_params` are defined for ISP
-			 vector and data memory respectively.
-======================== =======================================================
-
-Other often encountered acronyms not listed in above table:
-
-	ACC
-		Accelerator cluster
-	AWB_FR
-		Auto white balance filter response statistics
-	BDS
-		Bayer downscaler parameters
-	CCM
-		Color correction matrix coefficients
-	IEFd
-		Image enhancement filter directed
-	Obgrid
-		Optical black level compensation
-	OSYS
-		Output system configuration
-	ROI
-		Region of interest
-	YDS
-		Y down sampling
-	YTM
-		Y-tone mapping
-
-A few stages of the pipeline will be executed by firmware running on the ISP
-processor, while many others will use a set of fixed hardware blocks also
-called accelerator cluster (ACC) to crunch pixel data and produce statistics.
-
-ACC parameters of individual algorithms, as defined by
-:c:type:`ipu3_uapi_acc_param`, can be chosen to be applied by the user
-space through struct :c:type:`ipu3_uapi_flags` embedded in
-:c:type:`ipu3_uapi_params` structure. For parameters that are configured as
-not enabled by the user space, the corresponding structs are ignored by the
-driver, in which case the existing configuration of the algorithm will be
-preserved.
-
-References
-==========
-
-.. [#f5] drivers/staging/media/ipu3/include/intel-ipu3.h
-
-.. [#f1] https://github.com/intel/nvt
-
-.. [#f2] http://git.ideasonboard.org/yavta.git
-
-.. [#f3] http://git.ideasonboard.org/?p=media-ctl.git;a=summary
-
-.. [#f4] ImgU limitation requires an additional 16x16 for all input resolutions
diff --git a/Documentation/media/v4l-drivers/ipu3_rcb.svg b/Documentation/media/v4l-drivers/ipu3_rcb.svg
deleted file mode 100644
index d878421b42a0..000000000000
--- a/Documentation/media/v4l-drivers/ipu3_rcb.svg
+++ /dev/null
@@ -1,331 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="774pt" height="152pt" viewBox="0 0 774 152" version="1.1">
-<defs>
-<g>
-<symbol overflow="visible" id="glyph0-0">
-<path style="stroke:none;" d="M 1 0 L 1 -15 L 9 -15 L 9 0 Z M 8 -1 L 8 -14 L 2 -14 L 2 -1 Z M 8 -1 "/>
-</symbol>
-<symbol overflow="visible" id="glyph0-1">
-<path style="stroke:none;" d="M 4.6875 -1.15625 C 5.519531 -1.15625 6.15625 -1.316406 6.59375 -1.640625 C 7.039062 -1.960938 7.265625 -2.441406 7.265625 -3.078125 C 7.265625 -3.460938 7.179688 -3.789062 7.015625 -4.0625 C 6.859375 -4.34375 6.644531 -4.582031 6.375 -4.78125 C 6.113281 -4.988281 5.816406 -5.171875 5.484375 -5.328125 C 5.148438 -5.484375 4.804688 -5.628906 4.453125 -5.765625 C 4.054688 -5.921875 3.675781 -6.097656 3.3125 -6.296875 C 2.945312 -6.492188 2.617188 -6.726562 2.328125 -7 C 2.046875 -7.269531 1.820312 -7.582031 1.65625 -7.9375 C 1.488281 -8.300781 1.40625 -8.726562 1.40625 -9.21875 C 1.40625 -10.300781 1.742188 -11.144531 2.421875 -11.75 C 3.097656 -12.351562 4.046875 -12.65625 5.265625 -12.65625 C 5.597656 -12.65625 5.925781 -12.628906 6.25 -12.578125 C 6.570312 -12.535156 6.875 -12.476562 7.15625 -12.40625 C 7.4375 -12.34375 7.6875 -12.265625 7.90625 -12.171875 C 8.125 -12.085938 8.300781 -12 8.4375 -11.90625 L 7.921875 -10.515625 C 7.648438 -10.679688 7.28125 -10.84375 6.8125 -11 C 6.351562 -11.15625 5.835938 -11.234375 5.265625 -11.234375 C 4.660156 -11.234375 4.140625 -11.082031 3.703125 -10.78125 C 3.265625 -10.488281 3.046875 -10.039062 3.046875 -9.4375 C 3.046875 -9.09375 3.109375 -8.800781 3.234375 -8.5625 C 3.359375 -8.320312 3.53125 -8.109375 3.75 -7.921875 C 3.96875 -7.742188 4.222656 -7.582031 4.515625 -7.4375 C 4.804688 -7.289062 5.128906 -7.144531 5.484375 -7 C 5.984375 -6.789062 6.441406 -6.578125 6.859375 -6.359375 C 7.285156 -6.148438 7.648438 -5.894531 7.953125 -5.59375 C 8.253906 -5.300781 8.488281 -4.953125 8.65625 -4.546875 C 8.820312 -4.148438 8.90625 -3.664062 8.90625 -3.09375 C 8.90625 -2.019531 8.539062 -1.191406 7.8125 -0.609375 C 7.082031 -0.0234375 6.039062 0.265625 4.6875 0.265625 C 4.238281 0.265625 3.820312 0.234375 3.4375 0.171875 C 3.050781 0.109375 2.707031 0.03125 2.40625 -0.0625 C 2.101562 -0.15625 1.835938 -0.25 1.609375 -0.34375 C 1.390625 -0.4375 1.21875 -0.519531 1.09375 -0.59375 L 1.59375 -1.953125 C 1.863281 -1.804688 2.257812 -1.632812 2.78125 -1.4375 C 3.300781 -1.25 3.9375 -1.15625 4.6875 -1.15625 Z M 4.6875 -1.15625 "/>
-</symbol>
-<symbol overflow="visible" id="glyph0-2">
-<path style="stroke:none;" d="M 5.1875 -9.5 C 6.4375 -9.5 7.398438 -9.109375 8.078125 -8.328125 C 8.753906 -7.546875 9.09375 -6.363281 9.09375 -4.78125 L 9.09375 -4.203125 L 2.453125 -4.203125 C 2.523438 -3.242188 2.84375 -2.515625 3.40625 -2.015625 C 3.976562 -1.515625 4.773438 -1.265625 5.796875 -1.265625 C 6.390625 -1.265625 6.890625 -1.3125 7.296875 -1.40625 C 7.710938 -1.5 8.023438 -1.597656 8.234375 -1.703125 L 8.453125 -0.296875 C 8.253906 -0.191406 7.894531 -0.0820312 7.375 0.03125 C 6.851562 0.15625 6.269531 0.21875 5.625 0.21875 C 4.820312 0.21875 4.113281 0.0976562 3.5 -0.140625 C 2.894531 -0.390625 2.394531 -0.726562 2 -1.15625 C 1.601562 -1.582031 1.300781 -2.09375 1.09375 -2.6875 C 0.894531 -3.28125 0.796875 -3.925781 0.796875 -4.625 C 0.796875 -5.445312 0.921875 -6.164062 1.171875 -6.78125 C 1.429688 -7.394531 1.765625 -7.898438 2.171875 -8.296875 C 2.585938 -8.703125 3.054688 -9.003906 3.578125 -9.203125 C 4.097656 -9.398438 4.632812 -9.5 5.1875 -9.5 Z M 7.421875 -5.546875 C 7.421875 -6.328125 7.210938 -6.945312 6.796875 -7.40625 C 6.390625 -7.863281 5.84375 -8.09375 5.15625 -8.09375 C 4.769531 -8.09375 4.421875 -8.019531 4.109375 -7.875 C 3.796875 -7.726562 3.523438 -7.535156 3.296875 -7.296875 C 3.066406 -7.054688 2.882812 -6.78125 2.75 -6.46875 C 2.625 -6.164062 2.539062 -5.859375 2.5 -5.546875 Z M 7.421875 -5.546875 "/>
-</symbol>
-<symbol overflow="visible" id="glyph0-3">
-<path style="stroke:none;" d="M 1.421875 -9.015625 C 2.015625 -9.160156 2.609375 -9.273438 3.203125 -9.359375 C 3.796875 -9.441406 4.351562 -9.484375 4.875 -9.484375 C 6.113281 -9.484375 7.050781 -9.160156 7.6875 -8.515625 C 8.320312 -7.878906 8.640625 -6.851562 8.640625 -5.4375 L 8.640625 0 L 7 0 L 7 -5.140625 C 7 -5.742188 6.945312 -6.226562 6.84375 -6.59375 C 6.738281 -6.96875 6.585938 -7.257812 6.390625 -7.46875 C 6.191406 -7.675781 5.957031 -7.816406 5.6875 -7.890625 C 5.414062 -7.972656 5.117188 -8.015625 4.796875 -8.015625 C 4.535156 -8.015625 4.253906 -8 3.953125 -7.96875 C 3.648438 -7.9375 3.359375 -7.894531 3.078125 -7.84375 L 3.078125 0 L 1.421875 0 Z M 1.421875 -9.015625 "/>
-</symbol>
-<symbol overflow="visible" id="glyph0-4">
-<path style="stroke:none;" d="M 7.015625 -2.3125 C 7.015625 -2.644531 6.878906 -2.914062 6.609375 -3.125 C 6.335938 -3.34375 6 -3.53125 5.59375 -3.6875 C 5.1875 -3.851562 4.742188 -4.015625 4.265625 -4.171875 C 3.785156 -4.328125 3.335938 -4.515625 2.921875 -4.734375 C 2.515625 -4.960938 2.175781 -5.242188 1.90625 -5.578125 C 1.632812 -5.910156 1.5 -6.34375 1.5 -6.875 C 1.5 -7.625 1.800781 -8.25 2.40625 -8.75 C 3.007812 -9.25 3.960938 -9.5 5.265625 -9.5 C 5.765625 -9.5 6.285156 -9.460938 6.828125 -9.390625 C 7.367188 -9.316406 7.832031 -9.21875 8.21875 -9.09375 L 7.921875 -7.625 C 7.816406 -7.675781 7.671875 -7.726562 7.484375 -7.78125 C 7.296875 -7.84375 7.082031 -7.894531 6.84375 -7.9375 C 6.601562 -7.988281 6.34375 -8.023438 6.0625 -8.046875 C 5.789062 -8.078125 5.53125 -8.09375 5.28125 -8.09375 C 3.84375 -8.09375 3.125 -7.703125 3.125 -6.921875 C 3.125 -6.640625 3.257812 -6.398438 3.53125 -6.203125 C 3.800781 -6.015625 4.144531 -5.835938 4.5625 -5.671875 C 4.976562 -5.515625 5.425781 -5.351562 5.90625 -5.1875 C 6.382812 -5.019531 6.828125 -4.816406 7.234375 -4.578125 C 7.648438 -4.335938 7.992188 -4.046875 8.265625 -3.703125 C 8.546875 -3.367188 8.6875 -2.941406 8.6875 -2.421875 C 8.6875 -1.578125 8.359375 -0.925781 7.703125 -0.46875 C 7.046875 -0.0078125 6.007812 0.21875 4.59375 0.21875 C 3.957031 0.21875 3.375 0.164062 2.84375 0.0625 C 2.3125 -0.0390625 1.800781 -0.203125 1.3125 -0.421875 L 1.640625 -1.921875 C 2.109375 -1.703125 2.597656 -1.523438 3.109375 -1.390625 C 3.617188 -1.253906 4.171875 -1.1875 4.765625 -1.1875 C 6.265625 -1.1875 7.015625 -1.5625 7.015625 -2.3125 Z M 7.015625 -2.3125 "/>
-</symbol>
-<symbol overflow="visible" id="glyph0-5">
-<path style="stroke:none;" d="M 9.203125 -4.640625 C 9.203125 -3.910156 9.097656 -3.25 8.890625 -2.65625 C 8.679688 -2.0625 8.390625 -1.550781 8.015625 -1.125 C 7.640625 -0.695312 7.191406 -0.363281 6.671875 -0.125 C 6.160156 0.101562 5.597656 0.21875 4.984375 0.21875 C 4.378906 0.21875 3.820312 0.101562 3.3125 -0.125 C 2.800781 -0.363281 2.359375 -0.695312 1.984375 -1.125 C 1.609375 -1.550781 1.316406 -2.0625 1.109375 -2.65625 C 0.898438 -3.25 0.796875 -3.910156 0.796875 -4.640625 C 0.796875 -5.367188 0.898438 -6.035156 1.109375 -6.640625 C 1.316406 -7.242188 1.609375 -7.753906 1.984375 -8.171875 C 2.359375 -8.585938 2.800781 -8.910156 3.3125 -9.140625 C 3.820312 -9.378906 4.378906 -9.5 4.984375 -9.5 C 5.597656 -9.5 6.160156 -9.378906 6.671875 -9.140625 C 7.191406 -8.910156 7.640625 -8.585938 8.015625 -8.171875 C 8.390625 -7.753906 8.679688 -7.242188 8.890625 -6.640625 C 9.097656 -6.035156 9.203125 -5.367188 9.203125 -4.640625 Z M 7.5 -4.640625 C 7.5 -5.691406 7.269531 -6.519531 6.8125 -7.125 C 6.363281 -7.738281 5.753906 -8.046875 4.984375 -8.046875 C 4.222656 -8.046875 3.617188 -7.738281 3.171875 -7.125 C 2.722656 -6.519531 2.5 -5.691406 2.5 -4.640625 C 2.5 -3.597656 2.722656 -2.773438 3.171875 -2.171875 C 3.617188 -1.566406 4.222656 -1.265625 4.984375 -1.265625 C 5.753906 -1.265625 6.363281 -1.566406 6.8125 -2.171875 C 7.269531 -2.773438 7.5 -3.597656 7.5 -4.640625 Z M 7.5 -4.640625 "/>
-</symbol>
-<symbol overflow="visible" id="glyph0-6">
-<path style="stroke:none;" d="M 2.140625 0 L 2.140625 -8.78125 C 3.503906 -9.25 4.878906 -9.484375 6.265625 -9.484375 C 6.691406 -9.484375 7.097656 -9.460938 7.484375 -9.421875 C 7.867188 -9.390625 8.296875 -9.320312 8.765625 -9.21875 L 8.453125 -7.765625 C 8.023438 -7.878906 7.648438 -7.953125 7.328125 -7.984375 C 7.003906 -8.023438 6.648438 -8.046875 6.265625 -8.046875 C 5.453125 -8.046875 4.625 -7.929688 3.78125 -7.703125 L 3.78125 0 Z M 2.140625 0 "/>
-</symbol>
-<symbol overflow="visible" id="glyph0-7">
-<path style="stroke:none;" d="M 5.8125 -10.984375 L 5.8125 -1.40625 L 8.21875 -1.40625 L 8.21875 0 L 1.78125 0 L 1.78125 -1.40625 L 4.1875 -1.40625 L 4.1875 -10.984375 L 1.78125 -10.984375 L 1.78125 -12.375 L 8.21875 -12.375 L 8.21875 -10.984375 Z M 5.8125 -10.984375 "/>
-</symbol>
-<symbol overflow="visible" id="glyph0-8">
-<path style="stroke:none;" d="M 1.8125 0 L 1.8125 -12.375 L 8.84375 -12.375 L 8.84375 -10.984375 L 3.453125 -10.984375 L 3.453125 -7.125 L 8.203125 -7.125 L 8.203125 -5.734375 L 3.453125 -5.734375 L 3.453125 0 Z M 1.8125 0 "/>
-</symbol>
-<symbol overflow="visible" id="glyph0-9">
-<path style="stroke:none;" d="M 4.078125 0.09375 C 3.878906 0.09375 3.644531 0.0859375 3.375 0.078125 C 3.113281 0.0664062 2.847656 0.0507812 2.578125 0.03125 C 2.316406 0.0078125 2.050781 -0.0195312 1.78125 -0.0625 C 1.507812 -0.101562 1.273438 -0.148438 1.078125 -0.203125 L 1.078125 -12.203125 C 1.273438 -12.253906 1.503906 -12.300781 1.765625 -12.34375 C 2.023438 -12.382812 2.289062 -12.410156 2.5625 -12.421875 C 2.84375 -12.441406 3.113281 -12.457031 3.375 -12.46875 C 3.632812 -12.488281 3.867188 -12.5 4.078125 -12.5 C 4.691406 -12.5 5.265625 -12.445312 5.796875 -12.34375 C 6.328125 -12.238281 6.789062 -12.054688 7.1875 -11.796875 C 7.582031 -11.546875 7.890625 -11.210938 8.109375 -10.796875 C 8.328125 -10.390625 8.4375 -9.878906 8.4375 -9.265625 C 8.4375 -8.960938 8.390625 -8.675781 8.296875 -8.40625 C 8.203125 -8.132812 8.070312 -7.878906 7.90625 -7.640625 C 7.738281 -7.398438 7.546875 -7.1875 7.328125 -7 C 7.109375 -6.820312 6.875 -6.6875 6.625 -6.59375 C 7.300781 -6.40625 7.867188 -6.0625 8.328125 -5.5625 C 8.785156 -5.0625 9.015625 -4.414062 9.015625 -3.625 C 9.015625 -2.394531 8.617188 -1.46875 7.828125 -0.84375 C 7.046875 -0.21875 5.796875 0.09375 4.078125 0.09375 Z M 2.71875 -5.78125 L 2.71875 -1.359375 C 2.75 -1.347656 2.898438 -1.332031 3.171875 -1.3125 C 3.441406 -1.289062 3.785156 -1.28125 4.203125 -1.28125 C 4.609375 -1.28125 5 -1.3125 5.375 -1.375 C 5.757812 -1.445312 6.097656 -1.570312 6.390625 -1.75 C 6.691406 -1.925781 6.929688 -2.160156 7.109375 -2.453125 C 7.285156 -2.753906 7.375 -3.132812 7.375 -3.59375 C 7.375 -4.007812 7.289062 -4.359375 7.125 -4.640625 C 6.957031 -4.921875 6.738281 -5.144531 6.46875 -5.3125 C 6.195312 -5.476562 5.878906 -5.597656 5.515625 -5.671875 C 5.160156 -5.742188 4.789062 -5.78125 4.40625 -5.78125 Z M 2.71875 -7.140625 L 4.015625 -7.140625 C 4.347656 -7.140625 4.679688 -7.171875 5.015625 -7.234375 C 5.347656 -7.304688 5.644531 -7.414062 5.90625 -7.5625 C 6.175781 -7.707031 6.390625 -7.90625 6.546875 -8.15625 C 6.710938 -8.414062 6.796875 -8.738281 6.796875 -9.125 C 6.796875 -9.476562 6.722656 -9.78125 6.578125 -10.03125 C 6.429688 -10.289062 6.238281 -10.5 6 -10.65625 C 5.757812 -10.820312 5.484375 -10.9375 5.171875 -11 C 4.859375 -11.0625 4.53125 -11.09375 4.1875 -11.09375 C 3.832031 -11.09375 3.523438 -11.085938 3.265625 -11.078125 C 3.003906 -11.078125 2.820312 -11.066406 2.71875 -11.046875 Z M 2.71875 -7.140625 "/>
-</symbol>
-<symbol overflow="visible" id="glyph0-10">
-<path style="stroke:none;" d="M 9.203125 -6.203125 C 9.203125 -5.054688 9.054688 -4.082031 8.765625 -3.28125 C 8.484375 -2.476562 8.09375 -1.828125 7.59375 -1.328125 C 7.09375 -0.828125 6.5 -0.460938 5.8125 -0.234375 C 5.125 -0.015625 4.378906 0.09375 3.578125 0.09375 C 2.753906 0.09375 1.921875 -0.00390625 1.078125 -0.203125 L 1.078125 -12.203125 C 1.921875 -12.398438 2.753906 -12.5 3.578125 -12.5 C 4.378906 -12.5 5.125 -12.382812 5.8125 -12.15625 C 6.5 -11.925781 7.09375 -11.554688 7.59375 -11.046875 C 8.09375 -10.546875 8.484375 -9.894531 8.765625 -9.09375 C 9.054688 -8.300781 9.203125 -7.335938 9.203125 -6.203125 Z M 2.71875 -1.375 C 3.050781 -1.332031 3.390625 -1.3125 3.734375 -1.3125 C 4.335938 -1.3125 4.875 -1.398438 5.34375 -1.578125 C 5.8125 -1.765625 6.203125 -2.054688 6.515625 -2.453125 C 6.835938 -2.847656 7.082031 -3.351562 7.25 -3.96875 C 7.425781 -4.59375 7.515625 -5.335938 7.515625 -6.203125 C 7.515625 -7.878906 7.191406 -9.109375 6.546875 -9.890625 C 5.898438 -10.679688 4.945312 -11.078125 3.6875 -11.078125 C 3.507812 -11.078125 3.335938 -11.070312 3.171875 -11.0625 C 3.003906 -11.0625 2.851562 -11.046875 2.71875 -11.015625 Z M 2.71875 -1.375 "/>
-</symbol>
-<symbol overflow="visible" id="glyph0-11">
-<path style="stroke:none;" d="M 7.453125 -6.09375 L 9.09375 -6.09375 L 9.09375 -0.296875 C 8.84375 -0.203125 8.4375 -0.0859375 7.875 0.046875 C 7.320312 0.191406 6.664062 0.265625 5.90625 0.265625 C 5.15625 0.265625 4.472656 0.125 3.859375 -0.15625 C 3.242188 -0.445312 2.71875 -0.863281 2.28125 -1.40625 C 1.851562 -1.957031 1.519531 -2.632812 1.28125 -3.4375 C 1.039062 -4.25 0.921875 -5.171875 0.921875 -6.203125 C 0.921875 -7.242188 1.050781 -8.160156 1.3125 -8.953125 C 1.582031 -9.753906 1.945312 -10.425781 2.40625 -10.96875 C 2.863281 -11.519531 3.398438 -11.9375 4.015625 -12.21875 C 4.628906 -12.507812 5.289062 -12.65625 6 -12.65625 C 6.457031 -12.65625 6.859375 -12.617188 7.203125 -12.546875 C 7.546875 -12.484375 7.835938 -12.40625 8.078125 -12.3125 C 8.328125 -12.226562 8.53125 -12.132812 8.6875 -12.03125 C 8.851562 -11.925781 8.976562 -11.847656 9.0625 -11.796875 L 8.515625 -10.421875 C 8.210938 -10.660156 7.847656 -10.851562 7.421875 -11 C 7.003906 -11.15625 6.5625 -11.234375 6.09375 -11.234375 C 5.59375 -11.234375 5.125 -11.113281 4.6875 -10.875 C 4.257812 -10.632812 3.890625 -10.296875 3.578125 -9.859375 C 3.273438 -9.421875 3.035156 -8.890625 2.859375 -8.265625 C 2.679688 -7.648438 2.59375 -6.960938 2.59375 -6.203125 C 2.59375 -5.453125 2.671875 -4.769531 2.828125 -4.15625 C 2.984375 -3.539062 3.207031 -3.015625 3.5 -2.578125 C 3.789062 -2.140625 4.148438 -1.796875 4.578125 -1.546875 C 5.015625 -1.304688 5.515625 -1.1875 6.078125 -1.1875 C 6.460938 -1.1875 6.757812 -1.210938 6.96875 -1.265625 C 7.1875 -1.316406 7.347656 -1.367188 7.453125 -1.421875 Z M 7.453125 -6.09375 "/>
-</symbol>
-<symbol overflow="visible" id="glyph0-12">
-<path style="stroke:none;" d="M 9.203125 -0.515625 C 8.734375 -0.253906 8.234375 -0.0625 7.703125 0.0625 C 7.179688 0.195312 6.617188 0.265625 6.015625 0.265625 C 5.285156 0.265625 4.609375 0.132812 3.984375 -0.125 C 3.367188 -0.382812 2.832031 -0.773438 2.375 -1.296875 C 1.925781 -1.828125 1.570312 -2.5 1.3125 -3.3125 C 1.050781 -4.132812 0.921875 -5.097656 0.921875 -6.203125 C 0.921875 -7.253906 1.054688 -8.179688 1.328125 -8.984375 C 1.597656 -9.785156 1.96875 -10.457031 2.4375 -11 C 2.90625 -11.539062 3.453125 -11.953125 4.078125 -12.234375 C 4.703125 -12.515625 5.367188 -12.65625 6.078125 -12.65625 C 6.566406 -12.65625 7.066406 -12.585938 7.578125 -12.453125 C 8.097656 -12.328125 8.601562 -12.109375 9.09375 -11.796875 L 8.625 -10.4375 C 7.738281 -10.945312 6.910156 -11.203125 6.140625 -11.203125 C 5.585938 -11.203125 5.09375 -11.082031 4.65625 -10.84375 C 4.226562 -10.613281 3.859375 -10.28125 3.546875 -9.84375 C 3.242188 -9.40625 3.007812 -8.878906 2.84375 -8.265625 C 2.675781 -7.648438 2.59375 -6.960938 2.59375 -6.203125 C 2.59375 -5.347656 2.679688 -4.609375 2.859375 -3.984375 C 3.046875 -3.359375 3.296875 -2.835938 3.609375 -2.421875 C 3.929688 -2.003906 4.316406 -1.695312 4.765625 -1.5 C 5.210938 -1.300781 5.695312 -1.203125 6.21875 -1.203125 C 6.601562 -1.203125 7.007812 -1.25 7.4375 -1.34375 C 7.863281 -1.445312 8.304688 -1.625 8.765625 -1.875 Z M 9.203125 -0.515625 "/>
-</symbol>
-<symbol overflow="visible" id="glyph1-0">
-<path style="stroke:none;" d="M 0.59375 0 L 0.59375 -9 L 5.40625 -9 L 5.40625 0 Z M 4.796875 -0.59375 L 4.796875 -8.40625 L 1.203125 -8.40625 L 1.203125 -0.59375 Z M 4.796875 -0.59375 "/>
-</symbol>
-<symbol overflow="visible" id="glyph1-1">
-<path style="stroke:none;" d="M 2.515625 0 L 2.515625 -2.765625 C 2.023438 -3.554688 1.582031 -4.332031 1.1875 -5.09375 C 0.789062 -5.851562 0.445312 -6.628906 0.15625 -7.421875 L 1.265625 -7.421875 C 1.492188 -6.753906 1.757812 -6.113281 2.0625 -5.5 C 2.363281 -4.882812 2.6875 -4.253906 3.03125 -3.609375 C 3.394531 -4.285156 3.71875 -4.929688 4 -5.546875 C 4.28125 -6.160156 4.539062 -6.785156 4.78125 -7.421875 L 5.859375 -7.421875 C 5.554688 -6.640625 5.207031 -5.875 4.8125 -5.125 C 4.414062 -4.382812 3.976562 -3.601562 3.5 -2.78125 L 3.5 0 Z M 2.515625 0 "/>
-</symbol>
-<symbol overflow="visible" id="glyph1-2">
-<path style="stroke:none;" d="M 3 0.15625 C 2.5625 0.15625 2.1875 0.09375 1.875 -0.03125 C 1.570312 -0.164062 1.320312 -0.347656 1.125 -0.578125 C 0.9375 -0.804688 0.796875 -1.085938 0.703125 -1.421875 C 0.617188 -1.765625 0.578125 -2.144531 0.578125 -2.5625 L 0.578125 -7.421875 L 1.5625 -7.421875 L 1.5625 -2.65625 C 1.5625 -2.28125 1.59375 -1.96875 1.65625 -1.71875 C 1.726562 -1.46875 1.828125 -1.265625 1.953125 -1.109375 C 2.078125 -0.960938 2.222656 -0.859375 2.390625 -0.796875 C 2.566406 -0.734375 2.769531 -0.703125 3 -0.703125 C 3.226562 -0.703125 3.425781 -0.734375 3.59375 -0.796875 C 3.769531 -0.859375 3.921875 -0.960938 4.046875 -1.109375 C 4.171875 -1.265625 4.265625 -1.46875 4.328125 -1.71875 C 4.398438 -1.96875 4.4375 -2.28125 4.4375 -2.65625 L 4.4375 -7.421875 L 5.421875 -7.421875 L 5.421875 -2.5625 C 5.421875 -2.144531 5.375 -1.765625 5.28125 -1.421875 C 5.195312 -1.085938 5.054688 -0.804688 4.859375 -0.578125 C 4.671875 -0.347656 4.421875 -0.164062 4.109375 -0.03125 C 3.804688 0.09375 3.4375 0.15625 3 0.15625 Z M 3 0.15625 "/>
-</symbol>
-<symbol overflow="visible" id="glyph1-3">
-<path style="stroke:none;" d="M 1.21875 -7.421875 C 1.320312 -6.921875 1.445312 -6.375 1.59375 -5.78125 C 1.738281 -5.1875 1.890625 -4.585938 2.046875 -3.984375 C 2.210938 -3.390625 2.378906 -2.820312 2.546875 -2.28125 C 2.722656 -1.738281 2.882812 -1.265625 3.03125 -0.859375 C 3.15625 -1.265625 3.300781 -1.742188 3.46875 -2.296875 C 3.644531 -2.847656 3.816406 -3.421875 3.984375 -4.015625 C 4.148438 -4.609375 4.304688 -5.203125 4.453125 -5.796875 C 4.609375 -6.390625 4.734375 -6.929688 4.828125 -7.421875 L 5.859375 -7.421875 C 5.796875 -7.109375 5.691406 -6.679688 5.546875 -6.140625 C 5.398438 -5.597656 5.226562 -4.992188 5.03125 -4.328125 C 4.832031 -3.660156 4.609375 -2.953125 4.359375 -2.203125 C 4.117188 -1.453125 3.863281 -0.71875 3.59375 0 L 2.375 0 C 2.125 -0.71875 1.878906 -1.445312 1.640625 -2.1875 C 1.410156 -2.9375 1.195312 -3.644531 1 -4.3125 C 0.800781 -4.976562 0.628906 -5.582031 0.484375 -6.125 C 0.335938 -6.675781 0.226562 -7.109375 0.15625 -7.421875 Z M 1.21875 -7.421875 "/>
-</symbol>
-<symbol overflow="visible" id="glyph1-4">
-<path style="stroke:none;" d=""/>
-</symbol>
-<symbol overflow="visible" id="glyph1-5">
-<path style="stroke:none;" d="M 5.515625 -3.71875 C 5.515625 -3.03125 5.425781 -2.445312 5.25 -1.96875 C 5.082031 -1.488281 4.847656 -1.097656 4.546875 -0.796875 C 4.253906 -0.492188 3.898438 -0.273438 3.484375 -0.140625 C 3.078125 -0.00390625 2.628906 0.0625 2.140625 0.0625 C 1.648438 0.0625 1.148438 0 0.640625 -0.125 L 0.640625 -7.3125 C 1.148438 -7.4375 1.648438 -7.5 2.140625 -7.5 C 2.628906 -7.5 3.078125 -7.429688 3.484375 -7.296875 C 3.898438 -7.160156 4.253906 -6.941406 4.546875 -6.640625 C 4.847656 -6.335938 5.082031 -5.941406 5.25 -5.453125 C 5.425781 -4.972656 5.515625 -4.394531 5.515625 -3.71875 Z M 1.625 -0.828125 C 1.832031 -0.804688 2.039062 -0.796875 2.25 -0.796875 C 2.601562 -0.796875 2.921875 -0.847656 3.203125 -0.953125 C 3.484375 -1.054688 3.71875 -1.226562 3.90625 -1.46875 C 4.101562 -1.707031 4.253906 -2.007812 4.359375 -2.375 C 4.460938 -2.75 4.515625 -3.195312 4.515625 -3.71875 C 4.515625 -4.726562 4.316406 -5.46875 3.921875 -5.9375 C 3.535156 -6.40625 2.960938 -6.640625 2.203125 -6.640625 C 2.097656 -6.640625 1.992188 -6.640625 1.890625 -6.640625 C 1.796875 -6.640625 1.707031 -6.628906 1.625 -6.609375 Z M 1.625 -0.828125 "/>
-</symbol>
-<symbol overflow="visible" id="glyph1-6">
-<path style="stroke:none;" d="M 5.515625 -2.78125 C 5.515625 -2.34375 5.453125 -1.945312 5.328125 -1.59375 C 5.203125 -1.238281 5.023438 -0.929688 4.796875 -0.671875 C 4.578125 -0.410156 4.3125 -0.210938 4 -0.078125 C 3.695312 0.0546875 3.359375 0.125 2.984375 0.125 C 2.628906 0.125 2.296875 0.0546875 1.984375 -0.078125 C 1.679688 -0.210938 1.414062 -0.410156 1.1875 -0.671875 C 0.96875 -0.929688 0.796875 -1.238281 0.671875 -1.59375 C 0.546875 -1.945312 0.484375 -2.34375 0.484375 -2.78125 C 0.484375 -3.21875 0.546875 -3.617188 0.671875 -3.984375 C 0.796875 -4.347656 0.96875 -4.65625 1.1875 -4.90625 C 1.414062 -5.15625 1.679688 -5.347656 1.984375 -5.484375 C 2.296875 -5.628906 2.628906 -5.703125 2.984375 -5.703125 C 3.359375 -5.703125 3.695312 -5.628906 4 -5.484375 C 4.3125 -5.347656 4.578125 -5.15625 4.796875 -4.90625 C 5.023438 -4.65625 5.203125 -4.347656 5.328125 -3.984375 C 5.453125 -3.617188 5.515625 -3.21875 5.515625 -2.78125 Z M 4.5 -2.78125 C 4.5 -3.414062 4.363281 -3.914062 4.09375 -4.28125 C 3.820312 -4.644531 3.453125 -4.828125 2.984375 -4.828125 C 2.523438 -4.828125 2.160156 -4.644531 1.890625 -4.28125 C 1.628906 -3.914062 1.5 -3.414062 1.5 -2.78125 C 1.5 -2.15625 1.628906 -1.660156 1.890625 -1.296875 C 2.160156 -0.929688 2.523438 -0.75 2.984375 -0.75 C 3.453125 -0.75 3.820312 -0.929688 4.09375 -1.296875 C 4.363281 -1.660156 4.5 -2.15625 4.5 -2.78125 Z M 4.5 -2.78125 "/>
-</symbol>
-<symbol overflow="visible" id="glyph1-7">
-<path style="stroke:none;" d="M 4.109375 0 C 3.992188 -0.269531 3.890625 -0.515625 3.796875 -0.734375 C 3.710938 -0.960938 3.628906 -1.1875 3.546875 -1.40625 C 3.460938 -1.632812 3.378906 -1.867188 3.296875 -2.109375 C 3.210938 -2.359375 3.113281 -2.640625 3 -2.953125 C 2.882812 -2.640625 2.78125 -2.359375 2.6875 -2.109375 C 2.601562 -1.867188 2.519531 -1.632812 2.4375 -1.40625 C 2.351562 -1.1875 2.265625 -0.960938 2.171875 -0.734375 C 2.085938 -0.515625 1.984375 -0.269531 1.859375 0 L 1.109375 0 C 0.890625 -0.976562 0.707031 -1.953125 0.5625 -2.921875 C 0.414062 -3.890625 0.304688 -4.769531 0.234375 -5.5625 L 1.15625 -5.5625 C 1.1875 -5.25 1.210938 -4.941406 1.234375 -4.640625 C 1.265625 -4.347656 1.300781 -4.035156 1.34375 -3.703125 C 1.382812 -3.378906 1.429688 -3.023438 1.484375 -2.640625 C 1.535156 -2.253906 1.59375 -1.820312 1.65625 -1.34375 C 1.78125 -1.664062 1.882812 -1.945312 1.96875 -2.1875 C 2.0625 -2.425781 2.144531 -2.648438 2.21875 -2.859375 C 2.289062 -3.078125 2.359375 -3.296875 2.421875 -3.515625 C 2.492188 -3.742188 2.570312 -4 2.65625 -4.28125 L 3.390625 -4.28125 C 3.472656 -4 3.546875 -3.742188 3.609375 -3.515625 C 3.671875 -3.296875 3.738281 -3.078125 3.8125 -2.859375 C 3.882812 -2.648438 3.957031 -2.425781 4.03125 -2.1875 C 4.113281 -1.945312 4.21875 -1.671875 4.34375 -1.359375 C 4.414062 -1.796875 4.476562 -2.203125 4.53125 -2.578125 C 4.59375 -2.953125 4.640625 -3.304688 4.671875 -3.640625 C 4.710938 -3.972656 4.75 -4.296875 4.78125 -4.609375 C 4.820312 -4.921875 4.851562 -5.238281 4.875 -5.5625 L 5.765625 -5.5625 C 5.734375 -5.164062 5.6875 -4.738281 5.625 -4.28125 C 5.570312 -3.820312 5.503906 -3.351562 5.421875 -2.875 C 5.335938 -2.394531 5.25 -1.910156 5.15625 -1.421875 C 5.0625 -0.929688 4.960938 -0.457031 4.859375 0 Z M 4.109375 0 "/>
-</symbol>
-<symbol overflow="visible" id="glyph1-8">
-<path style="stroke:none;" d="M 0.859375 -5.40625 C 1.210938 -5.5 1.566406 -5.566406 1.921875 -5.609375 C 2.273438 -5.660156 2.609375 -5.6875 2.921875 -5.6875 C 3.671875 -5.6875 4.234375 -5.492188 4.609375 -5.109375 C 4.992188 -4.722656 5.1875 -4.109375 5.1875 -3.265625 L 5.1875 0 L 4.203125 0 L 4.203125 -3.078125 C 4.203125 -3.441406 4.171875 -3.734375 4.109375 -3.953125 C 4.046875 -4.179688 3.953125 -4.359375 3.828125 -4.484375 C 3.710938 -4.609375 3.570312 -4.691406 3.40625 -4.734375 C 3.25 -4.785156 3.070312 -4.8125 2.875 -4.8125 C 2.71875 -4.8125 2.546875 -4.800781 2.359375 -4.78125 C 2.179688 -4.757812 2.007812 -4.734375 1.84375 -4.703125 L 1.84375 0 L 0.859375 0 Z M 0.859375 -5.40625 "/>
-</symbol>
-<symbol overflow="visible" id="glyph1-9">
-<path style="stroke:none;" d="M 4.21875 -1.390625 C 4.21875 -1.585938 4.132812 -1.75 3.96875 -1.875 C 3.800781 -2.007812 3.59375 -2.125 3.34375 -2.21875 C 3.101562 -2.3125 2.835938 -2.40625 2.546875 -2.5 C 2.265625 -2.59375 2 -2.707031 1.75 -2.84375 C 1.507812 -2.976562 1.304688 -3.144531 1.140625 -3.34375 C 0.984375 -3.539062 0.90625 -3.800781 0.90625 -4.125 C 0.90625 -4.570312 1.082031 -4.945312 1.4375 -5.25 C 1.800781 -5.550781 2.375 -5.703125 3.15625 -5.703125 C 3.457031 -5.703125 3.769531 -5.675781 4.09375 -5.625 C 4.414062 -5.582031 4.695312 -5.523438 4.9375 -5.453125 L 4.75 -4.578125 C 4.6875 -4.609375 4.597656 -4.640625 4.484375 -4.671875 C 4.367188 -4.710938 4.238281 -4.742188 4.09375 -4.765625 C 3.957031 -4.796875 3.804688 -4.816406 3.640625 -4.828125 C 3.472656 -4.847656 3.316406 -4.859375 3.171875 -4.859375 C 2.304688 -4.859375 1.875 -4.625 1.875 -4.15625 C 1.875 -3.988281 1.953125 -3.84375 2.109375 -3.71875 C 2.273438 -3.601562 2.484375 -3.5 2.734375 -3.40625 C 2.984375 -3.3125 3.25 -3.210938 3.53125 -3.109375 C 3.820312 -3.015625 4.09375 -2.894531 4.34375 -2.75 C 4.59375 -2.601562 4.796875 -2.425781 4.953125 -2.21875 C 5.117188 -2.019531 5.203125 -1.765625 5.203125 -1.453125 C 5.203125 -0.953125 5.003906 -0.5625 4.609375 -0.28125 C 4.222656 -0.0078125 3.609375 0.125 2.765625 0.125 C 2.378906 0.125 2.023438 0.09375 1.703125 0.03125 C 1.378906 -0.03125 1.078125 -0.125 0.796875 -0.25 L 0.984375 -1.15625 C 1.265625 -1.019531 1.554688 -0.910156 1.859375 -0.828125 C 2.171875 -0.742188 2.503906 -0.703125 2.859375 -0.703125 C 3.765625 -0.703125 4.21875 -0.929688 4.21875 -1.390625 Z M 4.21875 -1.390625 "/>
-</symbol>
-<symbol overflow="visible" id="glyph1-10">
-<path style="stroke:none;" d="M 0.59375 -2.765625 C 0.59375 -3.273438 0.671875 -3.710938 0.828125 -4.078125 C 0.984375 -4.441406 1.203125 -4.742188 1.484375 -4.984375 C 1.765625 -5.234375 2.09375 -5.414062 2.46875 -5.53125 C 2.84375 -5.644531 3.238281 -5.703125 3.65625 -5.703125 C 3.925781 -5.703125 4.195312 -5.679688 4.46875 -5.640625 C 4.738281 -5.609375 5.023438 -5.546875 5.328125 -5.453125 L 5.09375 -4.59375 C 4.832031 -4.6875 4.59375 -4.75 4.375 -4.78125 C 4.15625 -4.8125 3.929688 -4.828125 3.703125 -4.828125 C 3.421875 -4.828125 3.148438 -4.785156 2.890625 -4.703125 C 2.640625 -4.628906 2.414062 -4.507812 2.21875 -4.34375 C 2.03125 -4.1875 1.878906 -3.976562 1.765625 -3.71875 C 1.660156 -3.457031 1.609375 -3.140625 1.609375 -2.765625 C 1.609375 -2.421875 1.660156 -2.117188 1.765625 -1.859375 C 1.867188 -1.609375 2.015625 -1.398438 2.203125 -1.234375 C 2.390625 -1.078125 2.613281 -0.957031 2.875 -0.875 C 3.144531 -0.789062 3.4375 -0.75 3.75 -0.75 C 4.007812 -0.75 4.253906 -0.765625 4.484375 -0.796875 C 4.722656 -0.828125 4.984375 -0.890625 5.265625 -0.984375 L 5.40625 -0.15625 C 5.125 -0.0507812 4.835938 0.0195312 4.546875 0.0625 C 4.265625 0.101562 3.957031 0.125 3.625 0.125 C 3.175781 0.125 2.765625 0.0664062 2.390625 -0.046875 C 2.023438 -0.171875 1.707031 -0.351562 1.4375 -0.59375 C 1.164062 -0.832031 0.957031 -1.132812 0.8125 -1.5 C 0.664062 -1.863281 0.59375 -2.285156 0.59375 -2.765625 Z M 0.59375 -2.765625 "/>
-</symbol>
-<symbol overflow="visible" id="glyph1-11">
-<path style="stroke:none;" d="M 3.0625 -0.703125 C 3.3125 -0.703125 3.53125 -0.707031 3.71875 -0.71875 C 3.914062 -0.738281 4.082031 -0.765625 4.21875 -0.796875 L 4.21875 -2.453125 C 4.082031 -2.492188 3.925781 -2.523438 3.75 -2.546875 C 3.570312 -2.566406 3.382812 -2.578125 3.1875 -2.578125 C 3 -2.578125 2.816406 -2.5625 2.640625 -2.53125 C 2.460938 -2.507812 2.304688 -2.460938 2.171875 -2.390625 C 2.035156 -2.316406 1.921875 -2.222656 1.828125 -2.109375 C 1.742188 -1.992188 1.703125 -1.847656 1.703125 -1.671875 C 1.703125 -1.304688 1.820312 -1.050781 2.0625 -0.90625 C 2.3125 -0.769531 2.644531 -0.703125 3.0625 -0.703125 Z M 2.96875 -5.703125 C 3.382812 -5.703125 3.734375 -5.648438 4.015625 -5.546875 C 4.296875 -5.441406 4.523438 -5.296875 4.703125 -5.109375 C 4.878906 -4.929688 5.003906 -4.707031 5.078125 -4.4375 C 5.148438 -4.175781 5.1875 -3.890625 5.1875 -3.578125 L 5.1875 -0.09375 C 4.957031 -0.0507812 4.648438 -0.00390625 4.265625 0.046875 C 3.890625 0.0976562 3.5 0.125 3.09375 0.125 C 2.789062 0.125 2.492188 0.0976562 2.203125 0.046875 C 1.921875 -0.00390625 1.664062 -0.09375 1.4375 -0.21875 C 1.21875 -0.351562 1.039062 -0.535156 0.90625 -0.765625 C 0.769531 -0.992188 0.703125 -1.289062 0.703125 -1.65625 C 0.703125 -1.976562 0.769531 -2.25 0.90625 -2.46875 C 1.039062 -2.6875 1.21875 -2.863281 1.4375 -3 C 1.664062 -3.132812 1.921875 -3.234375 2.203125 -3.296875 C 2.484375 -3.359375 2.769531 -3.390625 3.0625 -3.390625 C 3.445312 -3.390625 3.832031 -3.34375 4.21875 -3.25 L 4.21875 -3.53125 C 4.21875 -3.695312 4.195312 -3.859375 4.15625 -4.015625 C 4.125 -4.171875 4.054688 -4.3125 3.953125 -4.4375 C 3.847656 -4.5625 3.707031 -4.660156 3.53125 -4.734375 C 3.363281 -4.816406 3.144531 -4.859375 2.875 -4.859375 C 2.53125 -4.859375 2.226562 -4.832031 1.96875 -4.78125 C 1.71875 -4.738281 1.523438 -4.691406 1.390625 -4.640625 L 1.265625 -5.453125 C 1.398438 -5.523438 1.625 -5.582031 1.9375 -5.625 C 2.257812 -5.675781 2.601562 -5.703125 2.96875 -5.703125 Z M 2.96875 -5.703125 "/>
-</symbol>
-<symbol overflow="visible" id="glyph1-12">
-<path style="stroke:none;" d="M 4.0625 0.125 C 3.707031 0.125 3.410156 0.078125 3.171875 -0.015625 C 2.941406 -0.109375 2.757812 -0.25 2.625 -0.4375 C 2.488281 -0.632812 2.390625 -0.875 2.328125 -1.15625 C 2.273438 -1.4375 2.25 -1.765625 2.25 -2.140625 L 2.25 -7.421875 L 0.640625 -7.421875 L 0.640625 -8.25 L 3.234375 -8.25 L 3.234375 -2.140625 C 3.234375 -1.867188 3.25 -1.644531 3.28125 -1.46875 C 3.320312 -1.289062 3.378906 -1.144531 3.453125 -1.03125 C 3.535156 -0.925781 3.628906 -0.851562 3.734375 -0.8125 C 3.847656 -0.769531 3.984375 -0.75 4.140625 -0.75 C 4.367188 -0.75 4.582031 -0.773438 4.78125 -0.828125 C 4.988281 -0.890625 5.144531 -0.953125 5.25 -1.015625 L 5.40625 -0.1875 C 5.351562 -0.15625 5.28125 -0.117188 5.1875 -0.078125 C 5.101562 -0.046875 5 -0.015625 4.875 0.015625 C 4.757812 0.046875 4.628906 0.0703125 4.484375 0.09375 C 4.347656 0.113281 4.207031 0.125 4.0625 0.125 Z M 4.0625 0.125 "/>
-</symbol>
-<symbol overflow="visible" id="glyph1-13">
-<path style="stroke:none;" d="M 2.515625 -6.4375 C 2.304688 -6.4375 2.125 -6.503906 1.96875 -6.640625 C 1.8125 -6.785156 1.734375 -6.984375 1.734375 -7.234375 C 1.734375 -7.484375 1.8125 -7.679688 1.96875 -7.828125 C 2.125 -7.972656 2.304688 -8.046875 2.515625 -8.046875 C 2.722656 -8.046875 2.898438 -7.972656 3.046875 -7.828125 C 3.203125 -7.679688 3.28125 -7.484375 3.28125 -7.234375 C 3.28125 -6.984375 3.203125 -6.785156 3.046875 -6.640625 C 2.898438 -6.503906 2.722656 -6.4375 2.515625 -6.4375 Z M 2.25 -4.734375 L 0.640625 -4.734375 L 0.640625 -5.5625 L 3.234375 -5.5625 L 3.234375 -2.140625 C 3.234375 -1.585938 3.3125 -1.21875 3.46875 -1.03125 C 3.625 -0.84375 3.851562 -0.75 4.15625 -0.75 C 4.382812 -0.75 4.597656 -0.773438 4.796875 -0.828125 C 4.992188 -0.890625 5.144531 -0.953125 5.25 -1.015625 L 5.40625 -0.1875 C 5.351562 -0.15625 5.28125 -0.117188 5.1875 -0.078125 C 5.101562 -0.046875 5.003906 -0.015625 4.890625 0.015625 C 4.773438 0.046875 4.644531 0.0703125 4.5 0.09375 C 4.363281 0.113281 4.21875 0.125 4.0625 0.125 C 3.71875 0.125 3.425781 0.078125 3.1875 -0.015625 C 2.957031 -0.109375 2.769531 -0.25 2.625 -0.4375 C 2.488281 -0.632812 2.390625 -0.875 2.328125 -1.15625 C 2.273438 -1.4375 2.25 -1.765625 2.25 -2.140625 Z M 2.25 -4.734375 "/>
-</symbol>
-<symbol overflow="visible" id="glyph1-14">
-<path style="stroke:none;" d="M 4.15625 -0.515625 C 4.039062 -0.453125 3.863281 -0.382812 3.625 -0.3125 C 3.394531 -0.238281 3.128906 -0.203125 2.828125 -0.203125 C 2.503906 -0.203125 2.195312 -0.253906 1.90625 -0.359375 C 1.625 -0.472656 1.378906 -0.640625 1.171875 -0.859375 C 0.960938 -1.078125 0.796875 -1.351562 0.671875 -1.6875 C 0.546875 -2.03125 0.484375 -2.4375 0.484375 -2.90625 C 0.484375 -3.3125 0.539062 -3.679688 0.65625 -4.015625 C 0.769531 -4.359375 0.9375 -4.65625 1.15625 -4.90625 C 1.375 -5.15625 1.644531 -5.347656 1.96875 -5.484375 C 2.289062 -5.628906 2.65625 -5.703125 3.0625 -5.703125 C 3.539062 -5.703125 3.945312 -5.664062 4.28125 -5.59375 C 4.625 -5.53125 4.910156 -5.46875 5.140625 -5.40625 L 5.140625 -0.4375 C 5.140625 0.425781 4.921875 1.050781 4.484375 1.4375 C 4.054688 1.820312 3.398438 2.015625 2.515625 2.015625 C 2.160156 2.015625 1.835938 1.984375 1.546875 1.921875 C 1.253906 1.867188 0.992188 1.804688 0.765625 1.734375 L 0.953125 0.859375 C 1.160156 0.941406 1.394531 1.007812 1.65625 1.0625 C 1.925781 1.125 2.222656 1.15625 2.546875 1.15625 C 3.117188 1.15625 3.53125 1.035156 3.78125 0.796875 C 4.03125 0.566406 4.15625 0.191406 4.15625 -0.328125 Z M 4.15625 -4.6875 C 4.0625 -4.71875 3.925781 -4.75 3.75 -4.78125 C 3.582031 -4.8125 3.359375 -4.828125 3.078125 -4.828125 C 2.554688 -4.828125 2.160156 -4.648438 1.890625 -4.296875 C 1.628906 -3.941406 1.5 -3.472656 1.5 -2.890625 C 1.5 -2.566406 1.535156 -2.289062 1.609375 -2.0625 C 1.691406 -1.84375 1.796875 -1.65625 1.921875 -1.5 C 2.054688 -1.351562 2.207031 -1.242188 2.375 -1.171875 C 2.539062 -1.109375 2.722656 -1.078125 2.921875 -1.078125 C 3.160156 -1.078125 3.390625 -1.113281 3.609375 -1.1875 C 3.835938 -1.257812 4.019531 -1.34375 4.15625 -1.4375 Z M 4.15625 -4.6875 "/>
-</symbol>
-<symbol overflow="visible" id="glyph1-15">
-<path style="stroke:none;" d="M 2.8125 -0.703125 C 3.3125 -0.703125 3.691406 -0.796875 3.953125 -0.984375 C 4.222656 -1.171875 4.359375 -1.457031 4.359375 -1.84375 C 4.359375 -2.082031 4.304688 -2.28125 4.203125 -2.4375 C 4.109375 -2.601562 3.984375 -2.75 3.828125 -2.875 C 3.671875 -3 3.488281 -3.109375 3.28125 -3.203125 C 3.082031 -3.296875 2.878906 -3.378906 2.671875 -3.453125 C 2.429688 -3.546875 2.203125 -3.648438 1.984375 -3.765625 C 1.765625 -3.890625 1.566406 -4.03125 1.390625 -4.1875 C 1.222656 -4.351562 1.085938 -4.546875 0.984375 -4.765625 C 0.890625 -4.984375 0.84375 -5.238281 0.84375 -5.53125 C 0.84375 -6.175781 1.046875 -6.679688 1.453125 -7.046875 C 1.859375 -7.410156 2.425781 -7.59375 3.15625 -7.59375 C 3.351562 -7.59375 3.550781 -7.578125 3.75 -7.546875 C 3.945312 -7.523438 4.128906 -7.492188 4.296875 -7.453125 C 4.460938 -7.410156 4.609375 -7.359375 4.734375 -7.296875 C 4.867188 -7.242188 4.976562 -7.191406 5.0625 -7.140625 L 4.75 -6.3125 C 4.59375 -6.40625 4.375 -6.5 4.09375 -6.59375 C 3.8125 -6.695312 3.5 -6.75 3.15625 -6.75 C 2.789062 -6.75 2.476562 -6.65625 2.21875 -6.46875 C 1.957031 -6.289062 1.828125 -6.019531 1.828125 -5.65625 C 1.828125 -5.457031 1.863281 -5.285156 1.9375 -5.140625 C 2.007812 -4.992188 2.113281 -4.863281 2.25 -4.75 C 2.382812 -4.644531 2.535156 -4.546875 2.703125 -4.453125 C 2.878906 -4.367188 3.070312 -4.285156 3.28125 -4.203125 C 3.59375 -4.078125 3.875 -3.945312 4.125 -3.8125 C 4.375 -3.6875 4.585938 -3.535156 4.765625 -3.359375 C 4.953125 -3.179688 5.09375 -2.972656 5.1875 -2.734375 C 5.289062 -2.492188 5.34375 -2.203125 5.34375 -1.859375 C 5.34375 -1.210938 5.125 -0.710938 4.6875 -0.359375 C 4.25 -0.015625 3.625 0.15625 2.8125 0.15625 C 2.539062 0.15625 2.289062 0.132812 2.0625 0.09375 C 1.832031 0.0625 1.625 0.0195312 1.4375 -0.03125 C 1.257812 -0.09375 1.101562 -0.148438 0.96875 -0.203125 C 0.832031 -0.253906 0.726562 -0.304688 0.65625 -0.359375 L 0.953125 -1.171875 C 1.117188 -1.085938 1.359375 -0.988281 1.671875 -0.875 C 1.984375 -0.757812 2.363281 -0.703125 2.8125 -0.703125 Z M 2.8125 -0.703125 "/>
-</symbol>
-<symbol overflow="visible" id="glyph1-16">
-<path style="stroke:none;" d="M 3.109375 -5.703125 C 3.859375 -5.703125 4.4375 -5.46875 4.84375 -5 C 5.25 -4.53125 5.453125 -3.820312 5.453125 -2.875 L 5.453125 -2.515625 L 1.46875 -2.515625 C 1.507812 -1.941406 1.703125 -1.503906 2.046875 -1.203125 C 2.390625 -0.898438 2.867188 -0.75 3.484375 -0.75 C 3.835938 -0.75 4.132812 -0.773438 4.375 -0.828125 C 4.625 -0.890625 4.8125 -0.953125 4.9375 -1.015625 L 5.078125 -0.1875 C 4.953125 -0.113281 4.734375 -0.046875 4.421875 0.015625 C 4.109375 0.0859375 3.757812 0.125 3.375 0.125 C 2.894531 0.125 2.472656 0.0507812 2.109375 -0.09375 C 1.742188 -0.238281 1.441406 -0.4375 1.203125 -0.6875 C 0.960938 -0.945312 0.78125 -1.253906 0.65625 -1.609375 C 0.539062 -1.960938 0.484375 -2.347656 0.484375 -2.765625 C 0.484375 -3.265625 0.554688 -3.695312 0.703125 -4.0625 C 0.859375 -4.4375 1.0625 -4.742188 1.3125 -4.984375 C 1.5625 -5.222656 1.835938 -5.398438 2.140625 -5.515625 C 2.453125 -5.640625 2.773438 -5.703125 3.109375 -5.703125 Z M 4.453125 -3.328125 C 4.453125 -3.796875 4.328125 -4.164062 4.078125 -4.4375 C 3.828125 -4.71875 3.5 -4.859375 3.09375 -4.859375 C 2.863281 -4.859375 2.65625 -4.8125 2.46875 -4.71875 C 2.28125 -4.632812 2.117188 -4.519531 1.984375 -4.375 C 1.847656 -4.226562 1.738281 -4.0625 1.65625 -3.875 C 1.570312 -3.695312 1.519531 -3.515625 1.5 -3.328125 Z M 4.453125 -3.328125 "/>
-</symbol>
-<symbol overflow="visible" id="glyph1-17">
-<path style="stroke:none;" d="M 4.15625 -4.390625 C 4.039062 -4.492188 3.875 -4.59375 3.65625 -4.6875 C 3.445312 -4.78125 3.222656 -4.828125 2.984375 -4.828125 C 2.722656 -4.828125 2.5 -4.773438 2.3125 -4.671875 C 2.125 -4.566406 1.96875 -4.421875 1.84375 -4.234375 C 1.726562 -4.054688 1.640625 -3.84375 1.578125 -3.59375 C 1.523438 -3.34375 1.5 -3.070312 1.5 -2.78125 C 1.5 -2.132812 1.648438 -1.632812 1.953125 -1.28125 C 2.253906 -0.925781 2.648438 -0.75 3.140625 -0.75 C 3.390625 -0.75 3.597656 -0.757812 3.765625 -0.78125 C 3.941406 -0.8125 4.070312 -0.835938 4.15625 -0.859375 Z M 4.15625 -8.140625 L 5.140625 -8.3125 L 5.140625 -0.15625 C 4.929688 -0.09375 4.65625 -0.03125 4.3125 0.03125 C 3.976562 0.09375 3.585938 0.125 3.140625 0.125 C 2.742188 0.125 2.378906 0.0546875 2.046875 -0.078125 C 1.722656 -0.210938 1.441406 -0.40625 1.203125 -0.65625 C 0.972656 -0.90625 0.796875 -1.207031 0.671875 -1.5625 C 0.546875 -1.925781 0.484375 -2.332031 0.484375 -2.78125 C 0.484375 -3.21875 0.535156 -3.613281 0.640625 -3.96875 C 0.742188 -4.320312 0.898438 -4.625 1.109375 -4.875 C 1.316406 -5.132812 1.566406 -5.335938 1.859375 -5.484375 C 2.148438 -5.628906 2.488281 -5.703125 2.875 -5.703125 C 3.164062 -5.703125 3.421875 -5.664062 3.640625 -5.59375 C 3.867188 -5.519531 4.039062 -5.441406 4.15625 -5.359375 Z M 4.15625 -8.140625 "/>
-</symbol>
-<symbol overflow="visible" id="glyph1-18">
-<path style="stroke:none;" d="M 1.28125 0 L 1.28125 -5.265625 C 2.101562 -5.546875 2.925781 -5.6875 3.75 -5.6875 C 4.007812 -5.6875 4.253906 -5.675781 4.484375 -5.65625 C 4.722656 -5.632812 4.976562 -5.59375 5.25 -5.53125 L 5.078125 -4.65625 C 4.816406 -4.726562 4.585938 -4.773438 4.390625 -4.796875 C 4.203125 -4.816406 3.988281 -4.828125 3.75 -4.828125 C 3.269531 -4.828125 2.773438 -4.757812 2.265625 -4.625 L 2.265625 0 Z M 1.28125 0 "/>
-</symbol>
-<symbol overflow="visible" id="glyph1-19">
-<path style="stroke:none;" d="M 0.609375 1.046875 C 0.679688 1.085938 0.78125 1.117188 0.90625 1.140625 C 1.039062 1.160156 1.164062 1.171875 1.28125 1.171875 C 1.675781 1.171875 1.984375 1.082031 2.203125 0.90625 C 2.421875 0.738281 2.625 0.460938 2.8125 0.078125 C 2.363281 -0.773438 1.941406 -1.6875 1.546875 -2.65625 C 1.148438 -3.625 0.828125 -4.59375 0.578125 -5.5625 L 1.65625 -5.5625 C 1.738281 -5.25 1.832031 -4.90625 1.9375 -4.53125 C 2.039062 -4.15625 2.160156 -3.769531 2.296875 -3.375 C 2.441406 -2.988281 2.585938 -2.597656 2.734375 -2.203125 C 2.890625 -1.804688 3.054688 -1.425781 3.234375 -1.0625 C 3.367188 -1.4375 3.488281 -1.800781 3.59375 -2.15625 C 3.707031 -2.519531 3.8125 -2.882812 3.90625 -3.25 C 4.007812 -3.613281 4.109375 -3.984375 4.203125 -4.359375 C 4.296875 -4.742188 4.394531 -5.144531 4.5 -5.5625 L 5.53125 -5.5625 C 5.269531 -4.53125 4.984375 -3.523438 4.671875 -2.546875 C 4.359375 -1.566406 4.019531 -0.660156 3.65625 0.171875 C 3.519531 0.484375 3.375 0.753906 3.21875 0.984375 C 3.0625 1.222656 2.890625 1.414062 2.703125 1.5625 C 2.523438 1.71875 2.316406 1.832031 2.078125 1.90625 C 1.847656 1.976562 1.585938 2.015625 1.296875 2.015625 C 1.140625 2.015625 0.972656 1.992188 0.796875 1.953125 C 0.617188 1.910156 0.5 1.875 0.4375 1.84375 Z M 0.609375 1.046875 "/>
-</symbol>
-<symbol overflow="visible" id="glyph1-20">
-<path style="stroke:none;" d="M 0.34375 -3.71875 C 0.34375 -4.382812 0.40625 -4.960938 0.53125 -5.453125 C 0.664062 -5.941406 0.847656 -6.34375 1.078125 -6.65625 C 1.304688 -6.96875 1.582031 -7.203125 1.90625 -7.359375 C 2.238281 -7.515625 2.601562 -7.59375 3 -7.59375 C 3.394531 -7.59375 3.753906 -7.515625 4.078125 -7.359375 C 4.410156 -7.203125 4.691406 -6.96875 4.921875 -6.65625 C 5.148438 -6.34375 5.328125 -5.941406 5.453125 -5.453125 C 5.585938 -4.960938 5.65625 -4.382812 5.65625 -3.71875 C 5.65625 -3.050781 5.585938 -2.472656 5.453125 -1.984375 C 5.328125 -1.503906 5.148438 -1.101562 4.921875 -0.78125 C 4.691406 -0.457031 4.410156 -0.21875 4.078125 -0.0625 C 3.753906 0.0820312 3.394531 0.15625 3 0.15625 C 2.601562 0.15625 2.238281 0.0820312 1.90625 -0.0625 C 1.582031 -0.21875 1.304688 -0.457031 1.078125 -0.78125 C 0.847656 -1.101562 0.664062 -1.503906 0.53125 -1.984375 C 0.40625 -2.472656 0.34375 -3.050781 0.34375 -3.71875 Z M 1.359375 -3.71875 C 1.359375 -2.738281 1.488281 -1.988281 1.75 -1.46875 C 2.007812 -0.957031 2.414062 -0.703125 2.96875 -0.703125 C 3.53125 -0.703125 3.953125 -0.957031 4.234375 -1.46875 C 4.515625 -1.988281 4.65625 -2.738281 4.65625 -3.71875 C 4.65625 -4.695312 4.515625 -5.445312 4.234375 -5.96875 C 3.953125 -6.488281 3.53125 -6.75 2.96875 -6.75 C 2.414062 -6.75 2.007812 -6.488281 1.75 -5.96875 C 1.488281 -5.445312 1.359375 -4.695312 1.359375 -3.71875 Z M 1.359375 -3.71875 "/>
-</symbol>
-<symbol overflow="visible" id="glyph1-21">
-<path style="stroke:none;" d="M 5.140625 -0.15625 C 4.929688 -0.101562 4.644531 -0.046875 4.28125 0.015625 C 3.925781 0.0859375 3.507812 0.125 3.03125 0.125 C 2.613281 0.125 2.265625 0.0625 1.984375 -0.0625 C 1.703125 -0.1875 1.472656 -0.363281 1.296875 -0.59375 C 1.117188 -0.820312 0.992188 -1.09375 0.921875 -1.40625 C 0.847656 -1.71875 0.8125 -2.0625 0.8125 -2.4375 L 0.8125 -5.5625 L 1.796875 -5.5625 L 1.796875 -2.65625 C 1.796875 -1.96875 1.894531 -1.476562 2.09375 -1.1875 C 2.300781 -0.894531 2.644531 -0.75 3.125 -0.75 C 3.226562 -0.75 3.332031 -0.753906 3.4375 -0.765625 C 3.550781 -0.773438 3.65625 -0.785156 3.75 -0.796875 C 3.851562 -0.804688 3.9375 -0.816406 4 -0.828125 C 4.070312 -0.847656 4.125 -0.859375 4.15625 -0.859375 L 4.15625 -5.5625 L 5.140625 -5.5625 Z M 5.140625 -0.15625 "/>
-</symbol>
-<symbol overflow="visible" id="glyph1-22">
-<path style="stroke:none;" d="M 2.921875 -5.5625 L 5.265625 -5.5625 L 5.265625 -4.734375 L 2.921875 -4.734375 L 2.921875 -2.140625 C 2.921875 -1.867188 2.9375 -1.644531 2.96875 -1.46875 C 3.007812 -1.289062 3.078125 -1.144531 3.171875 -1.03125 C 3.265625 -0.925781 3.382812 -0.851562 3.53125 -0.8125 C 3.675781 -0.769531 3.851562 -0.75 4.0625 -0.75 C 4.34375 -0.75 4.570312 -0.773438 4.75 -0.828125 C 4.925781 -0.878906 5.09375 -0.941406 5.25 -1.015625 L 5.40625 -0.1875 C 5.289062 -0.132812 5.109375 -0.0703125 4.859375 0 C 4.617188 0.0820312 4.316406 0.125 3.953125 0.125 C 3.546875 0.125 3.207031 0.078125 2.9375 -0.015625 C 2.675781 -0.109375 2.46875 -0.25 2.3125 -0.4375 C 2.164062 -0.632812 2.066406 -0.875 2.015625 -1.15625 C 1.960938 -1.4375 1.9375 -1.765625 1.9375 -2.140625 L 1.9375 -4.734375 L 0.75 -4.734375 L 0.75 -5.5625 L 1.9375 -5.5625 L 1.9375 -7.125 L 2.921875 -7.296875 Z M 2.921875 -5.5625 "/>
-</symbol>
-<symbol overflow="visible" id="glyph1-23">
-<path style="stroke:none;" d="M 4.5 -2.765625 C 4.5 -3.421875 4.347656 -3.925781 4.046875 -4.28125 C 3.742188 -4.632812 3.347656 -4.8125 2.859375 -4.8125 C 2.585938 -4.8125 2.375 -4.796875 2.21875 -4.765625 C 2.0625 -4.742188 1.9375 -4.71875 1.84375 -4.6875 L 1.84375 -1.171875 C 1.957031 -1.066406 2.117188 -0.96875 2.328125 -0.875 C 2.546875 -0.789062 2.773438 -0.75 3.015625 -0.75 C 3.273438 -0.75 3.5 -0.800781 3.6875 -0.90625 C 3.875 -1.007812 4.023438 -1.148438 4.140625 -1.328125 C 4.265625 -1.515625 4.351562 -1.726562 4.40625 -1.96875 C 4.46875 -2.21875 4.5 -2.484375 4.5 -2.765625 Z M 5.515625 -2.765625 C 5.515625 -2.347656 5.460938 -1.957031 5.359375 -1.59375 C 5.253906 -1.238281 5.097656 -0.929688 4.890625 -0.671875 C 4.679688 -0.421875 4.429688 -0.222656 4.140625 -0.078125 C 3.847656 0.0546875 3.507812 0.125 3.125 0.125 C 2.832031 0.125 2.570312 0.0859375 2.34375 0.015625 C 2.125 -0.046875 1.957031 -0.125 1.84375 -0.21875 L 1.84375 1.984375 L 0.859375 1.984375 L 0.859375 -5.40625 C 1.066406 -5.46875 1.34375 -5.53125 1.6875 -5.59375 C 2.03125 -5.65625 2.421875 -5.6875 2.859375 -5.6875 C 3.253906 -5.6875 3.613281 -5.617188 3.9375 -5.484375 C 4.269531 -5.347656 4.550781 -5.15625 4.78125 -4.90625 C 5.019531 -4.65625 5.203125 -4.347656 5.328125 -3.984375 C 5.453125 -3.617188 5.515625 -3.210938 5.515625 -2.765625 Z M 5.515625 -2.765625 "/>
-</symbol>
-<symbol overflow="visible" id="glyph1-24">
-<path style="stroke:none;" d="M 3.015625 -3.734375 L 4.15625 -7.421875 L 5.09375 -7.421875 C 5.25 -6.253906 5.359375 -5.054688 5.421875 -3.828125 C 5.492188 -2.609375 5.554688 -1.332031 5.609375 0 L 4.65625 0 C 4.644531 -0.425781 4.632812 -0.890625 4.625 -1.390625 C 4.625 -1.898438 4.613281 -2.421875 4.59375 -2.953125 C 4.582031 -3.492188 4.570312 -4.039062 4.5625 -4.59375 C 4.550781 -5.144531 4.539062 -5.679688 4.53125 -6.203125 L 3.4375 -2.8125 L 2.578125 -2.8125 L 1.46875 -6.203125 C 1.46875 -5.679688 1.457031 -5.144531 1.4375 -4.59375 C 1.425781 -4.050781 1.414062 -3.507812 1.40625 -2.96875 C 1.394531 -2.425781 1.382812 -1.898438 1.375 -1.390625 C 1.363281 -0.890625 1.351562 -0.425781 1.34375 0 L 0.390625 0 C 0.410156 -0.601562 0.4375 -1.222656 0.46875 -1.859375 C 0.5 -2.503906 0.535156 -3.144531 0.578125 -3.78125 C 0.617188 -4.414062 0.671875 -5.039062 0.734375 -5.65625 C 0.796875 -6.269531 0.863281 -6.859375 0.9375 -7.421875 L 1.84375 -7.421875 Z M 3.015625 -3.734375 "/>
-</symbol>
-<symbol overflow="visible" id="glyph2-0">
-<path style="stroke:none;" d="M 0.640625 2.296875 L 0.640625 -9.171875 L 7.140625 -9.171875 L 7.140625 2.296875 Z M 1.375 1.578125 L 6.421875 1.578125 L 6.421875 -8.4375 L 1.375 -8.4375 Z M 1.375 1.578125 "/>
-</symbol>
-<symbol overflow="visible" id="glyph2-1">
-<path style="stroke:none;" d="M 6.34375 -6.84375 L 6.34375 -5.75 C 6.007812 -5.925781 5.675781 -6.0625 5.34375 -6.15625 C 5.007812 -6.25 4.675781 -6.296875 4.34375 -6.296875 C 3.582031 -6.296875 2.992188 -6.050781 2.578125 -5.5625 C 2.160156 -5.082031 1.953125 -4.410156 1.953125 -3.546875 C 1.953125 -2.679688 2.160156 -2.007812 2.578125 -1.53125 C 2.992188 -1.050781 3.582031 -0.8125 4.34375 -0.8125 C 4.675781 -0.8125 5.007812 -0.851562 5.34375 -0.9375 C 5.675781 -1.03125 6.007812 -1.171875 6.34375 -1.359375 L 6.34375 -0.265625 C 6.019531 -0.117188 5.679688 -0.0078125 5.328125 0.0625 C 4.984375 0.144531 4.613281 0.1875 4.21875 0.1875 C 3.144531 0.1875 2.289062 -0.144531 1.65625 -0.8125 C 1.03125 -1.488281 0.71875 -2.398438 0.71875 -3.546875 C 0.71875 -4.703125 1.035156 -5.613281 1.671875 -6.28125 C 2.304688 -6.945312 3.179688 -7.28125 4.296875 -7.28125 C 4.648438 -7.28125 5 -7.242188 5.34375 -7.171875 C 5.6875 -7.097656 6.019531 -6.988281 6.34375 -6.84375 Z M 6.34375 -6.84375 "/>
-</symbol>
-<symbol overflow="visible" id="glyph2-2">
-<path style="stroke:none;" d="M 5.34375 -6.015625 C 5.207031 -6.085938 5.0625 -6.140625 4.90625 -6.171875 C 4.757812 -6.210938 4.59375 -6.234375 4.40625 -6.234375 C 3.75 -6.234375 3.242188 -6.019531 2.890625 -5.59375 C 2.535156 -5.164062 2.359375 -4.550781 2.359375 -3.75 L 2.359375 0 L 1.1875 0 L 1.1875 -7.109375 L 2.359375 -7.109375 L 2.359375 -6 C 2.597656 -6.4375 2.914062 -6.757812 3.3125 -6.96875 C 3.707031 -7.175781 4.1875 -7.28125 4.75 -7.28125 C 4.832031 -7.28125 4.921875 -7.273438 5.015625 -7.265625 C 5.109375 -7.253906 5.21875 -7.238281 5.34375 -7.21875 Z M 5.34375 -6.015625 "/>
-</symbol>
-<symbol overflow="visible" id="glyph2-3">
-<path style="stroke:none;" d="M 3.984375 -6.296875 C 3.359375 -6.296875 2.863281 -6.050781 2.5 -5.5625 C 2.132812 -5.070312 1.953125 -4.398438 1.953125 -3.546875 C 1.953125 -2.691406 2.128906 -2.019531 2.484375 -1.53125 C 2.847656 -1.050781 3.347656 -0.8125 3.984375 -0.8125 C 4.597656 -0.8125 5.085938 -1.054688 5.453125 -1.546875 C 5.816406 -2.035156 6 -2.703125 6 -3.546875 C 6 -4.390625 5.816406 -5.054688 5.453125 -5.546875 C 5.085938 -6.046875 4.597656 -6.296875 3.984375 -6.296875 Z M 3.984375 -7.28125 C 4.992188 -7.28125 5.789062 -6.945312 6.375 -6.28125 C 6.957031 -5.625 7.25 -4.710938 7.25 -3.546875 C 7.25 -2.378906 6.957031 -1.460938 6.375 -0.796875 C 5.789062 -0.140625 4.992188 0.1875 3.984375 0.1875 C 2.960938 0.1875 2.160156 -0.140625 1.578125 -0.796875 C 1.003906 -1.460938 0.71875 -2.378906 0.71875 -3.546875 C 0.71875 -4.710938 1.003906 -5.625 1.578125 -6.28125 C 2.160156 -6.945312 2.960938 -7.28125 3.984375 -7.28125 Z M 3.984375 -7.28125 "/>
-</symbol>
-<symbol overflow="visible" id="glyph2-4">
-<path style="stroke:none;" d="M 2.359375 -1.0625 L 2.359375 2.703125 L 1.1875 2.703125 L 1.1875 -7.109375 L 2.359375 -7.109375 L 2.359375 -6.03125 C 2.597656 -6.457031 2.90625 -6.769531 3.28125 -6.96875 C 3.65625 -7.175781 4.101562 -7.28125 4.625 -7.28125 C 5.488281 -7.28125 6.191406 -6.9375 6.734375 -6.25 C 7.273438 -5.5625 7.546875 -4.660156 7.546875 -3.546875 C 7.546875 -2.429688 7.273438 -1.53125 6.734375 -0.84375 C 6.191406 -0.15625 5.488281 0.1875 4.625 0.1875 C 4.101562 0.1875 3.65625 0.0820312 3.28125 -0.125 C 2.90625 -0.332031 2.597656 -0.644531 2.359375 -1.0625 Z M 6.328125 -3.546875 C 6.328125 -4.410156 6.148438 -5.082031 5.796875 -5.5625 C 5.441406 -6.050781 4.957031 -6.296875 4.34375 -6.296875 C 3.726562 -6.296875 3.242188 -6.050781 2.890625 -5.5625 C 2.535156 -5.082031 2.359375 -4.410156 2.359375 -3.546875 C 2.359375 -2.691406 2.535156 -2.019531 2.890625 -1.53125 C 3.242188 -1.039062 3.726562 -0.796875 4.34375 -0.796875 C 4.957031 -0.796875 5.441406 -1.039062 5.796875 -1.53125 C 6.148438 -2.019531 6.328125 -2.691406 6.328125 -3.546875 Z M 6.328125 -3.546875 "/>
-</symbol>
-<symbol overflow="visible" id="glyph2-5">
-<path style="stroke:none;" d="M 5.75 -6.90625 L 5.75 -5.796875 C 5.425781 -5.960938 5.085938 -6.085938 4.734375 -6.171875 C 4.378906 -6.253906 4.007812 -6.296875 3.625 -6.296875 C 3.039062 -6.296875 2.601562 -6.207031 2.3125 -6.03125 C 2.03125 -5.851562 1.890625 -5.585938 1.890625 -5.234375 C 1.890625 -4.960938 1.988281 -4.75 2.1875 -4.59375 C 2.394531 -4.445312 2.816406 -4.300781 3.453125 -4.15625 L 3.84375 -4.0625 C 4.675781 -3.882812 5.265625 -3.632812 5.609375 -3.3125 C 5.960938 -2.988281 6.140625 -2.539062 6.140625 -1.96875 C 6.140625 -1.300781 5.878906 -0.773438 5.359375 -0.390625 C 4.835938 -0.00390625 4.117188 0.1875 3.203125 0.1875 C 2.816406 0.1875 2.414062 0.148438 2 0.078125 C 1.59375 0.00390625 1.160156 -0.109375 0.703125 -0.265625 L 0.703125 -1.46875 C 1.140625 -1.238281 1.566406 -1.066406 1.984375 -0.953125 C 2.398438 -0.847656 2.8125 -0.796875 3.21875 -0.796875 C 3.769531 -0.796875 4.191406 -0.890625 4.484375 -1.078125 C 4.785156 -1.265625 4.9375 -1.53125 4.9375 -1.875 C 4.9375 -2.1875 4.828125 -2.425781 4.609375 -2.59375 C 4.398438 -2.769531 3.9375 -2.9375 3.21875 -3.09375 L 2.8125 -3.1875 C 2.082031 -3.34375 1.554688 -3.578125 1.234375 -3.890625 C 0.910156 -4.203125 0.75 -4.632812 0.75 -5.1875 C 0.75 -5.851562 0.984375 -6.367188 1.453125 -6.734375 C 1.929688 -7.097656 2.609375 -7.28125 3.484375 -7.28125 C 3.910156 -7.28125 4.316406 -7.25 4.703125 -7.1875 C 5.085938 -7.125 5.4375 -7.03125 5.75 -6.90625 Z M 5.75 -6.90625 "/>
-</symbol>
-<symbol overflow="visible" id="glyph2-6">
-<path style="stroke:none;" d="M 4.453125 -3.578125 C 3.515625 -3.578125 2.863281 -3.46875 2.5 -3.25 C 2.132812 -3.03125 1.953125 -2.660156 1.953125 -2.140625 C 1.953125 -1.734375 2.085938 -1.40625 2.359375 -1.15625 C 2.628906 -0.914062 3 -0.796875 3.46875 -0.796875 C 4.113281 -0.796875 4.632812 -1.023438 5.03125 -1.484375 C 5.425781 -1.941406 5.625 -2.550781 5.625 -3.3125 L 5.625 -3.578125 Z M 6.78125 -4.0625 L 6.78125 0 L 5.625 0 L 5.625 -1.078125 C 5.351562 -0.648438 5.019531 -0.332031 4.625 -0.125 C 4.226562 0.0820312 3.738281 0.1875 3.15625 0.1875 C 2.425781 0.1875 1.847656 -0.015625 1.421875 -0.421875 C 0.992188 -0.835938 0.78125 -1.382812 0.78125 -2.0625 C 0.78125 -2.863281 1.046875 -3.46875 1.578125 -3.875 C 2.117188 -4.28125 2.921875 -4.484375 3.984375 -4.484375 L 5.625 -4.484375 L 5.625 -4.609375 C 5.625 -5.140625 5.445312 -5.550781 5.09375 -5.84375 C 4.738281 -6.144531 4.238281 -6.296875 3.59375 -6.296875 C 3.1875 -6.296875 2.789062 -6.242188 2.40625 -6.140625 C 2.019531 -6.046875 1.648438 -5.898438 1.296875 -5.703125 L 1.296875 -6.78125 C 1.722656 -6.945312 2.140625 -7.070312 2.546875 -7.15625 C 2.953125 -7.238281 3.34375 -7.28125 3.71875 -7.28125 C 4.75 -7.28125 5.515625 -7.015625 6.015625 -6.484375 C 6.523438 -5.953125 6.78125 -5.144531 6.78125 -4.0625 Z M 6.78125 -4.0625 "/>
-</symbol>
-<symbol overflow="visible" id="glyph2-7">
-<path style="stroke:none;" d="M 1.21875 -9.875 L 2.390625 -9.875 L 2.390625 0 L 1.21875 0 Z M 1.21875 -9.875 "/>
-</symbol>
-<symbol overflow="visible" id="glyph2-8">
-<path style="stroke:none;" d="M 7.3125 -3.84375 L 7.3125 -3.28125 L 1.9375 -3.28125 C 1.988281 -2.46875 2.226562 -1.851562 2.65625 -1.4375 C 3.09375 -1.019531 3.695312 -0.8125 4.46875 -0.8125 C 4.914062 -0.8125 5.347656 -0.863281 5.765625 -0.96875 C 6.191406 -1.082031 6.613281 -1.25 7.03125 -1.46875 L 7.03125 -0.359375 C 6.613281 -0.179688 6.179688 -0.046875 5.734375 0.046875 C 5.296875 0.140625 4.851562 0.1875 4.40625 0.1875 C 3.269531 0.1875 2.367188 -0.140625 1.703125 -0.796875 C 1.046875 -1.460938 0.71875 -2.359375 0.71875 -3.484375 C 0.71875 -4.648438 1.03125 -5.570312 1.65625 -6.25 C 2.289062 -6.9375 3.140625 -7.28125 4.203125 -7.28125 C 5.160156 -7.28125 5.914062 -6.972656 6.46875 -6.359375 C 7.03125 -5.742188 7.3125 -4.90625 7.3125 -3.84375 Z M 6.140625 -4.1875 C 6.128906 -4.820312 5.945312 -5.332031 5.59375 -5.71875 C 5.25 -6.101562 4.789062 -6.296875 4.21875 -6.296875 C 3.5625 -6.296875 3.035156 -6.109375 2.640625 -5.734375 C 2.253906 -5.367188 2.03125 -4.851562 1.96875 -4.1875 Z M 6.140625 -4.1875 "/>
-</symbol>
-<symbol overflow="visible" id="glyph2-9">
-<path style="stroke:none;" d="M 6.328125 -3.546875 C 6.328125 -4.410156 6.148438 -5.082031 5.796875 -5.5625 C 5.441406 -6.050781 4.957031 -6.296875 4.34375 -6.296875 C 3.726562 -6.296875 3.242188 -6.050781 2.890625 -5.5625 C 2.535156 -5.082031 2.359375 -4.410156 2.359375 -3.546875 C 2.359375 -2.691406 2.535156 -2.019531 2.890625 -1.53125 C 3.242188 -1.039062 3.726562 -0.796875 4.34375 -0.796875 C 4.957031 -0.796875 5.441406 -1.039062 5.796875 -1.53125 C 6.148438 -2.019531 6.328125 -2.691406 6.328125 -3.546875 Z M 2.359375 -6.03125 C 2.597656 -6.457031 2.90625 -6.769531 3.28125 -6.96875 C 3.65625 -7.175781 4.101562 -7.28125 4.625 -7.28125 C 5.488281 -7.28125 6.191406 -6.9375 6.734375 -6.25 C 7.273438 -5.5625 7.546875 -4.660156 7.546875 -3.546875 C 7.546875 -2.429688 7.273438 -1.53125 6.734375 -0.84375 C 6.191406 -0.15625 5.488281 0.1875 4.625 0.1875 C 4.101562 0.1875 3.65625 0.0820312 3.28125 -0.125 C 2.90625 -0.332031 2.597656 -0.644531 2.359375 -1.0625 L 2.359375 0 L 1.1875 0 L 1.1875 -9.875 L 2.359375 -9.875 Z M 2.359375 -6.03125 "/>
-</symbol>
-<symbol overflow="visible" id="glyph2-10">
-<path style="stroke:none;" d="M 1.21875 -7.109375 L 2.390625 -7.109375 L 2.390625 0 L 1.21875 0 Z M 1.21875 -9.875 L 2.390625 -9.875 L 2.390625 -8.390625 L 1.21875 -8.390625 Z M 1.21875 -9.875 "/>
-</symbol>
-<symbol overflow="visible" id="glyph2-11">
-<path style="stroke:none;" d="M 7.140625 -4.296875 L 7.140625 0 L 5.96875 0 L 5.96875 -4.25 C 5.96875 -4.925781 5.835938 -5.429688 5.578125 -5.765625 C 5.316406 -6.097656 4.921875 -6.265625 4.390625 -6.265625 C 3.765625 -6.265625 3.269531 -6.0625 2.90625 -5.65625 C 2.539062 -5.257812 2.359375 -4.710938 2.359375 -4.015625 L 2.359375 0 L 1.1875 0 L 1.1875 -7.109375 L 2.359375 -7.109375 L 2.359375 -6 C 2.640625 -6.425781 2.96875 -6.742188 3.34375 -6.953125 C 3.71875 -7.171875 4.15625 -7.28125 4.65625 -7.28125 C 5.46875 -7.28125 6.082031 -7.023438 6.5 -6.515625 C 6.925781 -6.015625 7.140625 -5.273438 7.140625 -4.296875 Z M 7.140625 -4.296875 "/>
-</symbol>
-<symbol overflow="visible" id="glyph2-12">
-<path style="stroke:none;" d="M 5.90625 -3.640625 C 5.90625 -4.484375 5.726562 -5.132812 5.375 -5.59375 C 5.03125 -6.0625 4.539062 -6.296875 3.90625 -6.296875 C 3.28125 -6.296875 2.789062 -6.0625 2.4375 -5.59375 C 2.09375 -5.132812 1.921875 -4.484375 1.921875 -3.640625 C 1.921875 -2.796875 2.09375 -2.140625 2.4375 -1.671875 C 2.789062 -1.210938 3.28125 -0.984375 3.90625 -0.984375 C 4.539062 -0.984375 5.03125 -1.210938 5.375 -1.671875 C 5.726562 -2.140625 5.90625 -2.796875 5.90625 -3.640625 Z M 7.078125 -0.875 C 7.078125 0.332031 6.804688 1.226562 6.265625 1.8125 C 5.722656 2.40625 4.898438 2.703125 3.796875 2.703125 C 3.390625 2.703125 3.003906 2.671875 2.640625 2.609375 C 2.273438 2.546875 1.921875 2.453125 1.578125 2.328125 L 1.578125 1.1875 C 1.921875 1.375 2.257812 1.507812 2.59375 1.59375 C 2.925781 1.6875 3.265625 1.734375 3.609375 1.734375 C 4.378906 1.734375 4.953125 1.535156 5.328125 1.140625 C 5.710938 0.742188 5.90625 0.140625 5.90625 -0.671875 L 5.90625 -1.25 C 5.664062 -0.832031 5.351562 -0.519531 4.96875 -0.3125 C 4.59375 -0.101562 4.144531 0 3.625 0 C 2.75 0 2.046875 -0.332031 1.515625 -1 C 0.984375 -1.664062 0.71875 -2.546875 0.71875 -3.640625 C 0.71875 -4.734375 0.984375 -5.613281 1.515625 -6.28125 C 2.046875 -6.945312 2.75 -7.28125 3.625 -7.28125 C 4.144531 -7.28125 4.59375 -7.175781 4.96875 -6.96875 C 5.351562 -6.757812 5.664062 -6.445312 5.90625 -6.03125 L 5.90625 -7.109375 L 7.078125 -7.109375 Z M 7.078125 -0.875 "/>
-</symbol>
-<symbol overflow="visible" id="glyph2-13">
-<path style="stroke:none;" d="M 5.125 -8.609375 C 4.1875 -8.609375 3.441406 -8.257812 2.890625 -7.5625 C 2.347656 -6.875 2.078125 -5.929688 2.078125 -4.734375 C 2.078125 -3.535156 2.347656 -2.585938 2.890625 -1.890625 C 3.441406 -1.203125 4.1875 -0.859375 5.125 -0.859375 C 6.050781 -0.859375 6.785156 -1.203125 7.328125 -1.890625 C 7.878906 -2.585938 8.15625 -3.535156 8.15625 -4.734375 C 8.15625 -5.929688 7.878906 -6.875 7.328125 -7.5625 C 6.785156 -8.257812 6.050781 -8.609375 5.125 -8.609375 Z M 5.125 -9.65625 C 6.445312 -9.65625 7.503906 -9.207031 8.296875 -8.3125 C 9.097656 -7.414062 9.5 -6.222656 9.5 -4.734375 C 9.5 -3.234375 9.097656 -2.035156 8.296875 -1.140625 C 7.503906 -0.253906 6.445312 0.1875 5.125 0.1875 C 3.789062 0.1875 2.722656 -0.253906 1.921875 -1.140625 C 1.128906 -2.035156 0.734375 -3.234375 0.734375 -4.734375 C 0.734375 -6.222656 1.128906 -7.414062 1.921875 -8.3125 C 2.722656 -9.207031 3.789062 -9.65625 5.125 -9.65625 Z M 5.125 -9.65625 "/>
-</symbol>
-<symbol overflow="visible" id="glyph2-14">
-<path style="stroke:none;" d="M 1.109375 -2.8125 L 1.109375 -7.109375 L 2.265625 -7.109375 L 2.265625 -2.84375 C 2.265625 -2.175781 2.394531 -1.671875 2.65625 -1.328125 C 2.925781 -0.992188 3.320312 -0.828125 3.84375 -0.828125 C 4.476562 -0.828125 4.976562 -1.023438 5.34375 -1.421875 C 5.707031 -1.828125 5.890625 -2.378906 5.890625 -3.078125 L 5.890625 -7.109375 L 7.0625 -7.109375 L 7.0625 0 L 5.890625 0 L 5.890625 -1.09375 C 5.609375 -0.65625 5.28125 -0.332031 4.90625 -0.125 C 4.53125 0.0820312 4.09375 0.1875 3.59375 0.1875 C 2.78125 0.1875 2.160156 -0.0664062 1.734375 -0.578125 C 1.316406 -1.085938 1.109375 -1.832031 1.109375 -2.8125 Z M 4.046875 -7.28125 Z M 4.046875 -7.28125 "/>
-</symbol>
-<symbol overflow="visible" id="glyph2-15">
-<path style="stroke:none;" d="M 2.375 -9.125 L 2.375 -7.109375 L 4.78125 -7.109375 L 4.78125 -6.203125 L 2.375 -6.203125 L 2.375 -2.34375 C 2.375 -1.757812 2.453125 -1.382812 2.609375 -1.21875 C 2.773438 -1.0625 3.101562 -0.984375 3.59375 -0.984375 L 4.78125 -0.984375 L 4.78125 0 L 3.59375 0 C 2.6875 0 2.0625 -0.164062 1.71875 -0.5 C 1.375 -0.84375 1.203125 -1.457031 1.203125 -2.34375 L 1.203125 -6.203125 L 0.34375 -6.203125 L 0.34375 -7.109375 L 1.203125 -7.109375 L 1.203125 -9.125 Z M 2.375 -9.125 "/>
-</symbol>
-<symbol overflow="visible" id="glyph2-16">
-<path style="stroke:none;" d=""/>
-</symbol>
-<symbol overflow="visible" id="glyph2-17">
-<path style="stroke:none;" d="M 1.28125 -9.484375 L 6.71875 -9.484375 L 6.71875 -8.390625 L 2.5625 -8.390625 L 2.5625 -5.609375 L 6.3125 -5.609375 L 6.3125 -4.53125 L 2.5625 -4.53125 L 2.5625 0 L 1.28125 0 Z M 1.28125 -9.484375 "/>
-</symbol>
-<symbol overflow="visible" id="glyph2-18">
-<path style="stroke:none;" d="M 6.765625 -5.75 C 7.054688 -6.269531 7.40625 -6.65625 7.8125 -6.90625 C 8.21875 -7.15625 8.695312 -7.28125 9.25 -7.28125 C 9.988281 -7.28125 10.554688 -7.019531 10.953125 -6.5 C 11.359375 -5.976562 11.5625 -5.242188 11.5625 -4.296875 L 11.5625 0 L 10.390625 0 L 10.390625 -4.25 C 10.390625 -4.9375 10.265625 -5.441406 10.015625 -5.765625 C 9.773438 -6.097656 9.410156 -6.265625 8.921875 -6.265625 C 8.316406 -6.265625 7.835938 -6.0625 7.484375 -5.65625 C 7.128906 -5.257812 6.953125 -4.710938 6.953125 -4.015625 L 6.953125 0 L 5.78125 0 L 5.78125 -4.25 C 5.78125 -4.9375 5.660156 -5.441406 5.421875 -5.765625 C 5.179688 -6.097656 4.804688 -6.265625 4.296875 -6.265625 C 3.703125 -6.265625 3.226562 -6.0625 2.875 -5.65625 C 2.53125 -5.25 2.359375 -4.703125 2.359375 -4.015625 L 2.359375 0 L 1.1875 0 L 1.1875 -7.109375 L 2.359375 -7.109375 L 2.359375 -6 C 2.617188 -6.4375 2.9375 -6.757812 3.3125 -6.96875 C 3.6875 -7.175781 4.128906 -7.28125 4.640625 -7.28125 C 5.160156 -7.28125 5.597656 -7.148438 5.953125 -6.890625 C 6.316406 -6.628906 6.585938 -6.25 6.765625 -5.75 Z M 6.765625 -5.75 "/>
-</symbol>
-<symbol overflow="visible" id="glyph2-19">
-<path style="stroke:none;" d="M 6.953125 -9.171875 L 6.953125 -7.921875 C 6.472656 -8.148438 6.015625 -8.320312 5.578125 -8.4375 C 5.148438 -8.550781 4.734375 -8.609375 4.328125 -8.609375 C 3.628906 -8.609375 3.085938 -8.472656 2.703125 -8.203125 C 2.328125 -7.929688 2.140625 -7.546875 2.140625 -7.046875 C 2.140625 -6.628906 2.265625 -6.3125 2.515625 -6.09375 C 2.773438 -5.882812 3.253906 -5.710938 3.953125 -5.578125 L 4.734375 -5.421875 C 5.679688 -5.234375 6.382812 -4.910156 6.84375 -4.453125 C 7.300781 -3.992188 7.53125 -3.378906 7.53125 -2.609375 C 7.53125 -1.691406 7.222656 -0.992188 6.609375 -0.515625 C 5.992188 -0.046875 5.085938 0.1875 3.890625 0.1875 C 3.441406 0.1875 2.960938 0.132812 2.453125 0.03125 C 1.953125 -0.0703125 1.429688 -0.222656 0.890625 -0.421875 L 0.890625 -1.734375 C 1.410156 -1.441406 1.921875 -1.222656 2.421875 -1.078125 C 2.921875 -0.929688 3.410156 -0.859375 3.890625 -0.859375 C 4.628906 -0.859375 5.195312 -1 5.59375 -1.28125 C 5.988281 -1.570312 6.1875 -1.984375 6.1875 -2.515625 C 6.1875 -2.984375 6.039062 -3.347656 5.75 -3.609375 C 5.46875 -3.867188 5.003906 -4.066406 4.359375 -4.203125 L 3.578125 -4.359375 C 2.617188 -4.546875 1.925781 -4.84375 1.5 -5.25 C 1.070312 -5.65625 0.859375 -6.21875 0.859375 -6.9375 C 0.859375 -7.78125 1.148438 -8.441406 1.734375 -8.921875 C 2.328125 -9.410156 3.144531 -9.65625 4.1875 -9.65625 C 4.625 -9.65625 5.070312 -9.613281 5.53125 -9.53125 C 6 -9.445312 6.472656 -9.328125 6.953125 -9.171875 Z M 6.953125 -9.171875 "/>
-</symbol>
-<symbol overflow="visible" id="glyph2-20">
-<path style="stroke:none;" d="M 4.1875 0.65625 C 3.851562 1.507812 3.53125 2.0625 3.21875 2.3125 C 2.90625 2.570312 2.488281 2.703125 1.96875 2.703125 L 1.03125 2.703125 L 1.03125 1.734375 L 1.71875 1.734375 C 2.039062 1.734375 2.289062 1.65625 2.46875 1.5 C 2.644531 1.34375 2.835938 0.984375 3.046875 0.421875 L 3.265625 -0.109375 L 0.390625 -7.109375 L 1.625 -7.109375 L 3.84375 -1.546875 L 6.0625 -7.109375 L 7.3125 -7.109375 Z M 4.1875 0.65625 "/>
-</symbol>
-</g>
-</defs>
-<g id="surface268880">
-<rect x="0" y="0" width="774" height="152" style="fill:rgb(100%,100%,100%);fill-opacity:1;stroke:none;"/>
-<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 21.75297 10.408118 L 26.433829 10.408118 L 26.433829 12.281165 L 21.75297 12.281165 Z M 21.75297 10.408118 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
-<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 29.079728 10.51222 L 32.829728 10.51222 L 32.829728 12.149915 L 29.079728 12.149915 Z M 29.079728 10.51222 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
-<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
-  <use xlink:href="#glyph0-1" x="20.171875" y="57.705621"/>
-  <use xlink:href="#glyph0-2" x="30.171875" y="57.705621"/>
-  <use xlink:href="#glyph0-3" x="40.171875" y="57.705621"/>
-  <use xlink:href="#glyph0-4" x="50.171875" y="57.705621"/>
-  <use xlink:href="#glyph0-5" x="60.171875" y="57.705621"/>
-  <use xlink:href="#glyph0-6" x="70.171875" y="57.705621"/>
-</g>
-<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
-  <use xlink:href="#glyph0-7" x="174.203125" y="60.053277"/>
-  <use xlink:href="#glyph0-8" x="184.203125" y="60.053277"/>
-</g>
-<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 40.925236 10.544446 L 44.675236 10.544446 L 44.675236 12.090345 L 40.925236 12.090345 Z M 40.925236 10.544446 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
-<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 34.883439 10.536634 L 38.633439 10.536634 L 38.633439 12.120032 L 34.883439 12.120032 Z M 34.883439 10.536634 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
-<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 47.084806 10.484876 L 52.045743 10.484876 L 52.045743 12.130774 L 47.084806 12.130774 Z M 47.084806 10.484876 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
-<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 53.980118 10.376868 L 59.866642 10.376868 L 59.866642 12.279603 L 53.980118 12.279603 Z M 53.980118 10.376868 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
-<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 54.048478 13.825501 L 59.868009 13.825501 L 59.868009 15.490345 L 54.048478 15.490345 Z M 54.048478 13.825501 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
-<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 26.481876 11.338001 L 28.593009 11.332337 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
-<path style="fill-rule:evenodd;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 28.968009 11.33136 L 28.468595 11.582728 L 28.593009 11.332337 L 28.467228 11.082728 Z M 28.968009 11.33136 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
-<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 32.876798 11.329798 L 34.396525 11.328626 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
-<path style="fill-rule:evenodd;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 34.771525 11.328431 L 34.27172 11.578821 L 34.396525 11.328626 L 34.271329 11.078821 Z M 34.771525 11.328431 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
-<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 38.633439 11.328431 L 40.438517 11.319642 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
-<path style="fill-rule:evenodd;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 40.813517 11.317884 L 40.314689 11.570228 L 40.438517 11.319642 L 40.312345 11.070423 Z M 40.813517 11.317884 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
-<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 44.675236 11.317298 L 46.597892 11.309876 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
-<path style="fill-rule:evenodd;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 46.972892 11.308313 L 46.473868 11.560267 L 46.597892 11.309876 L 46.471915 11.060267 Z M 46.972892 11.308313 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
-<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 52.045743 11.307923 L 53.4934 11.323157 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
-<path style="fill-rule:evenodd;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 53.8684 11.327063 L 53.365861 11.57179 L 53.4934 11.323157 L 53.370939 11.07179 Z M 53.8684 11.327063 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
-<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
-  <use xlink:href="#glyph0-9" x="286.757813" y="60.611871"/>
-  <use xlink:href="#glyph0-10" x="296.757813" y="60.611871"/>
-  <use xlink:href="#glyph0-1" x="306.757813" y="60.611871"/>
-</g>
-<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
-  <use xlink:href="#glyph0-11" x="405.660156" y="59.904839"/>
-  <use xlink:href="#glyph0-10" x="415.660156" y="59.904839"/>
-  <use xlink:href="#glyph0-12" x="425.660156" y="59.904839"/>
-</g>
-<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
-  <use xlink:href="#glyph1-1" x="511.308594" y="58.064616"/>
-  <use xlink:href="#glyph1-2" x="517.308757" y="58.064616"/>
-  <use xlink:href="#glyph1-3" x="523.308919" y="58.064616"/>
-  <use xlink:href="#glyph1-4" x="529.309082" y="58.064616"/>
-  <use xlink:href="#glyph1-5" x="535.309245" y="58.064616"/>
-  <use xlink:href="#glyph1-6" x="541.309408" y="58.064616"/>
-  <use xlink:href="#glyph1-7" x="547.30957" y="58.064616"/>
-  <use xlink:href="#glyph1-8" x="553.309733" y="58.064616"/>
-  <use xlink:href="#glyph1-9" x="559.309896" y="58.064616"/>
-  <use xlink:href="#glyph1-10" x="565.310059" y="58.064616"/>
-  <use xlink:href="#glyph1-11" x="571.310221" y="58.064616"/>
-  <use xlink:href="#glyph1-12" x="577.310384" y="58.064616"/>
-  <use xlink:href="#glyph1-13" x="583.310547" y="58.064616"/>
-  <use xlink:href="#glyph1-8" x="589.31071" y="58.064616"/>
-  <use xlink:href="#glyph1-14" x="595.310872" y="58.064616"/>
-</g>
-<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 45.671915 11.342298 L 45.655704 11.342298 L 45.655704 14.657923 L 53.561759 14.657923 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
-<path style="fill-rule:evenodd;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 53.936759 14.657923 L 53.436759 14.907923 L 53.561759 14.657923 L 53.436759 14.407923 Z M 53.936759 14.657923 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
-<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
-  <use xlink:href="#glyph1-15" x="657.078125" y="57.724772"/>
-  <use xlink:href="#glyph1-16" x="663.078288" y="57.724772"/>
-  <use xlink:href="#glyph1-10" x="669.078451" y="57.724772"/>
-  <use xlink:href="#glyph1-6" x="675.078613" y="57.724772"/>
-  <use xlink:href="#glyph1-8" x="681.078776" y="57.724772"/>
-  <use xlink:href="#glyph1-17" x="687.078939" y="57.724772"/>
-  <use xlink:href="#glyph1-11" x="693.079102" y="57.724772"/>
-  <use xlink:href="#glyph1-18" x="699.079264" y="57.724772"/>
-  <use xlink:href="#glyph1-19" x="705.079427" y="57.724772"/>
-  <use xlink:href="#glyph1-4" x="711.07959" y="57.724772"/>
-  <use xlink:href="#glyph1-20" x="717.079753" y="57.724772"/>
-  <use xlink:href="#glyph1-21" x="723.079915" y="57.724772"/>
-  <use xlink:href="#glyph1-22" x="729.080078" y="57.724772"/>
-  <use xlink:href="#glyph1-23" x="735.080241" y="57.724772"/>
-  <use xlink:href="#glyph1-21" x="741.080404" y="57.724772"/>
-  <use xlink:href="#glyph1-22" x="747.080566" y="57.724772"/>
-</g>
-<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
-  <use xlink:href="#glyph1-24" x="673.335938" y="124.170085"/>
-  <use xlink:href="#glyph1-11" x="679.3361" y="124.170085"/>
-  <use xlink:href="#glyph1-13" x="685.336263" y="124.170085"/>
-  <use xlink:href="#glyph1-8" x="691.336426" y="124.170085"/>
-  <use xlink:href="#glyph1-4" x="697.336589" y="124.170085"/>
-  <use xlink:href="#glyph1-20" x="703.336751" y="124.170085"/>
-  <use xlink:href="#glyph1-21" x="709.336914" y="124.170085"/>
-  <use xlink:href="#glyph1-22" x="715.337077" y="124.170085"/>
-  <use xlink:href="#glyph1-23" x="721.33724" y="124.170085"/>
-  <use xlink:href="#glyph1-21" x="727.337402" y="124.170085"/>
-  <use xlink:href="#glyph1-22" x="733.337565" y="124.170085"/>
-</g>
-<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
-  <use xlink:href="#glyph2-1" x="168.71875" y="31.959093"/>
-  <use xlink:href="#glyph2-2" x="175.866102" y="31.959093"/>
-  <use xlink:href="#glyph2-3" x="180.92551" y="31.959093"/>
-  <use xlink:href="#glyph2-4" x="188.879069" y="31.959093"/>
-</g>
-<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
-  <use xlink:href="#glyph2-5" x="288.109375" y="31.681749"/>
-  <use xlink:href="#glyph2-1" x="294.882378" y="31.681749"/>
-  <use xlink:href="#glyph2-6" x="302.029731" y="31.681749"/>
-  <use xlink:href="#glyph2-7" x="309.996039" y="31.681749"/>
-  <use xlink:href="#glyph2-8" x="313.607964" y="31.681749"/>
-</g>
-<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
-  <use xlink:href="#glyph2-5" x="535.988281" y="33.365343"/>
-  <use xlink:href="#glyph2-1" x="542.761285" y="33.365343"/>
-  <use xlink:href="#glyph2-6" x="549.908637" y="33.365343"/>
-  <use xlink:href="#glyph2-7" x="557.874946" y="33.365343"/>
-  <use xlink:href="#glyph2-8" x="561.486871" y="33.365343"/>
-</g>
-<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
-  <use xlink:href="#glyph2-9" x="26.695313" y="32.365343"/>
-  <use xlink:href="#glyph2-10" x="34.947266" y="32.365343"/>
-  <use xlink:href="#glyph2-11" x="38.559191" y="32.365343"/>
-  <use xlink:href="#glyph2-11" x="46.798394" y="32.365343"/>
-  <use xlink:href="#glyph2-10" x="55.037598" y="32.365343"/>
-  <use xlink:href="#glyph2-11" x="58.649523" y="32.365343"/>
-  <use xlink:href="#glyph2-12" x="66.888726" y="32.365343"/>
-</g>
-<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-dasharray:0.14,0.14;stroke-miterlimit:10;" d="M 45.300431 9.486438 L 60.373478 9.486438 L 60.373478 16.175696 L 45.300431 16.175696 Z M 45.300431 9.486438 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
-<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
-  <use xlink:href="#glyph2-13" x="532.003906" y="11.904405"/>
-  <use xlink:href="#glyph2-14" x="542.236382" y="11.904405"/>
-  <use xlink:href="#glyph2-15" x="550.475586" y="11.904405"/>
-  <use xlink:href="#glyph2-4" x="555.5727" y="11.904405"/>
-  <use xlink:href="#glyph2-14" x="563.824653" y="11.904405"/>
-  <use xlink:href="#glyph2-15" x="572.063856" y="11.904405"/>
-  <use xlink:href="#glyph2-16" x="577.16097" y="11.904405"/>
-  <use xlink:href="#glyph2-17" x="581.293186" y="11.904405"/>
-  <use xlink:href="#glyph2-3" x="588.307346" y="11.904405"/>
-  <use xlink:href="#glyph2-2" x="596.260905" y="11.904405"/>
-  <use xlink:href="#glyph2-18" x="601.377279" y="11.904405"/>
-  <use xlink:href="#glyph2-6" x="614.040853" y="11.904405"/>
-  <use xlink:href="#glyph2-15" x="622.007161" y="11.904405"/>
-  <use xlink:href="#glyph2-15" x="627.104275" y="11.904405"/>
-  <use xlink:href="#glyph2-8" x="632.201389" y="11.904405"/>
-  <use xlink:href="#glyph2-2" x="640.199436" y="11.904405"/>
-  <use xlink:href="#glyph2-16" x="645.544217" y="11.904405"/>
-  <use xlink:href="#glyph2-19" x="649.676432" y="11.904405"/>
-  <use xlink:href="#glyph2-20" x="657.928385" y="11.904405"/>
-  <use xlink:href="#glyph2-5" x="665.621799" y="11.904405"/>
-  <use xlink:href="#glyph2-15" x="672.394803" y="11.904405"/>
-  <use xlink:href="#glyph2-8" x="677.491916" y="11.904405"/>
-  <use xlink:href="#glyph2-18" x="685.489963" y="11.904405"/>
-</g>
-</g>
-</svg>
diff --git a/Documentation/media/v4l-drivers/ivtv-cardlist.rst b/Documentation/media/v4l-drivers/ivtv-cardlist.rst
deleted file mode 100644
index c34a9ebc9ac2..000000000000
--- a/Documentation/media/v4l-drivers/ivtv-cardlist.rst
+++ /dev/null
@@ -1,139 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-IVTV cards list
-===============
-
-.. tabularcolumns:: |p{1.4cm}|p{12.7cm}|p{3.4cm}|
-
-.. flat-table::
-   :header-rows: 1
-   :widths: 2 19 18
-   :stub-columns: 0
-
-   * - Card number
-     - Card name
-     - PCI IDs
-
-   * - 0
-     - Hauppauge WinTV PVR-250
-     - IVTV16 104d:813d
-
-   * - 1
-     - Hauppauge WinTV PVR-350
-     - IVTV16 104d:813d
-
-   * - 2
-     - Hauppauge WinTV PVR-150
-     - IVTV16 104d:813d
-
-   * - 3
-     - AVerMedia M179
-     - IVTV15 1461:a3cf, IVTV15 1461:a3ce
-
-   * - 4
-     - Yuan MPG600, Kuroutoshikou ITVC16-STVLP
-     - IVTV16 12ab:fff3, IVTV16 12ab:ffff
-
-   * - 5
-     - YUAN MPG160, Kuroutoshikou ITVC15-STVLP, I/O Data GV-M2TV/PCI
-     - IVTV15 10fc:40a0
-
-   * - 6
-     - Yuan PG600, Diamond PVR-550
-     - IVTV16 ff92:0070, IVTV16 ffab:0600
-
-   * - 7
-     - Adaptec VideOh! AVC-2410
-     - IVTV16 9005:0093
-
-   * - 8
-     - Adaptec VideOh! AVC-2010
-     - IVTV16 9005:0092
-
-   * - 9
-     - Nagase Transgear 5000TV
-     - IVTV16 1461:bfff
-
-   * - 10
-     - AOpen VA2000MAX-SNT6
-     - IVTV16 0000:ff5f
-
-   * - 11
-     - Yuan MPG600GR, Kuroutoshikou CX23416GYC-STVLP
-     - IVTV16 12ab:0600, IVTV16 fbab:0600, IVTV16 1154:0523
-
-   * - 12
-     - I/O Data GV-MVP/RX, GV-MVP/RX2W (dual tuner)
-     - IVTV16 10fc:d01e, IVTV16 10fc:d038, IVTV16 10fc:d039
-
-   * - 13
-     - I/O Data GV-MVP/RX2E
-     - IVTV16 10fc:d025
-
-   * - 14
-     - GotView PCI DVD
-     - IVTV16 12ab:0600
-
-   * - 15
-     - GotView PCI DVD2 Deluxe
-     - IVTV16 ffac:0600
-
-   * - 16
-     - Yuan MPC622
-     - IVTV16 ff01:d998
-
-   * - 17
-     - Digital Cowboy DCT-MTVP1
-     - IVTV16 1461:bfff
-
-   * - 18
-     - Yuan PG600-2, GotView PCI DVD Lite
-     - IVTV16 ffab:0600, IVTV16 ffad:0600
-
-   * - 19
-     - Club3D ZAP-TV1x01
-     - IVTV16 ffab:0600
-
-   * - 20
-     - AVerTV MCE 116 Plus
-     - IVTV16 1461:c439
-
-   * - 21
-     - ASUS Falcon2
-     - IVTV16 1043:4b66, IVTV16 1043:462e, IVTV16 1043:4b2e
-
-   * - 22
-     - AVerMedia PVR-150 Plus / AVerTV M113 Partsnic (Daewoo) Tuner
-     - IVTV16 1461:c034, IVTV16 1461:c035
-
-   * - 23
-     - AVerMedia EZMaker PCI Deluxe
-     - IVTV16 1461:c03f
-
-   * - 24
-     - AVerMedia M104
-     - IVTV16 1461:c136
-
-   * - 25
-     - Buffalo PC-MV5L/PCI
-     - IVTV16 1154:052b
-
-   * - 26
-     - AVerMedia UltraTV 1500 MCE / AVerTV M113 Philips Tuner
-     - IVTV16 1461:c019, IVTV16 1461:c01b
-
-   * - 27
-     - Sony VAIO Giga Pocket (ENX Kikyou)
-     - IVTV16 104d:813d
-
-   * - 28
-     - Hauppauge WinTV PVR-350 (V1)
-     - IVTV16 104d:813d
-
-   * - 29
-     - Yuan MPG600GR, Kuroutoshikou CX23416GYC-STVLP (no GR)
-     - IVTV16 104d:813d
-
-   * - 30
-     - Yuan MPG600GR, Kuroutoshikou CX23416GYC-STVLP (no GR/YCS)
-     - IVTV16 104d:813d
diff --git a/Documentation/media/v4l-drivers/ivtv.rst b/Documentation/media/v4l-drivers/ivtv.rst
deleted file mode 100644
index 7b8775d20214..000000000000
--- a/Documentation/media/v4l-drivers/ivtv.rst
+++ /dev/null
@@ -1,218 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-The ivtv driver
-===============
-
-Author: Hans Verkuil <hverkuil@xs4all.nl>
-
-This is a v4l2 device driver for the Conexant cx23415/6 MPEG encoder/decoder.
-The cx23415 can do both encoding and decoding, the cx23416 can only do MPEG
-encoding. Currently the only card featuring full decoding support is the
-Hauppauge PVR-350.
-
-.. note::
-
-   #) This driver requires the latest encoder firmware (version 2.06.039, size
-      376836 bytes). Get the firmware from here:
-
-      https://linuxtv.org/downloads/firmware/#conexant
-
-   #) 'normal' TV applications do not work with this driver, you need
-      an application that can handle MPEG input such as mplayer, xine, MythTV,
-      etc.
-
-The primary goal of the IVTV project is to provide a "clean room" Linux
-Open Source driver implementation for video capture cards based on the
-iCompression iTVC15 or Conexant CX23415/CX23416 MPEG Codec.
-
-Features
---------
-
- * Hardware mpeg2 capture of broadcast video (and sound) via the tuner or
-   S-Video/Composite and audio line-in.
- * Hardware mpeg2 capture of FM radio where hardware support exists
- * Supports NTSC, PAL, SECAM with stereo sound
- * Supports SAP and bilingual transmissions.
- * Supports raw VBI (closed captions and teletext).
- * Supports sliced VBI (closed captions and teletext) and is able to insert
-   this into the captured MPEG stream.
- * Supports raw YUV and PCM input.
-
-Additional features for the PVR-350 (CX23415 based)
----------------------------------------------------
-
- * Provides hardware mpeg2 playback
- * Provides comprehensive OSD (On Screen Display: ie. graphics overlaying the
-   video signal)
- * Provides a framebuffer (allowing X applications to appear on the video
-   device)
- * Supports raw YUV output.
-
-IMPORTANT: In case of problems first read this page:
-	https://help.ubuntu.com/community/Install_IVTV_Troubleshooting
-
-See also
---------
-
-https://linuxtv.org
-
-IRC
----
-
-irc://irc.freenode.net/#v4l
-
-----------------------------------------------------------
-
-Devices
--------
-
-A maximum of 12 ivtv boards are allowed at the moment.
-
-Cards that don't have a video output capability (i.e. non PVR350 cards)
-lack the vbi8, vbi16, video16 and video48 devices. They also do not
-support the framebuffer device /dev/fbx for OSD.
-
-The radio0 device may or may not be present, depending on whether the
-card has a radio tuner or not.
-
-Here is a list of the base v4l devices:
-
-.. code-block:: none
-
-	crw-rw----    1 root     video     81,   0 Jun 19 22:22 /dev/video0
-	crw-rw----    1 root     video     81,  16 Jun 19 22:22 /dev/video16
-	crw-rw----    1 root     video     81,  24 Jun 19 22:22 /dev/video24
-	crw-rw----    1 root     video     81,  32 Jun 19 22:22 /dev/video32
-	crw-rw----    1 root     video     81,  48 Jun 19 22:22 /dev/video48
-	crw-rw----    1 root     video     81,  64 Jun 19 22:22 /dev/radio0
-	crw-rw----    1 root     video     81, 224 Jun 19 22:22 /dev/vbi0
-	crw-rw----    1 root     video     81, 228 Jun 19 22:22 /dev/vbi8
-	crw-rw----    1 root     video     81, 232 Jun 19 22:22 /dev/vbi16
-
-Base devices
-------------
-
-For every extra card you have the numbers increased by one. For example,
-/dev/video0 is listed as the 'base' encoding capture device so we have:
-
-- /dev/video0  is the encoding capture device for the first card (card 0)
-- /dev/video1  is the encoding capture device for the second card (card 1)
-- /dev/video2  is the encoding capture device for the third card (card 2)
-
-Note that if the first card doesn't have a feature (eg no decoder, so no
-video16, the second card will still use video17. The simple rule is 'add
-the card number to the base device number'. If you have other capture
-cards (e.g. WinTV PCI) that are detected first, then you have to tell
-the ivtv module about it so that it will start counting at 1 (or 2, or
-whatever). Otherwise the device numbers can get confusing. The ivtv
-'ivtv_first_minor' module option can be used for that.
-
-
-- /dev/video0
-
-  The encoding capture device(s).
-
-  Read-only.
-
-  Reading from this device gets you the MPEG1/2 program stream.
-  Example:
-
-  .. code-block:: none
-
-	cat /dev/video0 > my.mpg (you need to hit ctrl-c to exit)
-
-
-- /dev/video16
-
-  The decoder output device(s)
-
-  Write-only. Only present if the MPEG decoder (i.e. CX23415) exists.
-
-  An mpeg2 stream sent to this device will appear on the selected video
-  display, audio will appear on the line-out/audio out.  It is only
-  available for cards that support video out. Example:
-
-  .. code-block:: none
-
-	cat my.mpg >/dev/video16
-
-
-- /dev/video24
-
-  The raw audio capture device(s).
-
-  Read-only
-
-  The raw audio PCM stereo stream from the currently selected
-  tuner or audio line-in.  Reading from this device results in a raw
-  (signed 16 bit Little Endian, 48000 Hz, stereo pcm) capture.
-  This device only captures audio. This should be replaced by an ALSA
-  device in the future.
-  Note that there is no corresponding raw audio output device, this is
-  not supported in the decoder firmware.
-
-
-- /dev/video32
-
-  The raw video capture device(s)
-
-  Read-only
-
-  The raw YUV video output from the current video input. The YUV format
-  is non-standard (V4L2_PIX_FMT_HM12).
-
-  Note that the YUV and PCM streams are not synchronized, so they are of
-  limited use.
-
-
-- /dev/video48
-
-  The raw video display device(s)
-
-  Write-only. Only present if the MPEG decoder (i.e. CX23415) exists.
-
-  Writes a YUV stream to the decoder of the card.
-
-
-- /dev/radio0
-
-  The radio tuner device(s)
-
-  Cannot be read or written.
-
-  Used to enable the radio tuner and tune to a frequency. You cannot
-  read or write audio streams with this device.  Once you use this
-  device to tune the radio, use /dev/video24 to read the raw pcm stream
-  or /dev/video0 to get an mpeg2 stream with black video.
-
-
-- /dev/vbi0
-
-  The 'vertical blank interval' (Teletext, CC, WSS etc) capture device(s)
-
-  Read-only
-
-  Captures the raw (or sliced) video data sent during the Vertical Blank
-  Interval. This data is used to encode teletext, closed captions, VPS,
-  widescreen signalling, electronic program guide information, and other
-  services.
-
-
-- /dev/vbi8
-
-  Processed vbi feedback device(s)
-
-  Read-only. Only present if the MPEG decoder (i.e. CX23415) exists.
-
-  The sliced VBI data embedded in an MPEG stream is reproduced on this
-  device. So while playing back a recording on /dev/video16, you can
-  read the embedded VBI data from /dev/vbi8.
-
-
-- /dev/vbi16
-
-  The vbi 'display' device(s)
-
-  Write-only. Only present if the MPEG decoder (i.e. CX23415) exists.
-
-  Can be used to send sliced VBI data to the video-out connector.
diff --git a/Documentation/media/v4l-drivers/max2175.rst b/Documentation/media/v4l-drivers/max2175.rst
deleted file mode 100644
index a5e35059d98d..000000000000
--- a/Documentation/media/v4l-drivers/max2175.rst
+++ /dev/null
@@ -1,64 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-Maxim Integrated MAX2175 RF to bits tuner driver
-================================================
-
-The MAX2175 driver implements the following driver-specific controls:
-
-``V4L2_CID_MAX2175_I2S_ENABLE``
--------------------------------
-    Enable/Disable I2S output of the tuner. This is a private control
-    that can be accessed only using the subdev interface.
-    Refer to Documentation/media/kapi/v4l2-controls.rst for more details.
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 4
-
-    * - ``(0)``
-      - I2S output is disabled.
-    * - ``(1)``
-      - I2S output is enabled.
-
-``V4L2_CID_MAX2175_HSLS``
--------------------------
-    The high-side/low-side (HSLS) control of the tuner for a given band.
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 4
-
-    * - ``(0)``
-      - The LO frequency position is below the desired frequency.
-    * - ``(1)``
-      - The LO frequency position is above the desired frequency.
-
-``V4L2_CID_MAX2175_RX_MODE (menu)``
------------------------------------
-    The Rx mode controls a number of preset parameters of the tuner like
-    sample clock (sck), sampling rate etc. These multiple settings are
-    provided under one single label called Rx mode in the datasheet. The
-    list below shows the supported modes with a brief description.
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 4
-
-    * - ``"Europe modes"``
-    * - ``"FM 1.2" (0)``
-      - This configures FM band with a sample rate of 0.512 million
-        samples/sec with a 10.24 MHz sck.
-    * - ``"DAB 1.2" (1)``
-      - This configures VHF band with a sample rate of 2.048 million
-        samples/sec with a 32.768 MHz sck.
-
-    * - ``"North America modes"``
-    * - ``"FM 1.0" (0)``
-      - This configures FM band with a sample rate of 0.7441875 million
-        samples/sec with a 14.88375 MHz sck.
-    * - ``"DAB 1.2" (1)``
-      - This configures FM band with a sample rate of 0.372 million
-        samples/sec with a 7.441875 MHz sck.
diff --git a/Documentation/media/v4l-drivers/meye.rst b/Documentation/media/v4l-drivers/meye.rst
deleted file mode 100644
index dc57a6a91b43..000000000000
--- a/Documentation/media/v4l-drivers/meye.rst
+++ /dev/null
@@ -1,134 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-.. include:: <isonum.txt>
-
-Vaio Picturebook Motion Eye Camera Driver
-=========================================
-
-Copyright |copy| 2001-2004 Stelian Pop <stelian@popies.net>
-
-Copyright |copy| 2001-2002 Alcôve <www.alcove.com>
-
-Copyright |copy| 2000 Andrew Tridgell <tridge@samba.org>
-
-This driver enable the use of video4linux compatible applications with the
-Motion Eye camera. This driver requires the "Sony Laptop Extras" driver (which
-can be found in the "Misc devices" section of the kernel configuration utility)
-to be compiled and installed (using its "camera=1" parameter).
-
-It can do at maximum 30 fps @ 320x240 or 15 fps @ 640x480.
-
-Grabbing is supported in packed YUV colorspace only.
-
-MJPEG hardware grabbing is supported via a private API (see below).
-
-Hardware supported
-------------------
-
-This driver supports the 'second' version of the MotionEye camera :)
-
-The first version was connected directly on the video bus of the Neomagic
-video card and is unsupported.
-
-The second one, made by Kawasaki Steel is fully supported by this
-driver (PCI vendor/device is 0x136b/0xff01)
-
-The third one, present in recent (more or less last year) Picturebooks
-(C1M* models), is not supported. The manufacturer has given the specs
-to the developers under a NDA (which allows the development of a GPL
-driver however), but things are not moving very fast (see
-http://r-engine.sourceforge.net/) (PCI vendor/device is 0x10cf/0x2011).
-
-There is a forth model connected on the USB bus in TR1* Vaio laptops.
-This camera is not supported at all by the current driver, in fact
-little information if any is available for this camera
-(USB vendor/device is 0x054c/0x0107).
-
-Driver options
---------------
-
-Several options can be passed to the meye driver using the standard
-module argument syntax (<param>=<value> when passing the option to the
-module or meye.<param>=<value> on the kernel boot line when meye is
-statically linked into the kernel). Those options are:
-
-.. code-block:: none
-
-	gbuffers:	number of capture buffers, default is 2 (32 max)
-
-	gbufsize:	size of each capture buffer, default is 614400
-
-	video_nr:	video device to register (0 = /dev/video0, etc)
-
-Module use
-----------
-
-In order to automatically load the meye module on use, you can put those lines
-in your /etc/modprobe.d/meye.conf file:
-
-.. code-block:: none
-
-	alias char-major-81 videodev
-	alias char-major-81-0 meye
-	options meye gbuffers=32
-
-Usage:
-------
-
-.. code-block:: none
-
-	xawtv >= 3.49 (<http://bytesex.org/xawtv/>)
-		for display and uncompressed video capture:
-
-			xawtv -c /dev/video0 -geometry 640x480
-				or
-			xawtv -c /dev/video0 -geometry 320x240
-
-	motioneye (<http://popies.net/meye/>)
-		for getting ppm or jpg snapshots, mjpeg video
-
-Private API
------------
-
-The driver supports frame grabbing with the video4linux API,
-so all video4linux tools (like xawtv) should work with this driver.
-
-Besides the video4linux interface, the driver has a private interface
-for accessing the Motion Eye extended parameters (camera sharpness,
-agc, video framerate), the snapshot and the MJPEG capture facilities.
-
-This interface consists of several ioctls (prototypes and structures
-can be found in include/linux/meye.h):
-
-MEYEIOC_G_PARAMS and MEYEIOC_S_PARAMS
-	Get and set the extended parameters of the motion eye camera.
-	The user should always query the current parameters with
-	MEYEIOC_G_PARAMS, change what he likes and then issue the
-	MEYEIOC_S_PARAMS call (checking for -EINVAL). The extended
-	parameters are described by the meye_params structure.
-
-
-MEYEIOC_QBUF_CAPT
-	Queue a buffer for capture (the buffers must have been
-	obtained with a VIDIOCGMBUF call and mmap'ed by the
-	application). The argument to MEYEIOC_QBUF_CAPT is the
-	buffer number to queue (or -1 to end capture). The first
-	call to MEYEIOC_QBUF_CAPT starts the streaming capture.
-
-MEYEIOC_SYNC
-	Takes as an argument the buffer number you want to sync.
-	This ioctl blocks until the buffer is filled and ready
-	for the application to use. It returns the buffer size.
-
-MEYEIOC_STILLCAPT and MEYEIOC_STILLJCAPT
-	Takes a snapshot in an uncompressed or compressed jpeg format.
-	This ioctl blocks until the snapshot is done and returns (for
-	jpeg snapshot) the size of the image. The image data is
-	available from the first mmap'ed buffer.
-
-Look at the 'motioneye' application code for an actual example.
-
-Bugs / Todo
------------
-
-- 'motioneye' still uses the meye private v4l1 API extensions.
diff --git a/Documentation/media/v4l-drivers/omap3isp.rst b/Documentation/media/v4l-drivers/omap3isp.rst
deleted file mode 100644
index 8974c444e3a1..000000000000
--- a/Documentation/media/v4l-drivers/omap3isp.rst
+++ /dev/null
@@ -1,284 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-.. include:: <isonum.txt>
-
-OMAP 3 Image Signal Processor (ISP) driver
-==========================================
-
-Copyright |copy| 2010 Nokia Corporation
-
-Copyright |copy| 2009 Texas Instruments, Inc.
-
-Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>,
-Sakari Ailus <sakari.ailus@iki.fi>, David Cohen <dacohen@gmail.com>
-
-
-Introduction
-------------
-
-This file documents the Texas Instruments OMAP 3 Image Signal Processor (ISP)
-driver located under drivers/media/platform/omap3isp. The original driver was
-written by Texas Instruments but since that it has been rewritten (twice) at
-Nokia.
-
-The driver has been successfully used on the following versions of OMAP 3:
-
-- 3430
-- 3530
-- 3630
-
-The driver implements V4L2, Media controller and v4l2_subdev interfaces.
-Sensor, lens and flash drivers using the v4l2_subdev interface in the kernel
-are supported.
-
-
-Split to subdevs
-----------------
-
-The OMAP 3 ISP is split into V4L2 subdevs, each of the blocks inside the ISP
-having one subdev to represent it. Each of the subdevs provide a V4L2 subdev
-interface to userspace.
-
-- OMAP3 ISP CCP2
-- OMAP3 ISP CSI2a
-- OMAP3 ISP CCDC
-- OMAP3 ISP preview
-- OMAP3 ISP resizer
-- OMAP3 ISP AEWB
-- OMAP3 ISP AF
-- OMAP3 ISP histogram
-
-Each possible link in the ISP is modelled by a link in the Media controller
-interface. For an example program see [#f2]_.
-
-
-Controlling the OMAP 3 ISP
---------------------------
-
-In general, the settings given to the OMAP 3 ISP take effect at the beginning
-of the following frame. This is done when the module becomes idle during the
-vertical blanking period on the sensor. In memory-to-memory operation the pipe
-is run one frame at a time. Applying the settings is done between the frames.
-
-All the blocks in the ISP, excluding the CSI-2 and possibly the CCP2 receiver,
-insist on receiving complete frames. Sensors must thus never send the ISP
-partial frames.
-
-Autoidle does have issues with some ISP blocks on the 3430, at least.
-Autoidle is only enabled on 3630 when the omap3isp module parameter autoidle
-is non-zero.
-
-
-Events
-------
-
-The OMAP 3 ISP driver does support the V4L2 event interface on CCDC and
-statistics (AEWB, AF and histogram) subdevs.
-
-The CCDC subdev produces V4L2_EVENT_FRAME_SYNC type event on HS_VS
-interrupt which is used to signal frame start. Earlier version of this
-driver used V4L2_EVENT_OMAP3ISP_HS_VS for this purpose. The event is
-triggered exactly when the reception of the first line of the frame starts
-in the CCDC module. The event can be subscribed on the CCDC subdev.
-
-(When using parallel interface one must pay account to correct configuration
-of the VS signal polarity. This is automatically correct when using the serial
-receivers.)
-
-Each of the statistics subdevs is able to produce events. An event is
-generated whenever a statistics buffer can be dequeued by a user space
-application using the VIDIOC_OMAP3ISP_STAT_REQ IOCTL. The events available
-are:
-
-- V4L2_EVENT_OMAP3ISP_AEWB
-- V4L2_EVENT_OMAP3ISP_AF
-- V4L2_EVENT_OMAP3ISP_HIST
-
-The type of the event data is struct omap3isp_stat_event_status for these
-ioctls. If there is an error calculating the statistics, there will be an
-event as usual, but no related statistics buffer. In this case
-omap3isp_stat_event_status.buf_err is set to non-zero.
-
-
-Private IOCTLs
---------------
-
-The OMAP 3 ISP driver supports standard V4L2 IOCTLs and controls where
-possible and practical. Much of the functions provided by the ISP, however,
-does not fall under the standard IOCTLs --- gamma tables and configuration of
-statistics collection are examples of such.
-
-In general, there is a private ioctl for configuring each of the blocks
-containing hardware-dependent functions.
-
-The following private IOCTLs are supported:
-
-- VIDIOC_OMAP3ISP_CCDC_CFG
-- VIDIOC_OMAP3ISP_PRV_CFG
-- VIDIOC_OMAP3ISP_AEWB_CFG
-- VIDIOC_OMAP3ISP_HIST_CFG
-- VIDIOC_OMAP3ISP_AF_CFG
-- VIDIOC_OMAP3ISP_STAT_REQ
-- VIDIOC_OMAP3ISP_STAT_EN
-
-The parameter structures used by these ioctls are described in
-include/linux/omap3isp.h. The detailed functions of the ISP itself related to
-a given ISP block is described in the Technical Reference Manuals (TRMs) ---
-see the end of the document for those.
-
-While it is possible to use the ISP driver without any use of these private
-IOCTLs it is not possible to obtain optimal image quality this way. The AEWB,
-AF and histogram modules cannot be used without configuring them using the
-appropriate private IOCTLs.
-
-
-CCDC and preview block IOCTLs
------------------------------
-
-The VIDIOC_OMAP3ISP_CCDC_CFG and VIDIOC_OMAP3ISP_PRV_CFG IOCTLs are used to
-configure, enable and disable functions in the CCDC and preview blocks,
-respectively. Both IOCTLs control several functions in the blocks they
-control. VIDIOC_OMAP3ISP_CCDC_CFG IOCTL accepts a pointer to struct
-omap3isp_ccdc_update_config as its argument. Similarly VIDIOC_OMAP3ISP_PRV_CFG
-accepts a pointer to struct omap3isp_prev_update_config. The definition of
-both structures is available in [#f1]_.
-
-The update field in the structures tells whether to update the configuration
-for the specific function and the flag tells whether to enable or disable the
-function.
-
-The update and flag bit masks accept the following values. Each separate
-functions in the CCDC and preview blocks is associated with a flag (either
-disable or enable; part of the flag field in the structure) and a pointer to
-configuration data for the function.
-
-Valid values for the update and flag fields are listed here for
-VIDIOC_OMAP3ISP_CCDC_CFG. Values may be or'ed to configure more than one
-function in the same IOCTL call.
-
-- OMAP3ISP_CCDC_ALAW
-- OMAP3ISP_CCDC_LPF
-- OMAP3ISP_CCDC_BLCLAMP
-- OMAP3ISP_CCDC_BCOMP
-- OMAP3ISP_CCDC_FPC
-- OMAP3ISP_CCDC_CULL
-- OMAP3ISP_CCDC_CONFIG_LSC
-- OMAP3ISP_CCDC_TBL_LSC
-
-The corresponding values for the VIDIOC_OMAP3ISP_PRV_CFG are here:
-
-- OMAP3ISP_PREV_LUMAENH
-- OMAP3ISP_PREV_INVALAW
-- OMAP3ISP_PREV_HRZ_MED
-- OMAP3ISP_PREV_CFA
-- OMAP3ISP_PREV_CHROMA_SUPP
-- OMAP3ISP_PREV_WB
-- OMAP3ISP_PREV_BLKADJ
-- OMAP3ISP_PREV_RGB2RGB
-- OMAP3ISP_PREV_COLOR_CONV
-- OMAP3ISP_PREV_YC_LIMIT
-- OMAP3ISP_PREV_DEFECT_COR
-- OMAP3ISP_PREV_GAMMABYPASS
-- OMAP3ISP_PREV_DRK_FRM_CAPTURE
-- OMAP3ISP_PREV_DRK_FRM_SUBTRACT
-- OMAP3ISP_PREV_LENS_SHADING
-- OMAP3ISP_PREV_NF
-- OMAP3ISP_PREV_GAMMA
-
-The associated configuration pointer for the function may not be NULL when
-enabling the function. When disabling a function the configuration pointer is
-ignored.
-
-
-Statistic blocks IOCTLs
------------------------
-
-The statistics subdevs do offer more dynamic configuration options than the
-other subdevs. They can be enabled, disable and reconfigured when the pipeline
-is in streaming state.
-
-The statistics blocks always get the input image data from the CCDC (as the
-histogram memory read isn't implemented). The statistics are dequeueable by
-the user from the statistics subdev nodes using private IOCTLs.
-
-The private IOCTLs offered by the AEWB, AF and histogram subdevs are heavily
-reflected by the register level interface offered by the ISP hardware. There
-are aspects that are purely related to the driver implementation and these are
-discussed next.
-
-VIDIOC_OMAP3ISP_STAT_EN
------------------------
-
-This private IOCTL enables/disables a statistic module. If this request is
-done before streaming, it will take effect as soon as the pipeline starts to
-stream.  If the pipeline is already streaming, it will take effect as soon as
-the CCDC becomes idle.
-
-VIDIOC_OMAP3ISP_AEWB_CFG, VIDIOC_OMAP3ISP_HIST_CFG and VIDIOC_OMAP3ISP_AF_CFG
------------------------------------------------------------------------------
-
-Those IOCTLs are used to configure the modules. They require user applications
-to have an in-depth knowledge of the hardware. Most of the fields explanation
-can be found on OMAP's TRMs. The two following fields common to all the above
-configure private IOCTLs require explanation for better understanding as they
-are not part of the TRM.
-
-omap3isp_[h3a_af/h3a_aewb/hist]\_config.buf_size:
-
-The modules handle their buffers internally. The necessary buffer size for the
-module's data output depends on the requested configuration. Although the
-driver supports reconfiguration while streaming, it does not support a
-reconfiguration which requires bigger buffer size than what is already
-internally allocated if the module is enabled. It will return -EBUSY on this
-case. In order to avoid such condition, either disable/reconfigure/enable the
-module or request the necessary buffer size during the first configuration
-while the module is disabled.
-
-The internal buffer size allocation considers the requested configuration's
-minimum buffer size and the value set on buf_size field. If buf_size field is
-out of [minimum, maximum] buffer size range, it's clamped to fit in there.
-The driver then selects the biggest value. The corrected buf_size value is
-written back to user application.
-
-omap3isp_[h3a_af/h3a_aewb/hist]\_config.config_counter:
-
-As the configuration doesn't take effect synchronously to the request, the
-driver must provide a way to track this information to provide more accurate
-data. After a configuration is requested, the config_counter returned to user
-space application will be an unique value associated to that request. When
-user application receives an event for buffer availability or when a new
-buffer is requested, this config_counter is used to match a buffer data and a
-configuration.
-
-VIDIOC_OMAP3ISP_STAT_REQ
-------------------------
-
-Send to user space the oldest data available in the internal buffer queue and
-discards such buffer afterwards. The field omap3isp_stat_data.frame_number
-matches with the video buffer's field_count.
-
-
-Technical reference manuals (TRMs) and other documentation
-----------------------------------------------------------
-
-OMAP 3430 TRM:
-<URL:http://focus.ti.com/pdfs/wtbu/OMAP34xx_ES3.1.x_PUBLIC_TRM_vZM.zip>
-Referenced 2011-03-05.
-
-OMAP 35xx TRM:
-<URL:http://www.ti.com/litv/pdf/spruf98o> Referenced 2011-03-05.
-
-OMAP 3630 TRM:
-<URL:http://focus.ti.com/pdfs/wtbu/OMAP36xx_ES1.x_PUBLIC_TRM_vQ.zip>
-Referenced 2011-03-05.
-
-DM 3730 TRM:
-<URL:http://www.ti.com/litv/pdf/sprugn4h> Referenced 2011-03-06.
-
-
-References
-----------
-
-.. [#f1] include/linux/omap3isp.h
-
-.. [#f2] http://git.ideasonboard.org/?p=media-ctl.git;a=summary
diff --git a/Documentation/media/v4l-drivers/omap4_camera.rst b/Documentation/media/v4l-drivers/omap4_camera.rst
deleted file mode 100644
index 24db4222d36d..000000000000
--- a/Documentation/media/v4l-drivers/omap4_camera.rst
+++ /dev/null
@@ -1,62 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-OMAP4 ISS Driver
-================
-
-Author: Sergio Aguirre <sergio.a.aguirre@gmail.com>
-
-Copyright (C) 2012, Texas Instruments
-
-Introduction
-------------
-
-The OMAP44XX family of chips contains the Imaging SubSystem (a.k.a. ISS),
-Which contains several components that can be categorized in 3 big groups:
-
-- Interfaces (2 Interfaces: CSI2-A & CSI2-B/CCP2)
-- ISP (Image Signal Processor)
-- SIMCOP (Still Image Coprocessor)
-
-For more information, please look in [#f1]_ for latest version of:
-"OMAP4430 Multimedia Device Silicon Revision 2.x"
-
-As of Revision AB, the ISS is described in detail in section 8.
-
-This driver is supporting **only** the CSI2-A/B interfaces for now.
-
-It makes use of the Media Controller framework [#f2]_, and inherited most of the
-code from OMAP3 ISP driver (found under drivers/media/platform/omap3isp/\*),
-except that it doesn't need an IOMMU now for ISS buffers memory mapping.
-
-Supports usage of MMAP buffers only (for now).
-
-Tested platforms
-----------------
-
-- OMAP4430SDP, w/ ES2.1 GP & SEVM4430-CAM-V1-0 (Contains IMX060 & OV5640, in
-  which only the last one is supported, outputting YUV422 frames).
-
-- TI Blaze MDP, w/ OMAP4430 ES2.2 EMU (Contains 1 IMX060 & 2 OV5650 sensors, in
-  which only the OV5650 are supported, outputting RAW10 frames).
-
-- PandaBoard, Rev. A2, w/ OMAP4430 ES2.1 GP & OV adapter board, tested with
-  following sensors:
-  * OV5640
-  * OV5650
-
-- Tested on mainline kernel:
-
-	http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=summary
-
-  Tag: v3.3 (commit c16fa4f2ad19908a47c63d8fa436a1178438c7e7)
-
-File list
----------
-drivers/staging/media/omap4iss/
-include/linux/platform_data/media/omap4iss.h
-
-References
-----------
-
-.. [#f1] http://focus.ti.com/general/docs/wtbu/wtbudocumentcenter.tsp?navigationId=12037&templateId=6123#62
-.. [#f2] http://lwn.net/Articles/420485/
diff --git a/Documentation/media/v4l-drivers/philips.rst b/Documentation/media/v4l-drivers/philips.rst
deleted file mode 100644
index e2840be10d08..000000000000
--- a/Documentation/media/v4l-drivers/philips.rst
+++ /dev/null
@@ -1,247 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-Philips webcams (pwc driver)
-============================
-
-This file contains some additional information for the Philips and OEM webcams.
-E-mail: webcam@smcc.demon.nl                        Last updated: 2004-01-19
-Site: http://www.smcc.demon.nl/webcam/
-
-As of this moment, the following cameras are supported:
-
- * Philips PCA645
- * Philips PCA646
- * Philips PCVC675
- * Philips PCVC680
- * Philips PCVC690
- * Philips PCVC720/40
- * Philips PCVC730
- * Philips PCVC740
- * Philips PCVC750
- * Askey VC010
- * Creative Labs Webcam 5
- * Creative Labs Webcam Pro Ex
- * Logitech QuickCam 3000 Pro
- * Logitech QuickCam 4000 Pro
- * Logitech QuickCam Notebook Pro
- * Logitech QuickCam Zoom
- * Logitech QuickCam Orbit
- * Logitech QuickCam Sphere
- * Samsung MPC-C10
- * Samsung MPC-C30
- * Sotec Afina Eye
- * AME CU-001
- * Visionite VCS-UM100
- * Visionite VCS-UC300
-
-The main webpage for the Philips driver is at the address above. It contains
-a lot of extra information, a FAQ, and the binary plugin 'PWCX'. This plugin
-contains decompression routines that allow you to use higher image sizes and
-framerates; in addition the webcam uses less bandwidth on the USB bus (handy
-if you want to run more than 1 camera simultaneously). These routines fall
-under a NDA, and may therefore not be distributed as source; however, its use
-is completely optional.
-
-You can build this code either into your kernel, or as a module. I recommend
-the latter, since it makes troubleshooting a lot easier. The built-in
-microphone is supported through the USB Audio class.
-
-When you load the module you can set some default settings for the
-camera; some programs depend on a particular image-size or -format and
-don't know how to set it properly in the driver. The options are:
-
-size
-   Can be one of 'sqcif', 'qsif', 'qcif', 'sif', 'cif' or
-   'vga', for an image size of resp. 128x96, 160x120, 176x144,
-   320x240, 352x288 and 640x480 (of course, only for those cameras that
-   support these resolutions).
-
-fps
-   Specifies the desired framerate. Is an integer in the range of 4-30.
-
-fbufs
-   This parameter specifies the number of internal buffers to use for storing
-   frames from the cam. This will help if the process that reads images from
-   the cam is a bit slow or momentarily busy. However, on slow machines it
-   only introduces lag, so choose carefully. The default is 3, which is
-   reasonable. You can set it between 2 and 5.
-
-mbufs
-   This is an integer between 1 and 10. It will tell the module the number of
-   buffers to reserve for mmap(), VIDIOCCGMBUF, VIDIOCMCAPTURE and friends.
-   The default is 2, which is adequate for most applications (double
-   buffering).
-
-   Should you experience a lot of 'Dumping frame...' messages during
-   grabbing with a tool that uses mmap(), you might want to increase if.
-   However, it doesn't really buffer images, it just gives you a bit more
-   slack when your program is behind. But you need a multi-threaded or
-   forked program to really take advantage of these buffers.
-
-   The absolute maximum is 10, but don't set it too high!  Every buffer takes
-   up 460 KB of RAM, so unless you have a lot of memory setting this to
-   something more than 4 is an absolute waste.  This memory is only
-   allocated during open(), so nothing is wasted when the camera is not in
-   use.
-
-power_save
-   When power_save is enabled (set to 1), the module will try to shut down
-   the cam on close() and re-activate on open(). This will save power and
-   turn off the LED. Not all cameras support this though (the 645 and 646
-   don't have power saving at all), and some models don't work either (they
-   will shut down, but never wake up). Consider this experimental. By
-   default this option is disabled.
-
-compression (only useful with the plugin)
-   With this option you can control the compression factor that the camera
-   uses to squeeze the image through the USB bus. You can set the
-   parameter between 0 and 3::
-
-     0 = prefer uncompressed images; if the requested mode is not available
-	 in an uncompressed format, the driver will silently switch to low
-	 compression.
-     1 = low compression.
-     2 = medium compression.
-     3 = high compression.
-
-   High compression takes less bandwidth of course, but it could also
-   introduce some unwanted artefacts. The default is 2, medium compression.
-   See the FAQ on the website for an overview of which modes require
-   compression.
-
-   The compression parameter does not apply to the 645 and 646 cameras
-   and OEM models derived from those (only a few). Most cams honour this
-   parameter.
-
-leds
-   This settings takes 2 integers, that define the on/off time for the LED
-   (in milliseconds). One of the interesting things that you can do with
-   this is let the LED blink while the camera is in use. This::
-
-     leds=500,500
-
-   will blink the LED once every second. But with::
-
-     leds=0,0
-
-   the LED never goes on, making it suitable for silent surveillance.
-
-   By default the camera's LED is on solid while in use, and turned off
-   when the camera is not used anymore.
-
-   This parameter works only with the ToUCam range of cameras (720, 730, 740,
-   750) and OEMs. For other cameras this command is silently ignored, and
-   the LED cannot be controlled.
-
-   Finally: this parameters does not take effect UNTIL the first time you
-   open the camera device. Until then, the LED remains on.
-
-dev_hint
-   A long standing problem with USB devices is their dynamic nature: you
-   never know what device a camera gets assigned; it depends on module load
-   order, the hub configuration, the order in which devices are plugged in,
-   and the phase of the moon (i.e. it can be random). With this option you
-   can give the driver a hint as to what video device node (/dev/videoX) it
-   should use with a specific camera. This is also handy if you have two
-   cameras of the same model.
-
-   A camera is specified by its type (the number from the camera model,
-   like PCA645, PCVC750VC, etc) and optionally the serial number (visible
-   in /sys/kernel/debug/usb/devices). A hint consists of a string with the
-   following format::
-
-      [type[.serialnumber]:]node
-
-   The square brackets mean that both the type and the serialnumber are
-   optional, but a serialnumber cannot be specified without a type (which
-   would be rather pointless). The serialnumber is separated from the type
-   by a '.'; the node number by a ':'.
-
-   This somewhat cryptic syntax is best explained by a few examples::
-
-     dev_hint=3,5              The first detected cam gets assigned
-			       /dev/video3, the second /dev/video5. Any
-			       other cameras will get the first free
-			       available slot (see below).
-
-     dev_hint=645:1,680:2      The PCA645 camera will get /dev/video1,
-			       and a PCVC680 /dev/video2.
-
-     dev_hint=645.0123:3,645.4567:0	The PCA645 camera with serialnumber
-					0123 goes to /dev/video3, the same
-					camera model with the 4567 serial
-					gets /dev/video0.
-
-     dev_hint=750:1,4,5,6       The PCVC750 camera will get /dev/video1, the
-				next 3 Philips cams will use /dev/video4
-				through /dev/video6.
-
-   Some points worth knowing:
-
-   - Serialnumbers are case sensitive and must be written full, including
-     leading zeroes (it's treated as a string).
-   - If a device node is already occupied, registration will fail and
-     the webcam is not available.
-   - You can have up to 64 video devices; be sure to make enough device
-     nodes in /dev if you want to spread the numbers.
-     After /dev/video9 comes /dev/video10 (not /dev/videoA).
-   - If a camera does not match any dev_hint, it will simply get assigned
-     the first available device node, just as it used to be.
-
-trace
-   In order to better detect problems, it is now possible to turn on a
-   'trace' of some of the calls the module makes; it logs all items in your
-   kernel log at debug level.
-
-   The trace variable is a bitmask; each bit represents a certain feature.
-   If you want to trace something, look up the bit value(s) in the table
-   below, add the values together and supply that to the trace variable.
-
-   ====== ======= ================================================ =======
-   Value  Value   Description					   Default
-   (dec)  (hex)
-   ====== ======= ================================================ =======
-       1    0x1   Module initialization; this will log messages       On
-		  while loading and unloading the module
-
-       2    0x2   probe() and disconnect() traces                     On
-
-       4    0x4   Trace open() and close() calls                      Off
-
-       8    0x8   read(), mmap() and associated ioctl() calls         Off
-
-      16   0x10   Memory allocation of buffers, etc.                  Off
-
-      32   0x20   Showing underflow, overflow and Dumping frame       On
-		  messages
-
-      64   0x40   Show viewport and image sizes                       Off
-
-     128   0x80   PWCX debugging                                      Off
-   ====== ======= ================================================ =======
-
-   For example, to trace the open() & read() functions, sum 8 + 4 = 12,
-   so you would supply trace=12 during insmod or modprobe. If
-   you want to turn the initialization and probing tracing off, set trace=0.
-   The default value for trace is 35 (0x23).
-
-
-
-Example::
-
-     # modprobe pwc size=cif fps=15 power_save=1
-
-The fbufs, mbufs and trace parameters are global and apply to all connected
-cameras. Each camera has its own set of buffers.
-
-size and fps only specify defaults when you open() the device; this is to
-accommodate some tools that don't set the size. You can change these
-settings after open() with the Video4Linux ioctl() calls. The default of
-defaults is QCIF size at 10 fps.
-
-The compression parameter is semiglobal; it sets the initial compression
-preference for all camera's, but this parameter can be set per camera with
-the VIDIOCPWCSCQUAL ioctl() call.
-
-All parameters are optional.
-
diff --git a/Documentation/media/v4l-drivers/pvrusb2.rst b/Documentation/media/v4l-drivers/pvrusb2.rst
deleted file mode 100644
index 83bfaa531ea8..000000000000
--- a/Documentation/media/v4l-drivers/pvrusb2.rst
+++ /dev/null
@@ -1,202 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-The pvrusb2 driver
-==================
-
-Author: Mike Isely <isely@pobox.com>
-
-Background
-----------
-
-This driver is intended for the "Hauppauge WinTV PVR USB 2.0", which
-is a USB 2.0 hosted TV Tuner.  This driver is a work in progress.
-Its history started with the reverse-engineering effort by Björn
-Danielsson <pvrusb2@dax.nu> whose web page can be found here:
-http://pvrusb2.dax.nu/
-
-From there Aurelien Alleaume <slts@free.fr> began an effort to
-create a video4linux compatible driver.  I began with Aurelien's
-last known snapshot and evolved the driver to the state it is in
-here.
-
-More information on this driver can be found at:
-http://www.isely.net/pvrusb2.html
-
-
-This driver has a strong separation of layers.  They are very
-roughly:
-
-1. Low level wire-protocol implementation with the device.
-
-2. I2C adaptor implementation and corresponding I2C client drivers
-   implemented elsewhere in V4L.
-
-3. High level hardware driver implementation which coordinates all
-   activities that ensure correct operation of the device.
-
-4. A "context" layer which manages instancing of driver, setup,
-   tear-down, arbitration, and interaction with high level
-   interfaces appropriately as devices are hotplugged in the
-   system.
-
-5. High level interfaces which glue the driver to various published
-   Linux APIs (V4L, sysfs, maybe DVB in the future).
-
-The most important shearing layer is between the top 2 layers.  A
-lot of work went into the driver to ensure that any kind of
-conceivable API can be laid on top of the core driver.  (Yes, the
-driver internally leverages V4L to do its work but that really has
-nothing to do with the API published by the driver to the outside
-world.)  The architecture allows for different APIs to
-simultaneously access the driver.  I have a strong sense of fairness
-about APIs and also feel that it is a good design principle to keep
-implementation and interface isolated from each other.  Thus while
-right now the V4L high level interface is the most complete, the
-sysfs high level interface will work equally well for similar
-functions, and there's no reason I see right now why it shouldn't be
-possible to produce a DVB high level interface that can sit right
-alongside V4L.
-
-Building
---------
-
-To build these modules essentially amounts to just running "Make",
-but you need the kernel source tree nearby and you will likely also
-want to set a few controlling environment variables first in order
-to link things up with that source tree.  Please see the Makefile
-here for comments that explain how to do that.
-
-Source file list / functional overview
---------------------------------------
-
-(Note: The term "module" used below generally refers to loosely
-defined functional units within the pvrusb2 driver and bears no
-relation to the Linux kernel's concept of a loadable module.)
-
-pvrusb2-audio.[ch] - This is glue logic that resides between this
-    driver and the msp3400.ko I2C client driver (which is found
-    elsewhere in V4L).
-
-pvrusb2-context.[ch] - This module implements the context for an
-    instance of the driver.  Everything else eventually ties back to
-    or is otherwise instanced within the data structures implemented
-    here.  Hotplugging is ultimately coordinated here.  All high level
-    interfaces tie into the driver through this module.  This module
-    helps arbitrate each interface's access to the actual driver core,
-    and is designed to allow concurrent access through multiple
-    instances of multiple interfaces (thus you can for example change
-    the tuner's frequency through sysfs while simultaneously streaming
-    video through V4L out to an instance of mplayer).
-
-pvrusb2-debug.h - This header defines a printk() wrapper and a mask
-    of debugging bit definitions for the various kinds of debug
-    messages that can be enabled within the driver.
-
-pvrusb2-debugifc.[ch] - This module implements a crude command line
-    oriented debug interface into the driver.  Aside from being part
-    of the process for implementing manual firmware extraction (see
-    the pvrusb2 web site mentioned earlier), probably I'm the only one
-    who has ever used this.  It is mainly a debugging aid.
-
-pvrusb2-eeprom.[ch] - This is glue logic that resides between this
-    driver the tveeprom.ko module, which is itself implemented
-    elsewhere in V4L.
-
-pvrusb2-encoder.[ch] - This module implements all protocol needed to
-    interact with the Conexant mpeg2 encoder chip within the pvrusb2
-    device.  It is a crude echo of corresponding logic in ivtv,
-    however the design goals (strict isolation) and physical layer
-    (proxy through USB instead of PCI) are enough different that this
-    implementation had to be completely different.
-
-pvrusb2-hdw-internal.h - This header defines the core data structure
-    in the driver used to track ALL internal state related to control
-    of the hardware.  Nobody outside of the core hardware-handling
-    modules should have any business using this header.  All external
-    access to the driver should be through one of the high level
-    interfaces (e.g. V4L, sysfs, etc), and in fact even those high
-    level interfaces are restricted to the API defined in
-    pvrusb2-hdw.h and NOT this header.
-
-pvrusb2-hdw.h - This header defines the full internal API for
-    controlling the hardware.  High level interfaces (e.g. V4L, sysfs)
-    will work through here.
-
-pvrusb2-hdw.c - This module implements all the various bits of logic
-    that handle overall control of a specific pvrusb2 device.
-    (Policy, instantiation, and arbitration of pvrusb2 devices fall
-    within the jurisdiction of pvrusb-context not here).
-
-pvrusb2-i2c-chips-\*.c - These modules implement the glue logic to
-    tie together and configure various I2C modules as they attach to
-    the I2C bus.  There are two versions of this file.  The "v4l2"
-    version is intended to be used in-tree alongside V4L, where we
-    implement just the logic that makes sense for a pure V4L
-    environment.  The "all" version is intended for use outside of
-    V4L, where we might encounter other possibly "challenging" modules
-    from ivtv or older kernel snapshots (or even the support modules
-    in the standalone snapshot).
-
-pvrusb2-i2c-cmd-v4l1.[ch] - This module implements generic V4L1
-    compatible commands to the I2C modules.  It is here where state
-    changes inside the pvrusb2 driver are translated into V4L1
-    commands that are in turn send to the various I2C modules.
-
-pvrusb2-i2c-cmd-v4l2.[ch] - This module implements generic V4L2
-    compatible commands to the I2C modules.  It is here where state
-    changes inside the pvrusb2 driver are translated into V4L2
-    commands that are in turn send to the various I2C modules.
-
-pvrusb2-i2c-core.[ch] - This module provides an implementation of a
-    kernel-friendly I2C adaptor driver, through which other external
-    I2C client drivers (e.g. msp3400, tuner, lirc) may connect and
-    operate corresponding chips within the pvrusb2 device.  It is
-    through here that other V4L modules can reach into this driver to
-    operate specific pieces (and those modules are in turn driven by
-    glue logic which is coordinated by pvrusb2-hdw, doled out by
-    pvrusb2-context, and then ultimately made available to users
-    through one of the high level interfaces).
-
-pvrusb2-io.[ch] - This module implements a very low level ring of
-    transfer buffers, required in order to stream data from the
-    device.  This module is *very* low level.  It only operates the
-    buffers and makes no attempt to define any policy or mechanism for
-    how such buffers might be used.
-
-pvrusb2-ioread.[ch] - This module layers on top of pvrusb2-io.[ch]
-    to provide a streaming API usable by a read() system call style of
-    I/O.  Right now this is the only layer on top of pvrusb2-io.[ch],
-    however the underlying architecture here was intended to allow for
-    other styles of I/O to be implemented with additional modules, like
-    mmap()'ed buffers or something even more exotic.
-
-pvrusb2-main.c - This is the top level of the driver.  Module level
-    and USB core entry points are here.  This is our "main".
-
-pvrusb2-sysfs.[ch] - This is the high level interface which ties the
-    pvrusb2 driver into sysfs.  Through this interface you can do
-    everything with the driver except actually stream data.
-
-pvrusb2-tuner.[ch] - This is glue logic that resides between this
-    driver and the tuner.ko I2C client driver (which is found
-    elsewhere in V4L).
-
-pvrusb2-util.h - This header defines some common macros used
-    throughout the driver.  These macros are not really specific to
-    the driver, but they had to go somewhere.
-
-pvrusb2-v4l2.[ch] - This is the high level interface which ties the
-    pvrusb2 driver into video4linux.  It is through here that V4L
-    applications can open and operate the driver in the usual V4L
-    ways.  Note that **ALL** V4L functionality is published only
-    through here and nowhere else.
-
-pvrusb2-video-\*.[ch] - This is glue logic that resides between this
-    driver and the saa711x.ko I2C client driver (which is found
-    elsewhere in V4L).  Note that saa711x.ko used to be known as
-    saa7115.ko in ivtv.  There are two versions of this; one is
-    selected depending on the particular saa711[5x].ko that is found.
-
-pvrusb2.h - This header contains compile time tunable parameters
-    (and at the moment the driver has very little that needs to be
-    tuned).
diff --git a/Documentation/media/v4l-drivers/pxa_camera.rst b/Documentation/media/v4l-drivers/pxa_camera.rst
deleted file mode 100644
index ee1bd96b66dd..000000000000
--- a/Documentation/media/v4l-drivers/pxa_camera.rst
+++ /dev/null
@@ -1,194 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-PXA-Camera Host Driver
-======================
-
-Author: Robert Jarzmik <robert.jarzmik@free.fr>
-
-Constraints
------------
-
-a) Image size for YUV422P format
-   All YUV422P images are enforced to have width x height % 16 = 0.
-   This is due to DMA constraints, which transfers only planes of 8 byte
-   multiples.
-
-
-Global video workflow
----------------------
-
-a) QCI stopped
-   Initially, the QCI interface is stopped.
-   When a buffer is queued (pxa_videobuf_ops->buf_queue), the QCI starts.
-
-b) QCI started
-   More buffers can be queued while the QCI is started without halting the
-   capture.  The new buffers are "appended" at the tail of the DMA chain, and
-   smoothly captured one frame after the other.
-
-   Once a buffer is filled in the QCI interface, it is marked as "DONE" and
-   removed from the active buffers list. It can be then requeud or dequeued by
-   userland application.
-
-   Once the last buffer is filled in, the QCI interface stops.
-
-c) Capture global finite state machine schema
-
-.. code-block:: none
-
-	+----+                             +---+  +----+
-	| DQ |                             | Q |  | DQ |
-	|    v                             |   v  |    v
-	+-----------+                     +------------------------+
-	|   STOP    |                     | Wait for capture start |
-	+-----------+         Q           +------------------------+
-	+-> | QCI: stop | ------------------> | QCI: run               | <------------+
-	|   | DMA: stop |                     | DMA: stop              |              |
-	|   +-----------+             +-----> +------------------------+              |
-	|                            /                            |                   |
-	|                           /             +---+  +----+   |                   |
-	|capture list empty        /              | Q |  | DQ |   | QCI Irq EOF       |
-	|                         /               |   v  |    v   v                   |
-	|   +--------------------+             +----------------------+               |
-	|   | DMA hotlink missed |             |    Capture running   |               |
-	|   +--------------------+             +----------------------+               |
-	|   | QCI: run           |     +-----> | QCI: run             | <-+           |
-	|   | DMA: stop          |    /        | DMA: run             |   |           |
-	|   +--------------------+   /         +----------------------+   | Other     |
-	|     ^                     /DMA still            |               | channels  |
-	|     | capture list       /  running             | DMA Irq End   | not       |
-	|     | not empty         /                       |               | finished  |
-	|     |                  /                        v               | yet       |
-	|   +----------------------+           +----------------------+   |           |
-	|   |  Videobuf released   |           |  Channel completed   |   |           |
-	|   +----------------------+           +----------------------+   |           |
-	+-- | QCI: run             |           | QCI: run             | --+           |
-	| DMA: run             |           | DMA: run             |               |
-	+----------------------+           +----------------------+               |
-		^                      /           |                           |
-		|          no overrun /            | overrun                   |
-		|                    /             v                           |
-	+--------------------+         /   +----------------------+               |
-	|  Frame completed   |        /    |     Frame overran    |               |
-	+--------------------+ <-----+     +----------------------+ restart frame |
-	| QCI: run           |             | QCI: stop            | --------------+
-	| DMA: run           |             | DMA: stop            |
-	+--------------------+             +----------------------+
-
-	Legend: - each box is a FSM state
-		- each arrow is the condition to transition to another state
-		- an arrow with a comment is a mandatory transition (no condition)
-		- arrow "Q" means : a buffer was enqueued
-		- arrow "DQ" means : a buffer was dequeued
-		- "QCI: stop" means the QCI interface is not enabled
-		- "DMA: stop" means all 3 DMA channels are stopped
-		- "DMA: run" means at least 1 DMA channel is still running
-
-DMA usage
----------
-
-a) DMA flow
-     - first buffer queued for capture
-       Once a first buffer is queued for capture, the QCI is started, but data
-       transfer is not started. On "End Of Frame" interrupt, the irq handler
-       starts the DMA chain.
-     - capture of one videobuffer
-       The DMA chain starts transferring data into videobuffer RAM pages.
-       When all pages are transferred, the DMA irq is raised on "ENDINTR" status
-     - finishing one videobuffer
-       The DMA irq handler marks the videobuffer as "done", and removes it from
-       the active running queue
-       Meanwhile, the next videobuffer (if there is one), is transferred by DMA
-     - finishing the last videobuffer
-       On the DMA irq of the last videobuffer, the QCI is stopped.
-
-b) DMA prepared buffer will have this structure
-
-.. code-block:: none
-
-     +------------+-----+---------------+-----------------+
-     | desc-sg[0] | ... | desc-sg[last] | finisher/linker |
-     +------------+-----+---------------+-----------------+
-
-This structure is pointed by dma->sg_cpu.
-The descriptors are used as follows:
-
-- desc-sg[i]: i-th descriptor, transferring the i-th sg
-  element to the video buffer scatter gather
-- finisher: has ddadr=DADDR_STOP, dcmd=ENDIRQEN
-- linker: has ddadr= desc-sg[0] of next video buffer, dcmd=0
-
-For the next schema, let's assume d0=desc-sg[0] .. dN=desc-sg[N],
-"f" stands for finisher and "l" for linker.
-A typical running chain is :
-
-.. code-block:: none
-
-         Videobuffer 1         Videobuffer 2
-     +---------+----+---+  +----+----+----+---+
-     | d0 | .. | dN | l |  | d0 | .. | dN | f |
-     +---------+----+-|-+  ^----+----+----+---+
-                      |    |
-                      +----+
-
-After the chaining is finished, the chain looks like :
-
-.. code-block:: none
-
-         Videobuffer 1         Videobuffer 2         Videobuffer 3
-     +---------+----+---+  +----+----+----+---+  +----+----+----+---+
-     | d0 | .. | dN | l |  | d0 | .. | dN | l |  | d0 | .. | dN | f |
-     +---------+----+-|-+  ^----+----+----+-|-+  ^----+----+----+---+
-                      |    |                |    |
-                      +----+                +----+
-                                           new_link
-
-c) DMA hot chaining timeslice issue
-
-As DMA chaining is done while DMA _is_ running, the linking may be done
-while the DMA jumps from one Videobuffer to another. On the schema, that
-would be a problem if the following sequence is encountered :
-
-- DMA chain is Videobuffer1 + Videobuffer2
-- pxa_videobuf_queue() is called to queue Videobuffer3
-- DMA controller finishes Videobuffer2, and DMA stops
-
-.. code-block:: none
-
-      =>
-         Videobuffer 1         Videobuffer 2
-     +---------+----+---+  +----+----+----+---+
-     | d0 | .. | dN | l |  | d0 | .. | dN | f |
-     +---------+----+-|-+  ^----+----+----+-^-+
-                      |    |                |
-                      +----+                +-- DMA DDADR loads DDADR_STOP
-
-- pxa_dma_add_tail_buf() is called, the Videobuffer2 "finisher" is
-  replaced by a "linker" to Videobuffer3 (creation of new_link)
-- pxa_videobuf_queue() finishes
-- the DMA irq handler is called, which terminates Videobuffer2
-- Videobuffer3 capture is not scheduled on DMA chain (as it stopped !!!)
-
-.. code-block:: none
-
-         Videobuffer 1         Videobuffer 2         Videobuffer 3
-     +---------+----+---+  +----+----+----+---+  +----+----+----+---+
-     | d0 | .. | dN | l |  | d0 | .. | dN | l |  | d0 | .. | dN | f |
-     +---------+----+-|-+  ^----+----+----+-|-+  ^----+----+----+---+
-                      |    |                |    |
-                      +----+                +----+
-                                           new_link
-                                          DMA DDADR still is DDADR_STOP
-
-- pxa_camera_check_link_miss() is called
-  This checks if the DMA is finished and a buffer is still on the
-  pcdev->capture list. If that's the case, the capture will be restarted,
-  and Videobuffer3 is scheduled on DMA chain.
-- the DMA irq handler finishes
-
-.. note::
-
-     If DMA stops just after pxa_camera_check_link_miss() reads DDADR()
-     value, we have the guarantee that the DMA irq handler will be called back
-     when the DMA will finish the buffer, and pxa_camera_check_link_miss() will
-     be called again, to reschedule Videobuffer3.
diff --git a/Documentation/media/v4l-drivers/qcom_camss.rst b/Documentation/media/v4l-drivers/qcom_camss.rst
deleted file mode 100644
index a72e17d09cb7..000000000000
--- a/Documentation/media/v4l-drivers/qcom_camss.rst
+++ /dev/null
@@ -1,185 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-.. include:: <isonum.txt>
-
-Qualcomm Camera Subsystem driver
-================================
-
-Introduction
-------------
-
-This file documents the Qualcomm Camera Subsystem driver located under
-drivers/media/platform/qcom/camss.
-
-The current version of the driver supports the Camera Subsystem found on
-Qualcomm MSM8916/APQ8016 and MSM8996/APQ8096 processors.
-
-The driver implements V4L2, Media controller and V4L2 subdev interfaces.
-Camera sensor using V4L2 subdev interface in the kernel is supported.
-
-The driver is implemented using as a reference the Qualcomm Camera Subsystem
-driver for Android as found in Code Aurora [#f1]_ [#f2]_.
-
-
-Qualcomm Camera Subsystem hardware
-----------------------------------
-
-The Camera Subsystem hardware found on 8x16 / 8x96 processors and supported by
-the driver consists of:
-
-- 2 / 3 CSIPHY modules. They handle the Physical layer of the CSI2 receivers.
-  A separate camera sensor can be connected to each of the CSIPHY module;
-- 2 / 4 CSID (CSI Decoder) modules. They handle the Protocol and Application
-  layer of the CSI2 receivers. A CSID can decode data stream from any of the
-  CSIPHY. Each CSID also contains a TG (Test Generator) block which can generate
-  artificial input data for test purposes;
-- ISPIF (ISP Interface) module. Handles the routing of the data streams from
-  the CSIDs to the inputs of the VFE;
-- 1 / 2 VFE (Video Front End) module(s). Contain a pipeline of image processing
-  hardware blocks. The VFE has different input interfaces. The PIX (Pixel) input
-  interface feeds the input data to the image processing pipeline. The image
-  processing pipeline contains also a scale and crop module at the end. Three
-  RDI (Raw Dump Interface) input interfaces bypass the image processing
-  pipeline. The VFE also contains the AXI bus interface which writes the output
-  data to memory.
-
-
-Supported functionality
------------------------
-
-The current version of the driver supports:
-
-- Input from camera sensor via CSIPHY;
-- Generation of test input data by the TG in CSID;
-- RDI interface of VFE
-
-  - Raw dump of the input data to memory.
-
-    Supported formats:
-
-    - YUYV/UYVY/YVYU/VYUY (packed YUV 4:2:2 - V4L2_PIX_FMT_YUYV /
-      V4L2_PIX_FMT_UYVY / V4L2_PIX_FMT_YVYU / V4L2_PIX_FMT_VYUY);
-    - MIPI RAW8 (8bit Bayer RAW - V4L2_PIX_FMT_SRGGB8 /
-      V4L2_PIX_FMT_SGRBG8 / V4L2_PIX_FMT_SGBRG8 / V4L2_PIX_FMT_SBGGR8);
-    - MIPI RAW10 (10bit packed Bayer RAW - V4L2_PIX_FMT_SBGGR10P /
-      V4L2_PIX_FMT_SGBRG10P / V4L2_PIX_FMT_SGRBG10P / V4L2_PIX_FMT_SRGGB10P /
-      V4L2_PIX_FMT_Y10P);
-    - MIPI RAW12 (12bit packed Bayer RAW - V4L2_PIX_FMT_SRGGB12P /
-      V4L2_PIX_FMT_SGBRG12P / V4L2_PIX_FMT_SGRBG12P / V4L2_PIX_FMT_SRGGB12P).
-    - (8x96 only) MIPI RAW14 (14bit packed Bayer RAW - V4L2_PIX_FMT_SRGGB14P /
-      V4L2_PIX_FMT_SGBRG14P / V4L2_PIX_FMT_SGRBG14P / V4L2_PIX_FMT_SRGGB14P).
-
-  - (8x96 only) Format conversion of the input data.
-
-    Supported input formats:
-
-    - MIPI RAW10 (10bit packed Bayer RAW - V4L2_PIX_FMT_SBGGR10P / V4L2_PIX_FMT_Y10P).
-
-    Supported output formats:
-
-    - Plain16 RAW10 (10bit unpacked Bayer RAW - V4L2_PIX_FMT_SBGGR10 / V4L2_PIX_FMT_Y10).
-
-- PIX interface of VFE
-
-  - Format conversion of the input data.
-
-    Supported input formats:
-
-    - YUYV/UYVY/YVYU/VYUY (packed YUV 4:2:2 - V4L2_PIX_FMT_YUYV /
-      V4L2_PIX_FMT_UYVY / V4L2_PIX_FMT_YVYU / V4L2_PIX_FMT_VYUY).
-
-    Supported output formats:
-
-    - NV12/NV21 (two plane YUV 4:2:0 - V4L2_PIX_FMT_NV12 / V4L2_PIX_FMT_NV21);
-    - NV16/NV61 (two plane YUV 4:2:2 - V4L2_PIX_FMT_NV16 / V4L2_PIX_FMT_NV61).
-    - (8x96 only) YUYV/UYVY/YVYU/VYUY (packed YUV 4:2:2 - V4L2_PIX_FMT_YUYV /
-      V4L2_PIX_FMT_UYVY / V4L2_PIX_FMT_YVYU / V4L2_PIX_FMT_VYUY).
-
-  - Scaling support. Configuration of the VFE Encoder Scale module
-    for downscalling with ratio up to 16x.
-
-  - Cropping support. Configuration of the VFE Encoder Crop module.
-
-- Concurrent and independent usage of two (8x96: three) data inputs -
-  could be camera sensors and/or TG.
-
-
-Driver Architecture and Design
-------------------------------
-
-The driver implements the V4L2 subdev interface. With the goal to model the
-hardware links between the modules and to expose a clean, logical and usable
-interface, the driver is split into V4L2 sub-devices as follows (8x16 / 8x96):
-
-- 2 / 3 CSIPHY sub-devices - each CSIPHY is represented by a single sub-device;
-- 2 / 4 CSID sub-devices - each CSID is represented by a single sub-device;
-- 2 / 4 ISPIF sub-devices - ISPIF is represented by a number of sub-devices
-  equal to the number of CSID sub-devices;
-- 4 / 8 VFE sub-devices - VFE is represented by a number of sub-devices equal to
-  the number of the input interfaces (3 RDI and 1 PIX for each VFE).
-
-The considerations to split the driver in this particular way are as follows:
-
-- representing CSIPHY and CSID modules by a separate sub-device for each module
-  allows to model the hardware links between these modules;
-- representing VFE by a separate sub-devices for each input interface allows
-  to use the input interfaces concurrently and independently as this is
-  supported by the hardware;
-- representing ISPIF by a number of sub-devices equal to the number of CSID
-  sub-devices allows to create linear media controller pipelines when using two
-  cameras simultaneously. This avoids branches in the pipelines which otherwise
-  will require a) userspace and b) media framework (e.g. power on/off
-  operations) to  make assumptions about the data flow from a sink pad to a
-  source pad on a single media entity.
-
-Each VFE sub-device is linked to a separate video device node.
-
-The media controller pipeline graph is as follows (with connected two / three
-OV5645 camera sensors):
-
-.. _qcom_camss_graph:
-
-.. kernel-figure:: qcom_camss_graph.dot
-    :alt:   qcom_camss_graph.dot
-    :align: center
-
-    Media pipeline graph 8x16
-
-.. kernel-figure:: qcom_camss_8x96_graph.dot
-    :alt:   qcom_camss_8x96_graph.dot
-    :align: center
-
-    Media pipeline graph 8x96
-
-
-Implementation
---------------
-
-Runtime configuration of the hardware (updating settings while streaming) is
-not required to implement the currently supported functionality. The complete
-configuration on each hardware module is applied on STREAMON ioctl based on
-the current active media links, formats and controls set.
-
-The output size of the scaler module in the VFE is configured with the actual
-compose selection rectangle on the sink pad of the 'msm_vfe0_pix' entity.
-
-The crop output area of the crop module in the VFE is configured with the actual
-crop selection rectangle on the source pad of the 'msm_vfe0_pix' entity.
-
-
-Documentation
--------------
-
-APQ8016 Specification:
-https://developer.qualcomm.com/download/sd410/snapdragon-410-processor-device-specification.pdf
-Referenced 2016-11-24.
-
-APQ8096 Specification:
-https://developer.qualcomm.com/download/sd820e/qualcomm-snapdragon-820e-processor-apq8096sge-device-specification.pdf
-Referenced 2018-06-22.
-
-References
-----------
-
-.. [#f1] https://source.codeaurora.org/quic/la/kernel/msm-3.10/
-.. [#f2] https://source.codeaurora.org/quic/la/kernel/msm-3.18/
diff --git a/Documentation/media/v4l-drivers/qcom_camss_8x96_graph.dot b/Documentation/media/v4l-drivers/qcom_camss_8x96_graph.dot
deleted file mode 100644
index 7ed243b41b67..000000000000
--- a/Documentation/media/v4l-drivers/qcom_camss_8x96_graph.dot
+++ /dev/null
@@ -1,106 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-digraph board {
-	rankdir=TB
-	n00000001 [label="{{<port0> 0} | msm_csiphy0\n/dev/v4l-subdev0 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
-	n00000001:port1 -> n0000000a:port0 [style=dashed]
-	n00000001:port1 -> n0000000d:port0 [style=dashed]
-	n00000001:port1 -> n00000010:port0 [style=dashed]
-	n00000001:port1 -> n00000013:port0 [style=dashed]
-	n00000004 [label="{{<port0> 0} | msm_csiphy1\n/dev/v4l-subdev1 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
-	n00000004:port1 -> n0000000a:port0 [style=dashed]
-	n00000004:port1 -> n0000000d:port0 [style=dashed]
-	n00000004:port1 -> n00000010:port0 [style=dashed]
-	n00000004:port1 -> n00000013:port0 [style=dashed]
-	n00000007 [label="{{<port0> 0} | msm_csiphy2\n/dev/v4l-subdev2 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
-	n00000007:port1 -> n0000000a:port0 [style=dashed]
-	n00000007:port1 -> n0000000d:port0 [style=dashed]
-	n00000007:port1 -> n00000010:port0 [style=dashed]
-	n00000007:port1 -> n00000013:port0 [style=dashed]
-	n0000000a [label="{{<port0> 0} | msm_csid0\n/dev/v4l-subdev3 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
-	n0000000a:port1 -> n00000016:port0 [style=dashed]
-	n0000000a:port1 -> n00000019:port0 [style=dashed]
-	n0000000a:port1 -> n0000001c:port0 [style=dashed]
-	n0000000a:port1 -> n0000001f:port0 [style=dashed]
-	n0000000d [label="{{<port0> 0} | msm_csid1\n/dev/v4l-subdev4 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
-	n0000000d:port1 -> n00000016:port0 [style=dashed]
-	n0000000d:port1 -> n00000019:port0 [style=dashed]
-	n0000000d:port1 -> n0000001c:port0 [style=dashed]
-	n0000000d:port1 -> n0000001f:port0 [style=dashed]
-	n00000010 [label="{{<port0> 0} | msm_csid2\n/dev/v4l-subdev5 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
-	n00000010:port1 -> n00000016:port0 [style=dashed]
-	n00000010:port1 -> n00000019:port0 [style=dashed]
-	n00000010:port1 -> n0000001c:port0 [style=dashed]
-	n00000010:port1 -> n0000001f:port0 [style=dashed]
-	n00000013 [label="{{<port0> 0} | msm_csid3\n/dev/v4l-subdev6 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
-	n00000013:port1 -> n00000016:port0 [style=dashed]
-	n00000013:port1 -> n00000019:port0 [style=dashed]
-	n00000013:port1 -> n0000001c:port0 [style=dashed]
-	n00000013:port1 -> n0000001f:port0 [style=dashed]
-	n00000016 [label="{{<port0> 0} | msm_ispif0\n/dev/v4l-subdev7 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
-	n00000016:port1 -> n00000022:port0 [style=dashed]
-	n00000016:port1 -> n0000002b:port0 [style=dashed]
-	n00000016:port1 -> n00000034:port0 [style=dashed]
-	n00000016:port1 -> n0000003d:port0 [style=dashed]
-	n00000016:port1 -> n00000046:port0 [style=dashed]
-	n00000016:port1 -> n0000004f:port0 [style=dashed]
-	n00000016:port1 -> n00000058:port0 [style=dashed]
-	n00000016:port1 -> n00000061:port0 [style=dashed]
-	n00000019 [label="{{<port0> 0} | msm_ispif1\n/dev/v4l-subdev8 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
-	n00000019:port1 -> n00000022:port0 [style=dashed]
-	n00000019:port1 -> n0000002b:port0 [style=dashed]
-	n00000019:port1 -> n00000034:port0 [style=dashed]
-	n00000019:port1 -> n0000003d:port0 [style=dashed]
-	n00000019:port1 -> n00000046:port0 [style=dashed]
-	n00000019:port1 -> n0000004f:port0 [style=dashed]
-	n00000019:port1 -> n00000058:port0 [style=dashed]
-	n00000019:port1 -> n00000061:port0 [style=dashed]
-	n0000001c [label="{{<port0> 0} | msm_ispif2\n/dev/v4l-subdev9 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
-	n0000001c:port1 -> n00000022:port0 [style=dashed]
-	n0000001c:port1 -> n0000002b:port0 [style=dashed]
-	n0000001c:port1 -> n00000034:port0 [style=dashed]
-	n0000001c:port1 -> n0000003d:port0 [style=dashed]
-	n0000001c:port1 -> n00000046:port0 [style=dashed]
-	n0000001c:port1 -> n0000004f:port0 [style=dashed]
-	n0000001c:port1 -> n00000058:port0 [style=dashed]
-	n0000001c:port1 -> n00000061:port0 [style=dashed]
-	n0000001f [label="{{<port0> 0} | msm_ispif3\n/dev/v4l-subdev10 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
-	n0000001f:port1 -> n00000022:port0 [style=dashed]
-	n0000001f:port1 -> n0000002b:port0 [style=dashed]
-	n0000001f:port1 -> n00000034:port0 [style=dashed]
-	n0000001f:port1 -> n0000003d:port0 [style=dashed]
-	n0000001f:port1 -> n00000046:port0 [style=dashed]
-	n0000001f:port1 -> n0000004f:port0 [style=dashed]
-	n0000001f:port1 -> n00000058:port0 [style=dashed]
-	n0000001f:port1 -> n00000061:port0 [style=dashed]
-	n00000022 [label="{{<port0> 0} | msm_vfe0_rdi0\n/dev/v4l-subdev11 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
-	n00000022:port1 -> n00000025 [style=bold]
-	n00000025 [label="msm_vfe0_video0\n/dev/video0", shape=box, style=filled, fillcolor=yellow]
-	n0000002b [label="{{<port0> 0} | msm_vfe0_rdi1\n/dev/v4l-subdev12 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
-	n0000002b:port1 -> n0000002e [style=bold]
-	n0000002e [label="msm_vfe0_video1\n/dev/video1", shape=box, style=filled, fillcolor=yellow]
-	n00000034 [label="{{<port0> 0} | msm_vfe0_rdi2\n/dev/v4l-subdev13 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
-	n00000034:port1 -> n00000037 [style=bold]
-	n00000037 [label="msm_vfe0_video2\n/dev/video2", shape=box, style=filled, fillcolor=yellow]
-	n0000003d [label="{{<port0> 0} | msm_vfe0_pix\n/dev/v4l-subdev14 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
-	n0000003d:port1 -> n00000040 [style=bold]
-	n00000040 [label="msm_vfe0_video3\n/dev/video3", shape=box, style=filled, fillcolor=yellow]
-	n00000046 [label="{{<port0> 0} | msm_vfe1_rdi0\n/dev/v4l-subdev15 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
-	n00000046:port1 -> n00000049 [style=bold]
-	n00000049 [label="msm_vfe1_video0\n/dev/video4", shape=box, style=filled, fillcolor=yellow]
-	n0000004f [label="{{<port0> 0} | msm_vfe1_rdi1\n/dev/v4l-subdev16 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
-	n0000004f:port1 -> n00000052 [style=bold]
-	n00000052 [label="msm_vfe1_video1\n/dev/video5", shape=box, style=filled, fillcolor=yellow]
-	n00000058 [label="{{<port0> 0} | msm_vfe1_rdi2\n/dev/v4l-subdev17 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
-	n00000058:port1 -> n0000005b [style=bold]
-	n0000005b [label="msm_vfe1_video2\n/dev/video6", shape=box, style=filled, fillcolor=yellow]
-	n00000061 [label="{{<port0> 0} | msm_vfe1_pix\n/dev/v4l-subdev18 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
-	n00000061:port1 -> n00000064 [style=bold]
-	n00000064 [label="msm_vfe1_video3\n/dev/video7", shape=box, style=filled, fillcolor=yellow]
-	n000000e2 [label="{{} | ov5645 3-0039\n/dev/v4l-subdev19 | {<port0> 0}}", shape=Mrecord, style=filled, fillcolor=green]
-	n000000e2:port0 -> n00000004:port0 [style=bold]
-	n000000e4 [label="{{} | ov5645 3-003a\n/dev/v4l-subdev20 | {<port0> 0}}", shape=Mrecord, style=filled, fillcolor=green]
-	n000000e4:port0 -> n00000007:port0 [style=bold]
-	n000000e6 [label="{{} | ov5645 3-003b\n/dev/v4l-subdev21 | {<port0> 0}}", shape=Mrecord, style=filled, fillcolor=green]
-	n000000e6:port0 -> n00000001:port0 [style=bold]
-}
diff --git a/Documentation/media/v4l-drivers/qcom_camss_graph.dot b/Documentation/media/v4l-drivers/qcom_camss_graph.dot
deleted file mode 100644
index ef7dca92fd0b..000000000000
--- a/Documentation/media/v4l-drivers/qcom_camss_graph.dot
+++ /dev/null
@@ -1,43 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-digraph board {
-	rankdir=TB
-	n00000001 [label="{{<port0> 0} | msm_csiphy0\n/dev/v4l-subdev0 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
-	n00000001:port1 -> n00000007:port0 [style=dashed]
-	n00000001:port1 -> n0000000a:port0 [style=dashed]
-	n00000004 [label="{{<port0> 0} | msm_csiphy1\n/dev/v4l-subdev1 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
-	n00000004:port1 -> n00000007:port0 [style=dashed]
-	n00000004:port1 -> n0000000a:port0 [style=dashed]
-	n00000007 [label="{{<port0> 0} | msm_csid0\n/dev/v4l-subdev2 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
-	n00000007:port1 -> n0000000d:port0 [style=dashed]
-	n00000007:port1 -> n00000010:port0 [style=dashed]
-	n0000000a [label="{{<port0> 0} | msm_csid1\n/dev/v4l-subdev3 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
-	n0000000a:port1 -> n0000000d:port0 [style=dashed]
-	n0000000a:port1 -> n00000010:port0 [style=dashed]
-	n0000000d [label="{{<port0> 0} | msm_ispif0\n/dev/v4l-subdev4 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
-	n0000000d:port1 -> n00000013:port0 [style=dashed]
-	n0000000d:port1 -> n0000001c:port0 [style=dashed]
-	n0000000d:port1 -> n00000025:port0 [style=dashed]
-	n0000000d:port1 -> n0000002e:port0 [style=dashed]
-	n00000010 [label="{{<port0> 0} | msm_ispif1\n/dev/v4l-subdev5 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
-	n00000010:port1 -> n00000013:port0 [style=dashed]
-	n00000010:port1 -> n0000001c:port0 [style=dashed]
-	n00000010:port1 -> n00000025:port0 [style=dashed]
-	n00000010:port1 -> n0000002e:port0 [style=dashed]
-	n00000013 [label="{{<port0> 0} | msm_vfe0_rdi0\n/dev/v4l-subdev6 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
-	n00000013:port1 -> n00000016 [style=bold]
-	n00000016 [label="msm_vfe0_video0\n/dev/video0", shape=box, style=filled, fillcolor=yellow]
-	n0000001c [label="{{<port0> 0} | msm_vfe0_rdi1\n/dev/v4l-subdev7 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
-	n0000001c:port1 -> n0000001f [style=bold]
-	n0000001f [label="msm_vfe0_video1\n/dev/video1", shape=box, style=filled, fillcolor=yellow]
-	n00000025 [label="{{<port0> 0} | msm_vfe0_rdi2\n/dev/v4l-subdev8 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
-	n00000025:port1 -> n00000028 [style=bold]
-	n00000028 [label="msm_vfe0_video2\n/dev/video2", shape=box, style=filled, fillcolor=yellow]
-	n0000002e [label="{{<port0> 0} | msm_vfe0_pix\n/dev/v4l-subdev9 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
-	n0000002e:port1 -> n00000031 [style=bold]
-	n00000031 [label="msm_vfe0_video3\n/dev/video3", shape=box, style=filled, fillcolor=yellow]
-	n00000057 [label="{{} | ov5645 1-0076\n/dev/v4l-subdev10 | {<port0> 0}}", shape=Mrecord, style=filled, fillcolor=green]
-	n00000057:port0 -> n00000001:port0 [style=bold]
-	n00000059 [label="{{} | ov5645 1-0074\n/dev/v4l-subdev11 | {<port0> 0}}", shape=Mrecord, style=filled, fillcolor=green]
-	n00000059:port0 -> n00000004:port0 [style=bold]
-}
diff --git a/Documentation/media/v4l-drivers/radiotrack.rst b/Documentation/media/v4l-drivers/radiotrack.rst
deleted file mode 100644
index a85cb6205db8..000000000000
--- a/Documentation/media/v4l-drivers/radiotrack.rst
+++ /dev/null
@@ -1,168 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-The Radiotrack radio driver
-===========================
-
-Author: Stephen M. Benoit <benoits@servicepro.com>
-
-Date:  Dec 14, 1996
-
-ACKNOWLEDGMENTS
-----------------
-
-This document was made based on 'C' code for Linux from Gideon le Grange
-(legrang@active.co.za or legrang@cs.sun.ac.za) in 1994, and elaborations from
-Frans Brinkman (brinkman@esd.nl) in 1996.  The results reported here are from
-experiments that the author performed on his own setup, so your mileage may
-vary... I make no guarantees, claims or warranties to the suitability or
-validity of this information.  No other documentation on the AIMS
-Lab (http://www.aimslab.com/) RadioTrack card was made available to the
-author.  This document is offered in the hopes that it might help users who
-want to use the RadioTrack card in an environment other than MS Windows.
-
-WHY THIS DOCUMENT?
-------------------
-
-I have a RadioTrack card from back when I ran an MS-Windows platform.  After
-converting to Linux, I found Gideon le Grange's command-line software for
-running the card, and found that it was good!  Frans Brinkman made a
-comfortable X-windows interface, and added a scanning feature.  For hack
-value, I wanted to see if the tuner could be tuned beyond the usual FM radio
-broadcast band, so I could pick up the audio carriers from North American
-broadcast TV channels, situated just below and above the 87.0-109.0 MHz range.
-I did not get much success, but I learned about programming ioports under
-Linux and gained some insights about the hardware design used for the card.
-
-So, without further delay, here are the details.
-
-
-PHYSICAL DESCRIPTION
---------------------
-
-The RadioTrack card is an ISA 8-bit FM radio card.  The radio frequency (RF)
-input is simply an antenna lead, and the output is a power audio signal
-available through a miniature phone plug.  Its RF frequencies of operation are
-more or less limited from 87.0 to 109.0 MHz (the commercial FM broadcast
-band).  Although the registers can be programmed to request frequencies beyond
-these limits, experiments did not give promising results.  The variable
-frequency oscillator (VFO) that demodulates the intermediate frequency (IF)
-signal probably has a small range of useful frequencies, and wraps around or
-gets clipped beyond the limits mentioned above.
-
-
-CONTROLLING THE CARD WITH IOPORT
---------------------------------
-
-The RadioTrack (base) ioport is configurable for 0x30c or 0x20c.  Only one
-ioport seems to be involved.  The ioport decoding circuitry must be pretty
-simple, as individual ioport bits are directly matched to specific functions
-(or blocks) of the radio card.  This way, many functions can be changed in
-parallel with one write to the ioport.  The only feedback available through
-the ioports appears to be the "Stereo Detect" bit.
-
-The bits of the ioport are arranged as follows:
-
-.. code-block:: none
-
-	MSb                                                         LSb
-	+------+------+------+--------+--------+-------+---------+--------+
-	| VolA | VolB | ???? | Stereo | Radio  | TuneA | TuneB   | Tune   |
-	|  (+) |  (-) |      | Detect | Audio  | (bit) | (latch) | Update |
-	|      |      |      | Enable | Enable |       |         | Enable |
-	+------+------+------+--------+--------+-------+---------+--------+
-
-
-====  ====  =================================
-VolA  VolB  Description
-====  ====  =================================
-0	 0  audio mute
-0	 1  volume +    (some delay required)
-1	 0  volume -    (some delay required)
-1	 1  stay at present volume
-====  ====  =================================
-
-====================	===========
-Stereo Detect Enable	Description
-====================	===========
-0			No Detect
-1			Detect
-====================	===========
-
-Results available by reading ioport >60 msec after last port write.
-
-  0xff ==> no stereo detected,  0xfd ==> stereo detected.
-
-=============================	=============================
-Radio to Audio (path) Enable	Description
-=============================	=============================
-0				Disable path (silence)
-1				Enable path  (audio produced)
-=============================	=============================
-
-=====  =====  ==================
-TuneA  TuneB  Description
-=====  =====  ==================
-0	0     "zero" bit phase 1
-0	1     "zero" bit phase 2
-1	0     "one" bit phase 1
-1	1     "one" bit phase 2
-=====  =====  ==================
-
-
-24-bit code, where bits = (freq*40) + 10486188.
-The Most Significant 11 bits must be 1010 xxxx 0x0 to be valid.
-The bits are shifted in LSb first.
-
-==================	===========================
-Tune Update Enable	Description
-==================	===========================
-0			Tuner held constant
-1			Tuner updating in progress
-==================	===========================
-
-
-PROGRAMMING EXAMPLES
---------------------
-
-.. code-block:: none
-
-	Default:        BASE <-- 0xc8  (current volume, no stereo detect,
-					radio enable, tuner adjust disable)
-
-	Card Off:	BASE <-- 0x00  (audio mute, no stereo detect,
-					radio disable, tuner adjust disable)
-
-	Card On:	BASE <-- 0x00  (see "Card Off", clears any unfinished business)
-			BASE <-- 0xc8  (see "Default")
-
-	Volume Down:    BASE <-- 0x48  (volume down, no stereo detect,
-					radio enable, tuner adjust disable)
-			wait 10 msec
-			BASE <-- 0xc8  (see "Default")
-
-	Volume Up:      BASE <-- 0x88  (volume up, no stereo detect,
-					radio enable, tuner adjust disable)
-			wait 10 msec
-			BASE <-- 0xc8  (see "Default")
-
-	Check Stereo:   BASE <-- 0xd8  (current volume, stereo detect,
-					radio enable, tuner adjust disable)
-			wait 100 msec
-			x <-- BASE     (read ioport)
-			BASE <-- 0xc8  (see "Default")
-
-			x=0xff ==> "not stereo", x=0xfd ==> "stereo detected"
-
-	Set Frequency:  code = (freq*40) + 10486188
-			foreach of the 24 bits in code,
-			(from Least to Most Significant):
-			to write a "zero" bit,
-			BASE <-- 0x01  (audio mute, no stereo detect, radio
-					disable, "zero" bit phase 1, tuner adjust)
-			BASE <-- 0x03  (audio mute, no stereo detect, radio
-					disable, "zero" bit phase 2, tuner adjust)
-			to write a "one" bit,
-			BASE <-- 0x05  (audio mute, no stereo detect, radio
-					disable, "one" bit phase 1, tuner adjust)
-			BASE <-- 0x07  (audio mute, no stereo detect, radio
-					disable, "one" bit phase 2, tuner adjust)
diff --git a/Documentation/media/v4l-drivers/rcar-fdp1.rst b/Documentation/media/v4l-drivers/rcar-fdp1.rst
deleted file mode 100644
index 88b0edcf9046..000000000000
--- a/Documentation/media/v4l-drivers/rcar-fdp1.rst
+++ /dev/null
@@ -1,39 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-Renesas R-Car Fine Display Processor (FDP1) Driver
-==================================================
-
-The R-Car FDP1 driver implements driver-specific controls as follows.
-
-``V4L2_CID_DEINTERLACING_MODE (menu)``
-    The video deinterlacing mode (such as Bob, Weave, ...). The R-Car FDP1
-    driver implements the following modes.
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 4
-
-    * - ``"Progressive" (0)``
-      - The input image video stream is progressive (not interlaced). No
-        deinterlacing is performed. Apart from (optional) format and encoding
-        conversion output frames are identical to the input frames.
-    * - ``"Adaptive 2D/3D" (1)``
-      - Motion adaptive version of 2D and 3D deinterlacing. Use 3D deinterlacing
-        in the presence of fast motion and 2D deinterlacing with diagonal
-        interpolation otherwise.
-    * - ``"Fixed 2D" (2)``
-      - The current field is scaled vertically by averaging adjacent lines to
-        recover missing lines. This method is also known as blending or Line
-        Averaging (LAV).
-    * - ``"Fixed 3D" (3)``
-      - The previous and next fields are averaged to recover lines missing from
-        the current field. This method is also known as Field Averaging (FAV).
-    * - ``"Previous field" (4)``
-      - The current field is weaved with the previous field, i.e. the previous
-        field is used to fill missing lines from the current field. This method
-        is also known as weave deinterlacing.
-    * - ``"Next field" (5)``
-      - The current field is weaved with the next field, i.e. the next field is
-        used to fill missing lines from the current field. This method is also
-        known as weave deinterlacing.
diff --git a/Documentation/media/v4l-drivers/saa7134-cardlist.rst b/Documentation/media/v4l-drivers/saa7134-cardlist.rst
deleted file mode 100644
index afb0e2fb52b0..000000000000
--- a/Documentation/media/v4l-drivers/saa7134-cardlist.rst
+++ /dev/null
@@ -1,803 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-SAA7134 cards list
-==================
-
-.. tabularcolumns:: |p{1.4cm}|p{11.1cm}|p{4.2cm}|
-
-.. flat-table::
-   :header-rows: 1
-   :widths: 2 19 18
-   :stub-columns: 0
-
-   * - Card number
-     - Card name
-     - PCI IDs
-
-   * - 0
-     - UNKNOWN/GENERIC
-     -
-
-   * - 1
-     - Proteus Pro [philips reference design]
-     - 1131:2001, 1131:2001
-
-   * - 2
-     - LifeView FlyVIDEO3000
-     - 5168:0138, 4e42:0138
-
-   * - 3
-     - LifeView/Typhoon FlyVIDEO2000
-     - 5168:0138, 4e42:0138
-
-   * - 4
-     - EMPRESS
-     - 1131:6752
-
-   * - 5
-     - SKNet Monster TV
-     - 1131:4e85
-
-   * - 6
-     - Tevion MD 9717
-     -
-
-   * - 7
-     - KNC One TV-Station RDS / Typhoon TV Tuner RDS
-     - 1131:fe01, 1894:fe01
-
-   * - 8
-     - Terratec Cinergy 400 TV
-     - 153b:1142
-
-   * - 9
-     - Medion 5044
-     -
-
-   * - 10
-     - Kworld/KuroutoShikou SAA7130-TVPCI
-     -
-
-   * - 11
-     - Terratec Cinergy 600 TV
-     - 153b:1143
-
-   * - 12
-     - Medion 7134
-     - 16be:0003, 16be:5000
-
-   * - 13
-     - Typhoon TV+Radio 90031
-     -
-
-   * - 14
-     - ELSA EX-VISION 300TV
-     - 1048:226b
-
-   * - 15
-     - ELSA EX-VISION 500TV
-     - 1048:226a
-
-   * - 16
-     - ASUS TV-FM 7134
-     - 1043:4842, 1043:4830, 1043:4840
-
-   * - 17
-     - AOPEN VA1000 POWER
-     - 1131:7133
-
-   * - 18
-     - BMK MPEX No Tuner
-     -
-
-   * - 19
-     - Compro VideoMate TV
-     - 185b:c100
-
-   * - 20
-     - Matrox CronosPlus
-     - 102B:48d0
-
-   * - 21
-     - 10MOONS PCI TV CAPTURE CARD
-     - 1131:2001
-
-   * - 22
-     - AverMedia M156 / Medion 2819
-     - 1461:a70b
-
-   * - 23
-     - BMK MPEX Tuner
-     -
-
-   * - 24
-     - KNC One TV-Station DVR
-     - 1894:a006
-
-   * - 25
-     - ASUS TV-FM 7133
-     - 1043:4843
-
-   * - 26
-     - Pinnacle PCTV Stereo (saa7134)
-     - 11bd:002b
-
-   * - 27
-     - Manli MuchTV M-TV002
-     -
-
-   * - 28
-     - Manli MuchTV M-TV001
-     -
-
-   * - 29
-     - Nagase Sangyo TransGear 3000TV
-     - 1461:050c
-
-   * - 30
-     - Elitegroup ECS TVP3XP FM1216 Tuner Card(PAL-BG,FM)
-     - 1019:4cb4
-
-   * - 31
-     - Elitegroup ECS TVP3XP FM1236 Tuner Card (NTSC,FM)
-     - 1019:4cb5
-
-   * - 32
-     - AVACS SmartTV
-     -
-
-   * - 33
-     - AVerMedia DVD EZMaker
-     - 1461:10ff
-
-   * - 34
-     - Noval Prime TV 7133
-     -
-
-   * - 35
-     - AverMedia AverTV Studio 305
-     - 1461:2115
-
-   * - 36
-     - UPMOST PURPLE TV
-     - 12ab:0800
-
-   * - 37
-     - Items MuchTV Plus / IT-005
-     -
-
-   * - 38
-     - Terratec Cinergy 200 TV
-     - 153b:1152
-
-   * - 39
-     - LifeView FlyTV Platinum Mini
-     - 5168:0212, 4e42:0212, 5169:1502
-
-   * - 40
-     - Compro VideoMate TV PVR/FM
-     - 185b:c100
-
-   * - 41
-     - Compro VideoMate TV Gold+
-     - 185b:c100
-
-   * - 42
-     - Sabrent SBT-TVFM (saa7130)
-     -
-
-   * - 43
-     - :Zolid Xpert TV7134
-     -
-
-   * - 44
-     - Empire PCI TV-Radio LE
-     -
-
-   * - 45
-     - Avermedia AVerTV Studio 307
-     - 1461:9715
-
-   * - 46
-     - AVerMedia Cardbus TV/Radio (E500)
-     - 1461:d6ee
-
-   * - 47
-     - Terratec Cinergy 400 mobile
-     - 153b:1162
-
-   * - 48
-     - Terratec Cinergy 600 TV MK3
-     - 153b:1158
-
-   * - 49
-     - Compro VideoMate Gold+ Pal
-     - 185b:c200
-
-   * - 50
-     - Pinnacle PCTV 300i DVB-T + PAL
-     - 11bd:002d
-
-   * - 51
-     - ProVideo PV952
-     - 1540:9524
-
-   * - 52
-     - AverMedia AverTV/305
-     - 1461:2108
-
-   * - 53
-     - ASUS TV-FM 7135
-     - 1043:4845
-
-   * - 54
-     - LifeView FlyTV Platinum FM / Gold
-     - 5168:0214, 5168:5214, 1489:0214, 5168:0304
-
-   * - 55
-     - LifeView FlyDVB-T DUO / MSI TV@nywhere Duo
-     - 5168:0306, 4E42:0306
-
-   * - 56
-     - Avermedia AVerTV 307
-     - 1461:a70a
-
-   * - 57
-     - Avermedia AVerTV GO 007 FM
-     - 1461:f31f
-
-   * - 58
-     - ADS Tech Instant TV (saa7135)
-     - 1421:0350, 1421:0351, 1421:0370, 1421:1370
-
-   * - 59
-     - Kworld/Tevion V-Stream Xpert TV PVR7134
-     -
-
-   * - 60
-     - LifeView/Typhoon/Genius FlyDVB-T Duo Cardbus
-     - 5168:0502, 4e42:0502, 1489:0502
-
-   * - 61
-     - Philips TOUGH DVB-T reference design
-     - 1131:2004
-
-   * - 62
-     - Compro VideoMate TV Gold+II
-     -
-
-   * - 63
-     - Kworld Xpert TV PVR7134
-     -
-
-   * - 64
-     - FlyTV mini Asus Digimatrix
-     - 1043:0210
-
-   * - 65
-     - V-Stream Studio TV Terminator
-     -
-
-   * - 66
-     - Yuan TUN-900 (saa7135)
-     -
-
-   * - 67
-     - Beholder BeholdTV 409 FM
-     - 0000:4091
-
-   * - 68
-     - GoTView 7135 PCI
-     - 5456:7135
-
-   * - 69
-     - Philips EUROPA V3 reference design
-     - 1131:2004
-
-   * - 70
-     - Compro Videomate DVB-T300
-     - 185b:c900
-
-   * - 71
-     - Compro Videomate DVB-T200
-     - 185b:c901
-
-   * - 72
-     - RTD Embedded Technologies VFG7350
-     - 1435:7350
-
-   * - 73
-     - RTD Embedded Technologies VFG7330
-     - 1435:7330
-
-   * - 74
-     - LifeView FlyTV Platinum Mini2
-     - 14c0:1212
-
-   * - 75
-     - AVerMedia AVerTVHD MCE A180
-     - 1461:1044
-
-   * - 76
-     - SKNet MonsterTV Mobile
-     - 1131:4ee9
-
-   * - 77
-     - Pinnacle PCTV 40i/50i/110i (saa7133)
-     - 11bd:002e
-
-   * - 78
-     - ASUSTeK P7131 Dual
-     - 1043:4862
-
-   * - 79
-     - Sedna/MuchTV PC TV Cardbus TV/Radio (ITO25 Rev:2B)
-     -
-
-   * - 80
-     - ASUS Digimatrix TV
-     - 1043:0210
-
-   * - 81
-     - Philips Tiger reference design
-     - 1131:2018
-
-   * - 82
-     - MSI TV@Anywhere plus
-     - 1462:6231, 1462:8624
-
-   * - 83
-     - Terratec Cinergy 250 PCI TV
-     - 153b:1160
-
-   * - 84
-     - LifeView FlyDVB Trio
-     - 5168:0319
-
-   * - 85
-     - AverTV DVB-T 777
-     - 1461:2c05, 1461:2c05
-
-   * - 86
-     - LifeView FlyDVB-T / Genius VideoWonder DVB-T
-     - 5168:0301, 1489:0301
-
-   * - 87
-     - ADS Instant TV Duo Cardbus PTV331
-     - 0331:1421
-
-   * - 88
-     - Tevion/KWorld DVB-T 220RF
-     - 17de:7201
-
-   * - 89
-     - ELSA EX-VISION 700TV
-     - 1048:226c
-
-   * - 90
-     - Kworld ATSC110/115
-     - 17de:7350, 17de:7352
-
-   * - 91
-     - AVerMedia A169 B
-     - 1461:7360
-
-   * - 92
-     - AVerMedia A169 B1
-     - 1461:6360
-
-   * - 93
-     - Medion 7134 Bridge #2
-     - 16be:0005
-
-   * - 94
-     - LifeView FlyDVB-T Hybrid Cardbus/MSI TV @nywhere A/D NB
-     - 5168:3306, 5168:3502, 5168:3307, 4e42:3502
-
-   * - 95
-     - LifeView FlyVIDEO3000 (NTSC)
-     - 5169:0138
-
-   * - 96
-     - Medion Md8800 Quadro
-     - 16be:0007, 16be:0008, 16be:000d
-
-   * - 97
-     - LifeView FlyDVB-S /Acorp TV134DS
-     - 5168:0300, 4e42:0300
-
-   * - 98
-     - Proteus Pro 2309
-     - 0919:2003
-
-   * - 99
-     - AVerMedia TV Hybrid A16AR
-     - 1461:2c00
-
-   * - 100
-     - Asus Europa2 OEM
-     - 1043:4860
-
-   * - 101
-     - Pinnacle PCTV 310i
-     - 11bd:002f
-
-   * - 102
-     - Avermedia AVerTV Studio 507
-     - 1461:9715
-
-   * - 103
-     - Compro Videomate DVB-T200A
-     -
-
-   * - 104
-     - Hauppauge WinTV-HVR1110 DVB-T/Hybrid
-     - 0070:6700, 0070:6701, 0070:6702, 0070:6703, 0070:6704, 0070:6705
-
-   * - 105
-     - Terratec Cinergy HT PCMCIA
-     - 153b:1172
-
-   * - 106
-     - Encore ENLTV
-     - 1131:2342, 1131:2341, 3016:2344
-
-   * - 107
-     - Encore ENLTV-FM
-     - 1131:230f
-
-   * - 108
-     - Terratec Cinergy HT PCI
-     - 153b:1175
-
-   * - 109
-     - Philips Tiger - S Reference design
-     -
-
-   * - 110
-     - Avermedia M102
-     - 1461:f31e
-
-   * - 111
-     - ASUS P7131 4871
-     - 1043:4871
-
-   * - 112
-     - ASUSTeK P7131 Hybrid
-     - 1043:4876
-
-   * - 113
-     - Elitegroup ECS TVP3XP FM1246 Tuner Card (PAL,FM)
-     - 1019:4cb6
-
-   * - 114
-     - KWorld DVB-T 210
-     - 17de:7250
-
-   * - 115
-     - Sabrent PCMCIA TV-PCB05
-     - 0919:2003
-
-   * - 116
-     - 10MOONS TM300 TV Card
-     - 1131:2304
-
-   * - 117
-     - Avermedia Super 007
-     - 1461:f01d
-
-   * - 118
-     - Beholder BeholdTV 401
-     - 0000:4016
-
-   * - 119
-     - Beholder BeholdTV 403
-     - 0000:4036
-
-   * - 120
-     - Beholder BeholdTV 403 FM
-     - 0000:4037
-
-   * - 121
-     - Beholder BeholdTV 405
-     - 0000:4050
-
-   * - 122
-     - Beholder BeholdTV 405 FM
-     - 0000:4051
-
-   * - 123
-     - Beholder BeholdTV 407
-     - 0000:4070
-
-   * - 124
-     - Beholder BeholdTV 407 FM
-     - 0000:4071
-
-   * - 125
-     - Beholder BeholdTV 409
-     - 0000:4090
-
-   * - 126
-     - Beholder BeholdTV 505 FM
-     - 5ace:5050
-
-   * - 127
-     - Beholder BeholdTV 507 FM / BeholdTV 509 FM
-     - 5ace:5070, 5ace:5090
-
-   * - 128
-     - Beholder BeholdTV Columbus TV/FM
-     - 0000:5201
-
-   * - 129
-     - Beholder BeholdTV 607 FM
-     - 5ace:6070
-
-   * - 130
-     - Beholder BeholdTV M6
-     - 5ace:6190
-
-   * - 131
-     - Twinhan Hybrid DTV-DVB 3056 PCI
-     - 1822:0022
-
-   * - 132
-     - Genius TVGO AM11MCE
-     -
-
-   * - 133
-     - NXP Snake DVB-S reference design
-     -
-
-   * - 134
-     - Medion/Creatix CTX953 Hybrid
-     - 16be:0010
-
-   * - 135
-     - MSI TV@nywhere A/D v1.1
-     - 1462:8625
-
-   * - 136
-     - AVerMedia Cardbus TV/Radio (E506R)
-     - 1461:f436
-
-   * - 137
-     - AVerMedia Hybrid TV/Radio (A16D)
-     - 1461:f936
-
-   * - 138
-     - Avermedia M115
-     - 1461:a836
-
-   * - 139
-     - Compro VideoMate T750
-     - 185b:c900
-
-   * - 140
-     - Avermedia DVB-S Pro A700
-     - 1461:a7a1
-
-   * - 141
-     - Avermedia DVB-S Hybrid+FM A700
-     - 1461:a7a2
-
-   * - 142
-     - Beholder BeholdTV H6
-     - 5ace:6290
-
-   * - 143
-     - Beholder BeholdTV M63
-     - 5ace:6191
-
-   * - 144
-     - Beholder BeholdTV M6 Extra
-     - 5ace:6193
-
-   * - 145
-     - AVerMedia MiniPCI DVB-T Hybrid M103
-     - 1461:f636, 1461:f736
-
-   * - 146
-     - ASUSTeK P7131 Analog
-     -
-
-   * - 147
-     - Asus Tiger 3in1
-     - 1043:4878
-
-   * - 148
-     - Encore ENLTV-FM v5.3
-     - 1a7f:2008
-
-   * - 149
-     - Avermedia PCI pure analog (M135A)
-     - 1461:f11d
-
-   * - 150
-     - Zogis Real Angel 220
-     -
-
-   * - 151
-     - ADS Tech Instant HDTV
-     - 1421:0380
-
-   * - 152
-     - Asus Tiger Rev:1.00
-     - 1043:4857
-
-   * - 153
-     - Kworld Plus TV Analog Lite PCI
-     - 17de:7128
-
-   * - 154
-     - Avermedia AVerTV GO 007 FM Plus
-     - 1461:f31d
-
-   * - 155
-     - Hauppauge WinTV-HVR1150 ATSC/QAM-Hybrid
-     - 0070:6706, 0070:6708
-
-   * - 156
-     - Hauppauge WinTV-HVR1120 DVB-T/Hybrid
-     - 0070:6707, 0070:6709, 0070:670a
-
-   * - 157
-     - Avermedia AVerTV Studio 507UA
-     - 1461:a11b
-
-   * - 158
-     - AVerMedia Cardbus TV/Radio (E501R)
-     - 1461:b7e9
-
-   * - 159
-     - Beholder BeholdTV 505 RDS
-     - 0000:505B
-
-   * - 160
-     - Beholder BeholdTV 507 RDS
-     - 0000:5071
-
-   * - 161
-     - Beholder BeholdTV 507 RDS
-     - 0000:507B
-
-   * - 162
-     - Beholder BeholdTV 607 FM
-     - 5ace:6071
-
-   * - 163
-     - Beholder BeholdTV 609 FM
-     - 5ace:6090
-
-   * - 164
-     - Beholder BeholdTV 609 FM
-     - 5ace:6091
-
-   * - 165
-     - Beholder BeholdTV 607 RDS
-     - 5ace:6072
-
-   * - 166
-     - Beholder BeholdTV 607 RDS
-     - 5ace:6073
-
-   * - 167
-     - Beholder BeholdTV 609 RDS
-     - 5ace:6092
-
-   * - 168
-     - Beholder BeholdTV 609 RDS
-     - 5ace:6093
-
-   * - 169
-     - Compro VideoMate S350/S300
-     - 185b:c900
-
-   * - 170
-     - AverMedia AverTV Studio 505
-     - 1461:a115
-
-   * - 171
-     - Beholder BeholdTV X7
-     - 5ace:7595
-
-   * - 172
-     - RoverMedia TV Link Pro FM
-     - 19d1:0138
-
-   * - 173
-     - Zolid Hybrid TV Tuner PCI
-     - 1131:2004
-
-   * - 174
-     - Asus Europa Hybrid OEM
-     - 1043:4847
-
-   * - 175
-     - Leadtek Winfast DTV1000S
-     - 107d:6655
-
-   * - 176
-     - Beholder BeholdTV 505 RDS
-     - 0000:5051
-
-   * - 177
-     - Hawell HW-404M7
-     -
-
-   * - 178
-     - Beholder BeholdTV H7
-     - 5ace:7190
-
-   * - 179
-     - Beholder BeholdTV A7
-     - 5ace:7090
-
-   * - 180
-     - Avermedia PCI M733A
-     - 1461:4155, 1461:4255
-
-   * - 181
-     - TechoTrend TT-budget T-3000
-     - 13c2:2804
-
-   * - 182
-     - Kworld PCI SBTVD/ISDB-T Full-Seg Hybrid
-     - 17de:b136
-
-   * - 183
-     - Compro VideoMate Vista M1F
-     - 185b:c900
-
-   * - 184
-     - Encore ENLTV-FM 3
-     - 1a7f:2108
-
-   * - 185
-     - MagicPro ProHDTV Pro2 DMB-TH/Hybrid
-     - 17de:d136
-
-   * - 186
-     - Beholder BeholdTV 501
-     - 5ace:5010
-
-   * - 187
-     - Beholder BeholdTV 503 FM
-     - 5ace:5030
-
-   * - 188
-     - Sensoray 811/911
-     - 6000:0811, 6000:0911
-
-   * - 189
-     - Kworld PC150-U
-     - 17de:a134
-
-   * - 190
-     - Asus My Cinema PS3-100
-     - 1043:48cd
-
-   * - 191
-     - Hawell HW-9004V1
-     -
-
-   * - 192
-     - AverMedia AverTV Satellite Hybrid+FM A706
-     - 1461:2055
-
-   * - 193
-     - WIS Voyager or compatible
-     - 1905:7007
-
-   * - 194
-     - AverMedia AverTV/505
-     - 1461:a10a
-
-   * - 195
-     - Leadtek Winfast TV2100 FM
-     - 107d:6f3a
-
-   * - 196
-     - SnaZio* TVPVR PRO
-     - 1779:13cf
diff --git a/Documentation/media/v4l-drivers/saa7134.rst b/Documentation/media/v4l-drivers/saa7134.rst
deleted file mode 100644
index 15d06facdbc1..000000000000
--- a/Documentation/media/v4l-drivers/saa7134.rst
+++ /dev/null
@@ -1,115 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-The saa7134 driver
-==================
-
-Author Gerd Hoffmann
-
-
-This is a v4l2/oss device driver for saa7130/33/34/35 based capture / TV
-boards.  See http://www.semiconductors.philips.com/pip/saa7134hl for a
-description.
-
-
-Status
-------
-
-Almost everything is working.  video, sound, tuner, radio, mpeg ts, ...
-
-As with bttv, card-specific tweaks are needed.  Check CARDLIST for a
-list of known TV cards and saa7134-cards.c for the drivers card
-configuration info.
-
-
-Build
------
-
-Pick up videodev + v4l2 patches from http://bytesex.org/patches/.
-Configure, build, install + boot the new kernel.  You'll need at least
-these config options:
-
-.. code-block:: none
-
-	CONFIG_I2C=m
-	CONFIG_VIDEO_DEV=m
-
-Type "make" to build the driver now.  "make install" installs the
-driver.  "modprobe saa7134" should load it.  Depending on the card you
-might have to pass card=<nr> as insmod option, check CARDLIST for
-valid choices.
-
-
-Changes / Fixes
----------------
-
-Please mail me unified diffs ("diff -u") with your changes, and don't
-forget to tell me what it changes / which problem it fixes / whatever
-it is good for ...
-
-
-Known Problems
---------------
-
-* The tuner for the flyvideos isn't detected automatically and the
-  default might not work for you depending on which version you have.
-  There is a tuner= insmod option to override the driver's default.
-
-Card Variations:
-----------------
-
-Cards can use either of these two crystals (xtal):
-
-- 32.11 MHz -> .audio_clock=0x187de7
-- 24.576MHz -> .audio_clock=0x200000 (xtal * .audio_clock = 51539600)
-
-Some details about 30/34/35:
-
-- saa7130 - low-price chip, doesn't have mute, that is why all those
-  cards should have .mute field defined in their tuner structure.
-
-- saa7134 - usual chip
-
-- saa7133/35 - saa7135 is probably a marketing decision, since all those
-  chips identifies itself as 33 on pci.
-
-LifeView GPIOs
---------------
-
-This section was authored by: Peter Missel <peter.missel@onlinehome.de>
-
-- LifeView FlyTV Platinum FM (LR214WF)
-
-    - GP27    MDT2005 PB4 pin 10
-    - GP26    MDT2005 PB3 pin 9
-    - GP25    MDT2005 PB2 pin 8
-    - GP23    MDT2005 PB1 pin 7
-    - GP22    MDT2005 PB0 pin 6
-    - GP21    MDT2005 PB5 pin 11
-    - GP20    MDT2005 PB6 pin 12
-    - GP19    MDT2005 PB7 pin 13
-    - nc      MDT2005 PA3 pin 2
-    - Remote  MDT2005 PA2 pin 1
-    - GP18    MDT2005 PA1 pin 18
-    - nc      MDT2005 PA0 pin 17 strap low
-    - GP17    Strap "GP7"=High
-    - GP16    Strap "GP6"=High
-
-	- 0=Radio 1=TV
-	- Drives SA630D ENCH1 and HEF4052 A1 pinsto do FM radio through
-	  SIF input
-
-    - GP15    nc
-    - GP14    nc
-    - GP13    nc
-    - GP12    Strap "GP5" = High
-    - GP11    Strap "GP4" = High
-    - GP10    Strap "GP3" = High
-    - GP09    Strap "GP2" = Low
-    - GP08    Strap "GP1" = Low
-    - GP07.00 nc
-
-Credits
--------
-
-andrew.stevens@philips.com + werner.leeb@philips.com for providing
-saa7134 hardware specs and sample board.
diff --git a/Documentation/media/v4l-drivers/saa7164-cardlist.rst b/Documentation/media/v4l-drivers/saa7164-cardlist.rst
deleted file mode 100644
index e8f36e084537..000000000000
--- a/Documentation/media/v4l-drivers/saa7164-cardlist.rst
+++ /dev/null
@@ -1,71 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-SAA7164 cards list
-==================
-
-.. tabularcolumns:: |p{1.4cm}|p{11.1cm}|p{4.2cm}|
-
-.. flat-table::
-   :header-rows: 1
-   :widths: 2 19 18
-   :stub-columns: 0
-
-   * - Card number
-     - Card name
-     - PCI IDs
-
-   * - 0
-     - Unknown
-     -
-
-   * - 1
-     - Generic Rev2
-     -
-
-   * - 2
-     - Generic Rev3
-     -
-
-   * - 3
-     - Hauppauge WinTV-HVR2250
-     - 0070:8880, 0070:8810
-
-   * - 4
-     - Hauppauge WinTV-HVR2200
-     - 0070:8980
-
-   * - 5
-     - Hauppauge WinTV-HVR2200
-     - 0070:8900
-
-   * - 6
-     - Hauppauge WinTV-HVR2200
-     - 0070:8901
-
-   * - 7
-     - Hauppauge WinTV-HVR2250
-     - 0070:8891, 0070:8851
-
-   * - 8
-     - Hauppauge WinTV-HVR2250
-     - 0070:88A1
-
-   * - 9
-     - Hauppauge WinTV-HVR2200
-     - 0070:8940
-
-   * - 10
-     - Hauppauge WinTV-HVR2200
-     - 0070:8953
-
-   * - 11
-     - Hauppauge WinTV-HVR2255(proto)
-     - 0070:f111
-
-   * - 12
-     - Hauppauge WinTV-HVR2255
-     - 0070:f111
-
-   * - 13
-     - Hauppauge WinTV-HVR2205
-     - 0070:f123, 0070:f120
diff --git a/Documentation/media/v4l-drivers/sh_mobile_ceu_camera.rst b/Documentation/media/v4l-drivers/sh_mobile_ceu_camera.rst
deleted file mode 100644
index 822fcb8368ae..000000000000
--- a/Documentation/media/v4l-drivers/sh_mobile_ceu_camera.rst
+++ /dev/null
@@ -1,142 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-Cropping and Scaling algorithm, used in the sh_mobile_ceu_camera driver
-=======================================================================
-
-Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
-
-Terminology
------------
-
-sensor scales: horizontal and vertical scales, configured by the sensor driver
-host scales: -"- host driver
-combined scales: sensor_scale * host_scale
-
-
-Generic scaling / cropping scheme
----------------------------------
-
-.. code-block:: none
-
-	-1--
-	|
-	-2-- -\
-	|      --\
-	|         --\
-	+-5-- .      -- -3-- -\
-	|      `...            -\
-	|          `... -4-- .   - -7..
-	|                     `.
-	|                       `. .6--
-	|
-	|                        . .6'-
-	|                      .´
-	|           ... -4'- .´
-	|       ...´             - -7'.
-	+-5'- .´               -/
-	|            -- -3'- -/
-	|         --/
-	|      --/
-	-2'- -/
-	|
-	|
-	-1'-
-
-In the above chart minuses and slashes represent "real" data amounts, points and
-accents represent "useful" data, basically, CEU scaled and cropped output,
-mapped back onto the client's source plane.
-
-Such a configuration can be produced by user requests:
-
-S_CROP(left / top = (5) - (1), width / height = (5') - (5))
-S_FMT(width / height = (6') - (6))
-
-Here:
-
-(1) to (1') - whole max width or height
-(1) to (2)  - sensor cropped left or top
-(2) to (2') - sensor cropped width or height
-(3) to (3') - sensor scale
-(3) to (4)  - CEU cropped left or top
-(4) to (4') - CEU cropped width or height
-(5) to (5') - reverse sensor scale applied to CEU cropped width or height
-(2) to (5)  - reverse sensor scale applied to CEU cropped left or top
-(6) to (6') - CEU scale - user window
-
-
-S_FMT
------
-
-Do not touch input rectangle - it is already optimal.
-
-1. Calculate current sensor scales:
-
-	scale_s = ((2') - (2)) / ((3') - (3))
-
-2. Calculate "effective" input crop (sensor subwindow) - CEU crop scaled back at
-current sensor scales onto input window - this is user S_CROP:
-
-	width_u = (5') - (5) = ((4') - (4)) * scale_s
-
-3. Calculate new combined scales from "effective" input window to requested user
-window:
-
-	scale_comb = width_u / ((6') - (6))
-
-4. Calculate sensor output window by applying combined scales to real input
-window:
-
-	width_s_out = ((7') - (7)) = ((2') - (2)) / scale_comb
-
-5. Apply iterative sensor S_FMT for sensor output window.
-
-	subdev->video_ops->s_fmt(.width = width_s_out)
-
-6. Retrieve sensor output window (g_fmt)
-
-7. Calculate new sensor scales:
-
-	scale_s_new = ((3')_new - (3)_new) / ((2') - (2))
-
-8. Calculate new CEU crop - apply sensor scales to previously calculated
-"effective" crop:
-
-	width_ceu = (4')_new - (4)_new = width_u / scale_s_new
-	left_ceu = (4)_new - (3)_new = ((5) - (2)) / scale_s_new
-
-9. Use CEU cropping to crop to the new window:
-
-	ceu_crop(.width = width_ceu, .left = left_ceu)
-
-10. Use CEU scaling to scale to the requested user window:
-
-	scale_ceu = width_ceu / width
-
-
-S_CROP
-------
-
-The :ref:`V4L2 crop API <crop-scale>` says:
-
-"...specification does not define an origin or units. However by convention
-drivers should horizontally count unscaled samples relative to 0H."
-
-We choose to follow the advise and interpret cropping units as client input
-pixels.
-
-Cropping is performed in the following 6 steps:
-
-1. Request exactly user rectangle from the sensor.
-
-2. If smaller - iterate until a larger one is obtained. Result: sensor cropped
-   to 2 : 2', target crop 5 : 5', current output format 6' - 6.
-
-3. In the previous step the sensor has tried to preserve its output frame as
-   good as possible, but it could have changed. Retrieve it again.
-
-4. Sensor scaled to 3 : 3'. Sensor's scale is (2' - 2) / (3' - 3). Calculate
-   intermediate window: 4' - 4 = (5' - 5) * (3' - 3) / (2' - 2)
-
-5. Calculate and apply host scale = (6' - 6) / (4' - 4)
-
-6. Calculate and apply host crop: 6 - 7 = (5 - 2) * (6' - 6) / (5' - 5)
diff --git a/Documentation/media/v4l-drivers/si470x.rst b/Documentation/media/v4l-drivers/si470x.rst
deleted file mode 100644
index d53bf5f95200..000000000000
--- a/Documentation/media/v4l-drivers/si470x.rst
+++ /dev/null
@@ -1,167 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-.. include:: <isonum.txt>
-
-The Silicon Labs Si470x FM Radio Receivers driver
-=================================================
-
-Copyright |copy| 2009 Tobias Lorenz <tobias.lorenz@gmx.net>
-
-
-Information from Silicon Labs
------------------------------
-
-Silicon Laboratories is the manufacturer of the radio ICs, that nowadays are the
-most often used radio receivers in cell phones. Usually they are connected with
-I2C. But SiLabs also provides a reference design, which integrates this IC,
-together with a small microcontroller C8051F321, to form a USB radio.
-Part of this reference design is also a radio application in binary and source
-code. The software also contains an automatic firmware upgrade to the most
-current version. Information on these can be downloaded here:
-http://www.silabs.com/usbradio
-
-
-Supported ICs
--------------
-
-The following ICs have a very similar register set, so that they are or will be
-supported somewhen by the driver:
-
-- Si4700: FM radio receiver
-- Si4701: FM radio receiver, RDS Support
-- Si4702: FM radio receiver
-- Si4703: FM radio receiver, RDS Support
-- Si4704: FM radio receiver, no external antenna required
-- Si4705: FM radio receiver, no external antenna required, RDS support, Dig I/O
-- Si4706: Enhanced FM RDS/TMC radio receiver, no external antenna required, RDS
-	  Support
-- Si4707: Dedicated weather band radio receiver with SAME decoder, RDS Support
-- Si4708: Smallest FM receivers
-- Si4709: Smallest FM receivers, RDS Support
-
-More information on these can be downloaded here:
-http://www.silabs.com/products/mcu/Pages/USBFMRadioRD.aspx
-
-
-Supported USB devices
----------------------
-
-Currently the following USB radios (vendor:product) with the Silicon Labs si470x
-chips are known to work:
-
-- 10c4:818a: Silicon Labs USB FM Radio Reference Design
-- 06e1:a155: ADS/Tech FM Radio Receiver (formerly Instant FM Music) (RDX-155-EF)
-- 1b80:d700: KWorld USB FM Radio SnapMusic Mobile 700 (FM700)
-- 10c5:819a: Sanei Electric, Inc. FM USB Radio (sold as DealExtreme.com PCear)
-
-
-Software
---------
-
-Testing is usually done with most application under Debian/testing:
-
-- fmtools - Utility for managing FM tuner cards
-- gnomeradio - FM-radio tuner for the GNOME desktop
-- gradio - GTK FM radio tuner
-- kradio - Comfortable Radio Application for KDE
-- radio - ncurses-based radio application
-- mplayer - The Ultimate Movie Player For Linux
-- v4l2-ctl - Collection of command line video4linux utilities
-
-For example, you can use:
-
-.. code-block:: none
-
-	v4l2-ctl -d /dev/radio0 --set-ctrl=volume=10,mute=0 --set-freq=95.21 --all
-
-There is also a library libv4l, which can be used. It's going to have a function
-for frequency seeking, either by using hardware functionality as in radio-si470x
-or by implementing a function as we currently have in every of the mentioned
-programs. Somewhen the radio programs should make use of libv4l.
-
-For processing RDS information, there is a project ongoing at:
-http://rdsd.berlios.de/
-
-There is currently no project for making TMC sentences human readable.
-
-
-Audio Listing
--------------
-
-USB Audio is provided by the ALSA snd_usb_audio module. It is recommended to
-also select SND_USB_AUDIO, as this is required to get sound from the radio. For
-listing you have to redirect the sound, for example using one of the following
-commands. Please adjust the audio devices to your needs (/dev/dsp* and hw:x,x).
-
-If you just want to test audio (very poor quality):
-
-.. code-block:: none
-
-	cat /dev/dsp1 > /dev/dsp
-
-If you use sox + OSS try:
-
-.. code-block:: none
-
-	sox -2 --endian little -r 96000 -t oss /dev/dsp1 -t oss /dev/dsp
-
-or using sox + alsa:
-
-.. code-block:: none
-
-	sox --endian little -c 2 -S -r 96000 -t alsa hw:1 -t alsa -r 96000 hw:0
-
-If you use arts try:
-
-.. code-block:: none
-
-	arecord -D hw:1,0 -r96000 -c2 -f S16_LE | artsdsp aplay -B -
-
-If you use mplayer try:
-
-.. code-block:: none
-
-	mplayer -radio adevice=hw=1.0:arate=96000 \
-		-rawaudio rate=96000 \
-		radio://<frequency>/capture
-
-Module Parameters
------------------
-
-After loading the module, you still have access to some of them in the sysfs
-mount under /sys/module/radio_si470x/parameters. The contents of read-only files
-(0444) are not updated, even if space, band and de are changed using private
-video controls. The others are runtime changeable.
-
-
-Errors
-------
-
-Increase tune_timeout, if you often get -EIO errors.
-
-When timed out or band limit is reached, hw_freq_seek returns -EAGAIN.
-
-If you get any errors from snd_usb_audio, please report them to the ALSA people.
-
-
-Open Issues
------------
-
-V4L minor device allocation and parameter setting is not perfect. A solution is
-currently under discussion.
-
-There is an USB interface for downloading/uploading new firmware images. Support
-for it can be implemented using the request_firmware interface.
-
-There is a RDS interrupt mode. The driver is already using the same interface
-for polling RDS information, but is currently not using the interrupt mode.
-
-There is a LED interface, which can be used to override the LED control
-programmed in the firmware. This can be made available using the LED support
-functions in the kernel.
-
-
-Other useful information and links
-----------------------------------
-
-http://www.silabs.com/usbradio
diff --git a/Documentation/media/v4l-drivers/si4713.rst b/Documentation/media/v4l-drivers/si4713.rst
deleted file mode 100644
index be8e6b49b7b4..000000000000
--- a/Documentation/media/v4l-drivers/si4713.rst
+++ /dev/null
@@ -1,192 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-.. include:: <isonum.txt>
-
-The Silicon Labs Si4713 FM Radio Transmitter Driver
-===================================================
-
-Copyright |copy| 2009 Nokia Corporation
-
-Contact: Eduardo Valentin <eduardo.valentin@nokia.com>
-
-
-Information about the Device
-----------------------------
-
-This chip is a Silicon Labs product. It is a I2C device, currently on 0x63 address.
-Basically, it has transmission and signal noise level measurement features.
-
-The Si4713 integrates transmit functions for FM broadcast stereo transmission.
-The chip also allows integrated receive power scanning to identify low signal
-power FM channels.
-
-The chip is programmed using commands and responses. There are also several
-properties which can change the behavior of this chip.
-
-Users must comply with local regulations on radio frequency (RF) transmission.
-
-Device driver description
--------------------------
-
-There are two modules to handle this device. One is a I2C device driver
-and the other is a platform driver.
-
-The I2C device driver exports a v4l2-subdev interface to the kernel.
-All properties can also be accessed by v4l2 extended controls interface, by
-using the v4l2-subdev calls (g_ext_ctrls, s_ext_ctrls).
-
-The platform device driver exports a v4l2 radio device interface to user land.
-So, it uses the I2C device driver as a sub device in order to send the user
-commands to the actual device. Basically it is a wrapper to the I2C device driver.
-
-Applications can use v4l2 radio API to specify frequency of operation, mute state,
-etc. But mostly of its properties will be present in the extended controls.
-
-When the v4l2 mute property is set to 1 (true), the driver will turn the chip off.
-
-Properties description
-----------------------
-
-The properties can be accessed using v4l2 extended controls.
-Here is an output from v4l2-ctl util:
-
-.. code-block:: none
-
-	/ # v4l2-ctl -d /dev/radio0 --all -L
-	Driver Info:
-		Driver name   : radio-si4713
-		Card type     : Silicon Labs Si4713 Modulator
-		Bus info      :
-		Driver version: 0
-		Capabilities  : 0x00080800
-			RDS Output
-			Modulator
-	Audio output: 0 (FM Modulator Audio Out)
-	Frequency: 1408000 (88.000000 MHz)
-	Video Standard = 0x00000000
-	Modulator:
-		Name                 : FM Modulator
-		Capabilities         : 62.5 Hz stereo rds
-		Frequency range      : 76.0 MHz - 108.0 MHz
-		Subchannel modulation: stereo+rds
-
-	User Controls
-
-				mute (bool) : default=1 value=0
-
-	FM Radio Modulator Controls
-
-		rds_signal_deviation (int)  : min=0 max=90000 step=10 default=200 value=200 flags=slider
-			rds_program_id (int)  : min=0 max=65535 step=1 default=0 value=0
-		rds_program_type (int)  : min=0 max=31 step=1 default=0 value=0
-			rds_ps_name (str)  : min=0 max=96 step=8 value='si4713  '
-			rds_radio_text (str)  : min=0 max=384 step=32 value=''
-	audio_limiter_feature_enabled (bool) : default=1 value=1
-	audio_limiter_release_time (int)  : min=250 max=102390 step=50 default=5010 value=5010 flags=slider
-		audio_limiter_deviation (int)  : min=0 max=90000 step=10 default=66250 value=66250 flags=slider
-	audio_compression_feature_enabl (bool) : default=1 value=1
-		audio_compression_gain (int)  : min=0 max=20 step=1 default=15 value=15 flags=slider
-	audio_compression_threshold (int)  : min=-40 max=0 step=1 default=-40 value=-40 flags=slider
-	audio_compression_attack_time (int)  : min=0 max=5000 step=500 default=0 value=0 flags=slider
-	audio_compression_release_time (int)  : min=100000 max=1000000 step=100000 default=1000000 value=1000000 flags=slider
-	pilot_tone_feature_enabled (bool) : default=1 value=1
-		pilot_tone_deviation (int)  : min=0 max=90000 step=10 default=6750 value=6750 flags=slider
-		pilot_tone_frequency (int)  : min=0 max=19000 step=1 default=19000 value=19000 flags=slider
-		pre_emphasis_settings (menu) : min=0 max=2 default=1 value=1
-		tune_power_level (int)  : min=0 max=120 step=1 default=88 value=88 flags=slider
-		tune_antenna_capacitor (int)  : min=0 max=191 step=1 default=0 value=110 flags=slider
-
-Here is a summary of them:
-
-* Pilot is an audible tone sent by the device.
-
-- pilot_frequency - Configures the frequency of the stereo pilot tone.
-- pilot_deviation - Configures pilot tone frequency deviation level.
-- pilot_enabled - Enables or disables the pilot tone feature.
-
-* The si4713 device is capable of applying audio compression to the
-  transmitted signal.
-
-- acomp_enabled - Enables or disables the audio dynamic range control feature.
-- acomp_gain - Sets the gain for audio dynamic range control.
-- acomp_threshold - Sets the threshold level for audio dynamic range control.
-- acomp_attack_time - Sets the attack time for audio dynamic range control.
-- acomp_release_time - Sets the release time for audio dynamic range control.
-
-* Limiter setups audio deviation limiter feature. Once a over deviation occurs,
-  it is possible to adjust the front-end gain of the audio input and always
-  prevent over deviation.
-
-- limiter_enabled - Enables or disables the limiter feature.
-- limiter_deviation - Configures audio frequency deviation level.
-- limiter_release_time - Sets the limiter release time.
-
-* Tuning power
-
-- power_level - Sets the output power level for signal transmission.
-  antenna_capacitor - This selects the value of antenna tuning capacitor
-  manually or automatically if set to zero.
-
-* RDS related
-
-- rds_ps_name - Sets the RDS ps name field for transmission.
-- rds_radio_text - Sets the RDS radio text for transmission.
-- rds_pi - Sets the RDS PI field for transmission.
-- rds_pty - Sets the RDS PTY field for transmission.
-
-* Region related
-
-- preemphasis - sets the preemphasis to be applied for transmission.
-
-RNL
----
-
-This device also has an interface to measure received noise level. To do that, you should
-ioctl the device node. Here is an code of example:
-
-.. code-block:: none
-
-	int main (int argc, char *argv[])
-	{
-		struct si4713_rnl rnl;
-		int fd = open("/dev/radio0", O_RDWR);
-		int rval;
-
-		if (argc < 2)
-			return -EINVAL;
-
-		if (fd < 0)
-			return fd;
-
-		sscanf(argv[1], "%d", &rnl.frequency);
-
-		rval = ioctl(fd, SI4713_IOC_MEASURE_RNL, &rnl);
-		if (rval < 0)
-			return rval;
-
-		printf("received noise level: %d\n", rnl.rnl);
-
-		close(fd);
-	}
-
-The struct si4713_rnl and SI4713_IOC_MEASURE_RNL are defined under
-include/linux/platform_data/media/si4713.h.
-
-Stereo/Mono and RDS subchannels
--------------------------------
-
-The device can also be configured using the available sub channels for
-transmission. To do that use S/G_MODULATOR ioctl and configure txsubchans properly.
-Refer to the V4L2 API specification for proper use of this ioctl.
-
-Testing
--------
-Testing is usually done with v4l2-ctl utility for managing FM tuner cards.
-The tool can be found in v4l-dvb repository under v4l2-apps/util directory.
-
-Example for setting rds ps name:
-
-.. code-block:: none
-
-	# v4l2-ctl -d /dev/radio0 --set-ctrl=rds_ps_name="Dummy"
-
diff --git a/Documentation/media/v4l-drivers/si476x.rst b/Documentation/media/v4l-drivers/si476x.rst
deleted file mode 100644
index 87062301d6a1..000000000000
--- a/Documentation/media/v4l-drivers/si476x.rst
+++ /dev/null
@@ -1,160 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-.. include:: <isonum.txt>
-
-
-The SI476x Driver
-=================
-
-Copyright |copy| 2013 Andrey Smirnov <andrew.smirnov@gmail.com>
-
-TODO for the driver
--------------------
-
-- According to the SiLabs' datasheet it is possible to update the
-  firmware of the radio chip in the run-time, thus bringing it to the
-  most recent version. Unfortunately I couldn't find any mentioning of
-  the said firmware update for the old chips that I tested the driver
-  against, so for chips like that the driver only exposes the old
-  functionality.
-
-
-Parameters exposed over debugfs
--------------------------------
-SI476x allow user to get multiple characteristics that can be very
-useful for EoL testing/RF performance estimation, parameters that have
-very little to do with V4L2 subsystem. Such parameters are exposed via
-debugfs and can be accessed via regular file I/O operations.
-
-The drivers exposes following files:
-
-* /sys/kernel/debug/<device-name>/acf
-  This file contains ACF(Automatically Controlled Features) status
-  information. The contents of the file is binary data of the
-  following layout:
-
-  .. tabularcolumns:: |p{7ex}|p{12ex}|L|
-
-  =============  ==============   ====================================
-  Offset	 Name		  Description
-  =============  ==============   ====================================
-  0x00		 blend_int	  Flag, set when stereo separation has
-				  crossed below the blend threshold
-  0x01		 hblend_int	  Flag, set when HiBlend cutoff
-				  frequency is lower than threshold
-  0x02		 hicut_int	  Flag, set when HiCut cutoff
-				  frequency is lower than threshold
-  0x03		 chbw_int	  Flag, set when channel filter
-				  bandwidth is less than threshold
-  0x04		 softmute_int	  Flag indicating that softmute
-				  attenuation has increased above
-				  softmute threshold
-  0x05		 smute		  0 - Audio is not soft muted
-				  1 - Audio is soft muted
-  0x06		 smattn		  Soft mute attenuation level in dB
-  0x07		 chbw		  Channel filter bandwidth in kHz
-  0x08		 hicut		  HiCut cutoff frequency in units of
-				  100Hz
-  0x09		 hiblend	  HiBlend cutoff frequency in units
-				  of 100 Hz
-  0x10		 pilot		  0 - Stereo pilot is not present
-				  1 - Stereo pilot is present
-  0x11		 stblend	  Stereo blend in %
-  =============  ==============   ====================================
-
-
-* /sys/kernel/debug/<device-name>/rds_blckcnt
-  This file contains statistics about RDS receptions. It's binary data
-  has the following layout:
-
-  .. tabularcolumns:: |p{7ex}|p{12ex}|L|
-
-  =============  ==============   ====================================
-  Offset	 Name		  Description
-  =============  ==============   ====================================
-  0x00		 expected	  Number of expected RDS blocks
-  0x02		 received	  Number of received RDS blocks
-  0x04		 uncorrectable	  Number of uncorrectable RDS blocks
-  =============  ==============   ====================================
-
-* /sys/kernel/debug/<device-name>/agc
-  This file contains information about parameters pertaining to
-  AGC(Automatic Gain Control)
-
-  The layout is:
-
-  .. tabularcolumns:: |p{7ex}|p{12ex}|L|
-
-  =============  ==============   ====================================
-  Offset	 Name		  Description
-  =============  ==============   ====================================
-  0x00		 mxhi		  0 - FM Mixer PD high threshold is
-				  not tripped
-				  1 - FM Mixer PD high threshold is
-				  tripped
-  0x01		 mxlo		  ditto for FM Mixer PD low
-  0x02		 lnahi		  ditto for FM LNA PD high
-  0x03		 lnalo		  ditto for FM LNA PD low
-  0x04		 fmagc1		  FMAGC1 attenuator resistance
-				  (see datasheet for more detail)
-  0x05		 fmagc2		  ditto for FMAGC2
-  0x06		 pgagain	  PGA gain in dB
-  0x07		 fmwblang	  FM/WB LNA Gain in dB
-  =============  ==============   ====================================
-
-* /sys/kernel/debug/<device-name>/rsq
-  This file contains information about parameters pertaining to
-  RSQ(Received Signal Quality)
-
-  The layout is:
-
-  .. tabularcolumns:: |p{7ex}|p{12ex}|p{60ex}|
-
-  =============  ==============   ====================================
-  Offset	 Name		  Description
-  =============  ==============   ====================================
-  0x00		 multhint	  0 - multipath value has not crossed
-				  the Multipath high threshold
-				  1 - multipath value has crossed
-				  the Multipath high threshold
-  0x01		 multlint	  ditto for Multipath low threshold
-  0x02		 snrhint	  0 - received signal's SNR has not
-				  crossed high threshold
-				  1 - received signal's SNR has
-				  crossed high threshold
-  0x03		 snrlint	  ditto for low threshold
-  0x04		 rssihint	  ditto for RSSI high threshold
-  0x05		 rssilint	  ditto for RSSI low threshold
-  0x06		 bltf		  Flag indicating if seek command
-				  reached/wrapped seek band limit
-  0x07		 snr_ready	  Indicates that SNR metrics is ready
-  0x08		 rssiready	  ditto for RSSI metrics
-  0x09		 injside	  0 - Low-side injection is being used
-				  1 - High-side injection is used
-  0x10		 afcrl		  Flag indicating if AFC rails
-  0x11		 valid		  Flag indicating if channel is valid
-  0x12		 readfreq	  Current tuned frequency
-  0x14		 freqoff	  Signed frequency offset in units of
-				  2ppm
-  0x15		 rssi		  Signed value of RSSI in dBuV
-  0x16		 snr		  Signed RF SNR in dB
-  0x17		 issi		  Signed Image Strength Signal
-				  indicator
-  0x18		 lassi		  Signed Low side adjacent Channel
-				  Strength indicator
-  0x19		 hassi		  ditto fpr High side
-  0x20		 mult		  Multipath indicator
-  0x21		 dev		  Frequency deviation
-  0x24		 assi		  Adjacent channel SSI
-  0x25		 usn		  Ultrasonic noise indicator
-  0x26		 pilotdev	  Pilot deviation in units of 100 Hz
-  0x27		 rdsdev		  ditto for RDS
-  0x28		 assidev	  ditto for ASSI
-  0x29		 strongdev	  Frequency deviation
-  0x30		 rdspi		  RDS PI code
-  =============  ==============   ====================================
-
-* /sys/kernel/debug/<device-name>/rsq_primary
-  This file contains information about parameters pertaining to
-  RSQ(Received Signal Quality) for primary tuner only. Layout is as
-  the one above.
diff --git a/Documentation/media/v4l-drivers/soc-camera.rst b/Documentation/media/v4l-drivers/soc-camera.rst
deleted file mode 100644
index 7c39711aebf8..000000000000
--- a/Documentation/media/v4l-drivers/soc-camera.rst
+++ /dev/null
@@ -1,171 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-The Soc-Camera Drivers
-======================
-
-Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
-
-Terminology
------------
-
-The following terms are used in this document:
- - camera / camera device / camera sensor - a video-camera sensor chip, capable
-   of connecting to a variety of systems and interfaces, typically uses i2c for
-   control and configuration, and a parallel or a serial bus for data.
- - camera host - an interface, to which a camera is connected. Typically a
-   specialised interface, present on many SoCs, e.g. PXA27x and PXA3xx, SuperH,
-   i.MX27, i.MX31.
- - camera host bus - a connection between a camera host and a camera. Can be
-   parallel or serial, consists of data and control lines, e.g. clock, vertical
-   and horizontal synchronization signals.
-
-Purpose of the soc-camera subsystem
------------------------------------
-
-The soc-camera subsystem initially provided a unified API between camera host
-drivers and camera sensor drivers. Later the soc-camera sensor API has been
-replaced with the V4L2 standard subdev API. This also made camera driver re-use
-with non-soc-camera hosts possible. The camera host API to the soc-camera core
-has been preserved.
-
-Soc-camera implements a V4L2 interface to the user, currently only the "mmap"
-method is supported by host drivers. However, the soc-camera core also provides
-support for the "read" method.
-
-The subsystem has been designed to support multiple camera host interfaces and
-multiple cameras per interface, although most applications have only one camera
-sensor.
-
-Existing drivers
-----------------
-
-As of 3.7 there are seven host drivers in the mainline: atmel-isi.c,
-mx1_camera.c (broken, scheduled for removal), mx2_camera.c, mx3_camera.c,
-omap1_camera.c, pxa_camera.c, sh_mobile_ceu_camera.c, and multiple sensor
-drivers under drivers/media/i2c/soc_camera/.
-
-Camera host API
----------------
-
-A host camera driver is registered using the
-
-.. code-block:: none
-
-	soc_camera_host_register(struct soc_camera_host *);
-
-function. The host object can be initialized as follows:
-
-.. code-block:: none
-
-	struct soc_camera_host	*ici;
-	ici->drv_name		= DRV_NAME;
-	ici->ops		= &camera_host_ops;
-	ici->priv		= pcdev;
-	ici->v4l2_dev.dev	= &pdev->dev;
-	ici->nr			= pdev->id;
-
-All camera host methods are passed in a struct soc_camera_host_ops:
-
-.. code-block:: none
-
-	static struct soc_camera_host_ops camera_host_ops = {
-		.owner		= THIS_MODULE,
-		.add		= camera_add_device,
-		.remove		= camera_remove_device,
-		.set_fmt	= camera_set_fmt_cap,
-		.try_fmt	= camera_try_fmt_cap,
-		.init_videobuf2	= camera_init_videobuf2,
-		.poll		= camera_poll,
-		.querycap	= camera_querycap,
-		.set_bus_param	= camera_set_bus_param,
-		/* The rest of host operations are optional */
-	};
-
-.add and .remove methods are called when a sensor is attached to or detached
-from the host. .set_bus_param is used to configure physical connection
-parameters between the host and the sensor. .init_videobuf2 is called by
-soc-camera core when a video-device is opened, the host driver would typically
-call vb2_queue_init() in this method. Further video-buffer management is
-implemented completely by the specific camera host driver. If the host driver
-supports non-standard pixel format conversion, it should implement a
-.get_formats and, possibly, a .put_formats operations. See below for more
-details about format conversion. The rest of the methods are called from
-respective V4L2 operations.
-
-Camera API
-----------
-
-Sensor drivers can use struct soc_camera_link, typically provided by the
-platform, and used to specify to which camera host bus the sensor is connected,
-and optionally provide platform .power and .reset methods for the camera. This
-struct is provided to the camera driver via the I2C client device platform data
-and can be obtained, using the soc_camera_i2c_to_link() macro. Care should be
-taken, when using soc_camera_vdev_to_subdev() and when accessing struct
-soc_camera_device, using v4l2_get_subdev_hostdata(): both only work, when
-running on an soc-camera host. The actual camera driver operation is implemented
-using the V4L2 subdev API. Additionally soc-camera camera drivers can use
-auxiliary soc-camera helper functions like soc_camera_power_on() and
-soc_camera_power_off(), which switch regulators, provided by the platform and call
-board-specific power switching methods. soc_camera_apply_board_flags() takes
-camera bus configuration capability flags and applies any board transformations,
-e.g. signal polarity inversion. soc_mbus_get_fmtdesc() can be used to obtain a
-pixel format descriptor, corresponding to a certain media-bus pixel format code.
-soc_camera_limit_side() can be used to restrict beginning and length of a frame
-side, based on camera capabilities.
-
-VIDIOC_S_CROP and VIDIOC_S_FMT behaviour
-----------------------------------------
-
-Above user ioctls modify image geometry as follows:
-
-VIDIOC_S_CROP: sets location and sizes of the sensor window. Unit is one sensor
-pixel. Changing sensor window sizes preserves any scaling factors, therefore
-user window sizes change as well.
-
-VIDIOC_S_FMT: sets user window. Should preserve previously set sensor window as
-much as possible by modifying scaling factors. If the sensor window cannot be
-preserved precisely, it may be changed too.
-
-In soc-camera there are two locations, where scaling and cropping can take
-place: in the camera driver and in the host driver. User ioctls are first passed
-to the host driver, which then generally passes them down to the camera driver.
-It is more efficient to perform scaling and cropping in the camera driver to
-save camera bus bandwidth and maximise the framerate. However, if the camera
-driver failed to set the required parameters with sufficient precision, the host
-driver may decide to also use its own scaling and cropping to fulfill the user's
-request.
-
-Camera drivers are interfaced to the soc-camera core and to host drivers over
-the v4l2-subdev API, which is completely functional, it doesn't pass any data.
-Therefore all camera drivers shall reply to .g_fmt() requests with their current
-output geometry. This is necessary to correctly configure the camera bus.
-.s_fmt() and .try_fmt() have to be implemented too. Sensor window and scaling
-factors have to be maintained by camera drivers internally. According to the
-V4L2 API all capture drivers must support the VIDIOC_CROPCAP ioctl, hence we
-rely on camera drivers implementing .cropcap(). If the camera driver does not
-support cropping, it may choose to not implement .s_crop(), but to enable
-cropping support by the camera host driver at least the .g_crop method must be
-implemented.
-
-User window geometry is kept in .user_width and .user_height fields in struct
-soc_camera_device and used by the soc-camera core and host drivers. The core
-updates these fields upon successful completion of a .s_fmt() call, but if these
-fields change elsewhere, e.g. during .s_crop() processing, the host driver is
-responsible for updating them.
-
-Format conversion
------------------
-
-V4L2 distinguishes between pixel formats, as they are stored in memory, and as
-they are transferred over a media bus. Soc-camera provides support to
-conveniently manage these formats. A table of standard transformations is
-maintained by soc-camera core, which describes, what FOURCC pixel format will
-be obtained, if a media-bus pixel format is stored in memory according to
-certain rules. E.g. if MEDIA_BUS_FMT_YUYV8_2X8 data is sampled with 8 bits per
-sample and stored in memory in the little-endian order with no gaps between
-bytes, data in memory will represent the V4L2_PIX_FMT_YUYV FOURCC format. These
-standard transformations will be used by soc-camera or by camera host drivers to
-configure camera drivers to produce the FOURCC format, requested by the user,
-using the VIDIOC_S_FMT ioctl(). Apart from those standard format conversions,
-host drivers can also provide their own conversion rules by implementing a
-.get_formats and, if required, a .put_formats methods.
diff --git a/Documentation/media/v4l-drivers/tm6000-cardlist.rst b/Documentation/media/v4l-drivers/tm6000-cardlist.rst
deleted file mode 100644
index 6d2769c0f4d8..000000000000
--- a/Documentation/media/v4l-drivers/tm6000-cardlist.rst
+++ /dev/null
@@ -1,83 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-TM6000 cards list
-=================
-
-.. tabularcolumns:: |p{1.4cm}|p{11.1cm}|p{4.2cm}|
-
-.. flat-table::
-   :header-rows: 1
-   :widths: 2 19 18
-   :stub-columns: 0
-
-   * - Card number
-     - Card name
-     - USB IDs
-
-   * - 0
-     - Unknown tm6000 video grabber
-     -
-
-   * - 1
-     - Generic tm5600 board
-     - 6000:0001
-
-   * - 2
-     - Generic tm6000 board
-     -
-
-   * - 3
-     - Generic tm6010 board
-     - 6000:0002
-
-   * - 4
-     - 10Moons UT 821
-     -
-
-   * - 5
-     - 10Moons UT 330
-     -
-
-   * - 6
-     - ADSTECH Dual TV USB
-     - 06e1:f332
-
-   * - 7
-     - Freecom Hybrid Stick / Moka DVB-T Receiver Dual
-     - 14aa:0620
-
-   * - 8
-     - ADSTECH Mini Dual TV USB
-     - 06e1:b339
-
-   * - 9
-     - Hauppauge WinTV HVR-900H / WinTV USB2-Stick
-     - 2040:6600, 2040:6601, 2040:6610, 2040:6611
-
-   * - 10
-     - Beholder Wander DVB-T/TV/FM USB2.0
-     - 6000:dec0
-
-   * - 11
-     - Beholder Voyager TV/FM USB2.0
-     - 6000:dec1
-
-   * - 12
-     - Terratec Cinergy Hybrid XE / Cinergy Hybrid-Stick
-     - 0ccd:0086, 0ccd:00A5
-
-   * - 13
-     - Twinhan TU501(704D1)
-     - 13d3:3240, 13d3:3241, 13d3:3243, 13d3:3264
-
-   * - 14
-     - Beholder Wander Lite DVB-T/TV/FM USB2.0
-     - 6000:dec2
-
-   * - 15
-     - Beholder Voyager Lite TV/FM USB2.0
-     - 6000:dec3
-
-   * - 16
-     - Terratec Grabster AV 150/250 MX
-     - 0ccd:0079
diff --git a/Documentation/media/v4l-drivers/tuner-cardlist.rst b/Documentation/media/v4l-drivers/tuner-cardlist.rst
deleted file mode 100644
index 362617c59c5d..000000000000
--- a/Documentation/media/v4l-drivers/tuner-cardlist.rst
+++ /dev/null
@@ -1,100 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-Tuner cards list
-================
-
-============ =====================================================
-Tuner number Card name
-============ =====================================================
-0            Temic PAL (4002 FH5)
-1            Philips PAL_I (FI1246 and compatibles)
-2            Philips NTSC (FI1236,FM1236 and compatibles)
-3            Philips (SECAM+PAL_BG) (FI1216MF, FM1216MF, FR1216MF)
-4            NoTuner
-5            Philips PAL_BG (FI1216 and compatibles)
-6            Temic NTSC (4032 FY5)
-7            Temic PAL_I (4062 FY5)
-8            Temic NTSC (4036 FY5)
-9            Alps HSBH1
-10           Alps TSBE1
-11           Alps TSBB5
-12           Alps TSBE5
-13           Alps TSBC5
-14           Temic PAL_BG (4006FH5)
-15           Alps TSCH6
-16           Temic PAL_DK (4016 FY5)
-17           Philips NTSC_M (MK2)
-18           Temic PAL_I (4066 FY5)
-19           Temic PAL* auto (4006 FN5)
-20           Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)
-21           Temic NTSC (4039 FR5)
-22           Temic PAL/SECAM multi (4046 FM5)
-23           Philips PAL_DK (FI1256 and compatibles)
-24           Philips PAL/SECAM multi (FQ1216ME)
-25           LG PAL_I+FM (TAPC-I001D)
-26           LG PAL_I (TAPC-I701D)
-27           LG NTSC+FM (TPI8NSR01F)
-28           LG PAL_BG+FM (TPI8PSB01D)
-29           LG PAL_BG (TPI8PSB11D)
-30           Temic PAL* auto + FM (4009 FN5)
-31           SHARP NTSC_JP (2U5JF5540)
-32           Samsung PAL TCPM9091PD27
-33           MT20xx universal
-34           Temic PAL_BG (4106 FH5)
-35           Temic PAL_DK/SECAM_L (4012 FY5)
-36           Temic NTSC (4136 FY5)
-37           LG PAL (newer TAPC series)
-38           Philips PAL/SECAM multi (FM1216ME MK3)
-39           LG NTSC (newer TAPC series)
-40           HITACHI V7-J180AT
-41           Philips PAL_MK (FI1216 MK)
-42           Philips FCV1236D ATSC/NTSC dual in
-43           Philips NTSC MK3 (FM1236MK3 or FM1236/F)
-44           Philips 4 in 1 (ATI TV Wonder Pro/Conexant)
-45           Microtune 4049 FM5
-46           Panasonic VP27s/ENGE4324D
-47           LG NTSC (TAPE series)
-48           Tenna TNF 8831 BGFF)
-49           Microtune 4042 FI5 ATSC/NTSC dual in
-50           TCL 2002N
-51           Philips PAL/SECAM_D (FM 1256 I-H3)
-52           Thomson DTT 7610 (ATSC/NTSC)
-53           Philips FQ1286
-54           Philips/NXP TDA 8290/8295 + 8275/8275A/18271
-55           TCL 2002MB
-56           Philips PAL/SECAM multi (FQ1216AME MK4)
-57           Philips FQ1236A MK4
-58           Ymec TVision TVF-8531MF/8831MF/8731MF
-59           Ymec TVision TVF-5533MF
-60           Thomson DTT 761X (ATSC/NTSC)
-61           Tena TNF9533-D/IF/TNF9533-B/DF
-62           Philips TEA5767HN FM Radio
-63           Philips FMD1216ME MK3 Hybrid Tuner
-64           LG TDVS-H06xF
-65           Ymec TVF66T5-B/DFF
-66           LG TALN series
-67           Philips TD1316 Hybrid Tuner
-68           Philips TUV1236D ATSC/NTSC dual in
-69           Tena TNF 5335 and similar models
-70           Samsung TCPN 2121P30A
-71           Xceive xc2028/xc3028 tuner
-72           Thomson FE6600
-73           Samsung TCPG 6121P30A
-75           Philips TEA5761 FM Radio
-76           Xceive 5000 tuner
-77           TCL tuner MF02GIP-5N-E
-78           Philips FMD1216MEX MK3 Hybrid Tuner
-79           Philips PAL/SECAM multi (FM1216 MK5)
-80           Philips FQ1216LME MK3 PAL/SECAM w/active loopthrough
-81           Partsnic (Daewoo) PTI-5NF05
-82           Philips CU1216L
-83           NXP TDA18271
-84           Sony BTF-Pxn01Z
-85           Philips FQ1236 MK5
-86           Tena TNF5337 MFD
-87           Xceive 4000 tuner
-88           Xceive 5000C tuner
-89           Sony BTF-PG472Z PAL/SECAM
-90           Sony BTF-PK467Z NTSC-M-JP
-91           Sony BTF-PB463Z NTSC-M
-============ =====================================================
diff --git a/Documentation/media/v4l-drivers/tuners.rst b/Documentation/media/v4l-drivers/tuners.rst
deleted file mode 100644
index 7509be888909..000000000000
--- a/Documentation/media/v4l-drivers/tuners.rst
+++ /dev/null
@@ -1,133 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-Tuner drivers
-=============
-
-Simple tuner Programming
-------------------------
-
-There are some flavors of Tuner programming APIs.
-These differ mainly by the bandswitch byte.
-
-- L= LG_API       (VHF_LO=0x01, VHF_HI=0x02, UHF=0x08, radio=0x04)
-- P= PHILIPS_API  (VHF_LO=0xA0, VHF_HI=0x90, UHF=0x30, radio=0x04)
-- T= TEMIC_API    (VHF_LO=0x02, VHF_HI=0x04, UHF=0x01)
-- A= ALPS_API     (VHF_LO=0x14, VHF_HI=0x12, UHF=0x11)
-- M= PHILIPS_MK3  (VHF_LO=0x01, VHF_HI=0x02, UHF=0x04, radio=0x19)
-
-Tuner Manufacturers
--------------------
-
-- SAMSUNG Tuner identification: (e.g. TCPM9091PD27)
-
-.. code-block:: none
-
- TCP [ABCJLMNQ] 90[89][125] [DP] [ACD] 27 [ABCD]
- [ABCJLMNQ]:
-   A= BG+DK
-   B= BG
-   C= I+DK
-   J= NTSC-Japan
-   L= Secam LL
-   M= BG+I+DK
-   N= NTSC
-   Q= BG+I+DK+LL
- [89]: ?
- [125]:
-   2: No FM
-   5: With FM
- [DP]:
-   D= NTSC
-   P= PAL
- [ACD]:
-   A= F-connector
-   C= Phono connector
-   D= Din Jack
- [ABCD]:
-   3-wire/I2C tuning, 2-band/3-band
-
-These Tuners are PHILIPS_API compatible.
-
-Philips Tuner identification: (e.g. FM1216MF)
-
-.. code-block:: none
-
-  F[IRMQ]12[1345]6{MF|ME|MP}
-  F[IRMQ]:
-   FI12x6: Tuner Series
-   FR12x6: Tuner + Radio IF
-   FM12x6: Tuner + FM
-   FQ12x6: special
-   FMR12x6: special
-   TD15xx: Digital Tuner ATSC
-  12[1345]6:
-   1216: PAL BG
-   1236: NTSC
-   1246: PAL I
-   1256: Pal DK
-  {MF|ME|MP}
-   MF: BG LL w/ Secam (Multi France)
-   ME: BG DK I LL   (Multi Europe)
-   MP: BG DK I      (Multi PAL)
-   MR: BG DK M (?)
-   MG: BG DKI M (?)
-  MK2 series PHILIPS_API, most tuners are compatible to this one !
-  MK3 series introduced in 2002 w/ PHILIPS_MK3_API
-
-Temic Tuner identification: (.e.g 4006FH5)
-
-.. code-block:: none
-
-   4[01][0136][269]F[HYNR]5
-    40x2: Tuner (5V/33V), TEMIC_API.
-    40x6: Tuner 5V
-    41xx: Tuner compact
-    40x9: Tuner+FM compact
-   [0136]
-    xx0x: PAL BG
-    xx1x: Pal DK, Secam LL
-    xx3x: NTSC
-    xx6x: PAL I
-   F[HYNR]5
-    FH5: Pal BG
-    FY5: others
-    FN5: multistandard
-    FR5: w/ FM radio
-   3X xxxx: order number with specific connector
-  Note: Only 40x2 series has TEMIC_API, all newer tuners have PHILIPS_API.
-
-LG Innotek Tuner:
-
-- TPI8NSR11 : NTSC J/M    (TPI8NSR01 w/FM)  (P,210/497)
-- TPI8PSB11 : PAL B/G     (TPI8PSB01 w/FM)  (P,170/450)
-- TAPC-I701 : PAL I       (TAPC-I001 w/FM)  (P,170/450)
-- TPI8PSB12 : PAL D/K+B/G (TPI8PSB02 w/FM)  (P,170/450)
-- TAPC-H701P: NTSC_JP     (TAPC-H001P w/FM) (L,170/450)
-- TAPC-G701P: PAL B/G     (TAPC-G001P w/FM) (L,170/450)
-- TAPC-W701P: PAL I       (TAPC-W001P w/FM) (L,170/450)
-- TAPC-Q703P: PAL D/K     (TAPC-Q001P w/FM) (L,170/450)
-- TAPC-Q704P: PAL D/K+I   (L,170/450)
-- TAPC-G702P: PAL D/K+B/G (L,170/450)
-
-- TADC-H002F: NTSC (L,175/410?; 2-B, C-W+11, W+12-69)
-- TADC-M201D: PAL D/K+B/G+I (L,143/425)  (sound control at I2C address 0xc8)
-- TADC-T003F: NTSC Taiwan  (L,175/410?; 2-B, C-W+11, W+12-69)
-
-Suffix:
-  - P= Standard phono female socket
-  - D= IEC female socket
-  - F= F-connector
-
-Other Tuners:
-
-- TCL2002MB-1 : PAL BG + DK       =TUNER_LG_PAL_NEW_TAPC
-- TCL2002MB-1F: PAL BG + DK w/FM  =PHILIPS_PAL
-- TCL2002MI-2 : PAL I		= ??
-
-ALPS Tuners:
-
-- Most are LG_API compatible
-- TSCH6 has ALPS_API (TSCH5 ?)
-- TSBE1 has extra API 05,02,08 Control_byte=0xCB Source:[#f1]_
-
-.. [#f1] conexant100029b-PCI-Decoder-ApplicationNote.pdf
diff --git a/Documentation/media/v4l-drivers/usbvision-cardlist.rst b/Documentation/media/v4l-drivers/usbvision-cardlist.rst
deleted file mode 100644
index 6aee115ee6e2..000000000000
--- a/Documentation/media/v4l-drivers/usbvision-cardlist.rst
+++ /dev/null
@@ -1,283 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-USBvision cards list
-====================
-
-.. tabularcolumns:: |p{1.4cm}|p{11.1cm}|p{4.2cm}|
-
-.. flat-table::
-   :header-rows: 1
-   :widths: 2 19 18
-   :stub-columns: 0
-
-   * - Card number
-     - Card name
-     - USB IDs
-
-   * - 0
-     - Xanboo
-     - 0a6f:0400
-
-   * - 1
-     - Belkin USB VideoBus II Adapter
-     - 050d:0106
-
-   * - 2
-     - Belkin Components USB VideoBus
-     - 050d:0207
-
-   * - 3
-     - Belkin USB VideoBus II
-     - 050d:0208
-
-   * - 4
-     - echoFX InterView Lite
-     - 0571:0002
-
-   * - 5
-     - USBGear USBG-V1 resp. HAMA USB
-     - 0573:0003
-
-   * - 6
-     - D-Link V100
-     - 0573:0400
-
-   * - 7
-     - X10 USB Camera
-     - 0573:2000
-
-   * - 8
-     - Hauppauge WinTV USB Live (PAL B/G)
-     - 0573:2d00
-
-   * - 9
-     - Hauppauge WinTV USB Live Pro (NTSC M/N)
-     - 0573:2d01
-
-   * - 10
-     - Zoran Co. PMD (Nogatech) AV-grabber Manhattan
-     - 0573:2101
-
-   * - 11
-     - Nogatech USB-TV (NTSC) FM
-     - 0573:4100
-
-   * - 12
-     - PNY USB-TV (NTSC) FM
-     - 0573:4110
-
-   * - 13
-     - PixelView PlayTv-USB PRO (PAL) FM
-     - 0573:4450
-
-   * - 14
-     - ZTV ZT-721 2.4GHz USB A/V Receiver
-     - 0573:4550
-
-   * - 15
-     - Hauppauge WinTV USB (NTSC M/N)
-     - 0573:4d00
-
-   * - 16
-     - Hauppauge WinTV USB (PAL B/G)
-     - 0573:4d01
-
-   * - 17
-     - Hauppauge WinTV USB (PAL I)
-     - 0573:4d02
-
-   * - 18
-     - Hauppauge WinTV USB (PAL/SECAM L)
-     - 0573:4d03
-
-   * - 19
-     - Hauppauge WinTV USB (PAL D/K)
-     - 0573:4d04
-
-   * - 20
-     - Hauppauge WinTV USB (NTSC FM)
-     - 0573:4d10
-
-   * - 21
-     - Hauppauge WinTV USB (PAL B/G FM)
-     - 0573:4d11
-
-   * - 22
-     - Hauppauge WinTV USB (PAL I FM)
-     - 0573:4d12
-
-   * - 23
-     - Hauppauge WinTV USB (PAL D/K FM)
-     - 0573:4d14
-
-   * - 24
-     - Hauppauge WinTV USB Pro (NTSC M/N)
-     - 0573:4d2a
-
-   * - 25
-     - Hauppauge WinTV USB Pro (NTSC M/N) V2
-     - 0573:4d2b
-
-   * - 26
-     - Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L)
-     - 0573:4d2c
-
-   * - 27
-     - Hauppauge WinTV USB Pro (NTSC M/N) V3
-     - 0573:4d20
-
-   * - 28
-     - Hauppauge WinTV USB Pro (PAL B/G)
-     - 0573:4d21
-
-   * - 29
-     - Hauppauge WinTV USB Pro (PAL I)
-     - 0573:4d22
-
-   * - 30
-     - Hauppauge WinTV USB Pro (PAL/SECAM L)
-     - 0573:4d23
-
-   * - 31
-     - Hauppauge WinTV USB Pro (PAL D/K)
-     - 0573:4d24
-
-   * - 32
-     - Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L)
-     - 0573:4d25
-
-   * - 33
-     - Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L) V2
-     - 0573:4d26
-
-   * - 34
-     - Hauppauge WinTV USB Pro (PAL B/G) V2
-     - 0573:4d27
-
-   * - 35
-     - Hauppauge WinTV USB Pro (PAL B/G,D/K)
-     - 0573:4d28
-
-   * - 36
-     - Hauppauge WinTV USB Pro (PAL I,D/K)
-     - 0573:4d29
-
-   * - 37
-     - Hauppauge WinTV USB Pro (NTSC M/N FM)
-     - 0573:4d30
-
-   * - 38
-     - Hauppauge WinTV USB Pro (PAL B/G FM)
-     - 0573:4d31
-
-   * - 39
-     - Hauppauge WinTV USB Pro (PAL I FM)
-     - 0573:4d32
-
-   * - 40
-     - Hauppauge WinTV USB Pro (PAL D/K FM)
-     - 0573:4d34
-
-   * - 41
-     - Hauppauge WinTV USB Pro (Temic PAL/SECAM B/G/I/D/K/L FM)
-     - 0573:4d35
-
-   * - 42
-     - Hauppauge WinTV USB Pro (Temic PAL B/G FM)
-     - 0573:4d36
-
-   * - 43
-     - Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L FM)
-     - 0573:4d37
-
-   * - 44
-     - Hauppauge WinTV USB Pro (NTSC M/N FM) V2
-     - 0573:4d38
-
-   * - 45
-     - Camtel Technology USB TV Genie Pro FM Model TVB330
-     - 0768:0006
-
-   * - 46
-     - Digital Video Creator I
-     - 07d0:0001
-
-   * - 47
-     - Global Village GV-007 (NTSC)
-     - 07d0:0002
-
-   * - 48
-     - Dazzle Fusion Model DVC-50 Rev 1 (NTSC)
-     - 07d0:0003
-
-   * - 49
-     - Dazzle Fusion Model DVC-80 Rev 1 (PAL)
-     - 07d0:0004
-
-   * - 50
-     - Dazzle Fusion Model DVC-90 Rev 1 (SECAM)
-     - 07d0:0005
-
-   * - 51
-     - Eskape Labs MyTV2Go
-     - 07f8:9104
-
-   * - 52
-     - Pinnacle Studio PCTV USB (PAL)
-     - 2304:010d
-
-   * - 53
-     - Pinnacle Studio PCTV USB (SECAM)
-     - 2304:0109
-
-   * - 54
-     - Pinnacle Studio PCTV USB (PAL) FM
-     - 2304:0110
-
-   * - 55
-     - Miro PCTV USB
-     - 2304:0111
-
-   * - 56
-     - Pinnacle Studio PCTV USB (NTSC) FM
-     - 2304:0112
-
-   * - 57
-     - Pinnacle Studio PCTV USB (PAL) FM V2
-     - 2304:0210
-
-   * - 58
-     - Pinnacle Studio PCTV USB (NTSC) FM V2
-     - 2304:0212
-
-   * - 59
-     - Pinnacle Studio PCTV USB (PAL) FM V3
-     - 2304:0214
-
-   * - 60
-     - Pinnacle Studio Linx Video input cable (NTSC)
-     - 2304:0300
-
-   * - 61
-     - Pinnacle Studio Linx Video input cable (PAL)
-     - 2304:0301
-
-   * - 62
-     - Pinnacle PCTV Bungee USB (PAL) FM
-     - 2304:0419
-
-   * - 63
-     - Hauppauge WinTv-USB
-     - 2400:4200
-
-   * - 64
-     - Pinnacle Studio PCTV USB (NTSC) FM V3
-     - 2304:0113
-
-   * - 65
-     - Nogatech USB MicroCam NTSC (NV3000N)
-     - 0573:3000
-
-   * - 66
-     - Nogatech USB MicroCam PAL (NV3001P)
-     - 0573:3001
diff --git a/Documentation/media/v4l-drivers/uvcvideo.rst b/Documentation/media/v4l-drivers/uvcvideo.rst
deleted file mode 100644
index e5fd8fad333c..000000000000
--- a/Documentation/media/v4l-drivers/uvcvideo.rst
+++ /dev/null
@@ -1,257 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-The Linux USB Video Class (UVC) driver
-======================================
-
-This file documents some driver-specific aspects of the UVC driver, such as
-driver-specific ioctls and implementation notes.
-
-Questions and remarks can be sent to the Linux UVC development mailing list at
-linux-uvc-devel@lists.berlios.de.
-
-
-Extension Unit (XU) support
----------------------------
-
-Introduction
-~~~~~~~~~~~~
-
-The UVC specification allows for vendor-specific extensions through extension
-units (XUs). The Linux UVC driver supports extension unit controls (XU controls)
-through two separate mechanisms:
-
-  - through mappings of XU controls to V4L2 controls
-  - through a driver-specific ioctl interface
-
-The first one allows generic V4L2 applications to use XU controls by mapping
-certain XU controls onto V4L2 controls, which then show up during ordinary
-control enumeration.
-
-The second mechanism requires uvcvideo-specific knowledge for the application to
-access XU controls but exposes the entire UVC XU concept to user space for
-maximum flexibility.
-
-Both mechanisms complement each other and are described in more detail below.
-
-
-Control mappings
-~~~~~~~~~~~~~~~~
-
-The UVC driver provides an API for user space applications to define so-called
-control mappings at runtime. These allow for individual XU controls or byte
-ranges thereof to be mapped to new V4L2 controls. Such controls appear and
-function exactly like normal V4L2 controls (i.e. the stock controls, such as
-brightness, contrast, etc.). However, reading or writing of such a V4L2 controls
-triggers a read or write of the associated XU control.
-
-The ioctl used to create these control mappings is called UVCIOC_CTRL_MAP.
-Previous driver versions (before 0.2.0) required another ioctl to be used
-beforehand (UVCIOC_CTRL_ADD) to pass XU control information to the UVC driver.
-This is no longer necessary as newer uvcvideo versions query the information
-directly from the device.
-
-For details on the UVCIOC_CTRL_MAP ioctl please refer to the section titled
-"IOCTL reference" below.
-
-
-3. Driver specific XU control interface
-
-For applications that need to access XU controls directly, e.g. for testing
-purposes, firmware upload, or accessing binary controls, a second mechanism to
-access XU controls is provided in the form of a driver-specific ioctl, namely
-UVCIOC_CTRL_QUERY.
-
-A call to this ioctl allows applications to send queries to the UVC driver that
-directly map to the low-level UVC control requests.
-
-In order to make such a request the UVC unit ID of the control's extension unit
-and the control selector need to be known. This information either needs to be
-hardcoded in the application or queried using other ways such as by parsing the
-UVC descriptor or, if available, using the media controller API to enumerate a
-device's entities.
-
-Unless the control size is already known it is necessary to first make a
-UVC_GET_LEN requests in order to be able to allocate a sufficiently large buffer
-and set the buffer size to the correct value. Similarly, to find out whether
-UVC_GET_CUR or UVC_SET_CUR are valid requests for a given control, a
-UVC_GET_INFO request should be made. The bits 0 (GET supported) and 1 (SET
-supported) of the resulting byte indicate which requests are valid.
-
-With the addition of the UVCIOC_CTRL_QUERY ioctl the UVCIOC_CTRL_GET and
-UVCIOC_CTRL_SET ioctls have become obsolete since their functionality is a
-subset of the former ioctl. For the time being they are still supported but
-application developers are encouraged to use UVCIOC_CTRL_QUERY instead.
-
-For details on the UVCIOC_CTRL_QUERY ioctl please refer to the section titled
-"IOCTL reference" below.
-
-
-Security
-~~~~~~~~
-
-The API doesn't currently provide a fine-grained access control facility. The
-UVCIOC_CTRL_ADD and UVCIOC_CTRL_MAP ioctls require super user permissions.
-
-Suggestions on how to improve this are welcome.
-
-
-Debugging
-~~~~~~~~~
-
-In order to debug problems related to XU controls or controls in general it is
-recommended to enable the UVC_TRACE_CONTROL bit in the module parameter 'trace'.
-This causes extra output to be written into the system log.
-
-
-IOCTL reference
-~~~~~~~~~~~~~~~
-
-UVCIOC_CTRL_MAP - Map a UVC control to a V4L2 control
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Argument: struct uvc_xu_control_mapping
-
-**Description**:
-
-	This ioctl creates a mapping between a UVC control or part of a UVC
-	control and a V4L2 control. Once mappings are defined, userspace
-	applications can access vendor-defined UVC control through the V4L2
-	control API.
-
-	To create a mapping, applications fill the uvc_xu_control_mapping
-	structure with information about an existing UVC control defined with
-	UVCIOC_CTRL_ADD and a new V4L2 control.
-
-	A UVC control can be mapped to several V4L2 controls. For instance,
-	a UVC pan/tilt control could be mapped to separate pan and tilt V4L2
-	controls. The UVC control is divided into non overlapping fields using
-	the 'size' and 'offset' fields and are then independently mapped to
-	V4L2 control.
-
-	For signed integer V4L2 controls the data_type field should be set to
-	UVC_CTRL_DATA_TYPE_SIGNED. Other values are currently ignored.
-
-**Return value**:
-
-	On success 0 is returned. On error -1 is returned and errno is set
-	appropriately.
-
-	ENOMEM
-		Not enough memory to perform the operation.
-	EPERM
-		Insufficient privileges (super user privileges are required).
-	EINVAL
-		No such UVC control.
-	EOVERFLOW
-		The requested offset and size would overflow the UVC control.
-	EEXIST
-		Mapping already exists.
-
-**Data types**:
-
-.. code-block:: none
-
-	* struct uvc_xu_control_mapping
-
-	__u32	id		V4L2 control identifier
-	__u8	name[32]	V4L2 control name
-	__u8	entity[16]	UVC extension unit GUID
-	__u8	selector	UVC control selector
-	__u8	size		V4L2 control size (in bits)
-	__u8	offset		V4L2 control offset (in bits)
-	enum v4l2_ctrl_type
-		v4l2_type	V4L2 control type
-	enum uvc_control_data_type
-		data_type	UVC control data type
-	struct uvc_menu_info
-		*menu_info	Array of menu entries (for menu controls only)
-	__u32	menu_count	Number of menu entries (for menu controls only)
-
-	* struct uvc_menu_info
-
-	__u32	value		Menu entry value used by the device
-	__u8	name[32]	Menu entry name
-
-
-	* enum uvc_control_data_type
-
-	UVC_CTRL_DATA_TYPE_RAW		Raw control (byte array)
-	UVC_CTRL_DATA_TYPE_SIGNED	Signed integer
-	UVC_CTRL_DATA_TYPE_UNSIGNED	Unsigned integer
-	UVC_CTRL_DATA_TYPE_BOOLEAN	Boolean
-	UVC_CTRL_DATA_TYPE_ENUM		Enumeration
-	UVC_CTRL_DATA_TYPE_BITMASK	Bitmask
-
-
-UVCIOC_CTRL_QUERY - Query a UVC XU control
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Argument: struct uvc_xu_control_query
-
-**Description**:
-
-	This ioctl queries a UVC XU control identified by its extension unit ID
-	and control selector.
-
-	There are a number of different queries available that closely
-	correspond to the low-level control requests described in the UVC
-	specification. These requests are:
-
-	UVC_GET_CUR
-		Obtain the current value of the control.
-	UVC_GET_MIN
-		Obtain the minimum value of the control.
-	UVC_GET_MAX
-		Obtain the maximum value of the control.
-	UVC_GET_DEF
-		Obtain the default value of the control.
-	UVC_GET_RES
-		Query the resolution of the control, i.e. the step size of the
-		allowed control values.
-	UVC_GET_LEN
-		Query the size of the control in bytes.
-	UVC_GET_INFO
-		Query the control information bitmap, which indicates whether
-		get/set requests are supported.
-	UVC_SET_CUR
-		Update the value of the control.
-
-	Applications must set the 'size' field to the correct length for the
-	control. Exceptions are the UVC_GET_LEN and UVC_GET_INFO queries, for
-	which the size must be set to 2 and 1, respectively. The 'data' field
-	must point to a valid writable buffer big enough to hold the indicated
-	number of data bytes.
-
-	Data is copied directly from the device without any driver-side
-	processing. Applications are responsible for data buffer formatting,
-	including little-endian/big-endian conversion. This is particularly
-	important for the result of the UVC_GET_LEN requests, which is always
-	returned as a little-endian 16-bit integer by the device.
-
-**Return value**:
-
-	On success 0 is returned. On error -1 is returned and errno is set
-	appropriately.
-
-	ENOENT
-		The device does not support the given control or the specified
-		extension unit could not be found.
-	ENOBUFS
-		The specified buffer size is incorrect (too big or too small).
-	EINVAL
-		An invalid request code was passed.
-	EBADRQC
-		The given request is not supported by the given control.
-	EFAULT
-		The data pointer references an inaccessible memory area.
-
-**Data types**:
-
-.. code-block:: none
-
-	* struct uvc_xu_control_query
-
-	__u8	unit		Extension unit ID
-	__u8	selector	Control selector
-	__u8	query		Request code to send to the device
-	__u16	size		Control data size (in bytes)
-	__u8	*data		Control value
diff --git a/Documentation/media/v4l-drivers/v4l-with-ir.rst b/Documentation/media/v4l-drivers/v4l-with-ir.rst
deleted file mode 100644
index ce23c8a7bc93..000000000000
--- a/Documentation/media/v4l-drivers/v4l-with-ir.rst
+++ /dev/null
@@ -1,75 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-Infrared remote control support in video4linux drivers
-======================================================
-
-Authors: Gerd Hoffmann, Mauro Carvalho Chehab
-
-Basics
-------
-
-Most analog and digital TV boards support remote controllers. Several of
-them have a microprocessor that receives the IR carriers, convert into
-pulse/space sequences and then to scan codes, returning such codes to
-userspace ("scancode mode"). Other boards return just the pulse/space
-sequences ("raw mode").
-
-The support for remote controller in scancode mode is provided by the
-standard Linux input layer. The support for raw mode is provided via LIRC.
-
-In order to check the support and test it, it is suggested to download
-the `v4l-utils <https://git.linuxtv.org/v4l-utils.git/>`_. It provides
-two tools to handle remote controllers:
-
-- ir-keytable: provides a way to query the remote controller, list the
-  protocols it supports, enable in-kernel support for IR decoder or
-  switch the protocol and to test the reception of scan codes;
-
-- ir-ctl: provide tools to handle remote controllers that support raw mode
-  via LIRC interface.
-
-Usually, the remote controller module is auto-loaded when the TV card is
-detected. However, for a few devices, you need to manually load the
-ir-kbd-i2c module.
-
-How it works
-------------
-
-The modules register the remote as keyboard within the linux input
-layer, i.e. you'll see the keys of the remote as normal key strokes
-(if CONFIG_INPUT_KEYBOARD is enabled).
-
-Using the event devices (CONFIG_INPUT_EVDEV) it is possible for
-applications to access the remote via /dev/input/event<n> devices.
-The udev/systemd will automatically create the devices. If you install
-the `v4l-utils <https://git.linuxtv.org/v4l-utils.git/>`_, it may also
-automatically load a different keytable than the default one. Please see
-`v4l-utils <https://git.linuxtv.org/v4l-utils.git/>`_ ir-keytable.1
-man page for details.
-
-The ir-keytable tool is nice for trouble shooting, i.e. to check
-whenever the input device is really present, which of the devices it
-is, check whenever pressing keys on the remote actually generates
-events and the like.  You can also use any other input utility that changes
-the keymaps, like the input kbd utility.
-
-
-Using with lircd
-================
-
-The latest versions of the lircd daemon supports reading events from the
-linux input layer (via event device). It also supports receiving IR codes
-in lirc mode.
-
-
-Using without lircd
-===================
-
-Xorg recognizes several IR keycodes that have its numerical value lower
-than 247. With the advent of Wayland, the input driver got updated too,
-and should now accept all keycodes. Yet, you may want to just reasign
-the keycodes to something that your favorite media application likes.
-
-This can be done by setting
-`v4l-utils <https://git.linuxtv.org/v4l-utils.git/>`_ to load your own
-keytable in runtime. Please read  ir-keytable.1 man page for details.
diff --git a/Documentation/media/v4l-drivers/vimc.dot b/Documentation/media/v4l-drivers/vimc.dot
deleted file mode 100644
index 57863a13fa39..000000000000
--- a/Documentation/media/v4l-drivers/vimc.dot
+++ /dev/null
@@ -1,22 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-digraph board {
-	rankdir=TB
-	n00000001 [label="{{} | Sensor A\n/dev/v4l-subdev0 | {<port0> 0}}", shape=Mrecord, style=filled, fillcolor=green]
-	n00000001:port0 -> n00000005:port0 [style=bold]
-	n00000001:port0 -> n0000000b [style=bold]
-	n00000003 [label="{{} | Sensor B\n/dev/v4l-subdev1 | {<port0> 0}}", shape=Mrecord, style=filled, fillcolor=green]
-	n00000003:port0 -> n00000008:port0 [style=bold]
-	n00000003:port0 -> n0000000f [style=bold]
-	n00000005 [label="{{<port0> 0} | Debayer A\n/dev/v4l-subdev2 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
-	n00000005:port1 -> n00000017:port0
-	n00000008 [label="{{<port0> 0} | Debayer B\n/dev/v4l-subdev3 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
-	n00000008:port1 -> n00000017:port0 [style=dashed]
-	n0000000b [label="Raw Capture 0\n/dev/video0", shape=box, style=filled, fillcolor=yellow]
-	n0000000f [label="Raw Capture 1\n/dev/video1", shape=box, style=filled, fillcolor=yellow]
-	n00000013 [label="RGB/YUV Input\n/dev/video2", shape=box, style=filled, fillcolor=yellow]
-	n00000013 -> n00000017:port0 [style=dashed]
-	n00000017 [label="{{<port0> 0} | Scaler\n/dev/v4l-subdev4 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
-	n00000017:port1 -> n0000001a [style=bold]
-	n0000001a [label="RGB/YUV Capture\n/dev/video3", shape=box, style=filled, fillcolor=yellow]
-}
diff --git a/Documentation/media/v4l-drivers/vimc.rst b/Documentation/media/v4l-drivers/vimc.rst
deleted file mode 100644
index 8f5d7f8d83bb..000000000000
--- a/Documentation/media/v4l-drivers/vimc.rst
+++ /dev/null
@@ -1,101 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-The Virtual Media Controller Driver (vimc)
-==========================================
-
-The vimc driver emulates complex video hardware using the V4L2 API and the Media
-API. It has a capture device and three subdevices: sensor, debayer and scaler.
-
-Topology
---------
-
-The topology is hardcoded, although you could modify it in vimc-core and
-recompile the driver to achieve your own topology. This is the default topology:
-
-.. _vimc_topology_graph:
-
-.. kernel-figure:: vimc.dot
-    :alt:   Diagram of the default media pipeline topology
-    :align: center
-
-    Media pipeline graph on vimc
-
-Configuring the topology
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-Each subdevice will come with its default configuration (pixelformat, height,
-width, ...). One needs to configure the topology in order to match the
-configuration on each linked subdevice to stream frames through the pipeline.
-If the configuration doesn't match, the stream will fail. The ``v4l-utils``
-package is a bundle of user-space applications, that comes with ``media-ctl`` and
-``v4l2-ctl`` that can be used to configure the vimc configuration. This sequence
-of commands fits for the default topology:
-
-.. code-block:: bash
-
-        media-ctl -d platform:vimc -V '"Sensor A":0[fmt:SBGGR8_1X8/640x480]'
-        media-ctl -d platform:vimc -V '"Debayer A":0[fmt:SBGGR8_1X8/640x480]'
-        media-ctl -d platform:vimc -V '"Sensor B":0[fmt:SBGGR8_1X8/640x480]'
-        media-ctl -d platform:vimc -V '"Debayer B":0[fmt:SBGGR8_1X8/640x480]'
-        v4l2-ctl -z platform:vimc -d "RGB/YUV Capture" -v width=1920,height=1440
-        v4l2-ctl -z platform:vimc -d "Raw Capture 0" -v pixelformat=BA81
-        v4l2-ctl -z platform:vimc -d "Raw Capture 1" -v pixelformat=BA81
-
-Subdevices
-----------
-
-Subdevices define the behavior of an entity in the topology. Depending on the
-subdevice, the entity can have multiple pads of type source or sink.
-
-vimc-sensor:
-	Generates images in several formats using video test pattern generator.
-	Exposes:
-
-	* 1 Pad source
-
-vimc-debayer:
-	Transforms images in bayer format into a non-bayer format.
-	Exposes:
-
-	* 1 Pad sink
-	* 1 Pad source
-
-vimc-scaler:
-	Scale up the image by a factor of 3. E.g.: a 640x480 image becomes a
-        1920x1440 image. (this value can be configured, see at
-        `Module options`_).
-	Exposes:
-
-	* 1 Pad sink
-	* 1 Pad source
-
-vimc-capture:
-	Exposes node /dev/videoX to allow userspace to capture the stream.
-	Exposes:
-
-	* 1 Pad sink
-	* 1 Pad source
-
-
-Module options
---------------
-
-Vimc has a module parameter to configure the driver.
-
-* ``sca_mult=<unsigned int>``
-
-        Image size multiplier factor to be used to multiply both width and
-        height, so the image size will be ``sca_mult^2`` bigger than the
-        original one. Currently, only supports scaling up (the default value
-        is 3).
-
-Source code documentation
--------------------------
-
-vimc-streamer
-~~~~~~~~~~~~~
-
-.. kernel-doc:: drivers/media/platform/vimc/vimc-streamer.h
-   :internal:
-
-.. kernel-doc:: drivers/media/platform/vimc/vimc-streamer.c
diff --git a/Documentation/media/v4l-drivers/vivid.rst b/Documentation/media/v4l-drivers/vivid.rst
deleted file mode 100644
index 52e57b773f07..000000000000
--- a/Documentation/media/v4l-drivers/vivid.rst
+++ /dev/null
@@ -1,1393 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-The Virtual Video Test Driver (vivid)
-=====================================
-
-This driver emulates video4linux hardware of various types: video capture, video
-output, vbi capture and output, metadata capture and output, radio receivers and
-transmitters, touch capture and a software defined radio receiver. In addition a
-simple framebuffer device is available for testing capture and output overlays.
-
-Up to 64 vivid instances can be created, each with up to 16 inputs and 16 outputs.
-
-Each input can be a webcam, TV capture device, S-Video capture device or an HDMI
-capture device. Each output can be an S-Video output device or an HDMI output
-device.
-
-These inputs and outputs act exactly as a real hardware device would behave. This
-allows you to use this driver as a test input for application development, since
-you can test the various features without requiring special hardware.
-
-This document describes the features implemented by this driver:
-
-- Support for read()/write(), MMAP, USERPTR and DMABUF streaming I/O.
-- A large list of test patterns and variations thereof
-- Working brightness, contrast, saturation and hue controls
-- Support for the alpha color component
-- Full colorspace support, including limited/full RGB range
-- All possible control types are present
-- Support for various pixel aspect ratios and video aspect ratios
-- Error injection to test what happens if errors occur
-- Supports crop/compose/scale in any combination for both input and output
-- Can emulate up to 4K resolutions
-- All Field settings are supported for testing interlaced capturing
-- Supports all standard YUV and RGB formats, including two multiplanar YUV formats
-- Raw and Sliced VBI capture and output support
-- Radio receiver and transmitter support, including RDS support
-- Software defined radio (SDR) support
-- Capture and output overlay support
-- Metadata capture and output support
-- Touch capture support
-
-These features will be described in more detail below.
-
-Configuring the driver
-----------------------
-
-By default the driver will create a single instance that has a video capture
-device with webcam, TV, S-Video and HDMI inputs, a video output device with
-S-Video and HDMI outputs, one vbi capture device, one vbi output device, one
-radio receiver device, one radio transmitter device and one SDR device.
-
-The number of instances, devices, video inputs and outputs and their types are
-all configurable using the following module options:
-
-- n_devs:
-
-	number of driver instances to create. By default set to 1. Up to 64
-	instances can be created.
-
-- node_types:
-
-	which devices should each driver instance create. An array of
-	hexadecimal values, one for each instance. The default is 0x1d3d.
-	Each value is a bitmask with the following meaning:
-
-		- bit 0: Video Capture node
-		- bit 2-3: VBI Capture node: 0 = none, 1 = raw vbi, 2 = sliced vbi, 3 = both
-		- bit 4: Radio Receiver node
-		- bit 5: Software Defined Radio Receiver node
-		- bit 8: Video Output node
-		- bit 10-11: VBI Output node: 0 = none, 1 = raw vbi, 2 = sliced vbi, 3 = both
-		- bit 12: Radio Transmitter node
-		- bit 16: Framebuffer for testing overlays
-		- bit 17: Metadata Capture node
-		- bit 18: Metadata Output node
-		- bit 19: Touch Capture node
-
-	So to create four instances, the first two with just one video capture
-	device, the second two with just one video output device you would pass
-	these module options to vivid:
-
-	.. code-block:: none
-
-		n_devs=4 node_types=0x1,0x1,0x100,0x100
-
-- num_inputs:
-
-	the number of inputs, one for each instance. By default 4 inputs
-	are created for each video capture device. At most 16 inputs can be created,
-	and there must be at least one.
-
-- input_types:
-
-	the input types for each instance, the default is 0xe4. This defines
-	what the type of each input is when the inputs are created for each driver
-	instance. This is a hexadecimal value with up to 16 pairs of bits, each
-	pair gives the type and bits 0-1 map to input 0, bits 2-3 map to input 1,
-	30-31 map to input 15. Each pair of bits has the following meaning:
-
-		- 00: this is a webcam input
-		- 01: this is a TV tuner input
-		- 10: this is an S-Video input
-		- 11: this is an HDMI input
-
-	So to create a video capture device with 8 inputs where input 0 is a TV
-	tuner, inputs 1-3 are S-Video inputs and inputs 4-7 are HDMI inputs you
-	would use the following module options:
-
-	.. code-block:: none
-
-		num_inputs=8 input_types=0xffa9
-
-- num_outputs:
-
-	the number of outputs, one for each instance. By default 2 outputs
-	are created for each video output device. At most 16 outputs can be
-	created, and there must be at least one.
-
-- output_types:
-
-	the output types for each instance, the default is 0x02. This defines
-	what the type of each output is when the outputs are created for each
-	driver instance. This is a hexadecimal value with up to 16 bits, each bit
-	gives the type and bit 0 maps to output 0, bit 1 maps to output 1, bit
-	15 maps to output 15. The meaning of each bit is as follows:
-
-		- 0: this is an S-Video output
-		- 1: this is an HDMI output
-
-	So to create a video output device with 8 outputs where outputs 0-3 are
-	S-Video outputs and outputs 4-7 are HDMI outputs you would use the
-	following module options:
-
-	.. code-block:: none
-
-		num_outputs=8 output_types=0xf0
-
-- vid_cap_nr:
-
-	give the desired videoX start number for each video capture device.
-	The default is -1 which will just take the first free number. This allows
-	you to map capture video nodes to specific videoX device nodes. Example:
-
-	.. code-block:: none
-
-		n_devs=4 vid_cap_nr=2,4,6,8
-
-	This will attempt to assign /dev/video2 for the video capture device of
-	the first vivid instance, video4 for the next up to video8 for the last
-	instance. If it can't succeed, then it will just take the next free
-	number.
-
-- vid_out_nr:
-
-	give the desired videoX start number for each video output device.
-	The default is -1 which will just take the first free number.
-
-- vbi_cap_nr:
-
-	give the desired vbiX start number for each vbi capture device.
-	The default is -1 which will just take the first free number.
-
-- vbi_out_nr:
-
-	give the desired vbiX start number for each vbi output device.
-	The default is -1 which will just take the first free number.
-
-- radio_rx_nr:
-
-	give the desired radioX start number for each radio receiver device.
-	The default is -1 which will just take the first free number.
-
-- radio_tx_nr:
-
-	give the desired radioX start number for each radio transmitter
-	device. The default is -1 which will just take the first free number.
-
-- sdr_cap_nr:
-
-	give the desired swradioX start number for each SDR capture device.
-	The default is -1 which will just take the first free number.
-
-- meta_cap_nr:
-
-        give the desired videoX start number for each metadata capture device.
-        The default is -1 which will just take the first free number.
-
-- meta_out_nr:
-
-        give the desired videoX start number for each metadata output device.
-        The default is -1 which will just take the first free number.
-
-- touch_cap_nr:
-
-        give the desired v4l-touchX start number for each touch capture device.
-        The default is -1 which will just take the first free number.
-
-- ccs_cap_mode:
-
-	specify the allowed video capture crop/compose/scaling combination
-	for each driver instance. Video capture devices can have any combination
-	of cropping, composing and scaling capabilities and this will tell the
-	vivid driver which of those is should emulate. By default the user can
-	select this through controls.
-
-	The value is either -1 (controlled by the user) or a set of three bits,
-	each enabling (1) or disabling (0) one of the features:
-
-	- bit 0:
-
-		Enable crop support. Cropping will take only part of the
-		incoming picture.
-	- bit 1:
-
-		Enable compose support. Composing will copy the incoming
-		picture into a larger buffer.
-
-	- bit 2:
-
-		Enable scaling support. Scaling can scale the incoming
-		picture. The scaler of the vivid driver can enlarge up
-		or down to four times the original size. The scaler is
-		very simple and low-quality. Simplicity and speed were
-		key, not quality.
-
-	Note that this value is ignored by webcam inputs: those enumerate
-	discrete framesizes and that is incompatible with cropping, composing
-	or scaling.
-
-- ccs_out_mode:
-
-	specify the allowed video output crop/compose/scaling combination
-	for each driver instance. Video output devices can have any combination
-	of cropping, composing and scaling capabilities and this will tell the
-	vivid driver which of those is should emulate. By default the user can
-	select this through controls.
-
-	The value is either -1 (controlled by the user) or a set of three bits,
-	each enabling (1) or disabling (0) one of the features:
-
-	- bit 0:
-
-		Enable crop support. Cropping will take only part of the
-		outgoing buffer.
-
-	- bit 1:
-
-		Enable compose support. Composing will copy the incoming
-		buffer into a larger picture frame.
-
-	- bit 2:
-
-		Enable scaling support. Scaling can scale the incoming
-		buffer. The scaler of the vivid driver can enlarge up
-		or down to four times the original size. The scaler is
-		very simple and low-quality. Simplicity and speed were
-		key, not quality.
-
-- multiplanar:
-
-	select whether each device instance supports multi-planar formats,
-	and thus the V4L2 multi-planar API. By default device instances are
-	single-planar.
-
-	This module option can override that for each instance. Values are:
-
-		- 1: this is a single-planar instance.
-		- 2: this is a multi-planar instance.
-
-- vivid_debug:
-
-	enable driver debugging info
-
-- no_error_inj:
-
-	if set disable the error injecting controls. This option is
-	needed in order to run a tool like v4l2-compliance. Tools like that
-	exercise all controls including a control like 'Disconnect' which
-	emulates a USB disconnect, making the device inaccessible and so
-	all tests that v4l2-compliance is doing will fail afterwards.
-
-	There may be other situations as well where you want to disable the
-	error injection support of vivid. When this option is set, then the
-	controls that select crop, compose and scale behavior are also
-	removed. Unless overridden by ccs_cap_mode and/or ccs_out_mode the
-	will default to enabling crop, compose and scaling.
-
-- allocators:
-
-	memory allocator selection, default is 0. It specifies the way buffers
-	will be allocated.
-
-		- 0: vmalloc
-		- 1: dma-contig
-
-Taken together, all these module options allow you to precisely customize
-the driver behavior and test your application with all sorts of permutations.
-It is also very suitable to emulate hardware that is not yet available, e.g.
-when developing software for a new upcoming device.
-
-
-Video Capture
--------------
-
-This is probably the most frequently used feature. The video capture device
-can be configured by using the module options num_inputs, input_types and
-ccs_cap_mode (see section 1 for more detailed information), but by default
-four inputs are configured: a webcam, a TV tuner, an S-Video and an HDMI
-input, one input for each input type. Those are described in more detail
-below.
-
-Special attention has been given to the rate at which new frames become
-available. The jitter will be around 1 jiffie (that depends on the HZ
-configuration of your kernel, so usually 1/100, 1/250 or 1/1000 of a second),
-but the long-term behavior is exactly following the framerate. So a
-framerate of 59.94 Hz is really different from 60 Hz. If the framerate
-exceeds your kernel's HZ value, then you will get dropped frames, but the
-frame/field sequence counting will keep track of that so the sequence
-count will skip whenever frames are dropped.
-
-
-Webcam Input
-~~~~~~~~~~~~
-
-The webcam input supports three framesizes: 320x180, 640x360 and 1280x720. It
-supports frames per second settings of 10, 15, 25, 30, 50 and 60 fps. Which ones
-are available depends on the chosen framesize: the larger the framesize, the
-lower the maximum frames per second.
-
-The initially selected colorspace when you switch to the webcam input will be
-sRGB.
-
-
-TV and S-Video Inputs
-~~~~~~~~~~~~~~~~~~~~~
-
-The only difference between the TV and S-Video input is that the TV has a
-tuner. Otherwise they behave identically.
-
-These inputs support audio inputs as well: one TV and one Line-In. They
-both support all TV standards. If the standard is queried, then the Vivid
-controls 'Standard Signal Mode' and 'Standard' determine what
-the result will be.
-
-These inputs support all combinations of the field setting. Special care has
-been taken to faithfully reproduce how fields are handled for the different
-TV standards. This is particularly noticeable when generating a horizontally
-moving image so the temporal effect of using interlaced formats becomes clearly
-visible. For 50 Hz standards the top field is the oldest and the bottom field
-is the newest in time. For 60 Hz standards that is reversed: the bottom field
-is the oldest and the top field is the newest in time.
-
-When you start capturing in V4L2_FIELD_ALTERNATE mode the first buffer will
-contain the top field for 50 Hz standards and the bottom field for 60 Hz
-standards. This is what capture hardware does as well.
-
-Finally, for PAL/SECAM standards the first half of the top line contains noise.
-This simulates the Wide Screen Signal that is commonly placed there.
-
-The initially selected colorspace when you switch to the TV or S-Video input
-will be SMPTE-170M.
-
-The pixel aspect ratio will depend on the TV standard. The video aspect ratio
-can be selected through the 'Standard Aspect Ratio' Vivid control.
-Choices are '4x3', '16x9' which will give letterboxed widescreen video and
-'16x9 Anamorphic' which will give full screen squashed anamorphic widescreen
-video that will need to be scaled accordingly.
-
-The TV 'tuner' supports a frequency range of 44-958 MHz. Channels are available
-every 6 MHz, starting from 49.25 MHz. For each channel the generated image
-will be in color for the +/- 0.25 MHz around it, and in grayscale for
-+/- 1 MHz around the channel. Beyond that it is just noise. The VIDIOC_G_TUNER
-ioctl will return 100% signal strength for +/- 0.25 MHz and 50% for +/- 1 MHz.
-It will also return correct afc values to show whether the frequency is too
-low or too high.
-
-The audio subchannels that are returned are MONO for the +/- 1 MHz range around
-a valid channel frequency. When the frequency is within +/- 0.25 MHz of the
-channel it will return either MONO, STEREO, either MONO | SAP (for NTSC) or
-LANG1 | LANG2 (for others), or STEREO | SAP.
-
-Which one is returned depends on the chosen channel, each next valid channel
-will cycle through the possible audio subchannel combinations. This allows
-you to test the various combinations by just switching channels..
-
-Finally, for these inputs the v4l2_timecode struct is filled in in the
-dequeued v4l2_buffer struct.
-
-
-HDMI Input
-~~~~~~~~~~
-
-The HDMI inputs supports all CEA-861 and DMT timings, both progressive and
-interlaced, for pixelclock frequencies between 25 and 600 MHz. The field
-mode for interlaced formats is always V4L2_FIELD_ALTERNATE. For HDMI the
-field order is always top field first, and when you start capturing an
-interlaced format you will receive the top field first.
-
-The initially selected colorspace when you switch to the HDMI input or
-select an HDMI timing is based on the format resolution: for resolutions
-less than or equal to 720x576 the colorspace is set to SMPTE-170M, for
-others it is set to REC-709 (CEA-861 timings) or sRGB (VESA DMT timings).
-
-The pixel aspect ratio will depend on the HDMI timing: for 720x480 is it
-set as for the NTSC TV standard, for 720x576 it is set as for the PAL TV
-standard, and for all others a 1:1 pixel aspect ratio is returned.
-
-The video aspect ratio can be selected through the 'DV Timings Aspect Ratio'
-Vivid control. Choices are 'Source Width x Height' (just use the
-same ratio as the chosen format), '4x3' or '16x9', either of which can
-result in pillarboxed or letterboxed video.
-
-For HDMI inputs it is possible to set the EDID. By default a simple EDID
-is provided. You can only set the EDID for HDMI inputs. Internally, however,
-the EDID is shared between all HDMI inputs.
-
-No interpretation is done of the EDID data with the exception of the
-physical address. See the CEC section for more details.
-
-There is a maximum of 15 HDMI inputs (if there are more, then they will be
-reduced to 15) since that's the limitation of the EDID physical address.
-
-
-Video Output
-------------
-
-The video output device can be configured by using the module options
-num_outputs, output_types and ccs_out_mode (see section 1 for more detailed
-information), but by default two outputs are configured: an S-Video and an
-HDMI input, one output for each output type. Those are described in more detail
-below.
-
-Like with video capture the framerate is also exact in the long term.
-
-
-S-Video Output
-~~~~~~~~~~~~~~
-
-This output supports audio outputs as well: "Line-Out 1" and "Line-Out 2".
-The S-Video output supports all TV standards.
-
-This output supports all combinations of the field setting.
-
-The initially selected colorspace when you switch to the TV or S-Video input
-will be SMPTE-170M.
-
-
-HDMI Output
-~~~~~~~~~~~
-
-The HDMI output supports all CEA-861 and DMT timings, both progressive and
-interlaced, for pixelclock frequencies between 25 and 600 MHz. The field
-mode for interlaced formats is always V4L2_FIELD_ALTERNATE.
-
-The initially selected colorspace when you switch to the HDMI output or
-select an HDMI timing is based on the format resolution: for resolutions
-less than or equal to 720x576 the colorspace is set to SMPTE-170M, for
-others it is set to REC-709 (CEA-861 timings) or sRGB (VESA DMT timings).
-
-The pixel aspect ratio will depend on the HDMI timing: for 720x480 is it
-set as for the NTSC TV standard, for 720x576 it is set as for the PAL TV
-standard, and for all others a 1:1 pixel aspect ratio is returned.
-
-An HDMI output has a valid EDID which can be obtained through VIDIOC_G_EDID.
-
-There is a maximum of 15 HDMI outputs (if there are more, then they will be
-reduced to 15) since that's the limitation of the EDID physical address. See
-also the CEC section for more details.
-
-VBI Capture
------------
-
-There are three types of VBI capture devices: those that only support raw
-(undecoded) VBI, those that only support sliced (decoded) VBI and those that
-support both. This is determined by the node_types module option. In all
-cases the driver will generate valid VBI data: for 60 Hz standards it will
-generate Closed Caption and XDS data. The closed caption stream will
-alternate between "Hello world!" and "Closed captions test" every second.
-The XDS stream will give the current time once a minute. For 50 Hz standards
-it will generate the Wide Screen Signal which is based on the actual Video
-Aspect Ratio control setting and teletext pages 100-159, one page per frame.
-
-The VBI device will only work for the S-Video and TV inputs, it will give
-back an error if the current input is a webcam or HDMI.
-
-
-VBI Output
-----------
-
-There are three types of VBI output devices: those that only support raw
-(undecoded) VBI, those that only support sliced (decoded) VBI and those that
-support both. This is determined by the node_types module option.
-
-The sliced VBI output supports the Wide Screen Signal and the teletext signal
-for 50 Hz standards and Closed Captioning + XDS for 60 Hz standards.
-
-The VBI device will only work for the S-Video output, it will give
-back an error if the current output is HDMI.
-
-
-Radio Receiver
---------------
-
-The radio receiver emulates an FM/AM/SW receiver. The FM band also supports RDS.
-The frequency ranges are:
-
-	- FM: 64 MHz - 108 MHz
-	- AM: 520 kHz - 1710 kHz
-	- SW: 2300 kHz - 26.1 MHz
-
-Valid channels are emulated every 1 MHz for FM and every 100 kHz for AM and SW.
-The signal strength decreases the further the frequency is from the valid
-frequency until it becomes 0% at +/- 50 kHz (FM) or 5 kHz (AM/SW) from the
-ideal frequency. The initial frequency when the driver is loaded is set to
-95 MHz.
-
-The FM receiver supports RDS as well, both using 'Block I/O' and 'Controls'
-modes. In the 'Controls' mode the RDS information is stored in read-only
-controls. These controls are updated every time the frequency is changed,
-or when the tuner status is requested. The Block I/O method uses the read()
-interface to pass the RDS blocks on to the application for decoding.
-
-The RDS signal is 'detected' for +/- 12.5 kHz around the channel frequency,
-and the further the frequency is away from the valid frequency the more RDS
-errors are randomly introduced into the block I/O stream, up to 50% of all
-blocks if you are +/- 12.5 kHz from the channel frequency. All four errors
-can occur in equal proportions: blocks marked 'CORRECTED', blocks marked
-'ERROR', blocks marked 'INVALID' and dropped blocks.
-
-The generated RDS stream contains all the standard fields contained in a
-0B group, and also radio text and the current time.
-
-The receiver supports HW frequency seek, either in Bounded mode, Wrap Around
-mode or both, which is configurable with the "Radio HW Seek Mode" control.
-
-
-Radio Transmitter
------------------
-
-The radio transmitter emulates an FM/AM/SW transmitter. The FM band also supports RDS.
-The frequency ranges are:
-
-	- FM: 64 MHz - 108 MHz
-	- AM: 520 kHz - 1710 kHz
-	- SW: 2300 kHz - 26.1 MHz
-
-The initial frequency when the driver is loaded is 95.5 MHz.
-
-The FM transmitter supports RDS as well, both using 'Block I/O' and 'Controls'
-modes. In the 'Controls' mode the transmitted RDS information is configured
-using controls, and in 'Block I/O' mode the blocks are passed to the driver
-using write().
-
-
-Software Defined Radio Receiver
--------------------------------
-
-The SDR receiver has three frequency bands for the ADC tuner:
-
-	- 300 kHz
-	- 900 kHz - 2800 kHz
-	- 3200 kHz
-
-The RF tuner supports 50 MHz - 2000 MHz.
-
-The generated data contains the In-phase and Quadrature components of a
-1 kHz tone that has an amplitude of sqrt(2).
-
-
-Metadata Capture
-----------------
-
-The Metadata capture generates UVC format metadata. The PTS and SCR are
-transmitted based on the values set in vivid contols.
-
-The Metadata device will only work for the Webcam input, it will give
-back an error for all other inputs.
-
-
-Metadata Output
----------------
-
-The Metadata output can be used to set brightness, contrast, saturation and hue.
-
-The Metadata device will only work for the Webcam output, it will give
-back an error for all other outputs.
-
-
-Touch Capture
--------------
-
-The Touch capture generates touch patterns simulating single tap, double tap,
-triple tap, move from left to right, zoom in, zoom out, palm press (simulating
-a large area being pressed on a touchpad), and simulating 16 simultaneous
-touch points.
-
-Controls
---------
-
-Different devices support different controls. The sections below will describe
-each control and which devices support them.
-
-
-User Controls - Test Controls
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The Button, Boolean, Integer 32 Bits, Integer 64 Bits, Menu, String, Bitmask and
-Integer Menu are controls that represent all possible control types. The Menu
-control and the Integer Menu control both have 'holes' in their menu list,
-meaning that one or more menu items return EINVAL when VIDIOC_QUERYMENU is called.
-Both menu controls also have a non-zero minimum control value.  These features
-allow you to check if your application can handle such things correctly.
-These controls are supported for every device type.
-
-
-User Controls - Video Capture
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The following controls are specific to video capture.
-
-The Brightness, Contrast, Saturation and Hue controls actually work and are
-standard. There is one special feature with the Brightness control: each
-video input has its own brightness value, so changing input will restore
-the brightness for that input. In addition, each video input uses a different
-brightness range (minimum and maximum control values). Switching inputs will
-cause a control event to be sent with the V4L2_EVENT_CTRL_CH_RANGE flag set.
-This allows you to test controls that can change their range.
-
-The 'Gain, Automatic' and Gain controls can be used to test volatile controls:
-if 'Gain, Automatic' is set, then the Gain control is volatile and changes
-constantly. If 'Gain, Automatic' is cleared, then the Gain control is a normal
-control.
-
-The 'Horizontal Flip' and 'Vertical Flip' controls can be used to flip the
-image. These combine with the 'Sensor Flipped Horizontally/Vertically' Vivid
-controls.
-
-The 'Alpha Component' control can be used to set the alpha component for
-formats containing an alpha channel.
-
-
-User Controls - Audio
-~~~~~~~~~~~~~~~~~~~~~
-
-The following controls are specific to video capture and output and radio
-receivers and transmitters.
-
-The 'Volume' and 'Mute' audio controls are typical for such devices to
-control the volume and mute the audio. They don't actually do anything in
-the vivid driver.
-
-
-Vivid Controls
-~~~~~~~~~~~~~~
-
-These vivid custom controls control the image generation, error injection, etc.
-
-
-Test Pattern Controls
-^^^^^^^^^^^^^^^^^^^^^
-
-The Test Pattern Controls are all specific to video capture.
-
-- Test Pattern:
-
-	selects which test pattern to use. Use the CSC Colorbar for
-	testing colorspace conversions: the colors used in that test pattern
-	map to valid colors in all colorspaces. The colorspace conversion
-	is disabled for the other test patterns.
-
-- OSD Text Mode:
-
-	selects whether the text superimposed on the
-	test pattern should be shown, and if so, whether only counters should
-	be displayed or the full text.
-
-- Horizontal Movement:
-
-	selects whether the test pattern should
-	move to the left or right and at what speed.
-
-- Vertical Movement:
-
-	does the same for the vertical direction.
-
-- Show Border:
-
-	show a two-pixel wide border at the edge of the actual image,
-	excluding letter or pillarboxing.
-
-- Show Square:
-
-	show a square in the middle of the image. If the image is
-	displayed with the correct pixel and image aspect ratio corrections,
-	then the width and height of the square on the monitor should be
-	the same.
-
-- Insert SAV Code in Image:
-
-	adds a SAV (Start of Active Video) code to the image.
-	This can be used to check if such codes in the image are inadvertently
-	interpreted instead of being ignored.
-
-- Insert EAV Code in Image:
-
-	does the same for the EAV (End of Active Video) code.
-
-
-Capture Feature Selection Controls
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-These controls are all specific to video capture.
-
-- Sensor Flipped Horizontally:
-
-	the image is flipped horizontally and the
-	V4L2_IN_ST_HFLIP input status flag is set. This emulates the case where
-	a sensor is for example mounted upside down.
-
-- Sensor Flipped Vertically:
-
-	the image is flipped vertically and the
-	V4L2_IN_ST_VFLIP input status flag is set. This emulates the case where
-	a sensor is for example mounted upside down.
-
-- Standard Aspect Ratio:
-
-	selects if the image aspect ratio as used for the TV or
-	S-Video input should be 4x3, 16x9 or anamorphic widescreen. This may
-	introduce letterboxing.
-
-- DV Timings Aspect Ratio:
-
-	selects if the image aspect ratio as used for the HDMI
-	input should be the same as the source width and height ratio, or if
-	it should be 4x3 or 16x9. This may introduce letter or pillarboxing.
-
-- Timestamp Source:
-
-	selects when the timestamp for each buffer is taken.
-
-- Colorspace:
-
-	selects which colorspace should be used when generating the image.
-	This only applies if the CSC Colorbar test pattern is selected,
-	otherwise the test pattern will go through unconverted.
-	This behavior is also what you want, since a 75% Colorbar
-	should really have 75% signal intensity and should not be affected
-	by colorspace conversions.
-
-	Changing the colorspace will result in the V4L2_EVENT_SOURCE_CHANGE
-	to be sent since it emulates a detected colorspace change.
-
-- Transfer Function:
-
-	selects which colorspace transfer function should be used when
-	generating an image. This only applies if the CSC Colorbar test pattern is
-	selected, otherwise the test pattern will go through unconverted.
-	This behavior is also what you want, since a 75% Colorbar
-	should really have 75% signal intensity and should not be affected
-	by colorspace conversions.
-
-	Changing the transfer function will result in the V4L2_EVENT_SOURCE_CHANGE
-	to be sent since it emulates a detected colorspace change.
-
-- Y'CbCr Encoding:
-
-	selects which Y'CbCr encoding should be used when generating
-	a Y'CbCr image.	This only applies if the format is set to a Y'CbCr format
-	as opposed to an RGB format.
-
-	Changing the Y'CbCr encoding will result in the V4L2_EVENT_SOURCE_CHANGE
-	to be sent since it emulates a detected colorspace change.
-
-- Quantization:
-
-	selects which quantization should be used for the RGB or Y'CbCr
-	encoding when generating the test pattern.
-
-	Changing the quantization will result in the V4L2_EVENT_SOURCE_CHANGE
-	to be sent since it emulates a detected colorspace change.
-
-- Limited RGB Range (16-235):
-
-	selects if the RGB range of the HDMI source should
-	be limited or full range. This combines with the Digital Video 'Rx RGB
-	Quantization Range' control and can be used to test what happens if
-	a source provides you with the wrong quantization range information.
-	See the description of that control for more details.
-
-- Apply Alpha To Red Only:
-
-	apply the alpha channel as set by the 'Alpha Component'
-	user control to the red color of the test pattern only.
-
-- Enable Capture Cropping:
-
-	enables crop support. This control is only present if
-	the ccs_cap_mode module option is set to the default value of -1 and if
-	the no_error_inj module option is set to 0 (the default).
-
-- Enable Capture Composing:
-
-	enables composing support. This control is only
-	present if the ccs_cap_mode module option is set to the default value of
-	-1 and if the no_error_inj module option is set to 0 (the default).
-
-- Enable Capture Scaler:
-
-	enables support for a scaler (maximum 4 times upscaling
-	and downscaling). This control is only present if the ccs_cap_mode
-	module option is set to the default value of -1 and if the no_error_inj
-	module option is set to 0 (the default).
-
-- Maximum EDID Blocks:
-
-	determines how many EDID blocks the driver supports.
-	Note that the vivid driver does not actually interpret new EDID
-	data, it just stores it. It allows for up to 256 EDID blocks
-	which is the maximum supported by the standard.
-
-- Fill Percentage of Frame:
-
-	can be used to draw only the top X percent
-	of the image. Since each frame has to be drawn by the driver, this
-	demands a lot of the CPU. For large resolutions this becomes
-	problematic. By drawing only part of the image this CPU load can
-	be reduced.
-
-
-Output Feature Selection Controls
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-These controls are all specific to video output.
-
-- Enable Output Cropping:
-
-	enables crop support. This control is only present if
-	the ccs_out_mode module option is set to the default value of -1 and if
-	the no_error_inj module option is set to 0 (the default).
-
-- Enable Output Composing:
-
-	enables composing support. This control is only
-	present if the ccs_out_mode module option is set to the default value of
-	-1 and if the no_error_inj module option is set to 0 (the default).
-
-- Enable Output Scaler:
-
-	enables support for a scaler (maximum 4 times upscaling
-	and downscaling). This control is only present if the ccs_out_mode
-	module option is set to the default value of -1 and if the no_error_inj
-	module option is set to 0 (the default).
-
-
-Error Injection Controls
-^^^^^^^^^^^^^^^^^^^^^^^^
-
-The following two controls are only valid for video and vbi capture.
-
-- Standard Signal Mode:
-
-	selects the behavior of VIDIOC_QUERYSTD: what should it return?
-
-	Changing this control will result in the V4L2_EVENT_SOURCE_CHANGE
-	to be sent since it emulates a changed input condition (e.g. a cable
-	was plugged in or out).
-
-- Standard:
-
-	selects the standard that VIDIOC_QUERYSTD should return if the
-	previous control is set to "Selected Standard".
-
-	Changing this control will result in the V4L2_EVENT_SOURCE_CHANGE
-	to be sent since it emulates a changed input standard.
-
-
-The following two controls are only valid for video capture.
-
-- DV Timings Signal Mode:
-
-	selects the behavior of VIDIOC_QUERY_DV_TIMINGS: what
-	should it return?
-
-	Changing this control will result in the V4L2_EVENT_SOURCE_CHANGE
-	to be sent since it emulates a changed input condition (e.g. a cable
-	was plugged in or out).
-
-- DV Timings:
-
-	selects the timings the VIDIOC_QUERY_DV_TIMINGS should return
-	if the previous control is set to "Selected DV Timings".
-
-	Changing this control will result in the V4L2_EVENT_SOURCE_CHANGE
-	to be sent since it emulates changed input timings.
-
-
-The following controls are only present if the no_error_inj module option
-is set to 0 (the default). These controls are valid for video and vbi
-capture and output streams and for the SDR capture device except for the
-Disconnect control which is valid for all devices.
-
-- Wrap Sequence Number:
-
-	test what happens when you wrap the sequence number in
-	struct v4l2_buffer around.
-
-- Wrap Timestamp:
-
-	test what happens when you wrap the timestamp in struct
-	v4l2_buffer around.
-
-- Percentage of Dropped Buffers:
-
-	sets the percentage of buffers that
-	are never returned by the driver (i.e., they are dropped).
-
-- Disconnect:
-
-	emulates a USB disconnect. The device will act as if it has
-	been disconnected. Only after all open filehandles to the device
-	node have been closed will the device become 'connected' again.
-
-- Inject V4L2_BUF_FLAG_ERROR:
-
-	when pressed, the next frame returned by
-	the driver will have the error flag set (i.e. the frame is marked
-	corrupt).
-
-- Inject VIDIOC_REQBUFS Error:
-
-	when pressed, the next REQBUFS or CREATE_BUFS
-	ioctl call will fail with an error. To be precise: the videobuf2
-	queue_setup() op will return -EINVAL.
-
-- Inject VIDIOC_QBUF Error:
-
-	when pressed, the next VIDIOC_QBUF or
-	VIDIOC_PREPARE_BUFFER ioctl call will fail with an error. To be
-	precise: the videobuf2 buf_prepare() op will return -EINVAL.
-
-- Inject VIDIOC_STREAMON Error:
-
-	when pressed, the next VIDIOC_STREAMON ioctl
-	call will fail with an error. To be precise: the videobuf2
-	start_streaming() op will return -EINVAL.
-
-- Inject Fatal Streaming Error:
-
-	when pressed, the streaming core will be
-	marked as having suffered a fatal error, the only way to recover
-	from that is to stop streaming. To be precise: the videobuf2
-	vb2_queue_error() function is called.
-
-
-VBI Raw Capture Controls
-^^^^^^^^^^^^^^^^^^^^^^^^
-
-- Interlaced VBI Format:
-
-	if set, then the raw VBI data will be interlaced instead
-	of providing it grouped by field.
-
-
-Digital Video Controls
-~~~~~~~~~~~~~~~~~~~~~~
-
-- Rx RGB Quantization Range:
-
-	sets the RGB quantization detection of the HDMI
-	input. This combines with the Vivid 'Limited RGB Range (16-235)'
-	control and can be used to test what happens if a source provides
-	you with the wrong quantization range information. This can be tested
-	by selecting an HDMI input, setting this control to Full or Limited
-	range and selecting the opposite in the 'Limited RGB Range (16-235)'
-	control. The effect is easy to see if the 'Gray Ramp' test pattern
-	is selected.
-
-- Tx RGB Quantization Range:
-
-	sets the RGB quantization detection of the HDMI
-	output. It is currently not used for anything in vivid, but most HDMI
-	transmitters would typically have this control.
-
-- Transmit Mode:
-
-	sets the transmit mode of the HDMI output to HDMI or DVI-D. This
-	affects the reported colorspace since DVI_D outputs will always use
-	sRGB.
-
-- Display Present:
-
-	sets the presence of a "display" on the HDMI output. This affects
-	the tx_edid_present, tx_hotplug and tx_rxsense controls.
-
-
-FM Radio Receiver Controls
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-- RDS Reception:
-
-	set if the RDS receiver should be enabled.
-
-- RDS Program Type:
-
-
-- RDS PS Name:
-
-
-- RDS Radio Text:
-
-
-- RDS Traffic Announcement:
-
-
-- RDS Traffic Program:
-
-
-- RDS Music:
-
-	these are all read-only controls. If RDS Rx I/O Mode is set to
-	"Block I/O", then they are inactive as well. If RDS Rx I/O Mode is set
-	to "Controls", then these controls report the received RDS data.
-
-.. note::
-	The vivid implementation of this is pretty basic: they are only
-	updated when you set a new frequency or when you get the tuner status
-	(VIDIOC_G_TUNER).
-
-- Radio HW Seek Mode:
-
-	can be one of "Bounded", "Wrap Around" or "Both". This
-	determines if VIDIOC_S_HW_FREQ_SEEK will be bounded by the frequency
-	range or wrap-around or if it is selectable by the user.
-
-- Radio Programmable HW Seek:
-
-	if set, then the user can provide the lower and
-	upper bound of the HW Seek. Otherwise the frequency range boundaries
-	will be used.
-
-- Generate RBDS Instead of RDS:
-
-	if set, then generate RBDS (the US variant of
-	RDS) data instead of RDS (European-style RDS). This affects only the
-	PICODE and PTY codes.
-
-- RDS Rx I/O Mode:
-
-	this can be "Block I/O" where the RDS blocks have to be read()
-	by the application, or "Controls" where the RDS data is provided by
-	the RDS controls mentioned above.
-
-
-FM Radio Modulator Controls
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-- RDS Program ID:
-
-
-- RDS Program Type:
-
-
-- RDS PS Name:
-
-
-- RDS Radio Text:
-
-
-- RDS Stereo:
-
-
-- RDS Artificial Head:
-
-
-- RDS Compressed:
-
-
-- RDS Dynamic PTY:
-
-
-- RDS Traffic Announcement:
-
-
-- RDS Traffic Program:
-
-
-- RDS Music:
-
-	these are all controls that set the RDS data that is transmitted by
-	the FM modulator.
-
-- RDS Tx I/O Mode:
-
-	this can be "Block I/O" where the application has to use write()
-	to pass the RDS blocks to the driver, or "Controls" where the RDS data
-	is Provided by the RDS controls mentioned above.
-
-Metadata Capture Controls
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-- Generate PTS
-
-        if set, then the generated metadata stream contains Presentation timestamp.
-
-- Generate SCR
-
-        if set, then the generated metadata stream contains Source Clock information.
-
-Video, VBI and RDS Looping
---------------------------
-
-The vivid driver supports looping of video output to video input, VBI output
-to VBI input and RDS output to RDS input. For video/VBI looping this emulates
-as if a cable was hooked up between the output and input connector. So video
-and VBI looping is only supported between S-Video and HDMI inputs and outputs.
-VBI is only valid for S-Video as it makes no sense for HDMI.
-
-Since radio is wireless this looping always happens if the radio receiver
-frequency is close to the radio transmitter frequency. In that case the radio
-transmitter will 'override' the emulated radio stations.
-
-Looping is currently supported only between devices created by the same
-vivid driver instance.
-
-
-Video and Sliced VBI looping
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The way to enable video/VBI looping is currently fairly crude. A 'Loop Video'
-control is available in the "Vivid" control class of the video
-capture and VBI capture devices. When checked the video looping will be enabled.
-Once enabled any video S-Video or HDMI input will show a static test pattern
-until the video output has started. At that time the video output will be
-looped to the video input provided that:
-
-- the input type matches the output type. So the HDMI input cannot receive
-  video from the S-Video output.
-
-- the video resolution of the video input must match that of the video output.
-  So it is not possible to loop a 50 Hz (720x576) S-Video output to a 60 Hz
-  (720x480) S-Video input, or a 720p60 HDMI output to a 1080p30 input.
-
-- the pixel formats must be identical on both sides. Otherwise the driver would
-  have to do pixel format conversion as well, and that's taking things too far.
-
-- the field settings must be identical on both sides. Same reason as above:
-  requiring the driver to convert from one field format to another complicated
-  matters too much. This also prohibits capturing with 'Field Top' or 'Field
-  Bottom' when the output video is set to 'Field Alternate'. This combination,
-  while legal, became too complicated to support. Both sides have to be 'Field
-  Alternate' for this to work. Also note that for this specific case the
-  sequence and field counting in struct v4l2_buffer on the capture side may not
-  be 100% accurate.
-
-- field settings V4L2_FIELD_SEQ_TB/BT are not supported. While it is possible to
-  implement this, it would mean a lot of work to get this right. Since these
-  field values are rarely used the decision was made not to implement this for
-  now.
-
-- on the input side the "Standard Signal Mode" for the S-Video input or the
-  "DV Timings Signal Mode" for the HDMI input should be configured so that a
-  valid signal is passed to the video input.
-
-The framerates do not have to match, although this might change in the future.
-
-By default you will see the OSD text superimposed on top of the looped video.
-This can be turned off by changing the "OSD Text Mode" control of the video
-capture device.
-
-For VBI looping to work all of the above must be valid and in addition the vbi
-output must be configured for sliced VBI. The VBI capture side can be configured
-for either raw or sliced VBI. Note that at the moment only CC/XDS (60 Hz formats)
-and WSS (50 Hz formats) VBI data is looped. Teletext VBI data is not looped.
-
-
-Radio & RDS Looping
-~~~~~~~~~~~~~~~~~~~
-
-As mentioned in section 6 the radio receiver emulates stations are regular
-frequency intervals. Depending on the frequency of the radio receiver a
-signal strength value is calculated (this is returned by VIDIOC_G_TUNER).
-However, it will also look at the frequency set by the radio transmitter and
-if that results in a higher signal strength than the settings of the radio
-transmitter will be used as if it was a valid station. This also includes
-the RDS data (if any) that the transmitter 'transmits'. This is received
-faithfully on the receiver side. Note that when the driver is loaded the
-frequencies of the radio receiver and transmitter are not identical, so
-initially no looping takes place.
-
-
-Cropping, Composing, Scaling
-----------------------------
-
-This driver supports cropping, composing and scaling in any combination. Normally
-which features are supported can be selected through the Vivid controls,
-but it is also possible to hardcode it when the module is loaded through the
-ccs_cap_mode and ccs_out_mode module options. See section 1 on the details of
-these module options.
-
-This allows you to test your application for all these variations.
-
-Note that the webcam input never supports cropping, composing or scaling. That
-only applies to the TV/S-Video/HDMI inputs and outputs. The reason is that
-webcams, including this virtual implementation, normally use
-VIDIOC_ENUM_FRAMESIZES to list a set of discrete framesizes that it supports.
-And that does not combine with cropping, composing or scaling. This is
-primarily a limitation of the V4L2 API which is carefully reproduced here.
-
-The minimum and maximum resolutions that the scaler can achieve are 16x16 and
-(4096 * 4) x (2160 x 4), but it can only scale up or down by a factor of 4 or
-less. So for a source resolution of 1280x720 the minimum the scaler can do is
-320x180 and the maximum is 5120x2880. You can play around with this using the
-qv4l2 test tool and you will see these dependencies.
-
-This driver also supports larger 'bytesperline' settings, something that
-VIDIOC_S_FMT allows but that few drivers implement.
-
-The scaler is a simple scaler that uses the Coarse Bresenham algorithm. It's
-designed for speed and simplicity, not quality.
-
-If the combination of crop, compose and scaling allows it, then it is possible
-to change crop and compose rectangles on the fly.
-
-
-Formats
--------
-
-The driver supports all the regular packed and planar 4:4:4, 4:2:2 and 4:2:0
-YUYV formats, 8, 16, 24 and 32 RGB packed formats and various multiplanar
-formats.
-
-The alpha component can be set through the 'Alpha Component' User control
-for those formats that support it. If the 'Apply Alpha To Red Only' control
-is set, then the alpha component is only used for the color red and set to
-0 otherwise.
-
-The driver has to be configured to support the multiplanar formats. By default
-the driver instances are single-planar. This can be changed by setting the
-multiplanar module option, see section 1 for more details on that option.
-
-If the driver instance is using the multiplanar formats/API, then the first
-single planar format (YUYV) and the multiplanar NV16M and NV61M formats the
-will have a plane that has a non-zero data_offset of 128 bytes. It is rare for
-data_offset to be non-zero, so this is a useful feature for testing applications.
-
-Video output will also honor any data_offset that the application set.
-
-
-Capture Overlay
----------------
-
-Note: capture overlay support is implemented primarily to test the existing
-V4L2 capture overlay API. In practice few if any GPUs support such overlays
-anymore, and neither are they generally needed anymore since modern hardware
-is so much more capable. By setting flag 0x10000 in the node_types module
-option the vivid driver will create a simple framebuffer device that can be
-used for testing this API. Whether this API should be used for new drivers is
-questionable.
-
-This driver has support for a destructive capture overlay with bitmap clipping
-and list clipping (up to 16 rectangles) capabilities. Overlays are not
-supported for multiplanar formats. It also honors the struct v4l2_window field
-setting: if it is set to FIELD_TOP or FIELD_BOTTOM and the capture setting is
-FIELD_ALTERNATE, then only the top or bottom fields will be copied to the overlay.
-
-The overlay only works if you are also capturing at that same time. This is a
-vivid limitation since it copies from a buffer to the overlay instead of
-filling the overlay directly. And if you are not capturing, then no buffers
-are available to fill.
-
-In addition, the pixelformat of the capture format and that of the framebuffer
-must be the same for the overlay to work. Otherwise VIDIOC_OVERLAY will return
-an error.
-
-In order to really see what it going on you will need to create two vivid
-instances: the first with a framebuffer enabled. You configure the capture
-overlay of the second instance to use the framebuffer of the first, then
-you start capturing in the second instance. For the first instance you setup
-the output overlay for the video output, turn on video looping and capture
-to see the blended framebuffer overlay that's being written to by the second
-instance. This setup would require the following commands:
-
-.. code-block:: none
-
-	$ sudo modprobe vivid n_devs=2 node_types=0x10101,0x1
-	$ v4l2-ctl -d1 --find-fb
-	/dev/fb1 is the framebuffer associated with base address 0x12800000
-	$ sudo v4l2-ctl -d2 --set-fbuf fb=1
-	$ v4l2-ctl -d1 --set-fbuf fb=1
-	$ v4l2-ctl -d0 --set-fmt-video=pixelformat='AR15'
-	$ v4l2-ctl -d1 --set-fmt-video-out=pixelformat='AR15'
-	$ v4l2-ctl -d2 --set-fmt-video=pixelformat='AR15'
-	$ v4l2-ctl -d0 -i2
-	$ v4l2-ctl -d2 -i2
-	$ v4l2-ctl -d2 -c horizontal_movement=4
-	$ v4l2-ctl -d1 --overlay=1
-	$ v4l2-ctl -d1 -c loop_video=1
-	$ v4l2-ctl -d2 --stream-mmap --overlay=1
-
-And from another console:
-
-.. code-block:: none
-
-	$ v4l2-ctl -d1 --stream-out-mmap
-
-And yet another console:
-
-.. code-block:: none
-
-	$ qv4l2
-
-and start streaming.
-
-As you can see, this is not for the faint of heart...
-
-
-Output Overlay
---------------
-
-Note: output overlays are primarily implemented in order to test the existing
-V4L2 output overlay API. Whether this API should be used for new drivers is
-questionable.
-
-This driver has support for an output overlay and is capable of:
-
-	- bitmap clipping,
-	- list clipping (up to 16 rectangles)
-	- chromakey
-	- source chromakey
-	- global alpha
-	- local alpha
-	- local inverse alpha
-
-Output overlays are not supported for multiplanar formats. In addition, the
-pixelformat of the capture format and that of the framebuffer must be the
-same for the overlay to work. Otherwise VIDIOC_OVERLAY will return an error.
-
-Output overlays only work if the driver has been configured to create a
-framebuffer by setting flag 0x10000 in the node_types module option. The
-created framebuffer has a size of 720x576 and supports ARGB 1:5:5:5 and
-RGB 5:6:5.
-
-In order to see the effects of the various clipping, chromakeying or alpha
-processing capabilities you need to turn on video looping and see the results
-on the capture side. The use of the clipping, chromakeying or alpha processing
-capabilities will slow down the video loop considerably as a lot of checks have
-to be done per pixel.
-
-
-CEC (Consumer Electronics Control)
-----------------------------------
-
-If there are HDMI inputs then a CEC adapter will be created that has
-the same number of input ports. This is the equivalent of e.g. a TV that
-has that number of inputs. Each HDMI output will also create a
-CEC adapter that is hooked up to the corresponding input port, or (if there
-are more outputs than inputs) is not hooked up at all. In other words,
-this is the equivalent of hooking up each output device to an input port of
-the TV. Any remaining output devices remain unconnected.
-
-The EDID that each output reads reports a unique CEC physical address that is
-based on the physical address of the EDID of the input. So if the EDID of the
-receiver has physical address A.B.0.0, then each output will see an EDID
-containing physical address A.B.C.0 where C is 1 to the number of inputs. If
-there are more outputs than inputs then the remaining outputs have a CEC adapter
-that is disabled and reports an invalid physical address.
-
-
-Some Future Improvements
-------------------------
-
-Just as a reminder and in no particular order:
-
-- Add a virtual alsa driver to test audio
-- Add virtual sub-devices and media controller support
-- Some support for testing compressed video
-- Add support to loop raw VBI output to raw VBI input
-- Add support to loop teletext sliced VBI output to VBI input
-- Fix sequence/field numbering when looping of video with alternate fields
-- Add support for V4L2_CID_BG_COLOR for video outputs
-- Add ARGB888 overlay support: better testing of the alpha channel
-- Improve pixel aspect support in the tpg code by passing a real v4l2_fract
-- Use per-queue locks and/or per-device locks to improve throughput
-- Add support to loop from a specific output to a specific input across
-  vivid instances
-- The SDR radio should use the same 'frequencies' for stations as the normal
-  radio receiver, and give back noise if the frequency doesn't match up with
-  a station frequency
-- Make a thread for the RDS generation, that would help in particular for the
-  "Controls" RDS Rx I/O Mode as the read-only RDS controls could be updated
-  in real-time.
-- Changing the EDID should cause hotplug detect emulation to happen.
diff --git a/Documentation/media/v4l-drivers/zr364xx.rst b/Documentation/media/v4l-drivers/zr364xx.rst
deleted file mode 100644
index ec8acb3e98fc..000000000000
--- a/Documentation/media/v4l-drivers/zr364xx.rst
+++ /dev/null
@@ -1,110 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-Zoran 364xx based USB webcam module
-===================================
-
-site: http://royale.zerezo.com/zr364xx/
-
-mail: royale@zerezo.com
-
-.. note::
-
-   This documentation is outdated
-
-Introduction
-------------
-
-
-This brings support under Linux for the Aiptek PocketDV 3300 in webcam
-mode. If you just want to get on your PC the pictures and movies on the
-camera, you should use the usb-storage module instead.
-
-The driver works with several other cameras in webcam mode (see the list
-below).
-
-Maybe this code can work for other JPEG/USB cams based on the Coach
-chips from Zoran?
-
-Possible chipsets are : ZR36430 (ZR36430BGC) and
-maybe ZR36431, ZR36440, ZR36442...
-
-You can try the experience changing the vendor/product ID values (look
-at the source code).
-
-You can get these values by looking at /var/log/messages when you plug
-your camera, or by typing : cat /sys/kernel/debug/usb/devices.
-
-If you manage to use your cam with this code, you can send me a mail
-(royale@zerezo.com) with the name of your cam and a patch if needed.
-
-This is a beta release of the driver. Since version 0.70, this driver is
-only compatible with V4L2 API and 2.6.x kernels. If you need V4L1 or
-2.4x kernels support, please use an older version, but the code is not
-maintained anymore. Good luck!
-
-Install
--------
-
-In order to use this driver, you must compile it with your kernel.
-
-Location: Device Drivers -> Multimedia devices -> Video For Linux -> Video Capture Adapters -> V4L USB devices
-
-Usage
------
-
-modprobe zr364xx debug=X mode=Y
-
-- debug      : set to 1 to enable verbose debug messages
-- mode       : 0 = 320x240, 1 = 160x120, 2 = 640x480
-
-You can then use the camera with V4L2 compatible applications, for
-example Ekiga.
-
-To capture a single image, try this: dd if=/dev/video0 of=test.jpg bs=1M
-count=1
-
-links
------
-
-http://mxhaard.free.fr/ (support for many others cams including some Aiptek PocketDV)
-http://www.harmwal.nl/pccam880/ (this project also supports cameras based on this chipset)
-
-Supported devices
------------------
-
-======  =======  ==============  ====================
-Vendor  Product  Distributor     Model
-======  =======  ==============  ====================
-0x08ca  0x0109   Aiptek          PocketDV 3300
-0x08ca  0x0109   Maxell          Maxcam PRO DV3
-0x041e  0x4024   Creative        PC-CAM 880
-0x0d64  0x0108   Aiptek          Fidelity 3200
-0x0d64  0x0108   Praktica        DCZ 1.3 S
-0x0d64  0x0108   Genius          Digital Camera (?)
-0x0d64  0x0108   DXG Technology  Fashion Cam
-0x0546  0x3187   Polaroid        iON 230
-0x0d64  0x3108   Praktica        Exakta DC 2200
-0x0d64  0x3108   Genius          G-Shot D211
-0x0595  0x4343   Concord         Eye-Q Duo 1300
-0x0595  0x4343   Concord         Eye-Q Duo 2000
-0x0595  0x4343   Fujifilm        EX-10
-0x0595  0x4343   Ricoh           RDC-6000
-0x0595  0x4343   Digitrex        DSC 1300
-0x0595  0x4343   Firstline       FDC 2000
-0x0bb0  0x500d   Concord         EyeQ Go Wireless
-0x0feb  0x2004   CRS Electronic  3.3 Digital Camera
-0x0feb  0x2004   Packard Bell    DSC-300
-0x055f  0xb500   Mustek          MDC 3000
-0x08ca  0x2062   Aiptek          PocketDV 5700
-0x052b  0x1a18   Chiphead        Megapix V12
-0x04c8  0x0729   Konica          Revio 2
-0x04f2  0xa208   Creative        PC-CAM 850
-0x0784  0x0040   Traveler        Slimline X5
-0x06d6  0x0034   Trust           Powerc@m 750
-0x0a17  0x0062   Pentax          Optio 50L
-0x06d6  0x003b   Trust           Powerc@m 970Z
-0x0a17  0x004e   Pentax          Optio 50
-0x041e  0x405d   Creative        DiVi CAM 516
-0x08ca  0x2102   Aiptek          DV T300
-0x06d6  0x003d   Trust           Powerc@m 910Z
-======  =======  ==============  ====================
diff --git a/Documentation/media/video.h.rst.exceptions b/Documentation/media/video.h.rst.exceptions
deleted file mode 100644
index ea9de59ad8b7..000000000000
--- a/Documentation/media/video.h.rst.exceptions
+++ /dev/null
@@ -1,39 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-# Ignore header name
-ignore define _UAPI_DVBVIDEO_H_
-
-# This is a deprecated obscure API. Just ignore things we don't know
-ignore define VIDEO_CMD_PLAY
-ignore define VIDEO_CMD_STOP
-ignore define VIDEO_CMD_FREEZE
-ignore define VIDEO_CMD_CONTINUE
-ignore define VIDEO_CMD_FREEZE_TO_BLACK
-ignore define VIDEO_CMD_STOP_TO_BLACK
-ignore define VIDEO_CMD_STOP_IMMEDIATELY
-ignore define VIDEO_PLAY_FMT_NONE
-ignore define VIDEO_PLAY_FMT_GOP
-ignore define VIDEO_VSYNC_FIELD_UNKNOWN
-ignore define VIDEO_VSYNC_FIELD_ODD
-ignore define VIDEO_VSYNC_FIELD_EVEN
-ignore define VIDEO_VSYNC_FIELD_PROGRESSIVE
-ignore define VIDEO_EVENT_SIZE_CHANGED
-ignore define VIDEO_EVENT_FRAME_RATE_CHANGED
-ignore define VIDEO_EVENT_DECODER_STOPPED
-ignore define VIDEO_EVENT_VSYNC
-ignore define VIDEO_CAP_MPEG1
-ignore define VIDEO_CAP_MPEG2
-ignore define VIDEO_CAP_SYS
-ignore define VIDEO_CAP_PROG
-ignore define VIDEO_CAP_SPU
-ignore define VIDEO_CAP_NAVI
-ignore define VIDEO_CAP_CSS
-
-# some typedefs should point to struct/enums
-replace typedef video_format_t :c:type:`video_format`
-replace typedef video_system_t :c:type:`video_system`
-replace typedef video_displayformat_t :c:type:`video_displayformat`
-replace typedef video_size_t :c:type:`video_size`
-replace typedef video_stream_source_t :c:type:`video_stream_source`
-replace typedef video_play_state_t :c:type:`video_play_state`
-replace typedef video_navi_pack_t :c:type:`video_navi_pack`
diff --git a/Documentation/media/videodev2.h.rst.exceptions b/Documentation/media/videodev2.h.rst.exceptions
deleted file mode 100644
index cb6ccf91776e..000000000000
--- a/Documentation/media/videodev2.h.rst.exceptions
+++ /dev/null
@@ -1,572 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-# Ignore header name
-ignore define _UAPI__LINUX_VIDEODEV2_H
-
-#
-# The cross reference valitator for videodev2.h DocBook never cared
-# about enum symbols or defines. Yet, they're all (or almost all?)
-# handled inside V4L API sections. So, for now, it is safe to just
-# ignore. This should be revisited, as validating it helps to avoid
-# having something not documented at the uAPI.
-#
-
-# Those symbols should not be used by uAPI - don't document them
-ignore symbol V4L2_BUF_TYPE_PRIVATE
-ignore symbol V4L2_TUNER_DIGITAL_TV
-ignore symbol V4L2_COLORSPACE_BT878
-
-# Documented enum v4l2_field
-replace symbol V4L2_FIELD_ALTERNATE :c:type:`v4l2_field`
-replace symbol V4L2_FIELD_ANY :c:type:`v4l2_field`
-replace symbol V4L2_FIELD_BOTTOM :c:type:`v4l2_field`
-replace symbol V4L2_FIELD_INTERLACED :c:type:`v4l2_field`
-replace symbol V4L2_FIELD_INTERLACED_BT :c:type:`v4l2_field`
-replace symbol V4L2_FIELD_INTERLACED_TB :c:type:`v4l2_field`
-replace symbol V4L2_FIELD_NONE :c:type:`v4l2_field`
-replace symbol V4L2_FIELD_SEQ_BT :c:type:`v4l2_field`
-replace symbol V4L2_FIELD_SEQ_TB :c:type:`v4l2_field`
-replace symbol V4L2_FIELD_TOP :c:type:`v4l2_field`
-
-# Documented enum v4l2_buf_type
-replace symbol V4L2_BUF_TYPE_META_CAPTURE :c:type:`v4l2_buf_type`
-replace symbol V4L2_BUF_TYPE_META_OUTPUT :c:type:`v4l2_buf_type`
-replace symbol V4L2_BUF_TYPE_SDR_CAPTURE :c:type:`v4l2_buf_type`
-replace symbol V4L2_BUF_TYPE_SDR_OUTPUT :c:type:`v4l2_buf_type`
-replace symbol V4L2_BUF_TYPE_SLICED_VBI_CAPTURE :c:type:`v4l2_buf_type`
-replace symbol V4L2_BUF_TYPE_SLICED_VBI_OUTPUT :c:type:`v4l2_buf_type`
-replace symbol V4L2_BUF_TYPE_VBI_CAPTURE :c:type:`v4l2_buf_type`
-replace symbol V4L2_BUF_TYPE_VBI_OUTPUT :c:type:`v4l2_buf_type`
-replace symbol V4L2_BUF_TYPE_VIDEO_CAPTURE :c:type:`v4l2_buf_type`
-replace symbol V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :c:type:`v4l2_buf_type`
-replace symbol V4L2_BUF_TYPE_VIDEO_OUTPUT :c:type:`v4l2_buf_type`
-replace symbol V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE :c:type:`v4l2_buf_type`
-replace symbol V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY :c:type:`v4l2_buf_type`
-replace symbol V4L2_BUF_TYPE_VIDEO_OVERLAY :c:type:`v4l2_buf_type`
-
-# Documented enum v4l2_tuner_type
-replace symbol V4L2_TUNER_ANALOG_TV :c:type:`v4l2_tuner_type`
-replace symbol V4L2_TUNER_RADIO :c:type:`v4l2_tuner_type`
-replace symbol V4L2_TUNER_RF :c:type:`v4l2_tuner_type`
-replace symbol V4L2_TUNER_SDR :c:type:`v4l2_tuner_type`
-
-# Documented enum v4l2_memory
-replace symbol V4L2_MEMORY_DMABUF :c:type:`v4l2_memory`
-replace symbol V4L2_MEMORY_MMAP :c:type:`v4l2_memory`
-replace symbol V4L2_MEMORY_OVERLAY :c:type:`v4l2_memory`
-replace symbol V4L2_MEMORY_USERPTR :c:type:`v4l2_memory`
-
-# Documented enum v4l2_colorspace
-replace symbol V4L2_COLORSPACE_470_SYSTEM_BG :c:type:`v4l2_colorspace`
-replace symbol V4L2_COLORSPACE_470_SYSTEM_M :c:type:`v4l2_colorspace`
-replace symbol V4L2_COLORSPACE_OPRGB :c:type:`v4l2_colorspace`
-replace define V4L2_COLORSPACE_ADOBERGB :c:type:`v4l2_colorspace`
-replace symbol V4L2_COLORSPACE_BT2020 :c:type:`v4l2_colorspace`
-replace symbol V4L2_COLORSPACE_DCI_P3 :c:type:`v4l2_colorspace`
-replace symbol V4L2_COLORSPACE_DEFAULT :c:type:`v4l2_colorspace`
-replace symbol V4L2_COLORSPACE_JPEG :c:type:`v4l2_colorspace`
-replace symbol V4L2_COLORSPACE_RAW :c:type:`v4l2_colorspace`
-replace symbol V4L2_COLORSPACE_REC709 :c:type:`v4l2_colorspace`
-replace symbol V4L2_COLORSPACE_SMPTE170M :c:type:`v4l2_colorspace`
-replace symbol V4L2_COLORSPACE_SMPTE240M :c:type:`v4l2_colorspace`
-replace symbol V4L2_COLORSPACE_SRGB :c:type:`v4l2_colorspace`
-
-# Documented enum v4l2_xfer_func
-replace symbol V4L2_XFER_FUNC_709 :c:type:`v4l2_xfer_func`
-replace symbol V4L2_XFER_FUNC_OPRGB :c:type:`v4l2_xfer_func`
-replace define V4L2_XFER_FUNC_ADOBERGB :c:type:`v4l2_xfer_func`
-replace symbol V4L2_XFER_FUNC_DCI_P3 :c:type:`v4l2_xfer_func`
-replace symbol V4L2_XFER_FUNC_DEFAULT :c:type:`v4l2_xfer_func`
-replace symbol V4L2_XFER_FUNC_NONE :c:type:`v4l2_xfer_func`
-replace symbol V4L2_XFER_FUNC_SMPTE2084 :c:type:`v4l2_xfer_func`
-replace symbol V4L2_XFER_FUNC_SMPTE240M :c:type:`v4l2_xfer_func`
-replace symbol V4L2_XFER_FUNC_SRGB :c:type:`v4l2_xfer_func`
-
-# Documented enum v4l2_ycbcr_encoding
-replace symbol V4L2_YCBCR_ENC_601 :c:type:`v4l2_ycbcr_encoding`
-replace symbol V4L2_YCBCR_ENC_709 :c:type:`v4l2_ycbcr_encoding`
-replace symbol V4L2_YCBCR_ENC_BT2020 :c:type:`v4l2_ycbcr_encoding`
-replace symbol V4L2_YCBCR_ENC_BT2020_CONST_LUM :c:type:`v4l2_ycbcr_encoding`
-replace symbol V4L2_YCBCR_ENC_DEFAULT :c:type:`v4l2_ycbcr_encoding`
-replace symbol V4L2_YCBCR_ENC_SYCC :c:type:`v4l2_ycbcr_encoding`
-replace symbol V4L2_YCBCR_ENC_XV601 :c:type:`v4l2_ycbcr_encoding`
-replace symbol V4L2_YCBCR_ENC_XV709 :c:type:`v4l2_ycbcr_encoding`
-replace symbol V4L2_YCBCR_ENC_SMPTE240M :c:type:`v4l2_ycbcr_encoding`
-
-# Documented enum v4l2_hsv_encoding
-replace symbol V4L2_HSV_ENC_180 :c:type:`v4l2_hsv_encoding`
-replace symbol V4L2_HSV_ENC_256 :c:type:`v4l2_hsv_encoding`
-
-# Documented enum v4l2_quantization
-replace symbol V4L2_QUANTIZATION_DEFAULT :c:type:`v4l2_quantization`
-replace symbol V4L2_QUANTIZATION_FULL_RANGE :c:type:`v4l2_quantization`
-replace symbol V4L2_QUANTIZATION_LIM_RANGE :c:type:`v4l2_quantization`
-
-# Documented enum v4l2_priority
-replace symbol V4L2_PRIORITY_BACKGROUND :c:type:`v4l2_priority`
-replace symbol V4L2_PRIORITY_DEFAULT :c:type:`v4l2_priority`
-replace symbol V4L2_PRIORITY_INTERACTIVE :c:type:`v4l2_priority`
-replace symbol V4L2_PRIORITY_RECORD :c:type:`v4l2_priority`
-replace symbol V4L2_PRIORITY_UNSET :c:type:`v4l2_priority`
-
-# Documented enum v4l2_frmsizetypes
-replace symbol V4L2_FRMSIZE_TYPE_CONTINUOUS :c:type:`v4l2_frmsizetypes`
-replace symbol V4L2_FRMSIZE_TYPE_DISCRETE :c:type:`v4l2_frmsizetypes`
-replace symbol V4L2_FRMSIZE_TYPE_STEPWISE :c:type:`v4l2_frmsizetypes`
-
-# Documented enum frmivaltypes
-replace symbol V4L2_FRMIVAL_TYPE_CONTINUOUS :c:type:`v4l2_frmivaltypes`
-replace symbol V4L2_FRMIVAL_TYPE_DISCRETE :c:type:`v4l2_frmivaltypes`
-replace symbol V4L2_FRMIVAL_TYPE_STEPWISE :c:type:`v4l2_frmivaltypes`
-
-# Documented enum :c:type:`v4l2_ctrl_type`
-replace symbol V4L2_CTRL_COMPOUND_TYPES vidioc_queryctrl
-
-replace symbol V4L2_CTRL_TYPE_BITMASK :c:type:`v4l2_ctrl_type`
-replace symbol V4L2_CTRL_TYPE_BOOLEAN :c:type:`v4l2_ctrl_type`
-replace symbol V4L2_CTRL_TYPE_BUTTON :c:type:`v4l2_ctrl_type`
-replace symbol V4L2_CTRL_TYPE_CTRL_CLASS :c:type:`v4l2_ctrl_type`
-replace symbol V4L2_CTRL_TYPE_INTEGER :c:type:`v4l2_ctrl_type`
-replace symbol V4L2_CTRL_TYPE_INTEGER64 :c:type:`v4l2_ctrl_type`
-replace symbol V4L2_CTRL_TYPE_INTEGER_MENU :c:type:`v4l2_ctrl_type`
-replace symbol V4L2_CTRL_TYPE_MENU :c:type:`v4l2_ctrl_type`
-replace symbol V4L2_CTRL_TYPE_STRING :c:type:`v4l2_ctrl_type`
-replace symbol V4L2_CTRL_TYPE_U16 :c:type:`v4l2_ctrl_type`
-replace symbol V4L2_CTRL_TYPE_U32 :c:type:`v4l2_ctrl_type`
-replace symbol V4L2_CTRL_TYPE_U8 :c:type:`v4l2_ctrl_type`
-replace symbol V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS :c:type:`v4l2_ctrl_type`
-replace symbol V4L2_CTRL_TYPE_MPEG2_QUANTIZATION :c:type:`v4l2_ctrl_type`
-replace symbol V4L2_CTRL_TYPE_H264_SPS :c:type:`v4l2_ctrl_type`
-replace symbol V4L2_CTRL_TYPE_H264_PPS :c:type:`v4l2_ctrl_type`
-replace symbol V4L2_CTRL_TYPE_H264_SCALING_MATRIX :c:type:`v4l2_ctrl_type`
-replace symbol V4L2_CTRL_TYPE_H264_SLICE_PARAMS :c:type:`v4l2_ctrl_type`
-replace symbol V4L2_CTRL_TYPE_H264_DECODE_PARAMS :c:type:`v4l2_ctrl_type`
-replace symbol V4L2_CTRL_TYPE_HEVC_SPS :c:type:`v4l2_ctrl_type`
-replace symbol V4L2_CTRL_TYPE_HEVC_PPS :c:type:`v4l2_ctrl_type`
-replace symbol V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS :c:type:`v4l2_ctrl_type`
-replace symbol V4L2_CTRL_TYPE_AREA :c:type:`v4l2_ctrl_type`
-
-# V4L2 capability defines
-replace define V4L2_CAP_VIDEO_CAPTURE device-capabilities
-replace define V4L2_CAP_VIDEO_CAPTURE_MPLANE device-capabilities
-replace define V4L2_CAP_VIDEO_OUTPUT device-capabilities
-replace define V4L2_CAP_VIDEO_OUTPUT_MPLANE device-capabilities
-replace define V4L2_CAP_VIDEO_M2M device-capabilities
-replace define V4L2_CAP_VIDEO_M2M_MPLANE device-capabilities
-replace define V4L2_CAP_VIDEO_OVERLAY device-capabilities
-replace define V4L2_CAP_VBI_CAPTURE device-capabilities
-replace define V4L2_CAP_VBI_OUTPUT device-capabilities
-replace define V4L2_CAP_SLICED_VBI_CAPTURE device-capabilities
-replace define V4L2_CAP_SLICED_VBI_OUTPUT device-capabilities
-replace define V4L2_CAP_RDS_CAPTURE device-capabilities
-replace define V4L2_CAP_VIDEO_OUTPUT_OVERLAY device-capabilities
-replace define V4L2_CAP_HW_FREQ_SEEK device-capabilities
-replace define V4L2_CAP_RDS_OUTPUT device-capabilities
-replace define V4L2_CAP_TUNER device-capabilities
-replace define V4L2_CAP_AUDIO device-capabilities
-replace define V4L2_CAP_RADIO device-capabilities
-replace define V4L2_CAP_MODULATOR device-capabilities
-replace define V4L2_CAP_SDR_CAPTURE device-capabilities
-replace define V4L2_CAP_EXT_PIX_FORMAT device-capabilities
-replace define V4L2_CAP_SDR_OUTPUT device-capabilities
-replace define V4L2_CAP_META_CAPTURE device-capabilities
-replace define V4L2_CAP_READWRITE device-capabilities
-replace define V4L2_CAP_ASYNCIO device-capabilities
-replace define V4L2_CAP_STREAMING device-capabilities
-replace define V4L2_CAP_META_OUTPUT device-capabilities
-replace define V4L2_CAP_DEVICE_CAPS device-capabilities
-replace define V4L2_CAP_TOUCH device-capabilities
-
-# V4L2 pix flags
-replace define V4L2_PIX_FMT_PRIV_MAGIC :c:type:`v4l2_pix_format`
-replace define V4L2_PIX_FMT_FLAG_PREMUL_ALPHA reserved-formats
-
-# V4L2 format flags
-replace define V4L2_FMT_FLAG_COMPRESSED fmtdesc-flags
-replace define V4L2_FMT_FLAG_EMULATED fmtdesc-flags
-replace define V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM fmtdesc-flags
-replace define V4L2_FMT_FLAG_DYN_RESOLUTION fmtdesc-flags
-
-# V4L2 timecode types
-replace define V4L2_TC_TYPE_24FPS timecode-type
-replace define V4L2_TC_TYPE_25FPS timecode-type
-replace define V4L2_TC_TYPE_30FPS timecode-type
-replace define V4L2_TC_TYPE_50FPS timecode-type
-replace define V4L2_TC_TYPE_60FPS timecode-type
-
-# V4L2 timecode flags
-replace define V4L2_TC_FLAG_DROPFRAME timecode-flags
-replace define V4L2_TC_FLAG_COLORFRAME timecode-flags
-replace define V4L2_TC_USERBITS_field timecode-flags
-replace define V4L2_TC_USERBITS_USERDEFINED timecode-flags
-replace define V4L2_TC_USERBITS_8BITCHARS timecode-flags
-
-# V4L2 JPEG markers
-replace define V4L2_JPEG_MARKER_DHT jpeg-markers
-replace define V4L2_JPEG_MARKER_DQT jpeg-markers
-replace define V4L2_JPEG_MARKER_DRI jpeg-markers
-replace define V4L2_JPEG_MARKER_COM jpeg-markers
-replace define V4L2_JPEG_MARKER_APP jpeg-markers
-
-# V4L2 framebuffer caps and flags
-
-replace define V4L2_FBUF_CAP_EXTERNOVERLAY framebuffer-cap
-replace define V4L2_FBUF_CAP_CHROMAKEY framebuffer-cap
-replace define V4L2_FBUF_CAP_LIST_CLIPPING framebuffer-cap
-replace define V4L2_FBUF_CAP_BITMAP_CLIPPING framebuffer-cap
-replace define V4L2_FBUF_CAP_LOCAL_ALPHA framebuffer-cap
-replace define V4L2_FBUF_CAP_GLOBAL_ALPHA framebuffer-cap
-replace define V4L2_FBUF_CAP_LOCAL_INV_ALPHA framebuffer-cap
-replace define V4L2_FBUF_CAP_SRC_CHROMAKEY framebuffer-cap
-
-replace define V4L2_FBUF_FLAG_PRIMARY framebuffer-flags
-replace define V4L2_FBUF_FLAG_OVERLAY framebuffer-flags
-replace define V4L2_FBUF_FLAG_CHROMAKEY framebuffer-flags
-replace define V4L2_FBUF_FLAG_LOCAL_ALPHA framebuffer-flags
-replace define V4L2_FBUF_FLAG_GLOBAL_ALPHA framebuffer-flags
-replace define V4L2_FBUF_FLAG_LOCAL_INV_ALPHA framebuffer-flags
-replace define V4L2_FBUF_FLAG_SRC_CHROMAKEY framebuffer-flags
-
-# Used on VIDIOC_G_PARM
-
-replace define V4L2_MODE_HIGHQUALITY parm-flags
-replace define V4L2_CAP_TIMEPERFRAME :c:type:`v4l2_captureparm`
-
-# The V4L2_STD_foo are all defined at v4l2_std_id table
-
-replace define V4L2_STD_PAL_B v4l2-std-id
-replace define V4L2_STD_PAL_B1 v4l2-std-id
-replace define V4L2_STD_PAL_G v4l2-std-id
-replace define V4L2_STD_PAL_H v4l2-std-id
-replace define V4L2_STD_PAL_I v4l2-std-id
-replace define V4L2_STD_PAL_D v4l2-std-id
-replace define V4L2_STD_PAL_D1 v4l2-std-id
-replace define V4L2_STD_PAL_K v4l2-std-id
-replace define V4L2_STD_PAL_M v4l2-std-id
-replace define V4L2_STD_PAL_N v4l2-std-id
-replace define V4L2_STD_PAL_Nc v4l2-std-id
-replace define V4L2_STD_PAL_60 v4l2-std-id
-replace define V4L2_STD_NTSC_M v4l2-std-id
-replace define V4L2_STD_NTSC_M_JP v4l2-std-id
-replace define V4L2_STD_NTSC_443 v4l2-std-id
-replace define V4L2_STD_NTSC_M_KR v4l2-std-id
-replace define V4L2_STD_SECAM_B v4l2-std-id
-replace define V4L2_STD_SECAM_D v4l2-std-id
-replace define V4L2_STD_SECAM_G v4l2-std-id
-replace define V4L2_STD_SECAM_H v4l2-std-id
-replace define V4L2_STD_SECAM_K v4l2-std-id
-replace define V4L2_STD_SECAM_K1 v4l2-std-id
-replace define V4L2_STD_SECAM_L v4l2-std-id
-replace define V4L2_STD_SECAM_LC v4l2-std-id
-replace define V4L2_STD_ATSC_8_VSB v4l2-std-id
-replace define V4L2_STD_ATSC_16_VSB v4l2-std-id
-replace define V4L2_STD_NTSC v4l2-std-id
-replace define V4L2_STD_SECAM_DK v4l2-std-id
-replace define V4L2_STD_SECAM v4l2-std-id
-replace define V4L2_STD_PAL_BG v4l2-std-id
-replace define V4L2_STD_PAL_DK v4l2-std-id
-replace define V4L2_STD_PAL v4l2-std-id
-replace define V4L2_STD_B v4l2-std-id
-replace define V4L2_STD_G v4l2-std-id
-replace define V4L2_STD_H v4l2-std-id
-replace define V4L2_STD_L v4l2-std-id
-replace define V4L2_STD_GH v4l2-std-id
-replace define V4L2_STD_DK v4l2-std-id
-replace define V4L2_STD_BG v4l2-std-id
-replace define V4L2_STD_MN v4l2-std-id
-replace define V4L2_STD_MTS v4l2-std-id
-replace define V4L2_STD_525_60 v4l2-std-id
-replace define V4L2_STD_625_50 v4l2-std-id
-replace define V4L2_STD_ATSC v4l2-std-id
-replace define V4L2_STD_UNKNOWN v4l2-std-id
-replace define V4L2_STD_ALL v4l2-std-id
-
-# V4L2 DT BT timings definitions
-
-replace define V4L2_DV_PROGRESSIVE :c:type:`v4l2_bt_timings`
-replace define V4L2_DV_INTERLACED :c:type:`v4l2_bt_timings`
-
-replace define V4L2_DV_VSYNC_POS_POL :c:type:`v4l2_bt_timings`
-replace define V4L2_DV_HSYNC_POS_POL :c:type:`v4l2_bt_timings`
-
-replace define V4L2_DV_BT_STD_CEA861 dv-bt-standards
-replace define V4L2_DV_BT_STD_DMT dv-bt-standards
-replace define V4L2_DV_BT_STD_CVT dv-bt-standards
-replace define V4L2_DV_BT_STD_GTF dv-bt-standards
-replace define V4L2_DV_BT_STD_SDI dv-bt-standards
-
-replace define V4L2_DV_FL_REDUCED_BLANKING dv-bt-standards
-replace define V4L2_DV_FL_CAN_REDUCE_FPS dv-bt-standards
-replace define V4L2_DV_FL_CAN_DETECT_REDUCED_FPS dv-bt-standards
-replace define V4L2_DV_FL_REDUCED_FPS dv-bt-standards
-replace define V4L2_DV_FL_HALF_LINE dv-bt-standards
-replace define V4L2_DV_FL_IS_CE_VIDEO dv-bt-standards
-replace define V4L2_DV_FL_FIRST_FIELD_EXTRA_LINE dv-bt-standards
-replace define V4L2_DV_FL_HAS_PICTURE_ASPECT dv-bt-standards
-replace define V4L2_DV_FL_HAS_CEA861_VIC dv-bt-standards
-replace define V4L2_DV_FL_HAS_HDMI_VIC dv-bt-standards
-
-replace define V4L2_DV_BT_656_1120 dv-timing-types
-
-replace define V4L2_DV_BT_CAP_INTERLACED framebuffer-cap
-replace define V4L2_DV_BT_CAP_PROGRESSIVE framebuffer-cap
-replace define V4L2_DV_BT_CAP_REDUCED_BLANKING framebuffer-cap
-replace define V4L2_DV_BT_CAP_CUSTOM framebuffer-cap
-
-# V4L2 input
-
-replace define V4L2_INPUT_TYPE_TUNER input-type
-replace define V4L2_INPUT_TYPE_CAMERA input-type
-replace define V4L2_INPUT_TYPE_TOUCH input-type
-
-replace define V4L2_IN_ST_NO_POWER input-status
-replace define V4L2_IN_ST_NO_SIGNAL input-status
-replace define V4L2_IN_ST_NO_COLOR input-status
-replace define V4L2_IN_ST_HFLIP input-status
-replace define V4L2_IN_ST_VFLIP input-status
-replace define V4L2_IN_ST_NO_H_LOCK input-status
-replace define V4L2_IN_ST_COLOR_KILL input-status
-replace define V4L2_IN_ST_NO_SYNC input-status
-replace define V4L2_IN_ST_NO_EQU input-status
-replace define V4L2_IN_ST_NO_CARRIER input-status
-replace define V4L2_IN_ST_MACROVISION input-status
-replace define V4L2_IN_ST_NO_ACCESS input-status
-replace define V4L2_IN_ST_VTR input-status
-replace define V4L2_IN_ST_NO_V_LOCK input-status
-replace define V4L2_IN_ST_NO_STD_LOCK input-status
-
-replace define V4L2_IN_CAP_DV_TIMINGS input-capabilities
-replace define V4L2_IN_CAP_STD input-capabilities
-replace define V4L2_IN_CAP_NATIVE_SIZE input-capabilities
-
-# V4L2 output
-
-replace define V4L2_OUTPUT_TYPE_MODULATOR output-type
-replace define V4L2_OUTPUT_TYPE_ANALOG output-type
-replace define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY output-type
-
-replace define V4L2_OUT_CAP_DV_TIMINGS output-capabilities
-replace define V4L2_OUT_CAP_STD output-capabilities
-replace define V4L2_OUT_CAP_NATIVE_SIZE output-capabilities
-
-# V4L2 control flags
-
-replace define V4L2_CTRL_FLAG_DISABLED control-flags
-replace define V4L2_CTRL_FLAG_GRABBED control-flags
-replace define V4L2_CTRL_FLAG_READ_ONLY control-flags
-replace define V4L2_CTRL_FLAG_UPDATE control-flags
-replace define V4L2_CTRL_FLAG_INACTIVE control-flags
-replace define V4L2_CTRL_FLAG_SLIDER control-flags
-replace define V4L2_CTRL_FLAG_WRITE_ONLY control-flags
-replace define V4L2_CTRL_FLAG_VOLATILE control-flags
-replace define V4L2_CTRL_FLAG_HAS_PAYLOAD control-flags
-replace define V4L2_CTRL_FLAG_EXECUTE_ON_WRITE control-flags
-replace define V4L2_CTRL_FLAG_MODIFY_LAYOUT control-flags
-
-replace define V4L2_CTRL_FLAG_NEXT_CTRL control
-replace define V4L2_CTRL_FLAG_NEXT_COMPOUND control
-replace define V4L2_CID_PRIVATE_BASE control
-
-# V4L2 tuner
-
-replace define V4L2_TUNER_CAP_LOW tuner-capability
-replace define V4L2_TUNER_CAP_NORM tuner-capability
-replace define V4L2_TUNER_CAP_HWSEEK_BOUNDED tuner-capability
-replace define V4L2_TUNER_CAP_HWSEEK_WRAP tuner-capability
-replace define V4L2_TUNER_CAP_STEREO tuner-capability
-replace define V4L2_TUNER_CAP_LANG2 tuner-capability
-replace define V4L2_TUNER_CAP_SAP tuner-capability
-replace define V4L2_TUNER_CAP_LANG1 tuner-capability
-replace define V4L2_TUNER_CAP_RDS tuner-capability
-replace define V4L2_TUNER_CAP_RDS_BLOCK_IO tuner-capability
-replace define V4L2_TUNER_CAP_RDS_CONTROLS tuner-capability
-replace define V4L2_TUNER_CAP_FREQ_BANDS tuner-capability
-replace define V4L2_TUNER_CAP_HWSEEK_PROG_LIM tuner-capability
-replace define V4L2_TUNER_CAP_1HZ tuner-capability
-
-replace define V4L2_TUNER_SUB_MONO tuner-rxsubchans
-replace define V4L2_TUNER_SUB_STEREO tuner-rxsubchans
-replace define V4L2_TUNER_SUB_LANG2 tuner-rxsubchans
-replace define V4L2_TUNER_SUB_SAP tuner-rxsubchans
-replace define V4L2_TUNER_SUB_LANG1 tuner-rxsubchans
-replace define V4L2_TUNER_SUB_RDS tuner-rxsubchans
-
-replace define V4L2_TUNER_MODE_MONO tuner-audmode
-replace define V4L2_TUNER_MODE_STEREO tuner-audmode
-replace define V4L2_TUNER_MODE_LANG2 tuner-audmode
-replace define V4L2_TUNER_MODE_SAP tuner-audmode
-replace define V4L2_TUNER_MODE_LANG1 tuner-audmode
-replace define V4L2_TUNER_MODE_LANG1_LANG2 tuner-audmode
-
-replace define V4L2_BAND_MODULATION_VSB band-modulation
-replace define V4L2_BAND_MODULATION_FM band-modulation
-replace define V4L2_BAND_MODULATION_AM band-modulation
-
-replace define V4L2_RDS_BLOCK_MSK v4l2-rds-block
-replace define V4L2_RDS_BLOCK_A v4l2-rds-block
-replace define V4L2_RDS_BLOCK_B v4l2-rds-block
-replace define V4L2_RDS_BLOCK_C v4l2-rds-block
-replace define V4L2_RDS_BLOCK_D v4l2-rds-block
-replace define V4L2_RDS_BLOCK_C_ALT v4l2-rds-block
-replace define V4L2_RDS_BLOCK_INVALID v4l2-rds-block
-replace define V4L2_RDS_BLOCK_CORRECTED v4l2-rds-block
-replace define V4L2_RDS_BLOCK_ERROR v4l2-rds-block
-
-# V4L2 audio
-
-replace define V4L2_AUDCAP_STEREO audio-capability
-replace define V4L2_AUDCAP_AVL audio-capability
-
-replace define V4L2_AUDMODE_AVL audio-mode
-
-# MPEG
-
-replace define V4L2_ENC_IDX_FRAME_I :c:type:`v4l2_enc_idx`
-replace define V4L2_ENC_IDX_FRAME_P :c:type:`v4l2_enc_idx`
-replace define V4L2_ENC_IDX_FRAME_B :c:type:`v4l2_enc_idx`
-replace define V4L2_ENC_IDX_FRAME_MASK :c:type:`v4l2_enc_idx`
-replace define V4L2_ENC_IDX_ENTRIES :c:type:`v4l2_enc_idx`
-
-replace define V4L2_ENC_CMD_START encoder-cmds
-replace define V4L2_ENC_CMD_STOP encoder-cmds
-replace define V4L2_ENC_CMD_PAUSE encoder-cmds
-replace define V4L2_ENC_CMD_RESUME encoder-cmds
-
-replace define V4L2_ENC_CMD_STOP_AT_GOP_END encoder-flags
-
-replace define V4L2_DEC_CMD_START decoder-cmds
-replace define V4L2_DEC_CMD_STOP decoder-cmds
-replace define V4L2_DEC_CMD_PAUSE decoder-cmds
-replace define V4L2_DEC_CMD_RESUME decoder-cmds
-replace define V4L2_DEC_CMD_FLUSH decoder-cmds
-
-replace define V4L2_DEC_CMD_START_MUTE_AUDIO decoder-cmds
-replace define V4L2_DEC_CMD_PAUSE_TO_BLACK decoder-cmds
-replace define V4L2_DEC_CMD_STOP_TO_BLACK decoder-cmds
-replace define V4L2_DEC_CMD_STOP_IMMEDIATELY decoder-cmds
-
-replace define V4L2_DEC_START_FMT_NONE decoder-cmds
-replace define V4L2_DEC_START_FMT_GOP decoder-cmds
-
-# V4L2 VBI
-
-replace define V4L2_VBI_UNSYNC vbifmt-flags
-replace define V4L2_VBI_INTERLACED vbifmt-flags
-
-replace define V4L2_VBI_ITU_525_F1_START :c:type:`v4l2_vbi_format`
-replace define V4L2_VBI_ITU_525_F2_START :c:type:`v4l2_vbi_format`
-replace define V4L2_VBI_ITU_625_F1_START :c:type:`v4l2_vbi_format`
-replace define V4L2_VBI_ITU_625_F2_START :c:type:`v4l2_vbi_format`
-
-
-replace define V4L2_SLICED_TELETEXT_B vbi-services
-replace define V4L2_SLICED_VPS vbi-services
-replace define V4L2_SLICED_CAPTION_525 vbi-services
-replace define V4L2_SLICED_WSS_625 vbi-services
-replace define V4L2_SLICED_VBI_525 vbi-services
-replace define V4L2_SLICED_VBI_625 vbi-services
-
-replace define V4L2_MPEG_VBI_IVTV_TELETEXT_B ITV0-Line-Identifier-Constants
-replace define V4L2_MPEG_VBI_IVTV_CAPTION_525 ITV0-Line-Identifier-Constants
-replace define V4L2_MPEG_VBI_IVTV_WSS_625 ITV0-Line-Identifier-Constants
-replace define V4L2_MPEG_VBI_IVTV_VPS ITV0-Line-Identifier-Constants
-
-replace define V4L2_MPEG_VBI_IVTV_MAGIC0 v4l2-mpeg-vbi-fmt-ivtv-magic
-replace define V4L2_MPEG_VBI_IVTV_MAGIC1 v4l2-mpeg-vbi-fmt-ivtv-magic
-
-# V4L2 events
-
-replace define V4L2_EVENT_ALL event-type
-replace define V4L2_EVENT_VSYNC event-type
-replace define V4L2_EVENT_EOS event-type
-replace define V4L2_EVENT_CTRL event-type
-replace define V4L2_EVENT_FRAME_SYNC event-type
-replace define V4L2_EVENT_SOURCE_CHANGE event-type
-replace define V4L2_EVENT_MOTION_DET event-type
-replace define V4L2_EVENT_PRIVATE_START event-type
-
-replace define V4L2_EVENT_CTRL_CH_VALUE ctrl-changes-flags
-replace define V4L2_EVENT_CTRL_CH_FLAGS ctrl-changes-flags
-replace define V4L2_EVENT_CTRL_CH_RANGE ctrl-changes-flags
-
-replace define V4L2_EVENT_SRC_CH_RESOLUTION src-changes-flags
-
-replace define V4L2_EVENT_MD_FL_HAVE_FRAME_SEQ :c:type:`v4l2_event_motion_det`
-
-replace define V4L2_EVENT_SUB_FL_SEND_INITIAL event-flags
-replace define V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK event-flags
-
-# V4L2 debugging
-replace define V4L2_CHIP_MATCH_BRIDGE vidioc_dbg_g_register
-replace define V4L2_CHIP_MATCH_SUBDEV vidioc_dbg_g_register
-replace define V4L2_CHIP_MATCH_HOST vidioc_dbg_g_register
-replace define V4L2_CHIP_MATCH_I2C_DRIVER vidioc_dbg_g_register
-replace define V4L2_CHIP_MATCH_I2C_ADDR vidioc_dbg_g_register
-replace define V4L2_CHIP_MATCH_AC97 vidioc_dbg_g_register
-
-replace define V4L2_CHIP_FL_READABLE vidioc_dbg_g_register
-replace define V4L2_CHIP_FL_WRITABLE vidioc_dbg_g_register
-
-# Ignore reserved ioctl and ancillary macros
-
-ignore define VIDEO_MAX_FRAME
-ignore define VIDEO_MAX_PLANES
-ignore define v4l2_fourcc
-ignore define v4l2_fourcc_be
-ignore define V4L2_FIELD_HAS_TOP
-ignore define V4L2_FIELD_HAS_BOTTOM
-ignore define V4L2_FIELD_HAS_BOTH
-ignore define V4L2_FIELD_HAS_T_OR_B
-ignore define V4L2_TYPE_IS_MULTIPLANAR
-ignore define V4L2_TYPE_IS_OUTPUT
-ignore define V4L2_TUNER_ADC
-ignore define V4L2_MAP_COLORSPACE_DEFAULT
-ignore define V4L2_MAP_XFER_FUNC_DEFAULT
-ignore define V4L2_MAP_YCBCR_ENC_DEFAULT
-ignore define V4L2_DV_BT_BLANKING_WIDTH
-ignore define V4L2_DV_BT_FRAME_WIDTH
-ignore define V4L2_DV_BT_BLANKING_HEIGHT
-ignore define V4L2_DV_BT_FRAME_HEIGHT
-ignore define V4L2_IN_CAP_CUSTOM_TIMINGS
-ignore define V4L2_CTRL_ID_MASK
-ignore define V4L2_CTRL_ID2CLASS
-ignore define V4L2_CTRL_ID2WHICH
-ignore define V4L2_CTRL_DRIVER_PRIV
-ignore define V4L2_CTRL_MAX_DIMS
-ignore define V4L2_CTRL_WHICH_CUR_VAL
-ignore define V4L2_CTRL_WHICH_DEF_VAL
-ignore define V4L2_CTRL_WHICH_REQUEST_VAL
-ignore define V4L2_OUT_CAP_CUSTOM_TIMINGS
-ignore define V4L2_CID_MAX_CTRLS
-
-ignore define BASE_VIDIOC_PRIVATE
-
-# Associate ioctls with their counterparts
-replace ioctl VIDIOC_DBG_S_REGISTER vidioc_dbg_g_register
-replace ioctl VIDIOC_DQBUF vidioc_qbuf
-replace ioctl VIDIOC_S_AUDOUT vidioc_g_audout
-replace ioctl VIDIOC_S_CROP vidioc_g_crop
-replace ioctl VIDIOC_S_CTRL vidioc_g_ctrl
-replace ioctl VIDIOC_S_DV_TIMINGS vidioc_g_dv_timings
-replace ioctl VIDIOC_S_EDID vidioc_g_edid
-replace ioctl VIDIOC_S_EXT_CTRLS vidioc_g_ext_ctrls
-replace ioctl VIDIOC_S_FBUF vidioc_g_fbuf
-replace ioctl VIDIOC_S_FMT vidioc_g_fmt
-replace ioctl VIDIOC_S_FREQUENCY vidioc_g_frequency
-replace ioctl VIDIOC_S_INPUT vidioc_g_input
-replace ioctl VIDIOC_S_JPEGCOMP vidioc_g_jpegcomp
-replace ioctl VIDIOC_S_MODULATOR vidioc_g_modulator
-replace ioctl VIDIOC_S_OUTPUT vidioc_g_output
-replace ioctl VIDIOC_S_PARM vidioc_g_parm
-replace ioctl VIDIOC_S_PRIORITY vidioc_g_priority
-replace ioctl VIDIOC_S_SELECTION vidioc_g_selection
-replace ioctl VIDIOC_S_STD vidioc_g_std
-replace ioctl VIDIOC_S_AUDIO vidioc_g_audio
-replace ioctl VIDIOC_S_TUNER vidioc_g_tuner
-replace ioctl VIDIOC_TRY_DECODER_CMD vidioc_decoder_cmd
-replace ioctl VIDIOC_TRY_ENCODER_CMD vidioc_encoder_cmd
-replace ioctl VIDIOC_TRY_EXT_CTRLS vidioc_g_ext_ctrls
-replace ioctl VIDIOC_TRY_FMT vidioc_g_fmt
-replace ioctl VIDIOC_STREAMOFF vidioc_streamon
-replace ioctl VIDIOC_QUERY_EXT_CTRL vidioc_queryctrl
-replace ioctl VIDIOC_QUERYMENU vidioc_queryctrl
diff --git a/Documentation/networking/devlink/devlink-trap.rst b/Documentation/networking/devlink/devlink-trap.rst
index a09971c2115c..fe089acb7783 100644
--- a/Documentation/networking/devlink/devlink-trap.rst
+++ b/Documentation/networking/devlink/devlink-trap.rst
@@ -257,6 +257,8 @@ drivers:
   * :doc:`netdevsim`
   * :doc:`mlxsw`
 
+.. _Generic-Packet-Trap-Groups:
+
 Generic Packet Trap Groups
 ==========================
 
diff --git a/Documentation/networking/index.rst b/Documentation/networking/index.rst
index 50133d9761c9..6538ede29661 100644
--- a/Documentation/networking/index.rst
+++ b/Documentation/networking/index.rst
@@ -22,6 +22,7 @@ Contents:
    z8530book
    msg_zerocopy
    failover
+   net_dim
    net_failover
    phy
    sfp-phylink
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index ee961d322d93..6fcfd313dbe4 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -812,7 +812,7 @@ tcp_limit_output_bytes - INTEGER
 tcp_challenge_ack_limit - INTEGER
 	Limits number of Challenge ACK sent per second, as recommended
 	in RFC 5961 (Improving TCP's Robustness to Blind In-Window Attacks)
-	Default: 100
+	Default: 1000
 
 tcp_rx_skb_cache - BOOLEAN
 	Controls a per TCP socket cache of one skb, that might help
diff --git a/Documentation/networking/net_dim.rst b/Documentation/networking/net_dim.rst
new file mode 100644
index 000000000000..3bed9fd95336
--- /dev/null
+++ b/Documentation/networking/net_dim.rst
@@ -0,0 +1,176 @@
+======================================================
+Net DIM - Generic Network Dynamic Interrupt Moderation
+======================================================
+
+:Author: Tal Gilboa <talgi@mellanox.com>
+
+.. contents:: :depth: 2
+
+Assumptions
+===========
+
+This document assumes the reader has basic knowledge in network drivers
+and in general interrupt moderation.
+
+
+Introduction
+============
+
+Dynamic Interrupt Moderation (DIM) (in networking) refers to changing the
+interrupt moderation configuration of a channel in order to optimize packet
+processing. The mechanism includes an algorithm which decides if and how to
+change moderation parameters for a channel, usually by performing an analysis on
+runtime data sampled from the system. Net DIM is such a mechanism. In each
+iteration of the algorithm, it analyses a given sample of the data, compares it
+to the previous sample and if required, it can decide to change some of the
+interrupt moderation configuration fields. The data sample is composed of data
+bandwidth, the number of packets and the number of events. The time between
+samples is also measured. Net DIM compares the current and the previous data and
+returns an adjusted interrupt moderation configuration object. In some cases,
+the algorithm might decide not to change anything. The configuration fields are
+the minimum duration (microseconds) allowed between events and the maximum
+number of wanted packets per event. The Net DIM algorithm ascribes importance to
+increase bandwidth over reducing interrupt rate.
+
+
+Net DIM Algorithm
+=================
+
+Each iteration of the Net DIM algorithm follows these steps:
+
+#. Calculates new data sample.
+#. Compares it to previous sample.
+#. Makes a decision - suggests interrupt moderation configuration fields.
+#. Applies a schedule work function, which applies suggested configuration.
+
+The first two steps are straightforward, both the new and the previous data are
+supplied by the driver registered to Net DIM. The previous data is the new data
+supplied to the previous iteration. The comparison step checks the difference
+between the new and previous data and decides on the result of the last step.
+A step would result as "better" if bandwidth increases and as "worse" if
+bandwidth reduces. If there is no change in bandwidth, the packet rate is
+compared in a similar fashion - increase == "better" and decrease == "worse".
+In case there is no change in the packet rate as well, the interrupt rate is
+compared. Here the algorithm tries to optimize for lower interrupt rate so an
+increase in the interrupt rate is considered "worse" and a decrease is
+considered "better". Step #2 has an optimization for avoiding false results: it
+only considers a difference between samples as valid if it is greater than a
+certain percentage. Also, since Net DIM does not measure anything by itself, it
+assumes the data provided by the driver is valid.
+
+Step #3 decides on the suggested configuration based on the result from step #2
+and the internal state of the algorithm. The states reflect the "direction" of
+the algorithm: is it going left (reducing moderation), right (increasing
+moderation) or standing still. Another optimization is that if a decision
+to stay still is made multiple times, the interval between iterations of the
+algorithm would increase in order to reduce calculation overhead. Also, after
+"parking" on one of the most left or most right decisions, the algorithm may
+decide to verify this decision by taking a step in the other direction. This is
+done in order to avoid getting stuck in a "deep sleep" scenario. Once a
+decision is made, an interrupt moderation configuration is selected from
+the predefined profiles.
+
+The last step is to notify the registered driver that it should apply the
+suggested configuration. This is done by scheduling a work function, defined by
+the Net DIM API and provided by the registered driver.
+
+As you can see, Net DIM itself does not actively interact with the system. It
+would have trouble making the correct decisions if the wrong data is supplied to
+it and it would be useless if the work function would not apply the suggested
+configuration. This does, however, allow the registered driver some room for
+manoeuvre as it may provide partial data or ignore the algorithm suggestion
+under some conditions.
+
+
+Registering a Network Device to DIM
+===================================
+
+Net DIM API exposes the main function net_dim().
+This function is the entry point to the Net
+DIM algorithm and has to be called every time the driver would like to check if
+it should change interrupt moderation parameters. The driver should provide two
+data structures: :c:type:`struct dim <dim>` and
+:c:type:`struct dim_sample <dim_sample>`. :c:type:`struct dim <dim>`
+describes the state of DIM for a specific object (RX queue, TX queue,
+other queues, etc.). This includes the current selected profile, previous data
+samples, the callback function provided by the driver and more.
+:c:type:`struct dim_sample <dim_sample>` describes a data sample,
+which will be compared to the data sample stored in :c:type:`struct dim <dim>`
+in order to decide on the algorithm's next
+step. The sample should include bytes, packets and interrupts, measured by
+the driver.
+
+In order to use Net DIM from a networking driver, the driver needs to call the
+main net_dim() function. The recommended method is to call net_dim() on each
+interrupt. Since Net DIM has a built-in moderation and it might decide to skip
+iterations under certain conditions, there is no need to moderate the net_dim()
+calls as well. As mentioned above, the driver needs to provide an object of type
+:c:type:`struct dim <dim>` to the net_dim() function call. It is advised for
+each entity using Net DIM to hold a :c:type:`struct dim <dim>` as part of its
+data structure and use it as the main Net DIM API object.
+The :c:type:`struct dim_sample <dim_sample>` should hold the latest
+bytes, packets and interrupts count. No need to perform any calculations, just
+include the raw data.
+
+The net_dim() call itself does not return anything. Instead Net DIM relies on
+the driver to provide a callback function, which is called when the algorithm
+decides to make a change in the interrupt moderation parameters. This callback
+will be scheduled and run in a separate thread in order not to add overhead to
+the data flow. After the work is done, Net DIM algorithm needs to be set to
+the proper state in order to move to the next iteration.
+
+
+Example
+=======
+
+The following code demonstrates how to register a driver to Net DIM. The actual
+usage is not complete but it should make the outline of the usage clear.
+
+.. code-block:: c
+
+  #include <linux/dim.h>
+
+  /* Callback for net DIM to schedule on a decision to change moderation */
+  void my_driver_do_dim_work(struct work_struct *work)
+  {
+	/* Get struct dim from struct work_struct */
+	struct dim *dim = container_of(work, struct dim,
+				       work);
+	/* Do interrupt moderation related stuff */
+	...
+
+	/* Signal net DIM work is done and it should move to next iteration */
+	dim->state = DIM_START_MEASURE;
+  }
+
+  /* My driver's interrupt handler */
+  int my_driver_handle_interrupt(struct my_driver_entity *my_entity, ...)
+  {
+	...
+	/* A struct to hold current measured data */
+	struct dim_sample dim_sample;
+	...
+	/* Initiate data sample struct with current data */
+	dim_update_sample(my_entity->events,
+		          my_entity->packets,
+		          my_entity->bytes,
+		          &dim_sample);
+	/* Call net DIM */
+	net_dim(&my_entity->dim, dim_sample);
+	...
+  }
+
+  /* My entity's initialization function (my_entity was already allocated) */
+  int my_driver_init_my_entity(struct my_driver_entity *my_entity, ...)
+  {
+	...
+	/* Initiate struct work_struct with my driver's callback function */
+	INIT_WORK(&my_entity->dim.work, my_driver_do_dim_work);
+	...
+  }
+
+Dynamic Interrupt Moderation (DIM) library API
+==============================================
+
+.. kernel-doc:: include/linux/dim.h
+    :internal:
diff --git a/Documentation/networking/net_dim.txt b/Documentation/networking/net_dim.txt
deleted file mode 100644
index 9bdb7d5a3ba3..000000000000
--- a/Documentation/networking/net_dim.txt
+++ /dev/null
@@ -1,174 +0,0 @@
-Net DIM - Generic Network Dynamic Interrupt Moderation
-======================================================
-
-Author:
-	Tal Gilboa <talgi@mellanox.com>
-
-
-Contents
-=========
-
-- Assumptions
-- Introduction
-- The Net DIM Algorithm
-- Registering a Network Device to DIM
-- Example
-
-Part 0: Assumptions
-======================
-
-This document assumes the reader has basic knowledge in network drivers
-and in general interrupt moderation.
-
-
-Part I: Introduction
-======================
-
-Dynamic Interrupt Moderation (DIM) (in networking) refers to changing the
-interrupt moderation configuration of a channel in order to optimize packet
-processing. The mechanism includes an algorithm which decides if and how to
-change moderation parameters for a channel, usually by performing an analysis on
-runtime data sampled from the system. Net DIM is such a mechanism. In each
-iteration of the algorithm, it analyses a given sample of the data, compares it
-to the previous sample and if required, it can decide to change some of the
-interrupt moderation configuration fields. The data sample is composed of data
-bandwidth, the number of packets and the number of events. The time between
-samples is also measured. Net DIM compares the current and the previous data and
-returns an adjusted interrupt moderation configuration object. In some cases,
-the algorithm might decide not to change anything. The configuration fields are
-the minimum duration (microseconds) allowed between events and the maximum
-number of wanted packets per event. The Net DIM algorithm ascribes importance to
-increase bandwidth over reducing interrupt rate.
-
-
-Part II: The Net DIM Algorithm
-===============================
-
-Each iteration of the Net DIM algorithm follows these steps:
-1. Calculates new data sample.
-2. Compares it to previous sample.
-3. Makes a decision - suggests interrupt moderation configuration fields.
-4. Applies a schedule work function, which applies suggested configuration.
-
-The first two steps are straightforward, both the new and the previous data are
-supplied by the driver registered to Net DIM. The previous data is the new data
-supplied to the previous iteration. The comparison step checks the difference
-between the new and previous data and decides on the result of the last step.
-A step would result as "better" if bandwidth increases and as "worse" if
-bandwidth reduces. If there is no change in bandwidth, the packet rate is
-compared in a similar fashion - increase == "better" and decrease == "worse".
-In case there is no change in the packet rate as well, the interrupt rate is
-compared. Here the algorithm tries to optimize for lower interrupt rate so an
-increase in the interrupt rate is considered "worse" and a decrease is
-considered "better". Step #2 has an optimization for avoiding false results: it
-only considers a difference between samples as valid if it is greater than a
-certain percentage. Also, since Net DIM does not measure anything by itself, it
-assumes the data provided by the driver is valid.
-
-Step #3 decides on the suggested configuration based on the result from step #2
-and the internal state of the algorithm. The states reflect the "direction" of
-the algorithm: is it going left (reducing moderation), right (increasing
-moderation) or standing still. Another optimization is that if a decision
-to stay still is made multiple times, the interval between iterations of the
-algorithm would increase in order to reduce calculation overhead. Also, after
-"parking" on one of the most left or most right decisions, the algorithm may
-decide to verify this decision by taking a step in the other direction. This is
-done in order to avoid getting stuck in a "deep sleep" scenario. Once a
-decision is made, an interrupt moderation configuration is selected from
-the predefined profiles.
-
-The last step is to notify the registered driver that it should apply the
-suggested configuration. This is done by scheduling a work function, defined by
-the Net DIM API and provided by the registered driver.
-
-As you can see, Net DIM itself does not actively interact with the system. It
-would have trouble making the correct decisions if the wrong data is supplied to
-it and it would be useless if the work function would not apply the suggested
-configuration. This does, however, allow the registered driver some room for
-manoeuvre as it may provide partial data or ignore the algorithm suggestion
-under some conditions.
-
-
-Part III: Registering a Network Device to DIM
-==============================================
-
-Net DIM API exposes the main function net_dim(struct dim *dim,
-struct dim_sample end_sample). This function is the entry point to the Net
-DIM algorithm and has to be called every time the driver would like to check if
-it should change interrupt moderation parameters. The driver should provide two
-data structures: struct dim and struct dim_sample. Struct dim
-describes the state of DIM for a specific object (RX queue, TX queue,
-other queues, etc.). This includes the current selected profile, previous data
-samples, the callback function provided by the driver and more.
-Struct dim_sample describes a data sample, which will be compared to the
-data sample stored in struct dim in order to decide on the algorithm's next
-step. The sample should include bytes, packets and interrupts, measured by
-the driver.
-
-In order to use Net DIM from a networking driver, the driver needs to call the
-main net_dim() function. The recommended method is to call net_dim() on each
-interrupt. Since Net DIM has a built-in moderation and it might decide to skip
-iterations under certain conditions, there is no need to moderate the net_dim()
-calls as well. As mentioned above, the driver needs to provide an object of type
-struct dim to the net_dim() function call. It is advised for each entity
-using Net DIM to hold a struct dim as part of its data structure and use it
-as the main Net DIM API object. The struct dim_sample should hold the latest
-bytes, packets and interrupts count. No need to perform any calculations, just
-include the raw data.
-
-The net_dim() call itself does not return anything. Instead Net DIM relies on
-the driver to provide a callback function, which is called when the algorithm
-decides to make a change in the interrupt moderation parameters. This callback
-will be scheduled and run in a separate thread in order not to add overhead to
-the data flow. After the work is done, Net DIM algorithm needs to be set to
-the proper state in order to move to the next iteration.
-
-
-Part IV: Example
-=================
-
-The following code demonstrates how to register a driver to Net DIM. The actual
-usage is not complete but it should make the outline of the usage clear.
-
-my_driver.c:
-
-#include <linux/dim.h>
-
-/* Callback for net DIM to schedule on a decision to change moderation */
-void my_driver_do_dim_work(struct work_struct *work)
-{
-	/* Get struct dim from struct work_struct */
-	struct dim *dim = container_of(work, struct dim,
-				       work);
-	/* Do interrupt moderation related stuff */
-	...
-
-	/* Signal net DIM work is done and it should move to next iteration */
-	dim->state = DIM_START_MEASURE;
-}
-
-/* My driver's interrupt handler */
-int my_driver_handle_interrupt(struct my_driver_entity *my_entity, ...)
-{
-	...
-	/* A struct to hold current measured data */
-	struct dim_sample dim_sample;
-	...
-	/* Initiate data sample struct with current data */
-	dim_update_sample(my_entity->events,
-		          my_entity->packets,
-		          my_entity->bytes,
-		          &dim_sample);
-	/* Call net DIM */
-	net_dim(&my_entity->dim, dim_sample);
-	...
-}
-
-/* My entity's initialization function (my_entity was already allocated) */
-int my_driver_init_my_entity(struct my_driver_entity *my_entity, ...)
-{
-	...
-	/* Initiate struct work_struct with my driver's callback function */
-	INIT_WORK(&my_entity->dim.work, my_driver_do_dim_work);
-	...
-}
diff --git a/Documentation/security/keys/core.rst b/Documentation/security/keys/core.rst
index d9b0b859018b..0154721b20b2 100644
--- a/Documentation/security/keys/core.rst
+++ b/Documentation/security/keys/core.rst
@@ -833,6 +833,7 @@ The keyctl syscall functions are:
      A process must have search permission on the key for this function to be
      successful.
 
+
   *  Compute a Diffie-Hellman shared secret or public key::
 
 	long keyctl(KEYCTL_DH_COMPUTE, struct keyctl_dh_params *params,
@@ -1026,6 +1027,63 @@ The keyctl syscall functions are:
      written into the output buffer.  Verification returns 0 on success.
 
 
+  *  Watch a key or keyring for changes::
+
+	long keyctl(KEYCTL_WATCH_KEY, key_serial_t key, int queue_fd,
+		    const struct watch_notification_filter *filter);
+
+     This will set or remove a watch for changes on the specified key or
+     keyring.
+
+     "key" is the ID of the key to be watched.
+
+     "queue_fd" is a file descriptor referring to an open "/dev/watch_queue"
+     which manages the buffer into which notifications will be delivered.
+
+     "filter" is either NULL to remove a watch or a filter specification to
+     indicate what events are required from the key.
+
+     See Documentation/watch_queue.rst for more information.
+
+     Note that only one watch may be emplaced for any particular { key,
+     queue_fd } combination.
+
+     Notification records look like::
+
+	struct key_notification {
+		struct watch_notification watch;
+		__u32	key_id;
+		__u32	aux;
+	};
+
+     In this, watch::type will be "WATCH_TYPE_KEY_NOTIFY" and subtype will be
+     one of::
+
+	NOTIFY_KEY_INSTANTIATED
+	NOTIFY_KEY_UPDATED
+	NOTIFY_KEY_LINKED
+	NOTIFY_KEY_UNLINKED
+	NOTIFY_KEY_CLEARED
+	NOTIFY_KEY_REVOKED
+	NOTIFY_KEY_INVALIDATED
+	NOTIFY_KEY_SETATTR
+
+     Where these indicate a key being instantiated/rejected, updated, a link
+     being made in a keyring, a link being removed from a keyring, a keyring
+     being cleared, a key being revoked, a key being invalidated or a key
+     having one of its attributes changed (user, group, perm, timeout,
+     restriction).
+
+     If a watched key is deleted, a basic watch_notification will be issued
+     with "type" set to WATCH_TYPE_META and "subtype" set to
+     watch_meta_removal_notification.  The watchpoint ID will be set in the
+     "info" field.
+
+     This needs to be configured by enabling:
+
+	"Provide key/keyring change notifications" (KEY_NOTIFICATIONS)
+
+
 Kernel Services
 ===============
 
diff --git a/Documentation/trace/coresight/coresight-ect.rst b/Documentation/trace/coresight/coresight-ect.rst
index ecc1e57012ef..a68732c5c6d6 100644
--- a/Documentation/trace/coresight/coresight-ect.rst
+++ b/Documentation/trace/coresight/coresight-ect.rst
@@ -1,4 +1,5 @@
 .. SPDX-License-Identifier: GPL-2.0
+
 =============================================
 CoreSight Embedded Cross Trigger (CTI & CTM).
 =============================================
@@ -72,7 +73,7 @@ capable of generating or using trigger signals.::
 
   >$ ls /sys/bus/coresight/devices/etm0/cti_cpu0
   channels  ctmid  enable  nr_trigger_cons mgmt  power powered  regs
-  subsystem triggers0 triggers1  uevent
+  connections subsystem triggers0 triggers1  uevent
 
 *Key file items are:-*
    * ``enable``: enables/disables the CTI. Read to determine current state.
@@ -88,6 +89,9 @@ capable of generating or using trigger signals.::
    * ``channels``: Contains the channel API - CTI main programming interface.
    * ``regs``: Gives access to the raw programmable CTI regs.
    * ``mgmt``: the standard CoreSight management registers.
+   * ``connections``: Links to connected *CoreSight* devices. The number of
+     links can be 0 to ``nr_trigger_cons``. Actual number given by ``nr_links``
+     in this directory.
 
 
 triggers<N> directories
diff --git a/Documentation/trace/coresight/coresight.rst b/Documentation/trace/coresight/coresight.rst
index 108600ee1e12..0b73acb44efa 100644
--- a/Documentation/trace/coresight/coresight.rst
+++ b/Documentation/trace/coresight/coresight.rst
@@ -241,6 +241,91 @@ to the newer scheme, to give a confirmation that what you see on your
 system is not unexpected. One must use the "names" as they appear on
 the system under specified locations.
 
+Topology Representation
+-----------------------
+
+Each CoreSight component has a ``connections`` directory which will contain
+links to other CoreSight components. This allows the user to explore the trace
+topology and for larger systems, determine the most appropriate sink for a
+given source. The connection information can also be used to establish
+which CTI devices are connected to a given component. This directory contains a
+``nr_links`` attribute detailing the number of links in the directory.
+
+For an ETM source, in this case ``etm0`` on a Juno platform, a typical
+arrangement will be::
+
+  linaro-developer:~# ls - l /sys/bus/coresight/devices/etm0/connections
+  <file details>  cti_cpu0 -> ../../../23020000.cti/cti_cpu0
+  <file details>  nr_links
+  <file details>  out:0 -> ../../../230c0000.funnel/funnel2
+
+Following the out port to ``funnel2``::
+
+  linaro-developer:~# ls -l /sys/bus/coresight/devices/funnel2/connections
+  <file details> in:0 -> ../../../23040000.etm/etm0
+  <file details> in:1 -> ../../../23140000.etm/etm3
+  <file details> in:2 -> ../../../23240000.etm/etm4
+  <file details> in:3 -> ../../../23340000.etm/etm5
+  <file details> nr_links
+  <file details> out:0 -> ../../../20040000.funnel/funnel0
+
+And again to ``funnel0``::
+
+  linaro-developer:~# ls -l /sys/bus/coresight/devices/funnel0/connections
+  <file details> in:0 -> ../../../220c0000.funnel/funnel1
+  <file details> in:1 -> ../../../230c0000.funnel/funnel2
+  <file details> nr_links
+  <file details> out:0 -> ../../../20010000.etf/tmc_etf0
+
+Finding the first sink ``tmc_etf0``. This can be used to collect data
+as a sink, or as a link to propagate further along the chain::
+
+  linaro-developer:~# ls -l /sys/bus/coresight/devices/tmc_etf0/connections
+  <file details> cti_sys0 -> ../../../20020000.cti/cti_sys0
+  <file details> in:0 -> ../../../20040000.funnel/funnel0
+  <file details> nr_links
+  <file details> out:0 -> ../../../20150000.funnel/funnel4
+
+via ``funnel4``::
+
+  linaro-developer:~# ls -l /sys/bus/coresight/devices/funnel4/connections
+  <file details> in:0 -> ../../../20010000.etf/tmc_etf0
+  <file details> in:1 -> ../../../20140000.etf/tmc_etf1
+  <file details> nr_links
+  <file details> out:0 -> ../../../20120000.replicator/replicator0
+
+and a ``replicator0``::
+
+  linaro-developer:~# ls -l /sys/bus/coresight/devices/replicator0/connections
+  <file details> in:0 -> ../../../20150000.funnel/funnel4
+  <file details> nr_links
+  <file details> out:0 -> ../../../20030000.tpiu/tpiu0
+  <file details> out:1 -> ../../../20070000.etr/tmc_etr0
+
+Arriving at the final sink in the chain, ``tmc_etr0``::
+
+  linaro-developer:~# ls -l /sys/bus/coresight/devices/tmc_etr0/connections
+  <file details> cti_sys0 -> ../../../20020000.cti/cti_sys0
+  <file details> in:0 -> ../../../20120000.replicator/replicator0
+  <file details> nr_links
+
+As described below, when using sysfs it is sufficient to enable a sink and
+a source for successful trace. The framework will correctly enable all
+intermediate links as required.
+
+Note: ``cti_sys0`` appears in two of the connections lists above.
+CTIs can connect to multiple devices and are arranged in a star topology
+via the CTM. See (:doc:`coresight-ect`) [#fourth]_ for further details.
+Looking at this device we see 4 connections::
+
+  linaro-developer:~# ls -l /sys/bus/coresight/devices/cti_sys0/connections
+  <file details> nr_links
+  <file details> stm0 -> ../../../20100000.stm/stm0
+  <file details> tmc_etf0 -> ../../../20010000.etf/tmc_etf0
+  <file details> tmc_etr0 -> ../../../20070000.etr/tmc_etr0
+  <file details> tpiu0 -> ../../../20030000.tpiu/tpiu0
+
+
 How to use the tracer modules
 -----------------------------
 
diff --git a/Documentation/translations/it_IT/doc-guide/parse-headers.rst b/Documentation/translations/it_IT/doc-guide/parse-headers.rst
index b38918ca637e..993d549ee2b8 100644
--- a/Documentation/translations/it_IT/doc-guide/parse-headers.rst
+++ b/Documentation/translations/it_IT/doc-guide/parse-headers.rst
@@ -17,7 +17,7 @@ con le modifiche del kernel.
 Il programma :ref:`parse_headers.pl <it_parse_headers>` genera questi riferimenti.
 Esso dev'essere invocato attraverso un Makefile, mentre si genera la
 documentazione. Per avere un esempio su come utilizzarlo all'interno del kernel
-consultate ``Documentation/media/Makefile``.
+consultate ``Documentation/userspace-api/media/Makefile``.
 
 .. _it_parse_headers:
 
diff --git a/Documentation/translations/zh_CN/video4linux/omap3isp.txt b/Documentation/translations/zh_CN/video4linux/omap3isp.txt
index e9f29375aa95..75e481985630 100644
--- a/Documentation/translations/zh_CN/video4linux/omap3isp.txt
+++ b/Documentation/translations/zh_CN/video4linux/omap3isp.txt
@@ -1,4 +1,4 @@
-Chinese translated version of Documentation/media/v4l-drivers/omap3isp.rst
+Chinese translated version of Documentation/admin-guide/media/omap3isp.rst
 
 If you have any comment or update to the content, please contact the
 original document maintainer directly.  However, if you have a problem
@@ -11,7 +11,7 @@ Maintainer: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
 	  David Cohen <dacohen@gmail.com>
 Chinese maintainer: Fu Wei <tekkamanninja@gmail.com>
 ---------------------------------------------------------------------
-Documentation/media/v4l-drivers/omap3isp.rst 的中文翻译
+Documentation/admin-guide/media/omap3isp.rst 的中文翻译
 
 如果想评论或更新本文的内容，请直接联系原文档的维护者。如果你使用英文
 交流有困难的话，也可以向中文版维护者求助。如果本翻译更新不及时或者翻
diff --git a/Documentation/translations/zh_CN/video4linux/v4l2-framework.txt b/Documentation/translations/zh_CN/video4linux/v4l2-framework.txt
index 9c39ee58ea50..4d2af480a112 100644
--- a/Documentation/translations/zh_CN/video4linux/v4l2-framework.txt
+++ b/Documentation/translations/zh_CN/video4linux/v4l2-framework.txt
@@ -1,4 +1,4 @@
-Chinese translated version of Documentation/media/media_kapi.rst
+Chinese translated version of Documentation/driver-api/media/index.rst
 
 If you have any comment or update to the content, please contact the
 original document maintainer directly.  However, if you have a problem
@@ -9,7 +9,7 @@ or if there is a problem with the translation.
 Maintainer: Mauro Carvalho Chehab <mchehab@kernel.org>
 Chinese maintainer: Fu Wei <tekkamanninja@gmail.com>
 ---------------------------------------------------------------------
-Documentation/media/media_kapi.rst 的中文翻译
+Documentation/driver-api/media/index.rst 的中文翻译
 
 如果想评论或更新本文的内容，请直接联系原文档的维护者。如果你使用英文
 交流有困难的话，也可以向中文版维护者求助。如果本翻译更新不及时或者翻
@@ -777,7 +777,7 @@ v4l2 核心 API 提供了一个处理视频缓冲的标准方法(称为“videob
 线性 DMA(videobuf-dma-contig)以及大多用于 USB 设备的用 vmalloc
 分配的缓冲(videobuf-vmalloc)。
 
-请参阅 Documentation/media/kapi/v4l2-videobuf.rst，以获得更多关于 videobuf
+请参阅 Documentation/driver-api/media/v4l2-videobuf.rst，以获得更多关于 videobuf
 层的使用信息。
 
 v4l2_fh 结构体
diff --git a/Documentation/userspace-api/index.rst b/Documentation/userspace-api/index.rst
index e983488b48b1..69fc5167e648 100644
--- a/Documentation/userspace-api/index.rst
+++ b/Documentation/userspace-api/index.rst
@@ -22,6 +22,7 @@ place where this information is gathered.
    spec_ctrl
    accelerators/ocxl
    ioctl/index
+   media/index
 
 .. only::  subproject and html
 
diff --git a/Documentation/userspace-api/ioctl/ioctl-number.rst b/Documentation/userspace-api/ioctl/ioctl-number.rst
index f759edafd938..9425377615ce 100644
--- a/Documentation/userspace-api/ioctl/ioctl-number.rst
+++ b/Documentation/userspace-api/ioctl/ioctl-number.rst
@@ -201,6 +201,7 @@ Code  Seq#    Include File                                           Comments
 'W'   00-1F  linux/wanrouter.h                                       conflict! (pre 3.9)
 'W'   00-3F  sound/asound.h                                          conflict!
 'W'   40-5F  drivers/pci/switch/switchtec.c
+'W'   60-61  linux/watch_queue.h
 'X'   all    fs/xfs/xfs_fs.h,                                        conflict!
              fs/xfs/linux-2.6/xfs_ioctl32.h,
              include/linux/falloc.h,
diff --git a/Documentation/userspace-api/media/Makefile b/Documentation/userspace-api/media/Makefile
new file mode 100644
index 000000000000..81a4a1a53bce
--- /dev/null
+++ b/Documentation/userspace-api/media/Makefile
@@ -0,0 +1,69 @@
+# SPDX-License-Identifier: GPL-2.0
+
+# Rules to convert a .h file to inline RST documentation
+
+SRC_DIR=$(srctree)/Documentation/userspace-api/media
+PARSER = $(srctree)/Documentation/sphinx/parse-headers.pl
+UAPI = $(srctree)/include/uapi/linux
+KAPI = $(srctree)/include/linux
+
+FILES = audio.h.rst ca.h.rst dmx.h.rst frontend.h.rst net.h.rst video.h.rst \
+	  videodev2.h.rst media.h.rst cec.h.rst lirc.h.rst
+
+TARGETS := $(addprefix $(BUILDDIR)/, $(FILES))
+
+gen_rst = \
+	echo ${PARSER} $< $@ $(SRC_DIR)/$(notdir $@).exceptions; \
+	${PARSER} $< $@ $(SRC_DIR)/$(notdir $@).exceptions
+
+quiet_gen_rst = echo '  PARSE   $(patsubst $(srctree)/%,%,$<)'; \
+	${PARSER} $< $@ $(SRC_DIR)/$(notdir $@).exceptions
+
+silent_gen_rst = ${gen_rst}
+
+$(BUILDDIR)/audio.h.rst: ${UAPI}/dvb/audio.h ${PARSER} $(SRC_DIR)/audio.h.rst.exceptions
+	@$($(quiet)gen_rst)
+
+$(BUILDDIR)/ca.h.rst: ${UAPI}/dvb/ca.h ${PARSER} $(SRC_DIR)/ca.h.rst.exceptions
+	@$($(quiet)gen_rst)
+
+$(BUILDDIR)/dmx.h.rst: ${UAPI}/dvb/dmx.h ${PARSER} $(SRC_DIR)/dmx.h.rst.exceptions
+	@$($(quiet)gen_rst)
+
+$(BUILDDIR)/frontend.h.rst: ${UAPI}/dvb/frontend.h ${PARSER} $(SRC_DIR)/frontend.h.rst.exceptions
+	@$($(quiet)gen_rst)
+
+$(BUILDDIR)/net.h.rst: ${UAPI}/dvb/net.h ${PARSER} $(SRC_DIR)/net.h.rst.exceptions
+	@$($(quiet)gen_rst)
+
+$(BUILDDIR)/video.h.rst: ${UAPI}/dvb/video.h ${PARSER} $(SRC_DIR)/video.h.rst.exceptions
+	@$($(quiet)gen_rst)
+
+$(BUILDDIR)/videodev2.h.rst: ${UAPI}/videodev2.h ${PARSER} $(SRC_DIR)/videodev2.h.rst.exceptions
+	@$($(quiet)gen_rst)
+
+$(BUILDDIR)/media.h.rst: ${UAPI}/media.h ${PARSER} $(SRC_DIR)/media.h.rst.exceptions
+	@$($(quiet)gen_rst)
+
+$(BUILDDIR)/cec.h.rst: ${UAPI}/cec.h ${PARSER} $(SRC_DIR)/cec.h.rst.exceptions
+	@$($(quiet)gen_rst)
+
+$(BUILDDIR)/lirc.h.rst: ${UAPI}/lirc.h ${PARSER} $(SRC_DIR)/lirc.h.rst.exceptions
+	@$($(quiet)gen_rst)
+
+# Media build rules
+
+.PHONY: all html epub xml latex
+
+all: $(IMGDOT) $(BUILDDIR) ${TARGETS}
+html: all
+epub: all
+xml: all
+latex: $(IMGPDF) all
+linkcheck:
+
+clean:
+	-rm -f $(DOTTGT) $(IMGTGT) ${TARGETS} 2>/dev/null
+
+$(BUILDDIR):
+	$(Q)mkdir -p $@
diff --git a/Documentation/userspace-api/media/audio.h.rst.exceptions b/Documentation/userspace-api/media/audio.h.rst.exceptions
new file mode 100644
index 000000000000..cf6620477f73
--- /dev/null
+++ b/Documentation/userspace-api/media/audio.h.rst.exceptions
@@ -0,0 +1,19 @@
+# SPDX-License-Identifier: GPL-2.0
+
+# Ignore header name
+ignore define _DVBAUDIO_H_
+
+# Undocumented audio caps, as this is a deprecated API anyway
+ignore define AUDIO_CAP_DTS
+ignore define AUDIO_CAP_LPCM
+ignore define AUDIO_CAP_MP1
+ignore define AUDIO_CAP_MP2
+ignore define AUDIO_CAP_MP3
+ignore define AUDIO_CAP_AAC
+ignore define AUDIO_CAP_OGG
+ignore define AUDIO_CAP_SDDS
+ignore define AUDIO_CAP_AC3
+
+# some typedefs should point to struct/enums
+replace typedef audio_mixer_t :c:type:`audio_mixer`
+replace typedef audio_status_t :c:type:`audio_status`
diff --git a/Documentation/userspace-api/media/ca.h.rst.exceptions b/Documentation/userspace-api/media/ca.h.rst.exceptions
new file mode 100644
index 000000000000..f6828238eb48
--- /dev/null
+++ b/Documentation/userspace-api/media/ca.h.rst.exceptions
@@ -0,0 +1,25 @@
+# SPDX-License-Identifier: GPL-2.0
+
+# Ignore header name
+ignore define _DVBCA_H_
+
+# struct ca_slot_info defines
+replace define CA_CI :c:type:`ca_slot_info`
+replace define CA_CI_LINK :c:type:`ca_slot_info`
+replace define CA_CI_PHYS :c:type:`ca_slot_info`
+replace define CA_DESCR :c:type:`ca_slot_info`
+replace define CA_SC :c:type:`ca_slot_info`
+replace define CA_CI_MODULE_PRESENT :c:type:`ca_slot_info`
+replace define CA_CI_MODULE_READY :c:type:`ca_slot_info`
+
+# struct ca_descr_info defines
+replace define CA_ECD :c:type:`ca_descr_info`
+replace define CA_NDS :c:type:`ca_descr_info`
+replace define CA_DSS :c:type:`ca_descr_info`
+
+# some typedefs should point to struct/enums
+replace typedef ca_slot_info_t :c:type:`ca_slot_info`
+replace typedef ca_descr_info_t :c:type:`ca_descr_info`
+replace typedef ca_caps_t :c:type:`ca_caps`
+replace typedef ca_msg_t :c:type:`ca_msg`
+replace typedef ca_descr_t :c:type:`ca_descr`
diff --git a/Documentation/userspace-api/media/cec.h.rst.exceptions b/Documentation/userspace-api/media/cec.h.rst.exceptions
new file mode 100644
index 000000000000..d83790ccac8e
--- /dev/null
+++ b/Documentation/userspace-api/media/cec.h.rst.exceptions
@@ -0,0 +1,575 @@
+# SPDX-License-Identifier: GPL-2.0
+
+# Ignore header name
+ignore define _CEC_UAPI_H
+
+# define macros to ignore
+
+ignore define CEC_MAX_MSG_SIZE
+ignore define CEC_MAX_LOG_ADDRS
+
+ignore define CEC_LOG_ADDR_MASK_TV
+ignore define CEC_LOG_ADDR_MASK_RECORD
+ignore define CEC_LOG_ADDR_MASK_TUNER
+ignore define CEC_LOG_ADDR_MASK_PLAYBACK
+ignore define CEC_LOG_ADDR_MASK_AUDIOSYSTEM
+ignore define CEC_LOG_ADDR_MASK_BACKUP
+ignore define CEC_LOG_ADDR_MASK_SPECIFIC
+ignore define CEC_LOG_ADDR_MASK_UNREGISTERED
+
+# Shouldn't them be documented?
+ignore define CEC_LOG_ADDR_INVALID
+ignore define CEC_PHYS_ADDR_INVALID
+
+ignore define CEC_VENDOR_ID_NONE
+
+ignore define CEC_MODE_INITIATOR_MSK
+ignore define CEC_MODE_FOLLOWER_MSK
+
+# Part of CEC 2.0 spec - shouldn't be documented too?
+ignore define CEC_LOG_ADDR_TV
+ignore define CEC_LOG_ADDR_RECORD_1
+ignore define CEC_LOG_ADDR_RECORD_2
+ignore define CEC_LOG_ADDR_TUNER_1
+ignore define CEC_LOG_ADDR_PLAYBACK_1
+ignore define CEC_LOG_ADDR_AUDIOSYSTEM
+ignore define CEC_LOG_ADDR_TUNER_2
+ignore define CEC_LOG_ADDR_TUNER_3
+ignore define CEC_LOG_ADDR_PLAYBACK_2
+ignore define CEC_LOG_ADDR_RECORD_3
+ignore define CEC_LOG_ADDR_TUNER_4
+ignore define CEC_LOG_ADDR_PLAYBACK_3
+ignore define CEC_LOG_ADDR_BACKUP_1
+ignore define CEC_LOG_ADDR_BACKUP_2
+ignore define CEC_LOG_ADDR_SPECIFIC
+ignore define CEC_LOG_ADDR_UNREGISTERED
+ignore define CEC_LOG_ADDR_BROADCAST
+
+# IMHO, those should also be documented
+
+ignore define CEC_MSG_ACTIVE_SOURCE
+ignore define CEC_MSG_IMAGE_VIEW_ON
+ignore define CEC_MSG_TEXT_VIEW_ON
+
+ignore define CEC_MSG_INACTIVE_SOURCE
+ignore define CEC_MSG_REQUEST_ACTIVE_SOURCE
+ignore define CEC_MSG_ROUTING_CHANGE
+ignore define CEC_MSG_ROUTING_INFORMATION
+ignore define CEC_MSG_SET_STREAM_PATH
+
+ignore define CEC_MSG_STANDBY
+
+ignore define CEC_MSG_RECORD_OFF
+ignore define CEC_MSG_RECORD_ON
+
+ignore define CEC_OP_RECORD_SRC_OWN
+ignore define CEC_OP_RECORD_SRC_DIGITAL
+ignore define CEC_OP_RECORD_SRC_ANALOG
+ignore define CEC_OP_RECORD_SRC_EXT_PLUG
+ignore define CEC_OP_RECORD_SRC_EXT_PHYS_ADDR
+
+ignore define CEC_OP_SERVICE_ID_METHOD_BY_DIG_ID
+ignore define CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL
+
+ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_GEN
+ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_GEN
+ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_GEN
+ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_BS
+ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_CS
+ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_T
+ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_CABLE
+ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_SAT
+ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_T
+ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_C
+ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_S
+ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_S2
+ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_T
+
+ignore define CEC_OP_ANA_BCAST_TYPE_CABLE
+ignore define CEC_OP_ANA_BCAST_TYPE_SATELLITE
+ignore define CEC_OP_ANA_BCAST_TYPE_TERRESTRIAL
+
+ignore define CEC_OP_BCAST_SYSTEM_PAL_BG
+ignore define CEC_OP_BCAST_SYSTEM_SECAM_LQ
+ignore define CEC_OP_BCAST_SYSTEM_PAL_M
+ignore define CEC_OP_BCAST_SYSTEM_NTSC_M
+ignore define CEC_OP_BCAST_SYSTEM_PAL_I
+ignore define CEC_OP_BCAST_SYSTEM_SECAM_DK
+ignore define CEC_OP_BCAST_SYSTEM_SECAM_BG
+ignore define CEC_OP_BCAST_SYSTEM_SECAM_L
+ignore define CEC_OP_BCAST_SYSTEM_PAL_DK
+ignore define CEC_OP_BCAST_SYSTEM_OTHER
+
+ignore define CEC_OP_CHANNEL_NUMBER_FMT_1_PART
+ignore define CEC_OP_CHANNEL_NUMBER_FMT_2_PART
+
+ignore define CEC_MSG_RECORD_STATUS
+
+ignore define CEC_OP_RECORD_STATUS_CUR_SRC
+ignore define CEC_OP_RECORD_STATUS_DIG_SERVICE
+ignore define CEC_OP_RECORD_STATUS_ANA_SERVICE
+ignore define CEC_OP_RECORD_STATUS_EXT_INPUT
+ignore define CEC_OP_RECORD_STATUS_NO_DIG_SERVICE
+ignore define CEC_OP_RECORD_STATUS_NO_ANA_SERVICE
+ignore define CEC_OP_RECORD_STATUS_NO_SERVICE
+ignore define CEC_OP_RECORD_STATUS_INVALID_EXT_PLUG
+ignore define CEC_OP_RECORD_STATUS_INVALID_EXT_PHYS_ADDR
+ignore define CEC_OP_RECORD_STATUS_UNSUP_CA
+ignore define CEC_OP_RECORD_STATUS_NO_CA_ENTITLEMENTS
+ignore define CEC_OP_RECORD_STATUS_CANT_COPY_SRC
+ignore define CEC_OP_RECORD_STATUS_NO_MORE_COPIES
+ignore define CEC_OP_RECORD_STATUS_NO_MEDIA
+ignore define CEC_OP_RECORD_STATUS_PLAYING
+ignore define CEC_OP_RECORD_STATUS_ALREADY_RECORDING
+ignore define CEC_OP_RECORD_STATUS_MEDIA_PROT
+ignore define CEC_OP_RECORD_STATUS_NO_SIGNAL
+ignore define CEC_OP_RECORD_STATUS_MEDIA_PROBLEM
+ignore define CEC_OP_RECORD_STATUS_NO_SPACE
+ignore define CEC_OP_RECORD_STATUS_PARENTAL_LOCK
+ignore define CEC_OP_RECORD_STATUS_TERMINATED_OK
+ignore define CEC_OP_RECORD_STATUS_ALREADY_TERM
+ignore define CEC_OP_RECORD_STATUS_OTHER
+
+ignore define CEC_MSG_RECORD_TV_SCREEN
+
+ignore define CEC_MSG_CLEAR_ANALOGUE_TIMER
+
+ignore define CEC_OP_REC_SEQ_SUNDAY
+ignore define CEC_OP_REC_SEQ_MONDAY
+ignore define CEC_OP_REC_SEQ_TUESDAY
+ignore define CEC_OP_REC_SEQ_WEDNESDAY
+ignore define CEC_OP_REC_SEQ_THURSDAY
+ignore define CEC_OP_REC_SEQ_FRIDAY
+ignore define CEC_OP_REC_SEQ_SATERDAY
+ignore define CEC_OP_REC_SEQ_ONCE_ONLY
+
+ignore define CEC_MSG_CLEAR_DIGITAL_TIMER
+
+ignore define CEC_MSG_CLEAR_EXT_TIMER
+
+ignore define CEC_OP_EXT_SRC_PLUG
+ignore define CEC_OP_EXT_SRC_PHYS_ADDR
+
+ignore define CEC_MSG_SET_ANALOGUE_TIMER
+ignore define CEC_MSG_SET_DIGITAL_TIMER
+ignore define CEC_MSG_SET_EXT_TIMER
+
+ignore define CEC_MSG_SET_TIMER_PROGRAM_TITLE
+ignore define CEC_MSG_TIMER_CLEARED_STATUS
+
+ignore define CEC_OP_TIMER_CLR_STAT_RECORDING
+ignore define CEC_OP_TIMER_CLR_STAT_NO_MATCHING
+ignore define CEC_OP_TIMER_CLR_STAT_NO_INFO
+ignore define CEC_OP_TIMER_CLR_STAT_CLEARED
+
+ignore define CEC_MSG_TIMER_STATUS
+
+ignore define CEC_OP_TIMER_OVERLAP_WARNING_NO_OVERLAP
+ignore define CEC_OP_TIMER_OVERLAP_WARNING_OVERLAP
+
+ignore define CEC_OP_MEDIA_INFO_UNPROT_MEDIA
+ignore define CEC_OP_MEDIA_INFO_PROT_MEDIA
+ignore define CEC_OP_MEDIA_INFO_NO_MEDIA
+
+ignore define CEC_OP_PROG_IND_NOT_PROGRAMMED
+ignore define CEC_OP_PROG_IND_PROGRAMMED
+
+ignore define CEC_OP_PROG_INFO_ENOUGH_SPACE
+ignore define CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE
+ignore define CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE
+ignore define CEC_OP_PROG_INFO_NONE_AVAILABLE
+
+ignore define CEC_OP_PROG_ERROR_NO_FREE_TIMER
+ignore define CEC_OP_PROG_ERROR_DATE_OUT_OF_RANGE
+ignore define CEC_OP_PROG_ERROR_REC_SEQ_ERROR
+ignore define CEC_OP_PROG_ERROR_INV_EXT_PLUG
+ignore define CEC_OP_PROG_ERROR_INV_EXT_PHYS_ADDR
+ignore define CEC_OP_PROG_ERROR_CA_UNSUPP
+ignore define CEC_OP_PROG_ERROR_INSUF_CA_ENTITLEMENTS
+ignore define CEC_OP_PROG_ERROR_RESOLUTION_UNSUPP
+ignore define CEC_OP_PROG_ERROR_PARENTAL_LOCK
+ignore define CEC_OP_PROG_ERROR_CLOCK_FAILURE
+ignore define CEC_OP_PROG_ERROR_DUPLICATE
+
+ignore define CEC_MSG_CEC_VERSION
+
+ignore define CEC_OP_CEC_VERSION_1_3A
+ignore define CEC_OP_CEC_VERSION_1_4
+ignore define CEC_OP_CEC_VERSION_2_0
+
+ignore define CEC_MSG_GET_CEC_VERSION
+ignore define CEC_MSG_GIVE_PHYSICAL_ADDR
+ignore define CEC_MSG_GET_MENU_LANGUAGE
+ignore define CEC_MSG_REPORT_PHYSICAL_ADDR
+
+ignore define CEC_OP_PRIM_DEVTYPE_TV
+ignore define CEC_OP_PRIM_DEVTYPE_RECORD
+ignore define CEC_OP_PRIM_DEVTYPE_TUNER
+ignore define CEC_OP_PRIM_DEVTYPE_PLAYBACK
+ignore define CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM
+ignore define CEC_OP_PRIM_DEVTYPE_SWITCH
+ignore define CEC_OP_PRIM_DEVTYPE_PROCESSOR
+
+ignore define CEC_MSG_SET_MENU_LANGUAGE
+ignore define CEC_MSG_REPORT_FEATURES
+
+ignore define CEC_OP_ALL_DEVTYPE_TV
+ignore define CEC_OP_ALL_DEVTYPE_RECORD
+ignore define CEC_OP_ALL_DEVTYPE_TUNER
+ignore define CEC_OP_ALL_DEVTYPE_PLAYBACK
+ignore define CEC_OP_ALL_DEVTYPE_AUDIOSYSTEM
+ignore define CEC_OP_ALL_DEVTYPE_SWITCH
+
+ignore define CEC_OP_FEAT_EXT
+
+ignore define CEC_OP_FEAT_RC_TV_PROFILE_NONE
+ignore define CEC_OP_FEAT_RC_TV_PROFILE_1
+ignore define CEC_OP_FEAT_RC_TV_PROFILE_2
+ignore define CEC_OP_FEAT_RC_TV_PROFILE_3
+ignore define CEC_OP_FEAT_RC_TV_PROFILE_4
+ignore define CEC_OP_FEAT_RC_SRC_HAS_DEV_ROOT_MENU
+ignore define CEC_OP_FEAT_RC_SRC_HAS_DEV_SETUP_MENU
+ignore define CEC_OP_FEAT_RC_SRC_HAS_CONTENTS_MENU
+ignore define CEC_OP_FEAT_RC_SRC_HAS_MEDIA_TOP_MENU
+ignore define CEC_OP_FEAT_RC_SRC_HAS_MEDIA_CONTEXT_MENU
+
+ignore define CEC_OP_FEAT_DEV_HAS_RECORD_TV_SCREEN
+ignore define CEC_OP_FEAT_DEV_HAS_SET_OSD_STRING
+ignore define CEC_OP_FEAT_DEV_HAS_DECK_CONTROL
+ignore define CEC_OP_FEAT_DEV_HAS_SET_AUDIO_RATE
+ignore define CEC_OP_FEAT_DEV_SINK_HAS_ARC_TX
+ignore define CEC_OP_FEAT_DEV_SOURCE_HAS_ARC_RX
+
+ignore define CEC_MSG_GIVE_FEATURES
+
+ignore define CEC_MSG_DECK_CONTROL
+
+ignore define CEC_OP_DECK_CTL_MODE_SKIP_FWD
+ignore define CEC_OP_DECK_CTL_MODE_SKIP_REV
+ignore define CEC_OP_DECK_CTL_MODE_STOP
+ignore define CEC_OP_DECK_CTL_MODE_EJECT
+
+ignore define CEC_MSG_DECK_STATUS
+
+ignore define CEC_OP_DECK_INFO_PLAY
+ignore define CEC_OP_DECK_INFO_RECORD
+ignore define CEC_OP_DECK_INFO_PLAY_REV
+ignore define CEC_OP_DECK_INFO_STILL
+ignore define CEC_OP_DECK_INFO_SLOW
+ignore define CEC_OP_DECK_INFO_SLOW_REV
+ignore define CEC_OP_DECK_INFO_FAST_FWD
+ignore define CEC_OP_DECK_INFO_FAST_REV
+ignore define CEC_OP_DECK_INFO_NO_MEDIA
+ignore define CEC_OP_DECK_INFO_STOP
+ignore define CEC_OP_DECK_INFO_SKIP_FWD
+ignore define CEC_OP_DECK_INFO_SKIP_REV
+ignore define CEC_OP_DECK_INFO_INDEX_SEARCH_FWD
+ignore define CEC_OP_DECK_INFO_INDEX_SEARCH_REV
+ignore define CEC_OP_DECK_INFO_OTHER
+
+ignore define CEC_MSG_GIVE_DECK_STATUS
+
+ignore define CEC_OP_STATUS_REQ_ON
+ignore define CEC_OP_STATUS_REQ_OFF
+ignore define CEC_OP_STATUS_REQ_ONCE
+
+ignore define CEC_MSG_PLAY
+
+ignore define CEC_OP_PLAY_MODE_PLAY_FWD
+ignore define CEC_OP_PLAY_MODE_PLAY_REV
+ignore define CEC_OP_PLAY_MODE_PLAY_STILL
+ignore define CEC_OP_PLAY_MODE_PLAY_FAST_FWD_MIN
+ignore define CEC_OP_PLAY_MODE_PLAY_FAST_FWD_MED
+ignore define CEC_OP_PLAY_MODE_PLAY_FAST_FWD_MAX
+ignore define CEC_OP_PLAY_MODE_PLAY_FAST_REV_MIN
+ignore define CEC_OP_PLAY_MODE_PLAY_FAST_REV_MED
+ignore define CEC_OP_PLAY_MODE_PLAY_FAST_REV_MAX
+ignore define CEC_OP_PLAY_MODE_PLAY_SLOW_FWD_MIN
+ignore define CEC_OP_PLAY_MODE_PLAY_SLOW_FWD_MED
+ignore define CEC_OP_PLAY_MODE_PLAY_SLOW_FWD_MAX
+ignore define CEC_OP_PLAY_MODE_PLAY_SLOW_REV_MIN
+ignore define CEC_OP_PLAY_MODE_PLAY_SLOW_REV_MED
+ignore define CEC_OP_PLAY_MODE_PLAY_SLOW_REV_MAX
+
+ignore define CEC_MSG_GIVE_TUNER_DEVICE_STATUS
+ignore define CEC_MSG_SELECT_ANALOGUE_SERVICE
+ignore define CEC_MSG_SELECT_DIGITAL_SERVICE
+ignore define CEC_MSG_TUNER_DEVICE_STATUS
+
+ignore define CEC_OP_REC_FLAG_USED
+ignore define CEC_OP_REC_FLAG_NOT_USED
+
+ignore define CEC_OP_TUNER_DISPLAY_INFO_DIGITAL
+ignore define CEC_OP_TUNER_DISPLAY_INFO_NONE
+ignore define CEC_OP_TUNER_DISPLAY_INFO_ANALOGUE
+
+ignore define CEC_MSG_TUNER_STEP_DECREMENT
+ignore define CEC_MSG_TUNER_STEP_INCREMENT
+
+ignore define CEC_MSG_DEVICE_VENDOR_ID
+ignore define CEC_MSG_GIVE_DEVICE_VENDOR_ID
+ignore define CEC_MSG_VENDOR_COMMAND
+ignore define CEC_MSG_VENDOR_COMMAND_WITH_ID
+ignore define CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN
+ignore define CEC_MSG_VENDOR_REMOTE_BUTTON_UP
+
+ignore define CEC_MSG_SET_OSD_STRING
+
+ignore define CEC_OP_DISP_CTL_DEFAULT
+ignore define CEC_OP_DISP_CTL_UNTIL_CLEARED
+ignore define CEC_OP_DISP_CTL_CLEAR
+
+ignore define CEC_MSG_GIVE_OSD_NAME
+ignore define CEC_MSG_SET_OSD_NAME
+
+ignore define CEC_MSG_MENU_REQUEST
+
+ignore define CEC_OP_MENU_REQUEST_ACTIVATE
+ignore define CEC_OP_MENU_REQUEST_DEACTIVATE
+ignore define CEC_OP_MENU_REQUEST_QUERY
+
+ignore define CEC_MSG_MENU_STATUS
+
+ignore define CEC_OP_MENU_STATE_ACTIVATED
+ignore define CEC_OP_MENU_STATE_DEACTIVATED
+
+ignore define CEC_MSG_USER_CONTROL_PRESSED
+
+ignore define CEC_OP_UI_CMD_SELECT
+ignore define CEC_OP_UI_CMD_UP
+ignore define CEC_OP_UI_CMD_DOWN
+ignore define CEC_OP_UI_CMD_LEFT
+ignore define CEC_OP_UI_CMD_RIGHT
+ignore define CEC_OP_UI_CMD_RIGHT_UP
+ignore define CEC_OP_UI_CMD_RIGHT_DOWN
+ignore define CEC_OP_UI_CMD_LEFT_UP
+ignore define CEC_OP_UI_CMD_LEFT_DOWN
+ignore define CEC_OP_UI_CMD_DEVICE_ROOT_MENU
+ignore define CEC_OP_UI_CMD_DEVICE_SETUP_MENU
+ignore define CEC_OP_UI_CMD_CONTENTS_MENU
+ignore define CEC_OP_UI_CMD_FAVORITE_MENU
+ignore define CEC_OP_UI_CMD_BACK
+ignore define CEC_OP_UI_CMD_MEDIA_TOP_MENU
+ignore define CEC_OP_UI_CMD_MEDIA_CONTEXT_SENSITIVE_MENU
+ignore define CEC_OP_UI_CMD_NUMBER_ENTRY_MODE
+ignore define CEC_OP_UI_CMD_NUMBER_11
+ignore define CEC_OP_UI_CMD_NUMBER_12
+ignore define CEC_OP_UI_CMD_NUMBER_0_OR_NUMBER_10
+ignore define CEC_OP_UI_CMD_NUMBER_1
+ignore define CEC_OP_UI_CMD_NUMBER_2
+ignore define CEC_OP_UI_CMD_NUMBER_3
+ignore define CEC_OP_UI_CMD_NUMBER_4
+ignore define CEC_OP_UI_CMD_NUMBER_5
+ignore define CEC_OP_UI_CMD_NUMBER_6
+ignore define CEC_OP_UI_CMD_NUMBER_7
+ignore define CEC_OP_UI_CMD_NUMBER_8
+ignore define CEC_OP_UI_CMD_NUMBER_9
+ignore define CEC_OP_UI_CMD_DOT
+ignore define CEC_OP_UI_CMD_ENTER
+ignore define CEC_OP_UI_CMD_CLEAR
+ignore define CEC_OP_UI_CMD_NEXT_FAVORITE
+ignore define CEC_OP_UI_CMD_CHANNEL_UP
+ignore define CEC_OP_UI_CMD_CHANNEL_DOWN
+ignore define CEC_OP_UI_CMD_PREVIOUS_CHANNEL
+ignore define CEC_OP_UI_CMD_SOUND_SELECT
+ignore define CEC_OP_UI_CMD_INPUT_SELECT
+ignore define CEC_OP_UI_CMD_DISPLAY_INFORMATION
+ignore define CEC_OP_UI_CMD_HELP
+ignore define CEC_OP_UI_CMD_PAGE_UP
+ignore define CEC_OP_UI_CMD_PAGE_DOWN
+ignore define CEC_OP_UI_CMD_POWER
+ignore define CEC_OP_UI_CMD_VOLUME_UP
+ignore define CEC_OP_UI_CMD_VOLUME_DOWN
+ignore define CEC_OP_UI_CMD_MUTE
+ignore define CEC_OP_UI_CMD_PLAY
+ignore define CEC_OP_UI_CMD_STOP
+ignore define CEC_OP_UI_CMD_PAUSE
+ignore define CEC_OP_UI_CMD_RECORD
+ignore define CEC_OP_UI_CMD_REWIND
+ignore define CEC_OP_UI_CMD_FAST_FORWARD
+ignore define CEC_OP_UI_CMD_EJECT
+ignore define CEC_OP_UI_CMD_SKIP_FORWARD
+ignore define CEC_OP_UI_CMD_SKIP_BACKWARD
+ignore define CEC_OP_UI_CMD_STOP_RECORD
+ignore define CEC_OP_UI_CMD_PAUSE_RECORD
+ignore define CEC_OP_UI_CMD_ANGLE
+ignore define CEC_OP_UI_CMD_SUB_PICTURE
+ignore define CEC_OP_UI_CMD_VIDEO_ON_DEMAND
+ignore define CEC_OP_UI_CMD_ELECTRONIC_PROGRAM_GUIDE
+ignore define CEC_OP_UI_CMD_TIMER_PROGRAMMING
+ignore define CEC_OP_UI_CMD_INITIAL_CONFIGURATION
+ignore define CEC_OP_UI_CMD_SELECT_BROADCAST_TYPE
+ignore define CEC_OP_UI_CMD_SELECT_SOUND_PRESENTATION
+ignore define CEC_OP_UI_CMD_AUDIO_DESCRIPTION
+ignore define CEC_OP_UI_CMD_INTERNET
+ignore define CEC_OP_UI_CMD_3D_MODE
+ignore define CEC_OP_UI_CMD_PLAY_FUNCTION
+ignore define CEC_OP_UI_CMD_PAUSE_PLAY_FUNCTION
+ignore define CEC_OP_UI_CMD_RECORD_FUNCTION
+ignore define CEC_OP_UI_CMD_PAUSE_RECORD_FUNCTION
+ignore define CEC_OP_UI_CMD_STOP_FUNCTION
+ignore define CEC_OP_UI_CMD_MUTE_FUNCTION
+ignore define CEC_OP_UI_CMD_RESTORE_VOLUME_FUNCTION
+ignore define CEC_OP_UI_CMD_TUNE_FUNCTION
+ignore define CEC_OP_UI_CMD_SELECT_MEDIA_FUNCTION
+ignore define CEC_OP_UI_CMD_SELECT_AV_INPUT_FUNCTION
+ignore define CEC_OP_UI_CMD_SELECT_AUDIO_INPUT_FUNCTION
+ignore define CEC_OP_UI_CMD_POWER_TOGGLE_FUNCTION
+ignore define CEC_OP_UI_CMD_POWER_OFF_FUNCTION
+ignore define CEC_OP_UI_CMD_POWER_ON_FUNCTION
+ignore define CEC_OP_UI_CMD_F1_BLUE
+ignore define CEC_OP_UI_CMD_F2_RED
+ignore define CEC_OP_UI_CMD_F3_GREEN
+ignore define CEC_OP_UI_CMD_F4_YELLOW
+ignore define CEC_OP_UI_CMD_F5
+ignore define CEC_OP_UI_CMD_DATA
+
+ignore define CEC_OP_UI_BCAST_TYPE_TOGGLE_ALL
+ignore define CEC_OP_UI_BCAST_TYPE_TOGGLE_DIG_ANA
+ignore define CEC_OP_UI_BCAST_TYPE_ANALOGUE
+ignore define CEC_OP_UI_BCAST_TYPE_ANALOGUE_T
+ignore define CEC_OP_UI_BCAST_TYPE_ANALOGUE_CABLE
+ignore define CEC_OP_UI_BCAST_TYPE_ANALOGUE_SAT
+ignore define CEC_OP_UI_BCAST_TYPE_DIGITAL
+ignore define CEC_OP_UI_BCAST_TYPE_DIGITAL_T
+ignore define CEC_OP_UI_BCAST_TYPE_DIGITAL_CABLE
+ignore define CEC_OP_UI_BCAST_TYPE_DIGITAL_SAT
+ignore define CEC_OP_UI_BCAST_TYPE_DIGITAL_COM_SAT
+ignore define CEC_OP_UI_BCAST_TYPE_DIGITAL_COM_SAT2
+ignore define CEC_OP_UI_BCAST_TYPE_IP
+
+ignore define CEC_OP_UI_SND_PRES_CTL_DUAL_MONO
+ignore define CEC_OP_UI_SND_PRES_CTL_KARAOKE
+ignore define CEC_OP_UI_SND_PRES_CTL_DOWNMIX
+ignore define CEC_OP_UI_SND_PRES_CTL_REVERB
+ignore define CEC_OP_UI_SND_PRES_CTL_EQUALIZER
+ignore define CEC_OP_UI_SND_PRES_CTL_BASS_UP
+ignore define CEC_OP_UI_SND_PRES_CTL_BASS_NEUTRAL
+ignore define CEC_OP_UI_SND_PRES_CTL_BASS_DOWN
+ignore define CEC_OP_UI_SND_PRES_CTL_TREBLE_UP
+ignore define CEC_OP_UI_SND_PRES_CTL_TREBLE_NEUTRAL
+ignore define CEC_OP_UI_SND_PRES_CTL_TREBLE_DOWN
+
+ignore define CEC_MSG_USER_CONTROL_RELEASED
+
+ignore define CEC_MSG_GIVE_DEVICE_POWER_STATUS
+ignore define CEC_MSG_REPORT_POWER_STATUS
+
+ignore define CEC_OP_POWER_STATUS_ON
+ignore define CEC_OP_POWER_STATUS_STANDBY
+ignore define CEC_OP_POWER_STATUS_TO_ON
+ignore define CEC_OP_POWER_STATUS_TO_STANDBY
+
+ignore define CEC_MSG_FEATURE_ABORT
+
+ignore define CEC_OP_ABORT_UNRECOGNIZED_OP
+ignore define CEC_OP_ABORT_INCORRECT_MODE
+ignore define CEC_OP_ABORT_NO_SOURCE
+ignore define CEC_OP_ABORT_INVALID_OP
+ignore define CEC_OP_ABORT_REFUSED
+ignore define CEC_OP_ABORT_UNDETERMINED
+
+ignore define CEC_MSG_ABORT
+
+ignore define CEC_MSG_GIVE_AUDIO_STATUS
+ignore define CEC_MSG_GIVE_SYSTEM_AUDIO_MODE_STATUS
+ignore define CEC_MSG_REPORT_AUDIO_STATUS
+
+ignore define CEC_OP_AUD_MUTE_STATUS_OFF
+ignore define CEC_OP_AUD_MUTE_STATUS_ON
+
+ignore define CEC_MSG_REPORT_SHORT_AUDIO_DESCRIPTOR
+ignore define CEC_MSG_REQUEST_SHORT_AUDIO_DESCRIPTOR
+ignore define CEC_MSG_SET_SYSTEM_AUDIO_MODE
+
+ignore define CEC_OP_SYS_AUD_STATUS_OFF
+ignore define CEC_OP_SYS_AUD_STATUS_ON
+
+ignore define CEC_MSG_SYSTEM_AUDIO_MODE_REQUEST
+ignore define CEC_MSG_SYSTEM_AUDIO_MODE_STATUS
+
+ignore define CEC_OP_AUD_FMT_ID_CEA861
+ignore define CEC_OP_AUD_FMT_ID_CEA861_CXT
+
+ignore define CEC_MSG_SET_AUDIO_RATE
+
+ignore define CEC_OP_AUD_RATE_OFF
+ignore define CEC_OP_AUD_RATE_WIDE_STD
+ignore define CEC_OP_AUD_RATE_WIDE_FAST
+ignore define CEC_OP_AUD_RATE_WIDE_SLOW
+ignore define CEC_OP_AUD_RATE_NARROW_STD
+ignore define CEC_OP_AUD_RATE_NARROW_FAST
+ignore define CEC_OP_AUD_RATE_NARROW_SLOW
+
+ignore define CEC_MSG_INITIATE_ARC
+ignore define CEC_MSG_REPORT_ARC_INITIATED
+ignore define CEC_MSG_REPORT_ARC_TERMINATED
+ignore define CEC_MSG_REQUEST_ARC_INITIATION
+ignore define CEC_MSG_REQUEST_ARC_TERMINATION
+ignore define CEC_MSG_TERMINATE_ARC
+
+ignore define CEC_MSG_REQUEST_CURRENT_LATENCY
+ignore define CEC_MSG_REPORT_CURRENT_LATENCY
+
+ignore define CEC_OP_LOW_LATENCY_MODE_OFF
+ignore define CEC_OP_LOW_LATENCY_MODE_ON
+
+ignore define CEC_OP_AUD_OUT_COMPENSATED_NA
+ignore define CEC_OP_AUD_OUT_COMPENSATED_DELAY
+ignore define CEC_OP_AUD_OUT_COMPENSATED_NO_DELAY
+ignore define CEC_OP_AUD_OUT_COMPENSATED_PARTIAL_DELAY
+
+ignore define CEC_MSG_CDC_MESSAGE
+
+ignore define CEC_MSG_CDC_HEC_INQUIRE_STATE
+ignore define CEC_MSG_CDC_HEC_REPORT_STATE
+
+ignore define CEC_OP_HEC_FUNC_STATE_NOT_SUPPORTED
+ignore define CEC_OP_HEC_FUNC_STATE_INACTIVE
+ignore define CEC_OP_HEC_FUNC_STATE_ACTIVE
+ignore define CEC_OP_HEC_FUNC_STATE_ACTIVATION_FIELD
+
+ignore define CEC_OP_HOST_FUNC_STATE_NOT_SUPPORTED
+ignore define CEC_OP_HOST_FUNC_STATE_INACTIVE
+ignore define CEC_OP_HOST_FUNC_STATE_ACTIVE
+
+ignore define CEC_OP_ENC_FUNC_STATE_EXT_CON_NOT_SUPPORTED
+ignore define CEC_OP_ENC_FUNC_STATE_EXT_CON_INACTIVE
+ignore define CEC_OP_ENC_FUNC_STATE_EXT_CON_ACTIVE
+
+ignore define CEC_OP_CDC_ERROR_CODE_NONE
+ignore define CEC_OP_CDC_ERROR_CODE_CAP_UNSUPPORTED
+ignore define CEC_OP_CDC_ERROR_CODE_WRONG_STATE
+ignore define CEC_OP_CDC_ERROR_CODE_OTHER
+
+ignore define CEC_OP_HEC_SUPPORT_NO
+ignore define CEC_OP_HEC_SUPPORT_YES
+
+ignore define CEC_OP_HEC_ACTIVATION_ON
+ignore define CEC_OP_HEC_ACTIVATION_OFF
+
+ignore define CEC_MSG_CDC_HEC_SET_STATE_ADJACENT
+ignore define CEC_MSG_CDC_HEC_SET_STATE
+
+ignore define CEC_OP_HEC_SET_STATE_DEACTIVATE
+ignore define CEC_OP_HEC_SET_STATE_ACTIVATE
+
+ignore define CEC_MSG_CDC_HEC_REQUEST_DEACTIVATION
+ignore define CEC_MSG_CDC_HEC_NOTIFY_ALIVE
+ignore define CEC_MSG_CDC_HEC_DISCOVER
+
+ignore define CEC_MSG_CDC_HPD_SET_STATE
+
+ignore define CEC_OP_HPD_STATE_CP_EDID_DISABLE
+ignore define CEC_OP_HPD_STATE_CP_EDID_ENABLE
+ignore define CEC_OP_HPD_STATE_CP_EDID_DISABLE_ENABLE
+ignore define CEC_OP_HPD_STATE_EDID_DISABLE
+ignore define CEC_OP_HPD_STATE_EDID_ENABLE
+ignore define CEC_OP_HPD_STATE_EDID_DISABLE_ENABLE
+ignore define CEC_MSG_CDC_HPD_REPORT_STATE
+
+ignore define CEC_OP_HPD_ERROR_NONE
+ignore define CEC_OP_HPD_ERROR_INITIATOR_NOT_CAPABLE
+ignore define CEC_OP_HPD_ERROR_INITIATOR_WRONG_STATE
+ignore define CEC_OP_HPD_ERROR_OTHER
+ignore define CEC_OP_HPD_ERROR_NONE_NO_VIDEO
diff --git a/Documentation/userspace-api/media/cec/cec-api.rst b/Documentation/userspace-api/media/cec/cec-api.rst
new file mode 100644
index 000000000000..871db54dfd24
--- /dev/null
+++ b/Documentation/userspace-api/media/cec/cec-api.rst
@@ -0,0 +1,54 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. include:: <isonum.txt>
+
+.. _cec:
+
+#########################################
+Part V - Consumer Electronics Control API
+#########################################
+
+This part describes the CEC: Consumer Electronics Control
+
+
+.. only:: html
+
+   .. class:: toc-title
+
+        Table of Contents
+
+.. toctree::
+    :maxdepth: 5
+    :numbered:
+
+    cec-intro
+    cec-funcs
+    cec-pin-error-inj
+    cec-header
+
+
+**********************
+Revision and Copyright
+**********************
+Authors:
+
+- Verkuil, Hans <hverkuil-cisco@xs4all.nl>
+
+ - Initial version.
+
+**Copyright** |copy| 2016 : Hans Verkuil
+
+****************
+Revision History
+****************
+
+:revision: 1.0.0 / 2016-03-17 (*hv*)
+
+Initial revision
diff --git a/Documentation/userspace-api/media/cec/cec-func-close.rst b/Documentation/userspace-api/media/cec/cec-func-close.rst
new file mode 100644
index 000000000000..b89e06a43dad
--- /dev/null
+++ b/Documentation/userspace-api/media/cec/cec-func-close.rst
@@ -0,0 +1,54 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _cec-func-close:
+
+***********
+cec close()
+***********
+
+Name
+====
+
+cec-close - Close a cec device
+
+
+Synopsis
+========
+
+.. code-block:: c
+
+    #include <unistd.h>
+
+
+.. c:function:: int close( int fd )
+    :name: cec-close
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :c:func:`open() <cec-open>`.
+
+
+Description
+===========
+
+Closes the cec device. Resources associated with the file descriptor are
+freed. The device configuration remain unchanged.
+
+
+Return Value
+============
+
+:c:func:`close() <cec-close>` returns 0 on success. On error, -1 is returned, and
+``errno`` is set appropriately. Possible error codes are:
+
+``EBADF``
+    ``fd`` is not a valid open file descriptor.
diff --git a/Documentation/userspace-api/media/cec/cec-func-ioctl.rst b/Documentation/userspace-api/media/cec/cec-func-ioctl.rst
new file mode 100644
index 000000000000..d16a479aacb1
--- /dev/null
+++ b/Documentation/userspace-api/media/cec/cec-func-ioctl.rst
@@ -0,0 +1,73 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _cec-func-ioctl:
+
+***********
+cec ioctl()
+***********
+
+Name
+====
+
+cec-ioctl - Control a cec device
+
+Synopsis
+========
+
+.. code-block:: c
+
+    #include <sys/ioctl.h>
+
+
+.. c:function:: int ioctl( int fd, int request, void *argp )
+   :name: cec-ioctl
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :c:func:`open() <cec-open>`.
+
+``request``
+    CEC ioctl request code as defined in the cec.h header file, for
+    example :ref:`CEC_ADAP_G_CAPS <CEC_ADAP_G_CAPS>`.
+
+``argp``
+    Pointer to a request-specific structure.
+
+
+Description
+===========
+
+The :c:func:`ioctl() <cec-ioctl>` function manipulates cec device parameters. The
+argument ``fd`` must be an open file descriptor.
+
+The ioctl ``request`` code specifies the cec function to be called. It
+has encoded in it whether the argument is an input, output or read/write
+parameter, and the size of the argument ``argp`` in bytes.
+
+Macros and structures definitions specifying cec ioctl requests and
+their parameters are located in the cec.h header file. All cec ioctl
+requests, their respective function and parameters are specified in
+:ref:`cec-user-func`.
+
+
+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.
+
+Request-specific error codes are listed in the individual requests
+descriptions.
+
+When an ioctl that takes an output or read/write parameter fails, the
+parameter remains unmodified.
diff --git a/Documentation/userspace-api/media/cec/cec-func-open.rst b/Documentation/userspace-api/media/cec/cec-func-open.rst
new file mode 100644
index 000000000000..67fd021556b2
--- /dev/null
+++ b/Documentation/userspace-api/media/cec/cec-func-open.rst
@@ -0,0 +1,85 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _cec-func-open:
+
+**********
+cec open()
+**********
+
+Name
+====
+
+cec-open - Open a cec device
+
+Synopsis
+========
+
+.. code-block:: c
+
+    #include <fcntl.h>
+
+
+.. c:function:: int open( const char *device_name, int flags )
+   :name: cec-open
+
+
+Arguments
+=========
+
+``device_name``
+    Device to be opened.
+
+``flags``
+    Open flags. Access mode must be ``O_RDWR``.
+
+    When the ``O_NONBLOCK`` flag is given, the
+    :ref:`CEC_RECEIVE <CEC_RECEIVE>` and :ref:`CEC_DQEVENT <CEC_DQEVENT>` ioctls
+    will return the ``EAGAIN`` error code when no message or event is available, and
+    ioctls :ref:`CEC_TRANSMIT <CEC_TRANSMIT>`,
+    :ref:`CEC_ADAP_S_PHYS_ADDR <CEC_ADAP_S_PHYS_ADDR>` and
+    :ref:`CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`
+    all return 0.
+
+    Other flags have no effect.
+
+
+Description
+===========
+
+To open a cec device applications call :c:func:`open() <cec-open>` with the
+desired device name. The function has no side effects; the device
+configuration remain unchanged.
+
+When the device is opened in read-only mode, attempts to modify its
+configuration will result in an error, and ``errno`` will be set to
+EBADF.
+
+
+Return Value
+============
+
+:c:func:`open() <cec-open>` returns the new file descriptor on success. On error,
+-1 is returned, and ``errno`` is set appropriately. Possible error codes
+include:
+
+``EACCES``
+    The requested access to the file is not allowed.
+
+``EMFILE``
+    The process already has the maximum number of files open.
+
+``ENFILE``
+    The system limit on the total number of open files has been reached.
+
+``ENOMEM``
+    Insufficient kernel memory was available.
+
+``ENXIO``
+    No device corresponding to this device special file exists.
diff --git a/Documentation/userspace-api/media/cec/cec-func-poll.rst b/Documentation/userspace-api/media/cec/cec-func-poll.rst
new file mode 100644
index 000000000000..ed3652d9bf17
--- /dev/null
+++ b/Documentation/userspace-api/media/cec/cec-func-poll.rst
@@ -0,0 +1,85 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _cec-func-poll:
+
+**********
+cec poll()
+**********
+
+Name
+====
+
+cec-poll - Wait for some event on a file descriptor
+
+
+Synopsis
+========
+
+.. code-block:: c
+
+    #include <sys/poll.h>
+
+
+.. c:function:: int poll( struct pollfd *ufds, unsigned int nfds, int timeout )
+   :name: cec-poll
+
+Arguments
+=========
+
+``ufds``
+   List of FD events to be watched
+
+``nfds``
+   Number of FD events at the \*ufds array
+
+``timeout``
+   Timeout to wait for events
+
+
+Description
+===========
+
+With the :c:func:`poll() <cec-poll>` function applications can wait for CEC
+events.
+
+On success :c:func:`poll() <cec-poll>` returns the number of file descriptors
+that have been selected (that is, file descriptors for which the
+``revents`` field of the respective struct :c:type:`pollfd`
+is non-zero). CEC devices set the ``POLLIN`` and ``POLLRDNORM`` flags in
+the ``revents`` field if there are messages in the receive queue. If the
+transmit queue has room for new messages, the ``POLLOUT`` and
+``POLLWRNORM`` flags are set. If there are events in the event queue,
+then the ``POLLPRI`` flag is set. When the function times out it returns
+a value of zero, on failure it returns -1 and the ``errno`` variable is
+set appropriately.
+
+For more details see the :c:func:`poll() <cec-poll>` manual page.
+
+
+Return Value
+============
+
+On success, :c:func:`poll() <cec-poll>` returns the number structures which have
+non-zero ``revents`` fields, or zero if the call timed out. On error -1
+is returned, and the ``errno`` variable is set appropriately:
+
+``EBADF``
+    One or more of the ``ufds`` members specify an invalid file
+    descriptor.
+
+``EFAULT``
+    ``ufds`` references an inaccessible memory area.
+
+``EINTR``
+    The call was interrupted by a signal.
+
+``EINVAL``
+    The ``nfds`` value exceeds the ``RLIMIT_NOFILE`` value. Use
+    ``getrlimit()`` to obtain this value.
diff --git a/Documentation/userspace-api/media/cec/cec-funcs.rst b/Documentation/userspace-api/media/cec/cec-funcs.rst
new file mode 100644
index 000000000000..88966b5175d2
--- /dev/null
+++ b/Documentation/userspace-api/media/cec/cec-funcs.rst
@@ -0,0 +1,30 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _cec-user-func:
+
+******************
+Function Reference
+******************
+
+
+.. toctree::
+    :maxdepth: 1
+
+    cec-func-open
+    cec-func-close
+    cec-func-ioctl
+    cec-func-poll
+    cec-ioc-adap-g-caps
+    cec-ioc-adap-g-log-addrs
+    cec-ioc-adap-g-phys-addr
+    cec-ioc-adap-g-conn-info
+    cec-ioc-dqevent
+    cec-ioc-g-mode
+    cec-ioc-receive
diff --git a/Documentation/userspace-api/media/cec/cec-header.rst b/Documentation/userspace-api/media/cec/cec-header.rst
new file mode 100644
index 000000000000..24a83b0c35af
--- /dev/null
+++ b/Documentation/userspace-api/media/cec/cec-header.rst
@@ -0,0 +1,17 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _cec_header:
+
+***************
+CEC Header File
+***************
+
+.. kernel-include:: $BUILDDIR/cec.h.rst
+
diff --git a/Documentation/userspace-api/media/cec/cec-intro.rst b/Documentation/userspace-api/media/cec/cec-intro.rst
new file mode 100644
index 000000000000..a4db82388202
--- /dev/null
+++ b/Documentation/userspace-api/media/cec/cec-intro.rst
@@ -0,0 +1,49 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _cec-intro:
+
+Introduction
+============
+
+HDMI connectors provide a single pin for use by the Consumer Electronics
+Control protocol. This protocol allows different devices connected by an
+HDMI cable to communicate. The protocol for CEC version 1.4 is defined
+in supplements 1 (CEC) and 2 (HEAC or HDMI Ethernet and Audio Return
+Channel) of the HDMI 1.4a (:ref:`hdmi`) specification and the
+extensions added to CEC version 2.0 are defined in chapter 11 of the
+HDMI 2.0 (:ref:`hdmi2`) specification.
+
+The bitrate is very slow (effectively no more than 36 bytes per second)
+and is based on the ancient AV.link protocol used in old SCART
+connectors. The protocol closely resembles a crazy Rube Goldberg
+contraption and is an unholy mix of low and high level messages. Some
+messages, especially those part of the HEAC protocol layered on top of
+CEC, need to be handled by the kernel, others can be handled either by
+the kernel or by userspace.
+
+In addition, CEC can be implemented in HDMI receivers, transmitters and
+in USB devices that have an HDMI input and an HDMI output and that
+control just the CEC pin.
+
+Drivers that support CEC will create a CEC device node (/dev/cecX) to
+give userspace access to the CEC adapter. The
+:ref:`CEC_ADAP_G_CAPS` ioctl will tell userspace what it is allowed to do.
+
+In order to check the support and test it, it is suggested to download
+the `v4l-utils <https://git.linuxtv.org/v4l-utils.git/>`_ package. It
+provides three tools to handle CEC:
+
+- cec-ctl: the Swiss army knife of CEC. Allows you to configure, transmit
+  and monitor CEC messages.
+
+- cec-compliance: does a CEC compliance test of a remote CEC device to
+  determine how compliant the CEC implementation is.
+
+- cec-follower: emulates a CEC follower.
diff --git a/Documentation/userspace-api/media/cec/cec-ioc-adap-g-caps.rst b/Documentation/userspace-api/media/cec/cec-ioc-adap-g-caps.rst
new file mode 100644
index 000000000000..94e46a11d68d
--- /dev/null
+++ b/Documentation/userspace-api/media/cec/cec-ioc-adap-g-caps.rst
@@ -0,0 +1,150 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _CEC_ADAP_G_CAPS:
+
+*********************
+ioctl CEC_ADAP_G_CAPS
+*********************
+
+Name
+====
+
+CEC_ADAP_G_CAPS - Query device capabilities
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, CEC_ADAP_G_CAPS, struct cec_caps *argp )
+    :name: CEC_ADAP_G_CAPS
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :c:func:`open() <cec-open>`.
+
+``argp``
+
+
+Description
+===========
+
+All cec devices must support :ref:`ioctl CEC_ADAP_G_CAPS <CEC_ADAP_G_CAPS>`. To query
+device information, applications call the ioctl with a pointer to a
+struct :c:type:`cec_caps`. The driver fills the structure and
+returns the information to the application. The ioctl never fails.
+
+.. tabularcolumns:: |p{1.2cm}|p{2.5cm}|p{13.8cm}|
+
+.. c:type:: cec_caps
+
+.. flat-table:: struct cec_caps
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 16
+
+    * - char
+      - ``driver[32]``
+      - The name of the cec adapter driver.
+    * - char
+      - ``name[32]``
+      - The name of this CEC adapter. The combination ``driver`` and
+	``name`` must be unique.
+    * - __u32
+      - ``capabilities``
+      - The capabilities of the CEC adapter, see
+	:ref:`cec-capabilities`.
+    * - __u32
+      - ``version``
+      - CEC Framework API version, formatted with the ``KERNEL_VERSION()``
+	macro.
+
+
+.. tabularcolumns:: |p{4.4cm}|p{2.5cm}|p{10.6cm}|
+
+.. _cec-capabilities:
+
+.. flat-table:: CEC Capabilities Flags
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 8
+
+    * .. _`CEC-CAP-PHYS-ADDR`:
+
+      - ``CEC_CAP_PHYS_ADDR``
+      - 0x00000001
+      - Userspace has to configure the physical address by calling
+	:ref:`ioctl CEC_ADAP_S_PHYS_ADDR <CEC_ADAP_S_PHYS_ADDR>`. If
+	this capability isn't set, then setting the physical address is
+	handled by the kernel whenever the EDID is set (for an HDMI
+	receiver) or read (for an HDMI transmitter).
+    * .. _`CEC-CAP-LOG-ADDRS`:
+
+      - ``CEC_CAP_LOG_ADDRS``
+      - 0x00000002
+      - Userspace has to configure the logical addresses by calling
+	:ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`. If
+	this capability isn't set, then the kernel will have configured
+	this.
+    * .. _`CEC-CAP-TRANSMIT`:
+
+      - ``CEC_CAP_TRANSMIT``
+      - 0x00000004
+      - Userspace can transmit CEC messages by calling
+	:ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>`. This implies that
+	userspace can be a follower as well, since being able to transmit
+	messages is a prerequisite of becoming a follower. If this
+	capability isn't set, then the kernel will handle all CEC
+	transmits and process all CEC messages it receives.
+    * .. _`CEC-CAP-PASSTHROUGH`:
+
+      - ``CEC_CAP_PASSTHROUGH``
+      - 0x00000008
+      - Userspace can use the passthrough mode by calling
+	:ref:`ioctl CEC_S_MODE <CEC_S_MODE>`.
+    * .. _`CEC-CAP-RC`:
+
+      - ``CEC_CAP_RC``
+      - 0x00000010
+      - This adapter supports the remote control protocol.
+    * .. _`CEC-CAP-MONITOR-ALL`:
+
+      - ``CEC_CAP_MONITOR_ALL``
+      - 0x00000020
+      - The CEC hardware can monitor all messages, not just directed and
+	broadcast messages.
+    * .. _`CEC-CAP-NEEDS-HPD`:
+
+      - ``CEC_CAP_NEEDS_HPD``
+      - 0x00000040
+      - The CEC hardware is only active if the HDMI Hotplug Detect pin is
+        high. This makes it impossible to use CEC to wake up displays that
+	set the HPD pin low when in standby mode, but keep the CEC bus
+	alive.
+    * .. _`CEC-CAP-MONITOR-PIN`:
+
+      - ``CEC_CAP_MONITOR_PIN``
+      - 0x00000080
+      - The CEC hardware can monitor CEC pin changes from low to high voltage
+        and vice versa. When in pin monitoring mode the application will
+	receive ``CEC_EVENT_PIN_CEC_LOW`` and ``CEC_EVENT_PIN_CEC_HIGH`` events.
+    * .. _`CEC-CAP-CONNECTOR-INFO`:
+
+      - ``CEC_CAP_CONNECTOR_INFO``
+      - 0x00000100
+      - If this capability is set, then :ref:`CEC_ADAP_G_CONNECTOR_INFO` can
+        be used.
+
+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/userspace-api/media/cec/cec-ioc-adap-g-conn-info.rst b/Documentation/userspace-api/media/cec/cec-ioc-adap-g-conn-info.rst
new file mode 100644
index 000000000000..6818ddf1495c
--- /dev/null
+++ b/Documentation/userspace-api/media/cec/cec-ioc-adap-g-conn-info.rst
@@ -0,0 +1,105 @@
+.. SPDX-License-Identifier: GPL-2.0
+..
+.. Copyright 2019 Google LLC
+..
+.. _CEC_ADAP_G_CONNECTOR_INFO:
+
+*******************************
+ioctl CEC_ADAP_G_CONNECTOR_INFO
+*******************************
+
+Name
+====
+
+CEC_ADAP_G_CONNECTOR_INFO - Query HDMI connector information
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, CEC_ADAP_G_CONNECTOR_INFO, struct cec_connector_info *argp )
+    :name: CEC_ADAP_G_CONNECTOR_INFO
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :c:func:`open() <cec-open>`.
+
+``argp``
+
+
+Description
+===========
+
+Using this ioctl an application can learn which HDMI connector this CEC
+device corresponds to. While calling this ioctl the application should
+provide a pointer to a cec_connector_info struct which will be populated
+by the kernel with the info provided by the adapter's driver. This ioctl
+is only available if the ``CEC_CAP_CONNECTOR_INFO`` capability is set.
+
+.. tabularcolumns:: |p{1.0cm}|p{4.4cm}|p{2.5cm}|p{9.6cm}|
+
+.. c:type:: cec_connector_info
+
+.. flat-table:: struct cec_connector_info
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 8
+
+    * - __u32
+      - ``type``
+      - The type of connector this adapter is associated with.
+    * - union {
+      - ``(anonymous)``
+    * - ``struct cec_drm_connector_info``
+      - drm
+      - :ref:`cec-drm-connector-info`
+    * - }
+      -
+
+
+.. tabularcolumns:: |p{4.4cm}|p{2.5cm}|p{10.6cm}|
+
+.. _connector-type:
+
+.. flat-table:: Connector types
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 8
+
+    * .. _`CEC-CONNECTOR-TYPE-NO-CONNECTOR`:
+
+      - ``CEC_CONNECTOR_TYPE_NO_CONNECTOR``
+      - 0
+      - No connector is associated with the adapter/the information is not
+        provided by the driver.
+    * .. _`CEC-CONNECTOR-TYPE-DRM`:
+
+      - ``CEC_CONNECTOR_TYPE_DRM``
+      - 1
+      - Indicates that a DRM connector is associated with this adapter.
+        Information about the connector can be found in
+	:ref:`cec-drm-connector-info`.
+
+.. tabularcolumns:: |p{4.4cm}|p{2.5cm}|p{10.6cm}|
+
+.. c:type:: cec_drm_connector_info
+
+.. _cec-drm-connector-info:
+
+.. flat-table:: struct cec_drm_connector_info
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 8
+
+    * .. _`CEC-DRM-CONNECTOR-TYPE-CARD-NO`:
+
+      - __u32
+      - ``card_no``
+      - DRM card number: the number from a card's path, e.g. 0 in case of
+        /dev/card0.
+    * .. _`CEC-DRM-CONNECTOR-TYPE-CONNECTOR_ID`:
+
+      - __u32
+      - ``connector_id``
+      - DRM connector ID.
diff --git a/Documentation/userspace-api/media/cec/cec-ioc-adap-g-log-addrs.rst b/Documentation/userspace-api/media/cec/cec-ioc-adap-g-log-addrs.rst
new file mode 100644
index 000000000000..8ba3511c88b8
--- /dev/null
+++ b/Documentation/userspace-api/media/cec/cec-ioc-adap-g-log-addrs.rst
@@ -0,0 +1,378 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _CEC_ADAP_LOG_ADDRS:
+.. _CEC_ADAP_G_LOG_ADDRS:
+.. _CEC_ADAP_S_LOG_ADDRS:
+
+****************************************************
+ioctls CEC_ADAP_G_LOG_ADDRS and CEC_ADAP_S_LOG_ADDRS
+****************************************************
+
+Name
+====
+
+CEC_ADAP_G_LOG_ADDRS, CEC_ADAP_S_LOG_ADDRS - Get or set the logical addresses
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, CEC_ADAP_G_LOG_ADDRS, struct cec_log_addrs *argp )
+   :name: CEC_ADAP_G_LOG_ADDRS
+
+.. c:function:: int ioctl( int fd, CEC_ADAP_S_LOG_ADDRS, struct cec_log_addrs *argp )
+   :name: CEC_ADAP_S_LOG_ADDRS
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :c:func:`open() <cec-open>`.
+
+``argp``
+    Pointer to struct :c:type:`cec_log_addrs`.
+
+Description
+===========
+
+To query the current CEC logical addresses, applications call
+:ref:`ioctl CEC_ADAP_G_LOG_ADDRS <CEC_ADAP_G_LOG_ADDRS>` with a pointer to a
+struct :c:type:`cec_log_addrs` where the driver stores the logical addresses.
+
+To set new logical addresses, applications fill in
+struct :c:type:`cec_log_addrs` and call :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`
+with a pointer to this struct. The :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`
+is only available if ``CEC_CAP_LOG_ADDRS`` is set (the ``ENOTTY`` error code is
+returned otherwise). The :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`
+can only be called by a file descriptor in initiator mode (see :ref:`CEC_S_MODE`), if not
+the ``EBUSY`` error code will be returned.
+
+To clear existing logical addresses set ``num_log_addrs`` to 0. All other fields
+will be ignored in that case. The adapter will go to the unconfigured state and the
+``cec_version``, ``vendor_id`` and ``osd_name`` fields are all reset to their default
+values (CEC version 2.0, no vendor ID and an empty OSD name).
+
+If the physical address is valid (see :ref:`ioctl CEC_ADAP_S_PHYS_ADDR <CEC_ADAP_S_PHYS_ADDR>`),
+then this ioctl will block until all requested logical
+addresses have been claimed. If the file descriptor is in non-blocking mode then it will
+not wait for the logical addresses to be claimed, instead it just returns 0.
+
+A :ref:`CEC_EVENT_STATE_CHANGE <CEC-EVENT-STATE-CHANGE>` event is sent when the
+logical addresses are claimed or cleared.
+
+Attempting to call :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>` when
+logical address types are already defined will return with error ``EBUSY``.
+
+.. c:type:: cec_log_addrs
+
+.. tabularcolumns:: |p{1.0cm}|p{8.0cm}|p{7.5cm}|
+
+.. cssclass:: longtable
+
+.. flat-table:: struct cec_log_addrs
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 16
+
+    * - __u8
+      - ``log_addr[CEC_MAX_LOG_ADDRS]``
+      - The actual logical addresses that were claimed. This is set by the
+	driver. If no logical address could be claimed, then it is set to
+	``CEC_LOG_ADDR_INVALID``. If this adapter is Unregistered, then
+	``log_addr[0]`` is set to 0xf and all others to
+	``CEC_LOG_ADDR_INVALID``.
+    * - __u16
+      - ``log_addr_mask``
+      - The bitmask of all logical addresses this adapter has claimed. If
+	this adapter is Unregistered then ``log_addr_mask`` sets bit 15
+	and clears all other bits. If this adapter is not configured at
+	all, then ``log_addr_mask`` is set to 0. Set by the driver.
+    * - __u8
+      - ``cec_version``
+      - The CEC version that this adapter shall use. See
+	:ref:`cec-versions`. Used to implement the
+	``CEC_MSG_CEC_VERSION`` and ``CEC_MSG_REPORT_FEATURES`` messages.
+	Note that :ref:`CEC_OP_CEC_VERSION_1_3A <CEC-OP-CEC-VERSION-1-3A>` is not allowed by the CEC
+	framework.
+    * - __u8
+      - ``num_log_addrs``
+      - Number of logical addresses to set up. Must be ≤
+	``available_log_addrs`` as returned by
+	:ref:`CEC_ADAP_G_CAPS`. All arrays in
+	this structure are only filled up to index
+	``available_log_addrs``-1. The remaining array elements will be
+	ignored. Note that the CEC 2.0 standard allows for a maximum of 2
+	logical addresses, although some hardware has support for more.
+	``CEC_MAX_LOG_ADDRS`` is 4. The driver will return the actual
+	number of logical addresses it could claim, which may be less than
+	what was requested. If this field is set to 0, then the CEC
+	adapter shall clear all claimed logical addresses and all other
+	fields will be ignored.
+    * - __u32
+      - ``vendor_id``
+      - The vendor ID is a 24-bit number that identifies the specific
+	vendor or entity. Based on this ID vendor specific commands may be
+	defined. If you do not want a vendor ID then set it to
+	``CEC_VENDOR_ID_NONE``.
+    * - __u32
+      - ``flags``
+      - Flags. See :ref:`cec-log-addrs-flags` for a list of available flags.
+    * - char
+      - ``osd_name[15]``
+      - The On-Screen Display name as is returned by the
+	``CEC_MSG_SET_OSD_NAME`` message.
+    * - __u8
+      - ``primary_device_type[CEC_MAX_LOG_ADDRS]``
+      - Primary device type for each logical address. See
+	:ref:`cec-prim-dev-types` for possible types.
+    * - __u8
+      - ``log_addr_type[CEC_MAX_LOG_ADDRS]``
+      - Logical address types. See :ref:`cec-log-addr-types` for
+	possible types. The driver will update this with the actual
+	logical address type that it claimed (e.g. it may have to fallback
+	to :ref:`CEC_LOG_ADDR_TYPE_UNREGISTERED <CEC-LOG-ADDR-TYPE-UNREGISTERED>`).
+    * - __u8
+      - ``all_device_types[CEC_MAX_LOG_ADDRS]``
+      - CEC 2.0 specific: the bit mask of all device types. See
+	:ref:`cec-all-dev-types-flags`. It is used in the CEC 2.0
+	``CEC_MSG_REPORT_FEATURES`` message. For CEC 1.4 you can either leave
+	this field to 0, or fill it in according to the CEC 2.0 guidelines to
+	give the CEC framework more information about the device type, even
+	though the framework won't use it directly in the CEC message.
+    * - __u8
+      - ``features[CEC_MAX_LOG_ADDRS][12]``
+      - Features for each logical address. It is used in the CEC 2.0
+	``CEC_MSG_REPORT_FEATURES`` message. The 12 bytes include both the
+	RC Profile and the Device Features. For CEC 1.4 you can either leave
+        this field to all 0, or fill it in according to the CEC 2.0 guidelines to
+        give the CEC framework more information about the device type, even
+        though the framework won't use it directly in the CEC message.
+
+
+.. tabularcolumns:: |p{7.8cm}|p{1.0cm}|p{8.7cm}|
+
+.. _cec-log-addrs-flags:
+
+.. flat-table:: Flags for struct cec_log_addrs
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * .. _`CEC-LOG-ADDRS-FL-ALLOW-UNREG-FALLBACK`:
+
+      - ``CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK``
+      - 1
+      - By default if no logical address of the requested type can be claimed, then
+	it will go back to the unconfigured state. If this flag is set, then it will
+	fallback to the Unregistered logical address. Note that if the Unregistered
+	logical address was explicitly requested, then this flag has no effect.
+    * .. _`CEC-LOG-ADDRS-FL-ALLOW-RC-PASSTHRU`:
+
+      - ``CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU``
+      - 2
+      - By default the ``CEC_MSG_USER_CONTROL_PRESSED`` and ``CEC_MSG_USER_CONTROL_RELEASED``
+        messages are only passed on to the follower(s), if any. If this flag is set,
+	then these messages are also passed on to the remote control input subsystem
+	and will appear as keystrokes. This features needs to be enabled explicitly.
+	If CEC is used to enter e.g. passwords, then you may not want to enable this
+	to avoid trivial snooping of the keystrokes.
+    * .. _`CEC-LOG-ADDRS-FL-CDC-ONLY`:
+
+      - ``CEC_LOG_ADDRS_FL_CDC_ONLY``
+      - 4
+      - If this flag is set, then the device is CDC-Only. CDC-Only CEC devices
+	are CEC devices that can only handle CDC messages.
+
+	All other messages are ignored.
+
+
+.. tabularcolumns:: |p{7.8cm}|p{1.0cm}|p{8.7cm}|
+
+.. _cec-versions:
+
+.. flat-table:: CEC Versions
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * .. _`CEC-OP-CEC-VERSION-1-3A`:
+
+      - ``CEC_OP_CEC_VERSION_1_3A``
+      - 4
+      - CEC version according to the HDMI 1.3a standard.
+    * .. _`CEC-OP-CEC-VERSION-1-4B`:
+
+      - ``CEC_OP_CEC_VERSION_1_4B``
+      - 5
+      - CEC version according to the HDMI 1.4b standard.
+    * .. _`CEC-OP-CEC-VERSION-2-0`:
+
+      - ``CEC_OP_CEC_VERSION_2_0``
+      - 6
+      - CEC version according to the HDMI 2.0 standard.
+
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. _cec-prim-dev-types:
+
+.. flat-table:: CEC Primary Device Types
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * .. _`CEC-OP-PRIM-DEVTYPE-TV`:
+
+      - ``CEC_OP_PRIM_DEVTYPE_TV``
+      - 0
+      - Use for a TV.
+    * .. _`CEC-OP-PRIM-DEVTYPE-RECORD`:
+
+      - ``CEC_OP_PRIM_DEVTYPE_RECORD``
+      - 1
+      - Use for a recording device.
+    * .. _`CEC-OP-PRIM-DEVTYPE-TUNER`:
+
+      - ``CEC_OP_PRIM_DEVTYPE_TUNER``
+      - 3
+      - Use for a device with a tuner.
+    * .. _`CEC-OP-PRIM-DEVTYPE-PLAYBACK`:
+
+      - ``CEC_OP_PRIM_DEVTYPE_PLAYBACK``
+      - 4
+      - Use for a playback device.
+    * .. _`CEC-OP-PRIM-DEVTYPE-AUDIOSYSTEM`:
+
+      - ``CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM``
+      - 5
+      - Use for an audio system (e.g. an audio/video receiver).
+    * .. _`CEC-OP-PRIM-DEVTYPE-SWITCH`:
+
+      - ``CEC_OP_PRIM_DEVTYPE_SWITCH``
+      - 6
+      - Use for a CEC switch.
+    * .. _`CEC-OP-PRIM-DEVTYPE-VIDEOPROC`:
+
+      - ``CEC_OP_PRIM_DEVTYPE_VIDEOPROC``
+      - 7
+      - Use for a video processor device.
+
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. _cec-log-addr-types:
+
+.. flat-table:: CEC Logical Address Types
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 16
+
+    * .. _`CEC-LOG-ADDR-TYPE-TV`:
+
+      - ``CEC_LOG_ADDR_TYPE_TV``
+      - 0
+      - Use for a TV.
+    * .. _`CEC-LOG-ADDR-TYPE-RECORD`:
+
+      - ``CEC_LOG_ADDR_TYPE_RECORD``
+      - 1
+      - Use for a recording device.
+    * .. _`CEC-LOG-ADDR-TYPE-TUNER`:
+
+      - ``CEC_LOG_ADDR_TYPE_TUNER``
+      - 2
+      - Use for a tuner device.
+    * .. _`CEC-LOG-ADDR-TYPE-PLAYBACK`:
+
+      - ``CEC_LOG_ADDR_TYPE_PLAYBACK``
+      - 3
+      - Use for a playback device.
+    * .. _`CEC-LOG-ADDR-TYPE-AUDIOSYSTEM`:
+
+      - ``CEC_LOG_ADDR_TYPE_AUDIOSYSTEM``
+      - 4
+      - Use for an audio system device.
+    * .. _`CEC-LOG-ADDR-TYPE-SPECIFIC`:
+
+      - ``CEC_LOG_ADDR_TYPE_SPECIFIC``
+      - 5
+      - Use for a second TV or for a video processor device.
+    * .. _`CEC-LOG-ADDR-TYPE-UNREGISTERED`:
+
+      - ``CEC_LOG_ADDR_TYPE_UNREGISTERED``
+      - 6
+      - Use this if you just want to remain unregistered. Used for pure
+	CEC switches or CDC-only devices (CDC: Capability Discovery and
+	Control).
+
+
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. _cec-all-dev-types-flags:
+
+.. flat-table:: CEC All Device Types Flags
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * .. _`CEC-OP-ALL-DEVTYPE-TV`:
+
+      - ``CEC_OP_ALL_DEVTYPE_TV``
+      - 0x80
+      - This supports the TV type.
+    * .. _`CEC-OP-ALL-DEVTYPE-RECORD`:
+
+      - ``CEC_OP_ALL_DEVTYPE_RECORD``
+      - 0x40
+      - This supports the Recording type.
+    * .. _`CEC-OP-ALL-DEVTYPE-TUNER`:
+
+      - ``CEC_OP_ALL_DEVTYPE_TUNER``
+      - 0x20
+      - This supports the Tuner type.
+    * .. _`CEC-OP-ALL-DEVTYPE-PLAYBACK`:
+
+      - ``CEC_OP_ALL_DEVTYPE_PLAYBACK``
+      - 0x10
+      - This supports the Playback type.
+    * .. _`CEC-OP-ALL-DEVTYPE-AUDIOSYSTEM`:
+
+      - ``CEC_OP_ALL_DEVTYPE_AUDIOSYSTEM``
+      - 0x08
+      - This supports the Audio System type.
+    * .. _`CEC-OP-ALL-DEVTYPE-SWITCH`:
+
+      - ``CEC_OP_ALL_DEVTYPE_SWITCH``
+      - 0x04
+      - This supports the CEC Switch or Video Processing type.
+
+
+
+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.
+
+The :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>` can return the following
+error codes:
+
+ENOTTY
+    The ``CEC_CAP_LOG_ADDRS`` capability wasn't set, so this ioctl is not supported.
+
+EBUSY
+    The CEC adapter is currently configuring itself, or it is already configured and
+    ``num_log_addrs`` is non-zero, or another filehandle is in exclusive follower or
+    initiator mode, or the filehandle is in mode ``CEC_MODE_NO_INITIATOR``.
+
+EINVAL
+    The contents of struct :c:type:`cec_log_addrs` is invalid.
diff --git a/Documentation/userspace-api/media/cec/cec-ioc-adap-g-phys-addr.rst b/Documentation/userspace-api/media/cec/cec-ioc-adap-g-phys-addr.rst
new file mode 100644
index 000000000000..ce8f64c3e060
--- /dev/null
+++ b/Documentation/userspace-api/media/cec/cec-ioc-adap-g-phys-addr.rst
@@ -0,0 +1,100 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _CEC_ADAP_PHYS_ADDR:
+.. _CEC_ADAP_G_PHYS_ADDR:
+.. _CEC_ADAP_S_PHYS_ADDR:
+
+****************************************************
+ioctls CEC_ADAP_G_PHYS_ADDR and CEC_ADAP_S_PHYS_ADDR
+****************************************************
+
+Name
+====
+
+CEC_ADAP_G_PHYS_ADDR, CEC_ADAP_S_PHYS_ADDR - Get or set the physical address
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, CEC_ADAP_G_PHYS_ADDR, __u16 *argp )
+    :name: CEC_ADAP_G_PHYS_ADDR
+
+.. c:function:: int ioctl( int fd, CEC_ADAP_S_PHYS_ADDR, __u16 *argp )
+    :name: CEC_ADAP_S_PHYS_ADDR
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :c:func:`open() <cec-open>`.
+
+``argp``
+    Pointer to the CEC address.
+
+Description
+===========
+
+To query the current physical address applications call
+:ref:`ioctl CEC_ADAP_G_PHYS_ADDR <CEC_ADAP_G_PHYS_ADDR>` with a pointer to a __u16 where the
+driver stores the physical address.
+
+To set a new physical address applications store the physical address in
+a __u16 and call :ref:`ioctl CEC_ADAP_S_PHYS_ADDR <CEC_ADAP_S_PHYS_ADDR>` with a pointer to
+this integer. The :ref:`ioctl CEC_ADAP_S_PHYS_ADDR <CEC_ADAP_S_PHYS_ADDR>` is only available if
+``CEC_CAP_PHYS_ADDR`` is set (the ``ENOTTY`` error code will be returned
+otherwise). The :ref:`ioctl CEC_ADAP_S_PHYS_ADDR <CEC_ADAP_S_PHYS_ADDR>` can only be called
+by a file descriptor in initiator mode (see :ref:`CEC_S_MODE`), if not
+the ``EBUSY`` error code will be returned.
+
+To clear an existing physical address use ``CEC_PHYS_ADDR_INVALID``.
+The adapter will go to the unconfigured state.
+
+If logical address types have been defined (see :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`),
+then this ioctl will block until all
+requested logical addresses have been claimed. If the file descriptor is in non-blocking mode
+then it will not wait for the logical addresses to be claimed, instead it just returns 0.
+
+A :ref:`CEC_EVENT_STATE_CHANGE <CEC-EVENT-STATE-CHANGE>` event is sent when the physical address
+changes.
+
+The physical address is a 16-bit number where each group of 4 bits
+represent a digit of the physical address a.b.c.d where the most
+significant 4 bits represent 'a'. The CEC root device (usually the TV)
+has address 0.0.0.0. Every device that is hooked up to an input of the
+TV has address a.0.0.0 (where 'a' is ≥ 1), devices hooked up to those in
+turn have addresses a.b.0.0, etc. So a topology of up to 5 devices deep
+is supported. The physical address a device shall use is stored in the
+EDID of the sink.
+
+For example, the EDID for each HDMI input of the TV will have a
+different physical address of the form a.0.0.0 that the sources will
+read out and use as their physical address.
+
+
+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.
+
+The :ref:`ioctl CEC_ADAP_S_PHYS_ADDR <CEC_ADAP_S_PHYS_ADDR>` can return the following
+error codes:
+
+ENOTTY
+    The ``CEC_CAP_PHYS_ADDR`` capability wasn't set, so this ioctl is not supported.
+
+EBUSY
+    Another filehandle is in exclusive follower or initiator mode, or the filehandle
+    is in mode ``CEC_MODE_NO_INITIATOR``.
+
+EINVAL
+    The physical address is malformed.
diff --git a/Documentation/userspace-api/media/cec/cec-ioc-dqevent.rst b/Documentation/userspace-api/media/cec/cec-ioc-dqevent.rst
new file mode 100644
index 000000000000..4a535fb64b4b
--- /dev/null
+++ b/Documentation/userspace-api/media/cec/cec-ioc-dqevent.rst
@@ -0,0 +1,257 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _CEC_DQEVENT:
+
+*****************
+ioctl CEC_DQEVENT
+*****************
+
+Name
+====
+
+CEC_DQEVENT - Dequeue a CEC event
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, CEC_DQEVENT, struct cec_event *argp )
+    :name: CEC_DQEVENT
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :c:func:`open() <cec-open>`.
+
+``argp``
+
+
+Description
+===========
+
+CEC devices can send asynchronous events. These can be retrieved by
+calling :c:func:`CEC_DQEVENT`. If the file descriptor is in
+non-blocking mode and no event is pending, then it will return -1 and
+set errno to the ``EAGAIN`` error code.
+
+The internal event queues are per-filehandle and per-event type. If
+there is no more room in a queue then the last event is overwritten with
+the new one. This means that intermediate results can be thrown away but
+that the latest event is always available. This also means that is it
+possible to read two successive events that have the same value (e.g.
+two :ref:`CEC_EVENT_STATE_CHANGE <CEC-EVENT-STATE-CHANGE>` events with
+the same state). In that case the intermediate state changes were lost but
+it is guaranteed that the state did change in between the two events.
+
+.. tabularcolumns:: |p{1.2cm}|p{2.9cm}|p{13.4cm}|
+
+.. c:type:: cec_event_state_change
+
+.. flat-table:: struct cec_event_state_change
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 8
+
+    * - __u16
+      - ``phys_addr``
+      - The current physical address. This is ``CEC_PHYS_ADDR_INVALID`` if no
+        valid physical address is set.
+    * - __u16
+      - ``log_addr_mask``
+      - The current set of claimed logical addresses. This is 0 if no logical
+        addresses are claimed or if ``phys_addr`` is ``CEC_PHYS_ADDR_INVALID``.
+	If bit 15 is set (``1 << CEC_LOG_ADDR_UNREGISTERED``) then this device
+	has the unregistered logical address. In that case all other bits are 0.
+    * - __u16
+      - ``have_conn_info``
+      - If non-zero, then HDMI connector information is available.
+        This field is only valid if ``CEC_CAP_CONNECTOR_INFO`` is set. If that
+        capability is set and ``have_conn_info`` is zero, then that indicates
+        that the HDMI connector device is not instantiated, either because
+        the HDMI driver is still configuring the device or because the HDMI
+        device was unbound.
+
+
+.. c:type:: cec_event_lost_msgs
+
+.. tabularcolumns:: |p{1.0cm}|p{2.0cm}|p{14.5cm}|
+
+.. flat-table:: struct cec_event_lost_msgs
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 16
+
+    * - __u32
+      - ``lost_msgs``
+      - Set to the number of lost messages since the filehandle was opened
+	or since the last time this event was dequeued for this
+	filehandle. The messages lost are the oldest messages. So when a
+	new message arrives and there is no more room, then the oldest
+	message is discarded to make room for the new one. The internal
+	size of the message queue guarantees that all messages received in
+	the last two seconds will be stored. Since messages should be
+	replied to within a second according to the CEC specification,
+	this is more than enough.
+
+
+.. tabularcolumns:: |p{1.0cm}|p{4.4cm}|p{2.5cm}|p{9.6cm}|
+
+.. c:type:: cec_event
+
+.. flat-table:: struct cec_event
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 8
+
+    * - __u64
+      - ``ts``
+      - Timestamp of the event in ns.
+
+	The timestamp has been taken from the ``CLOCK_MONOTONIC`` clock.
+
+	To access the same clock from userspace use :c:func:`clock_gettime`.
+    * - __u32
+      - ``event``
+      - The CEC event type, see :ref:`cec-events`.
+    * - __u32
+      - ``flags``
+      - Event flags, see :ref:`cec-event-flags`.
+    * - union {
+      - (anonymous)
+    * - struct cec_event_state_change
+      - ``state_change``
+      - The new adapter state as sent by the :ref:`CEC_EVENT_STATE_CHANGE <CEC-EVENT-STATE-CHANGE>`
+	event.
+    * - struct cec_event_lost_msgs
+      - ``lost_msgs``
+      - The number of lost messages as sent by the :ref:`CEC_EVENT_LOST_MSGS <CEC-EVENT-LOST-MSGS>`
+	event.
+    * - }
+      -
+
+
+.. tabularcolumns:: |p{5.6cm}|p{0.9cm}|p{11.0cm}|
+
+.. _cec-events:
+
+.. flat-table:: CEC Events Types
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 16
+
+    * .. _`CEC-EVENT-STATE-CHANGE`:
+
+      - ``CEC_EVENT_STATE_CHANGE``
+      - 1
+      - Generated when the CEC Adapter's state changes. When open() is
+	called an initial event will be generated for that filehandle with
+	the CEC Adapter's state at that time.
+    * .. _`CEC-EVENT-LOST-MSGS`:
+
+      - ``CEC_EVENT_LOST_MSGS``
+      - 2
+      - Generated if one or more CEC messages were lost because the
+	application didn't dequeue CEC messages fast enough.
+    * .. _`CEC-EVENT-PIN-CEC-LOW`:
+
+      - ``CEC_EVENT_PIN_CEC_LOW``
+      - 3
+      - Generated if the CEC pin goes from a high voltage to a low voltage.
+        Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN``
+	capability set.
+    * .. _`CEC-EVENT-PIN-CEC-HIGH`:
+
+      - ``CEC_EVENT_PIN_CEC_HIGH``
+      - 4
+      - Generated if the CEC pin goes from a low voltage to a high voltage.
+        Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN``
+	capability set.
+    * .. _`CEC-EVENT-PIN-HPD-LOW`:
+
+      - ``CEC_EVENT_PIN_HPD_LOW``
+      - 5
+      - Generated if the HPD pin goes from a high voltage to a low voltage.
+	Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN``
+	capability set. When open() is called, the HPD pin can be read and
+	if the HPD is low, then an initial event will be generated for that
+	filehandle.
+    * .. _`CEC-EVENT-PIN-HPD-HIGH`:
+
+      - ``CEC_EVENT_PIN_HPD_HIGH``
+      - 6
+      - Generated if the HPD pin goes from a low voltage to a high voltage.
+	Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN``
+	capability set. When open() is called, the HPD pin can be read and
+	if the HPD is high, then an initial event will be generated for that
+	filehandle.
+    * .. _`CEC-EVENT-PIN-5V-LOW`:
+
+      - ``CEC_EVENT_PIN_5V_LOW``
+      - 6
+      - Generated if the 5V pin goes from a high voltage to a low voltage.
+	Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN``
+	capability set. When open() is called, the 5V pin can be read and
+	if the 5V is low, then an initial event will be generated for that
+	filehandle.
+    * .. _`CEC-EVENT-PIN-5V-HIGH`:
+
+      - ``CEC_EVENT_PIN_5V_HIGH``
+      - 7
+      - Generated if the 5V pin goes from a low voltage to a high voltage.
+	Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN``
+	capability set. When open() is called, the 5V pin can be read and
+	if the 5V is high, then an initial event will be generated for that
+	filehandle.
+
+
+.. tabularcolumns:: |p{6.0cm}|p{0.6cm}|p{10.9cm}|
+
+.. _cec-event-flags:
+
+.. flat-table:: CEC Event Flags
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 8
+
+    * .. _`CEC-EVENT-FL-INITIAL-STATE`:
+
+      - ``CEC_EVENT_FL_INITIAL_STATE``
+      - 1
+      - Set for the initial events that are generated when the device is
+	opened. See the table above for which events do this. This allows
+	applications to learn the initial state of the CEC adapter at
+	open() time.
+    * .. _`CEC-EVENT-FL-DROPPED-EVENTS`:
+
+      - ``CEC_EVENT_FL_DROPPED_EVENTS``
+      - 2
+      - Set if one or more events of the given event type have been dropped.
+        This is an indication that the application cannot keep up.
+
+
+
+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.
+
+The :ref:`ioctl CEC_DQEVENT <CEC_DQEVENT>` can return the following
+error codes:
+
+EAGAIN
+    This is returned when the filehandle is in non-blocking mode and there
+    are no pending events.
+
+ERESTARTSYS
+    An interrupt (e.g. Ctrl-C) arrived while in blocking mode waiting for
+    events to arrive.
diff --git a/Documentation/userspace-api/media/cec/cec-ioc-g-mode.rst b/Documentation/userspace-api/media/cec/cec-ioc-g-mode.rst
new file mode 100644
index 000000000000..2d3227e80b4f
--- /dev/null
+++ b/Documentation/userspace-api/media/cec/cec-ioc-g-mode.rst
@@ -0,0 +1,301 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _CEC_MODE:
+.. _CEC_G_MODE:
+.. _CEC_S_MODE:
+
+********************************
+ioctls CEC_G_MODE and CEC_S_MODE
+********************************
+
+CEC_G_MODE, CEC_S_MODE - Get or set exclusive use of the CEC adapter
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, CEC_G_MODE, __u32 *argp )
+   :name: CEC_G_MODE
+
+.. c:function:: int ioctl( int fd, CEC_S_MODE, __u32 *argp )
+   :name: CEC_S_MODE
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :c:func:`open() <cec-open>`.
+
+``argp``
+    Pointer to CEC mode.
+
+Description
+===========
+
+By default any filehandle can use :ref:`CEC_TRANSMIT`, but in order to prevent
+applications from stepping on each others toes it must be possible to
+obtain exclusive access to the CEC adapter. This ioctl sets the
+filehandle to initiator and/or follower mode which can be exclusive
+depending on the chosen mode. The initiator is the filehandle that is
+used to initiate messages, i.e. it commands other CEC devices. The
+follower is the filehandle that receives messages sent to the CEC
+adapter and processes them. The same filehandle can be both initiator
+and follower, or this role can be taken by two different filehandles.
+
+When a CEC message is received, then the CEC framework will decide how
+it will be processed. If the message is a reply to an earlier
+transmitted message, then the reply is sent back to the filehandle that
+is waiting for it. In addition the CEC framework will process it.
+
+If the message is not a reply, then the CEC framework will process it
+first. If there is no follower, then the message is just discarded and a
+feature abort is sent back to the initiator if the framework couldn't
+process it. If there is a follower, then the message is passed on to the
+follower who will use :ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>` to dequeue
+the new message. The framework expects the follower to make the right
+decisions.
+
+The CEC framework will process core messages unless requested otherwise
+by the follower. The follower can enable the passthrough mode. In that
+case, the CEC framework will pass on most core messages without
+processing them and the follower will have to implement those messages.
+There are some messages that the core will always process, regardless of
+the passthrough mode. See :ref:`cec-core-processing` for details.
+
+If there is no initiator, then any CEC filehandle can use
+:ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>`. If there is an exclusive
+initiator then only that initiator can call
+:ref:`CEC_TRANSMIT`. The follower can of course
+always call :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>`.
+
+Available initiator modes are:
+
+.. tabularcolumns:: |p{5.6cm}|p{0.9cm}|p{11.0cm}|
+
+.. _cec-mode-initiator_e:
+
+.. flat-table:: Initiator Modes
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 16
+
+    * .. _`CEC-MODE-NO-INITIATOR`:
+
+      - ``CEC_MODE_NO_INITIATOR``
+      - 0x0
+      - This is not an initiator, i.e. it cannot transmit CEC messages or
+	make any other changes to the CEC adapter.
+    * .. _`CEC-MODE-INITIATOR`:
+
+      - ``CEC_MODE_INITIATOR``
+      - 0x1
+      - This is an initiator (the default when the device is opened) and
+	it can transmit CEC messages and make changes to the CEC adapter,
+	unless there is an exclusive initiator.
+    * .. _`CEC-MODE-EXCL-INITIATOR`:
+
+      - ``CEC_MODE_EXCL_INITIATOR``
+      - 0x2
+      - This is an exclusive initiator and this file descriptor is the
+	only one that can transmit CEC messages and make changes to the
+	CEC adapter. If someone else is already the exclusive initiator
+	then an attempt to become one will return the ``EBUSY`` error code
+	error.
+
+
+Available follower modes are:
+
+.. tabularcolumns:: |p{6.6cm}|p{0.9cm}|p{10.0cm}|
+
+.. _cec-mode-follower_e:
+
+.. cssclass:: longtable
+
+.. flat-table:: Follower Modes
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 16
+
+    * .. _`CEC-MODE-NO-FOLLOWER`:
+
+      - ``CEC_MODE_NO_FOLLOWER``
+      - 0x00
+      - This is not a follower (the default when the device is opened).
+    * .. _`CEC-MODE-FOLLOWER`:
+
+      - ``CEC_MODE_FOLLOWER``
+      - 0x10
+      - This is a follower and it will receive CEC messages unless there
+	is an exclusive follower. You cannot become a follower if
+	:ref:`CEC_CAP_TRANSMIT <CEC-CAP-TRANSMIT>` is not set or if :ref:`CEC_MODE_NO_INITIATOR <CEC-MODE-NO-INITIATOR>`
+	was specified, the ``EINVAL`` error code is returned in that case.
+    * .. _`CEC-MODE-EXCL-FOLLOWER`:
+
+      - ``CEC_MODE_EXCL_FOLLOWER``
+      - 0x20
+      - This is an exclusive follower and only this file descriptor will
+	receive CEC messages for processing. If someone else is already
+	the exclusive follower then an attempt to become one will return
+	the ``EBUSY`` error code. You cannot become a follower if
+	:ref:`CEC_CAP_TRANSMIT <CEC-CAP-TRANSMIT>` is not set or if :ref:`CEC_MODE_NO_INITIATOR <CEC-MODE-NO-INITIATOR>`
+	was specified, the ``EINVAL`` error code is returned in that case.
+    * .. _`CEC-MODE-EXCL-FOLLOWER-PASSTHRU`:
+
+      - ``CEC_MODE_EXCL_FOLLOWER_PASSTHRU``
+      - 0x30
+      - This is an exclusive follower and only this file descriptor will
+	receive CEC messages for processing. In addition it will put the
+	CEC device into passthrough mode, allowing the exclusive follower
+	to handle most core messages instead of relying on the CEC
+	framework for that. If someone else is already the exclusive
+	follower then an attempt to become one will return the ``EBUSY`` error
+	code. You cannot become a follower if :ref:`CEC_CAP_TRANSMIT <CEC-CAP-TRANSMIT>`
+	is not set or if :ref:`CEC_MODE_NO_INITIATOR <CEC-MODE-NO-INITIATOR>` was specified,
+	the ``EINVAL`` error code is returned in that case.
+    * .. _`CEC-MODE-MONITOR-PIN`:
+
+      - ``CEC_MODE_MONITOR_PIN``
+      - 0xd0
+      - Put the file descriptor into pin monitoring mode. Can only be used in
+	combination with :ref:`CEC_MODE_NO_INITIATOR <CEC-MODE-NO-INITIATOR>`,
+	otherwise the ``EINVAL`` error code will be returned.
+	This mode requires that the :ref:`CEC_CAP_MONITOR_PIN <CEC-CAP-MONITOR-PIN>`
+	capability is set, otherwise the ``EINVAL`` error code is returned.
+	While in pin monitoring mode this file descriptor can receive the
+	``CEC_EVENT_PIN_CEC_LOW`` and ``CEC_EVENT_PIN_CEC_HIGH`` events to see the
+	low-level CEC pin transitions. This is very useful for debugging.
+	This mode is only allowed if the process has the ``CAP_NET_ADMIN``
+	capability. If that is not set, then the ``EPERM`` error code is returned.
+    * .. _`CEC-MODE-MONITOR`:
+
+      - ``CEC_MODE_MONITOR``
+      - 0xe0
+      - Put the file descriptor into monitor mode. Can only be used in
+	combination with :ref:`CEC_MODE_NO_INITIATOR <CEC-MODE-NO-INITIATOR>`,
+	otherwise the ``EINVAL`` error code will be returned.
+	In monitor mode all messages this CEC
+	device transmits and all messages it receives (both broadcast
+	messages and directed messages for one its logical addresses) will
+	be reported. This is very useful for debugging. This is only
+	allowed if the process has the ``CAP_NET_ADMIN`` capability. If
+	that is not set, then the ``EPERM`` error code is returned.
+    * .. _`CEC-MODE-MONITOR-ALL`:
+
+      - ``CEC_MODE_MONITOR_ALL``
+      - 0xf0
+      - Put the file descriptor into 'monitor all' mode. Can only be used
+	in combination with :ref:`CEC_MODE_NO_INITIATOR <CEC-MODE-NO-INITIATOR>`, otherwise
+	the ``EINVAL`` error code will be returned. In 'monitor all' mode all messages
+	this CEC device transmits and all messages it receives, including
+	directed messages for other CEC devices will be reported. This is
+	very useful for debugging, but not all devices support this. This
+	mode requires that the :ref:`CEC_CAP_MONITOR_ALL <CEC-CAP-MONITOR-ALL>` capability is set,
+	otherwise the ``EINVAL`` error code is returned. This is only allowed if
+	the process has the ``CAP_NET_ADMIN`` capability. If that is not
+	set, then the ``EPERM`` error code is returned.
+
+
+Core message processing details:
+
+.. tabularcolumns:: |p{6.6cm}|p{10.9cm}|
+
+.. _cec-core-processing:
+
+.. flat-table:: Core Message Processing
+    :header-rows:  0
+    :stub-columns: 0
+    :widths: 1 8
+
+    * .. _`CEC-MSG-GET-CEC-VERSION`:
+
+      - ``CEC_MSG_GET_CEC_VERSION``
+      - The core will return the CEC version that was set with
+	:ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`,
+	except when in passthrough mode. In passthrough mode the core
+	does nothing and this message has to be handled by a follower
+	instead.
+    * .. _`CEC-MSG-GIVE-DEVICE-VENDOR-ID`:
+
+      - ``CEC_MSG_GIVE_DEVICE_VENDOR_ID``
+      - The core will return the vendor ID that was set with
+	:ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`,
+	except when in passthrough mode. In passthrough mode the core
+	does nothing and this message has to be handled by a follower
+	instead.
+    * .. _`CEC-MSG-ABORT`:
+
+      - ``CEC_MSG_ABORT``
+      - The core will return a Feature Abort message with reason
+        'Feature Refused' as per the specification, except when in
+	passthrough mode. In passthrough mode the core does nothing
+	and this message has to be handled by a follower instead.
+    * .. _`CEC-MSG-GIVE-PHYSICAL-ADDR`:
+
+      - ``CEC_MSG_GIVE_PHYSICAL_ADDR``
+      - The core will report the current physical address, except when
+        in passthrough mode. In passthrough mode the core does nothing
+	and this message has to be handled by a follower instead.
+    * .. _`CEC-MSG-GIVE-OSD-NAME`:
+
+      - ``CEC_MSG_GIVE_OSD_NAME``
+      - The core will report the current OSD name that was set with
+	:ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`,
+	except when in passthrough mode. In passthrough mode the core
+	does nothing and this message has to be handled by a follower
+	instead.
+    * .. _`CEC-MSG-GIVE-FEATURES`:
+
+      - ``CEC_MSG_GIVE_FEATURES``
+      - The core will do nothing if the CEC version is older than 2.0,
+        otherwise it will report the current features that were set with
+	:ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`,
+	except when in passthrough mode. In passthrough mode the core
+	does nothing (for any CEC version) and this message has to be handled
+	by a follower instead.
+    * .. _`CEC-MSG-USER-CONTROL-PRESSED`:
+
+      - ``CEC_MSG_USER_CONTROL_PRESSED``
+      - If :ref:`CEC_CAP_RC <CEC-CAP-RC>` is set and if
+        :ref:`CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU <CEC-LOG-ADDRS-FL-ALLOW-RC-PASSTHRU>`
+	is set, then generate a remote control key
+	press. This message is always passed on to the follower(s).
+    * .. _`CEC-MSG-USER-CONTROL-RELEASED`:
+
+      - ``CEC_MSG_USER_CONTROL_RELEASED``
+      - If :ref:`CEC_CAP_RC <CEC-CAP-RC>` is set and if
+        :ref:`CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU <CEC-LOG-ADDRS-FL-ALLOW-RC-PASSTHRU>`
+        is set, then generate a remote control key
+	release. This message is always passed on to the follower(s).
+    * .. _`CEC-MSG-REPORT-PHYSICAL-ADDR`:
+
+      - ``CEC_MSG_REPORT_PHYSICAL_ADDR``
+      - The CEC framework will make note of the reported physical address
+	and then just pass the message on to the follower(s).
+
+
+
+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.
+
+The :ref:`ioctl CEC_S_MODE <CEC_S_MODE>` can return the following
+error codes:
+
+EINVAL
+    The requested mode is invalid.
+
+EPERM
+    Monitor mode is requested, but the process does have the ``CAP_NET_ADMIN``
+    capability.
+
+EBUSY
+    Someone else is already an exclusive follower or initiator.
diff --git a/Documentation/userspace-api/media/cec/cec-ioc-receive.rst b/Documentation/userspace-api/media/cec/cec-ioc-receive.rst
new file mode 100644
index 000000000000..e456b2bc92a1
--- /dev/null
+++ b/Documentation/userspace-api/media/cec/cec-ioc-receive.rst
@@ -0,0 +1,391 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _CEC_TRANSMIT:
+.. _CEC_RECEIVE:
+
+***********************************
+ioctls CEC_RECEIVE and CEC_TRANSMIT
+***********************************
+
+Name
+====
+
+CEC_RECEIVE, CEC_TRANSMIT - Receive or transmit a CEC message
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, CEC_RECEIVE, struct cec_msg \*argp )
+    :name: CEC_RECEIVE
+
+.. c:function:: int ioctl( int fd, CEC_TRANSMIT, struct cec_msg \*argp )
+    :name: CEC_TRANSMIT
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :c:func:`open() <cec-open>`.
+
+``argp``
+    Pointer to struct cec_msg.
+
+Description
+===========
+
+To receive a CEC message the application has to fill in the
+``timeout`` field of struct :c:type:`cec_msg` and pass it to
+:ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>`.
+If the file descriptor is in non-blocking mode and there are no received
+messages pending, then it will return -1 and set errno to the ``EAGAIN``
+error code. If the file descriptor is in blocking mode and ``timeout``
+is non-zero and no message arrived within ``timeout`` milliseconds, then
+it will return -1 and set errno to the ``ETIMEDOUT`` error code.
+
+A received message can be:
+
+1. a message received from another CEC device (the ``sequence`` field will
+   be 0).
+2. the result of an earlier non-blocking transmit (the ``sequence`` field will
+   be non-zero).
+
+To send a CEC message the application has to fill in the struct
+:c:type:`cec_msg` and pass it to :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>`.
+The :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` is only available if
+``CEC_CAP_TRANSMIT`` is set. If there is no more room in the transmit
+queue, then it will return -1 and set errno to the ``EBUSY`` error code.
+The transmit queue has enough room for 18 messages (about 1 second worth
+of 2-byte messages). Note that the CEC kernel framework will also reply
+to core messages (see :ref:`cec-core-processing`), so it is not a good
+idea to fully fill up the transmit queue.
+
+If the file descriptor is in non-blocking mode then the transmit will
+return 0 and the result of the transmit will be available via
+:ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>` once the transmit has finished
+(including waiting for a reply, if requested).
+
+The ``sequence`` field is filled in for every transmit and this can be
+checked against the received messages to find the corresponding transmit
+result.
+
+Normally calling :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` when the physical
+address is invalid (due to e.g. a disconnect) will return ``ENONET``.
+
+However, the CEC specification allows sending messages from 'Unregistered' to
+'TV' when the physical address is invalid since some TVs pull the hotplug detect
+pin of the HDMI connector low when they go into standby, or when switching to
+another input.
+
+When the hotplug detect pin goes low the EDID disappears, and thus the
+physical address, but the cable is still connected and CEC still works.
+In order to detect/wake up the device it is allowed to send poll and 'Image/Text
+View On' messages from initiator 0xf ('Unregistered') to destination 0 ('TV').
+
+.. tabularcolumns:: |p{1.0cm}|p{3.5cm}|p{13.0cm}|
+
+.. c:type:: cec_msg
+
+.. cssclass:: longtable
+
+.. flat-table:: struct cec_msg
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 16
+
+    * - __u64
+      - ``tx_ts``
+      - Timestamp in ns of when the last byte of the message was transmitted.
+	The timestamp has been taken from the ``CLOCK_MONOTONIC`` clock. To access
+	the same clock from userspace use :c:func:`clock_gettime`.
+    * - __u64
+      - ``rx_ts``
+      - Timestamp in ns of when the last byte of the message was received.
+	The timestamp has been taken from the ``CLOCK_MONOTONIC`` clock. To access
+	the same clock from userspace use :c:func:`clock_gettime`.
+    * - __u32
+      - ``len``
+      - The length of the message. For :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` this is filled in
+	by the application. The driver will fill this in for
+	:ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>`. For :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` it will be
+	filled in by the driver with the length of the reply message if ``reply`` was set.
+    * - __u32
+      - ``timeout``
+      - The timeout in milliseconds. This is the time the device will wait
+	for a message to be received before timing out. If it is set to 0,
+	then it will wait indefinitely when it is called by :ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>`.
+	If it is 0 and it is called by :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>`,
+	then it will be replaced by 1000 if the ``reply`` is non-zero or
+	ignored if ``reply`` is 0.
+    * - __u32
+      - ``sequence``
+      - A non-zero sequence number is automatically assigned by the CEC framework
+	for all transmitted messages. It is used by the CEC framework when it queues
+	the transmit result (when transmit was called in non-blocking mode). This
+	allows the application to associate the received message with the original
+	transmit.
+    * - __u32
+      - ``flags``
+      - Flags. See :ref:`cec-msg-flags` for a list of available flags.
+    * - __u8
+      - ``tx_status``
+      - The status bits of the transmitted message. See
+	:ref:`cec-tx-status` for the possible status values. It is 0 if
+	this message was received, not transmitted.
+    * - __u8
+      - ``msg[16]``
+      - The message payload. For :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` this is filled in by the
+	application. The driver will fill this in for :ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>`.
+	For :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` it will be filled in by the driver with
+	the payload of the reply message if ``timeout`` was set.
+    * - __u8
+      - ``reply``
+      - Wait until this message is replied. If ``reply`` is 0 and the
+	``timeout`` is 0, then don't wait for a reply but return after
+	transmitting the message. Ignored by :ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>`.
+	The case where ``reply`` is 0 (this is the opcode for the Feature Abort
+	message) and ``timeout`` is non-zero is specifically allowed to make it
+	possible to send a message and wait up to ``timeout`` milliseconds for a
+	Feature Abort reply. In this case ``rx_status`` will either be set
+	to :ref:`CEC_RX_STATUS_TIMEOUT <CEC-RX-STATUS-TIMEOUT>` or
+	:ref:`CEC_RX_STATUS_FEATURE_ABORT <CEC-RX-STATUS-FEATURE-ABORT>`.
+
+	If the transmitter message is ``CEC_MSG_INITIATE_ARC`` then the ``reply``
+	values ``CEC_MSG_REPORT_ARC_INITIATED`` and ``CEC_MSG_REPORT_ARC_TERMINATED``
+	are processed differently: either value will match both possible replies.
+	The reason is that the ``CEC_MSG_INITIATE_ARC`` message is the only CEC
+	message that has two possible replies other than Feature Abort. The
+	``reply`` field will be updated with the actual reply so that it is
+	synchronized with the contents of the received message.
+    * - __u8
+      - ``rx_status``
+      - The status bits of the received message. See
+	:ref:`cec-rx-status` for the possible status values. It is 0 if
+	this message was transmitted, not received, unless this is the
+	reply to a transmitted message. In that case both ``rx_status``
+	and ``tx_status`` are set.
+    * - __u8
+      - ``tx_status``
+      - The status bits of the transmitted message. See
+	:ref:`cec-tx-status` for the possible status values. It is 0 if
+	this message was received, not transmitted.
+    * - __u8
+      - ``tx_arb_lost_cnt``
+      - A counter of the number of transmit attempts that resulted in the
+	Arbitration Lost error. This is only set if the hardware supports
+	this, otherwise it is always 0. This counter is only valid if the
+	:ref:`CEC_TX_STATUS_ARB_LOST <CEC-TX-STATUS-ARB-LOST>` status bit is set.
+    * - __u8
+      - ``tx_nack_cnt``
+      - A counter of the number of transmit attempts that resulted in the
+	Not Acknowledged error. This is only set if the hardware supports
+	this, otherwise it is always 0. This counter is only valid if the
+	:ref:`CEC_TX_STATUS_NACK <CEC-TX-STATUS-NACK>` status bit is set.
+    * - __u8
+      - ``tx_low_drive_cnt``
+      - A counter of the number of transmit attempts that resulted in the
+	Arbitration Lost error. This is only set if the hardware supports
+	this, otherwise it is always 0. This counter is only valid if the
+	:ref:`CEC_TX_STATUS_LOW_DRIVE <CEC-TX-STATUS-LOW-DRIVE>` status bit is set.
+    * - __u8
+      - ``tx_error_cnt``
+      - A counter of the number of transmit errors other than Arbitration
+	Lost or Not Acknowledged. This is only set if the hardware
+	supports this, otherwise it is always 0. This counter is only
+	valid if the :ref:`CEC_TX_STATUS_ERROR <CEC-TX-STATUS-ERROR>` status bit is set.
+
+
+.. tabularcolumns:: |p{6.2cm}|p{1.0cm}|p{10.3cm}|
+
+.. _cec-msg-flags:
+
+.. flat-table:: Flags for struct cec_msg
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * .. _`CEC-MSG-FL-REPLY-TO-FOLLOWERS`:
+
+      - ``CEC_MSG_FL_REPLY_TO_FOLLOWERS``
+      - 1
+      - If a CEC transmit expects a reply, then by default that reply is only sent to
+	the filehandle that called :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>`. If this
+	flag is set, then the reply is also sent to all followers, if any. If the
+	filehandle that called :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` is also a
+	follower, then that filehandle will receive the reply twice: once as the
+	result of the :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>`, and once via
+	:ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>`.
+
+    * .. _`CEC-MSG-FL-RAW`:
+
+      - ``CEC_MSG_FL_RAW``
+      - 2
+      - Normally CEC messages are validated before transmitting them. If this
+        flag is set when :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` is called,
+	then no validation takes place and the message is transmitted as-is.
+	This is useful when debugging CEC issues.
+	This flag is only allowed if the process has the ``CAP_SYS_RAWIO``
+	capability. If that is not set, then the ``EPERM`` error code is
+	returned.
+
+
+.. tabularcolumns:: |p{5.6cm}|p{0.9cm}|p{11.0cm}|
+
+.. _cec-tx-status:
+
+.. flat-table:: CEC Transmit Status
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 16
+
+    * .. _`CEC-TX-STATUS-OK`:
+
+      - ``CEC_TX_STATUS_OK``
+      - 0x01
+      - The message was transmitted successfully. This is mutually
+	exclusive with :ref:`CEC_TX_STATUS_MAX_RETRIES <CEC-TX-STATUS-MAX-RETRIES>`.
+	Other bits can still be set if earlier attempts met with failure before
+	the transmit was eventually successful.
+    * .. _`CEC-TX-STATUS-ARB-LOST`:
+
+      - ``CEC_TX_STATUS_ARB_LOST``
+      - 0x02
+      - CEC line arbitration was lost, i.e. another transmit started at the
+        same time with a higher priority. Optional status, not all hardware
+	can detect this error condition.
+    * .. _`CEC-TX-STATUS-NACK`:
+
+      - ``CEC_TX_STATUS_NACK``
+      - 0x04
+      - Message was not acknowledged. Note that some hardware cannot tell apart
+        a 'Not Acknowledged' status from other error conditions, i.e. the result
+	of a transmit is just OK or FAIL. In that case this status will be
+	returned when the transmit failed.
+    * .. _`CEC-TX-STATUS-LOW-DRIVE`:
+
+      - ``CEC_TX_STATUS_LOW_DRIVE``
+      - 0x08
+      - Low drive was detected on the CEC bus. This indicates that a
+	follower detected an error on the bus and requests a
+	retransmission. Optional status, not all hardware can detect this
+	error condition.
+    * .. _`CEC-TX-STATUS-ERROR`:
+
+      - ``CEC_TX_STATUS_ERROR``
+      - 0x10
+      - Some error occurred. This is used for any errors that do not fit
+	``CEC_TX_STATUS_ARB_LOST`` or ``CEC_TX_STATUS_LOW_DRIVE``, either because
+	the hardware could not tell which error occurred, or because the hardware
+	tested for other conditions besides those two. Optional status.
+    * .. _`CEC-TX-STATUS-MAX-RETRIES`:
+
+      - ``CEC_TX_STATUS_MAX_RETRIES``
+      - 0x20
+      - The transmit failed after one or more retries. This status bit is
+	mutually exclusive with :ref:`CEC_TX_STATUS_OK <CEC-TX-STATUS-OK>`.
+	Other bits can still be set to explain which failures were seen.
+    * .. _`CEC-TX-STATUS-ABORTED`:
+
+      - ``CEC_TX_STATUS_ABORTED``
+      - 0x40
+      - The transmit was aborted due to an HDMI disconnect, or the adapter
+        was unconfigured, or a transmit was interrupted, or the driver
+	returned an error when attempting to start a transmit.
+    * .. _`CEC-TX-STATUS-TIMEOUT`:
+
+      - ``CEC_TX_STATUS_TIMEOUT``
+      - 0x80
+      - The transmit timed out. This should not normally happen and this
+	indicates a driver problem.
+
+
+.. tabularcolumns:: |p{5.6cm}|p{0.9cm}|p{11.0cm}|
+
+.. _cec-rx-status:
+
+.. flat-table:: CEC Receive Status
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 16
+
+    * .. _`CEC-RX-STATUS-OK`:
+
+      - ``CEC_RX_STATUS_OK``
+      - 0x01
+      - The message was received successfully.
+    * .. _`CEC-RX-STATUS-TIMEOUT`:
+
+      - ``CEC_RX_STATUS_TIMEOUT``
+      - 0x02
+      - The reply to an earlier transmitted message timed out.
+    * .. _`CEC-RX-STATUS-FEATURE-ABORT`:
+
+      - ``CEC_RX_STATUS_FEATURE_ABORT``
+      - 0x04
+      - The message was received successfully but the reply was
+	``CEC_MSG_FEATURE_ABORT``. This status is only set if this message
+	was the reply to an earlier transmitted message.
+    * .. _`CEC-RX-STATUS-ABORTED`:
+
+      - ``CEC_RX_STATUS_ABORTED``
+      - 0x08
+      - The wait for a reply to an earlier transmitted message was aborted
+        because the HDMI cable was disconnected, the adapter was unconfigured
+	or the :ref:`CEC_TRANSMIT <CEC_RECEIVE>` that waited for a
+	reply was interrupted.
+
+
+
+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.
+
+The :ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>` can return the following
+error codes:
+
+EAGAIN
+    No messages are in the receive queue, and the filehandle is in non-blocking mode.
+
+ETIMEDOUT
+    The ``timeout`` was reached while waiting for a message.
+
+ERESTARTSYS
+    The wait for a message was interrupted (e.g. by Ctrl-C).
+
+The :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` can return the following
+error codes:
+
+ENOTTY
+    The ``CEC_CAP_TRANSMIT`` capability wasn't set, so this ioctl is not supported.
+
+EPERM
+    The CEC adapter is not configured, i.e. :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`
+    has never been called, or ``CEC_MSG_FL_RAW`` was used from a process that
+    did not have the ``CAP_SYS_RAWIO`` capability.
+
+ENONET
+    The CEC adapter is not configured, i.e. :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`
+    was called, but the physical address is invalid so no logical address was claimed.
+    An exception is made in this case for transmits from initiator 0xf ('Unregistered')
+    to destination 0 ('TV'). In that case the transmit will proceed as usual.
+
+EBUSY
+    Another filehandle is in exclusive follower or initiator mode, or the filehandle
+    is in mode ``CEC_MODE_NO_INITIATOR``. This is also returned if the transmit
+    queue is full.
+
+EINVAL
+    The contents of struct :c:type:`cec_msg` is invalid.
+
+ERESTARTSYS
+    The wait for a successful transmit was interrupted (e.g. by Ctrl-C).
diff --git a/Documentation/userspace-api/media/cec/cec-pin-error-inj.rst b/Documentation/userspace-api/media/cec/cec-pin-error-inj.rst
new file mode 100644
index 000000000000..78632199324d
--- /dev/null
+++ b/Documentation/userspace-api/media/cec/cec-pin-error-inj.rst
@@ -0,0 +1,334 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+CEC Pin Framework Error Injection
+=================================
+
+The CEC Pin Framework is a core CEC framework for CEC hardware that only
+has low-level support for the CEC bus. Most hardware today will have
+high-level CEC support where the hardware deals with driving the CEC bus,
+but some older devices aren't that fancy. However, this framework also
+allows you to connect the CEC pin to a GPIO on e.g. a Raspberry Pi and
+you have now made a CEC adapter.
+
+What makes doing this so interesting is that since we have full control
+over the bus it is easy to support error injection. This is ideal to
+test how well CEC adapters can handle error conditions.
+
+Currently only the cec-gpio driver (when the CEC line is directly
+connected to a pull-up GPIO line) and the AllWinner A10/A20 drm driver
+support this framework.
+
+If ``CONFIG_CEC_PIN_ERROR_INJ`` is enabled, then error injection is available
+through debugfs. Specifically, in ``/sys/kernel/debug/cec/cecX/`` there is
+now an ``error-inj`` file.
+
+.. note::
+
+    The error injection commands are not a stable ABI and may change in the
+    future.
+
+With ``cat error-inj`` you can see both the possible commands and the current
+error injection status::
+
+	$ cat /sys/kernel/debug/cec/cec0/error-inj
+	# Clear error injections:
+	#   clear          clear all rx and tx error injections
+	#   rx-clear       clear all rx error injections
+	#   tx-clear       clear all tx error injections
+	#   <op> clear     clear all rx and tx error injections for <op>
+	#   <op> rx-clear  clear all rx error injections for <op>
+	#   <op> tx-clear  clear all tx error injections for <op>
+	#
+	# RX error injection:
+	#   <op>[,<mode>] rx-nack              NACK the message instead of sending an ACK
+	#   <op>[,<mode>] rx-low-drive <bit>   force a low-drive condition at this bit position
+	#   <op>[,<mode>] rx-add-byte          add a spurious byte to the received CEC message
+	#   <op>[,<mode>] rx-remove-byte       remove the last byte from the received CEC message
+	#   <op>[,<mode>] rx-arb-lost <poll>   generate a POLL message to trigger an arbitration lost
+	#
+	# TX error injection settings:
+	#   tx-ignore-nack-until-eom           ignore early NACKs until EOM
+	#   tx-custom-low-usecs <usecs>        define the 'low' time for the custom pulse
+	#   tx-custom-high-usecs <usecs>       define the 'high' time for the custom pulse
+	#   tx-custom-pulse                    transmit the custom pulse once the bus is idle
+	#
+	# TX error injection:
+	#   <op>[,<mode>] tx-no-eom            don't set the EOM bit
+	#   <op>[,<mode>] tx-early-eom         set the EOM bit one byte too soon
+	#   <op>[,<mode>] tx-add-bytes <num>   append <num> (1-255) spurious bytes to the message
+	#   <op>[,<mode>] tx-remove-byte       drop the last byte from the message
+	#   <op>[,<mode>] tx-short-bit <bit>   make this bit shorter than allowed
+	#   <op>[,<mode>] tx-long-bit <bit>    make this bit longer than allowed
+	#   <op>[,<mode>] tx-custom-bit <bit>  send the custom pulse instead of this bit
+	#   <op>[,<mode>] tx-short-start       send a start pulse that's too short
+	#   <op>[,<mode>] tx-long-start        send a start pulse that's too long
+	#   <op>[,<mode>] tx-custom-start      send the custom pulse instead of the start pulse
+	#   <op>[,<mode>] tx-last-bit <bit>    stop sending after this bit
+	#   <op>[,<mode>] tx-low-drive <bit>   force a low-drive condition at this bit position
+	#
+	# <op>       CEC message opcode (0-255) or 'any'
+	# <mode>     'once' (default), 'always', 'toggle' or 'off'
+	# <bit>      CEC message bit (0-159)
+	#            10 bits per 'byte': bits 0-7: data, bit 8: EOM, bit 9: ACK
+	# <poll>     CEC poll message used to test arbitration lost (0x00-0xff, default 0x0f)
+	# <usecs>    microseconds (0-10000000, default 1000)
+
+	clear
+
+You can write error injection commands to ``error-inj`` using
+``echo 'cmd' >error-inj`` or ``cat cmd.txt >error-inj``. The ``cat error-inj``
+output contains the current error commands. You can save the output to a file
+and use it as an input to ``error-inj`` later.
+
+Basic Syntax
+------------
+
+Leading spaces/tabs are ignored. If the next character is a ``#`` or the end
+of the line was reached, then the whole line is ignored. Otherwise a command
+is expected.
+
+The error injection commands fall in two main groups: those relating to
+receiving CEC messages and those relating to transmitting CEC messages. In
+addition, there are commands to clear existing error injection commands and
+to create custom pulses on the CEC bus.
+
+Most error injection commands can be executed for specific CEC opcodes or for
+all opcodes (``any``). Each command also has a 'mode' which can be ``off``
+(can be used to turn off an existing error injection command), ``once``
+(the default) which will trigger the error injection only once for the next
+received or transmitted message, ``always`` to always trigger the error
+injection and ``toggle`` to toggle the error injection on or off for every
+transmit or receive.
+
+So '``any rx-nack``' will NACK the next received CEC message,
+'``any,always rx-nack``' will NACK all received CEC messages and
+'``0x82,toggle rx-nack``' will only NACK if an Active Source message was
+received and do that only for every other received message.
+
+After an error was injected with mode ``once`` the error injection command
+is cleared automatically, so ``once`` is a one-time deal.
+
+All combinations of ``<op>`` and error injection commands can co-exist. So
+this is fine::
+
+	0x9e tx-add-bytes 1
+	0x9e tx-early-eom
+	0x9f tx-add-bytes 2
+	any rx-nack
+
+All four error injection commands will be active simultaneously.
+
+However, if the same ``<op>`` and command combination is specified,
+but with different arguments::
+
+	0x9e tx-add-bytes 1
+	0x9e tx-add-bytes 2
+
+Then the second will overwrite the first.
+
+Clear Error Injections
+----------------------
+
+``clear``
+    Clear all error injections.
+
+``rx-clear``
+    Clear all receive error injections
+
+``tx-clear``
+    Clear all transmit error injections
+
+``<op> clear``
+    Clear all error injections for the given opcode.
+
+``<op> rx-clear``
+    Clear all receive error injections for the given opcode.
+
+``<op> tx-clear``
+    Clear all transmit error injections for the given opcode.
+
+Receive Messages
+----------------
+
+``<op>[,<mode>] rx-nack``
+    NACK broadcast messages and messages directed to this CEC adapter.
+    Every byte of the message will be NACKed in case the transmitter
+    keeps transmitting after the first byte was NACKed.
+
+``<op>[,<mode>] rx-low-drive <bit>``
+    Force a Low Drive condition at this bit position. If <op> specifies
+    a specific CEC opcode then the bit position must be at least 18,
+    otherwise the opcode hasn't been received yet. This tests if the
+    transmitter can handle the Low Drive condition correctly and reports
+    the error correctly. Note that a Low Drive in the first 4 bits can also
+    be interpreted as an Arbitration Lost condition by the transmitter.
+    This is implementation dependent.
+
+``<op>[,<mode>] rx-add-byte``
+    Add a spurious 0x55 byte to the received CEC message, provided
+    the message was 15 bytes long or less. This is useful to test
+    the high-level protocol since spurious bytes should be ignored.
+
+``<op>[,<mode>] rx-remove-byte``
+    Remove the last byte from the received CEC message, provided it
+    was at least 2 bytes long. This is useful to test the high-level
+    protocol since messages that are too short should be ignored.
+
+``<op>[,<mode>] rx-arb-lost <poll>``
+    Generate a POLL message to trigger an Arbitration Lost condition.
+    This command is only allowed for ``<op>`` values of ``next`` or ``all``.
+    As soon as a start bit has been received the CEC adapter will switch
+    to transmit mode and it will transmit a POLL message. By default this is
+    0x0f, but it can also be specified explicitly via the ``<poll>`` argument.
+
+    This command can be used to test the Arbitration Lost condition in
+    the remote CEC transmitter. Arbitration happens when two CEC adapters
+    start sending a message at the same time. In that case the initiator
+    with the most leading zeroes wins and the other transmitter has to
+    stop transmitting ('Arbitration Lost'). This is very hard to test,
+    except by using this error injection command.
+
+    This does not work if the remote CEC transmitter has logical address
+    0 ('TV') since that will always win.
+
+Transmit Messages
+-----------------
+
+``tx-ignore-nack-until-eom``
+    This setting changes the behavior of transmitting CEC messages. Normally
+    as soon as the receiver NACKs a byte the transmit will stop, but the
+    specification also allows that the full message is transmitted and only
+    at the end will the transmitter look at the ACK bit. This is not
+    recommended behavior since there is no point in keeping the CEC bus busy
+    for longer than is strictly needed. Especially given how slow the bus is.
+
+    This setting can be used to test how well a receiver deals with
+    transmitters that ignore NACKs until the very end of the message.
+
+``<op>[,<mode>] tx-no-eom``
+    Don't set the EOM bit. Normally the last byte of the message has the EOM
+    (End-Of-Message) bit set. With this command the transmit will just stop
+    without ever sending an EOM. This can be used to test how a receiver
+    handles this case. Normally receivers have a time-out after which
+    they will go back to the Idle state.
+
+``<op>[,<mode>] tx-early-eom``
+    Set the EOM bit one byte too soon. This obviously only works for messages
+    of two bytes or more. The EOM bit will be set for the second-to-last byte
+    and not for the final byte. The receiver should ignore the last byte in
+    this case. Since the resulting message is likely to be too short for this
+    same reason the whole message is typically ignored. The receiver should be
+    in Idle state after the last byte was transmitted.
+
+``<op>[,<mode>] tx-add-bytes <num>``
+    Append ``<num>`` (1-255) spurious bytes to the message. The extra bytes
+    have the value of the byte position in the message. So if you transmit a
+    two byte message (e.g. a Get CEC Version message) and add 2 bytes, then
+    the full message received by the remote CEC adapter is
+    ``0x40 0x9f 0x02 0x03``.
+
+    This command can be used to test buffer overflows in the receiver. E.g.
+    what does it do when it receives more than the maximum message size of 16
+    bytes.
+
+``<op>[,<mode>] tx-remove-byte``
+    Drop the last byte from the message, provided the message is at least
+    two bytes long. The receiver should ignore messages that are too short.
+
+``<op>[,<mode>] tx-short-bit <bit>``
+    Make this bit period shorter than allowed. The bit position cannot be
+    an Ack bit.  If <op> specifies a specific CEC opcode then the bit position
+    must be at least 18, otherwise the opcode hasn't been received yet.
+    Normally the period of a data bit is between 2.05 and 2.75 milliseconds.
+    With this command the period of this bit is 1.8 milliseconds, this is
+    done by reducing the time the CEC bus is high. This bit period is less
+    than is allowed and the receiver should respond with a Low Drive
+    condition.
+
+    This command is ignored for 0 bits in bit positions 0 to 3. This is
+    because the receiver also looks for an Arbitration Lost condition in
+    those first four bits and it is undefined what will happen if it
+    sees a too-short 0 bit.
+
+``<op>[,<mode>] tx-long-bit <bit>``
+    Make this bit period longer than is valid. The bit position cannot be
+    an Ack bit.  If <op> specifies a specific CEC opcode then the bit position
+    must be at least 18, otherwise the opcode hasn't been received yet.
+    Normally the period of a data bit is between 2.05 and 2.75 milliseconds.
+    With this command the period of this bit is 2.9 milliseconds, this is
+    done by increasing the time the CEC bus is high.
+
+    Even though this bit period is longer than is valid it is undefined what
+    a receiver will do. It might just accept it, or it might time out and
+    return to Idle state. Unfortunately the CEC specification is silent about
+    this.
+
+    This command is ignored for 0 bits in bit positions 0 to 3. This is
+    because the receiver also looks for an Arbitration Lost condition in
+    those first four bits and it is undefined what will happen if it
+    sees a too-long 0 bit.
+
+``<op>[,<mode>] tx-short-start``
+    Make this start bit period shorter than allowed. Normally the period of
+    a start bit is between 4.3 and 4.7 milliseconds. With this command the
+    period of the start bit is 4.1 milliseconds, this is done by reducing
+    the time the CEC bus is high. This start bit period is less than is
+    allowed and the receiver should return to Idle state when this is detected.
+
+``<op>[,<mode>] tx-long-start``
+    Make this start bit period longer than is valid. Normally the period of
+    a start bit is between 4.3 and 4.7 milliseconds. With this command the
+    period of the start bit is 5 milliseconds, this is done by increasing
+    the time the CEC bus is high. This start bit period is more than is
+    valid and the receiver should return to Idle state when this is detected.
+
+    Even though this start bit period is longer than is valid it is undefined
+    what a receiver will do. It might just accept it, or it might time out and
+    return to Idle state. Unfortunately the CEC specification is silent about
+    this.
+
+``<op>[,<mode>] tx-last-bit <bit>``
+    Just stop transmitting after this bit.  If <op> specifies a specific CEC
+    opcode then the bit position must be at least 18, otherwise the opcode
+    hasn't been received yet. This command can be used to test how the receiver
+    reacts when a message just suddenly stops. It should time out and go back
+    to Idle state.
+
+``<op>[,<mode>] tx-low-drive <bit>``
+    Force a Low Drive condition at this bit position. If <op> specifies a
+    specific CEC opcode then the bit position must be at least 18, otherwise
+    the opcode hasn't been received yet. This can be used to test how the
+    receiver handles Low Drive conditions. Note that if this happens at bit
+    positions 0-3 the receiver can interpret this as an Arbitration Lost
+    condition. This is implementation dependent.
+
+Custom Pulses
+-------------
+
+``tx-custom-low-usecs <usecs>``
+    This defines the duration in microseconds that the custom pulse pulls
+    the CEC line low. The default is 1000 microseconds.
+
+``tx-custom-high-usecs <usecs>``
+    This defines the duration in microseconds that the custom pulse keeps the
+    CEC line high (unless another CEC adapter pulls it low in that time).
+    The default is 1000 microseconds. The total period of the custom pulse is
+    ``tx-custom-low-usecs + tx-custom-high-usecs``.
+
+``<op>[,<mode>] tx-custom-bit <bit>``
+    Send the custom bit instead of a regular data bit. The bit position cannot
+    be an Ack bit.  If <op> specifies a specific CEC opcode then the bit
+    position must be at least 18, otherwise the opcode hasn't been received yet.
+
+``<op>[,<mode>] tx-custom-start``
+    Send the custom bit instead of a regular start bit.
+
+``tx-custom-pulse``
+    Transmit a single custom pulse as soon as the CEC bus is idle.
diff --git a/Documentation/userspace-api/media/conf_nitpick.py b/Documentation/userspace-api/media/conf_nitpick.py
new file mode 100644
index 000000000000..d0c50d75f518
--- /dev/null
+++ b/Documentation/userspace-api/media/conf_nitpick.py
@@ -0,0 +1,111 @@
+# -*- coding: utf-8; mode: python -*-
+
+# SPDX-License-Identifier: GPL-2.0
+
+project = 'Linux Media Subsystem Documentation'
+
+# It is possible to run Sphinx in nickpick mode with:
+nitpicky = True
+
+# within nit-picking build, do not refer to any intersphinx object
+intersphinx_mapping = {}
+
+# In nickpick mode, it will complain about lots of missing references that
+#
+# 1) are just typedefs like: bool, __u32, etc;
+# 2) It will complain for things like: enum, NULL;
+# 3) It will complain for symbols that should be on different
+#    books (but currently aren't ported to ReST)
+#
+# The list below has a list of such symbols to be ignored in nitpick mode
+#
+nitpick_ignore = [
+    ("c:func", "clock_gettime"),
+    ("c:func", "close"),
+    ("c:func", "container_of"),
+    ("c:func", "copy_from_user"),
+    ("c:func", "copy_to_user"),
+    ("c:func", "determine_valid_ioctls"),
+    ("c:func", "ERR_PTR"),
+    ("c:func", "i2c_new_device"),
+    ("c:func", "ioctl"),
+    ("c:func", "IS_ERR"),
+    ("c:func", "KERNEL_VERSION"),
+    ("c:func", "mmap"),
+    ("c:func", "open"),
+    ("c:func", "pci_name"),
+    ("c:func", "poll"),
+    ("c:func", "PTR_ERR"),
+    ("c:func", "read"),
+    ("c:func", "release"),
+    ("c:func", "set"),
+    ("c:func", "struct fd_set"),
+    ("c:func", "struct pollfd"),
+    ("c:func", "usb_make_path"),
+    ("c:func", "wait_finish"),
+    ("c:func", "wait_prepare"),
+    ("c:func", "write"),
+
+    ("c:type", "atomic_t"),
+    ("c:type", "bool"),
+    ("c:type", "boolean"),
+    ("c:type", "buf_queue"),
+    ("c:type", "device"),
+    ("c:type", "device_driver"),
+    ("c:type", "device_node"),
+    ("c:type", "enum"),
+    ("c:type", "fd"),
+    ("c:type", "fd_set"),
+    ("c:type", "file"),
+    ("c:type", "i2c_adapter"),
+    ("c:type", "i2c_board_info"),
+    ("c:type", "i2c_client"),
+    ("c:type", "int16_t"),
+    ("c:type", "ktime_t"),
+    ("c:type", "led_classdev_flash"),
+    ("c:type", "list_head"),
+    ("c:type", "lock_class_key"),
+    ("c:type", "module"),
+    ("c:type", "mutex"),
+    ("c:type", "NULL"),
+    ("c:type", "off_t"),
+    ("c:type", "pci_dev"),
+    ("c:type", "pdvbdev"),
+    ("c:type", "poll_table"),
+    ("c:type", "platform_device"),
+    ("c:type", "pollfd"),
+    ("c:type", "poll_table_struct"),
+    ("c:type", "s32"),
+    ("c:type", "s64"),
+    ("c:type", "sd"),
+    ("c:type", "size_t"),
+    ("c:type", "spi_board_info"),
+    ("c:type", "spi_device"),
+    ("c:type", "spi_master"),
+    ("c:type", "ssize_t"),
+    ("c:type", "fb_fix_screeninfo"),
+    ("c:type", "pollfd"),
+    ("c:type", "timeval"),
+    ("c:type", "video_capability"),
+    ("c:type", "timeval"),
+    ("c:type", "__u16"),
+    ("c:type", "u16"),
+    ("c:type", "__u32"),
+    ("c:type", "u32"),
+    ("c:type", "__u64"),
+    ("c:type", "u64"),
+    ("c:type", "u8"),
+    ("c:type", "uint16_t"),
+    ("c:type", "uint32_t"),
+    ("c:type", "union"),
+    ("c:type", "__user"),
+    ("c:type", "usb_device"),
+    ("c:type", "usb_interface"),
+    ("c:type", "v4l2_std_id"),
+    ("c:type", "video_system_t"),
+    ("c:type", "vm_area_struct"),
+
+    # Opaque structures
+
+    ("c:type", "v4l2_m2m_dev"),
+]
diff --git a/Documentation/userspace-api/media/dmx.h.rst.exceptions b/Documentation/userspace-api/media/dmx.h.rst.exceptions
new file mode 100644
index 000000000000..afc14d384b83
--- /dev/null
+++ b/Documentation/userspace-api/media/dmx.h.rst.exceptions
@@ -0,0 +1,66 @@
+# SPDX-License-Identifier: GPL-2.0
+
+# Ignore header name
+ignore define _UAPI_DVBDMX_H_
+
+# Ignore limit constants
+ignore define DMX_FILTER_SIZE
+
+# dmx_pes_type_t enum symbols
+replace enum dmx_ts_pes :c:type:`dmx_pes_type`
+replace symbol DMX_PES_AUDIO0 :c:type:`dmx_pes_type`
+replace symbol DMX_PES_VIDEO0 :c:type:`dmx_pes_type`
+replace symbol DMX_PES_TELETEXT0 :c:type:`dmx_pes_type`
+replace symbol DMX_PES_SUBTITLE0 :c:type:`dmx_pes_type`
+replace symbol DMX_PES_PCR0 :c:type:`dmx_pes_type`
+replace symbol DMX_PES_AUDIO1 :c:type:`dmx_pes_type`
+replace symbol DMX_PES_VIDEO1 :c:type:`dmx_pes_type`
+replace symbol DMX_PES_TELETEXT1 :c:type:`dmx_pes_type`
+replace symbol DMX_PES_SUBTITLE1 :c:type:`dmx_pes_type`
+replace symbol DMX_PES_PCR1 :c:type:`dmx_pes_type`
+replace symbol DMX_PES_AUDIO2 :c:type:`dmx_pes_type`
+replace symbol DMX_PES_VIDEO2 :c:type:`dmx_pes_type`
+replace symbol DMX_PES_TELETEXT2 :c:type:`dmx_pes_type`
+replace symbol DMX_PES_SUBTITLE2 :c:type:`dmx_pes_type`
+replace symbol DMX_PES_PCR2 :c:type:`dmx_pes_type`
+replace symbol DMX_PES_AUDIO3 :c:type:`dmx_pes_type`
+replace symbol DMX_PES_VIDEO3 :c:type:`dmx_pes_type`
+replace symbol DMX_PES_TELETEXT3 :c:type:`dmx_pes_type`
+replace symbol DMX_PES_SUBTITLE3 :c:type:`dmx_pes_type`
+replace symbol DMX_PES_PCR3 :c:type:`dmx_pes_type`
+replace symbol DMX_PES_OTHER :c:type:`dmx_pes_type`
+
+# Ignore obsolete symbols
+ignore define DMX_PES_AUDIO
+ignore define DMX_PES_VIDEO
+ignore define DMX_PES_TELETEXT
+ignore define DMX_PES_SUBTITLE
+ignore define DMX_PES_PCR
+
+# dmx_input_t symbols
+replace enum dmx_input :c:type:`dmx_input`
+replace symbol DMX_IN_FRONTEND :c:type:`dmx_input`
+replace symbol DMX_IN_DVR :c:type:`dmx_input`
+
+# Flags for struct dmx_sct_filter_params
+replace define DMX_CHECK_CRC :c:type:`dmx_sct_filter_params`
+replace define DMX_ONESHOT :c:type:`dmx_sct_filter_params`
+replace define DMX_IMMEDIATE_START :c:type:`dmx_sct_filter_params`
+
+# some typedefs should point to struct/enums
+replace typedef dmx_filter_t :c:type:`dmx_filter`
+replace typedef dmx_pes_type_t :c:type:`dmx_pes_type`
+replace typedef dmx_input_t :c:type:`dmx_input`
+
+replace symbol DMX_BUFFER_FLAG_HAD_CRC32_DISCARD :c:type:`dmx_buffer_flags`
+replace	symbol DMX_BUFFER_FLAG_TEI :c:type:`dmx_buffer_flags`
+replace	symbol DMX_BUFFER_PKT_COUNTER_MISMATCH :c:type:`dmx_buffer_flags`
+replace	symbol DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED :c:type:`dmx_buffer_flags`
+replace	symbol DMX_BUFFER_FLAG_DISCONTINUITY_INDICATOR :c:type:`dmx_buffer_flags`
+
+replace symbol DMX_OUT_DECODER :c:type:`dmx_output`
+replace symbol DMX_OUT_TAP :c:type:`dmx_output`
+replace symbol DMX_OUT_TS_TAP :c:type:`dmx_output`
+replace symbol DMX_OUT_TSDEMUX_TAP :c:type:`dmx_output`
+
+replace ioctl DMX_DQBUF dmx_qbuf
diff --git a/Documentation/userspace-api/media/drivers/cx2341x-uapi.rst b/Documentation/userspace-api/media/drivers/cx2341x-uapi.rst
new file mode 100644
index 000000000000..8a7977af79d5
--- /dev/null
+++ b/Documentation/userspace-api/media/drivers/cx2341x-uapi.rst
@@ -0,0 +1,179 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+The cx2341x driver
+==================
+
+Non-compressed file format
+--------------------------
+
+The cx23416 can produce (and the cx23415 can also read) raw YUV output. The
+format of a YUV frame is specific to this chip and is called HM12. 'HM' stands
+for 'Hauppauge Macroblock', which is a misnomer as 'Conexant Macroblock' would
+be more accurate.
+
+The format is YUV 4:2:0 which uses 1 Y byte per pixel and 1 U and V byte per
+four pixels.
+
+The data is encoded as two macroblock planes, the first containing the Y
+values, the second containing UV macroblocks.
+
+The Y plane is divided into blocks of 16x16 pixels from left to right
+and from top to bottom. Each block is transmitted in turn, line-by-line.
+
+So the first 16 bytes are the first line of the top-left block, the
+second 16 bytes are the second line of the top-left block, etc. After
+transmitting this block the first line of the block on the right to the
+first block is transmitted, etc.
+
+The UV plane is divided into blocks of 16x8 UV values going from left
+to right, top to bottom. Each block is transmitted in turn, line-by-line.
+
+So the first 16 bytes are the first line of the top-left block and
+contain 8 UV value pairs (16 bytes in total). The second 16 bytes are the
+second line of 8 UV pairs of the top-left block, etc. After transmitting
+this block the first line of the block on the right to the first block is
+transmitted, etc.
+
+The code below is given as an example on how to convert HM12 to separate
+Y, U and V planes. This code assumes frames of 720x576 (PAL) pixels.
+
+The width of a frame is always 720 pixels, regardless of the actual specified
+width.
+
+If the height is not a multiple of 32 lines, then the captured video is
+missing macroblocks at the end and is unusable. So the height must be a
+multiple of 32.
+
+Raw format c example
+~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: c
+
+	#include <stdio.h>
+	#include <stdlib.h>
+	#include <string.h>
+
+	static unsigned char frame[576*720*3/2];
+	static unsigned char framey[576*720];
+	static unsigned char frameu[576*720 / 4];
+	static unsigned char framev[576*720 / 4];
+
+	static void de_macro_y(unsigned char* dst, unsigned char *src, int dstride, int w, int h)
+	{
+	unsigned int y, x, i;
+
+	// descramble Y plane
+	// dstride = 720 = w
+	// The Y plane is divided into blocks of 16x16 pixels
+	// Each block in transmitted in turn, line-by-line.
+	for (y = 0; y < h; y += 16) {
+		for (x = 0; x < w; x += 16) {
+		for (i = 0; i < 16; i++) {
+			memcpy(dst + x + (y + i) * dstride, src, 16);
+			src += 16;
+		}
+		}
+	}
+	}
+
+	static void de_macro_uv(unsigned char *dstu, unsigned char *dstv, unsigned char *src, int dstride, int w, int h)
+	{
+	unsigned int y, x, i;
+
+	// descramble U/V plane
+	// dstride = 720 / 2 = w
+	// The U/V values are interlaced (UVUV...).
+	// Again, the UV plane is divided into blocks of 16x16 UV values.
+	// Each block in transmitted in turn, line-by-line.
+	for (y = 0; y < h; y += 16) {
+		for (x = 0; x < w; x += 8) {
+		for (i = 0; i < 16; i++) {
+			int idx = x + (y + i) * dstride;
+
+			dstu[idx+0] = src[0];  dstv[idx+0] = src[1];
+			dstu[idx+1] = src[2];  dstv[idx+1] = src[3];
+			dstu[idx+2] = src[4];  dstv[idx+2] = src[5];
+			dstu[idx+3] = src[6];  dstv[idx+3] = src[7];
+			dstu[idx+4] = src[8];  dstv[idx+4] = src[9];
+			dstu[idx+5] = src[10]; dstv[idx+5] = src[11];
+			dstu[idx+6] = src[12]; dstv[idx+6] = src[13];
+			dstu[idx+7] = src[14]; dstv[idx+7] = src[15];
+			src += 16;
+		}
+		}
+	}
+	}
+
+	/*************************************************************************/
+	int main(int argc, char **argv)
+	{
+	FILE *fin;
+	int i;
+
+	if (argc == 1) fin = stdin;
+	else fin = fopen(argv[1], "r");
+
+	if (fin == NULL) {
+		fprintf(stderr, "cannot open input\n");
+		exit(-1);
+	}
+	while (fread(frame, sizeof(frame), 1, fin) == 1) {
+		de_macro_y(framey, frame, 720, 720, 576);
+		de_macro_uv(frameu, framev, frame + 720 * 576, 720 / 2, 720 / 2, 576 / 2);
+		fwrite(framey, sizeof(framey), 1, stdout);
+		fwrite(framev, sizeof(framev), 1, stdout);
+		fwrite(frameu, sizeof(frameu), 1, stdout);
+	}
+	fclose(fin);
+	return 0;
+	}
+
+
+Format of embedded V4L2_MPEG_STREAM_VBI_FMT_IVTV VBI data
+---------------------------------------------------------
+
+Author: Hans Verkuil <hverkuil@xs4all.nl>
+
+
+This section describes the V4L2_MPEG_STREAM_VBI_FMT_IVTV format of the VBI data
+embedded in an MPEG-2 program stream. This format is in part dictated by some
+hardware limitations of the ivtv driver (the driver for the Conexant cx23415/6
+chips), in particular a maximum size for the VBI data. Anything longer is cut
+off when the MPEG stream is played back through the cx23415.
+
+The advantage of this format is it is very compact and that all VBI data for
+all lines can be stored while still fitting within the maximum allowed size.
+
+The stream ID of the VBI data is 0xBD. The maximum size of the embedded data is
+4 + 43 * 36, which is 4 bytes for a header and 2 * 18 VBI lines with a 1 byte
+header and a 42 bytes payload each. Anything beyond this limit is cut off by
+the cx23415/6 firmware. Besides the data for the VBI lines we also need 36 bits
+for a bitmask determining which lines are captured and 4 bytes for a magic cookie,
+signifying that this data package contains V4L2_MPEG_STREAM_VBI_FMT_IVTV VBI data.
+If all lines are used, then there is no longer room for the bitmask. To solve this
+two different magic numbers were introduced:
+
+'itv0': After this magic number two unsigned longs follow. Bits 0-17 of the first
+unsigned long denote which lines of the first field are captured. Bits 18-31 of
+the first unsigned long and bits 0-3 of the second unsigned long are used for the
+second field.
+
+'ITV0': This magic number assumes all VBI lines are captured, i.e. it implicitly
+implies that the bitmasks are 0xffffffff and 0xf.
+
+After these magic cookies (and the 8 byte bitmask in case of cookie 'itv0') the
+captured VBI lines start:
+
+For each line the least significant 4 bits of the first byte contain the data type.
+Possible values are shown in the table below. The payload is in the following 42
+bytes.
+
+Here is the list of possible data types:
+
+.. code-block:: c
+
+	#define IVTV_SLICED_TYPE_TELETEXT       0x1     // Teletext (uses lines 6-22 for PAL)
+	#define IVTV_SLICED_TYPE_CC             0x4     // Closed Captions (line 21 NTSC)
+	#define IVTV_SLICED_TYPE_WSS            0x5     // Wide Screen Signal (line 23 PAL)
+	#define IVTV_SLICED_TYPE_VPS            0x7     // Video Programming System (PAL) (line 16)
+
diff --git a/Documentation/userspace-api/media/drivers/imx-uapi.rst b/Documentation/userspace-api/media/drivers/imx-uapi.rst
new file mode 100644
index 000000000000..8d47712dea9f
--- /dev/null
+++ b/Documentation/userspace-api/media/drivers/imx-uapi.rst
@@ -0,0 +1,125 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=========================
+i.MX Video Capture Driver
+=========================
+
+Events
+======
+
+.. _imx_api_ipuX_csiY:
+
+ipuX_csiY
+---------
+
+This subdev can generate the following event when enabling the second
+IDMAC source pad:
+
+- V4L2_EVENT_IMX_FRAME_INTERVAL_ERROR
+
+The user application can subscribe to this event from the ipuX_csiY
+subdev node. This event is generated by the Frame Interval Monitor
+(see below for more on the FIM).
+
+Controls
+========
+
+.. _imx_api_FIM:
+
+Frame Interval Monitor in ipuX_csiY
+-----------------------------------
+
+The adv718x decoders can occasionally send corrupt fields during
+NTSC/PAL signal re-sync (too little or too many video lines). When
+this happens, the IPU triggers a mechanism to re-establish vertical
+sync by adding 1 dummy line every frame, which causes a rolling effect
+from image to image, and can last a long time before a stable image is
+recovered. Or sometimes the mechanism doesn't work at all, causing a
+permanent split image (one frame contains lines from two consecutive
+captured images).
+
+From experiment it was found that during image rolling, the frame
+intervals (elapsed time between two EOF's) drop below the nominal
+value for the current standard, by about one frame time (60 usec),
+and remain at that value until rolling stops.
+
+While the reason for this observation isn't known (the IPU dummy
+line mechanism should show an increase in the intervals by 1 line
+time every frame, not a fixed value), we can use it to detect the
+corrupt fields using a frame interval monitor. If the FIM detects a
+bad frame interval, the ipuX_csiY subdev will send the event
+V4L2_EVENT_IMX_FRAME_INTERVAL_ERROR. Userland can register with
+the FIM event notification on the ipuX_csiY subdev device node.
+Userland can issue a streaming restart when this event is received
+to correct the rolling/split image.
+
+The ipuX_csiY subdev includes custom controls to tweak some dials for
+FIM. If one of these controls is changed during streaming, the FIM will
+be reset and will continue at the new settings.
+
+- V4L2_CID_IMX_FIM_ENABLE
+
+Enable/disable the FIM.
+
+- V4L2_CID_IMX_FIM_NUM
+
+How many frame interval measurements to average before comparing against
+the nominal frame interval reported by the sensor. This can reduce noise
+caused by interrupt latency.
+
+- V4L2_CID_IMX_FIM_TOLERANCE_MIN
+
+If the averaged intervals fall outside nominal by this amount, in
+microseconds, the V4L2_EVENT_IMX_FRAME_INTERVAL_ERROR event is sent.
+
+- V4L2_CID_IMX_FIM_TOLERANCE_MAX
+
+If any intervals are higher than this value, those samples are
+discarded and do not enter into the average. This can be used to
+discard really high interval errors that might be due to interrupt
+latency from high system load.
+
+- V4L2_CID_IMX_FIM_NUM_SKIP
+
+How many frames to skip after a FIM reset or stream restart before
+FIM begins to average intervals.
+
+- V4L2_CID_IMX_FIM_ICAP_CHANNEL / V4L2_CID_IMX_FIM_ICAP_EDGE
+
+These controls will configure an input capture channel as the method
+for measuring frame intervals. This is superior to the default method
+of measuring frame intervals via EOF interrupt, since it is not subject
+to uncertainty errors introduced by interrupt latency.
+
+Input capture requires hardware support. A VSYNC signal must be routed
+to one of the i.MX6 input capture channel pads.
+
+V4L2_CID_IMX_FIM_ICAP_CHANNEL configures which i.MX6 input capture
+channel to use. This must be 0 or 1.
+
+V4L2_CID_IMX_FIM_ICAP_EDGE configures which signal edge will trigger
+input capture events. By default the input capture method is disabled
+with a value of IRQ_TYPE_NONE. Set this control to IRQ_TYPE_EDGE_RISING,
+IRQ_TYPE_EDGE_FALLING, or IRQ_TYPE_EDGE_BOTH to enable input capture,
+triggered on the given signal edge(s).
+
+When input capture is disabled, frame intervals will be measured via
+EOF interrupt.
+
+
+File list
+---------
+
+drivers/staging/media/imx/
+include/media/imx.h
+include/linux/imx-media.h
+
+
+Authors
+-------
+
+- Steve Longerbeam <steve_longerbeam@mentor.com>
+- Philipp Zabel <kernel@pengutronix.de>
+- Russell King <linux@armlinux.org.uk>
+
+Copyright (C) 2012-2017 Mentor Graphics Inc.
diff --git a/Documentation/userspace-api/media/drivers/index.rst b/Documentation/userspace-api/media/drivers/index.rst
new file mode 100644
index 000000000000..05a82f8c0c99
--- /dev/null
+++ b/Documentation/userspace-api/media/drivers/index.rst
@@ -0,0 +1,39 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: <isonum.txt>
+
+.. _v4l-drivers_uapi:
+
+################################################
+Video4Linux (V4L)  driver-specific documentation
+################################################
+
+**Copyright** |copy| 1999-2016 : LinuxTV Developers
+
+This documentation is free software; 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.
+
+For more details see the file COPYING in the source distribution of Linux.
+
+.. only:: html
+
+   .. class:: toc-title
+
+        Table of Contents
+
+.. toctree::
+	:maxdepth: 5
+	:numbered:
+
+	cx2341x-uapi
+	imx-uapi
+	max2175
+	meye-uapi
+	omap3isp-uapi
+	uvcvideo
diff --git a/Documentation/userspace-api/media/drivers/max2175.rst b/Documentation/userspace-api/media/drivers/max2175.rst
new file mode 100644
index 000000000000..35d3c4b41fc7
--- /dev/null
+++ b/Documentation/userspace-api/media/drivers/max2175.rst
@@ -0,0 +1,64 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Maxim Integrated MAX2175 RF to bits tuner driver
+================================================
+
+The MAX2175 driver implements the following driver-specific controls:
+
+``V4L2_CID_MAX2175_I2S_ENABLE``
+-------------------------------
+    Enable/Disable I2S output of the tuner. This is a private control
+    that can be accessed only using the subdev interface.
+    Refer to Documentation/driver-api/media/v4l2-controls.rst for more details.
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 4
+
+    * - ``(0)``
+      - I2S output is disabled.
+    * - ``(1)``
+      - I2S output is enabled.
+
+``V4L2_CID_MAX2175_HSLS``
+-------------------------
+    The high-side/low-side (HSLS) control of the tuner for a given band.
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 4
+
+    * - ``(0)``
+      - The LO frequency position is below the desired frequency.
+    * - ``(1)``
+      - The LO frequency position is above the desired frequency.
+
+``V4L2_CID_MAX2175_RX_MODE (menu)``
+-----------------------------------
+    The Rx mode controls a number of preset parameters of the tuner like
+    sample clock (sck), sampling rate etc. These multiple settings are
+    provided under one single label called Rx mode in the datasheet. The
+    list below shows the supported modes with a brief description.
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 4
+
+    * - ``"Europe modes"``
+    * - ``"FM 1.2" (0)``
+      - This configures FM band with a sample rate of 0.512 million
+        samples/sec with a 10.24 MHz sck.
+    * - ``"DAB 1.2" (1)``
+      - This configures VHF band with a sample rate of 2.048 million
+        samples/sec with a 32.768 MHz sck.
+
+    * - ``"North America modes"``
+    * - ``"FM 1.0" (0)``
+      - This configures FM band with a sample rate of 0.7441875 million
+        samples/sec with a 14.88375 MHz sck.
+    * - ``"DAB 1.2" (1)``
+      - This configures FM band with a sample rate of 0.372 million
+        samples/sec with a 7.441875 MHz sck.
diff --git a/Documentation/userspace-api/media/drivers/meye-uapi.rst b/Documentation/userspace-api/media/drivers/meye-uapi.rst
new file mode 100644
index 000000000000..66b1c142f920
--- /dev/null
+++ b/Documentation/userspace-api/media/drivers/meye-uapi.rst
@@ -0,0 +1,53 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: <isonum.txt>
+
+Vaio Picturebook Motion Eye Camera Driver
+=========================================
+
+Copyright |copy| 2001-2004 Stelian Pop <stelian@popies.net>
+
+Copyright |copy| 2001-2002 Alcôve <www.alcove.com>
+
+Copyright |copy| 2000 Andrew Tridgell <tridge@samba.org>
+
+Private API
+-----------
+
+The driver supports frame grabbing with the video4linux API,
+so all video4linux tools (like xawtv) should work with this driver.
+
+Besides the video4linux interface, the driver has a private interface
+for accessing the Motion Eye extended parameters (camera sharpness,
+agc, video framerate), the snapshot and the MJPEG capture facilities.
+
+This interface consists of several ioctls (prototypes and structures
+can be found in include/linux/meye.h):
+
+MEYEIOC_G_PARAMS and MEYEIOC_S_PARAMS
+	Get and set the extended parameters of the motion eye camera.
+	The user should always query the current parameters with
+	MEYEIOC_G_PARAMS, change what he likes and then issue the
+	MEYEIOC_S_PARAMS call (checking for -EINVAL). The extended
+	parameters are described by the meye_params structure.
+
+
+MEYEIOC_QBUF_CAPT
+	Queue a buffer for capture (the buffers must have been
+	obtained with a VIDIOCGMBUF call and mmap'ed by the
+	application). The argument to MEYEIOC_QBUF_CAPT is the
+	buffer number to queue (or -1 to end capture). The first
+	call to MEYEIOC_QBUF_CAPT starts the streaming capture.
+
+MEYEIOC_SYNC
+	Takes as an argument the buffer number you want to sync.
+	This ioctl blocks until the buffer is filled and ready
+	for the application to use. It returns the buffer size.
+
+MEYEIOC_STILLCAPT and MEYEIOC_STILLJCAPT
+	Takes a snapshot in an uncompressed or compressed jpeg format.
+	This ioctl blocks until the snapshot is done and returns (for
+	jpeg snapshot) the size of the image. The image data is
+	available from the first mmap'ed buffer.
+
+Look at the 'motioneye' application code for an actual example.
diff --git a/Documentation/userspace-api/media/drivers/omap3isp-uapi.rst b/Documentation/userspace-api/media/drivers/omap3isp-uapi.rst
new file mode 100644
index 000000000000..5f966a874a3c
--- /dev/null
+++ b/Documentation/userspace-api/media/drivers/omap3isp-uapi.rst
@@ -0,0 +1,208 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: <isonum.txt>
+
+OMAP 3 Image Signal Processor (ISP) driver
+==========================================
+
+Copyright |copy| 2010 Nokia Corporation
+
+Copyright |copy| 2009 Texas Instruments, Inc.
+
+Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>,
+Sakari Ailus <sakari.ailus@iki.fi>, David Cohen <dacohen@gmail.com>
+
+
+Events
+------
+
+The OMAP 3 ISP driver does support the V4L2 event interface on CCDC and
+statistics (AEWB, AF and histogram) subdevs.
+
+The CCDC subdev produces V4L2_EVENT_FRAME_SYNC type event on HS_VS
+interrupt which is used to signal frame start. Earlier version of this
+driver used V4L2_EVENT_OMAP3ISP_HS_VS for this purpose. The event is
+triggered exactly when the reception of the first line of the frame starts
+in the CCDC module. The event can be subscribed on the CCDC subdev.
+
+(When using parallel interface one must pay account to correct configuration
+of the VS signal polarity. This is automatically correct when using the serial
+receivers.)
+
+Each of the statistics subdevs is able to produce events. An event is
+generated whenever a statistics buffer can be dequeued by a user space
+application using the VIDIOC_OMAP3ISP_STAT_REQ IOCTL. The events available
+are:
+
+- V4L2_EVENT_OMAP3ISP_AEWB
+- V4L2_EVENT_OMAP3ISP_AF
+- V4L2_EVENT_OMAP3ISP_HIST
+
+The type of the event data is struct omap3isp_stat_event_status for these
+ioctls. If there is an error calculating the statistics, there will be an
+event as usual, but no related statistics buffer. In this case
+omap3isp_stat_event_status.buf_err is set to non-zero.
+
+
+Private IOCTLs
+--------------
+
+The OMAP 3 ISP driver supports standard V4L2 IOCTLs and controls where
+possible and practical. Much of the functions provided by the ISP, however,
+does not fall under the standard IOCTLs --- gamma tables and configuration of
+statistics collection are examples of such.
+
+In general, there is a private ioctl for configuring each of the blocks
+containing hardware-dependent functions.
+
+The following private IOCTLs are supported:
+
+- VIDIOC_OMAP3ISP_CCDC_CFG
+- VIDIOC_OMAP3ISP_PRV_CFG
+- VIDIOC_OMAP3ISP_AEWB_CFG
+- VIDIOC_OMAP3ISP_HIST_CFG
+- VIDIOC_OMAP3ISP_AF_CFG
+- VIDIOC_OMAP3ISP_STAT_REQ
+- VIDIOC_OMAP3ISP_STAT_EN
+
+The parameter structures used by these ioctls are described in
+include/linux/omap3isp.h. The detailed functions of the ISP itself related to
+a given ISP block is described in the Technical Reference Manuals (TRMs) ---
+see the end of the document for those.
+
+While it is possible to use the ISP driver without any use of these private
+IOCTLs it is not possible to obtain optimal image quality this way. The AEWB,
+AF and histogram modules cannot be used without configuring them using the
+appropriate private IOCTLs.
+
+
+CCDC and preview block IOCTLs
+-----------------------------
+
+The VIDIOC_OMAP3ISP_CCDC_CFG and VIDIOC_OMAP3ISP_PRV_CFG IOCTLs are used to
+configure, enable and disable functions in the CCDC and preview blocks,
+respectively. Both IOCTLs control several functions in the blocks they
+control. VIDIOC_OMAP3ISP_CCDC_CFG IOCTL accepts a pointer to struct
+omap3isp_ccdc_update_config as its argument. Similarly VIDIOC_OMAP3ISP_PRV_CFG
+accepts a pointer to struct omap3isp_prev_update_config. The definition of
+both structures is available in [#]_.
+
+The update field in the structures tells whether to update the configuration
+for the specific function and the flag tells whether to enable or disable the
+function.
+
+The update and flag bit masks accept the following values. Each separate
+functions in the CCDC and preview blocks is associated with a flag (either
+disable or enable; part of the flag field in the structure) and a pointer to
+configuration data for the function.
+
+Valid values for the update and flag fields are listed here for
+VIDIOC_OMAP3ISP_CCDC_CFG. Values may be or'ed to configure more than one
+function in the same IOCTL call.
+
+- OMAP3ISP_CCDC_ALAW
+- OMAP3ISP_CCDC_LPF
+- OMAP3ISP_CCDC_BLCLAMP
+- OMAP3ISP_CCDC_BCOMP
+- OMAP3ISP_CCDC_FPC
+- OMAP3ISP_CCDC_CULL
+- OMAP3ISP_CCDC_CONFIG_LSC
+- OMAP3ISP_CCDC_TBL_LSC
+
+The corresponding values for the VIDIOC_OMAP3ISP_PRV_CFG are here:
+
+- OMAP3ISP_PREV_LUMAENH
+- OMAP3ISP_PREV_INVALAW
+- OMAP3ISP_PREV_HRZ_MED
+- OMAP3ISP_PREV_CFA
+- OMAP3ISP_PREV_CHROMA_SUPP
+- OMAP3ISP_PREV_WB
+- OMAP3ISP_PREV_BLKADJ
+- OMAP3ISP_PREV_RGB2RGB
+- OMAP3ISP_PREV_COLOR_CONV
+- OMAP3ISP_PREV_YC_LIMIT
+- OMAP3ISP_PREV_DEFECT_COR
+- OMAP3ISP_PREV_GAMMABYPASS
+- OMAP3ISP_PREV_DRK_FRM_CAPTURE
+- OMAP3ISP_PREV_DRK_FRM_SUBTRACT
+- OMAP3ISP_PREV_LENS_SHADING
+- OMAP3ISP_PREV_NF
+- OMAP3ISP_PREV_GAMMA
+
+The associated configuration pointer for the function may not be NULL when
+enabling the function. When disabling a function the configuration pointer is
+ignored.
+
+
+Statistic blocks IOCTLs
+-----------------------
+
+The statistics subdevs do offer more dynamic configuration options than the
+other subdevs. They can be enabled, disable and reconfigured when the pipeline
+is in streaming state.
+
+The statistics blocks always get the input image data from the CCDC (as the
+histogram memory read isn't implemented). The statistics are dequeueable by
+the user from the statistics subdev nodes using private IOCTLs.
+
+The private IOCTLs offered by the AEWB, AF and histogram subdevs are heavily
+reflected by the register level interface offered by the ISP hardware. There
+are aspects that are purely related to the driver implementation and these are
+discussed next.
+
+VIDIOC_OMAP3ISP_STAT_EN
+-----------------------
+
+This private IOCTL enables/disables a statistic module. If this request is
+done before streaming, it will take effect as soon as the pipeline starts to
+stream.  If the pipeline is already streaming, it will take effect as soon as
+the CCDC becomes idle.
+
+VIDIOC_OMAP3ISP_AEWB_CFG, VIDIOC_OMAP3ISP_HIST_CFG and VIDIOC_OMAP3ISP_AF_CFG
+-----------------------------------------------------------------------------
+
+Those IOCTLs are used to configure the modules. They require user applications
+to have an in-depth knowledge of the hardware. Most of the fields explanation
+can be found on OMAP's TRMs. The two following fields common to all the above
+configure private IOCTLs require explanation for better understanding as they
+are not part of the TRM.
+
+omap3isp_[h3a_af/h3a_aewb/hist]\_config.buf_size:
+
+The modules handle their buffers internally. The necessary buffer size for the
+module's data output depends on the requested configuration. Although the
+driver supports reconfiguration while streaming, it does not support a
+reconfiguration which requires bigger buffer size than what is already
+internally allocated if the module is enabled. It will return -EBUSY on this
+case. In order to avoid such condition, either disable/reconfigure/enable the
+module or request the necessary buffer size during the first configuration
+while the module is disabled.
+
+The internal buffer size allocation considers the requested configuration's
+minimum buffer size and the value set on buf_size field. If buf_size field is
+out of [minimum, maximum] buffer size range, it's clamped to fit in there.
+The driver then selects the biggest value. The corrected buf_size value is
+written back to user application.
+
+omap3isp_[h3a_af/h3a_aewb/hist]\_config.config_counter:
+
+As the configuration doesn't take effect synchronously to the request, the
+driver must provide a way to track this information to provide more accurate
+data. After a configuration is requested, the config_counter returned to user
+space application will be an unique value associated to that request. When
+user application receives an event for buffer availability or when a new
+buffer is requested, this config_counter is used to match a buffer data and a
+configuration.
+
+VIDIOC_OMAP3ISP_STAT_REQ
+------------------------
+
+Send to user space the oldest data available in the internal buffer queue and
+discards such buffer afterwards. The field omap3isp_stat_data.frame_number
+matches with the video buffer's field_count.
+
+
+References
+----------
+
+.. [#] include/linux/omap3isp.h
diff --git a/Documentation/userspace-api/media/drivers/uvcvideo.rst b/Documentation/userspace-api/media/drivers/uvcvideo.rst
new file mode 100644
index 000000000000..e5fd8fad333c
--- /dev/null
+++ b/Documentation/userspace-api/media/drivers/uvcvideo.rst
@@ -0,0 +1,257 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+The Linux USB Video Class (UVC) driver
+======================================
+
+This file documents some driver-specific aspects of the UVC driver, such as
+driver-specific ioctls and implementation notes.
+
+Questions and remarks can be sent to the Linux UVC development mailing list at
+linux-uvc-devel@lists.berlios.de.
+
+
+Extension Unit (XU) support
+---------------------------
+
+Introduction
+~~~~~~~~~~~~
+
+The UVC specification allows for vendor-specific extensions through extension
+units (XUs). The Linux UVC driver supports extension unit controls (XU controls)
+through two separate mechanisms:
+
+  - through mappings of XU controls to V4L2 controls
+  - through a driver-specific ioctl interface
+
+The first one allows generic V4L2 applications to use XU controls by mapping
+certain XU controls onto V4L2 controls, which then show up during ordinary
+control enumeration.
+
+The second mechanism requires uvcvideo-specific knowledge for the application to
+access XU controls but exposes the entire UVC XU concept to user space for
+maximum flexibility.
+
+Both mechanisms complement each other and are described in more detail below.
+
+
+Control mappings
+~~~~~~~~~~~~~~~~
+
+The UVC driver provides an API for user space applications to define so-called
+control mappings at runtime. These allow for individual XU controls or byte
+ranges thereof to be mapped to new V4L2 controls. Such controls appear and
+function exactly like normal V4L2 controls (i.e. the stock controls, such as
+brightness, contrast, etc.). However, reading or writing of such a V4L2 controls
+triggers a read or write of the associated XU control.
+
+The ioctl used to create these control mappings is called UVCIOC_CTRL_MAP.
+Previous driver versions (before 0.2.0) required another ioctl to be used
+beforehand (UVCIOC_CTRL_ADD) to pass XU control information to the UVC driver.
+This is no longer necessary as newer uvcvideo versions query the information
+directly from the device.
+
+For details on the UVCIOC_CTRL_MAP ioctl please refer to the section titled
+"IOCTL reference" below.
+
+
+3. Driver specific XU control interface
+
+For applications that need to access XU controls directly, e.g. for testing
+purposes, firmware upload, or accessing binary controls, a second mechanism to
+access XU controls is provided in the form of a driver-specific ioctl, namely
+UVCIOC_CTRL_QUERY.
+
+A call to this ioctl allows applications to send queries to the UVC driver that
+directly map to the low-level UVC control requests.
+
+In order to make such a request the UVC unit ID of the control's extension unit
+and the control selector need to be known. This information either needs to be
+hardcoded in the application or queried using other ways such as by parsing the
+UVC descriptor or, if available, using the media controller API to enumerate a
+device's entities.
+
+Unless the control size is already known it is necessary to first make a
+UVC_GET_LEN requests in order to be able to allocate a sufficiently large buffer
+and set the buffer size to the correct value. Similarly, to find out whether
+UVC_GET_CUR or UVC_SET_CUR are valid requests for a given control, a
+UVC_GET_INFO request should be made. The bits 0 (GET supported) and 1 (SET
+supported) of the resulting byte indicate which requests are valid.
+
+With the addition of the UVCIOC_CTRL_QUERY ioctl the UVCIOC_CTRL_GET and
+UVCIOC_CTRL_SET ioctls have become obsolete since their functionality is a
+subset of the former ioctl. For the time being they are still supported but
+application developers are encouraged to use UVCIOC_CTRL_QUERY instead.
+
+For details on the UVCIOC_CTRL_QUERY ioctl please refer to the section titled
+"IOCTL reference" below.
+
+
+Security
+~~~~~~~~
+
+The API doesn't currently provide a fine-grained access control facility. The
+UVCIOC_CTRL_ADD and UVCIOC_CTRL_MAP ioctls require super user permissions.
+
+Suggestions on how to improve this are welcome.
+
+
+Debugging
+~~~~~~~~~
+
+In order to debug problems related to XU controls or controls in general it is
+recommended to enable the UVC_TRACE_CONTROL bit in the module parameter 'trace'.
+This causes extra output to be written into the system log.
+
+
+IOCTL reference
+~~~~~~~~~~~~~~~
+
+UVCIOC_CTRL_MAP - Map a UVC control to a V4L2 control
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Argument: struct uvc_xu_control_mapping
+
+**Description**:
+
+	This ioctl creates a mapping between a UVC control or part of a UVC
+	control and a V4L2 control. Once mappings are defined, userspace
+	applications can access vendor-defined UVC control through the V4L2
+	control API.
+
+	To create a mapping, applications fill the uvc_xu_control_mapping
+	structure with information about an existing UVC control defined with
+	UVCIOC_CTRL_ADD and a new V4L2 control.
+
+	A UVC control can be mapped to several V4L2 controls. For instance,
+	a UVC pan/tilt control could be mapped to separate pan and tilt V4L2
+	controls. The UVC control is divided into non overlapping fields using
+	the 'size' and 'offset' fields and are then independently mapped to
+	V4L2 control.
+
+	For signed integer V4L2 controls the data_type field should be set to
+	UVC_CTRL_DATA_TYPE_SIGNED. Other values are currently ignored.
+
+**Return value**:
+
+	On success 0 is returned. On error -1 is returned and errno is set
+	appropriately.
+
+	ENOMEM
+		Not enough memory to perform the operation.
+	EPERM
+		Insufficient privileges (super user privileges are required).
+	EINVAL
+		No such UVC control.
+	EOVERFLOW
+		The requested offset and size would overflow the UVC control.
+	EEXIST
+		Mapping already exists.
+
+**Data types**:
+
+.. code-block:: none
+
+	* struct uvc_xu_control_mapping
+
+	__u32	id		V4L2 control identifier
+	__u8	name[32]	V4L2 control name
+	__u8	entity[16]	UVC extension unit GUID
+	__u8	selector	UVC control selector
+	__u8	size		V4L2 control size (in bits)
+	__u8	offset		V4L2 control offset (in bits)
+	enum v4l2_ctrl_type
+		v4l2_type	V4L2 control type
+	enum uvc_control_data_type
+		data_type	UVC control data type
+	struct uvc_menu_info
+		*menu_info	Array of menu entries (for menu controls only)
+	__u32	menu_count	Number of menu entries (for menu controls only)
+
+	* struct uvc_menu_info
+
+	__u32	value		Menu entry value used by the device
+	__u8	name[32]	Menu entry name
+
+
+	* enum uvc_control_data_type
+
+	UVC_CTRL_DATA_TYPE_RAW		Raw control (byte array)
+	UVC_CTRL_DATA_TYPE_SIGNED	Signed integer
+	UVC_CTRL_DATA_TYPE_UNSIGNED	Unsigned integer
+	UVC_CTRL_DATA_TYPE_BOOLEAN	Boolean
+	UVC_CTRL_DATA_TYPE_ENUM		Enumeration
+	UVC_CTRL_DATA_TYPE_BITMASK	Bitmask
+
+
+UVCIOC_CTRL_QUERY - Query a UVC XU control
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Argument: struct uvc_xu_control_query
+
+**Description**:
+
+	This ioctl queries a UVC XU control identified by its extension unit ID
+	and control selector.
+
+	There are a number of different queries available that closely
+	correspond to the low-level control requests described in the UVC
+	specification. These requests are:
+
+	UVC_GET_CUR
+		Obtain the current value of the control.
+	UVC_GET_MIN
+		Obtain the minimum value of the control.
+	UVC_GET_MAX
+		Obtain the maximum value of the control.
+	UVC_GET_DEF
+		Obtain the default value of the control.
+	UVC_GET_RES
+		Query the resolution of the control, i.e. the step size of the
+		allowed control values.
+	UVC_GET_LEN
+		Query the size of the control in bytes.
+	UVC_GET_INFO
+		Query the control information bitmap, which indicates whether
+		get/set requests are supported.
+	UVC_SET_CUR
+		Update the value of the control.
+
+	Applications must set the 'size' field to the correct length for the
+	control. Exceptions are the UVC_GET_LEN and UVC_GET_INFO queries, for
+	which the size must be set to 2 and 1, respectively. The 'data' field
+	must point to a valid writable buffer big enough to hold the indicated
+	number of data bytes.
+
+	Data is copied directly from the device without any driver-side
+	processing. Applications are responsible for data buffer formatting,
+	including little-endian/big-endian conversion. This is particularly
+	important for the result of the UVC_GET_LEN requests, which is always
+	returned as a little-endian 16-bit integer by the device.
+
+**Return value**:
+
+	On success 0 is returned. On error -1 is returned and errno is set
+	appropriately.
+
+	ENOENT
+		The device does not support the given control or the specified
+		extension unit could not be found.
+	ENOBUFS
+		The specified buffer size is incorrect (too big or too small).
+	EINVAL
+		An invalid request code was passed.
+	EBADRQC
+		The given request is not supported by the given control.
+	EFAULT
+		The data pointer references an inaccessible memory area.
+
+**Data types**:
+
+.. code-block:: none
+
+	* struct uvc_xu_control_query
+
+	__u8	unit		Extension unit ID
+	__u8	selector	Control selector
+	__u8	query		Request code to send to the device
+	__u16	size		Control data size (in bytes)
+	__u8	*data		Control value
diff --git a/Documentation/userspace-api/media/dvb/audio-bilingual-channel-select.rst b/Documentation/userspace-api/media/dvb/audio-bilingual-channel-select.rst
new file mode 100644
index 000000000000..6841233f3fee
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/audio-bilingual-channel-select.rst
@@ -0,0 +1,66 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _AUDIO_BILINGUAL_CHANNEL_SELECT:
+
+==============================
+AUDIO_BILINGUAL_CHANNEL_SELECT
+==============================
+
+Name
+----
+
+AUDIO_BILINGUAL_CHANNEL_SELECT
+
+.. attention:: This ioctl is deprecated
+
+Synopsis
+--------
+
+.. c:function:: int ioctl(int fd, AUDIO_BILINGUAL_CHANNEL_SELECT, struct *audio_channel_select)
+    :name: AUDIO_BILINGUAL_CHANNEL_SELECT
+
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    -
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+    -
+
+       -  audio_channel_select_t ch
+
+       -  Select the output format of the audio (mono left/right, stereo).
+
+
+Description
+-----------
+
+This ioctl is obsolete. Do not use in new drivers. It has been replaced
+by the V4L2 ``V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK`` control
+for MPEG decoders controlled through V4L2.
+
+This ioctl call asks the Audio Device to select the requested channel
+for bilingual streams if possible.
+
+
+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/userspace-api/media/dvb/audio-channel-select.rst b/Documentation/userspace-api/media/dvb/audio-channel-select.rst
new file mode 100644
index 000000000000..18e880e7eab4
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/audio-channel-select.rst
@@ -0,0 +1,66 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _AUDIO_CHANNEL_SELECT:
+
+====================
+AUDIO_CHANNEL_SELECT
+====================
+
+Name
+----
+
+AUDIO_CHANNEL_SELECT
+
+.. attention:: This ioctl is deprecated
+
+Synopsis
+--------
+
+.. c:function:: int ioctl(int fd, AUDIO_CHANNEL_SELECT, struct *audio_channel_select)
+    :name: AUDIO_CHANNEL_SELECT
+
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+    -
+
+       -  audio_channel_select_t ch
+
+       -  Select the output format of the audio (mono left/right, stereo).
+
+
+Description
+-----------
+
+This ioctl is for Digital TV devices only. To control a V4L2 decoder use the
+V4L2 ``V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK`` control instead.
+
+This ioctl call asks the Audio Device to select the requested channel if
+possible.
+
+
+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/userspace-api/media/dvb/audio-clear-buffer.rst b/Documentation/userspace-api/media/dvb/audio-clear-buffer.rst
new file mode 100644
index 000000000000..19f2ed752ce2
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/audio-clear-buffer.rst
@@ -0,0 +1,55 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _AUDIO_CLEAR_BUFFER:
+
+==================
+AUDIO_CLEAR_BUFFER
+==================
+
+Name
+----
+
+AUDIO_CLEAR_BUFFER
+
+.. attention:: This ioctl is deprecated
+
+Synopsis
+--------
+
+.. c:function:: int  ioctl(int fd, AUDIO_CLEAR_BUFFER)
+    :name: AUDIO_CLEAR_BUFFER
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+Description
+-----------
+
+This ioctl call asks the Audio Device to clear all software and hardware
+buffers of the audio decoder device.
+
+
+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/userspace-api/media/dvb/audio-continue.rst b/Documentation/userspace-api/media/dvb/audio-continue.rst
new file mode 100644
index 000000000000..b9a2b1e608b6
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/audio-continue.rst
@@ -0,0 +1,56 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _AUDIO_CONTINUE:
+
+==============
+AUDIO_CONTINUE
+==============
+
+Name
+----
+
+AUDIO_CONTINUE
+
+.. attention:: This ioctl is deprecated
+
+Synopsis
+--------
+
+.. c:function:: int  ioctl(int fd, AUDIO_CONTINUE)
+    :name: AUDIO_CONTINUE
+
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+Description
+-----------
+
+This ioctl restarts the decoding and playing process previously paused
+with AUDIO_PAUSE command.
+
+
+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/userspace-api/media/dvb/audio-fclose.rst b/Documentation/userspace-api/media/dvb/audio-fclose.rst
new file mode 100644
index 000000000000..448471d2f570
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/audio-fclose.rst
@@ -0,0 +1,63 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _audio_fclose:
+
+========================
+Digital TV audio close()
+========================
+
+Name
+----
+
+Digital TV audio close()
+
+.. attention:: This ioctl is deprecated
+
+Synopsis
+--------
+
+.. c:function:: int close(int fd)
+    :name: dvb-audio-close
+
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+
+Description
+-----------
+
+This system call closes a previously opened audio device.
+
+
+Return Value
+------------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  ``EBADF``
+
+       -  fd is not a valid open file descriptor.
diff --git a/Documentation/userspace-api/media/dvb/audio-fopen.rst b/Documentation/userspace-api/media/dvb/audio-fopen.rst
new file mode 100644
index 000000000000..f7ae94378f92
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/audio-fopen.rst
@@ -0,0 +1,115 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _audio_fopen:
+
+=======================
+Digital TV audio open()
+=======================
+
+Name
+----
+
+Digital TV audio open()
+
+.. attention:: This ioctl is deprecated
+
+Synopsis
+--------
+
+.. c:function:: int open(const char *deviceName, int flags)
+    :name: dvb-audio-open
+
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  const char \*deviceName
+
+       -  Name of specific audio device.
+
+    -  .. row 2
+
+       -  int flags
+
+       -  A bit-wise OR of the following flags:
+
+    -  .. row 3
+
+       -
+       -  O_RDONLY read-only access
+
+    -  .. row 4
+
+       -
+       -  O_RDWR read/write access
+
+    -  .. row 5
+
+       -
+       -  O_NONBLOCK open in non-blocking mode
+
+    -  .. row 6
+
+       -
+       -  (blocking mode is the default)
+
+
+Description
+-----------
+
+This system call opens a named audio device (e.g.
+/dev/dvb/adapter0/audio0) for subsequent use. When an open() call has
+succeeded, the device will be ready for use. The significance of
+blocking or non-blocking mode is described in the documentation for
+functions where there is a difference. It does not affect the semantics
+of the open() call itself. A device opened in blocking mode can later be
+put into non-blocking mode (and vice versa) using the F_SETFL command
+of the fcntl system call. This is a standard system call, documented in
+the Linux manual page for fcntl. Only one user can open the Audio Device
+in O_RDWR mode. All other attempts to open the device in this mode will
+fail, and an error code will be returned. If the Audio Device is opened
+in O_RDONLY mode, the only ioctl call that can be used is
+AUDIO_GET_STATUS. All other call will return with an error code.
+
+
+Return Value
+------------
+
+.. tabularcolumns:: |p{2.5cm}|p{15.0cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  ``ENODEV``
+
+       -  Device driver not loaded/available.
+
+    -  .. row 2
+
+       -  ``EBUSY``
+
+       -  Device or resource busy.
+
+    -  .. row 3
+
+       -  ``EINVAL``
+
+       -  Invalid argument.
diff --git a/Documentation/userspace-api/media/dvb/audio-fwrite.rst b/Documentation/userspace-api/media/dvb/audio-fwrite.rst
new file mode 100644
index 000000000000..1482636f9b1a
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/audio-fwrite.rst
@@ -0,0 +1,91 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _audio_fwrite:
+
+=========================
+Digital TV audio write()
+=========================
+
+Name
+----
+
+Digital TV audio write()
+
+.. attention:: This ioctl is deprecated
+
+Synopsis
+--------
+
+.. c:function:: size_t write(int fd, const void *buf, size_t count)
+    :name: dvb-audio-write
+
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+    -  .. row 2
+
+       -  void \*buf
+
+       -  Pointer to the buffer containing the PES data.
+
+    -  .. row 3
+
+       -  size_t count
+
+       -  Size of buf.
+
+
+Description
+-----------
+
+This system call can only be used if AUDIO_SOURCE_MEMORY is selected
+in the ioctl call AUDIO_SELECT_SOURCE. The data provided shall be in
+PES format. If O_NONBLOCK is not specified the function will block
+until buffer space is available. The amount of data to be transferred is
+implied by count.
+
+
+Return Value
+------------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  ``EPERM``
+
+       -  Mode AUDIO_SOURCE_MEMORY not selected.
+
+    -  .. row 2
+
+       -  ``ENOMEM``
+
+       -  Attempted to write more data than the internal buffer can hold.
+
+    -  .. row 3
+
+       -  ``EBADF``
+
+       -  fd is not a valid open file descriptor.
diff --git a/Documentation/userspace-api/media/dvb/audio-get-capabilities.rst b/Documentation/userspace-api/media/dvb/audio-get-capabilities.rst
new file mode 100644
index 000000000000..4e70d82969ad
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/audio-get-capabilities.rst
@@ -0,0 +1,63 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _AUDIO_GET_CAPABILITIES:
+
+======================
+AUDIO_GET_CAPABILITIES
+======================
+
+Name
+----
+
+AUDIO_GET_CAPABILITIES
+
+.. attention:: This ioctl is deprecated
+
+Synopsis
+--------
+
+.. c:function:: int ioctl(int fd, AUDIO_GET_CAPABILITIES, unsigned int *cap)
+    :name: AUDIO_GET_CAPABILITIES
+
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+    -
+
+       -  unsigned int \*cap
+
+       -  Returns a bit array of supported sound formats.
+
+
+Description
+-----------
+
+This ioctl call asks the Audio Device to tell us about the decoding
+capabilities of the audio hardware.
+
+
+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/userspace-api/media/dvb/audio-get-status.rst b/Documentation/userspace-api/media/dvb/audio-get-status.rst
new file mode 100644
index 000000000000..5a5180d642d4
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/audio-get-status.rst
@@ -0,0 +1,63 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _AUDIO_GET_STATUS:
+
+================
+AUDIO_GET_STATUS
+================
+
+Name
+----
+
+AUDIO_GET_STATUS
+
+.. attention:: This ioctl is deprecated
+
+Synopsis
+--------
+
+.. c:function:: int ioctl(int fd, AUDIO_GET_STATUS, struct audio_status *status)
+    :name: AUDIO_GET_STATUS
+
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+    -
+
+       -  struct audio_status \*status
+
+       -  Returns the current state of Audio Device.
+
+
+Description
+-----------
+
+This ioctl call asks the Audio Device to return the current state of the
+Audio Device.
+
+
+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/userspace-api/media/dvb/audio-pause.rst b/Documentation/userspace-api/media/dvb/audio-pause.rst
new file mode 100644
index 000000000000..3e9fe06d3a0f
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/audio-pause.rst
@@ -0,0 +1,57 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _AUDIO_PAUSE:
+
+===========
+AUDIO_PAUSE
+===========
+
+Name
+----
+
+AUDIO_PAUSE
+
+.. attention:: This ioctl is deprecated
+
+Synopsis
+--------
+
+.. c:function:: int  ioctl(int fd, AUDIO_PAUSE)
+    :name: AUDIO_PAUSE
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+
+Description
+-----------
+
+This ioctl call suspends the audio stream being played. Decoding and
+playing are paused. It is then possible to restart again decoding and
+playing process of the audio stream using AUDIO_CONTINUE command.
+
+
+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/userspace-api/media/dvb/audio-play.rst b/Documentation/userspace-api/media/dvb/audio-play.rst
new file mode 100644
index 000000000000..388a581a19f2
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/audio-play.rst
@@ -0,0 +1,56 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _AUDIO_PLAY:
+
+==========
+AUDIO_PLAY
+==========
+
+Name
+----
+
+AUDIO_PLAY
+
+.. attention:: This ioctl is deprecated
+
+Synopsis
+--------
+
+.. c:function:: int  ioctl(int fd, AUDIO_PLAY)
+    :name: AUDIO_PLAY
+
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+Description
+-----------
+
+This ioctl call asks the Audio Device to start playing an audio stream
+from the selected source.
+
+
+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/userspace-api/media/dvb/audio-select-source.rst b/Documentation/userspace-api/media/dvb/audio-select-source.rst
new file mode 100644
index 000000000000..1ce64507de93
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/audio-select-source.rst
@@ -0,0 +1,65 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _AUDIO_SELECT_SOURCE:
+
+===================
+AUDIO_SELECT_SOURCE
+===================
+
+Name
+----
+
+AUDIO_SELECT_SOURCE
+
+.. attention:: This ioctl is deprecated
+
+Synopsis
+--------
+
+.. c:function:: int ioctl(int fd, AUDIO_SELECT_SOURCE, struct audio_stream_source *source)
+    :name: AUDIO_SELECT_SOURCE
+
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+    -
+
+       -  audio_stream_source_t source
+
+       -  Indicates the source that shall be used for the Audio stream.
+
+
+Description
+-----------
+
+This ioctl call informs the audio device which source shall be used for
+the input data. The possible sources are demux or memory. If
+AUDIO_SOURCE_MEMORY is selected, the data is fed to the Audio Device
+through the write command.
+
+
+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/userspace-api/media/dvb/audio-set-av-sync.rst b/Documentation/userspace-api/media/dvb/audio-set-av-sync.rst
new file mode 100644
index 000000000000..3a0400dcfae4
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/audio-set-av-sync.rst
@@ -0,0 +1,67 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _AUDIO_SET_AV_SYNC:
+
+=================
+AUDIO_SET_AV_SYNC
+=================
+
+Name
+----
+
+AUDIO_SET_AV_SYNC
+
+.. attention:: This ioctl is deprecated
+
+Synopsis
+--------
+
+.. c:function:: int  ioctl(int fd, AUDIO_SET_AV_SYNC, boolean state)
+    :name: AUDIO_SET_AV_SYNC
+
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+    -
+
+       -  boolean state
+
+       -  Tells the Digital TV subsystem if A/V synchronization shall be ON or OFF.
+
+          TRUE: AV-sync ON
+
+          FALSE: AV-sync OFF
+
+
+Description
+-----------
+
+This ioctl call asks the Audio Device to turn ON or OFF A/V
+synchronization.
+
+
+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/userspace-api/media/dvb/audio-set-bypass-mode.rst b/Documentation/userspace-api/media/dvb/audio-set-bypass-mode.rst
new file mode 100644
index 000000000000..0d2f23cc2f16
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/audio-set-bypass-mode.rst
@@ -0,0 +1,70 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _AUDIO_SET_BYPASS_MODE:
+
+=====================
+AUDIO_SET_BYPASS_MODE
+=====================
+
+Name
+----
+
+AUDIO_SET_BYPASS_MODE
+
+.. attention:: This ioctl is deprecated
+
+Synopsis
+--------
+
+.. c:function:: int ioctl(int fd, AUDIO_SET_BYPASS_MODE, boolean mode)
+    :name: AUDIO_SET_BYPASS_MODE
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+    -
+
+       -  boolean mode
+
+       -  Enables or disables the decoding of the current Audio stream in
+	  the Digital TV subsystem.
+
+          TRUE: Bypass is disabled
+
+          FALSE: Bypass is enabled
+
+
+Description
+-----------
+
+This ioctl call asks the Audio Device to bypass the Audio decoder and
+forward the stream without decoding. This mode shall be used if streams
+that can’t be handled by the Digital TV system shall be decoded. Dolby
+DigitalTM streams are automatically forwarded by the Digital TV subsystem if
+the hardware can handle it.
+
+
+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/userspace-api/media/dvb/audio-set-id.rst b/Documentation/userspace-api/media/dvb/audio-set-id.rst
new file mode 100644
index 000000000000..83fc1217fda0
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/audio-set-id.rst
@@ -0,0 +1,67 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _AUDIO_SET_ID:
+
+============
+AUDIO_SET_ID
+============
+
+Name
+----
+
+AUDIO_SET_ID
+
+.. attention:: This ioctl is deprecated
+
+Synopsis
+--------
+
+.. c:function:: int  ioctl(int fd, AUDIO_SET_ID, int id)
+    :name: AUDIO_SET_ID
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+    -
+
+       -  int id
+
+       -  audio sub-stream id
+
+
+Description
+-----------
+
+This ioctl selects which sub-stream is to be decoded if a program or
+system stream is sent to the video device. If no audio stream type is
+set the id has to be in [0xC0,0xDF] for MPEG sound, in [0x80,0x87] for
+AC3 and in [0xA0,0xA7] for LPCM. More specifications may follow for
+other stream types. If the stream type is set the id just specifies the
+substream id of the audio stream and only the first 5 bits are
+recognized.
+
+
+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/userspace-api/media/dvb/audio-set-mixer.rst b/Documentation/userspace-api/media/dvb/audio-set-mixer.rst
new file mode 100644
index 000000000000..52bfc3af79dc
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/audio-set-mixer.rst
@@ -0,0 +1,61 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _AUDIO_SET_MIXER:
+
+===============
+AUDIO_SET_MIXER
+===============
+
+Name
+----
+
+AUDIO_SET_MIXER
+
+.. attention:: This ioctl is deprecated
+
+Synopsis
+--------
+
+.. c:function:: int ioctl(int fd, AUDIO_SET_MIXER, struct audio_mixer *mix)
+    :name: AUDIO_SET_MIXER
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+    -
+
+       -  audio_mixer_t \*mix
+
+       -  mixer settings.
+
+
+Description
+-----------
+
+This ioctl lets you adjust the mixer settings of the audio decoder.
+
+
+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/userspace-api/media/dvb/audio-set-mute.rst b/Documentation/userspace-api/media/dvb/audio-set-mute.rst
new file mode 100644
index 000000000000..8f3a8332cebc
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/audio-set-mute.rst
@@ -0,0 +1,71 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _AUDIO_SET_MUTE:
+
+==============
+AUDIO_SET_MUTE
+==============
+
+Name
+----
+
+AUDIO_SET_MUTE
+
+.. attention:: This ioctl is deprecated
+
+Synopsis
+--------
+
+.. c:function:: int  ioctl(int fd, AUDIO_SET_MUTE, boolean state)
+    :name: AUDIO_SET_MUTE
+
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+    -
+
+       -  boolean state
+
+       -  Indicates if audio device shall mute or not.
+
+          TRUE: Audio Mute
+
+          FALSE: Audio Un-mute
+
+
+Description
+-----------
+
+This ioctl is for Digital TV devices only. To control a V4L2 decoder use the
+V4L2 :ref:`VIDIOC_DECODER_CMD` with the
+``V4L2_DEC_CMD_START_MUTE_AUDIO`` flag instead.
+
+This ioctl call asks the audio device to mute the stream that is
+currently being played.
+
+
+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/userspace-api/media/dvb/audio-set-streamtype.rst b/Documentation/userspace-api/media/dvb/audio-set-streamtype.rst
new file mode 100644
index 000000000000..c22bd247f03d
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/audio-set-streamtype.rst
@@ -0,0 +1,77 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _AUDIO_SET_STREAMTYPE:
+
+====================
+AUDIO_SET_STREAMTYPE
+====================
+
+Name
+----
+
+AUDIO_SET_STREAMTYPE
+
+.. attention:: This ioctl is deprecated
+
+Synopsis
+--------
+
+.. c:function:: int  ioctl(fd, AUDIO_SET_STREAMTYPE, int type)
+    :name: AUDIO_SET_STREAMTYPE
+
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+    -
+
+       -  int type
+
+       -  stream type
+
+
+Description
+-----------
+
+This ioctl tells the driver which kind of audio stream to expect. This
+is useful if the stream offers several audio sub-streams like LPCM and
+AC3.
+
+
+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.
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  ``EINVAL``
+
+       -  type is not a valid or supported stream type.
diff --git a/Documentation/userspace-api/media/dvb/audio-stop.rst b/Documentation/userspace-api/media/dvb/audio-stop.rst
new file mode 100644
index 000000000000..291b6a42efac
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/audio-stop.rst
@@ -0,0 +1,56 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _AUDIO_STOP:
+
+==========
+AUDIO_STOP
+==========
+
+Name
+----
+
+AUDIO_STOP
+
+.. attention:: This ioctl is deprecated
+
+Synopsis
+--------
+
+.. c:function:: int ioctl(int fd, AUDIO_STOP)
+    :name: AUDIO_STOP
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+
+Description
+-----------
+
+This ioctl call asks the Audio Device to stop playing the current
+stream.
+
+
+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/userspace-api/media/dvb/audio.rst b/Documentation/userspace-api/media/dvb/audio.rst
new file mode 100644
index 000000000000..e137c151335d
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/audio.rst
@@ -0,0 +1,34 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _dvb_audio:
+
+#######################
+Digital TV Audio Device
+#######################
+
+The Digital TV audio device controls the MPEG2 audio decoder of the Digital
+TV hardware. It can be accessed through ``/dev/dvb/adapter?/audio?``. Data
+types and and ioctl definitions can be accessed by including
+``linux/dvb/audio.h`` in your application.
+
+Please note that some Digital TV cards don’t have their own MPEG decoder, which
+results in the omission of the audio and video device.
+
+These ioctls were also used by V4L2 to control MPEG decoders implemented
+in V4L2. The use of these ioctls for that purpose has been made obsolete
+and proper V4L2 ioctls or controls have been created to replace that
+functionality.
+
+
+.. toctree::
+    :maxdepth: 1
+
+    audio_data_types
+    audio_function_calls
diff --git a/Documentation/userspace-api/media/dvb/audio_data_types.rst b/Documentation/userspace-api/media/dvb/audio_data_types.rst
new file mode 100644
index 000000000000..effe265b12d5
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/audio_data_types.rst
@@ -0,0 +1,123 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _audio_data_types:
+
+****************
+Audio Data Types
+****************
+
+This section describes the structures, data types and defines used when
+talking to the audio device.
+
+.. c:type:: audio_stream_source
+
+The audio stream source is set through the AUDIO_SELECT_SOURCE call
+and can take the following values, depending on whether we are replaying
+from an internal (demux) or external (user write) source.
+
+
+.. code-block:: c
+
+    typedef enum {
+	AUDIO_SOURCE_DEMUX,
+	AUDIO_SOURCE_MEMORY
+    } audio_stream_source_t;
+
+AUDIO_SOURCE_DEMUX selects the demultiplexer (fed either by the
+frontend or the DVR device) as the source of the video stream. If
+AUDIO_SOURCE_MEMORY is selected the stream comes from the application
+through the ``write()`` system call.
+
+
+.. c:type:: audio_play_state
+
+The following values can be returned by the AUDIO_GET_STATUS call
+representing the state of audio playback.
+
+
+.. code-block:: c
+
+    typedef enum {
+	AUDIO_STOPPED,
+	AUDIO_PLAYING,
+	AUDIO_PAUSED
+    } audio_play_state_t;
+
+
+.. c:type:: audio_channel_select
+
+The audio channel selected via AUDIO_CHANNEL_SELECT is determined by
+the following values.
+
+
+.. code-block:: c
+
+    typedef enum {
+	AUDIO_STEREO,
+	AUDIO_MONO_LEFT,
+	AUDIO_MONO_RIGHT,
+	AUDIO_MONO,
+	AUDIO_STEREO_SWAPPED
+    } audio_channel_select_t;
+
+
+.. c:type:: audio_status
+
+The AUDIO_GET_STATUS call returns the following structure informing
+about various states of the playback operation.
+
+
+.. code-block:: c
+
+    typedef struct audio_status {
+	boolean AV_sync_state;
+	boolean mute_state;
+	audio_play_state_t play_state;
+	audio_stream_source_t stream_source;
+	audio_channel_select_t channel_select;
+	boolean bypass_mode;
+	audio_mixer_t mixer_state;
+    } audio_status_t;
+
+
+.. c:type:: audio_mixer
+
+The following structure is used by the AUDIO_SET_MIXER call to set the
+audio volume.
+
+
+.. code-block:: c
+
+    typedef struct audio_mixer {
+	unsigned int volume_left;
+	unsigned int volume_right;
+    } audio_mixer_t;
+
+
+.. _audio_encodings:
+
+audio encodings
+===============
+
+A call to AUDIO_GET_CAPABILITIES returns an unsigned integer with the
+following bits set according to the hardwares capabilities.
+
+
+.. code-block:: c
+
+     #define AUDIO_CAP_DTS    1
+     #define AUDIO_CAP_LPCM   2
+     #define AUDIO_CAP_MP1    4
+     #define AUDIO_CAP_MP2    8
+     #define AUDIO_CAP_MP3   16
+     #define AUDIO_CAP_AAC   32
+     #define AUDIO_CAP_OGG   64
+     #define AUDIO_CAP_SDDS 128
+     #define AUDIO_CAP_AC3  256
diff --git a/Documentation/userspace-api/media/dvb/audio_function_calls.rst b/Documentation/userspace-api/media/dvb/audio_function_calls.rst
new file mode 100644
index 000000000000..be90a828fe29
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/audio_function_calls.rst
@@ -0,0 +1,37 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _audio_function_calls:
+
+********************
+Audio Function Calls
+********************
+
+.. toctree::
+    :maxdepth: 1
+
+    audio-fopen
+    audio-fclose
+    audio-fwrite
+    audio-stop
+    audio-play
+    audio-pause
+    audio-continue
+    audio-select-source
+    audio-set-mute
+    audio-set-av-sync
+    audio-set-bypass-mode
+    audio-channel-select
+    audio-bilingual-channel-select
+    audio-get-status
+    audio-get-capabilities
+    audio-clear-buffer
+    audio-set-id
+    audio-set-mixer
+    audio-set-streamtype
diff --git a/Documentation/userspace-api/media/dvb/ca-fclose.rst b/Documentation/userspace-api/media/dvb/ca-fclose.rst
new file mode 100644
index 000000000000..cedfb7ee6a01
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/ca-fclose.rst
@@ -0,0 +1,50 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _ca_fclose:
+
+=====================
+Digital TV CA close()
+=====================
+
+Name
+----
+
+Digital TV CA close()
+
+
+Synopsis
+--------
+
+.. c:function:: int close(int fd)
+    :name: dvb-ca-close
+
+
+Arguments
+---------
+
+``fd``
+  File descriptor returned by a previous call to :c:func:`open() <dvb-ca-open>`.
+
+Description
+-----------
+
+This system call closes a previously opened CA device.
+
+
+Return Value
+------------
+
+On success 0 is returned.
+
+On error -1 is returned, and the ``errno`` variable is set
+appropriately.
+
+Generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/userspace-api/media/dvb/ca-fopen.rst b/Documentation/userspace-api/media/dvb/ca-fopen.rst
new file mode 100644
index 000000000000..aa0fde1739a8
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/ca-fopen.rst
@@ -0,0 +1,84 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _ca_fopen:
+
+====================
+Digital TV CA open()
+====================
+
+Name
+----
+
+Digital TV CA open()
+
+
+Synopsis
+--------
+
+.. c:function:: int open(const char *name, int flags)
+    :name: dvb-ca-open
+
+
+Arguments
+---------
+
+``name``
+  Name of specific Digital TV CA device.
+
+``flags``
+  A bit-wise OR of the following flags:
+
+.. tabularcolumns:: |p{2.5cm}|p{15.0cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths: 1 16
+
+    -  - ``O_RDONLY``
+       - read-only access
+
+    -  - ``O_RDWR``
+       - read/write access
+
+    -  - ``O_NONBLOCK``
+       - open in non-blocking mode
+         (blocking mode is the default)
+
+
+Description
+-----------
+
+This system call opens a named ca device (e.g. ``/dev/dvb/adapter?/ca?``)
+for subsequent use.
+
+When an ``open()`` call has succeeded, the device will be ready for use. The
+significance of blocking or non-blocking mode is described in the
+documentation for functions where there is a difference. It does not
+affect the semantics of the ``open()`` call itself. A device opened in
+blocking mode can later be put into non-blocking mode (and vice versa)
+using the ``F_SETFL`` command of the ``fcntl`` system call. This is a
+standard system call, documented in the Linux manual page for fcntl.
+Only one user can open the CA Device in ``O_RDWR`` mode. All other
+attempts to open the device in this mode will fail, and an error code
+will be returned.
+
+
+Return Value
+------------
+
+
+On success 0 is returned.
+
+On error -1 is returned, and the ``errno`` variable is set
+appropriately.
+
+Generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/userspace-api/media/dvb/ca-get-cap.rst b/Documentation/userspace-api/media/dvb/ca-get-cap.rst
new file mode 100644
index 000000000000..b808d0592371
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/ca-get-cap.rst
@@ -0,0 +1,53 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _CA_GET_CAP:
+
+==========
+CA_GET_CAP
+==========
+
+Name
+----
+
+CA_GET_CAP
+
+
+Synopsis
+--------
+
+.. c:function:: int ioctl(fd, CA_GET_CAP, struct ca_caps *caps)
+    :name: CA_GET_CAP
+
+
+Arguments
+---------
+
+``fd``
+  File descriptor returned by a previous call to :c:func:`open() <dvb-ca-open>`.
+
+``caps``
+  Pointer to struct :c:type:`ca_caps`.
+
+Description
+-----------
+
+Queries the Kernel for information about the available CA and descrambler
+slots, and their types.
+
+Return Value
+------------
+
+On success 0 is returned and :c:type:`ca_caps` is filled.
+
+On error, -1 is returned 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/userspace-api/media/dvb/ca-get-descr-info.rst b/Documentation/userspace-api/media/dvb/ca-get-descr-info.rst
new file mode 100644
index 000000000000..396cc66a8243
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/ca-get-descr-info.rst
@@ -0,0 +1,49 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _CA_GET_DESCR_INFO:
+
+=================
+CA_GET_DESCR_INFO
+=================
+
+Name
+----
+
+CA_GET_DESCR_INFO
+
+
+Synopsis
+--------
+
+.. c:function:: int  ioctl(fd, CA_GET_DESCR_INFO, struct ca_descr_info *desc)
+    :name: CA_GET_DESCR_INFO
+
+Arguments
+---------
+
+``fd``
+  File descriptor returned by a previous call to :c:func:`open() <dvb-ca-open>`.
+
+``desc``
+  Pointer to struct :c:type:`ca_descr_info`.
+
+Description
+-----------
+
+Returns information about all descrambler slots.
+
+Return Value
+------------
+
+On success 0 is returned, and :c:type:`ca_descr_info` is filled.
+
+On error -1 is returned, 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/userspace-api/media/dvb/ca-get-msg.rst b/Documentation/userspace-api/media/dvb/ca-get-msg.rst
new file mode 100644
index 000000000000..995f461d6879
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/ca-get-msg.rst
@@ -0,0 +1,59 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _CA_GET_MSG:
+
+==========
+CA_GET_MSG
+==========
+
+Name
+----
+
+CA_GET_MSG
+
+
+Synopsis
+--------
+
+.. c:function:: int ioctl(fd, CA_GET_MSG, struct ca_msg *msg)
+    :name: CA_GET_MSG
+
+
+Arguments
+---------
+
+``fd``
+  File descriptor returned by a previous call to :c:func:`open() <dvb-ca-open>`.
+
+``msg``
+  Pointer to struct :c:type:`ca_msg`.
+
+Description
+-----------
+
+Receives a message via a CI CA module.
+
+.. note::
+
+   Please notice that, on most drivers, this is done by reading from
+   the /dev/adapter?/ca? device node.
+
+
+Return Value
+------------
+
+
+On success 0 is returned.
+
+On error -1 is returned, and the ``errno`` variable is set
+appropriately.
+
+Generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/userspace-api/media/dvb/ca-get-slot-info.rst b/Documentation/userspace-api/media/dvb/ca-get-slot-info.rst
new file mode 100644
index 000000000000..c65987ff9cb3
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/ca-get-slot-info.rst
@@ -0,0 +1,64 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _CA_GET_SLOT_INFO:
+
+================
+CA_GET_SLOT_INFO
+================
+
+Name
+----
+
+CA_GET_SLOT_INFO
+
+
+Synopsis
+--------
+
+.. c:function:: int ioctl(fd, CA_GET_SLOT_INFO, struct ca_slot_info *info)
+    :name: CA_GET_SLOT_INFO
+
+
+Arguments
+---------
+
+``fd``
+  File descriptor returned by a previous call to :c:func:`open() <cec-open>`.
+
+``info``
+  Pointer to struct :c:type:`ca_slot_info`.
+
+Description
+-----------
+
+Returns information about a CA slot identified by
+:c:type:`ca_slot_info`.slot_num.
+
+
+Return Value
+------------
+
+On success 0 is returned, and :c:type:`ca_slot_info` is filled.
+
+On error -1 is returned, and the ``errno`` variable is set
+appropriately.
+
+.. tabularcolumns:: |p{2.5cm}|p{15.0cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths: 1 16
+
+    -  -  ``ENODEV``
+       -  the slot is not available.
+
+The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/userspace-api/media/dvb/ca-reset.rst b/Documentation/userspace-api/media/dvb/ca-reset.rst
new file mode 100644
index 000000000000..116a5a8eeb5d
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/ca-reset.rst
@@ -0,0 +1,51 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _CA_RESET:
+
+========
+CA_RESET
+========
+
+Name
+----
+
+CA_RESET
+
+
+Synopsis
+--------
+
+.. c:function:: int ioctl(fd, CA_RESET)
+    :name: CA_RESET
+
+
+Arguments
+---------
+
+``fd``
+  File descriptor returned by a previous call to :c:func:`open() <cec-open>`.
+
+Description
+-----------
+
+Puts the Conditional Access hardware on its initial state. It should
+be called before start using the CA hardware.
+
+
+Return Value
+------------
+
+On success 0 is returned.
+
+On error -1 is returned, and the ``errno`` variable is set
+appropriately.
+
+Generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/userspace-api/media/dvb/ca-send-msg.rst b/Documentation/userspace-api/media/dvb/ca-send-msg.rst
new file mode 100644
index 000000000000..716d88e0fdc5
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/ca-send-msg.rst
@@ -0,0 +1,58 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _CA_SEND_MSG:
+
+===========
+CA_SEND_MSG
+===========
+
+Name
+----
+
+CA_SEND_MSG
+
+
+Synopsis
+--------
+
+.. c:function:: int ioctl(fd, CA_SEND_MSG, struct ca_msg *msg)
+    :name: CA_SEND_MSG
+
+
+Arguments
+---------
+
+``fd``
+  File descriptor returned by a previous call to :c:func:`open() <cec-open>`.
+
+``msg``
+  Pointer to struct :c:type:`ca_msg`.
+
+
+Description
+-----------
+
+Sends a message via a CI CA module.
+
+.. note::
+
+   Please notice that, on most drivers, this is done by writing
+   to the /dev/adapter?/ca? device node.
+
+Return Value
+------------
+
+On success 0 is returned.
+
+On error -1 is returned, and the ``errno`` variable is set
+appropriately.
+
+Generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/userspace-api/media/dvb/ca-set-descr.rst b/Documentation/userspace-api/media/dvb/ca-set-descr.rst
new file mode 100644
index 000000000000..2c57371675e2
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/ca-set-descr.rst
@@ -0,0 +1,53 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _CA_SET_DESCR:
+
+============
+CA_SET_DESCR
+============
+
+Name
+----
+
+CA_SET_DESCR
+
+
+Synopsis
+--------
+
+.. c:function:: int ioctl(fd, CA_SET_DESCR, struct ca_descr *desc)
+    :name: CA_SET_DESCR
+
+
+Arguments
+---------
+
+``fd``
+  File descriptor returned by a previous call to :c:func:`open() <cec-open>`.
+
+``msg``
+  Pointer to struct :c:type:`ca_descr`.
+
+Description
+-----------
+
+CA_SET_DESCR is used for feeding descrambler CA slots with descrambling
+keys (referred as control words).
+
+Return Value
+------------
+
+On success 0 is returned.
+
+On error -1 is returned, and the ``errno`` variable is set
+appropriately.
+
+Generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/userspace-api/media/dvb/ca.rst b/Documentation/userspace-api/media/dvb/ca.rst
new file mode 100644
index 000000000000..643b7c414943
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/ca.rst
@@ -0,0 +1,32 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _dvb_ca:
+
+####################
+Digital TV CA Device
+####################
+
+The Digital TV CA device controls the conditional access hardware. It
+can be accessed through ``/dev/dvb/adapter?/ca?``. Data types and and ioctl
+definitions can be accessed by including ``linux/dvb/ca.h`` in your
+application.
+
+.. note::
+
+   There are three ioctls at this API that aren't documented:
+   :ref:`CA_GET_MSG`, :ref:`CA_SEND_MSG` and :ref:`CA_SET_DESCR`.
+   Documentation for them are welcome.
+
+.. toctree::
+    :maxdepth: 1
+
+    ca_data_types
+    ca_function_calls
+    ca_high_level
diff --git a/Documentation/userspace-api/media/dvb/ca_data_types.rst b/Documentation/userspace-api/media/dvb/ca_data_types.rst
new file mode 100644
index 000000000000..20e2b552144f
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/ca_data_types.rst
@@ -0,0 +1,16 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _ca_data_types:
+
+*************
+CA Data Types
+*************
+
+.. kernel-doc:: include/uapi/linux/dvb/ca.h
diff --git a/Documentation/userspace-api/media/dvb/ca_function_calls.rst b/Documentation/userspace-api/media/dvb/ca_function_calls.rst
new file mode 100644
index 000000000000..b8aceb1895b6
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/ca_function_calls.rst
@@ -0,0 +1,27 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _ca_function_calls:
+
+*****************
+CA Function Calls
+*****************
+
+.. toctree::
+    :maxdepth: 1
+
+    ca-fopen
+    ca-fclose
+    ca-reset
+    ca-get-cap
+    ca-get-slot-info
+    ca-get-descr-info
+    ca-get-msg
+    ca-send-msg
+    ca-set-descr
diff --git a/Documentation/userspace-api/media/dvb/ca_high_level.rst b/Documentation/userspace-api/media/dvb/ca_high_level.rst
new file mode 100644
index 000000000000..a73f3691c31f
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/ca_high_level.rst
@@ -0,0 +1,157 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+The High level CI API
+=====================
+
+.. note::
+
+   This documentation is outdated.
+
+This document describes the high level CI API as in accordance to the
+Linux DVB API.
+
+
+With the High Level CI approach any new card with almost any random
+architecture can be implemented with this style, the definitions
+inside the switch statement can be easily adapted for any card, thereby
+eliminating the need for any additional ioctls.
+
+The disadvantage is that the driver/hardware has to manage the rest. For
+the application programmer it would be as simple as sending/receiving an
+array to/from the CI ioctls as defined in the Linux DVB API. No changes
+have been made in the API to accommodate this feature.
+
+
+Why the need for another CI interface?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This is one of the most commonly asked question. Well a nice question.
+Strictly speaking this is not a new interface.
+
+The CI interface is defined in the DVB API in ca.h as:
+
+.. code-block:: c
+
+	typedef struct ca_slot_info {
+		int num;               /* slot number */
+
+		int type;              /* CA interface this slot supports */
+	#define CA_CI            1     /* CI high level interface */
+	#define CA_CI_LINK       2     /* CI link layer level interface */
+	#define CA_CI_PHYS       4     /* CI physical layer level interface */
+	#define CA_DESCR         8     /* built-in descrambler */
+	#define CA_SC          128     /* simple smart card interface */
+
+		unsigned int flags;
+	#define CA_CI_MODULE_PRESENT 1 /* module (or card) inserted */
+	#define CA_CI_MODULE_READY   2
+	} ca_slot_info_t;
+
+This CI interface follows the CI high level interface, which is not
+implemented by most applications. Hence this area is revisited.
+
+This CI interface is quite different in the case that it tries to
+accommodate all other CI based devices, that fall into the other categories.
+
+This means that this CI interface handles the EN50221 style tags in the
+Application layer only and no session management is taken care of by the
+application. The driver/hardware will take care of all that.
+
+This interface is purely an EN50221 interface exchanging APDU's. This
+means that no session management, link layer or a transport layer do
+exist in this case in the application to driver communication. It is
+as simple as that. The driver/hardware has to take care of that.
+
+With this High Level CI interface, the interface can be defined with the
+regular ioctls.
+
+All these ioctls are also valid for the High level CI interface
+
+#define CA_RESET          _IO('o', 128)
+#define CA_GET_CAP        _IOR('o', 129, ca_caps_t)
+#define CA_GET_SLOT_INFO  _IOR('o', 130, ca_slot_info_t)
+#define CA_GET_DESCR_INFO _IOR('o', 131, ca_descr_info_t)
+#define CA_GET_MSG        _IOR('o', 132, ca_msg_t)
+#define CA_SEND_MSG       _IOW('o', 133, ca_msg_t)
+#define CA_SET_DESCR      _IOW('o', 134, ca_descr_t)
+
+
+On querying the device, the device yields information thus:
+
+.. code-block:: none
+
+	CA_GET_SLOT_INFO
+	----------------------------
+	Command = [info]
+	APP: Number=[1]
+	APP: Type=[1]
+	APP: flags=[1]
+	APP: CI High level interface
+	APP: CA/CI Module Present
+
+	CA_GET_CAP
+	----------------------------
+	Command = [caps]
+	APP: Slots=[1]
+	APP: Type=[1]
+	APP: Descrambler keys=[16]
+	APP: Type=[1]
+
+	CA_SEND_MSG
+	----------------------------
+	Descriptors(Program Level)=[ 09 06 06 04 05 50 ff f1]
+	Found CA descriptor @ program level
+
+	(20) ES type=[2] ES pid=[201]  ES length =[0 (0x0)]
+	(25) ES type=[4] ES pid=[301]  ES length =[0 (0x0)]
+	ca_message length is 25 (0x19) bytes
+	EN50221 CA MSG=[ 9f 80 32 19 03 01 2d d1 f0 08 01 09 06 06 04 05 50 ff f1 02 e0 c9 00 00 04 e1 2d 00 00]
+
+
+Not all ioctl's are implemented in the driver from the API, the other
+features of the hardware that cannot be implemented by the API are achieved
+using the CA_GET_MSG and CA_SEND_MSG ioctls. An EN50221 style wrapper is
+used to exchange the data to maintain compatibility with other hardware.
+
+.. code-block:: c
+
+	/* a message to/from a CI-CAM */
+	typedef struct ca_msg {
+		unsigned int index;
+		unsigned int type;
+		unsigned int length;
+		unsigned char msg[256];
+	} ca_msg_t;
+
+
+The flow of data can be described thus,
+
+.. code-block:: none
+
+	App (User)
+	-----
+	parse
+	  |
+	  |
+	  v
+	en50221 APDU (package)
+   --------------------------------------
+   |	  |				| High Level CI driver
+   |	  |				|
+   |	  v				|
+   |	en50221 APDU (unpackage)	|
+   |	  |				|
+   |	  |				|
+   |	  v				|
+   |	sanity checks			|
+   |	  |				|
+   |	  |				|
+   |	  v				|
+   |	do (H/W dep)			|
+   --------------------------------------
+	  |    Hardware
+	  |
+	  v
+
+The High Level CI interface uses the EN50221 DVB standard, following a
+standard ensures futureproofness.
diff --git a/Documentation/userspace-api/media/dvb/demux.rst b/Documentation/userspace-api/media/dvb/demux.rst
new file mode 100644
index 000000000000..00397b075e0f
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/demux.rst
@@ -0,0 +1,30 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _dvb_demux:
+
+#######################
+Digital TV Demux Device
+#######################
+
+The Digital TV demux device controls the MPEG-TS filters for the
+digital TV. If the driver and hardware supports, those filters are
+implemented at the hardware. Otherwise, the Kernel provides a software
+emulation.
+
+It can be accessed through ``/dev/adapter?/demux?``. Data types and and
+ioctl definitions can be accessed by including ``linux/dvb/dmx.h`` in
+your application.
+
+
+.. toctree::
+    :maxdepth: 1
+
+    dmx_types
+    dmx_fcalls
diff --git a/Documentation/userspace-api/media/dvb/dmx-add-pid.rst b/Documentation/userspace-api/media/dvb/dmx-add-pid.rst
new file mode 100644
index 000000000000..e309cd56fdf0
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/dmx-add-pid.rst
@@ -0,0 +1,56 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _DMX_ADD_PID:
+
+===========
+DMX_ADD_PID
+===========
+
+Name
+----
+
+DMX_ADD_PID
+
+
+Synopsis
+--------
+
+.. c:function:: int ioctl(fd, DMX_ADD_PID, __u16 *pid)
+    :name: DMX_ADD_PID
+
+
+Arguments
+---------
+
+``fd``
+    File descriptor returned by :c:func:`open() <dvb-dmx-open>`.
+
+``pid``
+   PID number to be filtered.
+
+
+Description
+-----------
+
+This ioctl call allows to add multiple PIDs to a transport stream filter
+previously set up with :ref:`DMX_SET_PES_FILTER` and output equal to
+:c:type:`DMX_OUT_TSDEMUX_TAP <dmx_output>`.
+
+
+Return Value
+------------
+
+On success 0 is returned.
+
+On error -1 is returned, and the ``errno`` variable is set
+appropriately.
+
+Generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/userspace-api/media/dvb/dmx-expbuf.rst b/Documentation/userspace-api/media/dvb/dmx-expbuf.rst
new file mode 100644
index 000000000000..f76db8ce3cfa
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/dmx-expbuf.rst
@@ -0,0 +1,97 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _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/userspace-api/media/dvb/dmx-fclose.rst b/Documentation/userspace-api/media/dvb/dmx-fclose.rst
new file mode 100644
index 000000000000..e93bc60da508
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/dmx-fclose.rst
@@ -0,0 +1,52 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _dmx_fclose:
+
+========================
+Digital TV demux close()
+========================
+
+Name
+----
+
+Digital TV demux close()
+
+
+Synopsis
+--------
+
+.. c:function:: int close(int fd)
+    :name: dvb-dmx-close
+
+
+Arguments
+---------
+
+``fd``
+  File descriptor returned by a previous call to
+  :c:func:`open() <dvb-dmx-open>`.
+
+Description
+-----------
+
+This system call deactivates and deallocates a filter that was
+previously allocated via the :c:func:`open() <dvb-dmx-open>` call.
+
+
+Return Value
+------------
+
+On success 0 is returned.
+
+On error, -1 is returned 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/userspace-api/media/dvb/dmx-fopen.rst b/Documentation/userspace-api/media/dvb/dmx-fopen.rst
new file mode 100644
index 000000000000..ea988714558e
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/dmx-fopen.rst
@@ -0,0 +1,98 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _dmx_fopen:
+
+=======================
+Digital TV demux open()
+=======================
+
+Name
+----
+
+Digital TV demux open()
+
+
+Synopsis
+--------
+
+.. c:function:: int open(const char *deviceName, int flags)
+    :name: dvb-dmx-open
+
+Arguments
+---------
+
+``name``
+  Name of specific Digital TV demux device.
+
+``flags``
+  A bit-wise OR of the following flags:
+
+.. tabularcolumns:: |p{2.5cm}|p{15.0cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths: 1 16
+
+    -
+       - ``O_RDONLY``
+       - read-only access
+
+    -
+       - ``O_RDWR``
+       - read/write access
+
+    -
+       - ``O_NONBLOCK``
+       - open in non-blocking mode
+         (blocking mode is the default)
+
+
+Description
+-----------
+
+This system call, used with a device name of ``/dev/dvb/adapter?/demux?``,
+allocates a new filter and returns a handle which can be used for
+subsequent control of that filter. This call has to be made for each
+filter to be used, i.e. every returned file descriptor is a reference to
+a single filter. ``/dev/dvb/adapter?/dvr?`` is a logical device to be used
+for retrieving Transport Streams for digital video recording. When
+reading from this device a transport stream containing the packets from
+all PES filters set in the corresponding demux device
+(``/dev/dvb/adapter?/demux?``) having the output set to ``DMX_OUT_TS_TAP``.
+A recorded Transport Stream is replayed by writing to this device.
+
+The significance of blocking or non-blocking mode is described in the
+documentation for functions where there is a difference. It does not
+affect the semantics of the ``open()`` call itself. A device opened
+in blocking mode can later be put into non-blocking mode (and vice versa)
+using the ``F_SETFL`` command of the fcntl system call.
+
+
+Return Value
+------------
+
+On success 0 is returned.
+
+On error -1 is returned, and the ``errno`` variable is set
+appropriately.
+
+.. tabularcolumns:: |p{2.5cm}|p{15.0cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths: 1 16
+
+    -  -  ``EMFILE``
+       -  “Too many open files”, i.e. no more filters available.
+
+The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/userspace-api/media/dvb/dmx-fread.rst b/Documentation/userspace-api/media/dvb/dmx-fread.rst
new file mode 100644
index 000000000000..25501be818f8
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/dmx-fread.rst
@@ -0,0 +1,87 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _dmx_fread:
+
+=======================
+Digital TV demux read()
+=======================
+
+Name
+----
+
+Digital TV demux read()
+
+
+Synopsis
+--------
+
+.. c:function:: size_t read(int fd, void *buf, size_t count)
+    :name: dvb-dmx-read
+
+Arguments
+---------
+
+``fd``
+  File descriptor returned by a previous call to :c:func:`open() <dvb-ca-open>`.
+
+ ``buf``
+   Buffer to be filled
+
+``count``
+   Max number of bytes to read
+
+Description
+-----------
+
+This system call returns filtered data, which might be section or Packetized
+Elementary Stream (PES) data. The filtered data is transferred from
+the driver’s internal circular buffer to ``buf``. The maximum amount of data
+to be transferred is implied by count.
+
+.. note::
+
+   if a section filter created with
+   :c:type:`DMX_CHECK_CRC <dmx_sct_filter_params>` flag set,
+   data that fails on CRC check will be silently ignored.
+
+
+Return Value
+------------
+
+On success 0 is returned.
+
+On error -1 is returned, and the ``errno`` variable is set
+appropriately.
+
+.. tabularcolumns:: |p{2.5cm}|p{15.0cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths: 1 16
+
+    -  -  ``EWOULDBLOCK``
+       -  No data to return and ``O_NONBLOCK`` was specified.
+
+    -  -  ``EOVERFLOW``
+       -  The filtered data was not read from the buffer in due time,
+	  resulting in non-read data being lost. The buffer is flushed.
+
+    -  -  ``ETIMEDOUT``
+       -  The section was not loaded within the stated timeout period.
+          See ioctl :ref:`DMX_SET_FILTER` for how to set a timeout.
+
+    -  -  ``EFAULT``
+       -  The driver failed to write to the callers buffer due to an
+          invalid \*buf pointer.
+
+
+The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/userspace-api/media/dvb/dmx-fwrite.rst b/Documentation/userspace-api/media/dvb/dmx-fwrite.rst
new file mode 100644
index 000000000000..4400f4ef8c65
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/dmx-fwrite.rst
@@ -0,0 +1,79 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _dmx_fwrite:
+
+========================
+Digital TV demux write()
+========================
+
+Name
+----
+
+Digital TV demux write()
+
+
+Synopsis
+--------
+
+.. c:function:: ssize_t write(int fd, const void *buf, size_t count)
+    :name: dvb-dmx-write
+
+Arguments
+---------
+
+``fd``
+  File descriptor returned by a previous call to :c:func:`open() <dvb-ca-open>`.
+
+``buf``
+     Buffer with data to be written
+
+``count``
+    Number of bytes at the buffer
+
+Description
+-----------
+
+This system call is only provided by the logical device
+``/dev/dvb/adapter?/dvr?``, associated with the physical demux device that
+provides the actual DVR functionality. It is used for replay of a
+digitally recorded Transport Stream. Matching filters have to be defined
+in the corresponding physical demux device, ``/dev/dvb/adapter?/demux?``.
+The amount of data to be transferred is implied by count.
+
+
+Return Value
+------------
+
+On success 0 is returned.
+
+On error -1 is returned, and the ``errno`` variable is set
+appropriately.
+
+.. tabularcolumns:: |p{2.5cm}|p{15.0cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths: 1 16
+
+    -  -  ``EWOULDBLOCK``
+       -  No data was written. This might happen if ``O_NONBLOCK`` was
+	  specified and there is no more buffer space available (if
+	  ``O_NONBLOCK`` is not specified the function will block until buffer
+	  space is available).
+
+    -  -  ``EBUSY``
+       -  This error code indicates that there are conflicting requests. The
+	  corresponding demux device is setup to receive data from the
+	  front- end. Make sure that these filters are stopped and that the
+	  filters with input set to ``DMX_IN_DVR`` are started.
+
+The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/userspace-api/media/dvb/dmx-get-pes-pids.rst b/Documentation/userspace-api/media/dvb/dmx-get-pes-pids.rst
new file mode 100644
index 000000000000..e1873e3fdc01
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/dmx-get-pes-pids.rst
@@ -0,0 +1,71 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _DMX_GET_PES_PIDS:
+
+================
+DMX_GET_PES_PIDS
+================
+
+Name
+----
+
+DMX_GET_PES_PIDS
+
+
+Synopsis
+--------
+
+.. c:function:: int ioctl(fd, DMX_GET_PES_PIDS, __u16 pids[5])
+    :name: DMX_GET_PES_PIDS
+
+Arguments
+---------
+
+``fd``
+    File descriptor returned by :c:func:`open() <dvb-dmx-open>`.
+
+``pids``
+    Array used to store 5 Program IDs.
+
+
+Description
+-----------
+
+This ioctl allows to query a DVB device to return the first PID used
+by audio, video, textext, subtitle and PCR programs on a given service.
+They're stored as:
+
+=======================	========	=======================================
+PID  element		position	content
+=======================	========	=======================================
+pids[DMX_PES_AUDIO]	0		first audio PID
+pids[DMX_PES_VIDEO]	1		first video PID
+pids[DMX_PES_TELETEXT]	2		first teletext PID
+pids[DMX_PES_SUBTITLE]	3		first subtitle PID
+pids[DMX_PES_PCR]	4		first Program Clock Reference PID
+=======================	========	=======================================
+
+
+.. note::
+
+	A value equal to 0xffff means that the PID was not filled by the
+	Kernel.
+
+
+Return Value
+------------
+
+On success 0 is returned.
+
+On error -1 is returned, 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/userspace-api/media/dvb/dmx-get-stc.rst b/Documentation/userspace-api/media/dvb/dmx-get-stc.rst
new file mode 100644
index 000000000000..026a884edb0a
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/dmx-get-stc.rst
@@ -0,0 +1,73 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _DMX_GET_STC:
+
+===========
+DMX_GET_STC
+===========
+
+Name
+----
+
+DMX_GET_STC
+
+
+Synopsis
+--------
+
+.. c:function:: int ioctl( int fd, DMX_GET_STC, struct dmx_stc *stc)
+    :name: DMX_GET_STC
+
+Arguments
+---------
+
+``fd``
+    File descriptor returned by :c:func:`open() <dvb-dmx-open>`.
+
+``stc``
+    Pointer to :c:type:`dmx_stc` where the stc data is to be stored.
+
+
+Description
+-----------
+
+This ioctl call returns the current value of the system time counter
+(which is driven by a PES filter of type :c:type:`DMX_PES_PCR <dmx_ts_pes>`).
+Some hardware supports more than one STC, so you must specify which one by
+setting the :c:type:`num <dmx_stc>` field of stc before the ioctl (range 0...n).
+The result is returned in form of a ratio with a 64 bit numerator
+and a 32 bit denominator, so the real 90kHz STC value is
+``stc->stc / stc->base``.
+
+
+Return Value
+------------
+
+On success 0 is returned.
+
+On error -1 is returned, and the ``errno`` variable is set
+appropriately.
+
+.. tabularcolumns:: |p{2.5cm}|p{15.0cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths: 1 16
+
+    -  .. row 1
+
+       -  ``EINVAL``
+
+       -  Invalid stc number.
+
+
+The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/userspace-api/media/dvb/dmx-mmap.rst b/Documentation/userspace-api/media/dvb/dmx-mmap.rst
new file mode 100644
index 000000000000..828ba9df73e2
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/dmx-mmap.rst
@@ -0,0 +1,125 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _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/userspace-api/media/dvb/dmx-munmap.rst b/Documentation/userspace-api/media/dvb/dmx-munmap.rst
new file mode 100644
index 000000000000..905fdd585a86
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/dmx-munmap.rst
@@ -0,0 +1,63 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _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/userspace-api/media/dvb/dmx-qbuf.rst b/Documentation/userspace-api/media/dvb/dmx-qbuf.rst
new file mode 100644
index 000000000000..2c4657c2c86d
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/dmx-qbuf.rst
@@ -0,0 +1,93 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _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 ``index`` field with the buffer ID to be queued.
+When ``DMX_DQBUF`` is called with a pointer to struct :c:type:`dmx_buffer`,
+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/userspace-api/media/dvb/dmx-querybuf.rst b/Documentation/userspace-api/media/dvb/dmx-querybuf.rst
new file mode 100644
index 000000000000..6e234daf1c44
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/dmx-querybuf.rst
@@ -0,0 +1,72 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _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/userspace-api/media/dvb/dmx-remove-pid.rst b/Documentation/userspace-api/media/dvb/dmx-remove-pid.rst
new file mode 100644
index 000000000000..dee553a48b63
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/dmx-remove-pid.rst
@@ -0,0 +1,57 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _DMX_REMOVE_PID:
+
+==============
+DMX_REMOVE_PID
+==============
+
+Name
+----
+
+DMX_REMOVE_PID
+
+
+Synopsis
+--------
+
+.. c:function:: int ioctl(fd, DMX_REMOVE_PID, __u16 *pid)
+    :name: DMX_REMOVE_PID
+
+
+Arguments
+---------
+
+``fd``
+    File descriptor returned by :c:func:`open() <dvb-dmx-open>`.
+
+``pid``
+    PID of the PES filter to be removed.
+
+
+Description
+-----------
+
+This ioctl call allows to remove a PID when multiple PIDs are set on a
+transport stream filter, e. g. a filter previously set up with output
+equal to :c:type:`DMX_OUT_TSDEMUX_TAP <dmx_output>`, created via either
+:ref:`DMX_SET_PES_FILTER` or :ref:`DMX_ADD_PID`.
+
+
+Return Value
+------------
+
+On success 0 is returned.
+
+On error -1 is returned, 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/userspace-api/media/dvb/dmx-reqbufs.rst b/Documentation/userspace-api/media/dvb/dmx-reqbufs.rst
new file mode 100644
index 000000000000..9b9be45d2b0b
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/dmx-reqbufs.rst
@@ -0,0 +1,83 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _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/userspace-api/media/dvb/dmx-set-buffer-size.rst b/Documentation/userspace-api/media/dvb/dmx-set-buffer-size.rst
new file mode 100644
index 000000000000..7c91da1da4be
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/dmx-set-buffer-size.rst
@@ -0,0 +1,57 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _DMX_SET_BUFFER_SIZE:
+
+===================
+DMX_SET_BUFFER_SIZE
+===================
+
+Name
+----
+
+DMX_SET_BUFFER_SIZE
+
+
+Synopsis
+--------
+
+.. c:function:: int ioctl( int fd, DMX_SET_BUFFER_SIZE, unsigned long size)
+    :name: DMX_SET_BUFFER_SIZE
+
+
+Arguments
+---------
+
+``fd``
+    File descriptor returned by :c:func:`open() <dvb-dmx-open>`.
+
+``size``
+    Unsigned long size
+
+Description
+-----------
+
+This ioctl call is used to set the size of the circular buffer used for
+filtered data. The default size is two maximum sized sections, i.e. if
+this function is not called a buffer size of ``2 * 4096`` bytes will be
+used.
+
+
+Return Value
+------------
+
+
+On success 0 is returned.
+
+On error -1 is returned, 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/userspace-api/media/dvb/dmx-set-filter.rst b/Documentation/userspace-api/media/dvb/dmx-set-filter.rst
new file mode 100644
index 000000000000..cb3333349bd0
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/dmx-set-filter.rst
@@ -0,0 +1,64 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _DMX_SET_FILTER:
+
+==============
+DMX_SET_FILTER
+==============
+
+Name
+----
+
+DMX_SET_FILTER
+
+
+Synopsis
+--------
+
+.. c:function:: int ioctl( int fd, DMX_SET_FILTER, struct dmx_sct_filter_params *params)
+    :name: DMX_SET_FILTER
+
+Arguments
+---------
+
+``fd``
+    File descriptor returned by :c:func:`open() <dvb-dmx-open>`.
+
+``params``
+
+    Pointer to structure containing filter parameters.
+
+
+Description
+-----------
+
+This ioctl call sets up a filter according to the filter and mask
+parameters provided. A timeout may be defined stating number of seconds
+to wait for a section to be loaded. A value of 0 means that no timeout
+should be applied. Finally there is a flag field where it is possible to
+state whether a section should be CRC-checked, whether the filter should
+be a ”one-shot” filter, i.e. if the filtering operation should be
+stopped after the first section is received, and whether the filtering
+operation should be started immediately (without waiting for a
+:ref:`DMX_START` ioctl call). If a filter was previously set-up, this
+filter will be canceled, and the receive buffer will be flushed.
+
+
+Return Value
+------------
+
+
+On success 0 is returned.
+
+On error -1 is returned, 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/userspace-api/media/dvb/dmx-set-pes-filter.rst b/Documentation/userspace-api/media/dvb/dmx-set-pes-filter.rst
new file mode 100644
index 000000000000..26da56947652
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/dmx-set-pes-filter.rst
@@ -0,0 +1,76 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _DMX_SET_PES_FILTER:
+
+==================
+DMX_SET_PES_FILTER
+==================
+
+Name
+----
+
+DMX_SET_PES_FILTER
+
+
+Synopsis
+--------
+
+.. c:function:: int ioctl( int fd, DMX_SET_PES_FILTER, struct dmx_pes_filter_params *params)
+    :name: DMX_SET_PES_FILTER
+
+
+Arguments
+---------
+
+
+``fd``
+    File descriptor returned by :c:func:`open() <dvb-dmx-open>`.
+
+``params``
+    Pointer to structure containing filter parameters.
+
+
+Description
+-----------
+
+This ioctl call sets up a PES filter according to the parameters
+provided. By a PES filter is meant a filter that is based just on the
+packet identifier (PID), i.e. no PES header or payload filtering
+capability is supported.
+
+
+Return Value
+------------
+
+On success 0 is returned.
+
+On error -1 is returned, and the ``errno`` variable is set
+appropriately.
+
+.. tabularcolumns:: |p{2.5cm}|p{15.0cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths: 1 16
+
+
+    -  .. row 1
+
+       -  ``EBUSY``
+
+       -  This error code indicates that there are conflicting requests.
+	  There are active filters filtering data from another input source.
+	  Make sure that these filters are stopped before starting this
+	  filter.
+
+
+The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/userspace-api/media/dvb/dmx-start.rst b/Documentation/userspace-api/media/dvb/dmx-start.rst
new file mode 100644
index 000000000000..a1d35f01fc95
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/dmx-start.rst
@@ -0,0 +1,75 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _DMX_START:
+
+=========
+DMX_START
+=========
+
+Name
+----
+
+DMX_START
+
+
+Synopsis
+--------
+
+.. c:function:: int ioctl( int fd, DMX_START)
+    :name: DMX_START
+
+
+Arguments
+---------
+
+``fd``
+    File descriptor returned by :c:func:`open() <dvb-dmx-open>`.
+
+Description
+-----------
+
+This ioctl call is used to start the actual filtering operation defined
+via the ioctl calls :ref:`DMX_SET_FILTER` or :ref:`DMX_SET_PES_FILTER`.
+
+
+Return Value
+------------
+
+On success 0 is returned.
+
+On error -1 is returned, and the ``errno`` variable is set
+appropriately.
+
+.. tabularcolumns:: |p{2.5cm}|p{15.0cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  ``EINVAL``
+
+       -  Invalid argument, i.e. no filtering parameters provided via the
+	  :ref:`DMX_SET_FILTER` or :ref:`DMX_SET_PES_FILTER` ioctls.
+
+    -  .. row 2
+
+       -  ``EBUSY``
+
+       -  This error code indicates that there are conflicting requests.
+	  There are active filters filtering data from another input source.
+	  Make sure that these filters are stopped before starting this
+	  filter.
+
+
+The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/userspace-api/media/dvb/dmx-stop.rst b/Documentation/userspace-api/media/dvb/dmx-stop.rst
new file mode 100644
index 000000000000..5e6e805010d0
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/dmx-stop.rst
@@ -0,0 +1,52 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _DMX_STOP:
+
+========
+DMX_STOP
+========
+
+Name
+----
+
+DMX_STOP
+
+
+Synopsis
+--------
+
+.. c:function:: int ioctl( int fd, DMX_STOP)
+    :name: DMX_STOP
+
+
+Arguments
+---------
+
+``fd``
+    File descriptor returned by :c:func:`open() <dvb-dmx-open>`.
+
+Description
+-----------
+
+This ioctl call is used to stop the actual filtering operation defined
+via the ioctl calls :ref:`DMX_SET_FILTER` or :ref:`DMX_SET_PES_FILTER` and
+started via the :ref:`DMX_START` command.
+
+
+Return Value
+------------
+
+On success 0 is returned.
+
+On error -1 is returned, 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/userspace-api/media/dvb/dmx_fcalls.rst b/Documentation/userspace-api/media/dvb/dmx_fcalls.rst
new file mode 100644
index 000000000000..04e150f00f84
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/dmx_fcalls.rst
@@ -0,0 +1,37 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _dmx_fcalls:
+
+********************
+Demux Function Calls
+********************
+
+.. toctree::
+    :maxdepth: 1
+
+    dmx-fopen
+    dmx-fclose
+    dmx-fread
+    dmx-fwrite
+    dmx-mmap
+    dmx-munmap
+    dmx-start
+    dmx-stop
+    dmx-set-filter
+    dmx-set-pes-filter
+    dmx-set-buffer-size
+    dmx-get-stc
+    dmx-get-pes-pids
+    dmx-add-pid
+    dmx-remove-pid
+    dmx-reqbufs
+    dmx-querybuf
+    dmx-expbuf
+    dmx-qbuf
diff --git a/Documentation/userspace-api/media/dvb/dmx_types.rst b/Documentation/userspace-api/media/dvb/dmx_types.rst
new file mode 100644
index 000000000000..635b8fd363be
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/dmx_types.rst
@@ -0,0 +1,16 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _dmx_types:
+
+****************
+Demux Data Types
+****************
+
+.. kernel-doc:: include/uapi/linux/dvb/dmx.h
diff --git a/Documentation/userspace-api/media/dvb/dvb-fe-read-status.rst b/Documentation/userspace-api/media/dvb/dvb-fe-read-status.rst
new file mode 100644
index 000000000000..5d6a7735a9d1
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/dvb-fe-read-status.rst
@@ -0,0 +1,32 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _dvb-fe-read-status:
+
+***************************************
+Querying frontend status and statistics
+***************************************
+
+Once :ref:`FE_SET_PROPERTY <FE_GET_PROPERTY>` is called, the
+frontend will run a kernel thread that will periodically check for the
+tuner lock status and provide statistics about the quality of the
+signal.
+
+The information about the frontend tuner locking status can be queried
+using :ref:`FE_READ_STATUS`.
+
+Signal statistics are provided via
+:ref:`FE_GET_PROPERTY`.
+
+.. note::
+
+   Most statistics require the demodulator to be fully locked
+   (e. g. with :c:type:`FE_HAS_LOCK <fe_status>` bit set). See
+   :ref:`Frontend statistics indicators <frontend-stat-properties>` for
+   more details.
diff --git a/Documentation/userspace-api/media/dvb/dvb-frontend-event.rst b/Documentation/userspace-api/media/dvb/dvb-frontend-event.rst
new file mode 100644
index 000000000000..7f5e56cf75cb
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/dvb-frontend-event.rst
@@ -0,0 +1,22 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. c:type:: dvb_frontend_event
+
+***************
+frontend events
+***************
+
+
+.. code-block:: c
+
+     struct dvb_frontend_event {
+	 fe_status_t status;
+	 struct dvb_frontend_parameters parameters;
+     };
diff --git a/Documentation/userspace-api/media/dvb/dvb-frontend-parameters.rst b/Documentation/userspace-api/media/dvb/dvb-frontend-parameters.rst
new file mode 100644
index 000000000000..83b1bcc6ef54
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/dvb-frontend-parameters.rst
@@ -0,0 +1,126 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. c:type:: dvb_frontend_parameters
+
+*******************
+frontend parameters
+*******************
+
+The kind of parameters passed to the frontend device for tuning depend
+on the kind of hardware you are using.
+
+The struct ``dvb_frontend_parameters`` uses a union with specific
+per-system parameters. However, as newer delivery systems required more
+data, the structure size weren't enough to fit, and just extending its
+size would break the existing applications. So, those parameters were
+replaced by the usage of
+:ref:`FE_GET_PROPERTY/FE_SET_PROPERTY <FE_GET_PROPERTY>`
+ioctl's. The new API is flexible enough to add new parameters to
+existing delivery systems, and to add newer delivery systems.
+
+So, newer applications should use
+:ref:`FE_GET_PROPERTY/FE_SET_PROPERTY <FE_GET_PROPERTY>`
+instead, in order to be able to support the newer System Delivery like
+DVB-S2, DVB-T2, DVB-C2, ISDB, etc.
+
+All kinds of parameters are combined as a union in the
+``dvb_frontend_parameters`` structure:
+
+
+.. code-block:: c
+
+    struct dvb_frontend_parameters {
+	uint32_t frequency;     /* (absolute) frequency in Hz for QAM/OFDM */
+		    /* intermediate frequency in kHz for QPSK */
+	fe_spectral_inversion_t inversion;
+	union {
+	    struct dvb_qpsk_parameters qpsk;
+	    struct dvb_qam_parameters  qam;
+	    struct dvb_ofdm_parameters ofdm;
+	    struct dvb_vsb_parameters  vsb;
+	} u;
+    };
+
+In the case of QPSK frontends the ``frequency`` field specifies the
+intermediate frequency, i.e. the offset which is effectively added to
+the local oscillator frequency (LOF) of the LNB. The intermediate
+frequency has to be specified in units of kHz. For QAM and OFDM
+frontends the ``frequency`` specifies the absolute frequency and is
+given in Hz.
+
+
+.. c:type:: dvb_qpsk_parameters
+
+QPSK parameters
+===============
+
+For satellite QPSK frontends you have to use the ``dvb_qpsk_parameters``
+structure:
+
+
+.. code-block:: c
+
+     struct dvb_qpsk_parameters {
+	 uint32_t        symbol_rate;  /* symbol rate in Symbols per second */
+	 fe_code_rate_t  fec_inner;    /* forward error correction (see above) */
+     };
+
+
+.. c:type:: dvb_qam_parameters
+
+QAM parameters
+==============
+
+for cable QAM frontend you use the ``dvb_qam_parameters`` structure:
+
+
+.. code-block:: c
+
+     struct dvb_qam_parameters {
+	 uint32_t         symbol_rate; /* symbol rate in Symbols per second */
+	 fe_code_rate_t   fec_inner;   /* forward error correction (see above) */
+	 fe_modulation_t  modulation;  /* modulation type (see above) */
+     };
+
+
+.. c:type:: dvb_vsb_parameters
+
+VSB parameters
+==============
+
+ATSC frontends are supported by the ``dvb_vsb_parameters`` structure:
+
+
+.. code-block:: c
+
+    struct dvb_vsb_parameters {
+	fe_modulation_t modulation; /* modulation type (see above) */
+    };
+
+
+.. c:type:: dvb_ofdm_parameters
+
+OFDM parameters
+===============
+
+DVB-T frontends are supported by the ``dvb_ofdm_parameters`` structure:
+
+
+.. code-block:: c
+
+     struct dvb_ofdm_parameters {
+	 fe_bandwidth_t      bandwidth;
+	 fe_code_rate_t      code_rate_HP;  /* high priority stream code rate */
+	 fe_code_rate_t      code_rate_LP;  /* low priority stream code rate */
+	 fe_modulation_t     constellation; /* modulation type (see above) */
+	 fe_transmit_mode_t  transmission_mode;
+	 fe_guard_interval_t guard_interval;
+	 fe_hierarchy_t      hierarchy_information;
+     };
diff --git a/Documentation/userspace-api/media/dvb/dvbapi.rst b/Documentation/userspace-api/media/dvb/dvbapi.rst
new file mode 100644
index 000000000000..74b16ab3fd94
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/dvbapi.rst
@@ -0,0 +1,126 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. include:: <isonum.txt>
+
+.. _dvbapi:
+
+########################
+Part II - Digital TV API
+########################
+
+.. note::
+
+   This API is also known as Linux **DVB API**.
+
+   It it was originally written to support the European digital TV
+   standard (DVB), and later extended to support all digital TV standards.
+
+   In order to avoid confusion, within this document, it was opted to refer to
+   it, and to associated hardware as **Digital TV**.
+
+   The word **DVB** is reserved to be used for:
+
+     - the Digital TV API version
+       (e. g. DVB API version 3 or DVB API version 5);
+     - digital TV data types (enums, structs, defines, etc);
+     - digital TV device nodes (``/dev/dvb/...``);
+     - the European DVB standard.
+
+**Version 5.10**
+
+.. only:: html
+
+   .. class:: toc-title
+
+        Table of Contents
+
+.. toctree::
+    :maxdepth: 5
+    :numbered:
+
+    intro
+    frontend
+    demux
+    ca
+    net
+    legacy_dvb_apis
+    examples
+    headers
+
+
+**********************
+Revision and Copyright
+**********************
+
+Authors:
+
+- J. K. Metzler, Ralph <rjkm@metzlerbros.de>
+
+ - Original author of the Digital TV API documentation.
+
+- O. C. Metzler, Marcus <rjkm@metzlerbros.de>
+
+ - Original author of the Digital TV API documentation.
+
+- Carvalho Chehab, Mauro <mchehab+samsung@kernel.org>
+
+ - Ported document to Docbook XML, addition of DVBv5 API, documentation gaps fix.
+
+**Copyright** |copy| 2002-2003 : Convergence GmbH
+
+**Copyright** |copy| 2009-2017 : Mauro Carvalho Chehab
+
+****************
+Revision History
+****************
+
+:revision: 2.2.0 / 2017-09-01 (*mcc*)
+
+Most gaps between the uAPI document and the Kernel implementation
+got fixed for the non-legacy API.
+
+:revision: 2.1.0 / 2015-05-29 (*mcc*)
+
+DocBook improvements and cleanups, in order to document the system calls
+on a more standard way and provide more description about the current
+Digital TV API.
+
+:revision: 2.0.4 / 2011-05-06 (*mcc*)
+
+Add more information about DVBv5 API, better describing the frontend
+GET/SET props ioctl's.
+
+
+:revision: 2.0.3 / 2010-07-03 (*mcc*)
+
+Add some frontend capabilities flags, present on kernel, but missing at
+the specs.
+
+
+:revision: 2.0.2 / 2009-10-25 (*mcc*)
+
+documents FE_SET_FRONTEND_TUNE_MODE and
+FE_DISHETWORK_SEND_LEGACY_CMD ioctls.
+
+
+:revision: 2.0.1 / 2009-09-16 (*mcc*)
+
+Added ISDB-T test originally written by Patrick Boettcher
+
+
+:revision: 2.0.0 / 2009-09-06 (*mcc*)
+
+Conversion from LaTex to DocBook XML. The contents is the same as the
+original LaTex version.
+
+
+:revision: 1.0.0 / 2003-07-24 (*rjkm*)
+
+Initial revision on LaTEX.
diff --git a/Documentation/userspace-api/media/dvb/dvbproperty.rst b/Documentation/userspace-api/media/dvb/dvbproperty.rst
new file mode 100644
index 000000000000..1716733d24ba
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/dvbproperty.rst
@@ -0,0 +1,133 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _frontend-properties:
+
+**************
+Property types
+**************
+
+Tuning into a Digital TV physical channel and starting decoding it
+requires changing a set of parameters, in order to control the tuner,
+the demodulator, the Linear Low-noise Amplifier (LNA) and to set the
+antenna subsystem via Satellite Equipment Control - SEC (on satellite
+systems). The actual parameters are specific to each particular digital
+TV standards, and may change as the digital TV specs evolves.
+
+In the past (up to DVB API version 3 - DVBv3), the strategy used was to have a
+union with the parameters needed to tune for DVB-S, DVB-C, DVB-T and
+ATSC delivery systems grouped there. The problem is that, as the second
+generation standards appeared, the size of such union was not big
+enough to group the structs that would be required for those new
+standards. Also, extending it would break userspace.
+
+So, the legacy union/struct based approach was deprecated, in favor
+of a properties set approach. On such approach,
+:ref:`FE_GET_PROPERTY and FE_SET_PROPERTY <FE_GET_PROPERTY>` are used
+to setup the frontend and read its status.
+
+The actual action is determined by a set of dtv_property cmd/data pairs.
+With one single ioctl, is possible to get/set up to 64 properties.
+
+This section describes the new and recommended way to set the frontend,
+with supports all digital TV delivery systems.
+
+.. note::
+
+   1. On Linux DVB API version 3, setting a frontend was done via
+      struct :c:type:`dvb_frontend_parameters`.
+
+   2. Don't use DVB API version 3 calls on hardware with supports
+      newer standards. Such API provides no support or a very limited
+      support to new standards and/or new hardware.
+
+   3. Nowadays, most frontends support multiple delivery systems.
+      Only with DVB API version 5 calls it is possible to switch between
+      the multiple delivery systems supported by a frontend.
+
+   4. DVB API version 5 is also called *S2API*, as the first
+      new standard added to it was DVB-S2.
+
+**Example**: in order to set the hardware to tune into a DVB-C channel
+at 651 kHz, modulated with 256-QAM, FEC 3/4 and symbol rate of 5.217
+Mbauds, those properties should be sent to
+:ref:`FE_SET_PROPERTY <FE_GET_PROPERTY>` ioctl:
+
+  :ref:`DTV_DELIVERY_SYSTEM <DTV-DELIVERY-SYSTEM>` = SYS_DVBC_ANNEX_A
+
+  :ref:`DTV_FREQUENCY <DTV-FREQUENCY>` = 651000000
+
+  :ref:`DTV_MODULATION <DTV-MODULATION>` = QAM_256
+
+  :ref:`DTV_INVERSION <DTV-INVERSION>` = INVERSION_AUTO
+
+  :ref:`DTV_SYMBOL_RATE <DTV-SYMBOL-RATE>` = 5217000
+
+  :ref:`DTV_INNER_FEC <DTV-INNER-FEC>` = FEC_3_4
+
+  :ref:`DTV_TUNE <DTV-TUNE>`
+
+The code that would that would do the above is show in
+:ref:`dtv-prop-example`.
+
+.. code-block:: c
+    :caption: Example: Setting digital TV frontend properties
+    :name: dtv-prop-example
+
+    #include <stdio.h>
+    #include <fcntl.h>
+    #include <sys/ioctl.h>
+    #include <linux/dvb/frontend.h>
+
+    static struct dtv_property props[] = {
+	{ .cmd = DTV_DELIVERY_SYSTEM, .u.data = SYS_DVBC_ANNEX_A },
+	{ .cmd = DTV_FREQUENCY,       .u.data = 651000000 },
+	{ .cmd = DTV_MODULATION,      .u.data = QAM_256 },
+	{ .cmd = DTV_INVERSION,       .u.data = INVERSION_AUTO },
+	{ .cmd = DTV_SYMBOL_RATE,     .u.data = 5217000 },
+	{ .cmd = DTV_INNER_FEC,       .u.data = FEC_3_4 },
+	{ .cmd = DTV_TUNE }
+    };
+
+    static struct dtv_properties dtv_prop = {
+	.num = 6, .props = props
+    };
+
+    int main(void)
+    {
+	int fd = open("/dev/dvb/adapter0/frontend0", O_RDWR);
+
+	if (!fd) {
+	    perror ("open");
+	    return -1;
+	}
+	if (ioctl(fd, FE_SET_PROPERTY, &dtv_prop) == -1) {
+	    perror("ioctl");
+	    return -1;
+	}
+	printf("Frontend set\\n");
+	return 0;
+    }
+
+.. attention:: While it is possible to directly call the Kernel code like the
+   above example, it is strongly recommended to use
+   `libdvbv5 <https://linuxtv.org/docs/libdvbv5/index.html>`__, as it
+   provides abstraction to work with the supported digital TV standards and
+   provides methods for usual operations like program scanning and to
+   read/write channel descriptor files.
+
+.. toctree::
+    :maxdepth: 1
+
+    fe_property_parameters
+    frontend-stat-properties
+    frontend-property-terrestrial-systems
+    frontend-property-cable-systems
+    frontend-property-satellite-systems
+    frontend-header
diff --git a/Documentation/userspace-api/media/dvb/dvbstb.svg b/Documentation/userspace-api/media/dvb/dvbstb.svg
new file mode 100644
index 000000000000..b333d0ff944f
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/dvbstb.svg
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    This file is dual-licensed: you can use it either under the terms
+    of the GPL 2.0 or the GFDL 1.1+ license, at your option. Note that this
+    dual licensing only applies to this file, and not this project as a
+    whole.
+
+    a) This file is free software; you can redistribute it and/or
+       modify it under the terms of the GNU General Public License as
+       published by the Free Software Foundation version 2 of
+       the License.
+
+       This file is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+    Or, alternatively,
+
+    b) Permission is granted to copy, distribute and/or modify this
+       document under the terms of the GNU Free Documentation License,
+       Version 1.1 or any later version published by the Free Software
+       Foundation, with no Invariant Sections, no Front-Cover Texts
+       and no Back-Cover Texts. A copy of the license is included at
+       Documentation/userspace-api/media/fdl-appendix.rst.
+
+    TODO: replace it to GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
+-->
+<svg id="svg2" width="15.847cm" height="8.4187cm" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" preserveAspectRatio="xMidYMid" version="1.2" viewBox="0 0 23770.123 12628.122" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><defs id="defs142"><marker id="Arrow1Lend" overflow="visible" orient="auto"><path id="path954" transform="matrix(-.8 0 0 -.8 -10 0)" d="m0 0 5-5-17.5 5 17.5 5z" fill-rule="evenodd" stroke="#000" stroke-width="1pt"/></marker><marker id="marker1243" overflow="visible" orient="auto"><path id="path1241" transform="matrix(-.8 0 0 -.8 -10 0)" d="m0 0 5-5-17.5 5 17.5 5z" fill-rule="evenodd" stroke="#000" stroke-width="1pt"/></marker></defs><metadata id="metadata519"><rdf:RDF><cc:Work
+rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title/></cc:Work></rdf:RDF></metadata><rect id="rect197" class="BoundingBox" x="5355.1" y="13.122" width="18403" height="9603" fill="none"/><path id="path199" d="m14556 9614.1h-9200v-9600h18400v9600z" fill="#fff"/><path id="path201" d="m14556 9614.1h-9200v-9600h18400v9600z" fill="none" stroke="#000"/><rect id="rect206" class="BoundingBox" x="13.122" y="4013.1" width="4544" height="2403" fill="none"/><path id="path208" d="m2285.1 6414.1h-2271v-2400h4541v2400z" fill="#fff"/><path id="path210" d="m2285.1 6414.1h-2271v-2400h4541v2400z" fill="none" stroke="#000"/><text id="text212" class="TextShape" x="-2443.8779" y="-4585.8779"><tspan id="tspan214" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan216" class="TextPosition"
+x="1281.1219" y="5435.1221"><tspan id="tspan218" fill="#000000">Antena</tspan></tspan></tspan></text>
+<rect id="rect223" class="BoundingBox" x="6213.1" y="1813.1" width="4544" height="2403" fill="none"/><path id="path225" d="m8485.1 4214.1h-2271v-2400h4541v2400z" fill="#fff"/><path id="path227" d="m8485.1 4214.1h-2271v-2400h4541v2400z" fill="none" stroke="#000"/><text id="text229" class="TextShape" x="-2443.8779" y="-4585.8779"><tspan id="tspan231" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan233" class="TextPosition" x="7217.1221" y="3235.1221"><tspan id="tspan235" fill="#000000">Frontend</tspan></tspan></tspan></text>
+<rect id="rect240" class="BoundingBox" x="12113" y="1813.1" width="4544" height="2403" fill="none"/><path id="path242" d="m14385 4214.1h-2271v-2400h4541v2400z" fill="#fff"/><path id="path244" d="m14385 4214.1h-2271v-2400h4541v2400z" fill="none" stroke="#000"/><text id="text246" class="TextShape" x="-2443.8779" y="-4585.8779"><tspan id="tspan248" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan250" class="TextPosition" x="13944.122" y="3235.1221"><tspan id="tspan252" fill="#000000">CA</tspan></tspan></tspan></text>
+<rect id="rect257" class="BoundingBox" x="18113" y="1813.1" width="4544" height="2403" fill="none"/><path id="path259" d="m20385 4214.1h-2271v-2400h4541v2400z" fill="#fff"/><path id="path261" d="m20385 4214.1h-2271v-2400h4541v2400z" fill="none" stroke="#000"/><text id="text263" class="TextShape" x="-2443.8779" y="-4585.8779"><tspan id="tspan265" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan267" class="TextPosition" x="19384.123" y="3235.1221"><tspan id="tspan269" fill="#000000">Demux</tspan></tspan></tspan></text>
+<rect id="rect274" class="BoundingBox" x="6113.1" y="5813.1" width="4544" height="2403" fill="none"/><path id="path276" d="m8385.1 8214.1h-2271v-2400h4541v2400z" fill="#fff"/><path id="path278" d="m8385.1 8214.1h-2271v-2400h4541v2400z" fill="none" stroke="#000"/><text id="text280" class="TextShape" x="-2443.8779" y="-4585.8779"><tspan id="tspan282" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan284" class="TextPosition" x="7733.1221" y="7235.1221"><tspan id="tspan286" fill="#000000">SEC</tspan></tspan></tspan></text>
+<rect id="rect291" class="BoundingBox" x="12213" y="5813.1" width="4544" height="2403" fill="none"/><path id="path293" d="m14485 8214.1h-2271v-2400h4541v2400z" fill="#fff"/><path id="path295" d="m14485 8214.1h-2271v-2400h4541v2400z" fill="none" stroke="#000" stroke-dasharray="28.22200113,56.44400226" stroke-width="28.222"/><text id="text297" class="TextShape" x="-2443.8779" y="-4903.3779"><tspan id="tspan299" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan301" class="TextPosition" x="13676.122" y="6917.6221"><tspan id="tspan303" fill="#000000">Audio</tspan></tspan></tspan></text>
+<rect id="rect308" class="BoundingBox" x="18113" y="5813.1" width="4544" height="2403" fill="none"/><path id="path310" d="m20385 8214.1h-2271v-2400h4541v2400z" fill="#fff"/><path id="path312" d="m20385 8214.1h-2271v-2400h4541v2400z" fill="none" stroke="#000" stroke-dasharray="28.22200113,56.44400226" stroke-width="28.222"/><text id="text314" class="TextShape" x="-2443.8779" y="-4903.3779"><tspan id="tspan316" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan318" class="TextPosition" x="19583.123" y="6917.6221"><tspan id="tspan320" fill="#000000">Video</tspan></tspan></tspan></text>
+<rect id="rect325" class="BoundingBox" x="15213" y="10213" width="4544" height="2403" fill="none"/><path id="path327" d="m17485 12614h-2271v-2400h4541v2400z" fill="#fff"/><path id="path329" d="m17485 12614h-2271v-2400h4541v2400z" fill="none" stroke="#000" stroke-dasharray="28.22200113,56.44400226" stroke-width="28.222"/><text id="text331" class="TextShape" x="-2443.8779" y="-4585.8779"><tspan id="tspan333" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan335" class="TextPosition" x="17076.123" y="11635.122"><tspan id="tspan337" fill="#000000">TV</tspan></tspan></tspan></text>
+<rect id="rect342" class="BoundingBox" x="4555.1" y="3014.1" width="1661" height="2202" fill="none"/><path id="path344" d="m4556.1 5214.1 1400-1857" fill="none" stroke="#000"/><path id="path346" d="m6215.1 3014.1-391 269 240 181z"/><rect id="rect351" class="BoundingBox" x="4555.1" y="5213.1" width="1561" height="1802" fill="none"/><path id="path353" d="m4556.1 5214.1 1277 1475" fill="none" stroke="#000"/><path id="path355" d="m6115.1 7014.1-181-438-227 196z"/><rect id="rect360" class="BoundingBox" x="10755" y="2864.1" width="1361" height="301" fill="none"/><path id="path362" d="m10756 3014.1h929" fill="none" stroke="#000"/><path id="path364" d="m12115 3014.1-450-150v300z"/><rect id="rect369" class="BoundingBox" x="16655" y="2864.1" width="1461" height="301" fill="none"/><path id="path371" d="m16656 3014.1h1029" fill="none" stroke="#000"/><path id="path373" d="m18115
+3014.1-450-150v300z"/><rect id="rect378" class="BoundingBox" x="20235" y="4213.1" width="301" height="1602" fill="none"/><rect id="rect387" class="BoundingBox" x="17485" y="8213.1" width="2902" height="2002" fill="none"/><path id="path389" d="m20385 8214.1-2546 1756" fill="none" stroke="#000" stroke-dasharray="28.22200113,56.44400226" stroke-width="28.222"/><path id="path391" d="m17485 10214 456-132-171-247z"/><rect id="rect396" class="BoundingBox" x="14484" y="8213.1" width="3002" height="2002" fill="none"/><path id="path398" d="m14485 8214.1 2642 1761" fill="none" stroke="#000" stroke-dasharray="28.22200113,56.44400226" stroke-width="28.222"/><path id="path400" d="m17485 10214-291-374-167 249z"/><rect id="rect405" class="BoundingBox" x="14485" y="4213.1" width="5902" height="1629" fill="none"/><path id="path949" d="m20387 4213.1v1629" fill="none" marker-end="url(#Arrow1Lend)"
+stroke="#000" stroke-dasharray="26.45879596, 52.91759192999999328" stroke-linejoin="miter" stroke-width="26.459"/><path id="path1233" d="m20385 4214.1-3628 1599" fill="none" marker-end="url(#marker1243)" stroke="#000" stroke-dasharray="26.45879596, 52.91759193" stroke-linejoin="miter" stroke-width="26.459"/><text id="text297-3" class="TextShape" x="-2911.9202" y="-4257.2061" font-size="12px" stroke-width="1"><tspan id="tspan299-6" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400" stroke-width="1"><tspan id="tspan301-7" class="TextPosition" x="13208.079" y="7563.793" stroke-width="1"><tspan id="tspan303-5" fill="#000000" stroke-width="1">Decoder</tspan></tspan></tspan></text>
+<text id="text297-3-3" class="TextShape" x="2950.9287" y="-4259.5928" font-size="12px" stroke-width="1"><tspan id="tspan299-6-5" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400" stroke-width="1"><tspan id="tspan301-7-6" class="TextPosition" x="19070.928" y="7561.4053" stroke-width="1"><tspan id="tspan303-5-2" fill="#000000" stroke-width="1">Decoder</tspan></tspan></tspan></text>
+</svg>
diff --git a/Documentation/userspace-api/media/dvb/examples.rst b/Documentation/userspace-api/media/dvb/examples.rst
new file mode 100644
index 000000000000..bd0adde86b96
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/examples.rst
@@ -0,0 +1,23 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _dvb_examples:
+
+********
+Examples
+********
+
+In the past, we used to have a set of examples here. However, those
+examples got out of date and doesn't even compile nowadays.
+
+Also, nowadays, the best is to use the libdvbv5 DVB API nowadays,
+with is fully documented.
+
+Please refer to the `libdvbv5 <https://linuxtv.org/docs/libdvbv5/index.html>`__
+for updated/recommended examples.
diff --git a/Documentation/userspace-api/media/dvb/fe-bandwidth-t.rst b/Documentation/userspace-api/media/dvb/fe-bandwidth-t.rst
new file mode 100644
index 000000000000..6293287af67c
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/fe-bandwidth-t.rst
@@ -0,0 +1,81 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+******************
+Frontend bandwidth
+******************
+
+.. c:type:: fe_bandwidth
+
+.. flat-table:: enum fe_bandwidth
+    :header-rows:  1
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  ID
+
+       -  Description
+
+    -  .. row 2
+
+       -  .. _BANDWIDTH-AUTO:
+
+	  ``BANDWIDTH_AUTO``
+
+       -  Autodetect bandwidth (if supported)
+
+    -  .. row 3
+
+       -  .. _BANDWIDTH-1-712-MHZ:
+
+	  ``BANDWIDTH_1_712_MHZ``
+
+       -  1.712 MHz
+
+    -  .. row 4
+
+       -  .. _BANDWIDTH-5-MHZ:
+
+	  ``BANDWIDTH_5_MHZ``
+
+       -  5 MHz
+
+    -  .. row 5
+
+       -  .. _BANDWIDTH-6-MHZ:
+
+	  ``BANDWIDTH_6_MHZ``
+
+       -  6 MHz
+
+    -  .. row 6
+
+       -  .. _BANDWIDTH-7-MHZ:
+
+	  ``BANDWIDTH_7_MHZ``
+
+       -  7 MHz
+
+    -  .. row 7
+
+       -  .. _BANDWIDTH-8-MHZ:
+
+	  ``BANDWIDTH_8_MHZ``
+
+       -  8 MHz
+
+    -  .. row 8
+
+       -  .. _BANDWIDTH-10-MHZ:
+
+	  ``BANDWIDTH_10_MHZ``
+
+       -  10 MHz
diff --git a/Documentation/userspace-api/media/dvb/fe-diseqc-recv-slave-reply.rst b/Documentation/userspace-api/media/dvb/fe-diseqc-recv-slave-reply.rst
new file mode 100644
index 000000000000..b520974e8c46
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/fe-diseqc-recv-slave-reply.rst
@@ -0,0 +1,55 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _FE_DISEQC_RECV_SLAVE_REPLY:
+
+********************************
+ioctl FE_DISEQC_RECV_SLAVE_REPLY
+********************************
+
+Name
+====
+
+FE_DISEQC_RECV_SLAVE_REPLY - Receives reply from a DiSEqC 2.0 command
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, FE_DISEQC_RECV_SLAVE_REPLY, struct dvb_diseqc_slave_reply *argp )
+    :name: FE_DISEQC_RECV_SLAVE_REPLY
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <frontend_f_open>`.
+
+``argp``
+    pointer to struct :c:type:`dvb_diseqc_slave_reply`.
+
+
+Description
+===========
+
+Receives reply from a DiSEqC 2.0 command.
+
+The received message is stored at the buffer pointed by ``argp``.
+
+Return Value
+============
+
+On success 0 is returned.
+
+On error -1 is returned, and the ``errno`` variable is set
+appropriately.
+
+Generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/userspace-api/media/dvb/fe-diseqc-reset-overload.rst b/Documentation/userspace-api/media/dvb/fe-diseqc-reset-overload.rst
new file mode 100644
index 000000000000..c59af46b8e87
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/fe-diseqc-reset-overload.rst
@@ -0,0 +1,53 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _FE_DISEQC_RESET_OVERLOAD:
+
+******************************
+ioctl FE_DISEQC_RESET_OVERLOAD
+******************************
+
+Name
+====
+
+FE_DISEQC_RESET_OVERLOAD - Restores the power to the antenna subsystem, if it was powered off due - to power overload.
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, FE_DISEQC_RESET_OVERLOAD, NULL )
+    :name: FE_DISEQC_RESET_OVERLOAD
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <frontend_f_open>`.
+
+Description
+===========
+
+If the bus has been automatically powered off due to power overload,
+this ioctl call restores the power to the bus. The call requires
+read/write access to the device. This call has no effect if the device
+is manually powered off. Not all Digital TV adapters support this ioctl.
+
+
+Return Value
+============
+
+On success 0 is returned.
+
+On error -1 is returned, and the ``errno`` variable is set
+appropriately.
+
+Generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/userspace-api/media/dvb/fe-diseqc-send-burst.rst b/Documentation/userspace-api/media/dvb/fe-diseqc-send-burst.rst
new file mode 100644
index 000000000000..19b51d0550f7
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/fe-diseqc-send-burst.rst
@@ -0,0 +1,59 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _FE_DISEQC_SEND_BURST:
+
+**************************
+ioctl FE_DISEQC_SEND_BURST
+**************************
+
+Name
+====
+
+FE_DISEQC_SEND_BURST - Sends a 22KHz tone burst for 2x1 mini DiSEqC satellite selection.
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, FE_DISEQC_SEND_BURST, enum fe_sec_mini_cmd tone )
+    :name: FE_DISEQC_SEND_BURST
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <frontend_f_open>`.
+
+``tone``
+    An integer enumered value described at :c:type:`fe_sec_mini_cmd`.
+
+
+Description
+===========
+
+This ioctl is used to set the generation of a 22kHz tone burst for mini
+DiSEqC satellite selection for 2x1 switches. This call requires
+read/write permissions.
+
+It provides support for what's specified at
+`Digital Satellite Equipment Control (DiSEqC) - Simple "ToneBurst" Detection Circuit specification. <http://www.eutelsat.com/files/contributed/satellites/pdf/Diseqc/associated%20docs/simple_tone_burst_detec.pdf>`__
+
+
+Return Value
+============
+
+On success 0 is returned.
+
+On error -1 is returned, and the ``errno`` variable is set
+appropriately.
+
+Generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/userspace-api/media/dvb/fe-diseqc-send-master-cmd.rst b/Documentation/userspace-api/media/dvb/fe-diseqc-send-master-cmd.rst
new file mode 100644
index 000000000000..f75513d018c8
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/fe-diseqc-send-master-cmd.rst
@@ -0,0 +1,56 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _FE_DISEQC_SEND_MASTER_CMD:
+
+*******************************
+ioctl FE_DISEQC_SEND_MASTER_CMD
+*******************************
+
+Name
+====
+
+FE_DISEQC_SEND_MASTER_CMD - Sends a DiSEqC command
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, FE_DISEQC_SEND_MASTER_CMD, struct dvb_diseqc_master_cmd *argp )
+    :name: FE_DISEQC_SEND_MASTER_CMD
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <frontend_f_open>`.
+
+``argp``
+    pointer to struct
+    :c:type:`dvb_diseqc_master_cmd`
+
+
+Description
+===========
+
+Sends the DiSEqC command pointed by :c:type:`dvb_diseqc_master_cmd`
+to the antenna subsystem.
+
+Return Value
+============
+
+On success 0 is returned.
+
+On error -1 is returned, and the ``errno`` variable is set
+appropriately.
+
+Generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
diff --git a/Documentation/userspace-api/media/dvb/fe-dishnetwork-send-legacy-cmd.rst b/Documentation/userspace-api/media/dvb/fe-dishnetwork-send-legacy-cmd.rst
new file mode 100644
index 000000000000..ea66f72fe5f8
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/fe-dishnetwork-send-legacy-cmd.rst
@@ -0,0 +1,62 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _FE_DISHNETWORK_SEND_LEGACY_CMD:
+
+******************************
+FE_DISHNETWORK_SEND_LEGACY_CMD
+******************************
+
+Name
+====
+
+FE_DISHNETWORK_SEND_LEGACY_CMD
+
+
+Synopsis
+========
+
+.. c:function:: int  ioctl(int fd, FE_DISHNETWORK_SEND_LEGACY_CMD, unsigned long cmd)
+    :name: FE_DISHNETWORK_SEND_LEGACY_CMD
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :c:func:`open() <dvb-fe-open>`.
+
+``cmd``
+    Sends the specified raw cmd to the dish via DISEqC.
+
+
+Description
+===========
+
+.. warning::
+   This is a very obscure legacy command, used only at stv0299
+   driver. Should not be used on newer drivers.
+
+It provides a non-standard method for selecting Diseqc voltage on the
+frontend, for Dish Network legacy switches.
+
+As support for this ioctl were added in 2004, this means that such
+dishes were already legacy in 2004.
+
+
+Return Value
+============
+
+On success 0 is returned.
+
+On error -1 is returned, and the ``errno`` variable is set
+appropriately.
+
+Generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/userspace-api/media/dvb/fe-enable-high-lnb-voltage.rst b/Documentation/userspace-api/media/dvb/fe-enable-high-lnb-voltage.rst
new file mode 100644
index 000000000000..9bdf1e898ddc
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/fe-enable-high-lnb-voltage.rst
@@ -0,0 +1,61 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _FE_ENABLE_HIGH_LNB_VOLTAGE:
+
+********************************
+ioctl FE_ENABLE_HIGH_LNB_VOLTAGE
+********************************
+
+Name
+====
+
+FE_ENABLE_HIGH_LNB_VOLTAGE - Select output DC level between normal LNBf voltages or higher LNBf - voltages.
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, FE_ENABLE_HIGH_LNB_VOLTAGE, unsigned int high )
+    :name: FE_ENABLE_HIGH_LNB_VOLTAGE
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <frontend_f_open>`.
+
+``high``
+    Valid flags:
+
+    -  0 - normal 13V and 18V.
+
+    -  >0 - enables slightly higher voltages instead of 13/18V, in order
+       to compensate for long antenna cables.
+
+
+Description
+===========
+
+Select output DC level between normal LNBf voltages or higher LNBf
+voltages between 0 (normal) or a value grater than 0 for higher
+voltages.
+
+
+Return Value
+============
+
+On success 0 is returned.
+
+On error -1 is returned, and the ``errno`` variable is set
+appropriately.
+
+Generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/userspace-api/media/dvb/fe-get-event.rst b/Documentation/userspace-api/media/dvb/fe-get-event.rst
new file mode 100644
index 000000000000..19df41dca238
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/fe-get-event.rst
@@ -0,0 +1,78 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _FE_GET_EVENT:
+
+************
+FE_GET_EVENT
+************
+
+Name
+====
+
+FE_GET_EVENT
+
+.. attention:: This ioctl is deprecated.
+
+
+Synopsis
+========
+
+.. c:function:: int  ioctl(int fd, FE_GET_EVENT, struct dvb_frontend_event *ev)
+    :name: FE_GET_EVENT
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :c:func:`open() <dvb-fe-open>`.
+
+``ev``
+    Points to the location where the event, if any, is to be stored.
+
+
+Description
+===========
+
+This ioctl call returns a frontend event if available. If an event is
+not available, the behavior depends on whether the device is in blocking
+or non-blocking mode. In the latter case, the call fails immediately
+with errno set to ``EWOULDBLOCK``. In the former case, the call blocks until
+an event becomes available.
+
+
+Return Value
+============
+
+On success 0 is returned.
+
+On error -1 is returned, and the ``errno`` variable is set
+appropriately.
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  ``EWOULDBLOCK``
+
+       -  There is no event pending, and the device is in non-blocking mode.
+
+    -  .. row 2
+
+       -  ``EOVERFLOW``
+
+       -  Overflow in event queue - one or more events were lost.
+
+Generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/userspace-api/media/dvb/fe-get-frontend.rst b/Documentation/userspace-api/media/dvb/fe-get-frontend.rst
new file mode 100644
index 000000000000..7968adc8e982
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/fe-get-frontend.rst
@@ -0,0 +1,69 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _FE_GET_FRONTEND:
+
+***************
+FE_GET_FRONTEND
+***************
+
+Name
+====
+
+FE_GET_FRONTEND
+
+.. attention:: This ioctl is deprecated.
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl(int fd, FE_GET_FRONTEND, struct dvb_frontend_parameters *p)
+    :name: FE_GET_FRONTEND
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :c:func:`open() <dvb-fe-open>`.
+
+
+``p``
+    Points to parameters for tuning operation.
+
+
+Description
+===========
+
+This ioctl call queries the currently effective frontend parameters. For
+this command, read-only access to the device is sufficient.
+
+
+Return Value
+============
+
+On success 0 is returned.
+
+On error -1 is returned, and the ``errno`` variable is set
+appropriately.
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  ``EINVAL``
+
+       -  Maximum supported symbol rate reached.
+
+Generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/userspace-api/media/dvb/fe-get-info.rst b/Documentation/userspace-api/media/dvb/fe-get-info.rst
new file mode 100644
index 000000000000..80d9f8195ac4
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/fe-get-info.rst
@@ -0,0 +1,70 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _FE_GET_INFO:
+
+*****************
+ioctl FE_GET_INFO
+*****************
+
+Name
+====
+
+FE_GET_INFO - Query Digital TV frontend capabilities and returns information
+about the - front-end. This call only requires read-only access to the device.
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, FE_GET_INFO, struct dvb_frontend_info *argp )
+    :name: FE_GET_INFO
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <frontend_f_open>`.
+
+``argp``
+    pointer to struct struct
+    :c:type:`dvb_frontend_info`
+
+
+Description
+===========
+
+All Digital TV frontend devices support the :ref:`FE_GET_INFO` ioctl. It is
+used to identify kernel devices compatible with this specification and to
+obtain information about driver and hardware capabilities. The ioctl
+takes a pointer to dvb_frontend_info which is filled by the driver.
+When the driver is not compatible with this specification the ioctl
+returns an error.
+
+
+frontend capabilities
+=====================
+
+Capabilities describe what a frontend can do. Some capabilities are
+supported only on some specific frontend types.
+
+The frontend capabilities are described at :c:type:`fe_caps`.
+
+
+Return Value
+============
+
+On success 0 is returned.
+
+On error -1 is returned, and the ``errno`` variable is set
+appropriately.
+
+Generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/userspace-api/media/dvb/fe-get-property.rst b/Documentation/userspace-api/media/dvb/fe-get-property.rst
new file mode 100644
index 000000000000..088d4e319405
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/fe-get-property.rst
@@ -0,0 +1,83 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _FE_GET_PROPERTY:
+
+**************************************
+ioctl FE_SET_PROPERTY, FE_GET_PROPERTY
+**************************************
+
+Name
+====
+
+FE_SET_PROPERTY - FE_GET_PROPERTY - FE_SET_PROPERTY sets one or more frontend properties. - FE_GET_PROPERTY returns one or more frontend properties.
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, FE_GET_PROPERTY, struct dtv_properties *argp )
+    :name: FE_GET_PROPERTY
+
+.. c:function:: int ioctl( int fd, FE_SET_PROPERTY, struct dtv_properties *argp )
+    :name: FE_SET_PROPERTY
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <frontend_f_open>`.
+
+``argp``
+    Pointer to struct :c:type:`dtv_properties`.
+
+
+Description
+===========
+
+All Digital TV frontend devices support the ``FE_SET_PROPERTY`` and
+``FE_GET_PROPERTY`` ioctls. The supported properties and statistics
+depends on the delivery system and on the device:
+
+-  ``FE_SET_PROPERTY:``
+
+   -  This ioctl is used to set one or more frontend properties.
+
+   -  This is the basic command to request the frontend to tune into
+      some frequency and to start decoding the digital TV signal.
+
+   -  This call requires read/write access to the device.
+
+.. note::
+
+   At return, the values aren't updated to reflect the actual
+   parameters used. If the actual parameters are needed, an explicit
+   call to ``FE_GET_PROPERTY`` is needed.
+
+-  ``FE_GET_PROPERTY:``
+
+   -  This ioctl is used to get properties and statistics from the
+      frontend.
+
+   -  No properties are changed, and statistics aren't reset.
+
+   -  This call only requires read-only access to the device.
+
+
+Return Value
+============
+
+On success 0 is returned.
+
+On error -1 is returned, and the ``errno`` variable is set
+appropriately.
+
+Generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/userspace-api/media/dvb/fe-read-ber.rst b/Documentation/userspace-api/media/dvb/fe-read-ber.rst
new file mode 100644
index 000000000000..d0a706ac9011
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/fe-read-ber.rst
@@ -0,0 +1,57 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _FE_READ_BER:
+
+***********
+FE_READ_BER
+***********
+
+Name
+====
+
+FE_READ_BER
+
+.. attention:: This ioctl is deprecated.
+
+Synopsis
+========
+
+.. c:function:: int  ioctl(int fd, FE_READ_BER, uint32_t *ber)
+    :name: FE_READ_BER
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :c:func:`open() <dvb-fe-open>`.
+
+``ber``
+    The bit error rate is stored into \*ber.
+
+
+Description
+===========
+
+This ioctl call returns the bit error rate for the signal currently
+received/demodulated by the front-end. For this command, read-only
+access to the device is sufficient.
+
+
+Return Value
+============
+
+On success 0 is returned.
+
+On error -1 is returned, and the ``errno`` variable is set
+appropriately.
+
+Generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/userspace-api/media/dvb/fe-read-signal-strength.rst b/Documentation/userspace-api/media/dvb/fe-read-signal-strength.rst
new file mode 100644
index 000000000000..df79837de47d
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/fe-read-signal-strength.rst
@@ -0,0 +1,57 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _FE_READ_SIGNAL_STRENGTH:
+
+***********************
+FE_READ_SIGNAL_STRENGTH
+***********************
+
+Name
+====
+
+FE_READ_SIGNAL_STRENGTH
+
+.. attention:: This ioctl is deprecated.
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, FE_READ_SIGNAL_STRENGTH, uint16_t *strength)
+    :name: FE_READ_SIGNAL_STRENGTH
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :c:func:`open() <dvb-fe-open>`.
+
+``strength``
+    The signal strength value is stored into \*strength.
+
+
+Description
+===========
+
+This ioctl call returns the signal strength value for the signal
+currently received by the front-end. For this command, read-only access
+to the device is sufficient.
+
+
+Return Value
+============
+
+On success 0 is returned.
+
+On error -1 is returned, and the ``errno`` variable is set
+appropriately.
+
+Generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/userspace-api/media/dvb/fe-read-snr.rst b/Documentation/userspace-api/media/dvb/fe-read-snr.rst
new file mode 100644
index 000000000000..e56147a40e23
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/fe-read-snr.rst
@@ -0,0 +1,57 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _FE_READ_SNR:
+
+***********
+FE_READ_SNR
+***********
+
+Name
+====
+
+FE_READ_SNR
+
+.. attention:: This ioctl is deprecated.
+
+Synopsis
+========
+
+.. c:function:: int  ioctl(int fd, FE_READ_SNR, int16_t *snr)
+    :name: FE_READ_SNR
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :c:func:`open() <dvb-fe-open>`.
+
+``snr``
+    The signal-to-noise ratio is stored into \*snr.
+
+
+Description
+===========
+
+This ioctl call returns the signal-to-noise ratio for the signal
+currently received by the front-end. For this command, read-only access
+to the device is sufficient.
+
+
+Return Value
+============
+
+On success 0 is returned.
+
+On error -1 is returned, and the ``errno`` variable is set
+appropriately.
+
+Generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/userspace-api/media/dvb/fe-read-status.rst b/Documentation/userspace-api/media/dvb/fe-read-status.rst
new file mode 100644
index 000000000000..cf781d463a20
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/fe-read-status.rst
@@ -0,0 +1,72 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _FE_READ_STATUS:
+
+********************
+ioctl FE_READ_STATUS
+********************
+
+Name
+====
+
+FE_READ_STATUS - Returns status information about the front-end. This call only requires - read-only access to the device
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, FE_READ_STATUS, unsigned int *status )
+    :name: FE_READ_STATUS
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <frontend_f_open>`.
+
+``status``
+    pointer to a bitmask integer filled with the values defined by enum
+    :c:type:`fe_status`.
+
+
+Description
+===========
+
+All Digital TV frontend devices support the ``FE_READ_STATUS`` ioctl. It is
+used to check about the locking status of the frontend after being
+tuned. The ioctl takes a pointer to an integer where the status will be
+written.
+
+.. note::
+
+   The size of status is actually sizeof(enum fe_status), with
+   varies according with the architecture. This needs to be fixed in the
+   future.
+
+
+int fe_status
+=============
+
+The fe_status parameter is used to indicate the current state and/or
+state changes of the frontend hardware. It is produced using the enum
+:c:type:`fe_status` values on a bitmask
+
+
+Return Value
+============
+
+On success 0 is returned.
+
+On error -1 is returned, and the ``errno`` variable is set
+appropriately.
+
+Generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/userspace-api/media/dvb/fe-read-uncorrected-blocks.rst b/Documentation/userspace-api/media/dvb/fe-read-uncorrected-blocks.rst
new file mode 100644
index 000000000000..d042e8c86930
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/fe-read-uncorrected-blocks.rst
@@ -0,0 +1,59 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _FE_READ_UNCORRECTED_BLOCKS:
+
+**************************
+FE_READ_UNCORRECTED_BLOCKS
+**************************
+
+Name
+====
+
+FE_READ_UNCORRECTED_BLOCKS
+
+.. attention:: This ioctl is deprecated.
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, FE_READ_UNCORRECTED_BLOCKS, uint32_t *ublocks)
+    :name: FE_READ_UNCORRECTED_BLOCKS
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :c:func:`open() <dvb-fe-open>`.
+
+``ublocks``
+    The total number of uncorrected blocks seen by the driver so far.
+
+
+Description
+===========
+
+This ioctl call returns the number of uncorrected blocks detected by the
+device driver during its lifetime. For meaningful measurements, the
+increment in block count during a specific time interval should be
+calculated. For this command, read-only access to the device is
+sufficient.
+
+
+Return Value
+============
+
+On success 0 is returned.
+
+On error -1 is returned, and the ``errno`` variable is set
+appropriately.
+
+Generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/userspace-api/media/dvb/fe-set-frontend-tune-mode.rst b/Documentation/userspace-api/media/dvb/fe-set-frontend-tune-mode.rst
new file mode 100644
index 000000000000..8e059967f49c
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/fe-set-frontend-tune-mode.rst
@@ -0,0 +1,64 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _FE_SET_FRONTEND_TUNE_MODE:
+
+*******************************
+ioctl FE_SET_FRONTEND_TUNE_MODE
+*******************************
+
+Name
+====
+
+FE_SET_FRONTEND_TUNE_MODE - Allow setting tuner mode flags to the frontend.
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, FE_SET_FRONTEND_TUNE_MODE, unsigned int flags )
+    :name: FE_SET_FRONTEND_TUNE_MODE
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <frontend_f_open>`.
+
+``flags``
+    Valid flags:
+
+    -  0 - normal tune mode
+
+    -  ``FE_TUNE_MODE_ONESHOT`` - When set, this flag will disable any
+       zigzagging or other "normal" tuning behaviour. Additionally,
+       there will be no automatic monitoring of the lock status, and
+       hence no frontend events will be generated. If a frontend device
+       is closed, this flag will be automatically turned off when the
+       device is reopened read-write.
+
+
+Description
+===========
+
+Allow setting tuner mode flags to the frontend, between 0 (normal) or
+``FE_TUNE_MODE_ONESHOT`` mode
+
+
+Return Value
+============
+
+On success 0 is returned.
+
+On error -1 is returned, and the ``errno`` variable is set
+appropriately.
+
+Generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/userspace-api/media/dvb/fe-set-frontend.rst b/Documentation/userspace-api/media/dvb/fe-set-frontend.rst
new file mode 100644
index 000000000000..960c95cb18a0
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/fe-set-frontend.rst
@@ -0,0 +1,78 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _FE_SET_FRONTEND:
+
+***************
+FE_SET_FRONTEND
+***************
+
+.. attention:: This ioctl is deprecated.
+
+Name
+====
+
+FE_SET_FRONTEND
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl(int fd, FE_SET_FRONTEND, struct dvb_frontend_parameters *p)
+    :name: FE_SET_FRONTEND
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :c:func:`open() <dvb-fe-open>`.
+
+``p``
+    Points to parameters for tuning operation.
+
+
+Description
+===========
+
+This ioctl call starts a tuning operation using specified parameters.
+The result of this call will be successful if the parameters were valid
+and the tuning could be initiated. The result of the tuning operation in
+itself, however, will arrive asynchronously as an event (see
+documentation for :ref:`FE_GET_EVENT` and
+FrontendEvent.) If a new :ref:`FE_SET_FRONTEND`
+operation is initiated before the previous one was completed, the
+previous operation will be aborted in favor of the new one. This command
+requires read/write access to the device.
+
+
+Return Value
+============
+
+On success 0 is returned.
+
+On error -1 is returned, and the ``errno`` variable is set
+appropriately.
+
+.. tabularcolumns:: |p{2.5cm}|p{15.0cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths: 1 16
+
+    -  .. row 1
+
+       -  ``EINVAL``
+
+       -  Maximum supported symbol rate reached.
+
+
+Generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/userspace-api/media/dvb/fe-set-tone.rst b/Documentation/userspace-api/media/dvb/fe-set-tone.rst
new file mode 100644
index 000000000000..5726a20c7991
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/fe-set-tone.rst
@@ -0,0 +1,65 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _FE_SET_TONE:
+
+*****************
+ioctl FE_SET_TONE
+*****************
+
+Name
+====
+
+FE_SET_TONE - Sets/resets the generation of the continuous 22kHz tone.
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, FE_SET_TONE, enum fe_sec_tone_mode tone )
+    :name: FE_SET_TONE
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <frontend_f_open>`.
+
+``tone``
+    an integer enumered value described at :c:type:`fe_sec_tone_mode`
+
+
+Description
+===========
+
+This ioctl is used to set the generation of the continuous 22kHz tone.
+This call requires read/write permissions.
+
+Usually, satellite antenna subsystems require that the digital TV device
+to send a 22kHz tone in order to select between high/low band on some
+dual-band LNBf. It is also used to send signals to DiSEqC equipment, but
+this is done using the DiSEqC ioctls.
+
+.. attention:: If more than one device is connected to the same antenna,
+   setting a tone may interfere on other devices, as they may lose the
+   capability of selecting the band. So, it is recommended that applications
+   would change to SEC_TONE_OFF when the device is not used.
+
+
+Return Value
+============
+
+On success 0 is returned.
+
+On error -1 is returned, and the ``errno`` variable is set
+appropriately.
+
+Generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/userspace-api/media/dvb/fe-set-voltage.rst b/Documentation/userspace-api/media/dvb/fe-set-voltage.rst
new file mode 100644
index 000000000000..f3191808f4fd
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/fe-set-voltage.rst
@@ -0,0 +1,69 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _FE_SET_VOLTAGE:
+
+********************
+ioctl FE_SET_VOLTAGE
+********************
+
+Name
+====
+
+FE_SET_VOLTAGE - Allow setting the DC level sent to the antenna subsystem.
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, FE_SET_VOLTAGE, enum fe_sec_voltage voltage )
+    :name: FE_SET_VOLTAGE
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <frontend_f_open>`.
+
+``voltage``
+    an integer enumered value described at :c:type:`fe_sec_voltage`
+
+
+Description
+===========
+
+This ioctl allows to set the DC voltage level sent through the antenna
+cable to 13V, 18V or off.
+
+Usually, a satellite antenna subsystems require that the digital TV
+device to send a DC voltage to feed power to the LNBf. Depending on the
+LNBf type, the polarization or the intermediate frequency (IF) of the
+LNBf can controlled by the voltage level. Other devices (for example,
+the ones that implement DISEqC and multipoint LNBf's don't need to
+control the voltage level, provided that either 13V or 18V is sent to
+power up the LNBf.
+
+.. attention:: if more than one device is connected to the same antenna,
+   setting a voltage level may interfere on other devices, as they may lose
+   the capability of setting polarization or IF. So, on those cases, setting
+   the voltage to SEC_VOLTAGE_OFF while the device is not is used is
+   recommended.
+
+
+Return Value
+============
+
+On success 0 is returned.
+
+On error -1 is returned, and the ``errno`` variable is set
+appropriately.
+
+Generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/userspace-api/media/dvb/fe-type-t.rst b/Documentation/userspace-api/media/dvb/fe-type-t.rst
new file mode 100644
index 000000000000..1617a8cc9045
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/fe-type-t.rst
@@ -0,0 +1,98 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+*************
+Frontend type
+*************
+
+For historical reasons, frontend types are named by the type of
+modulation used in transmission. The fontend types are given by
+fe_type_t type, defined as:
+
+
+.. c:type:: fe_type
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. flat-table:: Frontend types
+    :header-rows:  1
+    :stub-columns: 0
+    :widths:       3 1 4
+
+
+    -  .. row 1
+
+       -  fe_type
+
+       -  Description
+
+       -  :ref:`DTV_DELIVERY_SYSTEM <DTV-DELIVERY-SYSTEM>` equivalent
+	  type
+
+    -  .. row 2
+
+       -  .. _FE-QPSK:
+
+	  ``FE_QPSK``
+
+       -  For DVB-S standard
+
+       -  ``SYS_DVBS``
+
+    -  .. row 3
+
+       -  .. _FE-QAM:
+
+	  ``FE_QAM``
+
+       -  For DVB-C annex A standard
+
+       -  ``SYS_DVBC_ANNEX_A``
+
+    -  .. row 4
+
+       -  .. _FE-OFDM:
+
+	  ``FE_OFDM``
+
+       -  For DVB-T standard
+
+       -  ``SYS_DVBT``
+
+    -  .. row 5
+
+       -  .. _FE-ATSC:
+
+	  ``FE_ATSC``
+
+       -  For ATSC standard (terrestrial) or for DVB-C Annex B (cable) used
+	  in US.
+
+       -  ``SYS_ATSC`` (terrestrial) or ``SYS_DVBC_ANNEX_B`` (cable)
+
+
+Newer formats like DVB-S2, ISDB-T, ISDB-S and DVB-T2 are not described
+at the above, as they're supported via the new
+:ref:`FE_GET_PROPERTY/FE_GET_SET_PROPERTY <FE_GET_PROPERTY>`
+ioctl's, using the :ref:`DTV_DELIVERY_SYSTEM <DTV-DELIVERY-SYSTEM>`
+parameter.
+
+In the old days, struct :c:type:`dvb_frontend_info`
+used to contain ``fe_type_t`` field to indicate the delivery systems,
+filled with either ``FE_QPSK, FE_QAM, FE_OFDM`` or ``FE_ATSC``. While this
+is still filled to keep backward compatibility, the usage of this field
+is deprecated, as it can report just one delivery system, but some
+devices support multiple delivery systems. Please use
+:ref:`DTV_ENUM_DELSYS <DTV-ENUM-DELSYS>` instead.
+
+On devices that support multiple delivery systems, struct
+:c:type:`dvb_frontend_info`::``fe_type_t`` is
+filled with the currently standard, as selected by the last call to
+:ref:`FE_SET_PROPERTY <FE_GET_PROPERTY>` using the
+:ref:`DTV_DELIVERY_SYSTEM <DTV-DELIVERY-SYSTEM>` property.
diff --git a/Documentation/userspace-api/media/dvb/fe_property_parameters.rst b/Documentation/userspace-api/media/dvb/fe_property_parameters.rst
new file mode 100644
index 000000000000..3f4ced2800e3
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/fe_property_parameters.rst
@@ -0,0 +1,1014 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _fe_property_parameters:
+
+******************************
+Digital TV property parameters
+******************************
+
+There are several different Digital TV parameters that can be used by
+:ref:`FE_SET_PROPERTY and FE_GET_PROPERTY ioctls<FE_GET_PROPERTY>`.
+This section describes each of them. Please notice, however, that only
+a subset of them are needed to setup a frontend.
+
+
+.. _DTV-UNDEFINED:
+
+DTV_UNDEFINED
+=============
+
+Used internally. A GET/SET operation for it won't change or return
+anything.
+
+
+.. _DTV-TUNE:
+
+DTV_TUNE
+========
+
+Interpret the cache of data, build either a traditional frontend
+tunerequest so we can pass validation in the ``FE_SET_FRONTEND`` ioctl.
+
+
+.. _DTV-CLEAR:
+
+DTV_CLEAR
+=========
+
+Reset a cache of data specific to the frontend here. This does not
+effect hardware.
+
+
+.. _DTV-FREQUENCY:
+
+DTV_FREQUENCY
+=============
+
+Frequency of the digital TV transponder/channel.
+
+.. note::
+
+  #. For satellite delivery systems, the frequency is in kHz.
+
+  #. For cable and terrestrial delivery systems, the frequency is in
+     Hz.
+
+  #. On most delivery systems, the frequency is the center frequency
+     of the transponder/channel. The exception is for ISDB-T, where
+     the main carrier has a 1/7 offset from the center.
+
+  #. For ISDB-T, the channels are usually transmitted with an offset of
+     about 143kHz. E.g. a valid frequency could be 474,143 kHz. The
+     stepping is  bound to the bandwidth of the channel which is
+     typically 6MHz.
+
+  #. In ISDB-Tsb, the channel consists of only one or three segments the
+     frequency step is 429kHz, 3*429 respectively.
+
+
+.. _DTV-MODULATION:
+
+DTV_MODULATION
+==============
+
+Specifies the frontend modulation type for delivery systems that
+supports more multiple modulations.
+
+The modulation can be one of the types defined by enum :c:type:`fe_modulation`.
+
+Most of the digital TV standards offers more than one possible
+modulation type.
+
+The table below presents a summary of the types of modulation types
+supported by each delivery system, as currently defined by specs.
+
+======================= =======================================================
+Standard		Modulation types
+======================= =======================================================
+ATSC (version 1)	8-VSB and 16-VSB.
+DMTB			4-QAM, 16-QAM, 32-QAM, 64-QAM and 4-QAM-NR.
+DVB-C Annex A/C		16-QAM, 32-QAM, 64-QAM and 256-QAM.
+DVB-C Annex B		64-QAM.
+DVB-T			QPSK, 16-QAM and 64-QAM.
+DVB-T2			QPSK, 16-QAM, 64-QAM and 256-QAM.
+DVB-S			No need to set. It supports only QPSK.
+DVB-S2			QPSK, 8-PSK, 16-APSK and 32-APSK.
+ISDB-T			QPSK, DQPSK, 16-QAM and 64-QAM.
+ISDB-S			8-PSK, QPSK and BPSK.
+======================= =======================================================
+
+.. note::
+
+   Please notice that some of the above modulation types may not be
+   defined currently at the Kernel. The reason is simple: no driver
+   needed such definition yet.
+
+
+.. _DTV-BANDWIDTH-HZ:
+
+DTV_BANDWIDTH_HZ
+================
+
+Bandwidth for the channel, in HZ.
+
+Should be set only for terrestrial delivery systems.
+
+Possible values: ``1712000``, ``5000000``, ``6000000``, ``7000000``,
+``8000000``, ``10000000``.
+
+======================= =======================================================
+Terrestrial Standard	Possible values for bandwidth
+======================= =======================================================
+ATSC (version 1)	No need to set. It is always 6MHz.
+DMTB			No need to set. It is always 8MHz.
+DVB-T			6MHz, 7MHz and 8MHz.
+DVB-T2			1.172 MHz, 5MHz, 6MHz, 7MHz, 8MHz and 10MHz
+ISDB-T			5MHz, 6MHz, 7MHz and 8MHz, although most places
+			use 6MHz.
+======================= =======================================================
+
+
+.. note::
+
+
+  #. For ISDB-Tsb, the bandwidth can vary depending on the number of
+     connected segments.
+
+     It can be easily derived from other parameters
+     (DTV_ISDBT_SB_SEGMENT_IDX, DTV_ISDBT_SB_SEGMENT_COUNT).
+
+  #. On Satellite and Cable delivery systems, the bandwidth depends on
+     the symbol rate. So, the Kernel will silently ignore any setting
+     :ref:`DTV-BANDWIDTH-HZ`. I will however fill it back with a
+     bandwidth estimation.
+
+     Such bandwidth estimation takes into account the symbol rate set with
+     :ref:`DTV-SYMBOL-RATE`, and the rolloff factor, with is fixed for
+     DVB-C and DVB-S.
+
+     For DVB-S2, the rolloff should also be set via :ref:`DTV-ROLLOFF`.
+
+
+.. _DTV-INVERSION:
+
+DTV_INVERSION
+=============
+
+Specifies if the frontend should do spectral inversion or not.
+
+The acceptable values are defined by :c:type:`fe_spectral_inversion`.
+
+
+.. _DTV-DISEQC-MASTER:
+
+DTV_DISEQC_MASTER
+=================
+
+Currently not implemented.
+
+
+.. _DTV-SYMBOL-RATE:
+
+DTV_SYMBOL_RATE
+===============
+
+Used on cable and satellite delivery systems.
+
+Digital TV symbol rate, in bauds (symbols/second).
+
+
+.. _DTV-INNER-FEC:
+
+DTV_INNER_FEC
+=============
+
+Used on cable and satellite delivery systems.
+
+The acceptable values are defined by :c:type:`fe_code_rate`.
+
+
+.. _DTV-VOLTAGE:
+
+DTV_VOLTAGE
+===========
+
+Used on satellite delivery systems.
+
+The voltage is usually used with non-DiSEqC capable LNBs to switch the
+polarzation (horizontal/vertical). When using DiSEqC epuipment this
+voltage has to be switched consistently to the DiSEqC commands as
+described in the DiSEqC spec.
+
+The acceptable values are defined by :c:type:`fe_sec_voltage`.
+
+
+.. _DTV-TONE:
+
+DTV_TONE
+========
+
+Currently not used.
+
+
+.. _DTV-PILOT:
+
+DTV_PILOT
+=========
+
+Used on DVB-S2.
+
+Sets DVB-S2 pilot.
+
+The acceptable values are defined by :c:type:`fe_pilot`.
+
+
+.. _DTV-ROLLOFF:
+
+DTV_ROLLOFF
+===========
+
+Used on DVB-S2.
+
+Sets DVB-S2 rolloff.
+
+The acceptable values are defined by :c:type:`fe_rolloff`.
+
+
+.. _DTV-DISEQC-SLAVE-REPLY:
+
+DTV_DISEQC_SLAVE_REPLY
+======================
+
+Currently not implemented.
+
+
+.. _DTV-FE-CAPABILITY-COUNT:
+
+DTV_FE_CAPABILITY_COUNT
+=======================
+
+Currently not implemented.
+
+
+.. _DTV-FE-CAPABILITY:
+
+DTV_FE_CAPABILITY
+=================
+
+Currently not implemented.
+
+
+.. _DTV-DELIVERY-SYSTEM:
+
+DTV_DELIVERY_SYSTEM
+===================
+
+Specifies the type of the delivery system.
+
+The acceptable values are defined by :c:type:`fe_delivery_system`.
+
+
+.. _DTV-ISDBT-PARTIAL-RECEPTION:
+
+DTV_ISDBT_PARTIAL_RECEPTION
+===========================
+
+Used only on ISDB.
+
+If ``DTV_ISDBT_SOUND_BROADCASTING`` is '0' this bit-field represents
+whether the channel is in partial reception mode or not.
+
+If '1' ``DTV_ISDBT_LAYERA_*`` values are assigned to the center segment
+and ``DTV_ISDBT_LAYERA_SEGMENT_COUNT`` has to be '1'.
+
+If in addition ``DTV_ISDBT_SOUND_BROADCASTING`` is '1'
+``DTV_ISDBT_PARTIAL_RECEPTION`` represents whether this ISDB-Tsb channel
+is consisting of one segment and layer or three segments and two layers.
+
+Possible values: 0, 1, -1 (AUTO)
+
+
+.. _DTV-ISDBT-SOUND-BROADCASTING:
+
+DTV_ISDBT_SOUND_BROADCASTING
+============================
+
+Used only on ISDB.
+
+This field represents whether the other DTV_ISDBT_*-parameters are
+referring to an ISDB-T and an ISDB-Tsb channel. (See also
+``DTV_ISDBT_PARTIAL_RECEPTION``).
+
+Possible values: 0, 1, -1 (AUTO)
+
+
+.. _DTV-ISDBT-SB-SUBCHANNEL-ID:
+
+DTV_ISDBT_SB_SUBCHANNEL_ID
+==========================
+
+Used only on ISDB.
+
+This field only applies if ``DTV_ISDBT_SOUND_BROADCASTING`` is '1'.
+
+(Note of the author: This might not be the correct description of the
+``SUBCHANNEL-ID`` in all details, but it is my understanding of the
+technical background needed to program a device)
+
+An ISDB-Tsb channel (1 or 3 segments) can be broadcasted alone or in a
+set of connected ISDB-Tsb channels. In this set of channels every
+channel can be received independently. The number of connected ISDB-Tsb
+segment can vary, e.g. depending on the frequency spectrum bandwidth
+available.
+
+Example: Assume 8 ISDB-Tsb connected segments are broadcasted. The
+broadcaster has several possibilities to put those channels in the air:
+Assuming a normal 13-segment ISDB-T spectrum he can align the 8 segments
+from position 1-8 to 5-13 or anything in between.
+
+The underlying layer of segments are subchannels: each segment is
+consisting of several subchannels with a predefined IDs. A sub-channel
+is used to help the demodulator to synchronize on the channel.
+
+An ISDB-T channel is always centered over all sub-channels. As for the
+example above, in ISDB-Tsb it is no longer as simple as that.
+
+``The DTV_ISDBT_SB_SUBCHANNEL_ID`` parameter is used to give the
+sub-channel ID of the segment to be demodulated.
+
+Possible values: 0 .. 41, -1 (AUTO)
+
+
+.. _DTV-ISDBT-SB-SEGMENT-IDX:
+
+DTV_ISDBT_SB_SEGMENT_IDX
+========================
+
+Used only on ISDB.
+
+This field only applies if ``DTV_ISDBT_SOUND_BROADCASTING`` is '1'.
+
+``DTV_ISDBT_SB_SEGMENT_IDX`` gives the index of the segment to be
+demodulated for an ISDB-Tsb channel where several of them are
+transmitted in the connected manner.
+
+Possible values: 0 .. ``DTV_ISDBT_SB_SEGMENT_COUNT`` - 1
+
+Note: This value cannot be determined by an automatic channel search.
+
+
+.. _DTV-ISDBT-SB-SEGMENT-COUNT:
+
+DTV_ISDBT_SB_SEGMENT_COUNT
+==========================
+
+Used only on ISDB.
+
+This field only applies if ``DTV_ISDBT_SOUND_BROADCASTING`` is '1'.
+
+``DTV_ISDBT_SB_SEGMENT_COUNT`` gives the total count of connected
+ISDB-Tsb channels.
+
+Possible values: 1 .. 13
+
+Note: This value cannot be determined by an automatic channel search.
+
+
+.. _isdb-hierq-layers:
+
+DTV-ISDBT-LAYER[A-C] parameters
+===============================
+
+Used only on ISDB.
+
+ISDB-T channels can be coded hierarchically. As opposed to DVB-T in
+ISDB-T hierarchical layers can be decoded simultaneously. For that
+reason a ISDB-T demodulator has 3 Viterbi and 3 Reed-Solomon decoders.
+
+ISDB-T has 3 hierarchical layers which each can use a part of the
+available segments. The total number of segments over all layers has to
+13 in ISDB-T.
+
+There are 3 parameter sets, for Layers A, B and C.
+
+
+.. _DTV-ISDBT-LAYER-ENABLED:
+
+DTV_ISDBT_LAYER_ENABLED
+-----------------------
+
+Used only on ISDB.
+
+Hierarchical reception in ISDB-T is achieved by enabling or disabling
+layers in the decoding process. Setting all bits of
+``DTV_ISDBT_LAYER_ENABLED`` to '1' forces all layers (if applicable) to
+be demodulated. This is the default.
+
+If the channel is in the partial reception mode
+(``DTV_ISDBT_PARTIAL_RECEPTION`` = 1) the central segment can be decoded
+independently of the other 12 segments. In that mode layer A has to have
+a ``SEGMENT_COUNT`` of 1.
+
+In ISDB-Tsb only layer A is used, it can be 1 or 3 in ISDB-Tsb according
+to ``DTV_ISDBT_PARTIAL_RECEPTION``. ``SEGMENT_COUNT`` must be filled
+accordingly.
+
+Only the values of the first 3 bits are used. Other bits will be silently ignored:
+
+``DTV_ISDBT_LAYER_ENABLED`` bit 0: layer A enabled
+
+``DTV_ISDBT_LAYER_ENABLED`` bit 1: layer B enabled
+
+``DTV_ISDBT_LAYER_ENABLED`` bit 2: layer C enabled
+
+``DTV_ISDBT_LAYER_ENABLED`` bits 3-31: unused
+
+
+.. _DTV-ISDBT-LAYER-FEC:
+
+DTV_ISDBT_LAYER[A-C]_FEC
+------------------------
+
+Used only on ISDB.
+
+The Forward Error Correction mechanism used by a given ISDB Layer, as
+defined by :c:type:`fe_code_rate`.
+
+
+Possible values are: ``FEC_AUTO``, ``FEC_1_2``, ``FEC_2_3``, ``FEC_3_4``,
+``FEC_5_6``, ``FEC_7_8``
+
+
+.. _DTV-ISDBT-LAYER-MODULATION:
+
+DTV_ISDBT_LAYER[A-C]_MODULATION
+-------------------------------
+
+Used only on ISDB.
+
+The modulation used by a given ISDB Layer, as defined by
+:c:type:`fe_modulation`.
+
+Possible values are: ``QAM_AUTO``, ``QPSK``, ``QAM_16``, ``QAM_64``, ``DQPSK``
+
+.. note::
+
+   #. If layer C is ``DQPSK``, then layer B has to be ``DQPSK``.
+
+   #. If layer B is ``DQPSK`` and ``DTV_ISDBT_PARTIAL_RECEPTION``\ = 0,
+      then layer has to be ``DQPSK``.
+
+
+.. _DTV-ISDBT-LAYER-SEGMENT-COUNT:
+
+DTV_ISDBT_LAYER[A-C]_SEGMENT_COUNT
+----------------------------------
+
+Used only on ISDB.
+
+Possible values: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -1 (AUTO)
+
+Note: Truth table for ``DTV_ISDBT_SOUND_BROADCASTING`` and
+``DTV_ISDBT_PARTIAL_RECEPTION`` and ``LAYER[A-C]_SEGMENT_COUNT``
+
+.. _isdbt-layer_seg-cnt-table:
+
+.. flat-table:: Truth table for ISDB-T Sound Broadcasting
+    :header-rows:  1
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  Partial Reception
+
+       -  Sound Broadcasting
+
+       -  Layer A width
+
+       -  Layer B width
+
+       -  Layer C width
+
+       -  total width
+
+    -  .. row 2
+
+       -  0
+
+       -  0
+
+       -  1 .. 13
+
+       -  1 .. 13
+
+       -  1 .. 13
+
+       -  13
+
+    -  .. row 3
+
+       -  1
+
+       -  0
+
+       -  1
+
+       -  1 .. 13
+
+       -  1 .. 13
+
+       -  13
+
+    -  .. row 4
+
+       -  0
+
+       -  1
+
+       -  1
+
+       -  0
+
+       -  0
+
+       -  1
+
+    -  .. row 5
+
+       -  1
+
+       -  1
+
+       -  1
+
+       -  2
+
+       -  0
+
+       -  13
+
+
+
+.. _DTV-ISDBT-LAYER-TIME-INTERLEAVING:
+
+DTV_ISDBT_LAYER[A-C]_TIME_INTERLEAVING
+--------------------------------------
+
+Used only on ISDB.
+
+Valid values: 0, 1, 2, 4, -1 (AUTO)
+
+when DTV_ISDBT_SOUND_BROADCASTING is active, value 8 is also valid.
+
+Note: The real time interleaving length depends on the mode (fft-size).
+The values here are referring to what can be found in the
+TMCC-structure, as shown in the table below.
+
+
+.. c:type:: isdbt_layer_interleaving_table
+
+.. flat-table:: ISDB-T time interleaving modes
+    :header-rows:  1
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  ``DTV_ISDBT_LAYER[A-C]_TIME_INTERLEAVING``
+
+       -  Mode 1 (2K FFT)
+
+       -  Mode 2 (4K FFT)
+
+       -  Mode 3 (8K FFT)
+
+    -  .. row 2
+
+       -  0
+
+       -  0
+
+       -  0
+
+       -  0
+
+    -  .. row 3
+
+       -  1
+
+       -  4
+
+       -  2
+
+       -  1
+
+    -  .. row 4
+
+       -  2
+
+       -  8
+
+       -  4
+
+       -  2
+
+    -  .. row 5
+
+       -  4
+
+       -  16
+
+       -  8
+
+       -  4
+
+
+
+.. _DTV-ATSCMH-FIC-VER:
+
+DTV_ATSCMH_FIC_VER
+------------------
+
+Used only on ATSC-MH.
+
+Version number of the FIC (Fast Information Channel) signaling data.
+
+FIC is used for relaying information to allow rapid service acquisition
+by the receiver.
+
+Possible values: 0, 1, 2, 3, ..., 30, 31
+
+
+.. _DTV-ATSCMH-PARADE-ID:
+
+DTV_ATSCMH_PARADE_ID
+--------------------
+
+Used only on ATSC-MH.
+
+Parade identification number
+
+A parade is a collection of up to eight MH groups, conveying one or two
+ensembles.
+
+Possible values: 0, 1, 2, 3, ..., 126, 127
+
+
+.. _DTV-ATSCMH-NOG:
+
+DTV_ATSCMH_NOG
+--------------
+
+Used only on ATSC-MH.
+
+Number of MH groups per MH subframe for a designated parade.
+
+Possible values: 1, 2, 3, 4, 5, 6, 7, 8
+
+
+.. _DTV-ATSCMH-TNOG:
+
+DTV_ATSCMH_TNOG
+---------------
+
+Used only on ATSC-MH.
+
+Total number of MH groups including all MH groups belonging to all MH
+parades in one MH subframe.
+
+Possible values: 0, 1, 2, 3, ..., 30, 31
+
+
+.. _DTV-ATSCMH-SGN:
+
+DTV_ATSCMH_SGN
+--------------
+
+Used only on ATSC-MH.
+
+Start group number.
+
+Possible values: 0, 1, 2, 3, ..., 14, 15
+
+
+.. _DTV-ATSCMH-PRC:
+
+DTV_ATSCMH_PRC
+--------------
+
+Used only on ATSC-MH.
+
+Parade repetition cycle.
+
+Possible values: 1, 2, 3, 4, 5, 6, 7, 8
+
+
+.. _DTV-ATSCMH-RS-FRAME-MODE:
+
+DTV_ATSCMH_RS_FRAME_MODE
+------------------------
+
+Used only on ATSC-MH.
+
+Reed Solomon (RS) frame mode.
+
+The acceptable values are defined by :c:type:`atscmh_rs_frame_mode`.
+
+
+.. _DTV-ATSCMH-RS-FRAME-ENSEMBLE:
+
+DTV_ATSCMH_RS_FRAME_ENSEMBLE
+----------------------------
+
+Used only on ATSC-MH.
+
+Reed Solomon(RS) frame ensemble.
+
+The acceptable values are defined by :c:type:`atscmh_rs_frame_ensemble`.
+
+
+.. _DTV-ATSCMH-RS-CODE-MODE-PRI:
+
+DTV_ATSCMH_RS_CODE_MODE_PRI
+---------------------------
+
+Used only on ATSC-MH.
+
+Reed Solomon (RS) code mode (primary).
+
+The acceptable values are defined by :c:type:`atscmh_rs_code_mode`.
+
+
+.. _DTV-ATSCMH-RS-CODE-MODE-SEC:
+
+DTV_ATSCMH_RS_CODE_MODE_SEC
+---------------------------
+
+Used only on ATSC-MH.
+
+Reed Solomon (RS) code mode (secondary).
+
+The acceptable values are defined by :c:type:`atscmh_rs_code_mode`.
+
+
+.. _DTV-ATSCMH-SCCC-BLOCK-MODE:
+
+DTV_ATSCMH_SCCC_BLOCK_MODE
+--------------------------
+
+Used only on ATSC-MH.
+
+Series Concatenated Convolutional Code Block Mode.
+
+The acceptable values are defined by :c:type:`atscmh_sccc_block_mode`.
+
+
+.. _DTV-ATSCMH-SCCC-CODE-MODE-A:
+
+DTV_ATSCMH_SCCC_CODE_MODE_A
+---------------------------
+
+Used only on ATSC-MH.
+
+Series Concatenated Convolutional Code Rate.
+
+The acceptable values are defined by :c:type:`atscmh_sccc_code_mode`.
+
+.. _DTV-ATSCMH-SCCC-CODE-MODE-B:
+
+DTV_ATSCMH_SCCC_CODE_MODE_B
+---------------------------
+
+Used only on ATSC-MH.
+
+Series Concatenated Convolutional Code Rate.
+
+Possible values are the same as documented on enum
+:c:type:`atscmh_sccc_code_mode`.
+
+
+.. _DTV-ATSCMH-SCCC-CODE-MODE-C:
+
+DTV_ATSCMH_SCCC_CODE_MODE_C
+---------------------------
+
+Used only on ATSC-MH.
+
+Series Concatenated Convolutional Code Rate.
+
+Possible values are the same as documented on enum
+:c:type:`atscmh_sccc_code_mode`.
+
+
+.. _DTV-ATSCMH-SCCC-CODE-MODE-D:
+
+DTV_ATSCMH_SCCC_CODE_MODE_D
+---------------------------
+
+Used only on ATSC-MH.
+
+Series Concatenated Convolutional Code Rate.
+
+Possible values are the same as documented on enum
+:c:type:`atscmh_sccc_code_mode`.
+
+
+.. _DTV-API-VERSION:
+
+DTV_API_VERSION
+===============
+
+Returns the major/minor version of the Digital TV API
+
+
+.. _DTV-CODE-RATE-HP:
+
+DTV_CODE_RATE_HP
+================
+
+Used on terrestrial transmissions.
+
+The acceptable values are defined by :c:type:`fe_transmit_mode`.
+
+
+.. _DTV-CODE-RATE-LP:
+
+DTV_CODE_RATE_LP
+================
+
+Used on terrestrial transmissions.
+
+The acceptable values are defined by :c:type:`fe_transmit_mode`.
+
+
+.. _DTV-GUARD-INTERVAL:
+
+DTV_GUARD_INTERVAL
+==================
+
+The acceptable values are defined by :c:type:`fe_guard_interval`.
+
+.. note::
+
+   #. If ``DTV_GUARD_INTERVAL`` is set the ``GUARD_INTERVAL_AUTO`` the
+      hardware will try to find the correct guard interval (if capable) and
+      will use TMCC to fill in the missing parameters.
+   #. Intervals ``GUARD_INTERVAL_1_128``, ``GUARD_INTERVAL_19_128``
+      and ``GUARD_INTERVAL_19_256`` are used only for DVB-T2 at
+      present.
+   #. Intervals ``GUARD_INTERVAL_PN420``, ``GUARD_INTERVAL_PN595`` and
+      ``GUARD_INTERVAL_PN945`` are used only for DMTB at the present.
+      On such standard, only those intervals and ``GUARD_INTERVAL_AUTO``
+      are valid.
+
+.. _DTV-TRANSMISSION-MODE:
+
+DTV_TRANSMISSION_MODE
+=====================
+
+
+Used only on OFTM-based standards, e. g. DVB-T/T2, ISDB-T, DTMB.
+
+Specifies the FFT size (with corresponds to the approximate number of
+carriers) used by the standard.
+
+The acceptable values are defined by :c:type:`fe_transmit_mode`.
+
+.. note::
+
+   #. ISDB-T supports three carrier/symbol-size: 8K, 4K, 2K. It is called
+      **mode** on such standard, and are numbered from 1 to 3:
+
+      ====	========	========================
+      Mode	FFT size	Transmission mode
+      ====	========	========================
+      1		2K		``TRANSMISSION_MODE_2K``
+      2		4K		``TRANSMISSION_MODE_4K``
+      3		8K		``TRANSMISSION_MODE_8K``
+      ====	========	========================
+
+   #. If ``DTV_TRANSMISSION_MODE`` is set the ``TRANSMISSION_MODE_AUTO``
+      the hardware will try to find the correct FFT-size (if capable) and
+      will use TMCC to fill in the missing parameters.
+
+   #. DVB-T specifies 2K and 8K as valid sizes.
+
+   #. DVB-T2 specifies 1K, 2K, 4K, 8K, 16K and 32K.
+
+   #. DTMB specifies C1 and C3780.
+
+
+.. _DTV-HIERARCHY:
+
+DTV_HIERARCHY
+=============
+
+Used only on DVB-T and DVB-T2.
+
+Frontend hierarchy.
+
+The acceptable values are defined by :c:type:`fe_hierarchy`.
+
+
+.. _DTV-STREAM-ID:
+
+DTV_STREAM_ID
+=============
+
+Used on DVB-S2, DVB-T2 and ISDB-S.
+
+DVB-S2, DVB-T2 and ISDB-S support the transmission of several streams on
+a single transport stream. This property enables the digital TV driver to
+handle substream filtering, when supported by the hardware. By default,
+substream filtering is disabled.
+
+For DVB-S2 and DVB-T2, the valid substream id range is from 0 to 255.
+
+For ISDB, the valid substream id range is from 1 to 65535.
+
+To disable it, you should use the special macro NO_STREAM_ID_FILTER.
+
+Note: any value outside the id range also disables filtering.
+
+
+.. _DTV-DVBT2-PLP-ID-LEGACY:
+
+DTV_DVBT2_PLP_ID_LEGACY
+=======================
+
+Obsolete, replaced with DTV_STREAM_ID.
+
+
+.. _DTV-ENUM-DELSYS:
+
+DTV_ENUM_DELSYS
+===============
+
+A Multi standard frontend needs to advertise the delivery systems
+provided. Applications need to enumerate the provided delivery systems,
+before using any other operation with the frontend. Prior to it's
+introduction, FE_GET_INFO was used to determine a frontend type. A
+frontend which provides more than a single delivery system,
+FE_GET_INFO doesn't help much. Applications which intends to use a
+multistandard frontend must enumerate the delivery systems associated
+with it, rather than trying to use FE_GET_INFO. In the case of a
+legacy frontend, the result is just the same as with FE_GET_INFO, but
+in a more structured format
+
+The acceptable values are defined by :c:type:`fe_delivery_system`.
+
+
+.. _DTV-INTERLEAVING:
+
+DTV_INTERLEAVING
+================
+
+Time interleaving to be used.
+
+The acceptable values are defined by :c:type:`fe_interleaving`.
+
+
+.. _DTV-LNA:
+
+DTV_LNA
+=======
+
+Low-noise amplifier.
+
+Hardware might offer controllable LNA which can be set manually using
+that parameter. Usually LNA could be found only from terrestrial devices
+if at all.
+
+Possible values: 0, 1, LNA_AUTO
+
+0, LNA off
+
+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/userspace-api/media/dvb/frontend-header.rst b/Documentation/userspace-api/media/dvb/frontend-header.rst
new file mode 100644
index 000000000000..cf8e515e5e1f
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/frontend-header.rst
@@ -0,0 +1,13 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+Frontend uAPI data types
+========================
+
+.. kernel-doc:: include/uapi/linux/dvb/frontend.h
diff --git a/Documentation/userspace-api/media/dvb/frontend-property-cable-systems.rst b/Documentation/userspace-api/media/dvb/frontend-property-cable-systems.rst
new file mode 100644
index 000000000000..56657a6ec6ff
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/frontend-property-cable-systems.rst
@@ -0,0 +1,82 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _frontend-property-cable-systems:
+
+*****************************************
+Properties used on cable delivery systems
+*****************************************
+
+
+.. _dvbc-params:
+
+DVB-C delivery system
+=====================
+
+The DVB-C Annex-A is the widely used cable standard. Transmission uses
+QAM modulation.
+
+The DVB-C Annex-C is optimized for 6MHz, and is used in Japan. It
+supports a subset of the Annex A modulation types, and a roll-off of
+0.13, instead of 0.15
+
+The following parameters are valid for DVB-C Annex A/C:
+
+-  :ref:`DTV_API_VERSION <DTV-API-VERSION>`
+
+-  :ref:`DTV_DELIVERY_SYSTEM <DTV-DELIVERY-SYSTEM>`
+
+-  :ref:`DTV_TUNE <DTV-TUNE>`
+
+-  :ref:`DTV_CLEAR <DTV-CLEAR>`
+
+-  :ref:`DTV_FREQUENCY <DTV-FREQUENCY>`
+
+-  :ref:`DTV_MODULATION <DTV-MODULATION>`
+
+-  :ref:`DTV_INVERSION <DTV-INVERSION>`
+
+-  :ref:`DTV_SYMBOL_RATE <DTV-SYMBOL-RATE>`
+
+-  :ref:`DTV_INNER_FEC <DTV-INNER-FEC>`
+
+-  :ref:`DTV_LNA <DTV-LNA>`
+
+In addition, the :ref:`DTV QoS statistics <frontend-stat-properties>`
+are also valid.
+
+
+.. _dvbc-annex-b-params:
+
+DVB-C Annex B delivery system
+=============================
+
+The DVB-C Annex-B is only used on a few Countries like the United
+States.
+
+The following parameters are valid for DVB-C Annex B:
+
+-  :ref:`DTV_API_VERSION <DTV-API-VERSION>`
+
+-  :ref:`DTV_DELIVERY_SYSTEM <DTV-DELIVERY-SYSTEM>`
+
+-  :ref:`DTV_TUNE <DTV-TUNE>`
+
+-  :ref:`DTV_CLEAR <DTV-CLEAR>`
+
+-  :ref:`DTV_FREQUENCY <DTV-FREQUENCY>`
+
+-  :ref:`DTV_MODULATION <DTV-MODULATION>`
+
+-  :ref:`DTV_INVERSION <DTV-INVERSION>`
+
+-  :ref:`DTV_LNA <DTV-LNA>`
+
+In addition, the :ref:`DTV QoS statistics <frontend-stat-properties>`
+are also valid.
diff --git a/Documentation/userspace-api/media/dvb/frontend-property-satellite-systems.rst b/Documentation/userspace-api/media/dvb/frontend-property-satellite-systems.rst
new file mode 100644
index 000000000000..e64fd625c476
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/frontend-property-satellite-systems.rst
@@ -0,0 +1,112 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _frontend-property-satellite-systems:
+
+*********************************************
+Properties used on satellite delivery systems
+*********************************************
+
+
+.. _dvbs-params:
+
+DVB-S delivery system
+=====================
+
+The following parameters are valid for DVB-S:
+
+-  :ref:`DTV_API_VERSION <DTV-API-VERSION>`
+
+-  :ref:`DTV_DELIVERY_SYSTEM <DTV-DELIVERY-SYSTEM>`
+
+-  :ref:`DTV_TUNE <DTV-TUNE>`
+
+-  :ref:`DTV_CLEAR <DTV-CLEAR>`
+
+-  :ref:`DTV_FREQUENCY <DTV-FREQUENCY>`
+
+-  :ref:`DTV_INVERSION <DTV-INVERSION>`
+
+-  :ref:`DTV_SYMBOL_RATE <DTV-SYMBOL-RATE>`
+
+-  :ref:`DTV_INNER_FEC <DTV-INNER-FEC>`
+
+-  :ref:`DTV_VOLTAGE <DTV-VOLTAGE>`
+
+-  :ref:`DTV_TONE <DTV-TONE>`
+
+In addition, the :ref:`DTV QoS statistics <frontend-stat-properties>`
+are also valid.
+
+Future implementations might add those two missing parameters:
+
+-  :ref:`DTV_DISEQC_MASTER <DTV-DISEQC-MASTER>`
+
+-  :ref:`DTV_DISEQC_SLAVE_REPLY <DTV-DISEQC-SLAVE-REPLY>`
+
+
+.. _dvbs2-params:
+
+DVB-S2 delivery system
+======================
+
+In addition to all parameters valid for DVB-S, DVB-S2 supports the
+following parameters:
+
+-  :ref:`DTV_MODULATION <DTV-MODULATION>`
+
+-  :ref:`DTV_PILOT <DTV-PILOT>`
+
+-  :ref:`DTV_ROLLOFF <DTV-ROLLOFF>`
+
+-  :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.
+
+
+.. _turbo-params:
+
+Turbo code delivery system
+==========================
+
+In addition to all parameters valid for DVB-S, turbo code supports the
+following parameters:
+
+-  :ref:`DTV_MODULATION <DTV-MODULATION>`
+
+
+.. _isdbs-params:
+
+ISDB-S delivery system
+======================
+
+The following parameters are valid for ISDB-S:
+
+-  :ref:`DTV_API_VERSION <DTV-API-VERSION>`
+
+-  :ref:`DTV_DELIVERY_SYSTEM <DTV-DELIVERY-SYSTEM>`
+
+-  :ref:`DTV_TUNE <DTV-TUNE>`
+
+-  :ref:`DTV_CLEAR <DTV-CLEAR>`
+
+-  :ref:`DTV_FREQUENCY <DTV-FREQUENCY>`
+
+-  :ref:`DTV_INVERSION <DTV-INVERSION>`
+
+-  :ref:`DTV_SYMBOL_RATE <DTV-SYMBOL-RATE>`
+
+-  :ref:`DTV_INNER_FEC <DTV-INNER-FEC>`
+
+-  :ref:`DTV_VOLTAGE <DTV-VOLTAGE>`
+
+-  :ref:`DTV_STREAM_ID <DTV-STREAM-ID>`
diff --git a/Documentation/userspace-api/media/dvb/frontend-property-terrestrial-systems.rst b/Documentation/userspace-api/media/dvb/frontend-property-terrestrial-systems.rst
new file mode 100644
index 000000000000..1079522b2425
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/frontend-property-terrestrial-systems.rst
@@ -0,0 +1,301 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _frontend-property-terrestrial-systems:
+
+***********************************************
+Properties used on terrestrial delivery systems
+***********************************************
+
+
+.. _dvbt-params:
+
+DVB-T delivery system
+=====================
+
+The following parameters are valid for DVB-T:
+
+-  :ref:`DTV_API_VERSION <DTV-API-VERSION>`
+
+-  :ref:`DTV_DELIVERY_SYSTEM <DTV-DELIVERY-SYSTEM>`
+
+-  :ref:`DTV_TUNE <DTV-TUNE>`
+
+-  :ref:`DTV_CLEAR <DTV-CLEAR>`
+
+-  :ref:`DTV_FREQUENCY <DTV-FREQUENCY>`
+
+-  :ref:`DTV_MODULATION <DTV-MODULATION>`
+
+-  :ref:`DTV_BANDWIDTH_HZ <DTV-BANDWIDTH-HZ>`
+
+-  :ref:`DTV_INVERSION <DTV-INVERSION>`
+
+-  :ref:`DTV_CODE_RATE_HP <DTV-CODE-RATE-HP>`
+
+-  :ref:`DTV_CODE_RATE_LP <DTV-CODE-RATE-LP>`
+
+-  :ref:`DTV_GUARD_INTERVAL <DTV-GUARD-INTERVAL>`
+
+-  :ref:`DTV_TRANSMISSION_MODE <DTV-TRANSMISSION-MODE>`
+
+-  :ref:`DTV_HIERARCHY <DTV-HIERARCHY>`
+
+-  :ref:`DTV_LNA <DTV-LNA>`
+
+In addition, the :ref:`DTV QoS statistics <frontend-stat-properties>`
+are also valid.
+
+
+.. _dvbt2-params:
+
+DVB-T2 delivery system
+======================
+
+DVB-T2 support is currently in the early stages of development, so
+expect that this section maygrow and become more detailed with time.
+
+The following parameters are valid for DVB-T2:
+
+-  :ref:`DTV_API_VERSION <DTV-API-VERSION>`
+
+-  :ref:`DTV_DELIVERY_SYSTEM <DTV-DELIVERY-SYSTEM>`
+
+-  :ref:`DTV_TUNE <DTV-TUNE>`
+
+-  :ref:`DTV_CLEAR <DTV-CLEAR>`
+
+-  :ref:`DTV_FREQUENCY <DTV-FREQUENCY>`
+
+-  :ref:`DTV_MODULATION <DTV-MODULATION>`
+
+-  :ref:`DTV_BANDWIDTH_HZ <DTV-BANDWIDTH-HZ>`
+
+-  :ref:`DTV_INVERSION <DTV-INVERSION>`
+
+-  :ref:`DTV_CODE_RATE_HP <DTV-CODE-RATE-HP>`
+
+-  :ref:`DTV_CODE_RATE_LP <DTV-CODE-RATE-LP>`
+
+-  :ref:`DTV_GUARD_INTERVAL <DTV-GUARD-INTERVAL>`
+
+-  :ref:`DTV_TRANSMISSION_MODE <DTV-TRANSMISSION-MODE>`
+
+-  :ref:`DTV_HIERARCHY <DTV-HIERARCHY>`
+
+-  :ref:`DTV_STREAM_ID <DTV-STREAM-ID>`
+
+-  :ref:`DTV_LNA <DTV-LNA>`
+
+In addition, the :ref:`DTV QoS statistics <frontend-stat-properties>`
+are also valid.
+
+
+.. _isdbt:
+
+ISDB-T delivery system
+======================
+
+This ISDB-T/ISDB-Tsb API extension should reflect all information needed
+to tune any ISDB-T/ISDB-Tsb hardware. Of course it is possible that some
+very sophisticated devices won't need certain parameters to tune.
+
+The information given here should help application writers to know how
+to handle ISDB-T and ISDB-Tsb hardware using the Linux Digital TV API.
+
+The details given here about ISDB-T and ISDB-Tsb are just enough to
+basically show the dependencies between the needed parameter values, but
+surely some information is left out. For more detailed information see
+the following documents:
+
+ARIB STD-B31 - "Transmission System for Digital Terrestrial Television
+Broadcasting" and
+
+ARIB TR-B14 - "Operational Guidelines for Digital Terrestrial Television
+Broadcasting".
+
+In order to understand the ISDB specific parameters, one has to have
+some knowledge the channel structure in ISDB-T and ISDB-Tsb. I.e. it has
+to be known to the reader that an ISDB-T channel consists of 13
+segments, that it can have up to 3 layer sharing those segments, and
+things like that.
+
+The following parameters are valid for ISDB-T:
+
+-  :ref:`DTV_API_VERSION <DTV-API-VERSION>`
+
+-  :ref:`DTV_DELIVERY_SYSTEM <DTV-DELIVERY-SYSTEM>`
+
+-  :ref:`DTV_TUNE <DTV-TUNE>`
+
+-  :ref:`DTV_CLEAR <DTV-CLEAR>`
+
+-  :ref:`DTV_FREQUENCY <DTV-FREQUENCY>`
+
+-  :ref:`DTV_BANDWIDTH_HZ <DTV-BANDWIDTH-HZ>`
+
+-  :ref:`DTV_INVERSION <DTV-INVERSION>`
+
+-  :ref:`DTV_GUARD_INTERVAL <DTV-GUARD-INTERVAL>`
+
+-  :ref:`DTV_TRANSMISSION_MODE <DTV-TRANSMISSION-MODE>`
+
+-  :ref:`DTV_ISDBT_LAYER_ENABLED <DTV-ISDBT-LAYER-ENABLED>`
+
+-  :ref:`DTV_ISDBT_PARTIAL_RECEPTION <DTV-ISDBT-PARTIAL-RECEPTION>`
+
+-  :ref:`DTV_ISDBT_SOUND_BROADCASTING <DTV-ISDBT-SOUND-BROADCASTING>`
+
+-  :ref:`DTV_ISDBT_SB_SUBCHANNEL_ID <DTV-ISDBT-SB-SUBCHANNEL-ID>`
+
+-  :ref:`DTV_ISDBT_SB_SEGMENT_IDX <DTV-ISDBT-SB-SEGMENT-IDX>`
+
+-  :ref:`DTV_ISDBT_SB_SEGMENT_COUNT <DTV-ISDBT-SB-SEGMENT-COUNT>`
+
+-  :ref:`DTV_ISDBT_LAYERA_FEC <DTV-ISDBT-LAYER-FEC>`
+
+-  :ref:`DTV_ISDBT_LAYERA_MODULATION <DTV-ISDBT-LAYER-MODULATION>`
+
+-  :ref:`DTV_ISDBT_LAYERA_SEGMENT_COUNT <DTV-ISDBT-LAYER-SEGMENT-COUNT>`
+
+-  :ref:`DTV_ISDBT_LAYERA_TIME_INTERLEAVING <DTV-ISDBT-LAYER-TIME-INTERLEAVING>`
+
+-  :ref:`DTV_ISDBT_LAYERB_FEC <DTV-ISDBT-LAYER-FEC>`
+
+-  :ref:`DTV_ISDBT_LAYERB_MODULATION <DTV-ISDBT-LAYER-MODULATION>`
+
+-  :ref:`DTV_ISDBT_LAYERB_SEGMENT_COUNT <DTV-ISDBT-LAYER-SEGMENT-COUNT>`
+
+-  :ref:`DTV_ISDBT_LAYERB_TIME_INTERLEAVING <DTV-ISDBT-LAYER-TIME-INTERLEAVING>`
+
+-  :ref:`DTV_ISDBT_LAYERC_FEC <DTV-ISDBT-LAYER-FEC>`
+
+-  :ref:`DTV_ISDBT_LAYERC_MODULATION <DTV-ISDBT-LAYER-MODULATION>`
+
+-  :ref:`DTV_ISDBT_LAYERC_SEGMENT_COUNT <DTV-ISDBT-LAYER-SEGMENT-COUNT>`
+
+-  :ref:`DTV_ISDBT_LAYERC_TIME_INTERLEAVING <DTV-ISDBT-LAYER-TIME-INTERLEAVING>`
+
+In addition, the :ref:`DTV QoS statistics <frontend-stat-properties>`
+are also valid.
+
+
+.. _atsc-params:
+
+ATSC delivery system
+====================
+
+The following parameters are valid for ATSC:
+
+-  :ref:`DTV_API_VERSION <DTV-API-VERSION>`
+
+-  :ref:`DTV_DELIVERY_SYSTEM <DTV-DELIVERY-SYSTEM>`
+
+-  :ref:`DTV_TUNE <DTV-TUNE>`
+
+-  :ref:`DTV_CLEAR <DTV-CLEAR>`
+
+-  :ref:`DTV_FREQUENCY <DTV-FREQUENCY>`
+
+-  :ref:`DTV_MODULATION <DTV-MODULATION>`
+
+-  :ref:`DTV_BANDWIDTH_HZ <DTV-BANDWIDTH-HZ>`
+
+In addition, the :ref:`DTV QoS statistics <frontend-stat-properties>`
+are also valid.
+
+
+.. _atscmh-params:
+
+ATSC-MH delivery system
+=======================
+
+The following parameters are valid for ATSC-MH:
+
+-  :ref:`DTV_API_VERSION <DTV-API-VERSION>`
+
+-  :ref:`DTV_DELIVERY_SYSTEM <DTV-DELIVERY-SYSTEM>`
+
+-  :ref:`DTV_TUNE <DTV-TUNE>`
+
+-  :ref:`DTV_CLEAR <DTV-CLEAR>`
+
+-  :ref:`DTV_FREQUENCY <DTV-FREQUENCY>`
+
+-  :ref:`DTV_BANDWIDTH_HZ <DTV-BANDWIDTH-HZ>`
+
+-  :ref:`DTV_ATSCMH_FIC_VER <DTV-ATSCMH-FIC-VER>`
+
+-  :ref:`DTV_ATSCMH_PARADE_ID <DTV-ATSCMH-PARADE-ID>`
+
+-  :ref:`DTV_ATSCMH_NOG <DTV-ATSCMH-NOG>`
+
+-  :ref:`DTV_ATSCMH_TNOG <DTV-ATSCMH-TNOG>`
+
+-  :ref:`DTV_ATSCMH_SGN <DTV-ATSCMH-SGN>`
+
+-  :ref:`DTV_ATSCMH_PRC <DTV-ATSCMH-PRC>`
+
+-  :ref:`DTV_ATSCMH_RS_FRAME_MODE <DTV-ATSCMH-RS-FRAME-MODE>`
+
+-  :ref:`DTV_ATSCMH_RS_FRAME_ENSEMBLE <DTV-ATSCMH-RS-FRAME-ENSEMBLE>`
+
+-  :ref:`DTV_ATSCMH_RS_CODE_MODE_PRI <DTV-ATSCMH-RS-CODE-MODE-PRI>`
+
+-  :ref:`DTV_ATSCMH_RS_CODE_MODE_SEC <DTV-ATSCMH-RS-CODE-MODE-SEC>`
+
+-  :ref:`DTV_ATSCMH_SCCC_BLOCK_MODE <DTV-ATSCMH-SCCC-BLOCK-MODE>`
+
+-  :ref:`DTV_ATSCMH_SCCC_CODE_MODE_A <DTV-ATSCMH-SCCC-CODE-MODE-A>`
+
+-  :ref:`DTV_ATSCMH_SCCC_CODE_MODE_B <DTV-ATSCMH-SCCC-CODE-MODE-B>`
+
+-  :ref:`DTV_ATSCMH_SCCC_CODE_MODE_C <DTV-ATSCMH-SCCC-CODE-MODE-C>`
+
+-  :ref:`DTV_ATSCMH_SCCC_CODE_MODE_D <DTV-ATSCMH-SCCC-CODE-MODE-D>`
+
+In addition, the :ref:`DTV QoS statistics <frontend-stat-properties>`
+are also valid.
+
+
+.. _dtmb-params:
+
+DTMB delivery system
+====================
+
+The following parameters are valid for DTMB:
+
+-  :ref:`DTV_API_VERSION <DTV-API-VERSION>`
+
+-  :ref:`DTV_DELIVERY_SYSTEM <DTV-DELIVERY-SYSTEM>`
+
+-  :ref:`DTV_TUNE <DTV-TUNE>`
+
+-  :ref:`DTV_CLEAR <DTV-CLEAR>`
+
+-  :ref:`DTV_FREQUENCY <DTV-FREQUENCY>`
+
+-  :ref:`DTV_MODULATION <DTV-MODULATION>`
+
+-  :ref:`DTV_BANDWIDTH_HZ <DTV-BANDWIDTH-HZ>`
+
+-  :ref:`DTV_INVERSION <DTV-INVERSION>`
+
+-  :ref:`DTV_INNER_FEC <DTV-INNER-FEC>`
+
+-  :ref:`DTV_GUARD_INTERVAL <DTV-GUARD-INTERVAL>`
+
+-  :ref:`DTV_TRANSMISSION_MODE <DTV-TRANSMISSION-MODE>`
+
+-  :ref:`DTV_INTERLEAVING <DTV-INTERLEAVING>`
+
+-  :ref:`DTV_LNA <DTV-LNA>`
+
+In addition, the :ref:`DTV QoS statistics <frontend-stat-properties>`
+are also valid.
diff --git a/Documentation/userspace-api/media/dvb/frontend-stat-properties.rst b/Documentation/userspace-api/media/dvb/frontend-stat-properties.rst
new file mode 100644
index 000000000000..ae6ed5128deb
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/frontend-stat-properties.rst
@@ -0,0 +1,252 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _frontend-stat-properties:
+
+******************************
+Frontend statistics indicators
+******************************
+
+The values are returned via ``dtv_property.stat``. If the property is
+supported, ``dtv_property.stat.len`` is bigger than zero.
+
+For most delivery systems, ``dtv_property.stat.len`` will be 1 if the
+stats is supported, and the properties will return a single value for
+each parameter.
+
+It should be noted, however, that new OFDM delivery systems like ISDB
+can use different modulation types for each group of carriers. On such
+standards, up to 3 groups of statistics can be provided, and
+``dtv_property.stat.len`` is updated to reflect the "global" metrics,
+plus one metric per each carrier group (called "layer" on ISDB).
+
+So, in order to be consistent with other delivery systems, the first
+value at :c:type:`dtv_property.stat.dtv_stats <dtv_stats>` array refers
+to the global metric. The other elements of the array represent each
+layer, starting from layer A(index 1), layer B (index 2) and so on.
+
+The number of filled elements are stored at ``dtv_property.stat.len``.
+
+Each element of the ``dtv_property.stat.dtv_stats`` array consists on
+two elements:
+
+-  ``svalue`` or ``uvalue``, where ``svalue`` is for signed values of
+   the measure (dB measures) and ``uvalue`` is for unsigned values
+   (counters, relative scale)
+
+-  ``scale`` - Scale for the value. It can be:
+
+   -  ``FE_SCALE_NOT_AVAILABLE`` - The parameter is supported by the
+      frontend, but it was not possible to collect it (could be a
+      transitory or permanent condition)
+
+   -  ``FE_SCALE_DECIBEL`` - parameter is a signed value, measured in
+      1/1000 dB
+
+   -  ``FE_SCALE_RELATIVE`` - parameter is a unsigned value, where 0
+      means 0% and 65535 means 100%.
+
+   -  ``FE_SCALE_COUNTER`` - parameter is a unsigned value that counts
+      the occurrence of an event, like bit error, block error, or lapsed
+      time.
+
+
+.. _DTV-STAT-SIGNAL-STRENGTH:
+
+DTV_STAT_SIGNAL_STRENGTH
+========================
+
+Indicates the signal strength level at the analog part of the tuner or
+of the demod.
+
+Possible scales for this metric are:
+
+-  ``FE_SCALE_NOT_AVAILABLE`` - it failed to measure it, or the
+   measurement was not complete yet.
+
+-  ``FE_SCALE_DECIBEL`` - signal strength is in 0.001 dBm units, power
+   measured in miliwatts. This value is generally negative.
+
+-  ``FE_SCALE_RELATIVE`` - The frontend provides a 0% to 100%
+   measurement for power (actually, 0 to 65535).
+
+
+.. _DTV-STAT-CNR:
+
+DTV_STAT_CNR
+============
+
+Indicates the Signal to Noise ratio for the main carrier.
+
+Possible scales for this metric are:
+
+-  ``FE_SCALE_NOT_AVAILABLE`` - it failed to measure it, or the
+   measurement was not complete yet.
+
+-  ``FE_SCALE_DECIBEL`` - Signal/Noise ratio is in 0.001 dB units.
+
+-  ``FE_SCALE_RELATIVE`` - The frontend provides a 0% to 100%
+   measurement for Signal/Noise (actually, 0 to 65535).
+
+
+.. _DTV-STAT-PRE-ERROR-BIT-COUNT:
+
+DTV_STAT_PRE_ERROR_BIT_COUNT
+============================
+
+Measures the number of bit errors before the forward error correction
+(FEC) on the inner coding block (before Viterbi, LDPC or other inner
+code).
+
+This measure is taken during the same interval as
+``DTV_STAT_PRE_TOTAL_BIT_COUNT``.
+
+In order to get the BER (Bit Error Rate) measurement, it should be
+divided by
+:ref:`DTV_STAT_PRE_TOTAL_BIT_COUNT <DTV-STAT-PRE-TOTAL-BIT-COUNT>`.
+
+This measurement is monotonically increased, as the frontend gets more
+bit count measurements. The frontend may reset it when a
+channel/transponder is tuned.
+
+Possible scales for this metric are:
+
+-  ``FE_SCALE_NOT_AVAILABLE`` - it failed to measure it, or the
+   measurement was not complete yet.
+
+-  ``FE_SCALE_COUNTER`` - Number of error bits counted before the inner
+   coding.
+
+
+.. _DTV-STAT-PRE-TOTAL-BIT-COUNT:
+
+DTV_STAT_PRE_TOTAL_BIT_COUNT
+============================
+
+Measures the amount of bits received before the inner code block, during
+the same period as
+:ref:`DTV_STAT_PRE_ERROR_BIT_COUNT <DTV-STAT-PRE-ERROR-BIT-COUNT>`
+measurement was taken.
+
+It should be noted that this measurement can be smaller than the total
+amount of bits on the transport stream, as the frontend may need to
+manually restart the measurement, losing some data between each
+measurement interval.
+
+This measurement is monotonically increased, as the frontend gets more
+bit count measurements. The frontend may reset it when a
+channel/transponder is tuned.
+
+Possible scales for this metric are:
+
+-  ``FE_SCALE_NOT_AVAILABLE`` - it failed to measure it, or the
+   measurement was not complete yet.
+
+-  ``FE_SCALE_COUNTER`` - Number of bits counted while measuring
+   :ref:`DTV_STAT_PRE_ERROR_BIT_COUNT <DTV-STAT-PRE-ERROR-BIT-COUNT>`.
+
+
+.. _DTV-STAT-POST-ERROR-BIT-COUNT:
+
+DTV_STAT_POST_ERROR_BIT_COUNT
+=============================
+
+Measures the number of bit errors after the forward error correction
+(FEC) done by inner code block (after Viterbi, LDPC or other inner
+code).
+
+This measure is taken during the same interval as
+``DTV_STAT_POST_TOTAL_BIT_COUNT``.
+
+In order to get the BER (Bit Error Rate) measurement, it should be
+divided by
+:ref:`DTV_STAT_POST_TOTAL_BIT_COUNT <DTV-STAT-POST-TOTAL-BIT-COUNT>`.
+
+This measurement is monotonically increased, as the frontend gets more
+bit count measurements. The frontend may reset it when a
+channel/transponder is tuned.
+
+Possible scales for this metric are:
+
+-  ``FE_SCALE_NOT_AVAILABLE`` - it failed to measure it, or the
+   measurement was not complete yet.
+
+-  ``FE_SCALE_COUNTER`` - Number of error bits counted after the inner
+   coding.
+
+
+.. _DTV-STAT-POST-TOTAL-BIT-COUNT:
+
+DTV_STAT_POST_TOTAL_BIT_COUNT
+=============================
+
+Measures the amount of bits received after the inner coding, during the
+same period as
+:ref:`DTV_STAT_POST_ERROR_BIT_COUNT <DTV-STAT-POST-ERROR-BIT-COUNT>`
+measurement was taken.
+
+It should be noted that this measurement can be smaller than the total
+amount of bits on the transport stream, as the frontend may need to
+manually restart the measurement, losing some data between each
+measurement interval.
+
+This measurement is monotonically increased, as the frontend gets more
+bit count measurements. The frontend may reset it when a
+channel/transponder is tuned.
+
+Possible scales for this metric are:
+
+-  ``FE_SCALE_NOT_AVAILABLE`` - it failed to measure it, or the
+   measurement was not complete yet.
+
+-  ``FE_SCALE_COUNTER`` - Number of bits counted while measuring
+   :ref:`DTV_STAT_POST_ERROR_BIT_COUNT <DTV-STAT-POST-ERROR-BIT-COUNT>`.
+
+
+.. _DTV-STAT-ERROR-BLOCK-COUNT:
+
+DTV_STAT_ERROR_BLOCK_COUNT
+==========================
+
+Measures the number of block errors after the outer forward error
+correction coding (after Reed-Solomon or other outer code).
+
+This measurement is monotonically increased, as the frontend gets more
+bit count measurements. The frontend may reset it when a
+channel/transponder is tuned.
+
+Possible scales for this metric are:
+
+-  ``FE_SCALE_NOT_AVAILABLE`` - it failed to measure it, or the
+   measurement was not complete yet.
+
+-  ``FE_SCALE_COUNTER`` - Number of error blocks counted after the outer
+   coding.
+
+
+.. _DTV-STAT-TOTAL-BLOCK-COUNT:
+
+DTV-STAT_TOTAL_BLOCK_COUNT
+==========================
+
+Measures the total number of blocks received during the same period as
+:ref:`DTV_STAT_ERROR_BLOCK_COUNT <DTV-STAT-ERROR-BLOCK-COUNT>`
+measurement was taken.
+
+It can be used to calculate the PER indicator, by dividing
+:ref:`DTV_STAT_ERROR_BLOCK_COUNT <DTV-STAT-ERROR-BLOCK-COUNT>` by
+:ref:`DTV-STAT-TOTAL-BLOCK-COUNT`.
+
+Possible scales for this metric are:
+
+-  ``FE_SCALE_NOT_AVAILABLE`` - it failed to measure it, or the
+   measurement was not complete yet.
+
+-  ``FE_SCALE_COUNTER`` - Number of blocks counted while measuring
+   :ref:`DTV_STAT_ERROR_BLOCK_COUNT <DTV-STAT-ERROR-BLOCK-COUNT>`.
diff --git a/Documentation/userspace-api/media/dvb/frontend.rst b/Documentation/userspace-api/media/dvb/frontend.rst
new file mode 100644
index 000000000000..41ad519ca502
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/frontend.rst
@@ -0,0 +1,63 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _dvb_frontend:
+
+#######################
+Digital TV Frontend API
+#######################
+
+The Digital TV frontend API was designed to support three groups of delivery
+systems: Terrestrial, cable and Satellite. Currently, the following
+delivery systems are supported:
+
+-  Terrestrial systems: DVB-T, DVB-T2, ATSC, ATSC M/H, ISDB-T, DVB-H,
+   DTMB, CMMB
+
+-  Cable systems: DVB-C Annex A/C, ClearQAM (DVB-C Annex B)
+
+-  Satellite systems: DVB-S, DVB-S2, DVB Turbo, ISDB-S, DSS
+
+The Digital TV frontend controls several sub-devices including:
+
+-  Tuner
+
+-  Digital TV demodulator
+
+-  Low noise amplifier (LNA)
+
+-  Satellite Equipment Control (SEC) [#f1]_.
+
+The frontend can be accessed through ``/dev/dvb/adapter?/frontend?``.
+Data types and ioctl definitions can be accessed by including
+``linux/dvb/frontend.h`` in your application.
+
+.. note::
+
+   Transmission via the internet (DVB-IP) and MMT (MPEG Media Transport)
+   is not yet handled by this API but a future extension is possible.
+
+.. [#f1]
+
+   On Satellite systems, the API support for the Satellite Equipment
+   Control (SEC) allows to power control and to send/receive signals to
+   control the antenna subsystem, selecting the polarization and choosing
+   the Intermediate Frequency IF) of the Low Noise Block Converter Feed
+   Horn (LNBf). It supports the DiSEqC and V-SEC protocols. The DiSEqC
+   (digital SEC) specification is available at
+   `Eutelsat <http://www.eutelsat.com/satellites/4_5_5.html>`__.
+
+
+.. toctree::
+    :maxdepth: 1
+
+    query-dvb-frontend-info
+    dvb-fe-read-status
+    dvbproperty
+    frontend_fcalls
diff --git a/Documentation/userspace-api/media/dvb/frontend_f_close.rst b/Documentation/userspace-api/media/dvb/frontend_f_close.rst
new file mode 100644
index 000000000000..582e19a83c1a
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/frontend_f_close.rst
@@ -0,0 +1,57 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _frontend_f_close:
+
+***************************
+Digital TV frontend close()
+***************************
+
+Name
+====
+
+fe-close - Close a frontend device
+
+
+Synopsis
+========
+
+.. code-block:: c
+
+    #include <unistd.h>
+
+
+.. c:function:: int close( int fd )
+    :name: dvb-fe-close
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :c:func:`open() <dvb-fe-open>`.
+
+
+Description
+===========
+
+This system call closes a previously opened front-end device. After
+closing a front-end device, its corresponding hardware might be powered
+down automatically.
+
+
+Return Value
+============
+
+On success 0 is returned.
+
+On error -1 is returned, and the ``errno`` variable is set
+appropriately.
+
+Generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/userspace-api/media/dvb/frontend_f_open.rst b/Documentation/userspace-api/media/dvb/frontend_f_open.rst
new file mode 100644
index 000000000000..0be3b249d33b
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/frontend_f_open.rst
@@ -0,0 +1,117 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _frontend_f_open:
+
+***************************
+Digital TV frontend open()
+***************************
+
+Name
+====
+
+fe-open - Open a frontend device
+
+
+Synopsis
+========
+
+.. code-block:: c
+
+    #include <fcntl.h>
+
+
+.. c:function:: int open( const char *device_name, int flags )
+    :name: dvb-fe-open
+
+Arguments
+=========
+
+``device_name``
+    Device to be opened.
+
+``flags``
+    Open flags. Access can either be ``O_RDWR`` or ``O_RDONLY``.
+
+    Multiple opens are allowed with ``O_RDONLY``. In this mode, only
+    query and read ioctls are allowed.
+
+    Only one open is allowed in ``O_RDWR``. In this mode, all ioctls are
+    allowed.
+
+    When the ``O_NONBLOCK`` flag is given, the system calls may return
+    ``EAGAIN`` error code when no data is available or when the device
+    driver is temporarily busy.
+
+    Other flags have no effect.
+
+
+Description
+===========
+
+This system call opens a named frontend device
+(``/dev/dvb/adapter?/frontend?``) for subsequent use. Usually the first
+thing to do after a successful open is to find out the frontend type
+with :ref:`FE_GET_INFO`.
+
+The device can be opened in read-only mode, which only allows monitoring
+of device status and statistics, or read/write mode, which allows any
+kind of use (e.g. performing tuning operations.)
+
+In a system with multiple front-ends, it is usually the case that
+multiple devices cannot be open in read/write mode simultaneously. As
+long as a front-end device is opened in read/write mode, other open()
+calls in read/write mode will either fail or block, depending on whether
+non-blocking or blocking mode was specified. A front-end device opened
+in blocking mode can later be put into non-blocking mode (and vice
+versa) using the F_SETFL command of the fcntl system call. This is a
+standard system call, documented in the Linux manual page for fcntl.
+When an open() call has succeeded, the device will be ready for use in
+the specified mode. This implies that the corresponding hardware is
+powered up, and that other front-ends may have been powered down to make
+that possible.
+
+
+Return Value
+============
+
+On success :ref:`open() <frontend_f_open>` returns the new file descriptor.
+On error, -1 is returned, and the ``errno`` variable is set appropriately.
+
+Possible error codes are:
+
+
+On success 0 is returned, and :c:type:`ca_slot_info` is filled.
+
+On error -1 is returned, and the ``errno`` variable is set
+appropriately.
+
+.. tabularcolumns:: |p{2.5cm}|p{15.0cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths: 1 16
+
+    -  - ``EPERM``
+       -  The caller has no permission to access the device.
+
+    -  - ``EBUSY``
+       -  The the device driver is already in use.
+
+    -  - ``EMFILE``
+       -  The process already has the maximum number of files open.
+
+    -  - ``ENFILE``
+       -  The limit on the total number of files open on the system has been
+	  reached.
+
+
+The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/userspace-api/media/dvb/frontend_fcalls.rst b/Documentation/userspace-api/media/dvb/frontend_fcalls.rst
new file mode 100644
index 000000000000..2b5e7a4dba9e
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/frontend_fcalls.rst
@@ -0,0 +1,31 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _frontend_fcalls:
+
+#######################
+Frontend Function Calls
+#######################
+
+.. toctree::
+    :maxdepth: 1
+
+    frontend_f_open
+    frontend_f_close
+    fe-get-info
+    fe-read-status
+    fe-get-property
+    fe-diseqc-reset-overload
+    fe-diseqc-send-master-cmd
+    fe-diseqc-recv-slave-reply
+    fe-diseqc-send-burst
+    fe-set-tone
+    fe-set-voltage
+    fe-enable-high-lnb-voltage
+    fe-set-frontend-tune-mode
diff --git a/Documentation/userspace-api/media/dvb/frontend_legacy_api.rst b/Documentation/userspace-api/media/dvb/frontend_legacy_api.rst
new file mode 100644
index 000000000000..1bd804f9b364
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/frontend_legacy_api.rst
@@ -0,0 +1,45 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _frontend_legacy_types:
+
+Frontend Legacy Data Types
+==========================
+
+
+.. toctree::
+    :maxdepth: 1
+
+    fe-type-t
+    fe-bandwidth-t
+    dvb-frontend-parameters
+    dvb-frontend-event
+
+
+.. _frontend_legacy_fcalls:
+
+Frontend Legacy Function Calls
+==============================
+
+Those functions are defined at DVB version 3. The support is kept in the
+kernel due to compatibility issues only. Their usage is strongly not
+recommended
+
+
+.. toctree::
+    :maxdepth: 1
+
+    fe-read-ber
+    fe-read-snr
+    fe-read-signal-strength
+    fe-read-uncorrected-blocks
+    fe-set-frontend
+    fe-get-frontend
+    fe-get-event
+    fe-dishnetwork-send-legacy-cmd
diff --git a/Documentation/userspace-api/media/dvb/frontend_legacy_dvbv3_api.rst b/Documentation/userspace-api/media/dvb/frontend_legacy_dvbv3_api.rst
new file mode 100644
index 000000000000..29ad0f9b90a4
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/frontend_legacy_dvbv3_api.rst
@@ -0,0 +1,25 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _frontend_legacy_dvbv3_api:
+
+***********************************************
+Digital TV Frontend legacy API (a. k. a. DVBv3)
+***********************************************
+
+The usage of this API is deprecated, as it doesn't support all digital
+TV standards, doesn't provide good statistics measurements and provides
+incomplete information. This is kept only to support legacy
+applications.
+
+
+.. toctree::
+    :maxdepth: 1
+
+    frontend_legacy_api
diff --git a/Documentation/userspace-api/media/dvb/headers.rst b/Documentation/userspace-api/media/dvb/headers.rst
new file mode 100644
index 000000000000..ffd8f432484a
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/headers.rst
@@ -0,0 +1,30 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+****************************
+Digital TV uAPI header files
+****************************
+
+Digital TV uAPI headers
+***********************
+
+.. kernel-include:: $BUILDDIR/frontend.h.rst
+
+.. kernel-include:: $BUILDDIR/dmx.h.rst
+
+.. kernel-include:: $BUILDDIR/ca.h.rst
+
+.. kernel-include:: $BUILDDIR/net.h.rst
+
+Legacy uAPI
+***********
+
+.. kernel-include:: $BUILDDIR/audio.h.rst
+
+.. kernel-include:: $BUILDDIR/video.h.rst
diff --git a/Documentation/userspace-api/media/dvb/intro.rst b/Documentation/userspace-api/media/dvb/intro.rst
new file mode 100644
index 000000000000..f1235ef4599e
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/intro.rst
@@ -0,0 +1,190 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _dvb_introdution:
+
+************
+Introduction
+************
+
+
+.. _requisites:
+
+What you need to know
+=====================
+
+The reader of this document is required to have some knowledge in the
+area of digital video broadcasting (Digital TV) and should be familiar with
+part I of the MPEG2 specification ISO/IEC 13818 (aka ITU-T H.222), i.e
+you should know what a program/transport stream (PS/TS) is and what is
+meant by a packetized elementary stream (PES) or an I-frame.
+
+Various Digital TV standards documents are available for download at:
+
+- European standards (DVB): http://www.dvb.org and/or http://www.etsi.org.
+- American standards (ATSC): https://www.atsc.org/standards/
+- Japanese standards (ISDB): http://www.dibeg.org/
+
+It is also necessary to know how to access Linux devices and how to
+use ioctl calls. This also includes the knowledge of C or C++.
+
+
+.. _history:
+
+History
+=======
+
+The first API for Digital TV cards we used at Convergence in late 1999 was an
+extension of the Video4Linux API which was primarily developed for frame
+grabber cards. As such it was not really well suited to be used for Digital
+TV cards and their new features like recording MPEG streams and filtering
+several section and PES data streams at the same time.
+
+In early 2000, Convergence was approached by Nokia with a proposal for a new
+standard Linux Digital TV API. As a commitment to the development of terminals
+based on open standards, Nokia and Convergence made it available to all
+Linux developers and published it on https://linuxtv.org in September
+2000. With the Linux driver for the Siemens/Hauppauge DVB PCI card,
+Convergence provided a first implementation of the Linux Digital TV API.
+Convergence was the maintainer of the Linux Digital TV API in the early
+days.
+
+Now, the API is maintained by the LinuxTV community (i.e. you, the reader
+of this document). The Linux  Digital TV API is constantly reviewed and
+improved together with the improvements at the subsystem's core at the
+Kernel.
+
+
+.. _overview:
+
+Overview
+========
+
+
+.. _stb_components:
+
+.. kernel-figure:: dvbstb.svg
+    :alt:   dvbstb.svg
+    :align: center
+
+    Components of a Digital TV card/STB
+
+A Digital TV card or set-top-box (STB) usually consists of the
+following main hardware components:
+
+Frontend consisting of tuner and digital TV demodulator
+   Here the raw signal reaches the digital TV hardware from a satellite dish or
+   antenna or directly from cable. The frontend down-converts and
+   demodulates this signal into an MPEG transport stream (TS). In case
+   of a satellite frontend, this includes a facility for satellite
+   equipment control (SEC), which allows control of LNB polarization,
+   multi feed switches or dish rotors.
+
+Conditional Access (CA) hardware like CI adapters and smartcard slots
+   The complete TS is passed through the CA hardware. Programs to which
+   the user has access (controlled by the smart card) are decoded in
+   real time and re-inserted into the TS.
+
+   .. note::
+
+      Not every digital TV hardware provides conditional access hardware.
+
+Demultiplexer which filters the incoming Digital TV MPEG-TS stream
+   The demultiplexer splits the TS into its components like audio and
+   video streams. Besides usually several of such audio and video
+   streams it also contains data streams with information about the
+   programs offered in this or other streams of the same provider.
+
+Audio and video decoder
+   The main targets of the demultiplexer are audio and video
+   decoders. After decoding, they pass on the uncompressed audio and
+   video to the computer screen or to a TV set.
+
+   .. note::
+
+      Modern hardware usually doesn't have a separate decoder hardware, as
+      such functionality can be provided by the main CPU, by the graphics
+      adapter of the system or by a signal processing hardware embedded on
+      a Systems on a Chip (SoC) integrated circuit.
+
+      It may also not be needed for certain usages (e.g. for data-only
+      uses like “internet over satellite”).
+
+:ref:`stb_components` shows a crude schematic of the control and data
+flow between those components.
+
+
+
+.. _dvb_devices:
+
+Linux Digital TV Devices
+========================
+
+The Linux Digital TV API lets you control these hardware components through
+currently six Unix-style character devices for video, audio, frontend,
+demux, CA and IP-over-DVB networking. The video and audio devices
+control the MPEG2 decoder hardware, the frontend device the tuner and
+the Digital TV demodulator. The demux device gives you control over the PES
+and section filters of the hardware. If the hardware does not support
+filtering these filters can be implemented in software. Finally, the CA
+device controls all the conditional access capabilities of the hardware.
+It can depend on the individual security requirements of the platform,
+if and how many of the CA functions are made available to the
+application through this device.
+
+All devices can be found in the ``/dev`` tree under ``/dev/dvb``. The
+individual devices are called:
+
+-  ``/dev/dvb/adapterN/audioM``,
+
+-  ``/dev/dvb/adapterN/videoM``,
+
+-  ``/dev/dvb/adapterN/frontendM``,
+
+-  ``/dev/dvb/adapterN/netM``,
+
+-  ``/dev/dvb/adapterN/demuxM``,
+
+-  ``/dev/dvb/adapterN/dvrM``,
+
+-  ``/dev/dvb/adapterN/caM``,
+
+where ``N`` enumerates the Digital TV cards in a system starting from 0, and
+``M`` enumerates the devices of each type within each adapter, starting
+from 0, too. We will omit the “``/dev/dvb/adapterN/``\ ” in the further
+discussion of these devices.
+
+More details about the data structures and function calls of all the
+devices are described in the following chapters.
+
+
+.. _include_files:
+
+API include files
+=================
+
+For each of the Digital TV devices a corresponding include file exists. The
+Digital TV API include files should be included in application sources with a
+partial path like:
+
+
+.. code-block:: c
+
+	#include <linux/dvb/ca.h>
+
+	#include <linux/dvb/dmx.h>
+
+	#include <linux/dvb/frontend.h>
+
+	#include <linux/dvb/net.h>
+
+
+To enable applications to support different API version, an additional
+include file ``linux/dvb/version.h`` exists, which defines the constant
+``DVB_API_VERSION``. This document describes ``DVB_API_VERSION 5.10``.
diff --git a/Documentation/userspace-api/media/dvb/legacy_dvb_apis.rst b/Documentation/userspace-api/media/dvb/legacy_dvb_apis.rst
new file mode 100644
index 000000000000..17c3b062afb3
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/legacy_dvb_apis.rst
@@ -0,0 +1,39 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _legacy_dvb_apis:
+
+***************************
+Digital TV Deprecated APIs
+***************************
+
+The APIs described here **should not** be used on new drivers or applications.
+
+The DVBv3 frontend API has issues with new delivery systems, including
+DVB-S2, DVB-T2, ISDB, etc.
+
+There's just one driver for a very legacy hardware using the Digital TV
+audio and video APIs. No modern drivers should use it. Instead, audio and
+video should be using the V4L2 and ALSA APIs, and the pipelines should
+be set via the Media Controller API.
+
+.. attention::
+
+   The APIs described here doesn't necessarily reflect the current
+   code implementation, as this section of the document was written
+   for DVB version 1, while the code reflects DVB version 3
+   implementation.
+
+
+.. toctree::
+    :maxdepth: 1
+
+    frontend_legacy_dvbv3_api
+    video
+    audio
diff --git a/Documentation/userspace-api/media/dvb/net-add-if.rst b/Documentation/userspace-api/media/dvb/net-add-if.rst
new file mode 100644
index 000000000000..e75ec4d80a08
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/net-add-if.rst
@@ -0,0 +1,60 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _NET_ADD_IF:
+
+****************
+ioctl NET_ADD_IF
+****************
+
+Name
+====
+
+NET_ADD_IF - Creates a new network interface for a given Packet ID.
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, NET_ADD_IF, struct dvb_net_if *net_if )
+    :name: NET_ADD_IF
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <frontend_f_open>`.
+
+``net_if``
+    pointer to struct :c:type:`dvb_net_if`
+
+
+Description
+===========
+
+The NET_ADD_IF ioctl system call selects the Packet ID (PID) that
+contains a TCP/IP traffic, the type of encapsulation to be used (MPE or
+ULE) and the interface number for the new interface to be created. When
+the system call successfully returns, a new virtual network interface is
+created.
+
+The struct :c:type:`dvb_net_if`::ifnum field will be
+filled with the number of the created interface.
+
+Return Value
+============
+
+On success 0 is returned, and :c:type:`ca_slot_info` is filled.
+
+On error -1 is returned, 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/userspace-api/media/dvb/net-get-if.rst b/Documentation/userspace-api/media/dvb/net-get-if.rst
new file mode 100644
index 000000000000..c5421d9a8c0b
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/net-get-if.rst
@@ -0,0 +1,59 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _NET_GET_IF:
+
+****************
+ioctl NET_GET_IF
+****************
+
+Name
+====
+
+NET_GET_IF - Read the configuration data of an interface created via - :ref:`NET_ADD_IF <net>`.
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, NET_GET_IF, struct dvb_net_if *net_if )
+    :name: NET_GET_IF
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <frontend_f_open>`.
+
+``net_if``
+    pointer to struct :c:type:`dvb_net_if`
+
+
+Description
+===========
+
+The NET_GET_IF ioctl uses the interface number given by the struct
+:c:type:`dvb_net_if`::ifnum field and fills the content of
+struct :c:type:`dvb_net_if` with the packet ID and
+encapsulation type used on such interface. If the interface was not
+created yet with :ref:`NET_ADD_IF <net>`, it will return -1 and fill
+the ``errno`` with ``EINVAL`` error code.
+
+
+Return Value
+============
+
+On success 0 is returned, and :c:type:`ca_slot_info` is filled.
+
+On error -1 is returned, 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/userspace-api/media/dvb/net-remove-if.rst b/Documentation/userspace-api/media/dvb/net-remove-if.rst
new file mode 100644
index 000000000000..d530559f66f1
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/net-remove-if.rst
@@ -0,0 +1,55 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _NET_REMOVE_IF:
+
+*******************
+ioctl NET_REMOVE_IF
+*******************
+
+Name
+====
+
+NET_REMOVE_IF - Removes a network interface.
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, NET_REMOVE_IF, int ifnum )
+    :name: NET_REMOVE_IF
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <frontend_f_open>`.
+
+``net_if``
+    number of the interface to be removed
+
+
+Description
+===========
+
+The NET_REMOVE_IF ioctl deletes an interface previously created via
+:ref:`NET_ADD_IF <net>`.
+
+
+Return Value
+============
+
+On success 0 is returned, and :c:type:`ca_slot_info` is filled.
+
+On error -1 is returned, 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/userspace-api/media/dvb/net-types.rst b/Documentation/userspace-api/media/dvb/net-types.rst
new file mode 100644
index 000000000000..94323cffe8af
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/net-types.rst
@@ -0,0 +1,16 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _net_types:
+
+**************
+Net Data Types
+**************
+
+.. kernel-doc:: include/uapi/linux/dvb/net.h
diff --git a/Documentation/userspace-api/media/dvb/net.rst b/Documentation/userspace-api/media/dvb/net.rst
new file mode 100644
index 000000000000..084f33d1ba28
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/net.rst
@@ -0,0 +1,48 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _net:
+
+######################
+Digital TV Network API
+######################
+
+The Digital TV net device controls the mapping of data packages that are part
+of a transport stream to be mapped into a virtual network interface,
+visible through the standard Linux network protocol stack.
+
+Currently, two encapsulations are supported:
+
+-  `Multi Protocol Encapsulation (MPE) <http://en.wikipedia.org/wiki/Multiprotocol_Encapsulation>`__
+
+-  `Ultra Lightweight Encapsulation (ULE) <http://en.wikipedia.org/wiki/Unidirectional_Lightweight_Encapsulation>`__
+
+In order to create the Linux virtual network interfaces, an application
+needs to tell to the Kernel what are the PIDs and the encapsulation
+types that are present on the transport stream. This is done through
+``/dev/dvb/adapter?/net?`` device node. The data will be available via
+virtual ``dvb?_?`` network interfaces, and will be controlled/routed via
+the standard ip tools (like ip, route, netstat, ifconfig, etc).
+
+Data types and and ioctl definitions are defined via ``linux/dvb/net.h``
+header.
+
+
+.. _net_fcalls:
+
+Digital TV net Function Calls
+#############################
+
+.. toctree::
+    :maxdepth: 1
+
+    net-types
+    net-add-if
+    net-remove-if
+    net-get-if
diff --git a/Documentation/userspace-api/media/dvb/query-dvb-frontend-info.rst b/Documentation/userspace-api/media/dvb/query-dvb-frontend-info.rst
new file mode 100644
index 000000000000..d854ccf42ccf
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/query-dvb-frontend-info.rst
@@ -0,0 +1,20 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _query-dvb-frontend-info:
+
+*****************************
+Querying frontend information
+*****************************
+
+Usually, the first thing to do when the frontend is opened is to check
+the frontend capabilities. This is done using
+:ref:`FE_GET_INFO`. This ioctl will enumerate the
+Digital TV API version and other characteristics about the frontend, and can
+be opened either in read only or read/write mode.
diff --git a/Documentation/userspace-api/media/dvb/video-clear-buffer.rst b/Documentation/userspace-api/media/dvb/video-clear-buffer.rst
new file mode 100644
index 000000000000..ba7a13302862
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/video-clear-buffer.rst
@@ -0,0 +1,63 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDEO_CLEAR_BUFFER:
+
+==================
+VIDEO_CLEAR_BUFFER
+==================
+
+Name
+----
+
+VIDEO_CLEAR_BUFFER
+
+.. attention:: This ioctl is deprecated.
+
+Synopsis
+--------
+
+.. c:function:: int ioctl(fd, VIDEO_CLEAR_BUFFER)
+    :name: VIDEO_CLEAR_BUFFER
+
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+    -  .. row 2
+
+       -  int request
+
+       -  Equals VIDEO_CLEAR_BUFFER for this command.
+
+
+Description
+-----------
+
+This ioctl call clears all video buffers in the driver and in the
+decoder hardware.
+
+
+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/userspace-api/media/dvb/video-command.rst b/Documentation/userspace-api/media/dvb/video-command.rst
new file mode 100644
index 000000000000..d96d764d0eef
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/video-command.rst
@@ -0,0 +1,105 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDEO_COMMAND:
+
+=============
+VIDEO_COMMAND
+=============
+
+Name
+----
+
+VIDEO_COMMAND
+
+.. attention:: This ioctl is deprecated.
+
+Synopsis
+--------
+
+.. c:function:: int ioctl(int fd, VIDEO_COMMAND, struct video_command *cmd)
+    :name: VIDEO_COMMAND
+
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+    -  .. row 2
+
+       -  int request
+
+       -  Equals VIDEO_COMMAND for this command.
+
+    -  .. row 3
+
+       -  struct video_command \*cmd
+
+       -  Commands the decoder.
+
+
+Description
+-----------
+
+This ioctl is obsolete. Do not use in new drivers. For V4L2 decoders
+this ioctl has been replaced by the
+:ref:`VIDIOC_DECODER_CMD` ioctl.
+
+This ioctl commands the decoder. The ``video_command`` struct is a
+subset of the ``v4l2_decoder_cmd`` struct, so refer to the
+:ref:`VIDIOC_DECODER_CMD` documentation for
+more information.
+
+.. c:type:: struct video_command
+
+.. code-block:: c
+
+	/* The structure must be zeroed before use by the application
+	This ensures it can be extended safely in the future. */
+	struct video_command {
+		__u32 cmd;
+		__u32 flags;
+		union {
+			struct {
+				__u64 pts;
+			} stop;
+
+			struct {
+				/* 0 or 1000 specifies normal speed,
+				1 specifies forward single stepping,
+				-1 specifies backward single stepping,
+				>1: playback at speed/1000 of the normal speed,
+				<-1: reverse playback at (-speed/1000) of the normal speed. */
+				__s32 speed;
+				__u32 format;
+			} play;
+
+			struct {
+				__u32 data[16];
+			} raw;
+		};
+	};
+
+
+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/userspace-api/media/dvb/video-continue.rst b/Documentation/userspace-api/media/dvb/video-continue.rst
new file mode 100644
index 000000000000..bb18514ac5e9
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/video-continue.rst
@@ -0,0 +1,66 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDEO_CONTINUE:
+
+==============
+VIDEO_CONTINUE
+==============
+
+Name
+----
+
+VIDEO_CONTINUE
+
+.. attention:: This ioctl is deprecated.
+
+Synopsis
+--------
+
+.. c:function:: int ioctl(fd, VIDEO_CONTINUE)
+    :name: VIDEO_CONTINUE
+
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+    -  .. row 2
+
+       -  int request
+
+       -  Equals VIDEO_CONTINUE for this command.
+
+
+Description
+-----------
+
+This ioctl is for Digital TV devices only. To control a V4L2 decoder use the
+V4L2 :ref:`VIDIOC_DECODER_CMD` instead.
+
+This ioctl call restarts decoding and playing processes of the video
+stream which was played before a call to VIDEO_FREEZE was made.
+
+
+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/userspace-api/media/dvb/video-fast-forward.rst b/Documentation/userspace-api/media/dvb/video-fast-forward.rst
new file mode 100644
index 000000000000..1f6ec89574d1
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/video-fast-forward.rst
@@ -0,0 +1,83 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDEO_FAST_FORWARD:
+
+==================
+VIDEO_FAST_FORWARD
+==================
+
+Name
+----
+
+VIDEO_FAST_FORWARD
+
+.. attention:: This ioctl is deprecated.
+
+Synopsis
+--------
+
+.. c:function:: int ioctl(fd, VIDEO_FAST_FORWARD, int nFrames)
+    :name: VIDEO_FAST_FORWARD
+
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+    -  .. row 2
+
+       -  int request
+
+       -  Equals VIDEO_FAST_FORWARD for this command.
+
+    -  .. row 3
+
+       -  int nFrames
+
+       -  The number of frames to skip.
+
+
+Description
+-----------
+
+This ioctl call asks the Video Device to skip decoding of N number of
+I-frames. This call can only be used if VIDEO_SOURCE_MEMORY is
+selected.
+
+
+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.
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  ``EPERM``
+
+       -  Mode VIDEO_SOURCE_MEMORY not selected.
diff --git a/Documentation/userspace-api/media/dvb/video-fclose.rst b/Documentation/userspace-api/media/dvb/video-fclose.rst
new file mode 100644
index 000000000000..f9d2a8ebe4a4
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/video-fclose.rst
@@ -0,0 +1,62 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _video_fclose:
+
+=================
+dvb video close()
+=================
+
+Name
+----
+
+dvb video close()
+
+.. attention:: This ioctl is deprecated.
+
+Synopsis
+--------
+
+.. c:function:: int close(int fd)
+
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+
+Description
+-----------
+
+This system call closes a previously opened video device.
+
+
+Return Value
+------------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  ``EBADF``
+
+       -  fd is not a valid open file descriptor.
diff --git a/Documentation/userspace-api/media/dvb/video-fopen.rst b/Documentation/userspace-api/media/dvb/video-fopen.rst
new file mode 100644
index 000000000000..a418cf6d772e
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/video-fopen.rst
@@ -0,0 +1,122 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _video_fopen:
+
+================
+dvb video open()
+================
+
+Name
+----
+
+dvb video open()
+
+.. attention:: This ioctl is deprecated.
+
+Synopsis
+--------
+
+.. c:function:: int open(const char *deviceName, int flags)
+
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  const char \*deviceName
+
+       -  Name of specific video device.
+
+    -  .. row 2
+
+       -  int flags
+
+       -  A bit-wise OR of the following flags:
+
+    -  .. row 3
+
+       -
+       -  O_RDONLY read-only access
+
+    -  .. row 4
+
+       -
+       -  O_RDWR read/write access
+
+    -  .. row 5
+
+       -
+       -  O_NONBLOCK open in non-blocking mode
+
+    -  .. row 6
+
+       -
+       -  (blocking mode is the default)
+
+
+Description
+-----------
+
+This system call opens a named video device (e.g.
+/dev/dvb/adapter0/video0) for subsequent use.
+
+When an open() call has succeeded, the device will be ready for use. The
+significance of blocking or non-blocking mode is described in the
+documentation for functions where there is a difference. It does not
+affect the semantics of the open() call itself. A device opened in
+blocking mode can later be put into non-blocking mode (and vice versa)
+using the F_SETFL command of the fcntl system call. This is a standard
+system call, documented in the Linux manual page for fcntl. Only one
+user can open the Video Device in O_RDWR mode. All other attempts to
+open the device in this mode will fail, and an error-code will be
+returned. If the Video Device is opened in O_RDONLY mode, the only
+ioctl call that can be used is VIDEO_GET_STATUS. All other call will
+return an error code.
+
+
+Return Value
+------------
+
+.. tabularcolumns:: |p{2.5cm}|p{15.0cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  ``ENODEV``
+
+       -  Device driver not loaded/available.
+
+    -  .. row 2
+
+       -  ``EINTERNAL``
+
+       -  Internal error.
+
+    -  .. row 3
+
+       -  ``EBUSY``
+
+       -  Device or resource busy.
+
+    -  .. row 4
+
+       -  ``EINVAL``
+
+       -  Invalid argument.
diff --git a/Documentation/userspace-api/media/dvb/video-freeze.rst b/Documentation/userspace-api/media/dvb/video-freeze.rst
new file mode 100644
index 000000000000..46f287faa7fe
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/video-freeze.rst
@@ -0,0 +1,70 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDEO_FREEZE:
+
+============
+VIDEO_FREEZE
+============
+
+Name
+----
+
+VIDEO_FREEZE
+
+.. attention:: This ioctl is deprecated.
+
+Synopsis
+--------
+
+.. c:function:: int ioctl(fd, VIDEO_FREEZE)
+    :name: VIDEO_FREEZE
+
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+    -  .. row 2
+
+       -  int request
+
+       -  Equals VIDEO_FREEZE for this command.
+
+
+Description
+-----------
+
+This ioctl is for Digital TV devices only. To control a V4L2 decoder use the
+V4L2 :ref:`VIDIOC_DECODER_CMD` instead.
+
+This ioctl call suspends the live video stream being played. Decoding
+and playing are frozen. It is then possible to restart the decoding and
+playing process of the video stream using the VIDEO_CONTINUE command.
+If VIDEO_SOURCE_MEMORY is selected in the ioctl call
+VIDEO_SELECT_SOURCE, the Digital TV subsystem will not decode any more data
+until the ioctl call VIDEO_CONTINUE or VIDEO_PLAY is performed.
+
+
+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/userspace-api/media/dvb/video-fwrite.rst b/Documentation/userspace-api/media/dvb/video-fwrite.rst
new file mode 100644
index 000000000000..08dfafa9c6a1
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/video-fwrite.rst
@@ -0,0 +1,90 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _video_fwrite:
+
+=================
+dvb video write()
+=================
+
+Name
+----
+
+dvb video write()
+
+.. attention:: This ioctl is deprecated.
+
+Synopsis
+--------
+
+.. c:function:: size_t write(int fd, const void *buf, size_t count)
+
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+    -  .. row 2
+
+       -  void \*buf
+
+       -  Pointer to the buffer containing the PES data.
+
+    -  .. row 3
+
+       -  size_t count
+
+       -  Size of buf.
+
+
+Description
+-----------
+
+This system call can only be used if VIDEO_SOURCE_MEMORY is selected
+in the ioctl call VIDEO_SELECT_SOURCE. The data provided shall be in
+PES format, unless the capability allows other formats. If O_NONBLOCK
+is not specified the function will block until buffer space is
+available. The amount of data to be transferred is implied by count.
+
+
+Return Value
+------------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  ``EPERM``
+
+       -  Mode VIDEO_SOURCE_MEMORY not selected.
+
+    -  .. row 2
+
+       -  ``ENOMEM``
+
+       -  Attempted to write more data than the internal buffer can hold.
+
+    -  .. row 3
+
+       -  ``EBADF``
+
+       -  fd is not a valid open file descriptor.
diff --git a/Documentation/userspace-api/media/dvb/video-get-capabilities.rst b/Documentation/userspace-api/media/dvb/video-get-capabilities.rst
new file mode 100644
index 000000000000..f6f19df5a3b4
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/video-get-capabilities.rst
@@ -0,0 +1,70 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDEO_GET_CAPABILITIES:
+
+======================
+VIDEO_GET_CAPABILITIES
+======================
+
+Name
+----
+
+VIDEO_GET_CAPABILITIES
+
+.. attention:: This ioctl is deprecated.
+
+Synopsis
+--------
+
+.. c:function:: int ioctl(fd, VIDEO_GET_CAPABILITIES, unsigned int *cap)
+    :name: VIDEO_GET_CAPABILITIES
+
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+    -  .. row 2
+
+       -  int request
+
+       -  Equals VIDEO_GET_CAPABILITIES for this command.
+
+    -  .. row 3
+
+       -  unsigned int \*cap
+
+       -  Pointer to a location where to store the capability information.
+
+
+Description
+-----------
+
+This ioctl call asks the video device about its decoding capabilities.
+On success it returns and integer which has bits set according to the
+defines in section ??.
+
+
+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/userspace-api/media/dvb/video-get-event.rst b/Documentation/userspace-api/media/dvb/video-get-event.rst
new file mode 100644
index 000000000000..6db8e6337c4f
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/video-get-event.rst
@@ -0,0 +1,114 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDEO_GET_EVENT:
+
+===============
+VIDEO_GET_EVENT
+===============
+
+Name
+----
+
+VIDEO_GET_EVENT
+
+.. attention:: This ioctl is deprecated.
+
+Synopsis
+--------
+
+.. c:function:: int ioctl(fd, VIDEO_GET_EVENT, struct video_event *ev)
+    :name: VIDEO_GET_EVENT
+
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+    -  .. row 2
+
+       -  int request
+
+       -  Equals VIDEO_GET_EVENT for this command.
+
+    -  .. row 3
+
+       -  struct video_event \*ev
+
+       -  Points to the location where the event, if any, is to be stored.
+
+
+Description
+-----------
+
+This ioctl is for Digital TV devices only. To get events from a V4L2 decoder
+use the V4L2 :ref:`VIDIOC_DQEVENT` ioctl instead.
+
+This ioctl call returns an event of type video_event if available. If
+an event is not available, the behavior depends on whether the device is
+in blocking or non-blocking mode. In the latter case, the call fails
+immediately with errno set to ``EWOULDBLOCK``. In the former case, the call
+blocks until an event becomes available. The standard Linux poll()
+and/or select() system calls can be used with the device file descriptor
+to watch for new events. For select(), the file descriptor should be
+included in the exceptfds argument, and for poll(), POLLPRI should be
+specified as the wake-up condition. Read-only permissions are sufficient
+for this ioctl call.
+
+.. c:type:: video_event
+
+.. code-block:: c
+
+	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
+		long timestamp;
+		union {
+			video_size_t size;
+			unsigned int frame_rate;	/* in frames per 1000sec */
+			unsigned char vsync_field;	/* unknown/odd/even/progressive */
+		} u;
+	};
+
+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.
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  ``EWOULDBLOCK``
+
+       -  There is no event pending, and the device is in non-blocking mode.
+
+    -  .. row 2
+
+       -  ``EOVERFLOW``
+
+       -  Overflow in event queue - one or more events were lost.
diff --git a/Documentation/userspace-api/media/dvb/video-get-frame-count.rst b/Documentation/userspace-api/media/dvb/video-get-frame-count.rst
new file mode 100644
index 000000000000..4152a42daeb3
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/video-get-frame-count.rst
@@ -0,0 +1,74 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDEO_GET_FRAME_COUNT:
+
+=====================
+VIDEO_GET_FRAME_COUNT
+=====================
+
+Name
+----
+
+VIDEO_GET_FRAME_COUNT
+
+.. attention:: This ioctl is deprecated.
+
+Synopsis
+--------
+
+.. c:function:: int ioctl(int fd, VIDEO_GET_FRAME_COUNT, __u64 *pts)
+    :name: VIDEO_GET_FRAME_COUNT
+
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+    -  .. row 2
+
+       -  int request
+
+       -  Equals VIDEO_GET_FRAME_COUNT for this command.
+
+    -  .. row 3
+
+       -  __u64 \*pts
+
+       -  Returns the number of frames displayed since the decoder was
+	  started.
+
+
+Description
+-----------
+
+This ioctl is obsolete. Do not use in new drivers. For V4L2 decoders
+this ioctl has been replaced by the ``V4L2_CID_MPEG_VIDEO_DEC_FRAME``
+control.
+
+This ioctl call asks the Video Device to return the number of displayed
+frames since the decoder was started.
+
+
+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/userspace-api/media/dvb/video-get-pts.rst b/Documentation/userspace-api/media/dvb/video-get-pts.rst
new file mode 100644
index 000000000000..f957df792ae1
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/video-get-pts.rst
@@ -0,0 +1,78 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDEO_GET_PTS:
+
+=============
+VIDEO_GET_PTS
+=============
+
+Name
+----
+
+VIDEO_GET_PTS
+
+.. attention:: This ioctl is deprecated.
+
+Synopsis
+--------
+
+.. c:function:: int ioctl(int fd, VIDEO_GET_PTS, __u64 *pts)
+    :name: VIDEO_GET_PTS
+
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+    -  .. row 2
+
+       -  int request
+
+       -  Equals VIDEO_GET_PTS for this command.
+
+    -  .. row 3
+
+       -  __u64 \*pts
+
+       -  Returns the 33-bit timestamp as defined in ITU T-REC-H.222.0 /
+	  ISO/IEC 13818-1.
+
+	  The PTS should belong to the currently played frame if possible,
+	  but may also be a value close to it like the PTS of the last
+	  decoded frame or the last PTS extracted by the PES parser.
+
+
+Description
+-----------
+
+This ioctl is obsolete. Do not use in new drivers. For V4L2 decoders
+this ioctl has been replaced by the ``V4L2_CID_MPEG_VIDEO_DEC_PTS``
+control.
+
+This ioctl call asks the Video Device to return the current PTS
+timestamp.
+
+
+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/userspace-api/media/dvb/video-get-size.rst b/Documentation/userspace-api/media/dvb/video-get-size.rst
new file mode 100644
index 000000000000..376745550eb5
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/video-get-size.rst
@@ -0,0 +1,78 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDEO_GET_SIZE:
+
+==============
+VIDEO_GET_SIZE
+==============
+
+Name
+----
+
+VIDEO_GET_SIZE
+
+.. attention:: This ioctl is deprecated.
+
+Synopsis
+--------
+
+.. c:function:: int ioctl(int fd, VIDEO_GET_SIZE, video_size_t *size)
+    :name: VIDEO_GET_SIZE
+
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+    -  .. row 2
+
+       -  int request
+
+       -  Equals VIDEO_GET_SIZE for this command.
+
+    -  .. row 3
+
+       -  video_size_t \*size
+
+       -  Returns the size and aspect ratio.
+
+
+Description
+-----------
+
+This ioctl returns the size and aspect ratio.
+
+.. c:type:: video_size_t
+
+.. code-block::c
+
+	typedef struct {
+		int w;
+		int h;
+		video_format_t aspect_ratio;
+	} video_size_t;
+
+
+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/userspace-api/media/dvb/video-get-status.rst b/Documentation/userspace-api/media/dvb/video-get-status.rst
new file mode 100644
index 000000000000..d0172593e557
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/video-get-status.rst
@@ -0,0 +1,80 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDEO_GET_STATUS:
+
+================
+VIDEO_GET_STATUS
+================
+
+Name
+----
+
+VIDEO_GET_STATUS
+
+.. attention:: This ioctl is deprecated.
+
+Synopsis
+--------
+
+.. c:function:: int ioctl(fd, VIDEO_GET_STATUS, struct video_status *status)
+    :name: VIDEO_GET_STATUS
+
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+    -  .. row 2
+
+       -  int request
+
+       -  Equals VIDEO_GET_STATUS for this command.
+
+    -  .. row 3
+
+       -  struct video_status \*status
+
+       -  Returns the current status of the Video Device.
+
+
+Description
+-----------
+
+This ioctl call asks the Video Device to return the current status of
+the device.
+
+.. c:type:: video_status
+
+.. code-block:: c
+
+	struct video_status {
+		int                   video_blank;   /* blank video on freeze? */
+		video_play_state_t    play_state;    /* current state of playback */
+		video_stream_source_t stream_source; /* current source (demux/memory) */
+		video_format_t        video_format;  /* current aspect ratio of stream*/
+		video_displayformat_t display_format;/* selected cropping mode */
+	};
+
+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/userspace-api/media/dvb/video-play.rst b/Documentation/userspace-api/media/dvb/video-play.rst
new file mode 100644
index 000000000000..2b6b4e93bd93
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/video-play.rst
@@ -0,0 +1,66 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDEO_PLAY:
+
+==========
+VIDEO_PLAY
+==========
+
+Name
+----
+
+VIDEO_PLAY
+
+.. attention:: This ioctl is deprecated.
+
+Synopsis
+--------
+
+.. c:function:: int ioctl(fd, VIDEO_PLAY)
+    :name: VIDEO_PLAY
+
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+    -  .. row 2
+
+       -  int request
+
+       -  Equals VIDEO_PLAY for this command.
+
+
+Description
+-----------
+
+This ioctl is for Digital TV devices only. To control a V4L2 decoder use the
+V4L2 :ref:`VIDIOC_DECODER_CMD` instead.
+
+This ioctl call asks the Video Device to start playing a video stream
+from the selected source.
+
+
+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/userspace-api/media/dvb/video-select-source.rst b/Documentation/userspace-api/media/dvb/video-select-source.rst
new file mode 100644
index 000000000000..504f768da00c
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/video-select-source.rst
@@ -0,0 +1,84 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDEO_SELECT_SOURCE:
+
+===================
+VIDEO_SELECT_SOURCE
+===================
+
+Name
+----
+
+VIDEO_SELECT_SOURCE
+
+.. attention:: This ioctl is deprecated.
+
+Synopsis
+--------
+
+.. c:function:: int ioctl(fd, VIDEO_SELECT_SOURCE, video_stream_source_t source)
+    :name: VIDEO_SELECT_SOURCE
+
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+    -  .. row 2
+
+       -  int request
+
+       -  Equals VIDEO_SELECT_SOURCE for this command.
+
+    -  .. row 3
+
+       -  video_stream_source_t source
+
+       -  Indicates which source shall be used for the Video stream.
+
+
+Description
+-----------
+
+This ioctl is for Digital TV devices only. This ioctl was also supported by the
+V4L2 ivtv driver, but that has been replaced by the ivtv-specific
+``IVTV_IOC_PASSTHROUGH_MODE`` ioctl.
+
+This ioctl call informs the video device which source shall be used for
+the input data. The possible sources are demux or memory. If memory is
+selected, the data is fed to the video device through the write command.
+
+.. c:type:: video_stream_source_t
+
+.. code-block:: c
+
+	typedef enum {
+		VIDEO_SOURCE_DEMUX, /* Select the demux as the main source */
+		VIDEO_SOURCE_MEMORY /* If this source is selected, the stream
+				comes from the user through the write
+				system call */
+	} video_stream_source_t;
+
+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/userspace-api/media/dvb/video-set-blank.rst b/Documentation/userspace-api/media/dvb/video-set-blank.rst
new file mode 100644
index 000000000000..a2608df94d3e
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/video-set-blank.rst
@@ -0,0 +1,73 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDEO_SET_BLANK:
+
+===============
+VIDEO_SET_BLANK
+===============
+
+Name
+----
+
+VIDEO_SET_BLANK
+
+.. attention:: This ioctl is deprecated.
+
+Synopsis
+--------
+
+.. c:function:: int ioctl(fd, VIDEO_SET_BLANK, boolean mode)
+    :name: VIDEO_SET_BLANK
+
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+    -  .. row 2
+
+       -  int request
+
+       -  Equals VIDEO_SET_BLANK for this command.
+
+    -  .. row 3
+
+       -  boolean mode
+
+       -  TRUE: Blank screen when stop.
+
+    -  .. row 4
+
+       -
+       -  FALSE: Show last decoded frame.
+
+
+Description
+-----------
+
+This ioctl call asks the Video Device to blank out the picture.
+
+
+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/userspace-api/media/dvb/video-set-display-format.rst b/Documentation/userspace-api/media/dvb/video-set-display-format.rst
new file mode 100644
index 000000000000..c587b3d15e30
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/video-set-display-format.rst
@@ -0,0 +1,69 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDEO_SET_DISPLAY_FORMAT:
+
+========================
+VIDEO_SET_DISPLAY_FORMAT
+========================
+
+Name
+----
+
+VIDEO_SET_DISPLAY_FORMAT
+
+.. attention:: This ioctl is deprecated.
+
+Synopsis
+--------
+
+.. c:function:: int ioctl(fd, VIDEO_SET_DISPLAY_FORMAT)
+    :name: VIDEO_SET_DISPLAY_FORMAT
+
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+    -  .. row 2
+
+       -  int request
+
+       -  Equals VIDEO_SET_DISPLAY_FORMAT for this command.
+
+    -  .. row 3
+
+       -  video_display_format_t format
+
+       -  Selects the video format to be used.
+
+
+Description
+-----------
+
+This ioctl call asks the Video Device to select the video format to be
+applied by the MPEG chip on the video.
+
+
+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/userspace-api/media/dvb/video-set-format.rst b/Documentation/userspace-api/media/dvb/video-set-format.rst
new file mode 100644
index 000000000000..ced74edb74eb
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/video-set-format.rst
@@ -0,0 +1,92 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDEO_SET_FORMAT:
+
+================
+VIDEO_SET_FORMAT
+================
+
+Name
+----
+
+VIDEO_SET_FORMAT
+
+.. attention:: This ioctl is deprecated.
+
+Synopsis
+--------
+
+.. c:function:: int ioctl(fd, VIDEO_SET_FORMAT, video_format_t format)
+    :name: VIDEO_SET_FORMAT
+
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+    -  .. row 2
+
+       -  int request
+
+       -  Equals VIDEO_SET_FORMAT for this command.
+
+    -  .. row 3
+
+       -  video_format_t format
+
+       -  video format of TV as defined in section ??.
+
+
+Description
+-----------
+
+This ioctl sets the screen format (aspect ratio) of the connected output
+device (TV) so that the output of the decoder can be adjusted
+accordingly.
+
+.. c:type:: video_format_t
+
+.. code-block:: c
+
+	typedef enum {
+		VIDEO_FORMAT_4_3,     /* Select 4:3 format */
+		VIDEO_FORMAT_16_9,    /* Select 16:9 format. */
+		VIDEO_FORMAT_221_1    /* 2.21:1 */
+	} video_format_t;
+
+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.
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  ``EINVAL``
+
+       -  format is not a valid video format.
diff --git a/Documentation/userspace-api/media/dvb/video-set-streamtype.rst b/Documentation/userspace-api/media/dvb/video-set-streamtype.rst
new file mode 100644
index 000000000000..1729bc04e4f7
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/video-set-streamtype.rst
@@ -0,0 +1,70 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDEO_SET_STREAMTYPE:
+
+====================
+VIDEO_SET_STREAMTYPE
+====================
+
+Name
+----
+
+VIDEO_SET_STREAMTYPE
+
+.. attention:: This ioctl is deprecated.
+
+Synopsis
+--------
+
+.. c:function:: int ioctl(fd, VIDEO_SET_STREAMTYPE, int type)
+    :name: VIDEO_SET_STREAMTYPE
+
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+    -  .. row 2
+
+       -  int request
+
+       -  Equals VIDEO_SET_STREAMTYPE for this command.
+
+    -  .. row 3
+
+       -  int type
+
+       -  stream type
+
+
+Description
+-----------
+
+This ioctl tells the driver which kind of stream to expect being written
+to it. If this call is not used the default of video PES is used. Some
+drivers might not support this call and always expect PES.
+
+
+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/userspace-api/media/dvb/video-slowmotion.rst b/Documentation/userspace-api/media/dvb/video-slowmotion.rst
new file mode 100644
index 000000000000..b8cfba7bbfb3
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/video-slowmotion.rst
@@ -0,0 +1,83 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDEO_SLOWMOTION:
+
+================
+VIDEO_SLOWMOTION
+================
+
+Name
+----
+
+VIDEO_SLOWMOTION
+
+.. attention:: This ioctl is deprecated.
+
+Synopsis
+--------
+
+.. c:function:: int ioctl(fd, VIDEO_SLOWMOTION, int nFrames)
+    :name: VIDEO_SLOWMOTION
+
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+    -  .. row 2
+
+       -  int request
+
+       -  Equals VIDEO_SLOWMOTION for this command.
+
+    -  .. row 3
+
+       -  int nFrames
+
+       -  The number of times to repeat each frame.
+
+
+Description
+-----------
+
+This ioctl call asks the video device to repeat decoding frames N number
+of times. This call can only be used if VIDEO_SOURCE_MEMORY is
+selected.
+
+
+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.
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  ``EPERM``
+
+       -  Mode VIDEO_SOURCE_MEMORY not selected.
diff --git a/Documentation/userspace-api/media/dvb/video-stillpicture.rst b/Documentation/userspace-api/media/dvb/video-stillpicture.rst
new file mode 100644
index 000000000000..5432619a63a1
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/video-stillpicture.rst
@@ -0,0 +1,70 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDEO_STILLPICTURE:
+
+==================
+VIDEO_STILLPICTURE
+==================
+
+Name
+----
+
+VIDEO_STILLPICTURE
+
+.. attention:: This ioctl is deprecated.
+
+Synopsis
+--------
+
+.. c:function:: int ioctl(fd, VIDEO_STILLPICTURE, struct video_still_picture *sp)
+    :name: VIDEO_STILLPICTURE
+
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+    -  .. row 2
+
+       -  int request
+
+       -  Equals VIDEO_STILLPICTURE for this command.
+
+    -  .. row 3
+
+       -  struct video_still_picture \*sp
+
+       -  Pointer to a location where an I-frame and size is stored.
+
+
+Description
+-----------
+
+This ioctl call asks the Video Device to display a still picture
+(I-frame). The input data shall contain an I-frame. If the pointer is
+NULL, then the current displayed still picture is blanked.
+
+
+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/userspace-api/media/dvb/video-stop.rst b/Documentation/userspace-api/media/dvb/video-stop.rst
new file mode 100644
index 000000000000..9a53fe7f2fd0
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/video-stop.rst
@@ -0,0 +1,83 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDEO_STOP:
+
+==========
+VIDEO_STOP
+==========
+
+Name
+----
+
+VIDEO_STOP
+
+.. attention:: This ioctl is deprecated.
+
+Synopsis
+--------
+
+.. c:function:: int ioctl(fd, VIDEO_STOP, boolean mode)
+    :name: VIDEO_STOP
+
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+    -  .. row 2
+
+       -  int request
+
+       -  Equals VIDEO_STOP for this command.
+
+    -  .. row 3
+
+       -  Boolean mode
+
+       -  Indicates how the screen shall be handled.
+
+    -  .. row 4
+
+       -
+       -  TRUE: Blank screen when stop.
+
+    -  .. row 5
+
+       -
+       -  FALSE: Show last decoded frame.
+
+
+Description
+-----------
+
+This ioctl is for Digital TV devices only. To control a V4L2 decoder use the
+V4L2 :ref:`VIDIOC_DECODER_CMD` instead.
+
+This ioctl call asks the Video Device to stop playing the current
+stream. Depending on the input parameter, the screen can be blanked out
+or displaying the last decoded frame.
+
+
+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/userspace-api/media/dvb/video-try-command.rst b/Documentation/userspace-api/media/dvb/video-try-command.rst
new file mode 100644
index 000000000000..61667952030f
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/video-try-command.rst
@@ -0,0 +1,75 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDEO_TRY_COMMAND:
+
+=================
+VIDEO_TRY_COMMAND
+=================
+
+Name
+----
+
+VIDEO_TRY_COMMAND
+
+.. attention:: This ioctl is deprecated.
+
+Synopsis
+--------
+
+.. c:function:: int ioctl(int fd, VIDEO_TRY_COMMAND, struct video_command *cmd)
+    :name: VIDEO_TRY_COMMAND
+
+
+Arguments
+---------
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  int fd
+
+       -  File descriptor returned by a previous call to open().
+
+    -  .. row 2
+
+       -  int request
+
+       -  Equals VIDEO_TRY_COMMAND for this command.
+
+    -  .. row 3
+
+       -  struct video_command \*cmd
+
+       -  Try a decoder command.
+
+
+Description
+-----------
+
+This ioctl is obsolete. Do not use in new drivers. For V4L2 decoders
+this ioctl has been replaced by the
+:ref:`VIDIOC_TRY_DECODER_CMD <VIDIOC_DECODER_CMD>` ioctl.
+
+This ioctl tries a decoder command. The ``video_command`` struct is a
+subset of the ``v4l2_decoder_cmd`` struct, so refer to the
+:ref:`VIDIOC_TRY_DECODER_CMD <VIDIOC_DECODER_CMD>` documentation
+for more information.
+
+
+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/userspace-api/media/dvb/video.rst b/Documentation/userspace-api/media/dvb/video.rst
new file mode 100644
index 000000000000..537eae1b0723
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/video.rst
@@ -0,0 +1,43 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _dvb_video:
+
+#######################
+Digital TV Video Device
+#######################
+
+The Digital TV video device controls the MPEG2 video decoder of the Digital
+TV hardware. It can be accessed through **/dev/dvb/adapter0/video0**. Data
+types and and ioctl definitions can be accessed by including
+**linux/dvb/video.h** in your application.
+
+Note that the Digital TV video device only controls decoding of the MPEG video
+stream, not its presentation on the TV or computer screen. On PCs this
+is typically handled by an associated video4linux device, e.g.
+**/dev/video**, which allows scaling and defining output windows.
+
+Some Digital TV cards don’t have their own MPEG decoder, which results in the
+omission of the audio and video device as well as the video4linux
+device.
+
+The ioctls that deal with SPUs (sub picture units) and navigation
+packets are only supported on some MPEG decoders made for DVD playback.
+
+These ioctls were also used by V4L2 to control MPEG decoders implemented
+in V4L2. The use of these ioctls for that purpose has been made obsolete
+and proper V4L2 ioctls or controls have been created to replace that
+functionality.
+
+
+.. toctree::
+    :maxdepth: 1
+
+    video_types
+    video_function_calls
diff --git a/Documentation/userspace-api/media/dvb/video_function_calls.rst b/Documentation/userspace-api/media/dvb/video_function_calls.rst
new file mode 100644
index 000000000000..4902a40d65ba
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/video_function_calls.rst
@@ -0,0 +1,42 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _video_function_calls:
+
+********************
+Video Function Calls
+********************
+
+.. toctree::
+    :maxdepth: 1
+
+    video-fopen
+    video-fclose
+    video-fwrite
+    video-stop
+    video-play
+    video-freeze
+    video-continue
+    video-select-source
+    video-set-blank
+    video-get-status
+    video-get-frame-count
+    video-get-pts
+    video-get-event
+    video-command
+    video-try-command
+    video-get-size
+    video-set-display-format
+    video-stillpicture
+    video-fast-forward
+    video-slowmotion
+    video-get-capabilities
+    video-clear-buffer
+    video-set-streamtype
+    video-set-format
diff --git a/Documentation/userspace-api/media/dvb/video_types.rst b/Documentation/userspace-api/media/dvb/video_types.rst
new file mode 100644
index 000000000000..bdba1d48f647
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/video_types.rst
@@ -0,0 +1,255 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _video_types:
+
+****************
+Video Data Types
+****************
+
+
+.. _video-format-t:
+
+video_format_t
+==============
+
+The ``video_format_t`` data type defined by
+
+
+.. code-block:: c
+
+    typedef enum {
+	VIDEO_FORMAT_4_3,     /* Select 4:3 format */
+	VIDEO_FORMAT_16_9,    /* Select 16:9 format. */
+	VIDEO_FORMAT_221_1    /* 2.21:1 */
+    } video_format_t;
+
+is used in the VIDEO_SET_FORMAT function (??) to tell the driver which
+aspect ratio the output hardware (e.g. TV) has. It is also used in the
+data structures video_status (??) returned by VIDEO_GET_STATUS (??)
+and video_event (??) returned by VIDEO_GET_EVENT (??) which report
+about the display format of the current video stream.
+
+
+.. _video-displayformat-t:
+
+video_displayformat_t
+=====================
+
+In case the display format of the video stream and of the display
+hardware differ the application has to specify how to handle the
+cropping of the picture. This can be done using the
+VIDEO_SET_DISPLAY_FORMAT call (??) which accepts
+
+
+.. code-block:: c
+
+    typedef enum {
+	VIDEO_PAN_SCAN,       /* use pan and scan format */
+	VIDEO_LETTER_BOX,     /* use letterbox format */
+	VIDEO_CENTER_CUT_OUT  /* use center cut out format */
+    } video_displayformat_t;
+
+as argument.
+
+
+.. _video-stream-source-t:
+
+video_stream_source_t
+=====================
+
+The video stream source is set through the VIDEO_SELECT_SOURCE call
+and can take the following values, depending on whether we are replaying
+from an internal (demuxer) or external (user write) source.
+
+
+.. code-block:: c
+
+    typedef enum {
+	VIDEO_SOURCE_DEMUX, /* Select the demux as the main source */
+	VIDEO_SOURCE_MEMORY /* If this source is selected, the stream
+		       comes from the user through the write
+		       system call */
+    } video_stream_source_t;
+
+VIDEO_SOURCE_DEMUX selects the demultiplexer (fed either by the
+frontend or the DVR device) as the source of the video stream. If
+VIDEO_SOURCE_MEMORY is selected the stream comes from the application
+through the **write()** system call.
+
+
+.. _video-play-state-t:
+
+video_play_state_t
+==================
+
+The following values can be returned by the VIDEO_GET_STATUS call
+representing the state of video playback.
+
+
+.. code-block:: c
+
+    typedef enum {
+	VIDEO_STOPPED, /* Video is stopped */
+	VIDEO_PLAYING, /* Video is currently playing */
+	VIDEO_FREEZED  /* Video is freezed */
+    } video_play_state_t;
+
+
+.. c:type:: video_command
+
+struct video_command
+====================
+
+The structure must be zeroed before use by the application This ensures
+it can be extended safely in the future.
+
+
+.. code-block:: c
+
+    struct video_command {
+	__u32 cmd;
+	__u32 flags;
+	union {
+	    struct {
+		__u64 pts;
+	    } stop;
+
+	    struct {
+		/* 0 or 1000 specifies normal speed,
+		   1 specifies forward single stepping,
+		   -1 specifies backward single stepping,
+		   >>1: playback at speed/1000 of the normal speed,
+		   <-1: reverse playback at (-speed/1000) of the normal speed. */
+		__s32 speed;
+		__u32 format;
+	    } play;
+
+	    struct {
+		__u32 data[16];
+	    } raw;
+	};
+    };
+
+
+.. _video-size-t:
+
+video_size_t
+============
+
+
+.. code-block:: c
+
+    typedef struct {
+	int w;
+	int h;
+	video_format_t aspect_ratio;
+    } video_size_t;
+
+
+.. c:type:: video_event
+
+struct video_event
+==================
+
+The following is the structure of a video event as it is returned by the
+VIDEO_GET_EVENT call.
+
+
+.. code-block:: c
+
+    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
+	long timestamp;
+	union {
+	    video_size_t size;
+	    unsigned int frame_rate;    /* in frames per 1000sec */
+	    unsigned char vsync_field;  /* unknown/odd/even/progressive */
+	} u;
+    };
+
+
+.. c:type:: video_status
+
+struct video_status
+===================
+
+The VIDEO_GET_STATUS call returns the following structure informing
+about various states of the playback operation.
+
+
+.. code-block:: c
+
+    struct video_status {
+	int                   video_blank;   /* blank video on freeze? */
+	video_play_state_t    play_state;    /* current state of playback */
+	video_stream_source_t stream_source; /* current source (demux/memory) */
+	video_format_t        video_format;  /* current aspect ratio of stream */
+	video_displayformat_t display_format;/* selected cropping mode */
+    };
+
+If video_blank is set video will be blanked out if the channel is
+changed or if playback is stopped. Otherwise, the last picture will be
+displayed. play_state indicates if the video is currently frozen,
+stopped, or being played back. The stream_source corresponds to the
+selected source for the video stream. It can come either from the
+demultiplexer or from memory. The video_format indicates the aspect
+ratio (one of 4:3 or 16:9) of the currently played video stream.
+Finally, display_format corresponds to the selected cropping mode in
+case the source video format is not the same as the format of the output
+device.
+
+
+.. c:type:: video_still_picture
+
+struct video_still_picture
+==========================
+
+An I-frame displayed via the VIDEO_STILLPICTURE call is passed on
+within the following structure.
+
+
+.. code-block:: c
+
+    /* pointer to and size of a single iframe in memory */
+    struct video_still_picture {
+	char *iFrame;        /* pointer to a single iframe in memory */
+	int32_t size;
+    };
+
+
+.. _video_caps:
+
+video capabilities
+==================
+
+A call to VIDEO_GET_CAPABILITIES returns an unsigned integer with the
+following bits set according to the hardwares capabilities.
+
+
+.. code-block:: c
+
+     /* bit definitions for capabilities: */
+     /* can the hardware decode MPEG1 and/or MPEG2? */
+     #define VIDEO_CAP_MPEG1   1
+     #define VIDEO_CAP_MPEG2   2
+     /* can you send a system and/or program stream to video device?
+	(you still have to open the video and the audio device but only
+	 send the stream to the video device) */
+     #define VIDEO_CAP_SYS     4
+     #define VIDEO_CAP_PROG    8
+     /* can the driver also handle SPU, NAVI and CSS encoded data?
+	(CSS API is not present yet) */
+     #define VIDEO_CAP_SPU    16
+     #define VIDEO_CAP_NAVI   32
+     #define VIDEO_CAP_CSS    64
diff --git a/Documentation/userspace-api/media/fdl-appendix.rst b/Documentation/userspace-api/media/fdl-appendix.rst
new file mode 100644
index 000000000000..70c8cda10814
--- /dev/null
+++ b/Documentation/userspace-api/media/fdl-appendix.rst
@@ -0,0 +1,478 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _fdl:
+
+******************************
+GNU Free Documentation License
+******************************
+
+
+.. _fdl-preamble:
+
+0. PREAMBLE
+===========
+
+The purpose of this License is to make a manual, textbook, or other
+written document “free” in the sense of freedom: to assure everyone the
+effective freedom to copy and redistribute it, with or without modifying
+it, either commercially or noncommercially. Secondarily, this License
+preserves for the author and publisher a way to get credit for their
+work, while not being considered responsible for modifications made by
+others.
+
+This License is a kind of “copyleft”, which means that derivative works
+of the document must themselves be free in the same sense. It
+complements the GNU General Public License, which is a copyleft license
+designed for free software.
+
+We have designed this License in order to use it for manuals for free
+software, because free software needs free documentation: a free program
+should come with manuals providing the same freedoms that the software
+does. But this License is not limited to software manuals; it can be
+used for any textual work, regardless of subject matter or whether it is
+published as a printed book. We recommend this License principally for
+works whose purpose is instruction or reference.
+
+
+.. _fdl-section1:
+
+1. APPLICABILITY AND DEFINITIONS
+================================
+
+
+.. _fdl-document:
+
+This License applies to any manual or other work that contains a notice
+placed by the copyright holder saying it can be distributed under the
+terms of this License. The “Document”, below, refers to any such manual
+or work. Any member of the public is a licensee, and is addressed as
+“you”.
+
+
+.. _fdl-modified:
+
+A “Modified Version” of the Document means any work containing the
+Document or a portion of it, either copied verbatim, or with
+modifications and/or translated into another language.
+
+
+.. _fdl-secondary:
+
+A “Secondary Section” is a named appendix or a front-matter section of
+the :ref:`Document <fdl-document>` that deals exclusively with the
+relationship of the publishers or authors of the Document to the
+Document's overall subject (or to related matters) and contains nothing
+that could fall directly within that overall subject. (For example, if
+the Document is in part a textbook of mathematics, a Secondary Section
+may not explain any mathematics.) The relationship could be a matter of
+historical connection with the subject or with related matters, or of
+legal, commercial, philosophical, ethical or political position
+regarding them.
+
+
+.. _fdl-invariant:
+
+The “Invariant Sections” are certain
+:ref:`Secondary Sections <fdl-secondary>` whose titles are designated,
+as being those of Invariant Sections, in the notice that says that the
+:ref:`Document <fdl-document>` is released under this License.
+
+
+.. _fdl-cover-texts:
+
+The “Cover Texts” are certain short passages of text that are listed, as
+Front-Cover Texts or Back-Cover Texts, in the notice that says that the
+:ref:`Document <fdl-document>` is released under this License.
+
+
+.. _fdl-transparent:
+
+A “Transparent” copy of the :ref:`Document <fdl-document>` means a
+machine-readable copy, represented in a format whose specification is
+available to the general public, whose contents can be viewed and edited
+directly and straightforwardly with generic text editors or (for images
+composed of pixels) generic paint programs or (for drawings) some widely
+available drawing editor, and that is suitable for input to text
+formatters or for automatic translation to a variety of formats suitable
+for input to text formatters. A copy made in an otherwise Transparent
+file format whose markup has been designed to thwart or discourage
+subsequent modification by readers is not Transparent. A copy that is
+not “Transparent” is called “Opaque”.
+
+Examples of suitable formats for Transparent copies include plain ASCII
+without markup, Texinfo input format, LaTeX input format, SGML or XML
+using a publicly available DTD, and standard-conforming simple HTML
+designed for human modification. Opaque formats include PostScript, PDF,
+proprietary formats that can be read and edited only by proprietary word
+processors, SGML or XML for which the DTD and/or processing tools are
+not generally available, and the machine-generated HTML produced by some
+word processors for output purposes only.
+
+
+.. _fdl-title-page:
+
+The “Title Page” means, for a printed book, the title page itself, plus
+such following pages as are needed to hold, legibly, the material this
+License requires to appear in the title page. For works in formats which
+do not have any title page as such, “Title Page” means the text near the
+most prominent appearance of the work's title, preceding the beginning
+of the body of the text.
+
+
+.. _fdl-section2:
+
+2. VERBATIM COPYING
+===================
+
+You may copy and distribute the :ref:`Document <fdl-document>` in any
+medium, either commercially or noncommercially, provided that this
+License, the copyright notices, and the license notice saying this
+License applies to the Document are reproduced in all copies, and that
+you add no other conditions whatsoever to those of this License. You may
+not use technical measures to obstruct or control the reading or further
+copying of the copies you make or distribute. However, you may accept
+compensation in exchange for copies. If you distribute a large enough
+number of copies you must also follow the conditions in
+:ref:`section 3 <fdl-section3>`.
+
+You may also lend copies, under the same conditions stated above, and
+you may publicly display copies.
+
+
+.. _fdl-section3:
+
+3. COPYING IN QUANTITY
+======================
+
+If you publish printed copies of the :ref:`Document <fdl-document>`
+numbering more than 100, and the Document's license notice requires
+:ref:`Cover Texts <fdl-cover-texts>`, you must enclose the copies in
+covers that carry, clearly and legibly, all these Cover Texts:
+Front-Cover Texts on the front cover, and Back-Cover Texts on the back
+cover. Both covers must also clearly and legibly identify you as the
+publisher of these copies. The front cover must present the full title
+with all words of the title equally prominent and visible. You may add
+other material on the covers in addition. Copying with changes limited
+to the covers, as long as they preserve the title of the
+:ref:`Document <fdl-document>` and satisfy these conditions, can be
+treated as verbatim copying in other respects.
+
+If the required texts for either cover are too voluminous to fit
+legibly, you should put the first ones listed (as many as fit
+reasonably) on the actual cover, and continue the rest onto adjacent
+pages.
+
+If you publish or distribute :ref:`Opaque <fdl-transparent>` copies of
+the :ref:`Document <fdl-document>` numbering more than 100, you must
+either include a machine-readable :ref:`Transparent <fdl-transparent>`
+copy along with each Opaque copy, or state in or with each Opaque copy a
+publicly-accessible computer-network location containing a complete
+Transparent copy of the Document, free of added material, which the
+general network-using public has access to download anonymously at no
+charge using public-standard network protocols. If you use the latter
+option, you must take reasonably prudent steps, when you begin
+distribution of Opaque copies in quantity, to ensure that this
+Transparent copy will remain thus accessible at the stated location
+until at least one year after the last time you distribute an Opaque
+copy (directly or through your agents or retailers) of that edition to
+the public.
+
+It is requested, but not required, that you contact the authors of the
+:ref:`Document <fdl-document>` well before redistributing any large
+number of copies, to give them a chance to provide you with an updated
+version of the Document.
+
+
+.. _fdl-section4:
+
+4. MODIFICATIONS
+================
+
+You may copy and distribute a :ref:`Modified Version <fdl-modified>`
+of the :ref:`Document <fdl-document>` under the conditions of sections
+:ref:`2 <fdl-section2>` and :ref:`3 <fdl-section3>` above, provided
+that you release the Modified Version under precisely this License, with
+the Modified Version filling the role of the Document, thus licensing
+distribution and modification of the Modified Version to whoever
+possesses a copy of it. In addition, you must do these things in the
+Modified Version:
+
+-  **A.**
+   Use in the :ref:`Title Page <fdl-title-page>` (and on the covers,
+   if any) a title distinct from that of the
+   :ref:`Document <fdl-document>`, and from those of previous versions
+   (which should, if there were any, be listed in the History section of
+   the Document). You may use the same title as a previous version if
+   the original publisher of that version gives permission.
+
+-  **B.**
+   List on the :ref:`Title Page <fdl-title-page>`, as authors, one or
+   more persons or entities responsible for authorship of the
+   modifications in the :ref:`Modified Version <fdl-modified>`,
+   together with at least five of the principal authors of the
+   :ref:`Document <fdl-document>` (all of its principal authors, if it
+   has less than five).
+
+-  **C.**
+   State on the :ref:`Title Page <fdl-title-page>` the name of the
+   publisher of the :ref:`Modified Version <fdl-modified>`, as the
+   publisher.
+
+-  **D.**
+   Preserve all the copyright notices of the
+   :ref:`Document <fdl-document>`.
+
+-  **E.**
+   Add an appropriate copyright notice for your modifications adjacent
+   to the other copyright notices.
+
+-  **F.**
+   Include, immediately after the copyright notices, a license notice
+   giving the public permission to use the
+   :ref:`Modified Version <fdl-modified>` under the terms of this
+   License, in the form shown in the Addendum below.
+
+-  **G.**
+   Preserve in that license notice the full lists of
+   :ref:`Invariant Sections <fdl-invariant>` and required
+   :ref:`Cover Texts <fdl-cover-texts>` given in the
+   :ref:`Document's <fdl-document>` license notice.
+
+-  **H.**
+   Include an unaltered copy of this License.
+
+-  **I.**
+   Preserve the section entitled “History”, and its title, and add to it
+   an item stating at least the title, year, new authors, and publisher
+   of the :ref:`Modified Version <fdl-modified>` as given on the
+   :ref:`Title Page <fdl-title-page>`. If there is no section entitled
+   “History” in the :ref:`Document <fdl-document>`, create one stating
+   the title, year, authors, and publisher of the Document as given on
+   its Title Page, then add an item describing the Modified Version as
+   stated in the previous sentence.
+
+-  **J.**
+   Preserve the network location, if any, given in the
+   :ref:`Document <fdl-document>` for public access to a
+   :ref:`Transparent <fdl-transparent>` copy of the Document, and
+   likewise the network locations given in the Document for previous
+   versions it was based on. These may be placed in the “History”
+   section. You may omit a network location for a work that was
+   published at least four years before the Document itself, or if the
+   original publisher of the version it refers to gives permission.
+
+-  **K.**
+   In any section entitled “Acknowledgements” or “Dedications”, preserve
+   the section's title, and preserve in the section all the substance
+   and tone of each of the contributor acknowledgements and/or
+   dedications given therein.
+
+-  **L.**
+   Preserve all the :ref:`Invariant Sections <fdl-invariant>` of the
+   :ref:`Document <fdl-document>`, unaltered in their text and in
+   their titles. Section numbers or the equivalent are not considered
+   part of the section titles.
+
+-  **M.**
+   Delete any section entitled “Endorsements”. Such a section may not be
+   included in the :ref:`Modified Version <fdl-modified>`.
+
+-  **N.**
+   Do not retitle any existing section as “Endorsements” or to conflict
+   in title with any :ref:`Invariant Section <fdl-invariant>`.
+
+If the :ref:`Modified Version <fdl-modified>` includes new
+front-matter sections or appendices that qualify as
+:ref:`Secondary Sections <fdl-secondary>` and contain no material
+copied from the Document, you may at your option designate some or all
+of these sections as invariant. To do this, add their titles to the list
+of :ref:`Invariant Sections <fdl-invariant>` in the Modified Version's
+license notice. These titles must be distinct from any other section
+titles.
+
+You may add a section entitled “Endorsements”, provided it contains
+nothing but endorsements of your
+:ref:`Modified Version <fdl-modified>` by various parties--for
+example, statements of peer review or that the text has been approved by
+an organization as the authoritative definition of a standard.
+
+You may add a passage of up to five words as a
+:ref:`Front-Cover Text <fdl-cover-texts>`, and a passage of up to 25
+words as a :ref:`Back-Cover Text <fdl-cover-texts>`, to the end of the
+list of :ref:`Cover Texts <fdl-cover-texts>` in the
+:ref:`Modified Version <fdl-modified>`. Only one passage of
+Front-Cover Text and one of Back-Cover Text may be added by (or through
+arrangements made by) any one entity. If the
+:ref:`Document <fdl-document>` already includes a cover text for the
+same cover, previously added by you or by arrangement made by the same
+entity you are acting on behalf of, you may not add another; but you may
+replace the old one, on explicit permission from the previous publisher
+that added the old one.
+
+The author(s) and publisher(s) of the :ref:`Document <fdl-document>`
+do not by this License give permission to use their names for publicity
+for or to assert or imply endorsement of any
+:ref:`Modified Version <fdl-modified>`.
+
+
+.. _fdl-section5:
+
+5. COMBINING DOCUMENTS
+======================
+
+You may combine the :ref:`Document <fdl-document>` with other
+documents released under this License, under the terms defined in
+:ref:`section 4 <fdl-section4>` above for modified versions, provided
+that you include in the combination all of the
+:ref:`Invariant Sections <fdl-invariant>` of all of the original
+documents, unmodified, and list them all as Invariant Sections of your
+combined work in its license notice.
+
+The combined work need only contain one copy of this License, and
+multiple identical :ref:`Invariant Sections <fdl-invariant>` may be
+replaced with a single copy. If there are multiple Invariant Sections
+with the same name but different contents, make the title of each such
+section unique by adding at the end of it, in parentheses, the name of
+the original author or publisher of that section if known, or else a
+unique number. Make the same adjustment to the section titles in the
+list of Invariant Sections in the license notice of the combined work.
+
+In the combination, you must combine any sections entitled “History” in
+the various original documents, forming one section entitled “History”;
+likewise combine any sections entitled “Acknowledgements”, and any
+sections entitled “Dedications”. You must delete all sections entitled
+“Endorsements.”
+
+
+.. _fdl-section6:
+
+6. COLLECTIONS OF DOCUMENTS
+===========================
+
+You may make a collection consisting of the
+:ref:`Document <fdl-document>` and other documents released under this
+License, and replace the individual copies of this License in the
+various documents with a single copy that is included in the collection,
+provided that you follow the rules of this License for verbatim copying
+of each of the documents in all other respects.
+
+You may extract a single document from such a collection, and distribute
+it individually under this License, provided you insert a copy of this
+License into the extracted document, and follow this License in all
+other respects regarding verbatim copying of that document.
+
+
+.. _fdl-section7:
+
+7. AGGREGATION WITH INDEPENDENT WORKS
+=====================================
+
+A compilation of the :ref:`Document <fdl-document>` or its derivatives
+with other separate and independent documents or works, in or on a
+volume of a storage or distribution medium, does not as a whole count as
+a :ref:`Modified Version <fdl-modified>` of the Document, provided no
+compilation copyright is claimed for the compilation. Such a compilation
+is called an “aggregate”, and this License does not apply to the other
+self-contained works thus compiled with the Document , on account of
+their being thus compiled, if they are not themselves derivative works
+of the Document. If the :ref:`Cover Text <fdl-cover-texts>`
+requirement of :ref:`section 3 <fdl-section3>` is applicable to these
+copies of the Document, then if the Document is less than one quarter of
+the entire aggregate, the Document's Cover Texts may be placed on covers
+that surround only the Document within the aggregate. Otherwise they
+must appear on covers around the whole aggregate.
+
+
+.. _fdl-section8:
+
+8. TRANSLATION
+==============
+
+Translation is considered a kind of modification, so you may distribute
+translations of the :ref:`Document <fdl-document>` under the terms of
+:ref:`section 4 <fdl-section4>`. Replacing
+:ref:`Invariant Sections <fdl-invariant>` with translations requires
+special permission from their copyright holders, but you may include
+translations of some or all Invariant Sections in addition to the
+original versions of these Invariant Sections. You may include a
+translation of this License provided that you also include the original
+English version of this License. In case of a disagreement between the
+translation and the original English version of this License, the
+original English version will prevail.
+
+
+.. _fdl-section9:
+
+9. TERMINATION
+==============
+
+You may not copy, modify, sublicense, or distribute the
+:ref:`Document <fdl-document>` except as expressly provided for under
+this License. Any other attempt to copy, modify, sublicense or
+distribute the Document is void, and will automatically terminate your
+rights under this License. However, parties who have received copies, or
+rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+
+.. _fdl-section10:
+
+10. FUTURE REVISIONS OF THIS LICENSE
+====================================
+
+The `Free Software Foundation <http://www.gnu.org/fsf/fsf.html>`__
+may publish new, revised versions of the GNU Free Documentation License
+from time to time. Such new versions will be similar in spirit to the
+present version, but may differ in detail to address new problems or
+concerns. See
+`http://www.gnu.org/copyleft/ <http://www.gnu.org/copyleft>`__.
+
+Each version of the License is given a distinguishing version number. If
+the :ref:`Document <fdl-document>` specifies that a particular
+numbered version of this License “or any later version” applies to it,
+you have the option of following the terms and conditions either of that
+specified version or of any later version that has been published (not
+as a draft) by the Free Software Foundation. If the Document does not
+specify a version number of this License, you may choose any version
+ever published (not as a draft) by the Free Software Foundation.
+
+
+.. _fdl-using:
+
+Addendum
+========
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and license
+notices just after the title page:
+
+    Copyright © YEAR YOUR NAME.
+
+    Permission is granted to copy, distribute and/or modify this
+    document under the terms of the GNU Free Documentation License,
+    Version 1.1 or any later version published by the Free Software
+    Foundation; with the :ref:`Invariant Sections <fdl-invariant>`
+    being LIST THEIR TITLES, with the
+    :ref:`Front-Cover Texts <fdl-cover-texts>` being LIST, and with
+    the :ref:`Back-Cover Texts <fdl-cover-texts>` being LIST. A copy
+    of the license is included in the section entitled “GNU Free
+    Documentation License”.
+
+If you have no :ref:`Invariant Sections <fdl-invariant>`, write “with
+no Invariant Sections” instead of saying which ones are invariant. If
+you have no :ref:`Front-Cover Texts <fdl-cover-texts>`, write “no
+Front-Cover Texts” instead of “Front-Cover Texts being LIST”; likewise
+for :ref:`Back-Cover Texts <fdl-cover-texts>`.
+
+If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of free
+software license, such as the
+`GNU General Public License <http://www.gnu.org/copyleft/gpl.html>`__,
+to permit their use in free software.
diff --git a/Documentation/userspace-api/media/frontend.h.rst.exceptions b/Documentation/userspace-api/media/frontend.h.rst.exceptions
new file mode 100644
index 000000000000..6283702c08c8
--- /dev/null
+++ b/Documentation/userspace-api/media/frontend.h.rst.exceptions
@@ -0,0 +1,214 @@
+# SPDX-License-Identifier: GPL-2.0
+
+# Ignore header name
+ignore define _DVBFRONTEND_H_
+
+# Group layer A-C symbols together
+replace define DTV_ISDBT_LAYERA_FEC dtv-isdbt-layer-fec
+replace define DTV_ISDBT_LAYERB_FEC dtv-isdbt-layer-fec
+replace define DTV_ISDBT_LAYERC_FEC dtv-isdbt-layer-fec
+replace define DTV_ISDBT_LAYERA_MODULATION dtv-isdbt-layer-modulation
+replace define DTV_ISDBT_LAYERB_MODULATION dtv-isdbt-layer-modulation
+replace define DTV_ISDBT_LAYERC_MODULATION dtv-isdbt-layer-modulation
+replace define DTV_ISDBT_LAYERA_SEGMENT_COUNT dtv-isdbt-layer-segment-count
+replace define DTV_ISDBT_LAYERB_SEGMENT_COUNT dtv-isdbt-layer-segment-count
+replace define DTV_ISDBT_LAYERC_SEGMENT_COUNT dtv-isdbt-layer-segment-count
+replace define DTV_ISDBT_LAYERA_TIME_INTERLEAVING dtv-isdbt-layer-time-interleaving
+replace define DTV_ISDBT_LAYERB_TIME_INTERLEAVING dtv-isdbt-layer-time-interleaving
+replace define DTV_ISDBT_LAYERC_TIME_INTERLEAVING dtv-isdbt-layer-time-interleaving
+
+# Ignore legacy defines
+ignore define DTV_ISDBS_TS_ID_LEGACY
+ignore define SYS_DVBC_ANNEX_AC
+ignore define SYS_DMBTH
+
+# Ignore limits
+ignore define DTV_MAX_COMMAND
+ignore define MAX_DTV_STATS
+ignore define DTV_IOCTL_MAX_MSGS
+
+# the same reference is used for both get and set ioctls
+replace ioctl FE_SET_PROPERTY :c:type:`FE_GET_PROPERTY`
+
+# Typedefs that use the enum reference
+replace typedef fe_sec_voltage_t :c:type:`fe_sec_voltage`
+
+# Replaces for flag constants
+replace define FE_TUNE_MODE_ONESHOT :c:func:`FE_SET_FRONTEND_TUNE_MODE`
+replace define LNA_AUTO dtv-lna
+replace define NO_STREAM_ID_FILTER dtv-stream-id
+
+# Those enums are defined at the frontend.h header, and not externally
+
+ignore symbol FE_IS_STUPID
+ignore symbol FE_CAN_INVERSION_AUTO
+ignore symbol FE_CAN_FEC_1_2
+ignore symbol FE_CAN_FEC_2_3
+ignore symbol FE_CAN_FEC_3_4
+ignore symbol FE_CAN_FEC_4_5
+ignore symbol FE_CAN_FEC_5_6
+ignore symbol FE_CAN_FEC_6_7
+ignore symbol FE_CAN_FEC_7_8
+ignore symbol FE_CAN_FEC_8_9
+ignore symbol FE_CAN_FEC_AUTO
+ignore symbol FE_CAN_QPSK
+ignore symbol FE_CAN_QAM_16
+ignore symbol FE_CAN_QAM_32
+ignore symbol FE_CAN_QAM_64
+ignore symbol FE_CAN_QAM_128
+ignore symbol FE_CAN_QAM_256
+ignore symbol FE_CAN_QAM_AUTO
+ignore symbol FE_CAN_TRANSMISSION_MODE_AUTO
+ignore symbol FE_CAN_BANDWIDTH_AUTO
+ignore symbol FE_CAN_GUARD_INTERVAL_AUTO
+ignore symbol FE_CAN_HIERARCHY_AUTO
+ignore symbol FE_CAN_8VSB
+ignore symbol FE_CAN_16VSB
+ignore symbol FE_HAS_EXTENDED_CAPS
+ignore symbol FE_CAN_MULTISTREAM
+ignore symbol FE_CAN_TURBO_FEC
+ignore symbol FE_CAN_2G_MODULATION
+ignore symbol FE_NEEDS_BENDING
+ignore symbol FE_CAN_RECOVER
+ignore symbol FE_CAN_MUTE_TS
+
+ignore symbol QPSK
+ignore symbol QAM_16
+ignore symbol QAM_32
+ignore symbol QAM_64
+ignore symbol QAM_128
+ignore symbol QAM_256
+ignore symbol QAM_AUTO
+ignore symbol VSB_8
+ignore symbol VSB_16
+ignore symbol PSK_8
+ignore symbol APSK_16
+ignore symbol APSK_32
+ignore symbol DQPSK
+ignore symbol QAM_4_NR
+
+ignore symbol SEC_VOLTAGE_13
+ignore symbol SEC_VOLTAGE_18
+ignore symbol SEC_VOLTAGE_OFF
+
+ignore symbol SEC_TONE_ON
+ignore symbol SEC_TONE_OFF
+
+ignore symbol SEC_MINI_A
+ignore symbol SEC_MINI_B
+
+ignore symbol FE_NONE
+ignore symbol FE_HAS_SIGNAL
+ignore symbol FE_HAS_CARRIER
+ignore symbol FE_HAS_VITERBI
+ignore symbol FE_HAS_SYNC
+ignore symbol FE_HAS_LOCK
+ignore symbol FE_REINIT
+ignore symbol FE_TIMEDOUT
+
+ignore symbol FEC_NONE
+ignore symbol FEC_1_2
+ignore symbol FEC_2_3
+ignore symbol FEC_3_4
+ignore symbol FEC_4_5
+ignore symbol FEC_5_6
+ignore symbol FEC_6_7
+ignore symbol FEC_7_8
+ignore symbol FEC_8_9
+ignore symbol FEC_AUTO
+ignore symbol FEC_3_5
+ignore symbol FEC_9_10
+ignore symbol FEC_2_5
+
+ignore symbol TRANSMISSION_MODE_AUTO
+ignore symbol TRANSMISSION_MODE_1K
+ignore symbol TRANSMISSION_MODE_2K
+ignore symbol TRANSMISSION_MODE_8K
+ignore symbol TRANSMISSION_MODE_4K
+ignore symbol TRANSMISSION_MODE_16K
+ignore symbol TRANSMISSION_MODE_32K
+ignore symbol TRANSMISSION_MODE_C1
+ignore symbol TRANSMISSION_MODE_C3780
+ignore symbol TRANSMISSION_MODE_2K
+ignore symbol TRANSMISSION_MODE_8K
+
+ignore symbol GUARD_INTERVAL_AUTO
+ignore symbol GUARD_INTERVAL_1_128
+ignore symbol GUARD_INTERVAL_1_32
+ignore symbol GUARD_INTERVAL_1_16
+ignore symbol GUARD_INTERVAL_1_8
+ignore symbol GUARD_INTERVAL_1_4
+ignore symbol GUARD_INTERVAL_19_128
+ignore symbol GUARD_INTERVAL_19_256
+ignore symbol GUARD_INTERVAL_PN420
+ignore symbol GUARD_INTERVAL_PN595
+ignore symbol GUARD_INTERVAL_PN945
+
+ignore symbol HIERARCHY_NONE
+ignore symbol HIERARCHY_AUTO
+ignore symbol HIERARCHY_1
+ignore symbol HIERARCHY_2
+ignore symbol HIERARCHY_4
+
+ignore symbol INTERLEAVING_NONE
+ignore symbol INTERLEAVING_AUTO
+ignore symbol INTERLEAVING_240
+ignore symbol INTERLEAVING_720
+
+ignore symbol PILOT_ON
+ignore symbol PILOT_OFF
+ignore symbol PILOT_AUTO
+
+ignore symbol ROLLOFF_35
+ignore symbol ROLLOFF_20
+ignore symbol ROLLOFF_25
+ignore symbol ROLLOFF_AUTO
+
+ignore symbol INVERSION_ON
+ignore symbol INVERSION_OFF
+ignore symbol INVERSION_AUTO
+
+ignore symbol SYS_UNDEFINED
+ignore symbol SYS_DVBC_ANNEX_A
+ignore symbol SYS_DVBC_ANNEX_B
+ignore symbol SYS_DVBC_ANNEX_C
+ignore symbol SYS_ISDBC
+ignore symbol SYS_DVBT
+ignore symbol SYS_DVBT2
+ignore symbol SYS_ISDBT
+ignore symbol SYS_ATSC
+ignore symbol SYS_ATSCMH
+ignore symbol SYS_DTMB
+ignore symbol SYS_DVBS
+ignore symbol SYS_DVBS2
+ignore symbol SYS_TURBO
+ignore symbol SYS_ISDBS
+ignore symbol SYS_DAB
+ignore symbol SYS_DSS
+ignore symbol SYS_CMMB
+ignore symbol SYS_DVBH
+
+ignore symbol ATSCMH_SCCC_BLK_SEP
+ignore symbol ATSCMH_SCCC_BLK_COMB
+ignore symbol ATSCMH_SCCC_BLK_RES
+
+ignore symbol ATSCMH_SCCC_CODE_HLF
+ignore symbol ATSCMH_SCCC_CODE_QTR
+ignore symbol ATSCMH_SCCC_CODE_RES
+
+ignore symbol ATSCMH_RSFRAME_ENS_PRI
+ignore symbol ATSCMH_RSFRAME_ENS_SEC
+
+ignore symbol ATSCMH_RSFRAME_PRI_ONLY
+ignore symbol ATSCMH_RSFRAME_PRI_SEC
+ignore symbol ATSCMH_RSFRAME_RES
+
+ignore symbol ATSCMH_RSCODE_211_187
+ignore symbol ATSCMH_RSCODE_223_187
+ignore symbol ATSCMH_RSCODE_235_187
+ignore symbol ATSCMH_RSCODE_RES
+
+ignore symbol FE_SCALE_NOT_AVAILABLE
+ignore symbol FE_SCALE_DECIBEL
+ignore symbol FE_SCALE_RELATIVE
+ignore symbol FE_SCALE_COUNTER
diff --git a/Documentation/userspace-api/media/gen-errors.rst b/Documentation/userspace-api/media/gen-errors.rst
new file mode 100644
index 000000000000..abae4dbed549
--- /dev/null
+++ b/Documentation/userspace-api/media/gen-errors.rst
@@ -0,0 +1,103 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _gen_errors:
+
+*******************
+Generic Error Codes
+*******************
+
+
+.. _gen-errors:
+
+.. tabularcolumns:: |p{2.5cm}|p{15.0cm}|
+
+.. flat-table:: Generic error codes
+    :header-rows:  0
+    :stub-columns: 0
+    :widths: 1 16
+
+
+    -  -  ``EAGAIN`` (aka ``EWOULDBLOCK``)
+
+       -  The ioctl can't be handled because the device is in state where it
+	  can't perform it. This could happen for example in case where
+	  device is sleeping and ioctl is performed to query statistics. It
+	  is also returned when the ioctl would need to wait for an event,
+	  but the device was opened in non-blocking mode.
+
+    -  -  ``EBADF``
+
+       -  The file descriptor is not a valid.
+
+    -  -  ``EBUSY``
+
+       -  The ioctl can't be handled because the device is busy. This is
+	  typically return while device is streaming, and an ioctl tried to
+	  change something that would affect the stream, or would require
+	  the usage of a hardware resource that was already allocated. The
+	  ioctl must not be retried without performing another action to fix
+	  the problem first (typically: stop the stream before retrying).
+
+    -  -  ``EFAULT``
+
+       -  There was a failure while copying data from/to userspace, probably
+	  caused by an invalid pointer reference.
+
+    -  -  ``EINVAL``
+
+       -  One or more of the ioctl parameters are invalid or out of the
+	  allowed range. This is a widely used error code. See the
+	  individual ioctl requests for specific causes.
+
+    -  -  ``ENODEV``
+
+       -  Device not found or was removed.
+
+    -  -  ``ENOMEM``
+
+       -  There's not enough memory to handle the desired operation.
+
+    -  -  ``ENOTTY``
+
+       -  The ioctl is not supported by the driver, actually meaning that
+	  the required functionality is not available, or the file
+	  descriptor is not for a media device.
+
+    -  -  ``ENOSPC``
+
+       -  On USB devices, the stream ioctl's can return this error, meaning
+	  that this request would overcommit the usb bandwidth reserved for
+	  periodic transfers (up to 80% of the USB bandwidth).
+
+    -  -  ``EPERM``
+
+       -  Permission denied. Can be returned if the device needs write
+	  permission, or some special capabilities is needed (e. g. root)
+
+    -  -  ``EIO``
+
+       -  I/O error. Typically used when there are problems communicating with
+          a hardware device. This could indicate broken or flaky hardware.
+	  It's a 'Something is wrong, I give up!' type of error.
+
+    -  - ``ENXIO``
+
+       -  No device corresponding to this device special file exists.
+
+
+.. note::
+
+  #. This list is not exhaustive; ioctls may return other error codes.
+     Since errors may have side effects such as a driver reset,
+     applications should abort on unexpected errors, or otherwise
+     assume that the device is in a bad state.
+
+  #. Request-specific error codes are listed in the individual
+     requests descriptions.
diff --git a/Documentation/userspace-api/media/index.rst b/Documentation/userspace-api/media/index.rst
new file mode 100644
index 000000000000..70a3f3d73698
--- /dev/null
+++ b/Documentation/userspace-api/media/index.rst
@@ -0,0 +1,67 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: <isonum.txt>
+
+########################################
+Linux Media Infrastructure userspace API
+########################################
+
+This section contains the  driver development information and Kernel APIs
+used by media devices.
+
+Please see:
+
+- :doc:`/admin-guide/media/index`
+    for usage information about media subsystem and supported drivers;
+
+- :doc:`/driver-api/media/index`
+     for driver development information and Kernel APIs used by
+     media devices;
+
+
+.. only:: html
+
+   .. class:: toc-title
+
+        Table of Contents
+
+.. toctree::
+    :maxdepth: 1
+
+    intro
+    v4l/v4l2
+    dvb/dvbapi
+    rc/remote_controllers
+    mediactl/media-controller
+    cec/cec-api
+    gen-errors
+    fdl-appendix
+
+    drivers/index
+
+**Copyright** |copy| 2009-2020 : LinuxTV Developers
+
+::
+
+  Permission is granted to copy, distribute and/or modify this document
+  under the terms of the GNU Free Documentation License, Version 1.1 or
+  any later version published by the Free Software Foundation, with no
+  Invariant Sections. A copy of the license is included in the chapter
+  entitled "GNU Free Documentation License".
+
+Please notice that some documents inside the media userspace API,
+when explicitly mentioned on its source code, are dual-licensed
+with GNU Free Documentation License  Version 1.1 and with the
+GNU General Public License::
+
+  This documentation is free software; you can redistribute it and/or modify it
+  under the terms of the 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.
+
+  For more details see the file COPYING in the source distribution of Linux.
diff --git a/Documentation/userspace-api/media/intro.rst b/Documentation/userspace-api/media/intro.rst
new file mode 100644
index 000000000000..4a6bd665b884
--- /dev/null
+++ b/Documentation/userspace-api/media/intro.rst
@@ -0,0 +1,46 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+============
+Introduction
+============
+
+This document covers the Linux Kernel to Userspace API's used by video
+and radio streaming devices, including video cameras, analog and digital
+TV receiver cards, AM/FM receiver cards, Software Defined Radio (SDR),
+streaming capture and output devices, codec devices and remote controllers.
+
+A typical media device hardware is shown at :ref:`typical_media_device`.
+
+.. _typical_media_device:
+
+.. kernel-figure:: typical_media_device.svg
+    :alt:   typical_media_device.svg
+    :align: center
+
+    Typical Media Device
+
+The media infrastructure API was designed to control such devices. It is
+divided into five parts.
+
+1. The :ref:`first part <v4l2spec>` covers radio, video capture and output,
+   cameras, analog TV devices and codecs.
+
+2. The :ref:`second part <dvbapi>` covers the API used for digital TV and
+   Internet reception via one of the several digital tv standards. While it is
+   called as DVB API, in fact it covers several different video standards
+   including DVB-T/T2, DVB-S/S2, DVB-C, ATSC, ISDB-T, ISDB-S, DTMB, etc. The
+   complete list of supported standards can be found at
+   :c:type:`fe_delivery_system`.
+
+3. The :ref:`third part <remote_controllers>` covers the Remote Controller API.
+
+4. The :ref:`fourth part <media_controller>` covers the Media Controller API.
+
+5. The :ref:`fifth part <cec>` covers the CEC (Consumer Electronics Control) API.
+
+It should also be noted that a media device may also have audio components, like
+mixers, PCM capture, PCM playback, etc, which are controlled via ALSA API.  For
+additional information and for the latest development code, see:
+`https://linuxtv.org <https://linuxtv.org>`__.  For discussing improvements,
+reporting troubles, sending new drivers, etc, please mail to: `Linux Media
+Mailing List (LMML) <http://vger.kernel.org/vger-lists.html#linux-media>`__.
diff --git a/Documentation/userspace-api/media/lirc.h.rst.exceptions b/Documentation/userspace-api/media/lirc.h.rst.exceptions
new file mode 100644
index 000000000000..ac768d769113
--- /dev/null
+++ b/Documentation/userspace-api/media/lirc.h.rst.exceptions
@@ -0,0 +1,80 @@
+# SPDX-License-Identifier: GPL-2.0
+
+# Ignore header name
+ignore define _LINUX_LIRC_H
+
+# Ignore helper macros
+
+ignore define lirc_t
+
+ignore define LIRC_SPACE
+ignore define LIRC_PULSE
+ignore define LIRC_FREQUENCY
+ignore define LIRC_TIMEOUT
+ignore define LIRC_VALUE
+ignore define LIRC_MODE2
+ignore define LIRC_IS_SPACE
+ignore define LIRC_IS_PULSE
+ignore define LIRC_IS_FREQUENCY
+ignore define LIRC_IS_TIMEOUT
+
+ignore define LIRC_MODE2SEND
+ignore define LIRC_SEND2MODE
+ignore define LIRC_MODE2REC
+ignore define LIRC_REC2MODE
+
+ignore define LIRC_CAN_SEND
+ignore define LIRC_CAN_REC
+
+ignore define LIRC_CAN_SEND_MASK
+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
+ignore symbol RC_PROTO_IMON
+ignore symbol RC_PROTO_RCMM12
+ignore symbol RC_PROTO_RCMM24
+ignore symbol RC_PROTO_RCMM32
+ignore symbol RC_PROTO_XBOX_DVD
+
+# Undocumented macros
+
+ignore define PULSE_BIT
+ignore define PULSE_MASK
+
+ignore define LIRC_MODE2_SPACE
+ignore define LIRC_MODE2_PULSE
+
+ignore define LIRC_VALUE_MASK
+ignore define LIRC_MODE2_MASK
+
+ignore define LIRC_MODE_RAW
+ignore define LIRC_MODE_LIRCCODE
diff --git a/Documentation/userspace-api/media/media.h.rst.exceptions b/Documentation/userspace-api/media/media.h.rst.exceptions
new file mode 100644
index 000000000000..9b4c26502d95
--- /dev/null
+++ b/Documentation/userspace-api/media/media.h.rst.exceptions
@@ -0,0 +1,32 @@
+# SPDX-License-Identifier: GPL-2.0
+
+# Ignore header name
+ignore define __LINUX_MEDIA_H
+
+# Ignore macros
+ignore define MEDIA_API_VERSION
+ignore define MEDIA_ENT_F_BASE
+ignore define MEDIA_ENT_F_OLD_BASE
+ignore define MEDIA_ENT_F_OLD_SUBDEV_BASE
+ignore define MEDIA_ENT_F_DTV_DECODER
+ignore define MEDIA_INTF_T_DVB_BASE
+ignore define MEDIA_INTF_T_V4L_BASE
+ignore define MEDIA_INTF_T_ALSA_BASE
+#ignore legacy entity type macros
+ignore define MEDIA_ENT_TYPE_SHIFT
+ignore define MEDIA_ENT_TYPE_MASK
+ignore define MEDIA_ENT_SUBTYPE_MASK
+ignore define MEDIA_ENT_T_DEVNODE_UNKNOWN
+ignore define MEDIA_ENT_T_DEVNODE
+ignore define MEDIA_ENT_T_DEVNODE_V4L
+ignore define MEDIA_ENT_T_DEVNODE_FB
+ignore define MEDIA_ENT_T_DEVNODE_ALSA
+ignore define MEDIA_ENT_T_DEVNODE_DVB
+ignore define MEDIA_ENT_T_UNKNOWN
+ignore define MEDIA_ENT_T_V4L2_VIDEO
+ignore define MEDIA_ENT_T_V4L2_SUBDEV
+ignore define MEDIA_ENT_T_V4L2_SUBDEV_SENSOR
+ignore define MEDIA_ENT_T_V4L2_SUBDEV_FLASH
+ignore define MEDIA_ENT_T_V4L2_SUBDEV_LENS
+ignore define MEDIA_ENT_T_V4L2_SUBDEV_DECODER
+ignore define MEDIA_ENT_T_V4L2_SUBDEV_TUNER
diff --git a/Documentation/userspace-api/media/mediactl/media-controller-intro.rst b/Documentation/userspace-api/media/mediactl/media-controller-intro.rst
new file mode 100644
index 000000000000..1d06ea4c4d09
--- /dev/null
+++ b/Documentation/userspace-api/media/mediactl/media-controller-intro.rst
@@ -0,0 +1,40 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _media-controller-intro:
+
+Introduction
+============
+
+Media devices increasingly handle multiple related functions. Many USB
+cameras include microphones, video capture hardware can also output
+video, or SoC camera interfaces also perform memory-to-memory operations
+similar to video codecs.
+
+Independent functions, even when implemented in the same hardware, can
+be modelled as separate devices. A USB camera with a microphone will be
+presented to userspace applications as V4L2 and ALSA capture devices.
+The devices' relationships (when using a webcam, end-users shouldn't
+have to manually select the associated USB microphone), while not made
+available directly to applications by the drivers, can usually be
+retrieved from sysfs.
+
+With more and more advanced SoC devices being introduced, the current
+approach will not scale. Device topologies are getting increasingly
+complex and can't always be represented by a tree structure. Hardware
+blocks are shared between different functions, creating dependencies
+between seemingly unrelated devices.
+
+Kernel abstraction APIs such as V4L2 and ALSA provide means for
+applications to access hardware parameters. As newer hardware expose an
+increasingly high number of those parameters, drivers need to guess what
+applications really require based on limited information, thereby
+implementing policies that belong to userspace.
+
+The media controller API aims at solving those problems.
diff --git a/Documentation/userspace-api/media/mediactl/media-controller-model.rst b/Documentation/userspace-api/media/mediactl/media-controller-model.rst
new file mode 100644
index 000000000000..865e73d934d6
--- /dev/null
+++ b/Documentation/userspace-api/media/mediactl/media-controller-model.rst
@@ -0,0 +1,42 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _media-controller-model:
+
+Media device model
+==================
+
+Discovering a device internal topology, and configuring it at runtime,
+is one of the goals of the media controller API. To achieve this,
+hardware devices and Linux Kernel interfaces are modelled as graph
+objects on an oriented graph. The object types that constitute the graph
+are:
+
+-  An **entity** is a basic media hardware or software building block.
+   It can correspond to a large variety of logical blocks such as
+   physical hardware devices (CMOS sensor for instance), logical
+   hardware devices (a building block in a System-on-Chip image
+   processing pipeline), DMA channels or physical connectors.
+
+-  An **interface** is a graph representation of a Linux Kernel
+   userspace API interface, like a device node or a sysfs file that
+   controls one or more entities in the graph.
+
+-  A **pad** is a data connection endpoint through which an entity can
+   interact with other entities. Data (not restricted to video) produced
+   by an entity flows from the entity's output to one or more entity
+   inputs. Pads should not be confused with physical pins at chip
+   boundaries.
+
+-  A **data link** is a point-to-point oriented connection between two
+   pads, either on the same entity or on different entities. Data flows
+   from a source pad to a sink pad.
+
+-  An **interface link** is a point-to-point bidirectional control
+   connection between a Linux Kernel interface and an entity.
diff --git a/Documentation/userspace-api/media/mediactl/media-controller.rst b/Documentation/userspace-api/media/mediactl/media-controller.rst
new file mode 100644
index 000000000000..16bc3ab180d3
--- /dev/null
+++ b/Documentation/userspace-api/media/mediactl/media-controller.rst
@@ -0,0 +1,62 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. include:: <isonum.txt>
+
+.. _media_controller:
+
+##############################
+Part IV - Media Controller API
+##############################
+
+.. only:: html
+
+   .. class:: toc-title
+
+        Table of Contents
+
+.. toctree::
+    :maxdepth: 5
+    :numbered:
+
+    media-controller-intro
+    media-controller-model
+    media-types
+    request-api
+    media-funcs
+    media-header
+
+
+**********************
+Revision and Copyright
+**********************
+
+Authors:
+
+- Pinchart, Laurent <laurent.pinchart@ideasonboard.com>
+
+ - Initial version.
+
+- Carvalho Chehab, Mauro <mchehab@kernel.org>
+
+ - MEDIA_IOC_G_TOPOLOGY documentation and documentation improvements.
+
+**Copyright** |copy| 2010 : Laurent Pinchart
+
+**Copyright** |copy| 2015-2016 : Mauro Carvalho Chehab
+
+****************
+Revision History
+****************
+
+:revision: 1.1.0 / 2015-12-12 (*mcc*)
+
+:revision: 1.0.0 / 2010-11-10 (*lp*)
+
+Initial revision
diff --git a/Documentation/userspace-api/media/mediactl/media-func-close.rst b/Documentation/userspace-api/media/mediactl/media-func-close.rst
new file mode 100644
index 000000000000..ceec61c9e7c5
--- /dev/null
+++ b/Documentation/userspace-api/media/mediactl/media-func-close.rst
@@ -0,0 +1,54 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _media-func-close:
+
+*************
+media close()
+*************
+
+Name
+====
+
+media-close - Close a media device
+
+
+Synopsis
+========
+
+.. code-block:: c
+
+    #include <unistd.h>
+
+
+.. c:function:: int close( int fd )
+    :name: mc-close
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :c:func:`open() <mc-open>`.
+
+
+Description
+===========
+
+Closes the media device. Resources associated with the file descriptor
+are freed. The device configuration remain unchanged.
+
+
+Return Value
+============
+
+:ref:`close() <media-func-close>` returns 0 on success. On error, -1 is returned, and
+``errno`` is set appropriately. Possible error codes are:
+
+EBADF
+    ``fd`` is not a valid open file descriptor.
diff --git a/Documentation/userspace-api/media/mediactl/media-func-ioctl.rst b/Documentation/userspace-api/media/mediactl/media-func-ioctl.rst
new file mode 100644
index 000000000000..629e7be7c5be
--- /dev/null
+++ b/Documentation/userspace-api/media/mediactl/media-func-ioctl.rst
@@ -0,0 +1,74 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _media-func-ioctl:
+
+*************
+media ioctl()
+*************
+
+Name
+====
+
+media-ioctl - Control a media device
+
+
+Synopsis
+========
+
+.. code-block:: c
+
+    #include <sys/ioctl.h>
+
+
+.. c:function:: int ioctl( int fd, int request, void *argp )
+    :name: mc-ioctl
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :c:func:`open() <mc-open>`.
+
+``request``
+    Media ioctl request code as defined in the media.h header file, for
+    example MEDIA_IOC_SETUP_LINK.
+
+``argp``
+    Pointer to a request-specific structure.
+
+
+Description
+===========
+
+The :ref:`ioctl() <media-func-ioctl>` function manipulates media device
+parameters. The argument ``fd`` must be an open file descriptor.
+
+The ioctl ``request`` code specifies the media function to be called. It
+has encoded in it whether the argument is an input, output or read/write
+parameter, and the size of the argument ``argp`` in bytes.
+
+Macros and structures definitions specifying media ioctl requests and
+their parameters are located in the media.h header file. All media ioctl
+requests, their respective function and parameters are specified in
+:ref:`media-user-func`.
+
+
+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.
+
+Request-specific error codes are listed in the individual requests
+descriptions.
+
+When an ioctl that takes an output or read/write parameter fails, the
+parameter remains unmodified.
diff --git a/Documentation/userspace-api/media/mediactl/media-func-open.rst b/Documentation/userspace-api/media/mediactl/media-func-open.rst
new file mode 100644
index 000000000000..4ade1cc5048f
--- /dev/null
+++ b/Documentation/userspace-api/media/mediactl/media-func-open.rst
@@ -0,0 +1,76 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _media-func-open:
+
+************
+media open()
+************
+
+Name
+====
+
+media-open - Open a media device
+
+
+Synopsis
+========
+
+.. code-block:: c
+
+    #include <fcntl.h>
+
+
+.. c:function:: int open( const char *device_name, int flags )
+    :name: mc-open
+
+Arguments
+=========
+
+``device_name``
+    Device to be opened.
+
+``flags``
+    Open flags. Access mode must be either ``O_RDONLY`` or ``O_RDWR``.
+    Other flags have no effect.
+
+
+Description
+===========
+
+To open a media device applications call :ref:`open() <media-func-open>` with the
+desired device name. The function has no side effects; the device
+configuration remain unchanged.
+
+When the device is opened in read-only mode, attempts to modify its
+configuration will result in an error, and ``errno`` will be set to
+EBADF.
+
+
+Return Value
+============
+
+:ref:`open() <func-open>` returns the new file descriptor on success. On error,
+-1 is returned, and ``errno`` is set appropriately. Possible error codes
+are:
+
+EACCES
+    The requested access to the file is not allowed.
+
+EMFILE
+    The process already has the maximum number of files open.
+
+ENFILE
+    The system limit on the total number of open files has been reached.
+
+ENOMEM
+    Insufficient kernel memory was available.
+
+ENXIO
+    No device corresponding to this device special file exists.
diff --git a/Documentation/userspace-api/media/mediactl/media-funcs.rst b/Documentation/userspace-api/media/mediactl/media-funcs.rst
new file mode 100644
index 000000000000..085e80e7fbd5
--- /dev/null
+++ b/Documentation/userspace-api/media/mediactl/media-funcs.rst
@@ -0,0 +1,33 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _media-user-func:
+
+******************
+Function Reference
+******************
+
+
+.. toctree::
+    :maxdepth: 1
+
+    media-func-open
+    media-func-close
+    media-func-ioctl
+    media-ioc-device-info
+    media-ioc-g-topology
+    media-ioc-enum-entities
+    media-ioc-enum-links
+    media-ioc-setup-link
+    media-ioc-request-alloc
+    request-func-close
+    request-func-ioctl
+    request-func-poll
+    media-request-ioc-queue
+    media-request-ioc-reinit
diff --git a/Documentation/userspace-api/media/mediactl/media-header.rst b/Documentation/userspace-api/media/mediactl/media-header.rst
new file mode 100644
index 000000000000..7ff9d24ce65f
--- /dev/null
+++ b/Documentation/userspace-api/media/mediactl/media-header.rst
@@ -0,0 +1,17 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _media_header:
+
+****************************
+Media Controller Header File
+****************************
+
+.. kernel-include:: $BUILDDIR/media.h.rst
+
diff --git a/Documentation/userspace-api/media/mediactl/media-ioc-device-info.rst b/Documentation/userspace-api/media/mediactl/media-ioc-device-info.rst
new file mode 100644
index 000000000000..9c729bdc8e85
--- /dev/null
+++ b/Documentation/userspace-api/media/mediactl/media-ioc-device-info.rst
@@ -0,0 +1,118 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _media_ioc_device_info:
+
+***************************
+ioctl MEDIA_IOC_DEVICE_INFO
+***************************
+
+Name
+====
+
+MEDIA_IOC_DEVICE_INFO - Query device information
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, MEDIA_IOC_DEVICE_INFO, struct media_device_info *argp )
+    :name: MEDIA_IOC_DEVICE_INFO
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <media-func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`media_device_info`.
+
+
+Description
+===========
+
+All media devices must support the ``MEDIA_IOC_DEVICE_INFO`` ioctl. To
+query device information, applications call the ioctl with a pointer to
+a struct :c:type:`media_device_info`. The driver
+fills the structure and returns the information to the application. The
+ioctl never fails.
+
+
+.. c:type:: media_device_info
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. flat-table:: struct media_device_info
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+
+    *  -  char
+       -  ``driver``\ [16]
+       -  Name of the driver implementing the media API as a NUL-terminated
+	  ASCII string. The driver version is stored in the
+	  ``driver_version`` field.
+
+	  Driver specific applications can use this information to verify
+	  the driver identity. It is also useful to work around known bugs,
+	  or to identify drivers in error reports.
+
+    *  -  char
+       -  ``model``\ [32]
+       -  Device model name as a NUL-terminated UTF-8 string. The device
+	  version is stored in the ``device_version`` field and is not be
+	  appended to the model name.
+
+    *  -  char
+       -  ``serial``\ [40]
+       -  Serial number as a NUL-terminated ASCII string.
+
+    *  -  char
+       -  ``bus_info``\ [32]
+       -  Location of the device in the system as a NUL-terminated ASCII
+	  string. This includes the bus type name (PCI, USB, ...) and a
+	  bus-specific identifier.
+
+    *  -  __u32
+       -  ``media_version``
+       -  Media API version, formatted with the ``KERNEL_VERSION()`` macro.
+
+    *  -  __u32
+       -  ``hw_revision``
+       -  Hardware device revision in a driver-specific format.
+
+    *  -  __u32
+       -  ``driver_version``
+       -  Media device driver version, formatted with the
+	  ``KERNEL_VERSION()`` macro. Together with the ``driver`` field
+	  this identifies a particular driver.
+
+    *  -  __u32
+       -  ``reserved``\ [31]
+       -  Reserved for future extensions. Drivers and applications must set
+	  this array to zero.
+
+
+The ``serial`` and ``bus_info`` fields can be used to distinguish
+between multiple instances of otherwise identical hardware. The serial
+number takes precedence when provided and can be assumed to be unique.
+If the serial number is an empty string, the ``bus_info`` field can be
+used instead. The ``bus_info`` field is guaranteed to be unique, but can
+vary across reboots or device unplug/replug.
+
+
+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/userspace-api/media/mediactl/media-ioc-enum-entities.rst b/Documentation/userspace-api/media/mediactl/media-ioc-enum-entities.rst
new file mode 100644
index 000000000000..1d01de8e0f97
--- /dev/null
+++ b/Documentation/userspace-api/media/mediactl/media-ioc-enum-entities.rst
@@ -0,0 +1,156 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _media_ioc_enum_entities:
+
+*****************************
+ioctl MEDIA_IOC_ENUM_ENTITIES
+*****************************
+
+Name
+====
+
+MEDIA_IOC_ENUM_ENTITIES - Enumerate entities and their properties
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, MEDIA_IOC_ENUM_ENTITIES, struct media_entity_desc *argp )
+    :name: MEDIA_IOC_ENUM_ENTITIES
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <media-func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`media_entity_desc`.
+
+
+Description
+===========
+
+To query the attributes of an entity, applications set the id field of a
+struct :c:type:`media_entity_desc` structure and
+call the MEDIA_IOC_ENUM_ENTITIES ioctl with a pointer to this
+structure. The driver fills the rest of the structure or returns an
+EINVAL error code when the id is invalid.
+
+.. _media-ent-id-flag-next:
+
+Entities can be enumerated by or'ing the id with the
+``MEDIA_ENT_ID_FLAG_NEXT`` flag. The driver will return information
+about the entity with the smallest id strictly larger than the requested
+one ('next entity'), or the ``EINVAL`` error code if there is none.
+
+Entity IDs can be non-contiguous. Applications must *not* try to
+enumerate entities by calling MEDIA_IOC_ENUM_ENTITIES with increasing
+id's until they get an error.
+
+
+.. c:type:: media_entity_desc
+
+.. tabularcolumns:: |p{1.5cm}|p{1.7cm}|p{1.6cm}|p{1.5cm}|p{11.2cm}|
+
+.. flat-table:: struct media_entity_desc
+    :header-rows:  0
+    :stub-columns: 0
+    :widths: 2 2 1 8
+
+    *  -  __u32
+       -  ``id``
+       -
+       -  Entity ID, set by the application. When the ID is or'ed with
+	  ``MEDIA_ENT_ID_FLAG_NEXT``, the driver clears the flag and returns
+	  the first entity with a larger ID. Do not expect that the ID will
+	  always be the same for each instance of the device. In other words,
+	  do not hardcode entity IDs in an application.
+
+    *  -  char
+       -  ``name``\ [32]
+       -
+       -  Entity name as an UTF-8 NULL-terminated string. This name must be unique
+          within the media topology.
+
+    *  -  __u32
+       -  ``type``
+       -
+       -  Entity type, see :ref:`media-entity-functions` for details.
+
+    *  -  __u32
+       -  ``revision``
+       -
+       -  Entity revision. Always zero (obsolete)
+
+    *  -  __u32
+       -  ``flags``
+       -
+       -  Entity flags, see :ref:`media-entity-flag` for details.
+
+    *  -  __u32
+       -  ``group_id``
+       -
+       -  Entity group ID. Always zero (obsolete)
+
+    *  -  __u16
+       -  ``pads``
+       -
+       -  Number of pads
+
+    *  -  __u16
+       -  ``links``
+       -
+       -  Total number of outbound links. Inbound links are not counted in
+	  this field.
+
+    *  -  __u32
+       -  ``reserved[4]``
+       -
+       -  Reserved for future extensions. Drivers and applications must set
+          the array to zero.
+
+    *  -  union {
+       -  (anonymous)
+
+    *  -  struct
+       -  ``dev``
+       -
+       -  Valid for (sub-)devices that create a single device node.
+
+    *  -
+       -  __u32
+       -  ``major``
+       -  Device node major number.
+
+    *  -
+       -  __u32
+       -  ``minor``
+       -  Device node minor number.
+
+    *  -  __u8
+       -  ``raw``\ [184]
+       -
+       -
+    *  - }
+       -
+
+
+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
+    The struct :c:type:`media_entity_desc` ``id``
+    references a non-existing entity.
diff --git a/Documentation/userspace-api/media/mediactl/media-ioc-enum-links.rst b/Documentation/userspace-api/media/mediactl/media-ioc-enum-links.rst
new file mode 100644
index 000000000000..9929b639db97
--- /dev/null
+++ b/Documentation/userspace-api/media/mediactl/media-ioc-enum-links.rst
@@ -0,0 +1,157 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _media_ioc_enum_links:
+
+**************************
+ioctl MEDIA_IOC_ENUM_LINKS
+**************************
+
+Name
+====
+
+MEDIA_IOC_ENUM_LINKS - Enumerate all pads and links for a given entity
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, MEDIA_IOC_ENUM_LINKS, struct media_links_enum *argp )
+    :name: MEDIA_IOC_ENUM_LINKS
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <media-func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`media_links_enum`.
+
+
+Description
+===========
+
+To enumerate pads and/or links for a given entity, applications set the
+entity field of a struct :c:type:`media_links_enum`
+structure and initialize the struct
+:c:type:`media_pad_desc` and struct
+:c:type:`media_link_desc` structure arrays pointed by
+the ``pads`` and ``links`` fields. They then call the
+MEDIA_IOC_ENUM_LINKS ioctl with a pointer to this structure.
+
+If the ``pads`` field is not NULL, the driver fills the ``pads`` array
+with information about the entity's pads. The array must have enough
+room to store all the entity's pads. The number of pads can be retrieved
+with :ref:`MEDIA_IOC_ENUM_ENTITIES`.
+
+If the ``links`` field is not NULL, the driver fills the ``links`` array
+with information about the entity's outbound links. The array must have
+enough room to store all the entity's outbound links. The number of
+outbound links can be retrieved with :ref:`MEDIA_IOC_ENUM_ENTITIES`.
+
+Only forward links that originate at one of the entity's source pads are
+returned during the enumeration process.
+
+
+.. c:type:: media_links_enum
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. flat-table:: struct media_links_enum
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    *  -  __u32
+       -  ``entity``
+       -  Entity id, set by the application.
+
+    *  -  struct :c:type:`media_pad_desc`
+       -  \*\ ``pads``
+       -  Pointer to a pads array allocated by the application. Ignored if
+	  NULL.
+
+    *  -  struct :c:type:`media_link_desc`
+       -  \*\ ``links``
+       -  Pointer to a links array allocated by the application. Ignored if
+	  NULL.
+
+    *  -  __u32
+       -  ``reserved[4]``
+       -  Reserved for future extensions. Drivers and applications must set
+          the array to zero.
+
+
+.. c:type:: media_pad_desc
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. flat-table:: struct media_pad_desc
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    *  -  __u32
+       -  ``entity``
+       -  ID of the entity this pad belongs to.
+
+    *  -  __u16
+       -  ``index``
+       -  Pad index, starts at 0.
+
+    *  -  __u32
+       -  ``flags``
+       -  Pad flags, see :ref:`media-pad-flag` for more details.
+
+    *  -  __u32
+       -  ``reserved[2]``
+       -  Reserved for future extensions. Drivers and applications must set
+          the array to zero.
+
+
+
+.. c:type:: media_link_desc
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. flat-table:: struct media_link_desc
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    *  -  struct :c:type:`media_pad_desc`
+       -  ``source``
+       -  Pad at the origin of this link.
+
+    *  -  struct :c:type:`media_pad_desc`
+       -  ``sink``
+       -  Pad at the target of this link.
+
+    *  -  __u32
+       -  ``flags``
+       -  Link flags, see :ref:`media-link-flag` for more details.
+
+    *  -  __u32
+       -  ``reserved[2]``
+       -  Reserved for future extensions. Drivers and applications must set
+          the array to zero.
+
+
+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
+    The struct :c:type:`media_links_enum` ``id``
+    references a non-existing entity.
diff --git a/Documentation/userspace-api/media/mediactl/media-ioc-g-topology.rst b/Documentation/userspace-api/media/mediactl/media-ioc-g-topology.rst
new file mode 100644
index 000000000000..54e3112a3b5a
--- /dev/null
+++ b/Documentation/userspace-api/media/mediactl/media-ioc-g-topology.rst
@@ -0,0 +1,307 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _media_ioc_g_topology:
+
+**************************
+ioctl MEDIA_IOC_G_TOPOLOGY
+**************************
+
+Name
+====
+
+MEDIA_IOC_G_TOPOLOGY - Enumerate the graph topology and graph element properties
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, MEDIA_IOC_G_TOPOLOGY, struct media_v2_topology *argp )
+    :name: MEDIA_IOC_G_TOPOLOGY
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <media-func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`media_v2_topology`.
+
+
+Description
+===========
+
+The typical usage of this ioctl is to call it twice. On the first call,
+the structure defined at struct
+:c:type:`media_v2_topology` should be zeroed. At
+return, if no errors happen, this ioctl will return the
+``topology_version`` and the total number of entities, interfaces, pads
+and links.
+
+Before the second call, the userspace should allocate arrays to store
+the graph elements that are desired, putting the pointers to them at the
+ptr_entities, ptr_interfaces, ptr_links and/or ptr_pads, keeping the
+other values untouched.
+
+If the ``topology_version`` remains the same, the ioctl should fill the
+desired arrays with the media graph elements.
+
+.. tabularcolumns:: |p{1.6cm}|p{3.4cm}|p{12.5cm}|
+
+.. c:type:: media_v2_topology
+
+.. flat-table:: struct media_v2_topology
+    :header-rows:  0
+    :stub-columns: 0
+    :widths: 1 2 8
+
+    *  -  __u64
+       -  ``topology_version``
+       -  Version of the media graph topology. When the graph is created,
+	  this field starts with zero. Every time a graph element is added
+	  or removed, this field is incremented.
+
+    *  -  __u32
+       -  ``num_entities``
+       -  Number of entities in the graph
+
+    *  -  __u32
+       -  ``reserved1``
+       -  Applications and drivers shall set this to 0.
+
+    *  -  __u64
+       -  ``ptr_entities``
+       -  A pointer to a memory area where the entities array will be
+	  stored, converted to a 64-bits integer. It can be zero. if zero,
+	  the ioctl won't store the entities. It will just update
+	  ``num_entities``
+
+    *  -  __u32
+       -  ``num_interfaces``
+       -  Number of interfaces in the graph
+
+    *  -  __u32
+       -  ``reserved2``
+       -  Applications and drivers shall set this to 0.
+
+    *  -  __u64
+       -  ``ptr_interfaces``
+       -  A pointer to a memory area where the interfaces array will be
+	  stored, converted to a 64-bits integer. It can be zero. if zero,
+	  the ioctl won't store the interfaces. It will just update
+	  ``num_interfaces``
+
+    *  -  __u32
+       -  ``num_pads``
+       -  Total number of pads in the graph
+
+    *  -  __u32
+       -  ``reserved3``
+       -  Applications and drivers shall set this to 0.
+
+    *  -  __u64
+       -  ``ptr_pads``
+       -  A pointer to a memory area where the pads array will be stored,
+	  converted to a 64-bits integer. It can be zero. if zero, the ioctl
+	  won't store the pads. It will just update ``num_pads``
+
+    *  -  __u32
+       -  ``num_links``
+       -  Total number of data and interface links in the graph
+
+    *  -  __u32
+       -  ``reserved4``
+       -  Applications and drivers shall set this to 0.
+
+    *  -  __u64
+       -  ``ptr_links``
+       -  A pointer to a memory area where the links array will be stored,
+	  converted to a 64-bits integer. It can be zero. if zero, the ioctl
+	  won't store the links. It will just update ``num_links``
+
+
+.. tabularcolumns:: |p{1.6cm}|p{3.2cm}|p{12.7cm}|
+
+.. c:type:: media_v2_entity
+
+.. flat-table:: struct media_v2_entity
+    :header-rows:  0
+    :stub-columns: 0
+    :widths: 1 2 8
+
+    *  -  __u32
+       -  ``id``
+       -  Unique ID for the entity. Do not expect that the ID will
+	  always be the same for each instance of the device. In other words,
+	  do not hardcode entity IDs in an application.
+
+    *  -  char
+       -  ``name``\ [64]
+       -  Entity name as an UTF-8 NULL-terminated string. This name must be unique
+          within the media topology.
+
+    *  -  __u32
+       -  ``function``
+       -  Entity main function, see :ref:`media-entity-functions` for details.
+
+    *  -  __u32
+       -  ``flags``
+       -  Entity flags, see :ref:`media-entity-flag` for details.
+	  Only valid if ``MEDIA_V2_ENTITY_HAS_FLAGS(media_version)``
+	  returns true. The ``media_version`` is defined in struct
+	  :c:type:`media_device_info` and can be retrieved using
+	  :ref:`MEDIA_IOC_DEVICE_INFO`.
+
+    *  -  __u32
+       -  ``reserved``\ [5]
+       -  Reserved for future extensions. Drivers and applications must set
+	  this array to zero.
+
+
+.. tabularcolumns:: |p{1.6cm}|p{3.2cm}|p{12.7cm}|
+
+.. c:type:: media_v2_interface
+
+.. flat-table:: struct media_v2_interface
+    :header-rows:  0
+    :stub-columns: 0
+    :widths: 1 2 8
+
+    *  -  __u32
+       -  ``id``
+       -  Unique ID for the interface. Do not expect that the ID will
+	  always be the same for each instance of the device. In other words,
+	  do not hardcode interface IDs in an application.
+
+    *  -  __u32
+       -  ``intf_type``
+       -  Interface type, see :ref:`media-intf-type` for details.
+
+    *  -  __u32
+       -  ``flags``
+       -  Interface flags. Currently unused.
+
+    *  -  __u32
+       -  ``reserved``\ [9]
+       -  Reserved for future extensions. Drivers and applications must set
+	  this array to zero.
+
+    *  -  struct media_v2_intf_devnode
+       -  ``devnode``
+       -  Used only for device node interfaces. See
+	  :c:type:`media_v2_intf_devnode` for details.
+
+
+.. tabularcolumns:: |p{1.6cm}|p{3.2cm}|p{12.7cm}|
+
+.. c:type:: media_v2_intf_devnode
+
+.. flat-table:: struct media_v2_intf_devnode
+    :header-rows:  0
+    :stub-columns: 0
+    :widths: 1 2 8
+
+    *  -  __u32
+       -  ``major``
+       -  Device node major number.
+
+    *  -  __u32
+       -  ``minor``
+       -  Device node minor number.
+
+.. tabularcolumns:: |p{1.6cm}|p{3.2cm}|p{12.7cm}|
+
+.. c:type:: media_v2_pad
+
+.. flat-table:: struct media_v2_pad
+    :header-rows:  0
+    :stub-columns: 0
+    :widths: 1 2 8
+
+    *  -  __u32
+       -  ``id``
+       -  Unique ID for the pad. Do not expect that the ID will
+	  always be the same for each instance of the device. In other words,
+	  do not hardcode pad IDs in an application.
+
+    *  -  __u32
+       -  ``entity_id``
+       -  Unique ID for the entity where this pad belongs.
+
+    *  -  __u32
+       -  ``flags``
+       -  Pad flags, see :ref:`media-pad-flag` for more details.
+
+    *  -  __u32
+       -  ``index``
+       -  Pad index, starts at 0. Only valid if ``MEDIA_V2_PAD_HAS_INDEX(media_version)``
+	  returns true. The ``media_version`` is defined in struct
+	  :c:type:`media_device_info` and can be retrieved using
+	  :ref:`MEDIA_IOC_DEVICE_INFO`.
+
+    *  -  __u32
+       -  ``reserved``\ [4]
+       -  Reserved for future extensions. Drivers and applications must set
+	  this array to zero.
+
+
+.. tabularcolumns:: |p{1.6cm}|p{3.2cm}|p{12.7cm}|
+
+.. c:type:: media_v2_link
+
+.. flat-table:: struct media_v2_link
+    :header-rows:  0
+    :stub-columns: 0
+    :widths: 1 2 8
+
+    *  -  __u32
+       -  ``id``
+       -  Unique ID for the link. Do not expect that the ID will
+	  always be the same for each instance of the device. In other words,
+	  do not hardcode link IDs in an application.
+
+    *  -  __u32
+       -  ``source_id``
+       -  On pad to pad links: unique ID for the source pad.
+
+	  On interface to entity links: unique ID for the interface.
+
+    *  -  __u32
+       -  ``sink_id``
+       -  On pad to pad links: unique ID for the sink pad.
+
+	  On interface to entity links: unique ID for the entity.
+
+    *  -  __u32
+       -  ``flags``
+       -  Link flags, see :ref:`media-link-flag` for more details.
+
+    *  -  __u32
+       -  ``reserved``\ [6]
+       -  Reserved for future extensions. Drivers and applications must set
+	  this array to zero.
+
+
+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.
+
+ENOSPC
+    This is returned when either one or more of the num_entities,
+    num_interfaces, num_links or num_pads are non-zero and are
+    smaller than the actual number of elements inside the graph. This
+    may happen if the ``topology_version`` changed when compared to the
+    last time this ioctl was called. Userspace should usually free the
+    area for the pointers, zero the struct elements and call this ioctl
+    again.
diff --git a/Documentation/userspace-api/media/mediactl/media-ioc-request-alloc.rst b/Documentation/userspace-api/media/mediactl/media-ioc-request-alloc.rst
new file mode 100644
index 000000000000..82f86466c7f2
--- /dev/null
+++ b/Documentation/userspace-api/media/mediactl/media-ioc-request-alloc.rst
@@ -0,0 +1,90 @@
+.. This file is dual-licensed: you can use it either under the terms
+.. of the GPL 2.0 or the GFDL 1.1+ license, at your option. Note that this
+.. dual licensing only applies to this file, and not this project as a
+.. whole.
+..
+.. a) This file is free software; you can redistribute it and/or
+..    modify it under the terms of the GNU General Public License as
+..    published by the Free Software Foundation version 2 of
+..    the License.
+..
+..    This file is distributed in the hope that it will be useful,
+..    but WITHOUT ANY WARRANTY; without even the implied warranty of
+..    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+..    GNU General Public License for more details.
+..
+.. Or, alternatively,
+..
+.. b) Permission is granted to copy, distribute and/or modify this
+..    document under the terms of the GNU Free Documentation License,
+..    Version 1.1 or any later version published by the Free Software
+..    Foundation, with no Invariant Sections, no Front-Cover Texts
+..    and no Back-Cover Texts. A copy of the license is included at
+..    Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _media_ioc_request_alloc:
+
+*****************************
+ioctl MEDIA_IOC_REQUEST_ALLOC
+*****************************
+
+Name
+====
+
+MEDIA_IOC_REQUEST_ALLOC - Allocate a request
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, MEDIA_IOC_REQUEST_ALLOC, int *argp )
+    :name: MEDIA_IOC_REQUEST_ALLOC
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <media-func-open>`.
+
+``argp``
+    Pointer to an integer.
+
+
+Description
+===========
+
+If the media device supports :ref:`requests <media-request-api>`, then
+this ioctl can be used to allocate a request. If it is not supported, then
+``errno`` is set to ``ENOTTY``. A request is accessed through a file descriptor
+that is returned in ``*argp``.
+
+If the request was successfully allocated, then the request file descriptor
+can be passed to the :ref:`VIDIOC_QBUF <VIDIOC_QBUF>`,
+:ref:`VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>`,
+:ref:`VIDIOC_S_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` and
+:ref:`VIDIOC_TRY_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` ioctls.
+
+In addition, the request can be queued by calling
+:ref:`MEDIA_REQUEST_IOC_QUEUE` and re-initialized by calling
+:ref:`MEDIA_REQUEST_IOC_REINIT`.
+
+Finally, the file descriptor can be :ref:`polled <request-func-poll>` to wait
+for the request to complete.
+
+The request will remain allocated until all the file descriptors associated
+with it are closed by :ref:`close() <request-func-close>` and the driver no
+longer uses the request internally. See also
+:ref:`here <media-request-life-time>` for more information.
+
+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.
+
+ENOTTY
+    The driver has no support for requests.
diff --git a/Documentation/userspace-api/media/mediactl/media-ioc-setup-link.rst b/Documentation/userspace-api/media/mediactl/media-ioc-setup-link.rst
new file mode 100644
index 000000000000..7da3d0028285
--- /dev/null
+++ b/Documentation/userspace-api/media/mediactl/media-ioc-setup-link.rst
@@ -0,0 +1,74 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _media_ioc_setup_link:
+
+**************************
+ioctl MEDIA_IOC_SETUP_LINK
+**************************
+
+Name
+====
+
+MEDIA_IOC_SETUP_LINK - Modify the properties of a link
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, MEDIA_IOC_SETUP_LINK, struct media_link_desc *argp )
+    :name: MEDIA_IOC_SETUP_LINK
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <media-func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`media_link_desc`.
+
+
+Description
+===========
+
+To change link properties applications fill a struct
+:c:type:`media_link_desc` with link identification
+information (source and sink pad) and the new requested link flags. They
+then call the MEDIA_IOC_SETUP_LINK ioctl with a pointer to that
+structure.
+
+The only configurable property is the ``ENABLED`` link flag to
+enable/disable a link. Links marked with the ``IMMUTABLE`` link flag can
+not be enabled or disabled.
+
+Link configuration has no side effect on other links. If an enabled link
+at the sink pad prevents the link from being enabled, the driver returns
+with an ``EBUSY`` error code.
+
+Only links marked with the ``DYNAMIC`` link flag can be enabled/disabled
+while streaming media data. Attempting to enable or disable a streaming
+non-dynamic link will return an ``EBUSY`` error code.
+
+If the specified link can't be found the driver returns with an ``EINVAL``
+error code.
+
+
+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
+    The struct :c:type:`media_link_desc` references a
+    non-existing link, or the link is immutable and an attempt to modify
+    its configuration was made.
diff --git a/Documentation/userspace-api/media/mediactl/media-request-ioc-queue.rst b/Documentation/userspace-api/media/mediactl/media-request-ioc-queue.rst
new file mode 100644
index 000000000000..ad55b6b32616
--- /dev/null
+++ b/Documentation/userspace-api/media/mediactl/media-request-ioc-queue.rst
@@ -0,0 +1,102 @@
+.. This file is dual-licensed: you can use it either under the terms
+.. of the GPL 2.0 or the GFDL 1.1+ license, at your option. Note that this
+.. dual licensing only applies to this file, and not this project as a
+.. whole.
+..
+.. a) This file is free software; you can redistribute it and/or
+..    modify it under the terms of the GNU General Public License as
+..    published by the Free Software Foundation version 2 of
+..    the License.
+..
+..    This file is distributed in the hope that it will be useful,
+..    but WITHOUT ANY WARRANTY; without even the implied warranty of
+..    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+..    GNU General Public License for more details.
+..
+.. Or, alternatively,
+..
+.. b) Permission is granted to copy, distribute and/or modify this
+..    document under the terms of the GNU Free Documentation License,
+..    Version 1.1 or any later version published by the Free Software
+..    Foundation, with no Invariant Sections, no Front-Cover Texts
+..    and no Back-Cover Texts. A copy of the license is included at
+..    Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _media_request_ioc_queue:
+
+*****************************
+ioctl MEDIA_REQUEST_IOC_QUEUE
+*****************************
+
+Name
+====
+
+MEDIA_REQUEST_IOC_QUEUE - Queue a request
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int request_fd, MEDIA_REQUEST_IOC_QUEUE )
+    :name: MEDIA_REQUEST_IOC_QUEUE
+
+
+Arguments
+=========
+
+``request_fd``
+    File descriptor returned by :ref:`MEDIA_IOC_REQUEST_ALLOC`.
+
+
+Description
+===========
+
+If the media device supports :ref:`requests <media-request-api>`, then
+this request ioctl can be used to queue a previously allocated request.
+
+If the request was successfully queued, then the file descriptor can be
+:ref:`polled <request-func-poll>` to wait for the request to complete.
+
+If the request was already queued before, then ``EBUSY`` is returned.
+Other errors can be returned if the contents of the request contained
+invalid or inconsistent data, see the next section for a list of
+common error codes. On error both the request and driver state are unchanged.
+
+Once a request is queued, then the driver is required to gracefully handle
+errors that occur when the request is applied to the hardware. The
+exception is the ``EIO`` error which signals a fatal error that requires
+the application to stop streaming to reset the hardware state.
+
+It is not allowed to mix queuing requests with queuing buffers directly
+(without a request). ``EBUSY`` will be returned if the first buffer was
+queued directly and you next try to queue a request, or vice versa.
+
+A request must contain at least one buffer, otherwise this ioctl will
+return an ``ENOENT`` error.
+
+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.
+
+EBUSY
+    The request was already queued or the application queued the first
+    buffer directly, but later attempted to use a request. It is not permitted
+    to mix the two APIs.
+ENOENT
+    The request did not contain any buffers. All requests are required
+    to have at least one buffer. This can also be returned if some required
+    configuration is missing in the request.
+ENOMEM
+    Out of memory when allocating internal data structures for this
+    request.
+EINVAL
+    The request has invalid data.
+EIO
+    The hardware is in a bad state. To recover, the application needs to
+    stop streaming to reset the hardware state and then try to restart
+    streaming.
diff --git a/Documentation/userspace-api/media/mediactl/media-request-ioc-reinit.rst b/Documentation/userspace-api/media/mediactl/media-request-ioc-reinit.rst
new file mode 100644
index 000000000000..4c43fa05c8f6
--- /dev/null
+++ b/Documentation/userspace-api/media/mediactl/media-request-ioc-reinit.rst
@@ -0,0 +1,75 @@
+.. This file is dual-licensed: you can use it either under the terms
+.. of the GPL 2.0 or the GFDL 1.1+ license, at your option. Note that this
+.. dual licensing only applies to this file, and not this project as a
+.. whole.
+..
+.. a) This file is free software; you can redistribute it and/or
+..    modify it under the terms of the GNU General Public License as
+..    published by the Free Software Foundation version 2 of
+..    the License.
+..
+..    This file is distributed in the hope that it will be useful,
+..    but WITHOUT ANY WARRANTY; without even the implied warranty of
+..    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+..    GNU General Public License for more details.
+..
+.. Or, alternatively,
+..
+.. b) Permission is granted to copy, distribute and/or modify this
+..    document under the terms of the GNU Free Documentation License,
+..    Version 1.1 or any later version published by the Free Software
+..    Foundation, with no Invariant Sections, no Front-Cover Texts
+..    and no Back-Cover Texts. A copy of the license is included at
+..    Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _media_request_ioc_reinit:
+
+******************************
+ioctl MEDIA_REQUEST_IOC_REINIT
+******************************
+
+Name
+====
+
+MEDIA_REQUEST_IOC_REINIT - Re-initialize a request
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int request_fd, MEDIA_REQUEST_IOC_REINIT )
+    :name: MEDIA_REQUEST_IOC_REINIT
+
+
+Arguments
+=========
+
+``request_fd``
+    File descriptor returned by :ref:`MEDIA_IOC_REQUEST_ALLOC`.
+
+Description
+===========
+
+If the media device supports :ref:`requests <media-request-api>`, then
+this request ioctl can be used to re-initialize a previously allocated
+request.
+
+Re-initializing a request will clear any existing data from the request.
+This avoids having to :ref:`close() <request-func-close>` a completed
+request and allocate a new request. Instead the completed request can just
+be re-initialized and it is ready to be used again.
+
+A request can only be re-initialized if it either has not been queued
+yet, or if it was queued and completed. Otherwise it will set ``errno``
+to ``EBUSY``. No other error codes can be returned.
+
+Return Value
+============
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately.
+
+EBUSY
+    The request is queued but not yet completed.
diff --git a/Documentation/userspace-api/media/mediactl/media-types.rst b/Documentation/userspace-api/media/mediactl/media-types.rst
new file mode 100644
index 000000000000..77fd4c0c9ebc
--- /dev/null
+++ b/Documentation/userspace-api/media/mediactl/media-types.rst
@@ -0,0 +1,425 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _media-controller-types:
+
+Types and flags used to represent the media graph elements
+==========================================================
+
+..  tabularcolumns:: |p{8.2cm}|p{10.3cm}|
+
+.. _media-entity-functions:
+.. _MEDIA-ENT-F-UNKNOWN:
+.. _MEDIA-ENT-F-V4L2-SUBDEV-UNKNOWN:
+.. _MEDIA-ENT-F-IO-V4L:
+.. _MEDIA-ENT-F-IO-VBI:
+.. _MEDIA-ENT-F-IO-SWRADIO:
+.. _MEDIA-ENT-F-IO-DTV:
+.. _MEDIA-ENT-F-DTV-DEMOD:
+.. _MEDIA-ENT-F-TS-DEMUX:
+.. _MEDIA-ENT-F-DTV-CA:
+.. _MEDIA-ENT-F-DTV-NET-DECAP:
+.. _MEDIA-ENT-F-CONN-RF:
+.. _MEDIA-ENT-F-CONN-SVIDEO:
+.. _MEDIA-ENT-F-CONN-COMPOSITE:
+.. _MEDIA-ENT-F-CAM-SENSOR:
+.. _MEDIA-ENT-F-FLASH:
+.. _MEDIA-ENT-F-LENS:
+.. _MEDIA-ENT-F-ATV-DECODER:
+.. _MEDIA-ENT-F-TUNER:
+.. _MEDIA-ENT-F-IF-VID-DECODER:
+.. _MEDIA-ENT-F-IF-AUD-DECODER:
+.. _MEDIA-ENT-F-AUDIO-CAPTURE:
+.. _MEDIA-ENT-F-AUDIO-PLAYBACK:
+.. _MEDIA-ENT-F-AUDIO-MIXER:
+.. _MEDIA-ENT-F-PROC-VIDEO-COMPOSER:
+.. _MEDIA-ENT-F-PROC-VIDEO-PIXEL-FORMATTER:
+.. _MEDIA-ENT-F-PROC-VIDEO-PIXEL-ENC-CONV:
+.. _MEDIA-ENT-F-PROC-VIDEO-LUT:
+.. _MEDIA-ENT-F-PROC-VIDEO-SCALER:
+.. _MEDIA-ENT-F-PROC-VIDEO-STATISTICS:
+.. _MEDIA-ENT-F-PROC-VIDEO-ENCODER:
+.. _MEDIA-ENT-F-PROC-VIDEO-DECODER:
+.. _MEDIA-ENT-F-VID-MUX:
+.. _MEDIA-ENT-F-VID-IF-BRIDGE:
+.. _MEDIA-ENT-F-DV-DECODER:
+.. _MEDIA-ENT-F-DV-ENCODER:
+
+.. cssclass:: longtable
+
+.. flat-table:: Media entity functions
+    :header-rows:  0
+    :stub-columns: 0
+
+    *  -  ``MEDIA_ENT_F_UNKNOWN`` and
+	  ``MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN``
+       -  Unknown entity. That generally indicates that a driver didn't
+	  initialize properly the entity, which is a Kernel bug
+
+    *  -  ``MEDIA_ENT_F_IO_V4L``
+       -  Data streaming input and/or output entity.
+
+    *  -  ``MEDIA_ENT_F_IO_VBI``
+       -  V4L VBI streaming input or output entity
+
+    *  -  ``MEDIA_ENT_F_IO_SWRADIO``
+       -  V4L Software Digital Radio (SDR) streaming input or output entity
+
+    *  -  ``MEDIA_ENT_F_IO_DTV``
+       -  DVB Digital TV streaming input or output entity
+
+    *  -  ``MEDIA_ENT_F_DTV_DEMOD``
+       -  Digital TV demodulator entity.
+
+    *  -  ``MEDIA_ENT_F_TS_DEMUX``
+       -  MPEG Transport stream demux entity. Could be implemented on
+	  hardware or in Kernelspace by the Linux DVB subsystem.
+
+    *  -  ``MEDIA_ENT_F_DTV_CA``
+       -  Digital TV Conditional Access module (CAM) entity
+
+    *  -  ``MEDIA_ENT_F_DTV_NET_DECAP``
+       -  Digital TV network ULE/MLE desencapsulation entity. Could be
+	  implemented on hardware or in Kernelspace
+
+    *  -  ``MEDIA_ENT_F_CONN_RF``
+       -  Connector for a Radio Frequency (RF) signal.
+
+    *  -  ``MEDIA_ENT_F_CONN_SVIDEO``
+       -  Connector for a S-Video signal.
+
+    *  -  ``MEDIA_ENT_F_CONN_COMPOSITE``
+       -  Connector for a RGB composite signal.
+
+    *  -  ``MEDIA_ENT_F_CAM_SENSOR``
+       -  Camera video sensor entity.
+
+    *  -  ``MEDIA_ENT_F_FLASH``
+       -  Flash controller entity.
+
+    *  -  ``MEDIA_ENT_F_LENS``
+       -  Lens controller entity.
+
+    *  -  ``MEDIA_ENT_F_ATV_DECODER``
+       -  Analog video decoder, the basic function of the video decoder is
+	  to accept analogue video from a wide variety of sources such as
+	  broadcast, DVD players, cameras and video cassette recorders, in
+	  either NTSC, PAL, SECAM or HD format, separating the stream into
+	  its component parts, luminance and chrominance, and output it in
+	  some digital video standard, with appropriate timing signals.
+
+    *  -  ``MEDIA_ENT_F_TUNER``
+       -  Digital TV, analog TV, radio and/or software radio tuner, with
+	  consists on a PLL tuning stage that converts radio frequency (RF)
+	  signal into an Intermediate Frequency (IF). Modern tuners have
+	  internally IF-PLL decoders for audio and video, but older models
+	  have those stages implemented on separate entities.
+
+    *  -  ``MEDIA_ENT_F_IF_VID_DECODER``
+       -  IF-PLL video decoder. It receives the IF from a PLL and decodes
+	  the analog TV video signal. This is commonly found on some very
+	  old analog tuners, like Philips MK3 designs. They all contain a
+	  tda9887 (or some software compatible similar chip, like tda9885).
+	  Those devices use a different I2C address than the tuner PLL.
+
+    *  -  ``MEDIA_ENT_F_IF_AUD_DECODER``
+       -  IF-PLL sound decoder. It receives the IF from a PLL and decodes
+	  the analog TV audio signal. This is commonly found on some very
+	  old analog hardware, like Micronas msp3400, Philips tda9840,
+	  tda985x, etc. Those devices use a different I2C address than the
+	  tuner PLL and should be controlled together with the IF-PLL video
+	  decoder.
+
+    *  -  ``MEDIA_ENT_F_AUDIO_CAPTURE``
+       -  Audio Capture Function Entity.
+
+    *  -  ``MEDIA_ENT_F_AUDIO_PLAYBACK``
+       -  Audio Playback Function Entity.
+
+    *  -  ``MEDIA_ENT_F_AUDIO_MIXER``
+       -  Audio Mixer Function Entity.
+
+    *  -  ``MEDIA_ENT_F_PROC_VIDEO_COMPOSER``
+       -  Video composer (blender). An entity capable of video
+	  composing must have at least two sink pads and one source
+	  pad, and composes input video frames onto output video
+	  frames. Composition can be performed using alpha blending,
+	  color keying, raster operations (ROP), stitching or any other
+	  means.
+
+    *  -  ``MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER``
+       -  Video pixel formatter. An entity capable of pixel formatting
+	  must have at least one sink pad and one source pad. Read
+	  pixel formatters read pixels from memory and perform a subset
+	  of unpacking, cropping, color keying, alpha multiplication
+	  and pixel encoding conversion. Write pixel formatters perform
+	  a subset of dithering, pixel encoding conversion and packing
+	  and write pixels to memory.
+
+    *  -  ``MEDIA_ENT_F_PROC_VIDEO_PIXEL_ENC_CONV``
+       -  Video pixel encoding converter. An entity capable of pixel
+	  encoding conversion must have at least one sink pad and one
+	  source pad, and convert the encoding of pixels received on
+	  its sink pad(s) to a different encoding output on its source
+	  pad(s). Pixel encoding conversion includes but isn't limited
+	  to RGB to/from HSV, RGB to/from YUV and CFA (Bayer) to RGB
+	  conversions.
+
+    *  -  ``MEDIA_ENT_F_PROC_VIDEO_LUT``
+       -  Video look-up table. An entity capable of video lookup table
+	  processing must have one sink pad and one source pad. It uses
+	  the values of the pixels received on its sink pad to look up
+	  entries in internal tables and output them on its source pad.
+	  The lookup processing can be performed on all components
+	  separately or combine them for multi-dimensional table
+	  lookups.
+
+    *  -  ``MEDIA_ENT_F_PROC_VIDEO_SCALER``
+       -  Video scaler. An entity capable of video scaling must have
+	  at least one sink pad and one source pad, and scale the
+	  video frame(s) received on its sink pad(s) to a different
+	  resolution output on its source pad(s). The range of
+	  supported scaling ratios is entity-specific and can differ
+	  between the horizontal and vertical directions (in particular
+	  scaling can be supported in one direction only). Binning and
+	  sub-sampling (occasionally also referred to as skipping) are
+	  considered as scaling.
+
+    *  -  ``MEDIA_ENT_F_PROC_VIDEO_STATISTICS``
+       -  Video statistics computation (histogram, 3A, etc.). An entity
+	  capable of statistics computation must have one sink pad and
+	  one source pad. It computes statistics over the frames
+	  received on its sink pad and outputs the statistics data on
+	  its source pad.
+
+    *  -  ``MEDIA_ENT_F_PROC_VIDEO_ENCODER``
+       -  Video (MPEG, HEVC, VPx, etc.) encoder. An entity capable of
+          compressing video frames. Must have one sink pad and at least
+	  one source pad.
+
+    *  -  ``MEDIA_ENT_F_PROC_VIDEO_DECODER``
+       -  Video (MPEG, HEVC, VPx, etc.) decoder. An entity capable of
+          decompressing a compressed video stream into uncompressed video
+	  frames. Must have one sink pad and at least one source pad.
+
+    *  -  ``MEDIA_ENT_F_VID_MUX``
+       - Video multiplexer. An entity capable of multiplexing must have at
+         least two sink pads and one source pad, and must pass the video
+         frame(s) received from the active sink pad to the source pad.
+
+    *  -  ``MEDIA_ENT_F_VID_IF_BRIDGE``
+       - Video interface bridge. A video interface bridge entity must have at
+         least one sink pad and at least one source pad. It receives video
+         frames on its sink pad from an input video bus of one type (HDMI, eDP,
+         MIPI CSI-2, etc.), and outputs them on its source pad to an output
+         video bus of another type (eDP, MIPI CSI-2, parallel, etc.).
+
+    *  -  ``MEDIA_ENT_F_DV_DECODER``
+       -  Digital video decoder. The basic function of the video decoder is
+	  to accept digital video from a wide variety of sources
+	  and output it in some digital video standard, with appropriate
+	  timing signals.
+
+    *  -  ``MEDIA_ENT_F_DV_ENCODER``
+       -  Digital video encoder. The basic function of the video encoder is
+	  to accept digital video from some digital video standard with
+	  appropriate timing signals (usually a parallel video bus with sync
+	  signals) and output this to a digital video output connector such
+	  as HDMI or DisplayPort.
+
+..  tabularcolumns:: |p{5.5cm}|p{12.0cm}|
+
+.. _media-entity-flag:
+.. _MEDIA-ENT-FL-DEFAULT:
+.. _MEDIA-ENT-FL-CONNECTOR:
+
+.. flat-table:: Media entity flags
+    :header-rows:  0
+    :stub-columns: 0
+
+    *  -  ``MEDIA_ENT_FL_DEFAULT``
+       -  Default entity for its type. Used to discover the default audio,
+	  VBI and video devices, the default camera sensor, etc.
+
+    *  -  ``MEDIA_ENT_FL_CONNECTOR``
+       -  The entity represents a connector.
+
+
+..  tabularcolumns:: |p{6.5cm}|p{6.0cm}|p{5.0cm}|
+
+.. _media-intf-type:
+.. _MEDIA-INTF-T-DVB-FE:
+.. _MEDIA-INTF-T-DVB-DEMUX:
+.. _MEDIA-INTF-T-DVB-DVR:
+.. _MEDIA-INTF-T-DVB-CA:
+.. _MEDIA-INTF-T-DVB-NET:
+.. _MEDIA-INTF-T-V4L-VIDEO:
+.. _MEDIA-INTF-T-V4L-VBI:
+.. _MEDIA-INTF-T-V4L-RADIO:
+.. _MEDIA-INTF-T-V4L-SUBDEV:
+.. _MEDIA-INTF-T-V4L-SWRADIO:
+.. _MEDIA-INTF-T-V4L-TOUCH:
+.. _MEDIA-INTF-T-ALSA-PCM-CAPTURE:
+.. _MEDIA-INTF-T-ALSA-PCM-PLAYBACK:
+.. _MEDIA-INTF-T-ALSA-CONTROL:
+.. _MEDIA-INTF-T-ALSA-COMPRESS:
+.. _MEDIA-INTF-T-ALSA-RAWMIDI:
+.. _MEDIA-INTF-T-ALSA-HWDEP:
+.. _MEDIA-INTF-T-ALSA-SEQUENCER:
+.. _MEDIA-INTF-T-ALSA-TIMER:
+
+.. flat-table:: Media interface types
+    :header-rows:  0
+    :stub-columns: 0
+
+    *  -  ``MEDIA_INTF_T_DVB_FE``
+       -  Device node interface for the Digital TV frontend
+       -  typically, /dev/dvb/adapter?/frontend?
+
+    *  -  ``MEDIA_INTF_T_DVB_DEMUX``
+       -  Device node interface for the Digital TV demux
+       -  typically, /dev/dvb/adapter?/demux?
+
+    *  -  ``MEDIA_INTF_T_DVB_DVR``
+       -  Device node interface for the Digital TV DVR
+       -  typically, /dev/dvb/adapter?/dvr?
+
+    *  -  ``MEDIA_INTF_T_DVB_CA``
+       -  Device node interface for the Digital TV Conditional Access
+       -  typically, /dev/dvb/adapter?/ca?
+
+    *  -  ``MEDIA_INTF_T_DVB_NET``
+       -  Device node interface for the Digital TV network control
+       -  typically, /dev/dvb/adapter?/net?
+
+    *  -  ``MEDIA_INTF_T_V4L_VIDEO``
+       -  Device node interface for video (V4L)
+       -  typically, /dev/video?
+
+    *  -  ``MEDIA_INTF_T_V4L_VBI``
+       -  Device node interface for VBI (V4L)
+       -  typically, /dev/vbi?
+
+    *  -  ``MEDIA_INTF_T_V4L_RADIO``
+       -  Device node interface for radio (V4L)
+       -  typically, /dev/radio?
+
+    *  -  ``MEDIA_INTF_T_V4L_SUBDEV``
+       -  Device node interface for a V4L subdevice
+       -  typically, /dev/v4l-subdev?
+
+    *  -  ``MEDIA_INTF_T_V4L_SWRADIO``
+       -  Device node interface for Software Defined Radio (V4L)
+       -  typically, /dev/swradio?
+
+    *  -  ``MEDIA_INTF_T_V4L_TOUCH``
+       -  Device node interface for Touch device (V4L)
+       -  typically, /dev/v4l-touch?
+
+    *  -  ``MEDIA_INTF_T_ALSA_PCM_CAPTURE``
+       -  Device node interface for ALSA PCM Capture
+       -  typically, /dev/snd/pcmC?D?c
+
+    *  -  ``MEDIA_INTF_T_ALSA_PCM_PLAYBACK``
+       -  Device node interface for ALSA PCM Playback
+       -  typically, /dev/snd/pcmC?D?p
+
+    *  -  ``MEDIA_INTF_T_ALSA_CONTROL``
+       -  Device node interface for ALSA Control
+       -  typically, /dev/snd/controlC?
+
+    *  -  ``MEDIA_INTF_T_ALSA_COMPRESS``
+       -  Device node interface for ALSA Compress
+       -  typically, /dev/snd/compr?
+
+    *  -  ``MEDIA_INTF_T_ALSA_RAWMIDI``
+       -  Device node interface for ALSA Raw MIDI
+       -  typically, /dev/snd/midi?
+
+    *  -  ``MEDIA_INTF_T_ALSA_HWDEP``
+       -  Device node interface for ALSA Hardware Dependent
+       -  typically, /dev/snd/hwC?D?
+
+    *  -  ``MEDIA_INTF_T_ALSA_SEQUENCER``
+       -  Device node interface for ALSA Sequencer
+       -  typically, /dev/snd/seq
+
+    *  -  ``MEDIA_INTF_T_ALSA_TIMER``
+       -  Device node interface for ALSA Timer
+       -  typically, /dev/snd/timer
+
+
+.. tabularcolumns:: |p{5.5cm}|p{12.0cm}|
+
+.. _media-pad-flag:
+.. _MEDIA-PAD-FL-SINK:
+.. _MEDIA-PAD-FL-SOURCE:
+.. _MEDIA-PAD-FL-MUST-CONNECT:
+
+.. flat-table:: Media pad flags
+    :header-rows:  0
+    :stub-columns: 0
+
+    *  -  ``MEDIA_PAD_FL_SINK``
+       -  Input pad, relative to the entity. Input pads sink data and are
+	  targets of links.
+
+    *  -  ``MEDIA_PAD_FL_SOURCE``
+       -  Output pad, relative to the entity. Output pads source data and
+	  are origins of links.
+
+    *  -  ``MEDIA_PAD_FL_MUST_CONNECT``
+       -  If this flag is set and the pad is linked to any other pad, then
+	  at least one of those links must be enabled for the entity to be
+	  able to stream. There could be temporary reasons (e.g. device
+	  configuration dependent) for the pad to need enabled links even
+	  when this flag isn't set; the absence of the flag doesn't imply
+	  there is none.
+
+
+One and only one of ``MEDIA_PAD_FL_SINK`` and ``MEDIA_PAD_FL_SOURCE``
+must be set for every pad.
+
+.. tabularcolumns:: |p{5.5cm}|p{12.0cm}|
+
+.. _media-link-flag:
+.. _MEDIA-LNK-FL-ENABLED:
+.. _MEDIA-LNK-FL-IMMUTABLE:
+.. _MEDIA-LNK-FL-DYNAMIC:
+.. _MEDIA-LNK-FL-LINK-TYPE:
+
+.. flat-table:: Media link flags
+    :header-rows:  0
+    :stub-columns: 0
+
+    *  -  ``MEDIA_LNK_FL_ENABLED``
+       -  The link is enabled and can be used to transfer media data. When
+	  two or more links target a sink pad, only one of them can be
+	  enabled at a time.
+
+    *  -  ``MEDIA_LNK_FL_IMMUTABLE``
+       -  The link enabled state can't be modified at runtime. An immutable
+	  link is always enabled.
+
+    *  -  ``MEDIA_LNK_FL_DYNAMIC``
+       -  The link enabled state can be modified during streaming. This flag
+	  is set by drivers and is read-only for applications.
+
+    *  -  ``MEDIA_LNK_FL_LINK_TYPE``
+       -  This is a bitmask that defines the type of the link. Currently,
+	  two types of links are supported:
+
+	  .. _MEDIA-LNK-FL-DATA-LINK:
+
+	  ``MEDIA_LNK_FL_DATA_LINK`` if the link is between two pads
+
+	  .. _MEDIA-LNK-FL-INTERFACE-LINK:
+
+	  ``MEDIA_LNK_FL_INTERFACE_LINK`` if the link is between an
+	  interface and an entity
diff --git a/Documentation/userspace-api/media/mediactl/request-api.rst b/Documentation/userspace-api/media/mediactl/request-api.rst
new file mode 100644
index 000000000000..37d9442a541e
--- /dev/null
+++ b/Documentation/userspace-api/media/mediactl/request-api.rst
@@ -0,0 +1,276 @@
+.. This file is dual-licensed: you can use it either under the terms
+.. of the GPL 2.0 or the GFDL 1.1+ license, at your option. Note that this
+.. dual licensing only applies to this file, and not this project as a
+.. whole.
+..
+.. a) This file is free software; you can redistribute it and/or
+..    modify it under the terms of the GNU General Public License as
+..    published by the Free Software Foundation version 2 of
+..    the License.
+..
+..    This file is distributed in the hope that it will be useful,
+..    but WITHOUT ANY WARRANTY; without even the implied warranty of
+..    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+..    GNU General Public License for more details.
+..
+.. Or, alternatively,
+..
+.. b) Permission is granted to copy, distribute and/or modify this
+..    document under the terms of the GNU Free Documentation License,
+..    Version 1.1 or any later version published by the Free Software
+..    Foundation, with no Invariant Sections, no Front-Cover Texts
+..    and no Back-Cover Texts. A copy of the license is included at
+..    Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _media-request-api:
+
+Request API
+===========
+
+The Request API has been designed to allow V4L2 to deal with requirements of
+modern devices (stateless codecs, complex camera pipelines, ...) and APIs
+(Android Codec v2). One such requirement is the ability for devices belonging to
+the same pipeline to reconfigure and collaborate closely on a per-frame basis.
+Another is support of stateless codecs, which require controls to be applied
+to specific frames (aka 'per-frame controls') in order to be used efficiently.
+
+While the initial use-case was V4L2, it can be extended to other subsystems
+as well, as long as they use the media controller.
+
+Supporting these features without the Request API is not always possible and if
+it is, it is terribly inefficient: user-space would have to flush all activity
+on the media pipeline, reconfigure it for the next frame, queue the buffers to
+be processed with that configuration, and wait until they are all available for
+dequeuing before considering the next frame. This defeats the purpose of having
+buffer queues since in practice only one buffer would be queued at a time.
+
+The Request API allows a specific configuration of the pipeline (media
+controller topology + configuration for each media entity) to be associated with
+specific buffers. This allows user-space to schedule several tasks ("requests")
+with different configurations in advance, knowing that the configuration will be
+applied when needed to get the expected result. Configuration values at the time
+of request completion are also available for reading.
+
+General Usage
+-------------
+
+The Request API extends the Media Controller API and cooperates with
+subsystem-specific APIs to support request usage. At the Media Controller
+level, requests are allocated from the supporting Media Controller device
+node. Their life cycle is then managed through the request file descriptors in
+an opaque way. Configuration data, buffer handles and processing results
+stored in requests are accessed through subsystem-specific APIs extended for
+request support, such as V4L2 APIs that take an explicit ``request_fd``
+parameter.
+
+Request Allocation
+------------------
+
+User-space allocates requests using :ref:`MEDIA_IOC_REQUEST_ALLOC`
+for the media device node. This returns a file descriptor representing the
+request. Typically, several such requests will be allocated.
+
+Request Preparation
+-------------------
+
+Standard V4L2 ioctls can then receive a request file descriptor to express the
+fact that the ioctl is part of said request, and is not to be applied
+immediately. See :ref:`MEDIA_IOC_REQUEST_ALLOC` for a list of ioctls that
+support this. Configurations set with a ``request_fd`` parameter are stored
+instead of being immediately applied, and buffers queued to a request do not
+enter the regular buffer queue until the request itself is queued.
+
+Request Submission
+------------------
+
+Once the configuration and buffers of the request are specified, it can be
+queued by calling :ref:`MEDIA_REQUEST_IOC_QUEUE` on the request file descriptor.
+A request must contain at least one buffer, otherwise ``ENOENT`` is returned.
+A queued request cannot be modified anymore.
+
+.. caution::
+   For :ref:`memory-to-memory devices <mem2mem>` you can use requests only for
+   output buffers, not for capture buffers. Attempting to add a capture buffer
+   to a request will result in an ``EBADR`` error.
+
+If the request contains configurations for multiple entities, individual drivers
+may synchronize so the requested pipeline's topology is applied before the
+buffers are processed. Media controller drivers do a best effort implementation
+since perfect atomicity may not be possible due to hardware limitations.
+
+.. caution::
+
+   It is not allowed to mix queuing requests with directly queuing buffers:
+   whichever method is used first locks this in place until
+   :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` is called or the device is
+   :ref:`closed <func-close>`. Attempts to directly queue a buffer when earlier
+   a buffer was queued via a request or vice versa will result in an ``EBUSY``
+   error.
+
+Controls can still be set without a request and are applied immediately,
+regardless of whether a request is in use or not.
+
+.. caution::
+
+   Setting the same control through a request and also directly can lead to
+   undefined behavior!
+
+User-space can :ref:`poll() <request-func-poll>` a request file descriptor in
+order to wait until the request completes. A request is considered complete
+once all its associated buffers are available for dequeuing and all the
+associated controls have been updated with the values at the time of completion.
+Note that user-space does not need to wait for the request to complete to
+dequeue its buffers: buffers that are available halfway through a request can
+be dequeued independently of the request's state.
+
+A completed request contains the state of the device after the request was
+executed. User-space can query that state by calling
+:ref:`ioctl VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` with the request file
+descriptor. Calling :ref:`ioctl VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` for a
+request that has been queued but not yet completed will return ``EBUSY``
+since the control values might be changed at any time by the driver while the
+request is in flight.
+
+.. _media-request-life-time:
+
+Recycling and Destruction
+-------------------------
+
+Finally, a completed request can either be discarded or be reused. Calling
+:ref:`close() <request-func-close>` on a request file descriptor will make
+that file descriptor unusable and the request will be freed once it is no
+longer in use by the kernel. That is, if the request is queued and then the
+file descriptor is closed, then it won't be freed until the driver completed
+the request.
+
+The :ref:`MEDIA_REQUEST_IOC_REINIT` will clear a request's state and make it
+available again. No state is retained by this operation: the request is as
+if it had just been allocated.
+
+Example for a Codec Device
+--------------------------
+
+For use-cases such as :ref:`codecs <mem2mem>`, the request API can be used
+to associate specific controls to
+be applied by the driver for the OUTPUT buffer, allowing user-space
+to queue many such buffers in advance. It can also take advantage of requests'
+ability to capture the state of controls when the request completes to read back
+information that may be subject to change.
+
+Put into code, after obtaining a request, user-space can assign controls and one
+OUTPUT buffer to it:
+
+.. code-block:: c
+
+	struct v4l2_buffer buf;
+	struct v4l2_ext_controls ctrls;
+	int req_fd;
+	...
+	if (ioctl(media_fd, MEDIA_IOC_REQUEST_ALLOC, &req_fd))
+		return errno;
+	...
+	ctrls.which = V4L2_CTRL_WHICH_REQUEST_VAL;
+	ctrls.request_fd = req_fd;
+	if (ioctl(codec_fd, VIDIOC_S_EXT_CTRLS, &ctrls))
+		return errno;
+	...
+	buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+	buf.flags |= V4L2_BUF_FLAG_REQUEST_FD;
+	buf.request_fd = req_fd;
+	if (ioctl(codec_fd, VIDIOC_QBUF, &buf))
+		return errno;
+
+Note that it is not allowed to use the Request API for CAPTURE buffers
+since there are no per-frame settings to report there.
+
+Once the request is fully prepared, it can be queued to the driver:
+
+.. code-block:: c
+
+	if (ioctl(req_fd, MEDIA_REQUEST_IOC_QUEUE))
+		return errno;
+
+User-space can then either wait for the request to complete by calling poll() on
+its file descriptor, or start dequeuing CAPTURE buffers. Most likely, it will
+want to get CAPTURE buffers as soon as possible and this can be done using a
+regular :ref:`VIDIOC_DQBUF <VIDIOC_QBUF>`:
+
+.. code-block:: c
+
+	struct v4l2_buffer buf;
+
+	memset(&buf, 0, sizeof(buf));
+	buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	if (ioctl(codec_fd, VIDIOC_DQBUF, &buf))
+		return errno;
+
+Note that this example assumes for simplicity that for every OUTPUT buffer
+there will be one CAPTURE buffer, but this does not have to be the case.
+
+We can then, after ensuring that the request is completed via polling the
+request file descriptor, query control values at the time of its completion via
+a call to :ref:`VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>`.
+This is particularly useful for volatile controls for which we want to
+query values as soon as the capture buffer is produced.
+
+.. code-block:: c
+
+	struct pollfd pfd = { .events = POLLPRI, .fd = req_fd };
+	poll(&pfd, 1, -1);
+	...
+	ctrls.which = V4L2_CTRL_WHICH_REQUEST_VAL;
+	ctrls.request_fd = req_fd;
+	if (ioctl(codec_fd, VIDIOC_G_EXT_CTRLS, &ctrls))
+		return errno;
+
+Once we don't need the request anymore, we can either recycle it for reuse with
+:ref:`MEDIA_REQUEST_IOC_REINIT`...
+
+.. code-block:: c
+
+	if (ioctl(req_fd, MEDIA_REQUEST_IOC_REINIT))
+		return errno;
+
+... or close its file descriptor to completely dispose of it.
+
+.. code-block:: c
+
+	close(req_fd);
+
+Example for a Simple Capture Device
+-----------------------------------
+
+With a simple capture device, requests can be used to specify controls to apply
+for a given CAPTURE buffer.
+
+.. code-block:: c
+
+	struct v4l2_buffer buf;
+	struct v4l2_ext_controls ctrls;
+	int req_fd;
+	...
+	if (ioctl(media_fd, MEDIA_IOC_REQUEST_ALLOC, &req_fd))
+		return errno;
+	...
+	ctrls.which = V4L2_CTRL_WHICH_REQUEST_VAL;
+	ctrls.request_fd = req_fd;
+	if (ioctl(camera_fd, VIDIOC_S_EXT_CTRLS, &ctrls))
+		return errno;
+	...
+	buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	buf.flags |= V4L2_BUF_FLAG_REQUEST_FD;
+	buf.request_fd = req_fd;
+	if (ioctl(camera_fd, VIDIOC_QBUF, &buf))
+		return errno;
+
+Once the request is fully prepared, it can be queued to the driver:
+
+.. code-block:: c
+
+	if (ioctl(req_fd, MEDIA_REQUEST_IOC_QUEUE))
+		return errno;
+
+User-space can then dequeue buffers, wait for the request completion, query
+controls and recycle the request as in the M2M example above.
diff --git a/Documentation/userspace-api/media/mediactl/request-func-close.rst b/Documentation/userspace-api/media/mediactl/request-func-close.rst
new file mode 100644
index 000000000000..9618b5139764
--- /dev/null
+++ b/Documentation/userspace-api/media/mediactl/request-func-close.rst
@@ -0,0 +1,73 @@
+.. This file is dual-licensed: you can use it either under the terms
+.. of the GPL 2.0 or the GFDL 1.1+ license, at your option. Note that this
+.. dual licensing only applies to this file, and not this project as a
+.. whole.
+..
+.. a) This file is free software; you can redistribute it and/or
+..    modify it under the terms of the GNU General Public License as
+..    published by the Free Software Foundation version 2 of
+..    the License.
+..
+..    This file is distributed in the hope that it will be useful,
+..    but WITHOUT ANY WARRANTY; without even the implied warranty of
+..    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+..    GNU General Public License for more details.
+..
+.. Or, alternatively,
+..
+.. b) Permission is granted to copy, distribute and/or modify this
+..    document under the terms of the GNU Free Documentation License,
+..    Version 1.1 or any later version published by the Free Software
+..    Foundation, with no Invariant Sections, no Front-Cover Texts
+..    and no Back-Cover Texts. A copy of the license is included at
+..    Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _request-func-close:
+
+***************
+request close()
+***************
+
+Name
+====
+
+request-close - Close a request file descriptor
+
+
+Synopsis
+========
+
+.. code-block:: c
+
+    #include <unistd.h>
+
+
+.. c:function:: int close( int fd )
+    :name: req-close
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`MEDIA_IOC_REQUEST_ALLOC`.
+
+
+Description
+===========
+
+Closes the request file descriptor. Resources associated with the request
+are freed once all file descriptors associated with the request are closed
+and the driver has completed the request.
+See :ref:`here <media-request-life-time>` for more information.
+
+
+Return Value
+============
+
+:ref:`close() <request-func-close>` returns 0 on success. On error, -1 is
+returned, and ``errno`` is set appropriately. Possible error codes are:
+
+EBADF
+    ``fd`` is not a valid open file descriptor.
diff --git a/Documentation/userspace-api/media/mediactl/request-func-ioctl.rst b/Documentation/userspace-api/media/mediactl/request-func-ioctl.rst
new file mode 100644
index 000000000000..4bf985205bcc
--- /dev/null
+++ b/Documentation/userspace-api/media/mediactl/request-func-ioctl.rst
@@ -0,0 +1,91 @@
+.. This file is dual-licensed: you can use it either under the terms
+.. of the GPL 2.0 or the GFDL 1.1+ license, at your option. Note that this
+.. dual licensing only applies to this file, and not this project as a
+.. whole.
+..
+.. a) This file is free software; you can redistribute it and/or
+..    modify it under the terms of the GNU General Public License as
+..    published by the Free Software Foundation version 2 of
+..    the License.
+..
+..    This file is distributed in the hope that it will be useful,
+..    but WITHOUT ANY WARRANTY; without even the implied warranty of
+..    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+..    GNU General Public License for more details.
+..
+.. Or, alternatively,
+..
+.. b) Permission is granted to copy, distribute and/or modify this
+..    document under the terms of the GNU Free Documentation License,
+..    Version 1.1 or any later version published by the Free Software
+..    Foundation, with no Invariant Sections, no Front-Cover Texts
+..    and no Back-Cover Texts. A copy of the license is included at
+..    Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _request-func-ioctl:
+
+***************
+request ioctl()
+***************
+
+Name
+====
+
+request-ioctl - Control a request file descriptor
+
+
+Synopsis
+========
+
+.. code-block:: c
+
+    #include <sys/ioctl.h>
+
+
+.. c:function:: int ioctl( int fd, int cmd, void *argp )
+    :name: req-ioctl
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`MEDIA_IOC_REQUEST_ALLOC`.
+
+``cmd``
+    The request ioctl command code as defined in the media.h header file, for
+    example :ref:`MEDIA_REQUEST_IOC_QUEUE`.
+
+``argp``
+    Pointer to a request-specific structure.
+
+
+Description
+===========
+
+The :ref:`ioctl() <request-func-ioctl>` function manipulates request
+parameters. The argument ``fd`` must be an open file descriptor.
+
+The ioctl ``cmd`` code specifies the request function to be called. It
+has encoded in it whether the argument is an input, output or read/write
+parameter, and the size of the argument ``argp`` in bytes.
+
+Macros and structures definitions specifying request ioctl commands and
+their parameters are located in the media.h header file. All request ioctl
+commands, their respective function and parameters are specified in
+:ref:`media-user-func`.
+
+
+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.
+
+Command-specific error codes are listed in the individual command
+descriptions.
+
+When an ioctl that takes an output or read/write parameter fails, the
+parameter remains unmodified.
diff --git a/Documentation/userspace-api/media/mediactl/request-func-poll.rst b/Documentation/userspace-api/media/mediactl/request-func-poll.rst
new file mode 100644
index 000000000000..85a3427e5913
--- /dev/null
+++ b/Documentation/userspace-api/media/mediactl/request-func-poll.rst
@@ -0,0 +1,101 @@
+.. This file is dual-licensed: you can use it either under the terms
+.. of the GPL 2.0 or the GFDL 1.1+ license, at your option. Note that this
+.. dual licensing only applies to this file, and not this project as a
+.. whole.
+..
+.. a) This file is free software; you can redistribute it and/or
+..    modify it under the terms of the GNU General Public License as
+..    published by the Free Software Foundation version 2 of
+..    the License.
+..
+..    This file is distributed in the hope that it will be useful,
+..    but WITHOUT ANY WARRANTY; without even the implied warranty of
+..    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+..    GNU General Public License for more details.
+..
+.. Or, alternatively,
+..
+.. b) Permission is granted to copy, distribute and/or modify this
+..    document under the terms of the GNU Free Documentation License,
+..    Version 1.1 or any later version published by the Free Software
+..    Foundation, with no Invariant Sections, no Front-Cover Texts
+..    and no Back-Cover Texts. A copy of the license is included at
+..    Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _request-func-poll:
+
+**************
+request poll()
+**************
+
+Name
+====
+
+request-poll - Wait for some event on a file descriptor
+
+
+Synopsis
+========
+
+.. code-block:: c
+
+    #include <sys/poll.h>
+
+
+.. c:function:: int poll( struct pollfd *ufds, unsigned int nfds, int timeout )
+   :name: request-poll
+
+Arguments
+=========
+
+``ufds``
+   List of file descriptor events to be watched
+
+``nfds``
+   Number of file descriptor events at the \*ufds array
+
+``timeout``
+   Timeout to wait for events
+
+
+Description
+===========
+
+With the :c:func:`poll() <request-func-poll>` function applications can wait
+for a request to complete.
+
+On success :c:func:`poll() <request-func-poll>` returns the number of file
+descriptors that have been selected (that is, file descriptors for which the
+``revents`` field of the respective struct :c:type:`pollfd`
+is non-zero). Request file descriptor set the ``POLLPRI`` flag in ``revents``
+when the request was completed.  When the function times out it returns
+a value of zero, on failure it returns -1 and the ``errno`` variable is
+set appropriately.
+
+Attempting to poll for a request that is not yet queued will
+set the ``POLLERR`` flag in ``revents``.
+
+
+Return Value
+============
+
+On success, :c:func:`poll() <request-func-poll>` returns the number of
+structures which have non-zero ``revents`` fields, or zero if the call
+timed out. On error -1 is returned, and the ``errno`` variable is set
+appropriately:
+
+``EBADF``
+    One or more of the ``ufds`` members specify an invalid file
+    descriptor.
+
+``EFAULT``
+    ``ufds`` references an inaccessible memory area.
+
+``EINTR``
+    The call was interrupted by a signal.
+
+``EINVAL``
+    The ``nfds`` value exceeds the ``RLIMIT_NOFILE`` value. Use
+    ``getrlimit()`` to obtain this value.
diff --git a/Documentation/userspace-api/media/net.h.rst.exceptions b/Documentation/userspace-api/media/net.h.rst.exceptions
new file mode 100644
index 000000000000..5159aa4bbbb9
--- /dev/null
+++ b/Documentation/userspace-api/media/net.h.rst.exceptions
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: GPL-2.0
+
+# Ignore header name
+ignore define _DVBNET_H_
+
+# Ignore old ioctls/structs
+ignore ioctl __NET_ADD_IF_OLD
+ignore ioctl __NET_GET_IF_OLD
+ignore struct __dvb_net_if_old
+
+# Macros used at struct dvb_net_if
+replace define DVB_NET_FEEDTYPE_MPE :c:type:`dvb_net_if`
+replace define DVB_NET_FEEDTYPE_ULE :c:type:`dvb_net_if`
diff --git a/Documentation/userspace-api/media/rc/keytable.c.rst b/Documentation/userspace-api/media/rc/keytable.c.rst
new file mode 100644
index 000000000000..901d33d37843
--- /dev/null
+++ b/Documentation/userspace-api/media/rc/keytable.c.rst
@@ -0,0 +1,183 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+file: uapi/v4l/keytable.c
+=========================
+
+.. code-block:: c
+
+    /* keytable.c - This program allows checking/replacing keys at IR
+
+       Copyright (C) 2006-2009 Mauro Carvalho Chehab <mchehab@kernel.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 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 <ctype.h>
+    #include <errno.h>
+    #include <fcntl.h>
+    #include <stdio.h>
+    #include <stdlib.h>
+    #include <string.h>
+    #include <linux/input.h>
+    #include <sys/ioctl.h>
+
+    #include "parse.h"
+
+    void prtcode (int *codes)
+    {
+	    struct parse_key *p;
+
+	    for (p=keynames;p->name!=NULL;p++) {
+		    if (p->value == (unsigned)codes[1]) {
+			    printf("scancode 0x%04x = %s (0x%02x)\\n", codes[0], p->name, codes[1]);
+			    return;
+		    }
+	    }
+
+	    if (isprint (codes[1]))
+		    printf("scancode %d = '%c' (0x%02x)\\n", codes[0], codes[1], codes[1]);
+	    else
+		    printf("scancode %d = 0x%02x\\n", codes[0], codes[1]);
+    }
+
+    int parse_code(char *string)
+    {
+	    struct parse_key *p;
+
+	    for (p=keynames;p->name!=NULL;p++) {
+		    if (!strcasecmp(p->name, string)) {
+			    return p->value;
+		    }
+	    }
+	    return -1;
+    }
+
+    int main (int argc, char *argv[])
+    {
+	    int fd;
+	    unsigned int i, j;
+	    int codes[2];
+
+	    if (argc<2 || argc>4) {
+		    printf ("usage: %s <device> to get table; or\\n"
+			    "       %s <device> <scancode> <keycode>\\n"
+			    "       %s <device> <keycode_file>n",*argv,*argv,*argv);
+		    return -1;
+	    }
+
+	    if ((fd = open(argv[1], O_RDONLY)) < 0) {
+		    perror("Couldn't open input device");
+		    return(-1);
+	    }
+
+	    if (argc==4) {
+		    int value;
+
+		    value=parse_code(argv[3]);
+
+		    if (value==-1) {
+			    value = strtol(argv[3], NULL, 0);
+			    if (errno)
+				    perror("value");
+		    }
+
+		    codes [0] = (unsigned) strtol(argv[2], NULL, 0);
+		    codes [1] = (unsigned) value;
+
+		    if(ioctl(fd, EVIOCSKEYCODE, codes))
+			    perror ("EVIOCSKEYCODE");
+
+		    if(ioctl(fd, EVIOCGKEYCODE, codes)==0)
+			    prtcode(codes);
+		    return 0;
+	    }
+
+	    if (argc==3) {
+		    FILE *fin;
+		    int value;
+		    char *scancode, *keycode, s[2048];
+
+		    fin=fopen(argv[2],"r");
+		    if (fin==NULL) {
+			    perror ("opening keycode file");
+			    return -1;
+		    }
+
+		    /* Clears old table */
+		    for (j = 0; j < 256; j++) {
+			    for (i = 0; i < 256; i++) {
+				    codes[0] = (j << 8) | i;
+				    codes[1] = KEY_RESERVED;
+				    ioctl(fd, EVIOCSKEYCODE, codes);
+			    }
+		    }
+
+		    while (fgets(s,sizeof(s),fin)) {
+			    scancode=strtok(s,"\\n\\t =:");
+			    if (!scancode) {
+				    perror ("parsing input file scancode");
+				    return -1;
+			    }
+			    if (!strcasecmp(scancode, "scancode")) {
+				    scancode = strtok(NULL,"\\n\\t =:");
+				    if (!scancode) {
+					    perror ("parsing input file scancode");
+					    return -1;
+				    }
+			    }
+
+			    keycode=strtok(NULL,"\\n\\t =:(");
+			    if (!keycode) {
+				    perror ("parsing input file keycode");
+				    return -1;
+			    }
+
+			    // printf ("parsing %s=%s:", scancode, keycode);
+			    value=parse_code(keycode);
+			    // printf ("\\tvalue=%d\\n",value);
+
+			    if (value==-1) {
+				    value = strtol(keycode, NULL, 0);
+				    if (errno)
+					    perror("value");
+			    }
+
+			    codes [0] = (unsigned) strtol(scancode, NULL, 0);
+			    codes [1] = (unsigned) value;
+
+			    // printf("\\t%04x=%04x\\n",codes[0], codes[1]);
+			    if(ioctl(fd, EVIOCSKEYCODE, codes)) {
+				    fprintf(stderr, "Setting scancode 0x%04x with 0x%04x via ",codes[0], codes[1]);
+				    perror ("EVIOCSKEYCODE");
+			    }
+
+			    if(ioctl(fd, EVIOCGKEYCODE, codes)==0)
+				    prtcode(codes);
+		    }
+		    return 0;
+	    }
+
+	    /* Get scancode table */
+	    for (j = 0; j < 256; j++) {
+		    for (i = 0; i < 256; i++) {
+			    codes[0] = (j << 8) | i;
+			    if (!ioctl(fd, EVIOCGKEYCODE, codes) && codes[1] != KEY_RESERVED)
+				    prtcode(codes);
+		    }
+	    }
+	    return 0;
+    }
diff --git a/Documentation/userspace-api/media/rc/lirc-dev-intro.rst b/Documentation/userspace-api/media/rc/lirc-dev-intro.rst
new file mode 100644
index 000000000000..0c3d70ded55d
--- /dev/null
+++ b/Documentation/userspace-api/media/rc/lirc-dev-intro.rst
@@ -0,0 +1,171 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _lirc_dev_intro:
+
+************
+Introduction
+************
+
+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.
+
+It is also possible to attach a BPF program to a LIRC device for decoding
+raw IR into scancodes.
+
+Example dmesg output upon a driver registering w/LIRC:
+
+.. code-block:: none
+
+    $ dmesg |grep lirc_dev
+    rc rc0: lirc_dev: driver mceusb registered at minor = 0, raw IR receiver, raw IR transmitter
+
+What you should see for a chardev:
+
+.. code-block:: none
+
+    $ ls -l /dev/lirc*
+    crw-rw---- 1 root root 248, 0 Jul 2 22:20 /dev/lirc0
+
+Note that the package `v4l-utils <https://git.linuxtv.org/v4l-utils.git/>`_
+contains tools for working with LIRC devices:
+
+ - ir-ctl: can receive raw IR and transmit IR, as well as query LIRC
+   device features.
+
+ - ir-keytable: can load keymaps; allows you to set IR kernel protocols; load
+   BPF IR decoders and test IR decoding. Some BPF IR decoders are also
+   provided.
+
+.. _lirc_modes:
+
+**********
+LIRC modes
+**********
+
+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 to the :ref:`IR protocol <Remote_controllers_Protocols>`, and all other
+    members set to 0. Write this struct to the lirc device.
+
+    For receiving, you read ``struct lirc_scancode`` from the LIRC device.
+    The ``scancode`` field is set to the received scancode and the
+    :ref:`IR protocol <Remote_controllers_Protocols>` is set in
+    :c:type:`rc_proto`. If the scancode maps to a valid key code, this is set
+    in the ``keycode`` field, else it is set to ``KEY_RESERVED``.
+
+    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``
+
+    The driver returns a sequence of pulse and space codes to userspace,
+    as a series of u32 values.
+
+    This mode is used only for IR receive.
+
+    The upper 8 bits determine the packet type, and the lower 24 bits
+    the payload. Use ``LIRC_VALUE()`` macro to get the payload, and
+    the macro ``LIRC_MODE2()`` will give you the type, which
+    is one of:
+
+    ``LIRC_MODE2_PULSE``
+
+        Signifies the presence of IR in microseconds.
+
+    ``LIRC_MODE2_SPACE``
+
+        Signifies absence of IR in microseconds.
+
+    ``LIRC_MODE2_FREQUENCY``
+
+        If measurement of the carrier frequency was enabled with
+        :ref:`lirc_set_measure_carrier_mode` then this packet gives you
+        the carrier frequency in Hertz.
+
+    ``LIRC_MODE2_TIMEOUT``
+
+        If timeout reports are enabled with
+        :ref:`lirc_set_rec_timeout_reports`, when the timeout set with
+        :ref:`lirc_set_rec_timeout` expires due to no IR being detected,
+        this packet will be sent, with the number of microseconds with
+        no IR.
+
+.. _lirc-mode-pulse:
+
+``LIRC_MODE_PULSE``
+
+    In pulse mode, a sequence of pulse/space integer values are written to the
+    lirc device using :ref:`lirc-write`.
+
+    The values are alternating pulse and space lengths, in microseconds. The
+    first and last entry must be a pulse, so there must be an odd number
+    of entries.
+
+    This mode is used only for IR send.
+
+********************
+BPF based IR decoder
+********************
+
+The kernel has support for decoding the most common
+:ref:`IR protocols <Remote_controllers_Protocols>`, but there
+are many protocols which are not supported. To support these, it is possible
+to load an BPF program which does the decoding. This can only be done on
+LIRC devices which support reading raw IR.
+
+First, using the `bpf(2)`_ syscall with the ``BPF_LOAD_PROG`` argument,
+program must be loaded of type ``BPF_PROG_TYPE_LIRC_MODE2``. Once attached
+to the LIRC device, this program will be called for each pulse, space or
+timeout event on the LIRC device. The context for the BPF program is a
+pointer to a unsigned int, which is a :ref:`LIRC_MODE_MODE2 <lirc-mode-mode2>`
+value. When the program has decoded the scancode, it can be submitted using
+the BPF functions ``bpf_rc_keydown()`` or ``bpf_rc_repeat()``. Mouse or pointer
+movements can be reported using ``bpf_rc_pointer_rel()``.
+
+Once you have the file descriptor for the ``BPF_PROG_TYPE_LIRC_MODE2`` BPF
+program, it can be attached to the LIRC device using the `bpf(2)`_ syscall.
+The target must be the file descriptor for the LIRC device, and the
+attach type must be ``BPF_LIRC_MODE2``. No more than 64 BPF programs can be
+attached to a single LIRC device at a time.
+
+.. _bpf(2): http://man7.org/linux/man-pages/man2/bpf.2.html
diff --git a/Documentation/userspace-api/media/rc/lirc-dev.rst b/Documentation/userspace-api/media/rc/lirc-dev.rst
new file mode 100644
index 000000000000..7a395fa52934
--- /dev/null
+++ b/Documentation/userspace-api/media/rc/lirc-dev.rst
@@ -0,0 +1,21 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _lirc_dev:
+
+LIRC Device Interface
+=====================
+
+
+.. toctree::
+    :maxdepth: 1
+
+    lirc-dev-intro
+    lirc-func
+    lirc-header
diff --git a/Documentation/userspace-api/media/rc/lirc-func.rst b/Documentation/userspace-api/media/rc/lirc-func.rst
new file mode 100644
index 000000000000..e37c99583212
--- /dev/null
+++ b/Documentation/userspace-api/media/rc/lirc-func.rst
@@ -0,0 +1,34 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _lirc_func:
+
+LIRC Function Reference
+=======================
+
+
+.. toctree::
+    :maxdepth: 1
+
+    lirc-read
+    lirc-write
+    lirc-get-features
+    lirc-get-send-mode
+    lirc-get-rec-mode
+    lirc-get-rec-resolution
+    lirc-set-send-duty-cycle
+    lirc-get-timeout
+    lirc-set-rec-timeout
+    lirc-set-rec-carrier
+    lirc-set-rec-carrier-range
+    lirc-set-send-carrier
+    lirc-set-transmitter-mask
+    lirc-set-rec-timeout-reports
+    lirc-set-measure-carrier-mode
+    lirc-set-wideband-receiver
diff --git a/Documentation/userspace-api/media/rc/lirc-get-features.rst b/Documentation/userspace-api/media/rc/lirc-get-features.rst
new file mode 100644
index 000000000000..f4b9ca09f828
--- /dev/null
+++ b/Documentation/userspace-api/media/rc/lirc-get-features.rst
@@ -0,0 +1,200 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _lirc_get_features:
+
+***********************
+ioctl LIRC_GET_FEATURES
+***********************
+
+Name
+====
+
+LIRC_GET_FEATURES - Get the underlying hardware device's features
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, LIRC_GET_FEATURES, __u32 *features)
+    :name: LIRC_GET_FEATURES
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by open().
+
+``features``
+    Bitmask with the LIRC features.
+
+
+Description
+===========
+
+
+Get the underlying hardware device's features. If a driver does not
+announce support of certain features, calling of the corresponding ioctls
+is undefined.
+
+LIRC features
+=============
+
+.. _LIRC-CAN-REC-RAW:
+
+``LIRC_CAN_REC_RAW``
+
+    Unused. Kept just to avoid breaking uAPI.
+
+.. _LIRC-CAN-REC-PULSE:
+
+``LIRC_CAN_REC_PULSE``
+
+    Unused. Kept just to avoid breaking uAPI.
+    :ref:`LIRC_MODE_PULSE <lirc-mode-pulse>` can only be used for transmitting.
+
+.. _LIRC-CAN-REC-MODE2:
+
+``LIRC_CAN_REC_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``
+
+    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:
+
+``LIRC_CAN_SET_SEND_CARRIER``
+
+    The driver supports changing the modulation frequency via
+    :ref:`ioctl LIRC_SET_SEND_CARRIER <LIRC_SET_SEND_CARRIER>`.
+
+.. _LIRC-CAN-SET-SEND-DUTY-CYCLE:
+
+``LIRC_CAN_SET_SEND_DUTY_CYCLE``
+
+    The driver supports changing the duty cycle using
+    :ref:`ioctl LIRC_SET_SEND_DUTY_CYCLE <LIRC_SET_SEND_DUTY_CYCLE>`.
+
+.. _LIRC-CAN-SET-TRANSMITTER-MASK:
+
+``LIRC_CAN_SET_TRANSMITTER_MASK``
+
+    The driver supports changing the active transmitter(s) using
+    :ref:`ioctl LIRC_SET_TRANSMITTER_MASK <LIRC_SET_TRANSMITTER_MASK>`.
+
+.. _LIRC-CAN-SET-REC-CARRIER:
+
+``LIRC_CAN_SET_REC_CARRIER``
+
+    The driver supports setting the receive carrier frequency using
+    :ref:`ioctl LIRC_SET_REC_CARRIER <LIRC_SET_REC_CARRIER>`.
+
+.. _LIRC-CAN-SET-REC-DUTY-CYCLE-RANGE:
+
+``LIRC_CAN_SET_REC_DUTY_CYCLE_RANGE``
+
+    Unused. Kept just to avoid breaking uAPI.
+
+.. _LIRC-CAN-SET-REC-CARRIER-RANGE:
+
+``LIRC_CAN_SET_REC_CARRIER_RANGE``
+
+    The driver supports
+    :ref:`ioctl LIRC_SET_REC_CARRIER_RANGE <LIRC_SET_REC_CARRIER_RANGE>`.
+
+.. _LIRC-CAN-GET-REC-RESOLUTION:
+
+``LIRC_CAN_GET_REC_RESOLUTION``
+
+    The driver supports
+    :ref:`ioctl LIRC_GET_REC_RESOLUTION <LIRC_GET_REC_RESOLUTION>`.
+
+.. _LIRC-CAN-SET-REC-TIMEOUT:
+
+``LIRC_CAN_SET_REC_TIMEOUT``
+
+    The driver supports
+    :ref:`ioctl LIRC_SET_REC_TIMEOUT <LIRC_SET_REC_TIMEOUT>`.
+
+.. _LIRC-CAN-SET-REC-FILTER:
+
+``LIRC_CAN_SET_REC_FILTER``
+
+    Unused. Kept just to avoid breaking uAPI.
+
+.. _LIRC-CAN-MEASURE-CARRIER:
+
+``LIRC_CAN_MEASURE_CARRIER``
+
+    The driver supports measuring of the modulation frequency using
+    :ref:`ioctl LIRC_SET_MEASURE_CARRIER_MODE <LIRC_SET_MEASURE_CARRIER_MODE>`.
+
+.. _LIRC-CAN-USE-WIDEBAND-RECEIVER:
+
+``LIRC_CAN_USE_WIDEBAND_RECEIVER``
+
+    The driver supports learning mode using
+    :ref:`ioctl LIRC_SET_WIDEBAND_RECEIVER <LIRC_SET_WIDEBAND_RECEIVER>`.
+
+.. _LIRC-CAN-NOTIFY-DECODE:
+
+``LIRC_CAN_NOTIFY_DECODE``
+
+    Unused. Kept just to avoid breaking uAPI.
+
+.. _LIRC-CAN-SEND-RAW:
+
+``LIRC_CAN_SEND_RAW``
+
+    Unused. Kept just to avoid breaking uAPI.
+
+.. _LIRC-CAN-SEND-PULSE:
+
+``LIRC_CAN_SEND_PULSE``
+
+    The driver supports sending (also called as IR blasting or IR TX) using
+    :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:
+
+``LIRC_CAN_SEND_MODE2``
+
+    Unused. Kept just to avoid breaking uAPI.
+    :ref:`LIRC_MODE_MODE2 <lirc-mode-mode2>` can only be used for receiving.
+
+.. _LIRC-CAN-SEND-LIRCCODE:
+
+``LIRC_CAN_SEND_LIRCCODE``
+
+    Unused. Kept just to avoid breaking uAPI.
+
+
+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/userspace-api/media/rc/lirc-get-rec-mode.rst b/Documentation/userspace-api/media/rc/lirc-get-rec-mode.rst
new file mode 100644
index 000000000000..674ce16d5d33
--- /dev/null
+++ b/Documentation/userspace-api/media/rc/lirc-get-rec-mode.rst
@@ -0,0 +1,74 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _lirc_get_rec_mode:
+.. _lirc_set_rec_mode:
+
+**********************************************
+ioctls LIRC_GET_REC_MODE and LIRC_SET_REC_MODE
+**********************************************
+
+Name
+====
+
+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 *mode)
+	:name: LIRC_GET_REC_MODE
+
+.. c:function:: int ioctl( int fd, LIRC_SET_REC_MODE, __u32 *mode)
+	:name: LIRC_SET_REC_MODE
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by open().
+
+``mode``
+    Mode used for receive.
+
+Description
+===========
+
+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
+============
+
+.. 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/userspace-api/media/rc/lirc-get-rec-resolution.rst b/Documentation/userspace-api/media/rc/lirc-get-rec-resolution.rst
new file mode 100644
index 000000000000..f20b5bf41232
--- /dev/null
+++ b/Documentation/userspace-api/media/rc/lirc-get-rec-resolution.rst
@@ -0,0 +1,54 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _lirc_get_rec_resolution:
+
+*****************************
+ioctl LIRC_GET_REC_RESOLUTION
+*****************************
+
+Name
+====
+
+LIRC_GET_REC_RESOLUTION - Obtain the value of receive resolution, in microseconds.
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, LIRC_GET_REC_RESOLUTION, __u32 *microseconds)
+    :name: LIRC_GET_REC_RESOLUTION
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by open().
+
+``microseconds``
+    Resolution, in microseconds.
+
+
+Description
+===========
+
+Some receivers have maximum resolution which is defined by internal
+sample rate or data format limitations. E.g. it's common that
+signals can only be reported in 50 microsecond steps.
+
+This ioctl returns the integer value with such resolution, with can be
+used by userspace applications like lircd to automatically adjust the
+tolerance value.
+
+
+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/userspace-api/media/rc/lirc-get-send-mode.rst b/Documentation/userspace-api/media/rc/lirc-get-send-mode.rst
new file mode 100644
index 000000000000..973a47bf6068
--- /dev/null
+++ b/Documentation/userspace-api/media/rc/lirc-get-send-mode.rst
@@ -0,0 +1,78 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _lirc_get_send_mode:
+.. _lirc_set_send_mode:
+
+************************************************
+ioctls LIRC_GET_SEND_MODE and LIRC_SET_SEND_MODE
+************************************************
+
+Name
+====
+
+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 *mode )
+    :name: LIRC_GET_SEND_MODE
+
+.. c:function:: int ioctl( int fd, LIRC_SET_SEND_MODE, __u32 *mode )
+    :name: LIRC_SET_SEND_MODE
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by open().
+
+``mode``
+    The mode used for transmitting.
+
+
+Description
+===========
+
+Get/set current transmit mode.
+
+Only :ref:`LIRC_MODE_PULSE <lirc-mode-pulse>` and
+: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
+============
+
+
+.. 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/userspace-api/media/rc/lirc-get-timeout.rst b/Documentation/userspace-api/media/rc/lirc-get-timeout.rst
new file mode 100644
index 000000000000..5db84096d7f8
--- /dev/null
+++ b/Documentation/userspace-api/media/rc/lirc-get-timeout.rst
@@ -0,0 +1,63 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _lirc_get_min_timeout:
+.. _lirc_get_max_timeout:
+
+****************************************************
+ioctls LIRC_GET_MIN_TIMEOUT and LIRC_GET_MAX_TIMEOUT
+****************************************************
+
+Name
+====
+
+LIRC_GET_MIN_TIMEOUT / LIRC_GET_MAX_TIMEOUT - Obtain the possible timeout
+range for IR receive.
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, LIRC_GET_MIN_TIMEOUT, __u32 *timeout)
+    :name: LIRC_GET_MIN_TIMEOUT
+
+.. c:function:: int ioctl( int fd, LIRC_GET_MAX_TIMEOUT, __u32 *timeout)
+    :name: LIRC_GET_MAX_TIMEOUT
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by open().
+
+``timeout``
+    Timeout, in microseconds.
+
+
+Description
+===========
+
+Some devices have internal timers that can be used to detect when
+there's no IR activity for a long time. This can help lircd in
+detecting that a IR signal is finished and can speed up the decoding
+process. Returns an integer value with the minimum/maximum timeout
+that can be set.
+
+.. note::
+
+   Some devices have a fixed timeout, in that case
+   both ioctls will return the same value even though the timeout
+   cannot be changed via :ref:`LIRC_SET_REC_TIMEOUT`.
+
+
+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/userspace-api/media/rc/lirc-header.rst b/Documentation/userspace-api/media/rc/lirc-header.rst
new file mode 100644
index 000000000000..c7e0716da159
--- /dev/null
+++ b/Documentation/userspace-api/media/rc/lirc-header.rst
@@ -0,0 +1,17 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _lirc_header:
+
+****************
+LIRC Header File
+****************
+
+.. kernel-include:: $BUILDDIR/lirc.h.rst
+
diff --git a/Documentation/userspace-api/media/rc/lirc-read.rst b/Documentation/userspace-api/media/rc/lirc-read.rst
new file mode 100644
index 000000000000..13f7f5353851
--- /dev/null
+++ b/Documentation/userspace-api/media/rc/lirc-read.rst
@@ -0,0 +1,76 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _lirc-read:
+
+***********
+LIRC read()
+***********
+
+Name
+====
+
+lirc-read - Read from a LIRC device
+
+
+Synopsis
+========
+
+.. code-block:: c
+
+    #include <unistd.h>
+
+
+.. c:function:: ssize_t read( int fd, void *buf, size_t count )
+    :name: lirc-read
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by ``open()``.
+
+``buf``
+   Buffer to be filled
+
+``count``
+   Max number of bytes to read
+
+Description
+===========
+
+:ref:`read() <lirc-read>` attempts to read up to ``count`` bytes from file
+descriptor ``fd`` into the buffer starting at ``buf``.  If ``count`` is zero,
+:ref:`read() <lirc-read>` returns zero and has no other results. If ``count``
+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, and use
+:ref:`lirc_set_rec_mode` set the current active mode.
+
+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
+:ref:`IR protocol <Remote_controllers_Protocols>`
+used for transmission, and ``scancode`` to the decoded scancode,
+and the ``keycode`` set to the keycode or ``KEY_RESERVED``.
+
+
+Return Value
+============
+
+On success, the number of bytes read 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.
diff --git a/Documentation/userspace-api/media/rc/lirc-set-measure-carrier-mode.rst b/Documentation/userspace-api/media/rc/lirc-set-measure-carrier-mode.rst
new file mode 100644
index 000000000000..4cf9472eb904
--- /dev/null
+++ b/Documentation/userspace-api/media/rc/lirc-set-measure-carrier-mode.rst
@@ -0,0 +1,53 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _lirc_set_measure_carrier_mode:
+
+***********************************
+ioctl LIRC_SET_MEASURE_CARRIER_MODE
+***********************************
+
+Name
+====
+
+LIRC_SET_MEASURE_CARRIER_MODE - enable or disable measure mode
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, LIRC_SET_MEASURE_CARRIER_MODE, __u32 *enable )
+    :name: LIRC_SET_MEASURE_CARRIER_MODE
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by open().
+
+``enable``
+    enable = 1 means enable measure mode, enable = 0 means disable measure
+    mode.
+
+
+Description
+===========
+
+.. _lirc-mode2-frequency:
+
+Enable or disable measure mode. If enabled, from the next key
+press on, the driver will send ``LIRC_MODE2_FREQUENCY`` packets. By
+default this should be turned off.
+
+
+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/userspace-api/media/rc/lirc-set-rec-carrier-range.rst b/Documentation/userspace-api/media/rc/lirc-set-rec-carrier-range.rst
new file mode 100644
index 000000000000..0439e93aa267
--- /dev/null
+++ b/Documentation/userspace-api/media/rc/lirc-set-rec-carrier-range.rst
@@ -0,0 +1,54 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _lirc_set_rec_carrier_range:
+
+********************************
+ioctl LIRC_SET_REC_CARRIER_RANGE
+********************************
+
+Name
+====
+
+LIRC_SET_REC_CARRIER_RANGE - Set lower bound of the carrier used to modulate
+IR receive.
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, LIRC_SET_REC_CARRIER_RANGE, __u32 *frequency )
+    :name: LIRC_SET_REC_CARRIER_RANGE
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by open().
+
+``frequency``
+    Frequency of the carrier that modulates PWM data, in Hz.
+
+Description
+===========
+
+This ioctl sets the upper range of carrier frequency that will be recognized
+by the IR receiver.
+
+.. note::
+
+   To set a range use :ref:`LIRC_SET_REC_CARRIER_RANGE
+   <LIRC_SET_REC_CARRIER_RANGE>` with the lower bound first and later call
+   :ref:`LIRC_SET_REC_CARRIER <LIRC_SET_REC_CARRIER>` with the upper bound.
+
+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/userspace-api/media/rc/lirc-set-rec-carrier.rst b/Documentation/userspace-api/media/rc/lirc-set-rec-carrier.rst
new file mode 100644
index 000000000000..f4d18897cb9f
--- /dev/null
+++ b/Documentation/userspace-api/media/rc/lirc-set-rec-carrier.rst
@@ -0,0 +1,53 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _lirc_set_rec_carrier:
+
+**************************
+ioctl LIRC_SET_REC_CARRIER
+**************************
+
+Name
+====
+
+LIRC_SET_REC_CARRIER - Set carrier used to modulate IR receive.
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, LIRC_SET_REC_CARRIER, __u32 *frequency )
+    :name: LIRC_SET_REC_CARRIER
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by open().
+
+``frequency``
+    Frequency of the carrier that modulates PWM data, in Hz.
+
+Description
+===========
+
+Set receive carrier used to modulate IR PWM pulses and spaces.
+
+.. note::
+
+   If called together with :ref:`LIRC_SET_REC_CARRIER_RANGE`, this ioctl
+   sets the upper bound frequency that will be recognized by the device.
+
+
+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/userspace-api/media/rc/lirc-set-rec-timeout-reports.rst b/Documentation/userspace-api/media/rc/lirc-set-rec-timeout-reports.rst
new file mode 100644
index 000000000000..ab97f87fa757
--- /dev/null
+++ b/Documentation/userspace-api/media/rc/lirc-set-rec-timeout-reports.rst
@@ -0,0 +1,56 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _lirc_set_rec_timeout_reports:
+
+**********************************
+ioctl LIRC_SET_REC_TIMEOUT_REPORTS
+**********************************
+
+Name
+====
+
+LIRC_SET_REC_TIMEOUT_REPORTS - enable or disable timeout reports for IR receive
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, LIRC_SET_REC_TIMEOUT_REPORTS, __u32 *enable )
+    :name: LIRC_SET_REC_TIMEOUT_REPORTS
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by open().
+
+``enable``
+    enable = 1 means enable timeout report, enable = 0 means disable timeout
+    reports.
+
+
+Description
+===========
+
+.. _lirc-mode2-timeout:
+
+Enable or disable timeout reports for IR receive. By default, timeout reports
+should be turned off.
+
+.. note::
+
+   This ioctl is only valid for :ref:`LIRC_MODE_MODE2 <lirc-mode-mode2>`.
+
+
+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/userspace-api/media/rc/lirc-set-rec-timeout.rst b/Documentation/userspace-api/media/rc/lirc-set-rec-timeout.rst
new file mode 100644
index 000000000000..227776cf7c62
--- /dev/null
+++ b/Documentation/userspace-api/media/rc/lirc-set-rec-timeout.rst
@@ -0,0 +1,61 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _lirc_set_rec_timeout:
+.. _lirc_get_rec_timeout:
+
+***************************************************
+ioctl LIRC_GET_REC_TIMEOUT and LIRC_SET_REC_TIMEOUT
+***************************************************
+
+Name
+====
+
+LIRC_GET_REC_TIMEOUT/LIRC_SET_REC_TIMEOUT - Get/set the integer value for IR inactivity timeout.
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, LIRC_GET_REC_TIMEOUT, __u32 *timeout )
+    :name: LIRC_GET_REC_TIMEOUT
+
+.. c:function:: int ioctl( int fd, LIRC_SET_REC_TIMEOUT, __u32 *timeout )
+    :name: LIRC_SET_REC_TIMEOUT
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by open().
+
+``timeout``
+    Timeout, in microseconds.
+
+
+Description
+===========
+
+Get and set the integer value for IR inactivity timeout.
+
+If supported by the hardware, setting it to 0  disables all hardware timeouts
+and data should be reported as soon as possible. If the exact value
+cannot be set, then the next possible value _greater_ than the
+given value should be set.
+
+.. note::
+
+   The range of supported timeout is given by :ref:`LIRC_GET_MIN_TIMEOUT`.
+
+
+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/userspace-api/media/rc/lirc-set-send-carrier.rst b/Documentation/userspace-api/media/rc/lirc-set-send-carrier.rst
new file mode 100644
index 000000000000..7eaf2b993207
--- /dev/null
+++ b/Documentation/userspace-api/media/rc/lirc-set-send-carrier.rst
@@ -0,0 +1,48 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _lirc_set_send_carrier:
+
+***************************
+ioctl LIRC_SET_SEND_CARRIER
+***************************
+
+Name
+====
+
+LIRC_SET_SEND_CARRIER - Set send carrier used to modulate IR TX.
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, LIRC_SET_SEND_CARRIER, __u32 *frequency )
+    :name: LIRC_SET_SEND_CARRIER
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by open().
+
+``frequency``
+    Frequency of the carrier to be modulated, in Hz.
+
+Description
+===========
+
+Set send carrier used to modulate IR PWM pulses and spaces.
+
+
+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/userspace-api/media/rc/lirc-set-send-duty-cycle.rst b/Documentation/userspace-api/media/rc/lirc-set-send-duty-cycle.rst
new file mode 100644
index 000000000000..0dee89364cde
--- /dev/null
+++ b/Documentation/userspace-api/media/rc/lirc-set-send-duty-cycle.rst
@@ -0,0 +1,54 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _lirc_set_send_duty_cycle:
+
+******************************
+ioctl LIRC_SET_SEND_DUTY_CYCLE
+******************************
+
+Name
+====
+
+LIRC_SET_SEND_DUTY_CYCLE - Set the duty cycle of the carrier signal for
+IR transmit.
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, LIRC_SET_SEND_DUTY_CYCLE, __u32 *duty_cycle)
+    :name: LIRC_SET_SEND_DUTY_CYCLE
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by open().
+
+``duty_cycle``
+    Duty cicle, describing the pulse width in percent (from 1 to 99) of
+    the total cycle. Values 0 and 100 are reserved.
+
+
+Description
+===========
+
+Get/set the duty cycle of the carrier signal for IR transmit.
+
+Currently, no special meaning is defined for 0 or 100, but this
+could be used to switch off carrier generation in the future, so
+these values should be reserved.
+
+
+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/userspace-api/media/rc/lirc-set-transmitter-mask.rst b/Documentation/userspace-api/media/rc/lirc-set-transmitter-mask.rst
new file mode 100644
index 000000000000..dcee4b71dcf6
--- /dev/null
+++ b/Documentation/userspace-api/media/rc/lirc-set-transmitter-mask.rst
@@ -0,0 +1,58 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _lirc_set_transmitter_mask:
+
+*******************************
+ioctl LIRC_SET_TRANSMITTER_MASK
+*******************************
+
+Name
+====
+
+LIRC_SET_TRANSMITTER_MASK - Enables send codes on a given set of transmitters
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, LIRC_SET_TRANSMITTER_MASK, __u32 *mask )
+    :name: LIRC_SET_TRANSMITTER_MASK
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by open().
+
+``mask``
+    Mask with channels to enable tx. Channel 0 is the least significant bit.
+
+
+Description
+===========
+
+Some IR TX devices have multiple output channels, in such case,
+:ref:`LIRC_CAN_SET_TRANSMITTER_MASK <LIRC-CAN-SET-TRANSMITTER-MASK>` is
+returned via :ref:`LIRC_GET_FEATURES` and this ioctl sets what channels will
+send IR codes.
+
+This ioctl enables the given set of transmitters. The first transmitter is
+encoded by the least significant bit and so on.
+
+When an invalid bit mask is given, i.e. a bit is set, even though the device
+does not have so many transitters, then this ioctl returns the number of
+available transitters and does nothing otherwise.
+
+
+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/userspace-api/media/rc/lirc-set-wideband-receiver.rst b/Documentation/userspace-api/media/rc/lirc-set-wideband-receiver.rst
new file mode 100644
index 000000000000..22f6fe43b7e7
--- /dev/null
+++ b/Documentation/userspace-api/media/rc/lirc-set-wideband-receiver.rst
@@ -0,0 +1,63 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _lirc_set_wideband_receiver:
+
+********************************
+ioctl LIRC_SET_WIDEBAND_RECEIVER
+********************************
+
+Name
+====
+
+LIRC_SET_WIDEBAND_RECEIVER - enable wide band receiver.
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, LIRC_SET_WIDEBAND_RECEIVER, __u32 *enable )
+    :name: LIRC_SET_WIDEBAND_RECEIVER
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by open().
+
+``enable``
+    enable = 1 means enable wideband receiver, enable = 0 means disable
+    wideband receiver.
+
+
+Description
+===========
+
+Some receivers are equipped with special wide band receiver which is
+intended to be used to learn output of existing remote. This ioctl
+allows enabling or disabling it.
+
+This might be useful of receivers that have otherwise narrow band receiver
+that prevents them to be used with some remotes. Wide band receiver might
+also be more precise. On the other hand its disadvantage it usually
+reduced range of reception.
+
+.. note::
+
+    Wide band receiver might be implictly enabled if you enable
+    carrier reports. In that case it will be disabled as soon as you disable
+    carrier reports. Trying to disable wide band receiver while carrier
+    reports are active will do nothing.
+
+
+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/userspace-api/media/rc/lirc-write.rst b/Documentation/userspace-api/media/rc/lirc-write.rst
new file mode 100644
index 000000000000..96ca4a22062e
--- /dev/null
+++ b/Documentation/userspace-api/media/rc/lirc-write.rst
@@ -0,0 +1,82 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _lirc-write:
+
+************
+LIRC write()
+************
+
+Name
+====
+
+lirc-write - Write to a LIRC device
+
+
+Synopsis
+========
+
+.. code-block:: c
+
+    #include <unistd.h>
+
+
+.. c:function:: ssize_t write( int fd, void *buf, size_t count )
+    :name: lirc-write
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by ``open()``.
+
+``buf``
+    Buffer with data to be written
+
+``count``
+    Number of bytes at the buffer
+
+Description
+===========
+
+:ref:`write() <lirc-write>` writes up to ``count`` bytes to the device
+referenced by the file descriptor ``fd`` from the buffer starting at
+``buf``.
+
+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 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 :ref:`IR protocol <Remote_controllers_Protocols>` in the
+:c:type:`rc_proto`: member. All other members must be
+set to 0, else ``EINVAL`` is returned. If there is no protocol encoder
+for the protocol or the scancode is not valid for the specified protocol,
+``EINVAL`` is returned. The write function blocks until the scancode
+is transmitted by the hardware.
+
+
+Return Value
+============
+
+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
+:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/userspace-api/media/rc/rc-intro.rst b/Documentation/userspace-api/media/rc/rc-intro.rst
new file mode 100644
index 000000000000..14e85157bf23
--- /dev/null
+++ b/Documentation/userspace-api/media/rc/rc-intro.rst
@@ -0,0 +1,31 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _Remote_controllers_Intro:
+
+************
+Introduction
+************
+
+Currently, most analog and digital devices have a Infrared input for
+remote controllers. Each manufacturer has their own type of control. It
+is not rare for the same manufacturer to ship different types of
+controls, depending on the device.
+
+A Remote Controller interface is mapped as a normal evdev/input
+interface, just like a keyboard or a mouse. So, it uses all ioctls
+already defined for any other input devices.
+
+However, remove controllers are more flexible than a normal input
+device, as the IR receiver (and/or transmitter) can be used in
+conjunction with a wide variety of different IR remotes.
+
+In order to allow flexibility, the Remote Controller subsystem allows
+controlling the RC-specific attributes via
+:ref:`the sysfs class nodes <remote_controllers_sysfs_nodes>`.
diff --git a/Documentation/userspace-api/media/rc/rc-protos.rst b/Documentation/userspace-api/media/rc/rc-protos.rst
new file mode 100644
index 000000000000..b250ebe301d5
--- /dev/null
+++ b/Documentation/userspace-api/media/rc/rc-protos.rst
@@ -0,0 +1,456 @@
+.. SPDX-License-Identifier: GPL-2.0
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _Remote_controllers_Protocols:
+
+*****************************************
+Remote Controller Protocols and Scancodes
+*****************************************
+
+IR is encoded as a series of pulses and spaces, using a protocol. These
+protocols can encode e.g. an address (which device should respond) and a
+command: what it should do. The values for these are not always consistent
+across different devices for a given protocol.
+
+Therefore out the output of the IR decoder is a scancode; a single u32
+value. Using keymap tables this can be mapped to linux key codes.
+
+Other things can be encoded too. Some IR protocols encode a toggle bit; this
+is to distinguish whether the same button is being held down, or has been
+released and pressed again. If has been released and pressed again, the
+toggle bit will invert from one IR message to the next.
+
+Some remotes have a pointer-type device which can used to control the
+mouse; some air conditioning systems can have their target temperature
+target set in IR.
+
+The following are the protocols the kernel knows about and also lists
+how scancodes are encoded for each protocol.
+
+rc-5 (RC_PROTO_RC5)
+-------------------
+
+This IR protocol uses manchester encoding to encode 14 bits. There is a
+detailed description here https://www.sbprojects.net/knowledge/ir/rc5.php.
+
+The scancode encoding is *not* consistent with the lirc daemon (lircd) rc5
+protocol, or the manchester BPF decoder.
+
+.. flat-table:: rc5 bits scancode mapping
+   :widths:       1 1 2
+
+   * - rc-5 bit
+
+     - scancode bit
+
+     - description
+
+   * - 1
+
+     - none
+
+     - Start bit, always set
+
+   * - 1
+
+     - 6 (inverted)
+
+     - 2nd start bit in rc5,  re-used as 6th command bit
+
+   * - 1
+
+     - none
+
+     - Toggle bit
+
+   * - 5
+
+     - 8 to 13
+
+     - Address
+
+   * - 6
+
+     - 0 to 5
+
+     - Command
+
+There is a variant of rc5 called either rc5x or extended rc5
+where there the second stop bit is the 6th commmand bit, but inverted.
+This is done so it the scancodes and encoding is compatible with existing
+schemes. This bit is stored in bit 6 of the scancode, inverted. This is
+done to keep it compatible with plain rc-5 where there are two start bits.
+
+rc-5-sz (RC_PROTO_RC5_SZ)
+-------------------------
+This is much like rc-5 but one bit longer. The scancode is encoded
+differently.
+
+.. flat-table:: rc-5-sz bits scancode mapping
+   :widths:       1 1 2
+
+   * - rc-5-sz bits
+
+     - scancode bit
+
+     - description
+
+   * - 1
+
+     - none
+
+     - Start bit, always set
+
+   * - 1
+
+     - 13
+
+     - Address bit
+
+   * - 1
+
+     - none
+
+     - Toggle bit
+
+   * - 6
+
+     - 6 to 11
+
+     - Address
+
+   * - 6
+
+     - 0 to 5
+
+     - Command
+
+rc-5x-20 (RC_PROTO_RC5X_20)
+---------------------------
+
+This rc-5 extended to encoded 20 bits. The is a 3555 microseconds space
+after the 8th bit.
+
+.. flat-table:: rc-5x-20 bits scancode mapping
+   :widths:       1 1 2
+
+   * - rc-5-sz bits
+
+     - scancode bit
+
+     - description
+
+   * - 1
+
+     - none
+
+     - Start bit, always set
+
+   * - 1
+
+     - 14
+
+     - Address bit
+
+   * - 1
+
+     - none
+
+     - Toggle bit
+
+   * - 5
+
+     - 16 to 20
+
+     - Address
+
+   * - 6
+
+     - 8 to 13
+
+     - Address
+
+   * - 6
+
+     - 0 to 5
+
+     - Command
+
+
+jvc (RC_PROTO_JVC)
+------------------
+
+The jvc protocol is much like nec, without the inverted values. It is
+described here https://www.sbprojects.net/knowledge/ir/jvc.php.
+
+The scancode is a 16 bits value, where the address is the lower 8 bits
+and the command the higher 8 bits; this is reversed from IR order.
+
+sony-12 (RC_PROTO_SONY12)
+-------------------------
+
+The sony protocol is a pulse-width encoding. There are three variants,
+which just differ in number of bits and scancode encoding.
+
+.. flat-table:: sony-12 bits scancode mapping
+   :widths:       1 1 2
+
+   * - sony-12 bits
+
+     - scancode bit
+
+     - description
+
+   * - 5
+
+     - 16 to 20
+
+     - device
+
+   * - 7
+
+     - 0 to 6
+
+     - function
+
+sony-15 (RC_PROTO_SONY15)
+-------------------------
+
+The sony protocol is a pulse-width encoding. There are three variants,
+which just differ in number of bits and scancode encoding.
+
+.. flat-table:: sony-12 bits scancode mapping
+   :widths:       1 1 2
+
+   * - sony-12 bits
+
+     - scancode bit
+
+     - description
+
+   * - 8
+
+     - 16 to 23
+
+     - device
+
+   * - 7
+
+     - 0 to 6
+
+     - function
+
+sony-20 (RC_PROTO_SONY20)
+-------------------------
+
+The sony protocol is a pulse-width encoding. There are three variants,
+which just differ in number of bits and scancode encoding.
+
+.. flat-table:: sony-20 bits scancode mapping
+   :widths:       1 1 2
+
+   * - sony-20 bits
+
+     - scancode bit
+
+     - description
+
+   * - 5
+
+     - 16 to 20
+
+     - device
+
+   * - 7
+
+     - 0 to 7
+
+     - device
+
+   * - 8
+
+     - 8 to 15
+
+     - extended bits
+
+nec (RC_PROTO_NEC)
+------------------
+
+The nec protocol encodes an 8 bit address and an 8 bit command. It is
+described here https://www.sbprojects.net/knowledge/ir/nec.php. Note
+that the protocol sends least significant bit first.
+
+As a check, the nec protocol sends the address and command twice; the
+second time it is inverted. This is done for verification.
+
+A plain nec IR message has 16 bits; the high 8 bits are the address
+and the low 8 bits are the command.
+
+nec-x (RC_PROTO_NECX)
+---------------------
+
+Extended nec has a 16 bit address and a 8 bit command. This is encoded
+as a 24 bit value as you would expect, with the lower 8 bits the command
+and the upper 16 bits the address.
+
+nec-32 (RC_PROTO_NEC32)
+-----------------------
+
+nec-32 does not send an inverted address or an inverted command; the
+entire message, all 32 bits, are used.
+
+For this to be decoded correctly, the second 8 bits must not be the
+inverted value of the first, and also the last 8 bits must not be the
+inverted value of the third 8 bit value.
+
+The scancode has a somewhat unusual encoding.
+
+.. flat-table:: nec-32 bits scancode mapping
+
+   * - nec-32 bits
+
+     - scancode bit
+
+   * - First 8 bits
+
+     - 16 to 23
+
+   * - Second 8 bits
+
+     - 24 to 31
+
+   * - Third 8 bits
+
+     - 0 to 7
+
+   * - Fourth 8 bits
+
+     - 8 to 15
+
+sanyo (RC_PROTO_SANYO)
+----------------------
+
+The sanyo protocol is like the nec protocol, but with 13 bits address
+rather than 8 bits. Both the address and the command are followed by
+their inverted versions, but these are not present in the scancodes.
+
+Bis 8 to 20 of the scancode is the 13 bits address, and the lower 8
+bits are the command.
+
+mcir2-kbd (RC_PROTO_MCIR2_KBD)
+------------------------------
+
+This protocol is generated by the Microsoft MCE keyboard for keyboard
+events. Refer to the ir-mce_kbd-decoder.c to see how it is encoded.
+
+mcir2-mse (RC_PROTO_MCIR2_MSE)
+------------------------------
+
+This protocol is generated by the Microsoft MCE keyboard for pointer
+events. Refer to the ir-mce_kbd-decoder.c to see how it is encoded.
+
+rc-6-0 (RC_PROTO_RC6_0)
+-----------------------
+
+This is the rc-6 in mode 0. rc-6 is described here
+https://www.sbprojects.net/knowledge/ir/rc6.php.
+The scancode is the exact 16 bits as in the protocol. There is also a
+toggle bit.
+
+rc-6-6a-20 (RC_PROTO_RC6_6A_20)
+-------------------------------
+
+This is the rc-6 in mode 6a, 20 bits. rc-6 is described here
+https://www.sbprojects.net/knowledge/ir/rc6.php.
+The scancode is the exact 20 bits
+as in the protocol. There is also a toggle bit.
+
+rc-6-6a-24 (RC_PROTO_RC6_6A_24)
+-------------------------------
+
+This is the rc-6 in mode 6a, 24 bits. rc-6 is described here
+https://www.sbprojects.net/knowledge/ir/rc6.php.
+The scancode is the exact 24 bits
+as in the protocol. There is also a toggle bit.
+
+rc-6-6a-32 (RC_PROTO_RC6_6A_32)
+-------------------------------
+
+This is the rc-6 in mode 6a, 32 bits. rc-6 is described here
+https://www.sbprojects.net/knowledge/ir/rc6.php.
+The upper 16 bits are the vendor,
+and the lower 16 bits are the vendor-specific bits. This protocol is
+for the non-Microsoft MCE variant (vendor != 0x800f).
+
+
+rc-6-mce (RC_PROTO_RC6_MCE)
+---------------------------
+
+This is the rc-6 in mode 6a, 32 bits. The upper 16 bits are the vendor,
+and the lower 16 bits are the vendor-specific bits. This protocol is
+for the Microsoft MCE variant (vendor = 0x800f). The toggle bit in the
+protocol itself is ignored, and the 16th bit should be takes as the toggle
+bit.
+
+sharp (RC_PROTO_SHARP)
+----------------------
+
+This is a protocol used by Sharp VCRs, is described here
+https://www.sbprojects.net/knowledge/ir/sharp.php. There is a very long
+(40ms) space between the normal and inverted values, and some IR receivers
+cannot decode this.
+
+There is a 5 bit address and a 8 bit command. In the scancode the address is
+in bits 8 to 12, and the command in bits 0 to 7.
+
+xmp (RC_PROTO_XMP)
+------------------
+
+This protocol has several versions and only version 1 is supported. Refer
+to the decoder (ir-xmp-decoder.c) to see how it is encoded.
+
+
+cec (RC_PROTO_CEC)
+------------------
+
+This is not an IR protocol, this is a protocol over CEC. The CEC
+infrastructure uses rc-core for handling CEC commands, so that they
+can easily be remapped.
+
+imon (RC_PROTO_IMON)
+--------------------
+
+This protocol is used by Antec Veris/SoundGraph iMON remotes.
+
+The protocol
+describes both button presses and pointer movements. The protocol encodes
+31 bits, and the scancode is simply the 31 bits with the top bit always 0.
+
+rc-mm-12 (RC_PROTO_RCMM12)
+--------------------------
+
+The rc-mm protocol is described here
+https://www.sbprojects.net/knowledge/ir/rcmm.php. The scancode is simply
+the 12 bits.
+
+rc-mm-24 (RC_PROTO_RCMM24)
+--------------------------
+
+The rc-mm protocol is described here
+https://www.sbprojects.net/knowledge/ir/rcmm.php. The scancode is simply
+the 24 bits.
+
+rc-mm-32 (RC_PROTO_RCMM32)
+--------------------------
+
+The rc-mm protocol is described here
+https://www.sbprojects.net/knowledge/ir/rcmm.php. The scancode is simply
+the 32 bits.
+
+xbox-dvd (RC_PROTO_XBOX_DVD)
+----------------------------
+
+This protocol is used by XBox DVD Remote, which was made for the original
+XBox. There is no in-kernel decoder or encoder for this protocol. The usb
+device decodes the protocol. There is a BPF decoder available in v4l-utils.
diff --git a/Documentation/userspace-api/media/rc/rc-sysfs-nodes.rst b/Documentation/userspace-api/media/rc/rc-sysfs-nodes.rst
new file mode 100644
index 000000000000..73dd75f77d65
--- /dev/null
+++ b/Documentation/userspace-api/media/rc/rc-sysfs-nodes.rst
@@ -0,0 +1,151 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _remote_controllers_sysfs_nodes:
+
+*******************************
+Remote Controller's sysfs nodes
+*******************************
+
+As defined at ``Documentation/ABI/testing/sysfs-class-rc``, those are
+the sysfs nodes that control the Remote Controllers:
+
+
+.. _sys_class_rc:
+
+/sys/class/rc/
+==============
+
+The ``/sys/class/rc/`` class sub-directory belongs to the Remote
+Controller core and provides a sysfs interface for configuring infrared
+remote controller receivers.
+
+
+.. _sys_class_rc_rcN:
+
+/sys/class/rc/rcN/
+==================
+
+A ``/sys/class/rc/rcN`` directory is created for each remote control
+receiver device where N is the number of the receiver.
+
+
+.. _sys_class_rc_rcN_protocols:
+
+/sys/class/rc/rcN/protocols
+===========================
+
+Reading this file returns a list of available protocols, something like::
+
+	rc5 [rc6] nec jvc [sony]
+
+Enabled protocols are shown in [] brackets.
+
+Writing "+proto" will add a protocol to the list of enabled protocols.
+
+Writing "-proto" will remove a protocol from the list of enabled
+protocols.
+
+Writing "proto" will enable only "proto".
+
+Writing "none" will disable all protocols.
+
+Write fails with ``EINVAL`` if an invalid protocol combination or unknown
+protocol name is used.
+
+
+.. _sys_class_rc_rcN_filter:
+
+/sys/class/rc/rcN/filter
+========================
+
+Sets the scancode filter expected value.
+
+Use in combination with ``/sys/class/rc/rcN/filter_mask`` to set the
+expected value of the bits set in the filter mask. If the hardware
+supports it then scancodes which do not match the filter will be
+ignored. Otherwise the write will fail with an error.
+
+This value may be reset to 0 if the current protocol is altered.
+
+
+.. _sys_class_rc_rcN_filter_mask:
+
+/sys/class/rc/rcN/filter_mask
+=============================
+
+Sets the scancode filter mask of bits to compare. Use in combination
+with ``/sys/class/rc/rcN/filter`` to set the bits of the scancode which
+should be compared against the expected value. A value of 0 disables the
+filter to allow all valid scancodes to be processed.
+
+If the hardware supports it then scancodes which do not match the filter
+will be ignored. Otherwise the write will fail with an error.
+
+This value may be reset to 0 if the current protocol is altered.
+
+
+.. _sys_class_rc_rcN_wakeup_protocols:
+
+/sys/class/rc/rcN/wakeup_protocols
+==================================
+
+Reading this file returns a list of available protocols to use for the
+wakeup filter, something like::
+
+	rc-5 nec nec-x rc-6-0 rc-6-6a-24 [rc-6-6a-32] rc-6-mce
+
+Note that protocol variants are listed, so ``nec``, ``sony``, ``rc-5``, ``rc-6``
+have their different bit length encodings listed if available.
+
+Note that all protocol variants are listed.
+
+The enabled wakeup protocol is shown in [] brackets.
+
+Only one protocol can be selected at a time.
+
+Writing "proto" will use "proto" for wakeup events.
+
+Writing "none" will disable wakeup.
+
+Write fails with ``EINVAL`` if an invalid protocol combination or unknown
+protocol name is used, or if wakeup is not supported by the hardware.
+
+
+.. _sys_class_rc_rcN_wakeup_filter:
+
+/sys/class/rc/rcN/wakeup_filter
+===============================
+
+Sets the scancode wakeup filter expected value. Use in combination with
+``/sys/class/rc/rcN/wakeup_filter_mask`` to set the expected value of
+the bits set in the wakeup filter mask to trigger a system wake event.
+
+If the hardware supports it and wakeup_filter_mask is not 0 then
+scancodes which match the filter will wake the system from e.g. suspend
+to RAM or power off. Otherwise the write will fail with an error.
+
+This value may be reset to 0 if the wakeup protocol is altered.
+
+
+.. _sys_class_rc_rcN_wakeup_filter_mask:
+
+/sys/class/rc/rcN/wakeup_filter_mask
+====================================
+
+Sets the scancode wakeup filter mask of bits to compare. Use in
+combination with ``/sys/class/rc/rcN/wakeup_filter`` to set the bits of
+the scancode which should be compared against the expected value to
+trigger a system wake event.
+
+If the hardware supports it and wakeup_filter_mask is not 0 then
+scancodes which match the filter will wake the system from e.g. suspend
+to RAM or power off. Otherwise the write will fail with an error.
+
+This value may be reset to 0 if the wakeup protocol is altered.
diff --git a/Documentation/userspace-api/media/rc/rc-table-change.rst b/Documentation/userspace-api/media/rc/rc-table-change.rst
new file mode 100644
index 000000000000..f5d00a20b939
--- /dev/null
+++ b/Documentation/userspace-api/media/rc/rc-table-change.rst
@@ -0,0 +1,25 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _Remote_controllers_table_change:
+
+*******************************************
+Changing default Remote Controller mappings
+*******************************************
+
+The event interface provides two ioctls to be used against the
+/dev/input/event device, to allow changing the default keymapping.
+
+This program demonstrates how to replace the keymap tables.
+
+
+.. toctree::
+    :maxdepth: 1
+
+    keytable.c
diff --git a/Documentation/userspace-api/media/rc/rc-tables.rst b/Documentation/userspace-api/media/rc/rc-tables.rst
new file mode 100644
index 000000000000..33b724b17ff3
--- /dev/null
+++ b/Documentation/userspace-api/media/rc/rc-tables.rst
@@ -0,0 +1,766 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _Remote_controllers_tables:
+
+************************
+Remote controller tables
+************************
+
+Unfortunately, for several years, there was no effort to create uniform
+IR keycodes for different devices. This caused the same IR keyname to be
+mapped completely differently on different IR devices. This resulted
+that the same IR keyname to be mapped completely different on different
+IR's. Due to that, V4L2 API now specifies a standard for mapping Media
+keys on IR.
+
+This standard should be used by both V4L/DVB drivers and userspace
+applications
+
+The modules register the remote as keyboard within the linux input
+layer. This means that the IR key strokes will look like normal keyboard
+key strokes (if CONFIG_INPUT_KEYBOARD is enabled). Using the event
+devices (CONFIG_INPUT_EVDEV) it is possible for applications to access
+the remote via /dev/input/event devices.
+
+
+.. _rc_standard_keymap:
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. flat-table:: IR default keymapping
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+
+    -  .. row 1
+
+       -  Key code
+
+       -  Meaning
+
+       -  Key examples on IR
+
+    -  .. row 2
+
+       -  **Numeric keys**
+
+    -  .. row 3
+
+       -  ``KEY_NUMERIC_0``
+
+       -  Keyboard digit 0
+
+       -  0
+
+    -  .. row 4
+
+       -  ``KEY_NUMERIC_1``
+
+       -  Keyboard digit 1
+
+       -  1
+
+    -  .. row 5
+
+       -  ``KEY_NUMERIC_2``
+
+       -  Keyboard digit 2
+
+       -  2
+
+    -  .. row 6
+
+       -  ``KEY_NUMERIC_3``
+
+       -  Keyboard digit 3
+
+       -  3
+
+    -  .. row 7
+
+       -  ``KEY_NUMERIC_4``
+
+       -  Keyboard digit 4
+
+       -  4
+
+    -  .. row 8
+
+       -  ``KEY_NUMERIC_5``
+
+       -  Keyboard digit 5
+
+       -  5
+
+    -  .. row 9
+
+       -  ``KEY_NUMERIC_6``
+
+       -  Keyboard digit 6
+
+       -  6
+
+    -  .. row 10
+
+       -  ``KEY_NUMERIC_7``
+
+       -  Keyboard digit 7
+
+       -  7
+
+    -  .. row 11
+
+       -  ``KEY_NUMERIC_8``
+
+       -  Keyboard digit 8
+
+       -  8
+
+    -  .. row 12
+
+       -  ``KEY_NUMERIC_9``
+
+       -  Keyboard digit 9
+
+       -  9
+
+    -  .. row 13
+
+       -  **Movie play control**
+
+    -  .. row 14
+
+       -  ``KEY_FORWARD``
+
+       -  Instantly advance in time
+
+       -  >> / FORWARD
+
+    -  .. row 15
+
+       -  ``KEY_BACK``
+
+       -  Instantly go back in time
+
+       -  <<< / BACK
+
+    -  .. row 16
+
+       -  ``KEY_FASTFORWARD``
+
+       -  Play movie faster
+
+       -  >>> / FORWARD
+
+    -  .. row 17
+
+       -  ``KEY_REWIND``
+
+       -  Play movie back
+
+       -  REWIND / BACKWARD
+
+    -  .. row 18
+
+       -  ``KEY_NEXT``
+
+       -  Select next chapter / sub-chapter / interval
+
+       -  NEXT / SKIP
+
+    -  .. row 19
+
+       -  ``KEY_PREVIOUS``
+
+       -  Select previous chapter / sub-chapter / interval
+
+       -  << / PREV / PREVIOUS
+
+    -  .. row 20
+
+       -  ``KEY_AGAIN``
+
+       -  Repeat the video or a video interval
+
+       -  REPEAT / LOOP / RECALL
+
+    -  .. row 21
+
+       -  ``KEY_PAUSE``
+
+       -  Pause stream
+
+       -  PAUSE / FREEZE
+
+    -  .. row 22
+
+       -  ``KEY_PLAY``
+
+       -  Play movie at the normal timeshift
+
+       -  NORMAL TIMESHIFT / LIVE / >
+
+    -  .. row 23
+
+       -  ``KEY_PLAYPAUSE``
+
+       -  Alternate between play and pause
+
+       -  PLAY / PAUSE
+
+    -  .. row 24
+
+       -  ``KEY_STOP``
+
+       -  Stop stream
+
+       -  STOP
+
+    -  .. row 25
+
+       -  ``KEY_RECORD``
+
+       -  Start/stop recording stream
+
+       -  CAPTURE / REC / RECORD/PAUSE
+
+    -  .. row 26
+
+       -  ``KEY_CAMERA``
+
+       -  Take a picture of the image
+
+       -  CAMERA ICON / CAPTURE / SNAPSHOT
+
+    -  .. row 27
+
+       -  ``KEY_SHUFFLE``
+
+       -  Enable shuffle mode
+
+       -  SHUFFLE
+
+    -  .. row 28
+
+       -  ``KEY_TIME``
+
+       -  Activate time shift mode
+
+       -  TIME SHIFT
+
+    -  .. row 29
+
+       -  ``KEY_TITLE``
+
+       -  Allow changing the chapter
+
+       -  CHAPTER
+
+    -  .. row 30
+
+       -  ``KEY_SUBTITLE``
+
+       -  Allow changing the subtitle
+
+       -  SUBTITLE
+
+    -  .. row 31
+
+       -  **Image control**
+
+    -  .. row 32
+
+       -  ``KEY_BRIGHTNESSDOWN``
+
+       -  Decrease Brightness
+
+       -  BRIGHTNESS DECREASE
+
+    -  .. row 33
+
+       -  ``KEY_BRIGHTNESSUP``
+
+       -  Increase Brightness
+
+       -  BRIGHTNESS INCREASE
+
+    -  .. row 34
+
+       -  ``KEY_ANGLE``
+
+       -  Switch video camera angle (on videos with more than one angle
+	  stored)
+
+       -  ANGLE / SWAP
+
+    -  .. row 35
+
+       -  ``KEY_EPG``
+
+       -  Open the Elecrowonic Play Guide (EPG)
+
+       -  EPG / GUIDE
+
+    -  .. row 36
+
+       -  ``KEY_TEXT``
+
+       -  Activate/change closed caption mode
+
+       -  CLOSED CAPTION/TELETEXT / DVD TEXT / TELETEXT / TTX
+
+    -  .. row 37
+
+       -  **Audio control**
+
+    -  .. row 38
+
+       -  ``KEY_AUDIO``
+
+       -  Change audio source
+
+       -  AUDIO SOURCE / AUDIO / MUSIC
+
+    -  .. row 39
+
+       -  ``KEY_MUTE``
+
+       -  Mute/unmute audio
+
+       -  MUTE / DEMUTE / UNMUTE
+
+    -  .. row 40
+
+       -  ``KEY_VOLUMEDOWN``
+
+       -  Decrease volume
+
+       -  VOLUME- / VOLUME DOWN
+
+    -  .. row 41
+
+       -  ``KEY_VOLUMEUP``
+
+       -  Increase volume
+
+       -  VOLUME+ / VOLUME UP
+
+    -  .. row 42
+
+       -  ``KEY_MODE``
+
+       -  Change sound mode
+
+       -  MONO/STEREO
+
+    -  .. row 43
+
+       -  ``KEY_LANGUAGE``
+
+       -  Select Language
+
+       -  1ST / 2ND LANGUAGE / DVD LANG / MTS/SAP / MTS SEL
+
+    -  .. row 44
+
+       -  **Channel control**
+
+    -  .. row 45
+
+       -  ``KEY_CHANNEL``
+
+       -  Go to the next favorite channel
+
+       -  ALT / CHANNEL / CH SURFING / SURF / FAV
+
+    -  .. row 46
+
+       -  ``KEY_CHANNELDOWN``
+
+       -  Decrease channel sequentially
+
+       -  CHANNEL - / CHANNEL DOWN / DOWN
+
+    -  .. row 47
+
+       -  ``KEY_CHANNELUP``
+
+       -  Increase channel sequentially
+
+       -  CHANNEL + / CHANNEL UP / UP
+
+    -  .. row 48
+
+       -  ``KEY_DIGITS``
+
+       -  Use more than one digit for channel
+
+       -  PLUS / 100/ 1xx / xxx / -/-- / Single Double Triple Digit
+
+    -  .. row 49
+
+       -  ``KEY_SEARCH``
+
+       -  Start channel autoscan
+
+       -  SCAN / AUTOSCAN
+
+    -  .. row 50
+
+       -  **Colored keys**
+
+    -  .. row 51
+
+       -  ``KEY_BLUE``
+
+       -  IR Blue key
+
+       -  BLUE
+
+    -  .. row 52
+
+       -  ``KEY_GREEN``
+
+       -  IR Green Key
+
+       -  GREEN
+
+    -  .. row 53
+
+       -  ``KEY_RED``
+
+       -  IR Red key
+
+       -  RED
+
+    -  .. row 54
+
+       -  ``KEY_YELLOW``
+
+       -  IR Yellow key
+
+       -  YELLOW
+
+    -  .. row 55
+
+       -  **Media selection**
+
+    -  .. row 56
+
+       -  ``KEY_CD``
+
+       -  Change input source to Compact Disc
+
+       -  CD
+
+    -  .. row 57
+
+       -  ``KEY_DVD``
+
+       -  Change input to DVD
+
+       -  DVD / DVD MENU
+
+    -  .. row 58
+
+       -  ``KEY_EJECTCLOSECD``
+
+       -  Open/close the CD/DVD player
+
+       -  -> ) / CLOSE / OPEN
+
+    -  .. row 59
+
+       -  ``KEY_MEDIA``
+
+       -  Turn on/off Media application
+
+       -  PC/TV / TURN ON/OFF APP
+
+    -  .. row 60
+
+       -  ``KEY_PC``
+
+       -  Selects from TV to PC
+
+       -  PC
+
+    -  .. row 61
+
+       -  ``KEY_RADIO``
+
+       -  Put into AM/FM radio mode
+
+       -  RADIO / TV/FM / TV/RADIO / FM / FM/RADIO
+
+    -  .. row 62
+
+       -  ``KEY_TV``
+
+       -  Select tv mode
+
+       -  TV / LIVE TV
+
+    -  .. row 63
+
+       -  ``KEY_TV2``
+
+       -  Select Cable mode
+
+       -  AIR/CBL
+
+    -  .. row 64
+
+       -  ``KEY_VCR``
+
+       -  Select VCR mode
+
+       -  VCR MODE / DTR
+
+    -  .. row 65
+
+       -  ``KEY_VIDEO``
+
+       -  Alternate between input modes
+
+       -  SOURCE / SELECT / DISPLAY / SWITCH INPUTS / VIDEO
+
+    -  .. row 66
+
+       -  **Power control**
+
+    -  .. row 67
+
+       -  ``KEY_POWER``
+
+       -  Turn on/off computer
+
+       -  SYSTEM POWER / COMPUTER POWER
+
+    -  .. row 68
+
+       -  ``KEY_POWER2``
+
+       -  Turn on/off application
+
+       -  TV ON/OFF / POWER
+
+    -  .. row 69
+
+       -  ``KEY_SLEEP``
+
+       -  Activate sleep timer
+
+       -  SLEEP / SLEEP TIMER
+
+    -  .. row 70
+
+       -  ``KEY_SUSPEND``
+
+       -  Put computer into suspend mode
+
+       -  STANDBY / SUSPEND
+
+    -  .. row 71
+
+       -  **Window control**
+
+    -  .. row 72
+
+       -  ``KEY_CLEAR``
+
+       -  Stop stream and return to default input video/audio
+
+       -  CLEAR / RESET / BOSS KEY
+
+    -  .. row 73
+
+       -  ``KEY_CYCLEWINDOWS``
+
+       -  Minimize windows and move to the next one
+
+       -  ALT-TAB / MINIMIZE / DESKTOP
+
+    -  .. row 74
+
+       -  ``KEY_FAVORITES``
+
+       -  Open the favorites stream window
+
+       -  TV WALL / Favorites
+
+    -  .. row 75
+
+       -  ``KEY_MENU``
+
+       -  Call application menu
+
+       -  2ND CONTROLS (USA: MENU) / DVD/MENU / SHOW/HIDE CTRL
+
+    -  .. row 76
+
+       -  ``KEY_NEW``
+
+       -  Open/Close Picture in Picture
+
+       -  PIP
+
+    -  .. row 77
+
+       -  ``KEY_OK``
+
+       -  Send a confirmation code to application
+
+       -  OK / ENTER / RETURN
+
+    -  .. row 78
+
+       -  ``KEY_ASPECT_RATIO``
+
+       -  Select screen aspect ratio
+
+       -  4:3 16:9 SELECT
+
+    -  .. row 79
+
+       -  ``KEY_FULL_SCREEN``
+
+       -  Put device into zoom/full screen mode
+
+       -  ZOOM / FULL SCREEN / ZOOM+ / HIDE PANNEL / SWITCH
+
+    -  .. row 80
+
+       -  **Navigation keys**
+
+    -  .. row 81
+
+       -  ``KEY_ESC``
+
+       -  Cancel current operation
+
+       -  CANCEL / BACK
+
+    -  .. row 82
+
+       -  ``KEY_HELP``
+
+       -  Open a Help window
+
+       -  HELP
+
+    -  .. row 83
+
+       -  ``KEY_HOMEPAGE``
+
+       -  Navigate to Homepage
+
+       -  HOME
+
+    -  .. row 84
+
+       -  ``KEY_INFO``
+
+       -  Open On Screen Display
+
+       -  DISPLAY INFORMATION / OSD
+
+    -  .. row 85
+
+       -  ``KEY_WWW``
+
+       -  Open the default browser
+
+       -  WEB
+
+    -  .. row 86
+
+       -  ``KEY_UP``
+
+       -  Up key
+
+       -  UP
+
+    -  .. row 87
+
+       -  ``KEY_DOWN``
+
+       -  Down key
+
+       -  DOWN
+
+    -  .. row 88
+
+       -  ``KEY_LEFT``
+
+       -  Left key
+
+       -  LEFT
+
+    -  .. row 89
+
+       -  ``KEY_RIGHT``
+
+       -  Right key
+
+       -  RIGHT
+
+    -  .. row 90
+
+       -  **Miscellaneous keys**
+
+    -  .. row 91
+
+       -  ``KEY_DOT``
+
+       -  Return a dot
+
+       -  .
+
+    -  .. row 92
+
+       -  ``KEY_FN``
+
+       -  Select a function
+
+       -  FUNCTION
+
+
+It should be noted that, sometimes, there some fundamental missing keys
+at some cheaper IR's. Due to that, it is recommended to:
+
+
+.. _rc_keymap_notes:
+
+.. flat-table:: Notes
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  On simpler IR's, without separate channel keys, you need to map UP
+	  as ``KEY_CHANNELUP``
+
+    -  .. row 2
+
+       -  On simpler IR's, without separate channel keys, you need to map
+	  DOWN as ``KEY_CHANNELDOWN``
+
+    -  .. row 3
+
+       -  On simpler IR's, without separate volume keys, you need to map
+	  LEFT as ``KEY_VOLUMEDOWN``
+
+    -  .. row 4
+
+       -  On simpler IR's, without separate volume keys, you need to map
+	  RIGHT as ``KEY_VOLUMEUP``
diff --git a/Documentation/userspace-api/media/rc/remote_controllers.rst b/Documentation/userspace-api/media/rc/remote_controllers.rst
new file mode 100644
index 000000000000..3ab2d6db1564
--- /dev/null
+++ b/Documentation/userspace-api/media/rc/remote_controllers.rst
@@ -0,0 +1,59 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. include:: <isonum.txt>
+
+.. _remote_controllers:
+
+################################
+Part III - Remote Controller API
+################################
+
+.. only:: html
+
+   .. class:: toc-title
+
+        Table of Contents
+
+.. toctree::
+    :maxdepth: 5
+    :numbered:
+
+    rc-intro
+    rc-sysfs-nodes
+    rc-protos
+    rc-tables
+    rc-table-change
+    lirc-dev
+
+
+**********************
+Revision and Copyright
+**********************
+
+Authors:
+
+- Carvalho Chehab, Mauro <mchehab@kernel.org>
+
+ - Initial version.
+
+**Copyright** |copy| 2009-2016 : Mauro Carvalho Chehab
+
+****************
+Revision History
+****************
+
+:revision: 3.15 / 2014-02-06 (*mcc*)
+
+Added the interface description and the RC sysfs class description.
+
+
+:revision: 1.0 / 2009-09-06 (*mcc*)
+
+Initial revision
diff --git a/Documentation/userspace-api/media/typical_media_device.svg b/Documentation/userspace-api/media/typical_media_device.svg
new file mode 100644
index 000000000000..3420341ff7b6
--- /dev/null
+++ b/Documentation/userspace-api/media/typical_media_device.svg
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Permission is granted to copy, distribute and/or modify this
+    document under the terms of the GNU Free Documentation License,
+    Version 1.1 or any later version published by the Free Software
+    Foundation, with no Invariant Sections, no Front-Cover Texts
+    and no Back-Cover Texts. A copy of the license is included at
+    Documentation/userspace-api/media/fdl-appendix.rst.
+
+    TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+-->
+<svg id="svg2" width="235mm" height="179mm" clip-path="url(#a)" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" preserveAspectRatio="xMidYMid" version="1.2" viewBox="0 0 22648.239 17899.829" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><metadata id="metadata1533"><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title/></cc:Work></rdf:RDF></metadata><defs id="defs4"><clipPath id="a"><rect id="rect7" width="28000" height="21000"/></clipPath></defs><path id="path11" d="m10146 2636c-518.06 0-1035.1 515-1035.1 1031v4124c0 516 517.06 1032 1035.1 1032h8572.2c518.06 0 1036.1-516 1036.1-1032v-4124c0-516-518.06-1031-1036.1-1031h-8572.2z"
+fill="#fcf" style=""/><path id="path15" d="m1505.5 13443c-293 0-585 292-585 585v2340c0 293 292 586 585 586h3275c293 0 586-293 586-586v-2340c0-293-293-585-586-585h-3275z" fill="#ffc" style=""/><path id="path19" d="m517.15 22.013c-461 0-922 461-922 922v11169c0 461 461 923 922 923h3692c461 0 922-462 922-923v-11169c0-461-461-922-922-922h-3692z" fill="#e6e6e6" style=""/><path id="path23" d="m2371.5 6438h-2260v-1086h4520v1086h-2260z" fill="#ff8080" style=""/><path id="path25" d="m2371.5 6438h-2260v-1086h4520v1086h-2260z" fill="none" stroke="#3465af" style=""/><text id="text27" class="TextShape" x="-2089.4541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan29" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan31" class="TextPosition" x="489.5459" y="6111.0132" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan33"
+fill="#000000" font-family="Serif, serif" font-size="493.88px">Audio decoder</tspan></tspan></tspan></text>
+<path id="path37" d="m2371.5 9608h-2260v-1270h4520v1270h-2260z" fill="#ff8080" style=""/><path id="path39" d="m2371.5 9608h-2260v-1270h4520v1270h-2260z" fill="none" stroke="#3465af" style=""/><text id="text41" class="TextShape" x="-2089.4541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan43" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan45" class="TextPosition" x="527.5459" y="9189.0127" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan47" fill="#000000" font-family="Serif, serif" font-size="493.88px">Video decoder</tspan></tspan></tspan></text>
+<path id="path51" d="m2363.5 8053h-2269v-1224h4537v1224h-2268z" fill="#ff8080" style=""/><path id="path53" d="m2363.5 8053h-2269v-1224h4537v1224h-2268z" fill="none" stroke="#3465af" style=""/><text id="text55" class="TextShape" x="-2089.4541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan57" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan59" class="TextPosition" x="481.5459" y="7657.0132" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan61" fill="#000000" font-family="Serif, serif" font-size="493.88px">Audio encoder</tspan></tspan></tspan></text>
+<path id="path65" d="m13622 10386h-3810v-1281h7620v1281h-3810z" fill="#cfc" style=""/><path id="path67" d="m13622 10386h-3810v-1281h7620v1281h-3810z" fill="none" stroke="#3465af" style=""/><text id="text69" class="TextShape" x="-2089.4541" y="-2446.187" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan71" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan73" class="TextPosition" x="10287.546" y="9960.8135" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan75" fill="#000000" font-family="Serif, serif" font-size="493.88px">Button Key/IR input logic</tspan></tspan></tspan></text>
+<path id="path79" d="m12080 12182h-2268v-1412h4536v1412h-2268z" fill="#cfe7f5" style=""/><path id="path81" d="m12080 12182h-2268v-1412h4536v1412h-2268z" fill="none" stroke="#3465af" style=""/><text id="text83" class="TextShape" x="-2089.4541" y="-2389.7871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan85" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan87" class="TextPosition" x="10792.546" y="11692.213" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan89" fill="#000000" font-family="Serif, serif" font-size="493.88px">EEPROM</tspan></tspan></tspan></text>
+<path id="path93" d="m3050.5 15498h-1563v-1715h3126v1715h-1563z" fill="#fc9" style=""/><path id="path95" d="m3050.5 15498h-1563v-1715h3126v1715h-1563z" fill="none" stroke="#3465af" style=""/><text id="text97" class="TextShape" x="-2089.4541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan99" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan101" class="TextPosition" x="2186.5459" y="14856.013" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan103" fill="#000000" font-family="Serif, serif" font-size="493.88px">Sensor</tspan></tspan></tspan></text>
+<path id="path107" d="m4629.5 5866 385-353v176h1167v-176l386 353-386 354v-177h-1167v177l-385-354z" fill="#729fcf" style=""/><path id="path109" d="m4629.5 5866 385-353v176h1167v-176l386 353-386 354v-177h-1167v177l-385-354z" fill="none" stroke="#3465af" style=""/><path id="path113" d="m4629.5 7448 385-353v176h1167v-176l386 353-386 354v-177h-1167v177l-385-354z" fill="#729fcf" style=""/><path id="path115" d="m4629.5 7448 385-353v176h1167v-176l386 353-386 354v-177h-1167v177l-385-354z" fill="none" stroke="#3465af" style=""/><path id="path119" d="m4631.5 8936 385-353v176h1166v-176l386 353-386 354v-177h-1166v177l-385-354z" fill="#729fcf" style=""/><path id="path121" d="m4631.5 8936 385-353v176h1166v-176l386 353-386 354v-177h-1166v177l-385-354z" fill="none" stroke="#3465af" style=""/><path id="path125" d="m7872.5 11464 385-353v176h1166v-176l386 353-386 354v-177h-1166v177l-385-354z"
+fill="#729fcf" style=""/><path id="path127" d="m7872.5 11464 385-353v176h1166v-176l386 353-386 354v-177h-1166v177l-385-354z" fill="none" stroke="#3465af" style=""/><path id="path131" d="m7872.5 9716.8 385-353v176h1166v-176l386 353-386 354v-177h-1166v177l-385-354z" fill="#729fcf" style=""/><path id="path133" d="m7872.5 9716.8 385-353v176h1166v-176l386 353-386 354v-177h-1166v177l-385-354z" fill="none" stroke="#3465af" style=""/><path id="path137" d="m7872.5 14994 670-353v176h2028v-176l671 353-671 354v-177h-2028v177l-670-354z" fill="#729fcf" style=""/><path id="path139" d="m7872.5 14994 670-353v176h2028v-176l671 353-671 354v-177h-2028v177l-670-354z" fill="none" stroke="#3465af" style=""/><path id="path143" d="m17534 14105 978.49 840.89-978.49 840.89v-420.86h-2960.5v420.86l-979.49-840.89 979.49-840.89v420.03h2960.5v-420.03z" fill="#729fcf" style=""/><path id="path145" d="m17534 14105 978.49
+840.89-978.49 840.89v-420.86h-2960.5v420.86l-979.49-840.89 979.49-840.89v420.03h2960.5v-420.03z" fill="none" stroke="#3465af" stroke-width="25.77" style=""/><text id="text149" class="TextShape" x="-9922.1533" y="-644.58704" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan151" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan153" class="TextPosition" transform="matrix(0,-1,1,0,8509,40173)" x="14418.847" y="15187.413" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan155" fill="#000000" font-family="Serif, serif" font-size="493.88px">System Bus</tspan></tspan></tspan></text>
+<path id="path159" d="m11062 7098h-1250v-875h2499v875h-1249z" fill="#cff" style=""/><path id="path161" d="m11062 7098h-1250v-875h2499v875h-1249z" fill="none" stroke="#3465af" style=""/><text id="text163" class="TextShape" x="-2089.4541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan165" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan167" class="TextPosition" x="10125.546" y="6876.0132" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan169" fill="#000000" font-family="Serif, serif" font-size="493.88px">Demux</tspan></tspan></tspan></text>
+<path id="path173" d="m7906.5 6601 373-357v178h1130v-178l374 357-374 358v-179h-1130v179l-373-358z" fill="#729fcf" style=""/><path id="path175" d="m7906.5 6601 373-357v178h1130v-178l374 357-374 358v-179h-1130v179l-373-358z" fill="none" stroke="#3465af" style=""/><path id="path179" d="m7906.5 5214 373-358v179h1130v-179l374 358-374 358v-179h-1130v179l-373-358z" fill="#729fcf" style=""/><path id="path181" d="m7906.5 5214 373-358v179h1130v-179l374 358-374 358v-179h-1130v179l-373-358z" fill="none" stroke="#3465af" style=""/><path id="path185" d="m14233 5828h-4421v-1270h8841v1270h-4420z" fill="#cff" style=""/><path id="path187" d="m14233 5828h-4421v-1270h8841v1270h-4420z" fill="none" stroke="#3465af" style=""/><text id="text189" class="TextShape" x="-2089.4541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan191" class="TextParagraph" font-family="Serif, serif"
+font-size="493.88px"><tspan id="tspan193" class="TextPosition" x="10696.546" y="5409.0132" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan195" fill="#000000" font-family="Serif, serif" font-size="493.88px">Conditional Access Module</tspan></tspan></tspan></text>
+<path id="path199" d="m2355.5 11123h-2269v-1224h4537v1224h-2268z" fill="#ff8080" style=""/><path id="path201" d="m2355.5 11123h-2269v-1224h4537v1224h-2268z" fill="none" stroke="#3465af" style=""/><text id="text203" class="TextShape" x="-2089.4541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan205" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan207" class="TextPosition" x="511.5459" y="10727.013" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan209" fill="#000000" font-family="Serif, serif" font-size="493.88px">Video encoder</tspan></tspan></tspan></text>
+<path id="path213" d="m4631.5 10470 385-353v176h1166v-176l386 353-386 354v-177h-1166v177l-385-354z" fill="#729fcf" style=""/><path id="path215" d="m4631.5 10470 385-353v176h1166v-176l386 353-386 354v-177h-1166v177l-385-354z" fill="none" stroke="#3465af" style=""/><path id="path219" d="m18702 5381 385-353v176h1166v-176l386 353-386 354v-177h-1166v177l-385-354z" fill="#729fcf" style=""/><path id="path221" d="m18702 5381 385-353v176h1166v-176l386 353-386 354v-177h-1166v177l-385-354z" fill="none" stroke="#3465af" style=""/><text id="text225" class="TextShape" x="-1976.5541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan227" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan229" class="TextPosition" x="13.4459" y="12314.013" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan231" fill="#000000"
+font-family="Serif, serif" font-size="493.88px">Radio / Analog TV</tspan></tspan></tspan></text>
+<text id="text235" class="TextShape" x="-2089.4541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan237" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan239" class="TextPosition" x="12866.546" y="8560.0127" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan241" fill="#000000" font-family="Serif, serif" font-size="493.88px">Digital TV</tspan></tspan></tspan></text>
+<text id="text245" class="TextShape" x="-8919.0537" y="-1373.787" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan247" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan249" class="TextPosition" x="5804.9458" y="17793.213" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan251" fill="#000000" font-family="Serif, serif" font-size="493.88px">PS.: picture is not complete: other blocks may be present</tspan></tspan></tspan></text>
+<text id="text255" class="TextShape" x="-2089.4541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan257" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan259" class="TextPosition" x="2109.5459" y="16397.014" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan261" fill="#000000" font-family="Serif, serif" font-size="493.88px">Webcam</tspan></tspan></tspan></text>
+<path id="path265" d="m12463 13926h-2650v-1412h5299v1412h-2649z" fill="#f90" style=""/><path id="path267" d="m12463 13926h-2650v-1412h5299v1412h-2649z" fill="none" stroke="#3465af" style=""/><text id="text269" class="TextShape" x="-2089.4541" y="-2446.187" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan271" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan273" class="TextPosition" x="10175.546" y="13435.813" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan275" fill="#000000" font-family="Serif, serif" font-size="493.88px">Processing blocks</tspan></tspan></tspan></text>
+<path id="path279" d="m7872.5 13208 385-353v176h1166v-176l386 353-386 354v-177h-1166v177l-385-354z" fill="#729fcf" style=""/><path id="path281" d="m7872.5 13208 385-353v176h1166v-176l386 353-386 354v-177h-1166v177l-385-354z" fill="none" stroke="#3465af" style=""/><path id="path285" d="m4612.5 14790 397-353v176h1201v-176l398 353-398 354v-177h-1201v177l-397-354z" fill="#729fcf" style=""/><path id="path287" d="m4612.5 14790 397-353v176h1201v-176l398 353-398 354v-177h-1201v177l-397-354z" fill="none" stroke="#3465af" style=""/><text id="text291" class="TextShape" x="-2428.0542" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan293" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan295" class="TextPosition" x="20421.945" y="6628.0132" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan297" fill="#000000"
+font-family="Serif, serif" font-size="493.88px">Smartcard</tspan></tspan></tspan></text>
+<path id="path301" d="m623.32 436.01c-334.6 0-669.2 333-669.2 666v2668c0 333 334.6 666 669.2 666h18456c334.6 0 670.2-333 670.2-666v-2668c0-333-335.6-666-670.2-666h-18456z" fill="#fcf" style=""/><path id="path305" d="m3031.5 2991h-1614v-1816h3227v1816h-1613z" fill="#ff8080" style=""/><path id="path307" d="m3031.5 2991h-1614v-1816h3227v1816h-1613z" fill="none" stroke="#3465af" style=""/><text id="text309" class="TextShape" x="-2089.4541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan311" class="TextParagraph"><tspan id="tspan313" class="TextPosition" x="2284.5459" y="1947.0129" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan315" fill="#000000" font-family="Serif, serif" font-size="493.88px">Tuner</tspan></tspan></tspan><tspan id="tspan317" class="TextParagraph"><tspan id="tspan319" class="TextPosition" x="2061.5459" y="2650.0129"
+font-family="Serif, serif" font-size="493.88px"><tspan id="tspan321" fill="#000000" font-family="Serif, serif" font-size="493.88px">FM/TV</tspan></tspan></tspan></text>
+<path id="path325" d="m812.55 1538c0 111 40 202 88 202h530c48 0 89-91 89-202 0-110-41-202-89-202h-530c-48 0-88 92-88 202z" fill="#ff8080" style=""/><path id="path327" d="m812.55 1538c0 111 40 202 88 202h530c48 0 89-91 89-202 0-110-41-202-89-202h-530c-48 0-88 92-88 202z" fill="none" stroke="#3465af" style=""/><path id="path329" d="m812.55 1538c0 111 40 202 88 202s88-91 88-202c0-110-40-202-88-202s-88 92-88 202z" fill="#ffb3b3" style=""/><path id="path331" d="m812.55 1538c0 111 40 202 88 202s88-91 88-202c0-110-40-202-88-202s-88 92-88 202z" fill="none" stroke="#3465af" style=""/><path id="path335" d="m813.55 2103c0 110 40 202 88 202h530c48 0 89-92 89-202s-41-203-89-203h-530c-48 0-88 93-88 203z" fill="#ff8080" style=""/><path id="path337" d="m813.55 2103c0 110 40 202 88 202h530c48 0 89-92 89-202s-41-203-89-203h-530c-48 0-88 93-88 203z" fill="none" stroke="#3465af" style=""/><path
+id="path339" d="m813.55 2103c0 110 40 202 88 202s88-92 88-202-40-203-88-203-88 93-88 203z" fill="#ffb3b3" style=""/><path id="path341" d="m813.55 2103c0 110 40 202 88 202s88-92 88-202-40-203-88-203-88 93-88 203z" fill="none" stroke="#3465af" style=""/><path id="path345" d="m4629.5 2032 385-353v176h1167v-176l386 353-386 354v-177h-1167v177l-385-354z" fill="#729fcf" style=""/><path id="path347" d="m4629.5 2032 385-353v176h1167v-176l386 353-386 354v-177h-1167v177l-385-354z" fill="none" stroke="#3465af" style=""/><path id="path351" d="m7889.5 1986 402-368v184h1217v-184l403 368-403 369v-185h-1217v185l-402-369z" fill="#729fcf" style=""/><path id="path353" d="m7889.5 1986 402-368v184h1217v-184l403 368-403 369v-185h-1217v185l-402-369z" fill="none" stroke="#3465af" style=""/><path id="path357" d="m14411 4025h-4500v-1389h9e3v1389h-4500z" fill="#cff" style=""/><path id="path359" d="m14411
+4025h-4500v-1389h9e3v1389h-4500z" fill="none" stroke="#3465af" style=""/><text id="text361" class="TextShape" x="-2089.4541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan363" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan365" class="TextPosition" x="9961.5459" y="3546.0129" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan367" fill="#000000" font-family="Serif, serif" font-size="493.88px">Satellite Equipment Control (SEC)</tspan></tspan></tspan></text>
+<path id="path371" d="m11311 2436h-1400v-1e3h2800v1e3h-1400z" fill="#cff" style=""/><path id="path373" d="m11311 2436h-1400v-1e3h2800v1e3h-1400z" fill="none" stroke="#3465af" style=""/><text id="text375" class="TextShape" x="-2089.4541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan377" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan379" class="TextPosition" x="10375.546" y="2152.0129" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan381" fill="#000000" font-family="Serif, serif" font-size="493.88px">Demod</tspan></tspan></tspan></text>
+<path id="path385" d="m7889.5 3287 402-368v184h1217v-184l403 368-403 369v-185h-1217v185l-402-369z" fill="#729fcf" style=""/><path id="path387" d="m7889.5 3287 402-368v184h1217v-184l403 368-403 369v-185h-1217v185l-402-369z" fill="none" stroke="#3465af" style=""/><path id="path389" d="m7906.5 9121v7302h-1270v-14605h1270v7303z" fill="#ff9" style=""/><path id="path391" d="m7906.5 9121v7302h-1270v-14605h1270v7303z" fill="none" stroke="#3465af" style=""/><text id="text393" class="TextShape" transform="rotate(-90)" x="-20792.584" y="-6589.021" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan395" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan397" class="TextPosition" transform="matrix(0,-1,1,0,-4473,23627)" x="-11215.646" y="7460.9849" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan399" fill="#000000" font-family="Serif,
+serif" font-size="493.88px">I2C Bus (control bus)</tspan></tspan></tspan></text>
+<text id="text403" class="TextShape" x="-2145.854" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan405" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan407" class="TextPosition" x="7245.146" y="1114.0129" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan409" fill="#000000" font-family="Serif, serif" font-size="493.88px">Digital TV Frontend</tspan></tspan></tspan></text>
+<path id="path415" d="m863.15 636.14c-18.27 0-35.525 0.99994-53.795 2.9998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path417" d="m776.87 644.14c-17.255 2.9998-35.525 6.9996-52.78 11.999" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path419" d="m692.63 666.14c-16.24 5.9996-33.495 11.999-49.735 19.999" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path421" d="m613.46 700.14c-15.225 7.9995-31.465 16.999-46.69 26.998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path423" d="m539.36 745.14c-14.21 9.9994-28.42 20.999-42.63 31.998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path425" d="m471.36 798.14c-13.195 11.999-26.39 23.999-38.57 36.998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path427" d="m410.46 859.13c-11.165 12.999-22.33
+26.998-33.495 40.998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path429" d="m357.68 927.13c-10.15 13.999-19.285 28.998-28.42 44.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path431" d="m314.03 1000.1c-8.12 15.999-15.225 31.998-22.33 48.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path433" d="m280.54 1079.1c-5.075 16.999-10.15 33.998-14.21 50.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path435" d="m260.24 1162.1c-3.045 17.999-5.075 34.998-6.09 52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path437" d="m254.15 1247.1v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path439" d="m254.15 1333.1v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path441" d="m254.15 1418.1v52.997"
+fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path443" d="m254.15 1504.1v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path445" d="m254.15 1589.1v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path447" d="m254.15 1675.1v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path449" d="m254.15 1760.1v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path451" d="m254.15 1845.1v53.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path453" d="m254.15 1931.1v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path455" d="m254.15 2016.1v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path457" d="m254.15 2102.1v52.997" fill="none" stroke="#3465af" stroke-width="28.432"
+style=""/><path id="path459" d="m254.15 2187.1v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path461" d="m254.15 2273v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path463" d="m254.15 2358v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path465" d="m254.15 2443v53.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path467" d="m254.15 2529v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path469" d="m254.15 2614v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path471" d="m254.15 2700v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path473" d="m254.15 2785v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path475" d="m254.15 2871v52.997" fill="none"
+stroke="#3465af" stroke-width="28.432" style=""/><path id="path477" d="m254.15 2956v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path479" d="m254.15 3041v53.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path481" d="m254.15 3127v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path483" d="m254.15 3212v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path485" d="m254.15 3298v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path487" d="m254.15 3383v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path489" d="m254.15 3469v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path491" d="m254.15 3554v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path493"
+d="m254.15 3639c0 17.999 1.015 35.998 3.045 52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path495" d="m262.27 3724c4.06 17.999 8.12 34.998 13.195 51.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path497" d="m285.61 3807c6.09 15.999 13.195 32.998 20.3 48.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path499" d="m321.14 3885c8.12 14.999 17.255 30.998 27.405 45.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path501" d="m366.81 3957.9c10.15 13.999 21.315 27.998 32.48 41.998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path503" d="m420.61 4023.9c12.18 12.999 25.375 25.998 38.57 37.998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path505" d="m483.54 4083.9c13.195 10.999 27.405 22.999 41.615 32.998" fill="none"
+stroke="#3465af" stroke-width="28.432" style=""/><path id="path507" d="m552.56 4135.9c14.21 9.9994 29.435 18.999 45.675 26.998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path509" d="m627.67 4178.9c15.225 6.9996 32.48 14.999 48.72 20.999" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path511" d="m707.85 4210.9c17.255 4.9997 34.51 9.9994 51.765 13.999" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path513" d="m792.1 4230.9c17.255 1.9999 35.525 3.9998 53.795 4.9997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path515" d="m878.37 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path517" d="m964.65 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path519" d="m1051.9 4235.9h53.795" fill="none" stroke="#3465af"
+stroke-width="28.432" style=""/><path id="path521" d="m1138.2 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path523" d="m1225.5 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path525" d="m1311.8 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path527" d="m1398.1 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path529" d="m1485.3 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path531" d="m1571.6 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path533" d="m1658.9 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path535" d="m1745.2 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path537"
+d="m1832.5 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path539" d="m1918.7 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path541" d="m2005 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path543" d="m2092.3 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path545" d="m2178.6 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path547" d="m2265.9 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path549" d="m2352.2 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path551" d="m2439.4 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path553" d="m2525.7 4235.9h53.795" fill="none" stroke="#3465af"
+stroke-width="28.432" style=""/><path id="path555" d="m2612 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path557" d="m2699.3 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path559" d="m2785.6 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path561" d="m2872.8 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path563" d="m2959.1 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path565" d="m3046.4 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path567" d="m3132.7 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path569" d="m3220 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path571"
+d="m3306.3 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path573" d="m3392.5 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path575" d="m3479.8 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path577" d="m3566.1 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path579" d="m3653.4 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path581" d="m3739.7 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path583" d="m3826.9 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path585" d="m3913.2 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path587" d="m3999.5 4235.9h53.795" fill="none"
+stroke="#3465af" stroke-width="28.432" style=""/><path id="path589" d="m4086.8 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path591" d="m4173.1 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path593" d="m4260.4 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path595" d="m4346.6 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path597" d="m4433.9 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path599" d="m4520.2 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path601" d="m4606.5 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path603" d="m4693.8 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432"
+style=""/><path id="path605" d="m4780 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path607" d="m4867.3 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path609" d="m4953.6 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path611" d="m5040.9 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path613" d="m5127.2 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path615" d="m5213.4 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path617" d="m5300.7 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path619" d="m5387 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path621" d="m5474.3 4235.9h53.795"
+fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path623" d="m5560.6 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path625" d="m5647.9 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path627" d="m5734.1 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path629" d="m5820.4 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path631" d="m5907.7 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path633" d="m5994 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path635" d="m6081.3 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path637" d="m6167.5 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432"
+style=""/><path id="path639" d="m6254.8 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path641" d="m6341.1 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path643" d="m6427.4 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path645" d="m6514.7 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path647" d="m6600.9 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path649" d="m6688.2 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path651" d="m6774.5 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path653" d="m6861.8 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path655" d="m6948.1
+4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path657" d="m7035.4 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path659" d="m7121.6 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path661" d="m7207.9 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path663" d="m7295.2 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path665" d="m7381.5 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path667" d="m7468.8 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path669" d="m7555 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path671" d="m7642.3 4235.9h53.795" fill="none" stroke="#3465af"
+stroke-width="28.432" style=""/><path id="path673" d="m7728.6 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path675" d="m7814.9 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path677" d="m7902.2 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path679" d="m7988.4 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path681" d="m8075.7 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path683" d="m8162 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path685" d="m8249.3 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path687" d="m8335.6 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path689"
+d="m8421.9 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path691" d="m8509.1 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path693" d="m8595.4 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path695" d="m8682.7 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path697" d="m8769 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path699" d="m8856.3 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path701" d="m8942.5 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path703" d="m9028.8 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path705" d="m9116.1 4235.9h53.795" fill="none" stroke="#3465af"
+stroke-width="28.432" style=""/><path id="path707" d="m9202.4 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path709" d="m9289.7 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path711" d="m9376 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path713" d="m9463.2 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path715" d="m9549.5 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path717" d="m9635.8 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path719" d="m9723.1 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path721" d="m9809.4 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path723"
+d="m9896.6 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path725" d="m9982.9 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path727" d="m10070 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path729" d="m10156 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path731" d="m10243 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path733" d="m10330 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path735" d="m10416 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path737" d="m10504 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path739" d="m10590 4235.9h53.795" fill="none" stroke="#3465af"
+stroke-width="28.432" style=""/><path id="path741" d="m10677 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path743" d="m10763 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path745" d="m10850 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path747" d="m10937 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path749" d="m11023 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path751" d="m11111 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path753" d="m11197 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path755" d="m11284 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path757" d="m11370
+4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path759" d="m11458 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path761" d="m11544 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path763" d="m11630 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path765" d="m11718 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path767" d="m11804 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path769" d="m11891 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path771" d="m11977 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path773" d="m12065 4235.9h53.795" fill="none" stroke="#3465af"
+stroke-width="28.432" style=""/><path id="path775" d="m12151 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path777" d="m12237 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path779" d="m12325 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path781" d="m12411 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path783" d="m12498 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path785" d="m12584 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path787" d="m12672 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path789" d="m12758 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path791"
+d="m12844 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path793" d="m12931 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path795" d="m13018 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path797" d="m13105 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path799" d="m13191 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path801" d="m13279 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path803" d="m13365 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path805" d="m13451 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path807" d="m13538 4235.9h53.795" fill="none" stroke="#3465af"
+stroke-width="28.432" style=""/><path id="path809" d="m13625 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path811" d="m13712 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path813" d="m13798 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path815" d="m13886 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path817" d="m13972 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path819" d="m14058 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path821" d="m14145 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path823" d="m14232 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path825" d="m14319
+4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path827" d="m14405 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path829" d="m14493 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path831" d="m14579 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path833" d="m14665 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path835" d="m14752 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path837" d="m14839 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path839" d="m14926 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path841" d="m15012 4235.9h53.795" fill="none" stroke="#3465af"
+stroke-width="28.432" style=""/><path id="path843" d="m15100 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path845" d="m15186 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path847" d="m15272 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path849" d="m15359 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path851" d="m15446 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path853" d="m15533 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path855" d="m15619 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path857" d="m15707 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path859" d="m15793
+4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path861" d="m15880 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path863" d="m15966 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path865" d="m16053 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path867" d="m16140 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path869" d="m16226 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path871" d="m16313 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path873" d="m16400 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path875" d="m16487 4235.9h53.795" fill="none" stroke="#3465af"
+stroke-width="28.432" style=""/><path id="path877" d="m16573 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path879" d="m16660 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path881" d="m16747 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path883" d="m16833 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path885" d="m16920 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path887" d="m17007 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path889" d="m17094 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path891" d="m17180 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path893"
+d="m17267 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path895" d="m17354 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path897" d="m17440 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path899" d="m17527 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path901" d="m17614 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path903" d="m17701 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path905" d="m17787 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path907" d="m17874 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path909" d="m17961 4235.9h53.795" fill="none" stroke="#3465af"
+stroke-width="28.432" style=""/><path id="path911" d="m18047 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path913" d="m18134 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path915" d="m18221 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path917" d="m18308 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path919" d="m18394 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path921" d="m18481 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path923" d="m18568 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path925" d="m18654 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path927" d="m18741
+4235.9c17.255-0.9999 35.525-1.9999 53.795-4.9997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path929" d="m18828 4225.9c17.255-3.9998 34.51-8.9995 51.765-13.999" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path931" d="m18911 4200.9c16.24-5.9996 32.48-12.999 48.72-20.999" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path933" d="m18989 4164.9c15.225-7.9996 31.465-16.999 45.675-26.998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path935" d="m19062 4118.9c14.21-9.9994 28.42-20.999 42.63-31.998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path937" d="m19129 4064.9c13.195-11.999 25.375-24.998 37.555-37.998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path939" d="m19189 4002.9c11.165-13.999 22.33-27.998 33.495-41.998" fill="none"
+stroke="#3465af" stroke-width="28.432" style=""/><path id="path941" d="m19241 3933.9c10.15-14.999 19.285-29.998 27.405-44.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path943" d="m19283 3860c7.105-15.999 14.21-32.998 20.3-48.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path945" d="m19315 3780c5.075-16.999 9.135-33.998 13.195-50.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path947" d="m19333 3697c2.03-17.999 4.06-34.998 4.06-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path949" d="m19337 3612v-53.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path951" d="m19337 3526v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path953" d="m19337 3441v-52.997" fill="none" stroke="#3465af" stroke-width="28.432"
+style=""/><path id="path955" d="m19337 3355v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path957" d="m19337 3270v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path959" d="m19337 3184v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path961" d="m19337 3099v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path963" d="m19337 3014v-53.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path965" d="m19337 2928v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path967" d="m19337 2843v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path969" d="m19337 2757v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path971" d="m19337 2672v-52.997" fill="none"
+stroke="#3465af" stroke-width="28.432" style=""/><path id="path973" d="m19337 2586v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path975" d="m19337 2501v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path977" d="m19337 2415v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path979" d="m19337 2330v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path981" d="m19337 2245v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path983" d="m19337 2159.1v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path985" d="m19337 2074.1v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path987" d="m19337 1988.1v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path
+id="path989" d="m19337 1903.1v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path991" d="m19337 1817.1v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path993" d="m19337 1732.1v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path995" d="m19337 1647.1v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path997" d="m19337 1561.1v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path999" d="m19337 1476.1v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1001" d="m19337 1390.1v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1003" d="m19337 1305.1v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1005" d="m19337
+1219.1c-1.015-16.999-3.045-34.998-5.075-51.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1007" d="m19326 1135.1c-4.06-16.999-8.12-34.998-14.21-50.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1009" d="m19301 1053.1c-6.09-15.999-13.195-32.998-21.315-48.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1011" d="m19264 976.12c-9.135-15.999-18.27-30.998-28.42-45.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1013" d="m19216 904.13c-10.15-13.999-21.315-27.998-33.495-41.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1015" d="m19161 838.13c-12.18-12.999-24.36-24.998-37.555-36.998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1017" d="m19098 780.14c-14.21-11.999-28.42-21.999-42.63-32.998" fill="none"
+stroke="#3465af" stroke-width="28.432" style=""/><path id="path1019" d="m19028 729.14c-15.225-8.9995-30.45-17.999-46.69-26.998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1021" d="m18951 688.14c-16.24-7.9995-32.48-13.999-49.735-19.999" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1023" d="m18870 657.14c-17.255-4.9997-34.51-8.9995-51.765-11.999" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1025" d="m18786 640.14c-18.27-2.9998-35.525-3.9998-53.795-3.9998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1027" d="m18700 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1029" d="m18612 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1031" d="m18526 636.14h-53.795" fill="none" stroke="#3465af"
+stroke-width="28.432" style=""/><path id="path1033" d="m18439 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1035" d="m18353 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1037" d="m18266 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1039" d="m18179 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1041" d="m18093 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1043" d="m18005 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1045" d="m17919 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1047" d="m17832 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path
+id="path1049" d="m17746 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1051" d="m17659 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1053" d="m17572 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1055" d="m17486 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1057" d="m17399 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1059" d="m17312 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1061" d="m17225 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1063" d="m17139 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1065" d="m17052 636.14h-54.81"
+fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1067" d="m16965 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1069" d="m16879 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1071" d="m16792 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1073" d="m16705 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1075" d="m16618 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1077" d="m16532 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1079" d="m16445 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1081" d="m16358 636.14h-53.795" fill="none" stroke="#3465af"
+stroke-width="28.432" style=""/><path id="path1083" d="m16272 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1085" d="m16185 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1087" d="m16098 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1089" d="m16011 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1091" d="m15925 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1093" d="m15837 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1095" d="m15751 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1097" d="m15665 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path
+id="path1099" d="m15578 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1101" d="m15491 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1103" d="m15404 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1105" d="m15318 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1107" d="m15230 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1109" d="m15144 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1111" d="m15058 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1113" d="m14971 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1115" d="m14884 636.14h-53.795"
+fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1117" d="m14797 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1119" d="m14711 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1121" d="m14624 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1123" d="m14537 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1125" d="m14451 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1127" d="m14364 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1129" d="m14277 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1131" d="m14190 636.14h-53.795" fill="none" stroke="#3465af"
+stroke-width="28.432" style=""/><path id="path1133" d="m14104 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1135" d="m14017 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1137" d="m13930 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1139" d="m13844 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1141" d="m13757 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1143" d="m13670 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1145" d="m13583 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1147" d="m13497 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path
+id="path1149" d="m13410 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1151" d="m13323 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1153" d="m13237 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1155" d="m13150 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1157" d="m13063 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1159" d="m12976 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1161" d="m12890 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1163" d="m12803 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1165" d="m12716 636.14h-53.795"
+fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1167" d="m12630 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1169" d="m12543 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1171" d="m12456 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1173" d="m12369 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1175" d="m12283 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1177" d="m12196 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1179" d="m12109 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1181" d="m12022 636.14h-53.795" fill="none" stroke="#3465af"
+stroke-width="28.432" style=""/><path id="path1183" d="m11936 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1185" d="m11850 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1187" d="m11762 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1189" d="m11676 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1191" d="m11589 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1193" d="m11502 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1195" d="m11415 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1197" d="m11329 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path
+id="path1199" d="m11243 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1201" d="m11155 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1203" d="m11069 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1205" d="m10982 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1207" d="m10895 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1209" d="m10808 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1211" d="m10722 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1213" d="m10636 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1215" d="m10548 636.14h-53.795"
+fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1217" d="m10462 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1219" d="m10375 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1221" d="m10288 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1223" d="m10201 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1225" d="m10115 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1227" d="m10029 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1229" d="m9941.3 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1231" d="m9855 636.14h-53.795" fill="none" stroke="#3465af"
+stroke-width="28.432" style=""/><path id="path1233" d="m9767.7 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1235" d="m9681.5 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1237" d="m9594.2 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1239" d="m9507.9 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1241" d="m9421.6 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1243" d="m9334.3 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1245" d="m9248.1 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1247" d="m9160.8 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432"
+style=""/><path id="path1249" d="m9074.5 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1251" d="m8987.2 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1253" d="m8900.9 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1255" d="m8814.7 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1257" d="m8727.4 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1259" d="m8641.1 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1261" d="m8553.8 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1263" d="m8467.5 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1265"
+d="m8380.2 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1267" d="m8294 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1269" d="m8207.7 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1271" d="m8120.4 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1273" d="m8034.1 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1275" d="m7946.8 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1277" d="m7860.6 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1279" d="m7773.3 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1281" d="m7687 636.14h-53.795" fill="none"
+stroke="#3465af" stroke-width="28.432" style=""/><path id="path1283" d="m7599.7 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1285" d="m7513.4 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1287" d="m7427.2 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1289" d="m7339.9 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1291" d="m7253.6 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1293" d="m7166.3 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1295" d="m7080 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1297" d="m6992.7 636.14h-53.795" fill="none" stroke="#3465af"
+stroke-width="28.432" style=""/><path id="path1299" d="m6906.5 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1301" d="m6820.2 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1303" d="m6732.9 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1305" d="m6646.6 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1307" d="m6559.3 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1309" d="m6473.1 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1311" d="m6385.8 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1313" d="m6299.5 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432"
+style=""/><path id="path1315" d="m6213.2 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1317" d="m6125.9 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1319" d="m6039.6 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1321" d="m5952.4 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1323" d="m5866.1 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1325" d="m5778.8 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1327" d="m5692.5 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1329" d="m5606.2 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1331"
+d="m5519 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1333" d="m5432.7 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1335" d="m5345.4 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1337" d="m5259.1 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1339" d="m5171.8 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1341" d="m5085.5 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1343" d="m4999.3 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1345" d="m4912 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1347" d="m4825.7 636.14h-53.795" fill="none"
+stroke="#3465af" stroke-width="28.432" style=""/><path id="path1349" d="m4738.4 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1351" d="m4652.1 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1353" d="m4564.9 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1355" d="m4478.6 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1357" d="m4392.3 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1359" d="m4305 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1361" d="m4218.7 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1363" d="m4131.4 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432"
+style=""/><path id="path1365" d="m4045.2 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1367" d="m3957.9 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1369" d="m3871.6 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1371" d="m3785.3 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1373" d="m3698 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1375" d="m3611.8 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1377" d="m3524.5 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1379" d="m3438.2 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1381"
+d="m3350.9 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1383" d="m3264.6 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1385" d="m3177.3 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1387" d="m3091.1 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1389" d="m3004.8 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1391" d="m2917.5 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1393" d="m2831.2 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1395" d="m2743.9 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1397" d="m2657.7 636.14h-53.795"
+fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1399" d="m2570.4 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1401" d="m2484.1 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1403" d="m2397.8 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1405" d="m2310.5 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1407" d="m2224.3 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1409" d="m2137 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1411" d="m2050.7 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1413" d="m1963.4 636.14h-53.795" fill="none" stroke="#3465af"
+stroke-width="28.432" style=""/><path id="path1415" d="m1877.1 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1417" d="m1790.9 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1419" d="m1703.6 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1421" d="m1617.3 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1423" d="m1530 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1425" d="m1443.7 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1427" d="m1356.4 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1429" d="m1270.2 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path
+id="path1431" d="m1183.9 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1433" d="m1096.6 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1435" d="m1010.3 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1437" d="m923.03 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><g id="g4044" style=""><rect id="rect1441" x="21109" y="4753.1" width="1213.6" height="1100.7" fill="#f3e777" style=""/><path id="path1443" d="m20656 5536.4v-405.46l150.7-169.16c82.886-93.039 170.53-186.62 194.77-207.96l44.069-38.798 783.23-0.086 783.23-0.086v1227h-1956v-405.46zm1027.7 136.98v-78.372l-169.91 4.925-169.91 4.9249-5.09 45.854c-8.249 74.303 46.711 101.04 207.69 101.04h137.21v-78.372zm235.86-262.94 4.495-341.31 207.2-8.6408 207.2-8.6408
+5.144-46.443c9.596-86.615-41.863-102.05-322.02-96.607l-246.71 4.7956-4.438 419.08-4.439 419.08h149.08l4.494-341.31zm391.3 313.72c26.41-19.286 36.255-41.399 32.697-73.447l-5.09-45.854h-348.1l-5.38 48.984c-9.97 90.771 0.993 97.91 150.36 97.91 99.305 0 148.27-7.6982 175.52-27.594zm-627.16-274.84v-77.768h-348.1v66.246c0 36.436 4.973 71.431 11.051 77.768 6.078 6.3366 84.401 11.521 174.05 11.521h163v-77.768zm659.89-4.9154 5.125-74.042-179.18 4.9155-179.18 4.9155-5.38 48.984c-10.473 95.348-2.259 99.57 183.28 94.197l170.2-4.9284 5.125-74.042zm-659.89-237.63v-78.372l-169.91 4.925-169.91 4.925-5.097 73.447-5.097 73.447h350v-78.372zm659.86 4.925-5.097-73.447h-348.1l-5.38 48.984c-10.289 93.673-2.146 97.91 188.15 97.91h175.52l-5.097-73.447zm-659.86-228.98v-77.768h-137.21c-97.358 0-147.91 7.8138-174.05 26.902-34.952 25.523-49.645 92.242-25.79 117.11 6.078 6.3366 84.401 11.521 174.05
+11.521h163v-77.768z" fill="#ca4677" style=""/></g><text id="text1489" class="TextShape" transform="scale(1.1036 .90616)" x="171.41566" y="9913.7109" fill-rule="evenodd" font-family="Serif, serif" font-size="493.87px" stroke-linejoin="round" stroke-width="28.222"><tspan id="tspan1491" class="TextParagraph" font-family="Serif, serif" font-size="493.87px"/></text>
+<g id="g4048" style=""><rect id="rect1447" x="18797" y="13737" width="2320.7" height="2342.4" fill="#6076b3" style=""/><rect id="rect1451" x="18532" y="13817" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1453" x="18532" y="14076" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1455" x="18532" y="14334" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1457" x="18532" y="14593" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1459" x="18532" y="14851" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round"
+stroke-width="28.222" style=""/><rect id="rect1461" x="18532" y="15110" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1463" x="18532" y="15368" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1465" x="18532" y="15626" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1467" x="18532" y="15884" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1469" x="21080" y="13783" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1471" x="21080" y="14041" width="302.7"
+height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1473" x="21080" y="14299" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1475" x="21080" y="14558" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1477" x="21080" y="14816" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1479" x="21080" y="15075" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1481" x="21080" y="15333" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round"
+stroke-width="28.222" style=""/><rect id="rect1483" x="21080" y="15592" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1485" x="21080" y="15850" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><text id="text1493" transform="scale(1.1036 .90616)" x="17205.688" y="16777.641" fill="#000000" fill-rule="evenodd" font-family="Sans" font-size="856.96px" letter-spacing="0px" stroke-linejoin="round" stroke-width="28.222" word-spacing="0px" style="line-height:125%" line-height="125%" xml:space="preserve"><tspan id="tspan1495" x="17205.688" y="16777.641" style="">CPU</tspan></text>
+</g><text id="text1499" class="TextShape" x="-11700.553" y="565.61298" fill-rule="evenodd" font-family="Serif, serif" font-size="493.88px" stroke-linejoin="round" stroke-width="28.222"><tspan id="tspan1501" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan1503" class="TextPosition" transform="matrix(0,-1,1,0,8509,40173)" x="12640.447" y="16397.613" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan1505" fill="#000000" font-family="Serif, serif" font-size="493.88px">PCI, USB, SPI, I2C, ...</tspan></tspan></tspan></text>
+<path id="path1511" d="m12408 15562h-1115.1v-1420.3h2230.2v1420.3h-1115.1z" fill="#cfe7f5" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><path id="path1513" d="m12408 15562h-1115.1v-1420.3h2230.2v1420.3h-1115.1z" fill="none" stroke="#3465af" stroke-linejoin="round" stroke-width="19.847" style=""/><text id="text1515" class="TextShape" x="-1394.0863" y="590.73016" fill-rule="evenodd" font-family="Serif, serif" font-size="493.88px" stroke-linejoin="round" stroke-width="28.222"><tspan id="tspan1517" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan1519" class="TextPosition" x="11487.915" y="14672.743" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan1521" fill="#000000" font-family="Serif, serif" font-size="493.88px">Bridge</tspan></tspan></tspan></text>
+<text id="text1523" class="TextShape" x="-1450.5308" y="1324.5078" fill-rule="evenodd" font-family="Serif, serif" font-size="493.88px" stroke-linejoin="round" stroke-width="28.222"><tspan id="tspan1525" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan1527" class="TextPosition" x="11431.471" y="15406.52" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan1529" fill="#000000" font-family="Serif, serif" font-size="493.88px"> DMA</tspan></tspan></tspan></text>
+</svg>
diff --git a/Documentation/userspace-api/media/v4l/app-pri.rst b/Documentation/userspace-api/media/v4l/app-pri.rst
new file mode 100644
index 000000000000..5018ede2706f
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/app-pri.rst
@@ -0,0 +1,37 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _app-pri:
+
+********************
+Application Priority
+********************
+
+When multiple applications share a device it may be desirable to assign
+them different priorities. Contrary to the traditional "rm -rf /" school
+of thought, a video recording application could for example block other
+applications from changing video controls or switching the current TV
+channel. Another objective is to permit low priority applications
+working in background, which can be preempted by user controlled
+applications and automatically regain control of the device at a later
+time.
+
+Since these features cannot be implemented entirely in user space V4L2
+defines the :ref:`VIDIOC_G_PRIORITY <VIDIOC_G_PRIORITY>` and
+:ref:`VIDIOC_S_PRIORITY <VIDIOC_G_PRIORITY>` ioctls to request and
+query the access priority associate with a file descriptor. Opening a
+device assigns a medium priority, compatible with earlier versions of
+V4L2 and drivers not supporting these ioctls. Applications requiring a
+different priority will usually call :ref:`VIDIOC_S_PRIORITY
+<VIDIOC_G_PRIORITY>` after verifying the device with the
+:ref:`VIDIOC_QUERYCAP` ioctl.
+
+Ioctls changing driver properties, such as
+:ref:`VIDIOC_S_INPUT <VIDIOC_G_INPUT>`, return an ``EBUSY`` error code
+after another application obtained higher priority.
diff --git a/Documentation/userspace-api/media/v4l/async.rst b/Documentation/userspace-api/media/v4l/async.rst
new file mode 100644
index 000000000000..8bc4a726c95e
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/async.rst
@@ -0,0 +1,16 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _async:
+
+****************
+Asynchronous I/O
+****************
+
+This method is not defined yet.
diff --git a/Documentation/userspace-api/media/v4l/audio.rst b/Documentation/userspace-api/media/v4l/audio.rst
new file mode 100644
index 000000000000..d6bb85092e02
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/audio.rst
@@ -0,0 +1,104 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _audio:
+
+************************
+Audio Inputs and Outputs
+************************
+
+Audio inputs and outputs are physical connectors of a device. Video
+capture devices have inputs, output devices have outputs, zero or more
+each. Radio devices have no audio inputs or outputs. They have exactly
+one tuner which in fact *is* an audio source, but this API associates
+tuners with video inputs or outputs only, and radio devices have none of
+these. [#f1]_ A connector on a TV card to loop back the received audio
+signal to a sound card is not considered an audio output.
+
+Audio and video inputs and outputs are associated. Selecting a video
+source also selects an audio source. This is most evident when the video
+and audio source is a tuner. Further audio connectors can combine with
+more than one video input or output. Assumed two composite video inputs
+and two audio inputs exist, there may be up to four valid combinations.
+The relation of video and audio connectors is defined in the
+``audioset`` field of the respective struct
+:c:type:`v4l2_input` or struct
+:c:type:`v4l2_output`, where each bit represents the index
+number, starting at zero, of one audio input or output.
+
+To learn about the number and attributes of the available inputs and
+outputs applications can enumerate them with the
+:ref:`VIDIOC_ENUMAUDIO` and
+:ref:`VIDIOC_ENUMAUDOUT <VIDIOC_ENUMAUDOUT>` ioctl, respectively.
+The struct :c:type:`v4l2_audio` returned by the
+:ref:`VIDIOC_ENUMAUDIO` ioctl also contains signal
+status information applicable when the current audio input is queried.
+
+The :ref:`VIDIOC_G_AUDIO <VIDIOC_G_AUDIO>` and
+:ref:`VIDIOC_G_AUDOUT <VIDIOC_G_AUDOUT>` ioctls report the current
+audio input and output, respectively.
+
+.. note::
+
+   Note that, unlike :ref:`VIDIOC_G_INPUT <VIDIOC_G_INPUT>` and
+   :ref:`VIDIOC_G_OUTPUT <VIDIOC_G_OUTPUT>` these ioctls return a
+   structure as :ref:`VIDIOC_ENUMAUDIO` and
+   :ref:`VIDIOC_ENUMAUDOUT <VIDIOC_ENUMAUDOUT>` do, not just an index.
+
+To select an audio input and change its properties applications call the
+:ref:`VIDIOC_S_AUDIO <VIDIOC_G_AUDIO>` ioctl. To select an audio
+output (which presently has no changeable properties) applications call
+the :ref:`VIDIOC_S_AUDOUT <VIDIOC_G_AUDOUT>` ioctl.
+
+Drivers must implement all audio input ioctls when the device has
+multiple selectable audio inputs, all audio output ioctls when the
+device has multiple selectable audio outputs. When the device has any
+audio inputs or outputs the driver must set the ``V4L2_CAP_AUDIO`` flag
+in the struct :c:type:`v4l2_capability` returned by
+the :ref:`VIDIOC_QUERYCAP` ioctl.
+
+
+Example: Information about the current audio input
+==================================================
+
+.. code-block:: c
+
+    struct v4l2_audio audio;
+
+    memset(&audio, 0, sizeof(audio));
+
+    if (-1 == ioctl(fd, VIDIOC_G_AUDIO, &audio)) {
+	perror("VIDIOC_G_AUDIO");
+	exit(EXIT_FAILURE);
+    }
+
+    printf("Current input: %s\\n", audio.name);
+
+
+Example: Switching to the first audio input
+===========================================
+
+.. code-block:: c
+
+    struct v4l2_audio audio;
+
+    memset(&audio, 0, sizeof(audio)); /* clear audio.mode, audio.reserved */
+
+    audio.index = 0;
+
+    if (-1 == ioctl(fd, VIDIOC_S_AUDIO, &audio)) {
+	perror("VIDIOC_S_AUDIO");
+	exit(EXIT_FAILURE);
+    }
+
+.. [#f1]
+   Actually struct :c:type:`v4l2_audio` ought to have a
+   ``tuner`` field like struct :c:type:`v4l2_input`, not
+   only making the API more consistent but also permitting radio devices
+   with multiple tuners.
diff --git a/Documentation/userspace-api/media/v4l/bayer.svg b/Documentation/userspace-api/media/v4l/bayer.svg
new file mode 100644
index 000000000000..82e805c68c1f
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/bayer.svg
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    This file is dual-licensed: you can use it either under the terms
+    of the GPL 2.0 or the GFDL 1.1+ license, at your option. Note that this
+    dual licensing only applies to this file, and not this project as a
+    whole.
+
+    a) This file is free software; you can redistribute it and/or
+       modify it under the terms of the GNU General Public License as
+       published by the Free Software Foundation version 2 of
+       the License.
+
+       This file is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+    Or, alternatively,
+
+    b) Permission is granted to copy, distribute and/or modify this
+       document under the terms of the GNU Free Documentation License,
+       Version 1.1 or any later version published by the Free Software
+       Foundation, with no Invariant Sections, no Front-Cover Texts
+       and no Back-Cover Texts. A copy of the license is included at
+       Documentation/userspace-api/media/fdl-appendix.rst.
+
+    TODO: replace it to GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
+-->
+<svg id="svg2" width="164.15mm" height="46.771mm" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" preserveAspectRatio="xMidYMid" version="1.2" viewBox="0 0 16415.333 4677.1107" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><metadata id="metadata652"><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title/></cc:Work></rdf:RDF></metadata><g id="g186" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id6"><rect id="rect189" class="BoundingBox" x="3299" y="3199" width="1303" height="1203" fill="none"/><path id="path191" d="m3950 4400h-650v-1200h1300v1200h-650z" fill="#00f"/><path id="path193" d="m3950
+4400h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text195" class="TextShape"><tspan id="tspan197" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan199" class="TextPosition" x="3739" y="4021"><tspan id="tspan201" fill="#ffffff">B</tspan></tspan></tspan></text>
+</g></g><g id="g203" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id7"><rect id="rect206" class="BoundingBox" x="4599" y="3199" width="1303" height="1203" fill="none"/><path id="path208" d="m5250 4400h-650v-1200h1300v1200h-650z" fill="#0c0"/><path id="path210" d="m5250 4400h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text212" class="TextShape"><tspan id="tspan214" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan216" class="TextPosition" x="5003" y="4021"><tspan id="tspan218" fill="#ffffff">G</tspan></tspan></tspan></text>
+</g></g><g id="g220" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id8"><rect id="rect223" class="BoundingBox" x="3299" y="4399" width="1303" height="1203" fill="none"/><path id="path225" d="m3950 5600h-650v-1200h1300v1200h-650z" fill="#0c0"/><path id="path227" d="m3950 5600h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text229" class="TextShape"><tspan id="tspan231" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan233" class="TextPosition" x="3703" y="5221"><tspan id="tspan235" fill="#ffffff">G</tspan></tspan></tspan></text>
+</g></g><g id="g237" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id9"><rect id="rect240" class="BoundingBox" x="4599" y="4399" width="1303" height="1203" fill="none"/><path id="path242" d="m5250 5600h-650v-1200h1300v1200h-650z" fill="#f00"/><path id="path244" d="m5250 5600h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text246" class="TextShape"><tspan id="tspan248" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan250" class="TextPosition" x="5022" y="5221"><tspan id="tspan252" fill="#ffffff">R</tspan></tspan></tspan></text>
+</g></g><g id="g254" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id10" fill="none"><rect id="rect257" class="BoundingBox" x="5999" y="3299" width="1003" height="1003"/><path id="path259" d="m6500 4300h-500v-1e3h1e3v1e3h-500z" stroke="#00f"/></g></g><g id="g261" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id11" fill="none"><rect id="rect264" class="BoundingBox" x="4699" y="5699" width="1003" height="1003"/><path id="path266" d="m5200 6700h-500v-1e3h1e3v1e3h-500z" stroke="#0c0"/></g></g><g id="g268" class="com.sun.star.drawing.TextShape" transform="translate(-3285.9 -3185.9)"><g id="id12"><rect id="rect271" class="BoundingBox" x="4e3" y="6900" width="2374" height="963" fill="none"/><text id="text273" class="TextShape"><tspan id="tspan275" class="TextParagraph" font-family="sans-serif" font-size="635px"
+font-weight="400"><tspan id="tspan277" class="TextPosition" x="4250" y="7601"><tspan id="tspan279" fill="#000000">BGGR</tspan></tspan></tspan></text>
+</g></g><g id="g281" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id13"><rect id="rect284" class="BoundingBox" x="8799" y="3199" width="1303" height="1203" fill="none"/><path id="path286" d="m9450 4400h-650v-1200h1300v1200h-650z" fill="#00f"/><path id="path288" d="m9450 4400h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text290" class="TextShape"><tspan id="tspan292" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan294" class="TextPosition" x="9239" y="4021"><tspan id="tspan296" fill="#ffffff">B</tspan></tspan></tspan></text>
+</g></g><g id="g298" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id14"><rect id="rect301" class="BoundingBox" x="7499" y="3199" width="1303" height="1203" fill="none"/><path id="path303" d="m8150 4400h-650v-1200h1300v1200h-650z" fill="#0c0"/><path id="path305" d="m8150 4400h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text307" class="TextShape"><tspan id="tspan309" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan311" class="TextPosition" x="7903" y="4021"><tspan id="tspan313" fill="#ffffff">G</tspan></tspan></tspan></text>
+</g></g><g id="g315" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id15"><rect id="rect318" class="BoundingBox" x="8799" y="4399" width="1303" height="1203" fill="none"/><path id="path320" d="m9450 5600h-650v-1200h1300v1200h-650z" fill="#0c0"/><path id="path322" d="m9450 5600h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text324" class="TextShape"><tspan id="tspan326" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan328" class="TextPosition" x="9203" y="5221"><tspan id="tspan330" fill="#ffffff">G</tspan></tspan></tspan></text>
+</g></g><g id="g332" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id16"><rect id="rect335" class="BoundingBox" x="7499" y="4399" width="1303" height="1203" fill="none"/><path id="path337" d="m8150 5600h-650v-1200h1300v1200h-650z" fill="#f00"/><path id="path339" d="m8150 5600h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text341" class="TextShape"><tspan id="tspan343" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan345" class="TextPosition" x="7922" y="5221"><tspan id="tspan347" fill="#ffffff">R</tspan></tspan></tspan></text>
+</g></g><g id="g349" class="com.sun.star.drawing.TextShape" transform="translate(-3285.9 -3185.9)"><g id="id17"><rect id="rect352" class="BoundingBox" x="8200" y="6900" width="2374" height="963" fill="none"/><text id="text354" class="TextShape"><tspan id="tspan356" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan358" class="TextPosition" x="8450" y="7601"><tspan id="tspan360" fill="#000000">GBRG</tspan></tspan></tspan></text>
+</g></g><g id="g362" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id18"><rect id="rect365" class="BoundingBox" x="17299" y="4399" width="1303" height="1203" fill="none"/><path id="path367" d="m17950 5600h-650v-1200h1300v1200h-650z" fill="#00f"/><path id="path369" d="m17950 5600h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text371" class="TextShape"><tspan id="tspan373" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan375" class="TextPosition" x="17739" y="5221"><tspan id="tspan377" fill="#ffffff">B</tspan></tspan></tspan></text>
+</g></g><g id="g379" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id19"><rect id="rect382" class="BoundingBox" x="17299" y="3199" width="1303" height="1203" fill="none"/><path id="path384" d="m17950 4400h-650v-1200h1300v1200h-650z" fill="#0c0"/><path id="path386" d="m17950 4400h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text388" class="TextShape"><tspan id="tspan390" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan392" class="TextPosition" x="17703" y="4021"><tspan id="tspan394" fill="#ffffff">G</tspan></tspan></tspan></text>
+</g></g><g id="g396" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id20"><rect id="rect399" class="BoundingBox" x="15999" y="4399" width="1303" height="1203" fill="none"/><path id="path401" d="m16650 5600h-650v-1200h1300v1200h-650z" fill="#0c0"/><path id="path403" d="m16650 5600h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text405" class="TextShape"><tspan id="tspan407" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan409" class="TextPosition" x="16403" y="5221"><tspan id="tspan411" fill="#ffffff">G</tspan></tspan></tspan></text>
+</g></g><g id="g413" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id21"><rect id="rect416" class="BoundingBox" x="15999" y="3199" width="1303" height="1203" fill="none"/><path id="path418" d="m16650 4400h-650v-1200h1300v1200h-650z" fill="#f00"/><path id="path420" d="m16650 4400h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text422" class="TextShape"><tspan id="tspan424" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan426" class="TextPosition" x="16422" y="4021"><tspan id="tspan428" fill="#ffffff">R</tspan></tspan></tspan></text>
+</g></g><g id="g430" class="com.sun.star.drawing.TextShape" transform="translate(-3285.9 -3185.9)"><g id="id22"><rect id="rect433" class="BoundingBox" x="16700" y="6900" width="2374" height="963" fill="none"/><text id="text435" class="TextShape"><tspan id="tspan437" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan439" class="TextPosition" x="16950" y="7601"><tspan id="tspan441" fill="#000000">RGGB</tspan></tspan></tspan></text>
+</g></g><g id="g443" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id23"><rect id="rect446" class="BoundingBox" x="11699" y="4399" width="1303" height="1203" fill="none"/><path id="path448" d="m12350 5600h-650v-1200h1300v1200h-650z" fill="#00f"/><path id="path450" d="m12350 5600h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text452" class="TextShape"><tspan id="tspan454" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan456" class="TextPosition" x="12139" y="5221"><tspan id="tspan458" fill="#ffffff">B</tspan></tspan></tspan></text>
+</g></g><g id="g460" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id24"><rect id="rect463" class="BoundingBox" x="11699" y="3199" width="1303" height="1203" fill="none"/><path id="path465" d="m12350 4400h-650v-1200h1300v1200h-650z" fill="#0c0"/><path id="path467" d="m12350 4400h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text469" class="TextShape"><tspan id="tspan471" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan473" class="TextPosition" x="12103" y="4021"><tspan id="tspan475" fill="#ffffff">G</tspan></tspan></tspan></text>
+</g></g><g id="g477" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id25"><rect id="rect480" class="BoundingBox" x="12999" y="4399" width="1303" height="1203" fill="none"/><path id="path482" d="m13650 5600h-650v-1200h1300v1200h-650z" fill="#0c0"/><path id="path484" d="m13650 5600h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text486" class="TextShape"><tspan id="tspan488" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan490" class="TextPosition" x="13403" y="5221"><tspan id="tspan492" fill="#ffffff">G</tspan></tspan></tspan></text>
+</g></g><g id="g494" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id26"><rect id="rect497" class="BoundingBox" x="12999" y="3199" width="1303" height="1203" fill="none"/><path id="path499" d="m13650 4400h-650v-1200h1300v1200h-650z" fill="#f00"/><path id="path501" d="m13650 4400h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text503" class="TextShape"><tspan id="tspan505" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan507" class="TextPosition" x="13422" y="4021"><tspan id="tspan509" fill="#ffffff">R</tspan></tspan></tspan></text>
+</g></g><g id="g511" class="com.sun.star.drawing.TextShape" transform="translate(-3285.9 -3185.9)"><g id="id27"><rect id="rect514" class="BoundingBox" x="12400" y="6900" width="2374" height="963" fill="none"/><text id="text516" class="TextShape"><tspan id="tspan518" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan520" class="TextPosition" x="12650" y="7601"><tspan id="tspan522" fill="#000000">GRBG</tspan></tspan></tspan></text>
+</g></g><g id="g524" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id28" fill="none"><rect id="rect527" class="BoundingBox" x="5999" y="5699" width="1003" height="1003"/><path id="path529" d="m6500 6700h-500v-1e3h1e3v1e3h-500z" stroke="#00f"/></g></g><g id="g531" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id29" fill="none"><rect id="rect534" class="BoundingBox" x="3399" y="5699" width="1003" height="1003"/><path id="path536" d="m3900 6700h-500v-1e3h1e3v1e3h-500z" stroke="#00f"/></g></g><g id="g538" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id30" fill="none"><rect id="rect541" class="BoundingBox" x="5999" y="4499" width="1003" height="1003"/><path id="path543" d="m6500 5500h-500v-1e3h1e3v1e3h-500z" stroke="#0c0"/></g></g><g id="g545"
+class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id31" fill="none"><rect id="rect548" class="BoundingBox" x="7599" y="5799" width="1003" height="1003"/><path id="path550" d="m8100 6800h-500v-1e3h1e3v1e3h-500z" stroke="#0c0"/></g></g><g id="g552" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id32" fill="none"><rect id="rect555" class="BoundingBox" x="10199" y="5799" width="1003" height="1003"/><path id="path557" d="m10700 6800h-500v-1e3h1e3v1e3h-500z" stroke="#0c0"/></g></g><g id="g559" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id33" fill="none"><rect id="rect562" class="BoundingBox" x="8899" y="5799" width="1003" height="1003"/><path id="path564" d="m9400 6800h-500v-1e3h1e3v1e3h-500z" stroke="#00f"/></g></g><g id="g566" class="com.sun.star.drawing.CustomShape"
+transform="translate(-3285.9 -3185.9)"><g id="id34" fill="none"><rect id="rect569" class="BoundingBox" x="10199" y="4499" width="1003" height="1003"/><path id="path571" d="m10700 5500h-500v-1e3h1e3v1e3h-500z" stroke="#f00"/></g></g><g id="g573" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id35" fill="none"><rect id="rect576" class="BoundingBox" x="10199" y="3299" width="1003" height="1003"/><path id="path578" d="m10700 4300h-500v-1e3h1e3v1e3h-500z" stroke="#0c0"/></g></g><g id="g580" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id36" fill="none"><rect id="rect583" class="BoundingBox" x="14399" y="3299" width="1003" height="1003"/><path id="path585" d="m14900 4300h-500v-1e3h1e3v1e3h-500z" stroke="#0c0"/></g></g><g id="g587" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g
+id="id37" fill="none"><rect id="rect590" class="BoundingBox" x="14399" y="5799" width="1003" height="1003"/><path id="path592" d="m14900 6800h-500v-1e3h1e3v1e3h-500z" stroke="#0c0"/></g></g><g id="g594" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id38" fill="none"><rect id="rect597" class="BoundingBox" x="11799" y="5799" width="1003" height="1003"/><path id="path599" d="m12300 6800h-500v-1e3h1e3v1e3h-500z" stroke="#0c0"/></g></g><g id="g601" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id39" fill="none"><rect id="rect604" class="BoundingBox" x="14399" y="4499" width="1003" height="1003"/><path id="path606" d="m14900 5500h-500v-1e3h1e3v1e3h-500z" stroke="#00f"/></g></g><g id="g608" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id40" fill="none"><rect id="rect611"
+class="BoundingBox" x="13099" y="5799" width="1003" height="1003"/><path id="path613" d="m13600 6800h-500v-1e3h1e3v1e3h-500z" stroke="#f00"/></g></g><g id="g615" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id41" fill="none"><rect id="rect618" class="BoundingBox" x="16099" y="5799" width="1003" height="1003"/><path id="path620" d="m16600 6800h-500v-1e3h1e3v1e3h-500z" stroke="#f00"/></g></g><g id="g622" class="com.sun.star.drawing.CustomShape" transform="translate(-3398.8 -3185.9)"><g id="id42" fill="none"><rect id="rect625" class="BoundingBox" x="18799" y="5799" width="1003" height="1003"/><path id="path627" d="m19300 6800h-500v-1e3h1e3v1e3h-500z" stroke="#f00"/></g></g><g id="g629" class="com.sun.star.drawing.CustomShape" transform="translate(-3398.8 -3185.9)"><g id="id43" fill="none"><rect id="rect632" class="BoundingBox" x="18799" y="3299"
+width="1003" height="1003"/><path id="path634" d="m19300 4300h-500v-1e3h1e3v1e3h-500z" stroke="#f00"/></g></g><g id="g636" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id44" fill="none"><rect id="rect639" class="BoundingBox" x="17399" y="5799" width="1003" height="1003"/><path id="path641" d="m17900 6800h-500v-1e3h1e3v1e3h-500z" stroke="#0c0"/></g></g><g id="g643" class="com.sun.star.drawing.CustomShape" transform="translate(-3398.8 -3185.9)"><g id="id45" fill="none"><rect id="rect646" class="BoundingBox" x="18799" y="4499" width="1003" height="1003"/><path id="path648" d="m19300 5500h-500v-1e3h1e3v1e3h-500z" stroke="#0c0"/></g></g></svg>
diff --git a/Documentation/userspace-api/media/v4l/biblio.rst b/Documentation/userspace-api/media/v4l/biblio.rst
new file mode 100644
index 000000000000..3c9634173e82
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/biblio.rst
@@ -0,0 +1,416 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+**********
+References
+**********
+
+
+.. _cea608:
+
+CEA 608-E
+=========
+
+
+:title:     CEA-608-E R-2014 "Line 21 Data Services"
+
+:author:    Consumer Electronics Association (http://www.ce.org)
+
+.. _en300294:
+
+EN 300 294
+==========
+
+
+:title:     EN 300 294 "625-line television Wide Screen Signalling (WSS)"
+
+:author:    European Telecommunication Standards Institute (http://www.etsi.org)
+
+.. _ets300231:
+
+ETS 300 231
+===========
+
+
+:title:     ETS 300 231 "Specification of the domestic video Programme Delivery Control system (PDC)"
+
+:author:    European Telecommunication Standards Institute (http://www.etsi.org)
+
+.. _ets300706:
+
+ETS 300 706
+===========
+
+
+:title:     ETS 300 706 "Enhanced Teletext specification"
+
+:author:    European Telecommunication Standards Institute (http://www.etsi.org)
+
+.. _mpeg2part1:
+
+ISO 13818-1
+===========
+
+
+:title:     ITU-T Rec. H.222.0 | ISO/IEC 13818-1 "Information technology — Generic coding of moving pictures and associated audio information: Systems"
+
+:author:    International Telecommunication Union (http://www.itu.ch), International Organisation for Standardisation (http://www.iso.ch)
+
+.. _mpeg2part2:
+
+ISO 13818-2
+===========
+
+
+:title:     ITU-T Rec. H.262 | ISO/IEC 13818-2 "Information technology — Generic coding of moving pictures and associated audio information: Video"
+
+:author:    International Telecommunication Union (http://www.itu.ch), International Organisation for Standardisation (http://www.iso.ch)
+
+.. _itu470:
+
+ITU BT.470
+==========
+
+
+:title:     ITU-R Recommendation BT.470-6 "Conventional Television Systems"
+
+:author:    International Telecommunication Union (http://www.itu.ch)
+
+.. _itu601:
+
+ITU BT.601
+==========
+
+
+:title:     ITU-R Recommendation BT.601-5 "Studio Encoding Parameters of Digital Television for Standard 4:3 and Wide-Screen 16:9 Aspect Ratios"
+
+:author:    International Telecommunication Union (http://www.itu.ch)
+
+.. _itu653:
+
+ITU BT.653
+==========
+
+
+:title:     ITU-R Recommendation BT.653-3 "Teletext systems"
+
+:author:    International Telecommunication Union (http://www.itu.ch)
+
+.. _itu709:
+
+ITU BT.709
+==========
+
+
+:title:     ITU-R Recommendation BT.709-5 "Parameter values for the HDTV standards for production and international programme exchange"
+
+:author:    International Telecommunication Union (http://www.itu.ch)
+
+.. _itu1119:
+
+ITU BT.1119
+===========
+
+
+:title:     ITU-R Recommendation BT.1119 "625-line television Wide Screen Signalling (WSS)"
+
+:author:    International Telecommunication Union (http://www.itu.ch)
+
+.. _h264:
+
+ITU-T Rec. H.264 Specification (04/2017 Edition)
+================================================
+
+:title:     ITU-T Recommendation H.264 "Advanced Video Coding for Generic Audiovisual Services"
+
+:author:    International Telecommunication Union (http://www.itu.ch)
+
+.. _hevc:
+
+ITU H.265/HEVC
+==============
+
+:title:     ITU-T Rec. H.265 | ISO/IEC 23008-2 "High Efficiency Video Coding"
+
+:author:    International Telecommunication Union (http://www.itu.ch), International Organisation for Standardisation (http://www.iso.ch)
+
+.. _jfif:
+
+JFIF
+====
+
+
+:title:     JPEG File Interchange Format
+:subtitle:  Version 1.02
+
+:author:    Independent JPEG Group (http://www.ijg.org)
+
+.. _itu-t81:
+
+ITU-T.81
+========
+
+
+:title:     ITU-T Recommendation T.81 "Information Technology — Digital Compression and Coding of Continous-Tone Still Images — Requirements and Guidelines"
+
+:author:    International Telecommunication Union (http://www.itu.int)
+
+.. _w3c-jpeg-jfif:
+
+W3C JPEG JFIF
+=============
+
+
+:title:     JPEG JFIF
+
+:author:    The World Wide Web Consortium (http://www.w3.org)
+
+.. _smpte12m:
+
+SMPTE 12M
+=========
+
+
+:title:     SMPTE 12M-1999 "Television, Audio and Film - Time and Control Code"
+
+:author:    Society of Motion Picture and Television Engineers (http://www.smpte.org)
+
+.. _smpte170m:
+
+SMPTE 170M
+==========
+
+
+:title:     SMPTE 170M-1999 "Television - Composite Analog Video Signal - NTSC for Studio Applications"
+
+:author:    Society of Motion Picture and Television Engineers (http://www.smpte.org)
+
+.. _smpte240m:
+
+SMPTE 240M
+==========
+
+
+:title:     SMPTE 240M-1999 "Television - Signal Parameters - 1125-Line High-Definition Production"
+
+:author:    Society of Motion Picture and Television Engineers (http://www.smpte.org)
+
+.. _smpte431:
+
+SMPTE RP 431-2
+==============
+
+
+:title:     SMPTE RP 431-2:2011 "D-Cinema Quality - Reference Projector and Environment"
+
+:author:    Society of Motion Picture and Television Engineers (http://www.smpte.org)
+
+.. _smpte2084:
+
+SMPTE ST 2084
+=============
+
+
+:title:     SMPTE ST 2084:2014 "High Dynamic Range Electro-Optical Transfer Function of Master Reference Displays"
+
+:author:    Society of Motion Picture and Television Engineers (http://www.smpte.org)
+
+.. _srgb:
+
+sRGB
+====
+
+
+:title:     IEC 61966-2-1 ed1.0 "Multimedia systems and equipment - Colour measurement and management - Part 2-1: Colour management - Default RGB colour space - sRGB"
+
+:author:    International Electrotechnical Commission (http://www.iec.ch)
+
+.. _sycc:
+
+sYCC
+====
+
+
+:title:     IEC 61966-2-1-am1 ed1.0 "Amendment 1 - Multimedia systems and equipment - Colour measurement and management - Part 2-1: Colour management - Default RGB colour space - sRGB"
+
+:author:    International Electrotechnical Commission (http://www.iec.ch)
+
+.. _xvycc:
+
+xvYCC
+=====
+
+
+:title:     IEC 61966-2-4 ed1.0 "Multimedia systems and equipment - Colour measurement and management - Part 2-4: Colour management - Extended-gamut YCC colour space for video applications - xvYCC"
+
+:author:    International Electrotechnical Commission (http://www.iec.ch)
+
+.. _oprgb:
+
+opRGB
+=====
+
+
+:title:     IEC 61966-2-5 "Multimedia systems and equipment - Colour measurement and management - Part 2-5: Colour management - Optional RGB colour space - opRGB"
+
+:author:    International Electrotechnical Commission (http://www.iec.ch)
+
+.. _itu2020:
+
+ITU BT.2020
+===========
+
+
+:title:     ITU-R Recommendation BT.2020 (08/2012) "Parameter values for ultra-high definition television systems for production and international programme exchange"
+
+:author:    International Telecommunication Union (http://www.itu.ch)
+
+.. _tech3213:
+
+EBU Tech 3213
+=============
+
+
+:title:     E.B.U. Standard for Chromaticity Tolerances for Studio Monitors"
+
+:author:    European Broadcast Union (http://www.ebu.ch)
+
+.. _iec62106:
+
+IEC 62106
+=========
+
+
+:title:     Specification of the radio data system (RDS) for VHF/FM sound broadcasting in the frequency range from 87,5 to 108,0 MHz
+
+:author:    International Electrotechnical Commission (http://www.iec.ch)
+
+.. _nrsc4:
+
+NRSC-4-B
+========
+
+
+:title:     NRSC-4-B: United States RBDS Standard
+
+:author:    National Radio Systems Committee (http://www.nrscstandards.org)
+
+.. _iso12232:
+
+ISO 12232:2006
+==============
+
+
+:title:     Photography — Digital still cameras — Determination of exposure index, ISO speed ratings, standard output sensitivity, and recommended exposure index
+
+:author:    International Organization for Standardization (http://www.iso.org)
+
+.. _cea861:
+
+CEA-861-E
+=========
+
+
+:title:     A DTV Profile for Uncompressed High Speed Digital Interfaces
+
+:author:    Consumer Electronics Association (http://www.ce.org)
+
+.. _vesadmt:
+
+VESA DMT
+========
+
+
+:title:     VESA and Industry Standards and Guidelines for Computer Display Monitor Timing (DMT)
+
+:author:    Video Electronics Standards Association (http://www.vesa.org)
+
+.. _vesaedid:
+
+EDID
+====
+
+
+:title:     VESA Enhanced Extended Display Identification Data Standard
+:subtitle:  Release A, Revision 2
+
+:author:    Video Electronics Standards Association (http://www.vesa.org)
+
+.. _hdcp:
+
+HDCP
+====
+
+
+:title:     High-bandwidth Digital Content Protection System
+:subtitle:  Revision 1.3
+
+:author:    Digital Content Protection LLC (http://www.digital-cp.com)
+
+.. _hdmi:
+
+HDMI
+====
+
+
+:title:     High-Definition Multimedia Interface
+:subtitle:  Specification Version 1.4a
+
+:author:    HDMI Licensing LLC (http://www.hdmi.org)
+
+.. _hdmi2:
+
+HDMI2
+=====
+
+:title:     High-Definition Multimedia Interface
+:subtitle:  Specification Version 2.0
+
+:author:    HDMI Licensing LLC (http://www.hdmi.org)
+
+.. _dp:
+
+DP
+==
+
+
+:title:     VESA DisplayPort Standard
+:subtitle:  Version 1, Revision 2
+
+:author:    Video Electronics Standards Association (http://www.vesa.org)
+
+.. _poynton:
+
+poynton
+=======
+
+
+:title:     Digital Video and HDTV, Algorithms and Interfaces
+
+:author:    Charles Poynton
+
+.. _colimg:
+
+colimg
+======
+
+
+:title:     Color Imaging: Fundamentals and Applications
+
+:author:    Erik Reinhard et al.
+
+.. _vp8:
+
+VP8
+===
+
+
+:title:     RFC 6386: "VP8 Data Format and Decoding Guide"
+
+:author:    J. Bankoski et al.
diff --git a/Documentation/userspace-api/media/v4l/buffer.rst b/Documentation/userspace-api/media/v4l/buffer.rst
new file mode 100644
index 000000000000..951ae1ed485f
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/buffer.rst
@@ -0,0 +1,817 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _buffer:
+
+*******
+Buffers
+*******
+
+A buffer contains data exchanged by application and driver using one of
+the Streaming I/O methods. In the multi-planar API, the data is held in
+planes, while the buffer structure acts as a container for the planes.
+Only pointers to buffers (planes) are exchanged, the data itself is not
+copied. These pointers, together with meta-information like timestamps
+or field parity, are stored in a struct :c:type:`v4l2_buffer`,
+argument to the :ref:`VIDIOC_QUERYBUF`,
+:ref:`VIDIOC_QBUF <VIDIOC_QBUF>` and
+:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl. In the multi-planar API,
+some plane-specific members of struct :c:type:`v4l2_buffer`,
+such as pointers and sizes for each plane, are stored in struct
+struct :c:type:`v4l2_plane` instead. In that case, struct
+struct :c:type:`v4l2_buffer` contains an array of plane structures.
+
+Dequeued video buffers come with timestamps. The driver decides at which
+part of the frame and with which clock the timestamp is taken. Please
+see flags in the masks ``V4L2_BUF_FLAG_TIMESTAMP_MASK`` and
+``V4L2_BUF_FLAG_TSTAMP_SRC_MASK`` in :ref:`buffer-flags`. These flags
+are always valid and constant across all buffers during the whole video
+stream. Changes in these flags may take place as a side effect of
+:ref:`VIDIOC_S_INPUT <VIDIOC_G_INPUT>` or
+:ref:`VIDIOC_S_OUTPUT <VIDIOC_G_OUTPUT>` however. The
+``V4L2_BUF_FLAG_TIMESTAMP_COPY`` timestamp type which is used by e.g. on
+mem-to-mem devices is an exception to the rule: the timestamp source
+flags are copied from the OUTPUT video buffer to the CAPTURE video
+buffer.
+
+
+Interactions between formats, controls and buffers
+==================================================
+
+V4L2 exposes parameters that influence the buffer size, or the way data is
+laid out in the buffer. Those parameters are exposed through both formats and
+controls. One example of such a control is the ``V4L2_CID_ROTATE`` control
+that modifies the direction in which pixels are stored in the buffer, as well
+as the buffer size when the selected format includes padding at the end of
+lines.
+
+The set of information needed to interpret the content of a buffer (e.g. the
+pixel format, the line stride, the tiling orientation or the rotation) is
+collectively referred to in the rest of this section as the buffer layout.
+
+Controls that can modify the buffer layout shall set the
+``V4L2_CTRL_FLAG_MODIFY_LAYOUT`` flag.
+
+Modifying formats or controls that influence the buffer size or layout require
+the stream to be stopped. Any attempt at such a modification while the stream
+is active shall cause the ioctl setting the format or the control to return
+the ``EBUSY`` error code. In that case drivers shall also set the
+``V4L2_CTRL_FLAG_GRABBED`` flag when calling
+:c:func:`VIDIOC_QUERYCTRL` or :c:func:`VIDIOC_QUERY_EXT_CTRL` for such a
+control while the stream is active.
+
+.. note::
+
+   The :c:func:`VIDIOC_S_SELECTION` ioctl can, depending on the hardware (for
+   instance if the device doesn't include a scaler), modify the format in
+   addition to the selection rectangle. Similarly, the
+   :c:func:`VIDIOC_S_INPUT`, :c:func:`VIDIOC_S_OUTPUT`, :c:func:`VIDIOC_S_STD`
+   and :c:func:`VIDIOC_S_DV_TIMINGS` ioctls can also modify the format and
+   selection rectangles. When those ioctls result in a buffer size or layout
+   change, drivers shall handle that condition as they would handle it in the
+   :c:func:`VIDIOC_S_FMT` ioctl in all cases described in this section.
+
+Controls that only influence the buffer layout can be modified at any time
+when the stream is stopped. As they don't influence the buffer size, no
+special handling is needed to synchronize those controls with buffer
+allocation and the ``V4L2_CTRL_FLAG_GRABBED`` flag is cleared once the
+stream is stopped.
+
+Formats and controls that influence the buffer size interact with buffer
+allocation. The simplest way to handle this is for drivers to always require
+buffers to be reallocated in order to change those formats or controls. In
+that case, to perform such changes, userspace applications shall first stop
+the video stream with the :c:func:`VIDIOC_STREAMOFF` ioctl if it is running
+and free all buffers with the :c:func:`VIDIOC_REQBUFS` ioctl if they are
+allocated. After freeing all buffers the ``V4L2_CTRL_FLAG_GRABBED`` flag
+for controls is cleared. The format or controls can then be modified, and
+buffers shall then be reallocated and the stream restarted. A typical ioctl
+sequence is
+
+ #. VIDIOC_STREAMOFF
+ #. VIDIOC_REQBUFS(0)
+ #. VIDIOC_S_EXT_CTRLS
+ #. VIDIOC_S_FMT
+ #. VIDIOC_REQBUFS(n)
+ #. VIDIOC_QBUF
+ #. VIDIOC_STREAMON
+
+The second :c:func:`VIDIOC_REQBUFS` call will take the new format and control
+value into account to compute the buffer size to allocate. Applications can
+also retrieve the size by calling the :c:func:`VIDIOC_G_FMT` ioctl if needed.
+
+.. note::
+
+   The API doesn't mandate the above order for control (3.) and format (4.)
+   changes. Format and controls can be set in a different order, or even
+   interleaved, depending on the device and use case. For instance some
+   controls might behave differently for different pixel formats, in which
+   case the format might need to be set first.
+
+When reallocation is required, any attempt to modify format or controls that
+influences the buffer size while buffers are allocated shall cause the format
+or control set ioctl to return the ``EBUSY`` error. Any attempt to queue a
+buffer too small for the current format or controls shall cause the
+:c:func:`VIDIOC_QBUF` ioctl to return a ``EINVAL`` error.
+
+Buffer reallocation is an expensive operation. To avoid that cost, drivers can
+(and are encouraged to) allow format or controls that influence the buffer
+size to be changed with buffers allocated. In that case, a typical ioctl
+sequence to modify format and controls is
+
+ #. VIDIOC_STREAMOFF
+ #. VIDIOC_S_EXT_CTRLS
+ #. VIDIOC_S_FMT
+ #. VIDIOC_QBUF
+ #. VIDIOC_STREAMON
+
+For this sequence to operate correctly, queued buffers need to be large enough
+for the new format or controls. Drivers shall return a ``ENOSPC`` error in
+response to format change (:c:func:`VIDIOC_S_FMT`) or control changes
+(:c:func:`VIDIOC_S_CTRL` or :c:func:`VIDIOC_S_EXT_CTRLS`) if buffers too small
+for the new format are currently queued. As a simplification, drivers are
+allowed to return a ``EBUSY`` error from these ioctls if any buffer is
+currently queued, without checking the queued buffers sizes.
+
+Additionally, drivers shall return a ``EINVAL`` error from the
+:c:func:`VIDIOC_QBUF` ioctl if the buffer being queued is too small for the
+current format or controls. Together, these requirements ensure that queued
+buffers will always be large enough for the configured format and controls.
+
+Userspace applications can query the buffer size required for a given format
+and controls by first setting the desired control values and then trying the
+desired format. The :c:func:`VIDIOC_TRY_FMT` ioctl will return the required
+buffer size.
+
+ #. VIDIOC_S_EXT_CTRLS(x)
+ #. VIDIOC_TRY_FMT()
+ #. VIDIOC_S_EXT_CTRLS(y)
+ #. VIDIOC_TRY_FMT()
+
+The :c:func:`VIDIOC_CREATE_BUFS` ioctl can then be used to allocate buffers
+based on the queried sizes (for instance by allocating a set of buffers large
+enough for all the desired formats and controls, or by allocating separate set
+of appropriately sized buffers for each use case).
+
+
+.. c:type:: v4l2_buffer
+
+struct v4l2_buffer
+==================
+
+.. tabularcolumns:: |p{2.8cm}|p{2.5cm}|p{1.6cm}|p{10.2cm}|
+
+.. cssclass:: longtable
+
+.. flat-table:: struct v4l2_buffer
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 2 10
+
+    * - __u32
+      - ``index``
+      - Number of the buffer, set by the application except when calling
+	:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>`, then it is set by the
+	driver. This field can range from zero to the number of buffers
+	allocated with the :ref:`VIDIOC_REQBUFS` ioctl
+	(struct :c:type:`v4l2_requestbuffers`
+	``count``), plus any buffers allocated with
+	:ref:`VIDIOC_CREATE_BUFS` minus one.
+    * - __u32
+      - ``type``
+      - Type of the buffer, same as struct
+	:c:type:`v4l2_format` ``type`` or struct
+	:c:type:`v4l2_requestbuffers` ``type``, set
+	by the application. See :c:type:`v4l2_buf_type`
+    * - __u32
+      - ``bytesused``
+      - The number of bytes occupied by the data in the buffer. It depends
+	on the negotiated data format and may change with each buffer for
+	compressed variable size data like JPEG images. Drivers must set
+	this field when ``type`` refers to a capture stream, applications
+	when it refers to an output stream. If the application sets this
+	to 0 for an output stream, then ``bytesused`` will be set to the
+	size of the buffer (see the ``length`` field of this struct) by
+	the driver. For multiplanar formats this field is ignored and the
+	``planes`` pointer is used instead.
+    * - __u32
+      - ``flags``
+      - Flags set by the application or driver, see :ref:`buffer-flags`.
+    * - __u32
+      - ``field``
+      - Indicates the field order of the image in the buffer, see
+	:c:type:`v4l2_field`. This field is not used when the buffer
+	contains VBI data. Drivers must set it when ``type`` refers to a
+	capture stream, applications when it refers to an output stream.
+    * - struct timeval
+      - ``timestamp``
+      - For capture streams this is time when the first data byte was
+	captured, as returned by the :c:func:`clock_gettime()` function
+	for the relevant clock id; see ``V4L2_BUF_FLAG_TIMESTAMP_*`` in
+	:ref:`buffer-flags`. For output streams the driver stores the
+	time at which the last data byte was actually sent out in the
+	``timestamp`` field. This permits applications to monitor the
+	drift between the video and system clock. For output streams that
+	use ``V4L2_BUF_FLAG_TIMESTAMP_COPY`` the application has to fill
+	in the timestamp which will be copied by the driver to the capture
+	stream.
+    * - struct :c:type:`v4l2_timecode`
+      - ``timecode``
+      - When the ``V4L2_BUF_FLAG_TIMECODE`` flag is set in ``flags``, this
+	structure contains a frame timecode. In
+	:c:type:`V4L2_FIELD_ALTERNATE <v4l2_field>` mode the top and
+	bottom field contain the same timecode. Timecodes are intended to
+	help video editing and are typically recorded on video tapes, but
+	also embedded in compressed formats like MPEG. This field is
+	independent of the ``timestamp`` and ``sequence`` fields.
+    * - __u32
+      - ``sequence``
+      - Set by the driver, counting the frames (not fields!) in sequence.
+	This field is set for both input and output devices.
+    * - :cspan:`2`
+
+	In :c:type:`V4L2_FIELD_ALTERNATE <v4l2_field>` mode the top and
+	bottom field have the same sequence number. The count starts at
+	zero and includes dropped or repeated frames. A dropped frame was
+	received by an input device but could not be stored due to lack of
+	free buffer space. A repeated frame was displayed again by an
+	output device because the application did not pass new data in
+	time.
+
+	.. note::
+
+	   This may count the frames received e.g. over USB, without
+	   taking into account the frames dropped by the remote hardware due
+	   to limited compression throughput or bus bandwidth. These devices
+	   identify by not enumerating any video standards, see
+	   :ref:`standard`.
+
+    * - __u32
+      - ``memory``
+      - This field must be set by applications and/or drivers in
+	accordance with the selected I/O method. See :c:type:`v4l2_memory`
+    * - union {
+      - ``m``
+    * - __u32
+      - ``offset``
+      - For the single-planar API and when ``memory`` is
+	``V4L2_MEMORY_MMAP`` this is the offset of the buffer from the
+	start of the device memory. The value is returned by the driver
+	and apart of serving as parameter to the
+	:ref:`mmap() <func-mmap>` function not useful for applications.
+	See :ref:`mmap` for details
+    * - unsigned long
+      - ``userptr``
+      - For the single-planar API and when ``memory`` is
+	``V4L2_MEMORY_USERPTR`` this is a pointer to the buffer (casted to
+	unsigned long type) in virtual memory, set by the application. See
+	:ref:`userp` for details.
+    * - struct v4l2_plane
+      - ``*planes``
+      - When using the multi-planar API, contains a userspace pointer to
+	an array of struct :c:type:`v4l2_plane`. The size of
+	the array should be put in the ``length`` field of this
+	struct :c:type:`v4l2_buffer` structure.
+    * - int
+      - ``fd``
+      - For the single-plane API and when ``memory`` is
+	``V4L2_MEMORY_DMABUF`` this is the file descriptor associated with
+	a DMABUF buffer.
+    * - }
+      -
+    * - __u32
+      - ``length``
+      - Size of the buffer (not the payload) in bytes for the
+	single-planar API. This is set by the driver based on the calls to
+	:ref:`VIDIOC_REQBUFS` and/or
+	:ref:`VIDIOC_CREATE_BUFS`. For the
+	multi-planar API the application sets this to the number of
+	elements in the ``planes`` array. The driver will fill in the
+	actual number of valid elements in that array.
+    * - __u32
+      - ``reserved2``
+      - A place holder for future extensions. Drivers and applications
+	must set this to 0.
+    * - __u32
+      - ``request_fd``
+      - The file descriptor of the request to queue the buffer to. If the flag
+        ``V4L2_BUF_FLAG_REQUEST_FD`` is set, then the buffer will be
+	queued to this request. If the flag is not set, then this field will
+	be ignored.
+
+	The ``V4L2_BUF_FLAG_REQUEST_FD`` flag and this field are only used by
+	:ref:`ioctl VIDIOC_QBUF <VIDIOC_QBUF>` and ignored by other ioctls that
+	take a :c:type:`v4l2_buffer` as argument.
+
+	Applications should not set ``V4L2_BUF_FLAG_REQUEST_FD`` for any ioctls
+	other than :ref:`VIDIOC_QBUF <VIDIOC_QBUF>`.
+
+	If the device does not support requests, then ``EBADR`` will be returned.
+	If requests are supported but an invalid request file descriptor is
+	given, then ``EINVAL`` will be returned.
+
+
+
+.. c:type:: v4l2_plane
+
+struct v4l2_plane
+=================
+
+.. tabularcolumns:: |p{3.5cm}|p{3.5cm}|p{3.5cm}|p{7.0cm}|
+
+.. cssclass:: longtable
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``bytesused``
+      - The number of bytes occupied by data in the plane (its payload).
+	Drivers must set this field when ``type`` refers to a capture
+	stream, applications when it refers to an output stream. If the
+	application sets this to 0 for an output stream, then
+	``bytesused`` will be set to the size of the plane (see the
+	``length`` field of this struct) by the driver.
+
+	.. note::
+
+	   Note that the actual image data starts at ``data_offset``
+	   which may not be 0.
+    * - __u32
+      - ``length``
+      - Size in bytes of the plane (not its payload). This is set by the
+	driver based on the calls to
+	:ref:`VIDIOC_REQBUFS` and/or
+	:ref:`VIDIOC_CREATE_BUFS`.
+    * - union {
+      - ``m``
+    * - __u32
+      - ``mem_offset``
+      - When the memory type in the containing struct
+	:c:type:`v4l2_buffer` is ``V4L2_MEMORY_MMAP``, this
+	is the value that should be passed to :ref:`mmap() <func-mmap>`,
+	similar to the ``offset`` field in struct
+	:c:type:`v4l2_buffer`.
+    * - unsigned long
+      - ``userptr``
+      - When the memory type in the containing struct
+	:c:type:`v4l2_buffer` is ``V4L2_MEMORY_USERPTR``,
+	this is a userspace pointer to the memory allocated for this plane
+	by an application.
+    * - int
+      - ``fd``
+      - When the memory type in the containing struct
+	:c:type:`v4l2_buffer` is ``V4L2_MEMORY_DMABUF``,
+	this is a file descriptor associated with a DMABUF buffer, similar
+	to the ``fd`` field in struct :c:type:`v4l2_buffer`.
+    * - }
+      -
+    * - __u32
+      - ``data_offset``
+      - Offset in bytes to video data in the plane. Drivers must set this
+	field when ``type`` refers to a capture stream, applications when
+	it refers to an output stream.
+
+	.. note::
+
+	   That data_offset is included  in ``bytesused``. So the
+	   size of the image in the plane is ``bytesused``-``data_offset``
+	   at offset ``data_offset`` from the start of the plane.
+    * - __u32
+      - ``reserved[11]``
+      - Reserved for future use. Should be zeroed by drivers and
+	applications.
+
+
+
+.. c:type:: v4l2_buf_type
+
+enum v4l2_buf_type
+==================
+
+.. cssclass:: longtable
+
+.. tabularcolumns:: |p{7.8cm}|p{0.6cm}|p{9.1cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       4 1 9
+
+    * - ``V4L2_BUF_TYPE_VIDEO_CAPTURE``
+      - 1
+      - Buffer of a single-planar video capture stream, see
+	:ref:`capture`.
+    * - ``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE``
+      - 9
+      - Buffer of a multi-planar video capture stream, see
+	:ref:`capture`.
+    * - ``V4L2_BUF_TYPE_VIDEO_OUTPUT``
+      - 2
+      - Buffer of a single-planar video output stream, see
+	:ref:`output`.
+    * - ``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE``
+      - 10
+      - Buffer of a multi-planar video output stream, see :ref:`output`.
+    * - ``V4L2_BUF_TYPE_VIDEO_OVERLAY``
+      - 3
+      - Buffer for video overlay, see :ref:`overlay`.
+    * - ``V4L2_BUF_TYPE_VBI_CAPTURE``
+      - 4
+      - Buffer of a raw VBI capture stream, see :ref:`raw-vbi`.
+    * - ``V4L2_BUF_TYPE_VBI_OUTPUT``
+      - 5
+      - Buffer of a raw VBI output stream, see :ref:`raw-vbi`.
+    * - ``V4L2_BUF_TYPE_SLICED_VBI_CAPTURE``
+      - 6
+      - Buffer of a sliced VBI capture stream, see :ref:`sliced`.
+    * - ``V4L2_BUF_TYPE_SLICED_VBI_OUTPUT``
+      - 7
+      - Buffer of a sliced VBI output stream, see :ref:`sliced`.
+    * - ``V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY``
+      - 8
+      - Buffer for video output overlay (OSD), see :ref:`osd`.
+    * - ``V4L2_BUF_TYPE_SDR_CAPTURE``
+      - 11
+      - Buffer for Software Defined Radio (SDR) capture stream, see
+	:ref:`sdr`.
+    * - ``V4L2_BUF_TYPE_SDR_OUTPUT``
+      - 12
+      - Buffer for Software Defined Radio (SDR) output stream, see
+	:ref:`sdr`.
+    * - ``V4L2_BUF_TYPE_META_CAPTURE``
+      - 13
+      - Buffer for metadata capture, see :ref:`metadata`.
+    * - ``V4L2_BUF_TYPE_META_OUTPUT``
+      - 14
+      - Buffer for metadata output, see :ref:`metadata`.
+
+
+
+.. _buffer-flags:
+
+Buffer Flags
+============
+
+.. raw:: latex
+
+    \small
+
+.. tabularcolumns:: |p{7.0cm}|p{2.1cm}|p{8.4cm}|
+
+.. cssclass:: longtable
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * .. _`V4L2-BUF-FLAG-MAPPED`:
+
+      - ``V4L2_BUF_FLAG_MAPPED``
+      - 0x00000001
+      - The buffer resides in device memory and has been mapped into the
+	application's address space, see :ref:`mmap` for details.
+	Drivers set or clear this flag when the
+	:ref:`VIDIOC_QUERYBUF`,
+	:ref:`VIDIOC_QBUF` or
+	:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl is called. Set by the
+	driver.
+    * .. _`V4L2-BUF-FLAG-QUEUED`:
+
+      - ``V4L2_BUF_FLAG_QUEUED``
+      - 0x00000002
+      - Internally drivers maintain two buffer queues, an incoming and
+	outgoing queue. When this flag is set, the buffer is currently on
+	the incoming queue. It automatically moves to the outgoing queue
+	after the buffer has been filled (capture devices) or displayed
+	(output devices). Drivers set or clear this flag when the
+	``VIDIOC_QUERYBUF`` ioctl is called. After (successful) calling
+	the ``VIDIOC_QBUF``\ ioctl it is always set and after
+	``VIDIOC_DQBUF`` always cleared.
+    * .. _`V4L2-BUF-FLAG-DONE`:
+
+      - ``V4L2_BUF_FLAG_DONE``
+      - 0x00000004
+      - When this flag is set, the buffer is currently on the outgoing
+	queue, ready to be dequeued from the driver. Drivers set or clear
+	this flag when the ``VIDIOC_QUERYBUF`` ioctl is called. After
+	calling the ``VIDIOC_QBUF`` or ``VIDIOC_DQBUF`` it is always
+	cleared. Of course a buffer cannot be on both queues at the same
+	time, the ``V4L2_BUF_FLAG_QUEUED`` and ``V4L2_BUF_FLAG_DONE`` flag
+	are mutually exclusive. They can be both cleared however, then the
+	buffer is in "dequeued" state, in the application domain so to
+	say.
+    * .. _`V4L2-BUF-FLAG-ERROR`:
+
+      - ``V4L2_BUF_FLAG_ERROR``
+      - 0x00000040
+      - When this flag is set, the buffer has been dequeued successfully,
+	although the data might have been corrupted. This is recoverable,
+	streaming may continue as normal and the buffer may be reused
+	normally. Drivers set this flag when the ``VIDIOC_DQBUF`` ioctl is
+	called.
+    * .. _`V4L2-BUF-FLAG-IN-REQUEST`:
+
+      - ``V4L2_BUF_FLAG_IN_REQUEST``
+      - 0x00000080
+      - This buffer is part of a request that hasn't been queued yet.
+    * .. _`V4L2-BUF-FLAG-KEYFRAME`:
+
+      - ``V4L2_BUF_FLAG_KEYFRAME``
+      - 0x00000008
+      - Drivers set or clear this flag when calling the ``VIDIOC_DQBUF``
+	ioctl. It may be set by video capture devices when the buffer
+	contains a compressed image which is a key frame (or field), i. e.
+	can be decompressed on its own. Also known as an I-frame.
+	Applications can set this bit when ``type`` refers to an output
+	stream.
+    * .. _`V4L2-BUF-FLAG-PFRAME`:
+
+      - ``V4L2_BUF_FLAG_PFRAME``
+      - 0x00000010
+      - Similar to ``V4L2_BUF_FLAG_KEYFRAME`` this flags predicted frames
+	or fields which contain only differences to a previous key frame.
+	Applications can set this bit when ``type`` refers to an output
+	stream.
+    * .. _`V4L2-BUF-FLAG-BFRAME`:
+
+      - ``V4L2_BUF_FLAG_BFRAME``
+      - 0x00000020
+      - Similar to ``V4L2_BUF_FLAG_KEYFRAME`` this flags a bi-directional
+	predicted frame or field which contains only the differences
+	between the current frame and both the preceding and following key
+	frames to specify its content. Applications can set this bit when
+	``type`` refers to an output stream.
+    * .. _`V4L2-BUF-FLAG-TIMECODE`:
+
+      - ``V4L2_BUF_FLAG_TIMECODE``
+      - 0x00000100
+      - The ``timecode`` field is valid. Drivers set or clear this flag
+	when the ``VIDIOC_DQBUF`` ioctl is called. Applications can set
+	this bit and the corresponding ``timecode`` structure when
+	``type`` refers to an output stream.
+    * .. _`V4L2-BUF-FLAG-PREPARED`:
+
+      - ``V4L2_BUF_FLAG_PREPARED``
+      - 0x00000400
+      - The buffer has been prepared for I/O and can be queued by the
+	application. Drivers set or clear this flag when the
+	:ref:`VIDIOC_QUERYBUF`,
+	:ref:`VIDIOC_PREPARE_BUF <VIDIOC_QBUF>`,
+	:ref:`VIDIOC_QBUF` or
+	:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl is called.
+    * .. _`V4L2-BUF-FLAG-NO-CACHE-INVALIDATE`:
+
+      - ``V4L2_BUF_FLAG_NO_CACHE_INVALIDATE``
+      - 0x00000800
+      - Caches do not have to be invalidated for this buffer. Typically
+	applications shall use this flag if the data captured in the
+	buffer is not going to be touched by the CPU, instead the buffer
+	will, probably, be passed on to a DMA-capable hardware unit for
+	further processing or output.
+    * .. _`V4L2-BUF-FLAG-NO-CACHE-CLEAN`:
+
+      - ``V4L2_BUF_FLAG_NO_CACHE_CLEAN``
+      - 0x00001000
+      - Caches do not have to be cleaned for this buffer. Typically
+	applications shall use this flag for output buffers if the data in
+	this buffer has not been created by the CPU but by some
+	DMA-capable unit, in which case caches have not been used.
+    * .. _`V4L2-BUF-FLAG-M2M-HOLD-CAPTURE-BUF`:
+
+      - ``V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF``
+      - 0x00000200
+      - Only valid if ``V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF`` is
+	set. It is typically used with stateless decoders where multiple
+	output buffers each decode to a slice of the decoded frame.
+	Applications can set this flag when queueing the output buffer
+	to prevent the driver from dequeueing the capture buffer after
+	the output buffer has been decoded (i.e. the capture buffer is
+	'held'). If the timestamp of this output buffer differs from that
+	of the previous output buffer, then that indicates the start of a
+	new frame and the previously held capture buffer is dequeued.
+    * .. _`V4L2-BUF-FLAG-LAST`:
+
+      - ``V4L2_BUF_FLAG_LAST``
+      - 0x00100000
+      - Last buffer produced by the hardware. mem2mem codec drivers set
+	this flag on the capture queue for the last buffer when the
+	:ref:`VIDIOC_QUERYBUF` or
+	:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl is called. Due to
+	hardware limitations, the last buffer may be empty. In this case
+	the driver will set the ``bytesused`` field to 0, regardless of
+	the format. Any Any subsequent call to the
+	:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl will not block anymore,
+	but return an ``EPIPE`` error code.
+    * .. _`V4L2-BUF-FLAG-REQUEST-FD`:
+
+      - ``V4L2_BUF_FLAG_REQUEST_FD``
+      - 0x00800000
+      - The ``request_fd`` field contains a valid file descriptor.
+    * .. _`V4L2-BUF-FLAG-TIMESTAMP-MASK`:
+
+      - ``V4L2_BUF_FLAG_TIMESTAMP_MASK``
+      - 0x0000e000
+      - Mask for timestamp types below. To test the timestamp type, mask
+	out bits not belonging to timestamp type by performing a logical
+	and operation with buffer flags and timestamp mask.
+    * .. _`V4L2-BUF-FLAG-TIMESTAMP-UNKNOWN`:
+
+      - ``V4L2_BUF_FLAG_TIMESTAMP_UNKNOWN``
+      - 0x00000000
+      - Unknown timestamp type. This type is used by drivers before Linux
+	3.9 and may be either monotonic (see below) or realtime (wall
+	clock). Monotonic clock has been favoured in embedded systems
+	whereas most of the drivers use the realtime clock. Either kinds
+	of timestamps are available in user space via
+	:c:func:`clock_gettime` using clock IDs ``CLOCK_MONOTONIC``
+	and ``CLOCK_REALTIME``, respectively.
+    * .. _`V4L2-BUF-FLAG-TIMESTAMP-MONOTONIC`:
+
+      - ``V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC``
+      - 0x00002000
+      - The buffer timestamp has been taken from the ``CLOCK_MONOTONIC``
+	clock. To access the same clock outside V4L2, use
+	:c:func:`clock_gettime`.
+    * .. _`V4L2-BUF-FLAG-TIMESTAMP-COPY`:
+
+      - ``V4L2_BUF_FLAG_TIMESTAMP_COPY``
+      - 0x00004000
+      - The CAPTURE buffer timestamp has been taken from the corresponding
+	OUTPUT buffer. This flag applies only to mem2mem devices.
+    * .. _`V4L2-BUF-FLAG-TSTAMP-SRC-MASK`:
+
+      - ``V4L2_BUF_FLAG_TSTAMP_SRC_MASK``
+      - 0x00070000
+      - Mask for timestamp sources below. The timestamp source defines the
+	point of time the timestamp is taken in relation to the frame.
+	Logical 'and' operation between the ``flags`` field and
+	``V4L2_BUF_FLAG_TSTAMP_SRC_MASK`` produces the value of the
+	timestamp source. Applications must set the timestamp source when
+	``type`` refers to an output stream and
+	``V4L2_BUF_FLAG_TIMESTAMP_COPY`` is set.
+    * .. _`V4L2-BUF-FLAG-TSTAMP-SRC-EOF`:
+
+      - ``V4L2_BUF_FLAG_TSTAMP_SRC_EOF``
+      - 0x00000000
+      - End Of Frame. The buffer timestamp has been taken when the last
+	pixel of the frame has been received or the last pixel of the
+	frame has been transmitted. In practice, software generated
+	timestamps will typically be read from the clock a small amount of
+	time after the last pixel has been received or transmitten,
+	depending on the system and other activity in it.
+    * .. _`V4L2-BUF-FLAG-TSTAMP-SRC-SOE`:
+
+      - ``V4L2_BUF_FLAG_TSTAMP_SRC_SOE``
+      - 0x00010000
+      - Start Of Exposure. The buffer timestamp has been taken when the
+	exposure of the frame has begun. This is only valid for the
+	``V4L2_BUF_TYPE_VIDEO_CAPTURE`` buffer type.
+
+.. raw:: latex
+
+    \normalsize
+
+
+.. c:type:: v4l2_memory
+
+enum v4l2_memory
+================
+
+.. tabularcolumns:: |p{5.0cm}|p{0.8cm}|p{11.7cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_MEMORY_MMAP``
+      - 1
+      - The buffer is used for :ref:`memory mapping <mmap>` I/O.
+    * - ``V4L2_MEMORY_USERPTR``
+      - 2
+      - The buffer is used for :ref:`user pointer <userp>` I/O.
+    * - ``V4L2_MEMORY_OVERLAY``
+      - 3
+      - [to do]
+    * - ``V4L2_MEMORY_DMABUF``
+      - 4
+      - The buffer is used for :ref:`DMA shared buffer <dmabuf>` I/O.
+
+
+
+Timecodes
+=========
+
+The :c:type:`v4l2_buffer_timecode` structure is designed to hold a
+:ref:`smpte12m` or similar timecode.
+(struct :c:type:`timeval` timestamps are stored in the struct
+:c:type:`v4l2_buffer` ``timestamp`` field.)
+
+
+.. c:type:: v4l2_timecode
+
+struct v4l2_timecode
+--------------------
+
+.. tabularcolumns:: |p{1.4cm}|p{2.8cm}|p{12.3cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``type``
+      - Frame rate the timecodes are based on, see :ref:`timecode-type`.
+    * - __u32
+      - ``flags``
+      - Timecode flags, see :ref:`timecode-flags`.
+    * - __u8
+      - ``frames``
+      - Frame count, 0 ... 23/24/29/49/59, depending on the type of
+	timecode.
+    * - __u8
+      - ``seconds``
+      - Seconds count, 0 ... 59. This is a binary, not BCD number.
+    * - __u8
+      - ``minutes``
+      - Minutes count, 0 ... 59. This is a binary, not BCD number.
+    * - __u8
+      - ``hours``
+      - Hours count, 0 ... 29. This is a binary, not BCD number.
+    * - __u8
+      - ``userbits``\ [4]
+      - The "user group" bits from the timecode.
+
+
+
+.. _timecode-type:
+
+Timecode Types
+--------------
+
+.. tabularcolumns:: |p{5.6cm}|p{0.8cm}|p{11.1cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_TC_TYPE_24FPS``
+      - 1
+      - 24 frames per second, i. e. film.
+    * - ``V4L2_TC_TYPE_25FPS``
+      - 2
+      - 25 frames per second, i. e. PAL or SECAM video.
+    * - ``V4L2_TC_TYPE_30FPS``
+      - 3
+      - 30 frames per second, i. e. NTSC video.
+    * - ``V4L2_TC_TYPE_50FPS``
+      - 4
+      -
+    * - ``V4L2_TC_TYPE_60FPS``
+      - 5
+      -
+
+
+
+.. _timecode-flags:
+
+Timecode Flags
+--------------
+
+.. tabularcolumns:: |p{6.6cm}|p{1.4cm}|p{9.5cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_TC_FLAG_DROPFRAME``
+      - 0x0001
+      - Indicates "drop frame" semantics for counting frames in 29.97 fps
+	material. When set, frame numbers 0 and 1 at the start of each
+	minute, except minutes 0, 10, 20, 30, 40, 50 are omitted from the
+	count.
+    * - ``V4L2_TC_FLAG_COLORFRAME``
+      - 0x0002
+      - The "color frame" flag.
+    * - ``V4L2_TC_USERBITS_field``
+      - 0x000C
+      - Field mask for the "binary group flags".
+    * - ``V4L2_TC_USERBITS_USERDEFINED``
+      - 0x0000
+      - Unspecified format.
+    * - ``V4L2_TC_USERBITS_8BITCHARS``
+      - 0x0008
+      - 8-bit ISO characters.
diff --git a/Documentation/userspace-api/media/v4l/capture-example.rst b/Documentation/userspace-api/media/v4l/capture-example.rst
new file mode 100644
index 000000000000..6aa67c5aff8f
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/capture-example.rst
@@ -0,0 +1,20 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _capture-example:
+
+*********************
+Video Capture Example
+*********************
+
+
+.. toctree::
+    :maxdepth: 1
+
+    capture.c
diff --git a/Documentation/userspace-api/media/v4l/capture.c.rst b/Documentation/userspace-api/media/v4l/capture.c.rst
new file mode 100644
index 000000000000..30f7c816e858
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/capture.c.rst
@@ -0,0 +1,671 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+file: media/v4l/capture.c
+=========================
+
+.. code-block:: c
+
+    /*
+     *  V4L2 video capture example
+     *
+     *  This program can be used and distributed without restrictions.
+     *
+     *      This program is provided with the V4L2 API
+     * see https://linuxtv.org/docs.php for more information
+     */
+
+    #include <stdio.h>
+    #include <stdlib.h>
+    #include <string.h>
+    #include <assert.h>
+
+    #include <getopt.h>             /* getopt_long() */
+
+    #include <fcntl.h>              /* low-level i/o */
+    #include <unistd.h>
+    #include <errno.h>
+    #include <sys/stat.h>
+    #include <sys/types.h>
+    #include <sys/time.h>
+    #include <sys/mman.h>
+    #include <sys/ioctl.h>
+
+    #include <linux/videodev2.h>
+
+    #define CLEAR(x) memset(&(x), 0, sizeof(x))
+
+    enum io_method {
+	    IO_METHOD_READ,
+	    IO_METHOD_MMAP,
+	    IO_METHOD_USERPTR,
+    };
+
+    struct buffer {
+	    void   *start;
+	    size_t  length;
+    };
+
+    static char            *dev_name;
+    static enum io_method   io = IO_METHOD_MMAP;
+    static int              fd = -1;
+    struct buffer          *buffers;
+    static unsigned int     n_buffers;
+    static int              out_buf;
+    static int              force_format;
+    static int              frame_count = 70;
+
+    static void errno_exit(const char *s)
+    {
+	    fprintf(stderr, "%s error %d, %s\\n", s, errno, strerror(errno));
+	    exit(EXIT_FAILURE);
+    }
+
+    static int xioctl(int fh, int request, void *arg)
+    {
+	    int r;
+
+	    do {
+		    r = ioctl(fh, request, arg);
+	    } while (-1 == r && EINTR == errno);
+
+	    return r;
+    }
+
+    static void process_image(const void *p, int size)
+    {
+	    if (out_buf)
+		    fwrite(p, size, 1, stdout);
+
+	    fflush(stderr);
+	    fprintf(stderr, ".");
+	    fflush(stdout);
+    }
+
+    static int read_frame(void)
+    {
+	    struct v4l2_buffer buf;
+	    unsigned int i;
+
+	    switch (io) {
+	    case IO_METHOD_READ:
+		    if (-1 == read(fd, buffers[0].start, buffers[0].length)) {
+			    switch (errno) {
+			    case EAGAIN:
+				    return 0;
+
+			    case EIO:
+				    /* Could ignore EIO, see spec. */
+
+				    /* fall through */
+
+			    default:
+				    errno_exit("read");
+			    }
+		    }
+
+		    process_image(buffers[0].start, buffers[0].length);
+		    break;
+
+	    case IO_METHOD_MMAP:
+		    CLEAR(buf);
+
+		    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		    buf.memory = V4L2_MEMORY_MMAP;
+
+		    if (-1 == xioctl(fd, VIDIOC_DQBUF, &buf)) {
+			    switch (errno) {
+			    case EAGAIN:
+				    return 0;
+
+			    case EIO:
+				    /* Could ignore EIO, see spec. */
+
+				    /* fall through */
+
+			    default:
+				    errno_exit("VIDIOC_DQBUF");
+			    }
+		    }
+
+		    assert(buf.index < n_buffers);
+
+		    process_image(buffers[buf.index].start, buf.bytesused);
+
+		    if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))
+			    errno_exit("VIDIOC_QBUF");
+		    break;
+
+	    case IO_METHOD_USERPTR:
+		    CLEAR(buf);
+
+		    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		    buf.memory = V4L2_MEMORY_USERPTR;
+
+		    if (-1 == xioctl(fd, VIDIOC_DQBUF, &buf)) {
+			    switch (errno) {
+			    case EAGAIN:
+				    return 0;
+
+			    case EIO:
+				    /* Could ignore EIO, see spec. */
+
+				    /* fall through */
+
+			    default:
+				    errno_exit("VIDIOC_DQBUF");
+			    }
+		    }
+
+		    for (i = 0; i < n_buffers; ++i)
+			    if (buf.m.userptr == (unsigned long)buffers[i].start
+				&& buf.length == buffers[i].length)
+				    break;
+
+		    assert(i < n_buffers);
+
+		    process_image((void *)buf.m.userptr, buf.bytesused);
+
+		    if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))
+			    errno_exit("VIDIOC_QBUF");
+		    break;
+	    }
+
+	    return 1;
+    }
+
+    static void mainloop(void)
+    {
+	    unsigned int count;
+
+	    count = frame_count;
+
+	    while (count-- > 0) {
+		    for (;;) {
+			    fd_set fds;
+			    struct timeval tv;
+			    int r;
+
+			    FD_ZERO(&fds);
+			    FD_SET(fd, &fds);
+
+			    /* Timeout. */
+			    tv.tv_sec = 2;
+			    tv.tv_usec = 0;
+
+			    r = select(fd + 1, &fds, NULL, NULL, &tv);
+
+			    if (-1 == r) {
+				    if (EINTR == errno)
+					    continue;
+				    errno_exit("select");
+			    }
+
+			    if (0 == r) {
+				    fprintf(stderr, "select timeout\\n");
+				    exit(EXIT_FAILURE);
+			    }
+
+			    if (read_frame())
+				    break;
+			    /* EAGAIN - continue select loop. */
+		    }
+	    }
+    }
+
+    static void stop_capturing(void)
+    {
+	    enum v4l2_buf_type type;
+
+	    switch (io) {
+	    case IO_METHOD_READ:
+		    /* Nothing to do. */
+		    break;
+
+	    case IO_METHOD_MMAP:
+	    case IO_METHOD_USERPTR:
+		    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		    if (-1 == xioctl(fd, VIDIOC_STREAMOFF, &type))
+			    errno_exit("VIDIOC_STREAMOFF");
+		    break;
+	    }
+    }
+
+    static void start_capturing(void)
+    {
+	    unsigned int i;
+	    enum v4l2_buf_type type;
+
+	    switch (io) {
+	    case IO_METHOD_READ:
+		    /* Nothing to do. */
+		    break;
+
+	    case IO_METHOD_MMAP:
+		    for (i = 0; i < n_buffers; ++i) {
+			    struct v4l2_buffer buf;
+
+			    CLEAR(buf);
+			    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+			    buf.memory = V4L2_MEMORY_MMAP;
+			    buf.index = i;
+
+			    if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))
+				    errno_exit("VIDIOC_QBUF");
+		    }
+		    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		    if (-1 == xioctl(fd, VIDIOC_STREAMON, &type))
+			    errno_exit("VIDIOC_STREAMON");
+		    break;
+
+	    case IO_METHOD_USERPTR:
+		    for (i = 0; i < n_buffers; ++i) {
+			    struct v4l2_buffer buf;
+
+			    CLEAR(buf);
+			    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+			    buf.memory = V4L2_MEMORY_USERPTR;
+			    buf.index = i;
+			    buf.m.userptr = (unsigned long)buffers[i].start;
+			    buf.length = buffers[i].length;
+
+			    if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))
+				    errno_exit("VIDIOC_QBUF");
+		    }
+		    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		    if (-1 == xioctl(fd, VIDIOC_STREAMON, &type))
+			    errno_exit("VIDIOC_STREAMON");
+		    break;
+	    }
+    }
+
+    static void uninit_device(void)
+    {
+	    unsigned int i;
+
+	    switch (io) {
+	    case IO_METHOD_READ:
+		    free(buffers[0].start);
+		    break;
+
+	    case IO_METHOD_MMAP:
+		    for (i = 0; i < n_buffers; ++i)
+			    if (-1 == munmap(buffers[i].start, buffers[i].length))
+				    errno_exit("munmap");
+		    break;
+
+	    case IO_METHOD_USERPTR:
+		    for (i = 0; i < n_buffers; ++i)
+			    free(buffers[i].start);
+		    break;
+	    }
+
+	    free(buffers);
+    }
+
+    static void init_read(unsigned int buffer_size)
+    {
+	    buffers = calloc(1, sizeof(*buffers));
+
+	    if (!buffers) {
+		    fprintf(stderr, "Out of memory\\n");
+		    exit(EXIT_FAILURE);
+	    }
+
+	    buffers[0].length = buffer_size;
+	    buffers[0].start = malloc(buffer_size);
+
+	    if (!buffers[0].start) {
+		    fprintf(stderr, "Out of memory\\n");
+		    exit(EXIT_FAILURE);
+	    }
+    }
+
+    static void init_mmap(void)
+    {
+	    struct v4l2_requestbuffers req;
+
+	    CLEAR(req);
+
+	    req.count = 4;
+	    req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	    req.memory = V4L2_MEMORY_MMAP;
+
+	    if (-1 == xioctl(fd, VIDIOC_REQBUFS, &req)) {
+		    if (EINVAL == errno) {
+			    fprintf(stderr, "%s does not support "
+				     "memory mappingn", dev_name);
+			    exit(EXIT_FAILURE);
+		    } else {
+			    errno_exit("VIDIOC_REQBUFS");
+		    }
+	    }
+
+	    if (req.count < 2) {
+		    fprintf(stderr, "Insufficient buffer memory on %s\\n",
+			     dev_name);
+		    exit(EXIT_FAILURE);
+	    }
+
+	    buffers = calloc(req.count, sizeof(*buffers));
+
+	    if (!buffers) {
+		    fprintf(stderr, "Out of memory\\n");
+		    exit(EXIT_FAILURE);
+	    }
+
+	    for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {
+		    struct v4l2_buffer buf;
+
+		    CLEAR(buf);
+
+		    buf.type        = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		    buf.memory      = V4L2_MEMORY_MMAP;
+		    buf.index       = n_buffers;
+
+		    if (-1 == xioctl(fd, VIDIOC_QUERYBUF, &buf))
+			    errno_exit("VIDIOC_QUERYBUF");
+
+		    buffers[n_buffers].length = buf.length;
+		    buffers[n_buffers].start =
+			    mmap(NULL /* start anywhere */,
+				  buf.length,
+				  PROT_READ | PROT_WRITE /* required */,
+				  MAP_SHARED /* recommended */,
+				  fd, buf.m.offset);
+
+		    if (MAP_FAILED == buffers[n_buffers].start)
+			    errno_exit("mmap");
+	    }
+    }
+
+    static void init_userp(unsigned int buffer_size)
+    {
+	    struct v4l2_requestbuffers req;
+
+	    CLEAR(req);
+
+	    req.count  = 4;
+	    req.type   = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	    req.memory = V4L2_MEMORY_USERPTR;
+
+	    if (-1 == xioctl(fd, VIDIOC_REQBUFS, &req)) {
+		    if (EINVAL == errno) {
+			    fprintf(stderr, "%s does not support "
+				     "user pointer i/on", dev_name);
+			    exit(EXIT_FAILURE);
+		    } else {
+			    errno_exit("VIDIOC_REQBUFS");
+		    }
+	    }
+
+	    buffers = calloc(4, sizeof(*buffers));
+
+	    if (!buffers) {
+		    fprintf(stderr, "Out of memory\\n");
+		    exit(EXIT_FAILURE);
+	    }
+
+	    for (n_buffers = 0; n_buffers < 4; ++n_buffers) {
+		    buffers[n_buffers].length = buffer_size;
+		    buffers[n_buffers].start = malloc(buffer_size);
+
+		    if (!buffers[n_buffers].start) {
+			    fprintf(stderr, "Out of memory\\n");
+			    exit(EXIT_FAILURE);
+		    }
+	    }
+    }
+
+    static void init_device(void)
+    {
+	    struct v4l2_capability cap;
+	    struct v4l2_cropcap cropcap;
+	    struct v4l2_crop crop;
+	    struct v4l2_format fmt;
+	    unsigned int min;
+
+	    if (-1 == xioctl(fd, VIDIOC_QUERYCAP, &cap)) {
+		    if (EINVAL == errno) {
+			    fprintf(stderr, "%s is no V4L2 device\\n",
+				     dev_name);
+			    exit(EXIT_FAILURE);
+		    } else {
+			    errno_exit("VIDIOC_QUERYCAP");
+		    }
+	    }
+
+	    if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
+		    fprintf(stderr, "%s is no video capture device\\n",
+			     dev_name);
+		    exit(EXIT_FAILURE);
+	    }
+
+	    switch (io) {
+	    case IO_METHOD_READ:
+		    if (!(cap.capabilities & V4L2_CAP_READWRITE)) {
+			    fprintf(stderr, "%s does not support read i/o\\n",
+				     dev_name);
+			    exit(EXIT_FAILURE);
+		    }
+		    break;
+
+	    case IO_METHOD_MMAP:
+	    case IO_METHOD_USERPTR:
+		    if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
+			    fprintf(stderr, "%s does not support streaming i/o\\n",
+				     dev_name);
+			    exit(EXIT_FAILURE);
+		    }
+		    break;
+	    }
+
+
+	    /* Select video input, video standard and tune here. */
+
+
+	    CLEAR(cropcap);
+
+	    cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+	    if (0 == xioctl(fd, VIDIOC_CROPCAP, &cropcap)) {
+		    crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		    crop.c = cropcap.defrect; /* reset to default */
+
+		    if (-1 == xioctl(fd, VIDIOC_S_CROP, &crop)) {
+			    switch (errno) {
+			    case EINVAL:
+				    /* Cropping not supported. */
+				    break;
+			    default:
+				    /* Errors ignored. */
+				    break;
+			    }
+		    }
+	    } else {
+		    /* Errors ignored. */
+	    }
+
+
+	    CLEAR(fmt);
+
+	    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	    if (force_format) {
+		    fmt.fmt.pix.width       = 640;
+		    fmt.fmt.pix.height      = 480;
+		    fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
+		    fmt.fmt.pix.field       = V4L2_FIELD_INTERLACED;
+
+		    if (-1 == xioctl(fd, VIDIOC_S_FMT, &fmt))
+			    errno_exit("VIDIOC_S_FMT");
+
+		    /* Note VIDIOC_S_FMT may change width and height. */
+	    } else {
+		    /* Preserve original settings as set by v4l2-ctl for example */
+		    if (-1 == xioctl(fd, VIDIOC_G_FMT, &fmt))
+			    errno_exit("VIDIOC_G_FMT");
+	    }
+
+	    /* Buggy driver paranoia. */
+	    min = fmt.fmt.pix.width * 2;
+	    if (fmt.fmt.pix.bytesperline < min)
+		    fmt.fmt.pix.bytesperline = min;
+	    min = fmt.fmt.pix.bytesperline * fmt.fmt.pix.height;
+	    if (fmt.fmt.pix.sizeimage < min)
+		    fmt.fmt.pix.sizeimage = min;
+
+	    switch (io) {
+	    case IO_METHOD_READ:
+		    init_read(fmt.fmt.pix.sizeimage);
+		    break;
+
+	    case IO_METHOD_MMAP:
+		    init_mmap();
+		    break;
+
+	    case IO_METHOD_USERPTR:
+		    init_userp(fmt.fmt.pix.sizeimage);
+		    break;
+	    }
+    }
+
+    static void close_device(void)
+    {
+	    if (-1 == close(fd))
+		    errno_exit("close");
+
+	    fd = -1;
+    }
+
+    static void open_device(void)
+    {
+	    struct stat st;
+
+	    if (-1 == stat(dev_name, &st)) {
+		    fprintf(stderr, "Cannot identify '%s': %d, %s\\n",
+			     dev_name, errno, strerror(errno));
+		    exit(EXIT_FAILURE);
+	    }
+
+	    if (!S_ISCHR(st.st_mode)) {
+		    fprintf(stderr, "%s is no devicen", dev_name);
+		    exit(EXIT_FAILURE);
+	    }
+
+	    fd = open(dev_name, O_RDWR /* required */ | O_NONBLOCK, 0);
+
+	    if (-1 == fd) {
+		    fprintf(stderr, "Cannot open '%s': %d, %s\\n",
+			     dev_name, errno, strerror(errno));
+		    exit(EXIT_FAILURE);
+	    }
+    }
+
+    static void usage(FILE *fp, int argc, char **argv)
+    {
+	    fprintf(fp,
+		     "Usage: %s [options]\\n\\n"
+		     "Version 1.3\\n"
+		     "Options:\\n"
+		     "-d | --device name   Video device name [%s]n"
+		     "-h | --help          Print this messagen"
+		     "-m | --mmap          Use memory mapped buffers [default]n"
+		     "-r | --read          Use read() callsn"
+		     "-u | --userp         Use application allocated buffersn"
+		     "-o | --output        Outputs stream to stdoutn"
+		     "-f | --format        Force format to 640x480 YUYVn"
+		     "-c | --count         Number of frames to grab [%i]n"
+		     "",
+		     argv[0], dev_name, frame_count);
+    }
+
+    static const char short_options[] = "d:hmruofc:";
+
+    static const struct option
+    long_options[] = {
+	    { "device", required_argument, NULL, 'd' },
+	    { "help",   no_argument,       NULL, 'h' },
+	    { "mmap",   no_argument,       NULL, 'm' },
+	    { "read",   no_argument,       NULL, 'r' },
+	    { "userp",  no_argument,       NULL, 'u' },
+	    { "output", no_argument,       NULL, 'o' },
+	    { "format", no_argument,       NULL, 'f' },
+	    { "count",  required_argument, NULL, 'c' },
+	    { 0, 0, 0, 0 }
+    };
+
+    int main(int argc, char **argv)
+    {
+	    dev_name = "/dev/video0";
+
+	    for (;;) {
+		    int idx;
+		    int c;
+
+		    c = getopt_long(argc, argv,
+				    short_options, long_options, &idx);
+
+		    if (-1 == c)
+			    break;
+
+		    switch (c) {
+		    case 0: /* getopt_long() flag */
+			    break;
+
+		    case 'd':
+			    dev_name = optarg;
+			    break;
+
+		    case 'h':
+			    usage(stdout, argc, argv);
+			    exit(EXIT_SUCCESS);
+
+		    case 'm':
+			    io = IO_METHOD_MMAP;
+			    break;
+
+		    case 'r':
+			    io = IO_METHOD_READ;
+			    break;
+
+		    case 'u':
+			    io = IO_METHOD_USERPTR;
+			    break;
+
+		    case 'o':
+			    out_buf++;
+			    break;
+
+		    case 'f':
+			    force_format++;
+			    break;
+
+		    case 'c':
+			    errno = 0;
+			    frame_count = strtol(optarg, NULL, 0);
+			    if (errno)
+				    errno_exit(optarg);
+			    break;
+
+		    default:
+			    usage(stderr, argc, argv);
+			    exit(EXIT_FAILURE);
+		    }
+	    }
+
+	    open_device();
+	    init_device();
+	    start_capturing();
+	    mainloop();
+	    stop_capturing();
+	    uninit_device();
+	    close_device();
+	    fprintf(stderr, "\\n");
+	    return 0;
+    }
diff --git a/Documentation/userspace-api/media/v4l/colorspaces-defs.rst b/Documentation/userspace-api/media/v4l/colorspaces-defs.rst
new file mode 100644
index 000000000000..01404e1f609a
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/colorspaces-defs.rst
@@ -0,0 +1,183 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+****************************
+Defining Colorspaces in V4L2
+****************************
+
+In V4L2 colorspaces are defined by four values. The first is the
+colorspace identifier (enum :c:type:`v4l2_colorspace`)
+which defines the chromaticities, the default transfer function, the
+default Y'CbCr encoding and the default quantization method. The second
+is the transfer function identifier (enum
+:c:type:`v4l2_xfer_func`) to specify non-standard
+transfer functions. The third is the Y'CbCr encoding identifier (enum
+:c:type:`v4l2_ycbcr_encoding`) to specify
+non-standard Y'CbCr encodings and the fourth is the quantization
+identifier (enum :c:type:`v4l2_quantization`) to
+specify non-standard quantization methods. Most of the time only the
+colorspace field of struct :c:type:`v4l2_pix_format`
+or struct :c:type:`v4l2_pix_format_mplane`
+needs to be filled in.
+
+.. _hsv-colorspace:
+
+On :ref:`HSV formats <hsv-formats>` the *Hue* is defined as the angle on
+the cylindrical color representation. Usually this angle is measured in
+degrees, i.e. 0-360. When we map this angle value into 8 bits, there are
+two basic ways to do it: Divide the angular value by 2 (0-179), or use the
+whole range, 0-255, dividing the angular value by 1.41. The enum
+:c:type:`v4l2_hsv_encoding` specifies which encoding is used.
+
+.. note:: The default R'G'B' quantization is full range for all
+   colorspaces except for BT.2020 which uses limited range R'G'B'
+   quantization.
+
+.. tabularcolumns:: |p{6.7cm}|p{10.8cm}|
+
+.. c:type:: v4l2_colorspace
+
+.. flat-table:: V4L2 Colorspaces
+    :header-rows:  1
+    :stub-columns: 0
+
+    * - Identifier
+      - Details
+    * - ``V4L2_COLORSPACE_DEFAULT``
+      - The default colorspace. This can be used by applications to let
+	the driver fill in the colorspace.
+    * - ``V4L2_COLORSPACE_SMPTE170M``
+      - See :ref:`col-smpte-170m`.
+    * - ``V4L2_COLORSPACE_REC709``
+      - See :ref:`col-rec709`.
+    * - ``V4L2_COLORSPACE_SRGB``
+      - See :ref:`col-srgb`.
+    * - ``V4L2_COLORSPACE_OPRGB``
+      - See :ref:`col-oprgb`.
+    * - ``V4L2_COLORSPACE_BT2020``
+      - See :ref:`col-bt2020`.
+    * - ``V4L2_COLORSPACE_DCI_P3``
+      - See :ref:`col-dcip3`.
+    * - ``V4L2_COLORSPACE_SMPTE240M``
+      - See :ref:`col-smpte-240m`.
+    * - ``V4L2_COLORSPACE_470_SYSTEM_M``
+      - See :ref:`col-sysm`.
+    * - ``V4L2_COLORSPACE_470_SYSTEM_BG``
+      - See :ref:`col-sysbg`.
+    * - ``V4L2_COLORSPACE_JPEG``
+      - See :ref:`col-jpeg`.
+    * - ``V4L2_COLORSPACE_RAW``
+      - The raw colorspace. This is used for raw image capture where the
+	image is minimally processed and is using the internal colorspace
+	of the device. The software that processes an image using this
+	'colorspace' will have to know the internals of the capture
+	device.
+
+
+
+.. c:type:: v4l2_xfer_func
+
+.. tabularcolumns:: |p{5.5cm}|p{12.0cm}|
+
+.. flat-table:: V4L2 Transfer Function
+    :header-rows:  1
+    :stub-columns: 0
+
+    * - Identifier
+      - Details
+    * - ``V4L2_XFER_FUNC_DEFAULT``
+      - Use the default transfer function as defined by the colorspace.
+    * - ``V4L2_XFER_FUNC_709``
+      - Use the Rec. 709 transfer function.
+    * - ``V4L2_XFER_FUNC_SRGB``
+      - Use the sRGB transfer function.
+    * - ``V4L2_XFER_FUNC_OPRGB``
+      - Use the opRGB transfer function.
+    * - ``V4L2_XFER_FUNC_SMPTE240M``
+      - Use the SMPTE 240M transfer function.
+    * - ``V4L2_XFER_FUNC_NONE``
+      - Do not use a transfer function (i.e. use linear RGB values).
+    * - ``V4L2_XFER_FUNC_DCI_P3``
+      - Use the DCI-P3 transfer function.
+    * - ``V4L2_XFER_FUNC_SMPTE2084``
+      - Use the SMPTE 2084 transfer function. See :ref:`xf-smpte-2084`.
+
+
+
+.. c:type:: v4l2_ycbcr_encoding
+
+.. tabularcolumns:: |p{7.2cm}|p{10.3cm}|
+
+.. flat-table:: V4L2 Y'CbCr Encodings
+    :header-rows:  1
+    :stub-columns: 0
+
+    * - Identifier
+      - Details
+    * - ``V4L2_YCBCR_ENC_DEFAULT``
+      - Use the default Y'CbCr encoding as defined by the colorspace.
+    * - ``V4L2_YCBCR_ENC_601``
+      - Use the BT.601 Y'CbCr encoding.
+    * - ``V4L2_YCBCR_ENC_709``
+      - Use the Rec. 709 Y'CbCr encoding.
+    * - ``V4L2_YCBCR_ENC_XV601``
+      - Use the extended gamut xvYCC BT.601 encoding.
+    * - ``V4L2_YCBCR_ENC_XV709``
+      - Use the extended gamut xvYCC Rec. 709 encoding.
+    * - ``V4L2_YCBCR_ENC_BT2020``
+      - Use the default non-constant luminance BT.2020 Y'CbCr encoding.
+    * - ``V4L2_YCBCR_ENC_BT2020_CONST_LUM``
+      - Use the constant luminance BT.2020 Yc'CbcCrc encoding.
+    * - ``V4L2_YCBCR_ENC_SMPTE_240M``
+      - Use the SMPTE 240M Y'CbCr encoding.
+
+
+
+.. c:type:: v4l2_hsv_encoding
+
+.. tabularcolumns:: |p{6.5cm}|p{11.0cm}|
+
+.. flat-table:: V4L2 HSV Encodings
+    :header-rows:  1
+    :stub-columns: 0
+
+    * - Identifier
+      - Details
+    * - ``V4L2_HSV_ENC_180``
+      - For the Hue, each LSB is two degrees.
+    * - ``V4L2_HSV_ENC_256``
+      - For the Hue, the 360 degrees are mapped into 8 bits, i.e. each
+	LSB is roughly 1.41 degrees.
+
+
+
+.. c:type:: v4l2_quantization
+
+.. tabularcolumns:: |p{6.5cm}|p{11.0cm}|
+
+.. flat-table:: V4L2 Quantization Methods
+    :header-rows:  1
+    :stub-columns: 0
+
+    * - Identifier
+      - Details
+    * - ``V4L2_QUANTIZATION_DEFAULT``
+      - Use the default quantization encoding as defined by the
+	colorspace. This is always full range for R'G'B' (except for the
+	BT.2020 colorspace) and HSV. It is usually limited range for Y'CbCr.
+    * - ``V4L2_QUANTIZATION_FULL_RANGE``
+      - Use the full range quantization encoding. I.e. the range [0…1] is
+	mapped to [0…255] (with possible clipping to [1…254] to avoid the
+	0x00 and 0xff values). Cb and Cr are mapped from [-0.5…0.5] to
+	[0…255] (with possible clipping to [1…254] to avoid the 0x00 and
+	0xff values).
+    * - ``V4L2_QUANTIZATION_LIM_RANGE``
+      - Use the limited range quantization encoding. I.e. the range [0…1]
+	is mapped to [16…235]. Cb and Cr are mapped from [-0.5…0.5] to
+	[16…240].
diff --git a/Documentation/userspace-api/media/v4l/colorspaces-details.rst b/Documentation/userspace-api/media/v4l/colorspaces-details.rst
new file mode 100644
index 000000000000..79ed6f4f76eb
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/colorspaces-details.rst
@@ -0,0 +1,813 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+********************************
+Detailed Colorspace Descriptions
+********************************
+
+
+.. _col-smpte-170m:
+
+Colorspace SMPTE 170M (V4L2_COLORSPACE_SMPTE170M)
+=================================================
+
+The :ref:`smpte170m` standard defines the colorspace used by NTSC and
+PAL and by SDTV in general. The default transfer function is
+``V4L2_XFER_FUNC_709``. The default Y'CbCr encoding is
+``V4L2_YCBCR_ENC_601``. The default Y'CbCr quantization is limited
+range. The chromaticities of the primary colors and the white reference
+are:
+
+
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. flat-table:: SMPTE 170M Chromaticities
+    :header-rows:  1
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - Color
+      - x
+      - y
+    * - Red
+      - 0.630
+      - 0.340
+    * - Green
+      - 0.310
+      - 0.595
+    * - Blue
+      - 0.155
+      - 0.070
+    * - White Reference (D65)
+      - 0.3127
+      - 0.3290
+
+
+The red, green and blue chromaticities are also often referred to as the
+SMPTE C set, so this colorspace is sometimes called SMPTE C as well.
+
+The transfer function defined for SMPTE 170M is the same as the one
+defined in Rec. 709.
+
+.. math::
+
+    L' = -1.099(-L)^{0.45} + 0.099 \text{, for } L \le-0.018
+
+    L' = 4.5L \text{, for } -0.018 < L < 0.018
+
+    L' = 1.099L^{0.45} - 0.099 \text{, for } L \ge 0.018
+
+Inverse Transfer function:
+
+.. math::
+
+    L = -\left( \frac{L' - 0.099}{-1.099} \right) ^{\frac{1}{0.45}} \text{, for } L' \le -0.081
+
+    L = \frac{L'}{4.5} \text{, for } -0.081 < L' < 0.081
+
+    L = \left(\frac{L' + 0.099}{1.099}\right)^{\frac{1}{0.45} } \text{, for } L' \ge 0.081
+
+The luminance (Y') and color difference (Cb and Cr) are obtained with
+the following ``V4L2_YCBCR_ENC_601`` encoding:
+
+.. math::
+
+    Y' = 0.2990R' + 0.5870G' + 0.1140B'
+
+    Cb = -0.1687R' - 0.3313G' + 0.5B'
+
+    Cr = 0.5R' - 0.4187G' - 0.0813B'
+
+Y' is clamped to the range [0…1] and Cb and Cr are clamped to the range
+[-0.5…0.5]. This conversion to Y'CbCr is identical to the one defined in
+the :ref:`itu601` standard and this colorspace is sometimes called
+BT.601 as well, even though BT.601 does not mention any color primaries.
+
+The default quantization is limited range, but full range is possible
+although rarely seen.
+
+
+.. _col-rec709:
+
+Colorspace Rec. 709 (V4L2_COLORSPACE_REC709)
+============================================
+
+The :ref:`itu709` standard defines the colorspace used by HDTV in
+general. The default transfer function is ``V4L2_XFER_FUNC_709``. The
+default Y'CbCr encoding is ``V4L2_YCBCR_ENC_709``. The default Y'CbCr
+quantization is limited range. The chromaticities of the primary colors
+and the white reference are:
+
+
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. flat-table:: Rec. 709 Chromaticities
+    :header-rows:  1
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - Color
+      - x
+      - y
+    * - Red
+      - 0.640
+      - 0.330
+    * - Green
+      - 0.300
+      - 0.600
+    * - Blue
+      - 0.150
+      - 0.060
+    * - White Reference (D65)
+      - 0.3127
+      - 0.3290
+
+
+The full name of this standard is Rec. ITU-R BT.709-5.
+
+Transfer function. Normally L is in the range [0…1], but for the
+extended gamut xvYCC encoding values outside that range are allowed.
+
+.. math::
+
+    L' = -1.099(-L)^{0.45} + 0.099 \text{, for } L \le -0.018
+
+    L' = 4.5L \text{, for } -0.018 < L < 0.018
+
+    L' = 1.099L^{0.45} - 0.099 \text{, for } L \ge 0.018
+
+Inverse Transfer function:
+
+.. math::
+
+    L = -\left( \frac{L' - 0.099}{-1.099} \right)^\frac{1}{0.45} \text{, for } L' \le -0.081
+
+    L = \frac{L'}{4.5}\text{, for } -0.081 < L' < 0.081
+
+    L = \left(\frac{L' + 0.099}{1.099}\right)^{\frac{1}{0.45} } \text{, for } L' \ge 0.081
+
+The luminance (Y') and color difference (Cb and Cr) are obtained with
+the following ``V4L2_YCBCR_ENC_709`` encoding:
+
+.. math::
+
+    Y' = 0.2126R' + 0.7152G' + 0.0722B'
+
+    Cb = -0.1146R' - 0.3854G' + 0.5B'
+
+    Cr = 0.5R' - 0.4542G' - 0.0458B'
+
+Y' is clamped to the range [0…1] and Cb and Cr are clamped to the range
+[-0.5…0.5].
+
+The default quantization is limited range, but full range is possible
+although rarely seen.
+
+The ``V4L2_YCBCR_ENC_709`` encoding described above is the default for
+this colorspace, but it can be overridden with ``V4L2_YCBCR_ENC_601``,
+in which case the BT.601 Y'CbCr encoding is used.
+
+Two additional extended gamut Y'CbCr encodings are also possible with
+this colorspace:
+
+The xvYCC 709 encoding (``V4L2_YCBCR_ENC_XV709``, :ref:`xvycc`) is
+similar to the Rec. 709 encoding, but it allows for R', G' and B' values
+that are outside the range [0…1]. The resulting Y', Cb and Cr values are
+scaled and offset according to the limited range formula:
+
+.. math::
+
+    Y' = \frac{219}{256} * (0.2126R' + 0.7152G' + 0.0722B') + \frac{16}{256}
+
+    Cb = \frac{224}{256} * (-0.1146R' - 0.3854G' + 0.5B')
+
+    Cr = \frac{224}{256} * (0.5R' - 0.4542G' - 0.0458B')
+
+The xvYCC 601 encoding (``V4L2_YCBCR_ENC_XV601``, :ref:`xvycc`) is
+similar to the BT.601 encoding, but it allows for R', G' and B' values
+that are outside the range [0…1]. The resulting Y', Cb and Cr values are
+scaled and offset according to the limited range formula:
+
+.. math::
+
+    Y' = \frac{219}{256} * (0.2990R' + 0.5870G' + 0.1140B') + \frac{16}{256}
+
+    Cb = \frac{224}{256} * (-0.1687R' - 0.3313G' + 0.5B')
+
+    Cr = \frac{224}{256} * (0.5R' - 0.4187G' - 0.0813B')
+
+Y' is clamped to the range [0…1] and Cb and Cr are clamped to the range
+[-0.5…0.5] and quantized without further scaling or offsets.
+The non-standard xvYCC 709 or xvYCC 601 encodings can be
+used by selecting ``V4L2_YCBCR_ENC_XV709`` or ``V4L2_YCBCR_ENC_XV601``.
+As seen by the xvYCC formulas these encodings always use limited range quantization,
+there is no full range variant. The whole point of these extended gamut encodings
+is that values outside the limited range are still valid, although they
+map to R', G' and B' values outside the [0…1] range and are therefore outside
+the Rec. 709 colorspace gamut.
+
+
+.. _col-srgb:
+
+Colorspace sRGB (V4L2_COLORSPACE_SRGB)
+======================================
+
+The :ref:`srgb` standard defines the colorspace used by most webcams
+and computer graphics. The default transfer function is
+``V4L2_XFER_FUNC_SRGB``. The default Y'CbCr encoding is
+``V4L2_YCBCR_ENC_601``. The default Y'CbCr quantization is limited range.
+
+Note that the :ref:`sycc` standard specifies full range quantization,
+however all current capture hardware supported by the kernel convert
+R'G'B' to limited range Y'CbCr. So choosing full range as the default
+would break how applications interpret the quantization range.
+
+The chromaticities of the primary colors and the white reference are:
+
+
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. flat-table:: sRGB Chromaticities
+    :header-rows:  1
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - Color
+      - x
+      - y
+    * - Red
+      - 0.640
+      - 0.330
+    * - Green
+      - 0.300
+      - 0.600
+    * - Blue
+      - 0.150
+      - 0.060
+    * - White Reference (D65)
+      - 0.3127
+      - 0.3290
+
+
+These chromaticities are identical to the Rec. 709 colorspace.
+
+Transfer function. Note that negative values for L are only used by the
+Y'CbCr conversion.
+
+.. math::
+
+    L' = -1.055(-L)^{\frac{1}{2.4} } + 0.055\text{, for }L < -0.0031308
+
+    L' = 12.92L\text{, for }-0.0031308 \le L \le 0.0031308
+
+    L' = 1.055L ^{\frac{1}{2.4} } - 0.055\text{, for }0.0031308 < L \le 1
+
+Inverse Transfer function:
+
+.. math::
+
+    L = -((-L' + 0.055) / 1.055) ^{2.4}\text{, for }L' < -0.04045
+
+    L = L' / 12.92\text{, for }-0.04045 \le L' \le 0.04045
+
+    L = ((L' + 0.055) / 1.055) ^{2.4}\text{, for }L' > 0.04045
+
+The luminance (Y') and color difference (Cb and Cr) are obtained with
+the following ``V4L2_YCBCR_ENC_601`` encoding as defined by :ref:`sycc`:
+
+.. math::
+
+    Y' = 0.2990R' + 0.5870G' + 0.1140B'
+
+    Cb = -0.1687R' - 0.3313G' + 0.5B'
+
+    Cr = 0.5R' - 0.4187G' - 0.0813B'
+
+Y' is clamped to the range [0…1] and Cb and Cr are clamped to the range
+[-0.5…0.5]. This transform is identical to one defined in SMPTE
+170M/BT.601. The Y'CbCr quantization is limited range.
+
+
+.. _col-oprgb:
+
+Colorspace opRGB (V4L2_COLORSPACE_OPRGB)
+===============================================
+
+The :ref:`oprgb` standard defines the colorspace used by computer
+graphics that use the opRGB colorspace. The default transfer function is
+``V4L2_XFER_FUNC_OPRGB``. The default Y'CbCr encoding is
+``V4L2_YCBCR_ENC_601``. The default Y'CbCr quantization is limited
+range.
+
+Note that the :ref:`oprgb` standard specifies full range quantization,
+however all current capture hardware supported by the kernel convert
+R'G'B' to limited range Y'CbCr. So choosing full range as the default
+would break how applications interpret the quantization range.
+
+The chromaticities of the primary colors and the white reference are:
+
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. flat-table:: opRGB Chromaticities
+    :header-rows:  1
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - Color
+      - x
+      - y
+    * - Red
+      - 0.6400
+      - 0.3300
+    * - Green
+      - 0.2100
+      - 0.7100
+    * - Blue
+      - 0.1500
+      - 0.0600
+    * - White Reference (D65)
+      - 0.3127
+      - 0.3290
+
+
+
+Transfer function:
+
+.. math::
+
+    L' = L ^{\frac{1}{2.19921875}}
+
+Inverse Transfer function:
+
+.. math::
+
+    L = L'^{(2.19921875)}
+
+The luminance (Y') and color difference (Cb and Cr) are obtained with
+the following ``V4L2_YCBCR_ENC_601`` encoding:
+
+.. math::
+
+    Y' = 0.2990R' + 0.5870G' + 0.1140B'
+
+    Cb = -0.1687R' - 0.3313G' + 0.5B'
+
+    Cr = 0.5R' - 0.4187G' - 0.0813B'
+
+Y' is clamped to the range [0…1] and Cb and Cr are clamped to the range
+[-0.5…0.5]. This transform is identical to one defined in SMPTE
+170M/BT.601. The Y'CbCr quantization is limited range.
+
+
+.. _col-bt2020:
+
+Colorspace BT.2020 (V4L2_COLORSPACE_BT2020)
+===========================================
+
+The :ref:`itu2020` standard defines the colorspace used by Ultra-high
+definition television (UHDTV). The default transfer function is
+``V4L2_XFER_FUNC_709``. The default Y'CbCr encoding is
+``V4L2_YCBCR_ENC_BT2020``. The default R'G'B' quantization is limited
+range (!), and so is the default Y'CbCr quantization. The chromaticities
+of the primary colors and the white reference are:
+
+
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. flat-table:: BT.2020 Chromaticities
+    :header-rows:  1
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - Color
+      - x
+      - y
+    * - Red
+      - 0.708
+      - 0.292
+    * - Green
+      - 0.170
+      - 0.797
+    * - Blue
+      - 0.131
+      - 0.046
+    * - White Reference (D65)
+      - 0.3127
+      - 0.3290
+
+
+
+Transfer function (same as Rec. 709):
+
+.. math::
+
+    L' = 4.5L\text{, for }0 \le L < 0.018
+
+    L' = 1.099L ^{0.45} - 0.099\text{, for } 0.018 \le L \le 1
+
+Inverse Transfer function:
+
+.. math::
+
+    L = L' / 4.5\text{, for } L' < 0.081
+
+    L = \left( \frac{L' + 0.099}{1.099}\right) ^{\frac{1}{0.45} }\text{, for } L' \ge 0.081
+
+Please note that while Rec. 709 is defined as the default transfer function
+by the :ref:`itu2020` standard, in practice this colorspace is often used
+with the :ref:`xf-smpte-2084`. In particular Ultra HD Blu-ray discs use
+this combination.
+
+The luminance (Y') and color difference (Cb and Cr) are obtained with
+the following ``V4L2_YCBCR_ENC_BT2020`` encoding:
+
+.. math::
+
+    Y' = 0.2627R' + 0.6780G' + 0.0593B'
+
+    Cb = -0.1396R' - 0.3604G' + 0.5B'
+
+    Cr = 0.5R' - 0.4598G' - 0.0402B'
+
+Y' is clamped to the range [0…1] and Cb and Cr are clamped to the range
+[-0.5…0.5]. The Y'CbCr quantization is limited range.
+
+There is also an alternate constant luminance R'G'B' to Yc'CbcCrc
+(``V4L2_YCBCR_ENC_BT2020_CONST_LUM``) encoding:
+
+Luma:
+
+.. math::
+    :nowrap:
+
+    \begin{align*}
+    Yc' = (0.2627R + 0.6780G + 0.0593B)'& \\
+    B' - Yc' \le 0:& \\
+        &Cbc = (B' - Yc') / 1.9404 \\
+    B' - Yc' > 0: & \\
+        &Cbc = (B' - Yc') / 1.5816 \\
+    R' - Yc' \le 0:& \\
+        &Crc = (R' - Y') / 1.7184 \\
+    R' - Yc' > 0:& \\
+        &Crc = (R' - Y') / 0.9936
+    \end{align*}
+
+Yc' is clamped to the range [0…1] and Cbc and Crc are clamped to the
+range [-0.5…0.5]. The Yc'CbcCrc quantization is limited range.
+
+
+.. _col-dcip3:
+
+Colorspace DCI-P3 (V4L2_COLORSPACE_DCI_P3)
+==========================================
+
+The :ref:`smpte431` standard defines the colorspace used by cinema
+projectors that use the DCI-P3 colorspace. The default transfer function
+is ``V4L2_XFER_FUNC_DCI_P3``. The default Y'CbCr encoding is
+``V4L2_YCBCR_ENC_709``. The default Y'CbCr quantization is limited range.
+
+.. note::
+
+   Note that this colorspace standard does not specify a
+   Y'CbCr encoding since it is not meant to be encoded to Y'CbCr. So this
+   default Y'CbCr encoding was picked because it is the HDTV encoding.
+
+The chromaticities of the primary colors and the white reference are:
+
+
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. flat-table:: DCI-P3 Chromaticities
+    :header-rows:  1
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - Color
+      - x
+      - y
+    * - Red
+      - 0.6800
+      - 0.3200
+    * - Green
+      - 0.2650
+      - 0.6900
+    * - Blue
+      - 0.1500
+      - 0.0600
+    * - White Reference
+      - 0.3140
+      - 0.3510
+
+
+
+Transfer function:
+
+.. math::
+
+    L' = L^{\frac{1}{2.6}}
+
+Inverse Transfer function:
+
+.. math::
+
+    L = L'^{(2.6)}
+
+Y'CbCr encoding is not specified. V4L2 defaults to Rec. 709.
+
+
+.. _col-smpte-240m:
+
+Colorspace SMPTE 240M (V4L2_COLORSPACE_SMPTE240M)
+=================================================
+
+The :ref:`smpte240m` standard was an interim standard used during the
+early days of HDTV (1988-1998). It has been superseded by Rec. 709. The
+default transfer function is ``V4L2_XFER_FUNC_SMPTE240M``. The default
+Y'CbCr encoding is ``V4L2_YCBCR_ENC_SMPTE240M``. The default Y'CbCr
+quantization is limited range. The chromaticities of the primary colors
+and the white reference are:
+
+
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. flat-table:: SMPTE 240M Chromaticities
+    :header-rows:  1
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - Color
+      - x
+      - y
+    * - Red
+      - 0.630
+      - 0.340
+    * - Green
+      - 0.310
+      - 0.595
+    * - Blue
+      - 0.155
+      - 0.070
+    * - White Reference (D65)
+      - 0.3127
+      - 0.3290
+
+
+These chromaticities are identical to the SMPTE 170M colorspace.
+
+Transfer function:
+
+.. math::
+
+    L' = 4L\text{, for } 0 \le L < 0.0228
+
+    L' = 1.1115L ^{0.45} - 0.1115\text{, for } 0.0228 \le L \le 1
+
+Inverse Transfer function:
+
+.. math::
+
+    L = \frac{L'}{4}\text{, for } 0 \le L' < 0.0913
+
+    L = \left( \frac{L' + 0.1115}{1.1115}\right) ^{\frac{1}{0.45} }\text{, for } L' \ge 0.0913
+
+The luminance (Y') and color difference (Cb and Cr) are obtained with
+the following ``V4L2_YCBCR_ENC_SMPTE240M`` encoding:
+
+.. math::
+
+    Y' = 0.2122R' + 0.7013G' + 0.0865B'
+
+    Cb = -0.1161R' - 0.3839G' + 0.5B'
+
+    Cr = 0.5R' - 0.4451G' - 0.0549B'
+
+Y' is clamped to the range [0…1] and Cb and Cr are clamped to the
+range [-0.5…0.5]. The Y'CbCr quantization is limited range.
+
+
+.. _col-sysm:
+
+Colorspace NTSC 1953 (V4L2_COLORSPACE_470_SYSTEM_M)
+===================================================
+
+This standard defines the colorspace used by NTSC in 1953. In practice
+this colorspace is obsolete and SMPTE 170M should be used instead. The
+default transfer function is ``V4L2_XFER_FUNC_709``. The default Y'CbCr
+encoding is ``V4L2_YCBCR_ENC_601``. The default Y'CbCr quantization is
+limited range. The chromaticities of the primary colors and the white
+reference are:
+
+
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. flat-table:: NTSC 1953 Chromaticities
+    :header-rows:  1
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - Color
+      - x
+      - y
+    * - Red
+      - 0.67
+      - 0.33
+    * - Green
+      - 0.21
+      - 0.71
+    * - Blue
+      - 0.14
+      - 0.08
+    * - White Reference (C)
+      - 0.310
+      - 0.316
+
+
+.. note::
+
+   This colorspace uses Illuminant C instead of D65 as the white
+   reference. To correctly convert an image in this colorspace to another
+   that uses D65 you need to apply a chromatic adaptation algorithm such as
+   the Bradford method.
+
+The transfer function was never properly defined for NTSC 1953. The Rec.
+709 transfer function is recommended in the literature:
+
+.. math::
+
+    L' = 4.5L\text{, for } 0 \le L < 0.018
+
+    L' = 1.099L ^{0.45} - 0.099\text{, for } 0.018 \le L \le 1
+
+Inverse Transfer function:
+
+.. math::
+
+    L = \frac{L'}{4.5} \text{, for } L' < 0.081
+
+    L = \left( \frac{L' + 0.099}{1.099}\right) ^{\frac{1}{0.45} }\text{, for } L' \ge 0.081
+
+The luminance (Y') and color difference (Cb and Cr) are obtained with
+the following ``V4L2_YCBCR_ENC_601`` encoding:
+
+.. math::
+
+    Y' = 0.2990R' + 0.5870G' + 0.1140B'
+
+    Cb = -0.1687R' - 0.3313G' + 0.5B'
+
+    Cr = 0.5R' - 0.4187G' - 0.0813B'
+
+Y' is clamped to the range [0…1] and Cb and Cr are clamped to the range
+[-0.5…0.5]. The Y'CbCr quantization is limited range. This transform is
+identical to one defined in SMPTE 170M/BT.601.
+
+
+.. _col-sysbg:
+
+Colorspace EBU Tech. 3213 (V4L2_COLORSPACE_470_SYSTEM_BG)
+=========================================================
+
+The :ref:`tech3213` standard defines the colorspace used by PAL/SECAM
+in 1975. In practice this colorspace is obsolete and SMPTE 170M should
+be used instead. The default transfer function is
+``V4L2_XFER_FUNC_709``. The default Y'CbCr encoding is
+``V4L2_YCBCR_ENC_601``. The default Y'CbCr quantization is limited
+range. The chromaticities of the primary colors and the white reference
+are:
+
+
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. flat-table:: EBU Tech. 3213 Chromaticities
+    :header-rows:  1
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - Color
+      - x
+      - y
+    * - Red
+      - 0.64
+      - 0.33
+    * - Green
+      - 0.29
+      - 0.60
+    * - Blue
+      - 0.15
+      - 0.06
+    * - White Reference (D65)
+      - 0.3127
+      - 0.3290
+
+
+
+The transfer function was never properly defined for this colorspace.
+The Rec. 709 transfer function is recommended in the literature:
+
+.. math::
+
+    L' = 4.5L\text{, for } 0 \le L < 0.018
+
+    L' = 1.099L ^{0.45} - 0.099\text{, for } 0.018 \le L \le 1
+
+Inverse Transfer function:
+
+.. math::
+
+    L = \frac{L'}{4.5} \text{, for } L' < 0.081
+
+    L = \left(\frac{L' + 0.099}{1.099} \right) ^{\frac{1}{0.45} }\text{, for } L' \ge 0.081
+
+The luminance (Y') and color difference (Cb and Cr) are obtained with
+the following ``V4L2_YCBCR_ENC_601`` encoding:
+
+.. math::
+
+    Y' = 0.2990R' + 0.5870G' + 0.1140B'
+
+    Cb = -0.1687R' - 0.3313G' + 0.5B'
+
+    Cr = 0.5R' - 0.4187G' - 0.0813B'
+
+Y' is clamped to the range [0…1] and Cb and Cr are clamped to the range
+[-0.5…0.5]. The Y'CbCr quantization is limited range. This transform is
+identical to one defined in SMPTE 170M/BT.601.
+
+
+.. _col-jpeg:
+
+Colorspace JPEG (V4L2_COLORSPACE_JPEG)
+======================================
+
+This colorspace defines the colorspace used by most (Motion-)JPEG
+formats. The chromaticities of the primary colors and the white
+reference are identical to sRGB. The transfer function use is
+``V4L2_XFER_FUNC_SRGB``. The Y'CbCr encoding is ``V4L2_YCBCR_ENC_601``
+with full range quantization where Y' is scaled to [0…255] and Cb/Cr are
+scaled to [-128…128] and then clipped to [-128…127].
+
+.. note::
+
+   The JPEG standard does not actually store colorspace
+   information. So if something other than sRGB is used, then the driver
+   will have to set that information explicitly. Effectively
+   ``V4L2_COLORSPACE_JPEG`` can be considered to be an abbreviation for
+   ``V4L2_COLORSPACE_SRGB``, ``V4L2_YCBCR_ENC_601`` and
+   ``V4L2_QUANTIZATION_FULL_RANGE``.
+
+***************************************
+Detailed Transfer Function Descriptions
+***************************************
+
+.. _xf-smpte-2084:
+
+Transfer Function SMPTE 2084 (V4L2_XFER_FUNC_SMPTE2084)
+=======================================================
+
+The :ref:`smpte2084` standard defines the transfer function used by
+High Dynamic Range content.
+
+Constants:
+    m1 = (2610 / 4096) / 4
+
+    m2 = (2523 / 4096) * 128
+
+    c1 = 3424 / 4096
+
+    c2 = (2413 / 4096) * 32
+
+    c3 = (2392 / 4096) * 32
+
+Transfer function:
+    L' = ((c1 + c2 * L\ :sup:`m1`) / (1 + c3 * L\ :sup:`m1`))\ :sup:`m2`
+
+Inverse Transfer function:
+    L = (max(L':sup:`1/m2` - c1, 0) / (c2 - c3 *
+    L'\ :sup:`1/m2`))\ :sup:`1/m1`
+
+Take care when converting between this transfer function and non-HDR transfer
+functions: the linear RGB values [0…1] of HDR content map to a luminance range
+of 0 to 10000 cd/m\ :sup:`2` whereas the linear RGB values of non-HDR (aka
+Standard Dynamic Range or SDR) map to a luminance range of 0 to 100 cd/m\ :sup:`2`.
+
+To go from SDR to HDR you will have to divide L by 100 first. To go in the other
+direction you will have to multiply L by 100. Of course, this clamps all
+luminance values over 100 cd/m\ :sup:`2` to 100 cd/m\ :sup:`2`.
+
+There are better methods, see e.g. :ref:`colimg` for more in-depth information
+about this.
diff --git a/Documentation/userspace-api/media/v4l/colorspaces.rst b/Documentation/userspace-api/media/v4l/colorspaces.rst
new file mode 100644
index 000000000000..0846df9066c5
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/colorspaces.rst
@@ -0,0 +1,170 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _colorspaces:
+
+***********
+Colorspaces
+***********
+
+'Color' is a very complex concept and depends on physics, chemistry and
+biology. Just because you have three numbers that describe the 'red',
+'green' and 'blue' components of the color of a pixel does not mean that
+you can accurately display that color. A colorspace defines what it
+actually *means* to have an RGB value of e.g. (255, 0, 0). That is,
+which color should be reproduced on the screen in a perfectly calibrated
+environment.
+
+In order to do that we first need to have a good definition of color,
+i.e. some way to uniquely and unambiguously define a color so that
+someone else can reproduce it. Human color vision is trichromatic since
+the human eye has color receptors that are sensitive to three different
+wavelengths of light. Hence the need to use three numbers to describe
+color. Be glad you are not a mantis shrimp as those are sensitive to 12
+different wavelengths, so instead of RGB we would be using the
+ABCDEFGHIJKL colorspace...
+
+Color exists only in the eye and brain and is the result of how strongly
+color receptors are stimulated. This is based on the Spectral Power
+Distribution (SPD) which is a graph showing the intensity (radiant
+power) of the light at wavelengths covering the visible spectrum as it
+enters the eye. The science of colorimetry is about the relationship
+between the SPD and color as perceived by the human brain.
+
+Since the human eye has only three color receptors it is perfectly
+possible that different SPDs will result in the same stimulation of
+those receptors and are perceived as the same color, even though the SPD
+of the light is different.
+
+In the 1920s experiments were devised to determine the relationship
+between SPDs and the perceived color and that resulted in the CIE 1931
+standard that defines spectral weighting functions that model the
+perception of color. Specifically that standard defines functions that
+can take an SPD and calculate the stimulus for each color receptor.
+After some further mathematical transforms these stimuli are known as
+the *CIE XYZ tristimulus* values and these X, Y and Z values describe a
+color as perceived by a human unambiguously. These X, Y and Z values are
+all in the range [0…1].
+
+The Y value in the CIE XYZ colorspace corresponds to luminance. Often
+the CIE XYZ colorspace is transformed to the normalized CIE xyY
+colorspace:
+
+	x = X / (X + Y + Z)
+
+	y = Y / (X + Y + Z)
+
+The x and y values are the chromaticity coordinates and can be used to
+define a color without the luminance component Y. It is very confusing
+to have such similar names for these colorspaces. Just be aware that if
+colors are specified with lower case 'x' and 'y', then the CIE xyY
+colorspace is used. Upper case 'X' and 'Y' refer to the CIE XYZ
+colorspace. Also, y has nothing to do with luminance. Together x and y
+specify a color, and Y the luminance. That is really all you need to
+remember from a practical point of view. At the end of this section you
+will find reading resources that go into much more detail if you are
+interested.
+
+A monitor or TV will reproduce colors by emitting light at three
+different wavelengths, the combination of which will stimulate the color
+receptors in the eye and thus cause the perception of color.
+Historically these wavelengths were defined by the red, green and blue
+phosphors used in the displays. These *color primaries* are part of what
+defines a colorspace.
+
+Different display devices will have different primaries and some
+primaries are more suitable for some display technologies than others.
+This has resulted in a variety of colorspaces that are used for
+different display technologies or uses. To define a colorspace you need
+to define the three color primaries (these are typically defined as x, y
+chromaticity coordinates from the CIE xyY colorspace) but also the white
+reference: that is the color obtained when all three primaries are at
+maximum power. This determines the relative power or energy of the
+primaries. This is usually chosen to be close to daylight which has been
+defined as the CIE D65 Illuminant.
+
+To recapitulate: the CIE XYZ colorspace uniquely identifies colors.
+Other colorspaces are defined by three chromaticity coordinates defined
+in the CIE xyY colorspace. Based on those a 3x3 matrix can be
+constructed that transforms CIE XYZ colors to colors in the new
+colorspace.
+
+Both the CIE XYZ and the RGB colorspace that are derived from the
+specific chromaticity primaries are linear colorspaces. But neither the
+eye, nor display technology is linear. Doubling the values of all
+components in the linear colorspace will not be perceived as twice the
+intensity of the color. So each colorspace also defines a transfer
+function that takes a linear color component value and transforms it to
+the non-linear component value, which is a closer match to the
+non-linear performance of both the eye and displays. Linear component
+values are denoted RGB, non-linear are denoted as R'G'B'. In general
+colors used in graphics are all R'G'B', except in openGL which uses
+linear RGB. Special care should be taken when dealing with openGL to
+provide linear RGB colors or to use the built-in openGL support to apply
+the inverse transfer function.
+
+The final piece that defines a colorspace is a function that transforms
+non-linear R'G'B' to non-linear Y'CbCr. This function is determined by
+the so-called luma coefficients. There may be multiple possible Y'CbCr
+encodings allowed for the same colorspace. Many encodings of color
+prefer to use luma (Y') and chroma (CbCr) instead of R'G'B'. Since the
+human eye is more sensitive to differences in luminance than in color
+this encoding allows one to reduce the amount of color information
+compared to the luma data. Note that the luma (Y') is unrelated to the Y
+in the CIE XYZ colorspace. Also note that Y'CbCr is often called YCbCr
+or YUV even though these are strictly speaking wrong.
+
+Sometimes people confuse Y'CbCr as being a colorspace. This is not
+correct, it is just an encoding of an R'G'B' color into luma and chroma
+values. The underlying colorspace that is associated with the R'G'B'
+color is also associated with the Y'CbCr color.
+
+The final step is how the RGB, R'G'B' or Y'CbCr values are quantized.
+The CIE XYZ colorspace where X, Y and Z are in the range [0…1] describes
+all colors that humans can perceive, but the transform to another
+colorspace will produce colors that are outside the [0…1] range. Once
+clamped to the [0…1] range those colors can no longer be reproduced in
+that colorspace. This clamping is what reduces the extent or gamut of
+the colorspace. How the range of [0…1] is translated to integer values
+in the range of [0…255] (or higher, depending on the color depth) is
+called the quantization. This is *not* part of the colorspace
+definition. In practice RGB or R'G'B' values are full range, i.e. they
+use the full [0…255] range. Y'CbCr values on the other hand are limited
+range with Y' using [16…235] and Cb and Cr using [16…240].
+
+Unfortunately, in some cases limited range RGB is also used where the
+components use the range [16…235]. And full range Y'CbCr also exists
+using the [0…255] range.
+
+In order to correctly interpret a color you need to know the
+quantization range, whether it is R'G'B' or Y'CbCr, the used Y'CbCr
+encoding and the colorspace. From that information you can calculate the
+corresponding CIE XYZ color and map that again to whatever colorspace
+your display device uses.
+
+The colorspace definition itself consists of the three chromaticity
+primaries, the white reference chromaticity, a transfer function and the
+luma coefficients needed to transform R'G'B' to Y'CbCr. While some
+colorspace standards correctly define all four, quite often the
+colorspace standard only defines some, and you have to rely on other
+standards for the missing pieces. The fact that colorspaces are often a
+mix of different standards also led to very confusing naming conventions
+where the name of a standard was used to name a colorspace when in fact
+that standard was part of various other colorspaces as well.
+
+If you want to read more about colors and colorspaces, then the
+following resources are useful: :ref:`poynton` is a good practical
+book for video engineers, :ref:`colimg` has a much broader scope and
+describes many more aspects of color (physics, chemistry, biology,
+etc.). The
+`http://www.brucelindbloom.com <http://www.brucelindbloom.com>`__
+website is an excellent resource, especially with respect to the
+mathematics behind colorspace conversions. The wikipedia
+`CIE 1931 colorspace <http://en.wikipedia.org/wiki/CIE_1931_color_space#CIE_xy_chromaticity_diagram_and_the_CIE_xyY_color_space>`__
+article is also very useful.
diff --git a/Documentation/userspace-api/media/v4l/common-defs.rst b/Documentation/userspace-api/media/v4l/common-defs.rst
new file mode 100644
index 000000000000..370a1e364a51
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/common-defs.rst
@@ -0,0 +1,20 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _common-defs:
+
+******************************************************
+Common definitions for V4L2 and V4L2 subdev interfaces
+******************************************************
+
+
+.. toctree::
+    :maxdepth: 1
+
+    selections-common
diff --git a/Documentation/userspace-api/media/v4l/common.rst b/Documentation/userspace-api/media/v4l/common.rst
new file mode 100644
index 000000000000..7d81c58a13cd
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/common.rst
@@ -0,0 +1,65 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _common:
+
+###################
+Common API Elements
+###################
+Programming a V4L2 device consists of these steps:
+
+-  Opening the device
+
+-  Changing device properties, selecting a video and audio input, video
+   standard, picture brightness a. o.
+
+-  Negotiating a data format
+
+-  Negotiating an input/output method
+
+-  The actual input/output loop
+
+-  Closing the device
+
+In practice most steps are optional and can be executed out of order. It
+depends on the V4L2 device type, you can read about the details in
+:ref:`devices`. In this chapter we will discuss the basic concepts
+applicable to all devices.
+
+
+.. toctree::
+    :maxdepth: 1
+
+    open
+    querycap
+    app-pri
+    video
+    audio
+    tuner
+    standard
+    dv-timings
+    control
+    extended-controls
+    ext-ctrls-camera
+    ext-ctrls-flash
+    ext-ctrls-image-source
+    ext-ctrls-image-process
+    ext-ctrls-codec
+    ext-ctrls-jpeg
+    ext-ctrls-dv
+    ext-ctrls-rf-tuner
+    ext-ctrls-fm-tx
+    ext-ctrls-fm-rx
+    ext-ctrls-detect
+    fourcc
+    format
+    planar-apis
+    selection-api
+    crop
+    streaming-par
diff --git a/Documentation/userspace-api/media/v4l/compat.rst b/Documentation/userspace-api/media/v4l/compat.rst
new file mode 100644
index 000000000000..055286b86e9b
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/compat.rst
@@ -0,0 +1,25 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _compat:
+
+*******
+Changes
+*******
+
+The following chapters document the evolution of the V4L2 API, errata or
+extensions. They are also intended to help application and driver
+writers to port or update their code.
+
+
+.. toctree::
+    :maxdepth: 1
+
+    diff-v4l
+    hist-v4l2
diff --git a/Documentation/userspace-api/media/v4l/constraints.svg b/Documentation/userspace-api/media/v4l/constraints.svg
new file mode 100644
index 000000000000..1dfe51a9839d
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/constraints.svg
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    This file is dual-licensed: you can use it either under the terms
+    of the GPL 2.0 or the GFDL 1.1+ license, at your option. Note that this
+    dual licensing only applies to this file, and not this project as a
+    whole.
+
+    a) This file is free software; you can redistribute it and/or
+       modify it under the terms of the GNU General Public License as
+       published by the Free Software Foundation version 2 of
+       the License.
+
+       This file is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+    Or, alternatively,
+
+    b) Permission is granted to copy, distribute and/or modify this
+       document under the terms of the GNU Free Documentation License,
+       Version 1.1 or any later version published by the Free Software
+       Foundation, with no Invariant Sections, no Front-Cover Texts
+       and no Back-Cover Texts. A copy of the license is included at
+       Documentation/userspace-api/media/fdl-appendix.rst.
+
+    TODO: replace it to GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
+-->
+<svg id="svg2" width="249.01mm" height="143.01mm" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" preserveAspectRatio="xMidYMid" version="1.2" viewBox="0 0 24900.998 14300.999" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><metadata id="metadata325"><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title/></cc:Work></rdf:RDF></metadata><defs id="defs4" class="ClipPathGroup"><marker id="marker6261" overflow="visible" orient="auto"><path id="path6263" transform="matrix(-.4 0 0 -.4 -4 0)" d="m0 0 5-5-17.5 5 17.5 5-5-5z" fill="#f00" fill-rule="evenodd" stroke="#f00" stroke-width="1pt"/></marker><marker id="marker6125" overflow="visible"
+orient="auto"><path id="path6127" transform="matrix(-.4 0 0 -.4 -4 0)" d="m0 0 5-5-17.5 5 17.5 5-5-5z" fill="#f00" fill-rule="evenodd" stroke="#f00" stroke-width="1pt"/></marker><marker id="marker6001" overflow="visible" orient="auto"><path id="path6003" transform="matrix(-.4 0 0 -.4 -4 0)" d="m0 0 5-5-17.5 5 17.5 5-5-5z" fill="#f00" fill-rule="evenodd" stroke="#f00" stroke-width="1pt"/></marker><marker id="marker5693" overflow="visible" orient="auto"><path id="path5695" transform="matrix(-.4 0 0 -.4 -4 0)" d="m0 0 5-5-17.5 5 17.5 5-5-5z" fill="#f00" fill-rule="evenodd" stroke="#f00" stroke-width="1pt"/></marker><marker id="marker5575" overflow="visible" orient="auto"><path id="path5577" transform="matrix(-.4 0 0 -.4 -4 0)" d="m0 0 5-5-17.5 5 17.5 5-5-5z" fill="#000080" fill-rule="evenodd" stroke="#000080" stroke-width="1pt"/></marker><marker id="marker5469" overflow="visible"
+orient="auto"><path id="path5471" transform="matrix(-.4 0 0 -.4 -4 0)" d="m0 0 5-5-17.5 5 17.5 5-5-5z" fill="#000080" fill-rule="evenodd" stroke="#000080" stroke-width="1pt"/></marker><marker id="marker5259" overflow="visible" orient="auto"><path id="path5261" transform="matrix(-.4 0 0 -.4 -4 0)" d="m0 0 5-5-17.5 5 17.5 5-5-5z" fill="#000080" fill-rule="evenodd" stroke="#000080" stroke-width="1pt"/></marker><marker id="Arrow2Mend" overflow="visible" orient="auto"><path id="path4241" transform="scale(-.6)" d="m8.7186 4.0337-10.926-4.0177 10.926-4.0177c-1.7455 2.3721-1.7354 5.6175-6e-7 8.0354z" fill="#000080" fill-rule="evenodd" stroke="#000080" stroke-linejoin="round" stroke-width=".625"/></marker></defs><g id="g204" class="com.sun.star.drawing.CustomShape" transform="translate(-1350,-3250)"><g id="id6"><rect id="rect207" class="BoundingBox" x="1350" y="3250" width="24901" height="14301"
+fill="none"/><path id="path209" d="m13800 17500h-12400v-14200h24800v14200h-12400z" fill="#fff"/><path id="path211" d="m13800 17500h-12400v-14200h24800v14200h-12400z" fill="none" stroke="#f00" stroke-linejoin="round" stroke-width="100"/><text id="text213" class="TextShape"><tspan id="tspan215" class="TextParagraph" font-family="sans-serif" font-size="846px" font-weight="400"><tspan id="tspan217" class="TextPosition" x="1652" y="17093" fill="#ff0000"><tspan id="tspan219"/><tspan id="tspan221">V4L2_SEL_FLAG_GE</tspan></tspan></tspan></text>
+</g></g><rect id="rect226" class="BoundingBox" x="3e3" y="2200" width="18101" height="10101" fill="none"/><path id="path228" d="m12050 12250h-9e3v-1e4h18000v1e4h-9e3z" fill="#fff"/><path id="path230" d="m12050 12250h-9e3v-1e4h18000v1e4h-9e3z" fill="none" stroke="#000" stroke-linejoin="round" stroke-width="100"/><text id="text232" class="TextShape" x="-1350" y="-3250"><tspan id="tspan234" class="TextParagraph" font-family="sans-serif" font-size="987px" font-weight="400"><tspan id="tspan236" class="TextPosition" x="3227" y="11503" fill="#000000"><tspan id="tspan238"/><tspan id="tspan240">ORIGINAL</tspan></tspan></tspan></text>
+<g id="g242" class="com.sun.star.drawing.CustomShape" transform="translate(-1350,-3250)"><g id="id8"><rect id="rect245" class="BoundingBox" x="7050" y="7950" width="7901" height="5501" fill="none"/><path id="path247" d="m11000 13400h-3900v-5400h7800v5400h-3900z" fill="#fff"/><path id="path249" d="m11000 13400h-3900v-5400h7800v5400h-3900z" fill="none" stroke="#3465a4" stroke-linejoin="round" stroke-width="100"/><text id="text251" class="TextShape"><tspan id="tspan253" class="TextParagraph" font-family="sans-serif" font-size="776px" font-weight="400"><tspan id="tspan255" class="TextPosition" x="7228" y="10969"><tspan id="tspan257" fill="#000080">V4L2_SEL_FLAG_LE</tspan></tspan></tspan></text>
+</g></g><rect id="rect262" class="BoundingBox" x="13700" y="7100" width="7101" height="101" fill="none"/><path id="path264" d="m20750 7150h-7e3" fill="none" marker-end="url(#Arrow2Mend)" stroke="#000080" stroke-linejoin="round" stroke-width="99.991"/><rect id="rect269" class="BoundingBox" x="3400" y="7100" width="2101" height="101" fill="none"/><path id="path271" d="m3450 7150h2e3" fill="none" marker-end="url(#marker5575)" stroke="#000080" stroke-linejoin="round" stroke-width="100"/><rect id="rect276" class="BoundingBox" x="9800" y="2900" width="101" height="1501" fill="none"/><path id="path278" d="m9850 2950v1400" fill="none" marker-end="url(#marker5259)" stroke="#000080" stroke-linejoin="round" stroke-width="100"/><rect id="rect283" class="BoundingBox" x="9600" y="10600" width="101" height="1301" fill="none"/><path id="path285" d="m9650 11850v-1200" fill="none"
+marker-end="url(#marker5469)" stroke="#000080" stroke-linejoin="round" stroke-width="100"/><rect id="rect290" class="BoundingBox" x="450" y="6850" width="2051" height="601" fill="none"/><path id="path292" d="m2450 7150h-2000.9" fill="none" marker-end="url(#marker6125)" stroke="#f00" stroke-linejoin="round" stroke-width="132.48"/><rect id="rect299" class="BoundingBox" x="21600" y="6750" width="2651" height="601" fill="none"/><path id="path301" d="m21650 7050h2522.6" fill="none" marker-end="url(#marker6001)" stroke="#f00" stroke-linejoin="round" stroke-width="120.41"/><rect id="rect308" class="BoundingBox" x="9550" y="550" width="601" height="1451" fill="none"/><path id="path310" d="m9837 1950v-1453" fill="none" marker-end="url(#marker6261)" stroke="#f00" stroke-linejoin="round" stroke-width="164.04"/><rect id="rect317" class="BoundingBox" x="9350" y="12500" width="601" height="1451"
+fill="none"/><path id="path319" d="m9650 12550v1505.2" fill="none" marker-end="url(#marker5693)" stroke="#f00" stroke-linejoin="round" stroke-width="166.96"/></svg>
diff --git a/Documentation/userspace-api/media/v4l/control.rst b/Documentation/userspace-api/media/v4l/control.rst
new file mode 100644
index 000000000000..3e991c1f7a12
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/control.rst
@@ -0,0 +1,512 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _control:
+
+*************
+User Controls
+*************
+
+Devices typically have a number of user-settable controls such as
+brightness, saturation and so on, which would be presented to the user
+on a graphical user interface. But, different devices will have
+different controls available, and furthermore, the range of possible
+values, and the default value will vary from device to device. The
+control ioctls provide the information and a mechanism to create a nice
+user interface for these controls that will work correctly with any
+device.
+
+All controls are accessed using an ID value. V4L2 defines several IDs
+for specific purposes. Drivers can also implement their own custom
+controls using ``V4L2_CID_PRIVATE_BASE``  [#f1]_ and higher values. The
+pre-defined control IDs have the prefix ``V4L2_CID_``, and are listed in
+:ref:`control-id`. The ID is used when querying the attributes of a
+control, and when getting or setting the current value.
+
+Generally applications should present controls to the user without
+assumptions about their purpose. Each control comes with a name string
+the user is supposed to understand. When the purpose is non-intuitive
+the driver writer should provide a user manual, a user interface plug-in
+or a driver specific panel application. Predefined IDs were introduced
+to change a few controls programmatically, for example to mute a device
+during a channel switch.
+
+Drivers may enumerate different controls after switching the current
+video input or output, tuner or modulator, or audio input or output.
+Different in the sense of other bounds, another default and current
+value, step size or other menu items. A control with a certain *custom*
+ID can also change name and type.
+
+If a control is not applicable to the current configuration of the
+device (for example, it doesn't apply to the current video input)
+drivers set the ``V4L2_CTRL_FLAG_INACTIVE`` flag.
+
+Control values are stored globally, they do not change when switching
+except to stay within the reported bounds. They also do not change e. g.
+when the device is opened or closed, when the tuner radio frequency is
+changed or generally never without application request.
+
+V4L2 specifies an event mechanism to notify applications when controls
+change value (see
+:ref:`VIDIOC_SUBSCRIBE_EVENT`, event
+``V4L2_EVENT_CTRL``), panel applications might want to make use of that
+in order to always reflect the correct control value.
+
+All controls use machine endianness.
+
+
+.. _control-id:
+
+Control IDs
+===========
+
+``V4L2_CID_BASE``
+    First predefined ID, equal to ``V4L2_CID_BRIGHTNESS``.
+
+``V4L2_CID_USER_BASE``
+    Synonym of ``V4L2_CID_BASE``.
+
+``V4L2_CID_BRIGHTNESS`` ``(integer)``
+    Picture brightness, or more precisely, the black level.
+
+``V4L2_CID_CONTRAST`` ``(integer)``
+    Picture contrast or luma gain.
+
+``V4L2_CID_SATURATION`` ``(integer)``
+    Picture color saturation or chroma gain.
+
+``V4L2_CID_HUE`` ``(integer)``
+    Hue or color balance.
+
+``V4L2_CID_AUDIO_VOLUME`` ``(integer)``
+    Overall audio volume. Note some drivers also provide an OSS or ALSA
+    mixer interface.
+
+``V4L2_CID_AUDIO_BALANCE`` ``(integer)``
+    Audio stereo balance. Minimum corresponds to all the way left,
+    maximum to right.
+
+``V4L2_CID_AUDIO_BASS`` ``(integer)``
+    Audio bass adjustment.
+
+``V4L2_CID_AUDIO_TREBLE`` ``(integer)``
+    Audio treble adjustment.
+
+``V4L2_CID_AUDIO_MUTE`` ``(boolean)``
+    Mute audio, i. e. set the volume to zero, however without affecting
+    ``V4L2_CID_AUDIO_VOLUME``. Like ALSA drivers, V4L2 drivers must mute
+    at load time to avoid excessive noise. Actually the entire device
+    should be reset to a low power consumption state.
+
+``V4L2_CID_AUDIO_LOUDNESS`` ``(boolean)``
+    Loudness mode (bass boost).
+
+``V4L2_CID_BLACK_LEVEL`` ``(integer)``
+    Another name for brightness (not a synonym of
+    ``V4L2_CID_BRIGHTNESS``). This control is deprecated and should not
+    be used in new drivers and applications.
+
+``V4L2_CID_AUTO_WHITE_BALANCE`` ``(boolean)``
+    Automatic white balance (cameras).
+
+``V4L2_CID_DO_WHITE_BALANCE`` ``(button)``
+    This is an action control. When set (the value is ignored), the
+    device will do a white balance and then hold the current setting.
+    Contrast this with the boolean ``V4L2_CID_AUTO_WHITE_BALANCE``,
+    which, when activated, keeps adjusting the white balance.
+
+``V4L2_CID_RED_BALANCE`` ``(integer)``
+    Red chroma balance.
+
+``V4L2_CID_BLUE_BALANCE`` ``(integer)``
+    Blue chroma balance.
+
+``V4L2_CID_GAMMA`` ``(integer)``
+    Gamma adjust.
+
+``V4L2_CID_WHITENESS`` ``(integer)``
+    Whiteness for grey-scale devices. This is a synonym for
+    ``V4L2_CID_GAMMA``. This control is deprecated and should not be
+    used in new drivers and applications.
+
+``V4L2_CID_EXPOSURE`` ``(integer)``
+    Exposure (cameras). [Unit?]
+
+``V4L2_CID_AUTOGAIN`` ``(boolean)``
+    Automatic gain/exposure control.
+
+``V4L2_CID_GAIN`` ``(integer)``
+    Gain control.
+
+    Primarily used to control gain on e.g. TV tuners but also on
+    webcams. Most devices control only digital gain with this control
+    but on some this could include analogue gain as well. Devices that
+    recognise the difference between digital and analogue gain use
+    controls ``V4L2_CID_DIGITAL_GAIN`` and ``V4L2_CID_ANALOGUE_GAIN``.
+
+``V4L2_CID_HFLIP`` ``(boolean)``
+    Mirror the picture horizontally.
+
+``V4L2_CID_VFLIP`` ``(boolean)``
+    Mirror the picture vertically.
+
+.. _v4l2-power-line-frequency:
+
+``V4L2_CID_POWER_LINE_FREQUENCY`` ``(enum)``
+    Enables a power line frequency filter to avoid flicker. Possible
+    values for ``enum v4l2_power_line_frequency`` are:
+    ``V4L2_CID_POWER_LINE_FREQUENCY_DISABLED`` (0),
+    ``V4L2_CID_POWER_LINE_FREQUENCY_50HZ`` (1),
+    ``V4L2_CID_POWER_LINE_FREQUENCY_60HZ`` (2) and
+    ``V4L2_CID_POWER_LINE_FREQUENCY_AUTO`` (3).
+
+``V4L2_CID_HUE_AUTO`` ``(boolean)``
+    Enables automatic hue control by the device. The effect of setting
+    ``V4L2_CID_HUE`` while automatic hue control is enabled is
+    undefined, drivers should ignore such request.
+
+``V4L2_CID_WHITE_BALANCE_TEMPERATURE`` ``(integer)``
+    This control specifies the white balance settings as a color
+    temperature in Kelvin. A driver should have a minimum of 2800
+    (incandescent) to 6500 (daylight). For more information about color
+    temperature see
+    `Wikipedia <http://en.wikipedia.org/wiki/Color_temperature>`__.
+
+``V4L2_CID_SHARPNESS`` ``(integer)``
+    Adjusts the sharpness filters in a camera. The minimum value
+    disables the filters, higher values give a sharper picture.
+
+``V4L2_CID_BACKLIGHT_COMPENSATION`` ``(integer)``
+    Adjusts the backlight compensation in a camera. The minimum value
+    disables backlight compensation.
+
+``V4L2_CID_CHROMA_AGC`` ``(boolean)``
+    Chroma automatic gain control.
+
+``V4L2_CID_CHROMA_GAIN`` ``(integer)``
+    Adjusts the Chroma gain control (for use when chroma AGC is
+    disabled).
+
+``V4L2_CID_COLOR_KILLER`` ``(boolean)``
+    Enable the color killer (i. e. force a black & white image in case
+    of a weak video signal).
+
+.. _v4l2-colorfx:
+
+``V4L2_CID_COLORFX`` ``(enum)``
+    Selects a color effect. The following values are defined:
+
+
+
+.. tabularcolumns:: |p{5.5cm}|p{12cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths: 11 24
+
+    * - ``V4L2_COLORFX_NONE``
+      - Color effect is disabled.
+    * - ``V4L2_COLORFX_ANTIQUE``
+      - An aging (old photo) effect.
+    * - ``V4L2_COLORFX_ART_FREEZE``
+      - Frost color effect.
+    * - ``V4L2_COLORFX_AQUA``
+      - Water color, cool tone.
+    * - ``V4L2_COLORFX_BW``
+      - Black and white.
+    * - ``V4L2_COLORFX_EMBOSS``
+      - Emboss, the highlights and shadows replace light/dark boundaries
+	and low contrast areas are set to a gray background.
+    * - ``V4L2_COLORFX_GRASS_GREEN``
+      - Grass green.
+    * - ``V4L2_COLORFX_NEGATIVE``
+      - Negative.
+    * - ``V4L2_COLORFX_SEPIA``
+      - Sepia tone.
+    * - ``V4L2_COLORFX_SKETCH``
+      - Sketch.
+    * - ``V4L2_COLORFX_SKIN_WHITEN``
+      - Skin whiten.
+    * - ``V4L2_COLORFX_SKY_BLUE``
+      - Sky blue.
+    * - ``V4L2_COLORFX_SOLARIZATION``
+      - Solarization, the image is partially reversed in tone, only color
+	values above or below a certain threshold are inverted.
+    * - ``V4L2_COLORFX_SILHOUETTE``
+      - Silhouette (outline).
+    * - ``V4L2_COLORFX_VIVID``
+      - Vivid colors.
+    * - ``V4L2_COLORFX_SET_CBCR``
+      - The Cb and Cr chroma components are replaced by fixed coefficients
+	determined by ``V4L2_CID_COLORFX_CBCR`` control.
+
+
+
+``V4L2_CID_COLORFX_CBCR`` ``(integer)``
+    Determines the Cb and Cr coefficients for ``V4L2_COLORFX_SET_CBCR``
+    color effect. Bits [7:0] of the supplied 32 bit value are
+    interpreted as Cr component, bits [15:8] as Cb component and bits
+    [31:16] must be zero.
+
+``V4L2_CID_AUTOBRIGHTNESS`` ``(boolean)``
+    Enable Automatic Brightness.
+
+``V4L2_CID_ROTATE`` ``(integer)``
+    Rotates the image by specified angle. Common angles are 90, 270 and
+    180. Rotating the image to 90 and 270 will reverse the height and
+    width of the display window. It is necessary to set the new height
+    and width of the picture using the
+    :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl according to the
+    rotation angle selected.
+
+``V4L2_CID_BG_COLOR`` ``(integer)``
+    Sets the background color on the current output device. Background
+    color needs to be specified in the RGB24 format. The supplied 32 bit
+    value is interpreted as bits 0-7 Red color information, bits 8-15
+    Green color information, bits 16-23 Blue color information and bits
+    24-31 must be zero.
+
+``V4L2_CID_ILLUMINATORS_1 V4L2_CID_ILLUMINATORS_2`` ``(boolean)``
+    Switch on or off the illuminator 1 or 2 of the device (usually a
+    microscope).
+
+``V4L2_CID_MIN_BUFFERS_FOR_CAPTURE`` ``(integer)``
+    This is a read-only control that can be read by the application and
+    used as a hint to determine the number of CAPTURE buffers to pass to
+    REQBUFS. The value is the minimum number of CAPTURE buffers that is
+    necessary for hardware to work.
+
+``V4L2_CID_MIN_BUFFERS_FOR_OUTPUT`` ``(integer)``
+    This is a read-only control that can be read by the application and
+    used as a hint to determine the number of OUTPUT buffers to pass to
+    REQBUFS. The value is the minimum number of OUTPUT buffers that is
+    necessary for hardware to work.
+
+.. _v4l2-alpha-component:
+
+``V4L2_CID_ALPHA_COMPONENT`` ``(integer)``
+    Sets the alpha color component. When a capture device (or capture
+    queue of a mem-to-mem device) produces a frame format that includes
+    an alpha component (e.g.
+    :ref:`packed RGB image formats <pixfmt-rgb>`) and the alpha value
+    is not defined by the device or the mem-to-mem input data this
+    control lets you select the alpha component value of all pixels.
+    When an output device (or output queue of a mem-to-mem device)
+    consumes a frame format that doesn't include an alpha component and
+    the device supports alpha channel processing this control lets you
+    set the alpha component value of all pixels for further processing
+    in the device.
+
+``V4L2_CID_LASTP1``
+    End of the predefined control IDs (currently
+    ``V4L2_CID_ALPHA_COMPONENT`` + 1).
+
+``V4L2_CID_PRIVATE_BASE``
+    ID of the first custom (driver specific) control. Applications
+    depending on particular custom controls should check the driver name
+    and version, see :ref:`querycap`.
+
+Applications can enumerate the available controls with the
+:ref:`VIDIOC_QUERYCTRL` and
+:ref:`VIDIOC_QUERYMENU <VIDIOC_QUERYCTRL>` ioctls, get and set a
+control value with the :ref:`VIDIOC_G_CTRL <VIDIOC_G_CTRL>` and
+:ref:`VIDIOC_S_CTRL <VIDIOC_G_CTRL>` ioctls. Drivers must implement
+``VIDIOC_QUERYCTRL``, ``VIDIOC_G_CTRL`` and ``VIDIOC_S_CTRL`` when the
+device has one or more controls, ``VIDIOC_QUERYMENU`` when it has one or
+more menu type controls.
+
+
+.. _enum_all_controls:
+
+Example: Enumerating all controls
+=================================
+
+.. code-block:: c
+
+    struct v4l2_queryctrl queryctrl;
+    struct v4l2_querymenu querymenu;
+
+    static void enumerate_menu(__u32 id)
+    {
+	printf("  Menu items:\\n");
+
+	memset(&querymenu, 0, sizeof(querymenu));
+	querymenu.id = id;
+
+	for (querymenu.index = queryctrl.minimum;
+	     querymenu.index <= queryctrl.maximum;
+	     querymenu.index++) {
+	    if (0 == ioctl(fd, VIDIOC_QUERYMENU, &querymenu)) {
+		printf("  %s\\n", querymenu.name);
+	    }
+	}
+    }
+
+    memset(&queryctrl, 0, sizeof(queryctrl));
+
+    queryctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL;
+    while (0 == ioctl(fd, VIDIOC_QUERYCTRL, &queryctrl)) {
+	if (!(queryctrl.flags & V4L2_CTRL_FLAG_DISABLED)) {
+	    printf("Control %s\\n", queryctrl.name);
+
+	    if (queryctrl.type == V4L2_CTRL_TYPE_MENU)
+	        enumerate_menu(queryctrl.id);
+        }
+
+	queryctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
+    }
+    if (errno != EINVAL) {
+	perror("VIDIOC_QUERYCTRL");
+	exit(EXIT_FAILURE);
+    }
+
+Example: Enumerating all controls including compound controls
+=============================================================
+
+.. code-block:: c
+
+    struct v4l2_query_ext_ctrl query_ext_ctrl;
+
+    memset(&query_ext_ctrl, 0, sizeof(query_ext_ctrl));
+
+    query_ext_ctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL | V4L2_CTRL_FLAG_NEXT_COMPOUND;
+    while (0 == ioctl(fd, VIDIOC_QUERY_EXT_CTRL, &query_ext_ctrl)) {
+	if (!(query_ext_ctrl.flags & V4L2_CTRL_FLAG_DISABLED)) {
+	    printf("Control %s\\n", query_ext_ctrl.name);
+
+	    if (query_ext_ctrl.type == V4L2_CTRL_TYPE_MENU)
+	        enumerate_menu(query_ext_ctrl.id);
+        }
+
+	query_ext_ctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL | V4L2_CTRL_FLAG_NEXT_COMPOUND;
+    }
+    if (errno != EINVAL) {
+	perror("VIDIOC_QUERY_EXT_CTRL");
+	exit(EXIT_FAILURE);
+    }
+
+Example: Enumerating all user controls (old style)
+==================================================
+
+.. code-block:: c
+
+
+    memset(&queryctrl, 0, sizeof(queryctrl));
+
+    for (queryctrl.id = V4L2_CID_BASE;
+	 queryctrl.id < V4L2_CID_LASTP1;
+	 queryctrl.id++) {
+	if (0 == ioctl(fd, VIDIOC_QUERYCTRL, &queryctrl)) {
+	    if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED)
+		continue;
+
+	    printf("Control %s\\n", queryctrl.name);
+
+	    if (queryctrl.type == V4L2_CTRL_TYPE_MENU)
+		enumerate_menu(queryctrl.id);
+	} else {
+	    if (errno == EINVAL)
+		continue;
+
+	    perror("VIDIOC_QUERYCTRL");
+	    exit(EXIT_FAILURE);
+	}
+    }
+
+    for (queryctrl.id = V4L2_CID_PRIVATE_BASE;;
+	 queryctrl.id++) {
+	if (0 == ioctl(fd, VIDIOC_QUERYCTRL, &queryctrl)) {
+	    if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED)
+		continue;
+
+	    printf("Control %s\\n", queryctrl.name);
+
+	    if (queryctrl.type == V4L2_CTRL_TYPE_MENU)
+		enumerate_menu(queryctrl.id);
+	} else {
+	    if (errno == EINVAL)
+		break;
+
+	    perror("VIDIOC_QUERYCTRL");
+	    exit(EXIT_FAILURE);
+	}
+    }
+
+
+Example: Changing controls
+==========================
+
+.. code-block:: c
+
+    struct v4l2_queryctrl queryctrl;
+    struct v4l2_control control;
+
+    memset(&queryctrl, 0, sizeof(queryctrl));
+    queryctrl.id = V4L2_CID_BRIGHTNESS;
+
+    if (-1 == ioctl(fd, VIDIOC_QUERYCTRL, &queryctrl)) {
+	if (errno != EINVAL) {
+	    perror("VIDIOC_QUERYCTRL");
+	    exit(EXIT_FAILURE);
+	} else {
+	    printf("V4L2_CID_BRIGHTNESS is not supportedn");
+	}
+    } else if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) {
+	printf("V4L2_CID_BRIGHTNESS is not supportedn");
+    } else {
+	memset(&control, 0, sizeof (control));
+	control.id = V4L2_CID_BRIGHTNESS;
+	control.value = queryctrl.default_value;
+
+	if (-1 == ioctl(fd, VIDIOC_S_CTRL, &control)) {
+	    perror("VIDIOC_S_CTRL");
+	    exit(EXIT_FAILURE);
+	}
+    }
+
+    memset(&control, 0, sizeof(control));
+    control.id = V4L2_CID_CONTRAST;
+
+    if (0 == ioctl(fd, VIDIOC_G_CTRL, &control)) {
+	control.value += 1;
+
+	/* The driver may clamp the value or return ERANGE, ignored here */
+
+	if (-1 == ioctl(fd, VIDIOC_S_CTRL, &control)
+	    && errno != ERANGE) {
+	    perror("VIDIOC_S_CTRL");
+	    exit(EXIT_FAILURE);
+	}
+    /* Ignore if V4L2_CID_CONTRAST is unsupported */
+    } else if (errno != EINVAL) {
+	perror("VIDIOC_G_CTRL");
+	exit(EXIT_FAILURE);
+    }
+
+    control.id = V4L2_CID_AUDIO_MUTE;
+    control.value = 1; /* silence */
+
+    /* Errors ignored */
+    ioctl(fd, VIDIOC_S_CTRL, &control);
+
+.. [#f1]
+   The use of ``V4L2_CID_PRIVATE_BASE`` is problematic because different
+   drivers may use the same ``V4L2_CID_PRIVATE_BASE`` ID for different
+   controls. This makes it hard to programmatically set such controls
+   since the meaning of the control with that ID is driver dependent. In
+   order to resolve this drivers use unique IDs and the
+   ``V4L2_CID_PRIVATE_BASE`` IDs are mapped to those unique IDs by the
+   kernel. Consider these ``V4L2_CID_PRIVATE_BASE`` IDs as aliases to
+   the real IDs.
+
+   Many applications today still use the ``V4L2_CID_PRIVATE_BASE`` IDs
+   instead of using :ref:`VIDIOC_QUERYCTRL` with
+   the ``V4L2_CTRL_FLAG_NEXT_CTRL`` flag to enumerate all IDs, so
+   support for ``V4L2_CID_PRIVATE_BASE`` is still around.
diff --git a/Documentation/userspace-api/media/v4l/crop.rst b/Documentation/userspace-api/media/v4l/crop.rst
new file mode 100644
index 000000000000..cb7e2341aedf
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/crop.rst
@@ -0,0 +1,324 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _crop:
+
+*****************************************************
+Image Cropping, Insertion and Scaling -- the CROP API
+*****************************************************
+
+.. note::
+
+   The CROP API is mostly superseded by the newer :ref:`SELECTION API
+   <selection-api>`. The new API should be preferred in most cases,
+   with the exception of pixel aspect ratio detection, which is
+   implemented by :ref:`VIDIOC_CROPCAP <VIDIOC_CROPCAP>` and has no
+   equivalent in the SELECTION API. See :ref:`selection-vs-crop` for a
+   comparison of the two APIs.
+
+Some video capture devices can sample a subsection of the picture and
+shrink or enlarge it to an image of arbitrary size. We call these
+abilities cropping and scaling. Some video output devices can scale an
+image up or down and insert it at an arbitrary scan line and horizontal
+offset into a video signal.
+
+Applications can use the following API to select an area in the video
+signal, query the default area and the hardware limits.
+
+.. note::
+
+   Despite their name, the :ref:`VIDIOC_CROPCAP <VIDIOC_CROPCAP>`,
+   :ref:`VIDIOC_G_CROP <VIDIOC_G_CROP>` and :ref:`VIDIOC_S_CROP
+   <VIDIOC_G_CROP>` ioctls apply to input as well as output devices.
+
+Scaling requires a source and a target. On a video capture or overlay
+device the source is the video signal, and the cropping ioctls determine
+the area actually sampled. The target are images read by the application
+or overlaid onto the graphics screen. Their size (and position for an
+overlay) is negotiated with the :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>`
+and :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctls.
+
+On a video output device the source are the images passed in by the
+application, and their size is again negotiated with the
+:ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` and :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`
+ioctls, or may be encoded in a compressed video stream. The target is
+the video signal, and the cropping ioctls determine the area where the
+images are inserted.
+
+Source and target rectangles are defined even if the device does not
+support scaling or the :ref:`VIDIOC_G_CROP <VIDIOC_G_CROP>` and
+:ref:`VIDIOC_S_CROP <VIDIOC_G_CROP>` ioctls. Their size (and position
+where applicable) will be fixed in this case.
+
+.. note::
+
+   All capture and output devices that support the CROP or SELECTION
+   API will also support the :ref:`VIDIOC_CROPCAP <VIDIOC_CROPCAP>`
+   ioctl.
+
+Cropping Structures
+===================
+
+
+.. _crop-scale:
+
+.. kernel-figure:: crop.svg
+    :alt:    crop.svg
+    :align:  center
+
+    Image Cropping, Insertion and Scaling
+
+    The cropping, insertion and scaling process
+
+
+
+For capture devices the coordinates of the top left corner, width and
+height of the area which can be sampled is given by the ``bounds``
+substructure of the struct :c:type:`v4l2_cropcap` returned
+by the :ref:`VIDIOC_CROPCAP <VIDIOC_CROPCAP>` ioctl. To support a wide
+range of hardware this specification does not define an origin or units.
+However by convention drivers should horizontally count unscaled samples
+relative to 0H (the leading edge of the horizontal sync pulse, see
+:ref:`vbi-hsync`). Vertically ITU-R line numbers of the first field
+(see ITU R-525 line numbering for :ref:`525 lines <vbi-525>` and for
+:ref:`625 lines <vbi-625>`), multiplied by two if the driver
+can capture both fields.
+
+The top left corner, width and height of the source rectangle, that is
+the area actually sampled, is given by struct
+:c:type:`v4l2_crop` using the same coordinate system as
+struct :c:type:`v4l2_cropcap`. Applications can use the
+:ref:`VIDIOC_G_CROP <VIDIOC_G_CROP>` and :ref:`VIDIOC_S_CROP <VIDIOC_G_CROP>`
+ioctls to get and set this rectangle. It must lie completely within the
+capture boundaries and the driver may further adjust the requested size
+and/or position according to hardware limitations.
+
+Each capture device has a default source rectangle, given by the
+``defrect`` substructure of struct
+:c:type:`v4l2_cropcap`. The center of this rectangle
+shall align with the center of the active picture area of the video
+signal, and cover what the driver writer considers the complete picture.
+Drivers shall reset the source rectangle to the default when the driver
+is first loaded, but not later.
+
+For output devices these structures and ioctls are used accordingly,
+defining the *target* rectangle where the images will be inserted into
+the video signal.
+
+
+Scaling Adjustments
+===================
+
+Video hardware can have various cropping, insertion and scaling
+limitations. It may only scale up or down, support only discrete scaling
+factors, or have different scaling abilities in horizontal and vertical
+direction. Also it may not support scaling at all. At the same time the
+struct :c:type:`v4l2_crop` rectangle may have to be aligned,
+and both the source and target rectangles may have arbitrary upper and
+lower size limits. In particular the maximum ``width`` and ``height`` in
+struct :c:type:`v4l2_crop` may be smaller than the struct
+:c:type:`v4l2_cropcap`. ``bounds`` area. Therefore, as
+usual, drivers are expected to adjust the requested parameters and
+return the actual values selected.
+
+Applications can change the source or the target rectangle first, as
+they may prefer a particular image size or a certain area in the video
+signal. If the driver has to adjust both to satisfy hardware
+limitations, the last requested rectangle shall take priority, and the
+driver should preferably adjust the opposite one. The
+:ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` ioctl however shall not change
+the driver state and therefore only adjust the requested rectangle.
+
+Suppose scaling on a video capture device is restricted to a factor 1:1
+or 2:1 in either direction and the target image size must be a multiple
+of 16 × 16 pixels. The source cropping rectangle is set to defaults,
+which are also the upper limit in this example, of 640 × 400 pixels at
+offset 0, 0. An application requests an image size of 300 × 225 pixels,
+assuming video will be scaled down from the "full picture" accordingly.
+The driver sets the image size to the closest possible values 304 × 224,
+then chooses the cropping rectangle closest to the requested size, that
+is 608 × 224 (224 × 2:1 would exceed the limit 400). The offset 0, 0 is
+still valid, thus unmodified. Given the default cropping rectangle
+reported by :ref:`VIDIOC_CROPCAP <VIDIOC_CROPCAP>` the application can
+easily propose another offset to center the cropping rectangle.
+
+Now the application may insist on covering an area using a picture
+aspect ratio closer to the original request, so it asks for a cropping
+rectangle of 608 × 456 pixels. The present scaling factors limit
+cropping to 640 × 384, so the driver returns the cropping size 608 × 384
+and adjusts the image size to closest possible 304 × 192.
+
+
+Examples
+========
+
+Source and target rectangles shall remain unchanged across closing and
+reopening a device, such that piping data into or out of a device will
+work without special preparations. More advanced applications should
+ensure the parameters are suitable before starting I/O.
+
+.. note::
+
+   On the next two examples, a video capture device is assumed;
+   change ``V4L2_BUF_TYPE_VIDEO_CAPTURE`` for other types of device.
+
+Example: Resetting the cropping parameters
+==========================================
+
+.. code-block:: c
+
+    struct v4l2_cropcap cropcap;
+    struct v4l2_crop crop;
+
+    memset (&cropcap, 0, sizeof (cropcap));
+    cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+    if (-1 == ioctl (fd, VIDIOC_CROPCAP, &cropcap)) {
+	perror ("VIDIOC_CROPCAP");
+	exit (EXIT_FAILURE);
+    }
+
+    memset (&crop, 0, sizeof (crop));
+    crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+    crop.c = cropcap.defrect;
+
+    /* Ignore if cropping is not supported (EINVAL). */
+
+    if (-1 == ioctl (fd, VIDIOC_S_CROP, &crop)
+	&& errno != EINVAL) {
+	perror ("VIDIOC_S_CROP");
+	exit (EXIT_FAILURE);
+    }
+
+
+Example: Simple downscaling
+===========================
+
+.. code-block:: c
+
+    struct v4l2_cropcap cropcap;
+    struct v4l2_format format;
+
+    reset_cropping_parameters ();
+
+    /* Scale down to 1/4 size of full picture. */
+
+    memset (&format, 0, sizeof (format)); /* defaults */
+
+    format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+    format.fmt.pix.width = cropcap.defrect.width >> 1;
+    format.fmt.pix.height = cropcap.defrect.height >> 1;
+    format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
+
+    if (-1 == ioctl (fd, VIDIOC_S_FMT, &format)) {
+	perror ("VIDIOC_S_FORMAT");
+	exit (EXIT_FAILURE);
+    }
+
+    /* We could check the actual image size now, the actual scaling factor
+       or if the driver can scale at all. */
+
+Example: Selecting an output area
+=================================
+
+.. note:: This example assumes an output device.
+
+.. code-block:: c
+
+    struct v4l2_cropcap cropcap;
+    struct v4l2_crop crop;
+
+    memset (&cropcap, 0, sizeof (cropcap));
+    cropcap.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+
+    if (-1 == ioctl (fd, VIDIOC_CROPCAP;, &cropcap)) {
+	perror ("VIDIOC_CROPCAP");
+	exit (EXIT_FAILURE);
+    }
+
+    memset (&crop, 0, sizeof (crop));
+
+    crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+    crop.c = cropcap.defrect;
+
+    /* Scale the width and height to 50 % of their original size
+       and center the output. */
+
+    crop.c.width /= 2;
+    crop.c.height /= 2;
+    crop.c.left += crop.c.width / 2;
+    crop.c.top += crop.c.height / 2;
+
+    /* Ignore if cropping is not supported (EINVAL). */
+
+    if (-1 == ioctl (fd, VIDIOC_S_CROP, &crop)
+	&& errno != EINVAL) {
+	perror ("VIDIOC_S_CROP");
+	exit (EXIT_FAILURE);
+    }
+
+Example: Current scaling factor and pixel aspect
+================================================
+
+.. note:: This example assumes a video capture device.
+
+.. code-block:: c
+
+    struct v4l2_cropcap cropcap;
+    struct v4l2_crop crop;
+    struct v4l2_format format;
+    double hscale, vscale;
+    double aspect;
+    int dwidth, dheight;
+
+    memset (&cropcap, 0, sizeof (cropcap));
+    cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+    if (-1 == ioctl (fd, VIDIOC_CROPCAP, &cropcap)) {
+	perror ("VIDIOC_CROPCAP");
+	exit (EXIT_FAILURE);
+    }
+
+    memset (&crop, 0, sizeof (crop));
+    crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+    if (-1 == ioctl (fd, VIDIOC_G_CROP, &crop)) {
+	if (errno != EINVAL) {
+	    perror ("VIDIOC_G_CROP");
+	    exit (EXIT_FAILURE);
+	}
+
+	/* Cropping not supported. */
+	crop.c = cropcap.defrect;
+    }
+
+    memset (&format, 0, sizeof (format));
+    format.fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+    if (-1 == ioctl (fd, VIDIOC_G_FMT, &format)) {
+	perror ("VIDIOC_G_FMT");
+	exit (EXIT_FAILURE);
+    }
+
+    /* The scaling applied by the driver. */
+
+    hscale = format.fmt.pix.width / (double) crop.c.width;
+    vscale = format.fmt.pix.height / (double) crop.c.height;
+
+    aspect = cropcap.pixelaspect.numerator /
+	 (double) cropcap.pixelaspect.denominator;
+    aspect = aspect * hscale / vscale;
+
+    /* Devices following ITU-R BT.601 do not capture
+       square pixels. For playback on a computer monitor
+       we should scale the images to this size. */
+
+    dwidth = format.fmt.pix.width / aspect;
+    dheight = format.fmt.pix.height;
diff --git a/Documentation/userspace-api/media/v4l/crop.svg b/Documentation/userspace-api/media/v4l/crop.svg
new file mode 100644
index 000000000000..4cd47f98e7c8
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/crop.svg
@@ -0,0 +1,290 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+    Permission is granted to copy, distribute and/or modify this
+    document under the terms of the GNU Free Documentation License,
+    Version 1.1 or any later version published by the Free Software
+    Foundation, with no Invariant Sections, no Front-Cover Texts
+    and no Back-Cover Texts. A copy of the license is included at
+    Documentation/userspace-api/media/fdl-appendix.rst.
+
+    TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+-->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.91 r13725"
+   xml:space="preserve"
+   width="208.59436mm"
+   height="95.859146mm"
+   viewBox="0 0 739.11388 339.6584"
+   sodipodi:docname="crop.svg"><metadata
+     id="metadata8"><rdf:RDF><cc:Work
+	 rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+	   rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
+     id="defs6"><clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath44"><path
+	 d="m 0,0 0,1895 4118,0 L 4118,0 0,0 Z m 3051.62,250.48 8.19,17.01 -46.93,23.31 29.61,-25.515 -38.12,8.505 47.25,-23.31 z m -1559.25,800.73 -8.5,-17.01 46.93,-23.31 -29.29,25.2 37.8,-8.19 -46.94,23.31 z"
+	 id="path46"
+	 inkscape:connector-curvature="0"
+	 style="clip-rule:evenodd" /></clipPath><clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath64"><path
+	 d="m 0,0 0,1895 4118,0 0,-1626 -1,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -1,0 0,-1 1,0 0,-1 1,0 0,-1 2,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 2,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 2,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 -4,0 0,1 -5,0 0,1 -4,0 0,1 -5,0 0,1 -4,0 0,1 -4,0 0,1 -4,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 1,0 0,3 1,0 0,2 1,0 0,2 1,0 L 4118,0 0,0 Z m 4074,272 0,-1 1,0 0,1 -1,0 z m -1486,743 0,-1 1,0 0,1 -1,0 z m -2,1 0,-1 1,0 0,1 -1,0 0,1 -1,0 0,1 -1,0 0,1 -1,0 0,1 -1,0 0,1 -1,0 0,1 -2,0 0,1 -1,0 0,1 -1,0 0,1 -1,0 0,1 -1,0 0,1 -1,0 0,1 -2,0 0,1 -1,0 0,1 -1,0 0,1
+-1,0 0,1 -1,0 0,1 -1,0 0,1 -2,0 0,1 -1,0 0,2 2,0 0,-1 4,0 0,-1 5,0 0,-1 4,0 0,-1 5,0 0,-1 5,0 0,-1 4,0 0,-1 3,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -3,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,-2 -1,0 0,-2 -1,0 0,-2 -1,0 0,-2 -1,0 0,-2 -1,0 0,-2 -1,0 0,-2 -1,0 0,-2 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 z"
+	 id="path66"
+	 inkscape:connector-curvature="0"
+	 style="clip-rule:evenodd" /></clipPath><clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath84"><path
+	 d="m 0,0 0,1895 4118,0 0,-136 -3,0 0,-1 -11,0 0,-1 -11,0 0,-1 -11,0 0,-1 -11,0 0,-1 5,0 0,-1 6,0 0,-1 7,0 0,-1 6,0 0,-1 6,0 0,-1 4,0 0,-1 -1,0 0,-1 -3,0 0,-1 -3,0 0,-1 -2,0 0,-1 -3,0 0,-1 -3,0 0,-1 -3,0 0,-1 -3,0 0,-1 -3,0 0,-1 -3,0 0,-1 -3,0 0,-1 7,0 0,1 11,0 0,1 11,0 0,1 11,0 0,1 3,0 L 4118,0 0,0 Z m 2552,1599 0,-1 2,0 0,1 11,0 0,1 11,0 0,1 11,0 0,1 11,0 0,1 -4,0 0,1 -7,0 0,1 -6,0 0,1 -7,0 0,1 -6,0 0,1 -3,0 0,1 2,0 0,1 2,0 0,1 3,0 0,1 3,0 0,1 3,0 0,1 3,0 0,1 3,0 0,1 2,0 0,1 3,0 0,1 3,0 0,1 3,0 0,1 -7,0 0,-1 -12,0 0,-1 -11,0 0,-1 -11,0 0,-1 -4,0 0,-1 1,0 0,-12 1,0 0,-4 z"
+	 id="path86"
+	 inkscape:connector-curvature="0"
+	 style="clip-rule:evenodd" /></clipPath><clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath104"><path
+	 d="m 0,0 0,1895 4118,0 L 4118,0 0,0 Z m 3056.98,1740.43 -1.58,18.9 -52.6,-4.72 38.74,-6.3 -36.85,-12.6 52.29,4.72 z m -1570.28,-123.79 1.58,-18.9 52.6,4.72 -38.43,5.99 36.54,12.91 -52.29,-4.72 z"
+	 id="path106"
+	 inkscape:connector-curvature="0"
+	 style="clip-rule:evenodd" /></clipPath></defs><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="997"
+     id="namedview4"
+     showgrid="false"
+     inkscape:zoom="0.99625351"
+     inkscape:cx="-73.227122"
+     inkscape:cy="114.17568"
+     inkscape:window-x="1920"
+     inkscape:window-y="30"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="g10"
+     units="mm"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" /><g
+     id="g10"
+     inkscape:groupmode="layer"
+     inkscape:label="crop"
+     transform="matrix(1.25,0,0,-1.25,-0.35237428,339.91141)"><path
+       d="m 411.08474,0.37218832 0,271.38551168 -37.17867,0 0,-1.94649 -205.3611,1.94649 0,-2.58046 -155.911966,0 0,-1.90192 17.977663,-264.3219406 -17.977663,0 0,-2.58119108 193.135216,0 0,2.58119108 -137.934309,0 0,264.3219406 333.650679,0 0,-264.3219406 -177.10547,0 0,-1.947197 149.52695,0 0,-0.63399408"
+       style="fill:#7f7f7f;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path16"
+       inkscape:connector-curvature="0" /><path
+       d="m 411.08474,0.37218832 0,271.38551168 -37.17867,0 0,-1.94649 -205.3611,1.94649 0,-2.58046 -155.911966,0 0,-1.90192 17.977663,-264.3219406 -17.977663,0 0,-2.58119108 193.135216,0 0,2.58119108 -137.934309,0 0,264.3219406 333.650679,0 0,-264.3219406 -177.10547,0 0,-1.947197 149.52695,0 0,-0.63399408 37.17867,0 z"
+       style="fill:none;stroke:#000000;stroke-width:0.33962813;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path18"
+       inkscape:connector-curvature="0" /><path
+       d="m 40.256106,6.8024838 366.979524,0 0,253.4078762 -366.979524,0 0,-253.4078762 z"
+       style="fill:none;stroke:#ff0000;stroke-width:0.33962813;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path20"
+       inkscape:connector-curvature="0" /><path
+       d="m 77.434066,7.4364707 316.352284,0 0,244.4416893 -316.352284,0 0,-244.4416893 z"
+       style="fill:none;stroke:#0000ff;stroke-width:0.33962813;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path22"
+       inkscape:connector-curvature="0" /><path
+       d="m 214.41669,149.49157 152.83195,0 0,81.51075 -152.83195,0 0,-81.51075 z"
+       style="fill:none;stroke:#00b000;stroke-width:0.33962813;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path24"
+       inkscape:connector-curvature="0" /><path
+       d="m 438.57126,37.414285 152.83194,0 0,213.966445 -152.83194,0 0,-213.966445 z"
+       style="fill:none;stroke:#d100d1;stroke-width:0.33962813;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path26"
+       inkscape:connector-curvature="0" /><path
+       d="m 0.45168907,271.7577 168.09328093,0 0,-2.58046 -155.911966,0 0,-1.90192 17.977663,0 0,-264.3219406 -17.977663,0 0,-2.58119108 -12.18131493,0"
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path28"
+       inkscape:connector-curvature="0" /><path
+       d="m 0.45168907,271.7577 168.09328093,0 0,-2.58046 -155.911966,0 0,-1.90192 17.977663,0 0,-264.3219406 -17.977663,0 0,-2.58119108 -12.18131493,0 0,271.38551168 z"
+       style="fill:none;stroke:#000000;stroke-width:0.33962813;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path30"
+       inkscape:connector-curvature="0" /><path
+       d="m 373.90607,0.37218832 0,0.63399408 -149.52695,0 0,1.947197 -18.6109,0 0,-2.58119108"
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path32"
+       inkscape:connector-curvature="0" /><path
+       d="m 373.90607,0.37218832 0,0.63399408 -149.52695,0 0,1.947197 -18.6109,0 0,-2.58119108 168.13785,0 z"
+       style="fill:none;stroke:#000000;stroke-width:0.33962813;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path34"
+       inkscape:connector-curvature="0" /><path
+       d="m 205.76822,271.7577 168.13785,0 0,-1.94649 -149.52695,0 0,-2.53589 -18.6109,0"
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path36"
+       inkscape:connector-curvature="0" /><path
+       d="m 205.76822,271.7577 168.13785,0 0,-1.94649 -149.52695,0 0,-2.53589 -18.6109,0 0,4.48238 z"
+       style="fill:none;stroke:#000000;stroke-width:0.33962813;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path38"
+       inkscape:connector-curvature="0" /><g
+       id="g40"
+       transform="matrix(0.14375794,0,0,0.14375794,-0.12334269,-0.08856738)"><g
+	 clip-path="url(#clipPath44)"
+	 id="g42"><path
+	   inkscape:connector-curvature="0"
+	   id="path48"
+	   style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	   d="M 1492.37,1040.5 3051.62,260.875" /></g></g><g
+       id="g50"
+       transform="matrix(0.14375794,0,0,0.14375794,-0.12334269,-0.08856738)"><path
+	 inkscape:connector-curvature="0"
+	 id="path52"
+	 style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+	 d="m 1539.31,1027.9 -37.8,8.19 29.29,-25.2 8.51,17.01" /><path
+	 inkscape:connector-curvature="0"
+	 id="path54"
+	 style="fill:none;stroke:#000000;stroke-width:4.7249999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 1539.31,1027.9 -37.8,8.19 29.29,-25.2 8.51,17.01 z" /><path
+	 inkscape:connector-curvature="0"
+	 id="path56"
+	 style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+	 d="m 3004.37,273.79 38.12,-8.505 -29.61,25.515 -8.51,-17.01" /><path
+	 inkscape:connector-curvature="0"
+	 id="path58"
+	 style="fill:none;stroke:#000000;stroke-width:4.7249999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 3004.37,273.79 38.12,-8.505 -29.61,25.515 -8.51,-17.01 z" /></g><g
+       id="g60"
+       transform="matrix(0.14375794,0,0,0.14375794,-0.12334269,-0.08856738)"><g
+	 clip-path="url(#clipPath64)"
+	 id="g62"><path
+	   inkscape:connector-curvature="0"
+	   id="path68"
+	   style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	   d="M 2555.5,1040.5 4114.75,260.875" /></g></g><g
+       id="g70"
+       transform="matrix(0.14375794,0,0,0.14375794,-0.12334269,-0.08856738)"><path
+	 inkscape:connector-curvature="0"
+	 id="path72"
+	 style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+	 d="m 2602.43,1027.9 -37.8,8.19 29.3,-25.2 8.5,17.01" /><path
+	 inkscape:connector-curvature="0"
+	 id="path74"
+	 style="fill:none;stroke:#000000;stroke-width:4.7249999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 2602.43,1027.9 -37.8,8.19 29.3,-25.2 8.5,17.01 z" /><path
+	 inkscape:connector-curvature="0"
+	 id="path76"
+	 style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+	 d="m 4067.5,273.79 38.11,-8.505 -29.61,25.515 -8.5,-17.01" /><path
+	 inkscape:connector-curvature="0"
+	 id="path78"
+	 style="fill:none;stroke:#000000;stroke-width:4.7249999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 4067.5,273.79 38.11,-8.505 -29.61,25.515 -8.5,-17.01 z" /></g><g
+       id="g80"
+       transform="matrix(0.14375794,0,0,0.14375794,-0.12334269,-0.08856738)"><g
+	 clip-path="url(#clipPath84)"
+	 id="g82"><path
+	   inkscape:connector-curvature="0"
+	   id="path88"
+	   style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	   d="m 2555.5,1607.5 1559.25,141.75" /></g></g><g
+       id="g90"
+       transform="matrix(0.14375794,0,0,0.14375794,-0.12334269,-0.08856738)"><path
+	 inkscape:connector-curvature="0"
+	 id="path92"
+	 style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+	 d="m 2602.12,1621.36 -36.54,-12.91 38.43,-5.99 -1.89,18.9" /><path
+	 inkscape:connector-curvature="0"
+	 id="path94"
+	 style="fill:none;stroke:#000000;stroke-width:4.7249999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 2602.12,1621.36 -36.54,-12.91 38.43,-5.99 -1.89,18.9 z" /><path
+	 inkscape:connector-curvature="0"
+	 id="path96"
+	 style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+	 d="m 4067.81,1735.71 36.86,12.6 -38.75,6.3 1.89,-18.9" /><path
+	 inkscape:connector-curvature="0"
+	 id="path98"
+	 style="fill:none;stroke:#000000;stroke-width:4.7249999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 4067.81,1735.71 36.86,12.6 -38.75,6.3 1.89,-18.9 z" /></g><g
+       id="g100"
+       transform="matrix(0.14375794,0,0,0.14375794,-0.12334269,-0.08856738)"><g
+	 clip-path="url(#clipPath104)"
+	 id="g102"><path
+	   inkscape:connector-curvature="0"
+	   id="path108"
+	   style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	   d="m 1492.37,1607.5 1559.25,141.75" /></g></g><path
+       d="m 221.11869,232.99481 -5.25292,-1.85592 5.52462,-0.86111 -0.2717,2.71703"
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path112"
+       inkscape:connector-curvature="0" /><path
+       d="m 221.11869,232.99481 -5.25292,-1.85592 5.52462,-0.86111 -0.2717,2.71703 z"
+       style="fill:none;stroke:#000000;stroke-width:0.67925626;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path114"
+       inkscape:connector-curvature="0" /><path
+       d="m 431.8247,249.43353 5.29748,1.81135 -5.56918,0.90567 0.2717,-2.71702"
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path116"
+       inkscape:connector-curvature="0" /><path
+       d="m 431.8247,249.43353 5.29748,1.81135 -5.56918,0.90567 0.2717,-2.71702 z"
+       style="fill:none;stroke:#000000;stroke-width:0.67925626;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path118"
+       inkscape:connector-curvature="0" /><g
+       id="g120"
+       transform="matrix(1.4375794,0,0,1.4375794,-0.12334269,-0.08856738)"><text
+	 transform="matrix(1,0,0,-1,204.52,9.07751)"
+	 style="font-variant:normal;font-weight:normal;font-size:6.61499977px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#d10000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+	 id="text122"><tspan
+	   x="0 3.3074999 6.9854398 8.45397 12.13191 15.80985 19.11735 21.320145 24.998085 28.676025 31.983524 35.661465 39.339405 41.178375 44.856316 48.534256 52.212196 55.890137 59.568073"
+	   y="0"
+	   sodipodi:role="line"
+	   id="tspan124">v4l2_cropcap.bounds</tspan></text>
+</g><g
+       id="g126"
+       transform="matrix(1.4375794,0,0,1.4375794,-0.12334269,-0.08856738)"><text
+	 transform="matrix(1,0,0,-1,58.5175,166.42)"
+	 style="font-variant:normal;font-weight:normal;font-size:6.61499977px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#0000d1;fill-opacity:1;fill-rule:nonzero;stroke:none"
+	 id="text128"><tspan
+	   x="0 3.3074999 6.9854398 8.45397 12.13191 15.80985 19.11735 21.320145 24.998085 28.676025 31.983524 35.661465 39.339405 41.178375 44.856316 48.534256 50.373226 52.576019 56.25396 59.561459"
+	   y="0"
+	   sodipodi:role="line"
+	   id="tspan130">v4l2_cropcap.defrect</tspan></text>
+</g><g
+       id="g132"
+       transform="matrix(1.4375794,0,0,1.4375794,-0.12334269,-0.08856738)"><text
+	 transform="matrix(1,0,0,-1,153.49,152.245)"
+	 style="font-variant:normal;font-weight:normal;font-size:6.61499977px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#008f00;fill-opacity:1;fill-rule:nonzero;stroke:none"
+	 id="text134"><tspan
+	   x="0 3.3074999 6.9854398 8.45397 12.13191 15.80985 19.11735 21.320145 24.998085 28.676025 30.514996"
+	   y="0"
+	   sodipodi:role="line"
+	   id="tspan136">v4l2_crop.c</tspan></text>
+</g><g
+       id="g138"
+       transform="matrix(1.4375794,0,0,1.4375794,-0.12334269,-0.08856738)"><text
+	 transform="matrix(1,0,0,-1,309.415,30.34)"
+	 style="font-variant:normal;font-weight:normal;font-size:6.61499977px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#b000b0;fill-opacity:1;fill-rule:nonzero;stroke:none"
+	 id="text140"><tspan
+	   x="0 3.3074999 6.9854398 8.45397 12.13191 15.80985 17.648821 21.326759 23.529554 29.03985 32.717789"
+	   y="0"
+	   sodipodi:role="line"
+	   id="tspan142">v4l2_format</tspan></text>
+</g><text
+       xml:space="preserve"
+       style="font-style:normal;font-weight:normal;font-size:32px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       x="-99.291145"
+       y="-239.49893"
+       id="text3396"
+       sodipodi:linespacing="125%"
+       transform="scale(1,-1)"><tspan
+	 sodipodi:role="line"
+	 id="tspan3398"
+	 x="-99.291145"
+	 y="-239.49893"></tspan><tspan
+	 sodipodi:role="line"
+	 x="-99.291145"
+	 y="-199.49893"
+	 id="tspan3400" /></text>
+</g></svg>
diff --git a/Documentation/userspace-api/media/v4l/depth-formats.rst b/Documentation/userspace-api/media/v4l/depth-formats.rst
new file mode 100644
index 000000000000..6742486a83b5
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/depth-formats.rst
@@ -0,0 +1,24 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _depth-formats:
+
+*************
+Depth Formats
+*************
+
+Depth data provides distance to points, mapped onto the image plane
+
+
+.. toctree::
+    :maxdepth: 1
+
+    pixfmt-inzi
+    pixfmt-z16
+    pixfmt-cnf4
diff --git a/Documentation/userspace-api/media/v4l/dev-capture.rst b/Documentation/userspace-api/media/v4l/dev-capture.rst
new file mode 100644
index 000000000000..44d3094093ab
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/dev-capture.rst
@@ -0,0 +1,111 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _capture:
+
+***********************
+Video Capture Interface
+***********************
+
+Video capture devices sample an analog video signal and store the
+digitized images in memory. Today nearly all devices can capture at full
+25 or 30 frames/second. With this interface applications can control the
+capture process and move images from the driver into user space.
+
+Conventionally V4L2 video capture devices are accessed through character
+device special files named ``/dev/video`` and ``/dev/video0`` to
+``/dev/video63`` with major number 81 and minor numbers 0 to 63.
+``/dev/video`` is typically a symbolic link to the preferred video
+device.
+
+.. note:: The same device file names are used for video output devices.
+
+
+Querying Capabilities
+=====================
+
+Devices supporting the video capture interface set the
+``V4L2_CAP_VIDEO_CAPTURE`` or ``V4L2_CAP_VIDEO_CAPTURE_MPLANE`` flag in
+the ``capabilities`` field of struct
+:c:type:`v4l2_capability` returned by the
+:ref:`VIDIOC_QUERYCAP` ioctl. As secondary device
+functions they may also support the :ref:`video overlay <overlay>`
+(``V4L2_CAP_VIDEO_OVERLAY``) and the :ref:`raw VBI capture <raw-vbi>`
+(``V4L2_CAP_VBI_CAPTURE``) interface. At least one of the read/write or
+streaming I/O methods must be supported. Tuners and audio inputs are
+optional.
+
+
+Supplemental Functions
+======================
+
+Video capture devices shall support :ref:`audio input <audio>`,
+:ref:`tuner`, :ref:`controls <control>`,
+:ref:`cropping and scaling <crop>` and
+:ref:`streaming parameter <streaming-par>` ioctls as needed. The
+:ref:`video input <video>` ioctls must be supported by all video
+capture devices.
+
+
+Image Format Negotiation
+========================
+
+The result of a capture operation is determined by cropping and image
+format parameters. The former select an area of the video picture to
+capture, the latter how images are stored in memory, i. e. in RGB or YUV
+format, the number of bits per pixel or width and height. Together they
+also define how images are scaled in the process.
+
+As usual these parameters are *not* reset at :ref:`open() <func-open>`
+time to permit Unix tool chains, programming a device and then reading
+from it as if it was a plain file. Well written V4L2 applications ensure
+they really get what they want, including cropping and scaling.
+
+Cropping initialization at minimum requires to reset the parameters to
+defaults. An example is given in :ref:`crop`.
+
+To query the current image format applications set the ``type`` field of
+a struct :c:type:`v4l2_format` to
+``V4L2_BUF_TYPE_VIDEO_CAPTURE`` or
+``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE`` and call the
+:ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` ioctl with a pointer to this
+structure. Drivers fill the struct
+:c:type:`v4l2_pix_format` ``pix`` or the struct
+:c:type:`v4l2_pix_format_mplane` ``pix_mp``
+member of the ``fmt`` union.
+
+To request different parameters applications set the ``type`` field of a
+struct :c:type:`v4l2_format` as above and initialize all
+fields of the struct :c:type:`v4l2_pix_format`
+``vbi`` member of the ``fmt`` union, or better just modify the results
+of :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>`, and call the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`
+ioctl with a pointer to this structure. Drivers may adjust the
+parameters and finally return the actual parameters as :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>`
+does.
+
+Like :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` the :ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` ioctl
+can be used to learn about hardware limitations without disabling I/O or
+possibly time consuming hardware preparations.
+
+The contents of struct :c:type:`v4l2_pix_format` and
+struct :c:type:`v4l2_pix_format_mplane` are
+discussed in :ref:`pixfmt`. See also the specification of the
+:ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>`, :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` and :ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` ioctls for
+details. Video capture devices must implement both the :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>`
+and :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl, even if :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ignores all
+requests and always returns default parameters as :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` does.
+:ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` is optional.
+
+
+Reading Images
+==============
+
+A video capture device may support the :ref:`read() function <func-read>`
+and/or streaming (:ref:`memory mapping <func-mmap>` or
+:ref:`user pointer <userp>`) I/O. See :ref:`io` for details.
diff --git a/Documentation/userspace-api/media/v4l/dev-decoder.rst b/Documentation/userspace-api/media/v4l/dev-decoder.rst
new file mode 100644
index 000000000000..606b54947e10
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/dev-decoder.rst
@@ -0,0 +1,1101 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. _decoder:
+
+*************************************************
+Memory-to-Memory Stateful Video Decoder Interface
+*************************************************
+
+A stateful video decoder takes complete chunks of the bytestream (e.g. Annex-B
+H.264/HEVC stream, raw VP8/9 stream) and decodes them into raw video frames in
+display order. The decoder is expected not to require any additional information
+from the client to process these buffers.
+
+Performing software parsing, processing etc. of the stream in the driver in
+order to support this interface is strongly discouraged. In case such
+operations are needed, use of the Stateless Video Decoder Interface (in
+development) is strongly advised.
+
+Conventions and Notations Used in This Document
+===============================================
+
+1. The general V4L2 API rules apply if not specified in this document
+   otherwise.
+
+2. The meaning of words "must", "may", "should", etc. is as per `RFC
+   2119 <https://tools.ietf.org/html/rfc2119>`_.
+
+3. All steps not marked "optional" are required.
+
+4. :c:func:`VIDIOC_G_EXT_CTRLS` and :c:func:`VIDIOC_S_EXT_CTRLS` may be used
+   interchangeably with :c:func:`VIDIOC_G_CTRL` and :c:func:`VIDIOC_S_CTRL`,
+   unless specified otherwise.
+
+5. Single-planar API (see :ref:`planar-apis`) and applicable structures may be
+   used interchangeably with multi-planar API, unless specified otherwise,
+   depending on decoder capabilities and following the general V4L2 guidelines.
+
+6. i = [a..b]: sequence of integers from a to b, inclusive, i.e. i =
+   [0..2]: i = 0, 1, 2.
+
+7. Given an ``OUTPUT`` buffer A, then A’ represents a buffer on the ``CAPTURE``
+   queue containing data that resulted from processing buffer A.
+
+.. _decoder-glossary:
+
+Glossary
+========
+
+CAPTURE
+   the destination buffer queue; for decoders, the queue of buffers containing
+   decoded frames; for encoders, the queue of buffers containing an encoded
+   bytestream; ``V4L2_BUF_TYPE_VIDEO_CAPTURE`` or
+   ``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE``; data is captured from the hardware
+   into ``CAPTURE`` buffers.
+
+client
+   the application communicating with the decoder or encoder implementing
+   this interface.
+
+coded format
+   encoded/compressed video bytestream format (e.g. H.264, VP8, etc.); see
+   also: raw format.
+
+coded height
+   height for given coded resolution.
+
+coded resolution
+   stream resolution in pixels aligned to codec and hardware requirements;
+   typically visible resolution rounded up to full macroblocks;
+   see also: visible resolution.
+
+coded width
+   width for given coded resolution.
+
+decode order
+   the order in which frames are decoded; may differ from display order if the
+   coded format includes a feature of frame reordering; for decoders,
+   ``OUTPUT`` buffers must be queued by the client in decode order; for
+   encoders ``CAPTURE`` buffers must be returned by the encoder in decode order.
+
+destination
+   data resulting from the decode process; see ``CAPTURE``.
+
+display order
+   the order in which frames must be displayed; for encoders, ``OUTPUT``
+   buffers must be queued by the client in display order; for decoders,
+   ``CAPTURE`` buffers must be returned by the decoder in display order.
+
+DPB
+   Decoded Picture Buffer; an H.264/HEVC term for a buffer that stores a decoded
+   raw frame available for reference in further decoding steps.
+
+EOS
+   end of stream.
+
+IDR
+   Instantaneous Decoder Refresh; a type of a keyframe in an H.264/HEVC-encoded
+   stream, which clears the list of earlier reference frames (DPBs).
+
+keyframe
+   an encoded frame that does not reference frames decoded earlier, i.e.
+   can be decoded fully on its own.
+
+macroblock
+   a processing unit in image and video compression formats based on linear
+   block transforms (e.g. H.264, VP8, VP9); codec-specific, but for most of
+   popular codecs the size is 16x16 samples (pixels).
+
+OUTPUT
+   the source buffer queue; for decoders, the queue of buffers containing
+   an encoded bytestream; for encoders, the queue of buffers containing raw
+   frames; ``V4L2_BUF_TYPE_VIDEO_OUTPUT`` or
+   ``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE``; the hardware is fed with data
+   from ``OUTPUT`` buffers.
+
+PPS
+   Picture Parameter Set; a type of metadata entity in an H.264/HEVC bytestream.
+
+raw format
+   uncompressed format containing raw pixel data (e.g. YUV, RGB formats).
+
+resume point
+   a point in the bytestream from which decoding may start/continue, without
+   any previous state/data present, e.g.: a keyframe (VP8/VP9) or
+   SPS/PPS/IDR sequence (H.264/HEVC); a resume point is required to start decode
+   of a new stream, or to resume decoding after a seek.
+
+source
+   data fed to the decoder or encoder; see ``OUTPUT``.
+
+source height
+   height in pixels for given source resolution; relevant to encoders only.
+
+source resolution
+   resolution in pixels of source frames being source to the encoder and
+   subject to further cropping to the bounds of visible resolution; relevant to
+   encoders only.
+
+source width
+   width in pixels for given source resolution; relevant to encoders only.
+
+SPS
+   Sequence Parameter Set; a type of metadata entity in an H.264/HEVC bytestream.
+
+stream metadata
+   additional (non-visual) information contained inside encoded bytestream;
+   for example: coded resolution, visible resolution, codec profile.
+
+visible height
+   height for given visible resolution; display height.
+
+visible resolution
+   stream resolution of the visible picture, in pixels, to be used for
+   display purposes; must be smaller or equal to coded resolution;
+   display resolution.
+
+visible width
+   width for given visible resolution; display width.
+
+State Machine
+=============
+
+.. kernel-render:: DOT
+   :alt: DOT digraph of decoder state machine
+   :caption: Decoder State Machine
+
+   digraph decoder_state_machine {
+       node [shape = doublecircle, label="Decoding"] Decoding;
+
+       node [shape = circle, label="Initialization"] Initialization;
+       node [shape = circle, label="Capture\nsetup"] CaptureSetup;
+       node [shape = circle, label="Dynamic\nResolution\nChange"] ResChange;
+       node [shape = circle, label="Stopped"] Stopped;
+       node [shape = circle, label="Drain"] Drain;
+       node [shape = circle, label="Seek"] Seek;
+       node [shape = circle, label="End of Stream"] EoS;
+
+       node [shape = point]; qi
+       qi -> Initialization [ label = "open()" ];
+
+       Initialization -> CaptureSetup [ label = "CAPTURE\nformat\nestablished" ];
+
+       CaptureSetup -> Stopped [ label = "CAPTURE\nbuffers\nready" ];
+
+       Decoding -> ResChange [ label = "Stream\nresolution\nchange" ];
+       Decoding -> Drain [ label = "V4L2_DEC_CMD_STOP" ];
+       Decoding -> EoS [ label = "EoS mark\nin the stream" ];
+       Decoding -> Seek [ label = "VIDIOC_STREAMOFF(OUTPUT)" ];
+       Decoding -> Stopped [ label = "VIDIOC_STREAMOFF(CAPTURE)" ];
+       Decoding -> Decoding;
+
+       ResChange -> CaptureSetup [ label = "CAPTURE\nformat\nestablished" ];
+       ResChange -> Seek [ label = "VIDIOC_STREAMOFF(OUTPUT)" ];
+
+       EoS -> Drain [ label = "Implicit\ndrain" ];
+
+       Drain -> Stopped [ label = "All CAPTURE\nbuffers dequeued\nor\nVIDIOC_STREAMOFF(CAPTURE)" ];
+       Drain -> Seek [ label = "VIDIOC_STREAMOFF(OUTPUT)" ];
+
+       Seek -> Decoding [ label = "VIDIOC_STREAMON(OUTPUT)" ];
+       Seek -> Initialization [ label = "VIDIOC_REQBUFS(OUTPUT, 0)" ];
+
+       Stopped -> Decoding [ label = "V4L2_DEC_CMD_START\nor\nVIDIOC_STREAMON(CAPTURE)" ];
+       Stopped -> Seek [ label = "VIDIOC_STREAMOFF(OUTPUT)" ];
+   }
+
+Querying Capabilities
+=====================
+
+1. To enumerate the set of coded formats supported by the decoder, the
+   client may call :c:func:`VIDIOC_ENUM_FMT` on ``OUTPUT``.
+
+   * The full set of supported formats will be returned, regardless of the
+     format set on ``CAPTURE``.
+   * Check the flags field of :c:type:`v4l2_fmtdesc` for more information
+     about the decoder's capabilities with respect to each coded format.
+     In particular whether or not the decoder has a full-fledged bytestream
+     parser and if the decoder supports dynamic resolution changes.
+
+2. To enumerate the set of supported raw formats, the client may call
+   :c:func:`VIDIOC_ENUM_FMT` on ``CAPTURE``.
+
+   * Only the formats supported for the format currently active on ``OUTPUT``
+     will be returned.
+
+   * In order to enumerate raw formats supported by a given coded format,
+     the client must first set that coded format on ``OUTPUT`` and then
+     enumerate formats on ``CAPTURE``.
+
+3. The client may use :c:func:`VIDIOC_ENUM_FRAMESIZES` to detect supported
+   resolutions for a given format, passing desired pixel format in
+   :c:type:`v4l2_frmsizeenum` ``pixel_format``.
+
+   * Values returned by :c:func:`VIDIOC_ENUM_FRAMESIZES` for a coded pixel
+     format will include all possible coded resolutions supported by the
+     decoder for given coded pixel format.
+
+   * Values returned by :c:func:`VIDIOC_ENUM_FRAMESIZES` for a raw pixel format
+     will include all possible frame buffer resolutions supported by the
+     decoder for given raw pixel format and the coded format currently set on
+     ``OUTPUT``.
+
+4. Supported profiles and levels for the coded format currently set on
+   ``OUTPUT``, if applicable, may be queried using their respective controls
+   via :c:func:`VIDIOC_QUERYCTRL`.
+
+Initialization
+==============
+
+1. Set the coded format on ``OUTPUT`` via :c:func:`VIDIOC_S_FMT`
+
+   * **Required fields:**
+
+     ``type``
+         a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.
+
+     ``pixelformat``
+         a coded pixel format.
+
+     ``width``, ``height``
+         coded resolution of the stream; required only if it cannot be parsed
+         from the stream for the given coded format; otherwise the decoder will
+         use this resolution as a placeholder resolution that will likely change
+         as soon as it can parse the actual coded resolution from the stream.
+
+     ``sizeimage``
+         desired size of ``OUTPUT`` buffers; the decoder may adjust it to
+         match hardware requirements.
+
+     other fields
+         follow standard semantics.
+
+   * **Return fields:**
+
+     ``sizeimage``
+         adjusted size of ``OUTPUT`` buffers.
+
+   * The ``CAPTURE`` format will be updated with an appropriate frame buffer
+     resolution instantly based on the width and height returned by
+     :c:func:`VIDIOC_S_FMT`.
+     However, for coded formats that include stream resolution information,
+     after the decoder is done parsing the information from the stream, it will
+     update the ``CAPTURE`` format with new values and signal a source change
+     event, regardless of whether they match the values set by the client or
+     not.
+
+   .. important::
+
+      Changing the ``OUTPUT`` format may change the currently set ``CAPTURE``
+      format. How the new ``CAPTURE`` format is determined is up to the decoder
+      and the client must ensure it matches its needs afterwards.
+
+2.  Allocate source (bytestream) buffers via :c:func:`VIDIOC_REQBUFS` on
+    ``OUTPUT``.
+
+    * **Required fields:**
+
+      ``count``
+          requested number of buffers to allocate; greater than zero.
+
+      ``type``
+          a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.
+
+      ``memory``
+          follows standard semantics.
+
+    * **Return fields:**
+
+      ``count``
+          the actual number of buffers allocated.
+
+    .. warning::
+
+       The actual number of allocated buffers may differ from the ``count``
+       given. The client must check the updated value of ``count`` after the
+       call returns.
+
+    Alternatively, :c:func:`VIDIOC_CREATE_BUFS` on the ``OUTPUT`` queue can be
+    used to have more control over buffer allocation.
+
+    * **Required fields:**
+
+      ``count``
+          requested number of buffers to allocate; greater than zero.
+
+      ``type``
+          a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.
+
+      ``memory``
+          follows standard semantics.
+
+      ``format``
+          follows standard semantics.
+
+    * **Return fields:**
+
+      ``count``
+          adjusted to the number of allocated buffers.
+
+    .. warning::
+
+       The actual number of allocated buffers may differ from the ``count``
+       given. The client must check the updated value of ``count`` after the
+       call returns.
+
+3.  Start streaming on the ``OUTPUT`` queue via :c:func:`VIDIOC_STREAMON`.
+
+4.  **This step only applies to coded formats that contain resolution information
+    in the stream.** Continue queuing/dequeuing bytestream buffers to/from the
+    ``OUTPUT`` queue via :c:func:`VIDIOC_QBUF` and :c:func:`VIDIOC_DQBUF`. The
+    buffers will be processed and returned to the client in order, until
+    required metadata to configure the ``CAPTURE`` queue are found. This is
+    indicated by the decoder sending a ``V4L2_EVENT_SOURCE_CHANGE`` event with
+    ``changes`` set to ``V4L2_EVENT_SRC_CH_RESOLUTION``.
+
+    * It is not an error if the first buffer does not contain enough data for
+      this to occur. Processing of the buffers will continue as long as more
+      data is needed.
+
+    * If data in a buffer that triggers the event is required to decode the
+      first frame, it will not be returned to the client, until the
+      initialization sequence completes and the frame is decoded.
+
+    * If the client has not set the coded resolution of the stream on its own,
+      calling :c:func:`VIDIOC_G_FMT`, :c:func:`VIDIOC_S_FMT`,
+      :c:func:`VIDIOC_TRY_FMT` or :c:func:`VIDIOC_REQBUFS` on the ``CAPTURE``
+      queue will not return the real values for the stream until a
+      ``V4L2_EVENT_SOURCE_CHANGE`` event with ``changes`` set to
+      ``V4L2_EVENT_SRC_CH_RESOLUTION`` is signaled.
+
+    .. important::
+
+       Any client query issued after the decoder queues the event will return
+       values applying to the just parsed stream, including queue formats,
+       selection rectangles and controls.
+
+    .. note::
+
+       A client capable of acquiring stream parameters from the bytestream on
+       its own may attempt to set the width and height of the ``OUTPUT`` format
+       to non-zero values matching the coded size of the stream, skip this step
+       and continue with the `Capture Setup` sequence. However, it must not
+       rely on any driver queries regarding stream parameters, such as
+       selection rectangles and controls, since the decoder has not parsed them
+       from the stream yet. If the values configured by the client do not match
+       those parsed by the decoder, a `Dynamic Resolution Change` will be
+       triggered to reconfigure them.
+
+    .. note::
+
+       No decoded frames are produced during this phase.
+
+5.  Continue with the `Capture Setup` sequence.
+
+Capture Setup
+=============
+
+1.  Call :c:func:`VIDIOC_G_FMT` on the ``CAPTURE`` queue to get format for the
+    destination buffers parsed/decoded from the bytestream.
+
+    * **Required fields:**
+
+      ``type``
+          a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
+
+    * **Return fields:**
+
+      ``width``, ``height``
+          frame buffer resolution for the decoded frames.
+
+      ``pixelformat``
+          pixel format for decoded frames.
+
+      ``num_planes`` (for _MPLANE ``type`` only)
+          number of planes for pixelformat.
+
+      ``sizeimage``, ``bytesperline``
+          as per standard semantics; matching frame buffer format.
+
+    .. note::
+
+       The value of ``pixelformat`` may be any pixel format supported by the
+       decoder for the current stream. The decoder should choose a
+       preferred/optimal format for the default configuration. For example, a
+       YUV format may be preferred over an RGB format if an additional
+       conversion step would be required for the latter.
+
+2.  **Optional.** Acquire the visible resolution via
+    :c:func:`VIDIOC_G_SELECTION`.
+
+    * **Required fields:**
+
+      ``type``
+          a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
+
+      ``target``
+          set to ``V4L2_SEL_TGT_COMPOSE``.
+
+    * **Return fields:**
+
+      ``r.left``, ``r.top``, ``r.width``, ``r.height``
+          the visible rectangle; it must fit within the frame buffer resolution
+          returned by :c:func:`VIDIOC_G_FMT` on ``CAPTURE``.
+
+    * The following selection targets are supported on ``CAPTURE``:
+
+      ``V4L2_SEL_TGT_CROP_BOUNDS``
+          corresponds to the coded resolution of the stream.
+
+      ``V4L2_SEL_TGT_CROP_DEFAULT``
+          the rectangle covering the part of the ``CAPTURE`` buffer that
+          contains meaningful picture data (visible area); width and height
+          will be equal to the visible resolution of the stream.
+
+      ``V4L2_SEL_TGT_CROP``
+          the rectangle within the coded resolution to be output to
+          ``CAPTURE``; defaults to ``V4L2_SEL_TGT_CROP_DEFAULT``; read-only on
+          hardware without additional compose/scaling capabilities.
+
+      ``V4L2_SEL_TGT_COMPOSE_BOUNDS``
+          the maximum rectangle within a ``CAPTURE`` buffer, which the cropped
+          frame can be composed into; equal to ``V4L2_SEL_TGT_CROP`` if the
+          hardware does not support compose/scaling.
+
+      ``V4L2_SEL_TGT_COMPOSE_DEFAULT``
+          equal to ``V4L2_SEL_TGT_CROP``.
+
+      ``V4L2_SEL_TGT_COMPOSE``
+          the rectangle inside a ``CAPTURE`` buffer into which the cropped
+          frame is written; defaults to ``V4L2_SEL_TGT_COMPOSE_DEFAULT``;
+          read-only on hardware without additional compose/scaling capabilities.
+
+      ``V4L2_SEL_TGT_COMPOSE_PADDED``
+          the rectangle inside a ``CAPTURE`` buffer which is overwritten by the
+          hardware; equal to ``V4L2_SEL_TGT_COMPOSE`` if the hardware does not
+          write padding pixels.
+
+    .. warning::
+
+       The values are guaranteed to be meaningful only after the decoder
+       successfully parses the stream metadata. The client must not rely on the
+       query before that happens.
+
+3.  **Optional.** Enumerate ``CAPTURE`` formats via :c:func:`VIDIOC_ENUM_FMT` on
+    the ``CAPTURE`` queue. Once the stream information is parsed and known, the
+    client may use this ioctl to discover which raw formats are supported for
+    given stream and select one of them via :c:func:`VIDIOC_S_FMT`.
+
+    .. important::
+
+       The decoder will return only formats supported for the currently
+       established coded format, as per the ``OUTPUT`` format and/or stream
+       metadata parsed in this initialization sequence, even if more formats
+       may be supported by the decoder in general. In other words, the set
+       returned will be a subset of the initial query mentioned in the
+       `Querying Capabilities` section.
+
+       For example, a decoder may support YUV and RGB formats for resolutions
+       1920x1088 and lower, but only YUV for higher resolutions (due to
+       hardware limitations). After parsing a resolution of 1920x1088 or lower,
+       :c:func:`VIDIOC_ENUM_FMT` may return a set of YUV and RGB pixel formats,
+       but after parsing resolution higher than 1920x1088, the decoder will not
+       return RGB, unsupported for this resolution.
+
+       However, subsequent resolution change event triggered after
+       discovering a resolution change within the same stream may switch
+       the stream into a lower resolution and :c:func:`VIDIOC_ENUM_FMT`
+       would return RGB formats again in that case.
+
+4.  **Optional.** Set the ``CAPTURE`` format via :c:func:`VIDIOC_S_FMT` on the
+    ``CAPTURE`` queue. The client may choose a different format than
+    selected/suggested by the decoder in :c:func:`VIDIOC_G_FMT`.
+
+    * **Required fields:**
+
+      ``type``
+          a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
+
+      ``pixelformat``
+          a raw pixel format.
+
+      ``width``, ``height``
+         frame buffer resolution of the decoded stream; typically unchanged from
+	 what was returned with :c:func:`VIDIOC_G_FMT`, but it may be different
+	 if the hardware supports composition and/or scaling.
+
+   * Setting the ``CAPTURE`` format will reset the compose selection rectangles
+     to their default values, based on the new resolution, as described in the
+     previous step.
+
+5. **Optional.** Set the compose rectangle via :c:func:`VIDIOC_S_SELECTION` on
+   the ``CAPTURE`` queue if it is desired and if the decoder has compose and/or
+   scaling capabilities.
+
+   * **Required fields:**
+
+     ``type``
+         a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
+
+     ``target``
+         set to ``V4L2_SEL_TGT_COMPOSE``.
+
+     ``r.left``, ``r.top``, ``r.width``, ``r.height``
+         the rectangle inside a ``CAPTURE`` buffer into which the cropped
+         frame is written; defaults to ``V4L2_SEL_TGT_COMPOSE_DEFAULT``;
+         read-only on hardware without additional compose/scaling capabilities.
+
+   * **Return fields:**
+
+     ``r.left``, ``r.top``, ``r.width``, ``r.height``
+         the visible rectangle; it must fit within the frame buffer resolution
+         returned by :c:func:`VIDIOC_G_FMT` on ``CAPTURE``.
+
+   .. warning::
+
+      The decoder may adjust the compose rectangle to the nearest
+      supported one to meet codec and hardware requirements. The client needs
+      to check the adjusted rectangle returned by :c:func:`VIDIOC_S_SELECTION`.
+
+6.  If all the following conditions are met, the client may resume the decoding
+    instantly:
+
+    * ``sizeimage`` of the new format (determined in previous steps) is less
+      than or equal to the size of currently allocated buffers,
+
+    * the number of buffers currently allocated is greater than or equal to the
+      minimum number of buffers acquired in previous steps. To fulfill this
+      requirement, the client may use :c:func:`VIDIOC_CREATE_BUFS` to add new
+      buffers.
+
+    In that case, the remaining steps do not apply and the client may resume
+    the decoding by one of the following actions:
+
+    * if the ``CAPTURE`` queue is streaming, call :c:func:`VIDIOC_DECODER_CMD`
+      with the ``V4L2_DEC_CMD_START`` command,
+
+    * if the ``CAPTURE`` queue is not streaming, call :c:func:`VIDIOC_STREAMON`
+      on the ``CAPTURE`` queue.
+
+    However, if the client intends to change the buffer set, to lower
+    memory usage or for any other reasons, it may be achieved by following
+    the steps below.
+
+7.  **If the** ``CAPTURE`` **queue is streaming,** keep queuing and dequeuing
+    buffers on the ``CAPTURE`` queue until a buffer marked with the
+    ``V4L2_BUF_FLAG_LAST`` flag is dequeued.
+
+8.  **If the** ``CAPTURE`` **queue is streaming,** call :c:func:`VIDIOC_STREAMOFF`
+    on the ``CAPTURE`` queue to stop streaming.
+
+    .. warning::
+
+       The ``OUTPUT`` queue must remain streaming. Calling
+       :c:func:`VIDIOC_STREAMOFF` on it would abort the sequence and trigger a
+       seek.
+
+9.  **If the** ``CAPTURE`` **queue has buffers allocated,** free the ``CAPTURE``
+    buffers using :c:func:`VIDIOC_REQBUFS`.
+
+    * **Required fields:**
+
+      ``count``
+          set to 0.
+
+      ``type``
+          a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
+
+      ``memory``
+          follows standard semantics.
+
+10. Allocate ``CAPTURE`` buffers via :c:func:`VIDIOC_REQBUFS` on the
+    ``CAPTURE`` queue.
+
+    * **Required fields:**
+
+      ``count``
+          requested number of buffers to allocate; greater than zero.
+
+      ``type``
+          a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
+
+      ``memory``
+          follows standard semantics.
+
+    * **Return fields:**
+
+      ``count``
+          actual number of buffers allocated.
+
+    .. warning::
+
+       The actual number of allocated buffers may differ from the ``count``
+       given. The client must check the updated value of ``count`` after the
+       call returns.
+
+    .. note::
+
+       To allocate more than the minimum number of buffers (for pipeline
+       depth), the client may query the ``V4L2_CID_MIN_BUFFERS_FOR_CAPTURE``
+       control to get the minimum number of buffers required, and pass the
+       obtained value plus the number of additional buffers needed in the
+       ``count`` field to :c:func:`VIDIOC_REQBUFS`.
+
+    Alternatively, :c:func:`VIDIOC_CREATE_BUFS` on the ``CAPTURE`` queue can be
+    used to have more control over buffer allocation. For example, by
+    allocating buffers larger than the current ``CAPTURE`` format, future
+    resolution changes can be accommodated.
+
+    * **Required fields:**
+
+      ``count``
+          requested number of buffers to allocate; greater than zero.
+
+      ``type``
+          a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
+
+      ``memory``
+          follows standard semantics.
+
+      ``format``
+          a format representing the maximum framebuffer resolution to be
+          accommodated by newly allocated buffers.
+
+    * **Return fields:**
+
+      ``count``
+          adjusted to the number of allocated buffers.
+
+    .. warning::
+
+        The actual number of allocated buffers may differ from the ``count``
+        given. The client must check the updated value of ``count`` after the
+        call returns.
+
+    .. note::
+
+       To allocate buffers for a format different than parsed from the stream
+       metadata, the client must proceed as follows, before the metadata
+       parsing is initiated:
+
+       * set width and height of the ``OUTPUT`` format to desired coded resolution to
+         let the decoder configure the ``CAPTURE`` format appropriately,
+
+       * query the ``CAPTURE`` format using :c:func:`VIDIOC_G_FMT` and save it
+         until this step.
+
+       The format obtained in the query may be then used with
+       :c:func:`VIDIOC_CREATE_BUFS` in this step to allocate the buffers.
+
+11. Call :c:func:`VIDIOC_STREAMON` on the ``CAPTURE`` queue to start decoding
+    frames.
+
+Decoding
+========
+
+This state is reached after the `Capture Setup` sequence finishes successfully.
+In this state, the client queues and dequeues buffers to both queues via
+:c:func:`VIDIOC_QBUF` and :c:func:`VIDIOC_DQBUF`, following the standard
+semantics.
+
+The content of the source ``OUTPUT`` buffers depends on the active coded pixel
+format and may be affected by codec-specific extended controls, as stated in
+the documentation of each format.
+
+Both queues operate independently, following the standard behavior of V4L2
+buffer queues and memory-to-memory devices. In addition, the order of decoded
+frames dequeued from the ``CAPTURE`` queue may differ from the order of queuing
+coded frames to the ``OUTPUT`` queue, due to properties of the selected coded
+format, e.g. frame reordering.
+
+The client must not assume any direct relationship between ``CAPTURE``
+and ``OUTPUT`` buffers and any specific timing of buffers becoming
+available to dequeue. Specifically:
+
+* a buffer queued to ``OUTPUT`` may result in no buffers being produced
+  on ``CAPTURE`` (e.g. if it does not contain encoded data, or if only
+  metadata syntax structures are present in it),
+
+* a buffer queued to ``OUTPUT`` may result in more than one buffer produced
+  on ``CAPTURE`` (if the encoded data contained more than one frame, or if
+  returning a decoded frame allowed the decoder to return a frame that
+  preceded it in decode, but succeeded it in the display order),
+
+* a buffer queued to ``OUTPUT`` may result in a buffer being produced on
+  ``CAPTURE`` later into decode process, and/or after processing further
+  ``OUTPUT`` buffers, or be returned out of order, e.g. if display
+  reordering is used,
+
+* buffers may become available on the ``CAPTURE`` queue without additional
+  buffers queued to ``OUTPUT`` (e.g. during drain or ``EOS``), because of the
+  ``OUTPUT`` buffers queued in the past whose decoding results are only
+  available at later time, due to specifics of the decoding process.
+
+.. note::
+
+   To allow matching decoded ``CAPTURE`` buffers with ``OUTPUT`` buffers they
+   originated from, the client can set the ``timestamp`` field of the
+   :c:type:`v4l2_buffer` struct when queuing an ``OUTPUT`` buffer. The
+   ``CAPTURE`` buffer(s), which resulted from decoding that ``OUTPUT`` buffer
+   will have their ``timestamp`` field set to the same value when dequeued.
+
+   In addition to the straightforward case of one ``OUTPUT`` buffer producing
+   one ``CAPTURE`` buffer, the following cases are defined:
+
+   * one ``OUTPUT`` buffer generates multiple ``CAPTURE`` buffers: the same
+     ``OUTPUT`` timestamp will be copied to multiple ``CAPTURE`` buffers.
+
+   * multiple ``OUTPUT`` buffers generate one ``CAPTURE`` buffer: timestamp of
+     the ``OUTPUT`` buffer queued first will be copied.
+
+   * the decoding order differs from the display order (i.e. the ``CAPTURE``
+     buffers are out-of-order compared to the ``OUTPUT`` buffers): ``CAPTURE``
+     timestamps will not retain the order of ``OUTPUT`` timestamps.
+
+During the decoding, the decoder may initiate one of the special sequences, as
+listed below. The sequences will result in the decoder returning all the
+``CAPTURE`` buffers that originated from all the ``OUTPUT`` buffers processed
+before the sequence started. Last of the buffers will have the
+``V4L2_BUF_FLAG_LAST`` flag set. To determine the sequence to follow, the client
+must check if there is any pending event and:
+
+* if a ``V4L2_EVENT_SOURCE_CHANGE`` event with ``changes`` set to
+  ``V4L2_EVENT_SRC_CH_RESOLUTION`` is pending, the `Dynamic Resolution
+  Change` sequence needs to be followed,
+
+* if a ``V4L2_EVENT_EOS`` event is pending, the `End of Stream` sequence needs
+  to be followed.
+
+Some of the sequences can be intermixed with each other and need to be handled
+as they happen. The exact operation is documented for each sequence.
+
+Should a decoding error occur, it will be reported to the client with the level
+of details depending on the decoder capabilities. Specifically:
+
+* the CAPTURE buffer that contains the results of the failed decode operation
+  will be returned with the V4L2_BUF_FLAG_ERROR flag set,
+
+* if the decoder is able to precisely report the OUTPUT buffer that triggered
+  the error, such buffer will be returned with the V4L2_BUF_FLAG_ERROR flag
+  set.
+
+In case of a fatal failure that does not allow the decoding to continue, any
+further operations on corresponding decoder file handle will return the -EIO
+error code. The client may close the file handle and open a new one, or
+alternatively reinitialize the instance by stopping streaming on both queues,
+releasing all buffers and performing the Initialization sequence again.
+
+Seek
+====
+
+Seek is controlled by the ``OUTPUT`` queue, as it is the source of coded data.
+The seek does not require any specific operation on the ``CAPTURE`` queue, but
+it may be affected as per normal decoder operation.
+
+1. Stop the ``OUTPUT`` queue to begin the seek sequence via
+   :c:func:`VIDIOC_STREAMOFF`.
+
+   * **Required fields:**
+
+     ``type``
+         a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.
+
+   * The decoder will drop all the pending ``OUTPUT`` buffers and they must be
+     treated as returned to the client (following standard semantics).
+
+2. Restart the ``OUTPUT`` queue via :c:func:`VIDIOC_STREAMON`
+
+   * **Required fields:**
+
+     ``type``
+         a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.
+
+   * The decoder will start accepting new source bytestream buffers after the
+     call returns.
+
+3. Start queuing buffers containing coded data after the seek to the ``OUTPUT``
+   queue until a suitable resume point is found.
+
+   .. note::
+
+      There is no requirement to begin queuing coded data starting exactly
+      from a resume point (e.g. SPS or a keyframe). Any queued ``OUTPUT``
+      buffers will be processed and returned to the client until a suitable
+      resume point is found.  While looking for a resume point, the decoder
+      should not produce any decoded frames into ``CAPTURE`` buffers.
+
+      Some hardware is known to mishandle seeks to a non-resume point. Such an
+      operation may result in an unspecified number of corrupted decoded frames
+      being made available on the ``CAPTURE`` queue. Drivers must ensure that
+      no fatal decoding errors or crashes occur, and implement any necessary
+      handling and workarounds for hardware issues related to seek operations.
+
+   .. warning::
+
+      In case of the H.264/HEVC codec, the client must take care not to seek
+      over a change of SPS/PPS. Even though the target frame could be a
+      keyframe, the stale SPS/PPS inside decoder state would lead to undefined
+      results when decoding. Although the decoder must handle that case without
+      a crash or a fatal decode error, the client must not expect a sensible
+      decode output.
+
+      If the hardware can detect such corrupted decoded frames, then
+      corresponding buffers will be returned to the client with the
+      V4L2_BUF_FLAG_ERROR set. See the `Decoding` section for further
+      description of decode error reporting.
+
+4. After a resume point is found, the decoder will start returning ``CAPTURE``
+   buffers containing decoded frames.
+
+.. important::
+
+   A seek may result in the `Dynamic Resolution Change` sequence being
+   initiated, due to the seek target having decoding parameters different from
+   the part of the stream decoded before the seek. The sequence must be handled
+   as per normal decoder operation.
+
+.. warning::
+
+   It is not specified when the ``CAPTURE`` queue starts producing buffers
+   containing decoded data from the ``OUTPUT`` buffers queued after the seek,
+   as it operates independently from the ``OUTPUT`` queue.
+
+   The decoder may return a number of remaining ``CAPTURE`` buffers containing
+   decoded frames originating from the ``OUTPUT`` buffers queued before the
+   seek sequence is performed.
+
+   The ``VIDIOC_STREAMOFF`` operation discards any remaining queued
+   ``OUTPUT`` buffers, which means that not all of the ``OUTPUT`` buffers
+   queued before the seek sequence may have matching ``CAPTURE`` buffers
+   produced.  For example, given the sequence of operations on the
+   ``OUTPUT`` queue:
+
+     QBUF(A), QBUF(B), STREAMOFF(), STREAMON(), QBUF(G), QBUF(H),
+
+   any of the following results on the ``CAPTURE`` queue is allowed:
+
+     {A’, B’, G’, H’}, {A’, G’, H’}, {G’, H’}.
+
+   To determine the CAPTURE buffer containing the first decoded frame after the
+   seek, the client may observe the timestamps to match the CAPTURE and OUTPUT
+   buffers or use V4L2_DEC_CMD_STOP and V4L2_DEC_CMD_START to drain the
+   decoder.
+
+.. note::
+
+   To achieve instantaneous seek, the client may restart streaming on the
+   ``CAPTURE`` queue too to discard decoded, but not yet dequeued buffers.
+
+Dynamic Resolution Change
+=========================
+
+Streams that include resolution metadata in the bytestream may require switching
+to a different resolution during the decoding.
+
+.. note::
+
+   Not all decoders can detect resolution changes. Those that do set the
+   ``V4L2_FMT_FLAG_DYN_RESOLUTION`` flag for the coded format when
+   :c:func:`VIDIOC_ENUM_FMT` is called.
+
+The sequence starts when the decoder detects a coded frame with one or more of
+the following parameters different from those previously established (and
+reflected by corresponding queries):
+
+* coded resolution (``OUTPUT`` width and height),
+
+* visible resolution (selection rectangles),
+
+* the minimum number of buffers needed for decoding.
+
+Whenever that happens, the decoder must proceed as follows:
+
+1.  After encountering a resolution change in the stream, the decoder sends a
+    ``V4L2_EVENT_SOURCE_CHANGE`` event with ``changes`` set to
+    ``V4L2_EVENT_SRC_CH_RESOLUTION``.
+
+    .. important::
+
+       Any client query issued after the decoder queues the event will return
+       values applying to the stream after the resolution change, including
+       queue formats, selection rectangles and controls.
+
+2.  The decoder will then process and decode all remaining buffers from before
+    the resolution change point.
+
+    * The last buffer from before the change must be marked with the
+      ``V4L2_BUF_FLAG_LAST`` flag, similarly to the `Drain` sequence above.
+
+    .. warning::
+
+       The last buffer may be empty (with :c:type:`v4l2_buffer` ``bytesused``
+       = 0) and in that case it must be ignored by the client, as it does not
+       contain a decoded frame.
+
+    .. note::
+
+       Any attempt to dequeue more ``CAPTURE`` buffers beyond the buffer marked
+       with ``V4L2_BUF_FLAG_LAST`` will result in a -EPIPE error from
+       :c:func:`VIDIOC_DQBUF`.
+
+The client must continue the sequence as described below to continue the
+decoding process.
+
+1.  Dequeue the source change event.
+
+    .. important::
+
+       A source change triggers an implicit decoder drain, similar to the
+       explicit `Drain` sequence. The decoder is stopped after it completes.
+       The decoding process must be resumed with either a pair of calls to
+       :c:func:`VIDIOC_STREAMOFF` and :c:func:`VIDIOC_STREAMON` on the
+       ``CAPTURE`` queue, or a call to :c:func:`VIDIOC_DECODER_CMD` with the
+       ``V4L2_DEC_CMD_START`` command.
+
+2.  Continue with the `Capture Setup` sequence.
+
+.. note::
+
+   During the resolution change sequence, the ``OUTPUT`` queue must remain
+   streaming. Calling :c:func:`VIDIOC_STREAMOFF` on the ``OUTPUT`` queue would
+   abort the sequence and initiate a seek.
+
+   In principle, the ``OUTPUT`` queue operates separately from the ``CAPTURE``
+   queue and this remains true for the duration of the entire resolution change
+   sequence as well.
+
+   The client should, for best performance and simplicity, keep queuing/dequeuing
+   buffers to/from the ``OUTPUT`` queue even while processing this sequence.
+
+Drain
+=====
+
+To ensure that all queued ``OUTPUT`` buffers have been processed and related
+``CAPTURE`` buffers are given to the client, the client must follow the drain
+sequence described below. After the drain sequence ends, the client has
+received all decoded frames for all ``OUTPUT`` buffers queued before the
+sequence was started.
+
+1. Begin drain by issuing :c:func:`VIDIOC_DECODER_CMD`.
+
+   * **Required fields:**
+
+     ``cmd``
+         set to ``V4L2_DEC_CMD_STOP``.
+
+     ``flags``
+         set to 0.
+
+     ``pts``
+         set to 0.
+
+   .. warning::
+
+      The sequence can be only initiated if both ``OUTPUT`` and ``CAPTURE``
+      queues are streaming. For compatibility reasons, the call to
+      :c:func:`VIDIOC_DECODER_CMD` will not fail even if any of the queues is
+      not streaming, but at the same time it will not initiate the `Drain`
+      sequence and so the steps described below would not be applicable.
+
+2. Any ``OUTPUT`` buffers queued by the client before the
+   :c:func:`VIDIOC_DECODER_CMD` was issued will be processed and decoded as
+   normal. The client must continue to handle both queues independently,
+   similarly to normal decode operation. This includes:
+
+   * handling any operations triggered as a result of processing those buffers,
+     such as the `Dynamic Resolution Change` sequence, before continuing with
+     the drain sequence,
+
+   * queuing and dequeuing ``CAPTURE`` buffers, until a buffer marked with the
+     ``V4L2_BUF_FLAG_LAST`` flag is dequeued,
+
+     .. warning::
+
+        The last buffer may be empty (with :c:type:`v4l2_buffer`
+        ``bytesused`` = 0) and in that case it must be ignored by the client,
+        as it does not contain a decoded frame.
+
+     .. note::
+
+        Any attempt to dequeue more ``CAPTURE`` buffers beyond the buffer
+        marked with ``V4L2_BUF_FLAG_LAST`` will result in a -EPIPE error from
+        :c:func:`VIDIOC_DQBUF`.
+
+   * dequeuing processed ``OUTPUT`` buffers, until all the buffers queued
+     before the ``V4L2_DEC_CMD_STOP`` command are dequeued,
+
+   * dequeuing the ``V4L2_EVENT_EOS`` event, if the client subscribed to it.
+
+   .. note::
+
+      For backwards compatibility, the decoder will signal a ``V4L2_EVENT_EOS``
+      event when the last frame has been decoded and all frames are ready to be
+      dequeued. It is a deprecated behavior and the client must not rely on it.
+      The ``V4L2_BUF_FLAG_LAST`` buffer flag should be used instead.
+
+3. Once all the ``OUTPUT`` buffers queued before the ``V4L2_DEC_CMD_STOP`` call
+   are dequeued and the last ``CAPTURE`` buffer is dequeued, the decoder is
+   stopped and it will accept, but not process, any newly queued ``OUTPUT``
+   buffers until the client issues any of the following operations:
+
+   * ``V4L2_DEC_CMD_START`` - the decoder will not be reset and will resume
+     operation normally, with all the state from before the drain,
+
+   * a pair of :c:func:`VIDIOC_STREAMOFF` and :c:func:`VIDIOC_STREAMON` on the
+     ``CAPTURE`` queue - the decoder will resume the operation normally,
+     however any ``CAPTURE`` buffers still in the queue will be returned to the
+     client,
+
+   * a pair of :c:func:`VIDIOC_STREAMOFF` and :c:func:`VIDIOC_STREAMON` on the
+     ``OUTPUT`` queue - any pending source buffers will be returned to the
+     client and the `Seek` sequence will be triggered.
+
+.. note::
+
+   Once the drain sequence is initiated, the client needs to drive it to
+   completion, as described by the steps above, unless it aborts the process by
+   issuing :c:func:`VIDIOC_STREAMOFF` on any of the ``OUTPUT`` or ``CAPTURE``
+   queues.  The client is not allowed to issue ``V4L2_DEC_CMD_START`` or
+   ``V4L2_DEC_CMD_STOP`` again while the drain sequence is in progress and they
+   will fail with -EBUSY error code if attempted.
+
+   Although mandatory, the availability of decoder commands may be queried
+   using :c:func:`VIDIOC_TRY_DECODER_CMD`.
+
+End of Stream
+=============
+
+If the decoder encounters an end of stream marking in the stream, the decoder
+will initiate the `Drain` sequence, which the client must handle as described
+above, skipping the initial :c:func:`VIDIOC_DECODER_CMD`.
+
+Commit Points
+=============
+
+Setting formats and allocating buffers trigger changes in the behavior of the
+decoder.
+
+1. Setting the format on the ``OUTPUT`` queue may change the set of formats
+   supported/advertised on the ``CAPTURE`` queue. In particular, it also means
+   that the ``CAPTURE`` format may be reset and the client must not rely on the
+   previously set format being preserved.
+
+2. Enumerating formats on the ``CAPTURE`` queue always returns only formats
+   supported for the current ``OUTPUT`` format.
+
+3. Setting the format on the ``CAPTURE`` queue does not change the list of
+   formats available on the ``OUTPUT`` queue. An attempt to set a ``CAPTURE``
+   format that is not supported for the currently selected ``OUTPUT`` format
+   will result in the decoder adjusting the requested ``CAPTURE`` format to a
+   supported one.
+
+4. Enumerating formats on the ``OUTPUT`` queue always returns the full set of
+   supported coded formats, irrespectively of the current ``CAPTURE`` format.
+
+5. While buffers are allocated on any of the ``OUTPUT`` or ``CAPTURE`` queues,
+   the client must not change the format on the ``OUTPUT`` queue. Drivers will
+   return the -EBUSY error code for any such format change attempt.
+
+To summarize, setting formats and allocation must always start with the
+``OUTPUT`` queue and the ``OUTPUT`` queue is the master that governs the
+set of supported formats for the ``CAPTURE`` queue.
diff --git a/Documentation/userspace-api/media/v4l/dev-event.rst b/Documentation/userspace-api/media/v4l/dev-event.rst
new file mode 100644
index 000000000000..d09034fd680a
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/dev-event.rst
@@ -0,0 +1,54 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _event:
+
+***************
+Event Interface
+***************
+
+The V4L2 event interface provides a means for a user to get immediately
+notified on certain conditions taking place on a device. This might
+include start of frame or loss of signal events, for example. Changes in
+the value or state of a V4L2 control can also be reported through
+events.
+
+To receive events, the events the user is interested in first must be
+subscribed using the
+:ref:`VIDIOC_SUBSCRIBE_EVENT` ioctl. Once
+an event is subscribed, the events of subscribed types are dequeueable
+using the :ref:`VIDIOC_DQEVENT` ioctl. Events may be
+unsubscribed using VIDIOC_UNSUBSCRIBE_EVENT ioctl. The special event
+type V4L2_EVENT_ALL may be used to unsubscribe all the events the
+driver supports.
+
+The event subscriptions and event queues are specific to file handles.
+Subscribing an event on one file handle does not affect other file
+handles.
+
+The information on dequeueable events is obtained by using select or
+poll system calls on video devices. The V4L2 events use POLLPRI events
+on poll system call and exceptions on select system call.
+
+Starting with kernel 3.1 certain guarantees can be given with regards to
+events:
+
+1. Each subscribed event has its own internal dedicated event queue.
+   This means that flooding of one event type will not interfere with
+   other event types.
+
+2. If the internal event queue for a particular subscribed event becomes
+   full, then the oldest event in that queue will be dropped.
+
+3. Where applicable, certain event types can ensure that the payload of
+   the oldest event that is about to be dropped will be merged with the
+   payload of the next oldest event. Thus ensuring that no information
+   is lost, but only an intermediate step leading up to that
+   information. See the documentation for the event you want to
+   subscribe to whether this is applicable for that event or not.
diff --git a/Documentation/userspace-api/media/v4l/dev-mem2mem.rst b/Documentation/userspace-api/media/v4l/dev-mem2mem.rst
new file mode 100644
index 000000000000..9279d87c08a1
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/dev-mem2mem.rst
@@ -0,0 +1,49 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _mem2mem:
+
+********************************
+Video Memory-To-Memory Interface
+********************************
+
+A V4L2 memory-to-memory device can compress, decompress, transform, or
+otherwise convert video data from one format into another format, in memory.
+Such memory-to-memory devices set the ``V4L2_CAP_VIDEO_M2M`` or
+``V4L2_CAP_VIDEO_M2M_MPLANE`` capability. Examples of memory-to-memory
+devices are codecs, scalers, deinterlacers or format converters (i.e.
+converting from YUV to RGB).
+
+A memory-to-memory video node acts just like a normal video node, but it
+supports both output (sending frames from memory to the hardware)
+and capture (receiving the processed frames from the hardware into
+memory) stream I/O. An application will have to setup the stream I/O for
+both sides and finally call :ref:`VIDIOC_STREAMON <VIDIOC_STREAMON>`
+for both capture and output to start the hardware.
+
+Memory-to-memory devices function as a shared resource: you can
+open the video node multiple times, each application setting up their
+own properties that are local to the file handle, and each can use
+it independently from the others. The driver will arbitrate access to
+the hardware and reprogram it whenever another file handler gets access.
+This is different from the usual video node behavior where the video
+properties are global to the device (i.e. changing something through one
+file handle is visible through another file handle).
+
+One of the most common memory-to-memory device is the codec. Codecs
+are more complicated than most and require additional setup for
+their codec parameters. This is done through codec controls.
+See :ref:`mpeg-controls`. More details on how to use codec memory-to-memory
+devices are given in the following sections.
+
+.. toctree::
+    :maxdepth: 1
+
+    dev-decoder
+    dev-stateless-decoder
diff --git a/Documentation/userspace-api/media/v4l/dev-meta.rst b/Documentation/userspace-api/media/v4l/dev-meta.rst
new file mode 100644
index 000000000000..6d2c5a79b370
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/dev-meta.rst
@@ -0,0 +1,74 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _metadata:
+
+******************
+Metadata Interface
+******************
+
+Metadata refers to any non-image data that supplements video frames with
+additional information. This may include statistics computed over the image,
+frame capture parameters supplied by the image source or device specific
+parameters for specifying how the device processes images. This interface is
+intended for transfer of metadata between the userspace and the hardware and
+control of that operation.
+
+The metadata interface is implemented on video device nodes. The device can be
+dedicated to metadata or can support both video and metadata as specified in its
+reported capabilities.
+
+Querying Capabilities
+=====================
+
+Device nodes supporting the metadata capture interface set the
+``V4L2_CAP_META_CAPTURE`` flag in the ``device_caps`` field of the
+:c:type:`v4l2_capability` structure returned by the :c:func:`VIDIOC_QUERYCAP`
+ioctl. That flag means the device can capture metadata to memory. Similarly,
+device nodes supporting metadata output interface set the
+``V4L2_CAP_META_OUTPUT`` flag in the ``device_caps`` field of
+:c:type:`v4l2_capability` structure. That flag means the device can read
+metadata from memory.
+
+At least one of the read/write or streaming I/O methods must be supported.
+
+
+Data Format Negotiation
+=======================
+
+The metadata device uses the :ref:`format` ioctls to select the capture format.
+The metadata buffer content format is bound to that selected format. In addition
+to the basic :ref:`format` ioctls, the :c:func:`VIDIOC_ENUM_FMT` ioctl must be
+supported as well.
+
+To use the :ref:`format` ioctls applications set the ``type`` field of the
+:c:type:`v4l2_format` structure to ``V4L2_BUF_TYPE_META_CAPTURE`` or to
+``V4L2_BUF_TYPE_META_OUTPUT`` and use the :c:type:`v4l2_meta_format` ``meta``
+member of the ``fmt`` union as needed per the desired operation. Both drivers
+and applications must set the remainder of the :c:type:`v4l2_format` structure
+to 0.
+
+.. c:type:: v4l2_meta_format
+
+.. tabularcolumns:: |p{1.4cm}|p{2.2cm}|p{13.9cm}|
+
+.. flat-table:: struct v4l2_meta_format
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``dataformat``
+      - The data format, set by the application. This is a little endian
+        :ref:`four character code <v4l2-fourcc>`. V4L2 defines metadata formats
+        in :ref:`meta-formats`.
+    * - __u32
+      - ``buffersize``
+      - Maximum buffer size in bytes required for data. The value is set by the
+        driver.
diff --git a/Documentation/userspace-api/media/v4l/dev-osd.rst b/Documentation/userspace-api/media/v4l/dev-osd.rst
new file mode 100644
index 000000000000..67dc46373a91
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/dev-osd.rst
@@ -0,0 +1,157 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _osd:
+
+******************************
+Video Output Overlay Interface
+******************************
+
+**Also known as On-Screen Display (OSD)**
+
+Some video output devices can overlay a framebuffer image onto the
+outgoing video signal. Applications can set up such an overlay using
+this interface, which borrows structures and ioctls of the
+:ref:`Video Overlay <overlay>` interface.
+
+The OSD function is accessible through the same character special file
+as the :ref:`Video Output <capture>` function.
+
+.. note::
+
+   The default function of such a ``/dev/video`` device is video
+   capturing or output. The OSD function is only available after calling
+   the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl.
+
+
+Querying Capabilities
+=====================
+
+Devices supporting the *Video Output Overlay* interface set the
+``V4L2_CAP_VIDEO_OUTPUT_OVERLAY`` flag in the ``capabilities`` field of
+struct :c:type:`v4l2_capability` returned by the
+:ref:`VIDIOC_QUERYCAP` ioctl.
+
+
+Framebuffer
+===========
+
+Contrary to the *Video Overlay* interface the framebuffer is normally
+implemented on the TV card and not the graphics card. On Linux it is
+accessible as a framebuffer device (``/dev/fbN``). Given a V4L2 device,
+applications can find the corresponding framebuffer device by calling
+the :ref:`VIDIOC_G_FBUF <VIDIOC_G_FBUF>` ioctl. It returns, amongst
+other information, the physical address of the framebuffer in the
+``base`` field of struct :c:type:`v4l2_framebuffer`.
+The framebuffer device ioctl ``FBIOGET_FSCREENINFO`` returns the same
+address in the ``smem_start`` field of struct
+struct :c:type:`fb_fix_screeninfo`. The ``FBIOGET_FSCREENINFO``
+ioctl and struct :c:type:`fb_fix_screeninfo` are defined in
+the ``linux/fb.h`` header file.
+
+The width and height of the framebuffer depends on the current video
+standard. A V4L2 driver may reject attempts to change the video standard
+(or any other ioctl which would imply a framebuffer size change) with an
+``EBUSY`` error code until all applications closed the framebuffer device.
+
+Example: Finding a framebuffer device for OSD
+---------------------------------------------
+
+.. code-block:: c
+
+    #include <linux/fb.h>
+
+    struct v4l2_framebuffer fbuf;
+    unsigned int i;
+    int fb_fd;
+
+    if (-1 == ioctl(fd, VIDIOC_G_FBUF, &fbuf)) {
+	perror("VIDIOC_G_FBUF");
+	exit(EXIT_FAILURE);
+    }
+
+    for (i = 0; i < 30; i++) {
+	char dev_name[16];
+	struct fb_fix_screeninfo si;
+
+	snprintf(dev_name, sizeof(dev_name), "/dev/fb%u", i);
+
+	fb_fd = open(dev_name, O_RDWR);
+	if (-1 == fb_fd) {
+	    switch (errno) {
+	    case ENOENT: /* no such file */
+	    case ENXIO:  /* no driver */
+		continue;
+
+	    default:
+		perror("open");
+		exit(EXIT_FAILURE);
+	    }
+	}
+
+	if (0 == ioctl(fb_fd, FBIOGET_FSCREENINFO, &si)) {
+	    if (si.smem_start == (unsigned long)fbuf.base)
+		break;
+	} else {
+	    /* Apparently not a framebuffer device. */
+	}
+
+	close(fb_fd);
+	fb_fd = -1;
+    }
+
+    /* fb_fd is the file descriptor of the framebuffer device
+       for the video output overlay, or -1 if no device was found. */
+
+
+Overlay Window and Scaling
+==========================
+
+The overlay is controlled by source and target rectangles. The source
+rectangle selects a subsection of the framebuffer image to be overlaid,
+the target rectangle an area in the outgoing video signal where the
+image will appear. Drivers may or may not support scaling, and arbitrary
+sizes and positions of these rectangles. Further drivers may support any
+(or none) of the clipping/blending methods defined for the
+:ref:`Video Overlay <overlay>` interface.
+
+A struct :c:type:`v4l2_window` defines the size of the
+source rectangle, its position in the framebuffer and the
+clipping/blending method to be used for the overlay. To get the current
+parameters applications set the ``type`` field of a struct
+:c:type:`v4l2_format` to
+``V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY`` and call the
+:ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` ioctl. The driver fills the
+struct :c:type:`v4l2_window` substructure named ``win``. It is not
+possible to retrieve a previously programmed clipping list or bitmap.
+
+To program the source rectangle applications set the ``type`` field of a
+struct :c:type:`v4l2_format` to
+``V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY``, initialize the ``win``
+substructure and call the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl.
+The driver adjusts the parameters against hardware limits and returns
+the actual parameters as :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` does. Like :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`,
+the :ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` ioctl can be used to learn
+about driver capabilities without actually changing driver state. Unlike
+:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` this also works after the overlay has been enabled.
+
+A struct :c:type:`v4l2_crop` defines the size and position
+of the target rectangle. The scaling factor of the overlay is implied by
+the width and height given in struct :c:type:`v4l2_window`
+and struct :c:type:`v4l2_crop`. The cropping API applies to
+*Video Output* and *Video Output Overlay* devices in the same way as to
+*Video Capture* and *Video Overlay* devices, merely reversing the
+direction of the data flow. For more information see :ref:`crop`.
+
+
+Enabling Overlay
+================
+
+There is no V4L2 ioctl to enable or disable the overlay, however the
+framebuffer interface of the driver may support the ``FBIOBLANK`` ioctl.
diff --git a/Documentation/userspace-api/media/v4l/dev-output.rst b/Documentation/userspace-api/media/v4l/dev-output.rst
new file mode 100644
index 000000000000..e4f2a1d8b0fc
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/dev-output.rst
@@ -0,0 +1,108 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _output:
+
+**********************
+Video Output Interface
+**********************
+
+Video output devices encode stills or image sequences as analog video
+signal. With this interface applications can control the encoding
+process and move images from user space to the driver.
+
+Conventionally V4L2 video output devices are accessed through character
+device special files named ``/dev/video`` and ``/dev/video0`` to
+``/dev/video63`` with major number 81 and minor numbers 0 to 63.
+``/dev/video`` is typically a symbolic link to the preferred video
+device.
+
+.. note:: The same device file names are used also for video capture devices.
+
+
+Querying Capabilities
+=====================
+
+Devices supporting the video output interface set the
+``V4L2_CAP_VIDEO_OUTPUT`` or ``V4L2_CAP_VIDEO_OUTPUT_MPLANE`` flag in
+the ``capabilities`` field of struct
+:c:type:`v4l2_capability` returned by the
+:ref:`VIDIOC_QUERYCAP` ioctl. As secondary device
+functions they may also support the :ref:`raw VBI output <raw-vbi>`
+(``V4L2_CAP_VBI_OUTPUT``) interface. At least one of the read/write or
+streaming I/O methods must be supported. Modulators and audio outputs
+are optional.
+
+
+Supplemental Functions
+======================
+
+Video output devices shall support :ref:`audio output <audio>`,
+:ref:`modulator <tuner>`, :ref:`controls <control>`,
+:ref:`cropping and scaling <crop>` and
+:ref:`streaming parameter <streaming-par>` ioctls as needed. The
+:ref:`video output <video>` ioctls must be supported by all video
+output devices.
+
+
+Image Format Negotiation
+========================
+
+The output is determined by cropping and image format parameters. The
+former select an area of the video picture where the image will appear,
+the latter how images are stored in memory, i. e. in RGB or YUV format,
+the number of bits per pixel or width and height. Together they also
+define how images are scaled in the process.
+
+As usual these parameters are *not* reset at :ref:`open() <func-open>`
+time to permit Unix tool chains, programming a device and then writing
+to it as if it was a plain file. Well written V4L2 applications ensure
+they really get what they want, including cropping and scaling.
+
+Cropping initialization at minimum requires to reset the parameters to
+defaults. An example is given in :ref:`crop`.
+
+To query the current image format applications set the ``type`` field of
+a struct :c:type:`v4l2_format` to
+``V4L2_BUF_TYPE_VIDEO_OUTPUT`` or ``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE``
+and call the :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` ioctl with a pointer
+to this structure. Drivers fill the struct
+:c:type:`v4l2_pix_format` ``pix`` or the struct
+:c:type:`v4l2_pix_format_mplane` ``pix_mp``
+member of the ``fmt`` union.
+
+To request different parameters applications set the ``type`` field of a
+struct :c:type:`v4l2_format` as above and initialize all
+fields of the struct :c:type:`v4l2_pix_format`
+``vbi`` member of the ``fmt`` union, or better just modify the results
+of :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>`, and call the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`
+ioctl with a pointer to this structure. Drivers may adjust the
+parameters and finally return the actual parameters as :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>`
+does.
+
+Like :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` the :ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` ioctl
+can be used to learn about hardware limitations without disabling I/O or
+possibly time consuming hardware preparations.
+
+The contents of struct :c:type:`v4l2_pix_format` and
+struct :c:type:`v4l2_pix_format_mplane` are
+discussed in :ref:`pixfmt`. See also the specification of the
+:ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>`, :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` and :ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` ioctls for
+details. Video output devices must implement both the :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>`
+and :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl, even if :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ignores all
+requests and always returns default parameters as :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` does.
+:ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` is optional.
+
+
+Writing Images
+==============
+
+A video output device may support the :ref:`write() function <rw>`
+and/or streaming (:ref:`memory mapping <mmap>` or
+:ref:`user pointer <userp>`) I/O. See :ref:`io` for details.
diff --git a/Documentation/userspace-api/media/v4l/dev-overlay.rst b/Documentation/userspace-api/media/v4l/dev-overlay.rst
new file mode 100644
index 000000000000..7246d560173d
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/dev-overlay.rst
@@ -0,0 +1,328 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _overlay:
+
+***********************
+Video Overlay Interface
+***********************
+
+**Also known as Framebuffer Overlay or Previewing.**
+
+Video overlay devices have the ability to genlock (TV-)video into the
+(VGA-)video signal of a graphics card, or to store captured images
+directly in video memory of a graphics card, typically with clipping.
+This can be considerable more efficient than capturing images and
+displaying them by other means. In the old days when only nuclear power
+plants needed cooling towers this used to be the only way to put live
+video into a window.
+
+Video overlay devices are accessed through the same character special
+files as :ref:`video capture <capture>` devices.
+
+.. note::
+
+   The default function of a ``/dev/video`` device is video
+   capturing. The overlay function is only available after calling
+   the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl.
+
+The driver may support simultaneous overlay and capturing using the
+read/write and streaming I/O methods. If so, operation at the nominal
+frame rate of the video standard is not guaranteed. Frames may be
+directed away from overlay to capture, or one field may be used for
+overlay and the other for capture if the capture parameters permit this.
+
+Applications should use different file descriptors for capturing and
+overlay. This must be supported by all drivers capable of simultaneous
+capturing and overlay. Optionally these drivers may also permit
+capturing and overlay with a single file descriptor for compatibility
+with V4L and earlier versions of V4L2. [#f1]_
+
+
+Querying Capabilities
+=====================
+
+Devices supporting the video overlay interface set the
+``V4L2_CAP_VIDEO_OVERLAY`` flag in the ``capabilities`` field of struct
+:c:type:`v4l2_capability` returned by the
+:ref:`VIDIOC_QUERYCAP` ioctl. The overlay I/O
+method specified below must be supported. Tuners and audio inputs are
+optional.
+
+
+Supplemental Functions
+======================
+
+Video overlay devices shall support :ref:`audio input <audio>`,
+:ref:`tuner`, :ref:`controls <control>`,
+:ref:`cropping and scaling <crop>` and
+:ref:`streaming parameter <streaming-par>` ioctls as needed. The
+:ref:`video input <video>` and :ref:`video standard <standard>`
+ioctls must be supported by all video overlay devices.
+
+
+Setup
+=====
+
+Before overlay can commence applications must program the driver with
+frame buffer parameters, namely the address and size of the frame buffer
+and the image format, for example RGB 5:6:5. The
+:ref:`VIDIOC_G_FBUF <VIDIOC_G_FBUF>` and
+:ref:`VIDIOC_S_FBUF <VIDIOC_G_FBUF>` ioctls are available to get and
+set these parameters, respectively. The :ref:`VIDIOC_S_FBUF <VIDIOC_G_FBUF>` ioctl is
+privileged because it allows to set up DMA into physical memory,
+bypassing the memory protection mechanisms of the kernel. Only the
+superuser can change the frame buffer address and size. Users are not
+supposed to run TV applications as root or with SUID bit set. A small
+helper application with suitable privileges should query the graphics
+system and program the V4L2 driver at the appropriate time.
+
+Some devices add the video overlay to the output signal of the graphics
+card. In this case the frame buffer is not modified by the video device,
+and the frame buffer address and pixel format are not needed by the
+driver. The :ref:`VIDIOC_S_FBUF <VIDIOC_G_FBUF>` ioctl is not privileged. An application
+can check for this type of device by calling the :ref:`VIDIOC_G_FBUF <VIDIOC_G_FBUF>`
+ioctl.
+
+A driver may support any (or none) of five clipping/blending methods:
+
+1. Chroma-keying displays the overlaid image only where pixels in the
+   primary graphics surface assume a certain color.
+
+2. A bitmap can be specified where each bit corresponds to a pixel in
+   the overlaid image. When the bit is set, the corresponding video
+   pixel is displayed, otherwise a pixel of the graphics surface.
+
+3. A list of clipping rectangles can be specified. In these regions *no*
+   video is displayed, so the graphics surface can be seen here.
+
+4. The framebuffer has an alpha channel that can be used to clip or
+   blend the framebuffer with the video.
+
+5. A global alpha value can be specified to blend the framebuffer
+   contents with video images.
+
+When simultaneous capturing and overlay is supported and the hardware
+prohibits different image and frame buffer formats, the format requested
+first takes precedence. The attempt to capture
+(:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`) or overlay
+(:ref:`VIDIOC_S_FBUF <VIDIOC_G_FBUF>`) may fail with an ``EBUSY`` error
+code or return accordingly modified parameters..
+
+
+Overlay Window
+==============
+
+The overlaid image is determined by cropping and overlay window
+parameters. The former select an area of the video picture to capture,
+the latter how images are overlaid and clipped. Cropping initialization
+at minimum requires to reset the parameters to defaults. An example is
+given in :ref:`crop`.
+
+The overlay window is described by a struct
+:c:type:`v4l2_window`. It defines the size of the image,
+its position over the graphics surface and the clipping to be applied.
+To get the current parameters applications set the ``type`` field of a
+struct :c:type:`v4l2_format` to
+``V4L2_BUF_TYPE_VIDEO_OVERLAY`` and call the
+:ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` ioctl. The driver fills the
+struct :c:type:`v4l2_window` substructure named ``win``. It is not
+possible to retrieve a previously programmed clipping list or bitmap.
+
+To program the overlay window applications set the ``type`` field of a
+struct :c:type:`v4l2_format` to
+``V4L2_BUF_TYPE_VIDEO_OVERLAY``, initialize the ``win`` substructure and
+call the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl. The driver
+adjusts the parameters against hardware limits and returns the actual
+parameters as :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` does. Like :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`, the
+:ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` ioctl can be used to learn
+about driver capabilities without actually changing driver state. Unlike
+:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` this also works after the overlay has been enabled.
+
+The scaling factor of the overlaid image is implied by the width and
+height given in struct :c:type:`v4l2_window` and the size
+of the cropping rectangle. For more information see :ref:`crop`.
+
+When simultaneous capturing and overlay is supported and the hardware
+prohibits different image and window sizes, the size requested first
+takes precedence. The attempt to capture or overlay as well
+(:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`) may fail with an ``EBUSY`` error
+code or return accordingly modified parameters.
+
+
+.. c:type:: v4l2_window
+
+struct v4l2_window
+------------------
+
+``struct v4l2_rect w``
+    Size and position of the window relative to the top, left corner of
+    the frame buffer defined with
+    :ref:`VIDIOC_S_FBUF <VIDIOC_G_FBUF>`. The window can extend the
+    frame buffer width and height, the ``x`` and ``y`` coordinates can
+    be negative, and it can lie completely outside the frame buffer. The
+    driver clips the window accordingly, or if that is not possible,
+    modifies its size and/or position.
+
+``enum v4l2_field field``
+    Applications set this field to determine which video field shall be
+    overlaid, typically one of ``V4L2_FIELD_ANY`` (0),
+    ``V4L2_FIELD_TOP``, ``V4L2_FIELD_BOTTOM`` or
+    ``V4L2_FIELD_INTERLACED``. Drivers may have to choose a different
+    field order and return the actual setting here.
+
+``__u32 chromakey``
+    When chroma-keying has been negotiated with
+    :ref:`VIDIOC_S_FBUF <VIDIOC_G_FBUF>` applications set this field
+    to the desired pixel value for the chroma key. The format is the
+    same as the pixel format of the framebuffer (struct
+    :c:type:`v4l2_framebuffer` ``fmt.pixelformat``
+    field), with bytes in host order. E. g. for
+    :ref:`V4L2_PIX_FMT_BGR24 <V4L2-PIX-FMT-BGR32>` the value should
+    be 0xRRGGBB on a little endian, 0xBBGGRR on a big endian host.
+
+``struct v4l2_clip * clips``
+    When chroma-keying has *not* been negotiated and
+    :ref:`VIDIOC_G_FBUF <VIDIOC_G_FBUF>` indicated this capability,
+    applications can set this field to point to an array of clipping
+    rectangles.
+
+    Like the window coordinates w, clipping rectangles are defined
+    relative to the top, left corner of the frame buffer. However
+    clipping rectangles must not extend the frame buffer width and
+    height, and they must not overlap. If possible applications
+    should merge adjacent rectangles. Whether this must create
+    x-y or y-x bands, or the order of rectangles, is not defined. When
+    clip lists are not supported the driver ignores this field. Its
+    contents after calling :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`
+    are undefined.
+
+``__u32 clipcount``
+    When the application set the ``clips`` field, this field must
+    contain the number of clipping rectangles in the list. When clip
+    lists are not supported the driver ignores this field, its contents
+    after calling :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` are undefined. When clip lists are
+    supported but no clipping is desired this field must be set to zero.
+
+``void * bitmap``
+    When chroma-keying has *not* been negotiated and
+    :ref:`VIDIOC_G_FBUF <VIDIOC_G_FBUF>` indicated this capability,
+    applications can set this field to point to a clipping bit mask.
+
+It must be of the same size as the window, ``w.width`` and ``w.height``.
+Each bit corresponds to a pixel in the overlaid image, which is
+displayed only when the bit is *set*. Pixel coordinates translate to
+bits like:
+
+
+.. code-block:: c
+
+    ((__u8 *) bitmap)[w.width * y + x / 8] & (1 << (x & 7))
+
+where ``0`` ≤ x < ``w.width`` and ``0`` ≤ y <``w.height``. [#f2]_
+
+When a clipping bit mask is not supported the driver ignores this field,
+its contents after calling :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` are
+undefined. When a bit mask is supported but no clipping is desired this
+field must be set to ``NULL``.
+
+Applications need not create a clip list or bit mask. When they pass
+both, or despite negotiating chroma-keying, the results are undefined.
+Regardless of the chosen method, the clipping abilities of the hardware
+may be limited in quantity or quality. The results when these limits are
+exceeded are undefined. [#f3]_
+
+``__u8 global_alpha``
+    The global alpha value used to blend the framebuffer with video
+    images, if global alpha blending has been negotiated
+    (``V4L2_FBUF_FLAG_GLOBAL_ALPHA``, see
+    :ref:`VIDIOC_S_FBUF <VIDIOC_G_FBUF>`,
+    :ref:`framebuffer-flags`).
+
+.. note::
+
+   This field was added in Linux 2.6.23, extending the
+   structure. However the :ref:`VIDIOC_[G|S|TRY]_FMT <VIDIOC_G_FMT>`
+   ioctls, which take a pointer to a :c:type:`v4l2_format`
+   parent structure with padding bytes at the end, are not affected.
+
+
+.. c:type:: v4l2_clip
+
+struct v4l2_clip [#f4]_
+-----------------------
+
+``struct v4l2_rect c``
+    Coordinates of the clipping rectangle, relative to the top, left
+    corner of the frame buffer. Only window pixels *outside* all
+    clipping rectangles are displayed.
+
+``struct v4l2_clip * next``
+    Pointer to the next clipping rectangle, ``NULL`` when this is the last
+    rectangle. Drivers ignore this field, it cannot be used to pass a
+    linked list of clipping rectangles.
+
+
+.. c:type:: v4l2_rect
+
+struct v4l2_rect
+----------------
+
+``__s32 left``
+    Horizontal offset of the top, left corner of the rectangle, in
+    pixels.
+
+``__s32 top``
+    Vertical offset of the top, left corner of the rectangle, in pixels.
+    Offsets increase to the right and down.
+
+``__u32 width``
+    Width of the rectangle, in pixels.
+
+``__u32 height``
+    Height of the rectangle, in pixels.
+
+
+Enabling Overlay
+================
+
+To start or stop the frame buffer overlay applications call the
+:ref:`VIDIOC_OVERLAY` ioctl.
+
+.. [#f1]
+   A common application of two file descriptors is the XFree86
+   :ref:`Xv/V4L <xvideo>` interface driver and a V4L2 application.
+   While the X server controls video overlay, the application can take
+   advantage of memory mapping and DMA.
+
+   In the opinion of the designers of this API, no driver writer taking
+   the efforts to support simultaneous capturing and overlay will
+   restrict this ability by requiring a single file descriptor, as in
+   V4L and earlier versions of V4L2. Making this optional means
+   applications depending on two file descriptors need backup routines
+   to be compatible with all drivers, which is considerable more work
+   than using two fds in applications which do not. Also two fd's fit
+   the general concept of one file descriptor for each logical stream.
+   Hence as a complexity trade-off drivers *must* support two file
+   descriptors and *may* support single fd operation.
+
+.. [#f2]
+   Should we require ``w.width`` to be a multiple of eight?
+
+.. [#f3]
+   When the image is written into frame buffer memory it will be
+   undesirable if the driver clips out less pixels than expected,
+   because the application and graphics system are not aware these
+   regions need to be refreshed. The driver should clip out more pixels
+   or not write the image at all.
+
+.. [#f4]
+   The X Window system defines "regions" which are vectors of ``struct
+   BoxRec { short x1, y1, x2, y2; }`` with ``width = x2 - x1`` and
+   ``height = y2 - y1``, so one cannot pass X11 clip lists directly.
diff --git a/Documentation/userspace-api/media/v4l/dev-radio.rst b/Documentation/userspace-api/media/v4l/dev-radio.rst
new file mode 100644
index 000000000000..c0edd7b7d201
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/dev-radio.rst
@@ -0,0 +1,59 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _radio:
+
+***************
+Radio Interface
+***************
+
+This interface is intended for AM and FM (analog) radio receivers and
+transmitters.
+
+Conventionally V4L2 radio devices are accessed through character device
+special files named ``/dev/radio`` and ``/dev/radio0`` to
+``/dev/radio63`` with major number 81 and minor numbers 64 to 127.
+
+
+Querying Capabilities
+=====================
+
+Devices supporting the radio interface set the ``V4L2_CAP_RADIO`` and
+``V4L2_CAP_TUNER`` or ``V4L2_CAP_MODULATOR`` flag in the
+``capabilities`` field of struct
+:c:type:`v4l2_capability` returned by the
+:ref:`VIDIOC_QUERYCAP` ioctl. Other combinations of
+capability flags are reserved for future extensions.
+
+
+Supplemental Functions
+======================
+
+Radio devices can support :ref:`controls <control>`, and must support
+the :ref:`tuner or modulator <tuner>` ioctls.
+
+They do not support the video input or output, audio input or output,
+video standard, cropping and scaling, compression and streaming
+parameter, or overlay ioctls. All other ioctls and I/O methods are
+reserved for future extensions.
+
+
+Programming
+===========
+
+Radio devices may have a couple audio controls (as discussed in
+:ref:`control`) such as a volume control, possibly custom controls.
+Further all radio devices have one tuner or modulator (these are
+discussed in :ref:`tuner`) with index number zero to select the radio
+frequency and to determine if a monaural or FM stereo program is
+received/emitted. Drivers switch automatically between AM and FM
+depending on the selected frequency. The
+:ref:`VIDIOC_G_TUNER <VIDIOC_G_TUNER>` or
+:ref:`VIDIOC_G_MODULATOR <VIDIOC_G_MODULATOR>` ioctl reports the
+supported frequency range.
diff --git a/Documentation/userspace-api/media/v4l/dev-raw-vbi.rst b/Documentation/userspace-api/media/v4l/dev-raw-vbi.rst
new file mode 100644
index 000000000000..0307d44e17cb
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/dev-raw-vbi.rst
@@ -0,0 +1,306 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _raw-vbi:
+
+**********************
+Raw VBI Data Interface
+**********************
+
+VBI is an abbreviation of Vertical Blanking Interval, a gap in the
+sequence of lines of an analog video signal. During VBI no picture
+information is transmitted, allowing some time while the electron beam
+of a cathode ray tube TV returns to the top of the screen. Using an
+oscilloscope you will find here the vertical synchronization pulses and
+short data packages ASK modulated [#f1]_ onto the video signal. These are
+transmissions of services such as Teletext or Closed Caption.
+
+Subject of this interface type is raw VBI data, as sampled off a video
+signal, or to be added to a signal for output. The data format is
+similar to uncompressed video images, a number of lines times a number
+of samples per line, we call this a VBI image.
+
+Conventionally V4L2 VBI devices are accessed through character device
+special files named ``/dev/vbi`` and ``/dev/vbi0`` to ``/dev/vbi31``
+with major number 81 and minor numbers 224 to 255. ``/dev/vbi`` is
+typically a symbolic link to the preferred VBI device. This convention
+applies to both input and output devices.
+
+To address the problems of finding related video and VBI devices VBI
+capturing and output is also available as device function under
+``/dev/video``. To capture or output raw VBI data with these devices
+applications must call the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl.
+Accessed as ``/dev/vbi``, raw VBI capturing or output is the default
+device function.
+
+
+Querying Capabilities
+=====================
+
+Devices supporting the raw VBI capturing or output API set the
+``V4L2_CAP_VBI_CAPTURE`` or ``V4L2_CAP_VBI_OUTPUT`` flags, respectively,
+in the ``capabilities`` field of struct
+:c:type:`v4l2_capability` returned by the
+:ref:`VIDIOC_QUERYCAP` ioctl. At least one of the
+read/write, streaming or asynchronous I/O methods must be supported. VBI
+devices may or may not have a tuner or modulator.
+
+
+Supplemental Functions
+======================
+
+VBI devices shall support :ref:`video input or output <video>`,
+:ref:`tuner or modulator <tuner>`, and :ref:`controls <control>`
+ioctls as needed. The :ref:`video standard <standard>` ioctls provide
+information vital to program a VBI device, therefore must be supported.
+
+
+Raw VBI Format Negotiation
+==========================
+
+Raw VBI sampling abilities can vary, in particular the sampling
+frequency. To properly interpret the data V4L2 specifies an ioctl to
+query the sampling parameters. Moreover, to allow for some flexibility
+applications can also suggest different parameters.
+
+As usual these parameters are *not* reset at :ref:`open() <func-open>`
+time to permit Unix tool chains, programming a device and then reading
+from it as if it was a plain file. Well written V4L2 applications should
+always ensure they really get what they want, requesting reasonable
+parameters and then checking if the actual parameters are suitable.
+
+To query the current raw VBI capture parameters applications set the
+``type`` field of a struct :c:type:`v4l2_format` to
+``V4L2_BUF_TYPE_VBI_CAPTURE`` or ``V4L2_BUF_TYPE_VBI_OUTPUT``, and call
+the :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` ioctl with a pointer to this
+structure. Drivers fill the struct
+:c:type:`v4l2_vbi_format` ``vbi`` member of the
+``fmt`` union.
+
+To request different parameters applications set the ``type`` field of a
+struct :c:type:`v4l2_format` as above and initialize all
+fields of the struct :c:type:`v4l2_vbi_format`
+``vbi`` member of the ``fmt`` union, or better just modify the results
+of :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>`, and call the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`
+ioctl with a pointer to this structure. Drivers return an ``EINVAL`` error
+code only when the given parameters are ambiguous, otherwise they modify
+the parameters according to the hardware capabilities and return the
+actual parameters. When the driver allocates resources at this point, it
+may return an ``EBUSY`` error code to indicate the returned parameters are
+valid but the required resources are currently not available. That may
+happen for instance when the video and VBI areas to capture would
+overlap, or when the driver supports multiple opens and another process
+already requested VBI capturing or output. Anyway, applications must
+expect other resource allocation points which may return ``EBUSY``, at the
+:ref:`VIDIOC_STREAMON` ioctl and the first :ref:`read() <func-read>`
+, :ref:`write() <func-write>` and :ref:`select() <func-select>` calls.
+
+VBI devices must implement both the :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` and
+:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl, even if :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ignores all requests
+and always returns default parameters as :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` does.
+:ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` is optional.
+
+.. tabularcolumns:: |p{1.6cm}|p{4.2cm}|p{11.7cm}|
+
+.. c:type:: v4l2_vbi_format
+
+.. cssclass:: longtable
+
+.. flat-table:: struct v4l2_vbi_format
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``sampling_rate``
+      - Samples per second, i. e. unit 1 Hz.
+    * - __u32
+      - ``offset``
+      - Horizontal offset of the VBI image, relative to the leading edge
+	of the line synchronization pulse and counted in samples: The
+	first sample in the VBI image will be located ``offset`` /
+	``sampling_rate`` seconds following the leading edge. See also
+	:ref:`vbi-hsync`.
+    * - __u32
+      - ``samples_per_line``
+      -
+    * - __u32
+      - ``sample_format``
+      - Defines the sample format as in :ref:`pixfmt`, a
+	four-character-code. [#f2]_ Usually this is ``V4L2_PIX_FMT_GREY``,
+	i. e. each sample consists of 8 bits with lower values oriented
+	towards the black level. Do not assume any other correlation of
+	values with the signal level. For example, the MSB does not
+	necessarily indicate if the signal is 'high' or 'low' because 128
+	may not be the mean value of the signal. Drivers shall not convert
+	the sample format by software.
+    * - __u32
+      - ``start``\ [#f2]_
+      - This is the scanning system line number associated with the first
+	line of the VBI image, of the first and the second field
+	respectively. See :ref:`vbi-525` and :ref:`vbi-625` for valid
+	values. The ``V4L2_VBI_ITU_525_F1_START``,
+	``V4L2_VBI_ITU_525_F2_START``, ``V4L2_VBI_ITU_625_F1_START`` and
+	``V4L2_VBI_ITU_625_F2_START`` defines give the start line numbers
+	for each field for each 525 or 625 line format as a convenience.
+	Don't forget that ITU line numbering starts at 1, not 0. VBI input
+	drivers can return start values 0 if the hardware cannot reliable
+	identify scanning lines, VBI acquisition may not require this
+	information.
+    * - __u32
+      - ``count``\ [#f2]_
+      - The number of lines in the first and second field image,
+	respectively.
+    * - :cspan:`2`
+
+	Drivers should be as flexibility as possible. For example, it may
+	be possible to extend or move the VBI capture window down to the
+	picture area, implementing a 'full field mode' to capture data
+	service transmissions embedded in the picture.
+
+	An application can set the first or second ``count`` value to zero
+	if no data is required from the respective field; ``count``\ [1]
+	if the scanning system is progressive, i. e. not interlaced. The
+	corresponding start value shall be ignored by the application and
+	driver. Anyway, drivers may not support single field capturing and
+	return both count values non-zero.
+
+	Both ``count`` values set to zero, or line numbers are outside the
+	bounds depicted\ [#f4]_, or a field image covering lines of two
+	fields, are invalid and shall not be returned by the driver.
+
+	To initialize the ``start`` and ``count`` fields, applications
+	must first determine the current video standard selection. The
+	:ref:`v4l2_std_id <v4l2-std-id>` or the ``framelines`` field
+	of struct :c:type:`v4l2_standard` can be evaluated
+	for this purpose.
+    * - __u32
+      - ``flags``
+      - See :ref:`vbifmt-flags` below. Currently only drivers set flags,
+	applications must set this field to zero.
+    * - __u32
+      - ``reserved``\ [#f2]_
+      - This array is reserved for future extensions. Drivers and
+	applications must set it to zero.
+
+
+.. tabularcolumns:: |p{4.4cm}|p{1.5cm}|p{11.6cm}|
+
+.. _vbifmt-flags:
+
+.. flat-table:: Raw VBI Format Flags
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_VBI_UNSYNC``
+      - 0x0001
+      - This flag indicates hardware which does not properly distinguish
+	between fields. Normally the VBI image stores the first field
+	(lower scanning line numbers) first in memory. This may be a top
+	or bottom field depending on the video standard. When this flag is
+	set the first or second field may be stored first, however the
+	fields are still in correct temporal order with the older field
+	first in memory. [#f3]_
+    * - ``V4L2_VBI_INTERLACED``
+      - 0x0002
+      - By default the two field images will be passed sequentially; all
+	lines of the first field followed by all lines of the second field
+	(compare :ref:`field-order` ``V4L2_FIELD_SEQ_TB`` and
+	``V4L2_FIELD_SEQ_BT``, whether the top or bottom field is first in
+	memory depends on the video standard). When this flag is set, the
+	two fields are interlaced (cf. ``V4L2_FIELD_INTERLACED``). The
+	first line of the first field followed by the first line of the
+	second field, then the two second lines, and so on. Such a layout
+	may be necessary when the hardware has been programmed to capture
+	or output interlaced video images and is unable to separate the
+	fields for VBI capturing at the same time. For simplicity setting
+	this flag implies that both ``count`` values are equal and
+	non-zero.
+
+
+
+.. _vbi-hsync:
+
+.. kernel-figure:: vbi_hsync.svg
+    :alt:   vbi_hsync.svg
+    :align: center
+
+    **Figure 4.1. Line synchronization**
+
+
+.. _vbi-525:
+
+.. kernel-figure:: vbi_525.svg
+    :alt:   vbi_525.svg
+    :align: center
+
+    **Figure 4.2. ITU-R 525 line numbering (M/NTSC and M/PAL)**
+
+.. _vbi-625:
+
+.. kernel-figure:: vbi_625.svg
+    :alt:   vbi_625.svg
+    :align: center
+
+    **Figure 4.3. ITU-R 625 line numbering**
+
+Remember the VBI image format depends on the selected video standard,
+therefore the application must choose a new standard or query the
+current standard first. Attempts to read or write data ahead of format
+negotiation, or after switching the video standard which may invalidate
+the negotiated VBI parameters, should be refused by the driver. A format
+change during active I/O is not permitted.
+
+
+Reading and writing VBI images
+==============================
+
+To assure synchronization with the field number and easier
+implementation, the smallest unit of data passed at a time is one frame,
+consisting of two fields of VBI images immediately following in memory.
+
+The total size of a frame computes as follows:
+
+
+.. code-block:: c
+
+    (count[0] + count[1]) * samples_per_line * sample size in bytes
+
+The sample size is most likely always one byte, applications must check
+the ``sample_format`` field though, to function properly with other
+drivers.
+
+A VBI device may support :ref:`read/write <rw>` and/or streaming
+(:ref:`memory mapping <mmap>` or :ref:`user pointer <userp>`) I/O.
+The latter bears the possibility of synchronizing video and VBI data by
+using buffer timestamps.
+
+Remember the :ref:`VIDIOC_STREAMON <VIDIOC_STREAMON>` ioctl and the
+first :ref:`read() <func-read>`, :ref:`write() <func-write>` and
+:ref:`select() <func-select>` call can be resource allocation
+points returning an ``EBUSY`` error code if the required hardware resources
+are temporarily unavailable, for example the device is already in use by
+another process.
+
+.. [#f1]
+   ASK: Amplitude-Shift Keying. A high signal level represents a '1'
+   bit, a low level a '0' bit.
+
+.. [#f2]
+   A few devices may be unable to sample VBI data at all but can extend
+   the video capture window to the VBI region.
+
+.. [#f3]
+   Most VBI services transmit on both fields, but some have different
+   semantics depending on the field number. These cannot be reliable
+   decoded or encoded when ``V4L2_VBI_UNSYNC`` is set.
+
+.. [#f4]
+   The valid values ar shown at :ref:`vbi-525` and :ref:`vbi-625`.
diff --git a/Documentation/userspace-api/media/v4l/dev-rds.rst b/Documentation/userspace-api/media/v4l/dev-rds.rst
new file mode 100644
index 000000000000..13dba4a4180c
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/dev-rds.rst
@@ -0,0 +1,191 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _rds:
+
+*************
+RDS Interface
+*************
+
+The Radio Data System transmits supplementary information in binary
+format, for example the station name or travel information, on an
+inaudible audio subcarrier of a radio program. This interface is aimed
+at devices capable of receiving and/or transmitting RDS information.
+
+For more information see the core RDS standard :ref:`iec62106` and the
+RBDS standard :ref:`nrsc4`.
+
+.. note::
+
+   Note that the RBDS standard as is used in the USA is almost
+   identical to the RDS standard. Any RDS decoder/encoder can also handle
+   RBDS. Only some of the fields have slightly different meanings. See the
+   RBDS standard for more information.
+
+The RBDS standard also specifies support for MMBS (Modified Mobile
+Search). This is a proprietary format which seems to be discontinued.
+The RDS interface does not support this format. Should support for MMBS
+(or the so-called 'E blocks' in general) be needed, then please contact
+the linux-media mailing list:
+`https://linuxtv.org/lists.php <https://linuxtv.org/lists.php>`__.
+
+
+Querying Capabilities
+=====================
+
+Devices supporting the RDS capturing API set the
+``V4L2_CAP_RDS_CAPTURE`` flag in the ``capabilities`` field of struct
+:c:type:`v4l2_capability` returned by the
+:ref:`VIDIOC_QUERYCAP` ioctl. Any tuner that
+supports RDS will set the ``V4L2_TUNER_CAP_RDS`` flag in the
+``capability`` field of struct :c:type:`v4l2_tuner`. If the
+driver only passes RDS blocks without interpreting the data the
+``V4L2_TUNER_CAP_RDS_BLOCK_IO`` flag has to be set, see
+:ref:`Reading RDS data <reading-rds-data>`. For future use the flag
+``V4L2_TUNER_CAP_RDS_CONTROLS`` has also been defined. However, a driver
+for a radio tuner with this capability does not yet exist, so if you are
+planning to write such a driver you should discuss this on the
+linux-media mailing list:
+`https://linuxtv.org/lists.php <https://linuxtv.org/lists.php>`__.
+
+Whether an RDS signal is present can be detected by looking at the
+``rxsubchans`` field of struct :c:type:`v4l2_tuner`: the
+``V4L2_TUNER_SUB_RDS`` will be set if RDS data was detected.
+
+Devices supporting the RDS output API set the ``V4L2_CAP_RDS_OUTPUT``
+flag in the ``capabilities`` field of struct
+:c:type:`v4l2_capability` returned by the
+:ref:`VIDIOC_QUERYCAP` ioctl. Any modulator that
+supports RDS will set the ``V4L2_TUNER_CAP_RDS`` flag in the
+``capability`` field of struct
+:c:type:`v4l2_modulator`. In order to enable the RDS
+transmission one must set the ``V4L2_TUNER_SUB_RDS`` bit in the
+``txsubchans`` field of struct
+:c:type:`v4l2_modulator`. If the driver only passes RDS
+blocks without interpreting the data the ``V4L2_TUNER_CAP_RDS_BLOCK_IO``
+flag has to be set. If the tuner is capable of handling RDS entities
+like program identification codes and radio text, the flag
+``V4L2_TUNER_CAP_RDS_CONTROLS`` should be set, see
+:ref:`Writing RDS data <writing-rds-data>` and
+:ref:`FM Transmitter Control Reference <fm-tx-controls>`.
+
+
+.. _reading-rds-data:
+
+Reading RDS data
+================
+
+RDS data can be read from the radio device with the
+:ref:`read() <func-read>` function. The data is packed in groups of
+three bytes.
+
+
+.. _writing-rds-data:
+
+Writing RDS data
+================
+
+RDS data can be written to the radio device with the
+:ref:`write() <func-write>` function. The data is packed in groups of
+three bytes, as follows:
+
+
+RDS datastructures
+==================
+
+
+.. c:type:: v4l2_rds_data
+
+.. tabularcolumns:: |p{2.5cm}|p{2.5cm}|p{12.5cm}|
+
+.. flat-table:: struct v4l2_rds_data
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 5
+
+    * - __u8
+      - ``lsb``
+      - Least Significant Byte of RDS Block
+    * - __u8
+      - ``msb``
+      - Most Significant Byte of RDS Block
+    * - __u8
+      - ``block``
+      - Block description
+
+
+
+.. _v4l2-rds-block:
+
+.. tabularcolumns:: |p{2.9cm}|p{14.6cm}|
+
+.. flat-table:: Block description
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 5
+
+    * - Bits 0-2
+      - Block (aka offset) of the received data.
+    * - Bits 3-5
+      - Deprecated. Currently identical to bits 0-2. Do not use these
+	bits.
+    * - Bit 6
+      - Corrected bit. Indicates that an error was corrected for this data
+	block.
+    * - Bit 7
+      - Error bit. Indicates that an uncorrectable error occurred during
+	reception of this block.
+
+
+
+.. _v4l2-rds-block-codes:
+
+.. tabularcolumns:: |p{6.4cm}|p{2.0cm}|p{1.2cm}|p{7.9cm}|
+
+.. flat-table:: Block defines
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 1 5
+
+    * - V4L2_RDS_BLOCK_MSK
+      -
+      - 7
+      - Mask for bits 0-2 to get the block ID.
+    * - V4L2_RDS_BLOCK_A
+      -
+      - 0
+      - Block A.
+    * - V4L2_RDS_BLOCK_B
+      -
+      - 1
+      - Block B.
+    * - V4L2_RDS_BLOCK_C
+      -
+      - 2
+      - Block C.
+    * - V4L2_RDS_BLOCK_D
+      -
+      - 3
+      - Block D.
+    * - V4L2_RDS_BLOCK_C_ALT
+      -
+      - 4
+      - Block C'.
+    * - V4L2_RDS_BLOCK_INVALID
+      - read-only
+      - 7
+      - An invalid block.
+    * - V4L2_RDS_BLOCK_CORRECTED
+      - read-only
+      - 0x40
+      - A bit error was detected but corrected.
+    * - V4L2_RDS_BLOCK_ERROR
+      - read-only
+      - 0x80
+      - An uncorrectable error occurred.
diff --git a/Documentation/userspace-api/media/v4l/dev-sdr.rst b/Documentation/userspace-api/media/v4l/dev-sdr.rst
new file mode 100644
index 000000000000..c9563bca444e
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/dev-sdr.rst
@@ -0,0 +1,114 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _sdr:
+
+**************************************
+Software Defined Radio Interface (SDR)
+**************************************
+
+SDR is an abbreviation of Software Defined Radio, the radio device which
+uses application software for modulation or demodulation. This interface
+is intended for controlling and data streaming of such devices.
+
+SDR devices are accessed through character device special files named
+``/dev/swradio0`` to ``/dev/swradio255`` with major number 81 and
+dynamically allocated minor numbers 0 to 255.
+
+
+Querying Capabilities
+=====================
+
+Devices supporting the SDR receiver interface set the
+``V4L2_CAP_SDR_CAPTURE`` and ``V4L2_CAP_TUNER`` flag in the
+``capabilities`` field of struct
+:c:type:`v4l2_capability` returned by the
+:ref:`VIDIOC_QUERYCAP` ioctl. That flag means the
+device has an Analog to Digital Converter (ADC), which is a mandatory
+element for the SDR receiver.
+
+Devices supporting the SDR transmitter interface set the
+``V4L2_CAP_SDR_OUTPUT`` and ``V4L2_CAP_MODULATOR`` flag in the
+``capabilities`` field of struct
+:c:type:`v4l2_capability` returned by the
+:ref:`VIDIOC_QUERYCAP` ioctl. That flag means the
+device has an Digital to Analog Converter (DAC), which is a mandatory
+element for the SDR transmitter.
+
+At least one of the read/write, streaming or asynchronous I/O methods
+must be supported.
+
+
+Supplemental Functions
+======================
+
+SDR devices can support :ref:`controls <control>`, and must support
+the :ref:`tuner` ioctls. Tuner ioctls are used for setting the
+ADC/DAC sampling rate (sampling frequency) and the possible radio
+frequency (RF).
+
+The ``V4L2_TUNER_SDR`` tuner type is used for setting SDR device ADC/DAC
+frequency, and the ``V4L2_TUNER_RF`` tuner type is used for setting
+radio frequency. The tuner index of the RF tuner (if any) must always
+follow the SDR tuner index. Normally the SDR tuner is #0 and the RF
+tuner is #1.
+
+The :ref:`VIDIOC_S_HW_FREQ_SEEK` ioctl is
+not supported.
+
+
+Data Format Negotiation
+=======================
+
+The SDR device uses the :ref:`format` ioctls to select the
+capture and output format. Both the sampling resolution and the data
+streaming format are bound to that selectable format. In addition to the
+basic :ref:`format` ioctls, the
+:ref:`VIDIOC_ENUM_FMT` ioctl must be supported as
+well.
+
+To use the :ref:`format` ioctls applications set the ``type``
+field of a struct :c:type:`v4l2_format` to
+``V4L2_BUF_TYPE_SDR_CAPTURE`` or ``V4L2_BUF_TYPE_SDR_OUTPUT`` and use
+the struct :c:type:`v4l2_sdr_format` ``sdr`` member
+of the ``fmt`` union as needed per the desired operation. Currently
+there is two fields, ``pixelformat`` and ``buffersize``, of struct
+struct :c:type:`v4l2_sdr_format` which are used.
+Content of the ``pixelformat`` is V4L2 FourCC code of the data format.
+The ``buffersize`` field is maximum buffer size in bytes required for
+data transfer, set by the driver in order to inform application.
+
+
+.. c:type:: v4l2_sdr_format
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. flat-table:: struct v4l2_sdr_format
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``pixelformat``
+      - The data format or type of compression, set by the application.
+	This is a little endian
+	:ref:`four character code <v4l2-fourcc>`. V4L2 defines SDR
+	formats in :ref:`sdr-formats`.
+    * - __u32
+      - ``buffersize``
+      - Maximum size in bytes required for data. Value is set by the
+	driver.
+    * - __u8
+      - ``reserved[24]``
+      - This array is reserved for future extensions. Drivers and
+	applications must set it to zero.
+
+
+An SDR device may support :ref:`read/write <rw>` and/or streaming
+(:ref:`memory mapping <mmap>` or :ref:`user pointer <userp>`) I/O.
diff --git a/Documentation/userspace-api/media/v4l/dev-sliced-vbi.rst b/Documentation/userspace-api/media/v4l/dev-sliced-vbi.rst
new file mode 100644
index 000000000000..dd0b6646beb5
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/dev-sliced-vbi.rst
@@ -0,0 +1,669 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _sliced:
+
+*************************
+Sliced VBI Data Interface
+*************************
+
+VBI stands for Vertical Blanking Interval, a gap in the sequence of
+lines of an analog video signal. During VBI no picture information is
+transmitted, allowing some time while the electron beam of a cathode ray
+tube TV returns to the top of the screen.
+
+Sliced VBI devices use hardware to demodulate data transmitted in the
+VBI. V4L2 drivers shall *not* do this by software, see also the
+:ref:`raw VBI interface <raw-vbi>`. The data is passed as short
+packets of fixed size, covering one scan line each. The number of
+packets per video frame is variable.
+
+Sliced VBI capture and output devices are accessed through the same
+character special files as raw VBI devices. When a driver supports both
+interfaces, the default function of a ``/dev/vbi`` device is *raw* VBI
+capturing or output, and the sliced VBI function is only available after
+calling the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl as defined
+below. Likewise a ``/dev/video`` device may support the sliced VBI API,
+however the default function here is video capturing or output.
+Different file descriptors must be used to pass raw and sliced VBI data
+simultaneously, if this is supported by the driver.
+
+
+Querying Capabilities
+=====================
+
+Devices supporting the sliced VBI capturing or output API set the
+``V4L2_CAP_SLICED_VBI_CAPTURE`` or ``V4L2_CAP_SLICED_VBI_OUTPUT`` flag
+respectively, in the ``capabilities`` field of struct
+:c:type:`v4l2_capability` returned by the
+:ref:`VIDIOC_QUERYCAP` ioctl. At least one of the
+read/write, streaming or asynchronous :ref:`I/O methods <io>` must be
+supported. Sliced VBI devices may have a tuner or modulator.
+
+
+Supplemental Functions
+======================
+
+Sliced VBI devices shall support :ref:`video input or output <video>`
+and :ref:`tuner or modulator <tuner>` ioctls if they have these
+capabilities, and they may support :ref:`control` ioctls.
+The :ref:`video standard <standard>` ioctls provide information vital
+to program a sliced VBI device, therefore must be supported.
+
+
+.. _sliced-vbi-format-negotitation:
+
+Sliced VBI Format Negotiation
+=============================
+
+To find out which data services are supported by the hardware
+applications can call the
+:ref:`VIDIOC_G_SLICED_VBI_CAP <VIDIOC_G_SLICED_VBI_CAP>` ioctl.
+All drivers implementing the sliced VBI interface must support this
+ioctl. The results may differ from those of the
+:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl when the number of VBI
+lines the hardware can capture or output per frame, or the number of
+services it can identify on a given line are limited. For example on PAL
+line 16 the hardware may be able to look for a VPS or Teletext signal,
+but not both at the same time.
+
+To determine the currently selected services applications set the
+``type`` field of struct :c:type:`v4l2_format` to
+``V4L2_BUF_TYPE_SLICED_VBI_CAPTURE`` or
+``V4L2_BUF_TYPE_SLICED_VBI_OUTPUT``, and the
+:ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` ioctl fills the ``fmt.sliced``
+member, a struct
+:c:type:`v4l2_sliced_vbi_format`.
+
+Applications can request different parameters by initializing or
+modifying the ``fmt.sliced`` member and calling the
+:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl with a pointer to the
+struct :c:type:`v4l2_format` structure.
+
+The sliced VBI API is more complicated than the raw VBI API because the
+hardware must be told which VBI service to expect on each scan line. Not
+all services may be supported by the hardware on all lines (this is
+especially true for VBI output where Teletext is often unsupported and
+other services can only be inserted in one specific line). In many
+cases, however, it is sufficient to just set the ``service_set`` field
+to the required services and let the driver fill the ``service_lines``
+array according to hardware capabilities. Only if more precise control
+is needed should the programmer set the ``service_lines`` array
+explicitly.
+
+The :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl modifies the parameters
+according to hardware capabilities. When the driver allocates resources
+at this point, it may return an ``EBUSY`` error code if the required
+resources are temporarily unavailable. Other resource allocation points
+which may return ``EBUSY`` can be the
+:ref:`VIDIOC_STREAMON` ioctl and the first
+:ref:`read() <func-read>`, :ref:`write() <func-write>` and
+:ref:`select() <func-select>` call.
+
+
+.. c:type:: v4l2_sliced_vbi_format
+
+struct v4l2_sliced_vbi_format
+-----------------------------
+
+.. raw:: latex
+
+    \begingroup
+    \scriptsize
+    \setlength{\tabcolsep}{2pt}
+
+.. tabularcolumns:: |p{.85cm}|p{3.3cm}|p{4.4cm}|p{4.4cm}|p{4.4cm}|
+
+.. cssclass:: longtable
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 3 2 2 2
+
+    * - __u32
+      - ``service_set``
+      - :cspan:`2`
+
+	If ``service_set`` is non-zero when passed with
+	:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` or
+	:ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>`, the ``service_lines``
+	array will be filled by the driver according to the services
+	specified in this field. For example, if ``service_set`` is
+	initialized with ``V4L2_SLICED_TELETEXT_B | V4L2_SLICED_WSS_625``,
+	a driver for the cx25840 video decoder sets lines 7-22 of both
+	fields [#f1]_ to ``V4L2_SLICED_TELETEXT_B`` and line 23 of the first
+	field to ``V4L2_SLICED_WSS_625``. If ``service_set`` is set to
+	zero, then the values of ``service_lines`` will be used instead.
+
+	On return the driver sets this field to the union of all elements
+	of the returned ``service_lines`` array. It may contain less
+	services than requested, perhaps just one, if the hardware cannot
+	handle more services simultaneously. It may be empty (zero) if
+	none of the requested services are supported by the hardware.
+    * - __u16
+      - ``service_lines``\ [2][24]
+      - :cspan:`2`
+
+	Applications initialize this array with sets of data services the
+	driver shall look for or insert on the respective scan line.
+	Subject to hardware capabilities drivers return the requested set,
+	a subset, which may be just a single service, or an empty set.
+	When the hardware cannot handle multiple services on the same line
+	the driver shall choose one. No assumptions can be made on which
+	service the driver chooses.
+
+	Data services are defined in :ref:`vbi-services2`. Array indices
+	map to ITU-R line numbers\ [#f2]_ as follows:
+    * -
+      -
+      - Element
+      - 525 line systems
+      - 625 line systems
+    * -
+      -
+      - ``service_lines``\ [0][1]
+      - 1
+      - 1
+    * -
+      -
+      - ``service_lines``\ [0][23]
+      - 23
+      - 23
+    * -
+      -
+      - ``service_lines``\ [1][1]
+      - 264
+      - 314
+    * -
+      -
+      - ``service_lines``\ [1][23]
+      - 286
+      - 336
+    * -
+      -
+      - :cspan:`2` Drivers must set ``service_lines`` [0][0] and
+	``service_lines``\ [1][0] to zero. The
+	``V4L2_VBI_ITU_525_F1_START``, ``V4L2_VBI_ITU_525_F2_START``,
+	``V4L2_VBI_ITU_625_F1_START`` and ``V4L2_VBI_ITU_625_F2_START``
+	defines give the start line numbers for each field for each 525 or
+	625 line format as a convenience. Don't forget that ITU line
+	numbering starts at 1, not 0.
+    * - __u32
+      - ``io_size``
+      - :cspan:`2` Maximum number of bytes passed by one
+	:ref:`read() <func-read>` or :ref:`write() <func-write>` call,
+	and the buffer size in bytes for the
+	:ref:`VIDIOC_QBUF` and
+	:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl. Drivers set this field
+	to the size of struct
+	:c:type:`v4l2_sliced_vbi_data` times the
+	number of non-zero elements in the returned ``service_lines``
+	array (that is the number of lines potentially carrying data).
+    * - __u32
+      - ``reserved``\ [2]
+      - :cspan:`2` This array is reserved for future extensions.
+
+	Applications and drivers must set it to zero.
+
+.. raw:: latex
+
+    \endgroup
+
+.. _vbi-services2:
+
+Sliced VBI services
+-------------------
+
+.. raw:: latex
+
+    \scriptsize
+
+.. tabularcolumns:: |p{4.1cm}|p{1.1cm}|p{2.4cm}|p{2.0cm}|p{7.3cm}|
+
+.. flat-table::
+    :header-rows:  1
+    :stub-columns: 0
+    :widths:       2 1 1 2 2
+
+    * - Symbol
+      - Value
+      - Reference
+      - Lines, usually
+      - Payload
+    * - ``V4L2_SLICED_TELETEXT_B`` (Teletext System B)
+      - 0x0001
+      - :ref:`ets300706`,
+
+	:ref:`itu653`
+      - PAL/SECAM line 7-22, 320-335 (second field 7-22)
+      - Last 42 of the 45 byte Teletext packet, that is without clock
+	run-in and framing code, lsb first transmitted.
+    * - ``V4L2_SLICED_VPS``
+      - 0x0400
+      - :ref:`ets300231`
+      - PAL line 16
+      - Byte number 3 to 15 according to Figure 9 of ETS 300 231, lsb
+	first transmitted.
+    * - ``V4L2_SLICED_CAPTION_525``
+      - 0x1000
+      - :ref:`cea608`
+      - NTSC line 21, 284 (second field 21)
+      - Two bytes in transmission order, including parity bit, lsb first
+	transmitted.
+    * - ``V4L2_SLICED_WSS_625``
+      - 0x4000
+      - :ref:`itu1119`,
+
+	:ref:`en300294`
+      - PAL/SECAM line 23
+      -
+
+	::
+
+	    Byte         0                 1
+		  msb         lsb  msb           lsb
+	     Bit  7 6 5 4 3 2 1 0  x x 13 12 11 10 9
+    * - ``V4L2_SLICED_VBI_525``
+      - 0x1000
+      - :cspan:`2` Set of services applicable to 525 line systems.
+    * - ``V4L2_SLICED_VBI_625``
+      - 0x4401
+      - :cspan:`2` Set of services applicable to 625 line systems.
+
+.. raw:: latex
+
+    \normalsize
+
+
+Drivers may return an ``EINVAL`` error code when applications attempt to
+read or write data without prior format negotiation, after switching the
+video standard (which may invalidate the negotiated VBI parameters) and
+after switching the video input (which may change the video standard as
+a side effect). The :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl may
+return an ``EBUSY`` error code when applications attempt to change the
+format while i/o is in progress (between a
+:ref:`VIDIOC_STREAMON` and
+:ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` call, and after the first
+:ref:`read() <func-read>` or :ref:`write() <func-write>` call).
+
+
+Reading and writing sliced VBI data
+===================================
+
+A single :ref:`read() <func-read>` or :ref:`write() <func-write>`
+call must pass all data belonging to one video frame. That is an array
+of struct :c:type:`v4l2_sliced_vbi_data` structures with one or
+more elements and a total size not exceeding ``io_size`` bytes. Likewise
+in streaming I/O mode one buffer of ``io_size`` bytes must contain data
+of one video frame. The ``id`` of unused
+struct :c:type:`v4l2_sliced_vbi_data` elements must be zero.
+
+
+.. c:type:: v4l2_sliced_vbi_data
+
+struct v4l2_sliced_vbi_data
+---------------------------
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - __u32
+      - ``id``
+      - A flag from :ref:`vbi-services` identifying the type of data in
+	this packet. Only a single bit must be set. When the ``id`` of a
+	captured packet is zero, the packet is empty and the contents of
+	other fields are undefined. Applications shall ignore empty
+	packets. When the ``id`` of a packet for output is zero the
+	contents of the ``data`` field are undefined and the driver must
+	no longer insert data on the requested ``field`` and ``line``.
+    * - __u32
+      - ``field``
+      - The video field number this data has been captured from, or shall
+	be inserted at. ``0`` for the first field, ``1`` for the second
+	field.
+    * - __u32
+      - ``line``
+      - The field (as opposed to frame) line number this data has been
+	captured from, or shall be inserted at. See :ref:`vbi-525` and
+	:ref:`vbi-625` for valid values. Sliced VBI capture devices can
+	set the line number of all packets to ``0`` if the hardware cannot
+	reliably identify scan lines. The field number must always be
+	valid.
+    * - __u32
+      - ``reserved``
+      - This field is reserved for future extensions. Applications and
+	drivers must set it to zero.
+    * - __u8
+      - ``data``\ [48]
+      - The packet payload. See :ref:`vbi-services` for the contents and
+	number of bytes passed for each data type. The contents of padding
+	bytes at the end of this array are undefined, drivers and
+	applications shall ignore them.
+
+
+Packets are always passed in ascending line number order, without
+duplicate line numbers. The :ref:`write() <func-write>` function and
+the :ref:`VIDIOC_QBUF` ioctl must return an ``EINVAL``
+error code when applications violate this rule. They must also return an
+EINVAL error code when applications pass an incorrect field or line
+number, or a combination of ``field``, ``line`` and ``id`` which has not
+been negotiated with the :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` or
+:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl. When the line numbers are
+unknown the driver must pass the packets in transmitted order. The
+driver can insert empty packets with ``id`` set to zero anywhere in the
+packet array.
+
+To assure synchronization and to distinguish from frame dropping, when a
+captured frame does not carry any of the requested data services drivers
+must pass one or more empty packets. When an application fails to pass
+VBI data in time for output, the driver must output the last VPS and WSS
+packet again, and disable the output of Closed Caption and Teletext
+data, or output data which is ignored by Closed Caption and Teletext
+decoders.
+
+A sliced VBI device may support :ref:`read/write <rw>` and/or
+streaming (:ref:`memory mapping <mmap>` and/or
+:ref:`user pointer <userp>`) I/O. The latter bears the possibility of
+synchronizing video and VBI data by using buffer timestamps.
+
+
+Sliced VBI Data in MPEG Streams
+===============================
+
+If a device can produce an MPEG output stream, it may be capable of
+providing
+:ref:`negotiated sliced VBI services <sliced-vbi-format-negotitation>`
+as data embedded in the MPEG stream. Users or applications control this
+sliced VBI data insertion with the
+:ref:`V4L2_CID_MPEG_STREAM_VBI_FMT <v4l2-mpeg-stream-vbi-fmt>`
+control.
+
+If the driver does not provide the
+:ref:`V4L2_CID_MPEG_STREAM_VBI_FMT <v4l2-mpeg-stream-vbi-fmt>`
+control, or only allows that control to be set to
+:ref:`V4L2_MPEG_STREAM_VBI_FMT_NONE <v4l2-mpeg-stream-vbi-fmt>`,
+then the device cannot embed sliced VBI data in the MPEG stream.
+
+The
+:ref:`V4L2_CID_MPEG_STREAM_VBI_FMT <v4l2-mpeg-stream-vbi-fmt>`
+control does not implicitly set the device driver to capture nor cease
+capturing sliced VBI data. The control only indicates to embed sliced
+VBI data in the MPEG stream, if an application has negotiated sliced VBI
+service be captured.
+
+It may also be the case that a device can embed sliced VBI data in only
+certain types of MPEG streams: for example in an MPEG-2 PS but not an
+MPEG-2 TS. In this situation, if sliced VBI data insertion is requested,
+the sliced VBI data will be embedded in MPEG stream types when
+supported, and silently omitted from MPEG stream types where sliced VBI
+data insertion is not supported by the device.
+
+The following subsections specify the format of the embedded sliced VBI
+data.
+
+
+MPEG Stream Embedded, Sliced VBI Data Format: NONE
+--------------------------------------------------
+
+The
+:ref:`V4L2_MPEG_STREAM_VBI_FMT_NONE <v4l2-mpeg-stream-vbi-fmt>`
+embedded sliced VBI format shall be interpreted by drivers as a control
+to cease embedding sliced VBI data in MPEG streams. Neither the device
+nor driver shall insert "empty" embedded sliced VBI data packets in the
+MPEG stream when this format is set. No MPEG stream data structures are
+specified for this format.
+
+
+MPEG Stream Embedded, Sliced VBI Data Format: IVTV
+--------------------------------------------------
+
+The
+:ref:`V4L2_MPEG_STREAM_VBI_FMT_IVTV <v4l2-mpeg-stream-vbi-fmt>`
+embedded sliced VBI format, when supported, indicates to the driver to
+embed up to 36 lines of sliced VBI data per frame in an MPEG-2 *Private
+Stream 1 PES* packet encapsulated in an MPEG-2 *Program Pack* in the
+MPEG stream.
+
+*Historical context*: This format specification originates from a
+custom, embedded, sliced VBI data format used by the ``ivtv`` driver.
+This format has already been informally specified in the kernel sources
+in the file ``Documentation/userspace-api/media/drivers/cx2341x-uapi.rst`` . The
+maximum size of the payload and other aspects of this format are driven
+by the CX23415 MPEG decoder's capabilities and limitations with respect
+to extracting, decoding, and displaying sliced VBI data embedded within
+an MPEG stream.
+
+This format's use is *not* exclusive to the ``ivtv`` driver *nor*
+exclusive to CX2341x devices, as the sliced VBI data packet insertion
+into the MPEG stream is implemented in driver software. At least the
+``cx18`` driver provides sliced VBI data insertion into an MPEG-2 PS in
+this format as well.
+
+The following definitions specify the payload of the MPEG-2 *Private
+Stream 1 PES* packets that contain sliced VBI data when
+:ref:`V4L2_MPEG_STREAM_VBI_FMT_IVTV <v4l2-mpeg-stream-vbi-fmt>`
+is set. (The MPEG-2 *Private Stream 1 PES* packet header and
+encapsulating MPEG-2 *Program Pack* header are not detailed here. Please
+refer to the MPEG-2 specifications for details on those packet headers.)
+
+The payload of the MPEG-2 *Private Stream 1 PES* packets that contain
+sliced VBI data is specified by struct
+:c:type:`v4l2_mpeg_vbi_fmt_ivtv`. The
+payload is variable length, depending on the actual number of lines of
+sliced VBI data present in a video frame. The payload may be padded at
+the end with unspecified fill bytes to align the end of the payload to a
+4-byte boundary. The payload shall never exceed 1552 bytes (2 fields
+with 18 lines/field with 43 bytes of data/line and a 4 byte magic
+number).
+
+
+.. c:type:: v4l2_mpeg_vbi_fmt_ivtv
+
+struct v4l2_mpeg_vbi_fmt_ivtv
+-----------------------------
+
+.. tabularcolumns:: |p{1.0cm}|p{3.8cm}|p{1.0cm}|p{11.2cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u8
+      - ``magic``\ [4]
+      - A "magic" constant from :ref:`v4l2-mpeg-vbi-fmt-ivtv-magic` that
+	indicates this is a valid sliced VBI data payload and also
+	indicates which member of the anonymous union, ``itv0`` or
+	``ITV0``, to use for the payload data.
+    * - union {
+      - (anonymous)
+    * - struct :c:type:`v4l2_mpeg_vbi_itv0`
+      - ``itv0``
+      - The primary form of the sliced VBI data payload that contains
+	anywhere from 1 to 35 lines of sliced VBI data. Line masks are
+	provided in this form of the payload indicating which VBI lines
+	are provided.
+    * - struct :ref:`v4l2_mpeg_vbi_ITV0 <v4l2-mpeg-vbi-itv0-1>`
+      - ``ITV0``
+      - An alternate form of the sliced VBI data payload used when 36
+	lines of sliced VBI data are present. No line masks are provided
+	in this form of the payload; all valid line mask bits are
+	implcitly set.
+    * - }
+      -
+
+.. _v4l2-mpeg-vbi-fmt-ivtv-magic:
+
+Magic Constants for struct v4l2_mpeg_vbi_fmt_ivtv magic field
+-------------------------------------------------------------
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. flat-table::
+    :header-rows:  1
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - Defined Symbol
+      - Value
+      - Description
+    * - ``V4L2_MPEG_VBI_IVTV_MAGIC0``
+      - "itv0"
+      - Indicates the ``itv0`` member of the union in struct
+	:c:type:`v4l2_mpeg_vbi_fmt_ivtv` is
+	valid.
+    * - ``V4L2_MPEG_VBI_IVTV_MAGIC1``
+      - "ITV0"
+      - Indicates the ``ITV0`` member of the union in struct
+	:c:type:`v4l2_mpeg_vbi_fmt_ivtv` is
+	valid and that 36 lines of sliced VBI data are present.
+
+
+
+.. c:type:: v4l2_mpeg_vbi_itv0
+
+.. c:type:: v4l2_mpeg_vbi_ITV0
+
+structs v4l2_mpeg_vbi_itv0 and v4l2_mpeg_vbi_ITV0
+-------------------------------------------------
+
+.. tabularcolumns:: |p{5.2cm}|p{2.4cm}|p{9.9cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __le32
+      - ``linemask``\ [2]
+      - Bitmasks indicating the VBI service lines present. These
+	``linemask`` values are stored in little endian byte order in the
+	MPEG stream. Some reference ``linemask`` bit positions with their
+	corresponding VBI line number and video field are given below.
+	b\ :sub:`0` indicates the least significant bit of a ``linemask``
+	value:
+
+
+
+	::
+
+	    linemask[0] b0:     line  6  first field
+	    linemask[0] b17:    line 23  first field
+	    linemask[0] b18:    line  6  second field
+	    linemask[0] b31:    line 19  second field
+	    linemask[1] b0:     line 20  second field
+	    linemask[1] b3:     line 23  second field
+	    linemask[1] b4-b31: unused and set to 0
+    * - struct
+	:c:type:`v4l2_mpeg_vbi_itv0_line`
+      - ``line``\ [35]
+      - This is a variable length array that holds from 1 to 35 lines of
+	sliced VBI data. The sliced VBI data lines present correspond to
+	the bits set in the ``linemask`` array, starting from b\ :sub:`0`
+	of ``linemask``\ [0] up through b\ :sub:`31` of ``linemask``\ [0],
+	and from b\ :sub:`0` of ``linemask``\ [1] up through b\ :sub:`3` of
+	``linemask``\ [1]. ``line``\ [0] corresponds to the first bit
+	found set in the ``linemask`` array, ``line``\ [1] corresponds to
+	the second bit found set in the ``linemask`` array, etc. If no
+	``linemask`` array bits are set, then ``line``\ [0] may contain
+	one line of unspecified data that should be ignored by
+	applications.
+
+
+
+.. _v4l2-mpeg-vbi-itv0-1:
+
+struct v4l2_mpeg_vbi_ITV0
+-------------------------
+
+.. tabularcolumns:: |p{5.2cm}|p{2.4cm}|p{9.9cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - struct
+	:c:type:`v4l2_mpeg_vbi_itv0_line`
+      - ``line``\ [36]
+      - A fixed length array of 36 lines of sliced VBI data. ``line``\ [0]
+	through ``line``\ [17] correspond to lines 6 through 23 of the
+	first field. ``line``\ [18] through ``line``\ [35] corresponds to
+	lines 6 through 23 of the second field.
+
+
+
+.. c:type:: v4l2_mpeg_vbi_itv0_line
+
+struct v4l2_mpeg_vbi_itv0_line
+------------------------------
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u8
+      - ``id``
+      - A line identifier value from
+	:ref:`ITV0-Line-Identifier-Constants` that indicates the type of
+	sliced VBI data stored on this line.
+    * - __u8
+      - ``data``\ [42]
+      - The sliced VBI data for the line.
+
+
+
+.. _ITV0-Line-Identifier-Constants:
+
+Line Identifiers for struct v4l2_mpeg_vbi_itv0_line id field
+------------------------------------------------------------
+
+.. tabularcolumns:: |p{7.0cm}|p{1.8cm}|p{8.7cm}|
+
+.. flat-table::
+    :header-rows:  1
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - Defined Symbol
+      - Value
+      - Description
+    * - ``V4L2_MPEG_VBI_IVTV_TELETEXT_B``
+      - 1
+      - Refer to :ref:`Sliced VBI services <vbi-services2>` for a
+	description of the line payload.
+    * - ``V4L2_MPEG_VBI_IVTV_CAPTION_525``
+      - 4
+      - Refer to :ref:`Sliced VBI services <vbi-services2>` for a
+	description of the line payload.
+    * - ``V4L2_MPEG_VBI_IVTV_WSS_625``
+      - 5
+      - Refer to :ref:`Sliced VBI services <vbi-services2>` for a
+	description of the line payload.
+    * - ``V4L2_MPEG_VBI_IVTV_VPS``
+      - 7
+      - Refer to :ref:`Sliced VBI services <vbi-services2>` for a
+	description of the line payload.
+
+
+
+.. [#f1]
+   According to :ref:`ETS 300 706 <ets300706>` lines 6-22 of the first
+   field and lines 5-22 of the second field may carry Teletext data.
+
+.. [#f2]
+   See also :ref:`vbi-525` and :ref:`vbi-625`.
diff --git a/Documentation/userspace-api/media/v4l/dev-stateless-decoder.rst b/Documentation/userspace-api/media/v4l/dev-stateless-decoder.rst
new file mode 100644
index 000000000000..4a26646eeec5
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/dev-stateless-decoder.rst
@@ -0,0 +1,424 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. _stateless_decoder:
+
+**************************************************
+Memory-to-memory Stateless Video Decoder Interface
+**************************************************
+
+A stateless decoder is a decoder that works without retaining any kind of state
+between processed frames. This means that each frame is decoded independently
+of any previous and future frames, and that the client is responsible for
+maintaining the decoding state and providing it to the decoder with each
+decoding request. This is in contrast to the stateful video decoder interface,
+where the hardware and driver maintain the decoding state and all the client
+has to do is to provide the raw encoded stream and dequeue decoded frames in
+display order.
+
+This section describes how user-space ("the client") is expected to communicate
+with stateless decoders in order to successfully decode an encoded stream.
+Compared to stateful codecs, the decoder/client sequence is simpler, but the
+cost of this simplicity is extra complexity in the client which is responsible
+for maintaining a consistent decoding state.
+
+Stateless decoders make use of the :ref:`media-request-api`. A stateless
+decoder must expose the ``V4L2_BUF_CAP_SUPPORTS_REQUESTS`` capability on its
+``OUTPUT`` queue when :c:func:`VIDIOC_REQBUFS` or :c:func:`VIDIOC_CREATE_BUFS`
+are invoked.
+
+Depending on the encoded formats supported by the decoder, a single decoded
+frame may be the result of several decode requests (for instance, H.264 streams
+with multiple slices per frame). Decoders that support such formats must also
+expose the ``V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF`` capability on their
+``OUTPUT`` queue.
+
+Querying capabilities
+=====================
+
+1. To enumerate the set of coded formats supported by the decoder, the client
+   calls :c:func:`VIDIOC_ENUM_FMT` on the ``OUTPUT`` queue.
+
+   * The driver must always return the full set of supported ``OUTPUT`` formats,
+     irrespective of the format currently set on the ``CAPTURE`` queue.
+
+   * Simultaneously, the driver must restrain the set of values returned by
+     codec-specific capability controls (such as H.264 profiles) to the set
+     actually supported by the hardware.
+
+2. To enumerate the set of supported raw formats, the client calls
+   :c:func:`VIDIOC_ENUM_FMT` on the ``CAPTURE`` queue.
+
+   * The driver must return only the formats supported for the format currently
+     active on the ``OUTPUT`` queue.
+
+   * Depending on the currently set ``OUTPUT`` format, the set of supported raw
+     formats may depend on the value of some codec-dependent controls.
+     The client is responsible for making sure that these controls are set
+     before querying the ``CAPTURE`` queue. Failure to do so will result in the
+     default values for these controls being used, and a returned set of formats
+     that may not be usable for the media the client is trying to decode.
+
+3. The client may use :c:func:`VIDIOC_ENUM_FRAMESIZES` to detect supported
+   resolutions for a given format, passing desired pixel format in
+   :c:type:`v4l2_frmsizeenum`'s ``pixel_format``.
+
+4. Supported profiles and levels for the current ``OUTPUT`` format, if
+   applicable, may be queried using their respective controls via
+   :c:func:`VIDIOC_QUERYCTRL`.
+
+Initialization
+==============
+
+1. Set the coded format on the ``OUTPUT`` queue via :c:func:`VIDIOC_S_FMT`.
+
+   * **Required fields:**
+
+     ``type``
+         a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.
+
+     ``pixelformat``
+         a coded pixel format.
+
+     ``width``, ``height``
+         coded width and height parsed from the stream.
+
+     other fields
+         follow standard semantics.
+
+   .. note::
+
+      Changing the ``OUTPUT`` format may change the currently set ``CAPTURE``
+      format. The driver will derive a new ``CAPTURE`` format from the
+      ``OUTPUT`` format being set, including resolution, colorimetry
+      parameters, etc. If the client needs a specific ``CAPTURE`` format,
+      it must adjust it afterwards.
+
+2. Call :c:func:`VIDIOC_S_EXT_CTRLS` to set all the controls (parsed headers,
+   etc.) required by the ``OUTPUT`` format to enumerate the ``CAPTURE`` formats.
+
+3. Call :c:func:`VIDIOC_G_FMT` for ``CAPTURE`` queue to get the format for the
+   destination buffers parsed/decoded from the bytestream.
+
+   * **Required fields:**
+
+     ``type``
+         a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
+
+   * **Returned fields:**
+
+     ``width``, ``height``
+         frame buffer resolution for the decoded frames.
+
+     ``pixelformat``
+         pixel format for decoded frames.
+
+     ``num_planes`` (for _MPLANE ``type`` only)
+         number of planes for pixelformat.
+
+     ``sizeimage``, ``bytesperline``
+         as per standard semantics; matching frame buffer format.
+
+   .. note::
+
+      The value of ``pixelformat`` may be any pixel format supported for the
+      ``OUTPUT`` format, based on the hardware capabilities. It is suggested
+      that the driver chooses the preferred/optimal format for the current
+      configuration. For example, a YUV format may be preferred over an RGB
+      format, if an additional conversion step would be required for RGB.
+
+4. *[optional]* Enumerate ``CAPTURE`` formats via :c:func:`VIDIOC_ENUM_FMT` on
+   the ``CAPTURE`` queue. The client may use this ioctl to discover which
+   alternative raw formats are supported for the current ``OUTPUT`` format and
+   select one of them via :c:func:`VIDIOC_S_FMT`.
+
+   .. note::
+
+      The driver will return only formats supported for the currently selected
+      ``OUTPUT`` format and currently set controls, even if more formats may be
+      supported by the decoder in general.
+
+      For example, a decoder may support YUV and RGB formats for
+      resolutions 1920x1088 and lower, but only YUV for higher resolutions (due
+      to hardware limitations). After setting a resolution of 1920x1088 or lower
+      as the ``OUTPUT`` format, :c:func:`VIDIOC_ENUM_FMT` may return a set of
+      YUV and RGB pixel formats, but after setting a resolution higher than
+      1920x1088, the driver will not return RGB pixel formats, since they are
+      unsupported for this resolution.
+
+5. *[optional]* Choose a different ``CAPTURE`` format than suggested via
+   :c:func:`VIDIOC_S_FMT` on ``CAPTURE`` queue. It is possible for the client to
+   choose a different format than selected/suggested by the driver in
+   :c:func:`VIDIOC_G_FMT`.
+
+    * **Required fields:**
+
+      ``type``
+          a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
+
+      ``pixelformat``
+          a raw pixel format.
+
+      ``width``, ``height``
+         frame buffer resolution of the decoded stream; typically unchanged from
+         what was returned with :c:func:`VIDIOC_G_FMT`, but it may be different
+         if the hardware supports composition and/or scaling.
+
+   After performing this step, the client must perform step 3 again in order
+   to obtain up-to-date information about the buffers size and layout.
+
+6. Allocate source (bytestream) buffers via :c:func:`VIDIOC_REQBUFS` on
+   ``OUTPUT`` queue.
+
+    * **Required fields:**
+
+      ``count``
+          requested number of buffers to allocate; greater than zero.
+
+      ``type``
+          a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.
+
+      ``memory``
+          follows standard semantics.
+
+    * **Return fields:**
+
+      ``count``
+          actual number of buffers allocated.
+
+    * If required, the driver will adjust ``count`` to be equal or bigger to the
+      minimum of required number of ``OUTPUT`` buffers for the given format and
+      requested count. The client must check this value after the ioctl returns
+      to get the actual number of buffers allocated.
+
+7. Allocate destination (raw format) buffers via :c:func:`VIDIOC_REQBUFS` on the
+   ``CAPTURE`` queue.
+
+    * **Required fields:**
+
+      ``count``
+          requested number of buffers to allocate; greater than zero. The client
+          is responsible for deducing the minimum number of buffers required
+          for the stream to be properly decoded (taking e.g. reference frames
+          into account) and pass an equal or bigger number.
+
+      ``type``
+          a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
+
+      ``memory``
+          follows standard semantics. ``V4L2_MEMORY_USERPTR`` is not supported
+          for ``CAPTURE`` buffers.
+
+    * **Return fields:**
+
+      ``count``
+          adjusted to allocated number of buffers, in case the codec requires
+          more buffers than requested.
+
+    * The driver must adjust count to the minimum of required number of
+      ``CAPTURE`` buffers for the current format, stream configuration and
+      requested count. The client must check this value after the ioctl
+      returns to get the number of buffers allocated.
+
+8. Allocate requests (likely one per ``OUTPUT`` buffer) via
+    :c:func:`MEDIA_IOC_REQUEST_ALLOC` on the media device.
+
+9. Start streaming on both ``OUTPUT`` and ``CAPTURE`` queues via
+    :c:func:`VIDIOC_STREAMON`.
+
+Decoding
+========
+
+For each frame, the client is responsible for submitting at least one request to
+which the following is attached:
+
+* The amount of encoded data expected by the codec for its current
+  configuration, as a buffer submitted to the ``OUTPUT`` queue. Typically, this
+  corresponds to one frame worth of encoded data, but some formats may allow (or
+  require) different amounts per unit.
+* All the metadata needed to decode the submitted encoded data, in the form of
+  controls relevant to the format being decoded.
+
+The amount of data and contents of the source ``OUTPUT`` buffer, as well as the
+controls that must be set on the request, depend on the active coded pixel
+format and might be affected by codec-specific extended controls, as stated in
+documentation of each format.
+
+If there is a possibility that the decoded frame will require one or more
+decode requests after the current one in order to be produced, then the client
+must set the ``V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF`` flag on the ``OUTPUT``
+buffer. This will result in the (potentially partially) decoded ``CAPTURE``
+buffer not being made available for dequeueing, and reused for the next decode
+request if the timestamp of the next ``OUTPUT`` buffer has not changed.
+
+A typical frame would thus be decoded using the following sequence:
+
+1. Queue an ``OUTPUT`` buffer containing one unit of encoded bytestream data for
+   the decoding request, using :c:func:`VIDIOC_QBUF`.
+
+    * **Required fields:**
+
+      ``index``
+          index of the buffer being queued.
+
+      ``type``
+          type of the buffer.
+
+      ``bytesused``
+          number of bytes taken by the encoded data frame in the buffer.
+
+      ``flags``
+          the ``V4L2_BUF_FLAG_REQUEST_FD`` flag must be set. Additionally, if
+          we are not sure that the current decode request is the last one needed
+          to produce a fully decoded frame, then
+          ``V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF`` must also be set.
+
+      ``request_fd``
+          must be set to the file descriptor of the decoding request.
+
+      ``timestamp``
+          must be set to a unique value per frame. This value will be propagated
+          into the decoded frame's buffer and can also be used to use this frame
+          as the reference of another. If using multiple decode requests per
+          frame, then the timestamps of all the ``OUTPUT`` buffers for a given
+          frame must be identical. If the timestamp changes, then the currently
+          held ``CAPTURE`` buffer will be made available for dequeuing and the
+          current request will work on a new ``CAPTURE`` buffer.
+
+2. Set the codec-specific controls for the decoding request, using
+   :c:func:`VIDIOC_S_EXT_CTRLS`.
+
+    * **Required fields:**
+
+      ``which``
+          must be ``V4L2_CTRL_WHICH_REQUEST_VAL``.
+
+      ``request_fd``
+          must be set to the file descriptor of the decoding request.
+
+      other fields
+          other fields are set as usual when setting controls. The ``controls``
+          array must contain all the codec-specific controls required to decode
+          a frame.
+
+   .. note::
+
+      It is possible to specify the controls in different invocations of
+      :c:func:`VIDIOC_S_EXT_CTRLS`, or to overwrite a previously set control, as
+      long as ``request_fd`` and ``which`` are properly set. The controls state
+      at the moment of request submission is the one that will be considered.
+
+   .. note::
+
+      The order in which steps 1 and 2 take place is interchangeable.
+
+3. Submit the request by invoking :c:func:`MEDIA_REQUEST_IOC_QUEUE` on the
+   request FD.
+
+    If the request is submitted without an ``OUTPUT`` buffer, or if some of the
+    required controls are missing from the request, then
+    :c:func:`MEDIA_REQUEST_IOC_QUEUE` will return ``-ENOENT``. If more than one
+    ``OUTPUT`` buffer is queued, then it will return ``-EINVAL``.
+    :c:func:`MEDIA_REQUEST_IOC_QUEUE` returning non-zero means that no
+    ``CAPTURE`` buffer will be produced for this request.
+
+``CAPTURE`` buffers must not be part of the request, and are queued
+independently. They are returned in decode order (i.e. the same order as coded
+frames were submitted to the ``OUTPUT`` queue).
+
+Runtime decoding errors are signaled by the dequeued ``CAPTURE`` buffers
+carrying the ``V4L2_BUF_FLAG_ERROR`` flag. If a decoded reference frame has an
+error, then all following decoded frames that refer to it also have the
+``V4L2_BUF_FLAG_ERROR`` flag set, although the decoder will still try to
+produce (likely corrupted) frames.
+
+Buffer management while decoding
+================================
+Contrary to stateful decoders, a stateless decoder does not perform any kind of
+buffer management: it only guarantees that dequeued ``CAPTURE`` buffers can be
+used by the client for as long as they are not queued again. "Used" here
+encompasses using the buffer for compositing or display.
+
+A dequeued capture buffer can also be used as the reference frame of another
+buffer.
+
+A frame is specified as reference by converting its timestamp into nanoseconds,
+and storing it into the relevant member of a codec-dependent control structure.
+The :c:func:`v4l2_timeval_to_ns` function must be used to perform that
+conversion. The timestamp of a frame can be used to reference it as soon as all
+its units of encoded data are successfully submitted to the ``OUTPUT`` queue.
+
+A decoded buffer containing a reference frame must not be reused as a decoding
+target until all the frames referencing it have been decoded. The safest way to
+achieve this is to refrain from queueing a reference buffer until all the
+decoded frames referencing it have been dequeued. However, if the driver can
+guarantee that buffers queued to the ``CAPTURE`` queue are processed in queued
+order, then user-space can take advantage of this guarantee and queue a
+reference buffer when the following conditions are met:
+
+1. All the requests for frames affected by the reference frame have been
+   queued, and
+
+2. A sufficient number of ``CAPTURE`` buffers to cover all the decoded
+   referencing frames have been queued.
+
+When queuing a decoding request, the driver will increase the reference count of
+all the resources associated with reference frames. This means that the client
+can e.g. close the DMABUF file descriptors of reference frame buffers if it
+won't need them afterwards.
+
+Seeking
+=======
+In order to seek, the client just needs to submit requests using input buffers
+corresponding to the new stream position. It must however be aware that
+resolution may have changed and follow the dynamic resolution change sequence in
+that case. Also depending on the codec used, picture parameters (e.g. SPS/PPS
+for H.264) may have changed and the client is responsible for making sure that a
+valid state is sent to the decoder.
+
+The client is then free to ignore any returned ``CAPTURE`` buffer that comes
+from the pre-seek position.
+
+Pausing
+=======
+
+In order to pause, the client can just cease queuing buffers onto the ``OUTPUT``
+queue. Without source bytestream data, there is no data to process and the codec
+will remain idle.
+
+Dynamic resolution change
+=========================
+
+If the client detects a resolution change in the stream, it will need to perform
+the initialization sequence again with the new resolution:
+
+1. If the last submitted request resulted in a ``CAPTURE`` buffer being
+   held by the use of the ``V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF`` flag, then the
+   last frame is not available on the ``CAPTURE`` queue. In this case, a
+   ``V4L2_DEC_CMD_FLUSH`` command shall be sent. This will make the driver
+   dequeue the held ``CAPTURE`` buffer.
+
+2. Wait until all submitted requests have completed and dequeue the
+   corresponding output buffers.
+
+3. Call :c:func:`VIDIOC_STREAMOFF` on both the ``OUTPUT`` and ``CAPTURE``
+   queues.
+
+4. Free all ``CAPTURE`` buffers by calling :c:func:`VIDIOC_REQBUFS` on the
+   ``CAPTURE`` queue with a buffer count of zero.
+
+5. Perform the initialization sequence again (minus the allocation of
+   ``OUTPUT`` buffers), with the new resolution set on the ``OUTPUT`` queue.
+   Note that due to resolution constraints, a different format may need to be
+   picked on the ``CAPTURE`` queue.
+
+Drain
+=====
+
+If the last submitted request resulted in a ``CAPTURE`` buffer being
+held by the use of the ``V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF`` flag, then the
+last frame is not available on the ``CAPTURE`` queue. In this case, a
+``V4L2_DEC_CMD_FLUSH`` command shall be sent. This will make the driver
+dequeue the held ``CAPTURE`` buffer.
+
+After that, in order to drain the stream on a stateless decoder, the client
+just needs to wait until all the submitted requests are completed.
diff --git a/Documentation/userspace-api/media/v4l/dev-subdev.rst b/Documentation/userspace-api/media/v4l/dev-subdev.rst
new file mode 100644
index 000000000000..0c1a5f50ee21
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/dev-subdev.rst
@@ -0,0 +1,503 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _subdev:
+
+********************
+Sub-device Interface
+********************
+
+The complex nature of V4L2 devices, where hardware is often made of
+several integrated circuits that need to interact with each other in a
+controlled way, leads to complex V4L2 drivers. The drivers usually
+reflect the hardware model in software, and model the different hardware
+components as software blocks called sub-devices.
+
+V4L2 sub-devices are usually kernel-only objects. If the V4L2 driver
+implements the media device API, they will automatically inherit from
+media entities. Applications will be able to enumerate the sub-devices
+and discover the hardware topology using the media entities, pads and
+links enumeration API.
+
+In addition to make sub-devices discoverable, drivers can also choose to
+make them directly configurable by applications. When both the
+sub-device driver and the V4L2 device driver support this, sub-devices
+will feature a character device node on which ioctls can be called to
+
+-  query, read and write sub-devices controls
+
+-  subscribe and unsubscribe to events and retrieve them
+
+-  negotiate image formats on individual pads
+
+Sub-device character device nodes, conventionally named
+``/dev/v4l-subdev*``, use major number 81.
+
+
+Controls
+========
+
+Most V4L2 controls are implemented by sub-device hardware. Drivers
+usually merge all controls and expose them through video device nodes.
+Applications can control all sub-devices through a single interface.
+
+Complex devices sometimes implement the same control in different pieces
+of hardware. This situation is common in embedded platforms, where both
+sensors and image processing hardware implement identical functions,
+such as contrast adjustment, white balance or faulty pixels correction.
+As the V4L2 controls API doesn't support several identical controls in a
+single device, all but one of the identical controls are hidden.
+
+Applications can access those hidden controls through the sub-device
+node with the V4L2 control API described in :ref:`control`. The ioctls
+behave identically as when issued on V4L2 device nodes, with the
+exception that they deal only with controls implemented in the
+sub-device.
+
+Depending on the driver, those controls might also be exposed through
+one (or several) V4L2 device nodes.
+
+
+Events
+======
+
+V4L2 sub-devices can notify applications of events as described in
+:ref:`event`. The API behaves identically as when used on V4L2 device
+nodes, with the exception that it only deals with events generated by
+the sub-device. Depending on the driver, those events might also be
+reported on one (or several) V4L2 device nodes.
+
+
+.. _pad-level-formats:
+
+Pad-level Formats
+=================
+
+.. warning::
+
+    Pad-level formats are only applicable to very complex devices that
+    need to expose low-level format configuration to user space. Generic
+    V4L2 applications do *not* need to use the API described in this
+    section.
+
+.. note::
+
+    For the purpose of this section, the term *format* means the
+    combination of media bus data format, frame width and frame height.
+
+Image formats are typically negotiated on video capture and output
+devices using the format and
+:ref:`selection <VIDIOC_SUBDEV_G_SELECTION>` ioctls. The driver is
+responsible for configuring every block in the video pipeline according
+to the requested format at the pipeline input and/or output.
+
+For complex devices, such as often found in embedded systems, identical
+image sizes at the output of a pipeline can be achieved using different
+hardware configurations. One such example is shown on
+:ref:`pipeline-scaling`, where image scaling can be performed on both
+the video sensor and the host image processing hardware.
+
+
+.. _pipeline-scaling:
+
+.. kernel-figure:: pipeline.dot
+    :alt:   pipeline.dot
+    :align: center
+
+    Image Format Negotiation on Pipelines
+
+    High quality and high speed pipeline configuration
+
+
+
+The sensor scaler is usually of less quality than the host scaler, but
+scaling on the sensor is required to achieve higher frame rates.
+Depending on the use case (quality vs. speed), the pipeline must be
+configured differently. Applications need to configure the formats at
+every point in the pipeline explicitly.
+
+Drivers that implement the :ref:`media API <media-controller-intro>`
+can expose pad-level image format configuration to applications. When
+they do, applications can use the
+:ref:`VIDIOC_SUBDEV_G_FMT <VIDIOC_SUBDEV_G_FMT>` and
+:ref:`VIDIOC_SUBDEV_S_FMT <VIDIOC_SUBDEV_G_FMT>` ioctls. to
+negotiate formats on a per-pad basis.
+
+Applications are responsible for configuring coherent parameters on the
+whole pipeline and making sure that connected pads have compatible
+formats. The pipeline is checked for formats mismatch at
+:ref:`VIDIOC_STREAMON <VIDIOC_STREAMON>` time, and an ``EPIPE`` error
+code is then returned if the configuration is invalid.
+
+Pad-level image format configuration support can be tested by calling
+the :ref:`VIDIOC_SUBDEV_G_FMT` ioctl on pad
+0. If the driver returns an ``EINVAL`` error code pad-level format
+configuration is not supported by the sub-device.
+
+
+Format Negotiation
+------------------
+
+Acceptable formats on pads can (and usually do) depend on a number of
+external parameters, such as formats on other pads, active links, or
+even controls. Finding a combination of formats on all pads in a video
+pipeline, acceptable to both application and driver, can't rely on
+formats enumeration only. A format negotiation mechanism is required.
+
+Central to the format negotiation mechanism are the get/set format
+operations. When called with the ``which`` argument set to
+:ref:`V4L2_SUBDEV_FORMAT_TRY <VIDIOC_SUBDEV_G_FMT>`, the
+:ref:`VIDIOC_SUBDEV_G_FMT <VIDIOC_SUBDEV_G_FMT>` and
+:ref:`VIDIOC_SUBDEV_S_FMT <VIDIOC_SUBDEV_G_FMT>` ioctls operate on
+a set of formats parameters that are not connected to the hardware
+configuration. Modifying those 'try' formats leaves the device state
+untouched (this applies to both the software state stored in the driver
+and the hardware state stored in the device itself).
+
+While not kept as part of the device state, try formats are stored in
+the sub-device file handles. A
+:ref:`VIDIOC_SUBDEV_G_FMT <VIDIOC_SUBDEV_G_FMT>` call will return
+the last try format set *on the same sub-device file handle*. Several
+applications querying the same sub-device at the same time will thus not
+interact with each other.
+
+To find out whether a particular format is supported by the device,
+applications use the
+:ref:`VIDIOC_SUBDEV_S_FMT <VIDIOC_SUBDEV_G_FMT>` ioctl. Drivers
+verify and, if needed, change the requested ``format`` based on device
+requirements and return the possibly modified value. Applications can
+then choose to try a different format or accept the returned value and
+continue.
+
+Formats returned by the driver during a negotiation iteration are
+guaranteed to be supported by the device. In particular, drivers
+guarantee that a returned format will not be further changed if passed
+to an :ref:`VIDIOC_SUBDEV_S_FMT <VIDIOC_SUBDEV_G_FMT>` call as-is
+(as long as external parameters, such as formats on other pads or links'
+configuration are not changed).
+
+Drivers automatically propagate formats inside sub-devices. When a try
+or active format is set on a pad, corresponding formats on other pads of
+the same sub-device can be modified by the driver. Drivers are free to
+modify formats as required by the device. However, they should comply
+with the following rules when possible:
+
+-  Formats should be propagated from sink pads to source pads. Modifying
+   a format on a source pad should not modify the format on any sink
+   pad.
+
+-  Sub-devices that scale frames using variable scaling factors should
+   reset the scale factors to default values when sink pads formats are
+   modified. If the 1:1 scaling ratio is supported, this means that
+   source pads formats should be reset to the sink pads formats.
+
+Formats are not propagated across links, as that would involve
+propagating them from one sub-device file handle to another.
+Applications must then take care to configure both ends of every link
+explicitly with compatible formats. Identical formats on the two ends of
+a link are guaranteed to be compatible. Drivers are free to accept
+different formats matching device requirements as being compatible.
+
+:ref:`sample-pipeline-config` shows a sample configuration sequence
+for the pipeline described in :ref:`pipeline-scaling` (table columns
+list entity names and pad numbers).
+
+
+.. raw:: latex
+
+    \scriptsize
+
+.. tabularcolumns:: |p{2.0cm}|p{2.3cm}|p{2.3cm}|p{2.3cm}|p{2.3cm}|p{2.3cm}|p{2.3cm}|
+
+.. _sample-pipeline-config:
+
+.. flat-table:: Sample Pipeline Configuration
+    :header-rows:  1
+    :stub-columns: 0
+    :widths: 5 5 5 5 5 5 5
+
+    * -
+      - Sensor/0
+
+        format
+      - Frontend/0
+
+        format
+      - Frontend/1
+
+        format
+      - Scaler/0
+
+        format
+      - Scaler/0
+
+        compose selection rectangle
+      - Scaler/1
+
+        format
+    * - Initial state
+      - 2048x1536
+
+        SGRBG8_1X8
+      - (default)
+      - (default)
+      - (default)
+      - (default)
+      - (default)
+    * - Configure frontend sink format
+      - 2048x1536
+
+        SGRBG8_1X8
+      - *2048x1536*
+
+        *SGRBG8_1X8*
+      - *2046x1534*
+
+        *SGRBG8_1X8*
+      - (default)
+      - (default)
+      - (default)
+    * - Configure scaler sink format
+      - 2048x1536
+
+        SGRBG8_1X8
+      - 2048x1536
+
+        SGRBG8_1X8
+      - 2046x1534
+
+        SGRBG8_1X8
+      - *2046x1534*
+
+        *SGRBG8_1X8*
+      - *0,0/2046x1534*
+      - *2046x1534*
+
+        *SGRBG8_1X8*
+    * - Configure scaler sink compose selection
+      - 2048x1536
+
+        SGRBG8_1X8
+      - 2048x1536
+
+        SGRBG8_1X8
+      - 2046x1534
+
+        SGRBG8_1X8
+      - 2046x1534
+
+        SGRBG8_1X8
+      - *0,0/1280x960*
+      - *1280x960*
+
+        *SGRBG8_1X8*
+
+.. raw:: latex
+
+    \normalsize
+
+1. Initial state. The sensor source pad format is set to its native 3MP
+   size and V4L2_MBUS_FMT_SGRBG8_1X8 media bus code. Formats on the
+   host frontend and scaler sink and source pads have the default
+   values, as well as the compose rectangle on the scaler's sink pad.
+
+2. The application configures the frontend sink pad format's size to
+   2048x1536 and its media bus code to V4L2_MBUS_FMT_SGRBG_1X8. The
+   driver propagates the format to the frontend source pad.
+
+3. The application configures the scaler sink pad format's size to
+   2046x1534 and the media bus code to V4L2_MBUS_FMT_SGRBG_1X8 to
+   match the frontend source size and media bus code. The media bus code
+   on the sink pad is set to V4L2_MBUS_FMT_SGRBG_1X8. The driver
+   propagates the size to the compose selection rectangle on the
+   scaler's sink pad, and the format to the scaler source pad.
+
+4. The application configures the size of the compose selection
+   rectangle of the scaler's sink pad 1280x960. The driver propagates
+   the size to the scaler's source pad format.
+
+When satisfied with the try results, applications can set the active
+formats by setting the ``which`` argument to
+``V4L2_SUBDEV_FORMAT_ACTIVE``. Active formats are changed exactly as try
+formats by drivers. To avoid modifying the hardware state during format
+negotiation, applications should negotiate try formats first and then
+modify the active settings using the try formats returned during the
+last negotiation iteration. This guarantees that the active format will
+be applied as-is by the driver without being modified.
+
+
+.. _v4l2-subdev-selections:
+
+Selections: cropping, scaling and composition
+---------------------------------------------
+
+Many sub-devices support cropping frames on their input or output pads
+(or possible even on both). Cropping is used to select the area of
+interest in an image, typically on an image sensor or a video decoder.
+It can also be used as part of digital zoom implementations to select
+the area of the image that will be scaled up.
+
+Crop settings are defined by a crop rectangle and represented in a
+struct :c:type:`v4l2_rect` by the coordinates of the top
+left corner and the rectangle size. Both the coordinates and sizes are
+expressed in pixels.
+
+As for pad formats, drivers store try and active rectangles for the
+selection targets :ref:`v4l2-selections-common`.
+
+On sink pads, cropping is applied relative to the current pad format.
+The pad format represents the image size as received by the sub-device
+from the previous block in the pipeline, and the crop rectangle
+represents the sub-image that will be transmitted further inside the
+sub-device for processing.
+
+The scaling operation changes the size of the image by scaling it to new
+dimensions. The scaling ratio isn't specified explicitly, but is implied
+from the original and scaled image sizes. Both sizes are represented by
+struct :c:type:`v4l2_rect`.
+
+Scaling support is optional. When supported by a subdev, the crop
+rectangle on the subdev's sink pad is scaled to the size configured
+using the
+:ref:`VIDIOC_SUBDEV_S_SELECTION <VIDIOC_SUBDEV_G_SELECTION>` IOCTL
+using ``V4L2_SEL_TGT_COMPOSE`` selection target on the same pad. If the
+subdev supports scaling but not composing, the top and left values are
+not used and must always be set to zero.
+
+On source pads, cropping is similar to sink pads, with the exception
+that the source size from which the cropping is performed, is the
+COMPOSE rectangle on the sink pad. In both sink and source pads, the
+crop rectangle must be entirely contained inside the source image size
+for the crop operation.
+
+The drivers should always use the closest possible rectangle the user
+requests on all selection targets, unless specifically told otherwise.
+``V4L2_SEL_FLAG_GE`` and ``V4L2_SEL_FLAG_LE`` flags may be used to round
+the image size either up or down. :ref:`v4l2-selection-flags`
+
+
+Types of selection targets
+--------------------------
+
+
+Actual targets
+^^^^^^^^^^^^^^
+
+Actual targets (without a postfix) reflect the actual hardware
+configuration at any point of time. There is a BOUNDS target
+corresponding to every actual target.
+
+
+BOUNDS targets
+^^^^^^^^^^^^^^
+
+BOUNDS targets is the smallest rectangle that contains all valid actual
+rectangles. It may not be possible to set the actual rectangle as large
+as the BOUNDS rectangle, however. This may be because e.g. a sensor's
+pixel array is not rectangular but cross-shaped or round. The maximum
+size may also be smaller than the BOUNDS rectangle.
+
+
+Order of configuration and format propagation
+---------------------------------------------
+
+Inside subdevs, the order of image processing steps will always be from
+the sink pad towards the source pad. This is also reflected in the order
+in which the configuration must be performed by the user: the changes
+made will be propagated to any subsequent stages. If this behaviour is
+not desired, the user must set ``V4L2_SEL_FLAG_KEEP_CONFIG`` flag. This
+flag causes no propagation of the changes are allowed in any
+circumstances. This may also cause the accessed rectangle to be adjusted
+by the driver, depending on the properties of the underlying hardware.
+
+The coordinates to a step always refer to the actual size of the
+previous step. The exception to this rule is the sink compose
+rectangle, which refers to the sink compose bounds rectangle --- if it
+is supported by the hardware.
+
+1. Sink pad format. The user configures the sink pad format. This format
+   defines the parameters of the image the entity receives through the
+   pad for further processing.
+
+2. Sink pad actual crop selection. The sink pad crop defines the crop
+   performed to the sink pad format.
+
+3. Sink pad actual compose selection. The size of the sink pad compose
+   rectangle defines the scaling ratio compared to the size of the sink
+   pad crop rectangle. The location of the compose rectangle specifies
+   the location of the actual sink compose rectangle in the sink compose
+   bounds rectangle.
+
+4. Source pad actual crop selection. Crop on the source pad defines crop
+   performed to the image in the sink compose bounds rectangle.
+
+5. Source pad format. The source pad format defines the output pixel
+   format of the subdev, as well as the other parameters with the
+   exception of the image width and height. Width and height are defined
+   by the size of the source pad actual crop selection.
+
+Accessing any of the above rectangles not supported by the subdev will
+return ``EINVAL``. Any rectangle referring to a previous unsupported
+rectangle coordinates will instead refer to the previous supported
+rectangle. For example, if sink crop is not supported, the compose
+selection will refer to the sink pad format dimensions instead.
+
+
+.. _subdev-image-processing-crop:
+
+.. kernel-figure:: subdev-image-processing-crop.svg
+    :alt:   subdev-image-processing-crop.svg
+    :align: center
+
+    **Figure 4.5. Image processing in subdevs: simple crop example**
+
+In the above example, the subdev supports cropping on its sink pad. To
+configure it, the user sets the media bus format on the subdev's sink
+pad. Now the actual crop rectangle can be set on the sink pad --- the
+location and size of this rectangle reflect the location and size of a
+rectangle to be cropped from the sink format. The size of the sink crop
+rectangle will also be the size of the format of the subdev's source
+pad.
+
+
+.. _subdev-image-processing-scaling-multi-source:
+
+.. kernel-figure:: subdev-image-processing-scaling-multi-source.svg
+    :alt:   subdev-image-processing-scaling-multi-source.svg
+    :align: center
+
+    **Figure 4.6. Image processing in subdevs: scaling with multiple sources**
+
+In this example, the subdev is capable of first cropping, then scaling
+and finally cropping for two source pads individually from the resulting
+scaled image. The location of the scaled image in the cropped image is
+ignored in sink compose target. Both of the locations of the source crop
+rectangles refer to the sink scaling rectangle, independently cropping
+an area at location specified by the source crop rectangle from it.
+
+
+.. _subdev-image-processing-full:
+
+.. kernel-figure:: subdev-image-processing-full.svg
+    :alt:    subdev-image-processing-full.svg
+    :align:  center
+
+    **Figure 4.7. Image processing in subdevs: scaling and composition with multiple sinks and sources**
+
+The subdev driver supports two sink pads and two source pads. The images
+from both of the sink pads are individually cropped, then scaled and
+further composed on the composition bounds rectangle. From that, two
+independent streams are cropped and sent out of the subdev from the
+source pads.
+
+
+.. toctree::
+    :maxdepth: 1
+
+    subdev-formats
diff --git a/Documentation/userspace-api/media/v4l/dev-touch.rst b/Documentation/userspace-api/media/v4l/dev-touch.rst
new file mode 100644
index 000000000000..c1ce446274f2
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/dev-touch.rst
@@ -0,0 +1,63 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _touch:
+
+*************
+Touch Devices
+*************
+
+Touch devices are accessed through character device special files named
+``/dev/v4l-touch0`` to ``/dev/v4l-touch255`` with major number 81 and
+dynamically allocated minor numbers 0 to 255.
+
+Overview
+========
+
+Sensors may be Optical, or Projected Capacitive touch (PCT).
+
+Processing is required to analyse the raw data and produce input events. In
+some systems, this may be performed on the ASIC and the raw data is purely a
+side-channel for diagnostics or tuning. In other systems, the ASIC is a simple
+analogue front end device which delivers touch data at high rate, and any touch
+processing must be done on the host.
+
+For capacitive touch sensing, the touchscreen is composed of an array of
+horizontal and vertical conductors (alternatively called rows/columns, X/Y
+lines, or tx/rx). Mutual Capacitance measured is at the nodes where the
+conductors cross. Alternatively, Self Capacitance measures the signal from each
+column and row independently.
+
+A touch input may be determined by comparing the raw capacitance measurement to
+a no-touch reference (or "baseline") measurement:
+
+Delta = Raw - Reference
+
+The reference measurement takes account of variations in the capacitance across
+the touch sensor matrix, for example manufacturing irregularities,
+environmental or edge effects.
+
+Querying Capabilities
+=====================
+
+Devices supporting the touch interface set the ``V4L2_CAP_VIDEO_CAPTURE`` flag
+and the ``V4L2_CAP_TOUCH`` flag in the ``capabilities`` field of
+:c:type:`v4l2_capability` returned by the
+:ref:`VIDIOC_QUERYCAP` ioctl.
+
+At least one of the read/write or streaming I/O methods must be
+supported.
+
+The formats supported by touch devices are documented in
+:ref:`Touch Formats <tch-formats>`.
+
+Data Format Negotiation
+=======================
+
+A touch device may support any I/O method.
diff --git a/Documentation/userspace-api/media/v4l/devices.rst b/Documentation/userspace-api/media/v4l/devices.rst
new file mode 100644
index 000000000000..47ffe90753dd
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/devices.rst
@@ -0,0 +1,33 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _devices:
+
+**********
+Interfaces
+**********
+
+
+.. toctree::
+    :maxdepth: 1
+
+    dev-capture
+    dev-overlay
+    dev-output
+    dev-osd
+    dev-mem2mem
+    dev-raw-vbi
+    dev-sliced-vbi
+    dev-radio
+    dev-rds
+    dev-sdr
+    dev-touch
+    dev-event
+    dev-subdev
+    dev-meta
diff --git a/Documentation/userspace-api/media/v4l/diff-v4l.rst b/Documentation/userspace-api/media/v4l/diff-v4l.rst
new file mode 100644
index 000000000000..37644d26c4ae
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/diff-v4l.rst
@@ -0,0 +1,693 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _diff-v4l:
+
+********************************
+Differences between V4L and V4L2
+********************************
+
+The Video For Linux API was first introduced in Linux 2.1 to unify and
+replace various TV and radio device related interfaces, developed
+independently by driver writers in prior years. Starting with Linux 2.5
+the much improved V4L2 API replaces the V4L API. The support for the old
+V4L calls were removed from Kernel, but the library :ref:`libv4l`
+supports the conversion of a V4L API system call into a V4L2 one.
+
+
+Opening and Closing Devices
+===========================
+
+For compatibility reasons the character device file names recommended
+for V4L2 video capture, overlay, radio and raw vbi capture devices did
+not change from those used by V4L. They are listed in :ref:`devices`
+and below in :ref:`v4l-dev`.
+
+The teletext devices (minor range 192-223) have been removed in V4L2 and
+no longer exist. There is no hardware available anymore for handling
+pure teletext. Instead raw or sliced VBI is used.
+
+The V4L ``videodev`` module automatically assigns minor numbers to
+drivers in load order, depending on the registered device type. We
+recommend that V4L2 drivers by default register devices with the same
+numbers, but the system administrator can assign arbitrary minor numbers
+using driver module options. The major device number remains 81.
+
+
+.. _v4l-dev:
+
+.. flat-table:: V4L Device Types, Names and Numbers
+    :header-rows:  1
+    :stub-columns: 0
+
+    * - Device Type
+      - File Name
+      - Minor Numbers
+    * - Video capture and overlay
+      - ``/dev/video`` and ``/dev/bttv0``\  [#f1]_, ``/dev/video0`` to
+	``/dev/video63``
+      - 0-63
+    * - Radio receiver
+      - ``/dev/radio``\  [#f2]_, ``/dev/radio0`` to ``/dev/radio63``
+      - 64-127
+    * - Raw VBI capture
+      - ``/dev/vbi``, ``/dev/vbi0`` to ``/dev/vbi31``
+      - 224-255
+
+
+V4L prohibits (or used to prohibit) multiple opens of a device file.
+V4L2 drivers *may* support multiple opens, see :ref:`open` for details
+and consequences.
+
+V4L drivers respond to V4L2 ioctls with an ``EINVAL`` error code.
+
+
+Querying Capabilities
+=====================
+
+The V4L ``VIDIOCGCAP`` ioctl is equivalent to V4L2's
+:ref:`VIDIOC_QUERYCAP`.
+
+The ``name`` field in struct ``video_capability`` became
+``card`` in struct :c:type:`v4l2_capability`, ``type``
+was replaced by ``capabilities``. Note V4L2 does not distinguish between
+device types like this, better think of basic video input, video output
+and radio devices supporting a set of related functions like video
+capturing, video overlay and VBI capturing. See :ref:`open` for an
+introduction.
+
+.. tabularcolumns:: |p{5.5cm}|p{6.5cm}|p{5.5cm}
+
+.. cssclass:: longtable
+
+.. flat-table::
+    :header-rows:  1
+    :stub-columns: 0
+
+    * - ``struct video_capability`` ``type``
+      - struct :c:type:`v4l2_capability`
+	``capabilities`` flags
+      - Purpose
+    * - ``VID_TYPE_CAPTURE``
+      - ``V4L2_CAP_VIDEO_CAPTURE``
+      - The :ref:`video capture <capture>` interface is supported.
+    * - ``VID_TYPE_TUNER``
+      - ``V4L2_CAP_TUNER``
+      - The device has a :ref:`tuner or modulator <tuner>`.
+    * - ``VID_TYPE_TELETEXT``
+      - ``V4L2_CAP_VBI_CAPTURE``
+      - The :ref:`raw VBI capture <raw-vbi>` interface is supported.
+    * - ``VID_TYPE_OVERLAY``
+      - ``V4L2_CAP_VIDEO_OVERLAY``
+      - The :ref:`video overlay <overlay>` interface is supported.
+    * - ``VID_TYPE_CHROMAKEY``
+      - ``V4L2_FBUF_CAP_CHROMAKEY`` in field ``capability`` of struct
+	:c:type:`v4l2_framebuffer`
+      - Whether chromakey overlay is supported. For more information on
+	overlay see :ref:`overlay`.
+    * - ``VID_TYPE_CLIPPING``
+      - ``V4L2_FBUF_CAP_LIST_CLIPPING`` and
+	``V4L2_FBUF_CAP_BITMAP_CLIPPING`` in field ``capability`` of
+	struct :c:type:`v4l2_framebuffer`
+      - Whether clipping the overlaid image is supported, see
+	:ref:`overlay`.
+    * - ``VID_TYPE_FRAMERAM``
+      - ``V4L2_FBUF_CAP_EXTERNOVERLAY`` *not set* in field ``capability``
+	of struct :c:type:`v4l2_framebuffer`
+      - Whether overlay overwrites frame buffer memory, see
+	:ref:`overlay`.
+    * - ``VID_TYPE_SCALES``
+      - ``-``
+      - This flag indicates if the hardware can scale images. The V4L2 API
+	implies the scale factor by setting the cropping dimensions and
+	image size with the :ref:`VIDIOC_S_CROP <VIDIOC_G_CROP>` and
+	:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl, respectively. The
+	driver returns the closest sizes possible. For more information on
+	cropping and scaling see :ref:`crop`.
+    * - ``VID_TYPE_MONOCHROME``
+      - ``-``
+      - Applications can enumerate the supported image formats with the
+	:ref:`VIDIOC_ENUM_FMT` ioctl to determine if
+	the device supports grey scale capturing only. For more
+	information on image formats see :ref:`pixfmt`.
+    * - ``VID_TYPE_SUBCAPTURE``
+      - ``-``
+      - Applications can call the :ref:`VIDIOC_G_CROP <VIDIOC_G_CROP>`
+	ioctl to determine if the device supports capturing a subsection
+	of the full picture ("cropping" in V4L2). If not, the ioctl
+	returns the ``EINVAL`` error code. For more information on cropping
+	and scaling see :ref:`crop`.
+    * - ``VID_TYPE_MPEG_DECODER``
+      - ``-``
+      - Applications can enumerate the supported image formats with the
+	:ref:`VIDIOC_ENUM_FMT` ioctl to determine if
+	the device supports MPEG streams.
+    * - ``VID_TYPE_MPEG_ENCODER``
+      - ``-``
+      - See above.
+    * - ``VID_TYPE_MJPEG_DECODER``
+      - ``-``
+      - See above.
+    * - ``VID_TYPE_MJPEG_ENCODER``
+      - ``-``
+      - See above.
+
+
+The ``audios`` field was replaced by ``capabilities`` flag
+``V4L2_CAP_AUDIO``, indicating *if* the device has any audio inputs or
+outputs. To determine their number applications can enumerate audio
+inputs with the :ref:`VIDIOC_G_AUDIO <VIDIOC_G_AUDIO>` ioctl. The
+audio ioctls are described in :ref:`audio`.
+
+The ``maxwidth``, ``maxheight``, ``minwidth`` and ``minheight`` fields
+were removed. Calling the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` or
+:ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` ioctl with the desired
+dimensions returns the closest size possible, taking into account the
+current video standard, cropping and scaling limitations.
+
+
+Video Sources
+=============
+
+V4L provides the ``VIDIOCGCHAN`` and ``VIDIOCSCHAN`` ioctl using struct
+``video_channel`` to enumerate the video inputs of a V4L
+device. The equivalent V4L2 ioctls are
+:ref:`VIDIOC_ENUMINPUT`,
+:ref:`VIDIOC_G_INPUT <VIDIOC_G_INPUT>` and
+:ref:`VIDIOC_S_INPUT <VIDIOC_G_INPUT>` using struct
+:c:type:`v4l2_input` as discussed in :ref:`video`.
+
+The ``channel`` field counting inputs was renamed to ``index``, the
+video input types were renamed as follows:
+
+
+
+.. flat-table::
+    :header-rows:  1
+    :stub-columns: 0
+
+    * - struct ``video_channel`` ``type``
+      - struct :c:type:`v4l2_input` ``type``
+    * - ``VIDEO_TYPE_TV``
+      - ``V4L2_INPUT_TYPE_TUNER``
+    * - ``VIDEO_TYPE_CAMERA``
+      - ``V4L2_INPUT_TYPE_CAMERA``
+
+
+Unlike the ``tuners`` field expressing the number of tuners of this
+input, V4L2 assumes each video input is connected to at most one tuner.
+However a tuner can have more than one input, i. e. RF connectors, and a
+device can have multiple tuners. The index number of the tuner
+associated with the input, if any, is stored in field ``tuner`` of
+struct :c:type:`v4l2_input`. Enumeration of tuners is
+discussed in :ref:`tuner`.
+
+The redundant ``VIDEO_VC_TUNER`` flag was dropped. Video inputs
+associated with a tuner are of type ``V4L2_INPUT_TYPE_TUNER``. The
+``VIDEO_VC_AUDIO`` flag was replaced by the ``audioset`` field. V4L2
+considers devices with up to 32 audio inputs. Each set bit in the
+``audioset`` field represents one audio input this video input combines
+with. For information about audio inputs and how to switch between them
+see :ref:`audio`.
+
+The ``norm`` field describing the supported video standards was replaced
+by ``std``. The V4L specification mentions a flag ``VIDEO_VC_NORM``
+indicating whether the standard can be changed. This flag was a later
+addition together with the ``norm`` field and has been removed in the
+meantime. V4L2 has a similar, albeit more comprehensive approach to
+video standards, see :ref:`standard` for more information.
+
+
+Tuning
+======
+
+The V4L ``VIDIOCGTUNER`` and ``VIDIOCSTUNER`` ioctl and struct
+``video_tuner`` can be used to enumerate the tuners of a
+V4L TV or radio device. The equivalent V4L2 ioctls are
+:ref:`VIDIOC_G_TUNER <VIDIOC_G_TUNER>` and
+:ref:`VIDIOC_S_TUNER <VIDIOC_G_TUNER>` using struct
+:c:type:`v4l2_tuner`. Tuners are covered in :ref:`tuner`.
+
+The ``tuner`` field counting tuners was renamed to ``index``. The fields
+``name``, ``rangelow`` and ``rangehigh`` remained unchanged.
+
+The ``VIDEO_TUNER_PAL``, ``VIDEO_TUNER_NTSC`` and ``VIDEO_TUNER_SECAM``
+flags indicating the supported video standards were dropped. This
+information is now contained in the associated struct
+:c:type:`v4l2_input`. No replacement exists for the
+``VIDEO_TUNER_NORM`` flag indicating whether the video standard can be
+switched. The ``mode`` field to select a different video standard was
+replaced by a whole new set of ioctls and structures described in
+:ref:`standard`. Due to its ubiquity it should be mentioned the BTTV
+driver supports several standards in addition to the regular
+``VIDEO_MODE_PAL`` (0), ``VIDEO_MODE_NTSC``, ``VIDEO_MODE_SECAM`` and
+``VIDEO_MODE_AUTO`` (3). Namely N/PAL Argentina, M/PAL, N/PAL, and NTSC
+Japan with numbers 3-6 (sic).
+
+The ``VIDEO_TUNER_STEREO_ON`` flag indicating stereo reception became
+``V4L2_TUNER_SUB_STEREO`` in field ``rxsubchans``. This field also
+permits the detection of monaural and bilingual audio, see the
+definition of struct :c:type:`v4l2_tuner` for details.
+Presently no replacement exists for the ``VIDEO_TUNER_RDS_ON`` and
+``VIDEO_TUNER_MBS_ON`` flags.
+
+The ``VIDEO_TUNER_LOW`` flag was renamed to ``V4L2_TUNER_CAP_LOW`` in
+the struct :c:type:`v4l2_tuner` ``capability`` field.
+
+The ``VIDIOCGFREQ`` and ``VIDIOCSFREQ`` ioctl to change the tuner
+frequency where renamed to
+:ref:`VIDIOC_G_FREQUENCY <VIDIOC_G_FREQUENCY>` and
+:ref:`VIDIOC_S_FREQUENCY <VIDIOC_G_FREQUENCY>`. They take a pointer
+to a struct :c:type:`v4l2_frequency` instead of an
+unsigned long integer.
+
+
+.. _v4l-image-properties:
+
+Image Properties
+================
+
+V4L2 has no equivalent of the ``VIDIOCGPICT`` and ``VIDIOCSPICT`` ioctl
+and struct ``video_picture``. The following fields where
+replaced by V4L2 controls accessible with the
+:ref:`VIDIOC_QUERYCTRL`,
+:ref:`VIDIOC_G_CTRL <VIDIOC_G_CTRL>` and
+:ref:`VIDIOC_S_CTRL <VIDIOC_G_CTRL>` ioctls:
+
+
+
+.. flat-table::
+    :header-rows:  1
+    :stub-columns: 0
+
+    * - struct ``video_picture``
+      - V4L2 Control ID
+    * - ``brightness``
+      - ``V4L2_CID_BRIGHTNESS``
+    * - ``hue``
+      - ``V4L2_CID_HUE``
+    * - ``colour``
+      - ``V4L2_CID_SATURATION``
+    * - ``contrast``
+      - ``V4L2_CID_CONTRAST``
+    * - ``whiteness``
+      - ``V4L2_CID_WHITENESS``
+
+
+The V4L picture controls are assumed to range from 0 to 65535 with no
+particular reset value. The V4L2 API permits arbitrary limits and
+defaults which can be queried with the
+:ref:`VIDIOC_QUERYCTRL` ioctl. For general
+information about controls see :ref:`control`.
+
+The ``depth`` (average number of bits per pixel) of a video image is
+implied by the selected image format. V4L2 does not explicitly provide
+such information assuming applications recognizing the format are aware
+of the image depth and others need not know. The ``palette`` field moved
+into the struct :c:type:`v4l2_pix_format`:
+
+
+
+.. flat-table::
+    :header-rows:  1
+    :stub-columns: 0
+
+    * - struct ``video_picture`` ``palette``
+      - struct :c:type:`v4l2_pix_format` ``pixfmt``
+    * - ``VIDEO_PALETTE_GREY``
+      - :ref:`V4L2_PIX_FMT_GREY <V4L2-PIX-FMT-GREY>`
+    * - ``VIDEO_PALETTE_HI240``
+      - :ref:`V4L2_PIX_FMT_HI240 <pixfmt-reserved>` [#f3]_
+    * - ``VIDEO_PALETTE_RGB565``
+      - :ref:`V4L2_PIX_FMT_RGB565 <pixfmt-rgb>`
+    * - ``VIDEO_PALETTE_RGB555``
+      - :ref:`V4L2_PIX_FMT_RGB555 <pixfmt-rgb>`
+    * - ``VIDEO_PALETTE_RGB24``
+      - :ref:`V4L2_PIX_FMT_BGR24 <pixfmt-rgb>`
+    * - ``VIDEO_PALETTE_RGB32``
+      - :ref:`V4L2_PIX_FMT_BGR32 <pixfmt-rgb>` [#f4]_
+    * - ``VIDEO_PALETTE_YUV422``
+      - :ref:`V4L2_PIX_FMT_YUYV <V4L2-PIX-FMT-YUYV>`
+    * - ``VIDEO_PALETTE_YUYV``\  [#f5]_
+      - :ref:`V4L2_PIX_FMT_YUYV <V4L2-PIX-FMT-YUYV>`
+    * - ``VIDEO_PALETTE_UYVY``
+      - :ref:`V4L2_PIX_FMT_UYVY <V4L2-PIX-FMT-UYVY>`
+    * - ``VIDEO_PALETTE_YUV420``
+      - None
+    * - ``VIDEO_PALETTE_YUV411``
+      - :ref:`V4L2_PIX_FMT_Y41P <V4L2-PIX-FMT-Y41P>` [#f6]_
+    * - ``VIDEO_PALETTE_RAW``
+      - None [#f7]_
+    * - ``VIDEO_PALETTE_YUV422P``
+      - :ref:`V4L2_PIX_FMT_YUV422P <V4L2-PIX-FMT-YUV422P>`
+    * - ``VIDEO_PALETTE_YUV411P``
+      - :ref:`V4L2_PIX_FMT_YUV411P <V4L2-PIX-FMT-YUV411P>` [#f8]_
+    * - ``VIDEO_PALETTE_YUV420P``
+      - :ref:`V4L2_PIX_FMT_YVU420 <V4L2-PIX-FMT-YVU420>`
+    * - ``VIDEO_PALETTE_YUV410P``
+      - :ref:`V4L2_PIX_FMT_YVU410 <V4L2-PIX-FMT-YVU410>`
+
+
+V4L2 image formats are defined in :ref:`pixfmt`. The image format can
+be selected with the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl.
+
+
+Audio
+=====
+
+The ``VIDIOCGAUDIO`` and ``VIDIOCSAUDIO`` ioctl and struct
+``video_audio`` are used to enumerate the audio inputs
+of a V4L device. The equivalent V4L2 ioctls are
+:ref:`VIDIOC_G_AUDIO <VIDIOC_G_AUDIO>` and
+:ref:`VIDIOC_S_AUDIO <VIDIOC_G_AUDIO>` using struct
+:c:type:`v4l2_audio` as discussed in :ref:`audio`.
+
+The ``audio`` "channel number" field counting audio inputs was renamed
+to ``index``.
+
+On ``VIDIOCSAUDIO`` the ``mode`` field selects *one* of the
+``VIDEO_SOUND_MONO``, ``VIDEO_SOUND_STEREO``, ``VIDEO_SOUND_LANG1`` or
+``VIDEO_SOUND_LANG2`` audio demodulation modes. When the current audio
+standard is BTSC ``VIDEO_SOUND_LANG2`` refers to SAP and
+``VIDEO_SOUND_LANG1`` is meaningless. Also undocumented in the V4L
+specification, there is no way to query the selected mode. On
+``VIDIOCGAUDIO`` the driver returns the *actually received* audio
+programmes in this field. In the V4L2 API this information is stored in
+the struct :c:type:`v4l2_tuner` ``rxsubchans`` and
+``audmode`` fields, respectively. See :ref:`tuner` for more
+information on tuners. Related to audio modes struct
+:c:type:`v4l2_audio` also reports if this is a mono or
+stereo input, regardless if the source is a tuner.
+
+The following fields where replaced by V4L2 controls accessible with the
+:ref:`VIDIOC_QUERYCTRL`,
+:ref:`VIDIOC_G_CTRL <VIDIOC_G_CTRL>` and
+:ref:`VIDIOC_S_CTRL <VIDIOC_G_CTRL>` ioctls:
+
+
+
+.. flat-table::
+    :header-rows:  1
+    :stub-columns: 0
+
+    * - struct ``video_audio``
+      - V4L2 Control ID
+    * - ``volume``
+      - ``V4L2_CID_AUDIO_VOLUME``
+    * - ``bass``
+      - ``V4L2_CID_AUDIO_BASS``
+    * - ``treble``
+      - ``V4L2_CID_AUDIO_TREBLE``
+    * - ``balance``
+      - ``V4L2_CID_AUDIO_BALANCE``
+
+
+To determine which of these controls are supported by a driver V4L
+provides the ``flags`` ``VIDEO_AUDIO_VOLUME``, ``VIDEO_AUDIO_BASS``,
+``VIDEO_AUDIO_TREBLE`` and ``VIDEO_AUDIO_BALANCE``. In the V4L2 API the
+:ref:`VIDIOC_QUERYCTRL` ioctl reports if the
+respective control is supported. Accordingly the ``VIDEO_AUDIO_MUTABLE``
+and ``VIDEO_AUDIO_MUTE`` flags where replaced by the boolean
+``V4L2_CID_AUDIO_MUTE`` control.
+
+All V4L2 controls have a ``step`` attribute replacing the struct
+``video_audio`` ``step`` field. The V4L audio controls
+are assumed to range from 0 to 65535 with no particular reset value. The
+V4L2 API permits arbitrary limits and defaults which can be queried with
+the :ref:`VIDIOC_QUERYCTRL` ioctl. For general
+information about controls see :ref:`control`.
+
+
+Frame Buffer Overlay
+====================
+
+The V4L2 ioctls equivalent to ``VIDIOCGFBUF`` and ``VIDIOCSFBUF`` are
+:ref:`VIDIOC_G_FBUF <VIDIOC_G_FBUF>` and
+:ref:`VIDIOC_S_FBUF <VIDIOC_G_FBUF>`. The ``base`` field of struct
+``video_buffer`` remained unchanged, except V4L2 defines
+a flag to indicate non-destructive overlays instead of a ``NULL``
+pointer. All other fields moved into the struct
+:c:type:`v4l2_pix_format` ``fmt`` substructure of
+struct :c:type:`v4l2_framebuffer`. The ``depth``
+field was replaced by ``pixelformat``. See :ref:`pixfmt-rgb` for a
+list of RGB formats and their respective color depths.
+
+Instead of the special ioctls ``VIDIOCGWIN`` and ``VIDIOCSWIN`` V4L2
+uses the general-purpose data format negotiation ioctls
+:ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` and
+:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`. They take a pointer to a struct
+:c:type:`v4l2_format` as argument. Here the ``win`` member
+of the ``fmt`` union is used, a struct
+:c:type:`v4l2_window`.
+
+The ``x``, ``y``, ``width`` and ``height`` fields of struct
+``video_window`` moved into struct
+:c:type:`v4l2_rect` substructure ``w`` of struct
+:c:type:`v4l2_window`. The ``chromakey``, ``clips``, and
+``clipcount`` fields remained unchanged. Struct
+``video_clip`` was renamed to struct
+:c:type:`v4l2_clip`, also containing a struct
+:c:type:`v4l2_rect`, but the semantics are still the same.
+
+The ``VIDEO_WINDOW_INTERLACE`` flag was dropped. Instead applications
+must set the ``field`` field to ``V4L2_FIELD_ANY`` or
+``V4L2_FIELD_INTERLACED``. The ``VIDEO_WINDOW_CHROMAKEY`` flag moved
+into struct :c:type:`v4l2_framebuffer`, under the new
+name ``V4L2_FBUF_FLAG_CHROMAKEY``.
+
+In V4L, storing a bitmap pointer in ``clips`` and setting ``clipcount``
+to ``VIDEO_CLIP_BITMAP`` (-1) requests bitmap clipping, using a fixed
+size bitmap of 1024 × 625 bits. Struct :c:type:`v4l2_window`
+has a separate ``bitmap`` pointer field for this purpose and the bitmap
+size is determined by ``w.width`` and ``w.height``.
+
+The ``VIDIOCCAPTURE`` ioctl to enable or disable overlay was renamed to
+:ref:`VIDIOC_OVERLAY`.
+
+
+Cropping
+========
+
+To capture only a subsection of the full picture V4L defines the
+``VIDIOCGCAPTURE`` and ``VIDIOCSCAPTURE`` ioctls using struct
+``video_capture``. The equivalent V4L2 ioctls are
+:ref:`VIDIOC_G_CROP <VIDIOC_G_CROP>` and
+:ref:`VIDIOC_S_CROP <VIDIOC_G_CROP>` using struct
+:c:type:`v4l2_crop`, and the related
+:ref:`VIDIOC_CROPCAP` ioctl. This is a rather
+complex matter, see :ref:`crop` for details.
+
+The ``x``, ``y``, ``width`` and ``height`` fields moved into struct
+:c:type:`v4l2_rect` substructure ``c`` of struct
+:c:type:`v4l2_crop`. The ``decimation`` field was dropped. In
+the V4L2 API the scaling factor is implied by the size of the cropping
+rectangle and the size of the captured or overlaid image.
+
+The ``VIDEO_CAPTURE_ODD`` and ``VIDEO_CAPTURE_EVEN`` flags to capture
+only the odd or even field, respectively, were replaced by
+``V4L2_FIELD_TOP`` and ``V4L2_FIELD_BOTTOM`` in the field named
+``field`` of struct :c:type:`v4l2_pix_format` and
+struct :c:type:`v4l2_window`. These structures are used to
+select a capture or overlay format with the
+:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl.
+
+
+Reading Images, Memory Mapping
+==============================
+
+
+Capturing using the read method
+-------------------------------
+
+There is no essential difference between reading images from a V4L or
+V4L2 device using the :ref:`read() <func-read>` function, however V4L2
+drivers are not required to support this I/O method. Applications can
+determine if the function is available with the
+:ref:`VIDIOC_QUERYCAP` ioctl. All V4L2 devices
+exchanging data with applications must support the
+:ref:`select() <func-select>` and :ref:`poll() <func-poll>`
+functions.
+
+To select an image format and size, V4L provides the ``VIDIOCSPICT`` and
+``VIDIOCSWIN`` ioctls. V4L2 uses the general-purpose data format
+negotiation ioctls :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` and
+:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`. They take a pointer to a struct
+:c:type:`v4l2_format` as argument, here the struct
+:c:type:`v4l2_pix_format` named ``pix`` of its
+``fmt`` union is used.
+
+For more information about the V4L2 read interface see :ref:`rw`.
+
+
+Capturing using memory mapping
+------------------------------
+
+Applications can read from V4L devices by mapping buffers in device
+memory, or more often just buffers allocated in DMA-able system memory,
+into their address space. This avoids the data copying overhead of the
+read method. V4L2 supports memory mapping as well, with a few
+differences.
+
+
+
+.. flat-table::
+    :header-rows:  1
+    :stub-columns: 0
+
+    * - V4L
+      - V4L2
+    * -
+      - The image format must be selected before buffers are allocated,
+	with the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl. When no
+	format is selected the driver may use the last, possibly by
+	another application requested format.
+    * - Applications cannot change the number of buffers. The it is built
+	into the driver, unless it has a module option to change the
+	number when the driver module is loaded.
+      - The :ref:`VIDIOC_REQBUFS` ioctl allocates the
+	desired number of buffers, this is a required step in the
+	initialization sequence.
+    * - Drivers map all buffers as one contiguous range of memory. The
+	``VIDIOCGMBUF`` ioctl is available to query the number of buffers,
+	the offset of each buffer from the start of the virtual file, and
+	the overall amount of memory used, which can be used as arguments
+	for the :ref:`mmap() <func-mmap>` function.
+      - Buffers are individually mapped. The offset and size of each
+	buffer can be determined with the
+	:ref:`VIDIOC_QUERYBUF` ioctl.
+    * - The ``VIDIOCMCAPTURE`` ioctl prepares a buffer for capturing. It
+	also determines the image format for this buffer. The ioctl
+	returns immediately, eventually with an ``EAGAIN`` error code if no
+	video signal had been detected. When the driver supports more than
+	one buffer applications can call the ioctl multiple times and thus
+	have multiple outstanding capture requests.
+
+	The ``VIDIOCSYNC`` ioctl suspends execution until a particular
+	buffer has been filled.
+      - Drivers maintain an incoming and outgoing queue.
+	:ref:`VIDIOC_QBUF` enqueues any empty buffer into
+	the incoming queue. Filled buffers are dequeued from the outgoing
+	queue with the :ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl. To wait
+	until filled buffers become available this function,
+	:ref:`select() <func-select>` or :ref:`poll() <func-poll>` can
+	be used. The :ref:`VIDIOC_STREAMON` ioctl
+	must be called once after enqueuing one or more buffers to start
+	capturing. Its counterpart
+	:ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` stops capturing and
+	dequeues all buffers from both queues. Applications can query the
+	signal status, if known, with the
+	:ref:`VIDIOC_ENUMINPUT` ioctl.
+
+
+For a more in-depth discussion of memory mapping and examples, see
+:ref:`mmap`.
+
+
+Reading Raw VBI Data
+====================
+
+Originally the V4L API did not specify a raw VBI capture interface, only
+the device file ``/dev/vbi`` was reserved for this purpose. The only
+driver supporting this interface was the BTTV driver, de-facto defining
+the V4L VBI interface. Reading from the device yields a raw VBI image
+with the following parameters:
+
+
+
+.. flat-table::
+    :header-rows:  1
+    :stub-columns: 0
+
+    * - struct :c:type:`v4l2_vbi_format`
+      - V4L, BTTV driver
+    * - sampling_rate
+      - 28636363 Hz NTSC (or any other 525-line standard); 35468950 Hz PAL
+	and SECAM (625-line standards)
+    * - offset
+      - ?
+    * - samples_per_line
+      - 2048
+    * - sample_format
+      - V4L2_PIX_FMT_GREY. The last four bytes (a machine endianness
+	integer) contain a frame counter.
+    * - start[]
+      - 10, 273 NTSC; 22, 335 PAL and SECAM
+    * - count[]
+      - 16, 16 [#f9]_
+    * - flags
+      - 0
+
+
+Undocumented in the V4L specification, in Linux 2.3 the
+``VIDIOCGVBIFMT`` and ``VIDIOCSVBIFMT`` ioctls using struct
+``vbi_format`` were added to determine the VBI image
+parameters. These ioctls are only partially compatible with the V4L2 VBI
+interface specified in :ref:`raw-vbi`.
+
+An ``offset`` field does not exist, ``sample_format`` is supposed to be
+``VIDEO_PALETTE_RAW``, equivalent to ``V4L2_PIX_FMT_GREY``. The
+remaining fields are probably equivalent to struct
+:c:type:`v4l2_vbi_format`.
+
+Apparently only the Zoran (ZR 36120) driver implements these ioctls. The
+semantics differ from those specified for V4L2 in two ways. The
+parameters are reset on :ref:`open() <func-open>` and
+``VIDIOCSVBIFMT`` always returns an ``EINVAL`` error code if the parameters
+are invalid.
+
+
+Miscellaneous
+=============
+
+V4L2 has no equivalent of the ``VIDIOCGUNIT`` ioctl. Applications can
+find the VBI device associated with a video capture device (or vice
+versa) by reopening the device and requesting VBI data. For details see
+:ref:`open`.
+
+No replacement exists for ``VIDIOCKEY``, and the V4L functions for
+microcode programming. A new interface for MPEG compression and playback
+devices is documented in :ref:`extended-controls`.
+
+.. [#f1]
+   According to Documentation/admin-guide/devices.rst these should be symbolic links
+   to ``/dev/video0``. Note the original bttv interface is not
+   compatible with V4L or V4L2.
+
+.. [#f2]
+   According to ``Documentation/admin-guide/devices.rst`` a symbolic link to
+   ``/dev/radio0``.
+
+.. [#f3]
+   This is a custom format used by the BTTV driver, not one of the V4L2
+   standard formats.
+
+.. [#f4]
+   Presumably all V4L RGB formats are little-endian, although some
+   drivers might interpret them according to machine endianness. V4L2
+   defines little-endian, big-endian and red/blue swapped variants. For
+   details see :ref:`pixfmt-rgb`.
+
+.. [#f5]
+   ``VIDEO_PALETTE_YUV422`` and ``VIDEO_PALETTE_YUYV`` are the same
+   formats. Some V4L drivers respond to one, some to the other.
+
+.. [#f6]
+   Not to be confused with ``V4L2_PIX_FMT_YUV411P``, which is a planar
+   format.
+
+.. [#f7]
+   V4L explains this as: "RAW capture (BT848)"
+
+.. [#f8]
+   Not to be confused with ``V4L2_PIX_FMT_Y41P``, which is a packed
+   format.
+
+.. [#f9]
+   Old driver versions used different values, eventually the custom
+   ``BTTV_VBISIZE`` ioctl was added to query the correct values.
diff --git a/Documentation/userspace-api/media/v4l/dmabuf.rst b/Documentation/userspace-api/media/v4l/dmabuf.rst
new file mode 100644
index 000000000000..342421ff9497
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/dmabuf.rst
@@ -0,0 +1,169 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _dmabuf:
+
+************************************
+Streaming I/O (DMA buffer importing)
+************************************
+
+The DMABUF framework provides a generic method for sharing buffers
+between multiple devices. Device drivers that support DMABUF can export
+a DMA buffer to userspace as a file descriptor (known as the exporter
+role), import a DMA buffer from userspace using a file descriptor
+previously exported for a different or the same device (known as the
+importer role), or both. This section describes the DMABUF importer role
+API in V4L2.
+
+Refer to :ref:`DMABUF exporting <VIDIOC_EXPBUF>` for details about
+exporting V4L2 buffers as DMABUF file descriptors.
+
+Input and output devices support the streaming I/O method when the
+``V4L2_CAP_STREAMING`` flag in the ``capabilities`` field of struct
+:c:type:`v4l2_capability` returned by the
+:ref:`VIDIOC_QUERYCAP <VIDIOC_QUERYCAP>` ioctl is set. Whether
+importing DMA buffers through DMABUF file descriptors is supported is
+determined by calling the :ref:`VIDIOC_REQBUFS <VIDIOC_REQBUFS>`
+ioctl with the memory type set to ``V4L2_MEMORY_DMABUF``.
+
+This I/O method is dedicated to sharing DMA buffers between different
+devices, which may be V4L devices or other video-related devices (e.g.
+DRM). Buffers (planes) are allocated by a driver on behalf of an
+application. Next, these buffers are exported to the application as file
+descriptors using an API which is specific for an allocator driver. Only
+such file descriptor are exchanged. The descriptors and meta-information
+are passed in struct :c:type:`v4l2_buffer` (or in struct
+:c:type:`v4l2_plane` in the multi-planar API case). The
+driver must be switched into DMABUF I/O mode by calling the
+:ref:`VIDIOC_REQBUFS <VIDIOC_REQBUFS>` with the desired buffer type.
+
+
+Example: Initiating streaming I/O with DMABUF file descriptors
+==============================================================
+
+.. code-block:: c
+
+    struct v4l2_requestbuffers reqbuf;
+
+    memset(&reqbuf, 0, sizeof (reqbuf));
+    reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+    reqbuf.memory = V4L2_MEMORY_DMABUF;
+    reqbuf.count = 1;
+
+    if (ioctl(fd, VIDIOC_REQBUFS, &reqbuf) == -1) {
+	if (errno == EINVAL)
+	    printf("Video capturing or DMABUF streaming is not supported\\n");
+	else
+	    perror("VIDIOC_REQBUFS");
+
+	exit(EXIT_FAILURE);
+    }
+
+The buffer (plane) file descriptor is passed on the fly with the
+:ref:`VIDIOC_QBUF <VIDIOC_QBUF>` ioctl. In case of multiplanar
+buffers, every plane can be associated with a different DMABUF
+descriptor. Although buffers are commonly cycled, applications can pass
+a different DMABUF descriptor at each :ref:`VIDIOC_QBUF <VIDIOC_QBUF>` call.
+
+Example: Queueing DMABUF using single plane API
+===============================================
+
+.. code-block:: c
+
+    int buffer_queue(int v4lfd, int index, int dmafd)
+    {
+	struct v4l2_buffer buf;
+
+	memset(&buf, 0, sizeof buf);
+	buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	buf.memory = V4L2_MEMORY_DMABUF;
+	buf.index = index;
+	buf.m.fd = dmafd;
+
+	if (ioctl(v4lfd, VIDIOC_QBUF, &buf) == -1) {
+	    perror("VIDIOC_QBUF");
+	    return -1;
+	}
+
+	return 0;
+    }
+
+Example 3.6. Queueing DMABUF using multi plane API
+==================================================
+
+.. code-block:: c
+
+    int buffer_queue_mp(int v4lfd, int index, int dmafd[], int n_planes)
+    {
+	struct v4l2_buffer buf;
+	struct v4l2_plane planes[VIDEO_MAX_PLANES];
+	int i;
+
+	memset(&buf, 0, sizeof buf);
+	buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+	buf.memory = V4L2_MEMORY_DMABUF;
+	buf.index = index;
+	buf.m.planes = planes;
+	buf.length = n_planes;
+
+	memset(&planes, 0, sizeof planes);
+
+	for (i = 0; i < n_planes; ++i)
+	    buf.m.planes[i].m.fd = dmafd[i];
+
+	if (ioctl(v4lfd, VIDIOC_QBUF, &buf) == -1) {
+	    perror("VIDIOC_QBUF");
+	    return -1;
+	}
+
+	return 0;
+    }
+
+Captured or displayed buffers are dequeued with the
+:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl. The driver can unlock the
+buffer at any time between the completion of the DMA and this ioctl. The
+memory is also unlocked when
+:ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` is called,
+:ref:`VIDIOC_REQBUFS <VIDIOC_REQBUFS>`, or when the device is closed.
+
+For capturing applications it is customary to enqueue a number of empty
+buffers, to start capturing and enter the read loop. Here the
+application waits until a filled buffer can be dequeued, and re-enqueues
+the buffer when the data is no longer needed. Output applications fill
+and enqueue buffers, when enough buffers are stacked up output is
+started. In the write loop, when the application runs out of free
+buffers it must wait until an empty buffer can be dequeued and reused.
+Two methods exist to suspend execution of the application until one or
+more buffers can be dequeued. By default :ref:`VIDIOC_DQBUF
+<VIDIOC_QBUF>` blocks when no buffer is in the outgoing queue. When the
+``O_NONBLOCK`` flag was given to the :ref:`open() <func-open>` function,
+:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` returns immediately with an ``EAGAIN``
+error code when no buffer is available. The
+:ref:`select() <func-select>` and :ref:`poll() <func-poll>`
+functions are always available.
+
+To start and stop capturing or displaying applications call the
+:ref:`VIDIOC_STREAMON <VIDIOC_STREAMON>` and
+:ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` ioctls.
+
+.. note::
+
+   :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` removes all buffers from
+   both queues and unlocks all buffers as a side effect. Since there is no
+   notion of doing anything "now" on a multitasking system, if an
+   application needs to synchronize with another event it should examine
+   the struct :c:type:`v4l2_buffer` ``timestamp`` of captured or
+   outputted buffers.
+
+Drivers implementing DMABUF importing I/O must support the
+:ref:`VIDIOC_REQBUFS <VIDIOC_REQBUFS>`, :ref:`VIDIOC_QBUF <VIDIOC_QBUF>`,
+:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>`, :ref:`VIDIOC_STREAMON
+<VIDIOC_STREAMON>` and :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` ioctls,
+and the :ref:`select() <func-select>` and :ref:`poll() <func-poll>`
+functions.
diff --git a/Documentation/userspace-api/media/v4l/dv-timings.rst b/Documentation/userspace-api/media/v4l/dv-timings.rst
new file mode 100644
index 000000000000..e216aa9edef0
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/dv-timings.rst
@@ -0,0 +1,45 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _dv-timings:
+
+**************************
+Digital Video (DV) Timings
+**************************
+
+The video standards discussed so far have been dealing with Analog TV
+and the corresponding video timings. Today there are many more different
+hardware interfaces such as High Definition TV interfaces (HDMI), VGA,
+DVI connectors etc., that carry video signals and there is a need to
+extend the API to select the video timings for these interfaces. Since
+it is not possible to extend the :ref:`v4l2_std_id <v4l2-std-id>`
+due to the limited bits available, a new set of ioctls was added to
+set/get video timings at the input and output.
+
+These ioctls deal with the detailed digital video timings that define
+each video format. This includes parameters such as the active video
+width and height, signal polarities, frontporches, backporches, sync
+widths etc. The ``linux/v4l2-dv-timings.h`` header can be used to get
+the timings of the formats in the :ref:`cea861` and :ref:`vesadmt`
+standards.
+
+To enumerate and query the attributes of the DV timings supported by a
+device applications use the
+:ref:`VIDIOC_ENUM_DV_TIMINGS` and
+:ref:`VIDIOC_DV_TIMINGS_CAP` ioctls. To set
+DV timings for the device applications use the
+:ref:`VIDIOC_S_DV_TIMINGS <VIDIOC_G_DV_TIMINGS>` ioctl and to get
+current DV timings they use the
+:ref:`VIDIOC_G_DV_TIMINGS <VIDIOC_G_DV_TIMINGS>` ioctl. To detect
+the DV timings as seen by the video receiver applications use the
+:ref:`VIDIOC_QUERY_DV_TIMINGS` ioctl.
+
+Applications can make use of the :ref:`input-capabilities` and
+:ref:`output-capabilities` flags to determine whether the digital
+video ioctls can be used with the given input or output.
diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-camera.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-camera.rst
new file mode 100644
index 000000000000..e39f84d2447f
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-camera.rst
@@ -0,0 +1,515 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _camera-controls:
+
+************************
+Camera Control Reference
+************************
+
+The Camera class includes controls for mechanical (or equivalent
+digital) features of a device such as controllable lenses or sensors.
+
+
+.. _camera-control-id:
+
+Camera Control IDs
+==================
+
+``V4L2_CID_CAMERA_CLASS (class)``
+    The Camera class descriptor. Calling
+    :ref:`VIDIOC_QUERYCTRL` for this control will
+    return a description of this control class.
+
+.. _v4l2-exposure-auto-type:
+
+``V4L2_CID_EXPOSURE_AUTO``
+    (enum)
+
+enum v4l2_exposure_auto_type -
+    Enables automatic adjustments of the exposure time and/or iris
+    aperture. The effect of manual changes of the exposure time or iris
+    aperture while these features are enabled is undefined, drivers
+    should ignore such requests. Possible values are:
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_EXPOSURE_AUTO``
+      - Automatic exposure time, automatic iris aperture.
+    * - ``V4L2_EXPOSURE_MANUAL``
+      - Manual exposure time, manual iris.
+    * - ``V4L2_EXPOSURE_SHUTTER_PRIORITY``
+      - Manual exposure time, auto iris.
+    * - ``V4L2_EXPOSURE_APERTURE_PRIORITY``
+      - Auto exposure time, manual iris.
+
+
+
+``V4L2_CID_EXPOSURE_ABSOLUTE (integer)``
+    Determines the exposure time of the camera sensor. The exposure time
+    is limited by the frame interval. Drivers should interpret the
+    values as 100 µs units, where the value 1 stands for 1/10000th of a
+    second, 10000 for 1 second and 100000 for 10 seconds.
+
+``V4L2_CID_EXPOSURE_AUTO_PRIORITY (boolean)``
+    When ``V4L2_CID_EXPOSURE_AUTO`` is set to ``AUTO`` or
+    ``APERTURE_PRIORITY``, this control determines if the device may
+    dynamically vary the frame rate. By default this feature is disabled
+    (0) and the frame rate must remain constant.
+
+``V4L2_CID_AUTO_EXPOSURE_BIAS (integer menu)``
+    Determines the automatic exposure compensation, it is effective only
+    when ``V4L2_CID_EXPOSURE_AUTO`` control is set to ``AUTO``,
+    ``SHUTTER_PRIORITY`` or ``APERTURE_PRIORITY``. It is expressed in
+    terms of EV, drivers should interpret the values as 0.001 EV units,
+    where the value 1000 stands for +1 EV.
+
+    Increasing the exposure compensation value is equivalent to
+    decreasing the exposure value (EV) and will increase the amount of
+    light at the image sensor. The camera performs the exposure
+    compensation by adjusting absolute exposure time and/or aperture.
+
+.. _v4l2-exposure-metering:
+
+``V4L2_CID_EXPOSURE_METERING``
+    (enum)
+
+enum v4l2_exposure_metering -
+    Determines how the camera measures the amount of light available for
+    the frame exposure. Possible values are:
+
+.. tabularcolumns:: |p{8.7cm}|p{8.8cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_EXPOSURE_METERING_AVERAGE``
+      - Use the light information coming from the entire frame and average
+	giving no weighting to any particular portion of the metered area.
+    * - ``V4L2_EXPOSURE_METERING_CENTER_WEIGHTED``
+      - Average the light information coming from the entire frame giving
+	priority to the center of the metered area.
+    * - ``V4L2_EXPOSURE_METERING_SPOT``
+      - Measure only very small area at the center of the frame.
+    * - ``V4L2_EXPOSURE_METERING_MATRIX``
+      - A multi-zone metering. The light intensity is measured in several
+	points of the frame and the results are combined. The algorithm of
+	the zones selection and their significance in calculating the
+	final value is device dependent.
+
+
+
+``V4L2_CID_PAN_RELATIVE (integer)``
+    This control turns the camera horizontally by the specified amount.
+    The unit is undefined. A positive value moves the camera to the
+    right (clockwise when viewed from above), a negative value to the
+    left. A value of zero does not cause motion. This is a write-only
+    control.
+
+``V4L2_CID_TILT_RELATIVE (integer)``
+    This control turns the camera vertically by the specified amount.
+    The unit is undefined. A positive value moves the camera up, a
+    negative value down. A value of zero does not cause motion. This is
+    a write-only control.
+
+``V4L2_CID_PAN_RESET (button)``
+    When this control is set, the camera moves horizontally to the
+    default position.
+
+``V4L2_CID_TILT_RESET (button)``
+    When this control is set, the camera moves vertically to the default
+    position.
+
+``V4L2_CID_PAN_ABSOLUTE (integer)``
+    This control turns the camera horizontally to the specified
+    position. Positive values move the camera to the right (clockwise
+    when viewed from above), negative values to the left. Drivers should
+    interpret the values as arc seconds, with valid values between -180
+    * 3600 and +180 * 3600 inclusive.
+
+``V4L2_CID_TILT_ABSOLUTE (integer)``
+    This control turns the camera vertically to the specified position.
+    Positive values move the camera up, negative values down. Drivers
+    should interpret the values as arc seconds, with valid values
+    between -180 * 3600 and +180 * 3600 inclusive.
+
+``V4L2_CID_FOCUS_ABSOLUTE (integer)``
+    This control sets the focal point of the camera to the specified
+    position. The unit is undefined. Positive values set the focus
+    closer to the camera, negative values towards infinity.
+
+``V4L2_CID_FOCUS_RELATIVE (integer)``
+    This control moves the focal point of the camera by the specified
+    amount. The unit is undefined. Positive values move the focus closer
+    to the camera, negative values towards infinity. This is a
+    write-only control.
+
+``V4L2_CID_FOCUS_AUTO (boolean)``
+    Enables continuous automatic focus adjustments. The effect of manual
+    focus adjustments while this feature is enabled is undefined,
+    drivers should ignore such requests.
+
+``V4L2_CID_AUTO_FOCUS_START (button)``
+    Starts single auto focus process. The effect of setting this control
+    when ``V4L2_CID_FOCUS_AUTO`` is set to ``TRUE`` (1) is undefined,
+    drivers should ignore such requests.
+
+``V4L2_CID_AUTO_FOCUS_STOP (button)``
+    Aborts automatic focusing started with ``V4L2_CID_AUTO_FOCUS_START``
+    control. It is effective only when the continuous autofocus is
+    disabled, that is when ``V4L2_CID_FOCUS_AUTO`` control is set to
+    ``FALSE`` (0).
+
+.. _v4l2-auto-focus-status:
+
+``V4L2_CID_AUTO_FOCUS_STATUS (bitmask)``
+    The automatic focus status. This is a read-only control.
+
+    Setting ``V4L2_LOCK_FOCUS`` lock bit of the ``V4L2_CID_3A_LOCK``
+    control may stop updates of the ``V4L2_CID_AUTO_FOCUS_STATUS``
+    control value.
+
+.. tabularcolumns:: |p{6.7cm}|p{10.8cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_AUTO_FOCUS_STATUS_IDLE``
+      - Automatic focus is not active.
+    * - ``V4L2_AUTO_FOCUS_STATUS_BUSY``
+      - Automatic focusing is in progress.
+    * - ``V4L2_AUTO_FOCUS_STATUS_REACHED``
+      - Focus has been reached.
+    * - ``V4L2_AUTO_FOCUS_STATUS_FAILED``
+      - Automatic focus has failed, the driver will not transition from
+	this state until another action is performed by an application.
+
+
+
+.. _v4l2-auto-focus-range:
+
+``V4L2_CID_AUTO_FOCUS_RANGE``
+    (enum)
+
+enum v4l2_auto_focus_range -
+    Determines auto focus distance range for which lens may be adjusted.
+
+.. tabularcolumns:: |p{6.8cm}|p{10.7cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_AUTO_FOCUS_RANGE_AUTO``
+      - The camera automatically selects the focus range.
+    * - ``V4L2_AUTO_FOCUS_RANGE_NORMAL``
+      - Normal distance range, limited for best automatic focus
+	performance.
+    * - ``V4L2_AUTO_FOCUS_RANGE_MACRO``
+      - Macro (close-up) auto focus. The camera will use its minimum
+	possible distance for auto focus.
+    * - ``V4L2_AUTO_FOCUS_RANGE_INFINITY``
+      - The lens is set to focus on an object at infinite distance.
+
+
+
+``V4L2_CID_ZOOM_ABSOLUTE (integer)``
+    Specify the objective lens focal length as an absolute value. The
+    zoom unit is driver-specific and its value should be a positive
+    integer.
+
+``V4L2_CID_ZOOM_RELATIVE (integer)``
+    Specify the objective lens focal length relatively to the current
+    value. Positive values move the zoom lens group towards the
+    telephoto direction, negative values towards the wide-angle
+    direction. The zoom unit is driver-specific. This is a write-only
+    control.
+
+``V4L2_CID_ZOOM_CONTINUOUS (integer)``
+    Move the objective lens group at the specified speed until it
+    reaches physical device limits or until an explicit request to stop
+    the movement. A positive value moves the zoom lens group towards the
+    telephoto direction. A value of zero stops the zoom lens group
+    movement. A negative value moves the zoom lens group towards the
+    wide-angle direction. The zoom speed unit is driver-specific.
+
+``V4L2_CID_IRIS_ABSOLUTE (integer)``
+    This control sets the camera's aperture to the specified value. The
+    unit is undefined. Larger values open the iris wider, smaller values
+    close it.
+
+``V4L2_CID_IRIS_RELATIVE (integer)``
+    This control modifies the camera's aperture by the specified amount.
+    The unit is undefined. Positive values open the iris one step
+    further, negative values close it one step further. This is a
+    write-only control.
+
+``V4L2_CID_PRIVACY (boolean)``
+    Prevent video from being acquired by the camera. When this control
+    is set to ``TRUE`` (1), no image can be captured by the camera.
+    Common means to enforce privacy are mechanical obturation of the
+    sensor and firmware image processing, but the device is not
+    restricted to these methods. Devices that implement the privacy
+    control must support read access and may support write access.
+
+``V4L2_CID_BAND_STOP_FILTER (integer)``
+    Switch the band-stop filter of a camera sensor on or off, or specify
+    its strength. Such band-stop filters can be used, for example, to
+    filter out the fluorescent light component.
+
+.. _v4l2-auto-n-preset-white-balance:
+
+``V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE``
+    (enum)
+
+enum v4l2_auto_n_preset_white_balance -
+    Sets white balance to automatic, manual or a preset. The presets
+    determine color temperature of the light as a hint to the camera for
+    white balance adjustments resulting in most accurate color
+    representation. The following white balance presets are listed in
+    order of increasing color temperature.
+
+.. tabularcolumns:: |p{7.2 cm}|p{10.3cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_WHITE_BALANCE_MANUAL``
+      - Manual white balance.
+    * - ``V4L2_WHITE_BALANCE_AUTO``
+      - Automatic white balance adjustments.
+    * - ``V4L2_WHITE_BALANCE_INCANDESCENT``
+      - White balance setting for incandescent (tungsten) lighting. It
+	generally cools down the colors and corresponds approximately to
+	2500...3500 K color temperature range.
+    * - ``V4L2_WHITE_BALANCE_FLUORESCENT``
+      - White balance preset for fluorescent lighting. It corresponds
+	approximately to 4000...5000 K color temperature.
+    * - ``V4L2_WHITE_BALANCE_FLUORESCENT_H``
+      - With this setting the camera will compensate for fluorescent H
+	lighting.
+    * - ``V4L2_WHITE_BALANCE_HORIZON``
+      - White balance setting for horizon daylight. It corresponds
+	approximately to 5000 K color temperature.
+    * - ``V4L2_WHITE_BALANCE_DAYLIGHT``
+      - White balance preset for daylight (with clear sky). It corresponds
+	approximately to 5000...6500 K color temperature.
+    * - ``V4L2_WHITE_BALANCE_FLASH``
+      - With this setting the camera will compensate for the flash light.
+	It slightly warms up the colors and corresponds roughly to
+	5000...5500 K color temperature.
+    * - ``V4L2_WHITE_BALANCE_CLOUDY``
+      - White balance preset for moderately overcast sky. This option
+	corresponds approximately to 6500...8000 K color temperature
+	range.
+    * - ``V4L2_WHITE_BALANCE_SHADE``
+      - White balance preset for shade or heavily overcast sky. It
+	corresponds approximately to 9000...10000 K color temperature.
+
+
+
+.. _v4l2-wide-dynamic-range:
+
+``V4L2_CID_WIDE_DYNAMIC_RANGE (boolean)``
+    Enables or disables the camera's wide dynamic range feature. This
+    feature allows to obtain clear images in situations where intensity
+    of the illumination varies significantly throughout the scene, i.e.
+    there are simultaneously very dark and very bright areas. It is most
+    commonly realized in cameras by combining two subsequent frames with
+    different exposure times.  [#f1]_
+
+.. _v4l2-image-stabilization:
+
+``V4L2_CID_IMAGE_STABILIZATION (boolean)``
+    Enables or disables image stabilization.
+
+``V4L2_CID_ISO_SENSITIVITY (integer menu)``
+    Determines ISO equivalent of an image sensor indicating the sensor's
+    sensitivity to light. The numbers are expressed in arithmetic scale,
+    as per :ref:`iso12232` standard, where doubling the sensor
+    sensitivity is represented by doubling the numerical ISO value.
+    Applications should interpret the values as standard ISO values
+    multiplied by 1000, e.g. control value 800 stands for ISO 0.8.
+    Drivers will usually support only a subset of standard ISO values.
+    The effect of setting this control while the
+    ``V4L2_CID_ISO_SENSITIVITY_AUTO`` control is set to a value other
+    than ``V4L2_CID_ISO_SENSITIVITY_MANUAL`` is undefined, drivers
+    should ignore such requests.
+
+.. _v4l2-iso-sensitivity-auto-type:
+
+``V4L2_CID_ISO_SENSITIVITY_AUTO``
+    (enum)
+
+enum v4l2_iso_sensitivity_type -
+    Enables or disables automatic ISO sensitivity adjustments.
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_CID_ISO_SENSITIVITY_MANUAL``
+      - Manual ISO sensitivity.
+    * - ``V4L2_CID_ISO_SENSITIVITY_AUTO``
+      - Automatic ISO sensitivity adjustments.
+
+
+
+.. _v4l2-scene-mode:
+
+``V4L2_CID_SCENE_MODE``
+    (enum)
+
+enum v4l2_scene_mode -
+    This control allows to select scene programs as the camera automatic
+    modes optimized for common shooting scenes. Within these modes the
+    camera determines best exposure, aperture, focusing, light metering,
+    white balance and equivalent sensitivity. The controls of those
+    parameters are influenced by the scene mode control. An exact
+    behavior in each mode is subject to the camera specification.
+
+    When the scene mode feature is not used, this control should be set
+    to ``V4L2_SCENE_MODE_NONE`` to make sure the other possibly related
+    controls are accessible. The following scene programs are defined:
+
+.. raw:: latex
+
+    \small
+
+.. tabularcolumns:: |p{5.9cm}|p{11.5cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_SCENE_MODE_NONE``
+      - The scene mode feature is disabled.
+    * - ``V4L2_SCENE_MODE_BACKLIGHT``
+      - Backlight. Compensates for dark shadows when light is coming from
+	behind a subject, also by automatically turning on the flash.
+    * - ``V4L2_SCENE_MODE_BEACH_SNOW``
+      - Beach and snow. This mode compensates for all-white or bright
+	scenes, which tend to look gray and low contrast, when camera's
+	automatic exposure is based on an average scene brightness. To
+	compensate, this mode automatically slightly overexposes the
+	frames. The white balance may also be adjusted to compensate for
+	the fact that reflected snow looks bluish rather than white.
+    * - ``V4L2_SCENE_MODE_CANDLELIGHT``
+      - Candle light. The camera generally raises the ISO sensitivity and
+	lowers the shutter speed. This mode compensates for relatively
+	close subject in the scene. The flash is disabled in order to
+	preserve the ambiance of the light.
+    * - ``V4L2_SCENE_MODE_DAWN_DUSK``
+      - Dawn and dusk. Preserves the colors seen in low natural light
+	before dusk and after down. The camera may turn off the flash, and
+	automatically focus at infinity. It will usually boost saturation
+	and lower the shutter speed.
+    * - ``V4L2_SCENE_MODE_FALL_COLORS``
+      - Fall colors. Increases saturation and adjusts white balance for
+	color enhancement. Pictures of autumn leaves get saturated reds
+	and yellows.
+    * - ``V4L2_SCENE_MODE_FIREWORKS``
+      - Fireworks. Long exposure times are used to capture the expanding
+	burst of light from a firework. The camera may invoke image
+	stabilization.
+    * - ``V4L2_SCENE_MODE_LANDSCAPE``
+      - Landscape. The camera may choose a small aperture to provide deep
+	depth of field and long exposure duration to help capture detail
+	in dim light conditions. The focus is fixed at infinity. Suitable
+	for distant and wide scenery.
+    * - ``V4L2_SCENE_MODE_NIGHT``
+      - Night, also known as Night Landscape. Designed for low light
+	conditions, it preserves detail in the dark areas without blowing
+	out bright objects. The camera generally sets itself to a
+	medium-to-high ISO sensitivity, with a relatively long exposure
+	time, and turns flash off. As such, there will be increased image
+	noise and the possibility of blurred image.
+    * - ``V4L2_SCENE_MODE_PARTY_INDOOR``
+      - Party and indoor. Designed to capture indoor scenes that are lit
+	by indoor background lighting as well as the flash. The camera
+	usually increases ISO sensitivity, and adjusts exposure for the
+	low light conditions.
+    * - ``V4L2_SCENE_MODE_PORTRAIT``
+      - Portrait. The camera adjusts the aperture so that the depth of
+	field is reduced, which helps to isolate the subject against a
+	smooth background. Most cameras recognize the presence of faces in
+	the scene and focus on them. The color hue is adjusted to enhance
+	skin tones. The intensity of the flash is often reduced.
+    * - ``V4L2_SCENE_MODE_SPORTS``
+      - Sports. Significantly increases ISO and uses a fast shutter speed
+	to freeze motion of rapidly-moving subjects. Increased image noise
+	may be seen in this mode.
+    * - ``V4L2_SCENE_MODE_SUNSET``
+      - Sunset. Preserves deep hues seen in sunsets and sunrises. It bumps
+	up the saturation.
+    * - ``V4L2_SCENE_MODE_TEXT``
+      - Text. It applies extra contrast and sharpness, it is typically a
+	black-and-white mode optimized for readability. Automatic focus
+	may be switched to close-up mode and this setting may also involve
+	some lens-distortion correction.
+
+.. raw:: latex
+
+    \normalsize
+
+
+``V4L2_CID_3A_LOCK (bitmask)``
+    This control locks or unlocks the automatic focus, exposure and
+    white balance. The automatic adjustments can be paused independently
+    by setting the corresponding lock bit to 1. The camera then retains
+    the settings until the lock bit is cleared. The following lock bits
+    are defined:
+
+    When a given algorithm is not enabled, drivers should ignore
+    requests to lock it and should return no error. An example might be
+    an application setting bit ``V4L2_LOCK_WHITE_BALANCE`` when the
+    ``V4L2_CID_AUTO_WHITE_BALANCE`` control is set to ``FALSE``. The
+    value of this control may be changed by exposure, white balance or
+    focus controls.
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_LOCK_EXPOSURE``
+      - Automatic exposure adjustments lock.
+    * - ``V4L2_LOCK_WHITE_BALANCE``
+      - Automatic white balance adjustments lock.
+    * - ``V4L2_LOCK_FOCUS``
+      - Automatic focus lock.
+
+
+
+``V4L2_CID_PAN_SPEED (integer)``
+    This control turns the camera horizontally at the specific speed.
+    The unit is undefined. A positive value moves the camera to the
+    right (clockwise when viewed from above), a negative value to the
+    left. A value of zero stops the motion if one is in progress and has
+    no effect otherwise.
+
+``V4L2_CID_TILT_SPEED (integer)``
+    This control turns the camera vertically at the specified speed. The
+    unit is undefined. A positive value moves the camera up, a negative
+    value down. A value of zero stops the motion if one is in progress
+    and has no effect otherwise.
+
+.. [#f1]
+   This control may be changed to a menu control in the future, if more
+   options are required.
diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
new file mode 100644
index 000000000000..9b48338fb783
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
@@ -0,0 +1,4264 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _mpeg-controls:
+
+***********************
+Codec Control Reference
+***********************
+
+Below all controls within the Codec control class are described. First
+the generic controls, then controls specific for certain hardware.
+
+.. note::
+
+   These controls are applicable to all codecs and not just MPEG. The
+   defines are prefixed with V4L2_CID_MPEG/V4L2_MPEG as the controls
+   were originally made for MPEG codecs and later extended to cover all
+   encoding formats.
+
+
+Generic Codec Controls
+======================
+
+
+.. _mpeg-control-id:
+
+Codec Control IDs
+-----------------
+
+``V4L2_CID_MPEG_CLASS (class)``
+    The Codec class descriptor. Calling
+    :ref:`VIDIOC_QUERYCTRL` for this control will
+    return a description of this control class. This description can be
+    used as the caption of a Tab page in a GUI, for example.
+
+.. _v4l2-mpeg-stream-type:
+
+``V4L2_CID_MPEG_STREAM_TYPE``
+    (enum)
+
+enum v4l2_mpeg_stream_type -
+    The MPEG-1, -2 or -4 output stream type. One cannot assume anything
+    here. Each hardware MPEG encoder tends to support different subsets
+    of the available MPEG stream types. This control is specific to
+    multiplexed MPEG streams. The currently defined stream types are:
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_STREAM_TYPE_MPEG2_PS``
+      - MPEG-2 program stream
+    * - ``V4L2_MPEG_STREAM_TYPE_MPEG2_TS``
+      - MPEG-2 transport stream
+    * - ``V4L2_MPEG_STREAM_TYPE_MPEG1_SS``
+      - MPEG-1 system stream
+    * - ``V4L2_MPEG_STREAM_TYPE_MPEG2_DVD``
+      - MPEG-2 DVD-compatible stream
+    * - ``V4L2_MPEG_STREAM_TYPE_MPEG1_VCD``
+      - MPEG-1 VCD-compatible stream
+    * - ``V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD``
+      - MPEG-2 SVCD-compatible stream
+
+
+
+``V4L2_CID_MPEG_STREAM_PID_PMT (integer)``
+    Program Map Table Packet ID for the MPEG transport stream (default
+    16)
+
+``V4L2_CID_MPEG_STREAM_PID_AUDIO (integer)``
+    Audio Packet ID for the MPEG transport stream (default 256)
+
+``V4L2_CID_MPEG_STREAM_PID_VIDEO (integer)``
+    Video Packet ID for the MPEG transport stream (default 260)
+
+``V4L2_CID_MPEG_STREAM_PID_PCR (integer)``
+    Packet ID for the MPEG transport stream carrying PCR fields (default
+    259)
+
+``V4L2_CID_MPEG_STREAM_PES_ID_AUDIO (integer)``
+    Audio ID for MPEG PES
+
+``V4L2_CID_MPEG_STREAM_PES_ID_VIDEO (integer)``
+    Video ID for MPEG PES
+
+.. _v4l2-mpeg-stream-vbi-fmt:
+
+``V4L2_CID_MPEG_STREAM_VBI_FMT``
+    (enum)
+
+enum v4l2_mpeg_stream_vbi_fmt -
+    Some cards can embed VBI data (e. g. Closed Caption, Teletext) into
+    the MPEG stream. This control selects whether VBI data should be
+    embedded, and if so, what embedding method should be used. The list
+    of possible VBI formats depends on the driver. The currently defined
+    VBI format types are:
+
+
+
+.. tabularcolumns:: |p{6.6 cm}|p{10.9cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_STREAM_VBI_FMT_NONE``
+      - No VBI in the MPEG stream
+    * - ``V4L2_MPEG_STREAM_VBI_FMT_IVTV``
+      - VBI in private packets, IVTV format (documented in the kernel
+	sources in the file
+	``Documentation/userspace-api/media/drivers/cx2341x-uapi.rst``)
+
+
+
+.. _v4l2-mpeg-audio-sampling-freq:
+
+``V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ``
+    (enum)
+
+enum v4l2_mpeg_audio_sampling_freq -
+    MPEG Audio sampling frequency. Possible values are:
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100``
+      - 44.1 kHz
+    * - ``V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000``
+      - 48 kHz
+    * - ``V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000``
+      - 32 kHz
+
+
+
+.. _v4l2-mpeg-audio-encoding:
+
+``V4L2_CID_MPEG_AUDIO_ENCODING``
+    (enum)
+
+enum v4l2_mpeg_audio_encoding -
+    MPEG Audio encoding. This control is specific to multiplexed MPEG
+    streams. Possible values are:
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_AUDIO_ENCODING_LAYER_1``
+      - MPEG-1/2 Layer I encoding
+    * - ``V4L2_MPEG_AUDIO_ENCODING_LAYER_2``
+      - MPEG-1/2 Layer II encoding
+    * - ``V4L2_MPEG_AUDIO_ENCODING_LAYER_3``
+      - MPEG-1/2 Layer III encoding
+    * - ``V4L2_MPEG_AUDIO_ENCODING_AAC``
+      - MPEG-2/4 AAC (Advanced Audio Coding)
+    * - ``V4L2_MPEG_AUDIO_ENCODING_AC3``
+      - AC-3 aka ATSC A/52 encoding
+
+
+
+.. _v4l2-mpeg-audio-l1-bitrate:
+
+``V4L2_CID_MPEG_AUDIO_L1_BITRATE``
+    (enum)
+
+enum v4l2_mpeg_audio_l1_bitrate -
+    MPEG-1/2 Layer I bitrate. Possible values are:
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_AUDIO_L1_BITRATE_32K``
+      - 32 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L1_BITRATE_64K``
+      - 64 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L1_BITRATE_96K``
+      - 96 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L1_BITRATE_128K``
+      - 128 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L1_BITRATE_160K``
+      - 160 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L1_BITRATE_192K``
+      - 192 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L1_BITRATE_224K``
+      - 224 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L1_BITRATE_256K``
+      - 256 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L1_BITRATE_288K``
+      - 288 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L1_BITRATE_320K``
+      - 320 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L1_BITRATE_352K``
+      - 352 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L1_BITRATE_384K``
+      - 384 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L1_BITRATE_416K``
+      - 416 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L1_BITRATE_448K``
+      - 448 kbit/s
+
+
+
+.. _v4l2-mpeg-audio-l2-bitrate:
+
+``V4L2_CID_MPEG_AUDIO_L2_BITRATE``
+    (enum)
+
+enum v4l2_mpeg_audio_l2_bitrate -
+    MPEG-1/2 Layer II bitrate. Possible values are:
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_AUDIO_L2_BITRATE_32K``
+      - 32 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L2_BITRATE_48K``
+      - 48 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L2_BITRATE_56K``
+      - 56 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L2_BITRATE_64K``
+      - 64 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L2_BITRATE_80K``
+      - 80 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L2_BITRATE_96K``
+      - 96 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L2_BITRATE_112K``
+      - 112 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L2_BITRATE_128K``
+      - 128 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L2_BITRATE_160K``
+      - 160 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L2_BITRATE_192K``
+      - 192 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L2_BITRATE_224K``
+      - 224 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L2_BITRATE_256K``
+      - 256 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L2_BITRATE_320K``
+      - 320 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L2_BITRATE_384K``
+      - 384 kbit/s
+
+
+
+.. _v4l2-mpeg-audio-l3-bitrate:
+
+``V4L2_CID_MPEG_AUDIO_L3_BITRATE``
+    (enum)
+
+enum v4l2_mpeg_audio_l3_bitrate -
+    MPEG-1/2 Layer III bitrate. Possible values are:
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_AUDIO_L3_BITRATE_32K``
+      - 32 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L3_BITRATE_40K``
+      - 40 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L3_BITRATE_48K``
+      - 48 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L3_BITRATE_56K``
+      - 56 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L3_BITRATE_64K``
+      - 64 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L3_BITRATE_80K``
+      - 80 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L3_BITRATE_96K``
+      - 96 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L3_BITRATE_112K``
+      - 112 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L3_BITRATE_128K``
+      - 128 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L3_BITRATE_160K``
+      - 160 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L3_BITRATE_192K``
+      - 192 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L3_BITRATE_224K``
+      - 224 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L3_BITRATE_256K``
+      - 256 kbit/s
+    * - ``V4L2_MPEG_AUDIO_L3_BITRATE_320K``
+      - 320 kbit/s
+
+
+
+``V4L2_CID_MPEG_AUDIO_AAC_BITRATE (integer)``
+    AAC bitrate in bits per second.
+
+.. _v4l2-mpeg-audio-ac3-bitrate:
+
+``V4L2_CID_MPEG_AUDIO_AC3_BITRATE``
+    (enum)
+
+enum v4l2_mpeg_audio_ac3_bitrate -
+    AC-3 bitrate. Possible values are:
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_AUDIO_AC3_BITRATE_32K``
+      - 32 kbit/s
+    * - ``V4L2_MPEG_AUDIO_AC3_BITRATE_40K``
+      - 40 kbit/s
+    * - ``V4L2_MPEG_AUDIO_AC3_BITRATE_48K``
+      - 48 kbit/s
+    * - ``V4L2_MPEG_AUDIO_AC3_BITRATE_56K``
+      - 56 kbit/s
+    * - ``V4L2_MPEG_AUDIO_AC3_BITRATE_64K``
+      - 64 kbit/s
+    * - ``V4L2_MPEG_AUDIO_AC3_BITRATE_80K``
+      - 80 kbit/s
+    * - ``V4L2_MPEG_AUDIO_AC3_BITRATE_96K``
+      - 96 kbit/s
+    * - ``V4L2_MPEG_AUDIO_AC3_BITRATE_112K``
+      - 112 kbit/s
+    * - ``V4L2_MPEG_AUDIO_AC3_BITRATE_128K``
+      - 128 kbit/s
+    * - ``V4L2_MPEG_AUDIO_AC3_BITRATE_160K``
+      - 160 kbit/s
+    * - ``V4L2_MPEG_AUDIO_AC3_BITRATE_192K``
+      - 192 kbit/s
+    * - ``V4L2_MPEG_AUDIO_AC3_BITRATE_224K``
+      - 224 kbit/s
+    * - ``V4L2_MPEG_AUDIO_AC3_BITRATE_256K``
+      - 256 kbit/s
+    * - ``V4L2_MPEG_AUDIO_AC3_BITRATE_320K``
+      - 320 kbit/s
+    * - ``V4L2_MPEG_AUDIO_AC3_BITRATE_384K``
+      - 384 kbit/s
+    * - ``V4L2_MPEG_AUDIO_AC3_BITRATE_448K``
+      - 448 kbit/s
+    * - ``V4L2_MPEG_AUDIO_AC3_BITRATE_512K``
+      - 512 kbit/s
+    * - ``V4L2_MPEG_AUDIO_AC3_BITRATE_576K``
+      - 576 kbit/s
+    * - ``V4L2_MPEG_AUDIO_AC3_BITRATE_640K``
+      - 640 kbit/s
+
+
+
+.. _v4l2-mpeg-audio-mode:
+
+``V4L2_CID_MPEG_AUDIO_MODE``
+    (enum)
+
+enum v4l2_mpeg_audio_mode -
+    MPEG Audio mode. Possible values are:
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_AUDIO_MODE_STEREO``
+      - Stereo
+    * - ``V4L2_MPEG_AUDIO_MODE_JOINT_STEREO``
+      - Joint Stereo
+    * - ``V4L2_MPEG_AUDIO_MODE_DUAL``
+      - Bilingual
+    * - ``V4L2_MPEG_AUDIO_MODE_MONO``
+      - Mono
+
+
+
+.. _v4l2-mpeg-audio-mode-extension:
+
+``V4L2_CID_MPEG_AUDIO_MODE_EXTENSION``
+    (enum)
+
+enum v4l2_mpeg_audio_mode_extension -
+    Joint Stereo audio mode extension. In Layer I and II they indicate
+    which subbands are in intensity stereo. All other subbands are coded
+    in stereo. Layer III is not (yet) supported. Possible values are:
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4``
+      - Subbands 4-31 in intensity stereo
+    * - ``V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_8``
+      - Subbands 8-31 in intensity stereo
+    * - ``V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_12``
+      - Subbands 12-31 in intensity stereo
+    * - ``V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16``
+      - Subbands 16-31 in intensity stereo
+
+
+
+.. _v4l2-mpeg-audio-emphasis:
+
+``V4L2_CID_MPEG_AUDIO_EMPHASIS``
+    (enum)
+
+enum v4l2_mpeg_audio_emphasis -
+    Audio Emphasis. Possible values are:
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_AUDIO_EMPHASIS_NONE``
+      - None
+    * - ``V4L2_MPEG_AUDIO_EMPHASIS_50_DIV_15_uS``
+      - 50/15 microsecond emphasis
+    * - ``V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17``
+      - CCITT J.17
+
+
+
+.. _v4l2-mpeg-audio-crc:
+
+``V4L2_CID_MPEG_AUDIO_CRC``
+    (enum)
+
+enum v4l2_mpeg_audio_crc -
+    CRC method. Possible values are:
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_AUDIO_CRC_NONE``
+      - None
+    * - ``V4L2_MPEG_AUDIO_CRC_CRC16``
+      - 16 bit parity check
+
+
+
+``V4L2_CID_MPEG_AUDIO_MUTE (boolean)``
+    Mutes the audio when capturing. This is not done by muting audio
+    hardware, which can still produce a slight hiss, but in the encoder
+    itself, guaranteeing a fixed and reproducible audio bitstream. 0 =
+    unmuted, 1 = muted.
+
+.. _v4l2-mpeg-audio-dec-playback:
+
+``V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK``
+    (enum)
+
+enum v4l2_mpeg_audio_dec_playback -
+    Determines how monolingual audio should be played back. Possible
+    values are:
+
+
+
+.. tabularcolumns:: |p{9.8cm}|p{7.7cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_AUDIO_DEC_PLAYBACK_AUTO``
+      - Automatically determines the best playback mode.
+    * - ``V4L2_MPEG_AUDIO_DEC_PLAYBACK_STEREO``
+      - Stereo playback.
+    * - ``V4L2_MPEG_AUDIO_DEC_PLAYBACK_LEFT``
+      - Left channel playback.
+    * - ``V4L2_MPEG_AUDIO_DEC_PLAYBACK_RIGHT``
+      - Right channel playback.
+    * - ``V4L2_MPEG_AUDIO_DEC_PLAYBACK_MONO``
+      - Mono playback.
+    * - ``V4L2_MPEG_AUDIO_DEC_PLAYBACK_SWAPPED_STEREO``
+      - Stereo playback with swapped left and right channels.
+
+
+
+.. _v4l2-mpeg-audio-dec-multilingual-playback:
+
+``V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK``
+    (enum)
+
+enum v4l2_mpeg_audio_dec_playback -
+    Determines how multilingual audio should be played back.
+
+.. _v4l2-mpeg-video-encoding:
+
+``V4L2_CID_MPEG_VIDEO_ENCODING``
+    (enum)
+
+enum v4l2_mpeg_video_encoding -
+    MPEG Video encoding method. This control is specific to multiplexed
+    MPEG streams. Possible values are:
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_VIDEO_ENCODING_MPEG_1``
+      - MPEG-1 Video encoding
+    * - ``V4L2_MPEG_VIDEO_ENCODING_MPEG_2``
+      - MPEG-2 Video encoding
+    * - ``V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC``
+      - MPEG-4 AVC (H.264) Video encoding
+
+
+
+.. _v4l2-mpeg-video-aspect:
+
+``V4L2_CID_MPEG_VIDEO_ASPECT``
+    (enum)
+
+enum v4l2_mpeg_video_aspect -
+    Video aspect. Possible values are:
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_VIDEO_ASPECT_1x1``
+    * - ``V4L2_MPEG_VIDEO_ASPECT_4x3``
+    * - ``V4L2_MPEG_VIDEO_ASPECT_16x9``
+    * - ``V4L2_MPEG_VIDEO_ASPECT_221x100``
+
+
+
+``V4L2_CID_MPEG_VIDEO_B_FRAMES (integer)``
+    Number of B-Frames (default 2)
+
+``V4L2_CID_MPEG_VIDEO_GOP_SIZE (integer)``
+    GOP size (default 12)
+
+``V4L2_CID_MPEG_VIDEO_GOP_CLOSURE (boolean)``
+    GOP closure (default 1)
+
+``V4L2_CID_MPEG_VIDEO_PULLDOWN (boolean)``
+    Enable 3:2 pulldown (default 0)
+
+.. _v4l2-mpeg-video-bitrate-mode:
+
+``V4L2_CID_MPEG_VIDEO_BITRATE_MODE``
+    (enum)
+
+enum v4l2_mpeg_video_bitrate_mode -
+    Video bitrate mode. Possible values are:
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_VIDEO_BITRATE_MODE_VBR``
+      - Variable bitrate
+    * - ``V4L2_MPEG_VIDEO_BITRATE_MODE_CBR``
+      - Constant bitrate
+
+
+
+``V4L2_CID_MPEG_VIDEO_BITRATE (integer)``
+    Video bitrate in bits per second.
+
+``V4L2_CID_MPEG_VIDEO_BITRATE_PEAK (integer)``
+    Peak video bitrate in bits per second. Must be larger or equal to
+    the average video bitrate. It is ignored if the video bitrate mode
+    is set to constant bitrate.
+
+``V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION (integer)``
+    For every captured frame, skip this many subsequent frames (default
+    0).
+
+``V4L2_CID_MPEG_VIDEO_MUTE (boolean)``
+    "Mutes" the video to a fixed color when capturing. This is useful
+    for testing, to produce a fixed video bitstream. 0 = unmuted, 1 =
+    muted.
+
+``V4L2_CID_MPEG_VIDEO_MUTE_YUV (integer)``
+    Sets the "mute" color of the video. The supplied 32-bit integer is
+    interpreted as follows (bit 0 = least significant bit):
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - Bit 0:7
+      - V chrominance information
+    * - Bit 8:15
+      - U chrominance information
+    * - Bit 16:23
+      - Y luminance information
+    * - Bit 24:31
+      - Must be zero.
+
+
+
+.. _v4l2-mpeg-video-dec-pts:
+
+``V4L2_CID_MPEG_VIDEO_DEC_PTS (integer64)``
+    This read-only control returns the 33-bit video Presentation Time
+    Stamp as defined in ITU T-REC-H.222.0 and ISO/IEC 13818-1 of the
+    currently displayed frame. This is the same PTS as is used in
+    :ref:`VIDIOC_DECODER_CMD`.
+
+.. _v4l2-mpeg-video-dec-frame:
+
+``V4L2_CID_MPEG_VIDEO_DEC_FRAME (integer64)``
+    This read-only control returns the frame counter of the frame that
+    is currently displayed (decoded). This value is reset to 0 whenever
+    the decoder is started.
+
+``V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE (boolean)``
+    If enabled the decoder expects to receive a single slice per buffer,
+    otherwise the decoder expects a single frame in per buffer.
+    Applicable to the decoder, all codecs.
+
+``V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE (boolean)``
+    Enable writing sample aspect ratio in the Video Usability
+    Information. Applicable to the H264 encoder.
+
+.. _v4l2-mpeg-video-h264-vui-sar-idc:
+
+``V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC``
+    (enum)
+
+enum v4l2_mpeg_video_h264_vui_sar_idc -
+    VUI sample aspect ratio indicator for H.264 encoding. The value is
+    defined in the table E-1 in the standard. Applicable to the H264
+    encoder.
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED``
+      - Unspecified
+    * - ``V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_1x1``
+      - 1x1
+    * - ``V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_12x11``
+      - 12x11
+    * - ``V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_10x11``
+      - 10x11
+    * - ``V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_16x11``
+      - 16x11
+    * - ``V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_40x33``
+      - 40x33
+    * - ``V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_24x11``
+      - 24x11
+    * - ``V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_20x11``
+      - 20x11
+    * - ``V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_32x11``
+      - 32x11
+    * - ``V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_80x33``
+      - 80x33
+    * - ``V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_18x11``
+      - 18x11
+    * - ``V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_15x11``
+      - 15x11
+    * - ``V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_64x33``
+      - 64x33
+    * - ``V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_160x99``
+      - 160x99
+    * - ``V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_4x3``
+      - 4x3
+    * - ``V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_3x2``
+      - 3x2
+    * - ``V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_2x1``
+      - 2x1
+    * - ``V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED``
+      - Extended SAR
+
+
+
+``V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH (integer)``
+    Extended sample aspect ratio width for H.264 VUI encoding.
+    Applicable to the H264 encoder.
+
+``V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT (integer)``
+    Extended sample aspect ratio height for H.264 VUI encoding.
+    Applicable to the H264 encoder.
+
+.. _v4l2-mpeg-video-h264-level:
+
+``V4L2_CID_MPEG_VIDEO_H264_LEVEL``
+    (enum)
+
+enum v4l2_mpeg_video_h264_level -
+    The level information for the H264 video elementary stream.
+    Applicable to the H264 encoder. Possible values are:
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_VIDEO_H264_LEVEL_1_0``
+      - Level 1.0
+    * - ``V4L2_MPEG_VIDEO_H264_LEVEL_1B``
+      - Level 1B
+    * - ``V4L2_MPEG_VIDEO_H264_LEVEL_1_1``
+      - Level 1.1
+    * - ``V4L2_MPEG_VIDEO_H264_LEVEL_1_2``
+      - Level 1.2
+    * - ``V4L2_MPEG_VIDEO_H264_LEVEL_1_3``
+      - Level 1.3
+    * - ``V4L2_MPEG_VIDEO_H264_LEVEL_2_0``
+      - Level 2.0
+    * - ``V4L2_MPEG_VIDEO_H264_LEVEL_2_1``
+      - Level 2.1
+    * - ``V4L2_MPEG_VIDEO_H264_LEVEL_2_2``
+      - Level 2.2
+    * - ``V4L2_MPEG_VIDEO_H264_LEVEL_3_0``
+      - Level 3.0
+    * - ``V4L2_MPEG_VIDEO_H264_LEVEL_3_1``
+      - Level 3.1
+    * - ``V4L2_MPEG_VIDEO_H264_LEVEL_3_2``
+      - Level 3.2
+    * - ``V4L2_MPEG_VIDEO_H264_LEVEL_4_0``
+      - Level 4.0
+    * - ``V4L2_MPEG_VIDEO_H264_LEVEL_4_1``
+      - Level 4.1
+    * - ``V4L2_MPEG_VIDEO_H264_LEVEL_4_2``
+      - Level 4.2
+    * - ``V4L2_MPEG_VIDEO_H264_LEVEL_5_0``
+      - Level 5.0
+    * - ``V4L2_MPEG_VIDEO_H264_LEVEL_5_1``
+      - Level 5.1
+
+
+
+.. _v4l2-mpeg-video-mpeg2-level:
+
+``V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL``
+    (enum)
+
+enum v4l2_mpeg_video_mpeg2_level -
+    The level information for the MPEG2 elementary stream. Applicable to
+    MPEG2 codecs. Possible values are:
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_VIDEO_MPEG2_LEVEL_LOW``
+      - Low Level (LL)
+    * - ``V4L2_MPEG_VIDEO_MPEG2_LEVEL_MAIN``
+      - Main Level (ML)
+    * - ``V4L2_MPEG_VIDEO_MPEG2_LEVEL_HIGH_1440``
+      - High-1440 Level (H-14)
+    * - ``V4L2_MPEG_VIDEO_MPEG2_LEVEL_HIGH``
+      - High Level (HL)
+
+
+
+.. _v4l2-mpeg-video-mpeg4-level:
+
+``V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL``
+    (enum)
+
+enum v4l2_mpeg_video_mpeg4_level -
+    The level information for the MPEG4 elementary stream. Applicable to
+    the MPEG4 encoder. Possible values are:
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_VIDEO_MPEG4_LEVEL_0``
+      - Level 0
+    * - ``V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B``
+      - Level 0b
+    * - ``V4L2_MPEG_VIDEO_MPEG4_LEVEL_1``
+      - Level 1
+    * - ``V4L2_MPEG_VIDEO_MPEG4_LEVEL_2``
+      - Level 2
+    * - ``V4L2_MPEG_VIDEO_MPEG4_LEVEL_3``
+      - Level 3
+    * - ``V4L2_MPEG_VIDEO_MPEG4_LEVEL_3B``
+      - Level 3b
+    * - ``V4L2_MPEG_VIDEO_MPEG4_LEVEL_4``
+      - Level 4
+    * - ``V4L2_MPEG_VIDEO_MPEG4_LEVEL_5``
+      - Level 5
+
+
+
+.. _v4l2-mpeg-video-h264-profile:
+
+``V4L2_CID_MPEG_VIDEO_H264_PROFILE``
+    (enum)
+
+enum v4l2_mpeg_video_h264_profile -
+    The profile information for H264. Applicable to the H264 encoder.
+    Possible values are:
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE``
+      - Baseline profile
+    * - ``V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE``
+      - Constrained Baseline profile
+    * - ``V4L2_MPEG_VIDEO_H264_PROFILE_MAIN``
+      - Main profile
+    * - ``V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED``
+      - Extended profile
+    * - ``V4L2_MPEG_VIDEO_H264_PROFILE_HIGH``
+      - High profile
+    * - ``V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10``
+      - High 10 profile
+    * - ``V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422``
+      - High 422 profile
+    * - ``V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE``
+      - High 444 Predictive profile
+    * - ``V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10_INTRA``
+      - High 10 Intra profile
+    * - ``V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422_INTRA``
+      - High 422 Intra profile
+    * - ``V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_INTRA``
+      - High 444 Intra profile
+    * - ``V4L2_MPEG_VIDEO_H264_PROFILE_CAVLC_444_INTRA``
+      - CAVLC 444 Intra profile
+    * - ``V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_BASELINE``
+      - Scalable Baseline profile
+    * - ``V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH``
+      - Scalable High profile
+    * - ``V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH_INTRA``
+      - Scalable High Intra profile
+    * - ``V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH``
+      - Stereo High profile
+    * - ``V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH``
+      - Multiview High profile
+
+
+
+.. _v4l2-mpeg-video-mpeg2-profile:
+
+``V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE``
+    (enum)
+
+enum v4l2_mpeg_video_mpeg2_profile -
+    The profile information for MPEG2. Applicable to MPEG2 codecs.
+    Possible values are:
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_VIDEO_MPEG2_PROFILE_SIMPLE``
+      - Simple profile (SP)
+    * - ``V4L2_MPEG_VIDEO_MPEG2_PROFILE_MAIN``
+      - Main profile (MP)
+    * - ``V4L2_MPEG_VIDEO_MPEG2_PROFILE_SNR_SCALABLE``
+      - SNR Scalable profile (SNR)
+    * - ``V4L2_MPEG_VIDEO_MPEG2_PROFILE_SPATIALLY_SCALABLE``
+      - Spatially Scalable profile (Spt)
+    * - ``V4L2_MPEG_VIDEO_MPEG2_PROFILE_HIGH``
+      - High profile (HP)
+    * - ``V4L2_MPEG_VIDEO_MPEG2_PROFILE_MULTIVIEW``
+      - Multi-view profile (MVP)
+
+
+
+.. _v4l2-mpeg-video-mpeg4-profile:
+
+``V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE``
+    (enum)
+
+enum v4l2_mpeg_video_mpeg4_profile -
+    The profile information for MPEG4. Applicable to the MPEG4 encoder.
+    Possible values are:
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE``
+      - Simple profile
+    * - ``V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE``
+      - Advanced Simple profile
+    * - ``V4L2_MPEG_VIDEO_MPEG4_PROFILE_CORE``
+      - Core profile
+    * - ``V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE_SCALABLE``
+      - Simple Scalable profile
+    * - ``V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY``
+      -
+
+
+
+``V4L2_CID_MPEG_VIDEO_MAX_REF_PIC (integer)``
+    The maximum number of reference pictures used for encoding.
+    Applicable to the encoder.
+
+.. _v4l2-mpeg-video-multi-slice-mode:
+
+``V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE``
+    (enum)
+
+enum v4l2_mpeg_video_multi_slice_mode -
+    Determines how the encoder should handle division of frame into
+    slices. Applicable to the encoder. Possible values are:
+
+
+
+.. tabularcolumns:: |p{9.6cm}|p{7.9cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE``
+      - Single slice per frame.
+    * - ``V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB``
+      - Multiple slices with set maximum number of macroblocks per slice.
+    * - ``V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES``
+      - Multiple slice with set maximum size in bytes per slice.
+
+
+
+``V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB (integer)``
+    The maximum number of macroblocks in a slice. Used when
+    ``V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE`` is set to
+    ``V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB``. Applicable to the
+    encoder.
+
+``V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES (integer)``
+    The maximum size of a slice in bytes. Used when
+    ``V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE`` is set to
+    ``V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES``. Applicable to the
+    encoder.
+
+.. _v4l2-mpeg-video-h264-loop-filter-mode:
+
+``V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE``
+    (enum)
+
+enum v4l2_mpeg_video_h264_loop_filter_mode -
+    Loop filter mode for H264 encoder. Possible values are:
+
+.. raw:: latex
+
+    \small
+
+.. tabularcolumns:: |p{13.6cm}|p{3.9cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED``
+      - Loop filter is enabled.
+    * - ``V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED``
+      - Loop filter is disabled.
+    * - ``V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY``
+      - Loop filter is disabled at the slice boundary.
+
+.. raw:: latex
+
+    \normalsize
+
+
+``V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA (integer)``
+    Loop filter alpha coefficient, defined in the H264 standard.
+    This value corresponds to the slice_alpha_c0_offset_div2 slice header
+    field, and should be in the range of -6 to +6, inclusive. The actual alpha
+    offset FilterOffsetA is twice this value.
+    Applicable to the H264 encoder.
+
+``V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA (integer)``
+    Loop filter beta coefficient, defined in the H264 standard.
+    This corresponds to the slice_beta_offset_div2 slice header field, and
+    should be in the range of -6 to +6, inclusive. The actual beta offset
+    FilterOffsetB is twice this value.
+    Applicable to the H264 encoder.
+
+.. _v4l2-mpeg-video-h264-entropy-mode:
+
+``V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE``
+    (enum)
+
+enum v4l2_mpeg_video_h264_entropy_mode -
+    Entropy coding mode for H264 - CABAC/CAVALC. Applicable to the H264
+    encoder. Possible values are:
+
+
+.. tabularcolumns:: |p{9.0cm}|p{8.5cm}|
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC``
+      - Use CAVLC entropy coding.
+    * - ``V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC``
+      - Use CABAC entropy coding.
+
+
+
+``V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM (boolean)``
+    Enable 8X8 transform for H264. Applicable to the H264 encoder.
+
+``V4L2_CID_MPEG_VIDEO_H264_CONSTRAINED_INTRA_PREDICTION (boolean)``
+    Enable constrained intra prediction for H264. Applicable to the H264
+    encoder.
+
+``V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET (integer)``
+    Specify the offset that should be added to the luma quantization
+    parameter to determine the chroma quantization parameter. Applicable
+    to the H264 encoder.
+
+``V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB (integer)``
+    Cyclic intra macroblock refresh. This is the number of continuous
+    macroblocks refreshed every frame. Each frame a successive set of
+    macroblocks is refreshed until the cycle completes and starts from
+    the top of the frame. Applicable to H264, H263 and MPEG4 encoder.
+
+``V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE (boolean)``
+    Frame level rate control enable. If this control is disabled then
+    the quantization parameter for each frame type is constant and set
+    with appropriate controls (e.g.
+    ``V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP``). If frame rate control is
+    enabled then quantization parameter is adjusted to meet the chosen
+    bitrate. Minimum and maximum value for the quantization parameter
+    can be set with appropriate controls (e.g.
+    ``V4L2_CID_MPEG_VIDEO_H263_MIN_QP``). Applicable to encoders.
+
+``V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE (boolean)``
+    Macroblock level rate control enable. Applicable to the MPEG4 and
+    H264 encoders.
+
+``V4L2_CID_MPEG_VIDEO_MPEG4_QPEL (boolean)``
+    Quarter pixel motion estimation for MPEG4. Applicable to the MPEG4
+    encoder.
+
+``V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP (integer)``
+    Quantization parameter for an I frame for H263. Valid range: from 1
+    to 31.
+
+``V4L2_CID_MPEG_VIDEO_H263_MIN_QP (integer)``
+    Minimum quantization parameter for H263. Valid range: from 1 to 31.
+
+``V4L2_CID_MPEG_VIDEO_H263_MAX_QP (integer)``
+    Maximum quantization parameter for H263. Valid range: from 1 to 31.
+
+``V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP (integer)``
+    Quantization parameter for an P frame for H263. Valid range: from 1
+    to 31.
+
+``V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP (integer)``
+    Quantization parameter for an B frame for H263. Valid range: from 1
+    to 31.
+
+``V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP (integer)``
+    Quantization parameter for an I frame for H264. Valid range: from 0
+    to 51.
+
+``V4L2_CID_MPEG_VIDEO_H264_MIN_QP (integer)``
+    Minimum quantization parameter for H264. Valid range: from 0 to 51.
+
+``V4L2_CID_MPEG_VIDEO_H264_MAX_QP (integer)``
+    Maximum quantization parameter for H264. Valid range: from 0 to 51.
+
+``V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP (integer)``
+    Quantization parameter for an P frame for H264. Valid range: from 0
+    to 51.
+
+``V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP (integer)``
+    Quantization parameter for an B frame for H264. Valid range: from 0
+    to 51.
+
+``V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MIN_QP (integer)``
+    Minimum quantization parameter for the H264 I frame to limit I frame
+    quality to a range. Valid range: from 0 to 51. If
+    V4L2_CID_MPEG_VIDEO_H264_MIN_QP is also set, the quantization parameter
+    should be chosen to meet both requirements.
+
+``V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MAX_QP (integer)``
+    Maximum quantization parameter for the H264 I frame to limit I frame
+    quality to a range. Valid range: from 0 to 51. If
+    V4L2_CID_MPEG_VIDEO_H264_MAX_QP is also set, the quantization parameter
+    should be chosen to meet both requirements.
+
+``V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP (integer)``
+    Minimum quantization parameter for the H264 P frame to limit P frame
+    quality to a range. Valid range: from 0 to 51. If
+    V4L2_CID_MPEG_VIDEO_H264_MIN_QP is also set, the quantization parameter
+    should be chosen to meet both requirements.
+
+``V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP (integer)``
+    Maximum quantization parameter for the H264 P frame to limit P frame
+    quality to a range. Valid range: from 0 to 51. If
+    V4L2_CID_MPEG_VIDEO_H264_MAX_QP is also set, the quantization parameter
+    should be chosen to meet both requirements.
+
+``V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP (integer)``
+    Quantization parameter for an I frame for MPEG4. Valid range: from 1
+    to 31.
+
+``V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP (integer)``
+    Minimum quantization parameter for MPEG4. Valid range: from 1 to 31.
+
+``V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP (integer)``
+    Maximum quantization parameter for MPEG4. Valid range: from 1 to 31.
+
+``V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP (integer)``
+    Quantization parameter for an P frame for MPEG4. Valid range: from 1
+    to 31.
+
+``V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP (integer)``
+    Quantization parameter for an B frame for MPEG4. Valid range: from 1
+    to 31.
+
+``V4L2_CID_MPEG_VIDEO_VBV_SIZE (integer)``
+    The Video Buffer Verifier size in kilobytes, it is used as a
+    limitation of frame skip. The VBV is defined in the standard as a
+    mean to verify that the produced stream will be successfully
+    decoded. The standard describes it as "Part of a hypothetical
+    decoder that is conceptually connected to the output of the encoder.
+    Its purpose is to provide a constraint on the variability of the
+    data rate that an encoder or editing process may produce.".
+    Applicable to the MPEG1, MPEG2, MPEG4 encoders.
+
+.. _v4l2-mpeg-video-vbv-delay:
+
+``V4L2_CID_MPEG_VIDEO_VBV_DELAY (integer)``
+    Sets the initial delay in milliseconds for VBV buffer control.
+
+.. _v4l2-mpeg-video-hor-search-range:
+
+``V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE (integer)``
+    Horizontal search range defines maximum horizontal search area in
+    pixels to search and match for the present Macroblock (MB) in the
+    reference picture. This V4L2 control macro is used to set horizontal
+    search range for motion estimation module in video encoder.
+
+.. _v4l2-mpeg-video-vert-search-range:
+
+``V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE (integer)``
+    Vertical search range defines maximum vertical search area in pixels
+    to search and match for the present Macroblock (MB) in the reference
+    picture. This V4L2 control macro is used to set vertical search
+    range for motion estimation module in video encoder.
+
+.. _v4l2-mpeg-video-force-key-frame:
+
+``V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME (button)``
+    Force a key frame for the next queued buffer. Applicable to
+    encoders. This is a general, codec-agnostic keyframe control.
+
+``V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE (integer)``
+    The Coded Picture Buffer size in kilobytes, it is used as a
+    limitation of frame skip. The CPB is defined in the H264 standard as
+    a mean to verify that the produced stream will be successfully
+    decoded. Applicable to the H264 encoder.
+
+``V4L2_CID_MPEG_VIDEO_H264_I_PERIOD (integer)``
+    Period between I-frames in the open GOP for H264. In case of an open
+    GOP this is the period between two I-frames. The period between IDR
+    (Instantaneous Decoding Refresh) frames is taken from the GOP_SIZE
+    control. An IDR frame, which stands for Instantaneous Decoding
+    Refresh is an I-frame after which no prior frames are referenced.
+    This means that a stream can be restarted from an IDR frame without
+    the need to store or decode any previous frames. Applicable to the
+    H264 encoder.
+
+.. _v4l2-mpeg-video-header-mode:
+
+``V4L2_CID_MPEG_VIDEO_HEADER_MODE``
+    (enum)
+
+enum v4l2_mpeg_video_header_mode -
+    Determines whether the header is returned as the first buffer or is
+    it returned together with the first frame. Applicable to encoders.
+    Possible values are:
+
+.. raw:: latex
+
+    \small
+
+.. tabularcolumns:: |p{10.3cm}|p{7.2cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE``
+      - The stream header is returned separately in the first buffer.
+    * - ``V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME``
+      - The stream header is returned together with the first encoded
+	frame.
+
+.. raw:: latex
+
+    \normalsize
+
+
+``V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER (boolean)``
+    Repeat the video sequence headers. Repeating these headers makes
+    random access to the video stream easier. Applicable to the MPEG1, 2
+    and 4 encoder.
+
+``V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER (boolean)``
+    Enabled the deblocking post processing filter for MPEG4 decoder.
+    Applicable to the MPEG4 decoder.
+
+``V4L2_CID_MPEG_VIDEO_MPEG4_VOP_TIME_RES (integer)``
+    vop_time_increment_resolution value for MPEG4. Applicable to the
+    MPEG4 encoder.
+
+``V4L2_CID_MPEG_VIDEO_MPEG4_VOP_TIME_INC (integer)``
+    vop_time_increment value for MPEG4. Applicable to the MPEG4
+    encoder.
+
+``V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING (boolean)``
+    Enable generation of frame packing supplemental enhancement
+    information in the encoded bitstream. The frame packing SEI message
+    contains the arrangement of L and R planes for 3D viewing.
+    Applicable to the H264 encoder.
+
+``V4L2_CID_MPEG_VIDEO_H264_SEI_FP_CURRENT_FRAME_0 (boolean)``
+    Sets current frame as frame0 in frame packing SEI. Applicable to the
+    H264 encoder.
+
+.. _v4l2-mpeg-video-h264-sei-fp-arrangement-type:
+
+``V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE``
+    (enum)
+
+enum v4l2_mpeg_video_h264_sei_fp_arrangement_type -
+    Frame packing arrangement type for H264 SEI. Applicable to the H264
+    encoder. Possible values are:
+
+.. raw:: latex
+
+    \small
+
+.. tabularcolumns:: |p{12cm}|p{5.5cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_CHEKERBOARD``
+      - Pixels are alternatively from L and R.
+    * - ``V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_COLUMN``
+      - L and R are interlaced by column.
+    * - ``V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_ROW``
+      - L and R are interlaced by row.
+    * - ``V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_SIDE_BY_SIDE``
+      - L is on the left, R on the right.
+    * - ``V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_TOP_BOTTOM``
+      - L is on top, R on bottom.
+    * - ``V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_TEMPORAL``
+      - One view per frame.
+
+.. raw:: latex
+
+    \normalsize
+
+
+
+``V4L2_CID_MPEG_VIDEO_H264_FMO (boolean)``
+    Enables flexible macroblock ordering in the encoded bitstream. It is
+    a technique used for restructuring the ordering of macroblocks in
+    pictures. Applicable to the H264 encoder.
+
+.. _v4l2-mpeg-video-h264-fmo-map-type:
+
+``V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE``
+   (enum)
+
+enum v4l2_mpeg_video_h264_fmo_map_type -
+    When using FMO, the map type divides the image in different scan
+    patterns of macroblocks. Applicable to the H264 encoder. Possible
+    values are:
+
+.. raw:: latex
+
+    \small
+
+.. tabularcolumns:: |p{12.5cm}|p{5.0cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_INTERLEAVED_SLICES``
+      - Slices are interleaved one after other with macroblocks in run
+	length order.
+    * - ``V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_SCATTERED_SLICES``
+      - Scatters the macroblocks based on a mathematical function known to
+	both encoder and decoder.
+    * - ``V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_FOREGROUND_WITH_LEFT_OVER``
+      - Macroblocks arranged in rectangular areas or regions of interest.
+    * - ``V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_BOX_OUT``
+      - Slice groups grow in a cyclic way from centre to outwards.
+    * - ``V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_RASTER_SCAN``
+      - Slice groups grow in raster scan pattern from left to right.
+    * - ``V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_WIPE_SCAN``
+      - Slice groups grow in wipe scan pattern from top to bottom.
+    * - ``V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_EXPLICIT``
+      - User defined map type.
+
+.. raw:: latex
+
+    \normalsize
+
+
+
+``V4L2_CID_MPEG_VIDEO_H264_FMO_SLICE_GROUP (integer)``
+    Number of slice groups in FMO. Applicable to the H264 encoder.
+
+.. _v4l2-mpeg-video-h264-fmo-change-direction:
+
+``V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_DIRECTION``
+    (enum)
+
+enum v4l2_mpeg_video_h264_fmo_change_dir -
+    Specifies a direction of the slice group change for raster and wipe
+    maps. Applicable to the H264 encoder. Possible values are:
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_VIDEO_H264_FMO_CHANGE_DIR_RIGHT``
+      - Raster scan or wipe right.
+    * - ``V4L2_MPEG_VIDEO_H264_FMO_CHANGE_DIR_LEFT``
+      - Reverse raster scan or wipe left.
+
+
+
+``V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_RATE (integer)``
+    Specifies the size of the first slice group for raster and wipe map.
+    Applicable to the H264 encoder.
+
+``V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH (integer)``
+    Specifies the number of consecutive macroblocks for the interleaved
+    map. Applicable to the H264 encoder.
+
+``V4L2_CID_MPEG_VIDEO_H264_ASO (boolean)``
+    Enables arbitrary slice ordering in encoded bitstream. Applicable to
+    the H264 encoder.
+
+``V4L2_CID_MPEG_VIDEO_H264_ASO_SLICE_ORDER (integer)``
+    Specifies the slice order in ASO. Applicable to the H264 encoder.
+    The supplied 32-bit integer is interpreted as follows (bit 0 = least
+    significant bit):
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - Bit 0:15
+      - Slice ID
+    * - Bit 16:32
+      - Slice position or order
+
+
+
+``V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING (boolean)``
+    Enables H264 hierarchical coding. Applicable to the H264 encoder.
+
+.. _v4l2-mpeg-video-h264-hierarchical-coding-type:
+
+``V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE``
+    (enum)
+
+enum v4l2_mpeg_video_h264_hierarchical_coding_type -
+    Specifies the hierarchical coding type. Applicable to the H264
+    encoder. Possible values are:
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B``
+      - Hierarchical B coding.
+    * - ``V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P``
+      - Hierarchical P coding.
+
+
+
+``V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER (integer)``
+    Specifies the number of hierarchical coding layers. Applicable to
+    the H264 encoder.
+
+``V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP (integer)``
+    Specifies a user defined QP for each layer. Applicable to the H264
+    encoder. The supplied 32-bit integer is interpreted as follows (bit
+    0 = least significant bit):
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - Bit 0:15
+      - QP value
+    * - Bit 16:32
+      - Layer number
+
+
+.. _v4l2-mpeg-h264:
+
+``V4L2_CID_MPEG_VIDEO_H264_SPS (struct)``
+    Specifies the sequence parameter set (as extracted from the
+    bitstream) for the associated H264 slice data. This includes the
+    necessary parameters for configuring a stateless hardware decoding
+    pipeline for H264. The bitstream parameters are defined according
+    to :ref:`h264`, section 7.4.2.1.1 "Sequence Parameter Set Data
+    Semantics". For further documentation, refer to the above
+    specification, unless there is an explicit comment stating
+    otherwise.
+
+    .. note::
+
+       This compound control is not yet part of the public kernel API and
+       it is expected to change.
+
+.. c:type:: v4l2_ctrl_h264_sps
+
+.. cssclass:: longtable
+
+.. flat-table:: struct v4l2_ctrl_h264_sps
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u8
+      - ``profile_idc``
+      -
+    * - __u8
+      - ``constraint_set_flags``
+      - See :ref:`Sequence Parameter Set Constraints Set Flags <h264_sps_constraints_set_flags>`
+    * - __u8
+      - ``level_idc``
+      -
+    * - __u8
+      - ``seq_parameter_set_id``
+      -
+    * - __u8
+      - ``chroma_format_idc``
+      -
+    * - __u8
+      - ``bit_depth_luma_minus8``
+      -
+    * - __u8
+      - ``bit_depth_chroma_minus8``
+      -
+    * - __u8
+      - ``log2_max_frame_num_minus4``
+      -
+    * - __u8
+      - ``pic_order_cnt_type``
+      -
+    * - __u8
+      - ``log2_max_pic_order_cnt_lsb_minus4``
+      -
+    * - __u8
+      - ``max_num_ref_frames``
+      -
+    * - __u8
+      - ``num_ref_frames_in_pic_order_cnt_cycle``
+      -
+    * - __s32
+      - ``offset_for_ref_frame[255]``
+      -
+    * - __s32
+      - ``offset_for_non_ref_pic``
+      -
+    * - __s32
+      - ``offset_for_top_to_bottom_field``
+      -
+    * - __u16
+      - ``pic_width_in_mbs_minus1``
+      -
+    * - __u16
+      - ``pic_height_in_map_units_minus1``
+      -
+    * - __u32
+      - ``flags``
+      - See :ref:`Sequence Parameter Set Flags <h264_sps_flags>`
+
+.. _h264_sps_constraints_set_flags:
+
+``Sequence Parameter Set Constraints Set Flags``
+
+.. cssclass:: longtable
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - ``V4L2_H264_SPS_CONSTRAINT_SET0_FLAG``
+      - 0x00000001
+      -
+    * - ``V4L2_H264_SPS_CONSTRAINT_SET1_FLAG``
+      - 0x00000002
+      -
+    * - ``V4L2_H264_SPS_CONSTRAINT_SET2_FLAG``
+      - 0x00000004
+      -
+    * - ``V4L2_H264_SPS_CONSTRAINT_SET3_FLAG``
+      - 0x00000008
+      -
+    * - ``V4L2_H264_SPS_CONSTRAINT_SET4_FLAG``
+      - 0x00000010
+      -
+    * - ``V4L2_H264_SPS_CONSTRAINT_SET5_FLAG``
+      - 0x00000020
+      -
+
+.. _h264_sps_flags:
+
+``Sequence Parameter Set Flags``
+
+.. cssclass:: longtable
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - ``V4L2_H264_SPS_FLAG_SEPARATE_COLOUR_PLANE``
+      - 0x00000001
+      -
+    * - ``V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS``
+      - 0x00000002
+      -
+    * - ``V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO``
+      - 0x00000004
+      -
+    * - ``V4L2_H264_SPS_FLAG_GAPS_IN_FRAME_NUM_VALUE_ALLOWED``
+      - 0x00000008
+      -
+    * - ``V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY``
+      - 0x00000010
+      -
+    * - ``V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD``
+      - 0x00000020
+      -
+    * - ``V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE``
+      - 0x00000040
+      -
+
+``V4L2_CID_MPEG_VIDEO_H264_PPS (struct)``
+    Specifies the picture parameter set (as extracted from the
+    bitstream) for the associated H264 slice data. This includes the
+    necessary parameters for configuring a stateless hardware decoding
+    pipeline for H264.  The bitstream parameters are defined according
+    to :ref:`h264`, section 7.4.2.2 "Picture Parameter Set RBSP
+    Semantics". For further documentation, refer to the above
+    specification, unless there is an explicit comment stating
+    otherwise.
+
+    .. note::
+
+       This compound control is not yet part of the public kernel API and
+       it is expected to change.
+
+.. c:type:: v4l2_ctrl_h264_pps
+
+.. cssclass:: longtable
+
+.. flat-table:: struct v4l2_ctrl_h264_pps
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u8
+      - ``pic_parameter_set_id``
+      -
+    * - __u8
+      - ``seq_parameter_set_id``
+      -
+    * - __u8
+      - ``num_slice_groups_minus1``
+      -
+    * - __u8
+      - ``num_ref_idx_l0_default_active_minus1``
+      -
+    * - __u8
+      - ``num_ref_idx_l1_default_active_minus1``
+      -
+    * - __u8
+      - ``weighted_bipred_idc``
+      -
+    * - __s8
+      - ``pic_init_qp_minus26``
+      -
+    * - __s8
+      - ``pic_init_qs_minus26``
+      -
+    * - __s8
+      - ``chroma_qp_index_offset``
+      -
+    * - __s8
+      - ``second_chroma_qp_index_offset``
+      -
+    * - __u16
+      - ``flags``
+      - See :ref:`Picture Parameter Set Flags <h264_pps_flags>`
+
+.. _h264_pps_flags:
+
+``Picture Parameter Set Flags``
+
+.. cssclass:: longtable
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - ``V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE``
+      - 0x00000001
+      -
+    * - ``V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT``
+      - 0x00000002
+      -
+    * - ``V4L2_H264_PPS_FLAG_WEIGHTED_PRED``
+      - 0x00000004
+      -
+    * - ``V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT``
+      - 0x00000008
+      -
+    * - ``V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED``
+      - 0x00000010
+      -
+    * - ``V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT``
+      - 0x00000020
+      -
+    * - ``V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE``
+      - 0x00000040
+      -
+    * - ``V4L2_H264_PPS_FLAG_PIC_SCALING_MATRIX_PRESENT``
+      - 0x00000080
+      -
+
+``V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX (struct)``
+    Specifies the scaling matrix (as extracted from the bitstream) for
+    the associated H264 slice data. The bitstream parameters are
+    defined according to :ref:`h264`, section 7.4.2.1.1.1 "Scaling
+    List Semantics". For further documentation, refer to the above
+    specification, unless there is an explicit comment stating
+    otherwise.
+
+    .. note::
+
+       This compound control is not yet part of the public kernel API and
+       it is expected to change.
+
+.. c:type:: v4l2_ctrl_h264_scaling_matrix
+
+.. cssclass:: longtable
+
+.. flat-table:: struct v4l2_ctrl_h264_scaling_matrix
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u8
+      - ``scaling_list_4x4[6][16]``
+      - Scaling matrix after applying the inverse scanning process.
+        Expected list order is Intra Y, Intra Cb, Intra Cr, Inter Y,
+        Inter Cb, Inter Cr.
+    * - __u8
+      - ``scaling_list_8x8[6][64]``
+      - Scaling matrix after applying the inverse scanning process.
+        Expected list order is Intra Y, Inter Y, Intra Cb, Inter Cb,
+        Intra Cr, Inter Cr.
+
+``V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS (struct)``
+    Specifies the slice parameters (as extracted from the bitstream)
+    for the associated H264 slice data. This includes the necessary
+    parameters for configuring a stateless hardware decoding pipeline
+    for H264.  The bitstream parameters are defined according to
+    :ref:`h264`, section 7.4.3 "Slice Header Semantics". For further
+    documentation, refer to the above specification, unless there is
+    an explicit comment stating otherwise.
+
+    .. note::
+
+       This compound control is not yet part of the public kernel API
+       and it is expected to change.
+
+       This structure is expected to be passed as an array, with one
+       entry for each slice included in the bitstream buffer.
+
+.. c:type:: v4l2_ctrl_h264_slice_params
+
+.. cssclass:: longtable
+
+.. flat-table:: struct v4l2_ctrl_h264_slice_params
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``size``
+      -
+    * - __u32
+      - ``start_byte_offset``
+        Offset (in bytes) from the beginning of the OUTPUT buffer to the start
+        of the slice. If the slice starts with a start code, then this is the
+        offset to such start code. When operating in slice-based decoding mode
+        (see :c:type:`v4l2_mpeg_video_h264_decode_mode`), this field should
+        be set to 0. When operating in frame-based decoding mode, this field
+        should be 0 for the first slice.
+    * - __u32
+      - ``header_bit_size``
+      -
+    * - __u16
+      - ``first_mb_in_slice``
+      -
+    * - __u8
+      - ``slice_type``
+      -
+    * - __u8
+      - ``pic_parameter_set_id``
+      -
+    * - __u8
+      - ``colour_plane_id``
+      -
+    * - __u8
+      - ``redundant_pic_cnt``
+      -
+    * - __u16
+      - ``frame_num``
+      -
+    * - __u16
+      - ``idr_pic_id``
+      -
+    * - __u16
+      - ``pic_order_cnt_lsb``
+      -
+    * - __s32
+      - ``delta_pic_order_cnt_bottom``
+      -
+    * - __s32
+      - ``delta_pic_order_cnt0``
+      -
+    * - __s32
+      - ``delta_pic_order_cnt1``
+      -
+    * - struct :c:type:`v4l2_h264_pred_weight_table`
+      - ``pred_weight_table``
+      -
+    * - __u32
+      - ``dec_ref_pic_marking_bit_size``
+      - Size in bits of the dec_ref_pic_marking() syntax element.
+    * - __u32
+      - ``pic_order_cnt_bit_size``
+      -
+    * - __u8
+      - ``cabac_init_idc``
+      -
+    * - __s8
+      - ``slice_qp_delta``
+      -
+    * - __s8
+      - ``slice_qs_delta``
+      -
+    * - __u8
+      - ``disable_deblocking_filter_idc``
+      -
+    * - __s8
+      - ``slice_alpha_c0_offset_div2``
+      -
+    * - __s8
+      - ``slice_beta_offset_div2``
+      -
+    * - __u8
+      - ``num_ref_idx_l0_active_minus1``
+      - If num_ref_idx_active_override_flag is not set, this field must be
+        set to the value of num_ref_idx_l0_default_active_minus1.
+    * - __u8
+      - ``num_ref_idx_l1_active_minus1``
+      - If num_ref_idx_active_override_flag is not set, this field must be
+        set to the value of num_ref_idx_l1_default_active_minus1.
+    * - __u32
+      - ``slice_group_change_cycle``
+      -
+    * - __u8
+      - ``ref_pic_list0[32]``
+      - Reference picture list after applying the per-slice modifications
+    * - __u8
+      - ``ref_pic_list1[32]``
+      - Reference picture list after applying the per-slice modifications
+    * - __u32
+      - ``flags``
+      - See :ref:`Slice Parameter Flags <h264_slice_flags>`
+
+.. _h264_slice_flags:
+
+``Slice Parameter Set Flags``
+
+.. cssclass:: longtable
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - ``V4L2_H264_SLICE_FLAG_FIELD_PIC``
+      - 0x00000001
+      -
+    * - ``V4L2_H264_SLICE_FLAG_BOTTOM_FIELD``
+      - 0x00000002
+      -
+    * - ``V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED``
+      - 0x00000004
+      -
+    * - ``V4L2_H264_SLICE_FLAG_SP_FOR_SWITCH``
+      - 0x00000008
+      -
+
+``Prediction Weight Table``
+
+    The bitstream parameters are defined according to :ref:`h264`,
+    section 7.4.3.2 "Prediction Weight Table Semantics". For further
+    documentation, refer to the above specification, unless there is
+    an explicit comment stating otherwise.
+
+.. c:type:: v4l2_h264_pred_weight_table
+
+.. cssclass:: longtable
+
+.. flat-table:: struct v4l2_h264_pred_weight_table
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u16
+      - ``luma_log2_weight_denom``
+      -
+    * - __u16
+      - ``chroma_log2_weight_denom``
+      -
+    * - struct :c:type:`v4l2_h264_weight_factors`
+      - ``weight_factors[2]``
+      - The weight factors at index 0 are the weight factors for the reference
+        list 0, the one at index 1 for the reference list 1.
+
+.. c:type:: v4l2_h264_weight_factors
+
+.. cssclass:: longtable
+
+.. flat-table:: struct v4l2_h264_weight_factors
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __s16
+      - ``luma_weight[32]``
+      -
+    * - __s16
+      - ``luma_offset[32]``
+      -
+    * - __s16
+      - ``chroma_weight[32][2]``
+      -
+    * - __s16
+      - ``chroma_offset[32][2]``
+      -
+
+``V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS (struct)``
+    Specifies the decode parameters (as extracted from the bitstream)
+    for the associated H264 slice data. This includes the necessary
+    parameters for configuring a stateless hardware decoding pipeline
+    for H264. The bitstream parameters are defined according to
+    :ref:`h264`. For further documentation, refer to the above
+    specification, unless there is an explicit comment stating
+    otherwise.
+
+    .. note::
+
+       This compound control is not yet part of the public kernel API and
+       it is expected to change.
+
+.. c:type:: v4l2_ctrl_h264_decode_params
+
+.. cssclass:: longtable
+
+.. flat-table:: struct v4l2_ctrl_h264_decode_params
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - struct :c:type:`v4l2_h264_dpb_entry`
+      - ``dpb[16]``
+      -
+    * - __u16
+      - ``num_slices``
+      - Number of slices needed to decode the current frame/field. When
+        operating in slice-based decoding mode (see
+        :c:type:`v4l2_mpeg_video_h264_decode_mode`), this field
+        should always be set to one.
+    * - __u16
+      - ``nal_ref_idc``
+      - NAL reference ID value coming from the NAL Unit header
+    * - __s32
+      - ``top_field_order_cnt``
+      - Picture Order Count for the coded top field
+    * - __s32
+      - ``bottom_field_order_cnt``
+      - Picture Order Count for the coded bottom field
+    * - __u32
+      - ``flags``
+      - See :ref:`Decode Parameters Flags <h264_decode_params_flags>`
+
+.. _h264_decode_params_flags:
+
+``Decode Parameters Flags``
+
+.. cssclass:: longtable
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - ``V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC``
+      - 0x00000001
+      - That picture is an IDR picture
+
+.. c:type:: v4l2_h264_dpb_entry
+
+.. cssclass:: longtable
+
+.. flat-table:: struct v4l2_h264_dpb_entry
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u64
+      - ``reference_ts``
+      - Timestamp of the V4L2 capture buffer to use as reference, used
+        with B-coded and P-coded frames. The timestamp refers to the
+        ``timestamp`` field in struct :c:type:`v4l2_buffer`. Use the
+        :c:func:`v4l2_timeval_to_ns()` function to convert the struct
+        :c:type:`timeval` in struct :c:type:`v4l2_buffer` to a __u64.
+    * - __u16
+      - ``frame_num``
+      -
+    * - __u16
+      - ``pic_num``
+      -
+    * - __s32
+      - ``top_field_order_cnt``
+      -
+    * - __s32
+      - ``bottom_field_order_cnt``
+      -
+    * - __u32
+      - ``flags``
+      - See :ref:`DPB Entry Flags <h264_dpb_flags>`
+
+.. _h264_dpb_flags:
+
+``DPB Entries Flags``
+
+.. cssclass:: longtable
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - ``V4L2_H264_DPB_ENTRY_FLAG_VALID``
+      - 0x00000001
+      - The DPB entry is valid and should be considered
+    * - ``V4L2_H264_DPB_ENTRY_FLAG_ACTIVE``
+      - 0x00000002
+      - The DPB entry is currently being used as a reference frame
+    * - ``V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM``
+      - 0x00000004
+      - The DPB entry is a long term reference frame
+    * - ``V4L2_H264_DPB_ENTRY_FLAG_FIELD``
+      - 0x00000008
+      - The DPB entry is a field reference, which means only one of the field
+        will be used when decoding the new frame/field. When not set the DPB
+        entry is a frame reference (both fields will be used). Note that this
+        flag does not say anything about the number of fields contained in the
+        reference frame, it just describes the one used to decode the new
+        field/frame
+    * - ``V4L2_H264_DPB_ENTRY_FLAG_BOTTOM_FIELD``
+      - 0x00000010
+      - The DPB entry is a bottom field reference (only the bottom field of the
+        reference frame is needed to decode the new frame/field). Only valid if
+        V4L2_H264_DPB_ENTRY_FLAG_FIELD is set. When
+        V4L2_H264_DPB_ENTRY_FLAG_FIELD is set but
+        V4L2_H264_DPB_ENTRY_FLAG_BOTTOM_FIELD is not, that means the
+        DPB entry is a top field reference
+
+``V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE (enum)``
+    Specifies the decoding mode to use. Currently exposes slice-based and
+    frame-based decoding but new modes might be added later on.
+    This control is used as a modifier for V4L2_PIX_FMT_H264_SLICE
+    pixel format. Applications that support V4L2_PIX_FMT_H264_SLICE
+    are required to set this control in order to specify the decoding mode
+    that is expected for the buffer.
+    Drivers may expose a single or multiple decoding modes, depending
+    on what they can support.
+
+    .. note::
+
+       This menu control is not yet part of the public kernel API and
+       it is expected to change.
+
+.. c:type:: v4l2_mpeg_video_h264_decode_mode
+
+.. cssclass:: longtable
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - ``V4L2_MPEG_VIDEO_H264_DECODE_MODE_SLICE_BASED``
+      - 0
+      - Decoding is done at the slice granularity.
+        In this mode, ``num_slices`` field in struct
+        :c:type:`v4l2_ctrl_h264_decode_params` should be set to 1,
+        and ``start_byte_offset`` in struct
+        :c:type:`v4l2_ctrl_h264_slice_params` should be set to 0.
+        The OUTPUT buffer must contain a single slice.
+    * - ``V4L2_MPEG_VIDEO_H264_DECODE_MODE_FRAME_BASED``
+      - 1
+      - Decoding is done at the frame granularity.
+        In this mode, ``num_slices`` field in struct
+        :c:type:`v4l2_ctrl_h264_decode_params` should be set to the number
+        of slices in the frame, and ``start_byte_offset`` in struct
+        :c:type:`v4l2_ctrl_h264_slice_params` should be set accordingly
+        for each slice. For the first slice, ``start_byte_offset`` should
+        be zero.
+        The OUTPUT buffer must contain all slices needed to decode the
+        frame. The OUTPUT buffer must also contain both fields.
+
+``V4L2_CID_MPEG_VIDEO_H264_START_CODE (enum)``
+    Specifies the H264 slice start code expected for each slice.
+    This control is used as a modifier for V4L2_PIX_FMT_H264_SLICE
+    pixel format. Applications that support V4L2_PIX_FMT_H264_SLICE
+    are required to set this control in order to specify the start code
+    that is expected for the buffer.
+    Drivers may expose a single or multiple start codes, depending
+    on what they can support.
+
+    .. note::
+
+       This menu control is not yet part of the public kernel API and
+       it is expected to change.
+
+.. c:type:: v4l2_mpeg_video_h264_start_code
+
+.. cssclass:: longtable
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - ``V4L2_MPEG_VIDEO_H264_START_CODE_NONE``
+      - 0
+      - Selecting this value specifies that H264 slices are passed
+        to the driver without any start code.
+    * - ``V4L2_MPEG_VIDEO_H264_START_CODE_ANNEX_B``
+      - 1
+      - Selecting this value specifies that H264 slices are expected
+        to be prefixed by Annex B start codes. According to :ref:`h264`
+        valid start codes can be 3-bytes 0x000001 or 4-bytes 0x00000001.
+
+.. _v4l2-mpeg-mpeg2:
+
+``V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS (struct)``
+    Specifies the slice parameters (as extracted from the bitstream) for the
+    associated MPEG-2 slice data. This includes the necessary parameters for
+    configuring a stateless hardware decoding pipeline for MPEG-2.
+    The bitstream parameters are defined according to :ref:`mpeg2part2`.
+
+    .. note::
+
+       This compound control is not yet part of the public kernel API and
+       it is expected to change.
+
+.. c:type:: v4l2_ctrl_mpeg2_slice_params
+
+.. cssclass:: longtable
+
+.. tabularcolumns:: |p{5.8cm}|p{4.8cm}|p{6.6cm}|
+
+.. flat-table:: struct v4l2_ctrl_mpeg2_slice_params
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``bit_size``
+      - Size (in bits) of the current slice data.
+    * - __u32
+      - ``data_bit_offset``
+      - Offset (in bits) to the video data in the current slice data.
+    * - struct :c:type:`v4l2_mpeg2_sequence`
+      - ``sequence``
+      - Structure with MPEG-2 sequence metadata, merging relevant fields from
+	the sequence header and sequence extension parts of the bitstream.
+    * - struct :c:type:`v4l2_mpeg2_picture`
+      - ``picture``
+      - Structure with MPEG-2 picture metadata, merging relevant fields from
+	the picture header and picture coding extension parts of the bitstream.
+    * - __u64
+      - ``backward_ref_ts``
+      - Timestamp of the V4L2 capture buffer to use as backward reference, used
+        with B-coded and P-coded frames. The timestamp refers to the
+	``timestamp`` field in struct :c:type:`v4l2_buffer`. Use the
+	:c:func:`v4l2_timeval_to_ns()` function to convert the struct
+	:c:type:`timeval` in struct :c:type:`v4l2_buffer` to a __u64.
+    * - __u64
+      - ``forward_ref_ts``
+      - Timestamp for the V4L2 capture buffer to use as forward reference, used
+        with B-coded frames. The timestamp refers to the ``timestamp`` field in
+	struct :c:type:`v4l2_buffer`. Use the :c:func:`v4l2_timeval_to_ns()`
+	function to convert the struct :c:type:`timeval` in struct
+	:c:type:`v4l2_buffer` to a __u64.
+    * - __u32
+      - ``quantiser_scale_code``
+      - Code used to determine the quantization scale to use for the IDCT.
+
+.. c:type:: v4l2_mpeg2_sequence
+
+.. cssclass:: longtable
+
+.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
+
+.. flat-table:: struct v4l2_mpeg2_sequence
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u16
+      - ``horizontal_size``
+      - The width of the displayable part of the frame's luminance component.
+    * - __u16
+      - ``vertical_size``
+      - The height of the displayable part of the frame's luminance component.
+    * - __u32
+      - ``vbv_buffer_size``
+      - Used to calculate the required size of the video buffering verifier,
+	defined (in bits) as: 16 * 1024 * vbv_buffer_size.
+    * - __u16
+      - ``profile_and_level_indication``
+      - The current profile and level indication as extracted from the
+	bitstream.
+    * - __u8
+      - ``progressive_sequence``
+      - Indication that all the frames for the sequence are progressive instead
+	of interlaced.
+    * - __u8
+      - ``chroma_format``
+      - The chrominance sub-sampling format (1: 4:2:0, 2: 4:2:2, 3: 4:4:4).
+
+.. c:type:: v4l2_mpeg2_picture
+
+.. cssclass:: longtable
+
+.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
+
+.. flat-table:: struct v4l2_mpeg2_picture
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u8
+      - ``picture_coding_type``
+      - Picture coding type for the frame covered by the current slice
+	(V4L2_MPEG2_PICTURE_CODING_TYPE_I, V4L2_MPEG2_PICTURE_CODING_TYPE_P or
+	V4L2_MPEG2_PICTURE_CODING_TYPE_B).
+    * - __u8
+      - ``f_code[2][2]``
+      - Motion vector codes.
+    * - __u8
+      - ``intra_dc_precision``
+      - Precision of Discrete Cosine transform (0: 8 bits precision,
+	1: 9 bits precision, 2: 10 bits precision, 3: 11 bits precision).
+    * - __u8
+      - ``picture_structure``
+      - Picture structure (1: interlaced top field, 2: interlaced bottom field,
+	3: progressive frame).
+    * - __u8
+      - ``top_field_first``
+      - If set to 1 and interlaced stream, top field is output first.
+    * - __u8
+      - ``frame_pred_frame_dct``
+      - If set to 1, only frame-DCT and frame prediction are used.
+    * - __u8
+      - ``concealment_motion_vectors``
+      -  If set to 1, motion vectors are coded for intra macroblocks.
+    * - __u8
+      - ``q_scale_type``
+      - This flag affects the inverse quantization process.
+    * - __u8
+      - ``intra_vlc_format``
+      - This flag affects the decoding of transform coefficient data.
+    * - __u8
+      - ``alternate_scan``
+      - This flag affects the decoding of transform coefficient data.
+    * - __u8
+      - ``repeat_first_field``
+      - This flag affects the decoding process of progressive frames.
+    * - __u16
+      - ``progressive_frame``
+      - Indicates whether the current frame is progressive.
+
+``V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION (struct)``
+    Specifies quantization matrices (as extracted from the bitstream) for the
+    associated MPEG-2 slice data.
+
+    .. note::
+
+       This compound control is not yet part of the public kernel API and
+       it is expected to change.
+
+.. c:type:: v4l2_ctrl_mpeg2_quantization
+
+.. cssclass:: longtable
+
+.. tabularcolumns:: |p{1.2cm}|p{8.0cm}|p{7.4cm}|
+
+.. raw:: latex
+
+    \small
+
+.. flat-table:: struct v4l2_ctrl_mpeg2_quantization
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u8
+      - ``load_intra_quantiser_matrix``
+      - One bit to indicate whether to load the ``intra_quantiser_matrix`` data.
+    * - __u8
+      - ``load_non_intra_quantiser_matrix``
+      - One bit to indicate whether to load the ``non_intra_quantiser_matrix``
+	data.
+    * - __u8
+      - ``load_chroma_intra_quantiser_matrix``
+      - One bit to indicate whether to load the
+	``chroma_intra_quantiser_matrix`` data, only relevant for non-4:2:0 YUV
+	formats.
+    * - __u8
+      - ``load_chroma_non_intra_quantiser_matrix``
+      - One bit to indicate whether to load the
+	``chroma_non_intra_quantiser_matrix`` data, only relevant for non-4:2:0
+	YUV formats.
+    * - __u8
+      - ``intra_quantiser_matrix[64]``
+      - The quantization matrix coefficients for intra-coded frames, in zigzag
+	scanning order. It is relevant for both luma and chroma components,
+	although it can be superseded by the chroma-specific matrix for
+	non-4:2:0 YUV formats.
+    * - __u8
+      - ``non_intra_quantiser_matrix[64]``
+      - The quantization matrix coefficients for non-intra-coded frames, in
+	zigzag scanning order. It is relevant for both luma and chroma
+	components, although it can be superseded by the chroma-specific matrix
+	for non-4:2:0 YUV formats.
+    * - __u8
+      - ``chroma_intra_quantiser_matrix[64]``
+      - The quantization matrix coefficients for the chominance component of
+	intra-coded frames, in zigzag scanning order. Only relevant for
+	non-4:2:0 YUV formats.
+    * - __u8
+      - ``chroma_non_intra_quantiser_matrix[64]``
+      - The quantization matrix coefficients for the chrominance component of
+	non-intra-coded frames, in zigzag scanning order. Only relevant for
+	non-4:2:0 YUV formats.
+
+``V4L2_CID_FWHT_I_FRAME_QP (integer)``
+    Quantization parameter for an I frame for FWHT. Valid range: from 1
+    to 31.
+
+``V4L2_CID_FWHT_P_FRAME_QP (integer)``
+    Quantization parameter for a P frame for FWHT. Valid range: from 1
+    to 31.
+
+.. _v4l2-mpeg-vp8:
+
+``V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER (struct)``
+    Specifies the frame parameters for the associated VP8 parsed frame data.
+    This includes the necessary parameters for
+    configuring a stateless hardware decoding pipeline for VP8.
+    The bitstream parameters are defined according to :ref:`vp8`.
+
+    .. note::
+
+       This compound control is not yet part of the public kernel API and
+       it is expected to change.
+
+.. c:type:: v4l2_ctrl_vp8_frame_header
+
+.. cssclass:: longtable
+
+.. tabularcolumns:: |p{5.8cm}|p{4.8cm}|p{6.6cm}|
+
+.. flat-table:: struct v4l2_ctrl_vp8_frame_header
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - struct :c:type:`v4l2_vp8_segment_header`
+      - ``segment_header``
+      - Structure with segment-based adjustments metadata.
+    * - struct :c:type:`v4l2_vp8_loopfilter_header`
+      - ``loopfilter_header``
+      - Structure with loop filter level adjustments metadata.
+    * - struct :c:type:`v4l2_vp8_quantization_header`
+      - ``quant_header``
+      - Structure with VP8 dequantization indices metadata.
+    * - struct :c:type:`v4l2_vp8_entropy_header`
+      - ``entropy_header``
+      - Structure with VP8 entropy coder probabilities metadata.
+    * - struct :c:type:`v4l2_vp8_entropy_coder_state`
+      - ``coder_state``
+      - Structure with VP8 entropy coder state.
+    * - __u16
+      - ``width``
+      - The width of the frame. Must be set for all frames.
+    * - __u16
+      - ``height``
+      - The height of the frame. Must be set for all frames.
+    * - __u8
+      - ``horizontal_scale``
+      - Horizontal scaling factor.
+    * - __u8
+      - ``vertical_scaling factor``
+      - Vertical scale.
+    * - __u8
+      - ``version``
+      - Bitstream version.
+    * - __u8
+      - ``prob_skip_false``
+      - Indicates the probability that the macroblock is not skipped.
+    * - __u8
+      - ``prob_intra``
+      - Indicates the probability that a macroblock is intra-predicted.
+    * - __u8
+      - ``prob_last``
+      - Indicates the probability that the last reference frame is used
+        for inter-prediction
+    * - __u8
+      - ``prob_gf``
+      - Indicates the probability that the golden reference frame is used
+        for inter-prediction
+    * - __u8
+      - ``num_dct_parts``
+      - Number of DCT coefficients partitions. Must be one of: 1, 2, 4, or 8.
+    * - __u32
+      - ``first_part_size``
+      - Size of the first partition, i.e. the control partition.
+    * - __u32
+      - ``first_part_header_bits``
+      - Size in bits of the first partition header portion.
+    * - __u32
+      - ``dct_part_sizes[8]``
+      - DCT coefficients sizes.
+    * - __u64
+      - ``last_frame_ts``
+      - Timestamp for the V4L2 capture buffer to use as last reference frame, used
+        with inter-coded frames. The timestamp refers to the ``timestamp`` field in
+	struct :c:type:`v4l2_buffer`. Use the :c:func:`v4l2_timeval_to_ns()`
+	function to convert the struct :c:type:`timeval` in struct
+	:c:type:`v4l2_buffer` to a __u64.
+    * - __u64
+      - ``golden_frame_ts``
+      - Timestamp for the V4L2 capture buffer to use as last reference frame, used
+        with inter-coded frames. The timestamp refers to the ``timestamp`` field in
+	struct :c:type:`v4l2_buffer`. Use the :c:func:`v4l2_timeval_to_ns()`
+	function to convert the struct :c:type:`timeval` in struct
+	:c:type:`v4l2_buffer` to a __u64.
+    * - __u64
+      - ``alt_frame_ts``
+      - Timestamp for the V4L2 capture buffer to use as alternate reference frame, used
+        with inter-coded frames. The timestamp refers to the ``timestamp`` field in
+	struct :c:type:`v4l2_buffer`. Use the :c:func:`v4l2_timeval_to_ns()`
+	function to convert the struct :c:type:`timeval` in struct
+	:c:type:`v4l2_buffer` to a __u64.
+    * - __u64
+      - ``flags``
+      - See :ref:`Frame Header Flags <vp8_frame_header_flags>`
+
+.. _vp8_frame_header_flags:
+
+``Frame Header Flags``
+
+.. cssclass:: longtable
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - ``V4L2_VP8_FRAME_HEADER_FLAG_KEY_FRAME``
+      - 0x01
+      - Indicates if the frame is a key frame.
+    * - ``V4L2_VP8_FRAME_HEADER_FLAG_EXPERIMENTAL``
+      - 0x02
+      - Experimental bitstream.
+    * - ``V4L2_VP8_FRAME_HEADER_FLAG_SHOW_FRAME``
+      - 0x04
+      - Show frame flag, indicates if the frame is for display.
+    * - ``V4L2_VP8_FRAME_HEADER_FLAG_MB_NO_SKIP_COEFF``
+      - 0x08
+      - Enable/disable skipping of macroblocks with no non-zero coefficients.
+    * - ``V4L2_VP8_FRAME_HEADER_FLAG_SIGN_BIAS_GOLDEN``
+      - 0x10
+      - Sign of motion vectors when the golden frame is referenced.
+    * - ``V4L2_VP8_FRAME_HEADER_FLAG_SIGN_BIAS_ALT``
+      - 0x20
+      - Sign of motion vectors when the alt frame is referenced.
+
+.. c:type:: v4l2_vp8_entropy_coder_state
+
+.. cssclass:: longtable
+
+.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
+
+.. flat-table:: struct v4l2_vp8_entropy_coder_state
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u8
+      - ``range``
+      -
+    * - __u8
+      - ``value``
+      -
+    * - __u8
+      - ``bit_count``
+      -
+    * - __u8
+      - ``padding``
+      - Applications and drivers must set this to zero.
+
+.. c:type:: v4l2_vp8_segment_header
+
+.. cssclass:: longtable
+
+.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
+
+.. flat-table:: struct v4l2_vp8_segment_header
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __s8
+      - ``quant_update[4]``
+      - Signed quantizer value update.
+    * - __s8
+      - ``lf_update[4]``
+      - Signed loop filter level value update.
+    * - __u8
+      - ``segment_probs[3]``
+      - Segment probabilities.
+    * - __u8
+      - ``padding``
+      - Applications and drivers must set this to zero.
+    * - __u32
+      - ``flags``
+      - See :ref:`Segment Header Flags <vp8_segment_header_flags>`
+
+.. _vp8_segment_header_flags:
+
+``Segment Header Flags``
+
+.. cssclass:: longtable
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - ``V4L2_VP8_SEGMENT_HEADER_FLAG_ENABLED``
+      - 0x01
+      - Enable/disable segment-based adjustments.
+    * - ``V4L2_VP8_SEGMENT_HEADER_FLAG_UPDATE_MAP``
+      - 0x02
+      - Indicates if the macroblock segmentation map is updated in this frame.
+    * - ``V4L2_VP8_SEGMENT_HEADER_FLAG_UPDATE_FEATURE_DATA``
+      - 0x04
+      - Indicates if the segment feature data is updated in this frame.
+    * - ``V4L2_VP8_SEGMENT_HEADER_FLAG_DELTA_VALUE_MODE``
+      - 0x08
+      - If is set, the segment feature data mode is delta-value.
+        If cleared, it's absolute-value.
+
+.. c:type:: v4l2_vp8_loopfilter_header
+
+.. cssclass:: longtable
+
+.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
+
+.. flat-table:: struct v4l2_vp8_loopfilter_header
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __s8
+      - ``ref_frm_delta[4]``
+      - Reference adjustment (signed) delta value.
+    * - __s8
+      - ``mb_mode_delta[4]``
+      - Macroblock prediction mode adjustment (signed) delta value.
+    * - __u8
+      - ``sharpness_level``
+      - Sharpness level
+    * - __u8
+      - ``level``
+      - Filter level
+    * - __u16
+      - ``padding``
+      - Applications and drivers must set this to zero.
+    * - __u32
+      - ``flags``
+      - See :ref:`Loopfilter Header Flags <vp8_loopfilter_header_flags>`
+
+.. _vp8_loopfilter_header_flags:
+
+``Loopfilter Header Flags``
+
+.. cssclass:: longtable
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - ``V4L2_VP8_LF_HEADER_ADJ_ENABLE``
+      - 0x01
+      - Enable/disable macroblock-level loop filter adjustment.
+    * - ``V4L2_VP8_LF_HEADER_DELTA_UPDATE``
+      - 0x02
+      - Indicates if the delta values used in an adjustment are updated.
+    * - ``V4L2_VP8_LF_FILTER_TYPE_SIMPLE``
+      - 0x04
+      - If set, indicates the filter type is simple.
+        If cleared, the filter type is normal.
+
+.. c:type:: v4l2_vp8_quantization_header
+
+.. cssclass:: longtable
+
+.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
+
+.. flat-table:: struct v4l2_vp8_quantization_header
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u8
+      - ``y_ac_qi``
+      - Luma AC coefficient table index.
+    * - __s8
+      - ``y_dc_delta``
+      - Luma DC delta vaue.
+    * - __s8
+      - ``y2_dc_delta``
+      - Y2 block DC delta value.
+    * - __s8
+      - ``y2_ac_delta``
+      - Y2 block AC delta value.
+    * - __s8
+      - ``uv_dc_delta``
+      - Chroma DC delta value.
+    * - __s8
+      - ``uv_ac_delta``
+      - Chroma AC delta value.
+    * - __u16
+      - ``padding``
+      - Applications and drivers must set this to zero.
+
+.. c:type:: v4l2_vp8_entropy_header
+
+.. cssclass:: longtable
+
+.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
+
+.. flat-table:: struct v4l2_vp8_entropy_header
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u8
+      - ``coeff_probs[4][8][3][11]``
+      - Coefficient update probabilities.
+    * - __u8
+      - ``y_mode_probs[4]``
+      - Luma mode update probabilities.
+    * - __u8
+      - ``uv_mode_probs[3]``
+      - Chroma mode update probabilities.
+    * - __u8
+      - ``mv_probs[2][19]``
+      - MV decoding update probabilities.
+    * - __u8
+      - ``padding[3]``
+      - Applications and drivers must set this to zero.
+
+.. raw:: latex
+
+    \normalsize
+
+
+MFC 5.1 MPEG Controls
+=====================
+
+The following MPEG class controls deal with MPEG decoding and encoding
+settings that are specific to the Multi Format Codec 5.1 device present
+in the S5P family of SoCs by Samsung.
+
+
+.. _mfc51-control-id:
+
+MFC 5.1 Control IDs
+-------------------
+
+``V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY_ENABLE (boolean)``
+    If the display delay is enabled then the decoder is forced to return
+    a CAPTURE buffer (decoded frame) after processing a certain number
+    of OUTPUT buffers. The delay can be set through
+    ``V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY``. This
+    feature can be used for example for generating thumbnails of videos.
+    Applicable to the H264 decoder.
+
+``V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY (integer)``
+    Display delay value for H264 decoder. The decoder is forced to
+    return a decoded frame after the set 'display delay' number of
+    frames. If this number is low it may result in frames returned out
+    of display order, in addition the hardware may still be using the
+    returned buffer as a reference picture for subsequent frames.
+
+``V4L2_CID_MPEG_MFC51_VIDEO_H264_NUM_REF_PIC_FOR_P (integer)``
+    The number of reference pictures used for encoding a P picture.
+    Applicable to the H264 encoder.
+
+``V4L2_CID_MPEG_MFC51_VIDEO_PADDING (boolean)``
+    Padding enable in the encoder - use a color instead of repeating
+    border pixels. Applicable to encoders.
+
+``V4L2_CID_MPEG_MFC51_VIDEO_PADDING_YUV (integer)``
+    Padding color in the encoder. Applicable to encoders. The supplied
+    32-bit integer is interpreted as follows (bit 0 = least significant
+    bit):
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - Bit 0:7
+      - V chrominance information
+    * - Bit 8:15
+      - U chrominance information
+    * - Bit 16:23
+      - Y luminance information
+    * - Bit 24:31
+      - Must be zero.
+
+
+
+``V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF (integer)``
+    Reaction coefficient for MFC rate control. Applicable to encoders.
+
+    .. note::
+
+       #. Valid only when the frame level RC is enabled.
+
+       #. For tight CBR, this field must be small (ex. 2 ~ 10). For
+	  VBR, this field must be large (ex. 100 ~ 1000).
+
+       #. It is not recommended to use the greater number than
+	  FRAME_RATE * (10^9 / BIT_RATE).
+
+``V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_DARK (boolean)``
+    Adaptive rate control for dark region. Valid only when H.264 and
+    macroblock level RC is enabled
+    (``V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE``). Applicable to the H264
+    encoder.
+
+``V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_SMOOTH (boolean)``
+    Adaptive rate control for smooth region. Valid only when H.264 and
+    macroblock level RC is enabled
+    (``V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE``). Applicable to the H264
+    encoder.
+
+``V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_STATIC (boolean)``
+    Adaptive rate control for static region. Valid only when H.264 and
+    macroblock level RC is enabled
+    (``V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE``). Applicable to the H264
+    encoder.
+
+``V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_ACTIVITY (boolean)``
+    Adaptive rate control for activity region. Valid only when H.264 and
+    macroblock level RC is enabled
+    (``V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE``). Applicable to the H264
+    encoder.
+
+.. _v4l2-mpeg-mfc51-video-frame-skip-mode:
+
+``V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE``
+    (enum)
+
+enum v4l2_mpeg_mfc51_video_frame_skip_mode -
+    Indicates in what conditions the encoder should skip frames. If
+    encoding a frame would cause the encoded stream to be larger then a
+    chosen data limit then the frame will be skipped. Possible values
+    are:
+
+
+.. tabularcolumns:: |p{9.2cm}|p{8.3cm}|
+
+.. raw:: latex
+
+    \small
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_MFC51_FRAME_SKIP_MODE_DISABLED``
+      - Frame skip mode is disabled.
+    * - ``V4L2_MPEG_MFC51_FRAME_SKIP_MODE_LEVEL_LIMIT``
+      - Frame skip mode enabled and buffer limit is set by the chosen
+	level and is defined by the standard.
+    * - ``V4L2_MPEG_MFC51_FRAME_SKIP_MODE_BUF_LIMIT``
+      - Frame skip mode enabled and buffer limit is set by the VBV
+	(MPEG1/2/4) or CPB (H264) buffer size control.
+
+.. raw:: latex
+
+    \normalsize
+
+``V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT (integer)``
+    Enable rate-control with fixed target bit. If this setting is
+    enabled, then the rate control logic of the encoder will calculate
+    the average bitrate for a GOP and keep it below or equal the set
+    bitrate target. Otherwise the rate control logic calculates the
+    overall average bitrate for the stream and keeps it below or equal
+    to the set bitrate. In the first case the average bitrate for the
+    whole stream will be smaller then the set bitrate. This is caused
+    because the average is calculated for smaller number of frames, on
+    the other hand enabling this setting will ensure that the stream
+    will meet tight bandwidth constraints. Applicable to encoders.
+
+.. _v4l2-mpeg-mfc51-video-force-frame-type:
+
+``V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE``
+    (enum)
+
+enum v4l2_mpeg_mfc51_video_force_frame_type -
+    Force a frame type for the next queued buffer. Applicable to
+    encoders. Possible values are:
+
+.. tabularcolumns:: |p{9.5cm}|p{8.0cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_MFC51_FORCE_FRAME_TYPE_DISABLED``
+      - Forcing a specific frame type disabled.
+    * - ``V4L2_MPEG_MFC51_FORCE_FRAME_TYPE_I_FRAME``
+      - Force an I-frame.
+    * - ``V4L2_MPEG_MFC51_FORCE_FRAME_TYPE_NOT_CODED``
+      - Force a non-coded frame.
+
+
+.. _v4l2-mpeg-fwht:
+
+``V4L2_CID_MPEG_VIDEO_FWHT_PARAMS (struct)``
+    Specifies the fwht parameters (as extracted from the bitstream) for the
+    associated FWHT data. This includes the necessary parameters for
+    configuring a stateless hardware decoding pipeline for FWHT.
+
+    .. note::
+
+       This compound control is not yet part of the public kernel API and
+       it is expected to change.
+
+.. c:type:: v4l2_ctrl_fwht_params
+
+.. cssclass:: longtable
+
+.. tabularcolumns:: |p{1.4cm}|p{4.3cm}|p{11.8cm}|
+
+.. flat-table:: struct v4l2_ctrl_fwht_params
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u64
+      - ``backward_ref_ts``
+      - Timestamp of the V4L2 capture buffer to use as backward reference, used
+        with P-coded frames. The timestamp refers to the
+	``timestamp`` field in struct :c:type:`v4l2_buffer`. Use the
+	:c:func:`v4l2_timeval_to_ns()` function to convert the struct
+	:c:type:`timeval` in struct :c:type:`v4l2_buffer` to a __u64.
+    * - __u32
+      - ``version``
+      - The version of the codec
+    * - __u32
+      - ``width``
+      - The width of the frame
+    * - __u32
+      - ``height``
+      - The height of the frame
+    * - __u32
+      - ``flags``
+      - The flags of the frame, see :ref:`fwht-flags`.
+    * - __u32
+      - ``colorspace``
+      - The colorspace of the frame, from enum :c:type:`v4l2_colorspace`.
+    * - __u32
+      - ``xfer_func``
+      - The transfer function, from enum :c:type:`v4l2_xfer_func`.
+    * - __u32
+      - ``ycbcr_enc``
+      - The Y'CbCr encoding, from enum :c:type:`v4l2_ycbcr_encoding`.
+    * - __u32
+      - ``quantization``
+      - The quantization range, from enum :c:type:`v4l2_quantization`.
+
+
+
+.. _fwht-flags:
+
+FWHT Flags
+============
+
+.. cssclass:: longtable
+
+.. tabularcolumns:: |p{6.8cm}|p{2.4cm}|p{8.3cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``FWHT_FL_IS_INTERLACED``
+      - 0x00000001
+      - Set if this is an interlaced format
+    * - ``FWHT_FL_IS_BOTTOM_FIRST``
+      - 0x00000002
+      - Set if this is a bottom-first (NTSC) interlaced format
+    * - ``FWHT_FL_IS_ALTERNATE``
+      - 0x00000004
+      - Set if each 'frame' contains just one field
+    * - ``FWHT_FL_IS_BOTTOM_FIELD``
+      - 0x00000008
+      - If FWHT_FL_IS_ALTERNATE was set, then this is set if this 'frame' is the
+	bottom field, else it is the top field.
+    * - ``FWHT_FL_LUMA_IS_UNCOMPRESSED``
+      - 0x00000010
+      - Set if the luma plane is uncompressed
+    * - ``FWHT_FL_CB_IS_UNCOMPRESSED``
+      - 0x00000020
+      - Set if the cb plane is uncompressed
+    * - ``FWHT_FL_CR_IS_UNCOMPRESSED``
+      - 0x00000040
+      - Set if the cr plane is uncompressed
+    * - ``FWHT_FL_CHROMA_FULL_HEIGHT``
+      - 0x00000080
+      - Set if the chroma plane has the same height as the luma plane,
+	else the chroma plane is half the height of the luma plane
+    * - ``FWHT_FL_CHROMA_FULL_WIDTH``
+      - 0x00000100
+      - Set if the chroma plane has the same width as the luma plane,
+	else the chroma plane is half the width of the luma plane
+    * - ``FWHT_FL_ALPHA_IS_UNCOMPRESSED``
+      - 0x00000200
+      - Set if the alpha plane is uncompressed
+    * - ``FWHT_FL_I_FRAME``
+      - 0x00000400
+      - Set if this is an I-frame
+    * - ``FWHT_FL_COMPONENTS_NUM_MSK``
+      - 0x00070000
+      - A 4-values flag - the number of components - 1
+    * - ``FWHT_FL_PIXENC_YUV``
+      - 0x00080000
+      - Set if the pixel encoding is YUV
+    * - ``FWHT_FL_PIXENC_RGB``
+      - 0x00100000
+      - Set if the pixel encoding is RGB
+    * - ``FWHT_FL_PIXENC_HSV``
+      - 0x00180000
+      - Set if the pixel encoding is HSV
+
+
+CX2341x MPEG Controls
+=====================
+
+The following MPEG class controls deal with MPEG encoding settings that
+are specific to the Conexant CX23415 and CX23416 MPEG encoding chips.
+
+
+.. _cx2341x-control-id:
+
+CX2341x Control IDs
+-------------------
+
+.. _v4l2-mpeg-cx2341x-video-spatial-filter-mode:
+
+``V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE``
+    (enum)
+
+enum v4l2_mpeg_cx2341x_video_spatial_filter_mode -
+    Sets the Spatial Filter mode (default ``MANUAL``). Possible values
+    are:
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL``
+      - Choose the filter manually
+    * - ``V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO``
+      - Choose the filter automatically
+
+
+
+``V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER (integer (0-15))``
+    The setting for the Spatial Filter. 0 = off, 15 = maximum. (Default
+    is 0.)
+
+.. _luma-spatial-filter-type:
+
+``V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE``
+    (enum)
+
+enum v4l2_mpeg_cx2341x_video_luma_spatial_filter_type -
+    Select the algorithm to use for the Luma Spatial Filter (default
+    ``1D_HOR``). Possible values:
+
+.. tabularcolumns:: |p{14.5cm}|p{3.0cm}|
+
+.. raw:: latex
+
+    \small
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF``
+      - No filter
+    * - ``V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR``
+      - One-dimensional horizontal
+    * - ``V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_VERT``
+      - One-dimensional vertical
+    * - ``V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_HV_SEPARABLE``
+      - Two-dimensional separable
+    * - ``V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE``
+      - Two-dimensional symmetrical non-separable
+
+.. raw:: latex
+
+    \normalsize
+
+
+
+.. _chroma-spatial-filter-type:
+
+``V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE``
+    (enum)
+
+enum v4l2_mpeg_cx2341x_video_chroma_spatial_filter_type -
+    Select the algorithm for the Chroma Spatial Filter (default
+    ``1D_HOR``). Possible values are:
+
+
+.. tabularcolumns:: |p{14.0cm}|p{3.5cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF``
+      - No filter
+    * - ``V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR``
+      - One-dimensional horizontal
+
+
+
+.. _v4l2-mpeg-cx2341x-video-temporal-filter-mode:
+
+``V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE``
+    (enum)
+
+enum v4l2_mpeg_cx2341x_video_temporal_filter_mode -
+    Sets the Temporal Filter mode (default ``MANUAL``). Possible values
+    are:
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL``
+      - Choose the filter manually
+    * - ``V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO``
+      - Choose the filter automatically
+
+
+
+``V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER (integer (0-31))``
+    The setting for the Temporal Filter. 0 = off, 31 = maximum. (Default
+    is 8 for full-scale capturing and 0 for scaled capturing.)
+
+.. _v4l2-mpeg-cx2341x-video-median-filter-type:
+
+``V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE``
+    (enum)
+
+enum v4l2_mpeg_cx2341x_video_median_filter_type -
+    Median Filter Type (default ``OFF``). Possible values are:
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF``
+      - No filter
+    * - ``V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR``
+      - Horizontal filter
+    * - ``V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_VERT``
+      - Vertical filter
+    * - ``V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR_VERT``
+      - Horizontal and vertical filter
+    * - ``V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG``
+      - Diagonal filter
+
+
+
+``V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM (integer (0-255))``
+    Threshold above which the luminance median filter is enabled
+    (default 0)
+
+``V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP (integer (0-255))``
+    Threshold below which the luminance median filter is enabled
+    (default 255)
+
+``V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM (integer (0-255))``
+    Threshold above which the chroma median filter is enabled (default
+    0)
+
+``V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP (integer (0-255))``
+    Threshold below which the chroma median filter is enabled (default
+    255)
+
+``V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS (boolean)``
+    The CX2341X MPEG encoder can insert one empty MPEG-2 PES packet into
+    the stream between every four video frames. The packet size is 2048
+    bytes, including the packet_start_code_prefix and stream_id
+    fields. The stream_id is 0xBF (private stream 2). The payload
+    consists of 0x00 bytes, to be filled in by the application. 0 = do
+    not insert, 1 = insert packets.
+
+
+VPX Control Reference
+=====================
+
+The VPX controls include controls for encoding parameters of VPx video
+codec.
+
+
+.. _vpx-control-id:
+
+VPX Control IDs
+---------------
+
+.. _v4l2-vpx-num-partitions:
+
+``V4L2_CID_MPEG_VIDEO_VPX_NUM_PARTITIONS``
+    (enum)
+
+enum v4l2_vp8_num_partitions -
+    The number of token partitions to use in VP8 encoder. Possible
+    values are:
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_CID_MPEG_VIDEO_VPX_1_PARTITION``
+      - 1 coefficient partition
+    * - ``V4L2_CID_MPEG_VIDEO_VPX_2_PARTITIONS``
+      - 2 coefficient partitions
+    * - ``V4L2_CID_MPEG_VIDEO_VPX_4_PARTITIONS``
+      - 4 coefficient partitions
+    * - ``V4L2_CID_MPEG_VIDEO_VPX_8_PARTITIONS``
+      - 8 coefficient partitions
+
+
+
+``V4L2_CID_MPEG_VIDEO_VPX_IMD_DISABLE_4X4 (boolean)``
+    Setting this prevents intra 4x4 mode in the intra mode decision.
+
+.. _v4l2-vpx-num-ref-frames:
+
+``V4L2_CID_MPEG_VIDEO_VPX_NUM_REF_FRAMES``
+    (enum)
+
+enum v4l2_vp8_num_ref_frames -
+    The number of reference pictures for encoding P frames. Possible
+    values are:
+
+.. tabularcolumns:: |p{7.9cm}|p{9.6cm}|
+
+.. raw:: latex
+
+    \small
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_CID_MPEG_VIDEO_VPX_1_REF_FRAME``
+      - Last encoded frame will be searched
+    * - ``V4L2_CID_MPEG_VIDEO_VPX_2_REF_FRAME``
+      - Two frames will be searched among the last encoded frame, the
+	golden frame and the alternate reference (altref) frame. The
+	encoder implementation will decide which two are chosen.
+    * - ``V4L2_CID_MPEG_VIDEO_VPX_3_REF_FRAME``
+      - The last encoded frame, the golden frame and the altref frame will
+	be searched.
+
+.. raw:: latex
+
+    \normalsize
+
+
+
+``V4L2_CID_MPEG_VIDEO_VPX_FILTER_LEVEL (integer)``
+    Indicates the loop filter level. The adjustment of the loop filter
+    level is done via a delta value against a baseline loop filter
+    value.
+
+``V4L2_CID_MPEG_VIDEO_VPX_FILTER_SHARPNESS (integer)``
+    This parameter affects the loop filter. Anything above zero weakens
+    the deblocking effect on the loop filter.
+
+``V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_REF_PERIOD (integer)``
+    Sets the refresh period for the golden frame. The period is defined
+    in number of frames. For a value of 'n', every nth frame starting
+    from the first key frame will be taken as a golden frame. For eg.
+    for encoding sequence of 0, 1, 2, 3, 4, 5, 6, 7 where the golden
+    frame refresh period is set as 4, the frames 0, 4, 8 etc will be
+    taken as the golden frames as frame 0 is always a key frame.
+
+.. _v4l2-vpx-golden-frame-sel:
+
+``V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_SEL``
+    (enum)
+
+enum v4l2_vp8_golden_frame_sel -
+    Selects the golden frame for encoding. Possible values are:
+
+.. raw:: latex
+
+    \scriptsize
+
+.. tabularcolumns:: |p{9.0cm}|p{8.0cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_USE_PREV``
+      - Use the (n-2)th frame as a golden frame, current frame index being
+	'n'.
+    * - ``V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_USE_REF_PERIOD``
+      - Use the previous specific frame indicated by
+	``V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_REF_PERIOD`` as a
+	golden frame.
+
+.. raw:: latex
+
+    \normalsize
+
+
+``V4L2_CID_MPEG_VIDEO_VPX_MIN_QP (integer)``
+    Minimum quantization parameter for VP8.
+
+``V4L2_CID_MPEG_VIDEO_VPX_MAX_QP (integer)``
+    Maximum quantization parameter for VP8.
+
+``V4L2_CID_MPEG_VIDEO_VPX_I_FRAME_QP (integer)``
+    Quantization parameter for an I frame for VP8.
+
+``V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP (integer)``
+    Quantization parameter for a P frame for VP8.
+
+.. _v4l2-mpeg-video-vp8-profile:
+
+``V4L2_CID_MPEG_VIDEO_VP8_PROFILE``
+    (enum)
+
+enum v4l2_mpeg_video_vp8_profile -
+    This control allows selecting the profile for VP8 encoder.
+    This is also used to enumerate supported profiles by VP8 encoder or decoder.
+    Possible values are:
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_VIDEO_VP8_PROFILE_0``
+      - Profile 0
+    * - ``V4L2_MPEG_VIDEO_VP8_PROFILE_1``
+      - Profile 1
+    * - ``V4L2_MPEG_VIDEO_VP8_PROFILE_2``
+      - Profile 2
+    * - ``V4L2_MPEG_VIDEO_VP8_PROFILE_3``
+      - Profile 3
+
+.. _v4l2-mpeg-video-vp9-profile:
+
+``V4L2_CID_MPEG_VIDEO_VP9_PROFILE``
+    (enum)
+
+enum v4l2_mpeg_video_vp9_profile -
+    This control allows selecting the profile for VP9 encoder.
+    This is also used to enumerate supported profiles by VP9 encoder or decoder.
+    Possible values are:
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_VIDEO_VP9_PROFILE_0``
+      - Profile 0
+    * - ``V4L2_MPEG_VIDEO_VP9_PROFILE_1``
+      - Profile 1
+    * - ``V4L2_MPEG_VIDEO_VP9_PROFILE_2``
+      - Profile 2
+    * - ``V4L2_MPEG_VIDEO_VP9_PROFILE_3``
+      - Profile 3
+
+
+High Efficiency Video Coding (HEVC/H.265) Control Reference
+===========================================================
+
+The HEVC/H.265 controls include controls for encoding parameters of HEVC/H.265
+video codec.
+
+
+.. _hevc-control-id:
+
+HEVC/H.265 Control IDs
+----------------------
+
+``V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP (integer)``
+    Minimum quantization parameter for HEVC.
+    Valid range: from 0 to 51.
+
+``V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP (integer)``
+    Maximum quantization parameter for HEVC.
+    Valid range: from 0 to 51.
+
+``V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP (integer)``
+    Quantization parameter for an I frame for HEVC.
+    Valid range: [V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP,
+    V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP].
+
+``V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP (integer)``
+    Quantization parameter for a P frame for HEVC.
+    Valid range: [V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP,
+    V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP].
+
+``V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP (integer)``
+    Quantization parameter for a B frame for HEVC.
+    Valid range: [V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP,
+    V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP].
+
+``V4L2_CID_MPEG_VIDEO_HEVC_HIER_QP (boolean)``
+    HIERARCHICAL_QP allows the host to specify the quantization parameter
+    values for each temporal layer through HIERARCHICAL_QP_LAYER. This is
+    valid only if HIERARCHICAL_CODING_LAYER is greater than 1. Setting the
+    control value to 1 enables setting of the QP values for the layers.
+
+.. _v4l2-hevc-hier-coding-type:
+
+``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE``
+    (enum)
+
+enum v4l2_mpeg_video_hevc_hier_coding_type -
+    Selects the hierarchical coding type for encoding. Possible values are:
+
+.. raw:: latex
+
+    \footnotesize
+
+.. tabularcolumns:: |p{9.0cm}|p{8.0cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B``
+      - Use the B frame for hierarchical coding.
+    * - ``V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P``
+      - Use the P frame for hierarchical coding.
+
+.. raw:: latex
+
+    \normalsize
+
+
+``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER (integer)``
+    Selects the hierarchical coding layer. In normal encoding
+    (non-hierarchial coding), it should be zero. Possible values are [0, 6].
+    0 indicates HIERARCHICAL CODING LAYER 0, 1 indicates HIERARCHICAL CODING
+    LAYER 1 and so on.
+
+``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_QP (integer)``
+    Indicates quantization parameter for hierarchical coding layer 0.
+    Valid range: [V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP,
+    V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP].
+
+``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_QP (integer)``
+    Indicates quantization parameter for hierarchical coding layer 1.
+    Valid range: [V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP,
+    V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP].
+
+``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_QP (integer)``
+    Indicates quantization parameter for hierarchical coding layer 2.
+    Valid range: [V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP,
+    V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP].
+
+``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_QP (integer)``
+    Indicates quantization parameter for hierarchical coding layer 3.
+    Valid range: [V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP,
+    V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP].
+
+``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_QP (integer)``
+    Indicates quantization parameter for hierarchical coding layer 4.
+    Valid range: [V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP,
+    V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP].
+
+``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_QP (integer)``
+    Indicates quantization parameter for hierarchical coding layer 5.
+    Valid range: [V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP,
+    V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP].
+
+``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_QP (integer)``
+    Indicates quantization parameter for hierarchical coding layer 6.
+    Valid range: [V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP,
+    V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP].
+
+.. _v4l2-hevc-profile:
+
+``V4L2_CID_MPEG_VIDEO_HEVC_PROFILE``
+    (enum)
+
+enum v4l2_mpeg_video_hevc_profile -
+    Select the desired profile for HEVC encoder.
+
+.. raw:: latex
+
+    \footnotesize
+
+.. tabularcolumns:: |p{9.0cm}|p{8.0cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN``
+      - Main profile.
+    * - ``V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE``
+      - Main still picture profile.
+    * - ``V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10``
+      - Main 10 profile.
+
+.. raw:: latex
+
+    \normalsize
+
+
+.. _v4l2-hevc-level:
+
+``V4L2_CID_MPEG_VIDEO_HEVC_LEVEL``
+    (enum)
+
+enum v4l2_mpeg_video_hevc_level -
+    Selects the desired level for HEVC encoder.
+
+.. raw:: latex
+
+    \footnotesize
+
+.. tabularcolumns:: |p{9.0cm}|p{8.0cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_1``
+      - Level 1.0
+    * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_2``
+      - Level 2.0
+    * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1``
+      - Level 2.1
+    * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_3``
+      - Level 3.0
+    * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1``
+      - Level 3.1
+    * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_4``
+      - Level 4.0
+    * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1``
+      - Level 4.1
+    * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_5``
+      - Level 5.0
+    * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1``
+      - Level 5.1
+    * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2``
+      - Level 5.2
+    * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_6``
+      - Level 6.0
+    * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1``
+      - Level 6.1
+    * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2``
+      - Level 6.2
+
+.. raw:: latex
+
+    \normalsize
+
+
+``V4L2_CID_MPEG_VIDEO_HEVC_FRAME_RATE_RESOLUTION (integer)``
+    Indicates the number of evenly spaced subintervals, called ticks, within
+    one second. This is a 16 bit unsigned integer and has a maximum value up to
+    0xffff and a minimum value of 1.
+
+.. _v4l2-hevc-tier:
+
+``V4L2_CID_MPEG_VIDEO_HEVC_TIER``
+    (enum)
+
+enum v4l2_mpeg_video_hevc_tier -
+    TIER_FLAG specifies tiers information of the HEVC encoded picture. Tier
+    were made to deal with applications that differ in terms of maximum bit
+    rate. Setting the flag to 0 selects HEVC tier as Main tier and setting
+    this flag to 1 indicates High tier. High tier is for applications requiring
+    high bit rates.
+
+.. raw:: latex
+
+    \footnotesize
+
+.. tabularcolumns:: |p{9.0cm}|p{8.0cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_VIDEO_HEVC_TIER_MAIN``
+      - Main tier.
+    * - ``V4L2_MPEG_VIDEO_HEVC_TIER_HIGH``
+      - High tier.
+
+.. raw:: latex
+
+    \normalsize
+
+
+``V4L2_CID_MPEG_VIDEO_HEVC_MAX_PARTITION_DEPTH (integer)``
+    Selects HEVC maximum coding unit depth.
+
+.. _v4l2-hevc-loop-filter-mode:
+
+``V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE``
+    (enum)
+
+enum v4l2_mpeg_video_hevc_loop_filter_mode -
+    Loop filter mode for HEVC encoder. Possible values are:
+
+.. raw:: latex
+
+    \footnotesize
+
+.. tabularcolumns:: |p{12.1cm}|p{5.4cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_DISABLED``
+      - Loop filter is disabled.
+    * - ``V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_ENABLED``
+      - Loop filter is enabled.
+    * - ``V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY``
+      - Loop filter is disabled at the slice boundary.
+
+.. raw:: latex
+
+    \normalsize
+
+
+``V4L2_CID_MPEG_VIDEO_HEVC_LF_BETA_OFFSET_DIV2 (integer)``
+    Selects HEVC loop filter beta offset. The valid range is [-6, +6].
+
+``V4L2_CID_MPEG_VIDEO_HEVC_LF_TC_OFFSET_DIV2 (integer)``
+    Selects HEVC loop filter tc offset. The valid range is [-6, +6].
+
+.. _v4l2-hevc-refresh-type:
+
+``V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE``
+    (enum)
+
+enum v4l2_mpeg_video_hevc_hier_refresh_type -
+    Selects refresh type for HEVC encoder.
+    Host has to specify the period into
+    V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_PERIOD.
+
+.. raw:: latex
+
+    \footnotesize
+
+.. tabularcolumns:: |p{8.0cm}|p{9.0cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_VIDEO_HEVC_REFRESH_NONE``
+      - Use the B frame for hierarchical coding.
+    * - ``V4L2_MPEG_VIDEO_HEVC_REFRESH_CRA``
+      - Use CRA (Clean Random Access Unit) picture encoding.
+    * - ``V4L2_MPEG_VIDEO_HEVC_REFRESH_IDR``
+      - Use IDR (Instantaneous Decoding Refresh) picture encoding.
+
+.. raw:: latex
+
+    \normalsize
+
+
+``V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_PERIOD (integer)``
+    Selects the refresh period for HEVC encoder.
+    This specifies the number of I pictures between two CRA/IDR pictures.
+    This is valid only if REFRESH_TYPE is not 0.
+
+``V4L2_CID_MPEG_VIDEO_HEVC_LOSSLESS_CU (boolean)``
+    Indicates HEVC lossless encoding. Setting it to 0 disables lossless
+    encoding. Setting it to 1 enables lossless encoding.
+
+``V4L2_CID_MPEG_VIDEO_HEVC_CONST_INTRA_PRED (boolean)``
+    Indicates constant intra prediction for HEVC encoder. Specifies the
+    constrained intra prediction in which intra largest coding unit (LCU)
+    prediction is performed by using residual data and decoded samples of
+    neighboring intra LCU only. Setting the value to 1 enables constant intra
+    prediction and setting the value to 0 disables constant intra prediction.
+
+``V4L2_CID_MPEG_VIDEO_HEVC_WAVEFRONT (boolean)``
+    Indicates wavefront parallel processing for HEVC encoder. Setting it to 0
+    disables the feature and setting it to 1 enables the wavefront parallel
+    processing.
+
+``V4L2_CID_MPEG_VIDEO_HEVC_GENERAL_PB (boolean)``
+    Setting the value to 1 enables combination of P and B frame for HEVC
+    encoder.
+
+``V4L2_CID_MPEG_VIDEO_HEVC_TEMPORAL_ID (boolean)``
+    Indicates temporal identifier for HEVC encoder which is enabled by
+    setting the value to 1.
+
+``V4L2_CID_MPEG_VIDEO_HEVC_STRONG_SMOOTHING (boolean)``
+    Indicates bi-linear interpolation is conditionally used in the intra
+    prediction filtering process in the CVS when set to 1. Indicates bi-linear
+    interpolation is not used in the CVS when set to 0.
+
+``V4L2_CID_MPEG_VIDEO_HEVC_MAX_NUM_MERGE_MV_MINUS1 (integer)``
+    Indicates maximum number of merge candidate motion vectors.
+    Values are from 0 to 4.
+
+``V4L2_CID_MPEG_VIDEO_HEVC_TMV_PREDICTION (boolean)``
+    Indicates temporal motion vector prediction for HEVC encoder. Setting it to
+    1 enables the prediction. Setting it to 0 disables the prediction.
+
+``V4L2_CID_MPEG_VIDEO_HEVC_WITHOUT_STARTCODE (boolean)``
+    Specifies if HEVC generates a stream with a size of the length field
+    instead of start code pattern. The size of the length field is configurable
+    through the V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD control. Setting
+    the value to 0 disables encoding without startcode pattern. Setting the
+    value to 1 will enables encoding without startcode pattern.
+
+.. _v4l2-hevc-size-of-length-field:
+
+``V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD``
+(enum)
+
+enum v4l2_mpeg_video_hevc_size_of_length_field -
+    Indicates the size of length field.
+    This is valid when encoding WITHOUT_STARTCODE_ENABLE is enabled.
+
+.. raw:: latex
+
+    \footnotesize
+
+.. tabularcolumns:: |p{6.0cm}|p{11.0cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_MPEG_VIDEO_HEVC_SIZE_0``
+      - Generate start code pattern (Normal).
+    * - ``V4L2_MPEG_VIDEO_HEVC_SIZE_1``
+      - Generate size of length field instead of start code pattern and length is 1.
+    * - ``V4L2_MPEG_VIDEO_HEVC_SIZE_2``
+      - Generate size of length field instead of start code pattern and length is 2.
+    * - ``V4L2_MPEG_VIDEO_HEVC_SIZE_4``
+      - Generate size of length field instead of start code pattern and length is 4.
+
+.. raw:: latex
+
+    \normalsize
+
+``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_BR (integer)``
+    Indicates bit rate for hierarchical coding layer 0 for HEVC encoder.
+
+``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_BR (integer)``
+    Indicates bit rate for hierarchical coding layer 1 for HEVC encoder.
+
+``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_BR (integer)``
+    Indicates bit rate for hierarchical coding layer 2 for HEVC encoder.
+
+``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_BR (integer)``
+    Indicates bit rate for hierarchical coding layer 3 for HEVC encoder.
+
+``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_BR (integer)``
+    Indicates bit rate for hierarchical coding layer 4 for HEVC encoder.
+
+``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_BR (integer)``
+    Indicates bit rate for hierarchical coding layer 5 for HEVC encoder.
+
+``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_BR (integer)``
+    Indicates bit rate for hierarchical coding layer 6 for HEVC encoder.
+
+``V4L2_CID_MPEG_VIDEO_REF_NUMBER_FOR_PFRAMES (integer)``
+    Selects number of P reference pictures required for HEVC encoder.
+    P-Frame can use 1 or 2 frames for reference.
+
+``V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR (integer)``
+    Indicates whether to generate SPS and PPS at every IDR. Setting it to 0
+    disables generating SPS and PPS at every IDR. Setting it to one enables
+    generating SPS and PPS at every IDR.
+
+.. _v4l2-mpeg-hevc:
+
+``V4L2_CID_MPEG_VIDEO_HEVC_SPS (struct)``
+    Specifies the Sequence Parameter Set fields (as extracted from the
+    bitstream) for the associated HEVC slice data.
+    These bitstream parameters are defined according to :ref:`hevc`.
+    They are described in section 7.4.3.2 "Sequence parameter set RBSP
+    semantics" of the specification.
+
+.. c:type:: v4l2_ctrl_hevc_sps
+
+.. cssclass:: longtable
+
+.. flat-table:: struct v4l2_ctrl_hevc_sps
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u16
+      - ``pic_width_in_luma_samples``
+      -
+    * - __u16
+      - ``pic_height_in_luma_samples``
+      -
+    * - __u8
+      - ``bit_depth_luma_minus8``
+      -
+    * - __u8
+      - ``bit_depth_chroma_minus8``
+      -
+    * - __u8
+      - ``log2_max_pic_order_cnt_lsb_minus4``
+      -
+    * - __u8
+      - ``sps_max_dec_pic_buffering_minus1``
+      -
+    * - __u8
+      - ``sps_max_num_reorder_pics``
+      -
+    * - __u8
+      - ``sps_max_latency_increase_plus1``
+      -
+    * - __u8
+      - ``log2_min_luma_coding_block_size_minus3``
+      -
+    * - __u8
+      - ``log2_diff_max_min_luma_coding_block_size``
+      -
+    * - __u8
+      - ``log2_min_luma_transform_block_size_minus2``
+      -
+    * - __u8
+      - ``log2_diff_max_min_luma_transform_block_size``
+      -
+    * - __u8
+      - ``max_transform_hierarchy_depth_inter``
+      -
+    * - __u8
+      - ``max_transform_hierarchy_depth_intra``
+      -
+    * - __u8
+      - ``pcm_sample_bit_depth_luma_minus1``
+      -
+    * - __u8
+      - ``pcm_sample_bit_depth_chroma_minus1``
+      -
+    * - __u8
+      - ``log2_min_pcm_luma_coding_block_size_minus3``
+      -
+    * - __u8
+      - ``log2_diff_max_min_pcm_luma_coding_block_size``
+      -
+    * - __u8
+      - ``num_short_term_ref_pic_sets``
+      -
+    * - __u8
+      - ``num_long_term_ref_pics_sps``
+      -
+    * - __u8
+      - ``chroma_format_idc``
+      -
+    * - __u64
+      - ``flags``
+      - See :ref:`Sequence Parameter Set Flags <hevc_sps_flags>`
+
+.. _hevc_sps_flags:
+
+``Sequence Parameter Set Flags``
+
+.. cssclass:: longtable
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - ``V4L2_HEVC_SPS_FLAG_SEPARATE_COLOUR_PLANE``
+      - 0x00000001
+      -
+    * - ``V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED``
+      - 0x00000002
+      -
+    * - ``V4L2_HEVC_SPS_FLAG_AMP_ENABLED``
+      - 0x00000004
+      -
+    * - ``V4L2_HEVC_SPS_FLAG_SAMPLE_ADAPTIVE_OFFSET``
+      - 0x00000008
+      -
+    * - ``V4L2_HEVC_SPS_FLAG_PCM_ENABLED``
+      - 0x00000010
+      -
+    * - ``V4L2_HEVC_SPS_FLAG_PCM_LOOP_FILTER_DISABLED``
+      - 0x00000020
+      -
+    * - ``V4L2_HEVC_SPS_FLAG_LONG_TERM_REF_PICS_PRESENT``
+      - 0x00000040
+      -
+    * - ``V4L2_HEVC_SPS_FLAG_SPS_TEMPORAL_MVP_ENABLED``
+      - 0x00000080
+      -
+    * - ``V4L2_HEVC_SPS_FLAG_STRONG_INTRA_SMOOTHING_ENABLED``
+      - 0x00000100
+      -
+
+``V4L2_CID_MPEG_VIDEO_HEVC_PPS (struct)``
+    Specifies the Picture Parameter Set fields (as extracted from the
+    bitstream) for the associated HEVC slice data.
+    These bitstream parameters are defined according to :ref:`hevc`.
+    They are described in section 7.4.3.3 "Picture parameter set RBSP
+    semantics" of the specification.
+
+.. c:type:: v4l2_ctrl_hevc_pps
+
+.. cssclass:: longtable
+
+.. flat-table:: struct v4l2_ctrl_hevc_pps
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u8
+      - ``num_extra_slice_header_bits``
+      -
+    * - __s8
+      - ``init_qp_minus26``
+      -
+    * - __u8
+      - ``diff_cu_qp_delta_depth``
+      -
+    * - __s8
+      - ``pps_cb_qp_offset``
+      -
+    * - __s8
+      - ``pps_cr_qp_offset``
+      -
+    * - __u8
+      - ``num_tile_columns_minus1``
+      -
+    * - __u8
+      - ``num_tile_rows_minus1``
+      -
+    * - __u8
+      - ``column_width_minus1[20]``
+      -
+    * - __u8
+      - ``row_height_minus1[22]``
+      -
+    * - __s8
+      - ``pps_beta_offset_div2``
+      -
+    * - __s8
+      - ``pps_tc_offset_div2``
+      -
+    * - __u8
+      - ``log2_parallel_merge_level_minus2``
+      -
+    * - __u8
+      - ``padding[4]``
+      - Applications and drivers must set this to zero.
+    * - __u64
+      - ``flags``
+      - See :ref:`Picture Parameter Set Flags <hevc_pps_flags>`
+
+.. _hevc_pps_flags:
+
+``Picture Parameter Set Flags``
+
+.. cssclass:: longtable
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - ``V4L2_HEVC_PPS_FLAG_DEPENDENT_SLICE_SEGMENT``
+      - 0x00000001
+      -
+    * - ``V4L2_HEVC_PPS_FLAG_OUTPUT_FLAG_PRESENT``
+      - 0x00000002
+      -
+    * - ``V4L2_HEVC_PPS_FLAG_SIGN_DATA_HIDING_ENABLED``
+      - 0x00000004
+      -
+    * - ``V4L2_HEVC_PPS_FLAG_CABAC_INIT_PRESENT``
+      - 0x00000008
+      -
+    * - ``V4L2_HEVC_PPS_FLAG_CONSTRAINED_INTRA_PRED``
+      - 0x00000010
+      -
+    * - ``V4L2_HEVC_PPS_FLAG_TRANSFORM_SKIP_ENABLED``
+      - 0x00000020
+      -
+    * - ``V4L2_HEVC_PPS_FLAG_CU_QP_DELTA_ENABLED``
+      - 0x00000040
+      -
+    * - ``V4L2_HEVC_PPS_FLAG_PPS_SLICE_CHROMA_QP_OFFSETS_PRESENT``
+      - 0x00000080
+      -
+    * - ``V4L2_HEVC_PPS_FLAG_WEIGHTED_PRED``
+      - 0x00000100
+      -
+    * - ``V4L2_HEVC_PPS_FLAG_WEIGHTED_BIPRED``
+      - 0x00000200
+      -
+    * - ``V4L2_HEVC_PPS_FLAG_TRANSQUANT_BYPASS_ENABLED``
+      - 0x00000400
+      -
+    * - ``V4L2_HEVC_PPS_FLAG_TILES_ENABLED``
+      - 0x00000800
+      -
+    * - ``V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED``
+      - 0x00001000
+      -
+    * - ``V4L2_HEVC_PPS_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED``
+      - 0x00002000
+      -
+    * - ``V4L2_HEVC_PPS_FLAG_PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED``
+      - 0x00004000
+      -
+    * - ``V4L2_HEVC_PPS_FLAG_DEBLOCKING_FILTER_OVERRIDE_ENABLED``
+      - 0x00008000
+      -
+    * - ``V4L2_HEVC_PPS_FLAG_PPS_DISABLE_DEBLOCKING_FILTER``
+      - 0x00010000
+      -
+    * - ``V4L2_HEVC_PPS_FLAG_LISTS_MODIFICATION_PRESENT``
+      - 0x00020000
+      -
+    * - ``V4L2_HEVC_PPS_FLAG_SLICE_SEGMENT_HEADER_EXTENSION_PRESENT``
+      - 0x00040000
+      -
+
+``V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS (struct)``
+    Specifies various slice-specific parameters, especially from the NAL unit
+    header, general slice segment header and weighted prediction parameter
+    parts of the bitstream.
+    These bitstream parameters are defined according to :ref:`hevc`.
+    They are described in section 7.4.7 "General slice segment header
+    semantics" of the specification.
+
+.. c:type:: v4l2_ctrl_hevc_slice_params
+
+.. cssclass:: longtable
+
+.. flat-table:: struct v4l2_ctrl_hevc_slice_params
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``bit_size``
+      - Size (in bits) of the current slice data.
+    * - __u32
+      - ``data_bit_offset``
+      - Offset (in bits) to the video data in the current slice data.
+    * - __u8
+      - ``nal_unit_type``
+      -
+    * - __u8
+      - ``nuh_temporal_id_plus1``
+      -
+    * - __u8
+      - ``slice_type``
+      -
+	(V4L2_HEVC_SLICE_TYPE_I, V4L2_HEVC_SLICE_TYPE_P or
+	V4L2_HEVC_SLICE_TYPE_B).
+    * - __u8
+      - ``colour_plane_id``
+      -
+    * - __u16
+      - ``slice_pic_order_cnt``
+      -
+    * - __u8
+      - ``num_ref_idx_l0_active_minus1``
+      -
+    * - __u8
+      - ``num_ref_idx_l1_active_minus1``
+      -
+    * - __u8
+      - ``collocated_ref_idx``
+      -
+    * - __u8
+      - ``five_minus_max_num_merge_cand``
+      -
+    * - __s8
+      - ``slice_qp_delta``
+      -
+    * - __s8
+      - ``slice_cb_qp_offset``
+      -
+    * - __s8
+      - ``slice_cr_qp_offset``
+      -
+    * - __s8
+      - ``slice_act_y_qp_offset``
+      -
+    * - __s8
+      - ``slice_act_cb_qp_offset``
+      -
+    * - __s8
+      - ``slice_act_cr_qp_offset``
+      -
+    * - __s8
+      - ``slice_beta_offset_div2``
+      -
+    * - __s8
+      - ``slice_tc_offset_div2``
+      -
+    * - __u8
+      - ``pic_struct``
+      -
+    * - __u8
+      - ``num_active_dpb_entries``
+      - The number of entries in ``dpb``.
+    * - __u8
+      - ``ref_idx_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
+      - The list of L0 reference elements as indices in the DPB.
+    * - __u8
+      - ``ref_idx_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
+      - The list of L1 reference elements as indices in the DPB.
+    * - __u8
+      - ``num_rps_poc_st_curr_before``
+      - The number of reference pictures in the short-term set that come before
+        the current frame.
+    * - __u8
+      - ``num_rps_poc_st_curr_after``
+      - The number of reference pictures in the short-term set that come after
+        the current frame.
+    * - __u8
+      - ``num_rps_poc_lt_curr``
+      - The number of reference pictures in the long-term set.
+    * - __u8
+      - ``padding[7]``
+      - Applications and drivers must set this to zero.
+    * - struct :c:type:`v4l2_hevc_dpb_entry`
+      - ``dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
+      - The decoded picture buffer, for meta-data about reference frames.
+    * - struct :c:type:`v4l2_hevc_pred_weight_table`
+      - ``pred_weight_table``
+      - The prediction weight coefficients for inter-picture prediction.
+    * - __u64
+      - ``flags``
+      - See :ref:`Slice Parameters Flags <hevc_slice_params_flags>`
+
+.. _hevc_slice_params_flags:
+
+``Slice Parameters Flags``
+
+.. cssclass:: longtable
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - ``V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_SAO_LUMA``
+      - 0x00000001
+      -
+    * - ``V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_SAO_CHROMA``
+      - 0x00000002
+      -
+    * - ``V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_TEMPORAL_MVP_ENABLED``
+      - 0x00000004
+      -
+    * - ``V4L2_HEVC_SLICE_PARAMS_FLAG_MVD_L1_ZERO``
+      - 0x00000008
+      -
+    * - ``V4L2_HEVC_SLICE_PARAMS_FLAG_CABAC_INIT``
+      - 0x00000010
+      -
+    * - ``V4L2_HEVC_SLICE_PARAMS_FLAG_COLLOCATED_FROM_L0``
+      - 0x00000020
+      -
+    * - ``V4L2_HEVC_SLICE_PARAMS_FLAG_USE_INTEGER_MV``
+      - 0x00000040
+      -
+    * - ``V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_DEBLOCKING_FILTER_DISABLED``
+      - 0x00000080
+      -
+    * - ``V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED``
+      - 0x00000100
+      -
+
+.. c:type:: v4l2_hevc_dpb_entry
+
+.. cssclass:: longtable
+
+.. flat-table:: struct v4l2_hevc_dpb_entry
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u64
+      - ``timestamp``
+      - Timestamp of the V4L2 capture buffer to use as reference, used
+        with B-coded and P-coded frames. The timestamp refers to the
+	``timestamp`` field in struct :c:type:`v4l2_buffer`. Use the
+	:c:func:`v4l2_timeval_to_ns()` function to convert the struct
+	:c:type:`timeval` in struct :c:type:`v4l2_buffer` to a __u64.
+    * - __u8
+      - ``rps``
+      - The reference set for the reference frame
+        (V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_BEFORE,
+        V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_AFTER or
+        V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR)
+    * - __u8
+      - ``field_pic``
+      - Whether the reference is a field picture or a frame.
+    * - __u16
+      - ``pic_order_cnt[2]``
+      - The picture order count of the reference. Only the first element of the
+        array is used for frame pictures, while the first element identifies the
+        top field and the second the bottom field in field-coded pictures.
+    * - __u8
+      - ``padding[2]``
+      - Applications and drivers must set this to zero.
+
+.. c:type:: v4l2_hevc_pred_weight_table
+
+.. cssclass:: longtable
+
+.. flat-table:: struct v4l2_hevc_pred_weight_table
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u8
+      - ``luma_log2_weight_denom``
+      -
+    * - __s8
+      - ``delta_chroma_log2_weight_denom``
+      -
+    * - __s8
+      - ``delta_luma_weight_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
+      -
+    * - __s8
+      - ``luma_offset_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
+      -
+    * - __s8
+      - ``delta_chroma_weight_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2]``
+      -
+    * - __s8
+      - ``chroma_offset_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2]``
+      -
+    * - __s8
+      - ``delta_luma_weight_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
+      -
+    * - __s8
+      - ``luma_offset_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
+      -
+    * - __s8
+      - ``delta_chroma_weight_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2]``
+      -
+    * - __s8
+      - ``chroma_offset_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2]``
+      -
+    * - __u8
+      - ``padding[6]``
+      - Applications and drivers must set this to zero.
+
+``V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE (enum)``
+    Specifies the decoding mode to use. Currently exposes slice-based and
+    frame-based decoding but new modes might be added later on.
+    This control is used as a modifier for V4L2_PIX_FMT_HEVC_SLICE
+    pixel format. Applications that support V4L2_PIX_FMT_HEVC_SLICE
+    are required to set this control in order to specify the decoding mode
+    that is expected for the buffer.
+    Drivers may expose a single or multiple decoding modes, depending
+    on what they can support.
+
+    .. note::
+
+       This menu control is not yet part of the public kernel API and
+       it is expected to change.
+
+.. c:type:: v4l2_mpeg_video_hevc_decode_mode
+
+.. cssclass:: longtable
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - ``V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_SLICE_BASED``
+      - 0
+      - Decoding is done at the slice granularity.
+        The OUTPUT buffer must contain a single slice.
+    * - ``V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_FRAME_BASED``
+      - 1
+      - Decoding is done at the frame granularity.
+        The OUTPUT buffer must contain all slices needed to decode the
+        frame. The OUTPUT buffer must also contain both fields.
+
+``V4L2_CID_MPEG_VIDEO_HEVC_START_CODE (enum)``
+    Specifies the HEVC slice start code expected for each slice.
+    This control is used as a modifier for V4L2_PIX_FMT_HEVC_SLICE
+    pixel format. Applications that support V4L2_PIX_FMT_HEVC_SLICE
+    are required to set this control in order to specify the start code
+    that is expected for the buffer.
+    Drivers may expose a single or multiple start codes, depending
+    on what they can support.
+
+    .. note::
+
+       This menu control is not yet part of the public kernel API and
+       it is expected to change.
+
+.. c:type:: v4l2_mpeg_video_hevc_start_code
+
+.. cssclass:: longtable
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - ``V4L2_MPEG_VIDEO_HEVC_START_CODE_NONE``
+      - 0
+      - Selecting this value specifies that HEVC slices are passed
+        to the driver without any start code.
+    * - ``V4L2_MPEG_VIDEO_HEVC_START_CODE_ANNEX_B``
+      - 1
+      - Selecting this value specifies that HEVC slices are expected
+        to be prefixed by Annex B start codes. According to :ref:`hevc`
+        valid start codes can be 3-bytes 0x000001 or 4-bytes 0x00000001.
diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-detect.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-detect.rst
new file mode 100644
index 000000000000..77a4992f26bd
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-detect.rst
@@ -0,0 +1,71 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _detect-controls:
+
+************************
+Detect Control Reference
+************************
+
+The Detect class includes controls for common features of various motion
+or object detection capable devices.
+
+
+.. _detect-control-id:
+
+Detect Control IDs
+==================
+
+``V4L2_CID_DETECT_CLASS (class)``
+    The Detect class descriptor. Calling
+    :ref:`VIDIOC_QUERYCTRL` for this control will
+    return a description of this control class.
+
+``V4L2_CID_DETECT_MD_MODE (menu)``
+    Sets the motion detection mode.
+
+.. tabularcolumns:: |p{7.7cm}|p{9.8cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_DETECT_MD_MODE_DISABLED``
+      - Disable motion detection.
+    * - ``V4L2_DETECT_MD_MODE_GLOBAL``
+      - Use a single motion detection threshold.
+    * - ``V4L2_DETECT_MD_MODE_THRESHOLD_GRID``
+      - The image is divided into a grid, each cell with its own motion
+	detection threshold. These thresholds are set through the
+	``V4L2_CID_DETECT_MD_THRESHOLD_GRID`` matrix control.
+    * - ``V4L2_DETECT_MD_MODE_REGION_GRID``
+      - The image is divided into a grid, each cell with its own region
+	value that specifies which per-region motion detection thresholds
+	should be used. Each region has its own thresholds. How these
+	per-region thresholds are set up is driver-specific. The region
+	values for the grid are set through the
+	``V4L2_CID_DETECT_MD_REGION_GRID`` matrix control.
+
+
+
+``V4L2_CID_DETECT_MD_GLOBAL_THRESHOLD (integer)``
+    Sets the global motion detection threshold to be used with the
+    ``V4L2_DETECT_MD_MODE_GLOBAL`` motion detection mode.
+
+``V4L2_CID_DETECT_MD_THRESHOLD_GRID (__u16 matrix)``
+    Sets the motion detection thresholds for each cell in the grid. To
+    be used with the ``V4L2_DETECT_MD_MODE_THRESHOLD_GRID`` motion
+    detection mode. Matrix element (0, 0) represents the cell at the
+    top-left of the grid.
+
+``V4L2_CID_DETECT_MD_REGION_GRID (__u8 matrix)``
+    Sets the motion detection region value for each cell in the grid. To
+    be used with the ``V4L2_DETECT_MD_MODE_REGION_GRID`` motion
+    detection mode. Matrix element (0, 0) represents the cell at the
+    top-left of the grid.
diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-dv.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-dv.rst
new file mode 100644
index 000000000000..c572b65dc772
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-dv.rst
@@ -0,0 +1,166 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _dv-controls:
+
+*******************************
+Digital Video Control Reference
+*******************************
+
+The Digital Video control class is intended to control receivers and
+transmitters for `VGA <http://en.wikipedia.org/wiki/Vga>`__,
+`DVI <http://en.wikipedia.org/wiki/Digital_Visual_Interface>`__
+(Digital Visual Interface), HDMI (:ref:`hdmi`) and DisplayPort
+(:ref:`dp`). These controls are generally expected to be private to
+the receiver or transmitter subdevice that implements them, so they are
+only exposed on the ``/dev/v4l-subdev*`` device node.
+
+.. note::
+
+   Note that these devices can have multiple input or output pads which are
+   hooked up to e.g. HDMI connectors. Even though the subdevice will
+   receive or transmit video from/to only one of those pads, the other pads
+   can still be active when it comes to EDID (Extended Display
+   Identification Data, :ref:`vesaedid`) and HDCP (High-bandwidth Digital
+   Content Protection System, :ref:`hdcp`) processing, allowing the
+   device to do the fairly slow EDID/HDCP handling in advance. This allows
+   for quick switching between connectors.
+
+These pads appear in several of the controls in this section as
+bitmasks, one bit for each pad. Bit 0 corresponds to pad 0, bit 1 to pad
+1, etc. The maximum value of the control is the set of valid pads.
+
+
+.. _dv-control-id:
+
+Digital Video Control IDs
+=========================
+
+``V4L2_CID_DV_CLASS (class)``
+    The Digital Video class descriptor.
+
+``V4L2_CID_DV_TX_HOTPLUG (bitmask)``
+    Many connectors have a hotplug pin which is high if EDID information
+    is available from the source. This control shows the state of the
+    hotplug pin as seen by the transmitter. Each bit corresponds to an
+    output pad on the transmitter. If an output pad does not have an
+    associated hotplug pin, then the bit for that pad will be 0. This
+    read-only control is applicable to DVI-D, HDMI and DisplayPort
+    connectors.
+
+``V4L2_CID_DV_TX_RXSENSE (bitmask)``
+    Rx Sense is the detection of pull-ups on the TMDS clock lines. This
+    normally means that the sink has left/entered standby (i.e. the
+    transmitter can sense that the receiver is ready to receive video).
+    Each bit corresponds to an output pad on the transmitter. If an
+    output pad does not have an associated Rx Sense, then the bit for
+    that pad will be 0. This read-only control is applicable to DVI-D
+    and HDMI devices.
+
+``V4L2_CID_DV_TX_EDID_PRESENT (bitmask)``
+    When the transmitter sees the hotplug signal from the receiver it
+    will attempt to read the EDID. If set, then the transmitter has read
+    at least the first block (= 128 bytes). Each bit corresponds to an
+    output pad on the transmitter. If an output pad does not support
+    EDIDs, then the bit for that pad will be 0. This read-only control
+    is applicable to VGA, DVI-A/D, HDMI and DisplayPort connectors.
+
+``V4L2_CID_DV_TX_MODE``
+    (enum)
+
+enum v4l2_dv_tx_mode -
+    HDMI transmitters can transmit in DVI-D mode (just video) or in HDMI
+    mode (video + audio + auxiliary data). This control selects which
+    mode to use: V4L2_DV_TX_MODE_DVI_D or V4L2_DV_TX_MODE_HDMI.
+    This control is applicable to HDMI connectors.
+
+``V4L2_CID_DV_TX_RGB_RANGE``
+    (enum)
+
+enum v4l2_dv_rgb_range -
+    Select the quantization range for RGB output. V4L2_DV_RANGE_AUTO
+    follows the RGB quantization range specified in the standard for the
+    video interface (ie. :ref:`cea861` for HDMI).
+    V4L2_DV_RANGE_LIMITED and V4L2_DV_RANGE_FULL override the
+    standard to be compatible with sinks that have not implemented the
+    standard correctly (unfortunately quite common for HDMI and DVI-D).
+    Full range allows all possible values to be used whereas limited
+    range sets the range to (16 << (N-8)) - (235 << (N-8)) where N is
+    the number of bits per component. This control is applicable to VGA,
+    DVI-A/D, HDMI and DisplayPort connectors.
+
+``V4L2_CID_DV_TX_IT_CONTENT_TYPE``
+    (enum)
+
+enum v4l2_dv_it_content_type -
+    Configures the IT Content Type of the transmitted video. This
+    information is sent over HDMI and DisplayPort connectors as part of
+    the AVI InfoFrame. The term 'IT Content' is used for content that
+    originates from a computer as opposed to content from a TV broadcast
+    or an analog source. The enum v4l2_dv_it_content_type defines
+    the possible content types:
+
+.. tabularcolumns:: |p{7.3cm}|p{10.4cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_DV_IT_CONTENT_TYPE_GRAPHICS``
+      - Graphics content. Pixel data should be passed unfiltered and
+	without analog reconstruction.
+    * - ``V4L2_DV_IT_CONTENT_TYPE_PHOTO``
+      - Photo content. The content is derived from digital still pictures.
+	The content should be passed through with minimal scaling and
+	picture enhancements.
+    * - ``V4L2_DV_IT_CONTENT_TYPE_CINEMA``
+      - Cinema content.
+    * - ``V4L2_DV_IT_CONTENT_TYPE_GAME``
+      - Game content. Audio and video latency should be minimized.
+    * - ``V4L2_DV_IT_CONTENT_TYPE_NO_ITC``
+      - No IT Content information is available and the ITC bit in the AVI
+	InfoFrame is set to 0.
+
+
+
+``V4L2_CID_DV_RX_POWER_PRESENT (bitmask)``
+    Detects whether the receiver receives power from the source (e.g.
+    HDMI carries 5V on one of the pins). This is often used to power an
+    eeprom which contains EDID information, such that the source can
+    read the EDID even if the sink is in standby/power off. Each bit
+    corresponds to an input pad on the receiver. If an input pad
+    cannot detect whether power is present, then the bit for that pad
+    will be 0. This read-only control is applicable to DVI-D, HDMI and
+    DisplayPort connectors.
+
+``V4L2_CID_DV_RX_RGB_RANGE``
+    (enum)
+
+enum v4l2_dv_rgb_range -
+    Select the quantization range for RGB input. V4L2_DV_RANGE_AUTO
+    follows the RGB quantization range specified in the standard for the
+    video interface (ie. :ref:`cea861` for HDMI).
+    V4L2_DV_RANGE_LIMITED and V4L2_DV_RANGE_FULL override the
+    standard to be compatible with sources that have not implemented the
+    standard correctly (unfortunately quite common for HDMI and DVI-D).
+    Full range allows all possible values to be used whereas limited
+    range sets the range to (16 << (N-8)) - (235 << (N-8)) where N is
+    the number of bits per component. This control is applicable to VGA,
+    DVI-A/D, HDMI and DisplayPort connectors.
+
+``V4L2_CID_DV_RX_IT_CONTENT_TYPE``
+    (enum)
+
+enum v4l2_dv_it_content_type -
+    Reads the IT Content Type of the received video. This information is
+    sent over HDMI and DisplayPort connectors as part of the AVI
+    InfoFrame. The term 'IT Content' is used for content that originates
+    from a computer as opposed to content from a TV broadcast or an
+    analog source. See ``V4L2_CID_DV_TX_IT_CONTENT_TYPE`` for the
+    available content types.
diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-flash.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-flash.rst
new file mode 100644
index 000000000000..5053a380f7de
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-flash.rst
@@ -0,0 +1,192 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _flash-controls:
+
+***********************
+Flash Control Reference
+***********************
+
+The V4L2 flash controls are intended to provide generic access to flash
+controller devices. Flash controller devices are typically used in
+digital cameras.
+
+The interface can support both LED and xenon flash devices. As of
+writing this, there is no xenon flash driver using this interface.
+
+
+.. _flash-controls-use-cases:
+
+Supported use cases
+===================
+
+
+Unsynchronised LED flash (software strobe)
+------------------------------------------
+
+Unsynchronised LED flash is controlled directly by the host as the
+sensor. The flash must be enabled by the host before the exposure of the
+image starts and disabled once it ends. The host is fully responsible
+for the timing of the flash.
+
+Example of such device: Nokia N900.
+
+
+Synchronised LED flash (hardware strobe)
+----------------------------------------
+
+The synchronised LED flash is pre-programmed by the host (power and
+timeout) but controlled by the sensor through a strobe signal from the
+sensor to the flash.
+
+The sensor controls the flash duration and timing. This information
+typically must be made available to the sensor.
+
+
+LED flash as torch
+------------------
+
+LED flash may be used as torch in conjunction with another use case
+involving camera or individually.
+
+
+.. _flash-control-id:
+
+Flash Control IDs
+-----------------
+
+``V4L2_CID_FLASH_CLASS (class)``
+    The FLASH class descriptor.
+
+``V4L2_CID_FLASH_LED_MODE (menu)``
+    Defines the mode of the flash LED, the high-power white LED attached
+    to the flash controller. Setting this control may not be possible in
+    presence of some faults. See V4L2_CID_FLASH_FAULT.
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_FLASH_LED_MODE_NONE``
+      - Off.
+    * - ``V4L2_FLASH_LED_MODE_FLASH``
+      - Flash mode.
+    * - ``V4L2_FLASH_LED_MODE_TORCH``
+      - Torch mode. See V4L2_CID_FLASH_TORCH_INTENSITY.
+
+
+
+``V4L2_CID_FLASH_STROBE_SOURCE (menu)``
+    Defines the source of the flash LED strobe.
+
+.. tabularcolumns:: |p{7.5cm}|p{10.0cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_FLASH_STROBE_SOURCE_SOFTWARE``
+      - The flash strobe is triggered by using the
+	V4L2_CID_FLASH_STROBE control.
+    * - ``V4L2_FLASH_STROBE_SOURCE_EXTERNAL``
+      - The flash strobe is triggered by an external source. Typically
+	this is a sensor, which makes it possible to synchronise the
+	flash strobe start to exposure start.
+
+
+
+``V4L2_CID_FLASH_STROBE (button)``
+    Strobe flash. Valid when V4L2_CID_FLASH_LED_MODE is set to
+    V4L2_FLASH_LED_MODE_FLASH and V4L2_CID_FLASH_STROBE_SOURCE
+    is set to V4L2_FLASH_STROBE_SOURCE_SOFTWARE. Setting this
+    control may not be possible in presence of some faults. See
+    V4L2_CID_FLASH_FAULT.
+
+``V4L2_CID_FLASH_STROBE_STOP (button)``
+    Stop flash strobe immediately.
+
+``V4L2_CID_FLASH_STROBE_STATUS (boolean)``
+    Strobe status: whether the flash is strobing at the moment or not.
+    This is a read-only control.
+
+``V4L2_CID_FLASH_TIMEOUT (integer)``
+    Hardware timeout for flash. The flash strobe is stopped after this
+    period of time has passed from the start of the strobe.
+
+``V4L2_CID_FLASH_INTENSITY (integer)``
+    Intensity of the flash strobe when the flash LED is in flash mode
+    (V4L2_FLASH_LED_MODE_FLASH). The unit should be milliamps (mA)
+    if possible.
+
+``V4L2_CID_FLASH_TORCH_INTENSITY (integer)``
+    Intensity of the flash LED in torch mode
+    (V4L2_FLASH_LED_MODE_TORCH). The unit should be milliamps (mA)
+    if possible. Setting this control may not be possible in presence of
+    some faults. See V4L2_CID_FLASH_FAULT.
+
+``V4L2_CID_FLASH_INDICATOR_INTENSITY (integer)``
+    Intensity of the indicator LED. The indicator LED may be fully
+    independent of the flash LED. The unit should be microamps (uA) if
+    possible.
+
+``V4L2_CID_FLASH_FAULT (bitmask)``
+    Faults related to the flash. The faults tell about specific problems
+    in the flash chip itself or the LEDs attached to it. Faults may
+    prevent further use of some of the flash controls. In particular,
+    V4L2_CID_FLASH_LED_MODE is set to V4L2_FLASH_LED_MODE_NONE
+    if the fault affects the flash LED. Exactly which faults have such
+    an effect is chip dependent. Reading the faults resets the control
+    and returns the chip to a usable state if possible.
+
+.. tabularcolumns:: |p{8.4cm}|p{9.1cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_FLASH_FAULT_OVER_VOLTAGE``
+      - Flash controller voltage to the flash LED has exceeded the limit
+	specific to the flash controller.
+    * - ``V4L2_FLASH_FAULT_TIMEOUT``
+      - The flash strobe was still on when the timeout set by the user ---
+	V4L2_CID_FLASH_TIMEOUT control --- has expired. Not all flash
+	controllers may set this in all such conditions.
+    * - ``V4L2_FLASH_FAULT_OVER_TEMPERATURE``
+      - The flash controller has overheated.
+    * - ``V4L2_FLASH_FAULT_SHORT_CIRCUIT``
+      - The short circuit protection of the flash controller has been
+	triggered.
+    * - ``V4L2_FLASH_FAULT_OVER_CURRENT``
+      - Current in the LED power supply has exceeded the limit specific to
+	the flash controller.
+    * - ``V4L2_FLASH_FAULT_INDICATOR``
+      - The flash controller has detected a short or open circuit
+	condition on the indicator LED.
+    * - ``V4L2_FLASH_FAULT_UNDER_VOLTAGE``
+      - Flash controller voltage to the flash LED has been below the
+	minimum limit specific to the flash controller.
+    * - ``V4L2_FLASH_FAULT_INPUT_VOLTAGE``
+      - The input voltage of the flash controller is below the limit under
+	which strobing the flash at full current will not be possible.The
+	condition persists until this flag is no longer set.
+    * - ``V4L2_FLASH_FAULT_LED_OVER_TEMPERATURE``
+      - The temperature of the LED has exceeded its allowed upper limit.
+
+
+
+``V4L2_CID_FLASH_CHARGE (boolean)``
+    Enable or disable charging of the xenon flash capacitor.
+
+``V4L2_CID_FLASH_READY (boolean)``
+    Is the flash ready to strobe? Xenon flashes require their capacitors
+    charged before strobing. LED flashes often require a cooldown period
+    after strobe during which another strobe will not be possible. This
+    is a read-only control.
diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-fm-rx.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-fm-rx.rst
new file mode 100644
index 000000000000..69197bbe23dd
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-fm-rx.rst
@@ -0,0 +1,95 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _fm-rx-controls:
+
+*****************************
+FM Receiver Control Reference
+*****************************
+
+The FM Receiver (FM_RX) class includes controls for common features of
+FM Reception capable devices.
+
+
+.. _fm-rx-control-id:
+
+FM_RX Control IDs
+=================
+
+``V4L2_CID_FM_RX_CLASS (class)``
+    The FM_RX class descriptor. Calling
+    :ref:`VIDIOC_QUERYCTRL` for this control will
+    return a description of this control class.
+
+``V4L2_CID_RDS_RECEPTION (boolean)``
+    Enables/disables RDS reception by the radio tuner
+
+``V4L2_CID_RDS_RX_PTY (integer)``
+    Gets RDS Programme Type field. This encodes up to 31 pre-defined
+    programme types.
+
+``V4L2_CID_RDS_RX_PS_NAME (string)``
+    Gets the Programme Service name (PS_NAME). It is intended for
+    static display on a receiver. It is the primary aid to listeners in
+    programme service identification and selection. In Annex E of
+    :ref:`iec62106`, the RDS specification, there is a full
+    description of the correct character encoding for Programme Service
+    name strings. Also from RDS specification, PS is usually a single
+    eight character text. However, it is also possible to find receivers
+    which can scroll strings sized as 8 x N characters. So, this control
+    must be configured with steps of 8 characters. The result is it must
+    always contain a string with size multiple of 8.
+
+``V4L2_CID_RDS_RX_RADIO_TEXT (string)``
+    Gets the Radio Text info. It is a textual description of what is
+    being broadcasted. RDS Radio Text can be applied when broadcaster
+    wishes to transmit longer PS names, programme-related information or
+    any other text. In these cases, RadioText can be used in addition to
+    ``V4L2_CID_RDS_RX_PS_NAME``. The encoding for Radio Text strings is
+    also fully described in Annex E of :ref:`iec62106`. The length of
+    Radio Text strings depends on which RDS Block is being used to
+    transmit it, either 32 (2A block) or 64 (2B block). However, it is
+    also possible to find receivers which can scroll strings sized as 32
+    x N or 64 x N characters. So, this control must be configured with
+    steps of 32 or 64 characters. The result is it must always contain a
+    string with size multiple of 32 or 64.
+
+``V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT (boolean)``
+    If set, then a traffic announcement is in progress.
+
+``V4L2_CID_RDS_RX_TRAFFIC_PROGRAM (boolean)``
+    If set, then the tuned programme carries traffic announcements.
+
+``V4L2_CID_RDS_RX_MUSIC_SPEECH (boolean)``
+    If set, then this channel broadcasts music. If cleared, then it
+    broadcasts speech. If the transmitter doesn't make this distinction,
+    then it will be set.
+
+``V4L2_CID_TUNE_DEEMPHASIS``
+    (enum)
+
+enum v4l2_deemphasis -
+    Configures the de-emphasis value for reception. A de-emphasis filter
+    is applied to the broadcast to accentuate the high audio
+    frequencies. Depending on the region, a time constant of either 50
+    or 75 useconds is used. The enum v4l2_deemphasis defines possible
+    values for de-emphasis. Here they are:
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_DEEMPHASIS_DISABLED``
+      - No de-emphasis is applied.
+    * - ``V4L2_DEEMPHASIS_50_uS``
+      - A de-emphasis of 50 uS is used.
+    * - ``V4L2_DEEMPHASIS_75_uS``
+      - A de-emphasis of 75 uS is used.
diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-fm-tx.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-fm-tx.rst
new file mode 100644
index 000000000000..c13ec0a6af3a
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-fm-tx.rst
@@ -0,0 +1,188 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _fm-tx-controls:
+
+********************************
+FM Transmitter Control Reference
+********************************
+
+The FM Transmitter (FM_TX) class includes controls for common features
+of FM transmissions capable devices. Currently this class includes
+parameters for audio compression, pilot tone generation, audio deviation
+limiter, RDS transmission and tuning power features.
+
+
+.. _fm-tx-control-id:
+
+FM_TX Control IDs
+=================
+
+``V4L2_CID_FM_TX_CLASS (class)``
+    The FM_TX class descriptor. Calling
+    :ref:`VIDIOC_QUERYCTRL` for this control will
+    return a description of this control class.
+
+``V4L2_CID_RDS_TX_DEVIATION (integer)``
+    Configures RDS signal frequency deviation level in Hz. The range and
+    step are driver-specific.
+
+``V4L2_CID_RDS_TX_PI (integer)``
+    Sets the RDS Programme Identification field for transmission.
+
+``V4L2_CID_RDS_TX_PTY (integer)``
+    Sets the RDS Programme Type field for transmission. This encodes up
+    to 31 pre-defined programme types.
+
+``V4L2_CID_RDS_TX_PS_NAME (string)``
+    Sets the Programme Service name (PS_NAME) for transmission. It is
+    intended for static display on a receiver. It is the primary aid to
+    listeners in programme service identification and selection. In
+    Annex E of :ref:`iec62106`, the RDS specification, there is a full
+    description of the correct character encoding for Programme Service
+    name strings. Also from RDS specification, PS is usually a single
+    eight character text. However, it is also possible to find receivers
+    which can scroll strings sized as 8 x N characters. So, this control
+    must be configured with steps of 8 characters. The result is it must
+    always contain a string with size multiple of 8.
+
+``V4L2_CID_RDS_TX_RADIO_TEXT (string)``
+    Sets the Radio Text info for transmission. It is a textual
+    description of what is being broadcasted. RDS Radio Text can be
+    applied when broadcaster wishes to transmit longer PS names,
+    programme-related information or any other text. In these cases,
+    RadioText should be used in addition to ``V4L2_CID_RDS_TX_PS_NAME``.
+    The encoding for Radio Text strings is also fully described in Annex
+    E of :ref:`iec62106`. The length of Radio Text strings depends on
+    which RDS Block is being used to transmit it, either 32 (2A block)
+    or 64 (2B block). However, it is also possible to find receivers
+    which can scroll strings sized as 32 x N or 64 x N characters. So,
+    this control must be configured with steps of 32 or 64 characters.
+    The result is it must always contain a string with size multiple of
+    32 or 64.
+
+``V4L2_CID_RDS_TX_MONO_STEREO (boolean)``
+    Sets the Mono/Stereo bit of the Decoder Identification code. If set,
+    then the audio was recorded as stereo.
+
+``V4L2_CID_RDS_TX_ARTIFICIAL_HEAD (boolean)``
+    Sets the
+    `Artificial Head <http://en.wikipedia.org/wiki/Artificial_head>`__
+    bit of the Decoder Identification code. If set, then the audio was
+    recorded using an artificial head.
+
+``V4L2_CID_RDS_TX_COMPRESSED (boolean)``
+    Sets the Compressed bit of the Decoder Identification code. If set,
+    then the audio is compressed.
+
+``V4L2_CID_RDS_TX_DYNAMIC_PTY (boolean)``
+    Sets the Dynamic PTY bit of the Decoder Identification code. If set,
+    then the PTY code is dynamically switched.
+
+``V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT (boolean)``
+    If set, then a traffic announcement is in progress.
+
+``V4L2_CID_RDS_TX_TRAFFIC_PROGRAM (boolean)``
+    If set, then the tuned programme carries traffic announcements.
+
+``V4L2_CID_RDS_TX_MUSIC_SPEECH (boolean)``
+    If set, then this channel broadcasts music. If cleared, then it
+    broadcasts speech. If the transmitter doesn't make this distinction,
+    then it should be set.
+
+``V4L2_CID_RDS_TX_ALT_FREQS_ENABLE (boolean)``
+    If set, then transmit alternate frequencies.
+
+``V4L2_CID_RDS_TX_ALT_FREQS (__u32 array)``
+    The alternate frequencies in kHz units. The RDS standard allows for
+    up to 25 frequencies to be defined. Drivers may support fewer
+    frequencies so check the array size.
+
+``V4L2_CID_AUDIO_LIMITER_ENABLED (boolean)``
+    Enables or disables the audio deviation limiter feature. The limiter
+    is useful when trying to maximize the audio volume, minimize
+    receiver-generated distortion and prevent overmodulation.
+
+``V4L2_CID_AUDIO_LIMITER_RELEASE_TIME (integer)``
+    Sets the audio deviation limiter feature release time. Unit is in
+    useconds. Step and range are driver-specific.
+
+``V4L2_CID_AUDIO_LIMITER_DEVIATION (integer)``
+    Configures audio frequency deviation level in Hz. The range and step
+    are driver-specific.
+
+``V4L2_CID_AUDIO_COMPRESSION_ENABLED (boolean)``
+    Enables or disables the audio compression feature. This feature
+    amplifies signals below the threshold by a fixed gain and compresses
+    audio signals above the threshold by the ratio of Threshold/(Gain +
+    Threshold).
+
+``V4L2_CID_AUDIO_COMPRESSION_GAIN (integer)``
+    Sets the gain for audio compression feature. It is a dB value. The
+    range and step are driver-specific.
+
+``V4L2_CID_AUDIO_COMPRESSION_THRESHOLD (integer)``
+    Sets the threshold level for audio compression freature. It is a dB
+    value. The range and step are driver-specific.
+
+``V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME (integer)``
+    Sets the attack time for audio compression feature. It is a useconds
+    value. The range and step are driver-specific.
+
+``V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME (integer)``
+    Sets the release time for audio compression feature. It is a
+    useconds value. The range and step are driver-specific.
+
+``V4L2_CID_PILOT_TONE_ENABLED (boolean)``
+    Enables or disables the pilot tone generation feature.
+
+``V4L2_CID_PILOT_TONE_DEVIATION (integer)``
+    Configures pilot tone frequency deviation level. Unit is in Hz. The
+    range and step are driver-specific.
+
+``V4L2_CID_PILOT_TONE_FREQUENCY (integer)``
+    Configures pilot tone frequency value. Unit is in Hz. The range and
+    step are driver-specific.
+
+``V4L2_CID_TUNE_PREEMPHASIS``
+    (enum)
+
+enum v4l2_preemphasis -
+    Configures the pre-emphasis value for broadcasting. A pre-emphasis
+    filter is applied to the broadcast to accentuate the high audio
+    frequencies. Depending on the region, a time constant of either 50
+    or 75 useconds is used. The enum v4l2_preemphasis defines possible
+    values for pre-emphasis. Here they are:
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_PREEMPHASIS_DISABLED``
+      - No pre-emphasis is applied.
+    * - ``V4L2_PREEMPHASIS_50_uS``
+      - A pre-emphasis of 50 uS is used.
+    * - ``V4L2_PREEMPHASIS_75_uS``
+      - A pre-emphasis of 75 uS is used.
+
+
+
+``V4L2_CID_TUNE_POWER_LEVEL (integer)``
+    Sets the output power level for signal transmission. Unit is in
+    dBuV. Range and step are driver-specific.
+
+``V4L2_CID_TUNE_ANTENNA_CAPACITOR (integer)``
+    This selects the value of antenna tuning capacitor manually or
+    automatically if set to zero. Unit, range and step are
+    driver-specific.
+
+For more details about RDS specification, refer to :ref:`iec62106`
+document, from CENELEC.
diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-image-process.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-image-process.rst
new file mode 100644
index 000000000000..bb9d484c25e4
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-image-process.rst
@@ -0,0 +1,63 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _image-process-controls:
+
+*******************************
+Image Process Control Reference
+*******************************
+
+The Image Process control class is intended for low-level control of
+image processing functions. Unlike ``V4L2_CID_IMAGE_SOURCE_CLASS``, the
+controls in this class affect processing the image, and do not control
+capturing of it.
+
+
+.. _image-process-control-id:
+
+Image Process Control IDs
+=========================
+
+``V4L2_CID_IMAGE_PROC_CLASS (class)``
+    The IMAGE_PROC class descriptor.
+
+``V4L2_CID_LINK_FREQ (integer menu)``
+    Data bus frequency. Together with the media bus pixel code, bus type
+    (clock cycles per sample), the data bus frequency defines the pixel
+    rate (``V4L2_CID_PIXEL_RATE``) in the pixel array (or possibly
+    elsewhere, if the device is not an image sensor). The frame rate can
+    be calculated from the pixel clock, image width and height and
+    horizontal and vertical blanking. While the pixel rate control may
+    be defined elsewhere than in the subdev containing the pixel array,
+    the frame rate cannot be obtained from that information. This is
+    because only on the pixel array it can be assumed that the vertical
+    and horizontal blanking information is exact: no other blanking is
+    allowed in the pixel array. The selection of frame rate is performed
+    by selecting the desired horizontal and vertical blanking. The unit
+    of this control is Hz.
+
+``V4L2_CID_PIXEL_RATE (64-bit integer)``
+    Pixel rate in the source pads of the subdev. This control is
+    read-only and its unit is pixels / second.
+
+``V4L2_CID_TEST_PATTERN (menu)``
+    Some capture/display/sensor devices have the capability to generate
+    test pattern images. These hardware specific test patterns can be
+    used to test if a device is working properly.
+
+``V4L2_CID_DEINTERLACING_MODE (menu)``
+    The video deinterlacing mode (such as Bob, Weave, ...). The menu items are
+    driver specific and are documented in :ref:`uapi-v4l-drivers`.
+
+``V4L2_CID_DIGITAL_GAIN (integer)``
+    Digital gain is the value by which all colour components
+    are multiplied by. Typically the digital gain applied is the
+    control value divided by e.g. 0x100, meaning that to get no
+    digital gain the control value needs to be 0x100. The no-gain
+    configuration is also typically the default.
diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-image-source.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-image-source.rst
new file mode 100644
index 000000000000..7b75158aca4d
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-image-source.rst
@@ -0,0 +1,67 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _image-source-controls:
+
+******************************
+Image Source Control Reference
+******************************
+
+The Image Source control class is intended for low-level control of
+image source devices such as image sensors. The devices feature an
+analogue to digital converter and a bus transmitter to transmit the
+image data out of the device.
+
+
+.. _image-source-control-id:
+
+Image Source Control IDs
+========================
+
+``V4L2_CID_IMAGE_SOURCE_CLASS (class)``
+    The IMAGE_SOURCE class descriptor.
+
+``V4L2_CID_VBLANK (integer)``
+    Vertical blanking. The idle period after every frame during which no
+    image data is produced. The unit of vertical blanking is a line.
+    Every line has length of the image width plus horizontal blanking at
+    the pixel rate defined by ``V4L2_CID_PIXEL_RATE`` control in the
+    same sub-device.
+
+``V4L2_CID_HBLANK (integer)``
+    Horizontal blanking. The idle period after every line of image data
+    during which no image data is produced. The unit of horizontal
+    blanking is pixels.
+
+``V4L2_CID_ANALOGUE_GAIN (integer)``
+    Analogue gain is gain affecting all colour components in the pixel
+    matrix. The gain operation is performed in the analogue domain
+    before A/D conversion.
+
+``V4L2_CID_TEST_PATTERN_RED (integer)``
+    Test pattern red colour component.
+
+``V4L2_CID_TEST_PATTERN_GREENR (integer)``
+    Test pattern green (next to red) colour component.
+
+``V4L2_CID_TEST_PATTERN_BLUE (integer)``
+    Test pattern blue colour component.
+
+``V4L2_CID_TEST_PATTERN_GREENB (integer)``
+    Test pattern green (next to blue) colour component.
+
+``V4L2_CID_UNIT_CELL_SIZE (struct)``
+    This control returns the unit cell size in nanometers. The struct
+    :c:type:`v4l2_area` provides the width and the height in separate
+    fields to take into consideration asymmetric pixels.
+    This control does not take into consideration any possible hardware
+    binning.
+    The unit cell consists of the whole area of the pixel, sensitive and
+    non-sensitive.
+    This control is required for automatic calibration of sensors/cameras.
diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-jpeg.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-jpeg.rst
new file mode 100644
index 000000000000..5ea69978f3ea
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-jpeg.rst
@@ -0,0 +1,113 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _jpeg-controls:
+
+**********************
+JPEG Control Reference
+**********************
+
+The JPEG class includes controls for common features of JPEG encoders
+and decoders. Currently it includes features for codecs implementing
+progressive baseline DCT compression process with Huffman entrophy
+coding.
+
+
+.. _jpeg-control-id:
+
+JPEG Control IDs
+================
+
+``V4L2_CID_JPEG_CLASS (class)``
+    The JPEG class descriptor. Calling
+    :ref:`VIDIOC_QUERYCTRL` for this control will
+    return a description of this control class.
+
+``V4L2_CID_JPEG_CHROMA_SUBSAMPLING (menu)``
+    The chroma subsampling factors describe how each component of an
+    input image is sampled, in respect to maximum sample rate in each
+    spatial dimension. See :ref:`itu-t81`, clause A.1.1. for more
+    details. The ``V4L2_CID_JPEG_CHROMA_SUBSAMPLING`` control determines
+    how Cb and Cr components are downsampled after converting an input
+    image from RGB to Y'CbCr color space.
+
+.. tabularcolumns:: |p{7.5cm}|p{10.0cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_JPEG_CHROMA_SUBSAMPLING_444``
+      - No chroma subsampling, each pixel has Y, Cr and Cb values.
+    * - ``V4L2_JPEG_CHROMA_SUBSAMPLING_422``
+      - Horizontally subsample Cr, Cb components by a factor of 2.
+    * - ``V4L2_JPEG_CHROMA_SUBSAMPLING_420``
+      - Subsample Cr, Cb components horizontally and vertically by 2.
+    * - ``V4L2_JPEG_CHROMA_SUBSAMPLING_411``
+      - Horizontally subsample Cr, Cb components by a factor of 4.
+    * - ``V4L2_JPEG_CHROMA_SUBSAMPLING_410``
+      - Subsample Cr, Cb components horizontally by 4 and vertically by 2.
+    * - ``V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY``
+      - Use only luminance component.
+
+
+
+``V4L2_CID_JPEG_RESTART_INTERVAL (integer)``
+    The restart interval determines an interval of inserting RSTm
+    markers (m = 0..7). The purpose of these markers is to additionally
+    reinitialize the encoder process, in order to process blocks of an
+    image independently. For the lossy compression processes the restart
+    interval unit is MCU (Minimum Coded Unit) and its value is contained
+    in DRI (Define Restart Interval) marker. If
+    ``V4L2_CID_JPEG_RESTART_INTERVAL`` control is set to 0, DRI and RSTm
+    markers will not be inserted.
+
+.. _jpeg-quality-control:
+
+``V4L2_CID_JPEG_COMPRESSION_QUALITY (integer)``
+    ``V4L2_CID_JPEG_COMPRESSION_QUALITY`` control determines trade-off
+    between image quality and size. It provides simpler method for
+    applications to control image quality, without a need for direct
+    reconfiguration of luminance and chrominance quantization tables. In
+    cases where a driver uses quantization tables configured directly by
+    an application, using interfaces defined elsewhere,
+    ``V4L2_CID_JPEG_COMPRESSION_QUALITY`` control should be set by
+    driver to 0.
+
+    The value range of this control is driver-specific. Only positive,
+    non-zero values are meaningful. The recommended range is 1 - 100,
+    where larger values correspond to better image quality.
+
+.. _jpeg-active-marker-control:
+
+``V4L2_CID_JPEG_ACTIVE_MARKER (bitmask)``
+    Specify which JPEG markers are included in compressed stream. This
+    control is valid only for encoders.
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - ``V4L2_JPEG_ACTIVE_MARKER_APP0``
+      - Application data segment APP\ :sub:`0`.
+    * - ``V4L2_JPEG_ACTIVE_MARKER_APP1``
+      - Application data segment APP\ :sub:`1`.
+    * - ``V4L2_JPEG_ACTIVE_MARKER_COM``
+      - Comment segment.
+    * - ``V4L2_JPEG_ACTIVE_MARKER_DQT``
+      - Quantization tables segment.
+    * - ``V4L2_JPEG_ACTIVE_MARKER_DHT``
+      - Huffman tables segment.
+
+
+
+For more details about JPEG specification, refer to :ref:`itu-t81`,
+:ref:`jfif`, :ref:`w3c-jpeg-jfif`.
diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-rf-tuner.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-rf-tuner.rst
new file mode 100644
index 000000000000..5277138fce67
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-rf-tuner.rst
@@ -0,0 +1,96 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _rf-tuner-controls:
+
+**************************
+RF Tuner Control Reference
+**************************
+
+The RF Tuner (RF_TUNER) class includes controls for common features of
+devices having RF tuner.
+
+In this context, RF tuner is radio receiver circuit between antenna and
+demodulator. It receives radio frequency (RF) from the antenna and
+converts that received signal to lower intermediate frequency (IF) or
+baseband frequency (BB). Tuners that could do baseband output are often
+called Zero-IF tuners. Older tuners were typically simple PLL tuners
+inside a metal box, while newer ones are highly integrated chips
+without a metal box "silicon tuners". These controls are mostly
+applicable for new feature rich silicon tuners, just because older
+tuners does not have much adjustable features.
+
+For more information about RF tuners see
+`Tuner (radio) <http://en.wikipedia.org/wiki/Tuner_%28radio%29>`__
+and `RF front end <http://en.wikipedia.org/wiki/RF_front_end>`__
+from Wikipedia.
+
+
+.. _rf-tuner-control-id:
+
+RF_TUNER Control IDs
+====================
+
+``V4L2_CID_RF_TUNER_CLASS (class)``
+    The RF_TUNER class descriptor. Calling
+    :ref:`VIDIOC_QUERYCTRL` for this control will
+    return a description of this control class.
+
+``V4L2_CID_RF_TUNER_BANDWIDTH_AUTO (boolean)``
+    Enables/disables tuner radio channel bandwidth configuration. In
+    automatic mode bandwidth configuration is performed by the driver.
+
+``V4L2_CID_RF_TUNER_BANDWIDTH (integer)``
+    Filter(s) on tuner signal path are used to filter signal according
+    to receiving party needs. Driver configures filters to fulfill
+    desired bandwidth requirement. Used when
+    V4L2_CID_RF_TUNER_BANDWIDTH_AUTO is not set. Unit is in Hz. The
+    range and step are driver-specific.
+
+``V4L2_CID_RF_TUNER_LNA_GAIN_AUTO (boolean)``
+    Enables/disables LNA automatic gain control (AGC)
+
+``V4L2_CID_RF_TUNER_MIXER_GAIN_AUTO (boolean)``
+    Enables/disables mixer automatic gain control (AGC)
+
+``V4L2_CID_RF_TUNER_IF_GAIN_AUTO (boolean)``
+    Enables/disables IF automatic gain control (AGC)
+
+``V4L2_CID_RF_TUNER_RF_GAIN (integer)``
+    The RF amplifier is the very first amplifier on the receiver signal
+    path, just right after the antenna input. The difference between the
+    LNA gain and the RF gain in this document is that the LNA gain is
+    integrated in the tuner chip while the RF gain is a separate chip.
+    There may be both RF and LNA gain controls in the same device. The
+    range and step are driver-specific.
+
+``V4L2_CID_RF_TUNER_LNA_GAIN (integer)``
+    LNA (low noise amplifier) gain is first gain stage on the RF tuner
+    signal path. It is located very close to tuner antenna input. Used
+    when ``V4L2_CID_RF_TUNER_LNA_GAIN_AUTO`` is not set. See
+    ``V4L2_CID_RF_TUNER_RF_GAIN`` to understand how RF gain and LNA gain
+    differs from the each others. The range and step are
+    driver-specific.
+
+``V4L2_CID_RF_TUNER_MIXER_GAIN (integer)``
+    Mixer gain is second gain stage on the RF tuner signal path. It is
+    located inside mixer block, where RF signal is down-converted by the
+    mixer. Used when ``V4L2_CID_RF_TUNER_MIXER_GAIN_AUTO`` is not set.
+    The range and step are driver-specific.
+
+``V4L2_CID_RF_TUNER_IF_GAIN (integer)``
+    IF gain is last gain stage on the RF tuner signal path. It is
+    located on output of RF tuner. It controls signal level of
+    intermediate frequency output or baseband output. Used when
+    ``V4L2_CID_RF_TUNER_IF_GAIN_AUTO`` is not set. The range and step
+    are driver-specific.
+
+``V4L2_CID_RF_TUNER_PLL_LOCK (boolean)``
+    Is synthesizer PLL locked? RF tuner is receiving given frequency
+    when that control is set. This is a read-only control.
diff --git a/Documentation/userspace-api/media/v4l/extended-controls.rst b/Documentation/userspace-api/media/v4l/extended-controls.rst
new file mode 100644
index 000000000000..9aa352ac5ea4
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/extended-controls.rst
@@ -0,0 +1,180 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _extended-controls:
+
+*********************
+Extended Controls API
+*********************
+
+
+Introduction
+============
+
+The control mechanism as originally designed was meant to be used for
+user settings (brightness, saturation, etc). However, it turned out to
+be a very useful model for implementing more complicated driver APIs
+where each driver implements only a subset of a larger API.
+
+The MPEG encoding API was the driving force behind designing and
+implementing this extended control mechanism: the MPEG standard is quite
+large and the currently supported hardware MPEG encoders each only
+implement a subset of this standard. Further more, many parameters
+relating to how the video is encoded into an MPEG stream are specific to
+the MPEG encoding chip since the MPEG standard only defines the format
+of the resulting MPEG stream, not how the video is actually encoded into
+that format.
+
+Unfortunately, the original control API lacked some features needed for
+these new uses and so it was extended into the (not terribly originally
+named) extended control API.
+
+Even though the MPEG encoding API was the first effort to use the
+Extended Control API, nowadays there are also other classes of Extended
+Controls, such as Camera Controls and FM Transmitter Controls. The
+Extended Controls API as well as all Extended Controls classes are
+described in the following text.
+
+
+The Extended Control API
+========================
+
+Three new ioctls are available:
+:ref:`VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>`,
+:ref:`VIDIOC_S_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` and
+:ref:`VIDIOC_TRY_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>`. These ioctls act
+on arrays of controls (as opposed to the
+:ref:`VIDIOC_G_CTRL <VIDIOC_G_CTRL>` and
+:ref:`VIDIOC_S_CTRL <VIDIOC_G_CTRL>` ioctls that act on a single
+control). This is needed since it is often required to atomically change
+several controls at once.
+
+Each of the new ioctls expects a pointer to a struct
+:c:type:`v4l2_ext_controls`. This structure
+contains a pointer to the control array, a count of the number of
+controls in that array and a control class. Control classes are used to
+group similar controls into a single class. For example, control class
+``V4L2_CTRL_CLASS_USER`` contains all user controls (i. e. all controls
+that can also be set using the old :ref:`VIDIOC_S_CTRL <VIDIOC_G_CTRL>`
+ioctl). Control class ``V4L2_CTRL_CLASS_MPEG`` contains all controls
+relating to MPEG encoding, etc.
+
+All controls in the control array must belong to the specified control
+class. An error is returned if this is not the case.
+
+It is also possible to use an empty control array (``count`` == 0) to check
+whether the specified control class is supported.
+
+The control array is a struct
+:c:type:`v4l2_ext_control` array. The
+struct :c:type:`v4l2_ext_control` is very similar to
+struct :c:type:`v4l2_control`, except for the fact that
+it also allows for 64-bit values and pointers to be passed.
+
+Since the struct :c:type:`v4l2_ext_control` supports
+pointers it is now also possible to have controls with compound types
+such as N-dimensional arrays and/or structures. You need to specify the
+``V4L2_CTRL_FLAG_NEXT_COMPOUND`` when enumerating controls to actually
+be able to see such compound controls. In other words, these controls
+with compound types should only be used programmatically.
+
+Since such compound controls need to expose more information about
+themselves than is possible with :ref:`VIDIOC_QUERYCTRL <VIDIOC_QUERYCTRL>`
+the :ref:`VIDIOC_QUERY_EXT_CTRL <VIDIOC_QUERYCTRL>` ioctl was added. In
+particular, this ioctl gives the dimensions of the N-dimensional array if
+this control consists of more than one element.
+
+.. note::
+
+   #. It is important to realize that due to the flexibility of controls it is
+      necessary to check whether the control you want to set actually is
+      supported in the driver and what the valid range of values is. So use
+      :ref:`VIDIOC_QUERYCTRL` to check this.
+
+   #. It is possible that some of the menu indices in a control of
+      type ``V4L2_CTRL_TYPE_MENU`` may not be supported (``VIDIOC_QUERYMENU``
+      will return an error). A good example is the list of supported MPEG
+      audio bitrates. Some drivers only support one or two bitrates, others
+      support a wider range.
+
+All controls use machine endianness.
+
+
+Enumerating Extended Controls
+=============================
+
+The recommended way to enumerate over the extended controls is by using
+:ref:`VIDIOC_QUERYCTRL` in combination with the
+``V4L2_CTRL_FLAG_NEXT_CTRL`` flag:
+
+
+.. code-block:: c
+
+    struct v4l2_queryctrl qctrl;
+
+    qctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL;
+    while (0 == ioctl (fd, VIDIOC_QUERYCTRL, &qctrl)) {
+	/* ... */
+	qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
+    }
+
+The initial control ID is set to 0 ORed with the
+``V4L2_CTRL_FLAG_NEXT_CTRL`` flag. The ``VIDIOC_QUERYCTRL`` ioctl will
+return the first control with a higher ID than the specified one. When
+no such controls are found an error is returned.
+
+If you want to get all controls within a specific control class, then
+you can set the initial ``qctrl.id`` value to the control class and add
+an extra check to break out of the loop when a control of another
+control class is found:
+
+
+.. code-block:: c
+
+    qctrl.id = V4L2_CTRL_CLASS_MPEG | V4L2_CTRL_FLAG_NEXT_CTRL;
+    while (0 == ioctl(fd, VIDIOC_QUERYCTRL, &qctrl)) {
+	if (V4L2_CTRL_ID2CLASS(qctrl.id) != V4L2_CTRL_CLASS_MPEG)
+	    break;
+	/* ... */
+	qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
+    }
+
+The 32-bit ``qctrl.id`` value is subdivided into three bit ranges: the
+top 4 bits are reserved for flags (e. g. ``V4L2_CTRL_FLAG_NEXT_CTRL``)
+and are not actually part of the ID. The remaining 28 bits form the
+control ID, of which the most significant 12 bits define the control
+class and the least significant 16 bits identify the control within the
+control class. It is guaranteed that these last 16 bits are always
+non-zero for controls. The range of 0x1000 and up are reserved for
+driver-specific controls. The macro ``V4L2_CTRL_ID2CLASS(id)`` returns
+the control class ID based on a control ID.
+
+If the driver does not support extended controls, then
+``VIDIOC_QUERYCTRL`` will fail when used in combination with
+``V4L2_CTRL_FLAG_NEXT_CTRL``. In that case the old method of enumerating
+control should be used (see :ref:`enum_all_controls`). But if it is
+supported, then it is guaranteed to enumerate over all controls,
+including driver-private controls.
+
+
+Creating Control Panels
+=======================
+
+It is possible to create control panels for a graphical user interface
+where the user can select the various controls. Basically you will have
+to iterate over all controls using the method described above. Each
+control class starts with a control of type
+``V4L2_CTRL_TYPE_CTRL_CLASS``. ``VIDIOC_QUERYCTRL`` will return the name
+of this control class which can be used as the title of a tab page
+within a control panel.
+
+The flags field of struct :ref:`v4l2_queryctrl <v4l2-queryctrl>` also
+contains hints on the behavior of the control. See the
+:ref:`VIDIOC_QUERYCTRL` documentation for more
+details.
diff --git a/Documentation/userspace-api/media/v4l/field-order.rst b/Documentation/userspace-api/media/v4l/field-order.rst
new file mode 100644
index 000000000000..04e9a6932dc5
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/field-order.rst
@@ -0,0 +1,172 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _field-order:
+
+***********
+Field Order
+***********
+
+We have to distinguish between progressive and interlaced video.
+Progressive video transmits all lines of a video image sequentially.
+Interlaced video divides an image into two fields, containing only the
+odd and even lines of the image, respectively. Alternating the so called
+odd and even field are transmitted, and due to a small delay between
+fields a cathode ray TV displays the lines interleaved, yielding the
+original frame. This curious technique was invented because at refresh
+rates similar to film the image would fade out too quickly. Transmitting
+fields reduces the flicker without the necessity of doubling the frame
+rate and with it the bandwidth required for each channel.
+
+It is important to understand a video camera does not expose one frame
+at a time, merely transmitting the frames separated into fields. The
+fields are in fact captured at two different instances in time. An
+object on screen may well move between one field and the next. For
+applications analysing motion it is of paramount importance to recognize
+which field of a frame is older, the *temporal order*.
+
+When the driver provides or accepts images field by field rather than
+interleaved, it is also important applications understand how the fields
+combine to frames. We distinguish between top (aka odd) and bottom (aka
+even) fields, the *spatial order*: The first line of the top field is
+the first line of an interlaced frame, the first line of the bottom
+field is the second line of that frame.
+
+However because fields were captured one after the other, arguing
+whether a frame commences with the top or bottom field is pointless. Any
+two successive top and bottom, or bottom and top fields yield a valid
+frame. Only when the source was progressive to begin with, e. g. when
+transferring film to video, two fields may come from the same frame,
+creating a natural order.
+
+Counter to intuition the top field is not necessarily the older field.
+Whether the older field contains the top or bottom lines is a convention
+determined by the video standard. Hence the distinction between temporal
+and spatial order of fields. The diagrams below should make this
+clearer.
+
+In V4L it is assumed that all video cameras transmit fields on the media
+bus in the same order they were captured, so if the top field was
+captured first (is the older field), the top field is also transmitted
+first on the bus.
+
+All video capture and output devices must report the current field
+order. Some drivers may permit the selection of a different order, to
+this end applications initialize the ``field`` field of struct
+:c:type:`v4l2_pix_format` before calling the
+:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl. If this is not desired it
+should have the value ``V4L2_FIELD_ANY`` (0).
+
+
+enum v4l2_field
+===============
+
+.. c:type:: v4l2_field
+
+.. tabularcolumns:: |p{5.8cm}|p{0.6cm}|p{11.1cm}|
+
+.. cssclass:: longtable
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_FIELD_ANY``
+      - 0
+      - Applications request this field order when any field format
+	is acceptable. Drivers choose depending on hardware capabilities or
+	e.g. the requested image size, and return the actual field order.
+	Drivers must never return ``V4L2_FIELD_ANY``.
+	If multiple field orders are possible the
+	driver must choose one of the possible field orders during
+	:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` or
+	:ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>`. struct
+	:c:type:`v4l2_buffer` ``field`` can never be
+	``V4L2_FIELD_ANY``.
+    * - ``V4L2_FIELD_NONE``
+      - 1
+      - Images are in progressive (frame-based) format, not interlaced
+        (field-based).
+    * - ``V4L2_FIELD_TOP``
+      - 2
+      - Images consist of the top (aka odd) field only.
+    * - ``V4L2_FIELD_BOTTOM``
+      - 3
+      - Images consist of the bottom (aka even) field only. Applications
+	may wish to prevent a device from capturing interlaced images
+	because they will have "comb" or "feathering" artefacts around
+	moving objects.
+    * - ``V4L2_FIELD_INTERLACED``
+      - 4
+      - Images contain both fields, interleaved line by line. The temporal
+	order of the fields (whether the top or bottom field is older)
+	depends on the current video standard. In M/NTSC the bottom
+	field is the older field. In all other standards the top field
+	is the older field.
+    * - ``V4L2_FIELD_SEQ_TB``
+      - 5
+      - Images contain both fields, the top field lines are stored first
+	in memory, immediately followed by the bottom field lines. Fields
+	are always stored in temporal order, the older one first in
+	memory. Image sizes refer to the frame, not fields.
+    * - ``V4L2_FIELD_SEQ_BT``
+      - 6
+      - Images contain both fields, the bottom field lines are stored
+	first in memory, immediately followed by the top field lines.
+	Fields are always stored in temporal order, the older one first in
+	memory. Image sizes refer to the frame, not fields.
+    * - ``V4L2_FIELD_ALTERNATE``
+      - 7
+      - The two fields of a frame are passed in separate buffers, in
+	temporal order, i. e. the older one first. To indicate the field
+	parity (whether the current field is a top or bottom field) the
+	driver or application, depending on data direction, must set
+	struct :c:type:`v4l2_buffer` ``field`` to
+	``V4L2_FIELD_TOP`` or ``V4L2_FIELD_BOTTOM``. Any two successive
+	fields pair to build a frame. If fields are successive, without
+	any dropped fields between them (fields can drop individually),
+	can be determined from the struct
+	:c:type:`v4l2_buffer` ``sequence`` field. This
+	format cannot be selected when using the read/write I/O method
+	since there is no way to communicate if a field was a top or
+	bottom field.
+    * - ``V4L2_FIELD_INTERLACED_TB``
+      - 8
+      - Images contain both fields, interleaved line by line, top field
+	first. The top field is the older field.
+    * - ``V4L2_FIELD_INTERLACED_BT``
+      - 9
+      - Images contain both fields, interleaved line by line, top field
+	first. The bottom field is the older field.
+
+
+
+.. _fieldseq-tb:
+
+Field Order, Top Field First Transmitted
+========================================
+
+.. kernel-figure:: fieldseq_tb.svg
+    :alt:    fieldseq_tb.svg
+    :align:  center
+
+    Field Order, Top Field First Transmitted
+
+
+.. _fieldseq-bt:
+
+Field Order, Bottom Field First Transmitted
+===========================================
+
+.. kernel-figure:: fieldseq_bt.svg
+    :alt:    fieldseq_bt.svg
+    :align:  center
+
+    Field Order, Bottom Field First Transmitted
diff --git a/Documentation/userspace-api/media/v4l/fieldseq_bt.svg b/Documentation/userspace-api/media/v4l/fieldseq_bt.svg
new file mode 100644
index 000000000000..b663f6fcb70b
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/fieldseq_bt.svg
@@ -0,0 +1,2621 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+    Permission is granted to copy, distribute and/or modify this
+    document under the terms of the GNU Free Documentation License,
+    Version 1.1 or any later version published by the Free Software
+    Foundation, with no Invariant Sections, no Front-Cover Texts
+    and no Back-Cover Texts. A copy of the license is included at
+    Documentation/userspace-api/media/fdl-appendix.rst.
+
+    TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+-->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   id="svg3619"
+   version="1.1"
+   inkscape:version="0.91 r13725"
+   xml:space="preserve"
+   width="198.48296mm"
+   height="211.89406mm"
+   viewBox="0 0 703.28606 750.80571"
+   sodipodi:docname="fieldseq_bt.svg"><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="997"
+     id="namedview3621"
+     showgrid="false"
+     units="mm"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0"
+     inkscape:zoom="1.0721815"
+     inkscape:cx="8.4175633"
+     inkscape:cy="371.67214"
+     inkscape:window-x="1920"
+     inkscape:window-y="30"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="g3627" /><metadata
+     id="metadata3625"><rdf:RDF><cc:Work
+	 rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+	   rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
+     id="defs3623"><clipPath
+       id="clipPath4301"
+       clipPathUnits="userSpaceOnUse"><path
+	 style="clip-rule:evenodd"
+	 inkscape:connector-curvature="0"
+	 id="path4303"
+	 d="M 0,6040 0,0 l 5650,0 0,6040 -5650,0 z m 4786.76,-99.89 103.92,0 0,56.69 -103.92,0 0,0 85.03,-28.35 -85.03,-28.34 z" /></clipPath></defs><g
+     transform="matrix(1.25,0,0,-1.25,-1.0537,751.94632)"
+     inkscape:label="fieldseq_bt"
+     inkscape:groupmode="layer"
+     id="g3627"><path
+       d="m 188.622,346.001 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3631"
+       inkscape:connector-curvature="0" /><path
+       d="m 375.693,346.001 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3633"
+       inkscape:connector-curvature="0" /><path
+       d="m 282.157,346.001 93.5355,0 0,42.516 -93.5355,0 0,-42.516 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3635"
+       inkscape:connector-curvature="0" /><path
+       d="m 469.228,346.001 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3637"
+       inkscape:connector-curvature="0" /><path
+       d="m 95.0867,346.001 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3639"
+       inkscape:connector-curvature="0" /><path
+       d="m 1.55156,346.001 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3641"
+       inkscape:connector-curvature="0" /><path
+       d="m 95.0867,482.052 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3643"
+       inkscape:connector-curvature="0" /><path
+       d="m 469.228,482.052 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3645"
+       inkscape:connector-curvature="0" /><path
+       d="m 1.55156,414.027 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3647"
+       inkscape:connector-curvature="0" /><path
+       d="m 188.622,414.027 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3649"
+       inkscape:connector-curvature="0" /><path
+       d="m 375.693,414.027 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3651"
+       inkscape:connector-curvature="0" /><path
+       d="m 469.228,214.201 93.5352,0 0,76.5289 -93.5352,0 0,-76.5289 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3653"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,579.839 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3655"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,579.839 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3657"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,571.336 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3659"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,571.336 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3661"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,562.832 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3663"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,562.832 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3665"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,554.329 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3667"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,554.329 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3669"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,575.587 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3671"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,575.587 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3673"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,567.084 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3675"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,567.084 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3677"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,558.581 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3679"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,558.581 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3681"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,550.078 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3683"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,550.078 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3685"
+       inkscape:connector-curvature="0" /><path
+       d="m 282.157,482.052 93.5355,0 0,42.516 -93.5355,0 0,-42.516 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3687"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,222.704 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3689"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,222.704 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3691"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,231.207 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3693"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,231.207 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3695"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,226.956 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3697"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,226.956 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3699"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,239.711 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3701"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,239.711 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3703"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,235.459 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3705"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,235.459 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3707"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,248.214 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3709"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,248.214 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3711"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,243.962 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3713"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,243.962 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3715"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,256.717 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3717"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,256.717 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3719"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,252.466 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3721"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,252.466 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3723"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,265.22 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3725"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,265.22 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3727"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,260.969 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3729"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,260.969 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3731"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,273.723 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3733"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,273.723 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3735"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,269.472 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3737"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,269.472 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3739"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,277.975 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3741"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,277.975 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3743"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,218.453 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3745"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,218.453 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3747"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,282.227 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3749"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,282.227 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3751"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,380.014 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3753"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,380.014 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3755"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,371.511 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3757"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,371.511 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3759"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,363.007 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3761"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,363.007 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3763"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,354.504 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3765"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,354.504 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3767"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,375.762 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3769"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,375.762 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3771"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,367.259 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3773"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,367.259 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3775"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,358.755 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3777"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,358.755 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3779"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,350.252 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3781"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,350.252 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3783"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,375.762 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3785"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,375.762 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3787"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,367.259 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3789"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,367.259 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3791"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,358.755 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3793"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,358.755 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3795"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,350.252 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3797"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,350.252 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3799"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,380.014 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3801"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,380.014 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3803"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,371.511 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3805"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,371.511 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3807"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,363.007 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3809"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,363.007 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3811"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,354.504 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3813"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,354.504 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3815"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,363.007 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3817"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,363.007 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3819"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,371.511 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3821"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,371.511 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3823"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,354.504 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3825"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,354.504 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3827"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,375.762 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3829"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,375.762 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3831"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,367.259 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3833"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,367.259 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3835"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,358.755 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3837"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,358.755 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3839"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,350.252 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3841"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,350.252 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3843"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,380.014 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3845"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,380.014 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3847"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,380.014 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3849"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,380.014 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3851"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,371.511 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3853"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,371.511 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3855"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,363.007 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3857"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,363.007 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3859"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,354.504 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3861"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,354.504 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3863"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,358.755 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3865"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,358.755 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3867"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,350.252 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3869"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,350.252 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3871"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,367.259 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3873"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,367.259 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3875"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,375.762 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3877"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,375.762 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3879"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,380.014 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3881"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,380.014 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3883"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,371.511 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3885"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,371.511 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3887"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,363.007 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3889"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,363.007 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3891"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,354.504 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3893"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,354.504 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3895"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,375.762 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3897"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,375.762 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3899"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,367.259 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3901"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,367.259 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3903"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,358.755 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3905"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,358.755 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3907"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,350.252 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3909"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,350.252 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3911"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,375.762 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3913"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,375.762 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3915"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,367.259 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3917"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,367.259 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3919"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,358.755 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3921"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,358.755 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3923"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,350.252 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3925"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,350.252 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3927"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,380.014 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3929"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,380.014 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3931"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,371.511 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3933"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,371.511 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3935"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,363.007 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3937"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,363.007 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3939"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,354.504 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3941"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,354.504 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3943"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,448.039 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3945"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,448.039 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3947"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,439.536 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3949"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,439.536 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3951"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,431.033 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3953"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,431.033 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3955"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,422.53 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3957"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,422.53 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3959"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,443.788 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3961"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,443.788 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3963"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,435.284 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3965"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,435.284 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3967"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,426.781 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3969"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,426.781 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3971"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,418.278 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3973"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,418.278 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3975"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,431.033 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3977"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,431.033 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3979"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,439.536 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3981"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,439.536 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3983"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,422.53 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3985"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,422.53 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3987"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,443.788 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3989"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,443.788 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3991"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,435.284 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3993"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,435.284 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3995"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,426.781 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path3997"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,426.781 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path3999"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,418.278 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4001"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,418.278 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4003"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,448.039 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4005"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,448.039 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4007"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,448.039 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4009"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,448.039 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4011"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,439.536 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4013"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,439.536 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4015"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,431.033 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4017"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,431.033 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4019"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,422.53 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4021"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,422.53 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4023"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,443.788 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4025"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,443.788 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4027"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,435.284 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4029"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,435.284 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4031"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,426.781 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4033"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,426.781 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4035"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,418.278 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4037"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,418.278 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4039"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,511.813 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4041"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,511.813 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4043"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,503.31 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4045"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,503.31 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4047"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,494.807 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4049"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,494.807 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4051"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,486.304 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4053"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,486.304 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4055"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,516.065 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4057"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,516.065 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4059"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,507.562 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4061"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,507.562 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4063"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,499.059 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4065"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,499.059 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4067"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,490.555 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4069"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,490.555 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4071"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,516.065 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4073"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,516.065 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4075"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,507.562 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4077"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,507.562 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4079"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,499.059 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4081"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,499.059 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4083"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,490.555 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4085"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,490.555 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4087"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,494.807 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4089"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,494.807 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4091"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,486.304 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4093"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,486.304 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4095"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,503.31 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4097"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,503.31 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4099"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,511.813 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4101"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,511.813 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4103"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,511.813 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4105"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,511.813 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4107"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,503.31 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4109"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,503.31 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4111"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,494.807 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4113"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,494.807 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4115"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,486.304 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4117"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,486.304 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4119"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,516.065 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4121"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,516.065 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4123"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,507.562 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4125"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,507.562 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4127"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,499.059 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4129"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,499.059 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4131"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,490.555 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4133"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,490.555 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4135"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,575.587 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4137"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,575.587 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4139"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,567.084 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4141"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,567.084 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4143"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,558.581 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4145"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,558.581 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4147"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,550.078 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4149"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,550.078 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4151"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,579.839 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4153"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,579.839 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4155"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,571.336 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4157"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,571.336 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4159"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,562.832 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4161"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,562.832 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4163"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,554.329 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4165"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,554.329 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4167"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,579.839 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4169"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,579.839 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4171"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,571.336 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4173"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,571.336 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4175"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,562.832 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4177"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,562.832 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4179"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,554.329 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4181"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,554.329 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4183"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,558.581 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4185"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,558.581 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4187"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,550.078 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4189"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,550.078 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4191"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,567.084 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4193"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,567.084 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4195"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,575.587 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4197"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,575.587 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4199"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,562.832 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4201"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,562.832 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4203"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,571.336 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4205"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,571.336 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4207"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,554.329 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4209"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,554.329 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4211"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,575.587 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4213"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,575.587 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4215"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,567.084 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4217"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,567.084 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4219"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,558.581 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4221"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,558.581 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4223"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,550.078 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4225"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,550.078 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4227"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,579.839 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4229"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,579.839 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4231"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,575.587 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4233"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,575.587 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4235"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,567.084 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4237"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,567.084 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4239"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,558.581 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4241"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,558.581 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4243"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,550.078 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4245"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,550.078 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4247"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,579.839 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4249"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,579.839 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4251"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,571.336 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4253"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,571.336 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4255"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,562.832 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4257"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,562.832 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4259"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,554.329 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4261"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,554.329 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4263"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,579.839 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4265"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,579.839 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4267"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,571.336 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4269"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,571.336 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4271"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,562.832 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4273"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,562.832 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4275"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,554.329 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4277"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,554.329 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4279"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,575.587 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4281"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,575.587 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4283"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,567.084 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4285"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,567.084 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4287"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,558.581 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4289"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,558.581 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4291"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,550.078 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4293"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,550.078 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4295"
+       inkscape:connector-curvature="0" /><g
+       transform="scale(0.1,0.1)"
+       id="g4297"
+       style=""><g
+	 id="g4299"
+	 clip-path="url(#clipPath4301)"
+	 style=""><path
+	   d="m 3778.18,5968.45 1105.42,0"
+	   style="fill:none;stroke:#000000;stroke-width:14.17199993;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	   id="path4305"
+	   inkscape:connector-curvature="0" /></g></g><path
+       d="m 478.676,594.011 8.503,2.834 -8.503,2.835 0,-5.669"
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4307"
+       inkscape:connector-curvature="0" /><path
+       d="m 478.676,594.011 8.503,2.834 -8.503,2.835 0,-5.669 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4309"
+       inkscape:connector-curvature="0" /><path
+       d="m 95.0867,1.62109 93.5352,0 0,76.5289 -93.5352,0 0,-76.5289 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4311"
+       inkscape:connector-curvature="0" /><path
+       d="m 282.157,1.62109 93.5355,0 0,76.5289 -93.5355,0 0,-76.5289 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4313"
+       inkscape:connector-curvature="0" /><path
+       d="m 469.228,1.62109 93.5352,0 0,76.5289 -93.5352,0 0,-76.5289 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4315"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,10.1242 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4317"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,10.1242 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4319"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,18.6277 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4321"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,18.6277 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4323"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,27.1309 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4325"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,27.1309 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4327"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,35.634 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4329"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,35.634 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4331"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,5.87266 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4333"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,5.87266 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4335"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,14.3762 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4337"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,14.3762 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4339"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,22.8793 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4341"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,22.8793 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4343"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,31.3824 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4345"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,31.3824 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4347"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,10.1242 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4349"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,10.1242 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4351"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,18.6277 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4353"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,18.6277 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4355"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,27.1309 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4357"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,27.1309 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4359"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,35.634 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4361"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,35.634 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4363"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,5.87266 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4365"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,5.87266 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4367"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,14.3762 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4369"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,14.3762 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4371"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,22.8793 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4373"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,22.8793 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4375"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,31.3824 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4377"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,31.3824 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4379"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,69.6469 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4381"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,69.6469 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4383"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,65.3953 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4385"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,65.3953 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4387"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,61.1438 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4389"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,61.1438 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4391"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,56.8922 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4393"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,56.8922 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4395"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,52.6402 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4397"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,52.6402 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4399"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,48.3887 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4401"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,48.3887 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4403"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,44.1371 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4405"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,44.1371 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4407"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,5.87266 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4409"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,5.87266 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4411"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,10.1242 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4413"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,10.1242 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4415"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,14.3762 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4417"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,14.3762 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4419"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,18.6277 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4421"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,18.6277 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4423"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,22.8793 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4425"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,22.8793 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4427"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,27.1309 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4429"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,27.1309 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4431"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,31.3824 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4433"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,31.3824 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4435"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,39.8855 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4437"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,39.8855 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4439"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,35.634 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4441"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,35.634 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4443"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,39.8855 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4445"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,39.8855 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4447"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,48.3887 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4449"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,48.3887 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4451"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,56.8922 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4453"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,56.8922 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4455"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,65.3953 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4457"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,65.3953 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4459"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,44.1371 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4461"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,44.1371 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4463"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,52.6402 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4465"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,52.6402 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4467"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,61.1438 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4469"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,61.1438 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4471"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,69.6469 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4473"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,69.6469 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4475"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,39.8855 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4477"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,39.8855 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4479"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,48.3887 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4481"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,48.3887 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4483"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,56.8922 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4485"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,56.8922 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4487"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,65.3953 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4489"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,65.3953 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4491"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,44.1371 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4493"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,44.1371 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4495"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,52.6402 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4497"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,52.6402 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4499"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,61.1438 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4501"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,61.1438 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4503"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,69.6469 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4505"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,69.6469 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4507"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,116.414 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4509"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,116.414 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4511"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,112.163 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4513"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,112.163 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4515"
+       inkscape:connector-curvature="0" /><path
+       d="m 188.622,107.911 93.5352,0 0,76.5285 -93.5352,0 0,-76.5285 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4517"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,116.414 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4519"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,116.414 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4521"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,112.163 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4523"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,112.163 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4525"
+       inkscape:connector-curvature="0" /><path
+       d="m 375.693,107.911 93.5352,0 0,76.5285 -93.5352,0 0,-76.5285 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4527"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,116.414 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4529"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,116.414 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4531"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,112.163 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4533"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,112.163 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4535"
+       inkscape:connector-curvature="0" /><path
+       d="m 1.55156,107.911 93.5352,0 0,76.5285 -93.5352,0 0,-76.5285 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4537"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,175.937 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4539"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,175.937 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4541"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,167.434 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4543"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,167.434 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4545"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,158.93 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4547"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,158.93 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4549"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,150.427 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4551"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,150.427 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4553"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,141.924 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4555"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,141.924 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4557"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,133.421 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4559"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,133.421 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4561"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,124.918 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4563"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,124.918 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4565"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,171.685 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4567"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,171.685 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4569"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,163.182 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4571"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,163.182 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4573"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,154.679 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4575"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,154.679 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4577"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,146.176 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4579"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,146.176 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4581"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,137.672 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4583"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,137.672 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4585"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,129.169 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4587"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,129.169 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4589"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,120.666 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4591"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,120.666 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4593"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,175.937 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4595"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,175.937 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4597"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,167.434 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4599"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,167.434 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4601"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,158.93 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4603"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,158.93 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4605"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,150.427 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4607"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,150.427 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4609"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,141.924 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4611"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,141.924 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4613"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,133.421 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4615"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,133.421 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4617"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,124.918 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4619"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,124.918 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4621"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,171.685 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4623"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,171.685 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4625"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,163.182 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4627"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,163.182 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4629"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,154.679 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4631"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,154.679 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4633"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,146.176 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4635"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,146.176 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4637"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,137.672 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4639"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,137.672 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4641"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,129.169 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4643"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,129.169 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4645"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,120.666 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4647"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,120.666 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4649"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,175.937 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4651"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,175.937 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4653"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,167.434 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4655"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,167.434 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4657"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,158.93 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4659"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,158.93 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4661"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,150.427 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4663"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,150.427 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4665"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,141.924 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4667"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,141.924 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4669"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,133.421 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4671"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,133.421 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4673"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,124.918 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4675"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,124.918 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4677"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,171.685 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4679"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,171.685 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4681"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,163.182 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4683"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,163.182 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4685"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,154.679 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4687"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,154.679 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4689"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,146.176 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4691"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,146.176 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4693"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,137.672 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4695"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,137.672 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4697"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,129.169 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4699"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,129.169 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4701"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,120.666 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4703"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,120.666 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4705"
+       inkscape:connector-curvature="0" /><path
+       d="m 95.0867,214.201 93.5352,0 0,76.5289 -93.5352,0 0,-76.5289 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4707"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,222.704 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4709"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,222.704 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4711"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,231.207 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4713"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,231.207 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4715"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,226.956 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4717"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,226.956 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4719"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,239.711 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4721"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,239.711 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4723"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,235.459 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4725"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,235.459 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4727"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,248.214 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4729"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,248.214 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4731"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,243.962 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4733"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,243.962 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4735"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,256.717 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4737"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,256.717 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4739"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,252.466 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4741"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,252.466 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4743"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,265.22 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4745"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,265.22 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4747"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,260.969 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4749"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,260.969 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4751"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,273.723 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4753"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,273.723 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4755"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,269.472 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4757"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,269.472 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4759"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,277.975 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4761"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,277.975 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4763"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,218.453 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4765"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,218.453 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4767"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,282.227 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4769"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,282.227 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4771"
+       inkscape:connector-curvature="0" /><path
+       d="m 282.157,214.201 93.5355,0 0,76.5289 -93.5355,0 0,-76.5289 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4773"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,277.975 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4775"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,277.975 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4777"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,282.227 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4779"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,282.227 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4781"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,273.723 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4783"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,273.723 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4785"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,248.214 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4787"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,248.214 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4789"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,239.711 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4791"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,239.711 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4793"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,231.207 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4795"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,231.207 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4797"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,222.704 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4799"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,222.704 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4801"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,269.472 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4803"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,269.472 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4805"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,256.717 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4807"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,256.717 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4809"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,265.22 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4811"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,265.22 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4813"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,260.969 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4815"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,260.969 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4817"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,252.466 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4819"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,252.466 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4821"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,243.962 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4823"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,243.962 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4825"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,235.459 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4827"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,235.459 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4829"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,226.956 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4831"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,226.956 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4833"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,218.453 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path4835"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,218.453 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path4837"
+       inkscape:connector-curvature="0" /><text
+       y="-533.07098"
+       x="5.8031301"
+       id="text4841"
+       style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan4843"
+	 sodipodi:role="line"
+	 y="-533.07098"
+	 x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 88.500237 97.835464">V4L2_FIELD_TOP</tspan><tspan
+	 id="tspan4845"
+	 sodipodi:role="line"
+	 y="-465.04559"
+	 x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 98.507408 105.83879 113.17018 122.5054">V4L2_FIELD_BOTTOM</tspan><tspan
+	 id="tspan4847"
+	 sodipodi:role="line"
+	 y="-397.0202"
+	 x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 95.843628 103.17502 111.17835 119.84163 128.5049 136.50824 143.83963">V4L2_FIELD_ALTERNATE</tspan></text>
+<text
+       y="-316.23969"
+       x="103.58983"
+       id="text4849"
+       style="font-variant:normal;font-weight:normal;font-size:8.2495203px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan4851"
+	 sodipodi:role="line"
+	 y="-316.23969"
+	 x="103.58983 109.09226 113.67899 118.26572 122.85246 127.43919 132.47964 134.77301 140.27545 144.86218 150.81833 155.40506 160.44553 166.86365 188.62184 194.12427 198.711 203.29774 207.88448 212.47121 217.51166 219.80502 225.30746 229.8942 235.85034 240.43707 245.9395 252.35764 257.3981 262.43854 268.85669 375.69293 381.19534 385.78207 390.3688 394.95554 399.54227 404.58273 406.8761 412.37854 416.96527 422.92142 427.50815 433.01059 439.42871 444.46918 449.50961 455.92776 1.551828 7.0542617 11.640993 16.227724 20.814463 25.401194 30.441652 32.735016 38.237442 42.824177 48.780331 53.367065 58.869492 65.287621 70.328079 75.368538 81.786659">V4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_BOTTOMV4L2_FIELD_BOTTOM</tspan><tspan
+	 id="tspan4853"
+	 sodipodi:role="line"
+	 y="-328.99481"
+	 x="10.054964 14.17972 18.766451 20.597849 25.18458 29.771311 34.358047 38.944778 41.238144 43.531509 48.118244 50.865334 53.158699 55.452068 57.283459 61.870193 63.701588 68.288322">v4l2_buffer.field:</tspan></text>
+<text
+       y="-592.59381"
+       x="5.8034"
+       id="text4855"
+       style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan4857"
+	 sodipodi:role="line"
+	 y="-592.59381"
+	 x="5.8034 13.134789 19.806232 29.801399 36.472843 43.144287 47.139954 53.811398 56.475174 59.810898 66.482346 70.478004 77.149452 83.820892 87.816566 91.152283 94.488007 101.15945 107.83089 111.16662 114.50233 121.17377 131.16895 134.50468 137.84041 140.50418 147.17563 149.8394 156.51085 159.84657 163.1823 165.84607 169.84174 175.84123 179.17696 182.51268 185.8484 189.84407 196.51552 203.18695 209.18646 219.18163 221.8454 225.18112 228.51685 235.18829 241.85973 245.19545 249.19112 255.86256 259.19827 265.86972 269.20544 272.54117 282.53635 285.87207 294.53534 301.86673 309.87006 318.53336">Temporal order, bottom field first transmitted (e.g. M/NTSC)</tspan></text>
+<text
+       y="-316.23981"
+       x="290.6604"
+       id="text4859"
+       style="font-variant:normal;font-weight:normal;font-size:8.2495203px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan4861"
+	 sodipodi:role="line"
+	 y="-316.23981"
+	 x="290.6604 296.16284 300.74957 305.3363 309.92303 314.50977 319.55023 321.8436 327.34601 331.93274 337.88889 342.47565 347.51608 353.9342 477.73062 483.23306 487.81979 492.40652 496.99326 501.57999 506.62045 508.91382 514.41626 519.00299 524.95911 529.5459 534.5863 541.00446">V4L2_FIELD_TOPV4L2_FIELD_TOP</tspan></text>
+<text
+       y="-299.23349"
+       x="5.8034"
+       id="text4863"
+       style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan4865"
+	 sodipodi:role="line"
+	 y="-299.23349"
+	 x="5.8034 13.806733 20.478176 27.149622 33.821064 40.492508 47.823895 51.159618 59.162952 65.834396 74.497673 81.169121 84.504837 93.168114 100.4995 108.50284 117.16611 123.83755 131.8409 140.50418 148.50751 157.17079 160.50652 163.84224 167.17796 175.18129 181.85274 188.52419 195.19562 201.86707 209.19846 212.53418 220.53751 227.20895 235.87224 242.54367 245.87939 254.54268 261.87405 269.87741 278.54068 285.21213 293.21545 301.87872 309.88205 318.54535 325.2168 333.22012">V4L2_FIELD_INTERLACED / V4L2_FIELD_INTERLACED_BT</tspan><tspan
+	 id="tspan4867"
+	 sodipodi:role="line"
+	 y="-192.9435"
+	 x="1.5518398 9.5551729 16.226616 22.898062 29.569506 36.240948 43.572334 46.908058 54.911392 61.582836 70.246117 76.917557 80.253281 88.916557 96.247948 104.25128 112.91456 119.586 127.58932 136.25262 144.25595 152.91924 159.59067 166.92206 174.9254 178.26112 182.25679 192.25195 194.91573 200.91524 207.58667 210.25046 212.91423 219.58568 226.25713 232.92856 239.60001">V4L2_FIELD_INTERLACED_TB (misaligned)</tspan><tspan
+	 id="tspan4869"
+	 sodipodi:role="line"
+	 y="-86.653496"
+	 x="5.8034 13.806733 20.478176 27.149622 33.821064 40.492508 47.823895 51.159618 59.162952 65.834396 74.497673 81.169121 89.172447 97.175781 106.511 113.18245 121.18579">V4L2_FIELD_SEQ_BT</tspan></text>
+<text
+       y="-533.07098"
+       x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 88.500237 97.835464"
+       id="text4592"
+       style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan4594"
+	 sodipodi:role="line"
+	 y="-533.07098"
+	 x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 88.500237 97.835464">V4L2_FIELD_TOP</tspan></text>
+<text
+       y="-465.04559"
+       x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 98.507408 105.83879 113.17018 122.5054"
+       id="text4596"
+       style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan4598"
+	 sodipodi:role="line"
+	 y="-465.04559"
+	 x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 98.507408 105.83879 113.17018 122.5054">V4L2_FIELD_BOTTOM</tspan></text>
+<text
+       y="-397.0202"
+       x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 95.843628 103.17502 111.17835 119.84163 128.5049 136.50824 143.83963"
+       id="text4600"
+       style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan4602"
+	 sodipodi:role="line"
+	 y="-397.0202"
+	 x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 95.843628 103.17502 111.17835 119.84163 128.5049 136.50824 143.83963">V4L2_FIELD_ALTERNATE</tspan></text>
+<text
+       y="-299.23349"
+       x="5.8034 13.806733 20.478176 27.149622 33.821064 40.492508 47.823895 51.159618 59.162952 65.834396 74.497673 81.169121 84.504837 93.168114 100.4995 108.50284 117.16611 123.83755 131.8409 140.50418 148.50751 157.17079 160.50652 163.84224 167.17796 175.18129 181.85274 188.52419 195.19562 201.86707 209.19846 212.53418 220.53751 227.20895 235.87224 242.54367 245.87939 254.54268 261.87405 269.87741 278.54068 285.21213 293.21545 301.87872 309.88205 318.54535 325.2168 333.22012"
+       id="text5862"
+       style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan5864"
+	 sodipodi:role="line"
+	 y="-299.23349"
+	 x="5.8034 13.806733 20.478176 27.149622 33.821064 40.492508 47.823895 51.159618 59.162952 65.834396 74.497673 81.169121 84.504837 93.168114 100.4995 108.50284 117.16611 123.83755 131.8409 140.50418 148.50751 157.17079 160.50652 163.84224 167.17796 175.18129 181.85274 188.52419 195.19562 201.86707 209.19846 212.53418 220.53751 227.20895 235.87224 242.54367 245.87939 254.54268 261.87405 269.87741 278.54068 285.21213 293.21545 301.87872 309.88205 318.54535 325.2168 333.22012">V4L2_FIELD_INTERLACED / V4L2_FIELD_INTERLACED_BT</tspan></text>
+<text
+       y="-192.9435"
+       x="1.5518398 9.5551729 16.226616 22.898062 29.569506 36.240948 43.572334 46.908058 54.911392 61.582836 70.246117 76.917557 80.253281 88.916557 96.247948 104.25128 112.91456 119.586 127.58932 136.25262 144.25595 152.91924 159.59067 166.92206 174.9254 178.26112 182.25679 192.25195 194.91573 200.91524 207.58667 210.25046 212.91423 219.58568 226.25713 232.92856 239.60001"
+       id="text5866"
+       style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan5868"
+	 sodipodi:role="line"
+	 y="-192.9435"
+	 x="1.5518398 9.5551729 16.226616 22.898062 29.569506 36.240948 43.572334 46.908058 54.911392 61.582836 70.246117 76.917557 80.253281 88.916557 96.247948 104.25128 112.91456 119.586 127.58932 136.25262 144.25595 152.91924 159.59067 166.92206 174.9254 178.26112 182.25679 192.25195 194.91573 200.91524 207.58667 210.25046 212.91423 219.58568 226.25713 232.92856 239.60001">V4L2_FIELD_INTERLACED_TB (misaligned)</tspan></text>
+<text
+       y="-86.653496"
+       x="5.8034 13.806733 20.478176 27.149622 33.821064 40.492508 47.823895 51.159618 59.162952 65.834396 74.497673 81.169121 89.172447 97.175781 106.511 113.18245 121.18579"
+       id="text5870"
+       style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan5872"
+	 sodipodi:role="line"
+	 y="-86.653496"
+	 x="5.8034 13.806733 20.478176 27.149622 33.821064 40.492508 47.823895 51.159618 59.162952 65.834396 74.497673 81.169121 89.172447 97.175781 106.511 113.18245 121.18579">V4L2_FIELD_SEQ_BT</tspan></text>
+<text
+       y="-316.23969"
+       x="103.58983 109.09226 113.67899 118.26572 122.85246 127.43919 132.47964 134.77301 140.27545 144.86218 150.81833 155.40506 160.44553 166.86365 188.62184 194.12427 198.711 203.29774 207.88448 212.47121 217.51166 219.80502 225.30746 229.8942 235.85034 240.43707 245.9395 252.35764 257.3981 262.43854 268.85669 375.69293 381.19534 385.78207 390.3688 394.95554 399.54227 404.58273 406.8761 412.37854 416.96527 422.92142 427.50815 433.01059 439.42871 444.46918 449.50961 455.92776 1.551828 7.0542617 11.640993 16.227724 20.814463 25.401194 30.441652 32.735016 38.237442 42.824177 48.780331 53.367065 58.869492 65.287621 70.328079 75.368538 81.786659"
+       id="text7144"
+       style="font-variant:normal;font-weight:normal;font-size:8.2495203px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan7146"
+	 sodipodi:role="line"
+	 y="-316.23969"
+	 x="103.58983 109.09226 113.67899 118.26572 122.85246 127.43919 132.47964 134.77301 140.27545 144.86218 150.81833 155.40506 160.44553 166.86365 188.62184 194.12427 198.711 203.29774 207.88448 212.47121 217.51166 219.80502 225.30746 229.8942 235.85034 240.43707 245.9395 252.35764 257.3981 262.43854 268.85669 375.69293 381.19534 385.78207 390.3688 394.95554 399.54227 404.58273 406.8761 412.37854 416.96527 422.92142 427.50815 433.01059 439.42871 444.46918 449.50961 455.92776 1.551828 7.0542617 11.640993 16.227724 20.814463 25.401194 30.441652 32.735016 38.237442 42.824177 48.780331 53.367065 58.869492 65.287621 70.328079 75.368538 81.786659">V4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_BOTTOMV4L2_FIELD_BOTTOM</tspan></text>
+<text
+       y="-328.99481"
+       x="10.054964 14.17972 18.766451 20.597849 25.18458 29.771311 34.358047 38.944778 41.238144 43.531509 48.118244 50.865334 53.158699 55.452068 57.283459 61.870193 63.701588 68.288322"
+       id="text7148"
+       style="font-variant:normal;font-weight:normal;font-size:8.2495203px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan7150"
+	 sodipodi:role="line"
+	 y="-328.99481"
+	 x="10.054964 14.17972 18.766451 20.597849 25.18458 29.771311 34.358047 38.944778 41.238144 43.531509 48.118244 50.865334 53.158699 55.452068 57.283459 61.870193 63.701588 68.288322">v4l2_buffer.field:</tspan></text>
+</g></svg>
diff --git a/Documentation/userspace-api/media/v4l/fieldseq_tb.svg b/Documentation/userspace-api/media/v4l/fieldseq_tb.svg
new file mode 100644
index 000000000000..f8b440a1cb60
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/fieldseq_tb.svg
@@ -0,0 +1,2618 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+    Permission is granted to copy, distribute and/or modify this
+    document under the terms of the GNU Free Documentation License,
+    Version 1.1 or any later version published by the Free Software
+    Foundation, with no Invariant Sections, no Front-Cover Texts
+    and no Back-Cover Texts. A copy of the license is included at
+    Documentation/userspace-api/media/fdl-appendix.rst.
+
+    TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+-->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   id="svg5543"
+   version="1.1"
+   inkscape:version="0.91 r13725"
+   xml:space="preserve"
+   width="198.48296mm"
+   height="210.39415mm"
+   viewBox="0 0 703.28607 745.49109"
+   sodipodi:docname="fieldseq_tb.svg"><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="997"
+     id="namedview5545"
+     showgrid="false"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0"
+     units="mm"
+     inkscape:zoom="1.0733333"
+     inkscape:cx="9.8391479"
+     inkscape:cy="370.19322"
+     inkscape:window-x="1920"
+     inkscape:window-y="30"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="g5551" /><metadata
+     id="metadata5549"><rdf:RDF><cc:Work
+	 rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+	   rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
+     id="defs5547"><clipPath
+       id="clipPath6753"
+       clipPathUnits="userSpaceOnUse"><path
+	 style="clip-rule:evenodd"
+	 inkscape:connector-curvature="0"
+	 id="path6755"
+	 d="M 0,6000 0,0 l 5660,0 0,6000 -5660,0 z m 4786.76,-102.89 103.92,0 0,56.69 -103.92,0 0,0 85.03,-28.35 -85.03,-28.34 z" /></clipPath></defs><g
+     transform="matrix(1.25,0,0,-1.25,-1.0537,746.57119)"
+     inkscape:label="fieldseq_tb"
+     inkscape:groupmode="layer"
+     id="g5551"><path
+       d="m 379.944,571.287 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5555"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,571.287 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5557"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,562.784 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5559"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,562.784 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5561"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,554.281 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5563"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,554.281 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5565"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,545.778 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5567"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,545.778 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5569"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,575.539 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5571"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,575.539 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5573"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,567.036 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5575"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,567.036 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5577"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,558.532 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5579"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,558.532 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5581"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,550.029 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5583"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,550.029 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5585"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,575.539 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5587"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,575.539 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5589"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,567.036 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5591"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,567.036 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5593"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,558.532 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5595"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,558.532 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5597"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,550.029 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5599"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,550.029 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5601"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,571.287 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5603"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,571.287 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5605"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,562.784 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5607"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,562.784 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5609"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,554.281 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5611"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,554.281 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5613"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,545.778 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5615"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,545.778 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5617"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,507.513 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5619"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,507.513 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5621"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,499.01 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5623"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,499.01 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5625"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,490.507 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5627"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,490.507 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5629"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,482.004 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5631"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,482.004 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5633"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,511.765 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5635"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,511.765 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5637"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,503.262 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5639"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,503.262 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5641"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,494.759 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5643"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,494.759 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5645"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,486.255 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5647"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,486.255 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5649"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,443.739 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5651"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,443.739 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5653"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,435.236 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5655"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,435.236 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5657"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,426.733 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5659"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,426.733 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5661"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,418.23 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5663"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,418.23 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5665"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,439.488 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5667"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,439.488 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5669"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,430.984 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5671"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,430.984 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5673"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,422.481 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5675"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,422.481 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5677"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,413.978 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5679"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,413.978 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5681"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,218.404 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5683"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,218.404 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5685"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,226.907 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5687"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,226.907 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5689"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,222.656 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5691"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,222.656 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5693"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,235.411 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5695"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,235.411 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5697"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,231.159 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5699"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,231.159 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5701"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,243.914 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5703"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,243.914 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5705"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,239.662 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5707"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,239.662 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5709"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,252.417 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5711"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,252.417 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5713"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,248.166 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5715"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,248.166 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5717"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,260.92 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5719"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,260.92 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5721"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,256.669 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5723"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,256.669 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5725"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,269.423 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5727"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,269.423 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5729"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,265.172 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5731"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,265.172 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5733"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,273.675 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5735"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,273.675 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5737"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,214.153 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5739"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,214.153 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5741"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,277.927 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5743"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,277.927 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5745"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,218.404 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5747"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,218.404 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5749"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,226.907 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5751"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,226.907 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5753"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,222.656 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5755"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,222.656 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5757"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,235.411 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5759"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,235.411 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5761"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,231.159 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5763"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,231.159 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5765"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,243.914 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5767"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,243.914 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5769"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,239.662 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5771"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,239.662 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5773"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,252.417 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5775"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,252.417 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5777"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,248.166 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5779"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,248.166 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5781"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,260.92 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5783"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,260.92 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5785"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,256.669 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5787"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,256.669 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5789"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,269.423 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5791"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,269.423 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5793"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,265.172 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5795"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,265.172 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5797"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,273.675 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5799"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,273.675 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5801"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,214.153 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5803"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,214.153 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5805"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,277.927 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5807"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,277.927 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5809"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,375.714 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5811"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,375.714 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5813"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,367.211 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5815"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,367.211 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5817"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,358.707 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5819"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,358.707 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5821"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,350.204 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5823"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,350.204 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5825"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,371.462 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5827"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,371.462 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5829"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,362.959 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5831"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,362.959 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5833"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,354.455 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5835"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,354.455 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5837"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,345.952 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5839"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,345.952 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5841"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,371.462 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5843"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,371.462 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5845"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,362.959 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5847"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,362.959 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5849"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,354.455 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5851"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,354.455 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5853"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,345.952 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5855"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,345.952 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5857"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,375.714 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5859"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,375.714 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5861"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,367.211 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5863"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,367.211 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5865"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,358.707 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5867"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,358.707 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5869"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,350.204 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5871"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,350.204 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5873"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,35.5855 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5875"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,35.5855 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5877"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,27.0824 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5879"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,27.0824 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5881"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,18.5793 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5883"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,18.5793 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5885"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,10.0762 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5887"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,10.0762 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5889"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,31.334 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5891"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,31.334 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5893"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,22.8309 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5895"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,22.8309 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5897"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,14.3277 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5899"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,14.3277 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5901"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,5.82422 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5903"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,5.82422 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5905"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,35.5855 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5907"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,35.5855 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5909"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,27.0824 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5911"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,27.0824 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5913"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,18.5793 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5915"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,18.5793 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5917"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,10.0762 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5919"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,10.0762 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5921"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,31.334 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5923"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,31.334 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5925"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,22.8309 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5927"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,22.8309 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5929"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,14.3277 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5931"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,14.3277 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5933"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,5.82422 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5935"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,5.82422 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5937"
+       inkscape:connector-curvature="0" /><path
+       d="m 95.0867,409.727 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5939"
+       inkscape:connector-curvature="0" /><path
+       d="m 282.157,409.727 93.5355,0 0,42.516 -93.5355,0 0,-42.516 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5941"
+       inkscape:connector-curvature="0" /><path
+       d="m 469.228,409.727 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5943"
+       inkscape:connector-curvature="0" /><path
+       d="m 469.228,209.901 93.5352,0 0,76.5289 -93.5352,0 0,-76.5289 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5945"
+       inkscape:connector-curvature="0" /><path
+       d="m 282.157,209.901 93.5355,0 0,76.5289 -93.5355,0 0,-76.5289 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5947"
+       inkscape:connector-curvature="0" /><path
+       d="m 95.0867,209.901 93.5352,0 0,76.5289 -93.5352,0 0,-76.5289 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5949"
+       inkscape:connector-curvature="0" /><path
+       d="m 95.0867,341.701 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5951"
+       inkscape:connector-curvature="0" /><path
+       d="m 282.157,341.701 93.5355,0 0,42.516 -93.5355,0 0,-42.516 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5953"
+       inkscape:connector-curvature="0" /><path
+       d="m 469.228,341.701 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5955"
+       inkscape:connector-curvature="0" /><path
+       d="m 1.55156,341.701 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5957"
+       inkscape:connector-curvature="0" /><path
+       d="m 188.622,341.701 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5959"
+       inkscape:connector-curvature="0" /><path
+       d="m 375.693,341.701 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5961"
+       inkscape:connector-curvature="0" /><path
+       d="m 1.55156,477.752 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5963"
+       inkscape:connector-curvature="0" /><path
+       d="m 188.622,477.752 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5965"
+       inkscape:connector-curvature="0" /><path
+       d="m 375.693,477.752 93.5352,0 0,42.516 -93.5352,0 0,-42.516 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5967"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,571.287 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5969"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,571.287 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5971"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,562.784 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5973"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,562.784 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5975"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,554.281 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5977"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,554.281 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5979"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,545.778 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5981"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,545.778 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5983"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,575.539 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5985"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,575.539 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5987"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,567.036 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5989"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,567.036 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5991"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,558.532 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5993"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,558.532 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5995"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,550.029 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path5997"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,550.029 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path5999"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,575.539 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6001"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,575.539 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6003"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,567.036 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6005"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,567.036 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6007"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,558.532 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6009"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,558.532 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6011"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,550.029 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6013"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,550.029 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6015"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,571.287 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6017"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,571.287 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6019"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,562.784 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6021"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,562.784 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6023"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,554.281 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6025"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,554.281 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6027"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,545.778 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6029"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,545.778 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6031"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,507.513 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6033"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,507.513 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6035"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,499.01 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6037"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,499.01 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6039"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,490.507 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6041"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,490.507 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6043"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,482.004 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6045"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,482.004 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6047"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,511.765 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6049"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,511.765 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6051"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,503.262 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6053"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,503.262 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6055"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,494.759 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6057"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,494.759 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6059"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,486.255 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6061"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,486.255 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6063"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,443.739 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6065"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,443.739 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6067"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,435.236 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6069"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,435.236 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6071"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,426.733 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6073"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,426.733 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6075"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,418.23 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6077"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,418.23 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6079"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,439.488 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6081"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,439.488 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6083"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,430.984 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6085"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,430.984 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6087"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,422.481 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6089"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,422.481 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6091"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,413.978 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6093"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,413.978 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6095"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,575.539 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6097"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,575.539 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6099"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,575.539 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6101"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,575.539 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6103"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,571.287 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6105"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,571.287 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6107"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,567.036 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6109"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,567.036 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6111"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,562.784 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6113"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,562.784 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6115"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,558.532 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6117"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,558.532 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6119"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,554.281 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6121"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,554.281 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6123"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,550.029 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6125"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,550.029 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6127"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,545.778 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6129"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,545.778 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6131"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,511.765 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6133"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,511.765 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6135"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,507.513 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6137"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,507.513 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6139"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,503.262 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6141"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,503.262 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6143"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,499.01 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6145"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,499.01 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6147"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,494.759 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6149"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,494.759 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6151"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,490.507 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6153"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,490.507 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6155"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,486.255 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6157"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,486.255 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6159"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,482.004 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6161"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,482.004 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6163"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,375.714 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6165"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,375.714 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6167"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,371.462 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6169"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,371.462 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6171"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,367.211 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6173"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,367.211 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6175"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,362.959 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6177"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,362.959 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6179"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,358.707 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6181"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,358.707 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6183"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,354.455 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6185"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,354.455 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6187"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,350.204 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6189"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,350.204 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6191"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,345.952 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6193"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,345.952 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6195"
+       inkscape:connector-curvature="0" /><path
+       d="m 1.55156,107.863 93.5352,0 0,76.5289 -93.5352,0 0,-76.5289 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6197"
+       inkscape:connector-curvature="0" /><path
+       d="m 188.622,107.863 93.5352,0 0,76.5289 -93.5352,0 0,-76.5289 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6199"
+       inkscape:connector-curvature="0" /><path
+       d="m 375.693,107.863 93.5352,0 0,76.5289 -93.5352,0 0,-76.5289 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6201"
+       inkscape:connector-curvature="0" /><path
+       d="m 95.0867,1.57266 93.5352,0 0,76.5289 -93.5352,0 0,-76.5289 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6203"
+       inkscape:connector-curvature="0" /><path
+       d="m 282.157,1.57266 93.5355,0 0,76.5289 -93.5355,0 0,-76.5289 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6205"
+       inkscape:connector-curvature="0" /><path
+       d="m 469.228,1.57266 93.5352,0 0,76.5289 -93.5352,0 0,-76.5289 z"
+       style="fill:none;stroke:#000000;stroke-width:1.41719997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6207"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,65.3469 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6209"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,65.3469 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6211"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,56.8438 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6213"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,56.8438 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6215"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,48.3402 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6217"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,48.3402 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6219"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,39.8371 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6221"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,39.8371 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6223"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,69.5984 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6225"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,69.5984 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6227"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,61.0953 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6229"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,61.0953 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6231"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,52.5922 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6233"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,52.5922 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6235"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,44.0887 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6237"
+       inkscape:connector-curvature="0" /><path
+       d="m 473.479,44.0887 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6239"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,65.3469 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6241"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,65.3469 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6243"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,56.8438 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6245"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,56.8438 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6247"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,48.3402 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6249"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,48.3402 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6251"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,39.8371 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6253"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,39.8371 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6255"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,69.5984 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6257"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,69.5984 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6259"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,61.0953 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6261"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,61.0953 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6263"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,52.5922 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6265"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,52.5922 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6267"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,44.0887 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6269"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,44.0887 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6271"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,277.927 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6273"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,277.927 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6275"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,269.423 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6277"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,269.423 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6279"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,260.92 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6281"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,260.92 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6283"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,252.417 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6285"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,252.417 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6287"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,243.914 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6289"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,243.914 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6291"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,235.411 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6293"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,235.411 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6295"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,226.907 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6297"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,226.907 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6299"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,218.404 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6301"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,218.404 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6303"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,69.5984 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6305"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,69.5984 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6307"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,65.3469 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6309"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,65.3469 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6311"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,61.0953 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6313"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,61.0953 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6315"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,56.8438 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6317"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,56.8438 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6319"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,52.5922 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6321"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,52.5922 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6323"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,48.3402 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6325"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,48.3402 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6327"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,44.0887 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6329"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,44.0887 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6331"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,39.8371 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6333"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,39.8371 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6335"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,571.287 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6337"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,571.287 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6339"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,567.036 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6341"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,567.036 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6343"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,562.784 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6345"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,562.784 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6347"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,558.532 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6349"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,558.532 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6351"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,554.281 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6353"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,554.281 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6355"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,550.029 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6357"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,550.029 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6359"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,545.778 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6361"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,545.778 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6363"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,443.739 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6365"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,443.739 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6367"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,439.488 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6369"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,439.488 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6371"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,435.236 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6373"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,435.236 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6375"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,430.984 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6377"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,430.984 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6379"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,426.733 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6381"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,426.733 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6383"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,422.481 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6385"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,422.481 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6387"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,418.23 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6389"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,418.23 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6391"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,413.978 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6393"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,413.978 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6395"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,375.714 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6397"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,375.714 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6399"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,371.462 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6401"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,371.462 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6403"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,367.211 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6405"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,367.211 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6407"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,362.959 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6409"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,362.959 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6411"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,358.707 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6413"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,358.707 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6415"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,354.455 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6417"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,354.455 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6419"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,350.204 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6421"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,350.204 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6423"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,345.952 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6425"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,345.952 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6427"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,273.675 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6429"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,273.675 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6431"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,265.172 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6433"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,265.172 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6435"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,256.669 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6437"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,256.669 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6439"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,248.166 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6441"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,248.166 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6443"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,239.662 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6445"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,239.662 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6447"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,231.159 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6449"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,231.159 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6451"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,222.656 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6453"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,222.656 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6455"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,214.153 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6457"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,214.153 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6459"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,35.5855 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6461"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,35.5855 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6463"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,31.334 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6465"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,31.334 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6467"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,27.0824 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6469"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,27.0824 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6471"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,22.8309 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6473"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,22.8309 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6475"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,18.5793 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6477"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,18.5793 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6479"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,14.3277 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6481"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,14.3277 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6483"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,10.0762 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6485"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,10.0762 85.0316,0 0,4.25156 -85.0316,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6487"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,5.82422 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6489"
+       inkscape:connector-curvature="0" /><path
+       d="m 286.409,5.82422 85.0316,0 0,4.25195 -85.0316,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6491"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,175.888 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6493"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,175.888 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6495"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,167.385 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6497"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,167.385 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6499"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,158.882 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6501"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,158.882 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6503"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,150.379 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6505"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,150.379 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6507"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,141.876 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6509"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,141.876 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6511"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,133.372 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6513"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,133.372 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6515"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,124.869 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6517"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,124.869 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6519"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,116.366 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#008f00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6521"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,116.366 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6523"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,371.462 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6525"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,371.462 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6527"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,362.959 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6529"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,362.959 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6531"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,354.455 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6533"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,354.455 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6535"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,345.952 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6537"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,345.952 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6539"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,375.714 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6541"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,375.714 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6543"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,367.211 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6545"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,367.211 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6547"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,358.707 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6549"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,358.707 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6551"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,350.204 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6553"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,350.204 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6555"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,175.888 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6557"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,175.888 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6559"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,167.385 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6561"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,167.385 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6563"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,158.882 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6565"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,158.882 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6567"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,150.379 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6569"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,150.379 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6571"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,141.876 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6573"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,141.876 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6575"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,133.372 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6577"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,133.372 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6579"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,124.869 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6581"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,124.869 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6583"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,116.366 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6585"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,116.366 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6587"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,175.888 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6589"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,175.888 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6591"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,167.385 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6593"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,167.385 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6595"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,158.882 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6597"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,158.882 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6599"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,150.379 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6601"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,150.379 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6603"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,141.876 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6605"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,141.876 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6607"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,133.372 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6609"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,133.372 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6611"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,124.869 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6613"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,124.869 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6615"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,116.366 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#d10000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6617"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,116.366 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6619"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,375.714 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6621"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,375.714 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6623"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,367.211 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6625"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,367.211 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6627"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,358.707 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6629"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,358.707 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6631"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,350.204 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6633"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,350.204 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6635"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,371.462 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6637"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,371.462 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6639"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,362.959 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6641"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,362.959 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6643"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,354.455 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6645"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,354.455 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6647"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,345.952 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6649"
+       inkscape:connector-curvature="0" /><path
+       d="m 99.3383,345.952 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6651"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,171.637 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6653"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,171.637 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6655"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,163.134 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6657"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,163.134 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6659"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,154.63 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6661"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,154.63 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6663"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,146.127 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6665"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,146.127 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6667"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,137.624 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6669"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,137.624 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6671"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,129.121 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6673"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,129.121 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6675"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,120.618 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6677"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,120.618 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6679"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,112.114 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#0000d1;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6681"
+       inkscape:connector-curvature="0" /><path
+       d="m 192.873,112.114 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6683"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,171.637 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6685"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,171.637 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6687"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,163.134 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6689"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,163.134 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6691"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,154.63 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6693"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,154.63 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6695"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,146.127 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6697"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,146.127 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6699"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,137.624 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6701"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,137.624 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6703"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,129.121 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6705"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,129.121 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6707"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,120.618 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6709"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,120.618 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6711"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,112.114 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6713"
+       inkscape:connector-curvature="0" /><path
+       d="m 379.944,112.114 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6715"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,171.637 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6717"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,171.637 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6719"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,163.134 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6721"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,163.134 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6723"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,154.63 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6725"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,154.63 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6727"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,146.127 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6729"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,146.127 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6731"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,137.624 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6733"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,137.624 85.032,0 0,4.25195 -85.032,0 0,-4.25195 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6735"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,129.121 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6737"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,129.121 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6739"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,120.618 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6741"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,120.618 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6743"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,112.114 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6745"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.80312,112.114 85.032,0 0,4.25156 -85.032,0 0,-4.25156 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6747"
+       inkscape:connector-curvature="0" /><g
+       transform="scale(0.1,0.1)"
+       id="g6749"
+       style=""><g
+	 id="g6751"
+	 clip-path="url(#clipPath6753)"
+	 style=""><path
+	   d="m 3778.18,5925.45 1105.42,0"
+	   style="fill:none;stroke:#000000;stroke-width:14.17199993;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	   id="path6757"
+	   inkscape:connector-curvature="0" /></g></g><path
+       d="m 478.676,589.711 8.503,2.834 -8.503,2.835 0,-5.669"
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path6759"
+       inkscape:connector-curvature="0" /><path
+       d="m 478.676,589.711 8.503,2.834 -8.503,2.835 0,-5.669 z"
+       style="fill:none;stroke:#000000;stroke-width:0.35429999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path6761"
+       inkscape:connector-curvature="0" /><text
+       y="-528.771"
+       x="5.8031301"
+       id="text6765"
+       style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan6767"
+	 sodipodi:role="line"
+	 y="-528.771"
+	 x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 88.500237 97.835464">V4L2_FIELD_TOP</tspan><tspan
+	 id="tspan6769"
+	 sodipodi:role="line"
+	 y="-460.74561"
+	 x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 98.507408 105.83879 113.17018 122.5054">V4L2_FIELD_BOTTOM</tspan><tspan
+	 id="tspan6771"
+	 sodipodi:role="line"
+	 y="-392.72021"
+	 x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 95.843628 103.17502 111.17835 119.84163 128.5049 136.50824 143.83963">V4L2_FIELD_ALTERNATE</tspan></text>
+<text
+       y="-324.69479"
+       x="10.05469"
+       id="text6773"
+       style="font-variant:normal;font-weight:normal;font-size:8.2495203px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan6775"
+	 sodipodi:role="line"
+	 y="-324.69479"
+	 x="10.05469 14.17945 18.766184 20.597576 25.184309 29.771042 34.357777 38.944508 41.237877 43.531242 48.117977 50.865067 53.158432 55.451801 57.283192 61.869926 63.701321 68.288048">v4l2_buffer.field:</tspan><tspan
+	 id="tspan6777"
+	 sodipodi:role="line"
+	 y="-311.9397"
+	 x="10.05469 15.55712 20.143852 24.730585 29.317318 33.904053 38.944508 41.237877 46.740307 51.327042 57.283192 61.869926 66.910378 73.328506 95.0867 100.58913 105.17586 109.7626 114.34933 118.93606 123.97652 126.26987 131.77232 136.35905 142.3152 146.90193 152.40436 158.82249 163.86295 168.9034 175.32153 197.12534 202.62778 207.21451 211.80124 216.38797 220.9747 226.01515 228.30853 233.81096 238.39769 244.35384 248.94058 253.98103 260.39917 282.15695 287.65936 292.24609 296.83282 301.41956 306.00629 311.04675 313.34012 318.84256 323.42929 329.38544 333.97217 339.47461 345.89273 350.9332 355.97363 362.39175 384.19559 389.698 394.28473 398.87149 403.45822 408.04495 413.08539 415.37875 420.8812 425.46793 431.42407 436.0108 441.05127 447.46939 469.2276 474.73001 479.31674 483.90347 488.49023 493.07697 498.1174 500.41077 505.91321 510.49994 516.45612 521.04285 526.54523 532.96338
+538.00385 543.04431 549.4624">V4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_TOPV4L2_FIELD_BOTTOM</tspan></text>
+<text
+       y="-588.2937"
+       x="5.8031301"
+       id="text6779"
+       style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan6781"
+	 sodipodi:role="line"
+	 y="-588.2937"
+	 x="5.8031301 13.134519 19.805964 29.801128 36.472572 43.14402 47.139687 53.811131 56.474907 59.810631 66.482071 70.477737 77.149185 83.820625 87.816299 91.152016 94.48774 97.823463 104.4949 111.16635 114.50207 117.83779 120.50157 127.17302 129.83679 136.50824 139.84396 143.17969 145.84346 149.83913 155.83862 159.17435 162.51007 165.84579 169.84146 176.51291 183.18434 189.18385 199.17902 201.84279 205.17851 208.51424 215.18568 221.85713 225.19284 229.18851 235.85995 239.19568 245.86713 249.20285 252.53857 260.5419 269.87714 273.21286 281.21619 289.21951 295.89096">Temporal order, top field first transmitted (e.g. BG/PAL)</tspan><tspan
+	 id="tspan6783"
+	 sodipodi:role="line"
+	 y="-86.604706"
+	 x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 97.175514 106.51073 113.18218 120.51357">V4L2_FIELD_SEQ_TB</tspan><tspan
+	 id="tspan6785"
+	 sodipodi:role="line"
+	 y="-192.89471"
+	 x="10.05469 18.058023 24.729465 31.400909 38.072357 44.743801 52.075188 55.410912 63.414246 70.085686 78.748962 85.42041 88.756134 97.419411 104.7508 112.75413 121.41741 128.08885 136.09219 144.75546 152.7588 161.42207 168.09352 176.09685 183.42824 186.76396 190.75963 200.75479 203.41858 209.41808 216.08952 218.7533 221.41707 228.08852 234.75996 241.43141 248.10286">V4L2_FIELD_INTERLACED_BT (misaligned)</tspan><tspan
+	 id="tspan6787"
+	 sodipodi:role="line"
+	 y="-294.93271"
+	 x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 84.50457 93.167847 100.49924 108.50257 117.16585 123.83729 131.84062 140.50391 148.50723 157.17052 160.50624 163.84196 167.17769 175.18102 181.85246 188.52391 195.19534 201.86679 209.19818 212.53391 220.53723 227.20868 235.87196 242.5434 245.87912 254.5424 261.87378 269.87714 278.54041 285.21185 293.21518 301.87845 309.88177 318.54507 325.21652 332.54791">V4L2_FIELD_INTERLACED / V4L2_FIELD_INTERLACED_TB</tspan></text>
+<text
+       y="-528.771"
+       x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 88.500237 97.835464"
+       id="text4583"
+       style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan4585"
+	 sodipodi:role="line"
+	 y="-528.771"
+	 x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 88.500237 97.835464">V4L2_FIELD_TOP</tspan></text>
+<text
+       y="-460.74561"
+       x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 98.507408 105.83879 113.17018 122.5054"
+       id="text4587"
+       style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan4589"
+	 sodipodi:role="line"
+	 y="-460.74561"
+	 x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 98.507408 105.83879 113.17018 122.5054">V4L2_FIELD_BOTTOM</tspan></text>
+<text
+       y="-392.72021"
+       x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 95.843628 103.17502 111.17835 119.84163 128.5049 136.50824 143.83963"
+       id="text4591"
+       style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan4593"
+	 sodipodi:role="line"
+	 y="-392.72021"
+	 x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 95.843628 103.17502 111.17835 119.84163 128.5049 136.50824 143.83963">V4L2_FIELD_ALTERNATE</tspan></text>
+<text
+       y="-588.2937"
+       x="5.8031301 13.134519 19.805964 29.801128 36.472572 43.14402 47.139687 53.811131 56.474907 59.810631 66.482071 70.477737 77.149185 83.820625 87.816299 91.152016 94.48774 97.823463 104.4949 111.16635 114.50207 117.83779 120.50157 127.17302 129.83679 136.50824 139.84396 143.17969 145.84346 149.83913 155.83862 159.17435 162.51007 165.84579 169.84146 176.51291 183.18434 189.18385 199.17902 201.84279 205.17851 208.51424 215.18568 221.85713 225.19284 229.18851 235.85995 239.19568 245.86713 249.20285 252.53857 260.5419 269.87714 273.21286 281.21619 289.21951 295.89096"
+       id="text5847"
+       style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan5849"
+	 sodipodi:role="line"
+	 y="-588.2937"
+	 x="5.8031301 13.134519 19.805964 29.801128 36.472572 43.14402 47.139687 53.811131 56.474907 59.810631 66.482071 70.477737 77.149185 83.820625 87.816299 91.152016 94.48774 97.823463 104.4949 111.16635 114.50207 117.83779 120.50157 127.17302 129.83679 136.50824 139.84396 143.17969 145.84346 149.83913 155.83862 159.17435 162.51007 165.84579 169.84146 176.51291 183.18434 189.18385 199.17902 201.84279 205.17851 208.51424 215.18568 221.85713 225.19284 229.18851 235.85995 239.19568 245.86713 249.20285 252.53857 260.5419 269.87714 273.21286 281.21619 289.21951 295.89096">Temporal order, top field first transmitted (e.g. BG/PAL)</tspan></text>
+<text
+       y="-86.604706"
+       x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 97.175514 106.51073 113.18218 120.51357"
+       id="text5851"
+       style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan5853"
+	 sodipodi:role="line"
+	 y="-86.604706"
+	 x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 97.175514 106.51073 113.18218 120.51357">V4L2_FIELD_SEQ_TB</tspan></text>
+<text
+       y="-192.89471"
+       x="10.05469 18.058023 24.729465 31.400909 38.072357 44.743801 52.075188 55.410912 63.414246 70.085686 78.748962 85.42041 88.756134 97.419411 104.7508 112.75413 121.41741 128.08885 136.09219 144.75546 152.7588 161.42207 168.09352 176.09685 183.42824 186.76396 190.75963 200.75479 203.41858 209.41808 216.08952 218.7533 221.41707 228.08852 234.75996 241.43141 248.10286"
+       id="text5855"
+       style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan5857"
+	 sodipodi:role="line"
+	 y="-192.89471"
+	 x="10.05469 18.058023 24.729465 31.400909 38.072357 44.743801 52.075188 55.410912 63.414246 70.085686 78.748962 85.42041 88.756134 97.419411 104.7508 112.75413 121.41741 128.08885 136.09219 144.75546 152.7588 161.42207 168.09352 176.09685 183.42824 186.76396 190.75963 200.75479 203.41858 209.41808 216.08952 218.7533 221.41707 228.08852 234.75996 241.43141 248.10286">V4L2_FIELD_INTERLACED_BT (misaligned)</tspan></text>
+<text
+       y="-294.93271"
+       x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 84.50457 93.167847 100.49924 108.50257 117.16585 123.83729 131.84062 140.50391 148.50723 157.17052 160.50624 163.84196 167.17769 175.18102 181.85246 188.52391 195.19534 201.86679 209.19818 212.53391 220.53723 227.20868 235.87196 242.5434 245.87912 254.5424 261.87378 269.87714 278.54041 285.21185 293.21518 301.87845 309.88177 318.54507 325.21652 332.54791"
+       id="text5859"
+       style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan5861"
+	 sodipodi:role="line"
+	 y="-294.93271"
+	 x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 84.50457 93.167847 100.49924 108.50257 117.16585 123.83729 131.84062 140.50391 148.50723 157.17052 160.50624 163.84196 167.17769 175.18102 181.85246 188.52391 195.19534 201.86679 209.19818 212.53391 220.53723 227.20868 235.87196 242.5434 245.87912 254.5424 261.87378 269.87714 278.54041 285.21185 293.21518 301.87845 309.88177 318.54507 325.21652 332.54791">V4L2_FIELD_INTERLACED / V4L2_FIELD_INTERLACED_TB</tspan></text>
+<text
+       y="-324.69479"
+       x="10.05469 14.17945 18.766184 20.597576 25.184309 29.771042 34.357777 38.944508 41.237877 43.531242 48.117977 50.865067 53.158432 55.451801 57.283192 61.869926 63.701321 68.288048"
+       id="text7131"
+       style="font-variant:normal;font-weight:normal;font-size:8.2495203px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan7133"
+	 sodipodi:role="line"
+	 y="-324.69479"
+	 x="10.05469 14.17945 18.766184 20.597576 25.184309 29.771042 34.357777 38.944508 41.237877 43.531242 48.117977 50.865067 53.158432 55.451801 57.283192 61.869926 63.701321 68.288048">v4l2_buffer.field:</tspan></text>
+<text
+       y="-311.9397"
+       x="10.05469 15.55712 20.143852 24.730585 29.317318 33.904053 38.944508 41.237877 46.740307 51.327042 57.283192 61.869926 66.910378 73.328506 95.0867 100.58913 105.17586 109.7626 114.34933 118.93606 123.97652 126.26987 131.77232 136.35905 142.3152 146.90193 152.40436 158.82249 163.86295 168.9034 175.32153 197.12534 202.62778 207.21451 211.80124 216.38797 220.9747 226.01515 228.30853 233.81096 238.39769 244.35384 248.94058 253.98103 260.39917 282.15695 287.65936 292.24609 296.83282 301.41956 306.00629 311.04675 313.34012 318.84256 323.42929 329.38544 333.97217 339.47461 345.89273 350.9332 355.97363 362.39175 384.19559 389.698 394.28473 398.87149 403.45822 408.04495 413.08539 415.37875 420.8812 425.46793 431.42407 436.0108 441.05127 447.46939 469.2276 474.73001 479.31674 483.90347 488.49023 493.07697 498.1174 500.41077 505.91321 510.49994 516.45612 521.04285 526.54523 532.96338
+538.00385 543.04431 549.4624"
+       id="text7135"
+       style="font-variant:normal;font-weight:normal;font-size:8.2495203px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan7137"
+	 sodipodi:role="line"
+	 y="-311.9397"
+	 x="10.05469 15.55712 20.143852 24.730585 29.317318 33.904053 38.944508 41.237877 46.740307 51.327042 57.283192 61.869926 66.910378 73.328506 95.0867 100.58913 105.17586 109.7626 114.34933 118.93606 123.97652 126.26987 131.77232 136.35905 142.3152 146.90193 152.40436 158.82249 163.86295 168.9034 175.32153 197.12534 202.62778 207.21451 211.80124 216.38797 220.9747 226.01515 228.30853 233.81096 238.39769 244.35384 248.94058 253.98103 260.39917 282.15695 287.65936 292.24609 296.83282 301.41956 306.00629 311.04675 313.34012 318.84256 323.42929 329.38544 333.97217 339.47461 345.89273 350.9332 355.97363 362.39175 384.19559 389.698 394.28473 398.87149 403.45822 408.04495 413.08539 415.37875 420.8812 425.46793 431.42407 436.0108 441.05127 447.46939 469.2276 474.73001 479.31674 483.90347 488.49023 493.07697 498.1174 500.41077 505.91321 510.49994 516.45612 521.04285 526.54523 532.96338
+538.00385 543.04431 549.4624">V4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_TOPV4L2_FIELD_BOTTOM</tspan></text>
+</g></svg>
diff --git a/Documentation/userspace-api/media/v4l/format.rst b/Documentation/userspace-api/media/v4l/format.rst
new file mode 100644
index 000000000000..e47fc0505727
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/format.rst
@@ -0,0 +1,99 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _format:
+
+************
+Data Formats
+************
+
+
+Data Format Negotiation
+=======================
+
+Different devices exchange different kinds of data with applications,
+for example video images, raw or sliced VBI data, RDS datagrams. Even
+within one kind many different formats are possible, in particular there is an
+abundance of image formats. Although drivers must provide a default and
+the selection persists across closing and reopening a device,
+applications should always negotiate a data format before engaging in
+data exchange. Negotiation means the application asks for a particular
+format and the driver selects and reports the best the hardware can do
+to satisfy the request. Of course applications can also just query the
+current selection.
+
+A single mechanism exists to negotiate all data formats using the
+aggregate struct :c:type:`v4l2_format` and the
+:ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` and
+:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctls. Additionally the
+:ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` ioctl can be used to examine
+what the hardware *could* do, without actually selecting a new data
+format. The data formats supported by the V4L2 API are covered in the
+respective device section in :ref:`devices`. For a closer look at
+image formats see :ref:`pixfmt`.
+
+The :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl is a major turning-point in the
+initialization sequence. Prior to this point multiple panel applications
+can access the same device concurrently to select the current input,
+change controls or modify other properties. The first :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`
+assigns a logical stream (video data, VBI data etc.) exclusively to one
+file descriptor.
+
+Exclusive means no other application, more precisely no other file
+descriptor, can grab this stream or change device properties
+inconsistent with the negotiated parameters. A video standard change for
+example, when the new standard uses a different number of scan lines,
+can invalidate the selected image format. Therefore only the file
+descriptor owning the stream can make invalidating changes. Accordingly
+multiple file descriptors which grabbed different logical streams
+prevent each other from interfering with their settings. When for
+example video overlay is about to start or already in progress,
+simultaneous video capturing may be restricted to the same cropping and
+image size.
+
+When applications omit the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl its locking side
+effects are implied by the next step, the selection of an I/O method
+with the :ref:`VIDIOC_REQBUFS` ioctl or implicit
+with the first :ref:`read() <func-read>` or
+:ref:`write() <func-write>` call.
+
+Generally only one logical stream can be assigned to a file descriptor,
+the exception being drivers permitting simultaneous video capturing and
+overlay using the same file descriptor for compatibility with V4L and
+earlier versions of V4L2. Switching the logical stream or returning into
+"panel mode" is possible by closing and reopening the device. Drivers
+*may* support a switch using :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`.
+
+All drivers exchanging data with applications must support the
+:ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` and :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl. Implementation of the
+:ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` is highly recommended but optional.
+
+
+Image Format Enumeration
+========================
+
+Apart of the generic format negotiation functions a special ioctl to
+enumerate all image formats supported by video capture, overlay or
+output devices is available. [#f1]_
+
+The :ref:`VIDIOC_ENUM_FMT` ioctl must be supported
+by all drivers exchanging image data with applications.
+
+.. important::
+
+    Drivers are not supposed to convert image formats in kernel space.
+    They must enumerate only formats directly supported by the hardware.
+    If necessary driver writers should publish an example conversion
+    routine or library for integration into applications.
+
+.. [#f1]
+   Enumerating formats an application has no a-priori knowledge of
+   (otherwise it could explicitly ask for them and need not enumerate)
+   seems useless, but there are applications serving as proxy between
+   drivers and the actual video applications for which this is useful.
diff --git a/Documentation/userspace-api/media/v4l/fourcc.rst b/Documentation/userspace-api/media/v4l/fourcc.rst
new file mode 100644
index 000000000000..d3482c40da62
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/fourcc.rst
@@ -0,0 +1,32 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Guidelines for Video4Linux pixel format 4CCs
+============================================
+
+Guidelines for Video4Linux 4CC codes defined using v4l2_fourcc() are
+specified in this document. First of the characters defines the nature of
+the pixel format, compression and colour space. The interpretation of the
+other three characters depends on the first one.
+
+Existing 4CCs may not obey these guidelines.
+
+Raw bayer
+---------
+
+The following first characters are used by raw bayer formats:
+
+- B: raw bayer, uncompressed
+- b: raw bayer, DPCM compressed
+- a: A-law compressed
+- u: u-law compressed
+
+2nd character: pixel order
+
+- B: BGGR
+- G: GBRG
+- g: GRBG
+- R: RGGB
+
+3rd character: uncompressed bits-per-pixel 0--9, A--
+
+4th character: compressed bits-per-pixel 0--9, A--
diff --git a/Documentation/userspace-api/media/v4l/func-close.rst b/Documentation/userspace-api/media/v4l/func-close.rst
new file mode 100644
index 000000000000..37a64dae56b0
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/func-close.rst
@@ -0,0 +1,56 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _func-close:
+
+************
+V4L2 close()
+************
+
+Name
+====
+
+v4l2-close - Close a V4L2 device
+
+
+Synopsis
+========
+
+.. code-block:: c
+
+    #include <unistd.h>
+
+
+.. c:function:: int close( int fd )
+    :name: v4l2-close
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+
+Description
+===========
+
+Closes the device. Any I/O in progress is terminated and resources
+associated with the file descriptor are freed. However data format
+parameters, current input or output, control values or other properties
+remain unchanged.
+
+
+Return Value
+============
+
+The function returns 0 on success, -1 on failure and the ``errno`` is
+set appropriately. Possible error codes:
+
+EBADF
+    ``fd`` is not a valid open file descriptor.
diff --git a/Documentation/userspace-api/media/v4l/func-ioctl.rst b/Documentation/userspace-api/media/v4l/func-ioctl.rst
new file mode 100644
index 000000000000..4e69f303636b
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/func-ioctl.rst
@@ -0,0 +1,69 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _func-ioctl:
+
+************
+V4L2 ioctl()
+************
+
+Name
+====
+
+v4l2-ioctl - Program a V4L2 device
+
+
+Synopsis
+========
+
+.. code-block:: c
+
+    #include <sys/ioctl.h>
+
+
+.. c:function:: int ioctl( int fd, int request, void *argp )
+    :name: v4l2-ioctl
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``request``
+    V4L2 ioctl request code as defined in the ``videodev2.h`` header
+    file, for example VIDIOC_QUERYCAP.
+
+``argp``
+    Pointer to a function parameter, usually a structure.
+
+
+Description
+===========
+
+The :ref:`ioctl() <func-ioctl>` function is used to program V4L2 devices. The
+argument ``fd`` must be an open file descriptor. An ioctl ``request``
+has encoded in it whether the argument is an input, output or read/write
+parameter, and the size of the argument ``argp`` in bytes. Macros and
+defines specifying V4L2 ioctl requests are located in the
+``videodev2.h`` header file. Applications should use their own copy, not
+include the version in the kernel sources on the system they compile on.
+All V4L2 ioctl requests, their respective function and parameters are
+specified in :ref:`user-func`.
+
+
+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.
+
+When an ioctl that takes an output or read/write parameter fails, the
+parameter remains unmodified.
diff --git a/Documentation/userspace-api/media/v4l/func-mmap.rst b/Documentation/userspace-api/media/v4l/func-mmap.rst
new file mode 100644
index 000000000000..f9c77bdce434
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/func-mmap.rst
@@ -0,0 +1,148 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _func-mmap:
+
+***********
+V4L2 mmap()
+***********
+
+Name
+====
+
+v4l2-mmap - Map device memory into application address space
+
+
+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: v4l2-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 the same value as
+    returned by the driver in the struct
+    :c:type:`v4l2_buffer` ``length`` field for the
+    single-planar API, and the same value as returned by the driver in
+    the struct :c:type:`v4l2_plane` ``length`` field for
+    the multi-planar API.
+
+``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.
+
+    .. note::
+
+      #. The Linux ``videobuf`` kernel module, which is used by some
+	 drivers supports only ``PROT_READ`` | ``PROT_WRITE``. When the
+	 driver does not support the desired protection, the
+	 :ref:`mmap() <func-mmap>` function fails.
+
+      #. Device memory accesses (e. g. the memory on a graphics card
+	 with video capturing hardware) may incur a performance penalty
+	 compared to main memory accesses, or reads may be significantly
+	 slower than writes or vice versa. Other I/O methods may be more
+	 efficient in such case.
+
+``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() <func-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 ``videobuf`` module  which is used by some
+       drivers supports only ``MAP_SHARED``. ``MAP_PRIVATE`` requests
+       copy-on-write semantics. V4L2 applications should not set the
+       ``MAP_PRIVATE``, ``MAP_DENYWRITE``, ``MAP_EXECUTABLE`` or ``MAP_ANON``
+       flags.
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``offset``
+    Offset of the buffer in device memory. This must be the same value
+    as returned by the driver in the struct
+    :c:type:`v4l2_buffer` ``m`` union ``offset`` field for
+    the single-planar API, and the same value as returned by the driver
+    in the struct :c:type:`v4l2_plane` ``m`` union
+    ``mem_offset`` field for the multi-planar API.
+
+
+Description
+===========
+
+The :ref:`mmap() <func-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:`VIDIOC_QUERYBUF` ioctl. Buffers must be
+allocated with the :ref:`VIDIOC_REQBUFS` ioctl
+before they can be queried.
+
+To unmap buffers the :ref:`munmap() <func-munmap>` function is used.
+
+
+Return Value
+============
+
+On success :ref:`mmap() <func-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:`VIDIOC_REQBUFS` ioctl.
+
+ENOMEM
+    Not enough physical or virtual memory was available to complete the
+    request.
diff --git a/Documentation/userspace-api/media/v4l/func-munmap.rst b/Documentation/userspace-api/media/v4l/func-munmap.rst
new file mode 100644
index 000000000000..18a9941b47ab
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/func-munmap.rst
@@ -0,0 +1,65 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _func-munmap:
+
+*************
+V4L2 munmap()
+*************
+
+Name
+====
+
+v4l2-munmap - Unmap device memory
+
+
+Synopsis
+========
+
+.. code-block:: c
+
+    #include <unistd.h>
+    #include <sys/mman.h>
+
+
+.. c:function:: int munmap( void *start, size_t length )
+    :name: v4l2-munmap
+
+Arguments
+=========
+
+``start``
+    Address of the mapped buffer as returned by the
+    :ref:`mmap() <func-mmap>` function.
+
+``length``
+    Length of the mapped buffer. This must be the same value as given to
+    :ref:`mmap() <func-mmap>` and returned by the driver in the struct
+    :c:type:`v4l2_buffer` ``length`` field for the
+    single-planar API and in the struct
+    :c:type:`v4l2_plane` ``length`` field for the
+    multi-planar API.
+
+
+Description
+===========
+
+Unmaps a previously with the :ref:`mmap() <func-mmap>` function mapped
+buffer and frees it, if possible.
+
+
+Return Value
+============
+
+On success :ref:`munmap() <func-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/userspace-api/media/v4l/func-open.rst b/Documentation/userspace-api/media/v4l/func-open.rst
new file mode 100644
index 000000000000..8bcdec8ab387
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/func-open.rst
@@ -0,0 +1,90 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _func-open:
+
+***********
+V4L2 open()
+***********
+
+Name
+====
+
+v4l2-open - Open a V4L2 device
+
+
+Synopsis
+========
+
+.. code-block:: c
+
+    #include <fcntl.h>
+
+
+.. c:function:: int open( const char *device_name, int flags )
+    :name: v4l2-open
+
+Arguments
+=========
+
+``device_name``
+    Device to be opened.
+
+``flags``
+    Open flags. Access mode must be ``O_RDWR``. This is just a
+    technicality, input devices still support only reading and output
+    devices only writing.
+
+    When the ``O_NONBLOCK`` flag is given, the :ref:`read() <func-read>`
+    function and the :ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl will
+    return the ``EAGAIN`` error code when no data is available or no
+    buffer is in the driver outgoing queue, otherwise these functions
+    block until data becomes available. All V4L2 drivers exchanging data
+    with applications must support the ``O_NONBLOCK`` flag.
+
+    Other flags have no effect.
+
+
+Description
+===========
+
+To open a V4L2 device applications call :ref:`open() <func-open>` with the
+desired device name. This function has no side effects; all data format
+parameters, current input or output, control values or other properties
+remain unchanged. At the first :ref:`open() <func-open>` call after loading the
+driver they will be reset to default values, drivers are never in an
+undefined state.
+
+
+Return Value
+============
+
+On success :ref:`open() <func-open>` returns the new file descriptor. On error
+-1 is returned, and the ``errno`` variable is set appropriately.
+Possible error codes are:
+
+EACCES
+    The caller has no permission to access the device.
+
+EBUSY
+    The driver does not support multiple opens and the device is already
+    in use.
+
+ENXIO
+    No device corresponding to this device special file exists.
+
+ENOMEM
+    Not enough kernel memory was available to complete the request.
+
+EMFILE
+    The process already has the maximum number of files open.
+
+ENFILE
+    The limit on the total number of files open on the system has been
+    reached.
diff --git a/Documentation/userspace-api/media/v4l/func-poll.rst b/Documentation/userspace-api/media/v4l/func-poll.rst
new file mode 100644
index 000000000000..2c6704c1fab7
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/func-poll.rst
@@ -0,0 +1,124 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _func-poll:
+
+***********
+V4L2 poll()
+***********
+
+Name
+====
+
+v4l2-poll - Wait for some event on a file descriptor
+
+
+Synopsis
+========
+
+.. code-block:: c
+
+    #include <sys/poll.h>
+
+
+.. c:function:: int poll( struct pollfd *ufds, unsigned int nfds, int timeout )
+    :name: v4l2-poll
+
+Arguments
+=========
+
+
+
+Description
+===========
+
+With the :ref:`poll() <func-poll>` function applications can suspend execution
+until the driver has captured data or is ready to accept data for
+output.
+
+When streaming I/O has been negotiated this function waits until a
+buffer has been filled by the capture device and can be dequeued with
+the :ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl. For output devices this
+function waits until the device is ready to accept a new buffer to be
+queued up with the :ref:`VIDIOC_QBUF <VIDIOC_QBUF>` ioctl for
+display. When buffers are already in the outgoing queue of the driver
+(capture) or the incoming queue isn't full (display) the function
+returns immediately.
+
+On success :ref:`poll() <func-poll>` returns the number of file descriptors
+that have been selected (that is, file descriptors for which the
+``revents`` field of the respective :c:func:`struct pollfd` structure
+is non-zero). Capture devices set the ``POLLIN`` and ``POLLRDNORM``
+flags in the ``revents`` field, output devices the ``POLLOUT`` and
+``POLLWRNORM`` flags. When the function timed out it returns a value of
+zero, on failure it returns -1 and the ``errno`` variable is set
+appropriately. When the application did not call
+:ref:`VIDIOC_STREAMON <VIDIOC_STREAMON>` the :ref:`poll() <func-poll>`
+function succeeds, but sets the ``POLLERR`` flag in the ``revents``
+field. When the application has called
+:ref:`VIDIOC_STREAMON <VIDIOC_STREAMON>` for a capture device but
+hasn't yet called :ref:`VIDIOC_QBUF <VIDIOC_QBUF>`, the
+:ref:`poll() <func-poll>` function succeeds and sets the ``POLLERR`` flag in
+the ``revents`` field. For output devices this same situation will cause
+:ref:`poll() <func-poll>` to succeed as well, but it sets the ``POLLOUT`` and
+``POLLWRNORM`` flags in the ``revents`` field.
+
+If an event occurred (see :ref:`VIDIOC_DQEVENT`)
+then ``POLLPRI`` will be set in the ``revents`` field and
+:ref:`poll() <func-poll>` will return.
+
+When use of the :ref:`read() <func-read>` function has been negotiated and the
+driver does not capture yet, the :ref:`poll() <func-poll>` function starts
+capturing. When that fails it returns a ``POLLERR`` as above. Otherwise
+it waits until data has been captured and can be read. When the driver
+captures continuously (as opposed to, for example, still images) the
+function may return immediately.
+
+When use of the :ref:`write() <func-write>` function has been negotiated and the
+driver does not stream yet, the :ref:`poll() <func-poll>` function starts
+streaming. When that fails it returns a ``POLLERR`` as above. Otherwise
+it waits until the driver is ready for a non-blocking
+:ref:`write() <func-write>` call.
+
+If the caller is only interested in events (just ``POLLPRI`` is set in
+the ``events`` field), then :ref:`poll() <func-poll>` will *not* start
+streaming if the driver does not stream yet. This makes it possible to
+just poll for events and not for buffers.
+
+All drivers implementing the :ref:`read() <func-read>` or :ref:`write() <func-write>`
+function or streaming I/O must also support the :ref:`poll() <func-poll>`
+function.
+
+For more details see the :ref:`poll() <func-poll>` manual page.
+
+
+Return Value
+============
+
+On success, :ref:`poll() <func-poll>` returns the number structures which have
+non-zero ``revents`` fields, or zero if the call timed out. On error -1
+is returned, and the ``errno`` variable is set appropriately:
+
+EBADF
+    One or more of the ``ufds`` members specify an invalid file
+    descriptor.
+
+EBUSY
+    The driver does not support multiple read or write streams and the
+    device is already in use.
+
+EFAULT
+    ``ufds`` references an inaccessible memory area.
+
+EINTR
+    The call was interrupted by a signal.
+
+EINVAL
+    The ``nfds`` value exceeds the ``RLIMIT_NOFILE`` value. Use
+    ``getrlimit()`` to obtain this value.
diff --git a/Documentation/userspace-api/media/v4l/func-read.rst b/Documentation/userspace-api/media/v4l/func-read.rst
new file mode 100644
index 000000000000..1728aa5d8313
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/func-read.rst
@@ -0,0 +1,140 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _func-read:
+
+***********
+V4L2 read()
+***********
+
+Name
+====
+
+v4l2-read - Read from a V4L2 device
+
+
+Synopsis
+========
+
+.. code-block:: c
+
+    #include <unistd.h>
+
+
+.. c:function:: ssize_t read( int fd, void *buf, size_t count )
+    :name: v4l2-read
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``buf``
+   Buffer to be filled
+
+``count``
+  Max number of bytes to read
+
+Description
+===========
+
+:ref:`read() <func-read>` attempts to read up to ``count`` bytes from file
+descriptor ``fd`` into the buffer starting at ``buf``. The layout of the
+data in the buffer is discussed in the respective device interface
+section, see ##. If ``count`` is zero, :ref:`read() <func-read>` returns zero
+and has no other results. If ``count`` is greater than ``SSIZE_MAX``,
+the result is unspecified. Regardless of the ``count`` value each
+:ref:`read() <func-read>` call will provide at most one frame (two fields)
+worth of data.
+
+By default :ref:`read() <func-read>` blocks until data becomes available. When
+the ``O_NONBLOCK`` flag was given to the :ref:`open() <func-open>`
+function it returns immediately with an ``EAGAIN`` error code when no data
+is available. The :ref:`select() <func-select>` or
+:ref:`poll() <func-poll>` functions can always be used to suspend
+execution until data becomes available. All drivers supporting the
+:ref:`read() <func-read>` function must also support :ref:`select() <func-select>` and
+:ref:`poll() <func-poll>`.
+
+Drivers can implement read functionality in different ways, using a
+single or multiple buffers and discarding the oldest or newest frames
+once the internal buffers are filled.
+
+:ref:`read() <func-read>` never returns a "snapshot" of a buffer being filled.
+Using a single buffer the driver will stop capturing when the
+application starts reading the buffer until the read is finished. Thus
+only the period of the vertical blanking interval is available for
+reading, or the capture rate must fall below the nominal frame rate of
+the video standard.
+
+The behavior of :ref:`read() <func-read>` when called during the active picture
+period or the vertical blanking separating the top and bottom field
+depends on the discarding policy. A driver discarding the oldest frames
+keeps capturing into an internal buffer, continuously overwriting the
+previously, not read frame, and returns the frame being received at the
+time of the :ref:`read() <func-read>` call as soon as it is complete.
+
+A driver discarding the newest frames stops capturing until the next
+:ref:`read() <func-read>` call. The frame being received at :ref:`read() <func-read>`
+time is discarded, returning the following frame instead. Again this
+implies a reduction of the capture rate to one half or less of the
+nominal frame rate. An example of this model is the video read mode of
+the bttv driver, initiating a DMA to user memory when :ref:`read() <func-read>`
+is called and returning when the DMA finished.
+
+In the multiple buffer model drivers maintain a ring of internal
+buffers, automatically advancing to the next free buffer. This allows
+continuous capturing when the application can empty the buffers fast
+enough. Again, the behavior when the driver runs out of free buffers
+depends on the discarding policy.
+
+Applications can get and set the number of buffers used internally by
+the driver with the :ref:`VIDIOC_G_PARM <VIDIOC_G_PARM>` and
+:ref:`VIDIOC_S_PARM <VIDIOC_G_PARM>` ioctls. They are optional,
+however. The discarding policy is not reported and cannot be changed.
+For minimum requirements see :ref:`devices`.
+
+
+Return Value
+============
+
+On success, the number of bytes read 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. This may happen for example because
+:ref:`read() <func-read>` was interrupted by a signal. On error, -1 is
+returned, and the ``errno`` variable is set appropriately. In this case
+the next read will start at the beginning of a new frame. Possible error
+codes are:
+
+EAGAIN
+    Non-blocking I/O has been selected using O_NONBLOCK and no data was
+    immediately available for reading.
+
+EBADF
+    ``fd`` is not a valid file descriptor or is not open for reading, or
+    the process already has the maximum number of files open.
+
+EBUSY
+    The driver does not support multiple read streams and the device is
+    already in use.
+
+EFAULT
+    ``buf`` references an inaccessible memory area.
+
+EINTR
+    The call was interrupted by a signal before any data was read.
+
+EIO
+    I/O error. This indicates some hardware problem or a failure to
+    communicate with a remote device (USB camera etc.).
+
+EINVAL
+    The :ref:`read() <func-read>` function is not supported by this driver, not
+    on this device, or generally not on this type of device.
diff --git a/Documentation/userspace-api/media/v4l/func-select.rst b/Documentation/userspace-api/media/v4l/func-select.rst
new file mode 100644
index 000000000000..6aca8a290c1f
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/func-select.rst
@@ -0,0 +1,127 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _func-select:
+
+*************
+V4L2 select()
+*************
+
+Name
+====
+
+v4l2-select - Synchronous I/O multiplexing
+
+
+Synopsis
+========
+
+.. code-block:: c
+
+    #include <sys/time.h>
+    #include <sys/types.h>
+    #include <unistd.h>
+
+
+.. c:function:: int select( int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout )
+    :name: v4l2-select
+
+Arguments
+=========
+
+``nfds``
+  The highest-numbered file descriptor in any of the three sets, plus 1.
+
+``readfds``
+  File descriptions to be watched if a read() call won't block.
+
+``writefds``
+  File descriptions to be watched if a write() won't block.
+
+``exceptfds``
+  File descriptions to be watched for V4L2 events.
+
+``timeout``
+  Maximum time to wait.
+
+
+Description
+===========
+
+With the :ref:`select() <func-select>` function applications can suspend
+execution until the driver has captured data or is ready to accept data
+for output.
+
+When streaming I/O has been negotiated this function waits until a
+buffer has been filled or displayed and can be dequeued with the
+:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl. When buffers are already in
+the outgoing queue of the driver the function returns immediately.
+
+On success :ref:`select() <func-select>` returns the total number of bits set in
+:c:func:`struct fd_set`. When the function timed out it returns
+a value of zero. On failure it returns -1 and the ``errno`` variable is
+set appropriately. When the application did not call
+:ref:`VIDIOC_QBUF` or
+:ref:`VIDIOC_STREAMON` yet the :ref:`select() <func-select>`
+function succeeds, setting the bit of the file descriptor in ``readfds``
+or ``writefds``, but subsequent :ref:`VIDIOC_DQBUF <VIDIOC_QBUF>`
+calls will fail. [#f1]_
+
+When use of the :ref:`read() <func-read>` function has been negotiated and the
+driver does not capture yet, the :ref:`select() <func-select>` function starts
+capturing. When that fails, :ref:`select() <func-select>` returns successful and
+a subsequent :ref:`read() <func-read>` call, which also attempts to start
+capturing, will return an appropriate error code. When the driver
+captures continuously (as opposed to, for example, still images) and
+data is already available the :ref:`select() <func-select>` function returns
+immediately.
+
+When use of the :ref:`write() <func-write>` function has been negotiated the
+:ref:`select() <func-select>` function just waits until the driver is ready for a
+non-blocking :ref:`write() <func-write>` call.
+
+All drivers implementing the :ref:`read() <func-read>` or :ref:`write() <func-write>`
+function or streaming I/O must also support the :ref:`select() <func-select>`
+function.
+
+For more details see the :ref:`select() <func-select>` manual page.
+
+
+Return Value
+============
+
+On success, :ref:`select() <func-select>` returns the number of descriptors
+contained in the three returned descriptor sets, which will be zero if
+the timeout expired. On error -1 is returned, and the ``errno`` variable
+is set appropriately; the sets and ``timeout`` are undefined. Possible
+error codes are:
+
+EBADF
+    One or more of the file descriptor sets specified a file descriptor
+    that is not open.
+
+EBUSY
+    The driver does not support multiple read or write streams and the
+    device is already in use.
+
+EFAULT
+    The ``readfds``, ``writefds``, ``exceptfds`` or ``timeout`` pointer
+    references an inaccessible memory area.
+
+EINTR
+    The call was interrupted by a signal.
+
+EINVAL
+    The ``nfds`` argument is less than zero or greater than
+    ``FD_SETSIZE``.
+
+.. [#f1]
+   The Linux kernel implements :ref:`select() <func-select>` like the
+   :ref:`poll() <func-poll>` function, but :ref:`select() <func-select>` cannot
+   return a ``POLLERR``.
diff --git a/Documentation/userspace-api/media/v4l/func-write.rst b/Documentation/userspace-api/media/v4l/func-write.rst
new file mode 100644
index 000000000000..fb1955f70f0f
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/func-write.rst
@@ -0,0 +1,91 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _func-write:
+
+************
+V4L2 write()
+************
+
+Name
+====
+
+v4l2-write - Write to a V4L2 device
+
+
+Synopsis
+========
+
+.. code-block:: c
+
+    #include <unistd.h>
+
+
+.. c:function:: ssize_t write( int fd, void *buf, size_t count )
+    :name: v4l2-write
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``buf``
+     Buffer with data to be written
+
+``count``
+    Number of bytes at the buffer
+
+Description
+===========
+
+:ref:`write() <func-write>` writes up to ``count`` bytes to the device
+referenced by the file descriptor ``fd`` from the buffer starting at
+``buf``. When the hardware outputs are not active yet, this function
+enables them. When ``count`` is zero, :ref:`write() <func-write>` returns 0
+without any other effect.
+
+When the application does not provide more data in time, the previous
+video frame, raw VBI image, sliced VPS or WSS data is displayed again.
+Sliced Teletext or Closed Caption data is not repeated, the driver
+inserts a blank line instead.
+
+
+Return Value
+============
+
+On success, the number of bytes written are returned. Zero indicates
+nothing was written. On error, -1 is returned, and the ``errno``
+variable is set appropriately. In this case the next write will start at
+the beginning of a new frame. Possible error codes are:
+
+EAGAIN
+    Non-blocking I/O has been selected using the
+    :ref:`O_NONBLOCK <func-open>` flag and no buffer space was
+    available to write the data immediately.
+
+EBADF
+    ``fd`` is not a valid file descriptor or is not open for writing.
+
+EBUSY
+    The driver does not support multiple write streams and the device is
+    already in use.
+
+EFAULT
+    ``buf`` references an inaccessible memory area.
+
+EINTR
+    The call was interrupted by a signal before any data was written.
+
+EIO
+    I/O error. This indicates some hardware problem.
+
+EINVAL
+    The :ref:`write() <func-write>` function is not supported by this driver,
+    not on this device, or generally not on this type of device.
diff --git a/Documentation/userspace-api/media/v4l/hist-v4l2.rst b/Documentation/userspace-api/media/v4l/hist-v4l2.rst
new file mode 100644
index 000000000000..7913d017cd33
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/hist-v4l2.rst
@@ -0,0 +1,1374 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _hist-v4l2:
+
+***********************
+Changes of the V4L2 API
+***********************
+
+Soon after the V4L API was added to the kernel it was criticised as too
+inflexible. In August 1998 Bill Dirks proposed a number of improvements
+and began to work on documentation, example drivers and applications.
+With the help of other volunteers this eventually became the V4L2 API,
+not just an extension but a replacement for the V4L API. However it took
+another four years and two stable kernel releases until the new API was
+finally accepted for inclusion into the kernel in its present form.
+
+
+Early Versions
+==============
+
+1998-08-20: First version.
+
+1998-08-27: The :ref:`select() <func-select>` function was introduced.
+
+1998-09-10: New video standard interface.
+
+1998-09-18: The ``VIDIOC_NONCAP`` ioctl was replaced by the otherwise
+meaningless ``O_TRUNC`` :ref:`open() <func-open>` flag, and the
+aliases ``O_NONCAP`` and ``O_NOIO`` were defined. Applications can set
+this flag if they intend to access controls only, as opposed to capture
+applications which need exclusive access. The ``VIDEO_STD_XXX``
+identifiers are now ordinals instead of flags, and the
+``video_std_construct()`` helper function takes id and
+transmission arguments.
+
+1998-09-28: Revamped video standard. Made video controls individually
+enumerable.
+
+1998-10-02: The ``id`` field was removed from struct
+struct ``video_standard`` and the color subcarrier fields were
+renamed. The :ref:`VIDIOC_QUERYSTD` ioctl was
+renamed to :ref:`VIDIOC_ENUMSTD`,
+:ref:`VIDIOC_G_INPUT <VIDIOC_G_INPUT>` to
+:ref:`VIDIOC_ENUMINPUT`. A first draft of the
+Codec API was released.
+
+1998-11-08: Many minor changes. Most symbols have been renamed. Some
+material changes to struct :c:type:`v4l2_capability`.
+
+1998-11-12: The read/write directon of some ioctls was misdefined.
+
+1998-11-14: ``V4L2_PIX_FMT_RGB24`` changed to ``V4L2_PIX_FMT_BGR24``,
+and ``V4L2_PIX_FMT_RGB32`` changed to ``V4L2_PIX_FMT_BGR32``. Audio
+controls are now accessible with the
+:ref:`VIDIOC_G_CTRL <VIDIOC_G_CTRL>` and
+:ref:`VIDIOC_S_CTRL <VIDIOC_G_CTRL>` ioctls under names starting
+with ``V4L2_CID_AUDIO``. The ``V4L2_MAJOR`` define was removed from
+``videodev.h`` since it was only used once in the ``videodev`` kernel
+module. The ``YUV422`` and ``YUV411`` planar image formats were added.
+
+1998-11-28: A few ioctl symbols changed. Interfaces for codecs and video
+output devices were added.
+
+1999-01-14: A raw VBI capture interface was added.
+
+1999-01-19: The ``VIDIOC_NEXTBUF`` ioctl was removed.
+
+
+V4L2 Version 0.16 1999-01-31
+============================
+
+1999-01-27: There is now one QBUF ioctl, VIDIOC_QWBUF and VIDIOC_QRBUF
+are gone. VIDIOC_QBUF takes a v4l2_buffer as a parameter. Added
+digital zoom (cropping) controls.
+
+
+V4L2 Version 0.18 1999-03-16
+============================
+
+Added a v4l to V4L2 ioctl compatibility layer to videodev.c. Driver
+writers, this changes how you implement your ioctl handler. See the
+Driver Writer's Guide. Added some more control id codes.
+
+
+V4L2 Version 0.19 1999-06-05
+============================
+
+1999-03-18: Fill in the category and catname fields of v4l2_queryctrl
+objects before passing them to the driver. Required a minor change to
+the VIDIOC_QUERYCTRL handlers in the sample drivers.
+
+1999-03-31: Better compatibility for v4l memory capture ioctls. Requires
+changes to drivers to fully support new compatibility features, see
+Driver Writer's Guide and v4l2cap.c. Added new control IDs:
+V4L2_CID_HFLIP, _VFLIP. Changed V4L2_PIX_FMT_YUV422P to _YUV422P,
+and _YUV411P to _YUV411P.
+
+1999-04-04: Added a few more control IDs.
+
+1999-04-07: Added the button control type.
+
+1999-05-02: Fixed a typo in videodev.h, and added the
+V4L2_CTRL_FLAG_GRAYED (later V4L2_CTRL_FLAG_GRABBED) flag.
+
+1999-05-20: Definition of VIDIOC_G_CTRL was wrong causing a
+malfunction of this ioctl.
+
+1999-06-05: Changed the value of V4L2_CID_WHITENESS.
+
+
+V4L2 Version 0.20 (1999-09-10)
+==============================
+
+Version 0.20 introduced a number of changes which were *not backward
+compatible* with 0.19 and earlier versions. Purpose of these changes was
+to simplify the API, while making it more extensible and following
+common Linux driver API conventions.
+
+1. Some typos in ``V4L2_FMT_FLAG`` symbols were fixed. struct
+   :c:type:`v4l2_clip` was changed for compatibility with
+   v4l. (1999-08-30)
+
+2. ``V4L2_TUNER_SUB_LANG1`` was added. (1999-09-05)
+
+3. All ioctl() commands that used an integer argument now take a pointer
+   to an integer. Where it makes sense, ioctls will return the actual
+   new value in the integer pointed to by the argument, a common
+   convention in the V4L2 API. The affected ioctls are: VIDIOC_PREVIEW,
+   VIDIOC_STREAMON, VIDIOC_STREAMOFF, VIDIOC_S_FREQ,
+   VIDIOC_S_INPUT, VIDIOC_S_OUTPUT, VIDIOC_S_EFFECT. For example
+
+
+   .. code-block:: c
+
+       err = ioctl (fd, VIDIOC_XXX, V4L2_XXX);
+
+   becomes
+
+
+   .. code-block:: c
+
+       int a = V4L2_XXX; err = ioctl(fd, VIDIOC_XXX, &a);
+
+4. All the different get- and set-format commands were swept into one
+   :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` and
+   :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl taking a union and a
+   type field selecting the union member as parameter. Purpose is to
+   simplify the API by eliminating several ioctls and to allow new and
+   driver private data streams without adding new ioctls.
+
+   This change obsoletes the following ioctls: ``VIDIOC_S_INFMT``,
+   ``VIDIOC_G_INFMT``, ``VIDIOC_S_OUTFMT``, ``VIDIOC_G_OUTFMT``,
+   ``VIDIOC_S_VBIFMT`` and ``VIDIOC_G_VBIFMT``. The image format
+   structure struct :c:type:`v4l2_format` was renamed to struct
+   :c:type:`v4l2_pix_format`, while struct
+   :c:type:`v4l2_format` is now the envelopping structure
+   for all format negotiations.
+
+5. Similar to the changes above, the ``VIDIOC_G_PARM`` and
+   ``VIDIOC_S_PARM`` ioctls were merged with ``VIDIOC_G_OUTPARM`` and
+   ``VIDIOC_S_OUTPARM``. A ``type`` field in the new struct
+   :c:type:`v4l2_streamparm` selects the respective
+   union member.
+
+   This change obsoletes the ``VIDIOC_G_OUTPARM`` and
+   ``VIDIOC_S_OUTPARM`` ioctls.
+
+6. Control enumeration was simplified, and two new control flags were
+   introduced and one dropped. The ``catname`` field was replaced by a
+   ``group`` field.
+
+   Drivers can now flag unsupported and temporarily unavailable controls
+   with ``V4L2_CTRL_FLAG_DISABLED`` and ``V4L2_CTRL_FLAG_GRABBED``
+   respectively. The ``group`` name indicates a possibly narrower
+   classification than the ``category``. In other words, there may be
+   multiple groups within a category. Controls within a group would
+   typically be drawn within a group box. Controls in different
+   categories might have a greater separation, or may even appear in
+   separate windows.
+
+7. The struct :c:type:`v4l2_buffer` ``timestamp`` was
+   changed to a 64 bit integer, containing the sampling or output time
+   of the frame in nanoseconds. Additionally timestamps will be in
+   absolute system time, not starting from zero at the beginning of a
+   stream. The data type name for timestamps is stamp_t, defined as a
+   signed 64-bit integer. Output devices should not send a buffer out
+   until the time in the timestamp field has arrived. I would like to
+   follow SGI's lead, and adopt a multimedia timestamping system like
+   their UST (Unadjusted System Time). See
+   http://web.archive.org/web/\*/http://reality.sgi.com
+   /cpirazzi_engr/lg/time/intro.html. UST uses timestamps that are
+   64-bit signed integers (not struct timeval's) and given in nanosecond
+   units. The UST clock starts at zero when the system is booted and
+   runs continuously and uniformly. It takes a little over 292 years for
+   UST to overflow. There is no way to set the UST clock. The regular
+   Linux time-of-day clock can be changed periodically, which would
+   cause errors if it were being used for timestamping a multimedia
+   stream. A real UST style clock will require some support in the
+   kernel that is not there yet. But in anticipation, I will change the
+   timestamp field to a 64-bit integer, and I will change the
+   v4l2_masterclock_gettime() function (used only by drivers) to
+   return a 64-bit integer.
+
+8. A ``sequence`` field was added to struct
+   :c:type:`v4l2_buffer`. The ``sequence`` field counts
+   captured frames, it is ignored by output devices. When a capture
+   driver drops a frame, the sequence number of that frame is skipped.
+
+
+V4L2 Version 0.20 incremental changes
+=====================================
+
+1999-12-23: In struct :c:type:`v4l2_vbi_format` the
+``reserved1`` field became ``offset``. Previously drivers were required
+to clear the ``reserved1`` field.
+
+2000-01-13: The ``V4L2_FMT_FLAG_NOT_INTERLACED`` flag was added.
+
+2000-07-31: The ``linux/poll.h`` header is now included by
+``videodev.h`` for compatibility with the original ``videodev.h`` file.
+
+2000-11-20: ``V4L2_TYPE_VBI_OUTPUT`` and ``V4L2_PIX_FMT_Y41P`` were
+added.
+
+2000-11-25: ``V4L2_TYPE_VBI_INPUT`` was added.
+
+2000-12-04: A couple typos in symbol names were fixed.
+
+2001-01-18: To avoid namespace conflicts the ``fourcc`` macro defined in
+the ``videodev.h`` header file was renamed to ``v4l2_fourcc``.
+
+2001-01-25: A possible driver-level compatibility problem between the
+``videodev.h`` file in Linux 2.4.0 and the ``videodev.h`` file included
+in the ``videodevX`` patch was fixed. Users of an earlier version of
+``videodevX`` on Linux 2.4.0 should recompile their V4L and V4L2
+drivers.
+
+2001-01-26: A possible kernel-level incompatibility between the
+``videodev.h`` file in the ``videodevX`` patch and the ``videodev.h``
+file in Linux 2.2.x with devfs patches applied was fixed.
+
+2001-03-02: Certain V4L ioctls which pass data in both direction
+although they are defined with read-only parameter, did not work
+correctly through the backward compatibility layer. [Solution?]
+
+2001-04-13: Big endian 16-bit RGB formats were added.
+
+2001-09-17: New YUV formats and the
+:ref:`VIDIOC_G_FREQUENCY <VIDIOC_G_FREQUENCY>` and
+:ref:`VIDIOC_S_FREQUENCY <VIDIOC_G_FREQUENCY>` ioctls were added.
+(The old ``VIDIOC_G_FREQ`` and ``VIDIOC_S_FREQ`` ioctls did not take
+multiple tuners into account.)
+
+2000-09-18: ``V4L2_BUF_TYPE_VBI`` was added. This may *break
+compatibility* as the :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` and
+:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctls may fail now if the struct
+struct ``v4l2_fmt`` ``type`` field does not contain
+``V4L2_BUF_TYPE_VBI``. In the documentation of the struct
+:c:type:`v4l2_vbi_format` ``offset`` field the
+ambiguous phrase "rising edge" was changed to "leading edge".
+
+
+V4L2 Version 0.20 2000-11-23
+============================
+
+A number of changes were made to the raw VBI interface.
+
+1. Figures clarifying the line numbering scheme were added to the V4L2
+   API specification. The ``start``\ [0] and ``start``\ [1] fields no
+   longer count line numbers beginning at zero. Rationale: a) The
+   previous definition was unclear. b) The ``start``\ [] values are
+   ordinal numbers. c) There is no point in inventing a new line
+   numbering scheme. We now use line number as defined by ITU-R, period.
+   Compatibility: Add one to the start values. Applications depending on
+   the previous semantics may not function correctly.
+
+2. The restriction "count[0] > 0 and count[1] > 0" has been relaxed to
+   "(count[0] + count[1]) > 0". Rationale: Drivers may allocate
+   resources at scan line granularity and some data services are
+   transmitted only on the first field. The comment that both ``count``
+   values will usually be equal is misleading and pointless and has been
+   removed. This change *breaks compatibility* with earlier versions:
+   Drivers may return ``EINVAL``, applications may not function correctly.
+
+3. Drivers are again permitted to return negative (unknown) start values
+   as proposed earlier. Why this feature was dropped is unclear. This
+   change may *break compatibility* with applications depending on the
+   start values being positive. The use of ``EBUSY`` and ``EINVAL``
+   error codes with the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl was
+   clarified. The ``EBUSY`` error code was finally documented, and the
+   ``reserved2`` field which was previously mentioned only in the
+   ``videodev.h`` header file.
+
+4. New buffer types ``V4L2_TYPE_VBI_INPUT`` and ``V4L2_TYPE_VBI_OUTPUT``
+   were added. The former is an alias for the old ``V4L2_TYPE_VBI``, the
+   latter was missing in the ``videodev.h`` file.
+
+
+V4L2 Version 0.20 2002-07-25
+============================
+
+Added sliced VBI interface proposal.
+
+
+V4L2 in Linux 2.5.46, 2002-10
+=============================
+
+Around October-November 2002, prior to an announced feature freeze of
+Linux 2.5, the API was revised, drawing from experience with V4L2 0.20.
+This unnamed version was finally merged into Linux 2.5.46.
+
+1.  As specified in :ref:`related`, drivers must make related device
+    functions available under all minor device numbers.
+
+2.  The :ref:`open() <func-open>` function requires access mode
+    ``O_RDWR`` regardless of the device type. All V4L2 drivers
+    exchanging data with applications must support the ``O_NONBLOCK``
+    flag. The ``O_NOIO`` flag, a V4L2 symbol which aliased the
+    meaningless ``O_TRUNC`` to indicate accesses without data exchange
+    (panel applications) was dropped. Drivers must stay in "panel mode"
+    until the application attempts to initiate a data exchange, see
+    :ref:`open`.
+
+3.  The struct :c:type:`v4l2_capability` changed
+    dramatically. Note that also the size of the structure changed,
+    which is encoded in the ioctl request code, thus older V4L2 devices
+    will respond with an ``EINVAL`` error code to the new
+    :ref:`VIDIOC_QUERYCAP` ioctl.
+
+    There are new fields to identify the driver, a new RDS device
+    function ``V4L2_CAP_RDS_CAPTURE``, the ``V4L2_CAP_AUDIO`` flag
+    indicates if the device has any audio connectors, another I/O
+    capability ``V4L2_CAP_ASYNCIO`` can be flagged. In response to these
+    changes the ``type`` field became a bit set and was merged into the
+    ``flags`` field. ``V4L2_FLAG_TUNER`` was renamed to
+    ``V4L2_CAP_TUNER``, ``V4L2_CAP_VIDEO_OVERLAY`` replaced
+    ``V4L2_FLAG_PREVIEW`` and ``V4L2_CAP_VBI_CAPTURE`` and
+    ``V4L2_CAP_VBI_OUTPUT`` replaced ``V4L2_FLAG_DATA_SERVICE``.
+    ``V4L2_FLAG_READ`` and ``V4L2_FLAG_WRITE`` were merged into
+    ``V4L2_CAP_READWRITE``.
+
+    The redundant fields ``inputs``, ``outputs`` and ``audios`` were
+    removed. These properties can be determined as described in
+    :ref:`video` and :ref:`audio`.
+
+    The somewhat volatile and therefore barely useful fields
+    ``maxwidth``, ``maxheight``, ``minwidth``, ``minheight``,
+    ``maxframerate`` were removed. This information is available as
+    described in :ref:`format` and :ref:`standard`.
+
+    ``V4L2_FLAG_SELECT`` was removed. We believe the select() function
+    is important enough to require support of it in all V4L2 drivers
+    exchanging data with applications. The redundant
+    ``V4L2_FLAG_MONOCHROME`` flag was removed, this information is
+    available as described in :ref:`format`.
+
+4.  In struct :c:type:`v4l2_input` the ``assoc_audio``
+    field and the ``capability`` field and its only flag
+    ``V4L2_INPUT_CAP_AUDIO`` was replaced by the new ``audioset`` field.
+    Instead of linking one video input to one audio input this field
+    reports all audio inputs this video input combines with.
+
+    New fields are ``tuner`` (reversing the former link from tuners to
+    video inputs), ``std`` and ``status``.
+
+    Accordingly struct :c:type:`v4l2_output` lost its
+    ``capability`` and ``assoc_audio`` fields. ``audioset``,
+    ``modulator`` and ``std`` where added instead.
+
+5.  The struct :c:type:`v4l2_audio` field ``audio`` was
+    renamed to ``index``, for consistency with other structures. A new
+    capability flag ``V4L2_AUDCAP_STEREO`` was added to indicated if the
+    audio input in question supports stereo sound.
+    ``V4L2_AUDCAP_EFFECTS`` and the corresponding ``V4L2_AUDMODE`` flags
+    where removed. This can be easily implemented using controls.
+    (However the same applies to AVL which is still there.)
+
+    Again for consistency the struct
+    :c:type:`v4l2_audioout` field ``audio`` was renamed
+    to ``index``.
+
+6.  The struct :c:type:`v4l2_tuner` ``input`` field was
+    replaced by an ``index`` field, permitting devices with multiple
+    tuners. The link between video inputs and tuners is now reversed,
+    inputs point to their tuner. The ``std`` substructure became a
+    simple set (more about this below) and moved into struct
+    :c:type:`v4l2_input`. A ``type`` field was added.
+
+    Accordingly in struct :c:type:`v4l2_modulator` the
+    ``output`` was replaced by an ``index`` field.
+
+    In struct :c:type:`v4l2_frequency` the ``port``
+    field was replaced by a ``tuner`` field containing the respective
+    tuner or modulator index number. A tuner ``type`` field was added
+    and the ``reserved`` field became larger for future extensions
+    (satellite tuners in particular).
+
+7.  The idea of completely transparent video standards was dropped.
+    Experience showed that applications must be able to work with video
+    standards beyond presenting the user a menu. Instead of enumerating
+    supported standards with an ioctl applications can now refer to
+    standards by :ref:`v4l2_std_id <v4l2-std-id>` and symbols
+    defined in the ``videodev2.h`` header file. For details see
+    :ref:`standard`. The :ref:`VIDIOC_G_STD <VIDIOC_G_STD>` and
+    :ref:`VIDIOC_S_STD <VIDIOC_G_STD>` now take a pointer to this
+    type as argument. :ref:`VIDIOC_QUERYSTD` was
+    added to autodetect the received standard, if the hardware has this
+    capability. In struct :c:type:`v4l2_standard` an
+    ``index`` field was added for
+    :ref:`VIDIOC_ENUMSTD`. A
+    :ref:`v4l2_std_id <v4l2-std-id>` field named ``id`` was added as
+    machine readable identifier, also replacing the ``transmission``
+    field. The misleading ``framerate`` field was renamed to
+    ``frameperiod``. The now obsolete ``colorstandard`` information,
+    originally needed to distguish between variations of standards, were
+    removed.
+
+    Struct ``v4l2_enumstd`` ceased to be.
+    :ref:`VIDIOC_ENUMSTD` now takes a pointer to a
+    struct :c:type:`v4l2_standard` directly. The
+    information which standards are supported by a particular video
+    input or output moved into struct :c:type:`v4l2_input`
+    and struct :c:type:`v4l2_output` fields named ``std``,
+    respectively.
+
+8.  The struct :ref:`v4l2_queryctrl <v4l2-queryctrl>` fields
+    ``category`` and ``group`` did not catch on and/or were not
+    implemented as expected and therefore removed.
+
+9.  The :ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` ioctl was added to
+    negotiate data formats as with
+    :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`, but without the overhead of
+    programming the hardware and regardless of I/O in progress.
+
+    In struct :c:type:`v4l2_format` the ``fmt`` union was
+    extended to contain struct :c:type:`v4l2_window`. All
+    image format negotiations are now possible with ``VIDIOC_G_FMT``,
+    ``VIDIOC_S_FMT`` and ``VIDIOC_TRY_FMT``; ioctl. The ``VIDIOC_G_WIN``
+    and ``VIDIOC_S_WIN`` ioctls to prepare for a video overlay were
+    removed. The ``type`` field changed to type enum
+    :c:type:`v4l2_buf_type` and the buffer type names
+    changed as follows.
+
+
+
+    .. flat-table::
+	:header-rows:  1
+	:stub-columns: 0
+
+	* - Old defines
+	  - enum :c:type:`v4l2_buf_type`
+	* - ``V4L2_BUF_TYPE_CAPTURE``
+	  - ``V4L2_BUF_TYPE_VIDEO_CAPTURE``
+	* - ``V4L2_BUF_TYPE_CODECIN``
+	  - Omitted for now
+	* - ``V4L2_BUF_TYPE_CODECOUT``
+	  - Omitted for now
+	* - ``V4L2_BUF_TYPE_EFFECTSIN``
+	  - Omitted for now
+	* - ``V4L2_BUF_TYPE_EFFECTSIN2``
+	  - Omitted for now
+	* - ``V4L2_BUF_TYPE_EFFECTSOUT``
+	  - Omitted for now
+	* - ``V4L2_BUF_TYPE_VIDEOOUT``
+	  - ``V4L2_BUF_TYPE_VIDEO_OUTPUT``
+	* - ``-``
+	  - ``V4L2_BUF_TYPE_VIDEO_OVERLAY``
+	* - ``-``
+	  - ``V4L2_BUF_TYPE_VBI_CAPTURE``
+	* - ``-``
+	  - ``V4L2_BUF_TYPE_VBI_OUTPUT``
+	* - ``-``
+	  - ``V4L2_BUF_TYPE_SLICED_VBI_CAPTURE``
+	* - ``-``
+	  - ``V4L2_BUF_TYPE_SLICED_VBI_OUTPUT``
+	* - ``V4L2_BUF_TYPE_PRIVATE_BASE``
+	  - ``V4L2_BUF_TYPE_PRIVATE`` (but this is deprecated)
+
+
+10. In struct :c:type:`v4l2_fmtdesc` a enum
+    :c:type:`v4l2_buf_type` field named ``type`` was
+    added as in struct :c:type:`v4l2_format`. The
+    ``VIDIOC_ENUM_FBUFFMT`` ioctl is no longer needed and was removed.
+    These calls can be replaced by
+    :ref:`VIDIOC_ENUM_FMT` with type
+    ``V4L2_BUF_TYPE_VIDEO_OVERLAY``.
+
+11. In struct :c:type:`v4l2_pix_format` the ``depth``
+    field was removed, assuming applications which recognize the format
+    by its four-character-code already know the color depth, and others
+    do not care about it. The same rationale lead to the removal of the
+    ``V4L2_FMT_FLAG_COMPRESSED`` flag. The
+    ``V4L2_FMT_FLAG_SWCONVECOMPRESSED`` flag was removed because drivers
+    are not supposed to convert images in kernel space. A user library
+    of conversion functions should be provided instead. The
+    ``V4L2_FMT_FLAG_BYTESPERLINE`` flag was redundant. Applications can
+    set the ``bytesperline`` field to zero to get a reasonable default.
+    Since the remaining flags were replaced as well, the ``flags`` field
+    itself was removed.
+
+    The interlace flags were replaced by a enum
+    :c:type:`v4l2_field` value in a newly added ``field``
+    field.
+
+
+
+    .. flat-table::
+	:header-rows:  1
+	:stub-columns: 0
+
+	* - Old flag
+	  - enum :c:type:`v4l2_field`
+	* - ``V4L2_FMT_FLAG_NOT_INTERLACED``
+	  - ?
+	* - ``V4L2_FMT_FLAG_INTERLACED`` = ``V4L2_FMT_FLAG_COMBINED``
+	  - ``V4L2_FIELD_INTERLACED``
+	* - ``V4L2_FMT_FLAG_TOPFIELD`` = ``V4L2_FMT_FLAG_ODDFIELD``
+	  - ``V4L2_FIELD_TOP``
+	* - ``V4L2_FMT_FLAG_BOTFIELD`` = ``V4L2_FMT_FLAG_EVENFIELD``
+	  - ``V4L2_FIELD_BOTTOM``
+	* - ``-``
+	  - ``V4L2_FIELD_SEQ_TB``
+	* - ``-``
+	  - ``V4L2_FIELD_SEQ_BT``
+	* - ``-``
+	  - ``V4L2_FIELD_ALTERNATE``
+
+
+    The color space flags were replaced by a enum
+    :c:type:`v4l2_colorspace` value in a newly added
+    ``colorspace`` field, where one of ``V4L2_COLORSPACE_SMPTE170M``,
+    ``V4L2_COLORSPACE_BT878``, ``V4L2_COLORSPACE_470_SYSTEM_M`` or
+    ``V4L2_COLORSPACE_470_SYSTEM_BG`` replaces ``V4L2_FMT_CS_601YUV``.
+
+12. In struct :c:type:`v4l2_requestbuffers` the
+    ``type`` field was properly defined as enum
+    :c:type:`v4l2_buf_type`. Buffer types changed as
+    mentioned above. A new ``memory`` field of type enum
+    :c:type:`v4l2_memory` was added to distinguish between
+    I/O methods using buffers allocated by the driver or the
+    application. See :ref:`io` for details.
+
+13. In struct :c:type:`v4l2_buffer` the ``type`` field was
+    properly defined as enum :c:type:`v4l2_buf_type`.
+    Buffer types changed as mentioned above. A ``field`` field of type
+    enum :c:type:`v4l2_field` was added to indicate if a
+    buffer contains a top or bottom field. The old field flags were
+    removed. Since no unadjusted system time clock was added to the
+    kernel as planned, the ``timestamp`` field changed back from type
+    stamp_t, an unsigned 64 bit integer expressing the sample time in
+    nanoseconds, to struct :c:type:`timeval`. With the addition
+    of a second memory mapping method the ``offset`` field moved into
+    union ``m``, and a new ``memory`` field of type enum
+    :c:type:`v4l2_memory` was added to distinguish between
+    I/O methods. See :ref:`io` for details.
+
+    The ``V4L2_BUF_REQ_CONTIG`` flag was used by the V4L compatibility
+    layer, after changes to this code it was no longer needed. The
+    ``V4L2_BUF_ATTR_DEVICEMEM`` flag would indicate if the buffer was
+    indeed allocated in device memory rather than DMA-able system
+    memory. It was barely useful and so was removed.
+
+14. In struct :c:type:`v4l2_framebuffer` the
+    ``base[3]`` array anticipating double- and triple-buffering in
+    off-screen video memory, however without defining a synchronization
+    mechanism, was replaced by a single pointer. The
+    ``V4L2_FBUF_CAP_SCALEUP`` and ``V4L2_FBUF_CAP_SCALEDOWN`` flags were
+    removed. Applications can determine this capability more accurately
+    using the new cropping and scaling interface. The
+    ``V4L2_FBUF_CAP_CLIPPING`` flag was replaced by
+    ``V4L2_FBUF_CAP_LIST_CLIPPING`` and
+    ``V4L2_FBUF_CAP_BITMAP_CLIPPING``.
+
+15. In struct :c:type:`v4l2_clip` the ``x``, ``y``,
+    ``width`` and ``height`` field moved into a ``c`` substructure of
+    type struct :c:type:`v4l2_rect`. The ``x`` and ``y``
+    fields were renamed to ``left`` and ``top``, i. e. offsets to a
+    context dependent origin.
+
+16. In struct :c:type:`v4l2_window` the ``x``, ``y``,
+    ``width`` and ``height`` field moved into a ``w`` substructure as
+    above. A ``field`` field of type :c:type:`v4l2_field` was added to
+    distinguish between field and frame (interlaced) overlay.
+
+17. The digital zoom interface, including struct
+    struct ``v4l2_zoomcap``, struct
+    struct ``v4l2_zoom``, ``V4L2_ZOOM_NONCAP`` and
+    ``V4L2_ZOOM_WHILESTREAMING`` was replaced by a new cropping and
+    scaling interface. The previously unused struct
+    struct :c:type:`v4l2_cropcap` and struct :c:type:`v4l2_crop`
+    where redefined for this purpose. See :ref:`crop` for details.
+
+18. In struct :c:type:`v4l2_vbi_format` the
+    ``SAMPLE_FORMAT`` field now contains a four-character-code as used
+    to identify video image formats and ``V4L2_PIX_FMT_GREY`` replaces
+    the ``V4L2_VBI_SF_UBYTE`` define. The ``reserved`` field was
+    extended.
+
+19. In struct :c:type:`v4l2_captureparm` the type of
+    the ``timeperframe`` field changed from unsigned long to struct
+    :c:type:`v4l2_fract`. This allows the accurate
+    expression of multiples of the NTSC-M frame rate 30000 / 1001. A new
+    field ``readbuffers`` was added to control the driver behaviour in
+    read I/O mode.
+
+    Similar changes were made to struct
+    :c:type:`v4l2_outputparm`.
+
+20. The struct ``v4l2_performance`` and
+    ``VIDIOC_G_PERF`` ioctl were dropped. Except when using the
+    :ref:`read/write I/O method <rw>`, which is limited anyway, this
+    information is already available to applications.
+
+21. The example transformation from RGB to YCbCr color space in the old
+    V4L2 documentation was inaccurate, this has been corrected in
+    :ref:`pixfmt`.
+
+
+V4L2 2003-06-19
+===============
+
+1. A new capability flag ``V4L2_CAP_RADIO`` was added for radio devices.
+   Prior to this change radio devices would identify solely by having
+   exactly one tuner whose type field reads ``V4L2_TUNER_RADIO``.
+
+2. An optional driver access priority mechanism was added, see
+   :ref:`app-pri` for details.
+
+3. The audio input and output interface was found to be incomplete.
+
+   Previously the :ref:`VIDIOC_G_AUDIO <VIDIOC_G_AUDIO>` ioctl would
+   enumerate the available audio inputs. An ioctl to determine the
+   current audio input, if more than one combines with the current video
+   input, did not exist. So ``VIDIOC_G_AUDIO`` was renamed to
+   ``VIDIOC_G_AUDIO_OLD``, this ioctl was removed on Kernel 2.6.39. The
+   :ref:`VIDIOC_ENUMAUDIO` ioctl was added to
+   enumerate audio inputs, while
+   :ref:`VIDIOC_G_AUDIO <VIDIOC_G_AUDIO>` now reports the current
+   audio input.
+
+   The same changes were made to
+   :ref:`VIDIOC_G_AUDOUT <VIDIOC_G_AUDOUT>` and
+   :ref:`VIDIOC_ENUMAUDOUT <VIDIOC_ENUMAUDOUT>`.
+
+   Until further the "videodev" module will automatically translate
+   between the old and new ioctls, but drivers and applications must be
+   updated to successfully compile again.
+
+4. The :ref:`VIDIOC_OVERLAY` ioctl was incorrectly
+   defined with write-read parameter. It was changed to write-only,
+   while the write-read version was renamed to ``VIDIOC_OVERLAY_OLD``.
+   The old ioctl was removed on Kernel 2.6.39. Until further the
+   "videodev" kernel module will automatically translate to the new
+   version, so drivers must be recompiled, but not applications.
+
+5. :ref:`overlay` incorrectly stated that clipping rectangles define
+   regions where the video can be seen. Correct is that clipping
+   rectangles define regions where *no* video shall be displayed and so
+   the graphics surface can be seen.
+
+6. The :ref:`VIDIOC_S_PARM <VIDIOC_G_PARM>` and
+   :ref:`VIDIOC_S_CTRL <VIDIOC_G_CTRL>` ioctls were defined with
+   write-only parameter, inconsistent with other ioctls modifying their
+   argument. They were changed to write-read, while a ``_OLD`` suffix
+   was added to the write-only versions. The old ioctls were removed on
+   Kernel 2.6.39. Drivers and applications assuming a constant parameter
+   need an update.
+
+
+V4L2 2003-11-05
+===============
+
+1. In :ref:`pixfmt-rgb` the following pixel formats were incorrectly
+   transferred from Bill Dirks' V4L2 specification. Descriptions below
+   refer to bytes in memory, in ascending address order.
+
+
+
+   .. flat-table::
+       :header-rows:  1
+       :stub-columns: 0
+
+       * - Symbol
+	 - In this document prior to revision 0.5
+	 - Corrected
+       * - ``V4L2_PIX_FMT_RGB24``
+	 - B, G, R
+	 - R, G, B
+       * - ``V4L2_PIX_FMT_BGR24``
+	 - R, G, B
+	 - B, G, R
+       * - ``V4L2_PIX_FMT_RGB32``
+	 - B, G, R, X
+	 - R, G, B, X
+       * - ``V4L2_PIX_FMT_BGR32``
+	 - R, G, B, X
+	 - B, G, R, X
+
+
+   The ``V4L2_PIX_FMT_BGR24`` example was always correct.
+
+   In :ref:`v4l-image-properties` the mapping of the V4L
+   ``VIDEO_PALETTE_RGB24`` and ``VIDEO_PALETTE_RGB32`` formats to V4L2
+   pixel formats was accordingly corrected.
+
+2. Unrelated to the fixes above, drivers may still interpret some V4L2
+   RGB pixel formats differently. These issues have yet to be addressed,
+   for details see :ref:`pixfmt-rgb`.
+
+
+V4L2 in Linux 2.6.6, 2004-05-09
+===============================
+
+1. The :ref:`VIDIOC_CROPCAP` ioctl was incorrectly
+   defined with read-only parameter. It is now defined as write-read
+   ioctl, while the read-only version was renamed to
+   ``VIDIOC_CROPCAP_OLD``. The old ioctl was removed on Kernel 2.6.39.
+
+
+V4L2 in Linux 2.6.8
+===================
+
+1. A new field ``input`` (former ``reserved[0]``) was added to the
+   struct :c:type:`v4l2_buffer` structure. Purpose of this
+   field is to alternate between video inputs (e. g. cameras) in step
+   with the video capturing process. This function must be enabled with
+   the new ``V4L2_BUF_FLAG_INPUT`` flag. The ``flags`` field is no
+   longer read-only.
+
+
+V4L2 spec erratum 2004-08-01
+============================
+
+1. The return value of the :ref:`func-open` function was incorrectly
+   documented.
+
+2. Audio output ioctls end in -AUDOUT, not -AUDIOOUT.
+
+3. In the Current Audio Input example the ``VIDIOC_G_AUDIO`` ioctl took
+   the wrong argument.
+
+4. The documentation of the :ref:`VIDIOC_QBUF` and
+   :ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctls did not mention the
+   struct :c:type:`v4l2_buffer` ``memory`` field. It was
+   also missing from examples. Also on the ``VIDIOC_DQBUF`` page the ``EIO``
+   error code was not documented.
+
+
+V4L2 in Linux 2.6.14
+====================
+
+1. A new sliced VBI interface was added. It is documented in
+   :ref:`sliced` and replaces the interface first proposed in V4L2
+   specification 0.8.
+
+
+V4L2 in Linux 2.6.15
+====================
+
+1. The :ref:`VIDIOC_LOG_STATUS` ioctl was added.
+
+2. New video standards ``V4L2_STD_NTSC_443``, ``V4L2_STD_SECAM_LC``,
+   ``V4L2_STD_SECAM_DK`` (a set of SECAM D, K and K1), and
+   ``V4L2_STD_ATSC`` (a set of ``V4L2_STD_ATSC_8_VSB`` and
+   ``V4L2_STD_ATSC_16_VSB``) were defined. Note the ``V4L2_STD_525_60``
+   set now includes ``V4L2_STD_NTSC_443``. See also
+   :ref:`v4l2-std-id`.
+
+3. The ``VIDIOC_G_COMP`` and ``VIDIOC_S_COMP`` ioctl were renamed to
+   ``VIDIOC_G_MPEGCOMP`` and ``VIDIOC_S_MPEGCOMP`` respectively. Their
+   argument was replaced by a struct
+   ``v4l2_mpeg_compression`` pointer. (The
+   ``VIDIOC_G_MPEGCOMP`` and ``VIDIOC_S_MPEGCOMP`` ioctls where removed
+   in Linux 2.6.25.)
+
+
+V4L2 spec erratum 2005-11-27
+============================
+
+The capture example in :ref:`capture-example` called the
+:ref:`VIDIOC_S_CROP <VIDIOC_G_CROP>` ioctl without checking if
+cropping is supported. In the video standard selection example in
+:ref:`standard` the :ref:`VIDIOC_S_STD <VIDIOC_G_STD>` call used
+the wrong argument type.
+
+
+V4L2 spec erratum 2006-01-10
+============================
+
+1. The ``V4L2_IN_ST_COLOR_KILL`` flag in struct
+   :c:type:`v4l2_input` not only indicates if the color
+   killer is enabled, but also if it is active. (The color killer
+   disables color decoding when it detects no color in the video signal
+   to improve the image quality.)
+
+2. :ref:`VIDIOC_S_PARM <VIDIOC_G_PARM>` is a write-read ioctl, not
+   write-only as stated on its reference page. The ioctl changed in 2003
+   as noted above.
+
+
+V4L2 spec erratum 2006-02-03
+============================
+
+1. In struct :c:type:`v4l2_captureparm` and struct
+   :c:type:`v4l2_outputparm` the ``timeperframe``
+   field gives the time in seconds, not microseconds.
+
+
+V4L2 spec erratum 2006-02-04
+============================
+
+1. The ``clips`` field in struct :c:type:`v4l2_window`
+   must point to an array of struct :c:type:`v4l2_clip`, not
+   a linked list, because drivers ignore the struct
+   struct :c:type:`v4l2_clip`. ``next`` pointer.
+
+
+V4L2 in Linux 2.6.17
+====================
+
+1. New video standard macros were added: ``V4L2_STD_NTSC_M_KR`` (NTSC M
+   South Korea), and the sets ``V4L2_STD_MN``, ``V4L2_STD_B``,
+   ``V4L2_STD_GH`` and ``V4L2_STD_DK``. The ``V4L2_STD_NTSC`` and
+   ``V4L2_STD_SECAM`` sets now include ``V4L2_STD_NTSC_M_KR`` and
+   ``V4L2_STD_SECAM_LC`` respectively.
+
+2. A new ``V4L2_TUNER_MODE_LANG1_LANG2`` was defined to record both
+   languages of a bilingual program. The use of
+   ``V4L2_TUNER_MODE_STEREO`` for this purpose is deprecated now. See
+   the :ref:`VIDIOC_G_TUNER <VIDIOC_G_TUNER>` section for details.
+
+
+V4L2 spec erratum 2006-09-23 (Draft 0.15)
+=========================================
+
+1. In various places ``V4L2_BUF_TYPE_SLICED_VBI_CAPTURE`` and
+   ``V4L2_BUF_TYPE_SLICED_VBI_OUTPUT`` of the sliced VBI interface were
+   not mentioned along with other buffer types.
+
+2. In :ref:`VIDIOC_G_AUDIO <VIDIOC_G_AUDIO>` it was clarified that the struct
+   :c:type:`v4l2_audio` ``mode`` field is a flags field.
+
+3. :ref:`VIDIOC_QUERYCAP` did not mention the sliced VBI and radio
+   capability flags.
+
+4. In :ref:`VIDIOC_G_FREQUENCY <VIDIOC_G_FREQUENCY>` it was clarified that applications
+   must initialize the tuner ``type`` field of struct
+   :c:type:`v4l2_frequency` before calling
+   :ref:`VIDIOC_S_FREQUENCY <VIDIOC_G_FREQUENCY>`.
+
+5. The ``reserved`` array in struct
+   :c:type:`v4l2_requestbuffers` has 2 elements,
+   not 32.
+
+6. In :ref:`output` and :ref:`raw-vbi` the device file names
+   ``/dev/vout`` which never caught on were replaced by ``/dev/video``.
+
+7. With Linux 2.6.15 the possible range for VBI device minor numbers was
+   extended from 224-239 to 224-255. Accordingly device file names
+   ``/dev/vbi0`` to ``/dev/vbi31`` are possible now.
+
+
+V4L2 in Linux 2.6.18
+====================
+
+1. New ioctls :ref:`VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>`,
+   :ref:`VIDIOC_S_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` and
+   :ref:`VIDIOC_TRY_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` were added, a
+   flag to skip unsupported controls with
+   :ref:`VIDIOC_QUERYCTRL`, new control types
+   ``V4L2_CTRL_TYPE_INTEGER64`` and ``V4L2_CTRL_TYPE_CTRL_CLASS``
+   (:c:type:`v4l2_ctrl_type`), and new control flags
+   ``V4L2_CTRL_FLAG_READ_ONLY``, ``V4L2_CTRL_FLAG_UPDATE``,
+   ``V4L2_CTRL_FLAG_INACTIVE`` and ``V4L2_CTRL_FLAG_SLIDER``
+   (:ref:`control-flags`). See :ref:`extended-controls` for details.
+
+
+V4L2 in Linux 2.6.19
+====================
+
+1. In struct :c:type:`v4l2_sliced_vbi_cap` a
+   buffer type field was added replacing a reserved field. Note on
+   architectures where the size of enum types differs from int types the
+   size of the structure changed. The
+   :ref:`VIDIOC_G_SLICED_VBI_CAP <VIDIOC_G_SLICED_VBI_CAP>` ioctl
+   was redefined from being read-only to write-read. Applications must
+   initialize the type field and clear the reserved fields now. These
+   changes may *break the compatibility* with older drivers and
+   applications.
+
+2. The ioctls :ref:`VIDIOC_ENUM_FRAMESIZES`
+   and
+   :ref:`VIDIOC_ENUM_FRAMEINTERVALS`
+   were added.
+
+3. A new pixel format ``V4L2_PIX_FMT_RGB444`` (:ref:`pixfmt-rgb`) was
+   added.
+
+
+V4L2 spec erratum 2006-10-12 (Draft 0.17)
+=========================================
+
+1. ``V4L2_PIX_FMT_HM12`` (:ref:`reserved-formats`) is a YUV 4:2:0, not
+   4:2:2 format.
+
+
+V4L2 in Linux 2.6.21
+====================
+
+1. The ``videodev2.h`` header file is now dual licensed under GNU
+   General Public License version two or later, and under a 3-clause
+   BSD-style license.
+
+
+V4L2 in Linux 2.6.22
+====================
+
+1. Two new field orders ``V4L2_FIELD_INTERLACED_TB`` and
+   ``V4L2_FIELD_INTERLACED_BT`` were added. See :c:type:`v4l2_field` for
+   details.
+
+2. Three new clipping/blending methods with a global or straight or
+   inverted local alpha value were added to the video overlay interface.
+   See the description of the :ref:`VIDIOC_G_FBUF <VIDIOC_G_FBUF>`
+   and :ref:`VIDIOC_S_FBUF <VIDIOC_G_FBUF>` ioctls for details.
+
+   A new ``global_alpha`` field was added to
+   :c:type:`v4l2_window`, extending the structure. This
+   may *break compatibility* with applications using a struct
+   struct :c:type:`v4l2_window` directly. However the
+   :ref:`VIDIOC_G/S/TRY_FMT <VIDIOC_G_FMT>` ioctls, which take a
+   pointer to a :c:type:`v4l2_format` parent structure
+   with padding bytes at the end, are not affected.
+
+3. The format of the ``chromakey`` field in struct
+   :c:type:`v4l2_window` changed from "host order RGB32"
+   to a pixel value in the same format as the framebuffer. This may
+   *break compatibility* with existing applications. Drivers supporting
+   the "host order RGB32" format are not known.
+
+
+V4L2 in Linux 2.6.24
+====================
+
+1. The pixel formats ``V4L2_PIX_FMT_PAL8``, ``V4L2_PIX_FMT_YUV444``,
+   ``V4L2_PIX_FMT_YUV555``, ``V4L2_PIX_FMT_YUV565`` and
+   ``V4L2_PIX_FMT_YUV32`` were added.
+
+
+V4L2 in Linux 2.6.25
+====================
+
+1. The pixel formats :ref:`V4L2_PIX_FMT_Y16 <V4L2-PIX-FMT-Y16>` and
+   :ref:`V4L2_PIX_FMT_SBGGR16 <V4L2-PIX-FMT-SBGGR16>` were added.
+
+2. New :ref:`controls <control>` ``V4L2_CID_POWER_LINE_FREQUENCY``,
+   ``V4L2_CID_HUE_AUTO``, ``V4L2_CID_WHITE_BALANCE_TEMPERATURE``,
+   ``V4L2_CID_SHARPNESS`` and ``V4L2_CID_BACKLIGHT_COMPENSATION`` were
+   added. The controls ``V4L2_CID_BLACK_LEVEL``, ``V4L2_CID_WHITENESS``,
+   ``V4L2_CID_HCENTER`` and ``V4L2_CID_VCENTER`` were deprecated.
+
+3. A :ref:`Camera controls class <camera-controls>` was added, with
+   the new controls ``V4L2_CID_EXPOSURE_AUTO``,
+   ``V4L2_CID_EXPOSURE_ABSOLUTE``, ``V4L2_CID_EXPOSURE_AUTO_PRIORITY``,
+   ``V4L2_CID_PAN_RELATIVE``, ``V4L2_CID_TILT_RELATIVE``,
+   ``V4L2_CID_PAN_RESET``, ``V4L2_CID_TILT_RESET``,
+   ``V4L2_CID_PAN_ABSOLUTE``, ``V4L2_CID_TILT_ABSOLUTE``,
+   ``V4L2_CID_FOCUS_ABSOLUTE``, ``V4L2_CID_FOCUS_RELATIVE`` and
+   ``V4L2_CID_FOCUS_AUTO``.
+
+4. The ``VIDIOC_G_MPEGCOMP`` and ``VIDIOC_S_MPEGCOMP`` ioctls, which
+   were superseded by the :ref:`extended controls <extended-controls>`
+   interface in Linux 2.6.18, where finally removed from the
+   ``videodev2.h`` header file.
+
+
+V4L2 in Linux 2.6.26
+====================
+
+1. The pixel formats ``V4L2_PIX_FMT_Y16`` and ``V4L2_PIX_FMT_SBGGR16``
+   were added.
+
+2. Added user controls ``V4L2_CID_CHROMA_AGC`` and
+   ``V4L2_CID_COLOR_KILLER``.
+
+
+V4L2 in Linux 2.6.27
+====================
+
+1. The :ref:`VIDIOC_S_HW_FREQ_SEEK` ioctl
+   and the ``V4L2_CAP_HW_FREQ_SEEK`` capability were added.
+
+2. The pixel formats ``V4L2_PIX_FMT_YVYU``, ``V4L2_PIX_FMT_PCA501``,
+   ``V4L2_PIX_FMT_PCA505``, ``V4L2_PIX_FMT_PCA508``,
+   ``V4L2_PIX_FMT_PCA561``, ``V4L2_PIX_FMT_SGBRG8``,
+   ``V4L2_PIX_FMT_PAC207`` and ``V4L2_PIX_FMT_PJPG`` were added.
+
+
+V4L2 in Linux 2.6.28
+====================
+
+1. Added ``V4L2_MPEG_AUDIO_ENCODING_AAC`` and
+   ``V4L2_MPEG_AUDIO_ENCODING_AC3`` MPEG audio encodings.
+
+2. Added ``V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC`` MPEG video encoding.
+
+3. The pixel formats ``V4L2_PIX_FMT_SGRBG10`` and
+   ``V4L2_PIX_FMT_SGRBG10DPCM8`` were added.
+
+
+V4L2 in Linux 2.6.29
+====================
+
+1. The ``VIDIOC_G_CHIP_IDENT`` ioctl was renamed to
+   ``VIDIOC_G_CHIP_IDENT_OLD`` and ``VIDIOC_DBG_G_CHIP_IDENT`` was
+   introduced in its place. The old struct
+   struct ``v4l2_chip_ident`` was renamed to
+   struct ``v4l2_chip_ident_old``.
+
+2. The pixel formats ``V4L2_PIX_FMT_VYUY``, ``V4L2_PIX_FMT_NV16`` and
+   ``V4L2_PIX_FMT_NV61`` were added.
+
+3. Added camera controls ``V4L2_CID_ZOOM_ABSOLUTE``,
+   ``V4L2_CID_ZOOM_RELATIVE``, ``V4L2_CID_ZOOM_CONTINUOUS`` and
+   ``V4L2_CID_PRIVACY``.
+
+
+V4L2 in Linux 2.6.30
+====================
+
+1. New control flag ``V4L2_CTRL_FLAG_WRITE_ONLY`` was added.
+
+2. New control ``V4L2_CID_COLORFX`` was added.
+
+
+V4L2 in Linux 2.6.32
+====================
+
+1. In order to be easier to compare a V4L2 API and a kernel version, now
+   V4L2 API is numbered using the Linux Kernel version numeration.
+
+2. Finalized the RDS capture API. See :ref:`rds` for more information.
+
+3. Added new capabilities for modulators and RDS encoders.
+
+4. Add description for libv4l API.
+
+5. Added support for string controls via new type
+   ``V4L2_CTRL_TYPE_STRING``.
+
+6. Added ``V4L2_CID_BAND_STOP_FILTER`` documentation.
+
+7. Added FM Modulator (FM TX) Extended Control Class:
+   ``V4L2_CTRL_CLASS_FM_TX`` and their Control IDs.
+
+8. Added FM Receiver (FM RX) Extended Control Class:
+   ``V4L2_CTRL_CLASS_FM_RX`` and their Control IDs.
+
+9. Added Remote Controller chapter, describing the default Remote
+   Controller mapping for media devices.
+
+
+V4L2 in Linux 2.6.33
+====================
+
+1. Added support for Digital Video timings in order to support HDTV
+   receivers and transmitters.
+
+
+V4L2 in Linux 2.6.34
+====================
+
+1. Added ``V4L2_CID_IRIS_ABSOLUTE`` and ``V4L2_CID_IRIS_RELATIVE``
+   controls to the :ref:`Camera controls class <camera-controls>`.
+
+
+V4L2 in Linux 2.6.37
+====================
+
+1. Remove the vtx (videotext/teletext) API. This API was no longer used
+   and no hardware exists to verify the API. Nor were any userspace
+   applications found that used it. It was originally scheduled for
+   removal in 2.6.35.
+
+
+V4L2 in Linux 2.6.39
+====================
+
+1. The old VIDIOC_*_OLD symbols and V4L1 support were removed.
+
+2. Multi-planar API added. Does not affect the compatibility of current
+   drivers and applications. See :ref:`multi-planar API <planar-apis>`
+   for details.
+
+
+V4L2 in Linux 3.1
+=================
+
+1. VIDIOC_QUERYCAP now returns a per-subsystem version instead of a
+   per-driver one.
+
+   Standardize an error code for invalid ioctl.
+
+   Added V4L2_CTRL_TYPE_BITMASK.
+
+
+V4L2 in Linux 3.2
+=================
+
+1. V4L2_CTRL_FLAG_VOLATILE was added to signal volatile controls to
+   userspace.
+
+2. Add selection API for extended control over cropping and composing.
+   Does not affect the compatibility of current drivers and
+   applications. See :ref:`selection API <selection-api>` for details.
+
+
+V4L2 in Linux 3.3
+=================
+
+1. Added ``V4L2_CID_ALPHA_COMPONENT`` control to the
+   :ref:`User controls class <control>`.
+
+2. Added the device_caps field to struct v4l2_capabilities and added
+   the new V4L2_CAP_DEVICE_CAPS capability.
+
+
+V4L2 in Linux 3.4
+=================
+
+1. Added :ref:`JPEG compression control class <jpeg-controls>`.
+
+2. Extended the DV Timings API:
+   :ref:`VIDIOC_ENUM_DV_TIMINGS`,
+   :ref:`VIDIOC_QUERY_DV_TIMINGS` and
+   :ref:`VIDIOC_DV_TIMINGS_CAP`.
+
+
+V4L2 in Linux 3.5
+=================
+
+1. Added integer menus, the new type will be
+   V4L2_CTRL_TYPE_INTEGER_MENU.
+
+2. Added selection API for V4L2 subdev interface:
+   :ref:`VIDIOC_SUBDEV_G_SELECTION` and
+   :ref:`VIDIOC_SUBDEV_S_SELECTION <VIDIOC_SUBDEV_G_SELECTION>`.
+
+3. Added ``V4L2_COLORFX_ANTIQUE``, ``V4L2_COLORFX_ART_FREEZE``,
+   ``V4L2_COLORFX_AQUA``, ``V4L2_COLORFX_SILHOUETTE``,
+   ``V4L2_COLORFX_SOLARIZATION``, ``V4L2_COLORFX_VIVID`` and
+   ``V4L2_COLORFX_ARBITRARY_CBCR`` menu items to the
+   ``V4L2_CID_COLORFX`` control.
+
+4. Added ``V4L2_CID_COLORFX_CBCR`` control.
+
+5. Added camera controls ``V4L2_CID_AUTO_EXPOSURE_BIAS``,
+   ``V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE``,
+   ``V4L2_CID_IMAGE_STABILIZATION``, ``V4L2_CID_ISO_SENSITIVITY``,
+   ``V4L2_CID_ISO_SENSITIVITY_AUTO``, ``V4L2_CID_EXPOSURE_METERING``,
+   ``V4L2_CID_SCENE_MODE``, ``V4L2_CID_3A_LOCK``,
+   ``V4L2_CID_AUTO_FOCUS_START``, ``V4L2_CID_AUTO_FOCUS_STOP``,
+   ``V4L2_CID_AUTO_FOCUS_STATUS`` and ``V4L2_CID_AUTO_FOCUS_RANGE``.
+
+
+V4L2 in Linux 3.6
+=================
+
+1. Replaced ``input`` in struct :c:type:`v4l2_buffer` by
+   ``reserved2`` and removed ``V4L2_BUF_FLAG_INPUT``.
+
+2. Added V4L2_CAP_VIDEO_M2M and V4L2_CAP_VIDEO_M2M_MPLANE
+   capabilities.
+
+3. Added support for frequency band enumerations:
+   :ref:`VIDIOC_ENUM_FREQ_BANDS`.
+
+
+V4L2 in Linux 3.9
+=================
+
+1. Added timestamp types to ``flags`` field in
+   struct :c:type:`v4l2_buffer`. See :ref:`buffer-flags`.
+
+2. Added ``V4L2_EVENT_CTRL_CH_RANGE`` control event changes flag. See
+   :ref:`ctrl-changes-flags`.
+
+
+V4L2 in Linux 3.10
+==================
+
+1. Removed obsolete and unused DV_PRESET ioctls VIDIOC_G_DV_PRESET,
+   VIDIOC_S_DV_PRESET, VIDIOC_QUERY_DV_PRESET and
+   VIDIOC_ENUM_DV_PRESET. Remove the related v4l2_input/output
+   capability flags V4L2_IN_CAP_PRESETS and V4L2_OUT_CAP_PRESETS.
+
+2. Added new debugging ioctl
+   :ref:`VIDIOC_DBG_G_CHIP_INFO`.
+
+
+V4L2 in Linux 3.11
+==================
+
+1. Remove obsolete ``VIDIOC_DBG_G_CHIP_IDENT`` ioctl.
+
+
+V4L2 in Linux 3.14
+==================
+
+1. In struct :c:type:`v4l2_rect`, the type of ``width`` and
+   ``height`` fields changed from _s32 to _u32.
+
+
+V4L2 in Linux 3.15
+==================
+
+1. Added Software Defined Radio (SDR) Interface.
+
+
+V4L2 in Linux 3.16
+==================
+
+1. Added event V4L2_EVENT_SOURCE_CHANGE.
+
+
+V4L2 in Linux 3.17
+==================
+
+1. Extended struct :c:type:`v4l2_pix_format`. Added
+   format flags.
+
+2. Added compound control types and
+   :ref:`VIDIOC_QUERY_EXT_CTRL <VIDIOC_QUERYCTRL>`.
+
+
+V4L2 in Linux 3.18
+==================
+
+1. Added ``V4L2_CID_PAN_SPEED`` and ``V4L2_CID_TILT_SPEED`` camera
+   controls.
+
+
+V4L2 in Linux 3.19
+==================
+
+1. Rewrote Colorspace chapter, added new enum
+   :c:type:`v4l2_ycbcr_encoding` and enum
+   :c:type:`v4l2_quantization` fields to struct
+   :c:type:`v4l2_pix_format`, struct
+   :c:type:`v4l2_pix_format_mplane` and
+   struct :c:type:`v4l2_mbus_framefmt`.
+
+
+V4L2 in Linux 4.4
+=================
+
+1. Renamed ``V4L2_TUNER_ADC`` to ``V4L2_TUNER_SDR``. The use of
+   ``V4L2_TUNER_ADC`` is deprecated now.
+
+2. Added ``V4L2_CID_RF_TUNER_RF_GAIN`` RF Tuner control.
+
+3. Added transmitter support for Software Defined Radio (SDR) Interface.
+
+
+.. _other:
+
+Relation of V4L2 to other Linux multimedia APIs
+===============================================
+
+
+.. _xvideo:
+
+X Video Extension
+-----------------
+
+The X Video Extension (abbreviated XVideo or just Xv) is an extension of
+the X Window system, implemented for example by the XFree86 project. Its
+scope is similar to V4L2, an API to video capture and output devices for
+X clients. Xv allows applications to display live video in a window,
+send window contents to a TV output, and capture or output still images
+in XPixmaps [#f1]_. With their implementation XFree86 makes the extension
+available across many operating systems and architectures.
+
+Because the driver is embedded into the X server Xv has a number of
+advantages over the V4L2 :ref:`video overlay interface <overlay>`. The
+driver can easily determine the overlay target, i. e. visible graphics
+memory or off-screen buffers for a destructive overlay. It can program
+the RAMDAC for a non-destructive overlay, scaling or color-keying, or
+the clipping functions of the video capture hardware, always in sync
+with drawing operations or windows moving or changing their stacking
+order.
+
+To combine the advantages of Xv and V4L a special Xv driver exists in
+XFree86 and XOrg, just programming any overlay capable Video4Linux
+device it finds. To enable it ``/etc/X11/XF86Config`` must contain these
+lines:
+
+::
+
+    Section "Module"
+	Load "v4l"
+    EndSection
+
+As of XFree86 4.2 this driver still supports only V4L ioctls, however it
+should work just fine with all V4L2 devices through the V4L2
+backward-compatibility layer. Since V4L2 permits multiple opens it is
+possible (if supported by the V4L2 driver) to capture video while an X
+client requested video overlay. Restrictions of simultaneous capturing
+and overlay are discussed in :ref:`overlay` apply.
+
+Only marginally related to V4L2, XFree86 extended Xv to support hardware
+YUV to RGB conversion and scaling for faster video playback, and added
+an interface to MPEG-2 decoding hardware. This API is useful to display
+images captured with V4L2 devices.
+
+
+Digital Video
+-------------
+
+V4L2 does not support digital terrestrial, cable or satellite broadcast.
+A separate project aiming at digital receivers exists. You can find its
+homepage at `https://linuxtv.org <https://linuxtv.org>`__. The Linux
+DVB API has no connection to the V4L2 API except that drivers for hybrid
+hardware may support both.
+
+
+Audio Interfaces
+----------------
+
+[to do - OSS/ALSA]
+
+
+.. _experimental:
+
+Experimental API Elements
+=========================
+
+The following V4L2 API elements are currently experimental and may
+change in the future.
+
+-  :ref:`VIDIOC_DBG_G_REGISTER` and
+   :ref:`VIDIOC_DBG_S_REGISTER <VIDIOC_DBG_G_REGISTER>` ioctls.
+
+-  :ref:`VIDIOC_DBG_G_CHIP_INFO` ioctl.
+
+
+.. _obsolete:
+
+Obsolete API Elements
+=====================
+
+The following V4L2 API elements were superseded by new interfaces and
+should not be implemented in new drivers.
+
+-  ``VIDIOC_G_MPEGCOMP`` and ``VIDIOC_S_MPEGCOMP`` ioctls. Use Extended
+   Controls, :ref:`extended-controls`.
+
+-  VIDIOC_G_DV_PRESET, VIDIOC_S_DV_PRESET,
+   VIDIOC_ENUM_DV_PRESETS and VIDIOC_QUERY_DV_PRESET ioctls. Use
+   the DV Timings API (:ref:`dv-timings`).
+
+-  ``VIDIOC_SUBDEV_G_CROP`` and ``VIDIOC_SUBDEV_S_CROP`` ioctls. Use
+   ``VIDIOC_SUBDEV_G_SELECTION`` and ``VIDIOC_SUBDEV_S_SELECTION``,
+   :ref:`VIDIOC_SUBDEV_G_SELECTION`.
+
+.. [#f1]
+   This is not implemented in XFree86.
diff --git a/Documentation/userspace-api/media/v4l/hsv-formats.rst b/Documentation/userspace-api/media/v4l/hsv-formats.rst
new file mode 100644
index 000000000000..4906f7e0d80d
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/hsv-formats.rst
@@ -0,0 +1,26 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _hsv-formats:
+
+***********
+HSV Formats
+***********
+
+These formats store the color information of the image
+in a geometrical representation. The colors are mapped into a
+cylinder, where the angle is the HUE, the height is the VALUE
+and the distance to the center is the SATURATION. This is a very
+useful format for image segmentation algorithms.
+
+
+.. toctree::
+    :maxdepth: 1
+
+    pixfmt-packed-hsv
diff --git a/Documentation/userspace-api/media/v4l/io.rst b/Documentation/userspace-api/media/v4l/io.rst
new file mode 100644
index 000000000000..de0e2f529268
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/io.rst
@@ -0,0 +1,58 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _io:
+
+############
+Input/Output
+############
+The V4L2 API defines several different methods to read from or write to
+a device. All drivers exchanging data with applications must support at
+least one of them.
+
+The classic I/O method using the :ref:`read() <func-read>` and
+:ref:`write() <func-write>` function is automatically selected after opening a
+V4L2 device. When the driver does not support this method attempts to
+read or write will fail at any time.
+
+Other methods must be negotiated. To select the streaming I/O method
+with memory mapped or user buffers applications call the
+:ref:`VIDIOC_REQBUFS` ioctl. The asynchronous I/O
+method is not defined yet.
+
+Video overlay can be considered another I/O method, although the
+application does not directly receive the image data. It is selected by
+initiating video overlay with the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`
+ioctl. For more information see :ref:`overlay`.
+
+Generally exactly one I/O method, including overlay, is associated with
+each file descriptor. The only exceptions are applications not
+exchanging data with a driver ("panel applications", see :ref:`open`)
+and drivers permitting simultaneous video capturing and overlay using
+the same file descriptor, for compatibility with V4L and earlier
+versions of V4L2.
+
+:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` and :ref:`VIDIOC_REQBUFS` would permit this to some
+degree, but for simplicity drivers need not support switching the I/O
+method (after first switching away from read/write) other than by
+closing and reopening the device.
+
+The following sections describe the various I/O methods in more detail.
+
+
+.. toctree::
+    :maxdepth: 1
+
+    rw
+    mmap
+    userp
+    dmabuf
+    async
+    buffer
+    field-order
diff --git a/Documentation/userspace-api/media/v4l/libv4l-introduction.rst b/Documentation/userspace-api/media/v4l/libv4l-introduction.rst
new file mode 100644
index 000000000000..95f3127b4749
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/libv4l-introduction.rst
@@ -0,0 +1,191 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _libv4l-introduction:
+
+************
+Introduction
+************
+
+libv4l is a collection of libraries which adds a thin abstraction layer
+on top of video4linux2 devices. The purpose of this (thin) layer is to
+make it easy for application writers to support a wide variety of
+devices without having to write separate code for different devices in
+the same class.
+
+An example of using libv4l is provided by
+:ref:`v4l2grab <v4l2grab-example>`.
+
+libv4l consists of 3 different libraries:
+
+
+libv4lconvert
+=============
+
+libv4lconvert is a library that converts several different pixelformats
+found in V4L2 drivers into a few common RGB and YUY formats.
+
+It currently accepts the following V4L2 driver formats:
+:ref:`V4L2_PIX_FMT_BGR24 <V4L2-PIX-FMT-BGR24>`,
+:ref:`V4L2_PIX_FMT_HM12 <V4L2-PIX-FMT-HM12>`,
+:ref:`V4L2_PIX_FMT_JPEG <V4L2-PIX-FMT-JPEG>`,
+:ref:`V4L2_PIX_FMT_MJPEG <V4L2-PIX-FMT-MJPEG>`,
+:ref:`V4L2_PIX_FMT_MR97310A <V4L2-PIX-FMT-MR97310A>`,
+:ref:`V4L2_PIX_FMT_OV511 <V4L2-PIX-FMT-OV511>`,
+:ref:`V4L2_PIX_FMT_OV518 <V4L2-PIX-FMT-OV518>`,
+:ref:`V4L2_PIX_FMT_PAC207 <V4L2-PIX-FMT-PAC207>`,
+:ref:`V4L2_PIX_FMT_PJPG <V4L2-PIX-FMT-PJPG>`,
+:ref:`V4L2_PIX_FMT_RGB24 <V4L2-PIX-FMT-RGB24>`,
+:ref:`V4L2_PIX_FMT_SBGGR8 <V4L2-PIX-FMT-SBGGR8>`,
+:ref:`V4L2_PIX_FMT_SGBRG8 <V4L2-PIX-FMT-SGBRG8>`,
+:ref:`V4L2_PIX_FMT_SGRBG8 <V4L2-PIX-FMT-SGRBG8>`,
+:ref:`V4L2_PIX_FMT_SN9C10X <V4L2-PIX-FMT-SN9C10X>`,
+:ref:`V4L2_PIX_FMT_SN9C20X_I420 <V4L2-PIX-FMT-SN9C20X-I420>`,
+:ref:`V4L2_PIX_FMT_SPCA501 <V4L2-PIX-FMT-SPCA501>`,
+:ref:`V4L2_PIX_FMT_SPCA505 <V4L2-PIX-FMT-SPCA505>`,
+:ref:`V4L2_PIX_FMT_SPCA508 <V4L2-PIX-FMT-SPCA508>`,
+:ref:`V4L2_PIX_FMT_SPCA561 <V4L2-PIX-FMT-SPCA561>`,
+:ref:`V4L2_PIX_FMT_SQ905C <V4L2-PIX-FMT-SQ905C>`,
+:ref:`V4L2_PIX_FMT_SRGGB8 <V4L2-PIX-FMT-SRGGB8>`,
+:ref:`V4L2_PIX_FMT_UYVY <V4L2-PIX-FMT-UYVY>`,
+:ref:`V4L2_PIX_FMT_YUV420 <V4L2-PIX-FMT-YUV420>`,
+:ref:`V4L2_PIX_FMT_YUYV <V4L2-PIX-FMT-YUYV>`,
+:ref:`V4L2_PIX_FMT_YVU420 <V4L2-PIX-FMT-YVU420>`, and
+:ref:`V4L2_PIX_FMT_YVYU <V4L2-PIX-FMT-YVYU>`.
+
+Later on libv4lconvert was expanded to also be able to do various video
+processing functions to improve webcam video quality. The video
+processing is split in to 2 parts: libv4lconvert/control and
+libv4lconvert/processing.
+
+The control part is used to offer video controls which can be used to
+control the video processing functions made available by
+libv4lconvert/processing. These controls are stored application wide
+(until reboot) by using a persistent shared memory object.
+
+libv4lconvert/processing offers the actual video processing
+functionality.
+
+
+libv4l1
+=======
+
+This library offers functions that can be used to quickly make v4l1
+applications work with v4l2 devices. These functions work exactly like
+the normal open/close/etc, except that libv4l1 does full emulation of
+the v4l1 api on top of v4l2 drivers, in case of v4l1 drivers it will
+just pass calls through.
+
+Since those functions are emulations of the old V4L1 API, it shouldn't
+be used for new applications.
+
+
+libv4l2
+=======
+
+This library should be used for all modern V4L2 applications.
+
+It provides handles to call V4L2 open/ioctl/close/poll methods. Instead
+of just providing the raw output of the device, it enhances the calls in
+the sense that it will use libv4lconvert to provide more video formats
+and to enhance the image quality.
+
+In most cases, libv4l2 just passes the calls directly through to the
+v4l2 driver, intercepting the calls to
+:ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>`,
+:ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>`,
+:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`,
+:ref:`VIDIOC_ENUM_FRAMESIZES <VIDIOC_ENUM_FRAMESIZES>` and
+:ref:`VIDIOC_ENUM_FRAMEINTERVALS <VIDIOC_ENUM_FRAMEINTERVALS>` in
+order to emulate the formats
+:ref:`V4L2_PIX_FMT_BGR24 <V4L2-PIX-FMT-BGR24>`,
+:ref:`V4L2_PIX_FMT_RGB24 <V4L2-PIX-FMT-RGB24>`,
+:ref:`V4L2_PIX_FMT_YUV420 <V4L2-PIX-FMT-YUV420>`, and
+:ref:`V4L2_PIX_FMT_YVU420 <V4L2-PIX-FMT-YVU420>`, if they aren't
+available in the driver. :ref:`VIDIOC_ENUM_FMT <VIDIOC_ENUM_FMT>`
+keeps enumerating the hardware supported formats, plus the emulated
+formats offered by libv4l at the end.
+
+
+.. _libv4l-ops:
+
+Libv4l device control functions
+-------------------------------
+
+The common file operation methods are provided by libv4l.
+
+Those functions operate just like the gcc function ``dup()`` and
+V4L2 functions
+:c:func:`open() <v4l2-open>`, :c:func:`close() <v4l2-close>`,
+:c:func:`ioctl() <v4l2-ioctl>`, :c:func:`read() <v4l2-read>`,
+:c:func:`mmap() <v4l2-mmap>` and :c:func:`munmap() <v4l2-munmap>`:
+
+.. c:function:: int v4l2_open(const char *file, int oflag, ...)
+
+   operates like the :c:func:`open() <v4l2-open>` function.
+
+.. c:function:: int v4l2_close(int fd)
+
+   operates like the :c:func:`close() <v4l2-close>` function.
+
+.. c:function:: int v4l2_dup(int fd)
+
+   operates like the libc ``dup()`` function, duplicating a file handler.
+
+.. c:function:: int v4l2_ioctl (int fd, unsigned long int request, ...)
+
+   operates like the :c:func:`ioctl() <v4l2-ioctl>` function.
+
+.. c:function:: int v4l2_read (int fd, void* buffer, size_t n)
+
+   operates like the :c:func:`read() <v4l2-read>` function.
+
+.. c:function:: void v4l2_mmap(void *start, size_t length, int prot, int flags, int fd, int64_t offset);
+
+   operates like the :c:func:`munmap() <v4l2-munmap>` function.
+
+.. c:function:: int v4l2_munmap(void *_start, size_t length);
+
+   operates like the :c:func:`munmap() <v4l2-munmap>` function.
+
+Those functions provide additional control:
+
+.. c:function:: int v4l2_fd_open(int fd, int v4l2_flags)
+
+   opens an already opened fd for further use through v4l2lib and possibly
+   modify libv4l2's default behavior through the ``v4l2_flags`` argument.
+   Currently, ``v4l2_flags`` can be ``V4L2_DISABLE_CONVERSION``, to disable
+   format conversion.
+
+.. c:function:: int v4l2_set_control(int fd, int cid, int value)
+
+   This function takes a value of 0 - 65535, and then scales that range to the
+   actual range of the given v4l control id, and then if the cid exists and is
+   not locked sets the cid to the scaled value.
+
+.. c:function:: int v4l2_get_control(int fd, int cid)
+
+   This function returns a value of 0 - 65535, scaled to from the actual range
+   of the given v4l control id. when the cid does not exist, could not be
+   accessed for some reason, or some error occurred 0 is returned.
+
+
+v4l1compat.so wrapper library
+=============================
+
+This library intercepts calls to
+:c:func:`open() <v4l2-open>`, :c:func:`close() <v4l2-close>`,
+:c:func:`ioctl() <v4l2-ioctl>`, :c:func:`mmap() <v4l2-mmap>` and
+:c:func:`munmap() <v4l2-munmap>`
+operations and redirects them to the libv4l counterparts, by using
+``LD_PRELOAD=/usr/lib/v4l1compat.so``. It also emulates V4L1 calls via V4L2
+API.
+
+It allows usage of binary legacy applications that still don't use
+libv4l.
diff --git a/Documentation/userspace-api/media/v4l/libv4l.rst b/Documentation/userspace-api/media/v4l/libv4l.rst
new file mode 100644
index 000000000000..5ea2016cac65
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/libv4l.rst
@@ -0,0 +1,20 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _libv4l:
+
+************************
+Libv4l Userspace Library
+************************
+
+
+.. toctree::
+    :maxdepth: 1
+
+    libv4l-introduction
diff --git a/Documentation/userspace-api/media/v4l/meta-formats.rst b/Documentation/userspace-api/media/v4l/meta-formats.rst
new file mode 100644
index 000000000000..7dcc4bacbb0c
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/meta-formats.rst
@@ -0,0 +1,27 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _meta-formats:
+
+****************
+Metadata Formats
+****************
+
+These formats are used for the :ref:`metadata` interface only.
+
+
+.. toctree::
+    :maxdepth: 1
+
+    pixfmt-meta-d4xx
+    pixfmt-meta-intel-ipu3
+    pixfmt-meta-uvc
+    pixfmt-meta-vsp1-hgo
+    pixfmt-meta-vsp1-hgt
+    pixfmt-meta-vivid
diff --git a/Documentation/userspace-api/media/v4l/mmap.rst b/Documentation/userspace-api/media/v4l/mmap.rst
new file mode 100644
index 000000000000..9c44d05ebc3f
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/mmap.rst
@@ -0,0 +1,292 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _mmap:
+
+******************************
+Streaming I/O (Memory Mapping)
+******************************
+
+Input and output devices support this I/O method when the
+``V4L2_CAP_STREAMING`` flag in the ``capabilities`` field of struct
+:c:type:`v4l2_capability` returned by the
+:ref:`VIDIOC_QUERYCAP` ioctl is set. There are two
+streaming methods, to determine if the memory mapping flavor is
+supported applications must call the :ref:`VIDIOC_REQBUFS` ioctl
+with the memory type set to ``V4L2_MEMORY_MMAP``.
+
+Streaming is an I/O method where only pointers to buffers are exchanged
+between application and driver, the data itself is not copied. Memory
+mapping is primarily intended to map buffers in device memory into the
+application's address space. Device memory can be for example the video
+memory on a graphics card with a video capture add-on. However, being
+the most efficient I/O method available for a long time, many other
+drivers support streaming as well, allocating buffers in DMA-able main
+memory.
+
+A driver can support many sets of buffers. Each set is identified by a
+unique buffer type value. The sets are independent and each set can hold
+a different type of data. To access different sets at the same time
+different file descriptors must be used. [#f1]_
+
+To allocate device buffers applications call the
+:ref:`VIDIOC_REQBUFS` ioctl with the desired number
+of buffers and buffer type, for example ``V4L2_BUF_TYPE_VIDEO_CAPTURE``.
+This ioctl can also be used to change the number of buffers or to free
+the allocated memory, provided none of the buffers are still mapped.
+
+Before applications can access the buffers they must map them into their
+address space with the :ref:`mmap() <func-mmap>` function. The
+location of the buffers in device memory can be determined with the
+:ref:`VIDIOC_QUERYBUF` ioctl. In the single-planar
+API case, the ``m.offset`` and ``length`` returned in a struct
+:c:type:`v4l2_buffer` are passed as sixth and second
+parameter to the :ref:`mmap() <func-mmap>` function. When using the
+multi-planar API, struct :c:type:`v4l2_buffer` contains an
+array of struct :c:type:`v4l2_plane` structures, each
+containing its own ``m.offset`` and ``length``. When using the
+multi-planar API, every plane of every buffer has to be mapped
+separately, so the number of calls to :ref:`mmap() <func-mmap>` should
+be equal to number of buffers times number of planes in each buffer. The
+offset and length values must not be modified. Remember, the buffers are
+allocated in physical memory, as opposed to virtual memory, which can be
+swapped out to disk. Applications should free the buffers as soon as
+possible with the :ref:`munmap() <func-munmap>` function.
+
+Example: Mapping buffers in the single-planar API
+=================================================
+
+.. code-block:: c
+
+    struct v4l2_requestbuffers reqbuf;
+    struct {
+	void *start;
+	size_t length;
+    } *buffers;
+    unsigned int i;
+
+    memset(&reqbuf, 0, sizeof(reqbuf));
+    reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+    reqbuf.memory = V4L2_MEMORY_MMAP;
+    reqbuf.count = 20;
+
+    if (-1 == ioctl (fd, VIDIOC_REQBUFS, &reqbuf)) {
+	if (errno == EINVAL)
+	    printf("Video capturing or mmap-streaming is not supported\\n");
+	else
+	    perror("VIDIOC_REQBUFS");
+
+	exit(EXIT_FAILURE);
+    }
+
+    /* We want at least five buffers. */
+
+    if (reqbuf.count < 5) {
+	/* You may need to free the buffers here. */
+	printf("Not enough buffer memory\\n");
+	exit(EXIT_FAILURE);
+    }
+
+    buffers = calloc(reqbuf.count, sizeof(*buffers));
+    assert(buffers != NULL);
+
+    for (i = 0; i < reqbuf.count; i++) {
+	struct v4l2_buffer buffer;
+
+	memset(&buffer, 0, sizeof(buffer));
+	buffer.type = reqbuf.type;
+	buffer.memory = V4L2_MEMORY_MMAP;
+	buffer.index = i;
+
+	if (-1 == ioctl (fd, VIDIOC_QUERYBUF, &buffer)) {
+	    perror("VIDIOC_QUERYBUF");
+	    exit(EXIT_FAILURE);
+	}
+
+	buffers[i].length = buffer.length; /* remember for munmap() */
+
+	buffers[i].start = mmap(NULL, buffer.length,
+		    PROT_READ | PROT_WRITE, /* recommended */
+		    MAP_SHARED,             /* recommended */
+		    fd, buffer.m.offset);
+
+	if (MAP_FAILED == buffers[i].start) {
+	    /* If you do not exit here you should unmap() and free()
+	       the buffers mapped so far. */
+	    perror("mmap");
+	    exit(EXIT_FAILURE);
+	}
+    }
+
+    /* Cleanup. */
+
+    for (i = 0; i < reqbuf.count; i++)
+	munmap(buffers[i].start, buffers[i].length);
+
+
+Example: Mapping buffers in the multi-planar API
+================================================
+
+.. code-block:: c
+
+    struct v4l2_requestbuffers reqbuf;
+    /* Our current format uses 3 planes per buffer */
+    #define FMT_NUM_PLANES = 3
+
+    struct {
+	void *start[FMT_NUM_PLANES];
+	size_t length[FMT_NUM_PLANES];
+    } *buffers;
+    unsigned int i, j;
+
+    memset(&reqbuf, 0, sizeof(reqbuf));
+    reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+    reqbuf.memory = V4L2_MEMORY_MMAP;
+    reqbuf.count = 20;
+
+    if (ioctl(fd, VIDIOC_REQBUFS, &reqbuf) < 0) {
+	if (errno == EINVAL)
+	    printf("Video capturing or mmap-streaming is not supported\\n");
+	else
+	    perror("VIDIOC_REQBUFS");
+
+	exit(EXIT_FAILURE);
+    }
+
+    /* We want at least five buffers. */
+
+    if (reqbuf.count < 5) {
+	/* You may need to free the buffers here. */
+	printf("Not enough buffer memory\\n");
+	exit(EXIT_FAILURE);
+    }
+
+    buffers = calloc(reqbuf.count, sizeof(*buffers));
+    assert(buffers != NULL);
+
+    for (i = 0; i < reqbuf.count; i++) {
+	struct v4l2_buffer buffer;
+	struct v4l2_plane planes[FMT_NUM_PLANES];
+
+	memset(&buffer, 0, sizeof(buffer));
+	buffer.type = reqbuf.type;
+	buffer.memory = V4L2_MEMORY_MMAP;
+	buffer.index = i;
+	/* length in struct v4l2_buffer in multi-planar API stores the size
+	 * of planes array. */
+	buffer.length = FMT_NUM_PLANES;
+	buffer.m.planes = planes;
+
+	if (ioctl(fd, VIDIOC_QUERYBUF, &buffer) < 0) {
+	    perror("VIDIOC_QUERYBUF");
+	    exit(EXIT_FAILURE);
+	}
+
+	/* Every plane has to be mapped separately */
+	for (j = 0; j < FMT_NUM_PLANES; j++) {
+	    buffers[i].length[j] = buffer.m.planes[j].length; /* remember for munmap() */
+
+	    buffers[i].start[j] = mmap(NULL, buffer.m.planes[j].length,
+		     PROT_READ | PROT_WRITE, /* recommended */
+		     MAP_SHARED,             /* recommended */
+		     fd, buffer.m.planes[j].m.offset);
+
+	    if (MAP_FAILED == buffers[i].start[j]) {
+		/* If you do not exit here you should unmap() and free()
+		   the buffers and planes mapped so far. */
+		perror("mmap");
+		exit(EXIT_FAILURE);
+	    }
+	}
+    }
+
+    /* Cleanup. */
+
+    for (i = 0; i < reqbuf.count; i++)
+	for (j = 0; j < FMT_NUM_PLANES; j++)
+	    munmap(buffers[i].start[j], buffers[i].length[j]);
+
+Conceptually streaming drivers maintain two buffer queues, an incoming
+and an outgoing queue. They separate the synchronous capture or output
+operation locked to a video clock from the application which is subject
+to random disk or network delays and preemption by other processes,
+thereby reducing the probability of data loss. The queues are organized
+as FIFOs, buffers will be output in the order enqueued in the incoming
+FIFO, and were captured in the order dequeued from the outgoing FIFO.
+
+The driver may require a minimum number of buffers enqueued at all times
+to function, apart of this no limit exists on the number of buffers
+applications can enqueue in advance, or dequeue and process. They can
+also enqueue in a different order than buffers have been dequeued, and
+the driver can *fill* enqueued *empty* buffers in any order.  [#f2]_ The
+index number of a buffer (struct :c:type:`v4l2_buffer`
+``index``) plays no role here, it only identifies the buffer.
+
+Initially all mapped buffers are in dequeued state, inaccessible by the
+driver. For capturing applications it is customary to first enqueue all
+mapped buffers, then to start capturing and enter the read loop. Here
+the application waits until a filled buffer can be dequeued, and
+re-enqueues the buffer when the data is no longer needed. Output
+applications fill and enqueue buffers, when enough buffers are stacked
+up the output is started with :ref:`VIDIOC_STREAMON <VIDIOC_STREAMON>`.
+In the write loop, when the application runs out of free buffers, it
+must wait until an empty buffer can be dequeued and reused.
+
+To enqueue and dequeue a buffer applications use the
+:ref:`VIVIOC_QBUF <VIDIOC_QBUF>` and :ref:`VIDIOC_DQBUF <VIDIOC_QBUF>`
+ioctl. The status of a buffer being mapped, enqueued, full or empty can
+be determined at any time using the :ref:`VIDIOC_QUERYBUF` ioctl. Two
+methods exist to suspend execution of the application until one or more
+buffers can be dequeued.  By default :ref:`VIDIOC_DQBUF <VIDIOC_QBUF>`
+blocks when no buffer is in the outgoing queue. When the ``O_NONBLOCK``
+flag was given to the :ref:`open() <func-open>` function,
+:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` returns immediately with an ``EAGAIN``
+error code when no buffer is available. The :ref:`select() <func-select>`
+or :ref:`poll() <func-poll>` functions are always available.
+
+To start and stop capturing or output applications call the
+:ref:`VIDIOC_STREAMON <VIDIOC_STREAMON>` and :ref:`VIDIOC_STREAMOFF
+<VIDIOC_STREAMON>` ioctl.
+
+.. note:::ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>`
+   removes all buffers from both queues as a side effect. Since there is
+   no notion of doing anything "now" on a multitasking system, if an
+   application needs to synchronize with another event it should examine
+   the struct ::c:type:`v4l2_buffer` ``timestamp`` of captured
+   or outputted buffers.
+
+Drivers implementing memory mapping I/O must support the
+:ref:`VIDIOC_REQBUFS <VIDIOC_REQBUFS>`, :ref:`VIDIOC_QUERYBUF
+<VIDIOC_QUERYBUF>`, :ref:`VIDIOC_QBUF <VIDIOC_QBUF>`, :ref:`VIDIOC_DQBUF
+<VIDIOC_QBUF>`, :ref:`VIDIOC_STREAMON <VIDIOC_STREAMON>`
+and :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` ioctls, the :ref:`mmap()
+<func-mmap>`, :ref:`munmap() <func-munmap>`, :ref:`select()
+<func-select>` and :ref:`poll() <func-poll>` function. [#f3]_
+
+[capture example]
+
+.. [#f1]
+   One could use one file descriptor and set the buffer type field
+   accordingly when calling :ref:`VIDIOC_QBUF` etc.,
+   but it makes the :ref:`select() <func-select>` function ambiguous. We also
+   like the clean approach of one file descriptor per logical stream.
+   Video overlay for example is also a logical stream, although the CPU
+   is not needed for continuous operation.
+
+.. [#f2]
+   Random enqueue order permits applications processing images out of
+   order (such as video codecs) to return buffers earlier, reducing the
+   probability of data loss. Random fill order allows drivers to reuse
+   buffers on a LIFO-basis, taking advantage of caches holding
+   scatter-gather lists and the like.
+
+.. [#f3]
+   At the driver level :ref:`select() <func-select>` and :ref:`poll() <func-poll>` are
+   the same, and :ref:`select() <func-select>` is too important to be optional.
+   The rest should be evident.
diff --git a/Documentation/userspace-api/media/v4l/nv12mt.svg b/Documentation/userspace-api/media/v4l/nv12mt.svg
new file mode 100644
index 000000000000..d4bb4eb83f6a
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/nv12mt.svg
@@ -0,0 +1,477 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+    This file is dual-licensed: you can use it either under the terms
+    of the GPL 2.0 or the GFDL 1.1+ license, at your option. Note that this
+    dual licensing only applies to this file, and not this project as a
+    whole.
+
+    a) This file is free software; you can redistribute it and/or
+       modify it under the terms of the GNU General Public License as
+       published by the Free Software Foundation version 2 of
+       the License.
+
+       This file is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+    Or, alternatively,
+
+    b) Permission is granted to copy, distribute and/or modify this
+       document under the terms of the GNU Free Documentation License,
+       Version 1.1 or any later version published by the Free Software
+       Foundation, with no Invariant Sections, no Front-Cover Texts
+       and no Back-Cover Texts. A copy of the license is included at
+       Documentation/userspace-api/media/fdl-appendix.rst.
+
+    TODO: replace it to GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
+-->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.2"
+   width="96.282211mm"
+   height="28.282219mm"
+   viewBox="0 0 9628.2211 2828.2219"
+   preserveAspectRatio="xMidYMid"
+   xml:space="preserve"
+   id="svg2"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="nv12mt.svg"
+   style="fill-rule:evenodd;stroke-width:28.22200012;stroke-linejoin:round"><metadata
+     id="metadata383"><rdf:RDF><cc:Work
+	 rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+	   rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="997"
+     id="namedview381"
+     showgrid="false"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0"
+     inkscape:zoom="4.0919524"
+     inkscape:cx="170.57872"
+     inkscape:cy="50.106293"
+     inkscape:window-x="1920"
+     inkscape:window-y="30"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg2" /><defs
+     class="ClipPathGroup"
+     id="defs4"><clipPath
+       id="presentation_clip_path"
+       clipPathUnits="userSpaceOnUse"><rect
+	 x="0"
+	 y="0"
+	 width="28000"
+	 height="21000"
+	 id="rect7" /></clipPath></defs><defs
+     id="defs9" /><defs
+     id="defs80" /><defs
+     id="defs103" /><defs
+     class="TextShapeIndex"
+     id="defs114" /><defs
+     class="EmbeddedBulletChars"
+     id="defs118" /><defs
+     class="TextEmbeddedBitmaps"
+     id="defs147" /><g
+     class="SlideGroup"
+     id="g177"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="g179"><g
+	 id="id1"
+	 class="Slide"
+	 clip-path="url(#presentation_clip_path)"><g
+	   class="Page"
+	   id="g182"><g
+	     class="com.sun.star.drawing.CustomShape"
+	     id="g184"><g
+	       id="id6"><rect
+		 class="BoundingBox"
+		 x="3299"
+		 y="3199"
+		 width="2403"
+		 height="1403"
+		 id="rect187"
+		 style="fill:none;stroke:none" /><path
+		 d="m 4500,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+		 id="path189"
+		 inkscape:connector-curvature="0"
+		 style="fill:none;stroke:#3465a4" /><text
+		 class="TextShape"
+		 id="text191"><tspan
+		   class="TextParagraph"
+		   font-size="635px"
+		   font-weight="400"
+		   id="tspan193"
+		   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+		     class="TextPosition"
+		     x="4325"
+		     y="4121"
+		     id="tspan195"><tspan
+		       id="tspan197"
+		       style="fill:#000000;stroke:none">0</tspan></tspan></tspan></text>
+</g></g><g
+	     class="com.sun.star.drawing.CustomShape"
+	     id="g199"><g
+	       id="id7"><rect
+		 class="BoundingBox"
+		 x="5699"
+		 y="3199"
+		 width="2403"
+		 height="1403"
+		 id="rect202"
+		 style="fill:none;stroke:none" /><path
+		 d="m 6900,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+		 id="path204"
+		 inkscape:connector-curvature="0"
+		 style="fill:none;stroke:#3465a4" /></g></g><g
+	     class="com.sun.star.drawing.CustomShape"
+	     id="g206"><g
+	       id="id8"><rect
+		 class="BoundingBox"
+		 x="8099"
+		 y="3199"
+		 width="2403"
+		 height="1403"
+		 id="rect209"
+		 style="fill:none;stroke:none" /><path
+		 d="m 9300,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+		 id="path211"
+		 inkscape:connector-curvature="0"
+		 style="fill:none;stroke:#3465a4" /><text
+		 class="TextShape"
+		 id="text213"><tspan
+		   class="TextParagraph"
+		   font-size="635px"
+		   font-weight="400"
+		   id="tspan215"
+		   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+		     class="TextPosition"
+		     x="9125"
+		     y="4121"
+		     id="tspan217"><tspan
+		       id="tspan219"
+		       style="fill:#000000;stroke:none">6</tspan></tspan></tspan></text>
+</g></g><g
+	     class="com.sun.star.drawing.CustomShape"
+	     id="g221"><g
+	       id="id9"><rect
+		 class="BoundingBox"
+		 x="5699"
+		 y="3199"
+		 width="2403"
+		 height="1403"
+		 id="rect224"
+		 style="fill:none;stroke:none" /><path
+		 d="m 6900,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+		 id="path226"
+		 inkscape:connector-curvature="0"
+		 style="fill:none;stroke:#3465a4" /><text
+		 class="TextShape"
+		 id="text228"><tspan
+		   class="TextParagraph"
+		   font-size="635px"
+		   font-weight="400"
+		   id="tspan230"
+		   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+		     class="TextPosition"
+		     x="6725"
+		     y="4121"
+		     id="tspan232"><tspan
+		       id="tspan234"
+		       style="fill:#000000;stroke:none">1</tspan></tspan></tspan></text>
+</g></g><g
+	     class="com.sun.star.drawing.CustomShape"
+	     id="g236"><g
+	       id="id10"><rect
+		 class="BoundingBox"
+		 x="10499"
+		 y="3199"
+		 width="2403"
+		 height="1403"
+		 id="rect239"
+		 style="fill:none;stroke:none" /><path
+		 d="m 11700,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+		 id="path241"
+		 inkscape:connector-curvature="0"
+		 style="fill:none;stroke:#3465a4" /><text
+		 class="TextShape"
+		 id="text243"><tspan
+		   class="TextParagraph"
+		   font-size="635px"
+		   font-weight="400"
+		   id="tspan245"
+		   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+		     class="TextPosition"
+		     x="11525"
+		     y="4121"
+		     id="tspan247"><tspan
+		       id="tspan249"
+		       style="fill:#000000;stroke:none">7</tspan></tspan></tspan></text>
+</g></g><g
+	     class="com.sun.star.drawing.CustomShape"
+	     id="g251"><g
+	       id="id11"><rect
+		 class="BoundingBox"
+		 x="3299"
+		 y="4599"
+		 width="2403"
+		 height="1403"
+		 id="rect254"
+		 style="fill:none;stroke:none" /><path
+		 d="m 4500,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+		 id="path256"
+		 inkscape:connector-curvature="0"
+		 style="fill:none;stroke:#3465a4" /><text
+		 class="TextShape"
+		 id="text258"><tspan
+		   class="TextParagraph"
+		   font-size="635px"
+		   font-weight="400"
+		   id="tspan260"
+		   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+		     class="TextPosition"
+		     x="4325"
+		     y="5521"
+		     id="tspan262"><tspan
+		       id="tspan264"
+		       style="fill:#000000;stroke:none">2</tspan></tspan></tspan></text>
+</g></g><g
+	     class="com.sun.star.drawing.CustomShape"
+	     id="g266"><g
+	       id="id12"><rect
+		 class="BoundingBox"
+		 x="5699"
+		 y="4599"
+		 width="2403"
+		 height="1403"
+		 id="rect269"
+		 style="fill:none;stroke:none" /><path
+		 d="m 6900,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+		 id="path271"
+		 inkscape:connector-curvature="0"
+		 style="fill:none;stroke:#3465a4" /></g></g><g
+	     class="com.sun.star.drawing.CustomShape"
+	     id="g273"><g
+	       id="id13"><rect
+		 class="BoundingBox"
+		 x="8099"
+		 y="4599"
+		 width="2403"
+		 height="1403"
+		 id="rect276"
+		 style="fill:none;stroke:none" /><path
+		 d="m 9300,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+		 id="path278"
+		 inkscape:connector-curvature="0"
+		 style="fill:none;stroke:#3465a4" /><text
+		 class="TextShape"
+		 id="text280"><tspan
+		   class="TextParagraph"
+		   font-size="635px"
+		   font-weight="400"
+		   id="tspan282"
+		   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+		     class="TextPosition"
+		     x="9125"
+		     y="5521"
+		     id="tspan284"><tspan
+		       id="tspan286"
+		       style="fill:#000000;stroke:none">4</tspan></tspan></tspan></text>
+</g></g><g
+	     class="com.sun.star.drawing.CustomShape"
+	     id="g288"><g
+	       id="id14"><rect
+		 class="BoundingBox"
+		 x="5699"
+		 y="4599"
+		 width="2403"
+		 height="1403"
+		 id="rect291"
+		 style="fill:none;stroke:none" /><path
+		 d="m 6900,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+		 id="path293"
+		 inkscape:connector-curvature="0"
+		 style="fill:none;stroke:#3465a4" /><text
+		 class="TextShape"
+		 id="text295"><tspan
+		   class="TextParagraph"
+		   font-size="635px"
+		   font-weight="400"
+		   id="tspan297"
+		   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+		     class="TextPosition"
+		     x="6725"
+		     y="5521"
+		     id="tspan299"><tspan
+		       id="tspan301"
+		       style="fill:#000000;stroke:none">3</tspan></tspan></tspan></text>
+</g></g><g
+	     class="com.sun.star.drawing.CustomShape"
+	     id="g303"><g
+	       id="id15"><rect
+		 class="BoundingBox"
+		 x="10499"
+		 y="4599"
+		 width="2403"
+		 height="1403"
+		 id="rect306"
+		 style="fill:none;stroke:none" /><path
+		 d="m 11700,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+		 id="path308"
+		 inkscape:connector-curvature="0"
+		 style="fill:none;stroke:#3465a4" /><text
+		 class="TextShape"
+		 id="text310"><tspan
+		   class="TextParagraph"
+		   font-size="635px"
+		   font-weight="400"
+		   id="tspan312"
+		   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+		     class="TextPosition"
+		     x="11525"
+		     y="5521"
+		     id="tspan314"><tspan
+		       id="tspan316"
+		       style="fill:#000000;stroke:none">5</tspan></tspan></tspan></text>
+</g></g><g
+	     class="com.sun.star.drawing.LineShape"
+	     id="g318"><g
+	       id="id16"><rect
+		 class="BoundingBox"
+		 x="5199"
+		 y="3850"
+		 width="1402"
+		 height="301"
+		 id="rect321"
+		 style="fill:none;stroke:none" /><path
+		 d="m 5200,4000 970,0"
+		 id="path323"
+		 inkscape:connector-curvature="0"
+		 style="fill:none;stroke:#ff3333" /><path
+		 d="m 6600,4000 -450,-150 0,300 450,-150 z"
+		 id="path325"
+		 inkscape:connector-curvature="0"
+		 style="fill:#ff3333;stroke:none" /></g></g><g
+	     class="com.sun.star.drawing.LineShape"
+	     id="g327"><g
+	       id="id17"><rect
+		 class="BoundingBox"
+		 x="5000"
+		 y="4299"
+		 width="1202"
+		 height="802"
+		 id="rect330"
+		 style="fill:none;stroke:none" /><path
+		 d="m 6200,4300 -842,561"
+		 id="path332"
+		 inkscape:connector-curvature="0"
+		 style="fill:none;stroke:#ff3333" /><path
+		 d="m 5000,5100 458,-125 -167,-249 -291,374 z"
+		 id="path334"
+		 inkscape:connector-curvature="0"
+		 style="fill:#ff3333;stroke:none" /></g></g><g
+	     class="com.sun.star.drawing.LineShape"
+	     id="g336"><g
+	       id="id18"><rect
+		 class="BoundingBox"
+		 x="5399"
+		 y="5250"
+		 width="1202"
+		 height="301"
+		 id="rect339"
+		 style="fill:none;stroke:none" /><path
+		 d="m 5400,5400 770,0"
+		 id="path341"
+		 inkscape:connector-curvature="0"
+		 style="fill:none;stroke:#ff3333" /><path
+		 d="m 6600,5400 -450,-150 0,300 450,-150 z"
+		 id="path343"
+		 inkscape:connector-curvature="0"
+		 style="fill:#ff3333;stroke:none" /></g></g><g
+	     class="com.sun.star.drawing.LineShape"
+	     id="g345"><g
+	       id="id19"><rect
+		 class="BoundingBox"
+		 x="7599"
+		 y="5250"
+		 width="1202"
+		 height="301"
+		 id="rect348"
+		 style="fill:none;stroke:none" /><path
+		 d="m 7600,5400 770,0"
+		 id="path350"
+		 inkscape:connector-curvature="0"
+		 style="fill:none;stroke:#ff3333" /><path
+		 d="m 8800,5400 -450,-150 0,300 450,-150 z"
+		 id="path352"
+		 inkscape:connector-curvature="0"
+		 style="fill:#ff3333;stroke:none" /></g></g><g
+	     class="com.sun.star.drawing.LineShape"
+	     id="g354"><g
+	       id="id20"><rect
+		 class="BoundingBox"
+		 x="9799"
+		 y="5250"
+		 width="1402"
+		 height="301"
+		 id="rect357"
+		 style="fill:none;stroke:none" /><path
+		 d="m 9800,5400 970,0"
+		 id="path359"
+		 inkscape:connector-curvature="0"
+		 style="fill:none;stroke:#ff3333" /><path
+		 d="m 11200,5400 -450,-150 0,300 450,-150 z"
+		 id="path361"
+		 inkscape:connector-curvature="0"
+		 style="fill:#ff3333;stroke:none" /></g></g><g
+	     class="com.sun.star.drawing.LineShape"
+	     id="g363"><g
+	       id="id21"><rect
+		 class="BoundingBox"
+		 x="9900"
+		 y="4200"
+		 width="1202"
+		 height="802"
+		 id="rect366"
+		 style="fill:none;stroke:none" /><path
+		 d="m 11100,5000 -842,-561"
+		 id="path368"
+		 inkscape:connector-curvature="0"
+		 style="fill:none;stroke:#ff3333" /><path
+		 d="m 9900,4200 291,374 167,-249 -458,-125 z"
+		 id="path370"
+		 inkscape:connector-curvature="0"
+		 style="fill:#ff3333;stroke:none" /></g></g><g
+	     class="com.sun.star.drawing.LineShape"
+	     id="g372"><g
+	       id="id22"><rect
+		 class="BoundingBox"
+		 x="9999"
+		 y="3850"
+		 width="1402"
+		 height="301"
+		 id="rect375"
+		 style="fill:none;stroke:none" /><path
+		 d="m 10000,4000 970,0"
+		 id="path377"
+		 inkscape:connector-curvature="0"
+		 style="fill:none;stroke:#ff3333" /><path
+		 d="m 11400,4000 -450,-150 0,300 450,-150 z"
+		 id="path379"
+		 inkscape:connector-curvature="0"
+		 style="fill:#ff3333;stroke:none" /></g></g></g></g></g></g></svg>
diff --git a/Documentation/userspace-api/media/v4l/nv12mt_example.svg b/Documentation/userspace-api/media/v4l/nv12mt_example.svg
new file mode 100644
index 000000000000..e5075af9f45a
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/nv12mt_example.svg
@@ -0,0 +1,1616 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+    This file is dual-licensed: you can use it either under the terms
+    of the GPL 2.0 or the GFDL 1.1+ license, at your option. Note that this
+    dual licensing only applies to this file, and not this project as a
+    whole.
+
+    a) This file is free software; you can redistribute it and/or
+       modify it under the terms of the GNU General Public License as
+       published by the Free Software Foundation version 2 of
+       the License.
+
+       This file is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+    Or, alternatively,
+
+    b) Permission is granted to copy, distribute and/or modify this
+       document under the terms of the GNU Free Documentation License,
+       Version 1.1 or any later version published by the Free Software
+       Foundation, with no Invariant Sections, no Front-Cover Texts
+       and no Back-Cover Texts. A copy of the license is included at
+       Documentation/userspace-api/media/fdl-appendix.rst.
+
+    TODO: replace it to GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
+-->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.2"
+   width="144.28223mm"
+   height="70.282227mm"
+   viewBox="0 0 14428.222 7028.2226"
+   preserveAspectRatio="xMidYMid"
+   xml:space="preserve"
+   id="svg2"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="nv12mt_example.svg"
+   style="fill-rule:evenodd;stroke-width:28.22200012;stroke-linejoin:round"><metadata
+     id="metadata953"><rdf:RDF><cc:Work
+	 rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+	   rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="997"
+     id="namedview951"
+     showgrid="false"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0"
+     inkscape:zoom="2.7306359"
+     inkscape:cx="255.61812"
+     inkscape:cy="124.51576"
+     inkscape:window-x="1920"
+     inkscape:window-y="30"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg2" /><defs
+     class="ClipPathGroup"
+     id="defs4" /><defs
+     id="defs9" /><defs
+     id="defs84" /><defs
+     id="defs107" /><defs
+     class="TextShapeIndex"
+     id="defs118" /><defs
+     class="EmbeddedBulletChars"
+     id="defs122" /><defs
+     class="TextEmbeddedBitmaps"
+     id="defs151" /><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g188"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id6"><rect
+	 class="BoundingBox"
+	 x="3299"
+	 y="3199"
+	 width="2403"
+	 height="1403"
+	 id="rect191"
+	 style="fill:none;stroke:none" /><path
+	 d="m 4500,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path193"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /><text
+	 class="TextShape"
+	 id="text195"><tspan
+	   class="TextParagraph"
+	   font-size="635px"
+	   font-weight="400"
+	   id="tspan197"
+	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+	     class="TextPosition"
+	     x="4325"
+	     y="4121"
+	     id="tspan199"><tspan
+	       id="tspan201"
+	       style="fill:#000000;stroke:none">0</tspan></tspan></tspan></text>
+</g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g203"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id7"><rect
+	 class="BoundingBox"
+	 x="5699"
+	 y="3199"
+	 width="2403"
+	 height="1403"
+	 id="rect206"
+	 style="fill:none;stroke:none" /><path
+	 d="m 6900,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path208"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /></g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g210"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id8"><rect
+	 class="BoundingBox"
+	 x="8099"
+	 y="3199"
+	 width="2403"
+	 height="1403"
+	 id="rect213"
+	 style="fill:none;stroke:none" /><path
+	 d="m 9300,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path215"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /><text
+	 class="TextShape"
+	 id="text217"><tspan
+	   class="TextParagraph"
+	   font-size="635px"
+	   font-weight="400"
+	   id="tspan219"
+	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+	     class="TextPosition"
+	     x="9125"
+	     y="4121"
+	     id="tspan221"><tspan
+	       id="tspan223"
+	       style="fill:#000000;stroke:none">6</tspan></tspan></tspan></text>
+</g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g225"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id9"><rect
+	 class="BoundingBox"
+	 x="5699"
+	 y="3199"
+	 width="2403"
+	 height="1403"
+	 id="rect228"
+	 style="fill:none;stroke:none" /><path
+	 d="m 6900,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path230"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /><text
+	 class="TextShape"
+	 id="text232"><tspan
+	   class="TextParagraph"
+	   font-size="635px"
+	   font-weight="400"
+	   id="tspan234"
+	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+	     class="TextPosition"
+	     x="6725"
+	     y="4121"
+	     id="tspan236"><tspan
+	       id="tspan238"
+	       style="fill:#000000;stroke:none">1</tspan></tspan></tspan></text>
+</g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g240"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id10"><rect
+	 class="BoundingBox"
+	 x="10499"
+	 y="3199"
+	 width="2403"
+	 height="1403"
+	 id="rect243"
+	 style="fill:none;stroke:none" /><path
+	 d="m 11700,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path245"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /><text
+	 class="TextShape"
+	 id="text247"><tspan
+	   class="TextParagraph"
+	   font-size="635px"
+	   font-weight="400"
+	   id="tspan249"
+	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+	     class="TextPosition"
+	     x="11525"
+	     y="4121"
+	     id="tspan251"><tspan
+	       id="tspan253"
+	       style="fill:#000000;stroke:none">7</tspan></tspan></tspan></text>
+</g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g255"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id11"><rect
+	 class="BoundingBox"
+	 x="12899"
+	 y="3199"
+	 width="2403"
+	 height="1403"
+	 id="rect258"
+	 style="fill:none;stroke:none" /><path
+	 d="m 14100,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path260"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /></g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g262"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id12"><rect
+	 class="BoundingBox"
+	 x="15299"
+	 y="3199"
+	 width="2403"
+	 height="1403"
+	 id="rect265"
+	 style="fill:none;stroke:none" /><path
+	 d="m 16500,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path267"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /><text
+	 class="TextShape"
+	 id="text269"><tspan
+	   class="TextParagraph"
+	   font-size="635px"
+	   font-weight="400"
+	   id="tspan271"
+	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+	     class="TextPosition"
+	     x="16325"
+	     y="4121"
+	     id="tspan273"><tspan
+	       id="tspan275"
+	       style="fill:#000000;stroke:none">9</tspan></tspan></tspan></text>
+</g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g277"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id13"><rect
+	 class="BoundingBox"
+	 x="12899"
+	 y="3199"
+	 width="2403"
+	 height="1403"
+	 id="rect280"
+	 style="fill:none;stroke:none" /><path
+	 d="m 14100,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path282"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /><text
+	 class="TextShape"
+	 id="text284"><tspan
+	   class="TextParagraph"
+	   font-size="635px"
+	   font-weight="400"
+	   id="tspan286"
+	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+	     class="TextPosition"
+	     x="13925"
+	     y="4121"
+	     id="tspan288"><tspan
+	       id="tspan290"
+	       style="fill:#000000;stroke:none">8</tspan></tspan></tspan></text>
+</g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g292"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id14"><rect
+	 class="BoundingBox"
+	 x="3299"
+	 y="4599"
+	 width="2403"
+	 height="1403"
+	 id="rect295"
+	 style="fill:none;stroke:none" /><path
+	 d="m 4500,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path297"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /><text
+	 class="TextShape"
+	 id="text299"><tspan
+	   class="TextParagraph"
+	   font-size="635px"
+	   font-weight="400"
+	   id="tspan301"
+	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+	     class="TextPosition"
+	     x="4325"
+	     y="5521"
+	     id="tspan303"><tspan
+	       id="tspan305"
+	       style="fill:#000000;stroke:none">2</tspan></tspan></tspan></text>
+</g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g307"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id15"><rect
+	 class="BoundingBox"
+	 x="5699"
+	 y="4599"
+	 width="2403"
+	 height="1403"
+	 id="rect310"
+	 style="fill:none;stroke:none" /><path
+	 d="m 6900,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path312"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /></g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g314"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id16"><rect
+	 class="BoundingBox"
+	 x="8099"
+	 y="4599"
+	 width="2403"
+	 height="1403"
+	 id="rect317"
+	 style="fill:none;stroke:none" /><path
+	 d="m 9300,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path319"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /><text
+	 class="TextShape"
+	 id="text321"><tspan
+	   class="TextParagraph"
+	   font-size="635px"
+	   font-weight="400"
+	   id="tspan323"
+	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+	     class="TextPosition"
+	     x="9125"
+	     y="5521"
+	     id="tspan325"><tspan
+	       id="tspan327"
+	       style="fill:#000000;stroke:none">4</tspan></tspan></tspan></text>
+</g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g329"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id17"><rect
+	 class="BoundingBox"
+	 x="5699"
+	 y="4599"
+	 width="2403"
+	 height="1403"
+	 id="rect332"
+	 style="fill:none;stroke:none" /><path
+	 d="m 6900,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path334"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /><text
+	 class="TextShape"
+	 id="text336"><tspan
+	   class="TextParagraph"
+	   font-size="635px"
+	   font-weight="400"
+	   id="tspan338"
+	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+	     class="TextPosition"
+	     x="6725"
+	     y="5521"
+	     id="tspan340"><tspan
+	       id="tspan342"
+	       style="fill:#000000;stroke:none">3</tspan></tspan></tspan></text>
+</g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g344"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id18"><rect
+	 class="BoundingBox"
+	 x="10499"
+	 y="4599"
+	 width="2403"
+	 height="1403"
+	 id="rect347"
+	 style="fill:none;stroke:none" /><path
+	 d="m 11700,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path349"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /><text
+	 class="TextShape"
+	 id="text351"><tspan
+	   class="TextParagraph"
+	   font-size="635px"
+	   font-weight="400"
+	   id="tspan353"
+	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+	     class="TextPosition"
+	     x="11525"
+	     y="5521"
+	     id="tspan355"><tspan
+	       id="tspan357"
+	       style="fill:#000000;stroke:none">5</tspan></tspan></tspan></text>
+</g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g359"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id19"><rect
+	 class="BoundingBox"
+	 x="12899"
+	 y="4599"
+	 width="2403"
+	 height="1403"
+	 id="rect362"
+	 style="fill:none;stroke:none" /><path
+	 d="m 14100,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path364"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /></g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g366"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id20"><rect
+	 class="BoundingBox"
+	 x="15299"
+	 y="4599"
+	 width="2403"
+	 height="1403"
+	 id="rect369"
+	 style="fill:none;stroke:none" /><path
+	 d="m 16500,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path371"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /><text
+	 class="TextShape"
+	 id="text373"><tspan
+	   class="TextParagraph"
+	   font-size="635px"
+	   font-weight="400"
+	   id="tspan375"
+	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+	     class="TextPosition"
+	     x="16149"
+	     y="5521"
+	     id="tspan377"><tspan
+	       id="tspan379"
+	       style="fill:#000000;stroke:none">11</tspan></tspan></tspan></text>
+</g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g381"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id21"><rect
+	 class="BoundingBox"
+	 x="12899"
+	 y="4599"
+	 width="2403"
+	 height="1403"
+	 id="rect384"
+	 style="fill:none;stroke:none" /><path
+	 d="m 14100,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path386"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /><text
+	 class="TextShape"
+	 id="text388"><tspan
+	   class="TextParagraph"
+	   font-size="635px"
+	   font-weight="400"
+	   id="tspan390"
+	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+	     class="TextPosition"
+	     x="13749"
+	     y="5521"
+	     id="tspan392"><tspan
+	       id="tspan394"
+	       style="fill:#000000;stroke:none">10</tspan></tspan></tspan></text>
+</g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g396"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id22"><rect
+	 class="BoundingBox"
+	 x="3299"
+	 y="5999"
+	 width="2403"
+	 height="1403"
+	 id="rect399"
+	 style="fill:none;stroke:none" /><path
+	 d="m 4500,7400 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path401"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /><text
+	 class="TextShape"
+	 id="text403"><tspan
+	   class="TextParagraph"
+	   font-size="635px"
+	   font-weight="400"
+	   id="tspan405"
+	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+	     class="TextPosition"
+	     x="4149"
+	     y="6921"
+	     id="tspan407"><tspan
+	       id="tspan409"
+	       style="fill:#000000;stroke:none">12</tspan></tspan></tspan></text>
+</g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g411"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id23"><rect
+	 class="BoundingBox"
+	 x="5699"
+	 y="5999"
+	 width="2403"
+	 height="1403"
+	 id="rect414"
+	 style="fill:none;stroke:none" /><path
+	 d="m 6900,7400 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path416"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /></g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g418"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id24"><rect
+	 class="BoundingBox"
+	 x="8099"
+	 y="5999"
+	 width="2403"
+	 height="1403"
+	 id="rect421"
+	 style="fill:none;stroke:none" /><path
+	 d="m 9300,7400 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path423"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /><text
+	 class="TextShape"
+	 id="text425"><tspan
+	   class="TextParagraph"
+	   font-size="635px"
+	   font-weight="400"
+	   id="tspan427"
+	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+	     class="TextPosition"
+	     x="8949"
+	     y="6921"
+	     id="tspan429"><tspan
+	       id="tspan431"
+	       style="fill:#000000;stroke:none">18</tspan></tspan></tspan></text>
+</g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g433"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id25"><rect
+	 class="BoundingBox"
+	 x="5699"
+	 y="5999"
+	 width="2403"
+	 height="1403"
+	 id="rect436"
+	 style="fill:none;stroke:none" /><path
+	 d="m 6900,7400 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path438"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /><text
+	 class="TextShape"
+	 id="text440"><tspan
+	   class="TextParagraph"
+	   font-size="635px"
+	   font-weight="400"
+	   id="tspan442"
+	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+	     class="TextPosition"
+	     x="6549"
+	     y="6921"
+	     id="tspan444"><tspan
+	       id="tspan446"
+	       style="fill:#000000;stroke:none">13</tspan></tspan></tspan></text>
+</g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g448"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id26"><rect
+	 class="BoundingBox"
+	 x="10499"
+	 y="5999"
+	 width="2403"
+	 height="1403"
+	 id="rect451"
+	 style="fill:none;stroke:none" /><path
+	 d="m 11700,7400 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path453"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /><text
+	 class="TextShape"
+	 id="text455"><tspan
+	   class="TextParagraph"
+	   font-size="635px"
+	   font-weight="400"
+	   id="tspan457"
+	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+	     class="TextPosition"
+	     x="11349"
+	     y="6921"
+	     id="tspan459"><tspan
+	       id="tspan461"
+	       style="fill:#000000;stroke:none">19</tspan></tspan></tspan></text>
+</g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g463"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id27"><rect
+	 class="BoundingBox"
+	 x="12899"
+	 y="5999"
+	 width="2403"
+	 height="1403"
+	 id="rect466"
+	 style="fill:none;stroke:none" /><path
+	 d="m 14100,7400 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path468"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /></g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g470"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id28"><rect
+	 class="BoundingBox"
+	 x="15299"
+	 y="5999"
+	 width="2403"
+	 height="1403"
+	 id="rect473"
+	 style="fill:none;stroke:none" /><path
+	 d="m 16500,7400 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path475"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /><text
+	 class="TextShape"
+	 id="text477"><tspan
+	   class="TextParagraph"
+	   font-size="635px"
+	   font-weight="400"
+	   id="tspan479"
+	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+	     class="TextPosition"
+	     x="16149"
+	     y="6921"
+	     id="tspan481"><tspan
+	       id="tspan483"
+	       style="fill:#000000;stroke:none">21</tspan></tspan></tspan></text>
+</g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g485"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id29"><rect
+	 class="BoundingBox"
+	 x="12899"
+	 y="5999"
+	 width="2403"
+	 height="1403"
+	 id="rect488"
+	 style="fill:none;stroke:none" /><path
+	 d="m 14100,7400 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path490"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /><text
+	 class="TextShape"
+	 id="text492"><tspan
+	   class="TextParagraph"
+	   font-size="635px"
+	   font-weight="400"
+	   id="tspan494"
+	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+	     class="TextPosition"
+	     x="13749"
+	     y="6921"
+	     id="tspan496"><tspan
+	       id="tspan498"
+	       style="fill:#000000;stroke:none">20</tspan></tspan></tspan></text>
+</g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g500"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id30"><rect
+	 class="BoundingBox"
+	 x="3299"
+	 y="7399"
+	 width="2403"
+	 height="1403"
+	 id="rect503"
+	 style="fill:none;stroke:none" /><path
+	 d="m 4500,8800 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path505"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /><text
+	 class="TextShape"
+	 id="text507"><tspan
+	   class="TextParagraph"
+	   font-size="635px"
+	   font-weight="400"
+	   id="tspan509"
+	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+	     class="TextPosition"
+	     x="4149"
+	     y="8321"
+	     id="tspan511"><tspan
+	       id="tspan513"
+	       style="fill:#000000;stroke:none">14</tspan></tspan></tspan></text>
+</g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g515"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id31"><rect
+	 class="BoundingBox"
+	 x="5699"
+	 y="7399"
+	 width="2403"
+	 height="1403"
+	 id="rect518"
+	 style="fill:none;stroke:none" /><path
+	 d="m 6900,8800 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path520"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /></g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g522"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id32"><rect
+	 class="BoundingBox"
+	 x="8099"
+	 y="7399"
+	 width="2403"
+	 height="1403"
+	 id="rect525"
+	 style="fill:none;stroke:none" /><path
+	 d="m 9300,8800 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path527"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /><text
+	 class="TextShape"
+	 id="text529"><tspan
+	   class="TextParagraph"
+	   font-size="635px"
+	   font-weight="400"
+	   id="tspan531"
+	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+	     class="TextPosition"
+	     x="8949"
+	     y="8321"
+	     id="tspan533"><tspan
+	       id="tspan535"
+	       style="fill:#000000;stroke:none">16</tspan></tspan></tspan></text>
+</g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g537"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id33"><rect
+	 class="BoundingBox"
+	 x="5699"
+	 y="7399"
+	 width="2403"
+	 height="1403"
+	 id="rect540"
+	 style="fill:none;stroke:none" /><path
+	 d="m 6900,8800 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path542"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /><text
+	 class="TextShape"
+	 id="text544"><tspan
+	   class="TextParagraph"
+	   font-size="635px"
+	   font-weight="400"
+	   id="tspan546"
+	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+	     class="TextPosition"
+	     x="6549"
+	     y="8321"
+	     id="tspan548"><tspan
+	       id="tspan550"
+	       style="fill:#000000;stroke:none">15</tspan></tspan></tspan></text>
+</g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g552"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id34"><rect
+	 class="BoundingBox"
+	 x="10499"
+	 y="7399"
+	 width="2403"
+	 height="1403"
+	 id="rect555"
+	 style="fill:none;stroke:none" /><path
+	 d="m 11700,8800 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path557"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /><text
+	 class="TextShape"
+	 id="text559"><tspan
+	   class="TextParagraph"
+	   font-size="635px"
+	   font-weight="400"
+	   id="tspan561"
+	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+	     class="TextPosition"
+	     x="11349"
+	     y="8321"
+	     id="tspan563"><tspan
+	       id="tspan565"
+	       style="fill:#000000;stroke:none">17</tspan></tspan></tspan></text>
+</g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g567"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id35"><rect
+	 class="BoundingBox"
+	 x="12899"
+	 y="7399"
+	 width="2403"
+	 height="1403"
+	 id="rect570"
+	 style="fill:none;stroke:none" /><path
+	 d="m 14100,8800 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path572"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /></g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g574"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id36"><rect
+	 class="BoundingBox"
+	 x="15299"
+	 y="7399"
+	 width="2403"
+	 height="1403"
+	 id="rect577"
+	 style="fill:none;stroke:none" /><path
+	 d="m 16500,8800 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path579"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /><text
+	 class="TextShape"
+	 id="text581"><tspan
+	   class="TextParagraph"
+	   font-size="635px"
+	   font-weight="400"
+	   id="tspan583"
+	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+	     class="TextPosition"
+	     x="16149"
+	     y="8321"
+	     id="tspan585"><tspan
+	       id="tspan587"
+	       style="fill:#000000;stroke:none">23</tspan></tspan></tspan></text>
+</g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g589"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id37"><rect
+	 class="BoundingBox"
+	 x="12899"
+	 y="7399"
+	 width="2403"
+	 height="1403"
+	 id="rect592"
+	 style="fill:none;stroke:none" /><path
+	 d="m 14100,8800 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path594"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /><text
+	 class="TextShape"
+	 id="text596"><tspan
+	   class="TextParagraph"
+	   font-size="635px"
+	   font-weight="400"
+	   id="tspan598"
+	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+	     class="TextPosition"
+	     x="13749"
+	     y="8321"
+	     id="tspan600"><tspan
+	       id="tspan602"
+	       style="fill:#000000;stroke:none">22</tspan></tspan></tspan></text>
+</g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g604"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id38"><rect
+	 class="BoundingBox"
+	 x="3299"
+	 y="8799"
+	 width="2403"
+	 height="1403"
+	 id="rect607"
+	 style="fill:none;stroke:none" /><path
+	 d="m 4500,10200 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path609"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /><text
+	 class="TextShape"
+	 id="text611"><tspan
+	   class="TextParagraph"
+	   font-size="635px"
+	   font-weight="400"
+	   id="tspan613"
+	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+	     class="TextPosition"
+	     x="4149"
+	     y="9721"
+	     id="tspan615"><tspan
+	       id="tspan617"
+	       style="fill:#000000;stroke:none">24</tspan></tspan></tspan></text>
+</g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g619"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id39"><rect
+	 class="BoundingBox"
+	 x="5699"
+	 y="8799"
+	 width="2403"
+	 height="1403"
+	 id="rect622"
+	 style="fill:none;stroke:none" /><path
+	 d="m 6900,10200 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path624"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /></g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g626"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id40"><rect
+	 class="BoundingBox"
+	 x="8099"
+	 y="8799"
+	 width="2403"
+	 height="1403"
+	 id="rect629"
+	 style="fill:none;stroke:none" /><path
+	 d="m 9300,10200 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path631"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /><text
+	 class="TextShape"
+	 id="text633"><tspan
+	   class="TextParagraph"
+	   font-size="635px"
+	   font-weight="400"
+	   id="tspan635"
+	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+	     class="TextPosition"
+	     x="8949"
+	     y="9721"
+	     id="tspan637"><tspan
+	       id="tspan639"
+	       style="fill:#000000;stroke:none">26</tspan></tspan></tspan></text>
+</g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g641"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id41"><rect
+	 class="BoundingBox"
+	 x="5699"
+	 y="8799"
+	 width="2403"
+	 height="1403"
+	 id="rect644"
+	 style="fill:none;stroke:none" /><path
+	 d="m 6900,10200 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path646"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /><text
+	 class="TextShape"
+	 id="text648"><tspan
+	   class="TextParagraph"
+	   font-size="635px"
+	   font-weight="400"
+	   id="tspan650"
+	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+	     class="TextPosition"
+	     x="6549"
+	     y="9721"
+	     id="tspan652"><tspan
+	       id="tspan654"
+	       style="fill:#000000;stroke:none">25</tspan></tspan></tspan></text>
+</g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g656"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id42"><rect
+	 class="BoundingBox"
+	 x="10499"
+	 y="8799"
+	 width="2403"
+	 height="1403"
+	 id="rect659"
+	 style="fill:none;stroke:none" /><path
+	 d="m 11700,10200 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path661"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /><text
+	 class="TextShape"
+	 id="text663"><tspan
+	   class="TextParagraph"
+	   font-size="635px"
+	   font-weight="400"
+	   id="tspan665"
+	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+	     class="TextPosition"
+	     x="11349"
+	     y="9721"
+	     id="tspan667"><tspan
+	       id="tspan669"
+	       style="fill:#000000;stroke:none">27</tspan></tspan></tspan></text>
+</g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g671"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id43"><rect
+	 class="BoundingBox"
+	 x="12899"
+	 y="8799"
+	 width="2403"
+	 height="1403"
+	 id="rect674"
+	 style="fill:none;stroke:none" /><path
+	 d="m 14100,10200 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path676"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /></g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g678"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id44"><rect
+	 class="BoundingBox"
+	 x="15299"
+	 y="8799"
+	 width="2403"
+	 height="1403"
+	 id="rect681"
+	 style="fill:none;stroke:none" /><path
+	 d="m 16500,10200 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path683"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /><text
+	 class="TextShape"
+	 id="text685"><tspan
+	   class="TextParagraph"
+	   font-size="635px"
+	   font-weight="400"
+	   id="tspan687"
+	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+	     class="TextPosition"
+	     x="16149"
+	     y="9721"
+	     id="tspan689"><tspan
+	       id="tspan691"
+	       style="fill:#000000;stroke:none">29</tspan></tspan></tspan></text>
+</g></g><g
+     class="com.sun.star.drawing.CustomShape"
+     id="g693"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id45"><rect
+	 class="BoundingBox"
+	 x="12899"
+	 y="8799"
+	 width="2403"
+	 height="1403"
+	 id="rect696"
+	 style="fill:none;stroke:none" /><path
+	 d="m 14100,10200 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+	 id="path698"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#3465a4" /><text
+	 class="TextShape"
+	 id="text700"><tspan
+	   class="TextParagraph"
+	   font-size="635px"
+	   font-weight="400"
+	   id="tspan702"
+	   style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+	     class="TextPosition"
+	     x="13749"
+	     y="9721"
+	     id="tspan704"><tspan
+	       id="tspan706"
+	       style="fill:#000000;stroke:none">28</tspan></tspan></tspan></text>
+</g></g><g
+     class="com.sun.star.drawing.LineShape"
+     id="g708"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id46"><rect
+	 class="BoundingBox"
+	 x="5199"
+	 y="3850"
+	 width="1402"
+	 height="301"
+	 id="rect711"
+	 style="fill:none;stroke:none" /><path
+	 d="m 5200,4000 970,0"
+	 id="path713"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#ff3333" /><path
+	 d="m 6600,4000 -450,-150 0,300 450,-150 z"
+	 id="path715"
+	 inkscape:connector-curvature="0"
+	 style="fill:#ff3333;stroke:none" /></g></g><g
+     class="com.sun.star.drawing.LineShape"
+     id="g717"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id47"><rect
+	 class="BoundingBox"
+	 x="5000"
+	 y="4299"
+	 width="1202"
+	 height="802"
+	 id="rect720"
+	 style="fill:none;stroke:none" /><path
+	 d="m 6200,4300 -842,561"
+	 id="path722"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#ff3333" /><path
+	 d="m 5000,5100 458,-125 -167,-249 -291,374 z"
+	 id="path724"
+	 inkscape:connector-curvature="0"
+	 style="fill:#ff3333;stroke:none" /></g></g><g
+     class="com.sun.star.drawing.LineShape"
+     id="g726"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id48"><rect
+	 class="BoundingBox"
+	 x="5399"
+	 y="5250"
+	 width="1202"
+	 height="301"
+	 id="rect729"
+	 style="fill:none;stroke:none" /><path
+	 d="m 5400,5400 770,0"
+	 id="path731"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#ff3333" /><path
+	 d="m 6600,5400 -450,-150 0,300 450,-150 z"
+	 id="path733"
+	 inkscape:connector-curvature="0"
+	 style="fill:#ff3333;stroke:none" /></g></g><g
+     class="com.sun.star.drawing.LineShape"
+     id="g735"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id49"><rect
+	 class="BoundingBox"
+	 x="7599"
+	 y="5250"
+	 width="1202"
+	 height="301"
+	 id="rect738"
+	 style="fill:none;stroke:none" /><path
+	 d="m 7600,5400 770,0"
+	 id="path740"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#ff3333" /><path
+	 d="m 8800,5400 -450,-150 0,300 450,-150 z"
+	 id="path742"
+	 inkscape:connector-curvature="0"
+	 style="fill:#ff3333;stroke:none" /></g></g><g
+     class="com.sun.star.drawing.LineShape"
+     id="g744"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id50"><rect
+	 class="BoundingBox"
+	 x="9799"
+	 y="5250"
+	 width="1402"
+	 height="301"
+	 id="rect747"
+	 style="fill:none;stroke:none" /><path
+	 d="m 9800,5400 970,0"
+	 id="path749"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#ff3333" /><path
+	 d="m 11200,5400 -450,-150 0,300 450,-150 z"
+	 id="path751"
+	 inkscape:connector-curvature="0"
+	 style="fill:#ff3333;stroke:none" /></g></g><g
+     class="com.sun.star.drawing.LineShape"
+     id="g753"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id51"><rect
+	 class="BoundingBox"
+	 x="9900"
+	 y="4200"
+	 width="1202"
+	 height="802"
+	 id="rect756"
+	 style="fill:none;stroke:none" /><path
+	 d="m 11100,5000 -842,-561"
+	 id="path758"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#ff3333" /><path
+	 d="m 9900,4200 291,374 167,-249 -458,-125 z"
+	 id="path760"
+	 inkscape:connector-curvature="0"
+	 style="fill:#ff3333;stroke:none" /></g></g><g
+     class="com.sun.star.drawing.LineShape"
+     id="g762"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id52"><rect
+	 class="BoundingBox"
+	 x="9999"
+	 y="3850"
+	 width="1402"
+	 height="301"
+	 id="rect765"
+	 style="fill:none;stroke:none" /><path
+	 d="m 10000,4000 970,0"
+	 id="path767"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#ff3333" /><path
+	 d="m 11400,4000 -450,-150 0,300 450,-150 z"
+	 id="path769"
+	 inkscape:connector-curvature="0"
+	 style="fill:#ff3333;stroke:none" /></g></g><g
+     class="com.sun.star.drawing.LineShape"
+     id="g771"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id53"><rect
+	 class="BoundingBox"
+	 x="12399"
+	 y="3850"
+	 width="1202"
+	 height="301"
+	 id="rect774"
+	 style="fill:none;stroke:none" /><path
+	 d="m 12400,4000 770,0"
+	 id="path776"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#ff3333" /><path
+	 d="m 13600,4000 -450,-150 0,300 450,-150 z"
+	 id="path778"
+	 inkscape:connector-curvature="0"
+	 style="fill:#ff3333;stroke:none" /></g></g><g
+     class="com.sun.star.drawing.LineShape"
+     id="g780"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id54"><rect
+	 class="BoundingBox"
+	 x="14799"
+	 y="3850"
+	 width="1202"
+	 height="301"
+	 id="rect783"
+	 style="fill:none;stroke:none" /><path
+	 d="m 14800,4000 770,0"
+	 id="path785"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#ff3333" /><path
+	 d="m 16000,4000 -450,-150 0,300 450,-150 z"
+	 id="path787"
+	 inkscape:connector-curvature="0"
+	 style="fill:#ff3333;stroke:none" /></g></g><g
+     class="com.sun.star.drawing.LineShape"
+     id="g789"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id55"><rect
+	 class="BoundingBox"
+	 x="14400"
+	 y="4399"
+	 width="1402"
+	 height="602"
+	 id="rect792"
+	 style="fill:none;stroke:none" /><path
+	 d="m 15800,4400 -1005,431"
+	 id="path794"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#ff3333" /><path
+	 d="m 14400,5000 473,-39 -118,-276 -355,315 z"
+	 id="path796"
+	 inkscape:connector-curvature="0"
+	 style="fill:#ff3333;stroke:none" /></g></g><g
+     class="com.sun.star.drawing.LineShape"
+     id="g798"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id56"><rect
+	 class="BoundingBox"
+	 x="14599"
+	 y="5250"
+	 width="1402"
+	 height="301"
+	 id="rect801"
+	 style="fill:none;stroke:none" /><path
+	 d="m 14600,5400 970,0"
+	 id="path803"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#ff3333" /><path
+	 d="m 16000,5400 -450,-150 0,300 450,-150 z"
+	 id="path805"
+	 inkscape:connector-curvature="0"
+	 style="fill:#ff3333;stroke:none" /></g></g><g
+     class="com.sun.star.drawing.LineShape"
+     id="g807"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id57"><rect
+	 class="BoundingBox"
+	 x="5199"
+	 y="6550"
+	 width="1402"
+	 height="301"
+	 id="rect810"
+	 style="fill:none;stroke:none" /><path
+	 d="m 5200,6700 970,0"
+	 id="path812"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#ff3333" /><path
+	 d="m 6600,6700 -450,-150 0,300 450,-150 z"
+	 id="path814"
+	 inkscape:connector-curvature="0"
+	 style="fill:#ff3333;stroke:none" /></g></g><g
+     class="com.sun.star.drawing.LineShape"
+     id="g816"
+     transform="translate(-3285.889,-3129.4446)"><g
+       id="id58"><rect
+	 class="BoundingBox"
+	 x="5000"
+	 y="6999"
+	 width="1202"
+	 height="802"
+	 id="rect819"
+	 style="fill:none;stroke:none" /><path
+	 d="m 6200,7000 -842,561"
+	 id="path821"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#ff3333" /><path
+	 d="m 5000,7800 458,-125 -167,-249 -291,374 z"
+	 id="path823"
+	 inkscape:connector-curvature="0"
+	 style="fill:#ff3333;stroke:none" /></g></g><g
+     class="com.sun.star.drawing.LineShape"
+     id="g825"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id59"><rect
+	 class="BoundingBox"
+	 x="5399"
+	 y="7950"
+	 width="1202"
+	 height="301"
+	 id="rect828"
+	 style="fill:none;stroke:none" /><path
+	 d="m 5400,8100 770,0"
+	 id="path830"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#ff3333" /><path
+	 d="m 6600,8100 -450,-150 0,300 450,-150 z"
+	 id="path832"
+	 inkscape:connector-curvature="0"
+	 style="fill:#ff3333;stroke:none" /></g></g><g
+     class="com.sun.star.drawing.LineShape"
+     id="g834"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id60"><rect
+	 class="BoundingBox"
+	 x="7599"
+	 y="7950"
+	 width="1202"
+	 height="301"
+	 id="rect837"
+	 style="fill:none;stroke:none" /><path
+	 d="m 7600,8100 770,0"
+	 id="path839"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#ff3333" /><path
+	 d="m 8800,8100 -450,-150 0,300 450,-150 z"
+	 id="path841"
+	 inkscape:connector-curvature="0"
+	 style="fill:#ff3333;stroke:none" /></g></g><g
+     class="com.sun.star.drawing.LineShape"
+     id="g843"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id61"><rect
+	 class="BoundingBox"
+	 x="9799"
+	 y="7950"
+	 width="1402"
+	 height="301"
+	 id="rect846"
+	 style="fill:none;stroke:none" /><path
+	 d="m 9800,8100 970,0"
+	 id="path848"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#ff3333" /><path
+	 d="m 11200,8100 -450,-150 0,300 450,-150 z"
+	 id="path850"
+	 inkscape:connector-curvature="0"
+	 style="fill:#ff3333;stroke:none" /></g></g><g
+     class="com.sun.star.drawing.LineShape"
+     id="g852"
+     transform="translate(-3285.889,-3129.4446)"><g
+       id="id62"><rect
+	 class="BoundingBox"
+	 x="9900"
+	 y="6900"
+	 width="1202"
+	 height="802"
+	 id="rect855"
+	 style="fill:none;stroke:none" /><path
+	 d="m 11100,7700 -842,-561"
+	 id="path857"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#ff3333" /><path
+	 d="m 9900,6900 291,374 167,-249 -458,-125 z"
+	 id="path859"
+	 inkscape:connector-curvature="0"
+	 style="fill:#ff3333;stroke:none" /></g></g><g
+     class="com.sun.star.drawing.LineShape"
+     id="g861"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id63"><rect
+	 class="BoundingBox"
+	 x="9999"
+	 y="6550"
+	 width="1402"
+	 height="301"
+	 id="rect864"
+	 style="fill:none;stroke:none" /><path
+	 d="m 10000,6700 970,0"
+	 id="path866"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#ff3333" /><path
+	 d="m 11400,6700 -450,-150 0,300 450,-150 z"
+	 id="path868"
+	 inkscape:connector-curvature="0"
+	 style="fill:#ff3333;stroke:none" /></g></g><g
+     class="com.sun.star.drawing.LineShape"
+     id="g870"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id64"><rect
+	 class="BoundingBox"
+	 x="12399"
+	 y="6550"
+	 width="1202"
+	 height="301"
+	 id="rect873"
+	 style="fill:none;stroke:none" /><path
+	 d="m 12400,6700 770,0"
+	 id="path875"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#ff3333" /><path
+	 d="m 13600,6700 -450,-150 0,300 450,-150 z"
+	 id="path877"
+	 inkscape:connector-curvature="0"
+	 style="fill:#ff3333;stroke:none" /></g></g><g
+     class="com.sun.star.drawing.LineShape"
+     id="g879"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id65"><rect
+	 class="BoundingBox"
+	 x="14799"
+	 y="6550"
+	 width="1202"
+	 height="301"
+	 id="rect882"
+	 style="fill:none;stroke:none" /><path
+	 d="m 14800,6700 770,0"
+	 id="path884"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#ff3333" /><path
+	 d="m 16000,6700 -450,-150 0,300 450,-150 z"
+	 id="path886"
+	 inkscape:connector-curvature="0"
+	 style="fill:#ff3333;stroke:none" /></g></g><g
+     class="com.sun.star.drawing.LineShape"
+     id="g888"
+     transform="translate(-3285.889,-3129.4446)"><g
+       id="id66"><rect
+	 class="BoundingBox"
+	 x="14400"
+	 y="7099"
+	 width="1402"
+	 height="602"
+	 id="rect891"
+	 style="fill:none;stroke:none" /><path
+	 d="m 15800,7100 -1005,431"
+	 id="path893"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#ff3333" /><path
+	 d="m 14400,7700 473,-39 -118,-276 -355,315 z"
+	 id="path895"
+	 inkscape:connector-curvature="0"
+	 style="fill:#ff3333;stroke:none" /></g></g><g
+     class="com.sun.star.drawing.LineShape"
+     id="g897"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id67"><rect
+	 class="BoundingBox"
+	 x="14599"
+	 y="7950"
+	 width="1402"
+	 height="301"
+	 id="rect900"
+	 style="fill:none;stroke:none" /><path
+	 d="m 14600,8100 970,0"
+	 id="path902"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#ff3333" /><path
+	 d="m 16000,8100 -450,-150 0,300 450,-150 z"
+	 id="path904"
+	 inkscape:connector-curvature="0"
+	 style="fill:#ff3333;stroke:none" /></g></g><g
+     class="com.sun.star.drawing.LineShape"
+     id="g906"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id68"><rect
+	 class="BoundingBox"
+	 x="5399"
+	 y="9450"
+	 width="1202"
+	 height="301"
+	 id="rect909"
+	 style="fill:none;stroke:none" /><path
+	 d="m 5400,9600 770,0"
+	 id="path911"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#ff3333" /><path
+	 d="m 6600,9600 -450,-150 0,300 450,-150 z"
+	 id="path913"
+	 inkscape:connector-curvature="0"
+	 style="fill:#ff3333;stroke:none" /></g></g><g
+     class="com.sun.star.drawing.LineShape"
+     id="g915"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id69"><rect
+	 class="BoundingBox"
+	 x="7599"
+	 y="9450"
+	 width="1202"
+	 height="301"
+	 id="rect918"
+	 style="fill:none;stroke:none" /><path
+	 d="m 7600,9600 770,0"
+	 id="path920"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#ff3333" /><path
+	 d="m 8800,9600 -450,-150 0,300 450,-150 z"
+	 id="path922"
+	 inkscape:connector-curvature="0"
+	 style="fill:#ff3333;stroke:none" /></g></g><g
+     class="com.sun.star.drawing.LineShape"
+     id="g924"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id70"><rect
+	 class="BoundingBox"
+	 x="9999"
+	 y="9450"
+	 width="1202"
+	 height="301"
+	 id="rect927"
+	 style="fill:none;stroke:none" /><path
+	 d="m 10000,9600 770,0"
+	 id="path929"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#ff3333" /><path
+	 d="m 11200,9600 -450,-150 0,300 450,-150 z"
+	 id="path931"
+	 inkscape:connector-curvature="0"
+	 style="fill:#ff3333;stroke:none" /></g></g><g
+     class="com.sun.star.drawing.LineShape"
+     id="g933"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id71"><rect
+	 class="BoundingBox"
+	 x="12399"
+	 y="9450"
+	 width="1202"
+	 height="301"
+	 id="rect936"
+	 style="fill:none;stroke:none" /><path
+	 d="m 12400,9600 770,0"
+	 id="path938"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#ff3333" /><path
+	 d="m 13600,9600 -450,-150 0,300 450,-150 z"
+	 id="path940"
+	 inkscape:connector-curvature="0"
+	 style="fill:#ff3333;stroke:none" /></g></g><g
+     class="com.sun.star.drawing.LineShape"
+     id="g942"
+     transform="translate(-3285.889,-3185.889)"><g
+       id="id72"><rect
+	 class="BoundingBox"
+	 x="14799"
+	 y="9450"
+	 width="1202"
+	 height="301"
+	 id="rect945"
+	 style="fill:none;stroke:none" /><path
+	 d="m 14800,9600 770,0"
+	 id="path947"
+	 inkscape:connector-curvature="0"
+	 style="fill:none;stroke:#ff3333" /><path
+	 d="m 16000,9600 -450,-150 0,300 450,-150 z"
+	 id="path949"
+	 inkscape:connector-curvature="0"
+	 style="fill:#ff3333;stroke:none" /></g></g></svg>
diff --git a/Documentation/userspace-api/media/v4l/open.rst b/Documentation/userspace-api/media/v4l/open.rst
new file mode 100644
index 000000000000..38046ef20141
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/open.rst
@@ -0,0 +1,165 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _open:
+
+***************************
+Opening and Closing Devices
+***************************
+
+
+Device Naming
+=============
+
+V4L2 drivers are implemented as kernel modules, loaded manually by the
+system administrator or automatically when a device is first discovered.
+The driver modules plug into the "videodev" kernel module. It provides
+helper functions and a common application interface specified in this
+document.
+
+Each driver thus loaded registers one or more device nodes with major
+number 81 and a minor number between 0 and 255. Minor numbers are
+allocated dynamically unless the kernel is compiled with the kernel
+option CONFIG_VIDEO_FIXED_MINOR_RANGES. In that case minor numbers
+are allocated in ranges depending on the device node type (video, radio,
+etc.).
+
+Many drivers support "video_nr", "radio_nr" or "vbi_nr" module
+options to select specific video/radio/vbi node numbers. This allows the
+user to request that the device node is named e.g. /dev/video5 instead
+of leaving it to chance. When the driver supports multiple devices of
+the same type more than one device node number can be assigned,
+separated by commas:
+
+.. code-block:: none
+
+   # modprobe mydriver video_nr=0,1 radio_nr=0,1
+
+In ``/etc/modules.conf`` this may be written as:
+
+::
+
+    options mydriver video_nr=0,1 radio_nr=0,1
+
+When no device node number is given as module option the driver supplies
+a default.
+
+Normally udev will create the device nodes in /dev automatically for
+you. If udev is not installed, then you need to enable the
+CONFIG_VIDEO_FIXED_MINOR_RANGES kernel option in order to be able to
+correctly relate a minor number to a device node number. I.e., you need
+to be certain that minor number 5 maps to device node name video5. With
+this kernel option different device types have different minor number
+ranges. These ranges are listed in :ref:`devices`.
+
+The creation of character special files (with mknod) is a privileged
+operation and devices cannot be opened by major and minor number. That
+means applications cannot *reliably* scan for loaded or installed
+drivers. The user must enter a device name, or the application can try
+the conventional device names.
+
+
+.. _related:
+
+Related Devices
+===============
+
+Devices can support several functions. For example video capturing, VBI
+capturing and radio support.
+
+The V4L2 API creates different nodes for each of these functions.
+
+The V4L2 API was designed with the idea that one device node could
+support all functions. However, in practice this never worked: this
+'feature' was never used by applications and many drivers did not
+support it and if they did it was certainly never tested. In addition,
+switching a device node between different functions only works when
+using the streaming I/O API, not with the
+:ref:`read() <func-read>`/\ :ref:`write() <func-write>` API.
+
+Today each device node supports just one function.
+
+Besides video input or output the hardware may also support audio
+sampling or playback. If so, these functions are implemented as ALSA PCM
+devices with optional ALSA audio mixer devices.
+
+One problem with all these devices is that the V4L2 API makes no
+provisions to find these related devices. Some really complex devices
+use the Media Controller (see :ref:`media_controller`) which can be
+used for this purpose. But most drivers do not use it, and while some
+code exists that uses sysfs to discover related devices (see
+libmedia_dev in the
+`v4l-utils <http://git.linuxtv.org/cgit.cgi/v4l-utils.git/>`__ git
+repository), there is no library yet that can provide a single API
+towards both Media Controller-based devices and devices that do not use
+the Media Controller. If you want to work on this please write to the
+linux-media mailing list:
+`https://linuxtv.org/lists.php <https://linuxtv.org/lists.php>`__.
+
+
+Multiple Opens
+==============
+
+V4L2 devices can be opened more than once. [#f1]_ When this is supported
+by the driver, users can for example start a "panel" application to
+change controls like brightness or audio volume, while another
+application captures video and audio. In other words, panel applications
+are comparable to an ALSA audio mixer application. Just opening a V4L2
+device should not change the state of the device. [#f2]_
+
+Once an application has allocated the memory buffers needed for
+streaming data (by calling the :ref:`VIDIOC_REQBUFS`
+or :ref:`VIDIOC_CREATE_BUFS` ioctls, or
+implicitly by calling the :ref:`read() <func-read>` or
+:ref:`write() <func-write>` functions) that application (filehandle)
+becomes the owner of the device. It is no longer allowed to make changes
+that would affect the buffer sizes (e.g. by calling the
+:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl) and other applications are
+no longer allowed to allocate buffers or start or stop streaming. The
+EBUSY error code will be returned instead.
+
+Merely opening a V4L2 device does not grant exclusive access. [#f3]_
+Initiating data exchange however assigns the right to read or write the
+requested type of data, and to change related properties, to this file
+descriptor. Applications can request additional access privileges using
+the priority mechanism described in :ref:`app-pri`.
+
+
+Shared Data Streams
+===================
+
+V4L2 drivers should not support multiple applications reading or writing
+the same data stream on a device by copying buffers, time multiplexing
+or similar means. This is better handled by a proxy application in user
+space.
+
+
+Functions
+=========
+
+To open and close V4L2 devices applications use the
+:ref:`open() <func-open>` and :ref:`close() <func-close>` function,
+respectively. Devices are programmed using the
+:ref:`ioctl() <func-ioctl>` function as explained in the following
+sections.
+
+.. [#f1]
+   There are still some old and obscure drivers that have not been
+   updated to allow for multiple opens. This implies that for such
+   drivers :ref:`open() <func-open>` can return an ``EBUSY`` error code
+   when the device is already in use.
+
+.. [#f2]
+   Unfortunately, opening a radio device often switches the state of the
+   device to radio mode in many drivers. This behavior should be fixed
+   eventually as it violates the V4L2 specification.
+
+.. [#f3]
+   Drivers could recognize the ``O_EXCL`` open flag. Presently this is
+   not required, so applications cannot know if it really works.
diff --git a/Documentation/userspace-api/media/v4l/pipeline.dot b/Documentation/userspace-api/media/v4l/pipeline.dot
new file mode 100644
index 000000000000..8c53ce719a14
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pipeline.dot
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: GPL-2.0
+
+digraph board {
+	rankdir=TB
+	colorscheme=x11
+	scaler [label="{<scaler_0> 0} | Host\nScaler | {<scaler_1> 1} ", shape=Mrecord, style=filled, fillcolor=lightblue]
+	frontend [label="{<frontend_0> 0} | Host\nFrontend | {<frontend_1> 1}", shape=Mrecord, style=filled, fillcolor=lightblue]
+	sensor [label="Sensor | {<sensor_0> 0}", shape=Mrecord, style=filled, fillcolor=aquamarine]
+	io [label="{<io_0> 0} | V4L I/O", shape=Mrecord, style=filled, fillcolor=aquamarine]
+
+	sensor:sensor_0 -> frontend:frontend_0 [color=blue, label="HQ: 2592x1968\nHS: 1296x984"]
+	frontend:frontend_1 -> scaler:scaler_0 [color=blue, label="HQ: 2592x1968\nHS: 1296x984"]
+	scaler:scaler_1 -> io:io_0 [color=blue, label="HQ: 1280x720\nHS: 1280x720"]
+}
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-bayer.rst b/Documentation/userspace-api/media/v4l/pixfmt-bayer.rst
new file mode 100644
index 000000000000..be9a8385ebc1
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-bayer.rst
@@ -0,0 +1,39 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _pixfmt-bayer:
+
+*****************
+Raw Bayer Formats
+*****************
+
+Description
+===========
+
+The raw Bayer formats are used by image sensors before much if any processing is
+performed on the image. The formats contain green, red and blue components, with
+alternating lines of red and green, and blue and green pixels in different
+orders. See also `the Wikipedia article on Bayer filter
+<https://en.wikipedia.org/wiki/Bayer_filter>`__.
+
+
+.. toctree::
+    :maxdepth: 1
+
+    pixfmt-srggb8
+    pixfmt-srggb10
+    pixfmt-srggb10p
+    pixfmt-srggb10alaw8
+    pixfmt-srggb10dpcm8
+    pixfmt-srggb10-ipu3
+    pixfmt-srggb12
+    pixfmt-srggb12p
+    pixfmt-srggb14
+    pixfmt-srggb14p
+    pixfmt-srggb16
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-cnf4.rst b/Documentation/userspace-api/media/v4l/pixfmt-cnf4.rst
new file mode 100644
index 000000000000..8f469290c304
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-cnf4.rst
@@ -0,0 +1,31 @@
+.. -*- coding: utf-8; mode: rst -*-
+
+.. _V4L2-PIX-FMT-CNF4:
+
+******************************
+V4L2_PIX_FMT_CNF4 ('CNF4')
+******************************
+
+Depth sensor confidence information as a 4 bits per pixel packed array
+
+Description
+===========
+
+Proprietary format used by Intel RealSense Depth cameras containing depth
+confidence information in range 0-15 with 0 indicating that the sensor was
+unable to resolve any signal and 15 indicating maximum level of confidence for
+the specific sensor (actual error margins might change from sensor to sensor).
+
+Every two consecutive pixels are packed into a single byte.
+Bits 0-3 of byte n refer to confidence value of depth pixel 2*n,
+bits 4-7 to confidence value of depth pixel 2*n+1.
+
+**Bit-packed representation.**
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths: 64 64
+
+    * - Y'\ :sub:`01[3:0]`\ (bits 7--4) Y'\ :sub:`00[3:0]`\ (bits 3--0)
+      - Y'\ :sub:`03[3:0]`\ (bits 7--4) Y'\ :sub:`02[3:0]`\ (bits 3--0)
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst b/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst
new file mode 100644
index 000000000000..3828bb79225d
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst
@@ -0,0 +1,232 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+******************
+Compressed Formats
+******************
+
+
+.. _compressed-formats:
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. flat-table:: Compressed Image Formats
+    :header-rows:  1
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - Identifier
+      - Code
+      - Details
+    * .. _V4L2-PIX-FMT-JPEG:
+
+      - ``V4L2_PIX_FMT_JPEG``
+      - 'JPEG'
+      - TBD. See also :ref:`VIDIOC_G_JPEGCOMP <VIDIOC_G_JPEGCOMP>`,
+	:ref:`VIDIOC_S_JPEGCOMP <VIDIOC_G_JPEGCOMP>`.
+    * .. _V4L2-PIX-FMT-MPEG:
+
+      - ``V4L2_PIX_FMT_MPEG``
+      - 'MPEG'
+      - MPEG multiplexed stream. The actual format is determined by
+	extended control ``V4L2_CID_MPEG_STREAM_TYPE``, see
+	:ref:`mpeg-control-id`.
+    * .. _V4L2-PIX-FMT-H264:
+
+      - ``V4L2_PIX_FMT_H264``
+      - 'H264'
+      - H264 Access Unit.
+	The decoder expects one Access Unit per buffer.
+	The encoder generates one Access Unit per buffer.
+	If :ref:`VIDIOC_ENUM_FMT` reports ``V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM``
+	then the decoder has no requirements since it can parse all the
+	information from the raw bytestream.
+    * .. _V4L2-PIX-FMT-H264-NO-SC:
+
+      - ``V4L2_PIX_FMT_H264_NO_SC``
+      - 'AVC1'
+      - H264 video elementary stream without start codes.
+    * .. _V4L2-PIX-FMT-H264-MVC:
+
+      - ``V4L2_PIX_FMT_H264_MVC``
+      - 'M264'
+      - H264 MVC video elementary stream.
+    * .. _V4L2-PIX-FMT-H264-SLICE:
+
+      - ``V4L2_PIX_FMT_H264_SLICE``
+      - 'S264'
+      - H264 parsed slice data, including slice headers, either with or
+	without the start code, as extracted from the H264 bitstream.
+	This format is adapted for stateless video decoders that implement an
+	H264 pipeline (using the :ref:`mem2mem` and :ref:`media-request-api`).
+	This pixelformat has two modifiers that must be set at least once
+	through the ``V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE``
+        and ``V4L2_CID_MPEG_VIDEO_H264_START_CODE`` controls.
+	In addition, metadata associated with the frame to decode are
+	required to be passed through the ``V4L2_CID_MPEG_VIDEO_H264_SPS``,
+	``V4L2_CID_MPEG_VIDEO_H264_PPS``,
+	``V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX``,
+	``V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS`` and
+	``V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS`` controls.  See the
+	:ref:`associated Codec Control IDs <v4l2-mpeg-h264>`.  Exactly
+	one output and one capture buffer must be provided for use
+	with this pixel format. The output buffer must contain the
+	appropriate number of macroblocks to decode a full
+	corresponding frame to the matching capture buffer.
+
+	The syntax for this format is documented in :ref:`h264`, section
+	7.3.2.8 "Slice layer without partitioning RBSP syntax" and the following
+	sections.
+
+	.. note::
+
+	   This format is not yet part of the public kernel API and it
+	   is expected to change.
+
+    * .. _V4L2-PIX-FMT-H263:
+
+      - ``V4L2_PIX_FMT_H263``
+      - 'H263'
+      - H263 video elementary stream.
+    * .. _V4L2-PIX-FMT-MPEG1:
+
+      - ``V4L2_PIX_FMT_MPEG1``
+      - 'MPG1'
+      - MPEG1 Picture. Each buffer starts with a Picture header, followed
+	by other headers as needed and ending with the Picture data.
+	If :ref:`VIDIOC_ENUM_FMT` reports ``V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM``
+	then the decoder has no requirements since it can parse all the
+	information from the raw bytestream.
+    * .. _V4L2-PIX-FMT-MPEG2:
+
+      - ``V4L2_PIX_FMT_MPEG2``
+      - 'MPG2'
+      - MPEG2 Picture. Each buffer starts with a Picture header, followed
+	by other headers as needed and ending with the Picture data.
+	If :ref:`VIDIOC_ENUM_FMT` reports ``V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM``
+	then the decoder has no requirements since it can parse all the
+	information from the raw bytestream.
+    * .. _V4L2-PIX-FMT-MPEG2-SLICE:
+
+      - ``V4L2_PIX_FMT_MPEG2_SLICE``
+      - 'MG2S'
+      - MPEG-2 parsed slice data, as extracted from the MPEG-2 bitstream.
+	This format is adapted for stateless video decoders that implement a
+	MPEG-2 pipeline (using the :ref:`mem2mem` and :ref:`media-request-api`).
+	Metadata associated with the frame to decode is required to be passed
+	through the ``V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS`` control and
+	quantization matrices can optionally be specified through the
+	``V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION`` control.
+	See the :ref:`associated Codec Control IDs <v4l2-mpeg-mpeg2>`.
+	Exactly one output and one capture buffer must be provided for use with
+	this pixel format. The output buffer must contain the appropriate number
+	of macroblocks to decode a full corresponding frame to the matching
+	capture buffer.
+    * .. _V4L2-PIX-FMT-MPEG4:
+
+      - ``V4L2_PIX_FMT_MPEG4``
+      - 'MPG4'
+      - MPEG4 video elementary stream.
+    * .. _V4L2-PIX-FMT-XVID:
+
+      - ``V4L2_PIX_FMT_XVID``
+      - 'XVID'
+      - Xvid video elementary stream.
+    * .. _V4L2-PIX-FMT-VC1-ANNEX-G:
+
+      - ``V4L2_PIX_FMT_VC1_ANNEX_G``
+      - 'VC1G'
+      - VC1, SMPTE 421M Annex G compliant stream.
+    * .. _V4L2-PIX-FMT-VC1-ANNEX-L:
+
+      - ``V4L2_PIX_FMT_VC1_ANNEX_L``
+      - 'VC1L'
+      - VC1, SMPTE 421M Annex L compliant stream.
+    * .. _V4L2-PIX-FMT-VP8:
+
+      - ``V4L2_PIX_FMT_VP8``
+      - 'VP80'
+      - VP8 compressed video frame. The encoder generates one
+	compressed frame per buffer, and the decoder requires one
+	compressed frame per buffer.
+    * .. _V4L2-PIX-FMT-VP8-FRAME:
+
+      - ``V4L2_PIX_FMT_VP8_FRAME``
+      - 'VP8F'
+      - VP8 parsed frame, as extracted from the container.
+	This format is adapted for stateless video decoders that implement a
+	VP8 pipeline (using the :ref:`mem2mem` and :ref:`media-request-api`).
+	Metadata associated with the frame to decode is required to be passed
+	through the ``V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER`` control.
+	See the :ref:`associated Codec Control IDs <v4l2-mpeg-vp8>`.
+	Exactly one output and one capture buffer must be provided for use with
+	this pixel format. The output buffer must contain the appropriate number
+	of macroblocks to decode a full corresponding frame to the matching
+	capture buffer.
+
+	.. note::
+
+	   This format is not yet part of the public kernel API and it
+	   is expected to change.
+
+    * .. _V4L2-PIX-FMT-VP9:
+
+      - ``V4L2_PIX_FMT_VP9``
+      - 'VP90'
+      - VP9 compressed video frame. The encoder generates one
+	compressed frame per buffer, and the decoder requires one
+	compressed frame per buffer.
+    * .. _V4L2-PIX-FMT-HEVC:
+
+      - ``V4L2_PIX_FMT_HEVC``
+      - 'HEVC'
+      - HEVC/H.265 Access Unit.
+	The decoder expects one Access Unit per buffer.
+	The encoder generates one Access Unit per buffer.
+	If :ref:`VIDIOC_ENUM_FMT` reports ``V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM``
+	then the decoder has no	requirements since it can parse all the
+	information from the raw bytestream.
+    * .. _V4L2-PIX-FMT-HEVC-SLICE:
+
+      - ``V4L2_PIX_FMT_HEVC_SLICE``
+      - 'S265'
+      - HEVC parsed slice data, as extracted from the HEVC bitstream.
+	This format is adapted for stateless video decoders that implement a
+	HEVC pipeline (using the :ref:`mem2mem` and :ref:`media-request-api`).
+	This pixelformat has two modifiers that must be set at least once
+	through the ``V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE``
+        and ``V4L2_CID_MPEG_VIDEO_HEVC_START_CODE`` controls.
+	Metadata associated with the frame to decode is required to be passed
+	through the following controls :
+        * ``V4L2_CID_MPEG_VIDEO_HEVC_SPS``
+        * ``V4L2_CID_MPEG_VIDEO_HEVC_PPS``
+        * ``V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS``
+	See the :ref:`associated Codec Control IDs <v4l2-mpeg-hevc>`.
+	Buffers associated with this pixel format must contain the appropriate
+	number of macroblocks to decode a full corresponding frame.
+
+	.. note::
+
+	   This format is not yet part of the public kernel API and it
+	   is expected to change.
+    * .. _V4L2-PIX-FMT-FWHT:
+
+      - ``V4L2_PIX_FMT_FWHT``
+      - 'FWHT'
+      - Video elementary stream using a codec based on the Fast Walsh Hadamard
+        Transform. This codec is implemented by the vicodec ('Virtual Codec')
+	driver. See the codec-fwht.h header for more details.
+	:ref:`VIDIOC_ENUM_FMT` reports ``V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM``
+	since the decoder can parse all the information from the raw bytestream.
+    * .. _V4L2-PIX-FMT-FWHT-STATELESS:
+
+      - ``V4L2_PIX_FMT_FWHT_STATELESS``
+      - 'SFWH'
+      - Same format as V4L2_PIX_FMT_FWHT but requires stateless codec implementation.
+	See the :ref:`associated Codec Control IDs <v4l2-mpeg-fwht>`.
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-grey.rst b/Documentation/userspace-api/media/v4l/pixfmt-grey.rst
new file mode 100644
index 000000000000..7b03db3393be
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-grey.rst
@@ -0,0 +1,51 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-GREY:
+
+**************************
+V4L2_PIX_FMT_GREY ('GREY')
+**************************
+
+Grey-scale image
+
+
+Description
+===========
+
+This is a grey-scale image. It is really a degenerate Y'CbCr format
+which simply contains no Cb or Cr data.
+
+**Byte Order.**
+Each cell is one byte.
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - start + 0:
+      - Y'\ :sub:`00`
+      - Y'\ :sub:`01`
+      - Y'\ :sub:`02`
+      - Y'\ :sub:`03`
+    * - start + 4:
+      - Y'\ :sub:`10`
+      - Y'\ :sub:`11`
+      - Y'\ :sub:`12`
+      - Y'\ :sub:`13`
+    * - start + 8:
+      - Y'\ :sub:`20`
+      - Y'\ :sub:`21`
+      - Y'\ :sub:`22`
+      - Y'\ :sub:`23`
+    * - start + 12:
+      - Y'\ :sub:`30`
+      - Y'\ :sub:`31`
+      - Y'\ :sub:`32`
+      - Y'\ :sub:`33`
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-indexed.rst b/Documentation/userspace-api/media/v4l/pixfmt-indexed.rst
new file mode 100644
index 000000000000..d0d46ed27260
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-indexed.rst
@@ -0,0 +1,54 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _pixfmt-indexed:
+
+**************
+Indexed Format
+**************
+
+In this format each pixel is represented by an 8 bit index into a 256
+entry ARGB palette. It is intended for
+:ref:`Video Output Overlays <osd>` only. There are no ioctls to access
+the palette, this must be done with ioctls of the Linux framebuffer API.
+
+
+
+.. flat-table:: Indexed Image Format
+    :header-rows:  2
+    :stub-columns: 0
+
+    * - Identifier
+      - Code
+      -
+      - :cspan:`7` Byte 0
+    * -
+      -
+      - Bit
+      - 7
+      - 6
+      - 5
+      - 4
+      - 3
+      - 2
+      - 1
+      - 0
+    * .. _V4L2-PIX-FMT-PAL8:
+
+      - ``V4L2_PIX_FMT_PAL8``
+      - 'PAL8'
+      -
+      - i\ :sub:`7`
+      - i\ :sub:`6`
+      - i\ :sub:`5`
+      - i\ :sub:`4`
+      - i\ :sub:`3`
+      - i\ :sub:`2`
+      - i\ :sub:`1`
+      - i\ :sub:`0`
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-intro.rst b/Documentation/userspace-api/media/v4l/pixfmt-intro.rst
new file mode 100644
index 000000000000..af870895f653
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-intro.rst
@@ -0,0 +1,58 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+**********************
+Standard Image Formats
+**********************
+
+In order to exchange images between drivers and applications, it is
+necessary to have standard image data formats which both sides will
+interpret the same way. V4L2 includes several such formats, and this
+section is intended to be an unambiguous specification of the standard
+image data formats in V4L2.
+
+V4L2 drivers are not limited to these formats, however. Driver-specific
+formats are possible. In that case the application may depend on a codec
+to convert images to one of the standard formats when needed. But the
+data can still be stored and retrieved in the proprietary format. For
+example, a device may support a proprietary compressed format.
+Applications can still capture and save the data in the compressed
+format, saving much disk space, and later use a codec to convert the
+images to the X Windows screen format when the video is to be displayed.
+
+Even so, ultimately, some standard formats are needed, so the V4L2
+specification would not be complete without well-defined standard
+formats.
+
+The V4L2 standard formats are mainly uncompressed formats. The pixels
+are always arranged in memory from left to right, and from top to
+bottom. The first byte of data in the image buffer is always for the
+leftmost pixel of the topmost row. Following that is the pixel
+immediately to its right, and so on until the end of the top row of
+pixels. Following the rightmost pixel of the row there may be zero or
+more bytes of padding to guarantee that each row of pixel data has a
+certain alignment. Following the pad bytes, if any, is data for the
+leftmost pixel of the second row from the top, and so on. The last row
+has just as many pad bytes after it as the other rows.
+
+In V4L2 each format has an identifier which looks like ``PIX_FMT_XXX``,
+defined in the :ref:`videodev2.h <videodev>` header file. These
+identifiers represent
+:ref:`four character (FourCC) codes <v4l2-fourcc>` which are also
+listed below, however they are not the same as those used in the Windows
+world.
+
+For some formats, data is stored in separate, discontiguous memory
+buffers. Those formats are identified by a separate set of FourCC codes
+and are referred to as "multi-planar formats". For example, a
+:ref:`YUV422 <V4L2-PIX-FMT-YUV422M>` frame is normally stored in one
+memory buffer, but it can also be placed in two or three separate
+buffers, with Y component in one buffer and CbCr components in another
+in the 2-planar version or with each component in its own buffer in the
+3-planar case. Those sub-buffers are referred to as "*planes*".
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-inzi.rst b/Documentation/userspace-api/media/v4l/pixfmt-inzi.rst
new file mode 100644
index 000000000000..f85cccb71741
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-inzi.rst
@@ -0,0 +1,89 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-INZI:
+
+**************************
+V4L2_PIX_FMT_INZI ('INZI')
+**************************
+
+Infrared 10-bit linked with Depth 16-bit images
+
+
+Description
+===========
+
+Proprietary multi-planar format used by Intel SR300 Depth cameras, comprise of
+Infrared image followed by Depth data. The pixel definition is 32-bpp,
+with the Depth and Infrared Data split into separate continuous planes of
+identical dimensions.
+
+
+
+The first plane - Infrared data - is stored according to
+:ref:`V4L2_PIX_FMT_Y10 <V4L2-PIX-FMT-Y10>` greyscale format.
+Each pixel is 16-bit cell, with actual data stored in the 10 LSBs
+with values in range 0 to 1023.
+The six remaining MSBs are padded with zeros.
+
+
+The second plane provides 16-bit per-pixel Depth data arranged in
+:ref:`V4L2-PIX-FMT-Z16 <V4L2-PIX-FMT-Z16>` format.
+
+
+**Frame Structure.**
+Each cell is a 16-bit word with more significant data stored at higher
+memory address (byte order is little-endian).
+
+
+.. raw:: latex
+
+    \small
+
+.. tabularcolumns:: |p{2.5cm}|p{2.5cm}|p{2.5cm}|p{2.5cm}|p{2.5cm}|p{2.5cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 1
+    :widths:    1 1 1 1 1 1
+
+    * - Ir\ :sub:`0,0`
+      - Ir\ :sub:`0,1`
+      - Ir\ :sub:`0,2`
+      - ...
+      - ...
+      - ...
+    * - :cspan:`5` ...
+    * - :cspan:`5` Infrared Data
+    * - :cspan:`5` ...
+    * - ...
+      - ...
+      - ...
+      - Ir\ :sub:`n-1,n-3`
+      - Ir\ :sub:`n-1,n-2`
+      - Ir\ :sub:`n-1,n-1`
+    * - Depth\ :sub:`0,0`
+      - Depth\ :sub:`0,1`
+      - Depth\ :sub:`0,2`
+      - ...
+      - ...
+      - ...
+    * - :cspan:`5` ...
+    * - :cspan:`5` Depth Data
+    * - :cspan:`5` ...
+    * - ...
+      - ...
+      - ...
+      - Depth\ :sub:`n-1,n-3`
+      - Depth\ :sub:`n-1,n-2`
+      - Depth\ :sub:`n-1,n-1`
+
+.. raw:: latex
+
+    \normalsize
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-m420.rst b/Documentation/userspace-api/media/v4l/pixfmt-m420.rst
new file mode 100644
index 000000000000..5180bbe16c6e
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-m420.rst
@@ -0,0 +1,133 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-M420:
+
+**************************
+V4L2_PIX_FMT_M420 ('M420')
+**************************
+
+Format with ½ horizontal and vertical chroma resolution, also known as
+YUV 4:2:0. Hybrid plane line-interleaved layout.
+
+
+Description
+===========
+
+M420 is a YUV format with ½ horizontal and vertical chroma subsampling
+(YUV 4:2:0). Pixels are organized as interleaved luma and chroma planes.
+Two lines of luma data are followed by one line of chroma data.
+
+The luma plane has one byte per pixel. The chroma plane contains
+interleaved CbCr pixels subsampled by ½ in the horizontal and vertical
+directions. Each CbCr pair belongs to four pixels. For example,
+Cb\ :sub:`0`/Cr\ :sub:`0` belongs to Y'\ :sub:`00`, Y'\ :sub:`01`,
+Y'\ :sub:`10`, Y'\ :sub:`11`.
+
+All line lengths are identical: if the Y lines include pad bytes so do
+the CbCr lines.
+
+**Byte Order.**
+Each cell is one byte.
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - start + 0:
+      - Y'\ :sub:`00`
+      - Y'\ :sub:`01`
+      - Y'\ :sub:`02`
+      - Y'\ :sub:`03`
+    * - start + 4:
+      - Y'\ :sub:`10`
+      - Y'\ :sub:`11`
+      - Y'\ :sub:`12`
+      - Y'\ :sub:`13`
+    * - start + 8:
+      - Cb\ :sub:`00`
+      - Cr\ :sub:`00`
+      - Cb\ :sub:`01`
+      - Cr\ :sub:`01`
+    * - start + 16:
+      - Y'\ :sub:`20`
+      - Y'\ :sub:`21`
+      - Y'\ :sub:`22`
+      - Y'\ :sub:`23`
+    * - start + 20:
+      - Y'\ :sub:`30`
+      - Y'\ :sub:`31`
+      - Y'\ :sub:`32`
+      - Y'\ :sub:`33`
+    * - start + 24:
+      - Cb\ :sub:`10`
+      - Cr\ :sub:`10`
+      - Cb\ :sub:`11`
+      - Cr\ :sub:`11`
+
+
+**Color Sample Location:**
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * -
+      - 0
+      -
+      - 1
+      - 2
+      -
+      - 3
+    * - 0
+      - Y
+      -
+      - Y
+      - Y
+      -
+      - Y
+    * -
+      -
+      - C
+      -
+      -
+      - C
+      -
+    * - 1
+      - Y
+      -
+      - Y
+      - Y
+      -
+      - Y
+    * -
+    * - 2
+      - Y
+      -
+      - Y
+      - Y
+      -
+      - Y
+    * -
+      -
+      - C
+      -
+      -
+      - C
+      -
+    * - 3
+      - Y
+      -
+      - Y
+      - Y
+      -
+      - Y
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-meta-d4xx.rst b/Documentation/userspace-api/media/v4l/pixfmt-meta-d4xx.rst
new file mode 100644
index 000000000000..4eaf2f9086a9
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-meta-d4xx.rst
@@ -0,0 +1,220 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _v4l2-meta-fmt-d4xx:
+
+*******************************
+V4L2_META_FMT_D4XX ('D4XX')
+*******************************
+
+Intel D4xx UVC Cameras Metadata
+
+
+Description
+===========
+
+Intel D4xx (D435 and other) cameras include per-frame metadata in their UVC
+payload headers, following the Microsoft(R) UVC extension proposal [1_]. That
+means, that the private D4XX metadata, following the standard UVC header, is
+organised in blocks. D4XX cameras implement several standard block types,
+proposed by Microsoft, and several proprietary ones. Supported standard metadata
+types are MetadataId_CaptureStats (ID 3), MetadataId_CameraExtrinsics (ID 4),
+and MetadataId_CameraIntrinsics (ID 5). For their description see [1_]. This
+document describes proprietary metadata types, used by D4xx cameras.
+
+V4L2_META_FMT_D4XX buffers follow the metadata buffer layout of
+V4L2_META_FMT_UVC with the only difference, that it also includes proprietary
+payload header data. D4xx cameras use bulk transfers and only send one payload
+per frame, therefore their headers cannot be larger than 255 bytes.
+
+Below are proprietary Microsoft style metadata types, used by D4xx cameras,
+where all fields are in little endian order:
+
+.. tabularcolumns:: |p{5.0cm}|p{12.5cm}|
+
+
+.. flat-table:: D4xx metadata
+    :widths: 1 2
+    :header-rows:  1
+    :stub-columns: 0
+
+    * - **Field**
+      - **Description**
+    * - :cspan:`1` *Depth Control*
+    * - __u32 ID
+      - 0x80000000
+    * - __u32 Size
+      - Size in bytes (currently 56)
+    * - __u32 Version
+      - Version of this structure. The documentation herein corresponds to
+        version xxx. The version number will be incremented when new fields are
+        added.
+    * - __u32 Flags
+      - A bitmask of flags: see [2_] below
+    * - __u32 Gain
+      - Gain value in internal units, same as the V4L2_CID_GAIN control, used to
+	capture the frame
+    * - __u32 Exposure
+      - Exposure time (in microseconds) used to capture the frame
+    * - __u32 Laser power
+      - Power of the laser LED 0-360, used for depth measurement
+    * - __u32 AE mode
+      - 0: manual; 1: automatic exposure
+    * - __u32 Exposure priority
+      - Exposure priority value: 0 - constant frame rate
+    * - __u32 AE ROI left
+      - Left border of the AE Region of Interest (all ROI values are in pixels
+	and lie between 0 and maximum width or height respectively)
+    * - __u32 AE ROI right
+      - Right border of the AE Region of Interest
+    * - __u32 AE ROI top
+      - Top border of the AE Region of Interest
+    * - __u32 AE ROI bottom
+      - Bottom border of the AE Region of Interest
+    * - __u32 Preset
+      - Preset selector value, default: 0, unless changed by the user
+    * - __u32 Laser mode
+      - 0: off, 1: on
+    * - :cspan:`1` *Capture Timing*
+    * - __u32 ID
+      - 0x80000001
+    * - __u32 Size
+      - Size in bytes (currently 40)
+    * - __u32 Version
+      - Version of this structure. The documentation herein corresponds to
+        version xxx. The version number will be incremented when new fields are
+        added.
+    * - __u32 Flags
+      - A bitmask of flags: see [3_] below
+    * - __u32 Frame counter
+      - Monotonically increasing counter
+    * - __u32 Optical time
+      - Time in microseconds from the beginning of a frame till its middle
+    * - __u32 Readout time
+      - Time, used to read out a frame in microseconds
+    * - __u32 Exposure time
+      - Frame exposure time in microseconds
+    * - __u32 Frame interval
+      - In microseconds = 1000000 / framerate
+    * - __u32 Pipe latency
+      - Time in microseconds from start of frame to data in USB buffer
+    * - :cspan:`1` *Configuration*
+    * - __u32 ID
+      - 0x80000002
+    * - __u32 Size
+      - Size in bytes (currently 40)
+    * - __u32 Version
+      - Version of this structure. The documentation herein corresponds to
+        version xxx. The version number will be incremented when new fields are
+        added.
+    * - __u32 Flags
+      - A bitmask of flags: see [4_] below
+    * - __u8 Hardware type
+      - Camera hardware version [5_]
+    * - __u8 SKU ID
+      - Camera hardware configuration [6_]
+    * - __u32 Cookie
+      - Internal synchronisation
+    * - __u16 Format
+      - Image format code [7_]
+    * - __u16 Width
+      - Width in pixels
+    * - __u16 Height
+      - Height in pixels
+    * - __u16 Framerate
+      - Requested frame rate per second
+    * - __u16 Trigger
+      - Byte 0: bit 0: depth and RGB are synchronised, bit 1: external trigger
+
+.. _1:
+
+[1] https://docs.microsoft.com/en-us/windows-hardware/drivers/stream/uvc-extensions-1-5
+
+.. _2:
+
+[2] Depth Control flags specify which fields are valid: ::
+
+  0x00000001 Gain
+  0x00000002 Exposure
+  0x00000004 Laser power
+  0x00000008 AE mode
+  0x00000010 Exposure priority
+  0x00000020 AE ROI
+  0x00000040 Preset
+
+.. _3:
+
+[3] Capture Timing flags specify which fields are valid: ::
+
+  0x00000001 Frame counter
+  0x00000002 Optical time
+  0x00000004 Readout time
+  0x00000008 Exposure time
+  0x00000010 Frame interval
+  0x00000020 Pipe latency
+
+.. _4:
+
+[4] Configuration flags specify which fields are valid: ::
+
+  0x00000001 Hardware type
+  0x00000002 SKU ID
+  0x00000004 Cookie
+  0x00000008 Format
+  0x00000010 Width
+  0x00000020 Height
+  0x00000040 Framerate
+  0x00000080 Trigger
+  0x00000100 Cal count
+
+.. _5:
+
+[5] Camera model: ::
+
+  0 DS5
+  1 IVCAM2
+
+.. _6:
+
+[6] 8-bit camera hardware configuration bitfield: ::
+
+  [1:0] depthCamera
+	00: no depth
+	01: standard depth
+	10: wide depth
+	11: reserved
+  [2]   depthIsActive - has a laser projector
+  [3]   RGB presence
+  [4]   Inertial Measurement Unit (IMU) presence
+  [5]   projectorType
+	0: HPTG
+	1: Princeton
+  [6]   0: a projector, 1: an LED
+  [7]   reserved
+
+.. _7:
+
+[7] Image format codes per video streaming interface:
+
+Depth: ::
+
+  1 Z16
+  2 Z
+
+Left sensor: ::
+
+  1 Y8
+  2 UYVY
+  3 R8L8
+  4 Calibration
+  5 W10
+
+Fish Eye sensor: ::
+
+  1 RAW8
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-meta-intel-ipu3.rst b/Documentation/userspace-api/media/v4l/pixfmt-meta-intel-ipu3.rst
new file mode 100644
index 000000000000..97a9a2925671
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-meta-intel-ipu3.rst
@@ -0,0 +1,104 @@
+.. This file is dual-licensed: you can use it either under the terms
+.. of the GPL 2.0 or the GFDL 1.1+ license, at your option. Note that this
+.. dual licensing only applies to this file, and not this project as a
+.. whole.
+..
+.. a) This file is free software; you can redistribute it and/or
+..    modify it under the terms of the GNU General Public License version
+..    2.0 as published by the Free Software Foundation.
+..
+..    This file is distributed in the hope that it will be useful,
+..    but WITHOUT ANY WARRANTY; without even the implied warranty of
+..    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+..    GNU General Public License version 2.0 for more details.
+..
+.. Or, alternatively,
+..
+.. b) Permission is granted to copy, distribute and/or modify this
+..    document under the terms of the GNU Free Documentation License,
+..    Version 1.1 or any later version published by the Free Software
+..    Foundation, with no Invariant Sections, no Front-Cover Texts
+..    and no Back-Cover Texts. A copy of the license is included at
+..    Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _v4l2-meta-fmt-params:
+.. _v4l2-meta-fmt-stat-3a:
+
+******************************************************************
+V4L2_META_FMT_IPU3_PARAMS ('ip3p'), V4L2_META_FMT_IPU3_3A ('ip3s')
+******************************************************************
+
+.. ipu3_uapi_stats_3a
+
+3A statistics
+=============
+
+The IPU3 ImgU 3A statistics accelerators collect different statistics over
+an input Bayer frame. Those statistics are obtained from the "ipu3-imgu [01] 3a
+stat" metadata capture video nodes, using the :c:type:`v4l2_meta_format`
+interface. They are formatted as described by the :c:type:`ipu3_uapi_stats_3a`
+structure.
+
+The statistics collected are AWB (Auto-white balance) RGBS (Red, Green, Blue and
+Saturation measure) cells, AWB filter response, AF (Auto-focus) filter response,
+and AE (Auto-exposure) histogram.
+
+The struct :c:type:`ipu3_uapi_4a_config` saves all configurable parameters.
+
+.. code-block:: c
+
+	struct ipu3_uapi_stats_3a {
+		struct ipu3_uapi_awb_raw_buffer awb_raw_buffer;
+		struct ipu3_uapi_ae_raw_buffer_aligned ae_raw_buffer[IPU3_UAPI_MAX_STRIPES];
+		struct ipu3_uapi_af_raw_buffer af_raw_buffer;
+		struct ipu3_uapi_awb_fr_raw_buffer awb_fr_raw_buffer;
+		struct ipu3_uapi_4a_config stats_4a_config;
+		__u32 ae_join_buffers;
+		__u8 padding[28];
+		struct ipu3_uapi_stats_3a_bubble_info_per_stripe stats_3a_bubble_per_stripe;
+		struct ipu3_uapi_ff_status stats_3a_status;
+	};
+
+.. ipu3_uapi_params
+
+Pipeline parameters
+===================
+
+The pipeline parameters are passed to the "ipu3-imgu [01] parameters" metadata
+output video nodes, using the :c:type:`v4l2_meta_format` interface. They are
+formatted as described by the :c:type:`ipu3_uapi_params` structure.
+
+Both 3A statistics and pipeline parameters described here are closely tied to
+the underlying camera sub-system (CSS) APIs. They are usually consumed and
+produced by dedicated user space libraries that comprise the important tuning
+tools, thus freeing the developers from being bothered with the low level
+hardware and algorithm details.
+
+.. code-block:: c
+
+	struct ipu3_uapi_params {
+		/* Flags which of the settings below are to be applied */
+		struct ipu3_uapi_flags use;
+
+		/* Accelerator cluster parameters */
+		struct ipu3_uapi_acc_param acc_param;
+
+		/* ISP vector address space parameters */
+		struct ipu3_uapi_isp_lin_vmem_params lin_vmem_params;
+		struct ipu3_uapi_isp_tnr3_vmem_params tnr3_vmem_params;
+		struct ipu3_uapi_isp_xnr3_vmem_params xnr3_vmem_params;
+
+		/* ISP data memory (DMEM) parameters */
+		struct ipu3_uapi_isp_tnr3_params tnr3_dmem_params;
+		struct ipu3_uapi_isp_xnr3_params xnr3_dmem_params;
+
+		/* Optical black level compensation */
+		struct ipu3_uapi_obgrid_param obgrid_param;
+	};
+
+Intel IPU3 ImgU uAPI data types
+===============================
+
+.. kernel-doc:: drivers/staging/media/ipu3/include/intel-ipu3.h
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-meta-uvc.rst b/Documentation/userspace-api/media/v4l/pixfmt-meta-uvc.rst
new file mode 100644
index 000000000000..debc50285a25
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-meta-uvc.rst
@@ -0,0 +1,58 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _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/userspace-api/media/v4l/pixfmt-meta-vivid.rst b/Documentation/userspace-api/media/v4l/pixfmt-meta-vivid.rst
new file mode 100644
index 000000000000..34a2382ef91c
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-meta-vivid.rst
@@ -0,0 +1,60 @@
+.. This file is dual-licensed: you can use it either under the terms
+.. of the GPL 2.0 or the GFDL 1.1+ license, at your option. Note that this
+.. dual licensing only applies to this file, and not this project as a
+.. whole.
+..
+.. a) This file is free software; you can redistribute it and/or
+..    modify it under the terms of the GNU General Public License as
+..    published by the Free Software Foundation version 2 of
+..    the License.
+..
+..    This file is distributed in the hope that it will be useful,
+..    but WITHOUT ANY WARRANTY; without even the implied warranty of
+..    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+..    GNU General Public License for more details.
+..
+.. Or, alternatively,
+..
+.. b) Permission is granted to copy, distribute and/or modify this
+..    document under the terms of the GNU Free Documentation License,
+..    Version 1.1 or any later version published by the Free Software
+..    Foundation, with no Invariant Sections, no Front-Cover Texts
+..    and no Back-Cover Texts. A copy of the license is included at
+..    Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _v4l2-meta-fmt-vivid:
+
+*******************************
+V4L2_META_FMT_VIVID ('VIVD')
+*******************************
+
+VIVID Metadata Format
+
+
+Description
+===========
+
+This describes metadata format used by the vivid driver.
+
+It sets Brightness, Saturation, Contrast and Hue, each of which maps to
+corresponding controls of the vivid driver with respect to the range and default values.
+
+It contains the following fields:
+
+.. flat-table:: VIVID Metadata
+    :widths: 1 4
+    :header-rows:  1
+    :stub-columns: 0
+
+    * - Field
+      - Description
+    * - u16 brightness;
+      - Image brightness, the value is in the range 0 to 255, with the default value as 128.
+    * - u16 contrast;
+      - Image contrast, the value is in the range 0 to 255, with the default value as 128.
+    * - u16 saturation;
+      - Image color saturation, the value is in the range 0 to 255, with the default value as 128.
+    * - s16 hue;
+      - Image color balance, the value is in the range -128 to 128, with the default value as 0.
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-meta-vsp1-hgo.rst b/Documentation/userspace-api/media/v4l/pixfmt-meta-vsp1-hgo.rst
new file mode 100644
index 000000000000..b780e447dd4b
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-meta-vsp1-hgo.rst
@@ -0,0 +1,175 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _v4l2-meta-fmt-vsp1-hgo:
+
+*******************************
+V4L2_META_FMT_VSP1_HGO ('VSPH')
+*******************************
+
+Renesas R-Car VSP1 1-D Histogram Data
+
+
+Description
+===========
+
+This format describes histogram data generated by the Renesas R-Car VSP1 1-D
+Histogram (HGO) engine.
+
+The VSP1 HGO is a histogram computation engine that can operate on RGB, YCrCb
+or HSV data. It operates on a possibly cropped and subsampled input image and
+computes the minimum, maximum and sum of all pixels as well as per-channel
+histograms.
+
+The HGO can compute histograms independently per channel, on the maximum of the
+three channels (RGB data only) or on the Y channel only (YCbCr only). It can
+additionally output the histogram with 64 or 256 bins, resulting in four
+possible modes of operation.
+
+- In *64 bins normal mode*, the HGO operates on the three channels independently
+  to compute three 64-bins histograms. RGB, YCbCr and HSV image formats are
+  supported.
+- In *64 bins maximum mode*, the HGO operates on the maximum of the (R, G, B)
+  channels to compute a single 64-bins histogram. Only the RGB image format is
+  supported.
+- In *256 bins normal mode*, the HGO operates on the Y channel to compute a
+  single 256-bins histogram. Only the YCbCr image format is supported.
+- In *256 bins maximum mode*, the HGO operates on the maximum of the (R, G, B)
+  channels to compute a single 256-bins histogram. Only the RGB image format is
+  supported.
+
+**Byte Order.**
+All data is stored in memory in little endian format. Each cell in the tables
+contains one byte.
+
+.. flat-table:: VSP1 HGO Data - 64 Bins, Normal Mode (792 bytes)
+    :header-rows:  2
+    :stub-columns: 0
+
+    * - Offset
+      - :cspan:`4` Memory
+    * -
+      - [31:24]
+      - [23:16]
+      - [15:8]
+      - [7:0]
+    * - 0
+      -
+      - R/Cr/H max [7:0]
+      -
+      - R/Cr/H min [7:0]
+    * - 4
+      -
+      - G/Y/S max [7:0]
+      -
+      - G/Y/S min [7:0]
+    * - 8
+      -
+      - B/Cb/V max [7:0]
+      -
+      - B/Cb/V min [7:0]
+    * - 12
+      - :cspan:`4` R/Cr/H sum [31:0]
+    * - 16
+      - :cspan:`4` G/Y/S sum [31:0]
+    * - 20
+      - :cspan:`4` B/Cb/V sum [31:0]
+    * - 24
+      - :cspan:`4` R/Cr/H bin 0 [31:0]
+    * -
+      - :cspan:`4` ...
+    * - 276
+      - :cspan:`4` R/Cr/H bin 63 [31:0]
+    * - 280
+      - :cspan:`4` G/Y/S bin 0 [31:0]
+    * -
+      - :cspan:`4` ...
+    * - 532
+      - :cspan:`4` G/Y/S bin 63 [31:0]
+    * - 536
+      - :cspan:`4` B/Cb/V bin 0 [31:0]
+    * -
+      - :cspan:`4` ...
+    * - 788
+      - :cspan:`4` B/Cb/V bin 63 [31:0]
+
+.. flat-table:: VSP1 HGO Data - 64 Bins, Max Mode (264 bytes)
+    :header-rows:  2
+    :stub-columns: 0
+
+    * - Offset
+      - :cspan:`4` Memory
+    * -
+      - [31:24]
+      - [23:16]
+      - [15:8]
+      - [7:0]
+    * - 0
+      -
+      - max(R,G,B) max [7:0]
+      -
+      - max(R,G,B) min [7:0]
+    * - 4
+      - :cspan:`4` max(R,G,B) sum [31:0]
+    * - 8
+      - :cspan:`4` max(R,G,B) bin 0 [31:0]
+    * -
+      - :cspan:`4` ...
+    * - 260
+      - :cspan:`4` max(R,G,B) bin 63 [31:0]
+
+.. flat-table:: VSP1 HGO Data - 256 Bins, Normal Mode (1032 bytes)
+    :header-rows:  2
+    :stub-columns: 0
+
+    * - Offset
+      - :cspan:`4` Memory
+    * -
+      - [31:24]
+      - [23:16]
+      - [15:8]
+      - [7:0]
+    * - 0
+      -
+      - Y max [7:0]
+      -
+      - Y min [7:0]
+    * - 4
+      - :cspan:`4` Y sum [31:0]
+    * - 8
+      - :cspan:`4` Y bin 0 [31:0]
+    * -
+      - :cspan:`4` ...
+    * - 1028
+      - :cspan:`4` Y bin 255 [31:0]
+
+.. flat-table:: VSP1 HGO Data - 256 Bins, Max Mode (1032 bytes)
+    :header-rows:  2
+    :stub-columns: 0
+
+    * - Offset
+      - :cspan:`4` Memory
+    * -
+      - [31:24]
+      - [23:16]
+      - [15:8]
+      - [7:0]
+    * - 0
+      -
+      - max(R,G,B) max [7:0]
+      -
+      - max(R,G,B) min [7:0]
+    * - 4
+      - :cspan:`4` max(R,G,B) sum [31:0]
+    * - 8
+      - :cspan:`4` max(R,G,B) bin 0 [31:0]
+    * -
+      - :cspan:`4` ...
+    * - 1028
+      - :cspan:`4` max(R,G,B) bin 255 [31:0]
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-meta-vsp1-hgt.rst b/Documentation/userspace-api/media/v4l/pixfmt-meta-vsp1-hgt.rst
new file mode 100644
index 000000000000..e165320cc1ff
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-meta-vsp1-hgt.rst
@@ -0,0 +1,136 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _v4l2-meta-fmt-vsp1-hgt:
+
+*******************************
+V4L2_META_FMT_VSP1_HGT ('VSPT')
+*******************************
+
+Renesas R-Car VSP1 2-D Histogram Data
+
+
+Description
+===========
+
+This format describes histogram data generated by the Renesas R-Car VSP1
+2-D Histogram (HGT) engine.
+
+The VSP1 HGT is a histogram computation engine that operates on HSV
+data. It operates on a possibly cropped and subsampled input image and
+computes the sum, maximum and minimum of the S component as well as a
+weighted frequency histogram based on the H and S components.
+
+The histogram is a matrix of 6 Hue and 32 Saturation buckets, 192 in
+total. Each HSV value is added to one or more buckets with a weight
+between 1 and 16 depending on the Hue areas configuration. Finding the
+corresponding buckets is done by inspecting the H and S value independently.
+
+The Saturation position **n** (0 - 31) of the bucket in the matrix is
+found by the expression:
+
+    n = S / 8
+
+The Hue position **m** (0 - 5) of the bucket in the matrix depends on
+how the HGT Hue areas are configured. There are 6 user configurable Hue
+Areas which can be configured to cover overlapping Hue values:
+
+.. raw:: latex
+
+    \small
+
+::
+
+         Area 0       Area 1       Area 2       Area 3       Area 4       Area 5
+        ________     ________     ________     ________     ________     ________
+   \   /|      |\   /|      |\   /|      |\   /|      |\   /|      |\   /|      |\   /
+    \ / |      | \ / |      | \ / |      | \ / |      | \ / |      | \ / |      | \ /
+     X  |      |  X  |      |  X  |      |  X  |      |  X  |      |  X  |      |  X
+    / \ |      | / \ |      | / \ |      | / \ |      | / \ |      | / \ |      | / \
+   /   \|      |/   \|      |/   \|      |/   \|      |/   \|      |/   \|      |/   \
+  5U   0L      0U   1L      1U   2L      2U   3L      3U   4L      4U   5L      5U   0L
+        <0..............................Hue Value............................255>
+
+
+.. raw:: latex
+
+    \normalsize
+
+When two consecutive areas don't overlap (n+1L is equal to nU) the boundary
+value is considered as part of the lower area.
+
+Pixels with a hue value included in the centre of an area (between nL and nU
+included) are attributed to that single area and given a weight of 16. Pixels
+with a hue value included in the overlapping region between two areas (between
+n+1L and nU excluded) are attributed to both areas and given a weight for each
+of these areas proportional to their position along the diagonal lines
+(rounded down).
+
+The Hue area setup must match one of the following constrains:
+
+::
+
+    0L <= 0U <= 1L <= 1U <= 2L <= 2U <= 3L <= 3U <= 4L <= 4U <= 5L <= 5U
+
+::
+
+    0U <= 1L <= 1U <= 2L <= 2U <= 3L <= 3U <= 4L <= 4U <= 5L <= 5U <= 0L
+
+**Byte Order.**
+All data is stored in memory in little endian format. Each cell in the tables
+contains one byte.
+
+.. flat-table:: VSP1 HGT Data - (776 bytes)
+    :header-rows:  2
+    :stub-columns: 0
+
+    * - Offset
+      - :cspan:`4` Memory
+    * -
+      - [31:24]
+      - [23:16]
+      - [15:8]
+      - [7:0]
+    * - 0
+      - -
+      - S max [7:0]
+      - -
+      - S min [7:0]
+    * - 4
+      - :cspan:`4` S sum [31:0]
+    * - 8
+      - :cspan:`4` Histogram bucket (m=0, n=0) [31:0]
+    * - 12
+      - :cspan:`4` Histogram bucket (m=0, n=1) [31:0]
+    * -
+      - :cspan:`4` ...
+    * - 132
+      - :cspan:`4` Histogram bucket (m=0, n=31) [31:0]
+    * - 136
+      - :cspan:`4` Histogram bucket (m=1, n=0) [31:0]
+    * -
+      - :cspan:`4` ...
+    * - 264
+      - :cspan:`4` Histogram bucket (m=2, n=0) [31:0]
+    * -
+      - :cspan:`4` ...
+    * - 392
+      - :cspan:`4` Histogram bucket (m=3, n=0) [31:0]
+    * -
+      - :cspan:`4` ...
+    * - 520
+      - :cspan:`4` Histogram bucket (m=4, n=0) [31:0]
+    * -
+      - :cspan:`4` ...
+    * - 648
+      - :cspan:`4` Histogram bucket (m=5, n=0) [31:0]
+    * -
+      - :cspan:`4` ...
+    * - 772
+      - :cspan:`4` Histogram bucket (m=5, n=31) [31:0]
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-nv12.rst b/Documentation/userspace-api/media/v4l/pixfmt-nv12.rst
new file mode 100644
index 000000000000..19d47b38e02a
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-nv12.rst
@@ -0,0 +1,136 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-NV12:
+.. _V4L2-PIX-FMT-NV21:
+
+******************************************************
+V4L2_PIX_FMT_NV12 ('NV12'), V4L2_PIX_FMT_NV21 ('NV21')
+******************************************************
+
+
+V4L2_PIX_FMT_NV21
+Formats with ½ horizontal and vertical chroma resolution, also known as
+YUV 4:2:0. One luminance and one chrominance plane with alternating
+chroma samples as opposed to ``V4L2_PIX_FMT_YVU420``
+
+
+Description
+===========
+
+These are two-plane versions of the YUV 4:2:0 format. The three
+components are separated into two sub-images or planes. The Y plane is
+first. The Y plane has one byte per pixel. For ``V4L2_PIX_FMT_NV12``, a
+combined CbCr plane immediately follows the Y plane in memory. The CbCr
+plane is the same width, in bytes, as the Y plane (and of the image),
+but is half as tall in pixels. Each CbCr pair belongs to four pixels.
+For example, Cb\ :sub:`0`/Cr\ :sub:`0` belongs to Y'\ :sub:`00`,
+Y'\ :sub:`01`, Y'\ :sub:`10`, Y'\ :sub:`11`. ``V4L2_PIX_FMT_NV21`` is
+the same except the Cb and Cr bytes are swapped, the CrCb plane starts
+with a Cr byte.
+
+If the Y plane has pad bytes after each row, then the CbCr plane has as
+many pad bytes after its rows.
+
+**Byte Order.**
+Each cell is one byte.
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - start + 0:
+      - Y'\ :sub:`00`
+      - Y'\ :sub:`01`
+      - Y'\ :sub:`02`
+      - Y'\ :sub:`03`
+    * - start + 4:
+      - Y'\ :sub:`10`
+      - Y'\ :sub:`11`
+      - Y'\ :sub:`12`
+      - Y'\ :sub:`13`
+    * - start + 8:
+      - Y'\ :sub:`20`
+      - Y'\ :sub:`21`
+      - Y'\ :sub:`22`
+      - Y'\ :sub:`23`
+    * - start + 12:
+      - Y'\ :sub:`30`
+      - Y'\ :sub:`31`
+      - Y'\ :sub:`32`
+      - Y'\ :sub:`33`
+    * - start + 16:
+      - Cb\ :sub:`00`
+      - Cr\ :sub:`00`
+      - Cb\ :sub:`01`
+      - Cr\ :sub:`01`
+    * - start + 20:
+      - Cb\ :sub:`10`
+      - Cr\ :sub:`10`
+      - Cb\ :sub:`11`
+      - Cr\ :sub:`11`
+
+
+**Color Sample Location:**
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * -
+      - 0
+      -
+      - 1
+      - 2
+      -
+      - 3
+    * - 0
+      - Y
+      -
+      - Y
+      - Y
+      -
+      - Y
+    * -
+      -
+      - C
+      -
+      -
+      - C
+      -
+    * - 1
+      - Y
+      -
+      - Y
+      - Y
+      -
+      - Y
+    * -
+    * - 2
+      - Y
+      -
+      - Y
+      - Y
+      -
+      - Y
+    * -
+      -
+      - C
+      -
+      -
+      - C
+      -
+    * - 3
+      - Y
+      -
+      - Y
+      - Y
+      -
+      - Y
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-nv12m.rst b/Documentation/userspace-api/media/v4l/pixfmt-nv12m.rst
new file mode 100644
index 000000000000..115ea603c13f
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-nv12m.rst
@@ -0,0 +1,151 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-NV12M:
+.. _v4l2-pix-fmt-nv12mt-16x16:
+.. _V4L2-PIX-FMT-NV21M:
+
+***********************************************************************************
+V4L2_PIX_FMT_NV12M ('NM12'), V4L2_PIX_FMT_NV21M ('NM21'), V4L2_PIX_FMT_NV12MT_16X16
+***********************************************************************************
+
+
+V4L2_PIX_FMT_NV21M
+V4L2_PIX_FMT_NV12MT_16X16
+Variation of ``V4L2_PIX_FMT_NV12`` and ``V4L2_PIX_FMT_NV21`` with planes
+non contiguous in memory.
+
+
+Description
+===========
+
+This is a multi-planar, two-plane version of the YUV 4:2:0 format. The
+three components are separated into two sub-images or planes.
+``V4L2_PIX_FMT_NV12M`` differs from ``V4L2_PIX_FMT_NV12`` in that the
+two planes are non-contiguous in memory, i.e. the chroma plane do not
+necessarily immediately follows the luma plane. The luminance data
+occupies the first plane. The Y plane has one byte per pixel. In the
+second plane there is a chrominance data with alternating chroma
+samples. The CbCr plane is the same width, in bytes, as the Y plane (and
+of the image), but is half as tall in pixels. Each CbCr pair belongs to
+four pixels. For example, Cb\ :sub:`0`/Cr\ :sub:`0` belongs to
+Y'\ :sub:`00`, Y'\ :sub:`01`, Y'\ :sub:`10`, Y'\ :sub:`11`.
+``V4L2_PIX_FMT_NV12MT_16X16`` is the tiled version of
+``V4L2_PIX_FMT_NV12M`` with 16x16 macroblock tiles. Here pixels are
+arranged in 16x16 2D tiles and tiles are arranged in linear order in
+memory. ``V4L2_PIX_FMT_NV21M`` is the same as ``V4L2_PIX_FMT_NV12M``
+except the Cb and Cr bytes are swapped, the CrCb plane starts with a Cr
+byte.
+
+``V4L2_PIX_FMT_NV12M`` is intended to be used only in drivers and
+applications that support the multi-planar API, described in
+:ref:`planar-apis`.
+
+If the Y plane has pad bytes after each row, then the CbCr plane has as
+many pad bytes after its rows.
+
+**Byte Order.**
+Each cell is one byte.
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - start0 + 0:
+      - Y'\ :sub:`00`
+      - Y'\ :sub:`01`
+      - Y'\ :sub:`02`
+      - Y'\ :sub:`03`
+    * - start0 + 4:
+      - Y'\ :sub:`10`
+      - Y'\ :sub:`11`
+      - Y'\ :sub:`12`
+      - Y'\ :sub:`13`
+    * - start0 + 8:
+      - Y'\ :sub:`20`
+      - Y'\ :sub:`21`
+      - Y'\ :sub:`22`
+      - Y'\ :sub:`23`
+    * - start0 + 12:
+      - Y'\ :sub:`30`
+      - Y'\ :sub:`31`
+      - Y'\ :sub:`32`
+      - Y'\ :sub:`33`
+    * -
+    * - start1 + 0:
+      - Cb\ :sub:`00`
+      - Cr\ :sub:`00`
+      - Cb\ :sub:`01`
+      - Cr\ :sub:`01`
+    * - start1 + 4:
+      - Cb\ :sub:`10`
+      - Cr\ :sub:`10`
+      - Cb\ :sub:`11`
+      - Cr\ :sub:`11`
+
+
+**Color Sample Location:**
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * -
+      - 0
+      -
+      - 1
+      - 2
+      -
+      - 3
+    * - 0
+      - Y
+      -
+      - Y
+      - Y
+      -
+      - Y
+    * -
+      -
+      - C
+      -
+      -
+      - C
+      -
+    * - 1
+      - Y
+      -
+      - Y
+      - Y
+      -
+      - Y
+    * -
+    * - 2
+      - Y
+      -
+      - Y
+      - Y
+      -
+      - Y
+    * -
+      -
+      - C
+      -
+      -
+      -
+      - C
+      -
+    * - 3
+      - Y
+      -
+      - Y
+      - Y
+      -
+      - Y
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-nv12mt.rst b/Documentation/userspace-api/media/v4l/pixfmt-nv12mt.rst
new file mode 100644
index 000000000000..daac1c16d4f2
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-nv12mt.rst
@@ -0,0 +1,67 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-NV12MT:
+
+****************************
+V4L2_PIX_FMT_NV12MT ('TM12')
+****************************
+
+Formats with ½ horizontal and vertical chroma resolution. This format
+has two planes - one for luminance and one for chrominance. Chroma
+samples are interleaved. The difference to ``V4L2_PIX_FMT_NV12`` is the
+memory layout. Pixels are grouped in macroblocks of 64x32 size. The
+order of macroblocks in memory is also not standard.
+
+
+Description
+===========
+
+This is the two-plane versions of the YUV 4:2:0 format where data is
+grouped into 64x32 macroblocks. The three components are separated into
+two sub-images or planes. The Y plane has one byte per pixel and pixels
+are grouped into 64x32 macroblocks. The CbCr plane has the same width,
+in bytes, as the Y plane (and the image), but is half as tall in pixels.
+The chroma plane is also grouped into 64x32 macroblocks.
+
+Width of the buffer has to be aligned to the multiple of 128, and height
+alignment is 32. Every four adjacent buffers - two horizontally and two
+vertically are grouped together and are located in memory in Z or
+flipped Z order.
+
+Layout of macroblocks in memory is presented in the following figure.
+
+
+.. _nv12mt:
+
+.. kernel-figure:: nv12mt.svg
+    :alt:    nv12mt.svg
+    :align:  center
+
+    V4L2_PIX_FMT_NV12MT macroblock Z shape memory layout
+
+The requirement that width is multiple of 128 is implemented because,
+the Z shape cannot be cut in half horizontally. In case the vertical
+resolution of macroblocks is odd then the last row of macroblocks is
+arranged in a linear order.
+
+In case of chroma the layout is identical. Cb and Cr samples are
+interleaved. Height of the buffer is aligned to 32.
+
+
+.. _nv12mt_ex:
+
+.. kernel-figure:: nv12mt_example.svg
+    :alt:    nv12mt_example.svg
+    :align:  center
+
+    Example V4L2_PIX_FMT_NV12MT memory layout of macroblocks
+
+Memory layout of macroblocks of ``V4L2_PIX_FMT_NV12MT`` format in most
+extreme case.
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-nv16.rst b/Documentation/userspace-api/media/v4l/pixfmt-nv16.rst
new file mode 100644
index 000000000000..977636fc98d6
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-nv16.rst
@@ -0,0 +1,160 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-NV16:
+.. _V4L2-PIX-FMT-NV61:
+
+******************************************************
+V4L2_PIX_FMT_NV16 ('NV16'), V4L2_PIX_FMT_NV61 ('NV61')
+******************************************************
+
+V4L2_PIX_FMT_NV61
+Formats with ½ horizontal chroma resolution, also known as YUV 4:2:2.
+One luminance and one chrominance plane with alternating chroma samples
+as opposed to ``V4L2_PIX_FMT_YVU420``
+
+
+Description
+===========
+
+These are two-plane versions of the YUV 4:2:2 format. The three
+components are separated into two sub-images or planes. The Y plane is
+first. The Y plane has one byte per pixel. For ``V4L2_PIX_FMT_NV16``, a
+combined CbCr plane immediately follows the Y plane in memory. The CbCr
+plane is the same width and height, in bytes, as the Y plane (and of the
+image). Each CbCr pair belongs to two pixels. For example,
+Cb\ :sub:`0`/Cr\ :sub:`0` belongs to Y'\ :sub:`00`, Y'\ :sub:`01`.
+``V4L2_PIX_FMT_NV61`` is the same except the Cb and Cr bytes are
+swapped, the CrCb plane starts with a Cr byte.
+
+If the Y plane has pad bytes after each row, then the CbCr plane has as
+many pad bytes after its rows.
+
+**Byte Order.**
+Each cell is one byte.
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - start + 0:
+      - Y'\ :sub:`00`
+      - Y'\ :sub:`01`
+      - Y'\ :sub:`02`
+      - Y'\ :sub:`03`
+    * - start + 4:
+      - Y'\ :sub:`10`
+      - Y'\ :sub:`11`
+      - Y'\ :sub:`12`
+      - Y'\ :sub:`13`
+    * - start + 8:
+      - Y'\ :sub:`20`
+      - Y'\ :sub:`21`
+      - Y'\ :sub:`22`
+      - Y'\ :sub:`23`
+    * - start + 12:
+      - Y'\ :sub:`30`
+      - Y'\ :sub:`31`
+      - Y'\ :sub:`32`
+      - Y'\ :sub:`33`
+    * - start + 16:
+      - Cb\ :sub:`00`
+      - Cr\ :sub:`00`
+      - Cb\ :sub:`01`
+      - Cr\ :sub:`01`
+    * - start + 20:
+      - Cb\ :sub:`10`
+      - Cr\ :sub:`10`
+      - Cb\ :sub:`11`
+      - Cr\ :sub:`11`
+    * - start + 24:
+      - Cb\ :sub:`20`
+      - Cr\ :sub:`20`
+      - Cb\ :sub:`21`
+      - Cr\ :sub:`21`
+    * - start + 28:
+      - Cb\ :sub:`30`
+      - Cr\ :sub:`30`
+      - Cb\ :sub:`31`
+      - Cr\ :sub:`31`
+
+
+**Color Sample Location:**
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * -
+      - 0
+      -
+      - 1
+      - 2
+      -
+      - 3
+    * - 0
+      - Y
+      -
+      - Y
+      - Y
+      -
+      - Y
+    * -
+      -
+      - C
+      -
+      -
+      - C
+      -
+    * - 1
+      - Y
+      -
+      - Y
+      - Y
+      -
+      - Y
+    * -
+      -
+      - C
+      -
+      -
+      - C
+      -
+    * -
+    * - 2
+      - Y
+      -
+      - Y
+      - Y
+      -
+      - Y
+    * -
+      -
+      - C
+      -
+      -
+      - C
+      -
+    * - 3
+      - Y
+      -
+      - Y
+      - Y
+      -
+      - Y
+    * -
+      -
+      - C
+      -
+      -
+      - C
+      -
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-nv16m.rst b/Documentation/userspace-api/media/v4l/pixfmt-nv16m.rst
new file mode 100644
index 000000000000..cf33942d942d
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-nv16m.rst
@@ -0,0 +1,164 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-NV16M:
+.. _v4l2-pix-fmt-nv61m:
+
+********************************************************
+V4L2_PIX_FMT_NV16M ('NM16'), V4L2_PIX_FMT_NV61M ('NM61')
+********************************************************
+
+V4L2_PIX_FMT_NV61M
+Variation of ``V4L2_PIX_FMT_NV16`` and ``V4L2_PIX_FMT_NV61`` with planes
+non contiguous in memory.
+
+
+Description
+===========
+
+This is a multi-planar, two-plane version of the YUV 4:2:2 format. The
+three components are separated into two sub-images or planes.
+``V4L2_PIX_FMT_NV16M`` differs from ``V4L2_PIX_FMT_NV16`` in that the
+two planes are non-contiguous in memory, i.e. the chroma plane does not
+necessarily immediately follow the luma plane. The luminance data
+occupies the first plane. The Y plane has one byte per pixel. In the
+second plane there is chrominance data with alternating chroma samples.
+The CbCr plane is the same width and height, in bytes, as the Y plane.
+Each CbCr pair belongs to two pixels. For example,
+Cb\ :sub:`0`/Cr\ :sub:`0` belongs to Y'\ :sub:`00`, Y'\ :sub:`01`.
+``V4L2_PIX_FMT_NV61M`` is the same as ``V4L2_PIX_FMT_NV16M`` except the
+Cb and Cr bytes are swapped, the CrCb plane starts with a Cr byte.
+
+``V4L2_PIX_FMT_NV16M`` and ``V4L2_PIX_FMT_NV61M`` are intended to be
+used only in drivers and applications that support the multi-planar API,
+described in :ref:`planar-apis`.
+
+**Byte Order.**
+Each cell is one byte.
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - start0 + 0:
+      - Y'\ :sub:`00`
+      - Y'\ :sub:`01`
+      - Y'\ :sub:`02`
+      - Y'\ :sub:`03`
+    * - start0 + 4:
+      - Y'\ :sub:`10`
+      - Y'\ :sub:`11`
+      - Y'\ :sub:`12`
+      - Y'\ :sub:`13`
+    * - start0 + 8:
+      - Y'\ :sub:`20`
+      - Y'\ :sub:`21`
+      - Y'\ :sub:`22`
+      - Y'\ :sub:`23`
+    * - start0 + 12:
+      - Y'\ :sub:`30`
+      - Y'\ :sub:`31`
+      - Y'\ :sub:`32`
+      - Y'\ :sub:`33`
+    * -
+    * - start1 + 0:
+      - Cb\ :sub:`00`
+      - Cr\ :sub:`00`
+      - Cb\ :sub:`02`
+      - Cr\ :sub:`02`
+    * - start1 + 4:
+      - Cb\ :sub:`10`
+      - Cr\ :sub:`10`
+      - Cb\ :sub:`12`
+      - Cr\ :sub:`12`
+    * - start1 + 8:
+      - Cb\ :sub:`20`
+      - Cr\ :sub:`20`
+      - Cb\ :sub:`22`
+      - Cr\ :sub:`22`
+    * - start1 + 12:
+      - Cb\ :sub:`30`
+      - Cr\ :sub:`30`
+      - Cb\ :sub:`32`
+      - Cr\ :sub:`32`
+
+
+**Color Sample Location:**
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * -
+      - 0
+      -
+      - 1
+      - 2
+      -
+      - 3
+    * - 0
+      - Y
+      -
+      - Y
+      - Y
+      -
+      - Y
+    * -
+      -
+      - C
+      -
+      -
+      - C
+      -
+    * - 1
+      - Y
+      -
+      - Y
+      - Y
+      -
+      - Y
+    * -
+      -
+      - C
+      -
+      -
+      - C
+      -
+    * -
+    * - 2
+      - Y
+      -
+      - Y
+      - Y
+      -
+      - Y
+    * -
+      -
+      - C
+      -
+      -
+      - C
+      -
+    * - 3
+      - Y
+      -
+      - Y
+      - Y
+      -
+      - Y
+    * -
+      -
+      - C
+      -
+      -
+      - C
+      -
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-nv24.rst b/Documentation/userspace-api/media/v4l/pixfmt-nv24.rst
new file mode 100644
index 000000000000..c6fb97bd0472
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-nv24.rst
@@ -0,0 +1,102 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-NV24:
+.. _V4L2-PIX-FMT-NV42:
+
+******************************************************
+V4L2_PIX_FMT_NV24 ('NV24'), V4L2_PIX_FMT_NV42 ('NV42')
+******************************************************
+
+V4L2_PIX_FMT_NV42
+Formats with full horizontal and vertical chroma resolutions, also known
+as YUV 4:4:4. One luminance and one chrominance plane with alternating
+chroma samples as opposed to ``V4L2_PIX_FMT_YVU420``
+
+
+Description
+===========
+
+These are two-plane versions of the YUV 4:4:4 format. The three
+components are separated into two sub-images or planes. The Y plane is
+first, with each Y sample stored in one byte per pixel. For
+``V4L2_PIX_FMT_NV24``, a combined CbCr plane immediately follows the Y
+plane in memory. The CbCr plane has the same width and height, in
+pixels, as the Y plane (and the image). Each line contains one CbCr pair
+per pixel, with each Cb and Cr sample stored in one byte.
+``V4L2_PIX_FMT_NV42`` is the same except that the Cb and Cr samples are
+swapped, the CrCb plane starts with a Cr sample.
+
+If the Y plane has pad bytes after each row, then the CbCr plane has
+twice as many pad bytes after its rows.
+
+**Byte Order.**
+Each cell is one byte.
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - start + 0:
+      - Y'\ :sub:`00`
+      - Y'\ :sub:`01`
+      - Y'\ :sub:`02`
+      - Y'\ :sub:`03`
+    * - start + 4:
+      - Y'\ :sub:`10`
+      - Y'\ :sub:`11`
+      - Y'\ :sub:`12`
+      - Y'\ :sub:`13`
+    * - start + 8:
+      - Y'\ :sub:`20`
+      - Y'\ :sub:`21`
+      - Y'\ :sub:`22`
+      - Y'\ :sub:`23`
+    * - start + 12:
+      - Y'\ :sub:`30`
+      - Y'\ :sub:`31`
+      - Y'\ :sub:`32`
+      - Y'\ :sub:`33`
+    * - start + 16:
+      - Cb\ :sub:`00`
+      - Cr\ :sub:`00`
+      - Cb\ :sub:`01`
+      - Cr\ :sub:`01`
+      - Cb\ :sub:`02`
+      - Cr\ :sub:`02`
+      - Cb\ :sub:`03`
+      - Cr\ :sub:`03`
+    * - start + 24:
+      - Cb\ :sub:`10`
+      - Cr\ :sub:`10`
+      - Cb\ :sub:`11`
+      - Cr\ :sub:`11`
+      - Cb\ :sub:`12`
+      - Cr\ :sub:`12`
+      - Cb\ :sub:`13`
+      - Cr\ :sub:`13`
+    * - start + 32:
+      - Cb\ :sub:`20`
+      - Cr\ :sub:`20`
+      - Cb\ :sub:`21`
+      - Cr\ :sub:`21`
+      - Cb\ :sub:`22`
+      - Cr\ :sub:`22`
+      - Cb\ :sub:`23`
+      - Cr\ :sub:`23`
+    * - start + 40:
+      - Cb\ :sub:`30`
+      - Cr\ :sub:`30`
+      - Cb\ :sub:`31`
+      - Cr\ :sub:`31`
+      - Cb\ :sub:`32`
+      - Cr\ :sub:`32`
+      - Cb\ :sub:`33`
+      - Cr\ :sub:`33`
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-packed-hsv.rst b/Documentation/userspace-api/media/v4l/pixfmt-packed-hsv.rst
new file mode 100644
index 000000000000..b8c9b0225eea
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-packed-hsv.rst
@@ -0,0 +1,164 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _packed-hsv:
+
+******************
+Packed HSV formats
+******************
+
+Description
+===========
+
+The *hue* (h) is measured in degrees, the equivalence between degrees and LSBs
+depends on the hsv-encoding used, see :ref:`colorspaces`.
+The *saturation* (s) and the *value* (v) are measured in percentage of the
+cylinder: 0 being the smallest value and 255 the maximum.
+
+
+The values are packed in 24 or 32 bit formats.
+
+
+.. raw:: latex
+
+    \begingroup
+    \tiny
+    \setlength{\tabcolsep}{2pt}
+
+.. tabularcolumns:: |p{2.6cm}|p{0.8cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|
+
+.. _packed-hsv-formats:
+
+.. flat-table:: Packed HSV Image Formats
+    :header-rows:  2
+    :stub-columns: 0
+
+    * - Identifier
+      - Code
+      -
+      - :cspan:`7` Byte 0 in memory
+      - :cspan:`7` Byte 1
+      - :cspan:`7` Byte 2
+      - :cspan:`7` Byte 3
+    * -
+      -
+      - Bit
+      - 7
+      - 6
+      - 5
+      - 4
+      - 3
+      - 2
+      - 1
+      - 0
+
+      - 7
+      - 6
+      - 5
+      - 4
+      - 3
+      - 2
+      - 1
+      - 0
+
+      - 7
+      - 6
+      - 5
+      - 4
+      - 3
+      - 2
+      - 1
+      - 0
+
+      - 7
+      - 6
+      - 5
+      - 4
+      - 3
+      - 2
+      - 1
+      - 0
+    * .. _V4L2-PIX-FMT-HSV32:
+
+      - ``V4L2_PIX_FMT_HSV32``
+      - 'HSV4'
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+
+      - h\ :sub:`7`
+      - h\ :sub:`6`
+      - h\ :sub:`5`
+      - h\ :sub:`4`
+      - h\ :sub:`3`
+      - h\ :sub:`2`
+      - h\ :sub:`1`
+      - h\ :sub:`0`
+
+      - s\ :sub:`7`
+      - s\ :sub:`6`
+      - s\ :sub:`5`
+      - s\ :sub:`4`
+      - s\ :sub:`3`
+      - s\ :sub:`2`
+      - s\ :sub:`1`
+      - s\ :sub:`0`
+
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+    * .. _V4L2-PIX-FMT-HSV24:
+
+      - ``V4L2_PIX_FMT_HSV24``
+      - 'HSV3'
+      -
+      - h\ :sub:`7`
+      - h\ :sub:`6`
+      - h\ :sub:`5`
+      - h\ :sub:`4`
+      - h\ :sub:`3`
+      - h\ :sub:`2`
+      - h\ :sub:`1`
+      - h\ :sub:`0`
+
+      - s\ :sub:`7`
+      - s\ :sub:`6`
+      - s\ :sub:`5`
+      - s\ :sub:`4`
+      - s\ :sub:`3`
+      - s\ :sub:`2`
+      - s\ :sub:`1`
+      - s\ :sub:`0`
+
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+      -
+
+.. raw:: latex
+
+    \endgroup
+
+Bit 7 is the most significant bit.
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-packed-yuv.rst b/Documentation/userspace-api/media/v4l/pixfmt-packed-yuv.rst
new file mode 100644
index 000000000000..bbd4bd094deb
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-packed-yuv.rst
@@ -0,0 +1,380 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _packed-yuv:
+
+******************
+Packed YUV formats
+******************
+
+Description
+===========
+
+Similar to the packed RGB formats these formats store the Y, Cb and Cr
+component of each pixel in one 16 or 32 bit word.
+
+
+.. raw:: latex
+
+    \begingroup
+    \tiny
+    \setlength{\tabcolsep}{2pt}
+
+.. _packed-yuv-formats:
+
+.. tabularcolumns:: |p{2.5cm}|p{0.69cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|
+
+.. flat-table:: Packed YUV Image Formats
+    :header-rows:  2
+    :stub-columns: 0
+
+    * - Identifier
+      - Code
+
+      - :cspan:`7` Byte 0 in memory
+
+      - :cspan:`7` Byte 1
+
+      - :cspan:`7` Byte 2
+
+      - :cspan:`7` Byte 3
+
+    * -
+      -
+      - 7
+      - 6
+      - 5
+      - 4
+      - 3
+      - 2
+      - 1
+      - 0
+
+      - 7
+      - 6
+      - 5
+      - 4
+      - 3
+      - 2
+      - 1
+      - 0
+
+      - 7
+      - 6
+      - 5
+      - 4
+      - 3
+      - 2
+      - 1
+      - 0
+
+      - 7
+      - 6
+      - 5
+      - 4
+      - 3
+      - 2
+      - 1
+      - 0
+
+    * .. _V4L2-PIX-FMT-YUV444:
+
+      - ``V4L2_PIX_FMT_YUV444``
+      - 'Y444'
+
+      - Cb\ :sub:`3`
+      - Cb\ :sub:`2`
+      - Cb\ :sub:`1`
+      - Cb\ :sub:`0`
+      - Cr\ :sub:`3`
+      - Cr\ :sub:`2`
+      - Cr\ :sub:`1`
+      - Cr\ :sub:`0`
+
+      - a\ :sub:`3`
+      - a\ :sub:`2`
+      - a\ :sub:`1`
+      - a\ :sub:`0`
+      - Y'\ :sub:`3`
+      - Y'\ :sub:`2`
+      - Y'\ :sub:`1`
+      - Y'\ :sub:`0`
+
+      -  :cspan:`15`
+
+    * .. _V4L2-PIX-FMT-YUV555:
+
+      - ``V4L2_PIX_FMT_YUV555``
+      - 'YUVO'
+
+      - Cb\ :sub:`2`
+      - Cb\ :sub:`1`
+      - Cb\ :sub:`0`
+      - Cr\ :sub:`4`
+      - Cr\ :sub:`3`
+      - Cr\ :sub:`2`
+      - Cr\ :sub:`1`
+      - Cr\ :sub:`0`
+
+      - a
+      - Y'\ :sub:`4`
+      - Y'\ :sub:`3`
+      - Y'\ :sub:`2`
+      - Y'\ :sub:`1`
+      - Y'\ :sub:`0`
+      - Cb\ :sub:`4`
+      - Cb\ :sub:`3`
+
+      -  :cspan:`15`
+    * .. _V4L2-PIX-FMT-YUV565:
+
+      - ``V4L2_PIX_FMT_YUV565``
+      - 'YUVP'
+
+      - Cb\ :sub:`2`
+      - Cb\ :sub:`1`
+      - Cb\ :sub:`0`
+      - Cr\ :sub:`4`
+      - Cr\ :sub:`3`
+      - Cr\ :sub:`2`
+      - Cr\ :sub:`1`
+      - Cr\ :sub:`0`
+
+      - Y'\ :sub:`4`
+      - Y'\ :sub:`3`
+      - Y'\ :sub:`2`
+      - Y'\ :sub:`1`
+      - Y'\ :sub:`0`
+      - Cb\ :sub:`5`
+      - Cb\ :sub:`4`
+      - Cb\ :sub:`3`
+
+      -  :cspan:`15`
+
+    * .. _V4L2-PIX-FMT-YUV32:
+
+      - ``V4L2_PIX_FMT_YUV32``
+      - 'YUV4'
+
+      - a\ :sub:`7`
+      - a\ :sub:`6`
+      - a\ :sub:`5`
+      - a\ :sub:`4`
+      - a\ :sub:`3`
+      - a\ :sub:`2`
+      - a\ :sub:`1`
+      - a\ :sub:`0`
+
+      - Y'\ :sub:`7`
+      - Y'\ :sub:`6`
+      - Y'\ :sub:`5`
+      - Y'\ :sub:`4`
+      - Y'\ :sub:`3`
+      - Y'\ :sub:`2`
+      - Y'\ :sub:`1`
+      - Y'\ :sub:`0`
+
+      - Cb\ :sub:`7`
+      - Cb\ :sub:`6`
+      - Cb\ :sub:`5`
+      - Cb\ :sub:`4`
+      - Cb\ :sub:`3`
+      - Cb\ :sub:`2`
+      - Cb\ :sub:`1`
+      - Cb\ :sub:`0`
+
+      - Cr\ :sub:`7`
+      - Cr\ :sub:`6`
+      - Cr\ :sub:`5`
+      - Cr\ :sub:`4`
+      - Cr\ :sub:`3`
+      - Cr\ :sub:`2`
+      - Cr\ :sub:`1`
+      - Cr\ :sub:`0`
+
+    * .. _V4L2-PIX-FMT-AYUV32:
+
+      - ``V4L2_PIX_FMT_AYUV32``
+      - 'AYUV'
+
+      - a\ :sub:`7`
+      - a\ :sub:`6`
+      - a\ :sub:`5`
+      - a\ :sub:`4`
+      - a\ :sub:`3`
+      - a\ :sub:`2`
+      - a\ :sub:`1`
+      - a\ :sub:`0`
+
+      - Y'\ :sub:`7`
+      - Y'\ :sub:`6`
+      - Y'\ :sub:`5`
+      - Y'\ :sub:`4`
+      - Y'\ :sub:`3`
+      - Y'\ :sub:`2`
+      - Y'\ :sub:`1`
+      - Y'\ :sub:`0`
+
+      - Cb\ :sub:`7`
+      - Cb\ :sub:`6`
+      - Cb\ :sub:`5`
+      - Cb\ :sub:`4`
+      - Cb\ :sub:`3`
+      - Cb\ :sub:`2`
+      - Cb\ :sub:`1`
+      - Cb\ :sub:`0`
+
+      - Cr\ :sub:`7`
+      - Cr\ :sub:`6`
+      - Cr\ :sub:`5`
+      - Cr\ :sub:`4`
+      - Cr\ :sub:`3`
+      - Cr\ :sub:`2`
+      - Cr\ :sub:`1`
+      - Cr\ :sub:`0`
+
+    * .. _V4L2-PIX-FMT-XYUV32:
+
+      - ``V4L2_PIX_FMT_XYUV32``
+      - 'XYUV'
+
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+
+      - Y'\ :sub:`7`
+      - Y'\ :sub:`6`
+      - Y'\ :sub:`5`
+      - Y'\ :sub:`4`
+      - Y'\ :sub:`3`
+      - Y'\ :sub:`2`
+      - Y'\ :sub:`1`
+      - Y'\ :sub:`0`
+
+      - Cb\ :sub:`7`
+      - Cb\ :sub:`6`
+      - Cb\ :sub:`5`
+      - Cb\ :sub:`4`
+      - Cb\ :sub:`3`
+      - Cb\ :sub:`2`
+      - Cb\ :sub:`1`
+      - Cb\ :sub:`0`
+
+      - Cr\ :sub:`7`
+      - Cr\ :sub:`6`
+      - Cr\ :sub:`5`
+      - Cr\ :sub:`4`
+      - Cr\ :sub:`3`
+      - Cr\ :sub:`2`
+      - Cr\ :sub:`1`
+      - Cr\ :sub:`0`
+
+    * .. _V4L2-PIX-FMT-VUYA32:
+
+      - ``V4L2_PIX_FMT_VUYA32``
+      - 'VUYA'
+
+      - Cr\ :sub:`7`
+      - Cr\ :sub:`6`
+      - Cr\ :sub:`5`
+      - Cr\ :sub:`4`
+      - Cr\ :sub:`3`
+      - Cr\ :sub:`2`
+      - Cr\ :sub:`1`
+      - Cr\ :sub:`0`
+
+      - Cb\ :sub:`7`
+      - Cb\ :sub:`6`
+      - Cb\ :sub:`5`
+      - Cb\ :sub:`4`
+      - Cb\ :sub:`3`
+      - Cb\ :sub:`2`
+      - Cb\ :sub:`1`
+      - Cb\ :sub:`0`
+
+      - Y'\ :sub:`7`
+      - Y'\ :sub:`6`
+      - Y'\ :sub:`5`
+      - Y'\ :sub:`4`
+      - Y'\ :sub:`3`
+      - Y'\ :sub:`2`
+      - Y'\ :sub:`1`
+      - Y'\ :sub:`0`
+
+      - a\ :sub:`7`
+      - a\ :sub:`6`
+      - a\ :sub:`5`
+      - a\ :sub:`4`
+      - a\ :sub:`3`
+      - a\ :sub:`2`
+      - a\ :sub:`1`
+      - a\ :sub:`0`
+
+    * .. _V4L2-PIX-FMT-VUYX32:
+
+      - ``V4L2_PIX_FMT_VUYX32``
+      - 'VUYX'
+
+      - Cr\ :sub:`7`
+      - Cr\ :sub:`6`
+      - Cr\ :sub:`5`
+      - Cr\ :sub:`4`
+      - Cr\ :sub:`3`
+      - Cr\ :sub:`2`
+      - Cr\ :sub:`1`
+      - Cr\ :sub:`0`
+
+      - Cb\ :sub:`7`
+      - Cb\ :sub:`6`
+      - Cb\ :sub:`5`
+      - Cb\ :sub:`4`
+      - Cb\ :sub:`3`
+      - Cb\ :sub:`2`
+      - Cb\ :sub:`1`
+      - Cb\ :sub:`0`
+
+      - Y'\ :sub:`7`
+      - Y'\ :sub:`6`
+      - Y'\ :sub:`5`
+      - Y'\ :sub:`4`
+      - Y'\ :sub:`3`
+      - Y'\ :sub:`2`
+      - Y'\ :sub:`1`
+      - Y'\ :sub:`0`
+
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+
+.. raw:: latex
+
+    \endgroup
+
+.. note::
+
+    #) Bit 7 is the most significant bit;
+
+    #) The value of a = alpha bits is undefined when reading from the driver,
+       ignored when writing to the driver, except when alpha blending has
+       been negotiated for a :ref:`Video Overlay <overlay>` or
+       :ref:`Video Output Overlay <osd>` for the formats Y444, YUV555 and
+       YUV4. However, for formats AYUV32 and VUYA32, the alpha component is
+       expected to contain a meaningful value that can be used by drivers
+       and applications. And, the formats XYUV32 and VUYX32 contain undefined
+       alpha values that must be ignored by all applications and drivers.
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-reserved.rst b/Documentation/userspace-api/media/v4l/pixfmt-reserved.rst
new file mode 100644
index 000000000000..59b9e7238f90
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-reserved.rst
@@ -0,0 +1,282 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _pixfmt-reserved:
+
+***************************
+Reserved Format Identifiers
+***************************
+
+These formats are not defined by this specification, they are just
+listed for reference and to avoid naming conflicts. If you want to
+register your own format, send an e-mail to the linux-media mailing list
+`https://linuxtv.org/lists.php <https://linuxtv.org/lists.php>`__
+for inclusion in the ``videodev2.h`` file. If you want to share your
+format with other developers add a link to your documentation and send a
+copy to the linux-media mailing list for inclusion in this section. If
+you think your format should be listed in a standard format section
+please make a proposal on the linux-media mailing list.
+
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. _reserved-formats:
+
+.. flat-table:: Reserved Image Formats
+    :header-rows:  1
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - Identifier
+      - Code
+      - Details
+    * .. _V4L2-PIX-FMT-DV:
+
+      - ``V4L2_PIX_FMT_DV``
+      - 'dvsd'
+      - unknown
+    * .. _V4L2-PIX-FMT-ET61X251:
+
+      - ``V4L2_PIX_FMT_ET61X251``
+      - 'E625'
+      - Compressed format of the ET61X251 driver.
+    * .. _V4L2-PIX-FMT-HI240:
+
+      - ``V4L2_PIX_FMT_HI240``
+      - 'HI24'
+      - 8 bit RGB format used by the BTTV driver.
+    * .. _V4L2-PIX-FMT-HM12:
+
+      - ``V4L2_PIX_FMT_HM12``
+      - 'HM12'
+      - YUV 4:2:0 format used by the IVTV driver.
+
+	The format is documented in the kernel sources in the file
+	``Documentation/userspace-api/media/drivers/cx2341x-uapi.rst``
+    * .. _V4L2-PIX-FMT-CPIA1:
+
+      - ``V4L2_PIX_FMT_CPIA1``
+      - 'CPIA'
+      - YUV format used by the gspca cpia1 driver.
+    * .. _V4L2-PIX-FMT-JPGL:
+
+      - ``V4L2_PIX_FMT_JPGL``
+      - 'JPGL'
+      - JPEG-Light format (Pegasus Lossless JPEG) used in Divio webcams NW
+	80x.
+    * .. _V4L2-PIX-FMT-SPCA501:
+
+      - ``V4L2_PIX_FMT_SPCA501``
+      - 'S501'
+      - YUYV per line used by the gspca driver.
+    * .. _V4L2-PIX-FMT-SPCA505:
+
+      - ``V4L2_PIX_FMT_SPCA505``
+      - 'S505'
+      - YYUV per line used by the gspca driver.
+    * .. _V4L2-PIX-FMT-SPCA508:
+
+      - ``V4L2_PIX_FMT_SPCA508``
+      - 'S508'
+      - YUVY per line used by the gspca driver.
+    * .. _V4L2-PIX-FMT-SPCA561:
+
+      - ``V4L2_PIX_FMT_SPCA561``
+      - 'S561'
+      - Compressed GBRG Bayer format used by the gspca driver.
+    * .. _V4L2-PIX-FMT-PAC207:
+
+      - ``V4L2_PIX_FMT_PAC207``
+      - 'P207'
+      - Compressed BGGR Bayer format used by the gspca driver.
+    * .. _V4L2-PIX-FMT-MR97310A:
+
+      - ``V4L2_PIX_FMT_MR97310A``
+      - 'M310'
+      - Compressed BGGR Bayer format used by the gspca driver.
+    * .. _V4L2-PIX-FMT-JL2005BCD:
+
+      - ``V4L2_PIX_FMT_JL2005BCD``
+      - 'JL20'
+      - JPEG compressed RGGB Bayer format used by the gspca driver.
+    * .. _V4L2-PIX-FMT-OV511:
+
+      - ``V4L2_PIX_FMT_OV511``
+      - 'O511'
+      - OV511 JPEG format used by the gspca driver.
+    * .. _V4L2-PIX-FMT-OV518:
+
+      - ``V4L2_PIX_FMT_OV518``
+      - 'O518'
+      - OV518 JPEG format used by the gspca driver.
+    * .. _V4L2-PIX-FMT-PJPG:
+
+      - ``V4L2_PIX_FMT_PJPG``
+      - 'PJPG'
+      - Pixart 73xx JPEG format used by the gspca driver.
+    * .. _V4L2-PIX-FMT-SE401:
+
+      - ``V4L2_PIX_FMT_SE401``
+      - 'S401'
+      - Compressed RGB format used by the gspca se401 driver
+    * .. _V4L2-PIX-FMT-SQ905C:
+
+      - ``V4L2_PIX_FMT_SQ905C``
+      - '905C'
+      - Compressed RGGB bayer format used by the gspca driver.
+    * .. _V4L2-PIX-FMT-MJPEG:
+
+      - ``V4L2_PIX_FMT_MJPEG``
+      - 'MJPG'
+      - Compressed format used by the Zoran driver
+    * .. _V4L2-PIX-FMT-PWC1:
+
+      - ``V4L2_PIX_FMT_PWC1``
+      - 'PWC1'
+      - Compressed format of the PWC driver.
+    * .. _V4L2-PIX-FMT-PWC2:
+
+      - ``V4L2_PIX_FMT_PWC2``
+      - 'PWC2'
+      - Compressed format of the PWC driver.
+    * .. _V4L2-PIX-FMT-SN9C10X:
+
+      - ``V4L2_PIX_FMT_SN9C10X``
+      - 'S910'
+      - Compressed format of the SN9C102 driver.
+    * .. _V4L2-PIX-FMT-SN9C20X-I420:
+
+      - ``V4L2_PIX_FMT_SN9C20X_I420``
+      - 'S920'
+      - YUV 4:2:0 format of the gspca sn9c20x driver.
+    * .. _V4L2-PIX-FMT-SN9C2028:
+
+      - ``V4L2_PIX_FMT_SN9C2028``
+      - 'SONX'
+      - Compressed GBRG bayer format of the gspca sn9c2028 driver.
+    * .. _V4L2-PIX-FMT-STV0680:
+
+      - ``V4L2_PIX_FMT_STV0680``
+      - 'S680'
+      - Bayer format of the gspca stv0680 driver.
+    * .. _V4L2-PIX-FMT-WNVA:
+
+      - ``V4L2_PIX_FMT_WNVA``
+      - 'WNVA'
+      - Used by the Winnov Videum driver,
+	`http://www.thedirks.org/winnov/ <http://www.thedirks.org/winnov/>`__
+    * .. _V4L2-PIX-FMT-TM6000:
+
+      - ``V4L2_PIX_FMT_TM6000``
+      - 'TM60'
+      - Used by Trident tm6000
+    * .. _V4L2-PIX-FMT-CIT-YYVYUY:
+
+      - ``V4L2_PIX_FMT_CIT_YYVYUY``
+      - 'CITV'
+      - Used by xirlink CIT, found at IBM webcams.
+
+	Uses one line of Y then 1 line of VYUY
+    * .. _V4L2-PIX-FMT-KONICA420:
+
+      - ``V4L2_PIX_FMT_KONICA420``
+      - 'KONI'
+      - Used by Konica webcams.
+
+	YUV420 planar in blocks of 256 pixels.
+    * .. _V4L2-PIX-FMT-YYUV:
+
+      - ``V4L2_PIX_FMT_YYUV``
+      - 'YYUV'
+      - unknown
+    * .. _V4L2-PIX-FMT-Y4:
+
+      - ``V4L2_PIX_FMT_Y4``
+      - 'Y04 '
+      - Old 4-bit greyscale format. Only the most significant 4 bits of
+	each byte are used, the other bits are set to 0.
+    * .. _V4L2-PIX-FMT-Y6:
+
+      - ``V4L2_PIX_FMT_Y6``
+      - 'Y06 '
+      - Old 6-bit greyscale format. Only the most significant 6 bits of
+	each byte are used, the other bits are set to 0.
+    * .. _V4L2-PIX-FMT-S5C-UYVY-JPG:
+
+      - ``V4L2_PIX_FMT_S5C_UYVY_JPG``
+      - 'S5CI'
+      - Two-planar format used by Samsung S5C73MX cameras. The first plane
+	contains interleaved JPEG and UYVY image data, followed by meta
+	data in form of an array of offsets to the UYVY data blocks. The
+	actual pointer array follows immediately the interleaved JPEG/UYVY
+	data, the number of entries in this array equals the height of the
+	UYVY image. Each entry is a 4-byte unsigned integer in big endian
+	order and it's an offset to a single pixel line of the UYVY image.
+	The first plane can start either with JPEG or UYVY data chunk. The
+	size of a single UYVY block equals the UYVY image's width
+	multiplied by 2. The size of a JPEG chunk depends on the image and
+	can vary with each line.
+
+	The second plane, at an offset of 4084 bytes, contains a 4-byte
+	offset to the pointer array in the first plane. This offset is
+	followed by a 4-byte value indicating size of the pointer array.
+	All numbers in the second plane are also in big endian order.
+	Remaining data in the second plane is undefined. The information
+	in the second plane allows to easily find location of the pointer
+	array, which can be different for each frame. The size of the
+	pointer array is constant for given UYVY image height.
+
+	In order to extract UYVY and JPEG frames an application can
+	initially set a data pointer to the start of first plane and then
+	add an offset from the first entry of the pointers table. Such a
+	pointer indicates start of an UYVY image pixel line. Whole UYVY
+	line can be copied to a separate buffer. These steps should be
+	repeated for each line, i.e. the number of entries in the pointer
+	array. Anything what's in between the UYVY lines is JPEG data and
+	should be concatenated to form the JPEG stream.
+    * .. _V4L2-PIX-FMT-MT21C:
+
+      - ``V4L2_PIX_FMT_MT21C``
+      - 'MT21'
+      - Compressed two-planar YVU420 format used by Mediatek MT8173.
+	The compression is lossless.
+	It is an opaque intermediate format and the MDP hardware must be
+	used to convert ``V4L2_PIX_FMT_MT21C`` to ``V4L2_PIX_FMT_NV12M``,
+	``V4L2_PIX_FMT_YUV420M`` or ``V4L2_PIX_FMT_YVU420``.
+    * .. _V4L2-PIX-FMT-SUNXI-TILED-NV12:
+
+      - ``V4L2_PIX_FMT_SUNXI_TILED_NV12``
+      - 'ST12'
+      - Two-planar NV12-based format used by the video engine found on Allwinner
+	(codenamed sunxi) platforms, with 32x32 tiles for the luminance plane
+	and 32x64 tiles for the chrominance plane. The data in each tile is
+	stored in linear order, within the tile bounds. Each tile follows the
+	previous one linearly in memory (from left to right, top to bottom).
+
+	The associated buffer dimensions are aligned to match an integer number
+	of tiles, resulting in 32-aligned resolutions for the luminance plane
+	and 16-aligned resolutions for the chrominance plane (with 2x2
+	subsampling).
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. _format-flags:
+
+.. flat-table:: Format Flags
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_PIX_FMT_FLAG_PREMUL_ALPHA``
+      - 0x00000001
+      - The color values are premultiplied by the alpha channel value. For
+	example, if a light blue pixel with 50% transparency was described
+	by RGBA values (128, 192, 255, 128), the same pixel described with
+	premultiplied colors would be described by RGBA values (64, 96,
+	128, 128)
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-rgb.rst b/Documentation/userspace-api/media/v4l/pixfmt-rgb.rst
new file mode 100644
index 000000000000..89cc2a37b285
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-rgb.rst
@@ -0,0 +1,1304 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _pixfmt-rgb:
+
+***********
+RGB Formats
+***********
+
+Description
+===========
+
+These formats are designed to match the pixel formats of typical PC
+graphics frame buffers. They occupy 8, 16, 24 or 32 bits per pixel.
+These are all packed-pixel formats, meaning all the data for a pixel lie
+next to each other in memory.
+
+.. raw:: latex
+
+    \begingroup
+    \tiny
+    \setlength{\tabcolsep}{2pt}
+
+.. tabularcolumns:: |p{2.8cm}|p{2.0cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|
+
+
+.. flat-table:: RGB Image Formats
+    :header-rows:  2
+    :stub-columns: 0
+
+    * - Identifier
+      - Code
+      - :cspan:`7` Byte 0 in memory
+      - :cspan:`7` Byte 1
+      - :cspan:`7` Byte 2
+      - :cspan:`7` Byte 3
+    * -
+      -
+      - 7
+      - 6
+      - 5
+      - 4
+      - 3
+      - 2
+      - 1
+      - 0
+
+      - 7
+      - 6
+      - 5
+      - 4
+      - 3
+      - 2
+      - 1
+      - 0
+
+      - 7
+      - 6
+      - 5
+      - 4
+      - 3
+      - 2
+      - 1
+      - 0
+
+      - 7
+      - 6
+      - 5
+      - 4
+      - 3
+      - 2
+      - 1
+      - 0
+    * .. _V4L2-PIX-FMT-RGB332:
+
+      - ``V4L2_PIX_FMT_RGB332``
+      - 'RGB1'
+
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      -
+    * .. _V4L2-PIX-FMT-ARGB444:
+
+      - ``V4L2_PIX_FMT_ARGB444``
+      - 'AR12'
+
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+
+      - a\ :sub:`3`
+      - a\ :sub:`2`
+      - a\ :sub:`1`
+      - a\ :sub:`0`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      -
+    * .. _V4L2-PIX-FMT-XRGB444:
+
+      - ``V4L2_PIX_FMT_XRGB444``
+      - 'XR12'
+
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+
+      - `-`
+      - `-`
+      - `-`
+      - `-`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      -
+    * .. _V4L2-PIX-FMT-RGBA444:
+
+      - ``V4L2_PIX_FMT_RGBA444``
+      - 'RA12'
+
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      - a\ :sub:`3`
+      - a\ :sub:`2`
+      - a\ :sub:`1`
+      - a\ :sub:`0`
+
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      -
+    * .. _V4L2-PIX-FMT-RGBX444:
+
+      - ``V4L2_PIX_FMT_RGBX444``
+      - 'RX12'
+
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      - `-`
+      - `-`
+      - `-`
+      - `-`
+
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      -
+    * .. _V4L2-PIX-FMT-ABGR444:
+
+      - ``V4L2_PIX_FMT_ABGR444``
+      - 'AB12'
+
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+
+      - a\ :sub:`3`
+      - a\ :sub:`2`
+      - a\ :sub:`1`
+      - a\ :sub:`0`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      -
+    * .. _V4L2-PIX-FMT-XBGR444:
+
+      - ``V4L2_PIX_FMT_XBGR444``
+      - 'XB12'
+
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+
+      - `-`
+      - `-`
+      - `-`
+      - `-`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      -
+    * .. _V4L2-PIX-FMT-BGRA444:
+
+      - ``V4L2_PIX_FMT_BGRA444``
+      - 'BA12'
+
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - a\ :sub:`3`
+      - a\ :sub:`2`
+      - a\ :sub:`1`
+      - a\ :sub:`0`
+
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      -
+    * .. _V4L2-PIX-FMT-BGRX444:
+
+      - ``V4L2_PIX_FMT_BGRX444``
+      - 'BX12'
+
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - `-`
+      - `-`
+      - `-`
+      - `-`
+
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      -
+    * .. _V4L2-PIX-FMT-ARGB555:
+
+      - ``V4L2_PIX_FMT_ARGB555``
+      - 'AR15'
+
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+
+      - a
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      -
+    * .. _V4L2-PIX-FMT-XRGB555:
+
+      - ``V4L2_PIX_FMT_XRGB555``
+      - 'XR15'
+
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+
+      - `-`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      -
+    * .. _V4L2-PIX-FMT-RGBA555:
+
+      - ``V4L2_PIX_FMT_RGBA555``
+      - 'RA15'
+
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      - a
+
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      -
+    * .. _V4L2-PIX-FMT-RGBX555:
+
+      - ``V4L2_PIX_FMT_RGBX555``
+      - 'RX15'
+
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      - `-`
+
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      -
+    * .. _V4L2-PIX-FMT-ABGR555:
+
+      - ``V4L2_PIX_FMT_ABGR555``
+      - 'AB15'
+
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+
+      - a
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      -
+    * .. _V4L2-PIX-FMT-XBGR555:
+
+      - ``V4L2_PIX_FMT_XBGR555``
+      - 'XB15'
+
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+
+      - `-`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      -
+    * .. _V4L2-PIX-FMT-BGRA555:
+
+      - ``V4L2_PIX_FMT_BGRA555``
+      - 'BA15'
+
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - a
+
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      -
+    * .. _V4L2-PIX-FMT-BGRX555:
+
+      - ``V4L2_PIX_FMT_BGRX555``
+      - 'BX15'
+
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - `-`
+
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      -
+    * .. _V4L2-PIX-FMT-RGB565:
+
+      - ``V4L2_PIX_FMT_RGB565``
+      - 'RGBP'
+
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      -
+    * .. _V4L2-PIX-FMT-ARGB555X:
+
+      - ``V4L2_PIX_FMT_ARGB555X``
+      - 'AR15' | (1 << 31)
+
+      - a
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      -
+    * .. _V4L2-PIX-FMT-XRGB555X:
+
+      - ``V4L2_PIX_FMT_XRGB555X``
+      - 'XR15' | (1 << 31)
+
+      - `-`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      -
+    * .. _V4L2-PIX-FMT-RGB565X:
+
+      - ``V4L2_PIX_FMT_RGB565X``
+      - 'RGBR'
+
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      -
+    * .. _V4L2-PIX-FMT-BGR24:
+
+      - ``V4L2_PIX_FMT_BGR24``
+      - 'BGR3'
+
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      -
+    * .. _V4L2-PIX-FMT-RGB24:
+
+      - ``V4L2_PIX_FMT_RGB24``
+      - 'RGB3'
+
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      -
+    * .. _V4L2-PIX-FMT-BGR666:
+
+      - ``V4L2_PIX_FMT_BGR666``
+      - 'BGRH'
+
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - `-`
+      - `-`
+      - `-`
+      - `-`
+      - `-`
+      - `-`
+
+      - `-`
+      - `-`
+      - `-`
+      - `-`
+      - `-`
+      - `-`
+      - `-`
+      - `-`
+    * .. _V4L2-PIX-FMT-ABGR32:
+
+      - ``V4L2_PIX_FMT_ABGR32``
+      - 'AR24'
+
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+
+      - a\ :sub:`7`
+      - a\ :sub:`6`
+      - a\ :sub:`5`
+      - a\ :sub:`4`
+      - a\ :sub:`3`
+      - a\ :sub:`2`
+      - a\ :sub:`1`
+      - a\ :sub:`0`
+    * .. _V4L2-PIX-FMT-XBGR32:
+
+      - ``V4L2_PIX_FMT_XBGR32``
+      - 'XR24'
+
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+
+      - `-`
+      - `-`
+      - `-`
+      - `-`
+      - `-`
+      - `-`
+      - `-`
+      - `-`
+    * .. _V4L2-PIX-FMT-BGRA32:
+
+      - ``V4L2_PIX_FMT_BGRA32``
+      - 'RA24'
+
+      - a\ :sub:`7`
+      - a\ :sub:`6`
+      - a\ :sub:`5`
+      - a\ :sub:`4`
+      - a\ :sub:`3`
+      - a\ :sub:`2`
+      - a\ :sub:`1`
+      - a\ :sub:`0`
+
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+    * .. _V4L2-PIX-FMT-BGRX32:
+
+      - ``V4L2_PIX_FMT_BGRX32``
+      - 'RX24'
+
+      - `-`
+      - `-`
+      - `-`
+      - `-`
+      - `-`
+      - `-`
+      - `-`
+      - `-`
+
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+    * .. _V4L2-PIX-FMT-RGBA32:
+
+      - ``V4L2_PIX_FMT_RGBA32``
+      - 'AB24'
+
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+
+      - a\ :sub:`7`
+      - a\ :sub:`6`
+      - a\ :sub:`5`
+      - a\ :sub:`4`
+      - a\ :sub:`3`
+      - a\ :sub:`2`
+      - a\ :sub:`1`
+      - a\ :sub:`0`
+    * .. _V4L2-PIX-FMT-RGBX32:
+
+      - ``V4L2_PIX_FMT_RGBX32``
+      - 'XB24'
+
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+
+      - `-`
+      - `-`
+      - `-`
+      - `-`
+      - `-`
+      - `-`
+      - `-`
+      - `-`
+    * .. _V4L2-PIX-FMT-ARGB32:
+
+      - ``V4L2_PIX_FMT_ARGB32``
+      - 'BA24'
+
+      - a\ :sub:`7`
+      - a\ :sub:`6`
+      - a\ :sub:`5`
+      - a\ :sub:`4`
+      - a\ :sub:`3`
+      - a\ :sub:`2`
+      - a\ :sub:`1`
+      - a\ :sub:`0`
+
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+    * .. _V4L2-PIX-FMT-XRGB32:
+
+      - ``V4L2_PIX_FMT_XRGB32``
+      - 'BX24'
+
+      - `-`
+      - `-`
+      - `-`
+      - `-`
+      - `-`
+      - `-`
+      - `-`
+      - `-`
+
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+
+.. raw:: latex
+
+    \endgroup
+
+.. note:: Bit 7 is the most significant bit.
+
+The usage and value of the alpha bits (a) in the ARGB and ABGR formats
+(collectively referred to as alpha formats) depend on the device type
+and hardware operation. :ref:`Capture <capture>` devices (including
+capture queues of mem-to-mem devices) fill the alpha component in
+memory. When the device outputs an alpha channel the alpha component
+will have a meaningful value. Otherwise, when the device doesn't output
+an alpha channel but can set the alpha bit to a user-configurable value,
+the :ref:`V4L2_CID_ALPHA_COMPONENT <v4l2-alpha-component>` control
+is used to specify that alpha value, and the alpha component of all
+pixels will be set to the value specified by that control. Otherwise a
+corresponding format without an alpha component (XRGB or XBGR) must be
+used instead of an alpha format.
+
+:ref:`Output <output>` devices (including output queues of mem-to-mem
+devices and :ref:`video output overlay <osd>` devices) read the alpha
+component from memory. When the device processes the alpha channel the
+alpha component must be filled with meaningful values by applications.
+Otherwise a corresponding format without an alpha component (XRGB or
+XBGR) must be used instead of an alpha format.
+
+The XRGB and XBGR formats contain undefined bits (-). Applications,
+devices and drivers must ignore those bits, for both
+:ref:`capture` and :ref:`output` devices.
+
+**Byte Order.**
+Each cell is one byte.
+
+
+.. raw:: latex
+
+    \small
+
+.. tabularcolumns:: |p{3.1cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|
+
+.. flat-table:: RGB byte order
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       11 3 3 3 3 3 3 3 3 3 3 3 3
+
+    * - start + 0:
+      - B\ :sub:`00`
+      - G\ :sub:`00`
+      - R\ :sub:`00`
+      - B\ :sub:`01`
+      - G\ :sub:`01`
+      - R\ :sub:`01`
+      - B\ :sub:`02`
+      - G\ :sub:`02`
+      - R\ :sub:`02`
+      - B\ :sub:`03`
+      - G\ :sub:`03`
+      - R\ :sub:`03`
+    * - start + 12:
+      - B\ :sub:`10`
+      - G\ :sub:`10`
+      - R\ :sub:`10`
+      - B\ :sub:`11`
+      - G\ :sub:`11`
+      - R\ :sub:`11`
+      - B\ :sub:`12`
+      - G\ :sub:`12`
+      - R\ :sub:`12`
+      - B\ :sub:`13`
+      - G\ :sub:`13`
+      - R\ :sub:`13`
+    * - start + 24:
+      - B\ :sub:`20`
+      - G\ :sub:`20`
+      - R\ :sub:`20`
+      - B\ :sub:`21`
+      - G\ :sub:`21`
+      - R\ :sub:`21`
+      - B\ :sub:`22`
+      - G\ :sub:`22`
+      - R\ :sub:`22`
+      - B\ :sub:`23`
+      - G\ :sub:`23`
+      - R\ :sub:`23`
+    * - start + 36:
+      - B\ :sub:`30`
+      - G\ :sub:`30`
+      - R\ :sub:`30`
+      - B\ :sub:`31`
+      - G\ :sub:`31`
+      - R\ :sub:`31`
+      - B\ :sub:`32`
+      - G\ :sub:`32`
+      - R\ :sub:`32`
+      - B\ :sub:`33`
+      - G\ :sub:`33`
+      - R\ :sub:`33`
+
+.. raw:: latex
+
+    \normalsize
+
+Formats defined in :ref:`pixfmt-rgb-deprecated` are deprecated and
+must not be used by new drivers. They are documented here for reference.
+The meaning of their alpha bits ``(a)`` are ill-defined and interpreted as in
+either the corresponding ARGB or XRGB format, depending on the driver.
+
+
+.. raw:: latex
+
+    \begingroup
+    \tiny
+    \setlength{\tabcolsep}{2pt}
+
+.. tabularcolumns:: |p{2.6cm}|p{0.70cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|
+
+.. _pixfmt-rgb-deprecated:
+
+.. flat-table:: Deprecated Packed RGB Image Formats
+    :header-rows:  2
+    :stub-columns: 0
+
+    * - Identifier
+      - Code
+      - :cspan:`7` Byte 0 in memory
+
+      - :cspan:`7` Byte 1
+
+      - :cspan:`7` Byte 2
+
+      - :cspan:`7` Byte 3
+    * -
+      -
+      - 7
+      - 6
+      - 5
+      - 4
+      - 3
+      - 2
+      - 1
+      - 0
+
+      - 7
+      - 6
+      - 5
+      - 4
+      - 3
+      - 2
+      - 1
+      - 0
+
+      - 7
+      - 6
+      - 5
+      - 4
+      - 3
+      - 2
+      - 1
+      - 0
+
+      - 7
+      - 6
+      - 5
+      - 4
+      - 3
+      - 2
+      - 1
+      - 0
+    * .. _V4L2-PIX-FMT-RGB444:
+
+      - ``V4L2_PIX_FMT_RGB444``
+      - 'R444'
+
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+
+      - a\ :sub:`3`
+      - a\ :sub:`2`
+      - a\ :sub:`1`
+      - a\ :sub:`0`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      -
+    * .. _V4L2-PIX-FMT-RGB555:
+
+      - ``V4L2_PIX_FMT_RGB555``
+      - 'RGBO'
+
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+
+      - a
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      -
+    * .. _V4L2-PIX-FMT-RGB555X:
+
+      - ``V4L2_PIX_FMT_RGB555X``
+      - 'RGBQ'
+
+      - a
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      -
+    * .. _V4L2-PIX-FMT-BGR32:
+
+      - ``V4L2_PIX_FMT_BGR32``
+      - 'BGR4'
+
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+
+      - a\ :sub:`7`
+      - a\ :sub:`6`
+      - a\ :sub:`5`
+      - a\ :sub:`4`
+      - a\ :sub:`3`
+      - a\ :sub:`2`
+      - a\ :sub:`1`
+      - a\ :sub:`0`
+    * .. _V4L2-PIX-FMT-RGB32:
+
+      - ``V4L2_PIX_FMT_RGB32``
+      - 'RGB4'
+
+      - a\ :sub:`7`
+      - a\ :sub:`6`
+      - a\ :sub:`5`
+      - a\ :sub:`4`
+      - a\ :sub:`3`
+      - a\ :sub:`2`
+      - a\ :sub:`1`
+      - a\ :sub:`0`
+
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+
+.. raw:: latex
+
+    \endgroup
+
+A test utility to determine which RGB formats a driver actually supports
+is available from the LinuxTV v4l-dvb repository. See
+`https://linuxtv.org/repo/ <https://linuxtv.org/repo/>`__ for access
+instructions.
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-sdr-cs08.rst b/Documentation/userspace-api/media/v4l/pixfmt-sdr-cs08.rst
new file mode 100644
index 000000000000..13f3908d162a
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-sdr-cs08.rst
@@ -0,0 +1,37 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _v4l2-sdr-fmt-cs8:
+
+*************************
+V4L2_SDR_FMT_CS8 ('CS08')
+*************************
+
+Complex signed 8-bit IQ sample
+
+
+Description
+===========
+
+This format contains sequence of complex number samples. Each complex
+number consist two parts, called In-phase and Quadrature (IQ). Both I
+and Q are represented as a 8 bit signed number. I value comes first and
+Q value after that.
+
+**Byte Order.**
+Each cell is one byte.
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - start + 0:
+      - I'\ :sub:`0`
+    * - start + 1:
+      - Q'\ :sub:`0`
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-sdr-cs14le.rst b/Documentation/userspace-api/media/v4l/pixfmt-sdr-cs14le.rst
new file mode 100644
index 000000000000..41e5b990d499
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-sdr-cs14le.rst
@@ -0,0 +1,41 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-SDR-FMT-CS14LE:
+
+****************************
+V4L2_SDR_FMT_CS14LE ('CS14')
+****************************
+
+Complex signed 14-bit little endian IQ sample
+
+
+Description
+===========
+
+This format contains sequence of complex number samples. Each complex
+number consist two parts, called In-phase and Quadrature (IQ). Both I
+and Q are represented as a 14 bit signed little endian number. I value
+comes first and Q value after that. 14 bit value is stored in 16 bit
+space with unused high bits padded with 0.
+
+**Byte Order.**
+Each cell is one byte.
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - start + 0:
+      - I'\ :sub:`0[7:0]`
+      - I'\ :sub:`0[13:8]`
+    * - start + 2:
+      - Q'\ :sub:`0[7:0]`
+      - Q'\ :sub:`0[13:8]`
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-sdr-cu08.rst b/Documentation/userspace-api/media/v4l/pixfmt-sdr-cu08.rst
new file mode 100644
index 000000000000..1085b5ad8eb7
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-sdr-cu08.rst
@@ -0,0 +1,37 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _v4l2-sdr-fmt-cu8:
+
+*************************
+V4L2_SDR_FMT_CU8 ('CU08')
+*************************
+
+Complex unsigned 8-bit IQ sample
+
+
+Description
+===========
+
+This format contains sequence of complex number samples. Each complex
+number consist two parts, called In-phase and Quadrature (IQ). Both I
+and Q are represented as a 8 bit unsigned number. I value comes first
+and Q value after that.
+
+**Byte Order.**
+Each cell is one byte.
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - start + 0:
+      - I'\ :sub:`0`
+    * - start + 1:
+      - Q'\ :sub:`0`
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-sdr-cu16le.rst b/Documentation/userspace-api/media/v4l/pixfmt-sdr-cu16le.rst
new file mode 100644
index 000000000000..9772b30bda95
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-sdr-cu16le.rst
@@ -0,0 +1,41 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-SDR-FMT-CU16LE:
+
+****************************
+V4L2_SDR_FMT_CU16LE ('CU16')
+****************************
+
+
+Complex unsigned 16-bit little endian IQ sample
+
+
+Description
+===========
+
+This format contains sequence of complex number samples. Each complex
+number consist two parts, called In-phase and Quadrature (IQ). Both I
+and Q are represented as a 16 bit unsigned little endian number. I value
+comes first and Q value after that.
+
+**Byte Order.**
+Each cell is one byte.
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - start + 0:
+      - I'\ :sub:`0[7:0]`
+      - I'\ :sub:`0[15:8]`
+    * - start + 2:
+      - Q'\ :sub:`0[7:0]`
+      - Q'\ :sub:`0[15:8]`
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-sdr-pcu16be.rst b/Documentation/userspace-api/media/v4l/pixfmt-sdr-pcu16be.rst
new file mode 100644
index 000000000000..53a0a862f33a
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-sdr-pcu16be.rst
@@ -0,0 +1,62 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-SDR-FMT-PCU16BE:
+
+******************************
+V4L2_SDR_FMT_PCU16BE ('PC16')
+******************************
+
+Planar complex unsigned 16-bit big endian IQ sample
+
+Description
+===========
+
+This format contains a sequence of complex number samples. Each complex
+number consist of two parts called In-phase and Quadrature (IQ). Both I
+and Q are represented as a 16 bit unsigned big endian number stored in
+32 bit space. The remaining unused bits within the 32 bit space will be
+padded with 0. I value starts first and Q value starts at an offset
+equalling half of the buffer size (i.e.) offset = buffersize/2. Out of
+the 16 bits, bit 15:2 (14 bit) is data and bit 1:0 (2 bit) can be any
+value.
+
+**Byte Order.**
+Each cell is one byte.
+
+.. flat-table::
+    :header-rows:  1
+    :stub-columns: 0
+
+    * -  Offset:
+      -  Byte B0
+      -  Byte B1
+      -  Byte B2
+      -  Byte B3
+    * -  start + 0:
+      -  I'\ :sub:`0[13:6]`
+      -  I'\ :sub:`0[5:0]; B1[1:0]=pad`
+      -  pad
+      -  pad
+    * -  start + 4:
+      -  I'\ :sub:`1[13:6]`
+      -  I'\ :sub:`1[5:0]; B1[1:0]=pad`
+      -  pad
+      -  pad
+    * -  ...
+    * - start + offset:
+      -  Q'\ :sub:`0[13:6]`
+      -  Q'\ :sub:`0[5:0]; B1[1:0]=pad`
+      -  pad
+      -  pad
+    * - start + offset + 4:
+      -  Q'\ :sub:`1[13:6]`
+      -  Q'\ :sub:`1[5:0]; B1[1:0]=pad`
+      -  pad
+      -  pad
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-sdr-pcu18be.rst b/Documentation/userspace-api/media/v4l/pixfmt-sdr-pcu18be.rst
new file mode 100644
index 000000000000..7f2d2545fb04
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-sdr-pcu18be.rst
@@ -0,0 +1,62 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-SDR-FMT-PCU18BE:
+
+******************************
+V4L2_SDR_FMT_PCU18BE ('PC18')
+******************************
+
+Planar complex unsigned 18-bit big endian IQ sample
+
+Description
+===========
+
+This format contains a sequence of complex number samples. Each complex
+number consist of two parts called In-phase and Quadrature (IQ). Both I
+and Q are represented as a 18 bit unsigned big endian number stored in
+32 bit space. The remaining unused bits within the 32 bit space will be
+padded with 0. I value starts first and Q value starts at an offset
+equalling half of the buffer size (i.e.) offset = buffersize/2. Out of
+the 18 bits, bit 17:2 (16 bit) is data and bit 1:0 (2 bit) can be any
+value.
+
+**Byte Order.**
+Each cell is one byte.
+
+.. flat-table::
+    :header-rows:  1
+    :stub-columns: 0
+
+    * -  Offset:
+      -  Byte B0
+      -  Byte B1
+      -  Byte B2
+      -  Byte B3
+    * -  start + 0:
+      -  I'\ :sub:`0[17:10]`
+      -  I'\ :sub:`0[9:2]`
+      -  I'\ :sub:`0[1:0]; B2[5:0]=pad`
+      -  pad
+    * -  start + 4:
+      -  I'\ :sub:`1[17:10]`
+      -  I'\ :sub:`1[9:2]`
+      -  I'\ :sub:`1[1:0]; B2[5:0]=pad`
+      -  pad
+    * -  ...
+    * - start + offset:
+      -  Q'\ :sub:`0[17:10]`
+      -  Q'\ :sub:`0[9:2]`
+      -  Q'\ :sub:`0[1:0]; B2[5:0]=pad`
+      -  pad
+    * - start + offset + 4:
+      -  Q'\ :sub:`1[17:10]`
+      -  Q'\ :sub:`1[9:2]`
+      -  Q'\ :sub:`1[1:0]; B2[5:0]=pad`
+      -  pad
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-sdr-pcu20be.rst b/Documentation/userspace-api/media/v4l/pixfmt-sdr-pcu20be.rst
new file mode 100644
index 000000000000..9f3d67b4e94c
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-sdr-pcu20be.rst
@@ -0,0 +1,62 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-SDR-FMT-PCU20BE:
+
+******************************
+V4L2_SDR_FMT_PCU20BE ('PC20')
+******************************
+
+Planar complex unsigned 20-bit big endian IQ sample
+
+Description
+===========
+
+This format contains a sequence of complex number samples. Each complex
+number consist of two parts called In-phase and Quadrature (IQ). Both I
+and Q are represented as a 20 bit unsigned big endian number stored in
+32 bit space. The remaining unused bits within the 32 bit space will be
+padded with 0. I value starts first and Q value starts at an offset
+equalling half of the buffer size (i.e.) offset = buffersize/2. Out of
+the 20 bits, bit 19:2 (18 bit) is data and bit 1:0 (2 bit) can be any
+value.
+
+**Byte Order.**
+Each cell is one byte.
+
+.. flat-table::
+    :header-rows:  1
+    :stub-columns: 0
+
+    * -  Offset:
+      -  Byte B0
+      -  Byte B1
+      -  Byte B2
+      -  Byte B3
+    * -  start + 0:
+      -  I'\ :sub:`0[19:12]`
+      -  I'\ :sub:`0[11:4]`
+      -  I'\ :sub:`0[3:0]; B2[3:0]=pad`
+      -  pad
+    * -  start + 4:
+      -  I'\ :sub:`1[19:12]`
+      -  I'\ :sub:`1[11:4]`
+      -  I'\ :sub:`1[3:0]; B2[3:0]=pad`
+      -  pad
+    * -  ...
+    * - start + offset:
+      -  Q'\ :sub:`0[19:12]`
+      -  Q'\ :sub:`0[11:4]`
+      -  Q'\ :sub:`0[3:0]; B2[3:0]=pad`
+      -  pad
+    * - start + offset + 4:
+      -  Q'\ :sub:`1[19:12]`
+      -  Q'\ :sub:`1[11:4]`
+      -  Q'\ :sub:`1[3:0]; B2[3:0]=pad`
+      -  pad
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-sdr-ru12le.rst b/Documentation/userspace-api/media/v4l/pixfmt-sdr-ru12le.rst
new file mode 100644
index 000000000000..c9cde8d425f7
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-sdr-ru12le.rst
@@ -0,0 +1,39 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-SDR-FMT-RU12LE:
+
+****************************
+V4L2_SDR_FMT_RU12LE ('RU12')
+****************************
+
+
+Real unsigned 12-bit little endian sample
+
+
+Description
+===========
+
+This format contains sequence of real number samples. Each sample is
+represented as a 12 bit unsigned little endian number. Sample is stored
+in 16 bit space with unused high bits padded with 0.
+
+**Byte Order.**
+Each cell is one byte.
+
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - start + 0:
+      - I'\ :sub:`0[7:0]`
+      - I'\ :sub:`0[11:8]`
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-srggb10-ipu3.rst b/Documentation/userspace-api/media/v4l/pixfmt-srggb10-ipu3.rst
new file mode 100644
index 000000000000..5afa02a66698
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-srggb10-ipu3.rst
@@ -0,0 +1,342 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _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/userspace-api/media/v4l/pixfmt-srggb10.rst b/Documentation/userspace-api/media/v4l/pixfmt-srggb10.rst
new file mode 100644
index 000000000000..37cc1bb8241f
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-srggb10.rst
@@ -0,0 +1,83 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-SRGGB10:
+.. _v4l2-pix-fmt-sbggr10:
+.. _v4l2-pix-fmt-sgbrg10:
+.. _v4l2-pix-fmt-sgrbg10:
+
+***************************************************************************************************************************
+V4L2_PIX_FMT_SRGGB10 ('RG10'), V4L2_PIX_FMT_SGRBG10 ('BA10'), V4L2_PIX_FMT_SGBRG10 ('GB10'), V4L2_PIX_FMT_SBGGR10 ('BG10'),
+***************************************************************************************************************************
+
+
+V4L2_PIX_FMT_SGRBG10
+V4L2_PIX_FMT_SGBRG10
+V4L2_PIX_FMT_SBGGR10
+10-bit Bayer formats expanded to 16 bits
+
+
+Description
+===========
+
+These four pixel formats are raw sRGB / Bayer formats with 10 bits per
+sample. Each sample is stored in a 16-bit word, with 6 unused
+high bits filled with zeros. Each n-pixel row contains n/2 green samples and
+n/2 blue or red samples, with alternating red and blue rows. Bytes are
+stored in memory in little endian order. They are conventionally described
+as GRGR... BGBG..., RGRG... GBGB..., etc. Below is an example of one of
+these formats:
+
+**Byte Order.**
+Each cell is one byte, the 6 most significant bits in the high bytes
+are 0.
+
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - start + 0:
+      - B\ :sub:`00low`
+      - B\ :sub:`00high`
+      - G\ :sub:`01low`
+      - G\ :sub:`01high`
+      - B\ :sub:`02low`
+      - B\ :sub:`02high`
+      - G\ :sub:`03low`
+      - G\ :sub:`03high`
+    * - start + 8:
+      - G\ :sub:`10low`
+      - G\ :sub:`10high`
+      - R\ :sub:`11low`
+      - R\ :sub:`11high`
+      - G\ :sub:`12low`
+      - G\ :sub:`12high`
+      - R\ :sub:`13low`
+      - R\ :sub:`13high`
+    * - start + 16:
+      - B\ :sub:`20low`
+      - B\ :sub:`20high`
+      - G\ :sub:`21low`
+      - G\ :sub:`21high`
+      - B\ :sub:`22low`
+      - B\ :sub:`22high`
+      - G\ :sub:`23low`
+      - G\ :sub:`23high`
+    * - start + 24:
+      - G\ :sub:`30low`
+      - G\ :sub:`30high`
+      - R\ :sub:`31low`
+      - R\ :sub:`31high`
+      - G\ :sub:`32low`
+      - G\ :sub:`32high`
+      - R\ :sub:`33low`
+      - R\ :sub:`33high`
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-srggb10alaw8.rst b/Documentation/userspace-api/media/v4l/pixfmt-srggb10alaw8.rst
new file mode 100644
index 000000000000..f1b8627f0141
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-srggb10alaw8.rst
@@ -0,0 +1,31 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-SBGGR10ALAW8:
+.. _v4l2-pix-fmt-sgbrg10alaw8:
+.. _v4l2-pix-fmt-sgrbg10alaw8:
+.. _v4l2-pix-fmt-srggb10alaw8:
+
+***********************************************************************************************************************************************
+V4L2_PIX_FMT_SBGGR10ALAW8 ('aBA8'), V4L2_PIX_FMT_SGBRG10ALAW8 ('aGA8'), V4L2_PIX_FMT_SGRBG10ALAW8 ('agA8'), V4L2_PIX_FMT_SRGGB10ALAW8 ('aRA8'),
+***********************************************************************************************************************************************
+
+V4L2_PIX_FMT_SGBRG10ALAW8
+V4L2_PIX_FMT_SGRBG10ALAW8
+V4L2_PIX_FMT_SRGGB10ALAW8
+10-bit Bayer formats compressed to 8 bits
+
+
+Description
+===========
+
+These four pixel formats are raw sRGB / Bayer formats with 10 bits per
+color compressed to 8 bits each, using the A-LAW algorithm. Each color
+component consumes 8 bits of memory. In other respects this format is
+similar to :ref:`V4L2-PIX-FMT-SRGGB8`.
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-srggb10dpcm8.rst b/Documentation/userspace-api/media/v4l/pixfmt-srggb10dpcm8.rst
new file mode 100644
index 000000000000..9814c4ffac68
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-srggb10dpcm8.rst
@@ -0,0 +1,35 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-SBGGR10DPCM8:
+.. _v4l2-pix-fmt-sgbrg10dpcm8:
+.. _v4l2-pix-fmt-sgrbg10dpcm8:
+.. _v4l2-pix-fmt-srggb10dpcm8:
+
+
+***********************************************************************************************************************************************
+V4L2_PIX_FMT_SBGGR10DPCM8 ('bBA8'), V4L2_PIX_FMT_SGBRG10DPCM8 ('bGA8'), V4L2_PIX_FMT_SGRBG10DPCM8 ('BD10'), V4L2_PIX_FMT_SRGGB10DPCM8 ('bRA8'),
+***********************************************************************************************************************************************
+
+*man V4L2_PIX_FMT_SBGGR10DPCM8(2)*
+
+V4L2_PIX_FMT_SGBRG10DPCM8
+V4L2_PIX_FMT_SGRBG10DPCM8
+V4L2_PIX_FMT_SRGGB10DPCM8
+10-bit Bayer formats compressed to 8 bits
+
+
+Description
+===========
+
+These four pixel formats are raw sRGB / Bayer formats with 10 bits per
+colour compressed to 8 bits each, using DPCM compression. DPCM,
+differential pulse-code modulation, is lossy. Each colour component
+consumes 8 bits of memory. In other respects this format is similar to
+:ref:`V4L2-PIX-FMT-SRGGB10`.
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-srggb10p.rst b/Documentation/userspace-api/media/v4l/pixfmt-srggb10p.rst
new file mode 100644
index 000000000000..76a4d278e640
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-srggb10p.rst
@@ -0,0 +1,81 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-SRGGB10P:
+.. _v4l2-pix-fmt-sbggr10p:
+.. _v4l2-pix-fmt-sgbrg10p:
+.. _v4l2-pix-fmt-sgrbg10p:
+
+*******************************************************************************************************************************
+V4L2_PIX_FMT_SRGGB10P ('pRAA'), V4L2_PIX_FMT_SGRBG10P ('pgAA'), V4L2_PIX_FMT_SGBRG10P ('pGAA'), V4L2_PIX_FMT_SBGGR10P ('pBAA'),
+*******************************************************************************************************************************
+
+
+V4L2_PIX_FMT_SGRBG10P
+V4L2_PIX_FMT_SGBRG10P
+V4L2_PIX_FMT_SBGGR10P
+10-bit packed Bayer formats
+
+
+Description
+===========
+
+These four pixel formats are packed raw sRGB / Bayer formats with 10
+bits per sample. Every four consecutive samples are packed into 5
+bytes. Each of the first 4 bytes contain the 8 high order bits
+of the pixels, and the 5th byte contains the 2 least significants
+bits of each pixel, in the same order.
+
+Each n-pixel row contains n/2 green samples and n/2 blue or red samples,
+with alternating green-red and green-blue rows. They are conventionally
+described as GRGR... BGBG..., RGRG... GBGB..., etc. Below is an example
+of a small V4L2_PIX_FMT_SBGGR10P image:
+
+**Byte Order.**
+Each cell is one byte.
+
+.. tabularcolumns:: |p{2.4cm}|p{1.4cm}|p{1.2cm}|p{1.2cm}|p{1.2cm}|p{6.4cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths: 12 8 8 8 8 68
+
+    * - start + 0:
+      - B\ :sub:`00high`
+      - G\ :sub:`01high`
+      - B\ :sub:`02high`
+      - G\ :sub:`03high`
+      - G\ :sub:`03low`\ (bits 7--6) B\ :sub:`02low`\ (bits 5--4)
+
+	G\ :sub:`01low`\ (bits 3--2) B\ :sub:`00low`\ (bits 1--0)
+    * - start + 5:
+      - G\ :sub:`10high`
+      - R\ :sub:`11high`
+      - G\ :sub:`12high`
+      - R\ :sub:`13high`
+      - R\ :sub:`13low`\ (bits 7--6) G\ :sub:`12low`\ (bits 5--4)
+
+	R\ :sub:`11low`\ (bits 3--2) G\ :sub:`10low`\ (bits 1--0)
+    * - start + 10:
+      - B\ :sub:`20high`
+      - G\ :sub:`21high`
+      - B\ :sub:`22high`
+      - G\ :sub:`23high`
+      - G\ :sub:`23low`\ (bits 7--6) B\ :sub:`22low`\ (bits 5--4)
+
+	G\ :sub:`21low`\ (bits 3--2) B\ :sub:`20low`\ (bits 1--0)
+    * - start + 15:
+      - G\ :sub:`30high`
+      - R\ :sub:`31high`
+      - G\ :sub:`32high`
+      - R\ :sub:`33high`
+      - R\ :sub:`33low`\ (bits 7--6) G\ :sub:`32low`\ (bits 5--4)
+
+	R\ :sub:`31low`\ (bits 3--2) G\ :sub:`30low`\ (bits 1--0)
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-srggb12.rst b/Documentation/userspace-api/media/v4l/pixfmt-srggb12.rst
new file mode 100644
index 000000000000..98ae80b968ae
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-srggb12.rst
@@ -0,0 +1,84 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-SRGGB12:
+.. _v4l2-pix-fmt-sbggr12:
+.. _v4l2-pix-fmt-sgbrg12:
+.. _v4l2-pix-fmt-sgrbg12:
+
+
+***************************************************************************************************************************
+V4L2_PIX_FMT_SRGGB12 ('RG12'), V4L2_PIX_FMT_SGRBG12 ('BA12'), V4L2_PIX_FMT_SGBRG12 ('GB12'), V4L2_PIX_FMT_SBGGR12 ('BG12'),
+***************************************************************************************************************************
+
+
+V4L2_PIX_FMT_SGRBG12
+V4L2_PIX_FMT_SGBRG12
+V4L2_PIX_FMT_SBGGR12
+12-bit Bayer formats expanded to 16 bits
+
+
+Description
+===========
+
+These four pixel formats are raw sRGB / Bayer formats with 12 bits per
+colour. Each colour component is stored in a 16-bit word, with 4 unused
+high bits filled with zeros. Each n-pixel row contains n/2 green samples
+and n/2 blue or red samples, with alternating red and blue rows. Bytes
+are stored in memory in little endian order. They are conventionally
+described as GRGR... BGBG..., RGRG... GBGB..., etc. Below is an example
+of a small V4L2_PIX_FMT_SBGGR12 image:
+
+**Byte Order.**
+Each cell is one byte, the 4 most significant bits in the high bytes are
+0.
+
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - start + 0:
+      - B\ :sub:`00low`
+      - B\ :sub:`00high`
+      - G\ :sub:`01low`
+      - G\ :sub:`01high`
+      - B\ :sub:`02low`
+      - B\ :sub:`02high`
+      - G\ :sub:`03low`
+      - G\ :sub:`03high`
+    * - start + 8:
+      - G\ :sub:`10low`
+      - G\ :sub:`10high`
+      - R\ :sub:`11low`
+      - R\ :sub:`11high`
+      - G\ :sub:`12low`
+      - G\ :sub:`12high`
+      - R\ :sub:`13low`
+      - R\ :sub:`13high`
+    * - start + 16:
+      - B\ :sub:`20low`
+      - B\ :sub:`20high`
+      - G\ :sub:`21low`
+      - G\ :sub:`21high`
+      - B\ :sub:`22low`
+      - B\ :sub:`22high`
+      - G\ :sub:`23low`
+      - G\ :sub:`23high`
+    * - start + 24:
+      - G\ :sub:`30low`
+      - G\ :sub:`30high`
+      - R\ :sub:`31low`
+      - R\ :sub:`31high`
+      - G\ :sub:`32low`
+      - G\ :sub:`32high`
+      - R\ :sub:`33low`
+      - R\ :sub:`33high`
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-srggb12p.rst b/Documentation/userspace-api/media/v4l/pixfmt-srggb12p.rst
new file mode 100644
index 000000000000..7309dd7fa60f
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-srggb12p.rst
@@ -0,0 +1,94 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-SRGGB12P:
+.. _v4l2-pix-fmt-sbggr12p:
+.. _v4l2-pix-fmt-sgbrg12p:
+.. _v4l2-pix-fmt-sgrbg12p:
+
+*******************************************************************************************************************************
+V4L2_PIX_FMT_SRGGB12P ('pRCC'), V4L2_PIX_FMT_SGRBG12P ('pgCC'), V4L2_PIX_FMT_SGBRG12P ('pGCC'), V4L2_PIX_FMT_SBGGR12P ('pBCC'),
+*******************************************************************************************************************************
+
+
+12-bit packed Bayer formats
+---------------------------
+
+
+Description
+===========
+
+These four pixel formats are packed raw sRGB / Bayer formats with 12
+bits per colour. Every two consecutive samples are packed into three
+bytes. Each of the first two bytes contain the 8 high order bits of
+the pixels, and the third byte contains the four least significants
+bits of each pixel, in the same order.
+
+Each n-pixel row contains n/2 green samples and n/2 blue or red
+samples, with alternating green-red and green-blue rows. They are
+conventionally described as GRGR... BGBG..., RGRG... GBGB..., etc.
+Below is an example of a small V4L2_PIX_FMT_SBGGR12P image:
+
+**Byte Order.**
+Each cell is one byte.
+
+.. tabularcolumns:: |p{2.2cm}|p{1.2cm}|p{1.2cm}|p{3.1cm}|p{1.2cm}|p{1.2cm}|p{3.1cm}|
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       2 1 1 1 1 1 1
+
+
+    -  -  start + 0:
+       -  B\ :sub:`00high`
+       -  G\ :sub:`01high`
+       -  G\ :sub:`01low`\ (bits 7--4)
+
+          B\ :sub:`00low`\ (bits 3--0)
+       -  B\ :sub:`02high`
+       -  G\ :sub:`03high`
+       -  G\ :sub:`03low`\ (bits 7--4)
+
+          B\ :sub:`02low`\ (bits 3--0)
+
+    -  -  start + 6:
+       -  G\ :sub:`10high`
+       -  R\ :sub:`11high`
+       -  R\ :sub:`11low`\ (bits 7--4)
+
+          G\ :sub:`10low`\ (bits 3--0)
+       -  G\ :sub:`12high`
+       -  R\ :sub:`13high`
+       -  R\ :sub:`13low`\ (bits 3--2)
+
+          G\ :sub:`12low`\ (bits 3--0)
+    -  -  start + 12:
+       -  B\ :sub:`20high`
+       -  G\ :sub:`21high`
+       -  G\ :sub:`21low`\ (bits 7--4)
+
+          B\ :sub:`20low`\ (bits 3--0)
+       -  B\ :sub:`22high`
+       -  G\ :sub:`23high`
+       -  G\ :sub:`23low`\ (bits 7--4)
+
+          B\ :sub:`22low`\ (bits 3--0)
+    -  -  start + 18:
+       -  G\ :sub:`30high`
+       -  R\ :sub:`31high`
+       -  R\ :sub:`31low`\ (bits 7--4)
+
+          G\ :sub:`30low`\ (bits 3--0)
+       -  G\ :sub:`32high`
+       -  R\ :sub:`33high`
+       -  R\ :sub:`33low`\ (bits 3--2)
+
+          G\ :sub:`32low`\ (bits 3--0)
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-srggb14.rst b/Documentation/userspace-api/media/v4l/pixfmt-srggb14.rst
new file mode 100644
index 000000000000..a4c7a392fe7f
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-srggb14.rst
@@ -0,0 +1,82 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-SRGGB14:
+.. _v4l2-pix-fmt-sbggr14:
+.. _v4l2-pix-fmt-sgbrg14:
+.. _v4l2-pix-fmt-sgrbg14:
+
+
+***************************************************************************************************************************
+V4L2_PIX_FMT_SRGGB14 ('RG14'), V4L2_PIX_FMT_SGRBG14 ('GR14'), V4L2_PIX_FMT_SGBRG14 ('GB14'), V4L2_PIX_FMT_SBGGR14 ('BG14'),
+***************************************************************************************************************************
+
+
+14-bit Bayer formats expanded to 16 bits
+
+
+Description
+===========
+
+These four pixel formats are raw sRGB / Bayer formats with 14 bits per
+colour. Each sample is stored in a 16-bit word, with two unused high
+bits filled with zeros. Each n-pixel row contains n/2 green samples
+and n/2 blue or red samples, with alternating red and blue rows. Bytes
+are stored in memory in little endian order. They are conventionally
+described as GRGR... BGBG..., RGRG... GBGB..., etc. Below is an
+example of a small V4L2_PIX_FMT_SBGGR14 image:
+
+**Byte Order.**
+Each cell is one byte, the two most significant bits in the high bytes are
+zero.
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       2 1 1 1 1 1 1 1 1
+
+
+    * - start + 0:
+      - B\ :sub:`00low`
+      - B\ :sub:`00high`
+      - G\ :sub:`01low`
+      - G\ :sub:`01high`
+      - B\ :sub:`02low`
+      - B\ :sub:`02high`
+      - G\ :sub:`03low`
+      - G\ :sub:`03high`
+    * - start + 8:
+      - G\ :sub:`10low`
+      - G\ :sub:`10high`
+      - R\ :sub:`11low`
+      - R\ :sub:`11high`
+      - G\ :sub:`12low`
+      - G\ :sub:`12high`
+      - R\ :sub:`13low`
+      - R\ :sub:`13high`
+    * - start + 16:
+      - B\ :sub:`20low`
+      - B\ :sub:`20high`
+      - G\ :sub:`21low`
+      - G\ :sub:`21high`
+      - B\ :sub:`22low`
+      - B\ :sub:`22high`
+      - G\ :sub:`23low`
+      - G\ :sub:`23high`
+    * - start + 24:
+      - G\ :sub:`30low`
+      - G\ :sub:`30high`
+      - R\ :sub:`31low`
+      - R\ :sub:`31high`
+      - G\ :sub:`32low`
+      - G\ :sub:`32high`
+      - R\ :sub:`33low`
+      - R\ :sub:`33high`
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-srggb14p.rst b/Documentation/userspace-api/media/v4l/pixfmt-srggb14p.rst
new file mode 100644
index 000000000000..ec1239ada316
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-srggb14p.rst
@@ -0,0 +1,152 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-SRGGB14P:
+.. _v4l2-pix-fmt-sbggr14p:
+.. _v4l2-pix-fmt-sgbrg14p:
+.. _v4l2-pix-fmt-sgrbg14p:
+
+*******************************************************************************************************************************
+V4L2_PIX_FMT_SRGGB14P ('pREE'), V4L2_PIX_FMT_SGRBG14P ('pgEE'), V4L2_PIX_FMT_SGBRG14P ('pGEE'), V4L2_PIX_FMT_SBGGR14P ('pBEE'),
+*******************************************************************************************************************************
+
+*man V4L2_PIX_FMT_SRGGB14P(2)*
+
+V4L2_PIX_FMT_SGRBG14P
+V4L2_PIX_FMT_SGBRG14P
+V4L2_PIX_FMT_SBGGR14P
+14-bit packed Bayer formats
+
+
+Description
+===========
+
+These four pixel formats are packed raw sRGB / Bayer formats with 14
+bits per colour. Every four consecutive samples are packed into seven
+bytes. Each of the first four bytes contain the eight high order bits
+of the pixels, and the three following bytes contains the six least
+significants bits of each pixel, in the same order.
+
+Each n-pixel row contains n/2 green samples and n/2 blue or red samples,
+with alternating green-red and green-blue rows. They are conventionally
+described as GRGR... BGBG..., RGRG... GBGB..., etc. Below is an example
+of one of these formats:
+
+**Byte Order.**
+Each cell is one byte.
+
+.. raw:: latex
+
+    \footnotesize
+
+.. tabularcolumns:: |p{1.8cm}|p{1.0cm}|p{1.0cm}|p{1.0cm}|p{1.1cm}|p{3.3cm}|p{3.3cm}|p{3.3cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       2 1 1 1 1 3 3 3
+
+
+    -  .. row 1
+
+       -  start + 0
+
+       -  B\ :sub:`00high`
+
+       -  G\ :sub:`01high`
+
+       -  B\ :sub:`02high`
+
+       -  G\ :sub:`03high`
+
+       -  G\ :sub:`01low bits 1--0`\ (bits 7--6)
+
+	  B\ :sub:`00low bits 5--0`\ (bits 5--0)
+
+       -  R\ :sub:`02low bits 3--0`\ (bits 7--4)
+
+	  G\ :sub:`01low bits 5--2`\ (bits 3--0)
+
+       -  G\ :sub:`03low bits 5--0`\ (bits 7--2)
+
+	  R\ :sub:`02low bits 5--4`\ (bits 1--0)
+
+    -  .. row 2
+
+       -  start + 7
+
+       -  G\ :sub:`00high`
+
+       -  R\ :sub:`01high`
+
+       -  G\ :sub:`02high`
+
+       -  R\ :sub:`03high`
+
+       -  R\ :sub:`01low bits 1--0`\ (bits 7--6)
+
+	  G\ :sub:`00low bits 5--0`\ (bits 5--0)
+
+       -  G\ :sub:`02low bits 3--0`\ (bits 7--4)
+
+	  R\ :sub:`01low bits 5--2`\ (bits 3--0)
+
+       -  R\ :sub:`03low bits 5--0`\ (bits 7--2)
+
+	  G\ :sub:`02low bits 5--4`\ (bits 1--0)
+
+    -  .. row 3
+
+       -  start + 14
+
+       -  B\ :sub:`20high`
+
+       -  G\ :sub:`21high`
+
+       -  B\ :sub:`22high`
+
+       -  G\ :sub:`23high`
+
+       -  G\ :sub:`21low bits 1--0`\ (bits 7--6)
+
+	  B\ :sub:`20low bits 5--0`\ (bits 5--0)
+
+       -  R\ :sub:`22low bits 3--0`\ (bits 7--4)
+
+	  G\ :sub:`21low bits 5--2`\ (bits 3--0)
+
+       -  G\ :sub:`23low bits 5--0`\ (bits 7--2)
+
+	  R\ :sub:`22low bits 5--4`\ (bits 1--0)
+
+    -  .. row 4
+
+       -  start + 21
+
+       -  G\ :sub:`30high`
+
+       -  R\ :sub:`31high`
+
+       -  G\ :sub:`32high`
+
+       -  R\ :sub:`33high`
+
+       -  R\ :sub:`31low bits 1--0`\ (bits 7--6)
+	  G\ :sub:`30low bits 5--0`\ (bits 5--0)
+
+       -  G\ :sub:`32low bits 3--0`\ (bits 7--4)
+	  R\ :sub:`31low bits 5--2`\ (bits 3--0)
+
+       -  R\ :sub:`33low bits 5--0`\ (bits 7--2)
+	  G\ :sub:`32low bits 5--4`\ (bits 1--0)
+
+.. raw:: latex
+
+    \normalsize
+
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-srggb16.rst b/Documentation/userspace-api/media/v4l/pixfmt-srggb16.rst
new file mode 100644
index 000000000000..885f0d1f331d
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-srggb16.rst
@@ -0,0 +1,76 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-SRGGB16:
+.. _v4l2-pix-fmt-sbggr16:
+.. _v4l2-pix-fmt-sgbrg16:
+.. _v4l2-pix-fmt-sgrbg16:
+
+
+***************************************************************************************************************************
+V4L2_PIX_FMT_SRGGB16 ('RG16'), V4L2_PIX_FMT_SGRBG16 ('GR16'), V4L2_PIX_FMT_SGBRG16 ('GB16'), V4L2_PIX_FMT_SBGGR16 ('BYR2'),
+***************************************************************************************************************************
+
+
+16-bit Bayer formats
+
+
+Description
+===========
+
+These four pixel formats are raw sRGB / Bayer formats with 16 bits per
+sample. Each sample is stored in a 16-bit word. Each n-pixel row contains
+n/2 green samples and n/2 blue or red samples, with alternating red and blue
+rows. Bytes are stored in memory in little endian order. They are
+conventionally described as GRGR... BGBG..., RGRG... GBGB..., etc. Below is
+an example of a small V4L2_PIX_FMT_SBGGR16 image:
+
+**Byte Order.**
+Each cell is one byte.
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - start + 0:
+      - B\ :sub:`00low`
+      - B\ :sub:`00high`
+      - G\ :sub:`01low`
+      - G\ :sub:`01high`
+      - B\ :sub:`02low`
+      - B\ :sub:`02high`
+      - G\ :sub:`03low`
+      - G\ :sub:`03high`
+    * - start + 8:
+      - G\ :sub:`10low`
+      - G\ :sub:`10high`
+      - R\ :sub:`11low`
+      - R\ :sub:`11high`
+      - G\ :sub:`12low`
+      - G\ :sub:`12high`
+      - R\ :sub:`13low`
+      - R\ :sub:`13high`
+    * - start + 16:
+      - B\ :sub:`20low`
+      - B\ :sub:`20high`
+      - G\ :sub:`21low`
+      - G\ :sub:`21high`
+      - B\ :sub:`22low`
+      - B\ :sub:`22high`
+      - G\ :sub:`23low`
+      - G\ :sub:`23high`
+    * - start + 24:
+      - G\ :sub:`30low`
+      - G\ :sub:`30high`
+      - R\ :sub:`31low`
+      - R\ :sub:`31high`
+      - G\ :sub:`32low`
+      - G\ :sub:`32high`
+      - R\ :sub:`33low`
+      - R\ :sub:`33high`
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-srggb8.rst b/Documentation/userspace-api/media/v4l/pixfmt-srggb8.rst
new file mode 100644
index 000000000000..c275e6ef09f9
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-srggb8.rst
@@ -0,0 +1,61 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-SRGGB8:
+.. _v4l2-pix-fmt-sbggr8:
+.. _v4l2-pix-fmt-sgbrg8:
+.. _v4l2-pix-fmt-sgrbg8:
+
+***************************************************************************************************************************
+V4L2_PIX_FMT_SRGGB8 ('RGGB'), V4L2_PIX_FMT_SGRBG8 ('GRBG'), V4L2_PIX_FMT_SGBRG8 ('GBRG'), V4L2_PIX_FMT_SBGGR8 ('BA81'),
+***************************************************************************************************************************
+
+
+8-bit Bayer formats
+
+
+Description
+===========
+
+These four pixel formats are raw sRGB / Bayer formats with 8 bits per
+sample. Each sample is stored in a byte. Each n-pixel row contains n/2
+green samples and n/2 blue or red samples, with alternating red and
+blue rows. They are conventionally described as GRGR... BGBG...,
+RGRG... GBGB..., etc. Below is an example of a small V4L2_PIX_FMT_SBGGR8 image:
+
+**Byte Order.**
+Each cell is one byte.
+
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - start + 0:
+      - B\ :sub:`00`
+      - G\ :sub:`01`
+      - B\ :sub:`02`
+      - G\ :sub:`03`
+    * - start + 4:
+      - G\ :sub:`10`
+      - R\ :sub:`11`
+      - G\ :sub:`12`
+      - R\ :sub:`13`
+    * - start + 8:
+      - B\ :sub:`20`
+      - G\ :sub:`21`
+      - B\ :sub:`22`
+      - G\ :sub:`23`
+    * - start + 12:
+      - G\ :sub:`30`
+      - R\ :sub:`31`
+      - G\ :sub:`32`
+      - R\ :sub:`33`
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-tch-td08.rst b/Documentation/userspace-api/media/v4l/pixfmt-tch-td08.rst
new file mode 100644
index 000000000000..165c9be2bfc5
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-tch-td08.rst
@@ -0,0 +1,59 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-TCH-FMT-DELTA-TD08:
+
+********************************
+V4L2_TCH_FMT_DELTA_TD08 ('TD08')
+********************************
+
+*man V4L2_TCH_FMT_DELTA_TD08(2)*
+
+8-bit signed Touch Delta
+
+Description
+===========
+
+This format represents delta data from a touch controller.
+
+Delta values may range from -128 to 127. Typically the values will vary through
+a small range depending on whether the sensor is touched or not. The full value
+may be seen if one of the touchscreen nodes has a fault or the line is not
+connected.
+
+**Byte Order.**
+Each cell is one byte.
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       2 1 1 1 1
+
+    * - start + 0:
+      - D'\ :sub:`00`
+      - D'\ :sub:`01`
+      - D'\ :sub:`02`
+      - D'\ :sub:`03`
+    * - start + 4:
+      - D'\ :sub:`10`
+      - D'\ :sub:`11`
+      - D'\ :sub:`12`
+      - D'\ :sub:`13`
+    * - start + 8:
+      - D'\ :sub:`20`
+      - D'\ :sub:`21`
+      - D'\ :sub:`22`
+      - D'\ :sub:`23`
+    * - start + 12:
+      - D'\ :sub:`30`
+      - D'\ :sub:`31`
+      - D'\ :sub:`32`
+      - D'\ :sub:`33`
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-tch-td16.rst b/Documentation/userspace-api/media/v4l/pixfmt-tch-td16.rst
new file mode 100644
index 000000000000..6dca01182175
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-tch-td16.rst
@@ -0,0 +1,74 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-TCH-FMT-DELTA-TD16:
+
+********************************
+V4L2_TCH_FMT_DELTA_TD16 ('TD16')
+********************************
+
+*man V4L2_TCH_FMT_DELTA_TD16(2)*
+
+16-bit signed little endian Touch Delta
+
+
+Description
+===========
+
+This format represents delta data from a touch controller.
+
+Delta values may range from -32768 to 32767. Typically the values will vary
+through a small range depending on whether the sensor is touched or not. The
+full value may be seen if one of the touchscreen nodes has a fault or the line
+is not connected.
+
+**Byte Order.**
+Each cell is one byte.
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       2 1 1 1 1 1 1 1 1
+
+    * - start + 0:
+      - D'\ :sub:`00low`
+      - D'\ :sub:`00high`
+      - D'\ :sub:`01low`
+      - D'\ :sub:`01high`
+      - D'\ :sub:`02low`
+      - D'\ :sub:`02high`
+      - D'\ :sub:`03low`
+      - D'\ :sub:`03high`
+    * - start + 8:
+      - D'\ :sub:`10low`
+      - D'\ :sub:`10high`
+      - D'\ :sub:`11low`
+      - D'\ :sub:`11high`
+      - D'\ :sub:`12low`
+      - D'\ :sub:`12high`
+      - D'\ :sub:`13low`
+      - D'\ :sub:`13high`
+    * - start + 16:
+      - D'\ :sub:`20low`
+      - D'\ :sub:`20high`
+      - D'\ :sub:`21low`
+      - D'\ :sub:`21high`
+      - D'\ :sub:`22low`
+      - D'\ :sub:`22high`
+      - D'\ :sub:`23low`
+      - D'\ :sub:`23high`
+    * - start + 24:
+      - D'\ :sub:`30low`
+      - D'\ :sub:`30high`
+      - D'\ :sub:`31low`
+      - D'\ :sub:`31high`
+      - D'\ :sub:`32low`
+      - D'\ :sub:`32high`
+      - D'\ :sub:`33low`
+      - D'\ :sub:`33high`
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-tch-tu08.rst b/Documentation/userspace-api/media/v4l/pixfmt-tch-tu08.rst
new file mode 100644
index 000000000000..f1380b72977f
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-tch-tu08.rst
@@ -0,0 +1,57 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-TCH-FMT-TU08:
+
+**************************
+V4L2_TCH_FMT_TU08 ('TU08')
+**************************
+
+*man V4L2_TCH_FMT_TU08(2)*
+
+8-bit unsigned raw touch data
+
+Description
+===========
+
+This format represents unsigned 8-bit data from a touch controller.
+
+This may be used for output for raw and reference data. Values may range from
+0 to 255.
+
+**Byte Order.**
+Each cell is one byte.
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       2 1 1 1 1
+
+    * - start + 0:
+      - R'\ :sub:`00`
+      - R'\ :sub:`01`
+      - R'\ :sub:`02`
+      - R'\ :sub:`03`
+    * - start + 4:
+      - R'\ :sub:`10`
+      - R'\ :sub:`11`
+      - R'\ :sub:`12`
+      - R'\ :sub:`13`
+    * - start + 8:
+      - R'\ :sub:`20`
+      - R'\ :sub:`21`
+      - R'\ :sub:`22`
+      - R'\ :sub:`23`
+    * - start + 12:
+      - R'\ :sub:`30`
+      - R'\ :sub:`31`
+      - R'\ :sub:`32`
+      - R'\ :sub:`33`
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-tch-tu16.rst b/Documentation/userspace-api/media/v4l/pixfmt-tch-tu16.rst
new file mode 100644
index 000000000000..2b9e1b15abcf
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-tch-tu16.rst
@@ -0,0 +1,73 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-TCH-FMT-TU16:
+
+********************************
+V4L2_TCH_FMT_TU16 ('TU16')
+********************************
+
+*man V4L2_TCH_FMT_TU16(2)*
+
+16-bit unsigned little endian raw touch data
+
+
+Description
+===========
+
+This format represents unsigned 16-bit data from a touch controller.
+
+This may be used for output for raw and reference data. Values may range from
+0 to 65535.
+
+**Byte Order.**
+Each cell is one byte.
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       2 1 1 1 1 1 1 1 1
+
+    * - start + 0:
+      - R'\ :sub:`00low`
+      - R'\ :sub:`00high`
+      - R'\ :sub:`01low`
+      - R'\ :sub:`01high`
+      - R'\ :sub:`02low`
+      - R'\ :sub:`02high`
+      - R'\ :sub:`03low`
+      - R'\ :sub:`03high`
+    * - start + 8:
+      - R'\ :sub:`10low`
+      - R'\ :sub:`10high`
+      - R'\ :sub:`11low`
+      - R'\ :sub:`11high`
+      - R'\ :sub:`12low`
+      - R'\ :sub:`12high`
+      - R'\ :sub:`13low`
+      - R'\ :sub:`13high`
+    * - start + 16:
+      - R'\ :sub:`20low`
+      - R'\ :sub:`20high`
+      - R'\ :sub:`21low`
+      - R'\ :sub:`21high`
+      - R'\ :sub:`22low`
+      - R'\ :sub:`22high`
+      - R'\ :sub:`23low`
+      - R'\ :sub:`23high`
+    * - start + 24:
+      - R'\ :sub:`30low`
+      - R'\ :sub:`30high`
+      - R'\ :sub:`31low`
+      - R'\ :sub:`31high`
+      - R'\ :sub:`32low`
+      - R'\ :sub:`32high`
+      - R'\ :sub:`33low`
+      - R'\ :sub:`33high`
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-uv8.rst b/Documentation/userspace-api/media/v4l/pixfmt-uv8.rst
new file mode 100644
index 000000000000..a36c1a4d64a4
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-uv8.rst
@@ -0,0 +1,54 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-UV8:
+
+************************
+V4L2_PIX_FMT_UV8 ('UV8')
+************************
+
+
+UV plane interleaved
+
+
+Description
+===========
+
+In this format there is no Y plane, Only CbCr plane. ie (UV interleaved)
+
+**Byte Order.**
+Each cell is one byte.
+
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - start + 0:
+      - Cb\ :sub:`00`
+      - Cr\ :sub:`00`
+      - Cb\ :sub:`01`
+      - Cr\ :sub:`01`
+    * - start + 4:
+      - Cb\ :sub:`10`
+      - Cr\ :sub:`10`
+      - Cb\ :sub:`11`
+      - Cr\ :sub:`11`
+    * - start + 8:
+      - Cb\ :sub:`20`
+      - Cr\ :sub:`20`
+      - Cb\ :sub:`21`
+      - Cr\ :sub:`21`
+    * - start + 12:
+      - Cb\ :sub:`30`
+      - Cr\ :sub:`30`
+      - Cb\ :sub:`31`
+      - Cr\ :sub:`31`
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-uyvy.rst b/Documentation/userspace-api/media/v4l/pixfmt-uyvy.rst
new file mode 100644
index 000000000000..776cb37f76f1
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-uyvy.rst
@@ -0,0 +1,117 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-UYVY:
+
+**************************
+V4L2_PIX_FMT_UYVY ('UYVY')
+**************************
+
+
+Variation of ``V4L2_PIX_FMT_YUYV`` with different order of samples in
+memory
+
+
+Description
+===========
+
+In this format each four bytes is two pixels. Each four bytes is two
+Y's, a Cb and a Cr. Each Y goes to one of the pixels, and the Cb and Cr
+belong to both pixels. As you can see, the Cr and Cb components have
+half the horizontal resolution of the Y component.
+
+**Byte Order.**
+Each cell is one byte.
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - start + 0:
+      - Cb\ :sub:`00`
+      - Y'\ :sub:`00`
+      - Cr\ :sub:`00`
+      - Y'\ :sub:`01`
+      - Cb\ :sub:`01`
+      - Y'\ :sub:`02`
+      - Cr\ :sub:`01`
+      - Y'\ :sub:`03`
+    * - start + 8:
+      - Cb\ :sub:`10`
+      - Y'\ :sub:`10`
+      - Cr\ :sub:`10`
+      - Y'\ :sub:`11`
+      - Cb\ :sub:`11`
+      - Y'\ :sub:`12`
+      - Cr\ :sub:`11`
+      - Y'\ :sub:`13`
+    * - start + 16:
+      - Cb\ :sub:`20`
+      - Y'\ :sub:`20`
+      - Cr\ :sub:`20`
+      - Y'\ :sub:`21`
+      - Cb\ :sub:`21`
+      - Y'\ :sub:`22`
+      - Cr\ :sub:`21`
+      - Y'\ :sub:`23`
+    * - start + 24:
+      - Cb\ :sub:`30`
+      - Y'\ :sub:`30`
+      - Cr\ :sub:`30`
+      - Y'\ :sub:`31`
+      - Cb\ :sub:`31`
+      - Y'\ :sub:`32`
+      - Cr\ :sub:`31`
+      - Y'\ :sub:`33`
+
+
+**Color Sample Location:**
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * -
+      - 0
+      -
+      - 1
+      - 2
+      -
+      - 3
+    * - 0
+      - Y
+      - C
+      - Y
+      - Y
+      - C
+      - Y
+    * - 1
+      - Y
+      - C
+      - Y
+      - Y
+      - C
+      - Y
+    * - 2
+      - Y
+      - C
+      - Y
+      - Y
+      - C
+      - Y
+    * - 3
+      - Y
+      - C
+      - Y
+      - Y
+      - C
+      - Y
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-v4l2-mplane.rst b/Documentation/userspace-api/media/v4l/pixfmt-v4l2-mplane.rst
new file mode 100644
index 000000000000..444b4082684c
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-v4l2-mplane.rst
@@ -0,0 +1,138 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+******************************
+Multi-planar format structures
+******************************
+
+The struct :c:type:`v4l2_plane_pix_format` structures define size
+and layout for each of the planes in a multi-planar format. The
+struct :c:type:`v4l2_pix_format_mplane` structure contains
+information common to all planes (such as image width and height) and an
+array of struct :c:type:`v4l2_plane_pix_format` structures,
+describing all planes of that format.
+
+
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. c:type:: v4l2_plane_pix_format
+
+.. flat-table:: struct v4l2_plane_pix_format
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``sizeimage``
+      - Maximum size in bytes required for image data in this plane,
+	set by the driver. When the image consists of variable length
+	compressed data this is the number of bytes required by the
+	codec to support the worst-case compression scenario.
+
+	The driver will set the value for uncompressed images.
+
+	Clients are allowed to set the sizeimage field for variable length
+	compressed data flagged with ``V4L2_FMT_FLAG_COMPRESSED`` at
+	:ref:`VIDIOC_ENUM_FMT`, but the driver may ignore it and set the
+	value itself, or it may modify the provided value based on
+	alignment requirements or minimum/maximum size requirements.
+	If the client wants to leave this to the driver, then it should
+	set sizeimage to 0.
+    * - __u32
+      - ``bytesperline``
+      - Distance in bytes between the leftmost pixels in two adjacent
+	lines. See struct :c:type:`v4l2_pix_format`.
+    * - __u16
+      - ``reserved[6]``
+      - Reserved for future extensions. Should be zeroed by drivers and
+	applications.
+
+
+.. raw:: latex
+
+    \small
+
+.. tabularcolumns:: |p{4.4cm}|p{5.6cm}|p{7.5cm}|
+
+.. c:type:: v4l2_pix_format_mplane
+
+.. flat-table:: struct v4l2_pix_format_mplane
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``width``
+      - Image width in pixels. See struct
+	:c:type:`v4l2_pix_format`.
+    * - __u32
+      - ``height``
+      - Image height in pixels. See struct
+	:c:type:`v4l2_pix_format`.
+    * - __u32
+      - ``pixelformat``
+      - The pixel format. Both single- and multi-planar four character
+	codes can be used.
+    * - __u32
+      - ``field``
+      - Field order, from enum :c:type:`v4l2_field`.
+        See struct :c:type:`v4l2_pix_format`.
+    * - __u32
+      - ``colorspace``
+      - Colorspace encoding, from enum :c:type:`v4l2_colorspace`.
+        See struct :c:type:`v4l2_pix_format`.
+    * - struct :c:type:`v4l2_plane_pix_format`
+      - ``plane_fmt[VIDEO_MAX_PLANES]``
+      - An array of structures describing format of each plane this pixel
+	format consists of. The number of valid entries in this array has
+	to be put in the ``num_planes`` field.
+    * - __u8
+      - ``num_planes``
+      - Number of planes (i.e. separate memory buffers) for this format
+	and the number of valid entries in the ``plane_fmt`` array.
+    * - __u8
+      - ``flags``
+      - Flags set by the application or driver, see :ref:`format-flags`.
+    * - union {
+      - (anonymous)
+    * - __u8
+      - ``ycbcr_enc``
+      - Y'CbCr encoding, from enum :c:type:`v4l2_ycbcr_encoding`.
+        This information supplements the ``colorspace`` and must be set by
+	the driver for capture streams and by the application for output
+	streams, see :ref:`colorspaces`.
+    * - __u8
+      - ``hsv_enc``
+      - HSV encoding, from enum :c:type:`v4l2_hsv_encoding`.
+        This information supplements the ``colorspace`` and must be set by
+	the driver for capture streams and by the application for output
+	streams, see :ref:`colorspaces`.
+    * - }
+      -
+    * - __u8
+      - ``quantization``
+      - Quantization range, from enum :c:type:`v4l2_quantization`.
+        This information supplements the ``colorspace`` and must be set by
+	the driver for capture streams and by the application for output
+	streams, see :ref:`colorspaces`.
+    * - __u8
+      - ``xfer_func``
+      - Transfer function, from enum :c:type:`v4l2_xfer_func`.
+        This information supplements the ``colorspace`` and must be set by
+	the driver for capture streams and by the application for output
+	streams, see :ref:`colorspaces`.
+    * - __u8
+      - ``reserved[7]``
+      - Reserved for future extensions. Should be zeroed by drivers and
+	applications.
+
+.. raw:: latex
+
+    \normalsize
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-v4l2.rst b/Documentation/userspace-api/media/v4l/pixfmt-v4l2.rst
new file mode 100644
index 000000000000..759420a872d6
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-v4l2.rst
@@ -0,0 +1,171 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+******************************
+Single-planar format structure
+******************************
+
+.. tabularcolumns:: |p{4.0cm}|p{2.5cm}|p{11.0cm}|
+
+.. c:type:: v4l2_pix_format
+
+.. cssclass:: longtable
+
+.. flat-table:: struct v4l2_pix_format
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``width``
+      - Image width in pixels.
+    * - __u32
+      - ``height``
+      - Image height in pixels. If ``field`` is one of ``V4L2_FIELD_TOP``,
+	``V4L2_FIELD_BOTTOM`` or ``V4L2_FIELD_ALTERNATE`` then height
+	refers to the number of lines in the field, otherwise it refers to
+	the number of lines in the frame (which is twice the field height
+	for interlaced formats).
+    * - :cspan:`2` Applications set these fields to request an image
+	size, drivers return the closest possible values. In case of
+	planar formats the ``width`` and ``height`` applies to the largest
+	plane. To avoid ambiguities drivers must return values rounded up
+	to a multiple of the scale factor of any smaller planes. For
+	example when the image format is YUV 4:2:0, ``width`` and
+	``height`` must be multiples of two.
+
+	For compressed formats that contain the resolution information encoded
+	inside the stream, when fed to a stateful mem2mem decoder, the fields
+	may be zero to rely on the decoder to detect the right values. For more
+	details see :ref:`decoder` and format descriptions.
+    * - __u32
+      - ``pixelformat``
+      - The pixel format or type of compression, set by the application.
+	This is a little endian
+	:ref:`four character code <v4l2-fourcc>`. V4L2 defines standard
+	RGB formats in :ref:`pixfmt-rgb`, YUV formats in
+	:ref:`yuv-formats`, and reserved codes in
+	:ref:`reserved-formats`
+    * - __u32
+      - ``field``
+      - Field order, from enum :c:type:`v4l2_field`.
+        Video images are typically interlaced. Applications can request to
+	capture or output only the top or bottom field, or both fields
+	interlaced or sequentially stored in one buffer or alternating in
+	separate buffers. Drivers return the actual field order selected.
+	For more details on fields see :ref:`field-order`.
+    * - __u32
+      - ``bytesperline``
+      - Distance in bytes between the leftmost pixels in two adjacent
+	lines.
+    * - :cspan:`2`
+
+	Both applications and drivers can set this field to request
+	padding bytes at the end of each line. Drivers however may ignore
+	the value requested by the application, returning ``width`` times
+	bytes per pixel or a larger value required by the hardware. That
+	implies applications can just set this field to zero to get a
+	reasonable default.
+
+	Video hardware may access padding bytes, therefore they must
+	reside in accessible memory. Consider cases where padding bytes
+	after the last line of an image cross a system page boundary.
+	Input devices may write padding bytes, the value is undefined.
+	Output devices ignore the contents of padding bytes.
+
+	When the image format is planar the ``bytesperline`` value applies
+	to the first plane and is divided by the same factor as the
+	``width`` field for the other planes. For example the Cb and Cr
+	planes of a YUV 4:2:0 image have half as many padding bytes
+	following each line as the Y plane. To avoid ambiguities drivers
+	must return a ``bytesperline`` value rounded up to a multiple of
+	the scale factor.
+
+	For compressed formats the ``bytesperline`` value makes no sense.
+	Applications and drivers must set this to 0 in that case.
+    * - __u32
+      - ``sizeimage``
+      - Size in bytes of the buffer to hold a complete image, set by the
+	driver. Usually this is ``bytesperline`` times ``height``. When
+	the image consists of variable length compressed data this is the
+	number of bytes required by the codec to support the worst-case
+	compression scenario.
+
+	The driver will set the value for uncompressed images.
+
+	Clients are allowed to set the sizeimage field for variable length
+	compressed data flagged with ``V4L2_FMT_FLAG_COMPRESSED`` at
+	:ref:`VIDIOC_ENUM_FMT`, but the driver may ignore it and set the
+	value itself, or it may modify the provided value based on
+	alignment requirements or minimum/maximum size requirements.
+	If the client wants to leave this to the driver, then it should
+	set sizeimage to 0.
+    * - __u32
+      - ``colorspace``
+      - Image colorspace, from enum :c:type:`v4l2_colorspace`.
+        This information supplements the ``pixelformat`` and must be set
+	by the driver for capture streams and by the application for
+	output streams, see :ref:`colorspaces`.
+    * - __u32
+      - ``priv``
+      - This field indicates whether the remaining fields of the
+	struct :c:type:`v4l2_pix_format`, also called the
+	extended fields, are valid. When set to
+	``V4L2_PIX_FMT_PRIV_MAGIC``, it indicates that the extended fields
+	have been correctly initialized. When set to any other value it
+	indicates that the extended fields contain undefined values.
+
+	Applications that wish to use the pixel format extended fields
+	must first ensure that the feature is supported by querying the
+	device for the :ref:`V4L2_CAP_EXT_PIX_FORMAT <querycap>`
+	capability. If the capability isn't set the pixel format extended
+	fields are not supported and using the extended fields will lead
+	to undefined results.
+
+	To use the extended fields, applications must set the ``priv``
+	field to ``V4L2_PIX_FMT_PRIV_MAGIC``, initialize all the extended
+	fields and zero the unused bytes of the
+	struct :c:type:`v4l2_format` ``raw_data`` field.
+
+	When the ``priv`` field isn't set to ``V4L2_PIX_FMT_PRIV_MAGIC``
+	drivers must act as if all the extended fields were set to zero.
+	On return drivers must set the ``priv`` field to
+	``V4L2_PIX_FMT_PRIV_MAGIC`` and all the extended fields to
+	applicable values.
+    * - __u32
+      - ``flags``
+      - Flags set by the application or driver, see :ref:`format-flags`.
+    * - union {
+      - (anonymous)
+    * - __u32
+      - ``ycbcr_enc``
+      - Y'CbCr encoding, from enum :c:type:`v4l2_ycbcr_encoding`.
+        This information supplements the ``colorspace`` and must be set by
+	the driver for capture streams and by the application for output
+	streams, see :ref:`colorspaces`.
+    * - __u32
+      - ``hsv_enc``
+      - HSV encoding, from enum :c:type:`v4l2_hsv_encoding`.
+        This information supplements the ``colorspace`` and must be set by
+	the driver for capture streams and by the application for output
+	streams, see :ref:`colorspaces`.
+    * - }
+      -
+    * - __u32
+      - ``quantization``
+      - Quantization range, from enum :c:type:`v4l2_quantization`.
+        This information supplements the ``colorspace`` and must be set by
+	the driver for capture streams and by the application for output
+	streams, see :ref:`colorspaces`.
+    * - __u32
+      - ``xfer_func``
+      - Transfer function, from enum :c:type:`v4l2_xfer_func`.
+        This information supplements the ``colorspace`` and must be set by
+	the driver for capture streams and by the application for output
+	streams, see :ref:`colorspaces`.
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-vyuy.rst b/Documentation/userspace-api/media/v4l/pixfmt-vyuy.rst
new file mode 100644
index 000000000000..6cd574e78e4c
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-vyuy.rst
@@ -0,0 +1,115 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-VYUY:
+
+**************************
+V4L2_PIX_FMT_VYUY ('VYUY')
+**************************
+
+
+Variation of ``V4L2_PIX_FMT_YUYV`` with different order of samples in
+memory
+
+
+Description
+===========
+
+In this format each four bytes is two pixels. Each four bytes is two
+Y's, a Cb and a Cr. Each Y goes to one of the pixels, and the Cb and Cr
+belong to both pixels. As you can see, the Cr and Cb components have
+half the horizontal resolution of the Y component.
+
+**Byte Order.**
+Each cell is one byte.
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - start + 0:
+      - Cr\ :sub:`00`
+      - Y'\ :sub:`00`
+      - Cb\ :sub:`00`
+      - Y'\ :sub:`01`
+      - Cr\ :sub:`01`
+      - Y'\ :sub:`02`
+      - Cb\ :sub:`01`
+      - Y'\ :sub:`03`
+    * - start + 8:
+      - Cr\ :sub:`10`
+      - Y'\ :sub:`10`
+      - Cb\ :sub:`10`
+      - Y'\ :sub:`11`
+      - Cr\ :sub:`11`
+      - Y'\ :sub:`12`
+      - Cb\ :sub:`11`
+      - Y'\ :sub:`13`
+    * - start + 16:
+      - Cr\ :sub:`20`
+      - Y'\ :sub:`20`
+      - Cb\ :sub:`20`
+      - Y'\ :sub:`21`
+      - Cr\ :sub:`21`
+      - Y'\ :sub:`22`
+      - Cb\ :sub:`21`
+      - Y'\ :sub:`23`
+    * - start + 24:
+      - Cr\ :sub:`30`
+      - Y'\ :sub:`30`
+      - Cb\ :sub:`30`
+      - Y'\ :sub:`31`
+      - Cr\ :sub:`31`
+      - Y'\ :sub:`32`
+      - Cb\ :sub:`31`
+      - Y'\ :sub:`33`
+
+
+**Color Sample Location:**
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * -
+      - 0
+      -
+      - 1
+      -
+      - 2
+      - 3
+    * - 0
+      - Y
+      - C
+      - Y
+      - Y
+      - C
+      - Y
+    * - 1
+      - Y
+      - C
+      - Y
+      - Y
+      - C
+      - Y
+    * - 2
+      - Y
+      - C
+      - Y
+      - Y
+      - C
+      - Y
+    * - 3
+      - Y
+      - C
+      - Y
+      - Y
+      - C
+      - Y
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-y10.rst b/Documentation/userspace-api/media/v4l/pixfmt-y10.rst
new file mode 100644
index 000000000000..dfb352ae6784
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-y10.rst
@@ -0,0 +1,72 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-Y10:
+
+*************************
+V4L2_PIX_FMT_Y10 ('Y10 ')
+*************************
+
+
+Grey-scale image
+
+
+Description
+===========
+
+This is a grey-scale image with a depth of 10 bits per pixel. Pixels are
+stored in 16-bit words with unused high bits padded with 0. The least
+significant byte is stored at lower memory addresses (little-endian).
+
+**Byte Order.**
+Each cell is one byte.
+
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - start + 0:
+      - Y'\ :sub:`00low`
+      - Y'\ :sub:`00high`
+      - Y'\ :sub:`01low`
+      - Y'\ :sub:`01high`
+      - Y'\ :sub:`02low`
+      - Y'\ :sub:`02high`
+      - Y'\ :sub:`03low`
+      - Y'\ :sub:`03high`
+    * - start + 8:
+      - Y'\ :sub:`10low`
+      - Y'\ :sub:`10high`
+      - Y'\ :sub:`11low`
+      - Y'\ :sub:`11high`
+      - Y'\ :sub:`12low`
+      - Y'\ :sub:`12high`
+      - Y'\ :sub:`13low`
+      - Y'\ :sub:`13high`
+    * - start + 16:
+      - Y'\ :sub:`20low`
+      - Y'\ :sub:`20high`
+      - Y'\ :sub:`21low`
+      - Y'\ :sub:`21high`
+      - Y'\ :sub:`22low`
+      - Y'\ :sub:`22high`
+      - Y'\ :sub:`23low`
+      - Y'\ :sub:`23high`
+    * - start + 24:
+      - Y'\ :sub:`30low`
+      - Y'\ :sub:`30high`
+      - Y'\ :sub:`31low`
+      - Y'\ :sub:`31high`
+      - Y'\ :sub:`32low`
+      - Y'\ :sub:`32high`
+      - Y'\ :sub:`33low`
+      - Y'\ :sub:`33high`
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-y10b.rst b/Documentation/userspace-api/media/v4l/pixfmt-y10b.rst
new file mode 100644
index 000000000000..b5d89d6d5c52
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-y10b.rst
@@ -0,0 +1,40 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-Y10BPACK:
+
+******************************
+V4L2_PIX_FMT_Y10BPACK ('Y10B')
+******************************
+
+Grey-scale image as a bit-packed array
+
+
+Description
+===========
+
+This is a packed grey-scale image format with a depth of 10 bits per
+pixel. Pixels are stored in a bit-packed array of 10bit bits per pixel,
+with no padding between them and with the most significant bits coming
+first from the left.
+
+**Bit-packed representation.**
+
+pixels cross the byte boundary and have a ratio of 5 bytes for each 4
+pixels.
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - Y'\ :sub:`00[9:2]`
+      - Y'\ :sub:`00[1:0]`\ Y'\ :sub:`01[9:4]`
+      - Y'\ :sub:`01[3:0]`\ Y'\ :sub:`02[9:6]`
+      - Y'\ :sub:`02[5:0]`\ Y'\ :sub:`03[9:8]`
+      - Y'\ :sub:`03[7:0]`
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-y10p.rst b/Documentation/userspace-api/media/v4l/pixfmt-y10p.rst
new file mode 100644
index 000000000000..ffb6e1631b78
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-y10p.rst
@@ -0,0 +1,50 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-Y10P:
+
+******************************
+V4L2_PIX_FMT_Y10P ('Y10P')
+******************************
+
+Grey-scale image as a MIPI RAW10 packed array
+
+
+Description
+===========
+
+This is a packed grey-scale image format with a depth of 10 bits per
+pixel. Every four consecutive pixels are packed into 5 bytes. Each of
+the first 4 bytes contain the 8 high order bits of the pixels, and
+the 5th byte contains the 2 least significants bits of each pixel,
+in the same order.
+
+**Bit-packed representation.**
+
+.. raw:: latex
+
+    \small
+
+.. tabularcolumns:: |p{1.2cm}||p{1.2cm}||p{1.2cm}||p{1.2cm}|p{3.2cm}|p{3.2cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths: 8 8 8 8 64
+
+    * - Y'\ :sub:`00[9:2]`
+      - Y'\ :sub:`01[9:2]`
+      - Y'\ :sub:`02[9:2]`
+      - Y'\ :sub:`03[9:2]`
+      - Y'\ :sub:`03[1:0]`\ (bits 7--6) Y'\ :sub:`02[1:0]`\ (bits 5--4)
+	Y'\ :sub:`01[1:0]`\ (bits 3--2) Y'\ :sub:`00[1:0]`\ (bits 1--0)
+
+.. raw:: latex
+
+    \normalsize
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-y12.rst b/Documentation/userspace-api/media/v4l/pixfmt-y12.rst
new file mode 100644
index 000000000000..4226c49232de
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-y12.rst
@@ -0,0 +1,72 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-Y12:
+
+*************************
+V4L2_PIX_FMT_Y12 ('Y12 ')
+*************************
+
+
+Grey-scale image
+
+
+Description
+===========
+
+This is a grey-scale image with a depth of 12 bits per pixel. Pixels are
+stored in 16-bit words with unused high bits padded with 0. The least
+significant byte is stored at lower memory addresses (little-endian).
+
+**Byte Order.**
+Each cell is one byte.
+
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - start + 0:
+      - Y'\ :sub:`00low`
+      - Y'\ :sub:`00high`
+      - Y'\ :sub:`01low`
+      - Y'\ :sub:`01high`
+      - Y'\ :sub:`02low`
+      - Y'\ :sub:`02high`
+      - Y'\ :sub:`03low`
+      - Y'\ :sub:`03high`
+    * - start + 8:
+      - Y'\ :sub:`10low`
+      - Y'\ :sub:`10high`
+      - Y'\ :sub:`11low`
+      - Y'\ :sub:`11high`
+      - Y'\ :sub:`12low`
+      - Y'\ :sub:`12high`
+      - Y'\ :sub:`13low`
+      - Y'\ :sub:`13high`
+    * - start + 16:
+      - Y'\ :sub:`20low`
+      - Y'\ :sub:`20high`
+      - Y'\ :sub:`21low`
+      - Y'\ :sub:`21high`
+      - Y'\ :sub:`22low`
+      - Y'\ :sub:`22high`
+      - Y'\ :sub:`23low`
+      - Y'\ :sub:`23high`
+    * - start + 24:
+      - Y'\ :sub:`30low`
+      - Y'\ :sub:`30high`
+      - Y'\ :sub:`31low`
+      - Y'\ :sub:`31high`
+      - Y'\ :sub:`32low`
+      - Y'\ :sub:`32high`
+      - Y'\ :sub:`33low`
+      - Y'\ :sub:`33high`
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-y12i.rst b/Documentation/userspace-api/media/v4l/pixfmt-y12i.rst
new file mode 100644
index 000000000000..b4752754337b
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-y12i.rst
@@ -0,0 +1,43 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-Y12I:
+
+**************************
+V4L2_PIX_FMT_Y12I ('Y12I')
+**************************
+
+Interleaved grey-scale image, e.g. from a stereo-pair
+
+
+Description
+===========
+
+This is a grey-scale image with a depth of 12 bits per pixel, but with
+pixels from 2 sources interleaved and bit-packed. Each pixel is stored
+in a 24-bit word in the little-endian order. On a little-endian machine
+these pixels can be deinterlaced using
+
+.. code-block:: c
+
+    __u8 *buf;
+    left0 = 0xfff & *(__u16 *)buf;
+    right0 = *(__u16 *)(buf + 1) >> 4;
+
+**Bit-packed representation.**
+pixels cross the byte boundary and have a ratio of 3 bytes for each
+interleaved pixel.
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - Y'\ :sub:`0left[7:0]`
+      - Y'\ :sub:`0right[3:0]`\ Y'\ :sub:`0left[11:8]`
+      - Y'\ :sub:`0right[11:4]`
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-y14.rst b/Documentation/userspace-api/media/v4l/pixfmt-y14.rst
new file mode 100644
index 000000000000..d702b6549160
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-y14.rst
@@ -0,0 +1,72 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-Y14:
+
+*************************
+V4L2_PIX_FMT_Y14 ('Y14 ')
+*************************
+
+
+Grey-scale image
+
+
+Description
+===========
+
+This is a grey-scale image with a depth of 14 bits per pixel. Pixels are
+stored in 16-bit words with unused high bits padded with 0. The least
+significant byte is stored at lower memory addresses (little-endian).
+
+**Byte Order.**
+Each cell is one byte.
+
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - start + 0:
+      - Y'\ :sub:`00low`
+      - Y'\ :sub:`00high`
+      - Y'\ :sub:`01low`
+      - Y'\ :sub:`01high`
+      - Y'\ :sub:`02low`
+      - Y'\ :sub:`02high`
+      - Y'\ :sub:`03low`
+      - Y'\ :sub:`03high`
+    * - start + 8:
+      - Y'\ :sub:`10low`
+      - Y'\ :sub:`10high`
+      - Y'\ :sub:`11low`
+      - Y'\ :sub:`11high`
+      - Y'\ :sub:`12low`
+      - Y'\ :sub:`12high`
+      - Y'\ :sub:`13low`
+      - Y'\ :sub:`13high`
+    * - start + 16:
+      - Y'\ :sub:`20low`
+      - Y'\ :sub:`20high`
+      - Y'\ :sub:`21low`
+      - Y'\ :sub:`21high`
+      - Y'\ :sub:`22low`
+      - Y'\ :sub:`22high`
+      - Y'\ :sub:`23low`
+      - Y'\ :sub:`23high`
+    * - start + 24:
+      - Y'\ :sub:`30low`
+      - Y'\ :sub:`30high`
+      - Y'\ :sub:`31low`
+      - Y'\ :sub:`31high`
+      - Y'\ :sub:`32low`
+      - Y'\ :sub:`32high`
+      - Y'\ :sub:`33low`
+      - Y'\ :sub:`33high`
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-y16-be.rst b/Documentation/userspace-api/media/v4l/pixfmt-y16-be.rst
new file mode 100644
index 000000000000..f4eda7b95b51
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-y16-be.rst
@@ -0,0 +1,76 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-Y16-BE:
+
+****************************************
+V4L2_PIX_FMT_Y16_BE ('Y16 ' | (1 << 31))
+****************************************
+
+
+Grey-scale image
+
+
+Description
+===========
+
+This is a grey-scale image with a depth of 16 bits per pixel. The most
+significant byte is stored at lower memory addresses (big-endian).
+
+.. note::
+
+   The actual sampling precision may be lower than 16 bits, for
+   example 10 bits per pixel with values in range 0 to 1023.
+
+**Byte Order.**
+Each cell is one byte.
+
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - start + 0:
+      - Y'\ :sub:`00high`
+      - Y'\ :sub:`00low`
+      - Y'\ :sub:`01high`
+      - Y'\ :sub:`01low`
+      - Y'\ :sub:`02high`
+      - Y'\ :sub:`02low`
+      - Y'\ :sub:`03high`
+      - Y'\ :sub:`03low`
+    * - start + 8:
+      - Y'\ :sub:`10high`
+      - Y'\ :sub:`10low`
+      - Y'\ :sub:`11high`
+      - Y'\ :sub:`11low`
+      - Y'\ :sub:`12high`
+      - Y'\ :sub:`12low`
+      - Y'\ :sub:`13high`
+      - Y'\ :sub:`13low`
+    * - start + 16:
+      - Y'\ :sub:`20high`
+      - Y'\ :sub:`20low`
+      - Y'\ :sub:`21high`
+      - Y'\ :sub:`21low`
+      - Y'\ :sub:`22high`
+      - Y'\ :sub:`22low`
+      - Y'\ :sub:`23high`
+      - Y'\ :sub:`23low`
+    * - start + 24:
+      - Y'\ :sub:`30high`
+      - Y'\ :sub:`30low`
+      - Y'\ :sub:`31high`
+      - Y'\ :sub:`31low`
+      - Y'\ :sub:`32high`
+      - Y'\ :sub:`32low`
+      - Y'\ :sub:`33high`
+      - Y'\ :sub:`33low`
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-y16.rst b/Documentation/userspace-api/media/v4l/pixfmt-y16.rst
new file mode 100644
index 000000000000..a092b0a5ff12
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-y16.rst
@@ -0,0 +1,76 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-Y16:
+
+*************************
+V4L2_PIX_FMT_Y16 ('Y16 ')
+*************************
+
+
+Grey-scale image
+
+
+Description
+===========
+
+This is a grey-scale image with a depth of 16 bits per pixel. The least
+significant byte is stored at lower memory addresses (little-endian).
+
+.. note::
+
+   The actual sampling precision may be lower than 16 bits, for
+   example 10 bits per pixel with values in range 0 to 1023.
+
+**Byte Order.**
+Each cell is one byte.
+
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - start + 0:
+      - Y'\ :sub:`00low`
+      - Y'\ :sub:`00high`
+      - Y'\ :sub:`01low`
+      - Y'\ :sub:`01high`
+      - Y'\ :sub:`02low`
+      - Y'\ :sub:`02high`
+      - Y'\ :sub:`03low`
+      - Y'\ :sub:`03high`
+    * - start + 8:
+      - Y'\ :sub:`10low`
+      - Y'\ :sub:`10high`
+      - Y'\ :sub:`11low`
+      - Y'\ :sub:`11high`
+      - Y'\ :sub:`12low`
+      - Y'\ :sub:`12high`
+      - Y'\ :sub:`13low`
+      - Y'\ :sub:`13high`
+    * - start + 16:
+      - Y'\ :sub:`20low`
+      - Y'\ :sub:`20high`
+      - Y'\ :sub:`21low`
+      - Y'\ :sub:`21high`
+      - Y'\ :sub:`22low`
+      - Y'\ :sub:`22high`
+      - Y'\ :sub:`23low`
+      - Y'\ :sub:`23high`
+    * - start + 24:
+      - Y'\ :sub:`30low`
+      - Y'\ :sub:`30high`
+      - Y'\ :sub:`31low`
+      - Y'\ :sub:`31high`
+      - Y'\ :sub:`32low`
+      - Y'\ :sub:`32high`
+      - Y'\ :sub:`33low`
+      - Y'\ :sub:`33high`
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-y41p.rst b/Documentation/userspace-api/media/v4l/pixfmt-y41p.rst
new file mode 100644
index 000000000000..211afd7593cc
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-y41p.rst
@@ -0,0 +1,158 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-Y41P:
+
+**************************
+V4L2_PIX_FMT_Y41P ('Y41P')
+**************************
+
+
+Format with ¼ horizontal chroma resolution, also known as YUV 4:1:1
+
+
+Description
+===========
+
+In this format each 12 bytes is eight pixels. In the twelve bytes are
+two CbCr pairs and eight Y's. The first CbCr pair goes with the first
+four Y's, and the second CbCr pair goes with the other four Y's. The Cb
+and Cr components have one fourth the horizontal resolution of the Y
+component.
+
+Do not confuse this format with
+:ref:`V4L2_PIX_FMT_YUV411P <V4L2-PIX-FMT-YUV411P>`. Y41P is derived
+from "YUV 4:1:1 *packed*", while YUV411P stands for "YUV 4:1:1
+*planar*".
+
+**Byte Order.**
+Each cell is one byte.
+
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - start + 0:
+      - Cb\ :sub:`00`
+      - Y'\ :sub:`00`
+      - Cr\ :sub:`00`
+      - Y'\ :sub:`01`
+      - Cb\ :sub:`01`
+      - Y'\ :sub:`02`
+      - Cr\ :sub:`01`
+      - Y'\ :sub:`03`
+      - Y'\ :sub:`04`
+      - Y'\ :sub:`05`
+      - Y'\ :sub:`06`
+      - Y'\ :sub:`07`
+    * - start + 12:
+      - Cb\ :sub:`10`
+      - Y'\ :sub:`10`
+      - Cr\ :sub:`10`
+      - Y'\ :sub:`11`
+      - Cb\ :sub:`11`
+      - Y'\ :sub:`12`
+      - Cr\ :sub:`11`
+      - Y'\ :sub:`13`
+      - Y'\ :sub:`14`
+      - Y'\ :sub:`15`
+      - Y'\ :sub:`16`
+      - Y'\ :sub:`17`
+    * - start + 24:
+      - Cb\ :sub:`20`
+      - Y'\ :sub:`20`
+      - Cr\ :sub:`20`
+      - Y'\ :sub:`21`
+      - Cb\ :sub:`21`
+      - Y'\ :sub:`22`
+      - Cr\ :sub:`21`
+      - Y'\ :sub:`23`
+      - Y'\ :sub:`24`
+      - Y'\ :sub:`25`
+      - Y'\ :sub:`26`
+      - Y'\ :sub:`27`
+    * - start + 36:
+      - Cb\ :sub:`30`
+      - Y'\ :sub:`30`
+      - Cr\ :sub:`30`
+      - Y'\ :sub:`31`
+      - Cb\ :sub:`31`
+      - Y'\ :sub:`32`
+      - Cr\ :sub:`31`
+      - Y'\ :sub:`33`
+      - Y'\ :sub:`34`
+      - Y'\ :sub:`35`
+      - Y'\ :sub:`36`
+      - Y'\ :sub:`37`
+
+
+**Color Sample Location:**
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * -
+      - 0
+      - 1
+      -
+      - 2
+      - 3
+      - 4
+      - 5
+      -
+      - 6
+      - 7
+    * - 0
+      - Y
+      - Y
+      - C
+      - Y
+      - Y
+      - Y
+      - Y
+      - C
+      - Y
+      - Y
+    * - 1
+      - Y
+      - Y
+      - C
+      - Y
+      - Y
+      - Y
+      - Y
+      - C
+      - Y
+      - Y
+    * - 2
+      - Y
+      - Y
+      - C
+      - Y
+      - Y
+      - Y
+      - Y
+      - C
+      - Y
+      - Y
+    * - 3
+      - Y
+      - Y
+      - C
+      - Y
+      - Y
+      - Y
+      - Y
+      - C
+      - Y
+      - Y
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-y8i.rst b/Documentation/userspace-api/media/v4l/pixfmt-y8i.rst
new file mode 100644
index 000000000000..4248c6f735b7
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-y8i.rst
@@ -0,0 +1,73 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-Y8I:
+
+*************************
+V4L2_PIX_FMT_Y8I ('Y8I ')
+*************************
+
+
+Interleaved grey-scale image, e.g. from a stereo-pair
+
+
+Description
+===========
+
+This is a grey-scale image with a depth of 8 bits per pixel, but with
+pixels from 2 sources interleaved. Each pixel is stored in a 16-bit
+word. E.g. the R200 RealSense camera stores pixel from the left sensor
+in lower and from the right sensor in the higher 8 bits.
+
+**Byte Order.**
+Each cell is one byte.
+
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - start + 0:
+      - Y'\ :sub:`00left`
+      - Y'\ :sub:`00right`
+      - Y'\ :sub:`01left`
+      - Y'\ :sub:`01right`
+      - Y'\ :sub:`02left`
+      - Y'\ :sub:`02right`
+      - Y'\ :sub:`03left`
+      - Y'\ :sub:`03right`
+    * - start + 8:
+      - Y'\ :sub:`10left`
+      - Y'\ :sub:`10right`
+      - Y'\ :sub:`11left`
+      - Y'\ :sub:`11right`
+      - Y'\ :sub:`12left`
+      - Y'\ :sub:`12right`
+      - Y'\ :sub:`13left`
+      - Y'\ :sub:`13right`
+    * - start + 16:
+      - Y'\ :sub:`20left`
+      - Y'\ :sub:`20right`
+      - Y'\ :sub:`21left`
+      - Y'\ :sub:`21right`
+      - Y'\ :sub:`22left`
+      - Y'\ :sub:`22right`
+      - Y'\ :sub:`23left`
+      - Y'\ :sub:`23right`
+    * - start + 24:
+      - Y'\ :sub:`30left`
+      - Y'\ :sub:`30right`
+      - Y'\ :sub:`31left`
+      - Y'\ :sub:`31right`
+      - Y'\ :sub:`32left`
+      - Y'\ :sub:`32right`
+      - Y'\ :sub:`33left`
+      - Y'\ :sub:`33right`
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-yuv410.rst b/Documentation/userspace-api/media/v4l/pixfmt-yuv410.rst
new file mode 100644
index 000000000000..1d20115f2b1d
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-yuv410.rst
@@ -0,0 +1,134 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-YVU410:
+.. _v4l2-pix-fmt-yuv410:
+
+**********************************************************
+V4L2_PIX_FMT_YVU410 ('YVU9'), V4L2_PIX_FMT_YUV410 ('YUV9')
+**********************************************************
+
+
+V4L2_PIX_FMT_YUV410
+Planar formats with ¼ horizontal and vertical chroma resolution, also
+known as YUV 4:1:0
+
+
+Description
+===========
+
+These are planar formats, as opposed to a packed format. The three
+components are separated into three sub-images or planes. The Y plane is
+first. The Y plane has one byte per pixel. For ``V4L2_PIX_FMT_YVU410``,
+the Cr plane immediately follows the Y plane in memory. The Cr plane is
+¼ the width and ¼ the height of the Y plane (and of the image). Each Cr
+belongs to 16 pixels, a four-by-four square of the image. Following the
+Cr plane is the Cb plane, just like the Cr plane.
+``V4L2_PIX_FMT_YUV410`` is the same, except the Cb plane comes first,
+then the Cr plane.
+
+If the Y plane has pad bytes after each row, then the Cr and Cb planes
+have ¼ as many pad bytes after their rows. In other words, four Cx rows
+(including padding) are exactly as long as one Y row (including
+padding).
+
+**Byte Order.**
+Each cell is one byte.
+
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - start + 0:
+      - Y'\ :sub:`00`
+      - Y'\ :sub:`01`
+      - Y'\ :sub:`02`
+      - Y'\ :sub:`03`
+    * - start + 4:
+      - Y'\ :sub:`10`
+      - Y'\ :sub:`11`
+      - Y'\ :sub:`12`
+      - Y'\ :sub:`13`
+    * - start + 8:
+      - Y'\ :sub:`20`
+      - Y'\ :sub:`21`
+      - Y'\ :sub:`22`
+      - Y'\ :sub:`23`
+    * - start + 12:
+      - Y'\ :sub:`30`
+      - Y'\ :sub:`31`
+      - Y'\ :sub:`32`
+      - Y'\ :sub:`33`
+    * - start + 16:
+      - Cr\ :sub:`00`
+    * - start + 17:
+      - Cb\ :sub:`00`
+
+
+**Color Sample Location:**
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * -
+      - 0
+      -
+      - 1
+      -
+      - 2
+      -
+      - 3
+    * - 0
+      - Y
+      -
+      - Y
+      -
+      - Y
+      -
+      - Y
+    * -
+    * - 1
+      - Y
+      -
+      - Y
+      -
+      - Y
+      -
+      - Y
+    * -
+      -
+      -
+      -
+      - C
+      -
+      -
+      -
+    * - 2
+      - Y
+      -
+      - Y
+      -
+      - Y
+      -
+      - Y
+    * -
+    * - 3
+      - Y
+      -
+      - Y
+      -
+      - Y
+      -
+      - Y
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-yuv411p.rst b/Documentation/userspace-api/media/v4l/pixfmt-yuv411p.rst
new file mode 100644
index 000000000000..967ba7ce41a2
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-yuv411p.rst
@@ -0,0 +1,122 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-YUV411P:
+
+*****************************
+V4L2_PIX_FMT_YUV411P ('411P')
+*****************************
+
+
+Format with ¼ horizontal chroma resolution, also known as YUV 4:1:1.
+Planar layout as opposed to ``V4L2_PIX_FMT_Y41P``
+
+
+Description
+===========
+
+This format is not commonly used. This is a planar format similar to the
+4:2:2 planar format except with half as many chroma. The three
+components are separated into three sub-images or planes. The Y plane is
+first. The Y plane has one byte per pixel. The Cb plane immediately
+follows the Y plane in memory. The Cb plane is ¼ the width of the Y
+plane (and of the image). Each Cb belongs to 4 pixels all on the same
+row. For example, Cb\ :sub:`0` belongs to Y'\ :sub:`00`, Y'\ :sub:`01`,
+Y'\ :sub:`02` and Y'\ :sub:`03`. Following the Cb plane is the Cr plane,
+just like the Cb plane.
+
+If the Y plane has pad bytes after each row, then the Cr and Cb planes
+have ¼ as many pad bytes after their rows. In other words, four C x rows
+(including padding) is exactly as long as one Y row (including padding).
+
+**Byte Order.**
+Each cell is one byte.
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - start + 0:
+      - Y'\ :sub:`00`
+      - Y'\ :sub:`01`
+      - Y'\ :sub:`02`
+      - Y'\ :sub:`03`
+    * - start + 4:
+      - Y'\ :sub:`10`
+      - Y'\ :sub:`11`
+      - Y'\ :sub:`12`
+      - Y'\ :sub:`13`
+    * - start + 8:
+      - Y'\ :sub:`20`
+      - Y'\ :sub:`21`
+      - Y'\ :sub:`22`
+      - Y'\ :sub:`23`
+    * - start + 12:
+      - Y'\ :sub:`30`
+      - Y'\ :sub:`31`
+      - Y'\ :sub:`32`
+      - Y'\ :sub:`33`
+    * - start + 16:
+      - Cb\ :sub:`00`
+    * - start + 17:
+      - Cb\ :sub:`10`
+    * - start + 18:
+      - Cb\ :sub:`20`
+    * - start + 19:
+      - Cb\ :sub:`30`
+    * - start + 20:
+      - Cr\ :sub:`00`
+    * - start + 21:
+      - Cr\ :sub:`10`
+    * - start + 22:
+      - Cr\ :sub:`20`
+    * - start + 23:
+      - Cr\ :sub:`30`
+
+
+**Color Sample Location:**
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * -
+      - 0
+      - 1
+      -
+      - 2
+      - 3
+    * - 0
+      - Y
+      - Y
+      - C
+      - Y
+      - Y
+    * - 1
+      - Y
+      - Y
+      - C
+      - Y
+      - Y
+    * - 2
+      - Y
+      - Y
+      - C
+      - Y
+      - Y
+    * - 3
+      - Y
+      - Y
+      - C
+      - Y
+      - Y
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-yuv420.rst b/Documentation/userspace-api/media/v4l/pixfmt-yuv420.rst
new file mode 100644
index 000000000000..7cb685cc8289
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-yuv420.rst
@@ -0,0 +1,150 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-YVU420:
+.. _V4L2-PIX-FMT-YUV420:
+
+**********************************************************
+V4L2_PIX_FMT_YVU420 ('YV12'), V4L2_PIX_FMT_YUV420 ('YU12')
+**********************************************************
+
+
+V4L2_PIX_FMT_YUV420
+Planar formats with ½ horizontal and vertical chroma resolution, also
+known as YUV 4:2:0
+
+
+Description
+===========
+
+These are planar formats, as opposed to a packed format. The three
+components are separated into three sub- images or planes. The Y plane
+is first. The Y plane has one byte per pixel. For
+``V4L2_PIX_FMT_YVU420``, the Cr plane immediately follows the Y plane in
+memory. The Cr plane is half the width and half the height of the Y
+plane (and of the image). Each Cr belongs to four pixels, a two-by-two
+square of the image. For example, Cr\ :sub:`0` belongs to Y'\ :sub:`00`,
+Y'\ :sub:`01`, Y'\ :sub:`10`, and Y'\ :sub:`11`. Following the Cr plane
+is the Cb plane, just like the Cr plane. ``V4L2_PIX_FMT_YUV420`` is the
+same except the Cb plane comes first, then the Cr plane.
+
+If the Y plane has pad bytes after each row, then the Cr and Cb planes
+have half as many pad bytes after their rows. In other words, two Cx
+rows (including padding) is exactly as long as one Y row (including
+padding).
+
+**Byte Order.**
+Each cell is one byte.
+
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - start + 0:
+      - Y'\ :sub:`00`
+      - Y'\ :sub:`01`
+      - Y'\ :sub:`02`
+      - Y'\ :sub:`03`
+    * - start + 4:
+      - Y'\ :sub:`10`
+      - Y'\ :sub:`11`
+      - Y'\ :sub:`12`
+      - Y'\ :sub:`13`
+    * - start + 8:
+      - Y'\ :sub:`20`
+      - Y'\ :sub:`21`
+      - Y'\ :sub:`22`
+      - Y'\ :sub:`23`
+    * - start + 12:
+      - Y'\ :sub:`30`
+      - Y'\ :sub:`31`
+      - Y'\ :sub:`32`
+      - Y'\ :sub:`33`
+    * - start + 16:
+      - Cr\ :sub:`00`
+      - Cr\ :sub:`01`
+    * - start + 18:
+      - Cr\ :sub:`10`
+      - Cr\ :sub:`11`
+    * - start + 20:
+      - Cb\ :sub:`00`
+      - Cb\ :sub:`01`
+    * - start + 22:
+      - Cb\ :sub:`10`
+      - Cb\ :sub:`11`
+
+
+**Color Sample Location:**
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * -
+      - 0
+      -
+      - 1
+      -
+      - 2
+      -
+      - 3
+    * - 0
+      - Y
+      -
+      - Y
+      -
+      - Y
+      -
+      - Y
+    * -
+      -
+      - C
+      -
+      -
+      -
+      - C
+      -
+    * - 1
+      - Y
+      -
+      - Y
+      -
+      - Y
+      -
+      - Y
+    * -
+    * - 2
+      - Y
+      -
+      - Y
+      -
+      - Y
+      -
+      - Y
+    * -
+      -
+      - C
+      -
+      -
+      -
+      - C
+      -
+    * - 3
+      - Y
+      -
+      - Y
+      -
+      - Y
+      -
+      - Y
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-yuv420m.rst b/Documentation/userspace-api/media/v4l/pixfmt-yuv420m.rst
new file mode 100644
index 000000000000..80c14d4f5acb
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-yuv420m.rst
@@ -0,0 +1,159 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-YUV420M:
+.. _v4l2-pix-fmt-yvu420m:
+
+************************************************************
+V4L2_PIX_FMT_YUV420M ('YM12'), V4L2_PIX_FMT_YVU420M ('YM21')
+************************************************************
+
+
+V4L2_PIX_FMT_YVU420M
+Variation of ``V4L2_PIX_FMT_YUV420`` and ``V4L2_PIX_FMT_YVU420`` with
+planes non contiguous in memory.
+
+
+Description
+===========
+
+This is a multi-planar format, as opposed to a packed format. The three
+components are separated into three sub-images or planes.
+
+The Y plane is first. The Y plane has one byte per pixel. For
+``V4L2_PIX_FMT_YUV420M`` the Cb data constitutes the second plane which
+is half the width and half the height of the Y plane (and of the image).
+Each Cb belongs to four pixels, a two-by-two square of the image. For
+example, Cb\ :sub:`0` belongs to Y'\ :sub:`00`, Y'\ :sub:`01`,
+Y'\ :sub:`10`, and Y'\ :sub:`11`. The Cr data, just like the Cb plane,
+is in the third plane.
+
+``V4L2_PIX_FMT_YVU420M`` is the same except the Cr data is stored in the
+second plane and the Cb data in the third plane.
+
+If the Y plane has pad bytes after each row, then the Cb and Cr planes
+have half as many pad bytes after their rows. In other words, two Cx
+rows (including padding) is exactly as long as one Y row (including
+padding).
+
+``V4L2_PIX_FMT_YUV420M`` and ``V4L2_PIX_FMT_YVU420M`` are intended to be
+used only in drivers and applications that support the multi-planar API,
+described in :ref:`planar-apis`.
+
+**Byte Order.**
+Each cell is one byte.
+
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - start0 + 0:
+      - Y'\ :sub:`00`
+      - Y'\ :sub:`01`
+      - Y'\ :sub:`02`
+      - Y'\ :sub:`03`
+    * - start0 + 4:
+      - Y'\ :sub:`10`
+      - Y'\ :sub:`11`
+      - Y'\ :sub:`12`
+      - Y'\ :sub:`13`
+    * - start0 + 8:
+      - Y'\ :sub:`20`
+      - Y'\ :sub:`21`
+      - Y'\ :sub:`22`
+      - Y'\ :sub:`23`
+    * - start0 + 12:
+      - Y'\ :sub:`30`
+      - Y'\ :sub:`31`
+      - Y'\ :sub:`32`
+      - Y'\ :sub:`33`
+    * -
+    * - start1 + 0:
+      - Cb\ :sub:`00`
+      - Cb\ :sub:`01`
+    * - start1 + 2:
+      - Cb\ :sub:`10`
+      - Cb\ :sub:`11`
+    * -
+    * - start2 + 0:
+      - Cr\ :sub:`00`
+      - Cr\ :sub:`01`
+    * - start2 + 2:
+      - Cr\ :sub:`10`
+      - Cr\ :sub:`11`
+
+
+**Color Sample Location:**
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * -
+      - 0
+      -
+      - 1
+      -
+      - 2
+      -
+      - 3
+    * - 0
+      - Y
+      -
+      - Y
+      -
+      - Y
+      -
+      - Y
+    * -
+      -
+      - C
+      -
+      -
+      -
+      - C
+      -
+    * - 1
+      - Y
+      -
+      - Y
+      -
+      - Y
+      -
+      - Y
+    * -
+    * - 2
+      - Y
+      -
+      - Y
+      -
+      - Y
+      -
+      - Y
+    * -
+      -
+      - C
+      -
+      -
+      -
+      - C
+      -
+    * - 3
+      - Y
+      -
+      - Y
+      -
+      - Y
+      -
+      - Y
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-yuv422m.rst b/Documentation/userspace-api/media/v4l/pixfmt-yuv422m.rst
new file mode 100644
index 000000000000..29b78480ccad
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-yuv422m.rst
@@ -0,0 +1,148 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-YUV422M:
+.. _v4l2-pix-fmt-yvu422m:
+
+************************************************************
+V4L2_PIX_FMT_YUV422M ('YM16'), V4L2_PIX_FMT_YVU422M ('YM61')
+************************************************************
+
+
+V4L2_PIX_FMT_YVU422M
+Planar formats with ½ horizontal resolution, also known as YUV and YVU
+4:2:2
+
+
+Description
+===========
+
+This is a multi-planar format, as opposed to a packed format. The three
+components are separated into three sub-images or planes.
+
+The Y plane is first. The Y plane has one byte per pixel. For
+``V4L2_PIX_FMT_YUV422M`` the Cb data constitutes the second plane which
+is half the width of the Y plane (and of the image). Each Cb belongs to
+two pixels. For example, Cb\ :sub:`0` belongs to Y'\ :sub:`00`,
+Y'\ :sub:`01`. The Cr data, just like the Cb plane, is in the third
+plane.
+
+``V4L2_PIX_FMT_YVU422M`` is the same except the Cr data is stored in the
+second plane and the Cb data in the third plane.
+
+If the Y plane has pad bytes after each row, then the Cb and Cr planes
+have half as many pad bytes after their rows. In other words, two Cx
+rows (including padding) is exactly as long as one Y row (including
+padding).
+
+``V4L2_PIX_FMT_YUV422M`` and ``V4L2_PIX_FMT_YVU422M`` are intended to be
+used only in drivers and applications that support the multi-planar API,
+described in :ref:`planar-apis`.
+
+**Byte Order.**
+Each cell is one byte.
+
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - start0 + 0:
+      - Y'\ :sub:`00`
+      - Y'\ :sub:`01`
+      - Y'\ :sub:`02`
+      - Y'\ :sub:`03`
+    * - start0 + 4:
+      - Y'\ :sub:`10`
+      - Y'\ :sub:`11`
+      - Y'\ :sub:`12`
+      - Y'\ :sub:`13`
+    * - start0 + 8:
+      - Y'\ :sub:`20`
+      - Y'\ :sub:`21`
+      - Y'\ :sub:`22`
+      - Y'\ :sub:`23`
+    * - start0 + 12:
+      - Y'\ :sub:`30`
+      - Y'\ :sub:`31`
+      - Y'\ :sub:`32`
+      - Y'\ :sub:`33`
+    * -
+    * - start1 + 0:
+      - Cb\ :sub:`00`
+      - Cb\ :sub:`01`
+    * - start1 + 2:
+      - Cb\ :sub:`10`
+      - Cb\ :sub:`11`
+    * - start1 + 4:
+      - Cb\ :sub:`20`
+      - Cb\ :sub:`21`
+    * - start1 + 6:
+      - Cb\ :sub:`30`
+      - Cb\ :sub:`31`
+    * -
+    * - start2 + 0:
+      - Cr\ :sub:`00`
+      - Cr\ :sub:`01`
+    * - start2 + 2:
+      - Cr\ :sub:`10`
+      - Cr\ :sub:`11`
+    * - start2 + 4:
+      - Cr\ :sub:`20`
+      - Cr\ :sub:`21`
+    * - start2 + 6:
+      - Cr\ :sub:`30`
+      - Cr\ :sub:`31`
+
+
+**Color Sample Location:**
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * -
+      - 0
+      -
+      - 1
+      - 2
+      -
+      - 3
+    * - 0
+      - Y
+      - C
+      - Y
+      - Y
+      - C
+      - Y
+    * - 1
+      - Y
+      - C
+      - Y
+      - Y
+      - C
+      - Y
+    * - 2
+      - Y
+      - C
+      - Y
+      - Y
+      - C
+      - Y
+    * - 3
+      - Y
+      - C
+      - Y
+      - Y
+      - C
+      - Y
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-yuv422p.rst b/Documentation/userspace-api/media/v4l/pixfmt-yuv422p.rst
new file mode 100644
index 000000000000..73fde222d820
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-yuv422p.rst
@@ -0,0 +1,136 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-YUV422P:
+
+*****************************
+V4L2_PIX_FMT_YUV422P ('422P')
+*****************************
+
+
+Format with ½ horizontal chroma resolution, also known as YUV 4:2:2.
+Planar layout as opposed to ``V4L2_PIX_FMT_YUYV``
+
+
+Description
+===========
+
+This format is not commonly used. This is a planar version of the YUYV
+format. The three components are separated into three sub-images or
+planes. The Y plane is first. The Y plane has one byte per pixel. The Cb
+plane immediately follows the Y plane in memory. The Cb plane is half
+the width of the Y plane (and of the image). Each Cb belongs to two
+pixels. For example, Cb\ :sub:`0` belongs to Y'\ :sub:`00`,
+Y'\ :sub:`01`. Following the Cb plane is the Cr plane, just like the Cb
+plane.
+
+If the Y plane has pad bytes after each row, then the Cr and Cb planes
+have half as many pad bytes after their rows. In other words, two Cx
+rows (including padding) is exactly as long as one Y row (including
+padding).
+
+**Byte Order.**
+Each cell is one byte.
+
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - start + 0:
+      - Y'\ :sub:`00`
+      - Y'\ :sub:`01`
+      - Y'\ :sub:`02`
+      - Y'\ :sub:`03`
+    * - start + 4:
+      - Y'\ :sub:`10`
+      - Y'\ :sub:`11`
+      - Y'\ :sub:`12`
+      - Y'\ :sub:`13`
+    * - start + 8:
+      - Y'\ :sub:`20`
+      - Y'\ :sub:`21`
+      - Y'\ :sub:`22`
+      - Y'\ :sub:`23`
+    * - start + 12:
+      - Y'\ :sub:`30`
+      - Y'\ :sub:`31`
+      - Y'\ :sub:`32`
+      - Y'\ :sub:`33`
+    * - start + 16:
+      - Cb\ :sub:`00`
+      - Cb\ :sub:`01`
+    * - start + 18:
+      - Cb\ :sub:`10`
+      - Cb\ :sub:`11`
+    * - start + 20:
+      - Cb\ :sub:`20`
+      - Cb\ :sub:`21`
+    * - start + 22:
+      - Cb\ :sub:`30`
+      - Cb\ :sub:`31`
+    * - start + 24:
+      - Cr\ :sub:`00`
+      - Cr\ :sub:`01`
+    * - start + 26:
+      - Cr\ :sub:`10`
+      - Cr\ :sub:`11`
+    * - start + 28:
+      - Cr\ :sub:`20`
+      - Cr\ :sub:`21`
+    * - start + 30:
+      - Cr\ :sub:`30`
+      - Cr\ :sub:`31`
+
+
+**Color Sample Location:**
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * -
+      - 0
+      -
+      - 1
+      - 2
+      -
+      - 3
+    * - 0
+      - Y
+      - C
+      - Y
+      - Y
+      - C
+      - Y
+    * - 1
+      - Y
+      - C
+      - Y
+      - Y
+      - C
+      - Y
+    * - 2
+      - Y
+      - C
+      - Y
+      - Y
+      - C
+      - Y
+    * - 3
+      - Y
+      - C
+      - Y
+      - Y
+      - C
+      - Y
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-yuv444m.rst b/Documentation/userspace-api/media/v4l/pixfmt-yuv444m.rst
new file mode 100644
index 000000000000..7073ac7f842d
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-yuv444m.rst
@@ -0,0 +1,148 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-YUV444M:
+.. _v4l2-pix-fmt-yvu444m:
+
+************************************************************
+V4L2_PIX_FMT_YUV444M ('YM24'), V4L2_PIX_FMT_YVU444M ('YM42')
+************************************************************
+
+
+V4L2_PIX_FMT_YVU444M
+Planar formats with full horizontal resolution, also known as YUV and
+YVU 4:4:4
+
+
+Description
+===========
+
+This is a multi-planar format, as opposed to a packed format. The three
+components are separated into three sub-images or planes.
+
+The Y plane is first. The Y plane has one byte per pixel. For
+``V4L2_PIX_FMT_YUV444M`` the Cb data constitutes the second plane which
+is the same width and height as the Y plane (and as the image). The Cr
+data, just like the Cb plane, is in the third plane.
+
+``V4L2_PIX_FMT_YVU444M`` is the same except the Cr data is stored in the
+second plane and the Cb data in the third plane.
+
+If the Y plane has pad bytes after each row, then the Cb and Cr planes
+have the same number of pad bytes after their rows.
+
+``V4L2_PIX_FMT_YUV444M`` and ``V4L2_PIX_FMT_YUV444M`` are intended to be
+used only in drivers and applications that support the multi-planar API,
+described in :ref:`planar-apis`.
+
+**Byte Order.**
+Each cell is one byte.
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - start0 + 0:
+      - Y'\ :sub:`00`
+      - Y'\ :sub:`01`
+      - Y'\ :sub:`02`
+      - Y'\ :sub:`03`
+    * - start0 + 4:
+      - Y'\ :sub:`10`
+      - Y'\ :sub:`11`
+      - Y'\ :sub:`12`
+      - Y'\ :sub:`13`
+    * - start0 + 8:
+      - Y'\ :sub:`20`
+      - Y'\ :sub:`21`
+      - Y'\ :sub:`22`
+      - Y'\ :sub:`23`
+    * - start0 + 12:
+      - Y'\ :sub:`30`
+      - Y'\ :sub:`31`
+      - Y'\ :sub:`32`
+      - Y'\ :sub:`33`
+    * -
+    * - start1 + 0:
+      - Cb\ :sub:`00`
+      - Cb\ :sub:`01`
+      - Cb\ :sub:`02`
+      - Cb\ :sub:`03`
+    * - start1 + 4:
+      - Cb\ :sub:`10`
+      - Cb\ :sub:`11`
+      - Cb\ :sub:`12`
+      - Cb\ :sub:`13`
+    * - start1 + 8:
+      - Cb\ :sub:`20`
+      - Cb\ :sub:`21`
+      - Cb\ :sub:`22`
+      - Cb\ :sub:`23`
+    * - start1 + 12:
+      - Cb\ :sub:`20`
+      - Cb\ :sub:`21`
+      - Cb\ :sub:`32`
+      - Cb\ :sub:`33`
+    * -
+    * - start2 + 0:
+      - Cr\ :sub:`00`
+      - Cr\ :sub:`01`
+      - Cr\ :sub:`02`
+      - Cr\ :sub:`03`
+    * - start2 + 4:
+      - Cr\ :sub:`10`
+      - Cr\ :sub:`11`
+      - Cr\ :sub:`12`
+      - Cr\ :sub:`13`
+    * - start2 + 8:
+      - Cr\ :sub:`20`
+      - Cr\ :sub:`21`
+      - Cr\ :sub:`22`
+      - Cr\ :sub:`23`
+    * - start2 + 12:
+      - Cr\ :sub:`30`
+      - Cr\ :sub:`31`
+      - Cr\ :sub:`32`
+      - Cr\ :sub:`33`
+
+
+**Color Sample Location:**
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * -
+      - 0
+      - 1
+      - 2
+      - 3
+    * - 0
+      - YC
+      - YC
+      - YC
+      - YC
+    * - 1
+      - YC
+      - YC
+      - YC
+      - YC
+    * - 2
+      - YC
+      - YC
+      - YC
+      - YC
+    * - 3
+      - YC
+      - YC
+      - YC
+      - YC
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-yuyv.rst b/Documentation/userspace-api/media/v4l/pixfmt-yuyv.rst
new file mode 100644
index 000000000000..fe70e007787d
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-yuyv.rst
@@ -0,0 +1,125 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-YUYV:
+
+**************************
+V4L2_PIX_FMT_YUYV ('YUYV')
+**************************
+
+
+Packed format with ½ horizontal chroma resolution, also known as YUV
+4:2:2
+
+
+Description
+===========
+
+In this format each four bytes is two pixels. Each four bytes is two
+Y's, a Cb and a Cr. Each Y goes to one of the pixels, and the Cb and Cr
+belong to both pixels. As you can see, the Cr and Cb components have
+half the horizontal resolution of the Y component. ``V4L2_PIX_FMT_YUYV``
+is known in the Windows environment as YUY2.
+
+**Byte Order.**
+Each cell is one byte.
+
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - start + 0:
+      - Y'\ :sub:`00`
+      - Cb\ :sub:`00`
+      - Y'\ :sub:`01`
+      - Cr\ :sub:`00`
+      - Y'\ :sub:`02`
+      - Cb\ :sub:`01`
+      - Y'\ :sub:`03`
+      - Cr\ :sub:`01`
+    * - start + 8:
+      - Y'\ :sub:`10`
+      - Cb\ :sub:`10`
+      - Y'\ :sub:`11`
+      - Cr\ :sub:`10`
+      - Y'\ :sub:`12`
+      - Cb\ :sub:`11`
+      - Y'\ :sub:`13`
+      - Cr\ :sub:`11`
+    * - start + 16:
+      - Y'\ :sub:`20`
+      - Cb\ :sub:`20`
+      - Y'\ :sub:`21`
+      - Cr\ :sub:`20`
+      - Y'\ :sub:`22`
+      - Cb\ :sub:`21`
+      - Y'\ :sub:`23`
+      - Cr\ :sub:`21`
+    * - start + 24:
+      - Y'\ :sub:`30`
+      - Cb\ :sub:`30`
+      - Y'\ :sub:`31`
+      - Cr\ :sub:`30`
+      - Y'\ :sub:`32`
+      - Cb\ :sub:`31`
+      - Y'\ :sub:`33`
+      - Cr\ :sub:`31`
+
+
+**Color Sample Location:**
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * -
+      - 0
+      -
+      - 1
+      -
+      - 2
+      -
+      - 3
+    * - 0
+      - Y
+      - C
+      - Y
+      -
+      - Y
+      - C
+      - Y
+    * - 1
+      - Y
+      - C
+      - Y
+      -
+      - Y
+      - C
+      - Y
+    * - 2
+      - Y
+      - C
+      - Y
+      -
+      - Y
+      - C
+      - Y
+    * - 3
+      - Y
+      - C
+      - Y
+      -
+      - Y
+      - C
+      - Y
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-yvyu.rst b/Documentation/userspace-api/media/v4l/pixfmt-yvyu.rst
new file mode 100644
index 000000000000..96c1b537d5a0
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-yvyu.rst
@@ -0,0 +1,115 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-YVYU:
+
+**************************
+V4L2_PIX_FMT_YVYU ('YVYU')
+**************************
+
+
+Variation of ``V4L2_PIX_FMT_YUYV`` with different order of samples in
+memory
+
+
+Description
+===========
+
+In this format each four bytes is two pixels. Each four bytes is two
+Y's, a Cb and a Cr. Each Y goes to one of the pixels, and the Cb and Cr
+belong to both pixels. As you can see, the Cr and Cb components have
+half the horizontal resolution of the Y component.
+
+**Byte Order.**
+Each cell is one byte.
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - start + 0:
+      - Y'\ :sub:`00`
+      - Cr\ :sub:`00`
+      - Y'\ :sub:`01`
+      - Cb\ :sub:`00`
+      - Y'\ :sub:`02`
+      - Cr\ :sub:`01`
+      - Y'\ :sub:`03`
+      - Cb\ :sub:`01`
+    * - start + 8:
+      - Y'\ :sub:`10`
+      - Cr\ :sub:`10`
+      - Y'\ :sub:`11`
+      - Cb\ :sub:`10`
+      - Y'\ :sub:`12`
+      - Cr\ :sub:`11`
+      - Y'\ :sub:`13`
+      - Cb\ :sub:`11`
+    * - start + 16:
+      - Y'\ :sub:`20`
+      - Cr\ :sub:`20`
+      - Y'\ :sub:`21`
+      - Cb\ :sub:`20`
+      - Y'\ :sub:`22`
+      - Cr\ :sub:`21`
+      - Y'\ :sub:`23`
+      - Cb\ :sub:`21`
+    * - start + 24:
+      - Y'\ :sub:`30`
+      - Cr\ :sub:`30`
+      - Y'\ :sub:`31`
+      - Cb\ :sub:`30`
+      - Y'\ :sub:`32`
+      - Cr\ :sub:`31`
+      - Y'\ :sub:`33`
+      - Cb\ :sub:`31`
+
+
+**Color Sample Location:**
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * -
+      - 0
+      -
+      - 1
+      - 2
+      -
+      - 3
+    * - 0
+      - Y
+      - C
+      - Y
+      - Y
+      - C
+      - Y
+    * - 1
+      - Y
+      - C
+      - Y
+      - Y
+      - C
+      - Y
+    * - 2
+      - Y
+      - C
+      - Y
+      - Y
+      - C
+      - Y
+    * - 3
+      - Y
+      - C
+      - Y
+      - Y
+      - C
+      - Y
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-z16.rst b/Documentation/userspace-api/media/v4l/pixfmt-z16.rst
new file mode 100644
index 000000000000..fe2fb21edeea
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-z16.rst
@@ -0,0 +1,73 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _V4L2-PIX-FMT-Z16:
+
+*************************
+V4L2_PIX_FMT_Z16 ('Z16 ')
+*************************
+
+
+16-bit depth data with distance values at each pixel
+
+
+Description
+===========
+
+This is a 16-bit format, representing depth data. Each pixel is a
+distance to the respective point in the image coordinates. Distance unit
+can vary and has to be negotiated with the device separately. Each pixel
+is stored in a 16-bit word in the little endian byte order.
+
+**Byte Order.**
+Each cell is one byte.
+
+
+
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - start + 0:
+      - Z\ :sub:`00low`
+      - Z\ :sub:`00high`
+      - Z\ :sub:`01low`
+      - Z\ :sub:`01high`
+      - Z\ :sub:`02low`
+      - Z\ :sub:`02high`
+      - Z\ :sub:`03low`
+      - Z\ :sub:`03high`
+    * - start + 8:
+      - Z\ :sub:`10low`
+      - Z\ :sub:`10high`
+      - Z\ :sub:`11low`
+      - Z\ :sub:`11high`
+      - Z\ :sub:`12low`
+      - Z\ :sub:`12high`
+      - Z\ :sub:`13low`
+      - Z\ :sub:`13high`
+    * - start + 16:
+      - Z\ :sub:`20low`
+      - Z\ :sub:`20high`
+      - Z\ :sub:`21low`
+      - Z\ :sub:`21high`
+      - Z\ :sub:`22low`
+      - Z\ :sub:`22high`
+      - Z\ :sub:`23low`
+      - Z\ :sub:`23high`
+    * - start + 24:
+      - Z\ :sub:`30low`
+      - Z\ :sub:`30high`
+      - Z\ :sub:`31low`
+      - Z\ :sub:`31high`
+      - Z\ :sub:`32low`
+      - Z\ :sub:`32high`
+      - Z\ :sub:`33low`
+      - Z\ :sub:`33high`
diff --git a/Documentation/userspace-api/media/v4l/pixfmt.rst b/Documentation/userspace-api/media/v4l/pixfmt.rst
new file mode 100644
index 000000000000..70ca3a5c2cf1
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt.rst
@@ -0,0 +1,45 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _pixfmt:
+
+#############
+Image Formats
+#############
+The V4L2 API was primarily designed for devices exchanging image data
+with applications. The struct :c:type:`v4l2_pix_format` and
+struct :c:type:`v4l2_pix_format_mplane` structures define the
+format and layout of an image in memory. The former is used with the
+single-planar API, while the latter is used with the multi-planar
+version (see :ref:`planar-apis`). Image formats are negotiated with
+the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl. (The explanations here
+focus on video capturing and output, for overlay frame buffer formats
+see also :ref:`VIDIOC_G_FBUF <VIDIOC_G_FBUF>`.)
+
+
+.. toctree::
+    :maxdepth: 1
+
+    pixfmt-v4l2
+    pixfmt-v4l2-mplane
+    pixfmt-intro
+    pixfmt-indexed
+    pixfmt-rgb
+    pixfmt-bayer
+    yuv-formats
+    hsv-formats
+    depth-formats
+    pixfmt-compressed
+    sdr-formats
+    tch-formats
+    meta-formats
+    pixfmt-reserved
+    colorspaces
+    colorspaces-defs
+    colorspaces-details
diff --git a/Documentation/userspace-api/media/v4l/planar-apis.rst b/Documentation/userspace-api/media/v4l/planar-apis.rst
new file mode 100644
index 000000000000..6247b0c4ab4d
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/planar-apis.rst
@@ -0,0 +1,68 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _planar-apis:
+
+*****************************
+Single- and multi-planar APIs
+*****************************
+
+Some devices require data for each input or output video frame to be
+placed in discontiguous memory buffers. In such cases, one video frame
+has to be addressed using more than one memory address, i.e. one pointer
+per "plane". A plane is a sub-buffer of the current frame. For examples
+of such formats see :ref:`pixfmt`.
+
+Initially, V4L2 API did not support multi-planar buffers and a set of
+extensions has been introduced to handle them. Those extensions
+constitute what is being referred to as the "multi-planar API".
+
+Some of the V4L2 API calls and structures are interpreted differently,
+depending on whether single- or multi-planar API is being used. An
+application can choose whether to use one or the other by passing a
+corresponding buffer type to its ioctl calls. Multi-planar versions of
+buffer types are suffixed with an ``_MPLANE`` string. For a list of
+available multi-planar buffer types see enum
+:c:type:`v4l2_buf_type`.
+
+
+Multi-planar formats
+====================
+
+Multi-planar API introduces new multi-planar formats. Those formats use
+a separate set of FourCC codes. It is important to distinguish between
+the multi-planar API and a multi-planar format. Multi-planar API calls
+can handle all single-planar formats as well (as long as they are passed
+in multi-planar API structures), while the single-planar API cannot
+handle multi-planar formats.
+
+
+Calls that distinguish between single and multi-planar APIs
+===========================================================
+
+:ref:`VIDIOC_QUERYCAP <VIDIOC_QUERYCAP>`
+    Two additional multi-planar capabilities are added. They can be set
+    together with non-multi-planar ones for devices that handle both
+    single- and multi-planar formats.
+
+:ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>`, :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`, :ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>`
+    New structures for describing multi-planar formats are added: struct
+    :c:type:`v4l2_pix_format_mplane` and
+    struct :c:type:`v4l2_plane_pix_format`.
+    Drivers may define new multi-planar formats, which have distinct
+    FourCC codes from the existing single-planar ones.
+
+:ref:`VIDIOC_QBUF <VIDIOC_QBUF>`, :ref:`VIDIOC_DQBUF <VIDIOC_QBUF>`, :ref:`VIDIOC_QUERYBUF <VIDIOC_QUERYBUF>`
+    A new struct :c:type:`v4l2_plane` structure for
+    describing planes is added. Arrays of this structure are passed in
+    the new ``m.planes`` field of struct
+    :c:type:`v4l2_buffer`.
+
+:ref:`VIDIOC_REQBUFS <VIDIOC_REQBUFS>`
+    Will allocate multi-planar buffers as requested.
diff --git a/Documentation/userspace-api/media/v4l/querycap.rst b/Documentation/userspace-api/media/v4l/querycap.rst
new file mode 100644
index 000000000000..35fba2a9e09b
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/querycap.rst
@@ -0,0 +1,41 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _querycap:
+
+*********************
+Querying Capabilities
+*********************
+
+Because V4L2 covers a wide variety of devices not all aspects of the API
+are equally applicable to all types of devices. Furthermore devices of
+the same type have different capabilities and this specification permits
+the omission of a few complicated and less important parts of the API.
+
+The :ref:`VIDIOC_QUERYCAP` ioctl is available to
+check if the kernel device is compatible with this specification, and to
+query the :ref:`functions <devices>` and :ref:`I/O methods <io>`
+supported by the device.
+
+Starting with kernel version 3.1, :ref:`VIDIOC_QUERYCAP`
+will return the V4L2 API version used by the driver, with generally
+matches the Kernel version. There's no need of using
+:ref:`VIDIOC_QUERYCAP` to check if a specific ioctl
+is supported, the V4L2 core now returns ``ENOTTY`` if a driver doesn't
+provide support for an ioctl.
+
+Other features can be queried by calling the respective ioctl, for
+example :ref:`VIDIOC_ENUMINPUT` to learn about the
+number, types and names of video connectors on the device. Although
+abstraction is a major objective of this API, the
+:ref:`VIDIOC_QUERYCAP` ioctl also allows driver
+specific applications to reliably identify the driver.
+
+All V4L2 drivers must support :ref:`VIDIOC_QUERYCAP`.
+Applications should always call this ioctl after opening the device.
diff --git a/Documentation/userspace-api/media/v4l/rw.rst b/Documentation/userspace-api/media/v4l/rw.rst
new file mode 100644
index 000000000000..ce2768c994d0
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/rw.rst
@@ -0,0 +1,54 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _rw:
+
+**********
+Read/Write
+**********
+
+Input and output devices support the :ref:`read() <func-read>` and
+:ref:`write() <func-write>` function, respectively, when the
+``V4L2_CAP_READWRITE`` flag in the ``capabilities`` field of struct
+:c:type:`v4l2_capability` returned by the
+:ref:`VIDIOC_QUERYCAP` ioctl is set.
+
+Drivers may need the CPU to copy the data, but they may also support DMA
+to or from user memory, so this I/O method is not necessarily less
+efficient than other methods merely exchanging buffer pointers. It is
+considered inferior though because no meta-information like frame
+counters or timestamps are passed. This information is necessary to
+recognize frame dropping and to synchronize with other data streams.
+However this is also the simplest I/O method, requiring little or no
+setup to exchange data. It permits command line stunts like this (the
+vidctrl tool is fictitious):
+
+
+.. code-block:: none
+
+    $ vidctrl /dev/video --input=0 --format=YUYV --size=352x288
+    $ dd if=/dev/video of=myimage.422 bs=202752 count=1
+
+To read from the device applications use the :ref:`read() <func-read>`
+function, to write the :ref:`write() <func-write>` function. Drivers
+must implement one I/O method if they exchange data with applications,
+but it need not be this. [#f1]_ When reading or writing is supported, the
+driver must also support the :ref:`select() <func-select>` and
+:ref:`poll() <func-poll>` function. [#f2]_
+
+.. [#f1]
+   It would be desirable if applications could depend on drivers
+   supporting all I/O interfaces, but as much as the complex memory
+   mapping I/O can be inadequate for some devices we have no reason to
+   require this interface, which is most useful for simple applications
+   capturing still images.
+
+.. [#f2]
+   At the driver level :ref:`select() <func-select>` and :ref:`poll() <func-poll>` are
+   the same, and :ref:`select() <func-select>` is too important to be optional.
diff --git a/Documentation/userspace-api/media/v4l/sdr-formats.rst b/Documentation/userspace-api/media/v4l/sdr-formats.rst
new file mode 100644
index 000000000000..b7a1be75251f
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/sdr-formats.rst
@@ -0,0 +1,29 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _sdr-formats:
+
+***********
+SDR Formats
+***********
+
+These formats are used for :ref:`SDR <sdr>` interface only.
+
+
+.. toctree::
+    :maxdepth: 1
+
+    pixfmt-sdr-cu08
+    pixfmt-sdr-cu16le
+    pixfmt-sdr-cs08
+    pixfmt-sdr-cs14le
+    pixfmt-sdr-ru12le
+    pixfmt-sdr-pcu16be
+    pixfmt-sdr-pcu18be
+    pixfmt-sdr-pcu20be
diff --git a/Documentation/userspace-api/media/v4l/selection-api-configuration.rst b/Documentation/userspace-api/media/v4l/selection-api-configuration.rst
new file mode 100644
index 000000000000..67ff67fd734e
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/selection-api-configuration.rst
@@ -0,0 +1,144 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+*************
+Configuration
+*************
+
+Applications can use the :ref:`selection API <VIDIOC_G_SELECTION>` to
+select an area in a video signal or a buffer, and to query for default
+settings and hardware limits.
+
+Video hardware can have various cropping, composing and scaling
+limitations. It may only scale up or down, support only discrete scaling
+factors, or have different scaling abilities in the horizontal and
+vertical directions. Also it may not support scaling at all. At the same
+time the cropping/composing rectangles may have to be aligned, and both
+the source and the sink may have arbitrary upper and lower size limits.
+Therefore, as usual, drivers are expected to adjust the requested
+parameters and return the actual values selected. An application can
+control the rounding behaviour using
+:ref:`constraint flags <v4l2-selection-flags>`.
+
+
+Configuration of video capture
+==============================
+
+See figure :ref:`sel-targets-capture` for examples of the selection
+targets available for a video capture device. It is recommended to
+configure the cropping targets before to the composing targets.
+
+The range of coordinates of the top left corner, width and height of
+areas that can be sampled is given by the ``V4L2_SEL_TGT_CROP_BOUNDS``
+target. It is recommended for the driver developers to put the top/left
+corner at position ``(0,0)``. The rectangle's coordinates are expressed
+in pixels.
+
+The top left corner, width and height of the source rectangle, that is
+the area actually sampled, is given by the ``V4L2_SEL_TGT_CROP`` target.
+It uses the same coordinate system as ``V4L2_SEL_TGT_CROP_BOUNDS``. The
+active cropping area must lie completely inside the capture boundaries.
+The driver may further adjust the requested size and/or position
+according to hardware limitations.
+
+Each capture device has a default source rectangle, given by the
+``V4L2_SEL_TGT_CROP_DEFAULT`` target. This rectangle shall cover what the
+driver writer considers the complete picture. Drivers shall set the
+active crop rectangle to the default when the driver is first loaded,
+but not later.
+
+The composing targets refer to a memory buffer. The limits of composing
+coordinates are obtained using ``V4L2_SEL_TGT_COMPOSE_BOUNDS``. All
+coordinates are expressed in pixels. The rectangle's top/left corner
+must be located at position ``(0,0)``. The width and height are equal to
+the image size set by :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`.
+
+The part of a buffer into which the image is inserted by the hardware is
+controlled by the ``V4L2_SEL_TGT_COMPOSE`` target. The rectangle's
+coordinates are also expressed in the same coordinate system as the
+bounds rectangle. The composing rectangle must lie completely inside
+bounds rectangle. The driver must adjust the composing rectangle to fit
+to the bounding limits. Moreover, the driver can perform other
+adjustments according to hardware limitations. The application can
+control rounding behaviour using
+:ref:`constraint flags <v4l2-selection-flags>`.
+
+For capture devices the default composing rectangle is queried using
+``V4L2_SEL_TGT_COMPOSE_DEFAULT``. It is usually equal to the bounding
+rectangle.
+
+The part of a buffer that is modified by the hardware is given by
+``V4L2_SEL_TGT_COMPOSE_PADDED``. It contains all pixels defined using
+``V4L2_SEL_TGT_COMPOSE`` plus all padding data modified by hardware
+during insertion process. All pixels outside this rectangle *must not*
+be changed by the hardware. The content of pixels that lie inside the
+padded area but outside active area is undefined. The application can
+use the padded and active rectangles to detect where the rubbish pixels
+are located and remove them if needed.
+
+
+Configuration of video output
+=============================
+
+For output devices targets and ioctls are used similarly to the video
+capture case. The *composing* rectangle refers to the insertion of an
+image into a video signal. The cropping rectangles refer to a memory
+buffer. It is recommended to configure the composing targets before to
+the cropping targets.
+
+The cropping targets refer to the memory buffer that contains an image
+to be inserted into a video signal or graphical screen. The limits of
+cropping coordinates are obtained using ``V4L2_SEL_TGT_CROP_BOUNDS``.
+All coordinates are expressed in pixels. The top/left corner is always
+point ``(0,0)``. The width and height is equal to the image size
+specified using :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl.
+
+The top left corner, width and height of the source rectangle, that is
+the area from which image date are processed by the hardware, is given
+by the ``V4L2_SEL_TGT_CROP``. Its coordinates are expressed in in the
+same coordinate system as the bounds rectangle. The active cropping area
+must lie completely inside the crop boundaries and the driver may
+further adjust the requested size and/or position according to hardware
+limitations.
+
+For output devices the default cropping rectangle is queried using
+``V4L2_SEL_TGT_CROP_DEFAULT``. It is usually equal to the bounding
+rectangle.
+
+The part of a video signal or graphics display where the image is
+inserted by the hardware is controlled by ``V4L2_SEL_TGT_COMPOSE``
+target. The rectangle's coordinates are expressed in pixels. The
+composing rectangle must lie completely inside the bounds rectangle. The
+driver must adjust the area to fit to the bounding limits. Moreover, the
+driver can perform other adjustments according to hardware limitations.
+
+The device has a default composing rectangle, given by the
+``V4L2_SEL_TGT_COMPOSE_DEFAULT`` target. This rectangle shall cover what
+the driver writer considers the complete picture. It is recommended for
+the driver developers to put the top/left corner at position ``(0,0)``.
+Drivers shall set the active composing rectangle to the default one when
+the driver is first loaded.
+
+The devices may introduce additional content to video signal other than
+an image from memory buffers. It includes borders around an image.
+However, such a padded area is driver-dependent feature not covered by
+this document. Driver developers are encouraged to keep padded rectangle
+equal to active one. The padded target is accessed by the
+``V4L2_SEL_TGT_COMPOSE_PADDED`` identifier. It must contain all pixels
+from the ``V4L2_SEL_TGT_COMPOSE`` target.
+
+
+Scaling control
+===============
+
+An application can detect if scaling is performed by comparing the width
+and the height of rectangles obtained using ``V4L2_SEL_TGT_CROP`` and
+``V4L2_SEL_TGT_COMPOSE`` targets. If these are not equal then the
+scaling is applied. The application can compute the scaling ratios using
+these values.
diff --git a/Documentation/userspace-api/media/v4l/selection-api-examples.rst b/Documentation/userspace-api/media/v4l/selection-api-examples.rst
new file mode 100644
index 000000000000..2f4027211129
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/selection-api-examples.rst
@@ -0,0 +1,91 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+********
+Examples
+********
+
+(A video capture device is assumed; change
+``V4L2_BUF_TYPE_VIDEO_CAPTURE`` for other devices; change target to
+``V4L2_SEL_TGT_COMPOSE_*`` family to configure composing area)
+
+Example: Resetting the cropping parameters
+==========================================
+
+.. code-block:: c
+
+	struct v4l2_selection sel = {
+	    .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
+	    .target = V4L2_SEL_TGT_CROP_DEFAULT,
+	};
+	ret = ioctl(fd, VIDIOC_G_SELECTION, &sel);
+	if (ret)
+	    exit(-1);
+	sel.target = V4L2_SEL_TGT_CROP;
+	ret = ioctl(fd, VIDIOC_S_SELECTION, &sel);
+	if (ret)
+	    exit(-1);
+
+Setting a composing area on output of size of *at most* half of limit
+placed at a center of a display.
+
+Example: Simple downscaling
+===========================
+
+.. code-block:: c
+
+	struct v4l2_selection sel = {
+	    .type = V4L2_BUF_TYPE_VIDEO_OUTPUT,
+	    .target = V4L2_SEL_TGT_COMPOSE_BOUNDS,
+	};
+	struct v4l2_rect r;
+
+	ret = ioctl(fd, VIDIOC_G_SELECTION, &sel);
+	if (ret)
+	    exit(-1);
+	/* setting smaller compose rectangle */
+	r.width = sel.r.width / 2;
+	r.height = sel.r.height / 2;
+	r.left = sel.r.width / 4;
+	r.top = sel.r.height / 4;
+	sel.r = r;
+	sel.target = V4L2_SEL_TGT_COMPOSE;
+	sel.flags = V4L2_SEL_FLAG_LE;
+	ret = ioctl(fd, VIDIOC_S_SELECTION, &sel);
+	if (ret)
+	    exit(-1);
+
+A video output device is assumed; change ``V4L2_BUF_TYPE_VIDEO_OUTPUT``
+for other devices
+
+Example: Querying for scaling factors
+=====================================
+
+.. code-block:: c
+
+	struct v4l2_selection compose = {
+	    .type = V4L2_BUF_TYPE_VIDEO_OUTPUT,
+	    .target = V4L2_SEL_TGT_COMPOSE,
+	};
+	struct v4l2_selection crop = {
+	    .type = V4L2_BUF_TYPE_VIDEO_OUTPUT,
+	    .target = V4L2_SEL_TGT_CROP,
+	};
+	double hscale, vscale;
+
+	ret = ioctl(fd, VIDIOC_G_SELECTION, &compose);
+	if (ret)
+	    exit(-1);
+	ret = ioctl(fd, VIDIOC_G_SELECTION, &crop);
+	if (ret)
+	    exit(-1);
+
+	/* computing scaling factors */
+	hscale = (double)compose.r.width / crop.r.width;
+	vscale = (double)compose.r.height / crop.r.height;
diff --git a/Documentation/userspace-api/media/v4l/selection-api-intro.rst b/Documentation/userspace-api/media/v4l/selection-api-intro.rst
new file mode 100644
index 000000000000..0994ca25be5e
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/selection-api-intro.rst
@@ -0,0 +1,35 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+************
+Introduction
+************
+
+Some video capture devices can sample a subsection of a picture and
+shrink or enlarge it to an image of arbitrary size. Next, the devices
+can insert the image into larger one. Some video output devices can crop
+part of an input image, scale it up or down and insert it at an
+arbitrary scan line and horizontal offset into a video signal. We call
+these abilities cropping, scaling and composing.
+
+On a video *capture* device the source is a video signal, and the
+cropping target determine the area actually sampled. The sink is an
+image stored in a memory buffer. The composing area specifies which part
+of the buffer is actually written to by the hardware.
+
+On a video *output* device the source is an image in a memory buffer,
+and the cropping target is a part of an image to be shown on a display.
+The sink is the display or the graphics screen. The application may
+select the part of display where the image should be displayed. The size
+and position of such a window is controlled by the compose target.
+
+Rectangles for all cropping and composing targets are defined even if
+the device does supports neither cropping nor composing. Their size and
+position will be fixed in such a case. If the device does not support
+scaling then the cropping and composing rectangles have the same size.
diff --git a/Documentation/userspace-api/media/v4l/selection-api-targets.rst b/Documentation/userspace-api/media/v4l/selection-api-targets.rst
new file mode 100644
index 000000000000..56eab969c9d8
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/selection-api-targets.rst
@@ -0,0 +1,27 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+*****************
+Selection targets
+*****************
+
+
+.. _sel-targets-capture:
+
+.. kernel-figure:: selection.svg
+    :alt:   selection.svg
+    :align: center
+
+    Cropping and composing targets
+
+    Targets used by a cropping, composing and scaling process
+
+
+
+See :ref:`v4l2-selection-targets` for more information.
diff --git a/Documentation/userspace-api/media/v4l/selection-api-vs-crop-api.rst b/Documentation/userspace-api/media/v4l/selection-api-vs-crop-api.rst
new file mode 100644
index 000000000000..a9360a000022
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/selection-api-vs-crop-api.rst
@@ -0,0 +1,46 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _selection-vs-crop:
+
+********************************
+Comparison with old cropping API
+********************************
+
+The selection API was introduced to cope with deficiencies of the
+older :ref:`CROP API <crop>`, that was designed to control simple
+capture devices. Later the cropping API was adopted by video output
+drivers. The ioctls are used to select a part of the display were the
+video signal is inserted. It should be considered as an API abuse
+because the described operation is actually the composing. The
+selection API makes a clear distinction between composing and cropping
+operations by setting the appropriate targets.
+
+The CROP API lacks any support for composing to and cropping from an
+image inside a memory buffer. The application could configure a
+capture device to fill only a part of an image by abusing V4L2
+API. Cropping a smaller image from a larger one is achieved by setting
+the field ``bytesperline`` at struct :c:type:`v4l2_pix_format`.
+Introducing an image offsets could be done by modifying field
+``m_userptr`` at struct :c:type:`v4l2_buffer` before calling
+:ref:`VIDIOC_QBUF <VIDIOC_QBUF>`. Those operations should be avoided
+because they are not portable (endianness), and do not work for
+macroblock and Bayer formats and mmap buffers.
+
+The selection API deals with configuration of buffer
+cropping/composing in a clear, intuitive and portable way. Next, with
+the selection API the concepts of the padded target and constraints
+flags are introduced. Finally, struct :c:type:`v4l2_crop` and struct
+:c:type:`v4l2_cropcap` have no reserved fields. Therefore there is no
+way to extend their functionality. The new struct
+:c:type:`v4l2_selection` provides a lot of place for future
+extensions.
+
+Driver developers are encouraged to implement only selection API. The
+former cropping API would be simulated using the new one.
diff --git a/Documentation/userspace-api/media/v4l/selection-api.rst b/Documentation/userspace-api/media/v4l/selection-api.rst
new file mode 100644
index 000000000000..b86e387721df
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/selection-api.rst
@@ -0,0 +1,23 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _selection-api:
+
+Cropping, composing and scaling -- the SELECTION API
+====================================================
+
+
+.. toctree::
+    :maxdepth: 1
+
+    selection-api-intro.rst
+    selection-api-targets.rst
+    selection-api-configuration.rst
+    selection-api-vs-crop-api.rst
+    selection-api-examples.rst
diff --git a/Documentation/userspace-api/media/v4l/selection.svg b/Documentation/userspace-api/media/v4l/selection.svg
new file mode 100644
index 000000000000..c0e00ab2ae6b
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/selection.svg
@@ -0,0 +1,1178 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    This file is dual-licensed: you can use it either under the terms
+    of the GPL 2.0 or the GFDL 1.1+ license, at your option. Note that this
+    dual licensing only applies to this file, and not this project as a
+    whole.
+
+    a) This file is free software; you can redistribute it and/or
+       modify it under the terms of the GNU General Public License as
+       published by the Free Software Foundation version 2 of
+       the License.
+
+       This file is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+    Or, alternatively,
+
+    b) Permission is granted to copy, distribute and/or modify this
+       document under the terms of the GNU Free Documentation License,
+       Version 1.1 or any later version published by the Free Software
+       Foundation, with no Invariant Sections, no Front-Cover Texts
+       and no Back-Cover Texts. A copy of the license is included at
+       Documentation/userspace-api/media/fdl-appendix.rst.
+
+    TODO: replace it to GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
+-->
+<svg enable-background="new" version="1" viewBox="0 0 4226.3 1686.8" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <defs>
+  <pattern id="ig" xlink:href="#ka" patternTransform="matrix(5.4432 0 0 10.1 1722.4 161.06)"/>
+  <marker id="er" overflow="visible" orient="auto">
+   <path d="m-1.2 0l-1 1 3.5-1-3.5-1 1 1z" fill="#f8d615" fill-rule="evenodd" stroke="#f8d615" stroke-width=".2pt"/>
+  </marker>
+  <pattern id="ka" width="2" height="1" patternTransform="scale(10)" patternUnits="userSpaceOnUse">
+   <path d="M0-.5h1v2H0z" fill="#f815bb"/>
+  </pattern>
+  <filter id="ep" x="-.085" y="-.366" width="1.169" height="1.732">
+   <feGaussianBlur stdDeviation="4.574"/>
+  </filter>
+  <linearGradient id="n">
+   <stop stop-color="#fff" offset="0"/>
+   <stop stop-color="#fff" stop-opacity="0" offset="1"/>
+  </linearGradient>
+  <linearGradient id="j">
+   <stop stop-color="#f9eed3" offset="0"/>
+   <stop stop-opacity="0" offset="1"/>
+  </linearGradient>
+  <linearGradient id="s">
+   <stop stop-color="#283131" stop-opacity="0" offset="0"/>
+   <stop stop-color="#1e2424" offset=".5"/>
+   <stop offset="1"/>
+  </linearGradient>
+  <linearGradient id="u">
+   <stop stop-color="#cfc690" offset="0"/>
+   <stop stop-color="#afa775" offset=".212"/>
+   <stop stop-color="#615c3a" offset=".534"/>
+   <stop offset=".765"/>
+   <stop stop-color="#403518" offset="1"/>
+  </linearGradient>
+  <radialGradient id="jd" cx="418.3" cy="342.48" r="131.45" gradientTransform="matrix(1.3957 .62111 -.42441 .95372 -15.062 -227.97)" gradientUnits="userSpaceOnUse">
+   <stop stop-color="#283131" offset="0"/>
+   <stop stop-color="#1e2424" offset=".5"/>
+   <stop offset="1"/>
+  </radialGradient>
+  <filter id="iz" x="-.3" y="-.3" width="1.6" height="1.6">
+   <feGaussianBlur stdDeviation="2"/>
+  </filter>
+  <clipPath id="ea">
+   <path d="M179.64 267.36c-22.41 39.703-60.616 115.78-69.286 149.64-8.647 33.775-8.772 66.417-.357 86.429 8.36 19.882 26.164 35.633 40.714 41.429-.597-14.376 14.373-43.286 72.857-72.5 58.626-29.285 78.382-27.131 103.57-47.143 25.63-20.362 12.61-67.045 3.214-93.929-9.434-26.993-34.967-59.124-66.429-69.643-31.033-10.375-65.018-4.848-84.286 5.714z" fill="#f5ff04" fill-rule="evenodd"/>
+  </clipPath>
+  <radialGradient id="iy" cx="275.44" cy="335.35" r="36.75" gradientTransform="matrix(.05911 2.687 -.72343 .01591 408.73 -424.56)" gradientUnits="userSpaceOnUse">
+   <stop stop-color="#fff" offset="0"/>
+   <stop stop-color="#fff" stop-opacity="0" offset="1"/>
+  </radialGradient>
+  <clipPath id="kb">
+   <path d="m265.94 126.68l-18.767 168.86 174.11-73.121 61.954 88.659 57.884-31.99-37.534-180.06-237.64 27.649z" fill-rule="evenodd" stroke="#000" stroke-width=".9"/>
+  </clipPath>
+  <clipPath id="jz">
+   <path d="M352.25 211.99c-3.804-25.264-16.81-50.638-17.157-75.525-.186-13.356 3.273-26.571 13.756-39.554 36.347-65.296 116.94-84.695 185.93-91.465 86.922-11.017 184.91 17.94 233.37 95.401 54.124 75.733 56.675 172.54 80.612 259.53 29.438 127.13 54.779 256.21 60.392 386.85-3.063 78.182-8.426 165.18-60.503 228.13-48.027 50.357-122.79 50.053-187.07 59.002-90.555 4.655-184.35-16.146-261.78-64.198-64.776-37.94-95.73-113.48-97.279-186.02-8.39-79.875 26.392-153.81 51.62-227.16 7.47-82.761 9.413-166.25 9.653-249.38-.837-32.195-7.09-63.817-11.546-95.609z" enable-background="accumulate" fill="#262f2f" fill-rule="evenodd" stroke="#000"/>
+  </clipPath>
+  <clipPath id="kd">
+   <path d="M352.25 211.99c-3.804-25.264-16.81-50.638-17.157-75.525-.186-13.356 3.273-26.571 13.756-39.554 36.347-65.296 116.94-84.695 185.93-91.465 86.922-11.017 184.91 17.94 233.37 95.401 54.124 75.733 56.675 172.54 80.612 259.53 29.438 127.13 54.779 256.21 60.392 386.85-3.063 78.182-8.426 165.18-60.503 228.13-48.027 50.357-122.79 50.053-187.07 59.002-90.555 4.655-184.35-16.146-261.78-64.198-64.776-37.94-95.73-113.48-97.279-186.02-8.39-79.875 26.392-153.81 51.62-227.16 7.47-82.761 9.413-166.25 9.653-249.38-.837-32.195-7.09-63.817-11.546-95.609z" enable-background="accumulate" fill="#262f2f" fill-rule="evenodd" stroke="#000"/>
+  </clipPath>
+  <clipPath id="jx">
+   <path d="M352.25 211.99c-3.804-25.264-16.81-50.638-17.157-75.525-.186-13.356 3.273-26.571 13.756-39.554 36.347-65.296 116.94-84.695 185.93-91.465 86.922-11.017 184.91 17.94 233.37 95.401 54.124 75.733 56.675 172.54 80.612 259.53 29.438 127.13 54.779 256.21 60.392 386.85-3.063 78.182-8.426 165.18-60.503 228.13-48.027 50.357-122.79 50.053-187.07 59.002-90.555 4.655-184.35-16.146-261.78-64.198-64.776-37.94-95.73-113.48-97.279-186.02-8.39-79.875 26.392-153.81 51.62-227.16 7.47-82.761 9.413-166.25 9.653-249.38-.837-32.195-7.09-63.817-11.546-95.609z" enable-background="accumulate" fill="#262f2f" fill-rule="evenodd" stroke="#000"/>
+  </clipPath>
+  <clipPath id="en">
+   <path d="M352.25 211.99c-3.804-25.264-16.81-50.638-17.157-75.525-.186-13.356 3.273-26.571 13.756-39.554 36.347-65.296 116.94-84.695 185.93-91.465 86.922-11.017 184.91 17.94 233.37 95.401 54.124 75.733 56.675 172.54 80.612 259.53 29.438 127.13 54.779 256.21 60.392 386.85-3.063 78.182-8.426 165.18-60.503 228.13-48.027 50.357-122.79 50.053-187.07 59.002-90.555 4.655-184.35-16.146-261.78-64.198-64.776-37.94-95.73-113.48-97.279-186.02-8.39-79.875 26.392-153.81 51.62-227.16 7.47-82.761 9.413-166.25 9.653-249.38-.837-32.195-7.09-63.817-11.546-95.609z" enable-background="accumulate" fill="#262f2f" fill-rule="evenodd" stroke="#000"/>
+  </clipPath>
+  <clipPath id="jw">
+   <path d="M821.64 477.89s22.619-6.507 35.743-5.873c13.123.634 30.642 1.939 43.709 12.186 13.067 10.248 25.068 27.14 34.112 58.37s1.698 99.252-6.176 143.35-28.265 106.11-45 140-49.798 77.495-60.569 89.876c-11.364 13.062-56.206 36.426-79.431 42.267 5.303-10.607 48.9-50.589 35-60.714-14.019-10.212-45.76 45.982-84.293 29.033 21.382-13.132 41.779-51.186 34.041-66.594-7.84-15.61-30.705 48.758-93.536 37.013 30.052-27.527 55.407-70.904 41.263-82.98-14.415-12.307-60.462 54.293-60.462 54.293s-2.822-41.7 13.773-68.607c16.639-26.978 79.653-81.615 99.553-111.7 19.9-30.088 33.613-66.009 42.135-92.518s15.801-77.1 15.801-77.1" enable-background="new" fill="#202020" fill-rule="evenodd" stroke="#000"/>
+  </clipPath>
+  <clipPath id="kp">
+   <path d="m366.89 504.13s-29.554 40.573-47.857 74.286-58.621 126.36-70.357 171.07c-11.759 44.803-62.5 123.57-62.5 123.57l76.071 18.214s11.807-12.823 31.071-46.071 60.357-138.57 60.357-138.57l13.214-202.5z" enable-background="accumulate" fill="#0f0f0f" fill-rule="evenodd" stroke="#000"/>
+  </clipPath>
+  <clipPath id="eo">
+   <path d="M569.03 1018.8c-4.286.714-27.628 3.618-57.857 10s-99.775 25.962-142.86 35.714-117.26 34.816-156.91 27.265c-39.648-7.55-89.516-64.408-89.516-64.408l4.286-94.286s85.886-16.201 112.14-33.571c26.257-17.37 45.582-49.666 59.286-71.429s32.857-71.429 32.857-71.429l238.57 262.14z" enable-background="accumulate" fill="#0b0b0b" fill-rule="evenodd" stroke="#000"/>
+  </clipPath>
+  <filter id="kc" x="-.353" y="-.182" width="1.706" height="1.363">
+   <feGaussianBlur stdDeviation="48.038"/>
+  </filter>
+  <filter id="jb" x="-.611" y="-.149" width="2.223" height="1.299">
+   <feGaussianBlur stdDeviation="37.83"/>
+  </filter>
+  <filter id="eg" x="-.235" y="-.245" width="1.47" height="1.49">
+   <feGaussianBlur stdDeviation="58.328"/>
+  </filter>
+  <filter id="jy" x="-.205" y="-.29" width="1.409" height="1.58">
+   <feGaussianBlur stdDeviation="22.3"/>
+  </filter>
+  <filter id="jv" x="-.344" y="-.184" width="1.688" height="1.369">
+   <feGaussianBlur stdDeviation="34.542"/>
+  </filter>
+  <filter id="kf" x="-.274" y="-.213" width="1.549" height="1.427">
+   <feGaussianBlur stdDeviation="11.314"/>
+  </filter>
+  <filter id="ja" x="-.259" y="-.224" width="1.518" height="1.447">
+   <feGaussianBlur stdDeviation="19.632"/>
+  </filter>
+  <filter id="kq" x="-.325" y="-.19" width="1.651" height="1.38">
+   <feGaussianBlur stdDeviation="28.713"/>
+  </filter>
+  <filter id="ko" x="-.381" y="-.175" width="1.762" height="1.35">
+   <feGaussianBlur stdDeviation="19.304"/>
+  </filter>
+  <filter id="kv" x="-.211" y="-.168" width="1.422" height="1.336">
+   <feGaussianBlur stdDeviation="8.369"/>
+  </filter>
+  <filter id="ks" x="-.187" y="-.236" width="1.374" height="1.473">
+   <feGaussianBlur stdDeviation="31.212"/>
+  </filter>
+  <clipPath id="ju">
+   <path d="M352.25 211.99c-3.804-25.264-16.81-50.638-17.157-75.525-.186-13.356 3.273-26.571 13.756-39.554 36.347-65.296 116.94-84.695 185.93-91.465 86.922-11.017 184.91 17.94 233.37 95.401 54.124 75.733 56.675 172.54 80.612 259.53 29.438 127.13 54.779 256.21 60.392 386.85-3.063 78.182-8.426 165.18-60.503 228.13-48.027 50.357-122.79 50.053-187.07 59.002-90.555 4.655-184.35-16.146-261.78-64.198-64.776-37.94-95.73-113.48-97.279-186.02-8.39-79.875 26.392-153.81 51.62-227.16 7.47-82.761 9.413-166.25 9.653-249.38-.837-32.195-7.09-63.817-11.546-95.609z" enable-background="accumulate" fill="#262f2f" fill-rule="evenodd" stroke="#000"/>
+  </clipPath>
+  <filter id="ki" x="-.252" y="-.053" width="1.503" height="1.106">
+   <feGaussianBlur stdDeviation="13.025"/>
+  </filter>
+  <linearGradient id="t" x1="603.84" x2="616.24" y1="627.85" y2="585.43" gradientTransform="translate(450.03 73.844)" gradientUnits="userSpaceOnUse">
+   <stop stop-color="#1a1a1a" offset="0"/>
+   <stop stop-color="#1a1a1a" stop-opacity="0" offset="1"/>
+  </linearGradient>
+  <filter id="dq" x="-.329" y="-.182" width="1.657" height="1.364">
+   <feGaussianBlur stdDeviation="20.913"/>
+  </filter>
+  <filter id="dr" x="-.555" y="-.514" width="2.109" height="2.029">
+   <feGaussianBlur stdDeviation="20.913"/>
+  </filter>
+  <filter id="cy" x="-.326" y="-.845" width="1.653" height="2.691">
+   <feGaussianBlur stdDeviation="21.92"/>
+  </filter>
+  <filter id="he" x="-.409" y="-.715" width="1.818" height="2.431">
+   <feGaussianBlur stdDeviation="21.92"/>
+  </filter>
+  <filter id="o">
+   <feGaussianBlur stdDeviation="8.881"/>
+  </filter>
+  <clipPath id="jt">
+   <path d="M647.61 540.05s22.619-6.507 35.743-5.873c13.123.634 30.642 1.939 43.709 12.186 13.067 10.248 25.068 27.14 34.112 58.37s1.698 99.252-6.176 143.35-28.265 106.11-45 140-49.798 77.495-60.569 89.876c-11.364 13.062-56.206 36.426-79.431 42.267 5.303-10.607 48.9-50.589 35-60.714-14.019-10.212-45.76 45.982-84.293 29.033 21.382-13.132 41.779-51.186 34.041-66.594-7.84-15.61-30.705 48.758-93.536 37.013 30.052-27.527 55.407-70.904 41.263-82.98-14.415-12.307-60.462 54.293-60.462 54.293s-2.822-41.7 13.773-68.607c16.639-26.978 79.653-81.615 99.553-111.7 19.9-30.088 33.613-66.009 42.135-92.518s15.801-77.1 15.801-77.1" enable-background="new" fill="#202020" fill-rule="evenodd"/>
+  </clipPath>
+  <filter id="je" x="-.277" y="-.325" width="1.554" height="1.65">
+   <feGaussianBlur stdDeviation="19.956"/>
+  </filter>
+  <clipPath id="e">
+   <path d="M760.16 935.83c6.794 18.903 10.494 33.3 11.89 51.212 1.397 17.912-3.783 51.801-2.9 70.656.881 18.845 8.133 40.099 27.345 48.969 19.419 8.966 49.319 10.211 74.12-3.146 24.8-13.357 57.4-70.326 70.974-97.309 13.624-27.084 38.76-114.5 44.66-149.77 5.9-35.27 2.551-41.3-4.617-49.055 2.64-27.84-1.5-54.935 13.11-87.186-30.249 11.826-37.382 40.161-48.319 65.505-8-50.933.21-71.273 3.319-101.22-29.065 14.778-42.862 47.114-45 92.857-10.924-1.304-21.391-4.434-33.571-.714-.264-46.023-1.464-76.889 8.91-114.21-53.254 21.027-62.946 106.59-56.052 112.78-10.883.535-21.371-1.297-32.857 2.857.638-42.57-.261-84.909-30-122.86 0 0-30.958 80.922-31.43 103.57s9.452 40.166 9.452 40.166-8.568 36.741-6.298 58.232c2.295 21.741 20.443 59.676 27.265 78.658z" enable-background="new" fill="#ada469" fill-rule="evenodd"/>
+  </clipPath>
+  <clipPath id="kr">
+   <path d="m366.89 504.13s-29.554 40.573-47.857 74.286-58.621 126.36-70.357 171.07c-11.759 44.803-62.5 123.57-62.5 123.57l76.071 18.214s11.807-12.823 31.071-46.071 60.357-138.57 60.357-138.57l13.214-202.5z" enable-background="accumulate" fill="#0f0f0f" fill-rule="evenodd"/>
+  </clipPath>
+  <clipPath id="am">
+   <path d="M586.13 997.99c6.794 18.903 10.494 33.3 11.89 51.212 1.397 17.912-3.783 51.801-2.9 70.656.881 18.845 8.133 40.099 27.345 48.969 19.419 8.966 49.319 10.211 74.12-3.146 24.8-13.357 57.4-70.326 70.974-97.309 13.624-27.084 38.76-114.5 44.66-149.77 5.9-35.27 2.551-41.3-4.617-49.055 2.64-27.84-1.5-54.935 13.11-87.186-30.249 11.826-37.382 40.161-48.319 65.505-8-50.933.21-71.273 3.319-101.22-29.065 14.778-42.862 47.114-45 92.857-10.924-1.304-21.391-4.434-33.571-.714-.264-46.023-1.464-76.889 8.91-114.21-53.254 21.027-62.946 106.59-56.052 112.78-10.883.535-21.371-1.297-32.857 2.857.638-42.57-.261-84.909-30-122.86 0 0-30.958 80.922-31.43 103.57s9.452 40.166 9.452 40.166-8.568 36.741-6.298 58.232c2.295 21.741 20.443 59.676 27.265 78.658z" enable-background="new" fill="#ada469" fill-rule="evenodd"/>
+  </clipPath>
+  <filter id="ds">
+   <feGaussianBlur stdDeviation="10.893"/>
+  </filter>
+  <filter id="bz" x="-.495" y="-.267" width="1.99" height="1.534">
+   <feGaussianBlur stdDeviation="10.731"/>
+  </filter>
+  <filter id="by" x="-.406" y="-.303" width="1.812" height="1.605">
+   <feGaussianBlur stdDeviation="9.859"/>
+  </filter>
+  <clipPath id="cj">
+   <path d="M586.13 997.99c6.794 18.903 10.494 33.3 11.89 51.212 1.397 17.912-3.783 51.801-2.9 70.656.881 18.845 8.133 40.099 27.345 48.969 19.419 8.966 49.319 10.211 74.12-3.146 24.8-13.357 57.4-70.326 70.974-97.309 13.624-27.084 38.76-114.5 44.66-149.77 5.9-35.27 2.551-41.3-4.617-49.055 2.64-27.84-1.5-54.935 13.11-87.186-30.249 11.826-37.382 40.161-48.319 65.505-8-50.933.21-71.273 3.319-101.22-29.065 14.778-42.862 47.114-45 92.857-10.924-1.304-21.391-4.434-33.571-.714-.264-46.023-1.464-76.889 8.91-114.21-53.254 21.027-62.946 106.59-56.052 112.78-10.883.535-21.371-1.297-32.857 2.857.638-42.57-.261-84.909-30-122.86 0 0-30.958 80.922-31.43 103.57s9.452 40.166 9.452 40.166-8.568 36.741-6.298 58.232c2.295 21.741 20.443 59.676 27.265 78.658z" enable-background="new" fill="#ada469" fill-rule="evenodd"/>
+  </clipPath>
+  <filter id="il">
+   <feGaussianBlur stdDeviation="3.616"/>
+  </filter>
+  <filter id="ir">
+   <feGaussianBlur stdDeviation="3.864"/>
+  </filter>
+  <clipPath id="ku">
+   <path d="M569.03 1018.8c-4.286.714-27.628 3.618-57.857 10s-57.314 4.966-135.79 17.33c-79.852 12.581-94.064 42.542-108.12 47.064-14.7 4.729-145.38-65.822-145.38-65.822l4.286-94.286s85.886-16.201 112.14-33.571c26.257-17.37 45.582-49.666 59.286-71.429s32.857-71.429 32.857-71.429l238.57 262.14z" enable-background="accumulate" fill="#292929" fill-rule="evenodd" stroke="#000"/>
+  </clipPath>
+  <linearGradient id="dt" x1="699.33" x2="698.98" y1="269.77" y2="346.14" gradientUnits="userSpaceOnUse">
+   <stop stop-color="#fff" offset="0"/>
+   <stop offset="1"/>
+  </linearGradient>
+  <mask id="jc" maskUnits="userSpaceOnUse">
+   <ellipse transform="translate(-174.03 62.156)" cx="579.47" cy="260.58" rx="192.69" ry="164.05" enable-background="accumulate" fill="url(#dt)"/>
+  </mask>
+  <clipPath id="is">
+   <path d="m266.27 924.57c-1.407 18.801-1.145 32.751 2.082 49.303s16.406 45.907 20.334 63.184c3.926 17.267 2.694 38.31-12.46 51.148-15.317 12.977-42.05 21.599-67.831 15.734s-69.55-49.223-88.59-70.228c-19.112-21.083-63.761-93.851-77.94-124.28-14.177-30.425-12.66-36.719-8.119-45.53-9.367-24.52-12.414-50.067-33.712-75.577 30.325 3.114 43.88 26.956 60.126 47.14-5.53-48.076-18.055-64.416-28.374-90.724 29.994 6.082 50.579 31.872 63.98 72.712 9.554-3.918 18.238-9.373 30.187-9.061-11.298-41.696-17.949-69.916-36.687-101.07 53.442 5.67 83.657 80.639 78.971 87.96 9.978-2.243 19.006-6.53 30.437-5.65-11.249-38.348-21.048-76.869-3.66-118.65 0 0 48.287 65.436 54.39 85.805 6.103 20.37 1.52 38.701 1.52 38.701s16.96 31.085 20.293 51.094c3.373 20.241-3.533 59.103-4.946 77.983z" enable-background="new" fill="#ada469" fill-rule="evenodd"/>
+  </clipPath>
+  <clipPath id="im">
+   <path d="M760.16 935.83c6.794 18.903 10.494 33.3 11.89 51.212 1.397 17.912-3.783 51.801-2.9 70.656.881 18.845 8.133 40.099 27.345 48.969 19.419 8.966 49.319 10.211 74.12-3.146 24.8-13.357 57.4-70.326 70.974-97.309 13.624-27.084 38.76-114.5 44.66-149.77 5.9-35.27 2.551-41.3-4.617-49.055 2.64-27.84-1.5-54.935 13.11-87.186-30.249 11.826-37.382 40.161-48.319 65.505-8-50.933.21-71.273 3.319-101.22-29.065 14.778-42.862 47.114-45 92.857-10.924-1.304-21.391-4.434-33.571-.714-.264-46.023-1.464-76.889 8.91-114.21-53.254 21.027-62.946 106.59-56.052 112.78-10.883.535-21.371-1.297-32.857 2.857.638-42.57-.261-84.909-30-122.86 0 0-30.958 80.922-31.43 103.57s9.452 40.166 9.452 40.166-8.568 36.741-6.298 58.232c2.295 21.741 20.443 59.676 27.265 78.658z" enable-background="new" fill="#ada469" fill-rule="evenodd" stroke="#000"/>
+  </clipPath>
+  <filter id="jq" x="-.088" y="-.177" width="1.176" height="1.355">
+   <feGaussianBlur stdDeviation="16.34"/>
+  </filter>
+  <filter id="i">
+   <feTurbulence baseFrequency=".24" numOctaves="10" result="result0" seed="655" type="fractalNoise"/>
+   <feDisplacementMap in="SourceGraphic" in2="result0" scale="62" xChannelSelector="B" yChannelSelector="G"/>
+  </filter>
+  <filter id="em">
+   <feGaussianBlur stdDeviation="2.04"/>
+  </filter>
+  <clipPath id="jo">
+   <path d="m709.29 844.51c54.286-1.429 126.04-15.052 170-26.786 44.053-11.757 125.89-36.347 175.36-57.857 49.339-21.453 113.6-59.282 154.29-92.143 40.508-32.721 52.39-55.82 60.714-33.571 8.37 22.368-16.407 56.326-37.857 81.071-21.604 24.923-52.731 52.705-98.929 89.286s-156.08 101.58-212.86 128.57c-57.066 27.125-128.2 58.238-172.14 72.5s-131.43 31.071-131.43 31.071l92.857-192.14z" enable-background="accumulate" fill="#121212" fill-rule="evenodd"/>
+  </clipPath>
+  <clipPath id="jp">
+   <path d="m709.29 844.51c54.286-1.429 126.04-15.052 170-26.786 44.053-11.757 125.89-36.347 175.36-57.857 49.339-21.453 113.6-59.282 154.29-92.143 40.508-32.721 52.39-55.82 60.714-33.571 8.37 22.368-16.407 56.326-37.857 81.071-21.604 24.923-52.731 52.705-98.929 89.286s-156.08 101.58-212.86 128.57c-57.066 27.125-128.2 58.238-172.14 72.5s-131.43 31.071-131.43 31.071l92.857-192.14z" enable-background="accumulate" fill="#121212" fill-rule="evenodd"/>
+  </clipPath>
+  <clipPath id="js">
+   <path d="m709.29 844.51c54.286-1.429 126.04-15.052 170-26.786 44.053-11.757 125.89-36.347 175.36-57.857 49.339-21.453 113.6-59.282 154.29-92.143 40.508-32.721 52.39-55.82 60.714-33.571 8.37 22.368-16.407 56.326-37.857 81.071-21.604 24.923-52.731 52.705-98.929 89.286s-156.08 101.58-212.86 128.57c-57.066 27.125-128.2 58.238-172.14 72.5s-131.43 31.071-131.43 31.071l92.857-192.14z" enable-background="accumulate" fill="#121212" fill-rule="evenodd"/>
+  </clipPath>
+  <clipPath id="ke">
+   <path d="M178.21 274.15c-3.804-25.264-16.81-50.638-17.157-75.525-.186-13.356 3.273-26.571 13.756-39.554 36.347-65.296 116.94-84.695 185.93-91.465 86.922-11.017 184.91 17.94 233.37 95.401 54.124 75.733 56.675 172.54 80.612 259.53 29.438 127.13 54.779 256.21 60.392 386.85-3.063 78.182-8.426 165.18-60.503 228.13-48.027 50.357-122.79 50.053-187.07 59.002-90.555 4.655-184.35-16.146-261.78-64.198-64.776-37.94-95.73-113.48-97.279-186.02-8.39-79.875 26.392-153.81 51.62-227.16 7.47-82.761 9.413-166.25 9.653-249.38-.837-32.195-7.09-63.817-11.546-95.609z" enable-background="accumulate" fill="#262f2f" fill-rule="evenodd"/>
+  </clipPath>
+  <filter id="iv" x="-.243" y="-.391" width="1.487" height="1.782">
+   <feGaussianBlur stdDeviation="14.59"/>
+  </filter>
+  <filter id="iu" x="-.146" y="-.235" width="1.292" height="1.47">
+   <feGaussianBlur stdDeviation="4.444"/>
+  </filter>
+  <filter id="it">
+   <feGaussianBlur stdDeviation=".606"/>
+  </filter>
+  <filter id="ix">
+   <feGaussianBlur stdDeviation="6.589"/>
+  </filter>
+  <filter id="iw">
+   <feGaussianBlur stdDeviation="1.505"/>
+  </filter>
+  <filter id="jj" x="-.103" y="-.342" width="1.206" height="1.685">
+   <feGaussianBlur stdDeviation="1.168"/>
+  </filter>
+  <filter id="jf" x="-.098" y="-.198" width="1.197" height="1.395">
+   <feGaussianBlur stdDeviation="1.168"/>
+  </filter>
+  <filter id="jh" x="-.098" y="-.198" width="1.196" height="1.397">
+   <feGaussianBlur stdDeviation="1.168"/>
+  </filter>
+  <filter id="ji" x="-.099" y="-.226" width="1.198" height="1.453">
+   <feGaussianBlur stdDeviation="1.168"/>
+  </filter>
+  <filter id="hy" x="-.099" y="-.225" width="1.198" height="1.451">
+   <feGaussianBlur stdDeviation="1.168"/>
+  </filter>
+  <filter id="hu" x="-.105" y="-.405" width="1.209" height="1.809">
+   <feGaussianBlur stdDeviation="1.168"/>
+  </filter>
+  <filter id="hv" x="-.103" y="-.364" width="1.207" height="1.729">
+   <feGaussianBlur stdDeviation="1.168"/>
+  </filter>
+  <filter id="hw" x="-.102" y="-.324" width="1.204" height="1.647">
+   <feGaussianBlur stdDeviation="1.168"/>
+  </filter>
+  <filter id="hx" x="-.101" y="-.274" width="1.201" height="1.548">
+   <feGaussianBlur stdDeviation="1.168"/>
+  </filter>
+  <filter id="hz" x="-.098" y="-.209" width="1.197" height="1.417">
+   <feGaussianBlur stdDeviation="1.168"/>
+  </filter>
+  <filter id="ia" x="-.098" y="-.203" width="1.197" height="1.406">
+   <feGaussianBlur stdDeviation="1.168"/>
+  </filter>
+  <filter id="ib" x="-.098" y="-.198" width="1.196" height="1.397">
+   <feGaussianBlur stdDeviation="1.168"/>
+  </filter>
+  <filter id="jg">
+   <feGaussianBlur stdDeviation="1.168"/>
+  </filter>
+  <filter id="jk">
+   <feGaussianBlur stdDeviation="1.168"/>
+  </filter>
+  <filter id="hr" x="-.031" y="-.103" width="1.062" height="1.205">
+   <feGaussianBlur stdDeviation=".35"/>
+  </filter>
+  <filter id="hq">
+   <feGaussianBlur stdDeviation=".35"/>
+  </filter>
+  <filter id="hp">
+   <feGaussianBlur stdDeviation=".35"/>
+  </filter>
+  <filter id="hn">
+   <feGaussianBlur stdDeviation=".35"/>
+  </filter>
+  <filter id="hm">
+   <feGaussianBlur stdDeviation=".35"/>
+  </filter>
+  <filter id="hl">
+   <feGaussianBlur stdDeviation=".35"/>
+  </filter>
+  <filter id="hk">
+   <feGaussianBlur stdDeviation=".35"/>
+  </filter>
+  <filter id="hj">
+   <feGaussianBlur stdDeviation=".35"/>
+  </filter>
+  <filter id="hi">
+   <feGaussianBlur stdDeviation=".35"/>
+  </filter>
+  <filter id="hh">
+   <feGaussianBlur stdDeviation=".35"/>
+  </filter>
+  <filter id="hf" x="-.031" y="-.121" width="1.063" height="1.243">
+   <feGaussianBlur stdDeviation=".35"/>
+  </filter>
+  <filter id="hg" x="-.031" y="-.109" width="1.062" height="1.219">
+   <feGaussianBlur stdDeviation=".35"/>
+  </filter>
+  <filter id="hs">
+   <feGaussianBlur stdDeviation=".35"/>
+  </filter>
+  <filter id="ho">
+   <feGaussianBlur stdDeviation=".35"/>
+  </filter>
+  <filter id="ht">
+   <feGaussianBlur stdDeviation="1.723"/>
+  </filter>
+  <clipPath id="jl">
+   <path transform="translate(.08 -.031)" d="M1111.4-285.94l-3.937 1.875c-.041.01-.1.02-.125.031-.42.213-.165.1-.657.313-.486.21-1.737.584-4.093 1.469-3.332 1.25-5.805 2.15-7 3.062-1.537.021-3.72.233-5.657.719a227.677 227.677 0 0 1-6.75 1.594c-1.895.42-1.675.642-2.875.875-1.296.251-1.721-.01-5.437.78-3.49.743-8.895 1.932-10.156 2.688-1.584-.18-3.868-.321-5.844-.03-3.04.446-4.916.672-6.844.905-.655.08-1.04.201-1.344.282-.426.131-.685.26-1.375.343-1.311.16-1.762-.156-5.53.282-3.555.413-9.006 1.272-10.25 1.937-1.6-.297-3.859-.534-5.845-.344-3.058.294-4.972.484-6.906.657-1.934.172-1.688.422-2.906.53-1.316.119-1.76-.163-5.531.25-3.542.39-9.008 1.21-10.281 1.876-1.6-.295-3.887-.507-5.875-.313-3.059.3-4.941.48-6.875.657-.658.06-1.04.178-1.344.25-.428.119-.683.218-1.375.28-1.316.121-1.76-.194-5.531.22-3.556.39-9.006 1.239-10.25
+1.906-1.599-.294-3.86-.524-5.844-.313-3.056.326-4.974.527-6.906.719s-1.69.44-2.906.563c-1.315.131-1.763-.165-5.532.28-3.539.42-8.977 1.293-10.25 1.97-1.597-.281-3.86-.42-5.843-.188-3.052.358-4.945.568-6.875.781-.657.073-1.041.173-1.344.25-.427.128-.685.268-1.375.344-1.314.146-1.768-.174-5.531.313-3.55.458-8.979 1.419-10.22 2.125-1.593-.245-3.833-.382-5.812-.125-3.048.394-4.95.648-6.875.906-1.924.258-1.726.493-2.937.656-1.31.176-1.748-.104-5.5.469-3.525.538-8.924 1.699-10.188 2.437-1.588-.203-3.846-.254-5.813.094-3.026.536-4.899.862-6.812 1.188-.651.11-1.014.27-1.313.375-.42.164-.663.33-1.344.468-1.294.262-1.727-.006-5.437.813-3.499.772-8.846 2.383-10.062 3.219-1.563-.078-3.758.085-5.688.593-2.972.783-4.817 1.232-6.687 1.75s-1.667.768-2.844 1.094c-1.273.353-1.697.107-5.344 1.188-3.425 1.014-8.65 2.933-9.875 3.843-1.539.013-3.72.273-5.625.875-2.93.928-4.75 1.459-6.594
+2.063-.626.205-.991.393-1.28.531-.408.214-.654.409-1.313.625-1.255.412-1.687.19-5.282 1.438-3.39 1.177-8.595 3.213-9.78 4.156-1.525.06-3.65.395-5.532 1.062-2.897 1.029-4.699 1.676-6.531 2.313-1.832.637-1.628.848-2.781 1.25-1.247.434-1.664.2-5.22 1.562-3.338 1.28-8.486 3.483-9.687 4.47-1.507.107-3.635.498-5.5 1.218a1047.26 1047.26 0 0 1-6.437 2.469c-.617.233-.997.442-1.281.594v.03l-8 3.188 1.812 14.72c-.258-.062 6.188 3.312 6.188 3.312.226-.145.449-.273.718-.375 1.08-.41 2.172-.216 6-1.688 3.829-1.471 5.224-2.005 5.907-2.406.68-.4 1.611-.88 2.218-1.531 1.827-.138 3.571-.493 4.938-1 2.968-1.1 4.875-1.806 6.781-2.469 1.906-.662 2.354-1.415 3.406-1.781 1.092-.38 2.195-.166 6.063-1.531 3.867-1.366 5.283-1.827 5.969-2.22.7-.4 1.7-.932 2.312-1.593 1.97-.055 3.817-.385 5.281-.875 3.002-1.005 4.927-1.622 6.844-2.25 1.539-.504 2.174-1.047 2.906-1.437.23-.135.476-.254.75-.344 1.099-.36 2.182-.082
+6.094-1.313 3.912-1.23 5.366-1.673 6.063-2.03.694-.358 1.63-.794 2.25-1.407 1.865-.023 3.635-.267 5.03-.688 3.031-.913 4.993-1.43 6.938-1.968 1.945-.539 2.427-1.265 3.5-1.563 1.114-.31 2.22.007 6.188-1.031 3.967-1.039 5.417-1.433 6.125-1.75.735-.33 1.814-.754 2.437-1.375 1.998.116 3.858-.02 5.344-.375 3.078-.735 5.084-1.101 7.063-1.5 1.588-.32 2.244-.79 3-1.094a3.4 3.4 0 0 1 .75-.25c1.133-.23 2.304.209 6.343-.5 4.04-.709 5.5-.927 6.22-1.187.715-.26 1.704-.568 2.343-1.094 1.924.24 3.748.224 5.188 0 3.126-.488 5.154-.7 7.156-.969 2.001-.268 2.489-.945 3.594-1.094 1.146-.154 2.275.302 6.343-.219 4.068-.52 5.56-.695 6.282-.937.737-.247 1.798-.586 2.437-1.125 2.05.336 3.974.398 5.5.219 3.142-.37 5.18-.56 7.188-.782 1.61-.178 2.264-.608 3.03-.843.242-.086.495-.156.782-.188 1.15-.127 2.301.347 6.375-.125s5.559-.61 6.281-.844c.72-.232 1.7-.473 2.344-.968 1.936.333 3.77.404 5.219.25 3.146-.335
+5.177-.519 7.187-.719 2.01-.2 2.484-.826 3.594-.938 1.151-.115 2.297.366 6.375-.062s5.589-.562 6.313-.781c.739-.224 1.795-.514 2.437-1.031 2.057.398 4.002.493 5.531.343 3.149-.308 5.176-.473 7.188-.656 1.614-.147 2.263-.56 3.031-.781.241-.081.494-.13.781-.156 1.152-.106 2.293.392 6.375 0s5.59-.531 6.313-.75c.72-.219 1.7-.448 2.343-.938 1.939.35 3.77.454 5.22.313 3.148-.309 5.175-.474 7.187-.657 2.011-.183 2.514-.838 3.625-.937 1.152-.103 2.292.385 6.375 0s5.588-.501 6.312-.719c.74-.222 1.796-.514 2.438-1.031 2.057.402 4.003.503 5.531.344 3.147-.329 5.177-.523 7.187-.72 1.613-.156 2.266-.63 3.032-.874.24-.088.463-.122.75-.156 1.148-.14 2.316.34 6.375-.25 4.058-.59 5.562-.778 6.281-1.032.717-.253 1.675-.558 2.312-1.093 1.92.212 3.72.151 5.157-.094 3.119-.533 5.111-.929 7.093-1.313 1.983-.383 2.475-1.04 3.563-1.28 1.129-.251 2.27.115 6.25-.876s5.43-1.42 6.125-1.781c.722-.376 1.762-.87
+2.375-1.531 1.963-.012 3.794-.291 5.219-.844 2.95-1.145 4.873-1.87 6.687-2.75 1.456-.706 2.32-1.702 2.531-2 .213-.298.1-.729.125-.75.043-.035.34-.094.5-.437.86-1.848 2.324-5.628 2.438-6.313.114-.682.168-1.353.219-1.75.029-.23-.147-.879-.125-.937.03-.082.288-.251.343-.5.267-1.199.09-2.208-.125-3.625-.213-1.418-.971-4.615-1.625-5.47-.658-.861-1.224-1.01-1.75-1z" enable-background="new" fill="#bcb786" fill-rule="evenodd"/>
+  </clipPath>
+  <filter id="kk" x="-.082" y="-.227" width="1.163" height="1.453">
+   <feGaussianBlur stdDeviation="2.437"/>
+  </filter>
+  <filter id="kj" x="-.041" y="-.113" width="1.082" height="1.227">
+   <feGaussianBlur stdDeviation="1.219"/>
+  </filter>
+  <clipPath id="kl">
+   <path d="M1049.2-282.27l-.09.008c-1.387.884-6.603 1.607-6.629 9.523-.024 7.426 15.013 17.091 17.156 18.094 1.73.81 3.592 1.41 5.406 1.72l1.438.218c1.92.212 3.72.151 5.156-.094 3.12-.532 5.112-.928 7.094-1.312 1.982-.384 2.474-1.04 3.562-1.281 1.129-.251 2.27.116 6.25-.875 3.98-.992 5.43-1.42 6.125-1.782.723-.376 1.762-.87 2.375-1.53 1.963-.013 3.794-.292 5.219-.845 2.951-1.144 4.873-1.869 6.688-2.75 1.455-.706 2.319-1.702 2.53-2 .213-.298.1-.728.126-.75.043-.035.34-.094.5-.437.859-1.847 2.323-5.628 2.437-6.313.114-.682.168-1.352.219-1.75.029-.23-.147-.879-.125-.937.031-.082.288-.25.344-.5.266-1.198.089-2.208-.125-3.625-.214-1.418-.972-4.615-1.625-5.469-.42-.548-.8-.792-1.157-.906-.067-.017-.123-.047-.187-.063-.021-.004-.042.003-.062 0-.312-.075-.609-.158-1.156-.218-.986-.109-2.425-.26-3.969-.25-.515.003-1.037.047-1.563.093-3.558.313-9.01.991-10.218
+1.625-1.634-.334-3.949-.612-5.938-.468-3.064.22-4.968.342-6.906.468-1.939.127-1.686.389-2.906.469-1.32.087-1.787-.223-5.563.094-3.546.297-8.98.993-10.22 1.625-1.632-.335-3.945-.613-5.937-.469-3.064.221-4.967.373-6.906.5-.659.043-1.042.124-1.344.187z" enable-background="new" fill="#bcb786" fill-rule="evenodd" opacity=".824"/>
+  </clipPath>
+  <filter id="km" x="-.022" width="1.044">
+   <feGaussianBlur stdDeviation=".575"/>
+  </filter>
+  <clipPath id="kn">
+   <path d="M205.47-408.97l-.09.002c-1.446.786-6.7 1.143-7.276 9.039-.542 7.405 13.786 18.096 15.854 19.245 1.67.927 3.484 1.655 5.273 2.09l1.419.32c1.9.344 3.7.41 5.15.265 3.149-.314 5.164-.57 7.168-.815 2.004-.245 2.54-.865 3.643-1.03 1.144-.172 2.257.274 6.296-.438s5.515-1.038 6.234-1.35c.747-.325 1.818-.746 2.476-1.362 1.96.124 3.805-.026 5.265-.479 3.024-.936 4.991-1.525 6.863-2.277 1.501-.603 2.432-1.536 2.664-1.819.233-.282.15-.72.177-.74.045-.032.346-.07.53-.4.985-1.784 2.709-5.453 2.87-6.128.162-.673.263-1.338.34-1.73.046-.228-.085-.888-.059-.945.037-.08.305-.23.378-.475.35-1.177.243-2.195.128-3.625-.115-1.429-.648-4.67-1.24-5.568-.38-.577-.742-.846-1.09-.985-.066-.022-.12-.055-.183-.075-.02-.005-.042 0-.063-.004-.305-.097-.596-.2-1.138-.299-.975-.176-2.4-.428-3.942-.526a19.346 19.346 0 0
+0-1.565-.015c-3.572.064-9.057.361-10.307.91-1.606-.448-3.896-.886-5.89-.882-3.072.007-4.98-.005-6.922-.013-1.943-.01-1.71.27-2.932.265-1.322-.005-1.767-.347-5.556-.294-3.558.05-9.028.365-10.307.91-1.606-.448-3.893-.887-5.89-.882-3.072.007-4.982.027-6.924.018-.661-.003-1.049.05-1.354.093z" enable-background="new" fill="#bcb786" fill-rule="evenodd" opacity=".824"/>
+  </clipPath>
+  <linearGradient id="w" x1="774.98" x2="755.12" y1="-211.87" y2="-202.68" gradientTransform="translate(-19.092 4.243)" gradientUnits="userSpaceOnUse" xlink:href="#n"/>
+  <mask id="jm" maskUnits="userSpaceOnUse">
+   <path d="m718.41-224.31l33.25 56 276-24 159.5-48.25-66.5-82.75-402.25 99z" fill="url(#w)" fill-rule="evenodd"/>
+  </mask>
+  <clipPath id="kg">
+   <path d="M734.03 519.49s16.755 37.018 28.701 53.954 52.727 56.046 52.727 56.046l.597-138.59" enable-background="accumulate" fill="#1a1a1a" fill-rule="evenodd" stroke="#000"/>
+  </clipPath>
+  <filter id="jn">
+   <feGaussianBlur stdDeviation="10.662"/>
+  </filter>
+  <filter id="ip">
+   <feGaussianBlur stdDeviation="7.18"/>
+  </filter>
+  <clipPath id="iq">
+   <path d="m266.27 924.57c-1.407 18.801-1.145 32.751 2.082 49.303 3.226 16.552 16.406 45.907 20.334 63.184 3.926 17.267 2.694 38.31-12.46 51.148-15.317 12.978-42.05 21.599-67.831 15.734s-69.55-49.223-88.59-70.228c-19.112-21.083-63.761-93.851-77.94-124.28-14.177-30.425-12.66-36.719-8.119-45.53-9.367-24.52-12.414-50.067-33.712-75.577 30.325 3.114 43.88 26.956 60.126 47.14-5.53-48.076-18.055-64.417-28.374-90.724 29.994 6.082 50.579 31.872 63.98 72.712 9.554-3.918 18.238-9.373 30.187-9.061-11.298-41.696-17.949-69.916-36.687-101.07 53.442 5.67 83.657 80.639 78.971 87.96 9.978-2.243 19.006-6.53 30.437-5.65-11.249-38.348-21.048-76.869-3.66-118.65 0 0 48.287 65.436 54.39 85.805 6.103 20.37 1.52 38.701 1.52 38.701s16.96 31.085 20.293 51.094c3.373 20.241-3.533 59.103-4.946 77.983z" enable-background="new" fill="#ada469" fill-rule="evenodd"/>
+  </clipPath>
+  <filter id="in">
+   <feGaussianBlur stdDeviation="6.82"/>
+  </filter>
+  <clipPath id="io">
+   <path d="m266.27 924.57c-1.407 18.801-1.145 32.751 2.082 49.303 3.226 16.552 16.406 45.907 20.334 63.184 3.926 17.267 2.694 38.31-12.46 51.148-15.317 12.978-42.05 21.599-67.831 15.734s-69.55-49.223-88.59-70.228c-19.112-21.083-63.761-93.851-77.94-124.28-14.177-30.425-12.66-36.719-8.119-45.53-9.367-24.52-12.414-50.067-33.712-75.577 30.325 3.114 43.88 26.956 60.126 47.14-5.53-48.076-18.055-64.417-28.374-90.724 29.994 6.082 50.579 31.872 63.98 72.712 9.554-3.918 18.238-9.373 30.187-9.061-11.298-41.696-17.949-69.916-36.687-101.07 53.442 5.67 83.657 80.639 78.971 87.96 9.978-2.243 19.006-6.53 30.437-5.65-11.249-38.348-21.048-76.869-3.66-118.65 0 0 48.287 65.436 54.39 85.805 6.103 20.37 1.52 38.701 1.52 38.701s16.96 31.085 20.293 51.094c3.373 20.241-3.533 59.103-4.946 77.983z" enable-background="new" fill="#ada469" fill-rule="evenodd"/>
+  </clipPath>
+  <filter id="ij" x="-.144" y="-.103" width="1.288" height="1.206">
+   <feGaussianBlur stdDeviation="7.389"/>
+  </filter>
+  <clipPath id="ik">
+   <path d="M760.16 935.83c6.794 18.903 10.494 33.3 11.89 51.212 1.397 17.912-3.783 51.801-2.9 70.656.881 18.845 8.133 40.099 27.345 48.969 19.419 8.966 49.319 10.211 74.12-3.146 24.8-13.357 57.4-70.326 70.974-97.309 13.624-27.084 38.76-114.5 44.66-149.77 5.9-35.27 2.551-41.3-4.617-49.055 2.64-27.84-1.5-54.935 13.11-87.186-30.249 11.826-37.382 40.161-48.319 65.505-8-50.933.21-71.273 3.319-101.22-29.065 14.778-42.862 47.114-45 92.857-10.924-1.304-21.391-4.434-33.571-.714-.264-46.023-1.464-76.889 8.91-114.21-53.254 21.027-62.946 106.59-56.052 112.78-10.883.535-21.371-1.297-32.857 2.857.638-42.57-.261-84.909-30-122.86 0 0-30.958 80.922-31.43 103.57s9.452 40.166 9.452 40.166-8.568 36.741-6.298 58.232c2.295 21.741 20.443 59.676 27.265 78.658z" enable-background="new" fill="#ada469" fill-rule="evenodd"/>
+  </clipPath>
+  <filter id="ih" x="-.09" y="-.103" width="1.181" height="1.205">
+   <feGaussianBlur stdDeviation="5.346"/>
+  </filter>
+  <clipPath id="ii">
+   <path d="M760.16 935.83c6.794 18.903 10.494 33.3 11.89 51.212 1.397 17.912-3.783 51.801-2.9 70.656.881 18.845 8.133 40.099 27.345 48.969 19.419 8.966 49.319 10.211 74.12-3.146 24.8-13.357 57.4-70.326 70.974-97.309 13.624-27.084 38.76-114.5 44.66-149.77 5.9-35.27 2.551-41.3-4.617-49.055 2.64-27.84-1.5-54.935 13.11-87.186-30.249 11.826-37.382 40.161-48.319 65.505-8-50.933.21-71.273 3.319-101.22-29.065 14.778-42.862 47.114-45 92.857-10.924-1.304-21.391-4.434-33.571-.714-.264-46.023-1.464-76.889 8.91-114.21-53.254 21.027-62.946 106.59-56.052 112.78-10.883.535-21.371-1.297-32.857 2.857.638-42.57-.261-84.909-30-122.86 0 0-30.958 80.922-31.43 103.57s9.452 40.166 9.452 40.166-8.568 36.741-6.298 58.232c2.295 21.741 20.443 59.676 27.265 78.658z" enable-background="new" fill="#ada469" fill-rule="evenodd"/>
+  </clipPath>
+  <clipPath id="gc">
+   <path d="M569.03 1018.8c-4.286.714-27.628 3.618-57.857 10s-99.775 25.962-142.86 35.714-117.26 34.816-156.91 27.265c-39.648-7.55-89.516-64.408-89.516-64.408l4.286-94.286s85.886-16.201 112.14-33.571c26.257-17.37 45.582-49.666 59.286-71.429s32.857-71.429 32.857-71.429l238.57 262.14z" enable-background="accumulate" fill="#0b0b0b" fill-rule="evenodd" stroke="#000"/>
+  </clipPath>
+  <filter id="gb" x="-.211" y="-.168" width="1.422" height="1.336">
+   <feGaussianBlur stdDeviation="8.369"/>
+  </filter>
+  <clipPath id="fz">
+   <path d="M205.47-408.97l-.09.002c-1.446.786-6.7 1.143-7.276 9.039-.542 7.405 13.786 18.096 15.854 19.245 1.67.927 3.484 1.655 5.273 2.09l1.419.32c1.9.344 3.7.41 5.15.265 3.149-.314 5.164-.57 7.168-.815 2.004-.245 2.54-.865 3.643-1.03 1.144-.172 2.257.274 6.296-.438s5.515-1.038 6.234-1.35c.747-.325 1.818-.746 2.476-1.362 1.96.124 3.805-.026 5.265-.479 3.024-.936 4.991-1.525 6.863-2.277 1.501-.603 2.432-1.536 2.664-1.819.233-.282.15-.72.177-.74.045-.032.346-.07.53-.4.985-1.784 2.709-5.453 2.87-6.128.162-.673.263-1.338.34-1.73.046-.228-.085-.888-.059-.945.037-.08.305-.23.378-.475.35-1.177.243-2.195.128-3.625-.115-1.429-.648-4.67-1.24-5.568-.38-.577-.742-.846-1.09-.985-.066-.022-.12-.055-.183-.075-.02-.005-.042 0-.063-.004-.305-.097-.596-.2-1.138-.299-.975-.176-2.4-.428-3.942-.526a19.346 19.346 0 0
+0-1.565-.015c-3.572.064-9.057.361-10.307.91-1.606-.448-3.896-.886-5.89-.882-3.072.007-4.98-.005-6.922-.013-1.943-.01-1.71.27-2.932.265-1.322-.005-1.767-.347-5.556-.294-3.558.05-9.028.365-10.307.91-1.606-.448-3.893-.887-5.89-.882-3.072.007-4.982.027-6.924.018-.661-.003-1.049.05-1.354.093z" enable-background="new" fill="#bcb786" fill-rule="evenodd" opacity=".824"/>
+  </clipPath>
+  <filter id="fy" x="-.022" width="1.044">
+   <feGaussianBlur stdDeviation=".575"/>
+  </filter>
+  <clipPath id="fx">
+   <path d="M1049.2-282.27l-.09.008c-1.387.884-6.603 1.607-6.629 9.523-.024 7.426 15.013 17.091 17.156 18.094 1.73.81 3.592 1.41 5.406 1.72l1.438.218c1.92.212 3.72.151 5.156-.094 3.12-.532 5.112-.928 7.094-1.312 1.982-.384 2.474-1.04 3.562-1.281 1.129-.251 2.27.116 6.25-.875 3.98-.992 5.43-1.42 6.125-1.782.723-.376 1.762-.87 2.375-1.53 1.963-.013 3.794-.292 5.219-.845 2.951-1.144 4.873-1.869 6.688-2.75 1.455-.706 2.319-1.702 2.53-2 .213-.298.1-.728.126-.75.043-.035.34-.094.5-.437.859-1.847 2.323-5.628 2.437-6.313.114-.682.168-1.352.219-1.75.029-.23-.147-.879-.125-.937.031-.082.288-.25.344-.5.266-1.198.089-2.208-.125-3.625-.214-1.418-.972-4.615-1.625-5.469-.42-.548-.8-.792-1.157-.906-.067-.017-.123-.047-.187-.063-.021-.004-.042.003-.062 0-.312-.075-.609-.158-1.156-.218-.986-.109-2.425-.26-3.969-.25-.515.003-1.037.047-1.563.093-3.558.313-9.01.991-10.218
+1.625-1.634-.334-3.949-.612-5.938-.468-3.064.22-4.968.342-6.906.468-1.939.127-1.686.389-2.906.469-1.32.087-1.787-.223-5.563.094-3.546.297-8.98.993-10.22 1.625-1.632-.335-3.945-.613-5.937-.469-3.064.221-4.967.373-6.906.5-.659.043-1.042.124-1.344.187z" enable-background="new" fill="#bcb786" fill-rule="evenodd" opacity=".824"/>
+  </clipPath>
+  <filter id="fw" x="-.082" y="-.227" width="1.163" height="1.453">
+   <feGaussianBlur stdDeviation="2.437"/>
+  </filter>
+  <filter id="fv" x="-.041" y="-.113" width="1.082" height="1.227">
+   <feGaussianBlur stdDeviation="1.219"/>
+  </filter>
+  <clipPath id="y">
+   <path d="M352.25 211.99c-3.804-25.264-16.81-50.638-17.157-75.525-.186-13.356 3.273-26.571 13.756-39.554 36.347-65.296 116.94-84.695 185.93-91.465 86.922-11.017 184.91 17.94 233.37 95.401 54.124 75.733 56.675 172.54 80.612 259.53 29.438 127.13 54.779 256.21 60.392 386.85-3.063 78.182-8.426 165.18-60.503 228.13-48.027 50.357-122.79 50.053-187.07 59.002-90.555 4.655-184.35-16.146-261.78-64.198-64.776-37.94-95.73-113.48-97.279-186.02-8.39-79.875 26.392-153.81 51.62-227.16 7.47-82.761 9.413-166.25 9.653-249.38-.837-32.195-7.09-63.817-11.546-95.609z" enable-background="accumulate" fill="#262f2f" fill-rule="evenodd" stroke="#000"/>
+  </clipPath>
+  <filter id="fu" x="-.252" y="-.053" width="1.503" height="1.106">
+   <feGaussianBlur stdDeviation="13.025"/>
+  </filter>
+  <clipPath id="fs">
+   <path d="M734.03 519.49s16.755 37.018 28.701 53.954 52.727 56.046 52.727 56.046l.597-138.59" enable-background="accumulate" fill="#1a1a1a" fill-rule="evenodd" stroke="#000"/>
+  </clipPath>
+  <filter id="fr" x="-.274" y="-.213" width="1.549" height="1.427">
+   <feGaussianBlur stdDeviation="11.314"/>
+  </filter>
+  <clipPath id="fq">
+   <path d="M178.21 274.15c-3.804-25.264-16.81-50.638-17.157-75.525-.186-13.356 3.273-26.571 13.756-39.554 36.347-65.296 116.94-84.695 185.93-91.465 86.922-11.017 184.91 17.94 233.37 95.401 54.124 75.733 56.675 172.54 80.612 259.53 29.438 127.13 54.779 256.21 60.392 386.85-3.063 78.182-8.426 165.18-60.503 228.13-48.027 50.357-122.79 50.053-187.07 59.002-90.555 4.655-184.35-16.146-261.78-64.198-64.776-37.94-95.73-113.48-97.279-186.02-8.39-79.875 26.392-153.81 51.62-227.16 7.47-82.761 9.413-166.25 9.653-249.38-.837-32.195-7.09-63.817-11.546-95.609z" enable-background="accumulate" fill="#262f2f" fill-rule="evenodd"/>
+  </clipPath>
+  <filter id="aq">
+   <feGaussianBlur stdDeviation="2.04"/>
+  </filter>
+  <filter id="g">
+   <feTurbulence baseFrequency=".24" numOctaves="10" result="result0" seed="655" type="fractalNoise"/>
+   <feDisplacementMap in="SourceGraphic" in2="result0" scale="62" xChannelSelector="B" yChannelSelector="G"/>
+  </filter>
+  <clipPath id="fp">
+   <path d="M352.25 211.99c-3.804-25.264-16.81-50.638-17.157-75.525-.186-13.356 3.273-26.571 13.756-39.554 36.347-65.296 116.94-84.695 185.93-91.465 86.922-11.017 184.91 17.94 233.37 95.401 54.124 75.733 56.675 172.54 80.612 259.53 29.438 127.13 54.779 256.21 60.392 386.85-3.063 78.182-8.426 165.18-60.503 228.13-48.027 50.357-122.79 50.053-187.07 59.002-90.555 4.655-184.35-16.146-261.78-64.198-64.776-37.94-95.73-113.48-97.279-186.02-8.39-79.875 26.392-153.81 51.62-227.16 7.47-82.761 9.413-166.25 9.653-249.38-.837-32.195-7.09-63.817-11.546-95.609z" enable-background="accumulate" fill="#262f2f" fill-rule="evenodd" stroke="#000"/>
+  </clipPath>
+  <filter id="fo" x="-.353" y="-.182" width="1.706" height="1.363">
+   <feGaussianBlur stdDeviation="48.038"/>
+  </filter>
+  <clipPath id="fn">
+   <path d="m265.94 126.68l-18.767 168.86 174.11-73.121 61.954 88.659 57.884-31.99-37.534-180.06-237.64 27.649z" fill-rule="evenodd" stroke="#000" stroke-width=".9"/>
+  </clipPath>
+  <filter id="fm" x="-.277" y="-.325" width="1.554" height="1.65">
+   <feGaussianBlur stdDeviation="19.956"/>
+  </filter>
+  <mask id="fk" maskUnits="userSpaceOnUse">
+   <ellipse transform="translate(-174.03 62.156)" cx="579.47" cy="260.58" rx="192.69" ry="164.05" enable-background="accumulate" fill="url(#dt)"/>
+  </mask>
+  <filter id="fj" x="-.611" y="-.149" width="2.223" height="1.299">
+   <feGaussianBlur stdDeviation="37.83"/>
+  </filter>
+  <filter id="fi" x="-.259" y="-.224" width="1.518" height="1.447">
+   <feGaussianBlur stdDeviation="19.632"/>
+  </filter>
+  <filter id="fh" x="-.3" y="-.3" width="1.6" height="1.6">
+   <feGaussianBlur stdDeviation="2"/>
+  </filter>
+  <clipPath id="x">
+   <path d="M179.64 267.36c-22.41 39.703-60.616 115.78-69.286 149.64-8.647 33.775-8.772 66.417-.357 86.429 8.36 19.882 26.164 35.633 40.714 41.429-.597-14.376 14.373-43.286 72.857-72.5 58.626-29.285 78.382-27.131 103.57-47.143 25.63-20.362 12.61-67.045 3.214-93.929-9.434-26.993-34.967-59.124-66.429-69.643-31.033-10.375-65.018-4.848-84.286 5.714z" fill="#f5ff04" fill-rule="evenodd"/>
+  </clipPath>
+  <filter id="hd">
+   <feGaussianBlur stdDeviation="6.589"/>
+  </filter>
+  <filter id="hc">
+   <feGaussianBlur stdDeviation="1.505"/>
+  </filter>
+  <filter id="hb" x="-.243" y="-.391" width="1.487" height="1.782">
+   <feGaussianBlur stdDeviation="14.59"/>
+  </filter>
+  <filter id="ha" x="-.146" y="-.235" width="1.292" height="1.47">
+   <feGaussianBlur stdDeviation="4.444"/>
+  </filter>
+  <filter id="gz">
+   <feGaussianBlur stdDeviation=".606"/>
+  </filter>
+  <clipPath id="if">
+   <path d="m709.29 844.51c54.286-1.429 126.04-15.052 170-26.786 44.053-11.757 125.89-36.347 175.36-57.857 49.339-21.453 113.6-59.282 154.29-92.143 40.508-32.721 52.39-55.82 60.714-33.571 8.37 22.368-16.407 56.326-37.857 81.071-21.604 24.923-52.731 52.705-98.929 89.286s-156.08 101.58-212.86 128.57c-57.066 27.125-128.2 58.238-172.14 72.5s-131.43 31.071-131.43 31.071l92.857-192.14z" enable-background="accumulate" fill="#121212" fill-rule="evenodd"/>
+  </clipPath>
+  <mask id="gy" maskUnits="userSpaceOnUse">
+   <path d="m718.41-224.31l33.25 56 276-24 159.5-48.25-66.5-82.75-402.25 99z" fill="url(#w)" fill-rule="evenodd"/>
+  </mask>
+  <clipPath id="gx">
+   <path transform="translate(.08 -.031)" d="M1111.4-285.94l-3.937 1.875c-.041.01-.1.02-.125.031-.42.213-.165.1-.657.313-.486.21-1.737.584-4.093 1.469-3.332 1.25-5.805 2.15-7 3.062-1.537.021-3.72.233-5.657.719a227.677 227.677 0 0 1-6.75 1.594c-1.895.42-1.675.642-2.875.875-1.296.251-1.721-.01-5.437.78-3.49.743-8.895 1.932-10.156 2.688-1.584-.18-3.868-.321-5.844-.03-3.04.446-4.916.672-6.844.905-.655.08-1.04.201-1.344.282-.426.131-.685.26-1.375.343-1.311.16-1.762-.156-5.53.282-3.555.413-9.006 1.272-10.25 1.937-1.6-.297-3.859-.534-5.845-.344-3.058.294-4.972.484-6.906.657-1.934.172-1.688.422-2.906.53-1.316.119-1.76-.163-5.531.25-3.542.39-9.008 1.21-10.281 1.876-1.6-.295-3.887-.507-5.875-.313-3.059.3-4.941.48-6.875.657-.658.06-1.04.178-1.344.25-.428.119-.683.218-1.375.28-1.316.121-1.76-.194-5.531.22-3.556.39-9.006 1.239-10.25
+1.906-1.599-.294-3.86-.524-5.844-.313-3.056.326-4.974.527-6.906.719s-1.69.44-2.906.563c-1.315.131-1.763-.165-5.532.28-3.539.42-8.977 1.293-10.25 1.97-1.597-.281-3.86-.42-5.843-.188-3.052.358-4.945.568-6.875.781-.657.073-1.041.173-1.344.25-.427.128-.685.268-1.375.344-1.314.146-1.768-.174-5.531.313-3.55.458-8.979 1.419-10.22 2.125-1.593-.245-3.833-.382-5.812-.125-3.048.394-4.95.648-6.875.906-1.924.258-1.726.493-2.937.656-1.31.176-1.748-.104-5.5.469-3.525.538-8.924 1.699-10.188 2.437-1.588-.203-3.846-.254-5.813.094-3.026.536-4.899.862-6.812 1.188-.651.11-1.014.27-1.313.375-.42.164-.663.33-1.344.468-1.294.262-1.727-.006-5.437.813-3.499.772-8.846 2.383-10.062 3.219-1.563-.078-3.758.085-5.688.593-2.972.783-4.817 1.232-6.687 1.75s-1.667.768-2.844 1.094c-1.273.353-1.697.107-5.344 1.188-3.425 1.014-8.65 2.933-9.875 3.843-1.539.013-3.72.273-5.625.875-2.93.928-4.75 1.459-6.594
+2.063-.626.205-.991.393-1.28.531-.408.214-.654.409-1.313.625-1.255.412-1.687.19-5.282 1.438-3.39 1.177-8.595 3.213-9.78 4.156-1.525.06-3.65.395-5.532 1.062-2.897 1.029-4.699 1.676-6.531 2.313-1.832.637-1.628.848-2.781 1.25-1.247.434-1.664.2-5.22 1.562-3.338 1.28-8.486 3.483-9.687 4.47-1.507.107-3.635.498-5.5 1.218a1047.26 1047.26 0 0 1-6.437 2.469c-.617.233-.997.442-1.281.594v.03l-8 3.188 1.812 14.72c-.258-.062 6.188 3.312 6.188 3.312.226-.145.449-.273.718-.375 1.08-.41 2.172-.216 6-1.688 3.829-1.471 5.224-2.005 5.907-2.406.68-.4 1.611-.88 2.218-1.531 1.827-.138 3.571-.493 4.938-1 2.968-1.1 4.875-1.806 6.781-2.469 1.906-.662 2.354-1.415 3.406-1.781 1.092-.38 2.195-.166 6.063-1.531 3.867-1.366 5.283-1.827 5.969-2.22.7-.4 1.7-.932 2.312-1.593 1.97-.055 3.817-.385 5.281-.875 3.002-1.005 4.927-1.622 6.844-2.25 1.539-.504 2.174-1.047 2.906-1.437.23-.135.476-.254.75-.344 1.099-.36 2.182-.082
+6.094-1.313 3.912-1.23 5.366-1.673 6.063-2.03.694-.358 1.63-.794 2.25-1.407 1.865-.023 3.635-.267 5.03-.688 3.031-.913 4.993-1.43 6.938-1.968 1.945-.539 2.427-1.265 3.5-1.563 1.114-.31 2.22.007 6.188-1.031 3.967-1.039 5.417-1.433 6.125-1.75.735-.33 1.814-.754 2.437-1.375 1.998.116 3.858-.02 5.344-.375 3.078-.735 5.084-1.101 7.063-1.5 1.588-.32 2.244-.79 3-1.094a3.4 3.4 0 0 1 .75-.25c1.133-.23 2.304.209 6.343-.5 4.04-.709 5.5-.927 6.22-1.187.715-.26 1.704-.568 2.343-1.094 1.924.24 3.748.224 5.188 0 3.126-.488 5.154-.7 7.156-.969 2.001-.268 2.489-.945 3.594-1.094 1.146-.154 2.275.302 6.343-.219 4.068-.52 5.56-.695 6.282-.937.737-.247 1.798-.586 2.437-1.125 2.05.336 3.974.398 5.5.219 3.142-.37 5.18-.56 7.188-.782 1.61-.178 2.264-.608 3.03-.843.242-.086.495-.156.782-.188 1.15-.127 2.301.347 6.375-.125s5.559-.61 6.281-.844c.72-.232 1.7-.473 2.344-.968 1.936.333 3.77.404 5.219.25 3.146-.335
+5.177-.519 7.187-.719 2.01-.2 2.484-.826 3.594-.938 1.151-.115 2.297.366 6.375-.062s5.589-.562 6.313-.781c.739-.224 1.795-.514 2.437-1.031 2.057.398 4.002.493 5.531.343 3.149-.308 5.176-.473 7.188-.656 1.614-.147 2.263-.56 3.031-.781.241-.081.494-.13.781-.156 1.152-.106 2.293.392 6.375 0s5.59-.531 6.313-.75c.72-.219 1.7-.448 2.343-.938 1.939.35 3.77.454 5.22.313 3.148-.309 5.175-.474 7.187-.657 2.011-.183 2.514-.838 3.625-.937 1.152-.103 2.292.385 6.375 0s5.588-.501 6.312-.719c.74-.222 1.796-.514 2.438-1.031 2.057.402 4.003.503 5.531.344 3.147-.329 5.177-.523 7.187-.72 1.613-.156 2.266-.63 3.032-.874.24-.088.463-.122.75-.156 1.148-.14 2.316.34 6.375-.25 4.058-.59 5.562-.778 6.281-1.032.717-.253 1.675-.558 2.312-1.093 1.92.212 3.72.151 5.157-.094 3.119-.533 5.111-.929 7.093-1.313 1.983-.383 2.475-1.04 3.563-1.28 1.129-.251 2.27.115 6.25-.876s5.43-1.42 6.125-1.781c.722-.376 1.762-.87
+2.375-1.531 1.963-.012 3.794-.291 5.219-.844 2.95-1.145 4.873-1.87 6.687-2.75 1.456-.706 2.32-1.702 2.531-2 .213-.298.1-.729.125-.75.043-.035.34-.094.5-.437.86-1.848 2.324-5.628 2.438-6.313.114-.682.168-1.353.219-1.75.029-.23-.147-.879-.125-.937.03-.082.288-.251.343-.5.267-1.199.09-2.208-.125-3.625-.213-1.418-.971-4.615-1.625-5.47-.658-.861-1.224-1.01-1.75-1z" enable-background="new" fill="#bcb786" fill-rule="evenodd"/>
+  </clipPath>
+  <filter id="gw">
+   <feGaussianBlur stdDeviation="1.168"/>
+  </filter>
+  <filter id="gv" x="-.103" y="-.342" width="1.206" height="1.685">
+   <feGaussianBlur stdDeviation="1.168"/>
+  </filter>
+  <filter id="gu" x="-.099" y="-.226" width="1.198" height="1.453">
+   <feGaussianBlur stdDeviation="1.168"/>
+  </filter>
+  <filter id="gt" x="-.098" y="-.198" width="1.196" height="1.397">
+   <feGaussianBlur stdDeviation="1.168"/>
+  </filter>
+  <filter id="gs">
+   <feGaussianBlur stdDeviation="1.168"/>
+  </filter>
+  <filter id="gr" x="-.098" y="-.198" width="1.197" height="1.395">
+   <feGaussianBlur stdDeviation="1.168"/>
+  </filter>
+  <filter id="gq" x="-.098" y="-.198" width="1.196" height="1.397">
+   <feGaussianBlur stdDeviation="1.168"/>
+  </filter>
+  <filter id="gp" x="-.098" y="-.203" width="1.197" height="1.406">
+   <feGaussianBlur stdDeviation="1.168"/>
+  </filter>
+  <filter id="go" x="-.098" y="-.209" width="1.197" height="1.417">
+   <feGaussianBlur stdDeviation="1.168"/>
+  </filter>
+  <filter id="gn" x="-.099" y="-.225" width="1.198" height="1.451">
+   <feGaussianBlur stdDeviation="1.168"/>
+  </filter>
+  <filter id="gm" x="-.101" y="-.274" width="1.201" height="1.548">
+   <feGaussianBlur stdDeviation="1.168"/>
+  </filter>
+  <filter id="gl" x="-.102" y="-.324" width="1.204" height="1.647">
+   <feGaussianBlur stdDeviation="1.168"/>
+  </filter>
+  <filter id="gk" x="-.103" y="-.364" width="1.207" height="1.729">
+   <feGaussianBlur stdDeviation="1.168"/>
+  </filter>
+  <filter id="gj" x="-.105" y="-.405" width="1.209" height="1.809">
+   <feGaussianBlur stdDeviation="1.168"/>
+  </filter>
+  <filter id="gi">
+   <feGaussianBlur stdDeviation="1.723"/>
+  </filter>
+  <filter id="gh">
+   <feGaussianBlur stdDeviation=".35"/>
+  </filter>
+  <filter id="gg" x="-.031" y="-.103" width="1.062" height="1.205">
+   <feGaussianBlur stdDeviation=".35"/>
+  </filter>
+  <filter id="gf">
+   <feGaussianBlur stdDeviation=".35"/>
+  </filter>
+  <filter id="ge">
+   <feGaussianBlur stdDeviation=".35"/>
+  </filter>
+  <filter id="ff">
+   <feGaussianBlur stdDeviation=".35"/>
+  </filter>
+  <filter id="fe">
+   <feGaussianBlur stdDeviation=".35"/>
+  </filter>
+  <filter id="fd">
+   <feGaussianBlur stdDeviation=".35"/>
+  </filter>
+  <filter id="fc">
+   <feGaussianBlur stdDeviation=".35"/>
+  </filter>
+  <filter id="fb">
+   <feGaussianBlur stdDeviation=".35"/>
+  </filter>
+  <filter id="fa">
+   <feGaussianBlur stdDeviation=".35"/>
+  </filter>
+  <filter id="ez">
+   <feGaussianBlur stdDeviation=".35"/>
+  </filter>
+  <filter id="ey">
+   <feGaussianBlur stdDeviation=".35"/>
+  </filter>
+  <filter id="ex" x="-.031" y="-.109" width="1.062" height="1.219">
+   <feGaussianBlur stdDeviation=".35"/>
+  </filter>
+  <filter id="ew" x="-.031" y="-.121" width="1.063" height="1.243">
+   <feGaussianBlur stdDeviation=".35"/>
+  </filter>
+  <clipPath id="ie">
+   <path d="m266.27 924.57c-1.407 18.801-1.145 32.751 2.082 49.303 3.226 16.552 16.406 45.907 20.334 63.184 3.926 17.267 2.694 38.31-12.46 51.148-15.317 12.978-42.05 21.599-67.831 15.734s-69.55-49.223-88.59-70.228c-19.112-21.083-63.761-93.851-77.94-124.28-14.177-30.425-12.66-36.719-8.119-45.53-9.367-24.52-12.414-50.067-33.712-75.577 30.325 3.114 43.88 26.956 60.126 47.14-5.53-48.076-18.055-64.417-28.374-90.724 29.994 6.082 50.579 31.872 63.98 72.712 9.554-3.918 18.238-9.373 30.187-9.061-11.298-41.696-17.949-69.916-36.687-101.07 53.442 5.67 83.657 80.639 78.971 87.96 9.978-2.243 19.006-6.53 30.437-5.65-11.249-38.348-21.048-76.869-3.66-118.65 0 0 48.287 65.436 54.39 85.805 6.103 20.37 1.52 38.701 1.52 38.701s16.96 31.085 20.293 51.094c3.373 20.241-3.533 59.103-4.946 77.983z" enable-background="new" fill="#ada469" fill-rule="evenodd"/>
+  </clipPath>
+  <filter id="id">
+   <feGaussianBlur stdDeviation="7.18"/>
+  </filter>
+  <clipPath id="ic">
+   <path d="m266.27 924.57c-1.407 18.801-1.145 32.751 2.082 49.303 3.226 16.552 16.406 45.907 20.334 63.184 3.926 17.267 2.694 38.31-12.46 51.148-15.317 12.978-42.05 21.599-67.831 15.734s-69.55-49.223-88.59-70.228c-19.112-21.083-63.761-93.851-77.94-124.28-14.177-30.425-12.66-36.719-8.119-45.53-9.367-24.52-12.414-50.067-33.712-75.577 30.325 3.114 43.88 26.956 60.126 47.14-5.53-48.076-18.055-64.417-28.374-90.724 29.994 6.082 50.579 31.872 63.98 72.712 9.554-3.918 18.238-9.373 30.187-9.061-11.298-41.696-17.949-69.916-36.687-101.07 53.442 5.67 83.657 80.639 78.971 87.96 9.978-2.243 19.006-6.53 30.437-5.65-11.249-38.348-21.048-76.869-3.66-118.65 0 0 48.287 65.436 54.39 85.805 6.103 20.37 1.52 38.701 1.52 38.701s16.96 31.085 20.293 51.094c3.373 20.241-3.533 59.103-4.946 77.983z" enable-background="new" fill="#ada469" fill-rule="evenodd"/>
+  </clipPath>
+  <filter id="gd">
+   <feGaussianBlur stdDeviation="6.82"/>
+  </filter>
+  <clipPath id="ev">
+   <path d="M760.16 935.83c6.794 18.903 10.494 33.3 11.89 51.212 1.397 17.912-3.783 51.801-2.9 70.656.881 18.845 8.133 40.099 27.345 48.969 19.419 8.966 49.319 10.211 74.12-3.146 24.8-13.357 57.4-70.326 70.974-97.309 13.624-27.084 38.76-114.5 44.66-149.77 5.9-35.27 2.551-41.3-4.617-49.055 2.64-27.84-1.5-54.935 13.11-87.186-30.249 11.826-37.382 40.161-48.319 65.505-8-50.933.21-71.273 3.319-101.22-29.065 14.778-42.862 47.114-45 92.857-10.924-1.304-21.391-4.434-33.571-.714-.264-46.023-1.464-76.889 8.91-114.21-53.254 21.027-62.946 106.59-56.052 112.78-10.883.535-21.371-1.297-32.857 2.857.638-42.57-.261-84.909-30-122.86 0 0-30.958 80.922-31.43 103.57s9.452 40.166 9.452 40.166-8.568 36.741-6.298 58.232c2.295 21.741 20.443 59.676 27.265 78.658z" enable-background="new" fill="#ada469" fill-rule="evenodd"/>
+  </clipPath>
+  <filter id="eu" x="-.144" y="-.103" width="1.288" height="1.206">
+   <feGaussianBlur stdDeviation="7.389"/>
+  </filter>
+  <clipPath id="et">
+   <path d="M760.16 935.83c6.794 18.903 10.494 33.3 11.89 51.212 1.397 17.912-3.783 51.801-2.9 70.656.881 18.845 8.133 40.099 27.345 48.969 19.419 8.966 49.319 10.211 74.12-3.146 24.8-13.357 57.4-70.326 70.974-97.309 13.624-27.084 38.76-114.5 44.66-149.77 5.9-35.27 2.551-41.3-4.617-49.055 2.64-27.84-1.5-54.935 13.11-87.186-30.249 11.826-37.382 40.161-48.319 65.505-8-50.933.21-71.273 3.319-101.22-29.065 14.778-42.862 47.114-45 92.857-10.924-1.304-21.391-4.434-33.571-.714-.264-46.023-1.464-76.889 8.91-114.21-53.254 21.027-62.946 106.59-56.052 112.78-10.883.535-21.371-1.297-32.857 2.857.638-42.57-.261-84.909-30-122.86 0 0-30.958 80.922-31.43 103.57s9.452 40.166 9.452 40.166-8.568 36.741-6.298 58.232c2.295 21.741 20.443 59.676 27.265 78.658z" enable-background="new" fill="#ada469" fill-rule="evenodd"/>
+  </clipPath>
+  <filter id="es" x="-.09" y="-.103" width="1.181" height="1.205">
+   <feGaussianBlur stdDeviation="5.346"/>
+  </filter>
+  <marker id="eq" overflow="visible" orient="auto">
+   <path d="m-1.2 0l-1 1 3.5-1-3.5-1 1 1z" fill="#f8d615" fill-rule="evenodd" stroke="#f8d615" stroke-width=".2pt"/>
+  </marker>
+  <radialGradient id="r" cx="142.96" cy="107.09" r="66.982" gradientTransform="matrix(-.33248 .90223 -.95824 -.35312 305.29 19.909)" gradientUnits="userSpaceOnUse">
+   <stop stop-color="#1e2323" offset="0"/>
+   <stop stop-color="#181d1d" offset=".56"/>
+   <stop offset="1"/>
+  </radialGradient>
+  <radialGradient id="q" cx="317.79" cy="129.65" r="47.863" gradientTransform="matrix(1.0036 0 0 1.6613 -160.53 -96.205)" gradientUnits="userSpaceOnUse" xlink:href="#u"/>
+  <radialGradient id="p" cx="325.31" cy="80.91" r="26.938" gradientTransform="matrix(2.0748 -.1578 .23824 3.1325 -550.77 -65.729)" gradientUnits="userSpaceOnUse">
+   <stop stop-color="#283131" stop-opacity="0" offset="0"/>
+   <stop stop-color="#1e2424" stop-opacity="0" offset=".513"/>
+   <stop offset="1"/>
+  </radialGradient>
+  <linearGradient id="kt" x1="347.9" x2="275.58" y1="1070.2" y2="867.98" gradientUnits="userSpaceOnUse">
+   <stop offset="0"/>
+   <stop offset=".022"/>
+   <stop offset=".759"/>
+   <stop stop-color="#232323" offset=".885"/>
+   <stop stop-color="#595959" offset="1"/>
+  </linearGradient>
+  <linearGradient id="kh" x1="603.84" x2="616.24" y1="627.85" y2="585.43" gradientTransform="translate(450.03 73.844)" gradientUnits="userSpaceOnUse" xlink:href="#t"/>
+  <linearGradient id="el" x1="609.31" x2="560.83" y1="239.47" y2="262.86" gradientTransform="translate(450.03 73.844)" gradientUnits="userSpaceOnUse">
+   <stop stop-color="#0a0c0c" offset="0"/>
+   <stop stop-color="#1f2727" stop-opacity="0" offset="1"/>
+  </linearGradient>
+  <radialGradient id="ek" cx="543.67" cy="147.31" r="47.863" gradientTransform="matrix(2.1382 0 0 2.3383 -77.038 -101.69)" gradientUnits="userSpaceOnUse" xlink:href="#u"/>
+  <radialGradient id="ef" cx="385" cy="237.01" r="86.929" gradientTransform="matrix(1 0 0 .8562 0 34.08)" gradientUnits="userSpaceOnUse">
+   <stop stop-color="#ada469" offset="0"/>
+   <stop stop-color="#ada469" offset=".811"/>
+   <stop stop-color="#fff" offset="1"/>
+  </radialGradient>
+  <linearGradient id="ee" x1="398.21" x2="379.29" y1="343.52" y2="265.31" gradientTransform="translate(450.03 73.844)" gradientUnits="userSpaceOnUse" xlink:href="#s"/>
+  <radialGradient id="ed" cx="397.16" cy="336.95" r="36.75" gradientTransform="translate(-375.32 -318.42) scale(1.945)" gradientUnits="userSpaceOnUse">
+   <stop stop-color="#344040" offset="0"/>
+   <stop stop-color="#222929" offset=".5"/>
+   <stop offset="1"/>
+  </radialGradient>
+  <radialGradient id="ec" cx="402.49" cy="317.24" r="23.714" gradientTransform="translate(-1358.3 -1070.7) scale(4.3777)" gradientUnits="userSpaceOnUse">
+   <stop offset="0"/>
+   <stop stop-color="#1d1d1d" offset="1"/>
+  </radialGradient>
+  <radialGradient id="eb" cx="250.23" cy="475.1" r="95.989" gradientTransform="matrix(1.2259 -.70777 .1414 .24491 322.22 608.92)" gradientUnits="userSpaceOnUse">
+   <stop stop-color="#d9e002" offset="0"/>
+   <stop stop-color="#a9ae01" offset=".5"/>
+   <stop stop-color="#717501" offset="1"/>
+  </radialGradient>
+  <radialGradient id="m" cx="228.81" cy="440.27" r="119.18" gradientTransform="matrix(1.1323 .76595 -1.455 2.151 588.75 -711.8)" gradientUnits="userSpaceOnUse">
+   <stop stop-color="#ff0" offset="0"/>
+   <stop stop-color="#b2b200" offset="1"/>
+  </radialGradient>
+  <radialGradient id="dz" cx="275.44" cy="335.35" r="36.75" gradientTransform="matrix(.05911 2.687 -.72343 .01591 408.73 -424.56)" gradientUnits="userSpaceOnUse">
+   <stop stop-color="#ff0" offset="0"/>
+   <stop stop-color="#ff0" stop-opacity="0" offset="1"/>
+  </radialGradient>
+  <linearGradient id="l" x1="182.35" x2="145.53" y1="256.11" y2="542.21" gradientUnits="userSpaceOnUse">
+   <stop stop-color="#7d7d00" offset="0"/>
+   <stop stop-color="#c6c700" offset=".364"/>
+   <stop stop-color="#f6f800" offset="1"/>
+  </linearGradient>
+  <radialGradient id="dy" cx="296.34" cy="427.18" r="19.704" gradientTransform="translate(-599.29 -827.09) scale(2.9797)" gradientUnits="userSpaceOnUse">
+   <stop stop-opacity="0" offset="0"/>
+   <stop offset="1"/>
+  </radialGradient>
+  <radialGradient id="dx" cx="429.57" cy="377.43" r="72.08" gradientTransform="matrix(1 0 0 .61803 0 144.16)" gradientUnits="userSpaceOnUse">
+   <stop stop-color="#e2e2e2" offset="0"/>
+   <stop stop-color="#e2e2e2" stop-opacity="0" offset="1"/>
+  </radialGradient>
+  <radialGradient id="dw" cx="437.7" cy="391.22" r="36.612" gradientTransform="matrix(1 0 0 .61803 0 149.43)" gradientUnits="userSpaceOnUse">
+   <stop stop-color="#c7bd80" offset="0"/>
+   <stop stop-color="#c7bd80" stop-opacity="0" offset="1"/>
+  </radialGradient>
+  <linearGradient id="dv" x1="412.09" x2="417.38" y1="404.92" y2="401.83" gradientUnits="userSpaceOnUse" xlink:href="#j"/>
+  <linearGradient id="du" x1="411.91" x2="417.38" y1="404.92" y2="401.83" gradientUnits="userSpaceOnUse" xlink:href="#j"/>
+  <linearGradient id="ej" x1="411.91" x2="417.38" y1="405.54" y2="401.83" gradientUnits="userSpaceOnUse" xlink:href="#j"/>
+  <linearGradient id="ei" x1="412.09" x2="417.38" y1="405.54" y2="401.83" gradientUnits="userSpaceOnUse" xlink:href="#j"/>
+  <linearGradient id="eh" x1="411.73" x2="417.38" y1="405.54" y2="401.83" gradientUnits="userSpaceOnUse" xlink:href="#j"/>
+  <linearGradient id="jr" x1="1255.7" x2="893.7" y1="667.09" y2="858.01" gradientUnits="userSpaceOnUse" xlink:href="#n"/>
+  <linearGradient id="ft" x1="603.84" x2="616.24" y1="627.85" y2="585.43" gradientTransform="matrix(1.0057 0 0 2.3995 3424.4 -24.137)" gradientUnits="userSpaceOnUse" xlink:href="#t"/>
+  <radialGradient id="fl" cx="418.3" cy="342.48" r="131.45" gradientTransform="matrix(1.3957 .62111 -.42441 .95372 -15.062 -227.97)" gradientUnits="userSpaceOnUse" xlink:href="#s"/>
+  <radialGradient id="fg" cx="275.44" cy="335.35" r="36.75" gradientTransform="matrix(.05911 2.687 -.72343 .01591 408.73 -424.56)" gradientUnits="userSpaceOnUse" xlink:href="#n"/>
+  <clipPath id="ga">
+   <path d="M3492.3 296.46H3930v902.66h-437.7z" fill="#fff"/>
+  </clipPath>
+ </defs>
+ <g stroke-miterlimit="1">
+  <path d="M10.45 109.38h1876.7v1563H10.45z" enable-background="new" fill="#a8a8a8" stroke="#000" stroke-width="20.9"/>
+  <path d="M2337.1 111.42h1878.8v1565H2337.1z" enable-background="new" fill="none" stroke="#000" stroke-width="20.925"/>
+  <path d="M2358.4 132.96h1833.4v1522.9H2358.4z" enable-background="new" fill="#a8a8a8" stroke="#f83615" stroke-width="20.391"/>
+ </g>
+ <g fill-rule="evenodd">
+  <path transform="translate(-2833.5 -4370) scale(10.727)" d="M304.64 526.65c-10 .357-18.214 2.857-18.214 2.857l7.5 6.071 10.357 3.572 16.071.357 22.5-5.357 7.857 1.071 20.357-2.143-10.357 6.786c5.46-1.023 17.393 3.57 9.643 5.357-1.74.402 13.929-4.643 13.929-4.643l2.5-4.642 3.571-9.286h11.43l18.213-4.643 3.572-5-16.071 1.071-12.143 2.143-14.643-5-70.692 16.708-5.38-5.279z" enable-background="new" filter="url(#ep)" opacity=".5"/>
+  <g enable-background="new">
+   <path transform="matrix(.71084 -.19374 .26296 .96481 552.25 332.01)" d="m245.12 100.05s-47.128-31.647-67.215-35.801c-20.038-4.144-38.473-3.318-51.934 13.607s-12.077 61.265-13.536 86.97 2.55 70.177 17.605 88.666c15.055 18.488 45.886 13.585 49.927 21.414 2.213 4.287 65.152-174.86 65.152-174.86z" enable-background="accumulate" fill="url(#r)"/>
+   <path transform="matrix(.71084 -.19374 .26296 .96481 552.25 332.01)" d="M135.38 82.018s26.344 1.939 37.633 13.903c11.415 12.097 13.735 21.332 15.296 37.735 1.563 16.425-.85 28.418-7.814 36.037s-1.004 19.583-25.916 12.071-27.032-27.783-26.515-46.305c.517-18.529 7.316-53.441 7.316-53.441z" enable-background="accumulate" fill="url(#q)"/>
+   <path transform="matrix(.71084 -.19374 .26296 .96481 552.25 332.01)" d="M135.65 81.927s-4.645 16.365.588 28.563c5.488 12.793 27.224 44.26 27.224 54.656l22.656-5c2.542-6.966 3.21-15.752 2.188-26.5-1.562-16.403-3.867-25.621-15.281-37.719-9.655-10.232-31.593-13.375-37.375-14z" enable-background="new" fill="url(#p)"/>
+  </g>
+  <path d="m893.6 1350.3c-4.286 0.714-27.628 3.618-57.857 10s-57.314 4.966-135.79 17.33c-79.852 12.581-94.064 42.542-108.12 47.064-14.7 4.729-145.38-65.822-145.38-65.822l4.286-94.286s85.886-16.201 112.14-33.571c26.257-17.37 45.582-49.666 59.286-71.429s32.857-71.429 32.857-71.429l238.57 262.14z" enable-background="accumulate" stroke="#000"/>
+  <path transform="translate(324.57 331.53)" d="m332.34 898.39l-32.732-61.3-37.617 45.106c2.177 1.317 5.774-20.856 45.6-64.417l24.749 80.61z" clip-path="url(#eo)" enable-background="accumulate" fill="#fff" filter="url(#kv)" opacity=".5"/>
+  <path transform="translate(324.57 331.53)" d="m200.82 863.03l146.37-51.619 243.95 226.27-241.83 140.01-181.02-87.681 32.527-226.98z" clip-path="url(#ku)" enable-background="accumulate" fill="url(#kt)" filter="url(#ks)"/>
+  <path d="m691.46 835.66s-29.554 40.573-47.857 74.286-58.621 126.36-70.357 171.07c-11.759 44.803-62.5 123.57-62.5 123.57l76.071 18.214s11.807-12.823 31.071-46.071 60.357-138.57 60.357-138.57l13.214-202.5z" enable-background="accumulate" fill="#0f0f0f"/>
+  <path transform="translate(324.57 331.53)" d="m430.28 381.94c-7.071 2.828-236.18 32.152-236.18 32.152l-39.64 359.83 90.198 92.64 52.326-114.55 100.47-186.39 32.828-183.68z" clip-path="url(#kr)" enable-background="accumulate" fill="#fff" filter="url(#kq)" opacity=".4"/>
+  <path d="m1018.2 1359.5s23.256 11.394 36.068 20.476c12.697 9.001 29.472 24.649 41.692 37.36 12.306 12.8 20.113 22.599 41.533 24.161 21.432 1.563 53.282-8.788 73.296-24.664 20.014-15.877 45.647-69.233 45.647-69.233l-127.16-143.07" enable-background="accumulate" stroke="#000"/>
+  <path transform="translate(324.57 331.53)" d="M331.34 641.5L216.17 835.36l44.042 90.598 97.581-193.75-26.456-90.711z" clip-path="url(#kp)" enable-background="accumulate" filter="url(#ko)" opacity=".75"/>
+  <g enable-background="new">
+   <path d="M1113.913 623.101l-.09-.002c-1.48.72-6.744.842-7.674 8.704-.872 7.373 12.962 18.694 14.976 19.936 1.626 1.001 3.407 1.81 5.174 2.325l1.403.382c1.883.43 3.679.575 5.134.496 3.16-.173 5.184-.339 7.197-.493 2.013-.155 2.577-.75 3.686-.866 1.15-.12 2.242.375 6.309-.155 4.066-.53 5.556-.79 6.288-1.07.76-.29 1.85-.663 2.534-1.25 1.952.213 3.803.145 5.281-.241 3.063-.8 5.055-1.3 6.958-1.968 1.527-.536 2.499-1.426 2.744-1.698.245-.271.181-.712.21-.73.046-.03.348-.055.546-.378 1.065-1.737 2.951-5.325 3.143-5.993.191-.664.322-1.324.417-1.713.056-.225-.045-.89-.017-.946.04-.078.315-.216.399-.457.402-1.16.34-2.183.29-3.616-.05-1.433-.438-4.695-.99-5.618-.353-.593-.703-.88-1.044-1.033-.065-.025-.118-.06-.18-.083-.02-.007-.042-.002-.061-.007-.301-.111-.586-.228-1.124-.35-.966-.22-2.379-.535-3.914-.702a19.278 19.278 0 0
+0-1.563-.085c-3.571-.097-9.064-.045-10.338.446-1.584-.518-3.852-1.06-5.845-1.144-3.069-.13-4.974-.228-6.914-.324-1.94-.095-1.72.194-2.941.134-1.32-.065-1.75-.426-5.537-.543-3.556-.11-9.035-.04-10.338.447-1.584-.52-3.85-1.06-5.845-1.144-3.07-.131-4.978-.197-6.918-.293-.66-.032-1.05.004-1.356.033z" enable-background="new" fill="#bcb786"/>
+   <g transform="rotate(2.568 -22364 20373)" clip-path="url(#kn)" enable-background="new" filter="url(#km)">
+    <path d="M229.94-409.12c-3.558.05-9.024.36-10.303.904-1.606-.447-3.903-.881-5.9-.877a979.03 979.03 0 0 1-6.907 0c-.66-.003-1.048.068-1.353.11v1.096c.12-.18.393-.69.95-.767.747-.103 5.17-.151 7.31-.11 1.775.035 4.455.274 6.39.96.32.113.618.273.891.41 1.964.987 7.944 4.302 7.944 4.302s-6.633-3.948-7.483-4.439c-.203-.117-.575-.258-1.036-.41 1.22-.449 5.076-.62 7.828-.713 3.024-.102 3.348-.09 5.41.192 2.13.29 3.34.602 3.34.602s-.08-.64 1.035-.794c.748-.103 5.17-.152 7.31-.11 2.07.04 5.366.407 7.282 1.37 1.003.504 3.035 1.569 4.795 2.536l.096-.02s-3.58-2.162-4.43-2.653c-.204-.117-.575-.258-1.037-.411 1.22-.448 5.047-.62 7.8-.712 3.024-.102 3.347-.09 5.41.191 1.954.267 3.013.53 3.195.576l-.027-.312a8.503 8.503 0 0 0-1.4-.357c-1.301-.235-3.4-.602-5.51-.564-3.571.064-9.052.356-10.302.904-1.606-.447-3.877-.881-5.871-.877-3.072.007-4.994.01-6.936
+0-1.943-.009-1.713.28-2.936.274-1.322-.005-1.766-.354-5.555-.301M206.2-407.48c1.92.817 4.577 2.193 6.159 3.397s2.908 1.774 5.555 3.918c.885.718 1.748 1.35 2.591 1.922l.541-.19a57.511 57.511 0 0 1-2.269-1.622c-2.822-2.12-3.627-2.81-6.015-4.274s-4.1-2.366-6.562-3.15" enable-background="new"/>
+    <path d="M237.8-407.48c1.92.817 4.606 2.193 6.188 3.397.813.62 1.558 1.07 2.45 1.654l.65-.116a40.414 40.414 0 0 0-2.697-1.784c-2.389-1.465-4.128-2.366-6.59-3.151" enable-background="new"/>
+   </g>
+   <g transform="rotate(6.561 -6814.9 734.73)" clip-path="url(#kl)">
+    <path d="M1056.2-278.8c4.145-1.479 10 3.125 10 3.125.899.28 2.725-.894 2.624-1.686 0 0-1.55-1.86-.374-2.939s5.296 1.507 7.5 1.625 5.562-.23 7-.75 1.113-1.425 2.625-1.75 5.119 1.038 7.06 1.169 4.649.334 5.815-.169.178-1.16 1.875-1.875 7.76-.957 9.625-.125 1.81.52 2.625 3 7.44 5.163-1.125 13.375-59.378 13.786-65.625 2.75 6.23-14.271 10.375-15.75z" enable-background="new" filter="url(#kk)" opacity=".75"/>
+    <path d="M1058.5-275.43c4.145-1.479 10 3.125 10 3.125.899.28 2.725-.894 2.624-1.686 0 0-1.55-1.86-.374-2.939s5.296 1.507 7.5 1.625 5.562-.23 7-.75 1.113-1.425 2.625-1.75 5.119 1.038 7.06 1.169 4.649.334 5.815-.169.178-1.16 1.875-1.875 7.76-.957 9.625-.125 1.81.52 2.625 3 7.44 5.163-1.125 13.375-59.378 13.786-65.625 2.75 6.23-14.271 10.375-15.75z" enable-background="new" filter="url(#kj)" opacity=".75"/>
+   </g>
+  </g>
+  <path d="M676.821 543.52c-3.804-25.264-16.81-50.638-17.157-75.525-.186-13.356 3.273-26.571 13.756-39.554 36.347-65.296 116.94-84.695 185.93-91.465 86.922-11.017 184.91 17.94 233.37 95.401 54.124 75.733 56.675 172.54 80.612 259.53 29.438 127.13 54.779 256.21 60.392 386.85-3.063 78.182-8.426 165.18-60.503 228.13-48.026 50.357-122.79 50.053-187.07 59.002-90.555 4.655-184.35-16.146-261.78-64.198-64.776-37.94-95.73-113.48-97.279-186.02-8.39-79.875 26.392-153.81 51.62-227.16 7.47-82.761 9.413-166.25 9.653-249.38-.837-32.195-7.09-63.817-11.546-95.609z" enable-background="accumulate" fill="#101414"/>
+  <path transform="translate(324.57 331.53)" d="M311.83 415.43l9.9 121.62-60.105 136.47 15.556 174.66c15.613 61.879 32.185 98.669 74.376 117.05 4.32-36.24-38.612-142.96-39.243-189.12-.631-46.184 10.83-108.61 30.678-158.3 20.048-50.192 36.897-44.846 42.125-92.593s-17.426-149.39-17.426-149.39l-55.86 39.598z" clip-path="url(#en)" enable-background="accumulate" fill="#fff" filter="url(#ki)" opacity=".25"/>
+  <path transform="translate(48.571 195.53)" d="m1010 655.49s16.755 37.018 28.702 53.954c11.946 16.936 52.727 56.046 52.727 56.046l52.597-127.59" enable-background="accumulate" fill="url(#kh)"/>
+  <path transform="translate(324.57 331.53)" d="m730.32 536.57c0 8.485 42.548 58.468 42.548 58.468l12.607-28.77-55.154-29.698z" clip-path="url(#kg)" enable-background="accumulate" fill="#fff" filter="url(#kf)" opacity=".08"/>
+ </g>
+ <g transform="translate(498.6 269.37)" clip-path="url(#ke)" enable-background="new">
+  <g transform="translate(-174.03 62.156)" filter="url(#em)">
+   <g filter="url(#i)">
+    <path d="M425.88 476.99c10.805-1.479 24.744 3.354 44.643 3.214s57.453-16.91 82.143-17.143 62.752 12.284 79.286 15 22.848-.158 27.5 7.857 1.927 10.747-10.357 20.714-40.79 12.636-66.071 12.857c-25.282.221-70.381 7.079-95.357 3.93s-56.938-7.824-68.929-17.858-19.851-16.732-17.5-23.929 13.837-3.164 24.643-4.643z" enable-background="new" fill="#fff" fill-rule="evenodd"/>
+    <path d="M343.65 412.6h381.84v181.02H343.65z" enable-background="accumulate" fill="none"/>
+   </g>
+   <g filter="url(#i)">
+    <path d="m861.17 390.2c-10.462 9.714-86.98 19.005-100.71 29.286s-14.753 12.888-12.143 20 6.545 9.406 25.714 8.571 98.571-27.622 98.571-21.429l-11.429-36.429z" enable-background="new" fill="#fff" fill-rule="evenodd"/>
+    <path d="M702.86 344.82h207.89v162.63H702.86z" enable-background="accumulate" fill="none"/>
+   </g>
+  </g>
+  <g enable-background="new" opacity=".18">
+   <g transform="translate(-174.03 62.156)" filter="url(#i)">
+    <path d="M425.88 476.99c10.805-1.479 24.744 3.354 44.643 3.214s57.453-16.91 82.143-17.143 62.752 12.284 79.286 15 22.848-.158 27.5 7.857 1.927 10.747-10.357 20.714-40.79 12.636-66.071 12.857c-25.282.221-70.381 7.079-95.357 3.93s-56.938-7.824-68.929-17.858-19.851-16.732-17.5-23.929 13.837-3.164 24.643-4.643z" enable-background="new" fill="#fff" fill-rule="evenodd"/>
+    <path d="M343.65 412.6h381.84v181.02H343.65z" enable-background="accumulate" fill="none"/>
+   </g>
+   <g transform="translate(-174.03 62.156)" filter="url(#i)">
+    <path d="m861.17 390.2c-10.462 9.714-86.98 19.005-100.71 29.286s-14.753 12.888-12.143 20 6.545 9.406 25.714 8.571 98.571-27.622 98.571-21.429l-11.429-36.429z" enable-background="new" fill="#fff" fill-rule="evenodd"/>
+    <path d="M702.86 344.82h207.89v162.63H702.86z" enable-background="accumulate" fill="none"/>
+   </g>
+  </g>
+ </g>
+ <g transform="translate(48.571 195.53)" fill-rule="evenodd">
+  <path transform="translate(276 136)" d="m582.66-7.418l113.14 86.267 108.89 258.8 38.184 207.89 120.21 91.924s-12.728-287.09-19.799-313.96-149.91-393.15-149.91-393.15l-210.72 62.225z" clip-path="url(#kd)" enable-background="accumulate" filter="url(#kc)" opacity=".75"/>
+  <path d="m964.14 239.6s8.677 10.897 24.107 11.964c15.43 1.068 49.722-39.953 70.179-52.143 20.479-12.204 47.046-26.602 63.929-20.357 16.882 6.245 22.158 26.436 27.857 48.036 5.7 21.6 6.719 61.814-2.679 92.857-9.397 31.043-50.502 73.104-65.356 103.39s-11.607 39.821-11.607 39.821" enable-background="accumulate" fill="url(#el)"/>
+  <path d="m1124.5 207.63c-15.893-0.893-49.719 12.106-66.071 24.286-16.439 12.244-29.221 24.114-29.286 52.143-0.065 28.206 13.119 39.076 29.107 46.964s33.686 7.12 51.964-11.786c18.278-18.905 14.286-111.61 14.286-111.61z" enable-background="new" fill="url(#ek)"/>
+  <ellipse transform="matrix(.94347 -.12399 .14401 1.0958 451.95 134.6)" cx="385" cy="237.01" rx="86.429" ry="73.929" clip-path="url(#kb)" enable-background="accumulate" fill="url(#ef)" filter="url(#je)" opacity=".75"/>
+  <path transform="translate(450.03 73.844)" d="m527.61 407.45s-122.04 38.403-187.51 9.632c-65.473-28.772-74.377-124.72-74.377-124.72s73.382-80.504 129.92-83.615c55.827-3.072 90.574 20.143 114.87 65.852 24.352 45.813 17.101 132.85 17.101 132.85z" enable-background="accumulate" fill="url(#jd)" mask="url(#jc)"/>
+  <path d="m772.17 393.35s36.218-27.382 51.607-35.893c15.177-8.393 25.714-11.607 35.893-11.607l-15.536 66.964" enable-background="accumulate" fill="url(#ee)"/>
+  <circle transform="translate(449.5 74.915)" cx="409.29" cy="306.65" r="36.25" enable-background="accumulate" fill="url(#ed)"/>
+  <path transform="translate(276 136)" d="m311.83 415.43l9.9 121.62-60.105 136.47 15.556 174.66c15.613 61.879 32.185 98.669 74.376 117.05 4.32-36.24 8.682-72.368-31.243-223.12l17.678-69.296 72.125-138.59-42.426-158.39-55.86 39.598z" clip-path="url(#en)" enable-background="accumulate" fill="#fff" filter="url(#jb)" opacity=".3"/>
+  <path d="m635.21 581.13c-14.142 12.728 39.233 34.58 76.368 24.042s104.64-35.564 103.24-79.196c-1.407-43.632-76.368-128.69-76.368-128.69l-103.24 183.85z" enable-background="accumulate" filter="url(#ja)" opacity=".5"/>
+  <circle transform="translate(449.67 74.915)" cx="410" cy="306.65" r="23.214" enable-background="accumulate" fill="url(#ec)"/>
+  <circle transform="translate(452 73.487)" cx="414.29" cy="303.08" r="7.5" enable-background="accumulate" fill="#fff" filter="url(#iz)" stroke="#000" stroke-linejoin="bevel"/>
+  <path d="m789.32 478.35s7.023 19.569-1.071 35-42.323 38.988-67.5 50c-25.31 11.07-85.473 32.964-101.79 41.964-16.461 9.082-18.214 12.679-18.214 12.679s-7.147-19.064 28.75-51.786c36.172-32.972 142.03-48.05 159.82-87.857z" enable-background="accumulate" fill="url(#eb)"/>
+ </g>
+ <g enable-background="new">
+  <g transform="translate(829.32 270.09)" fill-rule="evenodd">
+   <path transform="translate(-329.81)" d="M179.64 267.36c-22.41 39.703-60.616 115.78-69.286 149.64-8.647 33.775-8.772 66.417-.357 86.429 8.36 19.882 26.164 35.633 40.714 41.429-.597-14.376 14.373-43.286 72.857-72.5 58.626-29.285 78.382-27.131 103.57-47.143 25.63-20.362 8.206-79.647 3.214-93.929s-1.236-3.38-1.946-5.093c-10.689-25.816-34.214-54.43-64.483-64.55s-65.018-4.848-84.286 5.714z" clip-path="url(#ea)" fill="url(#m)"/>
+   <ellipse transform="rotate(28.068 -88.085 -332.1)" cx="183.57" cy="338.08" rx="64.716" ry="134.01" enable-background="accumulate" fill="url(#dz)"/>
+   <ellipse transform="rotate(28.068 -43.578 -333.81)" cx="183.57" cy="338.08" rx="64.716" ry="134.01" enable-background="accumulate" fill="url(#iy)"/>
+  </g>
+  <path transform="translate(499.51 270.09)" d="M179.64 267.36c-22.41 39.703-60.616 115.78-69.286 149.64-8.647 33.775-8.772 66.417-.357 86.429 8.36 19.882 26.164 35.633 40.714 41.429-.597-14.376 14.373-43.286 72.857-72.5 58.626-29.285 78.382-27.131 103.57-47.143 25.63-20.362 8.206-79.647 3.214-93.929s-1.236-3.38-1.946-5.093c-10.689-25.816-34.214-54.43-64.483-64.55s-65.018-4.848-84.286 5.714z" clip-path="url(#ea)" enable-background="new" fill="none" filter="url(#ix)" stroke="url(#l)" stroke-width="20.8"/>
+ </g>
+ <g transform="translate(48.571 195.53)" fill-rule="evenodd">
+  <circle transform="translate(452.56 72.581)" cx="310.71" cy="398.08" r="19.704" enable-background="accumulate" stroke="#000" stroke-linejoin="bevel"/>
+  <circle transform="translate(450.56 72.581)" cx="310.71" cy="398.08" r="19.704" enable-background="accumulate" fill="url(#m)" filter="url(#iw)" stroke="url(#l)" stroke-width="20.8"/>
+  <circle transform="translate(450.56 72.581)" cx="310.71" cy="398.08" r="19.704" enable-background="accumulate" fill="url(#dy)"/>
+  <ellipse transform="rotate(-4.471 1823.1 -5529.2)" cx="429.57" cy="377.43" rx="72.08" ry="44.548" enable-background="accumulate" fill="url(#dx)" filter="url(#iv)"/>
+  <ellipse transform="matrix(1.4358 -.07 .07 1.4358 235.18 -63.865)" cx="437.7" cy="391.22" rx="36.612" ry="22.627" enable-background="accumulate" fill="url(#dw)" filter="url(#iu)"/>
+  <g transform="translate(450.03 73.844)" enable-background="new" filter="url(#it)">
+   <circle cx="413.66" cy="401.83" r="3.214" enable-background="accumulate" stroke="url(#dv)"/>
+   <circle transform="translate(13.125 8.125)" cx="413.66" cy="401.83" r="3.214" enable-background="accumulate" stroke="url(#du)"/>
+   <circle transform="translate(32.946 7.5)" cx="413.66" cy="401.83" r="3.214" enable-background="accumulate" stroke="url(#ej)"/>
+   <circle transform="translate(24.911 -10.268)" cx="413.66" cy="401.83" r="3.214" enable-background="accumulate" stroke="url(#ei)"/>
+   <circle transform="translate(47.589 -.625)" cx="413.66" cy="401.83" r="3.214" enable-background="accumulate" stroke="url(#eh)"/>
+  </g>
+ </g>
+ <g fill="none" stroke="#000">
+  <path d="M944.771 678.46c.985 4.35 4.537 6.18 7.387 7.892 4.46 2.513 6.52 1.522 9.154-.758 1.602-1.921 10.683-4.698 15.594-7.07 4.33-1.46 8.904-5.36 13.385-8.335 3.395-1.627 5.347.355 7.829 1.01 2.944.717 4.411 2.172 6.06 3.536 2.397 1.175-.927 3.143 3.284 4.293 1.19.218 2.417.577 3.283-.505" enable-background="new"/>
+  <path d="M959.421 670.88c2.315-.032 3.178.643 5.493-.82 3.455-3.082 5.402-3.146 7.955-4.42 3.026-1.315 6.535 8.152 10.102 9.849 2.395-.822 1.289 1.794 1.452 2.651.057 2.647 2.807 3.679 4.356 5.43 3.316 2.256 7.375 6.296 11.112 5.303 6.445-2.93 10.28-1.281 16.29-7.386.703-1.182-.585-6.895 3.093-7.198 2.524.254 4.166.05 6.06.569 5.442 2.117 7.738 6.45 14.71 7.955 6.184.966 7.613 3.794 13.89 5.05M925.551 679.05c2.399-.794 6.106 4.192 8.173 7.046.593 2.68 1.154 5.486.758 12.122.785 2.417 2.68 3.03 4.798 3.283 3.117-.537 5.877-1.325 7.324-3.03 1.871-1.943 5.312 2.393 8.08 4.04 3.61 1.912 7.775 1.979 11.87 2.273 1.703-.231 2.37 4.515 3.283 8.08.384 4.379-.886 6.896-1.768 9.85-.294 2.496 2.988 3.53 6.313 4.545 3.183.742 6.545 1.662 9.092 1.768 5.142.875 8.088 2.69 12.122 4.04 2.239.817 3.26 2.243 4.545 3.536" enable-background="new"/>
+ </g>
+ <g fill-rule="evenodd">
+  <path transform="translate(324.57 331.53)" d="m332 187.7s57.5-25.5 57.5-28 5.5-52 5.5-52 91-48.5 91.5-50.5 86-62 86-62l-186 22-75.5 106z" clip-path="url(#jz)" enable-background="new" fill="#fff" filter="url(#jy)" opacity=".25"/>
+  <path d="m1745.9 918.08s-115.97 73.539-123.04 77.782c-7.071 4.243-230.52 137.18-230.52 137.18l4.243 39.598 216.37-100.41 117.38-101.82 15.556-52.326z" enable-background="accumulate" fill="#fff" opacity=".25"/>
+  <path transform="translate(324.57 331.53)" d="m528.92 556.85c-5.657-1.414-181.02 74.953-181.02 74.953l-33.941 181.02 51.095 193.95 257.2 67.681s206.48 152.74 212.13 148.49c5.657-4.243 168.29-193.75 168.29-193.75l-159.81-183.85-46.669-178.19-267.29-110.31z" clip-path="url(#jx)" enable-background="accumulate" filter="url(#eg)" opacity=".5"/>
+  <path d="m1146.2 809.42s22.62-6.507 35.743-5.873 30.642 1.939 43.709 12.186c13.067 10.248 25.068 27.14 34.112 58.37 9.045 31.23 1.698 99.252-6.176 143.35-7.874 44.095-28.265 106.11-45 140-16.735 33.887-49.798 77.495-60.57 89.876-11.363 13.062-56.205 36.426-79.43 42.267 5.303-10.607 48.9-50.589 35-60.714-14.02-10.212-45.76 45.982-84.293 29.033 21.382-13.132 41.779-51.186 34.04-66.594-7.84-15.61-30.704 48.758-93.535 37.013 30.052-27.527 55.407-70.904 41.263-82.98-14.415-12.307-60.462 54.293-60.462 54.293s-2.822-41.7 13.773-68.607c16.639-26.978 79.653-81.615 99.553-111.7 19.9-30.088 33.613-66.009 42.136-92.518s15.8-77.1 15.8-77.1" enable-background="new" fill="#0c0c0c"/>
+  <path transform="translate(324.57 331.53)" d="m770.75 609.18l-50.912 97.581-79.903 111.02 34.648 71.418 42.426 79.196 72.125-45.255 14.142-192.33 21.213-138.59-14.142-90.156-39.598 107.13z" clip-path="url(#jw)" enable-background="accumulate" fill="#fff" filter="url(#jv)" opacity=".25"/>
+  <path transform="translate(324.57 331.53)" d="m295 846.2l6.645-68.923s90.32 89.005 162.36 122.92 308 62 308 62l154-26-36 162-286 26-298-89-11-189z" clip-path="url(#ju)" enable-background="accumulate" filter="url(#eg)"/>
+  <path transform="translate(498.6 269.37)" d="m405.8 845.99l74.953 65.054 2.5 16.88 19.403 10.159 6.492 23.051 31.709-8.371 14.849 48.083c12.257 12.728 89.793-113.11 55.86 38.184l-60.81 16.264-89.203-94.693-62.825-53.8 7.07-60.811z" clip-path="url(#jt)" enable-background="new" fill="#fff" filter="url(#o)"/>
+  <path d="m1207.9 1113.9c54.286-1.429 126.04-15.052 170-26.786 44.053-11.757 125.89-36.347 175.36-57.857 49.339-21.453 113.6-59.282 154.29-92.143 40.508-32.721 52.39-55.82 60.714-33.571 8.37 22.368-16.407 56.326-37.857 81.071-21.604 24.923-52.731 52.705-98.929 89.286s-156.08 101.58-212.86 128.57c-57.066 27.125-128.2 58.238-172.14 72.5s-131.43 31.071-131.43 31.071l92.857-192.14z" enable-background="accumulate" fill="#121212"/>
+  <path transform="translate(498.6 269.37)" d="m1241.6 652.95s-64.722 54.337-145.66 98.995c-82.024 45.255-284.26 93.338-284.26 93.338s-15.101 21.052 45.255 28.284 224.08-53.301 278.6-96.167 120.21-111.72 120.21-111.72l-14.142-12.728z" clip-path="url(#js)" enable-background="accumulate" fill="url(#jr)" filter="url(#jq)" opacity=".5"/>
+ </g>
+ <g transform="translate(498.6 269.37)" clip-path="url(#jp)" enable-background="new">
+  <g filter="url(#em)">
+   <g transform="translate(-174.03 62.156)" filter="url(#i)">
+    <path d="m1268.3 663.77s-0.296 26.161 4.643 37.857 20.038 26.487 28.572 31.429 18.929 8.571 18.929 8.571l117.86-115 17.857-75.714-96.43 38.571-91.428 74.286z" enable-background="new" fill="#fff" fill-rule="evenodd"/>
+    <path d="M1197.8 486.14h333.75v309.71H1197.8z" enable-background="accumulate" fill="none"/>
+   </g>
+  </g>
+  <g transform="translate(-174.03 62.156)" enable-background="new" filter="url(#i)" opacity=".18">
+   <path d="m1268.3 663.77s-0.296 26.161 4.643 37.857 20.038 26.487 28.572 31.429 18.929 8.571 18.929 8.571l117.86-115 17.857-75.714-96.43 38.571-91.428 74.286z" enable-background="new" fill="#fff" fill-rule="evenodd"/>
+   <path d="M1197.8 486.14h333.75v309.71H1197.8z" enable-background="accumulate" fill="none"/>
+  </g>
+ </g>
+ <path transform="translate(498.6 269.37)" d="M1264.2 605c-4.491.733-8.157 3.455-11.938 6.406-10.081 7.87-28.17 34.425-48.031 50.47-39.867 32.202-104 69.976-152.56 91.093-48.614 21.137-130.54 45.818-174.31 57.5-43.398 11.582-115.04 25.131-168.25 26.531l-4.562.125-2 4.125-92.844 192.12-6.5 13.47 14.656-2.845s87.27-16.65 132.34-31.28c44.725-14.518 115.79-45.668 173.03-72.876 57.603-27.38 166.94-91.98 214.28-129.47 46.36-36.71 77.805-64.717 99.938-90.25 10.9-12.576 22.745-27.53 31.03-42.75 8.287-15.219 19.16-44.218 13.688-58.844-1.218-3.254-2.552-6.06-4.594-8.5s-8.475-1.572-8.563-5.03c-.21-8.266-3.315-.245-4.812 0zm2.156 15.219c.415.586 1.031 1.558 1.782 3.563 2.896 7.742-1.441 31.899-8.813 45.438s-22.638 28.924-33.188 41.094c-21.075 24.314-51.904 51.862-97.938 88.312-45.05 35.672-155.46 101.09-211.41 127.69-56.892 27.042-128.1 58.118-171.25 72.125-36.365 11.803-95.845 23.834-115.72
+27.78l84.281-174.47c54.707-2.049 123.79-15.215 167.12-26.78 44.334-11.832 126.08-36.336 176.41-58.22 50.112-21.788 112.53-61.167 154.03-94.687 20.646-16.677 41.745-42.546 49.813-48.844 2.437-1.903 4.08-2.636 4.875-3z" clip-path="url(#jo)" enable-background="accumulate" fill="#050505" fill-rule="evenodd" filter="url(#jn)" opacity=".833"/>
+ <g transform="rotate(6.561 -6814.9 734.74)" enable-background="new" fill-rule="evenodd" mask="url(#jm)">
+  <path d="M1111.48-285.971l-3.937 1.875c-.041.01-.1.02-.125.031-.42.213-.165.1-.657.312-.486.21-1.737.585-4.093 1.47-3.332 1.25-5.805 2.15-7 3.062-1.537.021-3.72.233-5.657.719a227.677 227.677 0 0 1-6.75 1.593c-1.894.42-1.675.642-2.875.875-1.296.252-1.721-.009-5.437.782-3.49.742-8.895 1.93-10.156 2.687-1.584-.18-3.868-.322-5.844-.031-3.04.447-4.916.673-6.844.906-.655.08-1.04.2-1.343.281-.427.132-.686.26-1.375.344-1.312.16-1.763-.157-5.532.281-3.554.413-9.005 1.273-10.25 1.938-1.599-.297-3.857-.534-5.843-.344-3.06.293-4.972.484-6.907.656-1.934.173-1.688.423-2.906.532-1.316.117-1.76-.164-5.531.25-3.542.388-9.008 1.209-10.281 1.875-1.6-.295-3.887-.507-5.875-.313-3.058.3-4.941.48-6.875.656-.658.06-1.04.179-1.344.25-.428.12-.683.218-1.375.282-1.316.12-1.76-.195-5.531.218-3.556.39-9.006 1.24-10.25
+1.907-1.599-.295-3.86-.524-5.844-.313-3.056.325-4.974.526-6.906.719s-1.69.44-2.906.562c-1.315.132-1.763-.164-5.532.282-3.538.418-8.977 1.292-10.25 1.968-1.597-.28-3.86-.42-5.843-.187-3.052.358-4.945.568-6.875.781-.657.073-1.041.173-1.344.25-.427.127-.685.267-1.375.344-1.314.146-1.768-.174-5.531.312-3.55.46-8.979 1.42-10.22 2.125-1.592-.244-3.833-.381-5.812-.125-3.047.395-4.95.649-6.875.907-1.924.257-1.726.493-2.937.656-1.31.176-1.748-.105-5.5.469-3.525.538-8.924 1.699-10.188 2.437-1.588-.203-3.846-.255-5.813.094-3.026.536-4.899.861-6.812 1.187-.65.111-1.014.271-1.313.375-.42.165-.663.332-1.344.469-1.294.262-1.727-.006-5.437.813-3.499.771-8.846 2.382-10.062 3.218-1.563-.077-3.758.086-5.688.594-2.972.783-4.817 1.232-6.687 1.75s-1.667.767-2.844 1.094c-1.272.353-1.697.107-5.344 1.187-3.424 1.015-8.65 2.934-9.875 3.844-1.539.013-3.72.272-5.625.875-2.93.928-4.75 1.459-6.594
+2.063-.626.205-.991.392-1.28.53-.408.215-.654.41-1.313.626-1.255.411-1.686.189-5.281 1.437-3.39 1.178-8.595 3.214-9.782 4.157-1.524.06-3.65.395-5.53 1.062-2.898 1.028-4.7 1.676-6.532 2.313-1.832.637-1.628.848-2.781 1.25-1.247.434-1.664.2-5.22 1.562-3.338 1.28-8.486 3.483-9.687 4.469-1.507.108-3.635.499-5.5 1.219a1047.26 1047.26 0 0 1-6.437 2.469c-.617.233-.997.442-1.281.593v.031l-8 3.188-12.476 3.492 7.93 19.278c-.592 1.973 12.545-4.739 12.545-4.739.227-.144.45-.272.72-.375 1.08-.41 2.17-.215 6-1.687 3.828-1.472 5.223-2.005 5.905-2.406.68-.4 1.612-.88 2.22-1.531 1.826-.138 3.57-.494 4.937-1 2.968-1.1 4.875-1.807 6.78-2.47 1.907-.662 2.355-1.414 3.407-1.78 1.092-.38 2.195-.166 6.063-1.532 3.867-1.366 5.283-1.827 5.968-2.218.702-.4 1.701-.933 2.313-1.594 1.97-.055 3.817-.385 5.281-.875 3.002-1.005 4.926-1.622 6.844-2.25 1.538-.504 2.174-1.047 2.906-1.438.23-.134.476-.253.75-.343 1.098-.36
+2.181-.082 6.094-1.313 3.912-1.231 5.366-1.673 6.062-2.031.694-.357 1.63-.793 2.25-1.406 1.866-.023 3.636-.267 5.032-.688 3.03-.913 4.992-1.43 6.937-1.969 1.945-.538 2.426-1.264 3.5-1.562 1.114-.31 2.22.007 6.188-1.031 3.967-1.039 5.417-1.433 6.125-1.75.734-.33 1.813-.754 2.437-1.375 1.998.116 3.857-.02 5.344-.375 3.078-.735 5.083-1.101 7.062-1.5 1.588-.32 2.245-.79 3-1.094a3.4 3.4 0 0 1 .75-.25c1.134-.23 2.305.209 6.344-.5 4.04-.71 5.5-.927 6.219-1.188.716-.26 1.704-.567 2.344-1.093 1.924.239 3.748.224 5.187 0 3.127-.488 5.155-.701 7.156-.97 2.002-.267 2.49-.944 3.594-1.093 1.147-.154 2.276.302 6.344-.219 4.068-.52 5.56-.695 6.281-.937.737-.247 1.798-.586 2.438-1.125 2.05.335 3.973.398 5.5.218 3.142-.368 5.18-.559 7.187-.78 1.611-.179 2.265-.609 3.031-.845.241-.085.495-.155.782-.187 1.15-.128 2.301.347 6.375-.125s5.559-.61 6.28-.844c.72-.232 1.701-.473 2.345-.969 1.936.334 3.77.405
+5.219.25 3.146-.334 5.177-.518 7.187-.718 2.01-.2 2.484-.827 3.594-.938 1.15-.115 2.296.365 6.375-.062s5.589-.562 6.312-.782c.74-.223 1.796-.513 2.438-1.03 2.057.398 4.002.493 5.531.343 3.149-.308 5.176-.473 7.188-.656 1.614-.147 2.263-.56 3.03-.781.242-.081.494-.13.782-.157 1.152-.105 2.293.393 6.375 0s5.589-.53 6.312-.75c.721-.218 1.7-.447 2.344-.937 1.938.35 3.769.454 5.219.312 3.149-.308 5.176-.473 7.187-.656 2.012-.183 2.515-.838 3.625-.937 1.153-.104 2.293.384 6.375 0 4.083-.385 5.59-.501 6.313-.72.74-.222 1.796-.514 2.437-1.03 2.058.401 4.003.503 5.532.343 3.146-.328 5.177-.522 7.187-.718 1.613-.158 2.266-.632 3.031-.875.241-.088.464-.122.75-.157 1.149-.14 2.317.34 6.375-.25 4.059-.59 5.562-.777 6.282-1.03.716-.254 1.674-.559 2.312-1.095 1.92.212 3.72.152 5.156-.093 3.12-.533 5.112-.929 7.094-1.313 1.982-.384 2.474-1.04 3.563-1.281 1.128-.25 2.27.116 6.25-.875s5.43-1.42
+6.125-1.781c.722-.376 1.761-.87 2.375-1.531 1.963-.012 3.793-.292 5.218-.844 2.952-1.145 4.874-1.87 6.688-2.75 1.456-.707 2.32-1.702 2.531-2 .212-.298.1-.729.125-.75.043-.035.34-.094.5-.438.86-1.847 2.323-5.627 2.438-6.312.113-.682.168-1.353.218-1.75.03-.23-.147-.88-.125-.938.031-.082.289-.25.344-.5.266-1.198.09-2.207-.125-3.625-.214-1.417-.972-4.614-1.625-5.469-.659-.861-1.225-1.01-1.75-1z" enable-background="new" fill="#bcb786"/>
+  <g clip-path="url(#jl)">
+   <path d="M1107.4-284.05c-.419.213-.156.094-.647.306-.486.21-1.724.574-4.08 1.459-3.33 1.25-5.83 2.153-7.026 3.066-1.536.021-3.72.233-5.656.719a227.709 227.709 0 0 1-6.75 1.593c-1.895.42-1.676.643-2.875.875-1.297.252-1.721-.009-5.438.782-3.49.742-8.894 1.93-10.156 2.687-1.583-.18-3.867-.322-5.843-.031-3.04.447-4.917.673-6.844.906-.655.08-1.041.201-1.344.282-.426.131-.686.26-1.375.343-1.311.16-1.762-.157-5.531.282-3.554.413-9.005 1.272-10.25 1.937-1.599-.297-3.858-.534-5.844-.344-3.059.294-4.972.484-6.906.657-1.934.172-1.689.422-2.906.53-1.317.118-1.76-.163-5.532.25-3.541.39-9.007 1.21-10.28 1.876-1.6-.295-3.888-.507-5.876-.313-3.058.3-4.94.48-6.875.657-.657.06-1.04.178-1.343.25-.428.118-.684.218-1.375.28-1.316.121-1.76-.194-5.532.22-3.556.39-9.005 1.239-10.25
+1.906-1.598-.294-3.86-.524-5.843-.313-3.056.326-4.974.526-6.907.719-1.932.192-1.69.44-2.906.562-1.315.132-1.763-.164-5.53.282-3.54.418-8.979 1.292-10.25 1.969-1.599-.282-3.86-.42-5.845-.188-3.052.358-4.945.568-6.875.781-.656.073-1.04.173-1.344.25-.426.127-.684.267-1.375.344-1.313.146-1.767-.174-5.53.313-3.55.458-8.98 1.419-10.22 2.125-1.593-.245-3.834-.382-5.812-.125-3.048.394-4.95.648-6.875.906-1.925.258-1.726.493-2.938.656-1.31.176-1.747-.104-5.5.469-3.524.538-8.923 1.699-10.188 2.437-1.587-.203-3.845-.254-5.812.094-3.026.536-4.9.862-6.813 1.187-.65.111-1.013.271-1.312.375-.42.165-.664.332-1.344.47-1.295.26-1.727-.007-5.438.812-3.498.772-8.846 2.383-10.062 3.219-1.562-.078-3.757.085-5.687.593-2.972.783-4.818 1.232-6.688 1.75s-1.666.768-2.843 1.094c-1.273.353-1.697.107-5.344 1.188-3.425 1.014-8.65 2.933-9.875 3.843-1.539.013-3.72.273-5.625.875-2.931.928-4.75 1.459-6.594
+2.063-.627.205-.992.392-1.281.531-.408.214-.653.409-1.313.625-1.254.412-1.686.19-5.28 1.438-3.39 1.177-8.596 3.213-9.782 4.156-1.524.06-3.65.395-5.531 1.062-2.898 1.029-4.7 1.676-6.531 2.313-1.833.637-1.628.848-2.782 1.25-1.246.434-1.663.2-5.218 1.562-3.34 1.28-8.488 3.483-9.688 4.47-1.507.107-3.636.498-5.5 1.218a1044.752 1044.752 0 0 1-6.437 2.469c-.617.233-.997.442-1.282.593v1.094c.112-.222.386-.817.907-1.094.698-.37 4.813-1.993 6.812-2.718 1.657-.602 4.154-1.329 5.969-1.313.302.003.588.051.844.094 1.842.308 7.468 1.562 7.468 1.562s-6.233-1.646-7.03-1.843c-.191-.048-.536-.07-.97-.063 1.146-.87 4.762-2.393 7.344-3.437 2.839-1.148 3.117-1.252 5.063-1.657 2.008-.417 3.156-.5 3.156-.5s-.082-.6.969-1.125c.705-.351 4.887-1.892 6.906-2.562 1.952-.648 5.057-1.359 6.875-1 1.863.367 7.531 1.812 7.531 1.812s-6.287-1.87-7.094-2.093c-.193-.054-.53-.086-.968-.094 1.158-.833 4.794-2.195 7.406-3.156
+2.87-1.056 3.167-1.162 5.125-1.532 1.853-.35 2.859-.425 3.031-.437.114-.217.377-.81.906-1.063.71-.338 4.926-1.712 6.97-2.312 1.692-.497 4.24-1.037 6.093-.906.308.021.613.097.875.156 1.881.424 7.594 2.031 7.594 2.031s-6.342-2.065-7.157-2.312c-.194-.06-.557-.104-1-.125 1.17-.798 4.863-2.057 7.5-2.938 2.898-.968 3.233-1.003 5.22-1.281 2.049-.287 3.187-.313 3.187-.313s-.073-.607 1-1.062c.72-.306 4.99-1.5 7.062-2 2.003-.483 5.199-.928 7.063-.406 1.91.535 7.719 2.5 7.719 2.5s-6.423-2.424-7.25-2.72c-.198-.07-.583-.14-1.032-.187 1.188-.728 4.916-1.774 7.594-2.5 2.944-.797 3.292-.77 5.313-.906 1.913-.128 2.947-.07 3.125-.062.117-.204.391-.78.937-.97.732-.253 5.079-1.047 7.188-1.374 1.748-.271 4.4-.485 6.312-.094.318.065.605.186.875.281 1.94.69 7.844 3.094 7.844 3.094s-6.535-2.95-7.375-3.312c-.201-.087-.575-.167-1.031-.25 1.206-.633 5.03-1.396 7.75-1.906 2.99-.562 3.3-.53 5.344-.532 2.109-.002
+3.312.125 3.312.125s-.073-.63 1.031-.937c.74-.206 5.126-.834 7.25-1.063 2.053-.22 5.319-.252 7.22.47 1.947.738 7.843 3.374 7.843 3.374s-6.563-3.179-7.406-3.562c-.202-.092-.543-.187-1-.282 1.21-.602 4.984-1.248 7.718-1.656 3.005-.448 3.326-.452 5.375-.406 1.94.043 3.007.194 3.188.219.119-.194.384-.766.937-.907.743-.188 5.155-.734 7.282-.937 1.763-.169 4.42-.234 6.343.25.32.08.604.203.875.312 1.953.784 7.907 3.47 7.907 3.47s-6.592-3.254-7.438-3.657c-.202-.096-.572-.207-1.031-.313 1.214-.574 5.044-1.122 7.781-1.5 3.009-.415 3.323-.442 5.375-.375 2.118.07 3.313.25 3.313.25s-.078-.637 1.03-.906c.745-.18 5.153-.663 7.282-.844 2.059-.174 5.343-.124 7.25.657 1.955.8 7.875 3.53 7.875 3.53s-6.56-3.308-7.406-3.718c-.202-.098-.572-.203-1.031-.312 1.215-.564 5.01-1.115 7.75-1.47 3.01-.389 3.321-.397 5.375-.312 1.944.08 3.006.254 3.187.282.12-.191.383-.746.938-.875.744-.174 5.15-.65 7.28-.813
+1.767-.134 4.45-.126 6.376.375.32.083.603.201.875.313 1.954.8 7.906 3.562 7.906 3.562s-6.591-3.34-7.437-3.75c-.203-.098-.572-.203-1.032-.312 1.215-.564 5.042-1.084 7.782-1.438 3.01-.39 3.352-.429 5.406-.344 2.12.088 3.312.313 3.312.313s-.078-.65 1.032-.906c.744-.173 5.15-.624 7.28-.782 2.061-.152 5.344-.096 7.25.688 1.956.804 7.876 3.5 7.876 3.5s-6.56-3.276-7.406-3.688c-.203-.098-.572-.202-1.032-.312 1.216-.562 5.012-1.128 7.75-1.5 3.01-.41 3.323-.416 5.375-.344 1.943.068 3.008.165 3.188.188.119-.195.384-.73.937-.875.742-.197 5.131-.83 7.25-1.094 1.757-.22 4.406-.333 6.313.031.317.06.606.19.875.281 1.936.661 7.844 2.938 7.844 2.938s-6.537-2.807-7.375-3.156c-.2-.084-.577-.174-1.032-.25 1.204-.651 5.02-1.372 7.72-2 2.966-.69 3.288-.756 5.312-.875 2.088-.124 3.28-.032 3.28-.032s-.086-.632 1-1.03c.73-.269 5.048-1.339 7.126-1.813 2.008-.46 5.168-1.03 7-.625 1.878.414 13.578 3.015 13.578
+3.015s-12.328-3.022-13.141-3.265c-.195-.058-.559-.107-1-.125 1.167-.804 3.514-1.688 6.11-2.703 1.68-.659.923-.377 2.775-1.004 1.754-.594 2.486-1.01 2.63-1.113.347-.207-.355-.122-.544-.042z" enable-background="new" filter="url(#jk)"/>
+   <path d="m1082.6-275.12c1.873 0.393 4.496 1.146 6.031 1.969s2.822 1.056 5.375 2.5c2.527 1.43 4.796 2.007 6.969 2.531 2.348 0.566 5.435 0.715 8.844 1.188-1.09-0.84-6.608-1.173-8.406-1.563-1.8-0.39-3.895-1.016-6.594-2.313-2.7-1.296-3.495-1.799-5.813-2.687-2.318-0.889-4.004-1.383-6.406-1.625z" enable-background="new" filter="url(#jj)"/>
+   <path d="M1051.5-270c1.905.578 4.528 1.616 6.094 2.594 1.565.978 2.88 1.36 5.5 3.125 2.593 1.747 4.986 2.71 7.25 3.594 2.446.955 5.682 1.657 9.406 3.062-1.19-1.138-7.063-2.687-8.938-3.375-1.874-.688-4.081-1.566-6.874-3.281-2.794-1.715-3.574-2.284-5.938-3.406-2.364-1.123-4.057-1.835-6.5-2.313z" enable-background="new" filter="url(#ji)"/>
+   <path d="m1020.2-266.84c1.912 0.638 4.581 1.755 6.156 2.813 1.575 1.057 2.896 1.508 5.531 3.406 2.61 1.878 5.029 3.03 7.313 4.062 2.468 1.116 5.764 2.174 9.531 3.844-1.203-1.222-7.203-3.314-9.094-4.125-1.89-0.81-4.064-1.894-6.874-3.75s-3.622-2.477-6-3.719c-2.379-1.242-4.111-1.975-6.563-2.531z" enable-background="new" filter="url(#jh)"/>
+   <path d="M1110.2-266.89c.15.049.688.631.11 1.484-.81 1.195-5.705 3.325-8.563 4.125-2.845.798-6.29.978-10.562-.375-4.302-1.362-5.47-2.468-10.656-4.312 4.664 2.115 6.195 3.952 10.125 5.344 1.62.574 3.367.94 5.062 1.03-.445.327-1.53.984-3.562 1.595-2.796.84-6.65 1.534-8.25 1.625-1.515.086-3.142-.513-3.438-.625.167.103.374.377-.25 1.03-.899.945-6.147 1.924-9.125 2.25-2.964.326-6.521-.015-10.906-1.905-3.978-1.715-5.339-2.916-9.406-4.75v.156c3.643 2.095 5.284 3.883 8.875 5.562 1.73.81 3.592 1.41 5.406 1.72-.534.286-1.557.71-3.437 1.03-2.87.488-6.81.817-8.438.75-.85-.034-1.728-.184-2.406-.406-.685-.215-1.19-.444-1.312-.5.169.107.43.403-.22 1.031-.909.88-6.245 1.337-9.25 1.47-2.99.131-6.588-.451-11-2.563-4.44-2.127-5.64-3.402-10.905-5.782 4.734 2.597 6.286 4.63 10.344 6.72 1.673.861 3.485 1.493 5.25 1.937-.463.233-1.59.688-3.688.937-2.886.343-6.834.493-8.468.375-1.547-.111-3.232-.857-3.532-1
+.17.12.414.41-.218 1-.913.851-6.244 1.262-9.25 1.375-2.993.113-6.59-.49-11-2.594-4.002-1.908-5.388-3.137-9.47-5.093v.156c3.656 2.204 5.295 4.053 8.907 5.906 1.74.893 3.637 1.528 5.469 1.969-.54.248-1.578.615-3.469.844-2.886.348-6.866.52-8.5.406a9.446 9.446 0 0 1-2.406-.5 12.532 12.532 0 0 1-1.313-.531c.17.112.465.422-.187 1.03-.913.853-6.275 1.294-9.281 1.407-2.993.112-6.594-.528-11-2.594-4.437-2.08-5.647-3.331-10.906-5.656 4.729 2.548 6.29 4.578 10.344 6.625 1.671.844 3.485 1.467 5.25 1.906-.464.235-1.59.684-3.688.938-2.886.348-6.836.57-8.469.469-1.544-.096-3.2-.83-3.5-.97.17.12.382.405-.25 1-.912.861-6.246 1.331-9.25 1.47-2.99.138-6.567-.451-10.969-2.47-3.993-1.83-5.365-3.028-9.437-4.905v.156c3.647 2.133 5.27 3.935 8.875 5.719 1.737.86 3.607 1.45 5.437 1.875-.54.253-1.55.64-3.437.906-2.88.404-6.838.646-8.469.562a9.36 9.36 0 0 1-2.406-.437 12.971 12.971 0 0
+1-1.313-.5c.17.109.432.41-.218 1.031-.911.87-6.25 1.392-9.25 1.563-2.987.17-6.574-.316-10.97-2.282-4.424-1.978-5.605-3.228-10.843-5.375 4.71 2.388 6.27 4.39 10.312 6.344a23.73 23.73 0 0 0 5.218 1.781c-.461.25-1.597.713-3.687 1.032-2.876.438-6.78.733-8.406.687-1.539-.043-3.233-.745-3.532-.875.169.113.411.414-.218 1.031-.908.891-6.203 1.529-9.188 1.813-2.971.283-6.573-.176-10.938-1.938-3.96-1.598-5.329-2.795-9.344-4.312v.156c3.596 1.811 5.239 3.582 8.813 5.156 1.722.759 3.587 1.29 5.406 1.625-.536.28-1.566.688-3.437 1.063-2.856.572-6.79 1.02-8.407 1.031-.844.006-1.706-.08-2.375-.25-.676-.162-1.16-.33-1.28-.375.166.094.422.383-.22 1.062-.897.951-6.186 1.918-9.125 2.438-2.925.518-6.432.374-10.719-1.031-4.315-1.415-5.472-2.53-10.562-3.969 4.577 1.751 6.09 3.56 10.031 5 1.627.594 3.37.956 5.094 1.156-.453.297-1.555.884-3.594 1.469-2.804.805-6.638 1.576-8.218
+1.75-1.495.165-3.117-.317-3.407-.406.164.09.393.36-.218 1.062-.883 1.014-6.045 2.372-8.938 3.063-2.88.687-6.335.76-10.562-.438-3.835-1.086-5.172-2.072-9.062-3.125v.156c3.484 1.395 5.07 2.92 8.53 4.032 1.669.535 3.457.786 5.22.875-.52.352-1.5.914-3.313 1.53-2.765.942-6.59 1.936-8.156 2.157-.818.115-1.633.123-2.281.031-.655-.083-1.133-.218-1.25-.25.162.075.434.34-.188 1.094-.87 1.055-6.01 2.66-8.875 3.438-2.852.774-6.259.958-10.438-.094-4.206-1.06-5.356-2.042-10.344-3.156 4.485 1.46 5.97 3.135 9.813 4.25 1.585.46 3.287.638 4.969.687-.442.337-1.513 1.028-3.5 1.781-2.734 1.037-6.452 2.163-8 2.438-1.465.26-3.06-.117-3.344-.188.16.08.38.321-.219 1.063-.865 1.07-5.916 2.818-8.75 3.687-2.82.866-6.207 1.157-10.344.22-3.753-.852-5.048-1.717-8.875-2.595v.157c3.428 1.237 4.987 2.632 8.375 3.53 1.632.434 3.367.584 5.094.563-.51.384-1.477 1.022-3.25 1.75-2.706 1.112-6.436 2.308-7.969
+2.625-.8.166-1.612.219-2.25.157v1.406c.227-.145.449-.273.719-.375 1.08-.41 2.171-.216 6-1.688 3.828-1.471 5.224-2.005 5.906-2.406.68-.4 1.612-.88 2.219-1.531 1.827-.138 3.57-.493 4.937-1 2.968-1.1 4.876-1.806 6.782-2.469 1.905-.663 2.354-1.415 3.406-1.781 1.091-.38 2.195-.166 6.062-1.531 3.868-1.366 5.283-1.827 5.969-2.22.701-.4 1.7-.932 2.313-1.593 1.97-.055 3.816-.385 5.28-.875 3.002-1.005 4.927-1.622 6.845-2.25 1.538-.504 2.174-1.047 2.906-1.437.23-.135.475-.254.75-.344 1.098-.36 2.181-.082 6.094-1.313 3.912-1.23 5.366-1.673 6.062-2.03.694-.358 1.63-.794 2.25-1.407 1.865-.023 3.636-.267 5.031-.688 3.03-.913 4.993-1.43 6.938-1.968 1.945-.54 2.426-1.265 3.5-1.563 1.114-.31 2.22.007 6.187-1.031 3.968-1.039 5.418-1.433 6.125-1.75.735-.33 1.814-.754 2.438-1.375 1.997.116 3.857-.02 5.344-.375 3.078-.735 5.083-1.101 7.062-1.5 1.588-.32 2.244-.79 3-1.094.238-.107.467-.193.75-.25 1.134-.23
+2.305.209 6.344-.5s5.5-.927 6.219-1.187c.715-.26 1.704-.568 2.343-1.094 1.925.24 3.748.224 5.188 0 3.126-.488 5.155-.7 7.156-.969 2.002-.268 2.489-.945 3.594-1.094 1.146-.154 2.276.302 6.344-.219 4.068-.52 5.56-.695 6.28-.937.738-.247 1.799-.586 2.438-1.125 2.05.335 3.974.398 5.5.219 3.143-.37 5.18-.56 7.188-.782 1.61-.178 2.265-.608 3.031-.843a3.43 3.43 0 0 1 .781-.188c1.15-.128 2.302.347 6.375-.125s5.56-.61 6.282-.844c.719-.232 1.7-.473 2.343-.968 1.937.333 3.77.404 5.22.25 3.145-.335 5.177-.519 7.187-.719 2.01-.2 2.484-.826 3.593-.938 1.152-.115 2.297.366 6.375-.062s5.59-.562 6.313-.781c.74-.224 1.796-.514 2.437-1.031 2.058.398 4.002.493 5.532.343 3.148-.308 5.175-.473 7.187-.656 1.614-.147 2.263-.56 3.031-.781.242-.081.494-.13.782-.156 1.152-.106 2.293.392 6.375 0 4.082-.393 5.589-.531 6.312-.75.721-.219 1.7-.448 2.344-.938 1.938.35 3.769.454 5.219.313 3.148-.309 5.175-.474
+7.187-.657 2.012-.183 2.514-.838 3.625-.937 1.152-.103 2.292.385 6.375 0s5.589-.501 6.313-.719c.739-.222 1.795-.514 2.437-1.031 2.057.402 4.003.503 5.531.344 3.147-.329 5.178-.523 7.188-.72 1.613-.156 2.266-.63 3.031-.874.24-.088.463-.122.75-.156 1.148-.14 2.317.34 6.375-.25 4.058-.59 5.562-.778 6.281-1.032.717-.253 1.675-.558 2.313-1.093 1.92.211 3.72.151 5.156-.094 3.12-.533 5.112-.929 7.094-1.313 1.982-.384 2.474-1.04 3.562-1.28 1.13-.252 2.27.115 6.25-.876s5.43-1.42 6.125-1.781c.723-.376 1.762-.87 2.375-1.531 1.963-.012 3.794-.291 5.22-.844 2.95-1.145 4.872-1.87 6.687-2.75 1.455-.707 2.334-1.686 2.547-1.984.212-.298.111-.746.137-.767.043-.035.32-.085.48-.429.858-1.847 2.32-5.644
+2.435-6.329.113-.682.163-1.348.214-1.745.03-.23-.147-.865-.125-.924.031-.082.305-.265.36-.515.267-1.198.09-2.191-.125-3.609-.214-1.417-.983-4.622-1.637-5.476-.659-.862-1.223-1.011-1.748-1-.208.27.137.262.163.312.68.05.934.369 1.42.897s1.442 3.94 1.579 5.39.19 2.86-.088 3.468c-.278.609-.944.429-1.237.495.531.186.89.213.953 1.057.058.814-.134 1.64-.52 2.806-.391 1.18-1.845 4.35-2.286 4.599-.452.255-.952.182-1.288.05z" enable-background="new" filter="url(#jg)"/>
+   <path d="m988.75-263.84c1.912 0.634 4.55 1.758 6.125 2.813 1.575 1.054 2.896 1.482 5.531 3.375 2.609 1.873 5.027 3.015 7.313 4.062 2.47 1.132 5.752 2.155 9.531 3.938-1.207-1.259-7.139-3.365-9.031-4.188s-4.128-1.93-6.938-3.781-3.622-2.482-6-3.719c-2.377-1.237-4.08-1.95-6.53-2.5z" enable-background="new" filter="url(#jf)"/>
+   <path d="M957.5-260.78c1.91.618 4.583 1.71 6.156 2.75 1.574 1.04 2.896 1.482 5.531 3.375 2.609 1.873 5.027 3.015 7.313 4.063 2.47 1.131 5.752 2.154 9.531 3.937-1.207-1.258-7.201-3.396-9.094-4.219-1.892-.823-4.096-1.93-6.906-3.781-2.81-1.85-3.593-2.44-5.969-3.656s-4.113-1.939-6.562-2.469z" enable-background="new" filter="url(#ib)"/>
+   <path d="M926.09-257.38c1.908.597 4.553 1.664 6.125 2.688 1.571 1.023 2.87 1.44 5.5 3.28 2.603 1.823 5.029 2.973 7.313 4 2.467 1.111 5.755 2.094 9.53 3.845-1.205-1.249-7.171-3.319-9.062-4.125s-4.102-1.891-6.906-3.688c-2.804-1.796-3.627-2.402-6-3.594-2.373-1.191-4.054-1.903-6.5-2.406z" enable-background="new" filter="url(#ia)"/>
+   <path d="M894.91-253.56c1.902.554 4.587 1.589 6.156 2.594s2.874 1.408 5.5 3.219c2.6 1.791 5 2.871 7.281 3.875 2.465 1.083 5.76 2.04 9.532 3.75-1.205-1.236-7.175-3.245-9.063-4.032-1.888-.786-4.075-1.83-6.875-3.593s-3.6-2.369-5.969-3.532c-2.37-1.163-4.123-1.834-6.562-2.28z" enable-background="new" filter="url(#hz)"/>
+   <path d="M863.72-248.66c1.88.43 4.504 1.38 6.063 2.313 1.558.932 2.852 1.257 5.468 3 2.59 1.724 4.981 2.708 7.25 3.625 2.452.99 5.74 1.877 9.5 3.5-1.201-1.208-7.152-3.067-9.03-3.782-1.88-.715-4.086-1.684-6.876-3.375s-3.585-2.228-5.937-3.28-4.026-1.713-6.438-2z" enable-background="new" filter="url(#hy)"/>
+   <path d="m833.16-241.38c1.848 0.296 4.47 0.976 6 1.781s2.814 1.056 5.375 2.531c2.535 1.46 4.89 2.326 7.125 3.063 2.414 0.797 5.657 1.467 9.375 2.844-1.188-1.129-7.088-2.59-8.938-3.156-1.85-0.567-4.003-1.374-6.75-2.844-2.746-1.47-3.5-1.92-5.812-2.781-2.311-0.861-4.005-1.32-6.375-1.438z" enable-background="new" filter="url(#hx)"/>
+   <path d="m802.91-232.31c1.822 0.211 4.366 0.8 5.875 1.531 1.51 0.73 2.756 0.93 5.281 2.281 2.5 1.338 4.832 2.049 7.031 2.657 2.377 0.656 5.565 1.073 9.22 2.187-1.168-1.045-6.93-2.103-8.75-2.562-1.822-0.46-3.953-1.127-6.657-2.438s-3.471-1.72-5.75-2.469-3.913-1.179-6.25-1.187z" enable-background="new" filter="url(#hw)"/>
+   <path d="M773.19-222.19c1.811.179 4.32.665 5.813 1.344 1.491.678 2.753.798 5.25 2.062 2.47 1.252 4.79 1.896 6.968 2.438 2.354.585 5.492.897 9.094 1.844-1.15-.992-6.852-1.784-8.656-2.188s-3.916-1.021-6.594-2.25c-2.678-1.229-3.403-1.61-5.656-2.281-2.253-.67-3.896-1.002-6.219-.969z" enable-background="new" filter="url(#hv)"/>
+   <path d="M743.56-211.19c1.793.13 4.273.55 5.75 1.188s2.716.741 5.188 1.937c2.446 1.184 4.72 1.747 6.874 2.219 2.328.51 5.42.68 9 1.562-1.143-.97-6.747-1.59-8.53-1.937-1.784-.347-3.884-.888-6.532-2.031-2.648-1.144-3.395-1.517-5.625-2.125-2.23-.61-3.826-.91-6.125-.813z" enable-background="new" filter="url(#hu)"/>
+   <g fill="#fff" filter="url(#ht)">
+    <path d="M744.94-212.12s7.222-3.223 9.063-3.5 3.352-.003 6 .563c2.647.565 8.735 2.215 11.188 3.374s5.312 3.563 5.312 3.563-7.146-2.78-10.188-3.563-7.645-2.083-10.375-2.312-11 1.875-11 1.875z"/>
+    <path d="m735.47-206.95s3.66-2.223 5.5-2.5 3.665 0.247 6.313 0.813 8.735 2.215 11.188 3.375 6.562 2.125 6.562 2.125-8.396-1.343-11.438-2.125-7.957-2.334-10.688-2.563-7.438 0.875-7.438 0.875zm24.38-10.66s8.544-3.299 10.398-3.458c1.854-0.16 3.642 0.48 6.248 1.212s8.577 2.766 10.95 4.08 6.414 2.537 6.414 2.537-8.294-1.873-11.279-2.848c-2.985-0.974-7.792-2.834-10.503-3.236s-12.228 1.713-12.228 1.713zm15.35-5.62s7.771-2.782 9.628-2.904c1.857-0.12 3.631 0.555 6.222 1.341 2.59 0.787 8.519 2.942 10.864 4.304 2.346 1.362 6.36 2.67 6.36 2.67s-8.253-2.045-11.217-3.08c-2.965-1.035-7.733-2.995-10.434-3.452-2.702-0.458-11.422 1.121-11.422 1.121zm14.44-4.72s8.683-3.52 10.542-3.605 3.62 0.624 6.195 1.46c2.575 0.837 8.46 3.107 10.779 4.514 2.318 1.408 6.307 2.793 6.307 2.793s-8.212-2.204-11.156-3.297-7.673-3.144-10.365-3.654-12.3 1.789-12.3 1.789zm14.86-5.38s7.808-2.583 9.666-2.668c1.86-0.085 3.62
+0.625 6.195 1.461 2.575 0.837 8.46 3.107 10.78 4.514 2.318 1.407 6.307 2.792 6.307 2.792s-8.213-2.204-11.156-3.296-7.673-3.144-10.365-3.654-11.426 0.85-11.426 0.85zm15.06-4.25s8.558-2.583 10.417-2.668 3.62 0.625 6.195 1.461c2.575 0.837 8.46 3.107 10.779 4.514 2.318 1.407 6.307 2.792 6.307 2.792s-8.212-2.204-11.156-3.296-7.673-3.144-10.365-3.654-12.176 0.85-12.176 0.85zm16.67-5.02s6.967-1.987 8.828-1.968c1.86 0.02 3.579 0.827 6.102 1.807 2.524 0.98 8.272 3.578 10.508 5.113 2.236 1.536 6.14 3.143 6.14 3.143s-8.075-2.662-10.952-3.919c-2.878-1.256-7.484-3.57-10.143-4.231-2.66-0.66-10.482 0.055-10.482 0.055zm14.5-3.4s7.688-2.028 9.548-1.968 3.56 0.902 6.063 1.936c2.502 1.033 8.194 3.752 10.397 5.335 2.203 1.582 6.072 3.272 6.072 3.272s-8.017-2.833-10.868-4.15c-2.85-1.318-7.407-3.73-10.05-4.446s-11.162 0.021-11.162 0.021zm14.09-3.21s8.17-1.97 10.027-1.854c1.857 0.115 3.532 1.01 6.002
+2.118s8.077 3.997 10.23 5.645 5.972 3.454 5.972 3.454-7.928-3.074-10.738-4.476-7.291-3.95-9.913-4.746c-2.621-0.796-11.58-0.141-11.58-0.141zm16.56-2.39s8.085-1.908 9.938-1.737c1.853 0.172 3.5 1.117 5.935 2.3 2.436 1.182 7.952 4.24 10.055 5.953s5.864 3.633 5.864 3.633-7.832-3.312-10.597-4.8-7.168-4.169-9.764-5.044c-2.597-0.876-11.431-0.305-11.431-0.305zm15.2-2.75s7.642-1.428 9.495-1.265c1.854 0.162 3.505 1.1 5.946 2.27s7.973 4.203 10.084 5.905c2.112 1.703 5.881 3.605 5.881 3.605s-7.847-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.788-4.998-2.6-0.863-10.998-0.77-10.998-0.77zm14.87-1.64s8.642-1.553 10.495-1.39c1.854 0.162 3.505 1.1 5.946 2.27s7.972 4.203 10.084 5.905c2.111 1.703 5.88 3.605 5.88 3.605s-7.846-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.787-4.998-2.601-0.863-11.998-0.644-11.998-0.644zm16.25-2.31s7.642-0.865 9.495-0.703c1.854 0.163 3.505 1.1 5.946 2.27s7.973 4.203 10.084
+5.906c2.112 1.702 5.881 3.605 5.881 3.605s-7.847-3.275-10.62-4.749c-2.772-1.474-7.187-4.135-9.788-4.998-2.6-0.862-10.998-1.331-10.998-1.331zm15.13-1.19s8.58-1.49 10.433-1.328c1.854 0.163 3.505 1.1 5.946 2.27s7.972 4.203 10.084 5.906c2.111 1.702 5.88 3.605 5.88 3.605s-7.846-3.275-10.62-4.749c-2.772-1.474-7.187-4.135-9.787-4.998-2.601-0.862-11.935-0.706-11.935-0.706zm16.25-2.06s7.83-0.803 9.683-0.64c1.854 0.162 3.505 1.1 5.946 2.27s7.972 4.203 10.084 5.905c2.111 1.703 5.88 3.605 5.88 3.605s-7.846-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.787-4.998-2.601-0.863-11.185-1.394-11.185-1.394zm15.37-1.25s8.392-1.178 10.245-1.015c1.854 0.162 3.505 1.1 5.946 2.27s7.972 4.203 10.084 5.905c2.111 1.703 5.88 3.605 5.88 3.605s-7.847-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.788-4.998-2.6-0.863-11.748-1.02-11.748-1.02zm16.19-2.06s6.892-0.99 8.745-0.828c1.854 0.163 3.505 1.1 5.946 2.27s7.973 4.203
+10.084 5.906c2.112 1.702 5.881 3.605 5.881 3.605s-7.847-3.275-10.62-4.749-7.188-4.135-9.788-4.998c-2.6-0.862-10.248-1.206-10.248-1.206zm17.16-0.94s6.83-1.178 8.683-1.015c1.854 0.162 3.505 1.1 5.946 2.27 2.44 1.171 7.972 4.203 10.084 5.905 2.111 1.703 5.88 3.605 5.88 3.605s-7.847-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.788-4.998-2.6-0.863-10.185-1.02-10.185-1.02zm16.1-2s6.08-0.428 7.933-0.265c1.854 0.162 3.505 1.1 5.946 2.27 2.44 1.171 7.972 4.203 10.084 5.905 2.111 1.703 5.88 3.605 5.88 3.605s-7.847-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.788-4.998-2.6-0.863-9.435-1.77-9.435-1.77zm15.8-1.37s6.454-0.678 8.308-0.515c1.854 0.162 3.505 1.1 5.946 2.27 2.44 1.171 7.972 4.203 10.084 5.905 2.111 1.703 5.88 3.605 5.88 3.605s-7.847-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.788-4.998-2.6-0.863-9.81-1.52-9.81-1.52zm15.6-1.86s5.498-0.91 7.358-0.853c1.86 0.056 3.562 0.896 6.066 1.925
+2.504 1.03 8.2 3.739 10.406 5.318 2.205 1.578 6.078 3.261 6.078 3.261s-8.022-2.819-10.875-4.131c-2.853-1.313-7.413-3.716-10.06-4.429-2.645-0.712-8.973-1.091-8.973-1.091zm17.4-2.46s4.547-1.156 6.408-1.186c1.86-0.03 3.6 0.73 6.149 1.642 2.55 0.912 8.365 3.354 10.64 4.829 2.277 1.474 6.224 2.976 6.224 2.976s-8.145-2.444-11.055-3.623c-2.91-1.178-7.578-3.368-10.253-3.957-2.676-0.588-8.113-0.68-8.113-0.68zm14.5-3.03s5.96-1.774 7.82-1.83c1.86-0.057 3.61 0.68 6.172 1.555 2.562 0.876 2.522 0.857 5.333 1.49 2.797 0.63 7.077 1.513 7.077 1.513s-3.616-0.016-6.792-0.466c-3.116-0.441-7.375-1.698-10.058-2.249-2.684-0.55-9.552-0.013-9.552-0.013z" enable-background="new"/>
+    <path d="M1099.2-279.93c.161.269 11.208-4.6 12.188-4.688.98-.087 2 3.125 2 3.125s-.775-1.504-2.875-1.062-11.301 2.671-11.312 2.625z"/>
+   </g>
+   <path d="M1107.5-284.09c-.419.213-.156.094-.647.306-.486.21-1.724.574-4.08 1.459-3.33 1.25-5.83 2.153-7.026 3.066-1.536.021-3.72.233-5.656.719a227.709 227.709 0 0 1-6.75 1.593c-1.895.42-1.676.643-2.875.875-1.297.252-1.721-.009-5.438.782-3.49.742-8.894 1.93-10.156 2.687-1.583-.18-3.867-.322-5.843-.031-3.04.447-4.917.673-6.844.906-.655.08-1.041.201-1.344.282-.426.131-.686.26-1.375.343-1.311.16-1.762-.157-5.531.282-3.554.413-9.005 1.272-10.25 1.937-1.599-.297-3.858-.534-5.844-.344-3.059.294-4.972.484-6.906.657-1.934.172-1.689.422-2.906.53-1.317.118-1.76-.163-5.532.25-3.541.39-9.007 1.21-10.28 1.876-1.6-.295-3.888-.507-5.876-.313-3.058.3-4.94.48-6.875.657-.657.06-1.04.178-1.343.25-.428.118-.684.218-1.375.28-1.316.121-1.76-.194-5.532.22-3.556.39-9.005 1.239-10.25
+1.906-1.598-.294-3.86-.524-5.843-.313-3.056.326-4.974.526-6.907.719-1.932.192-1.69.44-2.906.562-1.315.132-1.763-.164-5.53.282-3.54.418-8.979 1.292-10.25 1.969-1.599-.282-3.86-.42-5.845-.188-3.052.358-4.945.568-6.875.781-.656.073-1.04.173-1.344.25-.426.127-.684.267-1.375.344-1.313.146-1.767-.174-5.53.313-3.55.458-8.98 1.419-10.22 2.125-1.593-.245-3.834-.382-5.812-.125-3.048.394-4.95.648-6.875.906-1.925.258-1.726.493-2.938.656-1.31.176-1.747-.104-5.5.469-3.524.538-8.923 1.699-10.188 2.437-1.587-.203-3.845-.254-5.812.094-3.026.536-4.9.862-6.813 1.187-.65.111-1.013.271-1.312.375-.42.165-.664.332-1.344.47-1.295.26-1.727-.007-5.438.812-3.498.772-8.846 2.383-10.062 3.219-1.562-.078-3.757.085-5.687.593-2.972.783-4.818 1.232-6.688 1.75s-1.666.768-2.843 1.094c-1.273.353-1.697.107-5.344 1.188-3.425 1.014-8.65 2.933-9.875 3.843-1.539.013-3.72.273-5.625.875-2.931.928-4.75 1.459-6.594
+2.063-.627.205-.992.392-1.281.531-.408.214-.653.409-1.313.625-1.254.412-1.686.19-5.28 1.438-3.39 1.177-8.596 3.213-9.782 4.156-1.524.06-3.65.395-5.531 1.062-2.898 1.029-4.7 1.676-6.531 2.313-1.833.637-1.628.848-2.782 1.25-1.246.434-1.663.2-5.218 1.562-3.34 1.28-8.488 3.483-9.688 4.47-1.507.107-3.636.498-5.5 1.218a1044.752 1044.752 0 0 1-6.437 2.469c-.617.233-.997.442-1.282.593v1.094c.112-.222.386-.817.907-1.094.698-.37 4.813-1.993 6.812-2.718 1.657-.602 4.154-1.329 5.969-1.313.302.003.588.051.844.094 1.842.308 7.468 1.562 7.468 1.562s-6.233-1.646-7.03-1.843c-.191-.048-.536-.07-.97-.063 1.146-.87 4.762-2.393 7.344-3.437 2.839-1.148 3.117-1.252 5.063-1.657 2.008-.417 3.156-.5 3.156-.5s-.082-.6.969-1.125c.705-.351 4.887-1.892 6.906-2.562 1.952-.648 5.057-1.359 6.875-1 1.863.367 7.531 1.812 7.531 1.812s-6.287-1.87-7.094-2.093c-.193-.054-.53-.086-.968-.094 1.158-.833 4.794-2.195 7.406-3.156
+2.87-1.056 3.167-1.162 5.125-1.532 1.853-.35 2.859-.425 3.031-.437.114-.217.377-.81.906-1.063.71-.338 4.926-1.712 6.97-2.312 1.692-.497 4.24-1.037 6.093-.906.308.021.613.097.875.156 1.881.424 7.594 2.031 7.594 2.031s-6.342-2.065-7.157-2.312c-.194-.06-.557-.104-1-.125 1.17-.798 4.863-2.057 7.5-2.938 2.898-.968 3.233-1.003 5.22-1.281 2.049-.287 3.187-.313 3.187-.313s-.073-.607 1-1.062c.72-.306 4.99-1.5 7.062-2 2.003-.483 5.199-.928 7.063-.406 1.91.535 7.719 2.5 7.719 2.5s-6.423-2.424-7.25-2.72c-.198-.07-.583-.14-1.032-.187 1.188-.728 4.916-1.774 7.594-2.5 2.944-.797 3.292-.77 5.313-.906 1.913-.128 2.947-.07 3.125-.062.117-.204.391-.78.937-.97.732-.253 5.079-1.047 7.188-1.374 1.748-.271 4.4-.485 6.312-.094.318.065.605.186.875.281 1.94.69 7.844 3.094 7.844 3.094s-6.535-2.95-7.375-3.312c-.201-.087-.575-.167-1.031-.25 1.206-.633 5.03-1.396 7.75-1.906 2.99-.562 3.3-.53 5.344-.532 2.109-.002
+3.312.125 3.312.125s-.073-.63 1.031-.937c.74-.206 5.126-.834 7.25-1.063 2.053-.22 5.319-.252 7.22.47 1.947.738 7.843 3.374 7.843 3.374s-6.563-3.179-7.406-3.562c-.202-.092-.543-.187-1-.282 1.21-.602 4.984-1.248 7.718-1.656 3.005-.448 3.326-.452 5.375-.406 1.94.043 3.007.194 3.188.219.119-.194.384-.766.937-.907.743-.188 5.155-.734 7.282-.937 1.763-.169 4.42-.234 6.343.25.32.08.604.203.875.312 1.953.784 7.907 3.47 7.907 3.47s-6.592-3.254-7.438-3.657c-.202-.096-.572-.207-1.031-.313 1.214-.574 5.044-1.122 7.781-1.5 3.009-.415 3.323-.442 5.375-.375 2.118.07 3.313.25 3.313.25s-.078-.637 1.03-.906c.745-.18 5.153-.663 7.282-.844 2.059-.174 5.343-.124 7.25.657 1.955.8 7.875 3.53 7.875 3.53s-6.56-3.308-7.406-3.718c-.202-.098-.572-.203-1.031-.312 1.215-.564 5.01-1.115 7.75-1.47 3.01-.389 3.321-.397 5.375-.312 1.944.08 3.006.254 3.187.282.12-.191.383-.746.938-.875.744-.174 5.15-.65 7.28-.813
+1.767-.134 4.45-.126 6.376.375.32.083.603.201.875.313 1.954.8 7.906 3.562 7.906 3.562s-6.591-3.34-7.437-3.75c-.203-.098-.572-.203-1.032-.312 1.215-.564 5.042-1.084 7.782-1.438 3.01-.39 3.352-.429 5.406-.344 2.12.088 3.312.313 3.312.313s-.078-.65 1.032-.906c.744-.173 5.15-.624 7.28-.782 2.061-.152 5.344-.096 7.25.688 1.956.804 7.876 3.5 7.876 3.5s-6.56-3.276-7.406-3.688c-.203-.098-.572-.202-1.032-.312 1.216-.562 5.012-1.128 7.75-1.5 3.01-.41 3.323-.416 5.375-.344 1.943.068 3.008.165 3.188.188.119-.195.384-.73.937-.875.742-.197 5.131-.83 7.25-1.094 1.757-.22 4.406-.333 6.313.031.317.06.606.19.875.281 1.936.661 7.844 2.938 7.844 2.938s-6.537-2.807-7.375-3.156c-.2-.084-.577-.174-1.032-.25 1.204-.651 5.02-1.372 7.72-2 2.966-.69 3.288-.756 5.312-.875 2.088-.124 3.28-.032 3.28-.032s-.086-.632 1-1.03c.73-.269 5.048-1.339 7.126-1.813 2.008-.46 5.168-1.03 7-.625 1.878.414 13.578 3.015 13.578
+3.015s-12.328-3.022-13.141-3.265c-.195-.058-.559-.107-1-.125 1.167-.804 3.514-1.688 6.11-2.703 1.68-.659.923-.377 2.775-1.004 1.754-.594 2.486-1.01 2.63-1.113.347-.207-.355-.122-.544-.042z" enable-background="new" filter="url(#hs)" opacity=".25"/>
+   <path d="m1082.6-275.12c1.873 0.393 4.496 1.146 6.031 1.969s2.822 1.056 5.375 2.5c2.527 1.43 4.796 2.007 6.969 2.531 2.348 0.566 5.435 0.715 8.844 1.188-1.09-0.84-6.608-1.173-8.406-1.563-1.8-0.39-3.895-1.016-6.594-2.313-2.7-1.296-3.495-1.799-5.813-2.687-2.318-0.889-4.004-1.383-6.406-1.625z" enable-background="new" filter="url(#hr)" opacity=".25"/>
+   <path d="M1051.5-270c1.905.578 4.528 1.616 6.094 2.594 1.565.978 2.88 1.36 5.5 3.125 2.593 1.747 4.986 2.71 7.25 3.594 2.446.955 5.682 1.657 9.406 3.062-1.19-1.138-7.063-2.687-8.938-3.375-1.874-.688-4.081-1.566-6.874-3.281-2.794-1.715-3.574-2.284-5.938-3.406-2.364-1.123-4.057-1.835-6.5-2.313z" enable-background="new" filter="url(#hq)" opacity=".25"/>
+   <path d="m1020.2-266.84c1.912 0.638 4.581 1.755 6.156 2.813 1.575 1.057 2.896 1.508 5.531 3.406 2.61 1.878 5.029 3.03 7.313 4.062 2.468 1.116 5.764 2.174 9.531 3.844-1.203-1.222-7.203-3.314-9.094-4.125-1.89-0.81-4.064-1.894-6.874-3.75s-3.622-2.477-6-3.719c-2.379-1.242-4.111-1.975-6.563-2.531z" enable-background="new" filter="url(#hp)" opacity=".25"/>
+   <path d="M1110.2-266.89c.15.049.688.631.11 1.484-.81 1.195-5.705 3.325-8.563 4.125-2.845.798-6.29.978-10.562-.375-4.302-1.362-5.47-2.468-10.656-4.312 4.664 2.115 6.195 3.952 10.125 5.344 1.62.574 3.367.94 5.062 1.03-.445.327-1.53.984-3.562 1.595-2.796.84-6.65 1.534-8.25 1.625-1.515.086-3.142-.513-3.438-.625.167.103.374.377-.25 1.03-.899.945-6.147 1.924-9.125 2.25-2.964.326-6.521-.015-10.906-1.905-3.978-1.715-5.339-2.916-9.406-4.75v.156c3.643 2.095 5.284 3.883 8.875 5.562 1.73.81 3.592 1.41 5.406 1.72-.534.286-1.557.71-3.437 1.03-2.87.488-6.81.817-8.438.75-.85-.034-1.728-.184-2.406-.406-.685-.215-1.19-.444-1.312-.5.169.107.43.403-.22 1.031-.909.88-6.245 1.337-9.25 1.47-2.99.131-6.588-.451-11-2.563-4.44-2.127-5.64-3.402-10.905-5.782 4.734 2.597 6.286 4.63 10.344 6.72 1.673.861 3.485 1.493 5.25 1.937-.463.233-1.59.688-3.688.937-2.886.343-6.834.493-8.468.375-1.547-.111-3.232-.857-3.532-1
+.17.12.414.41-.218 1-.913.851-6.244 1.262-9.25 1.375-2.993.113-6.59-.49-11-2.594-4.002-1.908-5.388-3.137-9.47-5.093v.156c3.656 2.204 5.295 4.053 8.907 5.906 1.74.893 3.637 1.528 5.469 1.969-.54.248-1.578.615-3.469.844-2.886.348-6.866.52-8.5.406a9.446 9.446 0 0 1-2.406-.5 12.532 12.532 0 0 1-1.313-.531c.17.112.465.422-.187 1.03-.913.853-6.275 1.294-9.281 1.407-2.993.112-6.594-.528-11-2.594-4.437-2.08-5.647-3.331-10.906-5.656 4.729 2.548 6.29 4.578 10.344 6.625 1.671.844 3.485 1.467 5.25 1.906-.464.235-1.59.684-3.688.938-2.886.348-6.836.57-8.469.469-1.544-.096-3.2-.83-3.5-.97.17.12.382.405-.25 1-.912.861-6.246 1.331-9.25 1.47-2.99.138-6.567-.451-10.969-2.47-3.993-1.83-5.365-3.028-9.437-4.905v.156c3.647 2.133 5.27 3.935 8.875 5.719 1.737.86 3.607 1.45 5.437 1.875-.54.253-1.55.64-3.437.906-2.88.404-6.838.646-8.469.562a9.36 9.36 0 0 1-2.406-.437 12.971 12.971 0 0
+1-1.313-.5c.17.109.432.41-.218 1.031-.911.87-6.25 1.392-9.25 1.563-2.987.17-6.574-.316-10.97-2.282-4.424-1.978-5.605-3.228-10.843-5.375 4.71 2.388 6.27 4.39 10.312 6.344a23.73 23.73 0 0 0 5.218 1.781c-.461.25-1.597.713-3.687 1.032-2.876.438-6.78.733-8.406.687-1.539-.043-3.233-.745-3.532-.875.169.113.411.414-.218 1.031-.908.891-6.203 1.529-9.188 1.813-2.971.283-6.573-.176-10.938-1.938-3.96-1.598-5.329-2.795-9.344-4.312v.156c3.596 1.811 5.239 3.582 8.813 5.156 1.722.759 3.587 1.29 5.406 1.625-.536.28-1.566.688-3.437 1.063-2.856.572-6.79 1.02-8.407 1.031-.844.006-1.706-.08-2.375-.25-.676-.162-1.16-.33-1.28-.375.166.094.422.383-.22 1.062-.897.951-6.186 1.918-9.125 2.438-2.925.518-6.432.374-10.719-1.031-4.315-1.415-5.472-2.53-10.562-3.969 4.577 1.751 6.09 3.56 10.031 5 1.627.594 3.37.956 5.094 1.156-.453.297-1.555.884-3.594 1.469-2.804.805-6.638 1.576-8.218
+1.75-1.495.165-3.117-.317-3.407-.406.164.09.393.36-.218 1.062-.883 1.014-6.045 2.372-8.938 3.063-2.88.687-6.335.76-10.562-.438-3.835-1.086-5.172-2.072-9.062-3.125v.156c3.484 1.395 5.07 2.92 8.53 4.032 1.669.535 3.457.786 5.22.875-.52.352-1.5.914-3.313 1.53-2.765.942-6.59 1.936-8.156 2.157-.818.115-1.633.123-2.281.031-.655-.083-1.133-.218-1.25-.25.162.075.434.34-.188 1.094-.87 1.055-6.01 2.66-8.875 3.438-2.852.774-6.259.958-10.438-.094-4.206-1.06-5.356-2.042-10.344-3.156 4.485 1.46 5.97 3.135 9.813 4.25 1.585.46 3.287.638 4.969.687-.442.337-1.513 1.028-3.5 1.781-2.734 1.037-6.452 2.163-8 2.438-1.465.26-3.06-.117-3.344-.188.16.08.38.321-.219 1.063-.865 1.07-5.916 2.818-8.75 3.687-2.82.866-6.207 1.157-10.344.22-3.753-.852-5.048-1.717-8.875-2.595v.157c3.428 1.237 4.987 2.632 8.375 3.53 1.632.434 3.367.584 5.094.563-.51.384-1.477 1.022-3.25 1.75-2.706 1.112-6.436 2.308-7.969
+2.625-.8.166-1.612.219-2.25.157v1.406c.227-.145.449-.273.719-.375 1.08-.41 2.171-.216 6-1.688 3.828-1.471 5.224-2.005 5.906-2.406.68-.4 1.612-.88 2.219-1.531 1.827-.138 3.57-.493 4.937-1 2.968-1.1 4.876-1.806 6.782-2.469 1.905-.663 2.354-1.415 3.406-1.781 1.091-.38 2.195-.166 6.062-1.531 3.868-1.366 5.283-1.827 5.969-2.22.701-.4 1.7-.932 2.313-1.593 1.97-.055 3.816-.385 5.28-.875 3.002-1.005 4.927-1.622 6.845-2.25 1.538-.504 2.174-1.047 2.906-1.437.23-.135.475-.254.75-.344 1.098-.36 2.181-.082 6.094-1.313 3.912-1.23 5.366-1.673 6.062-2.03.694-.358 1.63-.794 2.25-1.407 1.865-.023 3.636-.267 5.031-.688 3.03-.913 4.993-1.43 6.938-1.968 1.945-.54 2.426-1.265 3.5-1.563 1.114-.31 2.22.007 6.187-1.031 3.968-1.039 5.418-1.433 6.125-1.75.735-.33 1.814-.754 2.438-1.375 1.997.116 3.857-.02 5.344-.375 3.078-.735 5.083-1.101 7.062-1.5 1.588-.32 2.244-.79 3-1.094.238-.107.467-.193.75-.25 1.134-.23
+2.305.209 6.344-.5s5.5-.927 6.219-1.187c.715-.26 1.704-.568 2.343-1.094 1.925.24 3.748.224 5.188 0 3.126-.488 5.155-.7 7.156-.969 2.002-.268 2.489-.945 3.594-1.094 1.146-.154 2.276.302 6.344-.219 4.068-.52 5.56-.695 6.28-.937.738-.247 1.799-.586 2.438-1.125 2.05.335 3.974.398 5.5.219 3.143-.37 5.18-.56 7.188-.782 1.61-.178 2.265-.608 3.031-.843a3.43 3.43 0 0 1 .781-.188c1.15-.128 2.302.347 6.375-.125s5.56-.61 6.282-.844c.719-.232 1.7-.473 2.343-.968 1.937.333 3.77.404 5.22.25 3.145-.335 5.177-.519 7.187-.719 2.01-.2 2.484-.826 3.593-.938 1.152-.115 2.297.366 6.375-.062s5.59-.562 6.313-.781c.74-.224 1.796-.514 2.437-1.031 2.058.398 4.002.493 5.532.343 3.148-.308 5.175-.473 7.187-.656 1.614-.147 2.263-.56 3.031-.781.242-.081.494-.13.782-.156 1.152-.106 2.293.392 6.375 0 4.082-.393 5.589-.531 6.312-.75.721-.219 1.7-.448 2.344-.938 1.938.35 3.769.454 5.219.313 3.148-.309 5.175-.474
+7.187-.657 2.012-.183 2.514-.838 3.625-.937 1.152-.103 2.292.385 6.375 0s5.589-.501 6.313-.719c.739-.222 1.795-.514 2.437-1.031 2.057.402 4.003.503 5.531.344 3.147-.329 5.178-.523 7.188-.72 1.613-.156 2.266-.63 3.031-.874.24-.088.463-.122.75-.156 1.148-.14 2.317.34 6.375-.25 4.058-.59 5.562-.778 6.281-1.032.717-.253 1.675-.558 2.313-1.093 1.92.211 3.72.151 5.156-.094 3.12-.533 5.112-.929 7.094-1.313 1.982-.384 2.474-1.04 3.562-1.28 1.13-.252 2.27.115 6.25-.876s5.43-1.42 6.125-1.781c.723-.376 1.762-.87 2.375-1.531 1.963-.012 3.794-.291 5.22-.844 2.95-1.145 4.872-1.87 6.687-2.75 1.455-.707 2.334-1.686 2.547-1.984.212-.298.111-.746.137-.767.043-.035.32-.085.48-.429.858-1.847 2.32-5.644
+2.435-6.329.113-.682.163-1.348.214-1.745.03-.23-.147-.865-.125-.924.031-.082.305-.265.36-.515.267-1.198.09-2.191-.125-3.609-.214-1.417-.983-4.622-1.637-5.476-.659-.862-1.223-1.011-1.748-1-.208.27.137.262.163.312.68.05.934.369 1.42.897s1.221 3.85 1.358 5.301.19 2.86-.088 3.469c-.278.608-.723.517-1.016.583.531.186.67.125.732.969.058.813-.134 1.64-.52 2.806-.392 1.18-1.846 4.35-2.286 4.598-.452.256-.731.27-1.067.14z" enable-background="new" filter="url(#ho)" opacity=".25"/>
+   <path d="m988.75-263.84c1.912 0.634 4.55 1.758 6.125 2.813 1.575 1.054 2.896 1.482 5.531 3.375 2.609 1.873 5.027 3.015 7.313 4.062 2.47 1.132 5.752 2.155 9.531 3.938-1.207-1.259-7.139-3.365-9.031-4.188s-4.128-1.93-6.938-3.781-3.622-2.482-6-3.719c-2.377-1.237-4.08-1.95-6.53-2.5z" enable-background="new" filter="url(#hn)" opacity=".25"/>
+   <path d="M957.5-260.78c1.91.618 4.583 1.71 6.156 2.75 1.574 1.04 2.896 1.482 5.531 3.375 2.609 1.873 5.027 3.015 7.313 4.063 2.47 1.131 5.752 2.154 9.531 3.937-1.207-1.258-7.201-3.396-9.094-4.219-1.892-.823-4.096-1.93-6.906-3.781-2.81-1.85-3.593-2.44-5.969-3.656s-4.113-1.939-6.562-2.469z" enable-background="new" filter="url(#hm)" opacity=".25"/>
+   <path d="M926.09-257.38c1.908.597 4.553 1.664 6.125 2.688 1.571 1.023 2.87 1.44 5.5 3.28 2.603 1.823 5.029 2.973 7.313 4 2.467 1.111 5.755 2.094 9.53 3.845-1.205-1.249-7.171-3.319-9.062-4.125s-4.102-1.891-6.906-3.688c-2.804-1.796-3.627-2.402-6-3.594-2.373-1.191-4.054-1.903-6.5-2.406z" enable-background="new" filter="url(#hl)" opacity=".25"/>
+   <path d="M894.91-253.56c1.902.554 4.587 1.589 6.156 2.594s2.874 1.408 5.5 3.219c2.6 1.791 5 2.871 7.281 3.875 2.465 1.083 5.76 2.04 9.532 3.75-1.205-1.236-7.175-3.245-9.063-4.032-1.888-.786-4.075-1.83-6.875-3.593s-3.6-2.369-5.969-3.532c-2.37-1.163-4.123-1.834-6.562-2.28z" enable-background="new" filter="url(#hk)" opacity=".25"/>
+   <path d="M863.72-248.66c1.88.43 4.504 1.38 6.063 2.313 1.558.932 2.852 1.257 5.468 3 2.59 1.724 4.981 2.708 7.25 3.625 2.452.99 5.74 1.877 9.5 3.5-1.201-1.208-7.152-3.067-9.03-3.782-1.88-.715-4.086-1.684-6.876-3.375s-3.585-2.228-5.937-3.28-4.026-1.713-6.438-2z" enable-background="new" filter="url(#hj)" opacity=".25"/>
+   <path d="m833.16-241.38c1.848 0.296 4.47 0.976 6 1.781s2.814 1.056 5.375 2.531c2.535 1.46 4.89 2.326 7.125 3.063 2.414 0.797 5.657 1.467 9.375 2.844-1.188-1.129-7.088-2.59-8.938-3.156-1.85-0.567-4.003-1.374-6.75-2.844-2.746-1.47-3.5-1.92-5.812-2.781-2.311-0.861-4.005-1.32-6.375-1.438z" enable-background="new" filter="url(#hi)" opacity=".25"/>
+   <path d="m802.91-232.31c1.822 0.211 4.366 0.8 5.875 1.531 1.51 0.73 2.756 0.93 5.281 2.281 2.5 1.338 4.832 2.049 7.031 2.657 2.377 0.656 5.565 1.073 9.22 2.187-1.168-1.045-6.93-2.103-8.75-2.562-1.822-0.46-3.953-1.127-6.657-2.438s-3.471-1.72-5.75-2.469-3.913-1.179-6.25-1.187z" enable-background="new" filter="url(#hh)" opacity=".25"/>
+   <path d="M773.19-222.19c1.811.179 4.32.665 5.813 1.344 1.491.678 2.753.798 5.25 2.062 2.47 1.252 4.79 1.896 6.968 2.438 2.354.585 5.492.897 9.094 1.844-1.15-.992-6.852-1.784-8.656-2.188s-3.916-1.021-6.594-2.25c-2.678-1.229-3.403-1.61-5.656-2.281-2.253-.67-3.896-1.002-6.219-.969z" enable-background="new" filter="url(#hg)" opacity=".25"/>
+   <path d="M743.56-211.19c1.793.13 4.273.55 5.75 1.188s2.716.741 5.188 1.937c2.446 1.184 4.72 1.747 6.874 2.219 2.328.51 5.42.68 9 1.562-1.143-.97-6.747-1.59-8.53-1.937-1.784-.347-3.884-.888-6.532-2.031-2.648-1.144-3.395-1.517-5.625-2.125-2.23-.61-3.826-.91-6.125-.813z" enable-background="new" filter="url(#hf)" opacity=".25"/>
+  </g>
+ </g>
+ <path d="M912.45 671.2c1.642-3.218 3.518-5.735 4.861-9.849.8-3.658 3.312-2.03 7.26-8.397 1.403-2.24 5.477.391 8.966-2.399 1.27-.803 2.885-.404 4.483-.063 3.765 1.319 5.825 3.704 8.333 5.808 6.14 5.97 20.534 7.944 23.486 6.314 1.434-2.905 7.882-5.41 12.374-11.112.749-1.123 11.73-8.745 14.647-6.566" enable-background="new" fill="none" stroke="#000"/>
+ <path d="M937.07 660.78c7.363-3.233 13.811-8.908 20.708-13.385 3.31-1.97 6.87 3.216 10.796 3.599 2.298-.218 3.713 1.202 5.682 1.641 5.157 1.318 2.398 3.865 9.975 6.44 6.156 1.72 8.908-6.799 14.9-7.324 4.878-.503 8.1-.316 11.617-.252 3.927.139 4.079-3.498 6.061-5.304 2.98-2.805 7.156-1.85 10.145-4.74 1.018-1.385 1.955-3.011 2.735-5.109.882-2 3.04.306 4.798 1.263" enable-background="new" fill="none" stroke="#000"/>
+ <g fill-rule="evenodd">
+  <path transform="translate(48.571 195.53)" d="m403.28 1056.3l56.569-42.426 72.125 14.142-46.669 52.326-53.74 7.071-28.284-31.113z" enable-background="accumulate" filter="url(#he)" opacity=".25"/>
+  <path d="m590.84 1256.1c-1.407 18.801-1.145 32.751 2.082 49.303 3.226 16.552 16.406 45.907 20.334 63.184 3.926 17.267 2.694 38.31-12.46 51.148-15.317 12.977-42.05 21.599-67.831 15.734s-69.55-49.223-88.59-70.228c-19.112-21.083-63.761-93.851-77.94-124.28-14.177-30.425-12.66-36.719-8.119-45.53-9.367-24.52-12.414-50.067-33.712-75.577 30.325 3.114 43.88 26.956 60.126 47.14-5.53-48.076-18.055-64.416-28.374-90.724 29.994 6.082 50.579 31.872 63.98 72.712 9.554-3.918 18.238-9.373 30.187-9.061-11.298-41.696-17.949-69.916-36.687-101.07 53.442 5.67 83.657 80.639 78.971 87.96 9.978-2.243 19.006-6.53 30.437-5.65-11.249-38.348-21.048-76.869-3.66-118.65 0 0 48.287 65.436 54.39 85.805 6.103 20.37 1.52 38.701 1.52 38.701s16.96 31.085 20.293 51.094c3.373 20.241-3.533 59.103-4.946 77.983z" enable-background="new" fill="#ada469"/>
+  <path transform="matrix(-.90453 .25066 .25066 .90453 1043.9 219.06)" d="M719.5 738.7l18.312 15.432 44.411-15.388L805.5 713.2l11.464 19.221 30.672 12.784 25.097 5.728L892 723.2l16.023 23.826L947 752.2l10.245-6.198L964 754.7l25.5 11 2-40.5-35.551-14.538-32.493-21.527-40.452-11.466-21.307-15.533L840 685.2l-84.971-46.583-33.03 38.083-2.5 62z" clip-path="url(#e)" enable-background="accumulate" fill="#fff" filter="url(#o)"/>
+  <path transform="matrix(-.90453 .25066 .25066 .90453 870.86 206.47)" d="M584 696.5l-6.563 17.156s-7.811 20.365-15.688 43.656c-3.938 11.646-7.883 24.041-10.938 35.125s-5.335 20.38-5.5 28.281c-.398 19.162 5.747 34.888 8.938 41.75-.772 3.555-1.991 9.454-3.344 18.094-1.92 12.268-3.718 27.154-2.375 39.875 1.382 13.088 6.812 28.188 12.594 43.031s12.054 29.227 15.22 38.031c6.631 18.452 9.992 31.576 11.311 48.5.582 7.456-.242 20.336-1.25 33.375s-2.186 26.301-1.687 36.969c.989 21.14 9.328 46.835 33.375 57.937 22.775 10.515 55.327 11.702 83.438-3.437 16.16-8.704 30.076-27.098 43.375-46.906s24.969-41.053 31.938-54.906c15.353-30.521 39.394-115.46 45.625-152.72 3.018-18.047 3.921-29.066 2.625-38.031-.979-6.766-3.828-12.147-6.875-16.22 2.042-27.507-.732-51.368 11.969-79.405l10.562-23.281-23.812 9.312c-17.49 6.838-28.902 19.045-36.594 32.062-.323.546-.563 1.108-.875 1.656.222-22.515 4.408-37.638
+6.594-58.688l1.968-19-17.03 8.656c-30.595 15.556-45.696 48.193-49.72 90.22-4.245-.626-8.831-1.02-13.812-.844-.291-39.18-.396-67.037 8.594-99.375l5.594-20.125-19.438 7.656c-30.91 12.204-47.86 41.931-56.625 68.375-4.383 13.222-6.746 25.801-7.594 35.938a92.19 92.19 0 0 0-.312 7.719c-3.242-.037-6.42.136-10.062.5.041-39.005-3.485-79.754-32.281-116.5L584 696.498zm5.813 43.812c16.807 30.644 17.475 63.967 16.938 99.75l-.22 15.062 12.036-6.54c8.662-3.132 19.56-.227 31.934-.835l14.675 9.357-6.331-25.794c-.09-.23-.22-.417-.25-.72-.2-2.039-.222-5.472.125-9.624.694-8.304 2.79-19.585 6.625-31.156 5.155-15.553 13.488-31.192 25.125-42.531-4.684 28.638-3.216 60.259-3.012 95.805l-2.766 13.262 15.496-7.598c9.03-2.758 17.19-.35 29.281 1.094l13.246 9.444L741.094 840c1.448-30.972 8.222-53.678 20.719-68.875-2.987 19.779-5.43 41.785.313 78.344l1.065 6.373-2.938 11.517 10.617-8.168 9.19 10.222-1.549-10.464
+3.427-6.95c5.7-13.21 10.173-26.212 16.344-36.655.96-1.624 2.031-3.065 3.062-4.563-3.68 21.155-2.427 40.208-4.093 57.781l-4.68 7.807 7.398.225c3.22 3.483 3.868 3.85 4.563 8.656s.318 14.4-2.563 31.625c-5.568 33.288-31.846 77.84-43.74 101.49-6.605 13.13-18.528 57.486-31.123 76.246s-28.53 39.767-37.172 44.42c-21.49 11.575-44.556 25.507-60.619 18.09-14.375-6.636-23.04-21.192-23.814-37.742-.383-8.188.613-21.31 1.625-34.406 1.013-13.097 11.29-22.571 15.423-36.563 5.373-18.181-1.447-36.594-12.5-53.937-6.486-10.178-23.977-24.258-29.548-38.562s-10.368-29.003-11.28-37.656c-.927-8.771.422-23.025 2.218-34.5 1.796-11.475 3.844-20.281 3.844-20.281l9.423-3.615-10.485-3.885s-8.5-15.31-8.094-34.812c.071-3.423 1.836-12.728 4.719-23.188s6.764-22.553 10.625-33.97c3.044-9.002 5.78-16.602 8.344-23.687z" clip-path="url(#am)" enable-background="new" filter="url(#ds)" opacity=".588"/>
+  <g transform="translate(324.57 331.53)" clip-path="url(#is)" enable-background="new" fill="#fff">
+   <path transform="matrix(-.90453 .25066 .25066 .90453 -52.2 74.097)" d="m-15.668 843.49l-49.497-15.556-26.87 52.326 41.012 45.255 49.497-38.184z" enable-background="accumulate" filter="url(#dr)"/>
+   <path transform="matrix(-.90453 .25066 .25066 .90453 -46.928 75.511)" d="m118.71 859.93l-55.154-46.669-43.841 36.77 33.941 53.74-13.597 85.462-39.445 28.292-41.012 11.314-2.828 46.669 56.569 25.456 18.944-69.65 23.457-58.857 46.348-72.615 16.62-39.912z" enable-background="accumulate" filter="url(#dq)"/>
+  </g>
+  <path transform="matrix(-.90453 .25066 .25066 .90453 277.64 407.04)" d="m-70.822 932.58l60.811-26.87 100.41 31.113-63.64 31.113-82.024-16.971-15.556-18.385z" enable-background="accumulate" filter="url(#cy)" opacity=".25"/>
+  <path transform="matrix(-.90453 .25066 .25066 .90453 870.86 206.47)" d="M583.06 715.75c-12.106 34.45-26.714 68.533-31.75 104.84-.832 14.929 4.59 29.159 8.844 43.062-5.916 27.201-10.137 56.9 1.156 83.125 13.517 38.161 35.001 75.682 32.423 117.47-.948 29.294-9.014 60.994 5.39 88.282 10.199 19.335 33.14 27.312 53.968 27.668 27.862 1.174 56.463-11.622 72-35.261 22.596-29.372 41.802-61.497 55.24-96.06 16.89-45.506 29.672-92.561 37.934-140.4 1.824-12.941 3.1-27.47-4.58-38.823-3.43-7.336.043-15.56-.684-23.31.674-24.995 4.013-50.664 16.653-72.596-17.733 6.445-35.073 16.56-44.003 33.864-3.935 6.71-7.605 13.574-11.372 20.386-3.55-30.014 3.72-59.648 6.781-89.281-20.166 9.055-36.877 25.655-44.175 46.682-6.304 15.58-8.802 32.317-10.263 49.037-8.253-1.52-16.684-2.102-25.062-1.5-.963-38.698-.467-79.407 10.97-115.91-18.682 6.218-35.167 18.736-45.629 35.387-13.853 20.88-21.26 45.754-23.059 70.613.586
+4.325-.06 11.84-6.343 9.875-5.332.018-10.63.679-15.938 1.094 1.147-39.381-3.342-81.628-27.062-114.22-3.061-3.637-5.637-7.685-8.625-11.344l-2.813 7.312zm7.75 13.844c18.565 29.296 22.482 64.82 22.125 98.875.204 5.175-.517 11.829.125 16.062 12.319-6.103 26.739-2.44 39.781-2.187 2.317 1.223 3.192 1.652 1.906-1.407-4.164-13.953-1.848-28.613 1.805-42.408 6.367-26.29 20.628-51.088 42.82-67.03-8.617 37.237-5.716 76.562-6.094 113.97 12.253-6.91 27.28-3.446 40.031-.25 3.393 3.535 2.29-.73 2.188-3.812-.483-21.371 4.131-43.07 13.688-62.156 5.963-10.687 14.243-19.804 22.438-28.875-7.872 33.838-9.203 69.336-2.719 103.5 1.725-1.411 4.607-.454 5.656-.375 9.684-21.237 16.351-45.381 34.89-60.742 1.874-.371-1.448 8.525-1.484 11.898-3.535 21.846-7.175 44.142-8.784 66.219-8.784 2.342 2.849 2.323 3.469 4.062 7.923 10.566 4.663 24.405 3.632 36.353-7.064 45.034-22.142 87.362-35.954 130.68-12.075 32.95-27.374
+58.852-47.888 87.202-10.953 13.551-23.245 27.851-40.844 32.5-20.156 6.242-44.207 10.877-62.6.046-17.29-12.34-21.024-35.709-19.262-55.686.048-15.826 4.938-28.512 4.41-43.492-.538-15.263-2.291-30.565-6.542-46.866-4.252-16.302-9.044-24.918-16.12-41.573-7.24-17.045-15.07-36.749-18.204-56.288-1.75-18.627 2.891-37.123 5.78-55.25 3.297-2.837-1.597-5.196-2.312-8.187-7.6-17.015-8.407-36.775-2.742-54.56 7.13-25.072 15.761-49.632 24.68-74.128l2.125 3.906z" clip-path="url(#cj)" enable-background="new" filter="url(#ir)" opacity=".588"/>
+  <path transform="matrix(-.90453 .25066 .25066 .90453 1043.9 219.06)" d="m735.06 733.04l2.755 21.089 44.411-15.388 4.851-22.39-3.936-22.052-22.452-36.593-8.28 30.305-17.35 45.029z" clip-path="url(#e)" enable-background="accumulate" fill="#fff" filter="url(#bz)"/>
+  <path transform="matrix(-.90453 .25066 .25066 .90453 1043.9 219.06)" d="m831.81 730.29l15.822 14.905 20.855 2.9-1.59-39.926 8.325-30.508-7.165-6.341-21.697 20.942-14.55 38.028z" clip-path="url(#e)" enable-background="accumulate" fill="#fff" filter="url(#by)"/>
+ </g>
+ <g transform="translate(324.57 331.53)" clip-path="url(#iq)" enable-background="new" filter="url(#ip)">
+  <path d="M36.494 811.806l-14.799 11.372-17.47-31.162 14.663.65 17.606 19.14z" enable-background="accumulate" fill="#fff" fill-rule="evenodd"/>
+  <path d="M-55 757.2h182v177H-55z" enable-background="accumulate" fill="none"/>
+ </g>
+ <g transform="translate(324.57 331.53)" clip-path="url(#io)" enable-background="new" filter="url(#in)">
+  <path d="m83.111 790.72l-28.201 12.855-5.658-21.687-13.943-25.046 6.325-6.88 26.384 18.51 15.094 22.249z" enable-background="accumulate" fill="#fff" fill-rule="evenodd"/>
+  <path d="M-22 696.2h165v176H-22z" enable-background="accumulate" fill="none"/>
+ </g>
+ <g fill-rule="evenodd">
+  <path d="m1084.8 1267.3c6.794 18.903 10.494 33.3 11.89 51.212 1.397 17.912-3.783 51.801-2.9 70.656 0.881 18.845 8.133 40.099 27.345 48.969 19.419 8.966 49.319 10.211 74.12-3.146 24.8-13.357 57.4-70.326 70.973-97.309 13.624-27.084 38.761-114.5 44.661-149.77s2.551-41.3-4.617-49.055c2.64-27.84-1.5-54.935 13.11-87.186-30.249 11.826-37.382 40.161-48.319 65.505-8-50.933 0.21-71.273 3.319-101.22-29.065 14.778-42.862 47.114-45 92.857-10.924-1.304-21.391-4.434-33.571-0.714-0.264-46.023-1.464-76.889 8.91-114.21-53.254 21.027-62.946 106.59-56.053 112.78-10.883 0.535-21.371-1.297-32.857 2.857 0.638-42.57-0.26-84.909-30-122.86 0 0-30.958 80.922-31.43 103.57-0.47 22.65 9.452 40.166 9.452 40.166s-8.568 36.741-6.298 58.232c2.295 21.741 20.443 59.676 27.266 78.658z" enable-background="new" fill="#ada469"/>
+  <path transform="translate(324.57 331.53)" d="M719.5 738.7l18.312 15.432 44.411-15.388L805.5 713.2l11.464 19.221 30.672 12.784 25.097 5.728L892 723.2l16.023 23.826L947 752.2l10.245-6.198L964 754.7l25.5 11 2-40.5-35.551-14.538-32.493-21.527-40.452-11.466-21.307-15.533L840 685.2l-84.971-46.583-33.03 38.083-2.5 62z" clip-path="url(#e)" enable-background="accumulate" fill="#fff" filter="url(#o)"/>
+  <path transform="translate(498.6 269.37)" d="M584 696.5l-6.563 17.156s-7.811 20.365-15.688 43.656c-3.938 11.646-7.883 24.041-10.938 35.125s-5.335 20.38-5.5 28.281c-.398 19.162 5.747 34.888 8.938 41.75-.772 3.555-1.991 9.454-3.344 18.094-1.92 12.268-3.718 27.154-2.375 39.875 1.382 13.088 6.812 28.188 12.594 43.031s12.054 29.227 15.22 38.031c6.631 18.452 9.992 31.576 11.311 48.5.582 7.456-.242 20.336-1.25 33.375s-2.186 26.301-1.687 36.969c.989 21.14 9.328 46.835 33.375 57.937 22.775 10.515 55.327 11.702 83.438-3.437 16.16-8.704 30.076-27.098 43.375-46.906s24.969-41.053 31.938-54.906c15.353-30.521 39.394-115.46 45.625-152.72 3.018-18.047 3.921-29.066 2.625-38.031-.979-6.766-3.828-12.147-6.875-16.22 2.042-27.507-.732-51.368 11.969-79.405l10.562-23.281-23.812 9.312c-17.49 6.838-28.902 19.045-36.594 32.062-.323.546-.563 1.108-.875 1.656.222-22.515 4.408-37.638 6.594-58.688l1.968-19-17.03
+8.656c-30.595 15.556-45.696 48.193-49.72 90.22-4.245-.626-8.831-1.02-13.812-.844-.291-39.18-.396-67.037 8.594-99.375l5.594-20.125-19.438 7.656c-30.91 12.204-47.86 41.931-56.625 68.375-4.383 13.222-6.746 25.801-7.594 35.938a92.19 92.19 0 0 0-.312 7.719c-3.242-.037-6.42.136-10.062.5.041-39.005-3.485-79.754-32.281-116.5L584 696.498zm5.813 43.812c16.807 30.644 17.475 63.967 16.938 99.75l-.22 15.062 12.036-6.54c8.662-3.132 19.56-.227 31.934-.835l14.675 9.357-6.331-25.794c-.09-.23-.22-.417-.25-.72-.2-2.039-.222-5.472.125-9.624.694-8.304 2.79-19.585 6.625-31.156 5.155-15.553 13.488-31.192 25.125-42.531-4.684 28.638-3.216 60.259-3.012 95.805l-2.766 13.262 15.496-7.598c9.03-2.758 17.19-.35 29.281 1.094l13.246 9.444L741.094 840c1.448-30.972 8.222-53.678 20.719-68.875-2.987 19.779-5.43 41.785.313 78.344l1.065 6.373-2.938 11.517 10.617-8.168 9.19 10.222-1.549-10.464 3.427-6.95c5.7-13.21
+10.173-26.212 16.344-36.655.96-1.624 2.031-3.065 3.062-4.563-3.68 21.155-2.427 40.208-4.093 57.781l-4.68 7.807 7.398.225c3.22 3.483 3.868 3.85 4.563 8.656s.318 14.4-2.563 31.625c-5.568 33.288-31.793 123.17-43.688 146.81-6.605 13.13-18.03 33.896-30.625 52.656s-27.359 35.534-36 40.187c-21.49 11.574-48.78 10.26-64.844 2.844-14.375-6.637-20.538-23.45-21.312-40-.383-8.188.613-21.31 1.625-34.406 1.013-13.097 11.29-22.571 15.423-36.563 5.373-18.181-1.447-36.594-12.5-53.937-6.486-10.178-23.977-24.258-29.548-38.562s-10.368-29.003-11.28-37.656c-.927-8.771.422-23.025 2.218-34.5 1.796-11.475 3.844-20.281 3.844-20.281l9.423-3.616-10.485-3.884s-8.5-15.31-8.094-34.812c.071-3.424 1.836-12.728 4.719-23.188s6.764-22.553 10.625-33.97c3.044-9.002 5.78-16.602 8.344-23.687z" clip-path="url(#am)" enable-background="new" filter="url(#ds)" opacity=".588"/>
+  <g transform="translate(324.57 331.53)" clip-path="url(#im)" fill="#fff">
+   <path d="m824.49 818.48l-49.497-15.556-26.87 52.326 41.012 45.255 49.497-38.184z" enable-background="accumulate" filter="url(#dr)"/>
+   <path d="m964.49 855.25l-55.154-46.669-43.841 36.77 33.941 53.74 7.071 66.468-50.912 35.355-41.012 11.314-2.828 46.669 56.569 25.456 63.64-76.368 24.042-94.752 8.485-57.983z" enable-background="accumulate" filter="url(#dq)"/>
+  </g>
+  <path transform="translate(48.571 195.53)" d="m1045.3 1043.6l60.811-26.87 100.41 31.113-63.64 31.113-82.024-16.971-15.556-18.385z" enable-background="accumulate" filter="url(#cy)" opacity=".25"/>
+  <path transform="translate(498.6 269.37)" d="M583.06 715.75c-12.106 34.45-26.714 68.533-31.75 104.84-.832 14.929 4.59 29.159 8.844 43.062-5.916 27.201-10.137 56.9 1.156 83.125 13.517 38.161 35.001 75.682 32.423 117.47-.948 29.294-9.014 60.994 5.39 88.282 10.199 19.335 33.14 27.312 53.968 27.668 27.862 1.174 56.463-11.622 72-35.261 22.596-29.372 41.802-61.497 55.24-96.06 16.89-45.506 29.672-92.561 37.934-140.4 1.824-12.941 3.1-27.47-4.58-38.823-3.43-7.336.043-15.56-.684-23.31.674-24.995 4.013-50.664 16.653-72.596-17.733 6.445-35.073 16.56-44.003 33.864-3.935 6.71-7.605 13.574-11.372 20.386-3.55-30.014 3.72-59.648 6.781-89.281-20.166 9.055-36.877 25.655-44.175 46.682-6.304 15.58-8.802 32.317-10.263 49.037-8.253-1.52-16.684-2.102-25.062-1.5-.963-38.698-.467-79.407 10.97-115.91-18.682 6.218-35.167 18.736-45.629 35.387-13.853 20.88-21.26 45.754-23.059 70.613.586 4.325-.06 11.84-6.343
+9.875-5.332.018-10.63.679-15.938 1.094 1.147-39.381-3.342-81.628-27.062-114.22-3.061-3.637-5.637-7.685-8.625-11.344l-2.813 7.312zm7.75 13.844c18.565 29.296 22.482 64.82 22.125 98.875.204 5.175-.517 11.829.125 16.062 12.319-6.103 26.739-2.44 39.781-2.187 2.317 1.223 3.192 1.652 1.906-1.407-4.164-13.953-1.848-28.613 1.805-42.408 6.367-26.29 20.628-51.088 42.82-67.03-8.617 37.237-5.716 76.562-6.094 113.97 12.253-6.91 27.28-3.446 40.031-.25 3.393 3.535 2.29-.73 2.188-3.812-.483-21.371 4.131-43.07 13.688-62.156 5.963-10.687 14.243-19.804 22.438-28.875-7.872 33.838-9.203 69.336-2.719 103.5 1.725-1.411 4.607-.454 5.656-.375 9.684-21.237 16.351-45.381 34.89-60.742 1.874-.371-1.448 8.525-1.484 11.898-3.535 21.846-3.297 44.173-4.906 66.25-1.312 1.377 2.849 2.323 3.469 4.062 7.923 10.566 3.123 24.831 2.092 36.78-7.064 45.034-21.766 88.38-35.577 131.7-12.075 32.95-30.72 63.08-51.234 91.43-10.953
+13.55-23.245 27.85-40.844 32.5-20.156 6.24-43.576 5.174-61.97-5.657-17.29-12.34-21.023-35.709-19.261-55.686.048-15.826 2.372-27.8 7.917-42.805s2.471-31.332-1.78-47.633-12.18-26.26-21.822-42.204-17.637-36.037-20.772-55.577c-1.75-18.627 2.892-37.123 5.781-55.25 3.296-2.837-1.598-5.196-2.312-8.187-7.602-17.015-8.408-36.775-2.743-54.56 7.13-25.072 15.761-49.632 24.68-74.128l2.125 3.906z" clip-path="url(#cj)" enable-background="new" filter="url(#il)" opacity=".588"/>
+  <path transform="translate(324.57 331.53)" d="m735.06 733.04l2.755 21.089 44.411-15.388 4.851-22.39-3.936-22.052-22.452-36.593-8.28 30.305-17.35 45.029z" clip-path="url(#e)" enable-background="accumulate" fill="#fff" filter="url(#bz)"/>
+  <path transform="translate(324.57 331.53)" d="m831.81 730.29l15.822 14.905 20.855 2.9-1.59-39.926 8.325-30.508-7.165-6.341-21.697 20.942-14.55 38.028z" clip-path="url(#e)" enable-background="accumulate" fill="#fff" filter="url(#by)"/>
+ </g>
+ <g transform="translate(324.57 331.53)" clip-path="url(#ik)" filter="url(#ij)">
+  <path d="M910.14 746.31l32.613 5.174-.361-23.876 7.188-29.682-8.45-5.264-21.823 26.511-9.167 27.137z" enable-background="accumulate" fill="#fff" fill-rule="evenodd"/>
+  <path d="M877.52 650.19h123.04v172.53H877.52z" enable-background="accumulate" fill="none"/>
+ </g>
+ <g transform="translate(324.57 331.53)" clip-path="url(#ii)" filter="url(#ih)">
+  <path d="M964 754.69l18.429 7.465 9.071-36.964-14.87 4.839L964 754.69z" enable-background="accumulate" fill="#fff" fill-rule="evenodd"/>
+  <path d="M924.9 677.06h142.13v125.16H924.9z" enable-background="accumulate" fill="none"/>
+ </g>
+ <g stroke-miterlimit="1">
+  <path d="m596.57 400.85h440v376h-440z" fill="none" stroke="#f8d615" stroke-width="18"/>
+  <path d="m104.57 248.85h1684v1292h-1684z" fill="none" stroke="#f83615" stroke-width="18"/>
+  <path d="M3407.4 296.46h522.57v1182.5H3407.4z" fill="url(#ig)" stroke="#f815bb" stroke-width="13.347"/>
+ </g>
+ <g transform="matrix(1.0057 0 0 2.3995 3452.3 -18.515)" clip-path="url(#if)" enable-background="new">
+  <g filter="url(#aq)">
+   <g transform="translate(-174.03 62.156)" filter="url(#g)">
+    <path d="m1268.3 663.77s-0.296 26.161 4.643 37.857 20.038 26.487 28.572 31.429 18.929 8.571 18.929 8.571l117.86-115 17.857-75.714-96.43 38.571-91.428 74.286z" enable-background="new" fill="#fff" fill-rule="evenodd"/>
+    <path d="M1197.8 486.14h333.75v309.71H1197.8z" enable-background="accumulate" fill="none"/>
+   </g>
+  </g>
+  <g transform="translate(-174.03 62.156)" enable-background="new" filter="url(#g)" opacity=".18">
+   <path d="m1268.3 663.77s-0.296 26.161 4.643 37.857 20.038 26.487 28.572 31.429 18.929 8.571 18.929 8.571l117.86-115 17.857-75.714-96.43 38.571-91.428 74.286z" enable-background="new" fill="#fff" fill-rule="evenodd"/>
+   <path d="M1197.8 486.14h333.75v309.71H1197.8z" enable-background="accumulate" fill="none"/>
+  </g>
+ </g>
+ <path d="M3492.3 296.46H3930v902.66h-437.7z" fill="#fff" stroke="#f8d615" stroke-miterlimit="1" stroke-width="18"/>
+ <g transform="matrix(1.0057 0 0 2.3995 3249.4 125.01)" clip-path="url(#ie)" enable-background="new" filter="url(#id)">
+  <path d="M36.494 811.806l-14.799 11.372-17.47-31.162 14.663.65 17.606 19.14z" enable-background="accumulate" fill="#fff" fill-rule="evenodd"/>
+  <path d="M-55 757.2h182v177H-55z" enable-background="accumulate" fill="none"/>
+ </g>
+ <g transform="matrix(1.0057 0 0 2.3995 3249.4 125.01)" clip-path="url(#ic)" enable-background="new" filter="url(#gd)">
+  <path d="m83.111 790.72l-28.201 12.855-5.658-21.687-13.943-25.046 6.325-6.88 26.384 18.51 15.094 22.249z" enable-background="accumulate" fill="#fff" fill-rule="evenodd"/>
+  <path d="M-22 696.2h165v176H-22z" enable-background="accumulate" fill="none"/>
+ </g>
+ <path transform="matrix(1.0057 0 0 2.3995 3249.4 125.01)" d="m332.34 898.39l-32.732-61.3-37.617 45.106c2.177 1.317 5.774-20.856 45.6-64.417l24.749 80.61z" clip-path="url(#gc)" enable-background="accumulate" fill="#fff" fill-rule="evenodd" filter="url(#gb)" opacity=".5"/>
+ <g clip-path="url(#ga)">
+  <g fill-rule="evenodd">
+   <g enable-background="new">
+    <path transform="matrix(.71488 -.46488 .26446 2.3151 3478.4 126.16)" d="m245.12 100.05s-47.128-31.647-67.215-35.801c-20.038-4.144-38.473-3.318-51.934 13.607s-12.077 61.265-13.536 86.97 2.55 70.177 17.605 88.666c15.055 18.488 45.886 13.585 49.927 21.414 2.213 4.287 65.152-174.86 65.152-174.86z" enable-background="accumulate" fill="url(#r)"/>
+    <path transform="matrix(.71488 -.46488 .26446 2.3151 3478.4 126.16)" d="M135.38 82.018s26.344 1.939 37.633 13.903c11.415 12.097 13.735 21.332 15.296 37.735 1.563 16.425-.85 28.418-7.814 36.037s-1.004 19.583-25.916 12.071-27.032-27.783-26.515-46.305c.517-18.529 7.316-53.441 7.316-53.441z" enable-background="accumulate" fill="url(#q)"/>
+    <path transform="matrix(.71488 -.46488 .26446 2.3151 3478.4 126.16)" d="M135.65 81.927s-4.645 16.365.588 28.563c5.488 12.793 27.224 44.26 27.224 54.656l22.656-5c2.542-6.966 3.21-15.752 2.188-26.5-1.562-16.403-3.867-25.621-15.281-37.719-9.655-10.232-31.593-13.375-37.375-14z" enable-background="new" fill="url(#p)"/>
+   </g>
+   <g enable-background="new">
+    <path d="M4043.297 824.626l-.09-.006c-1.489 1.728-6.783 2.02-7.718 20.884-.878 17.694 13.035 44.859 15.06 47.837 1.636 2.403 3.427 4.343 5.205 5.58l1.41.916c1.894 1.031 3.7 1.38 5.163 1.19 3.177-.414 5.214-.812 7.238-1.183 2.025-.372 2.592-1.8 3.707-2.078 1.156-.288 2.255.9 6.345-.372 4.09-1.271 5.587-1.894 6.324-2.566.765-.698 1.86-1.592 2.549-2.999 1.962.51 3.823.346 5.31-.58 3.08-1.92 5.084-3.12 6.998-4.722 1.536-1.285 2.513-3.421 2.759-4.073.246-.653.183-1.71.211-1.754.047-.072.351-.13.55-.906 1.07-4.167 2.968-12.778
+3.16-14.38.193-1.594.324-3.178.42-4.11.056-.54-.046-2.136-.017-2.27.04-.187.317-.518.401-1.098.404-2.783.343-5.237.292-8.675-.05-3.438-.44-11.267-.995-13.482-.356-1.423-.708-2.109-1.051-2.478-.065-.06-.119-.145-.18-.2-.02-.015-.043-.004-.062-.017-.303-.265-.59-.545-1.13-.839-.972-.527-2.393-1.283-3.937-1.684-.514-.134-1.041-.17-1.572-.205-3.591-.231-9.115-.108-10.396 1.072-1.593-1.244-3.874-2.542-5.879-2.746-3.086-.313-5.002-.546-6.953-.776-1.952-.23-1.73.464-2.958.32-1.328-.155-1.76-1.022-5.568-1.302-3.577-.262-9.087-.095-10.397 1.072-1.593-1.245-3.872-2.542-5.878-2.746-3.087-.313-5.006-.472-6.958-.702-.663-.078-1.055.01-1.364.079z" enable-background="new" fill="#bcb786"/>
+    <g transform="matrix(1.0047 .1075 -.04506 2.3971 3818.4 1782.9)" clip-path="url(#fz)" enable-background="new" filter="url(#fy)">
+     <path d="M229.94-409.12c-3.558.05-9.024.36-10.303.904-1.606-.447-3.903-.881-5.9-.877a979.03 979.03 0 0 1-6.907 0c-.66-.003-1.048.068-1.353.11v1.096c.12-.18.393-.69.95-.767.747-.103 5.17-.151 7.31-.11 1.775.035 4.455.274 6.39.96.32.113.618.273.891.41 1.964.987 7.944 4.302 7.944 4.302s-6.633-3.948-7.483-4.439c-.203-.117-.575-.258-1.036-.41 1.22-.449 5.076-.62 7.828-.713 3.024-.102 3.348-.09 5.41.192 2.13.29 3.34.602 3.34.602s-.08-.64 1.035-.794c.748-.103 5.17-.152 7.31-.11 2.07.04 5.366.407 7.282 1.37 1.003.504 3.035 1.569 4.795 2.536l.096-.02s-3.58-2.162-4.43-2.653c-.204-.117-.575-.258-1.037-.411 1.22-.448 5.047-.62 7.8-.712 3.024-.102 3.347-.09 5.41.191 1.954.267 3.013.53 3.195.576l-.027-.312a8.503 8.503 0 0 0-1.4-.357c-1.301-.235-3.4-.602-5.51-.564-3.571.064-9.052.356-10.302.904-1.606-.447-3.877-.881-5.871-.877-3.072.007-4.994.01-6.936
+0-1.943-.009-1.713.28-2.936.274-1.322-.005-1.766-.354-5.555-.301M206.2-407.48c1.92.817 4.577 2.193 6.159 3.397s2.908 1.774 5.555 3.918c.885.718 1.748 1.35 2.591 1.922l.541-.19a57.511 57.511 0 0 1-2.269-1.622c-2.822-2.12-3.627-2.81-6.015-4.274s-4.1-2.366-6.562-3.15" enable-background="new"/>
+     <path d="M237.8-407.48c1.92.817 4.606 2.193 6.188 3.397.813.62 1.558 1.07 2.45 1.654l.65-.116a40.414 40.414 0 0 0-2.697-1.784c-2.389-1.465-4.128-2.366-6.59-3.151" enable-background="new"/>
+    </g>
+    <g transform="matrix(.9991 .27421 -.11493 2.3838 2962.6 1209.8)" clip-path="url(#fx)">
+     <path d="M1056.2-278.8c4.145-1.479 10 3.125 10 3.125.899.28 2.725-.894 2.624-1.686 0 0-1.55-1.86-.374-2.939s5.296 1.507 7.5 1.625 5.562-.23 7-.75 1.113-1.425 2.625-1.75 5.119 1.038 7.06 1.169 4.649.334 5.815-.169.178-1.16 1.875-1.875 7.76-.957 9.625-.125 1.81.52 2.625 3 7.44 5.163-1.125 13.375-59.378 13.786-65.625 2.75 6.23-14.271 10.375-15.75z" enable-background="new" filter="url(#fw)" opacity=".75"/>
+     <path d="M1058.5-275.43c4.145-1.479 10 3.125 10 3.125.899.28 2.725-.894 2.624-1.686 0 0-1.55-1.86-.374-2.939s5.296 1.507 7.5 1.625 5.562-.23 7-.75 1.113-1.425 2.625-1.75 5.119 1.038 7.06 1.169 4.649.334 5.815-.169.178-1.16 1.875-1.875 7.76-.957 9.625-.125 1.81.52 2.625 3 7.44 5.163-1.125 13.375-59.378 13.786-65.625 2.75 6.23-14.271 10.375-15.75z" enable-background="new" filter="url(#fv)" opacity=".75"/>
+    </g>
+   </g>
+   <path d="M3603.7 633.68c-3.826-60.621-16.906-121.51-17.254-181.22-.187-32.048 3.291-63.757 13.834-94.91 36.554-156.68 117.6-203.23 186.99-219.47 87.416-26.435 185.96 43.047 234.7 228.91 54.432 181.72 56.997 414.01 81.07 622.74 29.605 305.05 55.09 614.78 60.735 928.25-3.08 187.6-8.474 396.35-60.847 547.4-48.299 120.83-123.49 120.1-188.13 141.58-91.07 11.17-185.4-38.742-263.27-154.04-65.144-91.037-96.274-272.3-97.832-446.36-8.437-191.66 26.542-369.07 51.914-545.07 7.513-198.58 9.466-398.92 9.708-598.39-.841-77.252-7.13-153.13-11.612-229.41z" enable-background="accumulate" fill="#101414"/>
+   <path transform="matrix(1.0057 0 0 2.3995 3249.4 125.01)" d="M311.83 415.43l9.9 121.62-60.105 136.47 15.556 174.66c15.613 61.879 32.185 98.669 74.376 117.05 4.32-36.24-38.612-142.96-39.243-189.12-.631-46.184 10.83-108.61 30.678-158.3 20.048-50.192 36.897-44.846 42.125-92.593s-17.426-149.39-17.426-149.39l-55.86 39.598z" clip-path="url(#y)" enable-background="accumulate" fill="#fff" filter="url(#fu)" opacity=".25"/>
+   <path d="m3987.6 1371.5s16.85 88.825 28.865 129.46c12.014 40.638 53.027 134.48 53.027 134.48l52.896-306.15" enable-background="accumulate" fill="url(#ft)"/>
+   <path transform="matrix(1.0057 0 0 2.3995 3249.4 125.01)" d="m730.32 536.57c0 8.485 42.548 58.468 42.548 58.468l12.607-28.77-55.154-29.698z" clip-path="url(#fs)" enable-background="accumulate" fill="#fff" filter="url(#fr)" opacity=".08"/>
+  </g>
+  <g transform="matrix(1.0057 0 0 2.3995 3424.4 -24.137)" clip-path="url(#fq)" enable-background="new">
+   <g transform="translate(-174.03 62.156)" filter="url(#aq)">
+    <g filter="url(#g)">
+     <path d="M425.88 476.99c10.805-1.479 24.744 3.354 44.643 3.214s57.453-16.91 82.143-17.143 62.752 12.284 79.286 15 22.848-.158 27.5 7.857 1.927 10.747-10.357 20.714-40.79 12.636-66.071 12.857c-25.282.221-70.381 7.079-95.357 3.93s-56.938-7.824-68.929-17.858-19.851-16.732-17.5-23.929 13.837-3.164 24.643-4.643z" enable-background="new" fill="#fff" fill-rule="evenodd"/>
+     <path d="M343.65 412.6h381.84v181.02H343.65z" enable-background="accumulate" fill="none"/>
+    </g>
+    <g filter="url(#g)">
+     <path d="m861.17 390.2c-10.462 9.714-86.98 19.005-100.71 29.286s-14.753 12.888-12.143 20 6.545 9.406 25.714 8.571 98.571-27.622 98.571-21.429l-11.429-36.429z" enable-background="new" fill="#fff" fill-rule="evenodd"/>
+     <path d="M702.86 344.82h207.89v162.63H702.86z" enable-background="accumulate" fill="none"/>
+    </g>
+   </g>
+   <g enable-background="new" opacity=".18">
+    <g transform="translate(-174.03 62.156)" filter="url(#g)">
+     <path d="M425.88 476.99c10.805-1.479 24.744 3.354 44.643 3.214s57.453-16.91 82.143-17.143 62.752 12.284 79.286 15 22.848-.158 27.5 7.857 1.927 10.747-10.357 20.714-40.79 12.636-66.071 12.857c-25.282.221-70.381 7.079-95.357 3.93s-56.938-7.824-68.929-17.858-19.851-16.732-17.5-23.929 13.837-3.164 24.643-4.643z" enable-background="new" fill="#fff" fill-rule="evenodd"/>
+     <path d="M343.65 412.6h381.84v181.02H343.65z" enable-background="accumulate" fill="none"/>
+    </g>
+    <g transform="translate(-174.03 62.156)" filter="url(#g)">
+     <path d="m861.17 390.2c-10.462 9.714-86.98 19.005-100.71 29.286s-14.753 12.888-12.143 20 6.545 9.406 25.714 8.571 98.571-27.622 98.571-21.429l-11.429-36.429z" enable-background="new" fill="#fff" fill-rule="evenodd"/>
+     <path d="M702.86 344.82h207.89v162.63H702.86z" enable-background="accumulate" fill="none"/>
+    </g>
+   </g>
+  </g>
+  <g transform="matrix(1.0057 0 0 2.3995 2971.9 -201.33)" fill-rule="evenodd">
+   <path transform="translate(276 136)" d="m582.66-7.418l113.14 86.267 108.89 258.8 38.184 207.89 120.21 91.924s-12.728-287.09-19.799-313.96-149.91-393.15-149.91-393.15l-210.72 62.225z" clip-path="url(#fp)" enable-background="accumulate" filter="url(#fo)" opacity=".75"/>
+   <path d="m964.14 239.6s8.677 10.897 24.107 11.964c15.43 1.068 49.722-39.953 70.179-52.143 20.479-12.204 47.046-26.602 63.929-20.357 16.882 6.245 22.158 26.436 27.857 48.036 5.7 21.6 6.719 61.814-2.679 92.857-9.397 31.043-50.502 73.104-65.356 103.39s-11.607 39.821-11.607 39.821" enable-background="accumulate" fill="url(#el)"/>
+   <path d="m1124.5 207.63c-15.893-0.893-49.719 12.106-66.071 24.286-16.439 12.244-29.221 24.114-29.286 52.143-0.065 28.206 13.119 39.076 29.107 46.964s33.686 7.12 51.964-11.786c18.278-18.905 14.286-111.61 14.286-111.61z" enable-background="new" fill="url(#ek)"/>
+   <ellipse transform="matrix(.94347 -.12399 .14401 1.0958 451.95 134.6)" cx="385" cy="237.01" rx="86.429" ry="73.929" clip-path="url(#fn)" enable-background="accumulate" fill="url(#ef)" filter="url(#fm)" opacity=".75"/>
+   <path transform="translate(450.03 73.844)" d="m527.61 407.45s-122.04 38.403-187.51 9.632c-65.473-28.772-74.377-124.72-74.377-124.72s73.382-80.504 129.92-83.615c55.827-3.072 90.574 20.143 114.87 65.852 24.352 45.813 17.101 132.85 17.101 132.85z" enable-background="accumulate" fill="url(#fl)" mask="url(#fk)"/>
+   <path d="m772.17 393.35s36.218-27.382 51.607-35.893c15.177-8.393 25.714-11.607 35.893-11.607l-15.536 66.964" enable-background="accumulate" fill="url(#ee)"/>
+   <circle transform="translate(449.5 74.915)" cx="409.29" cy="306.65" r="36.25" enable-background="accumulate" fill="url(#ed)"/>
+   <path transform="translate(276 136)" d="m311.83 415.43l9.9 121.62-60.105 136.47 15.556 174.66c15.613 61.879 32.185 98.669 74.376 117.05 4.32-36.24 8.682-72.368-31.243-223.12l17.678-69.296 72.125-138.59-42.426-158.39-55.86 39.598z" clip-path="url(#y)" enable-background="accumulate" fill="#fff" filter="url(#fj)" opacity=".3"/>
+   <path d="m635.21 581.13c-14.142 12.728 39.233 34.58 76.368 24.042s104.64-35.564 103.24-79.196c-1.407-43.632-76.368-128.69-76.368-128.69l-103.24 183.85z" enable-background="accumulate" filter="url(#fi)" opacity=".5"/>
+   <circle transform="translate(449.67 74.915)" cx="410" cy="306.65" r="23.214" enable-background="accumulate" fill="url(#ec)"/>
+   <circle transform="translate(452 73.487)" cx="414.29" cy="303.08" r="7.5" enable-background="accumulate" fill="#fff" filter="url(#fh)" stroke="#000" stroke-linejoin="bevel"/>
+   <path d="m789.32 478.35s7.023 19.569-1.071 35-42.323 38.988-67.5 50c-25.31 11.07-85.473 32.964-101.79 41.964-16.461 9.082-18.214 12.679-18.214 12.679s-7.147-19.064 28.75-51.786c36.172-32.972 142.03-48.05 159.82-87.857z" enable-background="accumulate" fill="url(#eb)"/>
+  </g>
+  <g enable-background="new">
+   <g transform="matrix(1.0057 0 0 2.3995 3757 -22.424)" fill-rule="evenodd">
+    <path transform="translate(-329.81)" d="M179.64 267.36c-22.41 39.703-60.616 115.78-69.286 149.64-8.647 33.775-8.772 66.417-.357 86.429 8.36 19.882 26.164 35.633 40.714 41.429-.597-14.376 14.373-43.286 72.857-72.5 58.626-29.285 78.382-27.131 103.57-47.143 25.63-20.362 8.206-79.647 3.214-93.929s-1.236-3.38-1.946-5.093c-10.689-25.816-34.214-54.43-64.483-64.55s-65.018-4.848-84.286 5.714z" clip-path="url(#x)" fill="url(#m)"/>
+    <ellipse transform="rotate(28.068 -88.085 -332.1)" cx="183.57" cy="338.08" rx="64.716" ry="134.01" enable-background="accumulate" fill="url(#dz)"/>
+    <ellipse transform="rotate(28.068 -43.578 -333.81)" cx="183.57" cy="338.08" rx="64.716" ry="134.01" enable-background="accumulate" fill="url(#fg)"/>
+   </g>
+   <path transform="matrix(1.0057 0 0 2.3995 3425.3 -22.424)" d="M179.64 267.36c-22.41 39.703-60.616 115.78-69.286 149.64-8.647 33.775-8.772 66.417-.357 86.429 8.36 19.882 26.164 35.633 40.714 41.429-.597-14.376 14.373-43.286 72.857-72.5 58.626-29.285 78.382-27.131 103.57-47.143 25.63-20.362 8.206-79.647 3.214-93.929s-1.236-3.38-1.946-5.093c-10.689-25.816-34.214-54.43-64.483-64.55s-65.018-4.848-84.286 5.714z" clip-path="url(#x)" enable-background="new" fill="none" filter="url(#hd)" stroke="url(#l)" stroke-width="20.8"/>
+  </g>
+  <g transform="matrix(1.0057 0 0 2.3995 2971.9 -201.33)" fill-rule="evenodd">
+   <circle transform="translate(452.56 72.581)" cx="310.71" cy="398.08" r="19.704" enable-background="accumulate" stroke="#000" stroke-linejoin="bevel"/>
+   <circle transform="translate(450.56 72.581)" cx="310.71" cy="398.08" r="19.704" enable-background="accumulate" fill="url(#m)" filter="url(#hc)" stroke="url(#l)" stroke-width="20.8"/>
+   <circle transform="translate(450.56 72.581)" cx="310.71" cy="398.08" r="19.704" enable-background="accumulate" fill="url(#dy)"/>
+   <ellipse transform="rotate(-4.471 1823.1 -5529.2)" cx="429.57" cy="377.43" rx="72.08" ry="44.548" enable-background="accumulate" fill="url(#dx)" filter="url(#hb)"/>
+   <ellipse transform="matrix(1.4358 -.07 .07 1.4358 235.18 -63.865)" cx="437.7" cy="391.22" rx="36.612" ry="22.627" enable-background="accumulate" fill="url(#dw)" filter="url(#ha)"/>
+   <g transform="translate(450.03 73.844)" enable-background="new" filter="url(#gz)">
+    <circle cx="413.66" cy="401.83" r="3.214" enable-background="accumulate" stroke="url(#dv)"/>
+    <circle transform="translate(13.125 8.125)" cx="413.66" cy="401.83" r="3.214" enable-background="accumulate" stroke="url(#du)"/>
+    <circle transform="translate(32.946 7.5)" cx="413.66" cy="401.83" r="3.214" enable-background="accumulate" stroke="url(#ej)"/>
+    <circle transform="translate(24.911 -10.268)" cx="413.66" cy="401.83" r="3.214" enable-background="accumulate" stroke="url(#ei)"/>
+    <circle transform="translate(47.589 -.625)" cx="413.66" cy="401.83" r="3.214" enable-background="accumulate" stroke="url(#eh)"/>
+   </g>
+  </g>
+  <g fill="none" stroke="#000">
+   <path transform="matrix(1.0057 0 0 2.3995 2971.9 -201.33)" d="M896.2 482.93c.985 4.35 4.537 6.18 7.387 7.892 4.46 2.513 6.52 1.522 9.154-.758 1.602-1.921 10.683-4.698 15.594-7.07 4.33-1.46 8.904-5.36 13.385-8.335 3.395-1.627 5.347.355 7.829 1.01 2.944.717 4.411 2.172 6.06 3.536 2.397 1.175-.927 3.143 3.284 4.293 1.19.218 2.417.577 3.283-.505" enable-background="new"/>
+   <path transform="matrix(1.0057 0 0 2.3995 2971.9 -201.33)" d="M910.85 475.35c2.315-.032 3.178.643 5.493-.82 3.455-3.082 5.402-3.146 7.955-4.42 3.026-1.315 6.535 8.152 10.102 9.849 2.395-.822 1.289 1.794 1.452 2.651.057 2.647 2.807 3.679 4.356 5.43 3.316 2.256 7.375 6.296 11.112 5.303 6.445-2.93 10.28-1.281 16.29-7.386.703-1.182-.585-6.895 3.093-7.198 2.524.254 4.166.05 6.06.569 5.442 2.117 7.738 6.45 14.71 7.955 6.184.966 7.613 3.794 13.89 5.05M876.98 483.52c2.399-.794 6.106 4.192 8.173 7.046.593 2.68 1.154 5.486.758 12.122.785 2.417 2.68 3.03 4.798 3.283 3.117-.537 5.877-1.325 7.324-3.03 1.871-1.942 5.312 2.393 8.08 4.04 3.61 1.912 7.775 1.979 11.87 2.273 1.703-.231 2.37 4.515 3.283 8.08.384 4.379-.886 6.897-1.768 9.85-.294 2.496 2.988 3.53 6.313 4.546 3.183.74 6.545 1.661 9.092 1.767 5.142.875 8.088 2.69 12.122 4.04 2.239.817 3.26 2.243 4.545 3.536" enable-background="new"/>
+  </g>
+  <g transform="matrix(.9991 .27421 -.11493 2.3838 2962.6 1209.8)" enable-background="new" fill-rule="evenodd" mask="url(#gy)">
+   <path d="M1111.48-285.971l-3.937 1.875c-.041.01-.1.02-.125.031-.42.213-.165.1-.657.312-.486.21-1.737.585-4.093 1.47-3.332 1.25-5.805 2.15-7 3.062-1.537.021-3.72.233-5.657.719a227.677 227.677 0 0 1-6.75 1.593c-1.894.42-1.675.642-2.875.875-1.296.252-1.721-.009-5.437.782-3.49.742-8.895 1.93-10.156 2.687-1.584-.18-3.868-.322-5.844-.031-3.04.447-4.916.673-6.844.906-.655.08-1.04.2-1.343.281-.427.132-.686.26-1.375.344-1.312.16-1.763-.157-5.532.281-3.554.413-9.005 1.273-10.25 1.938-1.599-.297-3.857-.534-5.843-.344-3.06.293-4.972.484-6.907.656-1.934.173-1.688.423-2.906.532-1.316.117-1.76-.164-5.531.25-3.542.388-9.008 1.209-10.281 1.875-1.6-.295-3.887-.507-5.875-.313-3.058.3-4.941.48-6.875.656-.658.06-1.04.179-1.344.25-.428.12-.683.218-1.375.282-1.316.12-1.76-.195-5.531.218-3.556.39-9.006 1.24-10.25
+1.907-1.599-.295-3.86-.524-5.844-.313-3.056.325-4.974.526-6.906.719s-1.69.44-2.906.562c-1.315.132-1.763-.164-5.532.282-3.538.418-8.977 1.292-10.25 1.968-1.597-.28-3.86-.42-5.843-.187-3.052.358-4.945.568-6.875.781-.657.073-1.041.173-1.344.25-.427.127-.685.267-1.375.344-1.314.146-1.768-.174-5.531.312-3.55.46-8.979 1.42-10.22 2.125-1.592-.244-3.833-.381-5.812-.125-3.047.395-4.95.649-6.875.907-1.924.257-1.726.493-2.937.656-1.31.176-1.748-.105-5.5.469-3.525.538-8.924 1.699-10.188 2.437-1.588-.203-3.846-.255-5.813.094-3.026.536-4.899.861-6.812 1.187-.65.111-1.014.271-1.313.375-.42.165-.663.332-1.344.469-1.294.262-1.727-.006-5.437.813-3.499.771-8.846 2.382-10.062 3.218-1.563-.077-3.758.086-5.688.594-2.972.783-4.817 1.232-6.687 1.75s-1.667.767-2.844 1.094c-1.272.353-1.697.107-5.344 1.187-3.424 1.015-8.65 2.934-9.875 3.844-1.539.013-3.72.272-5.625.875-2.93.928-4.75 1.459-6.594
+2.063-.626.205-.991.392-1.28.53-.408.215-.654.41-1.313.626-1.255.411-1.686.189-5.281 1.437-3.39 1.178-8.595 3.214-9.782 4.157-1.524.06-3.65.395-5.53 1.062-2.898 1.028-4.7 1.676-6.532 2.313-1.832.637-1.628.848-2.781 1.25-1.247.434-1.664.2-5.22 1.562-3.338 1.28-8.486 3.483-9.687 4.469-1.507.108-3.635.499-5.5 1.219a1047.26 1047.26 0 0 1-6.437 2.469c-.617.233-.997.442-1.281.593v.031l-8 3.188-12.476 3.492 7.93 19.278c-.592 1.973 12.545-4.739 12.545-4.739.227-.144.45-.272.72-.375 1.08-.41 2.17-.215 6-1.687 3.828-1.472 5.223-2.005 5.905-2.406.68-.4 1.612-.88 2.22-1.531 1.826-.138 3.57-.494 4.937-1 2.968-1.1 4.875-1.807 6.78-2.47 1.907-.662 2.355-1.414 3.407-1.78 1.092-.38 2.195-.166 6.063-1.532 3.867-1.366 5.283-1.827 5.968-2.218.702-.4 1.701-.933 2.313-1.594 1.97-.055 3.817-.385 5.281-.875 3.002-1.005 4.926-1.622 6.844-2.25 1.538-.504 2.174-1.047 2.906-1.438.23-.134.476-.253.75-.343 1.098-.36
+2.181-.082 6.094-1.313 3.912-1.231 5.366-1.673 6.062-2.031.694-.357 1.63-.793 2.25-1.406 1.866-.023 3.636-.267 5.032-.688 3.03-.913 4.992-1.43 6.937-1.969 1.945-.538 2.426-1.264 3.5-1.562 1.114-.31 2.22.007 6.188-1.031 3.967-1.039 5.417-1.433 6.125-1.75.734-.33 1.813-.754 2.437-1.375 1.998.116 3.857-.02 5.344-.375 3.078-.735 5.083-1.101 7.062-1.5 1.588-.32 2.245-.79 3-1.094a3.4 3.4 0 0 1 .75-.25c1.134-.23 2.305.209 6.344-.5 4.04-.71 5.5-.927 6.219-1.188.716-.26 1.704-.567 2.344-1.093 1.924.239 3.748.224 5.187 0 3.127-.488 5.155-.701 7.156-.97 2.002-.267 2.49-.944 3.594-1.093 1.147-.154 2.276.302 6.344-.219 4.068-.52 5.56-.695 6.281-.937.737-.247 1.798-.586 2.438-1.125 2.05.335 3.973.398 5.5.218 3.142-.368 5.18-.559 7.187-.78 1.611-.179 2.265-.609 3.031-.845.241-.085.495-.155.782-.187 1.15-.128 2.301.347 6.375-.125s5.559-.61 6.28-.844c.72-.232 1.701-.473 2.345-.969 1.936.334 3.77.405
+5.219.25 3.146-.334 5.177-.518 7.187-.718 2.01-.2 2.484-.827 3.594-.938 1.15-.115 2.296.365 6.375-.062s5.589-.562 6.312-.782c.74-.223 1.796-.513 2.438-1.03 2.057.398 4.002.493 5.531.343 3.149-.308 5.176-.473 7.188-.656 1.614-.147 2.263-.56 3.03-.781.242-.081.494-.13.782-.157 1.152-.105 2.293.393 6.375 0s5.589-.53 6.312-.75c.721-.218 1.7-.447 2.344-.937 1.938.35 3.769.454 5.219.312 3.149-.308 5.176-.473 7.187-.656 2.012-.183 2.515-.838 3.625-.937 1.153-.104 2.293.384 6.375 0 4.083-.385 5.59-.501 6.313-.72.74-.222 1.796-.514 2.437-1.03 2.058.401 4.003.503 5.532.343 3.146-.328 5.177-.522 7.187-.718 1.613-.158 2.266-.632 3.031-.875.241-.088.464-.122.75-.157 1.149-.14 2.317.34 6.375-.25 4.059-.59 5.562-.777 6.282-1.03.716-.254 1.674-.559 2.312-1.095 1.92.212 3.72.152 5.156-.093 3.12-.533 5.112-.929 7.094-1.313 1.982-.384 2.474-1.04 3.563-1.281 1.128-.25 2.27.116 6.25-.875s5.43-1.42
+6.125-1.781c.722-.376 1.761-.87 2.375-1.531 1.963-.012 3.793-.292 5.218-.844 2.952-1.145 4.874-1.87 6.688-2.75 1.456-.707 2.32-1.702 2.531-2 .212-.298.1-.729.125-.75.043-.035.34-.094.5-.438.86-1.847 2.323-5.627 2.438-6.312.113-.682.168-1.353.218-1.75.03-.23-.147-.88-.125-.938.031-.082.289-.25.344-.5.266-1.198.09-2.207-.125-3.625-.214-1.417-.972-4.614-1.625-5.469-.659-.861-1.225-1.01-1.75-1z" enable-background="new" fill="#bcb786"/>
+   <g clip-path="url(#gx)">
+    <path d="M1107.4-284.05c-.419.213-.156.094-.647.306-.486.21-1.724.574-4.08 1.459-3.33 1.25-5.83 2.153-7.026 3.066-1.536.021-3.72.233-5.656.719a227.709 227.709 0 0 1-6.75 1.593c-1.895.42-1.676.643-2.875.875-1.297.252-1.721-.009-5.438.782-3.49.742-8.894 1.93-10.156 2.687-1.583-.18-3.867-.322-5.843-.031-3.04.447-4.917.673-6.844.906-.655.08-1.041.201-1.344.282-.426.131-.686.26-1.375.343-1.311.16-1.762-.157-5.531.282-3.554.413-9.005 1.272-10.25 1.937-1.599-.297-3.858-.534-5.844-.344-3.059.294-4.972.484-6.906.657-1.934.172-1.689.422-2.906.53-1.317.118-1.76-.163-5.532.25-3.541.39-9.007 1.21-10.28 1.876-1.6-.295-3.888-.507-5.876-.313-3.058.3-4.94.48-6.875.657-.657.06-1.04.178-1.343.25-.428.118-.684.218-1.375.28-1.316.121-1.76-.194-5.532.22-3.556.39-9.005 1.239-10.25
+1.906-1.598-.294-3.86-.524-5.843-.313-3.056.326-4.974.526-6.907.719-1.932.192-1.69.44-2.906.562-1.315.132-1.763-.164-5.53.282-3.54.418-8.979 1.292-10.25 1.969-1.599-.282-3.86-.42-5.845-.188-3.052.358-4.945.568-6.875.781-.656.073-1.04.173-1.344.25-.426.127-.684.267-1.375.344-1.313.146-1.767-.174-5.53.313-3.55.458-8.98 1.419-10.22 2.125-1.593-.245-3.834-.382-5.812-.125-3.048.394-4.95.648-6.875.906-1.925.258-1.726.493-2.938.656-1.31.176-1.747-.104-5.5.469-3.524.538-8.923 1.699-10.188 2.437-1.587-.203-3.845-.254-5.812.094-3.026.536-4.9.862-6.813 1.187-.65.111-1.013.271-1.312.375-.42.165-.664.332-1.344.47-1.295.26-1.727-.007-5.438.812-3.498.772-8.846 2.383-10.062 3.219-1.562-.078-3.757.085-5.687.593-2.972.783-4.818 1.232-6.688 1.75s-1.666.768-2.843 1.094c-1.273.353-1.697.107-5.344 1.188-3.425 1.014-8.65 2.933-9.875 3.843-1.539.013-3.72.273-5.625.875-2.931.928-4.75 1.459-6.594
+2.063-.627.205-.992.392-1.281.531-.408.214-.653.409-1.313.625-1.254.412-1.686.19-5.28 1.438-3.39 1.177-8.596 3.213-9.782 4.156-1.524.06-3.65.395-5.531 1.062-2.898 1.029-4.7 1.676-6.531 2.313-1.833.637-1.628.848-2.782 1.25-1.246.434-1.663.2-5.218 1.562-3.34 1.28-8.488 3.483-9.688 4.47-1.507.107-3.636.498-5.5 1.218a1044.752 1044.752 0 0 1-6.437 2.469c-.617.233-.997.442-1.282.593v1.094c.112-.222.386-.817.907-1.094.698-.37 4.813-1.993 6.812-2.718 1.657-.602 4.154-1.329 5.969-1.313.302.003.588.051.844.094 1.842.308 7.468 1.562 7.468 1.562s-6.233-1.646-7.03-1.843c-.191-.048-.536-.07-.97-.063 1.146-.87 4.762-2.393 7.344-3.437 2.839-1.148 3.117-1.252 5.063-1.657 2.008-.417 3.156-.5 3.156-.5s-.082-.6.969-1.125c.705-.351 4.887-1.892 6.906-2.562 1.952-.648 5.057-1.359 6.875-1 1.863.367 7.531 1.812 7.531 1.812s-6.287-1.87-7.094-2.093c-.193-.054-.53-.086-.968-.094 1.158-.833 4.794-2.195 7.406-3.156
+2.87-1.056 3.167-1.162 5.125-1.532 1.853-.35 2.859-.425 3.031-.437.114-.217.377-.81.906-1.063.71-.338 4.926-1.712 6.97-2.312 1.692-.497 4.24-1.037 6.093-.906.308.021.613.097.875.156 1.881.424 7.594 2.031 7.594 2.031s-6.342-2.065-7.157-2.312c-.194-.06-.557-.104-1-.125 1.17-.798 4.863-2.057 7.5-2.938 2.898-.968 3.233-1.003 5.22-1.281 2.049-.287 3.187-.313 3.187-.313s-.073-.607 1-1.062c.72-.306 4.99-1.5 7.062-2 2.003-.483 5.199-.928 7.063-.406 1.91.535 7.719 2.5 7.719 2.5s-6.423-2.424-7.25-2.72c-.198-.07-.583-.14-1.032-.187 1.188-.728 4.916-1.774 7.594-2.5 2.944-.797 3.292-.77 5.313-.906 1.913-.128 2.947-.07 3.125-.062.117-.204.391-.78.937-.97.732-.253 5.079-1.047 7.188-1.374 1.748-.271 4.4-.485 6.312-.094.318.065.605.186.875.281 1.94.69 7.844 3.094 7.844 3.094s-6.535-2.95-7.375-3.312c-.201-.087-.575-.167-1.031-.25 1.206-.633 5.03-1.396 7.75-1.906 2.99-.562 3.3-.53 5.344-.532 2.109-.002
+3.312.125 3.312.125s-.073-.63 1.031-.937c.74-.206 5.126-.834 7.25-1.063 2.053-.22 5.319-.252 7.22.47 1.947.738 7.843 3.374 7.843 3.374s-6.563-3.179-7.406-3.562c-.202-.092-.543-.187-1-.282 1.21-.602 4.984-1.248 7.718-1.656 3.005-.448 3.326-.452 5.375-.406 1.94.043 3.007.194 3.188.219.119-.194.384-.766.937-.907.743-.188 5.155-.734 7.282-.937 1.763-.169 4.42-.234 6.343.25.32.08.604.203.875.312 1.953.784 7.907 3.47 7.907 3.47s-6.592-3.254-7.438-3.657c-.202-.096-.572-.207-1.031-.313 1.214-.574 5.044-1.122 7.781-1.5 3.009-.415 3.323-.442 5.375-.375 2.118.07 3.313.25 3.313.25s-.078-.637 1.03-.906c.745-.18 5.153-.663 7.282-.844 2.059-.174 5.343-.124 7.25.657 1.955.8 7.875 3.53 7.875 3.53s-6.56-3.308-7.406-3.718c-.202-.098-.572-.203-1.031-.312 1.215-.564 5.01-1.115 7.75-1.47 3.01-.389 3.321-.397 5.375-.312 1.944.08 3.006.254 3.187.282.12-.191.383-.746.938-.875.744-.174 5.15-.65 7.28-.813
+1.767-.134 4.45-.126 6.376.375.32.083.603.201.875.313 1.954.8 7.906 3.562 7.906 3.562s-6.591-3.34-7.437-3.75c-.203-.098-.572-.203-1.032-.312 1.215-.564 5.042-1.084 7.782-1.438 3.01-.39 3.352-.429 5.406-.344 2.12.088 3.312.313 3.312.313s-.078-.65 1.032-.906c.744-.173 5.15-.624 7.28-.782 2.061-.152 5.344-.096 7.25.688 1.956.804 7.876 3.5 7.876 3.5s-6.56-3.276-7.406-3.688c-.203-.098-.572-.202-1.032-.312 1.216-.562 5.012-1.128 7.75-1.5 3.01-.41 3.323-.416 5.375-.344 1.943.068 3.008.165 3.188.188.119-.195.384-.73.937-.875.742-.197 5.131-.83 7.25-1.094 1.757-.22 4.406-.333 6.313.031.317.06.606.19.875.281 1.936.661 7.844 2.938 7.844 2.938s-6.537-2.807-7.375-3.156c-.2-.084-.577-.174-1.032-.25 1.204-.651 5.02-1.372 7.72-2 2.966-.69 3.288-.756 5.312-.875 2.088-.124 3.28-.032 3.28-.032s-.086-.632 1-1.03c.73-.269 5.048-1.339 7.126-1.813 2.008-.46 5.168-1.03 7-.625 1.878.414 13.578 3.015 13.578
+3.015s-12.328-3.022-13.141-3.265c-.195-.058-.559-.107-1-.125 1.167-.804 3.514-1.688 6.11-2.703 1.68-.659.923-.377 2.775-1.004 1.754-.594 2.486-1.01 2.63-1.113.347-.207-.355-.122-.544-.042z" enable-background="new" filter="url(#gw)"/>
+    <path d="m1082.6-275.12c1.873 0.393 4.496 1.146 6.031 1.969s2.822 1.056 5.375 2.5c2.527 1.43 4.796 2.007 6.969 2.531 2.348 0.566 5.435 0.715 8.844 1.188-1.09-0.84-6.608-1.173-8.406-1.563-1.8-0.39-3.895-1.016-6.594-2.313-2.7-1.296-3.495-1.799-5.813-2.687-2.318-0.889-4.004-1.383-6.406-1.625z" enable-background="new" filter="url(#gv)"/>
+    <path d="M1051.5-270c1.905.578 4.528 1.616 6.094 2.594 1.565.978 2.88 1.36 5.5 3.125 2.593 1.747 4.986 2.71 7.25 3.594 2.446.955 5.682 1.657 9.406 3.062-1.19-1.138-7.063-2.687-8.938-3.375-1.874-.688-4.081-1.566-6.874-3.281-2.794-1.715-3.574-2.284-5.938-3.406-2.364-1.123-4.057-1.835-6.5-2.313z" enable-background="new" filter="url(#gu)"/>
+    <path d="m1020.2-266.84c1.912 0.638 4.581 1.755 6.156 2.813 1.575 1.057 2.896 1.508 5.531 3.406 2.61 1.878 5.029 3.03 7.313 4.062 2.468 1.116 5.764 2.174 9.531 3.844-1.203-1.222-7.203-3.314-9.094-4.125-1.89-0.81-4.064-1.894-6.874-3.75s-3.622-2.477-6-3.719c-2.379-1.242-4.111-1.975-6.563-2.531z" enable-background="new" filter="url(#gt)"/>
+    <path d="M1110.2-266.89c.15.049.688.631.11 1.484-.81 1.195-5.705 3.325-8.563 4.125-2.845.798-6.29.978-10.562-.375-4.302-1.362-5.47-2.468-10.656-4.312 4.664 2.115 6.195 3.952 10.125 5.344 1.62.574 3.367.94 5.062 1.03-.445.327-1.53.984-3.562 1.595-2.796.84-6.65 1.534-8.25 1.625-1.515.086-3.142-.513-3.438-.625.167.103.374.377-.25 1.03-.899.945-6.147 1.924-9.125 2.25-2.964.326-6.521-.015-10.906-1.905-3.978-1.715-5.339-2.916-9.406-4.75v.156c3.643 2.095 5.284 3.883 8.875 5.562 1.73.81 3.592 1.41 5.406 1.72-.534.286-1.557.71-3.437 1.03-2.87.488-6.81.817-8.438.75-.85-.034-1.728-.184-2.406-.406-.685-.215-1.19-.444-1.312-.5.169.107.43.403-.22 1.031-.909.88-6.245 1.337-9.25 1.47-2.99.131-6.588-.451-11-2.563-4.44-2.127-5.64-3.402-10.905-5.782 4.734 2.597 6.286 4.63 10.344 6.72 1.673.861 3.485 1.493 5.25
+1.937-.463.233-1.59.688-3.688.937-2.886.343-6.834.493-8.468.375-1.547-.111-3.232-.857-3.532-1 .17.12.414.41-.218 1-.913.851-6.244 1.262-9.25 1.375-2.993.113-6.59-.49-11-2.594-4.002-1.908-5.388-3.137-9.47-5.093v.156c3.656 2.204 5.295 4.053 8.907 5.906 1.74.893 3.637 1.528 5.469 1.969-.54.248-1.578.615-3.469.844-2.886.348-6.866.52-8.5.406a9.446 9.446 0 0 1-2.406-.5 12.532 12.532 0 0 1-1.313-.531c.17.112.465.422-.187 1.03-.913.853-6.275 1.294-9.281 1.407-2.993.112-6.594-.528-11-2.594-4.437-2.08-5.647-3.331-10.906-5.656 4.729 2.548 6.29 4.578 10.344 6.625 1.671.844 3.485 1.467 5.25 1.906-.464.235-1.59.684-3.688.938-2.886.348-6.836.57-8.469.469-1.544-.096-3.2-.83-3.5-.97.17.12.382.405-.25 1-.912.861-6.246 1.331-9.25 1.47-2.99.138-6.567-.451-10.969-2.47-3.993-1.83-5.365-3.028-9.437-4.905v.156c3.647 2.133 5.27 3.935 8.875 5.719 1.737.86 3.607 1.45 5.437
+1.875-.54.253-1.55.64-3.437.906-2.88.404-6.838.646-8.469.562a9.36 9.36 0 0 1-2.406-.437 12.971 12.971 0 0 1-1.313-.5c.17.109.432.41-.218 1.031-.911.87-6.25 1.392-9.25 1.563-2.987.17-6.574-.316-10.97-2.282-4.424-1.978-5.605-3.228-10.843-5.375 4.71 2.388 6.27 4.39 10.312 6.344a23.73 23.73 0 0 0 5.218 1.781c-.461.25-1.597.713-3.687 1.032-2.876.438-6.78.733-8.406.687-1.539-.043-3.233-.745-3.532-.875.169.113.411.414-.218 1.031-.908.891-6.203 1.529-9.188 1.813-2.971.283-6.573-.176-10.938-1.938-3.96-1.598-5.329-2.795-9.344-4.312v.156c3.596 1.811 5.239 3.582 8.813 5.156 1.722.759 3.587 1.29 5.406 1.625-.536.28-1.566.688-3.437 1.063-2.856.572-6.79 1.02-8.407 1.031-.844.006-1.706-.08-2.375-.25-.676-.162-1.16-.33-1.28-.375.166.094.422.383-.22 1.062-.897.951-6.186 1.918-9.125 2.438-2.925.518-6.432.374-10.719-1.031-4.315-1.415-5.472-2.53-10.562-3.969 4.577 1.751 6.09 3.56 10.031 5 1.627.594 3.37.956
+5.094 1.156-.453.297-1.555.884-3.594 1.469-2.804.805-6.638 1.576-8.218 1.75-1.495.165-3.117-.317-3.407-.406.164.09.393.36-.218 1.062-.883 1.014-6.045 2.372-8.938 3.063-2.88.687-6.335.76-10.562-.438-3.835-1.086-5.172-2.072-9.062-3.125v.156c3.484 1.395 5.07 2.92 8.53 4.032 1.669.535 3.457.786 5.22.875-.52.352-1.5.914-3.313 1.53-2.765.942-6.59 1.936-8.156 2.157-.818.115-1.633.123-2.281.031-.655-.083-1.133-.218-1.25-.25.162.075.434.34-.188 1.094-.87 1.055-6.01 2.66-8.875 3.438-2.852.774-6.259.958-10.438-.094-4.206-1.06-5.356-2.042-10.344-3.156 4.485 1.46 5.97 3.135 9.813 4.25 1.585.46 3.287.638 4.969.687-.442.337-1.513 1.028-3.5 1.781-2.734 1.037-6.452 2.163-8 2.438-1.465.26-3.06-.117-3.344-.188.16.08.38.321-.219 1.063-.865 1.07-5.916 2.818-8.75 3.687-2.82.866-6.207 1.157-10.344.22-3.753-.852-5.048-1.717-8.875-2.595v.157c3.428 1.237 4.987 2.632 8.375 3.53 1.632.434 3.367.584
+5.094.563-.51.384-1.477 1.022-3.25 1.75-2.706 1.112-6.436 2.308-7.969 2.625-.8.166-1.612.219-2.25.157v1.406c.227-.145.449-.273.719-.375 1.08-.41 2.171-.216 6-1.688 3.828-1.471 5.224-2.005 5.906-2.406.68-.4 1.612-.88 2.219-1.531 1.827-.138 3.57-.493 4.937-1 2.968-1.1 4.876-1.806 6.782-2.469 1.905-.663 2.354-1.415 3.406-1.781 1.091-.38 2.195-.166 6.062-1.531 3.868-1.366 5.283-1.827 5.969-2.22.701-.4 1.7-.932 2.313-1.593 1.97-.055 3.816-.385 5.28-.875 3.002-1.005 4.927-1.622 6.845-2.25 1.538-.504 2.174-1.047 2.906-1.437.23-.135.475-.254.75-.344 1.098-.36 2.181-.082 6.094-1.313 3.912-1.23 5.366-1.673 6.062-2.03.694-.358 1.63-.794 2.25-1.407 1.865-.023 3.636-.267 5.031-.688 3.03-.913 4.993-1.43 6.938-1.968 1.945-.54 2.426-1.265 3.5-1.563 1.114-.31 2.22.007 6.187-1.031 3.968-1.039 5.418-1.433 6.125-1.75.735-.33 1.814-.754 2.438-1.375 1.997.116 3.857-.02 5.344-.375 3.078-.735 5.083-1.101
+7.062-1.5 1.588-.32 2.244-.79 3-1.094.238-.107.467-.193.75-.25 1.134-.23 2.305.209 6.344-.5s5.5-.927 6.219-1.187c.715-.26 1.704-.568 2.343-1.094 1.925.24 3.748.224 5.188 0 3.126-.488 5.155-.7 7.156-.969 2.002-.268 2.489-.945 3.594-1.094 1.146-.154 2.276.302 6.344-.219 4.068-.52 5.56-.695 6.28-.937.738-.247 1.799-.586 2.438-1.125 2.05.335 3.974.398 5.5.219 3.143-.37 5.18-.56 7.188-.782 1.61-.178 2.265-.608 3.031-.843a3.43 3.43 0 0 1 .781-.188c1.15-.128 2.302.347 6.375-.125s5.56-.61 6.282-.844c.719-.232 1.7-.473 2.343-.968 1.937.333 3.77.404 5.22.25 3.145-.335 5.177-.519 7.187-.719 2.01-.2 2.484-.826 3.593-.938 1.152-.115 2.297.366 6.375-.062s5.59-.562 6.313-.781c.74-.224 1.796-.514 2.437-1.031 2.058.398 4.002.493 5.532.343 3.148-.308 5.175-.473 7.187-.656 1.614-.147 2.263-.56 3.031-.781.242-.081.494-.13.782-.156 1.152-.106 2.293.392 6.375 0 4.082-.393 5.589-.531 6.312-.75.721-.219
+1.7-.448 2.344-.938 1.938.35 3.769.454 5.219.313 3.148-.309 5.175-.474 7.187-.657 2.012-.183 2.514-.838 3.625-.937 1.152-.103 2.292.385 6.375 0s5.589-.501 6.313-.719c.739-.222 1.795-.514 2.437-1.031 2.057.402 4.003.503 5.531.344 3.147-.329 5.178-.523 7.188-.72 1.613-.156 2.266-.63 3.031-.874.24-.088.463-.122.75-.156 1.148-.14 2.317.34 6.375-.25 4.058-.59 5.562-.778 6.281-1.032.717-.253 1.675-.558 2.313-1.093 1.92.211 3.72.151 5.156-.094 3.12-.533 5.112-.929 7.094-1.313 1.982-.384 2.474-1.04 3.562-1.28 1.13-.252 2.27.115 6.25-.876s5.43-1.42 6.125-1.781c.723-.376 1.762-.87 2.375-1.531 1.963-.012 3.794-.291 5.22-.844 2.95-1.145 4.872-1.87 6.687-2.75 1.455-.707 2.334-1.686 2.547-1.984.212-.298.111-.746.137-.767.043-.035.32-.085.48-.429.858-1.847 2.32-5.644
+2.435-6.329.113-.682.163-1.348.214-1.745.03-.23-.147-.865-.125-.924.031-.082.305-.265.36-.515.267-1.198.09-2.191-.125-3.609-.214-1.417-.983-4.622-1.637-5.476-.659-.862-1.223-1.011-1.748-1-.208.27.137.262.163.312.68.05.934.369 1.42.897s1.442 3.94 1.579 5.39.19 2.86-.088 3.468c-.278.609-.944.429-1.237.495.531.186.89.213.953 1.057.058.814-.134 1.64-.52 2.806-.391 1.18-1.845 4.35-2.286 4.599-.452.255-.952.182-1.288.05z" enable-background="new" filter="url(#gs)"/>
+    <path d="m988.75-263.84c1.912 0.634 4.55 1.758 6.125 2.813 1.575 1.054 2.896 1.482 5.531 3.375 2.609 1.873 5.027 3.015 7.313 4.062 2.47 1.132 5.752 2.155 9.531 3.938-1.207-1.259-7.139-3.365-9.031-4.188s-4.128-1.93-6.938-3.781-3.622-2.482-6-3.719c-2.377-1.237-4.08-1.95-6.53-2.5z" enable-background="new" filter="url(#gr)"/>
+    <path d="M957.5-260.78c1.91.618 4.583 1.71 6.156 2.75 1.574 1.04 2.896 1.482 5.531 3.375 2.609 1.873 5.027 3.015 7.313 4.063 2.47 1.131 5.752 2.154 9.531 3.937-1.207-1.258-7.201-3.396-9.094-4.219-1.892-.823-4.096-1.93-6.906-3.781-2.81-1.85-3.593-2.44-5.969-3.656s-4.113-1.939-6.562-2.469z" enable-background="new" filter="url(#gq)"/>
+    <path d="M926.09-257.38c1.908.597 4.553 1.664 6.125 2.688 1.571 1.023 2.87 1.44 5.5 3.28 2.603 1.823 5.029 2.973 7.313 4 2.467 1.111 5.755 2.094 9.53 3.845-1.205-1.249-7.171-3.319-9.062-4.125s-4.102-1.891-6.906-3.688c-2.804-1.796-3.627-2.402-6-3.594-2.373-1.191-4.054-1.903-6.5-2.406z" enable-background="new" filter="url(#gp)"/>
+    <path d="M894.91-253.56c1.902.554 4.587 1.589 6.156 2.594s2.874 1.408 5.5 3.219c2.6 1.791 5 2.871 7.281 3.875 2.465 1.083 5.76 2.04 9.532 3.75-1.205-1.236-7.175-3.245-9.063-4.032-1.888-.786-4.075-1.83-6.875-3.593s-3.6-2.369-5.969-3.532c-2.37-1.163-4.123-1.834-6.562-2.28z" enable-background="new" filter="url(#go)"/>
+    <path d="M863.72-248.66c1.88.43 4.504 1.38 6.063 2.313 1.558.932 2.852 1.257 5.468 3 2.59 1.724 4.981 2.708 7.25 3.625 2.452.99 5.74 1.877 9.5 3.5-1.201-1.208-7.152-3.067-9.03-3.782-1.88-.715-4.086-1.684-6.876-3.375s-3.585-2.228-5.937-3.28-4.026-1.713-6.438-2z" enable-background="new" filter="url(#gn)"/>
+    <path d="m833.16-241.38c1.848 0.296 4.47 0.976 6 1.781s2.814 1.056 5.375 2.531c2.535 1.46 4.89 2.326 7.125 3.063 2.414 0.797 5.657 1.467 9.375 2.844-1.188-1.129-7.088-2.59-8.938-3.156-1.85-0.567-4.003-1.374-6.75-2.844-2.746-1.47-3.5-1.92-5.812-2.781-2.311-0.861-4.005-1.32-6.375-1.438z" enable-background="new" filter="url(#gm)"/>
+    <path d="m802.91-232.31c1.822 0.211 4.366 0.8 5.875 1.531 1.51 0.73 2.756 0.93 5.281 2.281 2.5 1.338 4.832 2.049 7.031 2.657 2.377 0.656 5.565 1.073 9.22 2.187-1.168-1.045-6.93-2.103-8.75-2.562-1.822-0.46-3.953-1.127-6.657-2.438s-3.471-1.72-5.75-2.469-3.913-1.179-6.25-1.187z" enable-background="new" filter="url(#gl)"/>
+    <path d="M773.19-222.19c1.811.179 4.32.665 5.813 1.344 1.491.678 2.753.798 5.25 2.062 2.47 1.252 4.79 1.896 6.968 2.438 2.354.585 5.492.897 9.094 1.844-1.15-.992-6.852-1.784-8.656-2.188s-3.916-1.021-6.594-2.25c-2.678-1.229-3.403-1.61-5.656-2.281-2.253-.67-3.896-1.002-6.219-.969z" enable-background="new" filter="url(#gk)"/>
+    <path d="M743.56-211.19c1.793.13 4.273.55 5.75 1.188s2.716.741 5.188 1.937c2.446 1.184 4.72 1.747 6.874 2.219 2.328.51 5.42.68 9 1.562-1.143-.97-6.747-1.59-8.53-1.937-1.784-.347-3.884-.888-6.532-2.031-2.648-1.144-3.395-1.517-5.625-2.125-2.23-.61-3.826-.91-6.125-.813z" enable-background="new" filter="url(#gj)"/>
+    <g fill="#fff" filter="url(#gi)">
+     <path d="M744.94-212.12s7.222-3.223 9.063-3.5 3.352-.003 6 .563c2.647.565 8.735 2.215 11.188 3.374s5.312 3.563 5.312 3.563-7.146-2.78-10.188-3.563-7.645-2.083-10.375-2.312-11 1.875-11 1.875z"/>
+     <path d="m735.47-206.95s3.66-2.223 5.5-2.5 3.665 0.247 6.313 0.813 8.735 2.215 11.188 3.375 6.562 2.125 6.562 2.125-8.396-1.343-11.438-2.125-7.957-2.334-10.688-2.563-7.438 0.875-7.438 0.875zm24.38-10.66s8.544-3.299 10.398-3.458c1.854-0.16 3.642 0.48 6.248 1.212s8.577 2.766 10.95 4.08 6.414 2.537 6.414 2.537-8.294-1.873-11.279-2.848c-2.985-0.974-7.792-2.834-10.503-3.236s-12.228 1.713-12.228 1.713zm15.35-5.62s7.771-2.782 9.628-2.904c1.857-0.12 3.631 0.555 6.222 1.341 2.59 0.787 8.519 2.942 10.864 4.304 2.346 1.362 6.36 2.67 6.36 2.67s-8.253-2.045-11.217-3.08c-2.965-1.035-7.733-2.995-10.434-3.452-2.702-0.458-11.422 1.121-11.422 1.121zm14.44-4.72s8.683-3.52 10.542-3.605 3.62 0.624 6.195 1.46c2.575 0.837 8.46 3.107 10.779 4.514 2.318 1.408 6.307 2.793 6.307 2.793s-8.212-2.204-11.156-3.297-7.673-3.144-10.365-3.654-12.3 1.789-12.3 1.789zm14.86-5.38s7.808-2.583 9.666-2.668c1.86-0.085 3.62
+0.625 6.195 1.461 2.575 0.837 8.46 3.107 10.78 4.514 2.318 1.407 6.307 2.792 6.307 2.792s-8.213-2.204-11.156-3.296-7.673-3.144-10.365-3.654-11.426 0.85-11.426 0.85zm15.06-4.25s8.558-2.583 10.417-2.668 3.62 0.625 6.195 1.461c2.575 0.837 8.46 3.107 10.779 4.514 2.318 1.407 6.307 2.792 6.307 2.792s-8.212-2.204-11.156-3.296-7.673-3.144-10.365-3.654-12.176 0.85-12.176 0.85zm16.67-5.02s6.967-1.987 8.828-1.968c1.86 0.02 3.579 0.827 6.102 1.807 2.524 0.98 8.272 3.578 10.508 5.113 2.236 1.536 6.14 3.143 6.14 3.143s-8.075-2.662-10.952-3.919c-2.878-1.256-7.484-3.57-10.143-4.231-2.66-0.66-10.482 0.055-10.482 0.055zm14.5-3.4s7.688-2.028 9.548-1.968 3.56 0.902 6.063 1.936c2.502 1.033 8.194 3.752 10.397 5.335 2.203 1.582 6.072 3.272 6.072 3.272s-8.017-2.833-10.868-4.15c-2.85-1.318-7.407-3.73-10.05-4.446s-11.162 0.021-11.162 0.021zm14.09-3.21s8.17-1.97 10.027-1.854c1.857 0.115 3.532 1.01 6.002
+2.118s8.077 3.997 10.23 5.645 5.972 3.454 5.972 3.454-7.928-3.074-10.738-4.476-7.291-3.95-9.913-4.746c-2.621-0.796-11.58-0.141-11.58-0.141zm16.56-2.39s8.085-1.908 9.938-1.737c1.853 0.172 3.5 1.117 5.935 2.3 2.436 1.182 7.952 4.24 10.055 5.953s5.864 3.633 5.864 3.633-7.832-3.312-10.597-4.8-7.168-4.169-9.764-5.044c-2.597-0.876-11.431-0.305-11.431-0.305zm15.2-2.75s7.642-1.428 9.495-1.265c1.854 0.162 3.505 1.1 5.946 2.27s7.973 4.203 10.084 5.905c2.112 1.703 5.881 3.605 5.881 3.605s-7.847-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.788-4.998-2.6-0.863-10.998-0.77-10.998-0.77zm14.87-1.64s8.642-1.553 10.495-1.39c1.854 0.162 3.505 1.1 5.946 2.27s7.972 4.203 10.084 5.905c2.111 1.703 5.88 3.605 5.88 3.605s-7.846-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.787-4.998-2.601-0.863-11.998-0.644-11.998-0.644zm16.25-2.31s7.642-0.865 9.495-0.703c1.854 0.163 3.505 1.1 5.946 2.27s7.973 4.203 10.084
+5.906c2.112 1.702 5.881 3.605 5.881 3.605s-7.847-3.275-10.62-4.749c-2.772-1.474-7.187-4.135-9.788-4.998-2.6-0.862-10.998-1.331-10.998-1.331zm15.13-1.19s8.58-1.49 10.433-1.328c1.854 0.163 3.505 1.1 5.946 2.27s7.972 4.203 10.084 5.906c2.111 1.702 5.88 3.605 5.88 3.605s-7.846-3.275-10.62-4.749c-2.772-1.474-7.187-4.135-9.787-4.998-2.601-0.862-11.935-0.706-11.935-0.706zm16.25-2.06s7.83-0.803 9.683-0.64c1.854 0.162 3.505 1.1 5.946 2.27s7.972 4.203 10.084 5.905c2.111 1.703 5.88 3.605 5.88 3.605s-7.846-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.787-4.998-2.601-0.863-11.185-1.394-11.185-1.394zm15.37-1.25s8.392-1.178 10.245-1.015c1.854 0.162 3.505 1.1 5.946 2.27s7.972 4.203 10.084 5.905c2.111 1.703 5.88 3.605 5.88 3.605s-7.847-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.788-4.998-2.6-0.863-11.748-1.02-11.748-1.02zm16.19-2.06s6.892-0.99 8.745-0.828c1.854 0.163 3.505 1.1 5.946 2.27s7.973 4.203
+10.084 5.906c2.112 1.702 5.881 3.605 5.881 3.605s-7.847-3.275-10.62-4.749-7.188-4.135-9.788-4.998c-2.6-0.862-10.248-1.206-10.248-1.206zm17.16-0.94s6.83-1.178 8.683-1.015c1.854 0.162 3.505 1.1 5.946 2.27 2.44 1.171 7.972 4.203 10.084 5.905 2.111 1.703 5.88 3.605 5.88 3.605s-7.847-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.788-4.998-2.6-0.863-10.185-1.02-10.185-1.02zm16.1-2s6.08-0.428 7.933-0.265c1.854 0.162 3.505 1.1 5.946 2.27 2.44 1.171 7.972 4.203 10.084 5.905 2.111 1.703 5.88 3.605 5.88 3.605s-7.847-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.788-4.998-2.6-0.863-9.435-1.77-9.435-1.77zm15.8-1.37s6.454-0.678 8.308-0.515c1.854 0.162 3.505 1.1 5.946 2.27 2.44 1.171 7.972 4.203 10.084 5.905 2.111 1.703 5.88 3.605 5.88 3.605s-7.847-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.788-4.998-2.6-0.863-9.81-1.52-9.81-1.52zm15.6-1.86s5.498-0.91 7.358-0.853c1.86 0.056 3.562 0.896 6.066 1.925
+2.504 1.03 8.2 3.739 10.406 5.318 2.205 1.578 6.078 3.261 6.078 3.261s-8.022-2.819-10.875-4.131c-2.853-1.313-7.413-3.716-10.06-4.429-2.645-0.712-8.973-1.091-8.973-1.091zm17.4-2.46s4.547-1.156 6.408-1.186c1.86-0.03 3.6 0.73 6.149 1.642 2.55 0.912 8.365 3.354 10.64 4.829 2.277 1.474 6.224 2.976 6.224 2.976s-8.145-2.444-11.055-3.623c-2.91-1.178-7.578-3.368-10.253-3.957-2.676-0.588-8.113-0.68-8.113-0.68zm14.5-3.03s5.96-1.774 7.82-1.83c1.86-0.057 3.61 0.68 6.172 1.555 2.562 0.876 2.522 0.857 5.333 1.49 2.797 0.63 7.077 1.513 7.077 1.513s-3.616-0.016-6.792-0.466c-3.116-0.441-7.375-1.698-10.058-2.249-2.684-0.55-9.552-0.013-9.552-0.013z" enable-background="new"/>
+     <path d="M1099.2-279.93c.161.269 11.208-4.6 12.188-4.688.98-.087 2 3.125 2 3.125s-.775-1.504-2.875-1.062-11.301 2.671-11.312 2.625z"/>
+    </g>
+    <path d="M1107.5-284.09c-.419.213-.156.094-.647.306-.486.21-1.724.574-4.08 1.459-3.33 1.25-5.83 2.153-7.026 3.066-1.536.021-3.72.233-5.656.719a227.709 227.709 0 0 1-6.75 1.593c-1.895.42-1.676.643-2.875.875-1.297.252-1.721-.009-5.438.782-3.49.742-8.894 1.93-10.156 2.687-1.583-.18-3.867-.322-5.843-.031-3.04.447-4.917.673-6.844.906-.655.08-1.041.201-1.344.282-.426.131-.686.26-1.375.343-1.311.16-1.762-.157-5.531.282-3.554.413-9.005 1.272-10.25 1.937-1.599-.297-3.858-.534-5.844-.344-3.059.294-4.972.484-6.906.657-1.934.172-1.689.422-2.906.53-1.317.118-1.76-.163-5.532.25-3.541.39-9.007 1.21-10.28 1.876-1.6-.295-3.888-.507-5.876-.313-3.058.3-4.94.48-6.875.657-.657.06-1.04.178-1.343.25-.428.118-.684.218-1.375.28-1.316.121-1.76-.194-5.532.22-3.556.39-9.005 1.239-10.25
+1.906-1.598-.294-3.86-.524-5.843-.313-3.056.326-4.974.526-6.907.719-1.932.192-1.69.44-2.906.562-1.315.132-1.763-.164-5.53.282-3.54.418-8.979 1.292-10.25 1.969-1.599-.282-3.86-.42-5.845-.188-3.052.358-4.945.568-6.875.781-.656.073-1.04.173-1.344.25-.426.127-.684.267-1.375.344-1.313.146-1.767-.174-5.53.313-3.55.458-8.98 1.419-10.22 2.125-1.593-.245-3.834-.382-5.812-.125-3.048.394-4.95.648-6.875.906-1.925.258-1.726.493-2.938.656-1.31.176-1.747-.104-5.5.469-3.524.538-8.923 1.699-10.188 2.437-1.587-.203-3.845-.254-5.812.094-3.026.536-4.9.862-6.813 1.187-.65.111-1.013.271-1.312.375-.42.165-.664.332-1.344.47-1.295.26-1.727-.007-5.438.812-3.498.772-8.846 2.383-10.062 3.219-1.562-.078-3.757.085-5.687.593-2.972.783-4.818 1.232-6.688 1.75s-1.666.768-2.843 1.094c-1.273.353-1.697.107-5.344 1.188-3.425 1.014-8.65 2.933-9.875 3.843-1.539.013-3.72.273-5.625.875-2.931.928-4.75 1.459-6.594
+2.063-.627.205-.992.392-1.281.531-.408.214-.653.409-1.313.625-1.254.412-1.686.19-5.28 1.438-3.39 1.177-8.596 3.213-9.782 4.156-1.524.06-3.65.395-5.531 1.062-2.898 1.029-4.7 1.676-6.531 2.313-1.833.637-1.628.848-2.782 1.25-1.246.434-1.663.2-5.218 1.562-3.34 1.28-8.488 3.483-9.688 4.47-1.507.107-3.636.498-5.5 1.218a1044.752 1044.752 0 0 1-6.437 2.469c-.617.233-.997.442-1.282.593v1.094c.112-.222.386-.817.907-1.094.698-.37 4.813-1.993 6.812-2.718 1.657-.602 4.154-1.329 5.969-1.313.302.003.588.051.844.094 1.842.308 7.468 1.562 7.468 1.562s-6.233-1.646-7.03-1.843c-.191-.048-.536-.07-.97-.063 1.146-.87 4.762-2.393 7.344-3.437 2.839-1.148 3.117-1.252 5.063-1.657 2.008-.417 3.156-.5 3.156-.5s-.082-.6.969-1.125c.705-.351 4.887-1.892 6.906-2.562 1.952-.648 5.057-1.359 6.875-1 1.863.367 7.531 1.812 7.531 1.812s-6.287-1.87-7.094-2.093c-.193-.054-.53-.086-.968-.094 1.158-.833 4.794-2.195 7.406-3.156
+2.87-1.056 3.167-1.162 5.125-1.532 1.853-.35 2.859-.425 3.031-.437.114-.217.377-.81.906-1.063.71-.338 4.926-1.712 6.97-2.312 1.692-.497 4.24-1.037 6.093-.906.308.021.613.097.875.156 1.881.424 7.594 2.031 7.594 2.031s-6.342-2.065-7.157-2.312c-.194-.06-.557-.104-1-.125 1.17-.798 4.863-2.057 7.5-2.938 2.898-.968 3.233-1.003 5.22-1.281 2.049-.287 3.187-.313 3.187-.313s-.073-.607 1-1.062c.72-.306 4.99-1.5 7.062-2 2.003-.483 5.199-.928 7.063-.406 1.91.535 7.719 2.5 7.719 2.5s-6.423-2.424-7.25-2.72c-.198-.07-.583-.14-1.032-.187 1.188-.728 4.916-1.774 7.594-2.5 2.944-.797 3.292-.77 5.313-.906 1.913-.128 2.947-.07 3.125-.062.117-.204.391-.78.937-.97.732-.253 5.079-1.047 7.188-1.374 1.748-.271 4.4-.485 6.312-.094.318.065.605.186.875.281 1.94.69 7.844 3.094 7.844 3.094s-6.535-2.95-7.375-3.312c-.201-.087-.575-.167-1.031-.25 1.206-.633 5.03-1.396 7.75-1.906 2.99-.562 3.3-.53 5.344-.532 2.109-.002
+3.312.125 3.312.125s-.073-.63 1.031-.937c.74-.206 5.126-.834 7.25-1.063 2.053-.22 5.319-.252 7.22.47 1.947.738 7.843 3.374 7.843 3.374s-6.563-3.179-7.406-3.562c-.202-.092-.543-.187-1-.282 1.21-.602 4.984-1.248 7.718-1.656 3.005-.448 3.326-.452 5.375-.406 1.94.043 3.007.194 3.188.219.119-.194.384-.766.937-.907.743-.188 5.155-.734 7.282-.937 1.763-.169 4.42-.234 6.343.25.32.08.604.203.875.312 1.953.784 7.907 3.47 7.907 3.47s-6.592-3.254-7.438-3.657c-.202-.096-.572-.207-1.031-.313 1.214-.574 5.044-1.122 7.781-1.5 3.009-.415 3.323-.442 5.375-.375 2.118.07 3.313.25 3.313.25s-.078-.637 1.03-.906c.745-.18 5.153-.663 7.282-.844 2.059-.174 5.343-.124 7.25.657 1.955.8 7.875 3.53 7.875 3.53s-6.56-3.308-7.406-3.718c-.202-.098-.572-.203-1.031-.312 1.215-.564 5.01-1.115 7.75-1.47 3.01-.389 3.321-.397 5.375-.312 1.944.08 3.006.254 3.187.282.12-.191.383-.746.938-.875.744-.174 5.15-.65 7.28-.813
+1.767-.134 4.45-.126 6.376.375.32.083.603.201.875.313 1.954.8 7.906 3.562 7.906 3.562s-6.591-3.34-7.437-3.75c-.203-.098-.572-.203-1.032-.312 1.215-.564 5.042-1.084 7.782-1.438 3.01-.39 3.352-.429 5.406-.344 2.12.088 3.312.313 3.312.313s-.078-.65 1.032-.906c.744-.173 5.15-.624 7.28-.782 2.061-.152 5.344-.096 7.25.688 1.956.804 7.876 3.5 7.876 3.5s-6.56-3.276-7.406-3.688c-.203-.098-.572-.202-1.032-.312 1.216-.562 5.012-1.128 7.75-1.5 3.01-.41 3.323-.416 5.375-.344 1.943.068 3.008.165 3.188.188.119-.195.384-.73.937-.875.742-.197 5.131-.83 7.25-1.094 1.757-.22 4.406-.333 6.313.031.317.06.606.19.875.281 1.936.661 7.844 2.938 7.844 2.938s-6.537-2.807-7.375-3.156c-.2-.084-.577-.174-1.032-.25 1.204-.651 5.02-1.372 7.72-2 2.966-.69 3.288-.756 5.312-.875 2.088-.124 3.28-.032 3.28-.032s-.086-.632 1-1.03c.73-.269 5.048-1.339 7.126-1.813 2.008-.46 5.168-1.03 7-.625 1.878.414 13.578 3.015 13.578
+3.015s-12.328-3.022-13.141-3.265c-.195-.058-.559-.107-1-.125 1.167-.804 3.514-1.688 6.11-2.703 1.68-.659.923-.377 2.775-1.004 1.754-.594 2.486-1.01 2.63-1.113.347-.207-.355-.122-.544-.042z" enable-background="new" filter="url(#gh)" opacity=".25"/>
+    <path d="m1082.6-275.12c1.873 0.393 4.496 1.146 6.031 1.969s2.822 1.056 5.375 2.5c2.527 1.43 4.796 2.007 6.969 2.531 2.348 0.566 5.435 0.715 8.844 1.188-1.09-0.84-6.608-1.173-8.406-1.563-1.8-0.39-3.895-1.016-6.594-2.313-2.7-1.296-3.495-1.799-5.813-2.687-2.318-0.889-4.004-1.383-6.406-1.625z" enable-background="new" filter="url(#gg)" opacity=".25"/>
+    <path d="M1051.5-270c1.905.578 4.528 1.616 6.094 2.594 1.565.978 2.88 1.36 5.5 3.125 2.593 1.747 4.986 2.71 7.25 3.594 2.446.955 5.682 1.657 9.406 3.062-1.19-1.138-7.063-2.687-8.938-3.375-1.874-.688-4.081-1.566-6.874-3.281-2.794-1.715-3.574-2.284-5.938-3.406-2.364-1.123-4.057-1.835-6.5-2.313z" enable-background="new" filter="url(#gf)" opacity=".25"/>
+    <path d="m1020.2-266.84c1.912 0.638 4.581 1.755 6.156 2.813 1.575 1.057 2.896 1.508 5.531 3.406 2.61 1.878 5.029 3.03 7.313 4.062 2.468 1.116 5.764 2.174 9.531 3.844-1.203-1.222-7.203-3.314-9.094-4.125-1.89-0.81-4.064-1.894-6.874-3.75s-3.622-2.477-6-3.719c-2.379-1.242-4.111-1.975-6.563-2.531z" enable-background="new" filter="url(#ge)" opacity=".25"/>
+    <path d="M1110.2-266.89c.15.049.688.631.11 1.484-.81 1.195-5.705 3.325-8.563 4.125-2.845.798-6.29.978-10.562-.375-4.302-1.362-5.47-2.468-10.656-4.312 4.664 2.115 6.195 3.952 10.125 5.344 1.62.574 3.367.94 5.062 1.03-.445.327-1.53.984-3.562 1.595-2.796.84-6.65 1.534-8.25 1.625-1.515.086-3.142-.513-3.438-.625.167.103.374.377-.25 1.03-.899.945-6.147 1.924-9.125 2.25-2.964.326-6.521-.015-10.906-1.905-3.978-1.715-5.339-2.916-9.406-4.75v.156c3.643 2.095 5.284 3.883 8.875 5.562 1.73.81 3.592 1.41 5.406 1.72-.534.286-1.557.71-3.437 1.03-2.87.488-6.81.817-8.438.75-.85-.034-1.728-.184-2.406-.406-.685-.215-1.19-.444-1.312-.5.169.107.43.403-.22 1.031-.909.88-6.245 1.337-9.25 1.47-2.99.131-6.588-.451-11-2.563-4.44-2.127-5.64-3.402-10.905-5.782 4.734 2.597 6.286 4.63 10.344 6.72 1.673.861 3.485 1.493 5.25
+1.937-.463.233-1.59.688-3.688.937-2.886.343-6.834.493-8.468.375-1.547-.111-3.232-.857-3.532-1 .17.12.414.41-.218 1-.913.851-6.244 1.262-9.25 1.375-2.993.113-6.59-.49-11-2.594-4.002-1.908-5.388-3.137-9.47-5.093v.156c3.656 2.204 5.295 4.053 8.907 5.906 1.74.893 3.637 1.528 5.469 1.969-.54.248-1.578.615-3.469.844-2.886.348-6.866.52-8.5.406a9.446 9.446 0 0 1-2.406-.5 12.532 12.532 0 0 1-1.313-.531c.17.112.465.422-.187 1.03-.913.853-6.275 1.294-9.281 1.407-2.993.112-6.594-.528-11-2.594-4.437-2.08-5.647-3.331-10.906-5.656 4.729 2.548 6.29 4.578 10.344 6.625 1.671.844 3.485 1.467 5.25 1.906-.464.235-1.59.684-3.688.938-2.886.348-6.836.57-8.469.469-1.544-.096-3.2-.83-3.5-.97.17.12.382.405-.25 1-.912.861-6.246 1.331-9.25 1.47-2.99.138-6.567-.451-10.969-2.47-3.993-1.83-5.365-3.028-9.437-4.905v.156c3.647 2.133 5.27 3.935 8.875 5.719 1.737.86 3.607 1.45 5.437
+1.875-.54.253-1.55.64-3.437.906-2.88.404-6.838.646-8.469.562a9.36 9.36 0 0 1-2.406-.437 12.971 12.971 0 0 1-1.313-.5c.17.109.432.41-.218 1.031-.911.87-6.25 1.392-9.25 1.563-2.987.17-6.574-.316-10.97-2.282-4.424-1.978-5.605-3.228-10.843-5.375 4.71 2.388 6.27 4.39 10.312 6.344a23.73 23.73 0 0 0 5.218 1.781c-.461.25-1.597.713-3.687 1.032-2.876.438-6.78.733-8.406.687-1.539-.043-3.233-.745-3.532-.875.169.113.411.414-.218 1.031-.908.891-6.203 1.529-9.188 1.813-2.971.283-6.573-.176-10.938-1.938-3.96-1.598-5.329-2.795-9.344-4.312v.156c3.596 1.811 5.239 3.582 8.813 5.156 1.722.759 3.587 1.29 5.406 1.625-.536.28-1.566.688-3.437 1.063-2.856.572-6.79 1.02-8.407 1.031-.844.006-1.706-.08-2.375-.25-.676-.162-1.16-.33-1.28-.375.166.094.422.383-.22 1.062-.897.951-6.186 1.918-9.125 2.438-2.925.518-6.432.374-10.719-1.031-4.315-1.415-5.472-2.53-10.562-3.969 4.577 1.751 6.09 3.56 10.031 5 1.627.594 3.37.956
+5.094 1.156-.453.297-1.555.884-3.594 1.469-2.804.805-6.638 1.576-8.218 1.75-1.495.165-3.117-.317-3.407-.406.164.09.393.36-.218 1.062-.883 1.014-6.045 2.372-8.938 3.063-2.88.687-6.335.76-10.562-.438-3.835-1.086-5.172-2.072-9.062-3.125v.156c3.484 1.395 5.07 2.92 8.53 4.032 1.669.535 3.457.786 5.22.875-.52.352-1.5.914-3.313 1.53-2.765.942-6.59 1.936-8.156 2.157-.818.115-1.633.123-2.281.031-.655-.083-1.133-.218-1.25-.25.162.075.434.34-.188 1.094-.87 1.055-6.01 2.66-8.875 3.438-2.852.774-6.259.958-10.438-.094-4.206-1.06-5.356-2.042-10.344-3.156 4.485 1.46 5.97 3.135 9.813 4.25 1.585.46 3.287.638 4.969.687-.442.337-1.513 1.028-3.5 1.781-2.734 1.037-6.452 2.163-8 2.438-1.465.26-3.06-.117-3.344-.188.16.08.38.321-.219 1.063-.865 1.07-5.916 2.818-8.75 3.687-2.82.866-6.207 1.157-10.344.22-3.753-.852-5.048-1.717-8.875-2.595v.157c3.428 1.237 4.987 2.632 8.375 3.53 1.632.434 3.367.584
+5.094.563-.51.384-1.477 1.022-3.25 1.75-2.706 1.112-6.436 2.308-7.969 2.625-.8.166-1.612.219-2.25.157v1.406c.227-.145.449-.273.719-.375 1.08-.41 2.171-.216 6-1.688 3.828-1.471 5.224-2.005 5.906-2.406.68-.4 1.612-.88 2.219-1.531 1.827-.138 3.57-.493 4.937-1 2.968-1.1 4.876-1.806 6.782-2.469 1.905-.663 2.354-1.415 3.406-1.781 1.091-.38 2.195-.166 6.062-1.531 3.868-1.366 5.283-1.827 5.969-2.22.701-.4 1.7-.932 2.313-1.593 1.97-.055 3.816-.385 5.28-.875 3.002-1.005 4.927-1.622 6.845-2.25 1.538-.504 2.174-1.047 2.906-1.437.23-.135.475-.254.75-.344 1.098-.36 2.181-.082 6.094-1.313 3.912-1.23 5.366-1.673 6.062-2.03.694-.358 1.63-.794 2.25-1.407 1.865-.023 3.636-.267 5.031-.688 3.03-.913 4.993-1.43 6.938-1.968 1.945-.54 2.426-1.265 3.5-1.563 1.114-.31 2.22.007 6.187-1.031 3.968-1.039 5.418-1.433 6.125-1.75.735-.33 1.814-.754 2.438-1.375 1.997.116 3.857-.02 5.344-.375 3.078-.735 5.083-1.101
+7.062-1.5 1.588-.32 2.244-.79 3-1.094.238-.107.467-.193.75-.25 1.134-.23 2.305.209 6.344-.5s5.5-.927 6.219-1.187c.715-.26 1.704-.568 2.343-1.094 1.925.24 3.748.224 5.188 0 3.126-.488 5.155-.7 7.156-.969 2.002-.268 2.489-.945 3.594-1.094 1.146-.154 2.276.302 6.344-.219 4.068-.52 5.56-.695 6.28-.937.738-.247 1.799-.586 2.438-1.125 2.05.335 3.974.398 5.5.219 3.143-.37 5.18-.56 7.188-.782 1.61-.178 2.265-.608 3.031-.843a3.43 3.43 0 0 1 .781-.188c1.15-.128 2.302.347 6.375-.125s5.56-.61 6.282-.844c.719-.232 1.7-.473 2.343-.968 1.937.333 3.77.404 5.22.25 3.145-.335 5.177-.519 7.187-.719 2.01-.2 2.484-.826 3.593-.938 1.152-.115 2.297.366 6.375-.062s5.59-.562 6.313-.781c.74-.224 1.796-.514 2.437-1.031 2.058.398 4.002.493 5.532.343 3.148-.308 5.175-.473 7.187-.656 1.614-.147 2.263-.56 3.031-.781.242-.081.494-.13.782-.156 1.152-.106 2.293.392 6.375 0 4.082-.393 5.589-.531 6.312-.75.721-.219
+1.7-.448 2.344-.938 1.938.35 3.769.454 5.219.313 3.148-.309 5.175-.474 7.187-.657 2.012-.183 2.514-.838 3.625-.937 1.152-.103 2.292.385 6.375 0s5.589-.501 6.313-.719c.739-.222 1.795-.514 2.437-1.031 2.057.402 4.003.503 5.531.344 3.147-.329 5.178-.523 7.188-.72 1.613-.156 2.266-.63 3.031-.874.24-.088.463-.122.75-.156 1.148-.14 2.317.34 6.375-.25 4.058-.59 5.562-.778 6.281-1.032.717-.253 1.675-.558 2.313-1.093 1.92.211 3.72.151 5.156-.094 3.12-.533 5.112-.929 7.094-1.313 1.982-.384 2.474-1.04 3.562-1.28 1.13-.252 2.27.115 6.25-.876s5.43-1.42 6.125-1.781c.723-.376 1.762-.87 2.375-1.531 1.963-.012 3.794-.291 5.22-.844 2.95-1.145 4.872-1.87 6.687-2.75 1.455-.707 2.334-1.686 2.547-1.984.212-.298.111-.746.137-.767.043-.035.32-.085.48-.429.858-1.847 2.32-5.644
+2.435-6.329.113-.682.163-1.348.214-1.745.03-.23-.147-.865-.125-.924.031-.082.305-.265.36-.515.267-1.198.09-2.191-.125-3.609-.214-1.417-.983-4.622-1.637-5.476-.659-.862-1.223-1.011-1.748-1-.208.27.137.262.163.312.68.05.934.369 1.42.897s1.221 3.85 1.358 5.301.19 2.86-.088 3.469c-.278.608-.723.517-1.016.583.531.186.67.125.732.969.058.813-.134 1.64-.52 2.806-.392 1.18-1.846 4.35-2.286 4.598-.452.256-.731.27-1.067.14z" enable-background="new" filter="url(#ff)" opacity=".25"/>
+    <path d="m988.75-263.84c1.912 0.634 4.55 1.758 6.125 2.813 1.575 1.054 2.896 1.482 5.531 3.375 2.609 1.873 5.027 3.015 7.313 4.062 2.47 1.132 5.752 2.155 9.531 3.938-1.207-1.259-7.139-3.365-9.031-4.188s-4.128-1.93-6.938-3.781-3.622-2.482-6-3.719c-2.377-1.237-4.08-1.95-6.53-2.5z" enable-background="new" filter="url(#fe)" opacity=".25"/>
+    <path d="M957.5-260.78c1.91.618 4.583 1.71 6.156 2.75 1.574 1.04 2.896 1.482 5.531 3.375 2.609 1.873 5.027 3.015 7.313 4.063 2.47 1.131 5.752 2.154 9.531 3.937-1.207-1.258-7.201-3.396-9.094-4.219-1.892-.823-4.096-1.93-6.906-3.781-2.81-1.85-3.593-2.44-5.969-3.656s-4.113-1.939-6.562-2.469z" enable-background="new" filter="url(#fd)" opacity=".25"/>
+    <path d="M926.09-257.38c1.908.597 4.553 1.664 6.125 2.688 1.571 1.023 2.87 1.44 5.5 3.28 2.603 1.823 5.029 2.973 7.313 4 2.467 1.111 5.755 2.094 9.53 3.845-1.205-1.249-7.171-3.319-9.062-4.125s-4.102-1.891-6.906-3.688c-2.804-1.796-3.627-2.402-6-3.594-2.373-1.191-4.054-1.903-6.5-2.406z" enable-background="new" filter="url(#fc)" opacity=".25"/>
+    <path d="M894.91-253.56c1.902.554 4.587 1.589 6.156 2.594s2.874 1.408 5.5 3.219c2.6 1.791 5 2.871 7.281 3.875 2.465 1.083 5.76 2.04 9.532 3.75-1.205-1.236-7.175-3.245-9.063-4.032-1.888-.786-4.075-1.83-6.875-3.593s-3.6-2.369-5.969-3.532c-2.37-1.163-4.123-1.834-6.562-2.28z" enable-background="new" filter="url(#fb)" opacity=".25"/>
+    <path d="M863.72-248.66c1.88.43 4.504 1.38 6.063 2.313 1.558.932 2.852 1.257 5.468 3 2.59 1.724 4.981 2.708 7.25 3.625 2.452.99 5.74 1.877 9.5 3.5-1.201-1.208-7.152-3.067-9.03-3.782-1.88-.715-4.086-1.684-6.876-3.375s-3.585-2.228-5.937-3.28-4.026-1.713-6.438-2z" enable-background="new" filter="url(#fa)" opacity=".25"/>
+    <path d="m833.16-241.38c1.848 0.296 4.47 0.976 6 1.781s2.814 1.056 5.375 2.531c2.535 1.46 4.89 2.326 7.125 3.063 2.414 0.797 5.657 1.467 9.375 2.844-1.188-1.129-7.088-2.59-8.938-3.156-1.85-0.567-4.003-1.374-6.75-2.844-2.746-1.47-3.5-1.92-5.812-2.781-2.311-0.861-4.005-1.32-6.375-1.438z" enable-background="new" filter="url(#ez)" opacity=".25"/>
+    <path d="m802.91-232.31c1.822 0.211 4.366 0.8 5.875 1.531 1.51 0.73 2.756 0.93 5.281 2.281 2.5 1.338 4.832 2.049 7.031 2.657 2.377 0.656 5.565 1.073 9.22 2.187-1.168-1.045-6.93-2.103-8.75-2.562-1.822-0.46-3.953-1.127-6.657-2.438s-3.471-1.72-5.75-2.469-3.913-1.179-6.25-1.187z" enable-background="new" filter="url(#ey)" opacity=".25"/>
+    <path d="M773.19-222.19c1.811.179 4.32.665 5.813 1.344 1.491.678 2.753.798 5.25 2.062 2.47 1.252 4.79 1.896 6.968 2.438 2.354.585 5.492.897 9.094 1.844-1.15-.992-6.852-1.784-8.656-2.188s-3.916-1.021-6.594-2.25c-2.678-1.229-3.403-1.61-5.656-2.281-2.253-.67-3.896-1.002-6.219-.969z" enable-background="new" filter="url(#ex)" opacity=".25"/>
+    <path d="M743.56-211.19c1.793.13 4.273.55 5.75 1.188s2.716.741 5.188 1.937c2.446 1.184 4.72 1.747 6.874 2.219 2.328.51 5.42.68 9 1.562-1.143-.97-6.747-1.59-8.53-1.937-1.784-.347-3.884-.888-6.532-2.031-2.648-1.144-3.395-1.517-5.625-2.125-2.23-.61-3.826-.91-6.125-.813z" enable-background="new" filter="url(#ew)" opacity=".25"/>
+   </g>
+  </g>
+  <path d="M3840.7 940.04c1.651-7.722 3.538-13.762 4.889-23.633.803-8.777 3.33-4.873 7.302-20.148 1.41-5.374 5.507.94 9.016-5.757 1.278-1.927 2.901-.97 4.508-.151 3.787 3.165 5.859 8.887 8.381 13.937 6.174 14.326 20.651 19.06 23.62 15.149 1.442-6.97 7.926-12.979 12.444-26.663.752-2.694 11.796-20.982 14.73-15.755" enable-background="new" fill="none" stroke="#000"/>
+  <path d="M3865.4 915.04c7.405-7.758 13.89-21.376 20.826-32.117 3.33-4.726 6.909 7.717 10.857 8.635 2.31-.523 3.734 2.886 5.714 3.939 5.186 3.162 2.412 9.274 10.032 15.452 6.191 4.128 8.958-16.313 14.985-17.573 4.906-1.207 8.145-.758 11.683-.606 3.95.333 4.102-8.393 6.096-12.725 2.997-6.731 7.196-4.438 10.203-11.376 1.023-3.323 1.965-7.224 2.75-12.257.887-4.8 3.057.734 4.825 3.03" enable-background="new" fill="none" stroke="#000"/>
+  <g transform="matrix(1.0057 0 0 2.3995 3249.4 125.01)" clip-path="url(#ev)" filter="url(#eu)">
+   <path d="M910.14 746.31l32.613 5.174-.361-23.876 7.188-29.682-8.45-5.264-21.823 26.511-9.167 27.137z" enable-background="accumulate" fill="#fff" fill-rule="evenodd"/>
+   <path d="M877.52 650.19h123.04v172.53H877.52z" enable-background="accumulate" fill="none"/>
+  </g>
+  <g transform="matrix(1.0057 0 0 2.3995 3249.4 125.01)" clip-path="url(#et)" filter="url(#es)">
+   <path d="M964 754.69l18.429 7.465 9.071-36.964-14.87 4.839L964 754.69z" enable-background="accumulate" fill="#fff" fill-rule="evenodd"/>
+   <path d="M924.9 677.06h142.13v125.16H924.9z" enable-background="accumulate" fill="none"/>
+  </g>
+ </g>
+ <path d="m592.8 398.62l2899.5-102.16" fill="#f8d615" fill-rule="evenodd" marker-end="url(#er)" stroke="#f8d615" stroke-width="17.844"/>
+ <path d="m576.48 779.92l2914.5 416.44" enable-background="new" fill="#f8d615" fill-rule="evenodd" marker-end="url(#eq)" stroke="#f8d615" stroke-width="18"/>
+ <g font-family="sans-serif" letter-spacing="0" word-spacing="0">
+  <text transform="translate(48.571 195.53)" x="80.219" y="107.387" fill="#f83615" font-size="40" style="line-height:125%">
+   <tspan x="80.219" y="107.387" font-size="50">CROP_DEFAULT</tspan>
+  </text>
+  <g font-size="45.314">
+   <text transform="matrix(.96106 0 0 1.0405 48.571 195.53)" x="3861.367" y="1281.72" enable-background="new" fill="#f80000" fill-opacity="0" style="line-height:125%">
+    <tspan x="3861.367" y="1281.72" font-size="56.642">COMPOSE_PADDED</tspan>
+   </text>
+   <text transform="matrix(.96106 0 0 1.0405 48.571 195.53)" x="3615.155" y="49.157" enable-background="new" fill="#f8d615" style="line-height:125%">
+    <tspan x="3615.155" y="49.157" font-size="50">COMPOSE_ACTIVE</tspan>
+   </text>
+   <text transform="matrix(.96106 0 0 1.0405 48.571 195.53)" x="2429.153" y="-3.166" enable-background="new" fill="#f83615" style="line-height:125%">
+    <tspan x="2429.153" y="-3.166" font-size="50">COMPOSE_DEFAULT</tspan>
+   </text>
+   <text transform="matrix(.96106 0 0 1.0405 48.571 195.53)" x="3681.545" y="1289.954" enable-background="new" fill="#f815bb" style="line-height:125%">
+    <tspan x="3681.545" y="1289.954" font-size="50">COMPOSE_PADDED</tspan>
+   </text>
+  </g>
+  <text transform="matrix(.96106 0 0 1.0405 48.571 195.53)" x="2438.062" y="1368.429" enable-background="new" font-size="50" style="line-height:125%">
+   <tspan x="2438.062" y="1368.429">COMPOSE_BOUNDS</tspan>
+  </text>
+  <g font-size="40">
+   <text transform="translate(48.571 195.53)" x="8.082" y="1438.896" enable-background="new" style="line-height:125%">
+    <tspan x="8.082" y="1438.896" font-size="50">CROP_BOUNDS</tspan>
+   </text>
+   <text transform="translate(48.571 195.53)" x="1455.443" y="-26.808" enable-background="new" style="line-height:125%">
+    <tspan x="1455.443" y="-26.808" font-size="50">overscan area</tspan>
+   </text>
+   <text transform="translate(48.571 195.53)" x="179.631" y="385.388" enable-background="new" fill="#f8d615" style="line-height:125%">
+    <tspan x="179.631" y="385.388" font-size="50">CROP_ACTIVE</tspan>
+   </text>
+   <text transform="translate(48.571 195.53)" x="636.674" y="-138.845" enable-background="new" style="line-height:125%">
+    <tspan x="636.674" y="-138.845" font-size="70" font-weight="bold">DATA SOURCE</tspan>
+   </text>
+  </g>
+  <text transform="matrix(.96106 0 0 1.0405 48.571 195.53)" x="3178.715" y="-129.061" enable-background="new" font-size="45.314" style="line-height:125%">
+   <tspan x="3178.715" y="-129.061" font-size="70" font-weight="bold">DATA SINK</tspan>
+  </text>
+ </g>
+</svg>
diff --git a/Documentation/userspace-api/media/v4l/selections-common.rst b/Documentation/userspace-api/media/v4l/selections-common.rst
new file mode 100644
index 000000000000..d5ea05869a61
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/selections-common.rst
@@ -0,0 +1,30 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _v4l2-selections-common:
+
+Common selection definitions
+============================
+
+While the :ref:`V4L2 selection API <selection-api>` and
+:ref:`V4L2 subdev selection APIs <v4l2-subdev-selections>` are very
+similar, there's one fundamental difference between the two. On
+sub-device API, the selection rectangle refers to the media bus format,
+and is bound to a sub-device's pad. On the V4L2 interface the selection
+rectangles refer to the in-memory pixel format.
+
+This section defines the common definitions of the selection interfaces
+on the two APIs.
+
+
+.. toctree::
+    :maxdepth: 1
+
+    v4l2-selection-targets
+    v4l2-selection-flags
diff --git a/Documentation/userspace-api/media/v4l/standard.rst b/Documentation/userspace-api/media/v4l/standard.rst
new file mode 100644
index 000000000000..61c341508eb3
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/standard.rst
@@ -0,0 +1,192 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _standard:
+
+***************
+Video Standards
+***************
+
+Video devices typically support one or more different video standards or
+variations of standards. Each video input and output may support another
+set of standards. This set is reported by the ``std`` field of struct
+:c:type:`v4l2_input` and struct
+:c:type:`v4l2_output` returned by the
+:ref:`VIDIOC_ENUMINPUT` and
+:ref:`VIDIOC_ENUMOUTPUT` ioctls, respectively.
+
+V4L2 defines one bit for each analog video standard currently in use
+worldwide, and sets aside bits for driver defined standards, e. g.
+hybrid standards to watch NTSC video tapes on PAL TVs and vice versa.
+Applications can use the predefined bits to select a particular
+standard, although presenting the user a menu of supported standards is
+preferred. To enumerate and query the attributes of the supported
+standards applications use the :ref:`VIDIOC_ENUMSTD`
+ioctl.
+
+Many of the defined standards are actually just variations of a few
+major standards. The hardware may in fact not distinguish between them,
+or do so internal and switch automatically. Therefore enumerated
+standards also contain sets of one or more standard bits.
+
+Assume a hypothetic tuner capable of demodulating B/PAL, G/PAL and I/PAL
+signals. The first enumerated standard is a set of B and G/PAL, switched
+automatically depending on the selected radio frequency in UHF or VHF
+band. Enumeration gives a "PAL-B/G" or "PAL-I" choice. Similar a
+Composite input may collapse standards, enumerating "PAL-B/G/H/I",
+"NTSC-M" and "SECAM-D/K". [#f1]_
+
+To query and select the standard used by the current video input or
+output applications call the :ref:`VIDIOC_G_STD <VIDIOC_G_STD>` and
+:ref:`VIDIOC_S_STD <VIDIOC_G_STD>` ioctl, respectively. The
+*received* standard can be sensed with the
+:ref:`VIDIOC_QUERYSTD` ioctl.
+
+.. note::
+
+   The parameter of all these ioctls is a pointer to a
+   :ref:`v4l2_std_id <v4l2-std-id>` type (a standard set), *not* an
+   index into the standard enumeration. Drivers must implement all video
+   standard ioctls when the device has one or more video inputs or outputs.
+
+Special rules apply to devices such as USB cameras where the notion of
+video standards makes little sense. More generally for any capture or
+output device which is:
+
+-  incapable of capturing fields or frames at the nominal rate of the
+   video standard, or
+
+-  that does not support the video standard formats at all.
+
+Here the driver shall set the ``std`` field of struct
+:c:type:`v4l2_input` and struct
+:c:type:`v4l2_output` to zero and the :ref:`VIDIOC_G_STD <VIDIOC_G_STD>`,
+:ref:`VIDIOC_S_STD <VIDIOC_G_STD>`, :ref:`VIDIOC_QUERYSTD` and :ref:`VIDIOC_ENUMSTD` ioctls
+shall return the ``ENOTTY`` error code or the ``EINVAL`` error code.
+
+Applications can make use of the :ref:`input-capabilities` and
+:ref:`output-capabilities` flags to determine whether the video
+standard ioctls can be used with the given input or output.
+
+Example: Information about the current video standard
+=====================================================
+
+.. code-block:: c
+
+    v4l2_std_id std_id;
+    struct v4l2_standard standard;
+
+    if (-1 == ioctl(fd, VIDIOC_G_STD, &std_id)) {
+	/* Note when VIDIOC_ENUMSTD always returns ENOTTY this
+	   is no video device or it falls under the USB exception,
+	   and VIDIOC_G_STD returning ENOTTY is no error. */
+
+	perror("VIDIOC_G_STD");
+	exit(EXIT_FAILURE);
+    }
+
+    memset(&standard, 0, sizeof(standard));
+    standard.index = 0;
+
+    while (0 == ioctl(fd, VIDIOC_ENUMSTD, &standard)) {
+	if (standard.id & std_id) {
+	       printf("Current video standard: %s\\n", standard.name);
+	       exit(EXIT_SUCCESS);
+	}
+
+	standard.index++;
+    }
+
+    /* EINVAL indicates the end of the enumeration, which cannot be
+       empty unless this device falls under the USB exception. */
+
+    if (errno == EINVAL || standard.index == 0) {
+	perror("VIDIOC_ENUMSTD");
+	exit(EXIT_FAILURE);
+    }
+
+Example: Listing the video standards supported by the current input
+===================================================================
+
+.. code-block:: c
+
+    struct v4l2_input input;
+    struct v4l2_standard standard;
+
+    memset(&input, 0, sizeof(input));
+
+    if (-1 == ioctl(fd, VIDIOC_G_INPUT, &input.index)) {
+	perror("VIDIOC_G_INPUT");
+	exit(EXIT_FAILURE);
+    }
+
+    if (-1 == ioctl(fd, VIDIOC_ENUMINPUT, &input)) {
+	perror("VIDIOC_ENUM_INPUT");
+	exit(EXIT_FAILURE);
+    }
+
+    printf("Current input %s supports:\\n", input.name);
+
+    memset(&standard, 0, sizeof(standard));
+    standard.index = 0;
+
+    while (0 == ioctl(fd, VIDIOC_ENUMSTD, &standard)) {
+	if (standard.id & input.std)
+	    printf("%s\\n", standard.name);
+
+	standard.index++;
+    }
+
+    /* EINVAL indicates the end of the enumeration, which cannot be
+       empty unless this device falls under the USB exception. */
+
+    if (errno != EINVAL || standard.index == 0) {
+	perror("VIDIOC_ENUMSTD");
+	exit(EXIT_FAILURE);
+    }
+
+Example: Selecting a new video standard
+=======================================
+
+.. code-block:: c
+
+    struct v4l2_input input;
+    v4l2_std_id std_id;
+
+    memset(&input, 0, sizeof(input));
+
+    if (-1 == ioctl(fd, VIDIOC_G_INPUT, &input.index)) {
+	perror("VIDIOC_G_INPUT");
+	exit(EXIT_FAILURE);
+    }
+
+    if (-1 == ioctl(fd, VIDIOC_ENUMINPUT, &input)) {
+	perror("VIDIOC_ENUM_INPUT");
+	exit(EXIT_FAILURE);
+    }
+
+    if (0 == (input.std & V4L2_STD_PAL_BG)) {
+	fprintf(stderr, "Oops. B/G PAL is not supported.\\n");
+	exit(EXIT_FAILURE);
+    }
+
+    /* Note this is also supposed to work when only B
+       or G/PAL is supported. */
+
+    std_id = V4L2_STD_PAL_BG;
+
+    if (-1 == ioctl(fd, VIDIOC_S_STD, &std_id)) {
+	perror("VIDIOC_S_STD");
+	exit(EXIT_FAILURE);
+    }
+
+.. [#f1]
+   Some users are already confused by technical terms PAL, NTSC and
+   SECAM. There is no point asking them to distinguish between B, G, D,
+   or K when the software or hardware can do that automatically.
diff --git a/Documentation/userspace-api/media/v4l/streaming-par.rst b/Documentation/userspace-api/media/v4l/streaming-par.rst
new file mode 100644
index 000000000000..6d1a1b93ac8b
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/streaming-par.rst
@@ -0,0 +1,40 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _streaming-par:
+
+********************
+Streaming Parameters
+********************
+
+Streaming parameters are intended to optimize the video capture process
+as well as I/O. Presently applications can request a high quality
+capture mode with the :ref:`VIDIOC_S_PARM <VIDIOC_G_PARM>` ioctl.
+
+The current video standard determines a nominal number of frames per
+second. If less than this number of frames is to be captured or output,
+applications can request frame skipping or duplicating on the driver
+side. This is especially useful when using the
+:ref:`read() <func-read>` or :ref:`write() <func-write>`, which are
+not augmented by timestamps or sequence counters, and to avoid
+unnecessary data copying.
+
+Finally these ioctls can be used to determine the number of buffers used
+internally by a driver in read/write mode. For implications see the
+section discussing the :ref:`read() <func-read>` function.
+
+To get and set the streaming parameters applications call the
+:ref:`VIDIOC_G_PARM <VIDIOC_G_PARM>` and
+:ref:`VIDIOC_S_PARM <VIDIOC_G_PARM>` ioctl, respectively. They take
+a pointer to a struct :c:type:`v4l2_streamparm`, which
+contains a union holding separate parameters for input and output
+devices.
+
+These ioctls are optional, drivers need not implement them. If so, they
+return the ``EINVAL`` error code.
diff --git a/Documentation/userspace-api/media/v4l/subdev-formats.rst b/Documentation/userspace-api/media/v4l/subdev-formats.rst
new file mode 100644
index 000000000000..9a4d61b0d76f
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/subdev-formats.rst
@@ -0,0 +1,7833 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _v4l2-mbus-format:
+
+Media Bus Formats
+=================
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. c:type:: v4l2_mbus_framefmt
+
+.. flat-table:: struct v4l2_mbus_framefmt
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``width``
+      - Image width in pixels.
+    * - __u32
+      - ``height``
+      - Image height in pixels. If ``field`` is one of ``V4L2_FIELD_TOP``,
+	``V4L2_FIELD_BOTTOM`` or ``V4L2_FIELD_ALTERNATE`` then height
+	refers to the number of lines in the field, otherwise it refers to
+	the number of lines in the frame (which is twice the field height
+	for interlaced formats).
+    * - __u32
+      - ``code``
+      - Format code, from enum
+	:ref:`v4l2_mbus_pixelcode <v4l2-mbus-pixelcode>`.
+    * - __u32
+      - ``field``
+      - Field order, from enum :c:type:`v4l2_field`. See
+	:ref:`field-order` for details.
+    * - __u32
+      - ``colorspace``
+      - Image colorspace, from enum
+	:c:type:`v4l2_colorspace`. See
+	:ref:`colorspaces` for details.
+    * - __u16
+      - ``ycbcr_enc``
+      - Y'CbCr encoding, from enum :c:type:`v4l2_ycbcr_encoding`.
+        This information supplements the ``colorspace`` and must be set by
+	the driver for capture streams and by the application for output
+	streams, see :ref:`colorspaces`.
+    * - __u16
+      - ``quantization``
+      - Quantization range, from enum :c:type:`v4l2_quantization`.
+        This information supplements the ``colorspace`` and must be set by
+	the driver for capture streams and by the application for output
+	streams, see :ref:`colorspaces`.
+    * - __u16
+      - ``xfer_func``
+      - Transfer function, from enum :c:type:`v4l2_xfer_func`.
+        This information supplements the ``colorspace`` and must be set by
+	the driver for capture streams and by the application for output
+	streams, see :ref:`colorspaces`.
+    * - __u16
+      - ``reserved``\ [11]
+      - Reserved for future extensions. Applications and drivers must set
+	the array to zero.
+
+
+
+.. _v4l2-mbus-pixelcode:
+
+Media Bus Pixel Codes
+---------------------
+
+The media bus pixel codes describe image formats as flowing over
+physical buses (both between separate physical components and inside
+SoC devices). This should not be confused with the V4L2 pixel formats
+that describe, using four character codes, image formats as stored in
+memory.
+
+While there is a relationship between image formats on buses and image
+formats in memory (a raw Bayer image won't be magically converted to
+JPEG just by storing it to memory), there is no one-to-one
+correspondence between them.
+
+The media bus pixel codes document parallel formats. Should the pixel data be
+transported over a serial bus, the media bus pixel code that describes a
+parallel format that transfers a sample on a single clock cycle is used. For
+instance, both MEDIA_BUS_FMT_BGR888_1X24 and MEDIA_BUS_FMT_BGR888_3X8 are used
+on parallel busses for transferring an 8 bits per sample BGR data, whereas on
+serial busses the data in this format is only referred to using
+MEDIA_BUS_FMT_BGR888_1X24. This is because there is effectively only a single
+way to transport that format on the serial busses.
+
+Packed RGB Formats
+^^^^^^^^^^^^^^^^^^
+
+Those formats transfer pixel data as red, green and blue components. The
+format code is made of the following information.
+
+-  The red, green and blue components order code, as encoded in a pixel
+   sample. Possible values are RGB and BGR.
+
+-  The number of bits per component, for each component. The values can
+   be different for all components. Common values are 555 and 565.
+
+-  The number of bus samples per pixel. Pixels that are wider than the
+   bus width must be transferred in multiple samples. Common values are
+   1 and 2.
+
+-  The bus width.
+
+-  For formats where the total number of bits per pixel is smaller than
+   the number of bus samples per pixel times the bus width, a padding
+   value stating if the bytes are padded in their most high order bits
+   (PADHI) or low order bits (PADLO). A "C" prefix is used for
+   component-wise padding in the most high order bits (CPADHI) or low
+   order bits (CPADLO) of each separate component.
+
+-  For formats where the number of bus samples per pixel is larger than
+   1, an endianness value stating if the pixel is transferred MSB first
+   (BE) or LSB first (LE).
+
+For instance, a format where pixels are encoded as 5-bits red, 5-bits
+green and 5-bit blue values padded on the high bit, transferred as 2
+8-bit samples per pixel with the most significant bits (padding, red and
+half of the green value) transferred first will be named
+``MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE``.
+
+The following tables list existing packed RGB formats.
+
+.. HACK: ideally, we would be using adjustbox here. However, Sphinx
+.. is a very bad behaviored guy: if the table has more than 30 cols,
+.. it switches to long table, and there's no way to override it.
+
+
+.. tabularcolumns:: |p{4.0cm}|p{0.7cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|
+
+.. _v4l2-mbus-pixelcode-rgb:
+
+.. raw:: latex
+
+    \begingroup
+    \tiny
+    \setlength{\tabcolsep}{2pt}
+
+.. flat-table:: RGB formats
+    :header-rows:  2
+    :stub-columns: 0
+    :widths: 36 7 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
+
+    * - Identifier
+      - Code
+      -
+      - :cspan:`31` Data organization
+    * -
+      -
+      - Bit
+      - 31
+      - 30
+      - 29
+      - 28
+      - 27
+      - 26
+      - 25
+      - 24
+      - 23
+      - 22
+      - 21
+      - 20
+      - 19
+      - 18
+      - 17
+      - 16
+      - 15
+      - 14
+      - 13
+      - 12
+      - 11
+      - 10
+      - 9
+      - 8
+      - 7
+      - 6
+      - 5
+      - 4
+      - 3
+      - 2
+      - 1
+      - 0
+    * .. _MEDIA-BUS-FMT-RGB444-1X12:
+
+      - MEDIA_BUS_FMT_RGB444_1X12
+      - 0x1016
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-RGB444-2X8-PADHI-BE:
+
+      - MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE
+      - 0x1001
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - 0
+      - 0
+      - 0
+      - 0
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-RGB444-2X8-PADHI-LE:
+
+      - MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE
+      - 0x1002
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - 0
+      - 0
+      - 0
+      - 0
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-RGB555-2X8-PADHI-BE:
+
+      - MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE
+      - 0x1003
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - 0
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-RGB555-2X8-PADHI-LE:
+
+      - MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE
+      - 0x1004
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - 0
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+    * .. _MEDIA-BUS-FMT-RGB565-1X16:
+
+      - MEDIA_BUS_FMT_RGB565_1X16
+      - 0x1017
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-BGR565-2X8-BE:
+
+      - MEDIA_BUS_FMT_BGR565_2X8_BE
+      - 0x1005
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-BGR565-2X8-LE:
+
+      - MEDIA_BUS_FMT_BGR565_2X8_LE
+      - 0x1006
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+    * .. _MEDIA-BUS-FMT-RGB565-2X8-BE:
+
+      - MEDIA_BUS_FMT_RGB565_2X8_BE
+      - 0x1007
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-RGB565-2X8-LE:
+
+      - MEDIA_BUS_FMT_RGB565_2X8_LE
+      - 0x1008
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+    * .. _MEDIA-BUS-FMT-RGB666-1X18:
+
+      - MEDIA_BUS_FMT_RGB666_1X18
+      - 0x1009
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-RBG888-1X24:
+
+      - MEDIA_BUS_FMT_RBG888_1X24
+      - 0x100e
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-RGB666-1X24_CPADHI:
+
+      - MEDIA_BUS_FMT_RGB666_1X24_CPADHI
+      - 0x1015
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - 0
+      - 0
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - 0
+      - 0
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - 0
+      - 0
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-BGR888-1X24:
+
+      - MEDIA_BUS_FMT_BGR888_1X24
+      - 0x1013
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-BGR888-3X8:
+
+      - MEDIA_BUS_FMT_BGR888_3X8
+      - 0x101b
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-GBR888-1X24:
+
+      - MEDIA_BUS_FMT_GBR888_1X24
+      - 0x1014
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-RGB888-1X24:
+
+      - MEDIA_BUS_FMT_RGB888_1X24
+      - 0x100a
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-RGB888-2X12-BE:
+
+      - MEDIA_BUS_FMT_RGB888_2X12_BE
+      - 0x100b
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-RGB888-2X12-LE:
+
+      - MEDIA_BUS_FMT_RGB888_2X12_LE
+      - 0x100c
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+    * .. _MEDIA-BUS-FMT-RGB888-3X8:
+
+      - MEDIA_BUS_FMT_RGB888_3X8
+      - 0x101c
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-ARGB888-1X32:
+
+      - MEDIA_BUS_FMT_ARGB888_1X32
+      - 0x100d
+      -
+      - a\ :sub:`7`
+      - a\ :sub:`6`
+      - a\ :sub:`5`
+      - a\ :sub:`4`
+      - a\ :sub:`3`
+      - a\ :sub:`2`
+      - a\ :sub:`1`
+      - a\ :sub:`0`
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-RGB888-1X32-PADHI:
+
+      - MEDIA_BUS_FMT_RGB888_1X32_PADHI
+      - 0x100f
+      -
+      - 0
+      - 0
+      - 0
+      - 0
+      - 0
+      - 0
+      - 0
+      - 0
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-RGB101010-1X30:
+
+      - MEDIA_BUS_FMT_RGB101010_1X30
+      - 0x1018
+      -
+      - 0
+      - 0
+      - r\ :sub:`9`
+      - r\ :sub:`8`
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`9`
+      - g\ :sub:`8`
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`9`
+      - b\ :sub:`8`
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+
+.. raw:: latex
+
+    \endgroup
+
+
+The following table list existing packed 36bit wide RGB formats.
+
+.. tabularcolumns:: |p{4.0cm}|p{0.7cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|
+
+.. _v4l2-mbus-pixelcode-rgb-36:
+
+.. raw:: latex
+
+    \begingroup
+    \tiny
+    \setlength{\tabcolsep}{2pt}
+
+.. flat-table:: 36bit RGB formats
+    :header-rows:  2
+    :stub-columns: 0
+    :widths: 36 7 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
+
+    * - Identifier
+      - Code
+      -
+      - :cspan:`35` Data organization
+    * -
+      -
+      - Bit
+      - 35
+      - 34
+      - 33
+      - 32
+      - 31
+      - 30
+      - 29
+      - 28
+      - 27
+      - 26
+      - 25
+      - 24
+      - 23
+      - 22
+      - 21
+      - 20
+      - 19
+      - 18
+      - 17
+      - 16
+      - 15
+      - 14
+      - 13
+      - 12
+      - 11
+      - 10
+      - 9
+      - 8
+      - 7
+      - 6
+      - 5
+      - 4
+      - 3
+      - 2
+      - 1
+      - 0
+    * .. _MEDIA-BUS-FMT-RGB121212-1X36:
+
+      - MEDIA_BUS_FMT_RGB121212_1X36
+      - 0x1019
+      -
+      - r\ :sub:`11`
+      - r\ :sub:`10`
+      - r\ :sub:`9`
+      - r\ :sub:`8`
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`11`
+      - g\ :sub:`10`
+      - g\ :sub:`9`
+      - g\ :sub:`8`
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`11`
+      - b\ :sub:`10`
+      - b\ :sub:`9`
+      - b\ :sub:`8`
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+
+.. raw:: latex
+
+    \endgroup
+
+
+The following table list existing packed 48bit wide RGB formats.
+
+.. tabularcolumns:: |p{4.0cm}|p{0.7cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|
+
+.. _v4l2-mbus-pixelcode-rgb-48:
+
+.. raw:: latex
+
+    \begingroup
+    \tiny
+    \setlength{\tabcolsep}{2pt}
+
+.. flat-table:: 48bit RGB formats
+    :header-rows:  3
+    :stub-columns: 0
+    :widths: 36 7 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
+
+    * - Identifier
+      - Code
+      -
+      - :cspan:`31` Data organization
+    * -
+      -
+      - Bit
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - 47
+      - 46
+      - 45
+      - 44
+      - 43
+      - 42
+      - 41
+      - 40
+      - 39
+      - 38
+      - 37
+      - 36
+      - 35
+      - 34
+      - 33
+      - 32
+    * -
+      -
+      -
+      - 31
+      - 30
+      - 29
+      - 28
+      - 27
+      - 26
+      - 25
+      - 24
+      - 23
+      - 22
+      - 21
+      - 20
+      - 19
+      - 18
+      - 17
+      - 16
+      - 15
+      - 14
+      - 13
+      - 12
+      - 11
+      - 10
+      - 9
+      - 8
+      - 7
+      - 6
+      - 5
+      - 4
+      - 3
+      - 2
+      - 1
+      - 0
+    * .. _MEDIA-BUS-FMT-RGB161616-1X48:
+
+      - MEDIA_BUS_FMT_RGB161616_1X48
+      - 0x101a
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - r\ :sub:`15`
+      - r\ :sub:`14`
+      - r\ :sub:`13`
+      - r\ :sub:`12`
+      - r\ :sub:`11`
+      - r\ :sub:`10`
+      - r\ :sub:`9`
+      - r\ :sub:`8`
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+    * -
+      -
+      -
+      - g\ :sub:`15`
+      - g\ :sub:`14`
+      - g\ :sub:`13`
+      - g\ :sub:`12`
+      - g\ :sub:`11`
+      - g\ :sub:`10`
+      - g\ :sub:`9`
+      - g\ :sub:`8`
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`15`
+      - b\ :sub:`14`
+      - b\ :sub:`13`
+      - b\ :sub:`12`
+      - b\ :sub:`11`
+      - b\ :sub:`10`
+      - b\ :sub:`9`
+      - b\ :sub:`8`
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+
+.. raw:: latex
+
+    \endgroup
+
+On LVDS buses, usually each sample is transferred serialized in seven
+time slots per pixel clock, on three (18-bit) or four (24-bit)
+differential data pairs at the same time. The remaining bits are used
+for control signals as defined by SPWG/PSWG/VESA or JEIDA standards. The
+24-bit RGB format serialized in seven time slots on four lanes using
+JEIDA defined bit mapping will be named
+``MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA``, for example.
+
+.. raw:: latex
+
+    \tiny
+
+.. _v4l2-mbus-pixelcode-rgb-lvds:
+
+.. flat-table:: LVDS RGB formats
+    :header-rows:  2
+    :stub-columns: 0
+
+    * - Identifier
+      - Code
+      -
+      -
+      - :cspan:`3` Data organization
+    * -
+      -
+      - Timeslot
+      - Lane
+      - 3
+      - 2
+      - 1
+      - 0
+    * .. _MEDIA-BUS-FMT-RGB666-1X7X3-SPWG:
+
+      - MEDIA_BUS_FMT_RGB666_1X7X3_SPWG
+      - 0x1010
+      - 0
+      -
+      -
+      - d
+      - b\ :sub:`1`
+      - g\ :sub:`0`
+    * -
+      -
+      - 1
+      -
+      -
+      - d
+      - b\ :sub:`0`
+      - r\ :sub:`5`
+    * -
+      -
+      - 2
+      -
+      -
+      - d
+      - g\ :sub:`5`
+      - r\ :sub:`4`
+    * -
+      -
+      - 3
+      -
+      -
+      - b\ :sub:`5`
+      - g\ :sub:`4`
+      - r\ :sub:`3`
+    * -
+      -
+      - 4
+      -
+      -
+      - b\ :sub:`4`
+      - g\ :sub:`3`
+      - r\ :sub:`2`
+    * -
+      -
+      - 5
+      -
+      -
+      - b\ :sub:`3`
+      - g\ :sub:`2`
+      - r\ :sub:`1`
+    * -
+      -
+      - 6
+      -
+      -
+      - b\ :sub:`2`
+      - g\ :sub:`1`
+      - r\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-RGB888-1X7X4-SPWG:
+
+      - MEDIA_BUS_FMT_RGB888_1X7X4_SPWG
+      - 0x1011
+      - 0
+      -
+      - d
+      - d
+      - b\ :sub:`1`
+      - g\ :sub:`0`
+    * -
+      -
+      - 1
+      -
+      - b\ :sub:`7`
+      - d
+      - b\ :sub:`0`
+      - r\ :sub:`5`
+    * -
+      -
+      - 2
+      -
+      - b\ :sub:`6`
+      - d
+      - g\ :sub:`5`
+      - r\ :sub:`4`
+    * -
+      -
+      - 3
+      -
+      - g\ :sub:`7`
+      - b\ :sub:`5`
+      - g\ :sub:`4`
+      - r\ :sub:`3`
+    * -
+      -
+      - 4
+      -
+      - g\ :sub:`6`
+      - b\ :sub:`4`
+      - g\ :sub:`3`
+      - r\ :sub:`2`
+    * -
+      -
+      - 5
+      -
+      - r\ :sub:`7`
+      - b\ :sub:`3`
+      - g\ :sub:`2`
+      - r\ :sub:`1`
+    * -
+      -
+      - 6
+      -
+      - r\ :sub:`6`
+      - b\ :sub:`2`
+      - g\ :sub:`1`
+      - r\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-RGB888-1X7X4-JEIDA:
+
+      - MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA
+      - 0x1012
+      - 0
+      -
+      - d
+      - d
+      - b\ :sub:`3`
+      - g\ :sub:`2`
+    * -
+      -
+      - 1
+      -
+      - b\ :sub:`1`
+      - d
+      - b\ :sub:`2`
+      - r\ :sub:`7`
+    * -
+      -
+      - 2
+      -
+      - b\ :sub:`0`
+      - d
+      - g\ :sub:`7`
+      - r\ :sub:`6`
+    * -
+      -
+      - 3
+      -
+      - g\ :sub:`1`
+      - b\ :sub:`7`
+      - g\ :sub:`6`
+      - r\ :sub:`5`
+    * -
+      -
+      - 4
+      -
+      - g\ :sub:`0`
+      - b\ :sub:`6`
+      - g\ :sub:`5`
+      - r\ :sub:`4`
+    * -
+      -
+      - 5
+      -
+      - r\ :sub:`1`
+      - b\ :sub:`5`
+      - g\ :sub:`4`
+      - r\ :sub:`3`
+    * -
+      -
+      - 6
+      -
+      - r\ :sub:`0`
+      - b\ :sub:`4`
+      - g\ :sub:`3`
+      - r\ :sub:`2`
+
+.. raw:: latex
+
+    \normalsize
+
+
+Bayer Formats
+^^^^^^^^^^^^^
+
+Those formats transfer pixel data as red, green and blue components. The
+format code is made of the following information.
+
+-  The red, green and blue components order code, as encoded in a pixel
+   sample. The possible values are shown in :ref:`bayer-patterns`.
+
+-  The number of bits per pixel component. All components are
+   transferred on the same number of bits. Common values are 8, 10 and
+   12.
+
+-  The compression (optional). If the pixel components are ALAW- or
+   DPCM-compressed, a mention of the compression scheme and the number
+   of bits per compressed pixel component.
+
+-  The number of bus samples per pixel. Pixels that are wider than the
+   bus width must be transferred in multiple samples. Common values are
+   1 and 2.
+
+-  The bus width.
+
+-  For formats where the total number of bits per pixel is smaller than
+   the number of bus samples per pixel times the bus width, a padding
+   value stating if the bytes are padded in their most high order bits
+   (PADHI) or low order bits (PADLO).
+
+-  For formats where the number of bus samples per pixel is larger than
+   1, an endianness value stating if the pixel is transferred MSB first
+   (BE) or LSB first (LE).
+
+For instance, a format with uncompressed 10-bit Bayer components
+arranged in a red, green, green, blue pattern transferred as 2 8-bit
+samples per pixel with the least significant bits transferred first will
+be named ``MEDIA_BUS_FMT_SRGGB10_2X8_PADHI_LE``.
+
+
+.. _bayer-patterns:
+
+.. kernel-figure:: bayer.svg
+    :alt:    bayer.svg
+    :align:  center
+
+    **Figure 4.8 Bayer Patterns**
+
+The following table lists existing packed Bayer formats. The data
+organization is given as an example for the first pixel only.
+
+
+.. HACK: ideally, we would be using adjustbox here. However, Sphinx
+.. is a very bad behaviored guy: if the table has more than 30 cols,
+.. it switches to long table, and there's no way to override it.
+
+
+.. raw:: latex
+
+    \begingroup
+    \tiny
+    \setlength{\tabcolsep}{2pt}
+
+.. tabularcolumns:: |p{4.0cm}|p{0.7cm}|p{0.3cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|
+
+.. _v4l2-mbus-pixelcode-bayer:
+
+.. cssclass: longtable
+
+.. flat-table:: Bayer Formats
+    :header-rows:  2
+    :stub-columns: 0
+
+    * - Identifier
+      - Code
+      -
+      - :cspan:`15` Data organization
+    * -
+      -
+      - Bit
+      - 15
+      - 14
+      - 13
+      - 12
+      - 11
+      - 10
+      - 9
+      - 8
+      - 7
+      - 6
+      - 5
+      - 4
+      - 3
+      - 2
+      - 1
+      - 0
+    * .. _MEDIA-BUS-FMT-SBGGR8-1X8:
+
+      - MEDIA_BUS_FMT_SBGGR8_1X8
+      - 0x3001
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-SGBRG8-1X8:
+
+      - MEDIA_BUS_FMT_SGBRG8_1X8
+      - 0x3013
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-SGRBG8-1X8:
+
+      - MEDIA_BUS_FMT_SGRBG8_1X8
+      - 0x3002
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-SRGGB8-1X8:
+
+      - MEDIA_BUS_FMT_SRGGB8_1X8
+      - 0x3014
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-SBGGR10-ALAW8-1X8:
+
+      - MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8
+      - 0x3015
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-SGBRG10-ALAW8-1X8:
+
+      - MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8
+      - 0x3016
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-SGRBG10-ALAW8-1X8:
+
+      - MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8
+      - 0x3017
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-SRGGB10-ALAW8-1X8:
+
+      - MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8
+      - 0x3018
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-SBGGR10-DPCM8-1X8:
+
+      - MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8
+      - 0x300b
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-SGBRG10-DPCM8-1X8:
+
+      - MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8
+      - 0x300c
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-SGRBG10-DPCM8-1X8:
+
+      - MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8
+      - 0x3009
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-SRGGB10-DPCM8-1X8:
+
+      - MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8
+      - 0x300d
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-SBGGR10-2X8-PADHI-BE:
+
+      - MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE
+      - 0x3003
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - 0
+      - 0
+      - 0
+      - 0
+      - 0
+      - 0
+      - b\ :sub:`9`
+      - b\ :sub:`8`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-SBGGR10-2X8-PADHI-LE:
+
+      - MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE
+      - 0x3004
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - 0
+      - 0
+      - 0
+      - 0
+      - 0
+      - 0
+      - b\ :sub:`9`
+      - b\ :sub:`8`
+    * .. _MEDIA-BUS-FMT-SBGGR10-2X8-PADLO-BE:
+
+      - MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE
+      - 0x3005
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - b\ :sub:`9`
+      - b\ :sub:`8`
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      - 0
+      - 0
+      - 0
+      - 0
+      - 0
+      - 0
+    * .. _MEDIA-BUS-FMT-SBGGR10-2X8-PADLO-LE:
+
+      - MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE
+      - 0x3006
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      - 0
+      - 0
+      - 0
+      - 0
+      - 0
+      - 0
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - b\ :sub:`9`
+      - b\ :sub:`8`
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+    * .. _MEDIA-BUS-FMT-SBGGR10-1X10:
+
+      - MEDIA_BUS_FMT_SBGGR10_1X10
+      - 0x3007
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - b\ :sub:`9`
+      - b\ :sub:`8`
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-SGBRG10-1X10:
+
+      - MEDIA_BUS_FMT_SGBRG10_1X10
+      - 0x300e
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - g\ :sub:`9`
+      - g\ :sub:`8`
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-SGRBG10-1X10:
+
+      - MEDIA_BUS_FMT_SGRBG10_1X10
+      - 0x300a
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - g\ :sub:`9`
+      - g\ :sub:`8`
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-SRGGB10-1X10:
+
+      - MEDIA_BUS_FMT_SRGGB10_1X10
+      - 0x300f
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - r\ :sub:`9`
+      - r\ :sub:`8`
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-SBGGR12-1X12:
+
+      - MEDIA_BUS_FMT_SBGGR12_1X12
+      - 0x3008
+      -
+      -
+      -
+      -
+      -
+      - b\ :sub:`11`
+      - b\ :sub:`10`
+      - b\ :sub:`9`
+      - b\ :sub:`8`
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-SGBRG12-1X12:
+
+      - MEDIA_BUS_FMT_SGBRG12_1X12
+      - 0x3010
+      -
+      -
+      -
+      -
+      -
+      - g\ :sub:`11`
+      - g\ :sub:`10`
+      - g\ :sub:`9`
+      - g\ :sub:`8`
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-SGRBG12-1X12:
+
+      - MEDIA_BUS_FMT_SGRBG12_1X12
+      - 0x3011
+      -
+      -
+      -
+      -
+      -
+      - g\ :sub:`11`
+      - g\ :sub:`10`
+      - g\ :sub:`9`
+      - g\ :sub:`8`
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-SRGGB12-1X12:
+
+      - MEDIA_BUS_FMT_SRGGB12_1X12
+      - 0x3012
+      -
+      -
+      -
+      -
+      -
+      - r\ :sub:`11`
+      - r\ :sub:`10`
+      - r\ :sub:`9`
+      - r\ :sub:`8`
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-SBGGR14-1X14:
+
+      - MEDIA_BUS_FMT_SBGGR14_1X14
+      - 0x3019
+      -
+      -
+      -
+      - b\ :sub:`13`
+      - b\ :sub:`12`
+      - b\ :sub:`11`
+      - b\ :sub:`10`
+      - b\ :sub:`9`
+      - b\ :sub:`8`
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-SGBRG14-1X14:
+
+      - MEDIA_BUS_FMT_SGBRG14_1X14
+      - 0x301a
+      -
+      -
+      -
+      - g\ :sub:`13`
+      - g\ :sub:`12`
+      - g\ :sub:`11`
+      - g\ :sub:`10`
+      - g\ :sub:`9`
+      - g\ :sub:`8`
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-SGRBG14-1X14:
+
+      - MEDIA_BUS_FMT_SGRBG14_1X14
+      - 0x301b
+      -
+      -
+      -
+      - g\ :sub:`13`
+      - g\ :sub:`12`
+      - g\ :sub:`11`
+      - g\ :sub:`10`
+      - g\ :sub:`9`
+      - g\ :sub:`8`
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-SRGGB14-1X14:
+
+      - MEDIA_BUS_FMT_SRGGB14_1X14
+      - 0x301c
+      -
+      -
+      -
+      - r\ :sub:`13`
+      - r\ :sub:`12`
+      - r\ :sub:`11`
+      - r\ :sub:`10`
+      - r\ :sub:`9`
+      - r\ :sub:`8`
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-SBGGR16-1X16:
+
+      - MEDIA_BUS_FMT_SBGGR16_1X16
+      - 0x301d
+      -
+      - b\ :sub:`15`
+      - b\ :sub:`14`
+      - b\ :sub:`13`
+      - b\ :sub:`12`
+      - b\ :sub:`11`
+      - b\ :sub:`10`
+      - b\ :sub:`9`
+      - b\ :sub:`8`
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-SGBRG16-1X16:
+
+      - MEDIA_BUS_FMT_SGBRG16_1X16
+      - 0x301e
+      -
+      - g\ :sub:`15`
+      - g\ :sub:`14`
+      - g\ :sub:`13`
+      - g\ :sub:`12`
+      - g\ :sub:`11`
+      - g\ :sub:`10`
+      - g\ :sub:`9`
+      - g\ :sub:`8`
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-SGRBG16-1X16:
+
+      - MEDIA_BUS_FMT_SGRBG16_1X16
+      - 0x301f
+      -
+      - g\ :sub:`15`
+      - g\ :sub:`14`
+      - g\ :sub:`13`
+      - g\ :sub:`12`
+      - g\ :sub:`11`
+      - g\ :sub:`10`
+      - g\ :sub:`9`
+      - g\ :sub:`8`
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-SRGGB16-1X16:
+
+      - MEDIA_BUS_FMT_SRGGB16_1X16
+      - 0x3020
+      -
+      - r\ :sub:`15`
+      - r\ :sub:`14`
+      - r\ :sub:`13`
+      - r\ :sub:`12`
+      - r\ :sub:`11`
+      - r\ :sub:`10`
+      - r\ :sub:`9`
+      - r\ :sub:`8`
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+
+.. raw:: latex
+
+    \endgroup
+
+
+Packed YUV Formats
+^^^^^^^^^^^^^^^^^^
+
+Those data formats transfer pixel data as (possibly downsampled) Y, U
+and V components. Some formats include dummy bits in some of their
+samples and are collectively referred to as "YDYC" (Y-Dummy-Y-Chroma)
+formats. One cannot rely on the values of these dummy bits as those are
+undefined.
+
+The format code is made of the following information.
+
+-  The Y, U and V components order code, as transferred on the bus.
+   Possible values are YUYV, UYVY, YVYU and VYUY for formats with no
+   dummy bit, and YDYUYDYV, YDYVYDYU, YUYDYVYD and YVYDYUYD for YDYC
+   formats.
+
+-  The number of bits per pixel component. All components are
+   transferred on the same number of bits. Common values are 8, 10 and
+   12.
+
+-  The number of bus samples per pixel. Pixels that are wider than the
+   bus width must be transferred in multiple samples. Common values are
+   0.5 (encoded as 0_5; in this case two pixels are transferred per bus
+   sample), 1, 1.5 (encoded as 1_5) and 2.
+
+-  The bus width. When the bus width is larger than the number of bits
+   per pixel component, several components are packed in a single bus
+   sample. The components are ordered as specified by the order code,
+   with components on the left of the code transferred in the high order
+   bits. Common values are 8 and 16.
+
+For instance, a format where pixels are encoded as 8-bit YUV values
+downsampled to 4:2:2 and transferred as 2 8-bit bus samples per pixel in
+the U, Y, V, Y order will be named ``MEDIA_BUS_FMT_UYVY8_2X8``.
+
+:ref:`v4l2-mbus-pixelcode-yuv8` lists existing packed YUV formats and
+describes the organization of each pixel data in each sample. When a
+format pattern is split across multiple samples each of the samples in
+the pattern is described.
+
+The role of each bit transferred over the bus is identified by one of
+the following codes.
+
+-  y\ :sub:`x` for luma component bit number x
+
+-  u\ :sub:`x` for blue chroma component bit number x
+
+-  v\ :sub:`x` for red chroma component bit number x
+
+-  a\ :sub:`x` for alpha component bit number x
+
+- for non-available bits (for positions higher than the bus width)
+
+-  d for dummy bits
+
+.. HACK: ideally, we would be using adjustbox here. However, this
+.. will never work for this table, as, even with tiny font, it is
+.. to big for a single page. So, we need to manually adjust the
+.. size.
+
+.. raw:: latex
+
+    \begingroup
+    \tiny
+    \setlength{\tabcolsep}{2pt}
+
+.. tabularcolumns:: |p{4.0cm}|p{0.7cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|
+
+.. _v4l2-mbus-pixelcode-yuv8:
+
+.. flat-table:: YUV Formats
+    :header-rows:  2
+    :stub-columns: 0
+    :widths: 36 7 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
+
+    * - Identifier
+      - Code
+      -
+      - :cspan:`31` Data organization
+    * -
+      -
+      - Bit
+      - 31
+      - 30
+      - 29
+      - 28
+      - 27
+      - 26
+      - 25
+      - 24
+      - 23
+      - 22
+      - 21
+      - 10
+      - 19
+      - 18
+      - 17
+      - 16
+      - 15
+      - 14
+      - 13
+      - 12
+      - 11
+      - 10
+      - 9
+      - 8
+      - 7
+      - 6
+      - 5
+      - 4
+      - 3
+      - 2
+      - 1
+      - 0
+    * .. _MEDIA-BUS-FMT-Y8-1X8:
+
+      - MEDIA_BUS_FMT_Y8_1X8
+      - 0x2001
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-UV8-1X8:
+
+      - MEDIA_BUS_FMT_UV8_1X8
+      - 0x2015
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-UYVY8-1_5X8:
+
+      - MEDIA_BUS_FMT_UYVY8_1_5X8
+      - 0x2002
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-VYUY8-1_5X8:
+
+      - MEDIA_BUS_FMT_VYUY8_1_5X8
+      - 0x2003
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-YUYV8-1_5X8:
+
+      - MEDIA_BUS_FMT_YUYV8_1_5X8
+      - 0x2004
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-YVYU8-1_5X8:
+
+      - MEDIA_BUS_FMT_YVYU8_1_5X8
+      - 0x2005
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-UYVY8-2X8:
+
+      - MEDIA_BUS_FMT_UYVY8_2X8
+      - 0x2006
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-VYUY8-2X8:
+
+      - MEDIA_BUS_FMT_VYUY8_2X8
+      - 0x2007
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-YUYV8-2X8:
+
+      - MEDIA_BUS_FMT_YUYV8_2X8
+      - 0x2008
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-YVYU8-2X8:
+
+      - MEDIA_BUS_FMT_YVYU8_2X8
+      - 0x2009
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-Y10-1X10:
+
+      - MEDIA_BUS_FMT_Y10_1X10
+      - 0x200a
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-Y10-2X8-PADHI_LE:
+
+      - MEDIA_BUS_FMT_Y10_2X8_PADHI_LE
+      - 0x202c
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - 0
+      - 0
+      - 0
+      - 0
+      - 0
+      - 0
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+    * .. _MEDIA-BUS-FMT-UYVY10-2X10:
+
+      - MEDIA_BUS_FMT_UYVY10_2X10
+      - 0x2018
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - u\ :sub:`9`
+      - u\ :sub:`8`
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - v\ :sub:`9`
+      - v\ :sub:`8`
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-VYUY10-2X10:
+
+      - MEDIA_BUS_FMT_VYUY10_2X10
+      - 0x2019
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - v\ :sub:`9`
+      - v\ :sub:`8`
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - u\ :sub:`9`
+      - u\ :sub:`8`
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-YUYV10-2X10:
+
+      - MEDIA_BUS_FMT_YUYV10_2X10
+      - 0x200b
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - u\ :sub:`9`
+      - u\ :sub:`8`
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - v\ :sub:`9`
+      - v\ :sub:`8`
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-YVYU10-2X10:
+
+      - MEDIA_BUS_FMT_YVYU10_2X10
+      - 0x200c
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - v\ :sub:`9`
+      - v\ :sub:`8`
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - u\ :sub:`9`
+      - u\ :sub:`8`
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-Y12-1X12:
+
+      - MEDIA_BUS_FMT_Y12_1X12
+      - 0x2013
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`11`
+      - y\ :sub:`10`
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-UYVY12-2X12:
+
+      - MEDIA_BUS_FMT_UYVY12_2X12
+      - 0x201c
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - u\ :sub:`11`
+      - u\ :sub:`10`
+      - u\ :sub:`9`
+      - u\ :sub:`8`
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`11`
+      - y\ :sub:`10`
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - v\ :sub:`11`
+      - v\ :sub:`10`
+      - v\ :sub:`9`
+      - v\ :sub:`8`
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`11`
+      - y\ :sub:`10`
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-VYUY12-2X12:
+
+      - MEDIA_BUS_FMT_VYUY12_2X12
+      - 0x201d
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - v\ :sub:`11`
+      - v\ :sub:`10`
+      - v\ :sub:`9`
+      - v\ :sub:`8`
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`11`
+      - y\ :sub:`10`
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - u\ :sub:`11`
+      - u\ :sub:`10`
+      - u\ :sub:`9`
+      - u\ :sub:`8`
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`11`
+      - y\ :sub:`10`
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-YUYV12-2X12:
+
+      - MEDIA_BUS_FMT_YUYV12_2X12
+      - 0x201e
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`11`
+      - y\ :sub:`10`
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - u\ :sub:`11`
+      - u\ :sub:`10`
+      - u\ :sub:`9`
+      - u\ :sub:`8`
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`11`
+      - y\ :sub:`10`
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - v\ :sub:`11`
+      - v\ :sub:`10`
+      - v\ :sub:`9`
+      - v\ :sub:`8`
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-YVYU12-2X12:
+
+      - MEDIA_BUS_FMT_YVYU12_2X12
+      - 0x201f
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`11`
+      - y\ :sub:`10`
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - v\ :sub:`11`
+      - v\ :sub:`10`
+      - v\ :sub:`9`
+      - v\ :sub:`8`
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`11`
+      - y\ :sub:`10`
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - u\ :sub:`11`
+      - u\ :sub:`10`
+      - u\ :sub:`9`
+      - u\ :sub:`8`
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-Y14-1X14:
+
+      - MEDIA_BUS_FMT_Y14_1X14
+      - 0x202d
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`13`
+      - y\ :sub:`12`
+      - y\ :sub:`11`
+      - y\ :sub:`10`
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-UYVY8-1X16:
+
+      - MEDIA_BUS_FMT_UYVY8_1X16
+      - 0x200f
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-VYUY8-1X16:
+
+      - MEDIA_BUS_FMT_VYUY8_1X16
+      - 0x2010
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-YUYV8-1X16:
+
+      - MEDIA_BUS_FMT_YUYV8_1X16
+      - 0x2011
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-YVYU8-1X16:
+
+      - MEDIA_BUS_FMT_YVYU8_1X16
+      - 0x2012
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-YDYUYDYV8-1X16:
+
+      - MEDIA_BUS_FMT_YDYUYDYV8_1X16
+      - 0x2014
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+      - d
+      - d
+      - d
+      - d
+      - d
+      - d
+      - d
+      - d
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+      - d
+      - d
+      - d
+      - d
+      - d
+      - d
+      - d
+      - d
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-UYVY10-1X20:
+
+      - MEDIA_BUS_FMT_UYVY10_1X20
+      - 0x201a
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - u\ :sub:`9`
+      - u\ :sub:`8`
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - v\ :sub:`9`
+      - v\ :sub:`8`
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-VYUY10-1X20:
+
+      - MEDIA_BUS_FMT_VYUY10_1X20
+      - 0x201b
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - v\ :sub:`9`
+      - v\ :sub:`8`
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - u\ :sub:`9`
+      - u\ :sub:`8`
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-YUYV10-1X20:
+
+      - MEDIA_BUS_FMT_YUYV10_1X20
+      - 0x200d
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+      - u\ :sub:`9`
+      - u\ :sub:`8`
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+      - v\ :sub:`9`
+      - v\ :sub:`8`
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-YVYU10-1X20:
+
+      - MEDIA_BUS_FMT_YVYU10_1X20
+      - 0x200e
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+      - v\ :sub:`9`
+      - v\ :sub:`8`
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+      - u\ :sub:`9`
+      - u\ :sub:`8`
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-VUY8-1X24:
+
+      - MEDIA_BUS_FMT_VUY8_1X24
+      - 0x201a
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-YUV8-1X24:
+
+      - MEDIA_BUS_FMT_YUV8_1X24
+      - 0x2025
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-UYYVYY8-0-5X24:
+
+      - MEDIA_BUS_FMT_UYYVYY8_0_5X24
+      - 0x2026
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-UYVY12-1X24:
+
+      - MEDIA_BUS_FMT_UYVY12_1X24
+      - 0x2020
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - u\ :sub:`11`
+      - u\ :sub:`10`
+      - u\ :sub:`9`
+      - u\ :sub:`8`
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+      - y\ :sub:`11`
+      - y\ :sub:`10`
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - v\ :sub:`11`
+      - v\ :sub:`10`
+      - v\ :sub:`9`
+      - v\ :sub:`8`
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+      - y\ :sub:`11`
+      - y\ :sub:`10`
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-VYUY12-1X24:
+
+      - MEDIA_BUS_FMT_VYUY12_1X24
+      - 0x2021
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - v\ :sub:`11`
+      - v\ :sub:`10`
+      - v\ :sub:`9`
+      - v\ :sub:`8`
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+      - y\ :sub:`11`
+      - y\ :sub:`10`
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - u\ :sub:`11`
+      - u\ :sub:`10`
+      - u\ :sub:`9`
+      - u\ :sub:`8`
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+      - y\ :sub:`11`
+      - y\ :sub:`10`
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-YUYV12-1X24:
+
+      - MEDIA_BUS_FMT_YUYV12_1X24
+      - 0x2022
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`11`
+      - y\ :sub:`10`
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+      - u\ :sub:`11`
+      - u\ :sub:`10`
+      - u\ :sub:`9`
+      - u\ :sub:`8`
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`11`
+      - y\ :sub:`10`
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+      - v\ :sub:`11`
+      - v\ :sub:`10`
+      - v\ :sub:`9`
+      - v\ :sub:`8`
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-YVYU12-1X24:
+
+      - MEDIA_BUS_FMT_YVYU12_1X24
+      - 0x2023
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`11`
+      - y\ :sub:`10`
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+      - v\ :sub:`11`
+      - v\ :sub:`10`
+      - v\ :sub:`9`
+      - v\ :sub:`8`
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`11`
+      - y\ :sub:`10`
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+      - u\ :sub:`11`
+      - u\ :sub:`10`
+      - u\ :sub:`9`
+      - u\ :sub:`8`
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-YUV10-1X30:
+
+      - MEDIA_BUS_FMT_YUV10_1X30
+      - 0x2016
+      -
+      -
+      -
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+      - u\ :sub:`9`
+      - u\ :sub:`8`
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+      - v\ :sub:`9`
+      - v\ :sub:`8`
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-UYYVYY10-0-5X30:
+
+      - MEDIA_BUS_FMT_UYYVYY10_0_5X30
+      - 0x2027
+      -
+      -
+      -
+      - u\ :sub:`9`
+      - u\ :sub:`8`
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      - v\ :sub:`9`
+      - v\ :sub:`8`
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-AYUV8-1X32:
+
+      - MEDIA_BUS_FMT_AYUV8_1X32
+      - 0x2017
+      -
+      - a\ :sub:`7`
+      - a\ :sub:`6`
+      - a\ :sub:`5`
+      - a\ :sub:`4`
+      - a\ :sub:`3`
+      - a\ :sub:`2`
+      - a\ :sub:`1`
+      - a\ :sub:`0`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+
+
+.. raw:: latex
+
+	\endgroup
+
+
+The following table list existing packed 36bit wide YUV formats.
+
+.. raw:: latex
+
+    \begingroup
+    \tiny
+    \setlength{\tabcolsep}{2pt}
+
+.. tabularcolumns:: |p{4.0cm}|p{0.7cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|
+
+.. _v4l2-mbus-pixelcode-yuv8-36bit:
+
+.. flat-table:: 36bit YUV Formats
+    :header-rows:  2
+    :stub-columns: 0
+    :widths: 36 7 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
+
+    * - Identifier
+      - Code
+      -
+      - :cspan:`35` Data organization
+    * -
+      -
+      - Bit
+      - 35
+      - 34
+      - 33
+      - 32
+      - 31
+      - 30
+      - 29
+      - 28
+      - 27
+      - 26
+      - 25
+      - 24
+      - 23
+      - 22
+      - 21
+      - 10
+      - 19
+      - 18
+      - 17
+      - 16
+      - 15
+      - 14
+      - 13
+      - 12
+      - 11
+      - 10
+      - 9
+      - 8
+      - 7
+      - 6
+      - 5
+      - 4
+      - 3
+      - 2
+      - 1
+      - 0
+    * .. _MEDIA-BUS-FMT-UYYVYY12-0-5X36:
+
+      - MEDIA_BUS_FMT_UYYVYY12_0_5X36
+      - 0x2028
+      -
+      - u\ :sub:`11`
+      - u\ :sub:`10`
+      - u\ :sub:`9`
+      - u\ :sub:`8`
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+      - y\ :sub:`11`
+      - y\ :sub:`10`
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+      - y\ :sub:`11`
+      - y\ :sub:`10`
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      - v\ :sub:`11`
+      - v\ :sub:`10`
+      - v\ :sub:`9`
+      - v\ :sub:`8`
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+      - y\ :sub:`11`
+      - y\ :sub:`10`
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+      - y\ :sub:`11`
+      - y\ :sub:`10`
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-YUV12-1X36:
+
+      - MEDIA_BUS_FMT_YUV12_1X36
+      - 0x2029
+      -
+      - y\ :sub:`11`
+      - y\ :sub:`10`
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+      - u\ :sub:`11`
+      - u\ :sub:`10`
+      - u\ :sub:`9`
+      - u\ :sub:`8`
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+      - v\ :sub:`11`
+      - v\ :sub:`10`
+      - v\ :sub:`9`
+      - v\ :sub:`8`
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+
+
+.. raw:: latex
+
+	\endgroup
+
+
+The following table list existing packed 48bit wide YUV formats.
+
+.. raw:: latex
+
+    \begingroup
+    \tiny
+    \setlength{\tabcolsep}{2pt}
+
+.. tabularcolumns:: |p{4.0cm}|p{0.7cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|
+
+.. _v4l2-mbus-pixelcode-yuv8-48bit:
+
+.. flat-table:: 48bit YUV Formats
+    :header-rows:  3
+    :stub-columns: 0
+    :widths: 36 7 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
+
+    * - Identifier
+      - Code
+      -
+      - :cspan:`31` Data organization
+    * -
+      -
+      - Bit
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - 47
+      - 46
+      - 45
+      - 44
+      - 43
+      - 42
+      - 41
+      - 40
+      - 39
+      - 38
+      - 37
+      - 36
+      - 35
+      - 34
+      - 33
+      - 32
+    * -
+      -
+      -
+      - 31
+      - 30
+      - 29
+      - 28
+      - 27
+      - 26
+      - 25
+      - 24
+      - 23
+      - 22
+      - 21
+      - 10
+      - 19
+      - 18
+      - 17
+      - 16
+      - 15
+      - 14
+      - 13
+      - 12
+      - 11
+      - 10
+      - 9
+      - 8
+      - 7
+      - 6
+      - 5
+      - 4
+      - 3
+      - 2
+      - 1
+      - 0
+    * .. _MEDIA-BUS-FMT-YUV16-1X48:
+
+      - MEDIA_BUS_FMT_YUV16_1X48
+      - 0x202a
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - y\ :sub:`15`
+      - y\ :sub:`14`
+      - y\ :sub:`13`
+      - y\ :sub:`12`
+      - y\ :sub:`11`
+      - y\ :sub:`10`
+      - y\ :sub:`8`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      - u\ :sub:`15`
+      - u\ :sub:`14`
+      - u\ :sub:`13`
+      - u\ :sub:`12`
+      - u\ :sub:`11`
+      - u\ :sub:`10`
+      - u\ :sub:`9`
+      - u\ :sub:`8`
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+      - v\ :sub:`15`
+      - v\ :sub:`14`
+      - v\ :sub:`13`
+      - v\ :sub:`12`
+      - v\ :sub:`11`
+      - v\ :sub:`10`
+      - v\ :sub:`9`
+      - v\ :sub:`8`
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+    * .. _MEDIA-BUS-FMT-UYYVYY16-0-5X48:
+
+      - MEDIA_BUS_FMT_UYYVYY16_0_5X48
+      - 0x202b
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - u\ :sub:`15`
+      - u\ :sub:`14`
+      - u\ :sub:`13`
+      - u\ :sub:`12`
+      - u\ :sub:`11`
+      - u\ :sub:`10`
+      - u\ :sub:`9`
+      - u\ :sub:`8`
+      - u\ :sub:`7`
+      - u\ :sub:`6`
+      - u\ :sub:`5`
+      - u\ :sub:`4`
+      - u\ :sub:`3`
+      - u\ :sub:`2`
+      - u\ :sub:`1`
+      - u\ :sub:`0`
+    * -
+      -
+      -
+      - y\ :sub:`15`
+      - y\ :sub:`14`
+      - y\ :sub:`13`
+      - y\ :sub:`12`
+      - y\ :sub:`11`
+      - y\ :sub:`10`
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+      - y\ :sub:`15`
+      - y\ :sub:`14`
+      - y\ :sub:`13`
+      - y\ :sub:`12`
+      - y\ :sub:`11`
+      - y\ :sub:`10`
+      - y\ :sub:`8`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+    * -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      - v\ :sub:`15`
+      - v\ :sub:`14`
+      - v\ :sub:`13`
+      - v\ :sub:`12`
+      - v\ :sub:`11`
+      - v\ :sub:`10`
+      - v\ :sub:`9`
+      - v\ :sub:`8`
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+    * -
+      -
+      -
+      - y\ :sub:`15`
+      - y\ :sub:`14`
+      - y\ :sub:`13`
+      - y\ :sub:`12`
+      - y\ :sub:`11`
+      - y\ :sub:`10`
+      - y\ :sub:`9`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+      - y\ :sub:`15`
+      - y\ :sub:`14`
+      - y\ :sub:`13`
+      - y\ :sub:`12`
+      - y\ :sub:`11`
+      - y\ :sub:`10`
+      - y\ :sub:`8`
+      - y\ :sub:`8`
+      - y\ :sub:`7`
+      - y\ :sub:`6`
+      - y\ :sub:`5`
+      - y\ :sub:`4`
+      - y\ :sub:`3`
+      - y\ :sub:`2`
+      - y\ :sub:`1`
+      - y\ :sub:`0`
+
+
+.. raw:: latex
+
+	\endgroup
+
+HSV/HSL Formats
+^^^^^^^^^^^^^^^
+
+Those formats transfer pixel data as RGB values in a
+cylindrical-coordinate system using Hue-Saturation-Value or
+Hue-Saturation-Lightness components. The format code is made of the
+following information.
+
+-  The hue, saturation, value or lightness and optional alpha components
+   order code, as encoded in a pixel sample. The only currently
+   supported value is AHSV.
+
+-  The number of bits per component, for each component. The values can
+   be different for all components. The only currently supported value
+   is 8888.
+
+-  The number of bus samples per pixel. Pixels that are wider than the
+   bus width must be transferred in multiple samples. The only currently
+   supported value is 1.
+
+-  The bus width.
+
+-  For formats where the total number of bits per pixel is smaller than
+   the number of bus samples per pixel times the bus width, a padding
+   value stating if the bytes are padded in their most high order bits
+   (PADHI) or low order bits (PADLO).
+
+-  For formats where the number of bus samples per pixel is larger than
+   1, an endianness value stating if the pixel is transferred MSB first
+   (BE) or LSB first (LE).
+
+The following table lists existing HSV/HSL formats.
+
+
+.. raw:: latex
+
+    \begingroup
+    \tiny
+    \setlength{\tabcolsep}{2pt}
+
+.. tabularcolumns:: |p{3.9cm}|p{0.73cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|
+
+.. _v4l2-mbus-pixelcode-hsv:
+
+.. flat-table:: HSV/HSL formats
+    :header-rows:  2
+    :stub-columns: 0
+    :widths: 28 7 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
+
+    * - Identifier
+      - Code
+      -
+      - :cspan:`31` Data organization
+    * -
+      -
+      - Bit
+      - 31
+      - 30
+      - 29
+      - 28
+      - 27
+      - 26
+      - 25
+      - 24
+      - 23
+      - 22
+      - 21
+      - 20
+      - 19
+      - 18
+      - 17
+      - 16
+      - 15
+      - 14
+      - 13
+      - 12
+      - 11
+      - 10
+      - 9
+      - 8
+      - 7
+      - 6
+      - 5
+      - 4
+      - 3
+      - 2
+      - 1
+      - 0
+    * .. _MEDIA-BUS-FMT-AHSV8888-1X32:
+
+      - MEDIA_BUS_FMT_AHSV8888_1X32
+      - 0x6001
+      -
+      - a\ :sub:`7`
+      - a\ :sub:`6`
+      - a\ :sub:`5`
+      - a\ :sub:`4`
+      - a\ :sub:`3`
+      - a\ :sub:`2`
+      - a\ :sub:`1`
+      - a\ :sub:`0`
+      - h\ :sub:`7`
+      - h\ :sub:`6`
+      - h\ :sub:`5`
+      - h\ :sub:`4`
+      - h\ :sub:`3`
+      - h\ :sub:`2`
+      - h\ :sub:`1`
+      - h\ :sub:`0`
+      - s\ :sub:`7`
+      - s\ :sub:`6`
+      - s\ :sub:`5`
+      - s\ :sub:`4`
+      - s\ :sub:`3`
+      - s\ :sub:`2`
+      - s\ :sub:`1`
+      - s\ :sub:`0`
+      - v\ :sub:`7`
+      - v\ :sub:`6`
+      - v\ :sub:`5`
+      - v\ :sub:`4`
+      - v\ :sub:`3`
+      - v\ :sub:`2`
+      - v\ :sub:`1`
+      - v\ :sub:`0`
+
+.. raw:: latex
+
+    \normalsize
+
+
+JPEG Compressed Formats
+^^^^^^^^^^^^^^^^^^^^^^^
+
+Those data formats consist of an ordered sequence of 8-bit bytes
+obtained from JPEG compression process. Additionally to the ``_JPEG``
+postfix the format code is made of the following information.
+
+-  The number of bus samples per entropy encoded byte.
+
+-  The bus width.
+
+For instance, for a JPEG baseline process and an 8-bit bus width the
+format will be named ``MEDIA_BUS_FMT_JPEG_1X8``.
+
+The following table lists existing JPEG compressed formats.
+
+
+.. _v4l2-mbus-pixelcode-jpeg:
+
+.. tabularcolumns:: |p{6.0cm}|p{1.4cm}|p{10.1cm}|
+
+.. flat-table:: JPEG Formats
+    :header-rows:  1
+    :stub-columns: 0
+
+    * - Identifier
+      - Code
+      - Remarks
+    * .. _MEDIA-BUS-FMT-JPEG-1X8:
+
+      - MEDIA_BUS_FMT_JPEG_1X8
+      - 0x4001
+      - Besides of its usage for the parallel bus this format is
+	recommended for transmission of JPEG data over MIPI CSI bus using
+	the User Defined 8-bit Data types.
+
+
+
+.. _v4l2-mbus-vendor-spec-fmts:
+
+Vendor and Device Specific Formats
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This section lists complex data formats that are either vendor or device
+specific.
+
+The following table lists the existing vendor and device specific
+formats.
+
+
+.. _v4l2-mbus-pixelcode-vendor-specific:
+
+.. tabularcolumns:: |p{8.0cm}|p{1.4cm}|p{7.7cm}|
+
+.. flat-table:: Vendor and device specific formats
+    :header-rows:  1
+    :stub-columns: 0
+
+    * - Identifier
+      - Code
+      - Comments
+    * .. _MEDIA-BUS-FMT-S5C-UYVY-JPEG-1X8:
+
+      - MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8
+      - 0x5001
+      - Interleaved raw UYVY and JPEG image format with embedded meta-data
+	used by Samsung S3C73MX camera sensors.
diff --git a/Documentation/userspace-api/media/v4l/subdev-image-processing-crop.svg b/Documentation/userspace-api/media/v4l/subdev-image-processing-crop.svg
new file mode 100644
index 000000000000..109bbcebd3b4
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/subdev-image-processing-crop.svg
@@ -0,0 +1,312 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+    Permission is granted to copy, distribute and/or modify this
+    document under the terms of the GNU Free Documentation License,
+    Version 1.1 or any later version published by the Free Software
+    Foundation, with no Invariant Sections, no Front-Cover Texts
+    and no Back-Cover Texts. A copy of the license is included at
+    Documentation/userspace-api/media/fdl-appendix.rst.
+
+    TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+-->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="42.799767cm"
+   height="9.9348345cm"
+   viewBox="-194 128 840.06984 194.72276"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="subdev-image-processing-crop.svg">
+  <metadata
+     id="metadata100">
+    <rdf:RDF>
+      <cc:Work
+	 rdf:about="">
+	<dc:format>image/svg+xml</dc:format>
+	<dc:type
+	   rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+	<dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs98" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="997"
+     id="namedview96"
+     showgrid="false"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0"
+     inkscape:zoom="0.3649199"
+     inkscape:cx="764.40286"
+     inkscape:cy="176.91347"
+     inkscape:window-x="1920"
+     inkscape:window-y="30"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg2" />
+  <rect
+     style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+     x="-9.6002426"
+     y="128.86047"
+     width="469.77399"
+     height="193"
+     id="rect4" />
+  <g
+     id="g6"
+     transform="translate(-1.6002426,-1.1395339)">
+    <rect
+       style="fill:#ffffff"
+       x="4.5"
+       y="189"
+       width="159"
+       height="104"
+       id="rect8" />
+    <rect
+       style="fill:none;fill-opacity:0;stroke:#a52a2a;stroke-width:2"
+       x="4.5"
+       y="189"
+       width="159"
+       height="104"
+       id="rect10" />
+  </g>
+  <g
+     id="g12"
+     transform="translate(-1.6002426,-1.1395339)">
+    <rect
+       style="fill:#ffffff"
+       x="63.5"
+       y="211"
+       width="94"
+       height="77"
+       id="rect14" />
+    <rect
+       style="fill:none;fill-opacity:0;stroke:#0000ff;stroke-width:2"
+       x="63.5"
+       y="211"
+       width="94"
+       height="77"
+       id="rect16" />
+  </g>
+  <text
+     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#0000ff"
+     x="72.899757"
+     y="226.61047"
+     id="text18">
+    <tspan
+       x="72.899757"
+       y="226.61047"
+       id="tspan20">sink</tspan>
+    <tspan
+       x="72.899757"
+       y="242.61047"
+       id="tspan22">crop</tspan>
+    <tspan
+       x="72.899757"
+       y="258.61047"
+       id="tspan24">selection</tspan>
+  </text>
+  <text
+     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#000000"
+     x="27.899757"
+     y="156.86047"
+     id="text26">
+    <tspan
+       x="27.899757"
+       y="156.86047"
+       id="tspan28" />
+  </text>
+  <text
+     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#a52a2a"
+     x="6.938117"
+     y="156.77448"
+     id="text30">
+    <tspan
+       x="6.938117"
+       y="156.77448"
+       id="tspan32">sink media</tspan>
+    <tspan
+       x="6.938117"
+       y="172.77448"
+       id="tspan34">bus format</tspan>
+  </text>
+  <text
+     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#8b6914"
+     x="348.17374"
+     y="153.86047"
+     id="text36">
+    <tspan
+       x="348.17374"
+       y="153.86047"
+       id="tspan38">source media</tspan>
+    <tspan
+       x="348.17374"
+       y="169.86047"
+       id="tspan40">bus format</tspan>
+  </text>
+  <g
+     id="g42"
+     transform="translate(-1.6002426,-1.1395339)">
+    <rect
+       style="fill:#ffffff"
+       x="350.48801"
+       y="190.834"
+       width="93.286301"
+       height="75.166"
+       id="rect44" />
+    <rect
+       style="fill:none;fill-opacity:0;stroke:#8b6914;stroke-width:2"
+       x="350.48801"
+       y="190.834"
+       width="93.286301"
+       height="75.166"
+       id="rect46" />
+  </g>
+  <line
+     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
+     x1="348.88776"
+     y1="264.86047"
+     x2="61.899757"
+     y2="286.86047"
+     id="line48" />
+  <line
+     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
+     x1="348.88776"
+     y1="189.69447"
+     x2="61.899757"
+     y2="209.86047"
+     id="line50" />
+  <line
+     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
+     x1="442.17374"
+     y1="264.86047"
+     x2="155.89977"
+     y2="286.86047"
+     id="line52" />
+  <line
+     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
+     x1="442.17374"
+     y1="189.69447"
+     x2="155.89977"
+     y2="209.86047"
+     id="line54" />
+  <g
+     id="g56"
+     transform="translate(-1.6002426,-1.1395339)">
+    <circle
+       style="fill:#ffffff"
+       cx="473.10001"
+       cy="219.98399"
+       id="ellipse58"
+       r="8.5" />
+    <circle
+       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+       cx="473.10001"
+       cy="219.98399"
+       id="ellipse60"
+       r="8.5" />
+    <circle
+       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+       cx="473.10001"
+       cy="219.98399"
+       id="ellipse62"
+       r="8.5" />
+  </g>
+  <g
+     id="g64"
+     transform="translate(-1.6002426,-1.1395339)">
+    <line
+       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+       x1="481.60001"
+       y1="219.98399"
+       x2="637.93402"
+       y2="220.01199"
+       id="line66" />
+    <polygon
+       style="fill:#000000"
+       points="635.435,215.012 645.434,220.014 635.433,225.012 637.934,220.012 "
+       id="polygon68" />
+    <polygon
+       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+       points="635.435,215.012 645.434,220.014 635.433,225.012 637.934,220.012 "
+       id="polygon70" />
+  </g>
+  <text
+     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#000000"
+     x="505.30774"
+     y="208.66048"
+     id="text72">
+    <tspan
+       x="505.30774"
+       y="208.66048"
+       id="tspan74">pad 1 (source)</tspan>
+  </text>
+  <g
+     id="g76"
+     transform="translate(-1.6002426,-1.1395339)">
+    <circle
+       style="fill:#ffffff"
+       cx="-20.398199"
+       cy="241.51199"
+       id="ellipse78"
+       r="8.5" />
+    <circle
+       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+       cx="-20.398199"
+       cy="241.51199"
+       id="ellipse80"
+       r="8.5" />
+    <circle
+       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+       cx="-20.398199"
+       cy="241.51199"
+       id="ellipse82"
+       r="8.5" />
+  </g>
+  <g
+     id="g84"
+     transform="translate(-1.6002426,-1.1395339)">
+    <line
+       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+       x1="-192.39799"
+       y1="241.8"
+       x2="-38.6343"
+       y2="241.52901"
+       id="line86" />
+    <polygon
+       style="fill:#000000"
+       points="-41.1431,236.534 -31.1343,241.516 -41.1254,246.534 -38.6343,241.529 "
+       id="polygon88" />
+    <polygon
+       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+       points="-41.1431,236.534 -31.1343,241.516 -41.1254,246.534 -38.6343,241.529 "
+       id="polygon90" />
+  </g>
+  <text
+     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#000000"
+     x="-149.45824"
+     y="228.66048"
+     id="text92">
+    <tspan
+       x="-149.45824"
+       y="228.66048"
+       id="tspan94">pad 0 (sink)</tspan>
+  </text>
+</svg>
diff --git a/Documentation/userspace-api/media/v4l/subdev-image-processing-full.svg b/Documentation/userspace-api/media/v4l/subdev-image-processing-full.svg
new file mode 100644
index 000000000000..cfdb7532d5b6
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/subdev-image-processing-full.svg
@@ -0,0 +1,752 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+    Permission is granted to copy, distribute and/or modify this
+    document under the terms of the GNU Free Documentation License,
+    Version 1.1 or any later version published by the Free Software
+    Foundation, with no Invariant Sections, no Front-Cover Texts
+    and no Back-Cover Texts. A copy of the license is included at
+    Documentation/userspace-api/media/fdl-appendix.rst.
+
+    TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+-->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="58.825298cm"
+   height="17.279287cm"
+   viewBox="-186 71 1174.5119 332.1463"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="subdev-image-processing-full.svg">
+  <metadata
+     id="metadata260">
+    <rdf:RDF>
+      <cc:Work
+	 rdf:about="">
+	<dc:format>image/svg+xml</dc:format>
+	<dc:type
+	   rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+	<dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs258" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="997"
+     id="namedview256"
+     showgrid="false"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0"
+     inkscape:zoom="0.26595857"
+     inkscape:cx="1050.1367"
+     inkscape:cy="307.01645"
+     inkscape:window-x="1920"
+     inkscape:window-y="30"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg2" />
+  <g
+     id="g4"
+     transform="translate(-1.4982376,-7.6949076)">
+    <rect
+       style="fill:#ffffff"
+       x="318.89999"
+       y="129"
+       width="208.10001"
+       height="249"
+       id="rect6" />
+    <rect
+       style="fill:none;fill-opacity:0;stroke:#ff765a;stroke-width:2"
+       x="318.89999"
+       y="129"
+       width="208.10001"
+       height="249"
+       id="rect8" />
+  </g>
+  <rect
+     style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+     x="-3.4982376"
+     y="65.305092"
+     width="806"
+     height="343"
+     id="rect10" />
+  <g
+     id="g12"
+     transform="translate(-1.4982376,-7.6949076)">
+    <circle
+       style="fill:#ffffff"
+       cx="-12.5"
+       cy="166.71201"
+       id="ellipse14"
+       r="8.5" />
+    <circle
+       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+       cx="-12.5"
+       cy="166.71201"
+       id="ellipse16"
+       r="8.5" />
+    <circle
+       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+       cx="-12.5"
+       cy="166.71201"
+       id="ellipse18"
+       r="8.5" />
+  </g>
+  <g
+     id="g20"
+     transform="translate(-1.4982376,-7.6949076)">
+    <circle
+       style="fill:#ffffff"
+       cx="815.23199"
+       cy="205.18401"
+       id="ellipse22"
+       r="8.5" />
+    <circle
+       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+       cx="815.23199"
+       cy="205.18401"
+       id="ellipse24"
+       r="8.5" />
+    <circle
+       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+       cx="815.23199"
+       cy="205.18401"
+       id="ellipse26"
+       r="8.5" />
+  </g>
+  <g
+     id="g28"
+     transform="translate(-1.4982376,-7.6949076)">
+    <line
+       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+       x1="-184.5"
+       y1="167"
+       x2="-30.736099"
+       y2="166.729"
+       id="line30" />
+    <polygon
+       style="fill:#000000"
+       points="-33.2449,161.734 -23.2361,166.716 -33.2272,171.734 -30.7361,166.729 "
+       id="polygon32" />
+    <polygon
+       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+       points="-33.2449,161.734 -23.2361,166.716 -33.2272,171.734 -30.7361,166.729 "
+       id="polygon34" />
+  </g>
+  <g
+     id="g36"
+     transform="translate(-1.4982376,-7.6949076)">
+    <line
+       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+       x1="823.73199"
+       y1="205.18401"
+       x2="980.06598"
+       y2="205.21201"
+       id="line38" />
+    <polygon
+       style="fill:#000000"
+       points="977.567,200.212 987.566,205.214 977.565,210.212 980.066,205.212 "
+       id="polygon40" />
+    <polygon
+       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+       points="977.567,200.212 987.566,205.214 977.565,210.212 980.066,205.212 "
+       id="polygon42" />
+  </g>
+  <text
+     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#000000"
+     x="-141.45824"
+     y="147.3051"
+     id="text44">
+    <tspan
+       x="-141.45824"
+       y="147.3051"
+       id="tspan46">pad 0 (sink)</tspan>
+  </text>
+  <text
+     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#000000"
+     x="847.54175"
+     y="187.3051"
+     id="text48">
+    <tspan
+       x="847.54175"
+       y="187.3051"
+       id="tspan50">pad 2 (source)</tspan>
+  </text>
+  <g
+     id="g52"
+     transform="translate(-1.4982376,-7.6949076)">
+    <rect
+       style="fill:#ffffff"
+       x="5.5"
+       y="120"
+       width="159"
+       height="104"
+       id="rect54" />
+    <rect
+       style="fill:none;fill-opacity:0;stroke:#a52a2a;stroke-width:2"
+       x="5.5"
+       y="120"
+       width="159"
+       height="104"
+       id="rect56" />
+  </g>
+  <g
+     id="g58"
+     transform="translate(-1.4982376,-7.6949076)">
+    <rect
+       style="fill:#ffffff"
+       x="62.5"
+       y="136"
+       width="94"
+       height="77"
+       id="rect60" />
+    <rect
+       style="fill:none;fill-opacity:0;stroke:#0000ff;stroke-width:2"
+       x="62.5"
+       y="136"
+       width="94"
+       height="77"
+       id="rect62" />
+  </g>
+  <text
+     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#000000"
+     x="29.001762"
+     y="81.305092"
+     id="text64">
+    <tspan
+       x="29.001762"
+       y="81.305092"
+       id="tspan66" />
+  </text>
+  <text
+     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#a52a2a"
+     x="8.040122"
+     y="81.218895"
+     id="text68">
+    <tspan
+       x="8.040122"
+       y="81.218895"
+       id="tspan70">sink media</tspan>
+    <tspan
+       x="8.040122"
+       y="97.219093"
+       id="tspan72">bus format</tspan>
+  </text>
+  <g
+     id="g74"
+     transform="translate(-1.4982376,-7.6949076)">
+    <rect
+       style="fill:#ffffff"
+       x="333.64401"
+       y="185.64999"
+       width="165.2"
+       height="172.478"
+       id="rect76" />
+    <rect
+       style="fill:none;fill-opacity:0;stroke:#00ff00;stroke-width:2"
+       x="333.64401"
+       y="185.64999"
+       width="165.2"
+       height="172.478"
+       id="rect78" />
+  </g>
+  <line
+     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
+     x1="332.14578"
+     y1="350.43307"
+     x2="61.001762"
+     y2="205.3051"
+     id="line80" />
+  <line
+     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
+     x1="332.14578"
+     y1="177.95509"
+     x2="61.001762"
+     y2="128.3051"
+     id="line82" />
+  <line
+     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
+     x1="497.34576"
+     y1="350.43307"
+     x2="155.00177"
+     y2="205.3051"
+     id="line84" />
+  <line
+     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
+     x1="497.34576"
+     y1="177.95509"
+     x2="155.00177"
+     y2="128.3051"
+     id="line86" />
+  <text
+     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#00ff00"
+     x="333.20578"
+     y="141.7471"
+     id="text88">
+    <tspan
+       x="333.20578"
+       y="141.7471"
+       id="tspan90">sink compose</tspan>
+    <tspan
+       x="333.20578"
+       y="157.7471"
+       id="tspan92">selection (scaling)</tspan>
+  </text>
+  <g
+     id="g94"
+     transform="translate(-1.4982376,-7.6949076)">
+    <rect
+       style="fill:#ffffff"
+       x="409.32199"
+       y="194.565"
+       width="100.186"
+       height="71.452301"
+       id="rect96" />
+    <rect
+       style="fill:none;fill-opacity:0;stroke:#a020f0;stroke-width:2"
+       x="409.32199"
+       y="194.565"
+       width="100.186"
+       height="71.452301"
+       id="rect98" />
+  </g>
+  <text
+     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#8b6914"
+     x="688.00177"
+     y="97.43309"
+     id="text100">
+    <tspan
+       x="688.00177"
+       y="97.43309"
+       id="tspan102">source media</tspan>
+    <tspan
+       x="688.00177"
+       y="113.43309"
+       id="tspan104">bus format</tspan>
+  </text>
+  <g
+     id="g106"
+     transform="translate(-1.4982376,-7.6949076)">
+    <rect
+       style="fill:#ffffff"
+       x="688.48798"
+       y="173.834"
+       width="100.186"
+       height="71.452301"
+       id="rect108" />
+    <rect
+       style="fill:none;fill-opacity:0;stroke:#8b6914;stroke-width:2"
+       x="688.48798"
+       y="173.834"
+       width="100.186"
+       height="71.452301"
+       id="rect110" />
+  </g>
+  <line
+     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
+     x1="686.98975"
+     y1="237.59109"
+     x2="407.82376"
+     y2="258.32309"
+     id="line112" />
+  <line
+     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
+     x1="686.98975"
+     y1="166.1391"
+     x2="407.82376"
+     y2="186.8701"
+     id="line114" />
+  <line
+     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
+     x1="787.17578"
+     y1="237.59109"
+     x2="508.00977"
+     y2="258.32309"
+     id="line116" />
+  <line
+     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
+     x1="787.17578"
+     y1="166.1391"
+     x2="508.00977"
+     y2="186.8701"
+     id="line118" />
+  <text
+     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#ff765a"
+     x="323.50177"
+     y="95.305092"
+     id="text120">
+    <tspan
+       x="323.50177"
+       y="95.305092"
+       id="tspan122">sink compose</tspan>
+    <tspan
+       x="323.50177"
+       y="111.30509"
+       id="tspan124">bounds selection</tspan>
+  </text>
+  <g
+     id="g126"
+     transform="translate(-1.4982376,-7.6949076)">
+    <circle
+       style="fill:#ffffff"
+       cx="-12.0982"
+       cy="341.51199"
+       id="ellipse128"
+       r="8.5" />
+    <circle
+       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+       cx="-12.0982"
+       cy="341.51199"
+       id="ellipse130"
+       r="8.5" />
+    <circle
+       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+       cx="-12.0982"
+       cy="341.51199"
+       id="ellipse132"
+       r="8.5" />
+  </g>
+  <g
+     id="g134"
+     transform="translate(-1.4982376,-7.6949076)">
+    <line
+       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+       x1="-184.09801"
+       y1="341.79999"
+       x2="-30.334299"
+       y2="341.52899"
+       id="line136" />
+    <polygon
+       style="fill:#000000"
+       points="-32.8431,336.534 -22.8343,341.516 -32.8254,346.534 -30.3343,341.529 "
+       id="polygon138" />
+    <polygon
+       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+       points="-32.8431,336.534 -22.8343,341.516 -32.8254,346.534 -30.3343,341.529 "
+       id="polygon140" />
+  </g>
+  <text
+     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#000000"
+     x="-140.49823"
+     y="321.30508"
+     id="text142">
+    <tspan
+       x="-140.49823"
+       y="321.30508"
+       id="tspan144">pad 1 (sink)</tspan>
+  </text>
+  <g
+     id="g146"
+     transform="translate(-1.4982376,-7.6949076)">
+    <rect
+       style="fill:#ffffff"
+       x="7.8082399"
+       y="292.79999"
+       width="112.092"
+       height="82.199997"
+       id="rect148" />
+    <rect
+       style="fill:none;fill-opacity:0;stroke:#a52a2a;stroke-width:2"
+       x="7.8082399"
+       y="292.79999"
+       width="112.092"
+       height="82.199997"
+       id="rect150" />
+  </g>
+  <g
+     id="g152"
+     transform="translate(-1.4982376,-7.6949076)">
+    <rect
+       style="fill:#ffffff"
+       x="52.900002"
+       y="314.79999"
+       width="58.099998"
+       height="50.200001"
+       id="rect154" />
+    <rect
+       style="fill:none;fill-opacity:0;stroke:#0000ff;stroke-width:2"
+       x="52.900002"
+       y="314.79999"
+       width="58.099998"
+       height="50.200001"
+       id="rect156" />
+  </g>
+  <text
+     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#000000"
+     x="30.401762"
+     y="252.10509"
+     id="text158">
+    <tspan
+       x="30.401762"
+       y="252.10509"
+       id="tspan160" />
+  </text>
+  <line
+     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
+     x1="357.40176"
+     y1="244.20509"
+     x2="51.401764"
+     y2="307.10507"
+     id="line162" />
+  <line
+     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
+     x1="357.40176"
+     y1="308.30508"
+     x2="51.401764"
+     y2="357.30508"
+     id="line164" />
+  <line
+     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
+     x1="432.50177"
+     y1="308.30508"
+     x2="109.50176"
+     y2="357.30508"
+     id="line166" />
+  <line
+     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
+     x1="432.50177"
+     y1="244.20509"
+     x2="109.50176"
+     y2="307.10507"
+     id="line168" />
+  <rect
+     style="fill:none;fill-opacity:0;stroke:#00ff00;stroke-width:2"
+     x="357.40176"
+     y="244.20509"
+     width="75.099998"
+     height="64.099998"
+     id="rect170" />
+  <rect
+     style="fill:none;fill-opacity:0;stroke:#a020f0;stroke-width:2"
+     x="441.76376"
+     y="276.77109"
+     width="64.737999"
+     height="48.534"
+     id="rect172" />
+  <g
+     id="g174"
+     transform="translate(-1.4982376,-7.6949076)">
+    <rect
+       style="fill:#ffffff"
+       x="693.42798"
+       y="324.73401"
+       width="63.571999"
+       height="49.265999"
+       id="rect176" />
+    <rect
+       style="fill:none;fill-opacity:0;stroke:#8b6914;stroke-width:2"
+       x="693.42798"
+       y="324.73401"
+       width="63.571999"
+       height="49.265999"
+       id="rect178" />
+  </g>
+  <line
+     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
+     x1="691.92975"
+     y1="366.30508"
+     x2="441.76376"
+     y2="325.30508"
+     id="line180" />
+  <line
+     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
+     x1="691.92975"
+     y1="317.03909"
+     x2="441.76376"
+     y2="276.77109"
+     id="line182" />
+  <line
+     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
+     x1="755.50177"
+     y1="366.30508"
+     x2="506.50177"
+     y2="325.30508"
+     id="line184" />
+  <line
+     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
+     x1="755.50177"
+     y1="317.03909"
+     x2="506.50177"
+     y2="276.77109"
+     id="line186" />
+  <g
+     id="g188"
+     transform="translate(-1.4982376,-7.6949076)">
+    <circle
+       style="fill:#ffffff"
+       cx="815.44"
+       cy="343.98401"
+       id="ellipse190"
+       r="8.5" />
+    <circle
+       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+       cx="815.44"
+       cy="343.98401"
+       id="ellipse192"
+       r="8.5" />
+    <circle
+       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+       cx="815.44"
+       cy="343.98401"
+       id="ellipse194"
+       r="8.5" />
+  </g>
+  <g
+     id="g196"
+     transform="translate(-1.4982376,-7.6949076)">
+    <line
+       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+       x1="823.94"
+       y1="343.98401"
+       x2="980.27399"
+       y2="344.01199"
+       id="line198" />
+    <polygon
+       style="fill:#000000"
+       points="977.775,339.012 987.774,344.014 977.773,349.012 980.274,344.012 "
+       id="polygon200" />
+    <polygon
+       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+       points="977.775,339.012 987.774,344.014 977.773,349.012 980.274,344.012 "
+       id="polygon202" />
+  </g>
+  <text
+     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#000000"
+     x="847.74976"
+     y="326.10507"
+     id="text204">
+    <tspan
+       x="847.74976"
+       y="326.10507"
+       id="tspan206">pad 3 (source)</tspan>
+  </text>
+  <text
+     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#0000ff"
+     x="195.50177"
+     y="83.305092"
+     id="text208">
+    <tspan
+       x="195.50177"
+       y="83.305092"
+       id="tspan210">sink</tspan>
+    <tspan
+       x="195.50177"
+       y="99.305092"
+       id="tspan212">crop</tspan>
+    <tspan
+       x="195.50177"
+       y="115.30509"
+       id="tspan214">selection</tspan>
+  </text>
+  <text
+     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#a020f0"
+     x="551.50177"
+     y="87.305092"
+     id="text216">
+    <tspan
+       x="551.50177"
+       y="87.305092"
+       id="tspan218">source</tspan>
+    <tspan
+       x="551.50177"
+       y="103.30509"
+       id="tspan220">crop</tspan>
+    <tspan
+       x="551.50177"
+       y="119.30509"
+       id="tspan222">selection</tspan>
+  </text>
+  <g
+     id="g224"
+     transform="translate(-1.4982376,-7.6949076)">
+    <line
+       style="fill:none;fill-opacity:0;stroke:#0000ff;stroke-width:2"
+       x1="211"
+       y1="132"
+       x2="166.21001"
+       y2="135.287"
+       id="line226" />
+    <polygon
+       style="fill:#0000ff"
+       points="169.069,140.091 158.73,135.836 168.337,130.118 166.21,135.287 "
+       id="polygon228" />
+    <polygon
+       style="fill:none;fill-opacity:0;stroke:#0000ff;stroke-width:2"
+       points="169.069,140.091 158.73,135.836 168.337,130.118 166.21,135.287 "
+       id="polygon230" />
+  </g>
+  <g
+     id="g232"
+     transform="translate(-1.4982376,-7.6949076)">
+    <line
+       style="fill:none;fill-opacity:0;stroke:#0000ff;stroke-width:2"
+       x1="209"
+       y1="131"
+       x2="115.581"
+       y2="306.20901"
+       id="line234" />
+    <polygon
+       style="fill:#0000ff"
+       points="121.169,306.355 112.052,312.827 112.345,301.65 115.581,306.209 "
+       id="polygon236" />
+    <polygon
+       style="fill:none;fill-opacity:0;stroke:#0000ff;stroke-width:2"
+       points="121.169,306.355 112.052,312.827 112.345,301.65 115.581,306.209 "
+       id="polygon238" />
+  </g>
+  <g
+     id="g240"
+     transform="translate(-1.4982376,-7.6949076)">
+    <line
+       style="fill:none;fill-opacity:0;stroke:#a020f0;stroke-width:2"
+       x1="550.492"
+       y1="133.214"
+       x2="514.91602"
+       y2="186.46899"
+       id="line242" />
+    <polygon
+       style="fill:#a020f0"
+       points="520.463,187.168 510.75,192.706 512.147,181.613 514.916,186.469 "
+       id="polygon244" />
+    <polygon
+       style="fill:none;fill-opacity:0;stroke:#a020f0;stroke-width:2"
+       points="520.463,187.168 510.75,192.706 512.147,181.613 514.916,186.469 "
+       id="polygon246" />
+  </g>
+  <g
+     id="g248"
+     transform="translate(-1.4982376,-7.6949076)">
+    <line
+       style="fill:none;fill-opacity:0;stroke:#a020f0;stroke-width:2"
+       x1="550.07202"
+       y1="133.787"
+       x2="510.61801"
+       y2="275.08899"
+       id="line250" />
+    <polygon
+       style="fill:#a020f0"
+       points="516.106,274.025 508.601,282.312 506.475,271.336 510.618,275.089 "
+       id="polygon252" />
+    <polygon
+       style="fill:none;fill-opacity:0;stroke:#a020f0;stroke-width:2"
+       points="516.106,274.025 508.601,282.312 506.475,271.336 510.618,275.089 "
+       id="polygon254" />
+  </g>
+</svg>
diff --git a/Documentation/userspace-api/media/v4l/subdev-image-processing-scaling-multi-source.svg b/Documentation/userspace-api/media/v4l/subdev-image-processing-scaling-multi-source.svg
new file mode 100644
index 000000000000..f7f1379d30a6
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/subdev-image-processing-scaling-multi-source.svg
@@ -0,0 +1,550 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+    Permission is granted to copy, distribute and/or modify this
+    document under the terms of the GNU Free Documentation License,
+    Version 1.1 or any later version published by the Free Software
+    Foundation, with no Invariant Sections, no Front-Cover Texts
+    and no Back-Cover Texts. A copy of the license is included at
+    Documentation/userspace-api/media/fdl-appendix.rst.
+
+    TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+-->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="58.803326cm"
+   height="16.463955cm"
+   viewBox="-194 128 1175.0698 319.59442"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="subdev-image-processing-scaling-multi-source.svg">
+  <metadata
+     id="metadata186">
+    <rdf:RDF>
+      <cc:Work
+	 rdf:about="">
+	<dc:format>image/svg+xml</dc:format>
+	<dc:type
+	   rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+	<dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs184" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="997"
+     id="namedview182"
+     showgrid="false"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0"
+     inkscape:zoom="0.26595857"
+     inkscape:cx="1049.9581"
+     inkscape:cy="292.5708"
+     inkscape:window-x="1920"
+     inkscape:window-y="30"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg2" />
+  <rect
+     style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+     x="-9.6002426"
+     y="124.14409"
+     width="806"
+     height="327"
+     id="rect4" />
+  <g
+     id="g6"
+     transform="translate(-1.6002426,-5.8559115)">
+    <rect
+       style="fill:#ffffff"
+       x="4.5"
+       y="189"
+       width="159"
+       height="104"
+       id="rect8" />
+    <rect
+       style="fill:none;fill-opacity:0;stroke:#a52a2a;stroke-width:2"
+       x="4.5"
+       y="189"
+       width="159"
+       height="104"
+       id="rect10" />
+  </g>
+  <g
+     id="g12"
+     transform="translate(-1.6002426,-5.8559115)">
+    <rect
+       style="fill:#ffffff"
+       x="49.5"
+       y="204"
+       width="94"
+       height="77"
+       id="rect14" />
+    <rect
+       style="fill:none;fill-opacity:0;stroke:#0000ff;stroke-width:2"
+       x="49.5"
+       y="204"
+       width="94"
+       height="77"
+       id="rect16" />
+  </g>
+  <text
+     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#0000ff"
+     x="58.399757"
+     y="218.14409"
+     id="text18">
+    <tspan
+       x="58.399757"
+       y="218.14409"
+       id="tspan20">sink</tspan>
+    <tspan
+       x="58.399757"
+       y="234.14409"
+       id="tspan22">crop</tspan>
+    <tspan
+       x="58.399757"
+       y="250.14409"
+       id="tspan24">selection</tspan>
+  </text>
+  <text
+     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#000000"
+     x="27.899757"
+     y="152.14409"
+     id="text26">
+    <tspan
+       x="27.899757"
+       y="152.14409"
+       id="tspan28" />
+  </text>
+  <text
+     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#a52a2a"
+     x="6.938117"
+     y="152.05809"
+     id="text30">
+    <tspan
+       x="6.938117"
+       y="152.05809"
+       id="tspan32">sink media</tspan>
+    <tspan
+       x="6.938117"
+       y="168.05809"
+       id="tspan34">bus format</tspan>
+  </text>
+  <g
+     id="g36"
+     transform="translate(-1.6002426,-5.8559115)">
+    <rect
+       style="fill:#ffffff"
+       x="333.64401"
+       y="185.64999"
+       width="165.2"
+       height="172.478"
+       id="rect38" />
+    <rect
+       style="fill:none;fill-opacity:0;stroke:#00ff00;stroke-width:2"
+       x="333.64401"
+       y="185.64999"
+       width="165.2"
+       height="172.478"
+       id="rect40" />
+  </g>
+  <line
+     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
+     x1="332.04376"
+     y1="352.27206"
+     x2="47.899757"
+     y2="275.14407"
+     id="line42" />
+  <line
+     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
+     x1="332.04376"
+     y1="179.79408"
+     x2="47.899757"
+     y2="198.14409"
+     id="line44" />
+  <line
+     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
+     x1="497.24374"
+     y1="352.27206"
+     x2="141.89977"
+     y2="275.14407"
+     id="line46" />
+  <line
+     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
+     x1="497.24374"
+     y1="179.79408"
+     x2="141.89977"
+     y2="198.14409"
+     id="line48" />
+  <text
+     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#00ff00"
+     x="333.10376"
+     y="143.58609"
+     id="text50">
+    <tspan
+       x="333.10376"
+       y="143.58609"
+       id="tspan52">sink compose</tspan>
+    <tspan
+       x="333.10376"
+       y="159.58609"
+       id="tspan54">selection (scaling)</tspan>
+  </text>
+  <g
+     id="g56"
+     transform="translate(-1.6002426,-5.8559115)">
+    <rect
+       style="fill:#ffffff"
+       x="382.32199"
+       y="199.565"
+       width="100.186"
+       height="71.452301"
+       id="rect58" />
+    <rect
+       style="fill:none;fill-opacity:0;stroke:#a020f0;stroke-width:2"
+       x="382.32199"
+       y="199.565"
+       width="100.186"
+       height="71.452301"
+       id="rect60" />
+  </g>
+  <text
+     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#a020f0"
+     x="541.7218"
+     y="143.58609"
+     id="text62">
+    <tspan
+       x="541.7218"
+       y="143.58609"
+       id="tspan64">source</tspan>
+    <tspan
+       x="541.7218"
+       y="159.58609"
+       id="tspan66">crop</tspan>
+    <tspan
+       x="541.7218"
+       y="175.58609"
+       id="tspan68">selection</tspan>
+  </text>
+  <text
+     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#8b6914"
+     x="689.89978"
+     y="151.27209"
+     id="text70">
+    <tspan
+       x="689.89978"
+       y="151.27209"
+       id="tspan72">source media</tspan>
+    <tspan
+       x="689.89978"
+       y="167.27209"
+       id="tspan74">bus format</tspan>
+  </text>
+  <g
+     id="g76"
+     transform="translate(-1.6002426,-5.8559115)">
+    <rect
+       style="fill:#ffffff"
+       x="690.48798"
+       y="225.834"
+       width="100.186"
+       height="71.452301"
+       id="rect78" />
+    <rect
+       style="fill:none;fill-opacity:0;stroke:#8b6914;stroke-width:2"
+       x="690.48798"
+       y="225.834"
+       width="100.186"
+       height="71.452301"
+       id="rect80" />
+  </g>
+  <line
+     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
+     x1="688.88776"
+     y1="291.43008"
+     x2="380.72174"
+     y2="265.16208"
+     id="line82" />
+  <line
+     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
+     x1="688.88776"
+     y1="219.97809"
+     x2="380.72174"
+     y2="193.70909"
+     id="line84" />
+  <line
+     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
+     x1="789.07379"
+     y1="291.43008"
+     x2="480.90775"
+     y2="265.16208"
+     id="line86" />
+  <line
+     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
+     x1="789.07379"
+     y1="219.97809"
+     x2="480.90775"
+     y2="193.70909"
+     id="line88" />
+  <g
+     id="g90"
+     transform="translate(-1.6002426,-5.8559115)">
+    <circle
+       style="fill:#ffffff"
+       cx="808.09998"
+       cy="249.98399"
+       id="ellipse92"
+       r="8.5" />
+    <circle
+       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+       cx="808.09998"
+       cy="249.98399"
+       id="ellipse94"
+       r="8.5" />
+    <circle
+       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+       cx="808.09998"
+       cy="249.98399"
+       id="ellipse96"
+       r="8.5" />
+  </g>
+  <g
+     id="g98"
+     transform="translate(-1.6002426,-5.8559115)">
+    <line
+       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+       x1="816.59998"
+       y1="249.98399"
+       x2="972.93402"
+       y2="250.01199"
+       id="line100" />
+    <polygon
+       style="fill:#000000"
+       points="970.435,245.012 980.434,250.014 970.433,255.012 972.934,250.012 "
+       id="polygon102" />
+    <polygon
+       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+       points="970.435,245.012 980.434,250.014 970.433,255.012 972.934,250.012 "
+       id="polygon104" />
+  </g>
+  <text
+     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#000000"
+     x="840.3078"
+     y="233.94409"
+     id="text106">
+    <tspan
+       x="840.3078"
+       y="233.94409"
+       id="tspan108">pad 1 (source)</tspan>
+  </text>
+  <g
+     id="g110"
+     transform="translate(-1.6002426,-5.8559115)">
+    <circle
+       style="fill:#ffffff"
+       cx="-20.398199"
+       cy="241.51199"
+       id="ellipse112"
+       r="8.5" />
+    <circle
+       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+       cx="-20.398199"
+       cy="241.51199"
+       id="ellipse114"
+       r="8.5" />
+    <circle
+       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+       cx="-20.398199"
+       cy="241.51199"
+       id="ellipse116"
+       r="8.5" />
+  </g>
+  <g
+     id="g118"
+     transform="translate(-1.6002426,-5.8559115)">
+    <line
+       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+       x1="-192.39799"
+       y1="241.8"
+       x2="-38.6343"
+       y2="241.52901"
+       id="line120" />
+    <polygon
+       style="fill:#000000"
+       points="-41.1431,236.534 -31.1343,241.516 -41.1254,246.534 -38.6343,241.529 "
+       id="polygon122" />
+    <polygon
+       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+       points="-41.1431,236.534 -31.1343,241.516 -41.1254,246.534 -38.6343,241.529 "
+       id="polygon124" />
+  </g>
+  <text
+     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#000000"
+     x="-149.45824"
+     y="223.94409"
+     id="text126">
+    <tspan
+       x="-149.45824"
+       y="223.94409"
+       id="tspan128">pad 0 (sink)</tspan>
+  </text>
+  <rect
+     style="fill:none;fill-opacity:0;stroke:#a020f0;stroke-width:2"
+     x="388.22174"
+     y="270.81006"
+     width="100.186"
+     height="71.452301"
+     id="rect130" />
+  <g
+     id="g132"
+     transform="translate(-1.6002426,-5.8559115)">
+    <rect
+       style="fill:#ffffff"
+       x="689.98798"
+       y="345.93399"
+       width="100.186"
+       height="71.452301"
+       id="rect134" />
+    <rect
+       style="fill:none;fill-opacity:0;stroke:#8b6914;stroke-width:2"
+       x="689.98798"
+       y="345.93399"
+       width="100.186"
+       height="71.452301"
+       id="rect136" />
+  </g>
+  <line
+     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
+     x1="688.38776"
+     y1="411.53006"
+     x2="388.22174"
+     y2="342.26208"
+     id="line138" />
+  <line
+     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
+     x1="688.38776"
+     y1="340.07806"
+     x2="388.22174"
+     y2="270.81006"
+     id="line140" />
+  <line
+     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
+     x1="788.57379"
+     y1="411.53006"
+     x2="488.40775"
+     y2="342.26208"
+     id="line142" />
+  <line
+     style="fill:none;fill-opacity:0;stroke:#e60505;stroke-width:2;stroke-dasharray:4"
+     x1="788.57379"
+     y1="340.07806"
+     x2="488.40775"
+     y2="270.81006"
+     id="line144" />
+  <g
+     id="g146"
+     transform="translate(-1.6002426,-5.8559115)">
+    <circle
+       style="fill:#ffffff"
+       cx="805.59998"
+       cy="384.08401"
+       id="ellipse148"
+       r="8.5" />
+    <circle
+       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+       cx="805.59998"
+       cy="384.08401"
+       id="ellipse150"
+       r="8.5" />
+    <circle
+       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+       cx="805.59998"
+       cy="384.08401"
+       id="ellipse152"
+       r="8.5" />
+  </g>
+  <g
+     id="g154"
+     transform="translate(-1.6002426,-5.8559115)">
+    <line
+       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+       x1="814.09998"
+       y1="384.08401"
+       x2="970.43402"
+       y2="384.112"
+       id="line156" />
+    <polygon
+       style="fill:#000000"
+       points="967.935,379.112 977.934,384.114 967.933,389.112 970.434,384.112 "
+       id="polygon158" />
+    <polygon
+       style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:2"
+       points="967.935,379.112 977.934,384.114 967.933,389.112 970.434,384.112 "
+       id="polygon160" />
+  </g>
+  <text
+     style="font-style:normal;font-weight:normal;font-size:12.80000019px;font-family:sanserif;text-anchor:start;fill:#000000"
+     x="837.8078"
+     y="368.04407"
+     id="text162">
+    <tspan
+       x="837.8078"
+       y="368.04407"
+       id="tspan164">pad 2 (source)</tspan>
+  </text>
+  <g
+     id="g166"
+     transform="translate(-1.6002426,-5.8559115)">
+    <line
+       style="fill:none;fill-opacity:0;stroke:#a020f0;stroke-width:2"
+       x1="546"
+       y1="191"
+       x2="492.15701"
+       y2="198.263"
+       id="line168" />
+    <polygon
+       style="fill:#a020f0"
+       points="495.303,202.884 484.724,199.266 493.966,192.974 492.157,198.263 "
+       id="polygon170" />
+    <polygon
+       style="fill:none;fill-opacity:0;stroke:#a020f0;stroke-width:2"
+       points="495.303,202.884 484.724,199.266 493.966,192.974 492.157,198.263 "
+       id="polygon172" />
+  </g>
+  <g
+     id="g174"
+     transform="translate(-1.6002426,-5.8559115)">
+    <line
+       style="fill:none;fill-opacity:0;stroke:#a020f0;stroke-width:2"
+       x1="546.90802"
+       y1="190.72501"
+       x2="495.383"
+       y2="268.548"
+       id="line176" />
+    <polygon
+       style="fill:#a020f0"
+       points="500.932,269.224 491.242,274.802 492.594,263.703 495.383,268.548 "
+       id="polygon178" />
+    <polygon
+       style="fill:none;fill-opacity:0;stroke:#a020f0;stroke-width:2"
+       points="500.932,269.224 491.242,274.802 492.594,263.703 495.383,268.548 "
+       id="polygon180" />
+  </g>
+</svg>
diff --git a/Documentation/userspace-api/media/v4l/tch-formats.rst b/Documentation/userspace-api/media/v4l/tch-formats.rst
new file mode 100644
index 000000000000..f83aec85fd76
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/tch-formats.rst
@@ -0,0 +1,25 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _tch-formats:
+
+*************
+Touch Formats
+*************
+
+These formats are used for :ref:`touch` interface only.
+
+
+.. toctree::
+    :maxdepth: 1
+
+    pixfmt-tch-td16
+    pixfmt-tch-td08
+    pixfmt-tch-tu16
+    pixfmt-tch-tu08
diff --git a/Documentation/userspace-api/media/v4l/tuner.rst b/Documentation/userspace-api/media/v4l/tuner.rst
new file mode 100644
index 000000000000..02a396eb6613
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/tuner.rst
@@ -0,0 +1,92 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _tuner:
+
+*********************
+Tuners and Modulators
+*********************
+
+
+Tuners
+======
+
+Video input devices can have one or more tuners demodulating a RF
+signal. Each tuner is associated with one or more video inputs,
+depending on the number of RF connectors on the tuner. The ``type``
+field of the respective struct :c:type:`v4l2_input`
+returned by the :ref:`VIDIOC_ENUMINPUT` ioctl is
+set to ``V4L2_INPUT_TYPE_TUNER`` and its ``tuner`` field contains the
+index number of the tuner.
+
+Radio input devices have exactly one tuner with index zero, no video
+inputs.
+
+To query and change tuner properties applications use the
+:ref:`VIDIOC_G_TUNER <VIDIOC_G_TUNER>` and
+:ref:`VIDIOC_S_TUNER <VIDIOC_G_TUNER>` ioctls, respectively. The
+struct :c:type:`v4l2_tuner` returned by :ref:`VIDIOC_G_TUNER <VIDIOC_G_TUNER>`
+also contains signal status information applicable when the tuner of the
+current video or radio input is queried.
+
+.. note::
+
+   :ref:`VIDIOC_S_TUNER <VIDIOC_G_TUNER>` does not switch the
+   current tuner, when there is more than one. The tuner is solely
+   determined by the current video input. Drivers must support both ioctls
+   and set the ``V4L2_CAP_TUNER`` flag in the struct :c:type:`v4l2_capability`
+   returned by the :ref:`VIDIOC_QUERYCAP` ioctl when the
+   device has one or more tuners.
+
+
+Modulators
+==========
+
+Video output devices can have one or more modulators, that modulate a
+video signal for radiation or connection to the antenna input of a TV
+set or video recorder. Each modulator is associated with one or more
+video outputs, depending on the number of RF connectors on the
+modulator. The ``type`` field of the respective struct
+:c:type:`v4l2_output` returned by the
+:ref:`VIDIOC_ENUMOUTPUT` ioctl is set to
+``V4L2_OUTPUT_TYPE_MODULATOR`` and its ``modulator`` field contains the
+index number of the modulator.
+
+Radio output devices have exactly one modulator with index zero, no
+video outputs.
+
+A video or radio device cannot support both a tuner and a modulator. Two
+separate device nodes will have to be used for such hardware, one that
+supports the tuner functionality and one that supports the modulator
+functionality. The reason is a limitation with the
+:ref:`VIDIOC_S_FREQUENCY <VIDIOC_G_FREQUENCY>` ioctl where you
+cannot specify whether the frequency is for a tuner or a modulator.
+
+To query and change modulator properties applications use the
+:ref:`VIDIOC_G_MODULATOR <VIDIOC_G_MODULATOR>` and
+:ref:`VIDIOC_S_MODULATOR <VIDIOC_G_MODULATOR>` ioctl. Note that
+:ref:`VIDIOC_S_MODULATOR <VIDIOC_G_MODULATOR>` does not switch the current modulator, when there
+is more than one at all. The modulator is solely determined by the
+current video output. Drivers must support both ioctls and set the
+``V4L2_CAP_MODULATOR`` flag in the struct
+:c:type:`v4l2_capability` returned by the
+:ref:`VIDIOC_QUERYCAP` ioctl when the device has
+one or more modulators.
+
+
+Radio Frequency
+===============
+
+To get and set the tuner or modulator radio frequency applications use
+the :ref:`VIDIOC_G_FREQUENCY <VIDIOC_G_FREQUENCY>` and
+:ref:`VIDIOC_S_FREQUENCY <VIDIOC_G_FREQUENCY>` ioctl which both take
+a pointer to a struct :c:type:`v4l2_frequency`. These
+ioctls are used for TV and radio devices alike. Drivers must support
+both ioctls when the tuner or modulator ioctls are supported, or when
+the device is a radio device.
diff --git a/Documentation/userspace-api/media/v4l/user-func.rst b/Documentation/userspace-api/media/v4l/user-func.rst
new file mode 100644
index 000000000000..f235f88efe89
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/user-func.rst
@@ -0,0 +1,88 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _user-func:
+
+******************
+Function Reference
+******************
+
+
+.. toctree::
+    :maxdepth: 1
+
+    func-close
+    func-ioctl
+    vidioc-create-bufs
+    vidioc-cropcap
+    vidioc-dbg-g-chip-info
+    vidioc-dbg-g-register
+    vidioc-decoder-cmd
+    vidioc-dqevent
+    vidioc-dv-timings-cap
+    vidioc-encoder-cmd
+    vidioc-enumaudio
+    vidioc-enumaudioout
+    vidioc-enum-dv-timings
+    vidioc-enum-fmt
+    vidioc-enum-framesizes
+    vidioc-enum-frameintervals
+    vidioc-enum-freq-bands
+    vidioc-enuminput
+    vidioc-enumoutput
+    vidioc-enumstd
+    vidioc-expbuf
+    vidioc-g-audio
+    vidioc-g-audioout
+    vidioc-g-crop
+    vidioc-g-ctrl
+    vidioc-g-dv-timings
+    vidioc-g-edid
+    vidioc-g-enc-index
+    vidioc-g-ext-ctrls
+    vidioc-g-fbuf
+    vidioc-g-fmt
+    vidioc-g-frequency
+    vidioc-g-input
+    vidioc-g-jpegcomp
+    vidioc-g-modulator
+    vidioc-g-output
+    vidioc-g-parm
+    vidioc-g-priority
+    vidioc-g-selection
+    vidioc-g-sliced-vbi-cap
+    vidioc-g-std
+    vidioc-g-tuner
+    vidioc-log-status
+    vidioc-overlay
+    vidioc-prepare-buf
+    vidioc-qbuf
+    vidioc-querybuf
+    vidioc-querycap
+    vidioc-queryctrl
+    vidioc-query-dv-timings
+    vidioc-querystd
+    vidioc-reqbufs
+    vidioc-s-hw-freq-seek
+    vidioc-streamon
+    vidioc-subdev-enum-frame-interval
+    vidioc-subdev-enum-frame-size
+    vidioc-subdev-enum-mbus-code
+    vidioc-subdev-g-crop
+    vidioc-subdev-g-fmt
+    vidioc-subdev-g-frame-interval
+    vidioc-subdev-g-selection
+    vidioc-subscribe-event
+    func-mmap
+    func-munmap
+    func-open
+    func-poll
+    func-read
+    func-select
+    func-write
diff --git a/Documentation/userspace-api/media/v4l/userp.rst b/Documentation/userspace-api/media/v4l/userp.rst
new file mode 100644
index 000000000000..2d0fa7353066
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/userp.rst
@@ -0,0 +1,128 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _userp:
+
+*****************************
+Streaming I/O (User Pointers)
+*****************************
+
+Input and output devices support this I/O method when the
+``V4L2_CAP_STREAMING`` flag in the ``capabilities`` field of struct
+:c:type:`v4l2_capability` returned by the
+:ref:`VIDIOC_QUERYCAP` ioctl is set. If the
+particular user pointer method (not only memory mapping) is supported
+must be determined by calling the :ref:`VIDIOC_REQBUFS` ioctl
+with the memory type set to ``V4L2_MEMORY_USERPTR``.
+
+This I/O method combines advantages of the read/write and memory mapping
+methods. Buffers (planes) are allocated by the application itself, and
+can reside for example in virtual or shared memory. Only pointers to
+data are exchanged, these pointers and meta-information are passed in
+struct :c:type:`v4l2_buffer` (or in struct
+:c:type:`v4l2_plane` in the multi-planar API case). The
+driver must be switched into user pointer I/O mode by calling the
+:ref:`VIDIOC_REQBUFS` with the desired buffer type.
+No buffers (planes) are allocated beforehand, consequently they are not
+indexed and cannot be queried like mapped buffers with the
+:ref:`VIDIOC_QUERYBUF <VIDIOC_QUERYBUF>` ioctl.
+
+Example: Initiating streaming I/O with user pointers
+====================================================
+
+.. code-block:: c
+
+    struct v4l2_requestbuffers reqbuf;
+
+    memset (&reqbuf, 0, sizeof (reqbuf));
+    reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+    reqbuf.memory = V4L2_MEMORY_USERPTR;
+
+    if (ioctl (fd, VIDIOC_REQBUFS, &reqbuf) == -1) {
+	if (errno == EINVAL)
+	    printf ("Video capturing or user pointer streaming is not supported\\n");
+	else
+	    perror ("VIDIOC_REQBUFS");
+
+	exit (EXIT_FAILURE);
+    }
+
+Buffer (plane) addresses and sizes are passed on the fly with the
+:ref:`VIDIOC_QBUF <VIDIOC_QBUF>` ioctl. Although buffers are commonly
+cycled, applications can pass different addresses and sizes at each
+:ref:`VIDIOC_QBUF <VIDIOC_QBUF>` call. If required by the hardware the
+driver swaps memory pages within physical memory to create a continuous
+area of memory. This happens transparently to the application in the
+virtual memory subsystem of the kernel. When buffer pages have been
+swapped out to disk they are brought back and finally locked in physical
+memory for DMA. [#f1]_
+
+Filled or displayed buffers are dequeued with the
+:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl. The driver can unlock the
+memory pages at any time between the completion of the DMA and this
+ioctl. The memory is also unlocked when
+:ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` is called,
+:ref:`VIDIOC_REQBUFS`, or when the device is closed.
+Applications must take care not to free buffers without dequeuing.
+Firstly, the buffers remain locked for longer, wasting physical memory.
+Secondly the driver will not be notified when the memory is returned to
+the application's free list and subsequently reused for other purposes,
+possibly completing the requested DMA and overwriting valuable data.
+
+For capturing applications it is customary to enqueue a number of empty
+buffers, to start capturing and enter the read loop. Here the
+application waits until a filled buffer can be dequeued, and re-enqueues
+the buffer when the data is no longer needed. Output applications fill
+and enqueue buffers, when enough buffers are stacked up output is
+started. In the write loop, when the application runs out of free
+buffers it must wait until an empty buffer can be dequeued and reused.
+Two methods exist to suspend execution of the application until one or
+more buffers can be dequeued. By default :ref:`VIDIOC_DQBUF
+<VIDIOC_QBUF>` blocks when no buffer is in the outgoing queue. When the
+``O_NONBLOCK`` flag was given to the :ref:`open() <func-open>` function,
+:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` returns immediately with an ``EAGAIN``
+error code when no buffer is available. The :ref:`select()
+<func-select>` or :ref:`poll() <func-poll>` function are always
+available.
+
+To start and stop capturing or output applications call the
+:ref:`VIDIOC_STREAMON <VIDIOC_STREAMON>` and
+:ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` ioctl.
+
+.. note::
+
+   :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` removes all buffers from
+   both queues and unlocks all buffers as a side effect. Since there is no
+   notion of doing anything "now" on a multitasking system, if an
+   application needs to synchronize with another event it should examine
+   the struct :c:type:`v4l2_buffer` ``timestamp`` of captured or
+   outputted buffers.
+
+Drivers implementing user pointer I/O must support the
+:ref:`VIDIOC_REQBUFS <VIDIOC_REQBUFS>`, :ref:`VIDIOC_QBUF <VIDIOC_QBUF>`,
+:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>`, :ref:`VIDIOC_STREAMON <VIDIOC_STREAMON>`
+and :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` ioctls, the
+:ref:`select() <func-select>` and :ref:`poll() <func-poll>` function. [#f2]_
+
+.. [#f1]
+   We expect that frequently used buffers are typically not swapped out.
+   Anyway, the process of swapping, locking or generating scatter-gather
+   lists may be time consuming. The delay can be masked by the depth of
+   the incoming buffer queue, and perhaps by maintaining caches assuming
+   a buffer will be soon enqueued again. On the other hand, to optimize
+   memory usage drivers can limit the number of buffers locked in
+   advance and recycle the most recently used buffers first. Of course,
+   the pages of empty buffers in the incoming queue need not be saved to
+   disk. Output buffers must be saved on the incoming and outgoing queue
+   because an application may share them with other processes.
+
+.. [#f2]
+   At the driver level :ref:`select() <func-select>` and :ref:`poll() <func-poll>` are
+   the same, and :ref:`select() <func-select>` is too important to be optional.
+   The rest should be evident.
diff --git a/Documentation/userspace-api/media/v4l/v4l2-selection-flags.rst b/Documentation/userspace-api/media/v4l/v4l2-selection-flags.rst
new file mode 100644
index 000000000000..5c6f351b2443
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/v4l2-selection-flags.rst
@@ -0,0 +1,51 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _v4l2-selection-flags:
+
+***************
+Selection flags
+***************
+
+.. tabularcolumns:: |p{5.2cm}|p{2.0cm}|p{6.5cm}|p{1.2cm}|p{1.6cm}|
+
+.. _v4l2-selection-flags-table:
+
+.. flat-table:: Selection flag definitions
+    :header-rows:  1
+    :stub-columns: 0
+
+    * - Flag name
+      - id
+      - Definition
+      - Valid for V4L2
+      - Valid for V4L2 subdev
+    * - ``V4L2_SEL_FLAG_GE``
+      - (1 << 0)
+      - Suggest the driver it should choose greater or equal rectangle (in
+	size) than was requested. Albeit the driver may choose a lesser
+	size, it will only do so due to hardware limitations. Without this
+	flag (and ``V4L2_SEL_FLAG_LE``) the behaviour is to choose the
+	closest possible rectangle.
+      - Yes
+      - Yes
+    * - ``V4L2_SEL_FLAG_LE``
+      - (1 << 1)
+      - Suggest the driver it should choose lesser or equal rectangle (in
+	size) than was requested. Albeit the driver may choose a greater
+	size, it will only do so due to hardware limitations.
+      - Yes
+      - Yes
+    * - ``V4L2_SEL_FLAG_KEEP_CONFIG``
+      - (1 << 2)
+      - The configuration must not be propagated to any further processing
+	steps. If this flag is not given, the configuration is propagated
+	inside the subdevice to all further processing steps.
+      - No
+      - Yes
diff --git a/Documentation/userspace-api/media/v4l/v4l2-selection-targets.rst b/Documentation/userspace-api/media/v4l/v4l2-selection-targets.rst
new file mode 100644
index 000000000000..69f500093aa2
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/v4l2-selection-targets.rst
@@ -0,0 +1,78 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _v4l2-selection-targets:
+
+*****************
+Selection targets
+*****************
+
+The precise meaning of the selection targets may be dependent on which
+of the two interfaces they are used.
+
+
+.. _v4l2-selection-targets-table:
+
+.. tabularcolumns:: |p{6.0cm}|p{1.4cm}|p{7.4cm}|p{1.2cm}|p{1.4cm}|
+
+.. flat-table:: Selection target definitions
+    :header-rows:  1
+    :stub-columns: 0
+
+    * - Target name
+      - id
+      - Definition
+      - Valid for V4L2
+      - Valid for V4L2 subdev
+    * - ``V4L2_SEL_TGT_CROP``
+      - 0x0000
+      - Crop rectangle. Defines the cropped area.
+      - Yes
+      - Yes
+    * - ``V4L2_SEL_TGT_CROP_DEFAULT``
+      - 0x0001
+      - Suggested cropping rectangle that covers the "whole picture".
+        This includes only active pixels and excludes other non-active
+        pixels such as black pixels.
+      - Yes
+      - Yes
+    * - ``V4L2_SEL_TGT_CROP_BOUNDS``
+      - 0x0002
+      - Bounds of the crop rectangle. All valid crop rectangles fit inside
+	the crop bounds rectangle.
+      - Yes
+      - Yes
+    * - ``V4L2_SEL_TGT_NATIVE_SIZE``
+      - 0x0003
+      - The native size of the device, e.g. a sensor's pixel array.
+	``left`` and ``top`` fields are zero for this target.
+      - Yes
+      - Yes
+    * - ``V4L2_SEL_TGT_COMPOSE``
+      - 0x0100
+      - Compose rectangle. Used to configure scaling and composition.
+      - Yes
+      - Yes
+    * - ``V4L2_SEL_TGT_COMPOSE_DEFAULT``
+      - 0x0101
+      - Suggested composition rectangle that covers the "whole picture".
+      - Yes
+      - No
+    * - ``V4L2_SEL_TGT_COMPOSE_BOUNDS``
+      - 0x0102
+      - Bounds of the compose rectangle. All valid compose rectangles fit
+	inside the compose bounds rectangle.
+      - Yes
+      - Yes
+    * - ``V4L2_SEL_TGT_COMPOSE_PADDED``
+      - 0x0103
+      - The active area and all padding pixels that are inserted or
+	modified by hardware.
+      - Yes
+      - No
diff --git a/Documentation/userspace-api/media/v4l/v4l2.rst b/Documentation/userspace-api/media/v4l/v4l2.rst
new file mode 100644
index 000000000000..ab7c97c39b97
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/v4l2.rst
@@ -0,0 +1,423 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. include:: <isonum.txt>
+.. _v4l2spec:
+
+############################
+Part I - Video for Linux API
+############################
+
+This part describes the Video for Linux API version 2 (V4L2 API) specification.
+
+**Revision 4.5**
+
+.. only:: html
+
+   .. class:: toc-title
+
+        Table of Contents
+
+.. toctree::
+    :numbered:
+    :maxdepth: 5
+
+    common
+    pixfmt
+    io
+    devices
+    libv4l
+    compat
+    user-func
+    common-defs
+    videodev
+    capture-example
+    v4l2grab-example
+    biblio
+
+
+**********************
+Revision and Copyright
+**********************
+
+Authors, in alphabetical order:
+
+- Ailus, Sakari <sakari.ailus@iki.fi>
+
+  - Subdev selections API.
+
+- Carvalho Chehab, Mauro <mchehab+samsung@kernel.org>
+
+  - Documented libv4l, designed and added v4l2grab example, Remote Controller chapter.
+
+- Dirks, Bill
+
+  - Original author of the V4L2 API and documentation.
+
+- Figa, Tomasz <tfiga@chromium.org>
+
+  - Documented the memory-to-memory decoder interface.
+
+- H Schimek, Michael <mschimek@gmx.at>
+
+  - Original author of the V4L2 API and documentation.
+
+- Karicheri, Muralidharan <m-karicheri2@ti.com>
+
+  - Documented the Digital Video timings API.
+
+- Osciak, Pawel <posciak@chromium.org>
+
+  - Documented the memory-to-memory decoder interface.
+
+- Osciak, Pawel <pawel@osciak.com>
+
+  - Designed and documented the multi-planar API.
+
+- Palosaari, Antti <crope@iki.fi>
+
+  - SDR API.
+
+- Ribalda, Ricardo
+
+  - Introduce HSV formats and other minor changes.
+
+- Rubli, Martin
+
+  - Designed and documented the VIDIOC_ENUM_FRAMESIZES and VIDIOC_ENUM_FRAMEINTERVALS ioctls.
+
+- Walls, Andy <awalls@md.metrocast.net>
+
+  - Documented the fielded V4L2_MPEG_STREAM_VBI_FMT_IVTV MPEG stream embedded, sliced VBI data format in this specification.
+
+- Verkuil, Hans <hverkuil@xs4all.nl>
+
+  - Designed and documented the VIDIOC_LOG_STATUS ioctl, the extended control ioctls, major parts of the sliced VBI API, the MPEG encoder and decoder APIs and the DV Timings API.
+
+**Copyright** |copy| 1999-2018: Bill Dirks, Michael H. Schimek, Hans Verkuil, Martin Rubli, Andy Walls, Muralidharan Karicheri, Mauro Carvalho Chehab, Pawel Osciak, Sakari Ailus & Antti Palosaari, Tomasz Figa
+
+Except when explicitly stated as GPL, programming examples within this
+part can be used and distributed without restrictions.
+
+****************
+Revision History
+****************
+
+:revision: 4.10 / 2016-07-15 (*rr*)
+
+Introduce HSV formats.
+
+
+:revision: 4.5 / 2015-10-29 (*rr*)
+
+Extend VIDIOC_G_EXT_CTRLS;. Replace ctrl_class with a new union with
+ctrl_class and which. Which is used to select the current value of the
+control or the default value.
+
+
+:revision: 4.4 / 2015-05-26 (*ap*)
+
+Renamed V4L2_TUNER_ADC to V4L2_TUNER_SDR. Added
+V4L2_CID_RF_TUNER_RF_GAIN control. Added transmitter support for
+Software Defined Radio (SDR) Interface.
+
+
+:revision: 4.1 / 2015-02-13 (*mcc*)
+
+Fix documentation for media controller device nodes and add support for
+DVB device nodes. Add support for Tuner sub-device.
+
+
+:revision: 3.19 / 2014-12-05 (*hv*)
+
+Rewrote Colorspace chapter, added new enum
+:c:type:`v4l2_ycbcr_encoding` and enum
+:c:type:`v4l2_quantization` fields to struct
+:c:type:`v4l2_pix_format`, struct
+:c:type:`v4l2_pix_format_mplane` and struct
+:c:type:`v4l2_mbus_framefmt`.
+
+
+:revision: 3.17 / 2014-08-04 (*lp, hv*)
+
+Extended struct :c:type:`v4l2_pix_format`. Added
+format flags. Added compound control types and VIDIOC_QUERY_EXT_CTRL.
+
+
+:revision: 3.15 / 2014-02-03 (*hv, ap*)
+
+Update several sections of "Common API Elements": "Opening and Closing
+Devices" "Querying Capabilities", "Application Priority", "Video Inputs
+and Outputs", "Audio Inputs and Outputs" "Tuners and Modulators", "Video
+Standards" and "Digital Video (DV) Timings". Added SDR API.
+
+
+:revision: 3.14 / 2013-11-25 (*rr*)
+
+Set width and height as unsigned on v4l2_rect.
+
+
+:revision: 3.11 / 2013-05-26 (*hv*)
+
+Remove obsolete VIDIOC_DBG_G_CHIP_IDENT ioctl.
+
+
+:revision: 3.10 / 2013-03-25 (*hv*)
+
+Remove obsolete and unused DV_PRESET ioctls: VIDIOC_G_DV_PRESET,
+VIDIOC_S_DV_PRESET, VIDIOC_QUERY_DV_PRESET and
+VIDIOC_ENUM_DV_PRESET. Remove the related v4l2_input/output
+capability flags V4L2_IN_CAP_PRESETS and V4L2_OUT_CAP_PRESETS.
+Added VIDIOC_DBG_G_CHIP_INFO.
+
+
+:revision: 3.9 / 2012-12-03 (*sa, sn*)
+
+Added timestamp types to v4l2_buffer. Added
+V4L2_EVENT_CTRL_CH_RANGE control event changes flag.
+
+
+:revision: 3.6 / 2012-07-02 (*hv*)
+
+Added VIDIOC_ENUM_FREQ_BANDS.
+
+
+:revision: 3.5 / 2012-05-07 (*sa, sn, hv*)
+
+Added V4L2_CTRL_TYPE_INTEGER_MENU and V4L2 subdev selections API.
+Improved the description of V4L2_CID_COLORFX control, added
+V4L2_CID_COLORFX_CBCR control. Added camera controls
+V4L2_CID_AUTO_EXPOSURE_BIAS,
+V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE,
+V4L2_CID_IMAGE_STABILIZATION, V4L2_CID_ISO_SENSITIVITY,
+V4L2_CID_ISO_SENSITIVITY_AUTO, V4L2_CID_EXPOSURE_METERING,
+V4L2_CID_SCENE_MODE, V4L2_CID_3A_LOCK,
+V4L2_CID_AUTO_FOCUS_START, V4L2_CID_AUTO_FOCUS_STOP,
+V4L2_CID_AUTO_FOCUS_STATUS and V4L2_CID_AUTO_FOCUS_RANGE. Added
+VIDIOC_ENUM_DV_TIMINGS, VIDIOC_QUERY_DV_TIMINGS and
+VIDIOC_DV_TIMINGS_CAP.
+
+
+:revision: 3.4 / 2012-01-25 (*sn*)
+
+Added :ref:`JPEG compression control class. <jpeg-controls>`
+
+
+:revision: 3.3 / 2012-01-11 (*hv*)
+
+Added device_caps field to struct v4l2_capabilities.
+
+
+:revision: 3.2 / 2011-08-26 (*hv*)
+
+Added V4L2_CTRL_FLAG_VOLATILE.
+
+
+:revision: 3.1 / 2011-06-27 (*mcc, po, hv*)
+
+Documented that VIDIOC_QUERYCAP now returns a per-subsystem version
+instead of a per-driver one. Standardize an error code for invalid
+ioctl. Added V4L2_CTRL_TYPE_BITMASK.
+
+
+:revision: 2.6.39 / 2011-03-01 (*mcc, po*)
+
+Removed VIDIOC_*_OLD from videodev2.h header and update it to reflect
+latest changes. Added the :ref:`multi-planar API <planar-apis>`.
+
+
+:revision: 2.6.37 / 2010-08-06 (*hv*)
+
+Removed obsolete vtx (videotext) API.
+
+
+:revision: 2.6.33 / 2009-12-03 (*mk*)
+
+Added documentation for the Digital Video timings API.
+
+
+:revision: 2.6.32 / 2009-08-31 (*mcc*)
+
+Now, revisions will match the kernel version where the V4L2 API changes
+will be used by the Linux Kernel. Also added Remote Controller chapter.
+
+
+:revision: 0.29 / 2009-08-26 (*ev*)
+
+Added documentation for string controls and for FM Transmitter controls.
+
+
+:revision: 0.28 / 2009-08-26 (*gl*)
+
+Added V4L2_CID_BAND_STOP_FILTER documentation.
+
+
+:revision: 0.27 / 2009-08-15 (*mcc*)
+
+Added libv4l and Remote Controller documentation; added v4l2grab and
+keytable application examples.
+
+
+:revision: 0.26 / 2009-07-23 (*hv*)
+
+Finalized the RDS capture API. Added modulator and RDS encoder
+capabilities. Added support for string controls.
+
+
+:revision: 0.25 / 2009-01-18 (*hv*)
+
+Added pixel formats VYUY, NV16 and NV61, and changed the debug ioctls
+VIDIOC_DBG_G/S_REGISTER and VIDIOC_DBG_G_CHIP_IDENT. Added camera
+controls V4L2_CID_ZOOM_ABSOLUTE, V4L2_CID_ZOOM_RELATIVE,
+V4L2_CID_ZOOM_CONTINUOUS and V4L2_CID_PRIVACY.
+
+
+:revision: 0.24 / 2008-03-04 (*mhs*)
+
+Added pixel formats Y16 and SBGGR16, new controls and a camera controls
+class. Removed VIDIOC_G/S_MPEGCOMP.
+
+
+:revision: 0.23 / 2007-08-30 (*mhs*)
+
+Fixed a typo in VIDIOC_DBG_G/S_REGISTER. Clarified the byte order of
+packed pixel formats.
+
+
+:revision: 0.22 / 2007-08-29 (*mhs*)
+
+Added the Video Output Overlay interface, new MPEG controls,
+V4L2_FIELD_INTERLACED_TB and V4L2_FIELD_INTERLACED_BT,
+VIDIOC_DBG_G/S_REGISTER, VIDIOC\_(TRY\_)ENCODER_CMD,
+VIDIOC_G_CHIP_IDENT, VIDIOC_G_ENC_INDEX, new pixel formats.
+Clarifications in the cropping chapter, about RGB pixel formats, the
+mmap(), poll(), select(), read() and write() functions. Typographical
+fixes.
+
+
+:revision: 0.21 / 2006-12-19 (*mhs*)
+
+Fixed a link in the VIDIOC_G_EXT_CTRLS section.
+
+
+:revision: 0.20 / 2006-11-24 (*mhs*)
+
+Clarified the purpose of the audioset field in struct v4l2_input and
+v4l2_output.
+
+
+:revision: 0.19 / 2006-10-19 (*mhs*)
+
+Documented V4L2_PIX_FMT_RGB444.
+
+
+:revision: 0.18 / 2006-10-18 (*mhs*)
+
+Added the description of extended controls by Hans Verkuil. Linked
+V4L2_PIX_FMT_MPEG to V4L2_CID_MPEG_STREAM_TYPE.
+
+
+:revision: 0.17 / 2006-10-12 (*mhs*)
+
+Corrected V4L2_PIX_FMT_HM12 description.
+
+
+:revision: 0.16 / 2006-10-08 (*mhs*)
+
+VIDIOC_ENUM_FRAMESIZES and VIDIOC_ENUM_FRAMEINTERVALS are now part
+of the API.
+
+
+:revision: 0.15 / 2006-09-23 (*mhs*)
+
+Cleaned up the bibliography, added BT.653 and BT.1119.
+capture.c/start_capturing() for user pointer I/O did not initialize the
+buffer index. Documented the V4L MPEG and MJPEG VID_TYPEs and
+V4L2_PIX_FMT_SBGGR8. Updated the list of reserved pixel formats. See
+the history chapter for API changes.
+
+
+:revision: 0.14 / 2006-09-14 (*mr*)
+
+Added VIDIOC_ENUM_FRAMESIZES and VIDIOC_ENUM_FRAMEINTERVALS proposal
+for frame format enumeration of digital devices.
+
+
+:revision: 0.13 / 2006-04-07 (*mhs*)
+
+Corrected the description of struct v4l2_window clips. New V4L2_STD\_
+and V4L2_TUNER_MODE_LANG1_LANG2 defines.
+
+
+:revision: 0.12 / 2006-02-03 (*mhs*)
+
+Corrected the description of struct v4l2_captureparm and
+v4l2_outputparm.
+
+
+:revision: 0.11 / 2006-01-27 (*mhs*)
+
+Improved the description of struct v4l2_tuner.
+
+
+:revision: 0.10 / 2006-01-10 (*mhs*)
+
+VIDIOC_G_INPUT and VIDIOC_S_PARM clarifications.
+
+
+:revision: 0.9 / 2005-11-27 (*mhs*)
+
+Improved the 525 line numbering diagram. Hans Verkuil and I rewrote the
+sliced VBI section. He also contributed a VIDIOC_LOG_STATUS page.
+Fixed VIDIOC_S_STD call in the video standard selection example.
+Various updates.
+
+
+:revision: 0.8 / 2004-10-04 (*mhs*)
+
+Somehow a piece of junk slipped into the capture example, removed.
+
+
+:revision: 0.7 / 2004-09-19 (*mhs*)
+
+Fixed video standard selection, control enumeration, downscaling and
+aspect example. Added read and user pointer i/o to video capture
+example.
+
+
+:revision: 0.6 / 2004-08-01 (*mhs*)
+
+v4l2_buffer changes, added video capture example, various corrections.
+
+
+:revision: 0.5 / 2003-11-05 (*mhs*)
+
+Pixel format erratum.
+
+
+:revision: 0.4 / 2003-09-17 (*mhs*)
+
+Corrected source and Makefile to generate a PDF. SGML fixes. Added
+latest API changes. Closed gaps in the history chapter.
+
+
+:revision: 0.3 / 2003-02-05 (*mhs*)
+
+Another draft, more corrections.
+
+
+:revision: 0.2 / 2003-01-15 (*mhs*)
+
+Second draft, with corrections pointed out by Gerd Knorr.
+
+
+:revision: 0.1 / 2002-12-01 (*mhs*)
+
+First draft, based on documentation by Bill Dirks and discussions on the
+V4L mailing list.
diff --git a/Documentation/userspace-api/media/v4l/v4l2grab-example.rst b/Documentation/userspace-api/media/v4l/v4l2grab-example.rst
new file mode 100644
index 000000000000..270738876f72
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/v4l2grab-example.rst
@@ -0,0 +1,24 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _v4l2grab-example:
+
+**********************************
+Video Grabber example using libv4l
+**********************************
+
+This program demonstrates how to grab V4L2 images in ppm format by using
+libv4l handlers. The advantage is that this grabber can potentially work
+with any V4L2 driver.
+
+
+.. toctree::
+    :maxdepth: 1
+
+    v4l2grab.c
diff --git a/Documentation/userspace-api/media/v4l/v4l2grab.c.rst b/Documentation/userspace-api/media/v4l/v4l2grab.c.rst
new file mode 100644
index 000000000000..a21ff357a830
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/v4l2grab.c.rst
@@ -0,0 +1,176 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+file: media/v4l/v4l2grab.c
+==========================
+
+.. code-block:: c
+
+    /* V4L2 video picture grabber
+       Copyright (C) 2009 Mauro Carvalho Chehab <mchehab@kernel.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 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 <stdio.h>
+    #include <stdlib.h>
+    #include <string.h>
+    #include <fcntl.h>
+    #include <errno.h>
+    #include <sys/ioctl.h>
+    #include <sys/types.h>
+    #include <sys/time.h>
+    #include <sys/mman.h>
+    #include <linux/videodev2.h>
+    #include "../libv4l/include/libv4l2.h"
+
+    #define CLEAR(x) memset(&(x), 0, sizeof(x))
+
+    struct buffer {
+	    void   *start;
+	    size_t length;
+    };
+
+    static void xioctl(int fh, int request, void *arg)
+    {
+	    int r;
+
+	    do {
+		    r = v4l2_ioctl(fh, request, arg);
+	    } while (r == -1 && ((errno == EINTR) || (errno == EAGAIN)));
+
+	    if (r == -1) {
+		    fprintf(stderr, "error %d, %s\\n", errno, strerror(errno));
+		    exit(EXIT_FAILURE);
+	    }
+    }
+
+    int main(int argc, char **argv)
+    {
+	    struct v4l2_format              fmt;
+	    struct v4l2_buffer              buf;
+	    struct v4l2_requestbuffers      req;
+	    enum v4l2_buf_type              type;
+	    fd_set                          fds;
+	    struct timeval                  tv;
+	    int                             r, fd = -1;
+	    unsigned int                    i, n_buffers;
+	    char                            *dev_name = "/dev/video0";
+	    char                            out_name[256];
+	    FILE                            *fout;
+	    struct buffer                   *buffers;
+
+	    fd = v4l2_open(dev_name, O_RDWR | O_NONBLOCK, 0);
+	    if (fd < 0) {
+		    perror("Cannot open device");
+		    exit(EXIT_FAILURE);
+	    }
+
+	    CLEAR(fmt);
+	    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	    fmt.fmt.pix.width       = 640;
+	    fmt.fmt.pix.height      = 480;
+	    fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24;
+	    fmt.fmt.pix.field       = V4L2_FIELD_INTERLACED;
+	    xioctl(fd, VIDIOC_S_FMT, &fmt);
+	    if (fmt.fmt.pix.pixelformat != V4L2_PIX_FMT_RGB24) {
+		    printf("Libv4l didn't accept RGB24 format. Can't proceed.\\n");
+		    exit(EXIT_FAILURE);
+	    }
+	    if ((fmt.fmt.pix.width != 640) || (fmt.fmt.pix.height != 480))
+		    printf("Warning: driver is sending image at %dx%d\\n",
+			    fmt.fmt.pix.width, fmt.fmt.pix.height);
+
+	    CLEAR(req);
+	    req.count = 2;
+	    req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	    req.memory = V4L2_MEMORY_MMAP;
+	    xioctl(fd, VIDIOC_REQBUFS, &req);
+
+	    buffers = calloc(req.count, sizeof(*buffers));
+	    for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {
+		    CLEAR(buf);
+
+		    buf.type        = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		    buf.memory      = V4L2_MEMORY_MMAP;
+		    buf.index       = n_buffers;
+
+		    xioctl(fd, VIDIOC_QUERYBUF, &buf);
+
+		    buffers[n_buffers].length = buf.length;
+		    buffers[n_buffers].start = v4l2_mmap(NULL, buf.length,
+				  PROT_READ | PROT_WRITE, MAP_SHARED,
+				  fd, buf.m.offset);
+
+		    if (MAP_FAILED == buffers[n_buffers].start) {
+			    perror("mmap");
+			    exit(EXIT_FAILURE);
+		    }
+	    }
+
+	    for (i = 0; i < n_buffers; ++i) {
+		    CLEAR(buf);
+		    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		    buf.memory = V4L2_MEMORY_MMAP;
+		    buf.index = i;
+		    xioctl(fd, VIDIOC_QBUF, &buf);
+	    }
+	    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+	    xioctl(fd, VIDIOC_STREAMON, &type);
+	    for (i = 0; i < 20; i++) {
+		    do {
+			    FD_ZERO(&fds);
+			    FD_SET(fd, &fds);
+
+			    /* Timeout. */
+			    tv.tv_sec = 2;
+			    tv.tv_usec = 0;
+
+			    r = select(fd + 1, &fds, NULL, NULL, &tv);
+		    } while ((r == -1 && (errno = EINTR)));
+		    if (r == -1) {
+			    perror("select");
+			    return errno;
+		    }
+
+		    CLEAR(buf);
+		    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		    buf.memory = V4L2_MEMORY_MMAP;
+		    xioctl(fd, VIDIOC_DQBUF, &buf);
+
+		    sprintf(out_name, "out%03d.ppm", i);
+		    fout = fopen(out_name, "w");
+		    if (!fout) {
+			    perror("Cannot open image");
+			    exit(EXIT_FAILURE);
+		    }
+		    fprintf(fout, "P6\\n%d %d 255\\n",
+			    fmt.fmt.pix.width, fmt.fmt.pix.height);
+		    fwrite(buffers[buf.index].start, buf.bytesused, 1, fout);
+		    fclose(fout);
+
+		    xioctl(fd, VIDIOC_QBUF, &buf);
+	    }
+
+	    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	    xioctl(fd, VIDIOC_STREAMOFF, &type);
+	    for (i = 0; i < n_buffers; ++i)
+		    v4l2_munmap(buffers[i].start, buffers[i].length);
+	    v4l2_close(fd);
+
+	    return 0;
+    }
diff --git a/Documentation/userspace-api/media/v4l/vbi_525.svg b/Documentation/userspace-api/media/v4l/vbi_525.svg
new file mode 100644
index 000000000000..b7d09057617e
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vbi_525.svg
@@ -0,0 +1,821 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+    Permission is granted to copy, distribute and/or modify this
+    document under the terms of the GNU Free Documentation License,
+    Version 1.1 or any later version published by the Free Software
+    Foundation, with no Invariant Sections, no Front-Cover Texts
+    and no Back-Cover Texts. A copy of the license is included at
+    Documentation/userspace-api/media/fdl-appendix.rst.
+
+    TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+-->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.91 r13725"
+   xml:space="preserve"
+   width="208.73068mm"
+   height="51.395489mm"
+   viewBox="0 0 739.59691 182.11"
+   sodipodi:docname="vbi_525.svg"><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="997"
+     id="namedview4"
+     showgrid="false"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0"
+     inkscape:zoom="1.5350601"
+     inkscape:cx="264.23387"
+     inkscape:cy="44.916942"
+     inkscape:window-x="1920"
+     inkscape:window-y="30"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="g10"
+     units="mm" /><metadata
+     id="metadata8"><rdf:RDF><cc:Work
+	 rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+	   rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
+     id="defs6"><clipPath
+       id="clipPath20"
+       clipPathUnits="userSpaceOnUse"><path
+	 inkscape:connector-curvature="0"
+	 id="path22"
+	 d="m 0,0 5950,0 0,3922 L 0,3922 0,0 Z m 0,3922 5950,0 0,1 -5950,0 0,-1 z m 0,1 1359,0 0,1 -1359,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1363,0 0,1 -1363,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1367,0 0,1 -1367,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1371,0 0,1 -1371,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1375,0 0,1 -1375,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1379,0 0,1 -1379,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1383,0 0,1 -1383,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1387,0 0,1 -1387,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1391,0 0,1 -1391,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1390,0 0,1 -1390,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1386,0 0,1 -1386,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1382,0 0,1 -1382,0 0,-1 z m
+1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1378,0 0,1 -1378,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1374,0 0,1 -1374,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1370,0 0,1 -1370,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1366,0 0,1 -1366,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1362,0 0,1 -1362,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1358,0 0,1 -1358,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 5950,0 0,1 -5950,0 0,-1 z m 0,1 5950,0 0,4478 -5950,0 0,-4478 z" /></clipPath><clipPath
+       id="clipPath98"
+       clipPathUnits="userSpaceOnUse"><path
+	 inkscape:connector-curvature="0"
+	 id="path100"
+	 d="m 0,0 5950,0 0,4546 L 0,4546 0,0 Z m 0,4546 5950,0 0,1 -5950,0 0,-1 z m 0,1 1360,0 0,1 -1360,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1364,0 0,1 -1364,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1368,0 0,1 -1368,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1372,0 0,1 -1372,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1376,0 0,1 -1376,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1380,0 0,1 -1380,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1384,0 0,1 -1384,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1388,0 0,1 -1388,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1391,0 0,1 -1391,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1389,0 0,1 -1389,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1385,0 0,1 -1385,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1381,0 0,1 -1381,0 0,-1 z m
+1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1377,0 0,1 -1377,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1373,0 0,1 -1373,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1369,0 0,1 -1369,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1365,0 0,1 -1365,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1361,0 0,1 -1361,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1357,0 0,1 -1357,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 5950,0 0,1 -5950,0 0,-1 z m 0,1 5950,0 0,3854 -5950,0 0,-3854 z" /></clipPath></defs><g
+     transform="matrix(0.125,0,0,-0.125,-87.571875,638.05691)"
+     inkscape:label="vbi_525"
+     inkscape:groupmode="layer"
+     id="g10"><g
+       transform="matrix(1.3000026,0,0,1.3000026,-210.17435,-1094.2823)"
+       id="g12"
+       style=""><path
+	 inkscape:connector-curvature="0"
+	 id="path14"
+	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 1281.75,3974.45 0,-85.05" /></g><g
+       transform="matrix(1.3000026,0,0,1.3000026,-210.17435,-1094.2823)"
+       id="g16"
+       style=""><g
+	 clip-path="url(#clipPath20)"
+	 id="g18"
+	 style=""><path
+	   inkscape:connector-curvature="0"
+	   id="path24"
+	   style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	   d="m 1281.75,3931.93 113.4,0" /></g></g><g
+       transform="matrix(1.3000026,0,0,1.3000026,-210.17435,-1094.2823)"
+       id="g26"
+       style=""><path
+	 inkscape:connector-curvature="0"
+	 id="path28"
+	 style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+	 d="m 1352.31,3922.48 37.8,9.45 -37.8,9.45 0,-18.9" /><path
+	 inkscape:connector-curvature="0"
+	 id="path30"
+	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 1352.31,3922.48 37.8,9.45 -37.8,9.45 0,-18.9 z" /><path
+	 inkscape:connector-curvature="0"
+	 id="path32"
+	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 4683.75,4059.5 0,-56.7" /><path
+	 inkscape:connector-curvature="0"
+	 id="path34"
+	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 4400.25,4059.5 0,-56.7" /><path
+	 inkscape:connector-curvature="0"
+	 id="path36"
+	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 4116.75,4059.5 0,-56.7" /><path
+	 inkscape:connector-curvature="0"
+	 id="path38"
+	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 3833.25,4059.5 0,-56.7" /><path
+	 inkscape:connector-curvature="0"
+	 id="path40"
+	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 3549.75,4059.5 0,-56.7" /><path
+	 inkscape:connector-curvature="0"
+	 id="path42"
+	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 3266.25,4059.5 0,-56.7" /><path
+	 inkscape:connector-curvature="0"
+	 id="path44"
+	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 2982.75,4059.5 0,-56.7" /><path
+	 inkscape:connector-curvature="0"
+	 id="path46"
+	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 2699.25,4059.5 0,-56.7" /><path
+	 inkscape:connector-curvature="0"
+	 id="path48"
+	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 2415.75,4059.5 0,-56.7" /><path
+	 inkscape:connector-curvature="0"
+	 id="path50"
+	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 2132.25,4059.5 0,-56.7" /><path
+	 inkscape:connector-curvature="0"
+	 id="path52"
+	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 1848.75,4059.5 0,-56.7" /><path
+	 inkscape:connector-curvature="0"
+	 id="path54"
+	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 1565.25,4059.5 0,-56.7" /><path
+	 inkscape:connector-curvature="0"
+	 id="path56"
+	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 1281.75,4059.5 0,-56.7" /><path
+	 inkscape:connector-curvature="0"
+	 id="path58"
+	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 998.25,4059.5 0,-56.7" /><path
+	 inkscape:connector-curvature="0"
+	 id="path60"
+	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 714.75,4059.5 0,-56.7" /><path
+	 inkscape:connector-curvature="0"
+	 id="path62"
+	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 4683.75,4144.55 0,-56.7" /><path
+	 inkscape:connector-curvature="0"
+	 id="path64"
+	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 4400.25,4144.55 0,-56.7" /><path
+	 inkscape:connector-curvature="0"
+	 id="path66"
+	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 4116.75,4144.55 0,-56.7" /><path
+	 inkscape:connector-curvature="0"
+	 id="path68"
+	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 3833.25,4144.55 0,-56.7" /><path
+	 inkscape:connector-curvature="0"
+	 id="path70"
+	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 3549.75,4144.55 0,-56.7" /><path
+	 inkscape:connector-curvature="0"
+	 id="path72"
+	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 3266.25,4144.55 0,-56.7" /><path
+	 inkscape:connector-curvature="0"
+	 id="path74"
+	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 2982.75,4144.55 0,-56.7" /><path
+	 inkscape:connector-curvature="0"
+	 id="path76"
+	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 2699.25,4144.55 0,-56.7" /><path
+	 inkscape:connector-curvature="0"
+	 id="path78"
+	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 2415.75,4144.55 0,-56.7" /><path
+	 inkscape:connector-curvature="0"
+	 id="path80"
+	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 2132.25,4144.55 0,-56.7" /><path
+	 inkscape:connector-curvature="0"
+	 id="path82"
+	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 1848.75,4144.55 0,-56.7" /><path
+	 inkscape:connector-curvature="0"
+	 id="path84"
+	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 1565.25,4144.55 0,-56.7" /><path
+	 inkscape:connector-curvature="0"
+	 id="path86"
+	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 1281.75,4144.55 0,-56.7" /><path
+	 inkscape:connector-curvature="0"
+	 id="path88"
+	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 998.25,4144.55 0,-56.7" /><path
+	 inkscape:connector-curvature="0"
+	 id="path90"
+	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 714.75,4144.55 0,-56.7" /><path
+	 inkscape:connector-curvature="0"
+	 id="path92"
+	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 1281.75,4598.15 0,-85.05" /></g><g
+       transform="matrix(1.3000026,0,0,1.3000026,-210.17435,-1094.2823)"
+       id="g94"
+       style=""><g
+	 clip-path="url(#clipPath98)"
+	 id="g96"
+	 style=""><path
+	   inkscape:connector-curvature="0"
+	   id="path102"
+	   style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	   d="m 1281.75,4555.63 113.4,0" /></g></g><path
+       d="m 1547.8322,4815.7637 49.1401,12.2851 -49.1401,12.285 0,-24.5701"
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path106"
+       inkscape:connector-curvature="0" /><path
+       d="m 1547.8322,4815.7637 49.1401,12.2851 -49.1401,12.285 0,-24.5701 z"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path108"
+       inkscape:connector-curvature="0" /><path
+       d="m 1456.104,5104.4553 0,-73.7101"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path110"
+       inkscape:connector-curvature="0" /><path
+       d="m 1824.6548,5030.7452 0,73.7101"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path112"
+       inkscape:connector-curvature="0" /><path
+       d="m 2193.2055,5104.4553 0,-73.7101"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path114"
+       inkscape:connector-curvature="0" /><path
+       d="m 2561.7563,5104.4553 0,-73.7101"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path116"
+       inkscape:connector-curvature="0" /><path
+       d="m 2930.307,5104.4553 0,-73.7101"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path118"
+       inkscape:connector-curvature="0" /><path
+       d="m 3298.8578,5104.4553 0,-73.7101"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path120"
+       inkscape:connector-curvature="0" /><path
+       d="m 3667.4085,5104.4553 0,-73.7101"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path122"
+       inkscape:connector-curvature="0" /><path
+       d="m 4035.9593,5104.4553 0,-73.7101"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path124"
+       inkscape:connector-curvature="0" /><path
+       d="m 4404.51,5104.4553 0,-73.7101"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path126"
+       inkscape:connector-curvature="0" /><path
+       d="m 4773.0608,5104.4553 0,-73.7101"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path128"
+       inkscape:connector-curvature="0" /><path
+       d="m 5141.6115,5104.4553 0,-73.7101"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path130"
+       inkscape:connector-curvature="0" /><path
+       d="m 5510.1623,5104.4553 0,-73.7101"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path132"
+       inkscape:connector-curvature="0" /><path
+       d="m 5878.713,5104.4553 0,-73.7101"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path134"
+       inkscape:connector-curvature="0" /><path
+       d="m 1456.104,4993.8901 0,-73.7102"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path136"
+       inkscape:connector-curvature="0" /><path
+       d="m 1824.6548,4920.1799 0,73.7102"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path138"
+       inkscape:connector-curvature="0" /><path
+       d="m 2193.2055,4993.8901 0,-73.7102"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path140"
+       inkscape:connector-curvature="0" /><path
+       d="m 2561.7563,4993.8901 0,-73.7102"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path142"
+       inkscape:connector-curvature="0" /><path
+       d="m 2930.307,4993.8901 0,-73.7102"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path144"
+       inkscape:connector-curvature="0" /><path
+       d="m 3298.8578,4993.8901 0,-73.7102"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path146"
+       inkscape:connector-curvature="0" /><path
+       d="m 3667.4085,4993.8901 0,-73.7102"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path148"
+       inkscape:connector-curvature="0" /><path
+       d="m 4035.9593,4993.8901 0,-73.7102"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path150"
+       inkscape:connector-curvature="0" /><path
+       d="m 4404.51,4993.8901 0,-73.7102"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path152"
+       inkscape:connector-curvature="0" /><path
+       d="m 4773.0608,4993.8901 0,-73.7102"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path154"
+       inkscape:connector-curvature="0" /><path
+       d="m 5141.6115,4993.8901 0,-73.7102"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path156"
+       inkscape:connector-curvature="0" /><path
+       d="m 5510.1623,4993.8901 0,-73.7102"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path158"
+       inkscape:connector-curvature="0" /><path
+       d="m 5878.713,4993.8901 0,-73.7102"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path160"
+       inkscape:connector-curvature="0" /><path
+       d="m 719.00254,5104.4553 0,-73.7101"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path162"
+       inkscape:connector-curvature="0" /><path
+       d="m 719.00254,4993.8901 0,-73.7102"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path164"
+       inkscape:connector-curvature="0" /><path
+       d="m 1087.5533,5104.4553 0,-73.7101"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path166"
+       inkscape:connector-curvature="0" /><path
+       d="m 1087.5533,4993.8901 0,-73.7102"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path168"
+       inkscape:connector-curvature="0" /><path
+       d="m 700.575,4735.9046 18.42754,0 0,-110.5653 36.85507,0 0,110.5653 18.42754,0"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path170"
+       inkscape:connector-curvature="0" /><path
+       d="m 774.28515,4680.6285 18.42754,0 0,110.5652 -18.42754,0 0,-110.5652 z"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path172"
+       inkscape:connector-curvature="0" /><path
+       d="m 792.71269,4735.9046 18.42753,0 0,92.1442 18.42754,-18.4341 18.42754,36.8551 18.42754,-36.8551 18.42753,36.8551 18.42754,-55.2761 18.42754,55.2761 18.42754,-18.421 18.42753,55.2761 18.42754,-55.2761 18.42754,18.421 18.4275,36.8551 18.4276,-92.1312 18.4275,55.2761 18.4275,-55.2761 0,-55.2891"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path174"
+       inkscape:connector-curvature="0" /><path
+       d="m 1069.1257,4735.9046 18.4276,0 0,-110.5653 36.8551,0 0,110.5653 18.421,0"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path176"
+       inkscape:connector-curvature="0" /><path
+       d="m 1142.8294,4680.6285 18.4275,0 0,110.5652 -18.4275,0 0,-110.5652 z"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path178"
+       inkscape:connector-curvature="0" /><path
+       d="m 1456.104,4735.9046 0,-110.5653 18.4211,0 0,110.5653 165.8543,0 0,-110.5653 18.421,0 0,110.5653 165.8544,0 0,-110.5653 18.421,0 0,110.5653 165.8544,0 0,-110.5653 18.421,0 0,110.5653 165.8543,0 0,-110.5653 18.4211,0 0,110.5653 165.8543,0 0,-110.5653 18.421,0 0,110.5653 165.8544,0 0,-110.5653 147.4203,0 0,110.5653 36.8551,0 0,-110.5653 147.4203,0 0,110.5653 36.855,0 0,-110.5653 147.4203,0 0,110.5653 36.8551,0 0,-110.5653 147.4203,0 0,110.5653 36.8551,0 0,-110.5653 147.4203,0 0,110.5653 36.855,0 0,-110.5653 147.4203,0 0,110.5653 36.8551,0 0,-110.5653 18.4211,0 0,110.5653 165.8543,0 0,-110.5653 18.421,0 0,110.5653 165.8544,0 0,-110.5653 18.421,0 0,110.5653 165.8543,0 0,-110.5653 18.4211,0 0,110.5653 165.8543,0 0,-110.5653 18.4211,0 0,110.5653 165.8543,0 0,-110.5653 18.421,0 0,110.5653 165.8544,0 0,-110.5653 36.855,0 0,110.5653 18.4211,0"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path180"
+       inkscape:connector-curvature="0" /><path
+       d="m 1161.2634,4735.9046 294.8406,0"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path182"
+       inkscape:connector-curvature="0" /><path
+       d="m 6320.9739,4735.9046 18.421,0 0,92.1442 18.4341,-18.4341 18.421,73.7102 18.4341,-55.2761 18.421,36.855 18.434,-18.434 18.4211,36.8551 18.434,-36.8551 18.421,36.8551 18.4341,-36.8551 18.421,18.434 18.4341,-36.855 18.421,36.855 18.434,-36.855 18.4211,-18.4341 0,-73.7101 18.434,0"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path184"
+       inkscape:connector-curvature="0" /><path
+       d="m 4828.3369,4680.6285 18.4275,0 0,110.5652 -18.4275,0 0,-110.5652 z"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path186"
+       inkscape:connector-curvature="0" /><path
+       d="m 4846.7709,4735.9046 294.8406,0 0,-110.5653 36.8551,0 0,110.5653 18.421,0"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path188"
+       inkscape:connector-curvature="0" /><path
+       d="m 5196.8876,4680.6285 18.4276,0 0,110.5652 -18.4276,0 0,-110.5652 z"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path190"
+       inkscape:connector-curvature="0" /><path
+       d="m 5565.4384,4680.6285 18.4275,0 0,110.5652 -18.4275,0 0,-110.5652 z"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path192"
+       inkscape:connector-curvature="0" /><path
+       d="m 5933.9891,4680.6285 18.4276,0 0,110.5652 -18.4276,0 0,-110.5652 z"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path194"
+       inkscape:connector-curvature="0" /><path
+       d="m 5952.4232,4735.9046 294.8406,0 0,-110.5653 36.855,0 0,110.5653 18.4211,0"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path196"
+       inkscape:connector-curvature="0" /><path
+       d="m 6302.5399,4680.6285 18.4275,0 0,110.5652 -18.4275,0 0,-110.5652 z"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path198"
+       inkscape:connector-curvature="0" /><path
+       d="m 5786.5688,4735.9046 92.1442,0 0,-110.5653 36.8551,0 0,110.5653 18.421,0"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path200"
+       inkscape:connector-curvature="0" /><path
+       d="m 5805.0029,4791.1937 -36.8551,-110.5652"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path202"
+       inkscape:connector-curvature="0" /><path
+       d="m 5583.8724,4735.9046 165.8414,0"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path204"
+       inkscape:connector-curvature="0" /><path
+       d="m 5768.1478,4791.1937 -36.8551,-110.5652"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path206"
+       inkscape:connector-curvature="0" /><path
+       d="m 5215.3217,4735.9046 294.8406,0 0,-110.5653 36.855,0 0,110.5653 18.4211,0"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path208"
+       inkscape:connector-curvature="0" /><path
+       d="m 6247.2638,5104.4553 0,-73.7101"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path210"
+       inkscape:connector-curvature="0" /><path
+       d="m 6247.2638,4993.8901 0,-73.7102"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path212"
+       inkscape:connector-curvature="0" /><path
+       d="m 6615.8145,5104.4553 0,-73.7101"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path214"
+       inkscape:connector-curvature="0" /><path
+       d="m 6615.8145,4993.8901 0,-73.7102"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path216"
+       inkscape:connector-curvature="0" /><path
+       d="m 700.575,3925.0929 18.42754,0 0,-110.5652 36.85507,0 0,110.5652 18.42754,0"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path218"
+       inkscape:connector-curvature="0" /><path
+       d="m 774.28515,3869.8168 18.42754,0 0,110.5652 -18.42754,0 0,-110.5652 z"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path220"
+       inkscape:connector-curvature="0" /><path
+       d="m 1142.8294,3869.8168 18.4275,0 0,110.5652 -18.4275,0 0,-110.5652 z"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path222"
+       inkscape:connector-curvature="0" /><path
+       d="m 792.71269,3925.0929 18.42753,0 0,110.5652 18.42754,-36.855 18.42754,18.434 18.42754,-36.8551 18.42753,36.8551 0,-92.1442 202.70293,0 0,-110.5652 36.8551,0 0,110.5652 18.421,0"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path224"
+       inkscape:connector-curvature="0" /><path
+       d="m 1161.2634,3925.0929 110.5653,0 0,-110.5652 18.421,0 0,110.5652 165.8543,0 0,-110.5652 18.4211,0 0,110.5652 165.8543,0 0,-110.5652 18.421,0 0,110.5652 165.8544,0 0,-110.5652 18.421,0 0,110.5652 165.8544,0 0,-110.5652 18.421,0 0,110.5652 165.8543,0 0,-110.5652 18.4211,0 0,110.5652 165.8543,0 0,-110.5652 147.4203,0 0,110.5652 36.8551,0 0,-110.5652 147.4203,0 0,110.5652 36.8551,0 0,-110.5652 147.4203,0 0,110.5652 36.855,0 0,-110.5652 147.4203,0 0,110.5652 36.8551,0 0,-110.5652 147.4203,0 0,110.5652 36.8551,0 0,-110.5652 147.4203,0 0,110.5652 36.855,0 0,-110.5652 18.4211,0 0,110.5652 165.8543,0 0,-110.5652 18.4211,0 0,110.5652 165.8543,0 0,-110.5652 18.421,0 0,110.5652 165.8544,0 0,-110.5652 18.421,0 0,110.5652 165.8543,0"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path226"
+       inkscape:connector-curvature="0" /><path
+       d="m 4220.2346,3925.0929 0,-110.5652 18.4211,0 0,110.5652 165.8543,0 0,-110.5652 18.4211,0 0,110.5652 55.2891,0"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path228"
+       inkscape:connector-curvature="0" /><path
+       d="m 4478.2202,3925.0929 294.8406,0 0,-110.5652 36.855,0 0,110.5652 18.4211,0"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path230"
+       inkscape:connector-curvature="0" /><path
+       d="m 5952.4232,3925.0929 128.9862,0 0,73.7102 18.4341,36.855 18.421,-18.421 18.434,36.8551 18.4211,-36.8551 18.434,18.421 18.421,-36.855 18.4341,18.434 18.421,-36.8551 0,-55.2891 18.4341,0 0,-110.5652 36.855,0 0,110.5652 18.4211,0"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path232"
+       inkscape:connector-curvature="0" /><path
+       d="m 6302.5399,3869.8168 18.4275,0 0,110.5652 -18.4275,0 0,-110.5652 z"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path234"
+       inkscape:connector-curvature="0" /><path
+       d="m 6320.9739,3925.0929 18.421,0 0,73.7102 18.4341,36.855 18.421,-36.855 18.4341,36.855 18.421,-18.421 18.434,0 18.4211,-36.8551 18.434,55.2761 18.421,-18.421 0,36.8551 18.4341,-18.4341 18.421,18.4341 18.4341,-36.8551 18.421,18.421 18.434,-55.2761 18.4211,18.4211 0,-73.7102 18.434,0"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path236"
+       inkscape:connector-curvature="0" /><path
+       d="m 5933.9891,3869.8168 18.4276,0 0,110.5652 -18.4276,0 0,-110.5652 z"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path238"
+       inkscape:connector-curvature="0" /><path
+       d="m 5786.5688,3925.0929 92.1442,0 0,-110.5652 36.8551,0 0,110.5652 18.421,0"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path240"
+       inkscape:connector-curvature="0" /><path
+       d="m 5805.0029,3980.382 -36.8551,-110.5652"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path242"
+       inkscape:connector-curvature="0" /><path
+       d="m 5768.1478,3980.382 -36.8551,-110.5652"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path244"
+       inkscape:connector-curvature="0" /><path
+       d="m 4828.3369,3869.8168 18.4275,0 0,110.5652 -18.4275,0 0,-110.5652 z"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path246"
+       inkscape:connector-curvature="0" /><path
+       d="m 5583.8724,3925.0929 165.8414,0"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path248"
+       inkscape:connector-curvature="0" /><path
+       d="m 4846.7709,3925.0929 294.8406,0 0,-110.5652 36.8551,0 0,110.5652 18.421,0"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path250"
+       inkscape:connector-curvature="0" /><path
+       d="m 5196.8876,3869.8168 18.4276,0 0,110.5652 -18.4276,0 0,-110.5652 z"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path252"
+       inkscape:connector-curvature="0" /><path
+       d="m 5215.3217,3925.0929 294.8406,0 0,-110.5652 36.855,0 0,110.5652 18.4211,0"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path254"
+       inkscape:connector-curvature="0" /><path
+       d="m 5565.4384,3869.8168 18.4275,0 0,110.5652 -18.4275,0 0,-110.5652 z"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path256"
+       inkscape:connector-curvature="0" /><path
+       d="m 6247.2638,4293.6437 0,-73.7102"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path258"
+       inkscape:connector-curvature="0" /><path
+       d="m 6247.2638,4183.0784 0,-73.7101"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path260"
+       inkscape:connector-curvature="0" /><path
+       d="m 6615.8145,4293.6437 0,-73.7102"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path262"
+       inkscape:connector-curvature="0" /><path
+       d="m 6615.8145,4183.0784 0,-73.7101"
+       style="fill:none;stroke:#000000;stroke-width:3.07125616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path264"
+       inkscape:connector-curvature="0" /><text
+       y="-4035.6582"
+       x="1621.9453"
+       id="text268"
+       style="font-variant:normal;font-weight:normal;font-size:61.42512512px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan270"
+	 sodipodi:role="line"
+	 y="-4035.6582"
+	 x="1621.9453 1642.3999 1676.5522">(1)</tspan></text>
+<text
+       y="-4127.7959"
+       x="4199.7334"
+       id="text272"
+       style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan274"
+	 sodipodi:role="line"
+	 y="-4127.7959"
+	 x="4199.7334 3831.1829 2725.5305 3112.509 3462.6321 4568.2842 4916.3442 4957.3271 5653.4458 5694.4287 5284.895 5325.8779 2356.9773 1988.4264 1210.3424 1251.3252 1292.3081 1619.8759 841.79163 882.77454 923.75732">874569101211322631262</tspan><tspan
+	 id="tspan276"
+	 sodipodi:role="line"
+	 y="-4238.3613"
+	 x="4158.748 4199.7314 4240.7144 3790.1975 3831.1807 3872.1633 2684.5457 2725.5283 2766.5112 3071.5237 3112.5063 3153.4895 3421.647 3462.6299 3503.6125 4527.2988 4568.2822 4609.2646 4895.8496 4936.833 4977.8154 5632.9517 5673.9341 5714.917 5264.4009 5305.3833 5346.3662 2315.9946 2356.9775 2397.9604 1947.444 1988.4269 2029.4097 1210.3424 1251.3252 1292.3081 1578.8931 1619.876 1660.8589 841.79163 882.77454 923.75732">271270267268269272273275274266265263264262</tspan><tspan
+	 id="tspan278"
+	 sodipodi:role="line"
+	 y="-5049.1729"
+	 x="2725.5347 4568.2881 1988.4331 2356.9839 1619.8822 3094.0852 3462.636 4916.3506 4957.334 5284.9019 5325.8843 5653.4526 5694.4351 3812.7656 4181.3164">492315610111278</tspan><tspan
+	 id="tspan280"
+	 sodipodi:role="line"
+	 y="-4938.6074"
+	 x="2725.5474 4568.3013 1988.446 2356.9966 1619.8953 3094.0981 3462.6489 4916.3638 4957.3472 5284.9146 5325.8975 5653.4653 5694.4482 3812.7788 4181.3296">492315610111278</tspan><tspan
+	 id="tspan282"
+	 sodipodi:role="line"
+	 y="-5049.1729"
+	 x="841.81781 882.8006 923.78326">524</tspan><tspan
+	 id="tspan284"
+	 sodipodi:role="line"
+	 y="-4938.6074"
+	 x="841.81781 882.8006 923.78326">261</tspan><tspan
+	 id="tspan286"
+	 sodipodi:role="line"
+	 y="-5049.1729"
+	 x="1210.3684 1251.3512 1292.3342">525</tspan><tspan
+	 id="tspan288"
+	 sodipodi:role="line"
+	 y="-4938.6074"
+	 x="1210.3684 1251.3512 1292.3342">262</tspan><tspan
+	 id="tspan290"
+	 sodipodi:role="line"
+	 y="-5049.1729"
+	 x="6022.0161 6062.999">22</tspan><tspan
+	 id="tspan292"
+	 sodipodi:role="line"
+	 y="-4938.6074"
+	 x="6022.0161 6062.999">22</tspan><tspan
+	 id="tspan294"
+	 sodipodi:role="line"
+	 y="-5049.1729"
+	 x="6390.5669 6431.5498">23</tspan><tspan
+	 id="tspan296"
+	 sodipodi:role="line"
+	 y="-4938.6074"
+	 x="6390.5669 6431.5498">23</tspan><tspan
+	 id="tspan298"
+	 sodipodi:role="line"
+	 y="-4238.3623"
+	 x="6001.5244 6042.5068 6083.4902">285</tspan><tspan
+	 id="tspan300"
+	 sodipodi:role="line"
+	 y="-4127.7964"
+	 x="6022.0156 6062.9985">22</tspan><tspan
+	 id="tspan302"
+	 sodipodi:role="line"
+	 y="-4238.3623"
+	 x="6370.0747 6411.0571 6452.04">286</tspan><tspan
+	 id="tspan304"
+	 sodipodi:role="line"
+	 y="-4127.7964"
+	 x="6390.5664 6431.5493">23</tspan><tspan
+	 id="tspan306"
+	 sodipodi:role="line"
+	 y="-4459.4922"
+	 x="3540.4146 3581.3972 3618.2522 3638.7437 3659.2354 3679.7266 3696.0901 3737.073 3753.4365">1st field</tspan><tspan
+	 id="tspan308"
+	 sodipodi:role="line"
+	 y="-3648.6809"
+	 x="3528.1047 3569.0876 3610.0703 3651.0532 3671.5447 3692.0361 3708.3999 3749.3826 3765.7463">2nd field</tspan></text>
+<text
+       y="-4127.7959"
+       x="4199.7334 3831.1829 2725.5305 3112.509 3462.6321 4568.2842 4916.3442 4957.3271 5653.4458 5694.4287 5284.895 5325.8779 2356.9773 1988.4264 1210.3424 1251.3252 1292.3081 1619.8759 841.79163 882.77454 923.75732"
+       id="text3632"
+       style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan3634"
+	 sodipodi:role="line"
+	 y="-4127.7959"
+	 x="4199.7334 3831.1829 2725.5305 3112.509 3462.6321 4568.2842 4916.3442 4957.3271 5653.4458 5694.4287 5284.895 5325.8779 2356.9773 1988.4264 1210.3424 1251.3252 1292.3081 1619.8759 841.79163 882.77454 923.75732">874569101211322631262</tspan></text>
+<text
+       y="-4238.3613"
+       x="4158.748 4199.7314 4240.7144 3790.1975 3831.1807 3872.1633 2684.5457 2725.5283 2766.5112 3071.5237 3112.5063 3153.4895 3421.647 3462.6299 3503.6125 4527.2988 4568.2822 4609.2646 4895.8496 4936.833 4977.8154 5632.9517 5673.9341 5714.917 5264.4009 5305.3833 5346.3662 2315.9946 2356.9775 2397.9604 1947.444 1988.4269 2029.4097 1210.3424 1251.3252 1292.3081 1578.8931 1619.876 1660.8589 841.79163 882.77454 923.75732"
+       id="text3636"
+       style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan3638"
+	 sodipodi:role="line"
+	 y="-4238.3613"
+	 x="4158.748 4199.7314 4240.7144 3790.1975 3831.1807 3872.1633 2684.5457 2725.5283 2766.5112 3071.5237 3112.5063 3153.4895 3421.647 3462.6299 3503.6125 4527.2988 4568.2822 4609.2646 4895.8496 4936.833 4977.8154 5632.9517 5673.9341 5714.917 5264.4009 5305.3833 5346.3662 2315.9946 2356.9775 2397.9604 1947.444 1988.4269 2029.4097 1210.3424 1251.3252 1292.3081 1578.8931 1619.876 1660.8589 841.79163 882.77454 923.75732">271270267268269272273275274266265263264262</tspan></text>
+<text
+       y="-5049.1729"
+       x="2725.5347 4568.2881 1988.4331 2356.9839 1619.8822 3094.0852 3462.636 4916.3506 4957.334 5284.9019 5325.8843 5653.4526 5694.4351 3812.7656 4181.3164"
+       id="text3640"
+       style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan3642"
+	 sodipodi:role="line"
+	 y="-5049.1729"
+	 x="2725.5347 4568.2881 1988.4331 2356.9839 1619.8822 3094.0852 3462.636 4916.3506 4957.334 5284.9019 5325.8843 5653.4526 5694.4351 3812.7656 4181.3164">492315610111278</tspan></text>
+<text
+       y="-4938.6074"
+       x="2725.5474 4568.3013 1988.446 2356.9966 1619.8953 3094.0981 3462.6489 4916.3638 4957.3472 5284.9146 5325.8975 5653.4653 5694.4482 3812.7788 4181.3296"
+       id="text3644"
+       style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan3646"
+	 sodipodi:role="line"
+	 y="-4938.6074"
+	 x="2725.5474 4568.3013 1988.446 2356.9966 1619.8953 3094.0981 3462.6489 4916.3638 4957.3472 5284.9146 5325.8975 5653.4653 5694.4482 3812.7788 4181.3296">492315610111278</tspan></text>
+<text
+       y="-5049.1729"
+       x="841.81781 882.8006 923.78326"
+       id="text3648"
+       style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan3650"
+	 sodipodi:role="line"
+	 y="-5049.1729"
+	 x="841.81781 882.8006 923.78326">524</tspan></text>
+<text
+       y="-4938.6074"
+       x="841.81781 882.8006 923.78326"
+       id="text3652"
+       style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan3654"
+	 sodipodi:role="line"
+	 y="-4938.6074"
+	 x="841.81781 882.8006 923.78326">261</tspan></text>
+<text
+       y="-5049.1729"
+       x="1210.3684 1251.3512 1292.3342"
+       id="text3656"
+       style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan3658"
+	 sodipodi:role="line"
+	 y="-5049.1729"
+	 x="1210.3684 1251.3512 1292.3342">525</tspan></text>
+<text
+       y="-4938.6074"
+       x="1210.3684 1251.3512 1292.3342"
+       id="text3660"
+       style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan3662"
+	 sodipodi:role="line"
+	 y="-4938.6074"
+	 x="1210.3684 1251.3512 1292.3342">262</tspan></text>
+<text
+       y="-5049.1729"
+       x="6022.0161 6062.999"
+       id="text3664"
+       style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan3666"
+	 sodipodi:role="line"
+	 y="-5049.1729"
+	 x="6022.0161 6062.999">22</tspan></text>
+<text
+       y="-4938.6074"
+       x="6022.0161 6062.999"
+       id="text3668"
+       style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan3670"
+	 sodipodi:role="line"
+	 y="-4938.6074"
+	 x="6022.0161 6062.999">22</tspan></text>
+<text
+       y="-5049.1729"
+       x="6390.5669 6431.5498"
+       id="text3672"
+       style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan3674"
+	 sodipodi:role="line"
+	 y="-5049.1729"
+	 x="6390.5669 6431.5498">23</tspan></text>
+<text
+       y="-4938.6074"
+       x="6390.5669 6431.5498"
+       id="text3676"
+       style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan3678"
+	 sodipodi:role="line"
+	 y="-4938.6074"
+	 x="6390.5669 6431.5498">23</tspan></text>
+<text
+       y="-4238.3623"
+       x="6001.5244 6042.5068 6083.4902"
+       id="text3680"
+       style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan3682"
+	 sodipodi:role="line"
+	 y="-4238.3623"
+	 x="6001.5244 6042.5068 6083.4902">285</tspan></text>
+<text
+       y="-4127.7964"
+       x="6022.0156 6062.9985"
+       id="text3684"
+       style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan3686"
+	 sodipodi:role="line"
+	 y="-4127.7964"
+	 x="6022.0156 6062.9985">22</tspan></text>
+<text
+       y="-4238.3623"
+       x="6370.0747 6411.0571 6452.04"
+       id="text3688"
+       style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan3690"
+	 sodipodi:role="line"
+	 y="-4238.3623"
+	 x="6370.0747 6411.0571 6452.04">286</tspan></text>
+<text
+       y="-4127.7964"
+       x="6390.5664 6431.5493"
+       id="text3692"
+       style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan3694"
+	 sodipodi:role="line"
+	 y="-4127.7964"
+	 x="6390.5664 6431.5493">23</tspan></text>
+<text
+       y="-4459.4922"
+       x="3540.4146 3581.3972 3618.2522 3638.7437 3659.2354 3679.7266 3696.0901 3737.073 3753.4365"
+       id="text3696"
+       style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan3698"
+	 sodipodi:role="line"
+	 y="-4459.4922"
+	 x="3540.4146 3581.3972 3618.2522 3638.7437 3659.2354 3679.7266 3696.0901 3737.073 3753.4365">1st field</tspan></text>
+<text
+       y="-3648.6809"
+       x="3528.1047 3569.0876 3610.0703 3651.0532 3671.5447 3692.0361 3708.3999 3749.3826 3765.7463"
+       id="text3700"
+       style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"><tspan
+	 id="tspan3702"
+	 sodipodi:role="line"
+	 y="-3648.6809"
+	 x="3528.1047 3569.0876 3610.0703 3651.0532 3671.5447 3692.0361 3708.3999 3749.3826 3765.7463">2nd field</tspan></text>
+</g></svg>
diff --git a/Documentation/userspace-api/media/v4l/vbi_625.svg b/Documentation/userspace-api/media/v4l/vbi_625.svg
new file mode 100644
index 000000000000..e1f5e8552c37
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vbi_625.svg
@@ -0,0 +1,870 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+    Permission is granted to copy, distribute and/or modify this
+    document under the terms of the GNU Free Documentation License,
+    Version 1.1 or any later version published by the Free Software
+    Foundation, with no Invariant Sections, no Front-Cover Texts
+    and no Back-Cover Texts. A copy of the license is included at
+    Documentation/userspace-api/media/fdl-appendix.rst.
+
+    TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+-->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.91 r13725"
+   xml:space="preserve"
+   width="209.46608mm"
+   height="51.576824mm"
+   viewBox="0 0 742.20265 182.75252"
+   sodipodi:docname="vbi_625.svg"><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="997"
+     id="namedview4"
+     showgrid="false"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0"
+     inkscape:zoom="1.5350601"
+     inkscape:cx="288.91482"
+     inkscape:cy="170.67667"
+     inkscape:window-x="1920"
+     inkscape:window-y="30"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="g10"
+     units="mm" /><metadata
+     id="metadata8"><rdf:RDF><cc:Work
+	 rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+	   rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
+     id="defs6"><clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath20"><path
+	 d="m 0,0 5950,0 0,4546 L 0,4546 0,0 Z m 0,4546 5950,0 0,1 -5950,0 0,-1 z m 0,1 2211,0 0,1 -2211,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2215,0 0,1 -2215,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2219,0 0,1 -2219,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2223,0 0,1 -2223,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2227,0 0,1 -2227,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2231,0 0,1 -2231,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2235,0 0,1 -2235,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2239,0 0,1 -2239,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2241,0 0,1 -2241,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2240,0 0,1 -2240,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2236,0 0,1 -2236,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2232,0 0,1 -2232,0 0,-1 z m
+2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2228,0 0,1 -2228,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2224,0 0,1 -2224,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2220,0 0,1 -2220,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2216,0 0,1 -2216,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2212,0 0,1 -2212,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2208,0 0,1 -2208,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 5950,0 0,1 -5950,0 0,-1 z m 0,1 5950,0 0,3854 -5950,0 0,-3854 z"
+	 id="path22"
+	 inkscape:connector-curvature="0" /></clipPath><clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath98"><path
+	 d="m 0,0 5950,0 0,3922 L 0,3922 0,0 Z m 0,3922 5950,0 0,1 -5950,0 0,-1 z m 0,1 2209,0 0,1 -2209,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2213,0 0,1 -2213,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2217,0 0,1 -2217,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2221,0 0,1 -2221,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2225,0 0,1 -2225,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2229,0 0,1 -2229,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2233,0 0,1 -2233,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2237,0 0,1 -2237,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2241,0 0,1 -2241,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2241,0 0,1 -2241,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2237,0 0,1 -2237,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2233,0 0,1 -2233,0 0,-1 z m
+2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2229,0 0,1 -2229,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2225,0 0,1 -2225,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2221,0 0,1 -2221,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2217,0 0,1 -2217,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2213,0 0,1 -2213,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2209,0 0,1 -2209,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 5950,0 0,1 -5950,0 0,-1 z m 0,1 5950,0 0,4478 -5950,0 0,-4478 z"
+	 id="path100"
+	 inkscape:connector-curvature="0" /></clipPath></defs><g
+     id="g10"
+     inkscape:groupmode="layer"
+     inkscape:label="vbi_625"
+     transform="matrix(0.125,0,0,-0.125,-87.571875,638.69874)"><g
+       id="g12"
+       transform="matrix(1.3045828,0,0,1.3045828,-213.38312,-1110.9872)"
+       style=""><path
+	 d="m 2132.25,4598.15 0,-85.05"
+	 style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 id="path14"
+	 inkscape:connector-curvature="0" /></g><g
+       id="g16"
+       transform="matrix(1.3045828,0,0,1.3045828,-213.38312,-1110.9872)"
+       style=""><g
+	 id="g18"
+	 clip-path="url(#clipPath20)"
+	 style=""><path
+	   d="m 2132.25,4555.63 113.4,0"
+	   style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	   id="path24"
+	   inkscape:connector-curvature="0" /></g></g><path
+       inkscape:connector-curvature="0"
+       id="path28"
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       d="m 2660.3649,4819.881 49.3132,12.3283 -49.3132,12.3283 0,-24.6566" /><path
+       inkscape:connector-curvature="0"
+       id="path30"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 2660.3649,4819.881 49.3132,12.3283 -49.3132,12.3283 0,-24.6566 z" /><path
+       inkscape:connector-curvature="0"
+       id="path32"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 1828.6151,4924.6651 0,73.9699" /><path
+       inkscape:connector-curvature="0"
+       id="path34"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 2198.4643,4998.635 0,-73.9699" /><path
+       inkscape:connector-curvature="0"
+       id="path36"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 2568.3136,4998.635 0,-73.9699" /><path
+       inkscape:connector-curvature="0"
+       id="path38"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 2938.1628,4998.635 0,-73.9699" /><path
+       inkscape:connector-curvature="0"
+       id="path40"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 3308.012,4998.635 0,-73.9699" /><path
+       inkscape:connector-curvature="0"
+       id="path42"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 3677.8612,4998.635 0,-73.9699" /><path
+       inkscape:connector-curvature="0"
+       id="path44"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 4047.7105,4998.635 0,-73.9699" /><path
+       inkscape:connector-curvature="0"
+       id="path46"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 4417.5597,4998.635 0,-73.9699" /><path
+       inkscape:connector-curvature="0"
+       id="path48"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 4787.4089,4998.635 0,-73.9699" /><path
+       inkscape:connector-curvature="0"
+       id="path50"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 5157.2581,4998.635 0,-73.9699" /><path
+       inkscape:connector-curvature="0"
+       id="path52"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 5527.1073,4998.635 0,-73.9699" /><path
+       inkscape:connector-curvature="0"
+       id="path54"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 5896.9566,4998.635 0,-73.9699" /><path
+       inkscape:connector-curvature="0"
+       id="path56"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 1458.7659,5109.5897 0,-73.9698" /><path
+       inkscape:connector-curvature="0"
+       id="path58"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 1828.6151,5035.6199 0,73.9698" /><path
+       inkscape:connector-curvature="0"
+       id="path60"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 2198.4643,5109.5897 0,-73.9698" /><path
+       inkscape:connector-curvature="0"
+       id="path62"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 2568.3136,5109.5897 0,-73.9698" /><path
+       inkscape:connector-curvature="0"
+       id="path64"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 2938.1628,5109.5897 0,-73.9698" /><path
+       inkscape:connector-curvature="0"
+       id="path66"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 3308.012,5109.5897 0,-73.9698" /><path
+       inkscape:connector-curvature="0"
+       id="path68"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 3677.8612,5109.5897 0,-73.9698" /><path
+       inkscape:connector-curvature="0"
+       id="path70"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 4047.7105,5109.5897 0,-73.9698" /><path
+       inkscape:connector-curvature="0"
+       id="path72"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 4417.5597,5109.5897 0,-73.9698" /><path
+       inkscape:connector-curvature="0"
+       id="path74"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 4787.4089,5109.5897 0,-73.9698" /><path
+       inkscape:connector-curvature="0"
+       id="path76"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 5157.2581,5109.5897 0,-73.9698" /><path
+       inkscape:connector-curvature="0"
+       id="path78"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 5527.1073,5109.5897 0,-73.9698" /><path
+       inkscape:connector-curvature="0"
+       id="path80"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 5896.9566,5109.5897 0,-73.9698" /><path
+       inkscape:connector-curvature="0"
+       id="path82"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 1458.7659,4998.635 0,-73.9699" /><path
+       inkscape:connector-curvature="0"
+       id="path84"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 719.06744,4998.635 0,-73.9699" /><path
+       inkscape:connector-curvature="0"
+       id="path86"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 719.06744,5109.5897 0,-73.9698" /><path
+       inkscape:connector-curvature="0"
+       id="path88"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 1088.9167,4998.635 0,-73.9699" /><path
+       inkscape:connector-curvature="0"
+       id="path90"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 1088.9167,5109.5897 0,-73.9698" /><path
+       inkscape:connector-curvature="0"
+       id="path92"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 2568.3136,4074.0119 0,-110.9548" /><g
+       id="g94"
+       transform="matrix(1.3045828,0,0,1.3045828,-213.38312,-1110.9872)"
+       style=""><g
+	 id="g96"
+	 clip-path="url(#clipPath98)"
+	 style=""><path
+	   d="m 2132.25,3931.93 113.4,0"
+	   style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	   id="path102"
+	   inkscape:connector-curvature="0" /></g></g><path
+       inkscape:connector-curvature="0"
+       id="path106"
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       d="m 2660.365,4006.2129 49.3132,12.3283 -49.3132,12.3283 0,-24.6566" /><path
+       inkscape:connector-curvature="0"
+       id="path108"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 2660.365,4006.2129 49.3132,12.3283 -49.3132,12.3283 0,-24.6566 z" /><path
+       inkscape:connector-curvature="0"
+       id="path110"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 6266.806,4184.9668 0,-73.9698" /><path
+       inkscape:connector-curvature="0"
+       id="path112"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 5896.9567,4184.9668 0,-73.9698" /><path
+       inkscape:connector-curvature="0"
+       id="path114"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 5527.1075,4184.9668 0,-73.9698" /><path
+       inkscape:connector-curvature="0"
+       id="path116"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 5157.2583,4184.9668 0,-73.9698" /><path
+       inkscape:connector-curvature="0"
+       id="path118"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 4787.409,4184.9668 0,-73.9698" /><path
+       inkscape:connector-curvature="0"
+       id="path120"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 4417.5598,4184.9668 0,-73.9698" /><path
+       inkscape:connector-curvature="0"
+       id="path122"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 4047.7106,4184.9668 0,-73.9698" /><path
+       inkscape:connector-curvature="0"
+       id="path124"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 3677.8613,4184.9668 0,-73.9698" /><path
+       inkscape:connector-curvature="0"
+       id="path126"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 3308.0121,4184.9668 0,-73.9698" /><path
+       inkscape:connector-curvature="0"
+       id="path128"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 2938.1629,4184.9668 0,-73.9698" /><path
+       inkscape:connector-curvature="0"
+       id="path130"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 2568.3136,4184.9668 0,-73.9698" /><path
+       inkscape:connector-curvature="0"
+       id="path132"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 2198.4644,4184.9668 0,-73.9698" /><path
+       inkscape:connector-curvature="0"
+       id="path134"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 1828.6152,4184.9668 0,-73.9698" /><path
+       inkscape:connector-curvature="0"
+       id="path136"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 1458.7659,4184.9668 0,-73.9698" /><path
+       inkscape:connector-curvature="0"
+       id="path138"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 6266.806,4295.9216 0,-73.9699" /><path
+       inkscape:connector-curvature="0"
+       id="path140"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 5896.9567,4295.9216 0,-73.9699" /><path
+       inkscape:connector-curvature="0"
+       id="path142"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 5527.1075,4295.9216 0,-73.9699" /><path
+       inkscape:connector-curvature="0"
+       id="path144"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 5157.2583,4295.9216 0,-73.9699" /><path
+       inkscape:connector-curvature="0"
+       id="path146"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 4787.409,4295.9216 0,-73.9699" /><path
+       inkscape:connector-curvature="0"
+       id="path148"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 4417.5598,4295.9216 0,-73.9699" /><path
+       inkscape:connector-curvature="0"
+       id="path150"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 4047.7106,4295.9216 0,-73.9699" /><path
+       inkscape:connector-curvature="0"
+       id="path152"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 3677.8613,4295.9216 0,-73.9699" /><path
+       inkscape:connector-curvature="0"
+       id="path154"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 3308.0121,4295.9216 0,-73.9699" /><path
+       inkscape:connector-curvature="0"
+       id="path156"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 2938.1629,4295.9216 0,-73.9699" /><path
+       inkscape:connector-curvature="0"
+       id="path158"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 2568.3136,4295.9216 0,-73.9699" /><path
+       inkscape:connector-curvature="0"
+       id="path160"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 2198.4644,4295.9216 0,-73.9699" /><path
+       inkscape:connector-curvature="0"
+       id="path162"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 1828.6152,4295.9216 0,-73.9699" /><path
+       inkscape:connector-curvature="0"
+       id="path164"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 1458.7659,4295.9216 0,-73.9699" /><path
+       inkscape:connector-curvature="0"
+       id="path166"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 719.06746,4295.9216 0,-73.9699" /><path
+       inkscape:connector-curvature="0"
+       id="path168"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 719.06746,4184.9668 0,-73.9698" /><path
+       inkscape:connector-curvature="0"
+       id="path170"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 1088.9167,4295.9216 0,-73.9699" /><path
+       inkscape:connector-curvature="0"
+       id="path172"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 1088.9167,4184.9668 0,-73.9698" /><path
+       inkscape:connector-curvature="0"
+       id="path174"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 1144.3876,4684.2698 18.4924,0 0,110.9548 -18.4924,0 0,-110.9548 z" /><path
+       inkscape:connector-curvature="0"
+       id="path176"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 1070.4242,4739.7407 18.4925,0 0,-110.9548 36.9849,0 0,110.9548 18.486,0" /><path
+       inkscape:connector-curvature="0"
+       id="path178"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 700.575,4739.7407 18.49246,0 0,-110.9548 36.98492,0 0,110.9548 18.49247,0" /><path
+       inkscape:connector-curvature="0"
+       id="path180"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 809.886,4739.7407 3.28754,0" /><path
+       inkscape:connector-curvature="0"
+       id="path182"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 809.886,4739.7407 3.28754,0" /><path
+       inkscape:connector-curvature="0"
+       id="path184"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 774.54485,4684.2698 18.49246,0 0,110.9548 -18.49246,0 0,-110.9548 z" /><path
+       inkscape:connector-curvature="0"
+       id="path186"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 793.03731,4739.7407 18.49246,0 18.49246,73.9698 18.49246,-36.9849 18.49246,92.4688 18.49247,-55.4839 18.49246,18.499 18.49246,-36.9849 18.49246,55.4708 18.49246,-73.9698 18.49246,55.4839 18.49247,-73.9699 18.49241,110.9548 18.4925,-92.4688 18.4925,55.4839 18.4924,-55.4839 0,-36.9849" /><path
+       inkscape:connector-curvature="0"
+       id="path188"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 1162.8865,4739.7407 18.486,0 0,92.4688 18.499,-18.499 18.4859,36.9849 18.499,-36.9849 18.4859,36.9849 18.499,-55.4708 18.4859,55.4708 18.499,-18.4859 18.486,55.4708 18.499,-55.4708 18.4859,18.4859 18.499,36.9849 18.4859,-73.9698 18.499,36.9849 18.4859,-55.4708 0,-55.4839 18.499,0 0,-110.9548 36.985,0 0,110.9548 18.4859,0 0,55.4839 18.499,36.9849 18.4859,-36.9849 18.499,55.4708 18.4859,-18.4859 18.499,55.4708 18.486,-18.4859 0,-129.4537 18.4989,0 0,-110.9548 18.486,0 0,110.9548 166.4387,0 0,-110.9548 18.4859,0 0,110.9548 166.4387,0 0,-110.9548 18.4859,0 0,110.9548 166.4387,0 0,-110.9548 18.4859,0 0,110.9548 166.4387,0 0,-110.9548 18.4859,0 0,110.9548 166.4387,0 0,-110.9548 147.9397,0 0,110.9548 36.9849,0 0,-110.9548 147.9397,0 0,110.9548 36.985,0 0,-110.9548 147.9397,0 0,110.9548 36.9849,0 0,-110.9548 147.9397,0 0,110.9548 36.9849,0 0,-110.9548 147.9397,0 0,110.9548 36.9849,0
+0,-110.9548 18.4859,0 0,110.9548 166.4387,0 0,-110.9548 18.486,0 0,110.9548 166.4386,0 0,-110.9548 18.486,0 0,110.9548 166.4387,0 0,-110.9548 18.4859,0 0,110.9548 166.4387,0 0,-110.9548 18.4859,0 0,110.9548 166.4387,0 0,-110.9548 36.9849,0 0,110.9548 332.8643,0 0,-110.9548 36.9849,0 0,110.9548 18.486,0" /><path
+       inkscape:connector-curvature="0"
+       id="path190"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 700.575,3926.0723 18.49246,0 0,-110.9547 36.98492,0 0,110.9547 18.49247,0" /><path
+       inkscape:connector-curvature="0"
+       id="path192"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 774.54485,3870.6015 18.49246,0 0,110.9547 -18.49246,0 0,-110.9547 z" /><path
+       inkscape:connector-curvature="0"
+       id="path194"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 793.03731,3926.0723 18.49246,0 0,92.4689 18.49246,-36.985 18.49246,73.9699 18.49246,-73.9699 18.49247,73.9699 18.49246,-36.9849 18.49246,18.4859 18.49246,-73.9698 18.49246,55.4839 18.49246,-18.499 18.49247,36.9849 18.49241,-73.9698 18.4925,92.4688 18.4925,-92.4688 18.4924,55.4839 0,-92.4689" /><path
+       inkscape:connector-curvature="0"
+       id="path196"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 1070.4242,3926.0723 18.4925,0 0,-110.9547 36.9849,0 0,110.9547 18.486,0" /><path
+       inkscape:connector-curvature="0"
+       id="path198"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 1144.3876,3870.6015 18.4924,0 0,110.9547 -18.4924,0 0,-110.9547 z" /><path
+       inkscape:connector-curvature="0"
+       id="path200"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 1162.8865,3926.0723 18.486,0 0,55.4839 18.499,92.4558 18.4859,-55.4708 36.9849,36.9849 18.499,-55.4839 18.4859,18.499 18.499,-36.985 18.486,55.4709 18.499,-18.4859 18.4859,-36.985 18.499,18.486 18.4859,36.9849 18.499,-36.9849 18.4859,36.9849 0,-110.9548 18.499,0 0,-110.9547 18.486,0 0,110.9547 166.4386,0 0,-110.9547 18.486,0 0,110.9547 166.4387,0 0,-110.9547 18.4859,0 0,110.9547 166.4387,0 0,-110.9547 18.4859,0 0,110.9547 166.4387,0 0,-110.9547 18.4859,0 0,110.9547 166.4387,0 0,-110.9547 147.9397,0 0,110.9547 36.9849,0 0,-110.9547 147.9397,0 0,110.9547 36.9849,0 0,-110.9547 147.9397,0 0,110.9547 36.985,0 0,-110.9547 147.9397,0 0,110.9547 36.9849,0 0,-110.9547 147.9397,0 0,110.9547 36.9849,0 0,-110.9547 18.4859,0 0,110.9547 166.4387,0 0,-110.9547 18.4859,0 0,110.9547 166.4387,0 0,-110.9547 18.486,0 0,110.9547 166.4386,0 0,-110.9547 18.486,0 0,110.9547 166.4387,0 0,-110.9547
+18.4859,0 0,110.9547 351.3633,0 0,-110.9547 36.9849,0 0,110.9547 18.486,0" /><path
+       inkscape:connector-curvature="0"
+       id="path202"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 5453.1376,4795.2246 -36.9849,-110.9548" /><path
+       inkscape:connector-curvature="0"
+       id="path204"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 5434.6387,4739.7407 92.4688,0 0,-110.9548 36.9849,0 0,110.9548 18.486,0" /><path
+       inkscape:connector-curvature="0"
+       id="path206"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 5582.5784,4684.2698 18.4924,0 0,110.9548 -18.4924,0 0,-110.9548 z" /><path
+       inkscape:connector-curvature="0"
+       id="path208"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 5601.0773,4739.7407 295.8794,0 0,-110.9548 36.9849,0 0,110.9548 18.486,0" /><path
+       inkscape:connector-curvature="0"
+       id="path210"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 5952.4276,4684.2698 18.4924,0 0,110.9548 -18.4924,0 0,-110.9548 z" /><path
+       inkscape:connector-curvature="0"
+       id="path212"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 5970.9266,4739.7407 129.4407,0 0,147.9396 18.499,-36.9849 18.4859,36.9849 18.499,-36.9849 18.4859,18.499 18.499,-36.9849 18.4859,36.9849 18.499,-36.9849 18.486,-18.499 0,-73.9698" /><path
+       inkscape:connector-curvature="0"
+       id="path214"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 4842.8799,4684.2698 18.4924,0 0,110.9548 -18.4924,0 0,-110.9548 z" /><path
+       inkscape:connector-curvature="0"
+       id="path216"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 4861.3789,4739.7407 295.8794,0 0,-110.9548 36.9849,0 0,110.9548 18.4859,0" /><path
+       inkscape:connector-curvature="0"
+       id="path218"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 5212.7291,4684.2698 18.4925,0 0,110.9548 -18.4925,0 0,-110.9548 z" /><path
+       inkscape:connector-curvature="0"
+       id="path220"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 5231.2281,4739.7407 166.4256,0" /><path
+       inkscape:connector-curvature="0"
+       id="path222"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 5416.1527,4795.2246 -36.9849,-110.9548" /><path
+       inkscape:connector-curvature="0"
+       id="path224"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 4473.0307,3870.6015 18.4924,0 0,110.9547 -18.4924,0 0,-110.9547 z" /><path
+       inkscape:connector-curvature="0"
+       id="path226"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 4491.5296,3926.0723 295.8794,0 0,-110.9547 36.9849,0 0,110.9547 18.486,0" /><path
+       inkscape:connector-curvature="0"
+       id="path228"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 4842.8799,3870.6015 18.4924,0 0,110.9547 -18.4924,0 0,-110.9547 z" /><path
+       inkscape:connector-curvature="0"
+       id="path230"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 4861.3789,3926.0723 295.8794,0 0,-110.9547 36.9849,0 0,110.9547 18.4859,0" /><path
+       inkscape:connector-curvature="0"
+       id="path232"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 5212.7291,3870.6015 18.4925,0 0,110.9547 -18.4925,0 0,-110.9547 z" /><path
+       inkscape:connector-curvature="0"
+       id="path234"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 5416.1527,3981.5562 -36.9849,-110.9547" /><path
+       inkscape:connector-curvature="0"
+       id="path236"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 5231.2281,3926.0723 166.4256,0" /><path
+       inkscape:connector-curvature="0"
+       id="path238"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 5453.1376,3981.5562 -36.9849,-110.9547" /><path
+       inkscape:connector-curvature="0"
+       id="path240"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 5434.6387,3926.0723 92.4688,0 0,-110.9547 36.9849,0 0,110.9547 18.486,0" /><path
+       inkscape:connector-curvature="0"
+       id="path242"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 5582.5784,3870.6015 18.4924,0 0,110.9547 -18.4924,0 0,-110.9547 z" /><path
+       inkscape:connector-curvature="0"
+       id="path244"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 5601.0773,3926.0723 295.8794,0 0,-110.9547 36.9849,0 0,110.9547 18.486,0" /><path
+       inkscape:connector-curvature="0"
+       id="path246"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 5952.4276,3870.6015 18.4924,0 0,110.9547 -18.4924,0 0,-110.9547 z" /><path
+       inkscape:connector-curvature="0"
+       id="path248"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 5970.9266,3926.0723 18.4859,0 0,73.9699 18.499,36.9849 18.4859,-36.9849 18.499,36.9849 18.486,-18.4859 18.4989,0 18.486,-36.985 18.499,55.4709 18.4859,-18.4859 0,36.9849 18.499,-18.499 18.4859,18.499 18.499,-36.9849 18.4859,18.4859 18.499,-55.4709 18.486,18.486 0,-73.9699" /><path
+       inkscape:connector-curvature="0"
+       id="path250"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 6248.307,4739.7407 18.499,0 0,-110.9548 36.9849,0 0,110.9548 18.4859,0" /><path
+       inkscape:connector-curvature="0"
+       id="path252"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 6248.307,3926.0723 18.499,0 0,-110.9547 36.9849,0 0,110.9547 18.4859,0" /><path
+       inkscape:connector-curvature="0"
+       id="path254"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 6322.2768,3870.6015 18.4925,0 0,110.9547 -18.4925,0 0,-110.9547 z" /><path
+       inkscape:connector-curvature="0"
+       id="path256"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 6322.2768,4684.2698 18.4925,0 0,110.9548 -18.4925,0 0,-110.9548 z" /><path
+       inkscape:connector-curvature="0"
+       id="path258"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 6340.7758,4739.7407 18.4859,0 0,55.4839 18.499,55.4708 18.486,-92.4558 18.4989,55.4709 18.486,0 18.499,55.4839 18.4859,-73.9698 18.499,36.9849 18.4859,-36.9849 36.985,73.9698 18.4989,-36.9849 18.486,36.9849 18.499,-55.4839 18.4859,36.9849 0,-110.9547 18.499,0" /><path
+       inkscape:connector-curvature="0"
+       id="path260"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 6340.7758,3926.0723 18.4859,0 0,129.4538 18.499,-18.499 18.486,18.499 18.4989,-36.9849 18.486,18.4859 18.499,-36.9849 18.4859,18.499 18.499,-18.499 18.4859,55.4839 18.499,-18.499 18.486,36.9849 18.4989,-73.9698 18.486,55.4839 18.499,-55.4839 18.4859,36.9849 0,-110.9548 18.499,0" /><path
+       inkscape:connector-curvature="0"
+       id="path262"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 6636.6552,4184.9668 0,-73.9698" /><path
+       inkscape:connector-curvature="0"
+       id="path264"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 6636.6552,4295.9216 0,-73.9699" /><path
+       inkscape:connector-curvature="0"
+       id="path266"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 6266.806,4998.6351 0,-73.9698" /><path
+       inkscape:connector-curvature="0"
+       id="path268"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 6266.806,5109.5899 0,-73.9699" /><path
+       inkscape:connector-curvature="0"
+       id="path270"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 6636.6552,4998.6351 0,-73.9698" /><path
+       inkscape:connector-curvature="0"
+       id="path272"
+       style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       d="m 6636.6552,5109.5899 0,-73.9699" /><text
+       transform="scale(1,-1)"
+       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       id="text276"
+       x="3550.4165"
+       y="-4462.3472"><tspan
+	 x="3550.4165 3591.5437 3628.5286 3649.0923 3669.656 3690.2195 3706.6409 3747.7681 3764.1895"
+	 y="-4462.3472"
+	 sodipodi:role="line"
+	 id="tspan278">1st field</tspan><tspan
+	 x="2732.6792 3823.7344 4193.5835 4581.9253 4951.7744 5321.6235 3472.3777 3102.5283 2321.7029 2362.8303 2403.9575 1951.8538 1992.981 2034.1083 1582.0045 1623.132 1664.259 5670.9062 5712.0337"
+	 y="-4943.1509"
+	 sodipodi:role="line"
+	 id="tspan280">1456783231231131022</tspan><tspan
+	 x="2732.6726 3823.7278 4193.5771 4581.9189 4951.7681 5321.6172 3472.3711 3102.522 2321.6965 2362.8237 2403.9509 1951.8473 1992.9745 2034.1018 1581.998 1623.1254 1664.2524 5670.8999 5712.0269"
+	 y="-5054.1064"
+	 sodipodi:role="line"
+	 id="tspan282">1456783262562462322</tspan><tspan
+	 x="842.29962 883.42694 924.55408"
+	 y="-4943.1509"
+	 sodipodi:role="line"
+	 id="tspan284">308</tspan><tspan
+	 x="842.29962 883.42694 924.55408"
+	 y="-5054.1064"
+	 sodipodi:role="line"
+	 id="tspan286">621</tspan><tspan
+	 x="1212.1489 1253.276 1294.4033"
+	 y="-4943.1509"
+	 sodipodi:role="line"
+	 id="tspan288">309</tspan><tspan
+	 x="1212.1489 1253.276 1294.4033"
+	 y="-5054.1064"
+	 sodipodi:role="line"
+	 id="tspan290">622</tspan><tspan
+	 x="3538.0635 3579.1907 3620.3179 3661.4451 3682.0088 3702.5723 3718.9937 3760.1208 3776.5422"
+	 y="-3648.6792"
+	 sodipodi:role="line"
+	 id="tspan292">2nd field</tspan></text>
+<text
+       transform="scale(1,-1)"
+       style="font-variant:normal;font-weight:normal;font-size:61.64153671px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       id="text294"
+       x="2734.751"
+       y="-4037.021"><tspan
+	 x="2734.751 2755.2776 2789.5503"
+	 y="-4037.021"
+	 sodipodi:role="line"
+	 id="tspan296">(1)</tspan></text>
+<text
+       transform="scale(1,-1)"
+       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       id="text298"
+       x="4951.772"
+       y="-4129.4834"><tspan
+	 x="4951.772 4581.9229 4212.0737 3842.2244 3490.8677 3102.5259 2321.7004 2362.8276 2403.9551 1951.8512 1992.9785 2034.1057 1582.0022 1623.1293 1664.2563"
+	 y="-4129.4834"
+	 sodipodi:role="line"
+	 id="tspan300">765432313312311</tspan><tspan
+	 x="6020.1929 6061.3198 6102.4473 5650.3433 5691.4707 5732.5981 5280.4941 5321.6216 5362.7485 4910.645 4951.7725 4992.8994 4540.7959 4581.9229 4623.0503 4170.9468 4212.0737 4253.2012 3801.0974 3842.2246 3883.3518 3449.7405 3490.8677 3531.9951 3061.3989 3102.5261 3143.6533 2691.5496 2732.677 2773.8042 2321.7004 2362.8276 2403.9551 1951.8512 1992.9785 2034.1057 1582.0022 1623.1293 1664.2563"
+	 y="-4240.4385"
+	 sodipodi:role="line"
+	 id="tspan302">336335321320319318317316315314313312311</tspan><tspan
+	 x="2732.6765 5321.6211 5670.9062 5712.0337 6040.7554 6081.8828 842.30634 883.43323 924.56055"
+	 y="-4129.4834"
+	 sodipodi:role="line"
+	 id="tspan304">182223309</tspan><tspan
+	 x="842.30634 883.43323 924.56055"
+	 y="-4240.4385"
+	 sodipodi:role="line"
+	 id="tspan306">309</tspan><tspan
+	 x="1212.1553 1253.2826 1294.4099"
+	 y="-4129.4834"
+	 sodipodi:role="line"
+	 id="tspan308">310</tspan><tspan
+	 x="1212.1553 1253.2826 1294.4099"
+	 y="-4240.4385"
+	 sodipodi:role="line"
+	 id="tspan310">310</tspan><tspan
+	 x="6410.605 6451.7319"
+	 y="-4129.4834"
+	 sodipodi:role="line"
+	 id="tspan312">24</tspan><tspan
+	 x="6390.041 6431.1685 6472.2954"
+	 y="-4240.4385"
+	 sodipodi:role="line"
+	 id="tspan314">337</tspan><tspan
+	 x="6040.7559 6081.8833"
+	 y="-4943.1504"
+	 sodipodi:role="line"
+	 id="tspan316">23</tspan><tspan
+	 x="6040.7559 6081.8833"
+	 y="-5054.106"
+	 sodipodi:role="line"
+	 id="tspan318">23</tspan><tspan
+	 x="6410.605 6451.7324"
+	 y="-4943.1504"
+	 sodipodi:role="line"
+	 id="tspan320">24</tspan><tspan
+	 x="6410.605 6451.7324"
+	 y="-5054.106"
+	 sodipodi:role="line"
+	 id="tspan322">24</tspan></text>
+<text
+       transform="scale(1,-1)"
+       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       id="text3671"
+       x="3550.4165 3591.5437 3628.5286 3649.0923 3669.656 3690.2195 3706.6409 3747.7681 3764.1895"
+       y="-4462.3472"><tspan
+	 x="3550.4165 3591.5437 3628.5286 3649.0923 3669.656 3690.2195 3706.6409 3747.7681 3764.1895"
+	 y="-4462.3472"
+	 sodipodi:role="line"
+	 id="tspan3673">1st field</tspan></text>
+<text
+       transform="scale(1,-1)"
+       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       id="text3675"
+       x="2732.6792 3823.7344 4193.5835 4581.9253 4951.7744 5321.6235 3472.3777 3102.5283 2321.7029 2362.8303 2403.9575 1951.8538 1992.981 2034.1083 1582.0045 1623.132 1664.259 5670.9062 5712.0337"
+       y="-4943.1509"><tspan
+	 x="2732.6792 3823.7344 4193.5835 4581.9253 4951.7744 5321.6235 3472.3777 3102.5283 2321.7029 2362.8303 2403.9575 1951.8538 1992.981 2034.1083 1582.0045 1623.132 1664.259 5670.9062 5712.0337"
+	 y="-4943.1509"
+	 sodipodi:role="line"
+	 id="tspan3677">1456783231231131022</tspan></text>
+<text
+       transform="scale(1,-1)"
+       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       id="text3679"
+       x="2732.6726 3823.7278 4193.5771 4581.9189 4951.7681 5321.6172 3472.3711 3102.522 2321.6965 2362.8237 2403.9509 1951.8473 1992.9745 2034.1018 1581.998 1623.1254 1664.2524 5670.8999 5712.0269"
+       y="-5054.1064"><tspan
+	 x="2732.6726 3823.7278 4193.5771 4581.9189 4951.7681 5321.6172 3472.3711 3102.522 2321.6965 2362.8237 2403.9509 1951.8473 1992.9745 2034.1018 1581.998 1623.1254 1664.2524 5670.8999 5712.0269"
+	 y="-5054.1064"
+	 sodipodi:role="line"
+	 id="tspan3681">1456783262562462322</tspan></text>
+<text
+       transform="scale(1,-1)"
+       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       id="text3683"
+       x="842.29962 883.42694 924.55408"
+       y="-4943.1509"><tspan
+	 x="842.29962 883.42694 924.55408"
+	 y="-4943.1509"
+	 sodipodi:role="line"
+	 id="tspan3685">308</tspan></text>
+<text
+       transform="scale(1,-1)"
+       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       id="text3687"
+       x="842.29962 883.42694 924.55408"
+       y="-5054.1064"><tspan
+	 x="842.29962 883.42694 924.55408"
+	 y="-5054.1064"
+	 sodipodi:role="line"
+	 id="tspan3689">621</tspan></text>
+<text
+       transform="scale(1,-1)"
+       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       id="text3691"
+       x="1212.1489 1253.276 1294.4033"
+       y="-4943.1509"><tspan
+	 x="1212.1489 1253.276 1294.4033"
+	 y="-4943.1509"
+	 sodipodi:role="line"
+	 id="tspan3693">309</tspan></text>
+<text
+       transform="scale(1,-1)"
+       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       id="text3695"
+       x="1212.1489 1253.276 1294.4033"
+       y="-5054.1064"><tspan
+	 x="1212.1489 1253.276 1294.4033"
+	 y="-5054.1064"
+	 sodipodi:role="line"
+	 id="tspan3697">622</tspan></text>
+<text
+       transform="scale(1,-1)"
+       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       id="text3699"
+       x="3538.0635 3579.1907 3620.3179 3661.4451 3682.0088 3702.5723 3718.9937 3760.1208 3776.5422"
+       y="-3648.6792"><tspan
+	 x="3538.0635 3579.1907 3620.3179 3661.4451 3682.0088 3702.5723 3718.9937 3760.1208 3776.5422"
+	 y="-3648.6792"
+	 sodipodi:role="line"
+	 id="tspan3701">2nd field</tspan></text>
+<text
+       transform="scale(1,-1)"
+       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       id="text4083"
+       x="4951.772 4581.9229 4212.0737 3842.2244 3490.8677 3102.5259 2321.7004 2362.8276 2403.9551 1951.8512 1992.9785 2034.1057 1582.0022 1623.1293 1664.2563"
+       y="-4129.4834"><tspan
+	 x="4951.772 4581.9229 4212.0737 3842.2244 3490.8677 3102.5259 2321.7004 2362.8276 2403.9551 1951.8512 1992.9785 2034.1057 1582.0022 1623.1293 1664.2563"
+	 y="-4129.4834"
+	 sodipodi:role="line"
+	 id="tspan4085">765432313312311</tspan></text>
+<text
+       transform="scale(1,-1)"
+       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       id="text4087"
+       x="6020.1929 6061.3198 6102.4473 5650.3433 5691.4707 5732.5981 5280.4941 5321.6216 5362.7485 4910.645 4951.7725 4992.8994 4540.7959 4581.9229 4623.0503 4170.9468 4212.0737 4253.2012 3801.0974 3842.2246 3883.3518 3449.7405 3490.8677 3531.9951 3061.3989 3102.5261 3143.6533 2691.5496 2732.677 2773.8042 2321.7004 2362.8276 2403.9551 1951.8512 1992.9785 2034.1057 1582.0022 1623.1293 1664.2563"
+       y="-4240.4385"><tspan
+	 x="6020.1929 6061.3198 6102.4473 5650.3433 5691.4707 5732.5981 5280.4941 5321.6216 5362.7485 4910.645 4951.7725 4992.8994 4540.7959 4581.9229 4623.0503 4170.9468 4212.0737 4253.2012 3801.0974 3842.2246 3883.3518 3449.7405 3490.8677 3531.9951 3061.3989 3102.5261 3143.6533 2691.5496 2732.677 2773.8042 2321.7004 2362.8276 2403.9551 1951.8512 1992.9785 2034.1057 1582.0022 1623.1293 1664.2563"
+	 y="-4240.4385"
+	 sodipodi:role="line"
+	 id="tspan4089">336335321320319318317316315314313312311</tspan></text>
+<text
+       transform="scale(1,-1)"
+       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       id="text4091"
+       x="2732.6765 5321.6211 5670.9062 5712.0337 6040.7554 6081.8828 842.30634 883.43323 924.56055"
+       y="-4129.4834"><tspan
+	 x="2732.6765 5321.6211 5670.9062 5712.0337 6040.7554 6081.8828 842.30634 883.43323 924.56055"
+	 y="-4129.4834"
+	 sodipodi:role="line"
+	 id="tspan4093">182223309</tspan></text>
+<text
+       transform="scale(1,-1)"
+       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       id="text4095"
+       x="842.30634 883.43323 924.56055"
+       y="-4240.4385"><tspan
+	 x="842.30634 883.43323 924.56055"
+	 y="-4240.4385"
+	 sodipodi:role="line"
+	 id="tspan4097">309</tspan></text>
+<text
+       transform="scale(1,-1)"
+       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       id="text4099"
+       x="1212.1553 1253.2826 1294.4099"
+       y="-4129.4834"><tspan
+	 x="1212.1553 1253.2826 1294.4099"
+	 y="-4129.4834"
+	 sodipodi:role="line"
+	 id="tspan4101">310</tspan></text>
+<text
+       transform="scale(1,-1)"
+       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       id="text4103"
+       x="1212.1553 1253.2826 1294.4099"
+       y="-4240.4385"><tspan
+	 x="1212.1553 1253.2826 1294.4099"
+	 y="-4240.4385"
+	 sodipodi:role="line"
+	 id="tspan4105">310</tspan></text>
+<text
+       transform="scale(1,-1)"
+       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       id="text4107"
+       x="6410.605 6451.7319"
+       y="-4129.4834"><tspan
+	 x="6410.605 6451.7319"
+	 y="-4129.4834"
+	 sodipodi:role="line"
+	 id="tspan4109">24</tspan></text>
+<text
+       transform="scale(1,-1)"
+       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       id="text4111"
+       x="6390.041 6431.1685 6472.2954"
+       y="-4240.4385"><tspan
+	 x="6390.041 6431.1685 6472.2954"
+	 y="-4240.4385"
+	 sodipodi:role="line"
+	 id="tspan4113">337</tspan></text>
+<text
+       transform="scale(1,-1)"
+       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       id="text4115"
+       x="6040.7559 6081.8833"
+       y="-4943.1504"><tspan
+	 x="6040.7559 6081.8833"
+	 y="-4943.1504"
+	 sodipodi:role="line"
+	 id="tspan4117">23</tspan></text>
+<text
+       transform="scale(1,-1)"
+       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       id="text4119"
+       x="6040.7559 6081.8833"
+       y="-5054.106"><tspan
+	 x="6040.7559 6081.8833"
+	 y="-5054.106"
+	 sodipodi:role="line"
+	 id="tspan4121">23</tspan></text>
+<text
+       transform="scale(1,-1)"
+       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       id="text4123"
+       x="6410.605 6451.7324"
+       y="-4943.1504"><tspan
+	 x="6410.605 6451.7324"
+	 y="-4943.1504"
+	 sodipodi:role="line"
+	 id="tspan4125">24</tspan></text>
+<text
+       transform="scale(1,-1)"
+       style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       id="text4127"
+       x="6410.605 6451.7324"
+       y="-5054.106"><tspan
+	 x="6410.605 6451.7324"
+	 y="-5054.106"
+	 sodipodi:role="line"
+	 id="tspan4129">24</tspan></text>
+</g></svg>
diff --git a/Documentation/userspace-api/media/v4l/vbi_hsync.svg b/Documentation/userspace-api/media/v4l/vbi_hsync.svg
new file mode 100644
index 000000000000..77606a7b00a4
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vbi_hsync.svg
@@ -0,0 +1,321 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+    Permission is granted to copy, distribute and/or modify this
+    document under the terms of the GNU Free Documentation License,
+    Version 1.1 or any later version published by the Free Software
+    Foundation, with no Invariant Sections, no Front-Cover Texts
+    and no Back-Cover Texts. A copy of the license is included at
+    Documentation/userspace-api/media/fdl-appendix.rst.
+
+    TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+-->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.91 r13725"
+   xml:space="preserve"
+   width="192.39857mm"
+   height="146.83536mm"
+   viewBox="0 0 681.72724 520.28277"
+   sodipodi:docname="vbi_hsync.svg"><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="997"
+     id="namedview4"
+     showgrid="false"
+     inkscape:zoom="1.5350601"
+     inkscape:cx="131.95463"
+     inkscape:cy="428.88132"
+     inkscape:window-x="1920"
+     inkscape:window-y="30"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="g10"
+     units="mm"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" /><metadata
+     id="metadata8"><rdf:RDF><cc:Work
+	 rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+	   rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
+     id="defs6"><clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath30"><path
+	 d="m 0,0 0,1163 1544,0 L 1544,0 0,0 Z m 187.184,836.05 0,-19.278 48.517,0 -38.556,9.639 38.556,9.639 -48.517,0 z m 689.189,-19.278 0,19.278 -48.516,0 38.556,-9.639 -38.556,-9.639 48.516,0 z"
+	 id="path32"
+	 inkscape:connector-curvature="0"
+	 style="clip-rule:evenodd" /></clipPath><clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath52"><path
+	 d="m 0,0 0,1163 1544,0 L 1544,0 0,0 Z m 804.08,79.3887 0,19.2778 -48.516,0 38.556,-9.6389 -38.556,-9.6389 48.516,0 z m -703.647,19.2778 0,-19.2778 48.517,0 -38.556,9.6389 38.556,9.6389 -48.517,0 z"
+	 id="path54"
+	 inkscape:connector-curvature="0"
+	 style="clip-rule:evenodd" /></clipPath><clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath94"><path
+	 d="m 0,0 0,1163 1544,0 L 1544,0 0,0 Z m 471.535,195.057 0,19.278 -48.516,0 38.555,-9.639 -38.555,-9.639 48.516,0 z m -284.351,19.278 0,-19.278 48.517,0 -38.556,9.639 38.556,9.639 -48.517,0 z"
+	 id="path96"
+	 inkscape:connector-curvature="0"
+	 style="clip-rule:evenodd" /></clipPath></defs><g
+     id="g10"
+     inkscape:groupmode="layer"
+     inkscape:label="vbi_hsync"
+     transform="matrix(1.25,0,0,-1.25,-0.3625824,520.79867)"><g
+       id="g14"
+       transform="matrix(0.36030235,0,0,0.36030235,-0.75498483,-1.0743684)"
+       style=""><path
+	 inkscape:connector-curvature="0"
+	 id="path16"
+	 style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="M 32.9604,580.617 4.04346,493.866" /><path
+	 inkscape:connector-curvature="0"
+	 id="path18"
+	 style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 192.004,855.328 0,-665.091" /><path
+	 inkscape:connector-curvature="0"
+	 id="path20"
+	 style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 466.715,392.656 0,-202.419" /><path
+	 inkscape:connector-curvature="0"
+	 id="path22"
+	 style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 799.261,508.324 0,-433.7549" /><path
+	 inkscape:connector-curvature="0"
+	 id="path24"
+	 style="fill:none;stroke:#000000;stroke-width:4.81949997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 857.095,537.241 231.335,0" /></g><g
+       id="g26"
+       transform="matrix(0.36030235,0,0,0.36030235,-0.75498483,-1.0743684)"
+       style=""><g
+	 clip-path="url(#clipPath30)"
+	 id="g28"
+	 style=""><path
+	   inkscape:connector-curvature="0"
+	   id="path34"
+	   style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	   d="m 871.553,826.411 -679.549,0" /></g></g><g
+       id="g36"
+       transform="matrix(0.36030235,0,0,0.36030235,-0.75498483,-1.0743684)"
+       style=""><path
+	 inkscape:connector-curvature="0"
+	 id="path38"
+	 style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+	 d="m 827.857,816.772 38.556,9.639 -38.556,9.639 0,-19.278" /><path
+	 inkscape:connector-curvature="0"
+	 id="path40"
+	 style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 827.857,816.772 38.556,9.639 -38.556,9.639 0,-19.278 z" /><path
+	 inkscape:connector-curvature="0"
+	 id="path42"
+	 style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+	 d="m 235.701,836.05 -38.556,-9.639 38.556,-9.639 0,19.278" /><path
+	 inkscape:connector-curvature="0"
+	 id="path44"
+	 style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 235.701,836.05 -38.556,-9.639 38.556,-9.639 0,19.278 z" /><path
+	 inkscape:connector-curvature="0"
+	 id="path46"
+	 style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	 d="m 1073.97,493.866 28.92,86.751" /></g><g
+       id="g48"
+       transform="matrix(0.36030235,0,0,0.36030235,-0.75498483,-1.0743684)"
+       style=""><g
+	 clip-path="url(#clipPath52)"
+	 id="g50"
+	 style=""><path
+	   inkscape:connector-curvature="0"
+	   id="path56"
+	   style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	   d="m 105.253,89.0276 694.008,0" /></g></g><path
+       d="m 52.91205,34.475403 -13.891817,-3.472918 13.891817,-3.472918 0,6.945836"
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path60"
+       inkscape:connector-curvature="0" /><path
+       d="m 52.91205,34.475403 -13.891817,-3.472918 13.891817,-3.472918 0,6.945836 z"
+       style="fill:none;stroke:#000000;stroke-width:0.86823857;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path62"
+       inkscape:connector-curvature="0" /><path
+       d="m 271.4765,27.529567 13.89182,3.472918 -13.89182,3.472918 0,-6.945836"
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path64"
+       inkscape:connector-curvature="0" /><path
+       d="m 271.4765,27.529567 13.89182,3.472918 -13.89182,3.472918 0,-6.945836 z"
+       style="fill:none;stroke:#000000;stroke-width:0.86823857;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path66"
+       inkscape:connector-curvature="0" /><path
+       d="m 5.9113292,192.49483 31.2565888,0 0,-10.41887 26.046978,0 10.418863,-93.769765 88.560511,0 10.41887,93.769765 10.41886,0"
+       style="fill:none;stroke:#000000;stroke-width:1.73647714;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path68"
+       inkscape:connector-curvature="0" /><path
+       d="m 162.19427,88.306195 260.47086,0"
+       style="fill:none;stroke:#000000;stroke-width:0.86823857;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path70"
+       inkscape:connector-curvature="0" /><path
+       d="m 37.167918,182.07596 0,-156.282907"
+       style="fill:none;stroke:#000000;stroke-width:0.86823857;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path72"
+       inkscape:connector-curvature="0" /><path
+       d="m 235.12632,182.07596 52.09431,0 0,10.41887 20.83773,0 10.41886,208.3769 83.35162,0"
+       style="fill:none;stroke:#000000;stroke-width:1.73647714;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path74"
+       inkscape:connector-curvature="0" /><path
+       d="m 391.4089,192.49483 31.25623,0"
+       style="fill:none;stroke:#000000;stroke-width:0.86823857;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path76"
+       inkscape:connector-curvature="0" /><path
+       d="m 401.82884,400.87173 20.83629,0"
+       style="fill:none;stroke:#000000;stroke-width:0.86823857;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path78"
+       inkscape:connector-curvature="0" /><path
+       d="m 328.89608,192.49483 10.41887,208.3769"
+       style="fill:none;stroke:#000000;stroke-width:0.86823857;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path80"
+       inkscape:connector-curvature="0" /><path
+       d="m 349.73381,192.49483 10.41886,208.3769"
+       style="fill:none;stroke:#000000;stroke-width:0.86823857;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path82"
+       inkscape:connector-curvature="0" /><path
+       d="m 370.57262,192.49483 10.41634,208.3769"
+       style="fill:none;stroke:#000000;stroke-width:0.86823857;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path84"
+       inkscape:connector-curvature="0" /><path
+       d="m 396.61887,385.24541 10.41995,31.25623"
+       style="fill:none;stroke:#000000;stroke-width:0.86823857;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path86"
+       inkscape:connector-curvature="0" /><path
+       d="m 183.032,135.19126 52.09432,0 0,93.76977 -52.09432,0 0,-93.76977 z"
+       style="fill:none;stroke:#000000;stroke-width:1.73647714;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path88"
+       inkscape:connector-curvature="0" /><g
+       id="g90"
+       transform="matrix(0.36030235,0,0,0.36030235,-0.75498483,-1.0743684)"
+       style=""><g
+	 clip-path="url(#clipPath94)"
+	 id="g92"
+	 style=""><path
+	   inkscape:connector-curvature="0"
+	   id="path98"
+	   style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+	   d="m 192.004,204.696 274.711,0" /></g></g><path
+       d="m 84.168639,76.151036 -13.891817,-3.472955 13.891817,-3.472954 0,6.945909"
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path102"
+       inkscape:connector-curvature="0" /><path
+       d="m 84.168639,76.151036 -13.891817,-3.472955 13.891817,-3.472954 0,6.945909 z"
+       style="fill:none;stroke:#000000;stroke-width:0.86823857;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path104"
+       inkscape:connector-curvature="0" /><path
+       d="m 151.65975,69.205127 13.89146,3.472954 -13.89146,3.472955 0,-6.945909"
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="path106"
+       inkscape:connector-curvature="0" /><path
+       d="m 151.65975,69.205127 13.89146,3.472954 -13.89146,3.472955 0,-6.945909 z"
+       style="fill:none;stroke:#000000;stroke-width:0.86823857;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+       id="path108"
+       inkscape:connector-curvature="0" /><text
+       id="text112"
+       style="font-variant:normal;font-weight:normal;font-size:20.83772659px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"
+       x="438.29504"
+       y="-187.28558"><tspan
+	 id="tspan114"
+	 sodipodi:role="line"
+	 y="-187.28558"
+	 x="438.29504 452.19382 456.81979 468.40555 478.82443 489.24329 495.03619 506.62195 518.2077 528.62659 540.21234">Black Level</tspan><tspan
+	 id="tspan116"
+	 sodipodi:role="line"
+	 y="-83.096947"
+	 x="438.29504 452.19382 462.61267 474.19846 484.61731 490.41019 501.99597 513.58173 524.00061 535.58636">Sync Level</tspan><tspan
+	 id="tspan118"
+	 sodipodi:role="line"
+	 y="-395.66284"
+	 x="438.29504 457.96585 469.55164 474.17761 479.97049 491.55627 497.34915 508.93494 520.52069 530.93958 542.52533">White Level</tspan></text>
+<text
+       id="text120"
+       style="font-variant:normal;font-weight:normal;font-size:20.83772659px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"
+       x="159.88258"
+       y="-270.63647"><tspan
+	 id="tspan122"
+	 sodipodi:role="line"
+	 y="-270.63647"
+	 x="159.88258 172.61443 179.55339 186.49236 198.07812 209.66391">offset</tspan></text>
+<text
+       id="text124"
+       style="font-variant:normal;font-weight:normal;font-size:20.83772659px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"
+       x="46.973549"
+       y="-46.630745"><tspan
+	 id="tspan126"
+	 sodipodi:role="line"
+	 y="-46.630745"
+	 x="46.973549 58.559322 63.185299 74.771072 86.35685 92.149734 102.5686 112.98746 124.57324 134.9921 146.57788 153.51685 159.30972 165.10262 176.68839 188.27417 192.90015 203.319">Line synchr. pulse</tspan><tspan
+	 id="tspan128"
+	 sodipodi:role="line"
+	 y="-4.9552913"
+	 x="100.80776 112.39354 117.01952 128.60529 140.19107 145.98395 157.56973 162.19569 173.78148 185.36726 195.78612 200.41209 211.99788">Line blanking</tspan></text>
+<text
+       id="text3473"
+       style="font-variant:normal;font-weight:normal;font-size:20.83772659px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"
+       x="46.973549 58.559322 63.185299 74.771072 86.35685 92.149734 102.5686 112.98746 124.57324 134.9921 146.57788 153.51685 159.30972 165.10262 176.68839 188.27417 192.90015 203.319"
+       y="-46.630745"><tspan
+	 id="tspan3475"
+	 sodipodi:role="line"
+	 y="-46.630745"
+	 x="46.973549 58.559322 63.185299 74.771072 86.35685 92.149734 102.5686 112.98746 124.57324 134.9921 146.57788 153.51685 159.30972 165.10262 176.68839 188.27417 192.90015 203.319">Line synchr. pulse</tspan></text>
+<text
+       id="text3477"
+       style="font-variant:normal;font-weight:normal;font-size:20.83772659px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"
+       x="100.80776 112.39354 117.01952 128.60529 140.19107 145.98395 157.56973 162.19569 173.78148 185.36726 195.78612 200.41209 211.99788"
+       y="-4.9552913"><tspan
+	 id="tspan3479"
+	 sodipodi:role="line"
+	 y="-4.9552913"
+	 x="100.80776 112.39354 117.01952 128.60529 140.19107 145.98395 157.56973 162.19569 173.78148 185.36726 195.78612 200.41209 211.99788">Line blanking</tspan></text>
+<text
+       id="text3607"
+       style="font-variant:normal;font-weight:normal;font-size:20.83772659px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"
+       x="438.29504 452.19382 456.81979 468.40555 478.82443 489.24329 495.03619 506.62195 518.2077 528.62659 540.21234"
+       y="-187.28558"><tspan
+	 id="tspan3609"
+	 sodipodi:role="line"
+	 y="-187.28558"
+	 x="438.29504 452.19382 456.81979 468.40555 478.82443 489.24329 495.03619 506.62195 518.2077 528.62659 540.21234">Black Level</tspan></text>
+<text
+       id="text3611"
+       style="font-variant:normal;font-weight:normal;font-size:20.83772659px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"
+       x="438.29504 452.19382 462.61267 474.19846 484.61731 490.41019 501.99597 513.58173 524.00061 535.58636"
+       y="-83.096947"><tspan
+	 id="tspan3613"
+	 sodipodi:role="line"
+	 y="-83.096947"
+	 x="438.29504 452.19382 462.61267 474.19846 484.61731 490.41019 501.99597 513.58173 524.00061 535.58636">Sync Level</tspan></text>
+<text
+       id="text3615"
+       style="font-variant:normal;font-weight:normal;font-size:20.83772659px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
+       transform="scale(1,-1)"
+       x="438.29504 457.96585 469.55164 474.17761 479.97049 491.55627 497.34915 508.93494 520.52069 530.93958 542.52533"
+       y="-395.66284"><tspan
+	 id="tspan3617"
+	 sodipodi:role="line"
+	 y="-395.66284"
+	 x="438.29504 457.96585 469.55164 474.17761 479.97049 491.55627 497.34915 508.93494 520.52069 530.93958 542.52533">White Level</tspan></text>
+</g></svg>
diff --git a/Documentation/userspace-api/media/v4l/video.rst b/Documentation/userspace-api/media/v4l/video.rst
new file mode 100644
index 000000000000..9b73dba0eb8d
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/video.rst
@@ -0,0 +1,75 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _video:
+
+************************
+Video Inputs and Outputs
+************************
+
+Video inputs and outputs are physical connectors of a device. These can
+be for example: RF connectors (antenna/cable), CVBS a.k.a. Composite
+Video, S-Video and RGB connectors. Camera sensors are also considered to
+be a video input. Video and VBI capture devices have inputs. Video and
+VBI output devices have outputs, at least one each. Radio devices have
+no video inputs or outputs.
+
+To learn about the number and attributes of the available inputs and
+outputs applications can enumerate them with the
+:ref:`VIDIOC_ENUMINPUT` and
+:ref:`VIDIOC_ENUMOUTPUT` ioctl, respectively. The
+struct :c:type:`v4l2_input` returned by the
+:ref:`VIDIOC_ENUMINPUT` ioctl also contains signal
+status information applicable when the current video input is queried.
+
+The :ref:`VIDIOC_G_INPUT <VIDIOC_G_INPUT>` and
+:ref:`VIDIOC_G_OUTPUT <VIDIOC_G_OUTPUT>` ioctls return the index of
+the current video input or output. To select a different input or output
+applications call the :ref:`VIDIOC_S_INPUT <VIDIOC_G_INPUT>` and
+:ref:`VIDIOC_S_OUTPUT <VIDIOC_G_OUTPUT>` ioctls. Drivers must
+implement all the input ioctls when the device has one or more inputs,
+all the output ioctls when the device has one or more outputs.
+
+Example: Information about the current video input
+==================================================
+
+.. code-block:: c
+
+    struct v4l2_input input;
+    int index;
+
+    if (-1 == ioctl(fd, VIDIOC_G_INPUT, &index)) {
+	perror("VIDIOC_G_INPUT");
+	exit(EXIT_FAILURE);
+    }
+
+    memset(&input, 0, sizeof(input));
+    input.index = index;
+
+    if (-1 == ioctl(fd, VIDIOC_ENUMINPUT, &input)) {
+	perror("VIDIOC_ENUMINPUT");
+	exit(EXIT_FAILURE);
+    }
+
+    printf("Current input: %s\\n", input.name);
+
+
+Example: Switching to the first video input
+===========================================
+
+.. code-block:: c
+
+    int index;
+
+    index = 0;
+
+    if (-1 == ioctl(fd, VIDIOC_S_INPUT, &index)) {
+	perror("VIDIOC_S_INPUT");
+	exit(EXIT_FAILURE);
+    }
diff --git a/Documentation/userspace-api/media/v4l/videodev.rst b/Documentation/userspace-api/media/v4l/videodev.rst
new file mode 100644
index 000000000000..c8244b895802
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/videodev.rst
@@ -0,0 +1,16 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _videodev:
+
+*******************************
+Video For Linux Two Header File
+*******************************
+
+.. kernel-include:: $BUILDDIR/videodev2.h.rst
diff --git a/Documentation/userspace-api/media/v4l/vidioc-create-bufs.rst b/Documentation/userspace-api/media/v4l/vidioc-create-bufs.rst
new file mode 100644
index 000000000000..bd580232be10
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-create-bufs.rst
@@ -0,0 +1,141 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_CREATE_BUFS:
+
+************************
+ioctl VIDIOC_CREATE_BUFS
+************************
+
+Name
+====
+
+VIDIOC_CREATE_BUFS - Create buffers for Memory Mapped or User Pointer or DMA Buffer I/O
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_CREATE_BUFS, struct v4l2_create_buffers *argp )
+    :name: VIDIOC_CREATE_BUFS
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_create_buffers`.
+
+
+Description
+===========
+
+This ioctl is used to create buffers for :ref:`memory mapped <mmap>`
+or :ref:`user pointer <userp>` or :ref:`DMA buffer <dmabuf>` I/O. It
+can be used as an alternative or in addition to the
+:ref:`VIDIOC_REQBUFS` ioctl, when a tighter control
+over buffers is required. This ioctl can be called multiple times to
+create buffers of different sizes.
+
+To allocate the device buffers applications must initialize the relevant
+fields of the struct :c:type:`v4l2_create_buffers` structure. The
+``count`` field must be set to the number of requested buffers, the
+``memory`` field specifies the requested I/O method and the ``reserved``
+array must be zeroed.
+
+The ``format`` field specifies the image format that the buffers must be
+able to handle. The application has to fill in this struct
+:c:type:`v4l2_format`. Usually this will be done using the
+:ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` or
+:ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` ioctls to ensure that the
+requested format is supported by the driver. Based on the format's
+``type`` field the requested buffer size (for single-planar) or plane
+sizes (for multi-planar formats) will be used for the allocated buffers.
+The driver may return an error if the size(s) are not supported by the
+hardware (usually because they are too small).
+
+The buffers created by this ioctl will have as minimum size the size
+defined by the ``format.pix.sizeimage`` field (or the corresponding
+fields for other format types). Usually if the ``format.pix.sizeimage``
+field is less than the minimum required for the given format, then an
+error will be returned since drivers will typically not allow this. If
+it is larger, then the value will be used as-is. In other words, the
+driver may reject the requested size, but if it is accepted the driver
+will use it unchanged.
+
+When the ioctl is called with a pointer to this structure the driver
+will attempt to allocate up to the requested number of buffers and store
+the actual number allocated and the starting index in the ``count`` and
+the ``index`` fields respectively. On return ``count`` can be smaller
+than the number requested.
+
+
+.. c:type:: v4l2_create_buffers
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. flat-table:: struct v4l2_create_buffers
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``index``
+      - The starting buffer index, returned by the driver.
+    * - __u32
+      - ``count``
+      - The number of buffers requested or granted. If count == 0, then
+	:ref:`VIDIOC_CREATE_BUFS` will set ``index`` to the current number of
+	created buffers, and it will check the validity of ``memory`` and
+	``format.type``. If those are invalid -1 is returned and errno is
+	set to ``EINVAL`` error code, otherwise :ref:`VIDIOC_CREATE_BUFS` returns
+	0. It will never set errno to ``EBUSY`` error code in this particular
+	case.
+    * - __u32
+      - ``memory``
+      - Applications set this field to ``V4L2_MEMORY_MMAP``,
+	``V4L2_MEMORY_DMABUF`` or ``V4L2_MEMORY_USERPTR``. See
+	:c:type:`v4l2_memory`
+    * - struct :c:type:`v4l2_format`
+      - ``format``
+      - Filled in by the application, preserved by the driver.
+    * - __u32
+      - ``capabilities``
+      - Set by the driver. If 0, then the driver doesn't support
+        capabilities. In that case all you know is that the driver is
+	guaranteed to support ``V4L2_MEMORY_MMAP`` and *might* support
+	other :c:type:`v4l2_memory` types. It will not support any others
+	capabilities. See :ref:`here <v4l2-buf-capabilities>` for a list of the
+	capabilities.
+
+	If you want to just query the capabilities without making any
+	other changes, then set ``count`` to 0, ``memory`` to
+	``V4L2_MEMORY_MMAP`` and ``format.type`` to the buffer type.
+    * - __u32
+      - ``reserved``\ [7]
+      - A place holder for future extensions. Drivers and applications
+	must set the array to zero.
+
+
+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.
+
+ENOMEM
+    No memory to allocate buffers for :ref:`memory mapped <mmap>` I/O.
+
+EINVAL
+    The buffer type (``format.type`` field), requested I/O method
+    (``memory``) or format (``format`` field) is not valid.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-cropcap.rst b/Documentation/userspace-api/media/v4l/vidioc-cropcap.rst
new file mode 100644
index 000000000000..035ed9d577ae
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-cropcap.rst
@@ -0,0 +1,143 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_CROPCAP:
+
+********************
+ioctl VIDIOC_CROPCAP
+********************
+
+Name
+====
+
+VIDIOC_CROPCAP - Information about the video cropping and scaling abilities
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_CROPCAP, struct v4l2_cropcap *argp )
+    :name: VIDIOC_CROPCAP
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_cropcap`.
+
+
+Description
+===========
+
+Applications use this function to query the cropping limits, the pixel
+aspect of images and to calculate scale factors. They set the ``type``
+field of a v4l2_cropcap structure to the respective buffer (stream)
+type and call the :ref:`VIDIOC_CROPCAP` ioctl with a pointer to this
+structure. Drivers fill the rest of the structure. The results are
+constant except when switching the video standard. Remember this switch
+can occur implicit when switching the video input or output.
+
+This ioctl must be implemented for video capture or output devices that
+support cropping and/or scaling and/or have non-square pixels, and for
+overlay devices.
+
+.. c:type:: v4l2_cropcap
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. flat-table:: struct v4l2_cropcap
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``type``
+      - Type of the data stream, set by the application. Only these types
+	are valid here: ``V4L2_BUF_TYPE_VIDEO_CAPTURE``, ``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE``,
+	``V4L2_BUF_TYPE_VIDEO_OUTPUT``, ``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE`` and
+	``V4L2_BUF_TYPE_VIDEO_OVERLAY``. See :c:type:`v4l2_buf_type` and the note below.
+    * - struct :ref:`v4l2_rect <v4l2-rect-crop>`
+      - ``bounds``
+      - Defines the window within capturing or output is possible, this
+	may exclude for example the horizontal and vertical blanking
+	areas. The cropping rectangle cannot exceed these limits. Width
+	and height are defined in pixels, the driver writer is free to
+	choose origin and units of the coordinate system in the analog
+	domain.
+    * - struct :ref:`v4l2_rect <v4l2-rect-crop>`
+      - ``defrect``
+      - Default cropping rectangle, it shall cover the "whole picture".
+	Assuming pixel aspect 1/1 this could be for example a 640 × 480
+	rectangle for NTSC, a 768 × 576 rectangle for PAL and SECAM
+	centered over the active picture area. The same co-ordinate system
+	as for ``bounds`` is used.
+    * - struct :c:type:`v4l2_fract`
+      - ``pixelaspect``
+      - This is the pixel aspect (y / x) when no scaling is applied, the
+	ratio of the actual sampling frequency and the frequency required
+	to get square pixels.
+
+	When cropping coordinates refer to square pixels, the driver sets
+	``pixelaspect`` to 1/1. Other common values are 54/59 for PAL and
+	SECAM, 11/10 for NTSC sampled according to [:ref:`itu601`].
+
+.. note::
+   Unfortunately in the case of multiplanar buffer types
+   (``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE`` and ``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE``)
+   this API was messed up with regards to how the :c:type:`v4l2_cropcap` ``type`` field
+   should be filled in. Some drivers only accepted the ``_MPLANE`` buffer type while
+   other drivers only accepted a non-multiplanar buffer type (i.e. without the
+   ``_MPLANE`` at the end).
+
+   Starting with kernel 4.13 both variations are allowed.
+
+
+
+.. _v4l2-rect-crop:
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. flat-table:: struct v4l2_rect
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __s32
+      - ``left``
+      - Horizontal offset of the top, left corner of the rectangle, in
+	pixels.
+    * - __s32
+      - ``top``
+      - Vertical offset of the top, left corner of the rectangle, in
+	pixels.
+    * - __u32
+      - ``width``
+      - Width of the rectangle, in pixels.
+    * - __u32
+      - ``height``
+      - Height of the rectangle, in pixels.
+
+
+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
+    The struct :c:type:`v4l2_cropcap` ``type`` is
+    invalid.
+
+ENODATA
+    Cropping is not supported for this input or output.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-dbg-g-chip-info.rst b/Documentation/userspace-api/media/v4l/vidioc-dbg-g-chip-info.rst
new file mode 100644
index 000000000000..16078a2d3e3d
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-dbg-g-chip-info.rst
@@ -0,0 +1,167 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_DBG_G_CHIP_INFO:
+
+****************************
+ioctl VIDIOC_DBG_G_CHIP_INFO
+****************************
+
+Name
+====
+
+VIDIOC_DBG_G_CHIP_INFO - Identify the chips on a TV card
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_DBG_G_CHIP_INFO, struct v4l2_dbg_chip_info *argp )
+    :name: VIDIOC_DBG_G_CHIP_INFO
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_dbg_chip_info`.
+
+
+Description
+===========
+
+.. note::
+
+    This is an :ref:`experimental` interface and may
+    change in the future.
+
+For driver debugging purposes this ioctl allows test applications to
+query the driver about the chips present on the TV card. Regular
+applications must not use it. When you found a chip specific bug, please
+contact the linux-media mailing list
+(`https://linuxtv.org/lists.php <https://linuxtv.org/lists.php>`__)
+so it can be fixed.
+
+Additionally the Linux kernel must be compiled with the
+``CONFIG_VIDEO_ADV_DEBUG`` option to enable this ioctl.
+
+To query the driver applications must initialize the ``match.type`` and
+``match.addr`` or ``match.name`` fields of a struct
+:c:type:`v4l2_dbg_chip_info` and call
+:ref:`VIDIOC_DBG_G_CHIP_INFO` with a pointer to this structure. On success
+the driver stores information about the selected chip in the ``name``
+and ``flags`` fields.
+
+When ``match.type`` is ``V4L2_CHIP_MATCH_BRIDGE``, ``match.addr``
+selects the nth bridge 'chip' on the TV card. You can enumerate all
+chips by starting at zero and incrementing ``match.addr`` by one until
+:ref:`VIDIOC_DBG_G_CHIP_INFO` fails with an ``EINVAL`` error code. The number
+zero always selects the bridge chip itself, e. g. the chip connected to
+the PCI or USB bus. Non-zero numbers identify specific parts of the
+bridge chip such as an AC97 register block.
+
+When ``match.type`` is ``V4L2_CHIP_MATCH_SUBDEV``, ``match.addr``
+selects the nth sub-device. This allows you to enumerate over all
+sub-devices.
+
+On success, the ``name`` field will contain a chip name and the
+``flags`` field will contain ``V4L2_CHIP_FL_READABLE`` if the driver
+supports reading registers from the device or ``V4L2_CHIP_FL_WRITABLE``
+if the driver supports writing registers to the device.
+
+We recommended the v4l2-dbg utility over calling this ioctl directly. It
+is available from the LinuxTV v4l-dvb repository; see
+`https://linuxtv.org/repo/ <https://linuxtv.org/repo/>`__ for access
+instructions.
+
+
+.. tabularcolumns:: |p{3.5cm}|p{3.5cm}|p{3.5cm}|p{7.0cm}|
+
+.. _name-v4l2-dbg-match:
+
+.. flat-table:: struct v4l2_dbg_match
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``type``
+      - See :ref:`name-chip-match-types` for a list of possible types.
+    * - union {
+      - (anonymous)
+    * - __u32
+      - ``addr``
+      - Match a chip by this number, interpreted according to the ``type``
+	field.
+    * - char
+      - ``name[32]``
+      - Match a chip by this name, interpreted according to the ``type``
+	field. Currently unused.
+    * - }
+      -
+
+
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. c:type:: v4l2_dbg_chip_info
+
+.. flat-table:: struct v4l2_dbg_chip_info
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - struct v4l2_dbg_match
+      - ``match``
+      - How to match the chip, see :ref:`name-v4l2-dbg-match`.
+    * - char
+      - ``name[32]``
+      - The name of the chip.
+    * - __u32
+      - ``flags``
+      - Set by the driver. If ``V4L2_CHIP_FL_READABLE`` is set, then the
+	driver supports reading registers from the device. If
+	``V4L2_CHIP_FL_WRITABLE`` is set, then it supports writing
+	registers.
+    * - __u32
+      - ``reserved[8]``
+      - Reserved fields, both application and driver must set these to 0.
+
+
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. _name-chip-match-types:
+
+.. flat-table:: Chip Match Types
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_CHIP_MATCH_BRIDGE``
+      - 0
+      - Match the nth chip on the card, zero for the bridge chip. Does not
+	match sub-devices.
+    * - ``V4L2_CHIP_MATCH_SUBDEV``
+      - 4
+      - Match the nth sub-device.
+
+
+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
+    The ``match_type`` is invalid or no device could be matched.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-dbg-g-register.rst b/Documentation/userspace-api/media/v4l/vidioc-dbg-g-register.rst
new file mode 100644
index 000000000000..6311a63278a5
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-dbg-g-register.rst
@@ -0,0 +1,171 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_DBG_G_REGISTER:
+
+**************************************************
+ioctl VIDIOC_DBG_G_REGISTER, VIDIOC_DBG_S_REGISTER
+**************************************************
+
+Name
+====
+
+VIDIOC_DBG_G_REGISTER - VIDIOC_DBG_S_REGISTER - Read or write hardware registers
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_DBG_G_REGISTER, struct v4l2_dbg_register *argp )
+    :name: VIDIOC_DBG_G_REGISTER
+
+.. c:function:: int ioctl( int fd, VIDIOC_DBG_S_REGISTER, const struct v4l2_dbg_register *argp )
+    :name: VIDIOC_DBG_S_REGISTER
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_dbg_register`.
+
+
+Description
+===========
+
+.. note::
+
+    This is an :ref:`experimental` interface and may
+    change in the future.
+
+For driver debugging purposes these ioctls allow test applications to
+access hardware registers directly. Regular applications must not use
+them.
+
+Since writing or even reading registers can jeopardize the system
+security, its stability and damage the hardware, both ioctls require
+superuser privileges. Additionally the Linux kernel must be compiled
+with the ``CONFIG_VIDEO_ADV_DEBUG`` option to enable these ioctls.
+
+To write a register applications must initialize all fields of a struct
+:c:type:`v4l2_dbg_register` except for ``size`` and
+call ``VIDIOC_DBG_S_REGISTER`` with a pointer to this structure. The
+``match.type`` and ``match.addr`` or ``match.name`` fields select a chip
+on the TV card, the ``reg`` field specifies a register number and the
+``val`` field the value to be written into the register.
+
+To read a register applications must initialize the ``match.type``,
+``match.addr`` or ``match.name`` and ``reg`` fields, and call
+``VIDIOC_DBG_G_REGISTER`` with a pointer to this structure. On success
+the driver stores the register value in the ``val`` field and the size
+(in bytes) of the value in ``size``.
+
+When ``match.type`` is ``V4L2_CHIP_MATCH_BRIDGE``, ``match.addr``
+selects the nth non-sub-device chip on the TV card. The number zero
+always selects the host chip, e. g. the chip connected to the PCI or USB
+bus. You can find out which chips are present with the
+:ref:`VIDIOC_DBG_G_CHIP_INFO` ioctl.
+
+When ``match.type`` is ``V4L2_CHIP_MATCH_SUBDEV``, ``match.addr``
+selects the nth sub-device.
+
+These ioctls are optional, not all drivers may support them. However
+when a driver supports these ioctls it must also support
+:ref:`VIDIOC_DBG_G_CHIP_INFO`. Conversely
+it may support ``VIDIOC_DBG_G_CHIP_INFO`` but not these ioctls.
+
+``VIDIOC_DBG_G_REGISTER`` and ``VIDIOC_DBG_S_REGISTER`` were introduced
+in Linux 2.6.21, but their API was changed to the one described here in
+kernel 2.6.29.
+
+We recommended the v4l2-dbg utility over calling these ioctls directly.
+It is available from the LinuxTV v4l-dvb repository; see
+`https://linuxtv.org/repo/ <https://linuxtv.org/repo/>`__ for access
+instructions.
+
+
+.. tabularcolumns:: |p{3.5cm}|p{3.5cm}|p{3.5cm}|p{7.0cm}|
+
+.. c:type:: v4l2_dbg_match
+
+.. flat-table:: struct v4l2_dbg_match
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``type``
+      - See :ref:`chip-match-types` for a list of possible types.
+    * - union {
+      - (anonymous)
+    * - __u32
+      - ``addr``
+      - Match a chip by this number, interpreted according to the ``type``
+	field.
+    * - char
+      - ``name[32]``
+      - Match a chip by this name, interpreted according to the ``type``
+	field. Currently unused.
+    * - }
+      -
+
+
+
+.. c:type:: v4l2_dbg_register
+
+.. flat-table:: struct v4l2_dbg_register
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - struct v4l2_dbg_match
+      - ``match``
+      - How to match the chip, see :c:type:`v4l2_dbg_match`.
+    * - __u32
+      - ``size``
+      - The register size in bytes.
+    * - __u64
+      - ``reg``
+      - A register number.
+    * - __u64
+      - ``val``
+      - The value read from, or to be written into the register.
+
+
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. _chip-match-types:
+
+.. flat-table:: Chip Match Types
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_CHIP_MATCH_BRIDGE``
+      - 0
+      - Match the nth chip on the card, zero for the bridge chip. Does not
+	match sub-devices.
+    * - ``V4L2_CHIP_MATCH_SUBDEV``
+      - 4
+      - Match the nth sub-device.
+
+
+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.
+
+EPERM
+    Insufficient permissions. Root privileges are required to execute
+    these ioctls.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-decoder-cmd.rst b/Documentation/userspace-api/media/v4l/vidioc-decoder-cmd.rst
new file mode 100644
index 000000000000..7986a248bff9
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-decoder-cmd.rst
@@ -0,0 +1,226 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_DECODER_CMD:
+
+************************************************
+ioctl VIDIOC_DECODER_CMD, VIDIOC_TRY_DECODER_CMD
+************************************************
+
+Name
+====
+
+VIDIOC_DECODER_CMD - VIDIOC_TRY_DECODER_CMD - Execute an decoder command
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_DECODER_CMD, struct v4l2_decoder_cmd *argp )
+    :name: VIDIOC_DECODER_CMD
+
+
+.. c:function:: int ioctl( int fd, VIDIOC_TRY_DECODER_CMD, struct v4l2_decoder_cmd *argp )
+    :name: VIDIOC_TRY_DECODER_CMD
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    pointer to struct :c:type:`v4l2_decoder_cmd`.
+
+
+Description
+===========
+
+These ioctls control an audio/video (usually MPEG-) decoder.
+``VIDIOC_DECODER_CMD`` sends a command to the decoder,
+``VIDIOC_TRY_DECODER_CMD`` can be used to try a command without actually
+executing it. To send a command applications must initialize all fields
+of a struct :c:type:`v4l2_decoder_cmd` and call
+``VIDIOC_DECODER_CMD`` or ``VIDIOC_TRY_DECODER_CMD`` with a pointer to
+this structure.
+
+The ``cmd`` field must contain the command code. Some commands use the
+``flags`` field for additional information.
+
+A :ref:`write() <func-write>` or :ref:`VIDIOC_STREAMON`
+call sends an implicit START command to the decoder if it has not been
+started yet. Applies to both queues of mem2mem decoders.
+
+A :ref:`close() <func-close>` or :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>`
+call of a streaming file descriptor sends an implicit immediate STOP
+command to the decoder, and all buffered data is discarded. Applies to both
+queues of mem2mem decoders.
+
+In principle, these ioctls are optional, not all drivers may support them. They were
+introduced in Linux 3.3. They are, however, mandatory for stateful mem2mem decoders
+(as further documented in :ref:`decoder`).
+
+
+.. tabularcolumns:: |p{1.1cm}|p{2.4cm}|p{1.2cm}|p{1.6cm}|p{10.6cm}|
+
+.. c:type:: v4l2_decoder_cmd
+
+.. cssclass:: longtable
+
+.. flat-table:: struct v4l2_decoder_cmd
+    :header-rows:  0
+    :stub-columns: 0
+    :widths: 1 1 1 3
+
+    * - __u32
+      - ``cmd``
+      -
+      - The decoder command, see :ref:`decoder-cmds`.
+    * - __u32
+      - ``flags``
+      -
+      - Flags to go with the command. If no flags are defined for this
+	command, drivers and applications must set this field to zero.
+    * - union {
+      - (anonymous)
+    * - struct
+      - ``start``
+      -
+      - Structure containing additional data for the
+	``V4L2_DEC_CMD_START`` command.
+    * -
+      - __s32
+      - ``speed``
+      - Playback speed and direction. The playback speed is defined as
+	``speed``/1000 of the normal speed. So 1000 is normal playback.
+	Negative numbers denote reverse playback, so -1000 does reverse
+	playback at normal speed. Speeds -1, 0 and 1 have special
+	meanings: speed 0 is shorthand for 1000 (normal playback). A speed
+	of 1 steps just one frame forward, a speed of -1 steps just one
+	frame back.
+    * -
+      - __u32
+      - ``format``
+      - Format restrictions. This field is set by the driver, not the
+	application. Possible values are ``V4L2_DEC_START_FMT_NONE`` if
+	there are no format restrictions or ``V4L2_DEC_START_FMT_GOP`` if
+	the decoder operates on full GOPs (*Group Of Pictures*). This is
+	usually the case for reverse playback: the decoder needs full
+	GOPs, which it can then play in reverse order. So to implement
+	reverse playback the application must feed the decoder the last
+	GOP in the video file, then the GOP before that, etc. etc.
+    * - struct
+      - ``stop``
+      -
+      - Structure containing additional data for the ``V4L2_DEC_CMD_STOP``
+	command.
+    * -
+      - __u64
+      - ``pts``
+      - Stop playback at this ``pts`` or immediately if the playback is
+	already past that timestamp. Leave to 0 if you want to stop after
+	the last frame was decoded.
+    * - struct
+      - ``raw``
+    * -
+      - __u32
+      - ``data``\ [16]
+      - Reserved for future extensions. Drivers and applications must set
+	the array to zero.
+    * - }
+      -
+
+
+
+.. tabularcolumns:: |p{5.6cm}|p{0.6cm}|p{11.3cm}|
+
+.. _decoder-cmds:
+
+.. flat-table:: Decoder Commands
+    :header-rows:  0
+    :stub-columns: 0
+    :widths: 56 6 113
+
+    * - ``V4L2_DEC_CMD_START``
+      - 0
+      - Start the decoder. When the decoder is already running or paused,
+	this command will just change the playback speed. That means that
+	calling ``V4L2_DEC_CMD_START`` when the decoder was paused will
+	*not* resume the decoder. You have to explicitly call
+	``V4L2_DEC_CMD_RESUME`` for that. This command has one flag:
+	``V4L2_DEC_CMD_START_MUTE_AUDIO``. If set, then audio will be
+	muted when playing back at a non-standard speed.
+
+	For a device implementing the :ref:`decoder`, once the drain sequence
+	is initiated with the ``V4L2_DEC_CMD_STOP`` command, it must be driven
+	to completion before this command can be invoked.  Any attempt to
+	invoke the command while the drain sequence is in progress will trigger
+	an ``EBUSY`` error code.  The command may be also used to restart the
+	decoder in case of an implicit stop initiated by the decoder itself,
+	without the ``V4L2_DEC_CMD_STOP`` being called explicitly. See
+	:ref:`decoder` for more details.
+    * - ``V4L2_DEC_CMD_STOP``
+      - 1
+      - Stop the decoder. When the decoder is already stopped, this
+	command does nothing. This command has two flags: if
+	``V4L2_DEC_CMD_STOP_TO_BLACK`` is set, then the decoder will set
+	the picture to black after it stopped decoding. Otherwise the last
+	image will repeat. If
+	``V4L2_DEC_CMD_STOP_IMMEDIATELY`` is set, then the decoder stops
+	immediately (ignoring the ``pts`` value), otherwise it will keep
+	decoding until timestamp >= pts or until the last of the pending
+	data from its internal buffers was decoded.
+
+	For a device implementing the :ref:`decoder`, the command will initiate
+	the drain sequence as documented in :ref:`decoder`.  No flags or other
+	arguments are accepted in this case. Any attempt to invoke the command
+	again before the sequence completes will trigger an ``EBUSY`` error
+	code.
+    * - ``V4L2_DEC_CMD_PAUSE``
+      - 2
+      - Pause the decoder. When the decoder has not been started yet, the
+	driver will return an ``EPERM`` error code. When the decoder is
+	already paused, this command does nothing. This command has one
+	flag: if ``V4L2_DEC_CMD_PAUSE_TO_BLACK`` is set, then set the
+	decoder output to black when paused.
+    * - ``V4L2_DEC_CMD_RESUME``
+      - 3
+      - Resume decoding after a PAUSE command. When the decoder has not
+	been started yet, the driver will return an ``EPERM`` error code. When
+	the decoder is already running, this command does nothing. No
+	flags are defined for this command.
+    * - ``V4L2_DEC_CMD_FLUSH``
+      - 4
+      - Flush any held capture buffers. Only valid for stateless decoders.
+	This command is typically used when the application reached the
+	end of the stream and the last output buffer had the
+	``V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF`` flag set. This would prevent
+	dequeueing the capture buffer containing the last decoded frame.
+	So this command can be used to explicitly flush that final decoded
+	frame. This command does nothing if there are no held capture buffers.
+
+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.
+
+EBUSY
+    A drain sequence of a device implementing the :ref:`decoder` is still in
+    progress. It is not allowed to issue another decoder command until it
+    completes.
+
+EINVAL
+    The ``cmd`` field is invalid.
+
+EPERM
+    The application sent a PAUSE or RESUME command when the decoder was
+    not running.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-dqevent.rst b/Documentation/userspace-api/media/v4l/vidioc-dqevent.rst
new file mode 100644
index 000000000000..a9a176d5256d
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-dqevent.rst
@@ -0,0 +1,391 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_DQEVENT:
+
+********************
+ioctl VIDIOC_DQEVENT
+********************
+
+Name
+====
+
+VIDIOC_DQEVENT - Dequeue event
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_DQEVENT, struct v4l2_event *argp )
+    :name: VIDIOC_DQEVENT
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_event`.
+
+
+Description
+===========
+
+Dequeue an event from a video device. No input is required for this
+ioctl. All the fields of the struct :c:type:`v4l2_event`
+structure are filled by the driver. The file handle will also receive
+exceptions which the application may get by e.g. using the select system
+call.
+
+
+.. tabularcolumns:: |p{3.0cm}|p{4.4cm}|p{2.4cm}|p{7.7cm}|
+
+.. c:type:: v4l2_event
+
+.. cssclass: longtable
+
+.. flat-table:: struct v4l2_event
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``type``
+      - Type of the event, see :ref:`event-type`.
+    * - union {
+      - ``u``
+    * - struct :c:type:`v4l2_event_vsync`
+      - ``vsync``
+      - Event data for event ``V4L2_EVENT_VSYNC``.
+    * - struct :c:type:`v4l2_event_ctrl`
+      - ``ctrl``
+      - Event data for event ``V4L2_EVENT_CTRL``.
+    * - struct :c:type:`v4l2_event_frame_sync`
+      - ``frame_sync``
+      - Event data for event ``V4L2_EVENT_FRAME_SYNC``.
+    * - struct :c:type:`v4l2_event_motion_det`
+      - ``motion_det``
+      - Event data for event V4L2_EVENT_MOTION_DET.
+    * - struct :c:type:`v4l2_event_src_change`
+      - ``src_change``
+      - Event data for event V4L2_EVENT_SOURCE_CHANGE.
+    * - __u8
+      - ``data``\ [64]
+      - Event data. Defined by the event type. The union should be used to
+	define easily accessible type for events.
+    * - }
+      -
+    * - __u32
+      - ``pending``
+      - Number of pending events excluding this one.
+    * - __u32
+      - ``sequence``
+      - Event sequence number. The sequence number is incremented for
+	every subscribed event that takes place. If sequence numbers are
+	not contiguous it means that events have been lost.
+    * - struct timespec
+      - ``timestamp``
+      - Event timestamp. The timestamp has been taken from the
+	``CLOCK_MONOTONIC`` clock. To access the same clock outside V4L2,
+	use :c:func:`clock_gettime`.
+    * - u32
+      - ``id``
+      - The ID associated with the event source. If the event does not
+	have an associated ID (this depends on the event type), then this
+	is 0.
+    * - __u32
+      - ``reserved``\ [8]
+      - Reserved for future extensions. Drivers must set the array to
+	zero.
+
+
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. cssclass:: longtable
+
+.. _event-type:
+
+.. flat-table:: Event Types
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_EVENT_ALL``
+      - 0
+      - All events. V4L2_EVENT_ALL is valid only for
+	VIDIOC_UNSUBSCRIBE_EVENT for unsubscribing all events at once.
+    * - ``V4L2_EVENT_VSYNC``
+      - 1
+      - This event is triggered on the vertical sync. This event has a
+	struct :c:type:`v4l2_event_vsync` associated
+	with it.
+    * - ``V4L2_EVENT_EOS``
+      - 2
+      - This event is triggered when the end of a stream is reached. This
+	is typically used with MPEG decoders to report to the application
+	when the last of the MPEG stream has been decoded.
+    * - ``V4L2_EVENT_CTRL``
+      - 3
+      - This event requires that the ``id`` matches the control ID from
+	which you want to receive events. This event is triggered if the
+	control's value changes, if a button control is pressed or if the
+	control's flags change. This event has a struct
+	:c:type:`v4l2_event_ctrl` associated with it.
+	This struct contains much of the same information as struct
+	:ref:`v4l2_queryctrl <v4l2-queryctrl>` and struct
+	:c:type:`v4l2_control`.
+
+	If the event is generated due to a call to
+	:ref:`VIDIOC_S_CTRL <VIDIOC_G_CTRL>` or
+	:ref:`VIDIOC_S_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>`, then the
+	event will *not* be sent to the file handle that called the ioctl
+	function. This prevents nasty feedback loops. If you *do* want to
+	get the event, then set the ``V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK``
+	flag.
+
+	This event type will ensure that no information is lost when more
+	events are raised than there is room internally. In that case the
+	struct :c:type:`v4l2_event_ctrl` of the
+	second-oldest event is kept, but the ``changes`` field of the
+	second-oldest event is ORed with the ``changes`` field of the
+	oldest event.
+    * - ``V4L2_EVENT_FRAME_SYNC``
+      - 4
+      - Triggered immediately when the reception of a frame has begun.
+	This event has a struct
+	:c:type:`v4l2_event_frame_sync`
+	associated with it.
+
+	If the hardware needs to be stopped in the case of a buffer
+	underrun it might not be able to generate this event. In such
+	cases the ``frame_sequence`` field in struct
+	:c:type:`v4l2_event_frame_sync` will not
+	be incremented. This causes two consecutive frame sequence numbers
+	to have n times frame interval in between them.
+    * - ``V4L2_EVENT_SOURCE_CHANGE``
+      - 5
+      - This event is triggered when a source parameter change is detected
+	during runtime by the video device. It can be a runtime resolution
+	change triggered by a video decoder or the format change happening
+	on an input connector. This event requires that the ``id`` matches
+	the input index (when used with a video device node) or the pad
+	index (when used with a subdevice node) from which you want to
+	receive events.
+
+	This event has a struct
+	:c:type:`v4l2_event_src_change`
+	associated with it. The ``changes`` bitfield denotes what has
+	changed for the subscribed pad. If multiple events occurred before
+	application could dequeue them, then the changes will have the
+	ORed value of all the events generated.
+    * - ``V4L2_EVENT_MOTION_DET``
+      - 6
+      - Triggered whenever the motion detection state for one or more of
+	the regions changes. This event has a struct
+	:c:type:`v4l2_event_motion_det`
+	associated with it.
+    * - ``V4L2_EVENT_PRIVATE_START``
+      - 0x08000000
+      - Base event number for driver-private events.
+
+
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. c:type:: v4l2_event_vsync
+
+.. flat-table:: struct v4l2_event_vsync
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u8
+      - ``field``
+      - The upcoming field. See enum :c:type:`v4l2_field`.
+
+
+
+.. tabularcolumns:: |p{3.5cm}|p{3.0cm}|p{1.8cm}|p{8.5cm}|
+
+.. c:type:: v4l2_event_ctrl
+
+.. flat-table:: struct v4l2_event_ctrl
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``changes``
+      - A bitmask that tells what has changed. See
+	:ref:`ctrl-changes-flags`.
+    * - __u32
+      - ``type``
+      - The type of the control. See enum
+	:c:type:`v4l2_ctrl_type`.
+    * - union {
+      - (anonymous)
+    * - __s32
+      - ``value``
+      - The 32-bit value of the control for 32-bit control types. This is
+	0 for string controls since the value of a string cannot be passed
+	using :ref:`VIDIOC_DQEVENT`.
+    * - __s64
+      - ``value64``
+      - The 64-bit value of the control for 64-bit control types.
+    * - }
+      -
+    * - __u32
+      - ``flags``
+      - The control flags. See :ref:`control-flags`.
+    * - __s32
+      - ``minimum``
+      - The minimum value of the control. See struct
+	:ref:`v4l2_queryctrl <v4l2-queryctrl>`.
+    * - __s32
+      - ``maximum``
+      - The maximum value of the control. See struct
+	:ref:`v4l2_queryctrl <v4l2-queryctrl>`.
+    * - __s32
+      - ``step``
+      - The step value of the control. See struct
+	:ref:`v4l2_queryctrl <v4l2-queryctrl>`.
+    * - __s32
+      - ``default_value``
+      - The default value value of the control. See struct
+	:ref:`v4l2_queryctrl <v4l2-queryctrl>`.
+
+
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. c:type:: v4l2_event_frame_sync
+
+.. flat-table:: struct v4l2_event_frame_sync
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``frame_sequence``
+      - The sequence number of the frame being received.
+
+
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. c:type:: v4l2_event_src_change
+
+.. flat-table:: struct v4l2_event_src_change
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``changes``
+      - A bitmask that tells what has changed. See
+	:ref:`src-changes-flags`.
+
+
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. c:type:: v4l2_event_motion_det
+
+.. flat-table:: struct v4l2_event_motion_det
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``flags``
+      - Currently only one flag is available: if
+	``V4L2_EVENT_MD_FL_HAVE_FRAME_SEQ`` is set, then the
+	``frame_sequence`` field is valid, otherwise that field should be
+	ignored.
+    * - __u32
+      - ``frame_sequence``
+      - The sequence number of the frame being received. Only valid if the
+	``V4L2_EVENT_MD_FL_HAVE_FRAME_SEQ`` flag was set.
+    * - __u32
+      - ``region_mask``
+      - The bitmask of the regions that reported motion. There is at least
+	one region. If this field is 0, then no motion was detected at
+	all. If there is no ``V4L2_CID_DETECT_MD_REGION_GRID`` control
+	(see :ref:`detect-controls`) to assign a different region to
+	each cell in the motion detection grid, then that all cells are
+	automatically assigned to the default region 0.
+
+
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. _ctrl-changes-flags:
+
+.. flat-table:: Control Changes
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_EVENT_CTRL_CH_VALUE``
+      - 0x0001
+      - This control event was triggered because the value of the control
+	changed. Special cases: Volatile controls do no generate this
+	event; If a control has the ``V4L2_CTRL_FLAG_EXECUTE_ON_WRITE``
+	flag set, then this event is sent as well, regardless its value.
+    * - ``V4L2_EVENT_CTRL_CH_FLAGS``
+      - 0x0002
+      - This control event was triggered because the control flags
+	changed.
+    * - ``V4L2_EVENT_CTRL_CH_RANGE``
+      - 0x0004
+      - This control event was triggered because the minimum, maximum,
+	step or the default value of the control changed.
+
+
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. _src-changes-flags:
+
+.. flat-table:: Source Changes
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_EVENT_SRC_CH_RESOLUTION``
+      - 0x0001
+      - This event gets triggered when a resolution change is detected at
+	an input. This can come from an input connector or from a video
+	decoder. Applications will have to query the new resolution (if
+	any, the signal may also have been lost).
+
+	For stateful decoders follow the guidelines in :ref:`decoder`.
+	Video Capture devices have to query the new timings using
+	:ref:`VIDIOC_QUERY_DV_TIMINGS` or
+	:ref:`VIDIOC_QUERYSTD <VIDIOC_QUERYSTD>`.
+
+	*Important*: even if the new video timings appear identical to the old
+	ones, receiving this event indicates that there was an issue with the
+	video signal and you must stop and restart streaming
+	(:ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>`
+	followed by :ref:`VIDIOC_STREAMON <VIDIOC_STREAMON>`). The reason is
+	that many Video Capture devices are not able to recover from a temporary
+	loss of signal and so restarting streaming I/O is required in order for
+	the hardware to synchronize to the video signal.
+
+
+Return Value
+============
+
+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/userspace-api/media/v4l/vidioc-dv-timings-cap.rst b/Documentation/userspace-api/media/v4l/vidioc-dv-timings-cap.rst
new file mode 100644
index 000000000000..60730c32bfe4
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-dv-timings-cap.rst
@@ -0,0 +1,169 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_DV_TIMINGS_CAP:
+
+*********************************************************
+ioctl VIDIOC_DV_TIMINGS_CAP, VIDIOC_SUBDEV_DV_TIMINGS_CAP
+*********************************************************
+
+Name
+====
+
+VIDIOC_DV_TIMINGS_CAP - VIDIOC_SUBDEV_DV_TIMINGS_CAP - The capabilities of the Digital Video receiver/transmitter
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_DV_TIMINGS_CAP, struct v4l2_dv_timings_cap *argp )
+    :name: VIDIOC_DV_TIMINGS_CAP
+
+.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_DV_TIMINGS_CAP, struct v4l2_dv_timings_cap *argp )
+    :name: VIDIOC_SUBDEV_DV_TIMINGS_CAP
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_dv_timings_cap`.
+
+
+Description
+===========
+
+To query the capabilities of the DV receiver/transmitter applications
+initialize the ``pad`` field to 0, zero the reserved array of struct
+:c:type:`v4l2_dv_timings_cap` and call the
+``VIDIOC_DV_TIMINGS_CAP`` ioctl on a video node and the driver will fill
+in the structure.
+
+.. note::
+
+   Drivers may return different values after
+   switching the video input or output.
+
+When implemented by the driver DV capabilities of subdevices can be
+queried by calling the ``VIDIOC_SUBDEV_DV_TIMINGS_CAP`` ioctl directly
+on a subdevice node. The capabilities are specific to inputs (for DV
+receivers) or outputs (for DV transmitters), applications must specify
+the desired pad number in the struct
+:c:type:`v4l2_dv_timings_cap` ``pad`` field and
+zero the ``reserved`` array. Attempts to query capabilities on a pad
+that doesn't support them will return an ``EINVAL`` error code.
+
+
+.. tabularcolumns:: |p{1.2cm}|p{3.0cm}|p{13.3cm}|
+
+.. c:type:: v4l2_bt_timings_cap
+
+.. flat-table:: struct v4l2_bt_timings_cap
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``min_width``
+      - Minimum width of the active video in pixels.
+    * - __u32
+      - ``max_width``
+      - Maximum width of the active video in pixels.
+    * - __u32
+      - ``min_height``
+      - Minimum height of the active video in lines.
+    * - __u32
+      - ``max_height``
+      - Maximum height of the active video in lines.
+    * - __u64
+      - ``min_pixelclock``
+      - Minimum pixelclock frequency in Hz.
+    * - __u64
+      - ``max_pixelclock``
+      - Maximum pixelclock frequency in Hz.
+    * - __u32
+      - ``standards``
+      - The video standard(s) supported by the hardware. See
+	:ref:`dv-bt-standards` for a list of standards.
+    * - __u32
+      - ``capabilities``
+      - Several flags giving more information about the capabilities. See
+	:ref:`dv-bt-cap-capabilities` for a description of the flags.
+    * - __u32
+      - ``reserved``\ [16]
+      - Reserved for future extensions.
+	Drivers must set the array to zero.
+
+
+
+.. tabularcolumns:: |p{1.0cm}|p{4.0cm}|p{3.5cm}|p{9.2cm}|
+
+.. c:type:: v4l2_dv_timings_cap
+
+.. flat-table:: struct v4l2_dv_timings_cap
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``type``
+      - Type of DV timings as listed in :ref:`dv-timing-types`.
+    * - __u32
+      - ``pad``
+      - Pad number as reported by the media controller API. This field is
+	only used when operating on a subdevice node. When operating on a
+	video node applications must set this field to zero.
+    * - __u32
+      - ``reserved``\ [2]
+      - Reserved for future extensions.
+
+	Drivers and applications must set the array to zero.
+    * - union {
+      - (anonymous)
+    * - struct :c:type:`v4l2_bt_timings_cap`
+      - ``bt``
+      - BT.656/1120 timings capabilities of the hardware.
+    * - __u32
+      - ``raw_data``\ [32]
+    * - }
+      -
+
+.. tabularcolumns:: |p{7.0cm}|p{10.5cm}|
+
+.. _dv-bt-cap-capabilities:
+
+.. flat-table:: DV BT Timing capabilities
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - Flag
+      - Description
+    * -
+      -
+    * - ``V4L2_DV_BT_CAP_INTERLACED``
+      - Interlaced formats are supported.
+    * - ``V4L2_DV_BT_CAP_PROGRESSIVE``
+      - Progressive formats are supported.
+    * - ``V4L2_DV_BT_CAP_REDUCED_BLANKING``
+      - CVT/GTF specific: the timings can make use of reduced blanking
+	(CVT) or the 'Secondary GTF' curve (GTF).
+    * - ``V4L2_DV_BT_CAP_CUSTOM``
+      - Can support non-standard timings, i.e. timings not belonging to
+	the standards set in the ``standards`` field.
+
+
+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/userspace-api/media/v4l/vidioc-encoder-cmd.rst b/Documentation/userspace-api/media/v4l/vidioc-encoder-cmd.rst
new file mode 100644
index 000000000000..16269b3b1715
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-encoder-cmd.rst
@@ -0,0 +1,168 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_ENCODER_CMD:
+
+************************************************
+ioctl VIDIOC_ENCODER_CMD, VIDIOC_TRY_ENCODER_CMD
+************************************************
+
+Name
+====
+
+VIDIOC_ENCODER_CMD - VIDIOC_TRY_ENCODER_CMD - Execute an encoder command
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_ENCODER_CMD, struct v4l2_encoder_cmd *argp )
+    :name: VIDIOC_ENCODER_CMD
+
+.. c:function:: int ioctl( int fd, VIDIOC_TRY_ENCODER_CMD, struct v4l2_encoder_cmd *argp )
+    :name: VIDIOC_TRY_ENCODER_CMD
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_encoder_cmd`.
+
+Description
+===========
+
+These ioctls control an audio/video (usually MPEG-) encoder.
+``VIDIOC_ENCODER_CMD`` sends a command to the encoder,
+``VIDIOC_TRY_ENCODER_CMD`` can be used to try a command without actually
+executing it.
+
+To send a command applications must initialize all fields of a struct
+:c:type:`v4l2_encoder_cmd` and call
+``VIDIOC_ENCODER_CMD`` or ``VIDIOC_TRY_ENCODER_CMD`` with a pointer to
+this structure.
+
+The ``cmd`` field must contain the command code. The ``flags`` field is
+currently only used by the STOP command and contains one bit: If the
+``V4L2_ENC_CMD_STOP_AT_GOP_END`` flag is set, encoding will continue
+until the end of the current *Group Of Pictures*, otherwise it will stop
+immediately.
+
+A :ref:`read() <func-read>` or :ref:`VIDIOC_STREAMON <VIDIOC_STREAMON>`
+call sends an implicit START command to the encoder if it has not been
+started yet. After a STOP command, :ref:`read() <func-read>` calls will read
+the remaining data buffered by the driver. When the buffer is empty,
+:ref:`read() <func-read>` will return zero and the next :ref:`read() <func-read>`
+call will restart the encoder.
+
+A :ref:`close() <func-close>` or :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>`
+call of a streaming file descriptor sends an implicit immediate STOP to
+the encoder, and all buffered data is discarded.
+
+These ioctls are optional, not all drivers may support them. They were
+introduced in Linux 2.6.21.
+
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. c:type:: v4l2_encoder_cmd
+
+.. flat-table:: struct v4l2_encoder_cmd
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``cmd``
+      - The encoder command, see :ref:`encoder-cmds`.
+    * - __u32
+      - ``flags``
+      - Flags to go with the command, see :ref:`encoder-flags`. If no
+	flags are defined for this command, drivers and applications must
+	set this field to zero.
+    * - __u32
+      - ``data``\ [8]
+      - Reserved for future extensions. Drivers and applications must set
+	the array to zero.
+
+
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. _encoder-cmds:
+
+.. flat-table:: Encoder Commands
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_ENC_CMD_START``
+      - 0
+      - Start the encoder. When the encoder is already running or paused,
+	this command does nothing. No flags are defined for this command.
+    * - ``V4L2_ENC_CMD_STOP``
+      - 1
+      - Stop the encoder. When the ``V4L2_ENC_CMD_STOP_AT_GOP_END`` flag
+	is set, encoding will continue until the end of the current *Group
+	Of Pictures*, otherwise encoding will stop immediately. When the
+	encoder is already stopped, this command does nothing. mem2mem
+	encoders will send a ``V4L2_EVENT_EOS`` event when the last frame
+	has been encoded and all frames are ready to be dequeued and will
+	set the ``V4L2_BUF_FLAG_LAST`` buffer flag on the last buffer of
+	the capture queue to indicate there will be no new buffers
+	produced to dequeue. This buffer may be empty, indicated by the
+	driver setting the ``bytesused`` field to 0. Once the
+	``V4L2_BUF_FLAG_LAST`` flag was set, the
+	:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl will not block anymore,
+	but return an ``EPIPE`` error code.
+    * - ``V4L2_ENC_CMD_PAUSE``
+      - 2
+      - Pause the encoder. When the encoder has not been started yet, the
+	driver will return an ``EPERM`` error code. When the encoder is
+	already paused, this command does nothing. No flags are defined
+	for this command.
+    * - ``V4L2_ENC_CMD_RESUME``
+      - 3
+      - Resume encoding after a PAUSE command. When the encoder has not
+	been started yet, the driver will return an ``EPERM`` error code. When
+	the encoder is already running, this command does nothing. No
+	flags are defined for this command.
+
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. _encoder-flags:
+
+.. flat-table:: Encoder Command Flags
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_ENC_CMD_STOP_AT_GOP_END``
+      - 0x0001
+      - Stop encoding at the end of the current *Group Of Pictures*,
+	rather than immediately.
+
+
+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
+    The ``cmd`` field is invalid.
+
+EPERM
+    The application sent a PAUSE or RESUME command when the encoder was
+    not running.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-enum-dv-timings.rst b/Documentation/userspace-api/media/v4l/vidioc-enum-dv-timings.rst
new file mode 100644
index 000000000000..89d6b860193a
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-enum-dv-timings.rst
@@ -0,0 +1,114 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_ENUM_DV_TIMINGS:
+
+***********************************************************
+ioctl VIDIOC_ENUM_DV_TIMINGS, VIDIOC_SUBDEV_ENUM_DV_TIMINGS
+***********************************************************
+
+Name
+====
+
+VIDIOC_ENUM_DV_TIMINGS - VIDIOC_SUBDEV_ENUM_DV_TIMINGS - Enumerate supported Digital Video timings
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_ENUM_DV_TIMINGS, struct v4l2_enum_dv_timings *argp )
+    :name: VIDIOC_ENUM_DV_TIMINGS
+
+.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_ENUM_DV_TIMINGS, struct v4l2_enum_dv_timings *argp )
+    :name: VIDIOC_SUBDEV_ENUM_DV_TIMINGS
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_enum_dv_timings`.
+
+
+Description
+===========
+
+While some DV receivers or transmitters support a wide range of timings,
+others support only a limited number of timings. With this ioctl
+applications can enumerate a list of known supported timings. Call
+:ref:`VIDIOC_DV_TIMINGS_CAP` to check if it
+also supports other standards or even custom timings that are not in
+this list.
+
+To query the available timings, applications initialize the ``index``
+field, set the ``pad`` field to 0, zero the reserved array of struct
+:c:type:`v4l2_enum_dv_timings` and call the
+``VIDIOC_ENUM_DV_TIMINGS`` ioctl on a video node with a pointer to this
+structure. Drivers fill the rest of the structure or return an ``EINVAL``
+error code when the index is out of bounds. To enumerate all supported
+DV timings, applications shall begin at index zero, incrementing by one
+until the driver returns ``EINVAL``.
+
+.. note::
+
+   Drivers may enumerate a different set of DV timings after
+   switching the video input or output.
+
+When implemented by the driver DV timings of subdevices can be queried
+by calling the ``VIDIOC_SUBDEV_ENUM_DV_TIMINGS`` ioctl directly on a
+subdevice node. The DV timings are specific to inputs (for DV receivers)
+or outputs (for DV transmitters), applications must specify the desired
+pad number in the struct
+:c:type:`v4l2_enum_dv_timings` ``pad`` field.
+Attempts to enumerate timings on a pad that doesn't support them will
+return an ``EINVAL`` error code.
+
+
+.. c:type:: v4l2_enum_dv_timings
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. flat-table:: struct v4l2_enum_dv_timings
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``index``
+      - Number of the DV timings, set by the application.
+    * - __u32
+      - ``pad``
+      - Pad number as reported by the media controller API. This field is
+	only used when operating on a subdevice node. When operating on a
+	video node applications must set this field to zero.
+    * - __u32
+      - ``reserved``\ [2]
+      - Reserved for future extensions. Drivers and applications must set
+	the array to zero.
+    * - struct :c:type:`v4l2_dv_timings`
+      - ``timings``
+      - The timings.
+
+
+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
+    The struct :c:type:`v4l2_enum_dv_timings`
+    ``index`` is out of bounds or the ``pad`` number is invalid.
+
+ENODATA
+    Digital video presets are not supported for this input or output.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-enum-fmt.rst b/Documentation/userspace-api/media/v4l/vidioc-enum-fmt.rst
new file mode 100644
index 000000000000..7e3142e11d77
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-enum-fmt.rst
@@ -0,0 +1,159 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_ENUM_FMT:
+
+*********************
+ioctl VIDIOC_ENUM_FMT
+*********************
+
+Name
+====
+
+VIDIOC_ENUM_FMT - Enumerate image formats
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_ENUM_FMT, struct v4l2_fmtdesc *argp )
+    :name: VIDIOC_ENUM_FMT
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_fmtdesc`.
+
+
+Description
+===========
+
+To enumerate image formats applications initialize the ``type`` and
+``index`` field of struct :c:type:`v4l2_fmtdesc` and call
+the :ref:`VIDIOC_ENUM_FMT` ioctl with a pointer to this structure. Drivers
+fill the rest of the structure or return an ``EINVAL`` error code. All
+formats are enumerable by beginning at index zero and incrementing by
+one until ``EINVAL`` is returned. If applicable, drivers shall return
+formats in preference order, where preferred formats are returned before
+(that is, with lower ``index`` value) less-preferred formats.
+
+.. note::
+
+   After switching input or output the list of enumerated image
+   formats may be different.
+
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. c:type:: v4l2_fmtdesc
+
+.. flat-table:: struct v4l2_fmtdesc
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``index``
+      - Number of the format in the enumeration, set by the application.
+	This is in no way related to the ``pixelformat`` field.
+    * - __u32
+      - ``type``
+      - Type of the data stream, set by the application. Only these types
+	are valid here: ``V4L2_BUF_TYPE_VIDEO_CAPTURE``,
+	``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE``,
+	``V4L2_BUF_TYPE_VIDEO_OUTPUT``,
+	``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE``,
+	``V4L2_BUF_TYPE_VIDEO_OVERLAY``,
+	``V4L2_BUF_TYPE_SDR_CAPTURE``,
+	``V4L2_BUF_TYPE_SDR_OUTPUT`` and
+	``V4L2_BUF_TYPE_META_CAPTURE``.
+	See :c:type:`v4l2_buf_type`.
+    * - __u32
+      - ``flags``
+      - See :ref:`fmtdesc-flags`
+    * - __u8
+      - ``description``\ [32]
+      - Description of the format, a NUL-terminated ASCII string. This
+	information is intended for the user, for example: "YUV 4:2:2".
+    * - __u32
+      - ``pixelformat``
+      - The image format identifier. This is a four character code as
+	computed by the v4l2_fourcc() macro:
+    * - :cspan:`2`
+
+	.. _v4l2-fourcc:
+
+	``#define v4l2_fourcc(a,b,c,d)``
+
+	``(((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24))``
+
+	Several image formats are already defined by this specification in
+	:ref:`pixfmt`.
+
+	.. attention::
+
+	   These codes are not the same as those used
+	   in the Windows world.
+    * - __u32
+      - ``reserved``\ [4]
+      - Reserved for future extensions. Drivers must set the array to
+	zero.
+
+
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. _fmtdesc-flags:
+
+.. flat-table:: Image Format Description Flags
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_FMT_FLAG_COMPRESSED``
+      - 0x0001
+      - This is a compressed format.
+    * - ``V4L2_FMT_FLAG_EMULATED``
+      - 0x0002
+      - This format is not native to the device but emulated through
+	software (usually libv4l2), where possible try to use a native
+	format instead for better performance.
+    * - ``V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM``
+      - 0x0004
+      - The hardware decoder for this compressed bytestream format (aka coded
+	format) is capable of parsing a continuous bytestream. Applications do
+	not need to parse the bytestream themselves to find the boundaries
+	between frames/fields. This flag can only be used in combination with
+	the ``V4L2_FMT_FLAG_COMPRESSED`` flag, since this applies to compressed
+	formats only. This flag is valid for stateful decoders only.
+    * - ``V4L2_FMT_FLAG_DYN_RESOLUTION``
+      - 0x0008
+      - Dynamic resolution switching is supported by the device for this
+	compressed bytestream format (aka coded format). It will notify the user
+	via the event ``V4L2_EVENT_SOURCE_CHANGE`` when changes in the video
+	parameters are detected. This flag can only be used in combination
+	with the ``V4L2_FMT_FLAG_COMPRESSED`` flag, since this applies to
+	compressed formats only. It is also only applies to stateful codecs.
+
+
+Return Value
+============
+
+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
+    The struct :c:type:`v4l2_fmtdesc` ``type`` is not
+    supported or the ``index`` is out of bounds.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-enum-frameintervals.rst b/Documentation/userspace-api/media/v4l/vidioc-enum-frameintervals.rst
new file mode 100644
index 000000000000..0e3db737371f
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-enum-frameintervals.rst
@@ -0,0 +1,203 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_ENUM_FRAMEINTERVALS:
+
+********************************
+ioctl VIDIOC_ENUM_FRAMEINTERVALS
+********************************
+
+Name
+====
+
+VIDIOC_ENUM_FRAMEINTERVALS - Enumerate frame intervals
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_ENUM_FRAMEINTERVALS, struct v4l2_frmivalenum *argp )
+    :name: VIDIOC_ENUM_FRAMEINTERVALS
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_frmivalenum`
+    that contains a pixel format and size and receives a frame interval.
+
+
+Description
+===========
+
+This ioctl allows applications to enumerate all frame intervals that the
+device supports for the given pixel format and frame size.
+
+The supported pixel formats and frame sizes can be obtained by using the
+:ref:`VIDIOC_ENUM_FMT` and
+:ref:`VIDIOC_ENUM_FRAMESIZES` functions.
+
+The return value and the content of the ``v4l2_frmivalenum.type`` field
+depend on the type of frame intervals the device supports. Here are the
+semantics of the function for the different cases:
+
+-  **Discrete:** The function returns success if the given index value
+   (zero-based) is valid. The application should increase the index by
+   one for each call until ``EINVAL`` is returned. The
+   `v4l2_frmivalenum.type` field is set to
+   `V4L2_FRMIVAL_TYPE_DISCRETE` by the driver. Of the union only
+   the `discrete` member is valid.
+
+-  **Step-wise:** The function returns success if the given index value
+   is zero and ``EINVAL`` for any other index value. The
+   ``v4l2_frmivalenum.type`` field is set to
+   ``V4L2_FRMIVAL_TYPE_STEPWISE`` by the driver. Of the union only the
+   ``stepwise`` member is valid.
+
+-  **Continuous:** This is a special case of the step-wise type above.
+   The function returns success if the given index value is zero and
+   ``EINVAL`` for any other index value. The ``v4l2_frmivalenum.type``
+   field is set to ``V4L2_FRMIVAL_TYPE_CONTINUOUS`` by the driver. Of
+   the union only the ``stepwise`` member is valid and the ``step``
+   value is set to 1.
+
+When the application calls the function with index zero, it must check
+the ``type`` field to determine the type of frame interval enumeration
+the device supports. Only for the ``V4L2_FRMIVAL_TYPE_DISCRETE`` type
+does it make sense to increase the index value to receive more frame
+intervals.
+
+.. note::
+
+   The order in which the frame intervals are returned has no
+   special meaning. In particular does it not say anything about potential
+   default frame intervals.
+
+Applications can assume that the enumeration data does not change
+without any interaction from the application itself. This means that the
+enumeration data is consistent if the application does not perform any
+other ioctl calls while it runs the frame interval enumeration.
+
+.. note::
+
+   **Frame intervals and frame rates:** The V4L2 API uses frame
+   intervals instead of frame rates. Given the frame interval the frame
+   rate can be computed as follows:
+
+   ::
+
+       frame_rate = 1 / frame_interval
+
+
+Structs
+=======
+
+In the structs below, *IN* denotes a value that has to be filled in by
+the application, *OUT* denotes values that the driver fills in. The
+application should zero out all members except for the *IN* fields.
+
+
+.. c:type:: v4l2_frmival_stepwise
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. flat-table:: struct v4l2_frmival_stepwise
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - struct :c:type:`v4l2_fract`
+      - ``min``
+      - Minimum frame interval [s].
+    * - struct :c:type:`v4l2_fract`
+      - ``max``
+      - Maximum frame interval [s].
+    * - struct :c:type:`v4l2_fract`
+      - ``step``
+      - Frame interval step size [s].
+
+
+
+.. c:type:: v4l2_frmivalenum
+
+.. tabularcolumns:: |p{1.8cm}|p{4.4cm}|p{2.4cm}|p{8.9cm}|
+
+.. flat-table:: struct v4l2_frmivalenum
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - __u32
+      - ``index``
+      - IN: Index of the given frame interval in the enumeration.
+    * - __u32
+      - ``pixel_format``
+      - IN: Pixel format for which the frame intervals are enumerated.
+    * - __u32
+      - ``width``
+      - IN: Frame width for which the frame intervals are enumerated.
+    * - __u32
+      - ``height``
+      - IN: Frame height for which the frame intervals are enumerated.
+    * - __u32
+      - ``type``
+      - OUT: Frame interval type the device supports.
+    * - union {
+      - (anonymous)
+      - OUT: Frame interval with the given index.
+    * - struct :c:type:`v4l2_fract`
+      - ``discrete``
+      - Frame interval [s].
+    * - struct :c:type:`v4l2_frmival_stepwise`
+      - ``stepwise``
+      -
+    * - }
+      -
+      -
+    * - __u32
+      - ``reserved[2]``
+      -
+      - Reserved space for future use. Must be zeroed by drivers and
+	applications.
+
+
+
+Enums
+=====
+
+
+.. c:type:: v4l2_frmivaltypes
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. flat-table:: enum v4l2_frmivaltypes
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_FRMIVAL_TYPE_DISCRETE``
+      - 1
+      - Discrete frame interval.
+    * - ``V4L2_FRMIVAL_TYPE_CONTINUOUS``
+      - 2
+      - Continuous frame interval.
+    * - ``V4L2_FRMIVAL_TYPE_STEPWISE``
+      - 3
+      - Step-wise defined frame interval.
+
+
+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/userspace-api/media/v4l/vidioc-enum-framesizes.rst b/Documentation/userspace-api/media/v4l/vidioc-enum-framesizes.rst
new file mode 100644
index 000000000000..1934d7da9743
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-enum-framesizes.rst
@@ -0,0 +1,213 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_ENUM_FRAMESIZES:
+
+****************************
+ioctl VIDIOC_ENUM_FRAMESIZES
+****************************
+
+Name
+====
+
+VIDIOC_ENUM_FRAMESIZES - Enumerate frame sizes
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_ENUM_FRAMESIZES, struct v4l2_frmsizeenum *argp )
+    :name: VIDIOC_ENUM_FRAMESIZES
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_frmsizeenum`
+    that contains an index and pixel format and receives a frame width
+    and height.
+
+
+Description
+===========
+
+This ioctl allows applications to enumerate all frame sizes (i. e. width
+and height in pixels) that the device supports for the given pixel
+format.
+
+The supported pixel formats can be obtained by using the
+:ref:`VIDIOC_ENUM_FMT` function.
+
+The return value and the content of the ``v4l2_frmsizeenum.type`` field
+depend on the type of frame sizes the device supports. Here are the
+semantics of the function for the different cases:
+
+-  **Discrete:** The function returns success if the given index value
+   (zero-based) is valid. The application should increase the index by
+   one for each call until ``EINVAL`` is returned. The
+   ``v4l2_frmsizeenum.type`` field is set to
+   ``V4L2_FRMSIZE_TYPE_DISCRETE`` by the driver. Of the union only the
+   ``discrete`` member is valid.
+
+-  **Step-wise:** The function returns success if the given index value
+   is zero and ``EINVAL`` for any other index value. The
+   ``v4l2_frmsizeenum.type`` field is set to
+   ``V4L2_FRMSIZE_TYPE_STEPWISE`` by the driver. Of the union only the
+   ``stepwise`` member is valid.
+
+-  **Continuous:** This is a special case of the step-wise type above.
+   The function returns success if the given index value is zero and
+   ``EINVAL`` for any other index value. The ``v4l2_frmsizeenum.type``
+   field is set to ``V4L2_FRMSIZE_TYPE_CONTINUOUS`` by the driver. Of
+   the union only the ``stepwise`` member is valid and the
+   ``step_width`` and ``step_height`` values are set to 1.
+
+When the application calls the function with index zero, it must check
+the ``type`` field to determine the type of frame size enumeration the
+device supports. Only for the ``V4L2_FRMSIZE_TYPE_DISCRETE`` type does
+it make sense to increase the index value to receive more frame sizes.
+
+.. note::
+
+   The order in which the frame sizes are returned has no special
+   meaning. In particular does it not say anything about potential default
+   format sizes.
+
+Applications can assume that the enumeration data does not change
+without any interaction from the application itself. This means that the
+enumeration data is consistent if the application does not perform any
+other ioctl calls while it runs the frame size enumeration.
+
+
+Structs
+=======
+
+In the structs below, *IN* denotes a value that has to be filled in by
+the application, *OUT* denotes values that the driver fills in. The
+application should zero out all members except for the *IN* fields.
+
+
+.. c:type:: v4l2_frmsize_discrete
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. flat-table:: struct v4l2_frmsize_discrete
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``width``
+      - Width of the frame [pixel].
+    * - __u32
+      - ``height``
+      - Height of the frame [pixel].
+
+
+
+.. c:type:: v4l2_frmsize_stepwise
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. flat-table:: struct v4l2_frmsize_stepwise
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``min_width``
+      - Minimum frame width [pixel].
+    * - __u32
+      - ``max_width``
+      - Maximum frame width [pixel].
+    * - __u32
+      - ``step_width``
+      - Frame width step size [pixel].
+    * - __u32
+      - ``min_height``
+      - Minimum frame height [pixel].
+    * - __u32
+      - ``max_height``
+      - Maximum frame height [pixel].
+    * - __u32
+      - ``step_height``
+      - Frame height step size [pixel].
+
+
+
+.. c:type:: v4l2_frmsizeenum
+
+.. tabularcolumns:: |p{1.4cm}|p{5.9cm}|p{2.3cm}|p{8.0cm}|
+
+.. flat-table:: struct v4l2_frmsizeenum
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - __u32
+      - ``index``
+      - IN: Index of the given frame size in the enumeration.
+    * - __u32
+      - ``pixel_format``
+      - IN: Pixel format for which the frame sizes are enumerated.
+    * - __u32
+      - ``type``
+      - OUT: Frame size type the device supports.
+    * - union {
+      - (anonymous)
+      - OUT: Frame size with the given index.
+    * - struct :c:type:`v4l2_frmsize_discrete`
+      - ``discrete``
+      -
+    * - struct :c:type:`v4l2_frmsize_stepwise`
+      - ``stepwise``
+      -
+    * - }
+      -
+      -
+    * - __u32
+      - ``reserved[2]``
+      - Reserved space for future use. Must be zeroed by drivers and
+	applications.
+
+
+
+Enums
+=====
+
+
+.. c:type:: v4l2_frmsizetypes
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. flat-table:: enum v4l2_frmsizetypes
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_FRMSIZE_TYPE_DISCRETE``
+      - 1
+      - Discrete frame size.
+    * - ``V4L2_FRMSIZE_TYPE_CONTINUOUS``
+      - 2
+      - Continuous frame size.
+    * - ``V4L2_FRMSIZE_TYPE_STEPWISE``
+      - 3
+      - Step-wise defined frame size.
+
+
+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/userspace-api/media/v4l/vidioc-enum-freq-bands.rst b/Documentation/userspace-api/media/v4l/vidioc-enum-freq-bands.rst
new file mode 100644
index 000000000000..ee3ba67601fa
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-enum-freq-bands.rst
@@ -0,0 +1,150 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_ENUM_FREQ_BANDS:
+
+****************************
+ioctl VIDIOC_ENUM_FREQ_BANDS
+****************************
+
+Name
+====
+
+VIDIOC_ENUM_FREQ_BANDS - Enumerate supported frequency bands
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_ENUM_FREQ_BANDS, struct v4l2_frequency_band *argp )
+    :name: VIDIOC_ENUM_FREQ_BANDS
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_frequency_band`.
+
+
+Description
+===========
+
+Enumerates the frequency bands that a tuner or modulator supports. To do
+this applications initialize the ``tuner``, ``type`` and ``index``
+fields, and zero out the ``reserved`` array of a struct
+:c:type:`v4l2_frequency_band` and call the
+:ref:`VIDIOC_ENUM_FREQ_BANDS` ioctl with a pointer to this structure.
+
+This ioctl is supported if the ``V4L2_TUNER_CAP_FREQ_BANDS`` capability
+of the corresponding tuner/modulator is set.
+
+
+.. tabularcolumns:: |p{2.9cm}|p{2.9cm}|p{5.8cm}|p{2.9cm}|p{3.0cm}|
+
+.. c:type:: v4l2_frequency_band
+
+.. flat-table:: struct v4l2_frequency_band
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2 1 1
+
+    * - __u32
+      - ``tuner``
+      - The tuner or modulator index number. This is the same value as in
+	the struct :c:type:`v4l2_input` ``tuner`` field and
+	the struct :c:type:`v4l2_tuner` ``index`` field, or
+	the struct :c:type:`v4l2_output` ``modulator`` field
+	and the struct :c:type:`v4l2_modulator` ``index``
+	field.
+    * - __u32
+      - ``type``
+      - The tuner type. This is the same value as in the struct
+	:c:type:`v4l2_tuner` ``type`` field. The type must be
+	set to ``V4L2_TUNER_RADIO`` for ``/dev/radioX`` device nodes, and
+	to ``V4L2_TUNER_ANALOG_TV`` for all others. Set this field to
+	``V4L2_TUNER_RADIO`` for modulators (currently only radio
+	modulators are supported). See :c:type:`v4l2_tuner_type`
+    * - __u32
+      - ``index``
+      - Identifies the frequency band, set by the application.
+    * - __u32
+      - ``capability``
+      - :cspan:`2` The tuner/modulator capability flags for this
+	frequency band, see :ref:`tuner-capability`. The
+	``V4L2_TUNER_CAP_LOW`` or ``V4L2_TUNER_CAP_1HZ`` capability must
+	be the same for all frequency bands of the selected
+	tuner/modulator. So either all bands have that capability set, or
+	none of them have that capability.
+    * - __u32
+      - ``rangelow``
+      - :cspan:`2` The lowest tunable frequency in units of 62.5 kHz, or
+	if the ``capability`` flag ``V4L2_TUNER_CAP_LOW`` is set, in units
+	of 62.5 Hz, for this frequency band. A 1 Hz unit is used when the
+	``capability`` flag ``V4L2_TUNER_CAP_1HZ`` is set.
+    * - __u32
+      - ``rangehigh``
+      - :cspan:`2` The highest tunable frequency in units of 62.5 kHz,
+	or if the ``capability`` flag ``V4L2_TUNER_CAP_LOW`` is set, in
+	units of 62.5 Hz, for this frequency band. A 1 Hz unit is used
+	when the ``capability`` flag ``V4L2_TUNER_CAP_1HZ`` is set.
+    * - __u32
+      - ``modulation``
+      - :cspan:`2` The supported modulation systems of this frequency
+	band. See :ref:`band-modulation`.
+
+	.. note::
+
+	   Currently only one modulation system per frequency band
+	   is supported. More work will need to be done if multiple
+	   modulation systems are possible. Contact the linux-media
+	   mailing list
+	   (`https://linuxtv.org/lists.php <https://linuxtv.org/lists.php>`__)
+	   if you need such functionality.
+    * - __u32
+      - ``reserved``\ [9]
+      - Reserved for future extensions.
+
+	Applications and drivers must set the array to zero.
+
+
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. _band-modulation:
+
+.. flat-table:: Band Modulation Systems
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_BAND_MODULATION_VSB``
+      - 0x02
+      - Vestigial Sideband modulation, used for analog TV.
+    * - ``V4L2_BAND_MODULATION_FM``
+      - 0x04
+      - Frequency Modulation, commonly used for analog radio.
+    * - ``V4L2_BAND_MODULATION_AM``
+      - 0x08
+      - Amplitude Modulation, commonly used for analog radio.
+
+
+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
+    The ``tuner`` or ``index`` is out of bounds or the ``type`` field is
+    wrong.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-enumaudio.rst b/Documentation/userspace-api/media/v4l/vidioc-enumaudio.rst
new file mode 100644
index 000000000000..afe4821e5863
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-enumaudio.rst
@@ -0,0 +1,62 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_ENUMAUDIO:
+
+**********************
+ioctl VIDIOC_ENUMAUDIO
+**********************
+
+Name
+====
+
+VIDIOC_ENUMAUDIO - Enumerate audio inputs
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_ENUMAUDIO, struct v4l2_audio *argp )
+    :name: VIDIOC_ENUMAUDIO
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_audio`.
+
+
+Description
+===========
+
+To query the attributes of an audio input applications initialize the
+``index`` field and zero out the ``reserved`` array of a struct
+:c:type:`v4l2_audio` and call the :ref:`VIDIOC_ENUMAUDIO`
+ioctl with a pointer to this structure. Drivers fill the rest of the
+structure or return an ``EINVAL`` error code when the index is out of
+bounds. To enumerate all audio inputs applications shall begin at index
+zero, incrementing by one until the driver returns ``EINVAL``.
+
+See :ref:`VIDIOC_G_AUDIO <VIDIOC_G_AUDIO>` for a description of struct
+:c:type:`v4l2_audio`.
+
+
+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
+    The number of the audio input is out of bounds.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-enumaudioout.rst b/Documentation/userspace-api/media/v4l/vidioc-enumaudioout.rst
new file mode 100644
index 000000000000..31c2ae460e2d
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-enumaudioout.rst
@@ -0,0 +1,67 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_ENUMAUDOUT:
+
+***********************
+ioctl VIDIOC_ENUMAUDOUT
+***********************
+
+Name
+====
+
+VIDIOC_ENUMAUDOUT - Enumerate audio outputs
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_ENUMAUDOUT, struct v4l2_audioout *argp )
+    :name: VIDIOC_ENUMAUDOUT
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_audioout`.
+
+
+Description
+===========
+
+To query the attributes of an audio output applications initialize the
+``index`` field and zero out the ``reserved`` array of a struct
+:c:type:`v4l2_audioout` and call the ``VIDIOC_G_AUDOUT``
+ioctl with a pointer to this structure. Drivers fill the rest of the
+structure or return an ``EINVAL`` error code when the index is out of
+bounds. To enumerate all audio outputs applications shall begin at index
+zero, incrementing by one until the driver returns ``EINVAL``.
+
+.. note::
+
+    Connectors on a TV card to loop back the received audio signal
+    to a sound card are not audio outputs in this sense.
+
+See :ref:`VIDIOC_G_AUDIOout <VIDIOC_G_AUDOUT>` for a description of struct
+:c:type:`v4l2_audioout`.
+
+
+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
+    The number of the audio output is out of bounds.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-enuminput.rst b/Documentation/userspace-api/media/v4l/vidioc-enuminput.rst
new file mode 100644
index 000000000000..510670bff3de
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-enuminput.rst
@@ -0,0 +1,242 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_ENUMINPUT:
+
+**********************
+ioctl VIDIOC_ENUMINPUT
+**********************
+
+Name
+====
+
+VIDIOC_ENUMINPUT - Enumerate video inputs
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_ENUMINPUT, struct v4l2_input *argp )
+    :name: VIDIOC_ENUMINPUT
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_input`.
+
+
+Description
+===========
+
+To query the attributes of a video input applications initialize the
+``index`` field of struct :c:type:`v4l2_input` and call the
+:ref:`VIDIOC_ENUMINPUT` with a pointer to this structure. Drivers
+fill the rest of the structure or return an ``EINVAL`` error code when the
+index is out of bounds. To enumerate all inputs applications shall begin
+at index zero, incrementing by one until the driver returns ``EINVAL``.
+
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. c:type:: v4l2_input
+
+.. flat-table:: struct v4l2_input
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``index``
+      - Identifies the input, set by the application.
+    * - __u8
+      - ``name``\ [32]
+      - Name of the video input, a NUL-terminated ASCII string, for
+	example: "Vin (Composite 2)". This information is intended for the
+	user, preferably the connector label on the device itself.
+    * - __u32
+      - ``type``
+      - Type of the input, see :ref:`input-type`.
+    * - __u32
+      - ``audioset``
+      - Drivers can enumerate up to 32 video and audio inputs. This field
+	shows which audio inputs were selectable as audio source if this
+	was the currently selected video input. It is a bit mask. The LSB
+	corresponds to audio input 0, the MSB to input 31. Any number of
+	bits can be set, or none.
+
+	When the driver does not enumerate audio inputs no bits must be
+	set. Applications shall not interpret this as lack of audio
+	support. Some drivers automatically select audio sources and do
+	not enumerate them since there is no choice anyway.
+
+	For details on audio inputs and how to select the current input
+	see :ref:`audio`.
+    * - __u32
+      - ``tuner``
+      - Capture devices can have zero or more tuners (RF demodulators).
+	When the ``type`` is set to ``V4L2_INPUT_TYPE_TUNER`` this is an
+	RF connector and this field identifies the tuner. It corresponds
+	to struct :c:type:`v4l2_tuner` field ``index``. For
+	details on tuners see :ref:`tuner`.
+    * - :ref:`v4l2_std_id <v4l2-std-id>`
+      - ``std``
+      - Every video input supports one or more different video standards.
+	This field is a set of all supported standards. For details on
+	video standards and how to switch see :ref:`standard`.
+    * - __u32
+      - ``status``
+      - This field provides status information about the input. See
+	:ref:`input-status` for flags. With the exception of the sensor
+	orientation bits ``status`` is only valid when this is the current
+	input.
+    * - __u32
+      - ``capabilities``
+      - This field provides capabilities for the input. See
+	:ref:`input-capabilities` for flags.
+    * - __u32
+      - ``reserved``\ [3]
+      - Reserved for future extensions. Drivers must set the array to
+	zero.
+
+
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. _input-type:
+
+.. flat-table:: Input Types
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_INPUT_TYPE_TUNER``
+      - 1
+      - This input uses a tuner (RF demodulator).
+    * - ``V4L2_INPUT_TYPE_CAMERA``
+      - 2
+      - Any non-tuner video input, for example Composite Video,
+	S-Video, HDMI, camera sensor. The naming as ``_TYPE_CAMERA`` is historical,
+	today we would have called it ``_TYPE_VIDEO``.
+    * - ``V4L2_INPUT_TYPE_TOUCH``
+      - 3
+      - This input is a touch device for capturing raw touch data.
+
+
+
+.. tabularcolumns:: |p{4.8cm}|p{2.6cm}|p{10.1cm}|
+
+.. _input-status:
+
+.. flat-table:: Input Status Flags
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - :cspan:`2` General
+    * - ``V4L2_IN_ST_NO_POWER``
+      - 0x00000001
+      - Attached device is off.
+    * - ``V4L2_IN_ST_NO_SIGNAL``
+      - 0x00000002
+      -
+    * - ``V4L2_IN_ST_NO_COLOR``
+      - 0x00000004
+      - The hardware supports color decoding, but does not detect color
+	modulation in the signal.
+    * - :cspan:`2` Sensor Orientation
+    * - ``V4L2_IN_ST_HFLIP``
+      - 0x00000010
+      - The input is connected to a device that produces a signal that is
+	flipped horizontally and does not correct this before passing the
+	signal to userspace.
+    * - ``V4L2_IN_ST_VFLIP``
+      - 0x00000020
+      - The input is connected to a device that produces a signal that is
+	flipped vertically and does not correct this before passing the
+	signal to userspace.
+	.. note:: A 180 degree rotation is the same as HFLIP | VFLIP
+    * - :cspan:`2` Analog Video
+    * - ``V4L2_IN_ST_NO_H_LOCK``
+      - 0x00000100
+      - No horizontal sync lock.
+    * - ``V4L2_IN_ST_COLOR_KILL``
+      - 0x00000200
+      - A color killer circuit automatically disables color decoding when
+	it detects no color modulation. When this flag is set the color
+	killer is enabled *and* has shut off color decoding.
+    * - ``V4L2_IN_ST_NO_V_LOCK``
+      - 0x00000400
+      - No vertical sync lock.
+    * - ``V4L2_IN_ST_NO_STD_LOCK``
+      - 0x00000800
+      - No standard format lock in case of auto-detection format
+	by the component.
+    * - :cspan:`2` Digital Video
+    * - ``V4L2_IN_ST_NO_SYNC``
+      - 0x00010000
+      - No synchronization lock.
+    * - ``V4L2_IN_ST_NO_EQU``
+      - 0x00020000
+      - No equalizer lock.
+    * - ``V4L2_IN_ST_NO_CARRIER``
+      - 0x00040000
+      - Carrier recovery failed.
+    * - :cspan:`2` VCR and Set-Top Box
+    * - ``V4L2_IN_ST_MACROVISION``
+      - 0x01000000
+      - Macrovision is an analog copy prevention system mangling the video
+	signal to confuse video recorders. When this flag is set
+	Macrovision has been detected.
+    * - ``V4L2_IN_ST_NO_ACCESS``
+      - 0x02000000
+      - Conditional access denied.
+    * - ``V4L2_IN_ST_VTR``
+      - 0x04000000
+      - VTR time constant. [?]
+
+
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. _input-capabilities:
+
+.. flat-table:: Input capabilities
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_IN_CAP_DV_TIMINGS``
+      - 0x00000002
+      - This input supports setting video timings by using
+	``VIDIOC_S_DV_TIMINGS``.
+    * - ``V4L2_IN_CAP_STD``
+      - 0x00000004
+      - This input supports setting the TV standard by using
+	``VIDIOC_S_STD``.
+    * - ``V4L2_IN_CAP_NATIVE_SIZE``
+      - 0x00000008
+      - This input supports setting the native size using the
+	``V4L2_SEL_TGT_NATIVE_SIZE`` selection target, see
+	:ref:`v4l2-selections-common`.
+
+
+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
+    The struct :c:type:`v4l2_input` ``index`` is out of
+    bounds.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-enumoutput.rst b/Documentation/userspace-api/media/v4l/vidioc-enumoutput.rst
new file mode 100644
index 000000000000..591a99cf8000
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-enumoutput.rst
@@ -0,0 +1,165 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_ENUMOUTPUT:
+
+***********************
+ioctl VIDIOC_ENUMOUTPUT
+***********************
+
+Name
+====
+
+VIDIOC_ENUMOUTPUT - Enumerate video outputs
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_ENUMOUTPUT, struct v4l2_output *argp )
+    :name: VIDIOC_ENUMOUTPUT
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_output`.
+
+
+Description
+===========
+
+To query the attributes of a video outputs applications initialize the
+``index`` field of struct :c:type:`v4l2_output` and call
+the :ref:`VIDIOC_ENUMOUTPUT` with a pointer to this structure.
+Drivers fill the rest of the structure or return an ``EINVAL`` error code
+when the index is out of bounds. To enumerate all outputs applications
+shall begin at index zero, incrementing by one until the driver returns
+``EINVAL``.
+
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. c:type:: v4l2_output
+
+.. flat-table:: struct v4l2_output
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``index``
+      - Identifies the output, set by the application.
+    * - __u8
+      - ``name``\ [32]
+      - Name of the video output, a NUL-terminated ASCII string, for
+	example: "Vout". This information is intended for the user,
+	preferably the connector label on the device itself.
+    * - __u32
+      - ``type``
+      - Type of the output, see :ref:`output-type`.
+    * - __u32
+      - ``audioset``
+      - Drivers can enumerate up to 32 video and audio outputs. This field
+	shows which audio outputs were selectable as the current output if
+	this was the currently selected video output. It is a bit mask.
+	The LSB corresponds to audio output 0, the MSB to output 31. Any
+	number of bits can be set, or none.
+
+	When the driver does not enumerate audio outputs no bits must be
+	set. Applications shall not interpret this as lack of audio
+	support. Drivers may automatically select audio outputs without
+	enumerating them.
+
+	For details on audio outputs and how to select the current output
+	see :ref:`audio`.
+    * - __u32
+      - ``modulator``
+      - Output devices can have zero or more RF modulators. When the
+	``type`` is ``V4L2_OUTPUT_TYPE_MODULATOR`` this is an RF connector
+	and this field identifies the modulator. It corresponds to struct
+	:c:type:`v4l2_modulator` field ``index``. For
+	details on modulators see :ref:`tuner`.
+    * - :ref:`v4l2_std_id <v4l2-std-id>`
+      - ``std``
+      - Every video output supports one or more different video standards.
+	This field is a set of all supported standards. For details on
+	video standards and how to switch see :ref:`standard`.
+    * - __u32
+      - ``capabilities``
+      - This field provides capabilities for the output. See
+	:ref:`output-capabilities` for flags.
+    * - __u32
+      - ``reserved``\ [3]
+      - Reserved for future extensions. Drivers must set the array to
+	zero.
+
+
+
+.. tabularcolumns:: |p{7.0cm}|p{1.8cm}|p{8.7cm}|
+
+.. _output-type:
+
+.. flat-table:: Output Type
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_OUTPUT_TYPE_MODULATOR``
+      - 1
+      - This output is an analog TV modulator.
+    * - ``V4L2_OUTPUT_TYPE_ANALOG``
+      - 2
+      - Any non-modulator video output, for example Composite Video,
+	S-Video, HDMI. The naming as ``_TYPE_ANALOG`` is historical,
+	today we would have called it ``_TYPE_VIDEO``.
+    * - ``V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY``
+      - 3
+      - The video output will be copied to a :ref:`video overlay <overlay>`.
+
+
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. _output-capabilities:
+
+.. flat-table:: Output capabilities
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_OUT_CAP_DV_TIMINGS``
+      - 0x00000002
+      - This output supports setting video timings by using
+	``VIDIOC_S_DV_TIMINGS``.
+    * - ``V4L2_OUT_CAP_STD``
+      - 0x00000004
+      - This output supports setting the TV standard by using
+	``VIDIOC_S_STD``.
+    * - ``V4L2_OUT_CAP_NATIVE_SIZE``
+      - 0x00000008
+      - This output supports setting the native size using the
+	``V4L2_SEL_TGT_NATIVE_SIZE`` selection target, see
+	:ref:`v4l2-selections-common`.
+
+
+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
+    The struct :c:type:`v4l2_output` ``index`` is out of
+    bounds.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-enumstd.rst b/Documentation/userspace-api/media/v4l/vidioc-enumstd.rst
new file mode 100644
index 000000000000..8a0508536c13
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-enumstd.rst
@@ -0,0 +1,367 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_ENUMSTD:
+
+*******************************************
+ioctl VIDIOC_ENUMSTD, VIDIOC_SUBDEV_ENUMSTD
+*******************************************
+
+Name
+====
+
+VIDIOC_ENUMSTD - VIDIOC_SUBDEV_ENUMSTD - Enumerate supported video standards
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_ENUMSTD, struct v4l2_standard *argp )
+    :name: VIDIOC_ENUMSTD
+
+.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_ENUMSTD, struct v4l2_standard *argp )
+    :name: VIDIOC_SUBDEV_ENUMSTD
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_standard`.
+
+
+Description
+===========
+
+To query the attributes of a video standard, especially a custom (driver
+defined) one, applications initialize the ``index`` field of struct
+:c:type:`v4l2_standard` and call the :ref:`VIDIOC_ENUMSTD`
+ioctl with a pointer to this structure. Drivers fill the rest of the
+structure or return an ``EINVAL`` error code when the index is out of
+bounds. To enumerate all standards applications shall begin at index
+zero, incrementing by one until the driver returns ``EINVAL``. Drivers may
+enumerate a different set of standards after switching the video input
+or output. [#f1]_
+
+
+.. c:type:: v4l2_standard
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. flat-table:: struct v4l2_standard
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``index``
+      - Number of the video standard, set by the application.
+    * - :ref:`v4l2_std_id <v4l2-std-id>`
+      - ``id``
+      - The bits in this field identify the standard as one of the common
+	standards listed in :ref:`v4l2-std-id`, or if bits 32 to 63 are
+	set as custom standards. Multiple bits can be set if the hardware
+	does not distinguish between these standards, however separate
+	indices do not indicate the opposite. The ``id`` must be unique.
+	No other enumerated struct :c:type:`v4l2_standard` structure,
+	for this input or output anyway, can contain the same set of bits.
+    * - __u8
+      - ``name``\ [24]
+      - Name of the standard, a NUL-terminated ASCII string, for example:
+	"PAL-B/G", "NTSC Japan". This information is intended for the
+	user.
+    * - struct :c:type:`v4l2_fract`
+      - ``frameperiod``
+      - The frame period (not field period) is numerator / denominator.
+	For example M/NTSC has a frame period of 1001 / 30000 seconds.
+    * - __u32
+      - ``framelines``
+      - Total lines per frame including blanking, e. g. 625 for B/PAL.
+    * - __u32
+      - ``reserved``\ [4]
+      - Reserved for future extensions. Drivers must set the array to
+	zero.
+
+
+
+.. c:type:: v4l2_fract
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. flat-table:: struct v4l2_fract
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``numerator``
+      -
+    * - __u32
+      - ``denominator``
+      -
+
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. _v4l2-std-id:
+
+.. flat-table:: typedef v4l2_std_id
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u64
+      - ``v4l2_std_id``
+      - This type is a set, each bit representing another video standard
+	as listed below and in :ref:`video-standards`. The 32 most
+	significant bits are reserved for custom (driver defined) video
+	standards.
+
+
+
+.. code-block:: c
+
+    #define V4L2_STD_PAL_B          ((v4l2_std_id)0x00000001)
+    #define V4L2_STD_PAL_B1         ((v4l2_std_id)0x00000002)
+    #define V4L2_STD_PAL_G          ((v4l2_std_id)0x00000004)
+    #define V4L2_STD_PAL_H          ((v4l2_std_id)0x00000008)
+    #define V4L2_STD_PAL_I          ((v4l2_std_id)0x00000010)
+    #define V4L2_STD_PAL_D          ((v4l2_std_id)0x00000020)
+    #define V4L2_STD_PAL_D1         ((v4l2_std_id)0x00000040)
+    #define V4L2_STD_PAL_K          ((v4l2_std_id)0x00000080)
+
+    #define V4L2_STD_PAL_M          ((v4l2_std_id)0x00000100)
+    #define V4L2_STD_PAL_N          ((v4l2_std_id)0x00000200)
+    #define V4L2_STD_PAL_Nc         ((v4l2_std_id)0x00000400)
+    #define V4L2_STD_PAL_60         ((v4l2_std_id)0x00000800)
+
+``V4L2_STD_PAL_60`` is a hybrid standard with 525 lines, 60 Hz refresh
+rate, and PAL color modulation with a 4.43 MHz color subcarrier. Some
+PAL video recorders can play back NTSC tapes in this mode for display on
+a 50/60 Hz agnostic PAL TV.
+
+
+.. code-block:: c
+
+    #define V4L2_STD_NTSC_M         ((v4l2_std_id)0x00001000)
+    #define V4L2_STD_NTSC_M_JP      ((v4l2_std_id)0x00002000)
+    #define V4L2_STD_NTSC_443       ((v4l2_std_id)0x00004000)
+
+``V4L2_STD_NTSC_443`` is a hybrid standard with 525 lines, 60 Hz refresh
+rate, and NTSC color modulation with a 4.43 MHz color subcarrier.
+
+
+.. code-block:: c
+
+    #define V4L2_STD_NTSC_M_KR      ((v4l2_std_id)0x00008000)
+
+    #define V4L2_STD_SECAM_B        ((v4l2_std_id)0x00010000)
+    #define V4L2_STD_SECAM_D        ((v4l2_std_id)0x00020000)
+    #define V4L2_STD_SECAM_G        ((v4l2_std_id)0x00040000)
+    #define V4L2_STD_SECAM_H        ((v4l2_std_id)0x00080000)
+    #define V4L2_STD_SECAM_K        ((v4l2_std_id)0x00100000)
+    #define V4L2_STD_SECAM_K1       ((v4l2_std_id)0x00200000)
+    #define V4L2_STD_SECAM_L        ((v4l2_std_id)0x00400000)
+    #define V4L2_STD_SECAM_LC       ((v4l2_std_id)0x00800000)
+
+    /* ATSC/HDTV */
+    #define V4L2_STD_ATSC_8_VSB     ((v4l2_std_id)0x01000000)
+    #define V4L2_STD_ATSC_16_VSB    ((v4l2_std_id)0x02000000)
+
+``V4L2_STD_ATSC_8_VSB`` and ``V4L2_STD_ATSC_16_VSB`` are U.S.
+terrestrial digital TV standards. Presently the V4L2 API does not
+support digital TV. See also the Linux DVB API at
+`https://linuxtv.org <https://linuxtv.org>`__.
+
+
+.. code-block:: c
+
+    #define V4L2_STD_PAL_BG         (V4L2_STD_PAL_B         |
+		     V4L2_STD_PAL_B1        |
+		     V4L2_STD_PAL_G)
+    #define V4L2_STD_B              (V4L2_STD_PAL_B         |
+		     V4L2_STD_PAL_B1        |
+		     V4L2_STD_SECAM_B)
+    #define V4L2_STD_GH             (V4L2_STD_PAL_G         |
+		     V4L2_STD_PAL_H         |
+		     V4L2_STD_SECAM_G       |
+		     V4L2_STD_SECAM_H)
+    #define V4L2_STD_PAL_DK         (V4L2_STD_PAL_D         |
+		     V4L2_STD_PAL_D1        |
+		     V4L2_STD_PAL_K)
+    #define V4L2_STD_PAL            (V4L2_STD_PAL_BG        |
+		     V4L2_STD_PAL_DK        |
+		     V4L2_STD_PAL_H         |
+		     V4L2_STD_PAL_I)
+    #define V4L2_STD_NTSC           (V4L2_STD_NTSC_M        |
+		     V4L2_STD_NTSC_M_JP     |
+		     V4L2_STD_NTSC_M_KR)
+    #define V4L2_STD_MN             (V4L2_STD_PAL_M         |
+		     V4L2_STD_PAL_N         |
+		     V4L2_STD_PAL_Nc        |
+		     V4L2_STD_NTSC)
+    #define V4L2_STD_SECAM_DK       (V4L2_STD_SECAM_D       |
+		     V4L2_STD_SECAM_K       |
+		     V4L2_STD_SECAM_K1)
+    #define V4L2_STD_DK             (V4L2_STD_PAL_DK        |
+		     V4L2_STD_SECAM_DK)
+
+    #define V4L2_STD_SECAM          (V4L2_STD_SECAM_B       |
+		     V4L2_STD_SECAM_G       |
+		     V4L2_STD_SECAM_H       |
+		     V4L2_STD_SECAM_DK      |
+		     V4L2_STD_SECAM_L       |
+		     V4L2_STD_SECAM_LC)
+
+    #define V4L2_STD_525_60         (V4L2_STD_PAL_M         |
+		     V4L2_STD_PAL_60        |
+		     V4L2_STD_NTSC          |
+		     V4L2_STD_NTSC_443)
+    #define V4L2_STD_625_50         (V4L2_STD_PAL           |
+		     V4L2_STD_PAL_N         |
+		     V4L2_STD_PAL_Nc        |
+		     V4L2_STD_SECAM)
+
+    #define V4L2_STD_UNKNOWN        0
+    #define V4L2_STD_ALL            (V4L2_STD_525_60        |
+		     V4L2_STD_625_50)
+
+
+.. raw:: latex
+
+    \begingroup
+    \tiny
+    \setlength{\tabcolsep}{2pt}
+
+..                            NTSC/M   PAL/M    /N       /B       /D       /H       /I        SECAM/B    /D       /K1     /L
+.. tabularcolumns:: |p{1.43cm}|p{1.38cm}|p{1.59cm}|p{1.7cm}|p{1.7cm}|p{1.17cm}|p{0.64cm}|p{1.71cm}|p{1.6cm}|p{1.07cm}|p{1.07cm}|p{1.07cm}|
+
+.. _video-standards:
+
+.. flat-table:: Video Standards (based on :ref:`itu470`)
+    :header-rows:  1
+    :stub-columns: 0
+
+    * - Characteristics
+      - M/NTSC [#f2]_
+      - M/PAL
+      - N/PAL [#f3]_
+      - B, B1, G/PAL
+      - D, D1, K/PAL
+      - H/PAL
+      - I/PAL
+      - B, G/SECAM
+      - D, K/SECAM
+      - K1/SECAM
+      - L/SECAM
+    * - Frame lines
+      - :cspan:`1` 525
+      - :cspan:`8` 625
+    * - Frame period (s)
+      - :cspan:`1` 1001/30000
+      - :cspan:`8` 1/25
+    * - Chrominance sub-carrier frequency (Hz)
+      - 3579545 ± 10
+      - 3579611.49 ± 10
+      - 4433618.75 ± 5
+
+	(3582056.25 ± 5)
+      - :cspan:`3` 4433618.75 ± 5
+      - 4433618.75 ± 1
+      - :cspan:`2` f\ :sub:`OR` = 4406250 ± 2000,
+
+	f\ :sub:`OB` = 4250000 ± 2000
+    * - Nominal radio-frequency channel bandwidth (MHz)
+      - 6
+      - 6
+      - 6
+      - B: 7; B1, G: 8
+      - 8
+      - 8
+      - 8
+      - 8
+      - 8
+      - 8
+      - 8
+    * - Sound carrier relative to vision carrier (MHz)
+      - 4.5
+      - 4.5
+      - 4.5
+      - 5.5 ± 0.001  [#f4]_  [#f5]_  [#f6]_  [#f7]_
+      - 6.5 ± 0.001
+      - 5.5
+      - 5.9996 ± 0.0005
+      - 5.5 ± 0.001
+      - 6.5 ± 0.001
+      - 6.5
+      - 6.5 [#f8]_
+
+.. raw:: latex
+
+    \endgroup
+
+
+
+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
+    The struct :c:type:`v4l2_standard` ``index`` is out
+    of bounds.
+
+ENODATA
+    Standard video timings are not supported for this input or output.
+
+.. [#f1]
+   The supported standards may overlap and we need an unambiguous set to
+   find the current standard returned by :ref:`VIDIOC_G_STD <VIDIOC_G_STD>`.
+
+.. [#f2]
+   Japan uses a standard similar to M/NTSC (V4L2_STD_NTSC_M_JP).
+
+.. [#f3]
+   The values in brackets apply to the combination N/PAL a.k.a.
+   N\ :sub:`C` used in Argentina (V4L2_STD_PAL_Nc).
+
+.. [#f4]
+   In the Federal Republic of Germany, Austria, Italy, the Netherlands,
+   Slovakia and Switzerland a system of two sound carriers is used, the
+   frequency of the second carrier being 242.1875 kHz above the
+   frequency of the first sound carrier. For stereophonic sound
+   transmissions a similar system is used in Australia.
+
+.. [#f5]
+   New Zealand uses a sound carrier displaced 5.4996 ± 0.0005 MHz from
+   the vision carrier.
+
+.. [#f6]
+   In Denmark, Finland, New Zealand, Sweden and Spain a system of two
+   sound carriers is used. In Iceland, Norway and Poland the same system
+   is being introduced. The second carrier is 5.85 MHz above the vision
+   carrier and is DQPSK modulated with 728 kbit/s sound and data
+   multiplex. (NICAM system)
+
+.. [#f7]
+   In the United Kingdom, a system of two sound carriers is used. The
+   second sound carrier is 6.552 MHz above the vision carrier and is
+   DQPSK modulated with a 728 kbit/s sound and data multiplex able to
+   carry two sound channels. (NICAM system)
+
+.. [#f8]
+   In France, a digital carrier 5.85 MHz away from the vision carrier
+   may be used in addition to the main sound carrier. It is modulated in
+   differentially encoded QPSK with a 728 kbit/s sound and data
+   multiplexer capable of carrying two sound channels. (NICAM system)
diff --git a/Documentation/userspace-api/media/v4l/vidioc-expbuf.rst b/Documentation/userspace-api/media/v4l/vidioc-expbuf.rst
new file mode 100644
index 000000000000..384a9be9eba0
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-expbuf.rst
@@ -0,0 +1,175 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_EXPBUF:
+
+*******************
+ioctl VIDIOC_EXPBUF
+*******************
+
+Name
+====
+
+VIDIOC_EXPBUF - Export a buffer as a DMABUF file descriptor.
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_EXPBUF, struct v4l2_exportbuffer *argp )
+    :name: VIDIOC_EXPBUF
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_exportbuffer`.
+
+
+Description
+===========
+
+This ioctl is an extension to the :ref:`memory mapping <mmap>` I/O
+method, therefore it is available only for ``V4L2_MEMORY_MMAP`` buffers.
+It can be used to export a buffer as a DMABUF file at any time after
+buffers have been allocated with the
+:ref:`VIDIOC_REQBUFS` ioctl.
+
+To export a buffer, applications fill struct
+:c:type:`v4l2_exportbuffer`. The ``type`` field is
+set to the same buffer type as was previously used with struct
+:c:type:`v4l2_requestbuffers` ``type``.
+Applications must also set the ``index`` field. Valid index numbers
+range from zero to the number of buffers allocated with
+:ref:`VIDIOC_REQBUFS` (struct
+:c:type:`v4l2_requestbuffers` ``count``) minus
+one. For the multi-planar API, applications set the ``plane`` field to
+the index of the plane to be exported. Valid planes range from zero to
+the maximal number of valid planes for the currently active format. For
+the single-planar API, applications must set ``plane`` to zero.
+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:`VIDIOC_EXPBUF` calls.
+
+After calling :ref:`VIDIOC_EXPBUF` the ``fd`` field will be set by a
+driver. This is a DMABUF file descriptor. The application may pass it to
+other DMABUF-aware devices. Refer to :ref:`DMABUF importing <dmabuf>`
+for details about importing DMABUF files into V4L2 nodes. 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 v4l2_buf_type bt, int index, int *dmafd)
+    {
+	struct v4l2_exportbuffer expbuf;
+
+	memset(&expbuf, 0, sizeof(expbuf));
+	expbuf.type = bt;
+	expbuf.index = index;
+	if (ioctl(v4lfd, VIDIOC_EXPBUF, &expbuf) == -1) {
+	    perror("VIDIOC_EXPBUF");
+	    return -1;
+	}
+
+	*dmafd = expbuf.fd;
+
+	return 0;
+    }
+
+
+.. code-block:: c
+
+    int buffer_export_mp(int v4lfd, enum v4l2_buf_type bt, int index,
+	int dmafd[], int n_planes)
+    {
+	int i;
+
+	for (i = 0; i < n_planes; ++i) {
+	    struct v4l2_exportbuffer expbuf;
+
+	    memset(&expbuf, 0, sizeof(expbuf));
+	    expbuf.type = bt;
+	    expbuf.index = index;
+	    expbuf.plane = i;
+	    if (ioctl(v4lfd, VIDIOC_EXPBUF, &expbuf) == -1) {
+		perror("VIDIOC_EXPBUF");
+		while (i)
+		    close(dmafd[--i]);
+		return -1;
+	    }
+	    dmafd[i] = expbuf.fd;
+	}
+
+	return 0;
+    }
+
+
+.. c:type:: v4l2_exportbuffer
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. flat-table:: struct v4l2_exportbuffer
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``type``
+      - Type of the buffer, same as struct
+	:c:type:`v4l2_format` ``type`` or struct
+	:c:type:`v4l2_requestbuffers` ``type``, set
+	by the application. See :c:type:`v4l2_buf_type`
+    * - __u32
+      - ``index``
+      - Number of the buffer, set by the application. This field is only
+	used for :ref:`memory mapping <mmap>` I/O and can range from
+	zero to the number of buffers allocated with the
+	:ref:`VIDIOC_REQBUFS` and/or
+	:ref:`VIDIOC_CREATE_BUFS` ioctls.
+    * - __u32
+      - ``plane``
+      - Index of the plane to be exported when using the multi-planar API.
+	Otherwise this value must be set to zero.
+    * - __u32
+      - ``flags``
+      - Flags for the newly created file, currently only ``O_CLOEXEC``,
+	``O_RDONLY``, ``O_WRONLY``, and ``O_RDWR`` are supported, refer to
+	the manual of open() for more details.
+    * - __s32
+      - ``fd``
+      - The DMABUF file descriptor associated with a buffer. Set by the
+	driver.
+    * - __u32
+      - ``reserved[11]``
+      - Reserved field for future use. Drivers and applications must set
+	the array to zero.
+
+
+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 ``type`` or ``index`` or ``plane`` fields are invalid.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-g-audio.rst b/Documentation/userspace-api/media/v4l/vidioc-g-audio.rst
new file mode 100644
index 000000000000..68531bcb62ab
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-g-audio.rst
@@ -0,0 +1,135 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_G_AUDIO:
+
+************************************
+ioctl VIDIOC_G_AUDIO, VIDIOC_S_AUDIO
+************************************
+
+Name
+====
+
+VIDIOC_G_AUDIO - VIDIOC_S_AUDIO - Query or select the current audio input and its attributes
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_G_AUDIO, struct v4l2_audio *argp )
+    :name: VIDIOC_G_AUDIO
+
+.. c:function:: int ioctl( int fd, VIDIOC_S_AUDIO, const struct v4l2_audio *argp )
+    :name: VIDIOC_S_AUDIO
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_audio`.
+
+
+Description
+===========
+
+To query the current audio input applications zero out the ``reserved``
+array of a struct :c:type:`v4l2_audio` and call the
+:ref:`VIDIOC_G_AUDIO <VIDIOC_G_AUDIO>` ioctl with a pointer to this structure. Drivers fill
+the rest of the structure or return an ``EINVAL`` error code when the device
+has no audio inputs, or none which combine with the current video input.
+
+Audio inputs have one writable property, the audio mode. To select the
+current audio input *and* change the audio mode, applications initialize
+the ``index`` and ``mode`` fields, and the ``reserved`` array of a
+struct :c:type:`v4l2_audio` structure and call the :ref:`VIDIOC_S_AUDIO <VIDIOC_G_AUDIO>`
+ioctl. Drivers may switch to a different audio mode if the request
+cannot be satisfied. However, this is a write-only ioctl, it does not
+return the actual new audio mode.
+
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. c:type:: v4l2_audio
+
+.. flat-table:: struct v4l2_audio
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``index``
+      - Identifies the audio input, set by the driver or application.
+    * - __u8
+      - ``name``\ [32]
+      - Name of the audio input, a NUL-terminated ASCII string, for
+	example: "Line In". This information is intended for the user,
+	preferably the connector label on the device itself.
+    * - __u32
+      - ``capability``
+      - Audio capability flags, see :ref:`audio-capability`.
+    * - __u32
+      - ``mode``
+      - Audio mode flags set by drivers and applications (on
+	:ref:`VIDIOC_S_AUDIO <VIDIOC_G_AUDIO>` ioctl), see :ref:`audio-mode`.
+    * - __u32
+      - ``reserved``\ [2]
+      - Reserved for future extensions. Drivers and applications must set
+	the array to zero.
+
+
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. _audio-capability:
+
+.. flat-table:: Audio Capability Flags
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_AUDCAP_STEREO``
+      - 0x00001
+      - This is a stereo input. The flag is intended to automatically
+	disable stereo recording etc. when the signal is always monaural.
+	The API provides no means to detect if stereo is *received*,
+	unless the audio input belongs to a tuner.
+    * - ``V4L2_AUDCAP_AVL``
+      - 0x00002
+      - Automatic Volume Level mode is supported.
+
+
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. _audio-mode:
+
+.. flat-table:: Audio Mode Flags
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_AUDMODE_AVL``
+      - 0x00001
+      - AVL mode is on.
+
+
+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
+    No audio inputs combine with the current video input, or the number
+    of the selected audio input is out of bounds or it does not combine.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-g-audioout.rst b/Documentation/userspace-api/media/v4l/vidioc-g-audioout.rst
new file mode 100644
index 000000000000..e13b74bf5ce3
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-g-audioout.rst
@@ -0,0 +1,108 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_G_AUDOUT:
+
+**************************************
+ioctl VIDIOC_G_AUDOUT, VIDIOC_S_AUDOUT
+**************************************
+
+Name
+====
+
+VIDIOC_G_AUDOUT - VIDIOC_S_AUDOUT - Query or select the current audio output
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_G_AUDOUT, struct v4l2_audioout *argp )
+    :name: VIDIOC_G_AUDOUT
+
+.. c:function:: int ioctl( int fd, VIDIOC_S_AUDOUT, const struct v4l2_audioout *argp )
+    :name: VIDIOC_S_AUDOUT
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_audioout`.
+
+
+Description
+===========
+
+To query the current audio output applications zero out the ``reserved``
+array of a struct :c:type:`v4l2_audioout` and call the
+``VIDIOC_G_AUDOUT`` ioctl with a pointer to this structure. Drivers fill
+the rest of the structure or return an ``EINVAL`` error code when the device
+has no audio inputs, or none which combine with the current video
+output.
+
+Audio outputs have no writable properties. Nevertheless, to select the
+current audio output applications can initialize the ``index`` field and
+``reserved`` array (which in the future may contain writable properties)
+of a struct :c:type:`v4l2_audioout` structure and call the
+``VIDIOC_S_AUDOUT`` ioctl. Drivers switch to the requested output or
+return the ``EINVAL`` error code when the index is out of bounds. This is a
+write-only ioctl, it does not return the current audio output attributes
+as ``VIDIOC_G_AUDOUT`` does.
+
+.. note::
+
+   Connectors on a TV card to loop back the received audio signal
+   to a sound card are not audio outputs in this sense.
+
+
+.. c:type:: v4l2_audioout
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. flat-table:: struct v4l2_audioout
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``index``
+      - Identifies the audio output, set by the driver or application.
+    * - __u8
+      - ``name``\ [32]
+      - Name of the audio output, a NUL-terminated ASCII string, for
+	example: "Line Out". This information is intended for the user,
+	preferably the connector label on the device itself.
+    * - __u32
+      - ``capability``
+      - Audio capability flags, none defined yet. Drivers must set this
+	field to zero.
+    * - __u32
+      - ``mode``
+      - Audio mode, none defined yet. Drivers and applications (on
+	``VIDIOC_S_AUDOUT``) must set this field to zero.
+    * - __u32
+      - ``reserved``\ [2]
+      - Reserved for future extensions. Drivers and applications must set
+	the array to zero.
+
+
+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
+    No audio outputs combine with the current video output, or the
+    number of the selected audio output is out of bounds or it does not
+    combine.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-g-crop.rst b/Documentation/userspace-api/media/v4l/vidioc-g-crop.rst
new file mode 100644
index 000000000000..10e086be55d5
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-g-crop.rst
@@ -0,0 +1,119 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_G_CROP:
+
+**********************************
+ioctl VIDIOC_G_CROP, VIDIOC_S_CROP
+**********************************
+
+Name
+====
+
+VIDIOC_G_CROP - VIDIOC_S_CROP - Get or set the current cropping rectangle
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_G_CROP, struct v4l2_crop *argp )
+    :name: VIDIOC_G_CROP
+
+.. c:function:: int ioctl( int fd, VIDIOC_S_CROP, const struct v4l2_crop *argp )
+    :name: VIDIOC_S_CROP
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_crop`.
+
+
+Description
+===========
+
+To query the cropping rectangle size and position applications set the
+``type`` field of a struct :c:type:`v4l2_crop` structure to the
+respective buffer (stream) type and call the :ref:`VIDIOC_G_CROP <VIDIOC_G_CROP>` ioctl
+with a pointer to this structure. The driver fills the rest of the
+structure or returns the ``EINVAL`` error code if cropping is not supported.
+
+To change the cropping rectangle applications initialize the ``type``
+and struct :c:type:`v4l2_rect` substructure named ``c`` of a
+v4l2_crop structure and call the :ref:`VIDIOC_S_CROP <VIDIOC_G_CROP>` ioctl with a pointer
+to this structure.
+
+The driver first adjusts the requested dimensions against hardware
+limits, i. e. the bounds given by the capture/output window, and it
+rounds to the closest possible values of horizontal and vertical offset,
+width and height. In particular the driver must round the vertical
+offset of the cropping rectangle to frame lines modulo two, such that
+the field order cannot be confused.
+
+Second the driver adjusts the image size (the opposite rectangle of the
+scaling process, source or target depending on the data direction) to
+the closest size possible while maintaining the current horizontal and
+vertical scaling factor.
+
+Finally the driver programs the hardware with the actual cropping and
+image parameters. :ref:`VIDIOC_S_CROP <VIDIOC_G_CROP>` is a write-only ioctl, it does not
+return the actual parameters. To query them applications must call
+:ref:`VIDIOC_G_CROP <VIDIOC_G_CROP>` and :ref:`VIDIOC_G_FMT`. When the
+parameters are unsuitable the application may modify the cropping or
+image parameters and repeat the cycle until satisfactory parameters have
+been negotiated.
+
+When cropping is not supported then no parameters are changed and
+:ref:`VIDIOC_S_CROP <VIDIOC_G_CROP>` returns the ``EINVAL`` error code.
+
+
+.. c:type:: v4l2_crop
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. flat-table:: struct v4l2_crop
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``type``
+      - Type of the data stream, set by the application. Only these types
+	are valid here: ``V4L2_BUF_TYPE_VIDEO_CAPTURE``, ``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE``,
+	``V4L2_BUF_TYPE_VIDEO_OUTPUT``, ``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE`` and
+	``V4L2_BUF_TYPE_VIDEO_OVERLAY``. See :c:type:`v4l2_buf_type` and the note below.
+    * - struct :c:type:`v4l2_rect`
+      - ``c``
+      - Cropping rectangle. The same co-ordinate system as for struct
+	:c:type:`v4l2_cropcap` ``bounds`` is used.
+
+.. note::
+   Unfortunately in the case of multiplanar buffer types
+   (``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE`` and ``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE``)
+   this API was messed up with regards to how the :c:type:`v4l2_crop` ``type`` field
+   should be filled in. Some drivers only accepted the ``_MPLANE`` buffer type while
+   other drivers only accepted a non-multiplanar buffer type (i.e. without the
+   ``_MPLANE`` at the end).
+
+   Starting with kernel 4.13 both variations are allowed.
+
+
+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.
+
+ENODATA
+    Cropping is not supported for this input or output.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-g-ctrl.rst b/Documentation/userspace-api/media/v4l/vidioc-g-ctrl.rst
new file mode 100644
index 000000000000..9831b7514028
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-g-ctrl.rst
@@ -0,0 +1,106 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_G_CTRL:
+
+**********************************
+ioctl VIDIOC_G_CTRL, VIDIOC_S_CTRL
+**********************************
+
+Name
+====
+
+VIDIOC_G_CTRL - VIDIOC_S_CTRL - Get or set the value of a control
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_G_CTRL, struct v4l2_control *argp )
+    :name: VIDIOC_G_CTRL
+
+.. c:function:: int ioctl( int fd, VIDIOC_S_CTRL, struct v4l2_control *argp )
+    :name: VIDIOC_S_CTRL
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_control`.
+
+
+Description
+===========
+
+To get the current value of a control applications initialize the ``id``
+field of a struct :c:type:`v4l2_control` and call the
+:ref:`VIDIOC_G_CTRL <VIDIOC_G_CTRL>` ioctl with a pointer to this structure. To change the
+value of a control applications initialize the ``id`` and ``value``
+fields of a struct :c:type:`v4l2_control` and call the
+:ref:`VIDIOC_S_CTRL <VIDIOC_G_CTRL>` ioctl.
+
+When the ``id`` is invalid drivers return an ``EINVAL`` error code. When the
+``value`` is out of bounds drivers can choose to take the closest valid
+value or return an ``ERANGE`` error code, whatever seems more appropriate.
+However, :ref:`VIDIOC_S_CTRL <VIDIOC_G_CTRL>` is a write-only ioctl, it does not return the
+actual new value. If the ``value`` is inappropriate for the control
+(e.g. if it refers to an unsupported menu index of a menu control), then
+EINVAL error code is returned as well.
+
+These ioctls work only with user controls. For other control classes the
+:ref:`VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>`,
+:ref:`VIDIOC_S_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` or
+:ref:`VIDIOC_TRY_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` must be used.
+
+
+.. c:type:: v4l2_control
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. flat-table:: struct v4l2_control
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``id``
+      - Identifies the control, set by the application.
+    * - __s32
+      - ``value``
+      - New value or current value.
+
+
+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
+    The struct :c:type:`v4l2_control` ``id`` is invalid
+    or the ``value`` is inappropriate for the given control (i.e. if a
+    menu item is selected that is not supported by the driver according
+    to :ref:`VIDIOC_QUERYMENU <VIDIOC_QUERYCTRL>`).
+
+ERANGE
+    The struct :c:type:`v4l2_control` ``value`` is out of
+    bounds.
+
+EBUSY
+    The control is temporarily not changeable, possibly because another
+    applications took over control of the device function this control
+    belongs to.
+
+EACCES
+    Attempt to set a read-only control or to get a write-only control.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-g-dv-timings.rst b/Documentation/userspace-api/media/v4l/vidioc-g-dv-timings.rst
new file mode 100644
index 000000000000..84806a893cb7
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-g-dv-timings.rst
@@ -0,0 +1,312 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_G_DV_TIMINGS:
+
+**********************************************
+ioctl VIDIOC_G_DV_TIMINGS, VIDIOC_S_DV_TIMINGS
+**********************************************
+
+Name
+====
+
+VIDIOC_G_DV_TIMINGS - VIDIOC_S_DV_TIMINGS - VIDIOC_SUBDEV_G_DV_TIMINGS - VIDIOC_SUBDEV_S_DV_TIMINGS - Get or set DV timings for input or output
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_G_DV_TIMINGS, struct v4l2_dv_timings *argp )
+    :name: VIDIOC_G_DV_TIMINGS
+
+.. c:function:: int ioctl( int fd, VIDIOC_S_DV_TIMINGS, struct v4l2_dv_timings *argp )
+    :name: VIDIOC_S_DV_TIMINGS
+
+.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_G_DV_TIMINGS, struct v4l2_dv_timings *argp )
+    :name: VIDIOC_SUBDEV_G_DV_TIMINGS
+
+.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_S_DV_TIMINGS, struct v4l2_dv_timings *argp )
+    :name: VIDIOC_SUBDEV_S_DV_TIMINGS
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_dv_timings`.
+
+
+Description
+===========
+
+To set DV timings for the input or output, applications use the
+:ref:`VIDIOC_S_DV_TIMINGS <VIDIOC_G_DV_TIMINGS>` ioctl and to get the current timings,
+applications use the :ref:`VIDIOC_G_DV_TIMINGS <VIDIOC_G_DV_TIMINGS>` ioctl. The detailed timing
+information is filled in using the structure struct
+:c:type:`v4l2_dv_timings`. These ioctls take a
+pointer to the struct :c:type:`v4l2_dv_timings`
+structure as argument. If the ioctl is not supported or the timing
+values are not correct, the driver returns ``EINVAL`` error code.
+
+The ``linux/v4l2-dv-timings.h`` header can be used to get the timings of
+the formats in the :ref:`cea861` and :ref:`vesadmt` standards. If
+the current input or output does not support DV timings (e.g. if
+:ref:`VIDIOC_ENUMINPUT` does not set the
+``V4L2_IN_CAP_DV_TIMINGS`` flag), then ``ENODATA`` error code is returned.
+
+
+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
+    This ioctl is not supported, or the :ref:`VIDIOC_S_DV_TIMINGS <VIDIOC_G_DV_TIMINGS>`
+    parameter was unsuitable.
+
+ENODATA
+    Digital video timings are not supported for this input or output.
+
+EBUSY
+    The device is busy and therefore can not change the timings.
+
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. c:type:: v4l2_bt_timings
+
+.. flat-table:: struct v4l2_bt_timings
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``width``
+      - Width of the active video in pixels.
+    * - __u32
+      - ``height``
+      - Height of the active video frame in lines. So for interlaced
+	formats the height of the active video in each field is
+	``height``/2.
+    * - __u32
+      - ``interlaced``
+      - Progressive (``V4L2_DV_PROGRESSIVE``) or interlaced (``V4L2_DV_INTERLACED``).
+    * - __u32
+      - ``polarities``
+      - This is a bit mask that defines polarities of sync signals. bit 0
+	(``V4L2_DV_VSYNC_POS_POL``) is for vertical sync polarity and bit
+	1 (``V4L2_DV_HSYNC_POS_POL``) is for horizontal sync polarity. If
+	the bit is set (1) it is positive polarity and if is cleared (0),
+	it is negative polarity.
+    * - __u64
+      - ``pixelclock``
+      - Pixel clock in Hz. Ex. 74.25MHz->74250000
+    * - __u32
+      - ``hfrontporch``
+      - Horizontal front porch in pixels
+    * - __u32
+      - ``hsync``
+      - Horizontal sync length in pixels
+    * - __u32
+      - ``hbackporch``
+      - Horizontal back porch in pixels
+    * - __u32
+      - ``vfrontporch``
+      - Vertical front porch in lines. For interlaced formats this refers
+	to the odd field (aka field 1).
+    * - __u32
+      - ``vsync``
+      - Vertical sync length in lines. For interlaced formats this refers
+	to the odd field (aka field 1).
+    * - __u32
+      - ``vbackporch``
+      - Vertical back porch in lines. For interlaced formats this refers
+	to the odd field (aka field 1).
+    * - __u32
+      - ``il_vfrontporch``
+      - Vertical front porch in lines for the even field (aka field 2) of
+	interlaced field formats. Must be 0 for progressive formats.
+    * - __u32
+      - ``il_vsync``
+      - Vertical sync length in lines for the even field (aka field 2) of
+	interlaced field formats. Must be 0 for progressive formats.
+    * - __u32
+      - ``il_vbackporch``
+      - Vertical back porch in lines for the even field (aka field 2) of
+	interlaced field formats. Must be 0 for progressive formats.
+    * - __u32
+      - ``standards``
+      - The video standard(s) this format belongs to. This will be filled
+	in by the driver. Applications must set this to 0. See
+	:ref:`dv-bt-standards` for a list of standards.
+    * - __u32
+      - ``flags``
+      - Several flags giving more information about the format. See
+	:ref:`dv-bt-flags` for a description of the flags.
+    * - struct :c:type:`v4l2_fract`
+      - ``picture_aspect``
+      - The picture aspect if the pixels are not square. Only valid if the
+        ``V4L2_DV_FL_HAS_PICTURE_ASPECT`` flag is set.
+    * - __u8
+      - ``cea861_vic``
+      - The Video Identification Code according to the CEA-861 standard.
+        Only valid if the ``V4L2_DV_FL_HAS_CEA861_VIC`` flag is set.
+    * - __u8
+      - ``hdmi_vic``
+      - The Video Identification Code according to the HDMI standard.
+        Only valid if the ``V4L2_DV_FL_HAS_HDMI_VIC`` flag is set.
+    * - __u8
+      - ``reserved[46]``
+      - Reserved for future extensions. Drivers and applications must set
+	the array to zero.
+
+
+.. tabularcolumns:: |p{3.5cm}|p{3.5cm}|p{7.0cm}|p{3.5cm}|
+
+.. c:type:: v4l2_dv_timings
+
+.. flat-table:: struct v4l2_dv_timings
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``type``
+      - Type of DV timings as listed in :ref:`dv-timing-types`.
+    * - union {
+      - (anonymous)
+    * - struct :c:type:`v4l2_bt_timings`
+      - ``bt``
+      - Timings defined by BT.656/1120 specifications
+    * - __u32
+      - ``reserved``\ [32]
+      -
+    * - }
+      -
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. _dv-timing-types:
+
+.. flat-table:: DV Timing types
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - Timing type
+      - value
+      - Description
+    * -
+      -
+      -
+    * - ``V4L2_DV_BT_656_1120``
+      - 0
+      - BT.656/1120 timings
+
+.. tabularcolumns:: |p{4.5cm}|p{12.8cm}|
+
+.. _dv-bt-standards:
+
+.. flat-table:: DV BT Timing standards
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - Timing standard
+      - Description
+    * - ``V4L2_DV_BT_STD_CEA861``
+      - The timings follow the CEA-861 Digital TV Profile standard
+    * - ``V4L2_DV_BT_STD_DMT``
+      - The timings follow the VESA Discrete Monitor Timings standard
+    * - ``V4L2_DV_BT_STD_CVT``
+      - The timings follow the VESA Coordinated Video Timings standard
+    * - ``V4L2_DV_BT_STD_GTF``
+      - The timings follow the VESA Generalized Timings Formula standard
+    * - ``V4L2_DV_BT_STD_SDI``
+      - The timings follow the SDI Timings standard.
+	There are no horizontal syncs/porches at all in this format.
+	Total blanking timings must be set in hsync or vsync fields only.
+
+.. tabularcolumns:: |p{7.0cm}|p{10.5cm}|
+
+.. _dv-bt-flags:
+
+.. flat-table:: DV BT Timing flags
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - Flag
+      - Description
+    * - ``V4L2_DV_FL_REDUCED_BLANKING``
+      - CVT/GTF specific: the timings use reduced blanking (CVT) or the
+	'Secondary GTF' curve (GTF). In both cases the horizontal and/or
+	vertical blanking intervals are reduced, allowing a higher
+	resolution over the same bandwidth. This is a read-only flag,
+	applications must not set this.
+    * - ``V4L2_DV_FL_CAN_REDUCE_FPS``
+      - CEA-861 specific: set for CEA-861 formats with a framerate that is
+	a multiple of six. These formats can be optionally played at 1 /
+	1.001 speed to be compatible with 60 Hz based standards such as
+	NTSC and PAL-M that use a framerate of 29.97 frames per second. If
+	the transmitter can't generate such frequencies, then the flag
+	will also be cleared. This is a read-only flag, applications must
+	not set this.
+    * - ``V4L2_DV_FL_REDUCED_FPS``
+      - CEA-861 specific: only valid for video transmitters or video
+        receivers that have the ``V4L2_DV_FL_CAN_DETECT_REDUCED_FPS``
+	set. This flag is cleared otherwise. It is also only valid for
+	formats with the ``V4L2_DV_FL_CAN_REDUCE_FPS`` flag set, for other
+	formats the flag will be cleared by the driver.
+
+	If the application sets this flag for a transmitter, then the
+	pixelclock used to set up the transmitter is divided by 1.001 to
+	make it compatible with NTSC framerates. If the transmitter can't
+	generate such frequencies, then the flag will be cleared.
+
+	If a video receiver detects that the format uses a reduced framerate,
+	then it will set this flag to signal this to the application.
+    * - ``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
+	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
+	used depends on the hardware.
+    * - ``V4L2_DV_FL_IS_CE_VIDEO``
+      - If set, then this is a Consumer Electronics (CE) video format.
+	Such formats differ from other formats (commonly called IT
+	formats) in that if R'G'B' encoding is used then by default the
+	R'G'B' values use limited range (i.e. 16-235) as opposed to full
+	range (i.e. 0-255). All formats defined in CEA-861 except for the
+	640x480p59.94 format are CE formats.
+    * - ``V4L2_DV_FL_FIRST_FIELD_EXTRA_LINE``
+      - Some formats like SMPTE-125M have an interlaced signal with a odd
+	total height. For these formats, if this flag is set, the first
+	field has the extra line. Else, it is the second field.
+    * - ``V4L2_DV_FL_HAS_PICTURE_ASPECT``
+      - If set, then the picture_aspect field is valid. Otherwise assume that
+        the pixels are square, so the picture aspect ratio is the same as the
+	width to height ratio.
+    * - ``V4L2_DV_FL_HAS_CEA861_VIC``
+      - If set, then the cea861_vic field is valid and contains the Video
+        Identification Code as per the CEA-861 standard.
+    * - ``V4L2_DV_FL_HAS_HDMI_VIC``
+      - If set, then the hdmi_vic field is valid and contains the Video
+        Identification Code as per the HDMI standard (HDMI Vendor Specific
+	InfoFrame).
+    * - ``V4L2_DV_FL_CAN_DETECT_REDUCED_FPS``
+      - CEA-861 specific: only valid for video receivers, the flag is
+        cleared by transmitters.
+        If set, then the hardware can detect the difference between
+	regular framerates and framerates reduced by 1000/1001. E.g.:
+	60 vs 59.94 Hz, 30 vs 29.97 Hz or 24 vs 23.976 Hz.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-g-edid.rst b/Documentation/userspace-api/media/v4l/vidioc-g-edid.rst
new file mode 100644
index 000000000000..0620f4cbbcbd
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-g-edid.rst
@@ -0,0 +1,154 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_G_EDID:
+
+******************************************************************************
+ioctl VIDIOC_G_EDID, VIDIOC_S_EDID, VIDIOC_SUBDEV_G_EDID, VIDIOC_SUBDEV_S_EDID
+******************************************************************************
+
+Name
+====
+
+VIDIOC_G_EDID - VIDIOC_S_EDID - VIDIOC_SUBDEV_G_EDID - VIDIOC_SUBDEV_S_EDID - Get or set the EDID of a video receiver/transmitter
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_G_EDID, struct v4l2_edid *argp )
+    :name: VIDIOC_G_EDID
+
+.. c:function:: int ioctl( int fd, VIDIOC_S_EDID, struct v4l2_edid *argp )
+    :name: VIDIOC_S_EDID
+
+
+.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_G_EDID, struct v4l2_edid *argp )
+    :name: VIDIOC_SUBDEV_G_EDID
+
+.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_S_EDID, struct v4l2_edid *argp )
+    :name: VIDIOC_SUBDEV_S_EDID
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+   Pointer to struct :c:type:`v4l2_edid`.
+
+
+Description
+===========
+
+These ioctls can be used to get or set an EDID associated with an input
+from a receiver or an output of a transmitter device. They can be used
+with subdevice nodes (/dev/v4l-subdevX) or with video nodes
+(/dev/videoX).
+
+When used with video nodes the ``pad`` field represents the input (for
+video capture devices) or output (for video output devices) index as is
+returned by :ref:`VIDIOC_ENUMINPUT` and
+:ref:`VIDIOC_ENUMOUTPUT` respectively. When used
+with subdevice nodes the ``pad`` field represents the input or output
+pad of the subdevice. If there is no EDID support for the given ``pad``
+value, then the ``EINVAL`` error code will be returned.
+
+To get the EDID data the application has to fill in the ``pad``,
+``start_block``, ``blocks`` and ``edid`` fields, zero the ``reserved``
+array and call :ref:`VIDIOC_G_EDID <VIDIOC_G_EDID>`. The current EDID from block
+``start_block`` and of size ``blocks`` will be placed in the memory
+``edid`` points to. The ``edid`` pointer must point to memory at least
+``blocks`` * 128 bytes large (the size of one block is 128 bytes).
+
+If there are fewer blocks than specified, then the driver will set
+``blocks`` to the actual number of blocks. If there are no EDID blocks
+available at all, then the error code ``ENODATA`` is set.
+
+If blocks have to be retrieved from the sink, then this call will block
+until they have been read.
+
+If ``start_block`` and ``blocks`` are both set to 0 when
+:ref:`VIDIOC_G_EDID <VIDIOC_G_EDID>` is called, then the driver will set ``blocks`` to the
+total number of available EDID blocks and it will return 0 without
+copying any data. This is an easy way to discover how many EDID blocks
+there are.
+
+.. note::
+
+   If there are no EDID blocks available at all, then
+   the driver will set ``blocks`` to 0 and it returns 0.
+
+To set the EDID blocks of a receiver the application has to fill in the
+``pad``, ``blocks`` and ``edid`` fields, set ``start_block`` to 0 and
+zero the ``reserved`` array. It is not possible to set part of an EDID,
+it is always all or nothing. Setting the EDID data is only valid for
+receivers as it makes no sense for a transmitter.
+
+The driver assumes that the full EDID is passed in. If there are more
+EDID blocks than the hardware can handle then the EDID is not written,
+but instead the error code ``E2BIG`` is set and ``blocks`` is set to the
+maximum that the hardware supports. If ``start_block`` is any value
+other than 0 then the error code ``EINVAL`` is set.
+
+To disable an EDID you set ``blocks`` to 0. Depending on the hardware
+this will drive the hotplug pin low and/or block the source from reading
+the EDID data in some way. In any case, the end result is the same: the
+EDID is no longer available.
+
+
+.. c:type:: v4l2_edid
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. flat-table:: struct v4l2_edid
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``pad``
+      - Pad for which to get/set the EDID blocks. When used with a video
+	device node the pad represents the input or output index as
+	returned by :ref:`VIDIOC_ENUMINPUT` and
+	:ref:`VIDIOC_ENUMOUTPUT` respectively.
+    * - __u32
+      - ``start_block``
+      - Read the EDID from starting with this block. Must be 0 when
+	setting the EDID.
+    * - __u32
+      - ``blocks``
+      - The number of blocks to get or set. Must be less or equal to 256
+	(the maximum number of blocks as defined by the standard). When
+	you set the EDID and ``blocks`` is 0, then the EDID is disabled or
+	erased.
+    * - __u32
+      - ``reserved``\ [5]
+      - Reserved for future extensions. Applications and drivers must set
+	the array to zero.
+    * - __u8 *
+      - ``edid``
+      - Pointer to memory that contains the EDID. The minimum size is
+	``blocks`` * 128.
+
+
+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.
+
+``ENODATA``
+    The EDID data is not available.
+
+``E2BIG``
+    The EDID data you provided is more than the hardware can handle.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-g-enc-index.rst b/Documentation/userspace-api/media/v4l/vidioc-g-enc-index.rst
new file mode 100644
index 000000000000..8aad30a7c6c3
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-g-enc-index.rst
@@ -0,0 +1,156 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_G_ENC_INDEX:
+
+************************
+ioctl VIDIOC_G_ENC_INDEX
+************************
+
+Name
+====
+
+VIDIOC_G_ENC_INDEX - Get meta data about a compressed video stream
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_G_ENC_INDEX, struct v4l2_enc_idx *argp )
+    :name: VIDIOC_G_ENC_INDEX
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_enc_idx`.
+
+
+Description
+===========
+
+The :ref:`VIDIOC_G_ENC_INDEX <VIDIOC_G_ENC_INDEX>` ioctl provides meta data about a compressed
+video stream the same or another application currently reads from the
+driver, which is useful for random access into the stream without
+decoding it.
+
+To read the data applications must call :ref:`VIDIOC_G_ENC_INDEX <VIDIOC_G_ENC_INDEX>` with a
+pointer to a struct :c:type:`v4l2_enc_idx`. On success
+the driver fills the ``entry`` array, stores the number of elements
+written in the ``entries`` field, and initializes the ``entries_cap``
+field.
+
+Each element of the ``entry`` array contains meta data about one
+picture. A :ref:`VIDIOC_G_ENC_INDEX <VIDIOC_G_ENC_INDEX>` call reads up to
+``V4L2_ENC_IDX_ENTRIES`` entries from a driver buffer, which can hold up
+to ``entries_cap`` entries. This number can be lower or higher than
+``V4L2_ENC_IDX_ENTRIES``, but not zero. When the application fails to
+read the meta data in time the oldest entries will be lost. When the
+buffer is empty or no capturing/encoding is in progress, ``entries``
+will be zero.
+
+Currently this ioctl is only defined for MPEG-2 program streams and
+video elementary streams.
+
+
+.. tabularcolumns:: |p{3.8cm}|p{5.6cm}|p{8.1cm}|
+
+.. c:type:: v4l2_enc_idx
+
+.. flat-table:: struct v4l2_enc_idx
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 3 8
+
+    * - __u32
+      - ``entries``
+      - The number of entries the driver stored in the ``entry`` array.
+    * - __u32
+      - ``entries_cap``
+      - The number of entries the driver can buffer. Must be greater than
+	zero.
+    * - __u32
+      - ``reserved``\ [4]
+      - Reserved for future extensions. Drivers must set the
+	array to zero.
+    * - struct :c:type:`v4l2_enc_idx_entry`
+      - ``entry``\ [``V4L2_ENC_IDX_ENTRIES``]
+      - Meta data about a compressed video stream. Each element of the
+	array corresponds to one picture, sorted in ascending order by
+	their ``offset``.
+
+
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. c:type:: v4l2_enc_idx_entry
+
+.. flat-table:: struct v4l2_enc_idx_entry
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u64
+      - ``offset``
+      - The offset in bytes from the beginning of the compressed video
+	stream to the beginning of this picture, that is a *PES packet
+	header* as defined in :ref:`mpeg2part1` or a *picture header* as
+	defined in :ref:`mpeg2part2`. When the encoder is stopped, the
+	driver resets the offset to zero.
+    * - __u64
+      - ``pts``
+      - The 33 bit *Presentation Time Stamp* of this picture as defined in
+	:ref:`mpeg2part1`.
+    * - __u32
+      - ``length``
+      - The length of this picture in bytes.
+    * - __u32
+      - ``flags``
+      - Flags containing the coding type of this picture, see
+	:ref:`enc-idx-flags`.
+    * - __u32
+      - ``reserved``\ [2]
+      - Reserved for future extensions. Drivers must set the array to
+	zero.
+
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. _enc-idx-flags:
+
+.. flat-table:: Index Entry Flags
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_ENC_IDX_FRAME_I``
+      - 0x00
+      - This is an Intra-coded picture.
+    * - ``V4L2_ENC_IDX_FRAME_P``
+      - 0x01
+      - This is a Predictive-coded picture.
+    * - ``V4L2_ENC_IDX_FRAME_B``
+      - 0x02
+      - This is a Bidirectionally predictive-coded picture.
+    * - ``V4L2_ENC_IDX_FRAME_MASK``
+      - 0x0F
+      - *AND* the flags field with this mask to obtain the picture coding
+	type.
+
+
+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/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst b/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst
new file mode 100644
index 000000000000..add17c9204cb
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst
@@ -0,0 +1,416 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_G_EXT_CTRLS:
+
+******************************************************************
+ioctl VIDIOC_G_EXT_CTRLS, VIDIOC_S_EXT_CTRLS, VIDIOC_TRY_EXT_CTRLS
+******************************************************************
+
+Name
+====
+
+VIDIOC_G_EXT_CTRLS - VIDIOC_S_EXT_CTRLS - VIDIOC_TRY_EXT_CTRLS - Get or set the value of several controls, try control values
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_G_EXT_CTRLS, struct v4l2_ext_controls *argp )
+    :name: VIDIOC_G_EXT_CTRLS
+
+
+.. c:function:: int ioctl( int fd, VIDIOC_S_EXT_CTRLS, struct v4l2_ext_controls *argp )
+    :name: VIDIOC_S_EXT_CTRLS
+
+
+.. c:function:: int ioctl( int fd, VIDIOC_TRY_EXT_CTRLS, struct v4l2_ext_controls *argp )
+    :name: VIDIOC_TRY_EXT_CTRLS
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_ext_controls`.
+
+
+Description
+===========
+
+These ioctls allow the caller to get or set multiple controls
+atomically. Control IDs are grouped into control classes (see
+:ref:`ctrl-class`) and all controls in the control array must belong
+to the same control class.
+
+Applications must always fill in the ``count``, ``which``, ``controls``
+and ``reserved`` fields of struct
+:c:type:`v4l2_ext_controls`, and initialize the
+struct :c:type:`v4l2_ext_control` array pointed to
+by the ``controls`` fields.
+
+To get the current value of a set of controls applications initialize
+the ``id``, ``size`` and ``reserved2`` fields of each struct
+:c:type:`v4l2_ext_control` and call the
+:ref:`VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` ioctl. String controls controls must also set the
+``string`` field. Controls of compound types
+(``V4L2_CTRL_FLAG_HAS_PAYLOAD`` is set) must set the ``ptr`` field.
+
+If the ``size`` is too small to receive the control result (only
+relevant for pointer-type controls like strings), then the driver will
+set ``size`` to a valid value and return an ``ENOSPC`` error code. You
+should re-allocate the memory to this new size and try again. For the
+string type it is possible that the same issue occurs again if the
+string has grown in the meantime. It is recommended to call
+:ref:`VIDIOC_QUERYCTRL` first and use
+``maximum``\ +1 as the new ``size`` value. It is guaranteed that that is
+sufficient memory.
+
+N-dimensional arrays are set and retrieved row-by-row. You cannot set a
+partial array, all elements have to be set or retrieved. The total size
+is calculated as ``elems`` * ``elem_size``. These values can be obtained
+by calling :ref:`VIDIOC_QUERY_EXT_CTRL <VIDIOC_QUERYCTRL>`.
+
+To change the value of a set of controls applications initialize the
+``id``, ``size``, ``reserved2`` and ``value/value64/string/ptr`` fields
+of each struct :c:type:`v4l2_ext_control` and call
+the :ref:`VIDIOC_S_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` ioctl. The controls will only be set if *all*
+control values are valid.
+
+To check if a set of controls have correct values applications
+initialize the ``id``, ``size``, ``reserved2`` and
+``value/value64/string/ptr`` fields of each struct
+:c:type:`v4l2_ext_control` and call the
+:ref:`VIDIOC_TRY_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` ioctl. It is up to the driver whether wrong
+values are automatically adjusted to a valid value or if an error is
+returned.
+
+When the ``id`` or ``which`` is invalid drivers return an ``EINVAL`` error
+code. When the value is out of bounds drivers can choose to take the
+closest valid value or return an ``ERANGE`` error code, whatever seems more
+appropriate. In the first case the new value is set in struct
+:c:type:`v4l2_ext_control`. If the new control value
+is inappropriate (e.g. the given menu index is not supported by the menu
+control), then this will also result in an ``EINVAL`` error code error.
+
+If ``request_fd`` is set to a not-yet-queued :ref:`request <media-request-api>`
+file descriptor and ``which`` is set to ``V4L2_CTRL_WHICH_REQUEST_VAL``,
+then the controls are not applied immediately when calling
+:ref:`VIDIOC_S_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>`, but instead are applied by
+the driver for the buffer associated with the same request.
+If the device does not support requests, then ``EACCES`` will be returned.
+If requests are supported but an invalid request file descriptor is given,
+then ``EINVAL`` will be returned.
+
+An attempt to call :ref:`VIDIOC_S_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` for a
+request that has already been queued will result in an ``EBUSY`` error.
+
+If ``request_fd`` is specified and ``which`` is set to
+``V4L2_CTRL_WHICH_REQUEST_VAL`` during a call to
+:ref:`VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>`, then it will return the
+values of the controls at the time of request completion.
+If the request is not yet completed, then this will result in an
+``EACCES`` error.
+
+The driver will only set/get these controls if all control values are
+correct. This prevents the situation where only some of the controls
+were set/get. Only low-level errors (e. g. a failed i2c command) can
+still cause this situation.
+
+
+.. tabularcolumns:: |p{1.2cm}|p{3.0cm}|p{1.5cm}|p{11.8cm}|
+
+.. c:type:: v4l2_ext_control
+
+.. cssclass: longtable
+
+.. flat-table:: struct v4l2_ext_control
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``id``
+      - Identifies the control, set by the application.
+    * - __u32
+      - ``size``
+      - The total size in bytes of the payload of this control. This is
+	normally 0, but for pointer controls this should be set to the
+	size of the memory containing the payload, or that will receive
+	the payload. If :ref:`VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` finds that this value is
+	less than is required to store the payload result, then it is set
+	to a value large enough to store the payload result and ``ENOSPC`` is
+	returned.
+
+	.. note::
+
+	   For string controls, this ``size`` field should
+	   not be confused with the length of the string. This field refers
+	   to the size of the memory that contains the string. The actual
+	   *length* of the string may well be much smaller.
+    * - __u32
+      - ``reserved2``\ [1]
+      - Reserved for future extensions. Drivers and applications must set
+	the array to zero.
+    * - union {
+      - (anonymous)
+    * - __s32
+      - ``value``
+      - New value or current value. Valid if this control is not of type
+	``V4L2_CTRL_TYPE_INTEGER64`` and ``V4L2_CTRL_FLAG_HAS_PAYLOAD`` is
+	not set.
+    * - __s64
+      - ``value64``
+      - New value or current value. Valid if this control is of type
+	``V4L2_CTRL_TYPE_INTEGER64`` and ``V4L2_CTRL_FLAG_HAS_PAYLOAD`` is
+	not set.
+    * - char *
+      - ``string``
+      - A pointer to a string. Valid if this control is of type
+	``V4L2_CTRL_TYPE_STRING``.
+    * - __u8 *
+      - ``p_u8``
+      - A pointer to a matrix control of unsigned 8-bit values. Valid if
+	this control is of type ``V4L2_CTRL_TYPE_U8``.
+    * - __u16 *
+      - ``p_u16``
+      - A pointer to a matrix control of unsigned 16-bit values. Valid if
+	this control is of type ``V4L2_CTRL_TYPE_U16``.
+    * - __u32 *
+      - ``p_u32``
+      - A pointer to a matrix control of unsigned 32-bit values. Valid if
+	this control is of type ``V4L2_CTRL_TYPE_U32``.
+    * - :c:type:`v4l2_area` *
+      - ``p_area``
+      - A pointer to a struct :c:type:`v4l2_area`. Valid if this control is
+        of type ``V4L2_CTRL_TYPE_AREA``.
+    * - void *
+      - ``ptr``
+      - A pointer to a compound type which can be an N-dimensional array
+	and/or a compound type (the control's type is >=
+	``V4L2_CTRL_COMPOUND_TYPES``). Valid if
+	``V4L2_CTRL_FLAG_HAS_PAYLOAD`` is set for this control.
+    * - }
+      -
+
+
+.. tabularcolumns:: |p{4.0cm}|p{2.2cm}|p{2.1cm}|p{8.2cm}|
+
+.. c:type:: v4l2_ext_controls
+
+.. cssclass:: longtable
+
+.. flat-table:: struct v4l2_ext_controls
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - union {
+      - (anonymous)
+    * - __u32
+      - ``ctrl_class``
+      - The control class to which all controls belong, see
+	:ref:`ctrl-class`. Drivers that use a kernel framework for
+	handling controls will also accept a value of 0 here, meaning that
+	the controls can belong to any control class. Whether drivers
+	support this can be tested by setting ``ctrl_class`` to 0 and
+	calling :ref:`VIDIOC_TRY_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` with a ``count`` of 0. If that
+	succeeds, then the driver supports this feature.
+    * - __u32
+      - ``which``
+      - Which value of the control to get/set/try.
+	``V4L2_CTRL_WHICH_CUR_VAL`` will return the current value of the
+	control, ``V4L2_CTRL_WHICH_DEF_VAL`` will return the default
+	value of the control and ``V4L2_CTRL_WHICH_REQUEST_VAL`` indicates that
+	these controls have to be retrieved from a request or tried/set for
+	a request. In the latter case the ``request_fd`` field contains the
+	file descriptor of the request that should be used. If the device
+	does not support requests, then ``EACCES`` will be returned.
+
+	.. note::
+
+	   When using ``V4L2_CTRL_WHICH_DEF_VAL`` be aware that you can only
+	   get the default value of the control, you cannot set or try it.
+
+	For backwards compatibility you can also use a control class here
+	(see :ref:`ctrl-class`). In that case all controls have to
+	belong to that control class. This usage is deprecated, instead
+	just use ``V4L2_CTRL_WHICH_CUR_VAL``. There are some very old
+	drivers that do not yet support ``V4L2_CTRL_WHICH_CUR_VAL`` and
+	that require a control class here. You can test for such drivers
+	by setting ctrl_class to ``V4L2_CTRL_WHICH_CUR_VAL`` and calling
+	VIDIOC_TRY_EXT_CTRLS with a count of 0. If that fails, then the
+	driver does not support ``V4L2_CTRL_WHICH_CUR_VAL``.
+    * - }
+      -
+    * - __u32
+      - ``count``
+      - The number of controls in the controls array. May also be zero.
+    * - __u32
+      - ``error_idx``
+      - Set by the driver in case of an error. If the error is associated
+	with a particular control, then ``error_idx`` is set to the index
+	of that control. If the error is not related to a specific
+	control, or the validation step failed (see below), then
+	``error_idx`` is set to ``count``. The value is undefined if the
+	ioctl returned 0 (success).
+
+	Before controls are read from/written to hardware a validation
+	step takes place: this checks if all controls in the list are
+	valid controls, if no attempt is made to write to a read-only
+	control or read from a write-only control, and any other up-front
+	checks that can be done without accessing the hardware. The exact
+	validations done during this step are driver dependent since some
+	checks might require hardware access for some devices, thus making
+	it impossible to do those checks up-front. However, drivers should
+	make a best-effort to do as many up-front checks as possible.
+
+	This check is done to avoid leaving the hardware in an
+	inconsistent state due to easy-to-avoid problems. But it leads to
+	another problem: the application needs to know whether an error
+	came from the validation step (meaning that the hardware was not
+	touched) or from an error during the actual reading from/writing
+	to hardware.
+
+	The, in hindsight quite poor, solution for that is to set
+	``error_idx`` to ``count`` if the validation failed. This has the
+	unfortunate side-effect that it is not possible to see which
+	control failed the validation. If the validation was successful
+	and the error happened while accessing the hardware, then
+	``error_idx`` is less than ``count`` and only the controls up to
+	``error_idx-1`` were read or written correctly, and the state of
+	the remaining controls is undefined.
+
+	Since :ref:`VIDIOC_TRY_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` does not access hardware there is
+	also no need to handle the validation step in this special way, so
+	``error_idx`` will just be set to the control that failed the
+	validation step instead of to ``count``. This means that if
+	:ref:`VIDIOC_S_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` fails with ``error_idx`` set to ``count``,
+	then you can call :ref:`VIDIOC_TRY_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` to try to discover the
+	actual control that failed the validation step. Unfortunately,
+	there is no ``TRY`` equivalent for :ref:`VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>`.
+    * - __s32
+      - ``request_fd``
+      - File descriptor of the request to be used by this operation. Only
+	valid if ``which`` is set to ``V4L2_CTRL_WHICH_REQUEST_VAL``.
+	If the device does not support requests, then ``EACCES`` will be returned.
+	If requests are supported but an invalid request file descriptor is
+	given, then ``EINVAL`` will be returned.
+    * - __u32
+      - ``reserved``\ [1]
+      - Reserved for future extensions.
+
+	Drivers and applications must set the array to zero.
+    * - struct :c:type:`v4l2_ext_control` *
+      - ``controls``
+      - Pointer to an array of ``count`` v4l2_ext_control structures.
+
+	Ignored if ``count`` equals zero.
+
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. _ctrl-class:
+
+.. flat-table:: Control classes
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_CTRL_CLASS_USER``
+      - 0x980000
+      - The class containing user controls. These controls are described
+	in :ref:`control`. All controls that can be set using the
+	:ref:`VIDIOC_S_CTRL <VIDIOC_G_CTRL>` and
+	:ref:`VIDIOC_G_CTRL <VIDIOC_G_CTRL>` ioctl belong to this
+	class.
+    * - ``V4L2_CTRL_CLASS_MPEG``
+      - 0x990000
+      - The class containing MPEG compression controls. These controls are
+	described in :ref:`mpeg-controls`.
+    * - ``V4L2_CTRL_CLASS_CAMERA``
+      - 0x9a0000
+      - The class containing camera controls. These controls are described
+	in :ref:`camera-controls`.
+    * - ``V4L2_CTRL_CLASS_FM_TX``
+      - 0x9b0000
+      - The class containing FM Transmitter (FM TX) controls. These
+	controls are described in :ref:`fm-tx-controls`.
+    * - ``V4L2_CTRL_CLASS_FLASH``
+      - 0x9c0000
+      - The class containing flash device controls. These controls are
+	described in :ref:`flash-controls`.
+    * - ``V4L2_CTRL_CLASS_JPEG``
+      - 0x9d0000
+      - The class containing JPEG compression controls. These controls are
+	described in :ref:`jpeg-controls`.
+    * - ``V4L2_CTRL_CLASS_IMAGE_SOURCE``
+      - 0x9e0000
+      - The class containing image source controls. These controls are
+	described in :ref:`image-source-controls`.
+    * - ``V4L2_CTRL_CLASS_IMAGE_PROC``
+      - 0x9f0000
+      - The class containing image processing controls. These controls are
+	described in :ref:`image-process-controls`.
+    * - ``V4L2_CTRL_CLASS_FM_RX``
+      - 0xa10000
+      - The class containing FM Receiver (FM RX) controls. These controls
+	are described in :ref:`fm-rx-controls`.
+    * - ``V4L2_CTRL_CLASS_RF_TUNER``
+      - 0xa20000
+      - The class containing RF tuner controls. These controls are
+	described in :ref:`rf-tuner-controls`.
+
+
+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
+    The struct :c:type:`v4l2_ext_control` ``id`` is
+    invalid, or the struct :c:type:`v4l2_ext_controls`
+    ``which`` is invalid, or the struct
+    :c:type:`v4l2_ext_control` ``value`` was
+    inappropriate (e.g. the given menu index is not supported by the
+    driver), or the ``which`` field was set to ``V4L2_CTRL_WHICH_REQUEST_VAL``
+    but the given ``request_fd`` was invalid or ``V4L2_CTRL_WHICH_REQUEST_VAL``
+    is not supported by the kernel.
+    This error code is also returned by the
+    :ref:`VIDIOC_S_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` and :ref:`VIDIOC_TRY_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` ioctls if two or
+    more control values are in conflict.
+
+ERANGE
+    The struct :c:type:`v4l2_ext_control` ``value``
+    is out of bounds.
+
+EBUSY
+    The control is temporarily not changeable, possibly because another
+    applications took over control of the device function this control
+    belongs to, or (if the ``which`` field was set to
+    ``V4L2_CTRL_WHICH_REQUEST_VAL``) the request was queued but not yet
+    completed.
+
+ENOSPC
+    The space reserved for the control's payload is insufficient. The
+    field ``size`` is set to a value that is enough to store the payload
+    and this error code is returned.
+
+EACCES
+    Attempt to try or set a read-only control, or to get a write-only
+    control, or to get a control from a request that has not yet been
+    completed.
+
+    Or the ``which`` field was set to ``V4L2_CTRL_WHICH_REQUEST_VAL`` but the
+    device does not support requests.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-g-fbuf.rst b/Documentation/userspace-api/media/v4l/vidioc-g-fbuf.rst
new file mode 100644
index 000000000000..0124444419ae
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-g-fbuf.rst
@@ -0,0 +1,362 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_G_FBUF:
+
+**********************************
+ioctl VIDIOC_G_FBUF, VIDIOC_S_FBUF
+**********************************
+
+Name
+====
+
+VIDIOC_G_FBUF - VIDIOC_S_FBUF - Get or set frame buffer overlay parameters
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_G_FBUF, struct v4l2_framebuffer *argp )
+    :name: VIDIOC_G_FBUF
+
+.. c:function:: int ioctl( int fd, VIDIOC_S_FBUF, const struct v4l2_framebuffer *argp )
+    :name: VIDIOC_S_FBUF
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_framebuffer`.
+
+
+Description
+===========
+
+Applications can use the :ref:`VIDIOC_G_FBUF <VIDIOC_G_FBUF>` and :ref:`VIDIOC_S_FBUF <VIDIOC_G_FBUF>` ioctl
+to get and set the framebuffer parameters for a
+:ref:`Video Overlay <overlay>` or :ref:`Video Output Overlay <osd>`
+(OSD). The type of overlay is implied by the device type (capture or
+output device) and can be determined with the
+:ref:`VIDIOC_QUERYCAP` ioctl. One ``/dev/videoN``
+device must not support both kinds of overlay.
+
+The V4L2 API distinguishes destructive and non-destructive overlays. A
+destructive overlay copies captured video images into the video memory
+of a graphics card. A non-destructive overlay blends video images into a
+VGA signal or graphics into a video signal. *Video Output Overlays* are
+always non-destructive.
+
+To get the current parameters applications call the :ref:`VIDIOC_G_FBUF <VIDIOC_G_FBUF>`
+ioctl with a pointer to a struct :c:type:`v4l2_framebuffer`
+structure. The driver fills all fields of the structure or returns an
+EINVAL error code when overlays are not supported.
+
+To set the parameters for a *Video Output Overlay*, applications must
+initialize the ``flags`` field of a struct
+:c:type:`v4l2_framebuffer`. Since the framebuffer is
+implemented on the TV card all other parameters are determined by the
+driver. When an application calls :ref:`VIDIOC_S_FBUF <VIDIOC_G_FBUF>` with a pointer to
+this structure, the driver prepares for the overlay and returns the
+framebuffer parameters as :ref:`VIDIOC_G_FBUF <VIDIOC_G_FBUF>` does, or it returns an error
+code.
+
+To set the parameters for a *non-destructive Video Overlay*,
+applications must initialize the ``flags`` field, the ``fmt``
+substructure, and call :ref:`VIDIOC_S_FBUF <VIDIOC_G_FBUF>`. Again the driver prepares for
+the overlay and returns the framebuffer parameters as :ref:`VIDIOC_G_FBUF <VIDIOC_G_FBUF>`
+does, or it returns an error code.
+
+For a *destructive Video Overlay* applications must additionally provide
+a ``base`` address. Setting up a DMA to a random memory location can
+jeopardize the system security, its stability or even damage the
+hardware, therefore only the superuser can set the parameters for a
+destructive video overlay.
+
+
+.. tabularcolumns:: |p{3.5cm}|p{3.5cm}|p{3.5cm}|p{7.0cm}|
+
+.. c:type:: v4l2_framebuffer
+
+.. cssclass:: longtable
+
+.. flat-table:: struct v4l2_framebuffer
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 1 2
+
+    * - __u32
+      - ``capability``
+      -
+      - Overlay capability flags set by the driver, see
+	:ref:`framebuffer-cap`.
+    * - __u32
+      - ``flags``
+      -
+      - Overlay control flags set by application and driver, see
+	:ref:`framebuffer-flags`
+    * - void *
+      - ``base``
+      -
+      - Physical base address of the framebuffer, that is the address of
+	the pixel in the top left corner of the framebuffer. [#f1]_
+    * -
+      -
+      -
+      - This field is irrelevant to *non-destructive Video Overlays*. For
+	*destructive Video Overlays* applications must provide a base
+	address. The driver may accept only base addresses which are a
+	multiple of two, four or eight bytes. For *Video Output Overlays*
+	the driver must return a valid base address, so applications can
+	find the corresponding Linux framebuffer device (see
+	:ref:`osd`).
+    * - struct
+      - ``fmt``
+      -
+      - Layout of the frame buffer.
+    * -
+      - __u32
+      - ``width``
+      - Width of the frame buffer in pixels.
+    * -
+      - __u32
+      - ``height``
+      - Height of the frame buffer in pixels.
+    * -
+      - __u32
+      - ``pixelformat``
+      - The pixel format of the framebuffer.
+    * -
+      -
+      -
+      - For *non-destructive Video Overlays* this field only defines a
+	format for the struct :c:type:`v4l2_window`
+	``chromakey`` field.
+    * -
+      -
+      -
+      - For *destructive Video Overlays* applications must initialize this
+	field. For *Video Output Overlays* the driver must return a valid
+	format.
+    * -
+      -
+      -
+      - Usually this is an RGB format (for example
+	:ref:`V4L2_PIX_FMT_RGB565 <V4L2-PIX-FMT-RGB565>`) but YUV
+	formats (only packed YUV formats when chroma keying is used, not
+	including ``V4L2_PIX_FMT_YUYV`` and ``V4L2_PIX_FMT_UYVY``) and the
+	``V4L2_PIX_FMT_PAL8`` format are also permitted. The behavior of
+	the driver when an application requests a compressed format is
+	undefined. See :ref:`pixfmt` for information on pixel formats.
+    * -
+      - enum :c:type:`v4l2_field`
+      - ``field``
+      - Drivers and applications shall ignore this field. If applicable,
+	the field order is selected with the
+	:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl, using the ``field``
+	field of struct :c:type:`v4l2_window`.
+    * -
+      - __u32
+      - ``bytesperline``
+      - Distance in bytes between the leftmost pixels in two adjacent
+	lines.
+    * - :cspan:`3`
+
+	This field is irrelevant to *non-destructive Video Overlays*.
+
+	For *destructive Video Overlays* both applications and drivers can
+	set this field to request padding bytes at the end of each line.
+	Drivers however may ignore the requested value, returning
+	``width`` times bytes-per-pixel or a larger value required by the
+	hardware. That implies applications can just set this field to
+	zero to get a reasonable default.
+
+	For *Video Output Overlays* the driver must return a valid value.
+
+	Video hardware may access padding bytes, therefore they must
+	reside in accessible memory. Consider for example the case where
+	padding bytes after the last line of an image cross a system page
+	boundary. Capture devices may write padding bytes, the value is
+	undefined. Output devices ignore the contents of padding bytes.
+
+	When the image format is planar the ``bytesperline`` value applies
+	to the first plane and is divided by the same factor as the
+	``width`` field for the other planes. For example the Cb and Cr
+	planes of a YUV 4:2:0 image have half as many padding bytes
+	following each line as the Y plane. To avoid ambiguities drivers
+	must return a ``bytesperline`` value rounded up to a multiple of
+	the scale factor.
+    * -
+      - __u32
+      - ``sizeimage``
+      - This field is irrelevant to *non-destructive Video Overlays*. For
+	*destructive Video Overlays* applications must initialize this
+	field. For *Video Output Overlays* the driver must return a valid
+	format.
+
+	Together with ``base`` it defines the framebuffer memory
+	accessible by the driver.
+    * -
+      - enum :c:type:`v4l2_colorspace`
+      - ``colorspace``
+      - This information supplements the ``pixelformat`` and must be set
+	by the driver, see :ref:`colorspaces`.
+    * -
+      - __u32
+      - ``priv``
+      - Reserved. Drivers and applications must set this field to zero.
+
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. _framebuffer-cap:
+
+.. flat-table:: Frame Buffer Capability Flags
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_FBUF_CAP_EXTERNOVERLAY``
+      - 0x0001
+      - The device is capable of non-destructive overlays. When the driver
+	clears this flag, only destructive overlays are supported. There
+	are no drivers yet which support both destructive and
+	non-destructive overlays. Video Output Overlays are in practice
+	always non-destructive.
+    * - ``V4L2_FBUF_CAP_CHROMAKEY``
+      - 0x0002
+      - The device supports clipping by chroma-keying the images. That is,
+	image pixels replace pixels in the VGA or video signal only where
+	the latter assume a certain color. Chroma-keying makes no sense
+	for destructive overlays.
+    * - ``V4L2_FBUF_CAP_LIST_CLIPPING``
+      - 0x0004
+      - The device supports clipping using a list of clip rectangles.
+    * - ``V4L2_FBUF_CAP_BITMAP_CLIPPING``
+      - 0x0008
+      - The device supports clipping using a bit mask.
+    * - ``V4L2_FBUF_CAP_LOCAL_ALPHA``
+      - 0x0010
+      - The device supports clipping/blending using the alpha channel of
+	the framebuffer or VGA signal. Alpha blending makes no sense for
+	destructive overlays.
+    * - ``V4L2_FBUF_CAP_GLOBAL_ALPHA``
+      - 0x0020
+      - The device supports alpha blending using a global alpha value.
+	Alpha blending makes no sense for destructive overlays.
+    * - ``V4L2_FBUF_CAP_LOCAL_INV_ALPHA``
+      - 0x0040
+      - The device supports clipping/blending using the inverted alpha
+	channel of the framebuffer or VGA signal. Alpha blending makes no
+	sense for destructive overlays.
+    * - ``V4L2_FBUF_CAP_SRC_CHROMAKEY``
+      - 0x0080
+      - The device supports Source Chroma-keying. Video pixels with the
+	chroma-key colors are replaced by framebuffer pixels, which is
+	exactly opposite of ``V4L2_FBUF_CAP_CHROMAKEY``
+
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. _framebuffer-flags:
+
+.. cssclass:: longtable
+
+.. flat-table:: Frame Buffer Flags
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_FBUF_FLAG_PRIMARY``
+      - 0x0001
+      - The framebuffer is the primary graphics surface. In other words,
+	the overlay is destructive. This flag is typically set by any
+	driver that doesn't have the ``V4L2_FBUF_CAP_EXTERNOVERLAY``
+	capability and it is cleared otherwise.
+    * - ``V4L2_FBUF_FLAG_OVERLAY``
+      - 0x0002
+      - If this flag is set for a video capture device, then the driver
+	will set the initial overlay size to cover the full framebuffer
+	size, otherwise the existing overlay size (as set by
+	:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`) will be used. Only one
+	video capture driver (bttv) supports this flag. The use of this
+	flag for capture devices is deprecated. There is no way to detect
+	which drivers support this flag, so the only reliable method of
+	setting the overlay size is through
+	:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`. If this flag is set for a
+	video output device, then the video output overlay window is
+	relative to the top-left corner of the framebuffer and restricted
+	to the size of the framebuffer. If it is cleared, then the video
+	output overlay window is relative to the video output display.
+    * - ``V4L2_FBUF_FLAG_CHROMAKEY``
+      - 0x0004
+      - Use chroma-keying. The chroma-key color is determined by the
+	``chromakey`` field of struct :c:type:`v4l2_window`
+	and negotiated with the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`
+	ioctl, see :ref:`overlay` and :ref:`osd`.
+    * - :cspan:`2` There are no flags to enable clipping using a list of
+	clip rectangles or a bitmap. These methods are negotiated with the
+	:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl, see :ref:`overlay`
+	and :ref:`osd`.
+    * - ``V4L2_FBUF_FLAG_LOCAL_ALPHA``
+      - 0x0008
+      - Use the alpha channel of the framebuffer to clip or blend
+	framebuffer pixels with video images. The blend function is:
+	output = framebuffer pixel * alpha + video pixel * (1 - alpha).
+	The actual alpha depth depends on the framebuffer pixel format.
+    * - ``V4L2_FBUF_FLAG_GLOBAL_ALPHA``
+      - 0x0010
+      - Use a global alpha value to blend the framebuffer with video
+	images. The blend function is: output = (framebuffer pixel * alpha
+	+ video pixel * (255 - alpha)) / 255. The alpha value is
+	determined by the ``global_alpha`` field of struct
+	:c:type:`v4l2_window` and negotiated with the
+	:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl, see :ref:`overlay`
+	and :ref:`osd`.
+    * - ``V4L2_FBUF_FLAG_LOCAL_INV_ALPHA``
+      - 0x0020
+      - Like ``V4L2_FBUF_FLAG_LOCAL_ALPHA``, use the alpha channel of the
+	framebuffer to clip or blend framebuffer pixels with video images,
+	but with an inverted alpha value. The blend function is: output =
+	framebuffer pixel * (1 - alpha) + video pixel * alpha. The actual
+	alpha depth depends on the framebuffer pixel format.
+    * - ``V4L2_FBUF_FLAG_SRC_CHROMAKEY``
+      - 0x0040
+      - Use source chroma-keying. The source chroma-key color is
+	determined by the ``chromakey`` field of struct
+	:c:type:`v4l2_window` and negotiated with the
+	:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl, see :ref:`overlay`
+	and :ref:`osd`. Both chroma-keying are mutual exclusive to each
+	other, so same ``chromakey`` field of struct
+	:c:type:`v4l2_window` is being used.
+
+
+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.
+
+EPERM
+    :ref:`VIDIOC_S_FBUF <VIDIOC_G_FBUF>` can only be called by a privileged user to
+    negotiate the parameters for a destructive overlay.
+
+EINVAL
+    The :ref:`VIDIOC_S_FBUF <VIDIOC_G_FBUF>` parameters are unsuitable.
+
+.. [#f1]
+   A physical base address may not suit all platforms. GK notes in
+   theory we should pass something like PCI device + memory region +
+   offset instead. If you encounter problems please discuss on the
+   linux-media mailing list:
+   `https://linuxtv.org/lists.php <https://linuxtv.org/lists.php>`__.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-g-fmt.rst b/Documentation/userspace-api/media/v4l/vidioc-g-fmt.rst
new file mode 100644
index 000000000000..88bb69ec07e2
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-g-fmt.rst
@@ -0,0 +1,161 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_G_FMT:
+
+************************************************
+ioctl VIDIOC_G_FMT, VIDIOC_S_FMT, VIDIOC_TRY_FMT
+************************************************
+
+Name
+====
+
+VIDIOC_G_FMT - VIDIOC_S_FMT - VIDIOC_TRY_FMT - Get or set the data format, try a format
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_G_FMT, struct v4l2_format *argp )
+    :name: VIDIOC_G_FMT
+
+.. c:function:: int ioctl( int fd, VIDIOC_S_FMT, struct v4l2_format *argp )
+    :name: VIDIOC_S_FMT
+
+.. c:function:: int ioctl( int fd, VIDIOC_TRY_FMT, struct v4l2_format *argp )
+    :name: VIDIOC_TRY_FMT
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_format`.
+
+
+Description
+===========
+
+These ioctls are used to negotiate the format of data (typically image
+format) exchanged between driver and application.
+
+To query the current parameters applications set the ``type`` field of a
+struct :c:type:`v4l2_format` to the respective buffer (stream)
+type. For example video capture devices use
+``V4L2_BUF_TYPE_VIDEO_CAPTURE`` or
+``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE``. When the application calls the
+:ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` ioctl with a pointer to this structure the driver fills
+the respective member of the ``fmt`` union. In case of video capture
+devices that is either the struct
+:c:type:`v4l2_pix_format` ``pix`` or the struct
+:c:type:`v4l2_pix_format_mplane` ``pix_mp``
+member. When the requested buffer type is not supported drivers return
+an ``EINVAL`` error code.
+
+To change the current format parameters applications initialize the
+``type`` field and all fields of the respective ``fmt`` union member.
+For details see the documentation of the various devices types in
+:ref:`devices`. Good practice is to query the current parameters
+first, and to modify only those parameters not suitable for the
+application. When the application calls the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl with
+a pointer to a struct :c:type:`v4l2_format` structure the driver
+checks and adjusts the parameters against hardware abilities. Drivers
+should not return an error code unless the ``type`` field is invalid,
+this is a mechanism to fathom device capabilities and to approach
+parameters acceptable for both the application and driver. On success
+the driver may program the hardware, allocate resources and generally
+prepare for data exchange. Finally the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl returns
+the current format parameters as :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` does. Very simple,
+inflexible devices may even ignore all input and always return the
+default parameters. However all V4L2 devices exchanging data with the
+application must implement the :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` and :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`
+ioctl. When the requested buffer type is not supported drivers return an
+EINVAL error code on a :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` attempt. When I/O is already in
+progress or the resource is not available for other reasons drivers
+return the ``EBUSY`` error code.
+
+The :ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` ioctl is equivalent to :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` with one
+exception: it does not change driver state. It can also be called at any
+time, never returning ``EBUSY``. This function is provided to negotiate
+parameters, to learn about hardware limitations, without disabling I/O
+or possibly time consuming hardware preparations. Although strongly
+recommended drivers are not required to implement this ioctl.
+
+The format as returned by :ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` must be identical to what
+:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` returns for the same input or output.
+
+
+.. c:type:: v4l2_format
+
+.. tabularcolumns::  |p{1.2cm}|p{4.6cm}|p{3.0cm}|p{8.6cm}|
+
+.. flat-table:: struct v4l2_format
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - __u32
+      - ``type``
+      - Type of the data stream, see :c:type:`v4l2_buf_type`.
+    * - union {
+      - ``fmt``
+    * - struct :c:type:`v4l2_pix_format`
+      - ``pix``
+      - Definition of an image format, see :ref:`pixfmt`, used by video
+	capture and output devices.
+    * - struct :c:type:`v4l2_pix_format_mplane`
+      - ``pix_mp``
+      - Definition of an image format, see :ref:`pixfmt`, used by video
+	capture and output devices that support the
+	:ref:`multi-planar version of the API <planar-apis>`.
+    * - struct :c:type:`v4l2_window`
+      - ``win``
+      - Definition of an overlaid image, see :ref:`overlay`, used by
+	video overlay devices.
+    * - struct :c:type:`v4l2_vbi_format`
+      - ``vbi``
+      - Raw VBI capture or output parameters. This is discussed in more
+	detail in :ref:`raw-vbi`. Used by raw VBI capture and output
+	devices.
+    * - struct :c:type:`v4l2_sliced_vbi_format`
+      - ``sliced``
+      - Sliced VBI capture or output parameters. See :ref:`sliced` for
+	details. Used by sliced VBI capture and output devices.
+    * - struct :c:type:`v4l2_sdr_format`
+      - ``sdr``
+      - Definition of a data format, see :ref:`pixfmt`, used by SDR
+	capture and output devices.
+    * - struct :c:type:`v4l2_meta_format`
+      - ``meta``
+      - Definition of a metadata format, see :ref:`meta-formats`, used by
+	metadata capture devices.
+    * - __u8
+      - ``raw_data``\ [200]
+      - Place holder for future extensions.
+    * - }
+      -
+
+
+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
+    The struct :c:type:`v4l2_format` ``type`` field is
+    invalid or the requested buffer type not supported.
+
+EBUSY
+    The device is busy and cannot change the format. This could be
+    because or the device is streaming or buffers are allocated or
+    queued to the driver. Relevant for :ref:`VIDIOC_S_FMT
+    <VIDIOC_G_FMT>` only.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-g-frequency.rst b/Documentation/userspace-api/media/v4l/vidioc-g-frequency.rst
new file mode 100644
index 000000000000..26300e0258a3
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-g-frequency.rst
@@ -0,0 +1,112 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_G_FREQUENCY:
+
+********************************************
+ioctl VIDIOC_G_FREQUENCY, VIDIOC_S_FREQUENCY
+********************************************
+
+Name
+====
+
+VIDIOC_G_FREQUENCY - VIDIOC_S_FREQUENCY - Get or set tuner or modulator radio frequency
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_G_FREQUENCY, struct v4l2_frequency *argp )
+    :name: VIDIOC_G_FREQUENCY
+
+.. c:function:: int ioctl( int fd, VIDIOC_S_FREQUENCY, const struct v4l2_frequency *argp )
+    :name: VIDIOC_S_FREQUENCY
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_frequency`.
+
+
+Description
+===========
+
+To get the current tuner or modulator radio frequency applications set
+the ``tuner`` field of a struct
+:c:type:`v4l2_frequency` to the respective tuner or
+modulator number (only input devices have tuners, only output devices
+have modulators), zero out the ``reserved`` array and call the
+:ref:`VIDIOC_G_FREQUENCY <VIDIOC_G_FREQUENCY>` ioctl with a pointer to this structure. The
+driver stores the current frequency in the ``frequency`` field.
+
+To change the current tuner or modulator radio frequency applications
+initialize the ``tuner``, ``type`` and ``frequency`` fields, and the
+``reserved`` array of a struct :c:type:`v4l2_frequency`
+and call the :ref:`VIDIOC_S_FREQUENCY <VIDIOC_G_FREQUENCY>` ioctl with a pointer to this
+structure. When the requested frequency is not possible the driver
+assumes the closest possible value. However :ref:`VIDIOC_S_FREQUENCY <VIDIOC_G_FREQUENCY>` is a
+write-only ioctl, it does not return the actual new frequency.
+
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. c:type:: v4l2_frequency
+
+.. flat-table:: struct v4l2_frequency
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``tuner``
+      - The tuner or modulator index number. This is the same value as in
+	the struct :c:type:`v4l2_input` ``tuner`` field and
+	the struct :c:type:`v4l2_tuner` ``index`` field, or
+	the struct :c:type:`v4l2_output` ``modulator`` field
+	and the struct :c:type:`v4l2_modulator` ``index``
+	field.
+    * - __u32
+      - ``type``
+      - The tuner type. This is the same value as in the struct
+	:c:type:`v4l2_tuner` ``type`` field. The type must be
+	set to ``V4L2_TUNER_RADIO`` for ``/dev/radioX`` device nodes, and
+	to ``V4L2_TUNER_ANALOG_TV`` for all others. Set this field to
+	``V4L2_TUNER_RADIO`` for modulators (currently only radio
+	modulators are supported). See :c:type:`v4l2_tuner_type`
+    * - __u32
+      - ``frequency``
+      - Tuning frequency in units of 62.5 kHz, or if the struct
+	:c:type:`v4l2_tuner` or struct
+	:c:type:`v4l2_modulator` ``capability`` flag
+	``V4L2_TUNER_CAP_LOW`` is set, in units of 62.5 Hz. A 1 Hz unit is
+	used when the ``capability`` flag ``V4L2_TUNER_CAP_1HZ`` is set.
+    * - __u32
+      - ``reserved``\ [8]
+      - Reserved for future extensions. Drivers and applications must set
+	the array to zero.
+
+
+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
+    The ``tuner`` index is out of bounds or the value in the ``type``
+    field is wrong.
+
+EBUSY
+    A hardware seek is in progress.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-g-input.rst b/Documentation/userspace-api/media/v4l/vidioc-g-input.rst
new file mode 100644
index 000000000000..294e346678c1
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-g-input.rst
@@ -0,0 +1,71 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_G_INPUT:
+
+************************************
+ioctl VIDIOC_G_INPUT, VIDIOC_S_INPUT
+************************************
+
+Name
+====
+
+VIDIOC_G_INPUT - VIDIOC_S_INPUT - Query or select the current video input
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_G_INPUT, int *argp )
+    :name: VIDIOC_G_INPUT
+
+.. c:function:: int ioctl( int fd, VIDIOC_S_INPUT, int *argp )
+    :name: VIDIOC_S_INPUT
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer an integer with input index.
+
+
+Description
+===========
+
+To query the current video input applications call the
+:ref:`VIDIOC_G_INPUT <VIDIOC_G_INPUT>` ioctl with a pointer to an integer where the driver
+stores the number of the input, as in the struct
+:c:type:`v4l2_input` ``index`` field. This ioctl will fail
+only when there are no video inputs, returning ``EINVAL``.
+
+To select a video input applications store the number of the desired
+input in an integer and call the :ref:`VIDIOC_S_INPUT <VIDIOC_G_INPUT>` ioctl with a pointer
+to this integer. Side effects are possible. For example inputs may
+support different video standards, so the driver may implicitly switch
+the current standard. Because of these possible side effects
+applications must select an input before querying or negotiating any
+other parameters.
+
+Information about video inputs is available using the
+:ref:`VIDIOC_ENUMINPUT` ioctl.
+
+
+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
+    The number of the video input is out of bounds.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-g-jpegcomp.rst b/Documentation/userspace-api/media/v4l/vidioc-g-jpegcomp.rst
new file mode 100644
index 000000000000..3b9981dcb8e0
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-g-jpegcomp.rst
@@ -0,0 +1,134 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_G_JPEGCOMP:
+
+******************************************
+ioctl VIDIOC_G_JPEGCOMP, VIDIOC_S_JPEGCOMP
+******************************************
+
+Name
+====
+
+VIDIOC_G_JPEGCOMP - VIDIOC_S_JPEGCOMP
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_G_JPEGCOMP, v4l2_jpegcompression *argp )
+    :name: VIDIOC_G_JPEGCOMP
+
+.. c:function:: int ioctl( int fd, VIDIOC_S_JPEGCOMP, const v4l2_jpegcompression *argp )
+    :name: VIDIOC_S_JPEGCOMP
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_jpegcompression`.
+
+
+Description
+===========
+
+These ioctls are **deprecated**. New drivers and applications should use
+:ref:`JPEG class controls <jpeg-controls>` for image quality and JPEG
+markers control.
+
+[to do]
+
+Ronald Bultje elaborates:
+
+APP is some application-specific information. The application can set it
+itself, and it'll be stored in the JPEG-encoded fields (eg; interlacing
+information for in an AVI or so). COM is the same, but it's comments,
+like 'encoded by me' or so.
+
+jpeg_markers describes whether the huffman tables, quantization tables
+and the restart interval information (all JPEG-specific stuff) should be
+stored in the JPEG-encoded fields. These define how the JPEG field is
+encoded. If you omit them, applications assume you've used standard
+encoding. You usually do want to add them.
+
+
+.. tabularcolumns:: |p{1.2cm}|p{3.0cm}|p{13.3cm}|
+
+.. c:type:: v4l2_jpegcompression
+
+.. flat-table:: struct v4l2_jpegcompression
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - int
+      - ``quality``
+      - Deprecated. If
+	:ref:`V4L2_CID_JPEG_COMPRESSION_QUALITY <jpeg-quality-control>`
+	control is exposed by a driver applications should use it instead
+	and ignore this field.
+    * - int
+      - ``APPn``
+      -
+    * - int
+      - ``APP_len``
+      -
+    * - char
+      - ``APP_data``\ [60]
+      -
+    * - int
+      - ``COM_len``
+      -
+    * - char
+      - ``COM_data``\ [60]
+      -
+    * - __u32
+      - ``jpeg_markers``
+      - See :ref:`jpeg-markers`. Deprecated. If
+	:ref:`V4L2_CID_JPEG_ACTIVE_MARKER <jpeg-active-marker-control>`
+	control is exposed by a driver applications should use it instead
+	and ignore this field.
+
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. _jpeg-markers:
+
+.. flat-table:: JPEG Markers Flags
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_JPEG_MARKER_DHT``
+      - (1<<3)
+      - Define Huffman Tables
+    * - ``V4L2_JPEG_MARKER_DQT``
+      - (1<<4)
+      - Define Quantization Tables
+    * - ``V4L2_JPEG_MARKER_DRI``
+      - (1<<5)
+      - Define Restart Interval
+    * - ``V4L2_JPEG_MARKER_COM``
+      - (1<<6)
+      - Comment segment
+    * - ``V4L2_JPEG_MARKER_APP``
+      - (1<<7)
+      - App segment, driver will always use APP0
+
+
+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/userspace-api/media/v4l/vidioc-g-modulator.rst b/Documentation/userspace-api/media/v4l/vidioc-g-modulator.rst
new file mode 100644
index 000000000000..c2072f6e8756
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-g-modulator.rst
@@ -0,0 +1,202 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_G_MODULATOR:
+
+********************************************
+ioctl VIDIOC_G_MODULATOR, VIDIOC_S_MODULATOR
+********************************************
+
+Name
+====
+
+VIDIOC_G_MODULATOR - VIDIOC_S_MODULATOR - Get or set modulator attributes
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_G_MODULATOR, struct v4l2_modulator *argp )
+    :name: VIDIOC_G_MODULATOR
+
+.. c:function:: int ioctl( int fd, VIDIOC_S_MODULATOR, const struct v4l2_modulator *argp )
+    :name: VIDIOC_S_MODULATOR
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_modulator`.
+
+
+Description
+===========
+
+To query the attributes of a modulator applications initialize the
+``index`` field and zero out the ``reserved`` array of a struct
+:c:type:`v4l2_modulator` and call the
+:ref:`VIDIOC_G_MODULATOR <VIDIOC_G_MODULATOR>` ioctl with a pointer to this structure. Drivers
+fill the rest of the structure or return an ``EINVAL`` error code when the
+index is out of bounds. To enumerate all modulators applications shall
+begin at index zero, incrementing by one until the driver returns
+EINVAL.
+
+Modulators have two writable properties, an audio modulation set and the
+radio frequency. To change the modulated audio subprograms, applications
+initialize the ``index`` and ``txsubchans`` fields and the ``reserved``
+array and call the :ref:`VIDIOC_S_MODULATOR <VIDIOC_G_MODULATOR>` ioctl. Drivers may choose a
+different audio modulation if the request cannot be satisfied. However
+this is a write-only ioctl, it does not return the actual audio
+modulation selected.
+
+:ref:`SDR <sdr>` specific modulator types are ``V4L2_TUNER_SDR`` and
+``V4L2_TUNER_RF``. For SDR devices ``txsubchans`` field must be
+initialized to zero. The term 'modulator' means SDR transmitter in this
+context.
+
+To change the radio frequency the
+:ref:`VIDIOC_S_FREQUENCY <VIDIOC_G_FREQUENCY>` ioctl is available.
+
+
+.. tabularcolumns:: |p{2.9cm}|p{2.9cm}|p{5.8cm}|p{2.9cm}|p{3.0cm}|
+
+.. c:type:: v4l2_modulator
+
+.. flat-table:: struct v4l2_modulator
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2 1 1
+
+    * - __u32
+      - ``index``
+      - Identifies the modulator, set by the application.
+    * - __u8
+      - ``name``\ [32]
+      - Name of the modulator, a NUL-terminated ASCII string.
+
+	This information is intended for the user.
+    * - __u32
+      - ``capability``
+      - Modulator capability flags. No flags are defined for this field,
+	the tuner flags in struct :c:type:`v4l2_tuner` are
+	used accordingly. The audio flags indicate the ability to encode
+	audio subprograms. They will *not* change for example with the
+	current video standard.
+    * - __u32
+      - ``rangelow``
+      - The lowest tunable frequency in units of 62.5 KHz, or if the
+	``capability`` flag ``V4L2_TUNER_CAP_LOW`` is set, in units of
+	62.5 Hz, or if the ``capability`` flag ``V4L2_TUNER_CAP_1HZ`` is
+	set, in units of 1 Hz.
+    * - __u32
+      - ``rangehigh``
+      - The highest tunable frequency in units of 62.5 KHz, or if the
+	``capability`` flag ``V4L2_TUNER_CAP_LOW`` is set, in units of
+	62.5 Hz, or if the ``capability`` flag ``V4L2_TUNER_CAP_1HZ`` is
+	set, in units of 1 Hz.
+    * - __u32
+      - ``txsubchans``
+      - With this field applications can determine how audio sub-carriers
+	shall be modulated. It contains a set of flags as defined in
+	:ref:`modulator-txsubchans`.
+
+	.. note::
+
+	   The tuner ``rxsubchans`` flags  are reused, but the
+	   semantics are different. Video output devices
+	   are assumed to have an analog or PCM audio input with 1-3
+	   channels. The ``txsubchans`` flags select one or more channels
+	   for modulation, together with some audio subprogram indicator,
+	   for example, a stereo pilot tone.
+    * - __u32
+      - ``type``
+      - :cspan:`2` Type of the modulator, see :c:type:`v4l2_tuner_type`.
+    * - __u32
+      - ``reserved``\ [3]
+      - Reserved for future extensions.
+
+	Drivers and applications must set the array to zero.
+
+
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. _modulator-txsubchans:
+
+.. flat-table:: Modulator Audio Transmission Flags
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_TUNER_SUB_MONO``
+      - 0x0001
+      - Modulate channel 1 as mono audio, when the input has more
+	channels, a down-mix of channel 1 and 2. This flag does not
+	combine with ``V4L2_TUNER_SUB_STEREO`` or
+	``V4L2_TUNER_SUB_LANG1``.
+    * - ``V4L2_TUNER_SUB_STEREO``
+      - 0x0002
+      - Modulate channel 1 and 2 as left and right channel of a stereo
+	audio signal. When the input has only one channel or two channels
+	and ``V4L2_TUNER_SUB_SAP`` is also set, channel 1 is encoded as
+	left and right channel. This flag does not combine with
+	``V4L2_TUNER_SUB_MONO`` or ``V4L2_TUNER_SUB_LANG1``. When the
+	driver does not support stereo audio it shall fall back to mono.
+    * - ``V4L2_TUNER_SUB_LANG1``
+      - 0x0008
+      - Modulate channel 1 and 2 as primary and secondary language of a
+	bilingual audio signal. When the input has only one channel it is
+	used for both languages. It is not possible to encode the primary
+	or secondary language only. This flag does not combine with
+	``V4L2_TUNER_SUB_MONO``, ``V4L2_TUNER_SUB_STEREO`` or
+	``V4L2_TUNER_SUB_SAP``. If the hardware does not support the
+	respective audio matrix, or the current video standard does not
+	permit bilingual audio the :ref:`VIDIOC_S_MODULATOR <VIDIOC_G_MODULATOR>` ioctl shall
+	return an ``EINVAL`` error code and the driver shall fall back to mono
+	or stereo mode.
+    * - ``V4L2_TUNER_SUB_LANG2``
+      - 0x0004
+      - Same effect as ``V4L2_TUNER_SUB_SAP``.
+    * - ``V4L2_TUNER_SUB_SAP``
+      - 0x0004
+      - When combined with ``V4L2_TUNER_SUB_MONO`` the first channel is
+	encoded as mono audio, the last channel as Second Audio Program.
+	When the input has only one channel it is used for both audio
+	tracks. When the input has three channels the mono track is a
+	down-mix of channel 1 and 2. When combined with
+	``V4L2_TUNER_SUB_STEREO`` channel 1 and 2 are encoded as left and
+	right stereo audio, channel 3 as Second Audio Program. When the
+	input has only two channels, the first is encoded as left and
+	right channel and the second as SAP. When the input has only one
+	channel it is used for all audio tracks. It is not possible to
+	encode a Second Audio Program only. This flag must combine with
+	``V4L2_TUNER_SUB_MONO`` or ``V4L2_TUNER_SUB_STEREO``. If the
+	hardware does not support the respective audio matrix, or the
+	current video standard does not permit SAP the
+	:ref:`VIDIOC_S_MODULATOR <VIDIOC_G_MODULATOR>` ioctl shall return an ``EINVAL`` error code and
+	driver shall fall back to mono or stereo mode.
+    * - ``V4L2_TUNER_SUB_RDS``
+      - 0x0010
+      - Enable the RDS encoder for a radio FM transmitter.
+
+
+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
+    The struct :c:type:`v4l2_modulator` ``index`` is
+    out of bounds.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-g-output.rst b/Documentation/userspace-api/media/v4l/vidioc-g-output.rst
new file mode 100644
index 000000000000..cad477420fd7
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-g-output.rst
@@ -0,0 +1,73 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_G_OUTPUT:
+
+**************************************
+ioctl VIDIOC_G_OUTPUT, VIDIOC_S_OUTPUT
+**************************************
+
+Name
+====
+
+VIDIOC_G_OUTPUT - VIDIOC_S_OUTPUT - Query or select the current video output
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_G_OUTPUT, int *argp )
+    :name: VIDIOC_G_OUTPUT
+
+.. c:function:: int ioctl( int fd, VIDIOC_S_OUTPUT, int *argp )
+    :name: VIDIOC_S_OUTPUT
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to an integer with output index.
+
+
+Description
+===========
+
+To query the current video output applications call the
+:ref:`VIDIOC_G_OUTPUT <VIDIOC_G_OUTPUT>` ioctl with a pointer to an integer where the driver
+stores the number of the output, as in the struct
+:c:type:`v4l2_output` ``index`` field. This ioctl will
+fail only when there are no video outputs, returning the ``EINVAL`` error
+code.
+
+To select a video output applications store the number of the desired
+output in an integer and call the :ref:`VIDIOC_S_OUTPUT <VIDIOC_G_OUTPUT>` ioctl with a
+pointer to this integer. Side effects are possible. For example outputs
+may support different video standards, so the driver may implicitly
+switch the current standard. standard. Because of these possible side
+effects applications must select an output before querying or
+negotiating any other parameters.
+
+Information about video outputs is available using the
+:ref:`VIDIOC_ENUMOUTPUT` ioctl.
+
+
+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
+    The number of the video output is out of bounds, or there are no
+    video outputs at all.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-g-parm.rst b/Documentation/userspace-api/media/v4l/vidioc-g-parm.rst
new file mode 100644
index 000000000000..42e9f6ee7a59
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-g-parm.rst
@@ -0,0 +1,270 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_G_PARM:
+
+**********************************
+ioctl VIDIOC_G_PARM, VIDIOC_S_PARM
+**********************************
+
+Name
+====
+
+VIDIOC_G_PARM - VIDIOC_S_PARM - Get or set streaming parameters
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_G_PARM, v4l2_streamparm *argp )
+    :name: VIDIOC_G_PARM
+
+.. c:function:: int ioctl( int fd, VIDIOC_S_PARM, v4l2_streamparm *argp )
+    :name: VIDIOC_S_PARM
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_streamparm`.
+
+
+Description
+===========
+
+The current video standard determines a nominal number of frames per
+second. If less than this number of frames is to be captured or output,
+applications can request frame skipping or duplicating on the driver
+side. This is especially useful when using the :ref:`read() <func-read>` or
+:ref:`write() <func-write>`, which are not augmented by timestamps or sequence
+counters, and to avoid unnecessary data copying.
+
+Changing the frame interval shall never change the format. Changing the
+format, on the other hand, may change the frame interval.
+
+Further these ioctls can be used to determine the number of buffers used
+internally by a driver in read/write mode. For implications see the
+section discussing the :ref:`read() <func-read>` function.
+
+To get and set the streaming parameters applications call the
+:ref:`VIDIOC_G_PARM <VIDIOC_G_PARM>` and :ref:`VIDIOC_S_PARM <VIDIOC_G_PARM>` ioctl, respectively. They take a
+pointer to a struct :c:type:`v4l2_streamparm` which contains a
+union holding separate parameters for input and output devices.
+
+
+.. tabularcolumns:: |p{3.5cm}|p{3.5cm}|p{3.5cm}|p{7.0cm}|
+
+.. c:type:: v4l2_streamparm
+
+.. flat-table:: struct v4l2_streamparm
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``type``
+      - The buffer (stream) type, same as struct
+	:c:type:`v4l2_format` ``type``, set by the
+	application. See :c:type:`v4l2_buf_type`.
+    * - union {
+      - ``parm``
+    * - struct :c:type:`v4l2_captureparm`
+      - ``capture``
+      - Parameters for capture devices, used when ``type`` is
+	``V4L2_BUF_TYPE_VIDEO_CAPTURE`` or
+	``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE``.
+    * - struct :c:type:`v4l2_outputparm`
+      - ``output``
+      - Parameters for output devices, used when ``type`` is
+	``V4L2_BUF_TYPE_VIDEO_OUTPUT`` or ``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE``.
+    * - __u8
+      - ``raw_data``\ [200]
+      - A place holder for future extensions.
+    * - }
+      -
+
+
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. c:type:: v4l2_captureparm
+
+.. flat-table:: struct v4l2_captureparm
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``capability``
+      - See :ref:`parm-caps`.
+    * - __u32
+      - ``capturemode``
+      - Set by drivers and applications, see :ref:`parm-flags`.
+    * - struct :c:type:`v4l2_fract`
+      - ``timeperframe``
+      - This is the desired period between successive frames captured by
+	the driver, in seconds. The field is intended to skip frames on
+	the driver side, saving I/O bandwidth.
+
+	Applications store here the desired frame period, drivers return
+	the actual frame period, which must be greater or equal to the
+	nominal frame period determined by the current video standard
+	(struct :c:type:`v4l2_standard` ``frameperiod``
+	field). Changing the video standard (also implicitly by switching
+	the video input) may reset this parameter to the nominal frame
+	period. To reset manually applications can just set this field to
+	zero.
+
+	Drivers support this function only when they set the
+	``V4L2_CAP_TIMEPERFRAME`` flag in the ``capability`` field.
+    * - __u32
+      - ``extendedmode``
+      - Custom (driver specific) streaming parameters. When unused,
+	applications and drivers must set this field to zero. Applications
+	using this field should check the driver name and version, see
+	:ref:`querycap`.
+    * - __u32
+      - ``readbuffers``
+      - Applications set this field to the desired number of buffers used
+	internally by the driver in :ref:`read() <func-read>` mode.
+	Drivers return the actual number of buffers. When an application
+	requests zero buffers, drivers should just return the current
+	setting rather than the minimum or an error code. For details see
+	:ref:`rw`.
+    * - __u32
+      - ``reserved``\ [4]
+      - Reserved for future extensions. Drivers and applications must set
+	the array to zero.
+
+
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. c:type:: v4l2_outputparm
+
+.. flat-table:: struct v4l2_outputparm
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``capability``
+      - See :ref:`parm-caps`.
+    * - __u32
+      - ``outputmode``
+      - Set by drivers and applications, see :ref:`parm-flags`.
+    * - struct :c:type:`v4l2_fract`
+      - ``timeperframe``
+      - This is the desired period between successive frames output by the
+	driver, in seconds.
+    * - :cspan:`2`
+
+	The field is intended to repeat frames on the driver side in
+	:ref:`write() <func-write>` mode (in streaming mode timestamps
+	can be used to throttle the output), saving I/O bandwidth.
+
+	Applications store here the desired frame period, drivers return
+	the actual frame period, which must be greater or equal to the
+	nominal frame period determined by the current video standard
+	(struct :c:type:`v4l2_standard` ``frameperiod``
+	field). Changing the video standard (also implicitly by switching
+	the video output) may reset this parameter to the nominal frame
+	period. To reset manually applications can just set this field to
+	zero.
+
+	Drivers support this function only when they set the
+	``V4L2_CAP_TIMEPERFRAME`` flag in the ``capability`` field.
+    * - __u32
+      - ``extendedmode``
+      - Custom (driver specific) streaming parameters. When unused,
+	applications and drivers must set this field to zero. Applications
+	using this field should check the driver name and version, see
+	:ref:`querycap`.
+    * - __u32
+      - ``writebuffers``
+      - Applications set this field to the desired number of buffers used
+	internally by the driver in :ref:`write() <func-write>` mode. Drivers
+	return the actual number of buffers. When an application requests
+	zero buffers, drivers should just return the current setting
+	rather than the minimum or an error code. For details see
+	:ref:`rw`.
+    * - __u32
+      - ``reserved``\ [4]
+      - Reserved for future extensions. Drivers and applications must set
+	the array to zero.
+
+
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. _parm-caps:
+
+.. flat-table:: Streaming Parameters Capabilities
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_CAP_TIMEPERFRAME``
+      - 0x1000
+      - The frame skipping/repeating controlled by the ``timeperframe``
+	field is supported.
+
+
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. _parm-flags:
+
+.. flat-table:: Capture Parameters Flags
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_MODE_HIGHQUALITY``
+      - 0x0001
+      - High quality imaging mode. High quality mode is intended for still
+	imaging applications. The idea is to get the best possible image
+	quality that the hardware can deliver. It is not defined how the
+	driver writer may achieve that; it will depend on the hardware and
+	the ingenuity of the driver writer. High quality mode is a
+	different mode from the regular motion video capture modes. In
+	high quality mode:
+
+	-  The driver may be able to capture higher resolutions than for
+	   motion capture.
+
+	-  The driver may support fewer pixel formats than motion capture
+	   (eg; true color).
+
+	-  The driver may capture and arithmetically combine multiple
+	   successive fields or frames to remove color edge artifacts and
+	   reduce the noise in the video data.
+
+	-  The driver may capture images in slices like a scanner in order
+	   to handle larger format images than would otherwise be
+	   possible.
+
+	-  An image capture operation may be significantly slower than
+	   motion capture.
+
+	-  Moving objects in the image might have excessive motion blur.
+
+	-  Capture might only work through the :ref:`read() <func-read>` call.
+
+
+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/userspace-api/media/v4l/vidioc-g-priority.rst b/Documentation/userspace-api/media/v4l/vidioc-g-priority.rst
new file mode 100644
index 000000000000..c8add130c7a4
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-g-priority.rst
@@ -0,0 +1,100 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_G_PRIORITY:
+
+******************************************
+ioctl VIDIOC_G_PRIORITY, VIDIOC_S_PRIORITY
+******************************************
+
+Name
+====
+
+VIDIOC_G_PRIORITY - VIDIOC_S_PRIORITY - Query or request the access priority associated with a file descriptor
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_G_PRIORITY, enum v4l2_priority *argp )
+    :name: VIDIOC_G_PRIORITY
+
+.. c:function:: int ioctl( int fd, VIDIOC_S_PRIORITY, const enum v4l2_priority *argp )
+    :name: VIDIOC_S_PRIORITY
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to an enum :c:type:`v4l2_priority` type.
+
+
+Description
+===========
+
+To query the current access priority applications call the
+:ref:`VIDIOC_G_PRIORITY <VIDIOC_G_PRIORITY>` ioctl with a pointer to an enum v4l2_priority
+variable where the driver stores the current priority.
+
+To request an access priority applications store the desired priority in
+an enum v4l2_priority variable and call :ref:`VIDIOC_S_PRIORITY <VIDIOC_G_PRIORITY>` ioctl
+with a pointer to this variable.
+
+
+.. c:type:: v4l2_priority
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. flat-table:: enum v4l2_priority
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_PRIORITY_UNSET``
+      - 0
+      -
+    * - ``V4L2_PRIORITY_BACKGROUND``
+      - 1
+      - Lowest priority, usually applications running in background, for
+	example monitoring VBI transmissions. A proxy application running
+	in user space will be necessary if multiple applications want to
+	read from a device at this priority.
+    * - ``V4L2_PRIORITY_INTERACTIVE``
+      - 2
+      -
+    * - ``V4L2_PRIORITY_DEFAULT``
+      - 2
+      - Medium priority, usually applications started and interactively
+	controlled by the user. For example TV viewers, Teletext browsers,
+	or just "panel" applications to change the channel or video
+	controls. This is the default priority unless an application
+	requests another.
+    * - ``V4L2_PRIORITY_RECORD``
+      - 3
+      - Highest priority. Only one file descriptor can have this priority,
+	it blocks any other fd from changing device properties. Usually
+	applications which must not be interrupted, like video recording.
+
+
+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
+    The requested priority value is invalid.
+
+EBUSY
+    Another application already requested higher priority.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-g-selection.rst b/Documentation/userspace-api/media/v4l/vidioc-g-selection.rst
new file mode 100644
index 000000000000..faab0454b1e4
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-g-selection.rst
@@ -0,0 +1,200 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_G_SELECTION:
+
+********************************************
+ioctl VIDIOC_G_SELECTION, VIDIOC_S_SELECTION
+********************************************
+
+Name
+====
+
+VIDIOC_G_SELECTION - VIDIOC_S_SELECTION - Get or set one of the selection rectangles
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_G_SELECTION, struct v4l2_selection *argp )
+    :name: VIDIOC_G_SELECTION
+
+
+.. c:function:: int ioctl( int fd, VIDIOC_S_SELECTION, struct v4l2_selection *argp )
+    :name: VIDIOC_S_SELECTION
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_selection`.
+
+Description
+===========
+
+The ioctls are used to query and configure selection rectangles.
+
+To query the cropping (composing) rectangle set struct
+:c:type:`v4l2_selection` ``type`` field to the
+respective buffer type. The next step is setting the
+value of struct :c:type:`v4l2_selection` ``target``
+field to ``V4L2_SEL_TGT_CROP`` (``V4L2_SEL_TGT_COMPOSE``). Please refer
+to table :ref:`v4l2-selections-common` or :ref:`selection-api` for
+additional targets. The ``flags`` and ``reserved`` fields of struct
+:c:type:`v4l2_selection` are ignored and they must be
+filled with zeros. The driver fills the rest of the structure or returns
+EINVAL error code if incorrect buffer type or target was used. If
+cropping (composing) is not supported then the active rectangle is not
+mutable and it is always equal to the bounds rectangle. Finally, the
+struct :c:type:`v4l2_rect` ``r`` rectangle is filled with
+the current cropping (composing) coordinates. The coordinates are
+expressed in driver-dependent units. The only exception are rectangles
+for images in raw formats, whose coordinates are always expressed in
+pixels.
+
+To change the cropping (composing) rectangle set the struct
+:c:type:`v4l2_selection` ``type`` field to the
+respective buffer type. The next step is setting the
+value of struct :c:type:`v4l2_selection` ``target`` to
+``V4L2_SEL_TGT_CROP`` (``V4L2_SEL_TGT_COMPOSE``). Please refer to table
+:ref:`v4l2-selections-common` or :ref:`selection-api` for additional
+targets. The struct :c:type:`v4l2_rect` ``r`` rectangle need
+to be set to the desired active area. Field struct
+:c:type:`v4l2_selection` ``reserved`` is ignored and
+must be filled with zeros. The driver may adjust coordinates of the
+requested rectangle. An application may introduce constraints to control
+rounding behaviour. The struct :c:type:`v4l2_selection`
+``flags`` field must be set to one of the following:
+
+-  ``0`` - The driver can adjust the rectangle size freely and shall
+   choose a crop/compose rectangle as close as possible to the requested
+   one.
+
+-  ``V4L2_SEL_FLAG_GE`` - The driver is not allowed to shrink the
+   rectangle. The original rectangle must lay inside the adjusted one.
+
+-  ``V4L2_SEL_FLAG_LE`` - The driver is not allowed to enlarge the
+   rectangle. The adjusted rectangle must lay inside the original one.
+
+-  ``V4L2_SEL_FLAG_GE | V4L2_SEL_FLAG_LE`` - The driver must choose the
+   size exactly the same as in the requested rectangle.
+
+Please refer to :ref:`sel-const-adjust`.
+
+The driver may have to adjusts the requested dimensions against hardware
+limits and other parts as the pipeline, i.e. the bounds given by the
+capture/output window or TV display. The closest possible values of
+horizontal and vertical offset and sizes are chosen according to
+following priority:
+
+1. Satisfy constraints from struct
+   :c:type:`v4l2_selection` ``flags``.
+
+2. Adjust width, height, left, and top to hardware limits and
+   alignments.
+
+3. Keep center of adjusted rectangle as close as possible to the
+   original one.
+
+4. Keep width and height as close as possible to original ones.
+
+5. Keep horizontal and vertical offset as close as possible to original
+   ones.
+
+On success the struct :c:type:`v4l2_rect` ``r`` field
+contains the adjusted rectangle. When the parameters are unsuitable the
+application may modify the cropping (composing) or image parameters and
+repeat the cycle until satisfactory parameters have been negotiated. If
+constraints flags have to be violated at then ``ERANGE`` is returned. The
+error indicates that *there exist no rectangle* that satisfies the
+constraints.
+
+Selection targets and flags are documented in
+:ref:`v4l2-selections-common`.
+
+
+.. _sel-const-adjust:
+
+.. kernel-figure::  constraints.svg
+    :alt:    constraints.svg
+    :align:  center
+
+    Size adjustments with constraint flags.
+
+    Behaviour of rectangle adjustment for different constraint flags.
+
+
+
+
+.. c:type:: v4l2_selection
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. flat-table:: struct v4l2_selection
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``type``
+      - Type of the buffer (from enum
+	:c:type:`v4l2_buf_type`).
+    * - __u32
+      - ``target``
+      - Used to select between
+	:ref:`cropping and composing rectangles <v4l2-selections-common>`.
+    * - __u32
+      - ``flags``
+      - Flags controlling the selection rectangle adjustments, refer to
+	:ref:`selection flags <v4l2-selection-flags>`.
+    * - struct :c:type:`v4l2_rect`
+      - ``r``
+      - The selection rectangle.
+    * - __u32
+      - ``reserved[9]``
+      - Reserved fields for future use. Drivers and applications must zero
+	this array.
+
+.. note::
+   Unfortunately in the case of multiplanar buffer types
+   (``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE`` and ``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE``)
+   this API was messed up with regards to how the :c:type:`v4l2_selection` ``type`` field
+   should be filled in. Some drivers only accepted the ``_MPLANE`` buffer type while
+   other drivers only accepted a non-multiplanar buffer type (i.e. without the
+   ``_MPLANE`` at the end).
+
+   Starting with kernel 4.13 both variations are allowed.
+
+
+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
+    Given buffer type ``type`` or the selection target ``target`` is not
+    supported, or the ``flags`` argument is not valid.
+
+ERANGE
+    It is not possible to adjust struct :c:type:`v4l2_rect`
+    ``r`` rectangle to satisfy all constraints given in the ``flags``
+    argument.
+
+ENODATA
+    Selection is not supported for this input or output.
+
+EBUSY
+    It is not possible to apply change of the selection rectangle at the
+    moment. Usually because streaming is in progress.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-g-sliced-vbi-cap.rst b/Documentation/userspace-api/media/v4l/vidioc-g-sliced-vbi-cap.rst
new file mode 100644
index 000000000000..7a62c4f4e37f
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-g-sliced-vbi-cap.rst
@@ -0,0 +1,202 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_G_SLICED_VBI_CAP:
+
+*****************************
+ioctl VIDIOC_G_SLICED_VBI_CAP
+*****************************
+
+Name
+====
+
+VIDIOC_G_SLICED_VBI_CAP - Query sliced VBI capabilities
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_G_SLICED_VBI_CAP, struct v4l2_sliced_vbi_cap *argp )
+    :name: VIDIOC_G_SLICED_VBI_CAP
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_sliced_vbi_cap`.
+
+
+Description
+===========
+
+To find out which data services are supported by a sliced VBI capture or
+output device, applications initialize the ``type`` field of a struct
+:c:type:`v4l2_sliced_vbi_cap`, clear the
+``reserved`` array and call the :ref:`VIDIOC_G_SLICED_VBI_CAP <VIDIOC_G_SLICED_VBI_CAP>` ioctl. The
+driver fills in the remaining fields or returns an ``EINVAL`` error code if
+the sliced VBI API is unsupported or ``type`` is invalid.
+
+.. note::
+
+   The ``type`` field was added, and the ioctl changed from read-only
+   to write-read, in Linux 2.6.19.
+
+
+.. c:type:: v4l2_sliced_vbi_cap
+
+.. tabularcolumns:: |p{1.2cm}|p{4.2cm}|p{4.1cm}|p{4.0cm}|p{4.0cm}|
+
+.. flat-table:: struct v4l2_sliced_vbi_cap
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 3 2 2 2
+
+    * - __u16
+      - ``service_set``
+      - :cspan:`2` A set of all data services supported by the driver.
+
+	Equal to the union of all elements of the ``service_lines`` array.
+    * - __u16
+      - ``service_lines``\ [2][24]
+      - :cspan:`2` Each element of this array contains a set of data
+	services the hardware can look for or insert into a particular
+	scan line. Data services are defined in :ref:`vbi-services`.
+	Array indices map to ITU-R line numbers\ [#f1]_ as follows:
+    * -
+      -
+      - Element
+      - 525 line systems
+      - 625 line systems
+    * -
+      -
+      - ``service_lines``\ [0][1]
+      - 1
+      - 1
+    * -
+      -
+      - ``service_lines``\ [0][23]
+      - 23
+      - 23
+    * -
+      -
+      - ``service_lines``\ [1][1]
+      - 264
+      - 314
+    * -
+      -
+      - ``service_lines``\ [1][23]
+      - 286
+      - 336
+    * -
+    * -
+      -
+      - :cspan:`2` The number of VBI lines the hardware can capture or
+	output per frame, or the number of services it can identify on a
+	given line may be limited. For example on PAL line 16 the hardware
+	may be able to look for a VPS or Teletext signal, but not both at
+	the same time. Applications can learn about these limits using the
+	:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl as described in
+	:ref:`sliced`.
+    * -
+    * -
+      -
+      - :cspan:`2` Drivers must set ``service_lines`` [0][0] and
+	``service_lines``\ [1][0] to zero.
+    * - __u32
+      - ``type``
+      - Type of the data stream, see :c:type:`v4l2_buf_type`. Should be
+	``V4L2_BUF_TYPE_SLICED_VBI_CAPTURE`` or
+	``V4L2_BUF_TYPE_SLICED_VBI_OUTPUT``.
+    * - __u32
+      - ``reserved``\ [3]
+      - :cspan:`2` This array is reserved for future extensions.
+
+	Applications and drivers must set it to zero.
+
+.. [#f1]
+
+   See also :ref:`vbi-525` and :ref:`vbi-625`.
+
+
+.. raw:: latex
+
+    \scriptsize
+
+.. tabularcolumns:: |p{3.5cm}|p{1.0cm}|p{2.0cm}|p{2.0cm}|p{8.0cm}|
+
+.. _vbi-services:
+
+.. flat-table:: Sliced VBI services
+    :header-rows:  1
+    :stub-columns: 0
+    :widths:       2 1 1 2 2
+
+    * - Symbol
+      - Value
+      - Reference
+      - Lines, usually
+      - Payload
+    * - ``V4L2_SLICED_TELETEXT_B`` (Teletext System B)
+      - 0x0001
+      - :ref:`ets300706`,
+
+	:ref:`itu653`
+      - PAL/SECAM line 7-22, 320-335 (second field 7-22)
+      - Last 42 of the 45 byte Teletext packet, that is without clock
+	run-in and framing code, lsb first transmitted.
+    * - ``V4L2_SLICED_VPS``
+      - 0x0400
+      - :ref:`ets300231`
+      - PAL line 16
+      - Byte number 3 to 15 according to Figure 9 of ETS 300 231, lsb
+	first transmitted.
+    * - ``V4L2_SLICED_CAPTION_525``
+      - 0x1000
+      - :ref:`cea608`
+      - NTSC line 21, 284 (second field 21)
+      - Two bytes in transmission order, including parity bit, lsb first
+	transmitted.
+    * - ``V4L2_SLICED_WSS_625``
+      - 0x4000
+      - :ref:`en300294`,
+
+	:ref:`itu1119`
+      - PAL/SECAM line 23
+      -
+
+	::
+
+	    Byte        0                 1
+		 msb         lsb  msb           lsb
+	    Bit  7 6 5 4 3 2 1 0  x x 13 12 11 10 9
+    * - ``V4L2_SLICED_VBI_525``
+      - 0x1000
+      - :cspan:`2` Set of services applicable to 525 line systems.
+    * - ``V4L2_SLICED_VBI_625``
+      - 0x4401
+      - :cspan:`2` Set of services applicable to 625 line systems.
+
+.. raw:: latex
+
+    \normalsize
+
+
+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
+    The value in the ``type`` field is wrong.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-g-std.rst b/Documentation/userspace-api/media/v4l/vidioc-g-std.rst
new file mode 100644
index 000000000000..b0bdb719d405
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-g-std.rst
@@ -0,0 +1,81 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_G_STD:
+
+**************************************************************************
+ioctl VIDIOC_G_STD, VIDIOC_S_STD, VIDIOC_SUBDEV_G_STD, VIDIOC_SUBDEV_S_STD
+**************************************************************************
+
+Name
+====
+
+VIDIOC_G_STD - VIDIOC_S_STD - VIDIOC_SUBDEV_G_STD - VIDIOC_SUBDEV_S_STD - Query or select the video standard of the current input
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_G_STD, v4l2_std_id *argp )
+    :name: VIDIOC_G_STD
+
+.. c:function:: int ioctl( int fd, VIDIOC_S_STD, const v4l2_std_id *argp )
+    :name: VIDIOC_S_STD
+
+.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_G_STD, v4l2_std_id *argp )
+    :name: VIDIOC_SUBDEV_G_STD
+
+.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_S_STD, const v4l2_std_id *argp )
+    :name: VIDIOC_SUBDEV_S_STD
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to :c:type:`v4l2_std_id`.
+
+
+Description
+===========
+
+To query and select the current video standard applications use the
+:ref:`VIDIOC_G_STD <VIDIOC_G_STD>` and :ref:`VIDIOC_S_STD <VIDIOC_G_STD>` ioctls which take a pointer to a
+:ref:`v4l2_std_id <v4l2-std-id>` type as argument. :ref:`VIDIOC_G_STD <VIDIOC_G_STD>`
+can return a single flag or a set of flags as in struct
+:c:type:`v4l2_standard` field ``id``. The flags must be
+unambiguous such that they appear in only one enumerated
+struct :c:type:`v4l2_standard` structure.
+
+:ref:`VIDIOC_S_STD <VIDIOC_G_STD>` accepts one or more flags, being a write-only ioctl it
+does not return the actual new standard as :ref:`VIDIOC_G_STD <VIDIOC_G_STD>` does. When
+no flags are given or the current input does not support the requested
+standard the driver returns an ``EINVAL`` error code. When the standard set
+is ambiguous drivers may return ``EINVAL`` or choose any of the requested
+standards. If the current input or output does not support standard
+video timings (e.g. if :ref:`VIDIOC_ENUMINPUT`
+does not set the ``V4L2_IN_CAP_STD`` flag), then ``ENODATA`` error code is
+returned.
+
+
+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
+    The :ref:`VIDIOC_S_STD <VIDIOC_G_STD>` parameter was unsuitable.
+
+ENODATA
+    Standard video timings are not supported for this input or output.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-g-tuner.rst b/Documentation/userspace-api/media/v4l/vidioc-g-tuner.rst
new file mode 100644
index 000000000000..40bff6f0a88d
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-g-tuner.rst
@@ -0,0 +1,476 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_G_TUNER:
+
+************************************
+ioctl VIDIOC_G_TUNER, VIDIOC_S_TUNER
+************************************
+
+Name
+====
+
+VIDIOC_G_TUNER - VIDIOC_S_TUNER - Get or set tuner attributes
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_G_TUNER, struct v4l2_tuner *argp )
+    :name: VIDIOC_G_TUNER
+
+.. c:function:: int ioctl( int fd, VIDIOC_S_TUNER, const struct v4l2_tuner *argp )
+    :name: VIDIOC_S_TUNER
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_tuner`.
+
+
+Description
+===========
+
+To query the attributes of a tuner applications initialize the ``index``
+field and zero out the ``reserved`` array of a struct
+:c:type:`v4l2_tuner` and call the ``VIDIOC_G_TUNER`` ioctl
+with a pointer to this structure. Drivers fill the rest of the structure
+or return an ``EINVAL`` error code when the index is out of bounds. To
+enumerate all tuners applications shall begin at index zero,
+incrementing by one until the driver returns ``EINVAL``.
+
+Tuners have two writable properties, the audio mode and the radio
+frequency. To change the audio mode, applications initialize the
+``index``, ``audmode`` and ``reserved`` fields and call the
+``VIDIOC_S_TUNER`` ioctl. This will *not* change the current tuner,
+which is determined by the current video input. Drivers may choose a
+different audio mode if the requested mode is invalid or unsupported.
+Since this is a write-only ioctl, it does not return the actually
+selected audio mode.
+
+:ref:`SDR <sdr>` specific tuner types are ``V4L2_TUNER_SDR`` and
+``V4L2_TUNER_RF``. For SDR devices ``audmode`` field must be initialized
+to zero. The term 'tuner' means SDR receiver in this context.
+
+To change the radio frequency the
+:ref:`VIDIOC_S_FREQUENCY <VIDIOC_G_FREQUENCY>` ioctl is available.
+
+
+ .. tabularcolumns:: |p{1.3cm}|p{3.0cm}|p{6.6cm}|p{6.6cm}|
+
+.. c:type:: v4l2_tuner
+
+.. cssclass:: longtable
+
+.. flat-table:: struct v4l2_tuner
+    :header-rows:  0
+    :stub-columns: 0
+
+    * - __u32
+      - ``index``
+      - :cspan:`1` Identifies the tuner, set by the application.
+    * - __u8
+      - ``name``\ [32]
+      - :cspan:`1`
+
+	Name of the tuner, a NUL-terminated ASCII string.
+
+	This information is intended for the user.
+    * - __u32
+      - ``type``
+      - :cspan:`1` Type of the tuner, see :c:type:`v4l2_tuner_type`.
+    * - __u32
+      - ``capability``
+      - :cspan:`1`
+
+	Tuner capability flags, see :ref:`tuner-capability`. Audio flags
+	indicate the ability to decode audio subprograms. They will *not*
+	change, for example with the current video standard.
+
+	When the structure refers to a radio tuner the
+	``V4L2_TUNER_CAP_LANG1``, ``V4L2_TUNER_CAP_LANG2`` and
+	``V4L2_TUNER_CAP_NORM`` flags can't be used.
+
+	If multiple frequency bands are supported, then ``capability`` is
+	the union of all ``capability`` fields of each struct
+	:c:type:`v4l2_frequency_band`.
+    * - __u32
+      - ``rangelow``
+      - :cspan:`1` The lowest tunable frequency in units of 62.5 kHz, or
+	if the ``capability`` flag ``V4L2_TUNER_CAP_LOW`` is set, in units
+	of 62.5 Hz, or if the ``capability`` flag ``V4L2_TUNER_CAP_1HZ``
+	is set, in units of 1 Hz. If multiple frequency bands are
+	supported, then ``rangelow`` is the lowest frequency of all the
+	frequency bands.
+    * - __u32
+      - ``rangehigh``
+      - :cspan:`1` The highest tunable frequency in units of 62.5 kHz,
+	or if the ``capability`` flag ``V4L2_TUNER_CAP_LOW`` is set, in
+	units of 62.5 Hz, or if the ``capability`` flag
+	``V4L2_TUNER_CAP_1HZ`` is set, in units of 1 Hz. If multiple
+	frequency bands are supported, then ``rangehigh`` is the highest
+	frequency of all the frequency bands.
+    * - __u32
+      - ``rxsubchans``
+      - :cspan:`1`
+
+	Some tuners or audio decoders can determine the received audio
+	subprograms by analyzing audio carriers, pilot tones or other
+	indicators. To pass this information drivers set flags defined in
+	:ref:`tuner-rxsubchans` in this field. For example:
+    * -
+      -
+      - ``V4L2_TUNER_SUB_MONO``
+      - receiving mono audio
+    * -
+      -
+      - ``STEREO | SAP``
+      - receiving stereo audio and a secondary audio program
+    * -
+      -
+      - ``MONO | STEREO``
+      - receiving mono or stereo audio, the hardware cannot distinguish
+    * -
+      -
+      - ``LANG1 | LANG2``
+      - receiving bilingual audio
+    * -
+      -
+      - ``MONO | STEREO | LANG1 | LANG2``
+      - receiving mono, stereo or bilingual audio
+    * -
+      -
+      - :cspan:`1`
+
+	When the ``V4L2_TUNER_CAP_STEREO``, ``_LANG1``, ``_LANG2`` or
+	``_SAP`` flag is cleared in the ``capability`` field, the
+	corresponding ``V4L2_TUNER_SUB_`` flag must not be set here.
+
+	This field is valid only if this is the tuner of the current video
+	input, or when the structure refers to a radio tuner.
+    * - __u32
+      - ``audmode``
+      - :cspan:`1`
+
+	The selected audio mode, see :ref:`tuner-audmode` for valid
+	values. The audio mode does not affect audio subprogram detection,
+	and like a :ref:`control` it does not automatically
+	change unless the requested mode is invalid or unsupported. See
+	:ref:`tuner-matrix` for possible results when the selected and
+	received audio programs do not match.
+
+	Currently this is the only field of struct
+	struct :c:type:`v4l2_tuner` applications can change.
+    * - __u32
+      - ``signal``
+      - :cspan:`1` The signal strength if known.
+
+	Ranging from 0 to 65535. Higher values indicate a better signal.
+    * - __s32
+      - ``afc``
+      - :cspan:`1` Automatic frequency control.
+
+	When the ``afc`` value is negative, the frequency is too
+	low, when positive too high.
+    * - __u32
+      - ``reserved``\ [4]
+      - :cspan:`1` Reserved for future extensions.
+
+	Drivers and applications must set the array to zero.
+
+
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. c:type:: v4l2_tuner_type
+
+.. flat-table:: enum v4l2_tuner_type
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 6
+
+    * - ``V4L2_TUNER_RADIO``
+      - 1
+      - Tuner supports radio
+    * - ``V4L2_TUNER_ANALOG_TV``
+      - 2
+      - Tuner supports analog TV
+    * - ``V4L2_TUNER_SDR``
+      - 4
+      - Tuner controls the A/D and/or D/A block of a
+	Software Digital Radio (SDR)
+    * - ``V4L2_TUNER_RF``
+      - 5
+      - Tuner controls the RF part of a Software Digital Radio (SDR)
+
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. _tuner-capability:
+
+.. cssclass:: longtable
+
+.. flat-table:: Tuner and Modulator Capability Flags
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_TUNER_CAP_LOW``
+      - 0x0001
+      - When set, tuning frequencies are expressed in units of 62.5 Hz
+	instead of 62.5 kHz.
+    * - ``V4L2_TUNER_CAP_NORM``
+      - 0x0002
+      - This is a multi-standard tuner; the video standard can or must be
+	switched. (B/G PAL tuners for example are typically not considered
+	multi-standard because the video standard is automatically
+	determined from the frequency band.) The set of supported video
+	standards is available from the struct
+	:c:type:`v4l2_input` pointing to this tuner, see the
+	description of ioctl :ref:`VIDIOC_ENUMINPUT`
+	for details. Only ``V4L2_TUNER_ANALOG_TV`` tuners can have this
+	capability.
+    * - ``V4L2_TUNER_CAP_HWSEEK_BOUNDED``
+      - 0x0004
+      - If set, then this tuner supports the hardware seek functionality
+	where the seek stops when it reaches the end of the frequency
+	range.
+    * - ``V4L2_TUNER_CAP_HWSEEK_WRAP``
+      - 0x0008
+      - If set, then this tuner supports the hardware seek functionality
+	where the seek wraps around when it reaches the end of the
+	frequency range.
+    * - ``V4L2_TUNER_CAP_STEREO``
+      - 0x0010
+      - Stereo audio reception is supported.
+    * - ``V4L2_TUNER_CAP_LANG1``
+      - 0x0040
+      - Reception of the primary language of a bilingual audio program is
+	supported. Bilingual audio is a feature of two-channel systems,
+	transmitting the primary language monaural on the main audio
+	carrier and a secondary language monaural on a second carrier.
+	Only ``V4L2_TUNER_ANALOG_TV`` tuners can have this capability.
+    * - ``V4L2_TUNER_CAP_LANG2``
+      - 0x0020
+      - Reception of the secondary language of a bilingual audio program
+	is supported. Only ``V4L2_TUNER_ANALOG_TV`` tuners can have this
+	capability.
+    * - ``V4L2_TUNER_CAP_SAP``
+      - 0x0020
+      - Reception of a secondary audio program is supported. This is a
+	feature of the BTSC system which accompanies the NTSC video
+	standard. Two audio carriers are available for mono or stereo
+	transmissions of a primary language, and an independent third
+	carrier for a monaural secondary language. Only
+	``V4L2_TUNER_ANALOG_TV`` tuners can have this capability.
+
+	.. note::
+
+	   The ``V4L2_TUNER_CAP_LANG2`` and ``V4L2_TUNER_CAP_SAP``
+	   flags are synonyms. ``V4L2_TUNER_CAP_SAP`` applies when the tuner
+	   supports the ``V4L2_STD_NTSC_M`` video standard.
+    * - ``V4L2_TUNER_CAP_RDS``
+      - 0x0080
+      - RDS capture is supported. This capability is only valid for radio
+	tuners.
+    * - ``V4L2_TUNER_CAP_RDS_BLOCK_IO``
+      - 0x0100
+      - The RDS data is passed as unparsed RDS blocks.
+    * - ``V4L2_TUNER_CAP_RDS_CONTROLS``
+      - 0x0200
+      - The RDS data is parsed by the hardware and set via controls.
+    * - ``V4L2_TUNER_CAP_FREQ_BANDS``
+      - 0x0400
+      - The :ref:`VIDIOC_ENUM_FREQ_BANDS`
+	ioctl can be used to enumerate the available frequency bands.
+    * - ``V4L2_TUNER_CAP_HWSEEK_PROG_LIM``
+      - 0x0800
+      - The range to search when using the hardware seek functionality is
+	programmable, see
+	:ref:`VIDIOC_S_HW_FREQ_SEEK` for
+	details.
+    * - ``V4L2_TUNER_CAP_1HZ``
+      - 0x1000
+      - When set, tuning frequencies are expressed in units of 1 Hz
+	instead of 62.5 kHz.
+
+
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. _tuner-rxsubchans:
+
+.. flat-table:: Tuner Audio Reception Flags
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_TUNER_SUB_MONO``
+      - 0x0001
+      - The tuner receives a mono audio signal.
+    * - ``V4L2_TUNER_SUB_STEREO``
+      - 0x0002
+      - The tuner receives a stereo audio signal.
+    * - ``V4L2_TUNER_SUB_LANG1``
+      - 0x0008
+      - The tuner receives the primary language of a bilingual audio
+	signal. Drivers must clear this flag when the current video
+	standard is ``V4L2_STD_NTSC_M``.
+    * - ``V4L2_TUNER_SUB_LANG2``
+      - 0x0004
+      - The tuner receives the secondary language of a bilingual audio
+	signal (or a second audio program).
+    * - ``V4L2_TUNER_SUB_SAP``
+      - 0x0004
+      - The tuner receives a Second Audio Program.
+
+	.. note::
+
+	   The ``V4L2_TUNER_SUB_LANG2`` and ``V4L2_TUNER_SUB_SAP``
+	   flags are synonyms. The ``V4L2_TUNER_SUB_SAP`` flag applies
+	   when the current video standard is ``V4L2_STD_NTSC_M``.
+    * - ``V4L2_TUNER_SUB_RDS``
+      - 0x0010
+      - The tuner receives an RDS channel.
+
+
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. _tuner-audmode:
+
+.. flat-table:: Tuner Audio Modes
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_TUNER_MODE_MONO``
+      - 0
+      - Play mono audio. When the tuner receives a stereo signal this a
+	down-mix of the left and right channel. When the tuner receives a
+	bilingual or SAP signal this mode selects the primary language.
+    * - ``V4L2_TUNER_MODE_STEREO``
+      - 1
+      - Play stereo audio. When the tuner receives bilingual audio it may
+	play different languages on the left and right channel or the
+	primary language is played on both channels.
+
+	Playing different languages in this mode is deprecated. New
+	drivers should do this only in ``MODE_LANG1_LANG2``.
+
+	When the tuner receives no stereo signal or does not support
+	stereo reception the driver shall fall back to ``MODE_MONO``.
+    * - ``V4L2_TUNER_MODE_LANG1``
+      - 3
+      - Play the primary language, mono or stereo. Only
+	``V4L2_TUNER_ANALOG_TV`` tuners support this mode.
+    * - ``V4L2_TUNER_MODE_LANG2``
+      - 2
+      - Play the secondary language, mono. When the tuner receives no
+	bilingual audio or SAP, or their reception is not supported the
+	driver shall fall back to mono or stereo mode. Only
+	``V4L2_TUNER_ANALOG_TV`` tuners support this mode.
+    * - ``V4L2_TUNER_MODE_SAP``
+      - 2
+      - Play the Second Audio Program. When the tuner receives no
+	bilingual audio or SAP, or their reception is not supported the
+	driver shall fall back to mono or stereo mode. Only
+	``V4L2_TUNER_ANALOG_TV`` tuners support this mode.
+
+	.. note:: The ``V4L2_TUNER_MODE_LANG2`` and ``V4L2_TUNER_MODE_SAP``
+	   are synonyms.
+    * - ``V4L2_TUNER_MODE_LANG1_LANG2``
+      - 4
+      - Play the primary language on the left channel, the secondary
+	language on the right channel. When the tuner receives no
+	bilingual audio or SAP, it shall fall back to ``MODE_LANG1`` or
+	``MODE_MONO``. Only ``V4L2_TUNER_ANALOG_TV`` tuners support this
+	mode.
+
+.. raw:: latex
+
+    \scriptsize
+
+.. tabularcolumns:: |p{1.5cm}|p{1.5cm}|p{2.9cm}|p{2.9cm}|p{2.9cm}|p{2.9cm}|
+
+.. _tuner-matrix:
+
+.. flat-table:: Tuner Audio Matrix
+    :header-rows:  2
+    :stub-columns: 0
+    :widths: 7 7 14 14 14 14
+
+    * -
+      - :cspan:`4` Selected ``V4L2_TUNER_MODE_``
+    * - Received ``V4L2_TUNER_SUB_``
+      - ``MONO``
+      - ``STEREO``
+      - ``LANG1``
+      - ``LANG2 = SAP``
+      - ``LANG1_LANG2``\ [#f1]_
+    * - ``MONO``
+      - Mono
+      - Mono/Mono
+      - Mono
+      - Mono
+      - Mono/Mono
+    * - ``MONO | SAP``
+      - Mono
+      - Mono/Mono
+      - Mono
+      - SAP
+      - Mono/SAP (preferred) or Mono/Mono
+    * - ``STEREO``
+      - L+R
+      - L/R
+      - Stereo L/R (preferred) or Mono L+R
+      - Stereo L/R (preferred) or Mono L+R
+      - L/R (preferred) or L+R/L+R
+    * - ``STEREO | SAP``
+      - L+R
+      - L/R
+      - Stereo L/R (preferred) or Mono L+R
+      - SAP
+      - L+R/SAP (preferred) or L/R or L+R/L+R
+    * - ``LANG1 | LANG2``
+      - Language 1
+      - Lang1/Lang2 (deprecated\ [#f2]_) or Lang1/Lang1
+      - Language 1
+      - Language 2
+      - Lang1/Lang2 (preferred) or Lang1/Lang1
+
+.. raw:: latex
+
+    \normalsize
+
+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
+    The struct :c:type:`v4l2_tuner` ``index`` is out of
+    bounds.
+
+.. [#f1]
+   This mode has been added in Linux 2.6.17 and may not be supported by
+   older drivers.
+
+.. [#f2]
+   Playback of both languages in ``MODE_STEREO`` is deprecated. In the
+   future drivers should produce only the primary language in this mode.
+   Applications should request ``MODE_LANG1_LANG2`` to record both
+   languages or a stereo signal.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-log-status.rst b/Documentation/userspace-api/media/v4l/vidioc-log-status.rst
new file mode 100644
index 000000000000..64c06fa72b9c
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-log-status.rst
@@ -0,0 +1,56 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_LOG_STATUS:
+
+***********************
+ioctl VIDIOC_LOG_STATUS
+***********************
+
+Name
+====
+
+VIDIOC_LOG_STATUS - Log driver status information
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_LOG_STATUS)
+    :name: VIDIOC_LOG_STATUS
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+
+Description
+===========
+
+As the video/audio devices become more complicated it becomes harder to
+debug problems. When this ioctl is called the driver will output the
+current device status to the kernel log. This is particular useful when
+dealing with problems like no sound, no video and incorrectly tuned
+channels. Also many modern devices autodetect video and audio standards
+and this ioctl will report what the device thinks what the standard is.
+Mismatches may give an indication where the problem is.
+
+This ioctl is optional and not all drivers support it. It was introduced
+in Linux 2.6.15.
+
+
+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/userspace-api/media/v4l/vidioc-overlay.rst b/Documentation/userspace-api/media/v4l/vidioc-overlay.rst
new file mode 100644
index 000000000000..74310ff486ba
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-overlay.rst
@@ -0,0 +1,61 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_OVERLAY:
+
+********************
+ioctl VIDIOC_OVERLAY
+********************
+
+Name
+====
+
+VIDIOC_OVERLAY - Start or stop video overlay
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_OVERLAY, const int *argp )
+    :name: VIDIOC_OVERLAY
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to an integer.
+
+
+Description
+===========
+
+This ioctl is part of the :ref:`video overlay <overlay>` I/O method.
+Applications call :ref:`VIDIOC_OVERLAY` to start or stop the overlay. It
+takes a pointer to an integer which must be set to zero by the
+application to stop overlay, to one to start.
+
+Drivers do not support :ref:`VIDIOC_STREAMON` or
+:ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` with
+``V4L2_BUF_TYPE_VIDEO_OVERLAY``.
+
+
+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
+    The overlay parameters have not been set up. See :ref:`overlay`
+    for the necessary steps.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-prepare-buf.rst b/Documentation/userspace-api/media/v4l/vidioc-prepare-buf.rst
new file mode 100644
index 000000000000..b6c09d5b128f
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-prepare-buf.rst
@@ -0,0 +1,65 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_PREPARE_BUF:
+
+************************
+ioctl VIDIOC_PREPARE_BUF
+************************
+
+Name
+====
+
+VIDIOC_PREPARE_BUF - Prepare a buffer for I/O
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_PREPARE_BUF, struct v4l2_buffer *argp )
+    :name: VIDIOC_PREPARE_BUF
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_buffer`.
+
+
+Description
+===========
+
+Applications can optionally call the :ref:`VIDIOC_PREPARE_BUF` ioctl to
+pass ownership of the buffer to the driver before actually enqueuing it,
+using the :ref:`VIDIOC_QBUF <VIDIOC_QBUF>` ioctl, and to prepare it for future I/O. Such
+preparations may include cache invalidation or cleaning. Performing them
+in advance saves time during the actual I/O.
+
+The struct :c:type:`v4l2_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.
+
+EBUSY
+    File I/O is in progress.
+
+EINVAL
+    The buffer ``type`` is not supported, or the ``index`` is out of
+    bounds, or no buffers have been allocated yet, or the ``userptr`` or
+    ``length`` are invalid.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-qbuf.rst b/Documentation/userspace-api/media/v4l/vidioc-qbuf.rst
new file mode 100644
index 000000000000..ec0a54fbeb43
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-qbuf.rst
@@ -0,0 +1,205 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_QBUF:
+
+*******************************
+ioctl VIDIOC_QBUF, VIDIOC_DQBUF
+*******************************
+
+Name
+====
+
+VIDIOC_QBUF - VIDIOC_DQBUF - Exchange a buffer with the driver
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_QBUF, struct v4l2_buffer *argp )
+    :name: VIDIOC_QBUF
+
+.. c:function:: int ioctl( int fd, VIDIOC_DQBUF, struct v4l2_buffer *argp )
+    :name: VIDIOC_DQBUF
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_buffer`.
+
+
+Description
+===========
+
+Applications call the ``VIDIOC_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 ``type`` field of a struct
+:c:type:`v4l2_buffer` to the same buffer type as was
+previously used with struct :c:type:`v4l2_format` ``type``
+and struct :c:type:`v4l2_requestbuffers` ``type``.
+Applications must also set the ``index`` field. Valid index numbers
+range from zero to the number of buffers allocated with
+:ref:`VIDIOC_REQBUFS` (struct
+:c:type:`v4l2_requestbuffers` ``count``) minus
+one. The contents of the struct :c:type:`v4l2_buffer` returned
+by a :ref:`VIDIOC_QUERYBUF` ioctl will do as well.
+When the buffer is intended for output (``type`` is
+``V4L2_BUF_TYPE_VIDEO_OUTPUT``, ``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE``,
+or ``V4L2_BUF_TYPE_VBI_OUTPUT``) applications must also initialize the
+``bytesused``, ``field`` and ``timestamp`` fields, see :ref:`buffer`
+for details. Applications must also set ``flags`` to 0. The
+``reserved2`` and ``reserved`` fields must be set to 0. When using the
+:ref:`multi-planar API <planar-apis>`, the ``m.planes`` field must
+contain a userspace pointer to a filled-in array of struct
+:c:type:`v4l2_plane` and the ``length`` field must be set
+to the number of elements in that array.
+
+To enqueue a :ref:`memory mapped <mmap>` buffer applications set the
+``memory`` field to ``V4L2_MEMORY_MMAP``. When ``VIDIOC_QBUF`` is called
+with a pointer to this structure the driver sets the
+``V4L2_BUF_FLAG_MAPPED`` and ``V4L2_BUF_FLAG_QUEUED`` flags and clears
+the ``V4L2_BUF_FLAG_DONE`` flag in the ``flags`` field, or it returns an
+``EINVAL`` error code.
+
+To enqueue a :ref:`user pointer <userp>` buffer applications set the
+``memory`` field to ``V4L2_MEMORY_USERPTR``, the ``m.userptr`` field to
+the address of the buffer and ``length`` to its size. When the
+multi-planar API is used, ``m.userptr`` and ``length`` members of the
+passed array of struct :c:type:`v4l2_plane` have to be used
+instead. When ``VIDIOC_QBUF`` is called with a pointer to this structure
+the driver sets the ``V4L2_BUF_FLAG_QUEUED`` flag and clears the
+``V4L2_BUF_FLAG_MAPPED`` and ``V4L2_BUF_FLAG_DONE`` flags in the
+``flags`` field, or it returns an error code. This ioctl locks the
+memory pages of the buffer in physical memory, they cannot be swapped
+out to disk. Buffers remain locked until dequeued, until the
+:ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` or
+:ref:`VIDIOC_REQBUFS` ioctl is called, or until the
+device is closed.
+
+To enqueue a :ref:`DMABUF <dmabuf>` buffer applications set the
+``memory`` field to ``V4L2_MEMORY_DMABUF`` and the ``m.fd`` field to a
+file descriptor associated with a DMABUF buffer. When the multi-planar
+API is used the ``m.fd`` fields of the passed array of struct
+:c:type:`v4l2_plane` have to be used instead. When
+``VIDIOC_QBUF`` is called with a pointer to this structure the driver
+sets the ``V4L2_BUF_FLAG_QUEUED`` flag and clears the
+``V4L2_BUF_FLAG_MAPPED`` and ``V4L2_BUF_FLAG_DONE`` flags in the
+``flags`` field, or it returns an error code. This ioctl locks the
+buffer. Locking a buffer means passing it to a driver for a hardware
+access (usually DMA). If an application accesses (reads/writes) a locked
+buffer then the result is undefined. Buffers remain locked until
+dequeued, until the :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` or
+:ref:`VIDIOC_REQBUFS` ioctl is called, or until the
+device is closed.
+
+The ``request_fd`` field can be used with the ``VIDIOC_QBUF`` ioctl to specify
+the file descriptor of a :ref:`request <media-request-api>`, if requests are
+in use. Setting it means that the buffer will not be passed to the driver
+until the request itself is queued. Also, the driver will apply any
+settings associated with the request for this buffer. This field will
+be ignored unless the ``V4L2_BUF_FLAG_REQUEST_FD`` flag is set.
+If the device does not support requests, then ``EBADR`` will be returned.
+If requests are supported but an invalid request file descriptor is given,
+then ``EINVAL`` will be returned.
+
+.. caution::
+   It is not allowed to mix queuing requests with queuing buffers directly.
+   ``EBUSY`` will be returned if the first buffer was queued directly and
+   then the application tries to queue a request, or vice versa. After
+   closing the file descriptor, calling
+   :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` or calling :ref:`VIDIOC_REQBUFS`
+   the check for this will be reset.
+
+   For :ref:`memory-to-memory devices <mem2mem>` you can specify the
+   ``request_fd`` only for output buffers, not for capture buffers. Attempting
+   to specify this for a capture buffer will result in an ``EBADR`` error.
+
+Applications call the ``VIDIOC_DQBUF`` ioctl to dequeue a filled
+(capturing) or displayed (output) buffer from the driver's outgoing
+queue. They just set the ``type``, ``memory`` and ``reserved`` fields of
+a struct :c:type:`v4l2_buffer` as above, when
+``VIDIOC_DQBUF`` is called with a pointer to this structure the driver
+fills the remaining fields or returns an error code. The driver may also
+set ``V4L2_BUF_FLAG_ERROR`` in the ``flags`` field. It indicates a
+non-critical (recoverable) streaming error. In such case the application
+may continue as normal, but should be aware that data in the dequeued
+buffer might be corrupted. When using the multi-planar API, the planes
+array must be passed in as well.
+
+If the application sets the ``memory`` field to ``V4L2_MEMORY_DMABUF`` to
+dequeue a :ref:`DMABUF <dmabuf>` buffer, the driver fills the ``m.fd`` field
+with a file descriptor numerically the same as the one given to ``VIDIOC_QBUF``
+when the buffer was enqueued. No new file descriptor is created at dequeue time
+and the value is only for the application convenience. When the multi-planar
+API is used the ``m.fd`` fields of the passed array of struct
+:c:type:`v4l2_plane` are filled instead.
+
+By default ``VIDIOC_DQBUF`` blocks when no buffer is in the outgoing
+queue. When the ``O_NONBLOCK`` flag was given to the
+:ref:`open() <func-open>` function, ``VIDIOC_DQBUF`` returns
+immediately with an ``EAGAIN`` error code when no buffer is available.
+
+The struct :c:type:`v4l2_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 buffer ``type`` is not supported, or the ``index`` is out of
+    bounds, or no buffers have been allocated yet, or the ``userptr`` or
+    ``length`` are invalid, or the ``V4L2_BUF_FLAG_REQUEST_FD`` flag was
+    set but the the given ``request_fd`` was invalid, or ``m.fd`` was
+    an invalid DMABUF file descriptor.
+
+EIO
+    ``VIDIOC_DQBUF`` failed due to an internal error. Can also indicate
+    temporary problems like signal loss.
+
+    .. note::
+
+       The driver might dequeue an (empty) buffer despite returning
+       an error, or even stop capturing. Reusing such buffer may be unsafe
+       though and its details (e.g. ``index``) may not be returned either.
+       It is recommended that drivers indicate recoverable errors by setting
+       the ``V4L2_BUF_FLAG_ERROR`` and returning 0 instead. In that case the
+       application should be able to safely reuse the buffer and continue
+       streaming.
+
+EPIPE
+    ``VIDIOC_DQBUF`` returns this on an empty capture queue for mem2mem
+    codecs if a buffer with the ``V4L2_BUF_FLAG_LAST`` was already
+    dequeued and no new buffers are expected to become available.
+
+EBADR
+    The ``V4L2_BUF_FLAG_REQUEST_FD`` flag was set but the device does not
+    support requests for the given buffer type, or
+    the ``V4L2_BUF_FLAG_REQUEST_FD`` flag was not set but the device requires
+    that the buffer is part of a request.
+
+EBUSY
+    The first buffer was queued via a request, but the application now tries
+    to queue it directly, or vice versa (it is not permitted to mix the two
+    APIs).
diff --git a/Documentation/userspace-api/media/v4l/vidioc-query-dv-timings.rst b/Documentation/userspace-api/media/v4l/vidioc-query-dv-timings.rst
new file mode 100644
index 000000000000..ab86408446f3
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-query-dv-timings.rst
@@ -0,0 +1,94 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_QUERY_DV_TIMINGS:
+
+*****************************
+ioctl VIDIOC_QUERY_DV_TIMINGS
+*****************************
+
+Name
+====
+
+VIDIOC_QUERY_DV_TIMINGS - VIDIOC_SUBDEV_QUERY_DV_TIMINGS - Sense the DV preset received by the current input
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_QUERY_DV_TIMINGS, struct v4l2_dv_timings *argp )
+    :name: VIDIOC_QUERY_DV_TIMINGS
+
+.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_QUERY_DV_TIMINGS, struct v4l2_dv_timings *argp )
+    :name: VIDIOC_SUBDEV_QUERY_DV_TIMINGS
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_dv_timings`.
+
+
+Description
+===========
+
+The hardware may be able to detect the current DV timings automatically,
+similar to sensing the video standard. To do so, applications call
+:ref:`VIDIOC_QUERY_DV_TIMINGS` with a pointer to a struct
+:c:type:`v4l2_dv_timings`. Once the hardware detects
+the timings, it will fill in the timings structure.
+
+.. note::
+
+   Drivers shall *not* switch timings automatically if new
+   timings are detected. Instead, drivers should send the
+   ``V4L2_EVENT_SOURCE_CHANGE`` event (if they support this) and expect
+   that userspace will take action by calling :ref:`VIDIOC_QUERY_DV_TIMINGS`.
+   The reason is that new timings usually mean different buffer sizes as
+   well, and you cannot change buffer sizes on the fly. In general,
+   applications that receive the Source Change event will have to call
+   :ref:`VIDIOC_QUERY_DV_TIMINGS`, and if the detected timings are valid they
+   will have to stop streaming, set the new timings, allocate new buffers
+   and start streaming again.
+
+If the timings could not be detected because there was no signal, then
+ENOLINK is returned. If a signal was detected, but it was unstable and
+the receiver could not lock to the signal, then ``ENOLCK`` is returned. If
+the receiver could lock to the signal, but the format is unsupported
+(e.g. because the pixelclock is out of range of the hardware
+capabilities), then the driver fills in whatever timings it could find
+and returns ``ERANGE``. In that case the application can call
+:ref:`VIDIOC_DV_TIMINGS_CAP` to compare the
+found timings with the hardware's capabilities in order to give more
+precise feedback to the user.
+
+
+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.
+
+ENODATA
+    Digital video timings are not supported for this input or output.
+
+ENOLINK
+    No timings could be detected because no signal was found.
+
+ENOLCK
+    The signal was unstable and the hardware could not lock on to it.
+
+ERANGE
+    Timings were found, but they are out of range of the hardware
+    capabilities.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-querybuf.rst b/Documentation/userspace-api/media/v4l/vidioc-querybuf.rst
new file mode 100644
index 000000000000..646f91140ccf
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-querybuf.rst
@@ -0,0 +1,87 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_QUERYBUF:
+
+*********************
+ioctl VIDIOC_QUERYBUF
+*********************
+
+Name
+====
+
+VIDIOC_QUERYBUF - Query the status of a buffer
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_QUERYBUF, struct v4l2_buffer *argp )
+    :name: VIDIOC_QUERYBUF
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_buffer`.
+
+
+Description
+===========
+
+This ioctl is part of the :ref:`streaming <mmap>` 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:`VIDIOC_REQBUFS` ioctl.
+
+Applications set the ``type`` field of a struct
+:c:type:`v4l2_buffer` to the same buffer type as was
+previously used with struct :c:type:`v4l2_format` ``type``
+and struct :c:type:`v4l2_requestbuffers` ``type``,
+and the ``index`` field. Valid index numbers range from zero to the
+number of buffers allocated with
+:ref:`VIDIOC_REQBUFS` (struct
+:c:type:`v4l2_requestbuffers` ``count``) minus
+one. The ``reserved`` and ``reserved2`` fields must be set to 0. When
+using the :ref:`multi-planar API <planar-apis>`, the ``m.planes``
+field must contain a userspace pointer to an array of struct
+:c:type:`v4l2_plane` and the ``length`` field has to be set
+to the number of elements in that array. After calling
+:ref:`VIDIOC_QUERYBUF` with a pointer to this structure drivers return an
+error code or fill the rest of the structure.
+
+In the ``flags`` field the ``V4L2_BUF_FLAG_MAPPED``,
+``V4L2_BUF_FLAG_PREPARED``, ``V4L2_BUF_FLAG_QUEUED`` and
+``V4L2_BUF_FLAG_DONE`` flags will be valid. The ``memory`` field will be
+set to the current I/O method. For the single-planar API, the
+``m.offset`` contains the offset of the buffer from the start of the
+device memory, the ``length`` field its size. For the multi-planar API,
+fields ``m.mem_offset`` and ``length`` in the ``m.planes`` array
+elements will be used instead and the ``length`` field of struct
+:c:type:`v4l2_buffer` is set to the number of filled-in
+array elements. The driver may or may not set the remaining fields and
+flags, they are meaningless in this context.
+
+The struct :c:type:`v4l2_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.
+
+EINVAL
+    The buffer ``type`` is not supported, or the ``index`` is out of
+    bounds.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-querycap.rst b/Documentation/userspace-api/media/v4l/vidioc-querycap.rst
new file mode 100644
index 000000000000..28e1f766128c
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-querycap.rst
@@ -0,0 +1,284 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_QUERYCAP:
+
+*********************
+ioctl VIDIOC_QUERYCAP
+*********************
+
+Name
+====
+
+VIDIOC_QUERYCAP - Query device capabilities
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_QUERYCAP, struct v4l2_capability *argp )
+    :name: VIDIOC_QUERYCAP
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_capability`.
+
+
+Description
+===========
+
+All V4L2 devices support the ``VIDIOC_QUERYCAP`` ioctl. It is used to
+identify kernel devices compatible with this specification and to obtain
+information about driver and hardware capabilities. The ioctl takes a
+pointer to a struct :c:type:`v4l2_capability` which is
+filled by the driver. When the driver is not compatible with this
+specification the ioctl returns an ``EINVAL`` error code.
+
+
+.. tabularcolumns:: |p{1.5cm}|p{2.5cm}|p{13cm}|
+
+.. c:type:: v4l2_capability
+
+.. flat-table:: struct v4l2_capability
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 4 20
+
+    * - __u8
+      - ``driver``\ [16]
+      - Name of the driver, a unique NUL-terminated ASCII string. For
+	example: "bttv". Driver specific applications can use this
+	information to verify the driver identity. It is also useful to
+	work around known bugs, or to identify drivers in error reports.
+
+	Storing strings in fixed sized arrays is bad practice but
+	unavoidable here. Drivers and applications should take precautions
+	to never read or write beyond the end of the array and to make
+	sure the strings are properly NUL-terminated.
+    * - __u8
+      - ``card``\ [32]
+      - Name of the device, a NUL-terminated UTF-8 string. For example:
+	"Yoyodyne TV/FM". One driver may support different brands or
+	models of video hardware. This information is intended for users,
+	for example in a menu of available devices. Since multiple TV
+	cards of the same brand may be installed which are supported by
+	the same driver, this name should be combined with the character
+	device file name (e. g. ``/dev/video2``) or the ``bus_info``
+	string to avoid ambiguities.
+    * - __u8
+      - ``bus_info``\ [32]
+      - Location of the device in the system, a NUL-terminated ASCII
+	string. For example: "PCI:0000:05:06.0". This information is
+	intended for users, to distinguish multiple identical devices. If
+	no such information is available the field must simply count the
+	devices controlled by the driver ("platform:vivid-000"). The
+	bus_info must start with "PCI:" for PCI boards, "PCIe:" for PCI
+	Express boards, "usb-" for USB devices, "I2C:" for i2c devices,
+	"ISA:" for ISA devices, "parport" for parallel port devices and
+	"platform:" for platform devices.
+    * - __u32
+      - ``version``
+      - Version number of the driver.
+
+	Starting with kernel 3.1, the version reported is provided by the
+	V4L2 subsystem following the kernel numbering scheme. However, it
+	may not always return the same version as the kernel if, for
+	example, a stable or distribution-modified kernel uses the V4L2
+	stack from a newer kernel.
+
+	The version number is formatted using the ``KERNEL_VERSION()``
+	macro. For example if the media stack corresponds to the V4L2
+	version shipped with Kernel 4.14, it would be equivalent to:
+    * - :cspan:`2`
+
+	``#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))``
+
+	``__u32 version = KERNEL_VERSION(4, 14, 0);``
+
+	``printf ("Version: %u.%u.%u\\n",``
+
+	``(version >> 16) & 0xFF, (version >> 8) & 0xFF, version & 0xFF);``
+    * - __u32
+      - ``capabilities``
+      - Available capabilities of the physical device as a whole, see
+	:ref:`device-capabilities`. The same physical device can export
+	multiple devices in /dev (e.g. /dev/videoX, /dev/vbiY and
+	/dev/radioZ). The ``capabilities`` field should contain a union of
+	all capabilities available around the several V4L2 devices
+	exported to userspace. For all those devices the ``capabilities``
+	field returns the same set of capabilities. This allows
+	applications to open just one of the devices (typically the video
+	device) and discover whether video, vbi and/or radio are also
+	supported.
+    * - __u32
+      - ``device_caps``
+      - Device capabilities of the opened device, see
+	:ref:`device-capabilities`. Should contain the available
+	capabilities of that specific device node. So, for example,
+	``device_caps`` of a radio device will only contain radio related
+	capabilities and no video or vbi capabilities. This field is only
+	set if the ``capabilities`` field contains the
+	``V4L2_CAP_DEVICE_CAPS`` capability. Only the ``capabilities``
+	field can have the ``V4L2_CAP_DEVICE_CAPS`` capability,
+	``device_caps`` will never set ``V4L2_CAP_DEVICE_CAPS``.
+    * - __u32
+      - ``reserved``\ [3]
+      - Reserved for future extensions. Drivers must set this array to
+	zero.
+
+
+
+.. tabularcolumns:: |p{6.1cm}|p{2.2cm}|p{8.7cm}|
+
+.. _device-capabilities:
+
+.. cssclass:: longtable
+
+.. flat-table:: Device Capabilities Flags
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_CAP_VIDEO_CAPTURE``
+      - 0x00000001
+      - The device supports the single-planar API through the
+	:ref:`Video Capture <capture>` interface.
+    * - ``V4L2_CAP_VIDEO_CAPTURE_MPLANE``
+      - 0x00001000
+      - The device supports the :ref:`multi-planar API <planar-apis>`
+	through the :ref:`Video Capture <capture>` interface.
+    * - ``V4L2_CAP_VIDEO_OUTPUT``
+      - 0x00000002
+      - The device supports the single-planar API through the
+	:ref:`Video Output <output>` interface.
+    * - ``V4L2_CAP_VIDEO_OUTPUT_MPLANE``
+      - 0x00002000
+      - The device supports the :ref:`multi-planar API <planar-apis>`
+	through the :ref:`Video Output <output>` interface.
+    * - ``V4L2_CAP_VIDEO_M2M``
+      - 0x00004000
+      - The device supports the single-planar API through the Video
+	Memory-To-Memory interface.
+    * - ``V4L2_CAP_VIDEO_M2M_MPLANE``
+      - 0x00008000
+      - The device supports the :ref:`multi-planar API <planar-apis>`
+	through the Video Memory-To-Memory interface.
+    * - ``V4L2_CAP_VIDEO_OVERLAY``
+      - 0x00000004
+      - The device supports the :ref:`Video Overlay <overlay>`
+	interface. A video overlay device typically stores captured images
+	directly in the video memory of a graphics card, with hardware
+	clipping and scaling.
+    * - ``V4L2_CAP_VBI_CAPTURE``
+      - 0x00000010
+      - The device supports the :ref:`Raw VBI Capture <raw-vbi>`
+	interface, providing Teletext and Closed Caption data.
+    * - ``V4L2_CAP_VBI_OUTPUT``
+      - 0x00000020
+      - The device supports the :ref:`Raw VBI Output <raw-vbi>`
+	interface.
+    * - ``V4L2_CAP_SLICED_VBI_CAPTURE``
+      - 0x00000040
+      - The device supports the :ref:`Sliced VBI Capture <sliced>`
+	interface.
+    * - ``V4L2_CAP_SLICED_VBI_OUTPUT``
+      - 0x00000080
+      - The device supports the :ref:`Sliced VBI Output <sliced>`
+	interface.
+    * - ``V4L2_CAP_RDS_CAPTURE``
+      - 0x00000100
+      - The device supports the :ref:`RDS <rds>` capture interface.
+    * - ``V4L2_CAP_VIDEO_OUTPUT_OVERLAY``
+      - 0x00000200
+      - The device supports the :ref:`Video Output Overlay <osd>` (OSD)
+	interface. Unlike the *Video Overlay* interface, this is a
+	secondary function of video output devices and overlays an image
+	onto an outgoing video signal. When the driver sets this flag, it
+	must clear the ``V4L2_CAP_VIDEO_OVERLAY`` flag and vice
+	versa. [#f1]_
+    * - ``V4L2_CAP_HW_FREQ_SEEK``
+      - 0x00000400
+      - The device supports the
+	:ref:`VIDIOC_S_HW_FREQ_SEEK` ioctl
+	for hardware frequency seeking.
+    * - ``V4L2_CAP_RDS_OUTPUT``
+      - 0x00000800
+      - The device supports the :ref:`RDS <rds>` output interface.
+    * - ``V4L2_CAP_TUNER``
+      - 0x00010000
+      - The device has some sort of tuner to receive RF-modulated video
+	signals. For more information about tuner programming see
+	:ref:`tuner`.
+    * - ``V4L2_CAP_AUDIO``
+      - 0x00020000
+      - The device has audio inputs or outputs. It may or may not support
+	audio recording or playback, in PCM or compressed formats. PCM
+	audio support must be implemented as ALSA or OSS interface. For
+	more information on audio inputs and outputs see :ref:`audio`.
+    * - ``V4L2_CAP_RADIO``
+      - 0x00040000
+      - This is a radio receiver.
+    * - ``V4L2_CAP_MODULATOR``
+      - 0x00080000
+      - The device has some sort of modulator to emit RF-modulated
+	video/audio signals. For more information about modulator
+	programming see :ref:`tuner`.
+    * - ``V4L2_CAP_SDR_CAPTURE``
+      - 0x00100000
+      - The device supports the :ref:`SDR Capture <sdr>` interface.
+    * - ``V4L2_CAP_EXT_PIX_FORMAT``
+      - 0x00200000
+      - The device supports the struct
+	:c:type:`v4l2_pix_format` extended fields.
+    * - ``V4L2_CAP_SDR_OUTPUT``
+      - 0x00400000
+      - The device supports the :ref:`SDR Output <sdr>` interface.
+    * - ``V4L2_CAP_META_CAPTURE``
+      - 0x00800000
+      - The device supports the :ref:`metadata` capture interface.
+    * - ``V4L2_CAP_READWRITE``
+      - 0x01000000
+      - The device supports the :ref:`read() <rw>` and/or
+	:ref:`write() <rw>` I/O methods.
+    * - ``V4L2_CAP_ASYNCIO``
+      - 0x02000000
+      - The device supports the :ref:`asynchronous <async>` I/O methods.
+    * - ``V4L2_CAP_STREAMING``
+      - 0x04000000
+      - The device supports the :ref:`streaming <mmap>` I/O method.
+    * - ``V4L2_CAP_META_OUTPUT``
+      - 0x08000000
+      - The device supports the :ref:`metadata` output interface.
+    * - ``V4L2_CAP_TOUCH``
+      - 0x10000000
+      - This is a touch device.
+    * - ``V4L2_CAP_DEVICE_CAPS``
+      - 0x80000000
+      - The driver fills the ``device_caps`` field. This capability can
+	only appear in the ``capabilities`` field and never in the
+	``device_caps`` field.
+
+
+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.
+
+.. [#f1]
+   The struct :c:type:`v4l2_framebuffer` lacks an
+   enum :c:type:`v4l2_buf_type` field, therefore the
+   type of overlay is implied by the driver capabilities.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
new file mode 100644
index 000000000000..fbb0038d86bf
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
@@ -0,0 +1,616 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_QUERYCTRL:
+
+*******************************************************************
+ioctls VIDIOC_QUERYCTRL, VIDIOC_QUERY_EXT_CTRL and VIDIOC_QUERYMENU
+*******************************************************************
+
+Name
+====
+
+VIDIOC_QUERYCTRL - VIDIOC_QUERY_EXT_CTRL - VIDIOC_QUERYMENU - Enumerate controls and menu control items
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, int VIDIOC_QUERYCTRL, struct v4l2_queryctrl *argp )
+    :name: VIDIOC_QUERYCTRL
+
+.. c:function:: int ioctl( int fd, VIDIOC_QUERY_EXT_CTRL, struct v4l2_query_ext_ctrl *argp )
+    :name: VIDIOC_QUERY_EXT_CTRL
+
+.. c:function:: int ioctl( int fd, VIDIOC_QUERYMENU, struct v4l2_querymenu *argp )
+    :name: VIDIOC_QUERYMENU
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_queryctrl`, :c:type:`v4l2_query_ext_ctrl`
+    or :c:type:`v4l2_querymenu` (depending on the ioctl).
+
+
+Description
+===========
+
+To query the attributes of a control applications set the ``id`` field
+of a struct :ref:`v4l2_queryctrl <v4l2-queryctrl>` and call the
+``VIDIOC_QUERYCTRL`` ioctl with a pointer to this structure. The driver
+fills the rest of the structure or returns an ``EINVAL`` error code when the
+``id`` is invalid.
+
+It is possible to enumerate controls by calling ``VIDIOC_QUERYCTRL``
+with successive ``id`` values starting from ``V4L2_CID_BASE`` up to and
+exclusive ``V4L2_CID_LASTP1``. Drivers may return ``EINVAL`` if a control in
+this range is not supported. Further applications can enumerate private
+controls, which are not defined in this specification, by starting at
+``V4L2_CID_PRIVATE_BASE`` and incrementing ``id`` until the driver
+returns ``EINVAL``.
+
+In both cases, when the driver sets the ``V4L2_CTRL_FLAG_DISABLED`` flag
+in the ``flags`` field this control is permanently disabled and should
+be ignored by the application. [#f1]_
+
+When the application ORs ``id`` with ``V4L2_CTRL_FLAG_NEXT_CTRL`` the
+driver returns the next supported non-compound control, or ``EINVAL`` if
+there is none. In addition, the ``V4L2_CTRL_FLAG_NEXT_COMPOUND`` flag
+can be specified to enumerate all compound controls (i.e. controls with
+type ≥ ``V4L2_CTRL_COMPOUND_TYPES`` and/or array control, in other words
+controls that contain more than one value). Specify both
+``V4L2_CTRL_FLAG_NEXT_CTRL`` and ``V4L2_CTRL_FLAG_NEXT_COMPOUND`` in
+order to enumerate all controls, compound or not. Drivers which do not
+support these flags yet always return ``EINVAL``.
+
+The ``VIDIOC_QUERY_EXT_CTRL`` ioctl was introduced in order to better
+support controls that can use compound types, and to expose additional
+control information that cannot be returned in struct
+:ref:`v4l2_queryctrl <v4l2-queryctrl>` since that structure is full.
+
+``VIDIOC_QUERY_EXT_CTRL`` is used in the same way as
+``VIDIOC_QUERYCTRL``, except that the ``reserved`` array must be zeroed
+as well.
+
+Additional information is required for menu controls: the names of the
+menu items. To query them applications set the ``id`` and ``index``
+fields of struct :ref:`v4l2_querymenu <v4l2-querymenu>` and call the
+``VIDIOC_QUERYMENU`` ioctl with a pointer to this structure. The driver
+fills the rest of the structure or returns an ``EINVAL`` error code when the
+``id`` or ``index`` is invalid. Menu items are enumerated by calling
+``VIDIOC_QUERYMENU`` with successive ``index`` values from struct
+:ref:`v4l2_queryctrl <v4l2-queryctrl>` ``minimum`` to ``maximum``,
+inclusive.
+
+.. note::
+
+   It is possible for ``VIDIOC_QUERYMENU`` to return
+   an ``EINVAL`` error code for some indices between ``minimum`` and
+   ``maximum``. In that case that particular menu item is not supported by
+   this driver. Also note that the ``minimum`` value is not necessarily 0.
+
+See also the examples in :ref:`control`.
+
+
+.. tabularcolumns:: |p{1.2cm}|p{3.6cm}|p{12.7cm}|
+
+.. _v4l2-queryctrl:
+
+.. cssclass:: longtable
+
+.. flat-table:: struct v4l2_queryctrl
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``id``
+      - Identifies the control, set by the application. See
+	:ref:`control-id` for predefined IDs. When the ID is ORed with
+	V4L2_CTRL_FLAG_NEXT_CTRL the driver clears the flag and
+	returns the first control with a higher ID. Drivers which do not
+	support this flag yet always return an ``EINVAL`` error code.
+    * - __u32
+      - ``type``
+      - Type of control, see :c:type:`v4l2_ctrl_type`.
+    * - __u8
+      - ``name``\ [32]
+      - Name of the control, a NUL-terminated ASCII string. This
+	information is intended for the user.
+    * - __s32
+      - ``minimum``
+      - Minimum value, inclusive. This field gives a lower bound for the
+	control. See enum :c:type:`v4l2_ctrl_type` how
+	the minimum value is to be used for each possible control type.
+	Note that this a signed 32-bit value.
+    * - __s32
+      - ``maximum``
+      - Maximum value, inclusive. This field gives an upper bound for the
+	control. See enum :c:type:`v4l2_ctrl_type` how
+	the maximum value is to be used for each possible control type.
+	Note that this a signed 32-bit value.
+    * - __s32
+      - ``step``
+      - This field gives a step size for the control. See enum
+	:c:type:`v4l2_ctrl_type` how the step value is
+	to be used for each possible control type. Note that this an
+	unsigned 32-bit value.
+
+	Generally drivers should not scale hardware control values. It may
+	be necessary for example when the ``name`` or ``id`` imply a
+	particular unit and the hardware actually accepts only multiples
+	of said unit. If so, drivers must take care values are properly
+	rounded when scaling, such that errors will not accumulate on
+	repeated read-write cycles.
+
+	This field gives the smallest change of an integer control
+	actually affecting hardware. Often the information is needed when
+	the user can change controls by keyboard or GUI buttons, rather
+	than a slider. When for example a hardware register accepts values
+	0-511 and the driver reports 0-65535, step should be 128.
+
+	Note that although signed, the step value is supposed to be always
+	positive.
+    * - __s32
+      - ``default_value``
+      - The default value of a ``V4L2_CTRL_TYPE_INTEGER``, ``_BOOLEAN``,
+	``_BITMASK``, ``_MENU`` or ``_INTEGER_MENU`` control. Not valid
+	for other types of controls.
+
+	.. note::
+
+	   Drivers reset controls to their default value only when
+	   the driver is first loaded, never afterwards.
+    * - __u32
+      - ``flags``
+      - Control flags, see :ref:`control-flags`.
+    * - __u32
+      - ``reserved``\ [2]
+      - Reserved for future extensions. Drivers must set the array to
+	zero.
+
+
+
+.. tabularcolumns:: |p{1.2cm}|p{5.0cm}|p{11.3cm}|
+
+.. _v4l2-query-ext-ctrl:
+
+.. cssclass:: longtable
+
+.. flat-table:: struct v4l2_query_ext_ctrl
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``id``
+      - Identifies the control, set by the application. See
+	:ref:`control-id` for predefined IDs. When the ID is ORed with
+	``V4L2_CTRL_FLAG_NEXT_CTRL`` the driver clears the flag and
+	returns the first non-compound control with a higher ID. When the
+	ID is ORed with ``V4L2_CTRL_FLAG_NEXT_COMPOUND`` the driver clears
+	the flag and returns the first compound control with a higher ID.
+	Set both to get the first control (compound or not) with a higher
+	ID.
+    * - __u32
+      - ``type``
+      - Type of control, see :c:type:`v4l2_ctrl_type`.
+    * - char
+      - ``name``\ [32]
+      - Name of the control, a NUL-terminated ASCII string. This
+	information is intended for the user.
+    * - __s64
+      - ``minimum``
+      - Minimum value, inclusive. This field gives a lower bound for the
+	control. See enum :c:type:`v4l2_ctrl_type` how
+	the minimum value is to be used for each possible control type.
+	Note that this a signed 64-bit value.
+    * - __s64
+      - ``maximum``
+      - Maximum value, inclusive. This field gives an upper bound for the
+	control. See enum :c:type:`v4l2_ctrl_type` how
+	the maximum value is to be used for each possible control type.
+	Note that this a signed 64-bit value.
+    * - __u64
+      - ``step``
+      - This field gives a step size for the control. See enum
+	:c:type:`v4l2_ctrl_type` how the step value is
+	to be used for each possible control type. Note that this an
+	unsigned 64-bit value.
+
+	Generally drivers should not scale hardware control values. It may
+	be necessary for example when the ``name`` or ``id`` imply a
+	particular unit and the hardware actually accepts only multiples
+	of said unit. If so, drivers must take care values are properly
+	rounded when scaling, such that errors will not accumulate on
+	repeated read-write cycles.
+
+	This field gives the smallest change of an integer control
+	actually affecting hardware. Often the information is needed when
+	the user can change controls by keyboard or GUI buttons, rather
+	than a slider. When for example a hardware register accepts values
+	0-511 and the driver reports 0-65535, step should be 128.
+    * - __s64
+      - ``default_value``
+      - The default value of a ``V4L2_CTRL_TYPE_INTEGER``, ``_INTEGER64``,
+	``_BOOLEAN``, ``_BITMASK``, ``_MENU``, ``_INTEGER_MENU``, ``_U8``
+	or ``_U16`` control. Not valid for other types of controls.
+
+	.. note::
+
+	   Drivers reset controls to their default value only when
+	   the driver is first loaded, never afterwards.
+    * - __u32
+      - ``flags``
+      - Control flags, see :ref:`control-flags`.
+    * - __u32
+      - ``elem_size``
+      - The size in bytes of a single element of the array. Given a char
+	pointer ``p`` to a 3-dimensional array you can find the position
+	of cell ``(z, y, x)`` as follows:
+	``p + ((z * dims[1] + y) * dims[0] + x) * elem_size``.
+	``elem_size`` is always valid, also when the control isn't an
+	array. For string controls ``elem_size`` is equal to
+	``maximum + 1``.
+    * - __u32
+      - ``elems``
+      - The number of elements in the N-dimensional array. If this control
+	is not an array, then ``elems`` is 1. The ``elems`` field can
+	never be 0.
+    * - __u32
+      - ``nr_of_dims``
+      - The number of dimension in the N-dimensional array. If this
+	control is not an array, then this field is 0.
+    * - __u32
+      - ``dims[V4L2_CTRL_MAX_DIMS]``
+      - The size of each dimension. The first ``nr_of_dims`` elements of
+	this array must be non-zero, all remaining elements must be zero.
+    * - __u32
+      - ``reserved``\ [32]
+      - Reserved for future extensions. Applications and drivers must set
+	the array to zero.
+
+
+
+.. tabularcolumns:: |p{1.2cm}|p{1.0cm}|p{1.7cm}|p{13.0cm}|
+
+.. _v4l2-querymenu:
+
+.. flat-table:: struct v4l2_querymenu
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``id``
+      - Identifies the control, set by the application from the respective
+	struct :ref:`v4l2_queryctrl <v4l2-queryctrl>` ``id``.
+    * - __u32
+      - ``index``
+      - Index of the menu item, starting at zero, set by the application.
+    * - union {
+      - (anonymous)
+    * - __u8
+      - ``name``\ [32]
+      - Name of the menu item, a NUL-terminated ASCII string. This
+	information is intended for the user. This field is valid for
+	``V4L2_CTRL_TYPE_MENU`` type controls.
+    * - __s64
+      - ``value``
+      - Value of the integer menu item. This field is valid for
+	``V4L2_CTRL_TYPE_INTEGER_MENU`` type controls.
+    * - }
+      -
+    * - __u32
+      - ``reserved``
+      - Reserved for future extensions. Drivers must set the array to
+	zero.
+
+
+
+.. tabularcolumns:: |p{5.8cm}|p{1.4cm}|p{1.0cm}|p{1.4cm}|p{6.9cm}|
+
+.. c:type:: v4l2_ctrl_type
+
+.. cssclass:: longtable
+
+.. flat-table:: enum v4l2_ctrl_type
+    :header-rows:  1
+    :stub-columns: 0
+    :widths:       30 5 5 5 55
+
+    * - Type
+      - ``minimum``
+      - ``step``
+      - ``maximum``
+      - Description
+    * - ``V4L2_CTRL_TYPE_INTEGER``
+      - any
+      - any
+      - any
+      - An integer-valued control ranging from minimum to maximum
+	inclusive. The step value indicates the increment between values.
+    * - ``V4L2_CTRL_TYPE_BOOLEAN``
+      - 0
+      - 1
+      - 1
+      - A boolean-valued control. Zero corresponds to "disabled", and one
+	means "enabled".
+    * - ``V4L2_CTRL_TYPE_MENU``
+      - ≥ 0
+      - 1
+      - N-1
+      - The control has a menu of N choices. The names of the menu items
+	can be enumerated with the ``VIDIOC_QUERYMENU`` ioctl.
+    * - ``V4L2_CTRL_TYPE_INTEGER_MENU``
+      - ≥ 0
+      - 1
+      - N-1
+      - The control has a menu of N choices. The values of the menu items
+	can be enumerated with the ``VIDIOC_QUERYMENU`` ioctl. This is
+	similar to ``V4L2_CTRL_TYPE_MENU`` except that instead of strings,
+	the menu items are signed 64-bit integers.
+    * - ``V4L2_CTRL_TYPE_BITMASK``
+      - 0
+      - n/a
+      - any
+      - A bitmask field. The maximum value is the set of bits that can be
+	used, all other bits are to be 0. The maximum value is interpreted
+	as a __u32, allowing the use of bit 31 in the bitmask.
+    * - ``V4L2_CTRL_TYPE_BUTTON``
+      - 0
+      - 0
+      - 0
+      - A control which performs an action when set. Drivers must ignore
+	the value passed with ``VIDIOC_S_CTRL`` and return an ``EACCES`` error
+	code on a ``VIDIOC_G_CTRL`` attempt.
+    * - ``V4L2_CTRL_TYPE_INTEGER64``
+      - any
+      - any
+      - any
+      - A 64-bit integer valued control. Minimum, maximum and step size
+	cannot be queried using ``VIDIOC_QUERYCTRL``. Only
+	``VIDIOC_QUERY_EXT_CTRL`` can retrieve the 64-bit min/max/step
+	values, they should be interpreted as n/a when using
+	``VIDIOC_QUERYCTRL``.
+    * - ``V4L2_CTRL_TYPE_STRING``
+      - ≥ 0
+      - ≥ 1
+      - ≥ 0
+      - The minimum and maximum string lengths. The step size means that
+	the string must be (minimum + N * step) characters long for N ≥ 0.
+	These lengths do not include the terminating zero, so in order to
+	pass a string of length 8 to
+	:ref:`VIDIOC_S_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` you need to
+	set the ``size`` field of struct
+	:c:type:`v4l2_ext_control` to 9. For
+	:ref:`VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` you can set
+	the ``size`` field to ``maximum`` + 1. Which character encoding is
+	used will depend on the string control itself and should be part
+	of the control documentation.
+    * - ``V4L2_CTRL_TYPE_CTRL_CLASS``
+      - n/a
+      - n/a
+      - n/a
+      - This is not a control. When ``VIDIOC_QUERYCTRL`` is called with a
+	control ID equal to a control class code (see :ref:`ctrl-class`)
+	+ 1, the ioctl returns the name of the control class and this
+	control type. Older drivers which do not support this feature
+	return an ``EINVAL`` error code.
+    * - ``V4L2_CTRL_TYPE_U8``
+      - any
+      - any
+      - any
+      - An unsigned 8-bit valued control ranging from minimum to maximum
+	inclusive. The step value indicates the increment between values.
+    * - ``V4L2_CTRL_TYPE_U16``
+      - any
+      - any
+      - any
+      - An unsigned 16-bit valued control ranging from minimum to maximum
+	inclusive. The step value indicates the increment between values.
+    * - ``V4L2_CTRL_TYPE_U32``
+      - any
+      - any
+      - any
+      - An unsigned 32-bit valued control ranging from minimum to maximum
+	inclusive. The step value indicates the increment between values.
+    * - ``V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS``
+      - n/a
+      - n/a
+      - n/a
+      - A struct :c:type:`v4l2_ctrl_mpeg2_slice_params`, containing MPEG-2
+	slice parameters for stateless video decoders.
+    * - ``V4L2_CTRL_TYPE_MPEG2_QUANTIZATION``
+      - n/a
+      - n/a
+      - n/a
+      - A struct :c:type:`v4l2_ctrl_mpeg2_quantization`, containing MPEG-2
+	quantization matrices for stateless video decoders.
+    * - ``V4L2_CTRL_TYPE_AREA``
+      - n/a
+      - n/a
+      - n/a
+      - A struct :c:type:`v4l2_area`, containing the width and the height
+        of a rectangular area. Units depend on the use case.
+    * - ``V4L2_CTRL_TYPE_H264_SPS``
+      - n/a
+      - n/a
+      - n/a
+      - A struct :c:type:`v4l2_ctrl_h264_sps`, containing H264
+	sequence parameters for stateless video decoders.
+    * - ``V4L2_CTRL_TYPE_H264_PPS``
+      - n/a
+      - n/a
+      - n/a
+      - A struct :c:type:`v4l2_ctrl_h264_pps`, containing H264
+	picture parameters for stateless video decoders.
+    * - ``V4L2_CTRL_TYPE_H264_SCALING_MATRIX``
+      - n/a
+      - n/a
+      - n/a
+      - A struct :c:type:`v4l2_ctrl_h264_scaling_matrix`, containing H264
+	scaling matrices for stateless video decoders.
+    * - ``V4L2_CTRL_TYPE_H264_SLICE_PARAMS``
+      - n/a
+      - n/a
+      - n/a
+      - A struct :c:type:`v4l2_ctrl_h264_slice_params`, containing H264
+	slice parameters for stateless video decoders.
+    * - ``V4L2_CTRL_TYPE_H264_DECODE_PARAMS``
+      - n/a
+      - n/a
+      - n/a
+      - A struct :c:type:`v4l2_ctrl_h264_decode_params`, containing H264
+	decode parameters for stateless video decoders.
+    * - ``V4L2_CTRL_TYPE_HEVC_SPS``
+      - n/a
+      - n/a
+      - n/a
+      - A struct :c:type:`v4l2_ctrl_hevc_sps`, containing HEVC Sequence
+	Parameter Set for stateless video decoders.
+    * - ``V4L2_CTRL_TYPE_HEVC_PPS``
+      - n/a
+      - n/a
+      - n/a
+      - A struct :c:type:`v4l2_ctrl_hevc_pps`, containing HEVC Picture
+	Parameter Set for stateless video decoders.
+    * - ``V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS``
+      - n/a
+      - n/a
+      - n/a
+      - A struct :c:type:`v4l2_ctrl_hevc_slice_params`, containing HEVC
+	slice parameters for stateless video decoders.
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. _control-flags:
+
+.. cssclass:: longtable
+
+.. flat-table:: Control Flags
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_CTRL_FLAG_DISABLED``
+      - 0x0001
+      - This control is permanently disabled and should be ignored by the
+	application. Any attempt to change the control will result in an
+	``EINVAL`` error code.
+    * - ``V4L2_CTRL_FLAG_GRABBED``
+      - 0x0002
+      - This control is temporarily unchangeable, for example because
+	another application took over control of the respective resource.
+	Such controls may be displayed specially in a user interface.
+	Attempts to change the control may result in an ``EBUSY`` error code.
+    * - ``V4L2_CTRL_FLAG_READ_ONLY``
+      - 0x0004
+      - This control is permanently readable only. Any attempt to change
+	the control will result in an ``EINVAL`` error code.
+    * - ``V4L2_CTRL_FLAG_UPDATE``
+      - 0x0008
+      - A hint that changing this control may affect the value of other
+	controls within the same control class. Applications should update
+	their user interface accordingly.
+    * - ``V4L2_CTRL_FLAG_INACTIVE``
+      - 0x0010
+      - This control is not applicable to the current configuration and
+	should be displayed accordingly in a user interface. For example
+	the flag may be set on a MPEG audio level 2 bitrate control when
+	MPEG audio encoding level 1 was selected with another control.
+    * - ``V4L2_CTRL_FLAG_SLIDER``
+      - 0x0020
+      - A hint that this control is best represented as a slider-like
+	element in a user interface.
+    * - ``V4L2_CTRL_FLAG_WRITE_ONLY``
+      - 0x0040
+      - This control is permanently writable only. Any attempt to read the
+	control will result in an ``EACCES`` error code error code. This flag
+	is typically present for relative controls or action controls
+	where writing a value will cause the device to carry out a given
+	action (e. g. motor control) but no meaningful value can be
+	returned.
+    * - ``V4L2_CTRL_FLAG_VOLATILE``
+      - 0x0080
+      - This control is volatile, which means that the value of the
+	control changes continuously. A typical example would be the
+	current gain value if the device is in auto-gain mode. In such a
+	case the hardware calculates the gain value based on the lighting
+	conditions which can change over time.
+
+	.. note::
+
+	   Setting a new value for a volatile control will be ignored
+	   unless
+	   :ref:`V4L2_CTRL_FLAG_EXECUTE_ON_WRITE <FLAG_EXECUTE_ON_WRITE>`
+	   is also set.
+	   Setting a new value for a volatile control will *never* trigger a
+	   :ref:`V4L2_EVENT_CTRL_CH_VALUE <ctrl-changes-flags>` event.
+    * - ``V4L2_CTRL_FLAG_HAS_PAYLOAD``
+      - 0x0100
+      - This control has a pointer type, so its value has to be accessed
+	using one of the pointer fields of struct
+	:c:type:`v4l2_ext_control`. This flag is set
+	for controls that are an array, string, or have a compound type.
+	In all cases you have to set a pointer to memory containing the
+	payload of the control.
+    * .. _FLAG_EXECUTE_ON_WRITE:
+
+      - ``V4L2_CTRL_FLAG_EXECUTE_ON_WRITE``
+      - 0x0200
+      - The value provided to the control will be propagated to the driver
+	even if it remains constant. This is required when the control
+	represents an action on the hardware. For example: clearing an
+	error flag or triggering the flash. All the controls of the type
+	``V4L2_CTRL_TYPE_BUTTON`` have this flag set.
+    * .. _FLAG_MODIFY_LAYOUT:
+
+      - ``V4L2_CTRL_FLAG_MODIFY_LAYOUT``
+      - 0x0400
+      - Changing this control value may modify the layout of the
+        buffer (for video devices) or the media bus format (for sub-devices).
+
+	A typical example would be the ``V4L2_CID_ROTATE`` control.
+
+	Note that typically controls with this flag will also set the
+	``V4L2_CTRL_FLAG_GRABBED`` flag when buffers are allocated or
+	streaming is in progress since most drivers do not support changing
+	the format in that case.
+
+
+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
+    The struct :ref:`v4l2_queryctrl <v4l2-queryctrl>` ``id`` is
+    invalid. The struct :ref:`v4l2_querymenu <v4l2-querymenu>` ``id``
+    is invalid or ``index`` is out of range (less than ``minimum`` or
+    greater than ``maximum``) or this particular menu item is not
+    supported by the driver.
+
+EACCES
+    An attempt was made to read a write-only control.
+
+.. [#f1]
+   ``V4L2_CTRL_FLAG_DISABLED`` was intended for two purposes: Drivers
+   can skip predefined controls not supported by the hardware (although
+   returning ``EINVAL`` would do as well), or disable predefined and private
+   controls after hardware detection without the trouble of reordering
+   control arrays and indices (``EINVAL`` cannot be used to skip private
+   controls because it would prematurely end the enumeration).
diff --git a/Documentation/userspace-api/media/v4l/vidioc-querystd.rst b/Documentation/userspace-api/media/v4l/vidioc-querystd.rst
new file mode 100644
index 000000000000..899f0ef6eefe
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-querystd.rst
@@ -0,0 +1,77 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_QUERYSTD:
+
+*********************************************
+ioctl VIDIOC_QUERYSTD, VIDIOC_SUBDEV_QUERYSTD
+*********************************************
+
+Name
+====
+
+VIDIOC_QUERYSTD - VIDIOC_SUBDEV_QUERYSTD - Sense the video standard received by the current input
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_QUERYSTD, v4l2_std_id *argp )
+    :name: VIDIOC_QUERYSTD
+
+.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_QUERYSTD, v4l2_std_id *argp )
+    :name: VIDIOC_SUBDEV_QUERYSTD
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to :c:type:`v4l2_std_id`.
+
+
+Description
+===========
+
+The hardware may be able to detect the current video standard
+automatically. To do so, applications call :ref:`VIDIOC_QUERYSTD` with a
+pointer to a :ref:`v4l2_std_id <v4l2-std-id>` type. The driver
+stores here a set of candidates, this can be a single flag or a set of
+supported standards if for example the hardware can only distinguish
+between 50 and 60 Hz systems. If no signal was detected, then the driver
+will return V4L2_STD_UNKNOWN. When detection is not possible or fails,
+the set must contain all standards supported by the current video input
+or output.
+
+.. note::
+
+   Drivers shall *not* switch the video standard
+   automatically if a new video standard is detected. Instead, drivers
+   should send the ``V4L2_EVENT_SOURCE_CHANGE`` event (if they support
+   this) and expect that userspace will take action by calling
+   :ref:`VIDIOC_QUERYSTD`. The reason is that a new video standard can mean
+   different buffer sizes as well, and you cannot change buffer sizes on
+   the fly. In general, applications that receive the Source Change event
+   will have to call :ref:`VIDIOC_QUERYSTD`, and if the detected video
+   standard is valid they will have to stop streaming, set the new
+   standard, allocate new buffers and start streaming again.
+
+
+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.
+
+ENODATA
+    Standard video timings are not supported for this input or output.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-reqbufs.rst b/Documentation/userspace-api/media/v4l/vidioc-reqbufs.rst
new file mode 100644
index 000000000000..79884bb4893b
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-reqbufs.rst
@@ -0,0 +1,169 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_REQBUFS:
+
+********************
+ioctl VIDIOC_REQBUFS
+********************
+
+Name
+====
+
+VIDIOC_REQBUFS - Initiate Memory Mapping, User Pointer I/O or DMA buffer I/O
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_REQBUFS, struct v4l2_requestbuffers *argp )
+    :name: VIDIOC_REQBUFS
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_requestbuffers`.
+
+Description
+===========
+
+This ioctl is used to initiate :ref:`memory mapped <mmap>`,
+:ref:`user pointer <userp>` or :ref:`DMABUF <dmabuf>` based 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:`v4l2_requestbuffers` structure. They set the ``type``
+field to the respective stream or buffer type, the ``count`` field to
+the desired number of buffers, ``memory`` must be set to the requested
+I/O method and the ``reserved`` array must be zeroed. 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. It 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. For example video output requires at least two
+buffers, one displayed and one filled by the application.
+
+When the I/O method is not supported the ioctl returns an ``EINVAL`` error
+code.
+
+Applications can call :ref:`VIDIOC_REQBUFS` again to change the number of
+buffers. Note that if any buffers are still mapped or exported via DMABUF,
+then :ref:`VIDIOC_REQBUFS` can only succeed if the
+``V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS`` capability is set. Otherwise
+:ref:`VIDIOC_REQBUFS` will return the ``EBUSY`` error code.
+If ``V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS`` is set, then these buffers are
+orphaned and will be freed when they are unmapped or when the exported DMABUF
+fds are closed. A ``count`` value of zero frees or orphans all buffers, after
+aborting or finishing any DMA in progress, an implicit
+:ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>`.
+
+
+.. c:type:: v4l2_requestbuffers
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. flat-table:: struct v4l2_requestbuffers
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``count``
+      - The number of buffers requested or granted.
+    * - __u32
+      - ``type``
+      - Type of the stream or buffers, this is the same as the struct
+	:c:type:`v4l2_format` ``type`` field. See
+	:c:type:`v4l2_buf_type` for valid values.
+    * - __u32
+      - ``memory``
+      - Applications set this field to ``V4L2_MEMORY_MMAP``,
+	``V4L2_MEMORY_DMABUF`` or ``V4L2_MEMORY_USERPTR``. See
+	:c:type:`v4l2_memory`.
+    * - __u32
+      - ``capabilities``
+      - Set by the driver. If 0, then the driver doesn't support
+        capabilities. In that case all you know is that the driver is
+	guaranteed to support ``V4L2_MEMORY_MMAP`` and *might* support
+	other :c:type:`v4l2_memory` types. It will not support any others
+	capabilities.
+
+	If you want to query the capabilities with a minimum of side-effects,
+	then this can be called with ``count`` set to 0, ``memory`` set to
+	``V4L2_MEMORY_MMAP`` and ``type`` set to the buffer type. This will
+	free any previously allocated buffers, so this is typically something
+	that will be done at the start of the application.
+    * - __u32
+      - ``reserved``\ [1]
+      - A place holder for future extensions. Drivers and applications
+	must set the array to zero.
+
+.. tabularcolumns:: |p{6.1cm}|p{2.2cm}|p{8.7cm}|
+
+.. _v4l2-buf-capabilities:
+.. _V4L2-BUF-CAP-SUPPORTS-MMAP:
+.. _V4L2-BUF-CAP-SUPPORTS-USERPTR:
+.. _V4L2-BUF-CAP-SUPPORTS-DMABUF:
+.. _V4L2-BUF-CAP-SUPPORTS-REQUESTS:
+.. _V4L2-BUF-CAP-SUPPORTS-ORPHANED-BUFS:
+.. _V4L2-BUF-CAP-SUPPORTS-M2M-HOLD-CAPTURE-BUF:
+
+.. cssclass:: longtable
+
+.. flat-table:: V4L2 Buffer Capabilities Flags
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_BUF_CAP_SUPPORTS_MMAP``
+      - 0x00000001
+      - This buffer type supports the ``V4L2_MEMORY_MMAP`` streaming mode.
+    * - ``V4L2_BUF_CAP_SUPPORTS_USERPTR``
+      - 0x00000002
+      - This buffer type supports the ``V4L2_MEMORY_USERPTR`` streaming mode.
+    * - ``V4L2_BUF_CAP_SUPPORTS_DMABUF``
+      - 0x00000004
+      - This buffer type supports the ``V4L2_MEMORY_DMABUF`` streaming mode.
+    * - ``V4L2_BUF_CAP_SUPPORTS_REQUESTS``
+      - 0x00000008
+      - This buffer type supports :ref:`requests <media-request-api>`.
+    * - ``V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS``
+      - 0x00000010
+      - The kernel allows calling :ref:`VIDIOC_REQBUFS` while buffers are still
+        mapped or exported via DMABUF. These orphaned buffers will be freed
+        when they are unmapped or when the exported DMABUF fds are closed.
+    * - ``V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF``
+      - 0x00000020
+      - Only valid for stateless decoders. If set, then userspace can set the
+        ``V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF`` flag to hold off on returning the
+	capture buffer until the OUTPUT timestamp changes.
+
+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
+    The buffer type (``type`` field) or the requested I/O method
+    (``memory``) is not supported.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-s-hw-freq-seek.rst b/Documentation/userspace-api/media/v4l/vidioc-s-hw-freq-seek.rst
new file mode 100644
index 000000000000..4c16e7e89cfa
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-s-hw-freq-seek.rst
@@ -0,0 +1,147 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_S_HW_FREQ_SEEK:
+
+***************************
+ioctl VIDIOC_S_HW_FREQ_SEEK
+***************************
+
+Name
+====
+
+VIDIOC_S_HW_FREQ_SEEK - Perform a hardware frequency seek
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_S_HW_FREQ_SEEK, struct v4l2_hw_freq_seek *argp )
+    :name: VIDIOC_S_HW_FREQ_SEEK
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_hw_freq_seek`.
+
+
+Description
+===========
+
+Start a hardware frequency seek from the current frequency. To do this
+applications initialize the ``tuner``, ``type``, ``seek_upward``,
+``wrap_around``, ``spacing``, ``rangelow`` and ``rangehigh`` fields, and
+zero out the ``reserved`` array of a struct
+:c:type:`v4l2_hw_freq_seek` and call the
+``VIDIOC_S_HW_FREQ_SEEK`` ioctl with a pointer to this structure.
+
+The ``rangelow`` and ``rangehigh`` fields can be set to a non-zero value
+to tell the driver to search a specific band. If the struct
+:c:type:`v4l2_tuner` ``capability`` field has the
+``V4L2_TUNER_CAP_HWSEEK_PROG_LIM`` flag set, these values must fall
+within one of the bands returned by
+:ref:`VIDIOC_ENUM_FREQ_BANDS`. If the
+``V4L2_TUNER_CAP_HWSEEK_PROG_LIM`` flag is not set, then these values
+must exactly match those of one of the bands returned by
+:ref:`VIDIOC_ENUM_FREQ_BANDS`. If the
+current frequency of the tuner does not fall within the selected band it
+will be clamped to fit in the band before the seek is started.
+
+If an error is returned, then the original frequency will be restored.
+
+This ioctl is supported if the ``V4L2_CAP_HW_FREQ_SEEK`` capability is
+set.
+
+If this ioctl is called from a non-blocking filehandle, then ``EAGAIN``
+error code is returned and no seek takes place.
+
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. c:type:: v4l2_hw_freq_seek
+
+.. flat-table:: struct v4l2_hw_freq_seek
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``tuner``
+      - The tuner index number. This is the same value as in the struct
+	:c:type:`v4l2_input` ``tuner`` field and the struct
+	:c:type:`v4l2_tuner` ``index`` field.
+    * - __u32
+      - ``type``
+      - The tuner type. This is the same value as in the struct
+	:c:type:`v4l2_tuner` ``type`` field. See
+	:c:type:`v4l2_tuner_type`
+    * - __u32
+      - ``seek_upward``
+      - If non-zero, seek upward from the current frequency, else seek
+	downward.
+    * - __u32
+      - ``wrap_around``
+      - If non-zero, wrap around when at the end of the frequency range,
+	else stop seeking. The struct :c:type:`v4l2_tuner`
+	``capability`` field will tell you what the hardware supports.
+    * - __u32
+      - ``spacing``
+      - If non-zero, defines the hardware seek resolution in Hz. The
+	driver selects the nearest value that is supported by the device.
+	If spacing is zero a reasonable default value is used.
+    * - __u32
+      - ``rangelow``
+      - If non-zero, the lowest tunable frequency of the band to search in
+	units of 62.5 kHz, or if the struct
+	:c:type:`v4l2_tuner` ``capability`` field has the
+	``V4L2_TUNER_CAP_LOW`` flag set, in units of 62.5 Hz or if the
+	struct :c:type:`v4l2_tuner` ``capability`` field has
+	the ``V4L2_TUNER_CAP_1HZ`` flag set, in units of 1 Hz. If
+	``rangelow`` is zero a reasonable default value is used.
+    * - __u32
+      - ``rangehigh``
+      - If non-zero, the highest tunable frequency of the band to search
+	in units of 62.5 kHz, or if the struct
+	:c:type:`v4l2_tuner` ``capability`` field has the
+	``V4L2_TUNER_CAP_LOW`` flag set, in units of 62.5 Hz or if the
+	struct :c:type:`v4l2_tuner` ``capability`` field has
+	the ``V4L2_TUNER_CAP_1HZ`` flag set, in units of 1 Hz. If
+	``rangehigh`` is zero a reasonable default value is used.
+    * - __u32
+      - ``reserved``\ [5]
+      - Reserved for future extensions. Applications must set the array to
+	zero.
+
+
+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
+    The ``tuner`` index is out of bounds, the ``wrap_around`` value is
+    not supported or one of the values in the ``type``, ``rangelow`` or
+    ``rangehigh`` fields is wrong.
+
+EAGAIN
+    Attempted to call ``VIDIOC_S_HW_FREQ_SEEK`` with the filehandle in
+    non-blocking mode.
+
+ENODATA
+    The hardware seek found no channels.
+
+EBUSY
+    Another hardware seek is already in progress.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-streamon.rst b/Documentation/userspace-api/media/v4l/vidioc-streamon.rst
new file mode 100644
index 000000000000..13e0136d5c25
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-streamon.rst
@@ -0,0 +1,113 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_STREAMON:
+
+***************************************
+ioctl VIDIOC_STREAMON, VIDIOC_STREAMOFF
+***************************************
+
+Name
+====
+
+VIDIOC_STREAMON - VIDIOC_STREAMOFF - Start or stop streaming I/O
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_STREAMON, const int *argp )
+    :name: VIDIOC_STREAMON
+
+.. c:function:: int ioctl( int fd, VIDIOC_STREAMOFF, const int *argp )
+    :name: VIDIOC_STREAMOFF
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to an integer.
+
+Description
+===========
+
+The ``VIDIOC_STREAMON`` and ``VIDIOC_STREAMOFF`` ioctl start and stop
+the capture or output process during streaming
+(:ref:`memory mapping <mmap>`, :ref:`user pointer <userp>` or
+:ref:`DMABUF <dmabuf>`) I/O.
+
+Capture hardware is disabled and no input buffers are filled (if there
+are any empty buffers in the incoming queue) until ``VIDIOC_STREAMON``
+has been called. Output hardware is disabled and no video signal is
+produced until ``VIDIOC_STREAMON`` has been called. The ioctl will
+succeed when at least one output buffer is in the incoming queue.
+
+Memory-to-memory devices will not start until ``VIDIOC_STREAMON`` has
+been called for both the capture and output stream types.
+
+If ``VIDIOC_STREAMON`` fails then any already queued buffers will remain
+queued.
+
+The ``VIDIOC_STREAMOFF`` ioctl, apart of aborting or finishing any DMA
+in progress, unlocks any user pointer buffers locked in physical memory,
+and it removes all buffers from the incoming and outgoing queues. That
+means all images captured but not dequeued yet will be lost, likewise
+all images enqueued for output but not transmitted yet. I/O returns to
+the same state as after calling
+:ref:`VIDIOC_REQBUFS` and can be restarted
+accordingly.
+
+If buffers have been queued with :ref:`VIDIOC_QBUF` and
+``VIDIOC_STREAMOFF`` is called without ever having called
+``VIDIOC_STREAMON``, then those queued buffers will also be removed from
+the incoming queue and all are returned to the same state as after
+calling :ref:`VIDIOC_REQBUFS` and can be restarted
+accordingly.
+
+Both ioctls take a pointer to an integer, the desired buffer or stream
+type. This is the same as struct
+:c:type:`v4l2_requestbuffers` ``type``.
+
+If ``VIDIOC_STREAMON`` is called when streaming is already in progress,
+or if ``VIDIOC_STREAMOFF`` is called when streaming is already stopped,
+then 0 is returned. Nothing happens in the case of ``VIDIOC_STREAMON``,
+but ``VIDIOC_STREAMOFF`` will return queued buffers to their starting
+state as mentioned above.
+
+.. note::
+
+   Applications can be preempted for unknown periods right before
+   or after the ``VIDIOC_STREAMON`` or ``VIDIOC_STREAMOFF`` calls, there is
+   no notion of starting or stopping "now". Buffer timestamps can be used
+   to synchronize with other events.
+
+
+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
+    The buffer ``type`` is not supported, or no buffers have been
+    allocated (memory mapping) or enqueued (output) yet.
+
+EPIPE
+    The driver implements
+    :ref:`pad-level format configuration <pad-level-formats>` and the
+    pipeline configuration is invalid.
+
+ENOLINK
+    The driver implements Media Controller interface and the pipeline
+    link configuration is invalid.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-subdev-enum-frame-interval.rst b/Documentation/userspace-api/media/v4l/vidioc-subdev-enum-frame-interval.rst
new file mode 100644
index 000000000000..3527745935c7
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-subdev-enum-frame-interval.rst
@@ -0,0 +1,120 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL:
+
+***************************************
+ioctl VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL
+***************************************
+
+Name
+====
+
+VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL - Enumerate frame intervals
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL, struct v4l2_subdev_frame_interval_enum * argp )
+    :name: VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_subdev_frame_interval_enum`.
+
+
+Description
+===========
+
+This ioctl lets applications enumerate available frame intervals on a
+given sub-device pad. Frame intervals only makes sense for sub-devices
+that can control the frame period on their own. This includes, for
+instance, image sensors and TV tuners.
+
+For the common use case of image sensors, the frame intervals available
+on the sub-device output pad depend on the frame format and size on the
+same pad. Applications must thus specify the desired format and size
+when enumerating frame intervals.
+
+To enumerate frame intervals applications initialize the ``index``,
+``pad``, ``which``, ``code``, ``width`` and ``height`` fields of struct
+:c:type:`v4l2_subdev_frame_interval_enum`
+and call the :ref:`VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL` ioctl with a pointer
+to this structure. Drivers fill the rest of the structure or return an
+EINVAL error code if one of the input fields is invalid. All frame
+intervals are enumerable by beginning at index zero and incrementing by
+one until ``EINVAL`` is returned.
+
+Available frame intervals may depend on the current 'try' formats at
+other pads of the sub-device, as well as on the current active links.
+See :ref:`VIDIOC_SUBDEV_G_FMT` for more
+information about the try formats.
+
+Sub-devices that support the frame interval enumeration ioctl should
+implemented it on a single pad only. Its behaviour when supported on
+multiple pads of the same sub-device is not defined.
+
+.. c:type:: v4l2_subdev_frame_interval_enum
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. flat-table:: struct v4l2_subdev_frame_interval_enum
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``index``
+      - Number of the format in the enumeration, set by the application.
+    * - __u32
+      - ``pad``
+      - Pad number as reported by the media controller API.
+    * - __u32
+      - ``code``
+      - The media bus format code, as defined in
+	:ref:`v4l2-mbus-format`.
+    * - __u32
+      - ``width``
+      - Frame width, in pixels.
+    * - __u32
+      - ``height``
+      - Frame height, in pixels.
+    * - struct :c:type:`v4l2_fract`
+      - ``interval``
+      - Period, in seconds, between consecutive video frames.
+    * - __u32
+      - ``which``
+      - Frame intervals to be enumerated, from enum
+	:ref:`v4l2_subdev_format_whence <v4l2-subdev-format-whence>`.
+    * - __u32
+      - ``reserved``\ [8]
+      - Reserved for future extensions. Applications and drivers must set
+	the array to zero.
+
+
+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
+    The struct
+    :c:type:`v4l2_subdev_frame_interval_enum`
+    ``pad`` references a non-existing pad, one of the ``code``,
+    ``width`` or ``height`` fields are invalid for the given pad or the
+    ``index`` field is out of bounds.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-subdev-enum-frame-size.rst b/Documentation/userspace-api/media/v4l/vidioc-subdev-enum-frame-size.rst
new file mode 100644
index 000000000000..eb7401991d02
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-subdev-enum-frame-size.rst
@@ -0,0 +1,125 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_SUBDEV_ENUM_FRAME_SIZE:
+
+***********************************
+ioctl VIDIOC_SUBDEV_ENUM_FRAME_SIZE
+***********************************
+
+Name
+====
+
+VIDIOC_SUBDEV_ENUM_FRAME_SIZE - Enumerate media bus frame sizes
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_ENUM_FRAME_SIZE, struct v4l2_subdev_frame_size_enum * argp )
+    :name: VIDIOC_SUBDEV_ENUM_FRAME_SIZE
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_subdev_frame_size_enum`.
+
+
+Description
+===========
+
+This ioctl allows applications to enumerate all frame sizes supported by
+a sub-device on the given pad for the given media bus format. Supported
+formats can be retrieved with the
+:ref:`VIDIOC_SUBDEV_ENUM_MBUS_CODE`
+ioctl.
+
+To enumerate frame sizes applications initialize the ``pad``, ``which``
+, ``code`` and ``index`` fields of the struct
+:c:type:`v4l2_subdev_mbus_code_enum` and
+call the :ref:`VIDIOC_SUBDEV_ENUM_FRAME_SIZE` ioctl with a pointer to the
+structure. Drivers fill the minimum and maximum frame sizes or return an
+EINVAL error code if one of the input parameters is invalid.
+
+Sub-devices that only support discrete frame sizes (such as most
+sensors) will return one or more frame sizes with identical minimum and
+maximum values.
+
+Not all possible sizes in given [minimum, maximum] ranges need to be
+supported. For instance, a scaler that uses a fixed-point scaling ratio
+might not be able to produce every frame size between the minimum and
+maximum values. Applications must use the
+:ref:`VIDIOC_SUBDEV_S_FMT <VIDIOC_SUBDEV_G_FMT>` ioctl to try the
+sub-device for an exact supported frame size.
+
+Available frame sizes may depend on the current 'try' formats at other
+pads of the sub-device, as well as on the current active links and the
+current values of V4L2 controls. See
+:ref:`VIDIOC_SUBDEV_G_FMT` for more
+information about try formats.
+
+
+.. c:type:: v4l2_subdev_frame_size_enum
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. flat-table:: struct v4l2_subdev_frame_size_enum
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``index``
+      - Number of the format in the enumeration, set by the application.
+    * - __u32
+      - ``pad``
+      - Pad number as reported by the media controller API.
+    * - __u32
+      - ``code``
+      - The media bus format code, as defined in
+	:ref:`v4l2-mbus-format`.
+    * - __u32
+      - ``min_width``
+      - Minimum frame width, in pixels.
+    * - __u32
+      - ``max_width``
+      - Maximum frame width, in pixels.
+    * - __u32
+      - ``min_height``
+      - Minimum frame height, in pixels.
+    * - __u32
+      - ``max_height``
+      - Maximum frame height, in pixels.
+    * - __u32
+      - ``which``
+      - Frame sizes to be enumerated, from enum
+	:ref:`v4l2_subdev_format_whence <v4l2-subdev-format-whence>`.
+    * - __u32
+      - ``reserved``\ [8]
+      - Reserved for future extensions. Applications and drivers must set
+	the array to zero.
+
+
+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
+    The struct
+    :c:type:`v4l2_subdev_frame_size_enum`
+    ``pad`` references a non-existing pad, the ``code`` is invalid for
+    the given pad or the ``index`` field is out of bounds.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-subdev-enum-mbus-code.rst b/Documentation/userspace-api/media/v4l/vidioc-subdev-enum-mbus-code.rst
new file mode 100644
index 000000000000..35b8607203a4
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-subdev-enum-mbus-code.rst
@@ -0,0 +1,98 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_SUBDEV_ENUM_MBUS_CODE:
+
+**********************************
+ioctl VIDIOC_SUBDEV_ENUM_MBUS_CODE
+**********************************
+
+Name
+====
+
+VIDIOC_SUBDEV_ENUM_MBUS_CODE - Enumerate media bus formats
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_ENUM_MBUS_CODE, struct v4l2_subdev_mbus_code_enum * argp )
+    :name: VIDIOC_SUBDEV_ENUM_MBUS_CODE
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_subdev_mbus_code_enum`.
+
+
+Description
+===========
+
+To enumerate media bus formats available at a given sub-device pad
+applications initialize the ``pad``, ``which`` and ``index`` fields of
+struct
+:c:type:`v4l2_subdev_mbus_code_enum` and
+call the :ref:`VIDIOC_SUBDEV_ENUM_MBUS_CODE` ioctl with a pointer to this
+structure. Drivers fill the rest of the structure or return an ``EINVAL``
+error code if either the ``pad`` or ``index`` are invalid. All media bus
+formats are enumerable by beginning at index zero and incrementing by
+one until ``EINVAL`` is returned.
+
+Available media bus formats may depend on the current 'try' formats at
+other pads of the sub-device, as well as on the current active links.
+See :ref:`VIDIOC_SUBDEV_G_FMT` for more
+information about the try formats.
+
+
+.. c:type:: v4l2_subdev_mbus_code_enum
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. flat-table:: struct v4l2_subdev_mbus_code_enum
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``pad``
+      - Pad number as reported by the media controller API.
+    * - __u32
+      - ``index``
+      - Number of the format in the enumeration, set by the application.
+    * - __u32
+      - ``code``
+      - The media bus format code, as defined in
+	:ref:`v4l2-mbus-format`.
+    * - __u32
+      - ``which``
+      - Media bus format codes to be enumerated, from enum
+	:ref:`v4l2_subdev_format_whence <v4l2-subdev-format-whence>`.
+    * - __u32
+      - ``reserved``\ [8]
+      - Reserved for future extensions. Applications and drivers must set
+	the array to zero.
+
+
+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
+    The struct
+    :c:type:`v4l2_subdev_mbus_code_enum`
+    ``pad`` references a non-existing pad, or the ``index`` field is out
+    of bounds.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-subdev-g-crop.rst b/Documentation/userspace-api/media/v4l/vidioc-subdev-g-crop.rst
new file mode 100644
index 000000000000..8d9fc13015a6
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-subdev-g-crop.rst
@@ -0,0 +1,125 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_SUBDEV_G_CROP:
+
+************************************************
+ioctl VIDIOC_SUBDEV_G_CROP, VIDIOC_SUBDEV_S_CROP
+************************************************
+
+Name
+====
+
+VIDIOC_SUBDEV_G_CROP - VIDIOC_SUBDEV_S_CROP - Get or set the crop rectangle on a subdev pad
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_G_CROP, struct v4l2_subdev_crop *argp )
+    :name: VIDIOC_SUBDEV_G_CROP
+
+.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_S_CROP, const struct v4l2_subdev_crop *argp )
+    :name: VIDIOC_SUBDEV_S_CROP
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_subdev_crop`.
+
+
+Description
+===========
+
+.. note::
+
+    This is an :ref:`obsolete` interface and may be removed
+    in the future. It is superseded by
+    :ref:`the selection API <VIDIOC_SUBDEV_G_SELECTION>`.
+
+To retrieve the current crop rectangle applications set the ``pad``
+field of a struct :c:type:`v4l2_subdev_crop` to the
+desired pad number as reported by the media API and the ``which`` field
+to ``V4L2_SUBDEV_FORMAT_ACTIVE``. They then call the
+``VIDIOC_SUBDEV_G_CROP`` ioctl with a pointer to this structure. The
+driver fills the members of the ``rect`` field or returns ``EINVAL`` error
+code if the input arguments are invalid, or if cropping is not supported
+on the given pad.
+
+To change the current crop rectangle applications set both the ``pad``
+and ``which`` fields and all members of the ``rect`` field. They then
+call the ``VIDIOC_SUBDEV_S_CROP`` ioctl with a pointer to this
+structure. The driver verifies the requested crop rectangle, adjusts it
+based on the hardware capabilities and configures the device. Upon
+return the struct :c:type:`v4l2_subdev_crop`
+contains the current format as would be returned by a
+``VIDIOC_SUBDEV_G_CROP`` call.
+
+Applications can query the device capabilities by setting the ``which``
+to ``V4L2_SUBDEV_FORMAT_TRY``. When set, 'try' crop rectangles are not
+applied to the device by the driver, but are mangled exactly as active
+crop rectangles and stored in the sub-device file handle. Two
+applications querying the same sub-device would thus not interact with
+each other.
+
+Drivers must not return an error solely because the requested crop
+rectangle doesn't match the device capabilities. They must instead
+modify the rectangle to match what the hardware can provide. The
+modified format should be as close as possible to the original request.
+
+
+.. c:type:: v4l2_subdev_crop
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. flat-table:: struct v4l2_subdev_crop
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``pad``
+      - Pad number as reported by the media framework.
+    * - __u32
+      - ``which``
+      - Crop rectangle to get or set, from enum
+	:ref:`v4l2_subdev_format_whence <v4l2-subdev-format-whence>`.
+    * - struct :c:type:`v4l2_rect`
+      - ``rect``
+      - Crop rectangle boundaries, in pixels.
+    * - __u32
+      - ``reserved``\ [8]
+      - Reserved for future extensions. Applications and drivers must set
+	the array to zero.
+
+
+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.
+
+EBUSY
+    The crop rectangle can't be changed because the pad is currently
+    busy. This can be caused, for instance, by an active video stream on
+    the pad. The ioctl must not be retried without performing another
+    action to fix the problem first. Only returned by
+    ``VIDIOC_SUBDEV_S_CROP``
+
+EINVAL
+    The struct :c:type:`v4l2_subdev_crop` ``pad``
+    references a non-existing pad, the ``which`` field references a
+    non-existing format, or cropping is not supported on the given
+    subdev pad.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-subdev-g-fmt.rst b/Documentation/userspace-api/media/v4l/vidioc-subdev-g-fmt.rst
new file mode 100644
index 000000000000..69d60e18664b
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-subdev-g-fmt.rst
@@ -0,0 +1,154 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_SUBDEV_G_FMT:
+
+**********************************************
+ioctl VIDIOC_SUBDEV_G_FMT, VIDIOC_SUBDEV_S_FMT
+**********************************************
+
+Name
+====
+
+VIDIOC_SUBDEV_G_FMT - VIDIOC_SUBDEV_S_FMT - Get or set the data format on a subdev pad
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_G_FMT, struct v4l2_subdev_format *argp )
+    :name: VIDIOC_SUBDEV_G_FMT
+
+.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_S_FMT, struct v4l2_subdev_format *argp )
+    :name: VIDIOC_SUBDEV_S_FMT
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_subdev_format`.
+
+
+Description
+===========
+
+These ioctls are used to negotiate the frame format at specific subdev
+pads in the image pipeline.
+
+To retrieve the current format applications set the ``pad`` field of a
+struct :c:type:`v4l2_subdev_format` to the desired
+pad number as reported by the media API and the ``which`` field to
+``V4L2_SUBDEV_FORMAT_ACTIVE``. When they call the
+``VIDIOC_SUBDEV_G_FMT`` ioctl with a pointer to this structure the
+driver fills the members of the ``format`` field.
+
+To change the current format applications set both the ``pad`` and
+``which`` fields and all members of the ``format`` field. When they call
+the ``VIDIOC_SUBDEV_S_FMT`` ioctl with a pointer to this structure the
+driver verifies the requested format, adjusts it based on the hardware
+capabilities and configures the device. Upon return the struct
+:c:type:`v4l2_subdev_format` contains the current
+format as would be returned by a ``VIDIOC_SUBDEV_G_FMT`` call.
+
+Applications can query the device capabilities by setting the ``which``
+to ``V4L2_SUBDEV_FORMAT_TRY``. When set, 'try' formats are not applied
+to the device by the driver, but are changed exactly as active formats
+and stored in the sub-device file handle. Two applications querying the
+same sub-device would thus not interact with each other.
+
+For instance, to try a format at the output pad of a sub-device,
+applications would first set the try format at the sub-device input with
+the ``VIDIOC_SUBDEV_S_FMT`` ioctl. They would then either retrieve the
+default format at the output pad with the ``VIDIOC_SUBDEV_G_FMT`` ioctl,
+or set the desired output pad format with the ``VIDIOC_SUBDEV_S_FMT``
+ioctl and check the returned value.
+
+Try formats do not depend on active formats, but can depend on the
+current links configuration or sub-device controls value. For instance,
+a low-pass noise filter might crop pixels at the frame boundaries,
+modifying its output frame size.
+
+Drivers must not return an error solely because the requested format
+doesn't match the device capabilities. They must instead modify the
+format to match what the hardware can provide. The modified format
+should be as close as possible to the original request.
+
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. c:type:: v4l2_subdev_format
+
+.. flat-table:: struct v4l2_subdev_format
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``pad``
+      - Pad number as reported by the media controller API.
+    * - __u32
+      - ``which``
+      - Format to modified, from enum
+	:ref:`v4l2_subdev_format_whence <v4l2-subdev-format-whence>`.
+    * - struct :c:type:`v4l2_mbus_framefmt`
+      - ``format``
+      - Definition of an image format, see :c:type:`v4l2_mbus_framefmt` for
+	details.
+    * - __u32
+      - ``reserved``\ [8]
+      - Reserved for future extensions. Applications and drivers must set
+	the array to zero.
+
+
+
+.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
+
+.. _v4l2-subdev-format-whence:
+
+.. flat-table:: enum v4l2_subdev_format_whence
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - V4L2_SUBDEV_FORMAT_TRY
+      - 0
+      - Try formats, used for querying device capabilities.
+    * - V4L2_SUBDEV_FORMAT_ACTIVE
+      - 1
+      - Active formats, applied to the hardware.
+
+
+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.
+
+EBUSY
+    The format can't be changed because the pad is currently busy. This
+    can be caused, for instance, by an active video stream on the pad.
+    The ioctl must not be retried without performing another action to
+    fix the problem first. Only returned by ``VIDIOC_SUBDEV_S_FMT``
+
+EINVAL
+    The struct :c:type:`v4l2_subdev_format`
+    ``pad`` references a non-existing pad, or the ``which`` field
+    references a non-existing format.
+
+
+============
+
+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/userspace-api/media/v4l/vidioc-subdev-g-frame-interval.rst b/Documentation/userspace-api/media/v4l/vidioc-subdev-g-frame-interval.rst
new file mode 100644
index 000000000000..b61baaf11624
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-subdev-g-frame-interval.rst
@@ -0,0 +1,120 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_SUBDEV_G_FRAME_INTERVAL:
+
+********************************************************************
+ioctl VIDIOC_SUBDEV_G_FRAME_INTERVAL, VIDIOC_SUBDEV_S_FRAME_INTERVAL
+********************************************************************
+
+Name
+====
+
+VIDIOC_SUBDEV_G_FRAME_INTERVAL - VIDIOC_SUBDEV_S_FRAME_INTERVAL - Get or set the frame interval on a subdev pad
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_G_FRAME_INTERVAL, struct v4l2_subdev_frame_interval *argp )
+    :name: VIDIOC_SUBDEV_G_FRAME_INTERVAL
+
+.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_S_FRAME_INTERVAL, struct v4l2_subdev_frame_interval *argp )
+    :name: VIDIOC_SUBDEV_S_FRAME_INTERVAL
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_subdev_frame_interval`.
+
+
+Description
+===========
+
+These ioctls are used to get and set the frame interval at specific
+subdev pads in the image pipeline. The frame interval only makes sense
+for sub-devices that can control the frame period on their own. This
+includes, for instance, image sensors and TV tuners. Sub-devices that
+don't support frame intervals must not implement these ioctls.
+
+To retrieve the current frame interval applications set the ``pad``
+field of a struct
+:c:type:`v4l2_subdev_frame_interval` to
+the desired pad number as reported by the media controller API. When
+they call the ``VIDIOC_SUBDEV_G_FRAME_INTERVAL`` ioctl with a pointer to
+this structure the driver fills the members of the ``interval`` field.
+
+To change the current frame interval applications set both the ``pad``
+field and all members of the ``interval`` field. When they call the
+``VIDIOC_SUBDEV_S_FRAME_INTERVAL`` ioctl with a pointer to this
+structure the driver verifies the requested interval, adjusts it based
+on the hardware capabilities and configures the device. Upon return the
+struct
+:c:type:`v4l2_subdev_frame_interval`
+contains the current frame interval as would be returned by a
+``VIDIOC_SUBDEV_G_FRAME_INTERVAL`` call.
+
+Drivers must not return an error solely because the requested interval
+doesn't match the device capabilities. They must instead modify the
+interval to match what the hardware can provide. The modified interval
+should be as close as possible to the original request.
+
+Changing the frame interval shall never change the format. Changing the
+format, on the other hand, may change the frame interval.
+
+Sub-devices that support the frame interval ioctls should implement them
+on a single pad only. Their behaviour when supported on multiple pads of
+the same sub-device is not defined.
+
+
+.. c:type:: v4l2_subdev_frame_interval
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. flat-table:: struct v4l2_subdev_frame_interval
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``pad``
+      - Pad number as reported by the media controller API.
+    * - struct :c:type:`v4l2_fract`
+      - ``interval``
+      - Period, in seconds, between consecutive video frames.
+    * - __u32
+      - ``reserved``\ [9]
+      - Reserved for future extensions. Applications and drivers must set
+	the array to zero.
+
+
+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.
+
+EBUSY
+    The frame interval can't be changed because the pad is currently
+    busy. This can be caused, for instance, by an active video stream on
+    the pad. The ioctl must not be retried without performing another
+    action to fix the problem first. Only returned by
+    ``VIDIOC_SUBDEV_S_FRAME_INTERVAL``
+
+EINVAL
+    The struct
+    :c:type:`v4l2_subdev_frame_interval`
+    ``pad`` references a non-existing pad, or the pad doesn't support
+    frame intervals.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-subdev-g-selection.rst b/Documentation/userspace-api/media/v4l/vidioc-subdev-g-selection.rst
new file mode 100644
index 000000000000..981c95df2dec
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-subdev-g-selection.rst
@@ -0,0 +1,125 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_SUBDEV_G_SELECTION:
+
+**********************************************************
+ioctl VIDIOC_SUBDEV_G_SELECTION, VIDIOC_SUBDEV_S_SELECTION
+**********************************************************
+
+Name
+====
+
+VIDIOC_SUBDEV_G_SELECTION - VIDIOC_SUBDEV_S_SELECTION - Get or set selection rectangles on a subdev pad
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_G_SELECTION, struct v4l2_subdev_selection *argp )
+    :name: VIDIOC_SUBDEV_G_SELECTION
+
+.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_S_SELECTION, struct v4l2_subdev_selection *argp )
+    :name: VIDIOC_SUBDEV_S_SELECTION
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_subdev_selection`.
+
+
+Description
+===========
+
+The selections are used to configure various image processing
+functionality performed by the subdevs which affect the image size. This
+currently includes cropping, scaling and composition.
+
+The selection API replaces
+:ref:`the old subdev crop API <VIDIOC_SUBDEV_G_CROP>`. All the
+function of the crop API, and more, are supported by the selections API.
+
+See :ref:`subdev` for more information on how each selection target
+affects the image processing pipeline inside the subdevice.
+
+
+Types of selection targets
+--------------------------
+
+There are two types of selection targets: actual and bounds. The actual
+targets are the targets which configure the hardware. The BOUNDS target
+will return a rectangle that contain all possible actual rectangles.
+
+
+Discovering supported features
+------------------------------
+
+To discover which targets are supported, the user can perform
+``VIDIOC_SUBDEV_G_SELECTION`` on them. Any unsupported target will
+return ``EINVAL``.
+
+Selection targets and flags are documented in
+:ref:`v4l2-selections-common`.
+
+
+.. c:type:: v4l2_subdev_selection
+
+.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
+
+.. flat-table:: struct v4l2_subdev_selection
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``which``
+      - Active or try selection, from enum
+	:ref:`v4l2_subdev_format_whence <v4l2-subdev-format-whence>`.
+    * - __u32
+      - ``pad``
+      - Pad number as reported by the media framework.
+    * - __u32
+      - ``target``
+      - Target selection rectangle. See :ref:`v4l2-selections-common`.
+    * - __u32
+      - ``flags``
+      - Flags. See :ref:`v4l2-selection-flags`.
+    * - struct :c:type:`v4l2_rect`
+      - ``r``
+      - Selection rectangle, in pixels.
+    * - __u32
+      - ``reserved``\ [8]
+      - Reserved for future extensions. Applications and drivers must set
+	the array to zero.
+
+
+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.
+
+EBUSY
+    The selection rectangle can't be changed because the pad is
+    currently busy. This can be caused, for instance, by an active video
+    stream on the pad. The ioctl must not be retried without performing
+    another action to fix the problem first. Only returned by
+    ``VIDIOC_SUBDEV_S_SELECTION``
+
+EINVAL
+    The struct :c:type:`v4l2_subdev_selection`
+    ``pad`` references a non-existing pad, the ``which`` field
+    references a non-existing format, or the selection target is not
+    supported on the given subdev pad.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-subscribe-event.rst b/Documentation/userspace-api/media/v4l/vidioc-subscribe-event.rst
new file mode 100644
index 000000000000..ae3ed73c0a9e
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/vidioc-subscribe-event.rst
@@ -0,0 +1,123 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _VIDIOC_SUBSCRIBE_EVENT:
+.. _VIDIOC_UNSUBSCRIBE_EVENT:
+
+******************************************************
+ioctl VIDIOC_SUBSCRIBE_EVENT, VIDIOC_UNSUBSCRIBE_EVENT
+******************************************************
+
+Name
+====
+
+VIDIOC_SUBSCRIBE_EVENT - VIDIOC_UNSUBSCRIBE_EVENT - Subscribe or unsubscribe event
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, VIDIOC_SUBSCRIBE_EVENT, struct v4l2_event_subscription *argp )
+    :name: VIDIOC_SUBSCRIBE_EVENT
+
+.. c:function:: int ioctl( int fd, VIDIOC_UNSUBSCRIBE_EVENT, struct v4l2_event_subscription *argp )
+    :name: VIDIOC_UNSUBSCRIBE_EVENT
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <func-open>`.
+
+``argp``
+    Pointer to struct :c:type:`v4l2_event_subscription`.
+
+
+Description
+===========
+
+Subscribe or unsubscribe V4L2 event. Subscribed events are dequeued by
+using the :ref:`VIDIOC_DQEVENT` ioctl.
+
+
+.. tabularcolumns:: |p{4.6cm}|p{4.4cm}|p{8.7cm}|
+
+.. c:type:: v4l2_event_subscription
+
+.. flat-table:: struct v4l2_event_subscription
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``type``
+      - Type of the event, see :ref:`event-type`.
+
+	.. note::
+
+	   ``V4L2_EVENT_ALL`` can be used with
+	   :ref:`VIDIOC_UNSUBSCRIBE_EVENT <VIDIOC_SUBSCRIBE_EVENT>` for
+	   unsubscribing all events at once.
+    * - __u32
+      - ``id``
+      - ID of the event source. If there is no ID associated with the
+	event source, then set this to 0. Whether or not an event needs an
+	ID depends on the event type.
+    * - __u32
+      - ``flags``
+      - Event flags, see :ref:`event-flags`.
+    * - __u32
+      - ``reserved``\ [5]
+      - Reserved for future extensions. Drivers and applications must set
+	the array to zero.
+
+
+
+.. tabularcolumns:: |p{6.8cm}|p{2.2cm}|p{8.5cm}|
+
+.. _event-flags:
+
+.. flat-table:: Event Flags
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_EVENT_SUB_FL_SEND_INITIAL``
+      - 0x0001
+      - When this event is subscribed an initial event will be sent
+	containing the current status. This only makes sense for events
+	that are triggered by a status change such as ``V4L2_EVENT_CTRL``.
+	Other events will ignore this flag.
+    * - ``V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK``
+      - 0x0002
+      - If set, then events directly caused by an ioctl will also be sent
+	to the filehandle that called that ioctl. For example, changing a
+	control using :ref:`VIDIOC_S_CTRL <VIDIOC_G_CTRL>` will cause
+	a V4L2_EVENT_CTRL to be sent back to that same filehandle.
+	Normally such events are suppressed to prevent feedback loops
+	where an application changes a control to a one value and then
+	another, and then receives an event telling it that that control
+	has changed to the first value.
+
+	Since it can't tell whether that event was caused by another
+	application or by the :ref:`VIDIOC_S_CTRL <VIDIOC_G_CTRL>`
+	call it is hard to decide whether to set the control to the value
+	in the event, or ignore it.
+
+	Think carefully when you set this flag so you won't get into
+	situations like that.
+
+
+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/userspace-api/media/v4l/yuv-formats.rst b/Documentation/userspace-api/media/v4l/yuv-formats.rst
new file mode 100644
index 000000000000..8ee92d0cd769
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/yuv-formats.rst
@@ -0,0 +1,64 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/userspace-api/media/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _yuv-formats:
+
+***********
+YUV Formats
+***********
+
+YUV is the format native to TV broadcast and composite video signals. It
+separates the brightness information (Y) from the color information (U
+and V or Cb and Cr). The color information consists of red and blue
+*color difference* signals, this way the green component can be
+reconstructed by subtracting from the brightness component. See
+:ref:`colorspaces` for conversion examples. YUV was chosen because
+early television would only transmit brightness information. To add
+color in a way compatible with existing receivers a new signal carrier
+was added to transmit the color difference signals. Secondary in the YUV
+format the U and V components usually have lower resolution than the Y
+component. This is an analog video compression technique taking
+advantage of a property of the human visual system, being more sensitive
+to brightness information.
+
+
+.. toctree::
+    :maxdepth: 1
+
+    pixfmt-packed-yuv
+    pixfmt-grey
+    pixfmt-y10
+    pixfmt-y12
+    pixfmt-y14
+    pixfmt-y10b
+    pixfmt-y10p
+    pixfmt-y16
+    pixfmt-y16-be
+    pixfmt-y8i
+    pixfmt-y12i
+    pixfmt-uv8
+    pixfmt-yuyv
+    pixfmt-uyvy
+    pixfmt-yvyu
+    pixfmt-vyuy
+    pixfmt-y41p
+    pixfmt-yuv420
+    pixfmt-yuv420m
+    pixfmt-yuv422m
+    pixfmt-yuv444m
+    pixfmt-yuv410
+    pixfmt-yuv422p
+    pixfmt-yuv411p
+    pixfmt-nv12
+    pixfmt-nv12m
+    pixfmt-nv12mt
+    pixfmt-nv16
+    pixfmt-nv16m
+    pixfmt-nv24
+    pixfmt-m420
diff --git a/Documentation/userspace-api/media/video.h.rst.exceptions b/Documentation/userspace-api/media/video.h.rst.exceptions
new file mode 100644
index 000000000000..ea9de59ad8b7
--- /dev/null
+++ b/Documentation/userspace-api/media/video.h.rst.exceptions
@@ -0,0 +1,39 @@
+# SPDX-License-Identifier: GPL-2.0
+
+# Ignore header name
+ignore define _UAPI_DVBVIDEO_H_
+
+# This is a deprecated obscure API. Just ignore things we don't know
+ignore define VIDEO_CMD_PLAY
+ignore define VIDEO_CMD_STOP
+ignore define VIDEO_CMD_FREEZE
+ignore define VIDEO_CMD_CONTINUE
+ignore define VIDEO_CMD_FREEZE_TO_BLACK
+ignore define VIDEO_CMD_STOP_TO_BLACK
+ignore define VIDEO_CMD_STOP_IMMEDIATELY
+ignore define VIDEO_PLAY_FMT_NONE
+ignore define VIDEO_PLAY_FMT_GOP
+ignore define VIDEO_VSYNC_FIELD_UNKNOWN
+ignore define VIDEO_VSYNC_FIELD_ODD
+ignore define VIDEO_VSYNC_FIELD_EVEN
+ignore define VIDEO_VSYNC_FIELD_PROGRESSIVE
+ignore define VIDEO_EVENT_SIZE_CHANGED
+ignore define VIDEO_EVENT_FRAME_RATE_CHANGED
+ignore define VIDEO_EVENT_DECODER_STOPPED
+ignore define VIDEO_EVENT_VSYNC
+ignore define VIDEO_CAP_MPEG1
+ignore define VIDEO_CAP_MPEG2
+ignore define VIDEO_CAP_SYS
+ignore define VIDEO_CAP_PROG
+ignore define VIDEO_CAP_SPU
+ignore define VIDEO_CAP_NAVI
+ignore define VIDEO_CAP_CSS
+
+# some typedefs should point to struct/enums
+replace typedef video_format_t :c:type:`video_format`
+replace typedef video_system_t :c:type:`video_system`
+replace typedef video_displayformat_t :c:type:`video_displayformat`
+replace typedef video_size_t :c:type:`video_size`
+replace typedef video_stream_source_t :c:type:`video_stream_source`
+replace typedef video_play_state_t :c:type:`video_play_state`
+replace typedef video_navi_pack_t :c:type:`video_navi_pack`
diff --git a/Documentation/userspace-api/media/videodev2.h.rst.exceptions b/Documentation/userspace-api/media/videodev2.h.rst.exceptions
new file mode 100644
index 000000000000..cb6ccf91776e
--- /dev/null
+++ b/Documentation/userspace-api/media/videodev2.h.rst.exceptions
@@ -0,0 +1,572 @@
+# SPDX-License-Identifier: GPL-2.0
+
+# Ignore header name
+ignore define _UAPI__LINUX_VIDEODEV2_H
+
+#
+# The cross reference valitator for videodev2.h DocBook never cared
+# about enum symbols or defines. Yet, they're all (or almost all?)
+# handled inside V4L API sections. So, for now, it is safe to just
+# ignore. This should be revisited, as validating it helps to avoid
+# having something not documented at the uAPI.
+#
+
+# Those symbols should not be used by uAPI - don't document them
+ignore symbol V4L2_BUF_TYPE_PRIVATE
+ignore symbol V4L2_TUNER_DIGITAL_TV
+ignore symbol V4L2_COLORSPACE_BT878
+
+# Documented enum v4l2_field
+replace symbol V4L2_FIELD_ALTERNATE :c:type:`v4l2_field`
+replace symbol V4L2_FIELD_ANY :c:type:`v4l2_field`
+replace symbol V4L2_FIELD_BOTTOM :c:type:`v4l2_field`
+replace symbol V4L2_FIELD_INTERLACED :c:type:`v4l2_field`
+replace symbol V4L2_FIELD_INTERLACED_BT :c:type:`v4l2_field`
+replace symbol V4L2_FIELD_INTERLACED_TB :c:type:`v4l2_field`
+replace symbol V4L2_FIELD_NONE :c:type:`v4l2_field`
+replace symbol V4L2_FIELD_SEQ_BT :c:type:`v4l2_field`
+replace symbol V4L2_FIELD_SEQ_TB :c:type:`v4l2_field`
+replace symbol V4L2_FIELD_TOP :c:type:`v4l2_field`
+
+# Documented enum v4l2_buf_type
+replace symbol V4L2_BUF_TYPE_META_CAPTURE :c:type:`v4l2_buf_type`
+replace symbol V4L2_BUF_TYPE_META_OUTPUT :c:type:`v4l2_buf_type`
+replace symbol V4L2_BUF_TYPE_SDR_CAPTURE :c:type:`v4l2_buf_type`
+replace symbol V4L2_BUF_TYPE_SDR_OUTPUT :c:type:`v4l2_buf_type`
+replace symbol V4L2_BUF_TYPE_SLICED_VBI_CAPTURE :c:type:`v4l2_buf_type`
+replace symbol V4L2_BUF_TYPE_SLICED_VBI_OUTPUT :c:type:`v4l2_buf_type`
+replace symbol V4L2_BUF_TYPE_VBI_CAPTURE :c:type:`v4l2_buf_type`
+replace symbol V4L2_BUF_TYPE_VBI_OUTPUT :c:type:`v4l2_buf_type`
+replace symbol V4L2_BUF_TYPE_VIDEO_CAPTURE :c:type:`v4l2_buf_type`
+replace symbol V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :c:type:`v4l2_buf_type`
+replace symbol V4L2_BUF_TYPE_VIDEO_OUTPUT :c:type:`v4l2_buf_type`
+replace symbol V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE :c:type:`v4l2_buf_type`
+replace symbol V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY :c:type:`v4l2_buf_type`
+replace symbol V4L2_BUF_TYPE_VIDEO_OVERLAY :c:type:`v4l2_buf_type`
+
+# Documented enum v4l2_tuner_type
+replace symbol V4L2_TUNER_ANALOG_TV :c:type:`v4l2_tuner_type`
+replace symbol V4L2_TUNER_RADIO :c:type:`v4l2_tuner_type`
+replace symbol V4L2_TUNER_RF :c:type:`v4l2_tuner_type`
+replace symbol V4L2_TUNER_SDR :c:type:`v4l2_tuner_type`
+
+# Documented enum v4l2_memory
+replace symbol V4L2_MEMORY_DMABUF :c:type:`v4l2_memory`
+replace symbol V4L2_MEMORY_MMAP :c:type:`v4l2_memory`
+replace symbol V4L2_MEMORY_OVERLAY :c:type:`v4l2_memory`
+replace symbol V4L2_MEMORY_USERPTR :c:type:`v4l2_memory`
+
+# Documented enum v4l2_colorspace
+replace symbol V4L2_COLORSPACE_470_SYSTEM_BG :c:type:`v4l2_colorspace`
+replace symbol V4L2_COLORSPACE_470_SYSTEM_M :c:type:`v4l2_colorspace`
+replace symbol V4L2_COLORSPACE_OPRGB :c:type:`v4l2_colorspace`
+replace define V4L2_COLORSPACE_ADOBERGB :c:type:`v4l2_colorspace`
+replace symbol V4L2_COLORSPACE_BT2020 :c:type:`v4l2_colorspace`
+replace symbol V4L2_COLORSPACE_DCI_P3 :c:type:`v4l2_colorspace`
+replace symbol V4L2_COLORSPACE_DEFAULT :c:type:`v4l2_colorspace`
+replace symbol V4L2_COLORSPACE_JPEG :c:type:`v4l2_colorspace`
+replace symbol V4L2_COLORSPACE_RAW :c:type:`v4l2_colorspace`
+replace symbol V4L2_COLORSPACE_REC709 :c:type:`v4l2_colorspace`
+replace symbol V4L2_COLORSPACE_SMPTE170M :c:type:`v4l2_colorspace`
+replace symbol V4L2_COLORSPACE_SMPTE240M :c:type:`v4l2_colorspace`
+replace symbol V4L2_COLORSPACE_SRGB :c:type:`v4l2_colorspace`
+
+# Documented enum v4l2_xfer_func
+replace symbol V4L2_XFER_FUNC_709 :c:type:`v4l2_xfer_func`
+replace symbol V4L2_XFER_FUNC_OPRGB :c:type:`v4l2_xfer_func`
+replace define V4L2_XFER_FUNC_ADOBERGB :c:type:`v4l2_xfer_func`
+replace symbol V4L2_XFER_FUNC_DCI_P3 :c:type:`v4l2_xfer_func`
+replace symbol V4L2_XFER_FUNC_DEFAULT :c:type:`v4l2_xfer_func`
+replace symbol V4L2_XFER_FUNC_NONE :c:type:`v4l2_xfer_func`
+replace symbol V4L2_XFER_FUNC_SMPTE2084 :c:type:`v4l2_xfer_func`
+replace symbol V4L2_XFER_FUNC_SMPTE240M :c:type:`v4l2_xfer_func`
+replace symbol V4L2_XFER_FUNC_SRGB :c:type:`v4l2_xfer_func`
+
+# Documented enum v4l2_ycbcr_encoding
+replace symbol V4L2_YCBCR_ENC_601 :c:type:`v4l2_ycbcr_encoding`
+replace symbol V4L2_YCBCR_ENC_709 :c:type:`v4l2_ycbcr_encoding`
+replace symbol V4L2_YCBCR_ENC_BT2020 :c:type:`v4l2_ycbcr_encoding`
+replace symbol V4L2_YCBCR_ENC_BT2020_CONST_LUM :c:type:`v4l2_ycbcr_encoding`
+replace symbol V4L2_YCBCR_ENC_DEFAULT :c:type:`v4l2_ycbcr_encoding`
+replace symbol V4L2_YCBCR_ENC_SYCC :c:type:`v4l2_ycbcr_encoding`
+replace symbol V4L2_YCBCR_ENC_XV601 :c:type:`v4l2_ycbcr_encoding`
+replace symbol V4L2_YCBCR_ENC_XV709 :c:type:`v4l2_ycbcr_encoding`
+replace symbol V4L2_YCBCR_ENC_SMPTE240M :c:type:`v4l2_ycbcr_encoding`
+
+# Documented enum v4l2_hsv_encoding
+replace symbol V4L2_HSV_ENC_180 :c:type:`v4l2_hsv_encoding`
+replace symbol V4L2_HSV_ENC_256 :c:type:`v4l2_hsv_encoding`
+
+# Documented enum v4l2_quantization
+replace symbol V4L2_QUANTIZATION_DEFAULT :c:type:`v4l2_quantization`
+replace symbol V4L2_QUANTIZATION_FULL_RANGE :c:type:`v4l2_quantization`
+replace symbol V4L2_QUANTIZATION_LIM_RANGE :c:type:`v4l2_quantization`
+
+# Documented enum v4l2_priority
+replace symbol V4L2_PRIORITY_BACKGROUND :c:type:`v4l2_priority`
+replace symbol V4L2_PRIORITY_DEFAULT :c:type:`v4l2_priority`
+replace symbol V4L2_PRIORITY_INTERACTIVE :c:type:`v4l2_priority`
+replace symbol V4L2_PRIORITY_RECORD :c:type:`v4l2_priority`
+replace symbol V4L2_PRIORITY_UNSET :c:type:`v4l2_priority`
+
+# Documented enum v4l2_frmsizetypes
+replace symbol V4L2_FRMSIZE_TYPE_CONTINUOUS :c:type:`v4l2_frmsizetypes`
+replace symbol V4L2_FRMSIZE_TYPE_DISCRETE :c:type:`v4l2_frmsizetypes`
+replace symbol V4L2_FRMSIZE_TYPE_STEPWISE :c:type:`v4l2_frmsizetypes`
+
+# Documented enum frmivaltypes
+replace symbol V4L2_FRMIVAL_TYPE_CONTINUOUS :c:type:`v4l2_frmivaltypes`
+replace symbol V4L2_FRMIVAL_TYPE_DISCRETE :c:type:`v4l2_frmivaltypes`
+replace symbol V4L2_FRMIVAL_TYPE_STEPWISE :c:type:`v4l2_frmivaltypes`
+
+# Documented enum :c:type:`v4l2_ctrl_type`
+replace symbol V4L2_CTRL_COMPOUND_TYPES vidioc_queryctrl
+
+replace symbol V4L2_CTRL_TYPE_BITMASK :c:type:`v4l2_ctrl_type`
+replace symbol V4L2_CTRL_TYPE_BOOLEAN :c:type:`v4l2_ctrl_type`
+replace symbol V4L2_CTRL_TYPE_BUTTON :c:type:`v4l2_ctrl_type`
+replace symbol V4L2_CTRL_TYPE_CTRL_CLASS :c:type:`v4l2_ctrl_type`
+replace symbol V4L2_CTRL_TYPE_INTEGER :c:type:`v4l2_ctrl_type`
+replace symbol V4L2_CTRL_TYPE_INTEGER64 :c:type:`v4l2_ctrl_type`
+replace symbol V4L2_CTRL_TYPE_INTEGER_MENU :c:type:`v4l2_ctrl_type`
+replace symbol V4L2_CTRL_TYPE_MENU :c:type:`v4l2_ctrl_type`
+replace symbol V4L2_CTRL_TYPE_STRING :c:type:`v4l2_ctrl_type`
+replace symbol V4L2_CTRL_TYPE_U16 :c:type:`v4l2_ctrl_type`
+replace symbol V4L2_CTRL_TYPE_U32 :c:type:`v4l2_ctrl_type`
+replace symbol V4L2_CTRL_TYPE_U8 :c:type:`v4l2_ctrl_type`
+replace symbol V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS :c:type:`v4l2_ctrl_type`
+replace symbol V4L2_CTRL_TYPE_MPEG2_QUANTIZATION :c:type:`v4l2_ctrl_type`
+replace symbol V4L2_CTRL_TYPE_H264_SPS :c:type:`v4l2_ctrl_type`
+replace symbol V4L2_CTRL_TYPE_H264_PPS :c:type:`v4l2_ctrl_type`
+replace symbol V4L2_CTRL_TYPE_H264_SCALING_MATRIX :c:type:`v4l2_ctrl_type`
+replace symbol V4L2_CTRL_TYPE_H264_SLICE_PARAMS :c:type:`v4l2_ctrl_type`
+replace symbol V4L2_CTRL_TYPE_H264_DECODE_PARAMS :c:type:`v4l2_ctrl_type`
+replace symbol V4L2_CTRL_TYPE_HEVC_SPS :c:type:`v4l2_ctrl_type`
+replace symbol V4L2_CTRL_TYPE_HEVC_PPS :c:type:`v4l2_ctrl_type`
+replace symbol V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS :c:type:`v4l2_ctrl_type`
+replace symbol V4L2_CTRL_TYPE_AREA :c:type:`v4l2_ctrl_type`
+
+# V4L2 capability defines
+replace define V4L2_CAP_VIDEO_CAPTURE device-capabilities
+replace define V4L2_CAP_VIDEO_CAPTURE_MPLANE device-capabilities
+replace define V4L2_CAP_VIDEO_OUTPUT device-capabilities
+replace define V4L2_CAP_VIDEO_OUTPUT_MPLANE device-capabilities
+replace define V4L2_CAP_VIDEO_M2M device-capabilities
+replace define V4L2_CAP_VIDEO_M2M_MPLANE device-capabilities
+replace define V4L2_CAP_VIDEO_OVERLAY device-capabilities
+replace define V4L2_CAP_VBI_CAPTURE device-capabilities
+replace define V4L2_CAP_VBI_OUTPUT device-capabilities
+replace define V4L2_CAP_SLICED_VBI_CAPTURE device-capabilities
+replace define V4L2_CAP_SLICED_VBI_OUTPUT device-capabilities
+replace define V4L2_CAP_RDS_CAPTURE device-capabilities
+replace define V4L2_CAP_VIDEO_OUTPUT_OVERLAY device-capabilities
+replace define V4L2_CAP_HW_FREQ_SEEK device-capabilities
+replace define V4L2_CAP_RDS_OUTPUT device-capabilities
+replace define V4L2_CAP_TUNER device-capabilities
+replace define V4L2_CAP_AUDIO device-capabilities
+replace define V4L2_CAP_RADIO device-capabilities
+replace define V4L2_CAP_MODULATOR device-capabilities
+replace define V4L2_CAP_SDR_CAPTURE device-capabilities
+replace define V4L2_CAP_EXT_PIX_FORMAT device-capabilities
+replace define V4L2_CAP_SDR_OUTPUT device-capabilities
+replace define V4L2_CAP_META_CAPTURE device-capabilities
+replace define V4L2_CAP_READWRITE device-capabilities
+replace define V4L2_CAP_ASYNCIO device-capabilities
+replace define V4L2_CAP_STREAMING device-capabilities
+replace define V4L2_CAP_META_OUTPUT device-capabilities
+replace define V4L2_CAP_DEVICE_CAPS device-capabilities
+replace define V4L2_CAP_TOUCH device-capabilities
+
+# V4L2 pix flags
+replace define V4L2_PIX_FMT_PRIV_MAGIC :c:type:`v4l2_pix_format`
+replace define V4L2_PIX_FMT_FLAG_PREMUL_ALPHA reserved-formats
+
+# V4L2 format flags
+replace define V4L2_FMT_FLAG_COMPRESSED fmtdesc-flags
+replace define V4L2_FMT_FLAG_EMULATED fmtdesc-flags
+replace define V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM fmtdesc-flags
+replace define V4L2_FMT_FLAG_DYN_RESOLUTION fmtdesc-flags
+
+# V4L2 timecode types
+replace define V4L2_TC_TYPE_24FPS timecode-type
+replace define V4L2_TC_TYPE_25FPS timecode-type
+replace define V4L2_TC_TYPE_30FPS timecode-type
+replace define V4L2_TC_TYPE_50FPS timecode-type
+replace define V4L2_TC_TYPE_60FPS timecode-type
+
+# V4L2 timecode flags
+replace define V4L2_TC_FLAG_DROPFRAME timecode-flags
+replace define V4L2_TC_FLAG_COLORFRAME timecode-flags
+replace define V4L2_TC_USERBITS_field timecode-flags
+replace define V4L2_TC_USERBITS_USERDEFINED timecode-flags
+replace define V4L2_TC_USERBITS_8BITCHARS timecode-flags
+
+# V4L2 JPEG markers
+replace define V4L2_JPEG_MARKER_DHT jpeg-markers
+replace define V4L2_JPEG_MARKER_DQT jpeg-markers
+replace define V4L2_JPEG_MARKER_DRI jpeg-markers
+replace define V4L2_JPEG_MARKER_COM jpeg-markers
+replace define V4L2_JPEG_MARKER_APP jpeg-markers
+
+# V4L2 framebuffer caps and flags
+
+replace define V4L2_FBUF_CAP_EXTERNOVERLAY framebuffer-cap
+replace define V4L2_FBUF_CAP_CHROMAKEY framebuffer-cap
+replace define V4L2_FBUF_CAP_LIST_CLIPPING framebuffer-cap
+replace define V4L2_FBUF_CAP_BITMAP_CLIPPING framebuffer-cap
+replace define V4L2_FBUF_CAP_LOCAL_ALPHA framebuffer-cap
+replace define V4L2_FBUF_CAP_GLOBAL_ALPHA framebuffer-cap
+replace define V4L2_FBUF_CAP_LOCAL_INV_ALPHA framebuffer-cap
+replace define V4L2_FBUF_CAP_SRC_CHROMAKEY framebuffer-cap
+
+replace define V4L2_FBUF_FLAG_PRIMARY framebuffer-flags
+replace define V4L2_FBUF_FLAG_OVERLAY framebuffer-flags
+replace define V4L2_FBUF_FLAG_CHROMAKEY framebuffer-flags
+replace define V4L2_FBUF_FLAG_LOCAL_ALPHA framebuffer-flags
+replace define V4L2_FBUF_FLAG_GLOBAL_ALPHA framebuffer-flags
+replace define V4L2_FBUF_FLAG_LOCAL_INV_ALPHA framebuffer-flags
+replace define V4L2_FBUF_FLAG_SRC_CHROMAKEY framebuffer-flags
+
+# Used on VIDIOC_G_PARM
+
+replace define V4L2_MODE_HIGHQUALITY parm-flags
+replace define V4L2_CAP_TIMEPERFRAME :c:type:`v4l2_captureparm`
+
+# The V4L2_STD_foo are all defined at v4l2_std_id table
+
+replace define V4L2_STD_PAL_B v4l2-std-id
+replace define V4L2_STD_PAL_B1 v4l2-std-id
+replace define V4L2_STD_PAL_G v4l2-std-id
+replace define V4L2_STD_PAL_H v4l2-std-id
+replace define V4L2_STD_PAL_I v4l2-std-id
+replace define V4L2_STD_PAL_D v4l2-std-id
+replace define V4L2_STD_PAL_D1 v4l2-std-id
+replace define V4L2_STD_PAL_K v4l2-std-id
+replace define V4L2_STD_PAL_M v4l2-std-id
+replace define V4L2_STD_PAL_N v4l2-std-id
+replace define V4L2_STD_PAL_Nc v4l2-std-id
+replace define V4L2_STD_PAL_60 v4l2-std-id
+replace define V4L2_STD_NTSC_M v4l2-std-id
+replace define V4L2_STD_NTSC_M_JP v4l2-std-id
+replace define V4L2_STD_NTSC_443 v4l2-std-id
+replace define V4L2_STD_NTSC_M_KR v4l2-std-id
+replace define V4L2_STD_SECAM_B v4l2-std-id
+replace define V4L2_STD_SECAM_D v4l2-std-id
+replace define V4L2_STD_SECAM_G v4l2-std-id
+replace define V4L2_STD_SECAM_H v4l2-std-id
+replace define V4L2_STD_SECAM_K v4l2-std-id
+replace define V4L2_STD_SECAM_K1 v4l2-std-id
+replace define V4L2_STD_SECAM_L v4l2-std-id
+replace define V4L2_STD_SECAM_LC v4l2-std-id
+replace define V4L2_STD_ATSC_8_VSB v4l2-std-id
+replace define V4L2_STD_ATSC_16_VSB v4l2-std-id
+replace define V4L2_STD_NTSC v4l2-std-id
+replace define V4L2_STD_SECAM_DK v4l2-std-id
+replace define V4L2_STD_SECAM v4l2-std-id
+replace define V4L2_STD_PAL_BG v4l2-std-id
+replace define V4L2_STD_PAL_DK v4l2-std-id
+replace define V4L2_STD_PAL v4l2-std-id
+replace define V4L2_STD_B v4l2-std-id
+replace define V4L2_STD_G v4l2-std-id
+replace define V4L2_STD_H v4l2-std-id
+replace define V4L2_STD_L v4l2-std-id
+replace define V4L2_STD_GH v4l2-std-id
+replace define V4L2_STD_DK v4l2-std-id
+replace define V4L2_STD_BG v4l2-std-id
+replace define V4L2_STD_MN v4l2-std-id
+replace define V4L2_STD_MTS v4l2-std-id
+replace define V4L2_STD_525_60 v4l2-std-id
+replace define V4L2_STD_625_50 v4l2-std-id
+replace define V4L2_STD_ATSC v4l2-std-id
+replace define V4L2_STD_UNKNOWN v4l2-std-id
+replace define V4L2_STD_ALL v4l2-std-id
+
+# V4L2 DT BT timings definitions
+
+replace define V4L2_DV_PROGRESSIVE :c:type:`v4l2_bt_timings`
+replace define V4L2_DV_INTERLACED :c:type:`v4l2_bt_timings`
+
+replace define V4L2_DV_VSYNC_POS_POL :c:type:`v4l2_bt_timings`
+replace define V4L2_DV_HSYNC_POS_POL :c:type:`v4l2_bt_timings`
+
+replace define V4L2_DV_BT_STD_CEA861 dv-bt-standards
+replace define V4L2_DV_BT_STD_DMT dv-bt-standards
+replace define V4L2_DV_BT_STD_CVT dv-bt-standards
+replace define V4L2_DV_BT_STD_GTF dv-bt-standards
+replace define V4L2_DV_BT_STD_SDI dv-bt-standards
+
+replace define V4L2_DV_FL_REDUCED_BLANKING dv-bt-standards
+replace define V4L2_DV_FL_CAN_REDUCE_FPS dv-bt-standards
+replace define V4L2_DV_FL_CAN_DETECT_REDUCED_FPS dv-bt-standards
+replace define V4L2_DV_FL_REDUCED_FPS dv-bt-standards
+replace define V4L2_DV_FL_HALF_LINE dv-bt-standards
+replace define V4L2_DV_FL_IS_CE_VIDEO dv-bt-standards
+replace define V4L2_DV_FL_FIRST_FIELD_EXTRA_LINE dv-bt-standards
+replace define V4L2_DV_FL_HAS_PICTURE_ASPECT dv-bt-standards
+replace define V4L2_DV_FL_HAS_CEA861_VIC dv-bt-standards
+replace define V4L2_DV_FL_HAS_HDMI_VIC dv-bt-standards
+
+replace define V4L2_DV_BT_656_1120 dv-timing-types
+
+replace define V4L2_DV_BT_CAP_INTERLACED framebuffer-cap
+replace define V4L2_DV_BT_CAP_PROGRESSIVE framebuffer-cap
+replace define V4L2_DV_BT_CAP_REDUCED_BLANKING framebuffer-cap
+replace define V4L2_DV_BT_CAP_CUSTOM framebuffer-cap
+
+# V4L2 input
+
+replace define V4L2_INPUT_TYPE_TUNER input-type
+replace define V4L2_INPUT_TYPE_CAMERA input-type
+replace define V4L2_INPUT_TYPE_TOUCH input-type
+
+replace define V4L2_IN_ST_NO_POWER input-status
+replace define V4L2_IN_ST_NO_SIGNAL input-status
+replace define V4L2_IN_ST_NO_COLOR input-status
+replace define V4L2_IN_ST_HFLIP input-status
+replace define V4L2_IN_ST_VFLIP input-status
+replace define V4L2_IN_ST_NO_H_LOCK input-status
+replace define V4L2_IN_ST_COLOR_KILL input-status
+replace define V4L2_IN_ST_NO_SYNC input-status
+replace define V4L2_IN_ST_NO_EQU input-status
+replace define V4L2_IN_ST_NO_CARRIER input-status
+replace define V4L2_IN_ST_MACROVISION input-status
+replace define V4L2_IN_ST_NO_ACCESS input-status
+replace define V4L2_IN_ST_VTR input-status
+replace define V4L2_IN_ST_NO_V_LOCK input-status
+replace define V4L2_IN_ST_NO_STD_LOCK input-status
+
+replace define V4L2_IN_CAP_DV_TIMINGS input-capabilities
+replace define V4L2_IN_CAP_STD input-capabilities
+replace define V4L2_IN_CAP_NATIVE_SIZE input-capabilities
+
+# V4L2 output
+
+replace define V4L2_OUTPUT_TYPE_MODULATOR output-type
+replace define V4L2_OUTPUT_TYPE_ANALOG output-type
+replace define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY output-type
+
+replace define V4L2_OUT_CAP_DV_TIMINGS output-capabilities
+replace define V4L2_OUT_CAP_STD output-capabilities
+replace define V4L2_OUT_CAP_NATIVE_SIZE output-capabilities
+
+# V4L2 control flags
+
+replace define V4L2_CTRL_FLAG_DISABLED control-flags
+replace define V4L2_CTRL_FLAG_GRABBED control-flags
+replace define V4L2_CTRL_FLAG_READ_ONLY control-flags
+replace define V4L2_CTRL_FLAG_UPDATE control-flags
+replace define V4L2_CTRL_FLAG_INACTIVE control-flags
+replace define V4L2_CTRL_FLAG_SLIDER control-flags
+replace define V4L2_CTRL_FLAG_WRITE_ONLY control-flags
+replace define V4L2_CTRL_FLAG_VOLATILE control-flags
+replace define V4L2_CTRL_FLAG_HAS_PAYLOAD control-flags
+replace define V4L2_CTRL_FLAG_EXECUTE_ON_WRITE control-flags
+replace define V4L2_CTRL_FLAG_MODIFY_LAYOUT control-flags
+
+replace define V4L2_CTRL_FLAG_NEXT_CTRL control
+replace define V4L2_CTRL_FLAG_NEXT_COMPOUND control
+replace define V4L2_CID_PRIVATE_BASE control
+
+# V4L2 tuner
+
+replace define V4L2_TUNER_CAP_LOW tuner-capability
+replace define V4L2_TUNER_CAP_NORM tuner-capability
+replace define V4L2_TUNER_CAP_HWSEEK_BOUNDED tuner-capability
+replace define V4L2_TUNER_CAP_HWSEEK_WRAP tuner-capability
+replace define V4L2_TUNER_CAP_STEREO tuner-capability
+replace define V4L2_TUNER_CAP_LANG2 tuner-capability
+replace define V4L2_TUNER_CAP_SAP tuner-capability
+replace define V4L2_TUNER_CAP_LANG1 tuner-capability
+replace define V4L2_TUNER_CAP_RDS tuner-capability
+replace define V4L2_TUNER_CAP_RDS_BLOCK_IO tuner-capability
+replace define V4L2_TUNER_CAP_RDS_CONTROLS tuner-capability
+replace define V4L2_TUNER_CAP_FREQ_BANDS tuner-capability
+replace define V4L2_TUNER_CAP_HWSEEK_PROG_LIM tuner-capability
+replace define V4L2_TUNER_CAP_1HZ tuner-capability
+
+replace define V4L2_TUNER_SUB_MONO tuner-rxsubchans
+replace define V4L2_TUNER_SUB_STEREO tuner-rxsubchans
+replace define V4L2_TUNER_SUB_LANG2 tuner-rxsubchans
+replace define V4L2_TUNER_SUB_SAP tuner-rxsubchans
+replace define V4L2_TUNER_SUB_LANG1 tuner-rxsubchans
+replace define V4L2_TUNER_SUB_RDS tuner-rxsubchans
+
+replace define V4L2_TUNER_MODE_MONO tuner-audmode
+replace define V4L2_TUNER_MODE_STEREO tuner-audmode
+replace define V4L2_TUNER_MODE_LANG2 tuner-audmode
+replace define V4L2_TUNER_MODE_SAP tuner-audmode
+replace define V4L2_TUNER_MODE_LANG1 tuner-audmode
+replace define V4L2_TUNER_MODE_LANG1_LANG2 tuner-audmode
+
+replace define V4L2_BAND_MODULATION_VSB band-modulation
+replace define V4L2_BAND_MODULATION_FM band-modulation
+replace define V4L2_BAND_MODULATION_AM band-modulation
+
+replace define V4L2_RDS_BLOCK_MSK v4l2-rds-block
+replace define V4L2_RDS_BLOCK_A v4l2-rds-block
+replace define V4L2_RDS_BLOCK_B v4l2-rds-block
+replace define V4L2_RDS_BLOCK_C v4l2-rds-block
+replace define V4L2_RDS_BLOCK_D v4l2-rds-block
+replace define V4L2_RDS_BLOCK_C_ALT v4l2-rds-block
+replace define V4L2_RDS_BLOCK_INVALID v4l2-rds-block
+replace define V4L2_RDS_BLOCK_CORRECTED v4l2-rds-block
+replace define V4L2_RDS_BLOCK_ERROR v4l2-rds-block
+
+# V4L2 audio
+
+replace define V4L2_AUDCAP_STEREO audio-capability
+replace define V4L2_AUDCAP_AVL audio-capability
+
+replace define V4L2_AUDMODE_AVL audio-mode
+
+# MPEG
+
+replace define V4L2_ENC_IDX_FRAME_I :c:type:`v4l2_enc_idx`
+replace define V4L2_ENC_IDX_FRAME_P :c:type:`v4l2_enc_idx`
+replace define V4L2_ENC_IDX_FRAME_B :c:type:`v4l2_enc_idx`
+replace define V4L2_ENC_IDX_FRAME_MASK :c:type:`v4l2_enc_idx`
+replace define V4L2_ENC_IDX_ENTRIES :c:type:`v4l2_enc_idx`
+
+replace define V4L2_ENC_CMD_START encoder-cmds
+replace define V4L2_ENC_CMD_STOP encoder-cmds
+replace define V4L2_ENC_CMD_PAUSE encoder-cmds
+replace define V4L2_ENC_CMD_RESUME encoder-cmds
+
+replace define V4L2_ENC_CMD_STOP_AT_GOP_END encoder-flags
+
+replace define V4L2_DEC_CMD_START decoder-cmds
+replace define V4L2_DEC_CMD_STOP decoder-cmds
+replace define V4L2_DEC_CMD_PAUSE decoder-cmds
+replace define V4L2_DEC_CMD_RESUME decoder-cmds
+replace define V4L2_DEC_CMD_FLUSH decoder-cmds
+
+replace define V4L2_DEC_CMD_START_MUTE_AUDIO decoder-cmds
+replace define V4L2_DEC_CMD_PAUSE_TO_BLACK decoder-cmds
+replace define V4L2_DEC_CMD_STOP_TO_BLACK decoder-cmds
+replace define V4L2_DEC_CMD_STOP_IMMEDIATELY decoder-cmds
+
+replace define V4L2_DEC_START_FMT_NONE decoder-cmds
+replace define V4L2_DEC_START_FMT_GOP decoder-cmds
+
+# V4L2 VBI
+
+replace define V4L2_VBI_UNSYNC vbifmt-flags
+replace define V4L2_VBI_INTERLACED vbifmt-flags
+
+replace define V4L2_VBI_ITU_525_F1_START :c:type:`v4l2_vbi_format`
+replace define V4L2_VBI_ITU_525_F2_START :c:type:`v4l2_vbi_format`
+replace define V4L2_VBI_ITU_625_F1_START :c:type:`v4l2_vbi_format`
+replace define V4L2_VBI_ITU_625_F2_START :c:type:`v4l2_vbi_format`
+
+
+replace define V4L2_SLICED_TELETEXT_B vbi-services
+replace define V4L2_SLICED_VPS vbi-services
+replace define V4L2_SLICED_CAPTION_525 vbi-services
+replace define V4L2_SLICED_WSS_625 vbi-services
+replace define V4L2_SLICED_VBI_525 vbi-services
+replace define V4L2_SLICED_VBI_625 vbi-services
+
+replace define V4L2_MPEG_VBI_IVTV_TELETEXT_B ITV0-Line-Identifier-Constants
+replace define V4L2_MPEG_VBI_IVTV_CAPTION_525 ITV0-Line-Identifier-Constants
+replace define V4L2_MPEG_VBI_IVTV_WSS_625 ITV0-Line-Identifier-Constants
+replace define V4L2_MPEG_VBI_IVTV_VPS ITV0-Line-Identifier-Constants
+
+replace define V4L2_MPEG_VBI_IVTV_MAGIC0 v4l2-mpeg-vbi-fmt-ivtv-magic
+replace define V4L2_MPEG_VBI_IVTV_MAGIC1 v4l2-mpeg-vbi-fmt-ivtv-magic
+
+# V4L2 events
+
+replace define V4L2_EVENT_ALL event-type
+replace define V4L2_EVENT_VSYNC event-type
+replace define V4L2_EVENT_EOS event-type
+replace define V4L2_EVENT_CTRL event-type
+replace define V4L2_EVENT_FRAME_SYNC event-type
+replace define V4L2_EVENT_SOURCE_CHANGE event-type
+replace define V4L2_EVENT_MOTION_DET event-type
+replace define V4L2_EVENT_PRIVATE_START event-type
+
+replace define V4L2_EVENT_CTRL_CH_VALUE ctrl-changes-flags
+replace define V4L2_EVENT_CTRL_CH_FLAGS ctrl-changes-flags
+replace define V4L2_EVENT_CTRL_CH_RANGE ctrl-changes-flags
+
+replace define V4L2_EVENT_SRC_CH_RESOLUTION src-changes-flags
+
+replace define V4L2_EVENT_MD_FL_HAVE_FRAME_SEQ :c:type:`v4l2_event_motion_det`
+
+replace define V4L2_EVENT_SUB_FL_SEND_INITIAL event-flags
+replace define V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK event-flags
+
+# V4L2 debugging
+replace define V4L2_CHIP_MATCH_BRIDGE vidioc_dbg_g_register
+replace define V4L2_CHIP_MATCH_SUBDEV vidioc_dbg_g_register
+replace define V4L2_CHIP_MATCH_HOST vidioc_dbg_g_register
+replace define V4L2_CHIP_MATCH_I2C_DRIVER vidioc_dbg_g_register
+replace define V4L2_CHIP_MATCH_I2C_ADDR vidioc_dbg_g_register
+replace define V4L2_CHIP_MATCH_AC97 vidioc_dbg_g_register
+
+replace define V4L2_CHIP_FL_READABLE vidioc_dbg_g_register
+replace define V4L2_CHIP_FL_WRITABLE vidioc_dbg_g_register
+
+# Ignore reserved ioctl and ancillary macros
+
+ignore define VIDEO_MAX_FRAME
+ignore define VIDEO_MAX_PLANES
+ignore define v4l2_fourcc
+ignore define v4l2_fourcc_be
+ignore define V4L2_FIELD_HAS_TOP
+ignore define V4L2_FIELD_HAS_BOTTOM
+ignore define V4L2_FIELD_HAS_BOTH
+ignore define V4L2_FIELD_HAS_T_OR_B
+ignore define V4L2_TYPE_IS_MULTIPLANAR
+ignore define V4L2_TYPE_IS_OUTPUT
+ignore define V4L2_TUNER_ADC
+ignore define V4L2_MAP_COLORSPACE_DEFAULT
+ignore define V4L2_MAP_XFER_FUNC_DEFAULT
+ignore define V4L2_MAP_YCBCR_ENC_DEFAULT
+ignore define V4L2_DV_BT_BLANKING_WIDTH
+ignore define V4L2_DV_BT_FRAME_WIDTH
+ignore define V4L2_DV_BT_BLANKING_HEIGHT
+ignore define V4L2_DV_BT_FRAME_HEIGHT
+ignore define V4L2_IN_CAP_CUSTOM_TIMINGS
+ignore define V4L2_CTRL_ID_MASK
+ignore define V4L2_CTRL_ID2CLASS
+ignore define V4L2_CTRL_ID2WHICH
+ignore define V4L2_CTRL_DRIVER_PRIV
+ignore define V4L2_CTRL_MAX_DIMS
+ignore define V4L2_CTRL_WHICH_CUR_VAL
+ignore define V4L2_CTRL_WHICH_DEF_VAL
+ignore define V4L2_CTRL_WHICH_REQUEST_VAL
+ignore define V4L2_OUT_CAP_CUSTOM_TIMINGS
+ignore define V4L2_CID_MAX_CTRLS
+
+ignore define BASE_VIDIOC_PRIVATE
+
+# Associate ioctls with their counterparts
+replace ioctl VIDIOC_DBG_S_REGISTER vidioc_dbg_g_register
+replace ioctl VIDIOC_DQBUF vidioc_qbuf
+replace ioctl VIDIOC_S_AUDOUT vidioc_g_audout
+replace ioctl VIDIOC_S_CROP vidioc_g_crop
+replace ioctl VIDIOC_S_CTRL vidioc_g_ctrl
+replace ioctl VIDIOC_S_DV_TIMINGS vidioc_g_dv_timings
+replace ioctl VIDIOC_S_EDID vidioc_g_edid
+replace ioctl VIDIOC_S_EXT_CTRLS vidioc_g_ext_ctrls
+replace ioctl VIDIOC_S_FBUF vidioc_g_fbuf
+replace ioctl VIDIOC_S_FMT vidioc_g_fmt
+replace ioctl VIDIOC_S_FREQUENCY vidioc_g_frequency
+replace ioctl VIDIOC_S_INPUT vidioc_g_input
+replace ioctl VIDIOC_S_JPEGCOMP vidioc_g_jpegcomp
+replace ioctl VIDIOC_S_MODULATOR vidioc_g_modulator
+replace ioctl VIDIOC_S_OUTPUT vidioc_g_output
+replace ioctl VIDIOC_S_PARM vidioc_g_parm
+replace ioctl VIDIOC_S_PRIORITY vidioc_g_priority
+replace ioctl VIDIOC_S_SELECTION vidioc_g_selection
+replace ioctl VIDIOC_S_STD vidioc_g_std
+replace ioctl VIDIOC_S_AUDIO vidioc_g_audio
+replace ioctl VIDIOC_S_TUNER vidioc_g_tuner
+replace ioctl VIDIOC_TRY_DECODER_CMD vidioc_decoder_cmd
+replace ioctl VIDIOC_TRY_ENCODER_CMD vidioc_encoder_cmd
+replace ioctl VIDIOC_TRY_EXT_CTRLS vidioc_g_ext_ctrls
+replace ioctl VIDIOC_TRY_FMT vidioc_g_fmt
+replace ioctl VIDIOC_STREAMOFF vidioc_streamon
+replace ioctl VIDIOC_QUERY_EXT_CTRL vidioc_queryctrl
+replace ioctl VIDIOC_QUERYMENU vidioc_queryctrl
diff --git a/Documentation/watch_queue.rst b/Documentation/watch_queue.rst
new file mode 100644
index 000000000000..d8f70282d247
--- /dev/null
+++ b/Documentation/watch_queue.rst
@@ -0,0 +1,354 @@
+==============================
+General notification mechanism
+==============================
+
+The general notification mechanism is built on top of the standard pipe driver
+whereby it effectively splices notification messages from the kernel into pipes
+opened by userspace.  This can be used in conjunction with::
+
+  * Key/keyring notifications
+
+  * General device event notifications
+
+
+The notifications buffers can be enabled by:
+
+	"General setup"/"General notification queue"
+	(CONFIG_WATCH_QUEUE)
+
+This document has the following sections:
+
+.. contents:: :local:
+
+
+Overview
+========
+
+This facility appears as a pipe that is opened in a special mode.  The pipe's
+internal ring buffer is used to hold messages that are generated by the kernel.
+These messages are then read out by read().  Splice and similar are disabled on
+such pipes due to them wanting to, under some circumstances, revert their
+additions to the ring - which might end up interleaved with notification
+messages.
+
+The owner of the pipe has to tell the kernel which sources it would like to
+watch through that pipe.  Only sources that have been connected to a pipe will
+insert messages into it.  Note that a source may be bound to multiple pipes and
+insert messages into all of them simultaneously.
+
+Filters may also be emplaced on a pipe so that certain source types and
+subevents can be ignored if they're not of interest.
+
+A message will be discarded if there isn't a slot available in the ring or if
+no preallocated message buffer is available.  In both of these cases, read()
+will insert a WATCH_META_LOSS_NOTIFICATION message into the output buffer after
+the last message currently in the buffer has been read.
+
+Note that when producing a notification, the kernel does not wait for the
+consumers to collect it, but rather just continues on.  This means that
+notifications can be generated whilst spinlocks are held and also protects the
+kernel from being held up indefinitely by a userspace malfunction.
+
+
+Message Structure
+=================
+
+Notification messages begin with a short header::
+
+	struct watch_notification {
+		__u32	type:24;
+		__u32	subtype:8;
+		__u32	info;
+	};
+
+"type" indicates the source of the notification record and "subtype" indicates
+the type of record from that source (see the Watch Sources section below).  The
+type may also be "WATCH_TYPE_META".  This is a special record type generated
+internally by the watch queue itself.  There are two subtypes:
+
+  * WATCH_META_REMOVAL_NOTIFICATION
+  * WATCH_META_LOSS_NOTIFICATION
+
+The first indicates that an object on which a watch was installed was removed
+or destroyed and the second indicates that some messages have been lost.
+
+"info" indicates a bunch of things, including:
+
+  * The length of the message in bytes, including the header (mask with
+    WATCH_INFO_LENGTH and shift by WATCH_INFO_LENGTH__SHIFT).  This indicates
+    the size of the record, which may be between 8 and 127 bytes.
+
+  * The watch ID (mask with WATCH_INFO_ID and shift by WATCH_INFO_ID__SHIFT).
+    This indicates that caller's ID of the watch, which may be between 0
+    and 255.  Multiple watches may share a queue, and this provides a means to
+    distinguish them.
+
+  * A type-specific field (WATCH_INFO_TYPE_INFO).  This is set by the
+    notification producer to indicate some meaning specific to the type and
+    subtype.
+
+Everything in info apart from the length can be used for filtering.
+
+The header can be followed by supplementary information.  The format of this is
+at the discretion is defined by the type and subtype.
+
+
+Watch List (Notification Source) API
+====================================
+
+A "watch list" is a list of watchers that are subscribed to a source of
+notifications.  A list may be attached to an object (say a key or a superblock)
+or may be global (say for device events).  From a userspace perspective, a
+non-global watch list is typically referred to by reference to the object it
+belongs to (such as using KEYCTL_NOTIFY and giving it a key serial number to
+watch that specific key).
+
+To manage a watch list, the following functions are provided:
+
+  * ``void init_watch_list(struct watch_list *wlist,
+			   void (*release_watch)(struct watch *wlist));``
+
+    Initialise a watch list.  If ``release_watch`` is not NULL, then this
+    indicates a function that should be called when the watch_list object is
+    destroyed to discard any references the watch list holds on the watched
+    object.
+
+  * ``void remove_watch_list(struct watch_list *wlist);``
+
+    This removes all of the watches subscribed to a watch_list and frees them
+    and then destroys the watch_list object itself.
+
+
+Watch Queue (Notification Output) API
+=====================================
+
+A "watch queue" is the buffer allocated by an application that notification
+records will be written into.  The workings of this are hidden entirely inside
+of the watch_queue device driver, but it is necessary to gain a reference to it
+to set a watch.  These can be managed with:
+
+  * ``struct watch_queue *get_watch_queue(int fd);``
+
+    Since watch queues are indicated to the kernel by the fd of the pipe that
+    implements the buffer, userspace must hand that fd through a system call.
+    This can be used to look up an opaque pointer to the watch queue from the
+    system call.
+
+  * ``void put_watch_queue(struct watch_queue *wqueue);``
+
+    This discards the reference obtained from ``get_watch_queue()``.
+
+
+Watch Subscription API
+======================
+
+A "watch" is a subscription on a watch list, indicating the watch queue, and
+thus the buffer, into which notification records should be written.  The watch
+queue object may also carry filtering rules for that object, as set by
+userspace.  Some parts of the watch struct can be set by the driver::
+
+	struct watch {
+		union {
+			u32		info_id;	/* ID to be OR'd in to info field */
+			...
+		};
+		void			*private;	/* Private data for the watched object */
+		u64			id;		/* Internal identifier */
+		...
+	};
+
+The ``info_id`` value should be an 8-bit number obtained from userspace and
+shifted by WATCH_INFO_ID__SHIFT.  This is OR'd into the WATCH_INFO_ID field of
+struct watch_notification::info when and if the notification is written into
+the associated watch queue buffer.
+
+The ``private`` field is the driver's data associated with the watch_list and
+is cleaned up by the ``watch_list::release_watch()`` method.
+
+The ``id`` field is the source's ID.  Notifications that are posted with a
+different ID are ignored.
+
+The following functions are provided to manage watches:
+
+  * ``void init_watch(struct watch *watch, struct watch_queue *wqueue);``
+
+    Initialise a watch object, setting its pointer to the watch queue, using
+    appropriate barriering to avoid lockdep complaints.
+
+  * ``int add_watch_to_object(struct watch *watch, struct watch_list *wlist);``
+
+    Subscribe a watch to a watch list (notification source).  The
+    driver-settable fields in the watch struct must have been set before this
+    is called.
+
+  * ``int remove_watch_from_object(struct watch_list *wlist,
+				   struct watch_queue *wqueue,
+				   u64 id, false);``
+
+    Remove a watch from a watch list, where the watch must match the specified
+    watch queue (``wqueue``) and object identifier (``id``).  A notification
+    (``WATCH_META_REMOVAL_NOTIFICATION``) is sent to the watch queue to
+    indicate that the watch got removed.
+
+  * ``int remove_watch_from_object(struct watch_list *wlist, NULL, 0, true);``
+
+    Remove all the watches from a watch list.  It is expected that this will be
+    called preparatory to destruction and that the watch list will be
+    inaccessible to new watches by this point.  A notification
+    (``WATCH_META_REMOVAL_NOTIFICATION``) is sent to the watch queue of each
+    subscribed watch to indicate that the watch got removed.
+
+
+Notification Posting API
+========================
+
+To post a notification to watch list so that the subscribed watches can see it,
+the following function should be used::
+
+	void post_watch_notification(struct watch_list *wlist,
+				     struct watch_notification *n,
+				     const struct cred *cred,
+				     u64 id);
+
+The notification should be preformatted and a pointer to the header (``n``)
+should be passed in.  The notification may be larger than this and the size in
+units of buffer slots is noted in ``n->info & WATCH_INFO_LENGTH``.
+
+The ``cred`` struct indicates the credentials of the source (subject) and is
+passed to the LSMs, such as SELinux, to allow or suppress the recording of the
+note in each individual queue according to the credentials of that queue
+(object).
+
+The ``id`` is the ID of the source object (such as the serial number on a key).
+Only watches that have the same ID set in them will see this notification.
+
+
+Watch Sources
+=============
+
+Any particular buffer can be fed from multiple sources.  Sources include:
+
+  * WATCH_TYPE_KEY_NOTIFY
+
+    Notifications of this type indicate changes to keys and keyrings, including
+    the changes of keyring contents or the attributes of keys.
+
+    See Documentation/security/keys/core.rst for more information.
+
+  * WATCH_TYPE_BLOCK_NOTIFY
+
+    Notifications of this type indicate block layer events, such as I/O errors
+    or temporary link loss.  Watches of this type are set on a global queue.
+
+
+Event Filtering
+===============
+
+Once a watch queue has been created, a set of filters can be applied to limit
+the events that are received using::
+
+	struct watch_notification_filter filter = {
+		...
+	};
+	ioctl(fd, IOC_WATCH_QUEUE_SET_FILTER, &filter)
+
+The filter description is a variable of type::
+
+	struct watch_notification_filter {
+		__u32	nr_filters;
+		__u32	__reserved;
+		struct watch_notification_type_filter filters[];
+	};
+
+Where "nr_filters" is the number of filters in filters[] and "__reserved"
+should be 0.  The "filters" array has elements of the following type::
+
+	struct watch_notification_type_filter {
+		__u32	type;
+		__u32	info_filter;
+		__u32	info_mask;
+		__u32	subtype_filter[8];
+	};
+
+Where:
+
+  * ``type`` is the event type to filter for and should be something like
+    "WATCH_TYPE_KEY_NOTIFY"
+
+  * ``info_filter`` and ``info_mask`` act as a filter on the info field of the
+    notification record.  The notification is only written into the buffer if::
+
+	(watch.info & info_mask) == info_filter
+
+    This could be used, for example, to ignore events that are not exactly on
+    the watched point in a mount tree.
+
+  * ``subtype_filter`` is a bitmask indicating the subtypes that are of
+    interest.  Bit 0 of subtype_filter[0] corresponds to subtype 0, bit 1 to
+    subtype 1, and so on.
+
+If the argument to the ioctl() is NULL, then the filters will be removed and
+all events from the watched sources will come through.
+
+
+Userspace Code Example
+======================
+
+A buffer is created with something like the following::
+
+	pipe2(fds, O_TMPFILE);
+	ioctl(fds[1], IOC_WATCH_QUEUE_SET_SIZE, 256);
+
+It can then be set to receive keyring change notifications and device event
+notifications::
+
+	keyctl(KEYCTL_WATCH_KEY, KEY_SPEC_SESSION_KEYRING, fds[1], 0x01);
+	watch_devices(fds[1], 0x2);
+
+The notifications can then be consumed by something like the following::
+
+	static void consumer(int rfd, struct watch_queue_buffer *buf)
+	{
+		unsigned char buffer[128];
+		ssize_t buf_len;
+
+		while (buf_len = read(rfd, buffer, sizeof(buffer)),
+		       buf_len > 0
+		       ) {
+			void *p = buffer;
+			void *end = buffer + buf_len;
+			while (p < end) {
+				union {
+					struct watch_notification n;
+					unsigned char buf1[128];
+				} n;
+				size_t largest, len;
+
+				largest = end - p;
+				if (largest > 128)
+					largest = 128;
+				memcpy(&n, p, largest);
+
+				len = (n->info & WATCH_INFO_LENGTH) >>
+					WATCH_INFO_LENGTH__SHIFT;
+				if (len == 0 || len > largest)
+					return;
+
+				switch (n.n.type) {
+				case WATCH_TYPE_META:
+					got_meta(&n.n);
+				case WATCH_TYPE_KEY_NOTIFY:
+					saw_key_change(&n.n);
+					break;
+				case WATCH_TYPE_BLOCK_NOTIFY:
+					saw_block_event(&n.n);
+					break;
+				case WATCH_TYPE_USB_NOTIFY:
+					saw_usb_event(&n.n);
+					break;
+				}
+
+				p += len;
+			}
+		}
+	}
diff --git a/Documentation/x86/boot.rst b/Documentation/x86/boot.rst
index fa7ddc0428c8..5325c71ca877 100644
--- a/Documentation/x86/boot.rst
+++ b/Documentation/x86/boot.rst
@@ -1399,8 +1399,8 @@ must have read/write permission; CS must be __BOOT_CS and DS, ES, SS
 must be __BOOT_DS; interrupt must be disabled; %rsi must hold the base
 address of the struct boot_params.
 
-EFI Handover Protocol
-=====================
+EFI Handover Protocol (deprecated)
+==================================
 
 This protocol allows boot loaders to defer initialisation to the EFI
 boot stub. The boot loader is required to load the kernel/initrd(s)
@@ -1408,6 +1408,12 @@ from the boot media and jump to the EFI handover protocol entry point
 which is hdr->handover_offset bytes from the beginning of
 startup_{32,64}.
 
+The boot loader MUST respect the kernel's PE/COFF metadata when it comes
+to section alignment, the memory footprint of the executable image beyond
+the size of the file itself, and any other aspect of the PE/COFF header
+that may affect correct operation of the image as a PE/COFF binary in the
+execution context provided by the EFI firmware.
+
 The function prototype for the handover entry point looks like this::
 
     efi_main(void *handle, efi_system_table_t *table, struct boot_params *bp)
@@ -1419,9 +1425,18 @@ UEFI specification. 'bp' is the boot loader-allocated boot params.
 
 The boot loader *must* fill out the following fields in bp::
 
-  - hdr.code32_start
   - hdr.cmd_line_ptr
   - hdr.ramdisk_image (if applicable)
   - hdr.ramdisk_size  (if applicable)
 
 All other fields should be zero.
+
+NOTE: The EFI Handover Protocol is deprecated in favour of the ordinary PE/COFF
+      entry point, combined with the LINUX_EFI_INITRD_MEDIA_GUID based initrd
+      loading protocol (refer to [0] for an example of the bootloader side of
+      this), which removes the need for any knowledge on the part of the EFI
+      bootloader regarding the internal representation of boot_params or any
+      requirements/limitations regarding the placement of the command line
+      and ramdisk in memory, or the placement of the kernel image itself.
+
+[0] https://github.com/u-boot/u-boot/commit/ec80b4735a593961fe701cc3a5d717d4739b0fd0
diff --git a/MAINTAINERS b/MAINTAINERS
index e64e5db31497..e965e5467a4d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1323,7 +1323,10 @@ ARM INTEGRATOR, VERSATILE AND REALVIEW SUPPORT
 M:	Linus Walleij <linus.walleij@linaro.org>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
-F:	Documentation/devicetree/bindings/arm/arm-boards
+F:	Documentation/devicetree/bindings/arm/arm,integrator.yaml
+F:	Documentation/devicetree/bindings/arm/arm,realview.yaml
+F:	Documentation/devicetree/bindings/arm/arm,versatile.yaml
+F:	Documentation/devicetree/bindings/arm/arm,vexpress-juno.yaml
 F:	Documentation/devicetree/bindings/auxdisplay/arm-charlcd.txt
 F:	Documentation/devicetree/bindings/clock/arm,syscon-icst.yaml
 F:	Documentation/devicetree/bindings/i2c/i2c-versatile.txt
@@ -2270,6 +2273,8 @@ L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 L:	linux-realtek-soc@lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
 F:	Documentation/devicetree/bindings/arm/realtek.yaml
+F:	arch/arm/boot/dts/rtd*
+F:	arch/arm/mach-realtek/
 F:	arch/arm64/boot/dts/realtek/
 
 ARM/RENESAS ARM64 ARCHITECTURE
@@ -2692,8 +2697,8 @@ L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:	Supported
 W:	http://wiki.xilinx.com
 T:	git https://github.com/Xilinx/linux-xlnx.git
-F:	Documentation/devicetree/bindings/i2c/i2c-cadence.txt
-F:	Documentation/devicetree/bindings/i2c/i2c-xiic.txt
+F:	Documentation/devicetree/bindings/i2c/cdns,i2c-r1p10.yaml
+F:	Documentation/devicetree/bindings/i2c/xlnx,xps-iic-2.00.a.yaml
 F:	arch/arm/mach-zynq/
 F:	drivers/block/xsysace.c
 F:	drivers/clocksource/timer-cadence-ttc.c
@@ -3667,7 +3672,7 @@ L:	linux-media@vger.kernel.org
 S:	Odd fixes
 W:	https://linuxtv.org
 T:	git git://linuxtv.org/media_tree.git
-F:	Documentation/media/v4l-drivers/bttv*
+F:	Documentation/driver-api/media/drivers/bttv*
 F:	drivers/media/pci/bt8xx/bttv*
 
 BUS FREQUENCY DRIVER FOR SAMSUNG EXYNOS
@@ -3758,7 +3763,7 @@ M:	Jonathan Corbet <corbet@lwn.net>
 L:	linux-media@vger.kernel.org
 S:	Maintained
 T:	git git://linuxtv.org/media_tree.git
-F:	Documentation/media/v4l-drivers/cafe_ccic*
+F:	Documentation/admin-guide/media/cafe_ccic*
 F:	drivers/media/platform/marvell-ccic/
 
 CAIF NETWORK LAYER
@@ -3894,6 +3899,15 @@ S:	Supported
 W:	https://developer.arm.com/products/system-ip/trustzone-cryptocell/cryptocell-700-family
 F:	drivers/crypto/ccree/
 
+CCTRNG ARM TRUSTZONE CRYPTOCELL TRUE RANDOM NUMBER GENERATOR (TRNG) DRIVER
+M:	Hadar Gat <hadar.gat@arm.com>
+L:	linux-crypto@vger.kernel.org
+S:	Supported
+F:	drivers/char/hw_random/cctrng.c
+F:	drivers/char/hw_random/cctrng.h
+F:	Documentation/devicetree/bindings/rng/arm-cctrng.txt
+W:	https://developer.arm.com/products/system-ip/trustzone-cryptocell/cryptocell-700-family
+
 CEC FRAMEWORK
 M:	Hans Verkuil <hverkuil-cisco@xs4all.nl>
 L:	linux-media@vger.kernel.org
@@ -3902,8 +3916,8 @@ W:	http://linuxtv.org
 T:	git git://linuxtv.org/media_tree.git
 F:	Documentation/ABI/testing/debugfs-cec-error-inj
 F:	Documentation/devicetree/bindings/media/cec.txt
-F:	Documentation/media/kapi/cec-core.rst
-F:	Documentation/media/uapi/cec
+F:	Documentation/driver-api/media/cec-core.rst
+F:	Documentation/userspace-api/media/cec
 F:	drivers/media/cec/
 F:	drivers/media/rc/keymaps/rc-cec.c
 F:	include/media/cec-notifier.h
@@ -4539,7 +4553,7 @@ L:	linux-media@vger.kernel.org
 S:	Odd fixes
 W:	https://linuxtv.org
 T:	git git://linuxtv.org/media_tree.git
-F:	Documentation/media/v4l-drivers/cx88*
+F:	Documentation/driver-api/media/drivers/cx88*
 F:	drivers/media/pci/cx88/
 
 CXD2820R MEDIA DRIVER
@@ -5042,7 +5056,7 @@ F:	drivers/dma-buf/
 F:	include/linux/*fence.h
 F:	include/linux/dma-buf*
 F:	include/linux/dma-resv.h
-K:	dma_(buf|fence|resv)
+K:	\bdma_(?:buf|fence|resv)\b
 
 DMA GENERIC OFFLOAD ENGINE SUBSYSTEM
 M:	Vinod Koul <vkoul@kernel.org>
@@ -5125,7 +5139,9 @@ X:	Documentation/ABI/
 X:	Documentation/devicetree/
 X:	Documentation/firmware-guide/acpi/
 X:	Documentation/i2c/
-X:	Documentation/media/
+X:	Documentation/admin-guide/media/
+X:	Documentation/userspace-api/media/
+X:	Documentation/driver-api/media/
 X:	Documentation/power/
 X:	Documentation/spi/
 
@@ -5253,7 +5269,7 @@ DRM DRIVER FOR ARM VERSATILE TFT PANELS
 M:	Linus Walleij <linus.walleij@linaro.org>
 S:	Maintained
 T:	git git://anongit.freedesktop.org/drm/drm-misc
-F:	Documentation/devicetree/bindings/display/panel/arm,versatile-tft-panel.txt
+F:	Documentation/devicetree/bindings/display/panel/arm,versatile-tft-panel.yaml
 F:	drivers/gpu/drm/panel/panel-arm-versatile.c
 
 DRM DRIVER FOR ASPEED BMC GFX
@@ -5279,7 +5295,7 @@ F:	drivers/gpu/drm/bochs/
 DRM DRIVER FOR BOE HIMAX8279D PANELS
 M:	Jerry Han <hanxu5@huaqin.corp-partner.google.com>
 S:	Maintained
-F:	Documentation/devicetree/bindings/display/panel/boe,himax8279d.txt
+F:	Documentation/devicetree/bindings/display/panel/boe,himax8279d.yaml
 F:	drivers/gpu/drm/panel/panel-boe-himax8279d.c
 
 DRM DRIVER FOR FARADAY TVE200 TV ENCODER
@@ -5297,7 +5313,7 @@ F:	drivers/gpu/drm/panel/panel-feixin-k101-im2ba02.c
 DRM DRIVER FOR FEIYANG FY07024DI26A30-D MIPI-DSI LCD PANELS
 M:	Jagan Teki <jagan@amarulasolutions.com>
 S:	Maintained
-F:	Documentation/devicetree/bindings/display/panel/feiyang,fy07024di26a30d.txt
+F:	Documentation/devicetree/bindings/display/panel/feiyang,fy07024di26a30d.yaml
 F:	drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c
 
 DRM DRIVER FOR GRAIN MEDIA GM12U320 PROJECTORS
@@ -5380,7 +5396,7 @@ F:	include/uapi/drm/nouveau_drm.h
 DRM DRIVER FOR OLIMEX LCD-OLINUXINO PANELS
 M:	Stefan Mavrodiev <stefan@olimex.com>
 S:	Maintained
-F:	Documentation/devicetree/bindings/display/panel/olimex,lcd-olinuxino.txt
+F:	Documentation/devicetree/bindings/display/panel/olimex,lcd-olinuxino.yaml
 F:	drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c
 
 DRM DRIVER FOR PERVASIVE DISPLAYS REPAPER PANELS
@@ -5417,7 +5433,7 @@ F:	include/uapi/drm/r128_drm.h
 DRM DRIVER FOR RAYDIUM RM67191 PANELS
 M:	Robert Chiras <robert.chiras@nxp.com>
 S:	Maintained
-F:	Documentation/devicetree/bindings/display/panel/raydium,rm67191.txt
+F:	Documentation/devicetree/bindings/display/panel/raydium,rm67191.yaml
 F:	drivers/gpu/drm/panel/panel-raydium-rm67191.c
 
 DRM DRIVER FOR ROCKTECH JH057N00900 PANELS
@@ -5447,7 +5463,7 @@ F:	drivers/gpu/drm/tiny/st7586.c
 DRM DRIVER FOR SITRONIX ST7701 PANELS
 M:	Jagan Teki <jagan@amarulasolutions.com>
 S:	Maintained
-F:	Documentation/devicetree/bindings/display/panel/sitronix,st7701.txt
+F:	Documentation/devicetree/bindings/display/panel/sitronix,st7701.yaml
 F:	drivers/gpu/drm/panel/panel-sitronix-st7701.c
 
 DRM DRIVER FOR SITRONIX ST7735R PANELS
@@ -5552,7 +5568,7 @@ M:	Chen-Yu Tsai <wens@csie.org>
 L:	dri-devel@lists.freedesktop.org
 S:	Supported
 T:	git git://anongit.freedesktop.org/drm/drm-misc
-F:	Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
+F:	Documentation/devicetree/bindings/display/allwinner*
 F:	drivers/gpu/drm/sun4i/
 
 DRM DRIVERS FOR AMLOGIC SOCS
@@ -5934,6 +5950,7 @@ M:	Tal Gilboa <talgi@mellanox.com>
 S:	Maintained
 F:	include/linux/dim.h
 F:	lib/dim/
+F:	Documentation/networking/net_dim.rst
 
 DZ DECSTATION DZ11 SERIAL DRIVER
 M:	"Maciej W. Rozycki" <macro@linux-mips.org>
@@ -6172,7 +6189,6 @@ M:	Yash Shah <yash.shah@sifive.com>
 L:	linux-edac@vger.kernel.org
 S:	Supported
 F:	drivers/edac/sifive_edac.c
-F:	drivers/soc/sifive_l2_cache.c
 
 EDAC-SKYLAKE
 M:	Tony Luck <tony.luck@intel.com>
@@ -6232,7 +6248,7 @@ L:	linux-media@vger.kernel.org
 S:	Maintained
 W:	https://linuxtv.org
 T:	git git://linuxtv.org/media_tree.git
-F:	Documentation/media/v4l-drivers/em28xx*
+F:	Documentation/admin-guide/media/em28xx*
 F:	drivers/media/usb/em28xx/
 
 EMBEDDED LINUX
@@ -7178,7 +7194,7 @@ L:	cluster-devel@redhat.com
 S:	Supported
 W:	http://sources.redhat.com/cluster/
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2.git
-F:	Documentation/filesystems/gfs2*.txt
+F:	Documentation/filesystems/gfs2*
 F:	fs/gfs2/
 F:	include/uapi/linux/gfs2_ondisk.h
 
@@ -8641,16 +8657,16 @@ M:	Bingbu Cao <bingbu.cao@intel.com>
 R:	Tian Shu Qiu <tian.shu.qiu@intel.com>
 L:	linux-media@vger.kernel.org
 S:	Maintained
-F:	Documentation/media/uapi/v4l/pixfmt-srggb10-ipu3.rst
+F:	Documentation/userspace-api/media/v4l/pixfmt-srggb10-ipu3.rst
 F:	drivers/media/pci/intel/ipu3/
 
 INTEL IPU3 CSI-2 IMGU DRIVER
 M:	Sakari Ailus <sakari.ailus@linux.intel.com>
 L:	linux-media@vger.kernel.org
 S:	Maintained
-F:	Documentation/media/uapi/v4l/pixfmt-meta-intel-ipu3.rst
-F:	Documentation/media/v4l-drivers/ipu3.rst
-F:	Documentation/media/v4l-drivers/ipu3_rcb.svg
+F:	Documentation/userspace-api/media/v4l/pixfmt-meta-intel-ipu3.rst
+F:	Documentation/admin-guide/media/ipu3.rst
+F:	Documentation/admin-guide/media/ipu3_rcb.svg
 F:	drivers/staging/media/ipu3/
 
 INTEL IXP4XX QMGR, NPE, ETHERNET and HSS SUPPORT
@@ -9074,7 +9090,7 @@ L:	linux-media@vger.kernel.org
 S:	Maintained
 W:	https://linuxtv.org
 T:	git git://linuxtv.org/media_tree.git
-F:	Documentation/media/v4l-drivers/ivtv*
+F:	Documentation/admin-guide/media/ivtv*
 F:	drivers/media/pci/ivtv/
 F:	include/uapi/linux/ivtv*
 
@@ -9181,6 +9197,17 @@ F:	Documentation/kbuild/kconfig*
 F:	scripts/Kconfig.include
 F:	scripts/kconfig/
 
+KCSAN
+M:	Marco Elver <elver@google.com>
+R:	Dmitry Vyukov <dvyukov@google.com>
+L:	kasan-dev@googlegroups.com
+S:	Maintained
+F:	Documentation/dev-tools/kcsan.rst
+F:	include/linux/kcsan*.h
+F:	kernel/kcsan/
+F:	lib/Kconfig.kcsan
+F:	scripts/Makefile.kcsan
+
 KDUMP
 M:	Dave Young <dyoung@redhat.com>
 M:	Baoquan He <bhe@redhat.com>
@@ -9412,6 +9439,13 @@ F:	include/linux/keyctl.h
 F:	include/uapi/linux/keyctl.h
 F:	security/keys/
 
+KFIFO:
+M:	Stefani Seibold <stefani@seibold.net>
+S:	Maintained
+F:	lib/kfifo.c
+F:	include/linux/kfifo.h
+F:	samples/kfifo/
+
 KGDB / KDB /debug_core
 M:	Jason Wessel <jason.wessel@windriver.com>
 M:	Daniel Thompson <daniel.thompson@linaro.org>
@@ -9806,6 +9840,7 @@ M:	Luc Maranget <luc.maranget@inria.fr>
 M:	"Paul E. McKenney" <paulmck@kernel.org>
 R:	Akira Yokosawa <akiyks@gmail.com>
 R:	Daniel Lustig <dlustig@nvidia.com>
+R:	Joel Fernandes <joel@joelfernandes.org>
 L:	linux-kernel@vger.kernel.org
 L:	linux-arch@vger.kernel.org
 S:	Supported
@@ -9816,6 +9851,7 @@ F:	Documentation/core-api/atomic_ops.rst
 F:	Documentation/core-api/refcount-vs-atomic.rst
 F:	Documentation/memory-barriers.txt
 F:	tools/memory-model/
+F:	Documentation/litmus-tests/
 
 LIS3LV02D ACCELEROMETER DRIVER
 M:	Eric Piel <eric.piel@tremplin-utc.net>
@@ -10247,7 +10283,7 @@ L:	linux-media@vger.kernel.org
 S:	Maintained
 T:	git git://linuxtv.org/media_tree.git
 F:	Documentation/devicetree/bindings/media/i2c/max2175.txt
-F:	Documentation/media/v4l-drivers/max2175.rst
+F:	Documentation/userspace-api/media/drivers/max2175.rst
 F:	drivers/media/i2c/max2175*
 F:	include/uapi/linux/max2175.h
 
@@ -10448,7 +10484,7 @@ L:	linux-media@vger.kernel.org
 S:	Maintained
 T:	git git://linuxtv.org/media_tree.git
 F:	Documentation/devicetree/bindings/media/imx.txt
-F:	Documentation/media/v4l-drivers/imx.rst
+F:	Documentation/admin-guide/media/imx.rst
 F:	drivers/staging/media/imx/
 F:	include/linux/imx-media.h
 F:	include/media/imx.h
@@ -10460,7 +10496,7 @@ S:	Maintained
 T:	git git://linuxtv.org/media_tree.git
 F:	Documentation/devicetree/bindings/media/imx7-csi.txt
 F:	Documentation/devicetree/bindings/media/imx7-mipi-csi2.txt
-F:	Documentation/media/v4l-drivers/imx7.rst
+F:	Documentation/admin-guide/media/imx7.rst
 F:	drivers/staging/media/imx/imx7-media-csi.c
 F:	drivers/staging/media/imx/imx7-mipi-csis.c
 
@@ -10607,7 +10643,9 @@ W:	https://linuxtv.org
 Q:	http://patchwork.kernel.org/project/linux-media/list/
 T:	git git://linuxtv.org/media_tree.git
 F:	Documentation/devicetree/bindings/media/
-F:	Documentation/media/
+X:	Documentation/admin-guide/media/
+F:	Documentation/userspace-api/media/
+F:	Documentation/driver-api/media/
 F:	drivers/media/
 F:	drivers/staging/media/
 F:	include/linux/platform_data/media/
@@ -11385,7 +11423,7 @@ F:	drivers/regulator/mpq7920.h
 MOTION EYE VAIO PICTUREBOOK CAMERA DRIVER
 S:	Orphan
 W:	http://popies.net/meye/
-F:	Documentation/media/v4l-drivers/meye*
+F:	Documentation/userspace-api/media/drivers/meye*
 F:	drivers/media/pci/meye/
 F:	include/uapi/linux/meye.h
 
@@ -13697,7 +13735,7 @@ M:	Hans Verkuil <hverkuil@xs4all.nl>
 L:	linux-media@vger.kernel.org
 S:	Maintained
 T:	git git://linuxtv.org/media_tree.git
-F:	Documentation/media/cec-drivers/pulse8-cec.rst
+F:	Documentation/admin-guide/media/pulse8-cec.rst
 F:	drivers/media/usb/pulse8-cec/*
 
 PVRUSB2 VIDEO4LINUX DRIVER
@@ -13707,7 +13745,7 @@ L:	linux-media@vger.kernel.org
 S:	Maintained
 W:	http://www.isely.net/pvrusb2/
 T:	git git://linuxtv.org/media_tree.git
-F:	Documentation/media/v4l-drivers/pvrusb2*
+F:	Documentation/driver-api/media/drivers/pvrusb2*
 F:	drivers/media/usb/pvrusb2/
 
 PWC WEBCAM DRIVER
@@ -13853,7 +13891,8 @@ S:	Maintained
 F:	drivers/scsi/qla1280.[ch]
 
 QLOGIC QLA2XXX FC-SCSI DRIVER
-M:	hmadhani@marvell.com
+M:	Nilesh Javali <njavali@marvell.com>
+M:	GR-QLogic-Storage-Upstream@marvell.com
 L:	linux-scsi@vger.kernel.org
 S:	Supported
 F:	Documentation/scsi/LICENSE.qla2xxx
@@ -13954,7 +13993,7 @@ M:	Todor Tomov <todor.too@gmail.com>
 L:	linux-media@vger.kernel.org
 S:	Maintained
 F:	Documentation/devicetree/bindings/media/qcom,camss.txt
-F:	Documentation/media/v4l-drivers/qcom_camss.rst
+F:	Documentation/admin-guide/media/qcom_camss.rst
 F:	drivers/media/platform/qcom/camss/
 
 QUALCOMM CORE POWER REDUCTION (CPR) AVS DRIVER
@@ -14467,7 +14506,8 @@ M:	Jacob Chen <jacob-chen@iotwrt.com>
 M:	Ezequiel Garcia <ezequiel@collabora.com>
 L:	linux-media@vger.kernel.org
 S:	Maintained
-F:	Documentation/devicetree/bindings/media/rockchip-rga.txt
+F:	Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
+F:	Documentation/devicetree/bindings/media/rockchip-vpu.yaml
 F:	drivers/media/platform/rockchip/rga/
 
 ROCKER DRIVER
@@ -14716,7 +14756,7 @@ L:	linux-media@vger.kernel.org
 S:	Odd fixes
 W:	https://linuxtv.org
 T:	git git://linuxtv.org/media_tree.git
-F:	Documentation/media/v4l-drivers/saa7134*
+F:	Documentation/driver-api/media/drivers/saa7134*
 F:	drivers/media/pci/saa7134/
 
 SAA7146 VIDEO4LINUX-2 DRIVER
@@ -16227,6 +16267,7 @@ F:	drivers/tty/serial/8250/8250_lpss.c
 
 SYNOPSYS DESIGNWARE APB GPIO DRIVER
 M:	Hoan Tran <hoan@os.amperecomputing.com>
+M:	Serge Semin <fancer.lancer@gmail.com>
 L:	linux-gpio@vger.kernel.org
 S:	Maintained
 F:	Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt
@@ -16968,7 +17009,7 @@ L:	linux-media@vger.kernel.org
 S:	Odd fixes
 W:	https://linuxtv.org
 T:	git git://linuxtv.org/media_tree.git
-F:	Documentation/media/v4l-drivers/tm6000*
+F:	Documentation/admin-guide/media/tm6000*
 F:	drivers/media/usb/tm6000/
 
 TMIO/SDHI MMC DRIVER
@@ -17649,7 +17690,7 @@ L:	linux-media@vger.kernel.org
 S:	Maintained
 W:	http://royale.zerezo.com/zr364xx/
 T:	git git://linuxtv.org/media_tree.git
-F:	Documentation/media/v4l-drivers/zr364xx*
+F:	Documentation/admin-guide/media/zr364xx*
 F:	drivers/media/usb/zr364xx/
 
 USER-MODE LINUX (UML)
@@ -17798,7 +17839,7 @@ L:	linux-media@vger.kernel.org
 S:	Maintained
 W:	https://linuxtv.org
 T:	git git://linuxtv.org/media_tree.git
-F:	drivers/media/platform/vicodec/*
+F:	drivers/media/test-drivers/vicodec/*
 
 VIDEO I2C POLLING DRIVER
 M:	Matt Ranostay <matt.ranostay@konsulko.com>
@@ -17829,7 +17870,7 @@ L:	linux-media@vger.kernel.org
 S:	Maintained
 W:	https://linuxtv.org
 T:	git git://linuxtv.org/media_tree.git
-F:	drivers/media/platform/vimc/*
+F:	drivers/media/test-drivers/vimc/*
 
 VIRT LIB
 M:	Alex Williamson <alex.williamson@redhat.com>
@@ -17996,7 +18037,7 @@ L:	linux-media@vger.kernel.org
 S:	Maintained
 W:	https://linuxtv.org
 T:	git git://linuxtv.org/media_tree.git
-F:	drivers/media/platform/vivid/*
+F:	drivers/media/test-drivers/vivid/*
 
 VLYNQ BUS
 M:	Florian Fainelli <f.fainelli@gmail.com>
diff --git a/Makefile b/Makefile
index 70def4907036..dd055e0bf37b 100644
--- a/Makefile
+++ b/Makefile
@@ -499,7 +499,7 @@ export KBUILD_HOSTCXXFLAGS KBUILD_HOSTLDFLAGS KBUILD_HOSTLDLIBS LDFLAGS_MODULE
 
 export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS KBUILD_LDFLAGS
 export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE
-export CFLAGS_KASAN CFLAGS_KASAN_NOSANITIZE CFLAGS_UBSAN
+export CFLAGS_KASAN CFLAGS_KASAN_NOSANITIZE CFLAGS_UBSAN CFLAGS_KCSAN
 export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
 export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE KBUILD_LDFLAGS_MODULE
 export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL
@@ -920,6 +920,7 @@ endif
 include scripts/Makefile.kasan
 include scripts/Makefile.extrawarn
 include scripts/Makefile.ubsan
+include scripts/Makefile.kcsan
 
 # Add user supplied CPPFLAGS, AFLAGS and CFLAGS as the last assignments
 KBUILD_CPPFLAGS += $(KCPPFLAGS)
diff --git a/Next/SHA1s b/Next/SHA1s
new file mode 100644
index 000000000000..b540a15da139
--- /dev/null
+++ b/Next/SHA1s
@@ -0,0 +1,319 @@
+Name		SHA1
+----		----
+origin		2fcd80144b93ff90836a44f2054b4d82133d3a85
+fixes		6b038bdcd3d139f8da5f2eb08e275f9e57276df7
+kbuild-current	d2f1606edabd9ebba096b0efb133558f1aad6e88
+arc-current	5185f4773e906d477b2040d8eb6853ab330917e7
+arm-current	89604523a76eb3e13014b2bdab7f8870becee284
+arm-soc-fixes	c8042d1e5cb3e654b47447229ace3cd092a8fc27
+arm64-fixes	c9a4ef66450145a356a626c833d3d7b1668b3ded
+m68k-current	86cded5fc52567774b596827544874499532b8ae
+powerpc-fixes	1d0c32ec3b860a32df593a22bad0d1dbc5546a59
+s390-fixes	8f3d9f354286745c751374f5f1fcafee6b3f3136
+sparc		63bef48fd6c9d3f1ba4f0e23b4da1e007db6a3c0
+fscrypt-current	2b4eae95c7361e0a147b838715c8baa1380a428f
+net		2fcd80144b93ff90836a44f2054b4d82133d3a85
+bpf		edadedf1c5b4e4404192a0a4c3c0c05e3b7672ab
+ipsec		91fac45cd0061854633036695cf37a11befa8062
+netfilter	bc8e71314e8444c6315c482441f3204c032ab327
+ipvs		0141317611ab913d6c227b82f3dd02ff3e6fc5d8
+wireless-drivers	7dc7c41607d192ff660ba4ea82d517745c1d7523
+mac80211		93e2d04a1888668183f3fb48666e90b9b31d29e6
+rdma-fixes	8f3d9f354286745c751374f5f1fcafee6b3f3136
+sound-current	9a6418487b566503c772cb6e7d3d44e652b019b0
+sound-asoc-fixes	630c50e34d333a6b57c0a86bdf605bd1c4470cbb
+regmap-fixes	b810878a8feef52c402da8f02398195bf5b7dded
+regulator-fixes	8f3d9f354286745c751374f5f1fcafee6b3f3136
+spi-fixes	4bbae1279dfe6f5dac528b27726122a564c271c0
+pci-current	8f3d9f354286745c751374f5f1fcafee6b3f3136
+driver-core.current	8f3d9f354286745c751374f5f1fcafee6b3f3136
+tty.current	3dc4db3662366306e54ddcbda4804acb1258e4ba
+usb.current	be34a5854b4606bd7a160ad3cb43415d623596c7
+usb-gadget-fixes	d0550cd20e52558ecf6847a0f96ebd5d944c17e4
+usb-serial-fixes	8f3d9f354286745c751374f5f1fcafee6b3f3136
+usb-chipidea-fixes	7cbf3dd3139ab4683d9cffe9d6972a1dbe3ecaa6
+phy		8f3d9f354286745c751374f5f1fcafee6b3f3136
+staging.current	ea81c3486442f4643fc9825a2bb1b430b829bccd
+char-misc.current	8f3d9f354286745c751374f5f1fcafee6b3f3136
+soundwire-fixes	8f3d9f354286745c751374f5f1fcafee6b3f3136
+thunderbolt-fixes	8f3d9f354286745c751374f5f1fcafee6b3f3136
+input-current	3f8f770575d911c989043d8f0fb8dec96360c41c
+crypto-current	55b3209acbb01cb02b1ee6b1afe80d83b1aab36d
+ide		63bef48fd6c9d3f1ba4f0e23b4da1e007db6a3c0
+vfio-fixes	95f89e090618efca63918b658c2002e57d393036
+kselftest-fixes	8f3d9f354286745c751374f5f1fcafee6b3f3136
+modules-fixes	57baec7b1b0459ef885e816d8c28a9d9a62bb8de
+slave-dma-fixes	aee45dba3ad9c87affa95e50747fbb82ff4b2e20
+backlight-fixes	219d54332a09e8d8741c1e1982f5eae56099de85
+mtd-fixes	2098c564701c0dde76063dd9c5c00a7a1f173541
+mfd-fixes	603d9299da32955d49995738541f750f2ae74839
+v4l-dvb-fixes	8f3d9f354286745c751374f5f1fcafee6b3f3136
+reset-fixes	b460e0a9e2404450a0cc4c5e6476483d6cda1b26
+mips-fixes	8f3d9f354286745c751374f5f1fcafee6b3f3136
+at91-fixes	54ecb8f7028c5eb3d740bb82b0f1d90f2df63c5c
+omap-fixes	07bdc492cff6f555538df95e9812fe72e16d154a
+kvm-fixes	dbef2808af6c594922fe32833b30f55f35e9da6d
+kvms390-fixes	1493e0f944f3c319d11e067c185c904d01c17ae5
+hwmon-fixes	0e786f328b382e6df64f31390973b81f8fb9a044
+nvdimm-fixes	f84afbdd3a9e5e10633695677b95422572f920dc
+btrfs-fixes	9dba7a2365044653f5e4016be887f88012e605eb
+vfs-fixes	5bd73286d50fc242bbff1aaddb0e97c4527c9d78
+dma-mapping-fixes	9c24eaf81cc44d4bb38081c99eafd72ed85cf7f3
+i3c-fixes	6fbc7275c7a9ba97877050335f290341a1fd8dbf
+drivers-x86-fixes	8f3d9f354286745c751374f5f1fcafee6b3f3136
+samsung-krzk-fixes	8f3d9f354286745c751374f5f1fcafee6b3f3136
+pinctrl-samsung-fixes	8f3d9f354286745c751374f5f1fcafee6b3f3136
+devicetree-fixes	1bfed6c62d72a6145b2f230a84306ced2227863f
+scsi-fixes	fa17a6dc84d1eb6b62bcf981a4ddcc966b1a2c04
+drm-fixes	4da858c086433cd012c0bb16b5921f6fafe3f803
+amdgpu-fixes	2c409ba81be25516afe05ae27a4a15da01740b01
+drm-intel-fixes	5809e8f8ee42db54c283c3a6bcfcbbdbfd888f5c
+mmc-fixes	3d3e18fcd5915c75fe97e19c07fcb15ffea3d1eb
+rtc-fixes	bb6d3fb354c5ee8d6bde2d576eb7220ea09862b9
+gnss-fixes	8f3d9f354286745c751374f5f1fcafee6b3f3136
+hyperv-fixes	1a06d017fb3f388734ffbe5dedee6f8c3af5f2db
+soc-fsl-fixes	fe8fe7723a3a824790bda681b40efd767e2251a7
+risc-v-fixes	2191b4f298fa360f2d1d967c2c7db565bea2c32e
+pidfd-fixes	a966dcfe153ab0a3d8d79cd971a079411a489be7
+fpga-fixes	3c2760b78f90db874401d97e3c17829e2e36f400
+spdx		5b8b9d0c6d0e0f1993c6c56deaf9646942c49d94
+gpio-intel-fixes	8f3d9f354286745c751374f5f1fcafee6b3f3136
+pinctrl-intel-fixes	ccd025eaddaeb99e982029446197c544252108e2
+erofs-fixes	d1eef1c619749b2a57e514a3fa67d9a516ffa919
+drm-misc-fixes	8623b5255ae7ccaf276aac3920787bf575fa6b37
+kspp-gustavo	90e5d84c7b06b849a330ea43625086ff81388ed4
+kbuild		b032227c62939b5481bcd45442b36dfa263f4a7c
+compiler-attributes	98d54f81e36ba3bf92172791eba5ca5bd813989b
+leaks		9e98c678c2d6ae3a17cb2de55d17f69dddaa231b
+dma-mapping	9bb50ed7470944238ec8e30a94ef096caf9056ee
+asm-generic	060dc911501f6ee222569304f50962172a52b1d6
+arc		def9d2780727cec3313ed3522d0123158d87224d
+arm		52d3b2f98483c34af44171dd10f43f90b7cf1ae0
+arm64		fc2266011accd5aeb8ebc335c381991f20e26e33
+arm-perf		8f3d9f354286745c751374f5f1fcafee6b3f3136
+arm-soc		d9725e56e1d806021cb277c3faf0c9ffad621576
+amlogic		8f3d9f354286745c751374f5f1fcafee6b3f3136
+aspeed		de285b938cf330b30acfdb037d14018d38292c3e
+at91		ec539e70d882af33660bcab178a59b1251588a22
+imx-mxs		46535d78fdfe5e7ac8205a66bbf1fc838d91eb7d
+keystone		560b4d4691b07819f8d3e0cb030f72f863ec1ba3
+mediatek		23a1613226584c00ac303b563b37b62cf70e2e74
+mvebu		9d32706f8aa8bbea3722e8f074801c0807d19951
+omap		e90f16cc1a48c3ca39f3a1756b3f1fd34fedbc62
+qcom		217aeedd10d5b89f3be5d4cd0c8ce5856aef3f98
+raspberrypi	e7b7daeb48e0bf5d8412d77f11069750ee7032bb
+realtek		486f29df69413411a205d3101bae0427a892bee4
+renesas		a710158e9fa209a4187d46ecfba49d4c1664cb0f
+reset		2ebf89fd4ecf37e7ae4c323a9fd69f9d9d0ea260
+rockchip		c018aff1a20156b60e0cf9cc906a21e2e64767e6
+samsung-krzk	ff602fc2b39eb0beff2466132f7eec218fbde9ae
+scmi		8f3d9f354286745c751374f5f1fcafee6b3f3136
+sunxi		4f7a2d7e5f1e6c881b065303230a329d71a41c07
+tegra		9546812c92ef0b37c933bd2c0fa6aa5915f83041
+clk		e7f552f727f58cbb524f3b574ac253dc3e0e7508
+clk-samsung	54ecb8f7028c5eb3d740bb82b0f1d90f2df63c5c
+c6x		8adcc59974b8a65b7eac7d503364837c297139bc
+csky		10cb08260605a6ef5a2db13e900f2f1596fba96a
+h8300		beab3d5cb0e14e6397c4e596b3dbf1d36bf49d06
+ia64		172e7890406d6183b9b39271ffb434ff0a97ce72
+m68k		86cded5fc52567774b596827544874499532b8ae
+m68knommu	ba000760eb0f182e6ef04faca70bb9737a9674b4
+microblaze	8f3d9f354286745c751374f5f1fcafee6b3f3136
+mips		c02e96304451ad3e22c58235061a8363c30116b6
+nds32		d785c5a324cd8812720a409dc85050558281a567
+nios2		0ec8a5054d7fc5e31509fed7893358564ede2477
+openrisc		9737e2c5f0bc768b58416ec070bd96c91c52a153
+parisc-hd	7111951b8d4973bda27ff663f2cf18b663d15b48
+powerpc		6ba4a2d3591039aea1cb45c7c42262d26351a2fa
+fsl		a76bea0287ce13d28494b19649d80d8ee5e7b757
+soc-fsl		461c3ac0dc46ba7fc09628aadf63c81253c4c3de
+risc-v		37809df4b1c88927fe944eb766e0553811c51f64
+sifive		467e050e9760fc31dcf854ec88401e18419f5f78
+s390		8f3d9f354286745c751374f5f1fcafee6b3f3136
+sh		a193018e5290ee9d9fe62ad80cd8f874711eb575
+sparc-next	b71acb0e372160167bf6d5500b88b30b52ccef6e
+uml		4a7c46247f9c620c0390a15cb00b6ef9576b9c23
+xtensa		70cbddb973859158731ce77ab20cd5e53822c089
+fscrypt		861261f2a9cc488c845fc214d9035f7a11094591
+afs		4fe171bb81b13b40bf568330ec3716dfb304ced1
+btrfs		5a7ef5cb05dc077737d88162aeaa8661acc2a946
+ceph		2a575f138d003fff0f4930b5cfae4a1c46343b8f
+cifs		9692ea9d3288a201df762868a52552b2e07e1c55
+configfs		e2f238f7d5a1fa69ff1884d37acf9a2a3a01b308
+ecryptfs		8b614cb8f1dcac8ca77cf4dd85f46ef3055f8238
+erofs		8f3d9f354286745c751374f5f1fcafee6b3f3136
+exfat		b65dea785ed9aff9b91e395f02107c9643ca0c2d
+ext3		a32f0ecd79b4757e417b778c8dc64916e93f7b80
+ext4		12fb08d1900543d66edb6e0af36efbe3b2f56c5c
+f2fs		08d834cd9599c45a213acdcc78cf6aa8fa447e75
+fsverity		98d54f81e36ba3bf92172791eba5ca5bd813989b
+fuse		3e8cb8b2eaeb22f540f1cbc00cbb594047b7ba89
+jfs		7aba5dcc234635b44b2781dbc268048cfba388ad
+nfs		fbf4bcc9a8373122881909331f2f9566a128126e
+nfs-anna		55dee1bc0d72877b99805e42e0205087e98b9edd
+nfsd		2653de9f0398b3230bb098704451ba16be5458f0
+orangefs		aa317d3351dee7cb0b27db808af0cd2340dcbaef
+overlayfs	2eda9eaa6d7ec129150df4c7b7be65f27ac47346
+ubifs		3676f32a98cd6ed4481c21bceb8b4829d4b6d1cf
+v9fs		c6f141412d24c8d8a9d98ef45303c0235829044b
+xfs		63dc90feaa204437b8aed700eb7d572c581fbe19
+zonefs		0dda2ddb7ded1395189e95d43106469687c07795
+iomap		457df33e035a2cffc6561992f3f25a6c61605c46
+djw-vfs		56939e014a6c212b317414faa307029e2e80c3b9
+file-locks	dbdaf6a3250b9cda6d7f761e9ff8b8bed8409a38
+vfs		ffca8b2a77f27cdaec081a8bd447f8a5c59af142
+printk		d34f14ae521f076f68f3ce213c64193f9a5a8adf
+pci		8f3d9f354286745c751374f5f1fcafee6b3f3136
+pstore		8f3d9f354286745c751374f5f1fcafee6b3f3136
+hid		ce01b5b5386f3a7c48d76c90b5281134ea3e0589
+i2c		8859c2d37301b392c688fa2b6db483dec4fab310
+i3c		c4b9de11d0101792c4d5458b18581f4f527862d1
+dmi		8cf87c7446968660a8e997b4427be5340c2825ef
+hwmon-staging	635049d0e3a0464a63e85b382640446e06d581a7
+jc_docs		d98dbbe0d331b1a6dc1ca0b948c99d58cdba580c
+v4l-dvb		dacca5f0fa69f04c2e70aad9847e8250b459971c
+v4l-dvb-next	54ecb8f7028c5eb3d740bb82b0f1d90f2df63c5c
+fbdev		732146a3f1dc78ebb0d3c4b1f4dc6ea33cc2c58f
+pm		1f58b05f6672d307191bb29b3617ab8e8c96baca
+cpufreq-arm	8be6bbe59a6915ad9569e1353d1ea24f74d25e8e
+cpupower		8f3d9f354286745c751374f5f1fcafee6b3f3136
+opp		aca48b61f963869ccbb5cf84805a7ad68bf812cd
+thermal		79799562bf087b30d9dd0fddf5bed2d3b038be08
+thermal-rzhang	54ecb8f7028c5eb3d740bb82b0f1d90f2df63c5c
+thermal-soc	6c375eccded41df8033ed55a1b785531b304fc67
+ieee1394		67f8e65e4fc19e24993e8780f41279eeffbd0610
+dlm		a48f9721e6db74dfbeb8d4a2cd616b20017f4b78
+swiotlb		4cdfb27ba80d29aa04bc340b2e4b59e9ae74004c
+rdma		8f3d9f354286745c751374f5f1fcafee6b3f3136
+net-next		2fcd80144b93ff90836a44f2054b4d82133d3a85
+bpf-next		1a323ea5356edbb3073dc59d51b9e6b86908857d
+ipsec-next	308491755f36c461ee67290af159fdba6be0169d
+mlx5-next	826096d84f509d95ee8f72728fe19c44fbb9df6b
+netfilter-next	1a323ea5356edbb3073dc59d51b9e6b86908857d
+ipvs-next	d54725cd11a57c30f650260cfb0a92c268bdc3e0
+wireless-drivers-next	f0f383347ced96416d5e3062f8bb2b0f99ac9d5b
+bluetooth	7edc9079540b65026f3d3386b3642d1820d5fed5
+mac80211-next	1e8f471425f4012f2c98f228ac2ba19cea22c39b
+gfs2		197694d09af5b8a15c6d012c11f1b71ec094c3fa
+mtd		025a06c1104cd8995646b761d117816b5f28c873
+nand		fca88925d76978b7f20de42d8ead34fb91500003
+spi-nor		8f3d9f354286745c751374f5f1fcafee6b3f3136
+crypto		0a8f5989e03476cfb2a7756e33fa4d0163cb4375
+drm		8f3d9f354286745c751374f5f1fcafee6b3f3136
+amdgpu		4781c25592de03aa82f204440b56a7089c347068
+drm-intel	cef622d7634e0adc351d795f089e7b77700272ca
+drm-tegra	e32c8c2a5fbe1514e4ae9063a49e76ecf486ffb8
+drm-misc		13e3d94110d82e318d640d0980896d32e02ba4d6
+drm-msm		a5fb8b918920c6f7706a8b5b8ea535a7f077a7f6
+mali-dp		f634c6a8028789b05a9277a3d51303829ae29547
+imx-drm		2c76b324c7944fedf453abca5003569d9556c6df
+etnaviv		f232d9ec029ce3e2543b05213e2979e01e503408
+regmap		f320d878bff2ccc8b5ee2e8828ce9588f96507ec
+sound		3e8f3bd047163d30fb1ad32ca7e4628921555c09
+sound-asoc	33c385056aadd08490f3ccf5e8b10314f26fb195
+modules		0f74226649fb2875a91b68f3750f55220aa73425
+input		3a8579629665bd6c0b37afcb2291080e959b885d
+block		8f3d9f354286745c751374f5f1fcafee6b3f3136
+device-mapper	ad4e80a639fc61d5ecebb03caa5cdbfb91fcebfc
+pcmcia		a8c122f72d944f0e77b58c8b44a539a8f0e39017
+mmc		23ecdb29060f7ea770927de5c9bd51fc80b312c7
+md		e820d55cb99dd93ac2dc949cf486bb187e5cd70d
+mfd		d2923aa4535664ae5c46c3a093985afd18fec118
+backlight	ee0c8e494cc3c135350cd5c4752e82af3feae1ab
+battery		164eaf6b435c31d98fdabe0151e979fa0b4280a0
+regulator	2ea8db7200d40f89ebfb97fc512ced5f792e0e1c
+security		3e27a33932df104f4f9ff811467b0b4ccebde773
+apparmor		01df52d726b5d55d2970f5c957f1961930acd5d6
+integrity	9e2b4be377f0d715d9d910507890f9620cc22a9d
+keys		43672cf93c6d96380222064aec06e9593113cdea
+selinux		433e3aa37773e8a36858b9417c3e345eff79a079
+smack		92604e825304ce170955df44b00973843054dcd5
+tomoyo		8f3d9f354286745c751374f5f1fcafee6b3f3136
+tpmdd		8e0ea46271519d2a1cfb2d5173dde7cb916f3634
+watchdog		ea104a9e4d3e9ebc26fb78dac35585b142ee288b
+iommu		ff68eb23308e6538ec7864c83d39540f423bbe90
+vfio		f44efca0493ddc1e8731047c234ec8e475943077
+audit		8f3d9f354286745c751374f5f1fcafee6b3f3136
+devicetree	9f60a65bc5e6cd882120d8477cc7bec065887e3d
+mailbox		0a67003b1985c79811160af1b01aca07cd5fbc53
+spi		5810dd79dec450b8eecafa4605b3e54befeb891e
+tip		1030eb5ea1451558015c119bb7d4b6ddca6caa0f
+clockevents	c1ac28a4de6f848ef17b43ee76d1f28a219c3785
+edac		d9976bc155b11a0875a361e656255c64964d8090
+irqchip		4cea749d56bec9409f3bd126d2b2f949dc6c66e2
+ftrace		8e99cf91b99bb30e16727f10ad6828741c0e992f
+rcu		35095790846431ef9398bbc4875d8eb8515dd5ca
+kvm		dbef2808af6c594922fe32833b30f55f35e9da6d
+kvm-arm		463050599742a89e0508355e626e032e8d0dab8d
+kvm-ppc		9a5788c615f52f6d7bf0b61986a632d4ec86791d
+kvms390		7a2653612bb6f18fb236c5b0c4d28f7b459bf7c2
+xen-tip		6b51fd3f65a22e3d1471b18a1d56247e246edd46
+percpu		dedac37ea96b23c23b72d6e90f01d060d5287e4e
+workqueues	4acf8a423cd321248b4cc9eb21c11bb88931938b
+drivers-x86	8f3d9f354286745c751374f5f1fcafee6b3f3136
+chrome-platform	9d33ea331032332882d4cc1a38a9d0e237126bd0
+hsi		bb6d3fb354c5ee8d6bde2d576eb7220ea09862b9
+leds		10a6cce3c1a15e40dd7b69e66e4780476e590f68
+ipmi		ab032f08dc4584c4f2f73f4973d9a954a6787f47
+driver-core	8f3d9f354286745c751374f5f1fcafee6b3f3136
+usb		8f3d9f354286745c751374f5f1fcafee6b3f3136
+usb-gadget	4a5dbd9009570d3b23fd1392c4d178bfe3538d2c
+usb-serial	8f3d9f354286745c751374f5f1fcafee6b3f3136
+usb-chipidea-next	95caa2ae70fdbf626335700d24400f47c12825ee
+phy-next		8f3d9f354286745c751374f5f1fcafee6b3f3136
+tty		8f3d9f354286745c751374f5f1fcafee6b3f3136
+char-misc	8f3d9f354286745c751374f5f1fcafee6b3f3136
+extcon		8f3d9f354286745c751374f5f1fcafee6b3f3136
+soundwire	8f3d9f354286745c751374f5f1fcafee6b3f3136
+thunderbolt	cbb5494ebce5dfafab27de01e7e8bfe6d7c6a27f
+staging		ce920326663b3df22c94ade99a8b234baa6ccaa5
+mux		f356d58c3a04159f35003b26f8c5183f9456f95d
+icc		03c4e6186bbbe639b5277077c26786069e9e2b89
+slave-dma	c2ce6bbcfc9f142b426717bc5aa3f9ba20485a65
+cgroup		eec8fd0277e37cf447b88c6be181e81df867bcf1
+scsi		8d5e0fd1f2884e37c9754ac74a88c2bbe264a963
+scsi-mkp		1e4ffb8344c53b3d8297c9591c59debe4406e6cb
+vhost		1f8209a5564af6cd4e129b8e9230bba577906c4a
+rpmsg		ee7cef848adf02e61956a0964e84ccbaf166b8e6
+gpio		bbcb9d87dfa9f4d83de87e401ad3aa087adf7c70
+gpio-brgl	96d7c7b3e6545612c1d37944621fdd611afd6adf
+gpio-intel	8f3d9f354286745c751374f5f1fcafee6b3f3136
+pinctrl		aeddc3b7826643fbfa50c65793a127fa7f02d566
+pinctrl-intel	5f3b82a168d597099dfc20e47e9389c1f7d0c11b
+pinctrl-samsung	b577a279914085c6b657c33e9f39ef56d96a3302
+pwm		6f0841a8197b20d01de9d41cb1eeed09b7b31f9b
+userns		4fa3b1c417377c352208ee9f487e17cfcee32348
+ktest		1091c8fce8aa9c5abe1a73acab4bcaf58a729005
+random		ab9a7e27044b87ff2be47b8f8e095400e7fccc44
+kselftest	b87080eab4c1377706c113fc9c0157f19ea8fed1
+y2038		c4e71212a245017d2ab05f322f7722f0b87a55da
+livepatching	d28b4c1b2b3d1337069cbe0bf0bec151d0e4d576
+coresight	25a0b4731117bbd100cbe346edf5deea58423faa
+rtc		11ddbdfb68e4f9791e4bd4f8d7c87d3f19670967
+nvdimm		f6d2b802f80d0ca89ee1f51c1781b3f79cdb25d5
+at24		8f3d9f354286745c751374f5f1fcafee6b3f3136
+ntb		5cc3de3c74357b78202ed86ef68ee03d00267e6d
+kspp		c7527373fe28f97d8a196ab562db5589be0d34b9
+cisco		9e98c678c2d6ae3a17cb2de55d17f69dddaa231b
+gnss		8f3d9f354286745c751374f5f1fcafee6b3f3136
+fsi		2c01397b71c5e5001752046328d7f2aaf51b4c13
+slimbus		8f3d9f354286745c751374f5f1fcafee6b3f3136
+nvmem		8f3d9f354286745c751374f5f1fcafee6b3f3136
+xarray		27586ca786a729cda6c807621a1494900a56e7bc
+hyperv		e66b54d07be40dc5c0099a23deee6746f4e80809
+auxdisplay	2f920c0f0e29268827c2894c6e8f237a78159718
+kgdb		5ea771abd5a3734dfc55dee3772ff94ecc0b6f6a
+pidfd		6952a4f646446fde9e190b62c5e45f84c6cf91aa
+devfreq		a35a2f2b3e6e54e7ceee66f4bc3720cfb7d71490
+hmm		8f3d9f354286745c751374f5f1fcafee6b3f3136
+fpga		cef0ca6417de6c3805847b5e025a1e3af7c7d473
+kunit		8f3d9f354286745c751374f5f1fcafee6b3f3136
+cel		36b6e409294af454e5ec928c5fc7a878c3805d77
+generic-ioremap	4bdc0d676a643140bdf17dbf7eafedee3d496a3c
+cfi		b6fe8bc67d2d33a9eff1b0785482bccd14979115
+kunit-next	8f3d9f354286745c751374f5f1fcafee6b3f3136
+trivial		fad7c9020948eab2bc4661eade4e1ef357279590
+zx2c4		16fbf79b0f83bc752cee8589279f1ebfe57b3b6e
+mhi		8f3d9f354286745c751374f5f1fcafee6b3f3136
+akpm-current	547e35135ac5d10cfe5bb208830da744ebbd353d
+akpm		7a330aa1f8db1e6e2b401d8334434a3a43ee3620
diff --git a/Next/Trees b/Next/Trees
new file mode 100644
index 000000000000..2b889396182e
--- /dev/null
+++ b/Next/Trees
@@ -0,0 +1,321 @@
+Trees included into this release:
+
+Name		Type	URL
+----		----	---
+origin		git	git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git#master
+fixes		git	git://git.kernel.org/pub/scm/linux/kernel/git/sfr/next-fixes.git#master
+kbuild-current	git	git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild.git#fixes
+arc-current	git	git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc.git#for-curr
+arm-current	git	git://git.armlinux.org.uk/~rmk/linux-arm.git#fixes
+arm-soc-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git#arm/fixes
+arm64-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux#for-next/fixes
+m68k-current	git	git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k.git#for-linus
+powerpc-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git#fixes
+s390-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git#fixes
+sparc		git	git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc.git#master
+fscrypt-current	git	git://git.kernel.org/pub/scm/fs/fscrypt/fscrypt.git#for-stable
+net		git	git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git#master
+bpf		git	git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git#master
+ipsec		git	git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec.git#master
+netfilter	git	git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git#master
+ipvs		git	git://git.kernel.org/pub/scm/linux/kernel/git/horms/ipvs.git#master
+wireless-drivers	git	git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers.git#master
+mac80211		git	git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git#master
+rdma-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git#for-rc
+sound-current	git	git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git#for-linus
+sound-asoc-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git#for-linus
+regmap-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap.git#for-linus
+regulator-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git#for-linus
+spi-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git#for-linus
+pci-current	git	git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git#for-linus
+driver-core.current	git	git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git#driver-core-linus
+tty.current	git	git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git#tty-linus
+usb.current	git	git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git#usb-linus
+usb-gadget-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git#fixes
+usb-serial-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/johan/usb-serial.git#usb-linus
+usb-chipidea-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb.git#ci-for-usb-stable
+phy		git	git://git.kernel.org/pub/scm/linux/kernel/git/kishon/linux-phy.git#fixes
+staging.current	git	git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git#staging-linus
+char-misc.current	git	git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git#char-misc-linus
+soundwire-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire.git#fixes
+thunderbolt-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt.git#fixes
+input-current	git	git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git#for-linus
+crypto-current	git	git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6.git#master
+ide		git	git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide.git#master
+vfio-fixes	git	git://github.com/awilliam/linux-vfio.git#for-linus
+kselftest-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest.git#fixes
+modules-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/jeyu/linux.git#modules-linus
+slave-dma-fixes	git	git://git.infradead.org/users/vkoul/slave-dma.git#fixes
+backlight-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/lee/backlight.git#for-backlight-fixes
+mtd-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git#mtd/fixes
+mfd-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git#for-mfd-fixes
+v4l-dvb-fixes	git	git://linuxtv.org/mchehab/media-next.git#fixes
+reset-fixes	git	https://git.pengutronix.de/git/pza/linux#reset/fixes
+mips-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux.git#mips-fixes
+at91-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/at91/linux.git#at91-fixes
+omap-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap.git#fixes
+kvm-fixes	git	git://git.kernel.org/pub/scm/virt/kvm/kvm.git#master
+kvms390-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux.git#master
+hwmon-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git#hwmon
+nvdimm-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm.git#libnvdimm-fixes
+btrfs-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git#next-fixes
+vfs-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs.git#fixes
+dma-mapping-fixes	git	git://git.infradead.org/users/hch/dma-mapping.git#for-linus
+i3c-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux.git#master
+drivers-x86-fixes	git	git://git.infradead.org/linux-platform-drivers-x86.git#fixes
+samsung-krzk-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git#fixes
+pinctrl-samsung-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung.git#pinctrl-fixes
+devicetree-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git#dt/linus
+scsi-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git#fixes
+drm-fixes	git	git://git.freedesktop.org/git/drm/drm.git#drm-fixes
+amdgpu-fixes	git	git://people.freedesktop.org/~agd5f/linux#drm-fixes
+drm-intel-fixes	git	git://anongit.freedesktop.org/drm-intel#for-linux-next-fixes
+mmc-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc.git#fixes
+rtc-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux.git#rtc-fixes
+gnss-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/johan/gnss.git#gnss-linus
+hyperv-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux.git#hyperv-fixes
+soc-fsl-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/leo/linux.git#fix
+risc-v-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux.git#fixes
+pidfd-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/brauner/linux.git#fixes
+fpga-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/mdf/linux-fpga.git#fixes
+spdx		git	git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/spdx.git#spdx-linus
+gpio-intel-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/andy/linux-gpio-intel.git#fixes
+pinctrl-intel-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/intel.git#fixes
+erofs-fixes	git	git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git#fixes
+drm-misc-fixes	git	git://anongit.freedesktop.org/drm/drm-misc#for-linux-next-fixes
+kspp-gustavo	git	git://git.kernel.org/pub/scm/linux/kernel/git/gustavoars/linux.git#for-next/kspp
+kbuild		git	git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild.git#for-next
+compiler-attributes	git	https://github.com/ojeda/linux.git#compiler-attributes
+leaks		git	https://git.kernel.org/pub/scm/linux/kernel/git/tobin/leaks.git#leaks-next
+dma-mapping	git	git://git.infradead.org/users/hch/dma-mapping.git#for-next
+asm-generic	git	git://git.kernel.org/pub/scm/linux/kernel/git/arnd/asm-generic.git#master
+arc		git	git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc.git#for-next
+arm		git	git://git.armlinux.org.uk/~rmk/linux-arm.git#for-next
+arm64		git	git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux#for-next/core
+arm-perf		git	git://git.kernel.org/pub/scm/linux/kernel/git/will/linux.git#for-next/perf
+arm-soc		git	git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git#for-next
+amlogic		git	git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-amlogic.git#for-next
+aspeed		git	git://git.kernel.org/pub/scm/linux/kernel/git/joel/aspeed.git#for-next
+at91		git	git://git.kernel.org/pub/scm/linux/kernel/git/at91/linux-at91.git#at91-next
+imx-mxs		git	git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git#for-next
+keystone		git	git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone.git#next
+mediatek		git	git://git.kernel.org/pub/scm/linux/kernel/git/matthias.bgg/linux.git#for-next
+mvebu		git	git://git.infradead.org/linux-mvebu.git#for-next
+omap		git	git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap.git#for-next
+qcom		git	git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux.git#for-next
+raspberrypi	git	git://git.kernel.org/pub/scm/linux/kernel/git/nsaenz/linux-rpi.git#for-next
+realtek		git	git://git.kernel.org/pub/scm/linux/kernel/git/afaerber/linux-realtek.git#for-next
+renesas		git	git git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel.git#next
+reset		git	https://git.pengutronix.de/git/pza/linux#reset/next
+rockchip		git	git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git#for-next
+samsung-krzk	git	git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git#for-next
+scmi		git	git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux.git#for-linux-next
+sunxi		git	git://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux.git#sunxi/for-next
+tegra		git	git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git#for-next
+clk		git	git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git#clk-next
+clk-samsung	git	git://git.kernel.org/pub/scm/linux/kernel/git/snawrocki/clk.git#for-next
+c6x		git	git://linux-c6x.org/git/projects/linux-c6x-upstreaming.git#for-linux-next
+csky		git	git://github.com/c-sky/csky-linux.git#linux-next
+h8300		git	git://git.sourceforge.jp/gitroot/uclinux-h8/linux.git#h8300-next
+ia64		git	git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux.git#next
+m68k		git	git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k.git#for-next
+m68knommu	git	git://git.kernel.org/pub/scm/linux/kernel/git/gerg/m68knommu.git#for-next
+microblaze	git	git://git.monstr.eu/linux-2.6-microblaze.git#next
+mips		git	git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux.git#mips-next
+nds32		git	git://git.kernel.org/pub/scm/linux/kernel/git/greentime/linux.git#next
+nios2		git	git://git.kernel.org/pub/scm/linux/kernel/git/lftan/nios2.git#for-next
+openrisc		git	git://github.com/openrisc/linux.git#for-next
+parisc-hd	git	git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux.git#for-next
+powerpc		git	git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git#next
+fsl		git	git://git.kernel.org/pub/scm/linux/kernel/git/scottwood/linux.git#next
+soc-fsl		git	git://git.kernel.org/pub/scm/linux/kernel/git/leo/linux.git#next
+risc-v		git	git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux.git#for-next
+sifive		git	git://git.kernel.org/pub/scm/linux/kernel/git/pjw/sifive.git#for-next
+s390		git	git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git#features
+sh		git	git://git.sourceforge.jp/gitroot/uclinux-h8/linux.git#sh-next
+sparc-next	git	git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next.git#master
+uml		git	git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml.git#linux-next
+xtensa		git	git://github.com/jcmvbkbc/linux-xtensa.git#xtensa-for-next
+fscrypt		git	git://git.kernel.org/pub/scm/fs/fscrypt/fscrypt.git#master
+afs		git	git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git#afs-next
+btrfs		git	git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git#for-next
+ceph		git	git://github.com/ceph/ceph-client.git#master
+cifs		git	git://git.samba.org/sfrench/cifs-2.6.git#for-next
+configfs		git	git://git.infradead.org/users/hch/configfs.git#for-next
+ecryptfs		git	git://git.kernel.org/pub/scm/linux/kernel/git/tyhicks/ecryptfs.git#next
+erofs		git	git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git#dev
+exfat		git	git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/exfat.git#dev
+ext3		git	git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs.git#for_next
+ext4		git	git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4.git#dev
+f2fs		git	git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git#dev
+fsverity		git	git://git.kernel.org/pub/scm/fs/fscrypt/fscrypt.git#fsverity
+fuse		git	git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse.git#for-next
+jfs		git	git://github.com/kleikamp/linux-shaggy.git#jfs-next
+nfs		git	git://git.linux-nfs.org/projects/trondmy/nfs-2.6.git#linux-next
+nfs-anna		git	git://git.linux-nfs.org/projects/anna/linux-nfs.git#linux-next
+nfsd		git	git://git.linux-nfs.org/~bfields/linux.git#nfsd-next
+orangefs		git	git://git.kernel.org/pub/scm/linux/kernel/git/hubcap/linux#for-next
+overlayfs	git	git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs.git#overlayfs-next
+ubifs		git	git://git.infradead.org/ubifs-2.6.git#linux-next
+v9fs		git	git://github.com/martinetd/linux#9p-next
+xfs		git	git://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git#for-next
+zonefs		git	git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/zonefs.git#for-next
+iomap		git	git://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git#iomap-for-next
+djw-vfs		git	git://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git#vfs-for-next
+file-locks	git	git://git.kernel.org/pub/scm/linux/kernel/git/jlayton/linux.git#locks-next
+vfs		git	git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs.git#for-next
+printk		git	git://git.kernel.org/pub/scm/linux/kernel/git/pmladek/printk.git#for-next
+pci		git	git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git#next
+pstore		git	git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git#for-next/pstore
+hid		git	git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid.git#for-next
+i2c		git	git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git#i2c/for-next
+i3c		git	git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux.git#i3c/next
+dmi		quilt	http://jdelvare.nerim.net/devel/linux/jdelvare-dmi/
+hwmon-staging	git	git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git#hwmon-next
+jc_docs		git	git://git.lwn.net/linux.git#docs-next
+v4l-dvb		git	git://linuxtv.org/media_tree.git#master
+v4l-dvb-next	git	git://linuxtv.org/mchehab/media-next.git#master
+fbdev		git	git://github.com/bzolnier/linux.git#fbdev-for-next
+pm		git	git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git#linux-next
+cpufreq-arm	git	git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm.git#cpufreq/arm/linux-next
+cpupower		git	git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux.git#cpupower
+opp		git	git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm.git#opp/linux-next
+thermal		git	git://git.kernel.org/pub/scm/linux/kernel/git/thermal/linux.git#thermal/linux-next
+thermal-rzhang	git	git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux.git#next
+thermal-soc	git	git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal.git#next
+ieee1394		git	git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394.git#for-next
+dlm		git	git://git.kernel.org/pub/scm/linux/kernel/git/teigland/linux-dlm.git#next
+swiotlb		git	git://git.kernel.org/pub/scm/linux/kernel/git/konrad/swiotlb.git#linux-next
+rdma		git	git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git#for-next
+net-next		git	git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git#master
+bpf-next		git	git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git#master
+ipsec-next	git	git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec-next.git#master
+mlx5-next	git	git://git.kernel.org/pub/scm/linux/kernel/git/mellanox/linux.git#mlx5-next
+netfilter-next	git	git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git#master
+ipvs-next	git	git://git.kernel.org/pub/scm/linux/kernel/git/horms/ipvs-next.git#master
+wireless-drivers-next	git	git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git#master
+bluetooth	git	git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git#master
+mac80211-next	git	git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git#master
+gfs2		git	git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2.git#for-next
+mtd		git	git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git#mtd/next
+nand		git	git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git#nand/next
+spi-nor		git	git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git#spi-nor/next
+crypto		git	git://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git#master
+drm		git	git://git.freedesktop.org/git/drm/drm.git#drm-next
+amdgpu		git	git://people.freedesktop.org/~agd5f/linux#drm-next
+drm-intel	git	git://anongit.freedesktop.org/drm-intel#for-linux-next
+drm-tegra	git	git://anongit.freedesktop.org/tegra/linux.git#drm/tegra/for-next
+drm-misc		git	git://anongit.freedesktop.org/drm/drm-misc#for-linux-next
+drm-msm		git	https://gitlab.freedesktop.org/drm/msm.git#msm-next
+mali-dp		git	git://linux-arm.org/linux-ld#for-upstream/mali-dp
+imx-drm		git	https://git.pengutronix.de/git/pza/linux#imx-drm/next
+etnaviv		git	https://git.pengutronix.de/git/lst/linux#etnaviv/next
+regmap		git	git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap.git#for-next
+sound		git	git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git#for-next
+sound-asoc	git	git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git#for-next
+modules		git	git://git.kernel.org/pub/scm/linux/kernel/git/jeyu/linux.git#modules-next
+input		git	git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git#next
+block		git	git://git.kernel.dk/linux-block.git#for-next
+device-mapper	git	git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm.git#for-next
+pcmcia		git	git://git.kernel.org/pub/scm/linux/kernel/git/brodo/linux.git#pcmcia-next
+mmc		git	git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc.git#next
+md		git	git://git.kernel.org/pub/scm/linux/kernel/git/shli/md.git#for-next
+mfd		git	git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git#for-mfd-next
+backlight	git	git://git.kernel.org/pub/scm/linux/kernel/git/lee/backlight.git#for-backlight-next
+battery		git	git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply.git#for-next
+regulator	git	git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git#for-next
+security		git	git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security.git#next-testing
+apparmor		git	git://git.kernel.org/pub/scm/linux/kernel/git/jj/linux-apparmor#apparmor-next
+integrity	git	git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity#next-integrity
+keys		git	git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git#keys-next
+selinux		git	git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux.git#next
+smack		git	git://github.com/cschaufler/smack-next#for-next
+tomoyo		git	https://scm.osdn.net/gitroot/tomoyo/tomoyo-test1.git#master
+tpmdd		git	git://git.infradead.org/users/jjs/linux-tpmdd.git#next
+watchdog		git	git://www.linux-watchdog.org/linux-watchdog-next.git#master
+iommu		git	git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git#next
+vfio		git	git://github.com/awilliam/linux-vfio.git#next
+audit		git	git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit.git#next
+devicetree	git	git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git#for-next
+mailbox		git	git://git.linaro.org/landing-teams/working/fujitsu/integration.git#mailbox-for-next
+spi		git	git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git#for-next
+tip		git	git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git#auto-latest
+clockevents	git	git://git.linaro.org/people/daniel.lezcano/linux.git#timers/drivers/next
+edac		git	git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras.git#edac-for-next
+irqchip		git	git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git#irq/irqchip-next
+ftrace		git	git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace.git#for-next
+rcu		git	git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git#rcu/next
+kvm		git	git://git.kernel.org/pub/scm/virt/kvm/kvm.git#linux-next
+kvm-arm		git	git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git#next
+kvm-ppc		git	git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc.git#kvm-ppc-next
+kvms390		git	git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux.git#next
+xen-tip		git	git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip.git#linux-next
+percpu		git	git://git.kernel.org/pub/scm/linux/kernel/git/dennis/percpu.git#for-next
+workqueues	git	git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq.git#for-next
+drivers-x86	git	git://git.infradead.org/linux-platform-drivers-x86.git#for-next
+chrome-platform	git	git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux.git#for-next
+hsi		git	git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-hsi.git#for-next
+leds		git	git://git.kernel.org/pub/scm/linux/kernel/git/pavel/linux-leds.git#for-next
+ipmi		git	git://github.com/cminyard/linux-ipmi.git#for-next
+driver-core	git	git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git#driver-core-next
+usb		git	git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git#usb-next
+usb-gadget	git	git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git#next
+usb-serial	git	git://git.kernel.org/pub/scm/linux/kernel/git/johan/usb-serial.git#usb-next
+usb-chipidea-next	git	git://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb.git#ci-for-usb-next
+phy-next		git	git://git.kernel.org/pub/scm/linux/kernel/git/kishon/linux-phy.git#next
+tty		git	git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git#tty-next
+char-misc	git	git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git#char-misc-next
+extcon		git	git://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/extcon.git#extcon-next
+soundwire	git	git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire.git#next
+thunderbolt	git	git://git.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt.git#next
+staging		git	git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git#staging-next
+mux		git	https://gitlab.com/peda-linux/mux.git#for-next
+icc		git	git://git.linaro.org/people/georgi.djakov/linux.git#icc-next
+slave-dma	git	git://git.infradead.org/users/vkoul/slave-dma.git#next
+cgroup		git	git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup.git#for-next
+scsi		git	git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git#for-next
+scsi-mkp		git	git://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git#for-next
+vhost		git	git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost.git#linux-next
+rpmsg		git	git://git.kernel.org/pub/scm/linux/kernel/git/andersson/remoteproc.git#for-next
+gpio		git	git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git#for-next
+gpio-brgl	git	git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git#gpio/for-next
+gpio-intel	git	git://git.kernel.org/pub/scm/linux/kernel/git/andy/linux-gpio-intel.git#for-next
+pinctrl		git	git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git#for-next
+pinctrl-intel	git	git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/intel.git#for-next
+pinctrl-samsung	git	git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung.git#for-next
+pwm		git	git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm.git#for-next
+userns		git	git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace.git#for-next
+ktest		git	git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-ktest.git#for-next
+random		git	git://git.kernel.org/pub/scm/linux/kernel/git/tytso/random.git#dev
+kselftest	git	git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest.git#next
+y2038		git	git://git.kernel.org/pub/scm/linux/kernel/git/arnd/playground.git#y2038
+livepatching	git	git://git.kernel.org/pub/scm/linux/kernel/git/livepatching/livepatching#for-next
+coresight	git	git://git.linaro.org/kernel/coresight.git#next
+rtc		git	git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux.git#rtc-next
+nvdimm		git	git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm.git#libnvdimm-for-next
+at24		git	git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git#at24/for-next
+ntb		git	https://github.com/jonmason/ntb.git#ntb-next
+kspp		git	git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git#for-next/kspp
+cisco		git	https://github.com/daniel-walker/cisco-linux.git#for-next
+gnss		git	git://git.kernel.org/pub/scm/linux/kernel/git/johan/gnss.git#gnss-next
+fsi		git	git://git.kernel.org/pub/scm/linux/kernel/git/joel/fsi.git#next
+slimbus		git	git://git.kernel.org/pub/scm/linux/kernel/git/srini/slimbus.git#for-next
+nvmem		git	git://git.kernel.org/pub/scm/linux/kernel/git/srini/nvmem.git#for-next
+xarray		git	git://git.infradead.org/users/willy/linux-dax.git#xarray
+hyperv		git	git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux.git#hyperv-next
+auxdisplay	git	https://github.com/ojeda/linux.git#auxdisplay
+kgdb		git	git://git.kernel.org/pub/scm/linux/kernel/git/danielt/linux.git#kgdb/for-next
+pidfd		git	git://git.kernel.org/pub/scm/linux/kernel/git/brauner/linux.git#for-next
+devfreq		git	git://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/linux.git#devfreq-next
+hmm		git	git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git#hmm
+fpga		git	git://git.kernel.org/pub/scm/linux/kernel/git/mdf/linux-fpga.git#for-next
+kunit		git	git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest.git#test
+cel		git	git://git.linux-nfs.org/projects/cel/cel-2.6.git#cel-next
+generic-ioremap	git	git://git.infradead.org/users/hch/ioremap.git#for-next
+cfi		git	git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git#cfi/next
+kunit-next	git	git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest.git#kunit
+trivial		git	git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial.git#for-next
+zx2c4		git	git://git.kernel.org/pub/scm/linux/kernel/git/zx2c4/linux.git#for-next
+mhi		git	git://git.kernel.org/pub/scm/linux/kernel/git/mani/mhi.git#mhi-next
+akpm-current	mmotm	https://www.ozlabs.org/~akpm/mmotm/
+akpm		mmotm	https://www.ozlabs.org/~akpm/mmotm/
diff --git a/Next/merge.log b/Next/merge.log
new file mode 100644
index 000000000000..6f5c29eb2921
--- /dev/null
+++ b/Next/merge.log
@@ -0,0 +1,5680 @@
+$ date -R
+Fri, 17 Apr 2020 08:50:22 +1000
+$ git checkout master
+Already on 'master'
+$ git reset --hard stable
+HEAD is now at 8632e9b5645b Merge tag 'hyperv-fixes-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux
+Merging origin/master (2fcd80144b93 Merge tag 'tag-chrome-platform-fixes-for-v5.7-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux)
+$ git merge origin/master
+Updating 8632e9b5645b..2fcd80144b93
+Fast-forward
+ .../devicetree/bindings/net/ethernet-phy.yaml      |   3 +
+ Documentation/devicetree/bindings/net/fsl-fec.txt  |   2 +
+ Documentation/networking/devlink/devlink-trap.rst  |   2 +
+ Documentation/networking/index.rst                 |   1 +
+ Documentation/networking/ip-sysctl.txt             |   2 +-
+ .../networking/{net_dim.txt => net_dim.rst}        |  96 ++++++-------
+ Documentation/x86/boot.rst                         |  21 ++-
+ MAINTAINERS                                        |   1 +
+ arch/arm/boot/compressed/head.S                    |   3 +-
+ arch/arm/boot/dts/imx6qdl.dtsi                     |   6 +-
+ arch/arm/boot/dts/imx6qp.dtsi                      |   1 -
+ arch/arm/net/bpf_jit_32.c                          |  52 ++++---
+ arch/riscv/Kconfig                                 |   2 +-
+ arch/riscv/net/bpf_jit_comp64.c                    |  49 ++++---
+ arch/x86/include/asm/efi.h                         |   2 +
+ arch/x86/platform/efi/efi_64.c                     |  16 ++-
+ drivers/block/rbd.c                                |  33 +++--
+ drivers/firmware/efi/cper.c                        |   2 +-
+ drivers/firmware/efi/libstub/efistub.h             |   2 +-
+ drivers/firmware/efi/libstub/file.c                |  27 ++--
+ drivers/firmware/efi/libstub/x86-stub.c            |  18 ++-
+ drivers/isdn/hardware/mISDN/mISDNisar.c            |   4 +-
+ drivers/net/dsa/mt7530.c                           | 103 ++------------
+ drivers/net/dsa/mt7530.h                           |  17 +--
+ drivers/net/dsa/mv88e6xxx/chip.c                   |   5 +-
+ drivers/net/dsa/ocelot/felix.c                     |   5 +-
+ drivers/net/ethernet/amd/xgbe/xgbe-drv.c           |   2 +-
+ drivers/net/ethernet/chelsio/cxgb4/t4_hw.c         |   2 +-
+ drivers/net/ethernet/dec/tulip/tulip_core.c        |   2 +-
+ drivers/net/ethernet/freescale/fec.h               |   7 +
+ drivers/net/ethernet/freescale/fec_main.c          | 149 +++++++++++++++++----
+ drivers/net/ethernet/marvell/mvneta.c              |   2 +-
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c        |  24 +++-
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h        |   8 ++
+ drivers/net/ethernet/mellanox/mlx5/core/devlink.c  |   5 +-
+ drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c |  19 +--
+ drivers/net/ethernet/mellanox/mlx5/core/en_main.c  |   2 +-
+ drivers/net/ethernet/mellanox/mlx5/core/en_rep.c   |   9 +-
+ drivers/net/ethernet/mellanox/mlx5/core/en_tc.c    |   8 +-
+ drivers/net/ethernet/mellanox/mlx5/core/eswitch.h  |   1 -
+ .../ethernet/mellanox/mlx5/core/eswitch_offloads.c |  12 +-
+ drivers/net/ethernet/mellanox/mlx5/core/health.c   |   2 +-
+ drivers/net/ethernet/mscc/ocelot.c                 |  84 ++++++------
+ drivers/net/ethernet/mscc/ocelot.h                 |   2 -
+ drivers/net/ethernet/neterion/s2io.c               |   2 +-
+ drivers/net/ethernet/pensando/ionic/ionic_lif.c    |  44 +++---
+ .../net/ethernet/pensando/ionic/ionic_rx_filter.c  |  53 ++++++--
+ .../net/ethernet/pensando/ionic/ionic_rx_filter.h  |   2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-socfpga.c    |   2 +
+ drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c  |   2 +
+ drivers/net/ethernet/ti/am65-cpsw-nuss.c           |   6 +-
+ drivers/net/ipa/ipa_modem.c                        |   5 +-
+ drivers/net/macsec.c                               |   2 +-
+ drivers/net/phy/marvell.c                          |  46 ++++---
+ drivers/net/phy/marvell10g.c                       |  36 ++++-
+ drivers/net/phy/mdio_bus.c                         |   2 +-
+ drivers/net/phy/micrel.c                           |   2 +-
+ drivers/net/tun.c                                  |   3 +-
+ drivers/net/wireless/ath/ath11k/thermal.h          |   3 +-
+ .../wireless/broadcom/brcm80211/brcmfmac/core.c    |   9 ++
+ drivers/net/wireless/mac80211_hwsim.c              |  12 +-
+ drivers/net/wireless/realtek/rtw88/pci.c           |  11 +-
+ drivers/platform/chrome/cros_ec_sensorhub_ring.c   |   8 +-
+ fs/ceph/dir.c                                      |   4 +-
+ fs/ceph/file.c                                     |   4 +-
+ fs/ceph/mds_client.h                               |   2 +-
+ include/net/cfg80211.h                             |  10 ++
+ include/net/ip6_route.h                            |   1 +
+ include/net/netfilter/nf_tables.h                  |   2 +-
+ include/net/sock.h                                 |   6 +-
+ include/soc/mscc/ocelot.h                          |   4 +-
+ include/uapi/linux/netfilter/nf_tables.h           |   2 +
+ include/uapi/linux/netfilter/xt_IDLETIMER.h        |   1 +
+ kernel/bpf/bpf_lru_list.h                          |   2 +-
+ kernel/bpf/syscall.c                               |  16 +--
+ kernel/bpf/verifier.c                              |   3 +-
+ kernel/trace/trace_events_trigger.c                |  10 +-
+ lib/Kconfig.debug                                  |   2 +
+ net/core/dev.c                                     |   6 +-
+ net/core/filter.c                                  |   2 +-
+ net/core/net-sysfs.c                               |   2 +-
+ net/core/sock.c                                    |   2 +-
+ net/dsa/port.c                                     |   7 +-
+ net/hsr/hsr_netlink.c                              |  10 +-
+ net/ipv4/devinet.c                                 |  13 +-
+ net/ipv6/icmp.c                                    |  21 ++-
+ net/ipv6/seg6.c                                    |   2 +-
+ net/l2tp/l2tp_netlink.c                            |  16 +--
+ net/mac80211/main.c                                |  24 ++--
+ net/mac80211/mesh.c                                |  11 +-
+ net/mptcp/protocol.c                               |  25 ++--
+ net/netfilter/ipset/ip_set_core.c                  |   3 +-
+ net/netfilter/nf_tables_api.c                      |   7 +-
+ net/netfilter/nft_lookup.c                         |  12 +-
+ net/netfilter/nft_set_bitmap.c                     |   1 -
+ net/netfilter/nft_set_rbtree.c                     |  23 ++--
+ net/netfilter/xt_IDLETIMER.c                       |   3 +
+ net/qrtr/qrtr.c                                    |   7 +-
+ net/rds/message.c                                  |  25 ++--
+ net/rds/rdma.c                                     |  65 ++++-----
+ net/rds/rds.h                                      |  20 +--
+ net/rds/send.c                                     |   6 +-
+ net/rxrpc/local_object.c                           |   9 --
+ net/rxrpc/output.c                                 |  44 ++----
+ net/sched/cls_api.c                                |   1 +
+ net/tipc/link.c                                    |   2 +-
+ net/tls/tls_main.c                                 |   4 +-
+ net/wireless/nl80211.c                             |   6 +-
+ net/xdp/xdp_umem.c                                 |   5 +-
+ net/xdp/xsk.c                                      |   5 +-
+ security/keys/proc.c                               |   2 +
+ security/selinux/ss/policydb.c                     |   8 +-
+ tools/bpf/bpftool/struct_ops.c                     |   4 +-
+ tools/lib/bpf/libbpf.c                             | 126 +++++++++++------
+ tools/lib/bpf/libbpf.h                             |   2 +-
+ tools/lib/bpf/netlink.c                            |   6 +-
+ tools/testing/selftests/bpf/prog_tests/mmap.c      |  62 ++++++++-
+ .../selftests/bpf/prog_tests/section_names.c       |  42 +++---
+ tools/testing/selftests/bpf/prog_tests/test_lsm.c  |  18 +--
+ .../testing/selftests/bpf/prog_tests/xdp_attach.c  |  30 ++++-
+ tools/testing/selftests/bpf/prog_tests/xdp_info.c  |  68 ++++++++++
+ tools/testing/selftests/bpf/progs/lsm.c            |   8 +-
+ tools/testing/selftests/bpf/verifier/bounds.c      |   4 +-
+ tools/testing/selftests/tc-testing/tdc.py          |   5 +-
+ 124 files changed, 1165 insertions(+), 743 deletions(-)
+ rename Documentation/networking/{net_dim.txt => net_dim.rst} (78%)
+ create mode 100644 tools/testing/selftests/bpf/prog_tests/xdp_info.c
+Merging fixes/master (6b038bdcd3d1 sh: mm: Fix build error)
+$ git merge fixes/master
+Merge made by the 'recursive' strategy.
+ arch/sh/mm/init.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+Merging kbuild-current/fixes (d2f1606edabd scripts/config: allow colons in option strings for sed)
+$ git merge kbuild-current/fixes
+Merge made by the 'recursive' strategy.
+ scripts/config | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+Merging arc-current/for-curr (5185f4773e90 ARC: [plat-eznps]: Restrict to CONFIG_ISA_ARCOMPACT)
+$ git merge arc-current/for-curr
+Merge made by the 'recursive' strategy.
+ arch/arc/configs/hsdk_defconfig    | 1 +
+ arch/arc/include/asm/entry-arcv2.h | 2 ++
+ arch/arc/kernel/Makefile           | 3 ---
+ arch/arc/kernel/ptrace.c           | 2 +-
+ arch/arc/kernel/setup.c            | 5 +++--
+ arch/arc/kernel/unwind.c           | 2 --
+ arch/arc/plat-eznps/Kconfig        | 1 +
+ 7 files changed, 8 insertions(+), 8 deletions(-)
+Merging arm-current/fixes (89604523a76e ARM: 8961/2: Fix Kbuild issue caused by per-task stack protector GCC plugin)
+$ git merge arm-current/fixes
+Already up to date.
+Merging arm-soc-fixes/arm/fixes (c8042d1e5cb3 soc: samsung: chipid: Fix return value on non-Exynos platforms)
+$ git merge arm-soc-fixes/arm/fixes
+Already up to date.
+Merging arm64-fixes/for-next/fixes (c9a4ef664501 arm64: Delete the space separator in __emit_inst)
+$ git merge arm64-fixes/for-next/fixes
+Merge made by the 'recursive' strategy.
+ arch/arm64/include/asm/sysreg.h |  4 +++-
+ arch/arm64/kernel/vdso.c        | 13 +------------
+ 2 files changed, 4 insertions(+), 13 deletions(-)
+Merging m68k-current/for-linus (86cded5fc525 m68k: defconfig: Update defconfigs for v5.6-rc4)
+$ git merge m68k-current/for-linus
+Already up to date.
+Merging powerpc-fixes/fixes (1d0c32ec3b86 KVM: PPC: Fix kernel crash with PR KVM)
+$ git merge powerpc-fixes/fixes
+Already up to date.
+Merging s390-fixes/fixes (8f3d9f354286 Linux 5.7-rc1)
+$ git merge s390-fixes/fixes
+Already up to date.
+Merging sparc/master (63bef48fd6c9 Merge branch 'akpm' (patches from Andrew))
+$ git merge sparc/master
+Already up to date.
+Merging fscrypt-current/for-stable (2b4eae95c736 fscrypt: don't evict dirty inodes after removing key)
+$ git merge fscrypt-current/for-stable
+Already up to date.
+Merging net/master (2fcd80144b93 Merge tag 'tag-chrome-platform-fixes-for-v5.7-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux)
+$ git merge net/master
+Already up to date.
+Merging bpf/master (edadedf1c5b4 tipc: fix incorrect increasing of link window)
+$ git merge bpf/master
+Already up to date.
+Merging ipsec/master (91fac45cd006 Merge branch 'Fix-88x3310-leaving-power-save-mode')
+$ git merge ipsec/master
+Already up to date.
+Merging netfilter/master (bc8e71314e84 netfilter: flowtable: Free block_cb when being deleted)
+$ git merge netfilter/master
+Merge made by the 'recursive' strategy.
+ net/netfilter/nf_flow_table_core.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+Merging ipvs/master (0141317611ab Merge branch 'hns3-fixes')
+$ git merge ipvs/master
+Already up to date.
+Merging wireless-drivers/master (7dc7c41607d1 rtw88: avoid unused function warnings)
+$ git merge wireless-drivers/master
+Already up to date.
+Merging mac80211/master (93e2d04a1888 mac80211: fix channel switch trigger from unknown mesh peer)
+$ git merge mac80211/master
+Already up to date.
+Merging rdma-fixes/for-rc (8f3d9f354286 Linux 5.7-rc1)
+$ git merge rdma-fixes/for-rc
+Already up to date.
+Merging sound-current/for-linus (9a6418487b56 ALSA: hda: call runtime_allow() for all hda controllers)
+$ git merge sound-current/for-linus
+Merge made by the 'recursive' strategy.
+ include/sound/hda_codec.h     |   5 ++
+ sound/hda/Kconfig             |   7 +--
+ sound/pci/ctxfi/cthw20k1.c    |  14 +++---
+ sound/pci/hda/hda_codec.c     |   2 +-
+ sound/pci/hda/hda_intel.c     | 107 +++++++++++++++++++++++++-----------------
+ sound/pci/hda/hda_intel.h     |   1 +
+ sound/pci/hda/patch_realtek.c |   1 +
+ sound/usb/mixer.c             |  31 +++++++-----
+ sound/usb/mixer_maps.c        |   4 +-
+ 9 files changed, 104 insertions(+), 68 deletions(-)
+Merging sound-asoc-fixes/for-linus (630c50e34d33 Merge branch 'asoc-5.7' into asoc-linus)
+$ git merge sound-asoc-fixes/for-linus
+Removing Documentation/devicetree/bindings/sound/rockchip-spdif.txt
+Merge made by the 'recursive' strategy.
+ .../devicetree/bindings/sound/rockchip-i2s.yaml    |   3 +
+ .../devicetree/bindings/sound/rockchip-spdif.txt   |  45 --------
+ .../devicetree/bindings/sound/rockchip-spdif.yaml  | 101 ++++++++++++++++
+ include/sound/soc.h                                |   3 +
+ sound/soc/amd/acp3x-rt5682-max9836.c               |   6 +-
+ sound/soc/codecs/hdac_hdmi.c                       |   6 +-
+ sound/soc/codecs/madera.c                          |   4 -
+ sound/soc/codecs/tas571x.c                         |  20 +++-
+ sound/soc/codecs/wsa881x.c                         |   4 +
+ sound/soc/intel/common/soc-acpi-intel-cml-match.c  |   8 --
+ sound/soc/intel/common/soc-acpi-intel-icl-match.c  |   8 --
+ sound/soc/qcom/apq8096.c                           |   4 +-
+ sound/soc/qcom/sdm845.c                            |   4 +-
+ sound/soc/samsung/s3c-i2s-v2.c                     |  57 ---------
+ sound/soc/samsung/s3c2412-i2s.c                    |  56 +++++++++
+ sound/soc/sh/rcar/ssi.c                            |   8 +-
+ sound/soc/sh/rcar/ssiu.c                           |   2 +-
+ sound/soc/soc-dapm.c                               | 127 ++++++++++-----------
+ sound/soc/soc-topology.c                           | 113 ++++++++++++++----
+ sound/soc/stm/stm32_sai_sub.c                      |   2 +-
+ 20 files changed, 342 insertions(+), 239 deletions(-)
+ delete mode 100644 Documentation/devicetree/bindings/sound/rockchip-spdif.txt
+ create mode 100644 Documentation/devicetree/bindings/sound/rockchip-spdif.yaml
+Merging regmap-fixes/for-linus (b810878a8fee Merge branch 'regmap-5.7' into regmap-linus)
+$ git merge regmap-fixes/for-linus
+Merge made by the 'recursive' strategy.
+ drivers/base/regmap/regmap-debugfs.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+Merging regulator-fixes/for-linus (8f3d9f354286 Linux 5.7-rc1)
+$ git merge regulator-fixes/for-linus
+Already up to date.
+Merging spi-fixes/for-linus (4bbae1279dfe Merge branch 'spi-5.7' into spi-linus)
+$ git merge spi-fixes/for-linus
+Merge made by the 'recursive' strategy.
+ drivers/spi/spi-axi-spi-engine.c | 32 ++++++++++++++++----------------
+ drivers/spi/spi-ep93xx.c         |  8 ++++++--
+ drivers/spi/spi-sc18is602.c      |  2 +-
+ drivers/spi/spi.c                |  1 +
+ 4 files changed, 24 insertions(+), 19 deletions(-)
+Merging pci-current/for-linus (8f3d9f354286 Linux 5.7-rc1)
+$ git merge pci-current/for-linus
+Already up to date.
+Merging driver-core.current/driver-core-linus (8f3d9f354286 Linux 5.7-rc1)
+$ git merge driver-core.current/driver-core-linus
+Already up to date.
+Merging tty.current/tty-linus (3dc4db366236 serial: sh-sci: Make sure status register SCxSR is read in correct sequence)
+$ git merge tty.current/tty-linus
+Merge made by the 'recursive' strategy.
+ drivers/tty/serial/sh-sci.c        |  13 ++-
+ drivers/tty/serial/sunhv.c         |   3 +
+ drivers/tty/serial/xilinx_uartps.c | 211 +++++++++----------------------------
+ 3 files changed, 62 insertions(+), 165 deletions(-)
+Merging usb.current/usb-linus (be34a5854b46 USB: Add USB_QUIRK_DELAY_CTRL_MSG and USB_QUIRK_DELAY_INIT for Corsair K70 RGB RAPIDFIRE)
+$ git merge usb.current/usb-linus
+Merge made by the 'recursive' strategy.
+ drivers/phy/tegra/Kconfig              |  3 +-
+ drivers/usb/class/cdc-acm.c            | 36 ++++++++++++++---
+ drivers/usb/class/cdc-acm.h            |  5 ++-
+ drivers/usb/core/message.c             |  9 ++++-
+ drivers/usb/core/quirks.c              |  4 ++
+ drivers/usb/early/xhci-dbc.c           |  8 ++--
+ drivers/usb/early/xhci-dbc.h           | 18 ++++++++-
+ drivers/usb/gadget/function/f_fs.c     |  4 ++
+ drivers/usb/gadget/legacy/raw_gadget.c | 71 ++++++++++++++++++++--------------
+ drivers/usb/storage/uas.c              | 46 ++++++++++++++++++++--
+ drivers/usb/typec/mux/pi3usb30532.c    |  4 +-
+ drivers/usb/typec/tcpm/tcpm.c          | 26 +++++++++++++
+ 12 files changed, 186 insertions(+), 48 deletions(-)
+Merging usb-gadget-fixes/fixes (d0550cd20e52 usb: dwc3: gadget: Do link recovery for SS and SSP)
+$ git merge usb-gadget-fixes/fixes
+Merge made by the 'recursive' strategy.
+ .../devicetree/bindings/usb/qcom,dwc3.txt          |  4 +-
+ .../devicetree/bindings/usb/renesas,usb3-peri.yaml |  1 +
+ .../devicetree/bindings/usb/renesas,usbhs.yaml     |  1 +
+ Documentation/devicetree/bindings/usb/usb-xhci.txt |  3 +-
+ drivers/usb/dwc3/core.h                            |  8 ++-
+ drivers/usb/dwc3/gadget.c                          | 64 +++++++++++++++-------
+ drivers/usb/gadget/udc/bdc/bdc_ep.c                |  2 +-
+ 7 files changed, 58 insertions(+), 25 deletions(-)
+Merging usb-serial-fixes/usb-linus (8f3d9f354286 Linux 5.7-rc1)
+$ git merge usb-serial-fixes/usb-linus
+Already up to date.
+Merging usb-chipidea-fixes/ci-for-usb-stable (7cbf3dd3139a usb: chipidea: udc: fix sleeping function called from invalid context)
+$ git merge usb-chipidea-fixes/ci-for-usb-stable
+Auto-merging drivers/usb/chipidea/udc.c
+Merge made by the 'recursive' strategy.
+Merging phy/fixes (8f3d9f354286 Linux 5.7-rc1)
+$ git merge phy/fixes
+Already up to date.
+Merging staging.current/staging-linus (ea81c3486442 staging: vt6656: Power save stop wake_up_count wrap around.)
+$ git merge staging.current/staging-linus
+Merge made by the 'recursive' strategy.
+ drivers/staging/comedi/drivers/dt2815.c | 3 +++
+ drivers/staging/gasket/gasket_sysfs.c   | 3 +--
+ drivers/staging/gasket/gasket_sysfs.h   | 4 ----
+ drivers/staging/vt6656/usbpipe.c        | 3 ++-
+ 4 files changed, 6 insertions(+), 7 deletions(-)
+Merging char-misc.current/char-misc-linus (8f3d9f354286 Linux 5.7-rc1)
+$ git merge char-misc.current/char-misc-linus
+Already up to date.
+Merging soundwire-fixes/fixes (8f3d9f354286 Linux 5.7-rc1)
+$ git merge soundwire-fixes/fixes
+Already up to date.
+Merging thunderbolt-fixes/fixes (8f3d9f354286 Linux 5.7-rc1)
+$ git merge thunderbolt-fixes/fixes
+Already up to date.
+Merging input-current/for-linus (3f8f770575d9 Input: mms114 - fix handling of mms345l)
+$ git merge input-current/for-linus
+Merge made by the 'recursive' strategy.
+ drivers/input/touchscreen/elants_i2c.c | 11 ++++++++++-
+ drivers/input/touchscreen/mms114.c     | 12 +++++-------
+ 2 files changed, 15 insertions(+), 8 deletions(-)
+Merging crypto-current/master (55b3209acbb0 crypto: caam - fix the address of the last entry of S/G)
+$ git merge crypto-current/master
+Merge made by the 'recursive' strategy.
+ drivers/crypto/caam/caamalg.c  | 10 +++++++---
+ drivers/crypto/caam/caamhash.c |  8 ++++++--
+ drivers/crypto/caam/caampkc.c  |  8 ++++++--
+ 3 files changed, 19 insertions(+), 7 deletions(-)
+Merging ide/master (63bef48fd6c9 Merge branch 'akpm' (patches from Andrew))
+$ git merge ide/master
+Already up to date.
+Merging vfio-fixes/for-linus (95f89e090618 vfio/type1: Initialize resv_msi_base)
+$ git merge vfio-fixes/for-linus
+Already up to date.
+Merging kselftest-fixes/fixes (8f3d9f354286 Linux 5.7-rc1)
+$ git merge kselftest-fixes/fixes
+Already up to date.
+Merging modules-fixes/modules-linus (57baec7b1b04 scripts/nsdeps: make sure to pass all module source files to spatch)
+$ git merge modules-fixes/modules-linus
+Already up to date.
+Merging slave-dma-fixes/fixes (aee45dba3ad9 dt-bindings: dma: uniphier-xdmac: switch to single reg region)
+$ git merge slave-dma-fixes/fixes
+Merge made by the 'recursive' strategy.
+ .../bindings/dma/socionext,uniphier-xdmac.yaml       |  7 +++----
+ drivers/dma/Kconfig                                  |  3 ++-
+ drivers/dma/ti/k3-psil.c                             |  1 +
+ drivers/dma/xilinx/xilinx_dma.c                      | 20 ++++++++++----------
+ include/linux/dmaengine.h                            |  8 ++++----
+ 5 files changed, 20 insertions(+), 19 deletions(-)
+Merging backlight-fixes/for-backlight-fixes (219d54332a09 Linux 5.4)
+$ git merge backlight-fixes/for-backlight-fixes
+Already up to date.
+Merging mtd-fixes/mtd/fixes (2098c564701c mtd: spi-nor: Compile files in controllers/ directory)
+$ git merge mtd-fixes/mtd/fixes
+Merge made by the 'recursive' strategy.
+ drivers/mtd/spi-nor/Makefile | 2 ++
+ 1 file changed, 2 insertions(+)
+Merging mfd-fixes/for-mfd-fixes (603d9299da32 mfd: mt6397: Fix probe after changing mt6397-core)
+$ git merge mfd-fixes/for-mfd-fixes
+Already up to date.
+Merging v4l-dvb-fixes/fixes (8f3d9f354286 Linux 5.7-rc1)
+$ git merge v4l-dvb-fixes/fixes
+Already up to date.
+Merging reset-fixes/reset/fixes (b460e0a9e240 reset: intel: add unspecified HAS_IOMEM dependency)
+$ git merge reset-fixes/reset/fixes
+Already up to date.
+Merging mips-fixes/mips-fixes (8f3d9f354286 Linux 5.7-rc1)
+$ git merge mips-fixes/mips-fixes
+Already up to date.
+Merging at91-fixes/at91-fixes (54ecb8f7028c Linux 5.4-rc1)
+$ git merge at91-fixes/at91-fixes
+Already up to date.
+Merging omap-fixes/fixes (07bdc492cff6 ARM: dts: OMAP3: disable RNG on N950/N9)
+$ git merge omap-fixes/fixes
+Merge made by the 'recursive' strategy.
+ arch/arm/boot/dts/omap3-n950-n9.dtsi | 5 +++++
+ 1 file changed, 5 insertions(+)
+Merging kvm-fixes/master (dbef2808af6c KVM: VMX: fix crash cleanup when KVM wasn't used)
+$ git merge kvm-fixes/master
+Already up to date.
+Merging kvms390-fixes/master (1493e0f944f3 KVM: s390: vsie: Fix possible race when shadowing region 3 tables)
+$ git merge kvms390-fixes/master
+Already up to date.
+Merging hwmon-fixes/hwmon (0e786f328b38 hwmon: (k10temp) make some symbols static)
+$ git merge hwmon-fixes/hwmon
+Merge made by the 'recursive' strategy.
+ Documentation/hwmon/isl68137.rst | 76 ++++++++++++++++-----------------
+ drivers/hwmon/Kconfig            |  2 +-
+ drivers/hwmon/drivetemp.c        |  6 +++
+ drivers/hwmon/k10temp.c          |  6 +--
+ drivers/hwmon/pmbus/isl68137.c   | 92 +++++++++++++++++++++++++++++++++++++---
+ 5 files changed, 133 insertions(+), 49 deletions(-)
+Merging nvdimm-fixes/libnvdimm-fixes (f84afbdd3a9e libnvdimm: Out of bounds read in __nd_ioctl())
+$ git merge nvdimm-fixes/libnvdimm-fixes
+Already up to date.
+Merging btrfs-fixes/next-fixes (9dba7a236504 Merge branch 'misc-5.7' into next-fixes)
+$ git merge btrfs-fixes/next-fixes
+Already up to date!
+Merge made by the 'recursive' strategy.
+Merging vfs-fixes/fixes (5bd73286d50f fix a braino in legitimize_path())
+$ git merge vfs-fixes/fixes
+Already up to date.
+Merging dma-mapping-fixes/for-linus (9c24eaf81cc4 iommu/vt-d: Return the correct dma mask when we are bypassing the IOMMU)
+$ git merge dma-mapping-fixes/for-linus
+Already up to date.
+Merging i3c-fixes/master (6fbc7275c7a9 Linux 5.2-rc7)
+$ git merge i3c-fixes/master
+Already up to date.
+Merging drivers-x86-fixes/fixes (8f3d9f354286 Linux 5.7-rc1)
+$ git merge drivers-x86-fixes/fixes
+Already up to date.
+Merging samsung-krzk-fixes/fixes (8f3d9f354286 Linux 5.7-rc1)
+$ git merge samsung-krzk-fixes/fixes
+Already up to date.
+Merging pinctrl-samsung-fixes/pinctrl-fixes (8f3d9f354286 Linux 5.7-rc1)
+$ git merge pinctrl-samsung-fixes/pinctrl-fixes
+Already up to date.
+Merging devicetree-fixes/dt/linus (1bfed6c62d72 of: unittest: kmemleak in duplicate property update)
+$ git merge devicetree-fixes/dt/linus
+Auto-merging MAINTAINERS
+Merge made by the 'recursive' strategy.
+ .../arm/sunxi/allwinner,sun4i-a10-mbus.yaml        |  6 ++
+ .../devicetree/bindings/clock/arm,syscon-icst.yaml |  2 +-
+ .../bindings/display/bridge/adi,adv7123.txt        |  4 +-
+ .../bindings/display/bridge/adi,adv7511.txt        |  4 +-
+ .../devicetree/bindings/dma/adi,axi-dmac.txt       |  2 +-
+ .../bindings/hwmon/adi,axi-fan-control.yaml        |  4 +-
+ .../devicetree/bindings/hwmon/adt7475.yaml         |  2 +-
+ .../devicetree/bindings/iio/dac/ad5755.txt         |  2 +-
+ .../devicetree/bindings/iio/dac/adi,ad5770r.yaml   | 97 ++++++++++------------
+ .../bindings/input/touchscreen/edt-ft5x06.yaml     |  2 +-
+ .../interrupt-controller/loongson,liointc.yaml     |  5 +-
+ .../memory-controllers/nvidia,tegra186-mc.yaml     | 41 +++++----
+ .../devicetree/bindings/mfd/rohm,bd71837-pmic.yaml |  4 +-
+ .../devicetree/bindings/mfd/rohm,bd71847-pmic.yaml |  4 +-
+ .../devicetree/bindings/mfd/st,stpmic1.yaml        |  2 +-
+ .../devicetree/bindings/net/qcom,ipq8064-mdio.yaml |  1 +
+ .../devicetree/bindings/net/qualcomm-bluetooth.txt |  2 +-
+ .../devicetree/bindings/phy/ti,phy-j721e-wiz.yaml  |  2 +-
+ .../bindings/pwm/google,cros-ec-pwm.yaml           | 17 ++--
+ .../devicetree/bindings/rng/brcm,bcm2835.yaml      |  2 +-
+ .../bindings/spi/qcom,spi-qcom-qspi.yaml           |  2 +-
+ .../devicetree/bindings/usb/ingenic,musb.yaml      |  2 +-
+ .../devicetree/bindings/usb/rockchip,dwc3.txt      |  2 +-
+ MAINTAINERS                                        |  7 +-
+ drivers/of/overlay.c                               |  2 +
+ .../of/unittest-data/overlay_bad_add_dup_prop.dts  | 23 ++++-
+ drivers/of/unittest.c                              | 28 +++++--
+ 27 files changed, 159 insertions(+), 112 deletions(-)
+Merging scsi-fixes/fixes (fa17a6dc84d1 scsi: Update referenced link to cdrtools)
+$ git merge scsi-fixes/fixes
+Auto-merging MAINTAINERS
+Merge made by the 'recursive' strategy.
+ MAINTAINERS                             | 3 ++-
+ drivers/scsi/Kconfig                    | 2 +-
+ drivers/scsi/hisi_sas/Kconfig           | 1 +
+ drivers/scsi/qla2xxx/qla_dbg.c          | 3 ++-
+ drivers/scsi/qla2xxx/qla_init.c         | 2 --
+ drivers/scsi/qla2xxx/qla_isr.c          | 1 -
+ drivers/scsi/qla2xxx/qla_mbx.c          | 2 --
+ drivers/scsi/sg.c                       | 8 ++++++--
+ drivers/target/target_core_fabric_lib.c | 5 +++--
+ drivers/target/target_core_user.c       | 1 +
+ 10 files changed, 16 insertions(+), 12 deletions(-)
+Merging drm-fixes/drm-fixes (4da858c08643 Merge branch 'linux-5.7' of git://github.com/skeggsb/linux into drm-fixes)
+$ git merge drm-fixes/drm-fixes
+Merge made by the 'recursive' strategy.
+ drivers/gpu/drm/amd/amdgpu/amdgpu_device.c       | 22 +++++++-
+ drivers/gpu/drm/amd/amdgpu/cik.c                 |  2 -
+ drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c           |  2 +-
+ drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c            |  2 +
+ drivers/gpu/drm/amd/amdgpu/nv.c                  |  4 --
+ drivers/gpu/drm/amd/amdgpu/soc15.c               |  4 --
+ drivers/gpu/drm/amd/amdgpu/vi.c                  |  2 -
+ drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c |  5 +-
+ drivers/gpu/drm/amd/powerplay/smu_v11_0.c        |  6 +++
+ drivers/gpu/drm/i915/gvt/kvmgt.c                 | 46 ++++++++---------
+ drivers/gpu/drm/i915/i915_perf.c                 | 65 ++++--------------------
+ drivers/gpu/drm/nouveau/nvkm/engine/sec2/gp108.c |  3 ++
+ drivers/gpu/drm/nouveau/nvkm/engine/sec2/tu102.c | 16 ++++++
+ 13 files changed, 85 insertions(+), 94 deletions(-)
+Merging amdgpu-fixes/drm-fixes (2c409ba81be2 drm/radeon: fix si_enable_smc_cac() failed issue)
+$ git merge amdgpu-fixes/drm-fixes
+Already up to date.
+Merging drm-intel-fixes/for-linux-next-fixes (5809e8f8ee42 Merge tag 'gvt-fixes-2020-04-14' of https://github.com/intel/gvt-linux into drm-intel-fixes)
+$ git merge drm-intel-fixes/for-linux-next-fixes
+Already up to date.
+Merging mmc-fixes/fixes (3d3e18fcd591 mmc: core: make mmc_interrupt_hpi() static)
+$ git merge mmc-fixes/fixes
+Merge made by the 'recursive' strategy.
+ drivers/mmc/core/mmc_ops.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+Merging rtc-fixes/rtc-fixes (bb6d3fb354c5 Linux 5.6-rc1)
+$ git merge rtc-fixes/rtc-fixes
+Already up to date.
+Merging gnss-fixes/gnss-linus (8f3d9f354286 Linux 5.7-rc1)
+$ git merge gnss-fixes/gnss-linus
+Already up to date.
+Merging hyperv-fixes/hyperv-fixes (1a06d017fb3f Drivers: hv: vmbus: Fix Suspend-to-Idle for Generation-2 VM)
+$ git merge hyperv-fixes/hyperv-fixes
+Merge made by the 'recursive' strategy.
+ drivers/hv/vmbus_drv.c | 43 ++++++++++++++++++++++++++++++++++---------
+ 1 file changed, 34 insertions(+), 9 deletions(-)
+Merging soc-fsl-fixes/fix (fe8fe7723a3a soc: fsl: dpio: register dpio irq handlers after dpio create)
+$ git merge soc-fsl-fixes/fix
+Already up to date.
+Merging risc-v-fixes/fixes (2191b4f298fa RISC-V: Move all address space definition macros to one place)
+$ git merge risc-v-fixes/fixes
+Already up to date.
+Merging pidfd-fixes/fixes (a966dcfe153a clone3: add build-time CLONE_ARGS_SIZE_VER* validity checks)
+$ git merge pidfd-fixes/fixes
+Merge made by the 'recursive' strategy.
+ kernel/fork.c   | 11 ++++++++++-
+ kernel/signal.c | 14 +++++---------
+ 2 files changed, 15 insertions(+), 10 deletions(-)
+Merging fpga-fixes/fixes (3c2760b78f90 fpga: dfl: pci: fix return value of cci_pci_sriov_configure)
+$ git merge fpga-fixes/fixes
+Merge made by the 'recursive' strategy.
+ drivers/fpga/dfl-pci.c   | 6 ++++--
+ drivers/fpga/zynq-fpga.c | 3 ++-
+ 2 files changed, 6 insertions(+), 3 deletions(-)
+Merging spdx/spdx-linus (5b8b9d0c6d0e Merge branch 'akpm' (patches from Andrew))
+$ git merge spdx/spdx-linus
+Already up to date.
+Merging gpio-intel-fixes/fixes (8f3d9f354286 Linux 5.7-rc1)
+$ git merge gpio-intel-fixes/fixes
+Already up to date.
+Merging pinctrl-intel-fixes/fixes (ccd025eaddae pinctrl: baytrail: Enable pin configuration setting for GPIO chip)
+$ git merge pinctrl-intel-fixes/fixes
+Merge made by the 'recursive' strategy.
+ drivers/pinctrl/intel/pinctrl-baytrail.c     |  1 +
+ drivers/pinctrl/intel/pinctrl-sunrisepoint.c | 15 ++++++++-------
+ 2 files changed, 9 insertions(+), 7 deletions(-)
+Merging erofs-fixes/fixes (d1eef1c61974 Linux 5.5-rc2)
+$ git merge erofs-fixes/fixes
+Already up to date.
+Merging drm-misc-fixes/for-linux-next-fixes (8623b5255ae7 drm/scheduler: fix drm_sched_get_cleanup_job)
+$ git merge drm-misc-fixes/for-linux-next-fixes
+Merge made by the 'recursive' strategy.
+ .../bindings/display/panel/leadtek,ltk500hd1829.yaml           |  1 -
+ Documentation/devicetree/bindings/display/panel/lvds.yaml      | 10 +++++++++-
+ .../devicetree/bindings/display/panel/xinpeng,xpp055c272.yaml  |  1 -
+ drivers/gpu/drm/bridge/analogix/analogix-anx6345.c             |  3 +++
+ drivers/gpu/drm/meson/meson_dw_hdmi.c                          |  4 +---
+ drivers/gpu/drm/scheduler/sched_main.c                         |  2 +-
+ 6 files changed, 14 insertions(+), 7 deletions(-)
+Merging kspp-gustavo/for-next/kspp (90e5d84c7b06 xattr.h: Replace zero-length array with flexible-array member)
+$ git merge kspp-gustavo/for-next/kspp
+Auto-merging include/linux/xattr.h
+Auto-merging include/linux/swap.h
+Auto-merging include/linux/skbuff.h
+Auto-merging include/linux/sched/topology.h
+Auto-merging include/linux/platform_data/wilco-ec.h
+Auto-merging include/linux/memcontrol.h
+Auto-merging include/linux/irq.h
+Auto-merging include/linux/ethtool.h
+Auto-merging include/linux/blk-mq.h
+Auto-merging include/linux/bio.h
+Merge made by the 'recursive' strategy.
+ drivers/firmware/dmi-sysfs.c                  | 2 +-
+ drivers/firmware/google/memconsole-coreboot.c | 2 +-
+ drivers/firmware/google/vpd.c                 | 2 +-
+ include/linux/bio.h                           | 2 +-
+ include/linux/blk-mq.h                        | 2 +-
+ include/linux/blk_types.h                     | 2 +-
+ include/linux/can/dev/peak_canfd.h            | 4 ++--
+ include/linux/cpu_rmap.h                      | 2 +-
+ include/linux/digsig.h                        | 4 ++--
+ include/linux/dirent.h                        | 2 +-
+ include/linux/enclosure.h                     | 2 +-
+ include/linux/energy_model.h                  | 2 +-
+ include/linux/ethtool.h                       | 4 ++--
+ include/linux/genalloc.h                      | 2 +-
+ include/linux/igmp.h                          | 2 +-
+ include/linux/ihex.h                          | 2 +-
+ include/linux/irq.h                           | 4 ++--
+ include/linux/list_lru.h                      | 2 +-
+ include/linux/memcontrol.h                    | 4 ++--
+ include/linux/platform_data/wilco-ec.h        | 2 +-
+ include/linux/posix_acl.h                     | 2 +-
+ include/linux/rio.h                           | 4 ++--
+ include/linux/rslib.h                         | 2 +-
+ include/linux/sched/topology.h                | 2 +-
+ include/linux/skbuff.h                        | 2 +-
+ include/linux/swap.h                          | 2 +-
+ include/linux/ti_wilink_st.h                  | 6 +++---
+ include/linux/tpm_eventlog.h                  | 6 +++---
+ include/linux/xattr.h                         | 2 +-
+ include/uapi/linux/dlm_device.h               | 4 ++--
+ include/uapi/linux/fiemap.h                   | 2 +-
+ 31 files changed, 42 insertions(+), 42 deletions(-)
+Merging kbuild/for-next (b032227c6293 Merge tag 'nios2-v5.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/lftan/nios2)
+$ git merge kbuild/for-next
+Already up to date.
+Merging compiler-attributes/compiler-attributes (98d54f81e36b Linux 5.6-rc4)
+$ git merge compiler-attributes/compiler-attributes
+Already up to date.
+Merging leaks/leaks-next (9e98c678c2d6 Linux 5.1-rc1)
+$ git merge leaks/leaks-next
+Already up to date.
+Merging dma-mapping/for-next (9bb50ed74709 dma-debug: fix displaying of dma allocation type)
+$ git merge dma-mapping/for-next
+Already up to date.
+Merging asm-generic/master (060dc911501f nds32: fix build failure caused by page table folding updates)
+$ git merge asm-generic/master
+Already up to date.
+Merging arc/for-next (def9d2780727 Linux 5.5-rc7)
+$ git merge arc/for-next
+Already up to date.
+Merging arm/for-next (52d3b2f98483 Merge branch 'devel-stable' into for-next)
+$ git merge arm/for-next
+Already up to date!
+Merge made by the 'recursive' strategy.
+Merging arm64/for-next/core (fc2266011acc arm64: armv8_deprecated: Fix undef_hook mask for thumb setend)
+$ git merge arm64/for-next/core
+Already up to date.
+Merging arm-perf/for-next/perf (8f3d9f354286 Linux 5.7-rc1)
+$ git merge arm-perf/for-next/perf
+Already up to date.
+Merging arm-soc/for-next (d9725e56e1d8 soc: document merges)
+$ git merge arm-soc/for-next
+Merge made by the 'recursive' strategy.
+ arch/arm/arm-soc-for-next-contents.txt | 201 +++++++++++++++++++++++++++++++++
+ 1 file changed, 201 insertions(+)
+ create mode 100644 arch/arm/arm-soc-for-next-contents.txt
+Merging amlogic/for-next (8f3d9f354286 Linux 5.7-rc1)
+$ git merge amlogic/for-next
+Already up to date.
+Merging aspeed/for-next (de285b938cf3 ARM: dts: aspeed: ast2600: Fix SCU IRQ controller nodes)
+$ git merge aspeed/for-next
+Auto-merging arch/arm/boot/dts/aspeed-g6.dtsi
+Auto-merging arch/arm/boot/dts/aspeed-g5.dtsi
+Auto-merging arch/arm/boot/dts/aspeed-g4.dtsi
+Merge made by the 'recursive' strategy.
+ .../arm/boot/dts/aspeed-bmc-facebook-tiogapass.dts |  74 ++++++++++
+ .../boot/dts/aspeed-bmc-facebook-yosemitev2.dts    | 151 +++++++++++++++++++++
+ arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts       |  21 +++
+ arch/arm/boot/dts/aspeed-bmc-opp-tacoma.dts        |   4 +
+ arch/arm/boot/dts/aspeed-bmc-opp-witherspoon.dts   |  34 +++++
+ arch/arm/boot/dts/aspeed-g4.dtsi                   |  10 ++
+ arch/arm/boot/dts/aspeed-g5.dtsi                   |  19 +++
+ arch/arm/boot/dts/aspeed-g6.dtsi                   |  38 ++++++
+ 8 files changed, 351 insertions(+)
+ create mode 100644 arch/arm/boot/dts/aspeed-bmc-facebook-yosemitev2.dts
+Merging at91/at91-next (ec539e70d882 Merge branches 'at91-soc', 'at91-dt' and 'at91-defconfig' into at91-next)
+$ git merge at91/at91-next
+Already up to date!
+Merge made by the 'recursive' strategy.
+Merging imx-mxs/for-next (46535d78fdfe Merge branch 'imx/dt64' into for-next)
+$ git merge imx-mxs/for-next
+Merge made by the 'recursive' strategy.
+ Documentation/devicetree/bindings/arm/fsl.yaml     |   2 +
+ Documentation/devicetree/bindings/dma/fsl-edma.txt |   3 +-
+ arch/arm/boot/dts/Makefile                         |   1 +
+ arch/arm/boot/dts/imx6dl-colibri-v1_1-eval-v3.dts  |  31 ++++++
+ arch/arm/boot/dts/imx6dl-yapp4-ursa.dts            |   2 +-
+ arch/arm/boot/dts/imx6q-dhcom-pdk2.dts             | 115 ++++++++++++++++++++-
+ arch/arm/boot/dts/imx6qdl-colibri-v1_1-uhs.dtsi    |  44 ++++++++
+ arch/arm/boot/dts/imx6qdl-colibri.dtsi             |  11 +-
+ arch/arm/boot/dts/imx7-tqma7.dtsi                  |   2 +-
+ arch/arm/boot/dts/imx7d-cl-som-imx7.dts            |   4 +
+ arch/arm/boot/dts/imx7d-colibri.dtsi               |   4 +
+ arch/arm/boot/dts/imx7d-nitrogen7.dts              |   4 +
+ arch/arm/boot/dts/imx7d-sdb.dts                    |   4 +
+ arch/arm/boot/dts/imx7d-tqma7.dtsi                 |   4 +
+ arch/arm/boot/dts/imx7d-zii-rmu2.dts               |   2 +-
+ arch/arm/boot/dts/imx7d-zii-rpu2.dts               |   2 +-
+ arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi     |   2 +-
+ arch/arm64/boot/dts/freescale/imx8mm-evk.dts       |  12 +++
+ arch/arm64/boot/dts/freescale/imx8mn-ddr4-evk.dts  |  12 +++
+ drivers/clk/imx/Kconfig                            |   8 +-
+ drivers/clk/imx/clk-imx6ul.c                       |   2 +-
+ drivers/clk/imx/clk-imx7ulp.c                      |   6 +-
+ drivers/soc/imx/soc-imx8m.c                        |   7 +-
+ include/dt-bindings/clock/imx7ulp-clock.h          |   5 +-
+ 24 files changed, 268 insertions(+), 21 deletions(-)
+ create mode 100644 arch/arm/boot/dts/imx6dl-colibri-v1_1-eval-v3.dts
+ create mode 100644 arch/arm/boot/dts/imx6qdl-colibri-v1_1-uhs.dtsi
+Merging keystone/next (560b4d4691b0 Merge branch 'for_5.7/keystone-dts' into next)
+$ git merge keystone/next
+Merge made by the 'recursive' strategy.
+ arch/arm/boot/dts/keystone-k2g-evm.dts | 101 +++++++++++++++++++++++++++++++++
+ arch/arm/boot/dts/keystone-k2g.dtsi    |  22 +++++++
+ 2 files changed, 123 insertions(+)
+Merging mediatek/for-next (23a161322658 Merge branch 'v5.7-next/soc' into for-next)
+$ git merge mediatek/for-next
+Merge made by the 'recursive' strategy.
+ .../devicetree/bindings/arm/mediatek.yaml          |   22 +
+ .../bindings/arm/mediatek/mediatek,mmsys.txt       |    7 +-
+ arch/arm/boot/dts/mt7623n-rfb-emmc.dts             |    1 +
+ arch/arm64/boot/dts/mediatek/Makefile              |    3 +
+ .../boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts  |    4 +
+ arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts       |    4 +
+ arch/arm64/boot/dts/mediatek/mt7622.dtsi           |   11 +
+ .../boot/dts/mediatek/mt8173-elm-hana-rev7.dts     |   27 +
+ arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dts   |   14 +
+ arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi  |   70 ++
+ arch/arm64/boot/dts/mediatek/mt8173-elm.dts        |   14 +
+ arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi       | 1173 ++++++++++++++++++++
+ arch/arm64/boot/dts/mediatek/mt8173.dtsi           |   45 +-
+ arch/arm64/boot/dts/mediatek/mt8183.dtsi           |   26 +-
+ drivers/clk/mediatek/Kconfig                       |    7 +
+ drivers/clk/mediatek/Makefile                      |    1 +
+ drivers/clk/mediatek/clk-mt8173-mm.c               |  146 +++
+ drivers/clk/mediatek/clk-mt8173.c                  |  104 --
+ drivers/gpu/drm/mediatek/Kconfig                   |    1 +
+ drivers/gpu/drm/mediatek/mtk_disp_color.c          |    5 +-
+ drivers/gpu/drm/mediatek/mtk_disp_ovl.c            |    5 +-
+ drivers/gpu/drm/mediatek/mtk_disp_rdma.c           |    5 +-
+ drivers/gpu/drm/mediatek/mtk_dpi.c                 |   12 +-
+ drivers/gpu/drm/mediatek/mtk_drm_crtc.c            |   19 +-
+ drivers/gpu/drm/mediatek/mtk_drm_ddp.c             |  259 +----
+ drivers/gpu/drm/mediatek/mtk_drm_ddp.h             |    7 -
+ drivers/gpu/drm/mediatek/mtk_drm_drv.c             |   45 +-
+ drivers/gpu/drm/mediatek/mtk_drm_drv.h             |    2 +-
+ drivers/gpu/drm/mediatek/mtk_dsi.c                 |    8 +-
+ drivers/gpu/drm/mediatek/mtk_hdmi.c                |    4 +-
+ drivers/soc/mediatek/Kconfig                       |    8 +
+ drivers/soc/mediatek/Makefile                      |    1 +
+ drivers/soc/mediatek/mtk-mmsys.c                   |  337 ++++++
+ include/linux/soc/mediatek/mtk-mmsys.h             |   20 +
+ 34 files changed, 1984 insertions(+), 433 deletions(-)
+ create mode 100644 arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dts
+ create mode 100644 arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dts
+ create mode 100644 arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi
+ create mode 100644 arch/arm64/boot/dts/mediatek/mt8173-elm.dts
+ create mode 100644 arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi
+ create mode 100644 drivers/clk/mediatek/clk-mt8173-mm.c
+ create mode 100644 drivers/soc/mediatek/mtk-mmsys.c
+ create mode 100644 include/linux/soc/mediatek/mtk-mmsys.h
+Merging mvebu/for-next (9d32706f8aa8 Merge branch 'mvebu/dt64' into mvebu/for-next)
+$ git merge mvebu/for-next
+Merge made by the 'recursive' strategy.
+ arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts   | 2 +-
+ arch/arm64/boot/dts/marvell/armada-8040-mcbin-singleshot.dts | 4 ++--
+ arch/arm64/boot/dts/marvell/armada-8040-mcbin.dts            | 4 ++--
+ 3 files changed, 5 insertions(+), 5 deletions(-)
+Merging omap/for-next (e90f16cc1a48 Merge branch 'fixes' into for-next)
+$ git merge omap/for-next
+Already up to date!
+Merge made by the 'recursive' strategy.
+Merging qcom/for-next (217aeedd10d5 Merge branches 'arm64-defconfig-for-5.8', 'arm64-for-5.8', 'drivers-for-5.8' and 'dts-for-5.8' into for-next)
+$ git merge qcom/for-next
+Merge made by the 'recursive' strategy.
+ Documentation/devicetree/bindings/arm/cpus.yaml |   1 +
+ arch/arm/boot/dts/qcom-ipq4019.dtsi             |   1 +
+ arch/arm/boot/dts/qcom-ipq8064.dtsi             |   6 +
+ arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi       |  76 +++
+ arch/arm64/boot/dts/qcom/ipq8074-hk01.dts       | 112 ++--
+ arch/arm64/boot/dts/qcom/ipq8074.dtsi           | 474 ++++++++---------
+ arch/arm64/boot/dts/qcom/msm8916.dtsi           |  48 +-
+ arch/arm64/boot/dts/qcom/msm8996.dtsi           |  28 +-
+ arch/arm64/boot/dts/qcom/msm8998.dtsi           |  38 +-
+ arch/arm64/boot/dts/qcom/qcs404-evb.dtsi        |  85 ++-
+ arch/arm64/boot/dts/qcom/qcs404.dtsi            | 100 ++++
+ arch/arm64/boot/dts/qcom/sc7180-idp.dts         |   6 +-
+ arch/arm64/boot/dts/qcom/sc7180.dtsi            | 234 ++++++---
+ arch/arm64/boot/dts/qcom/sdm845-db845c.dts      | 210 ++++++++
+ arch/arm64/boot/dts/qcom/sdm845.dtsi            |  96 +++-
+ arch/arm64/configs/defconfig                    |   3 +
+ drivers/soc/qcom/Kconfig                        |   8 +-
+ drivers/soc/qcom/cmd-db.c                       |  78 ++-
+ drivers/soc/qcom/rpmh-internal.h                |  65 ++-
+ drivers/soc/qcom/rpmh-rsc.c                     | 659 +++++++++++++++++-------
+ drivers/soc/qcom/rpmh.c                         |  76 ++-
+ drivers/soc/qcom/rpmhpd.c                       |   5 +
+ drivers/soc/qcom/rpmpd.c                        |   5 +
+ drivers/soc/qcom/smp2p.c                        |   4 +-
+ drivers/soc/qcom/socinfo.c                      |   2 +
+ include/soc/qcom/cmd-db.h                       |   1 +
+ 26 files changed, 1760 insertions(+), 661 deletions(-)
+$ git am -3 ../patches/0001-Revert-soc-qcom-rpmh-Allow-RPMH-driver-to-be-loaded-.patch
+Applying: Revert "soc: qcom: rpmh: Allow RPMH driver to be loaded as a module"
+$ git reset HEAD^
+Unstaged changes after reset:
+M	drivers/soc/qcom/Kconfig
+M	drivers/soc/qcom/rpmh-rsc.c
+$ git add -A .
+$ git commit -v -a --amend
+[master 1da17ebc0c39] Merge remote-tracking branch 'qcom/for-next'
+ Date: Fri Apr 17 09:25:58 2020 +1000
+Merging raspberrypi/for-next (e7b7daeb48e0 ARM: dts: bcm283x: Use firmware PM driver for V3D)
+$ git merge raspberrypi/for-next
+Auto-merging arch/arm/configs/bcm2835_defconfig
+CONFLICT (content): Merge conflict in arch/arm/configs/bcm2835_defconfig
+Auto-merging arch/arm/boot/dts/bcm2711-rpi-4-b.dts
+Resolved 'arch/arm/configs/bcm2835_defconfig' using previous resolution.
+Automatic merge failed; fix conflicts and then commit the result.
+$ git commit --no-edit -v -a
+[master 97e696d5de59] Merge remote-tracking branch 'raspberrypi/for-next'
+$ git diff -M --stat --summary HEAD^..
+ arch/arm/boot/dts/bcm2711-rpi-4-b.dts     | 13 ++++++++++++-
+ arch/arm/boot/dts/bcm2835-common.dtsi     |  1 -
+ arch/arm/boot/dts/bcm2835-rpi-common.dtsi | 12 ++++++++++++
+ arch/arm/boot/dts/bcm2835.dtsi            |  1 +
+ arch/arm/boot/dts/bcm2836.dtsi            |  1 +
+ arch/arm/boot/dts/bcm2837.dtsi            |  1 +
+ arch/arm/configs/bcm2835_defconfig        |  1 +
+ 7 files changed, 28 insertions(+), 2 deletions(-)
+ create mode 100644 arch/arm/boot/dts/bcm2835-rpi-common.dtsi
+Merging realtek/for-next (486f29df6941 Merge branch 'v5.8/dt' into next)
+$ git merge realtek/for-next
+Auto-merging arch/arm/boot/dts/Makefile
+Auto-merging MAINTAINERS
+Merge made by the 'recursive' strategy.
+ Documentation/devicetree/bindings/arm/realtek.yaml |  21 ++
+ .../devicetree/bindings/vendor-prefixes.yaml       |   2 +
+ MAINTAINERS                                        |   2 +
+ arch/arm/Kconfig                                   |   2 +
+ arch/arm/Makefile                                  |   3 +
+ arch/arm/boot/dts/Makefile                         |   3 +
+ arch/arm/boot/dts/rtd1195-horseradish.dts          |  32 +++
+ arch/arm/boot/dts/rtd1195-mele-x1000.dts           |  32 +++
+ arch/arm/boot/dts/rtd1195.dtsi                     | 217 +++++++++++++++++++
+ arch/arm/mach-realtek/Kconfig                      |  11 +
+ arch/arm/mach-realtek/Makefile                     |   2 +
+ arch/arm/mach-realtek/rtd1195.c                    |  40 ++++
+ arch/arm64/boot/dts/realtek/Makefile               |   6 +
+ arch/arm64/boot/dts/realtek/rtd1293-ds418j.dts     |   6 +-
+ arch/arm64/boot/dts/realtek/rtd1293.dtsi           |  12 +-
+ arch/arm64/boot/dts/realtek/rtd1295-mele-v9.dts    |   6 +-
+ .../arm64/boot/dts/realtek/rtd1295-probox2-ava.dts |   6 +-
+ arch/arm64/boot/dts/realtek/rtd1295-xnano-x5.dts   |  30 +++
+ arch/arm64/boot/dts/realtek/rtd1295-zidoo-x9s.dts  |   4 +-
+ arch/arm64/boot/dts/realtek/rtd1295.dtsi           |  21 +-
+ arch/arm64/boot/dts/realtek/rtd1296-ds418.dts      |   4 +-
+ arch/arm64/boot/dts/realtek/rtd1296.dtsi           |   8 +-
+ arch/arm64/boot/dts/realtek/rtd129x.dtsi           | 221 +++++++++++++-------
+ arch/arm64/boot/dts/realtek/rtd1395-bpi-m4.dts     |  30 +++
+ arch/arm64/boot/dts/realtek/rtd1395-lionskin.dts   |  36 ++++
+ arch/arm64/boot/dts/realtek/rtd1395.dtsi           |  65 ++++++
+ arch/arm64/boot/dts/realtek/rtd139x.dtsi           | 193 +++++++++++++++++
+ arch/arm64/boot/dts/realtek/rtd1619-mjolnir.dts    |  44 ++++
+ arch/arm64/boot/dts/realtek/rtd1619.dtsi           |  12 ++
+ arch/arm64/boot/dts/realtek/rtd16xx.dtsi           | 229 +++++++++++++++++++++
+ include/dt-bindings/reset/realtek,rtd1195.h        |  74 +++++++
+ include/dt-bindings/reset/realtek,rtd1295.h        |   3 +
+ 32 files changed, 1268 insertions(+), 109 deletions(-)
+ create mode 100644 arch/arm/boot/dts/rtd1195-horseradish.dts
+ create mode 100644 arch/arm/boot/dts/rtd1195-mele-x1000.dts
+ create mode 100644 arch/arm/boot/dts/rtd1195.dtsi
+ create mode 100644 arch/arm/mach-realtek/Kconfig
+ create mode 100644 arch/arm/mach-realtek/Makefile
+ create mode 100644 arch/arm/mach-realtek/rtd1195.c
+ create mode 100644 arch/arm64/boot/dts/realtek/rtd1295-xnano-x5.dts
+ create mode 100644 arch/arm64/boot/dts/realtek/rtd1395-bpi-m4.dts
+ create mode 100644 arch/arm64/boot/dts/realtek/rtd1395-lionskin.dts
+ create mode 100644 arch/arm64/boot/dts/realtek/rtd1395.dtsi
+ create mode 100644 arch/arm64/boot/dts/realtek/rtd139x.dtsi
+ create mode 100644 arch/arm64/boot/dts/realtek/rtd1619-mjolnir.dts
+ create mode 100644 arch/arm64/boot/dts/realtek/rtd1619.dtsi
+ create mode 100644 arch/arm64/boot/dts/realtek/rtd16xx.dtsi
+ create mode 100644 include/dt-bindings/reset/realtek,rtd1195.h
+Merging renesas/next (a710158e9fa2 Merge branch 'renesas-arm-dt-for-v5.8' into renesas-next)
+$ git merge renesas/next
+Merge made by the 'recursive' strategy.
+ arch/arm64/boot/dts/renesas/r8a77961.dtsi | 403 ++++++++++++++++++++++++++++--
+ 1 file changed, 388 insertions(+), 15 deletions(-)
+Merging reset/reset/next (2ebf89fd4ecf reset: hi6220: Add support for AO reset controller)
+$ git merge reset/reset/next
+Merge made by the 'recursive' strategy.
+ .../devicetree/bindings/reset/fsl,imx7-src.txt     |   6 +-
+ drivers/reset/hisilicon/hi6220_reset.c             |  69 +++++++++++++-
+ drivers/reset/reset-imx7.c                         | 101 +++++++++++++++++++++
+ .../dt-bindings/reset/amlogic,meson-gxbb-reset.h   |   2 +-
+ include/dt-bindings/reset/imx8mp-reset.h           |  50 ++++++++++
+ include/dt-bindings/reset/imx8mq-reset.h           |  56 ++++++------
+ 6 files changed, 253 insertions(+), 31 deletions(-)
+ create mode 100644 include/dt-bindings/reset/imx8mp-reset.h
+Merging rockchip/for-next (c018aff1a201 Merge branch 'v5.7-armsoc/dts64' into for-next)
+$ git merge rockchip/for-next
+Merge made by the 'recursive' strategy.
+ arch/arm/mach-rockchip/platsmp.c  |  2 +-
+ arch/arm/mach-rockchip/rockchip.c |  2 +-
+ drivers/clk/rockchip/clk-pll.c    | 70 +++++++++++++++++++++++----------------
+ drivers/clk/rockchip/clk-rk3228.c | 17 +++-------
+ 4 files changed, 47 insertions(+), 44 deletions(-)
+Merging samsung-krzk/for-next (ff602fc2b39e Merge branch 'next/soc' into for-next)
+$ git merge samsung-krzk/for-next
+Auto-merging arch/arm/boot/dts/Makefile
+Merge made by the 'recursive' strategy.
+ .../bindings/arm/samsung/samsung-boards.yaml       |   1 +
+ arch/arm/boot/dts/Makefile                         |   1 +
+ arch/arm/boot/dts/exynos3250-monk.dts              |   3 +-
+ arch/arm/boot/dts/exynos3250-rinato.dts            |  48 +-
+ arch/arm/boot/dts/exynos4210-i9100.dts             | 768 +++++++++++++++++++++
+ arch/arm/boot/dts/exynos4210-origen.dts            |   7 +-
+ arch/arm/boot/dts/exynos4210-trats.dts             |  41 +-
+ arch/arm/boot/dts/exynos4210-universal_c210.dts    |  33 +-
+ arch/arm/boot/dts/exynos4412-galaxy-s3.dtsi        |   6 +-
+ arch/arm/boot/dts/exynos4412-midas.dtsi            |  17 +-
+ arch/arm/boot/dts/exynos4412-odroid-common.dtsi    |   8 +-
+ arch/arm/boot/dts/exynos4412-origen.dts            |  14 +-
+ arch/arm/boot/dts/exynos5250-arndale.dts           |  13 +-
+ arch/arm/boot/dts/exynos5420-arndale-octa.dts      |   2 +-
+ arch/arm/configs/exynos_defconfig                  |   8 +-
+ arch/arm/mach-s3c64xx/mach-crag6410-module.c       |   7 +-
+ 16 files changed, 921 insertions(+), 56 deletions(-)
+ create mode 100644 arch/arm/boot/dts/exynos4210-i9100.dts
+Merging scmi/for-linux-next (8f3d9f354286 Linux 5.7-rc1)
+$ git merge scmi/for-linux-next
+Already up to date.
+Merging sunxi/sunxi/for-next (4f7a2d7e5f1e Merge branches 'sunxi/clk-for-5.8', 'sunxi/config-for-5.8' and 'sunxi/dt-for-5.8' into sunxi/for-next)
+$ git merge sunxi/sunxi/for-next
+Auto-merging arch/arm/boot/dts/Makefile
+Merge made by the 'recursive' strategy.
+ Documentation/devicetree/bindings/arm/sunxi.yaml   |  5 ++++
+ arch/arm/boot/dts/Makefile                         |  1 +
+ .../arm/boot/dts/sun7i-a20-olinuxino-lime-emmc.dts | 32 ++++++++++++++++++++++
+ arch/arm/boot/dts/sun8i-a83t.dtsi                  | 10 +++++++
+ arch/arm/boot/dts/sun8i-h3.dtsi                    | 24 ++++++++++++++--
+ arch/arm/boot/dts/sunxi-h3-h5.dtsi                 | 10 +++++++
+ arch/arm/configs/sunxi_defconfig                   |  1 +
+ .../boot/dts/allwinner/sun50i-a64-olinuxino.dts    |  9 ++++++
+ arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi      | 10 +++++++
+ arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi       | 10 +++++++
+ drivers/clk/sunxi/clk-sunxi.c                      |  2 +-
+ 11 files changed, 110 insertions(+), 4 deletions(-)
+ create mode 100644 arch/arm/boot/dts/sun7i-a20-olinuxino-lime-emmc.dts
+Merging tegra/for-next (9546812c92ef Merge branch for-5.7/arm64/defconfig into for-next)
+$ git merge tegra/for-next
+Auto-merging arch/arm64/configs/defconfig
+Merge made by the 'recursive' strategy.
+ arch/arm64/configs/defconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+Merging clk/clk-next (e7f552f727f5 Merge branch 'clk-fixes' into clk-next)
+$ git merge clk/clk-next
+Merge made by the 'recursive' strategy.
+ drivers/clk/clk-asm9260.c      |  2 +-
+ drivers/clk/mmp/clk-pll.c      | 33 ++++++++++++++++++++++++++++++++-
+ drivers/clk/mmp/clk.c          | 31 -------------------------------
+ drivers/clk/mmp/clk.h          |  7 -------
+ drivers/clk/sprd/sc9863a-clk.c |  3 ++-
+ 5 files changed, 35 insertions(+), 41 deletions(-)
+Merging clk-samsung/for-next (54ecb8f7028c Linux 5.4-rc1)
+$ git merge clk-samsung/for-next
+Already up to date.
+Merging c6x/for-linux-next (8adcc59974b8 Merge branch 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs)
+$ git merge c6x/for-linux-next
+Already up to date.
+Merging csky/linux-next (10cb08260605 csky: Fixup perf probe -x hungup)
+$ git merge csky/linux-next
+Merge made by the 'recursive' strategy.
+ arch/csky/abiv2/mcount.S            | 2 ++
+ arch/csky/include/asm/thread_info.h | 8 ++++----
+ arch/csky/kernel/ftrace.c           | 2 ++
+ arch/csky/kernel/probes/uprobes.c   | 5 +++++
+ arch/csky/kernel/ptrace.c           | 6 ++++++
+ 5 files changed, 19 insertions(+), 4 deletions(-)
+Merging h8300/h8300-next (beab3d5cb0e1 irq-renesas-h8s: Fix external interrupt control.)
+$ git merge h8300/h8300-next
+Auto-merging drivers/tty/serial/sh-sci.c
+Merge made by the 'recursive' strategy.
+ arch/h8300/Kconfig.cpu                  |  4 ++
+ arch/h8300/boot/dts/edosk2674.dts       | 10 ++++-
+ arch/h8300/configs/edosk2674_defconfig  | 10 ++---
+ arch/h8300/configs/h8300h-sim_defconfig |  8 +---
+ arch/h8300/configs/h8s-sim_defconfig    |  8 +---
+ arch/h8300/lib/memset.S                 | 17 +++++----
+ drivers/clocksource/h8300_timer8.c      | 20 +++++-----
+ drivers/irqchip/irq-renesas-h8300h.c    | 19 +++++++++-
+ drivers/irqchip/irq-renesas-h8s.c       | 67 +++++++++++++++++++++++++--------
+ drivers/net/ethernet/smsc/Kconfig       |  1 -
+ drivers/net/ethernet/smsc/smc91x.c      | 10 +++++
+ drivers/tty/serial/sh-sci.c             |  5 +--
+ 12 files changed, 120 insertions(+), 59 deletions(-)
+Merging ia64/next (172e7890406d tty/serial: cleanup after ioc*_serial driver removal)
+$ git merge ia64/next
+Already up to date.
+Merging m68k/for-next (86cded5fc525 m68k: defconfig: Update defconfigs for v5.6-rc4)
+$ git merge m68k/for-next
+Already up to date.
+Merging m68knommu/for-next (ba000760eb0f m68k: Replace setup_irq() by request_irq())
+$ git merge m68knommu/for-next
+Already up to date.
+Merging microblaze/next (8f3d9f354286 Linux 5.7-rc1)
+$ git merge microblaze/next
+Already up to date.
+Merging mips/mips-next (c02e96304451 mips: loongsoon2ef: remove private clk api)
+$ git merge mips/mips-next
+Removing arch/mips/include/asm/mach-xilfpga/irq.h
+Removing arch/mips/include/asm/clock.h
+Merge made by the 'recursive' strategy.
+ arch/mips/Kconfig                                 |  2 +-
+ arch/mips/include/asm/asm-eva.h                   |  2 +-
+ arch/mips/include/asm/clock.h                     | 49 ------------
+ arch/mips/include/asm/mach-generic/irq.h          |  6 --
+ arch/mips/include/asm/mach-loongson2ef/loongson.h |  1 +
+ arch/mips/include/asm/mach-ralink/mt7621.h        |  2 -
+ arch/mips/include/asm/mach-xilfpga/irq.h          | 14 ----
+ arch/mips/include/asm/pgtable-64.h                |  4 +-
+ arch/mips/loongson2ef/Kconfig                     |  1 -
+ arch/mips/loongson2ef/lemote-2f/clock.c           | 98 +----------------------
+ arch/mips/loongson64/smp.c                        |  1 -
+ arch/mips/txx9/Kconfig                            | 14 ++--
+ drivers/cpufreq/loongson2_cpufreq.c               | 22 +----
+ 13 files changed, 19 insertions(+), 197 deletions(-)
+ delete mode 100644 arch/mips/include/asm/clock.h
+ delete mode 100644 arch/mips/include/asm/mach-xilfpga/irq.h
+Merging nds32/next (d785c5a324cd nds32: configs: Cleanup CONFIG_CROSS_COMPILE)
+$ git merge nds32/next
+Merge made by the 'recursive' strategy.
+ arch/nds32/configs/defconfig | 1 -
+ arch/nds32/kernel/time.c     | 2 +-
+ 2 files changed, 1 insertion(+), 2 deletions(-)
+Merging nios2/for-next (0ec8a5054d7f MAINTAINERS: Remove nios2-dev@lists.rocketboards.org)
+$ git merge nios2/for-next
+Already up to date.
+Merging openrisc/for-next (9737e2c5f0bc openrisc: Remove obsolete show_trace_task function)
+$ git merge openrisc/for-next
+Already up to date.
+Merging parisc-hd/for-next (7111951b8d49 Linux 5.6)
+$ git merge parisc-hd/for-next
+Already up to date.
+Merging powerpc/next (6ba4a2d35910 selftests/powerpc: Always build the tm-poison test 64-bit)
+$ git merge powerpc/next
+Already up to date.
+Merging fsl/next (a76bea0287ce powerpc/kmcent2: add ranges to the pci bridges)
+$ git merge fsl/next
+Already up to date.
+Merging soc-fsl/next (461c3ac0dc46 soc: fsl: qe: fix sparse warnings for ucc_slow.c)
+$ git merge soc-fsl/next
+Already up to date.
+Merging risc-v/for-next (37809df4b1c8 riscv: create a loader.bin boot image for Kendryte SoC)
+$ git merge risc-v/for-next
+Already up to date.
+Merging sifive/for-next (467e050e9760 Merge branch 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux)
+$ git merge sifive/for-next
+Already up to date.
+Merging s390/features (8f3d9f354286 Linux 5.7-rc1)
+$ git merge s390/features
+Already up to date.
+Merging sh/sh-next (a193018e5290 sh: add missing EXPORT_SYMBOL() for __delay)
+$ git merge sh/sh-next
+Merge made by the 'recursive' strategy.
+ arch/sh/include/asm/cache.h  |  2 +-
+ arch/sh/kernel/Makefile      |  2 --
+ arch/sh/kernel/sh_ksyms_32.c | 17 +++++++++++++++++
+ arch/sh/lib/delay.c          |  1 +
+ 4 files changed, 19 insertions(+), 3 deletions(-)
+Merging sparc-next/master (b71acb0e3721 Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6)
+$ git merge sparc-next/master
+Already up to date.
+Merging uml/linux-next (4a7c46247f9c um: Remove some unnecessary NULL checks in vector_user.c)
+$ git merge uml/linux-next
+Already up to date.
+Merging xtensa/xtensa-for-next (70cbddb97385 arch/xtensa: fix grammar in Kconfig help text)
+$ git merge xtensa/xtensa-for-next
+Already up to date.
+Merging fscrypt/master (861261f2a9cc ubifs: wire up FS_IOC_GET_ENCRYPTION_NONCE)
+$ git merge fscrypt/master
+Already up to date.
+Merging afs/afs-next (4fe171bb81b1 afs: Remove set but not used variable 'ret')
+$ git merge afs/afs-next
+Already up to date.
+Merging btrfs/for-next (5a7ef5cb05dc Merge branch 'for-next-current-v5.6-20200331' into for-next-20200331)
+$ git merge btrfs/for-next
+Already up to date!
+Merge made by the 'recursive' strategy.
+Merging ceph/master (2a575f138d00 ceph: fix potential bad pointer deref in async dirops cb's)
+$ git merge ceph/master
+Already up to date.
+Merging cifs/for-next (9692ea9d3288 smb3: remove overly noisy debug line in signing errors)
+$ git merge cifs/for-next
+Merge made by the 'recursive' strategy.
+ fs/cifs/cifssmb.c       |  4 ++++
+ fs/cifs/inode.c         |  2 +-
+ fs/cifs/smb2pdu.c       | 15 +++++++++++++++
+ fs/cifs/smb2transport.c |  4 ++--
+ 4 files changed, 22 insertions(+), 3 deletions(-)
+Merging configfs/for-next (e2f238f7d5a1 configfs: calculate the depth of parent item)
+$ git merge configfs/for-next
+Already up to date.
+Merging ecryptfs/next (8b614cb8f1dc Merge tag '5.6-rc4-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6)
+$ git merge ecryptfs/next
+Already up to date.
+Merging erofs/dev (8f3d9f354286 Linux 5.7-rc1)
+$ git merge erofs/dev
+Already up to date.
+Merging exfat/dev (b65dea785ed9 exfat: remove the assignment of 0 to bool variable)
+$ git merge exfat/dev
+Merge made by the 'recursive' strategy.
+ fs/exfat/Kconfig    |  7 ++--
+ fs/exfat/balloc.c   | 11 ++----
+ fs/exfat/dir.c      |  9 +++--
+ fs/exfat/exfat_fs.h |  9 +++--
+ fs/exfat/fatent.c   | 13 +++----
+ fs/exfat/misc.c     |  4 +--
+ fs/exfat/namei.c    | 45 ++++++++----------------
+ fs/exfat/nls.c      | 33 +++++-------------
+ fs/exfat/super.c    | 99 +++++++++++++++++++++++------------------------------
+ 9 files changed, 89 insertions(+), 141 deletions(-)
+Merging ext3/for_next (a32f0ecd79b4 Merge fanotify fix from Nathan Chancellor.)
+$ git merge ext3/for_next
+Already up to date!
+Merge made by the 'recursive' strategy.
+Merging ext4/dev (12fb08d19005 ext4: reject mount options not supported when remounting in handle_mount_opt())
+$ git merge ext4/dev
+Merge made by the 'recursive' strategy.
+ fs/buffer.c                 | 11 +++++++++++
+ fs/ext4/balloc.c            |  4 ++--
+ fs/ext4/ext4_jbd2.c         |  3 ---
+ fs/ext4/extents.c           |  8 ++++----
+ fs/ext4/ialloc.c            |  4 ++--
+ fs/ext4/inode.c             |  4 ++--
+ fs/ext4/mballoc.c           |  6 ++++--
+ fs/ext4/super.c             | 41 ++++++++++++-----------------------------
+ include/linux/buffer_head.h |  8 ++++++++
+ 9 files changed, 45 insertions(+), 44 deletions(-)
+Merging f2fs/dev (08d834cd9599 f2fs: fix quota_sync failure due to f2fs_lock_op)
+$ git merge f2fs/dev
+Merge made by the 'recursive' strategy.
+ Documentation/ABI/testing/sysfs-fs-f2fs | 15 ++++++
+ fs/f2fs/checkpoint.c                    | 10 +++-
+ fs/f2fs/compress.c                      |  2 +-
+ fs/f2fs/data.c                          | 33 ++++++++++++-
+ fs/f2fs/f2fs.h                          | 52 +++++++++++++++----
+ fs/f2fs/file.c                          | 12 ++++-
+ fs/f2fs/gc.c                            |  6 +++
+ fs/f2fs/node.c                          |  8 ++-
+ fs/f2fs/segment.c                       | 20 ++++++--
+ fs/f2fs/super.c                         |  1 +
+ fs/f2fs/sysfs.c                         | 88 +++++++++++++++++++++++++++------
+ include/trace/events/f2fs.h             | 71 ++++++++++++++++++++++++++
+ 12 files changed, 282 insertions(+), 36 deletions(-)
+Merging fsverity/fsverity (98d54f81e36b Linux 5.6-rc4)
+$ git merge fsverity/fsverity
+Already up to date.
+Merging fuse/for-next (3e8cb8b2eaeb fuse: fix stack use after return)
+$ git merge fuse/for-next
+Already up to date.
+Merging jfs/jfs-next (7aba5dcc2346 jfs: Replace zero-length array with flexible-array member)
+$ git merge jfs/jfs-next
+Merge made by the 'recursive' strategy.
+ fs/jfs/jfs_dtree.c | 2 +-
+ fs/jfs/jfs_xattr.h | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+Merging nfs/linux-next (fbf4bcc9a837 NFS: Fix an ABBA spinlock issue in pnfs_update_layout())
+$ git merge nfs/linux-next
+Merge made by the 'recursive' strategy.
+ fs/nfs/pnfs.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+Merging nfs-anna/linux-next (55dee1bc0d72 nfs: add minor version to nfs_server_key for fscache)
+$ git merge nfs-anna/linux-next
+Already up to date.
+Merging nfsd/nfsd-next (2653de9f0398 fs: nfsd: fileache.c: Use built-in RCU list checking)
+$ git merge nfsd/nfsd-next
+Auto-merging net/sunrpc/xprtrdma/svc_rdma_rw.c
+Auto-merging net/sunrpc/cache.c
+CONFLICT (content): Merge conflict in net/sunrpc/cache.c
+Auto-merging include/linux/sunrpc/svc.h
+Auto-merging fs/nfsd/nfs4xdr.c
+Auto-merging fs/nfsd/nfs4state.c
+Resolved 'net/sunrpc/cache.c' using previous resolution.
+Automatic merge failed; fix conflicts and then commit the result.
+$ git commit --no-edit -v -a
+[master fee58263294f] Merge remote-tracking branch 'nfsd/nfsd-next'
+$ git diff -M --stat --summary HEAD^..
+Merging orangefs/for-next (aa317d3351de orangefs: clarify build steps for test server in orangefs.txt)
+$ git merge orangefs/for-next
+Already up to date.
+Merging overlayfs/overlayfs-next (2eda9eaa6d7e ovl: document xino expected behavior)
+$ git merge overlayfs/overlayfs-next
+Already up to date.
+Merging ubifs/linux-next (3676f32a98cd ubi: ubi-media.h: Replace zero-length array with flexible-array member)
+$ git merge ubifs/linux-next
+Already up to date.
+Merging v9fs/9p-next (c6f141412d24 9p: document short read behaviour with O_NONBLOCK)
+$ git merge v9fs/9p-next
+Already up to date.
+Merging xfs/for-next (63dc90feaa20 xfs: move inode flush to the sync workqueue)
+$ git merge xfs/for-next
+Merge made by the 'recursive' strategy.
+ fs/xfs/xfs_icache.c  | 10 ++++++++++
+ fs/xfs/xfs_ioctl.c   |  5 ++++-
+ fs/xfs/xfs_mount.h   |  6 +++++-
+ fs/xfs/xfs_reflink.c |  1 +
+ fs/xfs/xfs_super.c   | 40 ++++++++++++++++++++++------------------
+ 5 files changed, 42 insertions(+), 20 deletions(-)
+Merging zonefs/for-next (0dda2ddb7ded zonefs: select FS_IOMAP)
+$ git merge zonefs/for-next
+Already up to date.
+Merging iomap/iomap-for-next (457df33e035a iomap: Handle memory allocation failure in readahead)
+$ git merge iomap/iomap-for-next
+Already up to date.
+Merging djw-vfs/vfs-for-next (56939e014a6c hibernate: Allow uswsusp to write to swap)
+$ git merge djw-vfs/vfs-for-next
+Already up to date.
+Merging file-locks/locks-next (dbdaf6a3250b locks: reinstate locks_delete_block optimization)
+$ git merge file-locks/locks-next
+Auto-merging fs/cifs/file.c
+Merge made by the 'recursive' strategy.
+Merging vfs/for-next (ffca8b2a77f2 Merge branch 'work.exfat' into for-next)
+$ git merge vfs/for-next
+Auto-merging fs/namespace.c
+Auto-merging fs/erofs/zdata.c
+Auto-merging fs/erofs/super.c
+Auto-merging fs/erofs/internal.h
+Merge made by the 'recursive' strategy.
+ fs/erofs/internal.h |  27 +++---
+ fs/erofs/super.c    | 251 +++++++++++++++++++++++-----------------------------
+ fs/erofs/xattr.c    |   4 +-
+ fs/erofs/zdata.c    |   4 +-
+ fs/namespace.c      |   5 +-
+ fs/super.c          |   2 +-
+ 6 files changed, 134 insertions(+), 159 deletions(-)
+Merging printk/for-next (d34f14ae521f Merge branch 'for-5.7-preferred-console' into for-next)
+$ git merge printk/for-next
+Auto-merging kernel/printk/printk.c
+Auto-merging include/linux/console.h
+Merge made by the 'recursive' strategy.
+ include/linux/console.h         |   2 +-
+ kernel/printk/console_cmdline.h |   1 +
+ kernel/printk/printk.c          | 128 +++++++++++++++++++++++++---------------
+ 3 files changed, 83 insertions(+), 48 deletions(-)
+Merging pci/next (8f3d9f354286 Linux 5.7-rc1)
+$ git merge pci/next
+Already up to date.
+Merging pstore/for-next/pstore (8f3d9f354286 Linux 5.7-rc1)
+$ git merge pstore/for-next/pstore
+Already up to date.
+Merging hid/for-next (ce01b5b5386f Merge branch 'for-5.8/mcp2221' into for-next)
+$ git merge hid/for-next
+Merge made by the 'recursive' strategy.
+ drivers/hid/Kconfig              |  10 +--
+ drivers/hid/hid-alps.c           |   1 +
+ drivers/hid/hid-ids.h            |   4 +-
+ drivers/hid/hid-lg-g15.c         |   4 +
+ drivers/hid/hid-logitech-dj.c    |   4 +-
+ drivers/hid/hid-logitech-hidpp.c |   2 +-
+ drivers/hid/hid-mcp2221.c        | 169 +++++++++++++++++++++++++++++++++++++++
+ drivers/hid/hid-multitouch.c     |   3 +
+ drivers/hid/wacom_sys.c          |   4 +-
+ drivers/hid/wacom_wac.c          |  79 ++++--------------
+ 10 files changed, 207 insertions(+), 73 deletions(-)
+Merging i2c/i2c/for-next (8859c2d37301 Merge branch 'i2c/for-current' into i2c/for-next)
+$ git merge i2c/i2c/for-next
+Merge made by the 'recursive' strategy.
+ drivers/i2c/busses/i2c-altera.c             |  13 +-
+ drivers/i2c/busses/i2c-axxia.c              |   4 +-
+ drivers/i2c/busses/i2c-bcm-kona.c           |   4 +-
+ drivers/i2c/busses/i2c-cadence.c            | 323 ++++++++++++++++++++++++++--
+ drivers/i2c/busses/i2c-davinci.c            |   4 +-
+ drivers/i2c/busses/i2c-designware-master.c  |  37 +++-
+ drivers/i2c/busses/i2c-designware-platdrv.c |  14 +-
+ drivers/i2c/busses/i2c-digicolor.c          |   4 +-
+ drivers/i2c/busses/i2c-emev2.c              |   4 +-
+ drivers/i2c/busses/i2c-exynos5.c            |   4 +-
+ drivers/i2c/busses/i2c-hix5hd2.c            |   4 +-
+ drivers/i2c/busses/i2c-i801.c               |   6 +-
+ drivers/i2c/busses/i2c-img-scb.c            |   4 +-
+ drivers/i2c/busses/i2c-jz4780.c             |   4 +-
+ drivers/i2c/busses/i2c-lpc2k.c              |   4 +-
+ drivers/i2c/busses/i2c-meson.c              |   4 +-
+ drivers/i2c/busses/i2c-mv64xxx.c            |   4 +-
+ drivers/i2c/busses/i2c-octeon-platdrv.c     |   4 +-
+ drivers/i2c/busses/i2c-owl.c                |   4 +-
+ drivers/i2c/busses/i2c-pca-platform.c       |   3 +-
+ drivers/i2c/busses/i2c-piix4.c              |   3 +-
+ drivers/i2c/busses/i2c-qup.c                |   4 +-
+ drivers/i2c/busses/i2c-rcar.c               |   4 +-
+ drivers/i2c/busses/i2c-rk3x.c               |   4 +-
+ drivers/i2c/busses/i2c-sirf.c               |   4 +-
+ drivers/i2c/busses/i2c-stm32f7.c            |   6 +-
+ drivers/i2c/busses/i2c-stu300.c             |   4 +-
+ drivers/i2c/busses/i2c-sun6i-p2wi.c         |   4 +-
+ drivers/i2c/busses/i2c-synquacer.c          |   4 +-
+ drivers/i2c/busses/i2c-tegra.c              |  36 ++--
+ drivers/i2c/busses/i2c-xlp9xx.c             |   4 +-
+ drivers/i2c/busses/i2c-xlr.c                |   4 +-
+ drivers/i2c/busses/i2c-zx2967.c             |   4 +-
+ drivers/i2c/i2c-core-base.c                 |  82 +++----
+ include/linux/i2c.h                         |   6 -
+ 35 files changed, 443 insertions(+), 182 deletions(-)
+Merging i3c/i3c/next (c4b9de11d010 i3c: convert to use i2c_new_client_device())
+$ git merge i3c/i3c/next
+Already up to date.
+Merging dmi/master (8cf87c744696 firmware/dmi: Report DMI Bios & EC firmware release)
+$ git merge dmi/master
+Auto-merging scripts/mod/file2alias.c
+Auto-merging include/linux/mod_devicetable.h
+Auto-merging drivers/firmware/dmi_scan.c
+Merge made by the 'recursive' strategy.
+ drivers/firmware/dmi-id.c       |  6 ++++++
+ drivers/firmware/dmi_scan.c     | 30 ++++++++++++++++++++++++++++++
+ include/linux/mod_devicetable.h |  2 ++
+ scripts/mod/file2alias.c        |  2 ++
+ 4 files changed, 40 insertions(+)
+Merging hwmon-staging/hwmon-next (635049d0e3a0 hwmon: (dell-smm) Use one DMI match for all XPS models)
+$ git merge hwmon-staging/hwmon-next
+Merge made by the 'recursive' strategy.
+ drivers/hwmon/Kconfig          |   6 +-
+ drivers/hwmon/dell-smm-hwmon.c |  26 +-------
+ drivers/hwmon/nct7904.c        | 138 ++++++++++++++++++++++++++++++++++++++++-
+ 3 files changed, 143 insertions(+), 27 deletions(-)
+Merging jc_docs/docs-next (d98dbbe0d331 scripts: documentation-file-ref-check: Add line break before exit)
+$ git merge jc_docs/docs-next
+Merge made by the 'recursive' strategy.
+ Documentation/admin-guide/sysctl/kernel.rst | 47 ++++++++++++-----------------
+ Documentation/core-api/timekeeping.rst      |  6 ++--
+ scripts/documentation-file-ref-check        |  2 +-
+ scripts/kernel-doc                          |  2 +-
+ 4 files changed, 24 insertions(+), 33 deletions(-)
+Merging v4l-dvb/master (dacca5f0fa69 media: media/test_drivers: rename to test-drivers)
+$ git merge v4l-dvb/master
+Removing drivers/media/platform/tegra-cec/Makefile
+Removing drivers/media/platform/sti/cec/Makefile
+Removing drivers/media/platform/seco-cec/Makefile
+Removing drivers/media/platform/meson/Makefile
+Removing drivers/media/platform/cros-ec-cec/Makefile
+Auto-merging arch/arm/configs/exynos_defconfig
+Auto-merging MAINTAINERS
+Removing Documentation/media/media_uapi.rst
+Removing Documentation/media/media_kapi.rst
+Removing Documentation/media/index.rst
+Removing Documentation/media/dvb-drivers/udev.rst
+Removing Documentation/media/dvb-drivers/intro.rst
+Removing Documentation/media/dvb-drivers/index.rst
+Removing Documentation/media/dvb-drivers/faq.rst
+Removing Documentation/media/dvb-drivers/bt8xx.rst
+Removing Documentation/media/dvb-drivers/avermedia.rst
+Removing Documentation/media/cec-drivers/index.rst
+Removing Documentation/media/.gitignore
+Removing Documentation/devicetree/bindings/media/rockchip-vpu.txt
+Merge made by the 'recursive' strategy.
+ Documentation/ABI/testing/debugfs-cec-error-inj    |   2 +-
+ Documentation/Makefile                             |  10 +-
+ Documentation/admin-guide/index.rst                |   1 +
+ Documentation/admin-guide/kernel-parameters.txt    |   4 +-
+ .../media}/au0828-cardlist.rst                     |   0
+ Documentation/admin-guide/media/avermedia.rst      |  94 +++
+ Documentation/admin-guide/media/bt8xx.rst          | 156 +++++
+ .../media}/bttv-cardlist.rst                       |   0
+ .../v4l-drivers => admin-guide/media}/bttv.rst     | 443 +++++----------
+ .../media}/cafe_ccic.rst                           |   0
+ .../v4l-drivers => admin-guide/media}/cardlist.rst |   1 +
+ .../dvb-drivers => admin-guide/media}/cards.rst    |   0
+ Documentation/admin-guide/media/ci.rst             |  77 +++
+ .../v4l-drivers => admin-guide/media}/cpia2.rst    |  56 +-
+ Documentation/admin-guide/media/cx18-cardlist.rst  |  17 +
+ .../media}/cx23885-cardlist.rst                    |   4 +
+ .../media}/cx88-cardlist.rst                       |   4 +
+ Documentation/admin-guide/media/cx88.rst           |  58 ++
+ .../media}/davinci-vpbe.rst                        |  42 +-
+ Documentation/admin-guide/media/dvb_intro.rst      | 616 ++++++++++++++++++++
+ Documentation/admin-guide/media/dvb_references.rst |  29 +
+ .../media}/em28xx-cardlist.rst                     |   6 +-
+ Documentation/admin-guide/media/faq.rst            | 216 +++++++
+ .../v4l-drivers => admin-guide/media}/fimc.rst     |  22 +-
+ .../media}/gspca-cardlist.rst                      |   0
+ .../v4l-drivers => admin-guide/media}/imx.rst      | 131 ++---
+ .../admin-guide/media/imx6q-sabreauto.dot          |  51 ++
+ Documentation/admin-guide/media/imx6q-sabresd.dot  |  56 ++
+ .../v4l-drivers => admin-guide/media}/imx7.rst     |   0
+ Documentation/admin-guide/media/index.rst          | 122 ++++
+ .../v4l-drivers => admin-guide/media}/ipu3.rst     |  29 +-
+ .../v4l-drivers => admin-guide/media}/ipu3_rcb.svg |   0
+ .../media}/ivtv-cardlist.rst                       |   0
+ .../v4l-drivers => admin-guide/media}/ivtv.rst     |   0
+ .../dvb-drivers => admin-guide/media}/lmedm04.rst  |   0
+ .../v4l-drivers => admin-guide/media}/meye.rst     |  41 --
+ Documentation/admin-guide/media/omap3isp.rst       |  92 +++
+ .../media}/omap4_camera.rst                        |   0
+ .../media}/opera-firmware.rst                      |   0
+ .../v4l-drivers => admin-guide/media}/philips.rst  |   0
+ .../media}/pulse8-cec.rst                          |   0
+ .../media}/qcom_camss.rst                          |   0
+ .../media}/qcom_camss_8x96_graph.dot               |   0
+ .../media}/qcom_camss_graph.dot                    |   0
+ .../media}/rcar-fdp1.rst                           |   0
+ .../media}/saa7134-cardlist.rst                    |   0
+ Documentation/admin-guide/media/saa7134.rst        |  88 +++
+ .../media}/saa7164-cardlist.rst                    |   0
+ .../v4l-drivers => admin-guide/media}/si470x.rst   |   0
+ .../v4l-drivers => admin-guide/media}/si4713.rst   |   0
+ .../v4l-drivers => admin-guide/media}/si476x.rst   |   0
+ .../media}/technisat.rst                           |   0
+ .../media}/tm6000-cardlist.rst                     |   0
+ .../media}/ttusb-dec.rst                           |   0
+ .../media}/tuner-cardlist.rst                      |   0
+ .../media}/usbvision-cardlist.rst                  |   0
+ .../media}/v4l-with-ir.rst                         |   0
+ .../v4l-drivers => admin-guide/media}/vimc.dot     |   0
+ .../v4l-drivers => admin-guide/media}/vimc.rst     |  11 -
+ .../v4l-drivers => admin-guide/media}/vivid.rst    |   0
+ .../v4l-drivers => admin-guide/media}/zr364xx.rst  |  28 +-
+ .../devicetree/bindings/media/rockchip-vpu.txt     |  43 --
+ .../devicetree/bindings/media/rockchip-vpu.yaml    |  74 +++
+ Documentation/doc-guide/parse-headers.rst          |   2 +-
+ Documentation/driver-api/index.rst                 |   1 +
+ .../{media/kapi => driver-api/media}/cec-core.rst  |   0
+ .../{media/kapi => driver-api/media}/csi2.rst      |   0
+ .../driver-api/media/drivers/bttv-devel.rst        | 116 ++++
+ .../media/drivers}/contributors.rst                |   0
+ .../driver-api/media/drivers/cpia2_devel.rst       |  56 ++
+ .../media/drivers/cx2341x-devel.rst}               | 175 ------
+ .../media/drivers/cx88-devel.rst}                  |  52 --
+ .../media/drivers/davinci-vpbe-devel.rst           |  39 ++
+ .../media/drivers}/dvb-usb.rst                     |   0
+ .../driver-api/media/drivers/fimc-devel.rst        |  33 ++
+ .../media/drivers}/frontends.rst                   |   0
+ Documentation/driver-api/media/drivers/index.rst   |  38 ++
+ .../media/drivers}/pvrusb2.rst                     |   0
+ .../media/drivers}/pxa_camera.rst                  |   0
+ .../media/drivers}/radiotrack.rst                  |   0
+ .../media/drivers/saa7134-devel.rst}               |  48 --
+ .../media/drivers}/sh_mobile_ceu_camera.rst        |   0
+ .../media/drivers}/tuners.rst                      |   0
+ .../driver-api/media/drivers/vimc-devel.rst        |  15 +
+ .../{media/kapi => driver-api/media}/dtv-ca.rst    |   0
+ .../kapi => driver-api/media}/dtv-common.rst       |   0
+ .../{media/kapi => driver-api/media}/dtv-core.rst  |   0
+ .../{media/kapi => driver-api/media}/dtv-demux.rst |   0
+ .../kapi => driver-api/media}/dtv-frontend.rst     |   0
+ .../{media/kapi => driver-api/media}/dtv-net.rst   |   0
+ Documentation/driver-api/media/index.rst           |  54 ++
+ .../{media/kapi => driver-api/media}/mc-core.rst   |   0
+ .../{media/kapi => driver-api/media}/rc-core.rst   |   0
+ .../kapi => driver-api/media}/v4l2-async.rst       |   0
+ .../kapi => driver-api/media}/v4l2-clocks.rst      |   0
+ .../kapi => driver-api/media}/v4l2-common.rst      |   0
+ .../kapi => driver-api/media}/v4l2-controls.rst    |   0
+ .../{media/kapi => driver-api/media}/v4l2-core.rst |   0
+ .../{media/kapi => driver-api/media}/v4l2-dev.rst  |   0
+ .../kapi => driver-api/media}/v4l2-device.rst      |   0
+ .../kapi => driver-api/media}/v4l2-dv-timings.rst  |   0
+ .../kapi => driver-api/media}/v4l2-event.rst       |   0
+ .../{media/kapi => driver-api/media}/v4l2-fh.rst   |   0
+ .../media}/v4l2-flash-led-class.rst                |   0
+ .../kapi => driver-api/media}/v4l2-fwnode.rst      |   0
+ .../kapi => driver-api/media}/v4l2-intro.rst       |   0
+ .../{media/kapi => driver-api/media}/v4l2-mc.rst   |   0
+ .../kapi => driver-api/media}/v4l2-mediabus.rst    |   0
+ .../kapi => driver-api/media}/v4l2-mem2mem.rst     |   0
+ .../{media/kapi => driver-api/media}/v4l2-rect.rst |   0
+ .../kapi => driver-api/media}/v4l2-subdev.rst      |   0
+ .../kapi => driver-api/media}/v4l2-tuner.rst       |   0
+ .../kapi => driver-api/media}/v4l2-tveeprom.rst    |   0
+ .../kapi => driver-api/media}/v4l2-videobuf.rst    |   5 +-
+ .../kapi => driver-api/media}/v4l2-videobuf2.rst   |   0
+ Documentation/fb/api.rst                           |   4 +-
+ Documentation/index.rst                            |   1 -
+ Documentation/media/.gitignore                     |   5 -
+ Documentation/media/cec-drivers/index.rst          |  34 --
+ Documentation/media/dvb-drivers/avermedia.rst      | 269 ---------
+ Documentation/media/dvb-drivers/bt8xx.rst          | 124 ----
+ Documentation/media/dvb-drivers/faq.rst            | 169 ------
+ Documentation/media/dvb-drivers/index.rst          |  45 --
+ Documentation/media/dvb-drivers/intro.rst          |  23 -
+ Documentation/media/dvb-drivers/udev.rst           |  63 --
+ Documentation/media/index.rst                      |  26 -
+ Documentation/media/media_kapi.rst                 |  38 --
+ Documentation/media/media_uapi.rst                 |  33 --
+ .../translations/it_IT/doc-guide/parse-headers.rst |   2 +-
+ .../translations/zh_CN/video4linux/omap3isp.txt    |   4 +-
+ .../zh_CN/video4linux/v4l2-framework.txt           |   6 +-
+ Documentation/userspace-api/index.rst              |   1 +
+ Documentation/{ => userspace-api}/media/Makefile   |   2 +-
+ .../media/audio.h.rst.exceptions                   |   0
+ .../{ => userspace-api}/media/ca.h.rst.exceptions  |   0
+ .../{ => userspace-api}/media/cec.h.rst.exceptions |   0
+ .../uapi => userspace-api/media}/cec/cec-api.rst   |   2 +-
+ .../media}/cec/cec-func-close.rst                  |   2 +-
+ .../media}/cec/cec-func-ioctl.rst                  |   2 +-
+ .../media}/cec/cec-func-open.rst                   |   2 +-
+ .../media}/cec/cec-func-poll.rst                   |   2 +-
+ .../uapi => userspace-api/media}/cec/cec-funcs.rst |   2 +-
+ .../media}/cec/cec-header.rst                      |   2 +-
+ .../uapi => userspace-api/media}/cec/cec-intro.rst |   2 +-
+ .../media}/cec/cec-ioc-adap-g-caps.rst             |   2 +-
+ .../media}/cec/cec-ioc-adap-g-conn-info.rst        |   0
+ .../media}/cec/cec-ioc-adap-g-log-addrs.rst        |   2 +-
+ .../media}/cec/cec-ioc-adap-g-phys-addr.rst        |   2 +-
+ .../media}/cec/cec-ioc-dqevent.rst                 |   2 +-
+ .../media}/cec/cec-ioc-g-mode.rst                  |   2 +-
+ .../media}/cec/cec-ioc-receive.rst                 |   2 +-
+ .../media}/cec/cec-pin-error-inj.rst               |   2 +-
+ .../{ => userspace-api}/media/conf_nitpick.py      |   0
+ .../{ => userspace-api}/media/dmx.h.rst.exceptions |   0
+ .../userspace-api/media/drivers/cx2341x-uapi.rst   | 179 ++++++
+ .../userspace-api/media/drivers/imx-uapi.rst       | 125 ++++
+ .../media/drivers}/index.rst                       |  39 +-
+ .../media/drivers}/max2175.rst                     |   2 +-
+ .../userspace-api/media/drivers/meye-uapi.rst      |  53 ++
+ .../media/drivers/omap3isp-uapi.rst}               |  80 +--
+ .../media/drivers}/uvcvideo.rst                    |   0
+ .../media}/dvb/audio-bilingual-channel-select.rst  |   2 +-
+ .../media}/dvb/audio-channel-select.rst            |   2 +-
+ .../media}/dvb/audio-clear-buffer.rst              |   2 +-
+ .../media}/dvb/audio-continue.rst                  |   2 +-
+ .../media}/dvb/audio-fclose.rst                    |   2 +-
+ .../media}/dvb/audio-fopen.rst                     |   2 +-
+ .../media}/dvb/audio-fwrite.rst                    |   2 +-
+ .../media}/dvb/audio-get-capabilities.rst          |   2 +-
+ .../media}/dvb/audio-get-status.rst                |   2 +-
+ .../media}/dvb/audio-pause.rst                     |   2 +-
+ .../media}/dvb/audio-play.rst                      |   2 +-
+ .../media}/dvb/audio-select-source.rst             |   2 +-
+ .../media}/dvb/audio-set-av-sync.rst               |   2 +-
+ .../media}/dvb/audio-set-bypass-mode.rst           |   2 +-
+ .../media}/dvb/audio-set-id.rst                    |   2 +-
+ .../media}/dvb/audio-set-mixer.rst                 |   2 +-
+ .../media}/dvb/audio-set-mute.rst                  |   2 +-
+ .../media}/dvb/audio-set-streamtype.rst            |   2 +-
+ .../media}/dvb/audio-stop.rst                      |   2 +-
+ .../uapi => userspace-api/media}/dvb/audio.rst     |   2 +-
+ .../media}/dvb/audio_data_types.rst                |   2 +-
+ .../media}/dvb/audio_function_calls.rst            |   2 +-
+ .../uapi => userspace-api/media}/dvb/ca-fclose.rst |   2 +-
+ .../uapi => userspace-api/media}/dvb/ca-fopen.rst  |   2 +-
+ .../media}/dvb/ca-get-cap.rst                      |   2 +-
+ .../media}/dvb/ca-get-descr-info.rst               |   2 +-
+ .../media}/dvb/ca-get-msg.rst                      |   2 +-
+ .../media}/dvb/ca-get-slot-info.rst                |   2 +-
+ .../uapi => userspace-api/media}/dvb/ca-reset.rst  |   2 +-
+ .../media}/dvb/ca-send-msg.rst                     |   2 +-
+ .../media}/dvb/ca-set-descr.rst                    |   2 +-
+ .../{media/uapi => userspace-api/media}/dvb/ca.rst |   3 +-
+ .../media}/dvb/ca_data_types.rst                   |   2 +-
+ .../media}/dvb/ca_function_calls.rst               |   2 +-
+ .../media/dvb/ca_high_level.rst}                   |  82 +--
+ .../uapi => userspace-api/media}/dvb/demux.rst     |   2 +-
+ .../media}/dvb/dmx-add-pid.rst                     |   2 +-
+ .../media}/dvb/dmx-expbuf.rst                      |   2 +-
+ .../media}/dvb/dmx-fclose.rst                      |   2 +-
+ .../uapi => userspace-api/media}/dvb/dmx-fopen.rst |   2 +-
+ .../uapi => userspace-api/media}/dvb/dmx-fread.rst |   2 +-
+ .../media}/dvb/dmx-fwrite.rst                      |   2 +-
+ .../media}/dvb/dmx-get-pes-pids.rst                |   2 +-
+ .../media}/dvb/dmx-get-stc.rst                     |   2 +-
+ .../uapi => userspace-api/media}/dvb/dmx-mmap.rst  |   2 +-
+ .../media}/dvb/dmx-munmap.rst                      |   2 +-
+ .../uapi => userspace-api/media}/dvb/dmx-qbuf.rst  |   2 +-
+ .../media}/dvb/dmx-querybuf.rst                    |   2 +-
+ .../media}/dvb/dmx-remove-pid.rst                  |   2 +-
+ .../media}/dvb/dmx-reqbufs.rst                     |   2 +-
+ .../media}/dvb/dmx-set-buffer-size.rst             |   2 +-
+ .../media}/dvb/dmx-set-filter.rst                  |   2 +-
+ .../media}/dvb/dmx-set-pes-filter.rst              |   2 +-
+ .../uapi => userspace-api/media}/dvb/dmx-start.rst |   2 +-
+ .../uapi => userspace-api/media}/dvb/dmx-stop.rst  |   2 +-
+ .../media}/dvb/dmx_fcalls.rst                      |   2 +-
+ .../uapi => userspace-api/media}/dvb/dmx_types.rst |   2 +-
+ .../media}/dvb/dvb-fe-read-status.rst              |   2 +-
+ .../media}/dvb/dvb-frontend-event.rst              |   2 +-
+ .../media}/dvb/dvb-frontend-parameters.rst         |   2 +-
+ .../uapi => userspace-api/media}/dvb/dvbapi.rst    |   2 +-
+ .../media}/dvb/dvbproperty.rst                     |   2 +-
+ .../uapi => userspace-api/media}/dvb/dvbstb.svg    |   2 +-
+ .../uapi => userspace-api/media}/dvb/examples.rst  |   2 +-
+ .../media}/dvb/fe-bandwidth-t.rst                  |   2 +-
+ .../media}/dvb/fe-diseqc-recv-slave-reply.rst      |   2 +-
+ .../media}/dvb/fe-diseqc-reset-overload.rst        |   2 +-
+ .../media}/dvb/fe-diseqc-send-burst.rst            |   2 +-
+ .../media}/dvb/fe-diseqc-send-master-cmd.rst       |   2 +-
+ .../media}/dvb/fe-dishnetwork-send-legacy-cmd.rst  |   2 +-
+ .../media}/dvb/fe-enable-high-lnb-voltage.rst      |   2 +-
+ .../media}/dvb/fe-get-event.rst                    |   2 +-
+ .../media}/dvb/fe-get-frontend.rst                 |   2 +-
+ .../media}/dvb/fe-get-info.rst                     |   2 +-
+ .../media}/dvb/fe-get-property.rst                 |   2 +-
+ .../media}/dvb/fe-read-ber.rst                     |   2 +-
+ .../media}/dvb/fe-read-signal-strength.rst         |   2 +-
+ .../media}/dvb/fe-read-snr.rst                     |   2 +-
+ .../media}/dvb/fe-read-status.rst                  |   2 +-
+ .../media}/dvb/fe-read-uncorrected-blocks.rst      |   2 +-
+ .../media}/dvb/fe-set-frontend-tune-mode.rst       |   2 +-
+ .../media}/dvb/fe-set-frontend.rst                 |   2 +-
+ .../media}/dvb/fe-set-tone.rst                     |   2 +-
+ .../media}/dvb/fe-set-voltage.rst                  |   2 +-
+ .../uapi => userspace-api/media}/dvb/fe-type-t.rst |   2 +-
+ .../media}/dvb/fe_property_parameters.rst          |   2 +-
+ .../media}/dvb/frontend-header.rst                 |   2 +-
+ .../media}/dvb/frontend-property-cable-systems.rst |   2 +-
+ .../dvb/frontend-property-satellite-systems.rst    |   2 +-
+ .../dvb/frontend-property-terrestrial-systems.rst  |   2 +-
+ .../media}/dvb/frontend-stat-properties.rst        |   2 +-
+ .../uapi => userspace-api/media}/dvb/frontend.rst  |   2 +-
+ .../media}/dvb/frontend_f_close.rst                |   2 +-
+ .../media}/dvb/frontend_f_open.rst                 |   2 +-
+ .../media}/dvb/frontend_fcalls.rst                 |   2 +-
+ .../media}/dvb/frontend_legacy_api.rst             |   2 +-
+ .../media}/dvb/frontend_legacy_dvbv3_api.rst       |   2 +-
+ .../uapi => userspace-api/media}/dvb/headers.rst   |   2 +-
+ .../uapi => userspace-api/media}/dvb/intro.rst     |   2 +-
+ .../media}/dvb/legacy_dvb_apis.rst                 |   2 +-
+ .../media}/dvb/net-add-if.rst                      |   2 +-
+ .../media}/dvb/net-get-if.rst                      |   2 +-
+ .../media}/dvb/net-remove-if.rst                   |   2 +-
+ .../uapi => userspace-api/media}/dvb/net-types.rst |   2 +-
+ .../uapi => userspace-api/media}/dvb/net.rst       |   2 +-
+ .../media}/dvb/query-dvb-frontend-info.rst         |   2 +-
+ .../media}/dvb/video-clear-buffer.rst              |   2 +-
+ .../media}/dvb/video-command.rst                   |   2 +-
+ .../media}/dvb/video-continue.rst                  |   2 +-
+ .../media}/dvb/video-fast-forward.rst              |   2 +-
+ .../media}/dvb/video-fclose.rst                    |   2 +-
+ .../media}/dvb/video-fopen.rst                     |   2 +-
+ .../media}/dvb/video-freeze.rst                    |   2 +-
+ .../media}/dvb/video-fwrite.rst                    |   2 +-
+ .../media}/dvb/video-get-capabilities.rst          |   2 +-
+ .../media}/dvb/video-get-event.rst                 |   2 +-
+ .../media}/dvb/video-get-frame-count.rst           |   2 +-
+ .../media}/dvb/video-get-pts.rst                   |   2 +-
+ .../media}/dvb/video-get-size.rst                  |   2 +-
+ .../media}/dvb/video-get-status.rst                |   2 +-
+ .../media}/dvb/video-play.rst                      |   2 +-
+ .../media}/dvb/video-select-source.rst             |   2 +-
+ .../media}/dvb/video-set-blank.rst                 |   2 +-
+ .../media}/dvb/video-set-display-format.rst        |   2 +-
+ .../media}/dvb/video-set-format.rst                |   2 +-
+ .../media}/dvb/video-set-streamtype.rst            |   2 +-
+ .../media}/dvb/video-slowmotion.rst                |   2 +-
+ .../media}/dvb/video-stillpicture.rst              |   2 +-
+ .../media}/dvb/video-stop.rst                      |   2 +-
+ .../media}/dvb/video-try-command.rst               |   2 +-
+ .../uapi => userspace-api/media}/dvb/video.rst     |   2 +-
+ .../media}/dvb/video_function_calls.rst            |   2 +-
+ .../media}/dvb/video_types.rst                     |   2 +-
+ .../uapi => userspace-api/media}/fdl-appendix.rst  |   2 +-
+ .../media/frontend.h.rst.exceptions                |   0
+ .../uapi => userspace-api/media}/gen-errors.rst    |   2 +-
+ Documentation/userspace-api/media/index.rst        |  67 +++
+ Documentation/{ => userspace-api}/media/intro.rst  |   0
+ .../media/lirc.h.rst.exceptions                    |   0
+ .../media/media.h.rst.exceptions                   |   0
+ .../media}/mediactl/media-controller-intro.rst     |   2 +-
+ .../media}/mediactl/media-controller-model.rst     |   2 +-
+ .../media}/mediactl/media-controller.rst           |   2 +-
+ .../media}/mediactl/media-func-close.rst           |   2 +-
+ .../media}/mediactl/media-func-ioctl.rst           |   2 +-
+ .../media}/mediactl/media-func-open.rst            |   2 +-
+ .../media}/mediactl/media-funcs.rst                |   2 +-
+ .../media}/mediactl/media-header.rst               |   2 +-
+ .../media}/mediactl/media-ioc-device-info.rst      |   2 +-
+ .../media}/mediactl/media-ioc-enum-entities.rst    |   2 +-
+ .../media}/mediactl/media-ioc-enum-links.rst       |   2 +-
+ .../media}/mediactl/media-ioc-g-topology.rst       |   2 +-
+ .../media}/mediactl/media-ioc-request-alloc.rst    |   2 +-
+ .../media}/mediactl/media-ioc-setup-link.rst       |   2 +-
+ .../media}/mediactl/media-request-ioc-queue.rst    |   2 +-
+ .../media}/mediactl/media-request-ioc-reinit.rst   |   2 +-
+ .../media}/mediactl/media-types.rst                |   2 +-
+ .../media}/mediactl/request-api.rst                |   2 +-
+ .../media}/mediactl/request-func-close.rst         |   2 +-
+ .../media}/mediactl/request-func-ioctl.rst         |   2 +-
+ .../media}/mediactl/request-func-poll.rst          |   2 +-
+ .../{ => userspace-api}/media/net.h.rst.exceptions |   0
+ .../uapi => userspace-api/media}/rc/keytable.c.rst |   2 +-
+ .../media}/rc/lirc-dev-intro.rst                   |   2 +-
+ .../uapi => userspace-api/media}/rc/lirc-dev.rst   |   2 +-
+ .../uapi => userspace-api/media}/rc/lirc-func.rst  |   2 +-
+ .../media}/rc/lirc-get-features.rst                |   2 +-
+ .../media}/rc/lirc-get-rec-mode.rst                |   2 +-
+ .../media}/rc/lirc-get-rec-resolution.rst          |   2 +-
+ .../media}/rc/lirc-get-send-mode.rst               |   2 +-
+ .../media}/rc/lirc-get-timeout.rst                 |   2 +-
+ .../media}/rc/lirc-header.rst                      |   2 +-
+ .../uapi => userspace-api/media}/rc/lirc-read.rst  |   2 +-
+ .../media}/rc/lirc-set-measure-carrier-mode.rst    |   2 +-
+ .../media}/rc/lirc-set-rec-carrier-range.rst       |   2 +-
+ .../media}/rc/lirc-set-rec-carrier.rst             |   2 +-
+ .../media}/rc/lirc-set-rec-timeout-reports.rst     |   2 +-
+ .../media}/rc/lirc-set-rec-timeout.rst             |   2 +-
+ .../media}/rc/lirc-set-send-carrier.rst            |   2 +-
+ .../media}/rc/lirc-set-send-duty-cycle.rst         |   2 +-
+ .../media}/rc/lirc-set-transmitter-mask.rst        |   2 +-
+ .../media}/rc/lirc-set-wideband-receiver.rst       |   2 +-
+ .../uapi => userspace-api/media}/rc/lirc-write.rst |   2 +-
+ .../uapi => userspace-api/media}/rc/rc-intro.rst   |   2 +-
+ .../uapi => userspace-api/media}/rc/rc-protos.rst  |   0
+ .../media}/rc/rc-sysfs-nodes.rst                   |   2 +-
+ .../media}/rc/rc-table-change.rst                  |   2 +-
+ .../uapi => userspace-api/media}/rc/rc-tables.rst  |   2 +-
+ .../media}/rc/remote_controllers.rst               |   2 +-
+ .../media/typical_media_device.svg                 |   2 +-
+ .../uapi => userspace-api/media}/v4l/app-pri.rst   |   2 +-
+ .../uapi => userspace-api/media}/v4l/async.rst     |   2 +-
+ .../uapi => userspace-api/media}/v4l/audio.rst     |   2 +-
+ .../uapi => userspace-api/media}/v4l/bayer.svg     |   2 +-
+ .../uapi => userspace-api/media}/v4l/biblio.rst    |   2 +-
+ .../uapi => userspace-api/media}/v4l/buffer.rst    |   2 +-
+ .../media}/v4l/capture-example.rst                 |   2 +-
+ .../uapi => userspace-api/media}/v4l/capture.c.rst |   2 +-
+ .../media}/v4l/colorspaces-defs.rst                |   2 +-
+ .../media}/v4l/colorspaces-details.rst             |   2 +-
+ .../media}/v4l/colorspaces.rst                     |   2 +-
+ .../media}/v4l/common-defs.rst                     |   2 +-
+ .../uapi => userspace-api/media}/v4l/common.rst    |   3 +-
+ .../uapi => userspace-api/media}/v4l/compat.rst    |   2 +-
+ .../media}/v4l/constraints.svg                     |   2 +-
+ .../uapi => userspace-api/media}/v4l/control.rst   |   2 +-
+ .../uapi => userspace-api/media}/v4l/crop.rst      |   2 +-
+ .../uapi => userspace-api/media}/v4l/crop.svg      |   2 +-
+ .../media}/v4l/depth-formats.rst                   |   2 +-
+ .../media}/v4l/dev-capture.rst                     |   2 +-
+ .../media}/v4l/dev-decoder.rst                     |   0
+ .../uapi => userspace-api/media}/v4l/dev-event.rst |   2 +-
+ .../media}/v4l/dev-mem2mem.rst                     |   2 +-
+ .../uapi => userspace-api/media}/v4l/dev-meta.rst  |   2 +-
+ .../uapi => userspace-api/media}/v4l/dev-osd.rst   |   2 +-
+ .../media}/v4l/dev-output.rst                      |   2 +-
+ .../media}/v4l/dev-overlay.rst                     |   2 +-
+ .../uapi => userspace-api/media}/v4l/dev-radio.rst |   2 +-
+ .../media}/v4l/dev-raw-vbi.rst                     |   2 +-
+ .../uapi => userspace-api/media}/v4l/dev-rds.rst   |   2 +-
+ .../uapi => userspace-api/media}/v4l/dev-sdr.rst   |   2 +-
+ .../media}/v4l/dev-sliced-vbi.rst                  |   4 +-
+ .../media}/v4l/dev-stateless-decoder.rst           |   0
+ .../media}/v4l/dev-subdev.rst                      |   2 +-
+ .../uapi => userspace-api/media}/v4l/dev-touch.rst |   2 +-
+ .../uapi => userspace-api/media}/v4l/devices.rst   |   2 +-
+ .../uapi => userspace-api/media}/v4l/diff-v4l.rst  |   2 +-
+ .../uapi => userspace-api/media}/v4l/dmabuf.rst    |   2 +-
+ .../media}/v4l/dv-timings.rst                      |   2 +-
+ .../media}/v4l/ext-ctrls-camera.rst                |   2 +-
+ .../media}/v4l/ext-ctrls-codec.rst                 |   4 +-
+ .../media}/v4l/ext-ctrls-detect.rst                |   2 +-
+ .../media}/v4l/ext-ctrls-dv.rst                    |   2 +-
+ .../media}/v4l/ext-ctrls-flash.rst                 |   2 +-
+ .../media}/v4l/ext-ctrls-fm-rx.rst                 |   2 +-
+ .../media}/v4l/ext-ctrls-fm-tx.rst                 |   2 +-
+ .../media}/v4l/ext-ctrls-image-process.rst         |   4 +-
+ .../media}/v4l/ext-ctrls-image-source.rst          |   2 +-
+ .../media}/v4l/ext-ctrls-jpeg.rst                  |   2 +-
+ .../media}/v4l/ext-ctrls-rf-tuner.rst              |   2 +-
+ .../media}/v4l/extended-controls.rst               |   2 +-
+ .../media}/v4l/field-order.rst                     |   2 +-
+ .../media}/v4l/fieldseq_bt.svg                     |   2 +-
+ .../media}/v4l/fieldseq_tb.svg                     |   2 +-
+ .../uapi => userspace-api/media}/v4l/format.rst    |   2 +-
+ .../media/v4l}/fourcc.rst                          |   0
+ .../media}/v4l/func-close.rst                      |   2 +-
+ .../media}/v4l/func-ioctl.rst                      |   2 +-
+ .../uapi => userspace-api/media}/v4l/func-mmap.rst |   2 +-
+ .../media}/v4l/func-munmap.rst                     |   2 +-
+ .../uapi => userspace-api/media}/v4l/func-open.rst |   2 +-
+ .../uapi => userspace-api/media}/v4l/func-poll.rst |   2 +-
+ .../uapi => userspace-api/media}/v4l/func-read.rst |   2 +-
+ .../media}/v4l/func-select.rst                     |   2 +-
+ .../media}/v4l/func-write.rst                      |   2 +-
+ .../uapi => userspace-api/media}/v4l/hist-v4l2.rst |   2 +-
+ .../media}/v4l/hsv-formats.rst                     |   2 +-
+ .../{media/uapi => userspace-api/media}/v4l/io.rst |   2 +-
+ .../media}/v4l/libv4l-introduction.rst             |   2 +-
+ .../uapi => userspace-api/media}/v4l/libv4l.rst    |   2 +-
+ .../media}/v4l/meta-formats.rst                    |   2 +-
+ .../uapi => userspace-api/media}/v4l/mmap.rst      |   2 +-
+ .../uapi => userspace-api/media}/v4l/nv12mt.svg    |   2 +-
+ .../media}/v4l/nv12mt_example.svg                  |   2 +-
+ .../uapi => userspace-api/media}/v4l/open.rst      |   2 +-
+ .../uapi => userspace-api/media}/v4l/pipeline.dot  |   0
+ .../media}/v4l/pixfmt-bayer.rst                    |   2 +-
+ .../media}/v4l/pixfmt-cnf4.rst                     |   0
+ .../media}/v4l/pixfmt-compressed.rst               |   2 +-
+ .../media}/v4l/pixfmt-grey.rst                     |   2 +-
+ .../media}/v4l/pixfmt-indexed.rst                  |   2 +-
+ .../media}/v4l/pixfmt-intro.rst                    |   2 +-
+ .../media}/v4l/pixfmt-inzi.rst                     |   2 +-
+ .../media}/v4l/pixfmt-m420.rst                     |   2 +-
+ .../media}/v4l/pixfmt-meta-d4xx.rst                |   2 +-
+ .../media}/v4l/pixfmt-meta-intel-ipu3.rst          |   2 +-
+ .../media}/v4l/pixfmt-meta-uvc.rst                 |   2 +-
+ .../media}/v4l/pixfmt-meta-vivid.rst               |   2 +-
+ .../media}/v4l/pixfmt-meta-vsp1-hgo.rst            |   2 +-
+ .../media}/v4l/pixfmt-meta-vsp1-hgt.rst            |   2 +-
+ .../media}/v4l/pixfmt-nv12.rst                     |   2 +-
+ .../media}/v4l/pixfmt-nv12m.rst                    |   2 +-
+ .../media}/v4l/pixfmt-nv12mt.rst                   |   2 +-
+ .../media}/v4l/pixfmt-nv16.rst                     |   2 +-
+ .../media}/v4l/pixfmt-nv16m.rst                    |   2 +-
+ .../media}/v4l/pixfmt-nv24.rst                     |   2 +-
+ .../media}/v4l/pixfmt-packed-hsv.rst               |   2 +-
+ .../media}/v4l/pixfmt-packed-yuv.rst               |   2 +-
+ .../media}/v4l/pixfmt-reserved.rst                 |   4 +-
+ .../media}/v4l/pixfmt-rgb.rst                      | 138 ++---
+ .../media}/v4l/pixfmt-sdr-cs08.rst                 |   2 +-
+ .../media}/v4l/pixfmt-sdr-cs14le.rst               |   2 +-
+ .../media}/v4l/pixfmt-sdr-cu08.rst                 |   2 +-
+ .../media}/v4l/pixfmt-sdr-cu16le.rst               |   2 +-
+ .../media}/v4l/pixfmt-sdr-pcu16be.rst              |   2 +-
+ .../media}/v4l/pixfmt-sdr-pcu18be.rst              |   2 +-
+ .../media}/v4l/pixfmt-sdr-pcu20be.rst              |   2 +-
+ .../media}/v4l/pixfmt-sdr-ru12le.rst               |   2 +-
+ .../media}/v4l/pixfmt-srggb10-ipu3.rst             |   2 +-
+ .../media}/v4l/pixfmt-srggb10.rst                  |   2 +-
+ .../media}/v4l/pixfmt-srggb10alaw8.rst             |   2 +-
+ .../media}/v4l/pixfmt-srggb10dpcm8.rst             |   2 +-
+ .../media}/v4l/pixfmt-srggb10p.rst                 |   2 +-
+ .../media}/v4l/pixfmt-srggb12.rst                  |   2 +-
+ .../media}/v4l/pixfmt-srggb12p.rst                 |   2 +-
+ .../media}/v4l/pixfmt-srggb14.rst                  |   2 +-
+ .../media}/v4l/pixfmt-srggb14p.rst                 |   2 +-
+ .../media}/v4l/pixfmt-srggb16.rst                  |   2 +-
+ .../media}/v4l/pixfmt-srggb8.rst                   |   2 +-
+ .../media}/v4l/pixfmt-tch-td08.rst                 |   2 +-
+ .../media}/v4l/pixfmt-tch-td16.rst                 |   2 +-
+ .../media}/v4l/pixfmt-tch-tu08.rst                 |   2 +-
+ .../media}/v4l/pixfmt-tch-tu16.rst                 |   2 +-
+ .../media}/v4l/pixfmt-uv8.rst                      |   2 +-
+ .../media}/v4l/pixfmt-uyvy.rst                     |   2 +-
+ .../media}/v4l/pixfmt-v4l2-mplane.rst              |   2 +-
+ .../media}/v4l/pixfmt-v4l2.rst                     |   2 +-
+ .../media}/v4l/pixfmt-vyuy.rst                     |   2 +-
+ .../media}/v4l/pixfmt-y10.rst                      |   2 +-
+ .../media}/v4l/pixfmt-y10b.rst                     |   2 +-
+ .../media}/v4l/pixfmt-y10p.rst                     |   2 +-
+ .../media}/v4l/pixfmt-y12.rst                      |   2 +-
+ .../media}/v4l/pixfmt-y12i.rst                     |   2 +-
+ .../media}/v4l/pixfmt-y14.rst                      |   2 +-
+ .../media}/v4l/pixfmt-y16-be.rst                   |   2 +-
+ .../media}/v4l/pixfmt-y16.rst                      |   2 +-
+ .../media}/v4l/pixfmt-y41p.rst                     |   2 +-
+ .../media}/v4l/pixfmt-y8i.rst                      |   2 +-
+ .../media}/v4l/pixfmt-yuv410.rst                   |   2 +-
+ .../media}/v4l/pixfmt-yuv411p.rst                  |   2 +-
+ .../media}/v4l/pixfmt-yuv420.rst                   |   2 +-
+ .../media}/v4l/pixfmt-yuv420m.rst                  |   2 +-
+ .../media}/v4l/pixfmt-yuv422m.rst                  |   2 +-
+ .../media}/v4l/pixfmt-yuv422p.rst                  |   2 +-
+ .../media}/v4l/pixfmt-yuv444m.rst                  |   2 +-
+ .../media}/v4l/pixfmt-yuyv.rst                     |   2 +-
+ .../media}/v4l/pixfmt-yvyu.rst                     |   2 +-
+ .../media}/v4l/pixfmt-z16.rst                      |   2 +-
+ .../uapi => userspace-api/media}/v4l/pixfmt.rst    |   2 +-
+ .../media}/v4l/planar-apis.rst                     |   2 +-
+ .../uapi => userspace-api/media}/v4l/querycap.rst  |   2 +-
+ .../{media/uapi => userspace-api/media}/v4l/rw.rst |   2 +-
+ .../media}/v4l/sdr-formats.rst                     |   2 +-
+ .../media}/v4l/selection-api-configuration.rst     |   2 +-
+ .../media}/v4l/selection-api-examples.rst          |   2 +-
+ .../media}/v4l/selection-api-intro.rst             |   2 +-
+ .../media}/v4l/selection-api-targets.rst           |   2 +-
+ .../media}/v4l/selection-api-vs-crop-api.rst       |   2 +-
+ .../media}/v4l/selection-api.rst                   |   2 +-
+ .../uapi => userspace-api/media}/v4l/selection.svg |   2 +-
+ .../media}/v4l/selections-common.rst               |   2 +-
+ .../uapi => userspace-api/media}/v4l/standard.rst  |   2 +-
+ .../media}/v4l/streaming-par.rst                   |   2 +-
+ .../media}/v4l/subdev-formats.rst                  |   2 +-
+ .../media}/v4l/subdev-image-processing-crop.svg    |   2 +-
+ .../media}/v4l/subdev-image-processing-full.svg    |   2 +-
+ ...ubdev-image-processing-scaling-multi-source.svg |   2 +-
+ .../media}/v4l/tch-formats.rst                     |   2 +-
+ .../uapi => userspace-api/media}/v4l/tuner.rst     |   2 +-
+ .../uapi => userspace-api/media}/v4l/user-func.rst |   2 +-
+ .../uapi => userspace-api/media}/v4l/userp.rst     |   2 +-
+ .../media}/v4l/v4l2-selection-flags.rst            |   2 +-
+ .../media}/v4l/v4l2-selection-targets.rst          |   2 +-
+ .../uapi => userspace-api/media}/v4l/v4l2.rst      |   2 +-
+ .../media}/v4l/v4l2grab-example.rst                |   2 +-
+ .../media}/v4l/v4l2grab.c.rst                      |   2 +-
+ .../uapi => userspace-api/media}/v4l/vbi_525.svg   |   2 +-
+ .../uapi => userspace-api/media}/v4l/vbi_625.svg   |   2 +-
+ .../uapi => userspace-api/media}/v4l/vbi_hsync.svg |   2 +-
+ .../uapi => userspace-api/media}/v4l/video.rst     |   2 +-
+ .../uapi => userspace-api/media}/v4l/videodev.rst  |   2 +-
+ .../media}/v4l/vidioc-create-bufs.rst              |   2 +-
+ .../media}/v4l/vidioc-cropcap.rst                  |   2 +-
+ .../media}/v4l/vidioc-dbg-g-chip-info.rst          |   2 +-
+ .../media}/v4l/vidioc-dbg-g-register.rst           |   2 +-
+ .../media}/v4l/vidioc-decoder-cmd.rst              |   2 +-
+ .../media}/v4l/vidioc-dqevent.rst                  |   2 +-
+ .../media}/v4l/vidioc-dv-timings-cap.rst           |   2 +-
+ .../media}/v4l/vidioc-encoder-cmd.rst              |   2 +-
+ .../media}/v4l/vidioc-enum-dv-timings.rst          |   2 +-
+ .../media}/v4l/vidioc-enum-fmt.rst                 |   2 +-
+ .../media}/v4l/vidioc-enum-frameintervals.rst      |   2 +-
+ .../media}/v4l/vidioc-enum-framesizes.rst          |   2 +-
+ .../media}/v4l/vidioc-enum-freq-bands.rst          |   2 +-
+ .../media}/v4l/vidioc-enumaudio.rst                |   2 +-
+ .../media}/v4l/vidioc-enumaudioout.rst             |   2 +-
+ .../media}/v4l/vidioc-enuminput.rst                |   2 +-
+ .../media}/v4l/vidioc-enumoutput.rst               |   2 +-
+ .../media}/v4l/vidioc-enumstd.rst                  |   2 +-
+ .../media}/v4l/vidioc-expbuf.rst                   |   2 +-
+ .../media}/v4l/vidioc-g-audio.rst                  |   2 +-
+ .../media}/v4l/vidioc-g-audioout.rst               |   2 +-
+ .../media}/v4l/vidioc-g-crop.rst                   |   2 +-
+ .../media}/v4l/vidioc-g-ctrl.rst                   |   2 +-
+ .../media}/v4l/vidioc-g-dv-timings.rst             |   2 +-
+ .../media}/v4l/vidioc-g-edid.rst                   |   2 +-
+ .../media}/v4l/vidioc-g-enc-index.rst              |   2 +-
+ .../media}/v4l/vidioc-g-ext-ctrls.rst              |   2 +-
+ .../media}/v4l/vidioc-g-fbuf.rst                   |   2 +-
+ .../media}/v4l/vidioc-g-fmt.rst                    |   2 +-
+ .../media}/v4l/vidioc-g-frequency.rst              |   2 +-
+ .../media}/v4l/vidioc-g-input.rst                  |   2 +-
+ .../media}/v4l/vidioc-g-jpegcomp.rst               |   2 +-
+ .../media}/v4l/vidioc-g-modulator.rst              |   2 +-
+ .../media}/v4l/vidioc-g-output.rst                 |   2 +-
+ .../media}/v4l/vidioc-g-parm.rst                   |   2 +-
+ .../media}/v4l/vidioc-g-priority.rst               |   2 +-
+ .../media}/v4l/vidioc-g-selection.rst              |   2 +-
+ .../media}/v4l/vidioc-g-sliced-vbi-cap.rst         |   2 +-
+ .../media}/v4l/vidioc-g-std.rst                    |   2 +-
+ .../media}/v4l/vidioc-g-tuner.rst                  |   2 +-
+ .../media}/v4l/vidioc-log-status.rst               |   2 +-
+ .../media}/v4l/vidioc-overlay.rst                  |   2 +-
+ .../media}/v4l/vidioc-prepare-buf.rst              |   2 +-
+ .../media}/v4l/vidioc-qbuf.rst                     |   2 +-
+ .../media}/v4l/vidioc-query-dv-timings.rst         |   2 +-
+ .../media}/v4l/vidioc-querybuf.rst                 |   2 +-
+ .../media}/v4l/vidioc-querycap.rst                 |   4 +-
+ .../media}/v4l/vidioc-queryctrl.rst                |   2 +-
+ .../media}/v4l/vidioc-querystd.rst                 |   2 +-
+ .../media}/v4l/vidioc-reqbufs.rst                  |   2 +-
+ .../media}/v4l/vidioc-s-hw-freq-seek.rst           |   2 +-
+ .../media}/v4l/vidioc-streamon.rst                 |   2 +-
+ .../v4l/vidioc-subdev-enum-frame-interval.rst      |   2 +-
+ .../media}/v4l/vidioc-subdev-enum-frame-size.rst   |   2 +-
+ .../media}/v4l/vidioc-subdev-enum-mbus-code.rst    |   2 +-
+ .../media}/v4l/vidioc-subdev-g-crop.rst            |   2 +-
+ .../media}/v4l/vidioc-subdev-g-fmt.rst             |   2 +-
+ .../media}/v4l/vidioc-subdev-g-frame-interval.rst  |   2 +-
+ .../media}/v4l/vidioc-subdev-g-selection.rst       |   2 +-
+ .../media}/v4l/vidioc-subscribe-event.rst          |   2 +-
+ .../media}/v4l/yuv-formats.rst                     |   2 +-
+ .../media/video.h.rst.exceptions                   |   0
+ .../media/videodev2.h.rst.exceptions               |   0
+ MAINTAINERS                                        |  59 +-
+ arch/arm/configs/exynos_defconfig                  |   2 +-
+ arch/arm/configs/multi_v7_defconfig                |   2 +-
+ drivers/media/Kconfig                              | 242 ++++----
+ drivers/media/Makefile                             |   2 +-
+ drivers/media/cec/Kconfig                          |  25 +
+ drivers/media/cec/Makefile                         |  16 +-
+ drivers/media/cec/core/Makefile                    |  16 +
+ drivers/media/cec/{ => core}/cec-adap.c            |   0
+ drivers/media/cec/{ => core}/cec-api.c             |   0
+ drivers/media/cec/{ => core}/cec-core.c            |   0
+ drivers/media/cec/{ => core}/cec-notifier.c        |   0
+ drivers/media/cec/{ => core}/cec-pin-error-inj.c   |   0
+ drivers/media/cec/{ => core}/cec-pin-priv.h        |   0
+ drivers/media/cec/{ => core}/cec-pin.c             |   0
+ drivers/media/cec/{ => core}/cec-priv.h            |   0
+ drivers/media/cec/platform/Kconfig                 | 121 ++++
+ drivers/media/cec/platform/Makefile                |  14 +
+ drivers/media/{ => cec}/platform/cec-gpio/Makefile |   0
+ .../media/{ => cec}/platform/cec-gpio/cec-gpio.c   |   0
+ drivers/media/cec/platform/cros-ec/Makefile        |   2 +
+ .../platform/cros-ec}/cros-ec-cec.c                |   0
+ drivers/media/cec/platform/meson/Makefile          |   3 +
+ .../media/{ => cec}/platform/meson/ao-cec-g12a.c   |   0
+ drivers/media/{ => cec}/platform/meson/ao-cec.c    |   0
+ .../s5p-cec => cec/platform/s5p}/Makefile          |   2 +-
+ .../s5p-cec => cec/platform/s5p}/exynos_hdmi_cec.h |   0
+ .../platform/s5p}/exynos_hdmi_cecctrl.c            |   0
+ .../s5p-cec => cec/platform/s5p}/regs-cec.h        |   0
+ .../s5p-cec => cec/platform/s5p}/s5p_cec.c         |   0
+ .../s5p-cec => cec/platform/s5p}/s5p_cec.h         |   0
+ drivers/media/cec/platform/seco/Makefile           |   2 +
+ .../seco-cec => cec/platform/seco}/seco-cec.c      |   2 +-
+ .../seco-cec => cec/platform/seco}/seco-cec.h      |   0
+ drivers/media/cec/platform/sti/Makefile            |   2 +
+ .../sti/cec => cec/platform/sti}/stih-cec.c        |   0
+ drivers/media/cec/platform/stm32/Makefile          |   2 +
+ drivers/media/{ => cec}/platform/stm32/stm32-cec.c |   0
+ drivers/media/cec/platform/tegra/Makefile          |   2 +
+ .../tegra-cec => cec/platform/tegra}/tegra_cec.c   |   0
+ .../tegra-cec => cec/platform/tegra}/tegra_cec.h   |   0
+ drivers/media/cec/usb/Kconfig                      |   6 +
+ drivers/media/cec/usb/Makefile                     |   6 +
+ .../{usb/pulse8-cec => cec/usb/pulse8}/Kconfig     |   3 +-
+ .../{usb/pulse8-cec => cec/usb/pulse8}/Makefile    |   0
+ .../pulse8-cec => cec/usb/pulse8}/pulse8-cec.c     |   0
+ .../rainshadow-cec => cec/usb/rainshadow}/Kconfig  |   3 +-
+ .../rainshadow-cec => cec/usb/rainshadow}/Makefile |   0
+ .../usb/rainshadow}/rainshadow-cec.c               |   0
+ drivers/media/common/Kconfig                       |   2 +-
+ drivers/media/dvb-core/Kconfig                     |  27 +
+ drivers/media/dvb-frontends/Kconfig                |  17 +-
+ drivers/media/dvb-frontends/dib3000.h              |   2 +-
+ drivers/media/dvb-frontends/dib3000mb.c            |   2 +-
+ drivers/media/dvb-frontends/eds1547.h              |   2 +-
+ drivers/media/dvb-frontends/z0194a.h               |   2 +-
+ drivers/media/firewire/Kconfig                     |   5 +-
+ drivers/media/i2c/Kconfig                          | 444 +++++++++------
+ drivers/media/i2c/et8ek8/Kconfig                   |   4 +-
+ drivers/media/i2c/m5mols/Kconfig                   |   5 +-
+ drivers/media/i2c/max2175.c                        |   6 +-
+ drivers/media/i2c/ov5640.c                         |   4 +-
+ drivers/media/i2c/smiapp/Kconfig                   |   5 +-
+ drivers/media/mc/Kconfig                           |  17 +-
+ drivers/media/mmc/Kconfig                          |   1 -
+ drivers/media/mmc/siano/Kconfig                    |   2 +
+ drivers/media/pci/Kconfig                          |  14 +-
+ drivers/media/pci/bt8xx/Kconfig                    |   2 +-
+ drivers/media/pci/cobalt/Kconfig                   |   4 +-
+ drivers/media/pci/cx18/cx18-streams.c              |   4 +-
+ drivers/media/pci/cx88/cx88-core.c                 |   3 +-
+ drivers/media/pci/cx88/cx88-input.c                |   2 +-
+ drivers/media/pci/cx88/cx88-video.c                |   2 +-
+ drivers/media/pci/ddbridge/Kconfig                 |   1 -
+ drivers/media/pci/ddbridge/Makefile                |   2 +-
+ drivers/media/pci/ddbridge/ddbridge-core.c         |   4 +-
+ drivers/media/pci/ddbridge/ddbridge-dummy-fe.c     | 153 +++++
+ drivers/media/pci/ddbridge/ddbridge-dummy-fe.h     |  16 +
+ drivers/media/pci/intel/ipu3/Kconfig               |   4 +-
+ drivers/media/pci/meye/Kconfig                     |   2 +-
+ drivers/media/pci/saa7134/saa7134-input.c          |   2 +-
+ drivers/media/pci/sta2x11/Kconfig                  |   6 +-
+ drivers/media/platform/Kconfig                     | 180 +-----
+ drivers/media/platform/Makefile                    |  17 -
+ drivers/media/platform/am437x/Kconfig              |   4 +-
+ drivers/media/platform/atmel/Kconfig               |   4 +-
+ drivers/media/platform/cadence/Kconfig             |   8 +-
+ drivers/media/platform/coda/coda-common.c          | 189 +++++-
+ drivers/media/platform/coda/coda-jpeg.c            | 577 +++++++++++++++++++
+ drivers/media/platform/coda/coda.h                 |  10 +-
+ drivers/media/platform/cros-ec-cec/Makefile        |   2 -
+ drivers/media/platform/exynos4-is/Kconfig          |   5 +-
+ drivers/media/platform/marvell-ccic/cafe-driver.c  |   2 +-
+ drivers/media/platform/meson/Makefile              |   3 -
+ drivers/media/platform/pxa_camera.c                |   4 +-
+ drivers/media/platform/qcom/venus/core.c           |  15 +-
+ drivers/media/platform/qcom/venus/core.h           |   2 +
+ drivers/media/platform/qcom/venus/hfi_cmds.h       |   2 +-
+ drivers/media/platform/qcom/venus/hfi_msgs.h       |  10 +-
+ drivers/media/platform/qcom/venus/vdec.c           | 134 ++++-
+ drivers/media/platform/rcar-vin/Kconfig            |   8 +-
+ drivers/media/platform/seco-cec/Makefile           |   2 -
+ drivers/media/platform/sti/cec/Makefile            |   2 -
+ drivers/media/platform/stm32/Makefile              |   1 -
+ drivers/media/platform/sunxi/Kconfig               |   2 +
+ drivers/media/platform/sunxi/Makefile              |   2 +
+ drivers/media/platform/sunxi/sun4i-csi/Kconfig     |   6 +-
+ drivers/media/platform/sunxi/sun4i-csi/Makefile    |   2 +
+ drivers/media/platform/sunxi/sun6i-csi/Kconfig     |   4 +-
+ drivers/media/platform/tegra-cec/Makefile          |   2 -
+ drivers/media/platform/ti-vpe/cal.c                | 397 +++++++------
+ drivers/media/platform/ti-vpe/cal_regs.h           |  21 +-
+ drivers/media/platform/xilinx/Kconfig              |   4 +-
+ drivers/media/radio/Kconfig                        |  12 +-
+ drivers/media/radio/si470x/Kconfig                 |   2 +-
+ drivers/media/radio/wl128x/Kconfig                 |   5 +-
+ drivers/media/spi/Kconfig                          |   8 +-
+ drivers/media/test-drivers/Kconfig                 |  26 +
+ drivers/media/test-drivers/Makefile                |   9 +
+ .../{platform => test-drivers}/vicodec/Kconfig     |   2 +
+ .../{platform => test-drivers}/vicodec/Makefile    |   0
+ .../vicodec/codec-fwht.c                           |   0
+ .../vicodec/codec-fwht.h                           |   0
+ .../vicodec/codec-v4l2-fwht.c                      |   0
+ .../vicodec/codec-v4l2-fwht.h                      |   0
+ .../vicodec/vicodec-core.c                         |   0
+ drivers/media/{platform => test-drivers}/vim2m.c   |   8 -
+ .../media/{platform => test-drivers}/vimc/Kconfig  |   4 +-
+ .../media/{platform => test-drivers}/vimc/Makefile |   0
+ .../{platform => test-drivers}/vimc/vimc-capture.c |  18 +-
+ .../{platform => test-drivers}/vimc/vimc-common.c  |   0
+ .../{platform => test-drivers}/vimc/vimc-common.h  |  75 ++-
+ .../{platform => test-drivers}/vimc/vimc-core.c    |  90 ++-
+ .../{platform => test-drivers}/vimc/vimc-debayer.c |  15 +-
+ .../{platform => test-drivers}/vimc/vimc-scaler.c  |  15 +-
+ .../{platform => test-drivers}/vimc/vimc-sensor.c  |  15 +-
+ .../vimc/vimc-streamer.c                           |   0
+ .../vimc/vimc-streamer.h                           |   7 +-
+ .../media/{platform => test-drivers}/vivid/Kconfig |   2 +
+ .../{platform => test-drivers}/vivid/Makefile      |   0
+ .../{platform => test-drivers}/vivid/vivid-cec.c   |   0
+ .../{platform => test-drivers}/vivid/vivid-cec.h   |   0
+ .../{platform => test-drivers}/vivid/vivid-core.c  |   0
+ .../{platform => test-drivers}/vivid/vivid-core.h  |   0
+ .../{platform => test-drivers}/vivid/vivid-ctrls.c |   0
+ .../{platform => test-drivers}/vivid/vivid-ctrls.h |   0
+ .../vivid/vivid-kthread-cap.c                      |   0
+ .../vivid/vivid-kthread-cap.h                      |   0
+ .../vivid/vivid-kthread-out.c                      |   0
+ .../vivid/vivid-kthread-out.h                      |   0
+ .../vivid/vivid-kthread-touch.c                    |   0
+ .../vivid/vivid-kthread-touch.h                    |   0
+ .../vivid/vivid-meta-cap.c                         |   0
+ .../vivid/vivid-meta-cap.h                         |   0
+ .../vivid/vivid-meta-out.c                         |   0
+ .../vivid/vivid-meta-out.h                         |   0
+ .../{platform => test-drivers}/vivid/vivid-osd.c   |   0
+ .../{platform => test-drivers}/vivid/vivid-osd.h   |   0
+ .../vivid/vivid-radio-common.c                     |   0
+ .../vivid/vivid-radio-common.h                     |   0
+ .../vivid/vivid-radio-rx.c                         |   0
+ .../vivid/vivid-radio-rx.h                         |   0
+ .../vivid/vivid-radio-tx.c                         |   0
+ .../vivid/vivid-radio-tx.h                         |   0
+ .../vivid/vivid-rds-gen.c                          |   0
+ .../vivid/vivid-rds-gen.h                          |   0
+ .../vivid/vivid-sdr-cap.c                          |   0
+ .../vivid/vivid-sdr-cap.h                          |   0
+ .../vivid/vivid-touch-cap.c                        |   0
+ .../vivid/vivid-touch-cap.h                        |   0
+ .../vivid/vivid-vbi-cap.c                          |   0
+ .../vivid/vivid-vbi-cap.h                          |   0
+ .../vivid/vivid-vbi-gen.c                          |   0
+ .../vivid/vivid-vbi-gen.h                          |   0
+ .../vivid/vivid-vbi-out.c                          |   0
+ .../vivid/vivid-vbi-out.h                          |   0
+ .../vivid/vivid-vid-cap.c                          |   0
+ .../vivid/vivid-vid-cap.h                          |   0
+ .../vivid/vivid-vid-common.c                       |   0
+ .../vivid/vivid-vid-common.h                       |   0
+ .../vivid/vivid-vid-out.c                          |   0
+ .../vivid/vivid-vid-out.h                          |   0
+ drivers/media/tuners/Kconfig                       |   2 +-
+ drivers/media/usb/Kconfig                          |  12 +-
+ drivers/media/usb/Makefile                         |   2 -
+ drivers/media/usb/cx231xx/cx231xx-input.c          |   5 +-
+ drivers/media/usb/dvb-usb-v2/Kconfig               |   2 +-
+ drivers/media/usb/dvb-usb-v2/gl861.c               |   2 +-
+ drivers/media/usb/dvb-usb-v2/lmedm04.c             |   4 +-
+ drivers/media/usb/dvb-usb-v2/lmedm04.h             |   2 +-
+ drivers/media/usb/dvb-usb-v2/mxl111sf.c            |   2 +-
+ drivers/media/usb/dvb-usb-v2/mxl111sf.h            |   2 +-
+ drivers/media/usb/dvb-usb/Kconfig                  |   3 +-
+ drivers/media/usb/dvb-usb/a800.c                   |   2 +-
+ drivers/media/usb/dvb-usb/af9005-fe.c              |   2 +-
+ drivers/media/usb/dvb-usb/af9005-remote.c          |   2 +-
+ drivers/media/usb/dvb-usb/af9005.c                 |   2 +-
+ drivers/media/usb/dvb-usb/af9005.h                 |   2 +-
+ drivers/media/usb/dvb-usb/az6027.c                 |   2 +-
+ drivers/media/usb/dvb-usb/cxusb.c                  |   2 +-
+ drivers/media/usb/dvb-usb/dibusb-common.c          |   2 +-
+ drivers/media/usb/dvb-usb/dibusb-mb.c              |   2 +-
+ drivers/media/usb/dvb-usb/dibusb-mc-common.c       |   2 +-
+ drivers/media/usb/dvb-usb/dibusb-mc.c              |   2 +-
+ drivers/media/usb/dvb-usb/dibusb.h                 |   2 +-
+ drivers/media/usb/dvb-usb/digitv.c                 |   2 +-
+ drivers/media/usb/dvb-usb/dtt200u-fe.c             |   2 +-
+ drivers/media/usb/dvb-usb/dtt200u.c                |   2 +-
+ drivers/media/usb/dvb-usb/dtt200u.h                |   2 +-
+ drivers/media/usb/dvb-usb/dvb-usb-init.c           |   2 +-
+ drivers/media/usb/dvb-usb/dw2102.c                 |   2 +-
+ drivers/media/usb/dvb-usb/gp8psk.c                 |   2 +-
+ drivers/media/usb/dvb-usb/gp8psk.h                 |   2 +-
+ drivers/media/usb/dvb-usb/m920x.c                  |   2 +-
+ drivers/media/usb/dvb-usb/nova-t-usb2.c            |   2 +-
+ drivers/media/usb/dvb-usb/opera1.c                 |   2 +-
+ drivers/media/usb/dvb-usb/ttusb2.c                 |   2 +-
+ drivers/media/usb/dvb-usb/ttusb2.h                 |   2 +-
+ drivers/media/usb/dvb-usb/umt-010.c                |   2 +-
+ drivers/media/usb/dvb-usb/vp702x-fe.c              |   2 +-
+ drivers/media/usb/dvb-usb/vp702x.c                 |   2 +-
+ drivers/media/usb/dvb-usb/vp7045-fe.c              |   2 +-
+ drivers/media/usb/dvb-usb/vp7045.c                 |   2 +-
+ drivers/media/usb/dvb-usb/vp7045.h                 |   2 +-
+ drivers/media/usb/gspca/Kconfig                    |   2 +-
+ drivers/media/usb/hdpvr/hdpvr-core.c               |   4 +-
+ drivers/media/usb/hdpvr/hdpvr-i2c.c                |   2 +-
+ drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c       |   4 +-
+ drivers/media/usb/zr364xx/Kconfig                  |   2 +-
+ drivers/media/v4l2-core/Kconfig                    |  23 +-
+ drivers/media/v4l2-core/Makefile                   |   2 +
+ drivers/media/v4l2-core/v4l2-common.c              |   3 +-
+ drivers/media/v4l2-core/v4l2-jpeg.c                | 632 +++++++++++++++++++++
+ drivers/media/v4l2-core/v4l2-mem2mem.c             |  11 +-
+ drivers/staging/media/hantro/Kconfig               |   5 +-
+ drivers/staging/media/hantro/Makefile              |   2 +
+ drivers/staging/media/hantro/hantro.h              |   7 +-
+ drivers/staging/media/hantro/hantro_drv.c          |  28 +-
+ drivers/staging/media/hantro/hantro_hw.h           |  31 +
+ drivers/staging/media/hantro/hantro_v4l2.c         | 111 ++--
+ drivers/staging/media/imx/Kconfig                  |   5 +-
+ drivers/staging/media/imx/imx7-mipi-csis.c         | 446 +++++++++------
+ drivers/staging/media/ipu3/Kconfig                 |   3 +-
+ drivers/staging/media/ipu3/TODO                    |   2 -
+ drivers/staging/media/ipu3/ipu3-css-params.c       |  14 +-
+ drivers/staging/media/ipu3/ipu3-mmu.c              |  10 +-
+ drivers/staging/media/ipu3/ipu3-v4l2.c             |  28 +-
+ drivers/staging/media/ipu3/ipu3.c                  |   3 +
+ drivers/staging/media/ipu3/ipu3.h                  |   4 +
+ drivers/staging/media/omap4iss/Kconfig             |   4 +-
+ drivers/staging/media/rkisp1/Kconfig               |   4 +-
+ drivers/staging/media/rkisp1/Makefile              |   2 +
+ .../staging/media/soc_camera}/soc-camera.rst       |   0
+ drivers/staging/media/sunxi/cedrus/Kconfig         |   5 +-
+ include/media/v4l2-jpeg.h                          | 135 +++++
+ 850 files changed, 6870 insertions(+), 3750 deletions(-)
+ rename Documentation/{media/v4l-drivers => admin-guide/media}/au0828-cardlist.rst (100%)
+ create mode 100644 Documentation/admin-guide/media/avermedia.rst
+ create mode 100644 Documentation/admin-guide/media/bt8xx.rst
+ rename Documentation/{media/v4l-drivers => admin-guide/media}/bttv-cardlist.rst (100%)
+ rename Documentation/{media/v4l-drivers => admin-guide/media}/bttv.rst (79%)
+ rename Documentation/{media/v4l-drivers => admin-guide/media}/cafe_ccic.rst (100%)
+ rename Documentation/{media/v4l-drivers => admin-guide/media}/cardlist.rst (95%)
+ rename Documentation/{media/dvb-drivers => admin-guide/media}/cards.rst (100%)
+ create mode 100644 Documentation/admin-guide/media/ci.rst
+ rename Documentation/{media/v4l-drivers => admin-guide/media}/cpia2.rst (66%)
+ create mode 100644 Documentation/admin-guide/media/cx18-cardlist.rst
+ rename Documentation/{media/v4l-drivers => admin-guide/media}/cx23885-cardlist.rst (98%)
+ rename Documentation/{media/v4l-drivers => admin-guide/media}/cx88-cardlist.rst (99%)
+ create mode 100644 Documentation/admin-guide/media/cx88.rst
+ rename Documentation/{media/v4l-drivers => admin-guide/media}/davinci-vpbe.rst (72%)
+ create mode 100644 Documentation/admin-guide/media/dvb_intro.rst
+ create mode 100644 Documentation/admin-guide/media/dvb_references.rst
+ rename Documentation/{media/v4l-drivers => admin-guide/media}/em28xx-cardlist.rst (98%)
+ create mode 100644 Documentation/admin-guide/media/faq.rst
+ rename Documentation/{media/v4l-drivers => admin-guide/media}/fimc.rst (91%)
+ rename Documentation/{media/v4l-drivers => admin-guide/media}/gspca-cardlist.rst (100%)
+ rename Documentation/{media/v4l-drivers => admin-guide/media}/imx.rst (86%)
+ create mode 100644 Documentation/admin-guide/media/imx6q-sabreauto.dot
+ create mode 100644 Documentation/admin-guide/media/imx6q-sabresd.dot
+ rename Documentation/{media/v4l-drivers => admin-guide/media}/imx7.rst (100%)
+ create mode 100644 Documentation/admin-guide/media/index.rst
+ rename Documentation/{media/v4l-drivers => admin-guide/media}/ipu3.rst (95%)
+ rename Documentation/{media/v4l-drivers => admin-guide/media}/ipu3_rcb.svg (100%)
+ rename Documentation/{media/v4l-drivers => admin-guide/media}/ivtv-cardlist.rst (100%)
+ rename Documentation/{media/v4l-drivers => admin-guide/media}/ivtv.rst (100%)
+ rename Documentation/{media/dvb-drivers => admin-guide/media}/lmedm04.rst (100%)
+ rename Documentation/{media/v4l-drivers => admin-guide/media}/meye.rst (63%)
+ create mode 100644 Documentation/admin-guide/media/omap3isp.rst
+ rename Documentation/{media/v4l-drivers => admin-guide/media}/omap4_camera.rst (100%)
+ rename Documentation/{media/dvb-drivers => admin-guide/media}/opera-firmware.rst (100%)
+ rename Documentation/{media/v4l-drivers => admin-guide/media}/philips.rst (100%)
+ rename Documentation/{media/cec-drivers => admin-guide/media}/pulse8-cec.rst (100%)
+ rename Documentation/{media/v4l-drivers => admin-guide/media}/qcom_camss.rst (100%)
+ rename Documentation/{media/v4l-drivers => admin-guide/media}/qcom_camss_8x96_graph.dot (100%)
+ rename Documentation/{media/v4l-drivers => admin-guide/media}/qcom_camss_graph.dot (100%)
+ rename Documentation/{media/v4l-drivers => admin-guide/media}/rcar-fdp1.rst (100%)
+ rename Documentation/{media/v4l-drivers => admin-guide/media}/saa7134-cardlist.rst (100%)
+ create mode 100644 Documentation/admin-guide/media/saa7134.rst
+ rename Documentation/{media/v4l-drivers => admin-guide/media}/saa7164-cardlist.rst (100%)
+ rename Documentation/{media/v4l-drivers => admin-guide/media}/si470x.rst (100%)
+ rename Documentation/{media/v4l-drivers => admin-guide/media}/si4713.rst (100%)
+ rename Documentation/{media/v4l-drivers => admin-guide/media}/si476x.rst (100%)
+ rename Documentation/{media/dvb-drivers => admin-guide/media}/technisat.rst (100%)
+ rename Documentation/{media/v4l-drivers => admin-guide/media}/tm6000-cardlist.rst (100%)
+ rename Documentation/{media/dvb-drivers => admin-guide/media}/ttusb-dec.rst (100%)
+ rename Documentation/{media/v4l-drivers => admin-guide/media}/tuner-cardlist.rst (100%)
+ rename Documentation/{media/v4l-drivers => admin-guide/media}/usbvision-cardlist.rst (100%)
+ rename Documentation/{media/v4l-drivers => admin-guide/media}/v4l-with-ir.rst (100%)
+ rename Documentation/{media/v4l-drivers => admin-guide/media}/vimc.dot (100%)
+ rename Documentation/{media/v4l-drivers => admin-guide/media}/vimc.rst (92%)
+ rename Documentation/{media/v4l-drivers => admin-guide/media}/vivid.rst (100%)
+ rename Documentation/{media/v4l-drivers => admin-guide/media}/zr364xx.rst (77%)
+ delete mode 100644 Documentation/devicetree/bindings/media/rockchip-vpu.txt
+ create mode 100644 Documentation/devicetree/bindings/media/rockchip-vpu.yaml
+ rename Documentation/{media/kapi => driver-api/media}/cec-core.rst (100%)
+ rename Documentation/{media/kapi => driver-api/media}/csi2.rst (100%)
+ create mode 100644 Documentation/driver-api/media/drivers/bttv-devel.rst
+ rename Documentation/{media/dvb-drivers => driver-api/media/drivers}/contributors.rst (100%)
+ create mode 100644 Documentation/driver-api/media/drivers/cpia2_devel.rst
+ rename Documentation/{media/v4l-drivers/cx2341x.rst => driver-api/media/drivers/cx2341x-devel.rst} (91%)
+ rename Documentation/{media/v4l-drivers/cx88.rst => driver-api/media/drivers/cx88-devel.rst} (66%)
+ create mode 100644 Documentation/driver-api/media/drivers/davinci-vpbe-devel.rst
+ rename Documentation/{media/dvb-drivers => driver-api/media/drivers}/dvb-usb.rst (100%)
+ create mode 100644 Documentation/driver-api/media/drivers/fimc-devel.rst
+ rename Documentation/{media/dvb-drivers => driver-api/media/drivers}/frontends.rst (100%)
+ create mode 100644 Documentation/driver-api/media/drivers/index.rst
+ rename Documentation/{media/v4l-drivers => driver-api/media/drivers}/pvrusb2.rst (100%)
+ rename Documentation/{media/v4l-drivers => driver-api/media/drivers}/pxa_camera.rst (100%)
+ rename Documentation/{media/v4l-drivers => driver-api/media/drivers}/radiotrack.rst (100%)
+ rename Documentation/{media/v4l-drivers/saa7134.rst => driver-api/media/drivers/saa7134-devel.rst} (56%)
+ rename Documentation/{media/v4l-drivers => driver-api/media/drivers}/sh_mobile_ceu_camera.rst (100%)
+ rename Documentation/{media/v4l-drivers => driver-api/media/drivers}/tuners.rst (100%)
+ create mode 100644 Documentation/driver-api/media/drivers/vimc-devel.rst
+ rename Documentation/{media/kapi => driver-api/media}/dtv-ca.rst (100%)
+ rename Documentation/{media/kapi => driver-api/media}/dtv-common.rst (100%)
+ rename Documentation/{media/kapi => driver-api/media}/dtv-core.rst (100%)
+ rename Documentation/{media/kapi => driver-api/media}/dtv-demux.rst (100%)
+ rename Documentation/{media/kapi => driver-api/media}/dtv-frontend.rst (100%)
+ rename Documentation/{media/kapi => driver-api/media}/dtv-net.rst (100%)
+ create mode 100644 Documentation/driver-api/media/index.rst
+ rename Documentation/{media/kapi => driver-api/media}/mc-core.rst (100%)
+ rename Documentation/{media/kapi => driver-api/media}/rc-core.rst (100%)
+ rename Documentation/{media/kapi => driver-api/media}/v4l2-async.rst (100%)
+ rename Documentation/{media/kapi => driver-api/media}/v4l2-clocks.rst (100%)
+ rename Documentation/{media/kapi => driver-api/media}/v4l2-common.rst (100%)
+ rename Documentation/{media/kapi => driver-api/media}/v4l2-controls.rst (100%)
+ rename Documentation/{media/kapi => driver-api/media}/v4l2-core.rst (100%)
+ rename Documentation/{media/kapi => driver-api/media}/v4l2-dev.rst (100%)
+ rename Documentation/{media/kapi => driver-api/media}/v4l2-device.rst (100%)
+ rename Documentation/{media/kapi => driver-api/media}/v4l2-dv-timings.rst (100%)
+ rename Documentation/{media/kapi => driver-api/media}/v4l2-event.rst (100%)
+ rename Documentation/{media/kapi => driver-api/media}/v4l2-fh.rst (100%)
+ rename Documentation/{media/kapi => driver-api/media}/v4l2-flash-led-class.rst (100%)
+ rename Documentation/{media/kapi => driver-api/media}/v4l2-fwnode.rst (100%)
+ rename Documentation/{media/kapi => driver-api/media}/v4l2-intro.rst (100%)
+ rename Documentation/{media/kapi => driver-api/media}/v4l2-mc.rst (100%)
+ rename Documentation/{media/kapi => driver-api/media}/v4l2-mediabus.rst (100%)
+ rename Documentation/{media/kapi => driver-api/media}/v4l2-mem2mem.rst (100%)
+ rename Documentation/{media/kapi => driver-api/media}/v4l2-rect.rst (100%)
+ rename Documentation/{media/kapi => driver-api/media}/v4l2-subdev.rst (100%)
+ rename Documentation/{media/kapi => driver-api/media}/v4l2-tuner.rst (100%)
+ rename Documentation/{media/kapi => driver-api/media}/v4l2-tveeprom.rst (100%)
+ rename Documentation/{media/kapi => driver-api/media}/v4l2-videobuf.rst (98%)
+ rename Documentation/{media/kapi => driver-api/media}/v4l2-videobuf2.rst (100%)
+ delete mode 100644 Documentation/media/.gitignore
+ delete mode 100644 Documentation/media/cec-drivers/index.rst
+ delete mode 100644 Documentation/media/dvb-drivers/avermedia.rst
+ delete mode 100644 Documentation/media/dvb-drivers/bt8xx.rst
+ delete mode 100644 Documentation/media/dvb-drivers/faq.rst
+ delete mode 100644 Documentation/media/dvb-drivers/index.rst
+ delete mode 100644 Documentation/media/dvb-drivers/intro.rst
+ delete mode 100644 Documentation/media/dvb-drivers/udev.rst
+ delete mode 100644 Documentation/media/index.rst
+ delete mode 100644 Documentation/media/media_kapi.rst
+ delete mode 100644 Documentation/media/media_uapi.rst
+ rename Documentation/{ => userspace-api}/media/Makefile (97%)
+ rename Documentation/{ => userspace-api}/media/audio.h.rst.exceptions (100%)
+ rename Documentation/{ => userspace-api}/media/ca.h.rst.exceptions (100%)
+ rename Documentation/{ => userspace-api}/media/cec.h.rst.exceptions (100%)
+ rename Documentation/{media/uapi => userspace-api/media}/cec/cec-api.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/cec/cec-func-close.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/cec/cec-func-ioctl.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/cec/cec-func-open.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/cec/cec-func-poll.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/cec/cec-funcs.rst (93%)
+ rename Documentation/{media/uapi => userspace-api/media}/cec/cec-header.rst (90%)
+ rename Documentation/{media/uapi => userspace-api/media}/cec/cec-intro.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/cec/cec-ioc-adap-g-caps.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/cec/cec-ioc-adap-g-conn-info.rst (100%)
+ rename Documentation/{media/uapi => userspace-api/media}/cec/cec-ioc-adap-g-log-addrs.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/cec/cec-ioc-adap-g-phys-addr.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/cec/cec-ioc-dqevent.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/cec/cec-ioc-g-mode.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/cec/cec-ioc-receive.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/cec/cec-pin-error-inj.rst (99%)
+ rename Documentation/{ => userspace-api}/media/conf_nitpick.py (100%)
+ rename Documentation/{ => userspace-api}/media/dmx.h.rst.exceptions (100%)
+ create mode 100644 Documentation/userspace-api/media/drivers/cx2341x-uapi.rst
+ create mode 100644 Documentation/userspace-api/media/drivers/imx-uapi.rst
+ rename Documentation/{media/v4l-drivers => userspace-api/media/drivers}/index.rst (73%)
+ rename Documentation/{media/v4l-drivers => userspace-api/media/drivers}/max2175.rst (96%)
+ create mode 100644 Documentation/userspace-api/media/drivers/meye-uapi.rst
+ rename Documentation/{media/v4l-drivers/omap3isp.rst => userspace-api/media/drivers/omap3isp-uapi.rst} (77%)
+ rename Documentation/{media/v4l-drivers => userspace-api/media/drivers}/uvcvideo.rst (100%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/audio-bilingual-channel-select.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/audio-channel-select.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/audio-clear-buffer.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/audio-continue.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/audio-fclose.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/audio-fopen.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/audio-fwrite.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/audio-get-capabilities.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/audio-get-status.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/audio-pause.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/audio-play.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/audio-select-source.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/audio-set-av-sync.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/audio-set-bypass-mode.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/audio-set-id.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/audio-set-mixer.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/audio-set-mute.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/audio-set-streamtype.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/audio-stop.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/audio.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/audio_data_types.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/audio_function_calls.rst (94%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/ca-fclose.rst (94%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/ca-fopen.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/ca-get-cap.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/ca-get-descr-info.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/ca-get-msg.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/ca-get-slot-info.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/ca-reset.rst (94%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/ca-send-msg.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/ca-set-descr.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/ca.rst (92%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/ca_data_types.rst (90%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/ca_function_calls.rst (92%)
+ rename Documentation/{media/dvb-drivers/ci.rst => userspace-api/media/dvb/ca_high_level.rst} (68%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/demux.rst (94%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/dmx-add-pid.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/dmx-expbuf.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/dmx-fclose.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/dmx-fopen.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/dmx-fread.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/dmx-fwrite.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/dmx-get-pes-pids.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/dmx-get-stc.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/dmx-mmap.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/dmx-munmap.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/dmx-qbuf.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/dmx-querybuf.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/dmx-remove-pid.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/dmx-reqbufs.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/dmx-set-buffer-size.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/dmx-set-filter.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/dmx-set-pes-filter.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/dmx-start.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/dmx-stop.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/dmx_fcalls.rst (93%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/dmx_types.rst (90%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/dvb-fe-read-status.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/dvb-frontend-event.rst (91%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/dvb-frontend-parameters.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/dvbapi.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/dvbproperty.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/dvbstb.svg (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/examples.rst (93%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/fe-bandwidth-t.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/fe-diseqc-recv-slave-reply.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/fe-diseqc-reset-overload.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/fe-diseqc-send-burst.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/fe-diseqc-send-master-cmd.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/fe-dishnetwork-send-legacy-cmd.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/fe-enable-high-lnb-voltage.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/fe-get-event.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/fe-get-frontend.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/fe-get-info.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/fe-get-property.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/fe-read-ber.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/fe-read-signal-strength.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/fe-read-snr.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/fe-read-status.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/fe-read-uncorrected-blocks.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/fe-set-frontend-tune-mode.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/fe-set-frontend.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/fe-set-tone.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/fe-set-voltage.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/fe-type-t.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/fe_property_parameters.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/frontend-header.rst (90%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/frontend-property-cable-systems.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/frontend-property-satellite-systems.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/frontend-property-terrestrial-systems.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/frontend-stat-properties.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/frontend.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/frontend_f_close.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/frontend_f_open.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/frontend_fcalls.rst (93%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/frontend_legacy_api.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/frontend_legacy_dvbv3_api.rst (93%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/headers.rst (93%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/intro.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/legacy_dvb_apis.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/net-add-if.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/net-get-if.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/net-remove-if.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/net-types.rst (90%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/net.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/query-dvb-frontend-info.rst (93%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/video-clear-buffer.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/video-command.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/video-continue.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/video-fast-forward.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/video-fclose.rst (94%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/video-fopen.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/video-freeze.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/video-fwrite.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/video-get-capabilities.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/video-get-event.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/video-get-frame-count.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/video-get-pts.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/video-get-size.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/video-get-status.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/video-play.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/video-select-source.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/video-set-blank.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/video-set-display-format.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/video-set-format.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/video-set-streamtype.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/video-slowmotion.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/video-stillpicture.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/video-stop.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/video-try-command.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/video.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/video_function_calls.rst (94%)
+ rename Documentation/{media/uapi => userspace-api/media}/dvb/video_types.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/fdl-appendix.rst (99%)
+ rename Documentation/{ => userspace-api}/media/frontend.h.rst.exceptions (100%)
+ rename Documentation/{media/uapi => userspace-api/media}/gen-errors.rst (98%)
+ create mode 100644 Documentation/userspace-api/media/index.rst
+ rename Documentation/{ => userspace-api}/media/intro.rst (100%)
+ rename Documentation/{ => userspace-api}/media/lirc.h.rst.exceptions (100%)
+ rename Documentation/{ => userspace-api}/media/media.h.rst.exceptions (100%)
+ rename Documentation/{media/uapi => userspace-api/media}/mediactl/media-controller-intro.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/mediactl/media-controller-model.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/mediactl/media-controller.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/mediactl/media-func-close.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/mediactl/media-func-ioctl.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/mediactl/media-func-open.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/mediactl/media-funcs.rst (93%)
+ rename Documentation/{media/uapi => userspace-api/media}/mediactl/media-header.rst (90%)
+ rename Documentation/{media/uapi => userspace-api/media}/mediactl/media-ioc-device-info.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/mediactl/media-ioc-enum-entities.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/mediactl/media-ioc-enum-links.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/mediactl/media-ioc-g-topology.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/mediactl/media-ioc-request-alloc.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/mediactl/media-ioc-setup-link.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/mediactl/media-request-ioc-queue.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/mediactl/media-request-ioc-reinit.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/mediactl/media-types.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/mediactl/request-api.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/mediactl/request-func-close.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/mediactl/request-func-ioctl.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/mediactl/request-func-poll.rst (98%)
+ rename Documentation/{ => userspace-api}/media/net.h.rst.exceptions (100%)
+ rename Documentation/{media/uapi => userspace-api/media}/rc/keytable.c.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/rc/lirc-dev-intro.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/rc/lirc-dev.rst (90%)
+ rename Documentation/{media/uapi => userspace-api/media}/rc/lirc-func.rst (94%)
+ rename Documentation/{media/uapi => userspace-api/media}/rc/lirc-get-features.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/rc/lirc-get-rec-mode.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/rc/lirc-get-rec-resolution.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/rc/lirc-get-send-mode.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/rc/lirc-get-timeout.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/rc/lirc-header.rst (90%)
+ rename Documentation/{media/uapi => userspace-api/media}/rc/lirc-read.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/rc/lirc-set-measure-carrier-mode.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/rc/lirc-set-rec-carrier-range.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/rc/lirc-set-rec-carrier.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/rc/lirc-set-rec-timeout-reports.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/rc/lirc-set-rec-timeout.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/rc/lirc-set-send-carrier.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/rc/lirc-set-send-duty-cycle.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/rc/lirc-set-transmitter-mask.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/rc/lirc-set-wideband-receiver.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/rc/lirc-write.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/rc/rc-intro.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/rc/rc-protos.rst (100%)
+ rename Documentation/{media/uapi => userspace-api/media}/rc/rc-sysfs-nodes.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/rc/rc-table-change.rst (93%)
+ rename Documentation/{media/uapi => userspace-api/media}/rc/rc-tables.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/rc/remote_controllers.rst (95%)
+ rename Documentation/{ => userspace-api}/media/typical_media_device.svg (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/app-pri.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/async.rst (90%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/audio.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/bayer.svg (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/biblio.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/buffer.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/capture-example.rst (90%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/capture.c.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/colorspaces-defs.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/colorspaces-details.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/colorspaces.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/common-defs.rst (92%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/common.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/compat.rst (92%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/constraints.svg (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/control.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/crop.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/crop.svg (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/depth-formats.rst (91%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/dev-capture.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/dev-decoder.rst (100%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/dev-event.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/dev-mem2mem.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/dev-meta.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/dev-osd.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/dev-output.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/dev-overlay.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/dev-radio.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/dev-raw-vbi.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/dev-rds.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/dev-sdr.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/dev-sliced-vbi.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/dev-stateless-decoder.rst (100%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/dev-subdev.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/dev-touch.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/devices.rst (92%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/diff-v4l.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/dmabuf.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/dv-timings.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/ext-ctrls-camera.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/ext-ctrls-codec.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/ext-ctrls-detect.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/ext-ctrls-dv.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/ext-ctrls-flash.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/ext-ctrls-fm-rx.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/ext-ctrls-fm-tx.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/ext-ctrls-image-process.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/ext-ctrls-image-source.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/ext-ctrls-jpeg.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/ext-ctrls-rf-tuner.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/extended-controls.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/field-order.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/fieldseq_bt.svg (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/fieldseq_tb.svg (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/format.rst (98%)
+ rename Documentation/{media/v4l-drivers => userspace-api/media/v4l}/fourcc.rst (100%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/func-close.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/func-ioctl.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/func-mmap.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/func-munmap.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/func-open.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/func-poll.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/func-read.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/func-select.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/func-write.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/hist-v4l2.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/hsv-formats.rst (93%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/io.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/libv4l-introduction.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/libv4l.rst (90%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/meta-formats.rst (92%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/mmap.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/nv12mt.svg (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/nv12mt_example.svg (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/open.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pipeline.dot (100%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-bayer.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-cnf4.rst (100%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-compressed.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-grey.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-indexed.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-intro.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-inzi.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-m420.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-meta-d4xx.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-meta-intel-ipu3.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-meta-uvc.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-meta-vivid.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-meta-vsp1-hgo.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-meta-vsp1-hgt.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-nv12.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-nv12m.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-nv12mt.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-nv16.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-nv16m.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-nv24.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-packed-hsv.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-packed-yuv.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-reserved.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-rgb.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-sdr-cs08.rst (94%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-sdr-cs14le.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-sdr-cu08.rst (94%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-sdr-cu16le.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-sdr-pcu16be.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-sdr-pcu18be.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-sdr-pcu20be.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-sdr-ru12le.rst (94%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-srggb10-ipu3.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-srggb10.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-srggb10alaw8.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-srggb10dpcm8.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-srggb10p.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-srggb12.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-srggb12p.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-srggb14.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-srggb14p.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-srggb16.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-srggb8.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-tch-td08.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-tch-td16.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-tch-tu08.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-tch-tu16.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-uv8.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-uyvy.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-v4l2-mplane.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-v4l2.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-vyuy.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-y10.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-y10b.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-y10p.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-y12.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-y12i.rst (95%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-y14.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-y16-be.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-y16.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-y41p.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-y8i.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-yuv410.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-yuv411p.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-yuv420.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-yuv420m.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-yuv422m.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-yuv422p.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-yuv444m.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-yuyv.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-yvyu.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt-z16.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/pixfmt.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/planar-apis.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/querycap.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/rw.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/sdr-formats.rst (92%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/selection-api-configuration.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/selection-api-examples.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/selection-api-intro.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/selection-api-targets.rst (92%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/selection-api-vs-crop-api.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/selection-api.rst (92%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/selection.svg (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/selections-common.rst (94%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/standard.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/streaming-par.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/subdev-formats.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/subdev-image-processing-crop.svg (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/subdev-image-processing-full.svg (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/subdev-image-processing-scaling-multi-source.svg (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/tch-formats.rst (91%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/tuner.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/user-func.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/userp.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/v4l2-selection-flags.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/v4l2-selection-targets.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/v4l2.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/v4l2grab-example.rst (93%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/v4l2grab.c.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vbi_525.svg (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vbi_625.svg (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vbi_hsync.svg (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/video.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/videodev.rst (91%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-create-bufs.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-cropcap.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-dbg-g-chip-info.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-dbg-g-register.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-decoder-cmd.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-dqevent.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-dv-timings-cap.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-encoder-cmd.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-enum-dv-timings.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-enum-fmt.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-enum-frameintervals.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-enum-framesizes.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-enum-freq-bands.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-enumaudio.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-enumaudioout.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-enuminput.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-enumoutput.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-enumstd.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-expbuf.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-g-audio.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-g-audioout.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-g-crop.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-g-ctrl.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-g-dv-timings.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-g-edid.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-g-enc-index.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-g-ext-ctrls.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-g-fbuf.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-g-fmt.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-g-frequency.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-g-input.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-g-jpegcomp.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-g-modulator.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-g-output.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-g-parm.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-g-priority.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-g-selection.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-g-sliced-vbi-cap.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-g-std.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-g-tuner.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-log-status.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-overlay.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-prepare-buf.rst (96%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-qbuf.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-query-dv-timings.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-querybuf.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-querycap.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-queryctrl.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-querystd.rst (97%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-reqbufs.rst (99%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-s-hw-freq-seek.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-streamon.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-subdev-enum-frame-interval.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-subdev-enum-frame-size.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-subdev-enum-mbus-code.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-subdev-g-crop.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-subdev-g-fmt.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-subdev-g-frame-interval.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-subdev-g-selection.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/vidioc-subscribe-event.rst (98%)
+ rename Documentation/{media/uapi => userspace-api/media}/v4l/yuv-formats.rst (97%)
+ rename Documentation/{ => userspace-api}/media/video.h.rst.exceptions (100%)
+ rename Documentation/{ => userspace-api}/media/videodev2.h.rst.exceptions (100%)
+ create mode 100644 drivers/media/cec/core/Makefile
+ rename drivers/media/cec/{ => core}/cec-adap.c (100%)
+ rename drivers/media/cec/{ => core}/cec-api.c (100%)
+ rename drivers/media/cec/{ => core}/cec-core.c (100%)
+ rename drivers/media/cec/{ => core}/cec-notifier.c (100%)
+ rename drivers/media/cec/{ => core}/cec-pin-error-inj.c (100%)
+ rename drivers/media/cec/{ => core}/cec-pin-priv.h (100%)
+ rename drivers/media/cec/{ => core}/cec-pin.c (100%)
+ rename drivers/media/cec/{ => core}/cec-priv.h (100%)
+ create mode 100644 drivers/media/cec/platform/Kconfig
+ create mode 100644 drivers/media/cec/platform/Makefile
+ rename drivers/media/{ => cec}/platform/cec-gpio/Makefile (100%)
+ rename drivers/media/{ => cec}/platform/cec-gpio/cec-gpio.c (100%)
+ create mode 100644 drivers/media/cec/platform/cros-ec/Makefile
+ rename drivers/media/{platform/cros-ec-cec => cec/platform/cros-ec}/cros-ec-cec.c (100%)
+ create mode 100644 drivers/media/cec/platform/meson/Makefile
+ rename drivers/media/{ => cec}/platform/meson/ao-cec-g12a.c (100%)
+ rename drivers/media/{ => cec}/platform/meson/ao-cec.c (100%)
+ rename drivers/media/{platform/s5p-cec => cec/platform/s5p}/Makefile (63%)
+ rename drivers/media/{platform/s5p-cec => cec/platform/s5p}/exynos_hdmi_cec.h (100%)
+ rename drivers/media/{platform/s5p-cec => cec/platform/s5p}/exynos_hdmi_cecctrl.c (100%)
+ rename drivers/media/{platform/s5p-cec => cec/platform/s5p}/regs-cec.h (100%)
+ rename drivers/media/{platform/s5p-cec => cec/platform/s5p}/s5p_cec.c (100%)
+ rename drivers/media/{platform/s5p-cec => cec/platform/s5p}/s5p_cec.h (100%)
+ create mode 100644 drivers/media/cec/platform/seco/Makefile
+ rename drivers/media/{platform/seco-cec => cec/platform/seco}/seco-cec.c (99%)
+ rename drivers/media/{platform/seco-cec => cec/platform/seco}/seco-cec.h (100%)
+ create mode 100644 drivers/media/cec/platform/sti/Makefile
+ rename drivers/media/{platform/sti/cec => cec/platform/sti}/stih-cec.c (100%)
+ create mode 100644 drivers/media/cec/platform/stm32/Makefile
+ rename drivers/media/{ => cec}/platform/stm32/stm32-cec.c (100%)
+ create mode 100644 drivers/media/cec/platform/tegra/Makefile
+ rename drivers/media/{platform/tegra-cec => cec/platform/tegra}/tegra_cec.c (100%)
+ rename drivers/media/{platform/tegra-cec => cec/platform/tegra}/tegra_cec.h (100%)
+ create mode 100644 drivers/media/cec/usb/Kconfig
+ create mode 100644 drivers/media/cec/usb/Makefile
+ rename drivers/media/{usb/pulse8-cec => cec/usb/pulse8}/Kconfig (91%)
+ rename drivers/media/{usb/pulse8-cec => cec/usb/pulse8}/Makefile (100%)
+ rename drivers/media/{usb/pulse8-cec => cec/usb/pulse8}/pulse8-cec.c (100%)
+ rename drivers/media/{usb/rainshadow-cec => cec/usb/rainshadow}/Kconfig (92%)
+ rename drivers/media/{usb/rainshadow-cec => cec/usb/rainshadow}/Makefile (100%)
+ rename drivers/media/{usb/rainshadow-cec => cec/usb/rainshadow}/rainshadow-cec.c (100%)
+ create mode 100644 drivers/media/pci/ddbridge/ddbridge-dummy-fe.c
+ create mode 100644 drivers/media/pci/ddbridge/ddbridge-dummy-fe.h
+ delete mode 100644 drivers/media/platform/cros-ec-cec/Makefile
+ delete mode 100644 drivers/media/platform/meson/Makefile
+ delete mode 100644 drivers/media/platform/seco-cec/Makefile
+ delete mode 100644 drivers/media/platform/sti/cec/Makefile
+ delete mode 100644 drivers/media/platform/tegra-cec/Makefile
+ create mode 100644 drivers/media/test-drivers/Kconfig
+ create mode 100644 drivers/media/test-drivers/Makefile
+ rename drivers/media/{platform => test-drivers}/vicodec/Kconfig (85%)
+ rename drivers/media/{platform => test-drivers}/vicodec/Makefile (100%)
+ rename drivers/media/{platform => test-drivers}/vicodec/codec-fwht.c (100%)
+ rename drivers/media/{platform => test-drivers}/vicodec/codec-fwht.h (100%)
+ rename drivers/media/{platform => test-drivers}/vicodec/codec-v4l2-fwht.c (100%)
+ rename drivers/media/{platform => test-drivers}/vicodec/codec-v4l2-fwht.h (100%)
+ rename drivers/media/{platform => test-drivers}/vicodec/vicodec-core.c (100%)
+ rename drivers/media/{platform => test-drivers}/vim2m.c (99%)
+ rename drivers/media/{platform => test-drivers}/vimc/Kconfig (83%)
+ rename drivers/media/{platform => test-drivers}/vimc/Makefile (100%)
+ rename drivers/media/{platform => test-drivers}/vimc/vimc-capture.c (96%)
+ rename drivers/media/{platform => test-drivers}/vimc/vimc-common.c (100%)
+ rename drivers/media/{platform => test-drivers}/vimc/vimc-common.h (79%)
+ rename drivers/media/{platform => test-drivers}/vimc/vimc-core.c (87%)
+ rename drivers/media/{platform => test-drivers}/vimc/vimc-debayer.c (97%)
+ rename drivers/media/{platform => test-drivers}/vimc/vimc-scaler.c (97%)
+ rename drivers/media/{platform => test-drivers}/vimc/vimc-sensor.c (96%)
+ rename drivers/media/{platform => test-drivers}/vimc/vimc-streamer.c (100%)
+ rename drivers/media/{platform => test-drivers}/vimc/vimc-streamer.h (85%)
+ rename drivers/media/{platform => test-drivers}/vivid/Kconfig (95%)
+ rename drivers/media/{platform => test-drivers}/vivid/Makefile (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-cec.c (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-cec.h (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-core.c (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-core.h (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-ctrls.c (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-ctrls.h (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-kthread-cap.c (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-kthread-cap.h (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-kthread-out.c (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-kthread-out.h (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-kthread-touch.c (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-kthread-touch.h (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-meta-cap.c (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-meta-cap.h (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-meta-out.c (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-meta-out.h (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-osd.c (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-osd.h (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-radio-common.c (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-radio-common.h (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-radio-rx.c (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-radio-rx.h (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-radio-tx.c (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-radio-tx.h (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-rds-gen.c (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-rds-gen.h (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-sdr-cap.c (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-sdr-cap.h (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-touch-cap.c (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-touch-cap.h (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-vbi-cap.c (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-vbi-cap.h (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-vbi-gen.c (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-vbi-gen.h (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-vbi-out.c (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-vbi-out.h (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-vid-cap.c (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-vid-cap.h (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-vid-common.c (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-vid-common.h (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-vid-out.c (100%)
+ rename drivers/media/{platform => test-drivers}/vivid/vivid-vid-out.h (100%)
+ create mode 100644 drivers/media/v4l2-core/v4l2-jpeg.c
+ rename {Documentation/media/v4l-drivers => drivers/staging/media/soc_camera}/soc-camera.rst (100%)
+ create mode 100644 include/media/v4l2-jpeg.h
+Merging v4l-dvb-next/master (54ecb8f7028c Linux 5.4-rc1)
+$ git merge v4l-dvb-next/master
+Already up to date.
+Merging fbdev/fbdev-for-next (732146a3f1dc video: fbdev: imxfb: fix a typo in imxfb_probe())
+$ git merge fbdev/fbdev-for-next
+Already up to date.
+Merging pm/linux-next (1f58b05f6672 Merge branch 'pm-opp' into linux-next)
+$ git merge pm/linux-next
+Merge made by the 'recursive' strategy.
+ drivers/opp/core.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+Merging cpufreq-arm/cpufreq/arm/linux-next (8be6bbe59a69 cpufreq: omap: Build driver by default for ARCH_OMAP2PLUS)
+$ git merge cpufreq-arm/cpufreq/arm/linux-next
+Merge made by the 'recursive' strategy.
+ drivers/cpufreq/Kconfig.arm | 1 +
+ 1 file changed, 1 insertion(+)
+Merging cpupower/cpupower (8f3d9f354286 Linux 5.7-rc1)
+$ git merge cpupower/cpupower
+Already up to date.
+Merging opp/opp/linux-next (aca48b61f963 opp: Manage empty OPP tables with clk handle)
+$ git merge opp/opp/linux-next
+Already up to date.
+Merging thermal/thermal/linux-next (79799562bf08 thermal: int3400_thermal: Statically initialize .get_mode()/.set_mode() ops)
+$ git merge thermal/thermal/linux-next
+Merge made by the 'recursive' strategy.
+ .../bindings/thermal/ti,am654-thermal.yaml         |  56 +++++
+ drivers/thermal/Kconfig                            |  10 +
+ drivers/thermal/Makefile                           |   1 +
+ drivers/thermal/devfreq_cooling.c                  |  70 ++----
+ drivers/thermal/imx_sc_thermal.c                   |   4 +
+ .../intel/int340x_thermal/int3400_thermal.c        |   5 +-
+ drivers/thermal/k3_bandgap.c                       | 264 +++++++++++++++++++++
+ drivers/thermal/rockchip_thermal.c                 |   4 +-
+ drivers/thermal/st/st_thermal_memmap.c             |   4 +-
+ drivers/thermal/st/stm_thermal.c                   |   4 +-
+ drivers/thermal/thermal_core.c                     |   6 -
+ drivers/thermal/thermal_core.h                     |  52 ++++
+ drivers/thermal/thermal_helpers.c                  |  13 +-
+ drivers/thermal/ti-soc-thermal/ti-bandgap.c        |   5 +-
+ include/linux/thermal.h                            |  84 +------
+ 15 files changed, 432 insertions(+), 150 deletions(-)
+ create mode 100644 Documentation/devicetree/bindings/thermal/ti,am654-thermal.yaml
+ create mode 100644 drivers/thermal/k3_bandgap.c
+Merging thermal-rzhang/next (54ecb8f7028c Linux 5.4-rc1)
+$ git merge thermal-rzhang/next
+Already up to date.
+Merging thermal-soc/next (6c375eccded4 thermal: db8500: Rewrite to be a pure OF sensor)
+$ git merge thermal-soc/next
+Already up to date.
+Merging ieee1394/for-next (67f8e65e4fc1 firewire: net: remove set but not used variable 'guid')
+$ git merge ieee1394/for-next
+Auto-merging drivers/firewire/net.c
+Merge made by the 'recursive' strategy.
+ drivers/firewire/net.c | 2 --
+ 1 file changed, 2 deletions(-)
+Merging dlm/next (a48f9721e6db dlm: no need to check return value of debugfs_create functions)
+$ git merge dlm/next
+Already up to date.
+Merging swiotlb/linux-next (4cdfb27ba80d xen/swiotlb: remember having called xen_create_contiguous_region())
+$ git merge swiotlb/linux-next
+Auto-merging include/linux/page-flags.h
+Auto-merging drivers/xen/swiotlb-xen.c
+Merge made by the 'recursive' strategy.
+Merging rdma/for-next (8f3d9f354286 Linux 5.7-rc1)
+$ git merge rdma/for-next
+Already up to date.
+Merging net-next/master (2fcd80144b93 Merge tag 'tag-chrome-platform-fixes-for-v5.7-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux)
+$ git merge net-next/master
+Already up to date.
+Merging bpf-next/master (1a323ea5356e x86: get rid of 'errret' argument to __get_user_xyz() macross)
+$ git merge bpf-next/master
+Already up to date.
+Merging ipsec-next/master (308491755f36 xfrm: add prep for esp beet mode offload)
+$ git merge ipsec-next/master
+Already up to date.
+Merging mlx5-next/mlx5-next (826096d84f50 mlx5: Remove uninitialized use of key in mlx5_core_create_mkey)
+$ git merge mlx5-next/mlx5-next
+Already up to date.
+Merging netfilter-next/master (1a323ea5356e x86: get rid of 'errret' argument to __get_user_xyz() macross)
+$ git merge netfilter-next/master
+Already up to date.
+Merging ipvs-next/master (d54725cd11a5 netfilter: nf_tables: support for multiple devices per netdev hook)
+$ git merge ipvs-next/master
+Already up to date.
+Merging wireless-drivers-next/master (f0f383347ced brcmfmac: remove leading space)
+$ git merge wireless-drivers-next/master
+Merge made by the 'recursive' strategy.
+ drivers/net/wireless/ath/ath10k/core.c             |   5 +-
+ drivers/net/wireless/ath/ath10k/hif.h              |   9 +
+ drivers/net/wireless/ath/ath10k/htc.c              |  10 +
+ drivers/net/wireless/ath/ath10k/htc.h              |   3 +
+ drivers/net/wireless/ath/ath10k/htt.c              |   5 +
+ drivers/net/wireless/ath/ath10k/htt.h              |  13 +-
+ drivers/net/wireless/ath/ath10k/htt_rx.c           |  34 +++-
+ drivers/net/wireless/ath/ath10k/htt_tx.c           |  35 ++++
+ drivers/net/wireless/ath/ath10k/hw.h               |   2 +-
+ drivers/net/wireless/ath/ath10k/mac.c              |  84 +++++---
+ drivers/net/wireless/ath/ath10k/pci.c              |   1 +
+ drivers/net/wireless/ath/ath10k/sdio.c             |  23 +++
+ drivers/net/wireless/ath/ath10k/sdio.h             |   3 +-
+ drivers/net/wireless/ath/ath10k/txrx.c             |   2 +
+ drivers/net/wireless/ath/ath10k/wmi-tlv.c          |   6 +-
+ drivers/net/wireless/ath/ath10k/wmi.c              |  50 +++--
+ drivers/net/wireless/ath/ath10k/wmi.h              |  10 +-
+ drivers/net/wireless/ath/ath11k/ahb.c              |   2 +-
+ drivers/net/wireless/ath/ath11k/core.h             |   6 +
+ drivers/net/wireless/ath/ath11k/debug.h            |   6 +
+ drivers/net/wireless/ath/ath11k/debugfs_sta.c      | 221 +++++++++++++++++++++
+ drivers/net/wireless/ath/ath11k/dp.h               |   4 +-
+ drivers/net/wireless/ath/ath11k/dp_rx.c            |  17 +-
+ drivers/net/wireless/ath/ath11k/hal.h              |   2 +-
+ drivers/net/wireless/ath/ath11k/peer.c             |  35 +++-
+ drivers/net/wireless/ath/ath11k/peer.h             |   1 +
+ drivers/net/wireless/ath/ath11k/trace.h            |  12 +-
+ drivers/net/wireless/ath/ath11k/wmi.c              | 170 ++++++++++++++--
+ drivers/net/wireless/ath/ath11k/wmi.h              |  46 ++++-
+ drivers/net/wireless/ath/ath9k/hif_usb.c           |  58 ++++--
+ drivers/net/wireless/ath/ath9k/hif_usb.h           |   6 +
+ drivers/net/wireless/ath/ath9k/htc_drv_init.c      |  10 +-
+ drivers/net/wireless/ath/ath9k/htc_hst.c           |   6 +-
+ drivers/net/wireless/ath/ath9k/wmi.c               |   6 +-
+ drivers/net/wireless/ath/ath9k/wmi.h               |   3 +-
+ drivers/net/wireless/broadcom/b43legacy/xmit.c     |   1 +
+ .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  |   2 +-
+ .../broadcom/brcm80211/brcmfmac/commonring.c       |   8 +-
+ .../wireless/broadcom/brcm80211/brcmfmac/feature.c |   3 +-
+ .../broadcom/brcm80211/brcmsmac/mac80211_if.c      |   2 +
+ .../wireless/broadcom/brcm80211/brcmsmac/main.c    |   5 +-
+ .../net/wireless/broadcom/brcm80211/brcmsmac/stf.c |   7 +-
+ .../net/wireless/broadcom/brcm80211/brcmsmac/stf.h |   2 +-
+ drivers/net/wireless/intel/ipw2x00/ipw2200.c       |  23 +--
+ drivers/net/wireless/intersil/hostap/hostap_proc.c |   2 +
+ .../net/wireless/intersil/orinoco/spectrum_cs.c    |   3 +-
+ drivers/net/wireless/intersil/p54/p54usb.c         |   1 +
+ drivers/net/wireless/marvell/libertas/cmd.h        |   2 +-
+ drivers/net/wireless/marvell/libertas/cmdresp.c    |   5 +-
+ drivers/net/wireless/marvell/libertas/mesh.c       |   6 +-
+ drivers/net/wireless/marvell/libertas/mesh.h       |   2 +-
+ .../wireless/quantenna/qtnfmac/pcie/pearl_pcie.c   |   2 +-
+ .../wireless/quantenna/qtnfmac/pcie/topaz_pcie.c   |   2 +-
+ .../wireless/realtek/rtlwifi/rtl8723ae/hal_btc.c   |   2 +-
+ drivers/net/wireless/realtek/rtw88/fw.c            |  21 +-
+ drivers/net/wireless/realtek/rtw88/mac80211.c      |  33 +++
+ drivers/net/wireless/realtek/rtw88/main.c          |   3 +
+ drivers/net/wireless/realtek/rtw88/main.h          |   9 +-
+ drivers/net/wireless/realtek/rtw88/rtw8822b.c      |  18 +-
+ drivers/net/wireless/realtek/rtw88/rtw8822c.c      |  35 ++++
+ drivers/net/wireless/rsi/rsi_91x_mac80211.c        |   2 +-
+ drivers/net/wireless/st/cw1200/cw1200_spi.c        |   6 +-
+ 62 files changed, 932 insertions(+), 181 deletions(-)
+Merging bluetooth/master (7edc9079540b Bluetooth: Enhanced Connection Complete event belongs to LL Privacy)
+$ git merge bluetooth/master
+Auto-merging Documentation/devicetree/bindings/net/qualcomm-bluetooth.txt
+Merge made by the 'recursive' strategy.
+ .../devicetree/bindings/net/qualcomm-bluetooth.txt |   1 +
+ drivers/bluetooth/btqca.c                          |  18 +-
+ drivers/bluetooth/btqca.h                          |   3 +-
+ drivers/bluetooth/btrtl.c                          |  10 +-
+ drivers/bluetooth/btusb.c                          | 185 ++++++++++++++++-----
+ drivers/bluetooth/hci_bcm.c                        |   8 +-
+ drivers/bluetooth/hci_qca.c                        |  40 ++++-
+ include/net/bluetooth/bluetooth.h                  |   8 +
+ include/net/bluetooth/hci.h                        |  17 +-
+ include/net/bluetooth/hci_core.h                   |  16 ++
+ include/net/bluetooth/mgmt.h                       |   7 +
+ net/bluetooth/Kconfig                              |  23 ++-
+ net/bluetooth/Makefile                             |   1 +
+ net/bluetooth/hci_conn.c                           |  25 ++-
+ net/bluetooth/hci_core.c                           | 131 ++++++++-------
+ net/bluetooth/hci_debugfs.c                        |  46 +++++
+ net/bluetooth/hci_event.c                          |  54 +++++-
+ net/bluetooth/hci_request.c                        |   4 +-
+ net/bluetooth/l2cap_sock.c                         | 138 ++++++++++++++-
+ net/bluetooth/mgmt.c                               |  55 +++++-
+ net/bluetooth/msft.c                               | 141 ++++++++++++++++
+ net/bluetooth/msft.h                               |  18 ++
+ net/bluetooth/smp.c                                |  33 +++-
+ 23 files changed, 830 insertions(+), 152 deletions(-)
+ create mode 100644 net/bluetooth/msft.c
+ create mode 100644 net/bluetooth/msft.h
+Merging mac80211-next/master (1e8f471425f4 mac80211_hwsim: notify wmediumd of used MAC addresses)
+$ git merge mac80211-next/master
+Auto-merging drivers/net/wireless/mac80211_hwsim.c
+Merge made by the 'recursive' strategy.
+ drivers/net/wireless/mac80211_hwsim.c | 51 +++++++++++++++++++++++++++++++++++
+ drivers/net/wireless/mac80211_hwsim.h |  8 ++++++
+ 2 files changed, 59 insertions(+)
+Merging gfs2/for-next (197694d09af5 docs: filesystems: convert gfs2-glocks.txt to ReST)
+$ git merge gfs2/for-next
+Auto-merging MAINTAINERS
+Merge made by the 'recursive' strategy.
+ .../{gfs2-glocks.txt => gfs2-glocks.rst}           | 149 ++++++++++++---------
+ Documentation/filesystems/index.rst                |   1 +
+ MAINTAINERS                                        |   2 +-
+ 3 files changed, 87 insertions(+), 65 deletions(-)
+ rename Documentation/filesystems/{gfs2-glocks.txt => gfs2-glocks.rst} (63%)
+Merging mtd/mtd/next (025a06c1104c mtd: Convert fallthrough comments into statements)
+$ git merge mtd/mtd/next
+Already up to date.
+Merging nand/nand/next (fca88925d769 mtd: rawnand: toshiba: Support reading the number of bitflips for BENAND (Built-in ECC NAND))
+$ git merge nand/nand/next
+Already up to date.
+Merging spi-nor/spi-nor/next (8f3d9f354286 Linux 5.7-rc1)
+$ git merge spi-nor/spi-nor/next
+Already up to date.
+Merging crypto/master (0a8f5989e034 crypto: marvell/octeontx - Add missing '\n' in log messages)
+$ git merge crypto/master
+Auto-merging MAINTAINERS
+Merge made by the 'recursive' strategy.
+ .../devicetree/bindings/rng/arm-cctrng.yaml        |  54 ++
+ MAINTAINERS                                        |   9 +
+ crypto/algapi.c                                    |  24 +-
+ crypto/api.c                                       |   3 +-
+ crypto/internal.h                                  |   1 +
+ drivers/char/hw_random/Kconfig                     |  12 +
+ drivers/char/hw_random/Makefile                    |   1 +
+ drivers/char/hw_random/cctrng.c                    | 736 +++++++++++++++++++
+ drivers/char/hw_random/cctrng.h                    |  72 ++
+ drivers/char/hw_random/omap-rng.c                  |   5 +-
+ drivers/char/hw_random/xgene-rng.c                 |   4 +-
+ drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c  |   4 +-
+ drivers/crypto/amlogic/amlogic-gxl-core.c          |   4 +-
+ drivers/crypto/ccp/Kconfig                         |   3 +-
+ drivers/crypto/hisilicon/hpre/hpre.h               |   1 -
+ drivers/crypto/hisilicon/hpre/hpre_main.c          | 176 ++---
+ drivers/crypto/hisilicon/qm.c                      | 803 ++++++++++++++++++++-
+ drivers/crypto/hisilicon/qm.h                      |  41 +-
+ drivers/crypto/hisilicon/sec2/sec.h                |   1 -
+ drivers/crypto/hisilicon/sec2/sec_main.c           | 177 ++---
+ drivers/crypto/hisilicon/zip/zip_main.c            | 188 ++---
+ drivers/crypto/marvell/octeontx/otx_cptpf_main.c   |   4 +-
+ drivers/crypto/marvell/octeontx/otx_cptpf_mbox.c   |  12 +-
+ drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c  |  95 +--
+ drivers/crypto/marvell/octeontx/otx_cptvf_algs.c   |   6 +-
+ drivers/crypto/marvell/octeontx/otx_cptvf_main.c   |  12 +-
+ drivers/crypto/marvell/octeontx/otx_cptvf_reqmgr.c |  10 +-
+ 27 files changed, 1984 insertions(+), 474 deletions(-)
+ create mode 100644 Documentation/devicetree/bindings/rng/arm-cctrng.yaml
+ create mode 100644 drivers/char/hw_random/cctrng.c
+ create mode 100644 drivers/char/hw_random/cctrng.h
+Merging drm/drm-next (8f3d9f354286 Linux 5.7-rc1)
+$ git merge drm/drm-next
+Already up to date.
+Merging amdgpu/drm-next (4781c25592de drm/amdgpu/display: give aux i2c buses more meaningful names)
+$ git merge amdgpu/drm-next
+Removing include/drm/ttm/ttm_debug.h
+Auto-merging drivers/pci/p2pdma.c
+Auto-merging drivers/gpu/drm/amd/powerplay/smu_v11_0.c
+Auto-merging drivers/gpu/drm/amd/powerplay/renoir_ppt.c
+CONFLICT (content): Merge conflict in drivers/gpu/drm/amd/powerplay/renoir_ppt.c
+Auto-merging drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
+Auto-merging drivers/gpu/drm/amd/powerplay/arcturus_ppt.c
+Auto-merging drivers/gpu/drm/amd/powerplay/amd_powerplay.c
+Auto-merging drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+Auto-merging drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+Auto-merging drivers/gpu/drm/amd/display/dc/core/dc.c
+Auto-merging drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+Auto-merging drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+Auto-merging drivers/gpu/drm/amd/amdgpu/vi.c
+Auto-merging drivers/gpu/drm/amd/amdgpu/soc15.c
+Auto-merging drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
+Auto-merging drivers/gpu/drm/amd/amdgpu/nv.c
+Auto-merging drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
+Auto-merging drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
+Auto-merging drivers/gpu/drm/amd/amdgpu/cik.c
+Auto-merging drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+Auto-merging drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
+CONFLICT (content): Merge conflict in drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
+Auto-merging drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+Auto-merging drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+Recorded preimage for 'drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c'
+Recorded preimage for 'drivers/gpu/drm/amd/powerplay/renoir_ppt.c'
+Automatic merge failed; fix conflicts and then commit the result.
+$ git commit --no-edit -v -a
+Recorded resolution for 'drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c'.
+Recorded resolution for 'drivers/gpu/drm/amd/powerplay/renoir_ppt.c'.
+[master c22a6ac21afb] Merge remote-tracking branch 'amdgpu/drm-next'
+$ git diff -M --stat --summary HEAD^..
+ Documentation/gpu/amdgpu.rst                       |   88 +
+ drivers/gpu/drm/amd/amdgpu/Makefile                |    2 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu.h                |   65 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c |    3 +
+ drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c   |    6 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c      |    2 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c            |    8 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c             |    3 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c            |  160 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h            |    3 -
+ drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c        |   73 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_device.c         |  252 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c      |   12 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.h      |    1 -
+ drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c            |   21 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.c     |  185 ++
+ drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.h     |   29 +
+ drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c            |   51 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c            |    4 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h            |    5 -
+ drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c            |   47 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h            |    4 +
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c             |   85 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c            |    6 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c            |    2 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_job.c            |   13 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_job.h            |    5 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.c           |    3 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.h           |    2 -
+ drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c            |   10 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h           |    1 -
+ drivers/gpu/drm/amd/amdgpu/amdgpu_object.c         |    2 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_object.h         |   11 +
+ drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c            |  143 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h            |    2 +
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c            |   80 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h            |    4 +
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c           |   13 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h           |   54 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h           |    7 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c           |    5 +
+ drivers/gpu/drm/amd/amdgpu/amdgpu_test.c           |    6 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h          |    4 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c            |  322 ++-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h            |    8 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c          |    4 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c            |    9 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c            |    3 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c            |    7 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c            |  103 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h            |   32 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c           |   79 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h           |   20 +
+ drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c             |   91 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h             |   20 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c         |    2 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c        |   28 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c           |   30 +
+ drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.h           |    1 +
+ drivers/gpu/drm/amd/amdgpu/atom.c                  |    7 +-
+ drivers/gpu/drm/amd/amdgpu/cik.c                   |    8 -
+ drivers/gpu/drm/amd/amdgpu/cik_sdma.c              |   11 +-
+ drivers/gpu/drm/amd/amdgpu/dce_v10_0.c             |    8 +-
+ drivers/gpu/drm/amd/amdgpu/dce_v11_0.c             |    8 +-
+ drivers/gpu/drm/amd/amdgpu/dce_v6_0.c              |   14 +-
+ drivers/gpu/drm/amd/amdgpu/dce_v8_0.c              |   14 +-
+ drivers/gpu/drm/amd/amdgpu/dce_virtual.c           |   10 +-
+ drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c             | 2813 +++++++++++++++++++-
+ drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c              |   31 +-
+ drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c              |   51 +-
+ drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c              |   41 +-
+ drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c              |  119 +-
+ drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c             |    6 +-
+ drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c              |    2 +-
+ drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c              |    2 +-
+ drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c              |    2 +-
+ drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c              |    3 +
+ drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.c             |    3 +-
+ drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c             |    6 +-
+ drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c             |    3 +-
+ drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h              |    3 +-
+ drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c              |   97 +-
+ drivers/gpu/drm/amd/amdgpu/mxgpu_nv.h              |   44 +-
+ drivers/gpu/drm/amd/amdgpu/mxgpu_vi.h              |    3 +-
+ drivers/gpu/drm/amd/amdgpu/navi10_ih.c             |  302 ++-
+ drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c             |   18 -
+ drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c             |   18 -
+ drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c             |    7 -
+ drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c             |   36 +-
+ drivers/gpu/drm/amd/amdgpu/nv.c                    |   17 +-
+ drivers/gpu/drm/amd/amdgpu/nvd.h                   |   49 +
+ drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c             |   11 +-
+ drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c             |   11 +-
+ drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c             |   40 +-
+ drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c             |  127 +-
+ drivers/gpu/drm/amd/amdgpu/si.c                    |    8 -
+ drivers/gpu/drm/amd/amdgpu/si_dma.c                |   10 +-
+ drivers/gpu/drm/amd/amdgpu/si_dpm.c                |   20 -
+ drivers/gpu/drm/amd/amdgpu/soc15.c                 |    3 +-
+ drivers/gpu/drm/amd/amdgpu/soc15d.h                |   26 +-
+ drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c              |    6 +-
+ drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c              |    6 +-
+ drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c              |   16 +-
+ drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c              |   23 +-
+ drivers/gpu/drm/amd/amdgpu/vce_v2_0.c              |    3 +-
+ drivers/gpu/drm/amd/amdgpu/vce_v3_0.c              |    3 +-
+ drivers/gpu/drm/amd/amdgpu/vce_v4_0.c              |    7 +-
+ drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c              |    9 +-
+ drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c              |   77 +-
+ drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c              |   90 +-
+ drivers/gpu/drm/amd/amdgpu/vi.c                    |   24 -
+ drivers/gpu/drm/amd/amdkfd/kfd_chardev.c           |   41 +
+ drivers/gpu/drm/amd/amdkfd/kfd_device.c            |   40 +-
+ drivers/gpu/drm/amd/amdkfd/kfd_priv.h              |    3 +
+ .../gpu/drm/amd/amdkfd/kfd_process_queue_manager.c |    9 +
+ drivers/gpu/drm/amd/amdkfd/kfd_topology.c          |    2 +-
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  |   80 +-
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h  |    2 +-
+ .../drm/amd/display/amdgpu_dm/amdgpu_dm_color.c    |    3 +-
+ .../drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c  |   61 +
+ .../drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c  |    2 +-
+ .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c    |   58 +-
+ .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.h    |    3 +-
+ drivers/gpu/drm/amd/display/dc/basics/Makefile     |    3 +-
+ .../amd/display/dc/clk_mgr/dce100/dce_clk_mgr.c    |    2 +-
+ drivers/gpu/drm/amd/display/dc/core/dc.c           |    4 +-
+ drivers/gpu/drm/amd/display/dc/core/dc_link.c      |  475 ++--
+ drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c   |   15 +-
+ drivers/gpu/drm/amd/display/dc/core/dc_resource.c  |    8 +-
+ drivers/gpu/drm/amd/display/dc/dc.h                |   45 +-
+ drivers/gpu/drm/amd/display/dc/dc_link.h           |    7 +
+ drivers/gpu/drm/amd/display/dc/dce/Makefile        |    2 +-
+ drivers/gpu/drm/amd/display/dc/dce/dce_abm.c       |    1 +
+ .../gpu/drm/amd/display/dc/dce/dce_link_encoder.c  |   20 +-
+ .../gpu/drm/amd/display/dc/dce/dce_link_encoder.h  |    3 +
+ drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c      |  436 +++
+ .../dc/{basics/log_helpers.c => dce/dmub_abm.h}    |   25 +-
+ drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c      |    3 -
+ .../drm/amd/display/dc/dce80/dce80_hw_sequencer.c  |   28 -
+ .../drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c  |   49 +-
+ .../drm/amd/display/dc/dcn10/dcn10_link_encoder.c  |   20 +-
+ .../drm/amd/display/dc/dcn10/dcn10_link_encoder.h  |    3 +
+ drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c  |    6 +-
+ drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c |    6 +
+ .../drm/amd/display/dc/dcn20/dcn20_link_encoder.c  |   40 +
+ .../drm/amd/display/dc/dcn20/dcn20_link_encoder.h  |    4 +
+ .../gpu/drm/amd/display/dc/dcn20/dcn20_resource.c  |   12 +-
+ drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c  |    1 +
+ .../drm/amd/display/dc/dcn21/dcn21_link_encoder.c  |   27 +-
+ .../gpu/drm/amd/display/dc/dcn21/dcn21_resource.c  |   43 +-
+ .../display/dc/dml/dcn20/display_mode_vba_20v2.c   |    3 +-
+ drivers/gpu/drm/amd/display/dc/hdcp/hdcp_msg.c     |   89 +
+ drivers/gpu/drm/amd/display/dc/inc/hw/abm.h        |    3 +
+ drivers/gpu/drm/amd/display/dc/inc/hw/transform.h  |    2 +
+ drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h  |    4 +
+ .../amd/display/dc/virtual/virtual_link_encoder.c  |    9 +
+ drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h    |   11 +
+ .../gpu/drm/amd/display/dmub/inc/dmub_cmd_dal.h    |   14 +-
+ drivers/gpu/drm/amd/display/dmub/inc/dmub_srv.h    |   11 +
+ drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c  |   24 +-
+ drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c    |   25 +-
+ drivers/gpu/drm/amd/display/include/hdcp_types.h   |    7 +
+ .../gpu/drm/amd/display/include/logger_interface.h |    4 -
+ drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c    |    5 +-
+ drivers/gpu/drm/amd/display/modules/hdcp/hdcp.h    |   30 +-
+ .../drm/amd/display/modules/hdcp/hdcp1_execution.c |    2 +-
+ .../drm/amd/display/modules/hdcp/hdcp2_execution.c |    2 +-
+ .../gpu/drm/amd/display/modules/hdcp/hdcp_log.c    |    8 +-
+ .../gpu/drm/amd/display/modules/hdcp/hdcp_psp.c    |  482 ++--
+ drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h |    5 +-
+ .../drm/amd/display/modules/power/power_helpers.c  |   27 +-
+ .../drm/amd/display/modules/power/power_helpers.h  |    3 +
+ .../amd/include/asic_reg/nbif/nbif_6_1_offset.h    |    2 +
+ .../amd/include/asic_reg/nbio/nbio_7_0_offset.h    |    2 +
+ .../amd/include/asic_reg/nbio/nbio_7_4_offset.h    |    2 +
+ .../drm/amd/include/asic_reg/pwr/pwr_10_0_offset.h |   27 +
+ .../amd/include/asic_reg/pwr/pwr_10_0_sh_mask.h    |   30 +
+ .../include/asic_reg/smuio/smuio_12_0_0_offset.h   |   30 +
+ .../include/asic_reg/smuio/smuio_12_0_0_sh_mask.h  |   33 +
+ drivers/gpu/drm/amd/include/atomfirmware.h         |  102 +
+ drivers/gpu/drm/amd/include/cgs_common.h           |    1 -
+ drivers/gpu/drm/amd/powerplay/amd_powerplay.c      |    3 +
+ drivers/gpu/drm/amd/powerplay/amdgpu_smu.c         |  283 +-
+ drivers/gpu/drm/amd/powerplay/arcturus_ppt.c       |   10 -
+ .../gpu/drm/amd/powerplay/hwmgr/processpptables.c  |   26 +
+ drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c  |  174 +-
+ .../amd/powerplay/hwmgr/smu7_clockpowergating.c    |   61 +-
+ drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c   |  135 +-
+ .../gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c   |   40 +-
+ drivers/gpu/drm/amd/powerplay/hwmgr/smu7_thermal.c |   17 +-
+ drivers/gpu/drm/amd/powerplay/hwmgr/smu8_hwmgr.c   |  157 +-
+ drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.c   |    4 +-
+ drivers/gpu/drm/amd/powerplay/hwmgr/vega10_baco.c  |    2 +-
+ drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c |  141 +-
+ .../gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c |    9 +-
+ .../gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c   |    6 +-
+ drivers/gpu/drm/amd/powerplay/hwmgr/vega12_baco.c  |    2 +-
+ drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c |  149 +-
+ .../gpu/drm/amd/powerplay/hwmgr/vega12_thermal.c   |    7 +-
+ drivers/gpu/drm/amd/powerplay/hwmgr/vega20_baco.c  |    8 +-
+ drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c |  181 +-
+ .../gpu/drm/amd/powerplay/hwmgr/vega20_powertune.c |    6 +-
+ .../gpu/drm/amd/powerplay/hwmgr/vega20_thermal.c   |    7 +-
+ drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h     |    9 +-
+ drivers/gpu/drm/amd/powerplay/inc/hwmgr.h          |    1 +
+ .../amd/powerplay/inc/smu11_driver_if_arcturus.h   |   15 +-
+ drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h      |    5 +-
+ drivers/gpu/drm/amd/powerplay/inc/smumgr.h         |    7 +-
+ drivers/gpu/drm/amd/powerplay/navi10_ppt.c         |   99 +-
+ drivers/gpu/drm/amd/powerplay/renoir_ppt.c         |   13 +-
+ drivers/gpu/drm/amd/powerplay/smu_internal.h       |    5 +
+ drivers/gpu/drm/amd/powerplay/smu_v11_0.c          |   40 +-
+ drivers/gpu/drm/amd/powerplay/smu_v12_0.c          |   16 +-
+ drivers/gpu/drm/amd/powerplay/smumgr/ci_smumgr.c   |   18 +-
+ drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c |   35 +-
+ .../gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c  |    1 +
+ .../drm/amd/powerplay/smumgr/polaris10_smumgr.c    |   31 +-
+ .../gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c    |   39 +-
+ drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c |   48 +-
+ drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h |    4 +-
+ drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c |   69 +-
+ drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c      |   56 +-
+ .../gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c    |   15 +-
+ .../gpu/drm/amd/powerplay/smumgr/vega10_smumgr.c   |   56 +-
+ .../gpu/drm/amd/powerplay/smumgr/vega12_smumgr.c   |   68 +-
+ .../gpu/drm/amd/powerplay/smumgr/vega20_smumgr.c   |  106 +-
+ .../gpu/drm/amd/powerplay/smumgr/vegam_smumgr.c    |   18 +-
+ drivers/gpu/drm/amd/powerplay/vega20_ppt.c         |    4 +-
+ drivers/gpu/drm/radeon/Makefile                    |   35 +-
+ drivers/gpu/drm/radeon/ci_dpm.c                    |   14 -
+ drivers/gpu/drm/radeon/si_dpm.c                    |   18 -
+ drivers/gpu/drm/ttm/ttm_bo.c                       |    2 +-
+ drivers/pci/p2pdma.c                               |    2 +
+ include/drm/ttm/ttm_debug.h                        |   31 -
+ include/uapi/drm/amdgpu_drm.h                      |   15 +-
+ include/uapi/linux/kfd_ioctl.h                     |   19 +-
+ 236 files changed, 8620 insertions(+), 2830 deletions(-)
+ create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.c
+ create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.h
+ create mode 100644 drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c
+ rename drivers/gpu/drm/amd/display/dc/{basics/log_helpers.c => dce/dmub_abm.h} (75%)
+ create mode 100644 drivers/gpu/drm/amd/include/asic_reg/pwr/pwr_10_0_offset.h
+ create mode 100644 drivers/gpu/drm/amd/include/asic_reg/pwr/pwr_10_0_sh_mask.h
+ create mode 100644 drivers/gpu/drm/amd/include/asic_reg/smuio/smuio_12_0_0_offset.h
+ create mode 100644 drivers/gpu/drm/amd/include/asic_reg/smuio/smuio_12_0_0_sh_mask.h
+ delete mode 100644 include/drm/ttm/ttm_debug.h
+Merging drm-intel/for-linux-next (cef622d7634e Merge tag 'topic/phy-compliance-2020-04-08' of git://anongit.freedesktop.org/drm/drm-misc into drm-intel-next-queued)
+$ git merge drm-intel/for-linux-next
+Removing drivers/gpu/drm/i915/oa/i915_oa_tgl.h
+Removing drivers/gpu/drm/i915/oa/i915_oa_tgl.c
+Removing drivers/gpu/drm/i915/oa/i915_oa_sklgt4.h
+Removing drivers/gpu/drm/i915/oa/i915_oa_sklgt4.c
+Removing drivers/gpu/drm/i915/oa/i915_oa_sklgt3.h
+Removing drivers/gpu/drm/i915/oa/i915_oa_sklgt3.c
+Removing drivers/gpu/drm/i915/oa/i915_oa_sklgt2.h
+Removing drivers/gpu/drm/i915/oa/i915_oa_sklgt2.c
+Removing drivers/gpu/drm/i915/oa/i915_oa_kblgt3.h
+Removing drivers/gpu/drm/i915/oa/i915_oa_kblgt3.c
+Removing drivers/gpu/drm/i915/oa/i915_oa_kblgt2.h
+Removing drivers/gpu/drm/i915/oa/i915_oa_kblgt2.c
+Removing drivers/gpu/drm/i915/oa/i915_oa_icl.h
+Removing drivers/gpu/drm/i915/oa/i915_oa_icl.c
+Removing drivers/gpu/drm/i915/oa/i915_oa_hsw.h
+Removing drivers/gpu/drm/i915/oa/i915_oa_hsw.c
+Removing drivers/gpu/drm/i915/oa/i915_oa_glk.h
+Removing drivers/gpu/drm/i915/oa/i915_oa_glk.c
+Removing drivers/gpu/drm/i915/oa/i915_oa_cnl.h
+Removing drivers/gpu/drm/i915/oa/i915_oa_cnl.c
+Removing drivers/gpu/drm/i915/oa/i915_oa_chv.h
+Removing drivers/gpu/drm/i915/oa/i915_oa_chv.c
+Removing drivers/gpu/drm/i915/oa/i915_oa_cflgt3.h
+Removing drivers/gpu/drm/i915/oa/i915_oa_cflgt3.c
+Removing drivers/gpu/drm/i915/oa/i915_oa_cflgt2.h
+Removing drivers/gpu/drm/i915/oa/i915_oa_cflgt2.c
+Removing drivers/gpu/drm/i915/oa/i915_oa_bxt.h
+Removing drivers/gpu/drm/i915/oa/i915_oa_bxt.c
+Removing drivers/gpu/drm/i915/oa/i915_oa_bdw.h
+Removing drivers/gpu/drm/i915/oa/i915_oa_bdw.c
+Auto-merging drivers/gpu/drm/i915/i915_perf.c
+Auto-merging drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+Merge made by the 'recursive' strategy.
+ Documentation/gpu/i915.rst                         |   6 +-
+ drivers/char/agp/intel-gtt.c                       |   4 +-
+ drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c   |   2 +-
+ drivers/gpu/drm/drm_dp_helper.c                    |  96 +++
+ drivers/gpu/drm/i915/Makefile                      |  23 +-
+ drivers/gpu/drm/i915/display/icl_dsi.c             | 167 +++-
+ drivers/gpu/drm/i915/display/intel_atomic_plane.c  |  21 +-
+ drivers/gpu/drm/i915/display/intel_atomic_plane.h  |   2 +
+ drivers/gpu/drm/i915/display/intel_audio.c         |  18 +-
+ drivers/gpu/drm/i915/display/intel_bw.c            |   9 +-
+ drivers/gpu/drm/i915/display/intel_color.c         | 121 ++-
+ drivers/gpu/drm/i915/display/intel_connector.c     |   2 +-
+ drivers/gpu/drm/i915/display/intel_crt.c           |  36 +-
+ drivers/gpu/drm/i915/display/intel_ddi.c           | 522 ++++++++----
+ drivers/gpu/drm/i915/display/intel_ddi.h           |   3 +-
+ drivers/gpu/drm/i915/display/intel_display.c       | 470 +++--------
+ drivers/gpu/drm/i915/display/intel_display.h       |   8 +-
+ .../gpu/drm/i915/display/intel_display_debugfs.c   |  12 +-
+ drivers/gpu/drm/i915/display/intel_display_power.c |  24 +-
+ drivers/gpu/drm/i915/display/intel_display_types.h |  39 +-
+ drivers/gpu/drm/i915/display/intel_dp.c            | 932 +++++++++++++++++----
+ drivers/gpu/drm/i915/display/intel_dp.h            |   4 +
+ .../gpu/drm/i915/display/intel_dp_aux_backlight.c  |  84 +-
+ .../gpu/drm/i915/display/intel_dp_link_training.c  |   9 +-
+ .../gpu/drm/i915/display/intel_dp_link_training.h  |   4 +
+ drivers/gpu/drm/i915/display/intel_dp_mst.c        | 153 ++--
+ drivers/gpu/drm/i915/display/intel_dsi.c           |   9 +-
+ drivers/gpu/drm/i915/display/intel_dsi_vbt.c       |  11 +-
+ drivers/gpu/drm/i915/display/intel_dvo.c           |   9 +-
+ drivers/gpu/drm/i915/display/intel_fbc.c           |  84 +-
+ drivers/gpu/drm/i915/display/intel_fbdev.c         |  96 ++-
+ drivers/gpu/drm/i915/display/intel_global_state.c  |   5 +-
+ drivers/gpu/drm/i915/display/intel_hdcp.c          |   6 +-
+ drivers/gpu/drm/i915/display/intel_hdcp.h          |   4 +-
+ drivers/gpu/drm/i915/display/intel_hdmi.c          | 256 ++++--
+ drivers/gpu/drm/i915/display/intel_hotplug.c       |  16 +-
+ drivers/gpu/drm/i915/display/intel_hotplug.h       |   3 +-
+ drivers/gpu/drm/i915/display/intel_lvds.c          |  22 +-
+ drivers/gpu/drm/i915/display/intel_overlay.c       |   2 +-
+ drivers/gpu/drm/i915/display/intel_panel.c         |  22 +-
+ drivers/gpu/drm/i915/display/intel_panel.h         |   3 +-
+ drivers/gpu/drm/i915/display/intel_psr.c           |  47 +-
+ drivers/gpu/drm/i915/display/intel_sdvo.c          |  22 +-
+ drivers/gpu/drm/i915/display/intel_sprite.c        |  25 +-
+ drivers/gpu/drm/i915/display/intel_tc.c            |  47 +-
+ drivers/gpu/drm/i915/display/intel_tv.c            |  15 +-
+ drivers/gpu/drm/i915/display/vlv_dsi.c             |  15 +-
+ drivers/gpu/drm/i915/gem/i915_gem_context.c        |  85 +-
+ drivers/gpu/drm/i915/gem/i915_gem_context.h        |   4 +
+ drivers/gpu/drm/i915/gem/i915_gem_domain.c         |   2 +-
+ drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c     | 365 ++++----
+ drivers/gpu/drm/i915/gem/i915_gem_object.c         |   1 -
+ drivers/gpu/drm/i915/gem/i915_gem_object_types.h   |   3 -
+ drivers/gpu/drm/i915/gem/i915_gem_pages.c          |   2 -
+ drivers/gpu/drm/i915/gem/i915_gem_shrinker.c       |  18 +-
+ drivers/gpu/drm/i915/gem/i915_gem_stolen.c         |   4 +-
+ .../gpu/drm/i915/gem/selftests/huge_gem_object.c   |   3 +-
+ .../gpu/drm/i915/gem/selftests/i915_gem_context.c  |   2 +-
+ drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c |   4 -
+ .../gpu/drm/i915/gem/selftests/i915_gem_object.c   |   2 +-
+ drivers/gpu/drm/i915/gt/debugfs_engines.c          |   2 +-
+ drivers/gpu/drm/i915/gt/debugfs_gt.c               |  15 +-
+ drivers/gpu/drm/i915/gt/debugfs_gt.h               |   9 +-
+ drivers/gpu/drm/i915/gt/debugfs_gt_pm.c            |  10 +-
+ drivers/gpu/drm/i915/gt/intel_breadcrumbs.c        |   6 +-
+ drivers/gpu/drm/i915/gt/intel_context.c            |   5 +
+ drivers/gpu/drm/i915/gt/intel_engine.h             |   2 +
+ drivers/gpu/drm/i915/gt/intel_engine_cs.c          | 127 +--
+ drivers/gpu/drm/i915/gt/intel_engine_heartbeat.c   |   2 +-
+ drivers/gpu/drm/i915/gt/intel_engine_pm.c          |   2 +-
+ drivers/gpu/drm/i915/gt/intel_engine_pm.h          |   6 +
+ drivers/gpu/drm/i915/gt/intel_engine_types.h       |  12 +
+ drivers/gpu/drm/i915/gt/intel_ggtt.c               |  52 +-
+ .../intel_ggtt_fencing.c}                          | 170 ++--
+ .../intel_ggtt_fencing.h}                          |  17 +-
+ drivers/gpu/drm/i915/gt/intel_gt.c                 |   3 +-
+ drivers/gpu/drm/i915/gt/intel_gt_irq.c             |  15 +-
+ drivers/gpu/drm/i915/gt/intel_gt_pm.c              |   5 +-
+ drivers/gpu/drm/i915/gt/intel_gt_requests.c        |   2 +-
+ drivers/gpu/drm/i915/gt/intel_gtt.h                |   5 +-
+ drivers/gpu/drm/i915/gt/intel_lrc.c                | 252 ++++--
+ drivers/gpu/drm/i915/gt/intel_rc6.c                |  39 +-
+ drivers/gpu/drm/i915/gt/intel_renderstate.c        |   2 +-
+ drivers/gpu/drm/i915/gt/intel_reset.c              |  16 +-
+ drivers/gpu/drm/i915/gt/intel_ring.h               |   5 +-
+ drivers/gpu/drm/i915/gt/intel_ring_submission.c    |  33 +-
+ drivers/gpu/drm/i915/gt/intel_rps.c                | 105 +--
+ drivers/gpu/drm/i915/gt/intel_sseu.c               |  33 +-
+ drivers/gpu/drm/i915/gt/intel_timeline.c           |  12 +-
+ drivers/gpu/drm/i915/gt/intel_workarounds.c        |  21 +-
+ drivers/gpu/drm/i915/gt/selftest_gt_pm.c           |   2 +
+ drivers/gpu/drm/i915/gt/selftest_lrc.c             | 117 ++-
+ drivers/gpu/drm/i915/gt/selftest_rc6.c             |  45 +-
+ drivers/gpu/drm/i915/gt/selftest_rps.c             | 223 +++++
+ drivers/gpu/drm/i915/gt/selftest_rps.h             |  11 +
+ drivers/gpu/drm/i915/gt/uc/intel_guc.c             |  46 +-
+ drivers/gpu/drm/i915/gt/uc/intel_guc.h             |   7 +
+ drivers/gpu/drm/i915/gt/uc/intel_guc_debugfs.c     |  42 +
+ drivers/gpu/drm/i915/gt/uc/intel_guc_debugfs.h     |  14 +
+ drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c          |  14 -
+ drivers/gpu/drm/i915/gt/uc/intel_guc_fw.h          |   1 -
+ drivers/gpu/drm/i915/gt/uc/intel_guc_log.c         |  97 ++-
+ drivers/gpu/drm/i915/gt/uc/intel_guc_log.h         |   4 +
+ drivers/gpu/drm/i915/gt/uc/intel_guc_log_debugfs.c | 124 +++
+ drivers/gpu/drm/i915/gt/uc/intel_guc_log_debugfs.h |  15 +
+ drivers/gpu/drm/i915/gt/uc/intel_huc.c             |  53 +-
+ drivers/gpu/drm/i915/gt/uc/intel_huc.h             |   2 +
+ drivers/gpu/drm/i915/gt/uc/intel_huc_debugfs.c     |  36 +
+ drivers/gpu/drm/i915/gt/uc/intel_huc_debugfs.h     |  14 +
+ drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c          |  17 -
+ drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h          |   1 -
+ drivers/gpu/drm/i915/gt/uc/intel_uc.c              |  35 +-
+ drivers/gpu/drm/i915/gt/uc/intel_uc.h              |   1 +
+ drivers/gpu/drm/i915/gt/uc/intel_uc_debugfs.c      |  30 +
+ drivers/gpu/drm/i915/gt/uc/intel_uc_debugfs.h      |  14 +
+ drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c           |  56 +-
+ drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h           |   3 +-
+ drivers/gpu/drm/i915/gvt/aperture_gm.c             |   2 +-
+ drivers/gpu/drm/i915/i915_active.c                 | 137 ++-
+ drivers/gpu/drm/i915/i915_active.h                 |  14 +-
+ drivers/gpu/drm/i915/i915_debugfs.c                | 298 +------
+ drivers/gpu/drm/i915/i915_drv.c                    |   4 -
+ drivers/gpu/drm/i915/i915_drv.h                    |   9 +-
+ drivers/gpu/drm/i915/i915_gem.c                    |  20 +-
+ drivers/gpu/drm/i915/i915_gem_evict.c              |   7 +-
+ drivers/gpu/drm/i915/i915_gpu_error.c              |   2 +-
+ drivers/gpu/drm/i915/i915_irq.c                    |   8 +-
+ drivers/gpu/drm/i915/i915_pci.c                    |  23 +-
+ drivers/gpu/drm/i915/i915_perf.c                   | 563 +++++++------
+ drivers/gpu/drm/i915/i915_perf_types.h             |  46 +-
+ drivers/gpu/drm/i915/i915_pmu.c                    |   4 +-
+ drivers/gpu/drm/i915/i915_reg.h                    | 130 ++-
+ drivers/gpu/drm/i915/i915_request.c                |  29 +-
+ drivers/gpu/drm/i915/i915_request.h                |   2 +
+ drivers/gpu/drm/i915/i915_scheduler.c              |  10 +
+ drivers/gpu/drm/i915/i915_sw_fence.c               |   2 +-
+ drivers/gpu/drm/i915/i915_sw_fence_work.c          |   5 +-
+ drivers/gpu/drm/i915/i915_sw_fence_work.h          |  23 +
+ drivers/gpu/drm/i915/i915_switcheroo.c             |   4 +-
+ drivers/gpu/drm/i915/i915_utils.c                  |   3 +-
+ drivers/gpu/drm/i915/i915_vma.c                    |  93 +-
+ drivers/gpu/drm/i915/i915_vma.h                    |   4 +-
+ drivers/gpu/drm/i915/intel_device_info.c           |  41 +-
+ drivers/gpu/drm/i915/intel_device_info.h           |   1 +
+ drivers/gpu/drm/i915/intel_dram.c                  |   3 +-
+ drivers/gpu/drm/i915/intel_pm.c                    |  12 +-
+ drivers/gpu/drm/i915/intel_uncore.c                |  24 +-
+ drivers/gpu/drm/i915/intel_uncore.h                |   6 +-
+ drivers/gpu/drm/i915/intel_wakeref.c               |  12 +-
+ drivers/gpu/drm/i915/intel_wakeref.h               |  22 +-
+ drivers/gpu/drm/i915/intel_wopcm.c                 |  22 +-
+ drivers/gpu/drm/i915/oa/i915_oa_bdw.c              |  90 --
+ drivers/gpu/drm/i915/oa/i915_oa_bdw.h              |  16 -
+ drivers/gpu/drm/i915/oa/i915_oa_bxt.c              |  88 --
+ drivers/gpu/drm/i915/oa/i915_oa_bxt.h              |  16 -
+ drivers/gpu/drm/i915/oa/i915_oa_cflgt2.c           |  89 --
+ drivers/gpu/drm/i915/oa/i915_oa_cflgt2.h           |  16 -
+ drivers/gpu/drm/i915/oa/i915_oa_cflgt3.c           |  89 --
+ drivers/gpu/drm/i915/oa/i915_oa_cflgt3.h           |  16 -
+ drivers/gpu/drm/i915/oa/i915_oa_chv.c              |  89 --
+ drivers/gpu/drm/i915/oa/i915_oa_chv.h              |  16 -
+ drivers/gpu/drm/i915/oa/i915_oa_cnl.c              | 101 ---
+ drivers/gpu/drm/i915/oa/i915_oa_cnl.h              |  16 -
+ drivers/gpu/drm/i915/oa/i915_oa_glk.c              |  88 --
+ drivers/gpu/drm/i915/oa/i915_oa_glk.h              |  16 -
+ drivers/gpu/drm/i915/oa/i915_oa_hsw.c              | 118 ---
+ drivers/gpu/drm/i915/oa/i915_oa_hsw.h              |  16 -
+ drivers/gpu/drm/i915/oa/i915_oa_icl.c              |  98 ---
+ drivers/gpu/drm/i915/oa/i915_oa_icl.h              |  16 -
+ drivers/gpu/drm/i915/oa/i915_oa_kblgt2.c           |  89 --
+ drivers/gpu/drm/i915/oa/i915_oa_kblgt2.h           |  16 -
+ drivers/gpu/drm/i915/oa/i915_oa_kblgt3.c           |  89 --
+ drivers/gpu/drm/i915/oa/i915_oa_kblgt3.h           |  16 -
+ drivers/gpu/drm/i915/oa/i915_oa_sklgt2.c           |  88 --
+ drivers/gpu/drm/i915/oa/i915_oa_sklgt2.h           |  16 -
+ drivers/gpu/drm/i915/oa/i915_oa_sklgt3.c           |  89 --
+ drivers/gpu/drm/i915/oa/i915_oa_sklgt3.h           |  16 -
+ drivers/gpu/drm/i915/oa/i915_oa_sklgt4.c           |  89 --
+ drivers/gpu/drm/i915/oa/i915_oa_sklgt4.h           |  16 -
+ drivers/gpu/drm/i915/oa/i915_oa_tgl.c              | 121 ---
+ drivers/gpu/drm/i915/oa/i915_oa_tgl.h              |  16 -
+ drivers/gpu/drm/i915/selftests/i915_active.c       |  12 +-
+ drivers/gpu/drm/i915/selftests/i915_gem.c          |   2 -
+ drivers/gpu/drm/i915/selftests/i915_gem_evict.c    |  26 +-
+ drivers/gpu/drm/i915/selftests/i915_gem_gtt.c      |   1 -
+ drivers/gpu/drm/i915/selftests/i915_perf.c         |  98 ++-
+ drivers/gpu/drm/i915/selftests/i915_request.c      |  16 +-
+ .../gpu/drm/i915/selftests/intel_memory_region.c   |   5 +-
+ drivers/gpu/drm/i915/selftests/mock_gem_device.c   |   6 +-
+ include/drm/drm_dp_helper.h                        | 170 +++-
+ include/drm/i915_pciids.h                          |   8 +-
+ include/uapi/drm/i915_drm.h                        |  24 +
+ 192 files changed, 5307 insertions(+), 4295 deletions(-)
+ rename drivers/gpu/drm/i915/{i915_gem_fence_reg.c => gt/intel_ggtt_fencing.c} (88%)
+ rename drivers/gpu/drm/i915/{i915_gem_fence_reg.h => gt/intel_ggtt_fencing.h} (86%)
+ create mode 100644 drivers/gpu/drm/i915/gt/selftest_rps.c
+ create mode 100644 drivers/gpu/drm/i915/gt/selftest_rps.h
+ create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_guc_debugfs.c
+ create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_guc_debugfs.h
+ create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_guc_log_debugfs.c
+ create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_guc_log_debugfs.h
+ create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_huc_debugfs.c
+ create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_huc_debugfs.h
+ create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_uc_debugfs.c
+ create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_uc_debugfs.h
+ delete mode 100644 drivers/gpu/drm/i915/oa/i915_oa_bdw.c
+ delete mode 100644 drivers/gpu/drm/i915/oa/i915_oa_bdw.h
+ delete mode 100644 drivers/gpu/drm/i915/oa/i915_oa_bxt.c
+ delete mode 100644 drivers/gpu/drm/i915/oa/i915_oa_bxt.h
+ delete mode 100644 drivers/gpu/drm/i915/oa/i915_oa_cflgt2.c
+ delete mode 100644 drivers/gpu/drm/i915/oa/i915_oa_cflgt2.h
+ delete mode 100644 drivers/gpu/drm/i915/oa/i915_oa_cflgt3.c
+ delete mode 100644 drivers/gpu/drm/i915/oa/i915_oa_cflgt3.h
+ delete mode 100644 drivers/gpu/drm/i915/oa/i915_oa_chv.c
+ delete mode 100644 drivers/gpu/drm/i915/oa/i915_oa_chv.h
+ delete mode 100644 drivers/gpu/drm/i915/oa/i915_oa_cnl.c
+ delete mode 100644 drivers/gpu/drm/i915/oa/i915_oa_cnl.h
+ delete mode 100644 drivers/gpu/drm/i915/oa/i915_oa_glk.c
+ delete mode 100644 drivers/gpu/drm/i915/oa/i915_oa_glk.h
+ delete mode 100644 drivers/gpu/drm/i915/oa/i915_oa_hsw.c
+ delete mode 100644 drivers/gpu/drm/i915/oa/i915_oa_hsw.h
+ delete mode 100644 drivers/gpu/drm/i915/oa/i915_oa_icl.c
+ delete mode 100644 drivers/gpu/drm/i915/oa/i915_oa_icl.h
+ delete mode 100644 drivers/gpu/drm/i915/oa/i915_oa_kblgt2.c
+ delete mode 100644 drivers/gpu/drm/i915/oa/i915_oa_kblgt2.h
+ delete mode 100644 drivers/gpu/drm/i915/oa/i915_oa_kblgt3.c
+ delete mode 100644 drivers/gpu/drm/i915/oa/i915_oa_kblgt3.h
+ delete mode 100644 drivers/gpu/drm/i915/oa/i915_oa_sklgt2.c
+ delete mode 100644 drivers/gpu/drm/i915/oa/i915_oa_sklgt2.h
+ delete mode 100644 drivers/gpu/drm/i915/oa/i915_oa_sklgt3.c
+ delete mode 100644 drivers/gpu/drm/i915/oa/i915_oa_sklgt3.h
+ delete mode 100644 drivers/gpu/drm/i915/oa/i915_oa_sklgt4.c
+ delete mode 100644 drivers/gpu/drm/i915/oa/i915_oa_sklgt4.h
+ delete mode 100644 drivers/gpu/drm/i915/oa/i915_oa_tgl.c
+ delete mode 100644 drivers/gpu/drm/i915/oa/i915_oa_tgl.h
+Merging drm-tegra/drm/tegra/for-next (e32c8c2a5fbe drm/tegra: hdmi: Silence deferred-probe error)
+$ git merge drm-tegra/drm/tegra/for-next
+Already up to date.
+Merging drm-misc/for-linux-next (13e3d94110d8 drm: Don't free a struct never allocated by drm_gem_fb_init())
+$ git merge drm-misc/for-linux-next
+Auto-merging mm/slub.c
+Removing include/drm/drm_pci.h
+Auto-merging include/drm/drm_legacy.h
+Auto-merging include/drm/drm_file.h
+Auto-merging include/drm/drm_dp_mst_helper.h
+Auto-merging drivers/gpu/drm/xen/xen_drm_front.c
+Auto-merging drivers/gpu/drm/virtio/virtgpu_object.c
+Auto-merging drivers/gpu/drm/vc4/vc4_hdmi.c
+Auto-merging drivers/gpu/drm/vboxvideo/vbox_drv.c
+Auto-merging drivers/gpu/drm/ttm/ttm_bo.c
+Auto-merging drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+Auto-merging drivers/gpu/drm/panel/panel-simple.c
+Auto-merging drivers/gpu/drm/nouveau/nouveau_debugfs.c
+Auto-merging drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
+Auto-merging drivers/gpu/drm/mediatek/mtk_dsi.c
+Auto-merging drivers/gpu/drm/mediatek/mtk_drm_drv.c
+Auto-merging drivers/gpu/drm/mediatek/mtk_dpi.c
+Auto-merging drivers/gpu/drm/i915/selftests/mock_gem_device.c
+Auto-merging drivers/gpu/drm/i915/i915_drv.h
+Auto-merging drivers/gpu/drm/i915/i915_drv.c
+Auto-merging drivers/gpu/drm/i915/i915_debugfs.c
+Auto-merging drivers/gpu/drm/i915/display/intel_dp_mst.c
+CONFLICT (content): Merge conflict in drivers/gpu/drm/i915/display/intel_dp_mst.c
+Auto-merging drivers/gpu/drm/i915/display/intel_display_types.h
+Auto-merging drivers/gpu/drm/i915/display/intel_display_debugfs.c
+Auto-merging drivers/gpu/drm/exynos/exynos_dp.c
+Removing drivers/gpu/drm/drm_vram_helper_common.c
+Auto-merging drivers/gpu/drm/drm_dp_mst_topology.c
+Auto-merging drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+Auto-merging drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+Auto-merging drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
+Auto-merging drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+Auto-merging MAINTAINERS
+CONFLICT (content): Merge conflict in MAINTAINERS
+Removing Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt
+Removing Documentation/devicetree/bindings/display/panel/tpo,td043mtea1.txt
+Removing Documentation/devicetree/bindings/display/panel/tpo,td028ttec1.txt
+Removing Documentation/devicetree/bindings/display/panel/startek,startek-kd050c.txt
+Removing Documentation/devicetree/bindings/display/panel/sony,acx565akm.txt
+Removing Documentation/devicetree/bindings/display/panel/sitronix,st7789v.txt
+Removing Documentation/devicetree/bindings/display/panel/sitronix,st7701.txt
+Removing Documentation/devicetree/bindings/display/panel/simple-panel.txt
+Removing Documentation/devicetree/bindings/display/panel/sharp,ls043t1le01.txt
+Removing Documentation/devicetree/bindings/display/panel/sharp,ls037v7dw01.txt
+Removing Documentation/devicetree/bindings/display/panel/sharp,lq150x1lg11.txt
+Removing Documentation/devicetree/bindings/display/panel/seiko,43wvf1g.txt
+Removing Documentation/devicetree/bindings/display/panel/samsung,s6e63m0.txt
+Removing Documentation/devicetree/bindings/display/panel/samsung,s6e63j0x03.txt
+Removing Documentation/devicetree/bindings/display/panel/samsung,s6e3ha2.txt
+Removing Documentation/devicetree/bindings/display/panel/samsung,s6d16d0.txt
+Removing Documentation/devicetree/bindings/display/panel/samsung,ld9040.txt
+Removing Documentation/devicetree/bindings/display/panel/raydium,rm67191.txt
+Removing Documentation/devicetree/bindings/display/panel/osddisplays,osd101t2587-53ts.txt
+Removing Documentation/devicetree/bindings/display/panel/olimex,lcd-olinuxino.txt
+Removing Documentation/devicetree/bindings/display/panel/lgphilips,lb035q02.txt
+Removing Documentation/devicetree/bindings/display/panel/lg,lh500wx1-sd03.txt
+Removing Documentation/devicetree/bindings/display/panel/lg,lg4573.txt
+Removing Documentation/devicetree/bindings/display/panel/lg,ld070wx3-sl01.txt
+Removing Documentation/devicetree/bindings/display/panel/lg,acx467akm-7.txt
+Removing Documentation/devicetree/bindings/display/panel/kingdisplay,kd097d04.txt
+Removing Documentation/devicetree/bindings/display/panel/kingdisplay,kd035g6-54nt.txt
+Removing Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt
+Removing Documentation/devicetree/bindings/display/panel/innolux,p120zdg-bf1.txt
+Removing Documentation/devicetree/bindings/display/panel/innolux,p097pfg.txt
+Removing Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.txt
+Removing Documentation/devicetree/bindings/display/panel/ilitek,ili9322.txt
+Removing Documentation/devicetree/bindings/display/panel/feiyang,fy07024di26a30d.txt
+Removing Documentation/devicetree/bindings/display/panel/boe,himax8279d.txt
+Removing Documentation/devicetree/bindings/display/panel/arm,versatile-tft-panel.txt
+Resolved 'MAINTAINERS' using previous resolution.
+Resolved 'drivers/gpu/drm/i915/display/intel_dp_mst.c' using previous resolution.
+Automatic merge failed; fix conflicts and then commit the result.
+$ git commit --no-edit -v -a
+[master 01677d197691] Merge remote-tracking branch 'drm-misc/for-linux-next'
+$ git diff -M --stat --summary HEAD^..
+ .../display/allwinner,sun6i-a31-mipi-dsi.yaml      |    2 +-
+ .../bindings/display/bridge/nwl-dsi.yaml           |  226 ++++
+ .../bindings/display/dsi-controller.yaml           |    4 +-
+ .../display/panel/arm,versatile-tft-panel.txt      |   31 -
+ .../display/panel/arm,versatile-tft-panel.yaml     |   54 +
+ .../bindings/display/panel/boe,himax8279d.txt      |   24 -
+ .../bindings/display/panel/boe,himax8279d.yaml     |   59 +
+ .../bindings/display/panel/boe,tv101wum-nl6.yaml   |    2 +
+ .../bindings/display/panel/display-timings.yaml    |    8 +-
+ .../display/panel/feiyang,fy07024di26a30d.txt      |   20 -
+ .../display/panel/feiyang,fy07024di26a30d.yaml     |   58 +
+ .../bindings/display/panel/ilitek,ili9322.txt      |   49 -
+ .../bindings/display/panel/ilitek,ili9322.yaml     |   71 ++
+ .../bindings/display/panel/ilitek,ili9881c.txt     |   20 -
+ .../bindings/display/panel/ilitek,ili9881c.yaml    |   50 +
+ .../bindings/display/panel/innolux,p097pfg.txt     |   24 -
+ .../bindings/display/panel/innolux,p097pfg.yaml    |   56 +
+ .../bindings/display/panel/innolux,p120zdg-bf1.txt |   22 -
+ .../display/panel/innolux,p120zdg-bf1.yaml         |   43 +
+ .../bindings/display/panel/jdi,lt070me05000.txt    |   31 -
+ .../bindings/display/panel/jdi,lt070me05000.yaml   |   69 ++
+ .../display/panel/kingdisplay,kd035g6-54nt.txt     |   42 -
+ .../display/panel/kingdisplay,kd035g6-54nt.yaml    |   65 ++
+ .../display/panel/kingdisplay,kd097d04.txt         |   22 -
+ .../display/panel/leadtek,ltk050h3146w.yaml        |   51 +
+ .../bindings/display/panel/lg,acx467akm-7.txt      |    7 -
+ .../bindings/display/panel/lg,ld070wx3-sl01.txt    |    7 -
+ .../bindings/display/panel/lg,lg4573.txt           |   19 -
+ .../bindings/display/panel/lg,lg4573.yaml          |   45 +
+ .../bindings/display/panel/lg,lh500wx1-sd03.txt    |    7 -
+ .../bindings/display/panel/lgphilips,lb035q02.txt  |   33 -
+ .../bindings/display/panel/lgphilips,lb035q02.yaml |   59 +
+ .../display/panel/olimex,lcd-olinuxino.txt         |   42 -
+ .../display/panel/olimex,lcd-olinuxino.yaml        |   70 ++
+ .../display/panel/osddisplays,osd101t2587-53ts.txt |   14 -
+ .../bindings/display/panel/panel-common.yaml       |   11 +-
+ .../bindings/display/panel/panel-simple-dsi.yaml   |   12 +
+ .../bindings/display/panel/panel-simple.yaml       |    8 +-
+ .../bindings/display/panel/raydium,rm67191.txt     |   41 -
+ .../bindings/display/panel/raydium,rm67191.yaml    |   75 ++
+ .../display/panel/samsung,amoled-mipi-dsi.yaml     |   65 ++
+ .../bindings/display/panel/samsung,ld9040.txt      |   66 --
+ .../bindings/display/panel/samsung,ld9040.yaml     |  107 ++
+ .../bindings/display/panel/samsung,s6d16d0.txt     |   30 -
+ .../bindings/display/panel/samsung,s6d16d0.yaml    |   56 +
+ .../bindings/display/panel/samsung,s6e3ha2.txt     |   31 -
+ .../bindings/display/panel/samsung,s6e63j0x03.txt  |   24 -
+ .../bindings/display/panel/samsung,s6e63m0.txt     |   33 -
+ .../bindings/display/panel/samsung,s6e63m0.yaml    |   60 +
+ .../bindings/display/panel/seiko,43wvf1g.txt       |   23 -
+ .../bindings/display/panel/seiko,43wvf1g.yaml      |   50 +
+ .../bindings/display/panel/sharp,lq150x1lg11.txt   |   36 -
+ .../bindings/display/panel/sharp,lq150x1lg11.yaml  |   58 +
+ .../bindings/display/panel/sharp,ls037v7dw01.txt   |   43 -
+ .../bindings/display/panel/sharp,ls037v7dw01.yaml  |   68 ++
+ .../bindings/display/panel/sharp,ls043t1le01.txt   |   22 -
+ .../bindings/display/panel/sharp,ls043t1le01.yaml  |   51 +
+ .../bindings/display/panel/simple-panel.txt        |    1 -
+ .../bindings/display/panel/sitronix,st7701.txt     |   30 -
+ .../bindings/display/panel/sitronix,st7701.yaml    |   69 ++
+ .../bindings/display/panel/sitronix,st7789v.txt    |   37 -
+ .../bindings/display/panel/sitronix,st7789v.yaml   |   63 +
+ .../bindings/display/panel/sony,acx565akm.txt      |   30 -
+ .../bindings/display/panel/sony,acx565akm.yaml     |   57 +
+ .../display/panel/startek,startek-kd050c.txt       |    4 -
+ .../display/panel/startek,startek-kd050c.yaml      |   33 +
+ .../devicetree/bindings/display/panel/tpo,td.yaml  |   65 ++
+ .../bindings/display/panel/tpo,td028ttec1.txt      |   32 -
+ .../bindings/display/panel/tpo,td043mtea1.txt      |   33 -
+ .../bindings/display/panel/visionox,rm69299.yaml   |   57 +
+ .../bindings/display/rockchip/rockchip-vop.txt     |   74 --
+ .../bindings/display/rockchip/rockchip-vop.yaml    |  134 +++
+ Documentation/gpu/drm-internals.rst                |   12 +
+ Documentation/gpu/drm-kms.rst                      |    5 +-
+ Documentation/gpu/drm-mm.rst                       |    9 -
+ MAINTAINERS                                        |   14 +-
+ drivers/dma-buf/Makefile                           |    3 +-
+ drivers/dma-buf/dma-buf.c                          |    2 +
+ drivers/dma-buf/dma-fence-chain.c                  |   10 +-
+ drivers/dma-buf/selftests.h                        |    1 +
+ drivers/dma-buf/st-dma-fence-chain.c               |  715 ++++++++++++
+ drivers/gpu/drm/Makefile                           |    6 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c        |   61 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c            |    2 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c            |    4 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h            |   12 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c       |   99 ++
+ .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c    |   45 +-
+ drivers/gpu/drm/arc/arcpgu_drv.c                   |    7 +-
+ drivers/gpu/drm/arm/display/komeda/komeda_kms.c    |    2 +
+ drivers/gpu/drm/arm/hdlcd_drv.c                    |    7 +-
+ drivers/gpu/drm/arm/malidp_drv.c                   |    3 +-
+ drivers/gpu/drm/armada/armada_drv.c                |    2 +
+ drivers/gpu/drm/ast/ast_drv.c                      |    3 +
+ drivers/gpu/drm/ast/ast_main.c                     |    5 -
+ drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_output.c   |   12 +-
+ drivers/gpu/drm/bochs/bochs.h                      |    1 -
+ drivers/gpu/drm/bochs/bochs_drv.c                  |    6 +-
+ drivers/gpu/drm/bochs/bochs_kms.c                  |   15 +-
+ drivers/gpu/drm/bridge/Kconfig                     |   16 +
+ drivers/gpu/drm/bridge/Makefile                    |    1 +
+ drivers/gpu/drm/bridge/adv7511/adv7511_audio.c     |   26 +-
+ drivers/gpu/drm/bridge/nwl-dsi.c                   | 1213 ++++++++++++++++++++
+ drivers/gpu/drm/bridge/nwl-dsi.h                   |  144 +++
+ drivers/gpu/drm/bridge/panel.c                     |    1 +
+ drivers/gpu/drm/bridge/sii9234.c                   |    3 +-
+ drivers/gpu/drm/bridge/synopsys/dw-hdmi.c          |   86 +-
+ drivers/gpu/drm/cirrus/cirrus.c                    |   74 +-
+ drivers/gpu/drm/drm_atomic.c                       |    8 +-
+ drivers/gpu/drm/drm_auth.c                         |   69 +-
+ drivers/gpu/drm/drm_blend.c                        |    6 +
+ drivers/gpu/drm/drm_bufs.c                         |    2 +-
+ drivers/gpu/drm/drm_client.c                       |    8 +-
+ drivers/gpu/drm/drm_connector.c                    |    6 +-
+ drivers/gpu/drm/drm_crtc_internal.h                |    4 +-
+ drivers/gpu/drm/drm_debugfs.c                      |   45 +-
+ drivers/gpu/drm/drm_dma.c                          |    2 +-
+ drivers/gpu/drm/drm_dp_mst_topology.c              |  307 ++---
+ drivers/gpu/drm/drm_drv.c                          |  219 ++--
+ drivers/gpu/drm/drm_edid.c                         |  103 +-
+ drivers/gpu/drm/drm_fb_helper.c                    |   31 +-
+ drivers/gpu/drm/drm_framebuffer.c                  |    8 +-
+ drivers/gpu/drm/drm_gem.c                          |   23 +-
+ drivers/gpu/drm/drm_gem_framebuffer_helper.c       |  224 +++-
+ drivers/gpu/drm/drm_gem_vram_helper.c              |  124 +-
+ drivers/gpu/drm/drm_internal.h                     |    7 +-
+ drivers/gpu/drm/drm_ioctl.c                        |    4 +-
+ drivers/gpu/drm/drm_managed.c                      |  275 +++++
+ drivers/gpu/drm/drm_mipi_dbi.c                     |   33 +-
+ drivers/gpu/drm/drm_mode_config.c                  |  110 +-
+ drivers/gpu/drm/drm_pci.c                          |    4 +-
+ drivers/gpu/drm/drm_vblank.c                       |   94 +-
+ drivers/gpu/drm/drm_vm.c                           |    4 +-
+ drivers/gpu/drm/drm_vram_helper_common.c           |   94 --
+ drivers/gpu/drm/etnaviv/etnaviv_drv.c              |   18 +-
+ drivers/gpu/drm/exynos/exynos_dp.c                 |    8 +-
+ drivers/gpu/drm/exynos/exynos_drm_dpi.c            |    8 +-
+ drivers/gpu/drm/exynos/exynos_drm_dsi.c            |    8 +-
+ drivers/gpu/drm/exynos/exynos_drm_vidi.c           |    8 +-
+ drivers/gpu/drm/exynos/exynos_hdmi.c               |    8 +-
+ drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c          |   14 +-
+ drivers/gpu/drm/gma500/cdv_intel_crt.c             |   14 +-
+ drivers/gpu/drm/gma500/cdv_intel_dp.c              |   16 +-
+ drivers/gpu/drm/gma500/cdv_intel_hdmi.c            |    4 +-
+ drivers/gpu/drm/gma500/cdv_intel_lvds.c            |   17 +-
+ drivers/gpu/drm/gma500/framebuffer.c               |   16 +-
+ drivers/gpu/drm/gma500/mdfld_dsi_dpi.c             |   11 +-
+ drivers/gpu/drm/gma500/mdfld_output.h              |    1 -
+ drivers/gpu/drm/gma500/mdfld_tmd_vid.c             |    6 -
+ drivers/gpu/drm/gma500/mdfld_tpo_vid.c             |    6 -
+ drivers/gpu/drm/gma500/oaktrail_hdmi.c             |   14 +-
+ drivers/gpu/drm/gma500/oaktrail_lvds.c             |    5 +-
+ drivers/gpu/drm/gma500/psb_intel_drv.h             |    1 -
+ drivers/gpu/drm/gma500/psb_intel_lvds.c            |   18 +-
+ drivers/gpu/drm/gma500/tc35876x-dsi-lvds.c         |   13 +-
+ drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c     |    9 +-
+ drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c    |    8 +-
+ drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c        |    2 +-
+ drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c       |    9 +-
+ drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c    |    1 -
+ drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c    |   43 -
+ drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.h    |    1 -
+ drivers/gpu/drm/i2c/sil164_drv.c                   |    7 +-
+ drivers/gpu/drm/i2c/tda998x_drv.c                  |   20 +-
+ .../gpu/drm/i915/display/intel_display_debugfs.c   |   18 +-
+ .../gpu/drm/i915/display/intel_display_debugfs.h   |    4 +-
+ drivers/gpu/drm/i915/display/intel_display_types.h |    2 +-
+ drivers/gpu/drm/i915/display/intel_dp_mst.c        |    4 +-
+ drivers/gpu/drm/i915/gem/i915_gem_phys.c           |    2 -
+ drivers/gpu/drm/i915/i915_debugfs.c                |    8 +-
+ drivers/gpu/drm/i915/i915_debugfs.h                |    4 +-
+ drivers/gpu/drm/i915/i915_drv.c                    |   22 +-
+ drivers/gpu/drm/i915/i915_drv.h                    |    3 +
+ drivers/gpu/drm/i915/selftests/mock_gem_device.c   |   32 +-
+ drivers/gpu/drm/imx/dw_hdmi-imx.c                  |    8 +-
+ drivers/gpu/drm/imx/imx-drm-core.c                 |   10 +-
+ drivers/gpu/drm/imx/imx-drm.h                      |    1 -
+ drivers/gpu/drm/imx/imx-ldb.c                      |    8 +-
+ drivers/gpu/drm/imx/imx-tve.c                      |    8 +-
+ drivers/gpu/drm/imx/parallel-display.c             |    8 +-
+ drivers/gpu/drm/ingenic/ingenic-drm.c              |   34 +-
+ drivers/gpu/drm/lima/Kconfig                       |    2 +
+ drivers/gpu/drm/lima/Makefile                      |    4 +-
+ drivers/gpu/drm/lima/lima_ctx.c                    |    3 +
+ drivers/gpu/drm/lima/lima_ctx.h                    |    5 +
+ drivers/gpu/drm/lima/lima_devfreq.c                |  234 ++++
+ drivers/gpu/drm/lima/lima_devfreq.h                |   41 +
+ drivers/gpu/drm/lima/lima_device.c                 |   17 +
+ drivers/gpu/drm/lima/lima_device.h                 |   11 +
+ drivers/gpu/drm/lima/lima_drv.c                    |  112 +-
+ drivers/gpu/drm/lima/lima_drv.h                    |    1 +
+ drivers/gpu/drm/lima/lima_dump.h                   |   77 ++
+ drivers/gpu/drm/lima/lima_sched.c                  |  142 ++-
+ drivers/gpu/drm/lima/lima_sched.h                  |   11 +
+ drivers/gpu/drm/lima/lima_trace.c                  |    7 +
+ drivers/gpu/drm/lima/lima_trace.h                  |   50 +
+ drivers/gpu/drm/mcde/mcde_drv.c                    |   35 +-
+ drivers/gpu/drm/mediatek/mtk_dpi.c                 |   14 +-
+ drivers/gpu/drm/mediatek/mtk_drm_drv.c             |   13 +-
+ drivers/gpu/drm/mediatek/mtk_dsi.c                 |   14 +-
+ drivers/gpu/drm/meson/meson_drv.c                  |    5 +-
+ drivers/gpu/drm/mgag200/mgag200_drv.c              |    2 +
+ drivers/gpu/drm/mgag200/mgag200_main.c             |    4 -
+ drivers/gpu/drm/msm/adreno/a5xx_debugfs.c          |   18 +-
+ drivers/gpu/drm/msm/adreno/a5xx_gpu.h              |    2 +-
+ drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c           |   14 +-
+ drivers/gpu/drm/msm/msm_debugfs.c                  |   23 +-
+ drivers/gpu/drm/msm/msm_debugfs.h                  |    2 +-
+ drivers/gpu/drm/msm/msm_gpu.h                      |    2 +-
+ drivers/gpu/drm/nouveau/nouveau_debugfs.c          |    6 +-
+ drivers/gpu/drm/nouveau/nouveau_debugfs.h          |    8 +-
+ drivers/gpu/drm/nouveau/nvkm/subdev/therm/ic.c     |    4 +-
+ drivers/gpu/drm/omapdrm/omap_debugfs.c             |   29 +-
+ drivers/gpu/drm/omapdrm/omap_drv.h                 |    2 +-
+ drivers/gpu/drm/panel/Kconfig                      |   11 +
+ drivers/gpu/drm/panel/Makefile                     |    1 +
+ drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c     |   31 +
+ drivers/gpu/drm/panel/panel-leadtek-ltk050h3146w.c |  691 +++++++++++
+ drivers/gpu/drm/panel/panel-leadtek-ltk500hd1829.c |    2 +-
+ drivers/gpu/drm/panel/panel-novatek-nt39016.c      |   46 +-
+ drivers/gpu/drm/panel/panel-simple.c               |   29 +
+ drivers/gpu/drm/pl111/pl111_debugfs.c              |    8 +-
+ drivers/gpu/drm/pl111/pl111_drm.h                  |    2 +-
+ drivers/gpu/drm/pl111/pl111_drv.c                  |   12 +-
+ drivers/gpu/drm/qxl/qxl_debugfs.c                  |   21 +-
+ drivers/gpu/drm/qxl/qxl_drv.c                      |    2 -
+ drivers/gpu/drm/qxl/qxl_drv.h                      |   13 +-
+ drivers/gpu/drm/qxl/qxl_kms.c                      |    4 +-
+ drivers/gpu/drm/qxl/qxl_ttm.c                      |    6 +-
+ drivers/gpu/drm/r128/ati_pcigart.c                 |    3 +-
+ drivers/gpu/drm/radeon/radeon_atombios.c           |    4 +-
+ drivers/gpu/drm/radeon/radeon_combios.c            |    4 +-
+ drivers/gpu/drm/radeon/radeon_drv.c                |    2 +-
+ drivers/gpu/drm/rcar-du/rcar_du_drv.c              |    1 -
+ drivers/gpu/drm/rcar-du/rcar_du_encoder.c          |   14 +-
+ drivers/gpu/drm/rcar-du/rcar_du_kms.c              |    4 +-
+ drivers/gpu/drm/rockchip/analogix_dp-rockchip.c    |    9 +-
+ drivers/gpu/drm/rockchip/cdn-dp-core.c             |    9 +-
+ drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c    |    8 +-
+ drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c        |    8 +-
+ drivers/gpu/drm/rockchip/inno_hdmi.c               |    8 +-
+ drivers/gpu/drm/rockchip/rk3066_hdmi.c             |    8 +-
+ drivers/gpu/drm/rockchip/rockchip_drm_drv.c        |   14 +-
+ drivers/gpu/drm/rockchip/rockchip_drm_drv.h        |    1 +
+ drivers/gpu/drm/rockchip/rockchip_drm_fb.c         |   43 +-
+ drivers/gpu/drm/rockchip/rockchip_drm_vop.c        |  137 ++-
+ drivers/gpu/drm/rockchip/rockchip_drm_vop.h        |   17 +
+ drivers/gpu/drm/rockchip/rockchip_lvds.c           |   10 +-
+ drivers/gpu/drm/rockchip/rockchip_rgb.c            |    8 +-
+ drivers/gpu/drm/rockchip/rockchip_vop_reg.c        |   83 +-
+ drivers/gpu/drm/shmobile/shmob_drm_crtc.c          |   14 +-
+ drivers/gpu/drm/shmobile/shmob_drm_drv.c           |    2 -
+ drivers/gpu/drm/shmobile/shmob_drm_kms.c           |    6 +-
+ drivers/gpu/drm/sti/sti_compositor.c               |    6 +-
+ drivers/gpu/drm/sti/sti_compositor.h               |    4 +-
+ drivers/gpu/drm/sti/sti_crtc.c                     |    2 +-
+ drivers/gpu/drm/sti/sti_cursor.c                   |   14 +-
+ drivers/gpu/drm/sti/sti_drv.c                      |   16 +-
+ drivers/gpu/drm/sti/sti_dvo.c                      |   13 +-
+ drivers/gpu/drm/sti/sti_gdp.c                      |    7 +-
+ drivers/gpu/drm/sti/sti_hda.c                      |   13 +-
+ drivers/gpu/drm/sti/sti_hdmi.c                     |   13 +-
+ drivers/gpu/drm/sti/sti_hqvdp.c                    |   12 +-
+ drivers/gpu/drm/sti/sti_mixer.c                    |   10 +-
+ drivers/gpu/drm/sti/sti_mixer.h                    |    2 +-
+ drivers/gpu/drm/sti/sti_tvout.c                    |   13 +-
+ drivers/gpu/drm/sti/sti_vid.c                      |    8 +-
+ drivers/gpu/drm/sti/sti_vid.h                      |    2 +-
+ drivers/gpu/drm/stm/drv.c                          |   10 +-
+ drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c             |   12 +-
+ drivers/gpu/drm/sun4i/sun4i_lvds.c                 |   12 +-
+ drivers/gpu/drm/sun4i/sun4i_rgb.c                  |   17 +-
+ drivers/gpu/drm/sun4i/sun4i_tcon.c                 |    4 +-
+ drivers/gpu/drm/sun4i/sun4i_tv.c                   |   17 +-
+ drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c             |   12 +-
+ drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c              |    8 +-
+ drivers/gpu/drm/sun4i/sun8i_mixer.c                |  111 +-
+ drivers/gpu/drm/sun4i/sun8i_mixer.h                |   10 +-
+ drivers/gpu/drm/sun4i/sun8i_ui_layer.c             |   14 +-
+ drivers/gpu/drm/sun4i/sun8i_vi_layer.c             |   40 +-
+ drivers/gpu/drm/tegra/dc.c                         |   11 +-
+ drivers/gpu/drm/tegra/drm.c                        |    8 +-
+ drivers/gpu/drm/tegra/drm.h                        |    2 -
+ drivers/gpu/drm/tegra/dsi.c                        |   21 +-
+ drivers/gpu/drm/tegra/hdmi.c                       |   20 +-
+ drivers/gpu/drm/tegra/output.c                     |    6 +-
+ drivers/gpu/drm/tegra/rgb.c                        |    8 +-
+ drivers/gpu/drm/tegra/sor.c                        |   19 +-
+ drivers/gpu/drm/tidss/tidss_drv.c                  |   10 +-
+ drivers/gpu/drm/tidss/tidss_encoder.c              |   10 +-
+ drivers/gpu/drm/tidss/tidss_kms.c                  |   19 +-
+ drivers/gpu/drm/tidss/tidss_kms.h                  |    1 -
+ drivers/gpu/drm/tilcdc/tilcdc_drv.c                |   20 +-
+ drivers/gpu/drm/tilcdc/tilcdc_external.c           |   10 +-
+ drivers/gpu/drm/tilcdc/tilcdc_panel.c              |    8 +-
+ drivers/gpu/drm/tiny/gm12u320.c                    |  226 ++--
+ drivers/gpu/drm/tiny/hx8357d.c                     |    5 +-
+ drivers/gpu/drm/tiny/ili9225.c                     |    5 +-
+ drivers/gpu/drm/tiny/ili9341.c                     |    5 +-
+ drivers/gpu/drm/tiny/ili9486.c                     |    5 +-
+ drivers/gpu/drm/tiny/mi0283qt.c                    |    5 +-
+ drivers/gpu/drm/tiny/repaper.c                     |   18 +-
+ drivers/gpu/drm/tiny/st7586.c                      |    5 +-
+ drivers/gpu/drm/tiny/st7735r.c                     |    5 +-
+ drivers/gpu/drm/ttm/ttm_bo.c                       |    4 +-
+ drivers/gpu/drm/udl/udl_drv.c                      |   22 +-
+ drivers/gpu/drm/udl/udl_drv.h                      |    2 -
+ drivers/gpu/drm/udl/udl_main.c                     |   10 -
+ drivers/gpu/drm/udl/udl_modeset.c                  |   21 +-
+ drivers/gpu/drm/v3d/v3d_debugfs.c                  |    8 +-
+ drivers/gpu/drm/v3d/v3d_drv.c                      |   38 +-
+ drivers/gpu/drm/v3d/v3d_drv.h                      |    2 +-
+ drivers/gpu/drm/vboxvideo/vbox_drv.c               |    8 +-
+ drivers/gpu/drm/vc4/vc4_debugfs.c                  |   11 +-
+ drivers/gpu/drm/vc4/vc4_dpi.c                      |    8 +-
+ drivers/gpu/drm/vc4/vc4_drv.h                      |    2 +-
+ drivers/gpu/drm/vc4/vc4_dsi.c                      |   15 +-
+ drivers/gpu/drm/vc4/vc4_hdmi.c                     |   17 +-
+ drivers/gpu/drm/vc4/vc4_vec.c                      |    8 +-
+ drivers/gpu/drm/vgem/vgem_drv.c                    |   15 +-
+ drivers/gpu/drm/virtio/virtgpu_debugfs.c           |    3 +-
+ drivers/gpu/drm/virtio/virtgpu_display.c           |    8 +-
+ drivers/gpu/drm/virtio/virtgpu_drv.h               |   36 +-
+ drivers/gpu/drm/virtio/virtgpu_gem.c               |   13 +-
+ drivers/gpu/drm/virtio/virtgpu_ioctl.c             |    1 -
+ drivers/gpu/drm/virtio/virtgpu_object.c            |    7 +-
+ drivers/gpu/drm/virtio/virtgpu_vq.c                |    9 +-
+ drivers/gpu/drm/vkms/vkms_drv.c                    |   19 +-
+ drivers/gpu/drm/vkms/vkms_output.c                 |    8 +-
+ drivers/gpu/drm/xen/xen_drm_front.c                |    4 +-
+ drivers/gpu/drm/zte/zx_hdmi.c                      |    8 +-
+ drivers/gpu/drm/zte/zx_tvenc.c                     |    8 +-
+ drivers/gpu/drm/zte/zx_vga.c                       |    8 +-
+ drivers/video/fbdev/atmel_lcdfb.c                  |    1 -
+ drivers/video/fbdev/aty/atyfb_base.c               |    2 +-
+ drivers/video/fbdev/core/fbmon.c                   |    2 +-
+ drivers/video/fbdev/cyber2000fb.c                  |    2 +
+ drivers/video/fbdev/matrox/g450_pll.c              |   22 -
+ drivers/video/fbdev/matrox/matroxfb_base.h         |    2 +-
+ drivers/video/fbdev/mb862xx/mb862xxfb_accel.c      |    2 -
+ drivers/video/fbdev/mx3fb.c                        |   20 +-
+ drivers/video/fbdev/omap/omapfb_main.c             |   14 +-
+ drivers/video/fbdev/omap2/omapfb/dss/dispc.c       |  114 --
+ drivers/video/fbdev/omap2/omapfb/dss/dss.h         |   20 -
+ drivers/video/fbdev/omap2/omapfb/omapfb-sysfs.c    |    8 +-
+ drivers/video/fbdev/pm2fb.c                        |    2 +-
+ drivers/video/fbdev/pm3fb.c                        |    8 +-
+ drivers/video/fbdev/savage/savagefb.h              |    2 +-
+ drivers/video/fbdev/uvesafb.c                      |    2 +-
+ drivers/video/fbdev/via/debug.h                    |    6 +-
+ drivers/video/fbdev/via/viafbdev.c                 |    2 +-
+ include/drm/drm_client.h                           |    2 +-
+ include/drm/drm_connector.h                        |    4 +-
+ include/drm/drm_debugfs.h                          |   16 +-
+ include/drm/drm_device.h                           |   24 +-
+ include/drm/drm_displayid.h                        |    2 +-
+ include/drm/drm_dp_mst_helper.h                    |   72 +-
+ include/drm/drm_drv.h                              |   11 +-
+ include/drm/drm_encoder.h                          |    8 +-
+ include/drm/drm_fb_helper.h                        |    6 +-
+ include/drm/drm_file.h                             |   11 +
+ include/drm/drm_framebuffer.h                      |   38 +
+ include/drm/drm_gem_framebuffer_helper.h           |   15 +
+ include/drm/drm_gem_vram_helper.h                  |    2 +-
+ include/drm/drm_legacy.h                           |   15 +
+ include/drm/drm_managed.h                          |  109 ++
+ include/drm/drm_mipi_dbi.h                         |    8 +-
+ include/drm/drm_mode_config.h                      |   18 +-
+ include/drm/drm_modeset_helper_vtables.h           |   27 +
+ include/drm/drm_pci.h                              |   63 -
+ include/drm/drm_print.h                            |    6 +
+ include/drm/drm_writeback.h                        |    9 +
+ include/drm/gpu_scheduler.h                        |    1 +
+ include/linux/dma-buf.h                            |   10 +
+ mm/slob.c                                          |    2 +
+ mm/slub.c                                          |    2 +
+ 376 files changed, 8568 insertions(+), 3557 deletions(-)
+ create mode 100644 Documentation/devicetree/bindings/display/bridge/nwl-dsi.yaml
+ delete mode 100644 Documentation/devicetree/bindings/display/panel/arm,versatile-tft-panel.txt
+ create mode 100644 Documentation/devicetree/bindings/display/panel/arm,versatile-tft-panel.yaml
+ delete mode 100644 Documentation/devicetree/bindings/display/panel/boe,himax8279d.txt
+ create mode 100644 Documentation/devicetree/bindings/display/panel/boe,himax8279d.yaml
+ delete mode 100644 Documentation/devicetree/bindings/display/panel/feiyang,fy07024di26a30d.txt
+ create mode 100644 Documentation/devicetree/bindings/display/panel/feiyang,fy07024di26a30d.yaml
+ delete mode 100644 Documentation/devicetree/bindings/display/panel/ilitek,ili9322.txt
+ create mode 100644 Documentation/devicetree/bindings/display/panel/ilitek,ili9322.yaml
+ delete mode 100644 Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.txt
+ create mode 100644 Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml
+ delete mode 100644 Documentation/devicetree/bindings/display/panel/innolux,p097pfg.txt
+ create mode 100644 Documentation/devicetree/bindings/display/panel/innolux,p097pfg.yaml
+ delete mode 100644 Documentation/devicetree/bindings/display/panel/innolux,p120zdg-bf1.txt
+ create mode 100644 Documentation/devicetree/bindings/display/panel/innolux,p120zdg-bf1.yaml
+ delete mode 100644 Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt
+ create mode 100644 Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.yaml
+ delete mode 100644 Documentation/devicetree/bindings/display/panel/kingdisplay,kd035g6-54nt.txt
+ create mode 100644 Documentation/devicetree/bindings/display/panel/kingdisplay,kd035g6-54nt.yaml
+ delete mode 100644 Documentation/devicetree/bindings/display/panel/kingdisplay,kd097d04.txt
+ create mode 100644 Documentation/devicetree/bindings/display/panel/leadtek,ltk050h3146w.yaml
+ delete mode 100644 Documentation/devicetree/bindings/display/panel/lg,acx467akm-7.txt
+ delete mode 100644 Documentation/devicetree/bindings/display/panel/lg,ld070wx3-sl01.txt
+ delete mode 100644 Documentation/devicetree/bindings/display/panel/lg,lg4573.txt
+ create mode 100644 Documentation/devicetree/bindings/display/panel/lg,lg4573.yaml
+ delete mode 100644 Documentation/devicetree/bindings/display/panel/lg,lh500wx1-sd03.txt
+ delete mode 100644 Documentation/devicetree/bindings/display/panel/lgphilips,lb035q02.txt
+ create mode 100644 Documentation/devicetree/bindings/display/panel/lgphilips,lb035q02.yaml
+ delete mode 100644 Documentation/devicetree/bindings/display/panel/olimex,lcd-olinuxino.txt
+ create mode 100644 Documentation/devicetree/bindings/display/panel/olimex,lcd-olinuxino.yaml
+ delete mode 100644 Documentation/devicetree/bindings/display/panel/osddisplays,osd101t2587-53ts.txt
+ delete mode 100644 Documentation/devicetree/bindings/display/panel/raydium,rm67191.txt
+ create mode 100644 Documentation/devicetree/bindings/display/panel/raydium,rm67191.yaml
+ create mode 100644 Documentation/devicetree/bindings/display/panel/samsung,amoled-mipi-dsi.yaml
+ delete mode 100644 Documentation/devicetree/bindings/display/panel/samsung,ld9040.txt
+ create mode 100644 Documentation/devicetree/bindings/display/panel/samsung,ld9040.yaml
+ delete mode 100644 Documentation/devicetree/bindings/display/panel/samsung,s6d16d0.txt
+ create mode 100644 Documentation/devicetree/bindings/display/panel/samsung,s6d16d0.yaml
+ delete mode 100644 Documentation/devicetree/bindings/display/panel/samsung,s6e3ha2.txt
+ delete mode 100644 Documentation/devicetree/bindings/display/panel/samsung,s6e63j0x03.txt
+ delete mode 100644 Documentation/devicetree/bindings/display/panel/samsung,s6e63m0.txt
+ create mode 100644 Documentation/devicetree/bindings/display/panel/samsung,s6e63m0.yaml
+ delete mode 100644 Documentation/devicetree/bindings/display/panel/seiko,43wvf1g.txt
+ create mode 100644 Documentation/devicetree/bindings/display/panel/seiko,43wvf1g.yaml
+ delete mode 100644 Documentation/devicetree/bindings/display/panel/sharp,lq150x1lg11.txt
+ create mode 100644 Documentation/devicetree/bindings/display/panel/sharp,lq150x1lg11.yaml
+ delete mode 100644 Documentation/devicetree/bindings/display/panel/sharp,ls037v7dw01.txt
+ create mode 100644 Documentation/devicetree/bindings/display/panel/sharp,ls037v7dw01.yaml
+ delete mode 100644 Documentation/devicetree/bindings/display/panel/sharp,ls043t1le01.txt
+ create mode 100644 Documentation/devicetree/bindings/display/panel/sharp,ls043t1le01.yaml
+ delete mode 100644 Documentation/devicetree/bindings/display/panel/simple-panel.txt
+ delete mode 100644 Documentation/devicetree/bindings/display/panel/sitronix,st7701.txt
+ create mode 100644 Documentation/devicetree/bindings/display/panel/sitronix,st7701.yaml
+ delete mode 100644 Documentation/devicetree/bindings/display/panel/sitronix,st7789v.txt
+ create mode 100644 Documentation/devicetree/bindings/display/panel/sitronix,st7789v.yaml
+ delete mode 100644 Documentation/devicetree/bindings/display/panel/sony,acx565akm.txt
+ create mode 100644 Documentation/devicetree/bindings/display/panel/sony,acx565akm.yaml
+ delete mode 100644 Documentation/devicetree/bindings/display/panel/startek,startek-kd050c.txt
+ create mode 100644 Documentation/devicetree/bindings/display/panel/startek,startek-kd050c.yaml
+ create mode 100644 Documentation/devicetree/bindings/display/panel/tpo,td.yaml
+ delete mode 100644 Documentation/devicetree/bindings/display/panel/tpo,td028ttec1.txt
+ delete mode 100644 Documentation/devicetree/bindings/display/panel/tpo,td043mtea1.txt
+ create mode 100644 Documentation/devicetree/bindings/display/panel/visionox,rm69299.yaml
+ delete mode 100644 Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt
+ create mode 100644 Documentation/devicetree/bindings/display/rockchip/rockchip-vop.yaml
+ create mode 100644 drivers/dma-buf/st-dma-fence-chain.c
+ create mode 100644 drivers/gpu/drm/bridge/nwl-dsi.c
+ create mode 100644 drivers/gpu/drm/bridge/nwl-dsi.h
+ create mode 100644 drivers/gpu/drm/drm_managed.c
+ delete mode 100644 drivers/gpu/drm/drm_vram_helper_common.c
+ create mode 100644 drivers/gpu/drm/lima/lima_devfreq.c
+ create mode 100644 drivers/gpu/drm/lima/lima_devfreq.h
+ create mode 100644 drivers/gpu/drm/lima/lima_dump.h
+ create mode 100644 drivers/gpu/drm/lima/lima_trace.c
+ create mode 100644 drivers/gpu/drm/lima/lima_trace.h
+ create mode 100644 drivers/gpu/drm/panel/panel-leadtek-ltk050h3146w.c
+ create mode 100644 include/drm/drm_managed.h
+ delete mode 100644 include/drm/drm_pci.h
+Merging drm-msm/msm-next (a5fb8b918920 drm/msm/a6xx: Use the DMA API for GMU memory objects)
+$ git merge drm-msm/msm-next
+Already up to date.
+Merging mali-dp/for-upstream/mali-dp (f634c6a80287 dt/bindings: display: Add optional property node define for Mali DP500)
+$ git merge mali-dp/for-upstream/mali-dp
+Merge made by the 'recursive' strategy.
+Merging imx-drm/imx-drm/next (2c76b324c794 drm/imx: parallel-display: Adjust bus_flags handling)
+$ git merge imx-drm/imx-drm/next
+Auto-merging drivers/gpu/drm/imx/parallel-display.c
+Merge made by the 'recursive' strategy.
+ drivers/gpu/drm/imx/parallel-display.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+Merging etnaviv/etnaviv/next (f232d9ec029c drm/etnaviv: fix TS cache flushing on GPUs with BLT engine)
+$ git merge etnaviv/etnaviv/next
+Already up to date.
+Merging regmap/for-next (f320d878bff2 Merge branch 'regmap-5.8' into regmap-next)
+$ git merge regmap/for-next
+Merge made by the 'recursive' strategy.
+ drivers/base/regmap/regmap-irq.c | 84 ++++++++++++++++++++++++++++++++--------
+ drivers/base/regmap/regmap.c     |  1 +
+ include/linux/regmap.h           | 17 ++++++++
+ 3 files changed, 86 insertions(+), 16 deletions(-)
+Merging sound/for-next (3e8f3bd04716 ALSA: usb-audio: RME Babyface Pro mixer patch)
+$ git merge sound/for-next
+Merge made by the 'recursive' strategy.
+ sound/hda/intel-dsp-config.c |  97 ++++++++--
+ sound/usb/mixer_quirks.c     | 418 +++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 499 insertions(+), 16 deletions(-)
+Merging sound-asoc/for-next (392fe651949f Merge branch 'asoc-5.8' into asoc-next)
+$ git merge sound-asoc/for-next
+Merge made by the 'recursive' strategy.
+ .../bindings/sound/nvidia,tegra-audio-wm8903.txt   |   1 +
+ include/sound/soc.h                                |  26 +-
+ sound/pci/hda/patch_hdmi.c                         |   1 +
+ sound/soc/codecs/rt1308-sdw.c                      |   4 +-
+ sound/soc/codecs/wm8900.c                          |   6 -
+ sound/soc/codecs/wm8990.c                          |  98 -------
+ sound/soc/codecs/wm8991.c                          |   8 -
+ sound/soc/codecs/wm8994.c                          |   8 -
+ sound/soc/intel/boards/Kconfig                     |  15 +
+ sound/soc/intel/boards/Makefile                    |   2 +
+ sound/soc/intel/boards/ehl_rt5660.c                | 323 +++++++++++++++++++++
+ sound/soc/intel/boards/skl_hda_dsp_generic.c       |  29 +-
+ sound/soc/intel/boards/sof_da7219_max98373.c       |  21 ++
+ sound/soc/intel/boards/sof_sdw.c                   |  41 ++-
+ sound/soc/intel/boards/sof_sdw_hdmi.c              |   4 +-
+ sound/soc/intel/boards/sof_sdw_rt1308.c            |   2 +-
+ sound/soc/intel/boards/sof_sdw_rt5682.c            |   3 +-
+ sound/soc/intel/boards/sof_sdw_rt700.c             |   3 +-
+ sound/soc/intel/boards/sof_sdw_rt711.c             |   3 +-
+ sound/soc/intel/common/soc-acpi-intel-ehl-match.c  |   7 +
+ sound/soc/soc-compress.c                           |  36 +--
+ sound/soc/soc-core.c                               |  60 ++--
+ sound/soc/soc-dapm.c                               |   4 +-
+ sound/soc/soc-generic-dmaengine-pcm.c              |   6 +-
+ sound/soc/soc-pcm.c                                |  30 +-
+ sound/soc/sof/intel/hda-codec.c                    |   5 +-
+ sound/soc/sof/intel/hda-dsp.c                      |   8 +-
+ sound/soc/sof/intel/hda.c                          |  10 +-
+ sound/soc/sof/nocodec.c                            |   6 +-
+ sound/soc/sof/sof-pci-dev.c                        |   2 +
+ sound/soc/tegra/tegra_wm8903.c                     |   6 +-
+ 31 files changed, 538 insertions(+), 240 deletions(-)
+ create mode 100644 sound/soc/intel/boards/ehl_rt5660.c
+$ git reset --hard HEAD^
+HEAD is now at 3e1c85f13f6e Merge remote-tracking branch 'sound/for-next'
+Merging next-20200414 version of sound-asoc
+$ git merge -m next-20200414/sound-asoc 33c385056aadd08490f3ccf5e8b10314f26fb195
+Already up to date!
+Merge made by the 'recursive' strategy.
+Merging modules/modules-next (0f74226649fb kernel: module: Replace zero-length array with flexible-array member)
+$ git merge modules/modules-next
+Already up to date.
+Merging input/next (3a8579629665 Input: update SPDX tag for input-event-codes.h)
+$ git merge input/next
+Already up to date.
+Merging block/for-next (8f3d9f354286 Linux 5.7-rc1)
+$ git merge block/for-next
+Already up to date.
+Merging device-mapper/for-next (ad4e80a639fc dm verity fec: fix hash block number in verity_fec_decode)
+$ git merge device-mapper/for-next
+Merge made by the 'recursive' strategy.
+ .../admin-guide/device-mapper/dm-integrity.rst     | 15 ++++---
+ drivers/md/dm-verity-fec.c                         |  2 +-
+ drivers/md/dm-writecache.c                         | 52 +++++++++++++++-------
+ 3 files changed, 47 insertions(+), 22 deletions(-)
+Merging pcmcia/pcmcia-next (a8c122f72d94 pcmcia: remove some unused space characters)
+$ git merge pcmcia/pcmcia-next
+Already up to date.
+Merging mmc/next (23ecdb29060f Merge branch 'fixes' into next)
+$ git merge mmc/next
+Merge made by the 'recursive' strategy.
+ .../devicetree/bindings/mmc/arasan,sdhci.txt       |  15 +
+ drivers/mmc/host/android-goldfish.c                |  10 +-
+ drivers/mmc/host/au1xmmc.c                         |  20 +-
+ drivers/mmc/host/renesas_sdhi.h                    |   2 +
+ drivers/mmc/host/renesas_sdhi_core.c               |  70 ++-
+ drivers/mmc/host/s3cmci.c                          |   7 -
+ drivers/mmc/host/sdhci-esdhc-imx.c                 |   4 +-
+ drivers/mmc/host/sdhci-of-arasan.c                 | 473 +++++++++++++++------
+ drivers/mmc/host/sdhci-of-at91.c                   |   5 +-
+ drivers/mmc/host/sdhci-pci-core.c                  |   8 +-
+ drivers/mmc/host/sdhci-sprd.c                      |   3 +-
+ drivers/mmc/host/sdhci.c                           |  19 +-
+ drivers/mmc/host/sdhci.h                           |  20 +-
+ drivers/mmc/host/wbsd.c                            |  26 +-
+ 14 files changed, 438 insertions(+), 244 deletions(-)
+Merging md/for-next (e820d55cb99d md: fix raid10 hang issue caused by barrier)
+$ git merge md/for-next
+Already up to date.
+Merging mfd/for-mfd-next (d2923aa45356 mfd: intel-lpss: Fix Intel Elkhart Lake LPSS I2C input clock)
+$ git merge mfd/for-mfd-next
+Already up to date.
+Merging backlight/for-backlight-next (ee0c8e494cc3 backlight: corgi: Convert to use GPIO descriptors)
+$ git merge backlight/for-backlight-next
+Already up to date.
+Merging battery/for-next (164eaf6b435c power: supply: 88pm860x_battery: remove redundant dev_err message)
+$ git merge battery/for-next
+Merge made by the 'recursive' strategy.
+ drivers/power/supply/88pm860x_battery.c          | 8 ++------
+ drivers/power/supply/Kconfig                     | 2 +-
+ drivers/power/supply/axp288_fuel_gauge.c         | 6 ++++++
+ drivers/power/supply/max14656_charger_detector.c | 5 ++---
+ 4 files changed, 11 insertions(+), 10 deletions(-)
+Merging regulator/for-next (2ea8db7200d4 regulator: tps80031: remove redundant assignment to variables ret and val)
+$ git merge regulator/for-next
+Merge made by the 'recursive' strategy.
+ drivers/regulator/ab8500.c             | 22 ----------------------
+ drivers/regulator/core.c               |  1 +
+ drivers/regulator/qcom_rpm-regulator.c | 10 ----------
+ drivers/regulator/tps80031-regulator.c |  7 ++++---
+ 4 files changed, 5 insertions(+), 35 deletions(-)
+Merging security/next-testing (3e27a33932df security: remove duplicated include from security.h)
+$ git merge security/next-testing
+Already up to date.
+Merging apparmor/apparmor-next (01df52d726b5 apparmor: remove duplicate check of xattrs on profile attachment.)
+$ git merge apparmor/apparmor-next
+Auto-merging security/apparmor/policy_unpack.c
+Auto-merging security/apparmor/apparmorfs.c
+Auto-merging fs/proc/base.c
+Merge made by the 'recursive' strategy.
+ fs/proc/base.c                    | 13 ++++++++++
+ security/apparmor/apparmorfs.c    | 54 +++++++++------------------------------
+ security/apparmor/domain.c        | 39 ++++++++++------------------
+ security/apparmor/include/label.h |  1 +
+ security/apparmor/include/match.h | 11 ++++++++
+ security/apparmor/label.c         | 37 +++++++++++++++++++++++++--
+ security/apparmor/match.c         | 53 +++++++++++++++++++++++++++++++++++++-
+ security/apparmor/path.c          |  2 +-
+ security/apparmor/policy_unpack.c |  4 +++
+ 9 files changed, 143 insertions(+), 71 deletions(-)
+Merging integrity/next-integrity (9e2b4be377f0 ima: add a new CONFIG for loading arch-specific policies)
+$ git merge integrity/next-integrity
+Already up to date.
+Merging keys/keys-next (43672cf93c6d Merge branch 'notifications-pipe-core' into keys-next)
+$ git merge keys/keys-next
+Auto-merging security/selinux/hooks.c
+Auto-merging security/security.c
+Auto-merging security/keys/keyring.c
+Auto-merging security/keys/keyctl.c
+Auto-merging security/keys/key.c
+Auto-merging security/keys/internal.h
+Auto-merging init/Kconfig
+Auto-merging include/linux/security.h
+Auto-merging include/linux/pipe_fs_i.h
+Auto-merging include/linux/lsm_hooks.h
+CONFLICT (content): Merge conflict in include/linux/lsm_hooks.h
+Auto-merging fs/splice.c
+Auto-merging fs/pipe.c
+CONFLICT (content): Merge conflict in fs/pipe.c
+Auto-merging Documentation/userspace-api/ioctl/ioctl-number.rst
+Resolved 'fs/pipe.c' using previous resolution.
+Resolved 'include/linux/lsm_hooks.h' using previous resolution.
+Automatic merge failed; fix conflicts and then commit the result.
+$ git commit --no-edit -v -a
+[master 683e01890c7c] Merge remote-tracking branch 'keys/keys-next'
+$ git diff -M --stat --summary HEAD^..
+ Documentation/security/keys/core.rst               |  58 ++
+ Documentation/userspace-api/ioctl/ioctl-number.rst |   1 +
+ Documentation/watch_queue.rst                      | 354 +++++++++++
+ fs/pipe.c                                          | 242 +++++---
+ fs/splice.c                                        |  12 +-
+ include/linux/key.h                                |   3 +
+ include/linux/lsm_audit.h                          |   1 +
+ include/linux/lsm_hooks.h                          |  18 +
+ include/linux/pipe_fs_i.h                          |  27 +-
+ include/linux/security.h                           |  31 +
+ include/linux/watch_queue.h                        | 127 ++++
+ include/uapi/linux/keyctl.h                        |   2 +
+ include/uapi/linux/watch_queue.h                   | 104 ++++
+ init/Kconfig                                       |  12 +
+ kernel/Makefile                                    |   1 +
+ kernel/watch_queue.c                               | 659 +++++++++++++++++++++
+ samples/Kconfig                                    |   6 +
+ samples/Makefile                                   |   1 +
+ samples/watch_queue/Makefile                       |   7 +
+ samples/watch_queue/watch_test.c                   | 186 ++++++
+ security/keys/Kconfig                              |   9 +
+ security/keys/compat.c                             |   3 +
+ security/keys/gc.c                                 |   5 +
+ security/keys/internal.h                           |  30 +-
+ security/keys/key.c                                |  38 +-
+ security/keys/keyctl.c                             |  99 +++-
+ security/keys/keyring.c                            |  20 +-
+ security/keys/request_key.c                        |   4 +-
+ security/security.c                                |  23 +
+ security/selinux/hooks.c                           |  14 +
+ security/smack/smack_lsm.c                         |  83 ++-
+ 31 files changed, 2075 insertions(+), 105 deletions(-)
+ create mode 100644 Documentation/watch_queue.rst
+ create mode 100644 include/linux/watch_queue.h
+ create mode 100644 include/uapi/linux/watch_queue.h
+ create mode 100644 kernel/watch_queue.c
+ create mode 100644 samples/watch_queue/Makefile
+ create mode 100644 samples/watch_queue/watch_test.c
+$ git am -3 ../patches/0001-io_uring-fix-up-get_pipe_info-API-change.patch
+Applying: io_uring: fix up for get_pipe_info() API change
+$ git reset HEAD^
+Unstaged changes after reset:
+M	fs/io_uring.c
+$ git add -A .
+$ git commit -v -a --amend
+[master 3166526da9d3] Merge remote-tracking branch 'keys/keys-next'
+ Date: Fri Apr 17 11:11:09 2020 +1000
+$ git am -3 ../patches/0001-security-keys-fixup-for-security-Refactor-declaratio.patch
+Applying: security: keys: fixup for "security: Refactor declaration of LSM hooks"
+$ git reset HEAD^
+Unstaged changes after reset:
+M	include/linux/lsm_hook_defs.h
+$ git add -A .
+$ git commit -v -a --amend
+[master dd4d8afc1921] Merge remote-tracking branch 'keys/keys-next'
+ Date: Fri Apr 17 11:11:09 2020 +1000
+Merging selinux/next (433e3aa37773 selinux: drop unnecessary smp_load_acquire() call)
+$ git merge selinux/next
+Merge made by the 'recursive' strategy.
+ security/selinux/ss/mls.c      | 2 +-
+ security/selinux/ss/services.c | 4 ++--
+ security/selinux/ss/sidtab.c   | 3 +--
+ 3 files changed, 4 insertions(+), 5 deletions(-)
+Merging smack/for-next (92604e825304 smack: use GFP_NOFS while holding inode_smack::smk_lock)
+$ git merge smack/for-next
+Auto-merging security/smack/smack_lsm.c
+Merge made by the 'recursive' strategy.
+Merging tomoyo/master (8f3d9f354286 Linux 5.7-rc1)
+$ git merge tomoyo/master
+Already up to date.
+Merging tpmdd/next (8e0ea4627151 tpm/tpm_tis: Free IRQ if probing fails)
+$ git merge tpmdd/next
+Merge made by the 'recursive' strategy.
+ drivers/char/tpm/tpm-interface.c |   2 +-
+ drivers/char/tpm/tpm2-cmd.c      |   1 +
+ drivers/char/tpm/tpm_ibmvtpm.c   | 136 +++++++++++++++++++++------------------
+ drivers/char/tpm/tpm_tis_core.c  |   8 ++-
+ 4 files changed, 82 insertions(+), 65 deletions(-)
+Merging watchdog/master (ea104a9e4d3e watchdog: sp805: fix restart handler)
+$ git merge watchdog/master
+Merge made by the 'recursive' strategy.
+ drivers/watchdog/sp805_wdt.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+Merging iommu/next (ff68eb23308e Merge branches 'iommu/fixes', 'arm/qcom', 'arm/omap', 'arm/smmu', 'x86/amd', 'x86/vt-d', 'virtio' and 'core' into next)
+$ git merge iommu/next
+Already up to date.
+Merging vfio/next (f44efca0493d vfio: Ignore -ENODEV when getting MSI cookie)
+$ git merge vfio/next
+Already up to date.
+Merging audit/next (8f3d9f354286 Linux 5.7-rc1)
+$ git merge audit/next
+Already up to date.
+Merging devicetree/for-next (9f60a65bc5e6 dt-bindings: Clean-up schema indentation formatting)
+$ git merge devicetree/for-next
+Auto-merging MAINTAINERS
+Auto-merging Documentation/devicetree/bindings/vendor-prefixes.yaml
+Removing Documentation/devicetree/bindings/timer/cadence,ttc-timer.txt
+Auto-merging Documentation/devicetree/bindings/spi/qcom,spi-qcom-qspi.yaml
+Removing Documentation/devicetree/bindings/net/stm32-dwmac.txt
+Removing Documentation/devicetree/bindings/input/gpio-keys.txt
+Removing Documentation/devicetree/bindings/input/gpio-keys-polled.txt
+Removing Documentation/devicetree/bindings/i2c/i2c-xiic.txt
+Removing Documentation/devicetree/bindings/i2c/i2c-cadence.txt
+Auto-merging Documentation/devicetree/bindings/display/panel/xinpeng,xpp055c272.yaml
+Auto-merging Documentation/devicetree/bindings/display/allwinner,sun6i-a31-mipi-dsi.yaml
+Merge made by the 'recursive' strategy.
+ Documentation/devicetree/bindings/arm/altera.yaml  |   6 +-
+ .../arm/amlogic/amlogic,meson-gx-ao-secure.yaml    |   2 +-
+ Documentation/devicetree/bindings/arm/bitmain.yaml |   2 +-
+ .../devicetree/bindings/arm/nxp/lpc32xx.yaml       |   9 +-
+ .../bindings/arm/socionext/uniphier.yaml           |  26 ++--
+ .../devicetree/bindings/arm/stm32/st,mlahb.yaml    |   2 +-
+ .../bindings/arm/stm32/st,stm32-syscon.yaml        |   6 +-
+ .../devicetree/bindings/ata/faraday,ftide010.yaml  |   4 +-
+ .../bindings/bus/allwinner,sun8i-a23-rsb.yaml      |   4 +-
+ .../clock/allwinner,sun4i-a10-gates-clk.yaml       |   8 +-
+ .../devicetree/bindings/clock/fsl,plldig.yaml      |  17 ++-
+ .../devicetree/bindings/clock/qcom,mmcc.yaml       |  16 +--
+ .../bindings/connector/usb-connector.yaml          |   6 +-
+ .../crypto/allwinner,sun4i-a10-crypto.yaml         |  14 +-
+ .../bindings/crypto/allwinner,sun8i-ce.yaml        |  16 +--
+ .../bindings/crypto/amlogic,gxl-crypto.yaml        |   2 +-
+ .../bindings/display/allwinner,sun4i-a10-hdmi.yaml |  40 +++---
+ .../bindings/display/allwinner,sun4i-a10-tcon.yaml |  58 ++++----
+ .../display/allwinner,sun6i-a31-mipi-dsi.yaml      |  28 ++--
+ .../display/allwinner,sun8i-a83t-dw-hdmi.yaml      |  10 +-
+ .../bindings/display/bridge/lvds-codec.yaml        |  18 +--
+ .../bindings/display/panel/sony,acx424akp.yaml     |   2 +-
+ .../bindings/display/panel/xinpeng,xpp055c272.yaml |   4 +-
+ .../devicetree/bindings/display/renesas,cmm.yaml   |  16 +--
+ .../devicetree/bindings/dma/ti/k3-udma.yaml        |   8 +-
+ .../bindings/gpio/brcm,xgs-iproc-gpio.yaml         |   2 +-
+ .../devicetree/bindings/gpu/arm,mali-midgard.yaml  |  18 +--
+ .../devicetree/bindings/gpu/vivante,gc.yaml        |   2 +-
+ .../devicetree/bindings/i2c/cdns,i2c-r1p10.yaml    |  58 ++++++++
+ .../devicetree/bindings/i2c/i2c-cadence.txt        |  28 ----
+ .../devicetree/bindings/i2c/i2c-rk3x.yaml          |  10 +-
+ Documentation/devicetree/bindings/i2c/i2c-xiic.txt |  25 ----
+ .../bindings/i2c/xlnx,xps-iic-2.00.a.yaml          |  49 +++++++
+ .../devicetree/bindings/iio/adc/adi,ad7124.yaml    |   4 +-
+ .../devicetree/bindings/iio/adc/lltc,ltc2496.yaml  |   6 +-
+ .../input/allwinner,sun4i-a10-lradc-keys.yaml      |   4 +-
+ .../devicetree/bindings/input/gpio-keys-polled.txt |  45 ------
+ .../devicetree/bindings/input/gpio-keys.txt        |  58 --------
+ .../devicetree/bindings/input/gpio-keys.yaml       | 152 +++++++++++++++++++++
+ .../bindings/input/touchscreen/goodix.yaml         |   2 +-
+ .../bindings/interconnect/qcom,msm8916.yaml        |   4 +-
+ .../bindings/interconnect/qcom,msm8974.yaml        |   4 +-
+ .../bindings/interconnect/qcom,qcs404.yaml         |   4 +-
+ .../allwinner,sun7i-a20-sc-nmi.yaml                |  12 +-
+ .../intel,ixp4xx-interrupt.yaml                    |   8 +-
+ .../interrupt-controller/st,stm32-exti.yaml        |  12 +-
+ .../devicetree/bindings/iommu/samsung,sysmmu.yaml  |  10 +-
+ .../devicetree/bindings/mailbox/st,stm32-ipcc.yaml |   2 +-
+ .../bindings/media/allwinner,sun4i-a10-csi.yaml    |  28 ++--
+ .../devicetree/bindings/media/amlogic,gx-vdec.yaml |  14 +-
+ .../devicetree/bindings/media/renesas,ceu.yaml     |  28 ++--
+ .../devicetree/bindings/media/renesas,vin.yaml     |   8 +-
+ .../devicetree/bindings/media/ti,vpe.yaml          |   2 +-
+ .../bindings/memory-controllers/exynos-srom.yaml   |   4 +-
+ .../memory-controllers/fsl/imx8m-ddrc.yaml         |   6 +-
+ .../memory-controllers/nvidia,tegra210-emc.yaml    |  82 +++++++++++
+ .../devicetree/bindings/mfd/st,stm32-lptimer.yaml  |   4 +-
+ .../devicetree/bindings/mfd/st,stm32-timers.yaml   |   4 +-
+ Documentation/devicetree/bindings/mfd/syscon.yaml  |  12 +-
+ .../devicetree/bindings/mmc/cdns,sdhci.yaml        |   2 +-
+ .../devicetree/bindings/mmc/rockchip-dw-mshc.yaml  |  16 +--
+ .../bindings/mmc/socionext,uniphier-sd.yaml        |  14 +-
+ .../devicetree/bindings/mtd/denali,nand.yaml       |   4 +-
+ .../bindings/net/allwinner,sun8i-a83t-emac.yaml    |   4 +-
+ .../devicetree/bindings/net/can/bosch,m_can.yaml   |  52 +++----
+ .../devicetree/bindings/net/renesas,ether.yaml     |   4 +-
+ .../devicetree/bindings/net/snps,dwmac.yaml        |   8 +-
+ .../devicetree/bindings/net/stm32-dwmac.txt        |  44 ------
+ .../devicetree/bindings/net/stm32-dwmac.yaml       | 149 ++++++++++++++++++++
+ .../devicetree/bindings/net/ti,cpsw-switch.yaml    |  12 +-
+ .../devicetree/bindings/net/ti,davinci-mdio.yaml   |  27 ++--
+ .../bindings/phy/intel,lgm-emmc-phy.yaml           |   2 +-
+ .../devicetree/bindings/pwm/pwm-samsung.yaml       |  16 +--
+ .../bindings/remoteproc/st,stm32-rproc.yaml        |   2 +-
+ .../bindings/reserved-memory/reserved-memory.txt   |   2 +
+ .../reset/brcm,bcm7216-pcie-sata-rescal.yaml       |   4 +-
+ .../devicetree/bindings/rtc/st,stm32-rtc.yaml      |  38 +++---
+ .../bindings/serial/amlogic,meson-uart.yaml        |  16 +--
+ .../devicetree/bindings/serial/rs485.yaml          |  17 +--
+ .../bindings/soc/amlogic/amlogic,canvas.yaml       |  10 +-
+ .../devicetree/bindings/sound/renesas,fsi.yaml     |  16 +--
+ .../bindings/spi/qcom,spi-qcom-qspi.yaml           |  10 +-
+ .../devicetree/bindings/spi/renesas,hspi.yaml      |   4 +-
+ .../devicetree/bindings/spi/spi-pl022.yaml         |   2 +-
+ .../devicetree/bindings/spi/st,stm32-qspi.yaml     |   4 +-
+ .../sram/allwinner,sun4i-a10-system-control.yaml   |  64 ++++-----
+ Documentation/devicetree/bindings/sram/sram.yaml   |   2 +
+ .../bindings/thermal/amlogic,thermal.yaml          |  10 +-
+ .../devicetree/bindings/timer/arm,arch_timer.yaml  |   4 +-
+ .../bindings/timer/arm,arch_timer_mmio.yaml        |   4 +-
+ .../bindings/timer/cadence,ttc-timer.txt           |  21 ---
+ .../devicetree/bindings/timer/cdns,ttc.yaml        |  48 +++++++
+ Documentation/devicetree/bindings/usb/dwc2.yaml    |   8 +-
+ .../devicetree/bindings/usb/generic-ehci.yaml      |   3 +
+ .../devicetree/bindings/usb/generic-ohci.yaml      |   3 +
+ .../devicetree/bindings/vendor-prefixes.yaml       |   8 ++
+ MAINTAINERS                                        |   4 +-
+ drivers/of/dynamic.c                               |   3 +-
+ drivers/of/property.c                              |   2 +
+ 99 files changed, 1019 insertions(+), 679 deletions(-)
+ create mode 100644 Documentation/devicetree/bindings/i2c/cdns,i2c-r1p10.yaml
+ delete mode 100644 Documentation/devicetree/bindings/i2c/i2c-cadence.txt
+ delete mode 100644 Documentation/devicetree/bindings/i2c/i2c-xiic.txt
+ create mode 100644 Documentation/devicetree/bindings/i2c/xlnx,xps-iic-2.00.a.yaml
+ delete mode 100644 Documentation/devicetree/bindings/input/gpio-keys-polled.txt
+ delete mode 100644 Documentation/devicetree/bindings/input/gpio-keys.txt
+ create mode 100644 Documentation/devicetree/bindings/input/gpio-keys.yaml
+ create mode 100644 Documentation/devicetree/bindings/memory-controllers/nvidia,tegra210-emc.yaml
+ delete mode 100644 Documentation/devicetree/bindings/net/stm32-dwmac.txt
+ create mode 100644 Documentation/devicetree/bindings/net/stm32-dwmac.yaml
+ delete mode 100644 Documentation/devicetree/bindings/timer/cadence,ttc-timer.txt
+ create mode 100644 Documentation/devicetree/bindings/timer/cdns,ttc.yaml
+Merging mailbox/mailbox-for-next (0a67003b1985 mailbox: imx: add SCU MU support)
+$ git merge mailbox/mailbox-for-next
+Already up to date.
+Merging spi/for-next (5810dd79dec4 Merge branch 'spi-5.8' into spi-next)
+$ git merge spi/for-next
+Removing Documentation/devicetree/bindings/spi/spi-rspi.txt
+Merge made by the 'recursive' strategy.
+ .../devicetree/bindings/spi/renesas,rspi.yaml      | 144 +++++++++++++++++++++
+ Documentation/devicetree/bindings/spi/spi-rspi.txt |  73 -----------
+ drivers/spi/spi-fsl-lpspi.c                        |  15 +--
+ drivers/spi/spi-fsl-spi.c                          |   2 +-
+ drivers/spi/spi-mtk-nor.c                          |   2 +-
+ drivers/spi/spi-sh-msiof.c                         |   2 +-
+ drivers/spi/spi-sprd-adi.c                         |   2 +-
+ drivers/spi/spi.c                                  |   2 +-
+ tools/spi/Makefile                                 |   4 +-
+ 9 files changed, 159 insertions(+), 87 deletions(-)
+ create mode 100644 Documentation/devicetree/bindings/spi/renesas,rspi.yaml
+ delete mode 100644 Documentation/devicetree/bindings/spi/spi-rspi.txt
+Merging tip/auto-latest (1030eb5ea145 Merge branch 'perf/urgent')
+$ git merge tip/auto-latest
+Auto-merging lib/Kconfig.debug
+Auto-merging kernel/Makefile
+Auto-merging include/linux/irq.h
+Auto-merging MAINTAINERS
+Merge made by the 'recursive' strategy.
+ Documentation/dev-tools/index.rst                  |   1 +
+ Documentation/dev-tools/kcsan.rst                  | 266 ++++++++
+ MAINTAINERS                                        |  11 +
+ Makefile                                           |   3 +-
+ arch/x86/Kconfig                                   |   1 +
+ arch/x86/Kconfig.debug                             |   9 -
+ arch/x86/boot/Makefile                             |   2 +
+ arch/x86/boot/compressed/Makefile                  |   2 +
+ arch/x86/entry/entry_32.S                          |   2 -
+ arch/x86/entry/vdso/Makefile                       |   6 +
+ arch/x86/include/asm/amd_nb.h                      |   1 +
+ arch/x86/include/asm/bitops.h                      |   6 +-
+ arch/x86/include/asm/doublefault.h                 |   2 +-
+ arch/x86/include/asm/mce.h                         |  28 +-
+ arch/x86/include/asm/microcode_amd.h               |   2 +-
+ arch/x86/include/asm/traps.h                       |   2 -
+ arch/x86/include/uapi/asm/mce.h                    |   1 +
+ arch/x86/kernel/Makefile                           |   8 +-
+ arch/x86/kernel/cpu/Makefile                       |   3 +
+ arch/x86/kernel/cpu/mce/amd.c                      | 233 +++----
+ arch/x86/kernel/cpu/mce/core.c                     |  84 ++-
+ arch/x86/kernel/cpu/mce/dev-mcelog.c               |   5 +
+ arch/x86/kernel/cpu/mce/internal.h                 |  10 +-
+ arch/x86/kernel/cpu/mce/severity.c                 |   6 +-
+ arch/x86/kernel/dumpstack_32.c                     |   4 -
+ arch/x86/kernel/e820.c                             |  18 +-
+ arch/x86/kernel/smpboot.c                          |  17 +-
+ arch/x86/kernel/traps.c                            |   2 -
+ arch/x86/kernel/umip.c                             |   2 +-
+ arch/x86/lib/Makefile                              |   9 +
+ arch/x86/mm/Makefile                               |   4 +
+ arch/x86/mm/cpu_entry_area.c                       |   4 +-
+ arch/x86/purgatory/.gitignore                      |   1 +
+ arch/x86/purgatory/Makefile                        |  21 +-
+ arch/x86/realmode/Makefile                         |   3 +
+ arch/x86/realmode/rm/Makefile                      |   3 +
+ drivers/acpi/acpi_extlog.c                         |  19 +-
+ drivers/acpi/nfit/mce.c                            |   1 +
+ drivers/edac/amd64_edac.c                          |   8 -
+ drivers/edac/edac_mc.c                             |  61 --
+ drivers/edac/i7core_edac.c                         |   5 +-
+ drivers/edac/mce_amd.c                             |  28 +-
+ drivers/edac/mce_amd.h                             |   2 -
+ drivers/edac/pnd2_edac.c                           |   8 +-
+ drivers/edac/sb_edac.c                             |   7 +-
+ drivers/edac/skx_common.c                          |   3 +-
+ drivers/firmware/efi/libstub/Makefile              |   2 +
+ drivers/ras/cec.c                                  |  33 +-
+ include/asm-generic/atomic-instrumented.h          | 711 ++++++++++----------
+ include/asm-generic/atomic-long.h                  | 331 ++++-----
+ include/asm-generic/bitops/instrumented-atomic.h   |  14 +-
+ include/asm-generic/bitops/instrumented-lock.h     |  10 +-
+ .../asm-generic/bitops/instrumented-non-atomic.h   |  16 +-
+ include/linux/atomic-fallback.h                    | 340 +++++-----
+ include/linux/compiler-clang.h                     |  11 +-
+ include/linux/compiler-gcc.h                       |   6 +
+ include/linux/compiler.h                           |  60 +-
+ include/linux/crash_dump.h                         |   2 -
+ include/linux/edac.h                               |   8 -
+ include/linux/instrumented.h                       | 109 +++
+ include/linux/irq.h                                |   2 -
+ include/linux/kcsan-checks.h                       | 251 +++++++
+ include/linux/kcsan.h                              |  72 ++
+ include/linux/ras.h                                |   5 -
+ include/linux/sched.h                              |   4 +
+ include/linux/seqlock.h                            |  51 +-
+ include/linux/uaccess.h                            |  14 +-
+ init/init_task.c                                   |   9 +
+ init/main.c                                        |   2 +
+ kernel/Makefile                                    |   6 +
+ kernel/crash_dump.c                                |   6 -
+ kernel/irq/manage.c                                |  44 --
+ kernel/kcsan/Makefile                              |  14 +
+ kernel/kcsan/atomic.h                              |  27 +
+ kernel/kcsan/core.c                                | 730 ++++++++++++++++++++
+ kernel/kcsan/debugfs.c                             | 326 +++++++++
+ kernel/kcsan/encoding.h                            |  95 +++
+ kernel/kcsan/kcsan.h                               | 138 ++++
+ kernel/kcsan/report.c                              | 515 ++++++++++++++
+ kernel/kcsan/test.c                                | 131 ++++
+ kernel/locking/Makefile                            |   3 +
+ kernel/rcu/tree.c                                  |   2 +-
+ kernel/sched/Makefile                              |   6 +
+ kernel/sched/cputime.c                             |   4 +-
+ kernel/sched/isolation.c                           |  21 +-
+ kernel/trace/Makefile                              |   3 +
+ lib/Kconfig.debug                                  |   2 +
+ lib/Kconfig.kcsan                                  | 156 +++++
+ lib/Makefile                                       |   4 +
+ lib/iov_iter.c                                     |   7 +-
+ lib/usercopy.c                                     |   7 +-
+ mm/Makefile                                        |   8 +
+ scripts/Makefile.kcsan                             |   6 +
+ scripts/Makefile.lib                               |  10 +
+ scripts/atomic/fallbacks/acquire                   |   2 +-
+ scripts/atomic/fallbacks/add_negative              |   2 +-
+ scripts/atomic/fallbacks/add_unless                |   2 +-
+ scripts/atomic/fallbacks/andnot                    |   2 +-
+ scripts/atomic/fallbacks/dec                       |   2 +-
+ scripts/atomic/fallbacks/dec_and_test              |   2 +-
+ scripts/atomic/fallbacks/dec_if_positive           |   2 +-
+ scripts/atomic/fallbacks/dec_unless_positive       |   2 +-
+ scripts/atomic/fallbacks/fence                     |   2 +-
+ scripts/atomic/fallbacks/fetch_add_unless          |   2 +-
+ scripts/atomic/fallbacks/inc                       |   2 +-
+ scripts/atomic/fallbacks/inc_and_test              |   2 +-
+ scripts/atomic/fallbacks/inc_not_zero              |   2 +-
+ scripts/atomic/fallbacks/inc_unless_negative       |   2 +-
+ scripts/atomic/fallbacks/read_acquire              |   2 +-
+ scripts/atomic/fallbacks/release                   |   2 +-
+ scripts/atomic/fallbacks/set_release               |   2 +-
+ scripts/atomic/fallbacks/sub_and_test              |   2 +-
+ scripts/atomic/fallbacks/try_cmpxchg               |   2 +-
+ scripts/atomic/gen-atomic-fallback.sh              |   2 +
+ scripts/atomic/gen-atomic-instrumented.sh          |   9 +-
+ scripts/atomic/gen-atomic-long.sh                  |   3 +-
+ tools/arch/x86/include/asm/cpufeatures.h           |   5 +-
+ tools/arch/x86/include/asm/msr-index.h             |   9 +
+ tools/include/linux/bits.h                         |  24 +-
+ tools/include/linux/build_bug.h                    |  82 +++
+ tools/include/linux/compiler.h                     |  26 +
+ tools/include/linux/const.h                        |   5 +-
+ tools/include/linux/kernel.h                       |   4 +-
+ tools/include/uapi/drm/drm.h                       |   2 +
+ tools/include/uapi/drm/i915_drm.h                  |  21 +
+ tools/include/uapi/linux/fscrypt.h                 |   1 +
+ tools/include/uapi/linux/kvm.h                     |  47 +-
+ tools/include/uapi/linux/mman.h                    |   5 +-
+ tools/include/uapi/linux/sched.h                   |   5 +
+ tools/include/uapi/linux/vhost.h                   |  24 +
+ tools/include/vdso/bits.h                          |   9 +
+ tools/include/vdso/const.h                         |  10 +
+ tools/objtool/check.c                              |  44 +-
+ tools/objtool/orc_dump.c                           |  44 +-
+ tools/objtool/orc_gen.c                            |  33 +-
+ tools/perf/arch/x86/entry/syscalls/syscall_64.tbl  | 740 ++++++++++-----------
+ tools/perf/check-headers.sh                        |   3 +
+ tools/perf/trace/beauty/clone.c                    |   1 +
+ tools/perf/trace/beauty/mmap.c                     |   1 +
+ tools/perf/util/setup.py                           |   2 +
+ tools/perf/util/stat-shadow.c                      |   7 +-
+ .../testing/selftests/wireguard/qemu/debug.config  |   1 -
+ 142 files changed, 4868 insertions(+), 1597 deletions(-)
+ create mode 100644 Documentation/dev-tools/kcsan.rst
+ create mode 100644 arch/x86/purgatory/.gitignore
+ create mode 100644 include/linux/instrumented.h
+ create mode 100644 include/linux/kcsan-checks.h
+ create mode 100644 include/linux/kcsan.h
+ create mode 100644 kernel/kcsan/Makefile
+ create mode 100644 kernel/kcsan/atomic.h
+ create mode 100644 kernel/kcsan/core.c
+ create mode 100644 kernel/kcsan/debugfs.c
+ create mode 100644 kernel/kcsan/encoding.h
+ create mode 100644 kernel/kcsan/kcsan.h
+ create mode 100644 kernel/kcsan/report.c
+ create mode 100644 kernel/kcsan/test.c
+ create mode 100644 lib/Kconfig.kcsan
+ create mode 100644 scripts/Makefile.kcsan
+ create mode 100644 tools/include/linux/build_bug.h
+ create mode 100644 tools/include/vdso/bits.h
+ create mode 100644 tools/include/vdso/const.h
+Merging clockevents/timers/drivers/next (c1ac28a4de6f Revert "clocksource: Avoid creating dead devices")
+$ git merge clockevents/timers/drivers/next
+Merge made by the 'recursive' strategy.
+Merging edac/edac-for-next (d9976bc155b1 MAINTAINERS: Remove sifive_l2_cache.c from EDAC-SIFIVE pattern)
+$ git merge edac/edac-for-next
+Auto-merging MAINTAINERS
+Merge made by the 'recursive' strategy.
+ MAINTAINERS                   |  1 -
+ drivers/edac/armada_xp_edac.c | 14 +++++++-------
+ drivers/edac/xgene_edac.c     |  3 ---
+ 3 files changed, 7 insertions(+), 11 deletions(-)
+Merging irqchip/irq/irqchip-next (4cea749d56be Revert "irqchip/xilinx: Enable generic irq multi handler")
+$ git merge irqchip/irq/irqchip-next
+Already up to date.
+Merging ftrace/for-next (8e99cf91b99b tracing: Do not allocate buffer in trace_find_next_entry() in atomic)
+$ git merge ftrace/for-next
+Already up to date.
+Merging rcu/rcu/next (350957908464 Improve KCSAN documentation a bit)
+$ git merge rcu/rcu/next
+Auto-merging tools/objtool/check.c
+Auto-merging kernel/rcu/tree.c
+Auto-merging kernel/fork.c
+Auto-merging drivers/gpu/drm/drm_dp_mst_topology.c
+Auto-merging arch/x86/kernel/Makefile
+Auto-merging arch/x86/Kconfig
+Auto-merging MAINTAINERS
+Auto-merging Documentation/admin-guide/kernel-parameters.txt
+Merge made by the 'recursive' strategy.
+ Documentation/admin-guide/kernel-parameters.txt    |   19 +
+ Documentation/atomic_t.txt                         |   24 +-
+ Documentation/dev-tools/kcsan.rst                  |  228 ++--
+ Documentation/litmus-tests/README                  |   14 +
+ ...b__after_atomic-is-stronger-than-acquire.litmus |   32 +
+ ...Atomic-RMW-ops-are-atomic-WRT-atomic_set.litmus |   24 +
+ Documentation/litmus-tests/atomic/README           |   16 +
+ .../rcu}/MP+onceassign+derefonce.litmus            |    0
+ .../litmus-tests/rcu/RCU+sync+free.litmus          |   42 +
+ .../litmus-tests/rcu/RCU+sync+read.litmus          |   37 +
+ MAINTAINERS                                        |    2 +
+ arch/x86/Kconfig                                   |    1 +
+ arch/x86/mm/pat/set_memory.c                       |    2 +-
+ drivers/gpu/drm/drm_dp_mst_topology.c              |    2 +-
+ include/linux/compiler.h                           |    4 +-
+ include/linux/kcsan-checks.h                       |  244 +++-
+ include/linux/kcsan.h                              |   19 +-
+ include/linux/rculist.h                            |    6 +-
+ include/linux/rcupdate.h                           |   53 +-
+ include/linux/rcupdate_trace.h                     |   88 ++
+ include/linux/rcupdate_wait.h                      |   19 +
+ include/linux/rcutiny.h                            |    3 +-
+ include/linux/rcutree.h                            |    1 +
+ include/linux/sched.h                              |   10 +-
+ include/linux/torture.h                            |    2 +-
+ include/linux/wait.h                               |    2 +
+ init/init_task.c                                   |    6 +
+ kernel/fork.c                                      |   13 +-
+ kernel/kcsan/atomic.h                              |   21 +-
+ kernel/kcsan/core.c                                |  176 ++-
+ kernel/kcsan/debugfs.c                             |   43 +-
+ kernel/kcsan/kcsan.h                               |    8 +-
+ kernel/kcsan/report.c                              |  455 +++++---
+ kernel/locking/locktorture.c                       |   14 +-
+ kernel/rcu/Kconfig                                 |   46 +-
+ kernel/rcu/Kconfig.debug                           |   15 +-
+ kernel/rcu/rcu.h                                   |    7 +
+ kernel/rcu/rcuperf.c                               |    5 +-
+ kernel/rcu/rcutorture.c                            |  155 ++-
+ kernel/rcu/srcutree.c                              |   21 +-
+ kernel/rcu/tasks.h                                 | 1189 ++++++++++++++++++++
+ kernel/rcu/tree.c                                  |  179 ++-
+ kernel/rcu/tree.h                                  |    3 +
+ kernel/rcu/tree_exp.h                              |   50 +-
+ kernel/rcu/tree_plugin.h                           |   86 +-
+ kernel/rcu/tree_stall.h                            |  144 ++-
+ kernel/rcu/update.c                                |  394 +------
+ kernel/sched/core.c                                |   48 +
+ kernel/trace/Kconfig                               |    1 +
+ kernel/trace/ftrace.c                              |   17 +-
+ lib/Kconfig.kcsan                                  |   39 +-
+ tools/memory-model/Documentation/explanation.txt   |   83 +-
+ tools/memory-model/Documentation/references.txt    |   21 +-
+ tools/memory-model/README                          |   10 +-
+ tools/memory-model/litmus-tests/.gitignore         |    2 +-
+ tools/memory-model/litmus-tests/README             |    3 -
+ tools/memory-model/scripts/README                  |   16 +-
+ tools/memory-model/scripts/checkalllitmus.sh       |   29 +-
+ tools/memory-model/scripts/checkghlitmus.sh        |   11 +-
+ tools/memory-model/scripts/checklitmus.sh          |   25 +-
+ tools/memory-model/scripts/checklitmushist.sh      |    2 +-
+ tools/memory-model/scripts/checktheselitmus.sh     |   43 +
+ tools/memory-model/scripts/cmplitmushist.sh        |   49 +-
+ tools/memory-model/scripts/hwfnseg.sh              |   20 +
+ tools/memory-model/scripts/initlitmushist.sh       |    2 +-
+ tools/memory-model/scripts/judgelitmus.sh          |  120 +-
+ tools/memory-model/scripts/newlitmushist.sh        |    4 +-
+ tools/memory-model/scripts/parseargs.sh            |   21 +-
+ tools/memory-model/scripts/runlitmus.sh            |   80 ++
+ tools/memory-model/scripts/runlitmushist.sh        |   29 +-
+ tools/memory-model/scripts/simpletest.sh           |   35 +
+ tools/objtool/check.c                              |    2 +
+ .../selftests/rcutorture/bin/kcsan-collapse.sh     |   22 +
+ .../selftests/rcutorture/bin/kvm-recheck-rcu.sh    |   16 +-
+ .../selftests/rcutorture/bin/kvm-recheck.sh        |    9 +
+ .../selftests/rcutorture/bin/kvm-test-1-run.sh     |   52 +-
+ tools/testing/selftests/rcutorture/bin/kvm.sh      |   11 +
+ .../selftests/rcutorture/configs/rcu/CFLIST        |    3 +
+ .../selftests/rcutorture/configs/rcu/RUDE01        |   10 +
+ .../selftests/rcutorture/configs/rcu/RUDE01.boot   |    1 +
+ .../selftests/rcutorture/configs/rcu/TRACE01       |   11 +
+ .../selftests/rcutorture/configs/rcu/TRACE01.boot  |    1 +
+ .../selftests/rcutorture/configs/rcu/TRACE02       |   11 +
+ .../selftests/rcutorture/configs/rcu/TRACE02.boot  |    1 +
+ .../selftests/rcutorture/configs/rcu/TREE10        |    2 +-
+ 85 files changed, 3654 insertions(+), 1132 deletions(-)
+ create mode 100644 Documentation/litmus-tests/README
+ create mode 100644 Documentation/litmus-tests/atomic/Atomic-RMW+mb__after_atomic-is-stronger-than-acquire.litmus
+ create mode 100644 Documentation/litmus-tests/atomic/Atomic-RMW-ops-are-atomic-WRT-atomic_set.litmus
+ create mode 100644 Documentation/litmus-tests/atomic/README
+ rename {tools/memory-model/litmus-tests => Documentation/litmus-tests/rcu}/MP+onceassign+derefonce.litmus (100%)
+ create mode 100644 Documentation/litmus-tests/rcu/RCU+sync+free.litmus
+ create mode 100644 Documentation/litmus-tests/rcu/RCU+sync+read.litmus
+ create mode 100644 include/linux/rcupdate_trace.h
+ create mode 100644 kernel/rcu/tasks.h
+ create mode 100755 tools/memory-model/scripts/checktheselitmus.sh
+ create mode 100755 tools/memory-model/scripts/hwfnseg.sh
+ create mode 100755 tools/memory-model/scripts/runlitmus.sh
+ create mode 100755 tools/memory-model/scripts/simpletest.sh
+ create mode 100755 tools/testing/selftests/rcutorture/bin/kcsan-collapse.sh
+ create mode 100644 tools/testing/selftests/rcutorture/configs/rcu/RUDE01
+ create mode 100644 tools/testing/selftests/rcutorture/configs/rcu/RUDE01.boot
+ create mode 100644 tools/testing/selftests/rcutorture/configs/rcu/TRACE01
+ create mode 100644 tools/testing/selftests/rcutorture/configs/rcu/TRACE01.boot
+ create mode 100644 tools/testing/selftests/rcutorture/configs/rcu/TRACE02
+ create mode 100644 tools/testing/selftests/rcutorture/configs/rcu/TRACE02.boot
+Merging kvm/linux-next (dbef2808af6c KVM: VMX: fix crash cleanup when KVM wasn't used)
+$ git merge kvm/linux-next
+Already up to date.
+Merging kvm-arm/next (463050599742 Merge tag 'kvm-arm-removal' into kvmarm-master/next)
+$ git merge kvm-arm/next
+Already up to date.
+Merging kvm-ppc/kvm-ppc-next (9a5788c615f5 KVM: PPC: Book3S HV: Add a capability for enabling secure guests)
+$ git merge kvm-ppc/kvm-ppc-next
+Already up to date.
+Merging kvms390/next (7a2653612bb6 s390/gmap: return proper error code on ksm unsharing)
+$ git merge kvms390/next
+Already up to date.
+Merging xen-tip/linux-next (6b51fd3f65a2 xen/xenbus: ensure xenbus_map_ring_valloc() returns proper grant status)
+$ git merge xen-tip/linux-next
+Merge made by the 'recursive' strategy.
+ drivers/xen/xenbus/xenbus_client.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+Merging percpu/for-next (dedac37ea96b Merge branch 'for-5.7' into for-next)
+$ git merge percpu/for-next
+Already up to date!
+Merge made by the 'recursive' strategy.
+Merging workqueues/for-next (4acf8a423cd3 Merge branch 'for-5.7' into for-next)
+$ git merge workqueues/for-next
+Already up to date!
+Merge made by the 'recursive' strategy.
+Merging drivers-x86/for-next (8f3d9f354286 Linux 5.7-rc1)
+$ git merge drivers-x86/for-next
+Already up to date.
+Merging chrome-platform/for-next (9d33ea331032 platform/chrome: cros_ec_typec: Register port partner)
+$ git merge chrome-platform/for-next
+Merge made by the 'recursive' strategy.
+ drivers/platform/chrome/Kconfig            |   1 +
+ drivers/platform/chrome/chromeos_pstore.c  |   1 +
+ drivers/platform/chrome/cros_ec_ishtp.c    |  45 ++++++++---
+ drivers/platform/chrome/cros_ec_typec.c    | 119 ++++++++++++++++++++++++-----
+ drivers/platform/chrome/wilco_ec/debugfs.c |   7 +-
+ 5 files changed, 143 insertions(+), 30 deletions(-)
+Merging hsi/for-next (bb6d3fb354c5 Linux 5.6-rc1)
+$ git merge hsi/for-next
+Already up to date.
+Merging leds/for-next (10a6cce3c1a1 Group LED functions according to functionality, and add some explaining comments.)
+$ git merge leds/for-next
+Auto-merging drivers/leds/Makefile
+CONFLICT (content): Merge conflict in drivers/leds/Makefile
+Resolved 'drivers/leds/Makefile' using previous resolution.
+Automatic merge failed; fix conflicts and then commit the result.
+$ git commit --no-edit -v -a
+[master 1568280d8132] Merge remote-tracking branch 'leds/for-next'
+$ git diff -M --stat --summary HEAD^..
+ drivers/leds/Kconfig             |  14 ++
+ drivers/leds/Makefile            |   1 +
+ drivers/leds/leds-turris-omnia.c | 295 +++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 310 insertions(+)
+ create mode 100644 drivers/leds/leds-turris-omnia.c
+Merging ipmi/for-next (ab032f08dc45 ipmi:bt-bmc: Avoid unnecessary check)
+$ git merge ipmi/for-next
+Merge made by the 'recursive' strategy.
+ drivers/char/ipmi/bt-bmc.c | 3 ---
+ 1 file changed, 3 deletions(-)
+Merging driver-core/driver-core-next (8f3d9f354286 Linux 5.7-rc1)
+$ git merge driver-core/driver-core-next
+Already up to date.
+Merging usb/usb-next (8f3d9f354286 Linux 5.7-rc1)
+$ git merge usb/usb-next
+Already up to date.
+Merging usb-gadget/next (4a5dbd900957 dt-bindings: usb: add documentation for aspeed usb-vhub)
+$ git merge usb-gadget/next
+Already up to date.
+Merging usb-serial/usb-next (8f3d9f354286 Linux 5.7-rc1)
+$ git merge usb-serial/usb-next
+Already up to date.
+Merging usb-chipidea-next/ci-for-usb-next (95caa2ae70fd usb: chipidea: allow disabling glue drivers if EMBEDDED)
+$ git merge usb-chipidea-next/ci-for-usb-next
+Removing drivers/usb/chipidea/ci_hdrc_zevio.c
+Merge made by the 'recursive' strategy.
+ drivers/usb/chipidea/Kconfig         | 37 ++++++++++++++------
+ drivers/usb/chipidea/Makefile        | 13 +++----
+ drivers/usb/chipidea/ci_hdrc_usb2.c  | 30 +++++++++-------
+ drivers/usb/chipidea/ci_hdrc_zevio.c | 67 ------------------------------------
+ drivers/usb/chipidea/core.c          | 42 +++++-----------------
+ drivers/usb/chipidea/udc.h           |  5 +--
+ 6 files changed, 58 insertions(+), 136 deletions(-)
+ delete mode 100644 drivers/usb/chipidea/ci_hdrc_zevio.c
+Merging phy-next/next (8f3d9f354286 Linux 5.7-rc1)
+$ git merge phy-next/next
+Already up to date.
+Merging tty/tty-next (8f3d9f354286 Linux 5.7-rc1)
+$ git merge tty/tty-next
+Already up to date.
+Merging char-misc/char-misc-next (8f3d9f354286 Linux 5.7-rc1)
+$ git merge char-misc/char-misc-next
+Already up to date.
+Merging extcon/extcon-next (8f3d9f354286 Linux 5.7-rc1)
+$ git merge extcon/extcon-next
+Already up to date.
+Merging soundwire/next (8f3d9f354286 Linux 5.7-rc1)
+$ git merge soundwire/next
+Already up to date.
+Merging thunderbolt/next (cbb5494ebce5 Revert "thunderbolt: Prevent crash if non-active NVMem file is read")
+$ git merge thunderbolt/next
+Merge made by the 'recursive' strategy.
+ drivers/thunderbolt/switch.c | 7 -------
+ 1 file changed, 7 deletions(-)
+Merging staging/staging-next (ce920326663b staging: vt6656: formulate rspinf values into tables)
+$ git merge staging/staging-next
+Removing drivers/staging/mt7621-pci-phy/mediatek,mt7621-pci-phy.txt
+Merge made by the 'recursive' strategy.
+ drivers/staging/android/ion/ion_page_pool.c        |   4 +-
+ drivers/staging/axis-fifo/axis-fifo.c              |  12 +-
+ drivers/staging/comedi/comedi_internal.h           |   4 +-
+ drivers/staging/fsl-dpaa2/ethsw/ethsw.c            |   6 +-
+ drivers/staging/gdm724x/gdm_lte.c                  |   2 +-
+ drivers/staging/greybus/hid.c                      |   3 +-
+ drivers/staging/greybus/light.c                    |   3 +-
+ drivers/staging/mt7621-dts/mt7621.dtsi             |   9 +-
+ .../mt7621-pci-phy/mediatek,mt7621-pci-phy.txt     |  28 -
+ .../mt7621-pci-phy/mediatek,mt7621-pci-phy.yaml    |  36 ++
+ drivers/staging/mt7621-pci/pci-mt7621.c            |  48 +-
+ drivers/staging/rtl8188eu/core/rtw_ap.c            |  99 +--
+ drivers/staging/rtl8188eu/core/rtw_efuse.c         |  33 +-
+ drivers/staging/rtl8188eu/core/rtw_ieee80211.c     |   4 +-
+ drivers/staging/rtl8188eu/core/rtw_led.c           |  17 +-
+ drivers/staging/rtl8188eu/core/rtw_mlme_ext.c      |   6 +-
+ drivers/staging/rtl8188eu/hal/odm.c                |  52 +-
+ drivers/staging/rtl8188eu/hal/phy.c                |   8 +-
+ drivers/staging/rtl8188eu/hal/rf.c                 |   2 +-
+ drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c       |   2 +-
+ drivers/staging/rtl8188eu/include/osdep_service.h  |   2 +-
+ drivers/staging/rtl8188eu/os_dep/ioctl_linux.c     | 116 ++--
+ drivers/staging/rtl8188eu/os_dep/rtw_android.c     |   2 +-
+ drivers/staging/rtl8192e/rtl8192e/rtl_dm.c         |   8 +-
+ drivers/staging/rtl8712/rtl871x_xmit.c             | 158 +++--
+ drivers/staging/rtl8712/rtl871x_xmit.h             |   2 +-
+ drivers/staging/rtl8723bs/hal/hal_com_phycfg.c     |   8 +-
+ drivers/staging/rtl8723bs/hal/odm.h                |   2 +-
+ drivers/staging/rtl8723bs/hal/odm_RegDefine11N.h   |   4 +-
+ drivers/staging/rtl8723bs/include/hal_data.h       |   8 +-
+ drivers/staging/sm750fb/sm750.c                    |   4 +-
+ drivers/staging/unisys/visorhba/visorhba_main.c    |   2 +-
+ .../vc04_services/bcm2835-camera/bcm2835-camera.c  | 382 ++++++------
+ .../vc04_services/bcm2835-camera/bcm2835-camera.h  |  62 +-
+ .../vc04_services/bcm2835-camera/controls.c        |  97 ++-
+ .../vc04_services/bcm2835-camera/mmal-common.h     |  18 +-
+ .../vc04_services/bcm2835-camera/mmal-parameters.h |  14 +-
+ .../vc04_services/interface/vchiq_arm/vchiq_arm.c  |   4 +-
+ drivers/staging/vt6655/baseband.c                  | 320 +++++-----
+ drivers/staging/vt6655/baseband.h                  |  37 +-
+ drivers/staging/vt6655/card.c                      | 145 +----
+ drivers/staging/vt6655/card.h                      |   4 -
+ drivers/staging/vt6655/channel.c                   |   4 +-
+ drivers/staging/vt6655/device_main.c               |  36 +-
+ drivers/staging/vt6655/rf.c                        |   4 +-
+ drivers/staging/vt6655/rxtx.c                      | 189 +++---
+ drivers/staging/vt6656/baseband.c                  | 399 ++++--------
+ drivers/staging/vt6656/card.c                      | 286 ++-------
+ drivers/staging/vt6656/device.h                    |   1 -
+ drivers/staging/vt6656/mac.h                       |   2 +-
+ drivers/staging/vt6656/main_usb.c                  |  22 +-
+ drivers/staging/vt6656/rf.c                        | 158 ++---
+ drivers/staging/vt6656/rf.h                        |   3 +-
+ drivers/staging/vt6656/rxtx.c                      |  15 +-
+ drivers/staging/vt6656/wcmd.c                      |   3 +-
+ drivers/staging/wfx/Makefile                       |   1 +
+ drivers/staging/wfx/bh.c                           |   4 +-
+ drivers/staging/wfx/data_tx.c                      | 216 +++----
+ drivers/staging/wfx/data_tx.h                      |   7 +-
+ drivers/staging/wfx/hif_api_cmd.h                  | 625 ++++++++++---------
+ drivers/staging/wfx/hif_api_general.h              | 429 +++++--------
+ drivers/staging/wfx/hif_api_mib.h                  | 671 ++++++++-------------
+ drivers/staging/wfx/hif_tx.c                       |   6 +-
+ drivers/staging/wfx/hif_tx_mib.c                   | 397 ++++++++++++
+ drivers/staging/wfx/hif_tx_mib.h                   | 435 ++-----------
+ drivers/staging/wfx/key.c                          |   1 +
+ drivers/staging/wfx/main.c                         |   8 +-
+ drivers/staging/wfx/queue.c                        | 515 +++++-----------
+ drivers/staging/wfx/queue.h                        |  39 +-
+ drivers/staging/wfx/scan.c                         |   4 +-
+ drivers/staging/wfx/sta.c                          | 333 ++++------
+ drivers/staging/wfx/sta.h                          |   6 +-
+ drivers/staging/wfx/wfx.h                          |   9 +-
+ 73 files changed, 2732 insertions(+), 3873 deletions(-)
+ delete mode 100644 drivers/staging/mt7621-pci-phy/mediatek,mt7621-pci-phy.txt
+ create mode 100644 drivers/staging/mt7621-pci-phy/mediatek,mt7621-pci-phy.yaml
+ create mode 100644 drivers/staging/wfx/hif_tx_mib.c
+Merging mux/for-next (f356d58c3a04 Merge branch 'i2c-mux/for-next' into for-next)
+$ git merge mux/for-next
+Already up to date!
+Merge made by the 'recursive' strategy.
+Merging icc/icc-next (03c4e6186bbb interconnect: qcom: Add OSM L3 support on SC7180)
+$ git merge icc/icc-next
+Already up to date.
+Merging slave-dma/next (c2ce6bbcfc9f dmaengine: idxd: export hw version through sysfs)
+$ git merge slave-dma/next
+Merge made by the 'recursive' strategy.
+ Documentation/ABI/stable/sysfs-driver-dma-idxd |  6 ++++++
+ drivers/dma/idxd/sysfs.c                       | 11 +++++++++++
+ drivers/dma/ti/Kconfig                         |  4 ++--
+ drivers/dma/ti/k3-udma.c                       |  2 +-
+ 4 files changed, 20 insertions(+), 3 deletions(-)
+Merging cgroup/for-next (eec8fd0277e3 device_cgroup: Cleanup cgroup eBPF device filter code)
+$ git merge cgroup/for-next
+Auto-merging drivers/gpu/drm/amd/amdkfd/kfd_priv.h
+Merge made by the 'recursive' strategy.
+ drivers/gpu/drm/amd/amdkfd/kfd_priv.h |  2 +-
+ fs/xattr.c                            |  6 +++---
+ include/linux/device_cgroup.h         | 14 +++++---------
+ kernel/cgroup/rstat.c                 | 16 +++-------------
+ security/Makefile                     |  2 +-
+ security/device_cgroup.c              | 19 ++++++++++++++++---
+ 6 files changed, 29 insertions(+), 30 deletions(-)
+Merging scsi/for-next (8d5e0fd1f288 Merge branch 'misc' into for-next)
+$ git merge scsi/for-next
+Merge made by the 'recursive' strategy.
+ drivers/message/fusion/mptbase.c |  8 ++--
+ drivers/scsi/qedf/qedf_els.c     | 10 ++---
+ drivers/scsi/qedi/qedi_iscsi.c   | 17 +++++---
+ drivers/scsi/qedi/qedi_main.c    | 11 +++--
+ drivers/scsi/qla2xxx/qla_init.c  | 92 ++++++++++++++++++++++------------------
+ 5 files changed, 75 insertions(+), 63 deletions(-)
+Merging scsi-mkp/for-next (1e4ffb8344c5 scsi: libsas: Add missing annotation for sas_ata_qc_issue())
+$ git merge scsi-mkp/for-next
+Auto-merging drivers/scsi/qla2xxx/qla_dbg.c
+Merge made by the 'recursive' strategy.
+ drivers/scsi/bfa/bfa_core.c                 |  2 +-
+ drivers/scsi/bfa/bfa_fcpim.c                |  4 ++--
+ drivers/scsi/bfa/bfa_fcs_lport.c            |  2 +-
+ drivers/scsi/bfa/bfa_ioc_ct.c               |  4 ++--
+ drivers/scsi/bfa/bfa_svc.c                  |  4 ++--
+ drivers/scsi/bfa/bfad.c                     |  2 +-
+ drivers/scsi/bfa/bfad_attr.c                |  4 ++--
+ drivers/scsi/gdth.c                         |  4 ++--
+ drivers/scsi/ipr.c                          |  2 +-
+ drivers/scsi/libsas/sas_ata.c               |  1 +
+ drivers/scsi/megaraid/megaraid_mbox.c       |  6 ++---
+ drivers/scsi/megaraid/megaraid_sas_base.c   |  4 ++--
+ drivers/scsi/megaraid/megaraid_sas_fp.c     | 12 +++++-----
+ drivers/scsi/megaraid/megaraid_sas_fusion.c |  6 ++---
+ drivers/scsi/qla1280.c                      |  4 ++--
+ drivers/scsi/qla2xxx/qla_dbg.c              | 36 ++++++++++++++---------------
+ 16 files changed, 49 insertions(+), 48 deletions(-)
+Merging vhost/linux-next (1f8209a5564a virtio-balloon: Avoid using the word 'report' when referring to free page hinting)
+$ git merge vhost/linux-next
+Auto-merging drivers/gpu/drm/virtio/virtgpu_ioctl.c
+Merge made by the 'recursive' strategy.
+ drivers/char/hw_random/virtio-rng.c    |  1 +
+ drivers/gpu/drm/virtio/virtgpu_ioctl.c |  1 +
+ drivers/gpu/drm/virtio/virtgpu_kms.c   |  1 +
+ drivers/misc/mic/Kconfig               |  2 +-
+ drivers/net/caif/Kconfig               |  2 +-
+ drivers/remoteproc/remoteproc_sysfs.c  |  1 +
+ drivers/remoteproc/stm32_rproc.c       |  1 +
+ drivers/rpmsg/mtk_rpmsg.c              |  1 +
+ drivers/vdpa/Kconfig                   | 18 ++++++------------
+ drivers/vdpa/ifcvf/ifcvf_base.c        |  2 --
+ drivers/vdpa/ifcvf/ifcvf_main.c        |  4 +---
+ drivers/vdpa/vdpa.c                    |  2 +-
+ drivers/vdpa/vdpa_sim/vdpa_sim.c       |  4 ++--
+ drivers/vhost/Kconfig                  | 21 ++++++++++++++++-----
+ drivers/vhost/net.c                    | 28 +++++++++++++++-------------
+ drivers/vhost/scsi.c                   | 14 +++++++-------
+ drivers/vhost/test.c                   | 14 +++++++-------
+ drivers/vhost/vdpa.c                   |  5 -----
+ drivers/vhost/vhost.h                  | 27 +++++++++++++++++++++++++++
+ drivers/vhost/vringh.c                 |  5 +++++
+ drivers/vhost/vsock.c                  | 14 +++++++-------
+ drivers/virtio/Kconfig                 |  2 +-
+ drivers/virtio/virtio_balloon.c        |  4 ++--
+ drivers/virtio/virtio_input.c          |  1 +
+ drivers/virtio/virtio_mmio.c           |  4 +---
+ drivers/virtio/virtio_pci_modern.c     |  1 +
+ include/linux/vdpa.h                   |  2 +-
+ include/linux/vringh.h                 |  6 ++++++
+ include/uapi/linux/virtio_balloon.h    | 11 +++++++++--
+ include/uapi/linux/virtio_ring.h       |  4 ++++
+ tools/virtio/Makefile                  |  5 +++--
+ tools/virtio/asm/barrier.h             |  1 +
+ tools/virtio/generated/autoconf.h      |  0
+ tools/virtio/linux/compiler.h          |  1 +
+ 34 files changed, 133 insertions(+), 77 deletions(-)
+ create mode 100644 tools/virtio/generated/autoconf.h
+Merging rpmsg/for-next (ee7cef848adf Merge branches 'hwspinlock-next', 'rpmsg-next' and 'rproc-next' into for-next)
+$ git merge rpmsg/for-next
+Merge made by the 'recursive' strategy.
+ drivers/remoteproc/mtk_common.h         |  2 +-
+ drivers/remoteproc/mtk_scp.c            |  6 +++---
+ drivers/remoteproc/qcom_q6v5_mss.c      | 33 ++++++++++++++++++++-------------
+ drivers/remoteproc/remoteproc_debugfs.c | 28 ++++------------------------
+ drivers/rpmsg/rpmsg_core.c              |  2 +-
+ 5 files changed, 29 insertions(+), 42 deletions(-)
+Merging gpio/for-next (bbcb9d87dfa9 gpio: mlxbf2: remove unused including <linux/version.h>)
+$ git merge gpio/for-next
+Auto-merging MAINTAINERS
+Removing Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt
+Merge made by the 'recursive' strategy.
+ .../devicetree/bindings/gpio/snps,dw-apb-gpio.yaml | 134 +++++++++++
+ .../devicetree/bindings/gpio/snps-dwapb-gpio.txt   |  65 ------
+ MAINTAINERS                                        |   1 +
+ drivers/gpio/gpio-dwapb.c                          | 244 +++++++++------------
+ drivers/gpio/gpio-mlxbf2.c                         |   1 -
+ drivers/gpio/gpiolib-acpi.c                        |   6 +-
+ 6 files changed, 242 insertions(+), 209 deletions(-)
+ create mode 100644 Documentation/devicetree/bindings/gpio/snps,dw-apb-gpio.yaml
+ delete mode 100644 Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt
+Merging gpio-brgl/gpio/for-next (96d7c7b3e654 gpio: gpio-pca953x, Add get_multiple function)
+$ git merge gpio-brgl/gpio/for-next
+Merge made by the 'recursive' strategy.
+ drivers/gpio/Kconfig         |  2 +-
+ drivers/gpio/TODO            |  4 ++++
+ drivers/gpio/gpio-pca953x.c  | 37 +++++++++++++++++++++++++++++++++++++
+ drivers/gpio/gpio-pl061.c    |  9 ++++-----
+ drivers/gpio/gpio-xgene-sb.c |  2 +-
+ drivers/gpio/gpiolib-of.c    | 10 ++++++++++
+ 6 files changed, 57 insertions(+), 7 deletions(-)
+Merging gpio-intel/for-next (8f3d9f354286 Linux 5.7-rc1)
+$ git merge gpio-intel/for-next
+Already up to date.
+Merging pinctrl/for-next (aeddc3b78266 Merge branch 'devel' into for-next)
+$ git merge pinctrl/for-next
+Removing include/linux/spi/mcp23s08.h
+Merge made by the 'recursive' strategy.
+ .../devicetree/bindings/arm/freescale/fsl,scu.txt  |   6 +-
+ drivers/pinctrl/Kconfig                            |  13 +-
+ drivers/pinctrl/Makefile                           |   2 +
+ drivers/pinctrl/actions/pinctrl-s700.c             |   2 +-
+ drivers/pinctrl/freescale/Kconfig                  |   7 +
+ drivers/pinctrl/freescale/Makefile                 |   1 +
+ drivers/pinctrl/freescale/pinctrl-imx8dxl.c        | 193 +++++++
+ drivers/pinctrl/mediatek/Kconfig                   |  13 +-
+ drivers/pinctrl/mediatek/Makefile                  |   5 +-
+ drivers/pinctrl/mediatek/mtk-eint.c                |   9 +
+ drivers/pinctrl/mediatek/pinctrl-mt6765.c          |   4 +
+ drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c   |  24 +
+ drivers/pinctrl/mediatek/pinctrl-paris.c           |   8 +-
+ drivers/pinctrl/nomadik/pinctrl-nomadik.c          |   4 +-
+ drivers/pinctrl/pinctrl-mcp23s08.c                 | 515 +----------------
+ drivers/pinctrl/pinctrl-mcp23s08.h                 |  52 ++
+ drivers/pinctrl/pinctrl-mcp23s08_i2c.c             | 124 ++++
+ drivers/pinctrl/pinctrl-mcp23s08_spi.c             | 262 +++++++++
+ drivers/pinctrl/qcom/pinctrl-msm.c                 |   3 +-
+ drivers/pinctrl/sunxi/pinctrl-sun8i-a23-r.c        |   7 +-
+ include/dt-bindings/pinctrl/pads-imx8dxl.h         | 639 +++++++++++++++++++++
+ include/linux/spi/mcp23s08.h                       |  18 -
+ 22 files changed, 1377 insertions(+), 534 deletions(-)
+ create mode 100644 drivers/pinctrl/freescale/pinctrl-imx8dxl.c
+ create mode 100644 drivers/pinctrl/pinctrl-mcp23s08.h
+ create mode 100644 drivers/pinctrl/pinctrl-mcp23s08_i2c.c
+ create mode 100644 drivers/pinctrl/pinctrl-mcp23s08_spi.c
+ create mode 100644 include/dt-bindings/pinctrl/pads-imx8dxl.h
+ delete mode 100644 include/linux/spi/mcp23s08.h
+Merging pinctrl-intel/for-next (5f3b82a168d5 pinctrl: lynxpoint: Use platform_get_irq_optional() explicitly)
+$ git merge pinctrl-intel/for-next
+Merge made by the 'recursive' strategy.
+ drivers/pinctrl/intel/Kconfig              |   8 +
+ drivers/pinctrl/intel/Makefile             |   1 +
+ drivers/pinctrl/intel/pinctrl-baytrail.c   |   9 +-
+ drivers/pinctrl/intel/pinctrl-cannonlake.c |  58 +++--
+ drivers/pinctrl/intel/pinctrl-cherryview.c | 278 +++++++++--------------
+ drivers/pinctrl/intel/pinctrl-icelake.c    |  30 ++-
+ drivers/pinctrl/intel/pinctrl-intel.c      |  22 +-
+ drivers/pinctrl/intel/pinctrl-intel.h      |  16 +-
+ drivers/pinctrl/intel/pinctrl-jasperlake.c | 344 +++++++++++++++++++++++++++++
+ drivers/pinctrl/intel/pinctrl-lynxpoint.c  |  10 +-
+ drivers/pinctrl/intel/pinctrl-tigerlake.c  |  32 ++-
+ 11 files changed, 554 insertions(+), 254 deletions(-)
+ create mode 100644 drivers/pinctrl/intel/pinctrl-jasperlake.c
+Merging pinctrl-samsung/for-next (b577a2799140 pinctrl: samsung: Correct setting of eint wakeup mask on s5pv210)
+$ git merge pinctrl-samsung/for-next
+Merge made by the 'recursive' strategy.
+ drivers/pinctrl/samsung/pinctrl-exynos.c | 73 +++++++++++++++++++++-----------
+ 1 file changed, 49 insertions(+), 24 deletions(-)
+Merging pwm/for-next (6f0841a8197b pwm: Add support for Azoteq IQS620A PWM generator)
+$ git merge pwm/for-next
+Merge made by the 'recursive' strategy.
+ .../devicetree/bindings/pwm/renesas,pwm-rcar.yaml  |   1 +
+ drivers/pwm/Kconfig                                |  10 +
+ drivers/pwm/Makefile                               |   1 +
+ drivers/pwm/core.c                                 |   2 +-
+ drivers/pwm/pwm-iqs620a.c                          | 270 +++++++++++++++++++++
+ 5 files changed, 283 insertions(+), 1 deletion(-)
+ create mode 100644 drivers/pwm/pwm-iqs620a.c
+Merging userns/for-next (4fa3b1c41737 proc: Handle umounts cleanly)
+$ git merge userns/for-next
+Merge made by the 'recursive' strategy.
+ fs/proc/root.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+Merging ktest/for-next (1091c8fce8aa ktest: Fix typos in ktest.pl)
+$ git merge ktest/for-next
+Already up to date.
+Merging random/dev (ab9a7e27044b random: avoid warnings for !CONFIG_NUMA builds)
+$ git merge random/dev
+Already up to date.
+Merging kselftest/next (b87080eab4c1 selftests/ipc: Fix test failure seen after initial test run)
+$ git merge kselftest/next
+Merge made by the 'recursive' strategy.
+ tools/testing/selftests/ftrace/config         |  1 +
+ tools/testing/selftests/ipc/msgque.c          |  2 +-
+ tools/testing/selftests/kselftest/runner.sh   |  2 +-
+ tools/testing/selftests/kselftest_harness.h   |  6 +++---
+ tools/testing/selftests/memfd/Makefile        |  3 ++-
+ tools/testing/selftests/seccomp/seccomp_bpf.c | 14 ++++++++------
+ tools/testing/selftests/tpm2/test_smoke.sh    | 13 ++-----------
+ tools/testing/selftests/tpm2/test_space.sh    |  9 +--------
+ tools/testing/selftests/vm/Makefile           |  4 ++--
+ tools/testing/selftests/vm/run_vmtests        |  2 +-
+ 10 files changed, 22 insertions(+), 34 deletions(-)
+Merging y2038/y2038 (c4e71212a245 Revert "drm/etnaviv: reject timeouts with tv_nsec >= NSEC_PER_SEC")
+$ git merge y2038/y2038
+Already up to date.
+Merging livepatching/for-next (d28b4c1b2b3d Merge branch 'for-5.6/selftests' into for-next)
+$ git merge livepatching/for-next
+Already up to date!
+Merge made by the 'recursive' strategy.
+Merging coresight/next (25a0b4731117 coresight: Fix support for sparsely populated ports)
+$ git merge coresight/next
+Merge made by the 'recursive' strategy.
+ Documentation/trace/coresight/coresight-ect.rst  |   6 +-
+ Documentation/trace/coresight/coresight.rst      |  85 ++++++++++
+ drivers/hwtracing/coresight/Makefile             |   3 +-
+ drivers/hwtracing/coresight/coresight-cti.c      |  58 ++++++-
+ drivers/hwtracing/coresight/coresight-etb10.c    |   2 +-
+ drivers/hwtracing/coresight/coresight-etm4x.c    |   6 +-
+ drivers/hwtracing/coresight/coresight-platform.c |  87 +++++++---
+ drivers/hwtracing/coresight/coresight-priv.h     |  12 +-
+ drivers/hwtracing/coresight/coresight-sysfs.c    | 204 +++++++++++++++++++++++
+ drivers/hwtracing/coresight/coresight.c          |  82 ++++++---
+ include/linux/coresight.h                        |  32 +++-
+ 11 files changed, 509 insertions(+), 68 deletions(-)
+ create mode 100644 drivers/hwtracing/coresight/coresight-sysfs.c
+Merging rtc/rtc-next (11ddbdfb68e4 rtc: rc5t619: Fix an ERR_PTR vs NULL check)
+$ git merge rtc/rtc-next
+Merge made by the 'recursive' strategy.
+ drivers/rtc/rtc-fsl-ftm-alarm.c | 4 +---
+ drivers/rtc/rtc-lpc24xx.c       | 4 +---
+ drivers/rtc/rtc-mt2712.c        | 4 +---
+ drivers/rtc/rtc-rc5t619.c       | 4 +---
+ 4 files changed, 4 insertions(+), 12 deletions(-)
+Merging nvdimm/libnvdimm-for-next (f6d2b802f80d Merge branch 'for-5.7/libnvdimm' into libnvdimm-for-next)
+$ git merge nvdimm/libnvdimm-for-next
+Already up to date.
+Merging at24/at24/for-next (8f3d9f354286 Linux 5.7-rc1)
+$ git merge at24/at24/for-next
+Already up to date.
+Merging ntb/ntb-next (5cc3de3c7435 NTB: ntb_test: Fix bug when counting remote files)
+$ git merge ntb/ntb-next
+Merge made by the 'recursive' strategy.
+ drivers/ntb/core.c                      |  9 ++-------
+ drivers/ntb/hw/amd/ntb_hw_amd.c         |  4 ----
+ drivers/ntb/hw/idt/ntb_hw_idt.c         |  6 ------
+ drivers/ntb/hw/intel/ntb_hw_gen1.c      |  4 ----
+ drivers/ntb/test/ntb_perf.c             | 33 ++++++++++++++++++++++++---------
+ drivers/ntb/test/ntb_pingpong.c         | 14 ++++++--------
+ drivers/ntb/test/ntb_tool.c             |  9 ++++-----
+ include/linux/ntb.h                     |  2 +-
+ tools/testing/selftests/ntb/ntb_test.sh |  2 +-
+ 9 files changed, 38 insertions(+), 45 deletions(-)
+Merging kspp/for-next/kspp (c7527373fe28 gcc-common.h: Update for GCC 10)
+$ git merge kspp/for-next/kspp
+Merge made by the 'recursive' strategy.
+ scripts/gcc-plugins/Makefile           | 1 +
+ scripts/gcc-plugins/gcc-common.h       | 4 ++++
+ scripts/gcc-plugins/stackleak_plugin.c | 5 ++---
+ 3 files changed, 7 insertions(+), 3 deletions(-)
+Merging cisco/for-next (9e98c678c2d6 Linux 5.1-rc1)
+$ git merge cisco/for-next
+Already up to date.
+Merging gnss/gnss-next (8f3d9f354286 Linux 5.7-rc1)
+$ git merge gnss/gnss-next
+Already up to date.
+Merging fsi/next (2c01397b71c5 fsi: aspeed: Fix OPB0 byte order register values)
+$ git merge fsi/next
+Auto-merging drivers/fsi/Kconfig
+CONFLICT (content): Merge conflict in drivers/fsi/Kconfig
+Resolved 'drivers/fsi/Kconfig' using previous resolution.
+Automatic merge failed; fix conflicts and then commit the result.
+$ git commit --no-edit -v -a
+[master ec70f801f054] Merge remote-tracking branch 'fsi/next'
+$ git diff -M --stat --summary HEAD^..
+Merging slimbus/for-next (8f3d9f354286 Linux 5.7-rc1)
+$ git merge slimbus/for-next
+Already up to date.
+Merging nvmem/for-next (8f3d9f354286 Linux 5.7-rc1)
+$ git merge nvmem/for-next
+Already up to date.
+Merging xarray/xarray (27586ca786a7 XArray: Handle retry entries within xas_find_marked)
+$ git merge xarray/xarray
+Merge made by the 'recursive' strategy.
+ Documentation/core-api/xarray.rst   | 13 +++++++------
+ drivers/infiniband/core/device.c    |  6 +-----
+ include/linux/xarray.h              | 23 +++++++++++++++++++++-
+ lib/idr.c                           |  1 +
+ lib/test_xarray.c                   | 20 +++++++++++++++++++
+ lib/xarray.c                        | 39 +++++++++++++++++++++++++++++++------
+ tools/testing/radix-tree/idr-test.c | 29 +++++++++++++++++++++++++++
+ 7 files changed, 113 insertions(+), 18 deletions(-)
+Merging hyperv/hyperv-next (e66b54d07be4 drivers: hv: remove redundant assignment to pointer primary_channel)
+$ git merge hyperv/hyperv-next
+Auto-merging drivers/pci/controller/pci-hyperv.c
+Auto-merging drivers/net/hyperv/netvsc.c
+Auto-merging drivers/hv/vmbus_drv.c
+Auto-merging drivers/hv/hyperv_vmbus.h
+Auto-merging drivers/hv/channel_mgmt.c
+Merge made by the 'recursive' strategy.
+ drivers/hv/channel.c                |  58 +++--
+ drivers/hv/channel_mgmt.c           | 411 +++++++++++++++++++-----------------
+ drivers/hv/connection.c             |  58 ++---
+ drivers/hv/hv.c                     |  16 +-
+ drivers/hv/hv_fcopy.c               |   2 +-
+ drivers/hv/hv_snapshot.c            |   2 +-
+ drivers/hv/hv_trace.h               |  19 ++
+ drivers/hv/hyperv_vmbus.h           |  33 ++-
+ drivers/hv/vmbus_drv.c              | 281 +++++++++++++++++++-----
+ drivers/net/hyperv/netvsc.c         |   7 +-
+ drivers/pci/controller/pci-hyperv.c |  44 ++--
+ drivers/scsi/storvsc_drv.c          |  95 ++++++++-
+ include/linux/hyperv.h              |  53 ++---
+ 13 files changed, 686 insertions(+), 393 deletions(-)
+Merging auxdisplay/auxdisplay (2f920c0f0e29 auxdisplay: charlcd: replace zero-length array with flexible-array member)
+$ git merge auxdisplay/auxdisplay
+Already up to date.
+Merging kgdb/kgdb/for-next (5ea771abd5a3 kdb: Censor attempts to set PROMPT without ENABLE_MEM_READ)
+$ git merge kgdb/kgdb/for-next
+Merge made by the 'recursive' strategy.
+Merging pidfd/for-next (6952a4f64644 selftests: add pid namespace ENOMEM regression test)
+$ git merge pidfd/for-next
+Already up to date.
+Merging devfreq/devfreq-next (a35a2f2b3e6e PM / devfreq: tegra30: Delete an error message in tegra_devfreq_probe())
+$ git merge devfreq/devfreq-next
+Merge made by the 'recursive' strategy.
+ drivers/devfreq/tegra30-devfreq.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+Merging hmm/hmm (8f3d9f354286 Linux 5.7-rc1)
+$ git merge hmm/hmm
+Already up to date.
+Merging fpga/for-next (cef0ca6417de fpga: dfl: afu: support debug access to memory-mapped afu regions)
+$ git merge fpga/for-next
+Auto-merging arch/arm64/boot/dts/intel/socfpga_agilex.dtsi
+Merge made by the 'recursive' strategy.
+ .../bindings/firmware/intel,stratix10-svc.txt      |  2 +-
+ .../bindings/fpga/intel-stratix10-soc-fpga-mgr.txt |  3 +-
+ arch/arm64/boot/dts/intel/socfpga_agilex.dtsi      |  4 +--
+ drivers/fpga/dfl-afu-main.c                        | 35 +++++++++++++-------
+ drivers/fpga/dfl-fme-main.c                        | 19 +++++++----
+ drivers/fpga/dfl.c                                 | 15 +++++++--
+ drivers/fpga/dfl.h                                 | 37 ++++++++++++++++------
+ drivers/fpga/ice40-spi.c                           | 10 ++++--
+ drivers/fpga/machxo2-spi.c                         | 12 ++++---
+ drivers/fpga/stratix10-soc.c                       |  3 +-
+ 10 files changed, 100 insertions(+), 40 deletions(-)
+Merging kunit/test (8f3d9f354286 Linux 5.7-rc1)
+$ git merge kunit/test
+Already up to date.
+Merging cel/cel-next (36b6e409294a svcrdma: Fix leak of svc_rdma_recv_ctxt objects)
+$ git merge cel/cel-next
+Merge made by the 'recursive' strategy.
+ fs/nfsd/nfs4callback.c                     |  4 ++-
+ fs/nfsd/nfs4state.c                        |  2 ++
+ include/linux/sunrpc/svc_rdma.h            |  1 +
+ include/trace/events/rpcrdma.h             | 50 +++++++++++++++++++++---------
+ net/sunrpc/cache.c                         |  5 +--
+ net/sunrpc/svc_xprt.c                      |  5 ++-
+ net/sunrpc/svcsock.c                       |  4 +++
+ net/sunrpc/xprtrdma/svc_rdma_backchannel.c |  2 ++
+ net/sunrpc/xprtrdma/svc_rdma_recvfrom.c    | 22 +++++++++++++
+ net/sunrpc/xprtrdma/svc_rdma_rw.c          |  3 +-
+ net/sunrpc/xprtrdma/svc_rdma_sendto.c      | 29 +++++++----------
+ net/sunrpc/xprtrdma/svc_rdma_transport.c   |  5 ---
+ net/sunrpc/xprtsock.c                      |  1 +
+ 13 files changed, 89 insertions(+), 44 deletions(-)
+Merging generic-ioremap/for-next (4bdc0d676a64 remove ioremap_nocache and devm_ioremap_nocache)
+$ git merge generic-ioremap/for-next
+Already up to date.
+Merging cfi/cfi/next (b6fe8bc67d2d mtd: hyperbus: move direct mapping setup to AM654 HBMC driver)
+$ git merge cfi/cfi/next
+Already up to date.
+Merging kunit-next/kunit (8f3d9f354286 Linux 5.7-rc1)
+$ git merge kunit-next/kunit
+Already up to date.
+Merging trivial/for-next (fad7c9020948 err.h: remove deprecated PTR_RET for good)
+$ git merge trivial/for-next
+Already up to date.
+Merging zx2c4/for-next (16fbf79b0f83 Linux 5.6-rc7)
+$ git merge zx2c4/for-next
+Already up to date.
+Merging mhi/mhi-next (8f3d9f354286 Linux 5.7-rc1)
+$ git merge mhi/mhi-next
+Already up to date.
+$ git am -3 ../patches/0001-Revert-crypto-hisilicon-qm-stop-qp-by-judging-sq-and.patch
+Applying: Revert "crypto: hisilicon/qm - stop qp by judging sq and cq tail"
+$ git am -3 ../patches/0002-Revert-crypto-hisilicon-sec2-add-controller-reset-su.patch
+Applying: Revert "crypto: hisilicon/sec2 - add controller reset support for SEC2"
+$ git am -3 ../patches/0003-Revert-crypto-hisilicon-hpre-add-controller-reset-su.patch
+Applying: Revert "crypto: hisilicon/hpre - add controller reset support for HPRE"
+$ git am -3 ../patches/0004-Revert-crypto-hisilicon-zip-add-controller-reset-sup.patch
+Applying: Revert "crypto: hisilicon/zip - add controller reset support for zip"
+$ git am -3 ../patches/0005-Revert-crypto-hisilicon-qm-add-controller-reset-inte.patch
+Applying: Revert "crypto: hisilicon/qm - add controller reset interface"
+Merging akpm-current/current (547e35135ac5 usb: core: kcov: collect coverage from usb complete callback)
+$ git merge --no-ff akpm-current/current
+Auto-merging lib/Kconfig.debug
+Auto-merging include/linux/wait.h
+Auto-merging include/linux/sched.h
+Auto-merging fs/buffer.c
+Auto-merging drivers/tty/serial/sh-sci.c
+Auto-merging MAINTAINERS
+Merge made by the 'recursive' strategy.
+ Documentation/dev-tools/kcov.rst |  17 +--
+ MAINTAINERS                      |   7 ++
+ drivers/base/memory.c            |  44 +++++--
+ drivers/hv/hv_balloon.c          |   1 +
+ drivers/tty/serial/sh-sci.c      |   2 +-
+ drivers/usb/core/hcd.c           |   3 +
+ fs/aio.c                         |   9 +-
+ fs/buffer.c                      |  56 ++++++++-
+ fs/exec.c                        |  14 ++-
+ fs/proc/page.c                   |  40 +++---
+ fs/ramfs/inode.c                 |  12 ++
+ include/linux/gfp.h              |   3 +
+ include/linux/list.h             |  50 +++++---
+ include/linux/memremap.h         |   6 +
+ include/linux/nmi.h              |   1 +
+ include/linux/sched.h            |  11 ++
+ include/linux/wait.h             |   4 +-
+ ipc/mqueue.c                     |  34 +++--
+ kernel/hung_task.c               |  44 +++++++
+ kernel/kcov.c                    | 266 +++++++++++++++++++++++++++------------
+ kernel/relay.c                   |  17 ++-
+ kernel/watchdog.c                |  22 ++++
+ kernel/watchdog_hld.c            |   1 +
+ lib/Kconfig.debug                |  15 +++
+ lib/cpumask.c                    | 102 +++++++++++++--
+ mm/memcontrol.c                  |  51 ++++----
+ mm/memremap.c                    |  20 +++
+ mm/mmap.c                        |  43 ++++---
+ mm/page_alloc.c                  |  14 +++
+ 29 files changed, 695 insertions(+), 214 deletions(-)
+$ git clone -s -l -n -q . ../rebase-tmp
+$ cd ../rebase-tmp
+$ git checkout -b akpm remotes/origin/akpm/master
+Switched to a new branch 'akpm'
+$ git rebase --onto master remotes/origin/akpm/master-base
+First, rewinding head to replay your work on top of it...
+Applying: mm/kmemleak: silence KCSAN splats in checksum
+Applying: mm/frontswap: mark various intentional data races
+Applying: mm/page_io: mark various intentional data races
+Applying: mm-page_io-mark-various-intentional-data-races-v2
+Applying: mm/swap_state: mark various intentional data races
+Applying: mm/filemap.c: fix a data race in filemap_fault()
+Applying: mm/swapfile: fix and annotate various data races
+Applying: mm-swapfile-fix-and-annotate-various-data-races-v2
+Applying: mm/page_counter: fix various data races at memsw
+Applying: mm/memcontrol: fix a data race in scan count
+Applying: mm/list_lru: fix a data race in list_lru_count_one
+Applying: mm/mempool: fix a data race in mempool_free()
+Applying: mm/util.c: annotate an data race at vm_committed_as
+Applying: mm/rmap: annotate a data race at tlb_flush_batched
+Applying: mm: annotate a data race in page_zonenum()
+Applying: mm/swap.c: annotate data races for lru_rotate_pvecs
+Applying: net-zerocopy: use vm_insert_pages() for tcp rcv zerocopy
+Applying: net-zerocopy-use-vm_insert_pages-for-tcp-rcv-zerocopy-fix
+Applying: mm/debug: add tests validating architecture page table helpers
+Applying: mm/madvise: pass task and mm to do_madvise
+Applying: mm/madvise: introduce process_madvise() syscall: an external memory hinting API
+Applying: fix process_madvise build break for arm64
+Applying: mm/madvise: check fatal signal pending of target process
+Applying: pid: move pidfd_get_pid() to pid.c
+Applying: mm/madvise: support both pid and pidfd for process_madvise
+Applying: mm/madvise: employ mmget_still_valid() for write lock
+Applying: mm/madvise: allow KSM hints for remote API
+Applying: kexec: prevent removal of memory in use by a loaded kexec image
+Applying: mm/memory_hotplug: allow arch override of non boot memory resource names
+Applying: arm64: memory: give hotplug memory a different resource name
+Applying: drivers/media/platform/sti/delta/delta-ipc.c: fix read buffer overflow
+$ cd ../next
+$ git fetch -f ../rebase-tmp akpm:akpm/master
+From ../rebase-tmp
+ + 572a70db833c...7a330aa1f8db akpm       -> akpm/master  (forced update)
+$ rm -rf ../rebase-tmp
+Merging akpm/master (7a330aa1f8db drivers/media/platform/sti/delta/delta-ipc.c: fix read buffer overflow)
+$ git merge --no-ff akpm/master
+Merge made by the 'recursive' strategy.
+ .../debug/debug-vm-pgtable/arch-support.txt        |  34 ++
+ arch/alpha/kernel/syscalls/syscall.tbl             |   1 +
+ arch/arc/Kconfig                                   |   1 +
+ arch/arm/tools/syscall.tbl                         |   1 +
+ arch/arm64/Kconfig                                 |   1 +
+ arch/arm64/include/asm/memory.h                    |  11 +
+ arch/arm64/include/asm/unistd.h                    |   2 +-
+ arch/arm64/include/asm/unistd32.h                  |   2 +
+ arch/ia64/kernel/syscalls/syscall.tbl              |   1 +
+ arch/m68k/kernel/syscalls/syscall.tbl              |   1 +
+ arch/microblaze/kernel/syscalls/syscall.tbl        |   1 +
+ arch/mips/kernel/syscalls/syscall_n32.tbl          |   1 +
+ arch/mips/kernel/syscalls/syscall_n64.tbl          |   1 +
+ arch/parisc/kernel/syscalls/syscall.tbl            |   1 +
+ arch/powerpc/Kconfig                               |   1 +
+ arch/powerpc/kernel/syscalls/syscall.tbl           |   1 +
+ arch/s390/Kconfig                                  |   1 +
+ arch/s390/kernel/syscalls/syscall.tbl              |   1 +
+ arch/sh/kernel/syscalls/syscall.tbl                |   1 +
+ arch/sparc/kernel/syscalls/syscall.tbl             |   1 +
+ arch/x86/Kconfig                                   |   1 +
+ arch/x86/entry/syscalls/syscall_32.tbl             |   1 +
+ arch/x86/entry/syscalls/syscall_64.tbl             |   1 +
+ arch/x86/include/asm/pgtable_64.h                  |   6 +
+ arch/xtensa/kernel/syscalls/syscall.tbl            |   1 +
+ drivers/media/platform/sti/delta/delta-ipc.c       |   4 +-
+ fs/io_uring.c                                      |   2 +-
+ include/linux/memcontrol.h                         |   2 +-
+ include/linux/mm.h                                 |   4 +-
+ include/linux/mmdebug.h                            |   5 +
+ include/linux/pid.h                                |   1 +
+ include/linux/syscalls.h                           |   3 +
+ include/uapi/asm-generic/unistd.h                  |   4 +-
+ init/main.c                                        |   2 +
+ kernel/exit.c                                      |  17 -
+ kernel/kexec_core.c                                |  56 +++
+ kernel/pid.c                                       |  17 +
+ kernel/sys_ni.c                                    |   1 +
+ lib/Kconfig.debug                                  |  26 ++
+ mm/Makefile                                        |   1 +
+ mm/debug_vm_pgtable.c                              | 392 +++++++++++++++++++++
+ mm/filemap.c                                       |  20 +-
+ mm/frontswap.c                                     |   8 +-
+ mm/kmemleak.c                                      |   2 +
+ mm/list_lru.c                                      |   2 +-
+ mm/madvise.c                                       | 144 ++++++--
+ mm/memory.c                                        |   4 +-
+ mm/memory_hotplug.c                                |   6 +-
+ mm/mempool.c                                       |   2 +-
+ mm/page_counter.c                                  |  13 +-
+ mm/page_io.c                                       |   8 +-
+ mm/rmap.c                                          |   2 +-
+ mm/swap.c                                          |   5 +-
+ mm/swap_state.c                                    |   4 +-
+ mm/swapfile.c                                      |  31 +-
+ mm/util.c                                          |   8 +-
+ net/ipv4/tcp.c                                     |  70 +++-
+ 57 files changed, 841 insertions(+), 100 deletions(-)
+ create mode 100644 Documentation/features/debug/debug-vm-pgtable/arch-support.txt
+ create mode 100644 mm/debug_vm_pgtable.c
diff --git a/Next/quilt-import.log b/Next/quilt-import.log
new file mode 100644
index 000000000000..17761a06ce4d
--- /dev/null
+++ b/Next/quilt-import.log
@@ -0,0 +1,2 @@
+Importing dmi based on 5.6
+Unchanged quilt series dmi
diff --git a/arch/alpha/kernel/syscalls/syscall.tbl b/arch/alpha/kernel/syscalls/syscall.tbl
index 36d42da7466a..c82952e6fb80 100644
--- a/arch/alpha/kernel/syscalls/syscall.tbl
+++ b/arch/alpha/kernel/syscalls/syscall.tbl
@@ -477,3 +477,4 @@
 # 545 reserved for clone3
 547	common	openat2				sys_openat2
 548	common	pidfd_getfd			sys_pidfd_getfd
+549	common	process_madvise			sys_process_madvise
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index ff306246d0f8..471ef22216c4 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -6,6 +6,7 @@
 config ARC
 	def_bool y
 	select ARC_TIMERS
+	select ARCH_HAS_DEBUG_VM_PGTABLE
 	select ARCH_HAS_DMA_PREP_COHERENT
 	select ARCH_HAS_PTE_SPECIAL
 	select ARCH_HAS_SETUP_DMA_OPS
diff --git a/arch/arc/configs/hsdk_defconfig b/arch/arc/configs/hsdk_defconfig
index 0974226fab55..aa000075a575 100644
--- a/arch/arc/configs/hsdk_defconfig
+++ b/arch/arc/configs/hsdk_defconfig
@@ -65,6 +65,7 @@ CONFIG_DRM_UDL=y
 CONFIG_DRM_ETNAVIV=y
 CONFIG_FB=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_HCD_PLATFORM=y
 CONFIG_USB_OHCI_HCD=y
diff --git a/arch/arc/include/asm/entry-arcv2.h b/arch/arc/include/asm/entry-arcv2.h
index ae0aa5323be1..0ff4c0610561 100644
--- a/arch/arc/include/asm/entry-arcv2.h
+++ b/arch/arc/include/asm/entry-arcv2.h
@@ -233,6 +233,8 @@
 
 #ifdef CONFIG_ARC_IRQ_NO_AUTOSAVE
 	__RESTORE_REGFILE_HARD
+
+	; SP points to PC/STAT32: hw restores them despite NO_AUTOSAVE
 	add	sp, sp, SZ_PT_REGS - 8
 #else
 	add	sp, sp, PT_r0
diff --git a/arch/arc/kernel/Makefile b/arch/arc/kernel/Makefile
index 75539670431a..8c4fc4b54c14 100644
--- a/arch/arc/kernel/Makefile
+++ b/arch/arc/kernel/Makefile
@@ -3,9 +3,6 @@
 # Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
 #
 
-# Pass UTS_MACHINE for user_regset definition
-CFLAGS_ptrace.o		+= -DUTS_MACHINE='"$(UTS_MACHINE)"'
-
 obj-y	:= arcksyms.o setup.o irq.o reset.o ptrace.o process.o devtree.o
 obj-y	+= signal.o traps.o sys.o troubleshoot.o stacktrace.o disasm.o
 obj-$(CONFIG_ISA_ARCOMPACT)		+= entry-compact.o intc-compact.o
diff --git a/arch/arc/kernel/ptrace.c b/arch/arc/kernel/ptrace.c
index d5f3fcf273b5..f49a054a1016 100644
--- a/arch/arc/kernel/ptrace.c
+++ b/arch/arc/kernel/ptrace.c
@@ -253,7 +253,7 @@ static const struct user_regset arc_regsets[] = {
 };
 
 static const struct user_regset_view user_arc_view = {
-	.name		= UTS_MACHINE,
+	.name		= "arc",
 	.e_machine	= EM_ARC_INUSE,
 	.regsets	= arc_regsets,
 	.n		= ARRAY_SIZE(arc_regsets)
diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c
index b2b1cb645d9e..dad8a656a2f1 100644
--- a/arch/arc/kernel/setup.c
+++ b/arch/arc/kernel/setup.c
@@ -11,6 +11,7 @@
 #include <linux/clocksource.h>
 #include <linux/console.h>
 #include <linux/module.h>
+#include <linux/sizes.h>
 #include <linux/cpu.h>
 #include <linux/of_clk.h>
 #include <linux/of_fdt.h>
@@ -424,12 +425,12 @@ static void arc_chk_core_config(void)
 	if ((unsigned int)__arc_dccm_base != cpu->dccm.base_addr)
 		panic("Linux built with incorrect DCCM Base address\n");
 
-	if (CONFIG_ARC_DCCM_SZ != cpu->dccm.sz)
+	if (CONFIG_ARC_DCCM_SZ * SZ_1K != cpu->dccm.sz)
 		panic("Linux built with incorrect DCCM Size\n");
 #endif
 
 #ifdef CONFIG_ARC_HAS_ICCM
-	if (CONFIG_ARC_ICCM_SZ != cpu->iccm.sz)
+	if (CONFIG_ARC_ICCM_SZ * SZ_1K != cpu->iccm.sz)
 		panic("Linux built with incorrect ICCM Size\n");
 #endif
 
diff --git a/arch/arc/kernel/unwind.c b/arch/arc/kernel/unwind.c
index 27ea64b1fa33..f87758a6851b 100644
--- a/arch/arc/kernel/unwind.c
+++ b/arch/arc/kernel/unwind.c
@@ -1178,11 +1178,9 @@ int arc_unwind(struct unwind_frame_info *frame)
 #endif
 
 	/* update frame */
-#ifndef CONFIG_AS_CFI_SIGNAL_FRAME
 	if (frame->call_frame
 	    && !UNW_DEFAULT_RA(state.regs[retAddrReg], state.dataAlign))
 		frame->call_frame = 0;
-#endif
 	cfa = FRAME_REG(state.cfa.reg, unsigned long) + state.cfa.offs;
 	startLoc = min_t(unsigned long, UNW_SP(frame), cfa);
 	endLoc = max_t(unsigned long, UNW_SP(frame), cfa);
diff --git a/arch/arc/plat-eznps/Kconfig b/arch/arc/plat-eznps/Kconfig
index a931d0a256d0..a645bca5899a 100644
--- a/arch/arc/plat-eznps/Kconfig
+++ b/arch/arc/plat-eznps/Kconfig
@@ -6,6 +6,7 @@
 
 menuconfig ARC_PLAT_EZNPS
 	bool "\"EZchip\" ARC dev platform"
+	depends on ISA_ARCOMPACT
 	select CPU_BIG_ENDIAN
 	select CLKSRC_NPS if !PHYS_ADDR_T_64BIT
 	select EZNPS_GIC
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 66a04f6f4775..cbd6629e7d75 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -698,6 +698,8 @@ source "arch/arm/mach-qcom/Kconfig"
 
 source "arch/arm/mach-rda/Kconfig"
 
+source "arch/arm/mach-realtek/Kconfig"
+
 source "arch/arm/mach-realview/Kconfig"
 
 source "arch/arm/mach-rockchip/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 7d5cd0f85461..0fb6de83dd50 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -148,6 +148,8 @@ head-y		:= arch/arm/kernel/head$(MMUEXT).o
 textofs-y	:= 0x00008000
 # We don't want the htc bootloader to corrupt kernel during resume
 textofs-$(CONFIG_PM_H1940)      := 0x00108000
+# RTD1195 has Boot ROM at start of address space
+textofs-$(CONFIG_ARCH_REALTEK)  := 0x00108000
 # SA1111 DMA bug: we don't want the kernel to live in precious DMA-able memory
 ifeq ($(CONFIG_ARCH_SA1100),y)
 textofs-$(CONFIG_SA1111) := 0x00208000
@@ -208,6 +210,7 @@ machine-$(CONFIG_ARCH_PICOXCELL)	+= picoxcell
 machine-$(CONFIG_ARCH_PXA)		+= pxa
 machine-$(CONFIG_ARCH_QCOM)		+= qcom
 machine-$(CONFIG_ARCH_RDA)		+= rda
+machine-$(CONFIG_ARCH_REALTEK)		+= realtek
 machine-$(CONFIG_ARCH_REALVIEW)		+= realview
 machine-$(CONFIG_ARCH_ROCKCHIP)		+= rockchip
 machine-$(CONFIG_ARCH_RPC)		+= rpc
diff --git a/arch/arm/arm-soc-for-next-contents.txt b/arch/arm/arm-soc-for-next-contents.txt
new file mode 100644
index 000000000000..c24470ec5b39
--- /dev/null
+++ b/arch/arm/arm-soc-for-next-contents.txt
@@ -0,0 +1,201 @@
+arm/soc
+	renesas/soc
+		git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel tags/renesas-arm-soc-for-v5.7-tag1
+	omap/soc
+		git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v5.7/soc-signed
+	omap/pm33xx
+		git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v5.7/pm33xx-signed
+	broadcom/soc
+		https://github.com/Broadcom/stblinux tags/arm-soc/for-5.7/soc
+	broadcom/soc-arm64
+		https://github.com/Broadcom/stblinux tags/arm-soc/for-5.7/soc-arm64
+	sunxi/soc
+		git://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux tags/sunxi-core-for-5.7
+	stm32/soc
+		git://git.kernel.org/pub/scm/linux/kernel/git/atorgue/stm32 tags/stm32-soc-for-v5.7-1
+	tegra/soc
+		git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux tags/tegra-for-5.7-soc
+		contains tegra/dt-bindings
+	tegra/arm-soc
+		git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux tags/tegra-for-5.7-arm-core
+	mvebu/soc
+		git://git.infradead.org/linux-mvebu tags/mvebu-arm-5.7-1
+	imx/soc
+		git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux tags/imx-soc-5.7
+	mediatek/soc
+		git://git.kernel.org/pub/scm/linux/kernel/git/matthias.bgg/linux tags/v5.6-next-soc
+	at91/soc
+		git://git.kernel.org/pub/scm/linux/kernel/git/at91/linux tags/at91-5.7-soc
+	zynq/soc
+		https://github.com/Xilinx/linux-xlnx tags/zynq-soc-for-v5.7
+	zynq/soc-arm64
+		https://github.com/Xilinx/linux-xlnx tags/zynqmp-soc-for-v5.7
+	tegra/cpuidle
+		git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux tags/tegra-for-5.7-cpuidle
+	patch
+		ARM: iop32x: replace setup_irq() by request_irq()
+		ARM: ep93xx: Replace setup_irq() by request_irq()
+		ARM: spear: replace setup_irq() by request_irq()
+		ARM: cns3xxx: replace setup_irq() by request_irq()
+		ARM: mmp: replace setup_irq() by request_irq()
+
+arm/dt
+	renesas/dt
+		git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel tags/renesas-arm-dt-for-v5.7-tag1
+	renesas/dt64
+		git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel tags/renesas-arm64-dt-for-v5.7-tag1
+	versatile/dt
+		git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator tags/versatile-dts-v5.7-1
+	omap/dt
+		git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v5.7/dt-signed
+	patch
+		arm64: dts: specify console via command line
+	broadcom/devicetree
+		https://github.com/Broadcom/stblinux tags/arm-soc/for-5.7/devicetree
+	sunxi/dt
+		git://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux tags/sunxi-dt-for-5.7
+	renesas/dt-2
+		git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel tags/renesas-arm-dt-for-v5.7-tag2
+	renesas/dt64-2
+		git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel tags/renesas-arm64-dt-for-v5.7-tag2
+	renesas/dt-bindings
+		git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel tags/renesas-dt-bindings-for-v5.7-tag1
+	stm32/dt
+		git://git.kernel.org/pub/scm/linux/kernel/git/atorgue/stm32 tags/stm32-dt-for-v5.7-1
+	tegra/dt-bindings
+		git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux tags/tegra-for-5.7-dt-bindings
+	tegra/dt
+		git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux tags/tegra-for-5.7-arm-dt
+	tegra/dt64
+		git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux tags/tegra-for-5.7-arm64-dt
+	mvebu/dt64
+		git://git.infradead.org/linux-mvebu tags/mvebu-dt64-5.7-1
+	ux500/dt
+		git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson tags/ux500-dts-v5.7
+	samsung/dt
+		git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux tags/samsung-dt-5.7
+	rockchip/dt
+		git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip tags/v5.7-rockchip-dts32-1
+	rockchip/dt64
+		git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip tags/v5.7-rockchip-dts64-1
+	amlogic/dt64
+		git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-amlogic tags/amlogic-dt64
+	uniphier/dt
+		git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-uniphier tags/uniphier-dt-v5.7
+	uniphier/dt64
+		git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-uniphier tags/uniphier-dt64-v5.7
+	imx/dt-bindings
+		git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux tags/imx-bindings-5.7
+	imx/dt
+		git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux tags/imx-dt-5.7
+	imx/dt64
+		git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux tags/imx-dt64-5.7
+	socfpga/dt
+		git://git.kernel.org/pub/scm/linux/kernel/git/dinguyen/linux tags/socfpga_dts_update_for_v5.7
+	keystone/dt64
+		git://git.kernel.org/pub/scm/linux/kernel/git/kristo/linux tags/ti-k3-soc-for-v5.7
+	mediatek/dt64
+		git://git.kernel.org/pub/scm/linux/kernel/git/matthias.bgg/linux tags/v5.6-next-dts64
+	mediatek/dt32
+		git://git.kernel.org/pub/scm/linux/kernel/git/matthias.bgg/linux tags/v5.6-next-dts32
+	gemini/dt
+		git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik tags/gemini-dts-v5.7
+	at91/dt
+		git://git.kernel.org/pub/scm/linux/kernel/git/at91/linux tags/at91-5.7-dt
+	amlogic/dt64-2
+		git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-amlogic tags/amlogic-dt64-2
+	socfpga/dt-2
+		git://git.kernel.org/pub/scm/linux/kernel/git/dinguyen/linux tags/socfpga_dts_update_for_v5.7_part2
+	qcom/dt
+		git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux tags/qcom-dts-for-5.7
+	patch
+		arm: dts: calxeda: Basic DT file fixes
+		arm: dts: calxeda: Provide UART clock
+		arm: dts: calxeda: Fix interrupt grouping
+		arm: dts: calxeda: Group port-phys and sgpio-gpio items
+		MAINTAINERS: Update Calxeda Highbank maintainership
+		arm64: dts: Revert "specify console via command line"
+		ARM: dts: ux500: Fix missing node renames
+
+arm/drivers
+	renesas/drivers
+		git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel tags/renesas-drivers-for-v5.7-tag1
+	hisi/drivers
+		git://github.com/hisilicon/linux-hisi tags/hisi-drivers-for-5.7
+	ti/sysc
+		git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v5.7/ti-sysc-signed
+	amlogic/driver
+		git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-amlogic tags/amlogic-drivers
+	qcom/driver
+		git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux tags/qcom-drivers-for-5.7
+	imx/driver
+		git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux tags/imx-drivers-5.7
+	omap/ti-sysc-fix
+		git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v5.7/ti-sysc-fix-signed
+	tegra/firmware
+		git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux tags/tegra-for-5.7-firmware
+	tegra/memory
+		git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux tags/tegra-for-5.7-memory
+	fsl/dpaa2
+		git://git.kernel.org/pub/scm/linux/kernel/git/leo/linux tags/soc-fsl-next-v5.7
+	drivers/tee
+		https://git.linaro.org/people/jens.wiklander/linux-tee tags/tee-cleanup-for-5.7
+	drivers/arm-scmi
+		git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux tags/scmi-updates-5.7
+
+arm/defconfig
+	renesas/defconfig
+		git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel tags/renesas-arm64-defconfig-for-v5.7-tag1
+	hisi/defconfig
+		git://github.com/hisilicon/linux-hisi tags/hisi-arm64-defconfig-for-5.7
+	broadcom/defconfig
+		https://github.com/Broadcom/stblinux tags/arm-soc/for-5.7/defconfig
+	tegra/defconfig
+		git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux tags/tegra-for-5.7-arm-defconfig
+	samsung/defconfig
+		git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux tags/samsung-defconfig-5.7
+	qcom/defconfig64
+		git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux tags/qcom-arm64-defconfig-for-5.7
+	qcom/defconfig
+		git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux tags/qcom-defconfig-for-5.7
+	imx/defconfig
+		git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux tags/imx-defconfig-5.7
+	omap/defconfig
+		git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v5.7/defconfig-signed
+	at91/defconfig
+		git://git.kernel.org/pub/scm/linux/kernel/git/at91/linux tags/at91-5.7-defconfig
+
+arm/newsoc
+
+arm/late
+	omap/sysc-drop-pdata
+		git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v5.7/ti-sysc-drop-pdata-signed
+		contains ti/sysc
+	omap/sysc-drop-pdata-ti81xx
+		git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v5.7/ti-sysc-drop-pdata-ti81xx-signed
+	qcom/dt-arm64
+		git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux tags/qcom-arm64-for-5.7
+
+arm/fixes
+	<no branch> (fe8fe7723a3a824790bda681b40efd767e2251a7)
+		git://git.kernel.org/pub/scm/linux/kernel/git/leo/linux tags/soc-fsl-fix-v5.6
+	<no branch> (d9b553b02e691185f8145637c46f9564395936e2)
+		git://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux tags/sunxi-fixes-for-5.6
+	<no branch> (00cef5e404a6c6e72cbec1fd7a41b01890b8d340)
+		git://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux tags/sunxi-fixes-for-5.6-2
+	<no branch> (636b45b8efa91db05553840b6c0120d6fa6b94fa)
+		git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux tags/imx-fixes-5.6-2
+	patch
+		ARM: dts: exynos: Fix regulator node aliasing on Midas-based boards
+	<no branch> (dfa7ea303f56a3a8b1ed3b91ef35af2da67ca4ee)
+		git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v5.6/fixes-rc6-signed
+	patch
+		arm64: dts: Fix leftover entry-methods for PSCI
+	<no branch> (55c7c0621078bd73e9d4d2a11eb36e61bc6fe998)
+		https://github.com/Broadcom/stblinux tags/arm-soc/for-5.6/devicetree-fixes-part2
+	<no branch> (deeabb4c1341a12bf8b599e6a2f4cfa4fd74738c)
+		git://git.kernel.org/pub/scm/linux/kernel/git/narmstrong/linux-oxnas tags/oxnas-arm-soc-dt-fixes-for-5.6
+	<no branch> (36fa3e50085e3858dd506e4431b9abd1bcb1f542)
+		https://git.linaro.org/people/jens.wiklander/linux-tee tags/tee-amdtee-fix2-for-5.6
+	patch
+		soc: samsung: chipid: Fix return value on non-Exynos platforms
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index cabdd8f4a248..e8e1c866e413 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -1450,7 +1450,8 @@ ENTRY(efi_enter_kernel)
 		@ running beyond the PoU, and so calling cache_off below from
 		@ inside the PE/COFF loader allocated region is unsafe unless
 		@ we explicitly clean it to the PoC.
-		adr	r0, call_cache_fn		@ region of code we will
+ ARM(		adrl	r0, call_cache_fn	)
+ THUMB(		adr	r0, call_cache_fn	)	@ region of code we will
 		adr	r1, 0f				@ run with MMU off
 		bl	cache_clean_flush
 		bl	cache_off
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index e8dd99201397..47af4ee65673 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -181,6 +181,7 @@ dtb-$(CONFIG_ARCH_EXYNOS3) += \
 	exynos3250-monk.dtb \
 	exynos3250-rinato.dtb
 dtb-$(CONFIG_ARCH_EXYNOS4) += \
+	exynos4210-i9100.dtb \
 	exynos4210-origen.dtb \
 	exynos4210-smdkv310.dtb \
 	exynos4210-trats.dtb \
@@ -412,6 +413,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
 	imx6dl-aristainetos2_4.dtb \
 	imx6dl-aristainetos2_7.dtb \
 	imx6dl-colibri-eval-v3.dtb \
+	imx6dl-colibri-v1_1-eval-v3.dtb \
 	imx6dl-cubox-i.dtb \
 	imx6dl-cubox-i-emmc-som-v15.dtb \
 	imx6dl-cubox-i-som-v15.dtb \
@@ -896,6 +898,9 @@ dtb-$(CONFIG_ARCH_QCOM) += \
 dtb-$(CONFIG_ARCH_RDA) += \
 	rda8810pl-orangepi-2g-iot.dtb \
 	rda8810pl-orangepi-i96.dtb
+dtb-$(CONFIG_ARCH_REALTEK) += \
+	rtd1195-horseradish.dtb \
+	rtd1195-mele-x1000.dtb
 dtb-$(CONFIG_ARCH_REALVIEW) += \
 	arm-realview-pb1176.dtb \
 	arm-realview-pb11mp.dtb \
@@ -1110,6 +1115,7 @@ dtb-$(CONFIG_MACH_SUN7I) += \
 	sun7i-a20-olimex-som204-evb.dtb \
 	sun7i-a20-olimex-som204-evb-emmc.dtb \
 	sun7i-a20-olinuxino-lime.dtb \
+	sun7i-a20-olinuxino-lime-emmc.dtb \
 	sun7i-a20-olinuxino-lime2.dtb \
 	sun7i-a20-olinuxino-lime2-emmc.dtb \
 	sun7i-a20-olinuxino-micro.dtb \
diff --git a/arch/arm/boot/dts/aspeed-bmc-facebook-tiogapass.dts b/arch/arm/boot/dts/aspeed-bmc-facebook-tiogapass.dts
index 5d7cbd9164d4..6b88c7f26bf7 100644
--- a/arch/arm/boot/dts/aspeed-bmc-facebook-tiogapass.dts
+++ b/arch/arm/boot/dts/aspeed-bmc-facebook-tiogapass.dts
@@ -5,6 +5,7 @@
 
 #include "aspeed-g5.dtsi"
 #include <dt-bindings/gpio/aspeed-gpio.h>
+#include <dt-bindings/i2c/i2c.h>
 
 / {
 	model = "Facebook TiogaPass BMC";
@@ -121,6 +122,69 @@ &kcs3 {
 	kcs_addr = <0xca2>;
 };
 
+&gpio {
+	status = "okay";
+	gpio-line-names =
+	/*A0-A7*/	"BMC_CPLD_FPGA_SEL","","","","","","","",
+	/*B0-B7*/	"","BMC_DEBUG_EN","","","","BMC_PPIN","PS_PWROK",
+			"IRQ_PVDDQ_GHJ_VRHOT_LVT3",
+	/*C0-C7*/	"","","","","","","","",
+	/*D0-D7*/	"BIOS_MRC_DEBUG_MSG_DIS","BOARD_REV_ID0","",
+			"BOARD_REV_ID1","IRQ_DIMM_SAVE_LVT3","BOARD_REV_ID2",
+			"CPU_ERR0_LVT3_BMC","CPU_ERR1_LVT3_BMC",
+	/*E0-E7*/	"RESET_BUTTON","RESET_OUT","POWER_BUTTON",
+			"POWER_OUT","NMI_BUTTON","","CPU0_PROCHOT_LVT3_ BMC",
+			"CPU1_PROCHOT_LVT3_ BMC",
+	/*F0-F7*/	"IRQ_PVDDQ_ABC_VRHOT_LVT3","",
+			"IRQ_PVCCIN_CPU0_VRHOT_LVC3",
+			"IRQ_PVCCIN_CPU1_VRHOT_LVC3",
+			"IRQ_PVDDQ_KLM_VRHOT_LVT3","","P3VBAT_BRIDGE_EN","",
+	/*G0-G7*/	"CPU_ERR2_LVT3","CPU_CATERR_LVT3","PCH_BMC_THERMTRIP",
+			"CPU0_SKTOCC_LVT3","","","","BIOS_SMI_ACTIVE",
+	/*H0-H7*/	"LED_POST_CODE_0","LED_POST_CODE_1","LED_POST_CODE_2",
+			"LED_POST_CODE_3","LED_POST_CODE_4","LED_POST_CODE_5",
+			"LED_POST_CODE_6","LED_POST_CODE_7",
+	/*I0-I7*/	"CPU0_FIVR_FAULT_LVT3","CPU1_FIVR_FAULT_LVT3",
+			"FORCE_ADR","UV_ADR_TRIGGER_EN","","","","",
+	/*J0-J7*/	"","","","","","","","",
+	/*K0-K7*/	"","","","","","","","",
+	/*L0-L7*/	"IRQ_UV_DETECT","IRQ_OC_DETECT","HSC_TIMER_EXP","",
+			"MEM_THERM_EVENT_PCH","PMBUS_ALERT_BUF_EN","","",
+	/*M0-M7*/	"CPU0_RC_ERROR","CPU1_RC_ERROR","","OC_DETECT_EN",
+			"CPU0_THERMTRIP_LATCH_LVT3",
+			"CPU1_THERMTRIP_LATCH_LVT3","","",
+	/*N0-N7*/	"","","","CPU_MSMI_LVT3","","BIOS_SPI_BMC_CTRL","","",
+	/*O0-O7*/	"","","","","","","","",
+	/*P0-P7*/	"BOARD_SKU_ID0","BOARD_SKU_ID1","BOARD_SKU_ID2",
+			"BOARD_SKU_ID3","BOARD_SKU_ID4","BMC_PREQ",
+			"BMC_PWR_DEBUG","RST_RSMRST",
+	/*Q0-Q7*/	"","","","","UARTSW_LSB","UARTSW_MSB",
+			"POST_CARD_PRES_BMC","PE_BMC_WAKE",
+	/*R0-R7*/	"","","BMC_TCK_MUX_SEL","BMC_PRDY",
+			"BMC_XDP_PRSNT_IN","RST_BMC_PLTRST_BUF","SLT_CFG0",
+			"SLT_CFG1",
+	/*S0-S7*/	"THROTTLE","BMC_READY","","HSC_SMBUS_SWITCH_EN","",
+			"","","",
+	/*T0-T7*/	"","","","","","","","",
+	/*U0-U7*/	"","","","","","BMC_FAULT","","",
+	/*V0-V7*/	"","","","FAST_PROCHOT_EN","","","","",
+	/*W0-W7*/	"","","","","","","","",
+	/*X0-X7*/	"","","","GLOBAL_RST_WARN",
+			"CPU0_MEMABC_MEMHOT_LVT3_BMC",
+			"CPU0_MEMDEF_MEMHOT_LVT3_BMC",
+			"CPU1_MEMGHJ_MEMHOT_LVT3_BMC",
+			"CPU1_MEMKLM_MEMHOT_LVT3_BMC",
+	/*Y0-Y7*/	"SIO_S3","SIO_S5","BMC_JTAG_SEL","SIO_ONCONTROL","",
+			"","","",
+	/*Z0-Z7*/	"","SIO_POWER_GOOD","IRQ_PVDDQ_DEF_VRHOT_LVT3","",
+			"","","","",
+	/*AA0-AA7*/	"CPU1_SKTOCC_LVT3","IRQ_SML1_PMBUS_ALERT",
+			"SERVER_POWER_LED","","PECI_MUX_SELECT","UV_HIGH_SET",
+			"","POST_COMPLETE",
+	/*AB0-AB7*/	"IRQ_HSC_FAULT","OCP_MEZZA_PRES","","","","","","",
+	/*AC0-AC7*/	"","","","","","","","";
+};
+
 &mac0 {
 	status = "okay";
 
@@ -368,6 +432,11 @@ &i2c3 {
 &i2c4 {
 	status = "okay";
 	// BMC Debug Header
+	ipmb0@10 {
+		compatible = "ipmb-dev";
+		reg = <(0x10 | I2C_OWN_SLAVE_ADDRESS)>;
+		i2c-protocol;
+	};
 };
 
 &i2c5 {
@@ -449,6 +518,11 @@ tmp421@1f {
 &i2c9 {
 	status = "okay";
 	//USB Debug Connector
+	ipmb0@10 {
+		compatible = "ipmb-dev";
+		reg = <(0x10 | I2C_OWN_SLAVE_ADDRESS)>;
+		i2c-protocol;
+	};
 };
 
 &pwm_tacho {
diff --git a/arch/arm/boot/dts/aspeed-bmc-facebook-yosemitev2.dts b/arch/arm/boot/dts/aspeed-bmc-facebook-yosemitev2.dts
new file mode 100644
index 000000000000..e16a42fbf41e
--- /dev/null
+++ b/arch/arm/boot/dts/aspeed-bmc-facebook-yosemitev2.dts
@@ -0,0 +1,151 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+// Copyright (c) 2018 Facebook Inc.
+
+/dts-v1/;
+
+#include "aspeed-g5.dtsi"
+/ {
+	model = "Facebook Yosemitev2 BMC";
+	compatible = "facebook,yosemitev2-bmc", "aspeed,ast2500";
+
+	aliases {
+		serial4 = &uart5;
+	};
+
+	chosen {
+		stdout-path = &uart5;
+	};
+
+	memory@80000000 {
+		reg = <0x80000000 0x20000000>;
+	};
+
+	iio-hwmon {
+		// Voltage sensor
+		compatible = "iio-hwmon";
+		io-channels = <&adc 0> , <&adc 1> , <&adc 2> ,  <&adc 3> ,
+		<&adc 4> , <&adc 5> , <&adc 6> ,  <&adc 7> ,
+		<&adc 8> , <&adc 9> , <&adc 10>, <&adc 11> ,
+		<&adc 12> , <&adc 13> , <&adc 14> , <&adc 15> ;
+	};
+};
+
+&fmc {
+	status = "okay";
+	flash@0 {
+		status = "okay";
+		m25p,fast-read;
+#include "openbmc-flash-layout.dtsi"
+	};
+};
+
+&spi1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_spi1_default>;
+	flash@0 {
+		status = "okay";
+		m25p,fast-read;
+		label = "pnor";
+	};
+};
+
+&uart5 {
+	// BMC Console
+	status = "okay";
+};
+
+&mac0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_rmii1_default>;
+	mlx,multi-host;
+	use-ncsi;
+};
+
+&adc {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_adc0_default
+			&pinctrl_adc1_default
+			&pinctrl_adc2_default
+			&pinctrl_adc3_default
+			&pinctrl_adc4_default
+			&pinctrl_adc5_default
+			&pinctrl_adc6_default
+			&pinctrl_adc7_default
+			&pinctrl_adc8_default
+			&pinctrl_adc9_default
+			&pinctrl_adc10_default
+			&pinctrl_adc11_default
+			&pinctrl_adc12_default
+			&pinctrl_adc13_default
+			&pinctrl_adc14_default
+			&pinctrl_adc15_default>;
+};
+
+&i2c8 {
+	//FRU EEPROM
+	status = "okay";
+	eeprom@51 {
+		compatible = "atmel,24c64";
+		reg = <0x51>;
+		pagesize = <32>;
+	};
+};
+
+&i2c9 {
+	// Inlet and outlet temp
+	status = "okay";
+	tmp421@4e {
+		compatible = "ti,tmp421";
+		reg = <0x4e>;
+	};
+	tmp421@4f {
+		compatible = "ti,tmp421";
+		reg = <0x4f>;
+	};
+};
+
+&i2c10 {
+	// HSC
+	status = "okay";
+	adm1278@40 {
+		compatible = "adi,adm1278";
+		reg = <0x40>;
+	};
+};
+
+&i2c11 {
+	// MEZZ_TEMP_SENSOR
+	status = "okay";
+	tmp421@1f {
+		compatible = "ti,tmp421";
+		reg = <0x1f>;
+	};
+};
+
+&i2c12 {
+	// MEZZ_FRU
+	status = "okay";
+	eeprom@51 {
+		compatible = "atmel,24c64";
+		reg = <0x51>;
+		pagesize = <32>;
+	};
+};
+
+&pwm_tacho {
+	// FSC
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm0_default &pinctrl_pwm1_default>;
+	fan@0 {
+		reg = <0x00>;
+		aspeed,fan-tach-ch = /bits/ 8 <0x00>;
+	};
+	fan@1 {
+		reg = <0x01>;
+		aspeed,fan-tach-ch = /bits/ 8 <0x01>;
+	};
+};
diff --git a/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts b/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts
index 6232cd726a7f..521b6e3d24cb 100644
--- a/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts
+++ b/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts
@@ -4,6 +4,7 @@
 
 #include "aspeed-g6.dtsi"
 #include <dt-bindings/gpio/aspeed-gpio.h>
+#include <dt-bindings/leds/leds-pca955x.h>
 
 / {
 	model = "Rainier";
@@ -269,66 +270,82 @@ pca0: pca9552@61 {
 
 		gpio@0 {
 			reg = <0>;
+			type = <PCA955X_TYPE_GPIO>;
 		};
 
 		gpio@1 {
 			reg = <1>;
+			type = <PCA955X_TYPE_GPIO>;
 		};
 
 		gpio@2 {
 			reg = <2>;
+			type = <PCA955X_TYPE_GPIO>;
 		};
 
 		gpio@3 {
 			reg = <3>;
+			type = <PCA955X_TYPE_GPIO>;
 		};
 
 		gpio@4 {
 			reg = <4>;
+			type = <PCA955X_TYPE_GPIO>;
 		};
 
 		gpio@5 {
 			reg = <5>;
+			type = <PCA955X_TYPE_GPIO>;
 		};
 
 		gpio@6 {
 			reg = <6>;
+			type = <PCA955X_TYPE_GPIO>;
 		};
 
 		gpio@7 {
 			reg = <7>;
+			type = <PCA955X_TYPE_GPIO>;
 		};
 
 		gpio@8 {
 			reg = <8>;
+			type = <PCA955X_TYPE_GPIO>;
 		};
 
 		gpio@9 {
 			reg = <9>;
+			type = <PCA955X_TYPE_GPIO>;
 		};
 
 		gpio@10 {
 			reg = <10>;
+			type = <PCA955X_TYPE_GPIO>;
 		};
 
 		gpio@11 {
 			reg = <11>;
+			type = <PCA955X_TYPE_GPIO>;
 		};
 
 		gpio@12 {
 			reg = <12>;
+			type = <PCA955X_TYPE_GPIO>;
 		};
 
 		gpio@13 {
 			reg = <13>;
+			type = <PCA955X_TYPE_GPIO>;
 		};
 
 		gpio@14 {
 			reg = <14>;
+			type = <PCA955X_TYPE_GPIO>;
 		};
 
 		gpio@15 {
 			reg = <15>;
+			type = <PCA955X_TYPE_GPIO>;
 		};
 	};
 
@@ -540,6 +557,10 @@ &vuart1 {
 	status = "okay";
 };
 
+&vuart2 {
+	status = "okay";
+};
+
 &lpc_ctrl {
 	status = "okay";
 	memory-region = <&flash_memory>;
diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-tacoma.dts b/arch/arm/boot/dts/aspeed-bmc-opp-tacoma.dts
index ff49ec76fa7c..47293a5e0c59 100644
--- a/arch/arm/boot/dts/aspeed-bmc-opp-tacoma.dts
+++ b/arch/arm/boot/dts/aspeed-bmc-opp-tacoma.dts
@@ -132,6 +132,10 @@ &mac2 {
 	use-ncsi;
 };
 
+&emmc_controller {
+	status = "okay";
+};
+
 &emmc {
 	status = "okay";
 };
diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-witherspoon.dts b/arch/arm/boot/dts/aspeed-bmc-opp-witherspoon.dts
index 421aa600148b..a0f99e34ac8e 100644
--- a/arch/arm/boot/dts/aspeed-bmc-opp-witherspoon.dts
+++ b/arch/arm/boot/dts/aspeed-bmc-opp-witherspoon.dts
@@ -191,6 +191,40 @@ iio-hwmon-bmp280 {
 
 };
 
+&gpio {
+	gpio-line-names =
+	/*A0-A7*/	"","cfam-reset","","","","","fsi-mux","",
+	/*B0-B7*/	"","","","","","air-water","","",
+	/*C0-C7*/	"","","","","","","","",
+	/*D0-D7*/	"fsi-enable","","","","","","","",
+	/*E0-E7*/	"fsi-data","","","","","","","",
+	/*F0-F7*/	"","","","","","","","",
+	/*G0-G7*/	"","","","","","","","",
+	/*H0-H7*/	"","","","","","","","",
+	/*I0-I7*/	"","","","","","","","",
+	/*J0-J7*/	"","","checkstop","","","","","",
+	/*K0-K7*/	"","","","","","","","",
+	/*L0-L7*/	"","","","","","","","",
+	/*M0-M7*/	"","","","","","","","",
+	/*N0-N7*/	"presence-ps1","","led-rear-fault","led-rear-power",
+		        "led-rear-id","","","",
+	/*O0-O7*/	"","","","","","","","",
+	/*P0-P7*/	"","","","","","","","presence-ps0",
+	/*Q0-Q7*/	"","","","","","","","",
+	/*R0-R7*/	"","","fsi-trans","","","power-button","","",
+	/*S0-S7*/	"","","","","","","","",
+	/*T0-T7*/	"","","","","","","","",
+	/*U0-U7*/	"","","","","","","","",
+	/*V0-V7*/	"","","","","","","","",
+	/*W0-W7*/	"","","","","","","","",
+	/*X0-X7*/	"","","","","","","","",
+	/*Y0-Y7*/	"","","","","","","","",
+	/*Z0-Z7*/	"","","","","","","","",
+	/*AA0-AA7*/	"fsi-clock","","","","","","","",
+	/*AB0-AB7*/	"","","","","","","","",
+	/*AC0-AC7*/	"","","","","","","","";
+};
+
 &fmc {
 	status = "okay";
 
diff --git a/arch/arm/boot/dts/aspeed-g4.dtsi b/arch/arm/boot/dts/aspeed-g4.dtsi
index 8e04303e8514..82f0213e3a3c 100644
--- a/arch/arm/boot/dts/aspeed-g4.dtsi
+++ b/arch/arm/boot/dts/aspeed-g4.dtsi
@@ -219,6 +219,16 @@ sram: sram@1e720000 {
 				reg = <0x1e720000 0x8000>;	// 32K
 			};
 
+			video: video@1e700000 {
+				compatible = "aspeed,ast2400-video-engine";
+				reg = <0x1e700000 0x1000>;
+				clocks = <&syscon ASPEED_CLK_GATE_VCLK>,
+					 <&syscon ASPEED_CLK_GATE_ECLK>;
+				clock-names = "vclk", "eclk";
+				interrupts = <7>;
+				status = "disabled";
+			};
+
 			sdmmc: sd-controller@1e740000 {
 				compatible = "aspeed,ast2400-sd-controller";
 				reg = <0x1e740000 0x100>;
diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi
index f12ec04d3cbc..284face7de2c 100644
--- a/arch/arm/boot/dts/aspeed-g5.dtsi
+++ b/arch/arm/boot/dts/aspeed-g5.dtsi
@@ -224,6 +224,14 @@ syscon: syscon@1e6e2000 {
 				#clock-cells = <1>;
 				#reset-cells = <1>;
 
+				scu_ic: interrupt-controller@18 {
+					#interrupt-cells = <1>;
+					compatible = "aspeed,ast2500-scu-ic";
+					reg = <0x18 0x4>;
+					interrupts = <21>;
+					interrupt-controller;
+				};
+
 				p2a: p2a-control@2c {
 					compatible = "aspeed,ast2500-p2a-ctrl";
 					reg = <0x2c 0x4>;
@@ -254,6 +262,17 @@ gfx: display@1e6e6000 {
 				interrupts = <0x19>;
 			};
 
+			xdma: xdma@1e6e7000 {
+				compatible = "aspeed,ast2500-xdma";
+				reg = <0x1e6e7000 0x100>;
+				clocks = <&syscon ASPEED_CLK_GATE_BCLK>;
+				resets = <&syscon ASPEED_RESET_XDMA>;
+				interrupts-extended = <&vic 6>, <&scu_ic 2>;
+				pcie-device = "bmc";
+				aspeed,scu = <&syscon>;
+				status = "disabled";
+			};
+
 			adc: adc@1e6e9000 {
 				compatible = "aspeed,ast2500-adc";
 				reg = <0x1e6e9000 0xb0>;
diff --git a/arch/arm/boot/dts/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed-g6.dtsi
index 0a29b3b57a9d..1ffc15177b79 100644
--- a/arch/arm/boot/dts/aspeed-g6.dtsi
+++ b/arch/arm/boot/dts/aspeed-g6.dtsi
@@ -313,6 +313,22 @@ smp-memram@180 {
 					compatible = "aspeed,ast2600-smpmem";
 					reg = <0x180 0x40>;
 				};
+
+				scu_ic0: interrupt-controller@560 {
+					#interrupt-cells = <1>;
+					compatible = "aspeed,ast2600-scu-ic0";
+					reg = <0x560 0x4>;
+					interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+					interrupt-controller;
+				};
+
+				scu_ic1: interrupt-controller@570 {
+					#interrupt-cells = <1>;
+					compatible = "aspeed,ast2600-scu-ic1";
+					reg = <0x570 0x4>;
+					interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+					interrupt-controller;
+				};
 			};
 
 			rng: hwrng@1e6e2524 {
@@ -322,6 +338,28 @@ rng: hwrng@1e6e2524 {
 				quality = <100>;
 			};
 
+			xdma: xdma@1e6e7000 {
+				compatible = "aspeed,ast2600-xdma";
+				reg = <0x1e6e7000 0x100>;
+				clocks = <&syscon ASPEED_CLK_GATE_BCLK>;
+				resets = <&syscon ASPEED_RESET_DEV_XDMA>;
+				interrupts-extended = <&gic GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+						      <&scu_ic0 2>;
+				pcie-device = "bmc";
+				aspeed,scu = <&syscon>;
+				status = "disabled";
+			};
+
+			video: video@1e700000 {
+				compatible = "aspeed,ast2600-video-engine";
+				reg = <0x1e700000 0x1000>;
+				clocks = <&syscon ASPEED_CLK_GATE_VCLK>,
+					 <&syscon ASPEED_CLK_GATE_ECLK>;
+				clock-names = "vclk", "eclk";
+				interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
 			gpio0: gpio@1e780000 {
 				#gpio-cells = <2>;
 				gpio-controller;
diff --git a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
index e26ea9006378..c7f1d97e69bb 100644
--- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
+++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
@@ -56,6 +56,16 @@ sd_io_1v8_reg: sd_io_1v8_reg {
 			  3300000 0x0>;
 		status = "okay";
 	};
+
+	sd_vcc_reg: sd_vcc_reg {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc-sd";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		enable-active-high;
+		gpio = <&expgpio 6 GPIO_ACTIVE_HIGH>;
+	};
 };
 
 &firmware {
@@ -69,7 +79,7 @@ expgpio: gpio {
 				  "GLOBAL_RESET",
 				  "VDD_SD_IO_SEL",
 				  "CAM_GPIO",
-				  "",
+				  "SD_PWR_ON",
 				  "";
 		status = "okay";
 	};
@@ -174,6 +184,7 @@ brcmf: wifi@1 {
 /* EMMC2 is used to drive the SD card */
 &emmc2 {
 	vqmmc-supply = <&sd_io_1v8_reg>;
+	vmmc-supply = <&sd_vcc_reg>;
 	broken-cd;
 	status = "okay";
 };
diff --git a/arch/arm/boot/dts/bcm2835-common.dtsi b/arch/arm/boot/dts/bcm2835-common.dtsi
index 2b1d9d4c0cde..4119271c979d 100644
--- a/arch/arm/boot/dts/bcm2835-common.dtsi
+++ b/arch/arm/boot/dts/bcm2835-common.dtsi
@@ -130,7 +130,6 @@ v3d: v3d@7ec00000 {
 			compatible = "brcm,bcm2835-v3d";
 			reg = <0x7ec00000 0x1000>;
 			interrupts = <1 10>;
-			power-domains = <&pm BCM2835_POWER_DOMAIN_GRAFX_V3D>;
 		};
 
 		vc4: gpu {
diff --git a/arch/arm/boot/dts/bcm2835-rpi-common.dtsi b/arch/arm/boot/dts/bcm2835-rpi-common.dtsi
new file mode 100644
index 000000000000..8a55b6cded59
--- /dev/null
+++ b/arch/arm/boot/dts/bcm2835-rpi-common.dtsi
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * This include file covers the common peripherals and configuration between
+ * bcm2835, bcm2836 and bcm2837 implementations that interact with RPi's
+ * firmware interface.
+ */
+
+#include <dt-bindings/power/raspberrypi-power.h>
+
+&v3d {
+	power-domains = <&power RPI_POWER_DOMAIN_V3D>;
+};
diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
index 53bf4579cc22..0549686134ea 100644
--- a/arch/arm/boot/dts/bcm2835.dtsi
+++ b/arch/arm/boot/dts/bcm2835.dtsi
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 #include "bcm283x.dtsi"
 #include "bcm2835-common.dtsi"
+#include "bcm2835-rpi-common.dtsi"
 
 / {
 	compatible = "brcm,bcm2835";
diff --git a/arch/arm/boot/dts/bcm2836.dtsi b/arch/arm/boot/dts/bcm2836.dtsi
index 82d6c4662ae4..b390006aef79 100644
--- a/arch/arm/boot/dts/bcm2836.dtsi
+++ b/arch/arm/boot/dts/bcm2836.dtsi
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 #include "bcm283x.dtsi"
 #include "bcm2835-common.dtsi"
+#include "bcm2835-rpi-common.dtsi"
 
 / {
 	compatible = "brcm,bcm2836";
diff --git a/arch/arm/boot/dts/bcm2837.dtsi b/arch/arm/boot/dts/bcm2837.dtsi
index 9e95fee78e19..0199ec98cd61 100644
--- a/arch/arm/boot/dts/bcm2837.dtsi
+++ b/arch/arm/boot/dts/bcm2837.dtsi
@@ -1,5 +1,6 @@
 #include "bcm283x.dtsi"
 #include "bcm2835-common.dtsi"
+#include "bcm2835-rpi-common.dtsi"
 
 / {
 	compatible = "brcm,bcm2837";
diff --git a/arch/arm/boot/dts/exynos3250-monk.dts b/arch/arm/boot/dts/exynos3250-monk.dts
index 248bd372fe70..ca29d7ed8216 100644
--- a/arch/arm/boot/dts/exynos3250-monk.dts
+++ b/arch/arm/boot/dts/exynos3250-monk.dts
@@ -57,7 +57,8 @@ vemmc_reg: voltage-regulator-0 {
 
 	i2c_max77836: i2c-gpio-0 {
 		compatible = "i2c-gpio";
-		gpios = <&gpd0 2 GPIO_ACTIVE_HIGH>, <&gpd0 3 GPIO_ACTIVE_HIGH>;
+		sda-gpios = <&gpd0 2 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+		scl-gpios = <&gpd0 3 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 
diff --git a/arch/arm/boot/dts/exynos3250-rinato.dts b/arch/arm/boot/dts/exynos3250-rinato.dts
index 86c26a4edfd7..aba8350cfdaf 100644
--- a/arch/arm/boot/dts/exynos3250-rinato.dts
+++ b/arch/arm/boot/dts/exynos3250-rinato.dts
@@ -50,9 +50,15 @@ power_key {
 		};
 	};
 
+	wlan_pwrseq: mshc1-pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		reset-gpios = <&gpe0 4 GPIO_ACTIVE_LOW>;
+	};
+
 	i2c_max77836: i2c-gpio-0 {
 		compatible = "i2c-gpio";
-		gpios = <&gpd0 2 GPIO_ACTIVE_HIGH>, <&gpd0 3 GPIO_ACTIVE_HIGH>;
+		sda-gpios = <&gpd0 2 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+		scl-gpios = <&gpd0 3 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 
@@ -605,8 +611,6 @@ &jpeg {
 };
 
 &mshc_0 {
-	#address-cells = <1>;
-	#size-cells = <0>;
 	broken-cd;
 	non-removable;
 	cap-mmc-highspeed;
@@ -625,10 +629,48 @@ &mshc_0 {
 	status = "okay";
 };
 
+&mshc_1 {
+	status = "okay";
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	non-removable;
+	cap-sd-highspeed;
+	cap-sdio-irq;
+	keep-power-in-suspend;
+	samsung,dw-mshc-ciu-div = <1>;
+	samsung,dw-mshc-sdr-timing = <0 1>;
+	samsung,dw-mshc-ddr-timing = <1 2>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sd1_clk &sd1_cmd &sd1_bus1 &sd1_bus4>;
+	bus-width = <4>;
+
+	mmc-pwrseq = <&wlan_pwrseq>;
+
+	brcmf: wifi@1 {
+		compatible = "brcm,bcm4334-fmac";
+		reg = <1>;
+
+		interrupt-parent = <&gpx1>;
+		interrupts = <1 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "host-wake";
+	};
+};
+
 &serial_0 {
 	assigned-clocks = <&cmu CLK_SCLK_UART0>;
 	assigned-clock-rates = <100000000>;
 	status = "okay";
+
+	bluetooth {
+		compatible = "brcm,bcm4330-bt";
+		max-speed = <3000000>;
+		shutdown-gpios = <&gpe0 0 GPIO_ACTIVE_HIGH>;
+		device-wakeup-gpios = <&gpx3 1 GPIO_ACTIVE_HIGH>;
+		host-wakeup-gpios = <&gpx2 6 GPIO_ACTIVE_HIGH>;
+		clocks = <&s2mps14_osc S2MPS11_CLK_BT>;
+	};
 };
 
 &serial_1 {
diff --git a/arch/arm/boot/dts/exynos4210-i9100.dts b/arch/arm/boot/dts/exynos4210-i9100.dts
new file mode 100644
index 000000000000..6d0c04d77a39
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4210-i9100.dts
@@ -0,0 +1,768 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Samsung's Exynos4210 based Galaxy S2 (GT-I9100 version) device tree
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ * Copyright (c) 2020 Stenkin Evgeniy <stenkinevgeniy@gmail.com>
+ * Copyright (c) 2020 Paul Cercueil <paul@crapouillou.net>
+ */
+
+/dts-v1/;
+#include "exynos4210.dtsi"
+#include "exynos4412-ppmu-common.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/linux-event-codes.h>
+
+/ {
+	model = "Samsung Galaxy S2 (GT-I9100)";
+	compatible = "samsung,i9100", "samsung,exynos4210", "samsung,exynos4";
+
+	memory@40000000 {
+		device_type = "memory";
+		reg = <0x40000000 0x40000000>;
+	};
+
+	chosen {
+		stdout-path = "serial2:115200n8";
+	};
+
+	vemmc_reg: regulator-0 {
+		compatible = "regulator-fixed";
+		regulator-name = "VMEM_VDD_2.8V";
+		regulator-min-microvolt = <2800000>;
+		regulator-max-microvolt = <2800000>;
+		gpio = <&gpk0 2 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	tsp_reg: regulator-1 {
+		compatible = "regulator-fixed";
+		regulator-name = "TSP_FIXED_VOLTAGES";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		gpio = <&gpl0 3 GPIO_ACTIVE_HIGH>;
+		startup-delay-us = <70000>;
+		enable-active-high;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+
+	cam_af_28v_reg: regulator-2 {
+		compatible = "regulator-fixed";
+		regulator-name = "8M_AF_2.8V_EN";
+		regulator-min-microvolt = <2800000>;
+		regulator-max-microvolt = <2800000>;
+		gpio = <&gpk1 1 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	cam_io_en_reg: regulator-3 {
+		compatible = "regulator-fixed";
+		regulator-name = "CAM_IO_EN";
+		regulator-min-microvolt = <2800000>;
+		regulator-max-microvolt = <2800000>;
+		gpio = <&gpe2 1 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	cam_io_12v_reg: regulator-4 {
+		compatible = "regulator-fixed";
+		regulator-name = "8M_1.2V_EN";
+		regulator-min-microvolt = <1200000>;
+		regulator-max-microvolt = <1200000>;
+		gpio = <&gpe2 5 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	vt_core_15v_reg: regulator-5 {
+		compatible = "regulator-fixed";
+		regulator-name = "VT_CORE_1.5V";
+		regulator-min-microvolt = <1500000>;
+		regulator-max-microvolt = <1500000>;
+		gpio = <&gpe2 2 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		vol-down {
+			gpios = <&gpx2 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_VOLUMEDOWN>;
+			label = "volume down";
+			debounce-interval = <10>;
+		};
+
+		vol-up {
+			gpios = <&gpx2 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_VOLUMEUP>;
+			label = "volume up";
+			debounce-interval = <10>;
+		};
+
+		power {
+			gpios = <&gpx2 7 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_POWER>;
+			label = "power";
+			debounce-interval = <10>;
+			wakeup-source;
+		};
+
+		ok {
+			gpios = <&gpx3 5 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_OK>;
+			label = "ok";
+			debounce-interval = <10>;
+		};
+	};
+
+	wlan_pwrseq: sdhci3-pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		reset-gpios = <&gpl1 2 GPIO_ACTIVE_LOW>;
+	};
+
+	i2c_max17042_fuel: i2c-gpio {
+		compatible = "i2c-gpio";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		sda-gpios = <&gpy4 0 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+		scl-gpios = <&gpy4 1 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+		i2c-gpio,delay-us = <5>;
+
+		battery@36 {
+			compatible = "maxim,max17042";
+
+			interrupt-parent = <&gpx2>;
+			interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
+
+			pinctrl-0 = <&max17042_fuel_irq>;
+			pinctrl-names = "default";
+
+			reg = <0x36>;
+			maxim,over-heat-temp = <700>;
+			maxim,over-volt = <4500>;
+		};
+	};
+
+	spi-lcd {
+		compatible = "spi-gpio";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		num-chipselects = <1>;
+		cs-gpios = <&gpy4 3 GPIO_ACTIVE_LOW>;
+		sck-gpios = <&gpy3 1 GPIO_ACTIVE_HIGH>;
+		mosi-gpios = <&gpy3 3 GPIO_ACTIVE_HIGH>;
+
+		lcd@0 {
+			compatible = "samsung,ld9040";
+			reg = <0>;
+
+			spi-max-frequency = <1200000>;
+
+			vdd3-supply = <&vmipi_reg>;
+			vci-supply = <&vcclcd_reg>;
+
+			reset-gpios = <&gpy4 5 GPIO_ACTIVE_HIGH>;
+			power-on-delay = <10>;
+			reset-delay = <10>;
+
+			panel-width-mm = <90>;
+			panel-height-mm = <154>;
+
+			display-timings {
+				timing {
+					clock-frequency = <23492370>;
+					hactive = <480>;
+					vactive = <800>;
+					hback-porch = <16>;
+					hfront-porch = <16>;
+					vback-porch = <2>;
+					vfront-porch = <28>;
+					hsync-len = <2>;
+					vsync-len = <1>;
+					hsync-active = <0>;
+					vsync-active = <0>;
+					de-active = <0>;
+					pixelclk-active = <0>;
+				};
+			};
+
+			port {
+				lcd_ep: endpoint {
+					remote-endpoint = <&fimd_dpi_ep>;
+				};
+			};
+		};
+	};
+
+	fixed-rate-clocks {
+		xxti {
+			compatible = "samsung,clock-xxti";
+			clock-frequency = <0>;
+		};
+
+		xusbxti {
+			compatible = "samsung,clock-xusbxti";
+			clock-frequency = <24000000>;
+		};
+	};
+
+	thermal-zones {
+		cpu_thermal: cpu-thermal {
+			cooling-maps {
+				map0 {
+					/* Corresponds to 800MHz */
+					cooling-device = <&cpu0 2 2>;
+				};
+				map1 {
+					/* Corresponds to 200MHz */
+					cooling-device = <&cpu0 4 4>;
+				};
+			};
+		};
+	};
+};
+
+&camera {
+	status = "okay";
+};
+
+&cpu0 {
+	cpu0-supply = <&varm_breg>;
+};
+
+&ehci {
+	status = "okay";
+
+	phys = <&exynos_usbphy 1>;
+	phy-names = "host";
+};
+
+&exynos_usbphy {
+	status = "okay";
+
+	vbus-supply = <&safe1_sreg>;
+};
+
+&fimc_0 {
+	status = "okay";
+
+	assigned-clocks = <&clock CLK_MOUT_FIMC0>, <&clock CLK_SCLK_FIMC0>;
+	assigned-clock-parents = <&clock CLK_SCLK_MPLL>;
+	assigned-clock-rates = <0>, <160000000>;
+};
+
+&fimc_1 {
+	status = "okay";
+
+	assigned-clocks = <&clock CLK_MOUT_FIMC1>, <&clock CLK_SCLK_FIMC1>;
+	assigned-clock-parents = <&clock CLK_SCLK_MPLL>;
+	assigned-clock-rates = <0>, <160000000>;
+};
+
+&fimc_2 {
+	status = "okay";
+
+	assigned-clocks = <&clock CLK_MOUT_FIMC2>, <&clock CLK_SCLK_FIMC2>;
+	assigned-clock-parents = <&clock CLK_SCLK_MPLL>;
+	assigned-clock-rates = <0>, <160000000>;
+};
+
+&fimc_3 {
+	status = "okay";
+
+	assigned-clocks = <&clock CLK_MOUT_FIMC3>, <&clock CLK_SCLK_FIMC3>;
+	assigned-clock-parents = <&clock CLK_SCLK_MPLL>;
+	assigned-clock-rates = <0>, <160000000>;
+};
+
+&fimd {
+	status = "okay";
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	samsung,invert-vden;
+	samsung,invert-vclk;
+
+	pinctrl-0 = <&lcd_clk>, <&lcd_data24>;
+	pinctrl-names = "default";
+
+	port@3 {
+		reg = <3>;
+
+		fimd_dpi_ep: endpoint {
+			remote-endpoint = <&lcd_ep>;
+		};
+	};
+};
+
+&gpu {
+	status = "okay";
+
+	mali-supply = <&vg3d_breg>;
+	regulator-microvolt-offset = <50000>;
+	regulator-microsecs-delay = <50>;
+};
+
+&hsotg {
+	status = "okay";
+
+	dr_mode = "otg";
+	vusb_d-supply = <&vusb_reg>;
+	vusb_a-supply = <&vusbdac_reg>;
+};
+
+&i2c_3 {
+	status = "okay";
+
+	samsung,i2c-sda-delay = <100>;
+	samsung,i2c-slave-addr = <0x10>;
+	samsung,i2c-max-bus-freq = <100000>;
+
+	pinctrl-0 = <&i2c3_bus>;
+	pinctrl-names = "default";
+
+	mxt224-touchscreen@4a {
+		compatible = "atmel,maxtouch";
+		reg = <0x4a>;
+
+		interrupt-parent = <&gpx0>;
+		interrupts = <4 IRQ_TYPE_EDGE_FALLING>;
+	};
+};
+
+&i2c_5 {
+	status = "okay";
+
+	samsung,i2c-sda-delay = <100>;
+	samsung,i2c-slave-addr = <0x10>;
+	samsung,i2c-max-bus-freq = <100000>;
+
+	pinctrl-0 = <&i2c5_bus>;
+	pinctrl-names = "default";
+
+	max8997_pmic@66 {
+		compatible = "maxim,max8997-pmic";
+		reg = <0x66>;
+
+		interrupts-extended = <&gpx0 7 IRQ_TYPE_NONE>,
+				      <&gpx2 3 IRQ_TYPE_EDGE_FALLING>;
+
+		max8997,pmic-buck1-uses-gpio-dvs;
+		max8997,pmic-buck2-uses-gpio-dvs;
+		max8997,pmic-buck5-uses-gpio-dvs;
+
+		max8997,pmic-ignore-gpiodvs-side-effect;
+		max8997,pmic-buck125-default-dvs-idx = <0>;
+
+		max8997,pmic-buck125-dvs-gpios = <&gpx0 5 GPIO_ACTIVE_HIGH>,
+						 <&gpx0 6 GPIO_ACTIVE_HIGH>,
+						 <&gpl0 0 GPIO_ACTIVE_HIGH>;
+
+		max8997,pmic-buck1-dvs-voltage = <1350000>, <1300000>,
+						 <1250000>, <1200000>,
+						 <1150000>, <1100000>,
+						 <1000000>, <950000>;
+
+		max8997,pmic-buck2-dvs-voltage = <1100000>, <1000000>,
+						 <950000>,  <900000>,
+						 <1100000>, <1000000>,
+						 <950000>,  <900000>;
+
+		max8997,pmic-buck5-dvs-voltage = <1200000>, <1200000>,
+						 <1200000>, <1200000>,
+						 <1200000>, <1200000>,
+						 <1200000>, <1200000>;
+
+		pinctrl-0 = <&max8997_irq>, <&otg_gp>, <&usb_sel>;
+		pinctrl-names = "default";
+
+		regulators {
+			vadc_reg: LDO1 {
+				regulator-name = "VADC_3.3V_C210";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+
+			};
+			valive_reg: LDO2 {
+				regulator-name = "VALIVE_1.1V_C210";
+				regulator-min-microvolt = <1100000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-always-on;
+
+			};
+
+			vusb_reg: LDO3 {
+				regulator-name = "VUSB_1.1V_C210";
+				regulator-min-microvolt = <1100000>;
+				regulator-max-microvolt = <1100000>;
+			};
+
+			vmipi_reg: LDO4 {
+				regulator-name = "VMIPI_1.8V";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+			};
+
+			vhsic_reg: LDO5 {
+				regulator-name = "VHSIC_1.2V";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+				regulator-always-on;
+			};
+
+			vpda_reg: LDO6 {
+				regulator-name = "VCC_1.8V_PDA";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+			};
+
+			vcam_reg: LDO7 {
+				regulator-name = "CAM_ISP_1.8V";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+			};
+
+			vusbdac_reg: LDO8 {
+				regulator-name = "VUSB+VDAC_3.3V_C210";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+			};
+
+			vccpda_reg: LDO9 {
+				regulator-name = "VCC_2.8V_PDA";
+				regulator-min-microvolt = <2800000>;
+				regulator-max-microvolt = <2800000>;
+				regulator-always-on;
+			};
+
+			vtouch_reg: LDO11 {
+				regulator-name = "TOUCH_2.8V";
+				regulator-min-microvolt = <2800000>;
+				regulator-max-microvolt = <2800000>;
+				regulator-always-on;
+			};
+
+			vpll_reg: LDO10 {
+				regulator-name = "VPLL_1.1V";
+				regulator-min-microvolt = <1100000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-always-on;
+			};
+
+			vtcam_reg: LDO12 {
+				regulator-name = "VT_CAM_1.8V";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+			};
+
+			vcclcd_reg: LDO13 {
+				regulator-name = "VCC_3.0V_LCD";
+				regulator-min-microvolt = <3000000>;
+				regulator-max-microvolt = <3000000>;
+			};
+
+			vmotor_reg: LDO14 {
+				regulator-name = "VCC_2.8V_MOTOR";
+				regulator-min-microvolt = <2800000>;
+				regulator-max-microvolt = <2800000>;
+			};
+
+			vled_reg: LDO15 {
+				regulator-name = "LED_A_2.8V";
+				regulator-min-microvolt = <2800000>;
+				regulator-max-microvolt = <2800000>;
+			};
+
+			camsensor_reg: LDO16 {
+				regulator-name = "CAM_SENSOR_IO_1.8V";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+			};
+
+			vtf_reg: LDO17 {
+				regulator-name = "VTF_2.8V";
+				regulator-min-microvolt = <2800000>;
+				regulator-max-microvolt = <2800000>;
+			};
+
+			vtouchled_reg: LDO18 {
+				regulator-name = "TOUCH_LED_3.3V";
+				regulator-min-microvolt = <2500000>;
+				regulator-max-microvolt = <3300000>;
+			};
+
+			vddq_reg: LDO21 {
+				regulator-name = "VDDQ_M1M2_1.2V";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+				regulator-always-on;
+			};
+
+			varm_breg: BUCK1 {
+				regulator-name = "VARM_1.2V_C210";
+				regulator-min-microvolt = <65000>;
+				regulator-max-microvolt = <2225000>;
+				regulator-always-on;
+			};
+
+			vint_breg: BUCK2 {
+				regulator-name = "VINT_1.1V_C210";
+				regulator-min-microvolt = <65000>;
+				regulator-max-microvolt = <2225000>;
+				regulator-always-on;
+			};
+
+			vg3d_breg: BUCK3 {
+				regulator-name = "G3D_1.1V";
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <1200000>;
+				regulator-always-on;
+			};
+
+			camisp_breg: BUCK4 {
+				regulator-name = "CAM_ISP_CORE_1.2V";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+			};
+
+			vmem_breg: BUCK5 {
+				regulator-name = "VMEM_1.2V";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+				regulator-always-on;
+			};
+
+			vccsub_breg: BUCK7 {
+				regulator-name = "VCC_SUB_2.0V";
+				regulator-min-microvolt = <2000000>;
+				regulator-max-microvolt = <2000000>;
+				regulator-always-on;
+			};
+
+			safe1_sreg: ESAFEOUT1 {
+				regulator-name = "SAFEOUT1";
+			};
+
+			safe2_sreg: ESAFEOUT2 {
+				regulator-name = "SAFEOUT2";
+				regulator-boot-on;
+			};
+
+			charger_reg: CHARGER {
+				regulator-name = "CHARGER";
+				regulator-min-microamp = <60000>;
+				regulator-max-microamp = <2580000>;
+				regulator-always-on;
+			};
+
+			chargercv_reg: CHARGER_CV {
+				regulator-name = "CHARGER_CV";
+				regulator-min-microvolt = <3800000>;
+				regulator-max-microvolt = <4100000>;
+				regulator-always-on;
+			};
+		};
+	};
+};
+
+&i2c_7 {
+	status = "okay";
+
+	samsung,i2c-sda-delay = <100>;
+	samsung,i2c-slave-addr = <0x10>;
+	samsung,i2c-max-bus-freq = <400000>;
+
+	pinctrl-0 = <&i2c7_bus>;
+	pinctrl-names = "default";
+
+	ak8975@c {
+		compatible = "asahi-kasei,ak8975";
+		reg = <0x0c>;
+
+		gpios = <&gpx2 2 GPIO_ACTIVE_HIGH>;
+	};
+};
+
+&pinctrl_0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&sleep0>;
+
+	sleep0: sleep-states {
+		gpa0-0 {
+			samsung,pins = "gpa0-0";
+			samsung,pin-con-pdn = <EXYNOS_PIN_PDN_INPUT>;
+			samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_NONE>;
+		};
+
+		gpa0-1 {
+			samsung,pins = "gpa0-1";
+			samsung,pin-con-pdn = <EXYNOS_PIN_PDN_OUT0>;
+			samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_NONE>;
+		};
+
+		gpa0-2 {
+			samsung,pins = "gpa0-2";
+			samsung,pin-con-pdn = <EXYNOS_PIN_PDN_INPUT>;
+			samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_NONE>;
+		};
+
+		gpa0-3 {
+			samsung,pins = "gpa0-3";
+			samsung,pin-con-pdn = <EXYNOS_PIN_PDN_OUT1>;
+			samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_NONE>;
+		};
+	};
+};
+
+&pinctrl_1 {
+	mhl_int: mhl-int {
+		samsung,pins = "gpf3-5";
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+	};
+
+	i2c_mhl_bus: i2c-mhl-bus {
+		samsung,pins = "gpf0-4", "gpf0-6";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	usb_sel: usb-sel {
+		samsung,pins = "gpl0-6";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+		samsung,pin-val = <0>;
+	};
+
+	bt_en: bt-en {
+		samsung,pins = "gpl0-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+		samsung,pin-val = <0>;
+	};
+
+	bt_res: bt-res {
+		samsung,pins = "gpl1-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+		samsung,pin-val = <0>;
+	};
+
+	otg_gp: otg-gp {
+		samsung,pins = "gpx3-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+		samsung,pin-val = <0>;
+	};
+
+	mag_mhl_gpio: mag-mhl-gpio {
+		samsung,pins = "gpd0-2";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+	};
+
+	max8997_irq: max8997-irq {
+		samsung,pins = "gpx0-7";
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+	};
+
+	max17042_fuel_irq: max17042-fuel-irq {
+		samsung,pins = "gpx2-3";
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+	};
+
+	tsp224_irq: tsp224-irq {
+		samsung,pins = "gpx0-4";
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+	};
+};
+
+&sdhci_0 {
+	status = "okay";
+
+	bus-width = <8>;
+	non-removable;
+	vmmc-supply = <&vemmc_reg>;
+
+	pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_bus8>;
+	pinctrl-names = "default";
+};
+
+&sdhci_2 {
+	status = "okay";
+
+	bus-width = <4>;
+	cd-gpios = <&gpx3 4 GPIO_ACTIVE_LOW>;
+	vmmc-supply = <&vtf_reg>;
+
+	pinctrl-0 = <&sd2_clk>, <&sd2_cmd>, <&sd2_bus4>;
+	pinctrl-names = "default";
+};
+
+&sdhci_3 {
+	status = "okay";
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	non-removable;
+	bus-width = <4>;
+	mmc-pwrseq = <&wlan_pwrseq>;
+	vmmc-supply = <&vtf_reg>;
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&sd3_clk>, <&sd3_cmd>, <&sd3_bus4>;
+
+	brcmf: wifi@1 {
+		compatible = "brcm,bcm4330-fmac";
+		reg = <1>;
+
+		interrupt-parent = <&gpx2>;
+		interrupts = <5 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "host-wake";
+	};
+};
+
+&serial_0 {
+	status = "okay";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&bt_en>, <&bt_res>, <&uart0_data>, <&uart0_fctl>;
+
+	bluetooth {
+		compatible = "brcm,bcm4330-bt";
+
+		shutdown-gpios = <&gpl0 4 GPIO_ACTIVE_HIGH>;
+		reset-gpios = <&gpl1 0 GPIO_ACTIVE_HIGH>;
+		device-wakeup-gpios = <&gpx3 1 GPIO_ACTIVE_HIGH>;
+		host-wakeup-gpios = <&gpx2 6 GPIO_ACTIVE_HIGH>;
+	};
+};
+
+&serial_1 {
+	status = "okay";
+};
+
+&serial_2 {
+	status = "okay";
+};
+
+&serial_3 {
+	status = "okay";
+};
+
+&tmu {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/exynos4210-origen.dts b/arch/arm/boot/dts/exynos4210-origen.dts
index 0d1e1a9c2f6e..890525b10d22 100644
--- a/arch/arm/boot/dts/exynos4210-origen.dts
+++ b/arch/arm/boot/dts/exynos4210-origen.dts
@@ -251,12 +251,7 @@ ldo21_reg: LDO21 {
 			};
 
 			buck1_reg: BUCK1 {
-				/*
-				* HACK: The real name is VDD_ARM_1.2V,
-				* but exynos-cpufreq does not support
-				* DT-based regulator lookup yet.
-				*/
-				regulator-name = "vdd_arm";
+				regulator-name = "VDD_ARM_1.2V";
 				regulator-min-microvolt = <950000>;
 				regulator-max-microvolt	= <1350000>;
 				regulator-always-on;
diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
index 7c39dd1c4d3a..3d791db6095c 100644
--- a/arch/arm/boot/dts/exynos4210-trats.dts
+++ b/arch/arm/boot/dts/exynos4210-trats.dts
@@ -121,6 +121,11 @@ ok-key {
 		};
 	};
 
+	wlan_pwrseq: sdhci3-pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		reset-gpios = <&gpl1 2 GPIO_ACTIVE_LOW>;
+	};
+
 	fixed-rate-clocks {
 		xxti {
 			compatible = "samsung,clock-xxti";
@@ -280,11 +285,10 @@ &i2c_5 {
 
 	max8997_pmic@66 {
 		compatible = "maxim,max8997-pmic";
-		interrupts-extended = <&gpx0 7 0>, <&gpx2 3 0>;
 
 		reg = <0x66>;
-		interrupt-parent = <&gpx0>;
-		interrupts = <7 IRQ_TYPE_NONE>;
+		interrupts-extended = <&gpx0 7 IRQ_TYPE_LEVEL_LOW>,
+				      <&gpx2 3 IRQ_TYPE_EDGE_FALLING>;
 
 		max8997,pmic-buck1-uses-gpio-dvs;
 		max8997,pmic-buck2-uses-gpio-dvs;
@@ -403,12 +407,7 @@ vddq_reg: LDO21 {
 			};
 
 			varm_breg: BUCK1 {
-			     /*
-			      * HACK: The real name is VARM_1.2V_C210,
-			      * but exynos-cpufreq does not support
-			      * DT-based regulator lookup yet.
-			      */
-			     regulator-name = "vdd_arm";
+			     regulator-name = "VARM_1.2V_C210";
 			     regulator-min-microvolt = <900000>;
 			     regulator-max-microvolt = <1350000>;
 			     regulator-always-on;
@@ -471,6 +470,30 @@ &sdhci_2 {
 	status = "okay";
 };
 
+&sdhci_3 {
+	status = "okay";
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	non-removable;
+	bus-width = <4>;
+	mmc-pwrseq = <&wlan_pwrseq>;
+	vmmc-supply = <&tflash_reg>;
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&sd3_clk>, <&sd3_cmd>, <&sd3_bus4>;
+
+	brcmf: wifi@1 {
+		compatible = "brcm,bcm4330-fmac";
+		reg = <1>;
+
+		interrupt-parent = <&gpx2>;
+		interrupts = <5 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "host-wake";
+	};
+};
+
 &serial_0 {
 	status = "okay";
 };
diff --git a/arch/arm/boot/dts/exynos4210-universal_c210.dts b/arch/arm/boot/dts/exynos4210-universal_c210.dts
index 9dda6bdb9253..02fde1a75ebd 100644
--- a/arch/arm/boot/dts/exynos4210-universal_c210.dts
+++ b/arch/arm/boot/dts/exynos4210-universal_c210.dts
@@ -50,6 +50,11 @@ vemmc_reg: voltage-regulator {
 		enable-active-high;
 	};
 
+	wlan_pwrseq: sdhci3-pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		reset-gpios = <&gpe3 1 GPIO_ACTIVE_LOW>;
+	};
+
 	gpio-keys {
 		compatible = "gpio-keys";
 
@@ -164,7 +169,8 @@ hdmi_en: voltage-regulator-hdmi-5v {
 
 	hdmi_ddc: i2c-ddc {
 		compatible = "i2c-gpio";
-		gpios = <&gpe4 2 GPIO_ACTIVE_HIGH &gpe4 3 GPIO_ACTIVE_HIGH>;
+		sda-gpios = <&gpe4 2 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+		scl-gpios = <&gpe4 3 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
 		i2c-gpio,delay-us = <100>;
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -317,7 +323,7 @@ vdd_arm_reg: pmic@60 {
 		max8952,sync-freq = <0>;
 		max8952,ramp-speed = <0>;
 
-		regulator-name = "vdd_arm";
+		regulator-name = "VARM_1.2V_C210";
 		regulator-min-microvolt = <770000>;
 		regulator-max-microvolt = <1400000>;
 		regulator-always-on;
@@ -563,6 +569,29 @@ &sdhci_2 {
 	status = "okay";
 };
 
+&sdhci_3 {
+	status = "okay";
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	non-removable;
+	bus-width = <4>;
+	mmc-pwrseq = <&wlan_pwrseq>;
+	vmmc-supply = <&ldo5_reg>;
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&sd3_clk>, <&sd3_cmd>, <&sd3_bus4>;
+
+	brcmf: wifi@1 {
+		compatible = "brcm,bcm4330-fmac";
+		reg = <1>;
+		interrupt-parent = <&gpx2>;
+		interrupts = <5 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "host-wake";
+	};
+};
+
 &serial_0 {
 	status = "okay";
 	/delete-property/dmas;
diff --git a/arch/arm/boot/dts/exynos4412-galaxy-s3.dtsi b/arch/arm/boot/dts/exynos4412-galaxy-s3.dtsi
index 44f97546dd0a..53b3ca3effab 100644
--- a/arch/arm/boot/dts/exynos4412-galaxy-s3.dtsi
+++ b/arch/arm/boot/dts/exynos4412-galaxy-s3.dtsi
@@ -53,7 +53,8 @@ ps_als_reg: voltage-regulator-8 {
 
 	i2c_ak8975: i2c-gpio-0 {
 		compatible = "i2c-gpio";
-		gpios = <&gpy2 4 GPIO_ACTIVE_HIGH>, <&gpy2 5 GPIO_ACTIVE_HIGH>;
+		sda-gpios = <&gpy2 4 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+		scl-gpios = <&gpy2 5 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
 		i2c-gpio,delay-us = <2>;
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -68,7 +69,8 @@ ak8975@c {
 
 	i2c_cm36651: i2c-gpio-2 {
 		compatible = "i2c-gpio";
-		gpios = <&gpf0 0 GPIO_ACTIVE_LOW>, <&gpf0 1 GPIO_ACTIVE_LOW>;
+		sda-gpios = <&gpf0 0 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+		scl-gpios = <&gpf0 1 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
 		i2c-gpio,delay-us = <2>;
 		#address-cells = <1>;
 		#size-cells = <0>;
diff --git a/arch/arm/boot/dts/exynos4412-midas.dtsi b/arch/arm/boot/dts/exynos4412-midas.dtsi
index 3023bc3b68ce..2c8111c6b065 100644
--- a/arch/arm/boot/dts/exynos4412-midas.dtsi
+++ b/arch/arm/boot/dts/exynos4412-midas.dtsi
@@ -140,7 +140,8 @@ key-ok {
 
 	i2c_max77693: i2c-gpio-1 {
 		compatible = "i2c-gpio";
-		gpios = <&gpm2 0 GPIO_ACTIVE_HIGH>, <&gpm2 1 GPIO_ACTIVE_HIGH>;
+		sda-gpios = <&gpm2 0 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+		scl-gpios = <&gpm2 1 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
 		i2c-gpio,delay-us = <2>;
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -188,7 +189,8 @@ charger {
 
 	i2c_max77693_fuel: i2c-gpio-3 {
 		compatible = "i2c-gpio";
-		gpios = <&gpf1 5 GPIO_ACTIVE_HIGH>, <&gpf1 4 GPIO_ACTIVE_HIGH>;
+		sda-gpios = <&gpf1 5 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+		scl-gpios = <&gpf1 4 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
 		i2c-gpio,delay-us = <2>;
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -228,7 +230,8 @@ touchkey@20 {
 
 	i2c-mhl {
 		compatible = "i2c-gpio";
-		gpios = <&gpf0 4 GPIO_ACTIVE_HIGH>, <&gpf0 6 GPIO_ACTIVE_HIGH>;
+		sda-gpios = <&gpf0 4 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+		scl-gpios = <&gpf0 6 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
 		i2c-gpio,delay-us = <100>;
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -820,7 +823,7 @@ ldo26_reg: LDO26 {
 			};
 
 			buck1_reg: BUCK1 {
-				regulator-name = "vdd_mif";
+				regulator-name = "VDD_MIF";
 				regulator-min-microvolt = <850000>;
 				regulator-max-microvolt = <1100000>;
 				regulator-always-on;
@@ -831,7 +834,7 @@ regulator-state-mem {
 			};
 
 			buck2_reg: BUCK2 {
-				regulator-name = "vdd_arm";
+				regulator-name = "VDD_ARM";
 				regulator-min-microvolt = <850000>;
 				regulator-max-microvolt = <1500000>;
 				regulator-always-on;
@@ -842,7 +845,7 @@ regulator-state-mem {
 			};
 
 			buck3_reg: BUCK3 {
-				regulator-name = "vdd_int";
+				regulator-name = "VDD_INT";
 				regulator-min-microvolt = <850000>;
 				regulator-max-microvolt = <1150000>;
 				regulator-always-on;
@@ -853,7 +856,7 @@ regulator-state-mem {
 			};
 
 			buck4_reg: BUCK4 {
-				regulator-name = "vdd_g3d";
+				regulator-name = "VDD_G3D";
 				regulator-min-microvolt = <850000>;
 				regulator-max-microvolt = <1150000>;
 				regulator-boot-on;
diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
index 73d6a71da88d..a5c1ce1e396c 100644
--- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
+++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
@@ -430,7 +430,7 @@ ldo25_reg: LDO25 {
 			};
 
 			buck1_reg: BUCK1 {
-				regulator-name = "vdd_mif";
+				regulator-name = "VDD_MIF";
 				regulator-min-microvolt = <900000>;
 				regulator-max-microvolt = <1100000>;
 				regulator-always-on;
@@ -438,7 +438,7 @@ buck1_reg: BUCK1 {
 			};
 
 			buck2_reg: BUCK2 {
-				regulator-name = "vdd_arm";
+				regulator-name = "VDD_ARM";
 				regulator-min-microvolt = <900000>;
 				regulator-max-microvolt = <1350000>;
 				regulator-always-on;
@@ -446,7 +446,7 @@ buck2_reg: BUCK2 {
 			};
 
 			buck3_reg: BUCK3 {
-				regulator-name = "vdd_int";
+				regulator-name = "VDD_INT";
 				regulator-min-microvolt = <900000>;
 				regulator-max-microvolt = <1050000>;
 				regulator-always-on;
@@ -454,7 +454,7 @@ buck3_reg: BUCK3 {
 			};
 
 			buck4_reg: BUCK4 {
-				regulator-name = "vdd_g3d";
+				regulator-name = "VDD_G3D";
 				regulator-min-microvolt = <900000>;
 				regulator-max-microvolt = <1100000>;
 				regulator-microvolt-offset = <50000>;
diff --git a/arch/arm/boot/dts/exynos4412-origen.dts b/arch/arm/boot/dts/exynos4412-origen.dts
index ecd14b283a6b..dc865be40751 100644
--- a/arch/arm/boot/dts/exynos4412-origen.dts
+++ b/arch/arm/boot/dts/exynos4412-origen.dts
@@ -363,7 +363,7 @@ ldo28_reg: LDO28 {
 			};
 
 			buck1_reg: BUCK1 {
-				regulator-name = "vdd_mif";
+				regulator-name = "VDD_MIF";
 				regulator-min-microvolt = <950000>;
 				regulator-max-microvolt	= <1100000>;
 				regulator-always-on;
@@ -372,7 +372,7 @@ buck1_reg: BUCK1 {
 			};
 
 			buck2_reg: BUCK2 {
-				regulator-name = "vdd_arm";
+				regulator-name = "VDD_ARM";
 				regulator-min-microvolt = <900000>;
 				regulator-max-microvolt	= <1350000>;
 				regulator-always-on;
@@ -381,7 +381,7 @@ buck2_reg: BUCK2 {
 			};
 
 			buck3_reg: BUCK3 {
-				regulator-name = "vdd_int";
+				regulator-name = "VDD_INT";
 				regulator-min-microvolt = <900000>;
 				regulator-max-microvolt	= <1200000>;
 				regulator-always-on;
@@ -390,7 +390,7 @@ buck3_reg: BUCK3 {
 			};
 
 			buck4_reg: BUCK4 {
-				regulator-name = "vdd_g3d";
+				regulator-name = "VDD_G3D";
 				regulator-min-microvolt = <750000>;
 				regulator-max-microvolt	= <1500000>;
 				regulator-always-on;
@@ -399,7 +399,7 @@ buck4_reg: BUCK4 {
 			};
 
 			buck5_reg: BUCK5 {
-				regulator-name = "vdd_m12";
+				regulator-name = "VDD_M12";
 				regulator-min-microvolt = <750000>;
 				regulator-max-microvolt	= <1500000>;
 				regulator-always-on;
@@ -408,7 +408,7 @@ buck5_reg: BUCK5 {
 			};
 
 			buck6_reg: BUCK6 {
-				regulator-name = "vdd12_5m";
+				regulator-name = "VDD12_5M";
 				regulator-min-microvolt = <750000>;
 				regulator-max-microvolt	= <1500000>;
 				regulator-always-on;
@@ -417,7 +417,7 @@ buck6_reg: BUCK6 {
 			};
 
 			buck9_reg: BUCK9 {
-				regulator-name = "vddf28_emmc";
+				regulator-name = "VDDF28_EMMC";
 				regulator-min-microvolt = <750000>;
 				regulator-max-microvolt	= <3000000>;
 				regulator-always-on;
diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts
index 6904091d4837..c4cc7611898c 100644
--- a/arch/arm/boot/dts/exynos5250-arndale.dts
+++ b/arch/arm/boot/dts/exynos5250-arndale.dts
@@ -454,7 +454,7 @@ ldo26_reg: LDO26 {
 			};
 
 			buck1_reg: BUCK1 {
-				regulator-name = "vdd_mif";
+				regulator-name = "VDD_MIF";
 				regulator-min-microvolt = <950000>;
 				regulator-max-microvolt = <1200000>;
 				regulator-always-on;
@@ -463,7 +463,7 @@ buck1_reg: BUCK1 {
 			};
 
 			buck2_reg: BUCK2 {
-				regulator-name = "vdd_arm";
+				regulator-name = "VDD_ARM";
 				regulator-min-microvolt = <912500>;
 				regulator-max-microvolt = <1300000>;
 				regulator-always-on;
@@ -472,7 +472,7 @@ buck2_reg: BUCK2 {
 			};
 
 			buck3_reg: BUCK3 {
-				regulator-name = "vdd_int";
+				regulator-name = "VDD_INT";
 				regulator-min-microvolt = <900000>;
 				regulator-max-microvolt = <1200000>;
 				regulator-always-on;
@@ -481,7 +481,7 @@ buck3_reg: BUCK3 {
 			};
 
 			buck4_reg: BUCK4 {
-				regulator-name = "vdd_g3d";
+				regulator-name = "VDD_G3D";
 				regulator-min-microvolt = <850000>;
 				regulator-max-microvolt = <1300000>;
 				regulator-always-on;
@@ -641,9 +641,8 @@ i2c_ddc: i2c-gpio {
 		pinctrl-0 = <&i2c2_gpio_bus>;
 		status = "okay";
 		compatible = "i2c-gpio";
-		gpios = <&gpa0 6 0 /* sda */
-			 &gpa0 7 0 /* scl */
-			>;
+		sda-gpios = <&gpa0 6 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+		scl-gpios = <&gpa0 7 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
 		i2c-gpio,delay-us = <2>;
 		#address-cells = <1>;
 		#size-cells = <0>;
diff --git a/arch/arm/boot/dts/exynos5420-arndale-octa.dts b/arch/arm/boot/dts/exynos5420-arndale-octa.dts
index e9a09dd0a49b..dd7f8385d81e 100644
--- a/arch/arm/boot/dts/exynos5420-arndale-octa.dts
+++ b/arch/arm/boot/dts/exynos5420-arndale-octa.dts
@@ -673,7 +673,7 @@ regulator-state-mem {
 			};
 
 			buck2_reg: BUCK2 {
-				regulator-name = "vdd_arm";
+				regulator-name = "PVDD_ARM_1V0";
 				regulator-min-microvolt = <800000>;
 				regulator-max-microvolt = <1500000>;
 				regulator-always-on;
diff --git a/arch/arm/boot/dts/imx6dl-colibri-v1_1-eval-v3.dts b/arch/arm/boot/dts/imx6dl-colibri-v1_1-eval-v3.dts
new file mode 100644
index 000000000000..223275f028f1
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-colibri-v1_1-eval-v3.dts
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright 2020 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx6dl-colibri-eval-v3.dts"
+#include "imx6qdl-colibri-v1_1-uhs.dtsi"
+
+/ {
+	model = "Toradex Colibri iMX6DL/S V1.1 on Colibri Evaluation Board V3";
+	compatible = "toradex,colibri_imx6dl-v1_1-eval-v3",
+		     "toradex,colibri_imx6dl-v1_1",
+		     "toradex,colibri_imx6dl-eval-v3",
+		     "toradex,colibri_imx6dl",
+		     "fsl,imx6dl";
+};
+
+/* Colibri MMC */
+&usdhc1 {
+	status = "okay";
+	/*
+	 * Please make sure your carrier board does not pull-up any of
+	 * the MMC/SD signals to 3.3 volt before attempting to activate
+	 * UHS-I support.
+	 * To let signaling voltage be changed to 1.8V, please
+	 * delete no-1-8-v property (example below):
+	 * /delete-property/no-1-8-v;
+	 */
+};
diff --git a/arch/arm/boot/dts/imx6dl-yapp4-ursa.dts b/arch/arm/boot/dts/imx6dl-yapp4-ursa.dts
index 0d594e4bd559..a1173bf5bff5 100644
--- a/arch/arm/boot/dts/imx6dl-yapp4-ursa.dts
+++ b/arch/arm/boot/dts/imx6dl-yapp4-ursa.dts
@@ -38,7 +38,7 @@ &reg_usb_h1_vbus {
 };
 
 &switch_ports {
-	/delete-node/ port@2;
+	/delete-node/ port@3;
 };
 
 &touchscreen {
diff --git a/arch/arm/boot/dts/imx6q-dhcom-pdk2.dts b/arch/arm/boot/dts/imx6q-dhcom-pdk2.dts
index bb74fc62d913..a2dd7e549568 100644
--- a/arch/arm/boot/dts/imx6q-dhcom-pdk2.dts
+++ b/arch/arm/boot/dts/imx6q-dhcom-pdk2.dts
@@ -22,6 +22,53 @@ clk_ext_audio_codec: clock-codec {
 		clock-frequency = <24000000>;
 	};
 
+	display_bl: display-bl {
+		compatible = "pwm-backlight";
+		pwms = <&pwm1 0 50000 PWM_POLARITY_INVERTED>;
+		brightness-levels = <0 16 22 30 40 55 75 102 138 188 255>;
+		default-brightness-level = <8>;
+		enable-gpios = <&gpio3 27 GPIO_ACTIVE_HIGH>;
+		status = "okay";
+	};
+
+	lcd_display: disp0 {
+		compatible = "fsl,imx-parallel-display";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		interface-pix-fmt = "rgb24";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_ipu1_lcdif>;
+		status = "okay";
+
+		port@0 {
+			reg = <0>;
+
+			lcd_display_in: endpoint {
+				remote-endpoint = <&ipu1_di0_disp0>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+
+			lcd_display_out: endpoint {
+				remote-endpoint = <&lcd_panel_in>;
+			};
+		};
+	};
+
+	panel {
+		compatible = "edt,etm0700g0edh6";
+		ddc-i2c-bus = <&i2c2>;
+		backlight = <&display_bl>;
+
+		port {
+			lcd_panel_in: endpoint {
+				remote-endpoint = <&lcd_display_out>;
+			};
+		};
+	};
+
 	sound {
 		compatible = "fsl,imx-audio-sgtl5000";
 		model = "imx-sgtl5000";
@@ -65,6 +112,15 @@ sgtl5000: codec@a {
 		VDDA-supply = <&reg_3p3v>;
 		VDDIO-supply = <&sw2_reg>;
 	};
+
+	touchscreen@38 {
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_touchscreen>;
+		compatible = "edt,edt-ft5406";
+		reg = <0x38>;
+		interrupt-parent = <&gpio4>;
+		interrupts = <5 IRQ_TYPE_EDGE_FALLING>; /* GPIO E */
+	};
 };
 
 &iomuxc {
@@ -77,9 +133,7 @@ MX6QDL_PAD_GPIO_2__GPIO1_IO02		0x400120b0
 			MX6QDL_PAD_GPIO_4__GPIO1_IO04		0x400120b0
 			MX6QDL_PAD_GPIO_5__GPIO1_IO05		0x400120b0
 			MX6QDL_PAD_CSI0_DAT17__GPIO6_IO03	0x400120b0
-			MX6QDL_PAD_GPIO_19__GPIO4_IO05		0x120b0
 			MX6QDL_PAD_DI0_PIN4__GPIO4_IO20		0x400120b0
-			MX6QDL_PAD_EIM_D27__GPIO3_IO27		0x120b0
 			MX6QDL_PAD_KEY_ROW0__GPIO4_IO07		0x120b0
 			MX6QDL_PAD_KEY_COL1__GPIO4_IO08		0x400120b0
 			MX6QDL_PAD_NANDF_CS1__GPIO6_IO14	0x400120b0
@@ -132,6 +186,52 @@ MX6QDL_PAD_EIM_D26__GPIO3_IO26		0x000b1
 		>;
 	};
 
+	pinctrl_ipu1_lcdif: ipu1-lcdif-grp {
+		fsl,pins = <
+			MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK	0x38
+			MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15		0x38
+			MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02		0x38
+			MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03		0x38
+			MX6QDL_PAD_DISP0_DAT0__IPU1_DISP0_DATA00	0x38
+			MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01	0x38
+			MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02	0x38
+			MX6QDL_PAD_DISP0_DAT3__IPU1_DISP0_DATA03	0x38
+			MX6QDL_PAD_DISP0_DAT4__IPU1_DISP0_DATA04	0x38
+			MX6QDL_PAD_DISP0_DAT5__IPU1_DISP0_DATA05	0x38
+			MX6QDL_PAD_DISP0_DAT6__IPU1_DISP0_DATA06	0x38
+			MX6QDL_PAD_DISP0_DAT7__IPU1_DISP0_DATA07	0x38
+			MX6QDL_PAD_DISP0_DAT8__IPU1_DISP0_DATA08	0x38
+			MX6QDL_PAD_DISP0_DAT9__IPU1_DISP0_DATA09	0x38
+			MX6QDL_PAD_DISP0_DAT10__IPU1_DISP0_DATA10	0x38
+			MX6QDL_PAD_DISP0_DAT11__IPU1_DISP0_DATA11	0x38
+			MX6QDL_PAD_DISP0_DAT12__IPU1_DISP0_DATA12	0x38
+			MX6QDL_PAD_DISP0_DAT13__IPU1_DISP0_DATA13	0x38
+			MX6QDL_PAD_DISP0_DAT14__IPU1_DISP0_DATA14	0x38
+			MX6QDL_PAD_DISP0_DAT15__IPU1_DISP0_DATA15	0x38
+			MX6QDL_PAD_DISP0_DAT16__IPU1_DISP0_DATA16	0x38
+			MX6QDL_PAD_DISP0_DAT17__IPU1_DISP0_DATA17	0x38
+			MX6QDL_PAD_DISP0_DAT18__IPU1_DISP0_DATA18	0x38
+			MX6QDL_PAD_DISP0_DAT19__IPU1_DISP0_DATA19	0x38
+			MX6QDL_PAD_DISP0_DAT20__IPU1_DISP0_DATA20	0x38
+			MX6QDL_PAD_DISP0_DAT21__IPU1_DISP0_DATA21	0x38
+			MX6QDL_PAD_DISP0_DAT22__IPU1_DISP0_DATA22	0x38
+			MX6QDL_PAD_DISP0_DAT23__IPU1_DISP0_DATA23	0x38
+			MX6QDL_PAD_EIM_D27__GPIO3_IO27			0x120b0
+		>;
+	};
+
+	pinctrl_pwm1: pwm1-grp {
+		fsl,pins = <
+			MX6QDL_PAD_SD1_DAT3__PWM1_OUT		0x1b0b1
+		>;
+	};
+
+	pinctrl_touchscreen: touchscreen-grp {
+		fsl,pins = <
+			MX6QDL_PAD_GPIO_19__GPIO4_IO05		0x1b0b1
+		>;
+	};
+
 	pinctrl_pcie: pcie-grp {
 		fsl,pins = <
 			MX6QDL_PAD_CSI0_DATA_EN__GPIO5_IO20	0x1b0b1
@@ -139,6 +239,10 @@ MX6QDL_PAD_CSI0_DATA_EN__GPIO5_IO20	0x1b0b1
 	};
 };
 
+&ipu1_di0_disp0 {
+	remote-endpoint = <&lcd_display_in>;
+};
+
 &pcie {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_pcie>;
@@ -146,6 +250,13 @@ &pcie {
 	status = "okay";
 };
 
+&pwm1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm1>;
+	#pwm-cells = <3>;
+	status = "okay";
+};
+
 &ssi1 {
 	status = "okay";
 };
diff --git a/arch/arm/boot/dts/imx6qdl-colibri-v1_1-uhs.dtsi b/arch/arm/boot/dts/imx6qdl-colibri-v1_1-uhs.dtsi
new file mode 100644
index 000000000000..7672fbfc29be
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-colibri-v1_1-uhs.dtsi
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright 2020 Toradex
+ */
+
+&iomuxc {
+	pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+		fsl,pins = <
+			MX6QDL_PAD_SD1_CMD__SD1_CMD    0x170b1
+			MX6QDL_PAD_SD1_CLK__SD1_CLK    0x100b1
+			MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x170b1
+			MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x170b1
+			MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x170b1
+			MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x170b1
+		>;
+	};
+
+	pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+		fsl,pins = <
+			MX6QDL_PAD_SD1_CMD__SD1_CMD    0x170f1
+			MX6QDL_PAD_SD1_CLK__SD1_CLK    0x100f1
+			MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x170f1
+			MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x170f1
+			MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x170f1
+			MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x170f1
+		>;
+	};
+};
+
+/* Colibri MMC */
+&usdhc1 {
+	pinctrl-names = "default", "state_100mhz", "state_200mhz";
+	pinctrl-0 = <&pinctrl_usdhc1 &pinctrl_mmc_cd>;
+	pinctrl-1 = <&pinctrl_usdhc1_100mhz &pinctrl_mmc_cd>;
+	pinctrl-2 = <&pinctrl_usdhc1_200mhz &pinctrl_mmc_cd>;
+	vmmc-supply = <&reg_module_3v3>;
+	vqmmc-supply = <&vgen3_reg>;
+	wakeup-source;
+	keep-power-in-suspend;
+	sd-uhs-sdr12;
+	sd-uhs-sdr25;
+	sd-uhs-sdr50;
+	sd-uhs-sdr104;
+};
diff --git a/arch/arm/boot/dts/imx6qdl-colibri.dtsi b/arch/arm/boot/dts/imx6qdl-colibri.dtsi
index 6e3c6b4925a7..240b86d2eb71 100644
--- a/arch/arm/boot/dts/imx6qdl-colibri.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-colibri.dtsi
@@ -193,7 +193,16 @@ vgen2_reg: vgen2 {
 				regulator-always-on;
 			};
 
-			/* vgen3: unused */
+			/*
+			 * +V3.3_1.8_SD1 coming off VGEN3 and supplying
+			 * the i.MX 6 NVCC_SD1.
+			 */
+			vgen3_reg: vgen3 {
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
 
 			vgen4_reg: vgen4 {
 				regulator-min-microvolt = <1800000>;
diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index 47982889d774..98da446aa0f2 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -1039,13 +1039,13 @@ fec: ethernet@2188000 {
 				compatible = "fsl,imx6q-fec";
 				reg = <0x02188000 0x4000>;
 				interrupt-names = "int0", "pps";
-				interrupts-extended =
-					<&intc 0 118 IRQ_TYPE_LEVEL_HIGH>,
-					<&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+				interrupts = <0 118 IRQ_TYPE_LEVEL_HIGH>,
+					     <0 119 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&clks IMX6QDL_CLK_ENET>,
 					 <&clks IMX6QDL_CLK_ENET>,
 					 <&clks IMX6QDL_CLK_ENET_REF>;
 				clock-names = "ipg", "ahb", "ptp";
+				gpr = <&gpr>;
 				status = "disabled";
 			};
 
diff --git a/arch/arm/boot/dts/imx6qp.dtsi b/arch/arm/boot/dts/imx6qp.dtsi
index 93b89dc1f53b..b310f13a53f2 100644
--- a/arch/arm/boot/dts/imx6qp.dtsi
+++ b/arch/arm/boot/dts/imx6qp.dtsi
@@ -77,7 +77,6 @@ prg2: prg@21cd000 {
 };
 
 &fec {
-	/delete-property/interrupts-extended;
 	interrupts = <0 118 IRQ_TYPE_LEVEL_HIGH>,
 		     <0 119 IRQ_TYPE_LEVEL_HIGH>;
 };
diff --git a/arch/arm/boot/dts/imx7-tqma7.dtsi b/arch/arm/boot/dts/imx7-tqma7.dtsi
index 9aaed85138cb..8773344b54aa 100644
--- a/arch/arm/boot/dts/imx7-tqma7.dtsi
+++ b/arch/arm/boot/dts/imx7-tqma7.dtsi
@@ -16,7 +16,7 @@ memory@80000000 {
 };
 
 &cpu0 {
-	arm-supply = <&sw1a_reg>;
+	cpu-supply = <&sw1a_reg>;
 };
 
 &i2c1 {
diff --git a/arch/arm/boot/dts/imx7d-cl-som-imx7.dts b/arch/arm/boot/dts/imx7d-cl-som-imx7.dts
index 89267cd59037..713483c39c9d 100644
--- a/arch/arm/boot/dts/imx7d-cl-som-imx7.dts
+++ b/arch/arm/boot/dts/imx7d-cl-som-imx7.dts
@@ -37,6 +37,10 @@ &cpu0 {
 	cpu-supply = <&sw1a_reg>;
 };
 
+&cpu1 {
+	cpu-supply = <&sw1a_reg>;
+};
+
 &fec1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_enet1>;
diff --git a/arch/arm/boot/dts/imx7d-colibri.dtsi b/arch/arm/boot/dts/imx7d-colibri.dtsi
index c59d72e50920..219a0404a058 100644
--- a/arch/arm/boot/dts/imx7d-colibri.dtsi
+++ b/arch/arm/boot/dts/imx7d-colibri.dtsi
@@ -13,6 +13,10 @@ memory@80000000 {
 	};
 };
 
+&cpu1 {
+	cpu-supply = <&reg_DCDC2>;
+};
+
 &gpmi {
 	status = "okay";
 };
diff --git a/arch/arm/boot/dts/imx7d-nitrogen7.dts b/arch/arm/boot/dts/imx7d-nitrogen7.dts
index 6b4acea1ef79..e0751e6ba3c0 100644
--- a/arch/arm/boot/dts/imx7d-nitrogen7.dts
+++ b/arch/arm/boot/dts/imx7d-nitrogen7.dts
@@ -121,6 +121,10 @@ &cpu0 {
 	cpu-supply = <&sw1a_reg>;
 };
 
+&cpu1 {
+	cpu-supply = <&sw1a_reg>;
+};
+
 &fec1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_enet1>;
diff --git a/arch/arm/boot/dts/imx7d-sdb.dts b/arch/arm/boot/dts/imx7d-sdb.dts
index 869efbc4af42..17cca8a9f77b 100644
--- a/arch/arm/boot/dts/imx7d-sdb.dts
+++ b/arch/arm/boot/dts/imx7d-sdb.dts
@@ -162,6 +162,10 @@ &cpu0 {
 	cpu-supply = <&sw1a_reg>;
 };
 
+&cpu1 {
+	cpu-supply = <&sw1a_reg>;
+};
+
 &ecspi3 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_ecspi3>;
diff --git a/arch/arm/boot/dts/imx7d-tqma7.dtsi b/arch/arm/boot/dts/imx7d-tqma7.dtsi
index 8ad3048dac0d..598aed1ffd99 100644
--- a/arch/arm/boot/dts/imx7d-tqma7.dtsi
+++ b/arch/arm/boot/dts/imx7d-tqma7.dtsi
@@ -9,3 +9,7 @@
 
 #include "imx7d.dtsi"
 #include "imx7-tqma7.dtsi"
+
+&cpu1 {
+	cpu-supply = <&sw1a_reg>;
+};
diff --git a/arch/arm/boot/dts/imx7d-zii-rmu2.dts b/arch/arm/boot/dts/imx7d-zii-rmu2.dts
index 2b8d6cc45a53..e5e20b07f184 100644
--- a/arch/arm/boot/dts/imx7d-zii-rmu2.dts
+++ b/arch/arm/boot/dts/imx7d-zii-rmu2.dts
@@ -33,7 +33,7 @@ debug {
 };
 
 &cpu0 {
-	arm-supply = <&sw1a_reg>;
+	cpu-supply = <&sw1a_reg>;
 };
 
 &ecspi1 {
diff --git a/arch/arm/boot/dts/imx7d-zii-rpu2.dts b/arch/arm/boot/dts/imx7d-zii-rpu2.dts
index 39812c92bf0d..cbf0dbb4c198 100644
--- a/arch/arm/boot/dts/imx7d-zii-rpu2.dts
+++ b/arch/arm/boot/dts/imx7d-zii-rpu2.dts
@@ -182,7 +182,7 @@ &adc2 {
 };
 
 &cpu0 {
-	arm-supply = <&sw1a_reg>;
+	cpu-supply = <&sw1a_reg>;
 };
 
 &clks {
diff --git a/arch/arm/boot/dts/keystone-k2g-evm.dts b/arch/arm/boot/dts/keystone-k2g-evm.dts
index b7f10bf94576..db640bab8c1d 100644
--- a/arch/arm/boot/dts/keystone-k2g-evm.dts
+++ b/arch/arm/boot/dts/keystone-k2g-evm.dts
@@ -45,6 +45,19 @@ vcc1v8_ldo1_reg: fixedregulator-vcc1v8-ldo1 {
 		regulator-max-microvolt = <1800000>;
 		regulator-always-on;
 	};
+
+	hdmi: connector {
+		compatible = "hdmi-connector";
+		label = "hdmi";
+
+		type = "a";
+
+		port {
+			hdmi_connector_in: endpoint {
+				remote-endpoint = <&sii9022_out>;
+			};
+		};
+	};
 };
 
 &k2g_pinctrl {
@@ -89,6 +102,13 @@ K2G_CORE_IOPAD(0x1380) (BUFFER_CLASS_B | PIN_PULLUP | MUX_MODE0)	/* i2c0_sda.i2c
 		>;
 	};
 
+	i2c1_pins: pinmux_i2c1_pins {
+		pinctrl-single,pins = <
+			K2G_CORE_IOPAD(0x1384) (BUFFER_CLASS_B | PIN_PULLUP | MUX_MODE0)	/* i2c1_scl.i2c1_scl */
+			K2G_CORE_IOPAD(0x1388) (BUFFER_CLASS_B | PIN_PULLUP | MUX_MODE0)	/* i2c1_sda.i2c1_sda */
+		>;
+	};
+
 	ecap0_pins: ecap0_pins {
 		pinctrl-single,pins = <
 			K2G_CORE_IOPAD(0x1374) (BUFFER_CLASS_B | MUX_MODE4)	/* pr1_mdio_data.ecap0_in_apwm0_out */
@@ -160,6 +180,40 @@ K2G_CORE_IOPAD(0x118C) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0)	/* MDIO_CLK.M
 			K2G_CORE_IOPAD(0x1188) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0)	/* MDIO_DATA.MDIO_DATA */
 		>;
 	};
+
+	vout_pins: pinmux_vout_pins {
+		pinctrl-single,pins = <
+			K2G_CORE_IOPAD(0x1078) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0) /* dssdata23.dssdata23 */
+			K2G_CORE_IOPAD(0x107c) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0) /* dssdata22.dssdata22 */
+			K2G_CORE_IOPAD(0x1080) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0) /* dssdata21.dssdata21 */
+			K2G_CORE_IOPAD(0x1084) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0) /* dssdata20.dssdata20 */
+			K2G_CORE_IOPAD(0x1088) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0) /* dssdata19.dssdata19 */
+			K2G_CORE_IOPAD(0x108c) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0) /* dssdata18.dssdata18 */
+			K2G_CORE_IOPAD(0x1090) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0) /* dssdata17.dssdata17 */
+			K2G_CORE_IOPAD(0x1094) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0) /* dssdata16.dssdata16 */
+			K2G_CORE_IOPAD(0x1098) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0) /* dssdata15.dssdata15 */
+			K2G_CORE_IOPAD(0x109c) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0) /* dssdata14.dssdata14 */
+			K2G_CORE_IOPAD(0x10a0) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0) /* dssdata13.dssdata13 */
+			K2G_CORE_IOPAD(0x10a4) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0) /* dssdata12.dssdata12 */
+			K2G_CORE_IOPAD(0x10a8) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0) /* dssdata11.dssdata11 */
+			K2G_CORE_IOPAD(0x10ac) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0) /* dssdata10.dssdata10 */
+			K2G_CORE_IOPAD(0x10b0) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0) /* dssdata9.dssdata9 */
+			K2G_CORE_IOPAD(0x10b4) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0) /* dssdata8.dssdata8 */
+			K2G_CORE_IOPAD(0x10b8) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0) /* dssdata7.dssdata7 */
+			K2G_CORE_IOPAD(0x10bc) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0) /* dssdata6.dssdata6 */
+			K2G_CORE_IOPAD(0x10c0) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0) /* dssdata5.dssdata5 */
+			K2G_CORE_IOPAD(0x10c4) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0) /* dssdata4.dssdata4 */
+			K2G_CORE_IOPAD(0x10c8) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0) /* dssdata3.dssdata3 */
+			K2G_CORE_IOPAD(0x10cc) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0) /* dssdata2.dssdata2 */
+			K2G_CORE_IOPAD(0x10d0) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0) /* dssdata1.dssdata1 */
+			K2G_CORE_IOPAD(0x10d4) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0) /* dssdata0.dssdata0 */
+			K2G_CORE_IOPAD(0x10d8) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0) /* dssvsync.dssvsync */
+			K2G_CORE_IOPAD(0x10dc) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0) /* dsshsync.dsshsync */
+			K2G_CORE_IOPAD(0x10e0) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0) /* dsspclk.dsspclk */
+			K2G_CORE_IOPAD(0x10e4) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0) /* dssde.dssde */
+			K2G_CORE_IOPAD(0x10e8) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0) /* dssfid.dssfid */
+		>;
+	};
 };
 
 &uart0 {
@@ -357,3 +411,50 @@ &netcp {
 	pinctrl-0 = <&emac_pins>;
 	status = "okay";
 };
+
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1_pins>;
+	status = "okay";
+	clock-frequency = <400000>;
+
+	sii9022: sii9022@3b {
+		#sound-dai-cells = <0>;
+		compatible = "sil,sii9022";
+		reg = <0x3b>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+
+				sii9022_in: endpoint {
+					remote-endpoint = <&dpi_out>;
+				};
+			};
+
+			port@1 {
+				reg = <1>;
+
+				sii9022_out: endpoint {
+					remote-endpoint = <&hdmi_connector_in>;
+				};
+			};
+		};
+	};
+};
+
+&dss {
+	pinctrl-names = "default";
+	pinctrl-0 = <&vout_pins>;
+	status = "ok";
+
+	port {
+		dpi_out: endpoint {
+			remote-endpoint = <&sii9022_in>;
+			data-lines = <24>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/keystone-k2g.dtsi b/arch/arm/boot/dts/keystone-k2g.dtsi
index 1c833105d6c5..08ba31780baa 100644
--- a/arch/arm/boot/dts/keystone-k2g.dtsi
+++ b/arch/arm/boot/dts/keystone-k2g.dtsi
@@ -324,6 +324,28 @@ gpio1: gpio@260a000 {
 			clock-names = "gpio";
 		};
 
+		dss: dss@02540000 {
+			compatible = "ti,k2g-dss";
+			reg =	<0x02540000 0x400>,
+				<0x02550000 0x1000>,
+				<0x02557000 0x1000>,
+				<0x0255a800 0x100>,
+				<0x0255ac00 0x100>;
+			reg-names = "cfg", "common", "vid1", "ovr1", "vp1";
+			clocks =	<&k2g_clks 0x2 0>,
+					<&k2g_clks 0x2 1>;
+			clock-names = "fck", "vp1";
+			interrupts = <GIC_SPI 247 IRQ_TYPE_EDGE_RISING>;
+
+			power-domains = <&k2g_pds 0x2>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+
+			max-memory-bandwidth = <230000000>;
+		};
+
 		edma0: edma@2700000 {
 			compatible = "ti,k2g-edma3-tpcc", "ti,edma3-tpcc";
 			reg =	<0x02700000 0x8000>;
diff --git a/arch/arm/boot/dts/mt7623n-rfb-emmc.dts b/arch/arm/boot/dts/mt7623n-rfb-emmc.dts
index b7606130ade9..0447748f9fa0 100644
--- a/arch/arm/boot/dts/mt7623n-rfb-emmc.dts
+++ b/arch/arm/boot/dts/mt7623n-rfb-emmc.dts
@@ -138,6 +138,7 @@ fixed-link {
 	mac@1 {
 		compatible = "mediatek,eth-mac";
 		reg = <1>;
+		phy-mode = "rgmii";
 		phy-handle = <&phy5>;
 	};
 
diff --git a/arch/arm/boot/dts/omap3-n950-n9.dtsi b/arch/arm/boot/dts/omap3-n950-n9.dtsi
index a075b63f3087..11d41e86f814 100644
--- a/arch/arm/boot/dts/omap3-n950-n9.dtsi
+++ b/arch/arm/boot/dts/omap3-n950-n9.dtsi
@@ -341,6 +341,11 @@ &mmc3 {
 	status = "disabled";
 };
 
+/* RNG not directly accessible on N950/N9. */
+&rng_target {
+	status = "disabled";
+};
+
 &usb_otg_hs {
 	interface-type = <0>;
 	usb-phy = <&usb2_phy>;
diff --git a/arch/arm/boot/dts/qcom-ipq4019.dtsi b/arch/arm/boot/dts/qcom-ipq4019.dtsi
index bfa9ce4c6e69..c6956015dedc 100644
--- a/arch/arm/boot/dts/qcom-ipq4019.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi
@@ -166,6 +166,7 @@ timer {
 			     <1 4 0xf08>,
 			     <1 1 0xf08>;
 		clock-frequency = <48000000>;
+		always-on;
 	};
 
 	soc {
diff --git a/arch/arm/boot/dts/qcom-ipq8064.dtsi b/arch/arm/boot/dts/qcom-ipq8064.dtsi
index 4021f661cd11..b912da9a3ff3 100644
--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
@@ -93,6 +93,12 @@ sleep_clk: sleep_clk {
 		};
 	};
 
+	firmware {
+		scm {
+			compatible = "qcom,scm-ipq806x", "qcom,scm";
+		};
+	};
+
 	soc: soc {
 		#address-cells = <1>;
 		#size-cells = <1>;
diff --git a/arch/arm/boot/dts/rtd1195-horseradish.dts b/arch/arm/boot/dts/rtd1195-horseradish.dts
new file mode 100644
index 000000000000..9d06d3d34c74
--- /dev/null
+++ b/arch/arm/boot/dts/rtd1195-horseradish.dts
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
+/*
+ * Copyright (c) 2019 Andreas Färber
+ */
+
+/dts-v1/;
+
+#include "rtd1195.dtsi"
+
+/ {
+	compatible = "realtek,horseradish", "realtek,rtd1195";
+	model = "Realtek Horseradish EVB";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory@a800 {
+		device_type = "memory";
+		reg = <0x0000a800 0x17ff5800>, /* boot ROM to r-bus */
+		      <0x18070000 0x00090000>, /* r-bus to NOR flash */
+		      <0x19100000 0x26f00000>; /* NOR flash to 1 GiB */
+	};
+};
+
+&uart0 {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/rtd1195-mele-x1000.dts b/arch/arm/boot/dts/rtd1195-mele-x1000.dts
new file mode 100644
index 000000000000..c7951b9a2c97
--- /dev/null
+++ b/arch/arm/boot/dts/rtd1195-mele-x1000.dts
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
+/*
+ * Copyright (c) 2017-2019 Andreas Färber
+ */
+
+/dts-v1/;
+
+#include "rtd1195.dtsi"
+
+/ {
+	compatible = "mele,x1000", "realtek,rtd1195";
+	model = "MeLE X1000";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory@a800 {
+		device_type = "memory";
+		reg = <0x0000a800 0x17ff5800>, /* boot ROM to r-bus */
+		      <0x18070000 0x00090000>, /* r-bus to NOR flash */
+		      <0x19100000 0x26f00000>; /* NOR flash to 1 GiB */
+	};
+};
+
+&uart0 {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/rtd1195.dtsi b/arch/arm/boot/dts/rtd1195.dtsi
new file mode 100644
index 000000000000..21897210d9d0
--- /dev/null
+++ b/arch/arm/boot/dts/rtd1195.dtsi
@@ -0,0 +1,217 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
+/*
+ * Copyright (c) 2017-2019 Andreas Färber
+ */
+
+/memreserve/ 0x00000000 0x0000a800; /* boot code */
+/memreserve/ 0x0000a800 0x000f5800;
+/memreserve/ 0x17fff000 0x00001000;
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/reset/realtek,rtd1195.h>
+
+/ {
+	compatible = "realtek,rtd1195";
+	interrupt-parent = <&gic>;
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x0>;
+			clock-frequency = <1000000000>;
+		};
+
+		cpu1: cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x1>;
+			clock-frequency = <1000000000>;
+		};
+	};
+
+	reserved-memory {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		rpc_comm: rpc@b000 {
+			reg = <0x0000b000 0x1000>;
+		};
+
+		audio@1b00000 {
+			reg = <0x01b00000 0x400000>;
+		};
+
+		rpc_ringbuf: rpc@1ffe000 {
+			reg = <0x01ffe000 0x4000>;
+		};
+
+		secure@10000000 {
+			reg = <0x10000000 0x100000>;
+			no-map;
+		};
+	};
+
+	arm-pmu {
+		compatible = "arm,cortex-a7-pmu";
+		interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&cpu0>, <&cpu1>;
+	};
+
+	timer {
+		compatible = "arm,armv7-timer";
+		interrupts = <GIC_PPI 13
+			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 14
+			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 11
+			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 10
+			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+		clock-frequency = <27000000>;
+	};
+
+	osc27M: osc {
+		compatible = "fixed-clock";
+		clock-frequency = <27000000>;
+		#clock-cells = <0>;
+		clock-output-names = "osc27M";
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0x00000000 0x00000000 0x0000a800>,
+			 <0x18000000 0x18000000 0x00070000>,
+			 <0x18100000 0x18100000 0x01000000>,
+			 <0x80000000 0x80000000 0x80000000>;
+
+		rbus: bus@18000000 {
+			compatible = "simple-bus";
+			reg = <0x18000000 0x70000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x0 0x18000000 0x70000>;
+
+			crt: syscon@0 {
+				compatible = "syscon", "simple-mfd";
+				reg = <0x0 0x1000>;
+				reg-io-width = <4>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0x0 0x0 0x1000>;
+			};
+
+			iso: syscon@7000 {
+				compatible = "syscon", "simple-mfd";
+				reg = <0x7000 0x1000>;
+				reg-io-width = <4>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0x0 0x7000 0x1000>;
+			};
+
+			sb2: syscon@1a000 {
+				compatible = "syscon", "simple-mfd";
+				reg = <0x1a000 0x1000>;
+				reg-io-width = <4>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0x0 0x1a000 0x1000>;
+			};
+
+			misc: syscon@1b000 {
+				compatible = "syscon", "simple-mfd";
+				reg = <0x1b000 0x1000>;
+				reg-io-width = <4>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0x0 0x1b000 0x1000>;
+			};
+
+			scpu_wrapper: syscon@1d000 {
+				compatible = "syscon", "simple-mfd";
+				reg = <0x1d000 0x1000>;
+				reg-io-width = <4>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0x0 0x1d000 0x1000>;
+			};
+		};
+
+		gic: interrupt-controller@ff011000 {
+			compatible = "arm,cortex-a7-gic";
+			reg = <0xff011000 0x1000>,
+			      <0xff012000 0x2000>,
+			      <0xff014000 0x2000>,
+			      <0xff016000 0x2000>;
+			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+		};
+	};
+};
+
+&crt {
+	reset1: reset-controller@0 {
+		compatible = "snps,dw-low-reset";
+		reg = <0x0 0x4>;
+		#reset-cells = <1>;
+	};
+
+	reset2: reset-controller@4 {
+		compatible = "snps,dw-low-reset";
+		reg = <0x4 0x4>;
+		#reset-cells = <1>;
+	};
+
+	reset3: reset-controller@8 {
+		compatible = "snps,dw-low-reset";
+		reg = <0x8 0x4>;
+		#reset-cells = <1>;
+	};
+};
+
+&iso {
+	iso_reset: reset-controller@88 {
+		compatible = "snps,dw-low-reset";
+		reg = <0x88 0x4>;
+		#reset-cells = <1>;
+	};
+
+	wdt: watchdog@680 {
+		compatible = "realtek,rtd1295-watchdog";
+		reg = <0x680 0x100>;
+		clocks = <&osc27M>;
+	};
+
+	uart0: serial@800 {
+		compatible = "snps,dw-apb-uart";
+		reg = <0x800 0x400>;
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		resets = <&iso_reset RTD1195_ISO_RSTN_UR0>;
+		clock-frequency = <27000000>;
+		status = "disabled";
+	};
+};
+
+&misc {
+	uart1: serial@200 {
+		compatible = "snps,dw-apb-uart";
+		reg = <0x200 0x100>;
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		resets = <&reset2 RTD1195_RSTN_UR1>;
+		clock-frequency = <27000000>;
+		status = "disabled";
+	};
+};
diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-lime-emmc.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-lime-emmc.dts
new file mode 100644
index 000000000000..033cab3443f8
--- /dev/null
+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-lime-emmc.dts
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2020 Olimex Ltd.
+ *   Author: Stefan Mavrodiev <stefan@olimex.com>
+ */
+
+#include "sun7i-a20-olinuxino-lime.dts"
+
+/ {
+	model = "Olimex A20-OLinuXino-LIME-eMMC";
+	compatible = "olimex,a20-olinuxino-lime-emmc", "allwinner,sun7i-a20";
+
+	mmc2_pwrseq: pwrseq {
+		compatible = "mmc-pwrseq-emmc";
+		reset-gpios = <&pio 2 16 GPIO_ACTIVE_LOW>;
+	};
+};
+
+&mmc2 {
+	vmmc-supply = <&reg_vcc3v3>;
+	vqmmc-supply = <&reg_vcc3v3>;
+	bus-width = <4>;
+	non-removable;
+	mmc-pwrseq = <&mmc2_pwrseq>;
+	status = "okay";
+
+	emmc: emmc@0 {
+		reg = <0>;
+		compatible = "mmc-card";
+		broken-hpi;
+	};
+};
diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi
index 655404d6d3a3..c010b27fdb6a 100644
--- a/arch/arm/boot/dts/sun8i-a83t.dtsi
+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
@@ -610,6 +610,16 @@ crypto: crypto@1c15000 {
 			clock-names = "bus", "mod";
 		};
 
+		msgbox: mailbox@1c17000 {
+			compatible = "allwinner,sun8i-a83t-msgbox",
+				     "allwinner,sun6i-a31-msgbox";
+			reg = <0x01c17000 0x1000>;
+			clocks = <&ccu CLK_BUS_MSGBOX>;
+			resets = <&ccu RST_BUS_MSGBOX>;
+			interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+			#mbox-cells = <1>;
+		};
+
 		usb_otg: usb@1c19000 {
 			compatible = "allwinner,sun8i-a83t-musb",
 				     "allwinner,sun8i-a33-musb";
diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi
index e83aa6866e7e..4e89701df91f 100644
--- a/arch/arm/boot/dts/sun8i-h3.dtsi
+++ b/arch/arm/boot/dts/sun8i-h3.dtsi
@@ -112,6 +112,26 @@ cpu3: cpu@3 {
 		};
 	};
 
+	gpu_opp_table: gpu-opp-table {
+		compatible = "operating-points-v2";
+
+		opp-120000000 {
+			opp-hz = /bits/ 64 <120000000>;
+		};
+
+		opp-312000000 {
+			opp-hz = /bits/ 64 <312000000>;
+		};
+
+		opp-432000000 {
+			opp-hz = /bits/ 64 <432000000>;
+		};
+
+		opp-576000000 {
+			opp-hz = /bits/ 64 <576000000>;
+		};
+	};
+
 	pmu {
 		compatible = "arm,cortex-a7-pmu";
 		interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
@@ -205,9 +225,7 @@ mali: gpu@1c40000 {
 			clocks = <&ccu CLK_BUS_GPU>, <&ccu CLK_GPU>;
 			clock-names = "bus", "core";
 			resets = <&ccu RST_BUS_GPU>;
-
-			assigned-clocks = <&ccu CLK_GPU>;
-			assigned-clock-rates = <384000000>;
+			operating-points-v2 = <&gpu_opp_table>;
 		};
 
 		ths: thermal-sensor@1c25000 {
diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
index 01a5df9aa71b..22d533d18992 100644
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
@@ -239,6 +239,16 @@ ths_calibration: thermal-sensor-calibration@34 {
 			};
 		};
 
+		msgbox: mailbox@1c17000 {
+			compatible = "allwinner,sun8i-h3-msgbox",
+				     "allwinner,sun6i-a31-msgbox";
+			reg = <0x01c17000 0x1000>;
+			clocks = <&ccu CLK_BUS_MSGBOX>;
+			resets = <&ccu RST_BUS_MSGBOX>;
+			interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+			#mbox-cells = <1>;
+		};
+
 		usb_otg: usb@1c19000 {
 			compatible = "allwinner,sun8i-h3-musb";
 			reg = <0x01c19000 0x400>;
diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig
index 8e7a3ed2a4df..44ff9cd88d81 100644
--- a/arch/arm/configs/bcm2835_defconfig
+++ b/arch/arm/configs/bcm2835_defconfig
@@ -103,6 +103,7 @@ CONFIG_WATCHDOG=y
 CONFIG_BCM2835_WDT=y
 CONFIG_MFD_SYSCON=y
 CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_GPIO=y
 CONFIG_MEDIA_SUPPORT=y
 CONFIG_MEDIA_CAMERA_SUPPORT=y
diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig
index 3c3a00fc71f6..374fbff8eaa6 100644
--- a/arch/arm/configs/exynos_defconfig
+++ b/arch/arm/configs/exynos_defconfig
@@ -69,6 +69,7 @@ CONFIG_BT_HCIUART=m
 CONFIG_BT_HCIUART_BCSP=y
 CONFIG_BT_HCIUART_ATH3K=y
 CONFIG_BT_HCIUART_INTEL=y
+CONFIG_BT_HCIUART_BCM=y
 CONFIG_BT_HCIUART_AG6XX=y
 CONFIG_BT_HCIUART_MRVL=y
 CONFIG_BT_HCIBCM203X=m
@@ -78,8 +79,8 @@ CONFIG_BT_HCIVHCI=m
 CONFIG_BT_MRVL=m
 CONFIG_BT_MRVL_SDIO=m
 CONFIG_BT_ATH3K=m
-CONFIG_CFG80211=y
-CONFIG_MAC80211=y
+CONFIG_CFG80211=m
+CONFIG_MAC80211=m
 CONFIG_MAC80211_LEDS=y
 CONFIG_NFC=y
 CONFIG_NFC_DIGITAL=m
@@ -94,7 +95,7 @@ CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=y
 CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=32768
+CONFIG_BLK_DEV_RAM_SIZE=65536
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_SG=y
@@ -133,6 +134,7 @@ CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_OF_PLATFORM=y
 CONFIG_SERIAL_SAMSUNG=y
 CONFIG_SERIAL_SAMSUNG_CONSOLE=y
+CONFIG_SERIAL_DEV_BUS=y
 CONFIG_HW_RANDOM=y
 CONFIG_TCG_TPM=y
 CONFIG_TCG_TIS_I2C_INFINEON=y
@@ -207,7 +209,7 @@ CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC=m
 CONFIG_V4L_TEST_DRIVERS=y
 CONFIG_VIDEO_VIVID=m
 CONFIG_CEC_PLATFORM_DRIVERS=y
-CONFIG_VIDEO_SAMSUNG_S5P_CEC=m
+CONFIG_CEC_SAMSUNG_S5P=m
 # CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
 CONFIG_VIDEO_S5K6A3=m
 CONFIG_VIDEO_S5C73M3=m
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index f8e45351c3f9..9c86b1ab2f1d 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -638,7 +638,7 @@ CONFIG_VIDEO_RENESAS_VSP1=m
 CONFIG_V4L_TEST_DRIVERS=y
 CONFIG_VIDEO_VIVID=m
 CONFIG_CEC_PLATFORM_DRIVERS=y
-CONFIG_VIDEO_SAMSUNG_S5P_CEC=m
+CONFIG_CEC_SAMSUNG_S5P=m
 CONFIG_VIDEO_ADV7180=m
 CONFIG_VIDEO_ML86V7667=m
 CONFIG_IMX_IPUV3_CORE=m
diff --git a/arch/arm/configs/sunxi_defconfig b/arch/arm/configs/sunxi_defconfig
index 61b8be19e527..b105ce7120cc 100644
--- a/arch/arm/configs/sunxi_defconfig
+++ b/arch/arm/configs/sunxi_defconfig
@@ -107,6 +107,7 @@ CONFIG_SOUND=y
 CONFIG_SND=y
 CONFIG_SND_SOC=y
 CONFIG_SND_SUN4I_CODEC=y
+CONFIG_SND_SUN8I_CODEC_ANALOG=y
 CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_HCD_PLATFORM=y
diff --git a/arch/arm/mach-realtek/Kconfig b/arch/arm/mach-realtek/Kconfig
new file mode 100644
index 000000000000..19fdcf093fd1
--- /dev/null
+++ b/arch/arm/mach-realtek/Kconfig
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+menuconfig ARCH_REALTEK
+	bool "Realtek SoCs"
+	depends on ARCH_MULTI_V7
+	select ARM_GIC
+	select ARM_GLOBAL_TIMER
+	select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
+	select GENERIC_IRQ_CHIP
+	select RESET_CONTROLLER
+	help
+	  This enables support for the Realtek RTD1195 SoC family.
diff --git a/arch/arm/mach-realtek/Makefile b/arch/arm/mach-realtek/Makefile
new file mode 100644
index 000000000000..5382d5bbdd3c
--- /dev/null
+++ b/arch/arm/mach-realtek/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+obj-y += rtd1195.o
diff --git a/arch/arm/mach-realtek/rtd1195.c b/arch/arm/mach-realtek/rtd1195.c
new file mode 100644
index 000000000000..0381a4447384
--- /dev/null
+++ b/arch/arm/mach-realtek/rtd1195.c
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Realtek RTD1195
+ *
+ * Copyright (c) 2017-2019 Andreas Färber
+ */
+
+#include <linux/memblock.h>
+#include <asm/mach/arch.h>
+
+static void __init rtd1195_memblock_remove(phys_addr_t base, phys_addr_t size)
+{
+	int ret;
+
+	ret = memblock_remove(base, size);
+	if (ret)
+		pr_err("Failed to remove memblock %pa (%d)\n", &base, ret);
+}
+
+static void __init rtd1195_reserve(void)
+{
+	/* Exclude boot ROM from RAM */
+	rtd1195_memblock_remove(0x00000000, 0x0000a800);
+
+	/* Exclude peripheral register spaces from RAM */
+	rtd1195_memblock_remove(0x18000000, 0x00070000);
+	rtd1195_memblock_remove(0x18100000, 0x01000000);
+}
+
+static const char *const rtd1195_dt_compat[] __initconst = {
+	"realtek,rtd1195",
+	NULL
+};
+
+DT_MACHINE_START(rtd1195, "Realtek RTD1195")
+	.dt_compat = rtd1195_dt_compat,
+	.reserve = rtd1195_reserve,
+	.l2c_aux_val = 0x0,
+	.l2c_aux_mask = ~0x0,
+MACHINE_END
diff --git a/arch/arm/mach-rockchip/platsmp.c b/arch/arm/mach-rockchip/platsmp.c
index 649e0a54784c..d60856898d97 100644
--- a/arch/arm/mach-rockchip/platsmp.c
+++ b/arch/arm/mach-rockchip/platsmp.c
@@ -180,7 +180,7 @@ static int __init rockchip_smp_prepare_sram(struct device_node *node)
 
 	rsize = resource_size(&res);
 	if (rsize < trampoline_sz) {
-		pr_err("%s: reserved block with size 0x%x is to small for trampoline size 0x%x\n",
+		pr_err("%s: reserved block with size 0x%x is too small for trampoline size 0x%x\n",
 		       __func__, rsize, trampoline_sz);
 		return -EINVAL;
 	}
diff --git a/arch/arm/mach-rockchip/rockchip.c b/arch/arm/mach-rockchip/rockchip.c
index f9797a2b5d0d..beea4564eed4 100644
--- a/arch/arm/mach-rockchip/rockchip.c
+++ b/arch/arm/mach-rockchip/rockchip.c
@@ -9,9 +9,9 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/of_clk.h>
 #include <linux/of_platform.h>
 #include <linux/irqchip.h>
-#include <linux/clk-provider.h>
 #include <linux/clocksource.h>
 #include <linux/mfd/syscon.h>
 #include <linux/regmap.h>
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410-module.c b/arch/arm/mach-s3c64xx/mach-crag6410-module.c
index 937d0a83f8fd..34f1baa10c54 100644
--- a/arch/arm/mach-s3c64xx/mach-crag6410-module.c
+++ b/arch/arm/mach-s3c64xx/mach-crag6410-module.c
@@ -405,10 +405,9 @@ static int wlf_gf_module_probe(struct i2c_client *i2c,
 			 gf_mods[i].name, rev + 1);
 
 		for (j = 0; j < gf_mods[i].num_i2c_devs; j++) {
-			if (!i2c_new_device(i2c->adapter,
-					    &(gf_mods[i].i2c_devs[j])))
-				dev_err(&i2c->dev,
-					"Failed to register dev: %d\n", ret);
+			if (IS_ERR(i2c_new_client_device(i2c->adapter,
+							 &(gf_mods[i].i2c_devs[j]))))
+				dev_err(&i2c->dev, "Failed to register\n");
 		}
 
 		spi_register_board_info(gf_mods[i].spi_devs,
diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c
index cc29869d12a3..bf85d6db4931 100644
--- a/arch/arm/net/bpf_jit_32.c
+++ b/arch/arm/net/bpf_jit_32.c
@@ -929,7 +929,11 @@ static inline void emit_a32_rsh_i64(const s8 dst[],
 	rd = arm_bpf_get_reg64(dst, tmp, ctx);
 
 	/* Do LSR operation */
-	if (val < 32) {
+	if (val == 0) {
+		/* An immediate value of 0 encodes a shift amount of 32
+		 * for LSR. To shift by 0, don't do anything.
+		 */
+	} else if (val < 32) {
 		emit(ARM_MOV_SI(tmp2[1], rd[1], SRTYPE_LSR, val), ctx);
 		emit(ARM_ORR_SI(rd[1], tmp2[1], rd[0], SRTYPE_ASL, 32 - val), ctx);
 		emit(ARM_MOV_SI(rd[0], rd[0], SRTYPE_LSR, val), ctx);
@@ -955,7 +959,11 @@ static inline void emit_a32_arsh_i64(const s8 dst[],
 	rd = arm_bpf_get_reg64(dst, tmp, ctx);
 
 	/* Do ARSH operation */
-	if (val < 32) {
+	if (val == 0) {
+		/* An immediate value of 0 encodes a shift amount of 32
+		 * for ASR. To shift by 0, don't do anything.
+		 */
+	} else if (val < 32) {
 		emit(ARM_MOV_SI(tmp2[1], rd[1], SRTYPE_LSR, val), ctx);
 		emit(ARM_ORR_SI(rd[1], tmp2[1], rd[0], SRTYPE_ASL, 32 - val), ctx);
 		emit(ARM_MOV_SI(rd[0], rd[0], SRTYPE_ASR, val), ctx);
@@ -992,21 +1000,35 @@ static inline void emit_a32_mul_r64(const s8 dst[], const s8 src[],
 	arm_bpf_put_reg32(dst_hi, rd[0], ctx);
 }
 
+static bool is_ldst_imm(s16 off, const u8 size)
+{
+	s16 off_max = 0;
+
+	switch (size) {
+	case BPF_B:
+	case BPF_W:
+		off_max = 0xfff;
+		break;
+	case BPF_H:
+		off_max = 0xff;
+		break;
+	case BPF_DW:
+		/* Need to make sure off+4 does not overflow. */
+		off_max = 0xfff - 4;
+		break;
+	}
+	return -off_max <= off && off <= off_max;
+}
+
 /* *(size *)(dst + off) = src */
 static inline void emit_str_r(const s8 dst, const s8 src[],
-			      s32 off, struct jit_ctx *ctx, const u8 sz){
+			      s16 off, struct jit_ctx *ctx, const u8 sz){
 	const s8 *tmp = bpf2a32[TMP_REG_1];
-	s32 off_max;
 	s8 rd;
 
 	rd = arm_bpf_get_reg32(dst, tmp[1], ctx);
 
-	if (sz == BPF_H)
-		off_max = 0xff;
-	else
-		off_max = 0xfff;
-
-	if (off < 0 || off > off_max) {
+	if (!is_ldst_imm(off, sz)) {
 		emit_a32_mov_i(tmp[0], off, ctx);
 		emit(ARM_ADD_R(tmp[0], tmp[0], rd), ctx);
 		rd = tmp[0];
@@ -1035,18 +1057,12 @@ static inline void emit_str_r(const s8 dst, const s8 src[],
 
 /* dst = *(size*)(src + off) */
 static inline void emit_ldx_r(const s8 dst[], const s8 src,
-			      s32 off, struct jit_ctx *ctx, const u8 sz){
+			      s16 off, struct jit_ctx *ctx, const u8 sz){
 	const s8 *tmp = bpf2a32[TMP_REG_1];
 	const s8 *rd = is_stacked(dst_lo) ? tmp : dst;
 	s8 rm = src;
-	s32 off_max;
-
-	if (sz == BPF_H)
-		off_max = 0xff;
-	else
-		off_max = 0xfff;
 
-	if (off < 0 || off > off_max) {
+	if (!is_ldst_imm(off, sz)) {
 		emit_a32_mov_i(tmp[0], off, ctx);
 		emit(ARM_ADD_R(tmp[0], tmp[0], src), ctx);
 		rm = tmp[0];
diff --git a/arch/arm/tools/syscall.tbl b/arch/arm/tools/syscall.tbl
index 4d1cf74a2caa..54c2719fec46 100644
--- a/arch/arm/tools/syscall.tbl
+++ b/arch/arm/tools/syscall.tbl
@@ -451,3 +451,4 @@
 435	common	clone3				sys_clone3
 437	common	openat2				sys_openat2
 438	common	pidfd_getfd			sys_pidfd_getfd
+439	common	process_madvise			sys_process_madvise
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 40fb05d96c60..0efb46abaf3d 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -10,6 +10,7 @@ config ARM64
 	select ACPI_SPCR_TABLE if ACPI
 	select ACPI_PPTT if ACPI
 	select ARCH_HAS_DEBUG_VIRTUAL
+	select ARCH_HAS_DEBUG_VM_PGTABLE
 	select ARCH_HAS_DEVMEM_IS_ALLOWED
 	select ARCH_HAS_DMA_PREP_COHERENT
 	select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
index 5fa9ca0191a8..f3f8e177ab61 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
@@ -32,6 +32,15 @@ hdmi_con_in: endpoint {
 		};
 	};
 
+	leds {
+		compatible = "gpio-leds";
+
+		led-0 {
+			label = "a64-olinuxino:red:user";
+			gpios = <&pio 4 17 GPIO_ACTIVE_HIGH>; /* PE17 */
+		};
+	};
+
 	reg_usb1_vbus: usb1-vbus {
 		compatible = "regulator-fixed";
 		regulator-name = "usb1-vbus";
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index 31143fe64d91..8d10fe6d06b6 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -557,6 +557,16 @@ crypto: crypto@1c15000 {
 			resets = <&ccu RST_BUS_CE>;
 		};
 
+		msgbox: mailbox@1c17000 {
+			compatible = "allwinner,sun50i-a64-msgbox",
+				     "allwinner,sun6i-a31-msgbox";
+			reg = <0x01c17000 0x1000>;
+			clocks = <&ccu CLK_BUS_MSGBOX>;
+			resets = <&ccu RST_BUS_MSGBOX>;
+			interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+			#mbox-cells = <1>;
+		};
+
 		usb_otg: usb@1c19000 {
 			compatible = "allwinner,sun8i-a33-musb";
 			reg = <0x01c19000 0x0400>;
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
index b9ab7d8fa8af..a5ee68388bd3 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -231,6 +231,16 @@ dma: dma-controller@3002000 {
 			#dma-cells = <1>;
 		};
 
+		msgbox: mailbox@3003000 {
+			compatible = "allwinner,sun50i-h6-msgbox",
+				     "allwinner,sun6i-a31-msgbox";
+			reg = <0x03003000 0x1000>;
+			clocks = <&ccu CLK_BUS_MSGBOX>;
+			resets = <&ccu RST_BUS_MSGBOX>;
+			interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+			#mbox-cells = <1>;
+		};
+
 		sid: efuse@3006000 {
 			compatible = "allwinner,sun50i-h6-sid";
 			reg = <0x03006000 0x400>;
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
index 2a7f70b71149..13d0570c7ed6 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
@@ -447,7 +447,7 @@ lpuart5: serial@22b0000 {
 
 		edma0: dma-controller@22c0000 {
 			#dma-cells = <2>;
-			compatible = "fsl,ls1028a-edma";
+			compatible = "fsl,ls1028a-edma", "fsl,vf610-edma";
 			reg = <0x0 0x22c0000 0x0 0x10000>,
 			      <0x0 0x22d0000 0x0 0x10000>,
 			      <0x0 0x22e0000 0x0 0x10000>;
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-evk.dts b/arch/arm64/boot/dts/freescale/imx8mm-evk.dts
index 951e14a3de0e..e5ec8322796d 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-evk.dts
@@ -82,6 +82,18 @@ &A53_0 {
 	cpu-supply = <&buck2_reg>;
 };
 
+&A53_1 {
+	cpu-supply = <&buck2_reg>;
+};
+
+&A53_2 {
+	cpu-supply = <&buck2_reg>;
+};
+
+&A53_3 {
+	cpu-supply = <&buck2_reg>;
+};
+
 &ddrc {
 	operating-points-v2 = <&ddrc_opp_table>;
 
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-ddr4-evk.dts b/arch/arm64/boot/dts/freescale/imx8mn-ddr4-evk.dts
index 2497eebb5739..d07e0e6a00cc 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn-ddr4-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mn-ddr4-evk.dts
@@ -17,6 +17,18 @@ &A53_0 {
 	cpu-supply = <&buck2_reg>;
 };
 
+&A53_1 {
+	cpu-supply = <&buck2_reg>;
+};
+
+&A53_2 {
+	cpu-supply = <&buck2_reg>;
+};
+
+&A53_3 {
+	cpu-supply = <&buck2_reg>;
+};
+
 &ddrc {
 	operating-points-v2 = <&ddrc_opp_table>;
 
diff --git a/arch/arm64/boot/dts/intel/socfpga_agilex.dtsi b/arch/arm64/boot/dts/intel/socfpga_agilex.dtsi
index d8c44d3ca15a..f52de8f7806a 100644
--- a/arch/arm64/boot/dts/intel/socfpga_agilex.dtsi
+++ b/arch/arm64/boot/dts/intel/socfpga_agilex.dtsi
@@ -539,12 +539,12 @@ qspi: spi@ff8d2000 {
 
 		firmware {
 			svc {
-				compatible = "intel,stratix10-svc";
+				compatible = "intel,agilex-svc";
 				method = "smc";
 				memory-region = <&service_reserved>;
 
 				fpga_mgr: fpga-mgr {
-					compatible = "intel,stratix10-soc-fpga-mgr";
+					compatible = "intel,agilex-soc-fpga-mgr";
 				};
 			};
 		};
diff --git a/arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts b/arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts
index b90d78a5724b..c8243da71041 100644
--- a/arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts
+++ b/arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts
@@ -276,7 +276,7 @@ &cp0_ethernet {
 /* SFP */
 &cp0_eth0 {
 	status = "okay";
-	phy-mode = "10gbase-kr";
+	phy-mode = "10gbase-r";
 	managed = "in-band-status";
 	phys = <&cp0_comphy2 0>;
 	sfp = <&sfp_cp0_eth0>;
diff --git a/arch/arm64/boot/dts/marvell/armada-8040-mcbin-singleshot.dts b/arch/arm64/boot/dts/marvell/armada-8040-mcbin-singleshot.dts
index c3e18fd5bc27..2e6832d02a59 100644
--- a/arch/arm64/boot/dts/marvell/armada-8040-mcbin-singleshot.dts
+++ b/arch/arm64/boot/dts/marvell/armada-8040-mcbin-singleshot.dts
@@ -16,14 +16,14 @@ / {
 
 &cp0_eth0 {
 	status = "okay";
-	phy-mode = "10gbase-kr";
+	phy-mode = "10gbase-r";
 	managed = "in-band-status";
 	sfp = <&sfp_eth0>;
 };
 
 &cp1_eth0 {
 	status = "okay";
-	phy-mode = "10gbase-kr";
+	phy-mode = "10gbase-r";
 	managed = "in-band-status";
 	sfp = <&sfp_eth1>;
 };
diff --git a/arch/arm64/boot/dts/marvell/armada-8040-mcbin.dts b/arch/arm64/boot/dts/marvell/armada-8040-mcbin.dts
index d06f5ab7ddab..1766cf58101b 100644
--- a/arch/arm64/boot/dts/marvell/armada-8040-mcbin.dts
+++ b/arch/arm64/boot/dts/marvell/armada-8040-mcbin.dts
@@ -34,12 +34,12 @@ &cp0_eth0 {
 	status = "okay";
 	/* Network PHY */
 	phy = <&phy0>;
-	phy-mode = "10gbase-kr";
+	phy-mode = "10gbase-r";
 };
 
 &cp1_eth0 {
 	status = "okay";
 	/* Network PHY */
 	phy = <&phy8>;
-	phy-mode = "10gbase-kr";
+	phy-mode = "10gbase-r";
 };
diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
index 2f8967cb8717..a57af9da9f5c 100644
--- a/arch/arm64/boot/dts/mediatek/Makefile
+++ b/arch/arm64/boot/dts/mediatek/Makefile
@@ -6,6 +6,9 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-evb.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-x20-dev.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-rfb1.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-bananapi-bpi-r64.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm-hana.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm-hana-rev7.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-evb.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-evb.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8516-pumpkin.dtb
diff --git a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
index 83e10591e0e5..d174ad214857 100644
--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
@@ -543,3 +543,7 @@ &watchdog {
 	pinctrl-0 = <&watchdog_pins>;
 	status = "okay";
 };
+
+&wmac {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
index 3f783348c66a..0b4de627f96e 100644
--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
@@ -506,3 +506,7 @@ &watchdog {
 	pinctrl-0 = <&watchdog_pins>;
 	status = "okay";
 };
+
+&wmac {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
index 339dc9f88f43..1a39e0ef776b 100644
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
@@ -699,6 +699,17 @@ mmc1: mmc@11240000 {
 		status = "disabled";
 	};
 
+	wmac: wmac@18000000 {
+		compatible = "mediatek,mt7622-wmac";
+		reg = <0 0x18000000 0 0x100000>;
+		interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_LOW>;
+
+		mediatek,infracfg = <&infracfg>;
+		status = "disabled";
+
+		power-domains = <&scpsys MT7622_POWER_DOMAIN_WB>;
+	};
+
 	ssusbsys: ssusbsys@1a000000 {
 		compatible = "mediatek,mt7622-ssusbsys",
 			     "syscon";
diff --git a/arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dts b/arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dts
new file mode 100644
index 000000000000..44f6149c1307
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dts
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2019 MediaTek Inc.
+ */
+
+/dts-v1/;
+#include "mt8173-elm-hana.dtsi"
+
+/ {
+	model = "Google Hanawl";
+	compatible = "google,hana-rev7", "mediatek,mt8173";
+};
+
+&cpu_thermal {
+	trips {
+		cpu_crit: cpu_crit0 {
+			temperature = <100000>;
+			type = "critical";
+		};
+	};
+};
+
+&gpio_keys {
+	/delete-node/tablet_mode;
+	/delete-node/volume_down;
+	/delete-node/volume_up;
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dts b/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dts
new file mode 100644
index 000000000000..c234296755e1
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2016 MediaTek Inc.
+ */
+
+/dts-v1/;
+#include "mt8173-elm-hana.dtsi"
+
+/ {
+	model = "Google Hana";
+	compatible = "google,hana-rev6", "google,hana-rev5",
+		     "google,hana-rev4", "google,hana-rev3",
+		     "google,hana", "mediatek,mt8173";
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi b/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi
new file mode 100644
index 000000000000..bdcd35cecad9
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi
@@ -0,0 +1,70 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2016 MediaTek Inc.
+ */
+
+#include "mt8173-elm.dtsi"
+
+&i2c0 {
+	clock-frequency = <200000>;
+};
+
+&i2c3 {
+	touchscreen2: touchscreen@34 {
+		compatible = "melfas,mip4_ts";
+		reg = <0x34>;
+		interrupt-parent = <&pio>;
+		interrupts = <88 IRQ_TYPE_LEVEL_LOW>;
+	};
+
+	/*
+	 * Lenovo 100e Chromebook 2nd Gen (MTK) and Lenovo 300e Chromebook 2nd
+	 * Gen (MTK) are using synaptics touchscreen (hid-over-i2c driver) as a
+	 * second source touchscreen.
+	 */
+	touchscreen3: touchscreen@20 {
+		compatible = "hid-over-i2c";
+		reg = <0x20>;
+		hid-descr-addr = <0x0020>;
+		interrupt-parent = <&pio>;
+		interrupts = <88 IRQ_TYPE_LEVEL_LOW>;
+	};
+};
+
+&i2c4 {
+	/*
+	 * Lenovo 100e Chromebook 2nd Gen (MTK) and Lenovo 300e Chromebook 2nd
+	 * Gen (MTK) are using synaptics trackpad (hid-over-i2c driver) as a
+	 * second source trackpad.
+	 */
+	trackpad2: trackpad@2c {
+		compatible = "hid-over-i2c";
+		interrupt-parent = <&pio>;
+		interrupts = <117 IRQ_TYPE_LEVEL_LOW>;
+		reg = <0x2c>;
+		hid-descr-addr = <0x0020>;
+		wakeup-source;
+	};
+};
+
+&mmc1 {
+	wp-gpios = <&pio 42 GPIO_ACTIVE_HIGH>;
+};
+
+&pio {
+	hdmi_mux_pins: hdmi_mux_pins {
+		pins2 {
+			pinmux = <MT8173_PIN_98_URTS1__FUNC_GPIO98>;
+			bias-pull-up;
+			output-high;
+		};
+	};
+
+	mmc1_pins_default: mmc1default {
+		pins_wp {
+			pinmux = <MT8173_PIN_42_DSI_TE__FUNC_GPIO42>;
+			input-enable;
+			bias-pull-up;
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8173-elm.dts b/arch/arm64/boot/dts/mediatek/mt8173-elm.dts
new file mode 100644
index 000000000000..e9e4ac0b74b2
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8173-elm.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2016 MediaTek Inc.
+ */
+
+/dts-v1/;
+#include "mt8173-elm.dtsi"
+
+/ {
+	model = "Google Elm";
+	compatible = "google,elm-rev8", "google,elm-rev7", "google,elm-rev6",
+		     "google,elm-rev5", "google,elm-rev4", "google,elm-rev3",
+		     "google,elm", "mediatek,mt8173";
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi
new file mode 100644
index 000000000000..a5a12b2599a4
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi
@@ -0,0 +1,1173 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2016 MediaTek Inc.
+ */
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/gpio/gpio.h>
+#include "mt8173.dtsi"
+
+/ {
+	memory@40000000 {
+		device_type = "memory";
+		reg = <0 0x40000000 0 0x80000000>;
+	};
+
+	backlight: backlight {
+		compatible = "pwm-backlight";
+		pwms = <&pwm0 0 1000000>;
+		power-supply = <&bl_fixed_reg>;
+		enable-gpios = <&pio 95 GPIO_ACTIVE_HIGH>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&disp_pwm0_pins>;
+		status = "okay";
+	};
+
+	bl_fixed_reg: fixedregulator2 {
+		compatible = "regulator-fixed";
+		regulator-name = "bl_fixed";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		startup-delay-us = <1000>;
+		enable-active-high;
+		gpio = <&pio 32 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&bl_fixed_pins>;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	gpio_keys: gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&gpio_keys_pins>;
+
+		lid {
+			label = "Lid";
+			gpios = <&pio 69 GPIO_ACTIVE_LOW>;
+			linux,code = <SW_LID>;
+			linux,input-type = <EV_SW>;
+			gpio-key,wakeup;
+		};
+
+		power {
+			label = "Power";
+			gpios = <&pio 14 GPIO_ACTIVE_HIGH>;
+			linux,code = <KEY_POWER>;
+			debounce-interval = <30>;
+			gpio-key,wakeup;
+		};
+
+		tablet_mode {
+			label = "Tablet_mode";
+			gpios = <&pio 121 GPIO_ACTIVE_HIGH>;
+			linux,code = <SW_TABLET_MODE>;
+			linux,input-type = <EV_SW>;
+			gpio-key,wakeup;
+		};
+
+		volume_down {
+			label = "Volume_down";
+			gpios = <&pio 123 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_VOLUMEDOWN>;
+		};
+
+		volume_up {
+			label = "Volume_up";
+			gpios = <&pio 124 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_VOLUMEUP>;
+		};
+	};
+
+	panel: panel {
+		compatible = "lg,lp120up1";
+		power-supply = <&panel_fixed_3v3>;
+		ddc-i2c-bus = <&i2c0>;
+		backlight = <&backlight>;
+
+		port {
+			panel_in: endpoint {
+				remote-endpoint = <&ps8640_out>;
+			};
+		};
+	};
+
+	panel_fixed_3v3: regulator1 {
+		compatible = "regulator-fixed";
+		regulator-name = "PANEL_3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		enable-active-high;
+		gpio = <&pio 41 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&panel_fixed_pins>;
+	};
+
+	ps8640_fixed_1v2: regulator2 {
+		compatible = "regulator-fixed";
+		regulator-name = "PS8640_1V2";
+		regulator-min-microvolt = <1200000>;
+		regulator-max-microvolt = <1200000>;
+		regulator-enable-ramp-delay = <2000>;
+		enable-active-high;
+		regulator-boot-on;
+		gpio = <&pio 30 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&ps8640_fixed_pins>;
+	};
+
+	sdio_fixed_3v3: fixedregulator0 {
+		compatible = "regulator-fixed";
+		regulator-name = "3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		gpio = <&pio 85 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&sdio_fixed_3v3_pins>;
+	};
+
+	sound: sound {
+		compatible = "mediatek,mt8173-rt5650";
+		mediatek,audio-codec = <&rt5650 &hdmi0>;
+		mediatek,platform = <&afe>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&aud_i2s2>;
+
+		mediatek,mclk = <1>;
+		codec-capture {
+			sound-dai = <&rt5650 1>;
+		};
+	};
+
+	hdmicon: connector {
+		compatible = "hdmi-connector";
+		label = "hdmi";
+		type = "a";
+		ddc-i2c-bus = <&hdmiddc0>;
+
+		port {
+			hdmi_connector_in: endpoint {
+				remote-endpoint = <&hdmi0_out>;
+			};
+		};
+	};
+};
+
+&cec {
+	status = "okay";
+};
+
+&cpu0 {
+	proc-supply = <&mt6397_vpca15_reg>;
+};
+
+&cpu1 {
+	proc-supply = <&mt6397_vpca15_reg>;
+};
+
+&cpu2 {
+	proc-supply = <&da9211_vcpu_reg>;
+	sram-supply = <&mt6397_vsramca7_reg>;
+};
+
+&cpu3 {
+	proc-supply = <&da9211_vcpu_reg>;
+	sram-supply = <&mt6397_vsramca7_reg>;
+};
+
+&cpu_thermal {
+	sustainable-power = <4500>; /* milliwatts */
+	trips {
+		threshold: trip-point0 {
+			temperature = <60000>;
+		};
+
+		target: trip-point1 {
+			temperature = <65000>;
+		};
+	};
+};
+
+&dsi0 {
+	status = "okay";
+	ports {
+		port {
+			dsi0_out: endpoint {
+				remote-endpoint = <&ps8640_in>;
+			};
+		};
+	};
+};
+
+&dpi0 {
+	status = "okay";
+};
+
+&hdmi0 {
+	status = "okay";
+	ports {
+		port@1 {
+			reg = <1>;
+
+			hdmi0_out: endpoint {
+				remote-endpoint = <&hdmi_connector_in>;
+			};
+		};
+	};
+};
+
+&hdmi_phy {
+	status = "okay";
+	mediatek,ibias = <0xc>;
+};
+
+&i2c0 {
+	status = "okay";
+
+	rt5650: audio-codec@1a {
+		compatible = "realtek,rt5650";
+		reg = <0x1a>;
+		avdd-supply = <&mt6397_vgp1_reg>;
+		cpvdd-supply = <&mt6397_vcama_reg>;
+		interrupt-parent = <&pio>;
+		interrupts = <3 IRQ_TYPE_EDGE_BOTH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&rt5650_irq>;
+		#sound-dai-cells = <1>;
+		realtek,dmic1-data-pin = <2>;
+		realtek,jd-mode = <2>;
+	};
+
+	ps8640: edp-bridge@8 {
+		compatible = "parade,ps8640";
+		reg = <0x8>;
+		powerdown-gpios = <&pio 127 GPIO_ACTIVE_LOW>;
+		reset-gpios = <&pio 115 GPIO_ACTIVE_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&ps8640_pins>;
+		vdd12-supply = <&ps8640_fixed_1v2>;
+		vdd33-supply = <&mt6397_vgp2_reg>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+
+				ps8640_in: endpoint {
+					remote-endpoint = <&dsi0_out>;
+				};
+			};
+
+			port@1 {
+				reg = <1>;
+
+				ps8640_out: endpoint {
+					remote-endpoint = <&panel_in>;
+				};
+			};
+		};
+	};
+};
+
+&i2c1 {
+	clock-frequency = <1500000>;
+	status = "okay";
+
+	da9211: da9211@68 {
+		compatible = "dlg,da9211";
+		reg = <0x68>;
+		interrupt-parent = <&pio>;
+		interrupts = <15 IRQ_TYPE_LEVEL_LOW>;
+
+		regulators {
+			da9211_vcpu_reg: BUCKA {
+				regulator-name = "VBUCKA";
+				regulator-min-microvolt = < 700000>;
+				regulator-max-microvolt = <1310000>;
+				regulator-min-microamp  = <2000000>;
+				regulator-max-microamp  = <4400000>;
+				regulator-ramp-delay = <10000>;
+				regulator-always-on;
+				regulator-allowed-modes = <0 1>;
+			};
+
+			da9211_vgpu_reg: BUCKB {
+				regulator-name = "VBUCKB";
+				regulator-min-microvolt = < 700000>;
+				regulator-max-microvolt = <1310000>;
+				regulator-min-microamp  = <2000000>;
+				regulator-max-microamp  = <3000000>;
+				regulator-ramp-delay = <10000>;
+			};
+		};
+	};
+};
+
+&i2c2 {
+	status = "okay";
+
+	tpm: tpm@20 {
+		compatible = "infineon,slb9645tt";
+		reg = <0x20>;
+		powered-while-suspended;
+	};
+};
+
+&i2c3 {
+	clock-frequency = <400000>;
+	status = "okay";
+
+	touchscreen: touchscreen@10 {
+		compatible = "elan,ekth3500";
+		reg = <0x10>;
+		interrupt-parent = <&pio>;
+		interrupts = <88 IRQ_TYPE_LEVEL_LOW>;
+	};
+};
+
+&i2c4 {
+	clock-frequency = <400000>;
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&trackpad_irq>;
+
+	trackpad: trackpad@15 {
+		compatible = "elan,ekth3000";
+		interrupt-parent = <&pio>;
+		interrupts = <117 IRQ_TYPE_LEVEL_LOW>;
+		reg = <0x15>;
+		vcc-supply = <&mt6397_vgp6_reg>;
+		wakeup-source;
+	};
+};
+
+&mipi_tx0 {
+	status = "okay";
+};
+
+&mmc0 {
+	status = "okay";
+	pinctrl-names = "default", "state_uhs";
+	pinctrl-0 = <&mmc0_pins_default>;
+	pinctrl-1 = <&mmc0_pins_uhs>;
+	bus-width = <8>;
+	max-frequency = <200000000>;
+	cap-mmc-highspeed;
+	mmc-hs200-1_8v;
+	mmc-hs400-1_8v;
+	cap-mmc-hw-reset;
+	hs400-ds-delay = <0x14015>;
+	mediatek,hs200-cmd-int-delay=<30>;
+	mediatek,hs400-cmd-int-delay=<14>;
+	mediatek,hs400-cmd-resp-sel-rising;
+	vmmc-supply = <&mt6397_vemc_3v3_reg>;
+	vqmmc-supply = <&mt6397_vio18_reg>;
+	assigned-clocks = <&topckgen CLK_TOP_MSDC50_0_SEL>;
+	assigned-clock-parents = <&topckgen CLK_TOP_MSDCPLL_D2>;
+	non-removable;
+};
+
+&mmc1 {
+	status = "okay";
+	pinctrl-names = "default", "state_uhs";
+	pinctrl-0 = <&mmc1_pins_default>;
+	pinctrl-1 = <&mmc1_pins_uhs>;
+	bus-width = <4>;
+	max-frequency = <200000000>;
+	cap-sd-highspeed;
+	sd-uhs-sdr50;
+	sd-uhs-sdr104;
+	cd-gpios = <&pio 1 GPIO_ACTIVE_LOW>;
+	vmmc-supply = <&mt6397_vmch_reg>;
+	vqmmc-supply = <&mt6397_vmc_reg>;
+};
+
+&mmc3 {
+	status = "okay";
+	pinctrl-names = "default", "state_uhs";
+	pinctrl-0 = <&mmc3_pins_default>;
+	pinctrl-1 = <&mmc3_pins_uhs>;
+	bus-width = <4>;
+	max-frequency = <200000000>;
+	cap-sd-highspeed;
+	sd-uhs-sdr50;
+	sd-uhs-sdr104;
+	keep-power-in-suspend;
+	enable-sdio-wakeup;
+	cap-sdio-irq;
+	vmmc-supply = <&sdio_fixed_3v3>;
+	vqmmc-supply = <&mt6397_vgp3_reg>;
+	non-removable;
+	cap-power-off-card;
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	btmrvl: btmrvl@2 {
+		compatible = "marvell,sd8897-bt";
+		reg = <2>;
+		interrupt-parent = <&pio>;
+		interrupts = <119 IRQ_TYPE_LEVEL_LOW>;
+		marvell,wakeup-pin = /bits/ 16 <0x0d>;
+		marvell,wakeup-gap-ms = /bits/ 16 <0x64>;
+	};
+
+	mwifiex: mwifiex@1 {
+		compatible = "marvell,sd8897";
+		reg = <1>;
+		interrupt-parent = <&pio>;
+		interrupts = <38 IRQ_TYPE_LEVEL_LOW>;
+		marvell,wakeup-pin = <3>;
+	};
+};
+
+&nor_flash {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&nor_gpio1_pins>;
+	bus-width = <8>;
+	max-frequency = <50000000>;
+	non-removable;
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+	};
+};
+
+&pio {
+	gpio-line-names = "EC_INT_1V8",
+			  "SD_CD_L",
+			  "ALC5514_IRQ",
+			  "ALC5650_IRQ",
+			  /*
+			   * AP_FLASH_WP_L is crossystem ABI. Schematics
+			   * call it SFWP_B.
+			   */
+			  "AP_FLASH_WP_L",
+			  "SFIN",
+			  "SFCS0",
+			  "SFHOLD",
+			  "SFOUT",
+			  "SFCK",
+			  "WRAP_EVENT_S_EINT10",
+			  "PMU_INT",
+			  "I2S2_WS_ALC5650",
+			  "I2S2_BCK_ALC5650",
+			  "PWR_BTN_1V8",
+			  "DA9212_IRQ",
+			  "IDDIG",
+			  "WATCHDOG",
+			  "CEC",
+			  "HDMISCK",
+			  "HDMISD",
+			  "HTPLG",
+			  "MSDC3_DAT0",
+			  "MSDC3_DAT1",
+			  "MSDC3_DAT2",
+			  "MSDC3_DAT3",
+			  "MSDC3_CLK",
+			  "MSDC3_CMD",
+			  "USB_C0_OC_FLAGB",
+			  "USBA_OC1_L",
+			  "PS8640_1V2_ENABLE",
+			  "THERM_ALERT_N",
+			  "PANEL_LCD_POWER_EN",
+			  "ANX7688_CHIP_PD_C",
+			  "EC_IN_RW_1V8",
+			  "ANX7688_1V_EN_C",
+			  "USB_DP_HPD_C",
+			  "TPM_DAVINT_N",
+			  "MARVELL8897_IRQ",
+			  "EN_USB_A0_PWR",
+			  "USBA_A0_OC_L",
+			  "EN_PP3300_DX_EDP",
+			  "",
+			  "SOC_I2C2_1V8_SDA_400K",
+			  "SOC_I2C2_1V8_SCL_400K",
+			  "SOC_I2C0_1V8_SDA_400K",
+			  "SOC_I2C0_1V8_SCL_400K",
+			  "EMMC_ID1",
+			  "EMMC_ID0",
+			  "MEM_CONFIG3",
+			  "EMMC_ID2",
+			  "MEM_CONFIG1",
+			  "MEM_CONFIG2",
+			  "BRD_ID2",
+			  "MEM_CONFIG0",
+			  "BRD_ID0",
+			  "BRD_ID1",
+			  "EMMC_DAT0",
+			  "EMMC_DAT1",
+			  "EMMC_DAT2",
+			  "EMMC_DAT3",
+			  "EMMC_DAT4",
+			  "EMMC_DAT5",
+			  "EMMC_DAT6",
+			  "EMMC_DAT7",
+			  "EMMC_CLK",
+			  "EMMC_CMD",
+			  "EMMC_RCLK",
+			  "PLT_RST_L",
+			  "LID_OPEN_1V8_L",
+			  "AUDIO_SPI_MISO_R",
+			  "",
+			  "AC_OK_1V8",
+			  "SD_DATA0",
+			  "SD_DATA1",
+			  "SD_DATA2",
+			  "SD_DATA3",
+			  "SD_CLK",
+			  "SD_CMD",
+			  "PWRAP_SPI0_MI",
+			  "PWRAP_SPI0_MO",
+			  "PWRAP_SPI0_CK",
+			  "PWRAP_SPI0_CSN",
+			  "",
+			  "",
+			  "WIFI_PDN",
+			  "RTC32K_1V8",
+			  "DISP_PWM0",
+			  "TOUCHSCREEN_INT_L",
+			  "",
+			  "SRCLKENA0",
+			  "SRCLKENA1",
+			  "PS8640_MODE_CONF",
+			  "TOUCHSCREEN_RESET_R",
+			  "PLATFORM_PROCHOT_L",
+			  "PANEL_POWER_EN",
+			  "REC_MODE_L",
+			  "EC_FW_UPDATE_L",
+			  "ACCEL2_INT_L",
+			  "HDMI_DP_INT",
+			  "ACCELGYRO3_INT_L",
+			  "ACCELGYRO4_INT_L",
+			  "SPI_EC_CLK",
+			  "SPI_EC_MI",
+			  "SPI_EC_MO",
+			  "SPI_EC_CSN",
+			  "SOC_I2C3_1V8_SDA_400K",
+			  "SOC_I2C3_1V8_SCL_400K",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "PS8640_SYSRSTN_1V8",
+			  "APIN_MAX98090_DOUT2",
+			  "TP_INT_1V8_L_R",
+			  "RST_USB_HUB_R",
+			  "BT_WAKE_L",
+			  "ACCEL1_INT_L",
+			  "TABLET_MODE_L",
+			  "",
+			  "V_UP_IN_L_R",
+			  "V_DOWN_IN_L_R",
+			  "SOC_I2C1_1V8_SDA_1M",
+			  "SOC_I2C1_1V8_SCL_1M",
+			  "PS8640_PDN_1V8",
+			  "MAX98090_LRCLK",
+			  "MAX98090_BCLK",
+			  "MAX98090_MCLK",
+			  "APOUT_MAX98090_DIN",
+			  "APIN_MAX98090_DOUT",
+			  "SOC_I2C4_1V8_SDA_400K",
+			  "SOC_I2C4_1V8_SCL_400K";
+
+	aud_i2s2: aud_i2s2 {
+		pins1 {
+			pinmux = <MT8173_PIN_128_I2S0_LRCK__FUNC_I2S1_WS>,
+				 <MT8173_PIN_129_I2S0_BCK__FUNC_I2S1_BCK>,
+				 <MT8173_PIN_130_I2S0_MCK__FUNC_I2S1_MCK>,
+				 <MT8173_PIN_131_I2S0_DATA0__FUNC_I2S1_DO_1>,
+				 <MT8173_PIN_12_EINT12__FUNC_I2S2_WS>,
+				 <MT8173_PIN_13_EINT13__FUNC_I2S2_BCK>,
+				 <MT8173_PIN_132_I2S0_DATA1__FUNC_I2S2_DI_2>;
+			bias-pull-down;
+		};
+	};
+
+	bl_fixed_pins: bl_fixed_pins {
+		pins1 {
+			pinmux = <MT8173_PIN_32_UTXD2__FUNC_GPIO32>;
+			output-low;
+		};
+	};
+
+	bt_wake_pins: bt_wake_pins {
+		pins1 {
+			pinmux = <MT8173_PIN_119_KPROW0__FUNC_GPIO119>;
+			bias-pull-up;
+		};
+	};
+
+	disp_pwm0_pins: disp_pwm0_pins {
+		pins1 {
+			pinmux = <MT8173_PIN_87_DISP_PWM0__FUNC_DISP_PWM0>;
+			output-low;
+		};
+	};
+
+	gpio_keys_pins: gpio_keys_pins {
+		volume_pins {
+			pinmux = <MT8173_PIN_123_KPCOL1__FUNC_GPIO123>,
+				 <MT8173_PIN_124_KPCOL2__FUNC_GPIO124>;
+			bias-pull-up;
+		};
+
+		tablet_mode_pins {
+			pinmux = <MT8173_PIN_121_KPROW2__FUNC_GPIO121>;
+			bias-pull-up;
+		};
+	};
+
+	hdmi_mux_pins: hdmi_mux_pins {
+		pins1 {
+			pinmux = <MT8173_PIN_36_DAISYNC__FUNC_GPIO36>;
+		};
+	};
+
+	i2c1_pins_a: i2c1 {
+		da9211_pins {
+			pinmux = <MT8173_PIN_15_EINT15__FUNC_GPIO15>;
+			bias-pull-up;
+		};
+	};
+
+	mmc0_pins_default: mmc0default {
+		pins_cmd_dat {
+			pinmux = <MT8173_PIN_57_MSDC0_DAT0__FUNC_MSDC0_DAT0>,
+				 <MT8173_PIN_58_MSDC0_DAT1__FUNC_MSDC0_DAT1>,
+				 <MT8173_PIN_59_MSDC0_DAT2__FUNC_MSDC0_DAT2>,
+				 <MT8173_PIN_60_MSDC0_DAT3__FUNC_MSDC0_DAT3>,
+				 <MT8173_PIN_61_MSDC0_DAT4__FUNC_MSDC0_DAT4>,
+				 <MT8173_PIN_62_MSDC0_DAT5__FUNC_MSDC0_DAT5>,
+				 <MT8173_PIN_63_MSDC0_DAT6__FUNC_MSDC0_DAT6>,
+				 <MT8173_PIN_64_MSDC0_DAT7__FUNC_MSDC0_DAT7>,
+				 <MT8173_PIN_66_MSDC0_CMD__FUNC_MSDC0_CMD>;
+			bias-pull-up;
+		};
+
+		pins_clk {
+			pinmux = <MT8173_PIN_65_MSDC0_CLK__FUNC_MSDC0_CLK>;
+			bias-pull-down;
+		};
+
+		pins_rst {
+			pinmux = <MT8173_PIN_68_MSDC0_RST___FUNC_MSDC0_RSTB>;
+			bias-pull-up;
+		};
+	};
+
+	mmc1_pins_default: mmc1default {
+		pins_cmd_dat {
+			pinmux = <MT8173_PIN_73_MSDC1_DAT0__FUNC_MSDC1_DAT0>,
+				 <MT8173_PIN_74_MSDC1_DAT1__FUNC_MSDC1_DAT1>,
+				 <MT8173_PIN_75_MSDC1_DAT2__FUNC_MSDC1_DAT2>,
+				 <MT8173_PIN_76_MSDC1_DAT3__FUNC_MSDC1_DAT3>,
+				 <MT8173_PIN_78_MSDC1_CMD__FUNC_MSDC1_CMD>;
+			input-enable;
+			drive-strength = <MTK_DRIVE_4mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_10>;
+		};
+
+		pins_clk {
+			pinmux = <MT8173_PIN_77_MSDC1_CLK__FUNC_MSDC1_CLK>;
+			bias-pull-down;
+			drive-strength = <MTK_DRIVE_4mA>;
+		};
+
+		pins_insert {
+			pinmux = <MT8173_PIN_1_EINT1__FUNC_GPIO1>;
+			bias-pull-up;
+		};
+	};
+
+	mmc3_pins_default: mmc3default {
+		pins_dat {
+			pinmux = <MT8173_PIN_22_MSDC3_DAT0__FUNC_MSDC3_DAT0>,
+				 <MT8173_PIN_23_MSDC3_DAT1__FUNC_MSDC3_DAT1>,
+				 <MT8173_PIN_24_MSDC3_DAT2__FUNC_MSDC3_DAT2>,
+				 <MT8173_PIN_25_MSDC3_DAT3__FUNC_MSDC3_DAT3>;
+			input-enable;
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_10>;
+		};
+
+		pins_cmd {
+			pinmux = <MT8173_PIN_27_MSDC3_CMD__FUNC_MSDC3_CMD>;
+			input-enable;
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_10>;
+		};
+
+		pins_clk {
+			pinmux = <MT8173_PIN_26_MSDC3_CLK__FUNC_MSDC3_CLK>;
+			bias-pull-down;
+			drive-strength = <MTK_DRIVE_8mA>;
+		};
+	};
+
+	mmc0_pins_uhs: mmc0 {
+		pins_cmd_dat {
+			pinmux = <MT8173_PIN_57_MSDC0_DAT0__FUNC_MSDC0_DAT0>,
+				 <MT8173_PIN_58_MSDC0_DAT1__FUNC_MSDC0_DAT1>,
+				 <MT8173_PIN_59_MSDC0_DAT2__FUNC_MSDC0_DAT2>,
+				 <MT8173_PIN_60_MSDC0_DAT3__FUNC_MSDC0_DAT3>,
+				 <MT8173_PIN_61_MSDC0_DAT4__FUNC_MSDC0_DAT4>,
+				 <MT8173_PIN_62_MSDC0_DAT5__FUNC_MSDC0_DAT5>,
+				 <MT8173_PIN_63_MSDC0_DAT6__FUNC_MSDC0_DAT6>,
+				 <MT8173_PIN_64_MSDC0_DAT7__FUNC_MSDC0_DAT7>,
+				 <MT8173_PIN_66_MSDC0_CMD__FUNC_MSDC0_CMD>;
+			input-enable;
+			drive-strength = <MTK_DRIVE_6mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+
+		pins_clk {
+			pinmux = <MT8173_PIN_65_MSDC0_CLK__FUNC_MSDC0_CLK>;
+			drive-strength = <MTK_DRIVE_6mA>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_01>;
+		};
+
+		pins_ds {
+			pinmux = <MT8173_PIN_67_MSDC0_DSL__FUNC_MSDC0_DSL>;
+			drive-strength = <MTK_DRIVE_10mA>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_01>;
+		};
+
+		pins_rst {
+			pinmux = <MT8173_PIN_68_MSDC0_RST___FUNC_MSDC0_RSTB>;
+			bias-pull-up;
+		};
+	};
+
+	mmc1_pins_uhs: mmc1 {
+		pins_cmd_dat {
+			pinmux = <MT8173_PIN_73_MSDC1_DAT0__FUNC_MSDC1_DAT0>,
+				 <MT8173_PIN_74_MSDC1_DAT1__FUNC_MSDC1_DAT1>,
+				 <MT8173_PIN_75_MSDC1_DAT2__FUNC_MSDC1_DAT2>,
+				 <MT8173_PIN_76_MSDC1_DAT3__FUNC_MSDC1_DAT3>,
+				 <MT8173_PIN_78_MSDC1_CMD__FUNC_MSDC1_CMD>;
+			input-enable;
+			drive-strength = <MTK_DRIVE_6mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_10>;
+		};
+
+		pins_clk {
+			pinmux = <MT8173_PIN_77_MSDC1_CLK__FUNC_MSDC1_CLK>;
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+		};
+	};
+
+	mmc3_pins_uhs: mmc3 {
+		pins_dat {
+			pinmux = <MT8173_PIN_22_MSDC3_DAT0__FUNC_MSDC3_DAT0>,
+				 <MT8173_PIN_23_MSDC3_DAT1__FUNC_MSDC3_DAT1>,
+				 <MT8173_PIN_24_MSDC3_DAT2__FUNC_MSDC3_DAT2>,
+				 <MT8173_PIN_25_MSDC3_DAT3__FUNC_MSDC3_DAT3>;
+			input-enable;
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_10>;
+		};
+
+		pins_cmd {
+			pinmux = <MT8173_PIN_27_MSDC3_CMD__FUNC_MSDC3_CMD>;
+			input-enable;
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_10>;
+		};
+
+		pins_clk {
+			pinmux = <MT8173_PIN_26_MSDC3_CLK__FUNC_MSDC3_CLK>;
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+		};
+	};
+
+	nor_gpio1_pins: nor {
+		pins1 {
+			pinmux = <MT8173_PIN_6_EINT6__FUNC_SFCS0>,
+				 <MT8173_PIN_7_EINT7__FUNC_SFHOLD>,
+				 <MT8173_PIN_8_EINT8__FUNC_SFIN>;
+			input-enable;
+			drive-strength = <MTK_DRIVE_4mA>;
+			bias-pull-up;
+		};
+
+		pins2 {
+			pinmux = <MT8173_PIN_5_EINT5__FUNC_SFOUT>;
+			drive-strength = <MTK_DRIVE_4mA>;
+			bias-pull-up;
+		};
+
+		pins_clk {
+			pinmux = <MT8173_PIN_9_EINT9__FUNC_SFCK>;
+			input-enable;
+			drive-strength = <MTK_DRIVE_4mA>;
+			bias-pull-up;
+		};
+	};
+
+	panel_fixed_pins: panel_fixed_pins {
+		pins1 {
+			pinmux = <MT8173_PIN_41_CMMCLK__FUNC_GPIO41>;
+		};
+	};
+
+	ps8640_pins: ps8640_pins {
+		pins1 {
+			pinmux = <MT8173_PIN_92_PCM_CLK__FUNC_GPIO92>,
+				 <MT8173_PIN_115_URTS0__FUNC_GPIO115>,
+				 <MT8173_PIN_127_LCM_RST__FUNC_GPIO127>;
+		};
+	};
+
+	ps8640_fixed_pins: ps8640_fixed_pins {
+		pins1 {
+			pinmux = <MT8173_PIN_30_URTS2__FUNC_GPIO30>;
+		};
+	};
+
+	rt5650_irq: rt5650_irq {
+		pins1 {
+			pinmux = <MT8173_PIN_3_EINT3__FUNC_GPIO3>;
+			bias-pull-down;
+		};
+	};
+
+	sdio_fixed_3v3_pins: sdio_fixed_3v3_pins {
+		pins1 {
+			pinmux = <MT8173_PIN_85_AUD_DAT_MOSI__FUNC_GPIO85>;
+			output-low;
+		};
+	};
+
+	spi_pins_a: spi1 {
+		pins1 {
+			pinmux = <MT8173_PIN_0_EINT0__FUNC_GPIO0>;
+			bias-pull-up;
+		};
+
+		pins_spi {
+			pinmux = <MT8173_PIN_102_MSDC2_DAT2__FUNC_SPI_CK_1_>,
+				 <MT8173_PIN_103_MSDC2_DAT3__FUNC_SPI_MI_1_>,
+				 <MT8173_PIN_104_MSDC2_CLK__FUNC_SPI_MO_1_>,
+				 <MT8173_PIN_105_MSDC2_CMD__FUNC_SPI_CS_1_>;
+			bias-disable;
+		};
+	};
+
+	trackpad_irq: trackpad_irq {
+		pins1 {
+			pinmux = <MT8173_PIN_117_URXD3__FUNC_GPIO117>;
+			input-enable;
+			bias-pull-up;
+		};
+	};
+
+	usb_pins: usb {
+		pins1 {
+			pinmux = <MT8173_PIN_101_MSDC2_DAT1__FUNC_GPIO101>;
+			output-high;
+			bias-disable;
+		};
+	};
+
+	wifi_wake_pins: wifi_wake_pins {
+		pins1 {
+			pinmux = <MT8173_PIN_38_CONN_RST__FUNC_GPIO38>;
+			bias-pull-up;
+		};
+	};
+};
+
+&pwm0 {
+	status = "okay";
+};
+
+&pwrap {
+	pmic: mt6397 {
+		compatible = "mediatek,mt6397";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		interrupt-parent = <&pio>;
+		interrupts = <11 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+
+		clock: mt6397clock {
+			compatible = "mediatek,mt6397-clk";
+			#clock-cells = <1>;
+		};
+
+		pio6397: pinctrl {
+			compatible = "mediatek,mt6397-pinctrl";
+			pins-are-numbered;
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		regulator: mt6397regulator {
+			compatible = "mediatek,mt6397-regulator";
+
+			mt6397_vpca15_reg: buck_vpca15 {
+				regulator-compatible = "buck_vpca15";
+				regulator-name = "vpca15";
+				regulator-min-microvolt = < 700000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <12500>;
+				regulator-always-on;
+				regulator-allowed-modes = <0 1>;
+			};
+
+			mt6397_vpca7_reg: buck_vpca7 {
+				regulator-compatible = "buck_vpca7";
+				regulator-name = "vpca7";
+				regulator-min-microvolt = < 700000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <12500>;
+				regulator-enable-ramp-delay = <115>;
+				regulator-always-on;
+			};
+
+			mt6397_vsramca15_reg: buck_vsramca15 {
+				regulator-compatible = "buck_vsramca15";
+				regulator-name = "vsramca15";
+				regulator-min-microvolt = < 700000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <12500>;
+				regulator-always-on;
+			};
+
+			mt6397_vsramca7_reg: buck_vsramca7 {
+				regulator-compatible = "buck_vsramca7";
+				regulator-name = "vsramca7";
+				regulator-min-microvolt = < 700000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <12500>;
+				regulator-always-on;
+			};
+
+			mt6397_vcore_reg: buck_vcore {
+				regulator-compatible = "buck_vcore";
+				regulator-name = "vcore";
+				regulator-min-microvolt = < 700000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <12500>;
+				regulator-always-on;
+			};
+
+			mt6397_vgpu_reg: buck_vgpu {
+				regulator-compatible = "buck_vgpu";
+				regulator-name = "vgpu";
+				regulator-min-microvolt = < 700000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <12500>;
+				regulator-enable-ramp-delay = <115>;
+			};
+
+			mt6397_vdrm_reg: buck_vdrm {
+				regulator-compatible = "buck_vdrm";
+				regulator-name = "vdrm";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1400000>;
+				regulator-ramp-delay = <12500>;
+				regulator-always-on;
+			};
+
+			mt6397_vio18_reg: buck_vio18 {
+				regulator-compatible = "buck_vio18";
+				regulator-name = "vio18";
+				regulator-min-microvolt = <1620000>;
+				regulator-max-microvolt = <1980000>;
+				regulator-ramp-delay = <12500>;
+				regulator-always-on;
+			};
+
+			mt6397_vtcxo_reg: ldo_vtcxo {
+				regulator-compatible = "ldo_vtcxo";
+				regulator-name = "vtcxo";
+				regulator-always-on;
+			};
+
+			mt6397_va28_reg: ldo_va28 {
+				regulator-compatible = "ldo_va28";
+				regulator-name = "va28";
+			};
+
+			mt6397_vcama_reg: ldo_vcama {
+				regulator-compatible = "ldo_vcama";
+				regulator-name = "vcama";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-enable-ramp-delay = <218>;
+			};
+
+			mt6397_vio28_reg: ldo_vio28 {
+				regulator-compatible = "ldo_vio28";
+				regulator-name = "vio28";
+				regulator-always-on;
+			};
+
+			mt6397_vusb_reg: ldo_vusb {
+				regulator-compatible = "ldo_vusb";
+				regulator-name = "vusb";
+			};
+
+			mt6397_vmc_reg: ldo_vmc {
+				regulator-compatible = "ldo_vmc";
+				regulator-name = "vmc";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-enable-ramp-delay = <218>;
+			};
+
+			mt6397_vmch_reg: ldo_vmch {
+				regulator-compatible = "ldo_vmch";
+				regulator-name = "vmch";
+				regulator-min-microvolt = <3000000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-enable-ramp-delay = <218>;
+			};
+
+			mt6397_vemc_3v3_reg: ldo_vemc3v3 {
+				regulator-compatible = "ldo_vemc3v3";
+				regulator-name = "vemc_3v3";
+				regulator-min-microvolt = <3000000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-enable-ramp-delay = <218>;
+			};
+
+			mt6397_vgp1_reg: ldo_vgp1 {
+				regulator-compatible = "ldo_vgp1";
+				regulator-name = "vcamd";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-enable-ramp-delay = <240>;
+			};
+
+			mt6397_vgp2_reg: ldo_vgp2 {
+				regulator-compatible = "ldo_vgp2";
+				regulator-name = "vcamio";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-enable-ramp-delay = <218>;
+			};
+
+			mt6397_vgp3_reg: ldo_vgp3 {
+				regulator-compatible = "ldo_vgp3";
+				regulator-name = "vcamaf";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-enable-ramp-delay = <218>;
+			};
+
+			mt6397_vgp4_reg: ldo_vgp4 {
+				regulator-compatible = "ldo_vgp4";
+				regulator-name = "vgp4";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-enable-ramp-delay = <218>;
+			};
+
+			mt6397_vgp5_reg: ldo_vgp5 {
+				regulator-compatible = "ldo_vgp5";
+				regulator-name = "vgp5";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <3000000>;
+				regulator-enable-ramp-delay = <218>;
+			};
+
+			mt6397_vgp6_reg: ldo_vgp6 {
+				regulator-compatible = "ldo_vgp6";
+				regulator-name = "vgp6";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-enable-ramp-delay = <218>;
+				regulator-always-on;
+			};
+
+			mt6397_vibr_reg: ldo_vibr {
+				regulator-compatible = "ldo_vibr";
+				regulator-name = "vibr";
+				regulator-min-microvolt = <1300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-enable-ramp-delay = <218>;
+			};
+		};
+
+		rtc: mt6397rtc {
+			compatible = "mediatek,mt6397-rtc";
+		};
+
+		syscfg_pctl_pmic: syscfg_pctl_pmic@c000 {
+			compatible = "mediatek,mt6397-pctl-pmic-syscfg",
+				     "syscon";
+			reg = <0 0x0000c000 0 0x0108>;
+		};
+	};
+};
+
+&spi {
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi_pins_a>;
+	mediatek,pad-select = <1>;
+	status = "okay";
+	/* clients */
+	cros_ec: ec@0 {
+		compatible = "google,cros-ec-spi";
+		reg = <0x0>;
+		spi-max-frequency = <12000000>;
+		interrupt-parent = <&pio>;
+		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+		google,cros-ec-spi-msg-delay = <500>;
+
+		i2c_tunnel: i2c-tunnel0 {
+			compatible = "google,cros-ec-i2c-tunnel";
+			google,remote-bus = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			battery: sbs-battery@b {
+				compatible = "sbs,sbs-battery";
+				reg = <0xb>;
+				sbs,i2c-retry-count = <2>;
+				sbs,poll-retry-count = <1>;
+			};
+		};
+	};
+};
+
+&ssusb {
+	dr_mode = "host";
+	wakeup-source;
+	vusb33-supply = <&mt6397_vusb_reg>;
+	status = "okay";
+};
+
+&thermal {
+	bank0-supply = <&mt6397_vpca15_reg>;
+	bank1-supply = <&da9211_vcpu_reg>;
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&usb_host {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb_pins>;
+	vusb33-supply = <&mt6397_vusb_reg>;
+	status = "okay";
+};
+
+#include <arm/cros-ec-keyboard.dtsi>
diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index ccb8e88a60c5..a212bf124e81 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -50,6 +50,10 @@ aliases {
 		mdp_wdma0 = &mdp_wdma0;
 		mdp_wrot0 = &mdp_wrot0;
 		mdp_wrot1 = &mdp_wrot1;
+		serial0 = &uart0;
+		serial1 = &uart1;
+		serial2 = &uart2;
+		serial3 = &uart3;
 	};
 
 	cluster0_opp: opp_table0 {
@@ -242,21 +246,21 @@ psci {
 		cpu_on	      = <0x84000003>;
 	};
 
-	clk26m: oscillator@0 {
+	clk26m: oscillator0 {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
 		clock-frequency = <26000000>;
 		clock-output-names = "clk26m";
 	};
 
-	clk32k: oscillator@1 {
+	clk32k: oscillator1 {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
 		clock-frequency = <32000>;
 		clock-output-names = "clk32k";
 	};
 
-	cpum_ck: oscillator@2 {
+	cpum_ck: oscillator2 {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
 		clock-frequency = <0>;
@@ -272,19 +276,19 @@ cpu_thermal: cpu_thermal {
 			sustainable-power = <1500>; /* milliwatts */
 
 			trips {
-				threshold: trip-point@0 {
+				threshold: trip-point0 {
 					temperature = <68000>;
 					hysteresis = <2000>;
 					type = "passive";
 				};
 
-				target: trip-point@1 {
+				target: trip-point1 {
 					temperature = <85000>;
 					hysteresis = <2000>;
 					type = "passive";
 				};
 
-				cpu_crit: cpu_crit@0 {
+				cpu_crit: cpu_crit0 {
 					temperature = <115000>;
 					hysteresis = <2000>;
 					type = "critical";
@@ -292,13 +296,13 @@ cpu_crit: cpu_crit@0 {
 			};
 
 			cooling-maps {
-				map@0 {
+				map0 {
 					trip = <&target>;
 					cooling-device = <&cpu0 0 0>,
 							 <&cpu1 0 0>;
 					contribution = <3072>;
 				};
-				map@1 {
+				map1 {
 					trip = <&target>;
 					cooling-device = <&cpu2 0 0>,
 							 <&cpu3 0 0>;
@@ -312,7 +316,7 @@ reserved-memory {
 		#address-cells = <2>;
 		#size-cells = <2>;
 		ranges;
-		vpu_dma_reserved: vpu_dma_mem_region {
+		vpu_dma_reserved: vpu_dma_mem_region@b7000000 {
 			compatible = "shared-dma-pool";
 			reg = <0 0xb7000000 0 0x500000>;
 			alignment = <0x1000>;
@@ -365,7 +369,7 @@ syscfg_pctl_a: syscfg_pctl_a@10005000 {
 			reg = <0 0x10005000 0 0x1000>;
 		};
 
-		pio: pinctrl@10005000 {
+		pio: pinctrl@1000b000 {
 			compatible = "mediatek,mt8173-pinctrl";
 			reg = <0 0x1000b000 0 0x1000>;
 			mediatek,pctl-regmap = <&syscfg_pctl_a>;
@@ -549,7 +553,7 @@ gce: mailbox@10212000 {
 			interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_LOW>;
 			clocks = <&infracfg CLK_INFRA_GCE>;
 			clock-names = "gce";
-			#mbox-cells = <3>;
+			#mbox-cells = <2>;
 		};
 
 		mipi_tx0: mipi-dphy@10215000 {
@@ -572,7 +576,7 @@ mipi_tx1: mipi-dphy@10216000 {
 			status = "disabled";
 		};
 
-		gic: interrupt-controller@10220000 {
+		gic: interrupt-controller@10221000 {
 			compatible = "arm,gic-400";
 			#interrupt-cells = <3>;
 			interrupt-parent = <&gic>;
@@ -916,6 +920,9 @@ mmsys: clock-controller@14000000 {
 			assigned-clocks = <&topckgen CLK_TOP_MM_SEL>;
 			assigned-clock-rates = <400000000>;
 			#clock-cells = <1>;
+			mboxes = <&gce 0 CMDQ_THR_PRIO_HIGHEST>,
+				 <&gce 1 CMDQ_THR_PRIO_HIGHEST>;
+			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0 0x1000>;
 		};
 
 		mdp_rdma0: rdma@14001000 {
@@ -996,6 +1003,7 @@ ovl0: ovl@1400c000 {
 			clocks = <&mmsys CLK_MM_DISP_OVL0>;
 			iommus = <&iommu M4U_PORT_DISP_OVL0>;
 			mediatek,larb = <&larb0>;
+			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xc000 0x1000>;
 		};
 
 		ovl1: ovl@1400d000 {
@@ -1006,6 +1014,7 @@ ovl1: ovl@1400d000 {
 			clocks = <&mmsys CLK_MM_DISP_OVL1>;
 			iommus = <&iommu M4U_PORT_DISP_OVL1>;
 			mediatek,larb = <&larb4>;
+			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xd000 0x1000>;
 		};
 
 		rdma0: rdma@1400e000 {
@@ -1016,6 +1025,7 @@ rdma0: rdma@1400e000 {
 			clocks = <&mmsys CLK_MM_DISP_RDMA0>;
 			iommus = <&iommu M4U_PORT_DISP_RDMA0>;
 			mediatek,larb = <&larb0>;
+			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xe000 0x1000>;
 		};
 
 		rdma1: rdma@1400f000 {
@@ -1026,6 +1036,7 @@ rdma1: rdma@1400f000 {
 			clocks = <&mmsys CLK_MM_DISP_RDMA1>;
 			iommus = <&iommu M4U_PORT_DISP_RDMA1>;
 			mediatek,larb = <&larb4>;
+			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xf000 0x1000>;
 		};
 
 		rdma2: rdma@14010000 {
@@ -1036,6 +1047,7 @@ rdma2: rdma@14010000 {
 			clocks = <&mmsys CLK_MM_DISP_RDMA2>;
 			iommus = <&iommu M4U_PORT_DISP_RDMA2>;
 			mediatek,larb = <&larb4>;
+			mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0 0x1000>;
 		};
 
 		wdma0: wdma@14011000 {
@@ -1046,6 +1058,7 @@ wdma0: wdma@14011000 {
 			clocks = <&mmsys CLK_MM_DISP_WDMA0>;
 			iommus = <&iommu M4U_PORT_DISP_WDMA0>;
 			mediatek,larb = <&larb0>;
+			mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x1000 0x1000>;
 		};
 
 		wdma1: wdma@14012000 {
@@ -1056,6 +1069,7 @@ wdma1: wdma@14012000 {
 			clocks = <&mmsys CLK_MM_DISP_WDMA1>;
 			iommus = <&iommu M4U_PORT_DISP_WDMA1>;
 			mediatek,larb = <&larb4>;
+			mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x2000 0x1000>;
 		};
 
 		color0: color@14013000 {
@@ -1064,6 +1078,7 @@ color0: color@14013000 {
 			interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_LOW>;
 			power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
 			clocks = <&mmsys CLK_MM_DISP_COLOR0>;
+			mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x3000 0x1000>;
 		};
 
 		color1: color@14014000 {
@@ -1072,6 +1087,7 @@ color1: color@14014000 {
 			interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_LOW>;
 			power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
 			clocks = <&mmsys CLK_MM_DISP_COLOR1>;
+			mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x4000 0x1000>;
 		};
 
 		aal@14015000 {
@@ -1080,6 +1096,7 @@ aal@14015000 {
 			interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_LOW>;
 			power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
 			clocks = <&mmsys CLK_MM_DISP_AAL>;
+			mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x5000 0x1000>;
 		};
 
 		gamma@14016000 {
@@ -1088,6 +1105,7 @@ gamma@14016000 {
 			interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_LOW>;
 			power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
 			clocks = <&mmsys CLK_MM_DISP_GAMMA>;
+			mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x6000 0x1000>;
 		};
 
 		merge@14017000 {
@@ -1193,6 +1211,8 @@ mutex: mutex@14020000 {
 			interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_LOW>;
 			power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
 			clocks = <&mmsys CLK_MM_MUTEX_32K>;
+			mediatek,gce-events = <CMDQ_EVENT_MUTEX0_STREAM_EOF>,
+                                              <CMDQ_EVENT_MUTEX1_STREAM_EOF>;
 		};
 
 		larb0: larb@14021000 {
@@ -1437,4 +1457,3 @@ larb5: larb@19001000 {
 		};
 	};
 };
-
diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index 97863adb7bc0..d946c1466c12 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -74,7 +74,7 @@ cpu0: cpu@0 {
 			reg = <0x000>;
 			enable-method = "psci";
 			capacity-dmips-mhz = <741>;
-			cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
+			cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP0>;
 			dynamic-power-coefficient = <84>;
 			#cooling-cells = <2>;
 		};
@@ -85,7 +85,7 @@ cpu1: cpu@1 {
 			reg = <0x001>;
 			enable-method = "psci";
 			capacity-dmips-mhz = <741>;
-			cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
+			cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP0>;
 			dynamic-power-coefficient = <84>;
 			#cooling-cells = <2>;
 		};
@@ -96,7 +96,7 @@ cpu2: cpu@2 {
 			reg = <0x002>;
 			enable-method = "psci";
 			capacity-dmips-mhz = <741>;
-			cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
+			cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP0>;
 			dynamic-power-coefficient = <84>;
 			#cooling-cells = <2>;
 		};
@@ -107,7 +107,7 @@ cpu3: cpu@3 {
 			reg = <0x003>;
 			enable-method = "psci";
 			capacity-dmips-mhz = <741>;
-			cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
+			cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP0>;
 			dynamic-power-coefficient = <84>;
 			#cooling-cells = <2>;
 		};
@@ -118,7 +118,7 @@ cpu4: cpu@100 {
 			reg = <0x100>;
 			enable-method = "psci";
 			capacity-dmips-mhz = <1024>;
-			cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
+			cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP1>;
 			dynamic-power-coefficient = <211>;
 			#cooling-cells = <2>;
 		};
@@ -129,7 +129,7 @@ cpu5: cpu@101 {
 			reg = <0x101>;
 			enable-method = "psci";
 			capacity-dmips-mhz = <1024>;
-			cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
+			cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP1>;
 			dynamic-power-coefficient = <211>;
 			#cooling-cells = <2>;
 		};
@@ -140,7 +140,7 @@ cpu6: cpu@102 {
 			reg = <0x102>;
 			enable-method = "psci";
 			capacity-dmips-mhz = <1024>;
-			cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
+			cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP1>;
 			dynamic-power-coefficient = <211>;
 			#cooling-cells = <2>;
 		};
@@ -151,7 +151,7 @@ cpu7: cpu@103 {
 			reg = <0x103>;
 			enable-method = "psci";
 			capacity-dmips-mhz = <1024>;
-			cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
+			cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP1>;
 			dynamic-power-coefficient = <211>;
 			#cooling-cells = <2>;
 		};
@@ -168,7 +168,15 @@ CPU_SLEEP: cpu-sleep {
 				min-residency-us = <800>;
 			};
 
-			CLUSTER_SLEEP: cluster-sleep {
+			CLUSTER_SLEEP0: cluster-sleep@0 {
+				compatible = "arm,idle-state";
+				local-timer-stop;
+				arm,psci-suspend-param = <0x01010001>;
+				entry-latency-us = <250>;
+				exit-latency-us = <400>;
+				min-residency-us = <1000>;
+			};
+			CLUSTER_SLEEP1: cluster-sleep@1 {
 				compatible = "arm,idle-state";
 				local-timer-stop;
 				arm,psci-suspend-param = <0x01010001>;
diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi
index 06aab44d798c..14982762088d 100644
--- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi
+++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi
@@ -51,6 +51,30 @@ chosen {
 		stdout-path = "serial0";
 	};
 
+	camera_vdddo_1v8: camera_vdddo_1v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "camera_vdddo";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		regulator-always-on;
+	};
+
+	camera_vdda_2v8: camera_vdda_2v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "camera_vdda";
+		regulator-min-microvolt = <2800000>;
+		regulator-max-microvolt = <2800000>;
+		regulator-always-on;
+	};
+
+	camera_vddd_1v5: camera_vddd_1v5 {
+		compatible = "regulator-fixed";
+		regulator-name = "camera_vddd";
+		regulator-min-microvolt = <1500000>;
+		regulator-max-microvolt = <1500000>;
+		regulator-always-on;
+	};
+
 	reserved-memory {
 		ramoops@bff00000{
 			compatible = "ramoops";
@@ -538,6 +562,58 @@ button@0 {
 	};
 };
 
+&camss {
+	status = "ok";
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		port@0 {
+			reg = <0>;
+			csiphy0_ep: endpoint {
+				clock-lanes = <1>;
+				data-lanes = <0 2>;
+				remote-endpoint = <&ov5640_ep>;
+				status = "okay";
+			};
+		};
+	};
+};
+
+&cci {
+	status = "ok";
+};
+
+&cci_i2c0 {
+	camera_rear@3b {
+		compatible = "ovti,ov5640";
+		reg = <0x3b>;
+
+		enable-gpios = <&msmgpio 34 GPIO_ACTIVE_HIGH>;
+		reset-gpios = <&msmgpio 35 GPIO_ACTIVE_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&camera_rear_default>;
+
+		clocks = <&gcc GCC_CAMSS_MCLK0_CLK>;
+		clock-names = "xclk";
+		clock-frequency = <23880000>;
+
+		vdddo-supply = <&camera_vdddo_1v8>;
+		vdda-supply = <&camera_vdda_2v8>;
+		vddd-supply = <&camera_vddd_1v5>;
+
+		/* No camera mezzanine by default */
+		status = "disabled";
+
+		port {
+			ov5640_ep: endpoint {
+				clock-lanes = <1>;
+				data-lanes = <0 2>;
+				remote-endpoint = <&csiphy0_ep>;
+			};
+		};
+	};
+};
+
 &spmi_bus {
 	pm8916_0: pm8916@0 {
 		pon@800 {
diff --git a/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts b/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts
index 70be3f95209b..6754cb0638f4 100644
--- a/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts
+++ b/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts
@@ -24,63 +24,61 @@ memory {
 		device_type = "memory";
 		reg = <0x0 0x40000000 0x0 0x20000000>;
 	};
+};
+
+&blsp1_i2c2 {
+	status = "ok";
+};
+
+&blsp1_spi1 {
+	status = "ok";
+
+	m25p80@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+	};
+};
+
+&blsp1_uart3 {
+	status = "ok";
+};
+
+&blsp1_uart5 {
+	status = "ok";
+};
+
+&pcie0 {
+	status = "ok";
+	perst-gpio = <&tlmm 61 0x1>;
+};
+
+&pcie1 {
+	status = "ok";
+	perst-gpio = <&tlmm 58 0x1>;
+};
+
+&pcie_phy0 {
+	status = "ok";
+};
+
+&pcie_phy1 {
+	status = "ok";
+};
+
+&qpic_bam {
+	status = "ok";
+};
+
+&qpic_nand {
+	status = "ok";
 
-	soc {
-		serial@78b3000 {
-			status = "ok";
-		};
-
-		spi@78b5000 {
-			status = "ok";
-
-			m25p80@0 {
-				  #address-cells = <1>;
-				  #size-cells = <1>;
-				  compatible = "jedec,spi-nor";
-				  reg = <0>;
-				  spi-max-frequency = <50000000>;
-			};
-		};
-
-		serial@78b1000 {
-			 status = "ok";
-		};
-
-		i2c@78b6000 {
-			 status = "ok";
-		};
-
-		dma@7984000 {
-			 status = "ok";
-		};
-
-		nand@79b0000 {
-			status = "ok";
-
-			nand@0 {
-				reg = <0>;
-				nand-ecc-strength = <4>;
-				nand-ecc-step-size = <512>;
-				nand-bus-width = <8>;
-			};
-		};
-
-		phy@86000 {
-			status = "ok";
-		};
-
-		phy@8e000 {
-			status = "ok";
-		};
-
-		pci@20000000 {
-			status = "ok";
-			perst-gpio = <&tlmm 58 0x1>;
-		};
-
-		pci@10000000 {
-			status = "ok";
-			perst-gpio = <&tlmm 61 0x1>;
-		};
+	nand@0 {
+		reg = <0>;
+		nand-ecc-strength = <4>;
+		nand-ecc-step-size = <512>;
+		nand-bus-width = <8>;
 	};
 };
diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
index 2b31823d3ccd..5303821300b4 100644
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
@@ -10,15 +10,111 @@ / {
 	model = "Qualcomm Technologies, Inc. IPQ8074";
 	compatible = "qcom,ipq8074";
 
+	clocks {
+		sleep_clk: sleep_clk {
+			compatible = "fixed-clock";
+			clock-frequency = <32000>;
+			#clock-cells = <0>;
+		};
+
+		xo: xo {
+			compatible = "fixed-clock";
+			clock-frequency = <19200000>;
+			#clock-cells = <0>;
+		};
+	};
+
+	cpus {
+		#address-cells = <0x1>;
+		#size-cells = <0x0>;
+
+		CPU0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			reg = <0x0>;
+			next-level-cache = <&L2_0>;
+			enable-method = "psci";
+		};
+
+		CPU1: cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			enable-method = "psci";
+			reg = <0x1>;
+			next-level-cache = <&L2_0>;
+		};
+
+		CPU2: cpu@2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			enable-method = "psci";
+			reg = <0x2>;
+			next-level-cache = <&L2_0>;
+		};
+
+		CPU3: cpu@3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			enable-method = "psci";
+			reg = <0x3>;
+			next-level-cache = <&L2_0>;
+		};
+
+		L2_0: l2-cache {
+			compatible = "cache";
+			cache-level = <0x2>;
+		};
+	};
+
+	pmu {
+		compatible = "arm,armv8-pmuv3";
+		interrupts = <GIC_PPI 7 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0";
+		method = "smc";
+	};
+
 	soc: soc {
 		#address-cells = <0x1>;
 		#size-cells = <0x1>;
 		ranges = <0 0 0 0xffffffff>;
 		compatible = "simple-bus";
 
+		pcie_phy0: phy@86000 {
+			compatible = "qcom,ipq8074-qmp-pcie-phy";
+			reg = <0x00086000 0x1000>;
+			#phy-cells = <0>;
+			clocks = <&gcc GCC_PCIE0_PIPE_CLK>;
+			clock-names = "pipe_clk";
+			clock-output-names = "pcie20_phy0_pipe_clk";
+
+			resets = <&gcc GCC_PCIE0_PHY_BCR>,
+				<&gcc GCC_PCIE0PHY_PHY_BCR>;
+			reset-names = "phy",
+				      "common";
+			status = "disabled";
+		};
+
+		pcie_phy1: phy@8e000 {
+			compatible = "qcom,ipq8074-qmp-pcie-phy";
+			reg = <0x0008e000 0x1000>;
+			#phy-cells = <0>;
+			clocks = <&gcc GCC_PCIE1_PIPE_CLK>;
+			clock-names = "pipe_clk";
+			clock-output-names = "pcie20_phy1_pipe_clk";
+
+			resets = <&gcc GCC_PCIE1_PHY_BCR>,
+				<&gcc GCC_PCIE1PHY_PHY_BCR>;
+			reset-names = "phy",
+				      "common";
+			status = "disabled";
+		};
+
 		tlmm: pinctrl@1000000 {
 			compatible = "qcom,ipq8074-pinctrl";
-			reg = <0x1000000 0x300000>;
+			reg = <0x01000000 0x300000>;
 			interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
 			gpio-controller;
 			gpio-ranges = <&tlmm 0 0 70>;
@@ -66,102 +162,16 @@ qpic_pins: qpic-pins {
 			};
 		};
 
-		intc: interrupt-controller@b000000 {
-			compatible = "qcom,msm-qgic2";
-			interrupt-controller;
-			#interrupt-cells = <0x3>;
-			reg = <0xb000000 0x1000>, <0xb002000 0x1000>;
-		};
-
-		timer {
-			compatible = "arm,armv8-timer";
-			interrupts = <GIC_PPI 2 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
-				     <GIC_PPI 3 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
-				     <GIC_PPI 4 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
-				     <GIC_PPI 1 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
-		};
-
-		timer@b120000 {
-			#address-cells = <1>;
-			#size-cells = <1>;
-			ranges;
-			compatible = "arm,armv7-timer-mem";
-			reg = <0xb120000 0x1000>;
-			clock-frequency = <19200000>;
-
-			frame@b120000 {
-				frame-number = <0>;
-				interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
-					     <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
-				reg = <0xb121000 0x1000>,
-				      <0xb122000 0x1000>;
-			};
-
-			frame@b123000 {
-				frame-number = <1>;
-				interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
-				reg = <0xb123000 0x1000>;
-				status = "disabled";
-			};
-
-			frame@b124000 {
-				frame-number = <2>;
-				interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
-				reg = <0xb124000 0x1000>;
-				status = "disabled";
-			};
-
-			frame@b125000 {
-				frame-number = <3>;
-				interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
-				reg = <0xb125000 0x1000>;
-				status = "disabled";
-			};
-
-			frame@b126000 {
-				frame-number = <4>;
-				interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
-				reg = <0xb126000 0x1000>;
-				status = "disabled";
-			};
-
-			frame@b127000 {
-				frame-number = <5>;
-				interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
-				reg = <0xb127000 0x1000>;
-				status = "disabled";
-			};
-
-			frame@b128000 {
-				frame-number = <6>;
-				interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
-				reg = <0xb128000 0x1000>;
-				status = "disabled";
-			};
-		};
-
 		gcc: gcc@1800000 {
 			compatible = "qcom,gcc-ipq8074";
-			reg = <0x1800000 0x80000>;
+			reg = <0x01800000 0x80000>;
 			#clock-cells = <0x1>;
 			#reset-cells = <0x1>;
 		};
 
-		blsp1_uart5: serial@78b3000 {
-			compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
-			reg = <0x78b3000 0x200>;
-			interrupts = <GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&gcc GCC_BLSP1_UART5_APPS_CLK>,
-				 <&gcc GCC_BLSP1_AHB_CLK>;
-			clock-names = "core", "iface";
-			pinctrl-0 = <&serial_4_pins>;
-			pinctrl-names = "default";
-			status = "disabled";
-		};
-
 		blsp_dma: dma@7884000 {
 			compatible = "qcom,bam-v1.7.0";
-			reg = <0x7884000 0x2b000>;
+			reg = <0x07884000 0x2b000>;
 			interrupts = <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&gcc GCC_BLSP1_AHB_CLK>;
 			clock-names = "bam_clk";
@@ -171,7 +181,7 @@ blsp_dma: dma@7884000 {
 
 		blsp1_uart1: serial@78af000 {
 			compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
-			reg = <0x78af000 0x200>;
+			reg = <0x078af000 0x200>;
 			interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&gcc GCC_BLSP1_UART1_APPS_CLK>,
 				 <&gcc GCC_BLSP1_AHB_CLK>;
@@ -181,7 +191,7 @@ blsp1_uart1: serial@78af000 {
 
 		blsp1_uart3: serial@78b1000 {
 			compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
-			reg = <0x78b1000 0x200>;
+			reg = <0x078b1000 0x200>;
 			interrupts = <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&gcc GCC_BLSP1_UART3_APPS_CLK>,
 				<&gcc GCC_BLSP1_AHB_CLK>;
@@ -194,11 +204,23 @@ blsp1_uart3: serial@78b1000 {
 			status = "disabled";
 		};
 
+		blsp1_uart5: serial@78b3000 {
+			compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+			reg = <0x078b3000 0x200>;
+			interrupts = <GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&gcc GCC_BLSP1_UART5_APPS_CLK>,
+				 <&gcc GCC_BLSP1_AHB_CLK>;
+			clock-names = "core", "iface";
+			pinctrl-0 = <&serial_4_pins>;
+			pinctrl-names = "default";
+			status = "disabled";
+		};
+
 		blsp1_spi1: spi@78b5000 {
 			compatible = "qcom,spi-qup-v2.2.1";
 			#address-cells = <1>;
 			#size-cells = <0>;
-			reg = <0x78b5000 0x600>;
+			reg = <0x078b5000 0x600>;
 			interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
 			spi-max-frequency = <50000000>;
 			clocks = <&gcc GCC_BLSP1_QUP1_SPI_APPS_CLK>,
@@ -215,7 +237,7 @@ blsp1_i2c2: i2c@78b6000 {
 			compatible = "qcom,i2c-qup-v2.2.1";
 			#address-cells = <1>;
 			#size-cells = <0>;
-			reg = <0x78b6000 0x600>;
+			reg = <0x078b6000 0x600>;
 			interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&gcc GCC_BLSP1_AHB_CLK>,
 				<&gcc GCC_BLSP1_QUP2_I2C_APPS_CLK>;
@@ -232,7 +254,7 @@ blsp1_i2c3: i2c@78b7000 {
 			compatible = "qcom,i2c-qup-v2.2.1";
 			#address-cells = <1>;
 			#size-cells = <0>;
-			reg = <0x78b7000 0x600>;
+			reg = <0x078b7000 0x600>;
 			interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&gcc GCC_BLSP1_AHB_CLK>,
 				<&gcc GCC_BLSP1_QUP3_I2C_APPS_CLK>;
@@ -245,7 +267,7 @@ blsp1_i2c3: i2c@78b7000 {
 
 		qpic_bam: dma@7984000 {
 			compatible = "qcom,bam-v1.7.0";
-			reg = <0x7984000 0x1a000>;
+			reg = <0x07984000 0x1a000>;
 			interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&gcc GCC_QPIC_AHB_CLK>;
 			clock-names = "bam_clk";
@@ -256,7 +278,7 @@ qpic_bam: dma@7984000 {
 
 		qpic_nand: nand@79b0000 {
 			compatible = "qcom,ipq8074-nand";
-			reg = <0x79b0000 0x10000>;
+			reg = <0x079b0000 0x10000>;
 			#address-cells = <1>;
 			#size-cells = <0>;
 			clocks = <&gcc GCC_QPIC_CLK>,
@@ -272,104 +294,85 @@ qpic_nand: nand@79b0000 {
 			status = "disabled";
 		};
 
-		pcie_phy0: phy@86000 {
-			compatible = "qcom,ipq8074-qmp-pcie-phy";
-			reg = <0x86000 0x1000>;
-			#phy-cells = <0>;
-			clocks = <&gcc GCC_PCIE0_PIPE_CLK>;
-			clock-names = "pipe_clk";
-			clock-output-names = "pcie20_phy0_pipe_clk";
+		intc: interrupt-controller@b000000 {
+			compatible = "qcom,msm-qgic2";
+			interrupt-controller;
+			#interrupt-cells = <0x3>;
+			reg = <0x0b000000 0x1000>, <0x0b002000 0x1000>;
+		};
 
-			resets = <&gcc GCC_PCIE0_PHY_BCR>,
-				<&gcc GCC_PCIE0PHY_PHY_BCR>;
-			reset-names = "phy",
-				      "common";
-			status = "disabled";
+		timer {
+			compatible = "arm,armv8-timer";
+			interrupts = <GIC_PPI 2 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+				     <GIC_PPI 3 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+				     <GIC_PPI 4 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+				     <GIC_PPI 1 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
 		};
 
-		pcie0: pci@20000000 {
-			compatible = "qcom,pcie-ipq8074";
-			reg =  <0x20000000 0xf1d
-				0x20000f20 0xa8
-				0x80000 0x2000
-				0x20100000 0x1000>;
-			reg-names = "dbi", "elbi", "parf", "config";
-			device_type = "pci";
-			linux,pci-domain = <0>;
-			bus-range = <0x00 0xff>;
-			num-lanes = <1>;
-			#address-cells = <3>;
-			#size-cells = <2>;
+		timer@b120000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+			compatible = "arm,armv7-timer-mem";
+			reg = <0x0b120000 0x1000>;
+			clock-frequency = <19200000>;
 
-			phys = <&pcie_phy0>;
-			phy-names = "pciephy";
+			frame@b120000 {
+				frame-number = <0>;
+				interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+				reg = <0x0b121000 0x1000>,
+				      <0x0b122000 0x1000>;
+			};
 
-			ranges = <0x81000000 0 0x20200000 0x20200000
-				  0 0x100000   /* downstream I/O */
-				  0x82000000 0 0x20300000 0x20300000
-				  0 0xd00000>; /* non-prefetchable memory */
+			frame@b123000 {
+				frame-number = <1>;
+				interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+				reg = <0x0b123000 0x1000>;
+				status = "disabled";
+			};
 
-			interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "msi";
-			#interrupt-cells = <1>;
-			interrupt-map-mask = <0 0 0 0x7>;
-			interrupt-map = <0 0 0 1 &intc 0 75
-					 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
-					<0 0 0 2 &intc 0 78
-					 IRQ_TYPE_LEVEL_HIGH>, /* int_b */
-					<0 0 0 3 &intc 0 79
-					 IRQ_TYPE_LEVEL_HIGH>, /* int_c */
-					<0 0 0 4 &intc 0 83
-					 IRQ_TYPE_LEVEL_HIGH>; /* int_d */
+			frame@b124000 {
+				frame-number = <2>;
+				interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+				reg = <0x0b124000 0x1000>;
+				status = "disabled";
+			};
 
-			clocks = <&gcc GCC_SYS_NOC_PCIE0_AXI_CLK>,
-				 <&gcc GCC_PCIE0_AXI_M_CLK>,
-				 <&gcc GCC_PCIE0_AXI_S_CLK>,
-				 <&gcc GCC_PCIE0_AHB_CLK>,
-				 <&gcc GCC_PCIE0_AUX_CLK>;
+			frame@b125000 {
+				frame-number = <3>;
+				interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+				reg = <0x0b125000 0x1000>;
+				status = "disabled";
+			};
 
-			clock-names = "iface",
-				      "axi_m",
-				      "axi_s",
-				      "ahb",
-				      "aux";
-			resets = <&gcc GCC_PCIE0_PIPE_ARES>,
-				 <&gcc GCC_PCIE0_SLEEP_ARES>,
-				 <&gcc GCC_PCIE0_CORE_STICKY_ARES>,
-				 <&gcc GCC_PCIE0_AXI_MASTER_ARES>,
-				 <&gcc GCC_PCIE0_AXI_SLAVE_ARES>,
-				 <&gcc GCC_PCIE0_AHB_ARES>,
-				 <&gcc GCC_PCIE0_AXI_MASTER_STICKY_ARES>;
-			reset-names = "pipe",
-				      "sleep",
-				      "sticky",
-				      "axi_m",
-				      "axi_s",
-				      "ahb",
-				      "axi_m_sticky";
-			status = "disabled";
-		};
+			frame@b126000 {
+				frame-number = <4>;
+				interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+				reg = <0x0b126000 0x1000>;
+				status = "disabled";
+			};
 
-		pcie_phy1: phy@8e000 {
-			compatible = "qcom,ipq8074-qmp-pcie-phy";
-			reg = <0x8e000 0x1000>;
-			#phy-cells = <0>;
-			clocks = <&gcc GCC_PCIE1_PIPE_CLK>;
-			clock-names = "pipe_clk";
-			clock-output-names = "pcie20_phy1_pipe_clk";
+			frame@b127000 {
+				frame-number = <5>;
+				interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+				reg = <0x0b127000 0x1000>;
+				status = "disabled";
+			};
 
-			resets = <&gcc GCC_PCIE1_PHY_BCR>,
-				<&gcc GCC_PCIE1PHY_PHY_BCR>;
-			reset-names = "phy",
-				      "common";
-			status = "disabled";
+			frame@b128000 {
+				frame-number = <6>;
+				interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+				reg = <0x0b128000 0x1000>;
+				status = "disabled";
+			};
 		};
 
 		pcie1: pci@10000000 {
 			compatible = "qcom,pcie-ipq8074";
 			reg =  <0x10000000 0xf1d
 				0x10000f20 0xa8
-				0x88000 0x2000
+				0x00088000 0x2000
 				0x10100000 0x1000>;
 			reg-names = "dbi", "elbi", "parf", "config";
 			device_type = "pci";
@@ -426,71 +429,68 @@ IRQ_TYPE_LEVEL_HIGH>, /* int_c */
 				      "axi_m_sticky";
 			status = "disabled";
 		};
-	};
-
-	cpus {
-		#address-cells = <0x1>;
-		#size-cells = <0x0>;
-
-		CPU0: cpu@0 {
-			device_type = "cpu";
-			compatible = "arm,cortex-a53";
-			reg = <0x0>;
-			next-level-cache = <&L2_0>;
-			enable-method = "psci";
-		};
-
-		CPU1: cpu@1 {
-			device_type = "cpu";
-			compatible = "arm,cortex-a53";
-			enable-method = "psci";
-			reg = <0x1>;
-			next-level-cache = <&L2_0>;
-		};
 
-		CPU2: cpu@2 {
-			device_type = "cpu";
-			compatible = "arm,cortex-a53";
-			enable-method = "psci";
-			reg = <0x2>;
-			next-level-cache = <&L2_0>;
-		};
-
-		CPU3: cpu@3 {
-			device_type = "cpu";
-			compatible = "arm,cortex-a53";
-			enable-method = "psci";
-			reg = <0x3>;
-			next-level-cache = <&L2_0>;
-		};
+		pcie0: pci@20000000 {
+			compatible = "qcom,pcie-ipq8074";
+			reg =  <0x20000000 0xf1d
+				0x20000f20 0xa8
+				0x00080000 0x2000
+				0x20100000 0x1000>;
+			reg-names = "dbi", "elbi", "parf", "config";
+			device_type = "pci";
+			linux,pci-domain = <0>;
+			bus-range = <0x00 0xff>;
+			num-lanes = <1>;
+			#address-cells = <3>;
+			#size-cells = <2>;
 
-		L2_0: l2-cache {
-			compatible = "cache";
-			cache-level = <0x2>;
-		};
-	};
+			phys = <&pcie_phy0>;
+			phy-names = "pciephy";
 
-	psci {
-		compatible = "arm,psci-1.0";
-		method = "smc";
-	};
+			ranges = <0x81000000 0 0x20200000 0x20200000
+				  0 0x100000   /* downstream I/O */
+				  0x82000000 0 0x20300000 0x20300000
+				  0 0xd00000>; /* non-prefetchable memory */
 
-	pmu {
-		compatible = "arm,armv8-pmuv3";
-		interrupts = <GIC_PPI 7 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
-	};
+			interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "msi";
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 0x7>;
+			interrupt-map = <0 0 0 1 &intc 0 75
+					 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
+					<0 0 0 2 &intc 0 78
+					 IRQ_TYPE_LEVEL_HIGH>, /* int_b */
+					<0 0 0 3 &intc 0 79
+					 IRQ_TYPE_LEVEL_HIGH>, /* int_c */
+					<0 0 0 4 &intc 0 83
+					 IRQ_TYPE_LEVEL_HIGH>; /* int_d */
 
-	clocks {
-		sleep_clk: sleep_clk {
-			compatible = "fixed-clock";
-			clock-frequency = <32000>;
-			#clock-cells = <0>;
-		};
+			clocks = <&gcc GCC_SYS_NOC_PCIE0_AXI_CLK>,
+				 <&gcc GCC_PCIE0_AXI_M_CLK>,
+				 <&gcc GCC_PCIE0_AXI_S_CLK>,
+				 <&gcc GCC_PCIE0_AHB_CLK>,
+				 <&gcc GCC_PCIE0_AUX_CLK>;
 
-		xo: xo {
-			compatible = "fixed-clock";
-			clock-frequency = <19200000>;
-			#clock-cells = <0>;
+			clock-names = "iface",
+				      "axi_m",
+				      "axi_s",
+				      "ahb",
+				      "aux";
+			resets = <&gcc GCC_PCIE0_PIPE_ARES>,
+				 <&gcc GCC_PCIE0_SLEEP_ARES>,
+				 <&gcc GCC_PCIE0_CORE_STICKY_ARES>,
+				 <&gcc GCC_PCIE0_AXI_MASTER_ARES>,
+				 <&gcc GCC_PCIE0_AXI_SLAVE_ARES>,
+				 <&gcc GCC_PCIE0_AHB_ARES>,
+				 <&gcc GCC_PCIE0_AXI_MASTER_STICKY_ARES>;
+			reset-names = "pipe",
+				      "sleep",
+				      "sticky",
+				      "axi_m",
+				      "axi_s",
+				      "ahb",
+				      "axi_m_sticky";
+			status = "disabled";
 		};
 	};
 };
diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi
index a88a15f2352b..569639fe8081 100644
--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
@@ -165,6 +165,9 @@ CPU_SLEEP_0: cpu-sleep-0 {
 				min-residency-us = <2000>;
 				local-timer-stop;
 			};
+		};
+
+		domain-idle-states {
 
 			CLUSTER_RET: cluster-retention {
 				compatible = "domain-idle-state";
@@ -188,31 +191,31 @@ psci {
 		compatible = "arm,psci-1.0";
 		method = "smc";
 
-		CPU_PD0: cpu-pd0 {
+		CPU_PD0: power-domain-cpu0 {
 			#power-domain-cells = <0>;
 			power-domains = <&CLUSTER_PD>;
 			domain-idle-states = <&CPU_SLEEP_0>;
 		};
 
-		CPU_PD1: cpu-pd1 {
+		CPU_PD1: power-domain-cpu1 {
 			#power-domain-cells = <0>;
 			power-domains = <&CLUSTER_PD>;
 			domain-idle-states = <&CPU_SLEEP_0>;
 		};
 
-		CPU_PD2: cpu-pd2 {
+		CPU_PD2: power-domain-cpu2 {
 			#power-domain-cells = <0>;
 			power-domains = <&CLUSTER_PD>;
 			domain-idle-states = <&CPU_SLEEP_0>;
 		};
 
-		CPU_PD3: cpu-pd3 {
+		CPU_PD3: power-domain-cpu3 {
 			#power-domain-cells = <0>;
 			power-domains = <&CLUSTER_PD>;
 			domain-idle-states = <&CPU_SLEEP_0>;
 		};
 
-		CLUSTER_PD: cluster-pd {
+		CLUSTER_PD: power-domain-cluster {
 			#power-domain-cells = <0>;
 			domain-idle-states = <&CLUSTER_RET>, <&CLUSTER_PWRDN>;
 		};
@@ -261,7 +264,7 @@ cpu2_3-thermal {
 			thermal-sensors = <&tsens 4>;
 
 			trips {
-				cpu2_3_alert0: trip-point@0 {
+				cpu2_3_alert0: trip-point0 {
 					temperature = <75000>;
 					hysteresis = <2000>;
 					type = "passive";
@@ -291,7 +294,7 @@ gpu-thermal {
 			thermal-sensors = <&tsens 2>;
 
 			trips {
-				gpu_alert0: trip-point@0 {
+				gpu_alert0: trip-point0 {
 					temperature = <75000>;
 					hysteresis = <2000>;
 					type = "passive";
@@ -311,7 +314,7 @@ camera-thermal {
 			thermal-sensors = <&tsens 1>;
 
 			trips {
-				cam_alert0: trip-point@0 {
+				cam_alert0: trip-point0 {
 					temperature = <75000>;
 					hysteresis = <2000>;
 					type = "hot";
@@ -326,7 +329,7 @@ modem-thermal {
 			thermal-sensors = <&tsens 0>;
 
 			trips {
-				modem_alert0: trip-point@0 {
+				modem_alert0: trip-point0 {
 					temperature = <85000>;
 					hysteresis = <2000>;
 					type = "hot";
@@ -1601,6 +1604,33 @@ ports {
 				#size-cells = <0>;
 			};
 		};
+
+		cci: cci@1b0c000 {
+			compatible = "qcom,msm8916-cci";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x1b0c000 0x1000>;
+			interrupts = <GIC_SPI 50 IRQ_TYPE_EDGE_RISING>;
+			clocks = <&gcc GCC_CAMSS_TOP_AHB_CLK>,
+				<&gcc GCC_CAMSS_CCI_AHB_CLK>,
+				<&gcc GCC_CAMSS_CCI_CLK>,
+				<&gcc GCC_CAMSS_AHB_CLK>;
+			clock-names = "camss_top_ahb", "cci_ahb",
+					  "cci", "camss_ahb";
+			assigned-clocks = <&gcc GCC_CAMSS_CCI_AHB_CLK>,
+					  <&gcc GCC_CAMSS_CCI_CLK>;
+			assigned-clock-rates = <80000000>, <19200000>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&cci0_default>;
+			status = "disabled";
+
+			cci_i2c0: i2c-bus@0 {
+				reg = <0>;
+				clock-frequency = <400000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+		};
 	};
 
 	smd {
diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
index 14827adebd94..895202d07a8b 100644
--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
@@ -2178,7 +2178,7 @@ cpu0-thermal {
 			thermal-sensors = <&tsens0 3>;
 
 			trips {
-				cpu0_alert0: trip-point@0 {
+				cpu0_alert0: trip-point0 {
 					temperature = <75000>;
 					hysteresis = <2000>;
 					type = "passive";
@@ -2199,7 +2199,7 @@ cpu1-thermal {
 			thermal-sensors = <&tsens0 5>;
 
 			trips {
-				cpu1_alert0: trip-point@0 {
+				cpu1_alert0: trip-point0 {
 					temperature = <75000>;
 					hysteresis = <2000>;
 					type = "passive";
@@ -2220,7 +2220,7 @@ cpu2-thermal {
 			thermal-sensors = <&tsens0 8>;
 
 			trips {
-				cpu2_alert0: trip-point@0 {
+				cpu2_alert0: trip-point0 {
 					temperature = <75000>;
 					hysteresis = <2000>;
 					type = "passive";
@@ -2241,7 +2241,7 @@ cpu3-thermal {
 			thermal-sensors = <&tsens0 10>;
 
 			trips {
-				cpu3_alert0: trip-point@0 {
+				cpu3_alert0: trip-point0 {
 					temperature = <75000>;
 					hysteresis = <2000>;
 					type = "passive";
@@ -2262,7 +2262,7 @@ gpu-thermal-top {
 			thermal-sensors = <&tsens1 6>;
 
 			trips {
-				gpu1_alert0: trip-point@0 {
+				gpu1_alert0: trip-point0 {
 					temperature = <90000>;
 					hysteresis = <2000>;
 					type = "hot";
@@ -2277,7 +2277,7 @@ gpu-thermal-bottom {
 			thermal-sensors = <&tsens1 7>;
 
 			trips {
-				gpu2_alert0: trip-point@0 {
+				gpu2_alert0: trip-point0 {
 					temperature = <90000>;
 					hysteresis = <2000>;
 					type = "hot";
@@ -2292,7 +2292,7 @@ m4m-thermal {
 			thermal-sensors = <&tsens0 1>;
 
 			trips {
-				m4m_alert0: trip-point@0 {
+				m4m_alert0: trip-point0 {
 					temperature = <90000>;
 					hysteresis = <2000>;
 					type = "hot";
@@ -2307,7 +2307,7 @@ l3-or-venus-thermal {
 			thermal-sensors = <&tsens0 2>;
 
 			trips {
-				l3_or_venus_alert0: trip-point@0 {
+				l3_or_venus_alert0: trip-point0 {
 					temperature = <90000>;
 					hysteresis = <2000>;
 					type = "hot";
@@ -2322,7 +2322,7 @@ cluster0-l2-thermal {
 			thermal-sensors = <&tsens0 7>;
 
 			trips {
-				cluster0_l2_alert0: trip-point@0 {
+				cluster0_l2_alert0: trip-point0 {
 					temperature = <90000>;
 					hysteresis = <2000>;
 					type = "hot";
@@ -2337,7 +2337,7 @@ cluster1-l2-thermal {
 			thermal-sensors = <&tsens0 12>;
 
 			trips {
-				cluster1_l2_alert0: trip-point@0 {
+				cluster1_l2_alert0: trip-point0 {
 					temperature = <90000>;
 					hysteresis = <2000>;
 					type = "hot";
@@ -2352,7 +2352,7 @@ camera-thermal {
 			thermal-sensors = <&tsens1 1>;
 
 			trips {
-				camera_alert0: trip-point@0 {
+				camera_alert0: trip-point0 {
 					temperature = <90000>;
 					hysteresis = <2000>;
 					type = "hot";
@@ -2367,7 +2367,7 @@ q6-dsp-thermal {
 			thermal-sensors = <&tsens1 2>;
 
 			trips {
-				q6_dsp_alert0: trip-point@0 {
+				q6_dsp_alert0: trip-point0 {
 					temperature = <90000>;
 					hysteresis = <2000>;
 					type = "hot";
@@ -2382,7 +2382,7 @@ mem-thermal {
 			thermal-sensors = <&tsens1 3>;
 
 			trips {
-				mem_alert0: trip-point@0 {
+				mem_alert0: trip-point0 {
 					temperature = <90000>;
 					hysteresis = <2000>;
 					type = "hot";
@@ -2397,7 +2397,7 @@ modemtx-thermal {
 			thermal-sensors = <&tsens1 4>;
 
 			trips {
-				modemtx_alert0: trip-point@0 {
+				modemtx_alert0: trip-point0 {
 					temperature = <90000>;
 					hysteresis = <2000>;
 					type = "hot";
diff --git a/arch/arm64/boot/dts/qcom/msm8998.dtsi b/arch/arm64/boot/dts/qcom/msm8998.dtsi
index c07fee6fd7eb..c45870600909 100644
--- a/arch/arm64/boot/dts/qcom/msm8998.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8998.dtsi
@@ -500,7 +500,7 @@ cpu0-thermal {
 			thermal-sensors = <&tsens0 1>;
 
 			trips {
-				cpu0_alert0: trip-point@0 {
+				cpu0_alert0: trip-point0 {
 					temperature = <75000>;
 					hysteresis = <2000>;
 					type = "passive";
@@ -521,7 +521,7 @@ cpu1-thermal {
 			thermal-sensors = <&tsens0 2>;
 
 			trips {
-				cpu1_alert0: trip-point@0 {
+				cpu1_alert0: trip-point0 {
 					temperature = <75000>;
 					hysteresis = <2000>;
 					type = "passive";
@@ -542,7 +542,7 @@ cpu2-thermal {
 			thermal-sensors = <&tsens0 3>;
 
 			trips {
-				cpu2_alert0: trip-point@0 {
+				cpu2_alert0: trip-point0 {
 					temperature = <75000>;
 					hysteresis = <2000>;
 					type = "passive";
@@ -563,7 +563,7 @@ cpu3-thermal {
 			thermal-sensors = <&tsens0 4>;
 
 			trips {
-				cpu3_alert0: trip-point@0 {
+				cpu3_alert0: trip-point0 {
 					temperature = <75000>;
 					hysteresis = <2000>;
 					type = "passive";
@@ -584,7 +584,7 @@ cpu4-thermal {
 			thermal-sensors = <&tsens0 7>;
 
 			trips {
-				cpu4_alert0: trip-point@0 {
+				cpu4_alert0: trip-point0 {
 					temperature = <75000>;
 					hysteresis = <2000>;
 					type = "passive";
@@ -605,7 +605,7 @@ cpu5-thermal {
 			thermal-sensors = <&tsens0 8>;
 
 			trips {
-				cpu5_alert0: trip-point@0 {
+				cpu5_alert0: trip-point0 {
 					temperature = <75000>;
 					hysteresis = <2000>;
 					type = "passive";
@@ -626,7 +626,7 @@ cpu6-thermal {
 			thermal-sensors = <&tsens0 9>;
 
 			trips {
-				cpu6_alert0: trip-point@0 {
+				cpu6_alert0: trip-point0 {
 					temperature = <75000>;
 					hysteresis = <2000>;
 					type = "passive";
@@ -647,7 +647,7 @@ cpu7-thermal {
 			thermal-sensors = <&tsens0 10>;
 
 			trips {
-				cpu7_alert0: trip-point@0 {
+				cpu7_alert0: trip-point0 {
 					temperature = <75000>;
 					hysteresis = <2000>;
 					type = "passive";
@@ -668,7 +668,7 @@ gpu-thermal-bottom {
 			thermal-sensors = <&tsens0 12>;
 
 			trips {
-				gpu1_alert0: trip-point@0 {
+				gpu1_alert0: trip-point0 {
 					temperature = <90000>;
 					hysteresis = <2000>;
 					type = "hot";
@@ -683,7 +683,7 @@ gpu-thermal-top {
 			thermal-sensors = <&tsens0 13>;
 
 			trips {
-				gpu2_alert0: trip-point@0 {
+				gpu2_alert0: trip-point0 {
 					temperature = <90000>;
 					hysteresis = <2000>;
 					type = "hot";
@@ -698,7 +698,7 @@ clust0-mhm-thermal {
 			thermal-sensors = <&tsens0 5>;
 
 			trips {
-				cluster0_mhm_alert0: trip-point@0 {
+				cluster0_mhm_alert0: trip-point0 {
 					temperature = <90000>;
 					hysteresis = <2000>;
 					type = "hot";
@@ -713,7 +713,7 @@ clust1-mhm-thermal {
 			thermal-sensors = <&tsens0 6>;
 
 			trips {
-				cluster1_mhm_alert0: trip-point@0 {
+				cluster1_mhm_alert0: trip-point0 {
 					temperature = <90000>;
 					hysteresis = <2000>;
 					type = "hot";
@@ -728,7 +728,7 @@ cluster1-l2-thermal {
 			thermal-sensors = <&tsens0 11>;
 
 			trips {
-				cluster1_l2_alert0: trip-point@0 {
+				cluster1_l2_alert0: trip-point0 {
 					temperature = <90000>;
 					hysteresis = <2000>;
 					type = "hot";
@@ -743,7 +743,7 @@ modem-thermal {
 			thermal-sensors = <&tsens1 1>;
 
 			trips {
-				modem_alert0: trip-point@0 {
+				modem_alert0: trip-point0 {
 					temperature = <90000>;
 					hysteresis = <2000>;
 					type = "hot";
@@ -758,7 +758,7 @@ mem-thermal {
 			thermal-sensors = <&tsens1 2>;
 
 			trips {
-				mem_alert0: trip-point@0 {
+				mem_alert0: trip-point0 {
 					temperature = <90000>;
 					hysteresis = <2000>;
 					type = "hot";
@@ -773,7 +773,7 @@ wlan-thermal {
 			thermal-sensors = <&tsens1 3>;
 
 			trips {
-				wlan_alert0: trip-point@0 {
+				wlan_alert0: trip-point0 {
 					temperature = <90000>;
 					hysteresis = <2000>;
 					type = "hot";
@@ -788,7 +788,7 @@ q6-dsp-thermal {
 			thermal-sensors = <&tsens1 4>;
 
 			trips {
-				q6_dsp_alert0: trip-point@0 {
+				q6_dsp_alert0: trip-point0 {
 					temperature = <90000>;
 					hysteresis = <2000>;
 					type = "hot";
@@ -803,7 +803,7 @@ camera-thermal {
 			thermal-sensors = <&tsens1 5>;
 
 			trips {
-				camera_alert0: trip-point@0 {
+				camera_alert0: trip-point0 {
 					temperature = <90000>;
 					hysteresis = <2000>;
 					type = "hot";
@@ -818,7 +818,7 @@ multimedia-thermal {
 			thermal-sensors = <&tsens1 6>;
 
 			trips {
-				multimedia_alert0: trip-point@0 {
+				multimedia_alert0: trip-point0 {
 					temperature = <90000>;
 					hysteresis = <2000>;
 					type = "hot";
diff --git a/arch/arm64/boot/dts/qcom/qcs404-evb.dtsi b/arch/arm64/boot/dts/qcom/qcs404-evb.dtsi
index afe69e8f3114..6422cf9d5855 100644
--- a/arch/arm64/boot/dts/qcom/qcs404-evb.dtsi
+++ b/arch/arm64/boot/dts/qcom/qcs404-evb.dtsi
@@ -4,6 +4,8 @@
 #include <dt-bindings/gpio/gpio.h>
 #include "qcs404.dtsi"
 #include "pms405.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
 
 / {
 	aliases {
@@ -31,6 +33,21 @@ vdd_esmps3_3p3: vdd-esmps3-3p3-regulator {
 		regulator-max-microvolt = <3300000>;
 		regulator-always-on;
 	};
+
+	usb3_vbus_reg: regulator-usb3-vbus {
+		compatible = "regulator-fixed";
+		regulator-name = "VBUS_BOOST_5V";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		gpio = <&pms405_gpios 3 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&usb_vbus_boost_pin>;
+		vin-supply = <&vph_pwr>;
+		enable-active-high;
+
+		/* TODO: Drop this when introducing role switching */
+		regulator-always-on;
+	};
 };
 
 &blsp1_uart3 {
@@ -186,7 +203,7 @@ vreg_l11_sdc2: l11 {
 		};
 
 		vreg_l12_3p3: l12 {
-			regulator-min-microvolt = <2968000>;
+			regulator-min-microvolt = <3050000>;
 			regulator-max-microvolt = <3300000>;
 		};
 
@@ -270,6 +287,72 @@ rclk {
 			bias-pull-down;
 		};
 	};
+
+	usb3_id_pin: usb3-id-pin {
+		pinmux {
+			pins = "gpio116";
+			function = "gpio";
+		};
+
+		pinconf {
+			pins = "gpio116";
+			drive-strength = <2>;
+			bias-pull-up;
+			input-enable;
+		};
+	};
+};
+
+&pms405_gpios {
+	usb_vbus_boost_pin: usb-vbus-boost-pin {
+		pinconf {
+			pins = "gpio3";
+			function = PMIC_GPIO_FUNC_NORMAL;
+			output-low;
+			power-source = <1>;
+		};
+	};
+	usb3_vbus_pin: usb3-vbus-pin {
+		pinconf {
+			pins = "gpio12";
+			function = PMIC_GPIO_FUNC_NORMAL;
+			input-enable;
+			bias-pull-down;
+			power-source = <1>;
+		};
+	};
+};
+
+&usb2 {
+	status = "okay";
+};
+
+&usb2_phy_sec {
+	vdd-supply = <&vreg_l4_1p2>;
+	vdda1p8-supply = <&vreg_l5_1p8>;
+	vdda3p3-supply = <&vreg_l12_3p3>;
+	status = "okay";
+};
+
+&usb3 {
+	status = "okay";
+
+	dwc3@7580000 {
+		dr_mode = "host";
+	};
+};
+
+&usb2_phy_prim {
+	vdd-supply = <&vreg_l4_1p2>;
+	vdda1p8-supply = <&vreg_l5_1p8>;
+	vdda3p3-supply = <&vreg_l12_3p3>;
+	status = "okay";
+};
+
+&usb3_phy {
+	vdd-supply = <&vreg_l3_1p05>;
+	vdda1p8-supply = <&vreg_l5_1p8>;
+	status = "okay";
 };
 
 &wifi {
diff --git a/arch/arm64/boot/dts/qcom/qcs404.dtsi b/arch/arm64/boot/dts/qcom/qcs404.dtsi
index f149a538c1cc..c685a1664810 100644
--- a/arch/arm64/boot/dts/qcom/qcs404.dtsi
+++ b/arch/arm64/boot/dts/qcom/qcs404.dtsi
@@ -323,6 +323,48 @@ rpm_msg_ram: memory@60000 {
 			reg = <0x00060000 0x6000>;
 		};
 
+		usb3_phy: phy@78000 {
+			compatible = "qcom,usb-ss-28nm-phy";
+			reg = <0x00078000 0x400>;
+			#phy-cells = <0>;
+			clocks = <&rpmcc RPM_SMD_LN_BB_CLK>,
+				 <&gcc GCC_USB_HS_PHY_CFG_AHB_CLK>,
+				 <&gcc GCC_USB3_PHY_PIPE_CLK>;
+			clock-names = "ref", "ahb", "pipe";
+			resets = <&gcc GCC_USB3_PHY_BCR>,
+				 <&gcc GCC_USB3PHY_PHY_BCR>;
+			reset-names = "com", "phy";
+			status = "disabled";
+		};
+
+		usb2_phy_prim: phy@7a000 {
+			compatible = "qcom,usb-hs-28nm-femtophy";
+			reg = <0x0007a000 0x200>;
+			#phy-cells = <0>;
+			clocks = <&rpmcc RPM_SMD_LN_BB_CLK>,
+				 <&gcc GCC_USB_HS_PHY_CFG_AHB_CLK>,
+				 <&gcc GCC_USB2A_PHY_SLEEP_CLK>;
+			clock-names = "ref", "ahb", "sleep";
+			resets = <&gcc GCC_USB_HS_PHY_CFG_AHB_BCR>,
+				 <&gcc GCC_USB2A_PHY_BCR>;
+			reset-names = "phy", "por";
+			status = "disabled";
+		};
+
+		usb2_phy_sec: phy@7c000 {
+			compatible = "qcom,usb-hs-28nm-femtophy";
+			reg = <0x0007c000 0x200>;
+			#phy-cells = <0>;
+			clocks = <&rpmcc RPM_SMD_LN_BB_CLK>,
+				 <&gcc GCC_USB_HS_PHY_CFG_AHB_CLK>,
+				 <&gcc GCC_USB2A_PHY_SLEEP_CLK>;
+			clock-names = "ref", "ahb", "sleep";
+			resets = <&gcc GCC_QUSB2_PHY_BCR>,
+				 <&gcc GCC_USB2_HS_PHY_ONLY_BCR>;
+			reset-names = "phy", "por";
+			status = "disabled";
+		};
+
 		qfprom: qfprom@a4000 {
 			compatible = "qcom,qfprom";
 			reg = <0x000a4000 0x1000>;
@@ -486,6 +528,64 @@ glink-edge {
 			};
 		};
 
+		usb3: usb@7678800 {
+			compatible = "qcom,dwc3";
+			reg = <0x07678800 0x400>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+			clocks = <&gcc GCC_USB30_MASTER_CLK>,
+				 <&gcc GCC_SYS_NOC_USB3_CLK>,
+				 <&gcc GCC_USB30_SLEEP_CLK>,
+				 <&gcc GCC_USB30_MOCK_UTMI_CLK>;
+			clock-names = "core", "iface", "sleep", "mock_utmi";
+			assigned-clocks = <&gcc GCC_USB20_MOCK_UTMI_CLK>,
+					  <&gcc GCC_USB30_MASTER_CLK>;
+			assigned-clock-rates = <19200000>, <200000000>;
+			status = "disabled";
+
+			dwc3@7580000 {
+				compatible = "snps,dwc3";
+				reg = <0x07580000 0xcd00>;
+				interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+				phys = <&usb2_phy_sec>, <&usb3_phy>;
+				phy-names = "usb2-phy", "usb3-phy";
+				snps,has-lpm-erratum;
+				snps,hird-threshold = /bits/ 8 <0x10>;
+				snps,usb3_lpm_capable;
+				dr_mode = "otg";
+			};
+		};
+
+		usb2: usb@79b8800 {
+			compatible = "qcom,dwc3";
+			reg = <0x079b8800 0x400>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+			clocks = <&gcc GCC_USB_HS_SYSTEM_CLK>,
+				 <&gcc GCC_PCNOC_USB2_CLK>,
+				 <&gcc GCC_USB_HS_INACTIVITY_TIMERS_CLK>,
+				 <&gcc GCC_USB20_MOCK_UTMI_CLK>;
+			clock-names = "core", "iface", "sleep", "mock_utmi";
+			assigned-clocks = <&gcc GCC_USB20_MOCK_UTMI_CLK>,
+					  <&gcc GCC_USB_HS_SYSTEM_CLK>;
+			assigned-clock-rates = <19200000>, <133333333>;
+			status = "disabled";
+
+			dwc3@78c0000 {
+				compatible = "snps,dwc3";
+				reg = <0x078c0000 0xcc00>;
+				interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+				phys = <&usb2_phy_prim>;
+				phy-names = "usb2-phy";
+				snps,has-lpm-erratum;
+				snps,hird-threshold = /bits/ 8 <0x10>;
+				snps,usb3_lpm_capable;
+				dr_mode = "peripheral";
+			};
+		};
+
 		tlmm: pinctrl@1000000 {
 			compatible = "qcom,qcs404-pinctrl";
 			reg = <0x01000000 0x200000>,
diff --git a/arch/arm64/boot/dts/qcom/sc7180-idp.dts b/arch/arm64/boot/dts/qcom/sc7180-idp.dts
index 043c9b9b5024..4dd8ebc22448 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-idp.dts
+++ b/arch/arm64/boot/dts/qcom/sc7180-idp.dts
@@ -310,9 +310,11 @@ &usb_1_hsphy {
 	vdda-pll-supply = <&vreg_l11a_1p8>;
 	vdda-phy-dpdm-supply = <&vreg_l17a_3p0>;
 	qcom,imp-res-offset-value = <8>;
-	qcom,hstx-trim-value = <QUSB2_V2_HSTX_TRIM_21_6_MA>;
-	qcom,preemphasis-level = <QUSB2_V2_PREEMPHASIS_5_PERCENT>;
+	qcom,preemphasis-level = <QUSB2_V2_PREEMPHASIS_15_PERCENT>;
 	qcom,preemphasis-width = <QUSB2_V2_PREEMPHASIS_WIDTH_HALF_BIT>;
+	qcom,bias-ctrl-value = <0x22>;
+	qcom,charge-ctrl-value = <3>;
+	qcom,hsdisc-trim-value = <0>;
 };
 
 &usb_1_qmpphy {
diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi
index 998f101ad623..ea1cb142cfe5 100644
--- a/arch/arm64/boot/dts/qcom/sc7180.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi
@@ -10,6 +10,7 @@
 #include <dt-bindings/clock/qcom,gpucc-sc7180.h>
 #include <dt-bindings/clock/qcom,rpmh.h>
 #include <dt-bindings/clock/qcom,videocc-sc7180.h>
+#include <dt-bindings/interconnect/qcom,sc7180.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/phy/phy-qcom-qusb2.h>
 #include <dt-bindings/power/qcom-aoss-qmp.h>
@@ -91,9 +92,12 @@ cpus {
 
 		CPU0: cpu@0 {
 			device_type = "cpu";
-			compatible = "arm,armv8";
+			compatible = "qcom,kryo468";
 			reg = <0x0 0x0>;
 			enable-method = "psci";
+			cpu-idle-states = <&LITTLE_CPU_SLEEP_0
+					   &LITTLE_CPU_SLEEP_1
+					   &CLUSTER_SLEEP_0>;
 			capacity-dmips-mhz = <1024>;
 			dynamic-power-coefficient = <100>;
 			next-level-cache = <&L2_0>;
@@ -110,9 +114,12 @@ L3_0: l3-cache {
 
 		CPU1: cpu@100 {
 			device_type = "cpu";
-			compatible = "arm,armv8";
+			compatible = "qcom,kryo468";
 			reg = <0x0 0x100>;
 			enable-method = "psci";
+			cpu-idle-states = <&LITTLE_CPU_SLEEP_0
+					   &LITTLE_CPU_SLEEP_1
+					   &CLUSTER_SLEEP_0>;
 			capacity-dmips-mhz = <1024>;
 			dynamic-power-coefficient = <100>;
 			next-level-cache = <&L2_100>;
@@ -126,9 +133,12 @@ L2_100: l2-cache {
 
 		CPU2: cpu@200 {
 			device_type = "cpu";
-			compatible = "arm,armv8";
+			compatible = "qcom,kryo468";
 			reg = <0x0 0x200>;
 			enable-method = "psci";
+			cpu-idle-states = <&LITTLE_CPU_SLEEP_0
+					   &LITTLE_CPU_SLEEP_1
+					   &CLUSTER_SLEEP_0>;
 			capacity-dmips-mhz = <1024>;
 			dynamic-power-coefficient = <100>;
 			next-level-cache = <&L2_200>;
@@ -142,9 +152,12 @@ L2_200: l2-cache {
 
 		CPU3: cpu@300 {
 			device_type = "cpu";
-			compatible = "arm,armv8";
+			compatible = "qcom,kryo468";
 			reg = <0x0 0x300>;
 			enable-method = "psci";
+			cpu-idle-states = <&LITTLE_CPU_SLEEP_0
+					   &LITTLE_CPU_SLEEP_1
+					   &CLUSTER_SLEEP_0>;
 			capacity-dmips-mhz = <1024>;
 			dynamic-power-coefficient = <100>;
 			next-level-cache = <&L2_300>;
@@ -158,9 +171,12 @@ L2_300: l2-cache {
 
 		CPU4: cpu@400 {
 			device_type = "cpu";
-			compatible = "arm,armv8";
+			compatible = "qcom,kryo468";
 			reg = <0x0 0x400>;
 			enable-method = "psci";
+			cpu-idle-states = <&LITTLE_CPU_SLEEP_0
+					   &LITTLE_CPU_SLEEP_1
+					   &CLUSTER_SLEEP_0>;
 			capacity-dmips-mhz = <1024>;
 			dynamic-power-coefficient = <100>;
 			next-level-cache = <&L2_400>;
@@ -174,9 +190,12 @@ L2_400: l2-cache {
 
 		CPU5: cpu@500 {
 			device_type = "cpu";
-			compatible = "arm,armv8";
+			compatible = "qcom,kryo468";
 			reg = <0x0 0x500>;
 			enable-method = "psci";
+			cpu-idle-states = <&LITTLE_CPU_SLEEP_0
+					   &LITTLE_CPU_SLEEP_1
+					   &CLUSTER_SLEEP_0>;
 			capacity-dmips-mhz = <1024>;
 			dynamic-power-coefficient = <100>;
 			next-level-cache = <&L2_500>;
@@ -190,9 +209,12 @@ L2_500: l2-cache {
 
 		CPU6: cpu@600 {
 			device_type = "cpu";
-			compatible = "arm,armv8";
+			compatible = "qcom,kryo468";
 			reg = <0x0 0x600>;
 			enable-method = "psci";
+			cpu-idle-states = <&BIG_CPU_SLEEP_0
+					   &BIG_CPU_SLEEP_1
+					   &CLUSTER_SLEEP_0>;
 			capacity-dmips-mhz = <1740>;
 			dynamic-power-coefficient = <405>;
 			next-level-cache = <&L2_600>;
@@ -206,9 +228,12 @@ L2_600: l2-cache {
 
 		CPU7: cpu@700 {
 			device_type = "cpu";
-			compatible = "arm,armv8";
+			compatible = "qcom,kryo468";
 			reg = <0x0 0x700>;
 			enable-method = "psci";
+			cpu-idle-states = <&BIG_CPU_SLEEP_0
+					   &BIG_CPU_SLEEP_1
+					   &CLUSTER_SLEEP_0>;
 			capacity-dmips-mhz = <1740>;
 			dynamic-power-coefficient = <405>;
 			next-level-cache = <&L2_700>;
@@ -255,6 +280,60 @@ core7 {
 				};
 			};
 		};
+
+		idle-states {
+			entry-method = "psci";
+
+			LITTLE_CPU_SLEEP_0: cpu-sleep-0-0 {
+				compatible = "arm,idle-state";
+				idle-state-name = "little-power-down";
+				arm,psci-suspend-param = <0x40000003>;
+				entry-latency-us = <549>;
+				exit-latency-us = <901>;
+				min-residency-us = <1774>;
+				local-timer-stop;
+			};
+
+			LITTLE_CPU_SLEEP_1: cpu-sleep-0-1 {
+				compatible = "arm,idle-state";
+				idle-state-name = "little-rail-power-down";
+				arm,psci-suspend-param = <0x40000004>;
+				entry-latency-us = <702>;
+				exit-latency-us = <915>;
+				min-residency-us = <4001>;
+				local-timer-stop;
+			};
+
+			BIG_CPU_SLEEP_0: cpu-sleep-1-0 {
+				compatible = "arm,idle-state";
+				idle-state-name = "big-power-down";
+				arm,psci-suspend-param = <0x40000003>;
+				entry-latency-us = <523>;
+				exit-latency-us = <1244>;
+				min-residency-us = <2207>;
+				local-timer-stop;
+			};
+
+			BIG_CPU_SLEEP_1: cpu-sleep-1-1 {
+				compatible = "arm,idle-state";
+				idle-state-name = "big-rail-power-down";
+				arm,psci-suspend-param = <0x40000004>;
+				entry-latency-us = <526>;
+				exit-latency-us = <1854>;
+				min-residency-us = <5555>;
+				local-timer-stop;
+			};
+
+			CLUSTER_SLEEP_0: cluster-sleep-0 {
+				compatible = "arm,idle-state";
+				idle-state-name = "cluster-power-down";
+				arm,psci-suspend-param = <0x40003444>;
+				entry-latency-us = <3263>;
+				exit-latency-us = <6562>;
+				min-residency-us = <9926>;
+				local-timer-stop;
+			};
+		};
 	};
 
 	memory@80000000 {
@@ -1294,6 +1373,20 @@ pinconf-sd-cd {
 			};
 		};
 
+		gpucc: clock-controller@5090000 {
+			compatible = "qcom,sc7180-gpucc";
+			reg = <0 0x05090000 0 0x9000>;
+			clocks = <&rpmhcc RPMH_CXO_CLK>,
+				 <&gcc GCC_GPU_GPLL0_CLK_SRC>,
+				 <&gcc GCC_GPU_GPLL0_DIV_CLK_SRC>;
+			clock-names = "bi_tcxo",
+				      "gcc_gpu_gpll0_clk_src",
+				      "gcc_gpu_gpll0_div_clk_src";
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+			#power-domain-cells = <1>;
+		};
+
 		sdhc_2: sdhci@8804000 {
 			compatible = "qcom,sc7180-sdhci", "qcom,sdhci-msm-v5";
 			reg = <0 0x08804000 0 0x1000>;
@@ -1312,20 +1405,6 @@ sdhc_2: sdhci@8804000 {
 			status = "disabled";
 		};
 
-		gpucc: clock-controller@5090000 {
-			compatible = "qcom,sc7180-gpucc";
-			reg = <0 0x05090000 0 0x9000>;
-			clocks = <&rpmhcc RPMH_CXO_CLK>,
-				 <&gcc GCC_GPU_GPLL0_CLK_SRC>,
-				 <&gcc GCC_GPU_GPLL0_DIV_CLK_SRC>;
-			clock-names = "bi_tcxo",
-				      "gcc_gpu_gpll0_clk_src",
-				      "gcc_gpu_gpll0_div_clk_src";
-			#clock-cells = <1>;
-			#reset-cells = <1>;
-			#power-domain-cells = <1>;
-		};
-
 		qspi: spi@88dc000 {
 			compatible = "qcom,qspi-v1";
 			reg = <0 0x088dc000 0 0x600>;
@@ -1339,7 +1418,7 @@ qspi: spi@88dc000 {
 		};
 
 		usb_1_hsphy: phy@88e3000 {
-			compatible = "qcom,sc7180-qusb2-phy";
+			compatible = "qcom,sc7180-qusb2-phy", "qcom,qusb2-v2-phy";
 			reg = <0 0x088e3000 0 0x400>;
 			status = "disabled";
 			#phy-cells = <0>;
@@ -1475,6 +1554,9 @@ venus: video-codec@aa00000 {
 				      "vcodec0_core", "vcodec0_bus";
 			iommus = <&apps_smmu 0x0c00 0x60>;
 			memory-region = <&venus_mem>;
+			interconnects = <&mmss_noc MASTER_VIDEO_P0 &mc_virt SLAVE_EBI1>,
+					<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_VENUS_CFG>;
+			interconnect-names = "video-mem", "cpu-cfg";
 
 			video-decoder {
 				compatible = "venus-decoder";
@@ -1544,8 +1626,12 @@ mdp: mdp@ae01000 {
 				clock-names = "iface", "rot", "lut", "core",
 					      "vsync";
 				assigned-clocks = <&dispcc DISP_CC_MDSS_MDP_CLK>,
-						  <&dispcc DISP_CC_MDSS_VSYNC_CLK>;
+						  <&dispcc DISP_CC_MDSS_VSYNC_CLK>,
+						  <&dispcc DISP_CC_MDSS_ROT_CLK>,
+						  <&dispcc DISP_CC_MDSS_AHB_CLK>;
 				assigned-clock-rates = <300000000>,
+						       <19200000>,
+						       <19200000>,
 						       <19200000>;
 
 				interrupt-parent = <&mdss>;
@@ -2011,8 +2097,8 @@ cpufreq_hw: cpufreq@18323000 {
 
 	thermal-zones {
 		cpu0-thermal {
-			polling-delay-passive = <250>;
-			polling-delay = <1000>;
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
 
 			thermal-sensors = <&tsens0 1>;
 
@@ -2059,8 +2145,8 @@ map1 {
 		};
 
 		cpu1-thermal {
-			polling-delay-passive = <250>;
-			polling-delay = <1000>;
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
 
 			thermal-sensors = <&tsens0 2>;
 
@@ -2107,8 +2193,8 @@ map1 {
 		};
 
 		cpu2-thermal {
-			polling-delay-passive = <250>;
-			polling-delay = <1000>;
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
 
 			thermal-sensors = <&tsens0 3>;
 
@@ -2155,8 +2241,8 @@ map1 {
 		};
 
 		cpu3-thermal {
-			polling-delay-passive = <250>;
-			polling-delay = <1000>;
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
 
 			thermal-sensors = <&tsens0 4>;
 
@@ -2203,8 +2289,8 @@ map1 {
 		};
 
 		cpu4-thermal {
-			polling-delay-passive = <250>;
-			polling-delay = <1000>;
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
 
 			thermal-sensors = <&tsens0 5>;
 
@@ -2251,8 +2337,8 @@ map1 {
 		};
 
 		cpu5-thermal {
-			polling-delay-passive = <250>;
-			polling-delay = <1000>;
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
 
 			thermal-sensors = <&tsens0 6>;
 
@@ -2299,8 +2385,8 @@ map1 {
 		};
 
 		cpu6-thermal {
-			polling-delay-passive = <250>;
-			polling-delay = <1000>;
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
 
 			thermal-sensors = <&tsens0 9>;
 
@@ -2339,8 +2425,8 @@ map1 {
 		};
 
 		cpu7-thermal {
-			polling-delay-passive = <250>;
-			polling-delay = <1000>;
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
 
 			thermal-sensors = <&tsens0 10>;
 
@@ -2379,8 +2465,8 @@ map1 {
 		};
 
 		cpu8-thermal {
-			polling-delay-passive = <250>;
-			polling-delay = <1000>;
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
 
 			thermal-sensors = <&tsens0 11>;
 
@@ -2419,8 +2505,8 @@ map1 {
 		};
 
 		cpu9-thermal {
-			polling-delay-passive = <250>;
-			polling-delay = <1000>;
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
 
 			thermal-sensors = <&tsens0 12>;
 
@@ -2459,8 +2545,8 @@ map1 {
 		};
 
 		aoss0-thermal {
-			polling-delay-passive = <250>;
-			polling-delay = <1000>;
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
 
 			thermal-sensors = <&tsens0 0>;
 
@@ -2480,8 +2566,8 @@ aoss0_crit: aoss0_crit {
 		};
 
 		cpuss0-thermal {
-			polling-delay-passive = <250>;
-			polling-delay = <1000>;
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
 
 			thermal-sensors = <&tsens0 7>;
 
@@ -2500,8 +2586,8 @@ cpuss0_crit: cluster0_crit {
 		};
 
 		cpuss1-thermal {
-			polling-delay-passive = <250>;
-			polling-delay = <1000>;
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
 
 			thermal-sensors = <&tsens0 8>;
 
@@ -2520,8 +2606,8 @@ cpuss1_crit: cluster0_crit {
 		};
 
 		gpuss0-thermal {
-			polling-delay-passive = <250>;
-			polling-delay = <1000>;
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
 
 			thermal-sensors = <&tsens0 13>;
 
@@ -2541,8 +2627,8 @@ gpuss0_crit: gpuss0_crit {
 		};
 
 		gpuss1-thermal {
-			polling-delay-passive = <250>;
-			polling-delay = <1000>;
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
 
 			thermal-sensors = <&tsens0 14>;
 
@@ -2562,8 +2648,8 @@ gpuss1_crit: gpuss1_crit {
 		};
 
 		aoss1-thermal {
-			polling-delay-passive = <250>;
-			polling-delay = <1000>;
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
 
 			thermal-sensors = <&tsens1 0>;
 
@@ -2583,8 +2669,8 @@ aoss1_crit: aoss1_crit {
 		};
 
 		cwlan-thermal {
-			polling-delay-passive = <250>;
-			polling-delay = <1000>;
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
 
 			thermal-sensors = <&tsens1 1>;
 
@@ -2604,8 +2690,8 @@ cwlan_crit: cwlan_crit {
 		};
 
 		audio-thermal {
-			polling-delay-passive = <250>;
-			polling-delay = <1000>;
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
 
 			thermal-sensors = <&tsens1 2>;
 
@@ -2625,8 +2711,8 @@ audio_crit: audio_crit {
 		};
 
 		ddr-thermal {
-			polling-delay-passive = <250>;
-			polling-delay = <1000>;
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
 
 			thermal-sensors = <&tsens1 3>;
 
@@ -2646,8 +2732,8 @@ ddr_crit: ddr_crit {
 		};
 
 		q6-hvx-thermal {
-			polling-delay-passive = <250>;
-			polling-delay = <1000>;
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
 
 			thermal-sensors = <&tsens1 4>;
 
@@ -2667,8 +2753,8 @@ q6_hvx_crit: q6_hvx_crit {
 		};
 
 		camera-thermal {
-			polling-delay-passive = <250>;
-			polling-delay = <1000>;
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
 
 			thermal-sensors = <&tsens1 5>;
 
@@ -2688,8 +2774,8 @@ camera_crit: camera_crit {
 		};
 
 		mdm-core-thermal {
-			polling-delay-passive = <250>;
-			polling-delay = <1000>;
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
 
 			thermal-sensors = <&tsens1 6>;
 
@@ -2709,8 +2795,8 @@ mdm_crit: mdm_crit {
 		};
 
 		mdm-dsp-thermal {
-			polling-delay-passive = <250>;
-			polling-delay = <1000>;
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
 
 			thermal-sensors = <&tsens1 7>;
 
@@ -2730,8 +2816,8 @@ mdm_dsp_crit: mdm_dsp_crit {
 		};
 
 		npu-thermal {
-			polling-delay-passive = <250>;
-			polling-delay = <1000>;
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
 
 			thermal-sensors = <&tsens1 8>;
 
@@ -2751,8 +2837,8 @@ npu_crit: npu_crit {
 		};
 
 		video-thermal {
-			polling-delay-passive = <250>;
-			polling-delay = <1000>;
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
 
 			thermal-sensors = <&tsens1 9>;
 
diff --git a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
index a2e05926b429..6072ca38cef7 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
@@ -112,6 +112,40 @@ pcie0_1p05v: pcie-0-1p05v-regulator {
 		// enable-active-high;
 	};
 
+	cam0_dvdd_1v2: reg_cam0_dvdd_1v2 {
+		compatible = "regulator-fixed";
+		regulator-name = "CAM0_DVDD_1V2";
+		regulator-min-microvolt = <1200000>;
+		regulator-max-microvolt = <1200000>;
+		enable-active-high;
+		gpio = <&pm8998_gpio 12 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&cam0_dvdd_1v2_en_default>;
+		vin-supply = <&vbat>;
+	};
+
+	cam0_avdd_2v8: reg_cam0_avdd_2v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "CAM0_AVDD_2V8";
+		regulator-min-microvolt = <2800000>;
+		regulator-max-microvolt = <2800000>;
+		enable-active-high;
+		gpio = <&pm8998_gpio 10 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&cam0_avdd_2v8_en_default>;
+		vin-supply = <&vbat>;
+	};
+
+	/* This regulator is enabled when the VREG_LVS1A_1P8 trace is enabled */
+	cam3_avdd_2v8: reg_cam3_avdd_2v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "CAM3_AVDD_2V8";
+		regulator-min-microvolt = <2800000>;
+		regulator-max-microvolt = <2800000>;
+		regulator-always-on;
+		vin-supply = <&vbat>;
+	};
+
 	pcie0_3p3v_dual: vldo-3v3-regulator {
 		compatible = "regulator-fixed";
 		regulator-name = "VLDO_3V3";
@@ -412,6 +446,52 @@ &pcie1_phy {
 };
 
 &pm8998_gpio {
+	gpio-line-names =
+		"NC",
+		"NC",
+		"WLAN_SW_CTRL",
+		"NC",
+		"PM_GPIO5_BLUE_BT_LED",
+		"VOL_UP_N",
+		"NC",
+		"ADC_IN1",
+		"PM_GPIO9_YEL_WIFI_LED",
+		"CAM0_AVDD_EN",
+		"NC",
+		"CAM0_DVDD_EN",
+		"PM_GPIO13_GREEN_U4_LED",
+		"DIV_CLK2",
+		"NC",
+		"NC",
+		"NC",
+		"SMB_STAT",
+		"NC",
+		"NC",
+		"ADC_IN2",
+		"OPTION1",
+		"WCSS_PWR_REQ",
+		"PM845_GPIO24",
+		"OPTION2",
+		"PM845_SLB";
+
+	cam0_dvdd_1v2_en_default: cam0-dvdd-1v2-en {
+		pins = "gpio12";
+		function = "normal";
+
+		bias-pull-up;
+		drive-push-pull;
+		qcom,drive-strength = <PMIC_GPIO_STRENGTH_HIGH>;
+	};
+
+	cam0_avdd_2v8_en_default: cam0-avdd-2v8-en {
+		pins = "gpio10";
+		function = "normal";
+
+		bias-pull-up;
+		drive-push-pull;
+		qcom,drive-strength = <PMIC_GPIO_STRENGTH_HIGH>;
+	};
+
 	vol_up_pin_a: vol-up-active {
 		pins = "gpio6";
 		function = "normal";
@@ -573,6 +653,42 @@ &spi2 {
 };
 
 &tlmm {
+	cam0_default: cam0_default {
+		rst {
+			pins = "gpio9";
+			function = "gpio";
+
+			drive-strength = <16>;
+			bias-disable;
+		};
+
+		mclk0 {
+			pins = "gpio13";
+			function = "cam_mclk";
+
+			drive-strength = <16>;
+			bias-disable;
+		};
+	};
+
+	cam3_default: cam3_default {
+		rst {
+			function = "gpio";
+			pins = "gpio21";
+
+			drive-strength = <16>;
+			bias-disable;
+		};
+
+		mclk3 {
+			function = "cam_mclk";
+			pins = "gpio16";
+
+			drive-strength = <16>;
+			bias-disable;
+		};
+	};
+
 	pcie0_default_state: pcie0-default {
 		clkreq {
 			pins = "gpio36";
@@ -866,3 +982,97 @@ pinconf-rx {
 		bias-pull-up;
 	};
 };
+
+&pm8998_gpio {
+
+};
+
+&cci {
+	status = "ok";
+};
+
+&cci_i2c0 {
+	camera@10 {
+		compatible = "ovti,ov8856";
+		reg = <0x10>;
+
+		// CAM0_RST_N
+		reset-gpios = <&tlmm 9 0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&cam0_default>;
+		gpios = <&tlmm 13 0>,
+			<&tlmm 9 0>;
+
+		clocks = <&clock_camcc CAM_CC_MCLK0_CLK>;
+		clock-names = "xvclk";
+		clock-frequency = <19200000>;
+
+		/* The &vreg_s4a_1p8 trace is powered on as a,
+		 * so it is represented by a fixed regulator.
+		 *
+		 * The 2.8V vdda-supply and 1.2V vddd-supply regulators
+		 * both have to be enabled through the power management
+		 * gpios.
+		 */
+		power-domains = <&clock_camcc TITAN_TOP_GDSC>;
+
+		dovdd-supply = <&vreg_lvs1a_1p8>;
+		avdd-supply = <&cam0_avdd_2v8>;
+		dvdd-supply = <&cam0_dvdd_1v2>;
+
+		status = "disable";
+
+		port {
+			ov8856_ep: endpoint {
+				clock-lanes = <1>;
+				link-frequencies = /bits/ 64
+					<360000000 180000000>;
+				data-lanes = <1 2 3 4>;
+//				remote-endpoint = <&csiphy0_ep>;
+			};
+		};
+	};
+};
+
+&cci_i2c1 {
+	camera@60 {
+		compatible = "ovti,ov7251";
+
+		// I2C address as per ov7251.txt linux documentation
+		reg = <0x60>;
+
+		// CAM3_RST_N
+		enable-gpios = <&tlmm 21 0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&cam3_default>;
+		gpios = <&tlmm 16 0>,
+			<&tlmm 21 0>;
+
+		clocks = <&clock_camcc CAM_CC_MCLK3_CLK>;
+		clock-names = "xclk";
+		clock-frequency = <24000000>;
+
+		/* The &vreg_s4a_1p8 trace always powered on.
+		 *
+		 * The 2.8V vdda-supply regulator is enabled when the
+		 * vreg_s4a_1p8 trace is pulled high.
+		 * It too is represented by a fixed regulator.
+		 *
+		 * No 1.2V vddd-supply regulator is used.
+		 */
+		power-domains = <&clock_camcc TITAN_TOP_GDSC>;
+
+		vdddo-supply = <&vreg_lvs1a_1p8>;
+		vdda-supply = <&cam3_avdd_2v8>;
+
+		status = "disable";
+
+		port {
+			ov7251_ep: endpoint {
+				clock-lanes = <1>;
+				data-lanes = <0 1>;
+//				remote-endpoint = <&csiphy3_ep>;
+			};
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index 8f926b5234d4..71dfdfcf2033 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -5,6 +5,7 @@
  * Copyright (c) 2018, The Linux Foundation. All rights reserved.
  */
 
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
 #include <dt-bindings/clock/qcom,dispcc-sdm845.h>
 #include <dt-bindings/clock/qcom,gcc-sdm845.h>
 #include <dt-bindings/clock/qcom,gpucc-sdm845.h>
@@ -1813,6 +1814,42 @@ tlmm: pinctrl@3400000 {
 			gpio-ranges = <&tlmm 0 0 150>;
 			wakeup-parent = <&pdc_intc>;
 
+			cci0_default: cci0-default {
+				/* SDA, SCL */
+				pins = "gpio17", "gpio18";
+				function = "cci_i2c";
+
+				bias-pull-up;
+				drive-strength = <2>; /* 2 mA */
+			};
+
+			cci0_sleep: cci0-sleep {
+				/* SDA, SCL */
+				pins = "gpio17", "gpio18";
+				function = "cci_i2c";
+
+				drive-strength = <2>; /* 2 mA */
+				bias-pull-down;
+			};
+
+			cci1_default: cci1-default {
+				/* SDA, SCL */
+				pins = "gpio19", "gpio20";
+				function = "cci_i2c";
+
+				bias-pull-up;
+				drive-strength = <2>; /* 2 mA */
+			};
+
+			cci1_sleep: cci1-sleep {
+				/* SDA, SCL */
+				pins = "gpio19", "gpio20";
+				function = "cci_i2c";
+
+				drive-strength = <2>; /* 2 mA */
+				bias-pull-down;
+			};
+
 			qspi_clk: qspi-clk {
 				pinmux {
 					pins = "gpio95";
@@ -2970,7 +3007,7 @@ sound: sound {
 		};
 
 		usb_1_hsphy: phy@88e2000 {
-			compatible = "qcom,sdm845-qusb2-phy";
+			compatible = "qcom,sdm845-qusb2-phy", "qcom,qusb2-v2-phy";
 			reg = <0 0x088e2000 0 0x400>;
 			status = "disabled";
 			#phy-cells = <0>;
@@ -2985,7 +3022,7 @@ usb_1_hsphy: phy@88e2000 {
 		};
 
 		usb_2_hsphy: phy@88e3000 {
-			compatible = "qcom,sdm845-qusb2-phy";
+			compatible = "qcom,sdm845-qusb2-phy", "qcom,qusb2-v2-phy";
 			reg = <0 0x088e3000 0 0x400>;
 			status = "disabled";
 			#phy-cells = <0>;
@@ -3194,6 +3231,61 @@ videocc: clock-controller@ab00000 {
 			#reset-cells = <1>;
 		};
 
+		cci: cci@ac4a000 {
+			compatible = "qcom,sdm845-cci";
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			reg = <0 0x0ac4a000 0 0x4000>;
+			interrupts = <GIC_SPI 460 IRQ_TYPE_EDGE_RISING>;
+			power-domains = <&clock_camcc TITAN_TOP_GDSC>;
+
+			clocks = <&clock_camcc CAM_CC_CAMNOC_AXI_CLK>,
+				<&clock_camcc CAM_CC_SOC_AHB_CLK>,
+				<&clock_camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+				<&clock_camcc CAM_CC_CPAS_AHB_CLK>,
+				<&clock_camcc CAM_CC_CCI_CLK>,
+				<&clock_camcc CAM_CC_CCI_CLK_SRC>;
+			clock-names = "camnoc_axi",
+				"soc_ahb",
+				"slow_ahb_src",
+				"cpas_ahb",
+				"cci",
+				"cci_src";
+
+			assigned-clocks = <&clock_camcc CAM_CC_CAMNOC_AXI_CLK>,
+				<&clock_camcc CAM_CC_CCI_CLK>;
+			assigned-clock-rates = <80000000>, <37500000>;
+
+			pinctrl-names = "default", "sleep";
+			pinctrl-0 = <&cci0_default &cci1_default>;
+			pinctrl-1 = <&cci0_sleep &cci1_sleep>;
+
+			status = "disabled";
+
+			cci_i2c0: i2c-bus@0 {
+				reg = <0>;
+				clock-frequency = <1000000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+
+			cci_i2c1: i2c-bus@1 {
+				reg = <1>;
+				clock-frequency = <1000000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+		};
+
+		clock_camcc: clock-controller@ad00000 {
+			compatible = "qcom,sdm845-camcc";
+			reg = <0 0x0ad00000 0 0x10000>;
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+			#power-domain-cells = <1>;
+		};
+
 		mdss: mdss@ae00000 {
 			compatible = "qcom,sdm845-mdss";
 			reg = <0 0x0ae00000 0 0x1000>;
diff --git a/arch/arm64/boot/dts/realtek/Makefile b/arch/arm64/boot/dts/realtek/Makefile
index 555638ada721..ef8d8fcbaa05 100644
--- a/arch/arm64/boot/dts/realtek/Makefile
+++ b/arch/arm64/boot/dts/realtek/Makefile
@@ -4,6 +4,12 @@ dtb-$(CONFIG_ARCH_REALTEK) += rtd1293-ds418j.dtb
 
 dtb-$(CONFIG_ARCH_REALTEK) += rtd1295-mele-v9.dtb
 dtb-$(CONFIG_ARCH_REALTEK) += rtd1295-probox2-ava.dtb
+dtb-$(CONFIG_ARCH_REALTEK) += rtd1295-xnano-x5.dtb
 dtb-$(CONFIG_ARCH_REALTEK) += rtd1295-zidoo-x9s.dtb
 
 dtb-$(CONFIG_ARCH_REALTEK) += rtd1296-ds418.dtb
+
+dtb-$(CONFIG_ARCH_REALTEK) += rtd1395-bpi-m4.dtb
+dtb-$(CONFIG_ARCH_REALTEK) += rtd1395-lionskin.dtb
+
+dtb-$(CONFIG_ARCH_REALTEK) += rtd1619-mjolnir.dtb
diff --git a/arch/arm64/boot/dts/realtek/rtd1293-ds418j.dts b/arch/arm64/boot/dts/realtek/rtd1293-ds418j.dts
index b2dd583146b4..b2e44c6c2d22 100644
--- a/arch/arm64/boot/dts/realtek/rtd1293-ds418j.dts
+++ b/arch/arm64/boot/dts/realtek/rtd1293-ds418j.dts
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
 /*
- * Copyright (c) 2017 Andreas Färber
+ * Copyright (c) 2017-2019 Andreas Färber
  */
 
 /dts-v1/;
@@ -11,9 +11,9 @@ / {
 	compatible = "synology,ds418j", "realtek,rtd1293";
 	model = "Synology DiskStation DS418j";
 
-	memory@0 {
+	memory@1f000 {
 		device_type = "memory";
-		reg = <0x0 0x40000000>;
+		reg = <0x1f000 0x3ffe1000>; /* boot ROM to 1 GiB */
 	};
 
 	aliases {
diff --git a/arch/arm64/boot/dts/realtek/rtd1293.dtsi b/arch/arm64/boot/dts/realtek/rtd1293.dtsi
index bd4e22723f7b..2d92b56ac94d 100644
--- a/arch/arm64/boot/dts/realtek/rtd1293.dtsi
+++ b/arch/arm64/boot/dts/realtek/rtd1293.dtsi
@@ -36,16 +36,20 @@ l2: l2-cache {
 	timer {
 		compatible = "arm,armv8-timer";
 		interrupts = <GIC_PPI 13
-			(GIC_CPU_MASK_RAW(0xf) | IRQ_TYPE_LEVEL_LOW)>,
+			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
 			     <GIC_PPI 14
-			(GIC_CPU_MASK_RAW(0xf) | IRQ_TYPE_LEVEL_LOW)>,
+			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
 			     <GIC_PPI 11
-			(GIC_CPU_MASK_RAW(0xf) | IRQ_TYPE_LEVEL_LOW)>,
+			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
 			     <GIC_PPI 10
-			(GIC_CPU_MASK_RAW(0xf) | IRQ_TYPE_LEVEL_LOW)>;
+			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
 	};
 };
 
 &arm_pmu {
 	interrupt-affinity = <&cpu0>, <&cpu1>;
 };
+
+&gic {
+	interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+};
diff --git a/arch/arm64/boot/dts/realtek/rtd1295-mele-v9.dts b/arch/arm64/boot/dts/realtek/rtd1295-mele-v9.dts
index bd584e99fff9..cf4a57c012a8 100644
--- a/arch/arm64/boot/dts/realtek/rtd1295-mele-v9.dts
+++ b/arch/arm64/boot/dts/realtek/rtd1295-mele-v9.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 Andreas Färber
+ * Copyright (c) 2017-2019 Andreas Färber
  *
  * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
  */
@@ -12,9 +12,9 @@ / {
 	compatible = "mele,v9", "realtek,rtd1295";
 	model = "MeLE V9";
 
-	memory@0 {
+	memory@1f000 {
 		device_type = "memory";
-		reg = <0x0 0x80000000>;
+		reg = <0x1f000 0x7ffe1000>; /* boot ROM to 2 GiB */
 	};
 
 	aliases {
diff --git a/arch/arm64/boot/dts/realtek/rtd1295-probox2-ava.dts b/arch/arm64/boot/dts/realtek/rtd1295-probox2-ava.dts
index 8e2b0e75298a..14161c3f304d 100644
--- a/arch/arm64/boot/dts/realtek/rtd1295-probox2-ava.dts
+++ b/arch/arm64/boot/dts/realtek/rtd1295-probox2-ava.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 Andreas Färber
+ * Copyright (c) 2017-2019 Andreas Färber
  *
  * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
  */
@@ -12,9 +12,9 @@ / {
 	compatible = "probox2,ava", "realtek,rtd1295";
 	model = "PROBOX2 AVA";
 
-	memory@0 {
+	memory@1f000 {
 		device_type = "memory";
-		reg = <0x0 0x80000000>;
+		reg = <0x1f000 0x7ffe1000>; /* boot ROM to 2 GiB */
 	};
 
 	aliases {
diff --git a/arch/arm64/boot/dts/realtek/rtd1295-xnano-x5.dts b/arch/arm64/boot/dts/realtek/rtd1295-xnano-x5.dts
new file mode 100644
index 000000000000..d7878ff942e6
--- /dev/null
+++ b/arch/arm64/boot/dts/realtek/rtd1295-xnano-x5.dts
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
+/*
+ * Copyright (c) 2017-2019 Andreas Färber
+ */
+
+/dts-v1/;
+
+#include "rtd1295.dtsi"
+
+/ {
+	compatible = "xnano,x5", "realtek,rtd1295";
+	model = "Xnano X5";
+
+	memory@1f000 {
+		device_type = "memory";
+		reg = <0x1f000 0x3ffe1000>; /* boot ROM to 1 GiB or 2 GiB */
+	};
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+};
+
+&uart0 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/realtek/rtd1295-zidoo-x9s.dts b/arch/arm64/boot/dts/realtek/rtd1295-zidoo-x9s.dts
index e98e508b9514..4beb37bb9522 100644
--- a/arch/arm64/boot/dts/realtek/rtd1295-zidoo-x9s.dts
+++ b/arch/arm64/boot/dts/realtek/rtd1295-zidoo-x9s.dts
@@ -11,9 +11,9 @@ / {
 	compatible = "zidoo,x9s", "realtek,rtd1295";
 	model = "Zidoo X9S";
 
-	memory@0 {
+	memory@1f000 {
 		device_type = "memory";
-		reg = <0x0 0x80000000>;
+		reg = <0x1f000 0x7ffe1000>; /* boot ROM to 2 GiB */
 	};
 
 	aliases {
diff --git a/arch/arm64/boot/dts/realtek/rtd1295.dtsi b/arch/arm64/boot/dts/realtek/rtd1295.dtsi
index 93f0e1d97721..1402abe80ea1 100644
--- a/arch/arm64/boot/dts/realtek/rtd1295.dtsi
+++ b/arch/arm64/boot/dts/realtek/rtd1295.dtsi
@@ -2,7 +2,7 @@
 /*
  * Realtek RTD1295 SoC
  *
- * Copyright (c) 2016-2017 Andreas Färber
+ * Copyright (c) 2016-2019 Andreas Färber
  */
 
 #include "rtd129x.dtsi"
@@ -47,27 +47,16 @@ l2: l2-cache {
 		};
 	};
 
-	reserved-memory {
-		#address-cells = <1>;
-		#size-cells = <1>;
-		ranges;
-
-		tee@10100000 {
-			reg = <0x10100000 0xf00000>;
-			no-map;
-		};
-	};
-
 	timer {
 		compatible = "arm,armv8-timer";
 		interrupts = <GIC_PPI 13
-			(GIC_CPU_MASK_RAW(0xf) | IRQ_TYPE_LEVEL_LOW)>,
+			(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
 			     <GIC_PPI 14
-			(GIC_CPU_MASK_RAW(0xf) | IRQ_TYPE_LEVEL_LOW)>,
+			(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
 			     <GIC_PPI 11
-			(GIC_CPU_MASK_RAW(0xf) | IRQ_TYPE_LEVEL_LOW)>,
+			(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
 			     <GIC_PPI 10
-			(GIC_CPU_MASK_RAW(0xf) | IRQ_TYPE_LEVEL_LOW)>;
+			(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
 	};
 };
 
diff --git a/arch/arm64/boot/dts/realtek/rtd1296-ds418.dts b/arch/arm64/boot/dts/realtek/rtd1296-ds418.dts
index 5a051a52bf88..cc706d13da8b 100644
--- a/arch/arm64/boot/dts/realtek/rtd1296-ds418.dts
+++ b/arch/arm64/boot/dts/realtek/rtd1296-ds418.dts
@@ -11,9 +11,9 @@ / {
 	compatible = "synology,ds418", "realtek,rtd1296";
 	model = "Synology DiskStation DS418";
 
-	memory@0 {
+	memory@1f000 {
 		device_type = "memory";
-		reg = <0x0 0x80000000>;
+		reg = <0x1f000 0x7ffe1000>; /* boot ROM to 2 GiB */
 	};
 
 	aliases {
diff --git a/arch/arm64/boot/dts/realtek/rtd1296.dtsi b/arch/arm64/boot/dts/realtek/rtd1296.dtsi
index 0f9e59cac086..fb864a139c97 100644
--- a/arch/arm64/boot/dts/realtek/rtd1296.dtsi
+++ b/arch/arm64/boot/dts/realtek/rtd1296.dtsi
@@ -50,13 +50,13 @@ l2: l2-cache {
 	timer {
 		compatible = "arm,armv8-timer";
 		interrupts = <GIC_PPI 13
-			(GIC_CPU_MASK_RAW(0xf) | IRQ_TYPE_LEVEL_LOW)>,
+			(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
 			     <GIC_PPI 14
-			(GIC_CPU_MASK_RAW(0xf) | IRQ_TYPE_LEVEL_LOW)>,
+			(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
 			     <GIC_PPI 11
-			(GIC_CPU_MASK_RAW(0xf) | IRQ_TYPE_LEVEL_LOW)>,
+			(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
 			     <GIC_PPI 10
-			(GIC_CPU_MASK_RAW(0xf) | IRQ_TYPE_LEVEL_LOW)>;
+			(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
 	};
 };
 
diff --git a/arch/arm64/boot/dts/realtek/rtd129x.dtsi b/arch/arm64/boot/dts/realtek/rtd129x.dtsi
index 4433114476f5..39aefe66a794 100644
--- a/arch/arm64/boot/dts/realtek/rtd129x.dtsi
+++ b/arch/arm64/boot/dts/realtek/rtd129x.dtsi
@@ -2,14 +2,12 @@
 /*
  * Realtek RTD1293/RTD1295/RTD1296 SoC
  *
- * Copyright (c) 2016-2017 Andreas Färber
+ * Copyright (c) 2016-2019 Andreas Färber
  */
 
-/memreserve/	0x0000000000000000 0x0000000000030000;
-/memreserve/	0x000000000001f000 0x0000000000001000;
-/memreserve/	0x0000000000030000 0x00000000000d0000;
+/memreserve/	0x0000000000000000 0x000000000001f000;
+/memreserve/	0x000000000001f000 0x00000000000e1000;
 /memreserve/	0x0000000001b00000 0x00000000004be000;
-/memreserve/	0x0000000001ffe000 0x0000000000004000;
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/reset/realtek,rtd1295.h>
@@ -19,6 +17,25 @@ / {
 	#address-cells = <1>;
 	#size-cells = <1>;
 
+	reserved-memory {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		rpc_comm: rpc@1f000 {
+			reg = <0x1f000 0x1000>;
+		};
+
+		rpc_ringbuf: rpc@1ffe000 {
+			reg = <0x1ffe000 0x4000>;
+		};
+
+		tee: tee@10100000 {
+			reg = <0x10100000 0xf00000>;
+			no-map;
+		};
+	};
+
 	arm_pmu: arm-pmu {
 		compatible = "arm,cortex-a53-pmu";
 		interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
@@ -35,73 +52,61 @@ soc {
 		compatible = "simple-bus";
 		#address-cells = <1>;
 		#size-cells = <1>;
-		/* Exclude up to 2 GiB of RAM */
-		ranges = <0x80000000 0x80000000 0x80000000>;
-
-		reset1: reset-controller@98000000 {
-			compatible = "snps,dw-low-reset";
-			reg = <0x98000000 0x4>;
-			#reset-cells = <1>;
-		};
-
-		reset2: reset-controller@98000004 {
-			compatible = "snps,dw-low-reset";
-			reg = <0x98000004 0x4>;
-			#reset-cells = <1>;
-		};
-
-		reset3: reset-controller@98000008 {
-			compatible = "snps,dw-low-reset";
-			reg = <0x98000008 0x4>;
-			#reset-cells = <1>;
-		};
-
-		reset4: reset-controller@98000050 {
-			compatible = "snps,dw-low-reset";
-			reg = <0x98000050 0x4>;
-			#reset-cells = <1>;
-		};
-
-		iso_reset: reset-controller@98007088 {
-			compatible = "snps,dw-low-reset";
-			reg = <0x98007088 0x4>;
-			#reset-cells = <1>;
-		};
-
-		wdt: watchdog@98007680 {
-			compatible = "realtek,rtd1295-watchdog";
-			reg = <0x98007680 0x100>;
-			clocks = <&osc27M>;
-		};
-
-		uart0: serial@98007800 {
-			compatible = "snps,dw-apb-uart";
-			reg = <0x98007800 0x400>;
-			reg-shift = <2>;
-			reg-io-width = <4>;
-			clock-frequency = <27000000>;
-			resets = <&iso_reset RTD1295_ISO_RSTN_UR0>;
-			status = "disabled";
-		};
-
-		uart1: serial@9801b200 {
-			compatible = "snps,dw-apb-uart";
-			reg = <0x9801b200 0x100>;
-			reg-shift = <2>;
-			reg-io-width = <4>;
-			clock-frequency = <432000000>;
-			resets = <&reset2 RTD1295_RSTN_UR1>;
-			status = "disabled";
-		};
-
-		uart2: serial@9801b400 {
-			compatible = "snps,dw-apb-uart";
-			reg = <0x9801b400 0x100>;
-			reg-shift = <2>;
-			reg-io-width = <4>;
-			clock-frequency = <432000000>;
-			resets = <&reset2 RTD1295_RSTN_UR2>;
-			status = "disabled";
+		ranges = <0x00000000 0x00000000 0x0001f000>, /* boot ROM */
+			 /* Exclude up to 2 GiB of RAM */
+			 <0x80000000 0x80000000 0x80000000>;
+
+		rbus: bus@98000000 {
+			compatible = "simple-bus";
+			reg = <0x98000000 0x200000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x0 0x98000000 0x200000>;
+
+			crt: syscon@0 {
+				compatible = "syscon", "simple-mfd";
+				reg = <0x0 0x1800>;
+				reg-io-width = <4>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0x0 0x0 0x1800>;
+			};
+
+			iso: syscon@7000 {
+				compatible = "syscon", "simple-mfd";
+				reg = <0x7000 0x1000>;
+				reg-io-width = <4>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0x0 0x7000 0x1000>;
+			};
+
+			sb2: syscon@1a000 {
+				compatible = "syscon", "simple-mfd";
+				reg = <0x1a000 0x1000>;
+				reg-io-width = <4>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0x0 0x1a000 0x1000>;
+			};
+
+			misc: syscon@1b000 {
+				compatible = "syscon", "simple-mfd";
+				reg = <0x1b000 0x1000>;
+				reg-io-width = <4>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0x0 0x1b000 0x1000>;
+			};
+
+			scpu_wrapper: syscon@1d000 {
+				compatible = "syscon", "simple-mfd";
+				reg = <0x1d000 0x2000>;
+				reg-io-width = <4>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0x0 0x1d000 0x2000>;
+			};
 		};
 
 		gic: interrupt-controller@ff011000 {
@@ -116,3 +121,75 @@ gic: interrupt-controller@ff011000 {
 		};
 	};
 };
+
+&crt {
+	reset1: reset-controller@0 {
+		compatible = "snps,dw-low-reset";
+		reg = <0x0 0x4>;
+		#reset-cells = <1>;
+	};
+
+	reset2: reset-controller@4 {
+		compatible = "snps,dw-low-reset";
+		reg = <0x4 0x4>;
+		#reset-cells = <1>;
+	};
+
+	reset3: reset-controller@8 {
+		compatible = "snps,dw-low-reset";
+		reg = <0x8 0x4>;
+		#reset-cells = <1>;
+	};
+
+	reset4: reset-controller@50 {
+		compatible = "snps,dw-low-reset";
+		reg = <0x50 0x4>;
+		#reset-cells = <1>;
+	};
+};
+
+&iso {
+	iso_reset: reset-controller@88 {
+		compatible = "snps,dw-low-reset";
+		reg = <0x88 0x4>;
+		#reset-cells = <1>;
+	};
+
+	wdt: watchdog@680 {
+		compatible = "realtek,rtd1295-watchdog";
+		reg = <0x680 0x100>;
+		clocks = <&osc27M>;
+	};
+
+	uart0: serial@800 {
+		compatible = "snps,dw-apb-uart";
+		reg = <0x800 0x400>;
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		clock-frequency = <27000000>;
+		resets = <&iso_reset RTD1295_ISO_RSTN_UR0>;
+		status = "disabled";
+	};
+};
+
+&misc {
+	uart1: serial@200 {
+		compatible = "snps,dw-apb-uart";
+		reg = <0x200 0x100>;
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		clock-frequency = <432000000>;
+		resets = <&reset2 RTD1295_RSTN_UR1>;
+		status = "disabled";
+	};
+
+	uart2: serial@400 {
+		compatible = "snps,dw-apb-uart";
+		reg = <0x400 0x100>;
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		clock-frequency = <432000000>;
+		resets = <&reset2 RTD1295_RSTN_UR2>;
+		status = "disabled";
+	};
+};
diff --git a/arch/arm64/boot/dts/realtek/rtd1395-bpi-m4.dts b/arch/arm64/boot/dts/realtek/rtd1395-bpi-m4.dts
new file mode 100644
index 000000000000..9891967d1315
--- /dev/null
+++ b/arch/arm64/boot/dts/realtek/rtd1395-bpi-m4.dts
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
+/*
+ * Copyright (c) 2019 Andreas Färber
+ */
+
+/dts-v1/;
+
+#include "rtd1395.dtsi"
+
+/ {
+	compatible = "bananapi,bpi-m4", "realtek,rtd1395";
+	model = "Banana Pi BPI-M4";
+
+	memory@2f000 {
+		device_type = "memory";
+		reg = <0x2f000 0x3ffd1000>; /* boot ROM to 1 GiB or 2 GiB */
+	};
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+};
+
+&uart0 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/realtek/rtd1395-lionskin.dts b/arch/arm64/boot/dts/realtek/rtd1395-lionskin.dts
new file mode 100644
index 000000000000..83f9b536cdea
--- /dev/null
+++ b/arch/arm64/boot/dts/realtek/rtd1395-lionskin.dts
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
+/*
+ * Copyright (c) 2019 Andreas Färber
+ */
+
+/dts-v1/;
+
+#include "rtd1395.dtsi"
+
+/ {
+	compatible = "realtek,lion-skin", "realtek,rtd1395";
+	model = "Realtek Lion Skin EVB";
+
+	memory@2f000 {
+		device_type = "memory";
+		reg = <0x2f000 0x3ffd1000>; /* boot ROM to 1 GiB or 2 GiB */
+	};
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+};
+
+/* debug console (J1) */
+&uart0 {
+	status = "okay";
+};
+
+/* M.2 slot (CON1) */
+&uart1 {
+	status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/realtek/rtd1395.dtsi b/arch/arm64/boot/dts/realtek/rtd1395.dtsi
new file mode 100644
index 000000000000..05c9216a87ee
--- /dev/null
+++ b/arch/arm64/boot/dts/realtek/rtd1395.dtsi
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
+/*
+ * Realtek RTD1395 SoC
+ *
+ * Copyright (c) 2019 Andreas Färber
+ */
+
+#include "rtd139x.dtsi"
+
+/ {
+	compatible = "realtek,rtd1395";
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			reg = <0x0 0x0>;
+			next-level-cache = <&l2>;
+		};
+
+		cpu1: cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			reg = <0x0 0x1>;
+			next-level-cache = <&l2>;
+		};
+
+		cpu2: cpu@2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			reg = <0x0 0x2>;
+			next-level-cache = <&l2>;
+		};
+
+		cpu3: cpu@3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			reg = <0x0 0x3>;
+			next-level-cache = <&l2>;
+		};
+
+		l2: l2-cache {
+			compatible = "cache";
+		};
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13
+			(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 14
+			(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 11
+			(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 10
+			(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+	};
+};
+
+&arm_pmu {
+	interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
+};
diff --git a/arch/arm64/boot/dts/realtek/rtd139x.dtsi b/arch/arm64/boot/dts/realtek/rtd139x.dtsi
new file mode 100644
index 000000000000..a3c10ceeb586
--- /dev/null
+++ b/arch/arm64/boot/dts/realtek/rtd139x.dtsi
@@ -0,0 +1,193 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
+/*
+ * Realtek RTD1395 SoC family
+ *
+ * Copyright (c) 2019 Andreas Färber
+ */
+
+/memreserve/	0x0000000000000000 0x000000000002f000;
+/memreserve/	0x000000000002f000 0x00000000000d1000;
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/reset/realtek,rtd1295.h>
+
+/ {
+	interrupt-parent = <&gic>;
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	reserved-memory {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		rpc_comm: rpc@2f000 {
+			reg = <0x2f000 0x1000>;
+		};
+
+		rpc_ringbuf: rpc@1ffe000 {
+			reg = <0x1ffe000 0x4000>;
+		};
+
+		tee: tee@10100000 {
+			reg = <0x10100000 0xf00000>;
+			no-map;
+		};
+	};
+
+	arm_pmu: arm-pmu {
+		compatible = "arm,cortex-a53-pmu";
+		interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	osc27M: osc {
+		compatible = "fixed-clock";
+		clock-frequency = <27000000>;
+		#clock-cells = <0>;
+		clock-output-names = "osc27M";
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0x00000000 0x00000000 0x0001f000>, /* boot ROM */
+			 <0x98000000 0x98000000 0x68000000>;
+
+		rbus: bus@98000000 {
+			compatible = "simple-bus";
+			reg = <0x98000000 0x200000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x0 0x98000000 0x200000>;
+
+			crt: syscon@0 {
+				compatible = "syscon", "simple-mfd";
+				reg = <0x0 0x1000>;
+				reg-io-width = <4>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0x0 0x0 0x1000>;
+			};
+
+			iso: syscon@7000 {
+				compatible = "syscon", "simple-mfd";
+				reg = <0x7000 0x1000>;
+				reg-io-width = <4>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0x0 0x7000 0x1000>;
+			};
+
+			sb2: syscon@1a000 {
+				compatible = "syscon", "simple-mfd";
+				reg = <0x1a000 0x1000>;
+				reg-io-width = <4>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0x0 0x1a000 0x1000>;
+			};
+
+			misc: syscon@1b000 {
+				compatible = "syscon", "simple-mfd";
+				reg = <0x1b000 0x1000>;
+				reg-io-width = <4>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0x0 0x1b000 0x1000>;
+			};
+
+			scpu_wrapper: syscon@1d000 {
+				compatible = "syscon", "simple-mfd";
+				reg = <0x1d000 0x2000>;
+				reg-io-width = <4>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0x0 0x1d000 0x2000>;
+			};
+		};
+
+		gic: interrupt-controller@ff011000 {
+			compatible = "arm,gic-400";
+			reg = <0xff011000 0x1000>,
+			      <0xff012000 0x2000>,
+			      <0xff014000 0x2000>,
+			      <0xff016000 0x2000>;
+			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+		};
+	};
+};
+
+&crt {
+	reset1: reset-controller@0 {
+		compatible = "snps,dw-low-reset";
+		reg = <0x0 0x4>;
+		#reset-cells = <1>;
+	};
+
+	reset2: reset-controller@4 {
+		compatible = "snps,dw-low-reset";
+		reg = <0x4 0x4>;
+		#reset-cells = <1>;
+	};
+
+	reset3: reset-controller@8 {
+		compatible = "snps,dw-low-reset";
+		reg = <0x8 0x4>;
+		#reset-cells = <1>;
+	};
+
+	reset4: reset-controller@50 {
+		compatible = "snps,dw-low-reset";
+		reg = <0x50 0x4>;
+		#reset-cells = <1>;
+	};
+};
+
+&iso {
+	iso_reset: reset-controller@88 {
+		compatible = "snps,dw-low-reset";
+		reg = <0x88 0x4>;
+		#reset-cells = <1>;
+	};
+
+	wdt: watchdog@680 {
+		compatible = "realtek,rtd1295-watchdog";
+		reg = <0x680 0x100>;
+		clocks = <&osc27M>;
+	};
+
+	uart0: serial@800 {
+		compatible = "snps,dw-apb-uart";
+		reg = <0x800 0x400>;
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		clock-frequency = <27000000>;
+		resets = <&iso_reset RTD1295_ISO_RSTN_UR0>;
+		status = "disabled";
+	};
+};
+
+&misc {
+	uart1: serial@200 {
+		compatible = "snps,dw-apb-uart";
+		reg = <0x200 0x100>;
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		clock-frequency = <432000000>;
+		resets = <&reset2 RTD1295_RSTN_UR1>;
+		status = "disabled";
+	};
+
+	uart2: serial@400 {
+		compatible = "snps,dw-apb-uart";
+		reg = <0x400 0x100>;
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		clock-frequency = <432000000>;
+		resets = <&reset2 RTD1295_RSTN_UR2>;
+		status = "disabled";
+	};
+};
diff --git a/arch/arm64/boot/dts/realtek/rtd1619-mjolnir.dts b/arch/arm64/boot/dts/realtek/rtd1619-mjolnir.dts
new file mode 100644
index 000000000000..90ed6681468f
--- /dev/null
+++ b/arch/arm64/boot/dts/realtek/rtd1619-mjolnir.dts
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
+/*
+ * Copyright (c) 2019 Realtek Semiconductor Corp.
+ * Copyright (c) 2019 Andreas Färber
+ */
+
+/dts-v1/;
+
+#include "rtd1619.dtsi"
+
+/ {
+	compatible = "realtek,mjolnir", "realtek,rtd1619";
+	model = "Realtek Mjolnir EVB";
+
+	memory@2e000 {
+		device_type = "memory";
+		reg = <0x2e000 0x7ffd2000>; /* boot ROM to 2 GiB */
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	aliases {
+		serial0 = &uart0;
+		serial1 = &uart1;
+		serial2 = &uart2;
+	};
+};
+
+/* debug console (J1) */
+&uart0 {
+	status = "okay";
+};
+
+/* M.2 slot (CON4) */
+&uart1 {
+	status = "disabled";
+};
+
+/* GPIO connector (T1) */
+&uart2 {
+	status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/realtek/rtd1619.dtsi b/arch/arm64/boot/dts/realtek/rtd1619.dtsi
new file mode 100644
index 000000000000..e52bf708b04e
--- /dev/null
+++ b/arch/arm64/boot/dts/realtek/rtd1619.dtsi
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
+/*
+ * Realtek RTD1619 SoC
+ *
+ * Copyright (c) 2019 Realtek Semiconductor Corp.
+ */
+
+#include "rtd16xx.dtsi"
+
+/ {
+	compatible = "realtek,rtd1619";
+};
diff --git a/arch/arm64/boot/dts/realtek/rtd16xx.dtsi b/arch/arm64/boot/dts/realtek/rtd16xx.dtsi
new file mode 100644
index 000000000000..afba5f04c8ec
--- /dev/null
+++ b/arch/arm64/boot/dts/realtek/rtd16xx.dtsi
@@ -0,0 +1,229 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
+/*
+ * Realtek RTD16xx SoC family
+ *
+ * Copyright (c) 2019 Realtek Semiconductor Corp.
+ * Copyright (c) 2019 Andreas Färber
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+	interrupt-parent = <&gic>;
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	reserved-memory {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		rpc_comm: rpc@2f000 {
+			reg = <0x2f000 0x1000>;
+		};
+
+		rpc_ringbuf: rpc@1ffe000 {
+			reg = <0x1ffe000 0x4000>;
+		};
+
+		tee: tee@10100000 {
+			reg = <0x10100000 0xf00000>;
+			no-map;
+		};
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x0>;
+			enable-method = "psci";
+			next-level-cache = <&l2>;
+		};
+
+		cpu1: cpu@100 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x100>;
+			enable-method = "psci";
+			next-level-cache = <&l3>;
+		};
+
+		cpu2: cpu@200 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x200>;
+			enable-method = "psci";
+			next-level-cache = <&l3>;
+		};
+
+		cpu3: cpu@300 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x300>;
+			enable-method = "psci";
+			next-level-cache = <&l3>;
+		};
+
+		cpu4: cpu@400 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x400>;
+			enable-method = "psci";
+			next-level-cache = <&l3>;
+		};
+
+		cpu5: cpu@500 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x500>;
+			enable-method = "psci";
+			next-level-cache = <&l3>;
+		};
+
+		l2: l2-cache {
+			compatible = "cache";
+			next-level-cache = <&l3>;
+
+		};
+
+		l3: l3-cache {
+			compatible = "cache";
+		};
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+	};
+
+	arm_pmu: pmu {
+		compatible = "arm,armv8-pmuv3";
+		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>,
+			<&cpu3>, <&cpu4>, <&cpu5>;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0";
+		method = "smc";
+	};
+
+	osc27M: osc {
+		compatible = "fixed-clock";
+		clock-frequency = <27000000>;
+		clock-output-names = "osc27M";
+		#clock-cells = <0>;
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0x00000000 0x00000000 0x0002e000>, /* boot ROM */
+			 <0x98000000 0x98000000 0x68000000>;
+
+		rbus: bus@98000000 {
+			compatible = "simple-bus";
+			reg = <0x98000000 0x200000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x0 0x98000000 0x200000>;
+
+			crt: syscon@0 {
+				compatible = "syscon", "simple-mfd";
+				reg = <0x0 0x1000>;
+				reg-io-width = <4>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0x0 0x0 0x1000>;
+			};
+
+			iso: syscon@7000 {
+				compatible = "syscon", "simple-mfd";
+				reg = <0x7000 0x1000>;
+				reg-io-width = <4>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0x0 0x7000 0x1000>;
+			};
+
+			sb2: syscon@1a000 {
+				compatible = "syscon", "simple-mfd";
+				reg = <0x1a000 0x1000>;
+				reg-io-width = <4>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0x0 0x1a000 0x1000>;
+			};
+
+			misc: syscon@1b000 {
+				compatible = "syscon", "simple-mfd";
+				reg = <0x1b000 0x1000>;
+				reg-io-width = <4>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0x0 0x1b000 0x1000>;
+			};
+
+			scpu_wrapper: syscon@1d000 {
+				compatible = "syscon", "simple-mfd";
+				reg = <0x1d000 0x1000>;
+				reg-io-width = <4>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0x0 0x1d000 0x1000>;
+			};
+		};
+
+		gic: interrupt-controller@ff100000 {
+			compatible = "arm,gic-v3";
+			reg = <0xff100000 0x10000>,
+			      <0xff140000 0xc0000>;
+			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+		};
+	};
+};
+
+&iso {
+	uart0: serial0@800 {
+		compatible = "snps,dw-apb-uart";
+		reg = <0x800 0x400>;
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
+		clock-frequency = <27000000>;
+		status = "disabled";
+	};
+};
+
+&misc {
+	uart1: serial1@200 {
+		compatible = "snps,dw-apb-uart";
+		reg = <0x200 0x400>;
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
+		clock-frequency = <432000000>;
+		status = "disabled";
+	};
+
+	uart2: serial2@400 {
+		compatible = "snps,dw-apb-uart";
+		reg = <0x400 0x400>;
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
+		clock-frequency = <432000000>;
+		status = "disabled";
+	};
+};
diff --git a/arch/arm64/boot/dts/renesas/r8a77961.dtsi b/arch/arm64/boot/dts/renesas/r8a77961.dtsi
index 0d96f2d3492b..760e738b75b3 100644
--- a/arch/arm64/boot/dts/renesas/r8a77961.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77961.dtsi
@@ -626,21 +626,150 @@ i2c_dvfs: i2c@e60b0000 {
 			status = "disabled";
 		};
 
+		hscif0: serial@e6540000 {
+			compatible = "renesas,hscif-r8a77961",
+				     "renesas,rcar-gen3-hscif",
+				     "renesas,hscif";
+			reg = <0 0xe6540000 0 0x60>;
+			interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 520>,
+				 <&cpg CPG_CORE R8A77961_CLK_S3D1>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac1 0x31>, <&dmac1 0x30>,
+			       <&dmac2 0x31>, <&dmac2 0x30>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+			resets = <&cpg 520>;
+			status = "disabled";
+		};
 
 		hscif1: serial@e6550000 {
+			compatible = "renesas,hscif-r8a77961",
+				     "renesas,rcar-gen3-hscif",
+				     "renesas,hscif";
 			reg = <0 0xe6550000 0 0x60>;
-			/* placeholder */
+			interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 519>,
+				 <&cpg CPG_CORE R8A77961_CLK_S3D1>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac1 0x33>, <&dmac1 0x32>,
+			       <&dmac2 0x33>, <&dmac2 0x32>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+			resets = <&cpg 519>;
+			status = "disabled";
+		};
+
+		hscif2: serial@e6560000 {
+			compatible = "renesas,hscif-r8a77961",
+				     "renesas,rcar-gen3-hscif",
+				     "renesas,hscif";
+			reg = <0 0xe6560000 0 0x60>;
+			interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 518>,
+				 <&cpg CPG_CORE R8A77961_CLK_S3D1>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac1 0x35>, <&dmac1 0x34>,
+			       <&dmac2 0x35>, <&dmac2 0x34>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+			resets = <&cpg 518>;
+			status = "disabled";
+		};
+
+		hscif3: serial@e66a0000 {
+			compatible = "renesas,hscif-r8a77961",
+				     "renesas,rcar-gen3-hscif",
+				     "renesas,hscif";
+			reg = <0 0xe66a0000 0 0x60>;
+			interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 517>,
+				 <&cpg CPG_CORE R8A77961_CLK_S3D1>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x37>, <&dmac0 0x36>;
+			dma-names = "tx", "rx";
+			power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+			resets = <&cpg 517>;
+			status = "disabled";
+		};
+
+		hscif4: serial@e66b0000 {
+			compatible = "renesas,hscif-r8a77961",
+				     "renesas,rcar-gen3-hscif",
+				     "renesas,hscif";
+			reg = <0 0xe66b0000 0 0x60>;
+			interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 516>,
+				 <&cpg CPG_CORE R8A77961_CLK_S3D1>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x39>, <&dmac0 0x38>;
+			dma-names = "tx", "rx";
+			power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+			resets = <&cpg 516>;
+			status = "disabled";
 		};
 
 		hsusb: usb@e6590000 {
+			compatible = "renesas,usbhs-r8a77961",
+				     "renesas,rcar-gen3-usbhs";
 			reg = <0 0xe6590000 0 0x200>;
-			/* placeholder */
+			interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 704>, <&cpg CPG_MOD 703>;
+			dmas = <&usb_dmac0 0>, <&usb_dmac0 1>,
+			       <&usb_dmac1 0>, <&usb_dmac1 1>;
+			dma-names = "ch0", "ch1", "ch2", "ch3";
+			renesas,buswait = <11>;
+			phys = <&usb2_phy0 3>;
+			phy-names = "usb";
+			power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+			resets = <&cpg 704>, <&cpg 703>;
+			status = "disabled";
+		};
+
+		usb_dmac0: dma-controller@e65a0000 {
+			compatible = "renesas,r8a77961-usb-dmac",
+				     "renesas,usb-dmac";
+			reg = <0 0xe65a0000 0 0x100>;
+			interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "ch0", "ch1";
+			clocks = <&cpg CPG_MOD 330>;
+			power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+			resets = <&cpg 330>;
+			#dma-cells = <1>;
+			dma-channels = <2>;
+		};
+
+		usb_dmac1: dma-controller@e65b0000 {
+			compatible = "renesas,r8a77961-usb-dmac",
+				     "renesas,usb-dmac";
+			reg = <0 0xe65b0000 0 0x100>;
+			interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "ch0", "ch1";
+			clocks = <&cpg CPG_MOD 331>;
+			power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+			resets = <&cpg 331>;
+			#dma-cells = <1>;
+			dma-channels = <2>;
 		};
 
 		usb3_phy0: usb-phy@e65ee000 {
+			compatible = "renesas,r8a77961-usb3-phy",
+				     "renesas,rcar-gen3-usb3-phy";
 			reg = <0 0xe65ee000 0 0x90>;
+			clocks = <&cpg CPG_MOD 328>, <&usb3s0_clk>,
+				 <&usb_extal_clk>;
+			clock-names = "usb3-if", "usb3s_clk", "usb_extal";
+			power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+			resets = <&cpg 328>;
 			#phy-cells = <0>;
-			/* placeholder */
+			status = "disabled";
 		};
 
 		arm_cc630p: crypto@e6601000 {
@@ -799,15 +928,108 @@ avb: ethernet@e6800000 {
 			status = "disabled";
 		};
 
+		pwm0: pwm@e6e30000 {
+			compatible = "renesas,pwm-r8a77961", "renesas,pwm-rcar";
+			reg = <0 0xe6e30000 0 8>;
+			#pwm-cells = <2>;
+			clocks = <&cpg CPG_MOD 523>;
+			resets = <&cpg 523>;
+			power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
 		pwm1: pwm@e6e31000 {
+			compatible = "renesas,pwm-r8a77961", "renesas,pwm-rcar";
 			reg = <0 0xe6e31000 0 8>;
 			#pwm-cells = <2>;
-			/* placeholder */
+			clocks = <&cpg CPG_MOD 523>;
+			resets = <&cpg 523>;
+			power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		pwm2: pwm@e6e32000 {
+			compatible = "renesas,pwm-r8a77961", "renesas,pwm-rcar";
+			reg = <0 0xe6e32000 0 8>;
+			#pwm-cells = <2>;
+			clocks = <&cpg CPG_MOD 523>;
+			resets = <&cpg 523>;
+			power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		pwm3: pwm@e6e33000 {
+			compatible = "renesas,pwm-r8a77961", "renesas,pwm-rcar";
+			reg = <0 0xe6e33000 0 8>;
+			#pwm-cells = <2>;
+			clocks = <&cpg CPG_MOD 523>;
+			resets = <&cpg 523>;
+			power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		pwm4: pwm@e6e34000 {
+			compatible = "renesas,pwm-r8a77961", "renesas,pwm-rcar";
+			reg = <0 0xe6e34000 0 8>;
+			#pwm-cells = <2>;
+			clocks = <&cpg CPG_MOD 523>;
+			resets = <&cpg 523>;
+			power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		pwm5: pwm@e6e35000 {
+			compatible = "renesas,pwm-r8a77961", "renesas,pwm-rcar";
+			reg = <0 0xe6e35000 0 8>;
+			#pwm-cells = <2>;
+			clocks = <&cpg CPG_MOD 523>;
+			resets = <&cpg 523>;
+			power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		pwm6: pwm@e6e36000 {
+			compatible = "renesas,pwm-r8a77961", "renesas,pwm-rcar";
+			reg = <0 0xe6e36000 0 8>;
+			#pwm-cells = <2>;
+			clocks = <&cpg CPG_MOD 523>;
+			resets = <&cpg 523>;
+			power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		scif0: serial@e6e60000 {
+			compatible = "renesas,scif-r8a77961",
+				     "renesas,rcar-gen3-scif", "renesas,scif";
+			reg = <0 0xe6e60000 0 64>;
+			interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 207>,
+				 <&cpg CPG_CORE R8A77961_CLK_S3D1>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac1 0x51>, <&dmac1 0x50>,
+			       <&dmac2 0x51>, <&dmac2 0x50>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+			resets = <&cpg 207>;
+			status = "disabled";
 		};
 
 		scif1: serial@e6e68000 {
+			compatible = "renesas,scif-r8a77961",
+				     "renesas,rcar-gen3-scif", "renesas,scif";
 			reg = <0 0xe6e68000 0 64>;
-			/* placeholder */
+			interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 206>,
+				 <&cpg CPG_CORE R8A77961_CLK_S3D1>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac1 0x53>, <&dmac1 0x52>,
+			       <&dmac2 0x53>, <&dmac2 0x52>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+			resets = <&cpg 206>;
+			status = "disabled";
 		};
 
 		scif2: serial@e6e88000 {
@@ -819,11 +1041,63 @@ scif2: serial@e6e88000 {
 				 <&cpg CPG_CORE R8A77961_CLK_S3D1>,
 				 <&scif_clk>;
 			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac1 0x13>, <&dmac1 0x12>,
+			       <&dmac2 0x13>, <&dmac2 0x12>;
+			dma-names = "tx", "rx", "tx", "rx";
 			power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
 			resets = <&cpg 310>;
 			status = "disabled";
 		};
 
+		scif3: serial@e6c50000 {
+			compatible = "renesas,scif-r8a77961",
+				     "renesas,rcar-gen3-scif", "renesas,scif";
+			reg = <0 0xe6c50000 0 64>;
+			interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 204>,
+				 <&cpg CPG_CORE R8A77961_CLK_S3D1>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x57>, <&dmac0 0x56>;
+			dma-names = "tx", "rx";
+			power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+			resets = <&cpg 204>;
+			status = "disabled";
+		};
+
+		scif4: serial@e6c40000 {
+			compatible = "renesas,scif-r8a77961",
+				     "renesas,rcar-gen3-scif", "renesas,scif";
+			reg = <0 0xe6c40000 0 64>;
+			interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 203>,
+				 <&cpg CPG_CORE R8A77961_CLK_S3D1>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x59>, <&dmac0 0x58>;
+			dma-names = "tx", "rx";
+			power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+			resets = <&cpg 203>;
+			status = "disabled";
+		};
+
+		scif5: serial@e6f30000 {
+			compatible = "renesas,scif-r8a77961",
+				     "renesas,rcar-gen3-scif", "renesas,scif";
+			reg = <0 0xe6f30000 0 64>;
+			interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 202>,
+				 <&cpg CPG_CORE R8A77961_CLK_S3D1>,
+				 <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac1 0x5b>, <&dmac1 0x5a>,
+			       <&dmac2 0x5b>, <&dmac2 0x5a>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+			resets = <&cpg 202>;
+			status = "disabled";
+		};
+
 		vin0: video@e6ef0000 {
 			reg = <0 0xe6ef0000 0 0x1000>;
 			/* placeholder */
@@ -889,43 +1163,98 @@ rcar_sound,ssi {
 		};
 
 		xhci0: usb@ee000000 {
+			compatible = "renesas,xhci-r8a77961",
+				     "renesas,rcar-gen3-xhci";
 			reg = <0 0xee000000 0 0xc00>;
-			/* placeholder */
+			interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 328>;
+			power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+			resets = <&cpg 328>;
+			status = "disabled";
 		};
 
 		usb3_peri0: usb@ee020000 {
+			compatible = "renesas,r8a77961-usb3-peri",
+				     "renesas,rcar-gen3-usb3-peri";
 			reg = <0 0xee020000 0 0x400>;
-			/* placeholder */
+			interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 328>;
+			power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+			resets = <&cpg 328>;
+			status = "disabled";
 		};
 
 		ohci0: usb@ee080000 {
+			compatible = "generic-ohci";
 			reg = <0 0xee080000 0 0x100>;
-			/* placeholder */
+			interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>;
+			phys = <&usb2_phy0 1>;
+			phy-names = "usb";
+			power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+			resets = <&cpg 703>, <&cpg 704>;
+			status = "disabled";
 		};
 
 		ohci1: usb@ee0a0000 {
+			compatible = "generic-ohci";
 			reg = <0 0xee0a0000 0 0x100>;
-			/* placeholder */
+			interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 702>;
+			phys = <&usb2_phy1 1>;
+			phy-names = "usb";
+			power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+			resets = <&cpg 702>;
+			status = "disabled";
 		};
 
 		ehci0: usb@ee080100 {
+			compatible = "generic-ehci";
 			reg = <0 0xee080100 0 0x100>;
-			/* placeholder */
+			interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>;
+			phys = <&usb2_phy0 2>;
+			phy-names = "usb";
+			companion = <&ohci0>;
+			power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+			resets = <&cpg 703>, <&cpg 704>;
+			status = "disabled";
 		};
 
 		ehci1: usb@ee0a0100 {
+			compatible = "generic-ehci";
 			reg = <0 0xee0a0100 0 0x100>;
-			/* placeholder */
+			interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 702>;
+			phys = <&usb2_phy1 2>;
+			phy-names = "usb";
+			companion = <&ohci1>;
+			power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+			resets = <&cpg 702>;
+			status = "disabled";
 		};
 
 		usb2_phy0: usb-phy@ee080200 {
+			compatible = "renesas,usb2-phy-r8a77961",
+				     "renesas,rcar-gen3-usb2-phy";
 			reg = <0 0xee080200 0 0x700>;
-			/* placeholder */
+			interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>;
+			power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+			resets = <&cpg 703>, <&cpg 704>;
+			#phy-cells = <1>;
+			status = "disabled";
 		};
 
 		usb2_phy1: usb-phy@ee0a0200 {
+			compatible = "renesas,usb2-phy-r8a77961",
+				     "renesas,rcar-gen3-usb2-phy";
 			reg = <0 0xee0a0200 0 0x700>;
-			/* placeholder */
+			clocks = <&cpg CPG_MOD 702>;
+			power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+			resets = <&cpg 702>;
+			#phy-cells = <1>;
+			status = "disabled";
 		};
 
 		sdhi0: sd@ee100000 {
@@ -994,13 +1323,57 @@ gic: interrupt-controller@f1010000 {
 		};
 
 		pciec0: pcie@fe000000 {
+			compatible = "renesas,pcie-r8a77961",
+				     "renesas,pcie-rcar-gen3";
 			reg = <0 0xfe000000 0 0x80000>;
-			/* placeholder */
+			#address-cells = <3>;
+			#size-cells = <2>;
+			bus-range = <0x00 0xff>;
+			device_type = "pci";
+			ranges = <0x01000000 0 0x00000000 0 0xfe100000 0 0x00100000>,
+				 <0x02000000 0 0xfe200000 0 0xfe200000 0 0x00200000>,
+				 <0x02000000 0 0x30000000 0 0x30000000 0 0x08000000>,
+				 <0x42000000 0 0x38000000 0 0x38000000 0 0x08000000>;
+			/* Map all possible DDR as inbound ranges */
+			dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000>;
+			interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 0>;
+			interrupt-map = <0 0 0 0 &gic GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 319>, <&pcie_bus_clk>;
+			clock-names = "pcie", "pcie_bus";
+			power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+			resets = <&cpg 319>;
+			status = "disabled";
 		};
 
 		pciec1: pcie@ee800000 {
+			compatible = "renesas,pcie-r8a77961",
+				     "renesas,pcie-rcar-gen3";
 			reg = <0 0xee800000 0 0x80000>;
-			/* placeholder */
+			#address-cells = <3>;
+			#size-cells = <2>;
+			bus-range = <0x00 0xff>;
+			device_type = "pci";
+			ranges = <0x01000000 0 0x00000000 0 0xee900000 0 0x00100000>,
+				 <0x02000000 0 0xeea00000 0 0xeea00000 0 0x00200000>,
+				 <0x02000000 0 0xc0000000 0 0xc0000000 0 0x08000000>,
+				 <0x42000000 0 0xc8000000 0 0xc8000000 0 0x08000000>;
+			/* Map all possible DDR as inbound ranges */
+			dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000>;
+			interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 0>;
+			interrupt-map = <0 0 0 0 &gic GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 318>, <&pcie_bus_clk>;
+			clock-names = "pcie", "pcie_bus";
+			power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+			resets = <&cpg 318>;
+			status = "disabled";
 		};
 
 		csi20: csi2@fea80000 {
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 24e534d85045..f9eefb5940ca 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -208,7 +208,7 @@ CONFIG_PCIE_QCOM=y
 CONFIG_PCIE_ARMADA_8K=y
 CONFIG_PCIE_KIRIN=y
 CONFIG_PCIE_HISI_STB=y
-CONFIG_PCIE_TEGRA194=m
+CONFIG_PCIE_TEGRA194_HOST=m
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_FW_LOADER_USER_HELPER=y
@@ -410,6 +410,7 @@ CONFIG_I2C_MESON=y
 CONFIG_I2C_MV64XXX=y
 CONFIG_I2C_OWL=y
 CONFIG_I2C_PXA=y
+CONFIG_I2C_QCOM_CCI=m
 CONFIG_I2C_QCOM_GENI=m
 CONFIG_I2C_QUP=y
 CONFIG_I2C_RK3X=y
@@ -583,6 +584,7 @@ CONFIG_VIDEO_RENESAS_FCP=m
 CONFIG_VIDEO_RENESAS_VSP1=m
 CONFIG_SDR_PLATFORM_DRIVERS=y
 CONFIG_VIDEO_RCAR_DRIF=m
+CONFIG_VIDEO_QCOM_CAMSS=m
 CONFIG_DRM=m
 CONFIG_DRM_I2C_NXP_TDA998X=m
 CONFIG_DRM_MALI_DISPLAY=m
@@ -802,6 +804,7 @@ CONFIG_MSM_GCC_8994=y
 CONFIG_MSM_MMCC_8996=y
 CONFIG_MSM_GCC_8998=y
 CONFIG_QCS_GCC_404=y
+CONFIG_SDM_CAMCC_845=m
 CONFIG_SDM_GCC_845=y
 CONFIG_SDM_GPUCC_845=y
 CONFIG_SDM_DISPCC_845=y
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index a1871bb32bb1..2d43983289b9 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -156,6 +156,17 @@
 #define IOREMAP_MAX_ORDER	(PMD_SHIFT)
 #endif
 
+/*
+ * Memory hotplug allows new regions of 'System RAM' to be added to the system.
+ * These aren't described as memory by the UEFI memory map, or DT memory node.
+ * If we kexec from one of these regions, the new kernel boots from a location
+ * that isn't described as RAM.
+ *
+ * Give these resources a different name, so unaware kexec doesn't do this by
+ * accident.
+ */
+#define MEMORY_HOTPLUG_RES_NAME "System RAM (hotplug)"
+
 #ifndef __ASSEMBLY__
 extern u64			vabits_actual;
 #define PAGE_END		(_PAGE_END(vabits_actual))
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index ebc622432831..c4ac0ac25a00 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -49,7 +49,9 @@
 #ifndef CONFIG_BROKEN_GAS_INST
 
 #ifdef __ASSEMBLY__
-#define __emit_inst(x)			.inst (x)
+// The space separator is omitted so that __emit_inst(x) can be parsed as
+// either an assembler directive or an assembler macro argument.
+#define __emit_inst(x)			.inst(x)
 #else
 #define __emit_inst(x)			".inst " __stringify((x)) "\n\t"
 #endif
diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
index 803039d504de..3b859596840d 100644
--- a/arch/arm64/include/asm/unistd.h
+++ b/arch/arm64/include/asm/unistd.h
@@ -38,7 +38,7 @@
 #define __ARM_NR_compat_set_tls		(__ARM_NR_COMPAT_BASE + 5)
 #define __ARM_NR_COMPAT_END		(__ARM_NR_COMPAT_BASE + 0x800)
 
-#define __NR_compat_syscalls		439
+#define __NR_compat_syscalls		440
 #endif
 
 #define __ARCH_WANT_SYS_CLONE
diff --git a/arch/arm64/include/asm/unistd32.h b/arch/arm64/include/asm/unistd32.h
index c1c61635f89c..a1eec8d879d4 100644
--- a/arch/arm64/include/asm/unistd32.h
+++ b/arch/arm64/include/asm/unistd32.h
@@ -883,6 +883,8 @@ __SYSCALL(__NR_clone3, sys_clone3)
 __SYSCALL(__NR_openat2, sys_openat2)
 #define __NR_pidfd_getfd 438
 __SYSCALL(__NR_pidfd_getfd, sys_pidfd_getfd)
+#define __NR_process_madvise 439
+__SYSCALL(__NR_process_madvise, sys_process_madvise)
 
 /*
  * Please add new compat syscalls above this comment and update
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index 354b11e27c07..033a48f30dbb 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -260,18 +260,7 @@ static int __aarch32_alloc_vdso_pages(void)
 	if (ret)
 		return ret;
 
-	ret = aarch32_alloc_kuser_vdso_page();
-	if (ret) {
-		unsigned long c_vvar =
-			(unsigned long)page_to_virt(aarch32_vdso_pages[C_VVAR]);
-		unsigned long c_vdso =
-			(unsigned long)page_to_virt(aarch32_vdso_pages[C_VDSO]);
-
-		free_page(c_vvar);
-		free_page(c_vdso);
-	}
-
-	return ret;
+	return aarch32_alloc_kuser_vdso_page();
 }
 #else
 static int __aarch32_alloc_vdso_pages(void)
diff --git a/arch/csky/abiv2/mcount.S b/arch/csky/abiv2/mcount.S
index 9331c7ed5958..911512bf480f 100644
--- a/arch/csky/abiv2/mcount.S
+++ b/arch/csky/abiv2/mcount.S
@@ -103,6 +103,8 @@ ENTRY(_mcount)
 	mov	a0, lr
 	subi	a0, 4
 	ldw	a1, (sp, 24)
+	lrw	a2, function_trace_op
+	ldw	a2, (a2, 0)
 
 	jsr	r26
 
diff --git a/arch/csky/include/asm/thread_info.h b/arch/csky/include/asm/thread_info.h
index 442fedad0260..5d33fcfd7f2a 100644
--- a/arch/csky/include/asm/thread_info.h
+++ b/arch/csky/include/asm/thread_info.h
@@ -54,10 +54,10 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_SIGPENDING		0	/* signal pending */
 #define TIF_NOTIFY_RESUME	1       /* callback before returning to user */
 #define TIF_NEED_RESCHED	2	/* rescheduling necessary */
-#define TIF_SYSCALL_TRACE	3	/* syscall trace active */
-#define TIF_SYSCALL_TRACEPOINT	4       /* syscall tracepoint instrumentation */
-#define TIF_SYSCALL_AUDIT	5	/* syscall auditing */
-#define TIF_UPROBE		6	/* uprobe breakpoint or singlestep */
+#define TIF_UPROBE		3	/* uprobe breakpoint or singlestep */
+#define TIF_SYSCALL_TRACE	4	/* syscall trace active */
+#define TIF_SYSCALL_TRACEPOINT	5       /* syscall tracepoint instrumentation */
+#define TIF_SYSCALL_AUDIT	6	/* syscall auditing */
 #define TIF_POLLING_NRFLAG	16	/* poll_idle() is TIF_NEED_RESCHED */
 #define TIF_MEMDIE		18      /* is terminating due to OOM killer */
 #define TIF_RESTORE_SIGMASK	20	/* restore signal mask in do_signal() */
diff --git a/arch/csky/kernel/ftrace.c b/arch/csky/kernel/ftrace.c
index 44628e3f7fa6..3c425b84e3be 100644
--- a/arch/csky/kernel/ftrace.c
+++ b/arch/csky/kernel/ftrace.c
@@ -202,6 +202,7 @@ int ftrace_disable_ftrace_graph_caller(void)
 #endif /* CONFIG_DYNAMIC_FTRACE */
 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
 
+#ifdef CONFIG_DYNAMIC_FTRACE
 #ifndef CONFIG_CPU_HAS_ICACHE_INS
 struct ftrace_modify_param {
 	int command;
@@ -231,6 +232,7 @@ void arch_ftrace_update_code(int command)
 	stop_machine(__ftrace_modify_code, &param, cpu_online_mask);
 }
 #endif
+#endif /* CONFIG_DYNAMIC_FTRACE */
 
 /* _mcount is defined in abi's mcount.S */
 EXPORT_SYMBOL(_mcount);
diff --git a/arch/csky/kernel/probes/uprobes.c b/arch/csky/kernel/probes/uprobes.c
index b3a56c260e3e..1a9e0961b2b5 100644
--- a/arch/csky/kernel/probes/uprobes.c
+++ b/arch/csky/kernel/probes/uprobes.c
@@ -11,6 +11,11 @@
 
 #define UPROBE_TRAP_NR	UINT_MAX
 
+bool is_swbp_insn(uprobe_opcode_t *insn)
+{
+	return (*insn & 0xffff) == UPROBE_SWBP_INSN;
+}
+
 unsigned long uprobe_get_swbp_addr(struct pt_regs *regs)
 {
 	return instruction_pointer(regs);
diff --git a/arch/csky/kernel/ptrace.c b/arch/csky/kernel/ptrace.c
index 21ac2608f205..5a82230bddf9 100644
--- a/arch/csky/kernel/ptrace.c
+++ b/arch/csky/kernel/ptrace.c
@@ -41,6 +41,9 @@ static void singlestep_disable(struct task_struct *tsk)
 
 	regs = task_pt_regs(tsk);
 	regs->sr = (regs->sr & TRACE_MODE_MASK) | TRACE_MODE_RUN;
+
+	/* Enable irq */
+	regs->sr |= BIT(6);
 }
 
 static void singlestep_enable(struct task_struct *tsk)
@@ -49,6 +52,9 @@ static void singlestep_enable(struct task_struct *tsk)
 
 	regs = task_pt_regs(tsk);
 	regs->sr = (regs->sr & TRACE_MODE_MASK) | TRACE_MODE_SI;
+
+	/* Disable irq */
+	regs->sr &= ~BIT(6);
 }
 
 /*
diff --git a/arch/h8300/Kconfig.cpu b/arch/h8300/Kconfig.cpu
index b5e14d513e62..2b9cbaf41cd0 100644
--- a/arch/h8300/Kconfig.cpu
+++ b/arch/h8300/Kconfig.cpu
@@ -97,4 +97,8 @@ config OFFSET
         hex "Load offset"
 	default 0
 
+config BOOT_LINK_OFFSET
+	hex	"zImage link offset"
+	default	0x200000
+
 endmenu
diff --git a/arch/h8300/boot/dts/edosk2674.dts b/arch/h8300/boot/dts/edosk2674.dts
index d1733805ea67..f9731fe8c7d0 100644
--- a/arch/h8300/boot/dts/edosk2674.dts
+++ b/arch/h8300/boot/dts/edosk2674.dts
@@ -61,7 +61,7 @@ h8intc: interrupt-controller@fffe00 {
 		compatible = "renesas,h8s-intc", "renesas,h8300-intc";
 		#interrupt-cells = <2>;
 		interrupt-controller;
-		reg = <0xfffe00 24>;
+		reg = <0xfffe00 24>, <0xffff30 6>;
 	};
 
 	bsc: memory-controller@fffec0 {
@@ -79,7 +79,7 @@ tpu: timer@ffffe0 {
 	timer8: timer@ffffb0 {
 		compatible = "renesas,8bit-timer";
 		reg = <0xffffb0 10>;
-		interrupts = <72 0>;
+		interrupts = <72 0>, <73 0>, <74 0>;
 		clocks = <&fclk>;
 		clock-names = "fck";
 	};
@@ -105,4 +105,10 @@ sci2: serial@ffff88 {
 		clocks = <&fclk>;
 		clock-names = "fck";
 	};
+	ethernet: ethernet@f80000 {
+		compatible = "smsc,lan91c94";
+		reg = <0xf80000 0xfbffff>;
+		reg-io-width = <1>;
+		interrupts = <16 0>;
+	};
 };
diff --git a/arch/h8300/configs/edosk2674_defconfig b/arch/h8300/configs/edosk2674_defconfig
index 23791dcf6c25..bcf2edb8fff9 100644
--- a/arch/h8300/configs/edosk2674_defconfig
+++ b/arch/h8300/configs/edosk2674_defconfig
@@ -1,9 +1,7 @@
 # CONFIG_LOCALVERSION_AUTO is not set
-# CONFIG_USELIB is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_UID16 is not set
 # CONFIG_SYSFS_SYSCALL is not set
-# CONFIG_KALLSYMS is not set
 # CONFIG_BASE_FULL is not set
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
@@ -12,17 +10,17 @@ CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_EVENTFD is not set
 # CONFIG_AIO is not set
 # CONFIG_ADVISE_SYSCALLS is not set
+# CONFIG_KALLSYMS is not set
 CONFIG_EMBEDDED=y
 # CONFIG_VM_EVENT_COUNTERS is not set
 # CONFIG_COMPAT_BRK is not set
 CONFIG_SLOB=y
+CONFIG_BOOT_LINK_OFFSET=0x400000
+CONFIG_H8S_EDOSK2674=y
 # CONFIG_BLOCK is not set
-CONFIG_H8S_SIM=y
-CONFIG_H8300_BUILTIN_DTB="h8s_sim"
 # CONFIG_BINFMT_SCRIPT is not set
 CONFIG_BINFMT_FLAT=y
 # CONFIG_COREDUMP is not set
-# CONFIG_UEVENT_HELPER is not set
 # CONFIG_STANDALONE is not set
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FW_LOADER is not set
@@ -32,9 +30,7 @@ CONFIG_BINFMT_FLAT=y
 # CONFIG_VT is not set
 # CONFIG_UNIX98_PTYS is not set
 # CONFIG_LEGACY_PTYS is not set
-# CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_SH_SCI=y
-CONFIG_SERIAL_SH_SCI_CONSOLE=y
 # CONFIG_HW_RANDOM is not set
 # CONFIG_HWMON is not set
 # CONFIG_USB_SUPPORT is not set
diff --git a/arch/h8300/configs/h8300h-sim_defconfig b/arch/h8300/configs/h8300h-sim_defconfig
index 7fc9c2f0acc0..1b90399758f3 100644
--- a/arch/h8300/configs/h8300h-sim_defconfig
+++ b/arch/h8300/configs/h8300h-sim_defconfig
@@ -1,9 +1,7 @@
 # CONFIG_LOCALVERSION_AUTO is not set
-# CONFIG_USELIB is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_UID16 is not set
 # CONFIG_SYSFS_SYSCALL is not set
-# CONFIG_KALLSYMS is not set
 # CONFIG_BASE_FULL is not set
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
@@ -12,17 +10,17 @@ CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_EVENTFD is not set
 # CONFIG_AIO is not set
 # CONFIG_ADVISE_SYSCALLS is not set
+# CONFIG_KALLSYMS is not set
 CONFIG_EMBEDDED=y
 # CONFIG_VM_EVENT_COUNTERS is not set
 # CONFIG_COMPAT_BRK is not set
 CONFIG_SLOB=y
-# CONFIG_BLOCK is not set
 CONFIG_H8300H_SIM=y
 CONFIG_H8300_BUILTIN_DTB="h8300h_sim"
+# CONFIG_BLOCK is not set
 # CONFIG_BINFMT_SCRIPT is not set
 CONFIG_BINFMT_FLAT=y
 # CONFIG_COREDUMP is not set
-# CONFIG_UEVENT_HELPER is not set
 # CONFIG_STANDALONE is not set
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FW_LOADER is not set
@@ -32,9 +30,7 @@ CONFIG_BINFMT_FLAT=y
 # CONFIG_VT is not set
 # CONFIG_UNIX98_PTYS is not set
 # CONFIG_LEGACY_PTYS is not set
-# CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_SH_SCI=y
-CONFIG_SERIAL_SH_SCI_EARLYCON=y
 # CONFIG_HW_RANDOM is not set
 # CONFIG_HWMON is not set
 # CONFIG_USB_SUPPORT is not set
diff --git a/arch/h8300/configs/h8s-sim_defconfig b/arch/h8300/configs/h8s-sim_defconfig
index 23791dcf6c25..4d46adcc21a4 100644
--- a/arch/h8300/configs/h8s-sim_defconfig
+++ b/arch/h8300/configs/h8s-sim_defconfig
@@ -1,9 +1,7 @@
 # CONFIG_LOCALVERSION_AUTO is not set
-# CONFIG_USELIB is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_UID16 is not set
 # CONFIG_SYSFS_SYSCALL is not set
-# CONFIG_KALLSYMS is not set
 # CONFIG_BASE_FULL is not set
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
@@ -12,17 +10,17 @@ CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_EVENTFD is not set
 # CONFIG_AIO is not set
 # CONFIG_ADVISE_SYSCALLS is not set
+# CONFIG_KALLSYMS is not set
 CONFIG_EMBEDDED=y
 # CONFIG_VM_EVENT_COUNTERS is not set
 # CONFIG_COMPAT_BRK is not set
 CONFIG_SLOB=y
-# CONFIG_BLOCK is not set
 CONFIG_H8S_SIM=y
 CONFIG_H8300_BUILTIN_DTB="h8s_sim"
+# CONFIG_BLOCK is not set
 # CONFIG_BINFMT_SCRIPT is not set
 CONFIG_BINFMT_FLAT=y
 # CONFIG_COREDUMP is not set
-# CONFIG_UEVENT_HELPER is not set
 # CONFIG_STANDALONE is not set
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FW_LOADER is not set
@@ -32,9 +30,7 @@ CONFIG_BINFMT_FLAT=y
 # CONFIG_VT is not set
 # CONFIG_UNIX98_PTYS is not set
 # CONFIG_LEGACY_PTYS is not set
-# CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_SH_SCI=y
-CONFIG_SERIAL_SH_SCI_CONSOLE=y
 # CONFIG_HW_RANDOM is not set
 # CONFIG_HWMON is not set
 # CONFIG_USB_SUPPORT is not set
diff --git a/arch/h8300/lib/memset.S b/arch/h8300/lib/memset.S
index 2d1abc37fd08..df873779bb5e 100644
--- a/arch/h8300/lib/memset.S
+++ b/arch/h8300/lib/memset.S
@@ -19,13 +19,15 @@
 ;; c   = er1(r1l)
 ;; count = er2
 memset:
-	btst	#0,r0l
+	mov.l	er4,@-sp
+	mov.l	er0,er4
+	btst	#0,r4l
 	beq	2f
 
 	;; odd address
 1:
-	mov.b	r1l,@er0
-	adds	#1,er0
+	mov.b	r1l,@er4
+	adds	#1,er4
 	dec.l	#1,er2
 	beq	6f
 
@@ -46,8 +48,8 @@ memset:
 	mov.b	r1l,r1h
 	mov.w	r1,e1
 3:
-	mov.l	er1,@er0
-	adds	#4,er0
+	mov.l	er1,@er4
+	adds	#4,er4
 	dec.l	#1,er2
 	bne	3b
 4:
@@ -55,11 +57,12 @@ memset:
 	and.b	#3,r3l
 	beq	6f
 5:
-	mov.b	r1l,@er0
-	adds	#1,er0
+	mov.b	r1l,@er4
+	adds	#1,er4
 	dec.b	r3l
 	bne	5b
 6:
+	mov.l	@sp+,er4
 	rts
 
 clear_user:
diff --git a/arch/ia64/kernel/syscalls/syscall.tbl b/arch/ia64/kernel/syscalls/syscall.tbl
index 042911e670b8..9524af1c318c 100644
--- a/arch/ia64/kernel/syscalls/syscall.tbl
+++ b/arch/ia64/kernel/syscalls/syscall.tbl
@@ -358,3 +358,4 @@
 # 435 reserved for clone3
 437	common	openat2				sys_openat2
 438	common	pidfd_getfd			sys_pidfd_getfd
+439	common	process_madvise			sys_process_madvise
diff --git a/arch/m68k/include/asm/Kbuild b/arch/m68k/include/asm/Kbuild
index a0765aa60ea9..1bff55aa2d54 100644
--- a/arch/m68k/include/asm/Kbuild
+++ b/arch/m68k/include/asm/Kbuild
@@ -1,7 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 generated-y += syscall_table.h
 generic-y += extable.h
-generic-y += hardirq.h
 generic-y += kvm_para.h
 generic-y += local64.h
 generic-y += mcs_spinlock.h
diff --git a/arch/m68k/kernel/syscalls/syscall.tbl b/arch/m68k/kernel/syscalls/syscall.tbl
index f4f49fcb76d0..8197050c097c 100644
--- a/arch/m68k/kernel/syscalls/syscall.tbl
+++ b/arch/m68k/kernel/syscalls/syscall.tbl
@@ -437,3 +437,4 @@
 435	common	clone3				__sys_clone3
 437	common	openat2				sys_openat2
 438	common	pidfd_getfd			sys_pidfd_getfd
+439	common	process_madvise			sys_process_madvise
diff --git a/arch/microblaze/kernel/syscalls/syscall.tbl b/arch/microblaze/kernel/syscalls/syscall.tbl
index 4c67b11f9c9e..c5b6c8afe445 100644
--- a/arch/microblaze/kernel/syscalls/syscall.tbl
+++ b/arch/microblaze/kernel/syscalls/syscall.tbl
@@ -443,3 +443,4 @@
 435	common	clone3				sys_clone3
 437	common	openat2				sys_openat2
 438	common	pidfd_getfd			sys_pidfd_getfd
+439	common	process_madvise			sys_process_madvise
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 690718b3701a..4f9303f6a687 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -475,7 +475,7 @@ config MACH_LOONGSON64
 	select ISA
 	select I8259
 	select IRQ_MIPS_CPU
-	select NR_CPUS_DEFAULT_4
+	select NR_CPUS_DEFAULT_64
 	select USE_GENERIC_EARLY_PRINTK_8250
 	select SYS_HAS_CPU_LOONGSON64
 	select SYS_HAS_EARLY_PRINTK
diff --git a/arch/mips/include/asm/asm-eva.h b/arch/mips/include/asm/asm-eva.h
index d80be38c4144..e327ebc76753 100644
--- a/arch/mips/include/asm/asm-eva.h
+++ b/arch/mips/include/asm/asm-eva.h
@@ -180,7 +180,7 @@
 #define user_ld(reg, addr)		kernel_lw(reg, addr)
 #else
 #define user_sd(reg, addr)		kernel_sd(reg, addr)
-#define user_ld(reg, addr)		kernel_sd(reg, addr)
+#define user_ld(reg, addr)		kernel_ld(reg, addr)
 #endif /* CONFIG_32BIT */
 
 #endif /* CONFIG_EVA */
diff --git a/arch/mips/include/asm/clock.h b/arch/mips/include/asm/clock.h
deleted file mode 100644
index 5a8f96ebe5fa..000000000000
--- a/arch/mips/include/asm/clock.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __ASM_MIPS_CLOCK_H
-#define __ASM_MIPS_CLOCK_H
-
-#include <linux/kref.h>
-#include <linux/list.h>
-#include <linux/seq_file.h>
-#include <linux/clk.h>
-
-struct clk;
-
-struct clk_ops {
-	void (*init) (struct clk *clk);
-	void (*enable) (struct clk *clk);
-	void (*disable) (struct clk *clk);
-	void (*recalc) (struct clk *clk);
-	int (*set_rate) (struct clk *clk, unsigned long rate, int algo_id);
-	long (*round_rate) (struct clk *clk, unsigned long rate);
-};
-
-struct clk {
-	struct list_head node;
-	const char *name;
-	int id;
-	struct module *owner;
-
-	struct clk *parent;
-	struct clk_ops *ops;
-
-	struct kref kref;
-
-	unsigned long rate;
-	unsigned long flags;
-};
-
-#define CLK_ALWAYS_ENABLED	(1 << 0)
-#define CLK_RATE_PROPAGATES	(1 << 1)
-
-int clk_init(void);
-
-int __clk_enable(struct clk *);
-void __clk_disable(struct clk *);
-
-void clk_recalc_rate(struct clk *);
-
-int clk_register(struct clk *);
-void clk_unregister(struct clk *);
-
-#endif				/* __ASM_MIPS_CLOCK_H */
diff --git a/arch/mips/include/asm/mach-generic/irq.h b/arch/mips/include/asm/mach-generic/irq.h
index be546a0f65fa..72ac2c202c55 100644
--- a/arch/mips/include/asm/mach-generic/irq.h
+++ b/arch/mips/include/asm/mach-generic/irq.h
@@ -36,10 +36,4 @@
 
 #endif /* CONFIG_IRQ_MIPS_CPU */
 
-#ifdef CONFIG_MIPS_GIC
-#ifndef MIPS_GIC_IRQ_BASE
-#define MIPS_GIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + 8)
-#endif
-#endif /* CONFIG_MIPS_GIC */
-
 #endif /* __ASM_MACH_GENERIC_IRQ_H */
diff --git a/arch/mips/include/asm/mach-loongson2ef/loongson.h b/arch/mips/include/asm/mach-loongson2ef/loongson.h
index 5008af0a1a19..57e571128489 100644
--- a/arch/mips/include/asm/mach-loongson2ef/loongson.h
+++ b/arch/mips/include/asm/mach-loongson2ef/loongson.h
@@ -244,6 +244,7 @@ static inline void do_perfcnt_IRQ(void)
 #ifdef CONFIG_CPU_SUPPORTS_CPUFREQ
 #include <linux/cpufreq.h>
 extern struct cpufreq_frequency_table loongson2_clockmod_table[];
+extern int loongson2_cpu_set_rate(unsigned long rate_khz);
 #endif
 
 /*
diff --git a/arch/mips/include/asm/mach-ralink/mt7621.h b/arch/mips/include/asm/mach-ralink/mt7621.h
index 65483a4681ab..e1af1ba50bd8 100644
--- a/arch/mips/include/asm/mach-ralink/mt7621.h
+++ b/arch/mips/include/asm/mach-ralink/mt7621.h
@@ -31,6 +31,4 @@
 #define MT7621_CHIP_NAME0		0x3637544D
 #define MT7621_CHIP_NAME1		0x20203132
 
-#define MIPS_GIC_IRQ_BASE           (MIPS_CPU_IRQ_BASE + 8)
-
 #endif
diff --git a/arch/mips/include/asm/mach-xilfpga/irq.h b/arch/mips/include/asm/mach-xilfpga/irq.h
deleted file mode 100644
index 15ad29ec1dee..000000000000
--- a/arch/mips/include/asm/mach-xilfpga/irq.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Copyright (C) 2015 Imagination Technologies
- * Author: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>
- */
-
-#ifndef __MIPS_ASM_MACH_XILFPGA_IRQ_H__
-#define __MIPS_ASM_MACH_XILFPGA_IRQ_H__
-
-#define NR_IRQS 32
-
-#include <asm/mach-generic/irq.h>
-
-#endif /* __MIPS_ASM_MACH_XILFPGA_IRQ_H__ */
diff --git a/arch/mips/include/asm/pgtable-64.h b/arch/mips/include/asm/pgtable-64.h
index f92716cfa4f4..ee5dc0c145b9 100644
--- a/arch/mips/include/asm/pgtable-64.h
+++ b/arch/mips/include/asm/pgtable-64.h
@@ -172,6 +172,8 @@
 
 extern pte_t invalid_pte_table[PTRS_PER_PTE];
 
+#define pud_index(address)	(((address) >> PUD_SHIFT) & (PTRS_PER_PUD - 1))
+
 #ifndef __PAGETABLE_PUD_FOLDED
 /*
  * For 4-level pagetables we defines these ourselves, for 3-level the
@@ -210,8 +212,6 @@ static inline void p4d_clear(p4d_t *p4dp)
 	p4d_val(*p4dp) = (unsigned long)invalid_pud_table;
 }
 
-#define pud_index(address)	(((address) >> PUD_SHIFT) & (PTRS_PER_PUD - 1))
-
 static inline unsigned long p4d_page_vaddr(p4d_t p4d)
 {
 	return p4d_val(p4d);
diff --git a/arch/mips/kernel/syscalls/syscall_n32.tbl b/arch/mips/kernel/syscalls/syscall_n32.tbl
index 1f9e8ad636cc..8ec8c558aa9c 100644
--- a/arch/mips/kernel/syscalls/syscall_n32.tbl
+++ b/arch/mips/kernel/syscalls/syscall_n32.tbl
@@ -376,3 +376,4 @@
 435	n32	clone3				__sys_clone3
 437	n32	openat2				sys_openat2
 438	n32	pidfd_getfd			sys_pidfd_getfd
+439	n32	process_madvise			sys_process_madvise
diff --git a/arch/mips/kernel/syscalls/syscall_n64.tbl b/arch/mips/kernel/syscalls/syscall_n64.tbl
index c0b9d802dbf6..0078f891bb92 100644
--- a/arch/mips/kernel/syscalls/syscall_n64.tbl
+++ b/arch/mips/kernel/syscalls/syscall_n64.tbl
@@ -352,3 +352,4 @@
 435	n64	clone3				__sys_clone3
 437	n64	openat2				sys_openat2
 438	n64	pidfd_getfd			sys_pidfd_getfd
+439	n64	process_madvise			sys_process_madvise
diff --git a/arch/mips/loongson2ef/Kconfig b/arch/mips/loongson2ef/Kconfig
index 595dd48e1e4d..96dc6eba4310 100644
--- a/arch/mips/loongson2ef/Kconfig
+++ b/arch/mips/loongson2ef/Kconfig
@@ -46,7 +46,6 @@ config LEMOTE_MACH2F
 	select CSRC_R4K if ! MIPS_EXTERNAL_TIMER
 	select DMA_NONCOHERENT
 	select GENERIC_ISA_DMA_SUPPORT_BROKEN
-	select HAVE_CLK
 	select FORCE_PCI
 	select I8259
 	select IRQ_MIPS_CPU
diff --git a/arch/mips/loongson2ef/lemote-2f/clock.c b/arch/mips/loongson2ef/lemote-2f/clock.c
index 414f282c8ab5..850b6b9f8f15 100644
--- a/arch/mips/loongson2ef/lemote-2f/clock.c
+++ b/arch/mips/loongson2ef/lemote-2f/clock.c
@@ -6,22 +6,12 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  */
-#include <linux/clk.h>
 #include <linux/cpufreq.h>
 #include <linux/errno.h>
 #include <linux/export.h>
-#include <linux/list.h>
-#include <linux/mutex.h>
-#include <linux/spinlock.h>
 
-#include <asm/clock.h>
 #include <asm/mach-loongson2ef/loongson.h>
 
-static LIST_HEAD(clock_list);
-static DEFINE_SPINLOCK(clock_lock);
-static DEFINE_MUTEX(clock_list_sem);
-
-/* Minimum CLK support */
 enum {
 	DC_ZERO, DC_25PT = 2, DC_37PT, DC_50PT, DC_62PT, DC_75PT,
 	DC_87PT, DC_DISABLE, DC_RESV
@@ -41,103 +31,21 @@ struct cpufreq_frequency_table loongson2_clockmod_table[] = {
 };
 EXPORT_SYMBOL_GPL(loongson2_clockmod_table);
 
-static struct clk cpu_clk = {
-	.name = "cpu_clk",
-	.flags = CLK_ALWAYS_ENABLED | CLK_RATE_PROPAGATES,
-	.rate = 800000000,
-};
-
-struct clk *clk_get(struct device *dev, const char *id)
-{
-	return &cpu_clk;
-}
-EXPORT_SYMBOL(clk_get);
-
-static void propagate_rate(struct clk *clk)
-{
-	struct clk *clkp;
-
-	list_for_each_entry(clkp, &clock_list, node) {
-		if (likely(clkp->parent != clk))
-			continue;
-		if (likely(clkp->ops && clkp->ops->recalc))
-			clkp->ops->recalc(clkp);
-		if (unlikely(clkp->flags & CLK_RATE_PROPAGATES))
-			propagate_rate(clkp);
-	}
-}
-
-int clk_enable(struct clk *clk)
-{
-	return 0;
-}
-EXPORT_SYMBOL(clk_enable);
-
-void clk_disable(struct clk *clk)
+int loongson2_cpu_set_rate(unsigned long rate_khz)
 {
-}
-EXPORT_SYMBOL(clk_disable);
-
-unsigned long clk_get_rate(struct clk *clk)
-{
-	if (!clk)
-		return 0;
-
-	return (unsigned long)clk->rate;
-}
-EXPORT_SYMBOL(clk_get_rate);
-
-void clk_put(struct clk *clk)
-{
-}
-EXPORT_SYMBOL(clk_put);
-
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
-	unsigned int rate_khz = rate / 1000;
 	struct cpufreq_frequency_table *pos;
-	int ret = 0;
 	int regval;
 
-	if (likely(clk->ops && clk->ops->set_rate)) {
-		unsigned long flags;
-
-		spin_lock_irqsave(&clock_lock, flags);
-		ret = clk->ops->set_rate(clk, rate, 0);
-		spin_unlock_irqrestore(&clock_lock, flags);
-	}
-
-	if (unlikely(clk->flags & CLK_RATE_PROPAGATES))
-		propagate_rate(clk);
-
 	cpufreq_for_each_valid_entry(pos, loongson2_clockmod_table)
 		if (rate_khz == pos->frequency)
 			break;
 	if (rate_khz != pos->frequency)
 		return -ENOTSUPP;
 
-	clk->rate = rate;
-
 	regval = readl(LOONGSON_CHIPCFG);
 	regval = (regval & ~0x7) | (pos->driver_data - 1);
 	writel(regval, LOONGSON_CHIPCFG);
 
-	return ret;
-}
-EXPORT_SYMBOL_GPL(clk_set_rate);
-
-long clk_round_rate(struct clk *clk, unsigned long rate)
-{
-	if (likely(clk->ops && clk->ops->round_rate)) {
-		unsigned long flags, rounded;
-
-		spin_lock_irqsave(&clock_lock, flags);
-		rounded = clk->ops->round_rate(clk, rate);
-		spin_unlock_irqrestore(&clock_lock, flags);
-
-		return rounded;
-	}
-
-	return rate;
+	return 0;
 }
-EXPORT_SYMBOL_GPL(clk_round_rate);
+EXPORT_SYMBOL_GPL(loongson2_cpu_set_rate);
diff --git a/arch/mips/loongson64/smp.c b/arch/mips/loongson64/smp.c
index e1fe8bbb377d..e744e1bee49e 100644
--- a/arch/mips/loongson64/smp.c
+++ b/arch/mips/loongson64/smp.c
@@ -15,7 +15,6 @@
 #include <linux/kexec.h>
 #include <asm/processor.h>
 #include <asm/time.h>
-#include <asm/clock.h>
 #include <asm/tlbflush.h>
 #include <asm/cacheflush.h>
 #include <loongson.h>
diff --git a/arch/mips/txx9/Kconfig b/arch/mips/txx9/Kconfig
index 9a22a182b7a4..85c4c121c71f 100644
--- a/arch/mips/txx9/Kconfig
+++ b/arch/mips/txx9/Kconfig
@@ -58,7 +58,7 @@ config TOSHIBA_RBTX4939
 config SOC_TX3927
 	bool
 	select CEVT_TXX9
-	select HAS_TXX9_SERIAL
+	imply HAS_TXX9_SERIAL
 	select HAVE_PCI
 	select IRQ_TXX9
 	select GPIO_TXX9
@@ -66,30 +66,30 @@ config SOC_TX3927
 config SOC_TX4927
 	bool
 	select CEVT_TXX9
-	select HAS_TXX9_SERIAL
+	imply HAS_TXX9_SERIAL
 	select HAVE_PCI
 	select IRQ_TXX9
 	select PCI_TX4927
 	select GPIO_TXX9
-	select HAS_TXX9_ACLC
+	imply HAS_TXX9_ACLC
 
 config SOC_TX4938
 	bool
 	select CEVT_TXX9
-	select HAS_TXX9_SERIAL
+	imply HAS_TXX9_SERIAL
 	select HAVE_PCI
 	select IRQ_TXX9
 	select PCI_TX4927
 	select GPIO_TXX9
-	select HAS_TXX9_ACLC
+	imply HAS_TXX9_ACLC
 
 config SOC_TX4939
 	bool
 	select CEVT_TXX9
-	select HAS_TXX9_SERIAL
+	imply HAS_TXX9_SERIAL
 	select HAVE_PCI
 	select PCI_TX4927
-	select HAS_TXX9_ACLC
+	imply HAS_TXX9_ACLC
 
 config TXX9_7SEGLED
 	bool
diff --git a/arch/nds32/configs/defconfig b/arch/nds32/configs/defconfig
index 40313a635075..f9a89cf00aa6 100644
--- a/arch/nds32/configs/defconfig
+++ b/arch/nds32/configs/defconfig
@@ -1,4 +1,3 @@
-CONFIG_CROSS_COMPILE="nds32le-linux-"
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
 CONFIG_HIGH_RES_TIMERS=y
diff --git a/arch/nds32/kernel/time.c b/arch/nds32/kernel/time.c
index ac9d78ce3a81..574a3d0a8539 100644
--- a/arch/nds32/kernel/time.c
+++ b/arch/nds32/kernel/time.c
@@ -2,7 +2,7 @@
 // Copyright (C) 2005-2017 Andes Technology Corporation
 
 #include <linux/clocksource.h>
-#include <linux/clk-provider.h>
+#include <linux/of_clk.h>
 
 void __init time_init(void)
 {
diff --git a/arch/parisc/kernel/syscalls/syscall.tbl b/arch/parisc/kernel/syscalls/syscall.tbl
index 52a15f5cd130..09c3b5dc6855 100644
--- a/arch/parisc/kernel/syscalls/syscall.tbl
+++ b/arch/parisc/kernel/syscalls/syscall.tbl
@@ -435,3 +435,4 @@
 435	common	clone3				sys_clone3_wrapper
 437	common	openat2				sys_openat2
 438	common	pidfd_getfd			sys_pidfd_getfd
+439	common	process_madvise			sys_process_madvise
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 924c541a9260..4e89f22cdd27 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -116,6 +116,7 @@ config PPC
 	#
 	select ARCH_32BIT_OFF_T if PPC32
 	select ARCH_HAS_DEBUG_VIRTUAL
+	select ARCH_HAS_DEBUG_VM_PGTABLE
 	select ARCH_HAS_DEVMEM_IS_ALLOWED
 	select ARCH_HAS_ELF_RANDOMIZE
 	select ARCH_HAS_FORTIFY_SOURCE
diff --git a/arch/powerpc/kernel/syscalls/syscall.tbl b/arch/powerpc/kernel/syscalls/syscall.tbl
index 220ae11555f2..8a0c7239a6f3 100644
--- a/arch/powerpc/kernel/syscalls/syscall.tbl
+++ b/arch/powerpc/kernel/syscalls/syscall.tbl
@@ -527,3 +527,4 @@
 435	spu	clone3				sys_ni_syscall
 437	common	openat2				sys_openat2
 438	common	pidfd_getfd			sys_pidfd_getfd
+439	common	process_madvise			sys_process_madvise
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index a197258595ef..62f7bfeb709e 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -55,7 +55,7 @@ config RISCV
 	select ARCH_HAS_PTE_SPECIAL
 	select ARCH_HAS_MMIOWB
 	select ARCH_HAS_DEBUG_VIRTUAL
-	select HAVE_EBPF_JIT
+	select HAVE_EBPF_JIT if MMU
 	select EDAC_SUPPORT
 	select ARCH_HAS_GIGANTIC_PAGE
 	select ARCH_HAS_SET_DIRECT_MAP
diff --git a/arch/riscv/net/bpf_jit_comp64.c b/arch/riscv/net/bpf_jit_comp64.c
index cc1985d8750a..d208a9fd6c52 100644
--- a/arch/riscv/net/bpf_jit_comp64.c
+++ b/arch/riscv/net/bpf_jit_comp64.c
@@ -110,6 +110,16 @@ static bool is_32b_int(s64 val)
 	return -(1L << 31) <= val && val < (1L << 31);
 }
 
+static bool in_auipc_jalr_range(s64 val)
+{
+	/*
+	 * auipc+jalr can reach any signed PC-relative offset in the range
+	 * [-2^31 - 2^11, 2^31 - 2^11).
+	 */
+	return (-(1L << 31) - (1L << 11)) <= val &&
+		val < ((1L << 31) - (1L << 11));
+}
+
 static void emit_imm(u8 rd, s64 val, struct rv_jit_context *ctx)
 {
 	/* Note that the immediate from the add is sign-extended,
@@ -380,20 +390,24 @@ static void emit_sext_32_rd(u8 *rd, struct rv_jit_context *ctx)
 	*rd = RV_REG_T2;
 }
 
-static void emit_jump_and_link(u8 rd, s64 rvoff, bool force_jalr,
-			       struct rv_jit_context *ctx)
+static int emit_jump_and_link(u8 rd, s64 rvoff, bool force_jalr,
+			      struct rv_jit_context *ctx)
 {
 	s64 upper, lower;
 
 	if (rvoff && is_21b_int(rvoff) && !force_jalr) {
 		emit(rv_jal(rd, rvoff >> 1), ctx);
-		return;
+		return 0;
+	} else if (in_auipc_jalr_range(rvoff)) {
+		upper = (rvoff + (1 << 11)) >> 12;
+		lower = rvoff & 0xfff;
+		emit(rv_auipc(RV_REG_T1, upper), ctx);
+		emit(rv_jalr(rd, RV_REG_T1, lower), ctx);
+		return 0;
 	}
 
-	upper = (rvoff + (1 << 11)) >> 12;
-	lower = rvoff & 0xfff;
-	emit(rv_auipc(RV_REG_T1, upper), ctx);
-	emit(rv_jalr(rd, RV_REG_T1, lower), ctx);
+	pr_err("bpf-jit: target offset 0x%llx is out of range\n", rvoff);
+	return -ERANGE;
 }
 
 static bool is_signed_bpf_cond(u8 cond)
@@ -407,18 +421,16 @@ static int emit_call(bool fixed, u64 addr, struct rv_jit_context *ctx)
 	s64 off = 0;
 	u64 ip;
 	u8 rd;
+	int ret;
 
 	if (addr && ctx->insns) {
 		ip = (u64)(long)(ctx->insns + ctx->ninsns);
 		off = addr - ip;
-		if (!is_32b_int(off)) {
-			pr_err("bpf-jit: target call addr %pK is out of range\n",
-			       (void *)addr);
-			return -ERANGE;
-		}
 	}
 
-	emit_jump_and_link(RV_REG_RA, off, !fixed, ctx);
+	ret = emit_jump_and_link(RV_REG_RA, off, !fixed, ctx);
+	if (ret)
+		return ret;
 	rd = bpf_to_rv_reg(BPF_REG_0, ctx);
 	emit(rv_addi(rd, RV_REG_A0, 0), ctx);
 	return 0;
@@ -429,7 +441,7 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
 {
 	bool is64 = BPF_CLASS(insn->code) == BPF_ALU64 ||
 		    BPF_CLASS(insn->code) == BPF_JMP;
-	int s, e, rvoff, i = insn - ctx->prog->insnsi;
+	int s, e, rvoff, ret, i = insn - ctx->prog->insnsi;
 	struct bpf_prog_aux *aux = ctx->prog->aux;
 	u8 rd = -1, rs = -1, code = insn->code;
 	s16 off = insn->off;
@@ -699,7 +711,9 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
 	/* JUMP off */
 	case BPF_JMP | BPF_JA:
 		rvoff = rv_offset(i, off, ctx);
-		emit_jump_and_link(RV_REG_ZERO, rvoff, false, ctx);
+		ret = emit_jump_and_link(RV_REG_ZERO, rvoff, false, ctx);
+		if (ret)
+			return ret;
 		break;
 
 	/* IF (dst COND src) JUMP off */
@@ -801,7 +815,6 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
 	case BPF_JMP | BPF_CALL:
 	{
 		bool fixed;
-		int ret;
 		u64 addr;
 
 		mark_call(ctx);
@@ -826,7 +839,9 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
 			break;
 
 		rvoff = epilogue_offset(ctx);
-		emit_jump_and_link(RV_REG_ZERO, rvoff, false, ctx);
+		ret = emit_jump_and_link(RV_REG_ZERO, rvoff, false, ctx);
+		if (ret)
+			return ret;
 		break;
 
 	/* dst = imm64 */
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 2167bce993ff..8206b2c19aa8 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -59,6 +59,7 @@ config KASAN_SHADOW_OFFSET
 config S390
 	def_bool y
 	select ARCH_BINFMT_ELF_STATE
+	select ARCH_HAS_DEBUG_VM_PGTABLE
 	select ARCH_HAS_DEVMEM_IS_ALLOWED
 	select ARCH_HAS_ELF_RANDOMIZE
 	select ARCH_HAS_FORTIFY_SOURCE
diff --git a/arch/s390/kernel/syscalls/syscall.tbl b/arch/s390/kernel/syscalls/syscall.tbl
index bd7bd3581a0f..8dc8bfd958ea 100644
--- a/arch/s390/kernel/syscalls/syscall.tbl
+++ b/arch/s390/kernel/syscalls/syscall.tbl
@@ -440,3 +440,4 @@
 435  common	clone3			sys_clone3			sys_clone3
 437  common	openat2			sys_openat2			sys_openat2
 438  common	pidfd_getfd		sys_pidfd_getfd			sys_pidfd_getfd
+439  common	process_madvise		sys_process_madvise		sys_process_madvise
diff --git a/arch/sh/include/asm/cache.h b/arch/sh/include/asm/cache.h
index 2408ac4873aa..07ddf31124a3 100644
--- a/arch/sh/include/asm/cache.h
+++ b/arch/sh/include/asm/cache.h
@@ -15,7 +15,7 @@
 
 #define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
 
-#define __read_mostly __attribute__((__section__(".data..read_mostly")))
+#define __read_mostly __section(.data..read_mostly)
 
 #ifndef __ASSEMBLY__
 struct cache_info {
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index 59673f8a3379..ef65f0625c6c 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -47,5 +47,3 @@ obj-$(CONFIG_DWARF_UNWINDER)	+= dwarf.o
 obj-$(CONFIG_PERF_EVENTS)	+= perf_event.o perf_callchain.o
 obj-$(CONFIG_DMA_NONCOHERENT)	+= dma-coherent.o
 obj-$(CONFIG_HAVE_HW_BREAKPOINT)		+= hw_breakpoint.o
-
-ccflags-y := -Werror
diff --git a/arch/sh/kernel/sh_ksyms_32.c b/arch/sh/kernel/sh_ksyms_32.c
index 282774472603..5858936cb431 100644
--- a/arch/sh/kernel/sh_ksyms_32.c
+++ b/arch/sh/kernel/sh_ksyms_32.c
@@ -38,6 +38,13 @@ DECLARE_EXPORT(__ashlsi3);
 DECLARE_EXPORT(__lshrsi3_r0);
 DECLARE_EXPORT(__ashrsi3_r0);
 DECLARE_EXPORT(__ashlsi3_r0);
+
+DECLARE_EXPORT(__ashiftrt_r4_0);
+DECLARE_EXPORT(__ashiftrt_r4_1);
+DECLARE_EXPORT(__ashiftrt_r4_2);
+DECLARE_EXPORT(__ashiftrt_r4_3);
+DECLARE_EXPORT(__ashiftrt_r4_4);
+DECLARE_EXPORT(__ashiftrt_r4_5);
 DECLARE_EXPORT(__ashiftrt_r4_6);
 DECLARE_EXPORT(__ashiftrt_r4_7);
 DECLARE_EXPORT(__ashiftrt_r4_8);
@@ -48,13 +55,23 @@ DECLARE_EXPORT(__ashiftrt_r4_12);
 DECLARE_EXPORT(__ashiftrt_r4_13);
 DECLARE_EXPORT(__ashiftrt_r4_14);
 DECLARE_EXPORT(__ashiftrt_r4_15);
+DECLARE_EXPORT(__ashiftrt_r4_16);
+DECLARE_EXPORT(__ashiftrt_r4_17);
+DECLARE_EXPORT(__ashiftrt_r4_18);
+DECLARE_EXPORT(__ashiftrt_r4_19);
 DECLARE_EXPORT(__ashiftrt_r4_20);
 DECLARE_EXPORT(__ashiftrt_r4_21);
 DECLARE_EXPORT(__ashiftrt_r4_22);
 DECLARE_EXPORT(__ashiftrt_r4_23);
 DECLARE_EXPORT(__ashiftrt_r4_24);
+DECLARE_EXPORT(__ashiftrt_r4_25);
+DECLARE_EXPORT(__ashiftrt_r4_26);
 DECLARE_EXPORT(__ashiftrt_r4_27);
+DECLARE_EXPORT(__ashiftrt_r4_28);
+DECLARE_EXPORT(__ashiftrt_r4_29);
 DECLARE_EXPORT(__ashiftrt_r4_30);
+DECLARE_EXPORT(__ashiftrt_r4_31);
+DECLARE_EXPORT(__ashiftrt_r4_32);
 DECLARE_EXPORT(__movstr);
 DECLARE_EXPORT(__movstrSI8);
 DECLARE_EXPORT(__movstrSI12);
diff --git a/arch/sh/kernel/syscalls/syscall.tbl b/arch/sh/kernel/syscalls/syscall.tbl
index c7a30fcd135f..e69d98040777 100644
--- a/arch/sh/kernel/syscalls/syscall.tbl
+++ b/arch/sh/kernel/syscalls/syscall.tbl
@@ -440,3 +440,4 @@
 # 435 reserved for clone3
 437	common	openat2				sys_openat2
 438	common	pidfd_getfd			sys_pidfd_getfd
+439	common	process_madvise			sys_process_madvise
diff --git a/arch/sh/lib/delay.c b/arch/sh/lib/delay.c
index dad8e6a54906..540e670dbafc 100644
--- a/arch/sh/lib/delay.c
+++ b/arch/sh/lib/delay.c
@@ -29,6 +29,7 @@ void __delay(unsigned long loops)
 		: "0" (loops)
 		: "t");
 }
+EXPORT_SYMBOL(__delay);
 
 inline void __const_udelay(unsigned long xloops)
 {
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index b9de2d4fa57e..8d2a68aea1fc 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -412,7 +412,7 @@ int arch_add_memory(int nid, u64 start, u64 size,
 	unsigned long nr_pages = size >> PAGE_SHIFT;
 	int ret;
 
-	if (WARN_ON_ONCE(params->pgprot.pgprot != PAGE_KERNEL.pgprot)
+	if (WARN_ON_ONCE(params->pgprot.pgprot != PAGE_KERNEL.pgprot))
 		return -EINVAL;
 
 	/* We only have ZONE_NORMAL, so this is easy.. */
diff --git a/arch/sparc/kernel/syscalls/syscall.tbl b/arch/sparc/kernel/syscalls/syscall.tbl
index f13615ecdecc..6f6e66dd51f9 100644
--- a/arch/sparc/kernel/syscalls/syscall.tbl
+++ b/arch/sparc/kernel/syscalls/syscall.tbl
@@ -483,3 +483,4 @@
 # 435 reserved for clone3
 437	common	openat2			sys_openat2
 438	common	pidfd_getfd			sys_pidfd_getfd
+439	common	process_madvise			sys_process_madvise
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 1d6104ea8af0..b07f179c2887 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -59,6 +59,7 @@ config X86
 	select ARCH_CLOCKSOURCE_INIT
 	select ARCH_HAS_ACPI_TABLE_UPGRADE	if ACPI
 	select ARCH_HAS_DEBUG_VIRTUAL
+	select ARCH_HAS_DEBUG_VM_PGTABLE	if !X86_PAE
 	select ARCH_HAS_DEVMEM_IS_ALLOWED
 	select ARCH_HAS_ELF_RANDOMIZE
 	select ARCH_HAS_FAST_MULTIPLIER
@@ -138,6 +139,7 @@ config X86
 	select HAVE_ARCH_JUMP_LABEL_RELATIVE
 	select HAVE_ARCH_KASAN			if X86_64
 	select HAVE_ARCH_KASAN_VMALLOC		if X86_64
+	select HAVE_ARCH_KCSAN			if X86_64
 	select HAVE_ARCH_KGDB
 	select HAVE_ARCH_MMAP_RND_BITS		if MMU
 	select HAVE_ARCH_MMAP_RND_COMPAT_BITS	if MMU && COMPAT
@@ -229,6 +231,7 @@ config X86
 	select THREAD_INFO_IN_TASK
 	select USER_STACKTRACE_SUPPORT
 	select VIRT_TO_BUS
+	select HAVE_ARCH_KCSAN			if X86_64
 	select X86_FEATURE_NAMES		if PROC_FS
 	select PROC_PID_ARCH_STATUS		if PROC_FS
 	imply IMA_SECURE_AND_OR_TRUSTED_BOOT    if EFI
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
index 2e74690b028a..f909d3ce36e6 100644
--- a/arch/x86/Kconfig.debug
+++ b/arch/x86/Kconfig.debug
@@ -99,15 +99,6 @@ config DEBUG_WX
 
 	  If in doubt, say "Y".
 
-config DOUBLEFAULT
-	default y
-	bool "Enable doublefault exception handler" if EXPERT && X86_32
-	---help---
-	  This option allows trapping of rare doublefault exceptions that
-	  would otherwise cause a system to silently reboot. Disabling this
-	  option saves about 4k and might cause you much additional grey
-	  hair.
-
 config DEBUG_TLBFLUSH
 	bool "Set upper limit of TLB entries to flush one-by-one"
 	depends on DEBUG_KERNEL
diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile
index e17be90ab312..d7aa1c3a6b25 100644
--- a/arch/x86/boot/Makefile
+++ b/arch/x86/boot/Makefile
@@ -9,7 +9,9 @@
 # Changed by many, many contributors over the years.
 #
 
+# Sanitizer runtimes are unavailable and cannot be linked for early boot code.
 KASAN_SANITIZE			:= n
+KCSAN_SANITIZE			:= n
 OBJECT_FILES_NON_STANDARD	:= y
 
 # Kernel does not boot with kcov instrumentation here.
diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
index 5f7c262bcc99..7619742f91c9 100644
--- a/arch/x86/boot/compressed/Makefile
+++ b/arch/x86/boot/compressed/Makefile
@@ -17,7 +17,9 @@
 #	(see scripts/Makefile.lib size_append)
 #	compressed vmlinux.bin.all + u32 size of vmlinux.bin.all
 
+# Sanitizer runtimes are unavailable and cannot be linked for early boot code.
 KASAN_SANITIZE			:= n
+KCSAN_SANITIZE			:= n
 OBJECT_FILES_NON_STANDARD	:= y
 
 # Prevents link failures: __sanitizer_cov_trace_pc() is not linked in.
diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S
index b67bae7091d7..5c9c7eee6325 100644
--- a/arch/x86/entry/entry_32.S
+++ b/arch/x86/entry/entry_32.S
@@ -1536,7 +1536,6 @@ SYM_CODE_START(debug)
 	jmp	common_exception
 SYM_CODE_END(debug)
 
-#ifdef CONFIG_DOUBLEFAULT
 SYM_CODE_START(double_fault)
 1:
 	/*
@@ -1576,7 +1575,6 @@ SYM_CODE_START(double_fault)
 	hlt
 	jmp 1b
 SYM_CODE_END(double_fault)
-#endif
 
 /*
  * NMI is doubly nasty.  It can happen on the first instruction of
diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl
index 54581ac671b4..90950255ae5c 100644
--- a/arch/x86/entry/syscalls/syscall_32.tbl
+++ b/arch/x86/entry/syscalls/syscall_32.tbl
@@ -442,3 +442,4 @@
 435	i386	clone3			sys_clone3
 437	i386	openat2			sys_openat2
 438	i386	pidfd_getfd		sys_pidfd_getfd
+439	i386	process_madvise		sys_process_madvise
diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl
index 37b844f839bc..bcf0d6d0dffe 100644
--- a/arch/x86/entry/syscalls/syscall_64.tbl
+++ b/arch/x86/entry/syscalls/syscall_64.tbl
@@ -359,6 +359,7 @@
 435	common	clone3			sys_clone3
 437	common	openat2			sys_openat2
 438	common	pidfd_getfd		sys_pidfd_getfd
+439	common	process_madvise		sys_process_madvise
 
 #
 # x32-specific system call numbers start at 512 to avoid cache impact
diff --git a/arch/x86/entry/vdso/Makefile b/arch/x86/entry/vdso/Makefile
index 433a1259f61d..ecf6128c9551 100644
--- a/arch/x86/entry/vdso/Makefile
+++ b/arch/x86/entry/vdso/Makefile
@@ -10,8 +10,11 @@ ARCH_REL_TYPE_ABS += R_386_GLOB_DAT|R_386_JMP_SLOT|R_386_RELATIVE
 include $(srctree)/lib/vdso/Makefile
 
 KBUILD_CFLAGS += $(DISABLE_LTO)
+
+# Sanitizer runtimes are unavailable and cannot be linked here.
 KASAN_SANITIZE			:= n
 UBSAN_SANITIZE			:= n
+KCSAN_SANITIZE			:= n
 OBJECT_FILES_NON_STANDARD	:= y
 
 # Prevents link failures: __sanitizer_cov_trace_pc() is not linked in.
@@ -27,6 +30,9 @@ vobjs-y := vdso-note.o vclock_gettime.o vgetcpu.o
 
 # files to link into kernel
 obj-y				+= vma.o
+KASAN_SANITIZE_vma.o		:= y
+UBSAN_SANITIZE_vma.o		:= y
+KCSAN_SANITIZE_vma.o		:= y
 OBJECT_FILES_NON_STANDARD_vma.o	:= n
 
 # vDSO images to build
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index b0da5320bcff..624f5d9b0f79 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -20,6 +20,7 @@
 #include <linux/mm.h>
 #include <linux/hyperv.h>
 #include <linux/slab.h>
+#include <linux/kernel.h>
 #include <linux/cpuhotplug.h>
 #include <linux/syscore_ops.h>
 #include <clocksource/hyperv_timer.h>
@@ -419,11 +420,14 @@ void hyperv_cleanup(void)
 }
 EXPORT_SYMBOL_GPL(hyperv_cleanup);
 
-void hyperv_report_panic(struct pt_regs *regs, long err)
+void hyperv_report_panic(struct pt_regs *regs, long err, bool in_die)
 {
 	static bool panic_reported;
 	u64 guest_id;
 
+	if (in_die && !panic_on_oops)
+		return;
+
 	/*
 	 * We prefer to report panic on 'die' chain as we have proper
 	 * registers to report, but if we miss it (e.g. on BUG()) we need
diff --git a/arch/x86/include/asm/amd_nb.h b/arch/x86/include/asm/amd_nb.h
index c7df20e78b09..455066a06f60 100644
--- a/arch/x86/include/asm/amd_nb.h
+++ b/arch/x86/include/asm/amd_nb.h
@@ -57,6 +57,7 @@ struct threshold_bank {
 
 	/* initialized to the number of CPUs on the node sharing this bank */
 	refcount_t		cpus;
+	unsigned int		shared;
 };
 
 struct amd_northbridge {
diff --git a/arch/x86/include/asm/bitops.h b/arch/x86/include/asm/bitops.h
index 53f246e9df5a..b392571c1f1d 100644
--- a/arch/x86/include/asm/bitops.h
+++ b/arch/x86/include/asm/bitops.h
@@ -201,8 +201,12 @@ arch_test_and_change_bit(long nr, volatile unsigned long *addr)
 	return GEN_BINARY_RMWcc(LOCK_PREFIX __ASM_SIZE(btc), *addr, c, "Ir", nr);
 }
 
-static __always_inline bool constant_test_bit(long nr, const volatile unsigned long *addr)
+static __no_kcsan_or_inline bool constant_test_bit(long nr, const volatile unsigned long *addr)
 {
+	/*
+	 * Because this is a plain access, we need to disable KCSAN here to
+	 * avoid double instrumentation via instrumented bitops.
+	 */
 	return ((1UL << (nr & (BITS_PER_LONG-1))) &
 		(addr[nr >> _BITOPS_LONG_SHIFT])) != 0;
 }
diff --git a/arch/x86/include/asm/doublefault.h b/arch/x86/include/asm/doublefault.h
index af9a14ac8962..54a6e4a2e132 100644
--- a/arch/x86/include/asm/doublefault.h
+++ b/arch/x86/include/asm/doublefault.h
@@ -2,7 +2,7 @@
 #ifndef _ASM_X86_DOUBLEFAULT_H
 #define _ASM_X86_DOUBLEFAULT_H
 
-#if defined(CONFIG_X86_32) && defined(CONFIG_DOUBLEFAULT)
+#ifdef CONFIG_X86_32
 extern void doublefault_init_cpu_tss(void);
 #else
 static inline void doublefault_init_cpu_tss(void)
diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
index cdcf48d52a12..8391c115c0ec 100644
--- a/arch/x86/include/asm/efi.h
+++ b/arch/x86/include/asm/efi.h
@@ -178,8 +178,10 @@ extern void efi_free_boot_services(void);
 extern pgd_t * __init efi_uv1_memmap_phys_prolog(void);
 extern void __init efi_uv1_memmap_phys_epilog(pgd_t *save_pgd);
 
+/* kexec external ABI */
 struct efi_setup_data {
 	u64 fw_vendor;
+	u64 __unused;
 	u64 tables;
 	u64 smbios;
 	u64 reserved[8];
diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h
index f9cea081c05b..c598aaab071b 100644
--- a/arch/x86/include/asm/mce.h
+++ b/arch/x86/include/asm/mce.h
@@ -127,6 +127,17 @@
 #define MSR_AMD64_SMCA_MCx_DEADDR(x)	(MSR_AMD64_SMCA_MC0_DEADDR + 0x10*(x))
 #define MSR_AMD64_SMCA_MCx_MISCy(x, y)	((MSR_AMD64_SMCA_MC0_MISC1 + y) + (0x10*(x)))
 
+#define XEC(x, mask)			(((x) >> 16) & mask)
+
+/* mce.kflags flag bits for logging etc. */
+#define	MCE_HANDLED_CEC		BIT_ULL(0)
+#define	MCE_HANDLED_UC		BIT_ULL(1)
+#define	MCE_HANDLED_EXTLOG	BIT_ULL(2)
+#define	MCE_HANDLED_NFIT	BIT_ULL(3)
+#define	MCE_HANDLED_EDAC	BIT_ULL(4)
+#define	MCE_HANDLED_MCELOG	BIT_ULL(5)
+#define MCE_IN_KERNEL_RECOV	BIT_ULL(6)
+
 /*
  * This structure contains all data related to the MCE log.  Also
  * carries a signature to make it easier to find from external
@@ -142,14 +153,16 @@ struct mce_log_buffer {
 	struct mce entry[];
 };
 
+/* Highest last */
 enum mce_notifier_prios {
-	MCE_PRIO_FIRST		= INT_MAX,
-	MCE_PRIO_UC		= INT_MAX - 1,
-	MCE_PRIO_EXTLOG		= INT_MAX - 2,
-	MCE_PRIO_NFIT		= INT_MAX - 3,
-	MCE_PRIO_EDAC		= INT_MAX - 4,
-	MCE_PRIO_MCELOG		= 1,
-	MCE_PRIO_LOWEST		= 0,
+	MCE_PRIO_LOWEST,
+	MCE_PRIO_MCELOG,
+	MCE_PRIO_EDAC,
+	MCE_PRIO_NFIT,
+	MCE_PRIO_EXTLOG,
+	MCE_PRIO_UC,
+	MCE_PRIO_EARLY,
+	MCE_PRIO_CEC
 };
 
 struct notifier_block;
@@ -347,5 +360,4 @@ umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr)	{ return
 #endif
 
 static inline void mce_hygon_feature_init(struct cpuinfo_x86 *c)	{ return mce_amd_feature_init(c); }
-
 #endif /* _ASM_X86_MCE_H */
diff --git a/arch/x86/include/asm/microcode_amd.h b/arch/x86/include/asm/microcode_amd.h
index 6685e1218959..7063b5a43220 100644
--- a/arch/x86/include/asm/microcode_amd.h
+++ b/arch/x86/include/asm/microcode_amd.h
@@ -41,7 +41,7 @@ struct microcode_amd {
 	unsigned int			mpb[0];
 };
 
-#define PATCH_MAX_SIZE PAGE_SIZE
+#define PATCH_MAX_SIZE (3 * PAGE_SIZE)
 
 #ifdef CONFIG_MICROCODE_AMD
 extern void __init load_ucode_amd_bsp(unsigned int family);
diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h
index df1373415f11..8d03ffd43794 100644
--- a/arch/x86/include/asm/pgtable_64.h
+++ b/arch/x86/include/asm/pgtable_64.h
@@ -53,6 +53,12 @@ static inline void sync_initial_page_table(void) { }
 
 struct mm_struct;
 
+#define mm_p4d_folded mm_p4d_folded
+static inline bool mm_p4d_folded(struct mm_struct *mm)
+{
+	return !pgtable_l5_enabled();
+}
+
 void set_pte_vaddr_p4d(p4d_t *p4d_page, unsigned long vaddr, pte_t new_pte);
 void set_pte_vaddr_pud(pud_t *pud_page, unsigned long vaddr, pte_t new_pte);
 
diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h
index c26a7e1d8a2c..70bd0f356e5d 100644
--- a/arch/x86/include/asm/traps.h
+++ b/arch/x86/include/asm/traps.h
@@ -69,9 +69,7 @@ dotraplinkage void do_overflow(struct pt_regs *regs, long error_code);
 dotraplinkage void do_bounds(struct pt_regs *regs, long error_code);
 dotraplinkage void do_invalid_op(struct pt_regs *regs, long error_code);
 dotraplinkage void do_device_not_available(struct pt_regs *regs, long error_code);
-#if defined(CONFIG_X86_64) || defined(CONFIG_DOUBLEFAULT)
 dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code, unsigned long cr2);
-#endif
 dotraplinkage void do_coprocessor_segment_overrun(struct pt_regs *regs, long error_code);
 dotraplinkage void do_invalid_TSS(struct pt_regs *regs, long error_code);
 dotraplinkage void do_segment_not_present(struct pt_regs *regs, long error_code);
diff --git a/arch/x86/include/uapi/asm/mce.h b/arch/x86/include/uapi/asm/mce.h
index 955c2a2e1cf9..5b59d80f1d4e 100644
--- a/arch/x86/include/uapi/asm/mce.h
+++ b/arch/x86/include/uapi/asm/mce.h
@@ -35,6 +35,7 @@ struct mce {
 	__u64 ipid;		/* MCA_IPID MSR: only valid on SMCA systems */
 	__u64 ppin;		/* Protected Processor Inventory Number */
 	__u32 microcode;	/* Microcode revision */
+	__u64 kflags;		/* Internal kernel use. See below */
 };
 
 #define MCE_GET_RECORD_LEN   _IOR('M', 1, int)
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index ba89cabe5fcf..92e1261ec4ec 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -28,6 +28,10 @@ KASAN_SANITIZE_dumpstack_$(BITS).o			:= n
 KASAN_SANITIZE_stacktrace.o				:= n
 KASAN_SANITIZE_paravirt.o				:= n
 
+# With some compiler versions the generated code results in boot hangs, caused
+# by several compilation units. To be safe, disable all instrumentation.
+KCSAN_SANITIZE := n
+
 OBJECT_FILES_NON_STANDARD_test_nx.o			:= y
 OBJECT_FILES_NON_STANDARD_paravirt_patch.o		:= y
 
@@ -102,9 +106,7 @@ obj-$(CONFIG_KEXEC_FILE)	+= kexec-bzimage64.o
 obj-$(CONFIG_CRASH_DUMP)	+= crash_dump_$(BITS).o
 obj-y				+= kprobes/
 obj-$(CONFIG_MODULES)		+= module.o
-ifeq ($(CONFIG_X86_32),y)
-obj-$(CONFIG_DOUBLEFAULT)	+= doublefault_32.o
-endif
+obj-$(CONFIG_X86_32)		+= doublefault_32.o
 obj-$(CONFIG_KGDB)		+= kgdb.o
 obj-$(CONFIG_VM86)		+= vm86_32.o
 obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile
index 7dc4ad68eb41..dba6a83bc349 100644
--- a/arch/x86/kernel/cpu/Makefile
+++ b/arch/x86/kernel/cpu/Makefile
@@ -13,6 +13,9 @@ endif
 KCOV_INSTRUMENT_common.o := n
 KCOV_INSTRUMENT_perf_event.o := n
 
+# As above, instrumenting secondary CPU boot code causes boot hangs.
+KCSAN_SANITIZE_common.o := n
+
 # Make sure load_percpu_segment has no stackprotector
 nostackp := $(call cc-option, -fno-stack-protector)
 CFLAGS_common.o		:= $(nostackp)
diff --git a/arch/x86/kernel/cpu/mce/amd.c b/arch/x86/kernel/cpu/mce/amd.c
index 52de616a8065..ea3cf714b7ad 100644
--- a/arch/x86/kernel/cpu/mce/amd.c
+++ b/arch/x86/kernel/cpu/mce/amd.c
@@ -192,7 +192,12 @@ EXPORT_SYMBOL_GPL(smca_banks);
 static char buf_mcatype[MAX_MCATYPE_NAME_LEN];
 
 static DEFINE_PER_CPU(struct threshold_bank **, threshold_banks);
-static DEFINE_PER_CPU(unsigned int, bank_map);	/* see which banks are on */
+
+/*
+ * A list of the banks enabled on each logical CPU. Controls which respective
+ * descriptors to initialize later in mce_threshold_create_device().
+ */
+static DEFINE_PER_CPU(unsigned int, bank_map);
 
 /* Map of banks that have more than MCA_MISC0 available. */
 static DEFINE_PER_CPU(u32, smca_misc_banks_map);
@@ -381,6 +386,10 @@ static void threshold_restart_bank(void *_tr)
 	struct thresh_restart *tr = _tr;
 	u32 hi, lo;
 
+	/* sysfs write might race against an offline operation */
+	if (this_cpu_read(threshold_banks))
+		return;
+
 	rdmsr(tr->b->address, lo, hi);
 
 	if (tr->b->threshold_limit < (hi & THRESHOLD_MAX))
@@ -568,14 +577,19 @@ bool amd_filter_mce(struct mce *m)
 {
 	enum smca_bank_types bank_type = smca_get_bank_type(m->bank);
 	struct cpuinfo_x86 *c = &boot_cpu_data;
-	u8 xec = (m->status >> 16) & 0x3F;
 
 	/* See Family 17h Models 10h-2Fh Erratum #1114. */
 	if (c->x86 == 0x17 &&
 	    c->x86_model >= 0x10 && c->x86_model <= 0x2F &&
-	    bank_type == SMCA_IF && xec == 10)
+	    bank_type == SMCA_IF && XEC(m->status, 0x3f) == 10)
 		return true;
 
+	/* NB GART TLB error reporting is disabled by default. */
+	if (c->x86 < 0x17) {
+		if (m->bank == 4 && XEC(m->status, 0x1f) == 0x5)
+			return true;
+	}
+
 	return false;
 }
 
@@ -1016,13 +1030,22 @@ static void log_and_reset_block(struct threshold_block *block)
 static void amd_threshold_interrupt(void)
 {
 	struct threshold_block *first_block = NULL, *block = NULL, *tmp = NULL;
+	struct threshold_bank **bp = this_cpu_read(threshold_banks);
 	unsigned int bank, cpu = smp_processor_id();
 
+	/*
+	 * Validate that the threshold bank has been initialized already. The
+	 * handler is installed at boot time, but on a hotplug event the
+	 * interrupt might fire before the data has been initialized.
+	 */
+	if (!bp)
+		return;
+
 	for (bank = 0; bank < this_cpu_read(mce_num_banks); ++bank) {
 		if (!(per_cpu(bank_map, cpu) & (1 << bank)))
 			continue;
 
-		first_block = per_cpu(threshold_banks, cpu)[bank]->blocks;
+		first_block = bp[bank]->blocks;
 		if (!first_block)
 			continue;
 
@@ -1071,7 +1094,8 @@ store_interrupt_enable(struct threshold_block *b, const char *buf, size_t size)
 	memset(&tr, 0, sizeof(tr));
 	tr.b		= b;
 
-	smp_call_function_single(b->cpu, threshold_restart_bank, &tr, 1);
+	if (smp_call_function_single(b->cpu, threshold_restart_bank, &tr, 1))
+		return -ENODEV;
 
 	return size;
 }
@@ -1095,7 +1119,8 @@ store_threshold_limit(struct threshold_block *b, const char *buf, size_t size)
 	b->threshold_limit = new;
 	tr.b = b;
 
-	smp_call_function_single(b->cpu, threshold_restart_bank, &tr, 1);
+	if (smp_call_function_single(b->cpu, threshold_restart_bank, &tr, 1))
+		return -ENODEV;
 
 	return size;
 }
@@ -1104,7 +1129,9 @@ static ssize_t show_error_count(struct threshold_block *b, char *buf)
 {
 	u32 lo, hi;
 
-	rdmsr_on_cpu(b->cpu, b->address, &lo, &hi);
+	/* CPU might be offline by now */
+	if (rdmsr_on_cpu(b->cpu, b->address, &lo, &hi))
+		return -ENODEV;
 
 	return sprintf(buf, "%u\n", ((hi & THRESHOLD_MAX) -
 				     (THRESHOLD_MAX - b->threshold_limit)));
@@ -1209,10 +1236,10 @@ static int allocate_threshold_blocks(unsigned int cpu, struct threshold_bank *tb
 	u32 low, high;
 	int err;
 
-	if ((bank >= per_cpu(mce_num_banks, cpu)) || (block >= NR_BLOCKS))
+	if ((bank >= this_cpu_read(mce_num_banks)) || (block >= NR_BLOCKS))
 		return 0;
 
-	if (rdmsr_safe_on_cpu(cpu, address, &low, &high))
+	if (rdmsr_safe(address, &low, &high))
 		return 0;
 
 	if (!(high & MASK_VALID_HI)) {
@@ -1247,6 +1274,7 @@ static int allocate_threshold_blocks(unsigned int cpu, struct threshold_bank *tb
 
 	INIT_LIST_HEAD(&b->miscj);
 
+	/* This is safe as @tb is not visible yet */
 	if (tb->blocks)
 		list_add(&b->miscj, &tb->blocks->miscj);
 	else
@@ -1267,13 +1295,12 @@ static int allocate_threshold_blocks(unsigned int cpu, struct threshold_bank *tb
 	if (b)
 		kobject_uevent(&b->kobj, KOBJ_ADD);
 
-	return err;
+	return 0;
 
 out_free:
 	if (b) {
-		kobject_put(&b->kobj);
 		list_del(&b->miscj);
-		kfree(b);
+		kobject_put(&b->kobj);
 	}
 	return err;
 }
@@ -1302,9 +1329,10 @@ static int __threshold_add_blocks(struct threshold_bank *b)
 	return err;
 }
 
-static int threshold_create_bank(unsigned int cpu, unsigned int bank)
+static int threshold_create_bank(struct threshold_bank **bp, unsigned int cpu,
+				 unsigned int bank)
 {
-	struct device *dev = per_cpu(mce_device, cpu);
+	struct device *dev = this_cpu_read(mce_device);
 	struct amd_northbridge *nb = NULL;
 	struct threshold_bank *b = NULL;
 	const char *name = get_name(bank, NULL);
@@ -1324,7 +1352,7 @@ static int threshold_create_bank(unsigned int cpu, unsigned int bank)
 			if (err)
 				goto out;
 
-			per_cpu(threshold_banks, cpu)[bank] = b;
+			bp[bank] = b;
 			refcount_inc(&b->cpus);
 
 			err = __threshold_add_blocks(b);
@@ -1339,6 +1367,7 @@ static int threshold_create_bank(unsigned int cpu, unsigned int bank)
 		goto out;
 	}
 
+	/* Associate the bank with the per-CPU MCE device */
 	b->kobj = kobject_create_and_add(name, &dev->kobj);
 	if (!b->kobj) {
 		err = -EINVAL;
@@ -1346,6 +1375,7 @@ static int threshold_create_bank(unsigned int cpu, unsigned int bank)
 	}
 
 	if (is_shared_bank(bank)) {
+		b->shared = 1;
 		refcount_set(&b->cpus, 1);
 
 		/* nb is already initialized, see above */
@@ -1357,16 +1387,16 @@ static int threshold_create_bank(unsigned int cpu, unsigned int bank)
 
 	err = allocate_threshold_blocks(cpu, b, bank, 0, msr_ops.misc(bank));
 	if (err)
-		goto out_free;
-
-	per_cpu(threshold_banks, cpu)[bank] = b;
+		goto out_kobj;
 
+	bp[bank] = b;
 	return 0;
 
- out_free:
+out_kobj:
+	kobject_put(b->kobj);
+out_free:
 	kfree(b);
-
- out:
+out:
 	return err;
 }
 
@@ -1375,21 +1405,16 @@ static void threshold_block_release(struct kobject *kobj)
 	kfree(to_block(kobj));
 }
 
-static void deallocate_threshold_block(unsigned int cpu, unsigned int bank)
+static void deallocate_threshold_blocks(struct threshold_bank *bank)
 {
-	struct threshold_block *pos = NULL;
-	struct threshold_block *tmp = NULL;
-	struct threshold_bank *head = per_cpu(threshold_banks, cpu)[bank];
+	struct threshold_block *pos, *tmp;
 
-	if (!head)
-		return;
-
-	list_for_each_entry_safe(pos, tmp, &head->blocks->miscj, miscj) {
+	list_for_each_entry_safe(pos, tmp, &bank->blocks->miscj, miscj) {
 		list_del(&pos->miscj);
 		kobject_put(&pos->kobj);
 	}
 
-	kobject_put(&head->blocks->kobj);
+	kobject_put(&bank->blocks->kobj);
 }
 
 static void __threshold_remove_blocks(struct threshold_bank *b)
@@ -1403,122 +1428,102 @@ static void __threshold_remove_blocks(struct threshold_bank *b)
 		kobject_del(&pos->kobj);
 }
 
-static void threshold_remove_bank(unsigned int cpu, int bank)
+static void threshold_remove_bank(struct threshold_bank *bank)
 {
 	struct amd_northbridge *nb;
-	struct threshold_bank *b;
 
-	b = per_cpu(threshold_banks, cpu)[bank];
-	if (!b)
-		return;
+	if (!bank->blocks)
+		goto out_free;
 
-	if (!b->blocks)
-		goto free_out;
+	if (!bank->shared)
+		goto out_dealloc;
 
-	if (is_shared_bank(bank)) {
-		if (!refcount_dec_and_test(&b->cpus)) {
-			__threshold_remove_blocks(b);
-			per_cpu(threshold_banks, cpu)[bank] = NULL;
-			return;
-		} else {
-			/*
-			 * the last CPU on this node using the shared bank is
-			 * going away, remove that bank now.
-			 */
-			nb = node_to_amd_nb(amd_get_nb_id(cpu));
-			nb->bank4 = NULL;
-		}
+	if (!refcount_dec_and_test(&bank->cpus)) {
+		__threshold_remove_blocks(bank);
+		return;
+	} else {
+		/*
+		 * The last CPU on this node using the shared bank is going
+		 * away, remove that bank now.
+		 */
+		nb = node_to_amd_nb(amd_get_nb_id(smp_processor_id()));
+		nb->bank4 = NULL;
 	}
 
-	deallocate_threshold_block(cpu, bank);
+out_dealloc:
+	deallocate_threshold_blocks(bank);
 
-free_out:
-	kobject_del(b->kobj);
-	kobject_put(b->kobj);
-	kfree(b);
-	per_cpu(threshold_banks, cpu)[bank] = NULL;
+out_free:
+	kobject_put(bank->kobj);
+	kfree(bank);
 }
 
 int mce_threshold_remove_device(unsigned int cpu)
 {
-	unsigned int bank;
+	struct threshold_bank **bp = this_cpu_read(threshold_banks);
+	unsigned int bank, numbanks = this_cpu_read(mce_num_banks);
 
-	for (bank = 0; bank < per_cpu(mce_num_banks, cpu); ++bank) {
-		if (!(per_cpu(bank_map, cpu) & (1 << bank)))
-			continue;
-		threshold_remove_bank(cpu, bank);
+	if (!bp)
+		return 0;
+
+	/*
+	 * Clear the pointer before cleaning up, so that the interrupt won't
+	 * touch anything of this.
+	 */
+	this_cpu_write(threshold_banks, NULL);
+
+	for (bank = 0; bank < numbanks; bank++) {
+		if (bp[bank]) {
+			threshold_remove_bank(bp[bank]);
+			bp[bank] = NULL;
+		}
 	}
-	kfree(per_cpu(threshold_banks, cpu));
-	per_cpu(threshold_banks, cpu) = NULL;
+	kfree(bp);
 	return 0;
 }
 
-/* create dir/files for all valid threshold banks */
+/**
+ * mce_threshold_create_device - Create the per-CPU MCE threshold device
+ * @cpu:	The plugged in CPU
+ *
+ * Create directories and files for all valid threshold banks.
+ *
+ * This is invoked from the CPU hotplug callback which was installed in
+ * mcheck_init_device(). The invocation happens in context of the hotplug
+ * thread running on @cpu.  The callback is invoked on all CPUs which are
+ * online when the callback is installed or during a real hotplug event.
+ */
 int mce_threshold_create_device(unsigned int cpu)
 {
-	unsigned int bank;
+	unsigned int numbanks, bank;
 	struct threshold_bank **bp;
-	int err = 0;
+	int err;
 
-	bp = per_cpu(threshold_banks, cpu);
+	if (!mce_flags.amd_threshold)
+		return 0;
+
+	bp = this_cpu_read(threshold_banks);
 	if (bp)
 		return 0;
 
-	bp = kcalloc(per_cpu(mce_num_banks, cpu), sizeof(struct threshold_bank *),
-		     GFP_KERNEL);
+	numbanks = this_cpu_read(mce_num_banks);
+	bp = kcalloc(numbanks, sizeof(*bp), GFP_KERNEL);
 	if (!bp)
 		return -ENOMEM;
 
-	per_cpu(threshold_banks, cpu) = bp;
-
-	for (bank = 0; bank < per_cpu(mce_num_banks, cpu); ++bank) {
-		if (!(per_cpu(bank_map, cpu) & (1 << bank)))
+	for (bank = 0; bank < numbanks; ++bank) {
+		if (!(this_cpu_read(bank_map) & (1 << bank)))
 			continue;
-		err = threshold_create_bank(cpu, bank);
+		err = threshold_create_bank(bp, cpu, bank);
 		if (err)
-			goto err;
-	}
-	return err;
-err:
-	mce_threshold_remove_device(cpu);
-	return err;
-}
-
-static __init int threshold_init_device(void)
-{
-	unsigned lcpu = 0;
-
-	/* to hit CPUs online before the notifier is up */
-	for_each_online_cpu(lcpu) {
-		int err = mce_threshold_create_device(lcpu);
-
-		if (err)
-			return err;
+			goto out_err;
 	}
+	this_cpu_write(threshold_banks, bp);
 
 	if (thresholding_irq_en)
 		mce_threshold_vector = amd_threshold_interrupt;
-
 	return 0;
+out_err:
+	mce_threshold_remove_device(cpu);
+	return err;
 }
-/*
- * there are 3 funcs which need to be _initcalled in a logic sequence:
- * 1. xen_late_init_mcelog
- * 2. mcheck_init_device
- * 3. threshold_init_device
- *
- * xen_late_init_mcelog must register xen_mce_chrdev_device before
- * native mce_chrdev_device registration if running under xen platform;
- *
- * mcheck_init_device should be inited before threshold_init_device to
- * initialize mce_device, otherwise a NULL ptr dereference will cause panic.
- *
- * so we use following _initcalls
- * 1. device_initcall(xen_late_init_mcelog);
- * 2. device_initcall_sync(mcheck_init_device);
- * 3. late_initcall(threshold_init_device);
- *
- * when running under xen, the initcall order is 1,2,3;
- * on baremetal, we skip 1 and we do only 2 and 3.
- */
-late_initcall(threshold_init_device);
diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c
index 54165f3569e8..02e1f165f148 100644
--- a/arch/x86/kernel/cpu/mce/core.c
+++ b/arch/x86/kernel/cpu/mce/core.c
@@ -158,29 +158,17 @@ void mce_log(struct mce *m)
 }
 EXPORT_SYMBOL_GPL(mce_log);
 
-/*
- * We run the default notifier if we have only the UC, the first and the
- * default notifier registered. I.e., the mandatory NUM_DEFAULT_NOTIFIERS
- * notifiers registered on the chain.
- */
-#define NUM_DEFAULT_NOTIFIERS	3
-static atomic_t num_notifiers;
-
 void mce_register_decode_chain(struct notifier_block *nb)
 {
 	if (WARN_ON(nb->priority > MCE_PRIO_MCELOG && nb->priority < MCE_PRIO_EDAC))
 		return;
 
-	atomic_inc(&num_notifiers);
-
 	blocking_notifier_chain_register(&x86_mce_decoder_chain, nb);
 }
 EXPORT_SYMBOL_GPL(mce_register_decode_chain);
 
 void mce_unregister_decode_chain(struct notifier_block *nb)
 {
-	atomic_dec(&num_notifiers);
-
 	blocking_notifier_chain_unregister(&x86_mce_decoder_chain, nb);
 }
 EXPORT_SYMBOL_GPL(mce_unregister_decode_chain);
@@ -263,6 +251,7 @@ static void __print_mce(struct mce *m)
 	}
 
 	pr_cont("\n");
+
 	/*
 	 * Note this output is parsed by external tools and old fields
 	 * should not be changed.
@@ -544,22 +533,7 @@ bool mce_is_correctable(struct mce *m)
 }
 EXPORT_SYMBOL_GPL(mce_is_correctable);
 
-static bool cec_add_mce(struct mce *m)
-{
-	if (!m)
-		return false;
-
-	/* We eat only correctable DRAM errors with usable addresses. */
-	if (mce_is_memory_error(m) &&
-	    mce_is_correctable(m)  &&
-	    mce_usable_address(m))
-		if (!cec_add_elem(m->addr >> PAGE_SHIFT))
-			return true;
-
-	return false;
-}
-
-static int mce_first_notifier(struct notifier_block *nb, unsigned long val,
+static int mce_early_notifier(struct notifier_block *nb, unsigned long val,
 			      void *data)
 {
 	struct mce *m = (struct mce *)data;
@@ -567,9 +541,6 @@ static int mce_first_notifier(struct notifier_block *nb, unsigned long val,
 	if (!m)
 		return NOTIFY_DONE;
 
-	if (cec_add_mce(m))
-		return NOTIFY_STOP;
-
 	/* Emit the trace record: */
 	trace_mce_record(m);
 
@@ -580,9 +551,9 @@ static int mce_first_notifier(struct notifier_block *nb, unsigned long val,
 	return NOTIFY_DONE;
 }
 
-static struct notifier_block first_nb = {
-	.notifier_call	= mce_first_notifier,
-	.priority	= MCE_PRIO_FIRST,
+static struct notifier_block early_nb = {
+	.notifier_call	= mce_early_notifier,
+	.priority	= MCE_PRIO_EARLY,
 };
 
 static int uc_decode_notifier(struct notifier_block *nb, unsigned long val,
@@ -599,8 +570,10 @@ static int uc_decode_notifier(struct notifier_block *nb, unsigned long val,
 		return NOTIFY_DONE;
 
 	pfn = mce->addr >> PAGE_SHIFT;
-	if (!memory_failure(pfn, 0))
+	if (!memory_failure(pfn, 0)) {
 		set_mce_nospec(pfn);
+		mce->kflags |= MCE_HANDLED_UC;
+	}
 
 	return NOTIFY_OK;
 }
@@ -618,10 +591,8 @@ static int mce_default_notifier(struct notifier_block *nb, unsigned long val,
 	if (!m)
 		return NOTIFY_DONE;
 
-	if (atomic_read(&num_notifiers) > NUM_DEFAULT_NOTIFIERS)
-		return NOTIFY_DONE;
-
-	__print_mce(m);
+	if (mca_cfg.print_all || !m->kflags)
+		__print_mce(m);
 
 	return NOTIFY_DONE;
 }
@@ -1360,8 +1331,19 @@ void notrace do_machine_check(struct pt_regs *regs, long error_code)
 		local_irq_disable();
 		ist_end_non_atomic();
 	} else {
-		if (!fixup_exception(regs, X86_TRAP_MC, error_code, 0))
-			mce_panic("Failed kernel mode recovery", &m, msg);
+		/*
+		 * Handle an MCE which has happened in kernel space but from
+		 * which the kernel can recover: ex_has_fault_handler() has
+		 * already verified that the rIP at which the error happened is
+		 * a rIP from which the kernel can recover (by jumping to
+		 * recovery code specified in _ASM_EXTABLE_FAULT()) and the
+		 * corresponding exception handler which would do that is the
+		 * proper one.
+		 */
+		if (m.kflags & MCE_IN_KERNEL_RECOV) {
+			if (!fixup_exception(regs, X86_TRAP_MC, error_code, 0))
+				mce_panic("Failed kernel mode recovery", &m, msg);
+		}
 	}
 
 out_ist:
@@ -1756,6 +1738,7 @@ static void __mcheck_cpu_init_early(struct cpuinfo_x86 *c)
 		mce_flags.overflow_recov = !!cpu_has(c, X86_FEATURE_OVERFLOW_RECOV);
 		mce_flags.succor	 = !!cpu_has(c, X86_FEATURE_SUCCOR);
 		mce_flags.smca		 = !!cpu_has(c, X86_FEATURE_SMCA);
+		mce_flags.amd_threshold	 = 1;
 
 		if (mce_flags.smca) {
 			msr_ops.ctl	= smca_ctl_reg;
@@ -1990,6 +1973,7 @@ void mce_disable_bank(int bank)
  * mce=no_cmci Disables CMCI
  * mce=no_lmce Disables LMCE
  * mce=dont_log_ce Clears corrected events silently, no log created for CEs.
+ * mce=print_all Print all machine check logs to console
  * mce=ignore_ce Disables polling and CMCI, corrected events are not cleared.
  * mce=TOLERANCELEVEL[,monarchtimeout] (number, see above)
  *	monarchtimeout is how long to wait for other CPUs on machine
@@ -2018,6 +2002,8 @@ static int __init mcheck_enable(char *str)
 		cfg->lmce_disabled = 1;
 	else if (!strcmp(str, "dont_log_ce"))
 		cfg->dont_log_ce = true;
+	else if (!strcmp(str, "print_all"))
+		cfg->print_all = true;
 	else if (!strcmp(str, "ignore_ce"))
 		cfg->ignore_ce = true;
 	else if (!strcmp(str, "bootlog") || !strcmp(str, "nobootlog"))
@@ -2040,7 +2026,7 @@ __setup("mce", mcheck_enable);
 int __init mcheck_init(void)
 {
 	mcheck_intel_therm_init();
-	mce_register_decode_chain(&first_nb);
+	mce_register_decode_chain(&early_nb);
 	mce_register_decode_chain(&mce_uc_nb);
 	mce_register_decode_chain(&mce_default_nb);
 	mcheck_vendor_init_severity();
@@ -2284,6 +2270,7 @@ static ssize_t store_int_with_restart(struct device *s,
 static DEVICE_INT_ATTR(tolerant, 0644, mca_cfg.tolerant);
 static DEVICE_INT_ATTR(monarch_timeout, 0644, mca_cfg.monarch_timeout);
 static DEVICE_BOOL_ATTR(dont_log_ce, 0644, mca_cfg.dont_log_ce);
+static DEVICE_BOOL_ATTR(print_all, 0644, mca_cfg.print_all);
 
 static struct dev_ext_attribute dev_attr_check_interval = {
 	__ATTR(check_interval, 0644, device_show_int, store_int_with_restart),
@@ -2308,6 +2295,7 @@ static struct device_attribute *mce_device_attrs[] = {
 #endif
 	&dev_attr_monarch_timeout.attr,
 	&dev_attr_dont_log_ce.attr,
+	&dev_attr_print_all.attr,
 	&dev_attr_ignore_ce.attr,
 	&dev_attr_cmci_disabled.attr,
 	NULL
@@ -2480,6 +2468,13 @@ static __init void mce_init_banks(void)
 	}
 }
 
+/*
+ * When running on XEN, this initcall is ordered against the XEN mcelog
+ * initcall:
+ *
+ *   device_initcall(xen_late_init_mcelog);
+ *   device_initcall_sync(mcheck_init_device);
+ */
 static __init int mcheck_init_device(void)
 {
 	int err;
@@ -2511,6 +2506,10 @@ static __init int mcheck_init_device(void)
 	if (err)
 		goto err_out_mem;
 
+	/*
+	 * Invokes mce_cpu_online() on all CPUs which are online when
+	 * the state is installed.
+	 */
 	err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "x86/mce:online",
 				mce_cpu_online, mce_cpu_pre_down);
 	if (err < 0)
@@ -2600,7 +2599,6 @@ static int __init mcheck_late_init(void)
 		static_branch_inc(&mcsafe_key);
 
 	mcheck_debugfs_init();
-	cec_init();
 
 	/*
 	 * Flush out everything that has been logged during early boot, now that
diff --git a/arch/x86/kernel/cpu/mce/dev-mcelog.c b/arch/x86/kernel/cpu/mce/dev-mcelog.c
index d089567a9ce8..c033e7ea9e3c 100644
--- a/arch/x86/kernel/cpu/mce/dev-mcelog.c
+++ b/arch/x86/kernel/cpu/mce/dev-mcelog.c
@@ -39,6 +39,9 @@ static int dev_mce_log(struct notifier_block *nb, unsigned long val,
 	struct mce *mce = (struct mce *)data;
 	unsigned int entry;
 
+	if (mce->kflags & MCE_HANDLED_CEC)
+		return NOTIFY_DONE;
+
 	mutex_lock(&mce_chrdev_read_mutex);
 
 	entry = mcelog->next;
@@ -56,6 +59,7 @@ static int dev_mce_log(struct notifier_block *nb, unsigned long val,
 
 	memcpy(mcelog->entry + entry, mce, sizeof(struct mce));
 	mcelog->entry[entry].finished = 1;
+	mcelog->entry[entry].kflags = 0;
 
 	/* wake processes polling /dev/mcelog */
 	wake_up_interruptible(&mce_chrdev_wait);
@@ -63,6 +67,7 @@ static int dev_mce_log(struct notifier_block *nb, unsigned long val,
 unlock:
 	mutex_unlock(&mce_chrdev_read_mutex);
 
+	mce->kflags |= MCE_HANDLED_MCELOG;
 	return NOTIFY_OK;
 }
 
diff --git a/arch/x86/kernel/cpu/mce/internal.h b/arch/x86/kernel/cpu/mce/internal.h
index 3b008172ad73..55f5c7b755f2 100644
--- a/arch/x86/kernel/cpu/mce/internal.h
+++ b/arch/x86/kernel/cpu/mce/internal.h
@@ -119,6 +119,7 @@ struct mca_config {
 	bool dont_log_ce;
 	bool cmci_disabled;
 	bool ignore_ce;
+	bool print_all;
 
 	__u64 lmce_disabled		: 1,
 	      disabled			: 1,
@@ -148,7 +149,7 @@ struct mce_vendor_flags {
 	 * Recovery. It indicates support for data poisoning in HW and deferred
 	 * error interrupts.
 	 */
-	      succor		: 1,
+	succor			: 1,
 
 	/*
 	 * (AMD) SMCA: This bit indicates support for Scalable MCA which expands
@@ -156,9 +157,12 @@ struct mce_vendor_flags {
 	 * banks. Also, to accommodate the new banks and registers, the MCA
 	 * register space is moved to a new MSR range.
 	 */
-	      smca		: 1,
+	smca			: 1,
 
-	      __reserved_0	: 61;
+	/* AMD-style error thresholding banks present. */
+	amd_threshold		: 1,
+
+	__reserved_0		: 60;
 };
 
 extern struct mce_vendor_flags mce_flags;
diff --git a/arch/x86/kernel/cpu/mce/severity.c b/arch/x86/kernel/cpu/mce/severity.c
index 87bcdc6dc2f0..e1da619add19 100644
--- a/arch/x86/kernel/cpu/mce/severity.c
+++ b/arch/x86/kernel/cpu/mce/severity.c
@@ -213,8 +213,12 @@ static int error_context(struct mce *m)
 {
 	if ((m->cs & 3) == 3)
 		return IN_USER;
-	if (mc_recoverable(m->mcgstatus) && ex_has_fault_handler(m->ip))
+
+	if (mc_recoverable(m->mcgstatus) && ex_has_fault_handler(m->ip)) {
+		m->kflags |= MCE_IN_KERNEL_RECOV;
 		return IN_KERNEL_RECOV;
+	}
+
 	return IN_KERNEL;
 }
 
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index caa032ce3fe3..ebf34c7bc8bc 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -227,8 +227,8 @@ static void __init ms_hyperv_init_platform(void)
 	ms_hyperv.misc_features = cpuid_edx(HYPERV_CPUID_FEATURES);
 	ms_hyperv.hints    = cpuid_eax(HYPERV_CPUID_ENLIGHTMENT_INFO);
 
-	pr_info("Hyper-V: features 0x%x, hints 0x%x\n",
-		ms_hyperv.features, ms_hyperv.hints);
+	pr_info("Hyper-V: features 0x%x, hints 0x%x, misc 0x%x\n",
+		ms_hyperv.features, ms_hyperv.hints, ms_hyperv.misc_features);
 
 	ms_hyperv.max_vp_index = cpuid_eax(HYPERV_CPUID_IMPLEMENT_LIMITS);
 	ms_hyperv.max_lp_index = cpuid_ebx(HYPERV_CPUID_IMPLEMENT_LIMITS);
@@ -263,6 +263,16 @@ static void __init ms_hyperv_init_platform(void)
 			cpuid_eax(HYPERV_CPUID_NESTED_FEATURES);
 	}
 
+	/*
+	 * Hyper-V expects to get crash register data or kmsg when
+	 * crash enlightment is available and system crashes. Set
+	 * crash_kexec_post_notifiers to be true to make sure that
+	 * calling crash enlightment interface before running kdump
+	 * kernel.
+	 */
+	if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE)
+		crash_kexec_post_notifiers = true;
+
 #ifdef CONFIG_X86_LOCAL_APIC
 	if (ms_hyperv.features & HV_X64_ACCESS_FREQUENCY_MSRS &&
 	    ms_hyperv.misc_features & HV_FEATURE_FREQUENCY_MSRS_AVAILABLE) {
diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c
index 8e3a8fedfa4d..722fd712e1cf 100644
--- a/arch/x86/kernel/dumpstack_32.c
+++ b/arch/x86/kernel/dumpstack_32.c
@@ -87,7 +87,6 @@ static bool in_softirq_stack(unsigned long *stack, struct stack_info *info)
 
 static bool in_doublefault_stack(unsigned long *stack, struct stack_info *info)
 {
-#ifdef CONFIG_DOUBLEFAULT
 	struct cpu_entry_area *cea = get_cpu_entry_area(raw_smp_processor_id());
 	struct doublefault_stack *ss = &cea->doublefault_stack;
 
@@ -103,9 +102,6 @@ static bool in_doublefault_stack(unsigned long *stack, struct stack_info *info)
 	info->next_sp	= (unsigned long *)this_cpu_read(cpu_tss_rw.x86_tss.sp);
 
 	return true;
-#else
-	return false;
-#endif
 }
 
 
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index c5399e80c59c..983cd53ed4c9 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -910,14 +910,6 @@ static int __init parse_memmap_one(char *p)
 		return -EINVAL;
 
 	if (!strncmp(p, "exactmap", 8)) {
-#ifdef CONFIG_CRASH_DUMP
-		/*
-		 * If we are doing a crash dump, we still need to know
-		 * the real memory size before the original memory map is
-		 * reset.
-		 */
-		saved_max_pfn = e820__end_of_ram_pfn();
-#endif
 		e820_table->nr_entries = 0;
 		userdef = 1;
 		return 0;
@@ -999,7 +991,15 @@ void __init e820__reserve_setup_data(void)
 	while (pa_data) {
 		data = early_memremap(pa_data, sizeof(*data));
 		e820__range_update(pa_data, sizeof(*data)+data->len, E820_TYPE_RAM, E820_TYPE_RESERVED_KERN);
-		e820__range_update_kexec(pa_data, sizeof(*data)+data->len, E820_TYPE_RAM, E820_TYPE_RESERVED_KERN);
+
+		/*
+		 * SETUP_EFI is supplied by kexec and does not need to be
+		 * reserved.
+		 */
+		if (data->type != SETUP_EFI)
+			e820__range_update_kexec(pa_data,
+						 sizeof(*data) + data->len,
+						 E820_TYPE_RAM, E820_TYPE_RESERVED_KERN);
 
 		if (data->type == SETUP_INDIRECT &&
 		    ((struct setup_indirect *)data->data)->type != SETUP_INDIRECT) {
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index fe3ab9632f3b..3b9bf8c7e29d 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -1849,24 +1849,25 @@ static bool slv_set_max_freq_ratio(u64 *base_freq, u64 *turbo_freq)
 #include <asm/cpu_device_id.h>
 #include <asm/intel-family.h>
 
-#define ICPU(model) \
-	{X86_VENDOR_INTEL, 6, model, X86_FEATURE_APERFMPERF, 0}
+#define X86_MATCH(model)					\
+	X86_MATCH_VENDOR_FAM_MODEL_FEATURE(INTEL, 6,		\
+		INTEL_FAM6_##model, X86_FEATURE_APERFMPERF, NULL)
 
 static const struct x86_cpu_id has_knl_turbo_ratio_limits[] = {
-	ICPU(INTEL_FAM6_XEON_PHI_KNL),
-	ICPU(INTEL_FAM6_XEON_PHI_KNM),
+	X86_MATCH(XEON_PHI_KNL),
+	X86_MATCH(XEON_PHI_KNM),
 	{}
 };
 
 static const struct x86_cpu_id has_skx_turbo_ratio_limits[] = {
-	ICPU(INTEL_FAM6_SKYLAKE_X),
+	X86_MATCH(SKYLAKE_X),
 	{}
 };
 
 static const struct x86_cpu_id has_glm_turbo_ratio_limits[] = {
-	ICPU(INTEL_FAM6_ATOM_GOLDMONT),
-	ICPU(INTEL_FAM6_ATOM_GOLDMONT_D),
-	ICPU(INTEL_FAM6_ATOM_GOLDMONT_PLUS),
+	X86_MATCH(ATOM_GOLDMONT),
+	X86_MATCH(ATOM_GOLDMONT_D),
+	X86_MATCH(ATOM_GOLDMONT_PLUS),
 	{}
 };
 
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index d54cffdc7cac..e85561fc0dc8 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -326,7 +326,6 @@ __visible void __noreturn handle_stack_overflow(const char *message,
 }
 #endif
 
-#if defined(CONFIG_X86_64) || defined(CONFIG_DOUBLEFAULT)
 /*
  * Runs on an IST stack for x86_64 and on a special task stack for x86_32.
  *
@@ -450,7 +449,6 @@ dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code, unsign
 	die("double fault", regs, error_code);
 	panic("Machine halted.");
 }
-#endif
 
 dotraplinkage void do_bounds(struct pt_regs *regs, long error_code)
 {
diff --git a/arch/x86/kernel/umip.c b/arch/x86/kernel/umip.c
index 4d732a444711..8d5cbe1bbb3b 100644
--- a/arch/x86/kernel/umip.c
+++ b/arch/x86/kernel/umip.c
@@ -81,7 +81,7 @@
 #define	UMIP_INST_SLDT  3       /* 0F 00 /0 */
 #define	UMIP_INST_STR   4       /* 0F 00 /1 */
 
-const char * const umip_insns[5] = {
+static const char * const umip_insns[5] = {
 	[UMIP_INST_SGDT] = "SGDT",
 	[UMIP_INST_SIDT] = "SIDT",
 	[UMIP_INST_SMSW] = "SMSW",
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index 5246db42de45..6110bce7237b 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -6,10 +6,19 @@
 # Produces uninteresting flaky coverage.
 KCOV_INSTRUMENT_delay.o	:= n
 
+# KCSAN uses udelay for introducing watchpoint delay; avoid recursion.
+KCSAN_SANITIZE_delay.o := n
+ifdef CONFIG_KCSAN
+# In case KCSAN+lockdep+ftrace are enabled, disable ftrace for delay.o to avoid
+# lockdep -> [other libs] -> KCSAN -> udelay -> ftrace -> lockdep recursion.
+CFLAGS_REMOVE_delay.o = $(CC_FLAGS_FTRACE)
+endif
+
 # Early boot use of cmdline; don't instrument it
 ifdef CONFIG_AMD_MEM_ENCRYPT
 KCOV_INSTRUMENT_cmdline.o := n
 KASAN_SANITIZE_cmdline.o  := n
+KCSAN_SANITIZE_cmdline.o  := n
 
 ifdef CONFIG_FUNCTION_TRACER
 CFLAGS_REMOVE_cmdline.o = -pg
diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile
index 98f7c6fa2eaa..f7fd0e868c9c 100644
--- a/arch/x86/mm/Makefile
+++ b/arch/x86/mm/Makefile
@@ -7,6 +7,10 @@ KCOV_INSTRUMENT_mem_encrypt_identity.o	:= n
 KASAN_SANITIZE_mem_encrypt.o		:= n
 KASAN_SANITIZE_mem_encrypt_identity.o	:= n
 
+# Disable KCSAN entirely, because otherwise we get warnings that some functions
+# reference __initdata sections.
+KCSAN_SANITIZE := n
+
 ifdef CONFIG_FUNCTION_TRACER
 CFLAGS_REMOVE_mem_encrypt.o		= -pg
 CFLAGS_REMOVE_mem_encrypt_identity.o	= -pg
diff --git a/arch/x86/mm/cpu_entry_area.c b/arch/x86/mm/cpu_entry_area.c
index 56f9189bbadb..5199d8a1daf1 100644
--- a/arch/x86/mm/cpu_entry_area.c
+++ b/arch/x86/mm/cpu_entry_area.c
@@ -17,7 +17,7 @@ static DEFINE_PER_CPU_PAGE_ALIGNED(struct exception_stacks, exception_stacks);
 DEFINE_PER_CPU(struct cea_exception_stacks*, cea_exception_stacks);
 #endif
 
-#if defined(CONFIG_X86_32) && defined(CONFIG_DOUBLEFAULT)
+#ifdef CONFIG_X86_32
 DECLARE_PER_CPU_PAGE_ALIGNED(struct doublefault_stack, doublefault_stack);
 #endif
 
@@ -114,12 +114,10 @@ static void __init percpu_setup_exception_stacks(unsigned int cpu)
 #else
 static inline void percpu_setup_exception_stacks(unsigned int cpu)
 {
-#ifdef CONFIG_DOUBLEFAULT
 	struct cpu_entry_area *cea = get_cpu_entry_area(cpu);
 
 	cea_map_percpu_pages(&cea->doublefault_stack,
 			     &per_cpu(doublefault_stack, cpu), 1, PAGE_KERNEL);
-#endif
 }
 #endif
 
diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
index 59eca6a94ce7..291b1c9d489c 100644
--- a/arch/x86/mm/pat/set_memory.c
+++ b/arch/x86/mm/pat/set_memory.c
@@ -129,7 +129,7 @@ static inline void cpa_inc_2m_checked(void)
 
 static inline void cpa_inc_4k_install(void)
 {
-	cpa_4k_install++;
+	data_race(cpa_4k_install++);
 }
 
 static inline void cpa_inc_lp_sameprot(int level)
diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c
index 211bb9358b73..c5e393f8bb3f 100644
--- a/arch/x86/platform/efi/efi_64.c
+++ b/arch/x86/platform/efi/efi_64.c
@@ -202,7 +202,7 @@ virt_to_phys_or_null_size(void *va, unsigned long size)
 
 int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages)
 {
-	unsigned long pfn, text, pf;
+	unsigned long pfn, text, pf, rodata;
 	struct page *page;
 	unsigned npages;
 	pgd_t *pgd = efi_mm.pgd;
@@ -256,7 +256,7 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages)
 
 	efi_scratch.phys_stack = page_to_phys(page + 1); /* stack grows down */
 
-	npages = (__end_rodata_aligned - _text) >> PAGE_SHIFT;
+	npages = (_etext - _text) >> PAGE_SHIFT;
 	text = __pa(_text);
 	pfn = text >> PAGE_SHIFT;
 
@@ -266,6 +266,14 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages)
 		return 1;
 	}
 
+	npages = (__end_rodata - __start_rodata) >> PAGE_SHIFT;
+	rodata = __pa(__start_rodata);
+	pfn = rodata >> PAGE_SHIFT;
+	if (kernel_map_pages_in_pgd(pgd, pfn, rodata, npages, pf)) {
+		pr_err("Failed to map kernel rodata 1:1\n");
+		return 1;
+	}
+
 	return 0;
 }
 
@@ -638,7 +646,7 @@ efi_thunk_set_variable(efi_char16_t *name, efi_guid_t *vendor,
 	phys_vendor = virt_to_phys_or_null(vnd);
 	phys_data = virt_to_phys_or_null_size(data, data_size);
 
-	if (!phys_name || !phys_data)
+	if (!phys_name || (data && !phys_data))
 		status = EFI_INVALID_PARAMETER;
 	else
 		status = efi_thunk(set_variable, phys_name, phys_vendor,
@@ -669,7 +677,7 @@ efi_thunk_set_variable_nonblocking(efi_char16_t *name, efi_guid_t *vendor,
 	phys_vendor = virt_to_phys_or_null(vnd);
 	phys_data = virt_to_phys_or_null_size(data, data_size);
 
-	if (!phys_name || !phys_data)
+	if (!phys_name || (data && !phys_data))
 		status = EFI_INVALID_PARAMETER;
 	else
 		status = efi_thunk(set_variable, phys_name, phys_vendor,
diff --git a/arch/x86/purgatory/.gitignore b/arch/x86/purgatory/.gitignore
new file mode 100644
index 000000000000..d2be1500671d
--- /dev/null
+++ b/arch/x86/purgatory/.gitignore
@@ -0,0 +1 @@
+purgatory.chk
diff --git a/arch/x86/purgatory/Makefile b/arch/x86/purgatory/Makefile
index fb4ee5444379..b04e6e72a592 100644
--- a/arch/x86/purgatory/Makefile
+++ b/arch/x86/purgatory/Makefile
@@ -14,10 +14,18 @@ $(obj)/sha256.o: $(srctree)/lib/crypto/sha256.c FORCE
 
 CFLAGS_sha256.o := -D__DISABLE_EXPORTS
 
-LDFLAGS_purgatory.ro := -e purgatory_start -r --no-undefined -nostdlib -z nodefaultlib
-targets += purgatory.ro
-
+# When linking purgatory.ro with -r unresolved symbols are not checked,
+# also link a purgatory.chk binary without -r to check for unresolved symbols.
+PURGATORY_LDFLAGS := -e purgatory_start -nostdlib -z nodefaultlib
+LDFLAGS_purgatory.ro := -r $(PURGATORY_LDFLAGS)
+LDFLAGS_purgatory.chk := $(PURGATORY_LDFLAGS)
+targets += purgatory.ro purgatory.chk
+
+# Sanitizer, etc. runtimes are unavailable and cannot be linked here.
+GCOV_PROFILE	:= n
 KASAN_SANITIZE	:= n
+UBSAN_SANITIZE	:= n
+KCSAN_SANITIZE	:= n
 KCOV_INSTRUMENT := n
 
 # These are adjustments to the compiler flags used for objects that
@@ -25,7 +33,7 @@ KCOV_INSTRUMENT := n
 
 PURGATORY_CFLAGS_REMOVE := -mcmodel=kernel
 PURGATORY_CFLAGS := -mcmodel=large -ffreestanding -fno-zero-initialized-in-bss
-PURGATORY_CFLAGS += $(DISABLE_STACKLEAK_PLUGIN)
+PURGATORY_CFLAGS += $(DISABLE_STACKLEAK_PLUGIN) -DDISABLE_BRANCH_PROFILING
 
 # Default KBUILD_CFLAGS can have -pg option set when FTRACE is enabled. That
 # in turn leaves some undefined symbols like __fentry__ in purgatory and not
@@ -58,12 +66,15 @@ CFLAGS_string.o			+= $(PURGATORY_CFLAGS)
 $(obj)/purgatory.ro: $(PURGATORY_OBJS) FORCE
 		$(call if_changed,ld)
 
+$(obj)/purgatory.chk: $(obj)/purgatory.ro FORCE
+		$(call if_changed,ld)
+
 targets += kexec-purgatory.c
 
 quiet_cmd_bin2c = BIN2C   $@
       cmd_bin2c = $(objtree)/scripts/bin2c kexec_purgatory < $< > $@
 
-$(obj)/kexec-purgatory.c: $(obj)/purgatory.ro FORCE
+$(obj)/kexec-purgatory.c: $(obj)/purgatory.ro $(obj)/purgatory.chk FORCE
 	$(call if_changed,bin2c)
 
 obj-$(CONFIG_KEXEC_FILE)	+= kexec-purgatory.o
diff --git a/arch/x86/realmode/Makefile b/arch/x86/realmode/Makefile
index 682c895753d9..6b1f3a4eeb44 100644
--- a/arch/x86/realmode/Makefile
+++ b/arch/x86/realmode/Makefile
@@ -6,7 +6,10 @@
 # for more details.
 #
 #
+
+# Sanitizer runtimes are unavailable and cannot be linked here.
 KASAN_SANITIZE			:= n
+KCSAN_SANITIZE			:= n
 OBJECT_FILES_NON_STANDARD	:= y
 
 subdir- := rm
diff --git a/arch/x86/realmode/rm/Makefile b/arch/x86/realmode/rm/Makefile
index b11ec5d8f8ac..83f1b6a56449 100644
--- a/arch/x86/realmode/rm/Makefile
+++ b/arch/x86/realmode/rm/Makefile
@@ -6,7 +6,10 @@
 # for more details.
 #
 #
+
+# Sanitizer runtimes are unavailable and cannot be linked here.
 KASAN_SANITIZE			:= n
+KCSAN_SANITIZE			:= n
 OBJECT_FILES_NON_STANDARD	:= y
 
 # Prevents link failures: __sanitizer_cov_trace_pc() is not linked in.
diff --git a/arch/xtensa/kernel/syscalls/syscall.tbl b/arch/xtensa/kernel/syscalls/syscall.tbl
index 85a9ab1bc04d..165cae047770 100644
--- a/arch/xtensa/kernel/syscalls/syscall.tbl
+++ b/arch/xtensa/kernel/syscalls/syscall.tbl
@@ -408,3 +408,4 @@
 435	common	clone3				sys_clone3
 437	common	openat2				sys_openat2
 438	common	pidfd_getfd			sys_pidfd_getfd
+439	common	process_madvise			sys_process_madvise
diff --git a/crypto/algapi.c b/crypto/algapi.c
index 69605e21af92..f1e6ccaff853 100644
--- a/crypto/algapi.c
+++ b/crypto/algapi.c
@@ -403,7 +403,7 @@ static void crypto_wait_for_test(struct crypto_larval *larval)
 	err = wait_for_completion_killable(&larval->completion);
 	WARN_ON(err);
 	if (!err)
-		crypto_probing_notify(CRYPTO_MSG_ALG_LOADED, larval);
+		crypto_notify(CRYPTO_MSG_ALG_LOADED, larval);
 
 out:
 	crypto_larval_kill(&larval->alg);
@@ -716,17 +716,27 @@ EXPORT_SYMBOL_GPL(crypto_drop_spawn);
 
 static struct crypto_alg *crypto_spawn_alg(struct crypto_spawn *spawn)
 {
-	struct crypto_alg *alg;
+	struct crypto_alg *alg = ERR_PTR(-EAGAIN);
+	struct crypto_alg *target;
+	bool shoot = false;
 
 	down_read(&crypto_alg_sem);
-	alg = spawn->alg;
-	if (!spawn->dead && !crypto_mod_get(alg)) {
-		alg->cra_flags |= CRYPTO_ALG_DYING;
-		alg = NULL;
+	if (!spawn->dead) {
+		alg = spawn->alg;
+		if (!crypto_mod_get(alg)) {
+			target = crypto_alg_get(alg);
+			shoot = true;
+			alg = ERR_PTR(-EAGAIN);
+		}
 	}
 	up_read(&crypto_alg_sem);
 
-	return alg ?: ERR_PTR(-EAGAIN);
+	if (shoot) {
+		crypto_shoot_alg(target);
+		crypto_alg_put(target);
+	}
+
+	return alg;
 }
 
 struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn, u32 type,
diff --git a/crypto/api.c b/crypto/api.c
index 7d71a9b10e5f..edcf690800d4 100644
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -333,12 +333,13 @@ static unsigned int crypto_ctxsize(struct crypto_alg *alg, u32 type, u32 mask)
 	return len;
 }
 
-static void crypto_shoot_alg(struct crypto_alg *alg)
+void crypto_shoot_alg(struct crypto_alg *alg)
 {
 	down_write(&crypto_alg_sem);
 	alg->cra_flags |= CRYPTO_ALG_DYING;
 	up_write(&crypto_alg_sem);
 }
+EXPORT_SYMBOL_GPL(crypto_shoot_alg);
 
 struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 type,
 				      u32 mask)
diff --git a/crypto/internal.h b/crypto/internal.h
index d5ebc60c5143..ff06a3bd1ca1 100644
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -65,6 +65,7 @@ void crypto_alg_tested(const char *name, int err);
 void crypto_remove_spawns(struct crypto_alg *alg, struct list_head *list,
 			  struct crypto_alg *nalg);
 void crypto_remove_final(struct list_head *list);
+void crypto_shoot_alg(struct crypto_alg *alg);
 struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 type,
 				      u32 mask);
 void *crypto_create_tfm(struct crypto_alg *alg,
diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c
index 8596a106a933..f138e12b7b82 100644
--- a/drivers/acpi/acpi_extlog.c
+++ b/drivers/acpi/acpi_extlog.c
@@ -42,8 +42,6 @@ struct extlog_l1_head {
 	u8  rev1[12];
 };
 
-static int old_edac_report_status;
-
 static u8 extlog_dsm_uuid[] __initdata = "663E35AF-CC10-41A4-88EA-5470AF055295";
 
 /* L1 table related physical address */
@@ -146,7 +144,7 @@ static int extlog_print(struct notifier_block *nb, unsigned long val,
 	static u32 err_seq;
 
 	estatus = extlog_elog_entry_check(cpu, bank);
-	if (estatus == NULL)
+	if (estatus == NULL || (mce->kflags & MCE_HANDLED_CEC))
 		return NOTIFY_DONE;
 
 	memcpy(elog_buf, (void *)estatus, ELOG_ENTRY_LEN);
@@ -176,7 +174,8 @@ static int extlog_print(struct notifier_block *nb, unsigned long val,
 	}
 
 out:
-	return NOTIFY_STOP;
+	mce->kflags |= MCE_HANDLED_EXTLOG;
+	return NOTIFY_OK;
 }
 
 static bool __init extlog_get_l1addr(void)
@@ -228,11 +227,6 @@ static int __init extlog_init(void)
 	if (!(cap & MCG_ELOG_P) || !extlog_get_l1addr())
 		return -ENODEV;
 
-	if (edac_get_report_status() == EDAC_REPORTING_FORCE) {
-		pr_warn("Not loading eMCA, error reporting force-enabled through EDAC.\n");
-		return -EPERM;
-	}
-
 	rc = -EINVAL;
 	/* get L1 header to fetch necessary information */
 	l1_hdr_size = sizeof(struct extlog_l1_head);
@@ -280,12 +274,6 @@ static int __init extlog_init(void)
 	if (elog_buf == NULL)
 		goto err_release_elog;
 
-	/*
-	 * eMCA event report method has higher priority than EDAC method,
-	 * unless EDAC event report method is mandatory.
-	 */
-	old_edac_report_status = edac_get_report_status();
-	edac_set_report_status(EDAC_REPORTING_DISABLED);
 	mce_register_decode_chain(&extlog_mce_dec);
 	/* enable OS to be involved to take over management from BIOS */
 	((struct extlog_l1_head *)extlog_l1_addr)->flags |= FLAG_OS_OPTIN;
@@ -307,7 +295,6 @@ static int __init extlog_init(void)
 
 static void __exit extlog_exit(void)
 {
-	edac_set_report_status(old_edac_report_status);
 	mce_unregister_decode_chain(&extlog_mce_dec);
 	((struct extlog_l1_head *)extlog_l1_addr)->flags &= ~FLAG_OS_OPTIN;
 	if (extlog_l1_addr)
diff --git a/drivers/acpi/nfit/mce.c b/drivers/acpi/nfit/mce.c
index f0ae48515b48..ee8d9973f60b 100644
--- a/drivers/acpi/nfit/mce.c
+++ b/drivers/acpi/nfit/mce.c
@@ -76,6 +76,7 @@ static int nfit_handle_mce(struct notifier_block *nb, unsigned long val,
 			 */
 			acpi_nfit_ars_rescan(acpi_desc, 0);
 		}
+		mce->kflags |= MCE_HANDLED_NFIT;
 		break;
 	}
 
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index dbec3a05590a..2b09b68b9f78 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -21,6 +21,7 @@
 #include <linux/mm.h>
 #include <linux/stat.h>
 #include <linux/slab.h>
+#include <linux/xarray.h>
 
 #include <linux/atomic.h>
 #include <linux/uaccess.h>
@@ -74,6 +75,13 @@ static struct bus_type memory_subsys = {
 	.offline = memory_subsys_offline,
 };
 
+/*
+ * Memory blocks are cached in a local radix tree to avoid
+ * a costly linear search for the corresponding device on
+ * the subsystem bus.
+ */
+static DEFINE_XARRAY(memory_blocks);
+
 static BLOCKING_NOTIFIER_HEAD(memory_chain);
 
 int register_memory_notifier(struct notifier_block *nb)
@@ -489,22 +497,23 @@ int __weak arch_get_memory_phys_device(unsigned long start_pfn)
 	return 0;
 }
 
-/* A reference for the returned memory block device is acquired. */
+/*
+ * A reference for the returned memory block device is acquired.
+ *
+ * Called under device_hotplug_lock.
+ */
 static struct memory_block *find_memory_block_by_id(unsigned long block_id)
 {
-	struct device *dev;
+	struct memory_block *mem;
 
-	dev = subsys_find_device_by_id(&memory_subsys, block_id, NULL);
-	return dev ? to_memory_block(dev) : NULL;
+	mem = xa_load(&memory_blocks, block_id);
+	if (mem)
+		get_device(&mem->dev);
+	return mem;
 }
 
 /*
- * For now, we have a linear search to go find the appropriate
- * memory_block corresponding to a particular phys_index. If
- * this gets to be a real problem, we can always use a radix
- * tree or something here.
- *
- * This could be made generic for all device subsystems.
+ * Called under device_hotplug_lock.
  */
 struct memory_block *find_memory_block(struct mem_section *section)
 {
@@ -548,9 +557,16 @@ int register_memory(struct memory_block *memory)
 	memory->dev.offline = memory->state == MEM_OFFLINE;
 
 	ret = device_register(&memory->dev);
-	if (ret)
+	if (ret) {
 		put_device(&memory->dev);
-
+		return ret;
+	}
+	ret = xa_err(xa_store(&memory_blocks, memory->dev.id, memory,
+			      GFP_KERNEL));
+	if (ret) {
+		put_device(&memory->dev);
+		device_unregister(&memory->dev);
+	}
 	return ret;
 }
 
@@ -604,6 +620,8 @@ static void unregister_memory(struct memory_block *memory)
 	if (WARN_ON_ONCE(memory->dev.bus != &memory_subsys))
 		return;
 
+	WARN_ON(xa_erase(&memory_blocks, memory->dev.id) == NULL);
+
 	/* drop the ref. we got via find_memory_block() */
 	put_device(&memory->dev);
 	device_unregister(&memory->dev);
@@ -750,6 +768,8 @@ void __init memory_dev_init(void)
  *
  * In case func() returns an error, walking is aborted and the error is
  * returned.
+ *
+ * Called under device_hotplug_lock.
  */
 int walk_memory_blocks(unsigned long start, unsigned long size,
 		       void *arg, walk_memory_blocks_func_t func)
diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c
index e72843fe41df..089e5dc7144a 100644
--- a/drivers/base/regmap/regmap-debugfs.c
+++ b/drivers/base/regmap/regmap-debugfs.c
@@ -227,6 +227,9 @@ static ssize_t regmap_read_debugfs(struct regmap *map, unsigned int from,
 	if (*ppos < 0 || !count)
 		return -EINVAL;
 
+	if (count > (PAGE_SIZE << (MAX_ORDER - 1)))
+		count = PAGE_SIZE << (MAX_ORDER - 1);
+
 	buf = kmalloc(count, GFP_KERNEL);
 	if (!buf)
 		return -ENOMEM;
@@ -371,6 +374,9 @@ static ssize_t regmap_reg_ranges_read_file(struct file *file,
 	if (*ppos < 0 || !count)
 		return -EINVAL;
 
+	if (count > (PAGE_SIZE << (MAX_ORDER - 1)))
+		count = PAGE_SIZE << (MAX_ORDER - 1);
+
 	buf = kmalloc(count, GFP_KERNEL);
 	if (!buf)
 		return -ENOMEM;
diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c
index 3d64c9331a82..4340e1d268b6 100644
--- a/drivers/base/regmap/regmap-irq.c
+++ b/drivers/base/regmap/regmap-irq.c
@@ -541,8 +541,9 @@ static const struct irq_domain_ops regmap_domain_ops = {
 };
 
 /**
- * regmap_add_irq_chip() - Use standard regmap IRQ controller handling
+ * regmap_add_irq_chip_np() - Use standard regmap IRQ controller handling
  *
+ * @np: The device_node where the IRQ domain should be added to.
  * @map: The regmap for the device.
  * @irq: The IRQ the device uses to signal interrupts.
  * @irq_flags: The IRQF_ flags to use for the primary interrupt.
@@ -556,9 +557,10 @@ static const struct irq_domain_ops regmap_domain_ops = {
  * register cache.  The chip driver is responsible for restoring the
  * register values used by the IRQ controller over suspend and resume.
  */
-int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
-			int irq_base, const struct regmap_irq_chip *chip,
-			struct regmap_irq_chip_data **data)
+int regmap_add_irq_chip_np(struct device_node *np, struct regmap *map, int irq,
+			   int irq_flags, int irq_base,
+			   const struct regmap_irq_chip *chip,
+			   struct regmap_irq_chip_data **data)
 {
 	struct regmap_irq_chip_data *d;
 	int i;
@@ -769,12 +771,10 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
 	}
 
 	if (irq_base)
-		d->domain = irq_domain_add_legacy(map->dev->of_node,
-						  chip->num_irqs, irq_base, 0,
-						  &regmap_domain_ops, d);
+		d->domain = irq_domain_add_legacy(np, chip->num_irqs, irq_base,
+						  0, &regmap_domain_ops, d);
 	else
-		d->domain = irq_domain_add_linear(map->dev->of_node,
-						  chip->num_irqs,
+		d->domain = irq_domain_add_linear(np, chip->num_irqs,
 						  &regmap_domain_ops, d);
 	if (!d->domain) {
 		dev_err(map->dev, "Failed to create IRQ domain\n");
@@ -808,6 +808,30 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
 	kfree(d);
 	return ret;
 }
+EXPORT_SYMBOL_GPL(regmap_add_irq_chip_np);
+
+/**
+ * regmap_add_irq_chip() - Use standard regmap IRQ controller handling
+ *
+ * @map: The regmap for the device.
+ * @irq: The IRQ the device uses to signal interrupts.
+ * @irq_flags: The IRQF_ flags to use for the primary interrupt.
+ * @irq_base: Allocate at specific IRQ number if irq_base > 0.
+ * @chip: Configuration for the interrupt controller.
+ * @data: Runtime data structure for the controller, allocated on success.
+ *
+ * Returns 0 on success or an errno on failure.
+ *
+ * This is the same as regmap_add_irq_chip_np, except that the device
+ * node of the regmap is used.
+ */
+int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
+			int irq_base, const struct regmap_irq_chip *chip,
+			struct regmap_irq_chip_data **data)
+{
+	return regmap_add_irq_chip_np(map->dev->of_node, map, irq, irq_flags,
+				      irq_base, chip, data);
+}
 EXPORT_SYMBOL_GPL(regmap_add_irq_chip);
 
 /**
@@ -875,9 +899,10 @@ static int devm_regmap_irq_chip_match(struct device *dev, void *res, void *data)
 }
 
 /**
- * devm_regmap_add_irq_chip() - Resource manager regmap_add_irq_chip()
+ * devm_regmap_add_irq_chip_np() - Resource manager regmap_add_irq_chip_np()
  *
  * @dev: The device pointer on which irq_chip belongs to.
+ * @np: The device_node where the IRQ domain should be added to.
  * @map: The regmap for the device.
  * @irq: The IRQ the device uses to signal interrupts
  * @irq_flags: The IRQF_ flags to use for the primary interrupt.
@@ -890,10 +915,11 @@ static int devm_regmap_irq_chip_match(struct device *dev, void *res, void *data)
  * The &regmap_irq_chip_data will be automatically released when the device is
  * unbound.
  */
-int devm_regmap_add_irq_chip(struct device *dev, struct regmap *map, int irq,
-			     int irq_flags, int irq_base,
-			     const struct regmap_irq_chip *chip,
-			     struct regmap_irq_chip_data **data)
+int devm_regmap_add_irq_chip_np(struct device *dev, struct device_node *np,
+				struct regmap *map, int irq, int irq_flags,
+				int irq_base,
+				const struct regmap_irq_chip *chip,
+				struct regmap_irq_chip_data **data)
 {
 	struct regmap_irq_chip_data **ptr, *d;
 	int ret;
@@ -903,8 +929,8 @@ int devm_regmap_add_irq_chip(struct device *dev, struct regmap *map, int irq,
 	if (!ptr)
 		return -ENOMEM;
 
-	ret = regmap_add_irq_chip(map, irq, irq_flags, irq_base,
-				  chip, &d);
+	ret = regmap_add_irq_chip_np(np, map, irq, irq_flags, irq_base,
+				     chip, &d);
 	if (ret < 0) {
 		devres_free(ptr);
 		return ret;
@@ -915,6 +941,32 @@ int devm_regmap_add_irq_chip(struct device *dev, struct regmap *map, int irq,
 	*data = d;
 	return 0;
 }
+EXPORT_SYMBOL_GPL(devm_regmap_add_irq_chip_np);
+
+/**
+ * devm_regmap_add_irq_chip() - Resource manager regmap_add_irq_chip()
+ *
+ * @dev: The device pointer on which irq_chip belongs to.
+ * @map: The regmap for the device.
+ * @irq: The IRQ the device uses to signal interrupts
+ * @irq_flags: The IRQF_ flags to use for the primary interrupt.
+ * @irq_base: Allocate at specific IRQ number if irq_base > 0.
+ * @chip: Configuration for the interrupt controller.
+ * @data: Runtime data structure for the controller, allocated on success
+ *
+ * Returns 0 on success or an errno on failure.
+ *
+ * The &regmap_irq_chip_data will be automatically released when the device is
+ * unbound.
+ */
+int devm_regmap_add_irq_chip(struct device *dev, struct regmap *map, int irq,
+			     int irq_flags, int irq_base,
+			     const struct regmap_irq_chip *chip,
+			     struct regmap_irq_chip_data **data)
+{
+	return devm_regmap_add_irq_chip_np(dev, map->dev->of_node, map, irq,
+					   irq_flags, irq_base, chip, data);
+}
 EXPORT_SYMBOL_GPL(devm_regmap_add_irq_chip);
 
 /**
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 59f911e57719..553d92aa0c68 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -827,6 +827,7 @@ struct regmap *__regmap_init(struct device *dev,
 	} else if (!bus->read || !bus->write) {
 		map->reg_read = _regmap_bus_reg_read;
 		map->reg_write = _regmap_bus_reg_write;
+		map->reg_update_bits = bus->reg_update_bits;
 
 		map->defer_caching = false;
 		goto skip_format_initialization;
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 1e0a6b19ae0d..67d65ac785e9 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -3754,11 +3754,7 @@ static int __rbd_notify_op_lock(struct rbd_device *rbd_dev,
 static void rbd_notify_op_lock(struct rbd_device *rbd_dev,
 			       enum rbd_notify_op notify_op)
 {
-	struct page **reply_pages;
-	size_t reply_len;
-
-	__rbd_notify_op_lock(rbd_dev, notify_op, &reply_pages, &reply_len);
-	ceph_release_page_vector(reply_pages, calc_pages_for(0, reply_len));
+	__rbd_notify_op_lock(rbd_dev, notify_op, NULL, NULL);
 }
 
 static void rbd_notify_acquired_lock(struct work_struct *work)
@@ -4527,6 +4523,10 @@ static void cancel_tasks_sync(struct rbd_device *rbd_dev)
 	cancel_work_sync(&rbd_dev->unlock_work);
 }
 
+/*
+ * header_rwsem must not be held to avoid a deadlock with
+ * rbd_dev_refresh() when flushing notifies.
+ */
 static void rbd_unregister_watch(struct rbd_device *rbd_dev)
 {
 	cancel_tasks_sync(rbd_dev);
@@ -6894,9 +6894,10 @@ static void rbd_print_dne(struct rbd_device *rbd_dev, bool is_snap)
 
 static void rbd_dev_image_release(struct rbd_device *rbd_dev)
 {
-	rbd_dev_unprobe(rbd_dev);
-	if (rbd_dev->opts)
+	if (!rbd_is_ro(rbd_dev))
 		rbd_unregister_watch(rbd_dev);
+
+	rbd_dev_unprobe(rbd_dev);
 	rbd_dev->image_format = 0;
 	kfree(rbd_dev->spec->image_id);
 	rbd_dev->spec->image_id = NULL;
@@ -6907,6 +6908,9 @@ static void rbd_dev_image_release(struct rbd_device *rbd_dev)
  * device.  If this image is the one being mapped (i.e., not a
  * parent), initiate a watch on its header object before using that
  * object to get detailed information about the rbd image.
+ *
+ * On success, returns with header_rwsem held for write if called
+ * with @depth == 0.
  */
 static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth)
 {
@@ -6936,11 +6940,14 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth)
 		}
 	}
 
+	if (!depth)
+		down_write(&rbd_dev->header_rwsem);
+
 	ret = rbd_dev_header_info(rbd_dev);
 	if (ret) {
 		if (ret == -ENOENT && !need_watch)
 			rbd_print_dne(rbd_dev, false);
-		goto err_out_watch;
+		goto err_out_probe;
 	}
 
 	/*
@@ -6985,10 +6992,11 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth)
 	return 0;
 
 err_out_probe:
-	rbd_dev_unprobe(rbd_dev);
-err_out_watch:
+	if (!depth)
+		up_write(&rbd_dev->header_rwsem);
 	if (need_watch)
 		rbd_unregister_watch(rbd_dev);
+	rbd_dev_unprobe(rbd_dev);
 err_out_format:
 	rbd_dev->image_format = 0;
 	kfree(rbd_dev->spec->image_id);
@@ -7050,12 +7058,9 @@ static ssize_t do_rbd_add(struct bus_type *bus,
 		goto err_out_rbd_dev;
 	}
 
-	down_write(&rbd_dev->header_rwsem);
 	rc = rbd_dev_image_probe(rbd_dev, 0);
-	if (rc < 0) {
-		up_write(&rbd_dev->header_rwsem);
+	if (rc < 0)
 		goto err_out_rbd_dev;
-	}
 
 	if (rbd_dev->opts->alloc_size > rbd_dev->layout.object_size) {
 		rbd_warn(rbd_dev, "alloc_size adjusted to %u",
diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
index a16845c0751d..3ea866d44568 100644
--- a/drivers/bluetooth/btqca.c
+++ b/drivers/bluetooth/btqca.c
@@ -32,7 +32,7 @@ int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version,
 	 * VSE event. WCN3991 sends version command response as a payload to
 	 * command complete event.
 	 */
-	if (soc_type == QCA_WCN3991) {
+	if (soc_type >= QCA_WCN3991) {
 		event_type = 0;
 		rlen += 1;
 		rtype = EDL_PATCH_VER_REQ_CMD;
@@ -69,7 +69,7 @@ int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version,
 		goto out;
 	}
 
-	if (soc_type == QCA_WCN3991)
+	if (soc_type >= QCA_WCN3991)
 		memmove(&edl->data, &edl->data[1], sizeof(*ver));
 
 	ver = (struct qca_btsoc_version *)(edl->data);
@@ -217,7 +217,7 @@ static void qca_tlv_check_data(struct qca_fw_config *config,
 				tlv_nvm->data[0] |= 0x80;
 
 				/* UART Baud Rate */
-				if (soc_type == QCA_WCN3991)
+				if (soc_type >= QCA_WCN3991)
 					tlv_nvm->data[1] = nvm_baud_rate;
 				else
 					tlv_nvm->data[2] = nvm_baud_rate;
@@ -268,7 +268,7 @@ static int qca_tlv_send_segment(struct hci_dev *hdev, int seg_size,
 	 * VSE event. WCN3991 sends version command response as a payload to
 	 * command complete event.
 	 */
-	if (soc_type == QCA_WCN3991) {
+	if (soc_type >= QCA_WCN3991) {
 		event_type = 0;
 		rlen = sizeof(*edl);
 		rtype = EDL_PATCH_TLV_REQ_CMD;
@@ -301,7 +301,7 @@ static int qca_tlv_send_segment(struct hci_dev *hdev, int seg_size,
 		err = -EIO;
 	}
 
-	if (soc_type == QCA_WCN3991)
+	if (soc_type >= QCA_WCN3991)
 		goto out;
 
 	tlv_resp = (struct tlv_seg_resp *)(edl->data);
@@ -442,6 +442,11 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
 			    (soc_ver & 0x0000000f);
 		snprintf(config.fwname, sizeof(config.fwname),
 			 "qca/crbtfw%02x.tlv", rom_ver);
+	} else if (soc_type == QCA_QCA6390) {
+		rom_ver = ((soc_ver & 0x00000f00) >> 0x04) |
+			    (soc_ver & 0x0000000f);
+		snprintf(config.fwname, sizeof(config.fwname),
+			 "qca/htbtfw%02x.tlv", rom_ver);
 	} else {
 		snprintf(config.fwname, sizeof(config.fwname),
 			 "qca/rampatch_%08x.bin", soc_ver);
@@ -464,6 +469,9 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
 	else if (qca_is_wcn399x(soc_type))
 		snprintf(config.fwname, sizeof(config.fwname),
 			 "qca/crnv%02x.bin", rom_ver);
+	else if (soc_type == QCA_QCA6390)
+		snprintf(config.fwname, sizeof(config.fwname),
+			 "qca/htnv%02x.bin", rom_ver);
 	else
 		snprintf(config.fwname, sizeof(config.fwname),
 			 "qca/nvm_%08x.bin", soc_ver);
diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h
index e16a4d650597..6e1e62dd4b95 100644
--- a/drivers/bluetooth/btqca.h
+++ b/drivers/bluetooth/btqca.h
@@ -125,8 +125,9 @@ enum qca_btsoc_type {
 	QCA_AR3002,
 	QCA_ROME,
 	QCA_WCN3990,
-	QCA_WCN3991,
 	QCA_WCN3998,
+	QCA_WCN3991,
+	QCA_QCA6390,
 };
 
 #if IS_ENABLED(CONFIG_BT_QCA)
diff --git a/drivers/bluetooth/btrtl.c b/drivers/bluetooth/btrtl.c
index 67f4bc21e7c5..3a9afc905f24 100644
--- a/drivers/bluetooth/btrtl.c
+++ b/drivers/bluetooth/btrtl.c
@@ -130,12 +130,19 @@ static const struct id_table ic_id_table[] = {
 	  .cfg_name = "rtl_bt/rtl8821c_config" },
 
 	/* 8761A */
-	{ IC_MATCH_FL_LMPSUBV, RTL_ROM_LMP_8761A, 0x0,
+	{ IC_INFO(RTL_ROM_LMP_8761A, 0xa),
 	  .config_needed = false,
 	  .has_rom_version = true,
 	  .fw_name  = "rtl_bt/rtl8761a_fw.bin",
 	  .cfg_name = "rtl_bt/rtl8761a_config" },
 
+	/* 8761B */
+	{ IC_INFO(RTL_ROM_LMP_8761A, 0xb),
+	  .config_needed = false,
+	  .has_rom_version = true,
+	  .fw_name  = "rtl_bt/rtl8761b_fw.bin",
+	  .cfg_name = "rtl_bt/rtl8761b_config" },
+
 	/* 8822C with UART interface */
 	{ .match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_HCIREV |
 			 IC_MATCH_FL_HCIBUS,
@@ -267,6 +274,7 @@ static int rtlbt_parse_firmware(struct hci_dev *hdev,
 		{ RTL_ROM_LMP_8723B, 9 },	/* 8723D */
 		{ RTL_ROM_LMP_8821A, 10 },	/* 8821C */
 		{ RTL_ROM_LMP_8822B, 13 },	/* 8822C */
+		{ RTL_ROM_LMP_8761A, 14 },	/* 8761B */
 	};
 
 	min_size = sizeof(struct rtl_epatch_header) + sizeof(extension_sig) + 3;
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 3bdec42c9612..871162790a0e 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -492,6 +492,8 @@ struct btusb_data {
 	__u8 cmdreq;
 
 	unsigned int sco_num;
+	unsigned int air_mode;
+	bool usb_alt6_packet_flow;
 	int isoc_altsetting;
 	int suspend_count;
 
@@ -983,6 +985,42 @@ static void btusb_isoc_complete(struct urb *urb)
 	}
 }
 
+static inline void __fill_isoc_descriptor_msbc(struct urb *urb, int len,
+					       int mtu, struct btusb_data *data)
+{
+	int i, offset = 0;
+	unsigned int interval;
+
+	BT_DBG("len %d mtu %d", len, mtu);
+
+	/* For mSBC ALT 6 setting the host will send the packet at continuous
+	 * flow. As per core spec 5, vol 4, part B, table 2.1. For ALT setting
+	 * 6 the HCI PACKET INTERVAL should be 7.5ms for every usb packets.
+	 * To maintain the rate we send 63bytes of usb packets alternatively for
+	 * 7ms and 8ms to maintain the rate as 7.5ms.
+	 */
+	if (data->usb_alt6_packet_flow) {
+		interval = 7;
+		data->usb_alt6_packet_flow = false;
+	} else {
+		interval = 6;
+		data->usb_alt6_packet_flow = true;
+	}
+
+	for (i = 0; i < interval; i++) {
+		urb->iso_frame_desc[i].offset = offset;
+		urb->iso_frame_desc[i].length = offset;
+	}
+
+	if (len && i < BTUSB_MAX_ISOC_FRAMES) {
+		urb->iso_frame_desc[i].offset = offset;
+		urb->iso_frame_desc[i].length = len;
+		i++;
+	}
+
+	urb->number_of_packets = i;
+}
+
 static inline void __fill_isoc_descriptor(struct urb *urb, int len, int mtu)
 {
 	int i, offset = 0;
@@ -1386,9 +1424,13 @@ static struct urb *alloc_isoc_urb(struct hci_dev *hdev, struct sk_buff *skb)
 
 	urb->transfer_flags  = URB_ISO_ASAP;
 
-	__fill_isoc_descriptor(urb, skb->len,
-			       le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize));
-
+	if (data->isoc_altsetting == 6)
+		__fill_isoc_descriptor_msbc(urb, skb->len,
+					    le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize),
+					    data);
+	else
+		__fill_isoc_descriptor(urb, skb->len,
+				       le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize));
 	skb->dev = (void *)hdev;
 
 	return urb;
@@ -1484,6 +1526,7 @@ static void btusb_notify(struct hci_dev *hdev, unsigned int evt)
 
 	if (hci_conn_num(hdev, SCO_LINK) != data->sco_num) {
 		data->sco_num = hci_conn_num(hdev, SCO_LINK);
+		data->air_mode = evt;
 		schedule_work(&data->work);
 	}
 }
@@ -1531,11 +1574,70 @@ static inline int __set_isoc_interface(struct hci_dev *hdev, int altsetting)
 	return 0;
 }
 
+static int btusb_switch_alt_setting(struct hci_dev *hdev, int new_alts)
+{
+	struct btusb_data *data = hci_get_drvdata(hdev);
+	int err;
+
+	if (data->isoc_altsetting != new_alts) {
+		unsigned long flags;
+
+		clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
+		usb_kill_anchored_urbs(&data->isoc_anchor);
+
+		/* When isochronous alternate setting needs to be
+		 * changed, because SCO connection has been added
+		 * or removed, a packet fragment may be left in the
+		 * reassembling state. This could lead to wrongly
+		 * assembled fragments.
+		 *
+		 * Clear outstanding fragment when selecting a new
+		 * alternate setting.
+		 */
+		spin_lock_irqsave(&data->rxlock, flags);
+		kfree_skb(data->sco_skb);
+		data->sco_skb = NULL;
+		spin_unlock_irqrestore(&data->rxlock, flags);
+
+		err = __set_isoc_interface(hdev, new_alts);
+		if (err < 0)
+			return err;
+	}
+
+	if (!test_and_set_bit(BTUSB_ISOC_RUNNING, &data->flags)) {
+		if (btusb_submit_isoc_urb(hdev, GFP_KERNEL) < 0)
+			clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
+		else
+			btusb_submit_isoc_urb(hdev, GFP_KERNEL);
+	}
+
+	return 0;
+}
+
+static struct usb_host_interface *btusb_find_altsetting(struct btusb_data *data,
+							int alt)
+{
+	struct usb_interface *intf = data->isoc;
+	int i;
+
+	BT_DBG("Looking for Alt no :%d", alt);
+
+	if (!intf)
+		return NULL;
+
+	for (i = 0; i < intf->num_altsetting; i++) {
+		if (intf->altsetting[i].desc.bAlternateSetting == alt)
+			return &intf->altsetting[i];
+	}
+
+	return NULL;
+}
+
 static void btusb_work(struct work_struct *work)
 {
 	struct btusb_data *data = container_of(work, struct btusb_data, work);
 	struct hci_dev *hdev = data->hdev;
-	int new_alts;
+	int new_alts = 0;
 	int err;
 
 	if (data->sco_num > 0) {
@@ -1550,44 +1652,27 @@ static void btusb_work(struct work_struct *work)
 			set_bit(BTUSB_DID_ISO_RESUME, &data->flags);
 		}
 
-		if (hdev->voice_setting & 0x0020) {
-			static const int alts[3] = { 2, 4, 5 };
+		if (data->air_mode == HCI_NOTIFY_ENABLE_SCO_CVSD) {
+			if (hdev->voice_setting & 0x0020) {
+				static const int alts[3] = { 2, 4, 5 };
 
-			new_alts = alts[data->sco_num - 1];
-		} else {
-			new_alts = data->sco_num;
-		}
-
-		if (data->isoc_altsetting != new_alts) {
-			unsigned long flags;
-
-			clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
-			usb_kill_anchored_urbs(&data->isoc_anchor);
-
-			/* When isochronous alternate setting needs to be
-			 * changed, because SCO connection has been added
-			 * or removed, a packet fragment may be left in the
-			 * reassembling state. This could lead to wrongly
-			 * assembled fragments.
-			 *
-			 * Clear outstanding fragment when selecting a new
-			 * alternate setting.
-			 */
-			spin_lock_irqsave(&data->rxlock, flags);
-			kfree_skb(data->sco_skb);
-			data->sco_skb = NULL;
-			spin_unlock_irqrestore(&data->rxlock, flags);
+				new_alts = alts[data->sco_num - 1];
+			} else {
+				new_alts = data->sco_num;
+			}
+		} else if (data->air_mode == HCI_NOTIFY_ENABLE_SCO_TRANSP) {
 
-			if (__set_isoc_interface(hdev, new_alts) < 0)
-				return;
-		}
+			data->usb_alt6_packet_flow = true;
 
-		if (!test_and_set_bit(BTUSB_ISOC_RUNNING, &data->flags)) {
-			if (btusb_submit_isoc_urb(hdev, GFP_KERNEL) < 0)
-				clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
+			/* Check if Alt 6 is supported for Transparent audio */
+			if (btusb_find_altsetting(data, 6))
+				new_alts = 6;
 			else
-				btusb_submit_isoc_urb(hdev, GFP_KERNEL);
+				bt_dev_err(hdev, "Device does not support ALT setting 6");
 		}
+
+		if (btusb_switch_alt_setting(hdev, new_alts) < 0)
+			bt_dev_err(hdev, "set USB alt:(%d) failed!", new_alts);
 	} else {
 		clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
 		usb_kill_anchored_urbs(&data->isoc_anchor);
@@ -2252,7 +2337,7 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
 	if (ver.fw_variant == 0x23) {
 		clear_bit(BTUSB_BOOTLOADER, &data->flags);
 		btintel_check_bdaddr(hdev);
-		return 0;
+		goto finish;
 	}
 
 	/* If the device is not in bootloader mode, then the only possible
@@ -2452,6 +2537,23 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
 	 */
 	btintel_load_ddc_config(hdev, fwname);
 
+	/* Read the Intel version information after loading the FW  */
+	err = btintel_read_version(hdev, &ver);
+	if (err)
+		return err;
+
+	btintel_version_info(hdev, &ver);
+
+finish:
+	/* All Intel controllers that support the Microsoft vendor
+	 * extension are using 0xFC1E for VsMsftOpCode.
+	 */
+	switch (ver.hw_variant) {
+	case 0x12:	/* ThP */
+		hci_set_msft_opcode(hdev, 0xFC1E);
+		break;
+	}
+
 	/* Set the event mask for Intel specific vendor events. This enables
 	 * a few extra events that are useful during general operation. It
 	 * does not enable any debugging related events.
@@ -2461,13 +2563,6 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
 	 */
 	btintel_set_event_mask(hdev, false);
 
-	/* Read the Intel version information after loading the FW  */
-	err = btintel_read_version(hdev, &ver);
-	if (err)
-		return err;
-
-	btintel_version_info(hdev, &ver);
-
 	return 0;
 }
 
diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c
index b236cb11c0dc..19e4587f366c 100644
--- a/drivers/bluetooth/hci_bcm.c
+++ b/drivers/bluetooth/hci_bcm.c
@@ -118,6 +118,7 @@ struct bcm_device {
 	u32			oper_speed;
 	int			irq;
 	bool			irq_active_low;
+	bool			irq_acquired;
 
 #ifdef CONFIG_PM
 	struct hci_uart		*hu;
@@ -333,6 +334,8 @@ static int bcm_request_irq(struct bcm_data *bcm)
 		goto unlock;
 	}
 
+	bdev->irq_acquired = true;
+
 	device_init_wakeup(bdev->dev, true);
 
 	pm_runtime_set_autosuspend_delay(bdev->dev,
@@ -514,7 +517,7 @@ static int bcm_close(struct hci_uart *hu)
 	}
 
 	if (bdev) {
-		if (IS_ENABLED(CONFIG_PM) && bdev->irq > 0) {
+		if (IS_ENABLED(CONFIG_PM) && bdev->irq_acquired) {
 			devm_free_irq(bdev->dev, bdev->irq, bdev);
 			device_init_wakeup(bdev->dev, false);
 			pm_runtime_disable(bdev->dev);
@@ -1153,7 +1156,8 @@ static int bcm_of_probe(struct bcm_device *bdev)
 	device_property_read_u8_array(bdev->dev, "brcm,bt-pcm-int-params",
 				      bdev->pcm_int_params, 5);
 	bdev->irq = of_irq_get_byname(bdev->dev->of_node, "host-wakeup");
-
+	bdev->irq_active_low = irq_get_trigger_type(bdev->irq)
+			     & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW);
 	return 0;
 }
 
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 439392b1c043..d0ac554584a4 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -26,6 +26,7 @@
 #include <linux/mod_devicetable.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
+#include <linux/acpi.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
 #include <linux/serdev.h>
@@ -1596,7 +1597,7 @@ static int qca_setup(struct hci_uart *hu)
 	set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
 
 	bt_dev_info(hdev, "setting up %s",
-		qca_is_wcn399x(soc_type) ? "wcn399x" : "ROME");
+		qca_is_wcn399x(soc_type) ? "wcn399x" : "ROME/QCA6390");
 
 retry:
 	ret = qca_power_on(hdev);
@@ -1665,10 +1666,10 @@ static int qca_setup(struct hci_uart *hu)
 	}
 
 	/* Setup bdaddr */
-	if (qca_is_wcn399x(soc_type))
-		hu->hdev->set_bdaddr = qca_set_bdaddr;
-	else
+	if (soc_type == QCA_ROME)
 		hu->hdev->set_bdaddr = qca_set_bdaddr_rome;
+	else
+		hu->hdev->set_bdaddr = qca_set_bdaddr;
 
 	return ret;
 }
@@ -1721,6 +1722,11 @@ static const struct qca_vreg_data qca_soc_data_wcn3998 = {
 	.num_vregs = 4,
 };
 
+static const struct qca_vreg_data qca_soc_data_qca6390 = {
+	.soc_type = QCA_QCA6390,
+	.num_vregs = 0,
+};
+
 static void qca_power_shutdown(struct hci_uart *hu)
 {
 	struct qca_serdev *qcadev;
@@ -1764,7 +1770,7 @@ static int qca_power_off(struct hci_dev *hdev)
 	enum qca_btsoc_type soc_type = qca_soc_type(hu);
 
 	/* Stop sending shutdown command if soc crashes. */
-	if (qca_is_wcn399x(soc_type)
+	if (soc_type != QCA_ROME
 		&& qca->memdump_state == QCA_MEMDUMP_IDLE) {
 		qca_send_pre_shutdown_cmd(hdev);
 		usleep_range(8000, 10000);
@@ -1900,7 +1906,11 @@ static int qca_serdev_probe(struct serdev_device *serdev)
 			return err;
 		}
 	} else {
-		qcadev->btsoc_type = QCA_ROME;
+		if (data)
+			qcadev->btsoc_type = data->soc_type;
+		else
+			qcadev->btsoc_type = QCA_ROME;
+
 		qcadev->bt_en = devm_gpiod_get_optional(&serdev->dev, "enable",
 					       GPIOD_OUT_LOW);
 		if (!qcadev->bt_en) {
@@ -2044,21 +2054,37 @@ static int __maybe_unused qca_resume(struct device *dev)
 
 static SIMPLE_DEV_PM_OPS(qca_pm_ops, qca_suspend, qca_resume);
 
+#ifdef CONFIG_OF
 static const struct of_device_id qca_bluetooth_of_match[] = {
 	{ .compatible = "qcom,qca6174-bt" },
+	{ .compatible = "qcom,qca6390-bt", .data = &qca_soc_data_qca6390},
 	{ .compatible = "qcom,wcn3990-bt", .data = &qca_soc_data_wcn3990},
 	{ .compatible = "qcom,wcn3991-bt", .data = &qca_soc_data_wcn3991},
 	{ .compatible = "qcom,wcn3998-bt", .data = &qca_soc_data_wcn3998},
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, qca_bluetooth_of_match);
+#endif
+
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id qca_bluetooth_acpi_match[] = {
+	{ "QCOM6390", (kernel_ulong_t)&qca_soc_data_qca6390 },
+	{ "DLA16390", (kernel_ulong_t)&qca_soc_data_qca6390 },
+	{ "DLB16390", (kernel_ulong_t)&qca_soc_data_qca6390 },
+	{ "DLB26390", (kernel_ulong_t)&qca_soc_data_qca6390 },
+	{ },
+};
+MODULE_DEVICE_TABLE(acpi, qca_bluetooth_acpi_match);
+#endif
+
 
 static struct serdev_device_driver qca_serdev_driver = {
 	.probe = qca_serdev_probe,
 	.remove = qca_serdev_remove,
 	.driver = {
 		.name = "hci_uart_qca",
-		.of_match_table = qca_bluetooth_of_match,
+		.of_match_table = of_match_ptr(qca_bluetooth_of_match),
+		.acpi_match_table = ACPI_PTR(qca_bluetooth_acpi_match),
 		.pm = &qca_pm_ops,
 	},
 };
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c
index 66a62d17a3f5..3d42fc4290bc 100644
--- a/drivers/char/agp/intel-gtt.c
+++ b/drivers/char/agp/intel-gtt.c
@@ -846,6 +846,7 @@ void intel_gtt_insert_page(dma_addr_t addr,
 			   unsigned int flags)
 {
 	intel_private.driver->write_entry(addr, pg, flags);
+	readl(intel_private.gtt + pg);
 	if (intel_private.driver->chipset_flush)
 		intel_private.driver->chipset_flush();
 }
@@ -871,7 +872,7 @@ void intel_gtt_insert_sg_entries(struct sg_table *st,
 			j++;
 		}
 	}
-	wmb();
+	readl(intel_private.gtt + j - 1);
 	if (intel_private.driver->chipset_flush)
 		intel_private.driver->chipset_flush();
 }
@@ -1105,6 +1106,7 @@ static void i9xx_cleanup(void)
 
 static void i9xx_chipset_flush(void)
 {
+	wmb();
 	if (intel_private.i9xx_flush_page)
 		writel(1, intel_private.i9xx_flush_page);
 }
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index 9bc46da8d77a..848f26f78dc1 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -474,6 +474,18 @@ config HW_RANDOM_KEYSTONE
 	help
 	  This option enables Keystone's hardware random generator.
 
+config HW_RANDOM_CCTRNG
+	tristate "Arm CryptoCell True Random Number Generator support"
+	default HW_RANDOM
+	help
+	  This driver provides support for the True Random Number
+	  Generator available in Arm TrustZone CryptoCell.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called cctrng.
+
+	  If unsure, say Y.
+
 endif # HW_RANDOM
 
 config UML_RANDOM
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
index a7801b49ce6c..2c6724735345 100644
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -41,3 +41,4 @@ obj-$(CONFIG_HW_RANDOM_S390) += s390-trng.o
 obj-$(CONFIG_HW_RANDOM_KEYSTONE) += ks-sa-rng.o
 obj-$(CONFIG_HW_RANDOM_OPTEE) += optee-rng.o
 obj-$(CONFIG_HW_RANDOM_NPCM) += npcm-rng.o
+obj-$(CONFIG_HW_RANDOM_CCTRNG) += cctrng.o
diff --git a/drivers/char/hw_random/cctrng.c b/drivers/char/hw_random/cctrng.c
new file mode 100644
index 000000000000..bdcd56243104
--- /dev/null
+++ b/drivers/char/hw_random/cctrng.c
@@ -0,0 +1,736 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (C) 2019-2020 ARM Limited or its affiliates. */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/hw_random.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/interrupt.h>
+#include <linux/irqreturn.h>
+#include <linux/workqueue.h>
+#include <linux/circ_buf.h>
+#include <linux/completion.h>
+#include <linux/of.h>
+#include <linux/bitfield.h>
+
+#include "cctrng.h"
+
+#define CC_REG_LOW(name)  (name ## _BIT_SHIFT)
+#define CC_REG_HIGH(name) (CC_REG_LOW(name) + name ## _BIT_SIZE - 1)
+#define CC_GENMASK(name)  GENMASK(CC_REG_HIGH(name), CC_REG_LOW(name))
+
+#define CC_REG_FLD_GET(reg_name, fld_name, reg_val)     \
+	(FIELD_GET(CC_GENMASK(CC_ ## reg_name ## _ ## fld_name), reg_val))
+
+#define CC_HW_RESET_LOOP_COUNT 10
+#define CC_TRNG_SUSPEND_TIMEOUT 3000
+
+/* data circular buffer in words must be:
+ *  - of a power-of-2 size (limitation of circ_buf.h macros)
+ *  - at least 6, the size generated in the EHR according to HW implementation
+ */
+#define CCTRNG_DATA_BUF_WORDS 32
+
+/* The timeout for the TRNG operation should be calculated with the formula:
+ * Timeout = EHR_NUM * VN_COEFF * EHR_LENGTH * SAMPLE_CNT * SCALE_VALUE
+ * while:
+ *  - SAMPLE_CNT is input value from the characterisation process
+ *  - all the rest are constants
+ */
+#define EHR_NUM 1
+#define VN_COEFF 4
+#define EHR_LENGTH CC_TRNG_EHR_IN_BITS
+#define SCALE_VALUE 2
+#define CCTRNG_TIMEOUT(smpl_cnt) \
+	(EHR_NUM * VN_COEFF * EHR_LENGTH * smpl_cnt * SCALE_VALUE)
+
+struct cctrng_drvdata {
+	struct platform_device *pdev;
+	void __iomem *cc_base;
+	struct clk *clk;
+	struct hwrng rng;
+	u32 active_rosc;
+	/* Sampling interval for each ring oscillator:
+	 * count of ring oscillator cycles between consecutive bits sampling.
+	 * Value of 0 indicates non-valid rosc
+	 */
+	u32 smpl_ratio[CC_TRNG_NUM_OF_ROSCS];
+
+	u32 data_buf[CCTRNG_DATA_BUF_WORDS];
+	struct circ_buf circ;
+	struct work_struct compwork;
+	struct work_struct startwork;
+
+	/* pending_hw - 1 when HW is pending, 0 when it is idle */
+	atomic_t pending_hw;
+
+	/* protects against multiple concurrent consumers of data_buf */
+	spinlock_t read_lock;
+};
+
+
+/* functions for write/read CC registers */
+static inline void cc_iowrite(struct cctrng_drvdata *drvdata, u32 reg, u32 val)
+{
+	iowrite32(val, (drvdata->cc_base + reg));
+}
+static inline u32 cc_ioread(struct cctrng_drvdata *drvdata, u32 reg)
+{
+	return ioread32(drvdata->cc_base + reg);
+}
+
+
+static int cc_trng_pm_get(struct device *dev)
+{
+	int rc = 0;
+
+	rc = pm_runtime_get_sync(dev);
+
+	/* pm_runtime_get_sync() can return 1 as a valid return code */
+	return (rc == 1 ? 0 : rc);
+}
+
+static void cc_trng_pm_put_suspend(struct device *dev)
+{
+	int rc = 0;
+
+	pm_runtime_mark_last_busy(dev);
+	rc = pm_runtime_put_autosuspend(dev);
+	if (rc)
+		dev_err(dev, "pm_runtime_put_autosuspend returned %x\n", rc);
+}
+
+static int cc_trng_pm_init(struct cctrng_drvdata *drvdata)
+{
+	struct device *dev = &(drvdata->pdev->dev);
+
+	/* must be before the enabling to avoid redundant suspending */
+	pm_runtime_set_autosuspend_delay(dev, CC_TRNG_SUSPEND_TIMEOUT);
+	pm_runtime_use_autosuspend(dev);
+	/* set us as active - note we won't do PM ops until cc_trng_pm_go()! */
+	return pm_runtime_set_active(dev);
+}
+
+static void cc_trng_pm_go(struct cctrng_drvdata *drvdata)
+{
+	struct device *dev = &(drvdata->pdev->dev);
+
+	/* enable the PM module*/
+	pm_runtime_enable(dev);
+}
+
+static void cc_trng_pm_fini(struct cctrng_drvdata *drvdata)
+{
+	struct device *dev = &(drvdata->pdev->dev);
+
+	pm_runtime_disable(dev);
+}
+
+
+static inline int cc_trng_parse_sampling_ratio(struct cctrng_drvdata *drvdata)
+{
+	struct device *dev = &(drvdata->pdev->dev);
+	struct device_node *np = drvdata->pdev->dev.of_node;
+	int rc;
+	int i;
+	/* ret will be set to 0 if at least one rosc has (sampling ratio > 0) */
+	int ret = -EINVAL;
+
+	rc = of_property_read_u32_array(np, "arm,rosc-ratio",
+					drvdata->smpl_ratio,
+					CC_TRNG_NUM_OF_ROSCS);
+	if (rc) {
+		/* arm,rosc-ratio was not found in device tree */
+		return rc;
+	}
+
+	/* verify that at least one rosc has (sampling ratio > 0) */
+	for (i = 0; i < CC_TRNG_NUM_OF_ROSCS; ++i) {
+		dev_dbg(dev, "rosc %d sampling ratio %u",
+			i, drvdata->smpl_ratio[i]);
+
+		if (drvdata->smpl_ratio[i] > 0)
+			ret = 0;
+	}
+
+	return ret;
+}
+
+static int cc_trng_change_rosc(struct cctrng_drvdata *drvdata)
+{
+	struct device *dev = &(drvdata->pdev->dev);
+
+	dev_dbg(dev, "cctrng change rosc (was %d)\n", drvdata->active_rosc);
+	drvdata->active_rosc += 1;
+
+	while (drvdata->active_rosc < CC_TRNG_NUM_OF_ROSCS) {
+		if (drvdata->smpl_ratio[drvdata->active_rosc] > 0)
+			return 0;
+
+		drvdata->active_rosc += 1;
+	}
+	return -EINVAL;
+}
+
+
+static void cc_trng_enable_rnd_source(struct cctrng_drvdata *drvdata)
+{
+	u32 max_cycles;
+
+	/* Set watchdog threshold to maximal allowed time (in CPU cycles) */
+	max_cycles = CCTRNG_TIMEOUT(drvdata->smpl_ratio[drvdata->active_rosc]);
+	cc_iowrite(drvdata, CC_RNG_WATCHDOG_VAL_REG_OFFSET, max_cycles);
+
+	/* enable the RND source */
+	cc_iowrite(drvdata, CC_RND_SOURCE_ENABLE_REG_OFFSET, 0x1);
+
+	/* unmask RNG interrupts */
+	cc_iowrite(drvdata, CC_RNG_IMR_REG_OFFSET, (u32)~CC_RNG_INT_MASK);
+}
+
+
+/* increase circular data buffer index (head/tail) */
+static inline void circ_idx_inc(int *idx, int bytes)
+{
+	*idx += (bytes + 3) >> 2;
+	*idx &= (CCTRNG_DATA_BUF_WORDS - 1);
+}
+
+static inline size_t circ_buf_space(struct cctrng_drvdata *drvdata)
+{
+	return CIRC_SPACE(drvdata->circ.head,
+			  drvdata->circ.tail, CCTRNG_DATA_BUF_WORDS);
+
+}
+
+static int cctrng_read(struct hwrng *rng, void *data, size_t max, bool wait)
+{
+	/* current implementation ignores "wait" */
+
+	struct cctrng_drvdata *drvdata = (struct cctrng_drvdata *)rng->priv;
+	struct device *dev = &(drvdata->pdev->dev);
+	u32 *buf = (u32 *)drvdata->circ.buf;
+	size_t copied = 0;
+	size_t cnt_w;
+	size_t size;
+	size_t left;
+
+	if (!spin_trylock(&drvdata->read_lock)) {
+		/* concurrent consumers from data_buf cannot be served */
+		dev_dbg_ratelimited(dev, "unable to hold lock\n");
+		return 0;
+	}
+
+	/* copy till end of data buffer (without wrap back) */
+	cnt_w = CIRC_CNT_TO_END(drvdata->circ.head,
+				drvdata->circ.tail, CCTRNG_DATA_BUF_WORDS);
+	size = min((cnt_w<<2), max);
+	memcpy(data, &(buf[drvdata->circ.tail]), size);
+	copied = size;
+	circ_idx_inc(&drvdata->circ.tail, size);
+	/* copy rest of data in data buffer */
+	left = max - copied;
+	if (left > 0) {
+		cnt_w = CIRC_CNT(drvdata->circ.head,
+				 drvdata->circ.tail, CCTRNG_DATA_BUF_WORDS);
+		size = min((cnt_w<<2), left);
+		memcpy(data, &(buf[drvdata->circ.tail]), size);
+		copied += size;
+		circ_idx_inc(&drvdata->circ.tail, size);
+	}
+
+	spin_unlock(&drvdata->read_lock);
+
+	if (circ_buf_space(drvdata) >= CC_TRNG_EHR_IN_WORDS) {
+		if (atomic_cmpxchg(&drvdata->pending_hw, 0, 1) == 0) {
+			/* re-check space in buffer to avoid potential race */
+			if (circ_buf_space(drvdata) >= CC_TRNG_EHR_IN_WORDS) {
+				/* increment device's usage counter */
+				int rc = cc_trng_pm_get(dev);
+
+				if (rc) {
+					dev_err(dev,
+						"cc_trng_pm_get returned %x\n",
+						rc);
+					return rc;
+				}
+
+				/* schedule execution of deferred work handler
+				 * for filling of data buffer
+				 */
+				schedule_work(&drvdata->startwork);
+			} else {
+				atomic_set(&drvdata->pending_hw, 0);
+			}
+		}
+	}
+
+	return copied;
+}
+
+static void cc_trng_hw_trigger(struct cctrng_drvdata *drvdata)
+{
+	u32 tmp_smpl_cnt = 0;
+	struct device *dev = &(drvdata->pdev->dev);
+
+	dev_dbg(dev, "cctrng hw trigger.\n");
+
+	/* enable the HW RND clock */
+	cc_iowrite(drvdata, CC_RNG_CLK_ENABLE_REG_OFFSET, 0x1);
+
+	/* do software reset */
+	cc_iowrite(drvdata, CC_RNG_SW_RESET_REG_OFFSET, 0x1);
+	/* in order to verify that the reset has completed,
+	 * the sample count need to be verified
+	 */
+	do {
+		/* enable the HW RND clock   */
+		cc_iowrite(drvdata, CC_RNG_CLK_ENABLE_REG_OFFSET, 0x1);
+
+		/* set sampling ratio (rng_clocks) between consecutive bits */
+		cc_iowrite(drvdata, CC_SAMPLE_CNT1_REG_OFFSET,
+			   drvdata->smpl_ratio[drvdata->active_rosc]);
+
+		/* read the sampling ratio  */
+		tmp_smpl_cnt = cc_ioread(drvdata, CC_SAMPLE_CNT1_REG_OFFSET);
+
+	} while (tmp_smpl_cnt != drvdata->smpl_ratio[drvdata->active_rosc]);
+
+	/* disable the RND source for setting new parameters in HW */
+	cc_iowrite(drvdata, CC_RND_SOURCE_ENABLE_REG_OFFSET, 0);
+
+	cc_iowrite(drvdata, CC_RNG_ICR_REG_OFFSET, 0xFFFFFFFF);
+
+	cc_iowrite(drvdata, CC_TRNG_CONFIG_REG_OFFSET, drvdata->active_rosc);
+
+	/* Debug Control register: set to 0 - no bypasses */
+	cc_iowrite(drvdata, CC_TRNG_DEBUG_CONTROL_REG_OFFSET, 0);
+
+	cc_trng_enable_rnd_source(drvdata);
+}
+
+void cc_trng_compwork_handler(struct work_struct *w)
+{
+	u32 isr = 0;
+	u32 ehr_valid = 0;
+	struct cctrng_drvdata *drvdata =
+			container_of(w, struct cctrng_drvdata, compwork);
+	struct device *dev = &(drvdata->pdev->dev);
+	int i;
+
+	/* stop DMA and the RNG source */
+	cc_iowrite(drvdata, CC_RNG_DMA_ENABLE_REG_OFFSET, 0);
+	cc_iowrite(drvdata, CC_RND_SOURCE_ENABLE_REG_OFFSET, 0);
+
+	/* read RNG_ISR and check for errors */
+	isr = cc_ioread(drvdata, CC_RNG_ISR_REG_OFFSET);
+	ehr_valid = CC_REG_FLD_GET(RNG_ISR, EHR_VALID, isr);
+	dev_dbg(dev, "Got RNG_ISR=0x%08X (EHR_VALID=%u)\n", isr, ehr_valid);
+
+#ifdef CONFIG_CRYPTO_FIPS
+	if (CC_REG_FLD_GET(RNG_ISR, CRNGT_ERR, isr) && fips_enabled) {
+		fips_fail_notify();
+		/* FIPS error is fatal */
+		panic("Got HW CRNGT error while fips is enabled!\n");
+	}
+#endif
+
+	/* Clear all pending RNG interrupts */
+	cc_iowrite(drvdata, CC_RNG_ICR_REG_OFFSET, isr);
+
+
+	if (!ehr_valid) {
+		/* in case of AUTOCORR/TIMEOUT error, try the next ROSC */
+		if (CC_REG_FLD_GET(RNG_ISR, AUTOCORR_ERR, isr) ||
+				CC_REG_FLD_GET(RNG_ISR, WATCHDOG, isr)) {
+			dev_dbg(dev, "cctrng autocorr/timeout error.\n");
+			goto next_rosc;
+		}
+
+		/* in case of VN error, ignore it */
+	}
+
+	/* read EHR data from registers */
+	for (i = 0; i < CC_TRNG_EHR_IN_WORDS; i++) {
+		/* calc word ptr in data_buf */
+		u32 *buf = (u32 *)drvdata->circ.buf;
+
+		buf[drvdata->circ.head] = cc_ioread(drvdata,
+				CC_EHR_DATA_0_REG_OFFSET + (i*sizeof(u32)));
+
+		/* EHR_DATA registers are cleared on read. In case 0 value was
+		 * returned, restart the entropy collection.
+		 */
+		if (buf[drvdata->circ.head] == 0) {
+			dev_dbg(dev, "Got 0 value in EHR. active_rosc %u\n",
+				drvdata->active_rosc);
+			goto next_rosc;
+		}
+
+		circ_idx_inc(&drvdata->circ.head, 1<<2);
+	}
+
+	atomic_set(&drvdata->pending_hw, 0);
+
+	/* continue to fill data buffer if needed */
+	if (circ_buf_space(drvdata) >= CC_TRNG_EHR_IN_WORDS) {
+		if (atomic_cmpxchg(&drvdata->pending_hw, 0, 1) == 0) {
+			/* Re-enable rnd source */
+			cc_trng_enable_rnd_source(drvdata);
+			return;
+		}
+	}
+
+	cc_trng_pm_put_suspend(dev);
+
+	dev_dbg(dev, "compwork handler done\n");
+	return;
+
+next_rosc:
+	if ((circ_buf_space(drvdata) >= CC_TRNG_EHR_IN_WORDS) &&
+			(cc_trng_change_rosc(drvdata) == 0)) {
+		/* trigger trng hw with next rosc */
+		cc_trng_hw_trigger(drvdata);
+	} else {
+		atomic_set(&drvdata->pending_hw, 0);
+		cc_trng_pm_put_suspend(dev);
+	}
+}
+
+static irqreturn_t cc_isr(int irq, void *dev_id)
+{
+	struct cctrng_drvdata *drvdata = (struct cctrng_drvdata *)dev_id;
+	struct device *dev = &(drvdata->pdev->dev);
+	u32 irr;
+
+	/* if driver suspended return, probably shared interrupt */
+	if (pm_runtime_suspended(dev))
+		return IRQ_NONE;
+
+	/* read the interrupt status */
+	irr = cc_ioread(drvdata, CC_HOST_RGF_IRR_REG_OFFSET);
+	dev_dbg(dev, "Got IRR=0x%08X\n", irr);
+
+	if (irr == 0) /* Probably shared interrupt line */
+		return IRQ_NONE;
+
+	/* clear interrupt - must be before processing events */
+	cc_iowrite(drvdata, CC_HOST_RGF_ICR_REG_OFFSET, irr);
+
+	/* RNG interrupt - most probable */
+	if (irr & CC_HOST_RNG_IRQ_MASK) {
+		/* Mask RNG interrupts - will be unmasked in deferred work */
+		cc_iowrite(drvdata, CC_RNG_IMR_REG_OFFSET, 0xFFFFFFFF);
+
+		/* We clear RNG interrupt here,
+		 * to avoid it from firing as we'll unmask RNG interrupts.
+		 */
+		cc_iowrite(drvdata, CC_HOST_RGF_ICR_REG_OFFSET,
+			   CC_HOST_RNG_IRQ_MASK);
+
+		irr &= ~CC_HOST_RNG_IRQ_MASK;
+
+		/* schedule execution of deferred work handler */
+		schedule_work(&drvdata->compwork);
+	}
+
+	if (irr) {
+		dev_dbg_ratelimited(dev,
+				"IRR includes unknown cause bits (0x%08X)\n",
+				irr);
+		/* Just warning */
+	}
+
+	return IRQ_HANDLED;
+}
+
+void cc_trng_startwork_handler(struct work_struct *w)
+{
+	struct cctrng_drvdata *drvdata =
+			container_of(w, struct cctrng_drvdata, startwork);
+
+	drvdata->active_rosc = 0;
+	cc_trng_hw_trigger(drvdata);
+}
+
+
+static int cc_trng_clk_init(struct cctrng_drvdata *drvdata)
+{
+	struct clk *clk;
+	struct device *dev = &(drvdata->pdev->dev);
+	int rc = 0;
+
+	clk = devm_clk_get_optional(dev, NULL);
+	if (IS_ERR(clk)) {
+		if (PTR_ERR(clk) != -EPROBE_DEFER)
+			dev_err(dev, "Error getting clock: %pe\n", clk);
+		return PTR_ERR(clk);
+	}
+	drvdata->clk = clk;
+
+	rc = clk_prepare_enable(drvdata->clk);
+	if (rc) {
+		dev_err(dev, "Failed to enable clock\n");
+		return rc;
+	}
+
+	return 0;
+}
+
+static void cc_trng_clk_fini(struct cctrng_drvdata *drvdata)
+{
+	clk_disable_unprepare(drvdata->clk);
+}
+
+
+static int cctrng_probe(struct platform_device *pdev)
+{
+	struct resource *req_mem_cc_regs = NULL;
+	struct cctrng_drvdata *drvdata;
+	struct device *dev = &pdev->dev;
+	int rc = 0;
+	u32 val;
+	int irq;
+
+	drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
+	if (!drvdata)
+		return -ENOMEM;
+
+	drvdata->rng.name = devm_kstrdup(dev, dev_name(dev), GFP_KERNEL);
+	if (!drvdata->rng.name)
+		return -ENOMEM;
+
+	drvdata->rng.read = cctrng_read;
+	drvdata->rng.priv = (unsigned long)drvdata;
+	drvdata->rng.quality = CC_TRNG_QUALITY;
+
+	platform_set_drvdata(pdev, drvdata);
+	drvdata->pdev = pdev;
+
+	drvdata->circ.buf = (char *)drvdata->data_buf;
+
+	/* Get device resources */
+	/* First CC registers space */
+	req_mem_cc_regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	/* Map registers space */
+	drvdata->cc_base = devm_ioremap_resource(dev, req_mem_cc_regs);
+	if (IS_ERR(drvdata->cc_base)) {
+		dev_err(dev, "Failed to ioremap registers");
+		return PTR_ERR(drvdata->cc_base);
+	}
+
+	dev_dbg(dev, "Got MEM resource (%s): %pR\n", req_mem_cc_regs->name,
+		req_mem_cc_regs);
+	dev_dbg(dev, "CC registers mapped from %pa to 0x%p\n",
+		&req_mem_cc_regs->start, drvdata->cc_base);
+
+	/* Then IRQ */
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(dev, "Failed getting IRQ resource\n");
+		return irq;
+	}
+
+	/* parse sampling rate from device tree */
+	rc = cc_trng_parse_sampling_ratio(drvdata);
+	if (rc) {
+		dev_err(dev, "Failed to get legal sampling ratio for rosc\n");
+		return rc;
+	}
+
+	rc = cc_trng_clk_init(drvdata);
+	if (rc) {
+		dev_err(dev, "cc_trng_clk_init failed\n");
+		return rc;
+	}
+
+	INIT_WORK(&drvdata->compwork, cc_trng_compwork_handler);
+	INIT_WORK(&drvdata->startwork, cc_trng_startwork_handler);
+	spin_lock_init(&drvdata->read_lock);
+
+	/* register the driver isr function */
+	rc = devm_request_irq(dev, irq, cc_isr, IRQF_SHARED, "cctrng", drvdata);
+	if (rc) {
+		dev_err(dev, "Could not register to interrupt %d\n", irq);
+		goto post_clk_err;
+	}
+	dev_dbg(dev, "Registered to IRQ: %d\n", irq);
+
+	/* Clear all pending interrupts */
+	val = cc_ioread(drvdata, CC_HOST_RGF_IRR_REG_OFFSET);
+	dev_dbg(dev, "IRR=0x%08X\n", val);
+	cc_iowrite(drvdata, CC_HOST_RGF_ICR_REG_OFFSET, val);
+
+	/* unmask HOST RNG interrupt */
+	cc_iowrite(drvdata, CC_HOST_RGF_IMR_REG_OFFSET,
+		   cc_ioread(drvdata, CC_HOST_RGF_IMR_REG_OFFSET) &
+		   ~CC_HOST_RNG_IRQ_MASK);
+
+	/* init PM */
+	rc = cc_trng_pm_init(drvdata);
+	if (rc) {
+		dev_err(dev, "cc_trng_pm_init failed\n");
+		goto post_clk_err;
+	}
+
+	/* increment device's usage counter */
+	rc = cc_trng_pm_get(dev);
+	if (rc) {
+		dev_err(dev, "cc_trng_pm_get returned %x\n", rc);
+		goto post_pm_err;
+	}
+
+	/* set pending_hw to verify that HW won't be triggered from read */
+	atomic_set(&drvdata->pending_hw, 1);
+
+	/* registration of the hwrng device */
+	rc = hwrng_register(&drvdata->rng);
+	if (rc) {
+		dev_err(dev, "Could not register hwrng device.\n");
+		goto post_pm_err;
+	}
+
+	/* trigger HW to start generate data */
+	drvdata->active_rosc = 0;
+	cc_trng_hw_trigger(drvdata);
+
+	/* All set, we can allow auto-suspend */
+	cc_trng_pm_go(drvdata);
+
+	dev_info(dev, "ARM cctrng device initialized\n");
+
+	return 0;
+
+post_pm_err:
+	cc_trng_pm_fini(drvdata);
+
+post_clk_err:
+	cc_trng_clk_fini(drvdata);
+
+	return rc;
+}
+
+static int cctrng_remove(struct platform_device *pdev)
+{
+	struct cctrng_drvdata *drvdata = platform_get_drvdata(pdev);
+	struct device *dev = &pdev->dev;
+
+	dev_dbg(dev, "Releasing cctrng resources...\n");
+
+	hwrng_unregister(&drvdata->rng);
+
+	cc_trng_pm_fini(drvdata);
+
+	cc_trng_clk_fini(drvdata);
+
+	dev_info(dev, "ARM cctrng device terminated\n");
+
+	return 0;
+}
+
+static int __maybe_unused cctrng_suspend(struct device *dev)
+{
+	struct cctrng_drvdata *drvdata = dev_get_drvdata(dev);
+
+	dev_dbg(dev, "set HOST_POWER_DOWN_EN\n");
+	cc_iowrite(drvdata, CC_HOST_POWER_DOWN_EN_REG_OFFSET,
+			POWER_DOWN_ENABLE);
+
+	clk_disable_unprepare(drvdata->clk);
+
+	return 0;
+}
+
+static bool cctrng_wait_for_reset_completion(struct cctrng_drvdata *drvdata)
+{
+	unsigned int val;
+	unsigned int i;
+
+	for (i = 0; i < CC_HW_RESET_LOOP_COUNT; i++) {
+		/* in cc7x3 NVM_IS_IDLE indicates that CC reset is
+		 *  completed and device is fully functional
+		 */
+		val = cc_ioread(drvdata, CC_NVM_IS_IDLE_REG_OFFSET);
+		if (val & BIT(CC_NVM_IS_IDLE_VALUE_BIT_SHIFT)) {
+			/* hw indicate reset completed */
+			return true;
+		}
+		/* allow scheduling other process on the processor */
+		schedule();
+	}
+	/* reset not completed */
+	return false;
+}
+
+static int __maybe_unused cctrng_resume(struct device *dev)
+{
+	struct cctrng_drvdata *drvdata = dev_get_drvdata(dev);
+	int rc;
+
+	dev_dbg(dev, "unset HOST_POWER_DOWN_EN\n");
+	/* Enables the device source clk */
+	rc = clk_prepare_enable(drvdata->clk);
+	if (rc) {
+		dev_err(dev, "failed getting clock back on. We're toast.\n");
+		return rc;
+	}
+
+	/* wait for Cryptocell reset completion */
+	if (!cctrng_wait_for_reset_completion(drvdata)) {
+		dev_err(dev, "Cryptocell reset not completed");
+		return -EBUSY;
+	}
+
+	/* unmask HOST RNG interrupt */
+	cc_iowrite(drvdata, CC_HOST_RGF_IMR_REG_OFFSET,
+		   cc_ioread(drvdata, CC_HOST_RGF_IMR_REG_OFFSET) &
+		   ~CC_HOST_RNG_IRQ_MASK);
+
+	cc_iowrite(drvdata, CC_HOST_POWER_DOWN_EN_REG_OFFSET,
+		   POWER_DOWN_DISABLE);
+
+	return 0;
+}
+
+static UNIVERSAL_DEV_PM_OPS(cctrng_pm, cctrng_suspend, cctrng_resume, NULL);
+
+static const struct of_device_id arm_cctrng_dt_match[] = {
+	{ .compatible = "arm,cryptocell-713-trng", },
+	{ .compatible = "arm,cryptocell-703-trng", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, arm_cctrng_dt_match);
+
+static struct platform_driver cctrng_driver = {
+	.driver = {
+		.name = "cctrng",
+		.of_match_table = arm_cctrng_dt_match,
+		.pm = &cctrng_pm,
+	},
+	.probe = cctrng_probe,
+	.remove = cctrng_remove,
+};
+
+static int __init cctrng_mod_init(void)
+{
+	/* Compile time assertion checks */
+	BUILD_BUG_ON(CCTRNG_DATA_BUF_WORDS < 6);
+	BUILD_BUG_ON((CCTRNG_DATA_BUF_WORDS & (CCTRNG_DATA_BUF_WORDS-1)) != 0);
+
+	return platform_driver_register(&cctrng_driver);
+}
+module_init(cctrng_mod_init);
+
+static void __exit cctrng_mod_exit(void)
+{
+	platform_driver_unregister(&cctrng_driver);
+}
+module_exit(cctrng_mod_exit);
+
+/* Module description */
+MODULE_DESCRIPTION("ARM CryptoCell TRNG Driver");
+MODULE_AUTHOR("ARM");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/char/hw_random/cctrng.h b/drivers/char/hw_random/cctrng.h
new file mode 100644
index 000000000000..1f2fde95adcb
--- /dev/null
+++ b/drivers/char/hw_random/cctrng.h
@@ -0,0 +1,72 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (C) 2019-2020 ARM Limited or its affiliates. */
+
+#include <linux/bitops.h>
+
+#define POWER_DOWN_ENABLE 0x01
+#define POWER_DOWN_DISABLE 0x00
+
+/* hwrng quality: bits of true entropy per 1024 bits of input */
+#define CC_TRNG_QUALITY	1024
+
+/* CryptoCell TRNG HW definitions */
+#define CC_TRNG_NUM_OF_ROSCS	4
+/* The number of words generated in the entropy holding register (EHR)
+ * 6 words (192 bit) according to HW implementation
+ */
+#define CC_TRNG_EHR_IN_WORDS	6
+#define CC_TRNG_EHR_IN_BITS	(CC_TRNG_EHR_IN_WORDS * BITS_PER_TYPE(u32))
+
+#define CC_HOST_RNG_IRQ_MASK BIT(CC_HOST_RGF_IRR_RNG_INT_BIT_SHIFT)
+
+/* RNG interrupt mask */
+#define CC_RNG_INT_MASK (BIT(CC_RNG_IMR_EHR_VALID_INT_MASK_BIT_SHIFT) | \
+			 BIT(CC_RNG_IMR_AUTOCORR_ERR_INT_MASK_BIT_SHIFT) | \
+			 BIT(CC_RNG_IMR_CRNGT_ERR_INT_MASK_BIT_SHIFT) | \
+			 BIT(CC_RNG_IMR_VN_ERR_INT_MASK_BIT_SHIFT) | \
+			 BIT(CC_RNG_IMR_WATCHDOG_INT_MASK_BIT_SHIFT))
+
+// --------------------------------------
+// BLOCK: RNG
+// --------------------------------------
+#define CC_RNG_IMR_REG_OFFSET	0x0100UL
+#define CC_RNG_IMR_EHR_VALID_INT_MASK_BIT_SHIFT	0x0UL
+#define CC_RNG_IMR_AUTOCORR_ERR_INT_MASK_BIT_SHIFT	0x1UL
+#define CC_RNG_IMR_CRNGT_ERR_INT_MASK_BIT_SHIFT	0x2UL
+#define CC_RNG_IMR_VN_ERR_INT_MASK_BIT_SHIFT	0x3UL
+#define CC_RNG_IMR_WATCHDOG_INT_MASK_BIT_SHIFT	0x4UL
+#define CC_RNG_ISR_REG_OFFSET	0x0104UL
+#define CC_RNG_ISR_EHR_VALID_BIT_SHIFT	0x0UL
+#define CC_RNG_ISR_EHR_VALID_BIT_SIZE	0x1UL
+#define CC_RNG_ISR_AUTOCORR_ERR_BIT_SHIFT	0x1UL
+#define CC_RNG_ISR_AUTOCORR_ERR_BIT_SIZE	0x1UL
+#define CC_RNG_ISR_CRNGT_ERR_BIT_SHIFT	0x2UL
+#define CC_RNG_ISR_CRNGT_ERR_BIT_SIZE	0x1UL
+#define CC_RNG_ISR_WATCHDOG_BIT_SHIFT	0x4UL
+#define CC_RNG_ISR_WATCHDOG_BIT_SIZE	0x1UL
+#define CC_RNG_ICR_REG_OFFSET	0x0108UL
+#define CC_TRNG_CONFIG_REG_OFFSET	0x010CUL
+#define CC_EHR_DATA_0_REG_OFFSET	0x0114UL
+#define CC_RND_SOURCE_ENABLE_REG_OFFSET	0x012CUL
+#define CC_SAMPLE_CNT1_REG_OFFSET	0x0130UL
+#define CC_TRNG_DEBUG_CONTROL_REG_OFFSET	0x0138UL
+#define CC_RNG_SW_RESET_REG_OFFSET	0x0140UL
+#define CC_RNG_CLK_ENABLE_REG_OFFSET	0x01C4UL
+#define CC_RNG_DMA_ENABLE_REG_OFFSET	0x01C8UL
+#define CC_RNG_WATCHDOG_VAL_REG_OFFSET	0x01D8UL
+// --------------------------------------
+// BLOCK: SEC_HOST_RGF
+// --------------------------------------
+#define CC_HOST_RGF_IRR_REG_OFFSET	0x0A00UL
+#define CC_HOST_RGF_IRR_RNG_INT_BIT_SHIFT	0xAUL
+#define CC_HOST_RGF_IMR_REG_OFFSET	0x0A04UL
+#define CC_HOST_RGF_ICR_REG_OFFSET	0x0A08UL
+
+#define CC_HOST_POWER_DOWN_EN_REG_OFFSET	0x0A78UL
+
+// --------------------------------------
+// BLOCK: NVM
+// --------------------------------------
+#define CC_NVM_IS_IDLE_REG_OFFSET	0x0F10UL
+#define CC_NVM_IS_IDLE_VALUE_BIT_SHIFT	0x0UL
+#define CC_NVM_IS_IDLE_VALUE_BIT_SIZE	0x1UL
diff --git a/drivers/char/hw_random/omap-rng.c b/drivers/char/hw_random/omap-rng.c
index 65952393e1bb..7290c603fcb8 100644
--- a/drivers/char/hw_random/omap-rng.c
+++ b/drivers/char/hw_random/omap-rng.c
@@ -392,11 +392,8 @@ static int of_get_omap_rng_device_details(struct omap_rng_dev *priv,
 	if (of_device_is_compatible(dev->of_node, "ti,omap4-rng") ||
 	    of_device_is_compatible(dev->of_node, "inside-secure,safexcel-eip76")) {
 		irq = platform_get_irq(pdev, 0);
-		if (irq < 0) {
-			dev_err(dev, "%s: error getting IRQ resource - %d\n",
-				__func__, irq);
+		if (irq < 0)
 			return irq;
-		}
 
 		err = devm_request_irq(dev, irq, omap4_rng_irq,
 				       IRQF_TRIGGER_NONE, dev_name(dev), priv);
diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c
index 718d8c087650..79a6e47b5fbc 100644
--- a/drivers/char/hw_random/virtio-rng.c
+++ b/drivers/char/hw_random/virtio-rng.c
@@ -11,6 +11,7 @@
 #include <linux/virtio.h>
 #include <linux/virtio_rng.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 static DEFINE_IDA(rng_index_ida);
 
diff --git a/drivers/char/hw_random/xgene-rng.c b/drivers/char/hw_random/xgene-rng.c
index d7516a446987..008e6db9ce01 100644
--- a/drivers/char/hw_random/xgene-rng.c
+++ b/drivers/char/hw_random/xgene-rng.c
@@ -328,10 +328,8 @@ static int xgene_rng_probe(struct platform_device *pdev)
 		return PTR_ERR(ctx->csr_base);
 
 	rc = platform_get_irq(pdev, 0);
-	if (rc < 0) {
-		dev_err(&pdev->dev, "No IRQ resource\n");
+	if (rc < 0)
 		return rc;
-	}
 	ctx->irq = rc;
 
 	dev_dbg(&pdev->dev, "APM X-Gene RNG BASE %p ALARM IRQ %d",
diff --git a/drivers/char/ipmi/bt-bmc.c b/drivers/char/ipmi/bt-bmc.c
index d36aeacb290e..890ad55aae79 100644
--- a/drivers/char/ipmi/bt-bmc.c
+++ b/drivers/char/ipmi/bt-bmc.c
@@ -430,9 +430,6 @@ static int bt_bmc_probe(struct platform_device *pdev)
 	struct device *dev;
 	int rc;
 
-	if (!pdev || !pdev->dev.of_node)
-		return -ENODEV;
-
 	dev = &pdev->dev;
 	dev_info(dev, "Found bt bmc device\n");
 
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index a438b1206fcb..1621ce818705 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -323,7 +323,7 @@ int tpm_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,
 
 	for (i = 0; i < chip->nr_allocated_banks; i++) {
 		if (digests[i].alg_id != chip->allocated_banks[i].alg_id) {
-			rc = EINVAL;
+			rc = -EINVAL;
 			goto out;
 		}
 	}
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
index 76f67b155bd5..eff1f12d981a 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -681,6 +681,7 @@ int tpm2_get_cc_attrs_tbl(struct tpm_chip *chip)
 		rc = -ENODEV;
 	return rc;
 }
+EXPORT_SYMBOL_GPL(tpm2_get_cc_attrs_tbl);
 
 /**
  * tpm2_startup - turn on the TPM
diff --git a/drivers/char/tpm/tpm_ibmvtpm.c b/drivers/char/tpm/tpm_ibmvtpm.c
index 1a49db9e108e..09fe45246b8c 100644
--- a/drivers/char/tpm/tpm_ibmvtpm.c
+++ b/drivers/char/tpm/tpm_ibmvtpm.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (C) 2012 IBM Corporation
+ * Copyright (C) 2012-2020 IBM Corporation
  *
  * Author: Ashley Lai <ashleydlai@gmail.com>
  *
@@ -134,6 +134,64 @@ static int tpm_ibmvtpm_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 	return len;
 }
 
+/**
+ * ibmvtpm_crq_send_init - Send a CRQ initialize message
+ * @ibmvtpm:	vtpm device struct
+ *
+ * Return:
+ *	0 on success.
+ *	Non-zero on failure.
+ */
+static int ibmvtpm_crq_send_init(struct ibmvtpm_dev *ibmvtpm)
+{
+	int rc;
+
+	rc = ibmvtpm_send_crq_word(ibmvtpm->vdev, INIT_CRQ_CMD);
+	if (rc != H_SUCCESS)
+		dev_err(ibmvtpm->dev,
+			"%s failed rc=%d\n", __func__, rc);
+
+	return rc;
+}
+
+/**
+ * tpm_ibmvtpm_resume - Resume from suspend
+ *
+ * @dev:	device struct
+ *
+ * Return: Always 0.
+ */
+static int tpm_ibmvtpm_resume(struct device *dev)
+{
+	struct tpm_chip *chip = dev_get_drvdata(dev);
+	struct ibmvtpm_dev *ibmvtpm = dev_get_drvdata(&chip->dev);
+	int rc = 0;
+
+	do {
+		if (rc)
+			msleep(100);
+		rc = plpar_hcall_norets(H_ENABLE_CRQ,
+					ibmvtpm->vdev->unit_address);
+	} while (rc == H_IN_PROGRESS || rc == H_BUSY || H_IS_LONG_BUSY(rc));
+
+	if (rc) {
+		dev_err(dev, "Error enabling ibmvtpm rc=%d\n", rc);
+		return rc;
+	}
+
+	rc = vio_enable_interrupts(ibmvtpm->vdev);
+	if (rc) {
+		dev_err(dev, "Error vio_enable_interrupts rc=%d\n", rc);
+		return rc;
+	}
+
+	rc = ibmvtpm_crq_send_init(ibmvtpm);
+	if (rc)
+		dev_err(dev, "Error send_init rc=%d\n", rc);
+
+	return rc;
+}
+
 /**
  * tpm_ibmvtpm_send() - Send a TPM command
  * @chip:	tpm chip struct
@@ -147,6 +205,7 @@ static int tpm_ibmvtpm_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count)
 {
 	struct ibmvtpm_dev *ibmvtpm = dev_get_drvdata(&chip->dev);
+	bool retry = true;
 	int rc, sig;
 
 	if (!ibmvtpm->rtce_buf) {
@@ -180,18 +239,27 @@ static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count)
 	 */
 	ibmvtpm->tpm_processing_cmd = true;
 
+again:
 	rc = ibmvtpm_send_crq(ibmvtpm->vdev,
 			IBMVTPM_VALID_CMD, VTPM_TPM_COMMAND,
 			count, ibmvtpm->rtce_dma_handle);
 	if (rc != H_SUCCESS) {
+		/*
+		 * H_CLOSED can be returned after LPM resume.  Call
+		 * tpm_ibmvtpm_resume() to re-enable the CRQ then retry
+		 * ibmvtpm_send_crq() once before failing.
+		 */
+		if (rc == H_CLOSED && retry) {
+			tpm_ibmvtpm_resume(ibmvtpm->dev);
+			retry = false;
+			goto again;
+		}
 		dev_err(ibmvtpm->dev, "tpm_ibmvtpm_send failed rc=%d\n", rc);
-		rc = 0;
 		ibmvtpm->tpm_processing_cmd = false;
-	} else
-		rc = 0;
+	}
 
 	spin_unlock(&ibmvtpm->rtce_lock);
-	return rc;
+	return 0;
 }
 
 static void tpm_ibmvtpm_cancel(struct tpm_chip *chip)
@@ -269,26 +337,6 @@ static int ibmvtpm_crq_send_init_complete(struct ibmvtpm_dev *ibmvtpm)
 	return rc;
 }
 
-/**
- * ibmvtpm_crq_send_init - Send a CRQ initialize message
- * @ibmvtpm:	vtpm device struct
- *
- * Return:
- *	0 on success.
- *	Non-zero on failure.
- */
-static int ibmvtpm_crq_send_init(struct ibmvtpm_dev *ibmvtpm)
-{
-	int rc;
-
-	rc = ibmvtpm_send_crq_word(ibmvtpm->vdev, INIT_CRQ_CMD);
-	if (rc != H_SUCCESS)
-		dev_err(ibmvtpm->dev,
-			"ibmvtpm_crq_send_init failed rc=%d\n", rc);
-
-	return rc;
-}
-
 /**
  * tpm_ibmvtpm_remove - ibm vtpm remove entry point
  * @vdev:	vio device struct
@@ -401,44 +449,6 @@ static int ibmvtpm_reset_crq(struct ibmvtpm_dev *ibmvtpm)
 				  ibmvtpm->crq_dma_handle, CRQ_RES_BUF_SIZE);
 }
 
-/**
- * tpm_ibmvtpm_resume - Resume from suspend
- *
- * @dev:	device struct
- *
- * Return: Always 0.
- */
-static int tpm_ibmvtpm_resume(struct device *dev)
-{
-	struct tpm_chip *chip = dev_get_drvdata(dev);
-	struct ibmvtpm_dev *ibmvtpm = dev_get_drvdata(&chip->dev);
-	int rc = 0;
-
-	do {
-		if (rc)
-			msleep(100);
-		rc = plpar_hcall_norets(H_ENABLE_CRQ,
-					ibmvtpm->vdev->unit_address);
-	} while (rc == H_IN_PROGRESS || rc == H_BUSY || H_IS_LONG_BUSY(rc));
-
-	if (rc) {
-		dev_err(dev, "Error enabling ibmvtpm rc=%d\n", rc);
-		return rc;
-	}
-
-	rc = vio_enable_interrupts(ibmvtpm->vdev);
-	if (rc) {
-		dev_err(dev, "Error vio_enable_interrupts rc=%d\n", rc);
-		return rc;
-	}
-
-	rc = ibmvtpm_crq_send_init(ibmvtpm);
-	if (rc)
-		dev_err(dev, "Error send_init rc=%d\n", rc);
-
-	return rc;
-}
-
 static bool tpm_ibmvtpm_req_canceled(struct tpm_chip *chip, u8 status)
 {
 	return (status == 0);
diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
index 27c6ca031e23..2435216bd10a 100644
--- a/drivers/char/tpm/tpm_tis_core.c
+++ b/drivers/char/tpm/tpm_tis_core.c
@@ -433,6 +433,9 @@ static void disable_interrupts(struct tpm_chip *chip)
 	u32 intmask;
 	int rc;
 
+	if (priv->irq == 0)
+		return;
+
 	rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
 	if (rc < 0)
 		intmask = 0;
@@ -1062,9 +1065,12 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
 		if (irq) {
 			tpm_tis_probe_irq_single(chip, intmask, IRQF_SHARED,
 						 irq);
-			if (!(chip->flags & TPM_CHIP_FLAG_IRQ))
+			if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) {
 				dev_err(&chip->dev, FW_BUG
 					"TPM interrupt not working, polling instead\n");
+
+				disable_interrupts(chip);
+			}
 		} else {
 			tpm_tis_probe_irq(chip, intmask);
 		}
diff --git a/drivers/clk/clk-asm9260.c b/drivers/clk/clk-asm9260.c
index 536b59aabd2c..bacebd457e6f 100644
--- a/drivers/clk/clk-asm9260.c
+++ b/drivers/clk/clk-asm9260.c
@@ -276,7 +276,7 @@ static void __init asm9260_acc_init(struct device_node *np)
 
 	/* TODO: Convert to DT parent scheme */
 	ref_clk = of_clk_get_parent_name(np, 0);
-	hw = __clk_hw_register_fixed_rate_with_accuracy(NULL, NULL, pll_clk,
+	hw = __clk_hw_register_fixed_rate(NULL, NULL, pll_clk,
 			ref_clk, NULL, NULL, 0, rate, 0,
 			CLK_FIXED_RATE_PARENT_ACCURACY);
 
diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig
index 01eadee88d66..db0253fa3d64 100644
--- a/drivers/clk/imx/Kconfig
+++ b/drivers/clk/imx/Kconfig
@@ -10,25 +10,25 @@ config MXC_CLK_SCU
 
 config CLK_IMX8MM
 	bool "IMX8MM CCM Clock Driver"
-	depends on ARCH_MXC && ARM64
+	depends on ARCH_MXC
 	help
 	    Build the driver for i.MX8MM CCM Clock Driver
 
 config CLK_IMX8MN
 	bool "IMX8MN CCM Clock Driver"
-	depends on ARCH_MXC && ARM64
+	depends on ARCH_MXC
 	help
 	    Build the driver for i.MX8MN CCM Clock Driver
 
 config CLK_IMX8MP
 	bool "IMX8MP CCM Clock Driver"
-	depends on ARCH_MXC && ARM64
+	depends on ARCH_MXC
 	help
 	    Build the driver for i.MX8MP CCM Clock Driver
 
 config CLK_IMX8MQ
 	bool "IMX8MQ CCM Clock Driver"
-	depends on ARCH_MXC && ARM64
+	depends on ARCH_MXC
 	help
 	    Build the driver for i.MX8MQ CCM Clock Driver
 
diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c
index dafc8806b03e..5dbb6a937732 100644
--- a/drivers/clk/imx/clk-imx6ul.c
+++ b/drivers/clk/imx/clk-imx6ul.c
@@ -503,7 +503,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
 		clk_prepare_enable(hws[IMX6UL_CLK_USBPHY2_GATE]->clk);
 	}
 
-	clk_set_parent(hws[IMX6UL_CLK_CAN_SEL]->clk, hws[IMX6UL_CLK_PLL3_60M]->clk);
+	clk_set_parent(hws[IMX6UL_CLK_CAN_SEL]->clk, hws[IMX6UL_CLK_PLL3_80M]->clk);
 	if (clk_on_imx6ul())
 		clk_set_parent(hws[IMX6UL_CLK_SIM_PRE_SEL]->clk, hws[IMX6UL_CLK_PLL3_USB_OTG]->clk);
 	else if (clk_on_imx6ull())
diff --git a/drivers/clk/imx/clk-imx7ulp.c b/drivers/clk/imx/clk-imx7ulp.c
index 3710aa0dee9b..634c0b6636b0 100644
--- a/drivers/clk/imx/clk-imx7ulp.c
+++ b/drivers/clk/imx/clk-imx7ulp.c
@@ -29,7 +29,7 @@ static const char * const ddr_sels[]		= { "apll_pfd_sel", "dummy", "dummy", "dum
 static const char * const nic_sels[]		= { "firc", "ddr_clk", };
 static const char * const periph_plat_sels[]	= { "dummy", "nic1_bus_clk", "nic1_clk", "ddr_clk", "apll_pfd2", "apll_pfd1", "apll_pfd0", "upll", };
 static const char * const periph_bus_sels[]	= { "dummy", "sosc_bus_clk", "dummy", "firc_bus_clk", "rosc", "nic1_bus_clk", "nic1_clk", "spll_bus_clk", };
-static const char * const arm_sels[]		= { "divcore", "dummy", "dummy", "hsrun_divcore", };
+static const char * const arm_sels[]		= { "core", "dummy", "dummy", "hsrun_core", };
 
 /* used by sosc/sirc/firc/ddr/spll/apll dividers */
 static const struct clk_div_table ulp_div_table[] = {
@@ -121,7 +121,9 @@ static void __init imx7ulp_clk_scg1_init(struct device_node *np)
 	hws[IMX7ULP_CLK_DDR_SEL]	= imx_clk_hw_mux_flags("ddr_sel", base + 0x30, 24, 2, ddr_sels, ARRAY_SIZE(ddr_sels), CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE);
 
 	hws[IMX7ULP_CLK_CORE_DIV]	= imx_clk_hw_divider_flags("divcore",	"scs_sel",  base + 0x14, 16, 4, CLK_SET_RATE_PARENT);
+	hws[IMX7ULP_CLK_CORE]		= imx_clk_hw_cpu("core", "divcore", hws[IMX7ULP_CLK_CORE_DIV]->clk, hws[IMX7ULP_CLK_SYS_SEL]->clk, hws[IMX7ULP_CLK_SPLL_SEL]->clk, hws[IMX7ULP_CLK_FIRC]->clk);
 	hws[IMX7ULP_CLK_HSRUN_CORE_DIV] = imx_clk_hw_divider_flags("hsrun_divcore", "hsrun_scs_sel", base + 0x1c, 16, 4, CLK_SET_RATE_PARENT);
+	hws[IMX7ULP_CLK_HSRUN_CORE] = imx_clk_hw_cpu("hsrun_core", "hsrun_divcore", hws[IMX7ULP_CLK_HSRUN_CORE_DIV]->clk, hws[IMX7ULP_CLK_HSRUN_SYS_SEL]->clk, hws[IMX7ULP_CLK_SPLL_SEL]->clk, hws[IMX7ULP_CLK_FIRC]->clk);
 
 	hws[IMX7ULP_CLK_DDR_DIV]	= imx_clk_hw_divider_gate("ddr_clk", "ddr_sel", CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, base + 0x30, 0, 3,
 							       0, ulp_div_table, &imx_ccm_lock);
@@ -270,7 +272,7 @@ static void __init imx7ulp_clk_smc1_init(struct device_node *np)
 	base = of_iomap(np, 0);
 	WARN_ON(!base);
 
-	hws[IMX7ULP_CLK_ARM] = imx_clk_hw_mux_flags("arm", base + 0x10, 8, 2, arm_sels, ARRAY_SIZE(arm_sels), CLK_IS_CRITICAL);
+	hws[IMX7ULP_CLK_ARM] = imx_clk_hw_mux_flags("arm", base + 0x10, 8, 2, arm_sels, ARRAY_SIZE(arm_sels), CLK_SET_RATE_PARENT);
 
 	imx_check_clk_hws(hws, clk_data->num);
 
diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig
index ea3c70d1307e..9e28db8125cd 100644
--- a/drivers/clk/mediatek/Kconfig
+++ b/drivers/clk/mediatek/Kconfig
@@ -274,6 +274,13 @@ config COMMON_CLK_MT8173
 	---help---
 	  This driver supports MediaTek MT8173 clocks.
 
+config COMMON_CLK_MT8173_MMSYS
+	bool "Clock driver for MediaTek MT8173 mmsys"
+	depends on COMMON_CLK_MT8173
+	default COMMON_CLK_MT8173
+	help
+	  This driver supports MediaTek MT8173 mmsys clocks.
+
 config COMMON_CLK_MT8183
 	bool "Clock driver for MediaTek MT8183"
 	depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 8cdb76a5cd71..bb0536942075 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -41,6 +41,7 @@ obj-$(CONFIG_COMMON_CLK_MT7629_ETHSYS) += clk-mt7629-eth.o
 obj-$(CONFIG_COMMON_CLK_MT7629_HIFSYS) += clk-mt7629-hif.o
 obj-$(CONFIG_COMMON_CLK_MT8135) += clk-mt8135.o
 obj-$(CONFIG_COMMON_CLK_MT8173) += clk-mt8173.o
+obj-$(CONFIG_COMMON_CLK_MT8173_MMSYS) += clk-mt8173-mm.o
 obj-$(CONFIG_COMMON_CLK_MT8183) += clk-mt8183.o
 obj-$(CONFIG_COMMON_CLK_MT8183_AUDIOSYS) += clk-mt8183-audio.o
 obj-$(CONFIG_COMMON_CLK_MT8183_CAMSYS) += clk-mt8183-cam.o
diff --git a/drivers/clk/mediatek/clk-mt8173-mm.c b/drivers/clk/mediatek/clk-mt8173-mm.c
new file mode 100644
index 000000000000..36fa20be77b6
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8173-mm.c
@@ -0,0 +1,146 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: James Liao <jamesjj.liao@mediatek.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#include "clk-gate.h"
+#include "clk-mtk.h"
+
+#include <dt-bindings/clock/mt8173-clk.h>
+
+static const struct mtk_gate_regs mm0_cg_regs = {
+	.set_ofs = 0x0104,
+	.clr_ofs = 0x0108,
+	.sta_ofs = 0x0100,
+};
+
+static const struct mtk_gate_regs mm1_cg_regs = {
+	.set_ofs = 0x0114,
+	.clr_ofs = 0x0118,
+	.sta_ofs = 0x0110,
+};
+
+#define GATE_MM0(_id, _name, _parent, _shift) {			\
+		.id = _id,					\
+		.name = _name,					\
+		.parent_name = _parent,				\
+		.regs = &mm0_cg_regs,				\
+		.shift = _shift,				\
+		.ops = &mtk_clk_gate_ops_setclr,		\
+	}
+
+#define GATE_MM1(_id, _name, _parent, _shift) {			\
+		.id = _id,					\
+		.name = _name,					\
+		.parent_name = _parent,				\
+		.regs = &mm1_cg_regs,				\
+		.shift = _shift,				\
+		.ops = &mtk_clk_gate_ops_setclr,		\
+	}
+
+static const struct mtk_gate mt8173_mm_clks[] = {
+	/* MM0 */
+	GATE_MM0(CLK_MM_SMI_COMMON, "mm_smi_common", "mm_sel", 0),
+	GATE_MM0(CLK_MM_SMI_LARB0, "mm_smi_larb0", "mm_sel", 1),
+	GATE_MM0(CLK_MM_CAM_MDP, "mm_cam_mdp", "mm_sel", 2),
+	GATE_MM0(CLK_MM_MDP_RDMA0, "mm_mdp_rdma0", "mm_sel", 3),
+	GATE_MM0(CLK_MM_MDP_RDMA1, "mm_mdp_rdma1", "mm_sel", 4),
+	GATE_MM0(CLK_MM_MDP_RSZ0, "mm_mdp_rsz0", "mm_sel", 5),
+	GATE_MM0(CLK_MM_MDP_RSZ1, "mm_mdp_rsz1", "mm_sel", 6),
+	GATE_MM0(CLK_MM_MDP_RSZ2, "mm_mdp_rsz2", "mm_sel", 7),
+	GATE_MM0(CLK_MM_MDP_TDSHP0, "mm_mdp_tdshp0", "mm_sel", 8),
+	GATE_MM0(CLK_MM_MDP_TDSHP1, "mm_mdp_tdshp1", "mm_sel", 9),
+	GATE_MM0(CLK_MM_MDP_WDMA, "mm_mdp_wdma", "mm_sel", 11),
+	GATE_MM0(CLK_MM_MDP_WROT0, "mm_mdp_wrot0", "mm_sel", 12),
+	GATE_MM0(CLK_MM_MDP_WROT1, "mm_mdp_wrot1", "mm_sel", 13),
+	GATE_MM0(CLK_MM_FAKE_ENG, "mm_fake_eng", "mm_sel", 14),
+	GATE_MM0(CLK_MM_MUTEX_32K, "mm_mutex_32k", "rtc_sel", 15),
+	GATE_MM0(CLK_MM_DISP_OVL0, "mm_disp_ovl0", "mm_sel", 16),
+	GATE_MM0(CLK_MM_DISP_OVL1, "mm_disp_ovl1", "mm_sel", 17),
+	GATE_MM0(CLK_MM_DISP_RDMA0, "mm_disp_rdma0", "mm_sel", 18),
+	GATE_MM0(CLK_MM_DISP_RDMA1, "mm_disp_rdma1", "mm_sel", 19),
+	GATE_MM0(CLK_MM_DISP_RDMA2, "mm_disp_rdma2", "mm_sel", 20),
+	GATE_MM0(CLK_MM_DISP_WDMA0, "mm_disp_wdma0", "mm_sel", 21),
+	GATE_MM0(CLK_MM_DISP_WDMA1, "mm_disp_wdma1", "mm_sel", 22),
+	GATE_MM0(CLK_MM_DISP_COLOR0, "mm_disp_color0", "mm_sel", 23),
+	GATE_MM0(CLK_MM_DISP_COLOR1, "mm_disp_color1", "mm_sel", 24),
+	GATE_MM0(CLK_MM_DISP_AAL, "mm_disp_aal", "mm_sel", 25),
+	GATE_MM0(CLK_MM_DISP_GAMMA, "mm_disp_gamma", "mm_sel", 26),
+	GATE_MM0(CLK_MM_DISP_UFOE, "mm_disp_ufoe", "mm_sel", 27),
+	GATE_MM0(CLK_MM_DISP_SPLIT0, "mm_disp_split0", "mm_sel", 28),
+	GATE_MM0(CLK_MM_DISP_SPLIT1, "mm_disp_split1", "mm_sel", 29),
+	GATE_MM0(CLK_MM_DISP_MERGE, "mm_disp_merge", "mm_sel", 30),
+	GATE_MM0(CLK_MM_DISP_OD, "mm_disp_od", "mm_sel", 31),
+	/* MM1 */
+	GATE_MM1(CLK_MM_DISP_PWM0MM, "mm_disp_pwm0mm", "mm_sel", 0),
+	GATE_MM1(CLK_MM_DISP_PWM026M, "mm_disp_pwm026m", "pwm_sel", 1),
+	GATE_MM1(CLK_MM_DISP_PWM1MM, "mm_disp_pwm1mm", "mm_sel", 2),
+	GATE_MM1(CLK_MM_DISP_PWM126M, "mm_disp_pwm126m", "pwm_sel", 3),
+	GATE_MM1(CLK_MM_DSI0_ENGINE, "mm_dsi0_engine", "mm_sel", 4),
+	GATE_MM1(CLK_MM_DSI0_DIGITAL, "mm_dsi0_digital", "dsi0_dig", 5),
+	GATE_MM1(CLK_MM_DSI1_ENGINE, "mm_dsi1_engine", "mm_sel", 6),
+	GATE_MM1(CLK_MM_DSI1_DIGITAL, "mm_dsi1_digital", "dsi1_dig", 7),
+	GATE_MM1(CLK_MM_DPI_PIXEL, "mm_dpi_pixel", "dpi0_sel", 8),
+	GATE_MM1(CLK_MM_DPI_ENGINE, "mm_dpi_engine", "mm_sel", 9),
+	GATE_MM1(CLK_MM_DPI1_PIXEL, "mm_dpi1_pixel", "lvds_pxl", 10),
+	GATE_MM1(CLK_MM_DPI1_ENGINE, "mm_dpi1_engine", "mm_sel", 11),
+	GATE_MM1(CLK_MM_HDMI_PIXEL, "mm_hdmi_pixel", "dpi0_sel", 12),
+	GATE_MM1(CLK_MM_HDMI_PLLCK, "mm_hdmi_pllck", "hdmi_sel", 13),
+	GATE_MM1(CLK_MM_HDMI_AUDIO, "mm_hdmi_audio", "apll1", 14),
+	GATE_MM1(CLK_MM_HDMI_SPDIF, "mm_hdmi_spdif", "apll2", 15),
+	GATE_MM1(CLK_MM_LVDS_PIXEL, "mm_lvds_pixel", "lvds_pxl", 16),
+	GATE_MM1(CLK_MM_LVDS_CTS, "mm_lvds_cts", "lvds_cts", 17),
+	GATE_MM1(CLK_MM_SMI_LARB4, "mm_smi_larb4", "mm_sel", 18),
+	GATE_MM1(CLK_MM_HDMI_HDCP, "mm_hdmi_hdcp", "hdcp_sel", 19),
+	GATE_MM1(CLK_MM_HDMI_HDCP24M, "mm_hdmi_hdcp24m", "hdcp_24m_sel", 20),
+};
+
+struct clk_mt8173_mm_driver_data {
+	const struct mtk_gate *gates_clk;
+	int gates_num;
+};
+
+static const struct clk_mt8173_mm_driver_data mt8173_mmsys_driver_data = {
+	.gates_clk = mt8173_mm_clks,
+	.gates_num = ARRAY_SIZE(mt8173_mm_clks),
+};
+
+static int clk_mt8173_mm_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *node = dev->parent->of_node;
+	const struct clk_mt8173_mm_driver_data *data;
+	struct clk_onecell_data *clk_data;
+	int ret;
+
+	clk_data = mtk_alloc_clk_data(CLK_MM_NR_CLK);
+	if (!clk_data)
+		return -ENOMEM;
+
+	data = &mt8173_mmsys_driver_data;
+
+	ret = mtk_clk_register_gates(node, data->gates_clk, data->gates_num,
+				     clk_data);
+	if (ret)
+		return ret;
+
+	ret = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static struct platform_driver clk_mt8173_mm_drv = {
+	.driver = {
+		.name = "clk-mt8173-mm",
+	},
+	.probe = clk_mt8173_mm_probe,
+};
+
+builtin_platform_driver(clk_mt8173_mm_drv);
diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c
index 537a7f49b0f7..8f898ac476c0 100644
--- a/drivers/clk/mediatek/clk-mt8173.c
+++ b/drivers/clk/mediatek/clk-mt8173.c
@@ -753,93 +753,6 @@ static const struct mtk_gate img_clks[] __initconst = {
 	GATE_IMG(CLK_IMG_FD, "img_fd", "mm_sel", 11),
 };
 
-static const struct mtk_gate_regs mm0_cg_regs __initconst = {
-	.set_ofs = 0x0104,
-	.clr_ofs = 0x0108,
-	.sta_ofs = 0x0100,
-};
-
-static const struct mtk_gate_regs mm1_cg_regs __initconst = {
-	.set_ofs = 0x0114,
-	.clr_ofs = 0x0118,
-	.sta_ofs = 0x0110,
-};
-
-#define GATE_MM0(_id, _name, _parent, _shift) {			\
-		.id = _id,					\
-		.name = _name,					\
-		.parent_name = _parent,				\
-		.regs = &mm0_cg_regs,				\
-		.shift = _shift,				\
-		.ops = &mtk_clk_gate_ops_setclr,		\
-	}
-
-#define GATE_MM1(_id, _name, _parent, _shift) {			\
-		.id = _id,					\
-		.name = _name,					\
-		.parent_name = _parent,				\
-		.regs = &mm1_cg_regs,				\
-		.shift = _shift,				\
-		.ops = &mtk_clk_gate_ops_setclr,		\
-	}
-
-static const struct mtk_gate mm_clks[] __initconst = {
-	/* MM0 */
-	GATE_MM0(CLK_MM_SMI_COMMON, "mm_smi_common", "mm_sel", 0),
-	GATE_MM0(CLK_MM_SMI_LARB0, "mm_smi_larb0", "mm_sel", 1),
-	GATE_MM0(CLK_MM_CAM_MDP, "mm_cam_mdp", "mm_sel", 2),
-	GATE_MM0(CLK_MM_MDP_RDMA0, "mm_mdp_rdma0", "mm_sel", 3),
-	GATE_MM0(CLK_MM_MDP_RDMA1, "mm_mdp_rdma1", "mm_sel", 4),
-	GATE_MM0(CLK_MM_MDP_RSZ0, "mm_mdp_rsz0", "mm_sel", 5),
-	GATE_MM0(CLK_MM_MDP_RSZ1, "mm_mdp_rsz1", "mm_sel", 6),
-	GATE_MM0(CLK_MM_MDP_RSZ2, "mm_mdp_rsz2", "mm_sel", 7),
-	GATE_MM0(CLK_MM_MDP_TDSHP0, "mm_mdp_tdshp0", "mm_sel", 8),
-	GATE_MM0(CLK_MM_MDP_TDSHP1, "mm_mdp_tdshp1", "mm_sel", 9),
-	GATE_MM0(CLK_MM_MDP_WDMA, "mm_mdp_wdma", "mm_sel", 11),
-	GATE_MM0(CLK_MM_MDP_WROT0, "mm_mdp_wrot0", "mm_sel", 12),
-	GATE_MM0(CLK_MM_MDP_WROT1, "mm_mdp_wrot1", "mm_sel", 13),
-	GATE_MM0(CLK_MM_FAKE_ENG, "mm_fake_eng", "mm_sel", 14),
-	GATE_MM0(CLK_MM_MUTEX_32K, "mm_mutex_32k", "rtc_sel", 15),
-	GATE_MM0(CLK_MM_DISP_OVL0, "mm_disp_ovl0", "mm_sel", 16),
-	GATE_MM0(CLK_MM_DISP_OVL1, "mm_disp_ovl1", "mm_sel", 17),
-	GATE_MM0(CLK_MM_DISP_RDMA0, "mm_disp_rdma0", "mm_sel", 18),
-	GATE_MM0(CLK_MM_DISP_RDMA1, "mm_disp_rdma1", "mm_sel", 19),
-	GATE_MM0(CLK_MM_DISP_RDMA2, "mm_disp_rdma2", "mm_sel", 20),
-	GATE_MM0(CLK_MM_DISP_WDMA0, "mm_disp_wdma0", "mm_sel", 21),
-	GATE_MM0(CLK_MM_DISP_WDMA1, "mm_disp_wdma1", "mm_sel", 22),
-	GATE_MM0(CLK_MM_DISP_COLOR0, "mm_disp_color0", "mm_sel", 23),
-	GATE_MM0(CLK_MM_DISP_COLOR1, "mm_disp_color1", "mm_sel", 24),
-	GATE_MM0(CLK_MM_DISP_AAL, "mm_disp_aal", "mm_sel", 25),
-	GATE_MM0(CLK_MM_DISP_GAMMA, "mm_disp_gamma", "mm_sel", 26),
-	GATE_MM0(CLK_MM_DISP_UFOE, "mm_disp_ufoe", "mm_sel", 27),
-	GATE_MM0(CLK_MM_DISP_SPLIT0, "mm_disp_split0", "mm_sel", 28),
-	GATE_MM0(CLK_MM_DISP_SPLIT1, "mm_disp_split1", "mm_sel", 29),
-	GATE_MM0(CLK_MM_DISP_MERGE, "mm_disp_merge", "mm_sel", 30),
-	GATE_MM0(CLK_MM_DISP_OD, "mm_disp_od", "mm_sel", 31),
-	/* MM1 */
-	GATE_MM1(CLK_MM_DISP_PWM0MM, "mm_disp_pwm0mm", "mm_sel", 0),
-	GATE_MM1(CLK_MM_DISP_PWM026M, "mm_disp_pwm026m", "pwm_sel", 1),
-	GATE_MM1(CLK_MM_DISP_PWM1MM, "mm_disp_pwm1mm", "mm_sel", 2),
-	GATE_MM1(CLK_MM_DISP_PWM126M, "mm_disp_pwm126m", "pwm_sel", 3),
-	GATE_MM1(CLK_MM_DSI0_ENGINE, "mm_dsi0_engine", "mm_sel", 4),
-	GATE_MM1(CLK_MM_DSI0_DIGITAL, "mm_dsi0_digital", "dsi0_dig", 5),
-	GATE_MM1(CLK_MM_DSI1_ENGINE, "mm_dsi1_engine", "mm_sel", 6),
-	GATE_MM1(CLK_MM_DSI1_DIGITAL, "mm_dsi1_digital", "dsi1_dig", 7),
-	GATE_MM1(CLK_MM_DPI_PIXEL, "mm_dpi_pixel", "dpi0_sel", 8),
-	GATE_MM1(CLK_MM_DPI_ENGINE, "mm_dpi_engine", "mm_sel", 9),
-	GATE_MM1(CLK_MM_DPI1_PIXEL, "mm_dpi1_pixel", "lvds_pxl", 10),
-	GATE_MM1(CLK_MM_DPI1_ENGINE, "mm_dpi1_engine", "mm_sel", 11),
-	GATE_MM1(CLK_MM_HDMI_PIXEL, "mm_hdmi_pixel", "dpi0_sel", 12),
-	GATE_MM1(CLK_MM_HDMI_PLLCK, "mm_hdmi_pllck", "hdmi_sel", 13),
-	GATE_MM1(CLK_MM_HDMI_AUDIO, "mm_hdmi_audio", "apll1", 14),
-	GATE_MM1(CLK_MM_HDMI_SPDIF, "mm_hdmi_spdif", "apll2", 15),
-	GATE_MM1(CLK_MM_LVDS_PIXEL, "mm_lvds_pixel", "lvds_pxl", 16),
-	GATE_MM1(CLK_MM_LVDS_CTS, "mm_lvds_cts", "lvds_cts", 17),
-	GATE_MM1(CLK_MM_SMI_LARB4, "mm_smi_larb4", "mm_sel", 18),
-	GATE_MM1(CLK_MM_HDMI_HDCP, "mm_hdmi_hdcp", "hdcp_sel", 19),
-	GATE_MM1(CLK_MM_HDMI_HDCP24M, "mm_hdmi_hdcp24m", "hdcp_24m_sel", 20),
-};
-
 static const struct mtk_gate_regs vdec0_cg_regs __initconst = {
 	.set_ofs = 0x0000,
 	.clr_ofs = 0x0004,
@@ -1144,23 +1057,6 @@ static void __init mtk_imgsys_init(struct device_node *node)
 }
 CLK_OF_DECLARE(mtk_imgsys, "mediatek,mt8173-imgsys", mtk_imgsys_init);
 
-static void __init mtk_mmsys_init(struct device_node *node)
-{
-	struct clk_onecell_data *clk_data;
-	int r;
-
-	clk_data = mtk_alloc_clk_data(CLK_MM_NR_CLK);
-
-	mtk_clk_register_gates(node, mm_clks, ARRAY_SIZE(mm_clks),
-						clk_data);
-
-	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
-	if (r)
-		pr_err("%s(): could not register clock provider: %d\n",
-			__func__, r);
-}
-CLK_OF_DECLARE(mtk_mmsys, "mediatek,mt8173-mmsys", mtk_mmsys_init);
-
 static void __init mtk_vdecsys_init(struct device_node *node)
 {
 	struct clk_onecell_data *clk_data;
diff --git a/drivers/clk/mmp/clk-pll.c b/drivers/clk/mmp/clk-pll.c
index 7077be293871..962014cfdc44 100644
--- a/drivers/clk/mmp/clk-pll.c
+++ b/drivers/clk/mmp/clk-pll.c
@@ -97,7 +97,7 @@ static const struct clk_ops mmp_clk_pll_ops = {
 	.recalc_rate = mmp_clk_pll_recalc_rate,
 };
 
-struct clk *mmp_clk_register_pll(char *name,
+static struct clk *mmp_clk_register_pll(char *name,
 			unsigned long default_rate,
 			void __iomem *enable_reg, u32 enable,
 			void __iomem *reg, u8 shift,
@@ -137,3 +137,34 @@ struct clk *mmp_clk_register_pll(char *name,
 
 	return clk;
 }
+
+void mmp_register_pll_clks(struct mmp_clk_unit *unit,
+			struct mmp_param_pll_clk *clks,
+			void __iomem *base, int size)
+{
+	struct clk *clk;
+	int i;
+
+	for (i = 0; i < size; i++) {
+		void __iomem *reg = NULL;
+
+		if (clks[i].offset)
+			reg = base + clks[i].offset;
+
+		clk = mmp_clk_register_pll(clks[i].name,
+					clks[i].default_rate,
+					base + clks[i].enable_offset,
+					clks[i].enable,
+					reg, clks[i].shift,
+					clks[i].input_rate,
+					base + clks[i].postdiv_offset,
+					clks[i].postdiv_shift);
+		if (IS_ERR(clk)) {
+			pr_err("%s: failed to register clock %s\n",
+			       __func__, clks[i].name);
+			continue;
+		}
+		if (clks[i].id)
+			unit->clk_table[clks[i].id] = clk;
+	}
+}
diff --git a/drivers/clk/mmp/clk.c b/drivers/clk/mmp/clk.c
index 317123641d1e..ca7d37e2c7be 100644
--- a/drivers/clk/mmp/clk.c
+++ b/drivers/clk/mmp/clk.c
@@ -176,37 +176,6 @@ void mmp_register_div_clks(struct mmp_clk_unit *unit,
 	}
 }
 
-void mmp_register_pll_clks(struct mmp_clk_unit *unit,
-			struct mmp_param_pll_clk *clks,
-			void __iomem *base, int size)
-{
-	struct clk *clk;
-	int i;
-
-	for (i = 0; i < size; i++) {
-		void __iomem *reg = NULL;
-
-		if (clks[i].offset)
-			reg = base + clks[i].offset;
-
-		clk = mmp_clk_register_pll(clks[i].name,
-					clks[i].default_rate,
-					base + clks[i].enable_offset,
-					clks[i].enable,
-					reg, clks[i].shift,
-					clks[i].input_rate,
-					base + clks[i].postdiv_offset,
-					clks[i].postdiv_shift);
-		if (IS_ERR(clk)) {
-			pr_err("%s: failed to register clock %s\n",
-			       __func__, clks[i].name);
-			continue;
-		}
-		if (clks[i].id)
-			unit->clk_table[clks[i].id] = clk;
-	}
-}
-
 void mmp_clk_add(struct mmp_clk_unit *unit, unsigned int id,
 			struct clk *clk)
 {
diff --git a/drivers/clk/mmp/clk.h b/drivers/clk/mmp/clk.h
index 971b4d6d992f..20dc1e5dd756 100644
--- a/drivers/clk/mmp/clk.h
+++ b/drivers/clk/mmp/clk.h
@@ -238,13 +238,6 @@ void mmp_register_pll_clks(struct mmp_clk_unit *unit,
 			struct mmp_param_pll_clk *clks,
 			void __iomem *base, int size);
 
-extern struct clk *mmp_clk_register_pll(char *name,
-			unsigned long default_rate,
-			void __iomem *enable_reg, u32 enable,
-			void __iomem *reg, u8 shift,
-			unsigned long input_rate,
-			void __iomem *postdiv_reg, u8 postdiv_shift);
-
 #define DEFINE_MIX_REG_INFO(w_d, s_d, w_m, s_m, fc)	\
 {							\
 	.width_div = (w_d),				\
diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c
index 10560d963baf..4c6c9167ef50 100644
--- a/drivers/clk/rockchip/clk-pll.c
+++ b/drivers/clk/rockchip/clk-pll.c
@@ -12,6 +12,7 @@
 #include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/clk-provider.h>
+#include <linux/iopoll.h>
 #include <linux/regmap.h>
 #include <linux/clk.h>
 #include "clk.h"
@@ -86,23 +87,14 @@ static int rockchip_pll_wait_lock(struct rockchip_clk_pll *pll)
 {
 	struct regmap *grf = pll->ctx->grf;
 	unsigned int val;
-	int delay = 24000000, ret;
-
-	while (delay > 0) {
-		ret = regmap_read(grf, pll->lock_offset, &val);
-		if (ret) {
-			pr_err("%s: failed to read pll lock status: %d\n",
-			       __func__, ret);
-			return ret;
-		}
+	int ret;
 
-		if (val & BIT(pll->lock_shift))
-			return 0;
-		delay--;
-	}
+	ret = regmap_read_poll_timeout(grf, pll->lock_offset, val,
+				       val & BIT(pll->lock_shift), 0, 1000);
+	if (ret)
+		pr_err("%s: timeout waiting for pll to lock\n", __func__);
 
-	pr_err("%s: timeout waiting for pll to lock\n", __func__);
-	return -ETIMEDOUT;
+	return ret;
 }
 
 /**
@@ -118,12 +110,31 @@ static int rockchip_pll_wait_lock(struct rockchip_clk_pll *pll)
 #define RK3036_PLLCON1_REFDIV_SHIFT		0
 #define RK3036_PLLCON1_POSTDIV2_MASK		0x7
 #define RK3036_PLLCON1_POSTDIV2_SHIFT		6
+#define RK3036_PLLCON1_LOCK_STATUS		BIT(10)
 #define RK3036_PLLCON1_DSMPD_MASK		0x1
 #define RK3036_PLLCON1_DSMPD_SHIFT		12
+#define RK3036_PLLCON1_PWRDOWN			BIT(13)
 #define RK3036_PLLCON2_FRAC_MASK		0xffffff
 #define RK3036_PLLCON2_FRAC_SHIFT		0
 
-#define RK3036_PLLCON1_PWRDOWN			(1 << 13)
+static int rockchip_rk3036_pll_wait_lock(struct rockchip_clk_pll *pll)
+{
+	u32 pllcon;
+	int ret;
+
+	/*
+	 * Lock time typical 250, max 500 input clock cycles @24MHz
+	 * So define a very safe maximum of 1000us, meaning 24000 cycles.
+	 */
+	ret = readl_relaxed_poll_timeout(pll->reg_base + RK3036_PLLCON(1),
+					 pllcon,
+					 pllcon & RK3036_PLLCON1_LOCK_STATUS,
+					 0, 1000);
+	if (ret)
+		pr_err("%s: timeout waiting for pll to lock\n", __func__);
+
+	return ret;
+}
 
 static void rockchip_rk3036_pll_get_params(struct rockchip_clk_pll *pll,
 					struct rockchip_pll_rate_table *rate)
@@ -221,7 +232,7 @@ static int rockchip_rk3036_pll_set_params(struct rockchip_clk_pll *pll,
 	writel_relaxed(pllcon, pll->reg_base + RK3036_PLLCON(2));
 
 	/* wait for the pll to lock */
-	ret = rockchip_pll_wait_lock(pll);
+	ret = rockchip_rk3036_pll_wait_lock(pll);
 	if (ret) {
 		pr_warn("%s: pll update unsuccessful, trying to restore old params\n",
 			__func__);
@@ -260,7 +271,7 @@ static int rockchip_rk3036_pll_enable(struct clk_hw *hw)
 
 	writel(HIWORD_UPDATE(0, RK3036_PLLCON1_PWRDOWN, 0),
 	       pll->reg_base + RK3036_PLLCON(1));
-	rockchip_pll_wait_lock(pll);
+	rockchip_rk3036_pll_wait_lock(pll);
 
 	return 0;
 }
@@ -589,19 +600,20 @@ static const struct clk_ops rockchip_rk3066_pll_clk_ops = {
 static int rockchip_rk3399_pll_wait_lock(struct rockchip_clk_pll *pll)
 {
 	u32 pllcon;
-	int delay = 24000000;
-
-	/* poll check the lock status in rk3399 xPLLCON2 */
-	while (delay > 0) {
-		pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(2));
-		if (pllcon & RK3399_PLLCON2_LOCK_STATUS)
-			return 0;
+	int ret;
 
-		delay--;
-	}
+	/*
+	 * Lock time typical 250, max 500 input clock cycles @24MHz
+	 * So define a very safe maximum of 1000us, meaning 24000 cycles.
+	 */
+	ret = readl_relaxed_poll_timeout(pll->reg_base + RK3399_PLLCON(2),
+					 pllcon,
+					 pllcon & RK3399_PLLCON2_LOCK_STATUS,
+					 0, 1000);
+	if (ret)
+		pr_err("%s: timeout waiting for pll to lock\n", __func__);
 
-	pr_err("%s: timeout waiting for pll to lock\n", __func__);
-	return -ETIMEDOUT;
+	return ret;
 }
 
 static void rockchip_rk3399_pll_get_params(struct rockchip_clk_pll *pll,
diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c
index d17cfb7a3ff4..d7243c09cc84 100644
--- a/drivers/clk/rockchip/clk-rk3228.c
+++ b/drivers/clk/rockchip/clk-rk3228.c
@@ -156,8 +156,6 @@ PNAME(mux_i2s_out_p)		= { "i2s1_pre", "xin12m" };
 PNAME(mux_i2s2_p)		= { "i2s2_src", "i2s2_frac", "xin12m" };
 PNAME(mux_sclk_spdif_p)		= { "sclk_spdif_src", "spdif_frac", "xin12m" };
 
-PNAME(mux_aclk_gpu_pre_p)	= { "cpll_gpu", "gpll_gpu", "hdmiphy_gpu", "usb480m_gpu" };
-
 PNAME(mux_uart0_p)		= { "uart0_src", "uart0_frac", "xin24m" };
 PNAME(mux_uart1_p)		= { "uart1_src", "uart1_frac", "xin24m" };
 PNAME(mux_uart2_p)		= { "uart2_src", "uart2_frac", "xin24m" };
@@ -468,16 +466,9 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
 			RK2928_CLKSEL_CON(24), 6, 10, DFLAGS,
 			RK2928_CLKGATE_CON(2), 8, GFLAGS),
 
-	GATE(0, "cpll_gpu", "cpll", 0,
-			RK2928_CLKGATE_CON(3), 13, GFLAGS),
-	GATE(0, "gpll_gpu", "gpll", 0,
-			RK2928_CLKGATE_CON(3), 13, GFLAGS),
-	GATE(0, "hdmiphy_gpu", "hdmiphy", 0,
-			RK2928_CLKGATE_CON(3), 13, GFLAGS),
-	GATE(0, "usb480m_gpu", "usb480m", 0,
+	COMPOSITE(0, "aclk_gpu_pre", mux_pll_src_4plls_p, 0,
+			RK2928_CLKSEL_CON(34), 5, 2, MFLAGS, 0, 5, DFLAGS,
 			RK2928_CLKGATE_CON(3), 13, GFLAGS),
-	COMPOSITE_NOGATE(0, "aclk_gpu_pre", mux_aclk_gpu_pre_p, 0,
-			RK2928_CLKSEL_CON(34), 5, 2, MFLAGS, 0, 5, DFLAGS),
 
 	COMPOSITE(SCLK_SPI0, "sclk_spi0", mux_pll_src_2plls_p, 0,
 			RK2928_CLKSEL_CON(25), 8, 1, MFLAGS, 0, 7, DFLAGS,
@@ -582,8 +573,8 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
 	GATE(0, "pclk_peri_noc", "pclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(12), 2, GFLAGS),
 
 	/* PD_GPU */
-	GATE(ACLK_GPU, "aclk_gpu", "aclk_gpu_pre", 0, RK2928_CLKGATE_CON(13), 14, GFLAGS),
-	GATE(0, "aclk_gpu_noc", "aclk_gpu_pre", 0, RK2928_CLKGATE_CON(13), 15, GFLAGS),
+	GATE(ACLK_GPU, "aclk_gpu", "aclk_gpu_pre", 0, RK2928_CLKGATE_CON(7), 14, GFLAGS),
+	GATE(0, "aclk_gpu_noc", "aclk_gpu_pre", 0, RK2928_CLKGATE_CON(7), 15, GFLAGS),
 
 	/* PD_BUS */
 	GATE(0, "sclk_initmem_mbist", "aclk_cpu", 0, RK2928_CLKGATE_CON(8), 1, GFLAGS),
diff --git a/drivers/clk/sprd/sc9863a-clk.c b/drivers/clk/sprd/sc9863a-clk.c
index a0631f7756cf..2e2dfb2d48ff 100644
--- a/drivers/clk/sprd/sc9863a-clk.c
+++ b/drivers/clk/sprd/sc9863a-clk.c
@@ -1641,8 +1641,9 @@ static SPRD_SC_GATE_CLK_FW_NAME(i2c4_eb,	"i2c4-eb",	"ext-26m", 0x0,
 				0x1000, BIT(12), 0, 0);
 static SPRD_SC_GATE_CLK_FW_NAME(uart0_eb,	"uart0-eb",	"ext-26m", 0x0,
 				0x1000, BIT(13), 0, 0);
+/* uart1_eb is for console, don't gate even if unused */
 static SPRD_SC_GATE_CLK_FW_NAME(uart1_eb,	"uart1-eb",	"ext-26m", 0x0,
-				0x1000, BIT(14), 0, 0);
+				0x1000, BIT(14), CLK_IGNORE_UNUSED, 0);
 static SPRD_SC_GATE_CLK_FW_NAME(uart2_eb,	"uart2-eb",	"ext-26m", 0x0,
 				0x1000, BIT(15), 0, 0);
 static SPRD_SC_GATE_CLK_FW_NAME(uart3_eb,	"uart3-eb",	"ext-26m", 0x0,
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index 27201fd26e44..e1aa1fbac48a 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -90,7 +90,7 @@ static void sun6i_a31_get_pll1_factors(struct factors_request *req)
 	 * Round down the frequency to the closest multiple of either
 	 * 6 or 16
 	 */
-	u32 round_freq_6 = round_down(freq_mhz, 6);
+	u32 round_freq_6 = rounddown(freq_mhz, 6);
 	u32 round_freq_16 = round_down(freq_mhz, 16);
 
 	if (round_freq_6 > round_freq_16)
diff --git a/drivers/clocksource/h8300_timer8.c b/drivers/clocksource/h8300_timer8.c
index 1d740a8c42ab..5bf514c78d8b 100644
--- a/drivers/clocksource/h8300_timer8.c
+++ b/drivers/clocksource/h8300_timer8.c
@@ -25,8 +25,8 @@
 #define TCORB	6
 #define _8TCNT	8
 
-#define CMIEA	6
-#define CMFA	6
+#define OVIE	5
+#define OVF	5
 
 #define FLAG_STARTED (1 << 3)
 
@@ -40,6 +40,7 @@ struct timer8_priv {
 	void __iomem *mapbase;
 	unsigned long flags;
 	unsigned int rate;
+	uint16_t cnt;
 };
 
 static irqreturn_t timer8_interrupt(int irq, void *dev_id)
@@ -51,7 +52,8 @@ static irqreturn_t timer8_interrupt(int irq, void *dev_id)
 
 	p->ced.event_handler(&p->ced);
 
-	bclr(CMFA, p->mapbase + _8TCSR);
+	iowrite16be(p->cnt, p->mapbase + _8TCNT);
+	bclr(OVF, p->mapbase + _8TCSR);
 
 	return IRQ_HANDLED;
 }
@@ -60,16 +62,14 @@ static void timer8_set_next(struct timer8_priv *p, unsigned long delta)
 {
 	if (delta >= 0x10000)
 		pr_warn("delta out of range\n");
-	bclr(CMIEA, p->mapbase + _8TCR);
-	iowrite16be(delta, p->mapbase + TCORA);
-	iowrite16be(0x0000, p->mapbase + _8TCNT);
-	bclr(CMFA, p->mapbase + _8TCSR);
-	bset(CMIEA, p->mapbase + _8TCR);
+	p->cnt = 0x10000 - delta;
+	iowrite16be(p->cnt, p->mapbase + _8TCNT);
+	bclr(OVF, p->mapbase + _8TCSR);
+	bset(OVIE, p->mapbase + _8TCR);
 }
 
 static int timer8_enable(struct timer8_priv *p)
 {
-	iowrite16be(0xffff, p->mapbase + TCORA);
 	iowrite16be(0x0000, p->mapbase + _8TCNT);
 	iowrite16be(0x0c02, p->mapbase + _8TCR);
 
@@ -177,7 +177,7 @@ static int __init h8300_8timer_init(struct device_node *node)
 	}
 
 	ret = -EINVAL;
-	irq = irq_of_parse_and_map(node, 0);
+	irq = irq_of_parse_and_map(node, 2);
 	if (!irq) {
 		pr_err("failed to get irq for clockevent\n");
 		goto unmap_reg;
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index 15c1a1231516..9481292981f0 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -317,6 +317,7 @@ config ARM_TEGRA186_CPUFREQ
 config ARM_TI_CPUFREQ
 	bool "Texas Instruments CPUFreq support"
 	depends on ARCH_OMAP2PLUS
+	default ARCH_OMAP2PLUS
 	help
 	  This driver enables valid OPPs on the running platform based on
 	  values contained within the SoC in use. Enable this in order to
diff --git a/drivers/cpufreq/loongson2_cpufreq.c b/drivers/cpufreq/loongson2_cpufreq.c
index 909f40fbcde2..d05e761d9572 100644
--- a/drivers/cpufreq/loongson2_cpufreq.c
+++ b/drivers/cpufreq/loongson2_cpufreq.c
@@ -20,7 +20,6 @@
 #include <linux/delay.h>
 #include <linux/platform_device.h>
 
-#include <asm/clock.h>
 #include <asm/idle.h>
 
 #include <asm/mach-loongson2ef/loongson.h>
@@ -58,29 +57,20 @@ static int loongson2_cpufreq_target(struct cpufreq_policy *policy,
 	     loongson2_clockmod_table[index].driver_data) / 8;
 
 	/* setting the cpu frequency */
-	clk_set_rate(policy->clk, freq * 1000);
+	loongson2_cpu_set_rate(freq);
 
 	return 0;
 }
 
 static int loongson2_cpufreq_cpu_init(struct cpufreq_policy *policy)
 {
-	struct clk *cpuclk;
 	int i;
 	unsigned long rate;
 	int ret;
 
-	cpuclk = clk_get(NULL, "cpu_clk");
-	if (IS_ERR(cpuclk)) {
-		pr_err("couldn't get CPU clk\n");
-		return PTR_ERR(cpuclk);
-	}
-
 	rate = cpu_clock_freq / 1000;
-	if (!rate) {
-		clk_put(cpuclk);
+	if (!rate)
 		return -EINVAL;
-	}
 
 	/* clock table init */
 	for (i = 2;
@@ -88,20 +78,16 @@ static int loongson2_cpufreq_cpu_init(struct cpufreq_policy *policy)
 	     i++)
 		loongson2_clockmod_table[i].frequency = (rate * i) / 8;
 
-	ret = clk_set_rate(cpuclk, rate * 1000);
-	if (ret) {
-		clk_put(cpuclk);
+	ret = loongson2_cpu_set_rate(rate);
+	if (ret)
 		return ret;
-	}
 
-	policy->clk = cpuclk;
 	cpufreq_generic_init(policy, &loongson2_clockmod_table[0], 0);
 	return 0;
 }
 
 static int loongson2_cpufreq_exit(struct cpufreq_policy *policy)
 {
-	clk_put(policy->clk);
 	return 0;
 }
 
diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c
index 6b301afffd11..a1fb2fbdbe7b 100644
--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c
+++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c
@@ -537,10 +537,8 @@ static int sun8i_ss_probe(struct platform_device *pdev)
 		return err;
 
 	irq = platform_get_irq(pdev, 0);
-	if (irq < 0) {
-		dev_err(ss->dev, "Cannot get SecuritySystem IRQ\n");
+	if (irq < 0)
 		return irq;
-	}
 
 	ss->reset = devm_reset_control_get(&pdev->dev, NULL);
 	if (IS_ERR(ss->reset)) {
diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index 9d4ead2f7ebb..411857fad8ba 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -253,10 +253,8 @@ static int meson_crypto_probe(struct platform_device *pdev)
 	mc->irqs = devm_kcalloc(mc->dev, MAXFLOW, sizeof(int), GFP_KERNEL);
 	for (i = 0; i < MAXFLOW; i++) {
 		mc->irqs[i] = platform_get_irq(pdev, i);
-		if (mc->irqs[i] < 0) {
-			dev_err(mc->dev, "Cannot get IRQ for flow %d\n", i);
+		if (mc->irqs[i] < 0)
 			return mc->irqs[i];
-		}
 
 		err = devm_request_irq(&pdev->dev, mc->irqs[i], meson_irq_handler, 0,
 				       "gxl-crypto", mc);
diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c
index b7bb7c30adeb..b2f9882bc010 100644
--- a/drivers/crypto/caam/caamalg.c
+++ b/drivers/crypto/caam/caamalg.c
@@ -963,10 +963,12 @@ static void aead_crypt_done(struct device *jrdev, u32 *desc, u32 err,
 	struct caam_drv_private_jr *jrp = dev_get_drvdata(jrdev);
 	struct aead_edesc *edesc;
 	int ecode = 0;
+	bool has_bklog;
 
 	dev_dbg(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
 
 	edesc = rctx->edesc;
+	has_bklog = edesc->bklog;
 
 	if (err)
 		ecode = caam_jr_strstatus(jrdev, err);
@@ -979,7 +981,7 @@ static void aead_crypt_done(struct device *jrdev, u32 *desc, u32 err,
 	 * If no backlog flag, the completion of the request is done
 	 * by CAAM, not crypto engine.
 	 */
-	if (!edesc->bklog)
+	if (!has_bklog)
 		aead_request_complete(req, ecode);
 	else
 		crypto_finalize_aead_request(jrp->engine, req, ecode);
@@ -995,10 +997,12 @@ static void skcipher_crypt_done(struct device *jrdev, u32 *desc, u32 err,
 	struct caam_drv_private_jr *jrp = dev_get_drvdata(jrdev);
 	int ivsize = crypto_skcipher_ivsize(skcipher);
 	int ecode = 0;
+	bool has_bklog;
 
 	dev_dbg(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
 
 	edesc = rctx->edesc;
+	has_bklog = edesc->bklog;
 	if (err)
 		ecode = caam_jr_strstatus(jrdev, err);
 
@@ -1028,7 +1032,7 @@ static void skcipher_crypt_done(struct device *jrdev, u32 *desc, u32 err,
 	 * If no backlog flag, the completion of the request is done
 	 * by CAAM, not crypto engine.
 	 */
-	if (!edesc->bklog)
+	if (!has_bklog)
 		skcipher_request_complete(req, ecode);
 	else
 		crypto_finalize_skcipher_request(jrp->engine, req, ecode);
@@ -1711,7 +1715,7 @@ static struct skcipher_edesc *skcipher_edesc_alloc(struct skcipher_request *req,
 
 	if (ivsize || mapped_dst_nents > 1)
 		sg_to_sec4_set_last(edesc->sec4_sg + dst_sg_idx +
-				    mapped_dst_nents);
+				    mapped_dst_nents - 1 + !!ivsize);
 
 	if (sec4_sg_bytes) {
 		edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
diff --git a/drivers/crypto/caam/caamhash.c b/drivers/crypto/caam/caamhash.c
index 943bc0296267..27ff4a3d037e 100644
--- a/drivers/crypto/caam/caamhash.c
+++ b/drivers/crypto/caam/caamhash.c
@@ -583,10 +583,12 @@ static inline void ahash_done_cpy(struct device *jrdev, u32 *desc, u32 err,
 	struct caam_hash_state *state = ahash_request_ctx(req);
 	struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
 	int ecode = 0;
+	bool has_bklog;
 
 	dev_dbg(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
 
 	edesc = state->edesc;
+	has_bklog = edesc->bklog;
 
 	if (err)
 		ecode = caam_jr_strstatus(jrdev, err);
@@ -603,7 +605,7 @@ static inline void ahash_done_cpy(struct device *jrdev, u32 *desc, u32 err,
 	 * If no backlog flag, the completion of the request is done
 	 * by CAAM, not crypto engine.
 	 */
-	if (!edesc->bklog)
+	if (!has_bklog)
 		req->base.complete(&req->base, ecode);
 	else
 		crypto_finalize_hash_request(jrp->engine, req, ecode);
@@ -632,10 +634,12 @@ static inline void ahash_done_switch(struct device *jrdev, u32 *desc, u32 err,
 	struct caam_hash_state *state = ahash_request_ctx(req);
 	int digestsize = crypto_ahash_digestsize(ahash);
 	int ecode = 0;
+	bool has_bklog;
 
 	dev_dbg(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
 
 	edesc = state->edesc;
+	has_bklog = edesc->bklog;
 	if (err)
 		ecode = caam_jr_strstatus(jrdev, err);
 
@@ -663,7 +667,7 @@ static inline void ahash_done_switch(struct device *jrdev, u32 *desc, u32 err,
 	 * If no backlog flag, the completion of the request is done
 	 * by CAAM, not crypto engine.
 	 */
-	if (!edesc->bklog)
+	if (!has_bklog)
 		req->base.complete(&req->base, ecode);
 	else
 		crypto_finalize_hash_request(jrp->engine, req, ecode);
diff --git a/drivers/crypto/caam/caampkc.c b/drivers/crypto/caam/caampkc.c
index 4fcae37a2e33..2e44d685618f 100644
--- a/drivers/crypto/caam/caampkc.c
+++ b/drivers/crypto/caam/caampkc.c
@@ -121,11 +121,13 @@ static void rsa_pub_done(struct device *dev, u32 *desc, u32 err, void *context)
 	struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
 	struct rsa_edesc *edesc;
 	int ecode = 0;
+	bool has_bklog;
 
 	if (err)
 		ecode = caam_jr_strstatus(dev, err);
 
 	edesc = req_ctx->edesc;
+	has_bklog = edesc->bklog;
 
 	rsa_pub_unmap(dev, edesc, req);
 	rsa_io_unmap(dev, edesc, req);
@@ -135,7 +137,7 @@ static void rsa_pub_done(struct device *dev, u32 *desc, u32 err, void *context)
 	 * If no backlog flag, the completion of the request is done
 	 * by CAAM, not crypto engine.
 	 */
-	if (!edesc->bklog)
+	if (!has_bklog)
 		akcipher_request_complete(req, ecode);
 	else
 		crypto_finalize_akcipher_request(jrp->engine, req, ecode);
@@ -152,11 +154,13 @@ static void rsa_priv_f_done(struct device *dev, u32 *desc, u32 err,
 	struct caam_rsa_req_ctx *req_ctx = akcipher_request_ctx(req);
 	struct rsa_edesc *edesc;
 	int ecode = 0;
+	bool has_bklog;
 
 	if (err)
 		ecode = caam_jr_strstatus(dev, err);
 
 	edesc = req_ctx->edesc;
+	has_bklog = edesc->bklog;
 
 	switch (key->priv_form) {
 	case FORM1:
@@ -176,7 +180,7 @@ static void rsa_priv_f_done(struct device *dev, u32 *desc, u32 err,
 	 * If no backlog flag, the completion of the request is done
 	 * by CAAM, not crypto engine.
 	 */
-	if (!edesc->bklog)
+	if (!has_bklog)
 		akcipher_request_complete(req, ecode);
 	else
 		crypto_finalize_akcipher_request(jrp->engine, req, ecode);
diff --git a/drivers/crypto/ccp/Kconfig b/drivers/crypto/ccp/Kconfig
index e0a8bd15aa74..32268e239bf1 100644
--- a/drivers/crypto/ccp/Kconfig
+++ b/drivers/crypto/ccp/Kconfig
@@ -10,10 +10,9 @@ config CRYPTO_DEV_CCP_DD
 config CRYPTO_DEV_SP_CCP
 	bool "Cryptographic Coprocessor device"
 	default y
-	depends on CRYPTO_DEV_CCP_DD
+	depends on CRYPTO_DEV_CCP_DD && DMADEVICES
 	select HW_RANDOM
 	select DMA_ENGINE
-	select DMADEVICES
 	select CRYPTO_SHA1
 	select CRYPTO_SHA256
 	help
diff --git a/drivers/crypto/hisilicon/hpre/hpre.h b/drivers/crypto/hisilicon/hpre/hpre.h
index 03d512ec6336..0a8ba468e2be 100644
--- a/drivers/crypto/hisilicon/hpre/hpre.h
+++ b/drivers/crypto/hisilicon/hpre/hpre.h
@@ -47,7 +47,6 @@ struct hpre_debug {
 struct hpre {
 	struct hisi_qm qm;
 	struct hpre_debug debug;
-	u32 num_vfs;
 	unsigned long status;
 };
 
diff --git a/drivers/crypto/hisilicon/hpre/hpre_main.c b/drivers/crypto/hisilicon/hpre/hpre_main.c
index 88be53bf4a38..9cff5c1b7c9b 100644
--- a/drivers/crypto/hisilicon/hpre/hpre_main.c
+++ b/drivers/crypto/hisilicon/hpre/hpre_main.c
@@ -195,6 +195,15 @@ static u32 hpre_pf_q_num = HPRE_PF_DEF_Q_NUM;
 module_param_cb(hpre_pf_q_num, &hpre_pf_q_num_ops, &hpre_pf_q_num, 0444);
 MODULE_PARM_DESC(hpre_pf_q_num, "Number of queues in PF of CS(1-1024)");
 
+static const struct kernel_param_ops vfs_num_ops = {
+	.set = vfs_num_set,
+	.get = param_get_int,
+};
+
+static u32 vfs_num;
+module_param_cb(vfs_num, &vfs_num_ops, &vfs_num, 0444);
+MODULE_PARM_DESC(vfs_num, "Number of VFs to enable(1-63), 0(default)");
+
 struct hisi_qp *hpre_create_qp(void)
 {
 	int node = cpu_to_node(smp_processor_id());
@@ -354,9 +363,7 @@ static u32 hpre_current_qm_read(struct hpre_debugfs_file *file)
 static int hpre_current_qm_write(struct hpre_debugfs_file *file, u32 val)
 {
 	struct hisi_qm *qm = hpre_file_to_qm(file);
-	struct hpre_debug *debug = file->debug;
-	struct hpre *hpre = container_of(debug, struct hpre, debug);
-	u32 num_vfs = hpre->num_vfs;
+	u32 num_vfs = qm->vfs_num;
 	u32 vfq_num, tmp;
 
 
@@ -779,8 +786,18 @@ static int hpre_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 		pci_err(pdev, "fail to register algs to crypto!\n");
 		goto err_with_qm_start;
 	}
+
+	if (qm->fun_type == QM_HW_PF && vfs_num) {
+		ret = hisi_qm_sriov_enable(pdev, vfs_num);
+		if (ret < 0)
+			goto err_with_crypto_register;
+	}
+
 	return 0;
 
+err_with_crypto_register:
+	hpre_algs_unregister();
+
 err_with_qm_start:
 	hisi_qm_del_from_list(qm, &hpre_devices);
 	hisi_qm_stop(qm);
@@ -794,107 +811,6 @@ static int hpre_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	return ret;
 }
 
-static int hpre_vf_q_assign(struct hpre *hpre, int num_vfs)
-{
-	struct hisi_qm *qm = &hpre->qm;
-	u32 qp_num = qm->qp_num;
-	int q_num, remain_q_num, i;
-	u32 q_base = qp_num;
-	int ret;
-
-	if (!num_vfs)
-		return -EINVAL;
-
-	remain_q_num = qm->ctrl_qp_num - qp_num;
-
-	/* If remaining queues are not enough, return error. */
-	if (remain_q_num < num_vfs)
-		return -EINVAL;
-
-	q_num = remain_q_num / num_vfs;
-	for (i = 1; i <= num_vfs; i++) {
-		if (i == num_vfs)
-			q_num += remain_q_num % num_vfs;
-		ret = hisi_qm_set_vft(qm, i, q_base, (u32)q_num);
-		if (ret)
-			return ret;
-		q_base += q_num;
-	}
-
-	return 0;
-}
-
-static int hpre_clear_vft_config(struct hpre *hpre)
-{
-	struct hisi_qm *qm = &hpre->qm;
-	u32 num_vfs = hpre->num_vfs;
-	int ret;
-	u32 i;
-
-	for (i = 1; i <= num_vfs; i++) {
-		ret = hisi_qm_set_vft(qm, i, 0, 0);
-		if (ret)
-			return ret;
-	}
-	hpre->num_vfs = 0;
-
-	return 0;
-}
-
-static int hpre_sriov_enable(struct pci_dev *pdev, int max_vfs)
-{
-	struct hpre *hpre = pci_get_drvdata(pdev);
-	int pre_existing_vfs, num_vfs, ret;
-
-	pre_existing_vfs = pci_num_vf(pdev);
-	if (pre_existing_vfs) {
-		pci_err(pdev,
-			"Can't enable VF. Please disable pre-enabled VFs!\n");
-		return 0;
-	}
-
-	num_vfs = min_t(int, max_vfs, HPRE_VF_NUM);
-	ret = hpre_vf_q_assign(hpre, num_vfs);
-	if (ret) {
-		pci_err(pdev, "Can't assign queues for VF!\n");
-		return ret;
-	}
-
-	hpre->num_vfs = num_vfs;
-
-	ret = pci_enable_sriov(pdev, num_vfs);
-	if (ret) {
-		pci_err(pdev, "Can't enable VF!\n");
-		hpre_clear_vft_config(hpre);
-		return ret;
-	}
-
-	return num_vfs;
-}
-
-static int hpre_sriov_disable(struct pci_dev *pdev)
-{
-	struct hpre *hpre = pci_get_drvdata(pdev);
-
-	if (pci_vfs_assigned(pdev)) {
-		pci_err(pdev, "Failed to disable VFs while VFs are assigned!\n");
-		return -EPERM;
-	}
-
-	/* remove in hpre_pci_driver will be called to free VF resources */
-	pci_disable_sriov(pdev);
-
-	return hpre_clear_vft_config(hpre);
-}
-
-static int hpre_sriov_configure(struct pci_dev *pdev, int num_vfs)
-{
-	if (num_vfs)
-		return hpre_sriov_enable(pdev, num_vfs);
-	else
-		return hpre_sriov_disable(pdev);
-}
-
 static void hpre_remove(struct pci_dev *pdev)
 {
 	struct hpre *hpre = pci_get_drvdata(pdev);
@@ -903,8 +819,8 @@ static void hpre_remove(struct pci_dev *pdev)
 
 	hpre_algs_unregister();
 	hisi_qm_del_from_list(qm, &hpre_devices);
-	if (qm->fun_type == QM_HW_PF && hpre->num_vfs != 0) {
-		ret = hpre_sriov_disable(pdev);
+	if (qm->fun_type == QM_HW_PF && qm->vfs_num) {
+		ret = hisi_qm_sriov_disable(pdev);
 		if (ret) {
 			pci_err(pdev, "Disable SRIOV fail!\n");
 			return;
@@ -931,7 +847,7 @@ static struct pci_driver hpre_pci_driver = {
 	.id_table		= hpre_dev_ids,
 	.probe			= hpre_probe,
 	.remove			= hpre_remove,
-	.sriov_configure	= hpre_sriov_configure,
+	.sriov_configure	= hisi_qm_sriov_configure,
 	.err_handler		= &hpre_err_handler,
 };
 
diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c
index f795fb557630..7c2dedc12d13 100644
--- a/drivers/crypto/hisilicon/qm.c
+++ b/drivers/crypto/hisilicon/qm.c
@@ -1781,12 +1781,6 @@ int hisi_qm_get_vft(struct hisi_qm *qm, u32 *base, u32 *number)
 EXPORT_SYMBOL_GPL(hisi_qm_get_vft);
 
 /**
- * hisi_qm_set_vft() - Set "virtual function table" for a qm.
- * @fun_num: Number of operated function.
- * @qm: The qm in which to set vft, alway in a PF.
- * @base: The base number of queue in vft.
- * @number: The number of queues in vft. 0 means invalid vft.
- *
  * This function is alway called in PF driver, it is used to assign queues
  * among PF and VFs.
  *
@@ -1794,7 +1788,7 @@ EXPORT_SYMBOL_GPL(hisi_qm_get_vft);
  * Assign queues A~B to VF: hisi_qm_set_vft(qm, 2, A, B - A + 1)
  * (VF function number 0x2)
  */
-int hisi_qm_set_vft(struct hisi_qm *qm, u32 fun_num, u32 base,
+static int hisi_qm_set_vft(struct hisi_qm *qm, u32 fun_num, u32 base,
 		    u32 number)
 {
 	u32 max_q_num = qm->ctrl_qp_num;
@@ -1805,7 +1799,6 @@ int hisi_qm_set_vft(struct hisi_qm *qm, u32 fun_num, u32 base,
 
 	return qm_set_sqc_cqc_vft(qm, fun_num, base, number);
 }
-EXPORT_SYMBOL_GPL(hisi_qm_set_vft);
 
 static void qm_init_eq_aeq_status(struct hisi_qm *qm)
 {
@@ -2299,6 +2292,133 @@ int hisi_qm_alloc_qps_node(struct hisi_qm_list *qm_list, int qp_num,
 }
 EXPORT_SYMBOL_GPL(hisi_qm_alloc_qps_node);
 
+static int qm_vf_q_assign(struct hisi_qm *qm, u32 num_vfs)
+{
+	u32 remain_q_num, q_num, i, j;
+	u32 q_base = qm->qp_num;
+	int ret;
+
+	if (!num_vfs)
+		return -EINVAL;
+
+	remain_q_num = qm->ctrl_qp_num - qm->qp_num;
+
+	/* If remain queues not enough, return error. */
+	if (qm->ctrl_qp_num < qm->qp_num || remain_q_num < num_vfs)
+		return -EINVAL;
+
+	q_num = remain_q_num / num_vfs;
+	for (i = 1; i <= num_vfs; i++) {
+		if (i == num_vfs)
+			q_num += remain_q_num % num_vfs;
+		ret = hisi_qm_set_vft(qm, i, q_base, q_num);
+		if (ret) {
+			for (j = i; j > 0; j--)
+				hisi_qm_set_vft(qm, j, 0, 0);
+			return ret;
+		}
+		q_base += q_num;
+	}
+
+	return 0;
+}
+
+static int qm_clear_vft_config(struct hisi_qm *qm)
+{
+	int ret;
+	u32 i;
+
+	for (i = 1; i <= qm->vfs_num; i++) {
+		ret = hisi_qm_set_vft(qm, i, 0, 0);
+		if (ret)
+			return ret;
+	}
+	qm->vfs_num = 0;
+
+	return 0;
+}
+
+/**
+ * hisi_qm_sriov_enable() - enable virtual functions
+ * @pdev: the PCIe device
+ * @max_vfs: the number of virtual functions to enable
+ *
+ * Returns the number of enabled VFs. If there are VFs enabled already or
+ * max_vfs is more than the total number of device can be enabled, returns
+ * failure.
+ */
+int hisi_qm_sriov_enable(struct pci_dev *pdev, int max_vfs)
+{
+	struct hisi_qm *qm = pci_get_drvdata(pdev);
+	int pre_existing_vfs, num_vfs, total_vfs, ret;
+
+	total_vfs = pci_sriov_get_totalvfs(pdev);
+	pre_existing_vfs = pci_num_vf(pdev);
+	if (pre_existing_vfs) {
+		pci_err(pdev, "%d VFs already enabled. Please disable pre-enabled VFs!\n",
+			pre_existing_vfs);
+		return 0;
+	}
+
+	num_vfs = min_t(int, max_vfs, total_vfs);
+	ret = qm_vf_q_assign(qm, num_vfs);
+	if (ret) {
+		pci_err(pdev, "Can't assign queues for VF!\n");
+		return ret;
+	}
+
+	qm->vfs_num = num_vfs;
+
+	ret = pci_enable_sriov(pdev, num_vfs);
+	if (ret) {
+		pci_err(pdev, "Can't enable VF!\n");
+		qm_clear_vft_config(qm);
+		return ret;
+	}
+
+	pci_info(pdev, "VF enabled, vfs_num(=%d)!\n", num_vfs);
+
+	return num_vfs;
+}
+EXPORT_SYMBOL_GPL(hisi_qm_sriov_enable);
+
+/**
+ * hisi_qm_sriov_disable - disable virtual functions
+ * @pdev: the PCI device
+ *
+ * Return failure if there are VFs assigned already.
+ */
+int hisi_qm_sriov_disable(struct pci_dev *pdev)
+{
+	struct hisi_qm *qm = pci_get_drvdata(pdev);
+
+	if (pci_vfs_assigned(pdev)) {
+		pci_err(pdev, "Failed to disable VFs as VFs are assigned!\n");
+		return -EPERM;
+	}
+
+	/* remove in hpre_pci_driver will be called to free VF resources */
+	pci_disable_sriov(pdev);
+	return qm_clear_vft_config(qm);
+}
+EXPORT_SYMBOL_GPL(hisi_qm_sriov_disable);
+
+/**
+ * hisi_qm_sriov_configure - configure the number of VFs
+ * @pdev: The PCI device
+ * @num_vfs: The number of VFs need enabled
+ *
+ * Enable SR-IOV according to num_vfs, 0 means disable.
+ */
+int hisi_qm_sriov_configure(struct pci_dev *pdev, int num_vfs)
+{
+	if (num_vfs == 0)
+		return hisi_qm_sriov_disable(pdev);
+	else
+		return hisi_qm_sriov_enable(pdev, num_vfs);
+}
+EXPORT_SYMBOL_GPL(hisi_qm_sriov_configure);
+
 static pci_ers_result_t qm_dev_err_handle(struct hisi_qm *qm)
 {
 	u32 err_sts;
diff --git a/drivers/crypto/hisilicon/qm.h b/drivers/crypto/hisilicon/qm.h
index ec5b6f48db6c..1b5171b91141 100644
--- a/drivers/crypto/hisilicon/qm.h
+++ b/drivers/crypto/hisilicon/qm.h
@@ -8,6 +8,8 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 
+#define QM_MAX_VFS_NUM_V2		63
+
 /* qm user domain */
 #define QM_ARUSER_M_CFG_1		0x100088
 #define AXUSER_SNOOP_ENABLE		BIT(30)
@@ -161,6 +163,7 @@ struct hisi_qm {
 	u32 qp_num;
 	u32 qp_in_used;
 	u32 ctrl_qp_num;
+	u32 vfs_num;
 	struct list_head list;
 
 	struct qm_dma qdma;
@@ -234,6 +237,24 @@ struct hisi_qp {
 	struct uacce_queue *uacce_q;
 };
 
+static inline int vfs_num_set(const char *val, const struct kernel_param *kp)
+{
+	u32 n;
+	int ret;
+
+	if (!val)
+		return -EINVAL;
+
+	ret = kstrtou32(val, 10, &n);
+	if (ret < 0)
+		return ret;
+
+	if (n > QM_MAX_VFS_NUM_V2)
+		return -EINVAL;
+
+	return param_set_int(val, kp);
+}
+
 static inline void hisi_qm_init_list(struct hisi_qm_list *qm_list)
 {
 	INIT_LIST_HEAD(&qm_list->list);
@@ -267,10 +288,12 @@ void hisi_qm_release_qp(struct hisi_qp *qp);
 int hisi_qp_send(struct hisi_qp *qp, const void *msg);
 int hisi_qm_get_free_qp_num(struct hisi_qm *qm);
 int hisi_qm_get_vft(struct hisi_qm *qm, u32 *base, u32 *number);
-int hisi_qm_set_vft(struct hisi_qm *qm, u32 fun_num, u32 base, u32 number);
 int hisi_qm_debug_init(struct hisi_qm *qm);
 enum qm_hw_ver hisi_qm_get_hw_version(struct pci_dev *pdev);
 void hisi_qm_debug_regs_clear(struct hisi_qm *qm);
+int hisi_qm_sriov_enable(struct pci_dev *pdev, int max_vfs);
+int hisi_qm_sriov_disable(struct pci_dev *pdev);
+int hisi_qm_sriov_configure(struct pci_dev *pdev, int num_vfs);
 void hisi_qm_dev_err_init(struct hisi_qm *qm);
 void hisi_qm_dev_err_uninit(struct hisi_qm *qm);
 pci_ers_result_t hisi_qm_dev_err_detected(struct pci_dev *pdev,
diff --git a/drivers/crypto/hisilicon/sec2/sec.h b/drivers/crypto/hisilicon/sec2/sec.h
index 3598fa17beb2..2326634a1d71 100644
--- a/drivers/crypto/hisilicon/sec2/sec.h
+++ b/drivers/crypto/hisilicon/sec2/sec.h
@@ -172,7 +172,6 @@ struct sec_dev {
 	struct sec_debug debug;
 	u32 ctx_q_num;
 	bool iommu_used;
-	u32 num_vfs;
 	unsigned long status;
 };
 
diff --git a/drivers/crypto/hisilicon/sec2/sec_main.c b/drivers/crypto/hisilicon/sec2/sec_main.c
index 1f54ebe164b6..c76c49ed883c 100644
--- a/drivers/crypto/hisilicon/sec2/sec_main.c
+++ b/drivers/crypto/hisilicon/sec2/sec_main.c
@@ -207,6 +207,15 @@ static u32 ctx_q_num = SEC_CTX_Q_NUM_DEF;
 module_param_cb(ctx_q_num, &sec_ctx_q_num_ops, &ctx_q_num, 0444);
 MODULE_PARM_DESC(ctx_q_num, "Queue num in ctx (24 default, 2, 4, ..., 32)");
 
+static const struct kernel_param_ops vfs_num_ops = {
+	.set = vfs_num_set,
+	.get = param_get_int,
+};
+
+static u32 vfs_num;
+module_param_cb(vfs_num, &vfs_num_ops, &vfs_num, 0444);
+MODULE_PARM_DESC(vfs_num, "Number of VFs to enable(1-63), 0(default)");
+
 void sec_destroy_qps(struct hisi_qp **qps, int qp_num)
 {
 	hisi_qm_free_qps(qps, qp_num);
@@ -424,23 +433,22 @@ static u32 sec_current_qm_read(struct sec_debug_file *file)
 static int sec_current_qm_write(struct sec_debug_file *file, u32 val)
 {
 	struct hisi_qm *qm = file->qm;
-	struct sec_dev *sec = container_of(qm, struct sec_dev, qm);
 	u32 vfq_num;
 	u32 tmp;
 
-	if (val > sec->num_vfs)
+	if (val > qm->vfs_num)
 		return -EINVAL;
 
 	/* According PF or VF Dev ID to calculation curr_qm_qp_num and store */
 	if (!val) {
 		qm->debug.curr_qm_qp_num = qm->qp_num;
 	} else {
-		vfq_num = (qm->ctrl_qp_num - qm->qp_num) / sec->num_vfs;
+		vfq_num = (qm->ctrl_qp_num - qm->qp_num) / qm->vfs_num;
 
-		if (val == sec->num_vfs)
+		if (val == qm->vfs_num)
 			qm->debug.curr_qm_qp_num =
 				qm->ctrl_qp_num - qm->qp_num -
-				(sec->num_vfs - 1) * vfq_num;
+				(qm->vfs_num - 1) * vfq_num;
 		else
 			qm->debug.curr_qm_qp_num = vfq_num;
 	}
@@ -877,8 +885,17 @@ static int sec_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 		goto err_remove_from_list;
 	}
 
+	if (qm->fun_type == QM_HW_PF && vfs_num) {
+		ret = hisi_qm_sriov_enable(pdev, vfs_num);
+		if (ret < 0)
+			goto err_crypto_unregister;
+	}
+
 	return 0;
 
+err_crypto_unregister:
+	sec_unregister_from_crypto();
+
 err_remove_from_list:
 	hisi_qm_del_from_list(qm, &sec_devices);
 	sec_debugfs_exit(sec);
@@ -893,110 +910,6 @@ static int sec_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	return ret;
 }
 
-/* now we only support equal assignment */
-static int sec_vf_q_assign(struct sec_dev *sec, u32 num_vfs)
-{
-	struct hisi_qm *qm = &sec->qm;
-	u32 qp_num = qm->qp_num;
-	u32 q_base = qp_num;
-	u32 q_num, remain_q_num;
-	int i, j, ret;
-
-	if (!num_vfs)
-		return -EINVAL;
-
-	remain_q_num = qm->ctrl_qp_num - qp_num;
-	q_num = remain_q_num / num_vfs;
-
-	for (i = 1; i <= num_vfs; i++) {
-		if (i == num_vfs)
-			q_num += remain_q_num % num_vfs;
-		ret = hisi_qm_set_vft(qm, i, q_base, q_num);
-		if (ret) {
-			for (j = i; j > 0; j--)
-				hisi_qm_set_vft(qm, j, 0, 0);
-			return ret;
-		}
-		q_base += q_num;
-	}
-
-	return 0;
-}
-
-static int sec_clear_vft_config(struct sec_dev *sec)
-{
-	struct hisi_qm *qm = &sec->qm;
-	u32 num_vfs = sec->num_vfs;
-	int ret;
-	u32 i;
-
-	for (i = 1; i <= num_vfs; i++) {
-		ret = hisi_qm_set_vft(qm, i, 0, 0);
-		if (ret)
-			return ret;
-	}
-
-	sec->num_vfs = 0;
-
-	return 0;
-}
-
-static int sec_sriov_enable(struct pci_dev *pdev, int max_vfs)
-{
-	struct sec_dev *sec = pci_get_drvdata(pdev);
-	int pre_existing_vfs, ret;
-	u32 num_vfs;
-
-	pre_existing_vfs = pci_num_vf(pdev);
-
-	if (pre_existing_vfs) {
-		pci_err(pdev, "Can't enable VF. Please disable at first!\n");
-		return 0;
-	}
-
-	num_vfs = min_t(u32, max_vfs, SEC_VF_NUM);
-
-	ret = sec_vf_q_assign(sec, num_vfs);
-	if (ret) {
-		pci_err(pdev, "Can't assign queues for VF!\n");
-		return ret;
-	}
-
-	sec->num_vfs = num_vfs;
-
-	ret = pci_enable_sriov(pdev, num_vfs);
-	if (ret) {
-		pci_err(pdev, "Can't enable VF!\n");
-		sec_clear_vft_config(sec);
-		return ret;
-	}
-
-	return num_vfs;
-}
-
-static int sec_sriov_disable(struct pci_dev *pdev)
-{
-	struct sec_dev *sec = pci_get_drvdata(pdev);
-
-	if (pci_vfs_assigned(pdev)) {
-		pci_err(pdev, "Can't disable VFs while VFs are assigned!\n");
-		return -EPERM;
-	}
-
-	/* remove in sec_pci_driver will be called to free VF resources */
-	pci_disable_sriov(pdev);
-
-	return sec_clear_vft_config(sec);
-}
-
-static int sec_sriov_configure(struct pci_dev *pdev, int num_vfs)
-{
-	if (num_vfs)
-		return sec_sriov_enable(pdev, num_vfs);
-	else
-		return sec_sriov_disable(pdev);
-}
-
 static void sec_remove(struct pci_dev *pdev)
 {
 	struct sec_dev *sec = pci_get_drvdata(pdev);
@@ -1006,8 +919,8 @@ static void sec_remove(struct pci_dev *pdev)
 
 	hisi_qm_del_from_list(qm, &sec_devices);
 
-	if (qm->fun_type == QM_HW_PF && sec->num_vfs)
-		(void)sec_sriov_disable(pdev);
+	if (qm->fun_type == QM_HW_PF && qm->vfs_num)
+		hisi_qm_sriov_disable(pdev);
 
 	sec_debugfs_exit(sec);
 
@@ -1031,7 +944,7 @@ static struct pci_driver sec_pci_driver = {
 	.probe = sec_probe,
 	.remove = sec_remove,
 	.err_handler = &sec_err_handler,
-	.sriov_configure = sec_sriov_configure,
+	.sriov_configure = hisi_qm_sriov_configure,
 };
 
 static void sec_register_debugfs(void)
diff --git a/drivers/crypto/hisilicon/zip/zip_main.c b/drivers/crypto/hisilicon/zip/zip_main.c
index fcc85d2dbd07..fe9d6d29eed2 100644
--- a/drivers/crypto/hisilicon/zip/zip_main.c
+++ b/drivers/crypto/hisilicon/zip/zip_main.c
@@ -134,7 +134,6 @@ struct ctrl_debug_file {
  * Just relevant for PF.
  */
 struct hisi_zip_ctrl {
-	u32 num_vfs;
 	struct hisi_zip *hisi_zip;
 	struct dentry *debug_root;
 	struct ctrl_debug_file files[HZIP_DEBUG_FILE_NUM];
@@ -232,9 +231,14 @@ static u32 pf_q_num = HZIP_PF_DEF_Q_NUM;
 module_param_cb(pf_q_num, &pf_q_num_ops, &pf_q_num, 0444);
 MODULE_PARM_DESC(pf_q_num, "Number of queues in PF(v1 1-4096, v2 1-1024)");
 
+static const struct kernel_param_ops vfs_num_ops = {
+	.set = vfs_num_set,
+	.get = param_get_int,
+};
+
 static u32 vfs_num;
-module_param(vfs_num, uint, 0444);
-MODULE_PARM_DESC(vfs_num, "Number of VFs to enable(1-63)");
+module_param_cb(vfs_num, &vfs_num_ops, &vfs_num, 0444);
+MODULE_PARM_DESC(vfs_num, "Number of VFs to enable(1-63), 0(default)");
 
 static const struct pci_device_id hisi_zip_dev_ids[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, PCI_DEVICE_ID_ZIP_PF) },
@@ -342,21 +346,20 @@ static u32 current_qm_read(struct ctrl_debug_file *file)
 static int current_qm_write(struct ctrl_debug_file *file, u32 val)
 {
 	struct hisi_qm *qm = file_to_qm(file);
-	struct hisi_zip_ctrl *ctrl = file->ctrl;
 	u32 vfq_num;
 	u32 tmp;
 
-	if (val > ctrl->num_vfs)
+	if (val > qm->vfs_num)
 		return -EINVAL;
 
 	/* Calculate curr_qm_qp_num and store */
 	if (val == 0) {
 		qm->debug.curr_qm_qp_num = qm->qp_num;
 	} else {
-		vfq_num = (qm->ctrl_qp_num - qm->qp_num) / ctrl->num_vfs;
-		if (val == ctrl->num_vfs)
+		vfq_num = (qm->ctrl_qp_num - qm->qp_num) / qm->vfs_num;
+		if (val == qm->vfs_num)
 			qm->debug.curr_qm_qp_num = qm->ctrl_qp_num -
-				qm->qp_num - (ctrl->num_vfs - 1) * vfq_num;
+				qm->qp_num - (qm->vfs_num - 1) * vfq_num;
 		else
 			qm->debug.curr_qm_qp_num = vfq_num;
 	}
@@ -655,102 +658,6 @@ static int hisi_zip_pf_probe_init(struct hisi_zip *hisi_zip)
 	return 0;
 }
 
-/* Currently we only support equal assignment */
-static int hisi_zip_vf_q_assign(struct hisi_zip *hisi_zip, int num_vfs)
-{
-	struct hisi_qm *qm = &hisi_zip->qm;
-	u32 qp_num = qm->qp_num;
-	u32 q_base = qp_num;
-	u32 q_num, remain_q_num, i;
-	int ret;
-
-	if (!num_vfs)
-		return -EINVAL;
-
-	remain_q_num = qm->ctrl_qp_num - qp_num;
-	if (remain_q_num < num_vfs)
-		return -EINVAL;
-
-	q_num = remain_q_num / num_vfs;
-	for (i = 1; i <= num_vfs; i++) {
-		if (i == num_vfs)
-			q_num += remain_q_num % num_vfs;
-		ret = hisi_qm_set_vft(qm, i, q_base, q_num);
-		if (ret)
-			return ret;
-		q_base += q_num;
-	}
-
-	return 0;
-}
-
-static int hisi_zip_clear_vft_config(struct hisi_zip *hisi_zip)
-{
-	struct hisi_zip_ctrl *ctrl = hisi_zip->ctrl;
-	struct hisi_qm *qm = &hisi_zip->qm;
-	u32 i, num_vfs = ctrl->num_vfs;
-	int ret;
-
-	for (i = 1; i <= num_vfs; i++) {
-		ret = hisi_qm_set_vft(qm, i, 0, 0);
-		if (ret)
-			return ret;
-	}
-
-	ctrl->num_vfs = 0;
-
-	return 0;
-}
-
-static int hisi_zip_sriov_enable(struct pci_dev *pdev, int max_vfs)
-{
-	struct hisi_zip *hisi_zip = pci_get_drvdata(pdev);
-	int pre_existing_vfs, num_vfs, ret;
-
-	pre_existing_vfs = pci_num_vf(pdev);
-
-	if (pre_existing_vfs) {
-		dev_err(&pdev->dev,
-			"Can't enable VF. Please disable pre-enabled VFs!\n");
-		return 0;
-	}
-
-	num_vfs = min_t(int, max_vfs, HZIP_VF_NUM);
-
-	ret = hisi_zip_vf_q_assign(hisi_zip, num_vfs);
-	if (ret) {
-		dev_err(&pdev->dev, "Can't assign queues for VF!\n");
-		return ret;
-	}
-
-	hisi_zip->ctrl->num_vfs = num_vfs;
-
-	ret = pci_enable_sriov(pdev, num_vfs);
-	if (ret) {
-		dev_err(&pdev->dev, "Can't enable VF!\n");
-		hisi_zip_clear_vft_config(hisi_zip);
-		return ret;
-	}
-
-	return num_vfs;
-}
-
-static int hisi_zip_sriov_disable(struct pci_dev *pdev)
-{
-	struct hisi_zip *hisi_zip = pci_get_drvdata(pdev);
-
-	if (pci_vfs_assigned(pdev)) {
-		dev_err(&pdev->dev,
-			"Can't disable VFs while VFs are assigned!\n");
-		return -EPERM;
-	}
-
-	/* remove in hisi_zip_pci_driver will be called to free VF resources */
-	pci_disable_sriov(pdev);
-
-	return hisi_zip_clear_vft_config(hisi_zip);
-}
-
 static int hisi_zip_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 {
 	struct hisi_zip *hisi_zip;
@@ -823,7 +730,7 @@ static int hisi_zip_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	}
 
 	if (qm->fun_type == QM_HW_PF && vfs_num > 0) {
-		ret = hisi_zip_sriov_enable(pdev, vfs_num);
+		ret = hisi_qm_sriov_enable(pdev, vfs_num);
 		if (ret < 0)
 			goto err_remove_from_list;
 	}
@@ -839,21 +746,13 @@ static int hisi_zip_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	return ret;
 }
 
-static int hisi_zip_sriov_configure(struct pci_dev *pdev, int num_vfs)
-{
-	if (num_vfs == 0)
-		return hisi_zip_sriov_disable(pdev);
-	else
-		return hisi_zip_sriov_enable(pdev, num_vfs);
-}
-
 static void hisi_zip_remove(struct pci_dev *pdev)
 {
 	struct hisi_zip *hisi_zip = pci_get_drvdata(pdev);
 	struct hisi_qm *qm = &hisi_zip->qm;
 
-	if (qm->fun_type == QM_HW_PF && hisi_zip->ctrl->num_vfs != 0)
-		hisi_zip_sriov_disable(pdev);
+	if (qm->fun_type == QM_HW_PF && qm->vfs_num)
+		hisi_qm_sriov_disable(pdev);
 
 	hisi_zip_debugfs_exit(hisi_zip);
 	hisi_qm_stop(qm);
@@ -873,7 +772,7 @@ static struct pci_driver hisi_zip_pci_driver = {
 	.probe			= hisi_zip_probe,
 	.remove			= hisi_zip_remove,
 	.sriov_configure	= IS_ENABLED(CONFIG_PCI_IOV) ?
-					hisi_zip_sriov_configure : NULL,
+					hisi_qm_sriov_configure : NULL,
 	.err_handler		= &hisi_zip_err_handler,
 };
 
diff --git a/drivers/crypto/marvell/octeontx/otx_cptpf_main.c b/drivers/crypto/marvell/octeontx/otx_cptpf_main.c
index 200fb3303db0..34bb3063eb70 100644
--- a/drivers/crypto/marvell/octeontx/otx_cptpf_main.c
+++ b/drivers/crypto/marvell/octeontx/otx_cptpf_main.c
@@ -79,13 +79,13 @@ static int otx_cpt_device_init(struct otx_cpt_device *cpt)
 	/* Check BIST status */
 	bist = (u64)otx_cpt_check_bist_status(cpt);
 	if (bist) {
-		dev_err(dev, "RAM BIST failed with code 0x%llx", bist);
+		dev_err(dev, "RAM BIST failed with code 0x%llx\n", bist);
 		return -ENODEV;
 	}
 
 	bist = otx_cpt_check_exe_bist_status(cpt);
 	if (bist) {
-		dev_err(dev, "Engine BIST failed with code 0x%llx", bist);
+		dev_err(dev, "Engine BIST failed with code 0x%llx\n", bist);
 		return -ENODEV;
 	}
 
diff --git a/drivers/crypto/marvell/octeontx/otx_cptpf_mbox.c b/drivers/crypto/marvell/octeontx/otx_cptpf_mbox.c
index a6774232e9a3..a9e3de65875a 100644
--- a/drivers/crypto/marvell/octeontx/otx_cptpf_mbox.c
+++ b/drivers/crypto/marvell/octeontx/otx_cptpf_mbox.c
@@ -63,11 +63,11 @@ static void dump_mbox_msg(struct otx_cpt_mbox *mbox_msg, int vf_id)
 	hex_dump_to_buffer(mbox_msg, sizeof(struct otx_cpt_mbox), 16, 8,
 			   raw_data_str, OTX_CPT_MAX_MBOX_DATA_STR_SIZE, false);
 	if (vf_id >= 0)
-		pr_debug("MBOX opcode %s received from VF%d raw_data %s",
+		pr_debug("MBOX opcode %s received from VF%d raw_data %s\n",
 			 get_mbox_opcode_str(mbox_msg->msg), vf_id,
 			 raw_data_str);
 	else
-		pr_debug("MBOX opcode %s received from PF raw_data %s",
+		pr_debug("MBOX opcode %s received from PF raw_data %s\n",
 			 get_mbox_opcode_str(mbox_msg->msg), raw_data_str);
 }
 
@@ -140,20 +140,20 @@ static int otx_cpt_bind_vq_to_grp(struct otx_cpt_device *cpt, u8 q, u8 grp)
 	struct otx_cpt_ucode *ucode;
 
 	if (q >= cpt->max_vfs) {
-		dev_err(dev, "Requested queue %d is > than maximum avail %d",
+		dev_err(dev, "Requested queue %d is > than maximum avail %d\n",
 			q, cpt->max_vfs);
 		return -EINVAL;
 	}
 
 	if (grp >= OTX_CPT_MAX_ENGINE_GROUPS) {
-		dev_err(dev, "Requested group %d is > than maximum avail %d",
+		dev_err(dev, "Requested group %d is > than maximum avail %d\n",
 			grp, OTX_CPT_MAX_ENGINE_GROUPS);
 		return -EINVAL;
 	}
 
 	eng_grp = &cpt->eng_grps.grp[grp];
 	if (!eng_grp->is_enabled) {
-		dev_err(dev, "Requested engine group %d is disabled", grp);
+		dev_err(dev, "Requested engine group %d is disabled\n", grp);
 		return -EINVAL;
 	}
 
@@ -212,7 +212,7 @@ static void otx_cpt_handle_mbox_intr(struct otx_cpt_device *cpt, int vf)
 		vftype = otx_cpt_bind_vq_to_grp(cpt, vf, (u8)mbx.data);
 		if ((vftype != OTX_CPT_AE_TYPES) &&
 		    (vftype != OTX_CPT_SE_TYPES)) {
-			dev_err(dev, "VF%d binding to eng group %llu failed",
+			dev_err(dev, "VF%d binding to eng group %llu failed\n",
 				vf, mbx.data);
 			otx_cptpf_mbox_send_nack(cpt, vf, &mbx);
 		} else {
diff --git a/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c b/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c
index d04baa319592..fec8f3b9b112 100644
--- a/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c
+++ b/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c
@@ -62,7 +62,7 @@ static struct otx_cpt_bitmap get_cores_bmap(struct device *dev,
 	int i;
 
 	if (eng_grp->g->engs_num > OTX_CPT_MAX_ENGINES) {
-		dev_err(dev, "unsupported number of engines %d on octeontx",
+		dev_err(dev, "unsupported number of engines %d on octeontx\n",
 			eng_grp->g->engs_num);
 		return bmap;
 	}
@@ -78,7 +78,7 @@ static struct otx_cpt_bitmap get_cores_bmap(struct device *dev,
 	}
 
 	if (!found)
-		dev_err(dev, "No engines reserved for engine group %d",
+		dev_err(dev, "No engines reserved for engine group %d\n",
 			eng_grp->idx);
 	return bmap;
 }
@@ -306,7 +306,7 @@ static int process_tar_file(struct device *dev,
 	ucode_size = ntohl(ucode_hdr->code_length) * 2;
 	if (!ucode_size || (size < round_up(ucode_size, 16) +
 	    sizeof(struct otx_cpt_ucode_hdr) + OTX_CPT_UCODE_SIGN_LEN)) {
-		dev_err(dev, "Ucode %s invalid size", filename);
+		dev_err(dev, "Ucode %s invalid size\n", filename);
 		return -EINVAL;
 	}
 
@@ -379,18 +379,18 @@ static void print_tar_dbg_info(struct tar_arch_info_t *tar_arch,
 {
 	struct tar_ucode_info_t *curr;
 
-	pr_debug("Tar archive filename %s", tar_filename);
-	pr_debug("Tar archive pointer %p, size %ld", tar_arch->fw->data,
+	pr_debug("Tar archive filename %s\n", tar_filename);
+	pr_debug("Tar archive pointer %p, size %ld\n", tar_arch->fw->data,
 		 tar_arch->fw->size);
 	list_for_each_entry(curr, &tar_arch->ucodes, list) {
-		pr_debug("Ucode filename %s", curr->ucode.filename);
-		pr_debug("Ucode version string %s", curr->ucode.ver_str);
-		pr_debug("Ucode version %d.%d.%d.%d",
+		pr_debug("Ucode filename %s\n", curr->ucode.filename);
+		pr_debug("Ucode version string %s\n", curr->ucode.ver_str);
+		pr_debug("Ucode version %d.%d.%d.%d\n",
 			 curr->ucode.ver_num.nn, curr->ucode.ver_num.xx,
 			 curr->ucode.ver_num.yy, curr->ucode.ver_num.zz);
-		pr_debug("Ucode type (%d) %s", curr->ucode.type,
+		pr_debug("Ucode type (%d) %s\n", curr->ucode.type,
 			 get_ucode_type_str(curr->ucode.type));
-		pr_debug("Ucode size %d", curr->ucode.size);
+		pr_debug("Ucode size %d\n", curr->ucode.size);
 		pr_debug("Ucode ptr %p\n", curr->ucode_ptr);
 	}
 }
@@ -417,14 +417,14 @@ static struct tar_arch_info_t *load_tar_archive(struct device *dev,
 		goto release_tar_arch;
 
 	if (tar_arch->fw->size < TAR_BLOCK_LEN) {
-		dev_err(dev, "Invalid tar archive %s ", tar_filename);
+		dev_err(dev, "Invalid tar archive %s\n", tar_filename);
 		goto release_tar_arch;
 	}
 
 	tar_size = tar_arch->fw->size;
 	tar_blk = (struct tar_blk_t *) tar_arch->fw->data;
 	if (strncmp(tar_blk->hdr.magic, TAR_MAGIC, TAR_MAGIC_LEN - 1)) {
-		dev_err(dev, "Unsupported format of tar archive %s",
+		dev_err(dev, "Unsupported format of tar archive %s\n",
 			tar_filename);
 		goto release_tar_arch;
 	}
@@ -437,7 +437,7 @@ static struct tar_arch_info_t *load_tar_archive(struct device *dev,
 
 		if (tar_offs + cur_size > tar_size ||
 		    tar_offs + 2*TAR_BLOCK_LEN > tar_size) {
-			dev_err(dev, "Invalid tar archive %s ", tar_filename);
+			dev_err(dev, "Invalid tar archive %s\n", tar_filename);
 			goto release_tar_arch;
 		}
 
@@ -458,7 +458,7 @@ static struct tar_arch_info_t *load_tar_archive(struct device *dev,
 
 		/* Check for the end of the archive */
 		if (tar_offs + 2*TAR_BLOCK_LEN > tar_size) {
-			dev_err(dev, "Invalid tar archive %s ", tar_filename);
+			dev_err(dev, "Invalid tar archive %s\n", tar_filename);
 			goto release_tar_arch;
 		}
 
@@ -563,13 +563,13 @@ static void print_engs_info(struct otx_cpt_eng_grp_info *eng_grp,
 
 static void print_ucode_dbg_info(struct otx_cpt_ucode *ucode)
 {
-	pr_debug("Ucode info");
-	pr_debug("Ucode version string %s", ucode->ver_str);
-	pr_debug("Ucode version %d.%d.%d.%d", ucode->ver_num.nn,
+	pr_debug("Ucode info\n");
+	pr_debug("Ucode version string %s\n", ucode->ver_str);
+	pr_debug("Ucode version %d.%d.%d.%d\n", ucode->ver_num.nn,
 		 ucode->ver_num.xx, ucode->ver_num.yy, ucode->ver_num.zz);
-	pr_debug("Ucode type %s", get_ucode_type_str(ucode->type));
-	pr_debug("Ucode size %d", ucode->size);
-	pr_debug("Ucode virt address %16.16llx", (u64)ucode->align_va);
+	pr_debug("Ucode type %s\n", get_ucode_type_str(ucode->type));
+	pr_debug("Ucode size %d\n", ucode->size);
+	pr_debug("Ucode virt address %16.16llx\n", (u64)ucode->align_va);
 	pr_debug("Ucode phys address %16.16llx\n", ucode->align_dma);
 }
 
@@ -600,19 +600,19 @@ static void print_dbg_info(struct device *dev,
 	u32 mask[4];
 	int i, j;
 
-	pr_debug("Engine groups global info");
-	pr_debug("max SE %d, max AE %d",
+	pr_debug("Engine groups global info\n");
+	pr_debug("max SE %d, max AE %d\n",
 		 eng_grps->avail.max_se_cnt, eng_grps->avail.max_ae_cnt);
-	pr_debug("free SE %d", eng_grps->avail.se_cnt);
-	pr_debug("free AE %d", eng_grps->avail.ae_cnt);
+	pr_debug("free SE %d\n", eng_grps->avail.se_cnt);
+	pr_debug("free AE %d\n", eng_grps->avail.ae_cnt);
 
 	for (i = 0; i < OTX_CPT_MAX_ENGINE_GROUPS; i++) {
 		grp = &eng_grps->grp[i];
-		pr_debug("engine_group%d, state %s", i, grp->is_enabled ?
+		pr_debug("engine_group%d, state %s\n", i, grp->is_enabled ?
 			 "enabled" : "disabled");
 		if (grp->is_enabled) {
 			mirrored_grp = &eng_grps->grp[grp->mirror.idx];
-			pr_debug("Ucode0 filename %s, version %s",
+			pr_debug("Ucode0 filename %s, version %s\n",
 				 grp->mirror.is_ena ?
 				 mirrored_grp->ucode[0].filename :
 				 grp->ucode[0].filename,
@@ -626,18 +626,18 @@ static void print_dbg_info(struct device *dev,
 			if (engs->type) {
 				print_engs_info(grp, engs_info,
 						2*OTX_CPT_UCODE_NAME_LENGTH, j);
-				pr_debug("Slot%d: %s", j, engs_info);
+				pr_debug("Slot%d: %s\n", j, engs_info);
 				bitmap_to_arr32(mask, engs->bmap,
 						eng_grps->engs_num);
-				pr_debug("Mask:  %8.8x %8.8x %8.8x %8.8x",
+				pr_debug("Mask: %8.8x %8.8x %8.8x %8.8x\n",
 					 mask[3], mask[2], mask[1], mask[0]);
 			} else
-				pr_debug("Slot%d not used", j);
+				pr_debug("Slot%d not used\n", j);
 		}
 		if (grp->is_enabled) {
 			cpt_print_engines_mask(grp, dev, engs_mask,
 					       OTX_CPT_UCODE_NAME_LENGTH);
-			pr_debug("Cmask: %s", engs_mask);
+			pr_debug("Cmask: %s\n", engs_mask);
 		}
 	}
 }
@@ -766,7 +766,7 @@ static int check_engines_availability(struct device *dev,
 
 	if (avail_cnt < req_eng->count) {
 		dev_err(dev,
-			"Error available %s engines %d < than requested %d",
+			"Error available %s engines %d < than requested %d\n",
 			get_eng_type_str(req_eng->type),
 			avail_cnt, req_eng->count);
 		return -EBUSY;
@@ -867,7 +867,7 @@ static int copy_ucode_to_dma_mem(struct device *dev,
 				       OTX_CPT_UCODE_ALIGNMENT,
 				       &ucode->dma, GFP_KERNEL);
 	if (!ucode->va) {
-		dev_err(dev, "Unable to allocate space for microcode");
+		dev_err(dev, "Unable to allocate space for microcode\n");
 		return -ENOMEM;
 	}
 	ucode->align_va = PTR_ALIGN(ucode->va, OTX_CPT_UCODE_ALIGNMENT);
@@ -905,15 +905,15 @@ static int ucode_load(struct device *dev, struct otx_cpt_ucode *ucode,
 	ucode->size = ntohl(ucode_hdr->code_length) * 2;
 	if (!ucode->size || (fw->size < round_up(ucode->size, 16)
 	    + sizeof(struct otx_cpt_ucode_hdr) + OTX_CPT_UCODE_SIGN_LEN)) {
-		dev_err(dev, "Ucode %s invalid size", ucode_filename);
+		dev_err(dev, "Ucode %s invalid size\n", ucode_filename);
 		ret = -EINVAL;
 		goto release_fw;
 	}
 
 	ret = get_ucode_type(ucode_hdr, &ucode->type);
 	if (ret) {
-		dev_err(dev, "Microcode %s unknown type 0x%x", ucode->filename,
-			ucode->type);
+		dev_err(dev, "Microcode %s unknown type 0x%x\n",
+			ucode->filename, ucode->type);
 		goto release_fw;
 	}
 
@@ -1083,7 +1083,7 @@ static int eng_grp_update_masks(struct device *dev,
 			break;
 
 		default:
-			dev_err(dev, "Invalid engine type %d", engs->type);
+			dev_err(dev, "Invalid engine type %d\n", engs->type);
 			return -EINVAL;
 		}
 
@@ -1142,13 +1142,14 @@ static int delete_engine_group(struct device *dev,
 		return -EINVAL;
 
 	if (eng_grp->mirror.ref_count) {
-		dev_err(dev, "Can't delete engine_group%d as it is used by:",
+		dev_err(dev, "Can't delete engine_group%d as it is used by engine_group(s):",
 			eng_grp->idx);
 		for (i = 0; i < OTX_CPT_MAX_ENGINE_GROUPS; i++) {
 			if (eng_grp->g->grp[i].mirror.is_ena &&
 			    eng_grp->g->grp[i].mirror.idx == eng_grp->idx)
-				dev_err(dev, "engine_group%d", i);
+				pr_cont(" %d", i);
 		}
+		pr_cont("\n");
 		return -EINVAL;
 	}
 
@@ -1182,7 +1183,7 @@ static int validate_1_ucode_scenario(struct device *dev,
 		if (!otx_cpt_uc_supports_eng_type(&eng_grp->ucode[0],
 						  engs[i].type)) {
 			dev_err(dev,
-				"Microcode %s does not support %s engines",
+				"Microcode %s does not support %s engines\n",
 				eng_grp->ucode[0].filename,
 				get_eng_type_str(engs[i].type));
 			return -EINVAL;
@@ -1220,7 +1221,7 @@ static int create_engine_group(struct device *dev,
 	/* Validate if requested engine types are supported by this device */
 	for (i = 0; i < engs_cnt; i++)
 		if (!dev_supports_eng_type(eng_grps, engs[i].type)) {
-			dev_err(dev, "Device does not support %s engines",
+			dev_err(dev, "Device does not support %s engines\n",
 				get_eng_type_str(engs[i].type));
 			return -EPERM;
 		}
@@ -1228,7 +1229,7 @@ static int create_engine_group(struct device *dev,
 	/* Find engine group which is not used */
 	eng_grp = find_unused_eng_grp(eng_grps);
 	if (!eng_grp) {
-		dev_err(dev, "Error all engine groups are being used");
+		dev_err(dev, "Error all engine groups are being used\n");
 		return -ENOSPC;
 	}
 
@@ -1298,11 +1299,11 @@ static int create_engine_group(struct device *dev,
 	eng_grp->is_enabled = true;
 	if (eng_grp->mirror.is_ena)
 		dev_info(dev,
-			 "Engine_group%d: reuse microcode %s from group %d",
+			 "Engine_group%d: reuse microcode %s from group %d\n",
 			 eng_grp->idx, mirrored_eng_grp->ucode[0].ver_str,
 			 mirrored_eng_grp->idx);
 	else
-		dev_info(dev, "Engine_group%d: microcode loaded %s",
+		dev_info(dev, "Engine_group%d: microcode loaded %s\n",
 			 eng_grp->idx, eng_grp->ucode[0].ver_str);
 
 	return 0;
@@ -1412,14 +1413,14 @@ static ssize_t ucode_load_store(struct device *dev,
 	} else {
 		if (del_grp_idx < 0 ||
 		    del_grp_idx >= OTX_CPT_MAX_ENGINE_GROUPS) {
-			dev_err(dev, "Invalid engine group index %d",
+			dev_err(dev, "Invalid engine group index %d\n",
 				del_grp_idx);
 			ret = -EINVAL;
 			return ret;
 		}
 
 		if (!eng_grps->grp[del_grp_idx].is_enabled) {
-			dev_err(dev, "Error engine_group%d is not configured",
+			dev_err(dev, "Error engine_group%d is not configured\n",
 				del_grp_idx);
 			ret = -EINVAL;
 			return ret;
@@ -1568,7 +1569,7 @@ void otx_cpt_disable_all_cores(struct otx_cpt_device *cpt)
 		udelay(CSR_DELAY);
 		reg = readq(cpt->reg_base + OTX_CPT_PF_EXEC_BUSY);
 		if (timeout--) {
-			dev_warn(&cpt->pdev->dev, "Cores still busy");
+			dev_warn(&cpt->pdev->dev, "Cores still busy\n");
 			break;
 		}
 	}
@@ -1626,7 +1627,7 @@ int otx_cpt_init_eng_grps(struct pci_dev *pdev,
 			     eng_grps->avail.max_ae_cnt;
 	if (eng_grps->engs_num > OTX_CPT_MAX_ENGINES) {
 		dev_err(&pdev->dev,
-			"Number of engines %d > than max supported %d",
+			"Number of engines %d > than max supported %d\n",
 			eng_grps->engs_num, OTX_CPT_MAX_ENGINES);
 		ret = -EINVAL;
 		goto err;
diff --git a/drivers/crypto/marvell/octeontx/otx_cptvf_algs.c b/drivers/crypto/marvell/octeontx/otx_cptvf_algs.c
index 06202bcffb33..60e744f680d3 100644
--- a/drivers/crypto/marvell/octeontx/otx_cptvf_algs.c
+++ b/drivers/crypto/marvell/octeontx/otx_cptvf_algs.c
@@ -1660,7 +1660,7 @@ int otx_cpt_crypto_init(struct pci_dev *pdev, struct module *mod,
 	case OTX_CPT_SE_TYPES:
 		count = atomic_read(&se_devices.count);
 		if (count >= CPT_MAX_VF_NUM) {
-			dev_err(&pdev->dev, "No space to add a new device");
+			dev_err(&pdev->dev, "No space to add a new device\n");
 			ret = -ENOSPC;
 			goto err;
 		}
@@ -1687,7 +1687,7 @@ int otx_cpt_crypto_init(struct pci_dev *pdev, struct module *mod,
 	case OTX_CPT_AE_TYPES:
 		count = atomic_read(&ae_devices.count);
 		if (count >= CPT_MAX_VF_NUM) {
-			dev_err(&pdev->dev, "No space to a add new device");
+			dev_err(&pdev->dev, "No space to a add new device\n");
 			ret = -ENOSPC;
 			goto err;
 		}
@@ -1728,7 +1728,7 @@ void otx_cpt_crypto_exit(struct pci_dev *pdev, struct module *mod,
 		}
 
 	if (!dev_found) {
-		dev_err(&pdev->dev, "%s device not found", __func__);
+		dev_err(&pdev->dev, "%s device not found\n", __func__);
 		goto exit;
 	}
 
diff --git a/drivers/crypto/marvell/octeontx/otx_cptvf_main.c b/drivers/crypto/marvell/octeontx/otx_cptvf_main.c
index a91860b5dc77..ce3168327a39 100644
--- a/drivers/crypto/marvell/octeontx/otx_cptvf_main.c
+++ b/drivers/crypto/marvell/octeontx/otx_cptvf_main.c
@@ -584,7 +584,7 @@ static irqreturn_t cptvf_done_intr_handler(int __always_unused irq,
 		cptvf_write_vq_done_ack(cptvf, intr);
 		wqe = get_cptvf_vq_wqe(cptvf, 0);
 		if (unlikely(!wqe)) {
-			dev_err(&pdev->dev, "No work to schedule for VF (%d)",
+			dev_err(&pdev->dev, "No work to schedule for VF (%d)\n",
 				cptvf->vfid);
 			return IRQ_NONE;
 		}
@@ -602,7 +602,7 @@ static void cptvf_set_irq_affinity(struct otx_cptvf *cptvf, int vec)
 	if (!zalloc_cpumask_var(&cptvf->affinity_mask[vec],
 				GFP_KERNEL)) {
 		dev_err(&pdev->dev,
-			"Allocation failed for affinity_mask for VF %d",
+			"Allocation failed for affinity_mask for VF %d\n",
 			cptvf->vfid);
 		return;
 	}
@@ -691,7 +691,7 @@ static ssize_t vf_engine_group_store(struct device *dev,
 		return -EINVAL;
 
 	if (val >= OTX_CPT_MAX_ENGINE_GROUPS) {
-		dev_err(dev, "Engine group >= than max available groups %d",
+		dev_err(dev, "Engine group >= than max available groups %d\n",
 			OTX_CPT_MAX_ENGINE_GROUPS);
 		return -EINVAL;
 	}
@@ -837,7 +837,7 @@ static int otx_cptvf_probe(struct pci_dev *pdev,
 			  cptvf_misc_intr_handler, 0, "CPT VF misc intr",
 			  cptvf);
 	if (err) {
-		dev_err(dev, "Failed to request misc irq");
+		dev_err(dev, "Failed to request misc irq\n");
 		goto free_vectors;
 	}
 
@@ -854,7 +854,7 @@ static int otx_cptvf_probe(struct pci_dev *pdev,
 	cptvf->cqinfo.qchunksize = OTX_CPT_CMD_QCHUNK_SIZE;
 	err = cptvf_sw_init(cptvf, OTX_CPT_CMD_QLEN, OTX_CPT_NUM_QS_PER_VF);
 	if (err) {
-		dev_err(dev, "cptvf_sw_init() failed");
+		dev_err(dev, "cptvf_sw_init() failed\n");
 		goto free_misc_irq;
 	}
 	/* Convey VQ LEN to PF */
@@ -946,7 +946,7 @@ static void otx_cptvf_remove(struct pci_dev *pdev)
 
 	/* Convey DOWN to PF */
 	if (otx_cptvf_send_vf_down(cptvf)) {
-		dev_err(&pdev->dev, "PF not responding to DOWN msg");
+		dev_err(&pdev->dev, "PF not responding to DOWN msg\n");
 	} else {
 		sysfs_remove_group(&pdev->dev.kobj, &otx_cptvf_sysfs_group);
 		otx_cpt_crypto_exit(pdev, THIS_MODULE, cptvf->vftype);
diff --git a/drivers/crypto/marvell/octeontx/otx_cptvf_reqmgr.c b/drivers/crypto/marvell/octeontx/otx_cptvf_reqmgr.c
index df839b880354..239195cccf93 100644
--- a/drivers/crypto/marvell/octeontx/otx_cptvf_reqmgr.c
+++ b/drivers/crypto/marvell/octeontx/otx_cptvf_reqmgr.c
@@ -314,7 +314,7 @@ static int process_request(struct pci_dev *pdev, struct otx_cpt_req_info *req,
 							      GFP_ATOMIC;
 	ret = setup_sgio_list(pdev, &info, req, gfp);
 	if (unlikely(ret)) {
-		dev_err(&pdev->dev, "Setting up SG list failed");
+		dev_err(&pdev->dev, "Setting up SG list failed\n");
 		goto request_cleanup;
 	}
 	cpt_req->dlen = info->dlen;
@@ -410,17 +410,17 @@ int otx_cpt_do_request(struct pci_dev *pdev, struct otx_cpt_req_info *req,
 	struct otx_cptvf *cptvf = pci_get_drvdata(pdev);
 
 	if (!otx_cpt_device_ready(cptvf)) {
-		dev_err(&pdev->dev, "CPT Device is not ready");
+		dev_err(&pdev->dev, "CPT Device is not ready\n");
 		return -ENODEV;
 	}
 
 	if ((cptvf->vftype == OTX_CPT_SE_TYPES) && (!req->ctrl.s.se_req)) {
-		dev_err(&pdev->dev, "CPTVF-%d of SE TYPE got AE request",
+		dev_err(&pdev->dev, "CPTVF-%d of SE TYPE got AE request\n",
 			cptvf->vfid);
 		return -EINVAL;
 	} else if ((cptvf->vftype == OTX_CPT_AE_TYPES) &&
 		   (req->ctrl.s.se_req)) {
-		dev_err(&pdev->dev, "CPTVF-%d of AE TYPE got SE request",
+		dev_err(&pdev->dev, "CPTVF-%d of AE TYPE got SE request\n",
 			cptvf->vfid);
 		return -EINVAL;
 	}
@@ -461,7 +461,7 @@ static int cpt_process_ccode(struct pci_dev *pdev,
 		/* check for timeout */
 		if (time_after_eq(jiffies, cpt_info->time_in +
 				  OTX_CPT_COMMAND_TIMEOUT * HZ))
-			dev_warn(&pdev->dev, "Request timed out 0x%p", req);
+			dev_warn(&pdev->dev, "Request timed out 0x%p\n", req);
 		else if (cpt_info->extra_time < OTX_CPT_TIME_IN_RESET_COUNT) {
 			cpt_info->time_in = jiffies;
 			cpt_info->extra_time++;
diff --git a/drivers/devfreq/tegra30-devfreq.c b/drivers/devfreq/tegra30-devfreq.c
index 28b2c7ca416e..e94a27804c20 100644
--- a/drivers/devfreq/tegra30-devfreq.c
+++ b/drivers/devfreq/tegra30-devfreq.c
@@ -420,7 +420,7 @@ tegra_actmon_cpufreq_contribution(struct tegra_devfreq *tegra,
 
 	static_cpu_emc_freq = actmon_cpu_to_emc_rate(tegra, cpu_freq);
 
-	if (dev_freq >= static_cpu_emc_freq)
+	if (dev_freq + actmon_dev->boost_freq >= static_cpu_emc_freq)
 		return 0;
 
 	return static_cpu_emc_freq;
@@ -807,10 +807,9 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
 	}
 
 	err = platform_get_irq(pdev, 0);
-	if (err < 0) {
-		dev_err(&pdev->dev, "Failed to get IRQ: %d\n", err);
+	if (err < 0)
 		return err;
-	}
+
 	tegra->irq = err;
 
 	irq_set_status_flags(tegra->irq, IRQ_NOAUTOEN);
diff --git a/drivers/dma-buf/Makefile b/drivers/dma-buf/Makefile
index 9c190026bfab..995e05f609ff 100644
--- a/drivers/dma-buf/Makefile
+++ b/drivers/dma-buf/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_UDMABUF)		+= udmabuf.o
 
 dmabuf_selftests-y := \
 	selftest.o \
-	st-dma-fence.o
+	st-dma-fence.o \
+	st-dma-fence-chain.o
 
 obj-$(CONFIG_DMABUF_SELFTESTS)	+= dmabuf_selftests.o
diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index ccc9eda1bc28..570c923023e6 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -690,6 +690,8 @@ dma_buf_dynamic_attach(struct dma_buf *dmabuf, struct device *dev,
 
 	attach->dev = dev;
 	attach->dmabuf = dmabuf;
+	if (importer_ops)
+		attach->peer2peer = importer_ops->allow_peer2peer;
 	attach->importer_ops = importer_ops;
 	attach->importer_priv = importer_priv;
 
diff --git a/drivers/dma-buf/dma-fence-chain.c b/drivers/dma-buf/dma-fence-chain.c
index 44a741677d25..c435bbba851c 100644
--- a/drivers/dma-buf/dma-fence-chain.c
+++ b/drivers/dma-buf/dma-fence-chain.c
@@ -62,7 +62,8 @@ struct dma_fence *dma_fence_chain_walk(struct dma_fence *fence)
 			replacement = NULL;
 		}
 
-		tmp = cmpxchg((void **)&chain->prev, (void *)prev, (void *)replacement);
+		tmp = cmpxchg((struct dma_fence __force **)&chain->prev,
+			      prev, replacement);
 		if (tmp == prev)
 			dma_fence_put(tmp);
 		else
@@ -98,6 +99,12 @@ int dma_fence_chain_find_seqno(struct dma_fence **pfence, uint64_t seqno)
 		return -EINVAL;
 
 	dma_fence_chain_for_each(*pfence, &chain->base) {
+		if ((*pfence)->seqno < seqno) { /* already signaled */
+			dma_fence_put(*pfence);
+			*pfence = NULL;
+			break;
+		}
+
 		if ((*pfence)->context != chain->base.context ||
 		    to_dma_fence_chain(*pfence)->prev_seqno < seqno)
 			break;
@@ -221,6 +228,7 @@ EXPORT_SYMBOL(dma_fence_chain_ops);
  * @chain: the chain node to initialize
  * @prev: the previous fence
  * @fence: the current fence
+ * @seqno: the sequence number (syncpt) of the fence within the chain
  *
  * Initialize a new chain node and either start a new chain or add the node to
  * the existing chain of the previous fence.
diff --git a/drivers/dma-buf/selftests.h b/drivers/dma-buf/selftests.h
index 5320386f02e5..55918ef9adab 100644
--- a/drivers/dma-buf/selftests.h
+++ b/drivers/dma-buf/selftests.h
@@ -11,3 +11,4 @@
  */
 selftest(sanitycheck, __sanitycheck__) /* keep first (igt selfcheck) */
 selftest(dma_fence, dma_fence)
+selftest(dma_fence_chain, dma_fence_chain)
diff --git a/drivers/dma-buf/st-dma-fence-chain.c b/drivers/dma-buf/st-dma-fence-chain.c
new file mode 100644
index 000000000000..5d45ba7ba3cd
--- /dev/null
+++ b/drivers/dma-buf/st-dma-fence-chain.c
@@ -0,0 +1,715 @@
+// SPDX-License-Identifier: MIT
+
+/*
+ * Copyright © 2019 Intel Corporation
+ */
+
+#include <linux/delay.h>
+#include <linux/dma-fence.h>
+#include <linux/dma-fence-chain.h>
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#include <linux/mm.h>
+#include <linux/sched/signal.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/random.h>
+
+#include "selftest.h"
+
+#define CHAIN_SZ (4 << 10)
+
+static struct kmem_cache *slab_fences;
+
+static inline struct mock_fence {
+	struct dma_fence base;
+	spinlock_t lock;
+} *to_mock_fence(struct dma_fence *f) {
+	return container_of(f, struct mock_fence, base);
+}
+
+static const char *mock_name(struct dma_fence *f)
+{
+	return "mock";
+}
+
+static void mock_fence_release(struct dma_fence *f)
+{
+	kmem_cache_free(slab_fences, to_mock_fence(f));
+}
+
+static const struct dma_fence_ops mock_ops = {
+	.get_driver_name = mock_name,
+	.get_timeline_name = mock_name,
+	.release = mock_fence_release,
+};
+
+static struct dma_fence *mock_fence(void)
+{
+	struct mock_fence *f;
+
+	f = kmem_cache_alloc(slab_fences, GFP_KERNEL);
+	if (!f)
+		return NULL;
+
+	spin_lock_init(&f->lock);
+	dma_fence_init(&f->base, &mock_ops, &f->lock, 0, 0);
+
+	return &f->base;
+}
+
+static inline struct mock_chain {
+	struct dma_fence_chain base;
+} *to_mock_chain(struct dma_fence *f) {
+	return container_of(f, struct mock_chain, base.base);
+}
+
+static struct dma_fence *mock_chain(struct dma_fence *prev,
+				    struct dma_fence *fence,
+				    u64 seqno)
+{
+	struct mock_chain *f;
+
+	f = kmalloc(sizeof(*f), GFP_KERNEL);
+	if (!f)
+		return NULL;
+
+	dma_fence_chain_init(&f->base,
+			     dma_fence_get(prev),
+			     dma_fence_get(fence),
+			     seqno);
+
+	return &f->base.base;
+}
+
+static int sanitycheck(void *arg)
+{
+	struct dma_fence *f, *chain;
+	int err = 0;
+
+	f = mock_fence();
+	if (!f)
+		return -ENOMEM;
+
+	chain = mock_chain(NULL, f, 1);
+	if (!chain)
+		err = -ENOMEM;
+
+	dma_fence_signal(f);
+	dma_fence_put(f);
+
+	dma_fence_put(chain);
+
+	return err;
+}
+
+struct fence_chains {
+	unsigned int chain_length;
+	struct dma_fence **fences;
+	struct dma_fence **chains;
+
+	struct dma_fence *tail;
+};
+
+static uint64_t seqno_inc(unsigned int i)
+{
+	return i + 1;
+}
+
+static int fence_chains_init(struct fence_chains *fc, unsigned int count,
+			     uint64_t (*seqno_fn)(unsigned int))
+{
+	unsigned int i;
+	int err = 0;
+
+	fc->chains = kvmalloc_array(count, sizeof(*fc->chains),
+				    GFP_KERNEL | __GFP_ZERO);
+	if (!fc->chains)
+		return -ENOMEM;
+
+	fc->fences = kvmalloc_array(count, sizeof(*fc->fences),
+				    GFP_KERNEL | __GFP_ZERO);
+	if (!fc->fences) {
+		err = -ENOMEM;
+		goto err_chains;
+	}
+
+	fc->tail = NULL;
+	for (i = 0; i < count; i++) {
+		fc->fences[i] = mock_fence();
+		if (!fc->fences[i]) {
+			err = -ENOMEM;
+			goto unwind;
+		}
+
+		fc->chains[i] = mock_chain(fc->tail,
+					   fc->fences[i],
+					   seqno_fn(i));
+		if (!fc->chains[i]) {
+			err = -ENOMEM;
+			goto unwind;
+		}
+
+		fc->tail = fc->chains[i];
+	}
+
+	fc->chain_length = i;
+	return 0;
+
+unwind:
+	for (i = 0; i < count; i++) {
+		dma_fence_put(fc->fences[i]);
+		dma_fence_put(fc->chains[i]);
+	}
+	kvfree(fc->fences);
+err_chains:
+	kvfree(fc->chains);
+	return err;
+}
+
+static void fence_chains_fini(struct fence_chains *fc)
+{
+	unsigned int i;
+
+	for (i = 0; i < fc->chain_length; i++) {
+		dma_fence_signal(fc->fences[i]);
+		dma_fence_put(fc->fences[i]);
+	}
+	kvfree(fc->fences);
+
+	for (i = 0; i < fc->chain_length; i++)
+		dma_fence_put(fc->chains[i]);
+	kvfree(fc->chains);
+}
+
+static int find_seqno(void *arg)
+{
+	struct fence_chains fc;
+	struct dma_fence *fence;
+	int err;
+	int i;
+
+	err = fence_chains_init(&fc, 64, seqno_inc);
+	if (err)
+		return err;
+
+	fence = dma_fence_get(fc.tail);
+	err = dma_fence_chain_find_seqno(&fence, 0);
+	dma_fence_put(fence);
+	if (err) {
+		pr_err("Reported %d for find_seqno(0)!\n", err);
+		goto err;
+	}
+
+	for (i = 0; i < fc.chain_length; i++) {
+		fence = dma_fence_get(fc.tail);
+		err = dma_fence_chain_find_seqno(&fence, i + 1);
+		dma_fence_put(fence);
+		if (err) {
+			pr_err("Reported %d for find_seqno(%d:%d)!\n",
+			       err, fc.chain_length + 1, i + 1);
+			goto err;
+		}
+		if (fence != fc.chains[i]) {
+			pr_err("Incorrect fence reported by find_seqno(%d:%d)\n",
+			       fc.chain_length + 1, i + 1);
+			err = -EINVAL;
+			goto err;
+		}
+
+		dma_fence_get(fence);
+		err = dma_fence_chain_find_seqno(&fence, i + 1);
+		dma_fence_put(fence);
+		if (err) {
+			pr_err("Error reported for finding self\n");
+			goto err;
+		}
+		if (fence != fc.chains[i]) {
+			pr_err("Incorrect fence reported by find self\n");
+			err = -EINVAL;
+			goto err;
+		}
+
+		dma_fence_get(fence);
+		err = dma_fence_chain_find_seqno(&fence, i + 2);
+		dma_fence_put(fence);
+		if (!err) {
+			pr_err("Error not reported for future fence: find_seqno(%d:%d)!\n",
+			       i + 1, i + 2);
+			err = -EINVAL;
+			goto err;
+		}
+
+		dma_fence_get(fence);
+		err = dma_fence_chain_find_seqno(&fence, i);
+		dma_fence_put(fence);
+		if (err) {
+			pr_err("Error reported for previous fence!\n");
+			goto err;
+		}
+		if (i > 0 && fence != fc.chains[i - 1]) {
+			pr_err("Incorrect fence reported by find_seqno(%d:%d)\n",
+			       i + 1, i);
+			err = -EINVAL;
+			goto err;
+		}
+	}
+
+err:
+	fence_chains_fini(&fc);
+	return err;
+}
+
+static int find_signaled(void *arg)
+{
+	struct fence_chains fc;
+	struct dma_fence *fence;
+	int err;
+
+	err = fence_chains_init(&fc, 2, seqno_inc);
+	if (err)
+		return err;
+
+	dma_fence_signal(fc.fences[0]);
+
+	fence = dma_fence_get(fc.tail);
+	err = dma_fence_chain_find_seqno(&fence, 1);
+	dma_fence_put(fence);
+	if (err) {
+		pr_err("Reported %d for find_seqno()!\n", err);
+		goto err;
+	}
+
+	if (fence && fence != fc.chains[0]) {
+		pr_err("Incorrect chain-fence.seqno:%lld reported for completed seqno:1\n",
+		       fence->seqno);
+
+		dma_fence_get(fence);
+		err = dma_fence_chain_find_seqno(&fence, 1);
+		dma_fence_put(fence);
+		if (err)
+			pr_err("Reported %d for finding self!\n", err);
+
+		err = -EINVAL;
+	}
+
+err:
+	fence_chains_fini(&fc);
+	return err;
+}
+
+static int find_out_of_order(void *arg)
+{
+	struct fence_chains fc;
+	struct dma_fence *fence;
+	int err;
+
+	err = fence_chains_init(&fc, 3, seqno_inc);
+	if (err)
+		return err;
+
+	dma_fence_signal(fc.fences[1]);
+
+	fence = dma_fence_get(fc.tail);
+	err = dma_fence_chain_find_seqno(&fence, 2);
+	dma_fence_put(fence);
+	if (err) {
+		pr_err("Reported %d for find_seqno()!\n", err);
+		goto err;
+	}
+
+	if (fence && fence != fc.chains[1]) {
+		pr_err("Incorrect chain-fence.seqno:%lld reported for completed seqno:2\n",
+		       fence->seqno);
+
+		dma_fence_get(fence);
+		err = dma_fence_chain_find_seqno(&fence, 2);
+		dma_fence_put(fence);
+		if (err)
+			pr_err("Reported %d for finding self!\n", err);
+
+		err = -EINVAL;
+	}
+
+err:
+	fence_chains_fini(&fc);
+	return err;
+}
+
+static uint64_t seqno_inc2(unsigned int i)
+{
+	return 2 * i + 2;
+}
+
+static int find_gap(void *arg)
+{
+	struct fence_chains fc;
+	struct dma_fence *fence;
+	int err;
+	int i;
+
+	err = fence_chains_init(&fc, 64, seqno_inc2);
+	if (err)
+		return err;
+
+	for (i = 0; i < fc.chain_length; i++) {
+		fence = dma_fence_get(fc.tail);
+		err = dma_fence_chain_find_seqno(&fence, 2 * i + 1);
+		dma_fence_put(fence);
+		if (err) {
+			pr_err("Reported %d for find_seqno(%d:%d)!\n",
+			       err, fc.chain_length + 1, 2 * i + 1);
+			goto err;
+		}
+		if (fence != fc.chains[i]) {
+			pr_err("Incorrect fence.seqno:%lld reported by find_seqno(%d:%d)\n",
+			       fence->seqno,
+			       fc.chain_length + 1,
+			       2 * i + 1);
+			err = -EINVAL;
+			goto err;
+		}
+
+		dma_fence_get(fence);
+		err = dma_fence_chain_find_seqno(&fence, 2 * i + 2);
+		dma_fence_put(fence);
+		if (err) {
+			pr_err("Error reported for finding self\n");
+			goto err;
+		}
+		if (fence != fc.chains[i]) {
+			pr_err("Incorrect fence reported by find self\n");
+			err = -EINVAL;
+			goto err;
+		}
+	}
+
+err:
+	fence_chains_fini(&fc);
+	return err;
+}
+
+struct find_race {
+	struct fence_chains fc;
+	atomic_t children;
+};
+
+static int __find_race(void *arg)
+{
+	struct find_race *data = arg;
+	int err = 0;
+
+	while (!kthread_should_stop()) {
+		struct dma_fence *fence = dma_fence_get(data->fc.tail);
+		int seqno;
+
+		seqno = prandom_u32_max(data->fc.chain_length) + 1;
+
+		err = dma_fence_chain_find_seqno(&fence, seqno);
+		if (err) {
+			pr_err("Failed to find fence seqno:%d\n",
+			       seqno);
+			dma_fence_put(fence);
+			break;
+		}
+		if (!fence)
+			goto signal;
+
+		err = dma_fence_chain_find_seqno(&fence, seqno);
+		if (err) {
+			pr_err("Reported an invalid fence for find-self:%d\n",
+			       seqno);
+			dma_fence_put(fence);
+			break;
+		}
+
+		if (fence->seqno < seqno) {
+			pr_err("Reported an earlier fence.seqno:%lld for seqno:%d\n",
+			       fence->seqno, seqno);
+			err = -EINVAL;
+			dma_fence_put(fence);
+			break;
+		}
+
+		dma_fence_put(fence);
+
+signal:
+		seqno = prandom_u32_max(data->fc.chain_length - 1);
+		dma_fence_signal(data->fc.fences[seqno]);
+		cond_resched();
+	}
+
+	if (atomic_dec_and_test(&data->children))
+		wake_up_var(&data->children);
+	return err;
+}
+
+static int find_race(void *arg)
+{
+	struct find_race data;
+	int ncpus = num_online_cpus();
+	struct task_struct **threads;
+	unsigned long count;
+	int err;
+	int i;
+
+	err = fence_chains_init(&data.fc, CHAIN_SZ, seqno_inc);
+	if (err)
+		return err;
+
+	threads = kmalloc_array(ncpus, sizeof(*threads), GFP_KERNEL);
+	if (!threads) {
+		err = -ENOMEM;
+		goto err;
+	}
+
+	atomic_set(&data.children, 0);
+	for (i = 0; i < ncpus; i++) {
+		threads[i] = kthread_run(__find_race, &data, "dmabuf/%d", i);
+		if (IS_ERR(threads[i])) {
+			ncpus = i;
+			break;
+		}
+		atomic_inc(&data.children);
+		get_task_struct(threads[i]);
+	}
+
+	wait_var_event_timeout(&data.children,
+			       !atomic_read(&data.children),
+			       5 * HZ);
+
+	for (i = 0; i < ncpus; i++) {
+		int ret;
+
+		ret = kthread_stop(threads[i]);
+		if (ret && !err)
+			err = ret;
+		put_task_struct(threads[i]);
+	}
+	kfree(threads);
+
+	count = 0;
+	for (i = 0; i < data.fc.chain_length; i++)
+		if (dma_fence_is_signaled(data.fc.fences[i]))
+			count++;
+	pr_info("Completed %lu cycles\n", count);
+
+err:
+	fence_chains_fini(&data.fc);
+	return err;
+}
+
+static int signal_forward(void *arg)
+{
+	struct fence_chains fc;
+	int err;
+	int i;
+
+	err = fence_chains_init(&fc, 64, seqno_inc);
+	if (err)
+		return err;
+
+	for (i = 0; i < fc.chain_length; i++) {
+		dma_fence_signal(fc.fences[i]);
+
+		if (!dma_fence_is_signaled(fc.chains[i])) {
+			pr_err("chain[%d] not signaled!\n", i);
+			err = -EINVAL;
+			goto err;
+		}
+
+		if (i + 1 < fc.chain_length &&
+		    dma_fence_is_signaled(fc.chains[i + 1])) {
+			pr_err("chain[%d] is signaled!\n", i);
+			err = -EINVAL;
+			goto err;
+		}
+	}
+
+err:
+	fence_chains_fini(&fc);
+	return err;
+}
+
+static int signal_backward(void *arg)
+{
+	struct fence_chains fc;
+	int err;
+	int i;
+
+	err = fence_chains_init(&fc, 64, seqno_inc);
+	if (err)
+		return err;
+
+	for (i = fc.chain_length; i--; ) {
+		dma_fence_signal(fc.fences[i]);
+
+		if (i > 0 && dma_fence_is_signaled(fc.chains[i])) {
+			pr_err("chain[%d] is signaled!\n", i);
+			err = -EINVAL;
+			goto err;
+		}
+	}
+
+	for (i = 0; i < fc.chain_length; i++) {
+		if (!dma_fence_is_signaled(fc.chains[i])) {
+			pr_err("chain[%d] was not signaled!\n", i);
+			err = -EINVAL;
+			goto err;
+		}
+	}
+
+err:
+	fence_chains_fini(&fc);
+	return err;
+}
+
+static int __wait_fence_chains(void *arg)
+{
+	struct fence_chains *fc = arg;
+
+	if (dma_fence_wait(fc->tail, false))
+		return -EIO;
+
+	return 0;
+}
+
+static int wait_forward(void *arg)
+{
+	struct fence_chains fc;
+	struct task_struct *tsk;
+	int err;
+	int i;
+
+	err = fence_chains_init(&fc, CHAIN_SZ, seqno_inc);
+	if (err)
+		return err;
+
+	tsk = kthread_run(__wait_fence_chains, &fc, "dmabuf/wait");
+	if (IS_ERR(tsk)) {
+		err = PTR_ERR(tsk);
+		goto err;
+	}
+	get_task_struct(tsk);
+	yield_to(tsk, true);
+
+	for (i = 0; i < fc.chain_length; i++)
+		dma_fence_signal(fc.fences[i]);
+
+	err = kthread_stop(tsk);
+	put_task_struct(tsk);
+
+err:
+	fence_chains_fini(&fc);
+	return err;
+}
+
+static int wait_backward(void *arg)
+{
+	struct fence_chains fc;
+	struct task_struct *tsk;
+	int err;
+	int i;
+
+	err = fence_chains_init(&fc, CHAIN_SZ, seqno_inc);
+	if (err)
+		return err;
+
+	tsk = kthread_run(__wait_fence_chains, &fc, "dmabuf/wait");
+	if (IS_ERR(tsk)) {
+		err = PTR_ERR(tsk);
+		goto err;
+	}
+	get_task_struct(tsk);
+	yield_to(tsk, true);
+
+	for (i = fc.chain_length; i--; )
+		dma_fence_signal(fc.fences[i]);
+
+	err = kthread_stop(tsk);
+	put_task_struct(tsk);
+
+err:
+	fence_chains_fini(&fc);
+	return err;
+}
+
+static void randomise_fences(struct fence_chains *fc)
+{
+	unsigned int count = fc->chain_length;
+
+	/* Fisher-Yates shuffle courtesy of Knuth */
+	while (--count) {
+		unsigned int swp;
+
+		swp = prandom_u32_max(count + 1);
+		if (swp == count)
+			continue;
+
+		swap(fc->fences[count], fc->fences[swp]);
+	}
+}
+
+static int wait_random(void *arg)
+{
+	struct fence_chains fc;
+	struct task_struct *tsk;
+	int err;
+	int i;
+
+	err = fence_chains_init(&fc, CHAIN_SZ, seqno_inc);
+	if (err)
+		return err;
+
+	randomise_fences(&fc);
+
+	tsk = kthread_run(__wait_fence_chains, &fc, "dmabuf/wait");
+	if (IS_ERR(tsk)) {
+		err = PTR_ERR(tsk);
+		goto err;
+	}
+	get_task_struct(tsk);
+	yield_to(tsk, true);
+
+	for (i = 0; i < fc.chain_length; i++)
+		dma_fence_signal(fc.fences[i]);
+
+	err = kthread_stop(tsk);
+	put_task_struct(tsk);
+
+err:
+	fence_chains_fini(&fc);
+	return err;
+}
+
+int dma_fence_chain(void)
+{
+	static const struct subtest tests[] = {
+		SUBTEST(sanitycheck),
+		SUBTEST(find_seqno),
+		SUBTEST(find_signaled),
+		SUBTEST(find_out_of_order),
+		SUBTEST(find_gap),
+		SUBTEST(find_race),
+		SUBTEST(signal_forward),
+		SUBTEST(signal_backward),
+		SUBTEST(wait_forward),
+		SUBTEST(wait_backward),
+		SUBTEST(wait_random),
+	};
+	int ret;
+
+	pr_info("sizeof(dma_fence_chain)=%zu\n",
+		sizeof(struct dma_fence_chain));
+
+	slab_fences = KMEM_CACHE(mock_fence,
+				 SLAB_TYPESAFE_BY_RCU |
+				 SLAB_HWCACHE_ALIGN);
+	if (!slab_fences)
+		return -ENOMEM;
+
+	ret = subtests(tests, NULL);
+
+	kmem_cache_destroy(slab_fences);
+	return ret;
+}
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 092483644315..023db6883d05 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -241,7 +241,8 @@ config FSL_RAID
 
 config HISI_DMA
 	tristate "HiSilicon DMA Engine support"
-	depends on ARM64 || (COMPILE_TEST && PCI_MSI)
+	depends on ARM64 || COMPILE_TEST
+	depends on PCI_MSI
 	select DMA_ENGINE
 	select DMA_VIRTUAL_CHANNELS
 	help
diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c
index 3999827970ab..052dae5d6ddd 100644
--- a/drivers/dma/idxd/sysfs.c
+++ b/drivers/dma/idxd/sysfs.c
@@ -1092,6 +1092,16 @@ static const struct attribute_group *idxd_wq_attribute_groups[] = {
 };
 
 /* IDXD device attribs */
+static ssize_t version_show(struct device *dev, struct device_attribute *attr,
+			    char *buf)
+{
+	struct idxd_device *idxd =
+		container_of(dev, struct idxd_device, conf_dev);
+
+	return sprintf(buf, "%#x\n", idxd->hw.version);
+}
+static DEVICE_ATTR_RO(version);
+
 static ssize_t max_work_queues_size_show(struct device *dev,
 					 struct device_attribute *attr,
 					 char *buf)
@@ -1313,6 +1323,7 @@ static ssize_t cdev_major_show(struct device *dev,
 static DEVICE_ATTR_RO(cdev_major);
 
 static struct attribute *idxd_device_attributes[] = {
+	&dev_attr_version.attr,
 	&dev_attr_max_groups.attr,
 	&dev_attr_max_work_queues.attr,
 	&dev_attr_max_work_queues_size.attr,
diff --git a/drivers/dma/ti/Kconfig b/drivers/dma/ti/Kconfig
index f76e06651f80..79618fac119a 100644
--- a/drivers/dma/ti/Kconfig
+++ b/drivers/dma/ti/Kconfig
@@ -36,7 +36,7 @@ config DMA_OMAP
 
 config TI_K3_UDMA
 	bool "Texas Instruments UDMA support"
-	depends on ARCH_K3 || COMPILE_TEST
+	depends on ARCH_K3
 	depends on TI_SCI_PROTOCOL
 	depends on TI_SCI_INTA_IRQCHIP
 	select DMA_ENGINE
@@ -49,7 +49,7 @@ config TI_K3_UDMA
 
 config TI_K3_UDMA_GLUE_LAYER
 	bool "Texas Instruments UDMA Glue layer for non DMAengine users"
-	depends on ARCH_K3 || COMPILE_TEST
+	depends on ARCH_K3
 	depends on TI_K3_UDMA
 	help
 	  Say y here to support the K3 NAVSS DMA glue interface
diff --git a/drivers/dma/ti/k3-psil.c b/drivers/dma/ti/k3-psil.c
index d7b965049ccb..fb7c8150b0d1 100644
--- a/drivers/dma/ti/k3-psil.c
+++ b/drivers/dma/ti/k3-psil.c
@@ -27,6 +27,7 @@ struct psil_endpoint_config *psil_get_ep_config(u32 thread_id)
 			soc_ep_map = &j721e_ep_map;
 		} else {
 			pr_err("PSIL: No compatible machine found for map\n");
+			mutex_unlock(&ep_map_mutex);
 			return ERR_PTR(-ENOTSUPP);
 		}
 		pr_debug("%s: Using map for %s\n", __func__, soc_ep_map->name);
diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c
index a9c0251adf1a..fa53234d8f09 100644
--- a/drivers/dma/ti/k3-udma.c
+++ b/drivers/dma/ti/k3-udma.c
@@ -3187,7 +3187,7 @@ static struct udma_match_data am654_main_data = {
 
 static struct udma_match_data am654_mcu_data = {
 	.psil_base = 0x6000,
-	.enable_memcpy_support = true, /* TEST: DMA domains */
+	.enable_memcpy_support = false,
 	.statictr_z_mask = GENMASK(11, 0),
 	.rchan_oes_offset = 0x2000,
 	.tpl_levels = 2,
diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
index aecd5a35a296..5429497d3560 100644
--- a/drivers/dma/xilinx/xilinx_dma.c
+++ b/drivers/dma/xilinx/xilinx_dma.c
@@ -1230,16 +1230,16 @@ static enum dma_status xilinx_dma_tx_status(struct dma_chan *dchan,
 		return ret;
 
 	spin_lock_irqsave(&chan->lock, flags);
-
-	desc = list_last_entry(&chan->active_list,
-			       struct xilinx_dma_tx_descriptor, node);
-	/*
-	 * VDMA and simple mode do not support residue reporting, so the
-	 * residue field will always be 0.
-	 */
-	if (chan->has_sg && chan->xdev->dma_config->dmatype != XDMA_TYPE_VDMA)
-		residue = xilinx_dma_get_residue(chan, desc);
-
+	if (!list_empty(&chan->active_list)) {
+		desc = list_last_entry(&chan->active_list,
+				       struct xilinx_dma_tx_descriptor, node);
+		/*
+		 * VDMA and simple mode do not support residue reporting, so the
+		 * residue field will always be 0.
+		 */
+		if (chan->has_sg && chan->xdev->dma_config->dmatype != XDMA_TYPE_VDMA)
+			residue = xilinx_dma_get_residue(chan, desc);
+	}
 	spin_unlock_irqrestore(&chan->lock, flags);
 
 	dma_set_residue(txstate, residue);
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index f91f3bc1e0b2..6bdc5bb8c8bc 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -4,9 +4,6 @@
 
 static struct edac_pci_ctl_info *pci_ctl;
 
-static int report_gart_errors;
-module_param(report_gart_errors, int, 0644);
-
 /*
  * Set by command line parameter. If BIOS has enabled the ECC, this override is
  * cleared to prevent re-enabling the hardware by this driver.
@@ -3681,9 +3678,6 @@ static int __init amd64_edac_init(void)
 	}
 
 	/* register stuff with EDAC MCE */
-	if (report_gart_errors)
-		amd_report_gart_errors(true);
-
 	if (boot_cpu_data.x86 >= 0x17)
 		amd_register_ecc_decoder(decode_umc_error);
 	else
@@ -3718,8 +3712,6 @@ static void __exit amd64_edac_exit(void)
 		edac_pci_release_generic_ctl(pci_ctl);
 
 	/* unregister from EDAC MCE */
-	amd_report_gart_errors(false);
-
 	if (boot_cpu_data.x86 >= 0x17)
 		amd_unregister_ecc_decoder(decode_umc_error);
 	else
diff --git a/drivers/edac/armada_xp_edac.c b/drivers/edac/armada_xp_edac.c
index a7502ebe9bdc..e3e757513d1b 100644
--- a/drivers/edac/armada_xp_edac.c
+++ b/drivers/edac/armada_xp_edac.c
@@ -78,7 +78,7 @@ struct axp_mc_drvdata {
 	char msg[128];
 };
 
-/* derived from "DRAM Address Multiplexing" in the ARAMDA XP Functional Spec */
+/* derived from "DRAM Address Multiplexing" in the ARMADA XP Functional Spec */
 static uint32_t axp_mc_calc_address(struct axp_mc_drvdata *drvdata,
 				    uint8_t cs, uint8_t bank, uint16_t row,
 				    uint16_t col)
@@ -160,12 +160,12 @@ static void axp_mc_check(struct mem_ctl_info *mci)
 		if (cnt_sbe)
 			cnt_sbe--;
 		else
-			dev_warn(mci->pdev, "inconsistent SBE count detected");
+			dev_warn(mci->pdev, "inconsistent SBE count detected\n");
 	} else {
 		if (cnt_dbe)
 			cnt_dbe--;
 		else
-			dev_warn(mci->pdev, "inconsistent DBE count detected");
+			dev_warn(mci->pdev, "inconsistent DBE count detected\n");
 	}
 
 	/* report earlier errors */
@@ -304,7 +304,7 @@ static int axp_mc_probe(struct platform_device *pdev)
 
 	config = readl(base + SDRAM_CONFIG_REG);
 	if (!(config & SDRAM_CONFIG_ECC_MASK)) {
-		dev_warn(&pdev->dev, "SDRAM ECC is not enabled");
+		dev_warn(&pdev->dev, "SDRAM ECC is not enabled\n");
 		return -EINVAL;
 	}
 
@@ -532,9 +532,9 @@ static int aurora_l2_probe(struct platform_device *pdev)
 
 	l2x0_aux_ctrl = readl(base + L2X0_AUX_CTRL);
 	if (!(l2x0_aux_ctrl & AURORA_ACR_PARITY_EN))
-		dev_warn(&pdev->dev, "tag parity is not enabled");
+		dev_warn(&pdev->dev, "tag parity is not enabled\n");
 	if (!(l2x0_aux_ctrl & AURORA_ACR_ECC_EN))
-		dev_warn(&pdev->dev, "data ECC is not enabled");
+		dev_warn(&pdev->dev, "data ECC is not enabled\n");
 
 	dci = edac_device_alloc_ctl_info(sizeof(*drvdata),
 					 "cpu", 1, "L", 1, 2, NULL, 0, 0);
@@ -618,7 +618,7 @@ static int __init armada_xp_edac_init(void)
 
 	res = platform_register_drivers(drivers, ARRAY_SIZE(drivers));
 	if (res)
-		pr_warn("Aramda XP EDAC drivers fail to register\n");
+		pr_warn("Armada XP EDAC drivers fail to register\n");
 
 	return 0;
 }
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
index 75ede27bdf6a..5813e931f2f0 100644
--- a/drivers/edac/edac_mc.c
+++ b/drivers/edac/edac_mc.c
@@ -43,8 +43,6 @@
 int edac_op_state = EDAC_OPSTATE_INVAL;
 EXPORT_SYMBOL_GPL(edac_op_state);
 
-static int edac_report = EDAC_REPORTING_ENABLED;
-
 /* lock to memory controller's control array */
 static DEFINE_MUTEX(mem_ctls_mutex);
 static LIST_HEAD(mc_devices);
@@ -60,65 +58,6 @@ static struct mem_ctl_info *error_desc_to_mci(struct edac_raw_error_desc *e)
 	return container_of(e, struct mem_ctl_info, error_desc);
 }
 
-int edac_get_report_status(void)
-{
-	return edac_report;
-}
-EXPORT_SYMBOL_GPL(edac_get_report_status);
-
-void edac_set_report_status(int new)
-{
-	if (new == EDAC_REPORTING_ENABLED ||
-	    new == EDAC_REPORTING_DISABLED ||
-	    new == EDAC_REPORTING_FORCE)
-		edac_report = new;
-}
-EXPORT_SYMBOL_GPL(edac_set_report_status);
-
-static int edac_report_set(const char *str, const struct kernel_param *kp)
-{
-	if (!str)
-		return -EINVAL;
-
-	if (!strncmp(str, "on", 2))
-		edac_report = EDAC_REPORTING_ENABLED;
-	else if (!strncmp(str, "off", 3))
-		edac_report = EDAC_REPORTING_DISABLED;
-	else if (!strncmp(str, "force", 5))
-		edac_report = EDAC_REPORTING_FORCE;
-
-	return 0;
-}
-
-static int edac_report_get(char *buffer, const struct kernel_param *kp)
-{
-	int ret = 0;
-
-	switch (edac_report) {
-	case EDAC_REPORTING_ENABLED:
-		ret = sprintf(buffer, "on");
-		break;
-	case EDAC_REPORTING_DISABLED:
-		ret = sprintf(buffer, "off");
-		break;
-	case EDAC_REPORTING_FORCE:
-		ret = sprintf(buffer, "force");
-		break;
-	default:
-		ret = -EINVAL;
-		break;
-	}
-
-	return ret;
-}
-
-static const struct kernel_param_ops edac_report_ops = {
-	.set = edac_report_set,
-	.get = edac_report_get,
-};
-
-module_param_cb(edac_report, &edac_report_ops, &edac_report, 0644);
-
 unsigned int edac_dimm_info_location(struct dimm_info *dimm, char *buf,
 				     unsigned int len)
 {
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c
index b3135b208f9a..5860ca41185c 100644
--- a/drivers/edac/i7core_edac.c
+++ b/drivers/edac/i7core_edac.c
@@ -1815,7 +1815,7 @@ static int i7core_mce_check_error(struct notifier_block *nb, unsigned long val,
 	struct mem_ctl_info *mci;
 
 	i7_dev = get_i7core_dev(mce->socketid);
-	if (!i7_dev)
+	if (!i7_dev || (mce->kflags & MCE_HANDLED_CEC))
 		return NOTIFY_DONE;
 
 	mci = i7_dev->mci;
@@ -1834,7 +1834,8 @@ static int i7core_mce_check_error(struct notifier_block *nb, unsigned long val,
 	i7core_check_error(mci, mce);
 
 	/* Advise mcelog that the errors were handled */
-	return NOTIFY_STOP;
+	mce->kflags |= MCE_HANDLED_EDAC;
+	return NOTIFY_OK;
 }
 
 static struct notifier_block i7_mce_dec = {
diff --git a/drivers/edac/mce_amd.c b/drivers/edac/mce_amd.c
index 8874b7722b2f..2b5401db56ad 100644
--- a/drivers/edac/mce_amd.c
+++ b/drivers/edac/mce_amd.c
@@ -10,15 +10,8 @@ static struct amd_decoder_ops fam_ops;
 
 static u8 xec_mask	 = 0xf;
 
-static bool report_gart_errors;
 static void (*decode_dram_ecc)(int node_id, struct mce *m);
 
-void amd_report_gart_errors(bool v)
-{
-	report_gart_errors = v;
-}
-EXPORT_SYMBOL_GPL(amd_report_gart_errors);
-
 void amd_register_ecc_decoder(void (*f)(int, struct mce *))
 {
 	decode_dram_ecc = f;
@@ -1030,20 +1023,6 @@ static inline void amd_decode_err_code(u16 ec)
 	pr_cont("\n");
 }
 
-/*
- * Filter out unwanted MCE signatures here.
- */
-static bool ignore_mce(struct mce *m)
-{
-	/*
-	 * NB GART TLB error reporting is disabled by default.
-	 */
-	if (m->bank == 4 && XEC(m->status, 0x1f) == 0x5 && !report_gart_errors)
-		return true;
-
-	return false;
-}
-
 static const char *decode_error_status(struct mce *m)
 {
 	if (m->status & MCI_STATUS_UC) {
@@ -1067,8 +1046,8 @@ amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)
 	unsigned int fam = x86_family(m->cpuid);
 	int ecc;
 
-	if (ignore_mce(m))
-		return NOTIFY_STOP;
+	if (m->kflags & MCE_HANDLED_CEC)
+		return NOTIFY_DONE;
 
 	pr_emerg(HW_ERR "%s\n", decode_error_status(m));
 
@@ -1170,7 +1149,8 @@ amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)
  err_code:
 	amd_decode_err_code(m->status & 0xffff);
 
-	return NOTIFY_STOP;
+	m->kflags |= MCE_HANDLED_EDAC;
+	return NOTIFY_OK;
 }
 
 static struct notifier_block amd_mce_dec_nb = {
diff --git a/drivers/edac/mce_amd.h b/drivers/edac/mce_amd.h
index 4e9c5e596c6c..4811b18d9606 100644
--- a/drivers/edac/mce_amd.h
+++ b/drivers/edac/mce_amd.h
@@ -7,7 +7,6 @@
 #include <asm/mce.h>
 
 #define EC(x)				((x) & 0xffff)
-#define XEC(x, mask)			(((x) >> 16) & mask)
 
 #define LOW_SYNDROME(x)			(((x) >> 15) & 0xff)
 #define HIGH_SYNDROME(x)		(((x) >> 24) & 0xff)
@@ -77,7 +76,6 @@ struct amd_decoder_ops {
 	bool (*mc2_mce)(u16, u8);
 };
 
-void amd_report_gart_errors(bool);
 void amd_register_ecc_decoder(void (*f)(int, struct mce *));
 void amd_unregister_ecc_decoder(void (*f)(int, struct mce *));
 
diff --git a/drivers/edac/pnd2_edac.c b/drivers/edac/pnd2_edac.c
index bc47328eb485..c1f2e6deb021 100644
--- a/drivers/edac/pnd2_edac.c
+++ b/drivers/edac/pnd2_edac.c
@@ -1396,11 +1396,8 @@ static int pnd2_mce_check_error(struct notifier_block *nb, unsigned long val, vo
 	struct dram_addr daddr;
 	char *type;
 
-	if (edac_get_report_status() == EDAC_REPORTING_DISABLED)
-		return NOTIFY_DONE;
-
 	mci = pnd2_mci;
-	if (!mci)
+	if (!mci || (mce->kflags & MCE_HANDLED_CEC))
 		return NOTIFY_DONE;
 
 	/*
@@ -1429,7 +1426,8 @@ static int pnd2_mce_check_error(struct notifier_block *nb, unsigned long val, vo
 	pnd2_mce_output_error(mci, mce, &daddr);
 
 	/* Advice mcelog that the error were handled */
-	return NOTIFY_STOP;
+	mce->kflags |= MCE_HANDLED_EDAC;
+	return NOTIFY_OK;
 }
 
 static struct notifier_block pnd2_mce_dec = {
diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c
index 7d51c82be62b..d414698ca324 100644
--- a/drivers/edac/sb_edac.c
+++ b/drivers/edac/sb_edac.c
@@ -3134,7 +3134,7 @@ static int sbridge_mce_check_error(struct notifier_block *nb, unsigned long val,
 	struct mem_ctl_info *mci;
 	char *type;
 
-	if (edac_get_report_status() == EDAC_REPORTING_DISABLED)
+	if (mce->kflags & MCE_HANDLED_CEC)
 		return NOTIFY_DONE;
 
 	/*
@@ -3183,7 +3183,8 @@ static int sbridge_mce_check_error(struct notifier_block *nb, unsigned long val,
 	sbridge_mce_output_error(mci, mce);
 
 	/* Advice mcelog that the error were handled */
-	return NOTIFY_STOP;
+	mce->kflags |= MCE_HANDLED_EDAC;
+	return NOTIFY_OK;
 }
 
 static struct notifier_block sbridge_mce_dec = {
@@ -3523,8 +3524,6 @@ static int __init sbridge_init(void)
 
 	if (rc >= 0) {
 		mce_register_decode_chain(&sbridge_mce_dec);
-		if (edac_get_report_status() == EDAC_REPORTING_DISABLED)
-			sbridge_printk(KERN_WARNING, "Loading driver, error reporting disabled.\n");
 		return 0;
 	}
 
diff --git a/drivers/edac/skx_common.c b/drivers/edac/skx_common.c
index 99bbaf629b8d..423d33aef54f 100644
--- a/drivers/edac/skx_common.c
+++ b/drivers/edac/skx_common.c
@@ -574,7 +574,7 @@ int skx_mce_check_error(struct notifier_block *nb, unsigned long val,
 	struct mem_ctl_info *mci;
 	char *type;
 
-	if (edac_get_report_status() == EDAC_REPORTING_DISABLED)
+	if (mce->kflags & MCE_HANDLED_CEC)
 		return NOTIFY_DONE;
 
 	/* ignore unless this is memory related with an address */
@@ -616,6 +616,7 @@ int skx_mce_check_error(struct notifier_block *nb, unsigned long val,
 
 	skx_mce_output_error(mci, mce, &res);
 
+	mce->kflags |= MCE_HANDLED_EDAC;
 	return NOTIFY_DONE;
 }
 
diff --git a/drivers/edac/xgene_edac.c b/drivers/edac/xgene_edac.c
index e4a1032ba0b5..1d2c27a00a4a 100644
--- a/drivers/edac/xgene_edac.c
+++ b/drivers/edac/xgene_edac.c
@@ -1349,7 +1349,6 @@ static int xgene_edac_l3_remove(struct xgene_edac_dev_ctx *l3)
 #define WORD_ALIGNED_ERR_MASK		BIT(28)
 #define PAGE_ACCESS_ERR_MASK		BIT(27)
 #define WRITE_ACCESS_MASK		BIT(26)
-#define RBERRADDR_RD(src)		((src) & 0x03FFFFFF)
 
 static const char * const soc_mem_err_v1[] = {
 	"10GbE0",
@@ -1483,13 +1482,11 @@ static void xgene_edac_rb_report(struct edac_device_ctl_info *edac_dev)
 		return;
 	if (reg & STICKYERR_MASK) {
 		bool write;
-		u32 address;
 
 		dev_err(edac_dev->dev, "IOB bus access error(s)\n");
 		if (regmap_read(ctx->edac->rb_map, RBEIR, &reg))
 			return;
 		write = reg & WRITE_ACCESS_MASK ? 1 : 0;
-		address = RBERRADDR_RD(reg);
 		if (reg & AGENT_OFFLINE_ERR_MASK)
 			dev_err(edac_dev->dev,
 				"IOB bus %s access to offline agent error\n",
diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c
index 715e491dfbc3..28785642a5c5 100644
--- a/drivers/firewire/net.c
+++ b/drivers/firewire/net.c
@@ -490,7 +490,6 @@ static int fwnet_finish_incoming_packet(struct net_device *net,
 {
 	struct fwnet_device *dev;
 	int status;
-	__be64 guid;
 
 	switch (ether_type) {
 	case ETH_P_ARP:
@@ -512,7 +511,6 @@ static int fwnet_finish_incoming_packet(struct net_device *net,
 	 * Parse the encapsulation header. This actually does the job of
 	 * converting to an ethernet-like pseudo frame header.
 	 */
-	guid = cpu_to_be64(dev->card->guid);
 	if (dev_hard_header(skb, net, ether_type,
 			   is_broadcast ? net->broadcast : net->dev_addr,
 			   NULL, skb->len) >= 0) {
diff --git a/drivers/firmware/dmi-id.c b/drivers/firmware/dmi-id.c
index ff39f64f2aae..86d71b0212b1 100644
--- a/drivers/firmware/dmi-id.c
+++ b/drivers/firmware/dmi-id.c
@@ -42,6 +42,8 @@ DEFINE_DMI_ATTR_WITH_SHOW(bios_vendor,		0444, DMI_BIOS_VENDOR);
 DEFINE_DMI_ATTR_WITH_SHOW(bios_version,		0444, DMI_BIOS_VERSION);
 DEFINE_DMI_ATTR_WITH_SHOW(bios_date,		0444, DMI_BIOS_DATE);
 DEFINE_DMI_ATTR_WITH_SHOW(sys_vendor,		0444, DMI_SYS_VENDOR);
+DEFINE_DMI_ATTR_WITH_SHOW(bios_release,		0444, DMI_BIOS_RELEASE);
+DEFINE_DMI_ATTR_WITH_SHOW(ec_firmware_release,	0444, DMI_EC_FIRMWARE_RELEASE);
 DEFINE_DMI_ATTR_WITH_SHOW(product_name,		0444, DMI_PRODUCT_NAME);
 DEFINE_DMI_ATTR_WITH_SHOW(product_version,	0444, DMI_PRODUCT_VERSION);
 DEFINE_DMI_ATTR_WITH_SHOW(product_serial,	0400, DMI_PRODUCT_SERIAL);
@@ -78,6 +80,8 @@ static ssize_t get_modalias(char *buffer, size_t buffer_size)
 		{ "bvn", DMI_BIOS_VENDOR },
 		{ "bvr", DMI_BIOS_VERSION },
 		{ "bd",  DMI_BIOS_DATE },
+		{ "br",  DMI_BIOS_RELEASE },
+		{ "efr", DMI_EC_FIRMWARE_RELEASE },
 		{ "svn", DMI_SYS_VENDOR },
 		{ "pn",  DMI_PRODUCT_NAME },
 		{ "pvr", DMI_PRODUCT_VERSION },
@@ -187,6 +191,8 @@ static void __init dmi_id_init_attr_table(void)
 	ADD_DMI_ATTR(bios_vendor,       DMI_BIOS_VENDOR);
 	ADD_DMI_ATTR(bios_version,      DMI_BIOS_VERSION);
 	ADD_DMI_ATTR(bios_date,         DMI_BIOS_DATE);
+	ADD_DMI_ATTR(bios_release,      DMI_BIOS_RELEASE);
+	ADD_DMI_ATTR(ec_firmware_release, DMI_EC_FIRMWARE_RELEASE);
 	ADD_DMI_ATTR(sys_vendor,        DMI_SYS_VENDOR);
 	ADD_DMI_ATTR(product_name,      DMI_PRODUCT_NAME);
 	ADD_DMI_ATTR(product_version,   DMI_PRODUCT_VERSION);
diff --git a/drivers/firmware/dmi-sysfs.c b/drivers/firmware/dmi-sysfs.c
index b6180023eba7..8b8127fa8955 100644
--- a/drivers/firmware/dmi-sysfs.c
+++ b/drivers/firmware/dmi-sysfs.c
@@ -262,7 +262,7 @@ struct dmi_system_event_log {
 	u8	header_format;
 	u8	type_descriptors_supported_count;
 	u8	per_log_type_descriptor_length;
-	u8	supported_log_type_descriptos[0];
+	u8	supported_log_type_descriptos[];
 } __packed;
 
 #define DMI_SYSFS_SEL_FIELD(_field) \
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
index f59163cb7cba..5066d1f1d687 100644
--- a/drivers/firmware/dmi_scan.c
+++ b/drivers/firmware/dmi_scan.c
@@ -186,6 +186,34 @@ static void __init dmi_save_ident(const struct dmi_header *dm, int slot,
 	dmi_ident[slot] = p;
 }
 
+static void __init dmi_save_release(const struct dmi_header *dm, int slot,
+		int index)
+{
+	const u8 *minor, *major;
+	char *s;
+
+	/* If the table doesn't have the field, let's return */
+	if (dmi_ident[slot] || dm->length < index)
+		return;
+
+	minor = (u8 *) dm + index;
+	major = (u8 *) dm + index - 1;
+
+	/* As per the spec, if the system doesn't support this field,
+	 * the value is FF
+	 */
+	if (*major == 0xFF && *minor == 0xFF)
+		return;
+
+	s = dmi_alloc(8);
+	if (!s)
+		return;
+
+	sprintf(s, "%u.%u", *major, *minor);
+
+	dmi_ident[slot] = s;
+}
+
 static void __init dmi_save_uuid(const struct dmi_header *dm, int slot,
 		int index)
 {
@@ -444,6 +472,8 @@ static void __init dmi_decode(const struct dmi_header *dm, void *dummy)
 		dmi_save_ident(dm, DMI_BIOS_VENDOR, 4);
 		dmi_save_ident(dm, DMI_BIOS_VERSION, 5);
 		dmi_save_ident(dm, DMI_BIOS_DATE, 8);
+		dmi_save_release(dm, DMI_BIOS_RELEASE, 21);
+		dmi_save_release(dm, DMI_EC_FIRMWARE_RELEASE, 23);
 		break;
 	case 1:		/* System Information */
 		dmi_save_ident(dm, DMI_SYS_VENDOR, 4);
diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c
index b1af0de2e100..9d2512913d25 100644
--- a/drivers/firmware/efi/cper.c
+++ b/drivers/firmware/efi/cper.c
@@ -101,7 +101,7 @@ void cper_print_bits(const char *pfx, unsigned int bits,
 		if (!len)
 			len = snprintf(buf, sizeof(buf), "%s%s", pfx, str);
 		else
-			len += snprintf(buf+len, sizeof(buf)-len, ", %s", str);
+			len += scnprintf(buf+len, sizeof(buf)-len, ", %s", str);
 	}
 	if (len)
 		printk("%s\n", buf);
diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
index 094eabdecfe6..dd31237fba2e 100644
--- a/drivers/firmware/efi/libstub/Makefile
+++ b/drivers/firmware/efi/libstub/Makefile
@@ -33,7 +33,9 @@ KBUILD_CFLAGS			:= $(cflags-y) -DDISABLE_BRANCH_PROFILING \
 				   -D__DISABLE_EXPORTS
 
 GCOV_PROFILE			:= n
+# Sanitizer runtimes are unavailable and cannot be linked here.
 KASAN_SANITIZE			:= n
+KCSAN_SANITIZE			:= n
 UBSAN_SANITIZE			:= n
 OBJECT_FILES_NON_STANDARD	:= y
 
diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
index cc90a748bcf0..67d26949fd26 100644
--- a/drivers/firmware/efi/libstub/efistub.h
+++ b/drivers/firmware/efi/libstub/efistub.h
@@ -25,7 +25,7 @@
 #define EFI_ALLOC_ALIGN		EFI_PAGE_SIZE
 #endif
 
-#ifdef CONFIG_ARM
+#if defined(CONFIG_ARM) || defined(CONFIG_X86)
 #define __efistub_global	__section(.data)
 #else
 #define __efistub_global
diff --git a/drivers/firmware/efi/libstub/file.c b/drivers/firmware/efi/libstub/file.c
index d4c7e5f59d2c..ea66b1f16a79 100644
--- a/drivers/firmware/efi/libstub/file.c
+++ b/drivers/firmware/efi/libstub/file.c
@@ -29,30 +29,31 @@
  */
 #define EFI_READ_CHUNK_SIZE	SZ_1M
 
+struct finfo {
+	efi_file_info_t info;
+	efi_char16_t	filename[MAX_FILENAME_SIZE];
+};
+
 static efi_status_t efi_open_file(efi_file_protocol_t *volume,
-				  efi_char16_t *filename_16,
+				  struct finfo *fi,
 				  efi_file_protocol_t **handle,
 				  unsigned long *file_size)
 {
-	struct {
-		efi_file_info_t info;
-		efi_char16_t	filename[MAX_FILENAME_SIZE];
-	} finfo;
 	efi_guid_t info_guid = EFI_FILE_INFO_ID;
 	efi_file_protocol_t *fh;
 	unsigned long info_sz;
 	efi_status_t status;
 
-	status = volume->open(volume, &fh, filename_16, EFI_FILE_MODE_READ, 0);
+	status = volume->open(volume, &fh, fi->filename, EFI_FILE_MODE_READ, 0);
 	if (status != EFI_SUCCESS) {
 		pr_efi_err("Failed to open file: ");
-		efi_char16_printk(filename_16);
+		efi_char16_printk(fi->filename);
 		efi_printk("\n");
 		return status;
 	}
 
-	info_sz = sizeof(finfo);
-	status = fh->get_info(fh, &info_guid, &info_sz, &finfo);
+	info_sz = sizeof(struct finfo);
+	status = fh->get_info(fh, &info_guid, &info_sz, fi);
 	if (status != EFI_SUCCESS) {
 		pr_efi_err("Failed to get file info\n");
 		fh->close(fh);
@@ -60,7 +61,7 @@ static efi_status_t efi_open_file(efi_file_protocol_t *volume,
 	}
 
 	*handle = fh;
-	*file_size = finfo.info.file_size;
+	*file_size = fi->info.file_size;
 	return EFI_SUCCESS;
 }
 
@@ -146,13 +147,13 @@ static efi_status_t handle_cmdline_files(efi_loaded_image_t *image,
 
 	alloc_addr = alloc_size = 0;
 	do {
-		efi_char16_t filename[MAX_FILENAME_SIZE];
+		struct finfo fi;
 		unsigned long size;
 		void *addr;
 
 		offset = find_file_option(cmdline, cmdline_len,
 					  optstr, optstr_size,
-					  filename, ARRAY_SIZE(filename));
+					  fi.filename, ARRAY_SIZE(fi.filename));
 
 		if (!offset)
 			break;
@@ -166,7 +167,7 @@ static efi_status_t handle_cmdline_files(efi_loaded_image_t *image,
 				return status;
 		}
 
-		status = efi_open_file(volume, filename, &file, &size);
+		status = efi_open_file(volume, &fi, &file, &size);
 		if (status != EFI_SUCCESS)
 			goto err_close_volume;
 
diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi/libstub/x86-stub.c
index 8d3a707789de..05ccb229fb45 100644
--- a/drivers/firmware/efi/libstub/x86-stub.c
+++ b/drivers/firmware/efi/libstub/x86-stub.c
@@ -20,7 +20,7 @@
 /* Maximum physical address for 64-bit kernel with 4-level paging */
 #define MAXMEM_X86_64_4LEVEL (1ull << 46)
 
-static efi_system_table_t *sys_table;
+static efi_system_table_t *sys_table __efistub_global;
 extern const bool efi_is64;
 extern u32 image_offset;
 
@@ -392,8 +392,6 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
 	image_base = efi_table_attr(image, image_base);
 	image_offset = (void *)startup_32 - image_base;
 
-	hdr = &((struct boot_params *)image_base)->hdr;
-
 	status = efi_allocate_pages(0x4000, (unsigned long *)&boot_params, ULONG_MAX);
 	if (status != EFI_SUCCESS) {
 		efi_printk("Failed to allocate lowmem for boot params\n");
@@ -742,8 +740,15 @@ unsigned long efi_main(efi_handle_t handle,
 	 * now use KERNEL_IMAGE_SIZE, which will be 512MiB, the same as what
 	 * KASLR uses.
 	 *
-	 * Also relocate it if image_offset is zero, i.e. we weren't loaded by
-	 * LoadImage, but we are not aligned correctly.
+	 * Also relocate it if image_offset is zero, i.e. the kernel wasn't
+	 * loaded by LoadImage, but rather by a bootloader that called the
+	 * handover entry. The reason we must always relocate in this case is
+	 * to handle the case of systemd-boot booting a unified kernel image,
+	 * which is a PE executable that contains the bzImage and an initrd as
+	 * COFF sections. The initrd section is placed after the bzImage
+	 * without ensuring that there are at least init_size bytes available
+	 * for the bzImage, and thus the compressed kernel's startup code may
+	 * overwrite the initrd unless it is moved out of the way.
 	 */
 
 	buffer_start = ALIGN(bzimage_addr - image_offset,
@@ -753,8 +758,7 @@ unsigned long efi_main(efi_handle_t handle,
 	if ((buffer_start < LOAD_PHYSICAL_ADDR)				     ||
 	    (IS_ENABLED(CONFIG_X86_32) && buffer_end > KERNEL_IMAGE_SIZE)    ||
 	    (IS_ENABLED(CONFIG_X86_64) && buffer_end > MAXMEM_X86_64_4LEVEL) ||
-	    (image_offset == 0 && !IS_ALIGNED(bzimage_addr,
-					      hdr->kernel_alignment))) {
+	    (image_offset == 0)) {
 		status = efi_relocate_kernel(&bzimage_addr,
 					     hdr->init_size, hdr->init_size,
 					     hdr->pref_address,
diff --git a/drivers/firmware/google/memconsole-coreboot.c b/drivers/firmware/google/memconsole-coreboot.c
index fd7f0fbec07e..d17e4d6ac9bc 100644
--- a/drivers/firmware/google/memconsole-coreboot.c
+++ b/drivers/firmware/google/memconsole-coreboot.c
@@ -21,7 +21,7 @@
 struct cbmem_cons {
 	u32 size_dont_access_after_boot;
 	u32 cursor;
-	u8  body[0];
+	u8  body[];
 } __packed;
 
 #define CURSOR_MASK ((1 << 28) - 1)
diff --git a/drivers/firmware/google/vpd.c b/drivers/firmware/google/vpd.c
index db0812263d46..d23c5c69ab52 100644
--- a/drivers/firmware/google/vpd.c
+++ b/drivers/firmware/google/vpd.c
@@ -32,7 +32,7 @@ struct vpd_cbmem {
 	u32 version;
 	u32 ro_size;
 	u32 rw_size;
-	u8  blob[0];
+	u8  blob[];
 };
 
 struct vpd_section {
diff --git a/drivers/fpga/dfl-afu-main.c b/drivers/fpga/dfl-afu-main.c
index 65437b6a6842..b0c31789a909 100644
--- a/drivers/fpga/dfl-afu-main.c
+++ b/drivers/fpga/dfl-afu-main.c
@@ -561,14 +561,16 @@ static int afu_open(struct inode *inode, struct file *filp)
 	if (WARN_ON(!pdata))
 		return -ENODEV;
 
-	ret = dfl_feature_dev_use_begin(pdata);
-	if (ret)
-		return ret;
-
-	dev_dbg(&fdev->dev, "Device File Open\n");
-	filp->private_data = fdev;
+	mutex_lock(&pdata->lock);
+	ret = dfl_feature_dev_use_begin(pdata, filp->f_flags & O_EXCL);
+	if (!ret) {
+		dev_dbg(&fdev->dev, "Device File Opened %d Times\n",
+			dfl_feature_dev_use_count(pdata));
+		filp->private_data = fdev;
+	}
+	mutex_unlock(&pdata->lock);
 
-	return 0;
+	return ret;
 }
 
 static int afu_release(struct inode *inode, struct file *filp)
@@ -581,12 +583,14 @@ static int afu_release(struct inode *inode, struct file *filp)
 	pdata = dev_get_platdata(&pdev->dev);
 
 	mutex_lock(&pdata->lock);
-	__port_reset(pdev);
-	afu_dma_region_destroy(pdata);
-	mutex_unlock(&pdata->lock);
-
 	dfl_feature_dev_use_end(pdata);
 
+	if (!dfl_feature_dev_use_count(pdata)) {
+		__port_reset(pdev);
+		afu_dma_region_destroy(pdata);
+	}
+	mutex_unlock(&pdata->lock);
+
 	return 0;
 }
 
@@ -746,6 +750,12 @@ static long afu_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 	return -EINVAL;
 }
 
+static const struct vm_operations_struct afu_vma_ops = {
+#ifdef CONFIG_HAVE_IOREMAP_PROT
+	.access = generic_access_phys,
+#endif
+};
+
 static int afu_mmap(struct file *filp, struct vm_area_struct *vma)
 {
 	struct platform_device *pdev = filp->private_data;
@@ -775,6 +785,9 @@ static int afu_mmap(struct file *filp, struct vm_area_struct *vma)
 	    !(region.flags & DFL_PORT_REGION_WRITE))
 		return -EPERM;
 
+	/* Support debug access to the mapping */
+	vma->vm_ops = &afu_vma_ops;
+
 	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 
 	return remap_pfn_range(vma, vma->vm_start,
diff --git a/drivers/fpga/dfl-fme-main.c b/drivers/fpga/dfl-fme-main.c
index 1d4690c99268..56d720c1af39 100644
--- a/drivers/fpga/dfl-fme-main.c
+++ b/drivers/fpga/dfl-fme-main.c
@@ -600,14 +600,16 @@ static int fme_open(struct inode *inode, struct file *filp)
 	if (WARN_ON(!pdata))
 		return -ENODEV;
 
-	ret = dfl_feature_dev_use_begin(pdata);
-	if (ret)
-		return ret;
-
-	dev_dbg(&fdev->dev, "Device File Open\n");
-	filp->private_data = pdata;
+	mutex_lock(&pdata->lock);
+	ret = dfl_feature_dev_use_begin(pdata, filp->f_flags & O_EXCL);
+	if (!ret) {
+		dev_dbg(&fdev->dev, "Device File Opened %d Times\n",
+			dfl_feature_dev_use_count(pdata));
+		filp->private_data = pdata;
+	}
+	mutex_unlock(&pdata->lock);
 
-	return 0;
+	return ret;
 }
 
 static int fme_release(struct inode *inode, struct file *filp)
@@ -616,7 +618,10 @@ static int fme_release(struct inode *inode, struct file *filp)
 	struct platform_device *pdev = pdata->dev;
 
 	dev_dbg(&pdev->dev, "Device File Release\n");
+
+	mutex_lock(&pdata->lock);
 	dfl_feature_dev_use_end(pdata);
+	mutex_unlock(&pdata->lock);
 
 	return 0;
 }
diff --git a/drivers/fpga/dfl-pci.c b/drivers/fpga/dfl-pci.c
index 89ca292236ad..538755062ab7 100644
--- a/drivers/fpga/dfl-pci.c
+++ b/drivers/fpga/dfl-pci.c
@@ -248,11 +248,13 @@ static int cci_pci_sriov_configure(struct pci_dev *pcidev, int num_vfs)
 			return ret;
 
 		ret = pci_enable_sriov(pcidev, num_vfs);
-		if (ret)
+		if (ret) {
 			dfl_fpga_cdev_config_ports_pf(cdev);
+			return ret;
+		}
 	}
 
-	return ret;
+	return num_vfs;
 }
 
 static void cci_pci_remove(struct pci_dev *pcidev)
diff --git a/drivers/fpga/dfl.c b/drivers/fpga/dfl.c
index 96a2b8274a33..990994874bf1 100644
--- a/drivers/fpga/dfl.c
+++ b/drivers/fpga/dfl.c
@@ -1079,6 +1079,7 @@ static int __init dfl_fpga_init(void)
  */
 int dfl_fpga_cdev_release_port(struct dfl_fpga_cdev *cdev, int port_id)
 {
+	struct dfl_feature_platform_data *pdata;
 	struct platform_device *port_pdev;
 	int ret = -ENODEV;
 
@@ -1093,7 +1094,11 @@ int dfl_fpga_cdev_release_port(struct dfl_fpga_cdev *cdev, int port_id)
 		goto put_dev_exit;
 	}
 
-	ret = dfl_feature_dev_use_begin(dev_get_platdata(&port_pdev->dev));
+	pdata = dev_get_platdata(&port_pdev->dev);
+
+	mutex_lock(&pdata->lock);
+	ret = dfl_feature_dev_use_begin(pdata, true);
+	mutex_unlock(&pdata->lock);
 	if (ret)
 		goto put_dev_exit;
 
@@ -1120,6 +1125,7 @@ EXPORT_SYMBOL_GPL(dfl_fpga_cdev_release_port);
  */
 int dfl_fpga_cdev_assign_port(struct dfl_fpga_cdev *cdev, int port_id)
 {
+	struct dfl_feature_platform_data *pdata;
 	struct platform_device *port_pdev;
 	int ret = -ENODEV;
 
@@ -1138,7 +1144,12 @@ int dfl_fpga_cdev_assign_port(struct dfl_fpga_cdev *cdev, int port_id)
 	if (ret)
 		goto put_dev_exit;
 
-	dfl_feature_dev_use_end(dev_get_platdata(&port_pdev->dev));
+	pdata = dev_get_platdata(&port_pdev->dev);
+
+	mutex_lock(&pdata->lock);
+	dfl_feature_dev_use_end(pdata);
+	mutex_unlock(&pdata->lock);
+
 	cdev->released_port_num--;
 put_dev_exit:
 	put_device(&port_pdev->dev);
diff --git a/drivers/fpga/dfl.h b/drivers/fpga/dfl.h
index 9f0e656de720..74784d3cfe7c 100644
--- a/drivers/fpga/dfl.h
+++ b/drivers/fpga/dfl.h
@@ -205,8 +205,6 @@ struct dfl_feature {
 	const struct dfl_feature_ops *ops;
 };
 
-#define DEV_STATUS_IN_USE	0
-
 #define FEATURE_DEV_ID_UNUSED	(-1)
 
 /**
@@ -219,8 +217,9 @@ struct dfl_feature {
  * @dfl_cdev: ptr to container device.
  * @id: id used for this feature device.
  * @disable_count: count for port disable.
+ * @excl_open: set on feature device exclusive open.
+ * @open_count: count for feature device open.
  * @num: number for sub features.
- * @dev_status: dev status (e.g. DEV_STATUS_IN_USE).
  * @private: ptr to feature dev private data.
  * @features: sub features of this feature dev.
  */
@@ -232,26 +231,46 @@ struct dfl_feature_platform_data {
 	struct dfl_fpga_cdev *dfl_cdev;
 	int id;
 	unsigned int disable_count;
-	unsigned long dev_status;
+	bool excl_open;
+	int open_count;
 	void *private;
 	int num;
-	struct dfl_feature features[0];
+	struct dfl_feature features[];
 };
 
 static inline
-int dfl_feature_dev_use_begin(struct dfl_feature_platform_data *pdata)
+int dfl_feature_dev_use_begin(struct dfl_feature_platform_data *pdata,
+			      bool excl)
 {
-	/* Test and set IN_USE flags to ensure file is exclusively used */
-	if (test_and_set_bit_lock(DEV_STATUS_IN_USE, &pdata->dev_status))
+	if (pdata->excl_open)
 		return -EBUSY;
 
+	if (excl) {
+		if (pdata->open_count)
+			return -EBUSY;
+
+		pdata->excl_open = true;
+	}
+	pdata->open_count++;
+
 	return 0;
 }
 
 static inline
 void dfl_feature_dev_use_end(struct dfl_feature_platform_data *pdata)
 {
-	clear_bit_unlock(DEV_STATUS_IN_USE, &pdata->dev_status);
+	pdata->excl_open = false;
+
+	if (WARN_ON(pdata->open_count <= 0))
+		return;
+
+	pdata->open_count--;
+}
+
+static inline
+int dfl_feature_dev_use_count(struct dfl_feature_platform_data *pdata)
+{
+	return pdata->open_count;
 }
 
 static inline
diff --git a/drivers/fpga/ice40-spi.c b/drivers/fpga/ice40-spi.c
index 56e112e14a10..8d689fea0dab 100644
--- a/drivers/fpga/ice40-spi.c
+++ b/drivers/fpga/ice40-spi.c
@@ -46,10 +46,16 @@ static int ice40_fpga_ops_write_init(struct fpga_manager *mgr,
 	struct spi_message message;
 	struct spi_transfer assert_cs_then_reset_delay = {
 		.cs_change   = 1,
-		.delay_usecs = ICE40_SPI_RESET_DELAY
+		.delay = {
+			.value = ICE40_SPI_RESET_DELAY,
+			.unit = SPI_DELAY_UNIT_USECS
+		}
 	};
 	struct spi_transfer housekeeping_delay_then_release_cs = {
-		.delay_usecs = ICE40_SPI_HOUSEKEEPING_DELAY
+		.delay = {
+			.value = ICE40_SPI_HOUSEKEEPING_DELAY,
+			.unit = SPI_DELAY_UNIT_USECS
+		}
 	};
 	int ret;
 
diff --git a/drivers/fpga/machxo2-spi.c b/drivers/fpga/machxo2-spi.c
index 4d8a87641587..b316369156fe 100644
--- a/drivers/fpga/machxo2-spi.c
+++ b/drivers/fpga/machxo2-spi.c
@@ -157,7 +157,8 @@ static int machxo2_cleanup(struct fpga_manager *mgr)
 	spi_message_init(&msg);
 	tx[1].tx_buf = &refresh;
 	tx[1].len = sizeof(refresh);
-	tx[1].delay_usecs = MACHXO2_REFRESH_USEC;
+	tx[1].delay.value = MACHXO2_REFRESH_USEC;
+	tx[1].delay.unit = SPI_DELAY_UNIT_USECS;
 	spi_message_add_tail(&tx[1], &msg);
 	ret = spi_sync(spi, &msg);
 	if (ret)
@@ -208,7 +209,8 @@ static int machxo2_write_init(struct fpga_manager *mgr,
 	spi_message_init(&msg);
 	tx[0].tx_buf = &enable;
 	tx[0].len = sizeof(enable);
-	tx[0].delay_usecs = MACHXO2_LOW_DELAY_USEC;
+	tx[0].delay.value = MACHXO2_LOW_DELAY_USEC;
+	tx[0].delay.unit = SPI_DELAY_UNIT_USECS;
 	spi_message_add_tail(&tx[0], &msg);
 
 	tx[1].tx_buf = &erase;
@@ -269,7 +271,8 @@ static int machxo2_write(struct fpga_manager *mgr, const char *buf,
 		spi_message_init(&msg);
 		tx.tx_buf = payload;
 		tx.len = MACHXO2_BUF_SIZE;
-		tx.delay_usecs = MACHXO2_HIGH_DELAY_USEC;
+		tx.delay.value = MACHXO2_HIGH_DELAY_USEC;
+		tx.delay.unit = SPI_DELAY_UNIT_USECS;
 		spi_message_add_tail(&tx, &msg);
 		ret = spi_sync(spi, &msg);
 		if (ret) {
@@ -317,7 +320,8 @@ static int machxo2_write_complete(struct fpga_manager *mgr,
 		spi_message_init(&msg);
 		tx[1].tx_buf = &refresh;
 		tx[1].len = sizeof(refresh);
-		tx[1].delay_usecs = MACHXO2_REFRESH_USEC;
+		tx[1].delay.value = MACHXO2_REFRESH_USEC;
+		tx[1].delay.unit = SPI_DELAY_UNIT_USECS;
 		spi_message_add_tail(&tx[1], &msg);
 		ret = spi_sync(spi, &msg);
 		if (ret)
diff --git a/drivers/fpga/stratix10-soc.c b/drivers/fpga/stratix10-soc.c
index 215d33789c74..bac93d009170 100644
--- a/drivers/fpga/stratix10-soc.c
+++ b/drivers/fpga/stratix10-soc.c
@@ -482,7 +482,8 @@ static int s10_remove(struct platform_device *pdev)
 }
 
 static const struct of_device_id s10_of_match[] = {
-	{ .compatible = "intel,stratix10-soc-fpga-mgr", },
+	{.compatible = "intel,stratix10-soc-fpga-mgr"},
+	{.compatible = "intel,agilex-soc-fpga-mgr"},
 	{},
 };
 
diff --git a/drivers/fpga/zynq-fpga.c b/drivers/fpga/zynq-fpga.c
index ee7765049607..07fa8d9ec675 100644
--- a/drivers/fpga/zynq-fpga.c
+++ b/drivers/fpga/zynq-fpga.c
@@ -583,7 +583,8 @@ static int zynq_fpga_probe(struct platform_device *pdev)
 
 	priv->clk = devm_clk_get(dev, "ref_clk");
 	if (IS_ERR(priv->clk)) {
-		dev_err(dev, "input clock not found\n");
+		if (PTR_ERR(priv->clk) != -EPROBE_DEFER)
+			dev_err(dev, "input clock not found\n");
 		return PTR_ERR(priv->clk);
 	}
 
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 1b96169d84f7..8ef2179fb999 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -422,7 +422,7 @@ config GPIO_OMAP
 	  Say yes here to enable GPIO support for TI OMAP SoCs.
 
 config GPIO_PL061
-	bool "PrimeCell PL061 GPIO support"
+	tristate "PrimeCell PL061 GPIO support"
 	depends on ARM_AMBA
 	select IRQ_DOMAIN
 	select GPIOLIB_IRQCHIP
diff --git a/drivers/gpio/TODO b/drivers/gpio/TODO
index 3a44e6ae52bd..b989c9352da2 100644
--- a/drivers/gpio/TODO
+++ b/drivers/gpio/TODO
@@ -99,6 +99,10 @@ similar and probe a proper driver in the gpiolib subsystem.
 In some cases it makes sense to create a GPIO chip from the local driver
 for a few GPIOs. Those should stay where they are.
 
+At the same time it makes sense to get rid of code duplication in existing or
+new coming drivers. For example, gpio-ml-ioh should be incorporated into
+gpio-pch. In similar way gpio-intel-mid into gpio-pxa.
+
 
 Generic MMIO GPIO
 
diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c
index 92e127e74813..a09332d9c7fe 100644
--- a/drivers/gpio/gpio-dwapb.c
+++ b/drivers/gpio/gpio-dwapb.c
@@ -49,7 +49,9 @@
 #define GPIO_EXT_PORTC		0x58
 #define GPIO_EXT_PORTD		0x5c
 
+#define DWAPB_DRIVER_NAME	"gpio-dwapb"
 #define DWAPB_MAX_PORTS		4
+
 #define GPIO_EXT_PORT_STRIDE	0x04 /* register stride 32 bits */
 #define GPIO_SWPORT_DR_STRIDE	0x0c /* register stride 3*32 bits */
 #define GPIO_SWPORT_DDR_STRIDE	0x0c /* register stride 3*32 bits */
@@ -62,6 +64,8 @@
 #define GPIO_INTSTATUS_V2	0x3c
 #define GPIO_PORTA_EOI_V2	0x40
 
+#define DWAPB_NR_CLOCKS		2
+
 struct dwapb_gpio;
 
 #ifdef CONFIG_PM_SLEEP
@@ -97,7 +101,7 @@ struct dwapb_gpio {
 	struct irq_domain	*domain;
 	unsigned int		flags;
 	struct reset_control	*rst;
-	struct clk		*clk;
+	struct clk_bulk_data	clks[DWAPB_NR_CLOCKS];
 };
 
 static inline u32 gpio_reg_v2_convert(unsigned int offset)
@@ -189,22 +193,21 @@ static void dwapb_toggle_trigger(struct dwapb_gpio *gpio, unsigned int offs)
 
 static u32 dwapb_do_irq(struct dwapb_gpio *gpio)
 {
-	u32 irq_status = dwapb_read(gpio, GPIO_INTSTATUS);
-	u32 ret = irq_status;
+	unsigned long irq_status;
+	irq_hw_number_t hwirq;
 
-	while (irq_status) {
-		int hwirq = fls(irq_status) - 1;
+	irq_status = dwapb_read(gpio, GPIO_INTSTATUS);
+	for_each_set_bit(hwirq, &irq_status, 32) {
 		int gpio_irq = irq_find_mapping(gpio->domain, hwirq);
+		u32 irq_type = irq_get_trigger_type(gpio_irq);
 
 		generic_handle_irq(gpio_irq);
-		irq_status &= ~BIT(hwirq);
 
-		if ((irq_get_trigger_type(gpio_irq) & IRQ_TYPE_SENSE_MASK)
-			== IRQ_TYPE_EDGE_BOTH)
+		if ((irq_type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
 			dwapb_toggle_trigger(gpio, hwirq);
 	}
 
-	return ret;
+	return irq_status;
 }
 
 static void dwapb_irq_handler(struct irq_desc *desc)
@@ -212,10 +215,9 @@ static void dwapb_irq_handler(struct irq_desc *desc)
 	struct dwapb_gpio *gpio = irq_desc_get_handler_data(desc);
 	struct irq_chip *chip = irq_desc_get_chip(desc);
 
+	chained_irq_enter(chip, desc);
 	dwapb_do_irq(gpio);
-
-	if (chip->irq_eoi)
-		chip->irq_eoi(irq_desc_get_irq_data(desc));
+	chained_irq_exit(chip, desc);
 }
 
 static void dwapb_irq_enable(struct irq_data *d)
@@ -228,7 +230,7 @@ static void dwapb_irq_enable(struct irq_data *d)
 
 	spin_lock_irqsave(&gc->bgpio_lock, flags);
 	val = dwapb_read(gpio, GPIO_INTEN);
-	val |= BIT(d->hwirq);
+	val |= BIT(irqd_to_hwirq(d));
 	dwapb_write(gpio, GPIO_INTEN, val);
 	spin_unlock_irqrestore(&gc->bgpio_lock, flags);
 }
@@ -243,46 +245,20 @@ static void dwapb_irq_disable(struct irq_data *d)
 
 	spin_lock_irqsave(&gc->bgpio_lock, flags);
 	val = dwapb_read(gpio, GPIO_INTEN);
-	val &= ~BIT(d->hwirq);
+	val &= ~BIT(irqd_to_hwirq(d));
 	dwapb_write(gpio, GPIO_INTEN, val);
 	spin_unlock_irqrestore(&gc->bgpio_lock, flags);
 }
 
-static int dwapb_irq_reqres(struct irq_data *d)
-{
-	struct irq_chip_generic *igc = irq_data_get_irq_chip_data(d);
-	struct dwapb_gpio *gpio = igc->private;
-	struct gpio_chip *gc = &gpio->ports[0].gc;
-	int ret;
-
-	ret = gpiochip_lock_as_irq(gc, irqd_to_hwirq(d));
-	if (ret) {
-		dev_err(gpio->dev, "unable to lock HW IRQ %lu for IRQ\n",
-			irqd_to_hwirq(d));
-		return ret;
-	}
-	return 0;
-}
-
-static void dwapb_irq_relres(struct irq_data *d)
-{
-	struct irq_chip_generic *igc = irq_data_get_irq_chip_data(d);
-	struct dwapb_gpio *gpio = igc->private;
-	struct gpio_chip *gc = &gpio->ports[0].gc;
-
-	gpiochip_unlock_as_irq(gc, irqd_to_hwirq(d));
-}
-
 static int dwapb_irq_set_type(struct irq_data *d, u32 type)
 {
 	struct irq_chip_generic *igc = irq_data_get_irq_chip_data(d);
 	struct dwapb_gpio *gpio = igc->private;
 	struct gpio_chip *gc = &gpio->ports[0].gc;
-	int bit = d->hwirq;
+	irq_hw_number_t bit = irqd_to_hwirq(d);
 	unsigned long level, polarity, flags;
 
-	if (type & ~(IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING |
-		     IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW))
+	if (type & ~IRQ_TYPE_SENSE_MASK)
 		return -EINVAL;
 
 	spin_lock_irqsave(&gc->bgpio_lock, flags);
@@ -328,11 +304,12 @@ static int dwapb_irq_set_wake(struct irq_data *d, unsigned int enable)
 	struct irq_chip_generic *igc = irq_data_get_irq_chip_data(d);
 	struct dwapb_gpio *gpio = igc->private;
 	struct dwapb_context *ctx = gpio->ports[0].ctx;
+	irq_hw_number_t bit = irqd_to_hwirq(d);
 
 	if (enable)
-		ctx->wake_en |= BIT(d->hwirq);
+		ctx->wake_en |= BIT(bit);
 	else
-		ctx->wake_en &= ~BIT(d->hwirq);
+		ctx->wake_en &= ~BIT(bit);
 
 	return 0;
 }
@@ -350,9 +327,10 @@ static int dwapb_gpio_set_debounce(struct gpio_chip *gc,
 
 	val_deb = dwapb_read(gpio, GPIO_PORTA_DEBOUNCE);
 	if (debounce)
-		dwapb_write(gpio, GPIO_PORTA_DEBOUNCE, val_deb | mask);
+		val_deb |= mask;
 	else
-		dwapb_write(gpio, GPIO_PORTA_DEBOUNCE, val_deb & ~mask);
+		val_deb &= ~mask;
+	dwapb_write(gpio, GPIO_PORTA_DEBOUNCE, val_deb);
 
 	spin_unlock_irqrestore(&gc->bgpio_lock, flags);
 
@@ -373,12 +351,7 @@ static int dwapb_gpio_set_config(struct gpio_chip *gc, unsigned offset,
 
 static irqreturn_t dwapb_irq_handler_mfd(int irq, void *dev_id)
 {
-	u32 worked;
-	struct dwapb_gpio *gpio = dev_id;
-
-	worked = dwapb_do_irq(gpio);
-
-	return worked ? IRQ_HANDLED : IRQ_NONE;
+	return IRQ_RETVAL(dwapb_do_irq(dev_id));
 }
 
 static void dwapb_configure_irqs(struct dwapb_gpio *gpio,
@@ -388,8 +361,9 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio,
 	struct gpio_chip *gc = &port->gc;
 	struct fwnode_handle  *fwnode = pp->fwnode;
 	struct irq_chip_generic	*irq_gc = NULL;
-	unsigned int hwirq, ngpio = gc->ngpio;
+	unsigned int ngpio = gc->ngpio;
 	struct irq_chip_type *ct;
+	irq_hw_number_t hwirq;
 	int err, i;
 
 	gpio->domain = irq_domain_create_linear(fwnode, ngpio,
@@ -398,7 +372,7 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio,
 		return;
 
 	err = irq_alloc_domain_generic_chips(gpio->domain, ngpio, 2,
-					     "gpio-dwapb", handle_level_irq,
+					     DWAPB_DRIVER_NAME, handle_bad_irq,
 					     IRQ_NOREQUEST, 0,
 					     IRQ_GC_INIT_NESTED_LOCK);
 	if (err) {
@@ -426,8 +400,6 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio,
 		ct->chip.irq_set_type = dwapb_irq_set_type;
 		ct->chip.irq_enable = dwapb_irq_enable;
 		ct->chip.irq_disable = dwapb_irq_disable;
-		ct->chip.irq_request_resources = dwapb_irq_reqres;
-		ct->chip.irq_release_resources = dwapb_irq_relres;
 #ifdef CONFIG_PM_SLEEP
 		ct->chip.irq_set_wake = dwapb_irq_set_wake;
 #endif
@@ -437,34 +409,35 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio,
 	}
 
 	irq_gc->chip_types[0].type = IRQ_TYPE_LEVEL_MASK;
+	irq_gc->chip_types[0].handler = handle_level_irq;
 	irq_gc->chip_types[1].type = IRQ_TYPE_EDGE_BOTH;
 	irq_gc->chip_types[1].handler = handle_edge_irq;
 
-	if (!pp->irq_shared) {
-		int i;
-
-		for (i = 0; i < pp->ngpio; i++) {
-			if (pp->irq[i] >= 0)
-				irq_set_chained_handler_and_data(pp->irq[i],
-						dwapb_irq_handler, gpio);
-		}
-	} else {
+	if (pp->irq_shared) {
 		/*
 		 * Request a shared IRQ since where MFD would have devices
 		 * using the same irq pin
 		 */
 		err = devm_request_irq(gpio->dev, pp->irq[0],
 				       dwapb_irq_handler_mfd,
-				       IRQF_SHARED, "gpio-dwapb-mfd", gpio);
+				       IRQF_SHARED, DWAPB_DRIVER_NAME, gpio);
 		if (err) {
 			dev_err(gpio->dev, "error requesting IRQ\n");
 			irq_domain_remove(gpio->domain);
 			gpio->domain = NULL;
 			return;
 		}
+	} else {
+		int i;
+
+		for (i = 0; i < pp->ngpio; i++) {
+			if (pp->irq[i] >= 0)
+				irq_set_chained_handler_and_data(pp->irq[i],
+						dwapb_irq_handler, gpio);
+		}
 	}
 
-	for (hwirq = 0 ; hwirq < ngpio ; hwirq++)
+	for (hwirq = 0; hwirq < ngpio; hwirq++)
 		irq_create_mapping(gpio->domain, hwirq);
 
 	port->gc.to_irq = dwapb_gpio_to_irq;
@@ -480,7 +453,7 @@ static void dwapb_irq_teardown(struct dwapb_gpio *gpio)
 	if (!gpio->domain)
 		return;
 
-	for (hwirq = 0 ; hwirq < ngpio ; hwirq++)
+	for (hwirq = 0; hwirq < ngpio; hwirq++)
 		irq_dispose_mapping(irq_find_mapping(gpio->domain, hwirq));
 
 	irq_domain_remove(gpio->domain);
@@ -505,10 +478,9 @@ static int dwapb_gpio_add_port(struct dwapb_gpio *gpio,
 		return -ENOMEM;
 #endif
 
-	dat = gpio->regs + GPIO_EXT_PORTA + (pp->idx * GPIO_EXT_PORT_STRIDE);
-	set = gpio->regs + GPIO_SWPORTA_DR + (pp->idx * GPIO_SWPORT_DR_STRIDE);
-	dirout = gpio->regs + GPIO_SWPORTA_DDR +
-		(pp->idx * GPIO_SWPORT_DDR_STRIDE);
+	dat = gpio->regs + GPIO_EXT_PORTA + pp->idx * GPIO_EXT_PORT_STRIDE;
+	set = gpio->regs + GPIO_SWPORTA_DR + pp->idx * GPIO_SWPORT_DR_STRIDE;
+	dirout = gpio->regs + GPIO_SWPORTA_DDR + pp->idx * GPIO_SWPORT_DDR_STRIDE;
 
 	/* This registers 32 GPIO lines per port */
 	err = bgpio_init(&port->gc, gpio->dev, 4, dat, set, NULL, dirout,
@@ -555,14 +527,38 @@ static void dwapb_gpio_unregister(struct dwapb_gpio *gpio)
 			gpiochip_remove(&gpio->ports[m].gc);
 }
 
-static struct dwapb_platform_data *
-dwapb_gpio_get_pdata(struct device *dev)
+static void dwapb_get_irq(struct device *dev, struct fwnode_handle *fwnode,
+			  struct dwapb_port_property *pp)
+{
+	struct device_node *np = NULL;
+	int j;
+
+	if (fwnode_property_read_bool(fwnode, "interrupt-controller"))
+		np = to_of_node(fwnode);
+
+	for (j = 0; j < pp->ngpio; j++) {
+		pp->irq[j] = -ENXIO;
+
+		if (np)
+			pp->irq[j] = of_irq_get(np, j);
+		else if (has_acpi_companion(dev))
+			pp->irq[j] = platform_get_irq(to_platform_device(dev), j);
+
+		if (pp->irq[j] >= 0)
+			pp->has_irq = true;
+	}
+
+	if (!pp->has_irq)
+		dev_warn(dev, "no irq for port%d\n", pp->idx);
+}
+
+static struct dwapb_platform_data *dwapb_gpio_get_pdata(struct device *dev)
 {
 	struct fwnode_handle *fwnode;
 	struct dwapb_platform_data *pdata;
 	struct dwapb_port_property *pp;
 	int nports;
-	int i, j;
+	int i;
 
 	nports = device_get_child_node_count(dev);
 	if (nports == 0)
@@ -580,24 +576,18 @@ dwapb_gpio_get_pdata(struct device *dev)
 
 	i = 0;
 	device_for_each_child_node(dev, fwnode)  {
-		struct device_node *np = NULL;
-
 		pp = &pdata->properties[i++];
 		pp->fwnode = fwnode;
 
 		if (fwnode_property_read_u32(fwnode, "reg", &pp->idx) ||
 		    pp->idx >= DWAPB_MAX_PORTS) {
-			dev_err(dev,
-				"missing/invalid port index for port%d\n", i);
+			dev_err(dev, "missing/invalid port index for port%d\n", i);
 			fwnode_handle_put(fwnode);
 			return ERR_PTR(-EINVAL);
 		}
 
-		if (fwnode_property_read_u32(fwnode, "snps,nr-gpios",
-					 &pp->ngpio)) {
-			dev_info(dev,
-				 "failed to get number of gpios for port%d\n",
-				 i);
+		if (fwnode_property_read_u32(fwnode, "snps,nr-gpios", &pp->ngpio)) {
+			dev_info(dev, "failed to get number of gpios for port%d\n", i);
 			pp->ngpio = 32;
 		}
 
@@ -608,28 +598,8 @@ dwapb_gpio_get_pdata(struct device *dev)
 		 * Only port A can provide interrupts in all configurations of
 		 * the IP.
 		 */
-		if (pp->idx != 0)
-			continue;
-
-		if (dev->of_node && fwnode_property_read_bool(fwnode,
-						  "interrupt-controller")) {
-			np = to_of_node(fwnode);
-		}
-
-		for (j = 0; j < pp->ngpio; j++) {
-			pp->irq[j] = -ENXIO;
-
-			if (np)
-				pp->irq[j] = of_irq_get(np, j);
-			else if (has_acpi_companion(dev))
-				pp->irq[j] = platform_get_irq(to_platform_device(dev), j);
-
-			if (pp->irq[j] >= 0)
-				pp->has_irq = true;
-		}
-
-		if (!pp->has_irq)
-			dev_warn(dev, "no irq for port%d\n", pp->idx);
+		if (pp->idx == 0)
+			dwapb_get_irq(dev, fwnode, pp);
 	}
 
 	return pdata;
@@ -689,29 +659,24 @@ static int dwapb_gpio_probe(struct platform_device *pdev)
 	if (IS_ERR(gpio->regs))
 		return PTR_ERR(gpio->regs);
 
-	/* Optional bus clock */
-	gpio->clk = devm_clk_get(&pdev->dev, "bus");
-	if (!IS_ERR(gpio->clk)) {
-		err = clk_prepare_enable(gpio->clk);
-		if (err) {
-			dev_info(&pdev->dev, "Cannot enable clock\n");
-			return err;
-		}
+	/* Optional bus and debounce clocks */
+	gpio->clks[0].id = "bus";
+	gpio->clks[1].id = "db";
+	err = devm_clk_bulk_get_optional(&pdev->dev, DWAPB_NR_CLOCKS,
+					 gpio->clks);
+	if (err) {
+		dev_err(&pdev->dev, "Cannot get APB/Debounce clocks\n");
+		return err;
 	}
 
-	gpio->flags = 0;
-	if (dev->of_node) {
-		gpio->flags = (uintptr_t)of_device_get_match_data(dev);
-	} else if (has_acpi_companion(dev)) {
-		const struct acpi_device_id *acpi_id;
-
-		acpi_id = acpi_match_device(dwapb_acpi_match, dev);
-		if (acpi_id) {
-			if (acpi_id->driver_data)
-				gpio->flags = acpi_id->driver_data;
-		}
+	err = clk_bulk_prepare_enable(DWAPB_NR_CLOCKS, gpio->clks);
+	if (err) {
+		dev_err(&pdev->dev, "Cannot enable APB/Debounce clocks\n");
+		return err;
 	}
 
+	gpio->flags = (uintptr_t)device_get_match_data(dev);
+
 	for (i = 0; i < gpio->nr_ports; i++) {
 		err = dwapb_gpio_add_port(gpio, &pdata->properties[i], i);
 		if (err)
@@ -724,7 +689,7 @@ static int dwapb_gpio_probe(struct platform_device *pdev)
 out_unregister:
 	dwapb_gpio_unregister(gpio);
 	dwapb_irq_teardown(gpio);
-	clk_disable_unprepare(gpio->clk);
+	clk_bulk_disable_unprepare(DWAPB_NR_CLOCKS, gpio->clks);
 
 	return err;
 }
@@ -736,7 +701,7 @@ static int dwapb_gpio_remove(struct platform_device *pdev)
 	dwapb_gpio_unregister(gpio);
 	dwapb_irq_teardown(gpio);
 	reset_control_assert(gpio->rst);
-	clk_disable_unprepare(gpio->clk);
+	clk_bulk_disable_unprepare(DWAPB_NR_CLOCKS, gpio->clks);
 
 	return 0;
 }
@@ -755,8 +720,6 @@ static int dwapb_gpio_suspend(struct device *dev)
 		unsigned int idx = gpio->ports[i].idx;
 		struct dwapb_context *ctx = gpio->ports[i].ctx;
 
-		BUG_ON(!ctx);
-
 		offset = GPIO_SWPORTA_DDR + idx * GPIO_SWPORT_DDR_STRIDE;
 		ctx->dir = dwapb_read(gpio, offset);
 
@@ -775,13 +738,12 @@ static int dwapb_gpio_suspend(struct device *dev)
 			ctx->int_deb	= dwapb_read(gpio, GPIO_PORTA_DEBOUNCE);
 
 			/* Mask out interrupts */
-			dwapb_write(gpio, GPIO_INTMASK,
-				    0xffffffff & ~ctx->wake_en);
+			dwapb_write(gpio, GPIO_INTMASK, 0xffffffff & ~ctx->wake_en);
 		}
 	}
 	spin_unlock_irqrestore(&gc->bgpio_lock, flags);
 
-	clk_disable_unprepare(gpio->clk);
+	clk_bulk_disable_unprepare(DWAPB_NR_CLOCKS, gpio->clks);
 
 	return 0;
 }
@@ -791,10 +753,13 @@ static int dwapb_gpio_resume(struct device *dev)
 	struct dwapb_gpio *gpio = dev_get_drvdata(dev);
 	struct gpio_chip *gc	= &gpio->ports[0].gc;
 	unsigned long flags;
-	int i;
+	int i, err;
 
-	if (!IS_ERR(gpio->clk))
-		clk_prepare_enable(gpio->clk);
+	err = clk_bulk_prepare_enable(DWAPB_NR_CLOCKS, gpio->clks);
+	if (err) {
+		dev_err(gpio->dev, "Cannot reenable APB/Debounce clocks\n");
+		return err;
+	}
 
 	spin_lock_irqsave(&gc->bgpio_lock, flags);
 	for (i = 0; i < gpio->nr_ports; i++) {
@@ -802,8 +767,6 @@ static int dwapb_gpio_resume(struct device *dev)
 		unsigned int idx = gpio->ports[i].idx;
 		struct dwapb_context *ctx = gpio->ports[i].ctx;
 
-		BUG_ON(!ctx);
-
 		offset = GPIO_SWPORTA_DR + idx * GPIO_SWPORT_DR_STRIDE;
 		dwapb_write(gpio, offset, ctx->data);
 
@@ -836,10 +799,10 @@ static SIMPLE_DEV_PM_OPS(dwapb_gpio_pm_ops, dwapb_gpio_suspend,
 
 static struct platform_driver dwapb_gpio_driver = {
 	.driver		= {
-		.name	= "gpio-dwapb",
+		.name	= DWAPB_DRIVER_NAME,
 		.pm	= &dwapb_gpio_pm_ops,
-		.of_match_table = of_match_ptr(dwapb_of_match),
-		.acpi_match_table = ACPI_PTR(dwapb_acpi_match),
+		.of_match_table = dwapb_of_match,
+		.acpi_match_table = dwapb_acpi_match,
 	},
 	.probe		= dwapb_gpio_probe,
 	.remove		= dwapb_gpio_remove,
@@ -850,3 +813,4 @@ module_platform_driver(dwapb_gpio_driver);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Jamie Iles");
 MODULE_DESCRIPTION("Synopsys DesignWare APB GPIO driver");
+MODULE_ALIAS("platform:" DWAPB_DRIVER_NAME);
diff --git a/drivers/gpio/gpio-mlxbf2.c b/drivers/gpio/gpio-mlxbf2.c
index 7b7085050219..240b488609ac 100644
--- a/drivers/gpio/gpio-mlxbf2.c
+++ b/drivers/gpio/gpio-mlxbf2.c
@@ -14,7 +14,6 @@
 #include <linux/resource.h>
 #include <linux/spinlock.h>
 #include <linux/types.h>
-#include <linux/version.h>
 
 /*
  * There are 3 YU GPIO blocks:
diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
index 5638b4e5355f..6317510b0dc3 100644
--- a/drivers/gpio/gpio-pca953x.c
+++ b/drivers/gpio/gpio-pca953x.c
@@ -115,6 +115,7 @@ MODULE_DEVICE_TABLE(acpi, pca953x_acpi_ids);
 
 #define MAX_BANK 5
 #define BANK_SZ 8
+#define BANK_SFT 3 /* ilog2(BANK_SZ) */
 #define MAX_LINE	(MAX_BANK * BANK_SZ)
 
 #define NBANK(chip) DIV_ROUND_UP(chip->gpio_chip.ngpio, BANK_SZ)
@@ -466,6 +467,41 @@ static int pca953x_gpio_get_direction(struct gpio_chip *gc, unsigned off)
 	return GPIO_LINE_DIRECTION_OUT;
 }
 
+static int pca953x_gpio_get_multiple(struct gpio_chip *gc,
+				      unsigned long *mask, unsigned long *bits)
+{
+	struct pca953x_chip *chip = gpiochip_get_data(gc);
+	unsigned int reg_val;
+	int offset, value, i, ret = 0;
+	u8 inreg;
+
+	/* Force offset outside the range of i so that
+	 * at least the first relevant register is read
+	 */
+	offset = gc->ngpio;
+	for_each_set_bit(i, mask, gc->ngpio) {
+		/* whenever i goes into a new bank update inreg
+		 * and read the register
+		 */
+		if ((offset >> BANK_SFT) != (i >> BANK_SFT)) {
+			offset = i;
+			inreg = pca953x_recalc_addr(chip, chip->regs->input,
+						    offset, true, false);
+			mutex_lock(&chip->i2c_lock);
+			ret = regmap_read(chip->regmap, inreg, &reg_val);
+			mutex_unlock(&chip->i2c_lock);
+			if (ret < 0)
+				return ret;
+		}
+		/* reg_val is relative to the last read byte,
+		 * so only shift the relative bits
+		 */
+		value = (reg_val >> (i % 8)) & 0x01;
+		__assign_bit(i, bits, value);
+	}
+	return ret;
+}
+
 static void pca953x_gpio_set_multiple(struct gpio_chip *gc,
 				      unsigned long *mask, unsigned long *bits)
 {
@@ -551,6 +587,7 @@ static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios)
 	gc->get = pca953x_gpio_get_value;
 	gc->set = pca953x_gpio_set_value;
 	gc->get_direction = pca953x_gpio_get_direction;
+	gc->get_multiple = pca953x_gpio_get_multiple;
 	gc->set_multiple = pca953x_gpio_set_multiple;
 	gc->set_config = pca953x_gpio_set_config;
 	gc->can_sleep = true;
diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c
index e241fb884c12..f1b53dd1df1a 100644
--- a/drivers/gpio/gpio-pl061.c
+++ b/drivers/gpio/gpio-pl061.c
@@ -16,6 +16,7 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/irqchip/chained_irq.h>
+#include <linux/module.h>
 #include <linux/bitops.h>
 #include <linux/gpio/driver.h>
 #include <linux/device.h>
@@ -408,6 +409,7 @@ static const struct amba_id pl061_ids[] = {
 	},
 	{ 0, 0 },
 };
+MODULE_DEVICE_TABLE(amba, pl061_ids);
 
 static struct amba_driver pl061_gpio_driver = {
 	.drv = {
@@ -419,9 +421,6 @@ static struct amba_driver pl061_gpio_driver = {
 	.id_table	= pl061_ids,
 	.probe		= pl061_probe,
 };
+module_amba_driver(pl061_gpio_driver);
 
-static int __init pl061_gpio_init(void)
-{
-	return amba_driver_register(&pl061_gpio_driver);
-}
-device_initcall(pl061_gpio_init);
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpio/gpio-xgene-sb.c b/drivers/gpio/gpio-xgene-sb.c
index 25d86441666e..b45bfa9baa26 100644
--- a/drivers/gpio/gpio-xgene-sb.c
+++ b/drivers/gpio/gpio-xgene-sb.c
@@ -122,7 +122,7 @@ static int xgene_gpio_sb_to_irq(struct gpio_chip *gc, u32 gpio)
 	fwspec.fwnode = gc->parent->fwnode;
 	fwspec.param_count = 2;
 	fwspec.param[0] = GPIO_TO_HWIRQ(priv, gpio);
-	fwspec.param[1] = IRQ_TYPE_NONE;
+	fwspec.param[1] = IRQ_TYPE_EDGE_RISING;
 	return irq_create_fwspec_mapping(&fwspec);
 }
 
diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
index 0017367e94ee..9276051663da 100644
--- a/drivers/gpio/gpiolib-acpi.c
+++ b/drivers/gpio/gpiolib-acpi.c
@@ -1353,7 +1353,7 @@ int acpi_gpio_count(struct device *dev, const char *con_id)
 }
 
 /* Run deferred acpi_gpiochip_request_irqs() */
-static int acpi_gpio_handle_deferred_request_irqs(void)
+static int __init acpi_gpio_handle_deferred_request_irqs(void)
 {
 	struct acpi_gpio_chip *acpi_gpio, *tmp;
 
@@ -1371,7 +1371,7 @@ static int acpi_gpio_handle_deferred_request_irqs(void)
 /* We must use _sync so that this runs after the first deferred_probe run */
 late_initcall_sync(acpi_gpio_handle_deferred_request_irqs);
 
-static const struct dmi_system_id gpiolib_acpi_quirks[] = {
+static const struct dmi_system_id gpiolib_acpi_quirks[] __initconst = {
 	{
 		/*
 		 * The Minix Neo Z83-4 has a micro-USB-B id-pin handler for
@@ -1455,7 +1455,7 @@ static const struct dmi_system_id gpiolib_acpi_quirks[] = {
 	{} /* Terminating entry */
 };
 
-static int acpi_gpio_setup_params(void)
+static int __init acpi_gpio_setup_params(void)
 {
 	const struct acpi_gpiolib_dmi_quirk *quirk = NULL;
 	const struct dmi_system_id *id;
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index ccc449df3792..2c5dd1349f16 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -344,6 +344,12 @@ struct gpio_desc *gpiod_get_from_of_node(struct device_node *node,
 	if (transitory)
 		lflags |= GPIO_TRANSITORY;
 
+	if (flags & OF_GPIO_PULL_UP)
+		lflags |= GPIO_PULL_UP;
+
+	if (flags & OF_GPIO_PULL_DOWN)
+		lflags |= GPIO_PULL_DOWN;
+
 	ret = gpiod_configure_flags(desc, propname, lflags, dflags);
 	if (ret < 0) {
 		gpiod_put(desc);
@@ -585,6 +591,10 @@ static struct gpio_desc *of_parse_own_gpio(struct device_node *np,
 		*lflags |= GPIO_ACTIVE_LOW;
 	if (xlate_flags & OF_GPIO_TRANSITORY)
 		*lflags |= GPIO_TRANSITORY;
+	if (xlate_flags & OF_GPIO_PULL_UP)
+		*lflags |= GPIO_PULL_UP;
+	if (xlate_flags & OF_GPIO_PULL_DOWN)
+		*lflags |= GPIO_PULL_DOWN;
 
 	if (of_property_read_bool(np, "input"))
 		*dflags |= GPIOD_IN;
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 7f72ef5e7811..f34d08c83485 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -17,7 +17,8 @@ drm-y       :=	drm_auth.o drm_cache.o \
 		drm_plane.o drm_color_mgmt.o drm_print.o \
 		drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \
 		drm_syncobj.o drm_lease.o drm_writeback.o drm_client.o \
-		drm_client_modeset.o drm_atomic_uapi.o drm_hdcp.o
+		drm_client_modeset.o drm_atomic_uapi.o drm_hdcp.o \
+		drm_managed.o
 
 drm-$(CONFIG_DRM_LEGACY) += drm_legacy_misc.o drm_bufs.o drm_context.o drm_dma.o drm_scatter.o drm_lock.o
 drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o
@@ -32,8 +33,7 @@ drm-$(CONFIG_PCI) += drm_pci.o
 drm-$(CONFIG_DEBUG_FS) += drm_debugfs.o drm_debugfs_crc.o
 drm-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
 
-drm_vram_helper-y := drm_gem_vram_helper.o \
-		     drm_vram_helper_common.o
+drm_vram_helper-y := drm_gem_vram_helper.o
 obj-$(CONFIG_DRM_VRAM_HELPER) += drm_vram_helper.o
 
 drm_ttm_helper-y := drm_gem_ttm_helper.o
diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile
index c2bbcdd9c875..210d57a4afc8 100644
--- a/drivers/gpu/drm/amd/amdgpu/Makefile
+++ b/drivers/gpu/drm/amd/amdgpu/Makefile
@@ -55,7 +55,7 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \
 	amdgpu_vf_error.o amdgpu_sched.o amdgpu_debugfs.o amdgpu_ids.o \
 	amdgpu_gmc.o amdgpu_mmhub.o amdgpu_xgmi.o amdgpu_csa.o amdgpu_ras.o amdgpu_vm_cpu.o \
 	amdgpu_vm_sdma.o amdgpu_discovery.o amdgpu_ras_eeprom.o amdgpu_nbio.o \
-	amdgpu_umc.o smu_v11_0_i2c.o
+	amdgpu_umc.o smu_v11_0_i2c.o amdgpu_fru_eeprom.o
 
 amdgpu-$(CONFIG_PERF_EVENTS) += amdgpu_pmu.o
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 2992a49ad4a5..4223b8eecaab 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -28,6 +28,18 @@
 #ifndef __AMDGPU_H__
 #define __AMDGPU_H__
 
+#ifdef pr_fmt
+#undef pr_fmt
+#endif
+
+#define pr_fmt(fmt) "amdgpu: " fmt
+
+#ifdef dev_fmt
+#undef dev_fmt
+#endif
+
+#define dev_fmt(fmt) "amdgpu: " fmt
+
 #include "amdgpu_ctx.h"
 
 #include <linux/atomic.h>
@@ -177,6 +189,8 @@ extern int sched_policy;
 static const int sched_policy = KFD_SCHED_POLICY_HWS;
 #endif
 
+extern int amdgpu_tmz;
+
 #ifdef CONFIG_DRM_AMDGPU_SI
 extern int amdgpu_si_support;
 #endif
@@ -190,8 +204,6 @@ extern int amdgpu_cik_support;
 #define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS	        3000
 #define AMDGPU_MAX_USEC_TIMEOUT			100000	/* 100 ms */
 #define AMDGPU_FENCE_JIFFIES_TIMEOUT		(HZ / 2)
-/* AMDGPU_IB_POOL_SIZE must be a power of 2 */
-#define AMDGPU_IB_POOL_SIZE			16
 #define AMDGPU_DEBUGFS_MAX_COMPONENTS		32
 #define AMDGPUFB_CONN_LIMIT			4
 #define AMDGPU_BIOS_NUM_SCRATCH			16
@@ -439,7 +451,9 @@ struct amdgpu_fpriv {
 int amdgpu_file_to_fpriv(struct file *filp, struct amdgpu_fpriv **fpriv);
 
 int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm,
-		  unsigned size, struct amdgpu_ib *ib);
+		  unsigned size,
+		  enum amdgpu_ib_pool_type pool,
+		  struct amdgpu_ib *ib);
 void amdgpu_ib_free(struct amdgpu_device *adev, struct amdgpu_ib *ib,
 		    struct dma_fence *f);
 int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
@@ -843,7 +857,8 @@ struct amdgpu_device {
 	unsigned			num_rings;
 	struct amdgpu_ring		*rings[AMDGPU_MAX_RINGS];
 	bool				ib_pool_ready;
-	struct amdgpu_sa_manager	ring_tmp_bo;
+	struct amdgpu_sa_manager	ib_pools[AMDGPU_IB_POOL_MAX];
+	struct amdgpu_sched		gpu_sched[AMDGPU_HW_IP_NUM][AMDGPU_RING_PRIO_MAX];
 
 	/* interrupts */
 	struct amdgpu_irq		irq;
@@ -923,7 +938,7 @@ struct amdgpu_device {
 	atomic64_t gart_pin_size;
 
 	/* soc15 register offset based on ip, instance and  segment */
-	uint32_t 		*reg_offset[MAX_HWIP][HWIP_MAX_INSTANCE];
+	uint32_t		*reg_offset[MAX_HWIP][HWIP_MAX_INSTANCE];
 
 	/* delayed work_func for deferring clockgating during resume */
 	struct delayed_work     delayed_init_work;
@@ -946,8 +961,6 @@ struct amdgpu_device {
 	/* s3/s4 mask */
 	bool                            in_suspend;
 
-	/* record last mm index being written through WREG32*/
-	unsigned long last_mm_index;
 	bool                            in_gpu_reset;
 	enum pp_mp1_state               mp1_state;
 	struct mutex  lock_reset;
@@ -974,6 +987,11 @@ struct amdgpu_device {
 
 	bool                            pm_sysfs_en;
 	bool                            ucode_sysfs_en;
+
+	/* Chip product information */
+	char				product_number[16];
+	char				product_name[32];
+	char				serial[16];
 };
 
 static inline struct amdgpu_device *amdgpu_ttm_adev(struct ttm_bo_device *bdev)
@@ -990,10 +1008,10 @@ int amdgpu_gpu_wait_for_idle(struct amdgpu_device *adev);
 
 void amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
 			       uint32_t *buf, size_t size, bool write);
-uint32_t amdgpu_mm_rreg(struct amdgpu_device *adev, uint32_t reg,
+uint32_t amdgpu_device_rreg(struct amdgpu_device *adev, uint32_t reg,
+			    uint32_t acc_flags);
+void amdgpu_device_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
 			uint32_t acc_flags);
-void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
-		    uint32_t acc_flags);
 void amdgpu_mm_wreg_mmio_rlc(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
 		    uint32_t acc_flags);
 void amdgpu_mm_wreg8(struct amdgpu_device *adev, uint32_t offset, uint8_t value);
@@ -1010,25 +1028,20 @@ int emu_soc_asic_init(struct amdgpu_device *adev);
 /*
  * Registers read & write functions.
  */
-
-#define AMDGPU_REGS_IDX       (1<<0)
 #define AMDGPU_REGS_NO_KIQ    (1<<1)
-#define AMDGPU_REGS_KIQ       (1<<2)
 
-#define RREG32_NO_KIQ(reg) amdgpu_mm_rreg(adev, (reg), AMDGPU_REGS_NO_KIQ)
-#define WREG32_NO_KIQ(reg, v) amdgpu_mm_wreg(adev, (reg), (v), AMDGPU_REGS_NO_KIQ)
+#define RREG32_NO_KIQ(reg) amdgpu_device_rreg(adev, (reg), AMDGPU_REGS_NO_KIQ)
+#define WREG32_NO_KIQ(reg, v) amdgpu_device_wreg(adev, (reg), (v), AMDGPU_REGS_NO_KIQ)
 
-#define RREG32_KIQ(reg) amdgpu_mm_rreg(adev, (reg), AMDGPU_REGS_KIQ)
-#define WREG32_KIQ(reg, v) amdgpu_mm_wreg(adev, (reg), (v), AMDGPU_REGS_KIQ)
+#define RREG32_KIQ(reg) amdgpu_kiq_rreg(adev, (reg))
+#define WREG32_KIQ(reg, v) amdgpu_kiq_wreg(adev, (reg), (v))
 
 #define RREG8(reg) amdgpu_mm_rreg8(adev, (reg))
 #define WREG8(reg, v) amdgpu_mm_wreg8(adev, (reg), (v))
 
-#define RREG32(reg) amdgpu_mm_rreg(adev, (reg), 0)
-#define RREG32_IDX(reg) amdgpu_mm_rreg(adev, (reg), AMDGPU_REGS_IDX)
-#define DREG32(reg) printk(KERN_INFO "REGISTER: " #reg " : 0x%08X\n", amdgpu_mm_rreg(adev, (reg), 0))
-#define WREG32(reg, v) amdgpu_mm_wreg(adev, (reg), (v), 0)
-#define WREG32_IDX(reg, v) amdgpu_mm_wreg(adev, (reg), (v), AMDGPU_REGS_IDX)
+#define RREG32(reg) amdgpu_device_rreg(adev, (reg), 0)
+#define DREG32(reg) printk(KERN_INFO "REGISTER: " #reg " : 0x%08X\n", amdgpu_device_rreg(adev, (reg), 0))
+#define WREG32(reg, v) amdgpu_device_wreg(adev, (reg), (v), 0)
 #define REG_SET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK)
 #define REG_GET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK)
 #define RREG32_PCIE(reg) adev->pcie_rreg(adev, (reg))
@@ -1065,7 +1078,7 @@ int emu_soc_asic_init(struct amdgpu_device *adev);
 		tmp_ |= ((val) & ~(mask));			\
 		WREG32_PLL(reg, tmp_);				\
 	} while (0)
-#define DREG32_SYS(sqf, adev, reg) seq_printf((sqf), #reg " : 0x%08X\n", amdgpu_mm_rreg((adev), (reg), false))
+#define DREG32_SYS(sqf, adev, reg) seq_printf((sqf), #reg " : 0x%08X\n", amdgpu_device_rreg((adev), (reg), false))
 #define RREG32_IO(reg) amdgpu_io_rreg(adev, (reg))
 #define WREG32_IO(reg, v) amdgpu_io_wreg(adev, (reg), (v))
 
@@ -1248,5 +1261,9 @@ _name##_show(struct device *dev,					\
 									\
 static struct device_attribute pmu_attr_##_name = __ATTR_RO(_name)
 
-#endif
+static inline bool amdgpu_is_tmz(struct amdgpu_device *adev)
+{
+       return adev->gmc.tmz_enabled;
+}
 
+#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c
index 4ec6d0c03201..691c89705bcd 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c
@@ -543,6 +543,9 @@ static int kgd_hqd_destroy(struct kgd_dev *kgd, void *mqd,
 	uint32_t temp;
 	struct v10_compute_mqd *m = get_mqd(mqd);
 
+	if (adev->in_gpu_reset)
+		return -EIO;
+
 #if 0
 	unsigned long flags;
 	int retry;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index 9dff792c9290..d7df11b07d11 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -362,13 +362,13 @@ static int vm_validate_pt_pd_bos(struct amdgpu_vm *vm)
 	ret = amdgpu_vm_validate_pt_bos(adev, vm, amdgpu_amdkfd_validate,
 					&param);
 	if (ret) {
-		pr_err("amdgpu: failed to validate PT BOs\n");
+		pr_err("failed to validate PT BOs\n");
 		return ret;
 	}
 
 	ret = amdgpu_amdkfd_validate(&param, pd);
 	if (ret) {
-		pr_err("amdgpu: failed to validate PD\n");
+		pr_err("failed to validate PD\n");
 		return ret;
 	}
 
@@ -377,7 +377,7 @@ static int vm_validate_pt_pd_bos(struct amdgpu_vm *vm)
 	if (vm->use_cpu_for_update) {
 		ret = amdgpu_bo_kmap(pd, NULL);
 		if (ret) {
-			pr_err("amdgpu: failed to kmap PD, ret=%d\n", ret);
+			pr_err("failed to kmap PD, ret=%d\n", ret);
 			return ret;
 		}
 	}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c
index d1495e1c9289..d9b35df33806 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c
@@ -40,7 +40,7 @@ static int amdgpu_benchmark_do_move(struct amdgpu_device *adev, unsigned size,
 	for (i = 0; i < n; i++) {
 		struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
 		r = amdgpu_copy_buffer(ring, saddr, daddr, size, NULL, &fence,
-				       false, false);
+				       false, false, false);
 		if (r)
 			goto exit_do_move;
 		r = dma_fence_wait(fence, false);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
index 031b094607bd..78ac6dbe70d8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
@@ -60,8 +60,6 @@ static uint32_t amdgpu_cgs_read_ind_register(struct cgs_device *cgs_device,
 {
 	CGS_FUNC_ADEV;
 	switch (space) {
-	case CGS_IND_REG__MMIO:
-		return RREG32_IDX(index);
 	case CGS_IND_REG__PCIE:
 		return RREG32_PCIE(index);
 	case CGS_IND_REG__SMC:
@@ -77,6 +75,8 @@ static uint32_t amdgpu_cgs_read_ind_register(struct cgs_device *cgs_device,
 	case CGS_IND_REG__AUDIO_ENDPT:
 		DRM_ERROR("audio endpt register access not implemented.\n");
 		return 0;
+	default:
+		BUG();
 	}
 	WARN(1, "Invalid indirect register space");
 	return 0;
@@ -88,8 +88,6 @@ static void amdgpu_cgs_write_ind_register(struct cgs_device *cgs_device,
 {
 	CGS_FUNC_ADEV;
 	switch (space) {
-	case CGS_IND_REG__MMIO:
-		return WREG32_IDX(index, value);
 	case CGS_IND_REG__PCIE:
 		return WREG32_PCIE(index, value);
 	case CGS_IND_REG__SMC:
@@ -105,6 +103,8 @@ static void amdgpu_cgs_write_ind_register(struct cgs_device *cgs_device,
 	case CGS_IND_REG__AUDIO_ENDPT:
 		DRM_ERROR("audio endpt register access not implemented.\n");
 		return;
+	default:
+		BUG();
 	}
 	WARN(1, "Invalid indirect register space");
 }
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index af91627b19b0..7653f62b1b2d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -924,7 +924,8 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev,
 
 		ring = to_amdgpu_ring(entity->rq->sched);
 		r =  amdgpu_ib_get(adev, vm, ring->funcs->parse_cs ?
-				   chunk_ib->ib_bytes : 0, ib);
+				   chunk_ib->ib_bytes : 0,
+				   AMDGPU_IB_POOL_DELAYED, ib);
 		if (r) {
 			DRM_ERROR("Failed to get ib !\n");
 			return r;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
index 6ed36a2c5f73..8842c55d4490 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
@@ -26,6 +26,7 @@
 #include "amdgpu.h"
 #include "amdgpu_sched.h"
 #include "amdgpu_ras.h"
+#include <linux/nospec.h>
 
 #define to_amdgpu_ctx_entity(e)	\
 	container_of((e), struct amdgpu_ctx_entity, entity)
@@ -72,13 +73,30 @@ static enum gfx_pipe_priority amdgpu_ctx_sched_prio_to_compute_prio(enum drm_sch
 	}
 }
 
-static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, const u32 hw_ip, const u32 ring)
+static unsigned int amdgpu_ctx_prio_sched_to_hw(struct amdgpu_device *adev,
+						 enum drm_sched_priority prio,
+						 u32 hw_ip)
+{
+	unsigned int hw_prio;
+
+	hw_prio = (hw_ip == AMDGPU_HW_IP_COMPUTE) ?
+			amdgpu_ctx_sched_prio_to_compute_prio(prio) :
+			AMDGPU_RING_PRIO_DEFAULT;
+	hw_ip = array_index_nospec(hw_ip, AMDGPU_HW_IP_NUM);
+	if (adev->gpu_sched[hw_ip][hw_prio].num_scheds == 0)
+		hw_prio = AMDGPU_RING_PRIO_DEFAULT;
+
+	return hw_prio;
+}
+
+static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, u32 hw_ip,
+				   const u32 ring)
 {
 	struct amdgpu_device *adev = ctx->adev;
 	struct amdgpu_ctx_entity *entity;
 	struct drm_gpu_scheduler **scheds = NULL, *sched = NULL;
 	unsigned num_scheds = 0;
-	enum gfx_pipe_priority hw_prio;
+	unsigned int hw_prio;
 	enum drm_sched_priority priority;
 	int r;
 
@@ -90,52 +108,16 @@ static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, const u32 hw_ip, const
 	entity->sequence = 1;
 	priority = (ctx->override_priority == DRM_SCHED_PRIORITY_UNSET) ?
 				ctx->init_priority : ctx->override_priority;
-	switch (hw_ip) {
-	case AMDGPU_HW_IP_GFX:
-		sched = &adev->gfx.gfx_ring[0].sched;
-		scheds = &sched;
-		num_scheds = 1;
-		break;
-	case AMDGPU_HW_IP_COMPUTE:
-		hw_prio = amdgpu_ctx_sched_prio_to_compute_prio(priority);
-		scheds = adev->gfx.compute_prio_sched[hw_prio];
-		num_scheds = adev->gfx.num_compute_sched[hw_prio];
-		break;
-	case AMDGPU_HW_IP_DMA:
-		scheds = adev->sdma.sdma_sched;
-		num_scheds = adev->sdma.num_sdma_sched;
-		break;
-	case AMDGPU_HW_IP_UVD:
-		sched = &adev->uvd.inst[0].ring.sched;
-		scheds = &sched;
-		num_scheds = 1;
-		break;
-	case AMDGPU_HW_IP_VCE:
-		sched = &adev->vce.ring[0].sched;
-		scheds = &sched;
-		num_scheds = 1;
-		break;
-	case AMDGPU_HW_IP_UVD_ENC:
-		sched = &adev->uvd.inst[0].ring_enc[0].sched;
-		scheds = &sched;
-		num_scheds = 1;
-		break;
-	case AMDGPU_HW_IP_VCN_DEC:
-		sched = drm_sched_pick_best(adev->vcn.vcn_dec_sched,
-					    adev->vcn.num_vcn_dec_sched);
-		scheds = &sched;
-		num_scheds = 1;
-		break;
-	case AMDGPU_HW_IP_VCN_ENC:
-		sched = drm_sched_pick_best(adev->vcn.vcn_enc_sched,
-					    adev->vcn.num_vcn_enc_sched);
+	hw_prio = amdgpu_ctx_prio_sched_to_hw(adev, priority, hw_ip);
+
+	hw_ip = array_index_nospec(hw_ip, AMDGPU_HW_IP_NUM);
+	scheds = adev->gpu_sched[hw_ip][hw_prio].sched;
+	num_scheds = adev->gpu_sched[hw_ip][hw_prio].num_scheds;
+
+	if (hw_ip == AMDGPU_HW_IP_VCN_ENC || hw_ip == AMDGPU_HW_IP_VCN_DEC) {
+		sched = drm_sched_pick_best(scheds, num_scheds);
 		scheds = &sched;
 		num_scheds = 1;
-		break;
-	case AMDGPU_HW_IP_VCN_JPEG:
-		scheds = adev->jpeg.jpeg_sched;
-		num_scheds =  adev->jpeg.num_jpeg_sched;
-		break;
 	}
 
 	r = drm_sched_entity_init(&entity->entity, priority, scheds, num_scheds,
@@ -178,7 +160,6 @@ static int amdgpu_ctx_init(struct amdgpu_device *adev,
 	ctx->override_priority = DRM_SCHED_PRIORITY_UNSET;
 
 	return 0;
-
 }
 
 static void amdgpu_ctx_fini_entity(struct amdgpu_ctx_entity *entity)
@@ -525,7 +506,7 @@ static void amdgpu_ctx_set_entity_priority(struct amdgpu_ctx *ctx,
 					    enum drm_sched_priority priority)
 {
 	struct amdgpu_device *adev = ctx->adev;
-	enum gfx_pipe_priority hw_prio;
+	unsigned int hw_prio;
 	struct drm_gpu_scheduler **scheds = NULL;
 	unsigned num_scheds;
 
@@ -534,9 +515,11 @@ static void amdgpu_ctx_set_entity_priority(struct amdgpu_ctx *ctx,
 
 	/* set hw priority */
 	if (hw_ip == AMDGPU_HW_IP_COMPUTE) {
-		hw_prio = amdgpu_ctx_sched_prio_to_compute_prio(priority);
-		scheds = adev->gfx.compute_prio_sched[hw_prio];
-		num_scheds = adev->gfx.num_compute_sched[hw_prio];
+		hw_prio = amdgpu_ctx_prio_sched_to_hw(adev, priority,
+						      AMDGPU_HW_IP_COMPUTE);
+		hw_prio = array_index_nospec(hw_prio, AMDGPU_RING_PRIO_MAX);
+		scheds = adev->gpu_sched[hw_ip][hw_prio].sched;
+		num_scheds = adev->gpu_sched[hw_ip][hw_prio].num_scheds;
 		drm_sched_entity_modify_sched(&aentity->entity, scheds,
 					      num_scheds);
 	}
@@ -665,78 +648,3 @@ void amdgpu_ctx_mgr_fini(struct amdgpu_ctx_mgr *mgr)
 	idr_destroy(&mgr->ctx_handles);
 	mutex_destroy(&mgr->lock);
 }
-
-
-static void amdgpu_ctx_init_compute_sched(struct amdgpu_device *adev)
-{
-	int num_compute_sched_normal = 0;
-	int num_compute_sched_high = AMDGPU_MAX_COMPUTE_RINGS - 1;
-	int i;
-
-	/* use one drm sched array, gfx.compute_sched to store both high and
-	 * normal priority drm compute schedulers */
-	for (i = 0; i < adev->gfx.num_compute_rings; i++) {
-		if (!adev->gfx.compute_ring[i].has_high_prio)
-			adev->gfx.compute_sched[num_compute_sched_normal++] =
-				&adev->gfx.compute_ring[i].sched;
-		else
-			adev->gfx.compute_sched[num_compute_sched_high--] =
-				&adev->gfx.compute_ring[i].sched;
-	}
-
-	/* compute ring only has two priority for now */
-	i = AMDGPU_GFX_PIPE_PRIO_NORMAL;
-	adev->gfx.compute_prio_sched[i] = &adev->gfx.compute_sched[0];
-	adev->gfx.num_compute_sched[i] = num_compute_sched_normal;
-
-	i = AMDGPU_GFX_PIPE_PRIO_HIGH;
-	if (num_compute_sched_high == (AMDGPU_MAX_COMPUTE_RINGS - 1)) {
-		/* When compute has no high priority rings then use */
-		/* normal priority sched array */
-		adev->gfx.compute_prio_sched[i] = &adev->gfx.compute_sched[0];
-		adev->gfx.num_compute_sched[i] = num_compute_sched_normal;
-	} else {
-		adev->gfx.compute_prio_sched[i] =
-			&adev->gfx.compute_sched[num_compute_sched_high - 1];
-		adev->gfx.num_compute_sched[i] =
-			adev->gfx.num_compute_rings - num_compute_sched_normal;
-	}
-}
-
-void amdgpu_ctx_init_sched(struct amdgpu_device *adev)
-{
-	int i, j;
-
-	amdgpu_ctx_init_compute_sched(adev);
-	for (i = 0; i < adev->gfx.num_gfx_rings; i++) {
-		adev->gfx.gfx_sched[i] = &adev->gfx.gfx_ring[i].sched;
-		adev->gfx.num_gfx_sched++;
-	}
-
-	for (i = 0; i < adev->sdma.num_instances; i++) {
-		adev->sdma.sdma_sched[i] = &adev->sdma.instance[i].ring.sched;
-		adev->sdma.num_sdma_sched++;
-	}
-
-	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
-		if (adev->vcn.harvest_config & (1 << i))
-			continue;
-		adev->vcn.vcn_dec_sched[adev->vcn.num_vcn_dec_sched++] =
-			&adev->vcn.inst[i].ring_dec.sched;
-	}
-
-	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
-		if (adev->vcn.harvest_config & (1 << i))
-			continue;
-		for (j = 0; j < adev->vcn.num_enc_rings; ++j)
-			adev->vcn.vcn_enc_sched[adev->vcn.num_vcn_enc_sched++] =
-				&adev->vcn.inst[i].ring_enc[j].sched;
-	}
-
-	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
-		if (adev->jpeg.harvest_config & (1 << i))
-			continue;
-		adev->jpeg.jpeg_sched[adev->jpeg.num_jpeg_sched++] =
-			&adev->jpeg.inst[i].ring_dec.sched;
-	}
-}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h
index de490f183af2..f54e10314661 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h
@@ -88,7 +88,4 @@ void amdgpu_ctx_mgr_entity_fini(struct amdgpu_ctx_mgr *mgr);
 long amdgpu_ctx_mgr_entity_flush(struct amdgpu_ctx_mgr *mgr, long timeout);
 void amdgpu_ctx_mgr_fini(struct amdgpu_ctx_mgr *mgr);
 
-void amdgpu_ctx_init_sched(struct amdgpu_device *adev);
-
-
 #endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
index c0f9a651dc06..1a4894fa3693 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
@@ -152,11 +152,16 @@ static int  amdgpu_debugfs_process_reg_op(bool read, struct file *f,
 	if (r < 0)
 		return r;
 
+	r = amdgpu_virt_enable_access_debugfs(adev);
+	if (r < 0)
+		return r;
+
 	if (use_bank) {
 		if ((sh_bank != 0xFFFFFFFF && sh_bank >= adev->gfx.config.max_sh_per_se) ||
 		    (se_bank != 0xFFFFFFFF && se_bank >= adev->gfx.config.max_shader_engines)) {
 			pm_runtime_mark_last_busy(adev->ddev->dev);
 			pm_runtime_put_autosuspend(adev->ddev->dev);
+			amdgpu_virt_disable_access_debugfs(adev);
 			return -EINVAL;
 		}
 		mutex_lock(&adev->grbm_idx_mutex);
@@ -207,6 +212,7 @@ static int  amdgpu_debugfs_process_reg_op(bool read, struct file *f,
 	pm_runtime_mark_last_busy(adev->ddev->dev);
 	pm_runtime_put_autosuspend(adev->ddev->dev);
 
+	amdgpu_virt_disable_access_debugfs(adev);
 	return result;
 }
 
@@ -255,6 +261,10 @@ static ssize_t amdgpu_debugfs_regs_pcie_read(struct file *f, char __user *buf,
 	if (r < 0)
 		return r;
 
+	r = amdgpu_virt_enable_access_debugfs(adev);
+	if (r < 0)
+		return r;
+
 	while (size) {
 		uint32_t value;
 
@@ -263,6 +273,7 @@ static ssize_t amdgpu_debugfs_regs_pcie_read(struct file *f, char __user *buf,
 		if (r) {
 			pm_runtime_mark_last_busy(adev->ddev->dev);
 			pm_runtime_put_autosuspend(adev->ddev->dev);
+			amdgpu_virt_disable_access_debugfs(adev);
 			return r;
 		}
 
@@ -275,6 +286,7 @@ static ssize_t amdgpu_debugfs_regs_pcie_read(struct file *f, char __user *buf,
 	pm_runtime_mark_last_busy(adev->ddev->dev);
 	pm_runtime_put_autosuspend(adev->ddev->dev);
 
+	amdgpu_virt_disable_access_debugfs(adev);
 	return result;
 }
 
@@ -304,6 +316,10 @@ static ssize_t amdgpu_debugfs_regs_pcie_write(struct file *f, const char __user
 	if (r < 0)
 		return r;
 
+	r = amdgpu_virt_enable_access_debugfs(adev);
+	if (r < 0)
+		return r;
+
 	while (size) {
 		uint32_t value;
 
@@ -311,6 +327,7 @@ static ssize_t amdgpu_debugfs_regs_pcie_write(struct file *f, const char __user
 		if (r) {
 			pm_runtime_mark_last_busy(adev->ddev->dev);
 			pm_runtime_put_autosuspend(adev->ddev->dev);
+			amdgpu_virt_disable_access_debugfs(adev);
 			return r;
 		}
 
@@ -325,6 +342,7 @@ static ssize_t amdgpu_debugfs_regs_pcie_write(struct file *f, const char __user
 	pm_runtime_mark_last_busy(adev->ddev->dev);
 	pm_runtime_put_autosuspend(adev->ddev->dev);
 
+	amdgpu_virt_disable_access_debugfs(adev);
 	return result;
 }
 
@@ -354,6 +372,10 @@ static ssize_t amdgpu_debugfs_regs_didt_read(struct file *f, char __user *buf,
 	if (r < 0)
 		return r;
 
+	r = amdgpu_virt_enable_access_debugfs(adev);
+	if (r < 0)
+		return r;
+
 	while (size) {
 		uint32_t value;
 
@@ -362,6 +384,7 @@ static ssize_t amdgpu_debugfs_regs_didt_read(struct file *f, char __user *buf,
 		if (r) {
 			pm_runtime_mark_last_busy(adev->ddev->dev);
 			pm_runtime_put_autosuspend(adev->ddev->dev);
+			amdgpu_virt_disable_access_debugfs(adev);
 			return r;
 		}
 
@@ -374,6 +397,7 @@ static ssize_t amdgpu_debugfs_regs_didt_read(struct file *f, char __user *buf,
 	pm_runtime_mark_last_busy(adev->ddev->dev);
 	pm_runtime_put_autosuspend(adev->ddev->dev);
 
+	amdgpu_virt_disable_access_debugfs(adev);
 	return result;
 }
 
@@ -403,6 +427,10 @@ static ssize_t amdgpu_debugfs_regs_didt_write(struct file *f, const char __user
 	if (r < 0)
 		return r;
 
+	r = amdgpu_virt_enable_access_debugfs(adev);
+	if (r < 0)
+		return r;
+
 	while (size) {
 		uint32_t value;
 
@@ -410,6 +438,7 @@ static ssize_t amdgpu_debugfs_regs_didt_write(struct file *f, const char __user
 		if (r) {
 			pm_runtime_mark_last_busy(adev->ddev->dev);
 			pm_runtime_put_autosuspend(adev->ddev->dev);
+			amdgpu_virt_disable_access_debugfs(adev);
 			return r;
 		}
 
@@ -424,6 +453,7 @@ static ssize_t amdgpu_debugfs_regs_didt_write(struct file *f, const char __user
 	pm_runtime_mark_last_busy(adev->ddev->dev);
 	pm_runtime_put_autosuspend(adev->ddev->dev);
 
+	amdgpu_virt_disable_access_debugfs(adev);
 	return result;
 }
 
@@ -453,6 +483,10 @@ static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf,
 	if (r < 0)
 		return r;
 
+	r = amdgpu_virt_enable_access_debugfs(adev);
+	if (r < 0)
+		return r;
+
 	while (size) {
 		uint32_t value;
 
@@ -461,6 +495,7 @@ static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf,
 		if (r) {
 			pm_runtime_mark_last_busy(adev->ddev->dev);
 			pm_runtime_put_autosuspend(adev->ddev->dev);
+			amdgpu_virt_disable_access_debugfs(adev);
 			return r;
 		}
 
@@ -473,6 +508,7 @@ static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf,
 	pm_runtime_mark_last_busy(adev->ddev->dev);
 	pm_runtime_put_autosuspend(adev->ddev->dev);
 
+	amdgpu_virt_disable_access_debugfs(adev);
 	return result;
 }
 
@@ -502,6 +538,10 @@ static ssize_t amdgpu_debugfs_regs_smc_write(struct file *f, const char __user *
 	if (r < 0)
 		return r;
 
+	r = amdgpu_virt_enable_access_debugfs(adev);
+	if (r < 0)
+		return r;
+
 	while (size) {
 		uint32_t value;
 
@@ -509,6 +549,7 @@ static ssize_t amdgpu_debugfs_regs_smc_write(struct file *f, const char __user *
 		if (r) {
 			pm_runtime_mark_last_busy(adev->ddev->dev);
 			pm_runtime_put_autosuspend(adev->ddev->dev);
+			amdgpu_virt_disable_access_debugfs(adev);
 			return r;
 		}
 
@@ -523,6 +564,7 @@ static ssize_t amdgpu_debugfs_regs_smc_write(struct file *f, const char __user *
 	pm_runtime_mark_last_busy(adev->ddev->dev);
 	pm_runtime_put_autosuspend(adev->ddev->dev);
 
+	amdgpu_virt_disable_access_debugfs(adev);
 	return result;
 }
 
@@ -651,16 +693,24 @@ static ssize_t amdgpu_debugfs_sensor_read(struct file *f, char __user *buf,
 	if (r < 0)
 		return r;
 
+	r = amdgpu_virt_enable_access_debugfs(adev);
+	if (r < 0)
+		return r;
+
 	r = amdgpu_dpm_read_sensor(adev, idx, &values[0], &valuesize);
 
 	pm_runtime_mark_last_busy(adev->ddev->dev);
 	pm_runtime_put_autosuspend(adev->ddev->dev);
 
-	if (r)
+	if (r) {
+		amdgpu_virt_disable_access_debugfs(adev);
 		return r;
+	}
 
-	if (size > valuesize)
+	if (size > valuesize) {
+		amdgpu_virt_disable_access_debugfs(adev);
 		return -EINVAL;
+	}
 
 	outsize = 0;
 	x = 0;
@@ -673,6 +723,7 @@ static ssize_t amdgpu_debugfs_sensor_read(struct file *f, char __user *buf,
 		}
 	}
 
+	amdgpu_virt_disable_access_debugfs(adev);
 	return !r ? outsize : r;
 }
 
@@ -720,6 +771,10 @@ static ssize_t amdgpu_debugfs_wave_read(struct file *f, char __user *buf,
 	if (r < 0)
 		return r;
 
+	r = amdgpu_virt_enable_access_debugfs(adev);
+	if (r < 0)
+		return r;
+
 	/* switch to the specific se/sh/cu */
 	mutex_lock(&adev->grbm_idx_mutex);
 	amdgpu_gfx_select_se_sh(adev, se, sh, cu);
@@ -734,16 +789,20 @@ static ssize_t amdgpu_debugfs_wave_read(struct file *f, char __user *buf,
 	pm_runtime_mark_last_busy(adev->ddev->dev);
 	pm_runtime_put_autosuspend(adev->ddev->dev);
 
-	if (!x)
+	if (!x) {
+		amdgpu_virt_disable_access_debugfs(adev);
 		return -EINVAL;
+	}
 
 	while (size && (offset < x * 4)) {
 		uint32_t value;
 
 		value = data[offset >> 2];
 		r = put_user(value, (uint32_t *)buf);
-		if (r)
+		if (r) {
+			amdgpu_virt_disable_access_debugfs(adev);
 			return r;
+		}
 
 		result += 4;
 		buf += 4;
@@ -751,6 +810,7 @@ static ssize_t amdgpu_debugfs_wave_read(struct file *f, char __user *buf,
 		size -= 4;
 	}
 
+	amdgpu_virt_disable_access_debugfs(adev);
 	return result;
 }
 
@@ -805,6 +865,10 @@ static ssize_t amdgpu_debugfs_gpr_read(struct file *f, char __user *buf,
 	if (r < 0)
 		return r;
 
+	r = amdgpu_virt_enable_access_debugfs(adev);
+	if (r < 0)
+		return r;
+
 	/* switch to the specific se/sh/cu */
 	mutex_lock(&adev->grbm_idx_mutex);
 	amdgpu_gfx_select_se_sh(adev, se, sh, cu);
@@ -840,6 +904,7 @@ static ssize_t amdgpu_debugfs_gpr_read(struct file *f, char __user *buf,
 
 err:
 	kfree(data);
+	amdgpu_virt_disable_access_debugfs(adev);
 	return result;
 }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 559dc24ef436..ad1c66763dc1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -64,6 +64,7 @@
 #include "amdgpu_xgmi.h"
 #include "amdgpu_ras.h"
 #include "amdgpu_pmu.h"
+#include "amdgpu_fru_eeprom.h"
 
 #include <linux/suspend.h>
 #include <drm/task_barrier.h>
@@ -137,6 +138,72 @@ static DEVICE_ATTR(pcie_replay_count, S_IRUGO,
 
 static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev);
 
+/**
+ * DOC: product_name
+ *
+ * The amdgpu driver provides a sysfs API for reporting the product name
+ * for the device
+ * The file serial_number is used for this and returns the product name
+ * as returned from the FRU.
+ * NOTE: This is only available for certain server cards
+ */
+
+static ssize_t amdgpu_device_get_product_name(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct drm_device *ddev = dev_get_drvdata(dev);
+	struct amdgpu_device *adev = ddev->dev_private;
+
+	return snprintf(buf, PAGE_SIZE, "%s\n", adev->product_name);
+}
+
+static DEVICE_ATTR(product_name, S_IRUGO,
+		amdgpu_device_get_product_name, NULL);
+
+/**
+ * DOC: product_number
+ *
+ * The amdgpu driver provides a sysfs API for reporting the part number
+ * for the device
+ * The file serial_number is used for this and returns the part number
+ * as returned from the FRU.
+ * NOTE: This is only available for certain server cards
+ */
+
+static ssize_t amdgpu_device_get_product_number(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct drm_device *ddev = dev_get_drvdata(dev);
+	struct amdgpu_device *adev = ddev->dev_private;
+
+	return snprintf(buf, PAGE_SIZE, "%s\n", adev->product_number);
+}
+
+static DEVICE_ATTR(product_number, S_IRUGO,
+		amdgpu_device_get_product_number, NULL);
+
+/**
+ * DOC: serial_number
+ *
+ * The amdgpu driver provides a sysfs API for reporting the serial number
+ * for the device
+ * The file serial_number is used for this and returns the serial number
+ * as returned from the FRU.
+ * NOTE: This is only available for certain server cards
+ */
+
+static ssize_t amdgpu_device_get_serial_number(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct drm_device *ddev = dev_get_drvdata(dev);
+	struct amdgpu_device *adev = ddev->dev_private;
+
+	return snprintf(buf, PAGE_SIZE, "%s\n", adev->serial);
+}
+
+static DEVICE_ATTR(serial_number, S_IRUGO,
+		amdgpu_device_get_serial_number, NULL);
+
 /**
  * amdgpu_device_supports_boco - Is the device a dGPU with HG/PX power control
  *
@@ -187,32 +254,6 @@ void amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
 	uint32_t hi = ~0;
 	uint64_t last;
 
-
-#ifdef CONFIG_64BIT
-	last = min(pos + size, adev->gmc.visible_vram_size);
-	if (last > pos) {
-		void __iomem *addr = adev->mman.aper_base_kaddr + pos;
-		size_t count = last - pos;
-
-		if (write) {
-			memcpy_toio(addr, buf, count);
-			mb();
-			amdgpu_asic_flush_hdp(adev, NULL);
-		} else {
-			amdgpu_asic_invalidate_hdp(adev, NULL);
-			mb();
-			memcpy_fromio(buf, addr, count);
-		}
-
-		if (count == size)
-			return;
-
-		pos += count;
-		buf += count / 4;
-		size -= count;
-	}
-#endif
-
 	spin_lock_irqsave(&adev->mmio_idx_lock, flags);
 	for (last = pos + size; pos < last; pos += 4) {
 		uint32_t tmp = pos >> 31;
@@ -231,10 +272,10 @@ void amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
 }
 
 /*
- * MMIO register access helper functions.
+ * device register access helper functions.
  */
 /**
- * amdgpu_mm_rreg - read a memory mapped IO register
+ * amdgpu_device_rreg - read a register
  *
  * @adev: amdgpu_device pointer
  * @reg: dword aligned register offset
@@ -242,25 +283,19 @@ void amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
  *
  * Returns the 32 bit value from the offset specified.
  */
-uint32_t amdgpu_mm_rreg(struct amdgpu_device *adev, uint32_t reg,
-			uint32_t acc_flags)
+uint32_t amdgpu_device_rreg(struct amdgpu_device *adev, uint32_t reg,
+			    uint32_t acc_flags)
 {
 	uint32_t ret;
 
-	if ((acc_flags & AMDGPU_REGS_KIQ) || (!(acc_flags & AMDGPU_REGS_NO_KIQ) && amdgpu_sriov_runtime(adev)))
+	if (!(acc_flags & AMDGPU_REGS_NO_KIQ) && amdgpu_sriov_runtime(adev))
 		return amdgpu_kiq_rreg(adev, reg);
 
-	if ((reg * 4) < adev->rmmio_size && !(acc_flags & AMDGPU_REGS_IDX))
+	if ((reg * 4) < adev->rmmio_size)
 		ret = readl(((void __iomem *)adev->rmmio) + (reg * 4));
-	else {
-		unsigned long flags;
-
-		spin_lock_irqsave(&adev->mmio_idx_lock, flags);
-		writel((reg * 4), ((void __iomem *)adev->rmmio) + (mmMM_INDEX * 4));
-		ret = readl(((void __iomem *)adev->rmmio) + (mmMM_DATA * 4));
-		spin_unlock_irqrestore(&adev->mmio_idx_lock, flags);
-	}
-	trace_amdgpu_mm_rreg(adev->pdev->device, reg, ret);
+	else
+		ret = adev->pcie_rreg(adev, (reg * 4));
+	trace_amdgpu_device_rreg(adev->pdev->device, reg, ret);
 	return ret;
 }
 
@@ -306,28 +341,19 @@ void amdgpu_mm_wreg8(struct amdgpu_device *adev, uint32_t offset, uint8_t value)
 		BUG();
 }
 
-void static inline amdgpu_mm_wreg_mmio(struct amdgpu_device *adev, uint32_t reg, uint32_t v, uint32_t acc_flags)
+void static inline amdgpu_device_wreg_no_kiq(struct amdgpu_device *adev, uint32_t reg,
+					     uint32_t v, uint32_t acc_flags)
 {
-	trace_amdgpu_mm_wreg(adev->pdev->device, reg, v);
+	trace_amdgpu_device_wreg(adev->pdev->device, reg, v);
 
-	if ((reg * 4) < adev->rmmio_size && !(acc_flags & AMDGPU_REGS_IDX))
+	if ((reg * 4) < adev->rmmio_size)
 		writel(v, ((void __iomem *)adev->rmmio) + (reg * 4));
-	else {
-		unsigned long flags;
-
-		spin_lock_irqsave(&adev->mmio_idx_lock, flags);
-		writel((reg * 4), ((void __iomem *)adev->rmmio) + (mmMM_INDEX * 4));
-		writel(v, ((void __iomem *)adev->rmmio) + (mmMM_DATA * 4));
-		spin_unlock_irqrestore(&adev->mmio_idx_lock, flags);
-	}
-
-	if (adev->asic_type >= CHIP_VEGA10 && reg == 1 && adev->last_mm_index == 0x5702C) {
-		udelay(500);
-	}
+	else
+		adev->pcie_wreg(adev, (reg * 4), v);
 }
 
 /**
- * amdgpu_mm_wreg - write to a memory mapped IO register
+ * amdgpu_device_wreg - write to a register
  *
  * @adev: amdgpu_device pointer
  * @reg: dword aligned register offset
@@ -336,17 +362,13 @@ void static inline amdgpu_mm_wreg_mmio(struct amdgpu_device *adev, uint32_t reg,
  *
  * Writes the value specified to the offset specified.
  */
-void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
-		    uint32_t acc_flags)
+void amdgpu_device_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
+			uint32_t acc_flags)
 {
-	if (adev->asic_type >= CHIP_VEGA10 && reg == 0) {
-		adev->last_mm_index = v;
-	}
-
-	if ((acc_flags & AMDGPU_REGS_KIQ) || (!(acc_flags & AMDGPU_REGS_NO_KIQ) && amdgpu_sriov_runtime(adev)))
+	if (!(acc_flags & AMDGPU_REGS_NO_KIQ) && amdgpu_sriov_runtime(adev))
 		return amdgpu_kiq_wreg(adev, reg, v);
 
-	amdgpu_mm_wreg_mmio(adev, reg, v, acc_flags);
+	amdgpu_device_wreg_no_kiq(adev, reg, v, acc_flags);
 }
 
 /*
@@ -365,7 +387,7 @@ void amdgpu_mm_wreg_mmio_rlc(struct amdgpu_device *adev, uint32_t reg, uint32_t
 			return adev->gfx.rlc.funcs->rlcg_wreg(adev, reg, v);
 	}
 
-	amdgpu_mm_wreg_mmio(adev, reg, v, acc_flags);
+	amdgpu_device_wreg_no_kiq(adev, reg, v, acc_flags);
 }
 
 /**
@@ -397,20 +419,12 @@ u32 amdgpu_io_rreg(struct amdgpu_device *adev, u32 reg)
  */
 void amdgpu_io_wreg(struct amdgpu_device *adev, u32 reg, u32 v)
 {
-	if (adev->asic_type >= CHIP_VEGA10 && reg == 0) {
-		adev->last_mm_index = v;
-	}
-
 	if ((reg * 4) < adev->rio_mem_size)
 		iowrite32(v, adev->rio_mem + (reg * 4));
 	else {
 		iowrite32((reg * 4), adev->rio_mem + (mmMM_INDEX * 4));
 		iowrite32(v, adev->rio_mem + (mmMM_DATA * 4));
 	}
-
-	if (adev->asic_type >= CHIP_VEGA10 && reg == 1 && adev->last_mm_index == 0x5702C) {
-		udelay(500);
-	}
 }
 
 /**
@@ -1126,6 +1140,8 @@ static int amdgpu_device_check_arguments(struct amdgpu_device *adev)
 
 	adev->firmware.load_type = amdgpu_ucode_get_load_type(adev, amdgpu_fw_load_type);
 
+	amdgpu_gmc_tmz_set(adev);
+
 	return 0;
 }
 
@@ -1147,7 +1163,7 @@ static void amdgpu_switcheroo_set_state(struct pci_dev *pdev, enum vga_switchero
 		return;
 
 	if (state == VGA_SWITCHEROO_ON) {
-		pr_info("amdgpu: switched on\n");
+		pr_info("switched on\n");
 		/* don't suspend or resume card normally */
 		dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
 
@@ -1161,7 +1177,7 @@ static void amdgpu_switcheroo_set_state(struct pci_dev *pdev, enum vga_switchero
 		dev->switch_power_state = DRM_SWITCH_POWER_ON;
 		drm_kms_helper_poll_enable(dev);
 	} else {
-		pr_info("amdgpu: switched off\n");
+		pr_info("switched off\n");
 		drm_kms_helper_poll_disable(dev);
 		dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
 		amdgpu_device_suspend(dev, true);
@@ -1731,9 +1747,28 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
 	amdgpu_amdkfd_device_probe(adev);
 
 	if (amdgpu_sriov_vf(adev)) {
+		/* handle vbios stuff prior full access mode for new handshake */
+		if (adev->virt.req_init_data_ver == 1) {
+			if (!amdgpu_get_bios(adev)) {
+				DRM_ERROR("failed to get vbios\n");
+				return -EINVAL;
+			}
+
+			r = amdgpu_atombios_init(adev);
+			if (r) {
+				dev_err(adev->dev, "amdgpu_atombios_init failed\n");
+				amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_ATOMBIOS_INIT_FAIL, 0, 0);
+				return r;
+			}
+		}
+	}
+
+	/* we need to send REQ_GPU here for legacy handshaker otherwise the vbios
+	 * will not be prepared by host for this VF */
+	if (amdgpu_sriov_vf(adev) && adev->virt.req_init_data_ver < 1) {
 		r = amdgpu_virt_request_full_gpu(adev, true);
 		if (r)
-			return -EAGAIN;
+			return r;
 	}
 
 	adev->pm.pp_feature = amdgpu_pp_feature_mask;
@@ -1763,6 +1798,10 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
 		}
 		/* get the vbios after the asic_funcs are set up */
 		if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_COMMON) {
+			/* skip vbios handling for new handshake */
+			if (amdgpu_sriov_vf(adev) && adev->virt.req_init_data_ver == 1)
+				continue;
+
 			/* Read BIOS */
 			if (!amdgpu_get_bios(adev))
 				return -EINVAL;
@@ -1889,6 +1928,12 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
 	if (r)
 		return r;
 
+	if (amdgpu_sriov_vf(adev) && adev->virt.req_init_data_ver > 0) {
+		r = amdgpu_virt_request_full_gpu(adev, true);
+		if (r)
+			return -EAGAIN;
+	}
+
 	for (i = 0; i < adev->num_ip_blocks; i++) {
 		if (!adev->ip_blocks[i].status.valid)
 			continue;
@@ -1975,6 +2020,8 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
 		amdgpu_xgmi_add_device(adev);
 	amdgpu_amdkfd_device_init(adev);
 
+	amdgpu_fru_get_product_info(adev);
+
 init_failed:
 	if (amdgpu_sriov_vf(adev))
 		amdgpu_virt_release_full_gpu(adev, true);
@@ -2008,8 +2055,24 @@ static void amdgpu_device_fill_reset_magic(struct amdgpu_device *adev)
  */
 static bool amdgpu_device_check_vram_lost(struct amdgpu_device *adev)
 {
-	return !!memcmp(adev->gart.ptr, adev->reset_magic,
-			AMDGPU_RESET_MAGIC_NUM);
+	if (memcmp(adev->gart.ptr, adev->reset_magic,
+			AMDGPU_RESET_MAGIC_NUM))
+		return true;
+
+	if (!adev->in_gpu_reset)
+		return false;
+
+	/*
+	 * For all ASICs with baco/mode1 reset, the VRAM is
+	 * always assumed to be lost.
+	 */
+	switch (amdgpu_asic_reset_method(adev)) {
+	case AMD_RESET_METHOD_BACO:
+	case AMD_RESET_METHOD_MODE1:
+		return true;
+	default:
+		return false;
+	}
 }
 
 /**
@@ -2340,6 +2403,8 @@ static int amdgpu_device_ip_suspend_phase1(struct amdgpu_device *adev)
 {
 	int i, r;
 
+	amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE);
+	amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE);
 
 	for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
 		if (!adev->ip_blocks[i].status.valid)
@@ -2767,12 +2832,12 @@ static int amdgpu_device_get_job_timeout_settings(struct amdgpu_device *adev)
 	 * By default timeout for non compute jobs is 10000.
 	 * And there is no timeout enforced on compute jobs.
 	 * In SR-IOV or passthrough mode, timeout for compute
-	 * jobs are 10000 by default.
+	 * jobs are 60000 by default.
 	 */
 	adev->gfx_timeout = msecs_to_jiffies(10000);
 	adev->sdma_timeout = adev->video_timeout = adev->gfx_timeout;
 	if (amdgpu_sriov_vf(adev) || amdgpu_passthrough(adev))
-		adev->compute_timeout = adev->gfx_timeout;
+		adev->compute_timeout =  msecs_to_jiffies(60000);
 	else
 		adev->compute_timeout = MAX_SCHEDULE_TIMEOUT;
 
@@ -2984,18 +3049,8 @@ int amdgpu_device_init(struct amdgpu_device *adev,
 	if (amdgpu_mes && adev->asic_type >= CHIP_NAVI10)
 		adev->enable_mes = true;
 
-	if (amdgpu_discovery && adev->asic_type >= CHIP_NAVI10) {
-		r = amdgpu_discovery_init(adev);
-		if (r) {
-			dev_err(adev->dev, "amdgpu_discovery_init failed\n");
-			return r;
-		}
-	}
-
-	/* early init functions */
-	r = amdgpu_device_ip_early_init(adev);
-	if (r)
-		return r;
+	/* detect hw virtualization here */
+	amdgpu_detect_virtualization(adev);
 
 	r = amdgpu_device_get_job_timeout_settings(adev);
 	if (r) {
@@ -3003,6 +3058,11 @@ int amdgpu_device_init(struct amdgpu_device *adev,
 		return r;
 	}
 
+	/* early init functions */
+	r = amdgpu_device_ip_early_init(adev);
+	if (r)
+		return r;
+
 	/* doorbell bar mapping and doorbell index init*/
 	amdgpu_device_doorbell_init(adev);
 
@@ -3115,8 +3175,6 @@ int amdgpu_device_init(struct amdgpu_device *adev,
 			adev->gfx.config.max_cu_per_sh,
 			adev->gfx.cu_info.number);
 
-	amdgpu_ctx_init_sched(adev);
-
 	adev->accel_working = true;
 
 	amdgpu_vm_check_compute_bug(adev);
@@ -3187,6 +3245,24 @@ int amdgpu_device_init(struct amdgpu_device *adev,
 		return r;
 	}
 
+	r = device_create_file(adev->dev, &dev_attr_product_name);
+	if (r) {
+		dev_err(adev->dev, "Could not create product_name");
+		return r;
+	}
+
+	r = device_create_file(adev->dev, &dev_attr_product_number);
+	if (r) {
+		dev_err(adev->dev, "Could not create product_number");
+		return r;
+	}
+
+	r = device_create_file(adev->dev, &dev_attr_serial_number);
+	if (r) {
+		dev_err(adev->dev, "Could not create serial_number");
+		return r;
+	}
+
 	if (IS_ENABLED(CONFIG_PERF_EVENTS))
 		r = amdgpu_pmu_init(adev);
 	if (r)
@@ -3269,6 +3345,9 @@ void amdgpu_device_fini(struct amdgpu_device *adev)
 	device_remove_file(adev->dev, &dev_attr_pcie_replay_count);
 	if (adev->ucode_sysfs_en)
 		amdgpu_ucode_sysfs_fini(adev);
+	device_remove_file(adev->dev, &dev_attr_product_name);
+	device_remove_file(adev->dev, &dev_attr_product_number);
+	device_remove_file(adev->dev, &dev_attr_serial_number);
 	if (IS_ENABLED(CONFIG_PERF_EVENTS))
 		amdgpu_pmu_fini(adev);
 	if (amdgpu_discovery && adev->asic_type >= CHIP_NAVI10)
@@ -3739,6 +3818,8 @@ static int amdgpu_device_reset_sriov(struct amdgpu_device *adev,
 	if (r)
 		return r;
 
+	amdgpu_amdkfd_pre_reset(adev);
+
 	/* Resume IP prior to SMC */
 	r = amdgpu_device_ip_reinit_early_sriov(adev);
 	if (r)
@@ -4076,6 +4157,8 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
 	need_full_reset = job_signaled = false;
 	INIT_LIST_HEAD(&device_list);
 
+	amdgpu_ras_set_error_query_ready(adev, false);
+
 	dev_info(adev->dev, "GPU %s begin!\n",
 		(in_ras_intr && !use_baco) ? "jobs stop":"reset");
 
@@ -4132,6 +4215,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
 	/* block all schedulers and reset given job's ring */
 	list_for_each_entry(tmp_adev, device_list_handle, gmc.xgmi.head) {
 		if (tmp_adev != adev) {
+			amdgpu_ras_set_error_query_ready(tmp_adev, false);
 			amdgpu_device_lock_adev(tmp_adev, false);
 			if (!amdgpu_sriov_vf(tmp_adev))
 			                amdgpu_amdkfd_pre_reset(tmp_adev);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
index 27d8ae19a7a4..43bb22ad8add 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
@@ -23,9 +23,7 @@
 
 #include "amdgpu.h"
 #include "amdgpu_discovery.h"
-#include "soc15_common.h"
 #include "soc15_hw_ip.h"
-#include "nbio/nbio_2_3_offset.h"
 #include "discovery.h"
 
 #define mmRCC_CONFIG_MEMSIZE	0xde3
@@ -158,7 +156,7 @@ static inline bool amdgpu_discovery_verify_checksum(uint8_t *data, uint32_t size
 	return !!(amdgpu_discovery_calculate_checksum(data, size) == expected);
 }
 
-int amdgpu_discovery_init(struct amdgpu_device *adev)
+static int amdgpu_discovery_init(struct amdgpu_device *adev)
 {
 	struct table_info *info;
 	struct binary_header *bhdr;
@@ -257,10 +255,12 @@ int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev)
 	uint8_t num_base_address;
 	int hw_ip;
 	int i, j, k;
+	int r;
 
-	if (!adev->discovery) {
-		DRM_ERROR("ip discovery uninitialized\n");
-		return -EINVAL;
+	r = amdgpu_discovery_init(adev);
+	if (r) {
+		DRM_ERROR("amdgpu_discovery_init failed\n");
+		return r;
 	}
 
 	bhdr = (struct binary_header *)adev->discovery;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.h
index ba78e15d9b05..d50d597c45ed 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.h
@@ -26,7 +26,6 @@
 
 #define DISCOVERY_TMR_SIZE  (64 << 10)
 
-int amdgpu_discovery_init(struct amdgpu_device *adev);
 void amdgpu_discovery_fini(struct amdgpu_device *adev);
 int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev);
 int amdgpu_discovery_get_ip_version(struct amdgpu_device *adev, int hw_id,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
index ffeb20f11c07..43d8ed7dbd00 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
@@ -38,6 +38,7 @@
 #include <drm/amdgpu_drm.h>
 #include <linux/dma-buf.h>
 #include <linux/dma-fence-array.h>
+#include <linux/pci-p2pdma.h>
 
 /**
  * amdgpu_gem_prime_vmap - &dma_buf_ops.vmap implementation
@@ -179,6 +180,9 @@ static int amdgpu_dma_buf_attach(struct dma_buf *dmabuf,
 	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
 	int r;
 
+	if (pci_p2pdma_distance_many(adev->pdev, &attach->dev, 1, true) < 0)
+		attach->peer2peer = false;
+
 	if (attach->dev->driver == adev->dev->driver)
 		return 0;
 
@@ -272,14 +276,21 @@ static struct sg_table *amdgpu_dma_buf_map(struct dma_buf_attachment *attach,
 	struct dma_buf *dma_buf = attach->dmabuf;
 	struct drm_gem_object *obj = dma_buf->priv;
 	struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
+	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
 	struct sg_table *sgt;
 	long r;
 
 	if (!bo->pin_count) {
-		/* move buffer into GTT */
+		/* move buffer into GTT or VRAM */
 		struct ttm_operation_ctx ctx = { false, false };
+		unsigned domains = AMDGPU_GEM_DOMAIN_GTT;
 
-		amdgpu_bo_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_GTT);
+		if (bo->preferred_domains & AMDGPU_GEM_DOMAIN_VRAM &&
+		    attach->peer2peer) {
+			bo->flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
+			domains |= AMDGPU_GEM_DOMAIN_VRAM;
+		}
+		amdgpu_bo_placement_from_domain(bo, domains);
 		r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
 		if (r)
 			return ERR_PTR(r);
@@ -289,20 +300,34 @@ static struct sg_table *amdgpu_dma_buf_map(struct dma_buf_attachment *attach,
 		return ERR_PTR(-EBUSY);
 	}
 
-	sgt = drm_prime_pages_to_sg(bo->tbo.ttm->pages, bo->tbo.num_pages);
-	if (IS_ERR(sgt))
-		return sgt;
-
-	if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir,
-			      DMA_ATTR_SKIP_CPU_SYNC))
-		goto error_free;
+	switch (bo->tbo.mem.mem_type) {
+	case TTM_PL_TT:
+		sgt = drm_prime_pages_to_sg(bo->tbo.ttm->pages,
+					    bo->tbo.num_pages);
+		if (IS_ERR(sgt))
+			return sgt;
+
+		if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir,
+				      DMA_ATTR_SKIP_CPU_SYNC))
+			goto error_free;
+		break;
+
+	case TTM_PL_VRAM:
+		r = amdgpu_vram_mgr_alloc_sgt(adev, &bo->tbo.mem, attach->dev,
+					      dir, &sgt);
+		if (r)
+			return ERR_PTR(r);
+		break;
+	default:
+		return ERR_PTR(-EINVAL);
+	}
 
 	return sgt;
 
 error_free:
 	sg_free_table(sgt);
 	kfree(sgt);
-	return ERR_PTR(-ENOMEM);
+	return ERR_PTR(-EBUSY);
 }
 
 /**
@@ -318,9 +343,18 @@ static void amdgpu_dma_buf_unmap(struct dma_buf_attachment *attach,
 				 struct sg_table *sgt,
 				 enum dma_data_direction dir)
 {
-	dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir);
-	sg_free_table(sgt);
-	kfree(sgt);
+	struct dma_buf *dma_buf = attach->dmabuf;
+	struct drm_gem_object *obj = dma_buf->priv;
+	struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
+	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
+
+	if (sgt->sgl->page_link) {
+		dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir);
+		sg_free_table(sgt);
+		kfree(sgt);
+	} else {
+		amdgpu_vram_mgr_free_sgt(adev, attach->dev, dir, sgt);
+	}
 }
 
 /**
@@ -514,6 +548,7 @@ amdgpu_dma_buf_move_notify(struct dma_buf_attachment *attach)
 }
 
 static const struct dma_buf_attach_ops amdgpu_dma_buf_attach_ops = {
+	.allow_peer2peer = true,
 	.move_notify = amdgpu_dma_buf_move_notify
 };
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c
index ba1bb95a3cf9..0e8018c9aa8e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c
@@ -856,7 +856,7 @@ void amdgpu_add_thermal_controller(struct amdgpu_device *adev)
 				const char *name = pp_lib_thermal_controller_names[controller->ucType];
 				info.addr = controller->ucI2cAddress >> 1;
 				strlcpy(info.type, name, sizeof(info.type));
-				i2c_new_device(&adev->pm.i2c_bus->adapter, &info);
+				i2c_new_client_device(&adev->pm.i2c_bus->adapter, &info);
 			}
 		} else {
 			DRM_INFO("Unknown thermal controller type %d at 0x%02x %s fan control\n",
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 8ea86ffdea0d..b49ebba3ebaa 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -85,9 +85,10 @@
  * - 3.34.0 - Non-DC can flip correctly between buffers with different pitches
  * - 3.35.0 - Add drm_amdgpu_info_device::tcc_disabled_mask
  * - 3.36.0 - Allow reading more status registers on si/cik
+ * - 3.37.0 - Add AMDGPU_IB_FLAG_EMIT_MEM_SYNC
  */
 #define KMS_DRIVER_MAJOR	3
-#define KMS_DRIVER_MINOR	36
+#define KMS_DRIVER_MINOR	37
 #define KMS_DRIVER_PATCHLEVEL	0
 
 int amdgpu_vram_limit = 0;
@@ -144,6 +145,7 @@ int amdgpu_discovery = -1;
 int amdgpu_mes = 0;
 int amdgpu_noretry;
 int amdgpu_force_asic_type = -1;
+int amdgpu_tmz = 0;
 
 struct amdgpu_mgpu_info mgpu_info = {
 	.mutex = __MUTEX_INITIALIZER(mgpu_info.mutex),
@@ -687,13 +689,12 @@ MODULE_PARM_DESC(halt_if_hws_hang, "Halt if HWS hang is detected (0 = off (defau
 
 /**
  * DOC: hws_gws_support(bool)
- * Whether HWS support gws barriers. Default value: false (not supported)
- * This will be replaced with a MEC firmware version check once firmware
- * is ready
+ * Assume that HWS supports GWS barriers regardless of what firmware version
+ * check says. Default value: false (rely on MEC2 firmware version check).
  */
 bool hws_gws_support;
 module_param(hws_gws_support, bool, 0444);
-MODULE_PARM_DESC(hws_gws_support, "MEC FW support gws barriers (false = not supported (Default), true = supported)");
+MODULE_PARM_DESC(hws_gws_support, "Assume MEC2 FW supports GWS barriers (false = rely on FW version check (Default), true = force supported)");
 
 /**
   * DOC: queue_preemption_timeout_ms (int)
@@ -728,6 +729,16 @@ uint amdgpu_dm_abm_level = 0;
 MODULE_PARM_DESC(abmlevel, "ABM level (0 = off (default), 1-4 = backlight reduction level) ");
 module_param_named(abmlevel, amdgpu_dm_abm_level, uint, 0444);
 
+/**
+ * DOC: tmz (int)
+ * Trusted Memory Zone (TMZ) is a method to protect data being written
+ * to or read from memory.
+ *
+ * The default value: 0 (off).  TODO: change to auto till it is completed.
+ */
+MODULE_PARM_DESC(tmz, "Enable TMZ feature (-1 = auto, 0 = off (default), 1 = on)");
+module_param_named(tmz, amdgpu_tmz, int, 0444);
+
 static const struct pci_device_id pciidlist[] = {
 #ifdef  CONFIG_DRM_AMDGPU_SI
 	{0x1002, 0x6780, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI},
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.c
new file mode 100644
index 000000000000..815c072ac4da
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright 2019 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <linux/pci.h>
+
+#include "amdgpu.h"
+#include "amdgpu_i2c.h"
+#include "smu_v11_0_i2c.h"
+#include "atom.h"
+
+#define I2C_PRODUCT_INFO_ADDR		0xAC
+#define I2C_PRODUCT_INFO_ADDR_SIZE	0x2
+#define I2C_PRODUCT_INFO_OFFSET		0xC0
+
+bool is_fru_eeprom_supported(struct amdgpu_device *adev)
+{
+	/* TODO: Gaming SKUs don't have the FRU EEPROM.
+	 * Use this hack to address hangs on modprobe on gaming SKUs
+	 * until a proper solution can be implemented by only supporting
+	 * the explicit chip IDs for VG20 Server cards
+	 *
+	 * TODO: Add list of supported Arcturus DIDs once confirmed
+	 */
+	if ((adev->asic_type == CHIP_VEGA20 && adev->pdev->device == 0x66a0) ||
+	    (adev->asic_type == CHIP_VEGA20 && adev->pdev->device == 0x66a1) ||
+	    (adev->asic_type == CHIP_VEGA20 && adev->pdev->device == 0x66a4))
+		return true;
+	return false;
+}
+
+int amdgpu_fru_read_eeprom(struct amdgpu_device *adev, uint32_t addrptr,
+			   unsigned char *buff)
+{
+	int ret, size;
+	struct i2c_msg msg = {
+			.addr   = I2C_PRODUCT_INFO_ADDR,
+			.flags  = I2C_M_RD,
+			.buf    = buff,
+	};
+	buff[0] = 0;
+	buff[1] = addrptr;
+	msg.len = I2C_PRODUCT_INFO_ADDR_SIZE + 1;
+	ret = i2c_transfer(&adev->pm.smu_i2c, &msg, 1);
+
+	if (ret < 1) {
+		DRM_WARN("FRU: Failed to get size field");
+		return ret;
+	}
+
+	/* The size returned by the i2c requires subtraction of 0xC0 since the
+	 * size apparently always reports as 0xC0+actual size.
+	 */
+	size = buff[2] - I2C_PRODUCT_INFO_OFFSET;
+	/* Add 1 since address field was 1 byte */
+	buff[1] = addrptr + 1;
+
+	msg.len = I2C_PRODUCT_INFO_ADDR_SIZE + size;
+	ret = i2c_transfer(&adev->pm.smu_i2c, &msg, 1);
+
+	if (ret < 1) {
+		DRM_WARN("FRU: Failed to get data field");
+		return ret;
+	}
+
+	return size;
+}
+
+int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
+{
+	unsigned char buff[34];
+	int addrptr = 0, size = 0;
+
+	if (!is_fru_eeprom_supported(adev))
+		return 0;
+
+	/* If algo exists, it means that the i2c_adapter's initialized */
+	if (!adev->pm.smu_i2c.algo) {
+		DRM_WARN("Cannot access FRU, EEPROM accessor not initialized");
+		return 0;
+	}
+
+	/* There's a lot of repetition here. This is due to the FRU having
+	 * variable-length fields. To get the information, we have to find the
+	 * size of each field, and then keep reading along and reading along
+	 * until we get all of the data that we want. We use addrptr to track
+	 * the address as we go
+	 */
+
+	/* The first fields are all of size 1-byte, from 0-7 are offsets that
+	 * contain information that isn't useful to us.
+	 * Bytes 8-a are all 1-byte and refer to the size of the entire struct,
+	 * and the language field, so just start from 0xb, manufacturer size
+	 */
+	addrptr = 0xb;
+	size = amdgpu_fru_read_eeprom(adev, addrptr, buff);
+	if (size < 1) {
+		DRM_ERROR("Failed to read FRU Manufacturer, ret:%d", size);
+		return size;
+	}
+
+	/* Increment the addrptr by the size of the field, and 1 due to the
+	 * size field being 1 byte. This pattern continues below.
+	 */
+	addrptr += size + 1;
+	size = amdgpu_fru_read_eeprom(adev, addrptr, buff);
+	if (size < 1) {
+		DRM_ERROR("Failed to read FRU product name, ret:%d", size);
+		return size;
+	}
+
+	/* Product name should only be 32 characters. Any more,
+	 * and something could be wrong. Cap it at 32 to be safe
+	 */
+	if (size > 32) {
+		DRM_WARN("FRU Product Number is larger than 32 characters. This is likely a mistake");
+		size = 32;
+	}
+	/* Start at 2 due to buff using fields 0 and 1 for the address */
+	memcpy(adev->product_name, &buff[2], size);
+	adev->product_name[size] = '\0';
+
+	addrptr += size + 1;
+	size = amdgpu_fru_read_eeprom(adev, addrptr, buff);
+	if (size < 1) {
+		DRM_ERROR("Failed to read FRU product number, ret:%d", size);
+		return size;
+	}
+
+	/* Product number should only be 16 characters. Any more,
+	 * and something could be wrong. Cap it at 16 to be safe
+	 */
+	if (size > 16) {
+		DRM_WARN("FRU Product Number is larger than 16 characters. This is likely a mistake");
+		size = 16;
+	}
+	memcpy(adev->product_number, &buff[2], size);
+	adev->product_number[size] = '\0';
+
+	addrptr += size + 1;
+	size = amdgpu_fru_read_eeprom(adev, addrptr, buff);
+
+	if (size < 1) {
+		DRM_ERROR("Failed to read FRU product version, ret:%d", size);
+		return size;
+	}
+
+	addrptr += size + 1;
+	size = amdgpu_fru_read_eeprom(adev, addrptr, buff);
+
+	if (size < 1) {
+		DRM_ERROR("Failed to read FRU serial number, ret:%d", size);
+		return size;
+	}
+
+	/* Serial number should only be 16 characters. Any more,
+	 * and something could be wrong. Cap it at 16 to be safe
+	 */
+	if (size > 16) {
+		DRM_WARN("FRU Serial Number is larger than 16 characters. This is likely a mistake");
+		size = 16;
+	}
+	memcpy(adev->serial, &buff[2], size);
+	adev->serial[size] = '\0';
+
+	return 0;
+}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.h
new file mode 100644
index 000000000000..968115c97e33
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2020 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef __AMDGPU_PRODINFO_H__
+#define __AMDGPU_PRODINFO_H__
+
+int amdgpu_fru_get_product_info(struct amdgpu_device *adev);
+
+#endif  // __AMDGPU_PRODINFO_H__
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
index 4277125a79ee..4ed9958af94e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
@@ -29,6 +29,7 @@
 #include <linux/module.h>
 #include <linux/pagemap.h>
 #include <linux/pci.h>
+#include <linux/dma-buf.h>
 
 #include <drm/amdgpu_drm.h>
 #include <drm/drm_debugfs.h>
@@ -161,16 +162,17 @@ void amdgpu_gem_object_close(struct drm_gem_object *obj,
 
 	struct amdgpu_bo_list_entry vm_pd;
 	struct list_head list, duplicates;
+	struct dma_fence *fence = NULL;
 	struct ttm_validate_buffer tv;
 	struct ww_acquire_ctx ticket;
 	struct amdgpu_bo_va *bo_va;
-	int r;
+	long r;
 
 	INIT_LIST_HEAD(&list);
 	INIT_LIST_HEAD(&duplicates);
 
 	tv.bo = &bo->tbo;
-	tv.num_shared = 1;
+	tv.num_shared = 2;
 	list_add(&tv.head, &list);
 
 	amdgpu_vm_get_pd_bo(vm, &list, &vm_pd);
@@ -178,28 +180,34 @@ void amdgpu_gem_object_close(struct drm_gem_object *obj,
 	r = ttm_eu_reserve_buffers(&ticket, &list, false, &duplicates);
 	if (r) {
 		dev_err(adev->dev, "leaking bo va because "
-			"we fail to reserve bo (%d)\n", r);
+			"we fail to reserve bo (%ld)\n", r);
 		return;
 	}
 	bo_va = amdgpu_vm_bo_find(vm, bo);
-	if (bo_va && --bo_va->ref_count == 0) {
-		amdgpu_vm_bo_rmv(adev, bo_va);
-
-		if (amdgpu_vm_ready(vm)) {
-			struct dma_fence *fence = NULL;
+	if (!bo_va || --bo_va->ref_count)
+		goto out_unlock;
 
-			r = amdgpu_vm_clear_freed(adev, vm, &fence);
-			if (unlikely(r)) {
-				dev_err(adev->dev, "failed to clear page "
-					"tables on GEM object close (%d)\n", r);
-			}
+	amdgpu_vm_bo_rmv(adev, bo_va);
+	if (!amdgpu_vm_ready(vm))
+		goto out_unlock;
 
-			if (fence) {
-				amdgpu_bo_fence(bo, fence, true);
-				dma_fence_put(fence);
-			}
-		}
+	fence = dma_resv_get_excl(bo->tbo.base.resv);
+	if (fence) {
+		amdgpu_bo_fence(bo, fence, true);
+		fence = NULL;
 	}
+
+	r = amdgpu_vm_clear_freed(adev, vm, &fence);
+	if (r || !fence)
+		goto out_unlock;
+
+	amdgpu_bo_fence(bo, fence, true);
+	dma_fence_put(fence);
+
+out_unlock:
+	if (unlikely(r < 0))
+		dev_err(adev->dev, "failed to clear page "
+			"tables on GEM object close (%ld)\n", r);
 	ttm_eu_backoff_reservation(&ticket, &list);
 }
 
@@ -226,7 +234,8 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
 		      AMDGPU_GEM_CREATE_CPU_GTT_USWC |
 		      AMDGPU_GEM_CREATE_VRAM_CLEARED |
 		      AMDGPU_GEM_CREATE_VM_ALWAYS_VALID |
-		      AMDGPU_GEM_CREATE_EXPLICIT_SYNC))
+		      AMDGPU_GEM_CREATE_EXPLICIT_SYNC |
+		      AMDGPU_GEM_CREATE_ENCRYPTED))
 
 		return -EINVAL;
 
@@ -234,6 +243,11 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
 	if (args->in.domains & ~AMDGPU_GEM_DOMAIN_MASK)
 		return -EINVAL;
 
+	if (!amdgpu_is_tmz(adev) && (flags & AMDGPU_GEM_CREATE_ENCRYPTED)) {
+		DRM_NOTE_ONCE("Cannot allocate secure buffer since TMZ is disabled\n");
+		return -EINVAL;
+	}
+
 	/* create a gem object to contain this object in */
 	if (args->in.domains & (AMDGPU_GEM_DOMAIN_GDS |
 	    AMDGPU_GEM_DOMAIN_GWS | AMDGPU_GEM_DOMAIN_OA)) {
@@ -854,7 +868,8 @@ static int amdgpu_debugfs_gem_bo_info(int id, void *ptr, void *data)
 	attachment = READ_ONCE(bo->tbo.base.import_attach);
 
 	if (attachment)
-		seq_printf(m, " imported from %p", dma_buf);
+		seq_printf(m, " imported from %p%s", dma_buf,
+			   attachment->peer2peer ? " P2P" : "");
 	else if (dma_buf)
 		seq_printf(m, " exported as %p", dma_buf);
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
index 6b9c9193cdfa..ea576b4260a4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
@@ -318,9 +318,11 @@ int amdgpu_gfx_kiq_init_ring(struct amdgpu_device *adev,
 		return r;
 
 	ring->eop_gpu_addr = kiq->eop_gpu_addr;
+	ring->no_scheduler = true;
 	sprintf(ring->name, "kiq_%d.%d.%d", ring->me, ring->pipe, ring->queue);
 	r = amdgpu_ring_init(adev, ring, 1024,
-			     irq, AMDGPU_CP_KIQ_IRQ_DRIVER0);
+			     irq, AMDGPU_CP_KIQ_IRQ_DRIVER0,
+			     AMDGPU_RING_PRIO_DEFAULT);
 	if (r)
 		dev_warn(adev->dev, "(%d) failed to init kiq ring\n", r);
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h
index 5825692d07e4..634746829024 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h
@@ -286,13 +286,8 @@ struct amdgpu_gfx {
 	bool				me_fw_write_wait;
 	bool				cp_fw_write_wait;
 	struct amdgpu_ring		gfx_ring[AMDGPU_MAX_GFX_RINGS];
-	struct drm_gpu_scheduler	*gfx_sched[AMDGPU_MAX_GFX_RINGS];
-	uint32_t			num_gfx_sched;
 	unsigned			num_gfx_rings;
 	struct amdgpu_ring		compute_ring[AMDGPU_MAX_COMPUTE_RINGS];
-	struct drm_gpu_scheduler        **compute_prio_sched[AMDGPU_GFX_PIPE_PRIO_MAX];
-	struct drm_gpu_scheduler	*compute_sched[AMDGPU_MAX_COMPUTE_RINGS];
-	uint32_t                        num_compute_sched[AMDGPU_GFX_PIPE_PRIO_MAX];
 	unsigned			num_compute_rings;
 	struct amdgpu_irq_src		eop_irq;
 	struct amdgpu_irq_src		priv_reg_irq;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
index 5884ab590486..acabb57aa8af 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
@@ -136,8 +136,8 @@ uint64_t amdgpu_gmc_agp_addr(struct ttm_buffer_object *bo)
 /**
  * amdgpu_gmc_vram_location - try to find VRAM location
  *
- * @adev: amdgpu device structure holding all necessary informations
- * @mc: memory controller structure holding memory informations
+ * @adev: amdgpu device structure holding all necessary information
+ * @mc: memory controller structure holding memory information
  * @base: base address at which to put VRAM
  *
  * Function will try to place VRAM at base address provided
@@ -165,8 +165,8 @@ void amdgpu_gmc_vram_location(struct amdgpu_device *adev, struct amdgpu_gmc *mc,
 /**
  * amdgpu_gmc_gart_location - try to find GART location
  *
- * @adev: amdgpu device structure holding all necessary informations
- * @mc: memory controller structure holding memory informations
+ * @adev: amdgpu device structure holding all necessary information
+ * @mc: memory controller structure holding memory information
  *
  * Function will place try to place GART before or after VRAM.
  *
@@ -207,8 +207,8 @@ void amdgpu_gmc_gart_location(struct amdgpu_device *adev, struct amdgpu_gmc *mc)
 
 /**
  * amdgpu_gmc_agp_location - try to find AGP location
- * @adev: amdgpu device structure holding all necessary informations
- * @mc: memory controller structure holding memory informations
+ * @adev: amdgpu device structure holding all necessary information
+ * @mc: memory controller structure holding memory information
  *
  * Function will place try to find a place for the AGP BAR in the MC address
  * space.
@@ -373,3 +373,38 @@ int amdgpu_gmc_allocate_vm_inv_eng(struct amdgpu_device *adev)
 
 	return 0;
 }
+
+/**
+ * amdgpu_tmz_set -- check and set if a device supports TMZ
+ * @adev: amdgpu_device pointer
+ *
+ * Check and set if an the device @adev supports Trusted Memory
+ * Zones (TMZ).
+ */
+void amdgpu_gmc_tmz_set(struct amdgpu_device *adev)
+{
+	switch (adev->asic_type) {
+	case CHIP_RAVEN:
+	case CHIP_RENOIR:
+	case CHIP_NAVI10:
+	case CHIP_NAVI14:
+	case CHIP_NAVI12:
+		/* Don't enable it by default yet.
+		 */
+		if (amdgpu_tmz < 1) {
+			adev->gmc.tmz_enabled = false;
+			dev_info(adev->dev,
+				 "Trusted Memory Zone (TMZ) feature disabled as experimental (default)\n");
+		} else {
+			adev->gmc.tmz_enabled = true;
+			dev_info(adev->dev,
+				 "Trusted Memory Zone (TMZ) feature enabled as experimental (cmd line)\n");
+		}
+		break;
+	default:
+		adev->gmc.tmz_enabled = false;
+		dev_warn(adev->dev,
+			 "Trusted Memory Zone (TMZ) feature not supported\n");
+		break;
+	}
+}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
index 7546da0cc70c..2bd9423c1dab 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
@@ -213,6 +213,8 @@ struct amdgpu_gmc {
 	} fault_hash[AMDGPU_GMC_FAULT_HASH_SIZE];
 	uint64_t		last_fault:AMDGPU_GMC_FAULT_RING_ORDER;
 
+	bool tmz_enabled;
+
 	const struct amdgpu_gmc_funcs	*gmc_funcs;
 
 	struct amdgpu_xgmi xgmi;
@@ -276,4 +278,6 @@ int amdgpu_gmc_ras_late_init(struct amdgpu_device *adev);
 void amdgpu_gmc_ras_fini(struct amdgpu_device *adev);
 int amdgpu_gmc_allocate_vm_inv_eng(struct amdgpu_device *adev);
 
+extern void amdgpu_gmc_tmz_set(struct amdgpu_device *adev);
+
 #endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
index ccbd7acfc4cb..ec2c5e164cd3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
@@ -61,12 +61,13 @@
  * Returns 0 on success, error on failure.
  */
 int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm,
-		  unsigned size, struct amdgpu_ib *ib)
+		  unsigned size, enum amdgpu_ib_pool_type pool_type,
+		  struct amdgpu_ib *ib)
 {
 	int r;
 
 	if (size) {
-		r = amdgpu_sa_bo_new(&adev->ring_tmp_bo,
+		r = amdgpu_sa_bo_new(&adev->ib_pools[pool_type],
 				      &ib->sa_bo, size, 256);
 		if (r) {
 			dev_err(adev->dev, "failed to get a new IB (%d)\n", r);
@@ -131,6 +132,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
 	uint64_t fence_ctx;
 	uint32_t status = 0, alloc_size;
 	unsigned fence_flags = 0;
+	bool secure;
 
 	unsigned i;
 	int r = 0;
@@ -181,6 +183,9 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
 		dma_fence_put(tmp);
 	}
 
+	if ((ib->flags & AMDGPU_IB_FLAG_EMIT_MEM_SYNC) && ring->funcs->emit_mem_sync)
+		ring->funcs->emit_mem_sync(ring);
+
 	if (ring->funcs->insert_start)
 		ring->funcs->insert_start(ring);
 
@@ -215,6 +220,14 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
 		amdgpu_ring_emit_cntxcntl(ring, status);
 	}
 
+	/* Setup initial TMZiness and send it off.
+	 */
+	secure = false;
+	if (job && ring->funcs->emit_frame_cntl) {
+		secure = ib->flags & AMDGPU_IB_FLAGS_SECURE;
+		amdgpu_ring_emit_frame_cntl(ring, true, secure);
+	}
+
 	for (i = 0; i < num_ibs; ++i) {
 		ib = &ibs[i];
 
@@ -226,12 +239,20 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
 		    !amdgpu_sriov_vf(adev)) /* for SRIOV preemption, Preamble CE ib must be inserted anyway */
 			continue;
 
+		if (job && ring->funcs->emit_frame_cntl) {
+			if (secure != !!(ib->flags & AMDGPU_IB_FLAGS_SECURE)) {
+				amdgpu_ring_emit_frame_cntl(ring, false, secure);
+				secure = !secure;
+				amdgpu_ring_emit_frame_cntl(ring, true, secure);
+			}
+		}
+
 		amdgpu_ring_emit_ib(ring, job, ib, status);
 		status &= ~AMDGPU_HAVE_CTX_SWITCH;
 	}
 
-	if (ring->funcs->emit_tmz)
-		amdgpu_ring_emit_tmz(ring, false);
+	if (job && ring->funcs->emit_frame_cntl)
+		amdgpu_ring_emit_frame_cntl(ring, false, secure);
 
 #ifdef CONFIG_X86_64
 	if (!(adev->flags & AMD_IS_APU))
@@ -280,22 +301,32 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
  */
 int amdgpu_ib_pool_init(struct amdgpu_device *adev)
 {
-	int r;
+	unsigned size;
+	int r, i;
 
-	if (adev->ib_pool_ready) {
+	if (adev->ib_pool_ready)
 		return 0;
-	}
-	r = amdgpu_sa_bo_manager_init(adev, &adev->ring_tmp_bo,
-				      AMDGPU_IB_POOL_SIZE*64*1024,
-				      AMDGPU_GPU_PAGE_SIZE,
-				      AMDGPU_GEM_DOMAIN_GTT);
-	if (r) {
-		return r;
-	}
 
+	for (i = 0; i < AMDGPU_IB_POOL_MAX; i++) {
+		if (i == AMDGPU_IB_POOL_DIRECT)
+			size = PAGE_SIZE * 2;
+		else
+			size = AMDGPU_IB_POOL_SIZE;
+
+		r = amdgpu_sa_bo_manager_init(adev, &adev->ib_pools[i],
+					      size, AMDGPU_GPU_PAGE_SIZE,
+					      AMDGPU_GEM_DOMAIN_GTT);
+		if (r)
+			goto error;
+	}
 	adev->ib_pool_ready = true;
 
 	return 0;
+
+error:
+	while (i--)
+		amdgpu_sa_bo_manager_fini(adev, &adev->ib_pools[i]);
+	return r;
 }
 
 /**
@@ -308,10 +339,14 @@ int amdgpu_ib_pool_init(struct amdgpu_device *adev)
  */
 void amdgpu_ib_pool_fini(struct amdgpu_device *adev)
 {
-	if (adev->ib_pool_ready) {
-		amdgpu_sa_bo_manager_fini(adev, &adev->ring_tmp_bo);
-		adev->ib_pool_ready = false;
-	}
+	int i;
+
+	if (!adev->ib_pool_ready)
+		return;
+
+	for (i = 0; i < AMDGPU_IB_POOL_MAX; i++)
+		amdgpu_sa_bo_manager_fini(adev, &adev->ib_pools[i]);
+	adev->ib_pool_ready = false;
 }
 
 /**
@@ -326,9 +361,9 @@ void amdgpu_ib_pool_fini(struct amdgpu_device *adev)
  */
 int amdgpu_ib_ring_tests(struct amdgpu_device *adev)
 {
-	unsigned i;
-	int r, ret = 0;
 	long tmo_gfx, tmo_mm;
+	int r, ret = 0;
+	unsigned i;
 
 	tmo_mm = tmo_gfx = AMDGPU_IB_TEST_TIMEOUT;
 	if (amdgpu_sriov_vf(adev)) {
@@ -406,10 +441,16 @@ static int amdgpu_debugfs_sa_info(struct seq_file *m, void *data)
 	struct drm_device *dev = node->minor->dev;
 	struct amdgpu_device *adev = dev->dev_private;
 
-	amdgpu_sa_bo_dump_debug_info(&adev->ring_tmp_bo, m);
+	seq_printf(m, "--------------------- DELAYED --------------------- \n");
+	amdgpu_sa_bo_dump_debug_info(&adev->ib_pools[AMDGPU_IB_POOL_DELAYED],
+				     m);
+	seq_printf(m, "-------------------- IMMEDIATE -------------------- \n");
+	amdgpu_sa_bo_dump_debug_info(&adev->ib_pools[AMDGPU_IB_POOL_IMMEDIATE],
+				     m);
+	seq_printf(m, "--------------------- DIRECT ---------------------- \n");
+	amdgpu_sa_bo_dump_debug_info(&adev->ib_pools[AMDGPU_IB_POOL_DIRECT], m);
 
 	return 0;
-
 }
 
 static const struct drm_info_list amdgpu_debugfs_sa_list[] = {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c
index 3a67f6c046d4..fe92dcd94d4a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c
@@ -282,7 +282,7 @@ static int amdgpu_vmid_grab_reserved(struct amdgpu_vm *vm,
 	    !dma_fence_is_later(updates, (*id)->flushed_updates))
 	    updates = NULL;
 
-	if ((*id)->owner != vm->direct.fence_context ||
+	if ((*id)->owner != vm->immediate.fence_context ||
 	    job->vm_pd_addr != (*id)->pd_gpu_addr ||
 	    updates || !(*id)->last_flush ||
 	    ((*id)->last_flush->context != fence_context &&
@@ -349,7 +349,7 @@ static int amdgpu_vmid_grab_used(struct amdgpu_vm *vm,
 		struct dma_fence *flushed;
 
 		/* Check all the prerequisites to using this VMID */
-		if ((*id)->owner != vm->direct.fence_context)
+		if ((*id)->owner != vm->immediate.fence_context)
 			continue;
 
 		if ((*id)->pd_gpu_addr != job->vm_pd_addr)
@@ -448,7 +448,7 @@ int amdgpu_vmid_grab(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
 	}
 
 	id->pd_gpu_addr = job->vm_pd_addr;
-	id->owner = vm->direct.fence_context;
+	id->owner = vm->immediate.fence_context;
 
 	if (job->vm_needs_flush) {
 		dma_fence_put(id->last_flush);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
index 5ed4227f304b..0cc4c67f95f7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
@@ -260,7 +260,7 @@ int amdgpu_irq_init(struct amdgpu_device *adev)
 		nvec = pci_alloc_irq_vectors(adev->pdev, 1, 1, flags);
 		if (nvec > 0) {
 			adev->irq.msi_enabled = true;
-			dev_dbg(adev->dev, "amdgpu: using MSI/MSI-X.\n");
+			dev_dbg(adev->dev, "using MSI/MSI-X.\n");
 		}
 	}
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
index 4981e443a884..35c381ec0423 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
@@ -33,6 +33,7 @@ static void amdgpu_job_timedout(struct drm_sched_job *s_job)
 	struct amdgpu_ring *ring = to_amdgpu_ring(s_job->sched);
 	struct amdgpu_job *job = to_amdgpu_job(s_job);
 	struct amdgpu_task_info ti;
+	struct amdgpu_device *adev = ring->adev;
 
 	memset(&ti, 0, sizeof(struct amdgpu_task_info));
 
@@ -49,10 +50,13 @@ static void amdgpu_job_timedout(struct drm_sched_job *s_job)
 	DRM_ERROR("Process information: process %s pid %d thread %s pid %d\n",
 		  ti.process_name, ti.tgid, ti.task_name, ti.pid);
 
-	if (amdgpu_device_should_recover_gpu(ring->adev))
+	if (amdgpu_device_should_recover_gpu(ring->adev)) {
 		amdgpu_device_gpu_recover(ring->adev, job);
-	else
+	} else {
 		drm_sched_suspend_timeout(&ring->sched);
+		if (amdgpu_sriov_vf(adev))
+			adev->virt.tdr_debug = true;
+	}
 }
 
 int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs,
@@ -87,7 +91,8 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs,
 }
 
 int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size,
-			     struct amdgpu_job **job)
+		enum amdgpu_ib_pool_type pool_type,
+		struct amdgpu_job **job)
 {
 	int r;
 
@@ -95,7 +100,7 @@ int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size,
 	if (r)
 		return r;
 
-	r = amdgpu_ib_get(adev, NULL, size, &(*job)->ibs[0]);
+	r = amdgpu_ib_get(adev, NULL, size, pool_type, &(*job)->ibs[0]);
 	if (r)
 		kfree(*job);
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
index 3f7b8433d179..81caac9b958a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
@@ -38,6 +38,7 @@
 #define AMDGPU_JOB_GET_VMID(job) ((job) ? (job)->vmid : 0)
 
 struct amdgpu_fence;
+enum amdgpu_ib_pool_type;
 
 struct amdgpu_job {
 	struct drm_sched_job    base;
@@ -61,14 +62,12 @@ struct amdgpu_job {
 	/* user fence handling */
 	uint64_t		uf_addr;
 	uint64_t		uf_sequence;
-
 };
 
 int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs,
 		     struct amdgpu_job **job, struct amdgpu_vm *vm);
 int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size,
-			     struct amdgpu_job **job);
-
+		enum amdgpu_ib_pool_type pool, struct amdgpu_job **job);
 void amdgpu_job_free_resources(struct amdgpu_job *job);
 void amdgpu_job_free(struct amdgpu_job *job);
 int amdgpu_job_submit(struct amdgpu_job *job, struct drm_sched_entity *entity,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.c
index 5727f00afc8e..d31d65e6b039 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.c
@@ -144,7 +144,8 @@ static int amdgpu_jpeg_dec_set_reg(struct amdgpu_ring *ring, uint32_t handle,
 	const unsigned ib_size_dw = 16;
 	int i, r;
 
-	r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
+	r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4,
+					AMDGPU_IB_POOL_DIRECT, &job);
 	if (r)
 		return r;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.h
index bd9ef9cc86de..5131a0a1bc8a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.h
@@ -43,8 +43,6 @@ struct amdgpu_jpeg {
 	uint8_t	num_jpeg_inst;
 	struct amdgpu_jpeg_inst inst[AMDGPU_MAX_JPEG_INSTANCES];
 	struct amdgpu_jpeg_reg internal;
-	struct drm_gpu_scheduler *jpeg_sched[AMDGPU_MAX_JPEG_INSTANCES];
-	uint32_t num_jpeg_sched;
 	unsigned harvest_config;
 	struct delayed_work idle_work;
 	enum amd_powergating_state cur_state;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index fd1dc3236eca..ea7e72ecaefa 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -183,12 +183,10 @@ int amdgpu_driver_load_kms(struct drm_device *dev, unsigned long flags)
 	/* Call ACPI methods: require modeset init
 	 * but failure is not fatal
 	 */
-	if (!r) {
-		acpi_status = amdgpu_acpi_init(adev);
-		if (acpi_status)
-			dev_dbg(&dev->pdev->dev,
-				"Error during ACPI methods call\n");
-	}
+
+	acpi_status = amdgpu_acpi_init(adev);
+	if (acpi_status)
+		dev_dbg(&dev->pdev->dev, "Error during ACPI methods call\n");
 
 	if (adev->runpm) {
 		dev_pm_set_driver_flags(dev->dev, DPM_FLAG_NEVER_SKIP);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h
index 919bd566ba3c..edaac242ff85 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h
@@ -77,7 +77,6 @@ struct amdgpu_nbio_funcs {
 				      u32 *flags);
 	void (*ih_control)(struct amdgpu_device *adev);
 	void (*init_registers)(struct amdgpu_device *adev);
-	void (*detect_hw_virt)(struct amdgpu_device *adev);
 	void (*remap_hdp_registers)(struct amdgpu_device *adev);
 	void (*handle_ras_controller_intr_no_bifring)(struct amdgpu_device *adev);
 	void (*handle_ras_err_event_athub_intr_no_bifring)(struct amdgpu_device *adev);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index c687f5415b3f..3d822eba9a5d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -753,7 +753,7 @@ int amdgpu_bo_restore_shadow(struct amdgpu_bo *shadow, struct dma_fence **fence)
 
 	return amdgpu_copy_buffer(ring, shadow_addr, parent_addr,
 				  amdgpu_bo_size(shadow), NULL, fence,
-				  true, false);
+				  true, false, false);
 }
 
 /**
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
index 5e39ecd8cc28..7d41f7b9a340 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
@@ -229,6 +229,17 @@ static inline bool amdgpu_bo_explicit_sync(struct amdgpu_bo *bo)
 	return bo->flags & AMDGPU_GEM_CREATE_EXPLICIT_SYNC;
 }
 
+/**
+ * amdgpu_bo_encrypted - test if the BO is encrypted
+ * @bo: pointer to a buffer object
+ *
+ * Return true if the buffer object is encrypted, false otherwise.
+ */
+static inline bool amdgpu_bo_encrypted(struct amdgpu_bo *bo)
+{
+	return bo->flags & AMDGPU_GEM_CREATE_ENCRYPTED;
+}
+
 bool amdgpu_bo_is_amdgpu_bo(struct ttm_buffer_object *bo);
 void amdgpu_bo_placement_from_domain(struct amdgpu_bo *abo, u32 domain);
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
index deaa26808841..8020f18d569d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
@@ -42,6 +42,8 @@ static void psp_set_funcs(struct amdgpu_device *adev);
 static int psp_sysfs_init(struct amdgpu_device *adev);
 static void psp_sysfs_fini(struct amdgpu_device *adev);
 
+static int psp_load_smu_fw(struct psp_context *psp);
+
 /*
  * Due to DF Cstate management centralized to PMFW, the firmware
  * loading sequence will be updated as below:
@@ -201,6 +203,7 @@ psp_cmd_submit_buf(struct psp_context *psp,
 	int index;
 	int timeout = 2000;
 	bool ras_intr = false;
+	bool skip_unsupport = false;
 
 	mutex_lock(&psp->mutex);
 
@@ -232,6 +235,9 @@ psp_cmd_submit_buf(struct psp_context *psp,
 		amdgpu_asic_invalidate_hdp(psp->adev, NULL);
 	}
 
+	/* We allow TEE_ERROR_NOT_SUPPORTED for VMR command in SRIOV */
+	skip_unsupport = (psp->cmd_buf_mem->resp.status == 0xffff000a) && amdgpu_sriov_vf(psp->adev);
+
 	/* In some cases, psp response status is not 0 even there is no
 	 * problem while the command is submitted. Some version of PSP FW
 	 * doesn't write 0 to that field.
@@ -239,7 +245,7 @@ psp_cmd_submit_buf(struct psp_context *psp,
 	 * during psp initialization to avoid breaking hw_init and it doesn't
 	 * return -EINVAL.
 	 */
-	if ((psp->cmd_buf_mem->resp.status || !timeout) && !ras_intr) {
+	if (!skip_unsupport && (psp->cmd_buf_mem->resp.status || !timeout) && !ras_intr) {
 		if (ucode)
 			DRM_WARN("failed to load ucode id (%d) ",
 				  ucode->ucode_id);
@@ -884,6 +890,7 @@ static int psp_hdcp_load(struct psp_context *psp)
 	if (!ret) {
 		psp->hdcp_context.hdcp_initialized = true;
 		psp->hdcp_context.session_id = cmd->resp.session_id;
+		mutex_init(&psp->hdcp_context.mutex);
 	}
 
 	kfree(cmd);
@@ -1029,6 +1036,7 @@ static int psp_dtm_load(struct psp_context *psp)
 	if (!ret) {
 		psp->dtm_context.dtm_initialized = true;
 		psp->dtm_context.session_id = cmd->resp.session_id;
+		mutex_init(&psp->dtm_context.mutex);
 	}
 
 	kfree(cmd);
@@ -1169,16 +1177,20 @@ static int psp_hw_start(struct psp_context *psp)
 	}
 
 	/*
-	 * For those ASICs with DF Cstate management centralized
+	 * For ASICs with DF Cstate management centralized
 	 * to PMFW, TMR setup should be performed after PMFW
 	 * loaded and before other non-psp firmware loaded.
 	 */
-	if (!psp->pmfw_centralized_cstate_management) {
-		ret = psp_tmr_load(psp);
-		if (ret) {
-			DRM_ERROR("PSP load tmr failed!\n");
+	if (psp->pmfw_centralized_cstate_management) {
+		ret = psp_load_smu_fw(psp);
+		if (ret)
 			return ret;
-		}
+	}
+
+	ret = psp_tmr_load(psp);
+	if (ret) {
+		DRM_ERROR("PSP load tmr failed!\n");
+		return ret;
 	}
 
 	return 0;
@@ -1355,7 +1367,7 @@ static int psp_prep_load_ip_fw_cmd_buf(struct amdgpu_firmware_info *ucode,
 }
 
 static int psp_execute_np_fw_load(struct psp_context *psp,
-			       struct amdgpu_firmware_info *ucode)
+			          struct amdgpu_firmware_info *ucode)
 {
 	int ret = 0;
 
@@ -1369,64 +1381,95 @@ static int psp_execute_np_fw_load(struct psp_context *psp,
 	return ret;
 }
 
+static int psp_load_smu_fw(struct psp_context *psp)
+{
+	int ret;
+	struct amdgpu_device* adev = psp->adev;
+	struct amdgpu_firmware_info *ucode =
+			&adev->firmware.ucode[AMDGPU_UCODE_ID_SMC];
+
+	if (!ucode->fw || amdgpu_sriov_vf(psp->adev))
+		return 0;
+
+
+	if (adev->in_gpu_reset) {
+		ret = amdgpu_dpm_set_mp1_state(adev, PP_MP1_STATE_UNLOAD);
+		if (ret) {
+			DRM_WARN("Failed to set MP1 state prepare for reload\n");
+		}
+	}
+
+	ret = psp_execute_np_fw_load(psp, ucode);
+
+	if (ret)
+		DRM_ERROR("PSP load smu failed!\n");
+
+	return ret;
+}
+
+static bool fw_load_skip_check(struct psp_context *psp,
+			       struct amdgpu_firmware_info *ucode)
+{
+	if (!ucode->fw)
+		return true;
+
+	if (ucode->ucode_id == AMDGPU_UCODE_ID_SMC &&
+	    (psp_smu_reload_quirk(psp) ||
+	     psp->autoload_supported ||
+	     psp->pmfw_centralized_cstate_management))
+		return true;
+
+	if (amdgpu_sriov_vf(psp->adev) &&
+	   (ucode->ucode_id == AMDGPU_UCODE_ID_SDMA0
+	    || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA1
+	    || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA2
+	    || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA3
+	    || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA4
+	    || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA5
+	    || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA6
+	    || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA7
+	    || ucode->ucode_id == AMDGPU_UCODE_ID_RLC_G
+	    || ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL
+	    || ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM
+	    || ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM
+	    || ucode->ucode_id == AMDGPU_UCODE_ID_SMC))
+		/*skip ucode loading in SRIOV VF */
+		return true;
+
+	if (psp->autoload_supported &&
+	    (ucode->ucode_id == AMDGPU_UCODE_ID_CP_MEC1_JT ||
+	     ucode->ucode_id == AMDGPU_UCODE_ID_CP_MEC2_JT))
+		/* skip mec JT when autoload is enabled */
+		return true;
+
+	return false;
+}
+
 static int psp_np_fw_load(struct psp_context *psp)
 {
 	int i, ret;
 	struct amdgpu_firmware_info *ucode;
 	struct amdgpu_device* adev = psp->adev;
 
-	if (psp->autoload_supported ||
-	    psp->pmfw_centralized_cstate_management) {
-		ucode = &adev->firmware.ucode[AMDGPU_UCODE_ID_SMC];
-		if (!ucode->fw || amdgpu_sriov_vf(adev))
-			goto out;
-
-		ret = psp_execute_np_fw_load(psp, ucode);
+	if (psp->autoload_supported &&
+	    !psp->pmfw_centralized_cstate_management) {
+		ret = psp_load_smu_fw(psp);
 		if (ret)
 			return ret;
 	}
 
-	if (psp->pmfw_centralized_cstate_management) {
-		ret = psp_tmr_load(psp);
-		if (ret) {
-			DRM_ERROR("PSP load tmr failed!\n");
-			return ret;
-		}
-	}
-
-out:
 	for (i = 0; i < adev->firmware.max_ucodes; i++) {
 		ucode = &adev->firmware.ucode[i];
-		if (!ucode->fw)
-			continue;
 
 		if (ucode->ucode_id == AMDGPU_UCODE_ID_SMC &&
-		    (psp_smu_reload_quirk(psp) ||
-		     psp->autoload_supported ||
-		     psp->pmfw_centralized_cstate_management))
-			continue;
-
-		if (amdgpu_sriov_vf(adev) &&
-		   (ucode->ucode_id == AMDGPU_UCODE_ID_SDMA0
-		    || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA1
-		    || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA2
-		    || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA3
-		    || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA4
-		    || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA5
-		    || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA6
-		    || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA7
-                    || ucode->ucode_id == AMDGPU_UCODE_ID_RLC_G
-	            || ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL
-	            || ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM
-	            || ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM
-	            || ucode->ucode_id == AMDGPU_UCODE_ID_SMC))
-			/*skip ucode loading in SRIOV VF */
+		    !fw_load_skip_check(psp, ucode)) {
+			ret = psp_load_smu_fw(psp);
+			if (ret)
+				return ret;
 			continue;
+		}
 
-		if (psp->autoload_supported &&
-		    (ucode->ucode_id == AMDGPU_UCODE_ID_CP_MEC1_JT ||
-		     ucode->ucode_id == AMDGPU_UCODE_ID_CP_MEC2_JT))
-			/* skip mec JT when autoload is enabled */
+		if (fw_load_skip_check(psp, ucode))
 			continue;
 
 		psp_print_fw_hdr(psp, ucode);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
index 297435c0c7c1..6a717fd5efc7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
@@ -161,6 +161,7 @@ struct psp_hdcp_context {
 	struct amdgpu_bo	*hdcp_shared_bo;
 	uint64_t		hdcp_shared_mc_addr;
 	void			*hdcp_shared_buf;
+	struct mutex		mutex;
 };
 
 struct psp_dtm_context {
@@ -169,6 +170,7 @@ struct psp_dtm_context {
 	struct amdgpu_bo	*dtm_shared_bo;
 	uint64_t		dtm_shared_mc_addr;
 	void			*dtm_shared_buf;
+	struct mutex		mutex;
 };
 
 #define MEM_TRAIN_SYSTEM_SIGNATURE		0x54534942
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
index ab379b44679c..68b82f7b0b80 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
@@ -80,6 +80,20 @@ atomic_t amdgpu_ras_in_intr = ATOMIC_INIT(0);
 static bool amdgpu_ras_check_bad_page(struct amdgpu_device *adev,
 				uint64_t addr);
 
+void amdgpu_ras_set_error_query_ready(struct amdgpu_device *adev, bool ready)
+{
+	if (adev && amdgpu_ras_get_context(adev))
+		amdgpu_ras_get_context(adev)->error_query_ready = ready;
+}
+
+bool amdgpu_ras_get_error_query_ready(struct amdgpu_device *adev)
+{
+	if (adev && amdgpu_ras_get_context(adev))
+		return amdgpu_ras_get_context(adev)->error_query_ready;
+
+	return false;
+}
+
 static ssize_t amdgpu_ras_debugfs_read(struct file *f, char __user *buf,
 					size_t size, loff_t *pos)
 {
@@ -281,8 +295,9 @@ static ssize_t amdgpu_ras_debugfs_ctrl_write(struct file *f, const char __user *
 	struct ras_debug_if data;
 	int ret = 0;
 
-	if (amdgpu_ras_intr_triggered()) {
-		DRM_WARN("RAS WARN: error injection currently inaccessible\n");
+	if (!amdgpu_ras_get_error_query_ready(adev)) {
+		dev_warn(adev->dev, "RAS WARN: error injection "
+				"currently inaccessible\n");
 		return size;
 	}
 
@@ -310,7 +325,8 @@ static ssize_t amdgpu_ras_debugfs_ctrl_write(struct file *f, const char __user *
 		/* umc ce/ue error injection for a bad page is not allowed */
 		if ((data.head.block == AMDGPU_RAS_BLOCK__UMC) &&
 		    amdgpu_ras_check_bad_page(adev, data.inject.address)) {
-			DRM_WARN("RAS WARN: 0x%llx has been marked as bad before error injection!\n",
+			dev_warn(adev->dev, "RAS WARN: 0x%llx has been marked "
+					"as bad before error injection!\n",
 					data.inject.address);
 			break;
 		}
@@ -399,7 +415,7 @@ static ssize_t amdgpu_ras_sysfs_read(struct device *dev,
 		.head = obj->head,
 	};
 
-	if (amdgpu_ras_intr_triggered())
+	if (!amdgpu_ras_get_error_query_ready(obj->adev))
 		return snprintf(buf, PAGE_SIZE,
 				"Query currently inaccessible\n");
 
@@ -576,7 +592,8 @@ int amdgpu_ras_feature_enable(struct amdgpu_device *adev,
 	if (!amdgpu_ras_intr_triggered()) {
 		ret = psp_ras_enable_features(&adev->psp, &info, enable);
 		if (ret) {
-			DRM_ERROR("RAS ERROR: %s %s feature failed ret %d\n",
+			dev_err(adev->dev, "RAS ERROR: %s %s feature "
+					"failed ret %d\n",
 					enable ? "enable":"disable",
 					ras_block_str(head->block),
 					ret);
@@ -618,7 +635,8 @@ int amdgpu_ras_feature_enable_on_boot(struct amdgpu_device *adev,
 			if (ret == -EINVAL) {
 				ret = __amdgpu_ras_feature_enable(adev, head, 1);
 				if (!ret)
-					DRM_INFO("RAS INFO: %s setup object\n",
+					dev_info(adev->dev,
+						"RAS INFO: %s setup object\n",
 						ras_block_str(head->block));
 			}
 		} else {
@@ -744,12 +762,17 @@ int amdgpu_ras_error_query(struct amdgpu_device *adev,
 	info->ce_count = obj->err_data.ce_count;
 
 	if (err_data.ce_count) {
-		dev_info(adev->dev, "%ld correctable errors detected in %s block\n",
-			 obj->err_data.ce_count, ras_block_str(info->head.block));
+		dev_info(adev->dev, "%ld correctable hardware errors "
+					"detected in %s block, no user "
+					"action is needed.\n",
+					obj->err_data.ce_count,
+					ras_block_str(info->head.block));
 	}
 	if (err_data.ue_count) {
-		dev_info(adev->dev, "%ld uncorrectable errors detected in %s block\n",
-			 obj->err_data.ue_count, ras_block_str(info->head.block));
+		dev_info(adev->dev, "%ld uncorrectable hardware errors "
+					"detected in %s block\n",
+					obj->err_data.ue_count,
+					ras_block_str(info->head.block));
 	}
 
 	return 0;
@@ -793,13 +816,13 @@ int amdgpu_ras_error_inject(struct amdgpu_device *adev,
 		ret = psp_ras_trigger_error(&adev->psp, &block_info);
 		break;
 	default:
-		DRM_INFO("%s error injection is not supported yet\n",
+		dev_info(adev->dev, "%s error injection is not supported yet\n",
 			 ras_block_str(info->head.block));
 		ret = -EINVAL;
 	}
 
 	if (ret)
-		DRM_ERROR("RAS ERROR: inject %s error failed ret %d\n",
+		dev_err(adev->dev, "RAS ERROR: inject %s error failed ret %d\n",
 				ras_block_str(info->head.block),
 				ret);
 
@@ -1430,9 +1453,10 @@ static void amdgpu_ras_do_recovery(struct work_struct *work)
 	struct amdgpu_hive_info *hive = amdgpu_get_xgmi_hive(adev, false);
 
 	/* Build list of devices to query RAS related errors */
-	if  (hive && adev->gmc.xgmi.num_physical_nodes > 1) {
+	if  (hive && adev->gmc.xgmi.num_physical_nodes > 1)
 		device_list_handle = &hive->device_list;
-	} else {
+	else {
+		INIT_LIST_HEAD(&device_list);
 		list_add_tail(&adev->gmc.xgmi.head, &device_list);
 		device_list_handle = &device_list;
 	}
@@ -1535,7 +1559,7 @@ static int amdgpu_ras_save_bad_pages(struct amdgpu_device *adev)
 							&data->bps[control->num_recs],
 							true,
 							save_count)) {
-			DRM_ERROR("Failed to save EEPROM table data!");
+			dev_err(adev->dev, "Failed to save EEPROM table data!");
 			return -EIO;
 		}
 
@@ -1563,7 +1587,7 @@ static int amdgpu_ras_load_bad_pages(struct amdgpu_device *adev)
 
 	if (amdgpu_ras_eeprom_process_recods(control, bps, false,
 		control->num_recs)) {
-		DRM_ERROR("Failed to load EEPROM table records!");
+		dev_err(adev->dev, "Failed to load EEPROM table records!");
 		ret = -EIO;
 		goto out;
 	}
@@ -1637,7 +1661,8 @@ int amdgpu_ras_reserve_bad_pages(struct amdgpu_device *adev)
 					       AMDGPU_GPU_PAGE_SIZE,
 					       AMDGPU_GEM_DOMAIN_VRAM,
 					       &bo, NULL))
-			DRM_WARN("RAS WARN: reserve vram for retired page %llx fail\n", bp);
+			dev_warn(adev->dev, "RAS WARN: reserve vram for "
+					"retired page %llx fail\n", bp);
 
 		data->bps_bo[i] = bo;
 		data->last_reserved = i + 1;
@@ -1725,7 +1750,7 @@ int amdgpu_ras_recovery_init(struct amdgpu_device *adev)
 	kfree(*data);
 	con->eh_data = NULL;
 out:
-	DRM_WARN("Failed to initialize ras recovery!\n");
+	dev_warn(adev->dev, "Failed to initialize ras recovery!\n");
 
 	return ret;
 }
@@ -1787,18 +1812,18 @@ static void amdgpu_ras_check_supported(struct amdgpu_device *adev,
 		return;
 
 	if (amdgpu_atomfirmware_mem_ecc_supported(adev)) {
-		DRM_INFO("HBM ECC is active.\n");
+		dev_info(adev->dev, "HBM ECC is active.\n");
 		*hw_supported |= (1 << AMDGPU_RAS_BLOCK__UMC |
 				1 << AMDGPU_RAS_BLOCK__DF);
 	} else
-		DRM_INFO("HBM ECC is not presented.\n");
+		dev_info(adev->dev, "HBM ECC is not presented.\n");
 
 	if (amdgpu_atomfirmware_sram_ecc_supported(adev)) {
-		DRM_INFO("SRAM ECC is active.\n");
+		dev_info(adev->dev, "SRAM ECC is active.\n");
 		*hw_supported |= ~(1 << AMDGPU_RAS_BLOCK__UMC |
 				1 << AMDGPU_RAS_BLOCK__DF);
 	} else
-		DRM_INFO("SRAM ECC is not presented.\n");
+		dev_info(adev->dev, "SRAM ECC is not presented.\n");
 
 	/* hw_supported needs to be aligned with RAS block mask. */
 	*hw_supported &= AMDGPU_RAS_BLOCK_MASK;
@@ -1855,7 +1880,7 @@ int amdgpu_ras_init(struct amdgpu_device *adev)
 	if (amdgpu_ras_fs_init(adev))
 		goto fs_out;
 
-	DRM_INFO("RAS INFO: ras initialized successfully, "
+	dev_info(adev->dev, "RAS INFO: ras initialized successfully, "
 			"hardware ability[%x] ras_mask[%x]\n",
 			con->hw_supported, con->supported);
 	return 0;
@@ -1896,8 +1921,10 @@ int amdgpu_ras_late_init(struct amdgpu_device *adev,
 	}
 
 	/* in resume phase, no need to create ras fs node */
-	if (adev->in_suspend || adev->in_gpu_reset)
+	if (adev->in_suspend || adev->in_gpu_reset) {
+		amdgpu_ras_set_error_query_ready(adev, true);
 		return 0;
+	}
 
 	if (ih_info->cb) {
 		r = amdgpu_ras_interrupt_add_handler(adev, ih_info);
@@ -1909,6 +1936,8 @@ int amdgpu_ras_late_init(struct amdgpu_device *adev,
 	if (r)
 		goto sysfs;
 
+	amdgpu_ras_set_error_query_ready(adev, true);
+
 	return 0;
 cleanup:
 	amdgpu_ras_sysfs_remove(adev, ras_block);
@@ -2037,7 +2066,8 @@ void amdgpu_ras_global_ras_isr(struct amdgpu_device *adev)
 		return;
 
 	if (atomic_cmpxchg(&amdgpu_ras_in_intr, 0, 1) == 0) {
-		DRM_WARN("RAS event of type ERREVENT_ATHUB_INTERRUPT detected!\n");
+		dev_info(adev->dev, "uncorrectable hardware error"
+			"(ERREVENT_ATHUB_INTERRUPT) detected!\n");
 
 		amdgpu_ras_reset_gpu(adev);
 	}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h
index 55c3eceb390d..e7df5d8429f8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h
@@ -334,6 +334,8 @@ struct amdgpu_ras {
 	uint32_t flags;
 	bool reboot;
 	struct amdgpu_ras_eeprom_control eeprom_control;
+
+	bool error_query_ready;
 };
 
 struct ras_fs_data {
@@ -629,4 +631,6 @@ static inline void amdgpu_ras_intr_cleared(void)
 
 void amdgpu_ras_global_ras_isr(struct amdgpu_device *adev);
 
+void amdgpu_ras_set_error_query_ready(struct amdgpu_device *adev, bool ready);
+
 #endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
index a7e1d0425ed0..13ea8ebc421c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
@@ -162,11 +162,13 @@ void amdgpu_ring_undo(struct amdgpu_ring *ring)
  * Returns 0 on success, error on failure.
  */
 int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring,
-		     unsigned max_dw, struct amdgpu_irq_src *irq_src,
-		     unsigned irq_type)
+		     unsigned int max_dw, struct amdgpu_irq_src *irq_src,
+		     unsigned int irq_type, unsigned int hw_prio)
 {
 	int r, i;
 	int sched_hw_submission = amdgpu_sched_hw_submission;
+	u32 *num_sched;
+	u32 hw_ip;
 
 	/* Set the hw submission limit higher for KIQ because
 	 * it's used for a number of gfx/compute tasks by both
@@ -258,6 +260,13 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring,
 	ring->priority = DRM_SCHED_PRIORITY_NORMAL;
 	mutex_init(&ring->priority_mutex);
 
+	if (!ring->no_scheduler) {
+		hw_ip = ring->funcs->type;
+		num_sched = &adev->gpu_sched[hw_ip][hw_prio].num_scheds;
+		adev->gpu_sched[hw_ip][hw_prio].sched[(*num_sched)++] =
+			&ring->sched;
+	}
+
 	for (i = 0; i < DRM_SCHED_PRIORITY_MAX; ++i)
 		atomic_set(&ring->num_jobs[i], 0);
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
index 9a443013d70d..f61664ee4940 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
@@ -30,11 +30,15 @@
 
 /* max number of rings */
 #define AMDGPU_MAX_RINGS		28
+#define AMDGPU_MAX_HWIP_RINGS		8
 #define AMDGPU_MAX_GFX_RINGS		2
 #define AMDGPU_MAX_COMPUTE_RINGS	8
 #define AMDGPU_MAX_VCE_RINGS		3
 #define AMDGPU_MAX_UVD_ENC_RINGS	2
 
+#define AMDGPU_RING_PRIO_DEFAULT	1
+#define AMDGPU_RING_PRIO_MAX		AMDGPU_GFX_PIPE_PRIO_MAX
+
 /* some special values for the owner field */
 #define AMDGPU_FENCE_OWNER_UNDEFINED	((void *)0ul)
 #define AMDGPU_FENCE_OWNER_VM		((void *)1ul)
@@ -46,17 +50,30 @@
 
 #define to_amdgpu_ring(s) container_of((s), struct amdgpu_ring, sched)
 
+#define AMDGPU_IB_POOL_SIZE	(1024 * 1024)
+
 enum amdgpu_ring_type {
-	AMDGPU_RING_TYPE_GFX,
-	AMDGPU_RING_TYPE_COMPUTE,
-	AMDGPU_RING_TYPE_SDMA,
-	AMDGPU_RING_TYPE_UVD,
-	AMDGPU_RING_TYPE_VCE,
-	AMDGPU_RING_TYPE_KIQ,
-	AMDGPU_RING_TYPE_UVD_ENC,
-	AMDGPU_RING_TYPE_VCN_DEC,
-	AMDGPU_RING_TYPE_VCN_ENC,
-	AMDGPU_RING_TYPE_VCN_JPEG
+	AMDGPU_RING_TYPE_GFX		= AMDGPU_HW_IP_GFX,
+	AMDGPU_RING_TYPE_COMPUTE	= AMDGPU_HW_IP_COMPUTE,
+	AMDGPU_RING_TYPE_SDMA		= AMDGPU_HW_IP_DMA,
+	AMDGPU_RING_TYPE_UVD		= AMDGPU_HW_IP_UVD,
+	AMDGPU_RING_TYPE_VCE		= AMDGPU_HW_IP_VCE,
+	AMDGPU_RING_TYPE_UVD_ENC	= AMDGPU_HW_IP_UVD_ENC,
+	AMDGPU_RING_TYPE_VCN_DEC	= AMDGPU_HW_IP_VCN_DEC,
+	AMDGPU_RING_TYPE_VCN_ENC	= AMDGPU_HW_IP_VCN_ENC,
+	AMDGPU_RING_TYPE_VCN_JPEG	= AMDGPU_HW_IP_VCN_JPEG,
+	AMDGPU_RING_TYPE_KIQ
+};
+
+enum amdgpu_ib_pool_type {
+	/* Normal submissions to the top of the pipeline. */
+	AMDGPU_IB_POOL_DELAYED,
+	/* Immediate submissions to the bottom of the pipeline. */
+	AMDGPU_IB_POOL_IMMEDIATE,
+	/* Direct submission to the ring buffer during init and reset. */
+	AMDGPU_IB_POOL_DIRECT,
+
+	AMDGPU_IB_POOL_MAX
 };
 
 struct amdgpu_device;
@@ -65,6 +82,11 @@ struct amdgpu_ib;
 struct amdgpu_cs_parser;
 struct amdgpu_job;
 
+struct amdgpu_sched {
+	u32				num_scheds;
+	struct drm_gpu_scheduler	*sched[AMDGPU_MAX_HWIP_RINGS];
+};
+
 /*
  * Fences.
  */
@@ -166,10 +188,12 @@ struct amdgpu_ring_funcs {
 	void (*emit_reg_write_reg_wait)(struct amdgpu_ring *ring,
 					uint32_t reg0, uint32_t reg1,
 					uint32_t ref, uint32_t mask);
-	void (*emit_tmz)(struct amdgpu_ring *ring, bool start);
+	void (*emit_frame_cntl)(struct amdgpu_ring *ring, bool start,
+				bool secure);
 	/* Try to soft recover the ring to make the fence signal */
 	void (*soft_recovery)(struct amdgpu_ring *ring, unsigned vmid);
 	int (*preempt_ib)(struct amdgpu_ring *ring);
+	void (*emit_mem_sync)(struct amdgpu_ring *ring);
 };
 
 struct amdgpu_ring {
@@ -214,12 +238,12 @@ struct amdgpu_ring {
 	unsigned		vm_inv_eng;
 	struct dma_fence	*vmid_wait;
 	bool			has_compute_vm_bug;
+	bool			no_scheduler;
 
 	atomic_t		num_jobs[DRM_SCHED_PRIORITY_MAX];
 	struct mutex		priority_mutex;
 	/* protected by priority_mutex */
 	int			priority;
-	bool			has_high_prio;
 
 #if defined(CONFIG_DEBUG_FS)
 	struct dentry *ent;
@@ -245,7 +269,7 @@ struct amdgpu_ring {
 #define amdgpu_ring_emit_wreg(r, d, v) (r)->funcs->emit_wreg((r), (d), (v))
 #define amdgpu_ring_emit_reg_wait(r, d, v, m) (r)->funcs->emit_reg_wait((r), (d), (v), (m))
 #define amdgpu_ring_emit_reg_write_reg_wait(r, d0, d1, v, m) (r)->funcs->emit_reg_write_reg_wait((r), (d0), (d1), (v), (m))
-#define amdgpu_ring_emit_tmz(r, b) (r)->funcs->emit_tmz((r), (b))
+#define amdgpu_ring_emit_frame_cntl(r, b, s) (r)->funcs->emit_frame_cntl((r), (b), (s))
 #define amdgpu_ring_pad_ib(r, ib) ((r)->funcs->pad_ib((r), (ib)))
 #define amdgpu_ring_init_cond_exec(r) (r)->funcs->init_cond_exec((r))
 #define amdgpu_ring_patch_cond_exec(r,o) (r)->funcs->patch_cond_exec((r),(o))
@@ -257,8 +281,8 @@ void amdgpu_ring_generic_pad_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib);
 void amdgpu_ring_commit(struct amdgpu_ring *ring);
 void amdgpu_ring_undo(struct amdgpu_ring *ring);
 int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring,
-		     unsigned ring_size, struct amdgpu_irq_src *irq_src,
-		     unsigned irq_type);
+		     unsigned int ring_size, struct amdgpu_irq_src *irq_src,
+		     unsigned int irq_type, unsigned int prio);
 void amdgpu_ring_fini(struct amdgpu_ring *ring);
 void amdgpu_ring_emit_reg_write_reg_wait_helper(struct amdgpu_ring *ring,
 						uint32_t reg0, uint32_t val0,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h
index 4b352206354b..e5b8fb8e75c5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h
@@ -61,8 +61,6 @@ struct amdgpu_sdma_ras_funcs {
 
 struct amdgpu_sdma {
 	struct amdgpu_sdma_instance instance[AMDGPU_MAX_SDMA_INSTANCES];
-	struct drm_gpu_scheduler    *sdma_sched[AMDGPU_MAX_SDMA_INSTANCES];
-	uint32_t		    num_sdma_sched;
 	struct amdgpu_irq_src	trap_irq;
 	struct amdgpu_irq_src	illegal_inst_irq;
 	struct amdgpu_irq_src	ecc_irq;
@@ -91,7 +89,8 @@ struct amdgpu_buffer_funcs {
 				 /* dst addr in bytes */
 				 uint64_t dst_offset,
 				 /* number of byte to transfer */
-				 uint32_t byte_count);
+				 uint32_t byte_count,
+				 bool tmz);
 
 	/* maximum bytes in a single operation */
 	uint32_t	fill_max_bytes;
@@ -109,7 +108,7 @@ struct amdgpu_buffer_funcs {
 				 uint32_t byte_count);
 };
 
-#define amdgpu_emit_copy_buffer(adev, ib, s, d, b) (adev)->mman.buffer_funcs->emit_copy_buffer((ib),  (s), (d), (b))
+#define amdgpu_emit_copy_buffer(adev, ib, s, d, b, t) (adev)->mman.buffer_funcs->emit_copy_buffer((ib),  (s), (d), (b), (t))
 #define amdgpu_emit_fill_buffer(adev, ib, s, d, b) (adev)->mman.buffer_funcs->emit_fill_buffer((ib), (s), (d), (b))
 
 struct amdgpu_sdma_instance *
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
index b86392253696..b87ca171986a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
@@ -249,6 +249,11 @@ int amdgpu_sync_resv(struct amdgpu_device *adev, struct amdgpu_sync *sync,
 		    owner != AMDGPU_FENCE_OWNER_UNDEFINED)
 			continue;
 
+		/* Never sync to VM updates either. */
+		if (fence_owner == AMDGPU_FENCE_OWNER_VM &&
+		    owner != AMDGPU_FENCE_OWNER_UNDEFINED)
+			continue;
+
 		/* Ignore fences depending on the sync mode */
 		switch (mode) {
 		case AMDGPU_SYNC_ALWAYS:
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c
index b158230af8db..2f4d5ca9894f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c
@@ -44,7 +44,7 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev)
 	/* Number of tests =
 	 * (Total GTT - IB pool - writeback page - ring buffers) / test size
 	 */
-	n = adev->gmc.gart_size - AMDGPU_IB_POOL_SIZE*64*1024;
+	n = adev->gmc.gart_size - AMDGPU_IB_POOL_SIZE;
 	for (i = 0; i < AMDGPU_MAX_RINGS; ++i)
 		if (adev->rings[i])
 			n -= adev->rings[i]->ring_size;
@@ -124,7 +124,7 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev)
 		amdgpu_bo_kunmap(gtt_obj[i]);
 
 		r = amdgpu_copy_buffer(ring, gart_addr, vram_addr,
-				       size, NULL, &fence, false, false);
+				       size, NULL, &fence, false, false, false);
 
 		if (r) {
 			DRM_ERROR("Failed GTT->VRAM copy %d\n", i);
@@ -170,7 +170,7 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev)
 		amdgpu_bo_kunmap(vram_obj);
 
 		r = amdgpu_copy_buffer(ring, vram_addr, gart_addr,
-				       size, NULL, &fence, false, false);
+				       size, NULL, &fence, false, false, false);
 
 		if (r) {
 			DRM_ERROR("Failed VRAM->GTT copy %d\n", i);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h
index 63e734a125fb..5da20fc166d9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h
@@ -35,7 +35,7 @@
 #define AMDGPU_JOB_GET_TIMELINE_NAME(job) \
 	 job->base.s_fence->finished.ops->get_timeline_name(&job->base.s_fence->finished)
 
-TRACE_EVENT(amdgpu_mm_rreg,
+TRACE_EVENT(amdgpu_device_rreg,
 	    TP_PROTO(unsigned did, uint32_t reg, uint32_t value),
 	    TP_ARGS(did, reg, value),
 	    TP_STRUCT__entry(
@@ -54,7 +54,7 @@ TRACE_EVENT(amdgpu_mm_rreg,
 		      (unsigned long)__entry->value)
 );
 
-TRACE_EVENT(amdgpu_mm_wreg,
+TRACE_EVENT(amdgpu_device_wreg,
 	    TP_PROTO(unsigned did, uint32_t reg, uint32_t value),
 	    TP_ARGS(did, reg, value),
 	    TP_STRUCT__entry(
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 6309ff72bd78..d5543c25f3c7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -62,11 +62,6 @@
 
 #define AMDGPU_TTM_VRAM_MAX_DW_READ	(size_t)128
 
-static int amdgpu_map_buffer(struct ttm_buffer_object *bo,
-			     struct ttm_mem_reg *mem, unsigned num_pages,
-			     uint64_t offset, unsigned window,
-			     struct amdgpu_ring *ring,
-			     uint64_t *addr);
 
 /**
  * amdgpu_init_mem_type - Initialize a memory manager for a specific type of
@@ -277,7 +272,7 @@ static uint64_t amdgpu_mm_node_addr(struct ttm_buffer_object *bo,
  *
  */
 static struct drm_mm_node *amdgpu_find_mm_node(struct ttm_mem_reg *mem,
-					       unsigned long *offset)
+					       uint64_t *offset)
 {
 	struct drm_mm_node *mm_node = mem->mm_node;
 
@@ -288,92 +283,192 @@ static struct drm_mm_node *amdgpu_find_mm_node(struct ttm_mem_reg *mem,
 	return mm_node;
 }
 
+/**
+ * amdgpu_ttm_map_buffer - Map memory into the GART windows
+ * @bo: buffer object to map
+ * @mem: memory object to map
+ * @mm_node: drm_mm node object to map
+ * @num_pages: number of pages to map
+ * @offset: offset into @mm_node where to start
+ * @window: which GART window to use
+ * @ring: DMA ring to use for the copy
+ * @tmz: if we should setup a TMZ enabled mapping
+ * @addr: resulting address inside the MC address space
+ *
+ * Setup one of the GART windows to access a specific piece of memory or return
+ * the physical address for local memory.
+ */
+static int amdgpu_ttm_map_buffer(struct ttm_buffer_object *bo,
+				 struct ttm_mem_reg *mem,
+				 struct drm_mm_node *mm_node,
+				 unsigned num_pages, uint64_t offset,
+				 unsigned window, struct amdgpu_ring *ring,
+				 bool tmz, uint64_t *addr)
+{
+	struct amdgpu_device *adev = ring->adev;
+	struct amdgpu_job *job;
+	unsigned num_dw, num_bytes;
+	struct dma_fence *fence;
+	uint64_t src_addr, dst_addr;
+	void *cpu_addr;
+	uint64_t flags;
+	unsigned int i;
+	int r;
+
+	BUG_ON(adev->mman.buffer_funcs->copy_max_bytes <
+	       AMDGPU_GTT_MAX_TRANSFER_SIZE * 8);
+
+	/* Map only what can't be accessed directly */
+	if (!tmz && mem->start != AMDGPU_BO_INVALID_OFFSET) {
+		*addr = amdgpu_mm_node_addr(bo, mm_node, mem) + offset;
+		return 0;
+	}
+
+	*addr = adev->gmc.gart_start;
+	*addr += (u64)window * AMDGPU_GTT_MAX_TRANSFER_SIZE *
+		AMDGPU_GPU_PAGE_SIZE;
+	*addr += offset & ~PAGE_MASK;
+
+	num_dw = ALIGN(adev->mman.buffer_funcs->copy_num_dw, 8);
+	num_bytes = num_pages * 8;
+
+	r = amdgpu_job_alloc_with_ib(adev, num_dw * 4 + num_bytes,
+				     AMDGPU_IB_POOL_DELAYED, &job);
+	if (r)
+		return r;
+
+	src_addr = num_dw * 4;
+	src_addr += job->ibs[0].gpu_addr;
+
+	dst_addr = amdgpu_bo_gpu_offset(adev->gart.bo);
+	dst_addr += window * AMDGPU_GTT_MAX_TRANSFER_SIZE * 8;
+	amdgpu_emit_copy_buffer(adev, &job->ibs[0], src_addr,
+				dst_addr, num_bytes, false);
+
+	amdgpu_ring_pad_ib(ring, &job->ibs[0]);
+	WARN_ON(job->ibs[0].length_dw > num_dw);
+
+	flags = amdgpu_ttm_tt_pte_flags(adev, bo->ttm, mem);
+	if (tmz)
+		flags |= AMDGPU_PTE_TMZ;
+
+	cpu_addr = &job->ibs[0].ptr[num_dw];
+
+	if (mem->mem_type == TTM_PL_TT) {
+		struct ttm_dma_tt *dma;
+		dma_addr_t *dma_address;
+
+		dma = container_of(bo->ttm, struct ttm_dma_tt, ttm);
+		dma_address = &dma->dma_address[offset >> PAGE_SHIFT];
+		r = amdgpu_gart_map(adev, 0, num_pages, dma_address, flags,
+				    cpu_addr);
+		if (r)
+			goto error_free;
+	} else {
+		dma_addr_t dma_address;
+
+		dma_address = (mm_node->start << PAGE_SHIFT) + offset;
+		dma_address += adev->vm_manager.vram_base_offset;
+
+		for (i = 0; i < num_pages; ++i) {
+			r = amdgpu_gart_map(adev, i << PAGE_SHIFT, 1,
+					    &dma_address, flags, cpu_addr);
+			if (r)
+				goto error_free;
+
+			dma_address += PAGE_SIZE;
+		}
+	}
+
+	r = amdgpu_job_submit(job, &adev->mman.entity,
+			      AMDGPU_FENCE_OWNER_UNDEFINED, &fence);
+	if (r)
+		goto error_free;
+
+	dma_fence_put(fence);
+
+	return r;
+
+error_free:
+	amdgpu_job_free(job);
+	return r;
+}
+
 /**
  * amdgpu_copy_ttm_mem_to_mem - Helper function for copy
+ * @adev: amdgpu device
+ * @src: buffer/address where to read from
+ * @dst: buffer/address where to write to
+ * @size: number of bytes to copy
+ * @tmz: if a secure copy should be used
+ * @resv: resv object to sync to
+ * @f: Returns the last fence if multiple jobs are submitted.
  *
  * The function copies @size bytes from {src->mem + src->offset} to
  * {dst->mem + dst->offset}. src->bo and dst->bo could be same BO for a
  * move and different for a BO to BO copy.
  *
- * @f: Returns the last fence if multiple jobs are submitted.
  */
 int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev,
-			       struct amdgpu_copy_mem *src,
-			       struct amdgpu_copy_mem *dst,
-			       uint64_t size,
+			       const struct amdgpu_copy_mem *src,
+			       const struct amdgpu_copy_mem *dst,
+			       uint64_t size, bool tmz,
 			       struct dma_resv *resv,
 			       struct dma_fence **f)
 {
+	const uint32_t GTT_MAX_BYTES = (AMDGPU_GTT_MAX_TRANSFER_SIZE *
+					AMDGPU_GPU_PAGE_SIZE);
+
+	uint64_t src_node_size, dst_node_size, src_offset, dst_offset;
 	struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
 	struct drm_mm_node *src_mm, *dst_mm;
-	uint64_t src_node_start, dst_node_start, src_node_size,
-		 dst_node_size, src_page_offset, dst_page_offset;
 	struct dma_fence *fence = NULL;
 	int r = 0;
-	const uint64_t GTT_MAX_BYTES = (AMDGPU_GTT_MAX_TRANSFER_SIZE *
-					AMDGPU_GPU_PAGE_SIZE);
 
 	if (!adev->mman.buffer_funcs_enabled) {
 		DRM_ERROR("Trying to move memory with ring turned off.\n");
 		return -EINVAL;
 	}
 
-	src_mm = amdgpu_find_mm_node(src->mem, &src->offset);
-	src_node_start = amdgpu_mm_node_addr(src->bo, src_mm, src->mem) +
-					     src->offset;
-	src_node_size = (src_mm->size << PAGE_SHIFT) - src->offset;
-	src_page_offset = src_node_start & (PAGE_SIZE - 1);
+	src_offset = src->offset;
+	src_mm = amdgpu_find_mm_node(src->mem, &src_offset);
+	src_node_size = (src_mm->size << PAGE_SHIFT) - src_offset;
 
-	dst_mm = amdgpu_find_mm_node(dst->mem, &dst->offset);
-	dst_node_start = amdgpu_mm_node_addr(dst->bo, dst_mm, dst->mem) +
-					     dst->offset;
-	dst_node_size = (dst_mm->size << PAGE_SHIFT) - dst->offset;
-	dst_page_offset = dst_node_start & (PAGE_SIZE - 1);
+	dst_offset = dst->offset;
+	dst_mm = amdgpu_find_mm_node(dst->mem, &dst_offset);
+	dst_node_size = (dst_mm->size << PAGE_SHIFT) - dst_offset;
 
 	mutex_lock(&adev->mman.gtt_window_lock);
 
 	while (size) {
-		unsigned long cur_size;
-		uint64_t from = src_node_start, to = dst_node_start;
+		uint32_t src_page_offset = src_offset & ~PAGE_MASK;
+		uint32_t dst_page_offset = dst_offset & ~PAGE_MASK;
 		struct dma_fence *next;
+		uint32_t cur_size;
+		uint64_t from, to;
 
 		/* Copy size cannot exceed GTT_MAX_BYTES. So if src or dst
 		 * begins at an offset, then adjust the size accordingly
 		 */
-		cur_size = min3(min(src_node_size, dst_node_size), size,
-				GTT_MAX_BYTES);
-		if (cur_size + src_page_offset > GTT_MAX_BYTES ||
-		    cur_size + dst_page_offset > GTT_MAX_BYTES)
-			cur_size -= max(src_page_offset, dst_page_offset);
-
-		/* Map only what needs to be accessed. Map src to window 0 and
-		 * dst to window 1
-		 */
-		if (src->mem->start == AMDGPU_BO_INVALID_OFFSET) {
-			r = amdgpu_map_buffer(src->bo, src->mem,
-					PFN_UP(cur_size + src_page_offset),
-					src_node_start, 0, ring,
-					&from);
-			if (r)
-				goto error;
-			/* Adjust the offset because amdgpu_map_buffer returns
-			 * start of mapped page
-			 */
-			from += src_page_offset;
-		}
+		cur_size = max(src_page_offset, dst_page_offset);
+		cur_size = min(min3(src_node_size, dst_node_size, size),
+			       (uint64_t)(GTT_MAX_BYTES - cur_size));
+
+		/* Map src to window 0 and dst to window 1. */
+		r = amdgpu_ttm_map_buffer(src->bo, src->mem, src_mm,
+					  PFN_UP(cur_size + src_page_offset),
+					  src_offset, 0, ring, tmz, &from);
+		if (r)
+			goto error;
 
-		if (dst->mem->start == AMDGPU_BO_INVALID_OFFSET) {
-			r = amdgpu_map_buffer(dst->bo, dst->mem,
-					PFN_UP(cur_size + dst_page_offset),
-					dst_node_start, 1, ring,
-					&to);
-			if (r)
-				goto error;
-			to += dst_page_offset;
-		}
+		r = amdgpu_ttm_map_buffer(dst->bo, dst->mem, dst_mm,
+					  PFN_UP(cur_size + dst_page_offset),
+					  dst_offset, 1, ring, tmz, &to);
+		if (r)
+			goto error;
 
 		r = amdgpu_copy_buffer(ring, from, to, cur_size,
-				       resv, &next, false, true);
+				       resv, &next, false, true, tmz);
 		if (r)
 			goto error;
 
@@ -386,23 +481,20 @@ int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev,
 
 		src_node_size -= cur_size;
 		if (!src_node_size) {
-			src_node_start = amdgpu_mm_node_addr(src->bo, ++src_mm,
-							     src->mem);
-			src_node_size = (src_mm->size << PAGE_SHIFT);
-			src_page_offset = 0;
+			++src_mm;
+			src_node_size = src_mm->size << PAGE_SHIFT;
+			src_offset = 0;
 		} else {
-			src_node_start += cur_size;
-			src_page_offset = src_node_start & (PAGE_SIZE - 1);
+			src_offset += cur_size;
 		}
+
 		dst_node_size -= cur_size;
 		if (!dst_node_size) {
-			dst_node_start = amdgpu_mm_node_addr(dst->bo, ++dst_mm,
-							     dst->mem);
-			dst_node_size = (dst_mm->size << PAGE_SHIFT);
-			dst_page_offset = 0;
+			++dst_mm;
+			dst_node_size = dst_mm->size << PAGE_SHIFT;
+			dst_offset = 0;
 		} else {
-			dst_node_start += cur_size;
-			dst_page_offset = dst_node_start & (PAGE_SIZE - 1);
+			dst_offset += cur_size;
 		}
 	}
 error:
@@ -425,6 +517,7 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo,
 			    struct ttm_mem_reg *old_mem)
 {
 	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev);
+	struct amdgpu_bo *abo = ttm_to_amdgpu_bo(bo);
 	struct amdgpu_copy_mem src, dst;
 	struct dma_fence *fence = NULL;
 	int r;
@@ -438,14 +531,14 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo,
 
 	r = amdgpu_ttm_copy_mem_to_mem(adev, &src, &dst,
 				       new_mem->num_pages << PAGE_SHIFT,
+				       amdgpu_bo_encrypted(abo),
 				       bo->base.resv, &fence);
 	if (r)
 		goto error;
 
 	/* clear the space being freed */
 	if (old_mem->mem_type == TTM_PL_VRAM &&
-	    (ttm_to_amdgpu_bo(bo)->flags &
-	     AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE)) {
+	    (abo->flags & AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE)) {
 		struct dma_fence *wipe_fence = NULL;
 
 		r = amdgpu_fill_buffer(ttm_to_amdgpu_bo(bo), AMDGPU_POISON,
@@ -742,8 +835,8 @@ static void amdgpu_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_mem_re
 static unsigned long amdgpu_ttm_io_mem_pfn(struct ttm_buffer_object *bo,
 					   unsigned long page_offset)
 {
+	uint64_t offset = (page_offset << PAGE_SHIFT);
 	struct drm_mm_node *mm;
-	unsigned long offset = (page_offset << PAGE_SHIFT);
 
 	mm = amdgpu_find_mm_node(&bo->mem, &offset);
 	return (bo->mem.bus.base >> PAGE_SHIFT) + mm->start +
@@ -1027,6 +1120,9 @@ int amdgpu_ttm_gart_bind(struct amdgpu_device *adev,
 	struct amdgpu_ttm_tt *gtt = (void *)ttm;
 	int r;
 
+	if (amdgpu_bo_encrypted(abo))
+		flags |= AMDGPU_PTE_TMZ;
+
 	if (abo->flags & AMDGPU_GEM_CREATE_CP_MQD_GFX9) {
 		uint64_t page_idx = 1;
 
@@ -1539,6 +1635,9 @@ static bool amdgpu_ttm_bo_eviction_valuable(struct ttm_buffer_object *bo,
 
 	switch (bo->mem.mem_type) {
 	case TTM_PL_TT:
+		if (amdgpu_bo_is_amdgpu_bo(bo) &&
+		    amdgpu_bo_encrypted(ttm_to_amdgpu_bo(bo)))
+			return false;
 		return true;
 
 	case TTM_PL_VRAM:
@@ -1587,8 +1686,9 @@ static int amdgpu_ttm_access_memory(struct ttm_buffer_object *bo,
 	if (bo->mem.mem_type != TTM_PL_VRAM)
 		return -EIO;
 
-	nodes = amdgpu_find_mm_node(&abo->tbo.mem, &offset);
-	pos = (nodes->start << PAGE_SHIFT) + offset;
+	pos = offset;
+	nodes = amdgpu_find_mm_node(&abo->tbo.mem, &pos);
+	pos += (nodes->start << PAGE_SHIFT);
 
 	while (len && pos < adev->gmc.mc_vram_size) {
 		uint64_t aligned_pos = pos & ~(uint64_t)3;
@@ -2015,75 +2115,14 @@ int amdgpu_mmap(struct file *filp, struct vm_area_struct *vma)
 	return ttm_bo_mmap(filp, vma, &adev->mman.bdev);
 }
 
-static int amdgpu_map_buffer(struct ttm_buffer_object *bo,
-			     struct ttm_mem_reg *mem, unsigned num_pages,
-			     uint64_t offset, unsigned window,
-			     struct amdgpu_ring *ring,
-			     uint64_t *addr)
-{
-	struct amdgpu_ttm_tt *gtt = (void *)bo->ttm;
-	struct amdgpu_device *adev = ring->adev;
-	struct ttm_tt *ttm = bo->ttm;
-	struct amdgpu_job *job;
-	unsigned num_dw, num_bytes;
-	dma_addr_t *dma_address;
-	struct dma_fence *fence;
-	uint64_t src_addr, dst_addr;
-	uint64_t flags;
-	int r;
-
-	BUG_ON(adev->mman.buffer_funcs->copy_max_bytes <
-	       AMDGPU_GTT_MAX_TRANSFER_SIZE * 8);
-
-	*addr = adev->gmc.gart_start;
-	*addr += (u64)window * AMDGPU_GTT_MAX_TRANSFER_SIZE *
-		AMDGPU_GPU_PAGE_SIZE;
-
-	num_dw = ALIGN(adev->mman.buffer_funcs->copy_num_dw, 8);
-	num_bytes = num_pages * 8;
-
-	r = amdgpu_job_alloc_with_ib(adev, num_dw * 4 + num_bytes, &job);
-	if (r)
-		return r;
-
-	src_addr = num_dw * 4;
-	src_addr += job->ibs[0].gpu_addr;
-
-	dst_addr = amdgpu_bo_gpu_offset(adev->gart.bo);
-	dst_addr += window * AMDGPU_GTT_MAX_TRANSFER_SIZE * 8;
-	amdgpu_emit_copy_buffer(adev, &job->ibs[0], src_addr,
-				dst_addr, num_bytes);
-
-	amdgpu_ring_pad_ib(ring, &job->ibs[0]);
-	WARN_ON(job->ibs[0].length_dw > num_dw);
-
-	dma_address = &gtt->ttm.dma_address[offset >> PAGE_SHIFT];
-	flags = amdgpu_ttm_tt_pte_flags(adev, ttm, mem);
-	r = amdgpu_gart_map(adev, 0, num_pages, dma_address, flags,
-			    &job->ibs[0].ptr[num_dw]);
-	if (r)
-		goto error_free;
-
-	r = amdgpu_job_submit(job, &adev->mman.entity,
-			      AMDGPU_FENCE_OWNER_UNDEFINED, &fence);
-	if (r)
-		goto error_free;
-
-	dma_fence_put(fence);
-
-	return r;
-
-error_free:
-	amdgpu_job_free(job);
-	return r;
-}
-
 int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset,
 		       uint64_t dst_offset, uint32_t byte_count,
 		       struct dma_resv *resv,
 		       struct dma_fence **fence, bool direct_submit,
-		       bool vm_needs_flush)
+		       bool vm_needs_flush, bool tmz)
 {
+	enum amdgpu_ib_pool_type pool = direct_submit ? AMDGPU_IB_POOL_DIRECT :
+		AMDGPU_IB_POOL_DELAYED;
 	struct amdgpu_device *adev = ring->adev;
 	struct amdgpu_job *job;
 
@@ -2101,7 +2140,7 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset,
 	num_loops = DIV_ROUND_UP(byte_count, max_bytes);
 	num_dw = ALIGN(num_loops * adev->mman.buffer_funcs->copy_num_dw, 8);
 
-	r = amdgpu_job_alloc_with_ib(adev, num_dw * 4, &job);
+	r = amdgpu_job_alloc_with_ib(adev, num_dw * 4, pool, &job);
 	if (r)
 		return r;
 
@@ -2123,7 +2162,7 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset,
 		uint32_t cur_size_in_bytes = min(byte_count, max_bytes);
 
 		amdgpu_emit_copy_buffer(adev, &job->ibs[0], src_offset,
-					dst_offset, cur_size_in_bytes);
+					dst_offset, cur_size_in_bytes, tmz);
 
 		src_offset += cur_size_in_bytes;
 		dst_offset += cur_size_in_bytes;
@@ -2190,7 +2229,8 @@ int amdgpu_fill_buffer(struct amdgpu_bo *bo,
 	/* for IB padding */
 	num_dw += 64;
 
-	r = amdgpu_job_alloc_with_ib(adev, num_dw * 4, &job);
+	r = amdgpu_job_alloc_with_ib(adev, num_dw * 4, AMDGPU_IB_POOL_DELAYED,
+				     &job);
 	if (r)
 		return r;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
index bd05bbb4878d..4351d02644a7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
@@ -24,8 +24,9 @@
 #ifndef __AMDGPU_TTM_H__
 #define __AMDGPU_TTM_H__
 
-#include "amdgpu.h"
+#include <linux/dma-direction.h>
 #include <drm/gpu_scheduler.h>
+#include "amdgpu.h"
 
 #define AMDGPU_PL_GDS		(TTM_PL_PRIV + 0)
 #define AMDGPU_PL_GWS		(TTM_PL_PRIV + 1)
@@ -74,6 +75,15 @@ uint64_t amdgpu_gtt_mgr_usage(struct ttm_mem_type_manager *man);
 int amdgpu_gtt_mgr_recover(struct ttm_mem_type_manager *man);
 
 u64 amdgpu_vram_mgr_bo_visible_size(struct amdgpu_bo *bo);
+int amdgpu_vram_mgr_alloc_sgt(struct amdgpu_device *adev,
+			      struct ttm_mem_reg *mem,
+			      struct device *dev,
+			      enum dma_data_direction dir,
+			      struct sg_table **sgt);
+void amdgpu_vram_mgr_free_sgt(struct amdgpu_device *adev,
+			      struct device *dev,
+			      enum dma_data_direction dir,
+			      struct sg_table *sgt);
 uint64_t amdgpu_vram_mgr_usage(struct ttm_mem_type_manager *man);
 uint64_t amdgpu_vram_mgr_vis_usage(struct ttm_mem_type_manager *man);
 
@@ -87,11 +97,11 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset,
 		       uint64_t dst_offset, uint32_t byte_count,
 		       struct dma_resv *resv,
 		       struct dma_fence **fence, bool direct_submit,
-		       bool vm_needs_flush);
+		       bool vm_needs_flush, bool tmz);
 int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev,
-			       struct amdgpu_copy_mem *src,
-			       struct amdgpu_copy_mem *dst,
-			       uint64_t size,
+			       const struct amdgpu_copy_mem *src,
+			       const struct amdgpu_copy_mem *dst,
+			       uint64_t size, bool tmz,
 			       struct dma_resv *resv,
 			       struct dma_fence **f);
 int amdgpu_fill_buffer(struct amdgpu_bo *bo,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c
index 9ef312428231..65bb25e31d45 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c
@@ -403,8 +403,8 @@ FW_VERSION_ATTR(mec_fw_version, 0444, gfx.mec_fw_version);
 FW_VERSION_ATTR(mec2_fw_version, 0444, gfx.mec2_fw_version);
 FW_VERSION_ATTR(sos_fw_version, 0444, psp.sos_fw_version);
 FW_VERSION_ATTR(asd_fw_version, 0444, psp.asd_fw_version);
-FW_VERSION_ATTR(ta_ras_fw_version, 0444, psp.ta_fw_version);
-FW_VERSION_ATTR(ta_xgmi_fw_version, 0444, psp.ta_fw_version);
+FW_VERSION_ATTR(ta_ras_fw_version, 0444, psp.ta_ras_ucode_version);
+FW_VERSION_ATTR(ta_xgmi_fw_version, 0444, psp.ta_xgmi_ucode_version);
 FW_VERSION_ATTR(smc_fw_version, 0444, pm.fw_version);
 FW_VERSION_ATTR(sdma_fw_version, 0444, sdma.instance[0].fw_version);
 FW_VERSION_ATTR(sdma2_fw_version, 0444, sdma.instance[1].fw_version);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c
index 9dd51f0d2c11..af1b1ccf613c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c
@@ -110,7 +110,8 @@ int amdgpu_umc_process_ras_data_cb(struct amdgpu_device *adev,
 		 * even NOMEM error is encountered
 		 */
 		if(!err_data->err_addr)
-			DRM_WARN("Failed to alloc memory for umc error address record!\n");
+			dev_warn(adev->dev, "Failed to alloc memory for "
+					"umc error address record!\n");
 
 		/* umc query_ras_error_address is also responsible for clearing
 		 * error status
@@ -120,10 +121,14 @@ int amdgpu_umc_process_ras_data_cb(struct amdgpu_device *adev,
 
 	/* only uncorrectable error needs gpu reset */
 	if (err_data->ue_count) {
+		dev_info(adev->dev, "%ld uncorrectable hardware errors "
+				"detected in UMC block\n",
+				err_data->ue_count);
+
 		if (err_data->err_addr_cnt &&
 		    amdgpu_ras_add_bad_pages(adev, err_data->err_addr,
 						err_data->err_addr_cnt))
-			DRM_WARN("Failed to add ras bad page!\n");
+			dev_warn(adev->dev, "Failed to add ras bad page!\n");
 
 		amdgpu_ras_reset_gpu(adev);
 	}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
index 5fd32ad1c575..5100ebe8858d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
@@ -1056,7 +1056,8 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, struct amdgpu_bo *bo,
 			goto err;
 	}
 
-	r = amdgpu_job_alloc_with_ib(adev, 64, &job);
+	r = amdgpu_job_alloc_with_ib(adev, 64, direct ? AMDGPU_IB_POOL_DIRECT :
+				     AMDGPU_IB_POOL_DELAYED, &job);
 	if (r)
 		goto err;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
index 59ddba137946..ecaa2d7483b2 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
@@ -446,7 +446,8 @@ static int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
 	uint64_t addr;
 	int i, r;
 
-	r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
+	r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4,
+				     AMDGPU_IB_POOL_DIRECT, &job);
 	if (r)
 		return r;
 
@@ -524,7 +525,9 @@ static int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
 	struct dma_fence *f = NULL;
 	int i, r;
 
-	r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
+	r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4,
+				     direct ? AMDGPU_IB_POOL_DIRECT :
+				     AMDGPU_IB_POOL_DELAYED, &job);
 	if (r)
 		return r;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
index a41272fbcba2..2de99b441601 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
@@ -56,13 +56,17 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct *work);
 
 int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
 {
-	unsigned long bo_size;
+	unsigned long bo_size, fw_shared_bo_size;
 	const char *fw_name;
 	const struct common_firmware_header *hdr;
 	unsigned char fw_check;
 	int i, r;
 
 	INIT_DELAYED_WORK(&adev->vcn.idle_work, amdgpu_vcn_idle_work_handler);
+	mutex_init(&adev->vcn.vcn_pg_lock);
+	atomic_set(&adev->vcn.total_submission_cnt, 0);
+	for (i = 0; i < adev->vcn.num_vcn_inst; i++)
+		atomic_set(&adev->vcn.inst[i].dpg_enc_submission_cnt, 0);
 
 	switch (adev->asic_type) {
 	case CHIP_RAVEN:
@@ -178,6 +182,17 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
 				return r;
 			}
 		}
+
+		r = amdgpu_bo_create_kernel(adev, AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_fw_shared)),
+				PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM, &adev->vcn.inst[i].fw_shared_bo,
+				&adev->vcn.inst[i].fw_shared_gpu_addr, &adev->vcn.inst[i].fw_shared_cpu_addr);
+		if (r) {
+			dev_err(adev->dev, "VCN %d (%d) failed to allocate firmware shared bo\n", i, r);
+			return r;
+		}
+
+		fw_shared_bo_size = amdgpu_bo_size(adev->vcn.inst[i].fw_shared_bo);
+		adev->vcn.inst[i].saved_shm_bo = kvmalloc(fw_shared_bo_size, GFP_KERNEL);
 	}
 
 	return 0;
@@ -192,6 +207,12 @@ int amdgpu_vcn_sw_fini(struct amdgpu_device *adev)
 	for (j = 0; j < adev->vcn.num_vcn_inst; ++j) {
 		if (adev->vcn.harvest_config & (1 << j))
 			continue;
+
+		kvfree(adev->vcn.inst[j].saved_shm_bo);
+		amdgpu_bo_free_kernel(&adev->vcn.inst[j].fw_shared_bo,
+					  &adev->vcn.inst[j].fw_shared_gpu_addr,
+					  (void **)&adev->vcn.inst[j].fw_shared_cpu_addr);
+
 		if (adev->vcn.indirect_sram) {
 			amdgpu_bo_free_kernel(&adev->vcn.inst[j].dpg_sram_bo,
 						  &adev->vcn.inst[j].dpg_sram_gpu_addr,
@@ -210,6 +231,7 @@ int amdgpu_vcn_sw_fini(struct amdgpu_device *adev)
 	}
 
 	release_firmware(adev->vcn.fw);
+	mutex_destroy(&adev->vcn.vcn_pg_lock);
 
 	return 0;
 }
@@ -236,6 +258,17 @@ int amdgpu_vcn_suspend(struct amdgpu_device *adev)
 			return -ENOMEM;
 
 		memcpy_fromio(adev->vcn.inst[i].saved_bo, ptr, size);
+
+		if (adev->vcn.inst[i].fw_shared_bo == NULL)
+			return 0;
+
+		if (!adev->vcn.inst[i].saved_shm_bo)
+			return -ENOMEM;
+
+		size = amdgpu_bo_size(adev->vcn.inst[i].fw_shared_bo);
+		ptr = adev->vcn.inst[i].fw_shared_cpu_addr;
+
+		memcpy_fromio(adev->vcn.inst[i].saved_shm_bo, ptr, size);
 	}
 	return 0;
 }
@@ -273,6 +306,17 @@ int amdgpu_vcn_resume(struct amdgpu_device *adev)
 			}
 			memset_io(ptr, 0, size);
 		}
+
+		if (adev->vcn.inst[i].fw_shared_bo == NULL)
+			return -EINVAL;
+
+		size = amdgpu_bo_size(adev->vcn.inst[i].fw_shared_bo);
+		ptr = adev->vcn.inst[i].fw_shared_cpu_addr;
+
+		if (adev->vcn.inst[i].saved_shm_bo != NULL)
+			memcpy_toio(ptr, adev->vcn.inst[i].saved_shm_bo, size);
+		else
+			memset_io(ptr, 0, size);
 	}
 	return 0;
 }
@@ -295,7 +339,8 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct *work)
 		if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)	{
 			struct dpg_pause_state new_state;
 
-			if (fence[j])
+			if (fence[j] ||
+				unlikely(atomic_read(&adev->vcn.inst[j].dpg_enc_submission_cnt)))
 				new_state.fw_based = VCN_DPG_STATE__PAUSE;
 			else
 				new_state.fw_based = VCN_DPG_STATE__UNPAUSE;
@@ -307,8 +352,7 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct *work)
 		fences += fence[j];
 	}
 
-	if (fences == 0) {
-		amdgpu_gfx_off_ctrl(adev, true);
+	if (!fences && !atomic_read(&adev->vcn.total_submission_cnt)) {
 		amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN,
 		       AMD_PG_STATE_GATE);
 	} else {
@@ -319,36 +363,46 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct *work)
 void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring)
 {
 	struct amdgpu_device *adev = ring->adev;
-	bool set_clocks = !cancel_delayed_work_sync(&adev->vcn.idle_work);
 
-	if (set_clocks) {
-		amdgpu_gfx_off_ctrl(adev, false);
-		amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN,
-		       AMD_PG_STATE_UNGATE);
-	}
+	atomic_inc(&adev->vcn.total_submission_cnt);
+	cancel_delayed_work_sync(&adev->vcn.idle_work);
+
+	mutex_lock(&adev->vcn.vcn_pg_lock);
+	amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN,
+	       AMD_PG_STATE_UNGATE);
 
 	if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)	{
 		struct dpg_pause_state new_state;
-		unsigned int fences = 0;
-		unsigned int i;
 
-		for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
-			fences += amdgpu_fence_count_emitted(&adev->vcn.inst[ring->me].ring_enc[i]);
-		}
-		if (fences)
+		if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC) {
+			atomic_inc(&adev->vcn.inst[ring->me].dpg_enc_submission_cnt);
 			new_state.fw_based = VCN_DPG_STATE__PAUSE;
-		else
-			new_state.fw_based = VCN_DPG_STATE__UNPAUSE;
+		} else {
+			unsigned int fences = 0;
+			unsigned int i;
 
-		if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC)
-			new_state.fw_based = VCN_DPG_STATE__PAUSE;
+			for (i = 0; i < adev->vcn.num_enc_rings; ++i)
+				fences += amdgpu_fence_count_emitted(&adev->vcn.inst[ring->me].ring_enc[i]);
+
+			if (fences || atomic_read(&adev->vcn.inst[ring->me].dpg_enc_submission_cnt))
+				new_state.fw_based = VCN_DPG_STATE__PAUSE;
+			else
+				new_state.fw_based = VCN_DPG_STATE__UNPAUSE;
+		}
 
 		adev->vcn.pause_dpg_mode(adev, ring->me, &new_state);
 	}
+	mutex_unlock(&adev->vcn.vcn_pg_lock);
 }
 
 void amdgpu_vcn_ring_end_use(struct amdgpu_ring *ring)
 {
+	if (ring->adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG &&
+		ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC)
+		atomic_dec(&ring->adev->vcn.inst[ring->me].dpg_enc_submission_cnt);
+
+	atomic_dec(&ring->adev->vcn.total_submission_cnt);
+
 	schedule_delayed_work(&ring->adev->vcn.idle_work, VCN_IDLE_TIMEOUT);
 }
 
@@ -390,7 +444,8 @@ static int amdgpu_vcn_dec_send_msg(struct amdgpu_ring *ring,
 	uint64_t addr;
 	int i, r;
 
-	r = amdgpu_job_alloc_with_ib(adev, 64, &job);
+	r = amdgpu_job_alloc_with_ib(adev, 64,
+					AMDGPU_IB_POOL_DIRECT, &job);
 	if (r)
 		goto err;
 
@@ -557,7 +612,8 @@ static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t hand
 	uint64_t addr;
 	int i, r;
 
-	r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
+	r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4,
+					AMDGPU_IB_POOL_DIRECT, &job);
 	if (r)
 		return r;
 
@@ -610,7 +666,8 @@ static int amdgpu_vcn_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t han
 	uint64_t addr;
 	int i, r;
 
-	r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
+	r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4,
+					AMDGPU_IB_POOL_DIRECT, &job);
 	if (r)
 		return r;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h
index 6fe057329de2..90aa12b22725 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h
@@ -132,6 +132,13 @@
 		}										\
 	} while (0)
 
+#define AMDGPU_VCN_MULTI_QUEUE_FLAG	(1 << 8)
+
+enum fw_queue_mode {
+	FW_QUEUE_RING_RESET = 1,
+	FW_QUEUE_DPG_HOLD_OFF = 2,
+};
+
 enum engine_status_constants {
 	UVD_PGFSM_STATUS__UVDM_UVDU_PWR_ON = 0x2AAAA0,
 	UVD_PGFSM_STATUS__UVDM_UVDU_PWR_ON_2_0 = 0xAAAA0,
@@ -179,10 +186,15 @@ struct amdgpu_vcn_inst {
 	struct amdgpu_irq_src	irq;
 	struct amdgpu_vcn_reg	external;
 	struct amdgpu_bo	*dpg_sram_bo;
+	struct amdgpu_bo	*fw_shared_bo;
 	struct dpg_pause_state	pause_state;
 	void			*dpg_sram_cpu_addr;
 	uint64_t		dpg_sram_gpu_addr;
 	uint32_t		*dpg_sram_curr_addr;
+	atomic_t		dpg_enc_submission_cnt;
+	void			*fw_shared_cpu_addr;
+	uint64_t		fw_shared_gpu_addr;
+	void			*saved_shm_bo;
 };
 
 struct amdgpu_vcn {
@@ -196,16 +208,28 @@ struct amdgpu_vcn {
 	uint8_t	num_vcn_inst;
 	struct amdgpu_vcn_inst	 inst[AMDGPU_MAX_VCN_INSTANCES];
 	struct amdgpu_vcn_reg	 internal;
-	struct drm_gpu_scheduler *vcn_enc_sched[AMDGPU_MAX_VCN_ENC_RINGS];
-	struct drm_gpu_scheduler *vcn_dec_sched[AMDGPU_MAX_VCN_INSTANCES];
-	uint32_t		 num_vcn_enc_sched;
-	uint32_t		 num_vcn_dec_sched;
+	struct mutex		 vcn_pg_lock;
+	atomic_t		 total_submission_cnt;
 
 	unsigned	harvest_config;
 	int (*pause_dpg_mode)(struct amdgpu_device *adev,
 		int inst_idx, struct dpg_pause_state *new_state);
 };
 
+struct amdgpu_fw_shared_multi_queue {
+	uint8_t decode_queue_mode;
+	uint8_t encode_generalpurpose_queue_mode;
+	uint8_t encode_lowlatency_queue_mode;
+	uint8_t encode_realtime_queue_mode;
+	uint8_t padding[4];
+};
+
+struct amdgpu_fw_shared {
+	uint32_t present_flag_0;
+	uint8_t pad[53];
+	struct amdgpu_fw_shared_multi_queue multi_queue;
+} __attribute__((__packed__));
+
 int amdgpu_vcn_sw_init(struct amdgpu_device *adev);
 int amdgpu_vcn_sw_fini(struct amdgpu_device *adev);
 int amdgpu_vcn_suspend(struct amdgpu_device *adev);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
index adc813cde8e2..8c10084f44ef 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
@@ -38,7 +38,8 @@ bool amdgpu_virt_mmio_blocked(struct amdgpu_device *adev)
 void amdgpu_virt_init_setting(struct amdgpu_device *adev)
 {
 	/* enable virtual display */
-	adev->mode_info.num_crtc = 1;
+	if (adev->mode_info.num_crtc == 0)
+		adev->mode_info.num_crtc = 1;
 	adev->enable_virtual_display = true;
 	adev->ddev->driver->driver_features &= ~DRIVER_ATOMIC;
 	adev->cg_flags = 0;
@@ -152,6 +153,19 @@ int amdgpu_virt_reset_gpu(struct amdgpu_device *adev)
 	return 0;
 }
 
+void amdgpu_virt_request_init_data(struct amdgpu_device *adev)
+{
+	struct amdgpu_virt *virt = &adev->virt;
+
+	if (virt->ops && virt->ops->req_init_data)
+		virt->ops->req_init_data(adev);
+
+	if (adev->virt.req_init_data_ver > 0)
+		DRM_INFO("host supports REQ_INIT_DATA handshake\n");
+	else
+		DRM_WARN("host doesn't support REQ_INIT_DATA handshake\n");
+}
+
 /**
  * amdgpu_virt_wait_reset() - wait for reset gpu completed
  * @amdgpu:	amdgpu device.
@@ -287,3 +301,66 @@ void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev)
 		}
 	}
 }
+
+void amdgpu_detect_virtualization(struct amdgpu_device *adev)
+{
+	uint32_t reg;
+
+	switch (adev->asic_type) {
+	case CHIP_TONGA:
+	case CHIP_FIJI:
+		reg = RREG32(mmBIF_IOV_FUNC_IDENTIFIER);
+		break;
+	case CHIP_VEGA10:
+	case CHIP_VEGA20:
+	case CHIP_NAVI10:
+	case CHIP_NAVI12:
+	case CHIP_ARCTURUS:
+		reg = RREG32(mmRCC_IOV_FUNC_IDENTIFIER);
+		break;
+	default: /* other chip doesn't support SRIOV */
+		reg = 0;
+		break;
+	}
+
+	if (reg & 1)
+		adev->virt.caps |= AMDGPU_SRIOV_CAPS_IS_VF;
+
+	if (reg & 0x80000000)
+		adev->virt.caps |= AMDGPU_SRIOV_CAPS_ENABLE_IOV;
+
+	if (!reg) {
+		if (is_virtual_machine())	/* passthrough mode exclus sriov mod */
+			adev->virt.caps |= AMDGPU_PASSTHROUGH_MODE;
+	}
+}
+
+bool amdgpu_virt_access_debugfs_is_mmio(struct amdgpu_device *adev)
+{
+	return amdgpu_sriov_is_debug(adev) ? true : false;
+}
+
+bool amdgpu_virt_access_debugfs_is_kiq(struct amdgpu_device *adev)
+{
+	return amdgpu_sriov_is_normal(adev) ? true : false;
+}
+
+int amdgpu_virt_enable_access_debugfs(struct amdgpu_device *adev)
+{
+	if (!amdgpu_sriov_vf(adev) ||
+	    amdgpu_virt_access_debugfs_is_kiq(adev))
+		return 0;
+
+	if (amdgpu_virt_access_debugfs_is_mmio(adev))
+		adev->virt.caps &= ~AMDGPU_SRIOV_CAPS_RUNTIME;
+	else
+		return -EPERM;
+
+	return 0;
+}
+
+void amdgpu_virt_disable_access_debugfs(struct amdgpu_device *adev)
+{
+	if (amdgpu_sriov_vf(adev))
+		adev->virt.caps |= AMDGPU_SRIOV_CAPS_RUNTIME;
+}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
index f0128f745bd2..de27308802c9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
@@ -30,6 +30,11 @@
 #define AMDGPU_PASSTHROUGH_MODE        (1 << 3) /* thw whole GPU is pass through for VM */
 #define AMDGPU_SRIOV_CAPS_RUNTIME      (1 << 4) /* is out of full access mode */
 
+/* all asic after AI use this offset */
+#define mmRCC_IOV_FUNC_IDENTIFIER 0xDE5
+/* tonga/fiji use this offset */
+#define mmBIF_IOV_FUNC_IDENTIFIER 0x1503
+
 struct amdgpu_mm_table {
 	struct amdgpu_bo	*bo;
 	uint32_t		*cpu_addr;
@@ -54,6 +59,7 @@ struct amdgpu_vf_error_buffer {
 struct amdgpu_virt_ops {
 	int (*req_full_gpu)(struct amdgpu_device *adev, bool init);
 	int (*rel_full_gpu)(struct amdgpu_device *adev, bool init);
+	int (*req_init_data)(struct amdgpu_device *adev);
 	int (*reset_gpu)(struct amdgpu_device *adev);
 	int (*wait_reset)(struct amdgpu_device *adev);
 	void (*trans_msg)(struct amdgpu_device *adev, u32 req, u32 data1, u32 data2, u32 data3);
@@ -83,6 +89,8 @@ enum AMDGIM_FEATURE_FLAG {
 	AMDGIM_FEATURE_GIM_LOAD_UCODES   = 0x2,
 	/* VRAM LOST by GIM */
 	AMDGIM_FEATURE_GIM_FLR_VRAMLOST = 0x4,
+	/* MM bandwidth */
+	AMDGIM_FEATURE_GIM_MM_BW_MGR = 0x8,
 	/* PP ONE VF MODE in GIM */
 	AMDGIM_FEATURE_PP_ONE_VF = (1 << 4),
 };
@@ -256,6 +264,8 @@ struct amdgpu_virt {
 	struct amdgpu_virt_fw_reserve	fw_reserve;
 	uint32_t gim_feature;
 	uint32_t reg_access_mode;
+	int req_init_data_ver;
+	bool tdr_debug;
 };
 
 #define amdgpu_sriov_enabled(adev) \
@@ -287,6 +297,10 @@ static inline bool is_virtual_machine(void)
 
 #define amdgpu_sriov_is_pp_one_vf(adev) \
 	((adev)->virt.gim_feature & AMDGIM_FEATURE_PP_ONE_VF)
+#define amdgpu_sriov_is_debug(adev) \
+	((!adev->in_gpu_reset) && adev->virt.tdr_debug)
+#define amdgpu_sriov_is_normal(adev) \
+	((!adev->in_gpu_reset) && (!adev->virt.tdr_debug))
 
 bool amdgpu_virt_mmio_blocked(struct amdgpu_device *adev);
 void amdgpu_virt_init_setting(struct amdgpu_device *adev);
@@ -296,6 +310,7 @@ void amdgpu_virt_kiq_reg_write_reg_wait(struct amdgpu_device *adev,
 int amdgpu_virt_request_full_gpu(struct amdgpu_device *adev, bool init);
 int amdgpu_virt_release_full_gpu(struct amdgpu_device *adev, bool init);
 int amdgpu_virt_reset_gpu(struct amdgpu_device *adev);
+void amdgpu_virt_request_init_data(struct amdgpu_device *adev);
 int amdgpu_virt_wait_reset(struct amdgpu_device *adev);
 int amdgpu_virt_alloc_mm_table(struct amdgpu_device *adev);
 void amdgpu_virt_free_mm_table(struct amdgpu_device *adev);
@@ -303,4 +318,9 @@ int amdgpu_virt_fw_reserve_get_checksum(void *obj, unsigned long obj_size,
 					unsigned int key,
 					unsigned int chksum);
 void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev);
+void amdgpu_detect_virtualization(struct amdgpu_device *adev);
+
+bool amdgpu_virt_can_access_debugfs(struct amdgpu_device *adev);
+int amdgpu_virt_enable_access_debugfs(struct amdgpu_device *adev);
+void amdgpu_virt_disable_access_debugfs(struct amdgpu_device *adev);
 #endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 6d9252a27916..accbb34ea670 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -726,7 +726,7 @@ bool amdgpu_vm_ready(struct amdgpu_vm *vm)
  * @adev: amdgpu_device pointer
  * @vm: VM to clear BO from
  * @bo: BO to clear
- * @direct: use a direct update
+ * @immediate: use an immediate update
  *
  * Root PD needs to be reserved when calling this.
  *
@@ -736,7 +736,7 @@ bool amdgpu_vm_ready(struct amdgpu_vm *vm)
 static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,
 			      struct amdgpu_vm *vm,
 			      struct amdgpu_bo *bo,
-			      bool direct)
+			      bool immediate)
 {
 	struct ttm_operation_ctx ctx = { true, false };
 	unsigned level = adev->vm_manager.root_level;
@@ -795,7 +795,7 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,
 	memset(&params, 0, sizeof(params));
 	params.adev = adev;
 	params.vm = vm;
-	params.direct = direct;
+	params.immediate = immediate;
 
 	r = vm->update_funcs->prepare(&params, NULL, AMDGPU_SYNC_EXPLICIT);
 	if (r)
@@ -850,11 +850,11 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,
  * @adev: amdgpu_device pointer
  * @vm: requesting vm
  * @level: the page table level
- * @direct: use a direct update
+ * @immediate: use a immediate update
  * @bp: resulting BO allocation parameters
  */
 static void amdgpu_vm_bo_param(struct amdgpu_device *adev, struct amdgpu_vm *vm,
-			       int level, bool direct,
+			       int level, bool immediate,
 			       struct amdgpu_bo_param *bp)
 {
 	memset(bp, 0, sizeof(*bp));
@@ -870,7 +870,7 @@ static void amdgpu_vm_bo_param(struct amdgpu_device *adev, struct amdgpu_vm *vm,
 	else if (!vm->root.base.bo || vm->root.base.bo->shadow)
 		bp->flags |= AMDGPU_GEM_CREATE_SHADOW;
 	bp->type = ttm_bo_type_kernel;
-	bp->no_wait_gpu = direct;
+	bp->no_wait_gpu = immediate;
 	if (vm->root.base.bo)
 		bp->resv = vm->root.base.bo->tbo.base.resv;
 }
@@ -881,7 +881,7 @@ static void amdgpu_vm_bo_param(struct amdgpu_device *adev, struct amdgpu_vm *vm,
  * @adev: amdgpu_device pointer
  * @vm: VM to allocate page tables for
  * @cursor: Which page table to allocate
- * @direct: use a direct update
+ * @immediate: use an immediate update
  *
  * Make sure a specific page table or directory is allocated.
  *
@@ -892,7 +892,7 @@ static void amdgpu_vm_bo_param(struct amdgpu_device *adev, struct amdgpu_vm *vm,
 static int amdgpu_vm_alloc_pts(struct amdgpu_device *adev,
 			       struct amdgpu_vm *vm,
 			       struct amdgpu_vm_pt_cursor *cursor,
-			       bool direct)
+			       bool immediate)
 {
 	struct amdgpu_vm_pt *entry = cursor->entry;
 	struct amdgpu_bo_param bp;
@@ -913,7 +913,7 @@ static int amdgpu_vm_alloc_pts(struct amdgpu_device *adev,
 	if (entry->base.bo)
 		return 0;
 
-	amdgpu_vm_bo_param(adev, vm, cursor->level, direct, &bp);
+	amdgpu_vm_bo_param(adev, vm, cursor->level, immediate, &bp);
 
 	r = amdgpu_bo_create(adev, &bp, &pt);
 	if (r)
@@ -925,7 +925,7 @@ static int amdgpu_vm_alloc_pts(struct amdgpu_device *adev,
 	pt->parent = amdgpu_bo_ref(cursor->parent->base.bo);
 	amdgpu_vm_bo_base_init(&entry->base, vm, pt);
 
-	r = amdgpu_vm_clear_bo(adev, vm, pt, direct);
+	r = amdgpu_vm_clear_bo(adev, vm, pt, immediate);
 	if (r)
 		goto error_free_pt;
 
@@ -1276,7 +1276,7 @@ static void amdgpu_vm_invalidate_pds(struct amdgpu_device *adev,
  *
  * @adev: amdgpu_device pointer
  * @vm: requested vm
- * @direct: submit directly to the paging queue
+ * @immediate: submit immediately to the paging queue
  *
  * Makes sure all directories are up to date.
  *
@@ -1284,7 +1284,7 @@ static void amdgpu_vm_invalidate_pds(struct amdgpu_device *adev,
  * 0 for success, error for failure.
  */
 int amdgpu_vm_update_pdes(struct amdgpu_device *adev,
-			  struct amdgpu_vm *vm, bool direct)
+			  struct amdgpu_vm *vm, bool immediate)
 {
 	struct amdgpu_vm_update_params params;
 	int r;
@@ -1295,7 +1295,7 @@ int amdgpu_vm_update_pdes(struct amdgpu_device *adev,
 	memset(&params, 0, sizeof(params));
 	params.adev = adev;
 	params.vm = vm;
-	params.direct = direct;
+	params.immediate = immediate;
 
 	r = vm->update_funcs->prepare(&params, NULL, AMDGPU_SYNC_EXPLICIT);
 	if (r)
@@ -1446,20 +1446,24 @@ static int amdgpu_vm_update_ptes(struct amdgpu_vm_update_params *params,
 		uint64_t incr, entry_end, pe_start;
 		struct amdgpu_bo *pt;
 
-		if (flags & (AMDGPU_PTE_VALID | AMDGPU_PTE_PRT)) {
+		if (!params->unlocked) {
 			/* make sure that the page tables covering the
 			 * address range are actually allocated
 			 */
 			r = amdgpu_vm_alloc_pts(params->adev, params->vm,
-						&cursor, params->direct);
+						&cursor, params->immediate);
 			if (r)
 				return r;
 		}
 
 		shift = amdgpu_vm_level_shift(adev, cursor.level);
 		parent_shift = amdgpu_vm_level_shift(adev, cursor.level - 1);
-		if (adev->asic_type < CHIP_VEGA10 &&
-		    (flags & AMDGPU_PTE_VALID)) {
+		if (params->unlocked) {
+			/* Unlocked updates are only allowed on the leaves */
+			if (amdgpu_vm_pt_descendant(adev, &cursor))
+				continue;
+		} else if (adev->asic_type < CHIP_VEGA10 &&
+			   (flags & AMDGPU_PTE_VALID)) {
 			/* No huge page support before GMC v9 */
 			if (cursor.level != AMDGPU_VM_PTB) {
 				if (!amdgpu_vm_pt_descendant(adev, &cursor))
@@ -1557,7 +1561,8 @@ static int amdgpu_vm_update_ptes(struct amdgpu_vm_update_params *params,
  *
  * @adev: amdgpu_device pointer
  * @vm: requested vm
- * @direct: direct submission in a page fault
+ * @immediate: immediate submission in a page fault
+ * @unlocked: unlocked invalidation during MM callback
  * @resv: fences we need to sync to
  * @start: start of mapped range
  * @last: last mapped entry
@@ -1572,8 +1577,8 @@ static int amdgpu_vm_update_ptes(struct amdgpu_vm_update_params *params,
  * 0 for success, -EINVAL for failure.
  */
 static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
-				       struct amdgpu_vm *vm, bool direct,
-				       struct dma_resv *resv,
+				       struct amdgpu_vm *vm, bool immediate,
+				       bool unlocked, struct dma_resv *resv,
 				       uint64_t start, uint64_t last,
 				       uint64_t flags, uint64_t addr,
 				       dma_addr_t *pages_addr,
@@ -1586,8 +1591,9 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
 	memset(&params, 0, sizeof(params));
 	params.adev = adev;
 	params.vm = vm;
-	params.direct = direct;
+	params.immediate = immediate;
 	params.pages_addr = pages_addr;
+	params.unlocked = unlocked;
 
 	/* Implicitly sync to command submissions in the same VM before
 	 * unmapping. Sync to moving fences before mapping.
@@ -1603,11 +1609,12 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
 		goto error_unlock;
 	}
 
-	if (flags & (AMDGPU_PTE_VALID | AMDGPU_PTE_PRT)) {
-		struct amdgpu_bo *root = vm->root.base.bo;
+	if (!unlocked && !dma_fence_is_signaled(vm->last_unlocked)) {
+		struct dma_fence *tmp = dma_fence_get_stub();
 
-		if (!dma_fence_is_signaled(vm->last_direct))
-			amdgpu_bo_fence(root, vm->last_direct, true);
+		amdgpu_bo_fence(vm->root.base.bo, vm->last_unlocked, true);
+		swap(vm->last_unlocked, tmp);
+		dma_fence_put(tmp);
 	}
 
 	r = vm->update_funcs->prepare(&params, resv, sync_mode);
@@ -1721,7 +1728,7 @@ static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev,
 		}
 
 		last = min((uint64_t)mapping->last, start + max_entries - 1);
-		r = amdgpu_vm_bo_update_mapping(adev, vm, false, resv,
+		r = amdgpu_vm_bo_update_mapping(adev, vm, false, false, resv,
 						start, last, flags, addr,
 						dma_addr, fence);
 		if (r)
@@ -1784,6 +1791,10 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va,
 
 	if (bo) {
 		flags = amdgpu_ttm_tt_pte_flags(adev, bo->tbo.ttm, mem);
+
+		if (amdgpu_bo_encrypted(bo))
+			flags |= AMDGPU_PTE_TMZ;
+
 		bo_adev = amdgpu_ttm_adev(bo->tbo.bdev);
 	} else {
 		flags = 0x0;
@@ -2014,7 +2025,7 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
 		    mapping->start < AMDGPU_GMC_HOLE_START)
 			init_pte_value = AMDGPU_PTE_DEFAULT_ATC;
 
-		r = amdgpu_vm_bo_update_mapping(adev, vm, false, resv,
+		r = amdgpu_vm_bo_update_mapping(adev, vm, false, false, resv,
 						mapping->start, mapping->last,
 						init_pte_value, 0, NULL, &f);
 		amdgpu_vm_free_mapping(adev, vm, mapping, f);
@@ -2585,7 +2596,7 @@ bool amdgpu_vm_evictable(struct amdgpu_bo *bo)
 		return false;
 
 	/* Don't evict VM page tables while they are updated */
-	if (!dma_fence_is_signaled(bo_base->vm->last_direct)) {
+	if (!dma_fence_is_signaled(bo_base->vm->last_unlocked)) {
 		amdgpu_vm_eviction_unlock(bo_base->vm);
 		return false;
 	}
@@ -2762,7 +2773,7 @@ long amdgpu_vm_wait_idle(struct amdgpu_vm *vm, long timeout)
 	if (timeout <= 0)
 		return timeout;
 
-	return dma_fence_wait_timeout(vm->last_direct, true, timeout);
+	return dma_fence_wait_timeout(vm->last_unlocked, true, timeout);
 }
 
 /**
@@ -2798,7 +2809,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
 
 
 	/* create scheduler entities for page table updates */
-	r = drm_sched_entity_init(&vm->direct, DRM_SCHED_PRIORITY_NORMAL,
+	r = drm_sched_entity_init(&vm->immediate, DRM_SCHED_PRIORITY_NORMAL,
 				  adev->vm_manager.vm_pte_scheds,
 				  adev->vm_manager.vm_pte_num_scheds, NULL);
 	if (r)
@@ -2808,7 +2819,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
 				  adev->vm_manager.vm_pte_scheds,
 				  adev->vm_manager.vm_pte_num_scheds, NULL);
 	if (r)
-		goto error_free_direct;
+		goto error_free_immediate;
 
 	vm->pte_support_ats = false;
 	vm->is_compute_context = false;
@@ -2834,7 +2845,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
 	else
 		vm->update_funcs = &amdgpu_vm_sdma_funcs;
 	vm->last_update = NULL;
-	vm->last_direct = dma_fence_get_stub();
+	vm->last_unlocked = dma_fence_get_stub();
 
 	mutex_init(&vm->eviction_lock);
 	vm->evicting = false;
@@ -2888,11 +2899,11 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
 	vm->root.base.bo = NULL;
 
 error_free_delayed:
-	dma_fence_put(vm->last_direct);
+	dma_fence_put(vm->last_unlocked);
 	drm_sched_entity_destroy(&vm->delayed);
 
-error_free_direct:
-	drm_sched_entity_destroy(&vm->direct);
+error_free_immediate:
+	drm_sched_entity_destroy(&vm->immediate);
 
 	return r;
 }
@@ -3089,8 +3100,8 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)
 		vm->pasid = 0;
 	}
 
-	dma_fence_wait(vm->last_direct, false);
-	dma_fence_put(vm->last_direct);
+	dma_fence_wait(vm->last_unlocked, false);
+	dma_fence_put(vm->last_unlocked);
 
 	list_for_each_entry_safe(mapping, tmp, &vm->freed, list) {
 		if (mapping->flags & AMDGPU_PTE_PRT && prt_fini_needed) {
@@ -3107,7 +3118,7 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)
 	amdgpu_bo_unref(&root);
 	WARN_ON(vm->root.base.bo);
 
-	drm_sched_entity_destroy(&vm->direct);
+	drm_sched_entity_destroy(&vm->immediate);
 	drm_sched_entity_destroy(&vm->delayed);
 
 	if (!RB_EMPTY_ROOT(&vm->va.rb_root)) {
@@ -3343,8 +3354,8 @@ bool amdgpu_vm_handle_fault(struct amdgpu_device *adev, unsigned int pasid,
 		value = 0;
 	}
 
-	r = amdgpu_vm_bo_update_mapping(adev, vm, true, NULL, addr, addr + 1,
-					flags, value, NULL, NULL);
+	r = amdgpu_vm_bo_update_mapping(adev, vm, true, false, NULL, addr,
+					addr + 1, flags, value, NULL, NULL);
 	if (r)
 		goto error_unlock;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
index 06fe30e1492d..ea771d84bf2b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
@@ -54,6 +54,9 @@ struct amdgpu_bo_list_entry;
 #define AMDGPU_PTE_SYSTEM	(1ULL << 1)
 #define AMDGPU_PTE_SNOOPED	(1ULL << 2)
 
+/* RV+ */
+#define AMDGPU_PTE_TMZ		(1ULL << 3)
+
 /* VI only */
 #define AMDGPU_PTE_EXECUTABLE	(1ULL << 4)
 
@@ -203,9 +206,14 @@ struct amdgpu_vm_update_params {
 	struct amdgpu_vm *vm;
 
 	/**
-	 * @direct: if changes should be made directly
+	 * @immediate: if changes should be made immediately
+	 */
+	bool immediate;
+
+	/**
+	 * @unlocked: true if the root BO is not locked
 	 */
-	bool direct;
+	bool unlocked;
 
 	/**
 	 * @pages_addr:
@@ -271,11 +279,11 @@ struct amdgpu_vm {
 	struct dma_fence	*last_update;
 
 	/* Scheduler entities for page table updates */
-	struct drm_sched_entity	direct;
+	struct drm_sched_entity	immediate;
 	struct drm_sched_entity	delayed;
 
-	/* Last submission to the scheduler entities */
-	struct dma_fence	*last_direct;
+	/* Last unlocked submission to the scheduler entities */
+	struct dma_fence	*last_unlocked;
 
 	unsigned int		pasid;
 	/* dedicated to vm */
@@ -380,7 +388,7 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
 			      void *param);
 int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job, bool need_pipe_sync);
 int amdgpu_vm_update_pdes(struct amdgpu_device *adev,
-			  struct amdgpu_vm *vm, bool direct);
+			  struct amdgpu_vm *vm, bool immediate);
 int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
 			  struct amdgpu_vm *vm,
 			  struct dma_fence **fence);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c
index e38516304070..39c704a1fb0e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c
@@ -84,7 +84,7 @@ static int amdgpu_vm_cpu_update(struct amdgpu_vm_update_params *p,
 
 	pe += (unsigned long)amdgpu_bo_kptr(bo);
 
-	trace_amdgpu_vm_set_ptes(pe, addr, count, incr, flags, p->direct);
+	trace_amdgpu_vm_set_ptes(pe, addr, count, incr, flags, p->immediate);
 
 	for (i = 0; i < count; i++) {
 		value = p->pages_addr ?
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
index cf96c335b258..8d9c6feba660 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
@@ -61,10 +61,12 @@ static int amdgpu_vm_sdma_prepare(struct amdgpu_vm_update_params *p,
 				  struct dma_resv *resv,
 				  enum amdgpu_sync_mode sync_mode)
 {
+	enum amdgpu_ib_pool_type pool = p->immediate ? AMDGPU_IB_POOL_IMMEDIATE
+		: AMDGPU_IB_POOL_DELAYED;
 	unsigned int ndw = AMDGPU_VM_SDMA_MIN_NUM_DW;
 	int r;
 
-	r = amdgpu_job_alloc_with_ib(p->adev, ndw * 4, &p->job);
+	r = amdgpu_job_alloc_with_ib(p->adev, ndw * 4, pool, &p->job);
 	if (r)
 		return r;
 
@@ -90,11 +92,11 @@ static int amdgpu_vm_sdma_commit(struct amdgpu_vm_update_params *p,
 {
 	struct amdgpu_ib *ib = p->job->ibs;
 	struct drm_sched_entity *entity;
-	struct dma_fence *f, *tmp;
 	struct amdgpu_ring *ring;
+	struct dma_fence *f;
 	int r;
 
-	entity = p->direct ? &p->vm->direct : &p->vm->delayed;
+	entity = p->immediate ? &p->vm->immediate : &p->vm->delayed;
 	ring = container_of(entity->rq->sched, struct amdgpu_ring, sched);
 
 	WARN_ON(ib->length_dw == 0);
@@ -104,15 +106,16 @@ static int amdgpu_vm_sdma_commit(struct amdgpu_vm_update_params *p,
 	if (r)
 		goto error;
 
-	if (p->direct) {
-		tmp = dma_fence_get(f);
-		swap(p->vm->last_direct, tmp);
+	if (p->unlocked) {
+		struct dma_fence *tmp = dma_fence_get(f);
+
+		swap(p->vm->last_unlocked, f);
 		dma_fence_put(tmp);
 	} else {
-		dma_resv_add_shared_fence(p->vm->root.base.bo->tbo.base.resv, f);
+		amdgpu_bo_fence(p->vm->root.base.bo, f, true);
 	}
 
-	if (fence && !p->direct)
+	if (fence && !p->immediate)
 		swap(*fence, f);
 	dma_fence_put(f);
 	return 0;
@@ -142,7 +145,7 @@ static void amdgpu_vm_sdma_copy_ptes(struct amdgpu_vm_update_params *p,
 	src += p->num_dw_left * 4;
 
 	pe += amdgpu_gmc_sign_extend(bo->tbo.offset);
-	trace_amdgpu_vm_copy_ptes(pe, src, count, p->direct);
+	trace_amdgpu_vm_copy_ptes(pe, src, count, p->immediate);
 
 	amdgpu_vm_copy_pte(p->adev, ib, pe, src, count);
 }
@@ -169,7 +172,7 @@ static void amdgpu_vm_sdma_set_ptes(struct amdgpu_vm_update_params *p,
 	struct amdgpu_ib *ib = p->job->ibs;
 
 	pe += amdgpu_gmc_sign_extend(bo->tbo.offset);
-	trace_amdgpu_vm_set_ptes(pe, addr, count, incr, flags, p->direct);
+	trace_amdgpu_vm_set_ptes(pe, addr, count, incr, flags, p->immediate);
 	if (count < 3) {
 		amdgpu_vm_write_pte(p->adev, ib, pe, addr | flags,
 				    count, incr);
@@ -198,6 +201,8 @@ static int amdgpu_vm_sdma_update(struct amdgpu_vm_update_params *p,
 				 uint64_t addr, unsigned count, uint32_t incr,
 				 uint64_t flags)
 {
+	enum amdgpu_ib_pool_type pool = p->immediate ? AMDGPU_IB_POOL_IMMEDIATE
+		: AMDGPU_IB_POOL_DELAYED;
 	unsigned int i, ndw, nptes;
 	uint64_t *pte;
 	int r;
@@ -223,7 +228,8 @@ static int amdgpu_vm_sdma_update(struct amdgpu_vm_update_params *p,
 			ndw = max(ndw, AMDGPU_VM_SDMA_MIN_NUM_DW);
 			ndw = min(ndw, AMDGPU_VM_SDMA_MAX_NUM_DW);
 
-			r = amdgpu_job_alloc_with_ib(p->adev, ndw * 4, &p->job);
+			r = amdgpu_job_alloc_with_ib(p->adev, ndw * 4, pool,
+						     &p->job);
 			if (r)
 				return r;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
index 82a3299e53c0..128a667ed8fa 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
@@ -22,6 +22,7 @@
  * Authors: Christian König
  */
 
+#include <linux/dma-mapping.h>
 #include "amdgpu.h"
 #include "amdgpu_vm.h"
 #include "amdgpu_atomfirmware.h"
@@ -458,6 +459,104 @@ static void amdgpu_vram_mgr_del(struct ttm_mem_type_manager *man,
 	mem->mm_node = NULL;
 }
 
+/**
+ * amdgpu_vram_mgr_alloc_sgt - allocate and fill a sg table
+ *
+ * @adev: amdgpu device pointer
+ * @mem: TTM memory object
+ * @dev: the other device
+ * @dir: dma direction
+ * @sgt: resulting sg table
+ *
+ * Allocate and fill a sg table from a VRAM allocation.
+ */
+int amdgpu_vram_mgr_alloc_sgt(struct amdgpu_device *adev,
+			      struct ttm_mem_reg *mem,
+			      struct device *dev,
+			      enum dma_data_direction dir,
+			      struct sg_table **sgt)
+{
+	struct drm_mm_node *node;
+	struct scatterlist *sg;
+	int num_entries = 0;
+	unsigned int pages;
+	int i, r;
+
+	*sgt = kmalloc(sizeof(*sg), GFP_KERNEL);
+	if (!*sgt)
+		return -ENOMEM;
+
+	for (pages = mem->num_pages, node = mem->mm_node;
+	     pages; pages -= node->size, ++node)
+		++num_entries;
+
+	r = sg_alloc_table(*sgt, num_entries, GFP_KERNEL);
+	if (r)
+		goto error_free;
+
+	for_each_sg((*sgt)->sgl, sg, num_entries, i)
+		sg->length = 0;
+
+	node = mem->mm_node;
+	for_each_sg((*sgt)->sgl, sg, num_entries, i) {
+		phys_addr_t phys = (node->start << PAGE_SHIFT) +
+			adev->gmc.aper_base;
+		size_t size = node->size << PAGE_SHIFT;
+		dma_addr_t addr;
+
+		++node;
+		addr = dma_map_resource(dev, phys, size, dir,
+					DMA_ATTR_SKIP_CPU_SYNC);
+		r = dma_mapping_error(dev, addr);
+		if (r)
+			goto error_unmap;
+
+		sg_set_page(sg, NULL, size, 0);
+		sg_dma_address(sg) = addr;
+		sg_dma_len(sg) = size;
+	}
+	return 0;
+
+error_unmap:
+	for_each_sg((*sgt)->sgl, sg, num_entries, i) {
+		if (!sg->length)
+			continue;
+
+		dma_unmap_resource(dev, sg->dma_address,
+				   sg->length, dir,
+				   DMA_ATTR_SKIP_CPU_SYNC);
+	}
+	sg_free_table(*sgt);
+
+error_free:
+	kfree(*sgt);
+	return r;
+}
+
+/**
+ * amdgpu_vram_mgr_alloc_sgt - allocate and fill a sg table
+ *
+ * @adev: amdgpu device pointer
+ * @sgt: sg table to free
+ *
+ * Free a previously allocate sg table.
+ */
+void amdgpu_vram_mgr_free_sgt(struct amdgpu_device *adev,
+			      struct device *dev,
+			      enum dma_data_direction dir,
+			      struct sg_table *sgt)
+{
+	struct scatterlist *sg;
+	int i;
+
+	for_each_sg(sgt->sgl, sg, sgt->nents, i)
+		dma_unmap_resource(dev, sg->dma_address,
+				   sg->length, dir,
+				   DMA_ATTR_SKIP_CPU_SYNC);
+	sg_free_table(sgt);
+	kfree(sgt);
+}
+
 /**
  * amdgpu_vram_mgr_usage - how many bytes are used in this domain
  *
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c
index 95b3327168ac..8c3215505e78 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c
@@ -604,6 +604,8 @@ int amdgpu_xgmi_ras_late_init(struct amdgpu_device *adev)
 	    adev->gmc.xgmi.num_physical_nodes == 0)
 		return 0;
 
+	amdgpu_xgmi_reset_ras_error_count(adev);
+
 	if (!adev->gmc.xgmi.ras_if) {
 		adev->gmc.xgmi.ras_if = kmalloc(sizeof(struct ras_common_if), GFP_KERNEL);
 		if (!adev->gmc.xgmi.ras_if)
@@ -668,6 +670,32 @@ uint64_t amdgpu_xgmi_get_relative_phy_addr(struct amdgpu_device *adev,
 	return addr + dram_base_addr;
 }
 
+static void pcs_clear_status(struct amdgpu_device *adev, uint32_t pcs_status_reg)
+{
+	WREG32_PCIE(pcs_status_reg, 0xFFFFFFFF);
+	WREG32_PCIE(pcs_status_reg, 0);
+}
+
+void amdgpu_xgmi_reset_ras_error_count(struct amdgpu_device *adev)
+{
+	uint32_t i;
+
+	switch (adev->asic_type) {
+	case CHIP_ARCTURUS:
+		for (i = 0; i < ARRAY_SIZE(xgmi_pcs_err_status_reg_arct); i++)
+			pcs_clear_status(adev,
+					 xgmi_pcs_err_status_reg_arct[i]);
+		break;
+	case CHIP_VEGA20:
+		for (i = 0; i < ARRAY_SIZE(xgmi_pcs_err_status_reg_vg20); i++)
+			pcs_clear_status(adev,
+					 xgmi_pcs_err_status_reg_vg20[i]);
+		break;
+	default:
+		break;
+	}
+}
+
 static int amdgpu_xgmi_query_pcs_error_status(struct amdgpu_device *adev,
 					      uint32_t value,
 					      uint32_t *ue_count,
@@ -758,6 +786,8 @@ int amdgpu_xgmi_query_ras_error_count(struct amdgpu_device *adev,
 		break;
 	}
 
+	amdgpu_xgmi_reset_ras_error_count(adev);
+
 	err_data->ue_count += ue_cnt;
 	err_data->ce_count += ce_cnt;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.h
index 4a92067fe595..d5a63904ec33 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.h
@@ -56,6 +56,7 @@ uint64_t amdgpu_xgmi_get_relative_phy_addr(struct amdgpu_device *adev,
 					   uint64_t addr);
 int amdgpu_xgmi_query_ras_error_count(struct amdgpu_device *adev,
 				      void *ras_error_status);
+void amdgpu_xgmi_reset_ras_error_count(struct amdgpu_device *adev);
 
 static inline bool amdgpu_xgmi_same_hive(struct amdgpu_device *adev,
 		struct amdgpu_device *bo_adev)
diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c
index cae426c7c086..4cfc786699c7 100644
--- a/drivers/gpu/drm/amd/amdgpu/atom.c
+++ b/drivers/gpu/drm/amd/amdgpu/atom.c
@@ -54,6 +54,8 @@
 #define PLL_INDEX	2
 #define PLL_DATA	3
 
+#define ATOM_CMD_TIMEOUT_SEC	20
+
 typedef struct {
 	struct atom_context *ctx;
 	uint32_t *ps, *ws;
@@ -744,8 +746,9 @@ static void atom_op_jump(atom_exec_context *ctx, int *ptr, int arg)
 			cjiffies = jiffies;
 			if (time_after(cjiffies, ctx->last_jump_jiffies)) {
 				cjiffies -= ctx->last_jump_jiffies;
-				if ((jiffies_to_msecs(cjiffies) > 10000)) {
-					DRM_ERROR("atombios stuck in loop for more than 10secs aborting\n");
+				if ((jiffies_to_msecs(cjiffies) > ATOM_CMD_TIMEOUT_SEC*1000)) {
+					DRM_ERROR("atombios stuck in loop for more than %dsecs aborting\n",
+						  ATOM_CMD_TIMEOUT_SEC);
 					ctx->abort = true;
 				}
 			} else {
diff --git a/drivers/gpu/drm/amd/amdgpu/cik.c b/drivers/gpu/drm/amd/amdgpu/cik.c
index 006f21ef7ddf..fe306d0f73f7 100644
--- a/drivers/gpu/drm/amd/amdgpu/cik.c
+++ b/drivers/gpu/drm/amd/amdgpu/cik.c
@@ -1358,8 +1358,6 @@ static int cik_asic_reset(struct amdgpu_device *adev)
 	int r;
 
 	if (cik_asic_reset_method(adev) == AMD_RESET_METHOD_BACO) {
-		if (!adev->in_suspend)
-			amdgpu_inc_vram_lost(adev);
 		r = amdgpu_dpm_baco_reset(adev);
 	} else {
 		r = cik_asic_pci_config_reset(adev);
@@ -1811,12 +1809,6 @@ static uint32_t cik_get_rev_id(struct amdgpu_device *adev)
 		>> CC_DRM_ID_STRAPS__ATI_REV_ID__SHIFT;
 }
 
-static void cik_detect_hw_virtualization(struct amdgpu_device *adev)
-{
-	if (is_virtual_machine()) /* passthrough mode */
-		adev->virt.caps |= AMDGPU_PASSTHROUGH_MODE;
-}
-
 static void cik_flush_hdp(struct amdgpu_device *adev, struct amdgpu_ring *ring)
 {
 	if (!ring || !ring->funcs->emit_wreg) {
@@ -2179,8 +2171,6 @@ static const struct amdgpu_ip_block_version cik_common_ip_block =
 
 int cik_set_ip_blocks(struct amdgpu_device *adev)
 {
-	cik_detect_hw_virtualization(adev);
-
 	switch (adev->asic_type) {
 	case CHIP_BONAIRE:
 		amdgpu_device_ip_block_add(adev, &cik_common_ip_block);
diff --git a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
index 580d3f93d670..20f108818b2b 100644
--- a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
+++ b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
@@ -320,8 +320,6 @@ static void cik_sdma_gfx_stop(struct amdgpu_device *adev)
 		WREG32(mmSDMA0_GFX_RB_CNTL + sdma_offsets[i], rb_cntl);
 		WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], 0);
 	}
-	sdma0->sched.ready = false;
-	sdma1->sched.ready = false;
 }
 
 /**
@@ -679,7 +677,8 @@ static int cik_sdma_ring_test_ib(struct amdgpu_ring *ring, long timeout)
 	tmp = 0xCAFEDEAD;
 	adev->wb.wb[index] = cpu_to_le32(tmp);
 	memset(&ib, 0, sizeof(ib));
-	r = amdgpu_ib_get(adev, NULL, 256, &ib);
+	r = amdgpu_ib_get(adev, NULL, 256,
+					AMDGPU_IB_POOL_DIRECT, &ib);
 	if (r)
 		goto err0;
 
@@ -980,7 +979,8 @@ static int cik_sdma_sw_init(void *handle)
 				     &adev->sdma.trap_irq,
 				     (i == 0) ?
 				     AMDGPU_SDMA_IRQ_INSTANCE0 :
-				     AMDGPU_SDMA_IRQ_INSTANCE1);
+				     AMDGPU_SDMA_IRQ_INSTANCE1,
+				     AMDGPU_RING_PRIO_DEFAULT);
 		if (r)
 			return r;
 	}
@@ -1313,7 +1313,8 @@ static void cik_sdma_set_irq_funcs(struct amdgpu_device *adev)
 static void cik_sdma_emit_copy_buffer(struct amdgpu_ib *ib,
 				      uint64_t src_offset,
 				      uint64_t dst_offset,
-				      uint32_t byte_count)
+				      uint32_t byte_count,
+				      bool tmz)
 {
 	ib->ptr[ib->length_dw++] = SDMA_PACKET(SDMA_OPCODE_COPY, SDMA_COPY_SUB_OPCODE_LINEAR, 0);
 	ib->ptr[ib->length_dw++] = byte_count;
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
index 2512e7ebfedf..e38744d06f4e 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
@@ -2303,9 +2303,9 @@ static void dce_v10_0_hide_cursor(struct drm_crtc *crtc)
 	struct amdgpu_device *adev = crtc->dev->dev_private;
 	u32 tmp;
 
-	tmp = RREG32_IDX(mmCUR_CONTROL + amdgpu_crtc->crtc_offset);
+	tmp = RREG32(mmCUR_CONTROL + amdgpu_crtc->crtc_offset);
 	tmp = REG_SET_FIELD(tmp, CUR_CONTROL, CURSOR_EN, 0);
-	WREG32_IDX(mmCUR_CONTROL + amdgpu_crtc->crtc_offset, tmp);
+	WREG32(mmCUR_CONTROL + amdgpu_crtc->crtc_offset, tmp);
 }
 
 static void dce_v10_0_show_cursor(struct drm_crtc *crtc)
@@ -2319,10 +2319,10 @@ static void dce_v10_0_show_cursor(struct drm_crtc *crtc)
 	WREG32(mmCUR_SURFACE_ADDRESS + amdgpu_crtc->crtc_offset,
 	       lower_32_bits(amdgpu_crtc->cursor_addr));
 
-	tmp = RREG32_IDX(mmCUR_CONTROL + amdgpu_crtc->crtc_offset);
+	tmp = RREG32(mmCUR_CONTROL + amdgpu_crtc->crtc_offset);
 	tmp = REG_SET_FIELD(tmp, CUR_CONTROL, CURSOR_EN, 1);
 	tmp = REG_SET_FIELD(tmp, CUR_CONTROL, CURSOR_MODE, 2);
-	WREG32_IDX(mmCUR_CONTROL + amdgpu_crtc->crtc_offset, tmp);
+	WREG32(mmCUR_CONTROL + amdgpu_crtc->crtc_offset, tmp);
 }
 
 static int dce_v10_0_cursor_move_locked(struct drm_crtc *crtc,
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
index 0dde22db9848..2584ff74423b 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
@@ -2382,9 +2382,9 @@ static void dce_v11_0_hide_cursor(struct drm_crtc *crtc)
 	struct amdgpu_device *adev = crtc->dev->dev_private;
 	u32 tmp;
 
-	tmp = RREG32_IDX(mmCUR_CONTROL + amdgpu_crtc->crtc_offset);
+	tmp = RREG32(mmCUR_CONTROL + amdgpu_crtc->crtc_offset);
 	tmp = REG_SET_FIELD(tmp, CUR_CONTROL, CURSOR_EN, 0);
-	WREG32_IDX(mmCUR_CONTROL + amdgpu_crtc->crtc_offset, tmp);
+	WREG32(mmCUR_CONTROL + amdgpu_crtc->crtc_offset, tmp);
 }
 
 static void dce_v11_0_show_cursor(struct drm_crtc *crtc)
@@ -2398,10 +2398,10 @@ static void dce_v11_0_show_cursor(struct drm_crtc *crtc)
 	WREG32(mmCUR_SURFACE_ADDRESS + amdgpu_crtc->crtc_offset,
 	       lower_32_bits(amdgpu_crtc->cursor_addr));
 
-	tmp = RREG32_IDX(mmCUR_CONTROL + amdgpu_crtc->crtc_offset);
+	tmp = RREG32(mmCUR_CONTROL + amdgpu_crtc->crtc_offset);
 	tmp = REG_SET_FIELD(tmp, CUR_CONTROL, CURSOR_EN, 1);
 	tmp = REG_SET_FIELD(tmp, CUR_CONTROL, CURSOR_MODE, 2);
-	WREG32_IDX(mmCUR_CONTROL + amdgpu_crtc->crtc_offset, tmp);
+	WREG32(mmCUR_CONTROL + amdgpu_crtc->crtc_offset, tmp);
 }
 
 static int dce_v11_0_cursor_move_locked(struct drm_crtc *crtc,
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
index 84219534bd38..d05c39f9ae40 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
@@ -2194,9 +2194,9 @@ static void dce_v6_0_hide_cursor(struct drm_crtc *crtc)
 	struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
 	struct amdgpu_device *adev = crtc->dev->dev_private;
 
-	WREG32_IDX(mmCUR_CONTROL + amdgpu_crtc->crtc_offset,
-		   (CURSOR_24_8_PRE_MULT << CUR_CONTROL__CURSOR_MODE__SHIFT) |
-		   (CURSOR_URGENT_1_2 << CUR_CONTROL__CURSOR_URGENT_CONTROL__SHIFT));
+	WREG32(mmCUR_CONTROL + amdgpu_crtc->crtc_offset,
+	       (CURSOR_24_8_PRE_MULT << CUR_CONTROL__CURSOR_MODE__SHIFT) |
+	       (CURSOR_URGENT_1_2 << CUR_CONTROL__CURSOR_URGENT_CONTROL__SHIFT));
 
 
 }
@@ -2211,10 +2211,10 @@ static void dce_v6_0_show_cursor(struct drm_crtc *crtc)
 	WREG32(mmCUR_SURFACE_ADDRESS + amdgpu_crtc->crtc_offset,
 	       lower_32_bits(amdgpu_crtc->cursor_addr));
 
-	WREG32_IDX(mmCUR_CONTROL + amdgpu_crtc->crtc_offset,
-		   CUR_CONTROL__CURSOR_EN_MASK |
-		   (CURSOR_24_8_PRE_MULT << CUR_CONTROL__CURSOR_MODE__SHIFT) |
-		   (CURSOR_URGENT_1_2 << CUR_CONTROL__CURSOR_URGENT_CONTROL__SHIFT));
+	WREG32(mmCUR_CONTROL + amdgpu_crtc->crtc_offset,
+	       CUR_CONTROL__CURSOR_EN_MASK |
+	       (CURSOR_24_8_PRE_MULT << CUR_CONTROL__CURSOR_MODE__SHIFT) |
+	       (CURSOR_URGENT_1_2 << CUR_CONTROL__CURSOR_URGENT_CONTROL__SHIFT));
 
 }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
index 3a640702d7d1..ad0f8adb6a2b 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
@@ -2205,9 +2205,9 @@ static void dce_v8_0_hide_cursor(struct drm_crtc *crtc)
 	struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
 	struct amdgpu_device *adev = crtc->dev->dev_private;
 
-	WREG32_IDX(mmCUR_CONTROL + amdgpu_crtc->crtc_offset,
-		   (CURSOR_24_8_PRE_MULT << CUR_CONTROL__CURSOR_MODE__SHIFT) |
-		   (CURSOR_URGENT_1_2 << CUR_CONTROL__CURSOR_URGENT_CONTROL__SHIFT));
+	WREG32(mmCUR_CONTROL + amdgpu_crtc->crtc_offset,
+	       (CURSOR_24_8_PRE_MULT << CUR_CONTROL__CURSOR_MODE__SHIFT) |
+	       (CURSOR_URGENT_1_2 << CUR_CONTROL__CURSOR_URGENT_CONTROL__SHIFT));
 }
 
 static void dce_v8_0_show_cursor(struct drm_crtc *crtc)
@@ -2220,10 +2220,10 @@ static void dce_v8_0_show_cursor(struct drm_crtc *crtc)
 	WREG32(mmCUR_SURFACE_ADDRESS + amdgpu_crtc->crtc_offset,
 	       lower_32_bits(amdgpu_crtc->cursor_addr));
 
-	WREG32_IDX(mmCUR_CONTROL + amdgpu_crtc->crtc_offset,
-		   CUR_CONTROL__CURSOR_EN_MASK |
-		   (CURSOR_24_8_PRE_MULT << CUR_CONTROL__CURSOR_MODE__SHIFT) |
-		   (CURSOR_URGENT_1_2 << CUR_CONTROL__CURSOR_URGENT_CONTROL__SHIFT));
+	WREG32(mmCUR_CONTROL + amdgpu_crtc->crtc_offset,
+	       CUR_CONTROL__CURSOR_EN_MASK |
+	       (CURSOR_24_8_PRE_MULT << CUR_CONTROL__CURSOR_MODE__SHIFT) |
+	       (CURSOR_URGENT_1_2 << CUR_CONTROL__CURSOR_URGENT_CONTROL__SHIFT));
 }
 
 static int dce_v8_0_cursor_move_locked(struct drm_crtc *crtc,
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
index 13e12be667fc..bb4fd1341352 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
@@ -286,7 +286,7 @@ static int dce_virtual_get_modes(struct drm_connector *connector)
 	static const struct mode_size {
 		int w;
 		int h;
-	} common_modes[17] = {
+	} common_modes[21] = {
 		{ 640,  480},
 		{ 720,  480},
 		{ 800,  600},
@@ -303,10 +303,14 @@ static int dce_virtual_get_modes(struct drm_connector *connector)
 		{1680, 1050},
 		{1600, 1200},
 		{1920, 1080},
-		{1920, 1200}
+		{1920, 1200},
+		{4096, 3112},
+		{3656, 2664},
+		{3840, 2160},
+		{4096, 2160},
 	};
 
-	for (i = 0; i < 17; i++) {
+	for (i = 0; i < 21; i++) {
 		mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h, 60, false, false, false);
 		drm_mode_probed_add(connector, mode);
 	}
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
index d78059fd2c72..0a03e2ad5d95 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
@@ -138,6 +138,1062 @@ static const struct soc15_reg_golden golden_settings_gc_10_0_nv10[] =
 	/* Pending on emulation bring up */
 };
 
+static const struct soc15_reg_golden golden_settings_gc_rlc_spm_10_0_nv10[] =
+{
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xe0000000, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x28),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x9),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1b),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1b),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x20),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xc8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xf),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xcc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xf),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xd0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xf),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xd4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xf),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x24),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xf),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x24),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xf),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x11),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xf),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x11),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x88),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x8c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xb0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x6),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xb4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x6),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xb8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xa),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xbc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xc0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xa),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xc4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xa),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x90),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x94),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x98),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x6),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x9c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x6),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xa0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xa4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xa8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x6),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xac),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x9),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xb),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x38),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x3c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x40),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xa),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x44),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x48),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x5),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x4c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x9),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x70),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x9),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x74),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x9),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x78),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xb),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x7c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xd),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x80),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xf),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x84),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xb),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x50),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x7),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x54),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x5),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x58),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x9),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x5c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x60),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xb),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x64),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x9),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x68),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x9),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x6c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xb),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x1c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x3),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x20),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x20),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x24),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x24),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x28),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x28),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x2c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1b),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x2c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1b),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x30),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x30),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x34),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x34),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x38),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x38),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x3c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1a),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x3c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1a),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x50),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x50),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x54),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x54),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x58),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x58),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x5c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x5c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1d),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1d),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x48),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1a),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x48),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1a),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x4c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1a),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x4c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1a),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x40),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x40),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x44),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1b),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x44),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1b),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x17),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x17),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x60),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x60),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x64),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xf),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x64),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xf),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x70),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x16),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x70),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x16),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x74),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x74),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x68),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x68),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x6c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x6c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x78),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xd),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x78),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xd),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x7c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xa),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x7c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xa),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x88),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x88),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x8c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xa),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x8c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xa),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x80),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x80),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x84),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xa),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x84),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xa),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x90),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x90),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x94),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x94),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xa0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x6),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xa0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x6),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xa4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x3),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xa4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x3),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x98),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x98),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x9c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x9c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xa8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xa8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xac),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xac),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xb8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x13),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xb8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x13),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xbc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xbc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xb0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xb0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xb4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xb4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xc0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xc0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xc4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xa),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xc4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xa),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xd0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xb),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xd0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xb),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xd4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x6),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xd4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x6),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xc8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xc8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xcc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xb),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xcc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xb),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xe8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xe8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xec),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xec),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xf0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xf0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xf4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xf4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xf8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xf8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xfc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xfc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x100),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x100),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x104),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x104),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xe0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x13),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xe0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x13),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x118),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x13),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x118),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x13),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x11c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x13),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x11c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x13),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x120),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x13),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x120),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x13),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x124),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x13),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x124),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x13),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xdc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1b),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xdc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1b),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x110),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x110),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x114),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x114),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x108),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x108),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x10c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x10c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xd8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x17),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xd8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x17),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x128),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xf),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x128),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xf),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x12c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x12c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x138),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x138),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x13c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x13c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x130),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x130),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x134),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x134),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x140),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xa),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x140),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xa),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x144),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x7),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x144),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x7),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x150),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xa),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x150),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xa),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x154),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x7),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x154),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x7),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x148),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xa),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x148),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xa),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x14c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x7),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x14c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x7),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x158),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x5),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x158),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x5),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x15c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x2),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x15c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x2),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x168),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x168),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x16c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x16c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x160),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x160),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x164),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x2),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x164),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x2),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x170),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x11),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x170),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x11),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x174),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xd),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x174),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xd),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x180),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xf),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x180),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xf),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x184),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x184),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x178),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x11),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x178),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x11),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x17c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xd),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x17c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xd),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x188),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xa),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x188),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xa),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x18c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x18c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x198),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x9),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x198),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x9),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x19c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x3),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x19c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x3),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x190),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xa),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x190),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xa),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x194),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x194),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x30),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x11),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x34),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1d),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1d),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1f),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1f),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x2c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xb),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLOBALS_SAMPLE_SKEW, 0x000000FF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLOBALS_MUXSEL_SKEW, 0x000000FF, 0x20),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLE_SKEW, 0x000000FF, 0x5),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLE_SKEW, 0x000000FF, 0xa),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_MUXSEL_SKEW, 0x000000FF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_MUXSEL_SKEW, 0x000000FF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_DESER_START_SKEW, 0x000000FF, 0x33),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xFFFFFFFF, 0xe0000000)
+};
+
 static const struct soc15_reg_golden golden_settings_gc_10_1_1[] =
 {
 	SOC15_REG_GOLDEN_VALUE(GC, 0, mmCB_HW_CONTROL_4, 0xffffffff, 0x003c0014),
@@ -272,14 +1328,1694 @@ static const struct soc15_reg_golden golden_settings_gc_10_1_nv14[] =
 	/* Pending on emulation bring up */
 };
 
+static const struct soc15_reg_golden golden_settings_gc_rlc_spm_10_1_nv14[] =
+{
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xE0000000L, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x28),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xa),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x20),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xf),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x80),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x84),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x88),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x8c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x24),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x24),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x20),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x60),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x64),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x2),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x68),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x2),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x6c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x2),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x70),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x2),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x74),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x2),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x78),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x7c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x2),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xa),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xa),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x38),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x3c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x40),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x3),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x44),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x9),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x48),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x7),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x4c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x3),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x50),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x3),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x54),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x3),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x58),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x7),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x5c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x9),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x1c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x2),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x20),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x24),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x16),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x28),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x2c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1a),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x30),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x16),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x34),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x38),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1a),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x3c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x50),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1e),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x54),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1e),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x58),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1e),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x5c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1e),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x20),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x48),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1a),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x4c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1a),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x40),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1e),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x44),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1e),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1a),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x60),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x16),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x64),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x70),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x16),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x74),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x16),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x68),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x16),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x6c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x78),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x7c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x88),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x8c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x80),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x84),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x90),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xa),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x94),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x6),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xa0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xa4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x98),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xa),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x9c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x6),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xa8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xac),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xb8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xbc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xb0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xb4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xc0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x16),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xc4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xd0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x16),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xd4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xc8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x16),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xcc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xd8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xdc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xe8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xec),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xe0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xe4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x100),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x104),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x108),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x10c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x110),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x114),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x118),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x11c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x16),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xf8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x17),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x130),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x134),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x138),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x13c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xf4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x20),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x128),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x12c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x120),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x124),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xf0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1a),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x140),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x144),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x150),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x154),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x148),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x14c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x158),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xa),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x15c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x6),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x168),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x16c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x160),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xa),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x164),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x6),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x170),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x174),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x180),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xa),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x184),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x178),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x17c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x188),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x16),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x18c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x198),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x19c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x190),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x16),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x194),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x1a0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x1a4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x1b0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x1b4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x1a8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x1ac),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x1b8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xa),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x1bc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x6),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x1c8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x1cc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xa),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x1c0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xa),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x1c4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x6),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x30),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x34),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x20),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x20),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x2c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLOBALS_SAMPLE_SKEW, 0x000000FF, 0x26),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLOBALS_MUXSEL_SKEW, 0x000000FF, 0x28),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLE_SKEW, 0x000000FF, 0xf),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLE_SKEW, 0x000000FF, 0x15),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_MUXSEL_SKEW, 0x000000FF, 0x1f),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_MUXSEL_SKEW, 0x000000FF, 0x25),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_DESER_START_SKEW, 0x000000FF, 0x3b),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xFFFFFFFF, 0xe0000000)
+};
+
 static const struct soc15_reg_golden golden_settings_gc_10_1_2_nv12[] =
 {
 	/* Pending on emulation bring up */
 };
 
+static const struct soc15_reg_golden golden_settings_gc_rlc_spm_10_1_2_nv12[] =
+{
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xe0000000L, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x28),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x5),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1b),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1b),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x20),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xc8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xd),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xcc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xd),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xd0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xd),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xd4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xd),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x24),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xd),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x24),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xd),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x11),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x11),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x88),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x8c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x2),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xb0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xb4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xb8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x6),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xbc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x6),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xc0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x7),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xc4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x6),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x90),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x2),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x94),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x98),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x5),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x9c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xa0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xa4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x6),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xa8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x6),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xac),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x6),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x5),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xd),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x9),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x38),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x7),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x3c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x7),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x40),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xd),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x44),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x48),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x4c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x7),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x70),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x74),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x7),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x78),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x7c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xa),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x80),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xb),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x84),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x6),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x50),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x6),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x54),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x3),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x58),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x5c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x7),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x60),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x6),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x64),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x68),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x7),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x6c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xa),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x1c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x3),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x11),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x20),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x20),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x24),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x24),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x28),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x28),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x2c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1a),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x2c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1a),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x30),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1d),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x30),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1d),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x34),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1a),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x34),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1a),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x38),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x16),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x38),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x16),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x3c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x3c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x18),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x50),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x50),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x54),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x54),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x58),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x58),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x5c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x5c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1a),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1a),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x48),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x48),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x4c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x4c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x40),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1a),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x40),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1a),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x44),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1a),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x44),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1a),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1b),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1b),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x60),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x15),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x60),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x15),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x64),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x13),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x64),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x13),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x70),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x16),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x70),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x16),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x74),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x74),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x68),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x15),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x68),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x15),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x6c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x13),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x6c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x13),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x78),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x78),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x7c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xb),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x7c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xb),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x88),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x88),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x8c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x8c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x80),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x80),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x84),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xb),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x84),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xb),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x90),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x9),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x90),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x9),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x94),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x94),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xa0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xa0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xa4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xd),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xa4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xd),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x98),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x9),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x98),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x9),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x9c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x9c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xa8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xa8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xac),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xac),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xb8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xb8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xbc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xbc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xb0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xb0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xb4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xb4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xc0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x11),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xc0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x11),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xc4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xb),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xc4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xb),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xd0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xd0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xd4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xd4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xc8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x11),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xc8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x11),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xcc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xb),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xcc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xb),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xe8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xe8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xec),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x16),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xec),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x16),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xf0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x15),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xf0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x15),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xf4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xf4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xf8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xf8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xfc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x17),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xfc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x17),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x100),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x13),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x100),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x13),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x104),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x11),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x104),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x11),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xe0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xe0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x118),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x15),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x118),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x15),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x11c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x15),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x11c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x15),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x120),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x15),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x120),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x15),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x124),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x15),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x124),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x15),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xdc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xdc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x110),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x15),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x110),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x15),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x114),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x114),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x14),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x108),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x108),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x10c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x10c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x19),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xd8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1b),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0xd8),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1b),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x128),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x128),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x12c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x12c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x138),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x138),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x13c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x13c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x130),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x130),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x12),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x134),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xf),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x134),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xf),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x140),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x140),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x144),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x7),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x144),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x7),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x150),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x150),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x154),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xd),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x154),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xd),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x148),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x148),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x14c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x7),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x14c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x7),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x158),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x5),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x158),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x5),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x15c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x15c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x168),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xa),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x168),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xa),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x16c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x9),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x16c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x9),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x160),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x5),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x160),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x5),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x164),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x164),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x170),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x170),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x174),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x174),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x180),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x180),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x184),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x184),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x178),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x178),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x17c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x17c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x188),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x188),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x18c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x5),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x18c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x5),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x198),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x198),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xc),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x19c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xb),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x19c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xb),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x190),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x190),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xe),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x194),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x6),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x194),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x6),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x30),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xd),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x34),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x11),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1d),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1d),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1f),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x4),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0x1f),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_ADDR, 0xFFFFFFFF, 0x2c),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLB_SAMPLEDELAY_IND_DATA, 0xFFFFFFFF, 0xb),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLOBALS_SAMPLE_SKEW, 0x000000FF, 0x1f),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_GLOBALS_MUXSEL_SKEW, 0x000000FF, 0x22),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLE_SKEW, 0x000000FF, 0x1),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_SAMPLE_SKEW, 0x000000FF, 0x6),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_MUXSEL_SKEW, 0x000000FF, 0x10),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x10000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_SE_MUXSEL_SKEW, 0x000000FF, 0x15),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xffffff, 0x0),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_DESER_START_SKEW, 0x000000FF, 0x35),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_GFX_INDEX, 0xFFFFFFFF, 0xe0000000)
+};
+
 #define DEFAULT_SH_MEM_CONFIG \
 	((SH_MEM_ADDRESS_MODE_64 << SH_MEM_CONFIG__ADDRESS_MODE__SHIFT) | \
-	 (SH_MEM_ALIGNMENT_MODE_DWORD << SH_MEM_CONFIG__ALIGNMENT_MODE__SHIFT) | \
+	 (SH_MEM_ALIGNMENT_MODE_UNALIGNED << SH_MEM_CONFIG__ALIGNMENT_MODE__SHIFT) | \
 	 (SH_MEM_RETRY_MODE_ALL << SH_MEM_CONFIG__RETRY_MODE__SHIFT) | \
 	 (3 << SH_MEM_CONFIG__INITIAL_INST_PREFETCH__SHIFT))
 
@@ -301,7 +3037,7 @@ static int gfx_v10_0_rlc_backdoor_autoload_enable(struct amdgpu_device *adev);
 static int gfx_v10_0_wait_for_rlc_autoload_complete(struct amdgpu_device *adev);
 static void gfx_v10_0_ring_emit_ce_meta(struct amdgpu_ring *ring, bool resume);
 static void gfx_v10_0_ring_emit_de_meta(struct amdgpu_ring *ring, bool resume);
-static void gfx_v10_0_ring_emit_tmz(struct amdgpu_ring *ring, bool start);
+static void gfx_v10_0_ring_emit_frame_cntl(struct amdgpu_ring *ring, bool start, bool secure);
 
 static void gfx10_kiq_set_resources(struct amdgpu_ring *kiq_ring, uint64_t queue_mask)
 {
@@ -431,6 +3167,9 @@ static void gfx_v10_0_init_golden_registers(struct amdgpu_device *adev)
 		soc15_program_register_sequence(adev,
 						golden_settings_gc_10_0_nv10,
 						(const u32)ARRAY_SIZE(golden_settings_gc_10_0_nv10));
+		soc15_program_register_sequence(adev,
+						golden_settings_gc_rlc_spm_10_0_nv10,
+						(const u32)ARRAY_SIZE(golden_settings_gc_rlc_spm_10_0_nv10));
 		break;
 	case CHIP_NAVI14:
 		soc15_program_register_sequence(adev,
@@ -439,6 +3178,9 @@ static void gfx_v10_0_init_golden_registers(struct amdgpu_device *adev)
 		soc15_program_register_sequence(adev,
 						golden_settings_gc_10_1_nv14,
 						(const u32)ARRAY_SIZE(golden_settings_gc_10_1_nv14));
+		soc15_program_register_sequence(adev,
+						golden_settings_gc_rlc_spm_10_1_nv14,
+						(const u32)ARRAY_SIZE(golden_settings_gc_rlc_spm_10_1_nv14));
 		break;
 	case CHIP_NAVI12:
 		soc15_program_register_sequence(adev,
@@ -447,6 +3189,9 @@ static void gfx_v10_0_init_golden_registers(struct amdgpu_device *adev)
 		soc15_program_register_sequence(adev,
 						golden_settings_gc_10_1_2_nv12,
 						(const u32)ARRAY_SIZE(golden_settings_gc_10_1_2_nv12));
+		soc15_program_register_sequence(adev,
+						golden_settings_gc_rlc_spm_10_1_2_nv12,
+						(const u32)ARRAY_SIZE(golden_settings_gc_rlc_spm_10_1_2_nv12));
 		break;
 	default:
 		break;
@@ -557,7 +3302,8 @@ static int gfx_v10_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
 	gpu_addr = adev->wb.gpu_addr + (index * 4);
 	adev->wb.wb[index] = cpu_to_le32(0xCAFEDEAD);
 	memset(&ib, 0, sizeof(ib));
-	r = amdgpu_ib_get(adev, NULL, 16, &ib);
+	r = amdgpu_ib_get(adev, NULL, 16,
+					AMDGPU_IB_POOL_DIRECT, &ib);
 	if (r)
 		goto err1;
 
@@ -1298,7 +4044,8 @@ static int gfx_v10_0_gfx_ring_init(struct amdgpu_device *adev, int ring_id,
 
 	irq_type = AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP + ring->pipe;
 	r = amdgpu_ring_init(adev, ring, 1024,
-			     &adev->gfx.eop_irq, irq_type);
+			     &adev->gfx.eop_irq, irq_type,
+			     AMDGPU_RING_PRIO_DEFAULT);
 	if (r)
 		return r;
 	return 0;
@@ -1309,7 +4056,8 @@ static int gfx_v10_0_compute_ring_init(struct amdgpu_device *adev, int ring_id,
 {
 	int r;
 	unsigned irq_type;
-	struct amdgpu_ring *ring = &adev->gfx.compute_ring[ring_id];
+	struct amdgpu_ring *ring;
+	unsigned int hw_prio;
 
 	ring = &adev->gfx.compute_ring[ring_id];
 
@@ -1328,10 +4076,11 @@ static int gfx_v10_0_compute_ring_init(struct amdgpu_device *adev, int ring_id,
 	irq_type = AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP
 		+ ((ring->me - 1) * adev->gfx.mec.num_pipe_per_mec)
 		+ ring->pipe;
-
+	hw_prio = amdgpu_gfx_is_high_priority_compute_queue(adev, ring->queue) ?
+			AMDGPU_GFX_PIPE_PRIO_HIGH : AMDGPU_GFX_PIPE_PRIO_NORMAL;
 	/* type-2 packets are deprecated on MEC, use type-3 instead */
 	r = amdgpu_ring_init(adev, ring, 1024,
-			     &adev->gfx.eop_irq, irq_type);
+			     &adev->gfx.eop_irq, irq_type, hw_prio);
 	if (r)
 		return r;
 
@@ -2441,10 +5190,6 @@ static int gfx_v10_0_cp_gfx_enable(struct amdgpu_device *adev, bool enable)
 	tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, ME_HALT, enable ? 0 : 1);
 	tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, PFP_HALT, enable ? 0 : 1);
 	tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, CE_HALT, enable ? 0 : 1);
-	if (!enable) {
-		for (i = 0; i < adev->gfx.num_gfx_rings; i++)
-			adev->gfx.gfx_ring[i].sched.ready = false;
-	}
 	WREG32_SOC15_RLC(GC, 0, mmCP_ME_CNTL, tmp);
 
 	for (i = 0; i < adev->usec_timeout; i++) {
@@ -2923,16 +5668,12 @@ static int gfx_v10_0_cp_gfx_resume(struct amdgpu_device *adev)
 
 static void gfx_v10_0_cp_compute_enable(struct amdgpu_device *adev, bool enable)
 {
-	int i;
-
 	if (enable) {
 		WREG32_SOC15(GC, 0, mmCP_MEC_CNTL, 0);
 	} else {
 		WREG32_SOC15(GC, 0, mmCP_MEC_CNTL,
 			     (CP_MEC_CNTL__MEC_ME1_HALT_MASK |
 			      CP_MEC_CNTL__MEC_ME2_HALT_MASK));
-		for (i = 0; i < adev->gfx.num_compute_rings; i++)
-			adev->gfx.compute_ring[i].sched.ready = false;
 		adev->gfx.kiq.ring.sched.ready = false;
 	}
 	udelay(50);
@@ -3268,11 +6009,8 @@ static void gfx_v10_0_compute_mqd_set_priority(struct amdgpu_ring *ring, struct
 	if (ring->funcs->type == AMDGPU_RING_TYPE_COMPUTE) {
 		if (amdgpu_gfx_is_high_priority_compute_queue(adev, ring->queue)) {
 			mqd->cp_hqd_pipe_priority = AMDGPU_GFX_PIPE_PRIO_HIGH;
-			ring->has_high_prio = true;
 			mqd->cp_hqd_queue_priority =
 				AMDGPU_GFX_QUEUE_PRIORITY_MAXIMUM;
-		} else {
-			ring->has_high_prio = false;
 		}
 	}
 }
@@ -4682,7 +7420,8 @@ static void gfx_v10_0_ring_emit_sb(struct amdgpu_ring *ring)
 	amdgpu_ring_write(ring, 0);
 }
 
-static void gfx_v10_0_ring_emit_cntxcntl(struct amdgpu_ring *ring, uint32_t flags)
+static void gfx_v10_0_ring_emit_cntxcntl(struct amdgpu_ring *ring,
+					 uint32_t flags)
 {
 	uint32_t dw2 = 0;
 
@@ -4690,8 +7429,6 @@ static void gfx_v10_0_ring_emit_cntxcntl(struct amdgpu_ring *ring, uint32_t flag
 		gfx_v10_0_ring_emit_ce_meta(ring,
 				    (!amdgpu_sriov_vf(ring->adev) && flags & AMDGPU_IB_PREEMPTED) ? true : false);
 
-	gfx_v10_0_ring_emit_tmz(ring, true);
-
 	dw2 |= 0x80000000; /* set load_enable otherwise this package is just NOPs */
 	if (flags & AMDGPU_HAVE_CTX_SWITCH) {
 		/* set load_global_config & load_global_uconfig */
@@ -4848,10 +7585,13 @@ static void gfx_v10_0_ring_emit_de_meta(struct amdgpu_ring *ring, bool resume)
 					   sizeof(de_payload) >> 2);
 }
 
-static void gfx_v10_0_ring_emit_tmz(struct amdgpu_ring *ring, bool start)
+static void gfx_v10_0_ring_emit_frame_cntl(struct amdgpu_ring *ring, bool start,
+				    bool secure)
 {
+	uint32_t v = secure ? FRAME_TMZ : 0;
+
 	amdgpu_ring_write(ring, PACKET3(PACKET3_FRAME_CONTROL, 0));
-	amdgpu_ring_write(ring, FRAME_CMD(start ? 0 : 1)); /* frame_end */
+	amdgpu_ring_write(ring, v | FRAME_CMD(start ? 0 : 1));
 }
 
 static void gfx_v10_0_ring_emit_rreg(struct amdgpu_ring *ring, uint32_t reg)
@@ -5241,6 +7981,29 @@ static int gfx_v10_0_kiq_irq(struct amdgpu_device *adev,
 	return 0;
 }
 
+static void gfx_v10_0_emit_mem_sync(struct amdgpu_ring *ring)
+{
+	const unsigned int gcr_cntl =
+			PACKET3_ACQUIRE_MEM_GCR_CNTL_GL2_INV(1) |
+			PACKET3_ACQUIRE_MEM_GCR_CNTL_GL2_WB(1) |
+			PACKET3_ACQUIRE_MEM_GCR_CNTL_GLM_INV(1) |
+			PACKET3_ACQUIRE_MEM_GCR_CNTL_GLM_WB(1) |
+			PACKET3_ACQUIRE_MEM_GCR_CNTL_GL1_INV(1) |
+			PACKET3_ACQUIRE_MEM_GCR_CNTL_GLV_INV(1) |
+			PACKET3_ACQUIRE_MEM_GCR_CNTL_GLK_INV(1) |
+			PACKET3_ACQUIRE_MEM_GCR_CNTL_GLI_INV(1);
+
+	/* ACQUIRE_MEM - make one or more surfaces valid for use by the subsequent operations */
+	amdgpu_ring_write(ring, PACKET3(PACKET3_ACQUIRE_MEM, 6));
+	amdgpu_ring_write(ring, 0); /* CP_COHER_CNTL */
+	amdgpu_ring_write(ring, 0xffffffff);  /* CP_COHER_SIZE */
+	amdgpu_ring_write(ring, 0xffffff);  /* CP_COHER_SIZE_HI */
+	amdgpu_ring_write(ring, 0); /* CP_COHER_BASE */
+	amdgpu_ring_write(ring, 0);  /* CP_COHER_BASE_HI */
+	amdgpu_ring_write(ring, 0x0000000A); /* POLL_INTERVAL */
+	amdgpu_ring_write(ring, gcr_cntl); /* GCR_CNTL */
+}
+
 static const struct amd_ip_funcs gfx_v10_0_ip_funcs = {
 	.name = "gfx_v10_0",
 	.early_init = gfx_v10_0_early_init,
@@ -5288,7 +8051,8 @@ static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_gfx = {
 		3 + /* CNTX_CTRL */
 		5 + /* HDP_INVL */
 		8 + 8 + /* FENCE x2 */
-		2, /* SWITCH_BUFFER */
+		2 + /* SWITCH_BUFFER */
+		8, /* gfx_v10_0_emit_mem_sync */
 	.emit_ib_size =	4, /* gfx_v10_0_ring_emit_ib_gfx */
 	.emit_ib = gfx_v10_0_ring_emit_ib_gfx,
 	.emit_fence = gfx_v10_0_ring_emit_fence,
@@ -5305,10 +8069,11 @@ static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_gfx = {
 	.init_cond_exec = gfx_v10_0_ring_emit_init_cond_exec,
 	.patch_cond_exec = gfx_v10_0_ring_emit_patch_cond_exec,
 	.preempt_ib = gfx_v10_0_ring_preempt_ib,
-	.emit_tmz = gfx_v10_0_ring_emit_tmz,
+	.emit_frame_cntl = gfx_v10_0_ring_emit_frame_cntl,
 	.emit_wreg = gfx_v10_0_ring_emit_wreg,
 	.emit_reg_wait = gfx_v10_0_ring_emit_reg_wait,
 	.emit_reg_write_reg_wait = gfx_v10_0_ring_emit_reg_write_reg_wait,
+	.emit_mem_sync = gfx_v10_0_emit_mem_sync,
 };
 
 static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_compute = {
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c
index 31f44d05e606..96112fb9273b 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c
@@ -1914,7 +1914,8 @@ static int gfx_v6_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
 
 	WREG32(scratch, 0xCAFEDEAD);
 	memset(&ib, 0, sizeof(ib));
-	r = amdgpu_ib_get(adev, NULL, 256, &ib);
+	r = amdgpu_ib_get(adev, NULL, 256,
+					AMDGPU_IB_POOL_DIRECT, &ib);
 	if (r)
 		goto err1;
 
@@ -1950,7 +1951,6 @@ static int gfx_v6_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
 
 static void gfx_v6_0_cp_gfx_enable(struct amdgpu_device *adev, bool enable)
 {
-	int i;
 	if (enable) {
 		WREG32(mmCP_ME_CNTL, 0);
 	} else {
@@ -1958,10 +1958,6 @@ static void gfx_v6_0_cp_gfx_enable(struct amdgpu_device *adev, bool enable)
 				      CP_ME_CNTL__PFP_HALT_MASK |
 				      CP_ME_CNTL__CE_HALT_MASK));
 		WREG32(mmSCRATCH_UMSK, 0);
-		for (i = 0; i < adev->gfx.num_gfx_rings; i++)
-			adev->gfx.gfx_ring[i].sched.ready = false;
-		for (i = 0; i < adev->gfx.num_compute_rings; i++)
-			adev->gfx.compute_ring[i].sched.ready = false;
 	}
 	udelay(50);
 }
@@ -3114,7 +3110,9 @@ static int gfx_v6_0_sw_init(void *handle)
 		ring->ring_obj = NULL;
 		sprintf(ring->name, "gfx");
 		r = amdgpu_ring_init(adev, ring, 1024,
-				     &adev->gfx.eop_irq, AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP);
+				     &adev->gfx.eop_irq,
+				     AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP,
+				     AMDGPU_RING_PRIO_DEFAULT);
 		if (r)
 			return r;
 	}
@@ -3136,7 +3134,8 @@ static int gfx_v6_0_sw_init(void *handle)
 		sprintf(ring->name, "comp_%d.%d.%d", ring->me, ring->pipe, ring->queue);
 		irq_type = AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP + ring->pipe;
 		r = amdgpu_ring_init(adev, ring, 1024,
-				     &adev->gfx.eop_irq, irq_type);
+				     &adev->gfx.eop_irq, irq_type,
+				     AMDGPU_RING_PRIO_DEFAULT);
 		if (r)
 			return r;
 	}
@@ -3466,6 +3465,18 @@ static int gfx_v6_0_set_powergating_state(void *handle,
 	return 0;
 }
 
+static void gfx_v6_0_emit_mem_sync(struct amdgpu_ring *ring)
+{
+	amdgpu_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3));
+	amdgpu_ring_write(ring, PACKET3_TCL1_ACTION_ENA |
+			  PACKET3_TC_ACTION_ENA |
+			  PACKET3_SH_KCACHE_ACTION_ENA |
+			  PACKET3_SH_ICACHE_ACTION_ENA);  /* CP_COHER_CNTL */
+	amdgpu_ring_write(ring, 0xffffffff);  /* CP_COHER_SIZE */
+	amdgpu_ring_write(ring, 0);  /* CP_COHER_BASE */
+	amdgpu_ring_write(ring, 0x0000000A); /* poll interval */
+}
+
 static const struct amd_ip_funcs gfx_v6_0_ip_funcs = {
 	.name = "gfx_v6_0",
 	.early_init = gfx_v6_0_early_init,
@@ -3496,7 +3507,8 @@ static const struct amdgpu_ring_funcs gfx_v6_0_ring_funcs_gfx = {
 		14 + 14 + 14 + /* gfx_v6_0_ring_emit_fence x3 for user fence, vm fence */
 		7 + 4 + /* gfx_v6_0_ring_emit_pipeline_sync */
 		SI_FLUSH_GPU_TLB_NUM_WREG * 5 + 7 + 6 + /* gfx_v6_0_ring_emit_vm_flush */
-		3 + 2, /* gfx_v6_ring_emit_cntxcntl including vgt flush */
+		3 + 2 + /* gfx_v6_ring_emit_cntxcntl including vgt flush */
+		5, /* SURFACE_SYNC */
 	.emit_ib_size = 6, /* gfx_v6_0_ring_emit_ib */
 	.emit_ib = gfx_v6_0_ring_emit_ib,
 	.emit_fence = gfx_v6_0_ring_emit_fence,
@@ -3507,6 +3519,7 @@ static const struct amdgpu_ring_funcs gfx_v6_0_ring_funcs_gfx = {
 	.insert_nop = amdgpu_ring_insert_nop,
 	.emit_cntxcntl = gfx_v6_ring_emit_cntxcntl,
 	.emit_wreg = gfx_v6_0_ring_emit_wreg,
+	.emit_mem_sync = gfx_v6_0_emit_mem_sync,
 };
 
 static const struct amdgpu_ring_funcs gfx_v6_0_ring_funcs_compute = {
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
index 733d398c61cc..b2f10e39eff1 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
@@ -2364,7 +2364,8 @@ static int gfx_v7_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
 
 	WREG32(scratch, 0xCAFEDEAD);
 	memset(&ib, 0, sizeof(ib));
-	r = amdgpu_ib_get(adev, NULL, 256, &ib);
+	r = amdgpu_ib_get(adev, NULL, 256,
+					AMDGPU_IB_POOL_DIRECT, &ib);
 	if (r)
 		goto err1;
 
@@ -2431,15 +2432,12 @@ static int gfx_v7_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
  */
 static void gfx_v7_0_cp_gfx_enable(struct amdgpu_device *adev, bool enable)
 {
-	int i;
-
-	if (enable) {
+	if (enable)
 		WREG32(mmCP_ME_CNTL, 0);
-	} else {
-		WREG32(mmCP_ME_CNTL, (CP_ME_CNTL__ME_HALT_MASK | CP_ME_CNTL__PFP_HALT_MASK | CP_ME_CNTL__CE_HALT_MASK));
-		for (i = 0; i < adev->gfx.num_gfx_rings; i++)
-			adev->gfx.gfx_ring[i].sched.ready = false;
-	}
+	else
+		WREG32(mmCP_ME_CNTL, (CP_ME_CNTL__ME_HALT_MASK |
+				      CP_ME_CNTL__PFP_HALT_MASK |
+				      CP_ME_CNTL__CE_HALT_MASK));
 	udelay(50);
 }
 
@@ -2700,15 +2698,11 @@ static void gfx_v7_0_ring_set_wptr_compute(struct amdgpu_ring *ring)
  */
 static void gfx_v7_0_cp_compute_enable(struct amdgpu_device *adev, bool enable)
 {
-	int i;
-
-	if (enable) {
+	if (enable)
 		WREG32(mmCP_MEC_CNTL, 0);
-	} else {
-		WREG32(mmCP_MEC_CNTL, (CP_MEC_CNTL__MEC_ME1_HALT_MASK | CP_MEC_CNTL__MEC_ME2_HALT_MASK));
-		for (i = 0; i < adev->gfx.num_compute_rings; i++)
-			adev->gfx.compute_ring[i].sched.ready = false;
-	}
+	else
+		WREG32(mmCP_MEC_CNTL, (CP_MEC_CNTL__MEC_ME1_HALT_MASK |
+				       CP_MEC_CNTL__MEC_ME2_HALT_MASK));
 	udelay(50);
 }
 
@@ -4439,7 +4433,8 @@ static int gfx_v7_0_compute_ring_init(struct amdgpu_device *adev, int ring_id,
 
 	/* type-2 packets are deprecated on MEC, use type-3 instead */
 	r = amdgpu_ring_init(adev, ring, 1024,
-			&adev->gfx.eop_irq, irq_type);
+			     &adev->gfx.eop_irq, irq_type,
+			     AMDGPU_RING_PRIO_DEFAULT);
 	if (r)
 		return r;
 
@@ -4511,7 +4506,9 @@ static int gfx_v7_0_sw_init(void *handle)
 		ring->ring_obj = NULL;
 		sprintf(ring->name, "gfx");
 		r = amdgpu_ring_init(adev, ring, 1024,
-				     &adev->gfx.eop_irq, AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP);
+				     &adev->gfx.eop_irq,
+				     AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP,
+				     AMDGPU_RING_PRIO_DEFAULT);
 		if (r)
 			return r;
 	}
@@ -5001,6 +4998,18 @@ static int gfx_v7_0_set_powergating_state(void *handle,
 	return 0;
 }
 
+static void gfx_v7_0_emit_mem_sync(struct amdgpu_ring *ring)
+{
+	amdgpu_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3));
+	amdgpu_ring_write(ring, PACKET3_TCL1_ACTION_ENA |
+			  PACKET3_TC_ACTION_ENA |
+			  PACKET3_SH_KCACHE_ACTION_ENA |
+			  PACKET3_SH_ICACHE_ACTION_ENA);  /* CP_COHER_CNTL */
+	amdgpu_ring_write(ring, 0xffffffff);  /* CP_COHER_SIZE */
+	amdgpu_ring_write(ring, 0);  /* CP_COHER_BASE */
+	amdgpu_ring_write(ring, 0x0000000A); /* poll interval */
+}
+
 static const struct amd_ip_funcs gfx_v7_0_ip_funcs = {
 	.name = "gfx_v7_0",
 	.early_init = gfx_v7_0_early_init,
@@ -5033,7 +5042,8 @@ static const struct amdgpu_ring_funcs gfx_v7_0_ring_funcs_gfx = {
 		12 + 12 + 12 + /* gfx_v7_0_ring_emit_fence_gfx x3 for user fence, vm fence */
 		7 + 4 + /* gfx_v7_0_ring_emit_pipeline_sync */
 		CIK_FLUSH_GPU_TLB_NUM_WREG * 5 + 7 + 6 + /* gfx_v7_0_ring_emit_vm_flush */
-		3 + 4, /* gfx_v7_ring_emit_cntxcntl including vgt flush*/
+		3 + 4 + /* gfx_v7_ring_emit_cntxcntl including vgt flush*/
+		5, /* SURFACE_SYNC */
 	.emit_ib_size = 4, /* gfx_v7_0_ring_emit_ib_gfx */
 	.emit_ib = gfx_v7_0_ring_emit_ib_gfx,
 	.emit_fence = gfx_v7_0_ring_emit_fence_gfx,
@@ -5048,6 +5058,7 @@ static const struct amdgpu_ring_funcs gfx_v7_0_ring_funcs_gfx = {
 	.emit_cntxcntl = gfx_v7_ring_emit_cntxcntl,
 	.emit_wreg = gfx_v7_0_ring_emit_wreg,
 	.soft_recovery = gfx_v7_0_ring_soft_recovery,
+	.emit_mem_sync = gfx_v7_0_emit_mem_sync,
 };
 
 static const struct amdgpu_ring_funcs gfx_v7_0_ring_funcs_compute = {
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
index fc32586ef80b..fc6c2f2bc76c 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
@@ -888,7 +888,8 @@ static int gfx_v8_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
 	gpu_addr = adev->wb.gpu_addr + (index * 4);
 	adev->wb.wb[index] = cpu_to_le32(0xCAFEDEAD);
 	memset(&ib, 0, sizeof(ib));
-	r = amdgpu_ib_get(adev, NULL, 16, &ib);
+	r = amdgpu_ib_get(adev, NULL, 16,
+					AMDGPU_IB_POOL_DIRECT, &ib);
 	if (r)
 		goto err1;
 
@@ -1550,7 +1551,8 @@ static int gfx_v8_0_do_edc_gpr_workarounds(struct amdgpu_device *adev)
 
 	/* allocate an indirect buffer to put the commands in */
 	memset(&ib, 0, sizeof(ib));
-	r = amdgpu_ib_get(adev, NULL, total_size, &ib);
+	r = amdgpu_ib_get(adev, NULL, total_size,
+					AMDGPU_IB_POOL_DIRECT, &ib);
 	if (r) {
 		DRM_ERROR("amdgpu: failed to get ib (%d).\n", r);
 		return r;
@@ -1892,6 +1894,7 @@ static int gfx_v8_0_compute_ring_init(struct amdgpu_device *adev, int ring_id,
 	int r;
 	unsigned irq_type;
 	struct amdgpu_ring *ring = &adev->gfx.compute_ring[ring_id];
+	unsigned int hw_prio;
 
 	ring = &adev->gfx.compute_ring[ring_id];
 
@@ -1911,9 +1914,11 @@ static int gfx_v8_0_compute_ring_init(struct amdgpu_device *adev, int ring_id,
 		+ ((ring->me - 1) * adev->gfx.mec.num_pipe_per_mec)
 		+ ring->pipe;
 
+	hw_prio = amdgpu_gfx_is_high_priority_compute_queue(adev, ring->queue) ?
+			AMDGPU_GFX_PIPE_PRIO_HIGH : AMDGPU_RING_PRIO_DEFAULT;
 	/* type-2 packets are deprecated on MEC, use type-3 instead */
 	r = amdgpu_ring_init(adev, ring, 1024,
-			&adev->gfx.eop_irq, irq_type);
+			     &adev->gfx.eop_irq, irq_type, hw_prio);
 	if (r)
 		return r;
 
@@ -2017,7 +2022,8 @@ static int gfx_v8_0_sw_init(void *handle)
 		}
 
 		r = amdgpu_ring_init(adev, ring, 1024, &adev->gfx.eop_irq,
-				     AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP);
+				     AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP,
+				     AMDGPU_RING_PRIO_DEFAULT);
 		if (r)
 			return r;
 	}
@@ -4120,7 +4126,6 @@ static int gfx_v8_0_rlc_resume(struct amdgpu_device *adev)
 
 static void gfx_v8_0_cp_gfx_enable(struct amdgpu_device *adev, bool enable)
 {
-	int i;
 	u32 tmp = RREG32(mmCP_ME_CNTL);
 
 	if (enable) {
@@ -4131,8 +4136,6 @@ static void gfx_v8_0_cp_gfx_enable(struct amdgpu_device *adev, bool enable)
 		tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, ME_HALT, 1);
 		tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, PFP_HALT, 1);
 		tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, CE_HALT, 1);
-		for (i = 0; i < adev->gfx.num_gfx_rings; i++)
-			adev->gfx.gfx_ring[i].sched.ready = false;
 	}
 	WREG32(mmCP_ME_CNTL, tmp);
 	udelay(50);
@@ -4320,14 +4323,10 @@ static int gfx_v8_0_cp_gfx_resume(struct amdgpu_device *adev)
 
 static void gfx_v8_0_cp_compute_enable(struct amdgpu_device *adev, bool enable)
 {
-	int i;
-
 	if (enable) {
 		WREG32(mmCP_MEC_CNTL, 0);
 	} else {
 		WREG32(mmCP_MEC_CNTL, (CP_MEC_CNTL__MEC_ME1_HALT_MASK | CP_MEC_CNTL__MEC_ME2_HALT_MASK));
-		for (i = 0; i < adev->gfx.num_compute_rings; i++)
-			adev->gfx.compute_ring[i].sched.ready = false;
 		adev->gfx.kiq.ring.sched.ready = false;
 	}
 	udelay(50);
@@ -4437,11 +4436,8 @@ static void gfx_v8_0_mqd_set_priority(struct amdgpu_ring *ring, struct vi_mqd *m
 	if (ring->funcs->type == AMDGPU_RING_TYPE_COMPUTE) {
 		if (amdgpu_gfx_is_high_priority_compute_queue(adev, ring->queue)) {
 			mqd->cp_hqd_pipe_priority = AMDGPU_GFX_PIPE_PRIO_HIGH;
-			ring->has_high_prio = true;
 			mqd->cp_hqd_queue_priority =
 				AMDGPU_GFX_QUEUE_PRIORITY_MAXIMUM;
-		} else {
-			ring->has_high_prio = false;
 		}
 	}
 }
@@ -6815,6 +6811,19 @@ static int gfx_v8_0_sq_irq(struct amdgpu_device *adev,
 	return 0;
 }
 
+static void gfx_v8_0_emit_mem_sync(struct amdgpu_ring *ring)
+{
+	amdgpu_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3));
+	amdgpu_ring_write(ring, PACKET3_TCL1_ACTION_ENA |
+			  PACKET3_TC_ACTION_ENA |
+			  PACKET3_SH_KCACHE_ACTION_ENA |
+			  PACKET3_SH_ICACHE_ACTION_ENA |
+			  PACKET3_TC_WB_ACTION_ENA);  /* CP_COHER_CNTL */
+	amdgpu_ring_write(ring, 0xffffffff);  /* CP_COHER_SIZE */
+	amdgpu_ring_write(ring, 0);  /* CP_COHER_BASE */
+	amdgpu_ring_write(ring, 0x0000000A); /* poll interval */
+}
+
 static const struct amd_ip_funcs gfx_v8_0_ip_funcs = {
 	.name = "gfx_v8_0",
 	.early_init = gfx_v8_0_early_init,
@@ -6861,7 +6870,8 @@ static const struct amdgpu_ring_funcs gfx_v8_0_ring_funcs_gfx = {
 		3 + /* CNTX_CTRL */
 		5 + /* HDP_INVL */
 		12 + 12 + /* FENCE x2 */
-		2, /* SWITCH_BUFFER */
+		2 + /* SWITCH_BUFFER */
+		5, /* SURFACE_SYNC */
 	.emit_ib_size =	4, /* gfx_v8_0_ring_emit_ib_gfx */
 	.emit_ib = gfx_v8_0_ring_emit_ib_gfx,
 	.emit_fence = gfx_v8_0_ring_emit_fence_gfx,
@@ -6879,6 +6889,7 @@ static const struct amdgpu_ring_funcs gfx_v8_0_ring_funcs_gfx = {
 	.patch_cond_exec = gfx_v8_0_ring_emit_patch_cond_exec,
 	.emit_wreg = gfx_v8_0_ring_emit_wreg,
 	.soft_recovery = gfx_v8_0_ring_soft_recovery,
+	.emit_mem_sync = gfx_v8_0_emit_mem_sync,
 };
 
 static const struct amdgpu_ring_funcs gfx_v8_0_ring_funcs_compute = {
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
index e6b113ed2f40..54eded9a6ac5 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
@@ -50,18 +50,14 @@
 
 #include "gfx_v9_4.h"
 
+#include "asic_reg/pwr/pwr_10_0_offset.h"
+#include "asic_reg/pwr/pwr_10_0_sh_mask.h"
+
 #define GFX9_NUM_GFX_RINGS     1
 #define GFX9_MEC_HPD_SIZE 4096
 #define RLCG_UCODE_LOADING_START_ADDRESS 0x00002000L
 #define RLC_SAVE_RESTORE_ADDR_STARTING_OFFSET 0x00000000L
 
-#define mmPWR_MISC_CNTL_STATUS					0x0183
-#define mmPWR_MISC_CNTL_STATUS_BASE_IDX				0
-#define PWR_MISC_CNTL_STATUS__PWR_GFX_RLC_CGPG_EN__SHIFT	0x0
-#define PWR_MISC_CNTL_STATUS__PWR_GFXOFF_STATUS__SHIFT		0x1
-#define PWR_MISC_CNTL_STATUS__PWR_GFX_RLC_CGPG_EN_MASK		0x00000001L
-#define PWR_MISC_CNTL_STATUS__PWR_GFXOFF_STATUS_MASK		0x00000006L
-
 #define mmGCEA_PROBE_MAP                        0x070c
 #define mmGCEA_PROBE_MAP_BASE_IDX               0
 
@@ -1082,7 +1078,8 @@ static int gfx_v9_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
 	gpu_addr = adev->wb.gpu_addr + (index * 4);
 	adev->wb.wb[index] = cpu_to_le32(0xCAFEDEAD);
 	memset(&ib, 0, sizeof(ib));
-	r = amdgpu_ib_get(adev, NULL, 16, &ib);
+	r = amdgpu_ib_get(adev, NULL, 16,
+					AMDGPU_IB_POOL_DIRECT, &ib);
 	if (r)
 		goto err1;
 
@@ -1234,6 +1231,8 @@ struct amdgpu_gfxoff_quirk {
 static const struct amdgpu_gfxoff_quirk amdgpu_gfxoff_quirk_list[] = {
 	/* https://bugzilla.kernel.org/show_bug.cgi?id=204689 */
 	{ 0x1002, 0x15dd, 0x1002, 0x15dd, 0xc8 },
+	/* https://bugzilla.kernel.org/show_bug.cgi?id=207171 */
+	{ 0x1002, 0x15dd, 0x103c, 0x83e7, 0xd3 },
 	{ 0, 0, 0, 0, 0 },
 };
 
@@ -2195,6 +2194,7 @@ static int gfx_v9_0_compute_ring_init(struct amdgpu_device *adev, int ring_id,
 	int r;
 	unsigned irq_type;
 	struct amdgpu_ring *ring = &adev->gfx.compute_ring[ring_id];
+	unsigned int hw_prio;
 
 	ring = &adev->gfx.compute_ring[ring_id];
 
@@ -2213,10 +2213,11 @@ static int gfx_v9_0_compute_ring_init(struct amdgpu_device *adev, int ring_id,
 	irq_type = AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP
 		+ ((ring->me - 1) * adev->gfx.mec.num_pipe_per_mec)
 		+ ring->pipe;
-
+	hw_prio = amdgpu_gfx_is_high_priority_compute_queue(adev, ring->queue) ?
+			AMDGPU_GFX_PIPE_PRIO_HIGH : AMDGPU_GFX_PIPE_PRIO_NORMAL;
 	/* type-2 packets are deprecated on MEC, use type-3 instead */
 	r = amdgpu_ring_init(adev, ring, 1024,
-			     &adev->gfx.eop_irq, irq_type);
+			     &adev->gfx.eop_irq, irq_type, hw_prio);
 	if (r)
 		return r;
 
@@ -2310,7 +2311,9 @@ static int gfx_v9_0_sw_init(void *handle)
 		ring->use_doorbell = true;
 		ring->doorbell_index = adev->doorbell_index.gfx_ring0 << 1;
 		r = amdgpu_ring_init(adev, ring, 1024,
-				     &adev->gfx.eop_irq, AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP);
+				     &adev->gfx.eop_irq,
+				     AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP,
+				     AMDGPU_RING_PRIO_DEFAULT);
 		if (r)
 			return r;
 	}
@@ -3100,16 +3103,11 @@ static int gfx_v9_0_rlc_resume(struct amdgpu_device *adev)
 
 static void gfx_v9_0_cp_gfx_enable(struct amdgpu_device *adev, bool enable)
 {
-	int i;
 	u32 tmp = RREG32_SOC15(GC, 0, mmCP_ME_CNTL);
 
 	tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, ME_HALT, enable ? 0 : 1);
 	tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, PFP_HALT, enable ? 0 : 1);
 	tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, CE_HALT, enable ? 0 : 1);
-	if (!enable) {
-		for (i = 0; i < adev->gfx.num_gfx_rings; i++)
-			adev->gfx.gfx_ring[i].sched.ready = false;
-	}
 	WREG32_SOC15_RLC(GC, 0, mmCP_ME_CNTL, tmp);
 	udelay(50);
 }
@@ -3305,15 +3303,11 @@ static int gfx_v9_0_cp_gfx_resume(struct amdgpu_device *adev)
 
 static void gfx_v9_0_cp_compute_enable(struct amdgpu_device *adev, bool enable)
 {
-	int i;
-
 	if (enable) {
 		WREG32_SOC15_RLC(GC, 0, mmCP_MEC_CNTL, 0);
 	} else {
 		WREG32_SOC15_RLC(GC, 0, mmCP_MEC_CNTL,
 			(CP_MEC_CNTL__MEC_ME1_HALT_MASK | CP_MEC_CNTL__MEC_ME2_HALT_MASK));
-		for (i = 0; i < adev->gfx.num_compute_rings; i++)
-			adev->gfx.compute_ring[i].sched.ready = false;
 		adev->gfx.kiq.ring.sched.ready = false;
 	}
 	udelay(50);
@@ -3383,11 +3377,8 @@ static void gfx_v9_0_mqd_set_priority(struct amdgpu_ring *ring, struct v9_mqd *m
 	if (ring->funcs->type == AMDGPU_RING_TYPE_COMPUTE) {
 		if (amdgpu_gfx_is_high_priority_compute_queue(adev, ring->queue)) {
 			mqd->cp_hqd_pipe_priority = AMDGPU_GFX_PIPE_PRIO_HIGH;
-			ring->has_high_prio = true;
 			mqd->cp_hqd_queue_priority =
 				AMDGPU_GFX_QUEUE_PRIORITY_MAXIMUM;
-		} else {
-			ring->has_high_prio = false;
 		}
 	}
 }
@@ -4487,7 +4478,8 @@ static int gfx_v9_0_do_edc_gpr_workarounds(struct amdgpu_device *adev)
 
 	/* allocate an indirect buffer to put the commands in */
 	memset(&ib, 0, sizeof(ib));
-	r = amdgpu_ib_get(adev, NULL, total_size, &ib);
+	r = amdgpu_ib_get(adev, NULL, total_size,
+					AMDGPU_IB_POOL_DIRECT, &ib);
 	if (r) {
 		DRM_ERROR("amdgpu: failed to get ib (%d).\n", r);
 		return r;
@@ -5426,10 +5418,13 @@ static void gfx_v9_0_ring_emit_de_meta(struct amdgpu_ring *ring)
 	amdgpu_ring_write_multiple(ring, (void *)&de_payload, sizeof(de_payload) >> 2);
 }
 
-static void gfx_v9_0_ring_emit_tmz(struct amdgpu_ring *ring, bool start)
+static void gfx_v9_0_ring_emit_frame_cntl(struct amdgpu_ring *ring, bool start,
+				   bool secure)
 {
+	uint32_t v = secure ? FRAME_TMZ : 0;
+
 	amdgpu_ring_write(ring, PACKET3(PACKET3_FRAME_CONTROL, 0));
-	amdgpu_ring_write(ring, FRAME_CMD(start ? 0 : 1)); /* frame_end */
+	amdgpu_ring_write(ring, v | FRAME_CMD(start ? 0 : 1));
 }
 
 static void gfx_v9_ring_emit_cntxcntl(struct amdgpu_ring *ring, uint32_t flags)
@@ -5439,8 +5434,6 @@ static void gfx_v9_ring_emit_cntxcntl(struct amdgpu_ring *ring, uint32_t flags)
 	if (amdgpu_sriov_vf(ring->adev))
 		gfx_v9_0_ring_emit_ce_meta(ring);
 
-	gfx_v9_0_ring_emit_tmz(ring, true);
-
 	dw2 |= 0x80000000; /* set load_enable otherwise this package is just NOPs */
 	if (flags & AMDGPU_HAVE_CTX_SWITCH) {
 		/* set load_global_config & load_global_uconfig */
@@ -6406,15 +6399,15 @@ static int gfx_v9_0_query_utc_edc_status(struct amdgpu_device *adev,
 
 		sec_count = REG_GET_FIELD(data, VM_L2_MEM_ECC_CNT, SEC_COUNT);
 		if (sec_count) {
-			DRM_INFO("Instance[%d]: SubBlock %s, SEC %d\n", i,
-				 vml2_mems[i], sec_count);
+			dev_info(adev->dev, "Instance[%d]: SubBlock %s, "
+				"SEC %d\n", i, vml2_mems[i], sec_count);
 			err_data->ce_count += sec_count;
 		}
 
 		ded_count = REG_GET_FIELD(data, VM_L2_MEM_ECC_CNT, DED_COUNT);
 		if (ded_count) {
-			DRM_INFO("Instance[%d]: SubBlock %s, DED %d\n", i,
-				 vml2_mems[i], ded_count);
+			dev_info(adev->dev, "Instance[%d]: SubBlock %s, "
+				"DED %d\n", i, vml2_mems[i], ded_count);
 			err_data->ue_count += ded_count;
 		}
 	}
@@ -6426,16 +6419,16 @@ static int gfx_v9_0_query_utc_edc_status(struct amdgpu_device *adev,
 		sec_count = REG_GET_FIELD(data, VM_L2_WALKER_MEM_ECC_CNT,
 						SEC_COUNT);
 		if (sec_count) {
-			DRM_INFO("Instance[%d]: SubBlock %s, SEC %d\n", i,
-				 vml2_walker_mems[i], sec_count);
+			dev_info(adev->dev, "Instance[%d]: SubBlock %s, "
+				"SEC %d\n", i, vml2_walker_mems[i], sec_count);
 			err_data->ce_count += sec_count;
 		}
 
 		ded_count = REG_GET_FIELD(data, VM_L2_WALKER_MEM_ECC_CNT,
 						DED_COUNT);
 		if (ded_count) {
-			DRM_INFO("Instance[%d]: SubBlock %s, DED %d\n", i,
-				 vml2_walker_mems[i], ded_count);
+			dev_info(adev->dev, "Instance[%d]: SubBlock %s, "
+				"DED %d\n", i, vml2_walker_mems[i], ded_count);
 			err_data->ue_count += ded_count;
 		}
 	}
@@ -6446,8 +6439,9 @@ static int gfx_v9_0_query_utc_edc_status(struct amdgpu_device *adev,
 
 		sec_count = (data & 0x00006000L) >> 0xd;
 		if (sec_count) {
-			DRM_INFO("Instance[%d]: SubBlock %s, SEC %d\n", i,
-				 atc_l2_cache_2m_mems[i], sec_count);
+			dev_info(adev->dev, "Instance[%d]: SubBlock %s, "
+				"SEC %d\n", i, atc_l2_cache_2m_mems[i],
+				sec_count);
 			err_data->ce_count += sec_count;
 		}
 	}
@@ -6458,15 +6452,17 @@ static int gfx_v9_0_query_utc_edc_status(struct amdgpu_device *adev,
 
 		sec_count = (data & 0x00006000L) >> 0xd;
 		if (sec_count) {
-			DRM_INFO("Instance[%d]: SubBlock %s, SEC %d\n", i,
-				 atc_l2_cache_4k_mems[i], sec_count);
+			dev_info(adev->dev, "Instance[%d]: SubBlock %s, "
+				"SEC %d\n", i, atc_l2_cache_4k_mems[i],
+				sec_count);
 			err_data->ce_count += sec_count;
 		}
 
 		ded_count = (data & 0x00018000L) >> 0xf;
 		if (ded_count) {
-			DRM_INFO("Instance[%d]: SubBlock %s, DED %d\n", i,
-				 atc_l2_cache_4k_mems[i], ded_count);
+			dev_info(adev->dev, "Instance[%d]: SubBlock %s, "
+				"DED %d\n", i, atc_l2_cache_4k_mems[i],
+				ded_count);
 			err_data->ue_count += ded_count;
 		}
 	}
@@ -6479,7 +6475,8 @@ static int gfx_v9_0_query_utc_edc_status(struct amdgpu_device *adev,
 	return 0;
 }
 
-static int gfx_v9_0_ras_error_count(const struct soc15_reg_entry *reg,
+static int gfx_v9_0_ras_error_count(struct amdgpu_device *adev,
+	const struct soc15_reg_entry *reg,
 	uint32_t se_id, uint32_t inst_id, uint32_t value,
 	uint32_t *sec_count, uint32_t *ded_count)
 {
@@ -6496,7 +6493,8 @@ static int gfx_v9_0_ras_error_count(const struct soc15_reg_entry *reg,
 				gfx_v9_0_ras_fields[i].sec_count_mask) >>
 				gfx_v9_0_ras_fields[i].sec_count_shift;
 		if (sec_cnt) {
-			DRM_INFO("GFX SubBlock %s, Instance[%d][%d], SEC %d\n",
+			dev_info(adev->dev, "GFX SubBlock %s, "
+				"Instance[%d][%d], SEC %d\n",
 				gfx_v9_0_ras_fields[i].name,
 				se_id, inst_id,
 				sec_cnt);
@@ -6507,7 +6505,8 @@ static int gfx_v9_0_ras_error_count(const struct soc15_reg_entry *reg,
 				gfx_v9_0_ras_fields[i].ded_count_mask) >>
 				gfx_v9_0_ras_fields[i].ded_count_shift;
 		if (ded_cnt) {
-			DRM_INFO("GFX SubBlock %s, Instance[%d][%d], DED %d\n",
+			dev_info(adev->dev, "GFX SubBlock %s, "
+				"Instance[%d][%d], DED %d\n",
 				gfx_v9_0_ras_fields[i].name,
 				se_id, inst_id,
 				ded_cnt);
@@ -6596,9 +6595,10 @@ static int gfx_v9_0_query_ras_error_count(struct amdgpu_device *adev,
 				reg_value =
 					RREG32(SOC15_REG_ENTRY_OFFSET(gfx_v9_0_edc_counter_regs[i]));
 				if (reg_value)
-					gfx_v9_0_ras_error_count(&gfx_v9_0_edc_counter_regs[i],
-							j, k, reg_value,
-							&sec_count, &ded_count);
+					gfx_v9_0_ras_error_count(adev,
+						&gfx_v9_0_edc_counter_regs[i],
+						j, k, reg_value,
+						&sec_count, &ded_count);
 			}
 		}
 	}
@@ -6614,6 +6614,25 @@ static int gfx_v9_0_query_ras_error_count(struct amdgpu_device *adev,
 	return 0;
 }
 
+static void gfx_v9_0_emit_mem_sync(struct amdgpu_ring *ring)
+{
+	const unsigned int cp_coher_cntl =
+			PACKET3_ACQUIRE_MEM_CP_COHER_CNTL_SH_ICACHE_ACTION_ENA(1) |
+			PACKET3_ACQUIRE_MEM_CP_COHER_CNTL_SH_KCACHE_ACTION_ENA(1) |
+			PACKET3_ACQUIRE_MEM_CP_COHER_CNTL_TC_ACTION_ENA(1) |
+			PACKET3_ACQUIRE_MEM_CP_COHER_CNTL_TCL1_ACTION_ENA(1) |
+			PACKET3_ACQUIRE_MEM_CP_COHER_CNTL_TC_WB_ACTION_ENA(1);
+
+	/* ACQUIRE_MEM -make one or more surfaces valid for use by the subsequent operations */
+	amdgpu_ring_write(ring, PACKET3(PACKET3_ACQUIRE_MEM, 5));
+	amdgpu_ring_write(ring, cp_coher_cntl); /* CP_COHER_CNTL */
+	amdgpu_ring_write(ring, 0xffffffff);  /* CP_COHER_SIZE */
+	amdgpu_ring_write(ring, 0xffffff);  /* CP_COHER_SIZE_HI */
+	amdgpu_ring_write(ring, 0); /* CP_COHER_BASE */
+	amdgpu_ring_write(ring, 0);  /* CP_COHER_BASE_HI */
+	amdgpu_ring_write(ring, 0x0000000A); /* POLL_INTERVAL */
+}
+
 static const struct amd_ip_funcs gfx_v9_0_ip_funcs = {
 	.name = "gfx_v9_0",
 	.early_init = gfx_v9_0_early_init,
@@ -6660,7 +6679,8 @@ static const struct amdgpu_ring_funcs gfx_v9_0_ring_funcs_gfx = {
 		3 + /* CNTX_CTRL */
 		5 + /* HDP_INVL */
 		8 + 8 + /* FENCE x2 */
-		2, /* SWITCH_BUFFER */
+		2 + /* SWITCH_BUFFER */
+		7, /* gfx_v9_0_emit_mem_sync */
 	.emit_ib_size =	4, /* gfx_v9_0_ring_emit_ib_gfx */
 	.emit_ib = gfx_v9_0_ring_emit_ib_gfx,
 	.emit_fence = gfx_v9_0_ring_emit_fence,
@@ -6676,11 +6696,12 @@ static const struct amdgpu_ring_funcs gfx_v9_0_ring_funcs_gfx = {
 	.emit_cntxcntl = gfx_v9_ring_emit_cntxcntl,
 	.init_cond_exec = gfx_v9_0_ring_emit_init_cond_exec,
 	.patch_cond_exec = gfx_v9_0_ring_emit_patch_cond_exec,
-	.emit_tmz = gfx_v9_0_ring_emit_tmz,
+	.emit_frame_cntl = gfx_v9_0_ring_emit_frame_cntl,
 	.emit_wreg = gfx_v9_0_ring_emit_wreg,
 	.emit_reg_wait = gfx_v9_0_ring_emit_reg_wait,
 	.emit_reg_write_reg_wait = gfx_v9_0_ring_emit_reg_write_reg_wait,
 	.soft_recovery = gfx_v9_0_ring_soft_recovery,
+	.emit_mem_sync = gfx_v9_0_emit_mem_sync,
 };
 
 static const struct amdgpu_ring_funcs gfx_v9_0_ring_funcs_compute = {
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
index 9775eca6fe43..30b75d79efdb 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
@@ -170,6 +170,9 @@ static int gmc_v10_0_process_interrupt(struct amdgpu_device *adev,
 			dev_err(adev->dev,
 				"GCVM_L2_PROTECTION_FAULT_STATUS:0x%08X\n",
 				status);
+			dev_err(adev->dev, "\t Faulty UTCL2 client ID: 0x%lx\n",
+				REG_GET_FIELD(status,
+				GCVM_L2_PROTECTION_FAULT_STATUS, CID));
 			dev_err(adev->dev, "\t MORE_FAULTS: 0x%lx\n",
 				REG_GET_FIELD(status,
 				GCVM_L2_PROTECTION_FAULT_STATUS, MORE_FAULTS));
@@ -369,7 +372,8 @@ static void gmc_v10_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
 	 * translation. Avoid this by doing the invalidation from the SDMA
 	 * itself.
 	 */
-	r = amdgpu_job_alloc_with_ib(adev, 16 * 4, &job);
+	r = amdgpu_job_alloc_with_ib(adev, 16 * 4, AMDGPU_IB_POOL_IMMEDIATE,
+				     &job);
 	if (r)
 		goto error_alloc;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
index b205039350b6..c1a530dbe162 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
@@ -858,7 +858,7 @@ static int gmc_v6_0_sw_init(void *handle)
 
 	r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(44));
 	if (r) {
-		dev_warn(adev->dev, "amdgpu: No suitable DMA available.\n");
+		dev_warn(adev->dev, "No suitable DMA available.\n");
 		return r;
 	}
 	adev->need_swiotlb = drm_need_swiotlb(44);
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
index 9da9596a3638..e8529e244a2b 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
@@ -1019,7 +1019,7 @@ static int gmc_v7_0_sw_init(void *handle)
 
 	r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(40));
 	if (r) {
-		pr_warn("amdgpu: No suitable DMA available\n");
+		pr_warn("No suitable DMA available\n");
 		return r;
 	}
 	adev->need_swiotlb = drm_need_swiotlb(40);
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
index 27d83204fa2b..0aa5b82808d1 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
@@ -1144,7 +1144,7 @@ static int gmc_v8_0_sw_init(void *handle)
 
 	r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(40));
 	if (r) {
-		pr_warn("amdgpu: No suitable DMA available\n");
+		pr_warn("No suitable DMA available\n");
 		return r;
 	}
 	adev->need_swiotlb = drm_need_swiotlb(40);
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
index 8606f877478f..fecdbc471983 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
@@ -362,6 +362,9 @@ static int gmc_v9_0_process_interrupt(struct amdgpu_device *adev,
 			dev_err(adev->dev,
 				"VM_L2_PROTECTION_FAULT_STATUS:0x%08X\n",
 				status);
+			dev_err(adev->dev, "\t Faulty UTCL2 client ID: 0x%lx\n",
+				REG_GET_FIELD(status,
+				VM_L2_PROTECTION_FAULT_STATUS, CID));
 			dev_err(adev->dev, "\t MORE_FAULTS: 0x%lx\n",
 				REG_GET_FIELD(status,
 				VM_L2_PROTECTION_FAULT_STATUS, MORE_FAULTS));
diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.c
index 0debfd9f428c..b10c95cad9a2 100644
--- a/drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.c
@@ -480,7 +480,8 @@ int jpeg_v1_0_sw_init(void *handle)
 
 	ring = &adev->jpeg.inst->ring_dec;
 	sprintf(ring->name, "jpeg_dec");
-	r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst->irq, 0);
+	r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst->irq,
+			     0, AMDGPU_RING_PRIO_DEFAULT);
 	if (r)
 		return r;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c
index 6173951db7b4..e67d09cb1b03 100644
--- a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c
@@ -106,7 +106,8 @@ static int jpeg_v2_0_sw_init(void *handle)
 	ring->use_doorbell = true;
 	ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 1;
 	sprintf(ring->name, "jpeg_dec");
-	r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst->irq, 0);
+	r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst->irq,
+			     0, AMDGPU_RING_PRIO_DEFAULT);
 	if (r)
 		return r;
 
@@ -169,14 +170,11 @@ static int jpeg_v2_0_hw_init(void *handle)
 static int jpeg_v2_0_hw_fini(void *handle)
 {
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
-	struct amdgpu_ring *ring = &adev->jpeg.inst->ring_dec;
 
 	if (adev->jpeg.cur_state != AMD_PG_STATE_GATE &&
 	      RREG32_SOC15(JPEG, 0, mmUVD_JRBC_STATUS))
 		jpeg_v2_0_set_powergating_state(adev, AMD_PG_STATE_GATE);
 
-	ring->sched.ready = false;
-
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c
index c04c2078a7c1..37df3f2e587a 100644
--- a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c
+++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c
@@ -118,7 +118,8 @@ static int jpeg_v2_5_sw_init(void *handle)
 		ring->use_doorbell = true;
 		ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 1 + 8 * i;
 		sprintf(ring->name, "jpeg_dec_%d", i);
-		r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst[i].irq, 0);
+		r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst[i].irq,
+				     0, AMDGPU_RING_PRIO_DEFAULT);
 		if (r)
 			return r;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h
index 37dbe0f2142f..52a697545801 100644
--- a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h
+++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h
@@ -46,7 +46,8 @@ enum idh_event {
 	IDH_SUCCESS,
 	IDH_FAIL,
 	IDH_QUERY_ALIVE,
-	IDH_EVENT_MAX
+
+	IDH_TEXT_MESSAGE = 255,
 };
 
 extern const struct amdgpu_virt_ops xgpu_ai_virt_ops;
diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c b/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c
index 237fa5e16b7c..ce2bf1fb79ed 100644
--- a/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c
+++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c
@@ -30,7 +30,6 @@
 #include "navi10_ih.h"
 #include "soc15_common.h"
 #include "mxgpu_nv.h"
-#include "mxgpu_ai.h"
 
 static void xgpu_nv_mailbox_send_ack(struct amdgpu_device *adev)
 {
@@ -53,8 +52,7 @@ static void xgpu_nv_mailbox_set_valid(struct amdgpu_device *adev, bool val)
  */
 static enum idh_event xgpu_nv_mailbox_peek_msg(struct amdgpu_device *adev)
 {
-	return RREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0,
-				mmBIF_BX_PF_MAILBOX_MSGBUF_RCV_DW0));
+	return RREG32_NO_KIQ(mmMAILBOX_MSGBUF_RCV_DW0);
 }
 
 
@@ -63,8 +61,7 @@ static int xgpu_nv_mailbox_rcv_msg(struct amdgpu_device *adev,
 {
 	u32 reg;
 
-	reg = RREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0,
-					     mmBIF_BX_PF_MAILBOX_MSGBUF_RCV_DW0));
+	reg = RREG32_NO_KIQ(mmMAILBOX_MSGBUF_RCV_DW0);
 	if (reg != event)
 		return -ENOENT;
 
@@ -110,7 +107,6 @@ static int xgpu_nv_poll_msg(struct amdgpu_device *adev, enum idh_event event)
 		timeout -= 10;
 	} while (timeout > 1);
 
-	pr_err("Doesn't get msg:%d from pf, error=%d\n", event, r);
 
 	return -ETIME;
 }
@@ -118,7 +114,6 @@ static int xgpu_nv_poll_msg(struct amdgpu_device *adev, enum idh_event event)
 static void xgpu_nv_mailbox_trans_msg (struct amdgpu_device *adev,
 	      enum idh_request req, u32 data1, u32 data2, u32 data3)
 {
-	u32 reg;
 	int r;
 	uint8_t trn;
 
@@ -137,19 +132,10 @@ static void xgpu_nv_mailbox_trans_msg (struct amdgpu_device *adev,
 		}
 	} while (trn);
 
-	reg = RREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0,
-					     mmBIF_BX_PF_MAILBOX_MSGBUF_TRN_DW0));
-	reg = REG_SET_FIELD(reg, BIF_BX_PF_MAILBOX_MSGBUF_TRN_DW0,
-			    MSGBUF_DATA, req);
-	WREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF_MAILBOX_MSGBUF_TRN_DW0),
-		      reg);
-	WREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF_MAILBOX_MSGBUF_TRN_DW1),
-				data1);
-	WREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF_MAILBOX_MSGBUF_TRN_DW2),
-				data2);
-	WREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF_MAILBOX_MSGBUF_TRN_DW3),
-				data3);
-
+	WREG32_NO_KIQ(mmMAILBOX_MSGBUF_TRN_DW0, req);
+	WREG32_NO_KIQ(mmMAILBOX_MSGBUF_TRN_DW1, data1);
+	WREG32_NO_KIQ(mmMAILBOX_MSGBUF_TRN_DW2, data2);
+	WREG32_NO_KIQ(mmMAILBOX_MSGBUF_TRN_DW3, data3);
 	xgpu_nv_mailbox_set_valid(adev, true);
 
 	/* start to poll ack */
@@ -164,23 +150,48 @@ static int xgpu_nv_send_access_requests(struct amdgpu_device *adev,
 					enum idh_request req)
 {
 	int r;
+	enum idh_event event = -1;
 
 	xgpu_nv_mailbox_trans_msg(adev, req, 0, 0, 0);
 
-	/* start to check msg if request is idh_req_gpu_init_access */
-	if (req == IDH_REQ_GPU_INIT_ACCESS ||
-		req == IDH_REQ_GPU_FINI_ACCESS ||
-		req == IDH_REQ_GPU_RESET_ACCESS) {
-		r = xgpu_nv_poll_msg(adev, IDH_READY_TO_ACCESS_GPU);
+	switch (req) {
+	case IDH_REQ_GPU_INIT_ACCESS:
+	case IDH_REQ_GPU_FINI_ACCESS:
+	case IDH_REQ_GPU_RESET_ACCESS:
+		event = IDH_READY_TO_ACCESS_GPU;
+		break;
+	case IDH_REQ_GPU_INIT_DATA:
+		event = IDH_REQ_GPU_INIT_DATA_READY;
+		break;
+	default:
+		break;
+	}
+
+	if (event != -1) {
+		r = xgpu_nv_poll_msg(adev, event);
 		if (r) {
-			pr_err("Doesn't get READY_TO_ACCESS_GPU from pf, give up\n");
-			return r;
+			if (req != IDH_REQ_GPU_INIT_DATA) {
+				pr_err("Doesn't get msg:%d from pf, error=%d\n", event, r);
+				return r;
+			}
+			else /* host doesn't support REQ_GPU_INIT_DATA handshake */
+				adev->virt.req_init_data_ver = 0;
+		} else {
+			if (req == IDH_REQ_GPU_INIT_DATA)
+			{
+				adev->virt.req_init_data_ver =
+					RREG32_NO_KIQ(mmMAILBOX_MSGBUF_RCV_DW1);
+
+				/* assume V1 in case host doesn't set version number */
+				if (adev->virt.req_init_data_ver < 1)
+					adev->virt.req_init_data_ver = 1;
+			}
 		}
+
 		/* Retrieve checksum from mailbox2 */
 		if (req == IDH_REQ_GPU_INIT_ACCESS || req == IDH_REQ_GPU_RESET_ACCESS) {
 			adev->virt.fw_reserve.checksum_key =
-				RREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0,
-					mmBIF_BX_PF_MAILBOX_MSGBUF_RCV_DW2));
+				RREG32_NO_KIQ(mmMAILBOX_MSGBUF_RCV_DW2);
 		}
 	}
 
@@ -213,6 +224,11 @@ static int xgpu_nv_release_full_gpu_access(struct amdgpu_device *adev,
 	return r;
 }
 
+static int xgpu_nv_request_init_data(struct amdgpu_device *adev)
+{
+	return xgpu_nv_send_access_requests(adev, IDH_REQ_GPU_INIT_DATA);
+}
+
 static int xgpu_nv_mailbox_ack_irq(struct amdgpu_device *adev,
 					struct amdgpu_irq_src *source,
 					struct amdgpu_iv_entry *entry)
@@ -226,11 +242,14 @@ static int xgpu_nv_set_mailbox_ack_irq(struct amdgpu_device *adev,
 					unsigned type,
 					enum amdgpu_interrupt_state state)
 {
-	u32 tmp = RREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF_MAILBOX_INT_CNTL));
+	u32 tmp = RREG32_NO_KIQ(mmMAILBOX_INT_CNTL);
+
+	if (state == AMDGPU_IRQ_STATE_ENABLE)
+		tmp |= 2;
+	else
+		tmp &= ~2;
 
-	tmp = REG_SET_FIELD(tmp, BIF_BX_PF_MAILBOX_INT_CNTL, ACK_INT_EN,
-				(state == AMDGPU_IRQ_STATE_ENABLE) ? 1 : 0);
-	WREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF_MAILBOX_INT_CNTL), tmp);
+	WREG32_NO_KIQ(mmMAILBOX_INT_CNTL, tmp);
 
 	return 0;
 }
@@ -282,11 +301,14 @@ static int xgpu_nv_set_mailbox_rcv_irq(struct amdgpu_device *adev,
 				       unsigned type,
 				       enum amdgpu_interrupt_state state)
 {
-	u32 tmp = RREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF_MAILBOX_INT_CNTL));
+	u32 tmp = RREG32_NO_KIQ(mmMAILBOX_INT_CNTL);
+
+	if (state == AMDGPU_IRQ_STATE_ENABLE)
+		tmp |= 1;
+	else
+		tmp &= ~1;
 
-	tmp = REG_SET_FIELD(tmp, BIF_BX_PF_MAILBOX_INT_CNTL, VALID_INT_EN,
-			    (state == AMDGPU_IRQ_STATE_ENABLE) ? 1 : 0);
-	WREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF_MAILBOX_INT_CNTL), tmp);
+	WREG32_NO_KIQ(mmMAILBOX_INT_CNTL, tmp);
 
 	return 0;
 }
@@ -378,6 +400,7 @@ void xgpu_nv_mailbox_put_irq(struct amdgpu_device *adev)
 const struct amdgpu_virt_ops xgpu_nv_virt_ops = {
 	.req_full_gpu	= xgpu_nv_request_full_gpu_access,
 	.rel_full_gpu	= xgpu_nv_release_full_gpu_access,
+	.req_init_data  = xgpu_nv_request_init_data,
 	.reset_gpu = xgpu_nv_request_reset,
 	.wait_reset = NULL,
 	.trans_msg = xgpu_nv_mailbox_trans_msg,
diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.h b/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.h
index 99b15f6865cb..45bcf438e607 100644
--- a/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.h
+++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.h
@@ -25,9 +25,33 @@
 #define __MXGPU_NV_H__
 
 #define NV_MAILBOX_POLL_ACK_TIMEDOUT	500
-#define NV_MAILBOX_POLL_MSG_TIMEDOUT	12000
+#define NV_MAILBOX_POLL_MSG_TIMEDOUT	6000
 #define NV_MAILBOX_POLL_FLR_TIMEDOUT	500
 
+enum idh_request {
+	IDH_REQ_GPU_INIT_ACCESS = 1,
+	IDH_REL_GPU_INIT_ACCESS,
+	IDH_REQ_GPU_FINI_ACCESS,
+	IDH_REL_GPU_FINI_ACCESS,
+	IDH_REQ_GPU_RESET_ACCESS,
+	IDH_REQ_GPU_INIT_DATA,
+
+	IDH_LOG_VF_ERROR       = 200,
+};
+
+enum idh_event {
+	IDH_CLR_MSG_BUF	= 0,
+	IDH_READY_TO_ACCESS_GPU,
+	IDH_FLR_NOTIFICATION,
+	IDH_FLR_NOTIFICATION_CMPL,
+	IDH_SUCCESS,
+	IDH_FAIL,
+	IDH_QUERY_ALIVE,
+	IDH_REQ_GPU_INIT_DATA_READY,
+
+	IDH_TEXT_MESSAGE = 255,
+};
+
 extern const struct amdgpu_virt_ops xgpu_nv_virt_ops;
 
 void xgpu_nv_mailbox_set_irq_funcs(struct amdgpu_device *adev);
@@ -35,7 +59,21 @@ int xgpu_nv_mailbox_add_irq_id(struct amdgpu_device *adev);
 int xgpu_nv_mailbox_get_irq(struct amdgpu_device *adev);
 void xgpu_nv_mailbox_put_irq(struct amdgpu_device *adev);
 
-#define NV_MAIBOX_CONTROL_TRN_OFFSET_BYTE (SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF_MAILBOX_CONTROL) * 4)
-#define NV_MAIBOX_CONTROL_RCV_OFFSET_BYTE (SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF_MAILBOX_CONTROL) * 4 + 1)
+#define mmMAILBOX_CONTROL 0xE5E
+
+#define NV_MAIBOX_CONTROL_TRN_OFFSET_BYTE (mmMAILBOX_CONTROL * 4)
+#define NV_MAIBOX_CONTROL_RCV_OFFSET_BYTE (NV_MAIBOX_CONTROL_TRN_OFFSET_BYTE + 1)
+
+#define mmMAILBOX_MSGBUF_TRN_DW0 0xE56
+#define mmMAILBOX_MSGBUF_TRN_DW1 0xE57
+#define mmMAILBOX_MSGBUF_TRN_DW2 0xE58
+#define mmMAILBOX_MSGBUF_TRN_DW3 0xE59
+
+#define mmMAILBOX_MSGBUF_RCV_DW0 0xE5A
+#define mmMAILBOX_MSGBUF_RCV_DW1 0xE5B
+#define mmMAILBOX_MSGBUF_RCV_DW2 0xE5C
+#define mmMAILBOX_MSGBUF_RCV_DW3 0xE5D
+
+#define mmMAILBOX_INT_CNTL 0xE5F
 
 #endif
diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.h b/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.h
index f13dc6cc158f..713ee66a4d3e 100644
--- a/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.h
+++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.h
@@ -43,7 +43,8 @@ enum idh_event {
 	IDH_READY_TO_ACCESS_GPU,
 	IDH_FLR_NOTIFICATION,
 	IDH_FLR_NOTIFICATION_CMPL,
-	IDH_EVENT_MAX
+
+	IDH_TEXT_MESSAGE = 255
 };
 
 extern const struct amdgpu_virt_ops xgpu_vi_virt_ops;
diff --git a/drivers/gpu/drm/amd/amdgpu/navi10_ih.c b/drivers/gpu/drm/amd/amdgpu/navi10_ih.c
index e08245a446fc..f97857ed3c7e 100644
--- a/drivers/gpu/drm/amd/amdgpu/navi10_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/navi10_ih.c
@@ -49,8 +49,48 @@ static void navi10_ih_enable_interrupts(struct amdgpu_device *adev)
 
 	ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RB_ENABLE, 1);
 	ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, ENABLE_INTR, 1);
-	WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl);
+	if (amdgpu_sriov_vf(adev) && adev->asic_type < CHIP_NAVI10) {
+		if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL, ih_rb_cntl)) {
+			DRM_ERROR("PSP program IH_RB_CNTL failed!\n");
+			return;
+		}
+	} else {
+		WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl);
+	}
+
 	adev->irq.ih.enabled = true;
+
+	if (adev->irq.ih1.ring_size) {
+		ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
+		ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING1,
+					   RB_ENABLE, 1);
+		if (amdgpu_sriov_vf(adev) && adev->asic_type < CHIP_NAVI10) {
+			if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL_RING1,
+						ih_rb_cntl)) {
+				DRM_ERROR("program IH_RB_CNTL_RING1 failed!\n");
+				return;
+			}
+		} else {
+			WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl);
+		}
+		adev->irq.ih1.enabled = true;
+	}
+
+	if (adev->irq.ih2.ring_size) {
+		ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2);
+		ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING2,
+					   RB_ENABLE, 1);
+		if (amdgpu_sriov_vf(adev) && adev->asic_type < CHIP_NAVI10) {
+			if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL_RING2,
+						ih_rb_cntl)) {
+				DRM_ERROR("program IH_RB_CNTL_RING2 failed!\n");
+				return;
+			}
+		} else {
+			WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl);
+		}
+		adev->irq.ih2.enabled = true;
+	}
 }
 
 /**
@@ -66,12 +106,61 @@ static void navi10_ih_disable_interrupts(struct amdgpu_device *adev)
 
 	ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RB_ENABLE, 0);
 	ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, ENABLE_INTR, 0);
-	WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl);
+	if (amdgpu_sriov_vf(adev) && adev->asic_type < CHIP_NAVI10) {
+		if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL, ih_rb_cntl)) {
+			DRM_ERROR("PSP program IH_RB_CNTL failed!\n");
+			return;
+		}
+	} else {
+		WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl);
+	}
+
 	/* set rptr, wptr to 0 */
 	WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, 0);
 	WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR, 0);
 	adev->irq.ih.enabled = false;
 	adev->irq.ih.rptr = 0;
+
+	if (adev->irq.ih1.ring_size) {
+		ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
+		ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING1,
+					   RB_ENABLE, 0);
+		if (amdgpu_sriov_vf(adev) && adev->asic_type < CHIP_NAVI10) {
+			if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL_RING1,
+						ih_rb_cntl)) {
+				DRM_ERROR("program IH_RB_CNTL_RING1 failed!\n");
+				return;
+			}
+		} else {
+			WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl);
+		}
+		/* set rptr, wptr to 0 */
+		WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING1, 0);
+		WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING1, 0);
+		adev->irq.ih1.enabled = false;
+		adev->irq.ih1.rptr = 0;
+	}
+
+	if (adev->irq.ih2.ring_size) {
+		ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2);
+		ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING2,
+					   RB_ENABLE, 0);
+		if (amdgpu_sriov_vf(adev) && adev->asic_type < CHIP_NAVI10) {
+			if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL_RING2,
+						ih_rb_cntl)) {
+				DRM_ERROR("program IH_RB_CNTL_RING2 failed!\n");
+				return;
+			}
+		} else {
+			WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl);
+		}
+		/* set rptr, wptr to 0 */
+		WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING2, 0);
+		WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING2, 0);
+		adev->irq.ih2.enabled = false;
+		adev->irq.ih2.rptr = 0;
+	}
+
 }
 
 static uint32_t navi10_ih_rb_cntl(struct amdgpu_ih_ring *ih, uint32_t ih_rb_cntl)
@@ -97,6 +186,43 @@ static uint32_t navi10_ih_rb_cntl(struct amdgpu_ih_ring *ih, uint32_t ih_rb_cntl
 	return ih_rb_cntl;
 }
 
+static uint32_t navi10_ih_doorbell_rptr(struct amdgpu_ih_ring *ih)
+{
+	u32 ih_doorbell_rtpr = 0;
+
+	if (ih->use_doorbell) {
+		ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr,
+						 IH_DOORBELL_RPTR, OFFSET,
+						 ih->doorbell_index);
+		ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr,
+						 IH_DOORBELL_RPTR,
+						 ENABLE, 1);
+	} else {
+		ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr,
+						 IH_DOORBELL_RPTR,
+						 ENABLE, 0);
+	}
+	return ih_doorbell_rtpr;
+}
+
+static void navi10_ih_reroute_ih(struct amdgpu_device *adev)
+{
+	uint32_t tmp;
+
+	/* Reroute to IH ring 1 for VMC */
+	WREG32_SOC15(OSSSYS, 0, mmIH_CLIENT_CFG_INDEX, 0x12);
+	tmp = RREG32_SOC15(OSSSYS, 0, mmIH_CLIENT_CFG_DATA);
+	tmp = REG_SET_FIELD(tmp, IH_CLIENT_CFG_DATA, CLIENT_TYPE, 1);
+	tmp = REG_SET_FIELD(tmp, IH_CLIENT_CFG_DATA, RING_ID, 1);
+	WREG32_SOC15(OSSSYS, 0, mmIH_CLIENT_CFG_DATA, tmp);
+
+	/* Reroute IH ring 1 for UMC */
+	WREG32_SOC15(OSSSYS, 0, mmIH_CLIENT_CFG_INDEX, 0x1B);
+	tmp = RREG32_SOC15(OSSSYS, 0, mmIH_CLIENT_CFG_DATA);
+	tmp = REG_SET_FIELD(tmp, IH_CLIENT_CFG_DATA, RING_ID, 1);
+	WREG32_SOC15(OSSSYS, 0, mmIH_CLIENT_CFG_DATA, tmp);
+}
+
 /**
  * navi10_ih_irq_init - init and enable the interrupt ring
  *
@@ -111,7 +237,7 @@ static uint32_t navi10_ih_rb_cntl(struct amdgpu_ih_ring *ih, uint32_t ih_rb_cntl
 static int navi10_ih_irq_init(struct amdgpu_device *adev)
 {
 	struct amdgpu_ih_ring *ih = &adev->irq.ih;
-	u32 ih_rb_cntl, ih_doorbell_rtpr, ih_chicken;
+	u32 ih_rb_cntl, ih_chicken;
 	u32 tmp;
 
 	/* disable irqs */
@@ -127,6 +253,15 @@ static int navi10_ih_irq_init(struct amdgpu_device *adev)
 	ih_rb_cntl = navi10_ih_rb_cntl(ih, ih_rb_cntl);
 	ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RPTR_REARM,
 				   !!adev->irq.msi_enabled);
+	if (amdgpu_sriov_vf(adev) && adev->asic_type < CHIP_NAVI10) {
+		if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL, ih_rb_cntl)) {
+			DRM_ERROR("PSP program IH_RB_CNTL failed!\n");
+			return -ETIMEDOUT;
+		}
+	} else {
+		WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl);
+	}
+	navi10_ih_reroute_ih(adev);
 
 	if (unlikely(adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT)) {
 		if (ih->use_bus_addr) {
@@ -137,8 +272,6 @@ static int navi10_ih_irq_init(struct amdgpu_device *adev)
 		}
 	}
 
-	WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl);
-
 	/* set the writeback address whether it's enabled or not */
 	WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_ADDR_LO,
 		     lower_32_bits(ih->wptr_addr));
@@ -149,22 +282,68 @@ static int navi10_ih_irq_init(struct amdgpu_device *adev)
 	WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, 0);
 	WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR, 0);
 
-	ih_doorbell_rtpr = RREG32_SOC15(OSSSYS, 0, mmIH_DOORBELL_RPTR);
-	if (ih->use_doorbell) {
-		ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr,
-						 IH_DOORBELL_RPTR, OFFSET,
-						 ih->doorbell_index);
-		ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr,
-						 IH_DOORBELL_RPTR, ENABLE, 1);
-	} else {
-		ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr,
-						 IH_DOORBELL_RPTR, ENABLE, 0);
-	}
-	WREG32_SOC15(OSSSYS, 0, mmIH_DOORBELL_RPTR, ih_doorbell_rtpr);
+	WREG32_SOC15(OSSSYS, 0, mmIH_DOORBELL_RPTR,
+			navi10_ih_doorbell_rptr(ih));
 
 	adev->nbio.funcs->ih_doorbell_range(adev, ih->use_doorbell,
 					    ih->doorbell_index);
 
+	ih = &adev->irq.ih1;
+	if (ih->ring_size) {
+		WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_RING1, ih->gpu_addr >> 8);
+		WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI_RING1,
+			     (ih->gpu_addr >> 40) & 0xff);
+
+		ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
+		ih_rb_cntl = navi10_ih_rb_cntl(ih, ih_rb_cntl);
+		ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
+					   WPTR_OVERFLOW_ENABLE, 0);
+		ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
+					   RB_FULL_DRAIN_ENABLE, 1);
+		if (amdgpu_sriov_vf(adev) && adev->asic_type < CHIP_NAVI10) {
+			if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL_RING1,
+						ih_rb_cntl)) {
+				DRM_ERROR("program IH_RB_CNTL_RING1 failed!\n");
+				return -ETIMEDOUT;
+			}
+		} else {
+			WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl);
+		}
+		/* set rptr, wptr to 0 */
+		WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING1, 0);
+		WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING1, 0);
+
+		WREG32_SOC15(OSSSYS, 0, mmIH_DOORBELL_RPTR_RING1,
+				navi10_ih_doorbell_rptr(ih));
+	}
+
+	ih = &adev->irq.ih2;
+	if (ih->ring_size) {
+		WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_RING2, ih->gpu_addr >> 8);
+		WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI_RING2,
+			     (ih->gpu_addr >> 40) & 0xff);
+
+		ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2);
+		ih_rb_cntl = navi10_ih_rb_cntl(ih, ih_rb_cntl);
+
+		if (amdgpu_sriov_vf(adev) && adev->asic_type < CHIP_NAVI10) {
+			if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL_RING2,
+						ih_rb_cntl)) {
+				DRM_ERROR("program IH_RB_CNTL_RING2 failed!\n");
+				return -ETIMEDOUT;
+			}
+		} else {
+			WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl);
+		}
+		/* set rptr, wptr to 0 */
+		WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING2, 0);
+		WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING2, 0);
+
+		WREG32_SOC15(OSSSYS, 0, mmIH_DOORBELL_RPTR_RING2,
+			     navi10_ih_doorbell_rptr(ih));
+	}
+
+
 	tmp = RREG32_SOC15(OSSSYS, 0, mmIH_STORM_CLIENT_LIST_CNTL);
 	tmp = REG_SET_FIELD(tmp, IH_STORM_CLIENT_LIST_CNTL,
 			    CLIENT18_IS_STORM_CLIENT, 1);
@@ -217,7 +396,15 @@ static u32 navi10_ih_get_wptr(struct amdgpu_device *adev,
 	if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW))
 		goto out;
 
-	reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_WPTR);
+	if (ih == &adev->irq.ih)
+		reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_WPTR);
+	else if (ih == &adev->irq.ih1)
+		reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_WPTR_RING1);
+	else if (ih == &adev->irq.ih2)
+		reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_WPTR_RING2);
+	else
+		BUG();
+
 	wptr = RREG32_NO_KIQ(reg);
 	if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW))
 		goto out;
@@ -233,7 +420,15 @@ static u32 navi10_ih_get_wptr(struct amdgpu_device *adev,
 		 wptr, ih->rptr, tmp);
 	ih->rptr = tmp;
 
-	reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL);
+	if (ih == &adev->irq.ih)
+		reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL);
+	else if (ih == &adev->irq.ih1)
+		reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL_RING1);
+	else if (ih == &adev->irq.ih2)
+		reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL_RING2);
+	else
+		BUG();
+
 	tmp = RREG32_NO_KIQ(reg);
 	tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
 	WREG32_NO_KIQ(reg, tmp);
@@ -333,8 +528,52 @@ static void navi10_ih_set_rptr(struct amdgpu_device *adev,
 
 		if (amdgpu_sriov_vf(adev))
 			navi10_ih_irq_rearm(adev, ih);
-	} else
+	} else if (ih == &adev->irq.ih) {
 		WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, ih->rptr);
+	} else if (ih == &adev->irq.ih1) {
+		WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING1, ih->rptr);
+	} else if (ih == &adev->irq.ih2) {
+		WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING2, ih->rptr);
+	}
+}
+
+/**
+ * navi10_ih_self_irq - dispatch work for ring 1 and 2
+ *
+ * @adev: amdgpu_device pointer
+ * @source: irq source
+ * @entry: IV with WPTR update
+ *
+ * Update the WPTR from the IV and schedule work to handle the entries.
+ */
+static int navi10_ih_self_irq(struct amdgpu_device *adev,
+			      struct amdgpu_irq_src *source,
+			      struct amdgpu_iv_entry *entry)
+{
+	uint32_t wptr = cpu_to_le32(entry->src_data[0]);
+
+	switch (entry->ring_id) {
+	case 1:
+		*adev->irq.ih1.wptr_cpu = wptr;
+		schedule_work(&adev->irq.ih1_work);
+		break;
+	case 2:
+		*adev->irq.ih2.wptr_cpu = wptr;
+		schedule_work(&adev->irq.ih2_work);
+		break;
+	default: break;
+	}
+	return 0;
+}
+
+static const struct amdgpu_irq_src_funcs navi10_ih_self_irq_funcs = {
+	.process = navi10_ih_self_irq,
+};
+
+static void navi10_ih_set_self_irq_funcs(struct amdgpu_device *adev)
+{
+	adev->irq.self_irq.num_types = 0;
+	adev->irq.self_irq.funcs = &navi10_ih_self_irq_funcs;
 }
 
 static int navi10_ih_early_init(void *handle)
@@ -342,6 +581,7 @@ static int navi10_ih_early_init(void *handle)
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
 	navi10_ih_set_interrupt_funcs(adev);
+	navi10_ih_set_self_irq_funcs(adev);
 	return 0;
 }
 
@@ -351,6 +591,12 @@ static int navi10_ih_sw_init(void *handle)
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 	bool use_bus_addr;
 
+	r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_IH, 0,
+				&adev->irq.self_irq);
+
+	if (r)
+		return r;
+
 	/* use gpu virtual address for ih ring
 	 * until ih_checken is programmed to allow
 	 * use bus address for ih ring by psp bl */
@@ -363,6 +609,20 @@ static int navi10_ih_sw_init(void *handle)
 	adev->irq.ih.use_doorbell = true;
 	adev->irq.ih.doorbell_index = adev->doorbell_index.ih << 1;
 
+	r = amdgpu_ih_ring_init(adev, &adev->irq.ih1, PAGE_SIZE, true);
+	if (r)
+		return r;
+
+	adev->irq.ih1.use_doorbell = true;
+	adev->irq.ih1.doorbell_index = (adev->doorbell_index.ih + 1) << 1;
+
+	r = amdgpu_ih_ring_init(adev, &adev->irq.ih2, PAGE_SIZE, true);
+	if (r)
+		return r;
+
+	adev->irq.ih2.use_doorbell = true;
+	adev->irq.ih2.doorbell_index = (adev->doorbell_index.ih + 2) << 1;
+
 	r = amdgpu_irq_init(adev);
 
 	return r;
@@ -373,6 +633,8 @@ static int navi10_ih_sw_fini(void *handle)
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
 	amdgpu_irq_fini(adev);
+	amdgpu_ih_ring_fini(adev, &adev->irq.ih2);
+	amdgpu_ih_ring_fini(adev, &adev->irq.ih1);
 	amdgpu_ih_ring_fini(adev, &adev->irq.ih);
 
 	return 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c b/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c
index f3a3fe746222..cbcf04578b99 100644
--- a/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c
+++ b/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c
@@ -290,23 +290,6 @@ const struct nbio_hdp_flush_reg nbio_v2_3_hdp_flush_reg = {
 	.ref_and_mask_sdma1 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__SDMA1_MASK,
 };
 
-static void nbio_v2_3_detect_hw_virt(struct amdgpu_device *adev)
-{
-	uint32_t reg;
-
-	reg = RREG32_SOC15(NBIO, 0, mmRCC_DEV0_EPF0_RCC_IOV_FUNC_IDENTIFIER);
-	if (reg & 1)
-		adev->virt.caps |= AMDGPU_SRIOV_CAPS_IS_VF;
-
-	if (reg & 0x80000000)
-		adev->virt.caps |= AMDGPU_SRIOV_CAPS_ENABLE_IOV;
-
-	if (!reg) {
-		if (is_virtual_machine())	/* passthrough mode exclus sriov mod */
-			adev->virt.caps |= AMDGPU_PASSTHROUGH_MODE;
-	}
-}
-
 static void nbio_v2_3_init_registers(struct amdgpu_device *adev)
 {
 	uint32_t def, data;
@@ -338,6 +321,5 @@ const struct amdgpu_nbio_funcs nbio_v2_3_funcs = {
 	.get_clockgating_state = nbio_v2_3_get_clockgating_state,
 	.ih_control = nbio_v2_3_ih_control,
 	.init_registers = nbio_v2_3_init_registers,
-	.detect_hw_virt = nbio_v2_3_detect_hw_virt,
 	.remap_hdp_registers = nbio_v2_3_remap_hdp_registers,
 };
diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c b/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c
index 635d9e1fc0a3..7b2fb050407d 100644
--- a/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c
+++ b/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c
@@ -241,23 +241,6 @@ const struct nbio_hdp_flush_reg nbio_v6_1_hdp_flush_reg = {
 	.ref_and_mask_sdma1 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__SDMA1_MASK
 };
 
-static void nbio_v6_1_detect_hw_virt(struct amdgpu_device *adev)
-{
-	uint32_t reg;
-
-	reg = RREG32_SOC15(NBIO, 0, mmRCC_PF_0_0_RCC_IOV_FUNC_IDENTIFIER);
-	if (reg & 1)
-		adev->virt.caps |= AMDGPU_SRIOV_CAPS_IS_VF;
-
-	if (reg & 0x80000000)
-		adev->virt.caps |= AMDGPU_SRIOV_CAPS_ENABLE_IOV;
-
-	if (!reg) {
-		if (is_virtual_machine())	/* passthrough mode exclus sriov mod */
-			adev->virt.caps |= AMDGPU_PASSTHROUGH_MODE;
-	}
-}
-
 static void nbio_v6_1_init_registers(struct amdgpu_device *adev)
 {
 	uint32_t def, data;
@@ -294,5 +277,4 @@ const struct amdgpu_nbio_funcs nbio_v6_1_funcs = {
 	.get_clockgating_state = nbio_v6_1_get_clockgating_state,
 	.ih_control = nbio_v6_1_ih_control,
 	.init_registers = nbio_v6_1_init_registers,
-	.detect_hw_virt = nbio_v6_1_detect_hw_virt,
 };
diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c b/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c
index d6cbf26074bc..d34628e113fc 100644
--- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c
@@ -280,12 +280,6 @@ const struct nbio_hdp_flush_reg nbio_v7_0_hdp_flush_reg = {
 	.ref_and_mask_sdma1 = GPU_HDP_FLUSH_DONE__SDMA1_MASK,
 };
 
-static void nbio_v7_0_detect_hw_virt(struct amdgpu_device *adev)
-{
-	if (is_virtual_machine())	/* passthrough mode exclus sriov mod */
-		adev->virt.caps |= AMDGPU_PASSTHROUGH_MODE;
-}
-
 static void nbio_v7_0_init_registers(struct amdgpu_device *adev)
 {
 
@@ -310,6 +304,5 @@ const struct amdgpu_nbio_funcs nbio_v7_0_funcs = {
 	.get_clockgating_state = nbio_v7_0_get_clockgating_state,
 	.ih_control = nbio_v7_0_ih_control,
 	.init_registers = nbio_v7_0_init_registers,
-	.detect_hw_virt = nbio_v7_0_detect_hw_virt,
 	.remap_hdp_registers = nbio_v7_0_remap_hdp_registers,
 };
diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c
index 149d386590df..e629156173d3 100644
--- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c
+++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c
@@ -185,7 +185,7 @@ static void nbio_v7_4_ih_doorbell_range(struct amdgpu_device *adev,
 
 	if (use_doorbell) {
 		ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range, BIF_IH_DOORBELL_RANGE, OFFSET, doorbell_index);
-		ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range, BIF_IH_DOORBELL_RANGE, SIZE, 2);
+		ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range, BIF_IH_DOORBELL_RANGE, SIZE, 4);
 	} else
 		ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range, BIF_IH_DOORBELL_RANGE, SIZE, 0);
 
@@ -292,23 +292,6 @@ const struct nbio_hdp_flush_reg nbio_v7_4_hdp_flush_reg = {
 	.ref_and_mask_sdma7 = GPU_HDP_FLUSH_DONE__RSVD_ENG5_MASK,
 };
 
-static void nbio_v7_4_detect_hw_virt(struct amdgpu_device *adev)
-{
-	uint32_t reg;
-
-	reg = RREG32_SOC15(NBIO, 0, mmRCC_IOV_FUNC_IDENTIFIER);
-	if (reg & 1)
-		adev->virt.caps |= AMDGPU_SRIOV_CAPS_IS_VF;
-
-	if (reg & 0x80000000)
-		adev->virt.caps |= AMDGPU_SRIOV_CAPS_ENABLE_IOV;
-
-	if (!reg) {
-		if (is_virtual_machine())	/* passthrough mode exclus sriov mod */
-			adev->virt.caps |= AMDGPU_PASSTHROUGH_MODE;
-	}
-}
-
 static void nbio_v7_4_init_registers(struct amdgpu_device *adev)
 {
 
@@ -340,14 +323,20 @@ static void nbio_v7_4_handle_ras_controller_intr_no_bifring(struct amdgpu_device
 		obj->err_data.ce_count += err_data.ce_count;
 
 		if (err_data.ce_count)
-			DRM_INFO("%ld correctable errors detected in %s block\n",
-				obj->err_data.ce_count, adev->nbio.ras_if->name);
+			dev_info(adev->dev, "%ld correctable hardware "
+					"errors detected in %s block, "
+					"no user action is needed.\n",
+					obj->err_data.ce_count,
+					adev->nbio.ras_if->name);
 
 		if (err_data.ue_count)
-			DRM_INFO("%ld uncorrectable errors detected in %s block\n",
-				obj->err_data.ue_count, adev->nbio.ras_if->name);
+			dev_info(adev->dev, "%ld uncorrectable hardware "
+					"errors detected in %s block\n",
+					obj->err_data.ue_count,
+					adev->nbio.ras_if->name);
 
-		DRM_WARN("RAS controller interrupt triggered by NBIF error\n");
+		dev_info(adev->dev, "RAS controller interrupt triggered "
+					"by NBIF error\n");
 
 		/* ras_controller_int is dedicated for nbif ras error,
 		 * not the global interrupt for sync flood
@@ -561,7 +550,6 @@ const struct amdgpu_nbio_funcs nbio_v7_4_funcs = {
 	.get_clockgating_state = nbio_v7_4_get_clockgating_state,
 	.ih_control = nbio_v7_4_ih_control,
 	.init_registers = nbio_v7_4_init_registers,
-	.detect_hw_virt = nbio_v7_4_detect_hw_virt,
 	.remap_hdp_registers = nbio_v7_4_remap_hdp_registers,
 	.handle_ras_controller_intr_no_bifring = nbio_v7_4_handle_ras_controller_intr_no_bifring,
 	.handle_ras_err_event_athub_intr_no_bifring = nbio_v7_4_handle_ras_err_event_athub_intr_no_bifring,
diff --git a/drivers/gpu/drm/amd/amdgpu/nv.c b/drivers/gpu/drm/amd/amdgpu/nv.c
index 033cbbca2072..995bdec9fa7d 100644
--- a/drivers/gpu/drm/amd/amdgpu/nv.c
+++ b/drivers/gpu/drm/amd/amdgpu/nv.c
@@ -351,8 +351,6 @@ static int nv_asic_reset(struct amdgpu_device *adev)
 	struct smu_context *smu = &adev->smu;
 
 	if (nv_asic_reset_method(adev) == AMD_RESET_METHOD_BACO) {
-		if (!adev->in_suspend)
-			amdgpu_inc_vram_lost(adev);
 		ret = smu_baco_enter(smu);
 		if (ret)
 			return ret;
@@ -360,8 +358,6 @@ static int nv_asic_reset(struct amdgpu_device *adev)
 		if (ret)
 			return ret;
 	} else {
-		if (!adev->in_suspend)
-			amdgpu_inc_vram_lost(adev);
 		ret = nv_asic_mode1_reset(adev);
 	}
 
@@ -457,18 +453,19 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
 {
 	int r;
 
-	/* Set IP register base before any HW register access */
-	r = nv_reg_base_init(adev);
-	if (r)
-		return r;
-
 	adev->nbio.funcs = &nbio_v2_3_funcs;
 	adev->nbio.hdp_flush_reg = &nbio_v2_3_hdp_flush_reg;
 
-	adev->nbio.funcs->detect_hw_virt(adev);
-
-	if (amdgpu_sriov_vf(adev))
+	if (amdgpu_sriov_vf(adev)) {
 		adev->virt.ops = &xgpu_nv_virt_ops;
+		/* try send GPU_INIT_DATA request to host */
+		amdgpu_virt_request_init_data(adev);
+	}
+
+	/* Set IP register base before any HW register access */
+	r = nv_reg_base_init(adev);
+	if (r)
+		return r;
 
 	switch (adev->asic_type) {
 	case CHIP_NAVI10:
diff --git a/drivers/gpu/drm/amd/amdgpu/nvd.h b/drivers/gpu/drm/amd/amdgpu/nvd.h
index 1de984647dbb..fd6b58243b03 100644
--- a/drivers/gpu/drm/amd/amdgpu/nvd.h
+++ b/drivers/gpu/drm/amd/amdgpu/nvd.h
@@ -256,6 +256,54 @@
 #define	PACKET3_BLK_CNTX_UPDATE				0x53
 #define	PACKET3_INCR_UPDT_STATE				0x55
 #define	PACKET3_ACQUIRE_MEM				0x58
+/* 1.  HEADER
+ * 2.  COHER_CNTL [30:0]
+ * 2.1 ENGINE_SEL [31:31]
+ * 2.  COHER_SIZE [31:0]
+ * 3.  COHER_SIZE_HI [7:0]
+ * 4.  COHER_BASE_LO [31:0]
+ * 5.  COHER_BASE_HI [23:0]
+ * 7.  POLL_INTERVAL [15:0]
+ * 8.  GCR_CNTL [18:0]
+ */
+#define 	PACKET3_ACQUIRE_MEM_GCR_CNTL_GLI_INV(x) ((x) << 0)
+		/*
+		 * 0:NOP
+		 * 1:ALL
+		 * 2:RANGE
+		 * 3:FIRST_LAST
+		 */
+#define 	PACKET3_ACQUIRE_MEM_GCR_CNTL_GL1_RANGE(x) ((x) << 2)
+		/*
+		 * 0:ALL
+		 * 1:reserved
+		 * 2:RANGE
+		 * 3:FIRST_LAST
+		 */
+#define 	PACKET3_ACQUIRE_MEM_GCR_CNTL_GLM_WB(x) ((x) << 4)
+#define 	PACKET3_ACQUIRE_MEM_GCR_CNTL_GLM_INV(x) ((x) << 5)
+#define 	PACKET3_ACQUIRE_MEM_GCR_CNTL_GLK_WB(x) ((x) << 6)
+#define 	PACKET3_ACQUIRE_MEM_GCR_CNTL_GLK_INV(x) ((x) << 7)
+#define 	PACKET3_ACQUIRE_MEM_GCR_CNTL_GLV_INV(x) ((x) << 8)
+#define 	PACKET3_ACQUIRE_MEM_GCR_CNTL_GL1_INV(x) ((x) << 9)
+#define 	PACKET3_ACQUIRE_MEM_GCR_CNTL_GL2_US(x) ((x) << 10)
+#define 	PACKET3_ACQUIRE_MEM_GCR_CNTL_GL2_RANGE(x) ((x) << 11)
+		/*
+		 * 0:ALL
+		 * 1:VOL
+		 * 2:RANGE
+		 * 3:FIRST_LAST
+		 */
+#define 	PACKET3_ACQUIRE_MEM_GCR_CNTL_GL2_DISCARD(x)  ((x) << 13)
+#define 	PACKET3_ACQUIRE_MEM_GCR_CNTL_GL2_INV(x) ((x) << 14)
+#define 	PACKET3_ACQUIRE_MEM_GCR_CNTL_GL2_WB(x) ((x) << 15)
+#define 	PACKET3_ACQUIRE_MEM_GCR_CNTL_SEQ(x) ((x) << 16)
+		/*
+		 * 0: PARALLEL
+		 * 1: FORWARD
+		 * 2: REVERSE
+		 */
+#define 	PACKET3_ACQUIRE_MEM_GCR_RANGE_IS_PA  (1 << 18)
 #define	PACKET3_REWIND					0x59
 #define	PACKET3_INTERRUPT				0x5A
 #define	PACKET3_GEN_PDEPTE				0x5B
@@ -306,6 +354,7 @@
 #define	PACKET3_GET_LOD_STATS				0x8E
 #define	PACKET3_DRAW_MULTI_PREAMBLE			0x8F
 #define	PACKET3_FRAME_CONTROL				0x90
+#			define FRAME_TMZ	(1 << 0)
 #			define FRAME_CMD(x) ((x) << 28)
 			/*
 			 * x=0: tmz_begin
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c
index 7d509a40076f..5f304d61999e 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c
@@ -355,8 +355,6 @@ static void sdma_v2_4_gfx_stop(struct amdgpu_device *adev)
 		ib_cntl = REG_SET_FIELD(ib_cntl, SDMA0_GFX_IB_CNTL, IB_ENABLE, 0);
 		WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl);
 	}
-	sdma0->sched.ready = false;
-	sdma1->sched.ready = false;
 }
 
 /**
@@ -614,7 +612,8 @@ static int sdma_v2_4_ring_test_ib(struct amdgpu_ring *ring, long timeout)
 	tmp = 0xCAFEDEAD;
 	adev->wb.wb[index] = cpu_to_le32(tmp);
 	memset(&ib, 0, sizeof(ib));
-	r = amdgpu_ib_get(adev, NULL, 256, &ib);
+	r = amdgpu_ib_get(adev, NULL, 256,
+					AMDGPU_IB_POOL_DIRECT, &ib);
 	if (r)
 		goto err0;
 
@@ -874,7 +873,8 @@ static int sdma_v2_4_sw_init(void *handle)
 				     &adev->sdma.trap_irq,
 				     (i == 0) ?
 				     AMDGPU_SDMA_IRQ_INSTANCE0 :
-				     AMDGPU_SDMA_IRQ_INSTANCE1);
+				     AMDGPU_SDMA_IRQ_INSTANCE1,
+				     AMDGPU_RING_PRIO_DEFAULT);
 		if (r)
 			return r;
 	}
@@ -1200,7 +1200,8 @@ static void sdma_v2_4_set_irq_funcs(struct amdgpu_device *adev)
 static void sdma_v2_4_emit_copy_buffer(struct amdgpu_ib *ib,
 				       uint64_t src_offset,
 				       uint64_t dst_offset,
-				       uint32_t byte_count)
+				       uint32_t byte_count,
+				       bool tmz)
 {
 	ib->ptr[ib->length_dw++] = SDMA_PKT_HEADER_OP(SDMA_OP_COPY) |
 		SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_COPY_LINEAR);
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
index b6109a99fc43..c59f6f6f4c09 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
@@ -529,8 +529,6 @@ static void sdma_v3_0_gfx_stop(struct amdgpu_device *adev)
 		ib_cntl = REG_SET_FIELD(ib_cntl, SDMA0_GFX_IB_CNTL, IB_ENABLE, 0);
 		WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl);
 	}
-	sdma0->sched.ready = false;
-	sdma1->sched.ready = false;
 }
 
 /**
@@ -886,7 +884,8 @@ static int sdma_v3_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
 	tmp = 0xCAFEDEAD;
 	adev->wb.wb[index] = cpu_to_le32(tmp);
 	memset(&ib, 0, sizeof(ib));
-	r = amdgpu_ib_get(adev, NULL, 256, &ib);
+	r = amdgpu_ib_get(adev, NULL, 256,
+					AMDGPU_IB_POOL_DIRECT, &ib);
 	if (r)
 		goto err0;
 
@@ -1158,7 +1157,8 @@ static int sdma_v3_0_sw_init(void *handle)
 				     &adev->sdma.trap_irq,
 				     (i == 0) ?
 				     AMDGPU_SDMA_IRQ_INSTANCE0 :
-				     AMDGPU_SDMA_IRQ_INSTANCE1);
+				     AMDGPU_SDMA_IRQ_INSTANCE1,
+				     AMDGPU_RING_PRIO_DEFAULT);
 		if (r)
 			return r;
 	}
@@ -1638,7 +1638,8 @@ static void sdma_v3_0_set_irq_funcs(struct amdgpu_device *adev)
 static void sdma_v3_0_emit_copy_buffer(struct amdgpu_ib *ib,
 				       uint64_t src_offset,
 				       uint64_t dst_offset,
-				       uint32_t byte_count)
+				       uint32_t byte_count,
+				       bool tmz)
 {
 	ib->ptr[ib->length_dw++] = SDMA_PKT_HEADER_OP(SDMA_OP_COPY) |
 		SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_COPY_LINEAR);
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
index 5f3a5ee2a3f4..d723b240d668 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
@@ -115,17 +115,21 @@ static const struct soc15_reg_golden golden_settings_sdma_4[] = {
 static const struct soc15_reg_golden golden_settings_sdma_vg10[] = {
 	SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_GB_ADDR_CONFIG, 0x0018773f, 0x00104002),
 	SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_GB_ADDR_CONFIG_READ, 0x0018773f, 0x00104002),
+	SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_TIMEOUT, 0xffffffff, 0x00010001),
 	SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_CHICKEN_BITS, 0xfe931f07, 0x02831d07),
 	SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_GB_ADDR_CONFIG, 0x0018773f, 0x00104002),
-	SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_GB_ADDR_CONFIG_READ, 0x0018773f, 0x00104002)
+	SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_GB_ADDR_CONFIG_READ, 0x0018773f, 0x00104002),
+	SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_UTCL1_TIMEOUT, 0xffffffff, 0x00010001),
 };
 
 static const struct soc15_reg_golden golden_settings_sdma_vg12[] = {
 	SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_GB_ADDR_CONFIG, 0x0018773f, 0x00104001),
 	SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_GB_ADDR_CONFIG_READ, 0x0018773f, 0x00104001),
+	SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_TIMEOUT, 0xffffffff, 0x00010001),
 	SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_CHICKEN_BITS, 0xfe931f07, 0x02831d07),
 	SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_GB_ADDR_CONFIG, 0x0018773f, 0x00104001),
-	SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_GB_ADDR_CONFIG_READ, 0x0018773f, 0x00104001)
+	SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_GB_ADDR_CONFIG_READ, 0x0018773f, 0x00104001),
+	SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_UTCL1_TIMEOUT, 0xffffffff, 0x00010001),
 };
 
 static const struct soc15_reg_golden golden_settings_sdma_4_1[] = {
@@ -174,6 +178,7 @@ static const struct soc15_reg_golden golden_settings_sdma0_4_2[] =
 	SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC7_RB_RPTR_ADDR_LO, 0xfffffffd, 0x00000001),
 	SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC7_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
 	SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_PAGE, 0x000003ff, 0x000003c0),
+	SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_TIMEOUT, 0xffffffff, 0x00010001),
 };
 
 static const struct soc15_reg_golden golden_settings_sdma1_4_2[] = {
@@ -203,6 +208,7 @@ static const struct soc15_reg_golden golden_settings_sdma1_4_2[] = {
 	SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_RLC7_RB_RPTR_ADDR_LO, 0xfffffffd, 0x00000001),
 	SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_RLC7_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
 	SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_UTCL1_PAGE, 0x000003ff, 0x000003c0),
+	SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_UTCL1_TIMEOUT, 0xffffffff, 0x00010001),
 };
 
 static const struct soc15_reg_golden golden_settings_sdma_rv1[] =
@@ -222,27 +228,35 @@ static const struct soc15_reg_golden golden_settings_sdma_arct[] =
 	SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_CHICKEN_BITS, 0xfe931f07, 0x02831f07),
 	SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_GB_ADDR_CONFIG, 0x0000773f, 0x00004002),
 	SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_GB_ADDR_CONFIG_READ, 0x0000773f, 0x00004002),
+	SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_TIMEOUT, 0xffffffff, 0x00010001),
 	SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_CHICKEN_BITS, 0xfe931f07, 0x02831f07),
 	SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_GB_ADDR_CONFIG, 0x0000773f, 0x00004002),
 	SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_GB_ADDR_CONFIG_READ, 0x0000773f, 0x00004002),
+	SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_UTCL1_TIMEOUT, 0xffffffff, 0x00010001),
 	SOC15_REG_GOLDEN_VALUE(SDMA2, 0, mmSDMA2_CHICKEN_BITS, 0xfe931f07, 0x02831f07),
 	SOC15_REG_GOLDEN_VALUE(SDMA2, 0, mmSDMA2_GB_ADDR_CONFIG, 0x0000773f, 0x00004002),
 	SOC15_REG_GOLDEN_VALUE(SDMA2, 0, mmSDMA2_GB_ADDR_CONFIG_READ, 0x0000773f, 0x00004002),
+	SOC15_REG_GOLDEN_VALUE(SDMA2, 0, mmSDMA2_UTCL1_TIMEOUT, 0xffffffff, 0x00010001),
 	SOC15_REG_GOLDEN_VALUE(SDMA3, 0, mmSDMA3_CHICKEN_BITS, 0xfe931f07, 0x02831f07),
 	SOC15_REG_GOLDEN_VALUE(SDMA3, 0, mmSDMA3_GB_ADDR_CONFIG, 0x0000773f, 0x00004002),
 	SOC15_REG_GOLDEN_VALUE(SDMA3, 0, mmSDMA3_GB_ADDR_CONFIG_READ, 0x0000773f, 0x00004002),
+	SOC15_REG_GOLDEN_VALUE(SDMA3, 0, mmSDMA3_UTCL1_TIMEOUT, 0xffffffff, 0x00010001),
 	SOC15_REG_GOLDEN_VALUE(SDMA4, 0, mmSDMA4_CHICKEN_BITS, 0xfe931f07, 0x02831f07),
 	SOC15_REG_GOLDEN_VALUE(SDMA4, 0, mmSDMA4_GB_ADDR_CONFIG, 0x0000773f, 0x00004002),
 	SOC15_REG_GOLDEN_VALUE(SDMA4, 0, mmSDMA4_GB_ADDR_CONFIG_READ, 0x0000773f, 0x00004002),
+	SOC15_REG_GOLDEN_VALUE(SDMA4, 0, mmSDMA4_UTCL1_TIMEOUT, 0xffffffff, 0x00010001),
 	SOC15_REG_GOLDEN_VALUE(SDMA5, 0, mmSDMA5_CHICKEN_BITS, 0xfe931f07, 0x02831f07),
 	SOC15_REG_GOLDEN_VALUE(SDMA5, 0, mmSDMA5_GB_ADDR_CONFIG, 0x0000773f, 0x00004002),
 	SOC15_REG_GOLDEN_VALUE(SDMA5, 0, mmSDMA5_GB_ADDR_CONFIG_READ, 0x0000773f, 0x00004002),
+	SOC15_REG_GOLDEN_VALUE(SDMA5, 0, mmSDMA5_UTCL1_TIMEOUT, 0xffffffff, 0x00010001),
 	SOC15_REG_GOLDEN_VALUE(SDMA6, 0, mmSDMA6_CHICKEN_BITS, 0xfe931f07, 0x02831f07),
 	SOC15_REG_GOLDEN_VALUE(SDMA6, 0, mmSDMA6_GB_ADDR_CONFIG, 0x0000773f, 0x00004002),
 	SOC15_REG_GOLDEN_VALUE(SDMA6, 0, mmSDMA6_GB_ADDR_CONFIG_READ, 0x0000773f, 0x00004002),
+	SOC15_REG_GOLDEN_VALUE(SDMA6, 0, mmSDMA6_UTCL1_TIMEOUT, 0xffffffff, 0x00010001),
 	SOC15_REG_GOLDEN_VALUE(SDMA7, 0, mmSDMA7_CHICKEN_BITS, 0xfe931f07, 0x02831f07),
 	SOC15_REG_GOLDEN_VALUE(SDMA7, 0, mmSDMA7_GB_ADDR_CONFIG, 0x0000773f, 0x00004002),
-	SOC15_REG_GOLDEN_VALUE(SDMA7, 0, mmSDMA7_GB_ADDR_CONFIG_READ, 0x0000773f, 0x00004002)
+	SOC15_REG_GOLDEN_VALUE(SDMA7, 0, mmSDMA7_GB_ADDR_CONFIG_READ, 0x0000773f, 0x00004002),
+	SOC15_REG_GOLDEN_VALUE(SDMA7, 0, mmSDMA7_UTCL1_TIMEOUT, 0xffffffff, 0x00010001)
 };
 
 static const struct soc15_reg_golden golden_settings_sdma_4_3[] = {
@@ -923,8 +937,6 @@ static void sdma_v4_0_gfx_stop(struct amdgpu_device *adev)
 		ib_cntl = RREG32_SDMA(i, mmSDMA0_GFX_IB_CNTL);
 		ib_cntl = REG_SET_FIELD(ib_cntl, SDMA0_GFX_IB_CNTL, IB_ENABLE, 0);
 		WREG32_SDMA(i, mmSDMA0_GFX_IB_CNTL, ib_cntl);
-
-		sdma[i]->sched.ready = false;
 	}
 }
 
@@ -971,8 +983,6 @@ static void sdma_v4_0_page_stop(struct amdgpu_device *adev)
 		ib_cntl = REG_SET_FIELD(ib_cntl, SDMA0_PAGE_IB_CNTL,
 					IB_ENABLE, 0);
 		WREG32_SDMA(i, mmSDMA0_PAGE_IB_CNTL, ib_cntl);
-
-		sdma[i]->sched.ready = false;
 	}
 }
 
@@ -1062,6 +1072,7 @@ static uint32_t sdma_v4_0_rb_cntl(struct amdgpu_ring *ring, uint32_t rb_cntl)
 	/* Set ring buffer size in dwords */
 	uint32_t rb_bufsz = order_base_2(ring->ring_size / 4);
 
+	barrier(); /* work around https://bugs.llvm.org/show_bug.cgi?id=42576 */
 	rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_SIZE, rb_bufsz);
 #ifdef __BIG_ENDIAN
 	rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_SWAP_ENABLE, 1);
@@ -1539,7 +1550,8 @@ static int sdma_v4_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
 	tmp = 0xCAFEDEAD;
 	adev->wb.wb[index] = cpu_to_le32(tmp);
 	memset(&ib, 0, sizeof(ib));
-	r = amdgpu_ib_get(adev, NULL, 256, &ib);
+	r = amdgpu_ib_get(adev, NULL, 256,
+					AMDGPU_IB_POOL_DIRECT, &ib);
 	if (r)
 		goto err0;
 
@@ -1848,7 +1860,8 @@ static int sdma_v4_0_sw_init(void *handle)
 
 		sprintf(ring->name, "sdma%d", i);
 		r = amdgpu_ring_init(adev, ring, 1024, &adev->sdma.trap_irq,
-				     AMDGPU_SDMA_IRQ_INSTANCE0 + i);
+				     AMDGPU_SDMA_IRQ_INSTANCE0 + i,
+				     AMDGPU_RING_PRIO_DEFAULT);
 		if (r)
 			return r;
 
@@ -1866,7 +1879,8 @@ static int sdma_v4_0_sw_init(void *handle)
 			sprintf(ring->name, "page%d", i);
 			r = amdgpu_ring_init(adev, ring, 1024,
 					     &adev->sdma.trap_irq,
-					     AMDGPU_SDMA_IRQ_INSTANCE0 + i);
+					     AMDGPU_SDMA_IRQ_INSTANCE0 + i,
+					     AMDGPU_RING_PRIO_DEFAULT);
 			if (r)
 				return r;
 		}
@@ -2445,10 +2459,12 @@ static void sdma_v4_0_set_irq_funcs(struct amdgpu_device *adev)
 static void sdma_v4_0_emit_copy_buffer(struct amdgpu_ib *ib,
 				       uint64_t src_offset,
 				       uint64_t dst_offset,
-				       uint32_t byte_count)
+				       uint32_t byte_count,
+				       bool tmz)
 {
 	ib->ptr[ib->length_dw++] = SDMA_PKT_HEADER_OP(SDMA_OP_COPY) |
-		SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_COPY_LINEAR);
+		SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_COPY_LINEAR) |
+		SDMA_PKT_COPY_LINEAR_HEADER_TMZ(tmz ? 1 : 0);
 	ib->ptr[ib->length_dw++] = byte_count - 1;
 	ib->ptr[ib->length_dw++] = 0; /* src/dst endian swap */
 	ib->ptr[ib->length_dw++] = lower_32_bits(src_offset);
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
index ebfd2cdf4e65..f7b2bcf3f293 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
@@ -88,6 +88,29 @@ static const struct soc15_reg_golden golden_settings_sdma_5[] = {
 	SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA1_UTCL1_PAGE, 0x00ffffff, 0x000c5c00)
 };
 
+static const struct soc15_reg_golden golden_settings_sdma_5_sriov[] = {
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA0_GFX_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA0_PAGE_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA0_RLC0_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA0_RLC1_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA0_RLC2_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA0_RLC3_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA0_RLC4_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA0_RLC5_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA0_RLC6_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA0_RLC7_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA1_GFX_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA1_PAGE_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA1_RLC0_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA1_RLC1_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA1_RLC2_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA1_RLC3_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA1_RLC4_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA1_RLC5_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA1_RLC6_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
+	SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA1_RLC7_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
+};
+
 static const struct soc15_reg_golden golden_settings_sdma_nv10[] = {
 	SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA0_RLC3_RB_WPTR_POLL_CNTL, 0x0000fff0, 0x00403000),
 	SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA1_RLC3_RB_WPTR_POLL_CNTL, 0x0000fff0, 0x00403000),
@@ -141,9 +164,14 @@ static void sdma_v5_0_init_golden_registers(struct amdgpu_device *adev)
 						(const u32)ARRAY_SIZE(golden_settings_sdma_nv14));
 		break;
 	case CHIP_NAVI12:
-		soc15_program_register_sequence(adev,
-						golden_settings_sdma_5,
-						(const u32)ARRAY_SIZE(golden_settings_sdma_5));
+		if (amdgpu_sriov_vf(adev))
+			soc15_program_register_sequence(adev,
+							golden_settings_sdma_5_sriov,
+							(const u32)ARRAY_SIZE(golden_settings_sdma_5_sriov));
+		else
+			soc15_program_register_sequence(adev,
+							golden_settings_sdma_5,
+							(const u32)ARRAY_SIZE(golden_settings_sdma_5));
 		soc15_program_register_sequence(adev,
 						golden_settings_sdma_nv12,
 						(const u32)ARRAY_SIZE(golden_settings_sdma_nv12));
@@ -502,9 +530,6 @@ static void sdma_v5_0_gfx_stop(struct amdgpu_device *adev)
 		ib_cntl = REG_SET_FIELD(ib_cntl, SDMA0_GFX_IB_CNTL, IB_ENABLE, 0);
 		WREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_GFX_IB_CNTL), ib_cntl);
 	}
-
-	sdma0->sched.ready = false;
-	sdma1->sched.ready = false;
 }
 
 /**
@@ -529,7 +554,7 @@ static void sdma_v5_0_rlc_stop(struct amdgpu_device *adev)
  */
 static void sdma_v5_0_ctx_switch_enable(struct amdgpu_device *adev, bool enable)
 {
-	u32 f32_cntl, phase_quantum = 0;
+	u32 f32_cntl = 0, phase_quantum = 0;
 	int i;
 
 	if (amdgpu_sdma_phase_quantum) {
@@ -557,9 +582,12 @@ static void sdma_v5_0_ctx_switch_enable(struct amdgpu_device *adev, bool enable)
 	}
 
 	for (i = 0; i < adev->sdma.num_instances; i++) {
-		f32_cntl = RREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_CNTL));
-		f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_CNTL,
-				AUTO_CTXSW_ENABLE, enable ? 1 : 0);
+		if (!amdgpu_sriov_vf(adev)) {
+			f32_cntl = RREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_CNTL));
+			f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_CNTL,
+						 AUTO_CTXSW_ENABLE, enable ? 1 : 0);
+		}
+
 		if (enable && amdgpu_sdma_phase_quantum) {
 			WREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_PHASE0_QUANTUM),
 			       phase_quantum);
@@ -568,7 +596,8 @@ static void sdma_v5_0_ctx_switch_enable(struct amdgpu_device *adev, bool enable)
 			WREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_PHASE2_QUANTUM),
 			       phase_quantum);
 		}
-		WREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_CNTL), f32_cntl);
+		if (!amdgpu_sriov_vf(adev))
+			WREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_CNTL), f32_cntl);
 	}
 
 }
@@ -591,6 +620,9 @@ static void sdma_v5_0_enable(struct amdgpu_device *adev, bool enable)
 		sdma_v5_0_rlc_stop(adev);
 	}
 
+	if (amdgpu_sriov_vf(adev))
+		return;
+
 	for (i = 0; i < adev->sdma.num_instances; i++) {
 		f32_cntl = RREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_F32_CNTL));
 		f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_F32_CNTL, HALT, enable ? 0 : 1);
@@ -623,7 +655,8 @@ static int sdma_v5_0_gfx_resume(struct amdgpu_device *adev)
 		ring = &adev->sdma.instance[i].ring;
 		wb_offset = (ring->rptr_offs * 4);
 
-		WREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_SEM_WAIT_FAIL_TIMER_CNTL), 0);
+		if (!amdgpu_sriov_vf(adev))
+			WREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_SEM_WAIT_FAIL_TIMER_CNTL), 0);
 
 		/* Set ring buffer size in dwords */
 		rb_bufsz = order_base_2(ring->ring_size / 4);
@@ -699,26 +732,28 @@ static int sdma_v5_0_gfx_resume(struct amdgpu_device *adev)
 		/* set minor_ptr_update to 0 after wptr programed */
 		WREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_GFX_MINOR_PTR_UPDATE), 0);
 
-		/* set utc l1 enable flag always to 1 */
-		temp = RREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_CNTL));
-		temp = REG_SET_FIELD(temp, SDMA0_CNTL, UTC_L1_ENABLE, 1);
-
-		/* enable MCBP */
-		temp = REG_SET_FIELD(temp, SDMA0_CNTL, MIDCMD_PREEMPT_ENABLE, 1);
-		WREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_CNTL), temp);
-
-		/* Set up RESP_MODE to non-copy addresses */
-		temp = RREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_UTCL1_CNTL));
-		temp = REG_SET_FIELD(temp, SDMA0_UTCL1_CNTL, RESP_MODE, 3);
-		temp = REG_SET_FIELD(temp, SDMA0_UTCL1_CNTL, REDO_DELAY, 9);
-		WREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_UTCL1_CNTL), temp);
-
-		/* program default cache read and write policy */
-		temp = RREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_UTCL1_PAGE));
-		/* clean read policy and write policy bits */
-		temp &= 0xFF0FFF;
-		temp |= ((CACHE_READ_POLICY_L2__DEFAULT << 12) | (CACHE_WRITE_POLICY_L2__DEFAULT << 14));
-		WREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_UTCL1_PAGE), temp);
+		if (!amdgpu_sriov_vf(adev)) {
+			/* set utc l1 enable flag always to 1 */
+			temp = RREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_CNTL));
+			temp = REG_SET_FIELD(temp, SDMA0_CNTL, UTC_L1_ENABLE, 1);
+
+			/* enable MCBP */
+			temp = REG_SET_FIELD(temp, SDMA0_CNTL, MIDCMD_PREEMPT_ENABLE, 1);
+			WREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_CNTL), temp);
+
+			/* Set up RESP_MODE to non-copy addresses */
+			temp = RREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_UTCL1_CNTL));
+			temp = REG_SET_FIELD(temp, SDMA0_UTCL1_CNTL, RESP_MODE, 3);
+			temp = REG_SET_FIELD(temp, SDMA0_UTCL1_CNTL, REDO_DELAY, 9);
+			WREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_UTCL1_CNTL), temp);
+
+			/* program default cache read and write policy */
+			temp = RREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_UTCL1_PAGE));
+			/* clean read policy and write policy bits */
+			temp &= 0xFF0FFF;
+			temp |= ((CACHE_READ_POLICY_L2__DEFAULT << 12) | (CACHE_WRITE_POLICY_L2__DEFAULT << 14));
+			WREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_UTCL1_PAGE), temp);
+		}
 
 		if (!amdgpu_sriov_vf(adev)) {
 			/* unhalt engine */
@@ -948,7 +983,8 @@ static int sdma_v5_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
 	tmp = 0xCAFEDEAD;
 	adev->wb.wb[index] = cpu_to_le32(tmp);
 	memset(&ib, 0, sizeof(ib));
-	r = amdgpu_ib_get(adev, NULL, 256, &ib);
+	r = amdgpu_ib_get(adev, NULL, 256,
+					AMDGPU_IB_POOL_DIRECT, &ib);
 	if (r) {
 		DRM_ERROR("amdgpu: failed to get ib (%ld).\n", r);
 		goto err0;
@@ -1236,7 +1272,8 @@ static int sdma_v5_0_sw_init(void *handle)
 				     &adev->sdma.trap_irq,
 				     (i == 0) ?
 				     AMDGPU_SDMA_IRQ_INSTANCE0 :
-				     AMDGPU_SDMA_IRQ_INSTANCE1);
+				     AMDGPU_SDMA_IRQ_INSTANCE1,
+				     AMDGPU_RING_PRIO_DEFAULT);
 		if (r)
 			return r;
 	}
@@ -1387,14 +1424,16 @@ static int sdma_v5_0_set_trap_irq_state(struct amdgpu_device *adev,
 {
 	u32 sdma_cntl;
 
-	u32 reg_offset = (type == AMDGPU_SDMA_IRQ_INSTANCE0) ?
-		sdma_v5_0_get_reg_offset(adev, 0, mmSDMA0_CNTL) :
-		sdma_v5_0_get_reg_offset(adev, 1, mmSDMA0_CNTL);
+	if (!amdgpu_sriov_vf(adev)) {
+		u32 reg_offset = (type == AMDGPU_SDMA_IRQ_INSTANCE0) ?
+			sdma_v5_0_get_reg_offset(adev, 0, mmSDMA0_CNTL) :
+			sdma_v5_0_get_reg_offset(adev, 1, mmSDMA0_CNTL);
 
-	sdma_cntl = RREG32(reg_offset);
-	sdma_cntl = REG_SET_FIELD(sdma_cntl, SDMA0_CNTL, TRAP_ENABLE,
-		       state == AMDGPU_IRQ_STATE_ENABLE ? 1 : 0);
-	WREG32(reg_offset, sdma_cntl);
+		sdma_cntl = RREG32(reg_offset);
+		sdma_cntl = REG_SET_FIELD(sdma_cntl, SDMA0_CNTL, TRAP_ENABLE,
+					  state == AMDGPU_IRQ_STATE_ENABLE ? 1 : 0);
+		WREG32(reg_offset, sdma_cntl);
+	}
 
 	return 0;
 }
@@ -1655,10 +1694,12 @@ static void sdma_v5_0_set_irq_funcs(struct amdgpu_device *adev)
 static void sdma_v5_0_emit_copy_buffer(struct amdgpu_ib *ib,
 				       uint64_t src_offset,
 				       uint64_t dst_offset,
-				       uint32_t byte_count)
+				       uint32_t byte_count,
+				       bool tmz)
 {
 	ib->ptr[ib->length_dw++] = SDMA_PKT_HEADER_OP(SDMA_OP_COPY) |
-		SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_COPY_LINEAR);
+		SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_COPY_LINEAR) |
+		SDMA_PKT_COPY_LINEAR_HEADER_TMZ(tmz ? 1 : 0);
 	ib->ptr[ib->length_dw++] = byte_count - 1;
 	ib->ptr[ib->length_dw++] = 0; /* src/dst endian swap */
 	ib->ptr[ib->length_dw++] = lower_32_bits(src_offset);
diff --git a/drivers/gpu/drm/amd/amdgpu/si.c b/drivers/gpu/drm/amd/amdgpu/si.c
index 4d415bfdb42f..153db3f763bc 100644
--- a/drivers/gpu/drm/amd/amdgpu/si.c
+++ b/drivers/gpu/drm/amd/amdgpu/si.c
@@ -1249,12 +1249,6 @@ static int si_set_uvd_clocks(struct amdgpu_device *adev, u32 vclk, u32 dclk)
 	return 0;
 }
 
-static void si_detect_hw_virtualization(struct amdgpu_device *adev)
-{
-	if (is_virtual_machine()) /* passthrough mode */
-		adev->virt.caps |= AMDGPU_PASSTHROUGH_MODE;
-}
-
 static void si_flush_hdp(struct amdgpu_device *adev, struct amdgpu_ring *ring)
 {
 	if (!ring || !ring->funcs->emit_wreg) {
@@ -2165,8 +2159,6 @@ static const struct amdgpu_ip_block_version si_common_ip_block =
 
 int si_set_ip_blocks(struct amdgpu_device *adev)
 {
-	si_detect_hw_virtualization(adev);
-
 	switch (adev->asic_type) {
 	case CHIP_VERDE:
 	case CHIP_TAHITI:
diff --git a/drivers/gpu/drm/amd/amdgpu/si_dma.c b/drivers/gpu/drm/amd/amdgpu/si_dma.c
index 42d5601b6bf3..7d2bbcbe547b 100644
--- a/drivers/gpu/drm/amd/amdgpu/si_dma.c
+++ b/drivers/gpu/drm/amd/amdgpu/si_dma.c
@@ -124,7 +124,6 @@ static void si_dma_stop(struct amdgpu_device *adev)
 
 		if (adev->mman.buffer_funcs_ring == ring)
 			amdgpu_ttm_set_buffer_funcs_status(adev, false);
-		ring->sched.ready = false;
 	}
 }
 
@@ -267,7 +266,8 @@ static int si_dma_ring_test_ib(struct amdgpu_ring *ring, long timeout)
 	tmp = 0xCAFEDEAD;
 	adev->wb.wb[index] = cpu_to_le32(tmp);
 	memset(&ib, 0, sizeof(ib));
-	r = amdgpu_ib_get(adev, NULL, 256, &ib);
+	r = amdgpu_ib_get(adev, NULL, 256,
+					AMDGPU_IB_POOL_DIRECT, &ib);
 	if (r)
 		goto err0;
 
@@ -504,7 +504,8 @@ static int si_dma_sw_init(void *handle)
 				     &adev->sdma.trap_irq,
 				     (i == 0) ?
 				     AMDGPU_SDMA_IRQ_INSTANCE0 :
-				     AMDGPU_SDMA_IRQ_INSTANCE1);
+				     AMDGPU_SDMA_IRQ_INSTANCE1,
+				     AMDGPU_RING_PRIO_DEFAULT);
 		if (r)
 			return r;
 	}
@@ -775,7 +776,8 @@ static void si_dma_set_irq_funcs(struct amdgpu_device *adev)
 static void si_dma_emit_copy_buffer(struct amdgpu_ib *ib,
 				       uint64_t src_offset,
 				       uint64_t dst_offset,
-				       uint32_t byte_count)
+				       uint32_t byte_count,
+				       bool tmz)
 {
 	ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_COPY,
 					      1, 0, 0, byte_count);
diff --git a/drivers/gpu/drm/amd/amdgpu/si_dpm.c b/drivers/gpu/drm/amd/amdgpu/si_dpm.c
index 0860e85a2d35..c00ba4b23c9a 100644
--- a/drivers/gpu/drm/amd/amdgpu/si_dpm.c
+++ b/drivers/gpu/drm/amd/amdgpu/si_dpm.c
@@ -345,26 +345,6 @@ static const struct si_dte_data dte_data_tahiti =
 	false
 };
 
-#if 0
-static const struct si_dte_data dte_data_tahiti_le =
-{
-	{ 0x1E8480, 0x7A1200, 0x2160EC0, 0x3938700, 0 },
-	{ 0x7D, 0x7D, 0x4E4, 0xB00, 0 },
-	0x5,
-	0xAFC8,
-	0x64,
-	0x32,
-	1,
-	0,
-	0x10,
-	{ 0x78, 0x7C, 0x82, 0x88, 0x8E, 0x94, 0x9A, 0xA0, 0xA6, 0xAC, 0xB0, 0xB4, 0xB8, 0xBC, 0xC0, 0xC4 },
-	{ 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700 },
-	{ 0x2AF8, 0x2AF8, 0x29BB, 0x27F9, 0x2637, 0x2475, 0x22B3, 0x20F1, 0x1F2F, 0x1D6D, 0x1734, 0x1414, 0x10F4, 0xDD4, 0xAB4, 0x794 },
-	85,
-	true
-};
-#endif
-
 static const struct si_dte_data dte_data_tahiti_pro =
 {
 	{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },
diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c
index a40499d51c93..58a440a15525 100644
--- a/drivers/gpu/drm/amd/amdgpu/soc15.c
+++ b/drivers/gpu/drm/amd/amdgpu/soc15.c
@@ -569,14 +569,10 @@ static int soc15_asic_reset(struct amdgpu_device *adev)
 
 	switch (soc15_asic_reset_method(adev)) {
 		case AMD_RESET_METHOD_BACO:
-			if (!adev->in_suspend)
-				amdgpu_inc_vram_lost(adev);
 			return soc15_asic_baco_reset(adev);
 		case AMD_RESET_METHOD_MODE2:
 			return amdgpu_dpm_mode2_reset(adev);
 		default:
-			if (!adev->in_suspend)
-				amdgpu_inc_vram_lost(adev);
 			return soc15_asic_mode1_reset(adev);
 	}
 }
@@ -712,7 +708,6 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
 		adev->df.funcs = &df_v1_7_funcs;
 
 	adev->rev_id = soc15_get_rev_id(adev);
-	adev->nbio.funcs->detect_hw_virt(adev);
 
 	if (amdgpu_sriov_vf(adev))
 		adev->virt.ops = &xgpu_ai_virt_ops;
@@ -1222,7 +1217,7 @@ static int soc15_common_early_init(void *handle)
 			AMD_CG_SUPPORT_IH_CG |
 			AMD_CG_SUPPORT_VCN_MGCG |
 			AMD_CG_SUPPORT_JPEG_MGCG;
-		adev->pg_flags = 0;
+		adev->pg_flags = AMD_PG_SUPPORT_VCN | AMD_PG_SUPPORT_VCN_DPG;
 		adev->external_rev_id = adev->rev_id + 0x32;
 		break;
 	case CHIP_RENOIR:
diff --git a/drivers/gpu/drm/amd/amdgpu/soc15d.h b/drivers/gpu/drm/amd/amdgpu/soc15d.h
index edfe50821cd9..799925d22fc8 100644
--- a/drivers/gpu/drm/amd/amdgpu/soc15d.h
+++ b/drivers/gpu/drm/amd/amdgpu/soc15d.h
@@ -253,7 +253,30 @@
 #              define PACKET3_DMA_DATA_CMD_SAIC    (1 << 28)
 #              define PACKET3_DMA_DATA_CMD_DAIC    (1 << 29)
 #              define PACKET3_DMA_DATA_CMD_RAW_WAIT  (1 << 30)
-#define	PACKET3_AQUIRE_MEM				0x58
+#define	PACKET3_ACQUIRE_MEM				0x58
+/* 1.  HEADER
+ * 2.  COHER_CNTL [30:0]
+ * 2.1 ENGINE_SEL [31:31]
+ * 3.  COHER_SIZE [31:0]
+ * 4.  COHER_SIZE_HI [7:0]
+ * 5.  COHER_BASE_LO [31:0]
+ * 6.  COHER_BASE_HI [23:0]
+ * 7.  POLL_INTERVAL [15:0]
+ */
+/* COHER_CNTL fields for CP_COHER_CNTL */
+#define 	PACKET3_ACQUIRE_MEM_CP_COHER_CNTL_TC_NC_ACTION_ENA(x) ((x) << 3)
+#define 	PACKET3_ACQUIRE_MEM_CP_COHER_CNTL_TC_WC_ACTION_ENA(x) ((x) << 4)
+#define 	PACKET3_ACQUIRE_MEM_CP_COHER_CNTL_TC_INV_METADATA_ACTION_ENA(x) ((x) << 5)
+#define 	PACKET3_ACQUIRE_MEM_CP_COHER_CNTL_TCL1_VOL_ACTION_ENA(x) ((x) << 15)
+#define 	PACKET3_ACQUIRE_MEM_CP_COHER_CNTL_TC_WB_ACTION_ENA(x) ((x) << 18)
+#define 	PACKET3_ACQUIRE_MEM_CP_COHER_CNTL_TCL1_ACTION_ENA(x) ((x) << 22)
+#define 	PACKET3_ACQUIRE_MEM_CP_COHER_CNTL_TC_ACTION_ENA(x) ((x) << 23)
+#define 	PACKET3_ACQUIRE_MEM_CP_COHER_CNTL_CB_ACTION_ENA(x) ((x) << 25)
+#define 	PACKET3_ACQUIRE_MEM_CP_COHER_CNTL_DB_ACTION_ENA(x) ((x) << 26)
+#define 	PACKET3_ACQUIRE_MEM_CP_COHER_CNTL_SH_KCACHE_ACTION_ENA(x) ((x) << 27)
+#define 	PACKET3_ACQUIRE_MEM_CP_COHER_CNTL_SH_KCACHE_VOL_ACTION_ENA(x) ((x) << 28)
+#define 	PACKET3_ACQUIRE_MEM_CP_COHER_CNTL_SH_ICACHE_ACTION_ENA(x) ((x) << 29)
+#define 	PACKET3_ACQUIRE_MEM_CP_COHER_CNTL_SH_KCACHE_WB_ACTION_ENA(x) ((x) << 30)
 #define	PACKET3_REWIND					0x59
 #define	PACKET3_LOAD_UCONFIG_REG			0x5E
 #define	PACKET3_LOAD_SH_REG				0x5F
@@ -286,6 +309,7 @@
 #define	PACKET3_WAIT_ON_DE_COUNTER_DIFF			0x88
 #define	PACKET3_SWITCH_BUFFER				0x8B
 #define PACKET3_FRAME_CONTROL				0x90
+#			define FRAME_TMZ	(1 << 0)
 #			define FRAME_CMD(x) ((x) << 28)
 			/*
 			 * x=0: tmz_begin
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c
index 82abd8e728ab..3cafba726587 100644
--- a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c
+++ b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c
@@ -118,7 +118,8 @@ static int uvd_v4_2_sw_init(void *handle)
 
 	ring = &adev->uvd.inst->ring;
 	sprintf(ring->name, "uvd");
-	r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst->irq, 0);
+	r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst->irq, 0,
+			     AMDGPU_RING_PRIO_DEFAULT);
 	if (r)
 		return r;
 
@@ -210,13 +211,10 @@ static int uvd_v4_2_hw_init(void *handle)
 static int uvd_v4_2_hw_fini(void *handle)
 {
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
-	struct amdgpu_ring *ring = &adev->uvd.inst->ring;
 
 	if (RREG32(mmUVD_STATUS) != 0)
 		uvd_v4_2_stop(adev);
 
-	ring->sched.ready = false;
-
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c
index 0fa8aae2d78e..a566ff926e90 100644
--- a/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c
@@ -116,7 +116,8 @@ static int uvd_v5_0_sw_init(void *handle)
 
 	ring = &adev->uvd.inst->ring;
 	sprintf(ring->name, "uvd");
-	r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst->irq, 0);
+	r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst->irq, 0,
+			     AMDGPU_RING_PRIO_DEFAULT);
 	if (r)
 		return r;
 
@@ -208,13 +209,10 @@ static int uvd_v5_0_hw_init(void *handle)
 static int uvd_v5_0_hw_fini(void *handle)
 {
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
-	struct amdgpu_ring *ring = &adev->uvd.inst->ring;
 
 	if (RREG32(mmUVD_STATUS) != 0)
 		uvd_v5_0_stop(adev);
 
-	ring->sched.ready = false;
-
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c
index e0aadcaf6c8b..0a880bc101b8 100644
--- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c
@@ -216,7 +216,8 @@ static int uvd_v6_0_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle
 	uint64_t addr;
 	int i, r;
 
-	r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
+	r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4,
+					AMDGPU_IB_POOL_DIRECT, &job);
 	if (r)
 		return r;
 
@@ -279,7 +280,8 @@ static int uvd_v6_0_enc_get_destroy_msg(struct amdgpu_ring *ring,
 	uint64_t addr;
 	int i, r;
 
-	r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
+	r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4,
+					AMDGPU_IB_POOL_DIRECT, &job);
 	if (r)
 		return r;
 
@@ -416,7 +418,8 @@ static int uvd_v6_0_sw_init(void *handle)
 
 	ring = &adev->uvd.inst->ring;
 	sprintf(ring->name, "uvd");
-	r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst->irq, 0);
+	r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst->irq, 0,
+			     AMDGPU_RING_PRIO_DEFAULT);
 	if (r)
 		return r;
 
@@ -428,7 +431,9 @@ static int uvd_v6_0_sw_init(void *handle)
 		for (i = 0; i < adev->uvd.num_enc_rings; ++i) {
 			ring = &adev->uvd.inst->ring_enc[i];
 			sprintf(ring->name, "uvd_enc%d", i);
-			r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst->irq, 0);
+			r = amdgpu_ring_init(adev, ring, 512,
+					     &adev->uvd.inst->irq, 0,
+					     AMDGPU_RING_PRIO_DEFAULT);
 			if (r)
 				return r;
 		}
@@ -535,13 +540,10 @@ static int uvd_v6_0_hw_init(void *handle)
 static int uvd_v6_0_hw_fini(void *handle)
 {
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
-	struct amdgpu_ring *ring = &adev->uvd.inst->ring;
 
 	if (RREG32(mmUVD_STATUS) != 0)
 		uvd_v6_0_stop(adev);
 
-	ring->sched.ready = false;
-
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c
index 0995378d8263..7a55457e6f9e 100644
--- a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c
@@ -224,7 +224,8 @@ static int uvd_v7_0_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle
 	uint64_t addr;
 	int i, r;
 
-	r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
+	r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4,
+					AMDGPU_IB_POOL_DIRECT, &job);
 	if (r)
 		return r;
 
@@ -286,7 +287,8 @@ static int uvd_v7_0_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handl
 	uint64_t addr;
 	int i, r;
 
-	r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
+	r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4,
+					AMDGPU_IB_POOL_DIRECT, &job);
 	if (r)
 		return r;
 
@@ -450,7 +452,9 @@ static int uvd_v7_0_sw_init(void *handle)
 		if (!amdgpu_sriov_vf(adev)) {
 			ring = &adev->uvd.inst[j].ring;
 			sprintf(ring->name, "uvd_%d", ring->me);
-			r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst[j].irq, 0);
+			r = amdgpu_ring_init(adev, ring, 512,
+					     &adev->uvd.inst[j].irq, 0,
+					     AMDGPU_RING_PRIO_DEFAULT);
 			if (r)
 				return r;
 		}
@@ -469,7 +473,9 @@ static int uvd_v7_0_sw_init(void *handle)
 				else
 					ring->doorbell_index = adev->doorbell_index.uvd_vce.uvd_ring2_3 * 2 + 1;
 			}
-			r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst[j].irq, 0);
+			r = amdgpu_ring_init(adev, ring, 512,
+					     &adev->uvd.inst[j].irq, 0,
+					     AMDGPU_RING_PRIO_DEFAULT);
 			if (r)
 				return r;
 		}
@@ -598,7 +604,6 @@ static int uvd_v7_0_hw_init(void *handle)
 static int uvd_v7_0_hw_fini(void *handle)
 {
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
-	int i;
 
 	if (!amdgpu_sriov_vf(adev))
 		uvd_v7_0_stop(adev);
@@ -607,12 +612,6 @@ static int uvd_v7_0_hw_fini(void *handle)
 		DRM_DEBUG("For SRIOV client, shouldn't do anything.\n");
 	}
 
-	for (i = 0; i < adev->uvd.num_uvd_inst; ++i) {
-		if (adev->uvd.harvest_config & (1 << i))
-			continue;
-		adev->uvd.inst[i].ring.sched.ready = false;
-	}
-
 	return 0;
 }
 
@@ -1694,7 +1693,7 @@ static int uvd_v7_0_set_clockgating_state(void *handle,
 					  enum amd_clockgating_state state)
 {
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
-	bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
+	bool enable = (state == AMD_CG_STATE_GATE);
 
 	uvd_v7_0_set_bypass_mode(adev, enable);
 
diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c
index b6837fcfdba7..0e2945baf0f1 100644
--- a/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c
@@ -434,7 +434,8 @@ static int vce_v2_0_sw_init(void *handle)
 		ring = &adev->vce.ring[i];
 		sprintf(ring->name, "vce%d", i);
 		r = amdgpu_ring_init(adev, ring, 512,
-				     &adev->vce.irq, 0);
+				     &adev->vce.irq, 0,
+				     AMDGPU_RING_PRIO_DEFAULT);
 		if (r)
 			return r;
 	}
diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
index 217db187207c..6d9108fa22e0 100644
--- a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
@@ -442,7 +442,8 @@ static int vce_v3_0_sw_init(void *handle)
 	for (i = 0; i < adev->vce.num_rings; i++) {
 		ring = &adev->vce.ring[i];
 		sprintf(ring->name, "vce%d", i);
-		r = amdgpu_ring_init(adev, ring, 512, &adev->vce.irq, 0);
+		r = amdgpu_ring_init(adev, ring, 512, &adev->vce.irq, 0,
+				     AMDGPU_RING_PRIO_DEFAULT);
 		if (r)
 			return r;
 	}
diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c
index 3fd102efb7af..a0fb119240f4 100644
--- a/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c
@@ -476,7 +476,8 @@ static int vce_v4_0_sw_init(void *handle)
 			else
 				ring->doorbell_index = adev->doorbell_index.uvd_vce.vce_ring2_3 * 2 + 1;
 		}
-		r = amdgpu_ring_init(adev, ring, 512, &adev->vce.irq, 0);
+		r = amdgpu_ring_init(adev, ring, 512, &adev->vce.irq, 0,
+				     AMDGPU_RING_PRIO_DEFAULT);
 		if (r)
 			return r;
 	}
@@ -539,7 +540,6 @@ static int vce_v4_0_hw_init(void *handle)
 static int vce_v4_0_hw_fini(void *handle)
 {
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
-	int i;
 
 	if (!amdgpu_sriov_vf(adev)) {
 		/* vce_v4_0_wait_for_idle(handle); */
@@ -549,9 +549,6 @@ static int vce_v4_0_hw_fini(void *handle)
 		DRM_DEBUG("For SRIOV client, shouldn't do anything.\n");
 	}
 
-	for (i = 0; i < adev->vce.num_rings; i++)
-		adev->vce.ring[i].sched.ready = false;
-
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c
index 09b0572b838d..1ad79155ed00 100644
--- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c
@@ -127,7 +127,8 @@ static int vcn_v1_0_sw_init(void *handle)
 
 	ring = &adev->vcn.inst->ring_dec;
 	sprintf(ring->name, "vcn_dec");
-	r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst->irq, 0);
+	r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst->irq, 0,
+			     AMDGPU_RING_PRIO_DEFAULT);
 	if (r)
 		return r;
 
@@ -145,7 +146,8 @@ static int vcn_v1_0_sw_init(void *handle)
 	for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
 		ring = &adev->vcn.inst->ring_enc[i];
 		sprintf(ring->name, "vcn_enc%d", i);
-		r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst->irq, 0);
+		r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst->irq, 0,
+				     AMDGPU_RING_PRIO_DEFAULT);
 		if (r)
 			return r;
 	}
@@ -227,14 +229,11 @@ static int vcn_v1_0_hw_init(void *handle)
 static int vcn_v1_0_hw_fini(void *handle)
 {
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
-	struct amdgpu_ring *ring = &adev->vcn.inst->ring_dec;
 
 	if ((adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) ||
 		RREG32_SOC15(VCN, 0, mmUVD_STATUS))
 		vcn_v1_0_set_powergating_state(adev, AMD_PG_STATE_GATE);
 
-	ring->sched.ready = false;
-
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c
index ec8091a661df..349da7bf7c68 100644
--- a/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c
@@ -92,6 +92,7 @@ static int vcn_v2_0_sw_init(void *handle)
 	struct amdgpu_ring *ring;
 	int i, r;
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+	volatile struct amdgpu_fw_shared *fw_shared;
 
 	/* VCN DEC TRAP */
 	r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN,
@@ -133,7 +134,8 @@ static int vcn_v2_0_sw_init(void *handle)
 	ring->doorbell_index = adev->doorbell_index.vcn.vcn_ring0_1 << 1;
 
 	sprintf(ring->name, "vcn_dec");
-	r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst->irq, 0);
+	r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst->irq, 0,
+			     AMDGPU_RING_PRIO_DEFAULT);
 	if (r)
 		return r;
 
@@ -163,7 +165,8 @@ static int vcn_v2_0_sw_init(void *handle)
 		else
 			ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 1 + i;
 		sprintf(ring->name, "vcn_enc%d", i);
-		r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst->irq, 0);
+		r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst->irq, 0,
+				     AMDGPU_RING_PRIO_DEFAULT);
 		if (r)
 			return r;
 	}
@@ -174,6 +177,8 @@ static int vcn_v2_0_sw_init(void *handle)
 	if (r)
 		return r;
 
+	fw_shared = adev->vcn.inst->fw_shared_cpu_addr;
+	fw_shared->present_flag_0 = cpu_to_le32(AMDGPU_VCN_MULTI_QUEUE_FLAG);
 	return 0;
 }
 
@@ -188,6 +193,9 @@ static int vcn_v2_0_sw_fini(void *handle)
 {
 	int r;
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+	volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst->fw_shared_cpu_addr;
+
+	fw_shared->present_flag_0 = 0;
 
 	amdgpu_virt_free_mm_table(adev);
 
@@ -223,6 +231,10 @@ static int vcn_v2_0_hw_init(void *handle)
 	if (r)
 		goto done;
 
+	//Disable vcn decode for sriov
+	if (amdgpu_sriov_vf(adev))
+		ring->sched.ready = false;
+
 	for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
 		ring = &adev->vcn.inst->ring_enc[i];
 		r = amdgpu_ring_test_helper(ring);
@@ -248,21 +260,12 @@ static int vcn_v2_0_hw_init(void *handle)
 static int vcn_v2_0_hw_fini(void *handle)
 {
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
-	struct amdgpu_ring *ring = &adev->vcn.inst->ring_dec;
-	int i;
 
 	if ((adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) ||
 	    (adev->vcn.cur_state != AMD_PG_STATE_GATE &&
 	      RREG32_SOC15(VCN, 0, mmUVD_STATUS)))
 		vcn_v2_0_set_powergating_state(adev, AMD_PG_STATE_GATE);
 
-	ring->sched.ready = false;
-
-	for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
-		ring = &adev->vcn.inst->ring_enc[i];
-		ring->sched.ready = false;
-	}
-
 	return 0;
 }
 
@@ -359,6 +362,15 @@ static void vcn_v2_0_mc_resume(struct amdgpu_device *adev)
 	WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_OFFSET2, 0);
 	WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_SIZE2, AMDGPU_VCN_CONTEXT_SIZE);
 
+	/* non-cache window */
+	WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_NC0_64BIT_BAR_LOW,
+		lower_32_bits(adev->vcn.inst->fw_shared_gpu_addr));
+	WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH,
+		upper_32_bits(adev->vcn.inst->fw_shared_gpu_addr));
+	WREG32_SOC15(UVD, 0, mmUVD_VCPU_NONCACHE_OFFSET0, 0);
+	WREG32_SOC15(UVD, 0, mmUVD_VCPU_NONCACHE_SIZE0,
+		AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_fw_shared)));
+
 	WREG32_SOC15(UVD, 0, mmUVD_GFX10_ADDR_CONFIG, adev->gfx.config.gb_addr_config);
 }
 
@@ -442,13 +454,16 @@ static void vcn_v2_0_mc_resume_dpg_mode(struct amdgpu_device *adev, bool indirec
 
 	/* non-cache window */
 	WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
-		UVD, 0, mmUVD_LMI_VCPU_NC0_64BIT_BAR_LOW), 0, 0, indirect);
+		UVD, 0, mmUVD_LMI_VCPU_NC0_64BIT_BAR_LOW),
+		lower_32_bits(adev->vcn.inst->fw_shared_gpu_addr), 0, indirect);
 	WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
-		UVD, 0, mmUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH), 0, 0, indirect);
+		UVD, 0, mmUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH),
+		upper_32_bits(adev->vcn.inst->fw_shared_gpu_addr), 0, indirect);
 	WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
 		UVD, 0, mmUVD_VCPU_NONCACHE_OFFSET0), 0, 0, indirect);
 	WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
-		UVD, 0, mmUVD_VCPU_NONCACHE_SIZE0), 0, 0, indirect);
+		UVD, 0, mmUVD_VCPU_NONCACHE_SIZE0),
+		AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_fw_shared)), 0, indirect);
 
 	/* VCN global tiling registers */
 	WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
@@ -773,6 +788,7 @@ static void vcn_v2_0_enable_static_power_gating(struct amdgpu_device *adev)
 
 static int vcn_v2_0_start_dpg_mode(struct amdgpu_device *adev, bool indirect)
 {
+	volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst->fw_shared_cpu_addr;
 	struct amdgpu_ring *ring = &adev->vcn.inst->ring_dec;
 	uint32_t rb_bufsz, tmp;
 
@@ -872,6 +888,12 @@ static int vcn_v2_0_start_dpg_mode(struct amdgpu_device *adev, bool indirect)
 	tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
 	WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_CNTL, tmp);
 
+	/* Stall DPG before WPTR/RPTR reset */
+	WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_POWER_STATUS),
+		UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK,
+		~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK);
+	fw_shared->multi_queue.decode_queue_mode |= FW_QUEUE_RING_RESET;
+
 	/* set the write pointer delay */
 	WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR_CNTL, 0);
 
@@ -894,11 +916,16 @@ static int vcn_v2_0_start_dpg_mode(struct amdgpu_device *adev, bool indirect)
 	WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR,
 		lower_32_bits(ring->wptr));
 
+	fw_shared->multi_queue.decode_queue_mode &= ~FW_QUEUE_RING_RESET;
+	/* Unstall DPG */
+	WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_POWER_STATUS),
+		0, ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK);
 	return 0;
 }
 
 static int vcn_v2_0_start(struct amdgpu_device *adev)
 {
+	volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst->fw_shared_cpu_addr;
 	struct amdgpu_ring *ring = &adev->vcn.inst->ring_dec;
 	uint32_t rb_bufsz, tmp;
 	uint32_t lmi_swap_cntl;
@@ -1033,6 +1060,7 @@ static int vcn_v2_0_start(struct amdgpu_device *adev)
 	tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
 	WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_CNTL, tmp);
 
+	fw_shared->multi_queue.decode_queue_mode |= FW_QUEUE_RING_RESET;
 	/* programm the RB_BASE for ring buffer */
 	WREG32_SOC15(UVD, 0, mmUVD_LMI_RBC_RB_64BIT_BAR_LOW,
 		lower_32_bits(ring->gpu_addr));
@@ -1045,20 +1073,25 @@ static int vcn_v2_0_start(struct amdgpu_device *adev)
 	ring->wptr = RREG32_SOC15(UVD, 0, mmUVD_RBC_RB_RPTR);
 	WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR,
 			lower_32_bits(ring->wptr));
+	fw_shared->multi_queue.decode_queue_mode &= ~FW_QUEUE_RING_RESET;
 
+	fw_shared->multi_queue.encode_generalpurpose_queue_mode |= FW_QUEUE_RING_RESET;
 	ring = &adev->vcn.inst->ring_enc[0];
 	WREG32_SOC15(UVD, 0, mmUVD_RB_RPTR, lower_32_bits(ring->wptr));
 	WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
 	WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_LO, ring->gpu_addr);
 	WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
 	WREG32_SOC15(UVD, 0, mmUVD_RB_SIZE, ring->ring_size / 4);
+	fw_shared->multi_queue.encode_generalpurpose_queue_mode &= ~FW_QUEUE_RING_RESET;
 
+	fw_shared->multi_queue.encode_lowlatency_queue_mode |= FW_QUEUE_RING_RESET;
 	ring = &adev->vcn.inst->ring_enc[1];
 	WREG32_SOC15(UVD, 0, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr));
 	WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
 	WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_LO2, ring->gpu_addr);
 	WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
 	WREG32_SOC15(UVD, 0, mmUVD_RB_SIZE2, ring->ring_size / 4);
+	fw_shared->multi_queue.encode_lowlatency_queue_mode &= ~FW_QUEUE_RING_RESET;
 
 	return 0;
 }
@@ -1180,6 +1213,7 @@ static int vcn_v2_0_pause_dpg_mode(struct amdgpu_device *adev,
 				UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code);
 
 			if (!ret_code) {
+				volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst->fw_shared_cpu_addr;
 				/* pause DPG */
 				reg_data |= UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;
 				WREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE, reg_data);
@@ -1189,23 +1223,38 @@ static int vcn_v2_0_pause_dpg_mode(struct amdgpu_device *adev,
 					   UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK,
 					   UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK, ret_code);
 
+				/* Stall DPG before WPTR/RPTR reset */
+				WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_POWER_STATUS),
+					   UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK,
+					   ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK);
 				/* Restore */
+				fw_shared->multi_queue.encode_generalpurpose_queue_mode |= FW_QUEUE_RING_RESET;
 				ring = &adev->vcn.inst->ring_enc[0];
+				ring->wptr = 0;
 				WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_LO, ring->gpu_addr);
 				WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
 				WREG32_SOC15(UVD, 0, mmUVD_RB_SIZE, ring->ring_size / 4);
 				WREG32_SOC15(UVD, 0, mmUVD_RB_RPTR, lower_32_bits(ring->wptr));
 				WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
+				fw_shared->multi_queue.encode_generalpurpose_queue_mode &= ~FW_QUEUE_RING_RESET;
 
+				fw_shared->multi_queue.encode_lowlatency_queue_mode |= FW_QUEUE_RING_RESET;
 				ring = &adev->vcn.inst->ring_enc[1];
+				ring->wptr = 0;
 				WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_LO2, ring->gpu_addr);
 				WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
 				WREG32_SOC15(UVD, 0, mmUVD_RB_SIZE2, ring->ring_size / 4);
 				WREG32_SOC15(UVD, 0, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr));
 				WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
+				fw_shared->multi_queue.encode_lowlatency_queue_mode &= ~FW_QUEUE_RING_RESET;
 
+				fw_shared->multi_queue.decode_queue_mode |= FW_QUEUE_RING_RESET;
 				WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR,
 					   RREG32_SOC15(UVD, 0, mmUVD_SCRATCH2) & 0x7FFFFFFF);
+				fw_shared->multi_queue.decode_queue_mode &= ~FW_QUEUE_RING_RESET;
+				/* Unstall DPG */
+				WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_POWER_STATUS),
+					   0, ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK);
 
 				SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS,
 					   UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON,
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c b/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c
index c6363f5ad564..0fa1c5cec439 100644
--- a/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c
+++ b/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c
@@ -165,6 +165,8 @@ static int vcn_v2_5_sw_init(void *handle)
 		return r;
 
 	for (j = 0; j < adev->vcn.num_vcn_inst; j++) {
+		volatile struct amdgpu_fw_shared *fw_shared;
+
 		if (adev->vcn.harvest_config & (1 << j))
 			continue;
 		adev->vcn.internal.context_id = mmUVD_CONTEXT_ID_INTERNAL_OFFSET;
@@ -191,7 +193,8 @@ static int vcn_v2_5_sw_init(void *handle)
 		ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) +
 				(amdgpu_sriov_vf(adev) ? 2*j : 8*j);
 		sprintf(ring->name, "vcn_dec_%d", j);
-		r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst[j].irq, 0);
+		r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst[j].irq,
+				     0, AMDGPU_RING_PRIO_DEFAULT);
 		if (r)
 			return r;
 
@@ -203,10 +206,15 @@ static int vcn_v2_5_sw_init(void *handle)
 					(amdgpu_sriov_vf(adev) ? (1 + i + 2*j) : (2 + i + 8*j));
 
 			sprintf(ring->name, "vcn_enc_%d.%d", j, i);
-			r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst[j].irq, 0);
+			r = amdgpu_ring_init(adev, ring, 512,
+					     &adev->vcn.inst[j].irq, 0,
+					     AMDGPU_RING_PRIO_DEFAULT);
 			if (r)
 				return r;
 		}
+
+		fw_shared = adev->vcn.inst[j].fw_shared_cpu_addr;
+		fw_shared->present_flag_0 = cpu_to_le32(AMDGPU_VCN_MULTI_QUEUE_FLAG);
 	}
 
 	if (amdgpu_sriov_vf(adev)) {
@@ -230,8 +238,16 @@ static int vcn_v2_5_sw_init(void *handle)
  */
 static int vcn_v2_5_sw_fini(void *handle)
 {
-	int r;
+	int i, r;
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+	volatile struct amdgpu_fw_shared *fw_shared;
+
+	for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
+		if (adev->vcn.harvest_config & (1 << i))
+			continue;
+		fw_shared = adev->vcn.inst[i].fw_shared_cpu_addr;
+		fw_shared->present_flag_0 = 0;
+	}
 
 	if (amdgpu_sriov_vf(adev))
 		amdgpu_virt_free_mm_table(adev);
@@ -308,25 +324,16 @@ static int vcn_v2_5_hw_init(void *handle)
 static int vcn_v2_5_hw_fini(void *handle)
 {
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
-	struct amdgpu_ring *ring;
-	int i, j;
+	int i;
 
 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
 		if (adev->vcn.harvest_config & (1 << i))
 			continue;
-		ring = &adev->vcn.inst[i].ring_dec;
 
 		if ((adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) ||
 		    (adev->vcn.cur_state != AMD_PG_STATE_GATE &&
 		     RREG32_SOC15(VCN, i, mmUVD_STATUS)))
 			vcn_v2_5_set_powergating_state(adev, AMD_PG_STATE_GATE);
-
-		ring->sched.ready = false;
-
-		for (j = 0; j < adev->vcn.num_enc_rings; ++j) {
-			ring = &adev->vcn.inst[i].ring_enc[j];
-			ring->sched.ready = false;
-		}
 	}
 
 	return 0;
@@ -424,6 +431,15 @@ static void vcn_v2_5_mc_resume(struct amdgpu_device *adev)
 			upper_32_bits(adev->vcn.inst[i].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE));
 		WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_OFFSET2, 0);
 		WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_SIZE2, AMDGPU_VCN_CONTEXT_SIZE);
+
+		/* non-cache window */
+		WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_NC0_64BIT_BAR_LOW,
+			lower_32_bits(adev->vcn.inst[i].fw_shared_gpu_addr));
+		WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH,
+			upper_32_bits(adev->vcn.inst[i].fw_shared_gpu_addr));
+		WREG32_SOC15(UVD, i, mmUVD_VCPU_NONCACHE_OFFSET0, 0);
+		WREG32_SOC15(UVD, i, mmUVD_VCPU_NONCACHE_SIZE0,
+			AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_fw_shared)));
 	}
 }
 
@@ -507,13 +523,16 @@ static void vcn_v2_5_mc_resume_dpg_mode(struct amdgpu_device *adev, int inst_idx
 
 	/* non-cache window */
 	WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-		UVD, 0, mmUVD_LMI_VCPU_NC0_64BIT_BAR_LOW), 0, 0, indirect);
+		UVD, 0, mmUVD_LMI_VCPU_NC0_64BIT_BAR_LOW),
+		lower_32_bits(adev->vcn.inst[inst_idx].fw_shared_gpu_addr), 0, indirect);
 	WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-		UVD, 0, mmUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH), 0, 0, indirect);
+		UVD, 0, mmUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH),
+		upper_32_bits(adev->vcn.inst[inst_idx].fw_shared_gpu_addr), 0, indirect);
 	WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
 		UVD, 0, mmUVD_VCPU_NONCACHE_OFFSET0), 0, 0, indirect);
 	WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-		UVD, 0, mmUVD_VCPU_NONCACHE_SIZE0), 0, 0, indirect);
+		UVD, 0, mmUVD_VCPU_NONCACHE_SIZE0),
+		AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_fw_shared)), 0, indirect);
 
 	/* VCN global tiling registers */
 	WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
@@ -750,6 +769,7 @@ static void vcn_v2_5_enable_clock_gating(struct amdgpu_device *adev)
 
 static int vcn_v2_5_start_dpg_mode(struct amdgpu_device *adev, int inst_idx, bool indirect)
 {
+	volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst[inst_idx].fw_shared_cpu_addr;
 	struct amdgpu_ring *ring;
 	uint32_t rb_bufsz, tmp;
 
@@ -855,6 +875,12 @@ static int vcn_v2_5_start_dpg_mode(struct amdgpu_device *adev, int inst_idx, boo
 	tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
 	WREG32_SOC15(UVD, inst_idx, mmUVD_RBC_RB_CNTL, tmp);
 
+	/* Stall DPG before WPTR/RPTR reset */
+	WREG32_P(SOC15_REG_OFFSET(UVD, inst_idx, mmUVD_POWER_STATUS),
+		UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK,
+		~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK);
+	fw_shared->multi_queue.decode_queue_mode |= FW_QUEUE_RING_RESET;
+
 	/* set the write pointer delay */
 	WREG32_SOC15(UVD, inst_idx, mmUVD_RBC_RB_WPTR_CNTL, 0);
 
@@ -877,6 +903,11 @@ static int vcn_v2_5_start_dpg_mode(struct amdgpu_device *adev, int inst_idx, boo
 	WREG32_SOC15(UVD, inst_idx, mmUVD_RBC_RB_WPTR,
 		lower_32_bits(ring->wptr));
 
+	fw_shared->multi_queue.decode_queue_mode &= ~FW_QUEUE_RING_RESET;
+	/* Unstall DPG */
+	WREG32_P(SOC15_REG_OFFSET(UVD, inst_idx, mmUVD_POWER_STATUS),
+		0, ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK);
+
 	return 0;
 }
 
@@ -962,6 +993,7 @@ static int vcn_v2_5_start(struct amdgpu_device *adev)
 	vcn_v2_5_mc_resume(adev);
 
 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
+		volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst[i].fw_shared_cpu_addr;
 		if (adev->vcn.harvest_config & (1 << i))
 			continue;
 		/* VCN global tiling registers */
@@ -1035,6 +1067,7 @@ static int vcn_v2_5_start(struct amdgpu_device *adev)
 		tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
 		WREG32_SOC15(UVD, i, mmUVD_RBC_RB_CNTL, tmp);
 
+		fw_shared->multi_queue.decode_queue_mode |= FW_QUEUE_RING_RESET;
 		/* programm the RB_BASE for ring buffer */
 		WREG32_SOC15(UVD, i, mmUVD_LMI_RBC_RB_64BIT_BAR_LOW,
 			lower_32_bits(ring->gpu_addr));
@@ -1047,19 +1080,25 @@ static int vcn_v2_5_start(struct amdgpu_device *adev)
 		ring->wptr = RREG32_SOC15(UVD, i, mmUVD_RBC_RB_RPTR);
 		WREG32_SOC15(UVD, i, mmUVD_RBC_RB_WPTR,
 				lower_32_bits(ring->wptr));
+		fw_shared->multi_queue.decode_queue_mode &= ~FW_QUEUE_RING_RESET;
+
+		fw_shared->multi_queue.encode_generalpurpose_queue_mode |= FW_QUEUE_RING_RESET;
 		ring = &adev->vcn.inst[i].ring_enc[0];
 		WREG32_SOC15(UVD, i, mmUVD_RB_RPTR, lower_32_bits(ring->wptr));
 		WREG32_SOC15(UVD, i, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
 		WREG32_SOC15(UVD, i, mmUVD_RB_BASE_LO, ring->gpu_addr);
 		WREG32_SOC15(UVD, i, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
 		WREG32_SOC15(UVD, i, mmUVD_RB_SIZE, ring->ring_size / 4);
+		fw_shared->multi_queue.encode_generalpurpose_queue_mode &= ~FW_QUEUE_RING_RESET;
 
+		fw_shared->multi_queue.encode_lowlatency_queue_mode |= FW_QUEUE_RING_RESET;
 		ring = &adev->vcn.inst[i].ring_enc[1];
 		WREG32_SOC15(UVD, i, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr));
 		WREG32_SOC15(UVD, i, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
 		WREG32_SOC15(UVD, i, mmUVD_RB_BASE_LO2, ring->gpu_addr);
 		WREG32_SOC15(UVD, i, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
 		WREG32_SOC15(UVD, i, mmUVD_RB_SIZE2, ring->ring_size / 4);
+		fw_shared->multi_queue.encode_lowlatency_queue_mode &= ~FW_QUEUE_RING_RESET;
 	}
 
 	return 0;
@@ -1380,6 +1419,8 @@ static int vcn_v2_5_pause_dpg_mode(struct amdgpu_device *adev,
 				UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code);
 
 			if (!ret_code) {
+				volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst[inst_idx].fw_shared_cpu_addr;
+
 				/* pause DPG */
 				reg_data |= UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;
 				WREG32_SOC15(UVD, inst_idx, mmUVD_DPG_PAUSE, reg_data);
@@ -1389,23 +1430,40 @@ static int vcn_v2_5_pause_dpg_mode(struct amdgpu_device *adev,
 					   UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK,
 					   UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK, ret_code);
 
+				/* Stall DPG before WPTR/RPTR reset */
+				WREG32_P(SOC15_REG_OFFSET(UVD, inst_idx, mmUVD_POWER_STATUS),
+					   UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK,
+					   ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK);
+
 				/* Restore */
+				fw_shared->multi_queue.encode_generalpurpose_queue_mode |= FW_QUEUE_RING_RESET;
 				ring = &adev->vcn.inst[inst_idx].ring_enc[0];
+				ring->wptr = 0;
 				WREG32_SOC15(UVD, inst_idx, mmUVD_RB_BASE_LO, ring->gpu_addr);
 				WREG32_SOC15(UVD, inst_idx, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
 				WREG32_SOC15(UVD, inst_idx, mmUVD_RB_SIZE, ring->ring_size / 4);
 				WREG32_SOC15(UVD, inst_idx, mmUVD_RB_RPTR, lower_32_bits(ring->wptr));
 				WREG32_SOC15(UVD, inst_idx, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
+				fw_shared->multi_queue.encode_generalpurpose_queue_mode &= ~FW_QUEUE_RING_RESET;
 
+				fw_shared->multi_queue.encode_lowlatency_queue_mode |= FW_QUEUE_RING_RESET;
 				ring = &adev->vcn.inst[inst_idx].ring_enc[1];
+				ring->wptr = 0;
 				WREG32_SOC15(UVD, inst_idx, mmUVD_RB_BASE_LO2, ring->gpu_addr);
 				WREG32_SOC15(UVD, inst_idx, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
 				WREG32_SOC15(UVD, inst_idx, mmUVD_RB_SIZE2, ring->ring_size / 4);
 				WREG32_SOC15(UVD, inst_idx, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr));
 				WREG32_SOC15(UVD, inst_idx, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
+				fw_shared->multi_queue.encode_lowlatency_queue_mode &= ~FW_QUEUE_RING_RESET;
 
+				fw_shared->multi_queue.decode_queue_mode |= FW_QUEUE_RING_RESET;
 				WREG32_SOC15(UVD, inst_idx, mmUVD_RBC_RB_WPTR,
 					   RREG32_SOC15(UVD, inst_idx, mmUVD_SCRATCH2) & 0x7FFFFFFF);
+				fw_shared->multi_queue.decode_queue_mode &= ~FW_QUEUE_RING_RESET;
+
+				/* Unstall DPG */
+				WREG32_P(SOC15_REG_OFFSET(UVD, inst_idx, mmUVD_POWER_STATUS),
+					   0, ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK);
 
 				SOC15_WAIT_ON_RREG(UVD, inst_idx, mmUVD_POWER_STATUS,
 					   UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON, UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code);
diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c
index 78b35901643b..af8986a55354 100644
--- a/drivers/gpu/drm/amd/amdgpu/vi.c
+++ b/drivers/gpu/drm/amd/amdgpu/vi.c
@@ -448,27 +448,6 @@ static bool vi_read_bios_from_rom(struct amdgpu_device *adev,
 	return true;
 }
 
-static void vi_detect_hw_virtualization(struct amdgpu_device *adev)
-{
-	uint32_t reg = 0;
-
-	if (adev->asic_type == CHIP_TONGA ||
-	    adev->asic_type == CHIP_FIJI) {
-	       reg = RREG32(mmBIF_IOV_FUNC_IDENTIFIER);
-	       /* bit0: 0 means pf and 1 means vf */
-	       if (REG_GET_FIELD(reg, BIF_IOV_FUNC_IDENTIFIER, FUNC_IDENTIFIER))
-		       adev->virt.caps |= AMDGPU_SRIOV_CAPS_IS_VF;
-	       /* bit31: 0 means disable IOV and 1 means enable */
-	       if (REG_GET_FIELD(reg, BIF_IOV_FUNC_IDENTIFIER, IOV_ENABLE))
-		       adev->virt.caps |= AMDGPU_SRIOV_CAPS_ENABLE_IOV;
-	}
-
-	if (reg == 0) {
-		if (is_virtual_machine()) /* passthrough mode exclus sr-iov mode */
-			adev->virt.caps |= AMDGPU_PASSTHROUGH_MODE;
-	}
-}
-
 static const struct amdgpu_allowed_register_entry vi_allowed_read_registers[] = {
 	{mmGRBM_STATUS},
 	{mmGRBM_STATUS2},
@@ -765,8 +744,6 @@ static int vi_asic_reset(struct amdgpu_device *adev)
 	int r;
 
 	if (vi_asic_reset_method(adev) == AMD_RESET_METHOD_BACO) {
-		if (!adev->in_suspend)
-			amdgpu_inc_vram_lost(adev);
 		r = amdgpu_dpm_baco_reset(adev);
 	} else {
 		r = vi_asic_pci_config_reset(adev);
@@ -1730,9 +1707,6 @@ static const struct amdgpu_ip_block_version vi_common_ip_block =
 
 int vi_set_ip_blocks(struct amdgpu_device *adev)
 {
-	/* in early init stage, vbios code won't work */
-	vi_detect_hw_virtualization(adev);
-
 	if (amdgpu_sriov_vf(adev))
 		adev->virt.ops = &xgpu_vi_virt_ops;
 
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
index 0ec5f25adf56..f8fa03a12add 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
@@ -1584,6 +1584,45 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep,
 	return err;
 }
 
+static int kfd_ioctl_alloc_queue_gws(struct file *filep,
+		struct kfd_process *p, void *data)
+{
+	int retval;
+	struct kfd_ioctl_alloc_queue_gws_args *args = data;
+	struct queue *q;
+	struct kfd_dev *dev;
+
+	mutex_lock(&p->mutex);
+	q = pqm_get_user_queue(&p->pqm, args->queue_id);
+
+	if (q) {
+		dev = q->device;
+	} else {
+		retval = -EINVAL;
+		goto out_unlock;
+	}
+
+	if (!dev->gws) {
+		retval = -ENODEV;
+		goto out_unlock;
+	}
+
+	if (dev->dqm->sched_policy == KFD_SCHED_POLICY_NO_HWS) {
+		retval = -ENODEV;
+		goto out_unlock;
+	}
+
+	retval = pqm_set_gws(&p->pqm, args->queue_id, args->num_gws ? dev->gws : NULL);
+	mutex_unlock(&p->mutex);
+
+	args->first_gws = 0;
+	return retval;
+
+out_unlock:
+	mutex_unlock(&p->mutex);
+	return retval;
+}
+
 static int kfd_ioctl_get_dmabuf_info(struct file *filep,
 		struct kfd_process *p, void *data)
 {
@@ -1786,6 +1825,8 @@ static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = {
 	AMDKFD_IOCTL_DEF(AMDKFD_IOC_IMPORT_DMABUF,
 				kfd_ioctl_import_dmabuf, 0),
 
+	AMDKFD_IOCTL_DEF(AMDKFD_IOC_ALLOC_QUEUE_GWS,
+			kfd_ioctl_alloc_queue_gws, 0),
 };
 
 #define AMDKFD_CORE_IOCTL_COUNT	ARRAY_SIZE(amdkfd_ioctls)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
index 05bc6d96ec52..0491ab2b4a9b 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
@@ -569,6 +569,23 @@ static void kfd_cwsr_init(struct kfd_dev *kfd)
 	}
 }
 
+static int kfd_gws_init(struct kfd_dev *kfd)
+{
+	int ret = 0;
+
+	if (kfd->dqm->sched_policy == KFD_SCHED_POLICY_NO_HWS)
+		return 0;
+
+	if (hws_gws_support
+		|| (kfd->device_info->asic_family >= CHIP_VEGA10
+			&& kfd->device_info->asic_family <= CHIP_RAVEN
+			&& kfd->mec2_fw_version >= 0x1b3))
+		ret = amdgpu_amdkfd_alloc_gws(kfd->kgd,
+				amdgpu_amdkfd_get_num_gws(kfd->kgd), &kfd->gws);
+
+	return ret;
+}
+
 bool kgd2kfd_device_init(struct kfd_dev *kfd,
 			 struct drm_device *ddev,
 			 const struct kgd2kfd_shared_resources *gpu_resources)
@@ -578,6 +595,8 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
 	kfd->ddev = ddev;
 	kfd->mec_fw_version = amdgpu_amdkfd_get_fw_version(kfd->kgd,
 			KGD_ENGINE_MEC1);
+	kfd->mec2_fw_version = amdgpu_amdkfd_get_fw_version(kfd->kgd,
+			KGD_ENGINE_MEC2);
 	kfd->sdma_fw_version = amdgpu_amdkfd_get_fw_version(kfd->kgd,
 			KGD_ENGINE_SDMA1);
 	kfd->shared_resources = *gpu_resources;
@@ -598,13 +617,6 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
 	} else
 		kfd->max_proc_per_quantum = hws_max_conc_proc;
 
-	/* Allocate global GWS that is shared by all KFD processes */
-	if (hws_gws_support && amdgpu_amdkfd_alloc_gws(kfd->kgd,
-			amdgpu_amdkfd_get_num_gws(kfd->kgd), &kfd->gws)) {
-		dev_err(kfd_device, "Could not allocate %d gws\n",
-			amdgpu_amdkfd_get_num_gws(kfd->kgd));
-		goto out;
-	}
 	/* calculate max size of mqds needed for queues */
 	size = max_num_of_queues_per_device *
 			kfd->device_info->mqd_size_aligned;
@@ -662,6 +674,15 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
 		goto device_queue_manager_error;
 	}
 
+	/* If supported on this device, allocate global GWS that is shared
+	 * by all KFD processes
+	 */
+	if (kfd_gws_init(kfd)) {
+		dev_err(kfd_device, "Could not allocate %d gws\n",
+			amdgpu_amdkfd_get_num_gws(kfd->kgd));
+		goto gws_error;
+	}
+
 	if (kfd_iommu_device_init(kfd)) {
 		dev_err(kfd_device, "Error initializing iommuv2\n");
 		goto device_iommu_error;
@@ -691,6 +712,7 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
 kfd_topology_add_device_error:
 kfd_resume_error:
 device_iommu_error:
+gws_error:
 	device_queue_manager_uninit(kfd->dqm);
 device_queue_manager_error:
 	kfd_interrupt_exit(kfd);
@@ -701,7 +723,7 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
 kfd_gtt_sa_init_error:
 	amdgpu_amdkfd_free_gtt_mem(kfd->kgd, kfd->gtt_mem);
 alloc_gtt_mem_failure:
-	if (hws_gws_support)
+	if (kfd->gws)
 		amdgpu_amdkfd_free_gws(kfd->kgd, kfd->gws);
 	dev_err(kfd_device,
 		"device %x:%x NOT added due to errors\n",
@@ -720,7 +742,7 @@ void kgd2kfd_device_exit(struct kfd_dev *kfd)
 		kfd_doorbell_fini(kfd);
 		kfd_gtt_sa_fini(kfd);
 		amdgpu_amdkfd_free_gtt_mem(kfd->kgd, kfd->gtt_mem);
-		if (hws_gws_support)
+		if (kfd->gws)
 			amdgpu_amdkfd_free_gws(kfd->kgd, kfd->gws);
 	}
 
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
index 4a3049841086..49ec566e7e54 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
@@ -282,6 +282,7 @@ struct kfd_dev {
 
 	/* Firmware versions */
 	uint16_t mec_fw_version;
+	uint16_t mec2_fw_version;
 	uint16_t sdma_fw_version;
 
 	/* Maximum process number mapped to HW scheduler */
@@ -923,6 +924,8 @@ int pqm_set_gws(struct process_queue_manager *pqm, unsigned int qid,
 			void *gws);
 struct kernel_queue *pqm_get_kernel_queue(struct process_queue_manager *pqm,
 						unsigned int qid);
+struct queue *pqm_get_user_queue(struct process_queue_manager *pqm,
+						unsigned int qid);
 int pqm_get_wave_state(struct process_queue_manager *pqm,
 		       unsigned int qid,
 		       void __user *ctl_stack,
@@ -1050,7 +1053,7 @@ void kfd_dec_compute_active(struct kfd_dev *dev);
 /* Check with device cgroup if @kfd device is accessible */
 static inline int kfd_devcgroup_check_permission(struct kfd_dev *kfd)
 {
-#if defined(CONFIG_CGROUP_DEVICE)
+#if defined(CONFIG_CGROUP_DEVICE) || defined(CONFIG_CGROUP_BPF)
 	struct drm_device *ddev = kfd->ddev;
 
 	return devcgroup_check_permission(DEVCG_DEV_CHAR, ddev->driver->major,
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
index 084c35f55d59..eb1635ac8988 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
@@ -476,6 +476,15 @@ struct kernel_queue *pqm_get_kernel_queue(
 	return NULL;
 }
 
+struct queue *pqm_get_user_queue(struct process_queue_manager *pqm,
+					unsigned int qid)
+{
+	struct process_queue_node *pqn;
+
+	pqn = get_queue_by_qid(pqm, qid);
+	return pqn ? pqn->q : NULL;
+}
+
 int pqm_get_wave_state(struct process_queue_manager *pqm,
 		       unsigned int qid,
 		       void __user *ctl_stack,
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
index aa0bfa78a667..5db42814dd51 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
@@ -1317,7 +1317,7 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
 				gpu->device_info->num_xgmi_sdma_engines;
 	dev->node_props.num_sdma_queues_per_engine =
 				gpu->device_info->num_sdma_queues_per_engine;
-	dev->node_props.num_gws = (hws_gws_support &&
+	dev->node_props.num_gws = (dev->gpu->gws &&
 		dev->gpu->dqm->sched_policy != KFD_SCHED_POLICY_NO_HWS) ?
 		amdgpu_amdkfd_get_num_gws(dev->gpu->kgd) : 0;
 	dev->node_props.num_cp_queues = get_cp_queues_num(dev->gpu->dqm);
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index f7c5cdc10a70..8b3b735ec339 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -825,8 +825,9 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev)
 				fw_inst_const_size);
 	}
 
-	memcpy(fb_info->fb[DMUB_WINDOW_2_BSS_DATA].cpu_addr, fw_bss_data,
-	       fw_bss_data_size);
+	if (fw_bss_data_size)
+		memcpy(fb_info->fb[DMUB_WINDOW_2_BSS_DATA].cpu_addr,
+		       fw_bss_data, fw_bss_data_size);
 
 	/* Copy firmware bios info into FB memory. */
 	memcpy(fb_info->fb[DMUB_WINDOW_3_VBIOS].cpu_addr, adev->bios,
@@ -1265,6 +1266,10 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev)
 		adev->dm.dmub_fw->data +
 		le32_to_cpu(hdr->header.ucode_array_offset_bytes) +
 		le32_to_cpu(hdr->inst_const_bytes);
+	region_params.fw_inst_const =
+		adev->dm.dmub_fw->data +
+		le32_to_cpu(hdr->header.ucode_array_offset_bytes) +
+		PSP_HEADER_BYTES;
 
 	status = dmub_srv_calc_region_info(dmub_srv, &region_params,
 					   &region_info);
@@ -3304,7 +3309,7 @@ static int fill_dc_scaling_info(const struct drm_plane_state *state,
 }
 
 static int get_fb_info(const struct amdgpu_framebuffer *amdgpu_fb,
-		       uint64_t *tiling_flags)
+		       uint64_t *tiling_flags, bool *tmz_surface)
 {
 	struct amdgpu_bo *rbo = gem_to_amdgpu_bo(amdgpu_fb->base.obj[0]);
 	int r = amdgpu_bo_reserve(rbo, false);
@@ -3319,6 +3324,9 @@ static int get_fb_info(const struct amdgpu_framebuffer *amdgpu_fb,
 	if (tiling_flags)
 		amdgpu_bo_get_tiling_flags(rbo, tiling_flags);
 
+	if (tmz_surface)
+		*tmz_surface = amdgpu_bo_encrypted(rbo);
+
 	amdgpu_bo_unreserve(rbo);
 
 	return r;
@@ -3401,7 +3409,8 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
 			     union dc_tiling_info *tiling_info,
 			     struct plane_size *plane_size,
 			     struct dc_plane_dcc_param *dcc,
-			     struct dc_plane_address *address)
+			     struct dc_plane_address *address,
+			     bool tmz_surface)
 {
 	const struct drm_framebuffer *fb = &afb->base;
 	int ret;
@@ -3411,6 +3420,8 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
 	memset(dcc, 0, sizeof(*dcc));
 	memset(address, 0, sizeof(*address));
 
+	address->tmz_surface = tmz_surface;
+
 	if (format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
 		plane_size->surface_size.x = 0;
 		plane_size->surface_size.y = 0;
@@ -3599,7 +3610,8 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev,
 			    const struct drm_plane_state *plane_state,
 			    const uint64_t tiling_flags,
 			    struct dc_plane_info *plane_info,
-			    struct dc_plane_address *address)
+			    struct dc_plane_address *address,
+			    bool tmz_surface)
 {
 	const struct drm_framebuffer *fb = plane_state->fb;
 	const struct amdgpu_framebuffer *afb =
@@ -3681,7 +3693,7 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev,
 					   plane_info->rotation, tiling_flags,
 					   &plane_info->tiling_info,
 					   &plane_info->plane_size,
-					   &plane_info->dcc, address);
+					   &plane_info->dcc, address, tmz_surface);
 	if (ret)
 		return ret;
 
@@ -3693,17 +3705,19 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev,
 }
 
 static int fill_dc_plane_attributes(struct amdgpu_device *adev,
-				    struct dc_plane_state *dc_plane_state,
+				    struct dm_plane_state *dm_plane_state,
 				    struct drm_plane_state *plane_state,
 				    struct drm_crtc_state *crtc_state)
 {
 	struct dm_crtc_state *dm_crtc_state = to_dm_crtc_state(crtc_state);
+	struct dc_plane_state *dc_plane_state = dm_plane_state->dc_state;
 	const struct amdgpu_framebuffer *amdgpu_fb =
 		to_amdgpu_framebuffer(plane_state->fb);
 	struct dc_scaling_info scaling_info;
 	struct dc_plane_info plane_info;
 	uint64_t tiling_flags;
 	int ret;
+	bool tmz_surface = false;
 
 	ret = fill_dc_scaling_info(plane_state, &scaling_info);
 	if (ret)
@@ -3714,13 +3728,14 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev,
 	dc_plane_state->clip_rect = scaling_info.clip_rect;
 	dc_plane_state->scaling_quality = scaling_info.scaling_quality;
 
-	ret = get_fb_info(amdgpu_fb, &tiling_flags);
+	ret = get_fb_info(amdgpu_fb, &tiling_flags, &tmz_surface);
 	if (ret)
 		return ret;
 
 	ret = fill_dc_plane_info_and_addr(adev, plane_state, tiling_flags,
 					  &plane_info,
-					  &dc_plane_state->address);
+					  &dc_plane_state->address,
+					  tmz_surface);
 	if (ret)
 		return ret;
 
@@ -3743,7 +3758,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev,
 	 * Always set input transfer function, since plane state is refreshed
 	 * every time.
 	 */
-	ret = amdgpu_dm_update_plane_color_mgmt(dm_crtc_state, dc_plane_state);
+	ret = amdgpu_dm_update_plane_color_mgmt(dm_crtc_state, dm_plane_state);
 	if (ret)
 		return ret;
 
@@ -4664,6 +4679,7 @@ static void amdgpu_dm_connector_destroy(struct drm_connector *connector)
 		i2c_del_adapter(&aconnector->i2c->base);
 		kfree(aconnector->i2c);
 	}
+	kfree(aconnector->dm_dp_aux.aux.name);
 
 	kfree(connector);
 }
@@ -4726,6 +4742,15 @@ amdgpu_dm_connector_late_register(struct drm_connector *connector)
 #if defined(CONFIG_DEBUG_FS)
 	struct amdgpu_dm_connector *amdgpu_dm_connector =
 		to_amdgpu_dm_connector(connector);
+	int r;
+
+	if ((connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
+	    (connector->connector_type == DRM_MODE_CONNECTOR_eDP)) {
+		amdgpu_dm_connector->dm_dp_aux.aux.dev = connector->kdev;
+		r = drm_dp_aux_register(&amdgpu_dm_connector->dm_dp_aux.aux);
+		if (r)
+			return r;
+	}
 
 	connector_debugfs_init(amdgpu_dm_connector);
 #endif
@@ -5332,6 +5357,7 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane,
 	uint64_t tiling_flags;
 	uint32_t domain;
 	int r;
+	bool tmz_surface = false;
 
 	dm_plane_state_old = to_dm_plane_state(plane->state);
 	dm_plane_state_new = to_dm_plane_state(new_state);
@@ -5380,6 +5406,8 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane,
 
 	amdgpu_bo_get_tiling_flags(rbo, &tiling_flags);
 
+	tmz_surface = amdgpu_bo_encrypted(rbo);
+
 	ttm_eu_backoff_reservation(&ticket, &list);
 
 	afb->address = amdgpu_bo_gpu_offset(rbo);
@@ -5394,7 +5422,7 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane,
 			adev, afb, plane_state->format, plane_state->rotation,
 			tiling_flags, &plane_state->tiling_info,
 			&plane_state->plane_size, &plane_state->dcc,
-			&plane_state->address);
+			&plane_state->address, tmz_surface);
 	}
 
 	return 0;
@@ -6092,7 +6120,7 @@ static int amdgpu_dm_connector_init(struct amdgpu_display_manager *dm,
 
 	if (connector_type == DRM_MODE_CONNECTOR_DisplayPort
 		|| connector_type == DRM_MODE_CONNECTOR_eDP)
-		amdgpu_dm_initialize_dp_connector(dm, aconnector);
+		amdgpu_dm_initialize_dp_connector(dm, aconnector, link->link_index);
 
 out_free:
 	if (res) {
@@ -6567,6 +6595,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
 	unsigned long flags;
 	struct amdgpu_bo *abo;
 	uint64_t tiling_flags;
+	bool tmz_surface = false;
 	uint32_t target_vblank, last_flip_vblank;
 	bool vrr_active = amdgpu_dm_vrr_active(acrtc_state);
 	bool pflip_present = false;
@@ -6661,12 +6690,14 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
 
 		amdgpu_bo_get_tiling_flags(abo, &tiling_flags);
 
+		tmz_surface = amdgpu_bo_encrypted(abo);
+
 		amdgpu_bo_unreserve(abo);
 
 		fill_dc_plane_info_and_addr(
 			dm->adev, new_plane_state, tiling_flags,
 			&bundle->plane_infos[planes_count],
-			&bundle->flip_addrs[planes_count].address);
+			&bundle->flip_addrs[planes_count].address, tmz_surface);
 
 		bundle->surface_updates[planes_count].plane_info =
 			&bundle->plane_infos[planes_count];
@@ -7929,16 +7960,6 @@ static int dm_update_plane_state(struct dc *dc,
 		DRM_DEBUG_DRIVER("Enabling DRM plane: %d on DRM crtc %d\n",
 				plane->base.id, new_plane_crtc->base.id);
 
-		ret = fill_dc_plane_attributes(
-			new_plane_crtc->dev->dev_private,
-			dc_new_plane_state,
-			new_plane_state,
-			new_crtc_state);
-		if (ret) {
-			dc_plane_state_release(dc_new_plane_state);
-			return ret;
-		}
-
 		ret = dm_atomic_get_state(state, &dm_state);
 		if (ret) {
 			dc_plane_state_release(dc_new_plane_state);
@@ -7964,6 +7985,14 @@ static int dm_update_plane_state(struct dc *dc,
 
 		dm_new_plane_state->dc_state = dc_new_plane_state;
 
+		ret = fill_dc_plane_attributes(
+			new_plane_crtc->dev->dev_private,
+			dm_new_plane_state,
+			new_plane_state,
+			new_crtc_state);
+		if (ret)
+			return ret;
+
 		/* Tell DC to do a full surface update every time there
 		 * is a plane change. Inefficient, but works for now.
 		 */
@@ -8034,6 +8063,7 @@ dm_determine_update_type_for_commit(struct amdgpu_display_manager *dm,
 			struct dc_flip_addrs *flip_addr = &bundle->flip_addrs[num_plane];
 			struct dc_scaling_info *scaling_info = &bundle->scaling_infos[num_plane];
 			uint64_t tiling_flags;
+			bool tmz_surface = false;
 
 			new_plane_crtc = new_plane_state->crtc;
 			new_dm_plane_state = to_dm_plane_state(new_plane_state);
@@ -8079,14 +8109,14 @@ dm_determine_update_type_for_commit(struct amdgpu_display_manager *dm,
 			bundle->surface_updates[num_plane].scaling_info = scaling_info;
 
 			if (amdgpu_fb) {
-				ret = get_fb_info(amdgpu_fb, &tiling_flags);
+				ret = get_fb_info(amdgpu_fb, &tiling_flags, &tmz_surface);
 				if (ret)
 					goto cleanup;
 
 				ret = fill_dc_plane_info_and_addr(
 					dm->adev, new_plane_state, tiling_flags,
 					plane_info,
-					&flip_addr->address);
+					&flip_addr->address, tmz_surface);
 				if (ret)
 					goto cleanup;
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index 5cab3e65d992..cdf0dc1b2e05 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -481,7 +481,7 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector *connector,
 void amdgpu_dm_init_color_mod(void);
 int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc);
 int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
-				      struct dc_plane_state *dc_plane_state);
+				      struct dm_plane_state *plane);
 
 void amdgpu_dm_update_connector_after_detect(
 		struct amdgpu_dm_connector *aconnector);
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 2233d293a707..6b58761e4b04 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -416,9 +416,10 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc)
  * Returns 0 on success.
  */
 int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
-				      struct dc_plane_state *dc_plane_state)
+				      struct dm_plane_state *plane)
 {
 	const struct drm_color_lut *degamma_lut;
+	struct dc_plane_state *dc_plane_state = plane->dc_state;
 	uint32_t degamma_size;
 	int r;
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
index 0461fecd68db..4b695f6a80c6 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
@@ -838,6 +838,44 @@ static int vrr_range_show(struct seq_file *m, void *data)
 	return 0;
 }
 
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+/*
+ * Returns the HDCP capability of the Display (1.4 for now).
+ *
+ * NOTE* Not all HDMI displays report their HDCP caps even when they are capable.
+ * Since its rare for a display to not be HDCP 1.4 capable, we set HDMI as always capable.
+ *
+ * Example usage: cat /sys/kernel/debug/dri/0/DP-1/hdcp_sink_capability
+ *		or cat /sys/kernel/debug/dri/0/HDMI-A-1/hdcp_sink_capability
+ */
+static int hdcp_sink_capability_show(struct seq_file *m, void *data)
+{
+	struct drm_connector *connector = m->private;
+	struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
+	bool hdcp_cap, hdcp2_cap;
+
+	if (connector->status != connector_status_connected)
+		return -ENODEV;
+
+	seq_printf(m, "%s:%d HDCP version: ", connector->name, connector->base.id);
+
+	hdcp_cap = dc_link_is_hdcp14(aconnector->dc_link);
+	hdcp2_cap = dc_link_is_hdcp22(aconnector->dc_link);
+
+
+	if (hdcp_cap)
+		seq_printf(m, "%s ", "HDCP1.4");
+	if (hdcp2_cap)
+		seq_printf(m, "%s ", "HDCP2.2");
+
+	if (!hdcp_cap && !hdcp2_cap)
+		seq_printf(m, "%s ", "None");
+
+	seq_puts(m, "\n");
+
+	return 0;
+}
+#endif
 /* function description
  *
  * generic SDP message access for testing
@@ -964,6 +1002,9 @@ DEFINE_SHOW_ATTRIBUTE(dmub_fw_state);
 DEFINE_SHOW_ATTRIBUTE(dmub_tracebuffer);
 DEFINE_SHOW_ATTRIBUTE(output_bpc);
 DEFINE_SHOW_ATTRIBUTE(vrr_range);
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+DEFINE_SHOW_ATTRIBUTE(hdcp_sink_capability);
+#endif
 
 static const struct file_operations dp_link_settings_debugfs_fops = {
 	.owner = THIS_MODULE,
@@ -1019,12 +1060,23 @@ static const struct {
 		{"test_pattern", &dp_phy_test_pattern_fops},
 		{"output_bpc", &output_bpc_fops},
 		{"vrr_range", &vrr_range_fops},
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+		{"hdcp_sink_capability", &hdcp_sink_capability_fops},
+#endif
 		{"sdp_message", &sdp_message_fops},
 		{"aux_dpcd_address", &dp_dpcd_address_debugfs_fops},
 		{"aux_dpcd_size", &dp_dpcd_size_debugfs_fops},
 		{"aux_dpcd_data", &dp_dpcd_data_debugfs_fops}
 };
 
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+static const struct {
+	char *name;
+	const struct file_operations *fops;
+} hdmi_debugfs_entries[] = {
+		{"hdcp_sink_capability", &hdcp_sink_capability_fops}
+};
+#endif
 /*
  * Force YUV420 output if available from the given mode
  */
@@ -1093,6 +1145,15 @@ void connector_debugfs_init(struct amdgpu_dm_connector *connector)
 	connector->debugfs_dpcd_address = 0;
 	connector->debugfs_dpcd_size = 0;
 
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+	if (connector->base.connector_type == DRM_MODE_CONNECTOR_HDMIA) {
+		for (i = 0; i < ARRAY_SIZE(hdmi_debugfs_entries); i++) {
+			debugfs_create_file(hdmi_debugfs_entries[i].name,
+					    0644, dir, connector,
+					    hdmi_debugfs_entries[i].fops);
+		}
+	}
+#endif
 }
 
 /*
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index c20fb08c450b..c407f06cd1f5 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -445,7 +445,7 @@ bool dm_helpers_dp_read_dpcd(
 	struct amdgpu_dm_connector *aconnector = link->priv;
 
 	if (!aconnector) {
-		DRM_ERROR("Failed to find connector for link!");
+		DC_LOG_DC("Failed to find connector for link!\n");
 		return false;
 	}
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index fabbe78d5aef..ae0a7ef1d595 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -41,53 +41,10 @@
 #include "amdgpu_dm_debugfs.h"
 #endif
 
-
 #if defined(CONFIG_DRM_AMD_DC_DCN)
 #include "dc/dcn20/dcn20_resource.h"
 #endif
 
-/* #define TRACE_DPCD */
-
-#ifdef TRACE_DPCD
-#define SIDE_BAND_MSG(address) (address >= DP_SIDEBAND_MSG_DOWN_REQ_BASE && address < DP_SINK_COUNT_ESI)
-
-static inline char *side_band_msg_type_to_str(uint32_t address)
-{
-	static char str[10] = {0};
-
-	if (address < DP_SIDEBAND_MSG_UP_REP_BASE)
-		strcpy(str, "DOWN_REQ");
-	else if (address < DP_SIDEBAND_MSG_DOWN_REP_BASE)
-		strcpy(str, "UP_REP");
-	else if (address < DP_SIDEBAND_MSG_UP_REQ_BASE)
-		strcpy(str, "DOWN_REP");
-	else
-		strcpy(str, "UP_REQ");
-
-	return str;
-}
-
-static void log_dpcd(uint8_t type,
-		     uint32_t address,
-		     uint8_t *data,
-		     uint32_t size,
-		     bool res)
-{
-	DRM_DEBUG_KMS("Op: %s, addr: %04x, SideBand Msg: %s, Op res: %s\n",
-			(type == DP_AUX_NATIVE_READ) ||
-			(type == DP_AUX_I2C_READ) ?
-					"Read" : "Write",
-			address,
-			SIDE_BAND_MSG(address) ?
-					side_band_msg_type_to_str(address) : "Nop",
-			res ? "OK" : "Fail");
-
-	if (res) {
-		print_hex_dump(KERN_INFO, "Body: ", DUMP_PREFIX_NONE, 16, 1, data, size, false);
-	}
-}
-#endif
-
 static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,
 				  struct drm_dp_aux_msg *msg)
 {
@@ -136,17 +93,23 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,
 static void
 dm_dp_mst_connector_destroy(struct drm_connector *connector)
 {
-	struct amdgpu_dm_connector *amdgpu_dm_connector = to_amdgpu_dm_connector(connector);
-	struct amdgpu_encoder *amdgpu_encoder = amdgpu_dm_connector->mst_encoder;
+	struct amdgpu_dm_connector *aconnector =
+		to_amdgpu_dm_connector(connector);
+	struct amdgpu_encoder *amdgpu_encoder = aconnector->mst_encoder;
 
-	kfree(amdgpu_dm_connector->edid);
-	amdgpu_dm_connector->edid = NULL;
+	if (aconnector->dc_sink) {
+		dc_link_remove_remote_sink(aconnector->dc_link,
+					   aconnector->dc_sink);
+		dc_sink_release(aconnector->dc_sink);
+	}
+
+	kfree(aconnector->edid);
 
 	drm_encoder_cleanup(&amdgpu_encoder->base);
 	kfree(amdgpu_encoder);
 	drm_connector_cleanup(connector);
-	drm_dp_mst_put_port_malloc(amdgpu_dm_connector->port);
-	kfree(amdgpu_dm_connector);
+	drm_dp_mst_put_port_malloc(aconnector->port);
+	kfree(aconnector);
 }
 
 static int
@@ -156,16 +119,16 @@ amdgpu_dm_mst_connector_late_register(struct drm_connector *connector)
 		to_amdgpu_dm_connector(connector);
 	int r;
 
-	amdgpu_dm_connector->dm_dp_aux.aux.dev = connector->kdev;
-	r = drm_dp_aux_register(&amdgpu_dm_connector->dm_dp_aux.aux);
-	if (r)
+	r = drm_dp_mst_connector_late_register(connector,
+					       amdgpu_dm_connector->port);
+	if (r < 0)
 		return r;
 
 #if defined(CONFIG_DEBUG_FS)
 	connector_debugfs_init(amdgpu_dm_connector);
 #endif
 
-	return r;
+	return 0;
 }
 
 static void
@@ -435,46 +398,22 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
 	 */
 	amdgpu_dm_connector_funcs_reset(connector);
 
-	DRM_INFO("DM_MST: added connector: %p [id: %d] [master: %p]\n",
-		 aconnector, connector->base.id, aconnector->mst_port);
-
 	drm_dp_mst_get_port_malloc(port);
 
-	DRM_DEBUG_KMS(":%d\n", connector->base.id);
-
 	return connector;
 }
 
-static void dm_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
-					struct drm_connector *connector)
-{
-	struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
-
-	DRM_INFO("DM_MST: Disabling connector: %p [id: %d] [master: %p]\n",
-		 aconnector, connector->base.id, aconnector->mst_port);
-
-	if (aconnector->dc_sink) {
-		amdgpu_dm_update_freesync_caps(connector, NULL);
-		dc_link_remove_remote_sink(aconnector->dc_link,
-					   aconnector->dc_sink);
-		dc_sink_release(aconnector->dc_sink);
-		aconnector->dc_sink = NULL;
-		aconnector->dc_link->cur_link_settings.lane_count = 0;
-	}
-
-	drm_connector_unregister(connector);
-	drm_connector_put(connector);
-}
-
 static const struct drm_dp_mst_topology_cbs dm_mst_cbs = {
 	.add_connector = dm_dp_add_mst_connector,
-	.destroy_connector = dm_dp_destroy_mst_connector,
 };
 
 void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm,
-				       struct amdgpu_dm_connector *aconnector)
+				       struct amdgpu_dm_connector *aconnector,
+				       int link_index)
 {
-	aconnector->dm_dp_aux.aux.name = "dmdc";
+	aconnector->dm_dp_aux.aux.name =
+		kasprintf(GFP_KERNEL, "AMDGPU DM aux hw bus %d",
+			  link_index);
 	aconnector->dm_dp_aux.aux.transfer = dm_dp_aux_transfer;
 	aconnector->dm_dp_aux.ddc_service = aconnector->dc_link->ddc;
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h
index d6813ce67bbd..d2c56579a2cc 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h
@@ -32,7 +32,8 @@ struct amdgpu_dm_connector;
 int dm_mst_get_pbn_divider(struct dc_link *link);
 
 void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm,
-				       struct amdgpu_dm_connector *aconnector);
+				       struct amdgpu_dm_connector *aconnector,
+				       int link_index);
 
 #if defined(CONFIG_DRM_AMD_DC_DCN)
 bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state,
diff --git a/drivers/gpu/drm/amd/display/dc/basics/Makefile b/drivers/gpu/drm/amd/display/dc/basics/Makefile
index 7ad0cad0f4ef..01b99e0d788e 100644
--- a/drivers/gpu/drm/amd/display/dc/basics/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/basics/Makefile
@@ -24,8 +24,7 @@
 # It provides the general basic services required by other DAL
 # subcomponents.
 
-BASICS = conversion.o fixpt31_32.o \
-	log_helpers.o vector.o dc_common.o
+BASICS = conversion.o fixpt31_32.o vector.o dc_common.o
 
 AMD_DAL_BASICS = $(addprefix $(AMDDALPATH)/dc/basics/,$(BASICS))
 
diff --git a/drivers/gpu/drm/amd/display/dc/basics/log_helpers.c b/drivers/gpu/drm/amd/display/dc/basics/log_helpers.c
deleted file mode 100644
index 26583f346c39..000000000000
--- a/drivers/gpu/drm/amd/display/dc/basics/log_helpers.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2012-16 Advanced Micro Devices, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: AMD
- *
- */
-
-#include "core_types.h"
-#include "logger.h"
-#include "include/logger_interface.h"
-#include "dm_helpers.h"
-
-void dc_conn_log_hex_linux(const uint8_t *hex_data, int hex_data_count)
-{
-	int i;
-
-	if (hex_data)
-		for (i = 0; i < hex_data_count; i++)
-			DC_LOG_DEBUG("%2.2X ", hex_data[i]);
-}
-
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.c
index 26db1c5d4e4d..b210f8e9d592 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.c
@@ -131,7 +131,7 @@ int dce_get_dp_ref_freq_khz(struct clk_mgr *clk_mgr_base)
 	struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
 	int dprefclk_wdivider;
 	int dprefclk_src_sel;
-	int dp_ref_clk_khz = 600000;
+	int dp_ref_clk_khz;
 	int target_div;
 
 	/* ASSERT DP Reference Clock source is from DFS*/
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 8489f1e56892..508048147278 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -1035,9 +1035,9 @@ static void program_timing_sync(
 				status->timing_sync_info.master = false;
 
 		}
-		/* remove any other pipes with plane as they have already been synced */
+		/* remove any other pipes without plane as they have already been synced */
 		for (j = j + 1; j < group_size; j++) {
-			if (pipe_set[j]->plane_state) {
+			if (!pipe_set[j]->plane_state) {
 				group_size--;
 				pipe_set[j] = pipe_set[group_size];
 				j--;
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index 67cfff1586e9..00f70e43ed76 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -49,7 +49,6 @@
 
 #define DC_LOGGER_INIT(logger)
 
-
 #define LINK_INFO(...) \
 	DC_LOG_HW_HOTPLUG(  \
 		__VA_ARGS__)
@@ -64,11 +63,11 @@
 enum {
 	PEAK_FACTOR_X1000 = 1006,
 	/*
-	* Some receivers fail to train on first try and are good
-	* on subsequent tries. 2 retries should be plenty. If we
-	* don't have a successful training then we don't expect to
-	* ever get one.
-	*/
+	 * Some receivers fail to train on first try and are good
+	 * on subsequent tries. 2 retries should be plenty. If we
+	 * don't have a successful training then we don't expect to
+	 * ever get one.
+	 */
 	LINK_TRAINING_MAX_VERIFY_RETRY = 2
 };
 
@@ -79,7 +78,7 @@ static void dc_link_destruct(struct dc_link *link)
 {
 	int i;
 
-	if (link->hpd_gpio != NULL) {
+	if (link->hpd_gpio) {
 		dal_gpio_destroy_irq(&link->hpd_gpio);
 		link->hpd_gpio = NULL;
 	}
@@ -87,7 +86,7 @@ static void dc_link_destruct(struct dc_link *link)
 	if (link->ddc)
 		dal_ddc_service_destroy(&link->ddc);
 
-	if(link->link_enc)
+	if (link->link_enc)
 		link->link_enc->funcs->destroy(&link->link_enc);
 
 	if (link->local_sink)
@@ -98,8 +97,8 @@ static void dc_link_destruct(struct dc_link *link)
 }
 
 struct gpio *get_hpd_gpio(struct dc_bios *dcb,
-		struct graphics_object_id link_id,
-		struct gpio_service *gpio_service)
+			  struct graphics_object_id link_id,
+			  struct gpio_service *gpio_service)
 {
 	enum bp_result bp_result;
 	struct graphics_object_hpd_info hpd_info;
@@ -116,10 +115,9 @@ struct gpio *get_hpd_gpio(struct dc_bios *dcb,
 		return NULL;
 	}
 
-	return dal_gpio_service_create_irq(
-		gpio_service,
-		pin_info.offset,
-		pin_info.mask);
+	return dal_gpio_service_create_irq(gpio_service,
+					   pin_info.offset,
+					   pin_info.mask);
 }
 
 /*
@@ -134,13 +132,10 @@ struct gpio *get_hpd_gpio(struct dc_bios *dcb,
  *  @return
  *     true on success, false otherwise
  */
-static bool program_hpd_filter(
-	const struct dc_link *link)
+static bool program_hpd_filter(const struct dc_link *link)
 {
 	bool result = false;
-
 	struct gpio *hpd;
-
 	int delay_on_connect_in_ms = 0;
 	int delay_on_disconnect_in_ms = 0;
 
@@ -159,10 +154,10 @@ static bool program_hpd_filter(
 	case SIGNAL_TYPE_DISPLAY_PORT_MST:
 		/* Program hpd filter to allow DP signal to settle */
 		/* 500:	not able to detect MST <-> SST switch as HPD is low for
-		 * 	only 100ms on DELL U2413
-		 * 0:	some passive dongle still show aux mode instead of i2c
-		 * 20-50:not enough to hide bouncing HPD with passive dongle.
-		 * 	also see intermittent i2c read issues.
+		 * only 100ms on DELL U2413
+		 * 0: some passive dongle still show aux mode instead of i2c
+		 * 20-50: not enough to hide bouncing HPD with passive dongle.
+		 * also see intermittent i2c read issues.
 		 */
 		delay_on_connect_in_ms = 80;
 		delay_on_disconnect_in_ms = 0;
@@ -175,7 +170,8 @@ static bool program_hpd_filter(
 	}
 
 	/* Obtain HPD handle */
-	hpd = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service);
+	hpd = get_hpd_gpio(link->ctx->dc_bios, link->link_id,
+			   link->ctx->gpio_service);
 
 	if (!hpd)
 		return result;
@@ -226,8 +222,9 @@ bool dc_link_detect_sink(struct dc_link *link, enum dc_connection_type *type)
 	}
 
 	/* todo: may need to lock gpio access */
-	hpd_pin = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service);
-	if (hpd_pin == NULL)
+	hpd_pin = get_hpd_gpio(link->ctx->dc_bios, link->link_id,
+			       link->ctx->gpio_service);
+	if (!hpd_pin)
 		goto hpd_gpio_failure;
 
 	dal_gpio_open(hpd_pin, GPIO_MODE_INTERRUPT);
@@ -248,8 +245,7 @@ bool dc_link_detect_sink(struct dc_link *link, enum dc_connection_type *type)
 	return false;
 }
 
-static enum ddc_transaction_type get_ddc_transaction_type(
-		enum signal_type sink_signal)
+static enum ddc_transaction_type get_ddc_transaction_type(enum signal_type sink_signal)
 {
 	enum ddc_transaction_type transaction_type = DDC_TRANSACTION_TYPE_NONE;
 
@@ -270,7 +266,8 @@ static enum ddc_transaction_type get_ddc_transaction_type(
 	case SIGNAL_TYPE_DISPLAY_PORT_MST:
 		/* MST does not use I2COverAux, but there is the
 		 * SPECIAL use case for "immediate dwnstrm device
-		 * access" (EPR#370830). */
+		 * access" (EPR#370830).
+		 */
 		transaction_type = DDC_TRANSACTION_TYPE_I2C_OVER_AUX;
 		break;
 
@@ -281,9 +278,8 @@ static enum ddc_transaction_type get_ddc_transaction_type(
 	return transaction_type;
 }
 
-static enum signal_type get_basic_signal_type(
-	struct graphics_object_id encoder,
-	struct graphics_object_id downstream)
+static enum signal_type get_basic_signal_type(struct graphics_object_id encoder,
+					      struct graphics_object_id downstream)
 {
 	if (downstream.type == OBJECT_TYPE_CONNECTOR) {
 		switch (downstream.id) {
@@ -369,10 +365,11 @@ bool dc_link_is_dp_sink_present(struct dc_link *link)
 	/* Open GPIO and set it to I2C mode */
 	/* Note: this GpioMode_Input will be converted
 	 * to GpioConfigType_I2cAuxDualMode in GPIO component,
-	 * which indicates we need additional delay */
+	 * which indicates we need additional delay
+	 */
 
-	if (GPIO_RESULT_OK != dal_ddc_open(
-		ddc, GPIO_MODE_INPUT, GPIO_DDC_CONFIG_TYPE_MODE_I2C)) {
+	if (dal_ddc_open(ddc, GPIO_MODE_INPUT,
+			 GPIO_DDC_CONFIG_TYPE_MODE_I2C) != GPIO_RESULT_OK) {
 		dal_ddc_close(ddc);
 
 		return present;
@@ -406,25 +403,25 @@ bool dc_link_is_dp_sink_present(struct dc_link *link)
  * @brief
  * Detect output sink type
  */
-static enum signal_type link_detect_sink(
-	struct dc_link *link,
-	enum dc_detect_reason reason)
+static enum signal_type link_detect_sink(struct dc_link *link,
+					 enum dc_detect_reason reason)
 {
-	enum signal_type result = get_basic_signal_type(
-		link->link_enc->id, link->link_id);
+	enum signal_type result = get_basic_signal_type(link->link_enc->id,
+							link->link_id);
 
 	/* Internal digital encoder will detect only dongles
-	 * that require digital signal */
+	 * that require digital signal
+	 */
 
 	/* Detection mechanism is different
 	 * for different native connectors.
 	 * LVDS connector supports only LVDS signal;
 	 * PCIE is a bus slot, the actual connector needs to be detected first;
 	 * eDP connector supports only eDP signal;
-	 * HDMI should check straps for audio */
+	 * HDMI should check straps for audio
+	 */
 
 	/* PCIE detects the actual connector on add-on board */
-
 	if (link->link_id.id == CONNECTOR_ID_PCIE) {
 		/* ZAZTODO implement PCIE add-on card detection */
 	}
@@ -432,8 +429,10 @@ static enum signal_type link_detect_sink(
 	switch (link->link_id.id) {
 	case CONNECTOR_ID_HDMI_TYPE_A: {
 		/* check audio support:
-		 * if native HDMI is not supported, switch to DVI */
-		struct audio_support *aud_support = &link->dc->res_pool->audio_support;
+		 * if native HDMI is not supported, switch to DVI
+		 */
+		struct audio_support *aud_support =
+					&link->dc->res_pool->audio_support;
 
 		if (!aud_support->hdmi_audio_native)
 			if (link->link_id.id == CONNECTOR_ID_HDMI_TYPE_A)
@@ -461,16 +460,15 @@ static enum signal_type link_detect_sink(
 	return result;
 }
 
-static enum signal_type decide_signal_from_strap_and_dongle_type(
-		enum display_dongle_type dongle_type,
-		struct audio_support *audio_support)
+static enum signal_type decide_signal_from_strap_and_dongle_type(enum display_dongle_type dongle_type,
+								 struct audio_support *audio_support)
 {
 	enum signal_type signal = SIGNAL_TYPE_NONE;
 
 	switch (dongle_type) {
 	case DISPLAY_DONGLE_DP_HDMI_DONGLE:
 		if (audio_support->hdmi_audio_on_dongle)
-			signal =  SIGNAL_TYPE_HDMI_TYPE_A;
+			signal = SIGNAL_TYPE_HDMI_TYPE_A;
 		else
 			signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
 		break;
@@ -491,16 +489,14 @@ static enum signal_type decide_signal_from_strap_and_dongle_type(
 	return signal;
 }
 
-static enum signal_type dp_passive_dongle_detection(
-		struct ddc_service *ddc,
-		struct display_sink_capability *sink_cap,
-		struct audio_support *audio_support)
+static enum signal_type dp_passive_dongle_detection(struct ddc_service *ddc,
+						    struct display_sink_capability *sink_cap,
+						    struct audio_support *audio_support)
 {
-	dal_ddc_service_i2c_query_dp_dual_mode_adaptor(
-						ddc, sink_cap);
-	return decide_signal_from_strap_and_dongle_type(
-			sink_cap->dongle_type,
-			audio_support);
+	dal_ddc_service_i2c_query_dp_dual_mode_adaptor(ddc, sink_cap);
+
+	return decide_signal_from_strap_and_dongle_type(sink_cap->dongle_type,
+							audio_support);
 }
 
 static void link_disconnect_sink(struct dc_link *link)
@@ -519,6 +515,96 @@ static void link_disconnect_remap(struct dc_sink *prev_sink, struct dc_link *lin
 	link->local_sink = prev_sink;
 }
 
+#if defined(CONFIG_DRM_AMD_DC_HDCP)
+bool dc_link_is_hdcp14(struct dc_link *link)
+{
+	bool ret = false;
+
+	switch (link->connector_signal)	{
+	case SIGNAL_TYPE_DISPLAY_PORT:
+	case SIGNAL_TYPE_DISPLAY_PORT_MST:
+		ret = link->hdcp_caps.bcaps.bits.HDCP_CAPABLE;
+		break;
+	case SIGNAL_TYPE_DVI_SINGLE_LINK:
+	case SIGNAL_TYPE_DVI_DUAL_LINK:
+	case SIGNAL_TYPE_HDMI_TYPE_A:
+	/* HDMI doesn't tell us its HDCP(1.4) capability, so assume to always be capable,
+	 * we can poll for bksv but some displays have an issue with this. Since its so rare
+	 * for a display to not be 1.4 capable, this assumtion is ok
+	 */
+		ret = true;
+		break;
+	default:
+		break;
+	}
+	return ret;
+}
+
+bool dc_link_is_hdcp22(struct dc_link *link)
+{
+	bool ret = false;
+
+	switch (link->connector_signal)	{
+	case SIGNAL_TYPE_DISPLAY_PORT:
+	case SIGNAL_TYPE_DISPLAY_PORT_MST:
+		ret = (link->hdcp_caps.bcaps.bits.HDCP_CAPABLE &&
+				link->hdcp_caps.rx_caps.fields.byte0.hdcp_capable &&
+				(link->hdcp_caps.rx_caps.fields.version == 0x2)) ? 1 : 0;
+		break;
+	case SIGNAL_TYPE_DVI_SINGLE_LINK:
+	case SIGNAL_TYPE_DVI_DUAL_LINK:
+	case SIGNAL_TYPE_HDMI_TYPE_A:
+		ret = (link->hdcp_caps.rx_caps.fields.version == 0x4) ? 1:0;
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+static void query_hdcp_capability(enum signal_type signal, struct dc_link *link)
+{
+	struct hdcp_protection_message msg22;
+	struct hdcp_protection_message msg14;
+
+	memset(&msg22, 0, sizeof(struct hdcp_protection_message));
+	memset(&msg14, 0, sizeof(struct hdcp_protection_message));
+	memset(link->hdcp_caps.rx_caps.raw, 0,
+		sizeof(link->hdcp_caps.rx_caps.raw));
+
+	if ((link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT &&
+			link->ddc->transaction_type ==
+			DDC_TRANSACTION_TYPE_I2C_OVER_AUX) ||
+			link->connector_signal == SIGNAL_TYPE_EDP) {
+		msg22.data = link->hdcp_caps.rx_caps.raw;
+		msg22.length = sizeof(link->hdcp_caps.rx_caps.raw);
+		msg22.msg_id = HDCP_MESSAGE_ID_RX_CAPS;
+	} else {
+		msg22.data = &link->hdcp_caps.rx_caps.fields.version;
+		msg22.length = sizeof(link->hdcp_caps.rx_caps.fields.version);
+		msg22.msg_id = HDCP_MESSAGE_ID_HDCP2VERSION;
+	}
+	msg22.version = HDCP_VERSION_22;
+	msg22.link = HDCP_LINK_PRIMARY;
+	msg22.max_retries = 5;
+	dc_process_hdcp_msg(signal, link, &msg22);
+
+	if (signal == SIGNAL_TYPE_DISPLAY_PORT || signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
+		enum hdcp_message_status status = HDCP_MESSAGE_UNSUPPORTED;
+
+		msg14.data = &link->hdcp_caps.bcaps.raw;
+		msg14.length = sizeof(link->hdcp_caps.bcaps.raw);
+		msg14.msg_id = HDCP_MESSAGE_ID_READ_BCAPS;
+		msg14.version = HDCP_VERSION_14;
+		msg14.link = HDCP_LINK_PRIMARY;
+		msg14.max_retries = 5;
+
+		status = dc_process_hdcp_msg(signal, link, &msg14);
+	}
+
+}
+#endif
 
 static void read_current_link_settings_on_detect(struct dc_link *link)
 {
@@ -532,18 +618,18 @@ static void read_current_link_settings_on_detect(struct dc_link *link)
 
 	// Read DPCD 00101h to find out the number of lanes currently set
 	for (i = 0; i < read_dpcd_retry_cnt; i++) {
-		status = core_link_read_dpcd(
-				link,
-				DP_LANE_COUNT_SET,
-				&lane_count_set.raw,
-				sizeof(lane_count_set));
+		status = core_link_read_dpcd(link,
+					     DP_LANE_COUNT_SET,
+					     &lane_count_set.raw,
+					     sizeof(lane_count_set));
 		/* First DPCD read after VDD ON can fail if the particular board
 		 * does not have HPD pin wired correctly. So if DPCD read fails,
 		 * which it should never happen, retry a few times. Target worst
 		 * case scenario of 80 ms.
 		 */
 		if (status == DC_OK) {
-			link->cur_link_settings.lane_count = lane_count_set.bits.LANE_COUNT_SET;
+			link->cur_link_settings.lane_count =
+					lane_count_set.bits.LANE_COUNT_SET;
 			break;
 		}
 
@@ -552,7 +638,7 @@ static void read_current_link_settings_on_detect(struct dc_link *link)
 
 	// Read DPCD 00100h to find if standard link rates are set
 	core_link_read_dpcd(link, DP_LINK_BW_SET,
-			&link_bw_set, sizeof(link_bw_set));
+			    &link_bw_set, sizeof(link_bw_set));
 
 	if (link_bw_set == 0) {
 		if (link->connector_signal == SIGNAL_TYPE_EDP) {
@@ -560,12 +646,12 @@ static void read_current_link_settings_on_detect(struct dc_link *link)
 			 * Read DPCD 00115h to find the edp link rate set used
 			 */
 			core_link_read_dpcd(link, DP_LINK_RATE_SET,
-					&link_rate_set, sizeof(link_rate_set));
+					    &link_rate_set, sizeof(link_rate_set));
 
 			// edp_supported_link_rates_count = 0 for DP
 			if (link_rate_set < link->dpcd_caps.edp_supported_link_rates_count) {
 				link->cur_link_settings.link_rate =
-						link->dpcd_caps.edp_supported_link_rates[link_rate_set];
+					link->dpcd_caps.edp_supported_link_rates[link_rate_set];
 				link->cur_link_settings.link_rate_set = link_rate_set;
 				link->cur_link_settings.use_link_rate_set = true;
 			}
@@ -579,7 +665,7 @@ static void read_current_link_settings_on_detect(struct dc_link *link)
 	}
 	// Read DPCD 00003h to find the max down spread.
 	core_link_read_dpcd(link, DP_MAX_DOWNSPREAD,
-			&max_down_spread.raw, sizeof(max_down_spread));
+			    &max_down_spread.raw, sizeof(max_down_spread));
 	link->cur_link_settings.link_spread =
 		max_down_spread.bits.MAX_DOWN_SPREAD ?
 		LINK_SPREAD_05_DOWNSPREAD_30KHZ : LINK_SPREAD_DISABLED;
@@ -612,6 +698,12 @@ static bool detect_dp(struct dc_link *link,
 			dal_ddc_service_set_transaction_type(link->ddc,
 							     sink_caps->transaction_type);
 
+#if defined(CONFIG_DRM_AMD_DC_HDCP)
+			/* In case of fallback to SST when topology discovery below fails
+			 * HDCP caps will be querried again later by the upper layer (caller
+			 * of this function). */
+			query_hdcp_capability(SIGNAL_TYPE_DISPLAY_PORT_MST, link);
+#endif
 			/*
 			 * This call will initiate MST topology discovery. Which
 			 * will detect MST ports and add new DRM connector DRM
@@ -683,12 +775,12 @@ static bool is_same_edid(struct dc_edid *old_edid, struct dc_edid *new_edid)
 	if (new_edid->length == 0)
 		return false;
 
-	return (memcmp(old_edid->raw_edid, new_edid->raw_edid, new_edid->length) == 0);
+	return (memcmp(old_edid->raw_edid,
+		       new_edid->raw_edid, new_edid->length) == 0);
 }
 
-static bool wait_for_alt_mode(struct dc_link *link)
+static bool wait_for_entering_dp_alt_mode(struct dc_link *link)
 {
-
 	/**
 	 * something is terribly wrong if time out is > 200ms. (5Hz)
 	 * 500 microseconds * 400 tries us 200 ms
@@ -703,7 +795,7 @@ static bool wait_for_alt_mode(struct dc_link *link)
 
 	DC_LOGGER_INIT(link->ctx->logger);
 
-	if (link->link_enc->funcs->is_in_alt_mode == NULL)
+	if (!link->link_enc->funcs->is_in_alt_mode)
 		return true;
 
 	is_in_alt_mode = link->link_enc->funcs->is_in_alt_mode(link->link_enc);
@@ -718,21 +810,21 @@ static bool wait_for_alt_mode(struct dc_link *link)
 		udelay(sleep_time_in_microseconds);
 		/* ask the link if alt mode is enabled, if so return ok */
 		if (link->link_enc->funcs->is_in_alt_mode(link->link_enc)) {
-
 			finish_timestamp = dm_get_timestamp(link->ctx);
-			time_taken_in_ns = dm_get_elapse_time_in_ns(
-				link->ctx, finish_timestamp, enter_timestamp);
+			time_taken_in_ns =
+				dm_get_elapse_time_in_ns(link->ctx,
+							 finish_timestamp,
+							 enter_timestamp);
 			DC_LOG_WARNING("Alt mode entered finished after %llu ms\n",
 				       div_u64(time_taken_in_ns, 1000000));
 			return true;
 		}
-
 	}
 	finish_timestamp = dm_get_timestamp(link->ctx);
 	time_taken_in_ns = dm_get_elapse_time_in_ns(link->ctx, finish_timestamp,
 						    enter_timestamp);
 	DC_LOG_WARNING("Alt mode has timed out after %llu ms\n",
-			div_u64(time_taken_in_ns, 1000000));
+		       div_u64(time_taken_in_ns, 1000000));
 	return false;
 }
 
@@ -768,30 +860,30 @@ static bool dc_link_detect_helper(struct dc_link *link,
 		return false;
 
 	if ((link->connector_signal == SIGNAL_TYPE_LVDS ||
-			link->connector_signal == SIGNAL_TYPE_EDP) &&
-			link->local_sink) {
-
+	     link->connector_signal == SIGNAL_TYPE_EDP) &&
+	    link->local_sink) {
 		// need to re-write OUI and brightness in resume case
 		if (link->connector_signal == SIGNAL_TYPE_EDP) {
 			dpcd_set_source_specific_data(link);
-			dc_link_set_default_brightness_aux(link); //TODO: use cached
+			dc_link_set_default_brightness_aux(link);
+			//TODO: use cached
 		}
 
 		return true;
 	}
 
-	if (false == dc_link_detect_sink(link, &new_connection_type)) {
+	if (!dc_link_detect_sink(link, &new_connection_type)) {
 		BREAK_TO_DEBUGGER();
 		return false;
 	}
 
 	prev_sink = link->local_sink;
-	if (prev_sink != NULL) {
+	if (prev_sink) {
 		dc_sink_retain(prev_sink);
 		memcpy(&prev_dpcd_caps, &link->dpcd_caps, sizeof(struct dpcd_caps));
 	}
-	link_disconnect_sink(link);
 
+	link_disconnect_sink(link);
 	if (new_connection_type != dc_connection_none) {
 		link->type = new_connection_type;
 		link->link_state_valid = false;
@@ -838,35 +930,31 @@ static bool dc_link_detect_helper(struct dc_link *link,
 		}
 
 		case SIGNAL_TYPE_DISPLAY_PORT: {
-
 			/* wa HPD high coming too early*/
 			if (link->link_enc->features.flags.bits.DP_IS_USB_C == 1) {
-
 				/* if alt mode times out, return false */
-				if (wait_for_alt_mode(link) == false) {
+				if (!wait_for_entering_dp_alt_mode(link))
 					return false;
-				}
 			}
 
-			if (!detect_dp(
-				link,
-				&sink_caps,
-				&converter_disable_audio,
-				aud_support, reason)) {
-				if (prev_sink != NULL)
+			if (!detect_dp(link, &sink_caps,
+				       &converter_disable_audio,
+				       aud_support, reason)) {
+				if (prev_sink)
 					dc_sink_release(prev_sink);
 				return false;
 			}
 
 			// Check if dpcp block is the same
-			if (prev_sink != NULL) {
-				if (memcmp(&link->dpcd_caps, &prev_dpcd_caps, sizeof(struct dpcd_caps)))
+			if (prev_sink) {
+				if (memcmp(&link->dpcd_caps, &prev_dpcd_caps,
+					   sizeof(struct dpcd_caps)))
 					same_dpcd = false;
 			}
 			/* Active dongle downstream unplug*/
 			if (link->type == dc_connection_active_dongle &&
-				link->dpcd_caps.sink_count.bits.SINK_COUNT == 0) {
-				if (prev_sink != NULL)
+			    link->dpcd_caps.sink_count.bits.SINK_COUNT == 0) {
+				if (prev_sink)
 					/* Downstream unplug */
 					dc_sink_release(prev_sink);
 				return true;
@@ -874,7 +962,7 @@ static bool dc_link_detect_helper(struct dc_link *link,
 
 			if (link->type == dc_connection_mst_branch) {
 				LINK_INFO("link=%d, mst branch is now Connected\n",
-					link->link_index);
+					  link->link_index);
 				/* Need to setup mst link_cap struct here
 				 * otherwise dc_link_detect() will leave mst link_cap
 				 * empty which leads to allocate_mst_payload() has "0"
@@ -882,15 +970,15 @@ static bool dc_link_detect_helper(struct dc_link *link,
 				 */
 				dp_verify_mst_link_cap(link);
 
-				if (prev_sink != NULL)
+				if (prev_sink)
 					dc_sink_release(prev_sink);
 				return false;
 			}
 
 			// For seamless boot, to skip verify link cap, we read UEFI settings and set them as verified.
 			if (reason == DETECT_REASON_BOOT &&
-					dc_ctx->dc->config.power_down_display_on_boot == false &&
-					link->link_status.link_active == true)
+			    !dc_ctx->dc->config.power_down_display_on_boot &&
+			    link->link_status.link_active)
 				perform_dp_seamless_boot = true;
 
 			if (perform_dp_seamless_boot) {
@@ -903,24 +991,23 @@ static bool dc_link_detect_helper(struct dc_link *link,
 
 		default:
 			DC_ERROR("Invalid connector type! signal:%d\n",
-				link->connector_signal);
-			if (prev_sink != NULL)
+				 link->connector_signal);
+			if (prev_sink)
 				dc_sink_release(prev_sink);
 			return false;
 		} /* switch() */
 
 		if (link->dpcd_caps.sink_count.bits.SINK_COUNT)
-			link->dpcd_sink_count = link->dpcd_caps.sink_count.
-					bits.SINK_COUNT;
+			link->dpcd_sink_count =
+				link->dpcd_caps.sink_count.bits.SINK_COUNT;
 		else
 			link->dpcd_sink_count = 1;
 
-		dal_ddc_service_set_transaction_type(
-						link->ddc,
-						sink_caps.transaction_type);
+		dal_ddc_service_set_transaction_type(link->ddc,
+						     sink_caps.transaction_type);
 
-		link->aux_mode = dal_ddc_service_is_in_aux_transaction_mode(
-				link->ddc);
+		link->aux_mode =
+			dal_ddc_service_is_in_aux_transaction_mode(link->ddc);
 
 		sink_init_data.link = link;
 		sink_init_data.sink_signal = sink_caps.signal;
@@ -928,7 +1015,7 @@ static bool dc_link_detect_helper(struct dc_link *link,
 		sink = dc_sink_create(&sink_init_data);
 		if (!sink) {
 			DC_ERROR("Failed to create sink!\n");
-			if (prev_sink != NULL)
+			if (prev_sink)
 				dc_sink_release(prev_sink);
 			return false;
 		}
@@ -939,10 +1026,8 @@ static bool dc_link_detect_helper(struct dc_link *link,
 		/* dc_sink_create returns a new reference */
 		link->local_sink = sink;
 
-		edid_status = dm_helpers_read_local_edid(
-				link->ctx,
-				link,
-				sink);
+		edid_status = dm_helpers_read_local_edid(link->ctx,
+							 link, sink);
 
 		switch (edid_status) {
 		case EDID_BAD_CHECKSUM:
@@ -950,7 +1035,6 @@ static bool dc_link_detect_helper(struct dc_link *link,
 			break;
 		case EDID_NO_RESPONSE:
 			DC_LOG_ERROR("No EDID read.\n");
-
 			/*
 			 * Abort detection for non-DP connectors if we have
 			 * no EDID
@@ -961,7 +1045,7 @@ static bool dc_link_detect_helper(struct dc_link *link,
 			 */
 			if (dc_is_hdmi_signal(link->connector_signal) ||
 			    dc_is_dvi_signal(link->connector_signal)) {
-				if (prev_sink != NULL)
+				if (prev_sink)
 					dc_sink_release(prev_sink);
 
 				return false;
@@ -974,45 +1058,53 @@ static bool dc_link_detect_helper(struct dc_link *link,
 			link->ctx->dc->debug.disable_fec = true;
 
 		// Check if edid is the same
-		if ((prev_sink != NULL) && ((edid_status == EDID_THE_SAME) || (edid_status == EDID_OK)))
-			same_edid = is_same_edid(&prev_sink->dc_edid, &sink->dc_edid);
+		if ((prev_sink) &&
+		    (edid_status == EDID_THE_SAME || edid_status == EDID_OK))
+			same_edid = is_same_edid(&prev_sink->dc_edid,
+						 &sink->dc_edid);
 
 		if (sink->edid_caps.panel_patch.skip_scdc_overwrite)
 			link->ctx->dc->debug.hdmi20_disable = true;
 
 		if (link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT &&
-			sink_caps.transaction_type == DDC_TRANSACTION_TYPE_I2C_OVER_AUX) {
+		    sink_caps.transaction_type ==
+		    DDC_TRANSACTION_TYPE_I2C_OVER_AUX) {
 			/*
 			 * TODO debug why Dell 2413 doesn't like
 			 *  two link trainings
 			 */
+#if defined(CONFIG_DRM_AMD_DC_HDCP)
+			query_hdcp_capability(sink->sink_signal, link);
+#endif
 
 			// verify link cap for SST non-seamless boot
 			if (!perform_dp_seamless_boot)
 				dp_verify_link_cap_with_retries(link,
-						&link->reported_link_cap,
-						LINK_TRAINING_MAX_VERIFY_RETRY);
+								&link->reported_link_cap,
+								LINK_TRAINING_MAX_VERIFY_RETRY);
 		} else {
 			// If edid is the same, then discard new sink and revert back to original sink
 			if (same_edid) {
 				link_disconnect_remap(prev_sink, link);
 				sink = prev_sink;
 				prev_sink = NULL;
-
 			}
+#if defined(CONFIG_DRM_AMD_DC_HDCP)
+			query_hdcp_capability(sink->sink_signal, link);
+#endif
 		}
 
 		/* HDMI-DVI Dongle */
 		if (sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A &&
-				!sink->edid_caps.edid_hdmi)
+		    !sink->edid_caps.edid_hdmi)
 			sink->sink_signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
 
 		/* Connectivity log: detection */
 		for (i = 0; i < sink->dc_edid.length / DC_EDID_BLOCK_SIZE; i++) {
 			CONN_DATA_DETECT(link,
-					&sink->dc_edid.raw_edid[i * DC_EDID_BLOCK_SIZE],
-					DC_EDID_BLOCK_SIZE,
-					"%s: [Block %d] ", sink->edid_caps.display_name, i);
+					 &sink->dc_edid.raw_edid[i * DC_EDID_BLOCK_SIZE],
+					 DC_EDID_BLOCK_SIZE,
+					 "%s: [Block %d] ", sink->edid_caps.display_name, i);
 		}
 
 		DC_LOG_DETECTION_EDID_PARSER("%s: "
@@ -1047,17 +1139,18 @@ static bool dc_link_detect_helper(struct dc_link *link,
 				sink->edid_caps.audio_modes[i].sample_rate,
 				sink->edid_caps.audio_modes[i].sample_size);
 		}
-
 	} else {
 		/* From Connected-to-Disconnected. */
 		if (link->type == dc_connection_mst_branch) {
 			LINK_INFO("link=%d, mst branch is now Disconnected\n",
-				link->link_index);
+				  link->link_index);
 
 			dm_helpers_dp_mst_stop_top_mgr(link->ctx, link);
 
 			link->mst_stream_alloc_table.stream_count = 0;
-			memset(link->mst_stream_alloc_table.stream_allocations, 0, sizeof(link->mst_stream_alloc_table.stream_allocations));
+			memset(link->mst_stream_alloc_table.stream_allocations,
+			       0,
+			       sizeof(link->mst_stream_alloc_table.stream_allocations));
 		}
 
 		link->type = dc_connection_none;
@@ -1071,16 +1164,15 @@ static bool dc_link_detect_helper(struct dc_link *link,
 	}
 
 	LINK_INFO("link=%d, dc_sink_in=%p is now %s prev_sink=%p dpcd same=%d edid same=%d\n",
-		link->link_index, sink,
-		(sink_caps.signal == SIGNAL_TYPE_NONE ?
-			"Disconnected":"Connected"), prev_sink,
-			same_dpcd, same_edid);
+		  link->link_index, sink,
+		  (sink_caps.signal ==
+		   SIGNAL_TYPE_NONE ? "Disconnected" : "Connected"),
+		  prev_sink, same_dpcd, same_edid);
 
-	if (prev_sink != NULL)
+	if (prev_sink)
 		dc_sink_release(prev_sink);
 
 	return true;
-
 }
 
 bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
@@ -1110,13 +1202,13 @@ bool dc_link_get_hpd_state(struct dc_link *dc_link)
 	return state;
 }
 
-static enum hpd_source_id get_hpd_line(
-		struct dc_link *link)
+static enum hpd_source_id get_hpd_line(struct dc_link *link)
 {
 	struct gpio *hpd;
 	enum hpd_source_id hpd_id = HPD_SOURCEID_UNKNOWN;
 
-	hpd = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service);
+	hpd = get_hpd_gpio(link->ctx->dc_bios, link->link_id,
+			   link->ctx->gpio_service);
 
 	if (hpd) {
 		switch (dal_irq_get_source(hpd)) {
@@ -1191,8 +1283,7 @@ static enum channel_id get_ddc_line(struct dc_link *link)
 	return channel;
 }
 
-static enum transmitter translate_encoder_to_transmitter(
-	struct graphics_object_id encoder)
+static enum transmitter translate_encoder_to_transmitter(struct graphics_object_id encoder)
 {
 	switch (encoder.id) {
 	case ENCODER_ID_INTERNAL_UNIPHY:
@@ -1256,9 +1347,8 @@ static enum transmitter translate_encoder_to_transmitter(
 	}
 }
 
-static bool dc_link_construct(
-	struct dc_link *link,
-	const struct link_init_data *init_params)
+static bool dc_link_construct(struct dc_link *link,
+			      const struct link_init_data *init_params)
 {
 	uint8_t i;
 	struct ddc_service_init_data ddc_service_init_data = { { 0 } };
@@ -1267,6 +1357,7 @@ static bool dc_link_construct(
 	struct integrated_info info = {{{ 0 }}};
 	struct dc_bios *bios = init_params->dc->ctx->dc_bios;
 	const struct dc_vbios_funcs *bp_funcs = bios->funcs;
+
 	DC_LOGGER_INIT(dc_ctx->logger);
 
 	link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
@@ -1278,23 +1369,27 @@ static bool dc_link_construct(
 	link->ctx = dc_ctx;
 	link->link_index = init_params->link_index;
 
-	memset(&link->preferred_training_settings, 0, sizeof(struct dc_link_training_overrides));
-	memset(&link->preferred_link_setting, 0, sizeof(struct dc_link_settings));
+	memset(&link->preferred_training_settings, 0,
+	       sizeof(struct dc_link_training_overrides));
+	memset(&link->preferred_link_setting, 0,
+	       sizeof(struct dc_link_settings));
 
-	link->link_id = bios->funcs->get_connector_id(bios, init_params->connector_index);
+	link->link_id =
+		bios->funcs->get_connector_id(bios, init_params->connector_index);
 
 	if (link->link_id.type != OBJECT_TYPE_CONNECTOR) {
 		dm_output_to_console("%s: Invalid Connector ObjectID from Adapter Service for connector index:%d! type %d expected %d\n",
-			 __func__, init_params->connector_index,
-			 link->link_id.type, OBJECT_TYPE_CONNECTOR);
+				     __func__, init_params->connector_index,
+				     link->link_id.type, OBJECT_TYPE_CONNECTOR);
 		goto create_fail;
 	}
 
 	if (link->dc->res_pool->funcs->link_init)
 		link->dc->res_pool->funcs->link_init(link);
 
-	link->hpd_gpio = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service);
-	if (link->hpd_gpio != NULL) {
+	link->hpd_gpio = get_hpd_gpio(link->ctx->dc_bios, link->link_id,
+				      link->ctx->gpio_service);
+	if (link->hpd_gpio) {
 		dal_gpio_open(link->hpd_gpio, GPIO_MODE_INTERRUPT);
 		dal_gpio_unlock_pin(link->hpd_gpio);
 		link->irq_source_hpd = dal_irq_get_source(link->hpd_gpio);
@@ -1314,9 +1409,9 @@ static bool dc_link_construct(
 		link->connector_signal = SIGNAL_TYPE_DVI_DUAL_LINK;
 		break;
 	case CONNECTOR_ID_DISPLAY_PORT:
-		link->connector_signal =	SIGNAL_TYPE_DISPLAY_PORT;
+		link->connector_signal = SIGNAL_TYPE_DISPLAY_PORT;
 
-		if (link->hpd_gpio != NULL)
+		if (link->hpd_gpio)
 			link->irq_source_hpd_rx =
 					dal_irq_get_rx_source(link->hpd_gpio);
 
@@ -1324,7 +1419,7 @@ static bool dc_link_construct(
 	case CONNECTOR_ID_EDP:
 		link->connector_signal = SIGNAL_TYPE_EDP;
 
-		if (link->hpd_gpio != NULL) {
+		if (link->hpd_gpio) {
 			link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
 			link->irq_source_hpd_rx =
 					dal_irq_get_rx_source(link->hpd_gpio);
@@ -1334,32 +1429,33 @@ static bool dc_link_construct(
 		link->connector_signal = SIGNAL_TYPE_LVDS;
 		break;
 	default:
-		DC_LOG_WARNING("Unsupported Connector type:%d!\n", link->link_id.id);
+		DC_LOG_WARNING("Unsupported Connector type:%d!\n",
+			       link->link_id.id);
 		goto create_fail;
 	}
 
 	/* TODO: #DAL3 Implement id to str function.*/
 	LINK_INFO("Connector[%d] description:"
-			"signal %d\n",
-			init_params->connector_index,
-			link->connector_signal);
+		  "signal %d\n",
+		  init_params->connector_index,
+		  link->connector_signal);
 
 	ddc_service_init_data.ctx = link->ctx;
 	ddc_service_init_data.id = link->link_id;
 	ddc_service_init_data.link = link;
 	link->ddc = dal_ddc_service_create(&ddc_service_init_data);
 
-	if (link->ddc == NULL) {
+	if (!link->ddc) {
 		DC_ERROR("Failed to create ddc_service!\n");
 		goto ddc_create_fail;
 	}
 
 	link->ddc_hw_inst =
-		dal_ddc_get_line(
-			dal_ddc_service_get_ddc_pin(link->ddc));
+		dal_ddc_get_line(dal_ddc_service_get_ddc_pin(link->ddc));
 
 	enc_init_data.ctx = dc_ctx;
-	bp_funcs->get_src_obj(dc_ctx->dc_bios, link->link_id, 0, &enc_init_data.encoder);
+	bp_funcs->get_src_obj(dc_ctx->dc_bios, link->link_id, 0,
+			      &enc_init_data.encoder);
 	enc_init_data.connector = link->link_id;
 	enc_init_data.channel = get_ddc_line(link);
 	enc_init_data.hpd_source = get_hpd_line(link);
@@ -1367,11 +1463,11 @@ static bool dc_link_construct(
 	link->hpd_src = enc_init_data.hpd_source;
 
 	enc_init_data.transmitter =
-			translate_encoder_to_transmitter(enc_init_data.encoder);
-	link->link_enc = link->dc->res_pool->funcs->link_enc_create(
-								&enc_init_data);
+		translate_encoder_to_transmitter(enc_init_data.encoder);
+	link->link_enc =
+		link->dc->res_pool->funcs->link_enc_create(&enc_init_data);
 
-	if (link->link_enc == NULL) {
+	if (!link->link_enc) {
 		DC_ERROR("Failed to create link encoder!\n");
 		goto link_enc_create_fail;
 	}
@@ -1379,8 +1475,9 @@ static bool dc_link_construct(
 	link->link_enc_hw_inst = link->link_enc->transmitter;
 
 	for (i = 0; i < 4; i++) {
-		if (BP_RESULT_OK !=
-				bp_funcs->get_device_tag(dc_ctx->dc_bios, link->link_id, i, &link->device_tag)) {
+		if (bp_funcs->get_device_tag(dc_ctx->dc_bios,
+					     link->link_id, i,
+					     &link->device_tag) != BP_RESULT_OK) {
 			DC_ERROR("Failed to find device tag!\n");
 			goto device_tag_fail;
 		}
@@ -1388,13 +1485,14 @@ static bool dc_link_construct(
 		/* Look for device tag that matches connector signal,
 		 * CRT for rgb, LCD for other supported signal tyes
 		 */
-		if (!bp_funcs->is_device_id_supported(dc_ctx->dc_bios, link->device_tag.dev_id))
+		if (!bp_funcs->is_device_id_supported(dc_ctx->dc_bios,
+						      link->device_tag.dev_id))
 			continue;
-		if (link->device_tag.dev_id.device_type == DEVICE_TYPE_CRT
-			&& link->connector_signal != SIGNAL_TYPE_RGB)
+		if (link->device_tag.dev_id.device_type == DEVICE_TYPE_CRT &&
+		    link->connector_signal != SIGNAL_TYPE_RGB)
 			continue;
-		if (link->device_tag.dev_id.device_type == DEVICE_TYPE_LCD
-			&& link->connector_signal == SIGNAL_TYPE_RGB)
+		if (link->device_tag.dev_id.device_type == DEVICE_TYPE_LCD &&
+		    link->connector_signal == SIGNAL_TYPE_RGB)
 			continue;
 		break;
 	}
@@ -1406,16 +1504,16 @@ static bool dc_link_construct(
 	for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; i++) {
 		struct external_display_path *path =
 			&info.ext_disp_conn_info.path[i];
-		if (path->device_connector_id.enum_id == link->link_id.enum_id
-			&& path->device_connector_id.id == link->link_id.id
-			&& path->device_connector_id.type == link->link_id.type) {
 
-			if (link->device_tag.acpi_device != 0
-				&& path->device_acpi_enum == link->device_tag.acpi_device) {
+		if (path->device_connector_id.enum_id == link->link_id.enum_id &&
+		    path->device_connector_id.id == link->link_id.id &&
+		    path->device_connector_id.type == link->link_id.type) {
+			if (link->device_tag.acpi_device != 0 &&
+			    path->device_acpi_enum == link->device_tag.acpi_device) {
 				link->ddi_channel_mapping = path->channel_mapping;
 				link->chip_caps = path->caps;
 			} else if (path->device_tag ==
-					link->device_tag.dev_id.raw_device_tag) {
+				   link->device_tag.dev_id.raw_device_tag) {
 				link->ddi_channel_mapping = path->channel_mapping;
 				link->chip_caps = path->caps;
 			}
@@ -1439,7 +1537,7 @@ static bool dc_link_construct(
 ddc_create_fail:
 create_fail:
 
-	if (link->hpd_gpio != NULL) {
+	if (link->hpd_gpio) {
 		dal_gpio_destroy_irq(&link->hpd_gpio);
 		link->hpd_gpio = NULL;
 	}
@@ -3040,6 +3138,18 @@ void core_link_enable_stream(
 		if (pipe_ctx->stream->dpms_off)
 			return;
 
+		/* Have to setup DSC before DIG FE and BE are connected (which happens before the
+		 * link training). This is to make sure the bandwidth sent to DIG BE won't be
+		 * bigger than what the link and/or DIG BE can handle. VBID[6]/CompressedStream_flag
+		 * will be automatically set at a later time when the video is enabled
+		 * (DP_VID_STREAM_EN = 1).
+		 */
+		if (pipe_ctx->stream->timing.flags.DSC) {
+			if (dc_is_dp_signal(pipe_ctx->stream->signal) ||
+					dc_is_virtual_signal(pipe_ctx->stream->signal))
+				dp_set_dsc_enable(pipe_ctx, true);
+		}
+
 		status = enable_link(state, pipe_ctx);
 
 		if (status != DC_OK) {
@@ -3067,11 +3177,6 @@ void core_link_enable_stream(
 					CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
 					COLOR_DEPTH_UNDEFINED);
 
-		if (pipe_ctx->stream->timing.flags.DSC) {
-			if (dc_is_dp_signal(pipe_ctx->stream->signal) ||
-					dc_is_virtual_signal(pipe_ctx->stream->signal))
-				dp_set_dsc_enable(pipe_ctx, true);
-		}
 		dc->hwss.enable_stream(pipe_ctx);
 
 		/* Set DPS PPS SDP (AKA "info frames") */
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index 7cbb1efb4f68..7f546566e049 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -1710,19 +1710,10 @@ bool dc_link_dp_sync_lt_end(struct dc_link *link, bool link_down)
 
 static struct dc_link_settings get_max_link_cap(struct dc_link *link)
 {
-	/* Set Default link settings */
-	struct dc_link_settings max_link_cap = {LANE_COUNT_FOUR, LINK_RATE_HIGH,
-			LINK_SPREAD_05_DOWNSPREAD_30KHZ, false, 0};
-
-	/* Higher link settings based on feature supported */
-	if (link->link_enc->features.flags.bits.IS_HBR2_CAPABLE)
-		max_link_cap.link_rate = LINK_RATE_HIGH2;
-
-	if (link->link_enc->features.flags.bits.IS_HBR3_CAPABLE)
-		max_link_cap.link_rate = LINK_RATE_HIGH3;
+	struct dc_link_settings max_link_cap = {0};
 
-	if (link->link_enc->funcs->get_max_link_cap)
-		link->link_enc->funcs->get_max_link_cap(link->link_enc, &max_link_cap);
+	/* get max link encoder capability */
+	link->link_enc->funcs->get_max_link_cap(link->link_enc, &max_link_cap);
 
 	/* Lower link settings based on sink's link cap */
 	if (link->reported_link_cap.lane_count < max_link_cap.lane_count)
@@ -2530,7 +2521,7 @@ static void dp_test_send_phy_test_pattern(struct dc_link *link)
 	/* get phy test pattern and pattern parameters from DP receiver */
 	core_link_read_dpcd(
 			link,
-			DP_TEST_PHY_PATTERN,
+			DP_PHY_TEST_PATTERN,
 			&dpcd_test_pattern.raw,
 			sizeof(dpcd_test_pattern));
 	core_link_read_dpcd(
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
index f4bcc71b2920..12f5c6881cd0 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -692,6 +692,9 @@ static void calculate_viewport(struct pipe_ctx *pipe_ctx)
 	/* Round up, assume original video size always even dimensions */
 	data->viewport_c.width = (data->viewport.width + vpc_div - 1) / vpc_div;
 	data->viewport_c.height = (data->viewport.height + vpc_div - 1) / vpc_div;
+
+	data->viewport_unadjusted = data->viewport;
+	data->viewport_c_unadjusted = data->viewport_c;
 }
 
 static void calculate_recout(struct pipe_ctx *pipe_ctx)
@@ -1358,9 +1361,6 @@ bool dc_add_plane_to_context(
 	dc_plane_state_retain(plane_state);
 
 	while (head_pipe) {
-		tail_pipe = resource_get_tail_pipe(&context->res_ctx, head_pipe);
-		ASSERT(tail_pipe);
-
 		free_pipe = acquire_free_pipe_for_head(context, pool, head_pipe);
 
 	#if defined(CONFIG_DRM_AMD_DC_DCN)
@@ -1378,6 +1378,8 @@ bool dc_add_plane_to_context(
 		free_pipe->plane_state = plane_state;
 
 		if (head_pipe != free_pipe) {
+			tail_pipe = resource_get_tail_pipe(&context->res_ctx, head_pipe);
+			ASSERT(tail_pipe);
 			free_pipe->stream_res.tg = tail_pipe->stream_res.tg;
 			free_pipe->stream_res.abm = tail_pipe->stream_res.abm;
 			free_pipe->stream_res.opp = tail_pipe->stream_res.opp;
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index 1935cf6601eb..8560032a66ba 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -29,6 +29,9 @@
 #include "dc_types.h"
 #include "grph_object_defs.h"
 #include "logger_types.h"
+#if defined(CONFIG_DRM_AMD_DC_HDCP)
+#include "hdcp_types.h"
+#endif
 #include "gpio_types.h"
 #include "link_service_types.h"
 #include "grph_object_ctrl_defs.h"
@@ -39,7 +42,7 @@
 #include "inc/hw/dmcu.h"
 #include "dml/display_mode_lib.h"
 
-#define DC_VER "3.2.76"
+#define DC_VER "3.2.80"
 
 #define MAX_SURFACES 3
 #define MAX_PLANES 6
@@ -230,7 +233,7 @@ struct dc_config {
 	bool forced_clocks;
 	bool disable_extended_timeout_support; // Used to disable extended timeout and lttpr feature as well
 	bool multi_mon_pp_mclk_switch;
-	bool psr_on_dmub;
+	bool disable_dmcu;
 };
 
 enum visual_confirm {
@@ -1004,6 +1007,35 @@ union dpcd_sink_ext_caps {
 	uint8_t raw;
 };
 
+#if defined(CONFIG_DRM_AMD_DC_HDCP)
+union hdcp_rx_caps {
+	struct {
+		uint8_t version;
+		uint8_t reserved;
+		struct {
+			uint8_t repeater	: 1;
+			uint8_t hdcp_capable	: 1;
+			uint8_t reserved	: 6;
+		} byte0;
+	} fields;
+	uint8_t raw[3];
+};
+
+union hdcp_bcaps {
+	struct {
+		uint8_t HDCP_CAPABLE:1;
+		uint8_t REPEATER:1;
+		uint8_t RESERVED:6;
+	} bits;
+	uint8_t raw;
+};
+
+struct hdcp_caps {
+	union hdcp_rx_caps rx_caps;
+	union hdcp_bcaps bcaps;
+};
+#endif
+
 #include "dc_link.h"
 
 /*******************************************************************************
@@ -1107,6 +1139,15 @@ void dc_resume(struct dc *dc);
 unsigned int dc_get_current_backlight_pwm(struct dc *dc);
 unsigned int dc_get_target_backlight_pwm(struct dc *dc);
 
+#if defined(CONFIG_DRM_AMD_DC_HDCP)
+/*
+ * HDCP Interfaces
+ */
+enum hdcp_message_status dc_process_hdcp_msg(
+		enum signal_type signal,
+		struct dc_link *link,
+		struct hdcp_protection_message *message_info);
+#endif
 bool dc_is_dmcu_initialized(struct dc *dc);
 
 enum dc_status dc_set_clock(struct dc *dc, enum dc_clock_type clock_type, uint32_t clk_khz, uint32_t stepping);
diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h
index 00ff5e98278c..e131dc99f283 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_link.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
@@ -126,6 +126,9 @@ struct dc_link {
 	uint32_t dongle_max_pix_clk;
 	unsigned short chip_caps;
 	unsigned int dpcd_sink_count;
+#if defined(CONFIG_DRM_AMD_DC_HDCP)
+	struct hdcp_caps hdcp_caps;
+#endif
 	enum edp_revision edp_revision;
 	bool psr_feature_enabled;
 	bool psr_allow_active;
@@ -290,6 +293,10 @@ bool dc_link_detect_sink(struct dc_link *link, enum dc_connection_type *type);
  * DPCD access interfaces
  */
 
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+bool dc_link_is_hdcp14(struct dc_link *link);
+bool dc_link_is_hdcp22(struct dc_link *link);
+#endif
 void dc_link_set_drive_settings(struct dc *dc,
 				struct link_training_settings *lt_settings,
 				const struct dc_link *link);
diff --git a/drivers/gpu/drm/amd/display/dc/dce/Makefile b/drivers/gpu/drm/amd/display/dc/dce/Makefile
index fbfcff700971..b31a1b71dab0 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dce/Makefile
@@ -29,7 +29,7 @@
 DCE = dce_audio.o dce_stream_encoder.o dce_link_encoder.o dce_hwseq.o \
 dce_mem_input.o dce_clock_source.o dce_scl_filters.o dce_transform.o \
 dce_opp.o dce_dmcu.o dce_abm.o dce_ipp.o dce_aux.o \
-dce_i2c.o dce_i2c_hw.o dce_i2c_sw.o dmub_psr.o
+dce_i2c.o dce_i2c_hw.o dce_i2c_sw.o dmub_psr.o dmub_abm.o
 
 AMD_DAL_DCE = $(addprefix $(AMDDALPATH)/dc/dce/,$(DCE))
 
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c
index b8a3fc505c9b..e345df621a6a 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c
@@ -447,6 +447,7 @@ static const struct abm_funcs dce_funcs = {
 	.set_backlight_level_pwm = dce_abm_set_backlight_level_pwm,
 	.get_current_backlight = dce_abm_get_current_backlight,
 	.get_target_backlight = dce_abm_get_target_backlight,
+	.init_abm_config = NULL,
 	.set_abm_immediate_disable = dce_abm_immediate_disable
 };
 
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
index 8527cce81c6f..8d8c84c81b34 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
@@ -118,7 +118,8 @@ static const struct link_encoder_funcs dce110_lnk_enc_funcs = {
 	.enable_hpd = dce110_link_encoder_enable_hpd,
 	.disable_hpd = dce110_link_encoder_disable_hpd,
 	.is_dig_enabled = dce110_is_dig_enabled,
-	.destroy = dce110_link_encoder_destroy
+	.destroy = dce110_link_encoder_destroy,
+	.get_max_link_cap = dce110_link_encoder_get_max_link_cap
 };
 
 static enum bp_result link_transmitter_control(
@@ -1389,3 +1390,20 @@ void dce110_link_encoder_disable_hpd(struct link_encoder *enc)
 
 	set_reg_field_value(value, 0, DC_HPD_CONTROL, DC_HPD_EN);
 }
+
+void dce110_link_encoder_get_max_link_cap(struct link_encoder *enc,
+	struct dc_link_settings *link_settings)
+{
+	/* Set Default link settings */
+	struct dc_link_settings max_link_cap = {LANE_COUNT_FOUR, LINK_RATE_HIGH,
+			LINK_SPREAD_05_DOWNSPREAD_30KHZ, false, 0};
+
+	/* Higher link settings based on feature supported */
+	if (enc->features.flags.bits.IS_HBR2_CAPABLE)
+		max_link_cap.link_rate = LINK_RATE_HIGH2;
+
+	if (enc->features.flags.bits.IS_HBR3_CAPABLE)
+		max_link_cap.link_rate = LINK_RATE_HIGH3;
+
+	*link_settings = max_link_cap;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h
index 3c9368df4093..384389f0e2c3 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h
@@ -271,4 +271,7 @@ void dce110_psr_program_secondary_packet(struct link_encoder *enc,
 
 bool dce110_is_dig_enabled(struct link_encoder *enc);
 
+void dce110_link_encoder_get_max_link_cap(struct link_encoder *enc,
+	struct dc_link_settings *link_settings);
+
 #endif /* __DC_LINK_ENCODER__DCE110_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c
new file mode 100644
index 000000000000..06435ecaf6a3
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c
@@ -0,0 +1,436 @@
+/*
+ * Copyright 2019 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "dmub_abm.h"
+#include "dce_abm.h"
+#include "dc.h"
+#include "dc_dmub_srv.h"
+#include "../../dmub/inc/dmub_srv.h"
+#include "core_types.h"
+#include "dm_services.h"
+#include "reg_helper.h"
+#include "fixed31_32.h"
+
+#include "atom.h"
+
+#define TO_DMUB_ABM(abm)\
+	container_of(abm, struct dce_abm, base)
+
+#define REG(reg) \
+	(dce_abm->regs->reg)
+
+#undef FN
+#define FN(reg_name, field_name) \
+	dce_abm->abm_shift->field_name, dce_abm->abm_mask->field_name
+
+#define CTX \
+	dce_abm->base.ctx
+
+#define DISABLE_ABM_IMMEDIATELY 255
+
+static bool dmub_abm_set_pipe(struct abm *abm, uint32_t otg_inst)
+{
+	union dmub_rb_cmd cmd;
+	struct dc_context *dc = abm->ctx;
+	uint32_t ramping_boundary = 0xFFFF;
+
+	cmd.abm_set_pipe.header.type = DMUB_CMD__ABM;
+	cmd.abm_set_pipe.header.sub_type = DMUB_CMD__ABM_SET_PIPE;
+	cmd.abm_set_pipe.abm_set_pipe_data.otg_inst = otg_inst;
+	cmd.abm_set_pipe.abm_set_pipe_data.ramping_boundary = ramping_boundary;
+	cmd.abm_set_pipe.header.payload_bytes = sizeof(struct dmub_cmd_abm_set_pipe_data);
+
+	dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd.abm_set_pipe.header);
+	dc_dmub_srv_cmd_execute(dc->dmub_srv);
+	dc_dmub_srv_wait_idle(dc->dmub_srv);
+
+	return true;
+}
+
+static unsigned int calculate_16_bit_backlight_from_pwm(struct dce_abm *dce_abm)
+{
+	uint64_t current_backlight;
+	uint32_t round_result;
+	uint32_t bl_period, bl_int_count;
+	uint32_t bl_pwm, fractional_duty_cycle_en;
+	uint32_t bl_period_mask, bl_pwm_mask;
+
+	REG_GET(BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD, &bl_period);
+	REG_GET(BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD_BITCNT, &bl_int_count);
+
+	REG_GET(BL_PWM_CNTL, BL_ACTIVE_INT_FRAC_CNT, &bl_pwm);
+	REG_GET(BL_PWM_CNTL, BL_PWM_FRACTIONAL_EN, &fractional_duty_cycle_en);
+
+	if (bl_int_count == 0)
+		bl_int_count = 16;
+
+	bl_period_mask = (1 << bl_int_count) - 1;
+	bl_period &= bl_period_mask;
+
+	bl_pwm_mask = bl_period_mask << (16 - bl_int_count);
+
+	if (fractional_duty_cycle_en == 0)
+		bl_pwm &= bl_pwm_mask;
+	else
+		bl_pwm &= 0xFFFF;
+
+	current_backlight = (uint64_t)bl_pwm << (1 + bl_int_count);
+
+	if (bl_period == 0)
+		bl_period = 0xFFFF;
+
+	current_backlight = div_u64(current_backlight, bl_period);
+	current_backlight = (current_backlight + 1) >> 1;
+
+	current_backlight = (uint64_t)(current_backlight) * bl_period;
+
+	round_result = (uint32_t)(current_backlight & 0xFFFFFFFF);
+
+	round_result = (round_result >> (bl_int_count-1)) & 1;
+
+	current_backlight >>= bl_int_count;
+	current_backlight += round_result;
+
+	return (uint32_t)(current_backlight);
+}
+
+static void dmcub_set_backlight_level(
+	struct dce_abm *dce_abm,
+	uint32_t backlight_pwm_u16_16,
+	uint32_t frame_ramp,
+	uint32_t otg_inst)
+{
+	union dmub_rb_cmd cmd;
+	struct dc_context *dc = dce_abm->base.ctx;
+	unsigned int backlight_8_bit = 0;
+	uint32_t s2;
+
+	if (backlight_pwm_u16_16 & 0x10000)
+		// Check for max backlight condition
+		backlight_8_bit = 0xFF;
+	else
+		// Take MSB of fractional part since backlight is not max
+		backlight_8_bit = (backlight_pwm_u16_16 >> 8) & 0xFF;
+
+	dmub_abm_set_pipe(&dce_abm->base, otg_inst);
+
+	if (otg_inst == 0)
+		frame_ramp = 0;
+
+	cmd.abm_set_backlight.header.type = DMUB_CMD__ABM;
+	cmd.abm_set_backlight.header.sub_type = DMUB_CMD__ABM_SET_BACKLIGHT;
+	cmd.abm_set_backlight.abm_set_backlight_data.frame_ramp = frame_ramp;
+	cmd.abm_set_backlight.header.payload_bytes = sizeof(struct dmub_cmd_abm_set_backlight_data);
+
+	dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd.abm_set_backlight.header);
+	dc_dmub_srv_cmd_execute(dc->dmub_srv);
+	dc_dmub_srv_wait_idle(dc->dmub_srv);
+
+	// Update requested backlight level
+	s2 = REG_READ(BIOS_SCRATCH_2);
+
+	s2 &= ~ATOM_S2_CURRENT_BL_LEVEL_MASK;
+	backlight_8_bit &= (ATOM_S2_CURRENT_BL_LEVEL_MASK >>
+				ATOM_S2_CURRENT_BL_LEVEL_SHIFT);
+	s2 |= (backlight_8_bit << ATOM_S2_CURRENT_BL_LEVEL_SHIFT);
+
+	REG_WRITE(BIOS_SCRATCH_2, s2);
+}
+
+static void dmub_abm_init(struct abm *abm)
+{
+	struct dce_abm *dce_abm = TO_DMUB_ABM(abm);
+	unsigned int backlight = calculate_16_bit_backlight_from_pwm(dce_abm);
+
+	REG_WRITE(DC_ABM1_HG_SAMPLE_RATE, 0x103);
+	REG_WRITE(DC_ABM1_HG_SAMPLE_RATE, 0x101);
+	REG_WRITE(DC_ABM1_LS_SAMPLE_RATE, 0x103);
+	REG_WRITE(DC_ABM1_LS_SAMPLE_RATE, 0x101);
+	REG_WRITE(BL1_PWM_BL_UPDATE_SAMPLE_RATE, 0x101);
+
+	REG_SET_3(DC_ABM1_HG_MISC_CTRL, 0,
+			ABM1_HG_NUM_OF_BINS_SEL, 0,
+			ABM1_HG_VMAX_SEL, 1,
+			ABM1_HG_BIN_BITWIDTH_SIZE_SEL, 0);
+
+	REG_SET_3(DC_ABM1_IPCSC_COEFF_SEL, 0,
+			ABM1_IPCSC_COEFF_SEL_R, 2,
+			ABM1_IPCSC_COEFF_SEL_G, 4,
+			ABM1_IPCSC_COEFF_SEL_B, 2);
+
+	REG_UPDATE(BL1_PWM_CURRENT_ABM_LEVEL,
+			BL1_PWM_CURRENT_ABM_LEVEL, backlight);
+
+	REG_UPDATE(BL1_PWM_TARGET_ABM_LEVEL,
+			BL1_PWM_TARGET_ABM_LEVEL, backlight);
+
+	REG_UPDATE(BL1_PWM_USER_LEVEL,
+			BL1_PWM_USER_LEVEL, backlight);
+
+	REG_UPDATE_2(DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES,
+			ABM1_LS_MIN_PIXEL_VALUE_THRES, 0,
+			ABM1_LS_MAX_PIXEL_VALUE_THRES, 1000);
+
+	REG_SET_3(DC_ABM1_HGLS_REG_READ_PROGRESS, 0,
+			ABM1_HG_REG_READ_MISSED_FRAME_CLEAR, 1,
+			ABM1_LS_REG_READ_MISSED_FRAME_CLEAR, 1,
+			ABM1_BL_REG_READ_MISSED_FRAME_CLEAR, 1);
+}
+
+static unsigned int dmub_abm_get_current_backlight(struct abm *abm)
+{
+	struct dce_abm *dce_abm = TO_DMUB_ABM(abm);
+	unsigned int backlight = REG_READ(BL1_PWM_CURRENT_ABM_LEVEL);
+
+	/* return backlight in hardware format which is unsigned 17 bits, with
+	 * 1 bit integer and 16 bit fractional
+	 */
+	return backlight;
+}
+
+static unsigned int dmub_abm_get_target_backlight(struct abm *abm)
+{
+	struct dce_abm *dce_abm = TO_DMUB_ABM(abm);
+	unsigned int backlight = REG_READ(BL1_PWM_TARGET_ABM_LEVEL);
+
+	/* return backlight in hardware format which is unsigned 17 bits, with
+	 * 1 bit integer and 16 bit fractional
+	 */
+	return backlight;
+}
+
+static bool dmub_abm_set_level(struct abm *abm, uint32_t level)
+{
+	union dmub_rb_cmd cmd;
+	struct dc_context *dc = abm->ctx;
+
+	cmd.abm_set_level.header.type = DMUB_CMD__ABM;
+	cmd.abm_set_level.header.sub_type = DMUB_CMD__ABM_SET_LEVEL;
+	cmd.abm_set_level.abm_set_level_data.level = level;
+	cmd.abm_set_level.header.payload_bytes = sizeof(struct dmub_cmd_abm_set_level_data);
+
+	dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd.abm_set_level.header);
+	dc_dmub_srv_cmd_execute(dc->dmub_srv);
+	dc_dmub_srv_wait_idle(dc->dmub_srv);
+
+	return true;
+}
+
+static bool dmub_abm_immediate_disable(struct abm *abm)
+{
+	struct dce_abm *dce_abm = TO_DMUB_ABM(abm);
+
+	dmub_abm_set_pipe(abm, DISABLE_ABM_IMMEDIATELY);
+
+	abm->stored_backlight_registers.BL_PWM_CNTL =
+		REG_READ(BL_PWM_CNTL);
+	abm->stored_backlight_registers.BL_PWM_CNTL2 =
+		REG_READ(BL_PWM_CNTL2);
+	abm->stored_backlight_registers.BL_PWM_PERIOD_CNTL =
+		REG_READ(BL_PWM_PERIOD_CNTL);
+
+	REG_GET(LVTMA_PWRSEQ_REF_DIV, BL_PWM_REF_DIV,
+		&abm->stored_backlight_registers.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV);
+
+	return true;
+}
+
+static void dmub_abm_enable_fractional_pwm(struct dc_context *dc)
+{
+	union dmub_rb_cmd cmd;
+	uint32_t fractional_pwm = (dc->dc->config.disable_fractional_pwm == false) ? 1 : 0;
+
+	cmd.abm_set_pwm_frac.header.type = DMUB_CMD__ABM;
+	cmd.abm_set_pwm_frac.header.sub_type = DMUB_CMD__ABM_SET_PWM_FRAC;
+	cmd.abm_set_pwm_frac.abm_set_pwm_frac_data.fractional_pwm = fractional_pwm;
+	cmd.abm_set_pwm_frac.header.payload_bytes = sizeof(struct dmub_cmd_abm_set_pwm_frac_data);
+
+	dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd.abm_set_pwm_frac.header);
+	dc_dmub_srv_cmd_execute(dc->dmub_srv);
+	dc_dmub_srv_wait_idle(dc->dmub_srv);
+}
+
+static bool dmub_abm_init_backlight(struct abm *abm)
+{
+	struct dce_abm *dce_abm = TO_DMUB_ABM(abm);
+	uint32_t value;
+
+	dmub_abm_enable_fractional_pwm(abm->ctx);
+
+	/* It must not be 0, so we have to restore them
+	 * Bios bug w/a - period resets to zero,
+	 * restoring to cache values which is always correct
+	 */
+	REG_GET(BL_PWM_CNTL, BL_ACTIVE_INT_FRAC_CNT, &value);
+
+	if (value == 0 || value == 1) {
+		if (abm->stored_backlight_registers.BL_PWM_CNTL != 0) {
+			REG_WRITE(BL_PWM_CNTL,
+				abm->stored_backlight_registers.BL_PWM_CNTL);
+			REG_WRITE(BL_PWM_CNTL2,
+				abm->stored_backlight_registers.BL_PWM_CNTL2);
+			REG_WRITE(BL_PWM_PERIOD_CNTL,
+				abm->stored_backlight_registers.BL_PWM_PERIOD_CNTL);
+			REG_UPDATE(LVTMA_PWRSEQ_REF_DIV,
+				BL_PWM_REF_DIV,
+				abm->stored_backlight_registers.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV);
+		} else {
+			/* TODO: Note: This should not really happen since VBIOS
+			 * should have initialized PWM registers on boot.
+			 */
+			REG_WRITE(BL_PWM_CNTL, 0xC000FA00);
+			REG_WRITE(BL_PWM_PERIOD_CNTL, 0x000C0FA0);
+		}
+	} else {
+		abm->stored_backlight_registers.BL_PWM_CNTL =
+				REG_READ(BL_PWM_CNTL);
+		abm->stored_backlight_registers.BL_PWM_CNTL2 =
+				REG_READ(BL_PWM_CNTL2);
+		abm->stored_backlight_registers.BL_PWM_PERIOD_CNTL =
+				REG_READ(BL_PWM_PERIOD_CNTL);
+
+		REG_GET(LVTMA_PWRSEQ_REF_DIV, BL_PWM_REF_DIV,
+				&abm->stored_backlight_registers.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV);
+	}
+
+	// Have driver take backlight control
+	// TakeBacklightControl(true)
+	value = REG_READ(BIOS_SCRATCH_2);
+	value |= ATOM_S2_VRI_BRIGHT_ENABLE;
+	REG_WRITE(BIOS_SCRATCH_2, value);
+
+	// Enable the backlight output
+	REG_UPDATE(BL_PWM_CNTL, BL_PWM_EN, 1);
+
+	// Unlock group 2 backlight registers
+	REG_UPDATE(BL_PWM_GRP1_REG_LOCK,
+			BL_PWM_GRP1_REG_LOCK, 0);
+
+	return true;
+}
+
+static bool dmub_abm_set_backlight_level_pwm(
+		struct abm *abm,
+		unsigned int backlight_pwm_u16_16,
+		unsigned int frame_ramp,
+		unsigned int otg_inst,
+		bool use_smooth_brightness)
+{
+	struct dce_abm *dce_abm = TO_DMUB_ABM(abm);
+
+	dmcub_set_backlight_level(dce_abm,
+			backlight_pwm_u16_16,
+			frame_ramp,
+			otg_inst);
+
+	return true;
+}
+
+static bool dmub_abm_init_config(struct abm *abm,
+	const char *src,
+	unsigned int bytes)
+{
+	union dmub_rb_cmd cmd;
+	struct dc_context *dc = abm->ctx;
+
+	// TODO: Optimize by only reading back final 4 bytes
+	dmub_flush_buffer_mem(&dc->dmub_srv->dmub->scratch_mem_fb);
+
+	// Copy iramtable into cw7
+	memcpy(dc->dmub_srv->dmub->scratch_mem_fb.cpu_addr, (void *)src, bytes);
+
+	// Fw will copy from cw7 to fw_state
+	cmd.abm_init_config.header.type = DMUB_CMD__ABM;
+	cmd.abm_init_config.header.sub_type = DMUB_CMD__ABM_INIT_CONFIG;
+	cmd.abm_init_config.abm_init_config_data.src.quad_part = dc->dmub_srv->dmub->scratch_mem_fb.gpu_addr;
+	cmd.abm_init_config.abm_init_config_data.bytes = bytes;
+	cmd.abm_init_config.header.payload_bytes = sizeof(struct dmub_cmd_abm_init_config_data);
+
+	dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd.abm_init_config.header);
+	dc_dmub_srv_cmd_execute(dc->dmub_srv);
+	dc_dmub_srv_wait_idle(dc->dmub_srv);
+
+	return true;
+}
+
+static const struct abm_funcs abm_funcs = {
+	.abm_init = dmub_abm_init,
+	.set_abm_level = dmub_abm_set_level,
+	.init_backlight = dmub_abm_init_backlight,
+	.set_pipe = dmub_abm_set_pipe,
+	.set_backlight_level_pwm = dmub_abm_set_backlight_level_pwm,
+	.get_current_backlight = dmub_abm_get_current_backlight,
+	.get_target_backlight = dmub_abm_get_target_backlight,
+	.set_abm_immediate_disable = dmub_abm_immediate_disable,
+	.init_abm_config = dmub_abm_init_config,
+};
+
+static void dmub_abm_construct(
+	struct dce_abm *abm_dce,
+	struct dc_context *ctx,
+	const struct dce_abm_registers *regs,
+	const struct dce_abm_shift *abm_shift,
+	const struct dce_abm_mask *abm_mask)
+{
+	struct abm *base = &abm_dce->base;
+
+	base->ctx = ctx;
+	base->funcs = &abm_funcs;
+	base->stored_backlight_registers.BL_PWM_CNTL = 0;
+	base->stored_backlight_registers.BL_PWM_CNTL2 = 0;
+	base->stored_backlight_registers.BL_PWM_PERIOD_CNTL = 0;
+	base->stored_backlight_registers.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV = 0;
+	base->dmcu_is_running = false;
+
+	abm_dce->regs = regs;
+	abm_dce->abm_shift = abm_shift;
+	abm_dce->abm_mask = abm_mask;
+}
+
+struct abm *dmub_abm_create(
+	struct dc_context *ctx,
+	const struct dce_abm_registers *regs,
+	const struct dce_abm_shift *abm_shift,
+	const struct dce_abm_mask *abm_mask)
+{
+	struct dce_abm *abm_dce = kzalloc(sizeof(*abm_dce), GFP_KERNEL);
+
+	if (abm_dce == NULL) {
+		BREAK_TO_DEBUGGER();
+		return NULL;
+	}
+
+	dmub_abm_construct(abm_dce, ctx, regs, abm_shift, abm_mask);
+
+	return &abm_dce->base;
+}
+
+void dmub_abm_destroy(struct abm **abm)
+{
+	struct dce_abm *abm_dce = TO_DMUB_ABM(*abm);
+
+	kfree(abm_dce);
+	*abm = NULL;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.h b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.h
new file mode 100644
index 000000000000..3a5d5ac7a86e
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2019 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DMUB_ABM_H__
+#define __DMUB_ABM_H__
+
+#include "abm.h"
+#include "dce_abm.h"
+
+struct abm *dmub_abm_create(
+	struct dc_context *ctx,
+	const struct dce_abm_registers *regs,
+	const struct dce_abm_shift *abm_shift,
+	const struct dce_abm_mask *abm_mask);
+
+void dmub_abm_destroy(struct abm **abm);
+
+#endif
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
index bc109d4fc6e6..31a9b12ff880 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
@@ -60,9 +60,6 @@ static bool dmub_psr_set_version(struct dmub_psr *dmub, struct dc_stream_state *
 		return false;
 	else if (stream->psr_version == 0x1)
 		cmd.psr_set_version.psr_set_version_data.version = PSR_VERSION_1;
-	else if (stream->psr_version == 0x2)
-		cmd.psr_set_version.psr_set_version_data.version = PSR_VERSION_2;
-
 	cmd.psr_enable.header.payload_bytes = sizeof(struct dmub_cmd_psr_set_version_data);
 
 	dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd.psr_enable.header);
diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce80/dce80_hw_sequencer.c
index 893261c81854..d2ceebdbdf51 100644
--- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dce80/dce80_hw_sequencer.c
@@ -36,34 +36,6 @@
 #include "dce/dce_8_0_d.h"
 #include "dce/dce_8_0_sh_mask.h"
 
-struct dce80_hw_seq_reg_offsets {
-	uint32_t crtc;
-};
-
-static const struct dce80_hw_seq_reg_offsets reg_offsets[] = {
-{
-	.crtc = (mmCRTC0_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
-},
-{
-	.crtc = (mmCRTC1_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
-},
-{
-	.crtc = (mmCRTC2_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
-},
-{
-	.crtc = (mmCRTC3_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
-},
-{
-	.crtc = (mmCRTC4_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
-},
-{
-	.crtc = (mmCRTC5_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
-}
-};
-
-#define HW_REG_CRTC(reg, id)\
-	(reg + reg_offsets[id].crtc)
-
 /*******************************************************************************
  * Private definitions
  ******************************************************************************/
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
index b0357546471b..9f41efddc9bc 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
@@ -1238,7 +1238,7 @@ void dcn10_init_pipes(struct dc *dc, struct dc_state *context)
 
 void dcn10_init_hw(struct dc *dc)
 {
-	int i;
+	int i, j;
 	struct abm *abm = dc->res_pool->abm;
 	struct dmcu *dmcu = dc->res_pool->dmcu;
 	struct dce_hwseq *hws = dc->hwseq;
@@ -1342,8 +1342,21 @@ void dcn10_init_hw(struct dc *dc)
 				/* if any of the displays are lit up turn them off */
 				status = core_link_read_dpcd(dc->links[i], DP_SET_POWER,
 								&dpcd_power_state, sizeof(dpcd_power_state));
-				if (status == DC_OK && dpcd_power_state == DP_POWER_STATE_D0)
+				if (status == DC_OK && dpcd_power_state == DP_POWER_STATE_D0) {
+					/* blank dp stream before power off receiver*/
+					if (dc->links[i]->link_enc->funcs->get_dig_frontend) {
+						unsigned int fe = dc->links[i]->link_enc->funcs->get_dig_frontend(dc->links[i]->link_enc);
+
+						for (j = 0; j < dc->res_pool->stream_enc_count; j++) {
+							if (fe == dc->res_pool->stream_enc[j]->id) {
+								dc->res_pool->stream_enc[j]->funcs->dp_blank(
+											dc->res_pool->stream_enc[j]);
+								break;
+							}
+						}
+					}
 					dp_receiver_power_ctrl(dc->links[i], false);
+				}
 			}
 		}
 	}
@@ -1361,6 +1374,38 @@ void dcn10_init_hw(struct dc *dc)
 					!dc->res_pool->hubbub->ctx->dc->debug.disable_stutter);
 	}
 
+	/* In headless boot cases, DIG may be turned
+	 * on which causes HW/SW discrepancies.
+	 * To avoid this, power down hardware on boot
+	 * if DIG is turned on and seamless boot not enabled
+	 */
+	if (dc->config.power_down_display_on_boot) {
+		struct dc_link *edp_link = get_edp_link(dc);
+
+		if (edp_link &&
+				edp_link->link_enc->funcs->is_dig_enabled &&
+				edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc) &&
+				dc->hwss.edp_backlight_control &&
+				dc->hwss.power_down &&
+				dc->hwss.edp_power_control) {
+			dc->hwss.edp_backlight_control(edp_link, false);
+			dc->hwss.power_down(dc);
+			dc->hwss.edp_power_control(edp_link, false);
+		} else {
+			for (i = 0; i < dc->link_count; i++) {
+				struct dc_link *link = dc->links[i];
+
+				if (link->link_enc->funcs->is_dig_enabled &&
+						link->link_enc->funcs->is_dig_enabled(link->link_enc) &&
+						dc->hwss.power_down) {
+					dc->hwss.power_down(dc);
+					break;
+				}
+
+			}
+		}
+	}
+
 	for (i = 0; i < res_pool->audio_count; i++) {
 		struct audio *audio = res_pool->audios[i];
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c
index d3617d6785a7..7fd385be3f3d 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c
@@ -90,7 +90,8 @@ static const struct link_encoder_funcs dcn10_lnk_enc_funcs = {
 	.is_dig_enabled = dcn10_is_dig_enabled,
 	.get_dig_frontend = dcn10_get_dig_frontend,
 	.get_dig_mode = dcn10_get_dig_mode,
-	.destroy = dcn10_link_encoder_destroy
+	.destroy = dcn10_link_encoder_destroy,
+	.get_max_link_cap = dcn10_link_encoder_get_max_link_cap,
 };
 
 static enum bp_result link_transmitter_control(
@@ -1370,7 +1371,6 @@ void dcn10_link_encoder_disable_hpd(struct link_encoder *enc)
 			DC_HPD_EN, 0);
 }
 
-
 #define AUX_REG(reg)\
 	(enc10->aux_regs->reg)
 
@@ -1425,3 +1425,19 @@ enum signal_type dcn10_get_dig_mode(
 	return SIGNAL_TYPE_NONE;
 }
 
+void dcn10_link_encoder_get_max_link_cap(struct link_encoder *enc,
+	struct dc_link_settings *link_settings)
+{
+	/* Set Default link settings */
+	struct dc_link_settings max_link_cap = {LANE_COUNT_FOUR, LINK_RATE_HIGH,
+			LINK_SPREAD_05_DOWNSPREAD_30KHZ, false, 0};
+
+	/* Higher link settings based on feature supported */
+	if (enc->features.flags.bits.IS_HBR2_CAPABLE)
+		max_link_cap.link_rate = LINK_RATE_HIGH2;
+
+	if (enc->features.flags.bits.IS_HBR3_CAPABLE)
+		max_link_cap.link_rate = LINK_RATE_HIGH3;
+
+	*link_settings = max_link_cap;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h
index 762109174fb8..68395bcc24fd 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h
@@ -575,4 +575,7 @@ void dcn10_aux_initialize(struct dcn10_link_encoder *enc10);
 
 enum signal_type dcn10_get_dig_mode(
 	struct link_encoder *enc);
+
+void dcn10_link_encoder_get_max_link_cap(struct link_encoder *enc,
+	struct dc_link_settings *link_settings);
 #endif /* __DC_LINK_ENCODER__DCN10_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c
index 17d96ec6acd8..ec0ab42becba 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c
@@ -299,6 +299,7 @@ void optc1_set_vtg_params(struct timing_generator *optc,
 	uint32_t asic_blank_end;
 	uint32_t v_init;
 	uint32_t v_fp2 = 0;
+	int32_t vertical_line_start;
 
 	struct optc *optc1 = DCN10TG_FROM_TG(optc);
 
@@ -315,8 +316,9 @@ void optc1_set_vtg_params(struct timing_generator *optc,
 			patched_crtc_timing.v_border_top;
 
 	/* if VSTARTUP is before VSYNC, FP2 is the offset, otherwise 0 */
-	if (optc1->vstartup_start > asic_blank_end)
-		v_fp2 = optc1->vstartup_start - asic_blank_end;
+	vertical_line_start = asic_blank_end - optc1->vstartup_start + 1;
+	if (vertical_line_start < 0)
+		v_fp2 = -vertical_line_start;
 
 	/* Interlace */
 	if (REG(OTG_INTERLACE_CONTROL)) {
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
index 22f421e82733..7e65c774c800 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -2171,6 +2171,12 @@ void dcn20_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
 	 */
 	mpcc_id = hubp->inst;
 
+	/* If there is no full update, don't need to touch MPC tree*/
+	if (!pipe_ctx->plane_state->update_flags.bits.full_update) {
+		mpc->funcs->update_blending(mpc, &blnd_cfg, mpcc_id);
+		return;
+	}
+
 	/* check if this MPCC is already being used */
 	new_mpcc = mpc->funcs->get_mpcc_for_dpp(mpc_tree_params, mpcc_id);
 	/* remove MPCC if being used */
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.c
index e4ac73035c84..8d209dae66e6 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.c
@@ -49,6 +49,12 @@
 #define IND_REG(index) \
 	(enc10->link_regs->index)
 
+#ifndef MAX
+#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
+#endif
+#ifndef MIN
+#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
+#endif
 
 static struct mpll_cfg dcn2_mpll_cfg[] = {
 	// RBR
@@ -260,6 +266,38 @@ void dcn20_link_encoder_enable_dp_output(
 
 }
 
+void dcn20_link_encoder_get_max_link_cap(struct link_encoder *enc,
+	struct dc_link_settings *link_settings)
+{
+	struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
+	uint32_t is_in_usb_c_dp4_mode = 0;
+
+	dcn10_link_encoder_get_max_link_cap(enc, link_settings);
+
+	/* in usb c dp2 mode, max lane count is 2 */
+	if (enc->funcs->is_in_alt_mode && enc->funcs->is_in_alt_mode(enc)) {
+		REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, &is_in_usb_c_dp4_mode);
+		if (!is_in_usb_c_dp4_mode)
+			link_settings->lane_count = MIN(LANE_COUNT_TWO, link_settings->lane_count);
+	}
+
+}
+
+bool dcn20_link_encoder_is_in_alt_mode(struct link_encoder *enc)
+{
+	struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
+	uint32_t dp_alt_mode_disable = 0;
+	bool is_usb_c_alt_mode = false;
+
+	if (enc->features.flags.bits.DP_IS_USB_C) {
+		/* if value == 1 alt mode is disabled, otherwise it is enabled */
+		REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &dp_alt_mode_disable);
+		is_usb_c_alt_mode = (dp_alt_mode_disable == 0);
+	}
+
+	return is_usb_c_alt_mode;
+}
+
 #define AUX_REG(reg)\
 	(enc10->aux_regs->reg)
 
@@ -338,6 +376,8 @@ static const struct link_encoder_funcs dcn20_link_enc_funcs = {
 	.fec_is_active = enc2_fec_is_active,
 	.get_dig_mode = dcn10_get_dig_mode,
 	.get_dig_frontend = dcn10_get_dig_frontend,
+	.is_in_alt_mode = dcn20_link_encoder_is_in_alt_mode,
+	.get_max_link_cap = dcn20_link_encoder_get_max_link_cap,
 };
 
 void dcn20_link_encoder_construct(
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.h
index 8cab8107fd94..284a1ee4d249 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.h
@@ -343,6 +343,10 @@ void dcn20_link_encoder_enable_dp_output(
 	const struct dc_link_settings *link_settings,
 	enum clock_source_id clock_source);
 
+bool dcn20_link_encoder_is_in_alt_mode(struct link_encoder *enc);
+void dcn20_link_encoder_get_max_link_cap(struct link_encoder *enc,
+	struct dc_link_settings *link_settings);
+
 void dcn20_link_encoder_construct(
 	struct dcn20_link_encoder *enc20,
 	const struct encoder_init_data *init_data,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
index 5cdbba0cd873..9e1d2b2e58f9 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
@@ -2212,12 +2212,12 @@ int dcn20_populate_dml_pipes_from_context(
 					|| pipes[pipe_cnt].pipe.dest.odm_combine != dm_odm_combine_mode_disabled;
 			pipes[pipe_cnt].pipe.src.source_scan = pln->rotation == ROTATION_ANGLE_90
 					|| pln->rotation == ROTATION_ANGLE_270 ? dm_vert : dm_horz;
-			pipes[pipe_cnt].pipe.src.viewport_y_y = scl->viewport.y;
-			pipes[pipe_cnt].pipe.src.viewport_y_c = scl->viewport_c.y;
-			pipes[pipe_cnt].pipe.src.viewport_width = scl->viewport.width;
-			pipes[pipe_cnt].pipe.src.viewport_width_c = scl->viewport_c.width;
-			pipes[pipe_cnt].pipe.src.viewport_height = scl->viewport.height;
-			pipes[pipe_cnt].pipe.src.viewport_height_c = scl->viewport_c.height;
+			pipes[pipe_cnt].pipe.src.viewport_y_y = scl->viewport_unadjusted.y;
+			pipes[pipe_cnt].pipe.src.viewport_y_c = scl->viewport_c_unadjusted.y;
+			pipes[pipe_cnt].pipe.src.viewport_width = scl->viewport_unadjusted.width;
+			pipes[pipe_cnt].pipe.src.viewport_width_c = scl->viewport_c_unadjusted.width;
+			pipes[pipe_cnt].pipe.src.viewport_height = scl->viewport_unadjusted.height;
+			pipes[pipe_cnt].pipe.src.viewport_height_c = scl->viewport_c_unadjusted.height;
 			pipes[pipe_cnt].pipe.src.surface_width_y = pln->plane_size.surface_size.width;
 			pipes[pipe_cnt].pipe.src.surface_height_y = pln->plane_size.surface_size.height;
 			pipes[pipe_cnt].pipe.src.surface_width_c = pln->plane_size.chroma_size.width;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c
index b9ff9767e08f..a6ed70fcbc19 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c
@@ -90,6 +90,7 @@ static const struct hw_sequencer_funcs dcn21_funcs = {
 	.set_cursor_sdr_white_level = dcn10_set_cursor_sdr_white_level,
 	.optimize_pwr_state = dcn21_optimize_pwr_state,
 	.exit_optimized_pwr_state = dcn21_exit_optimized_pwr_state,
+	.power_down = dce110_power_down,
 };
 
 static const struct hwseq_private_funcs dcn21_private_funcs = {
diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_link_encoder.c
index e45683ac871a..aa46c35b05a2 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_link_encoder.c
@@ -203,29 +203,6 @@ static bool update_cfg_data(
 	return true;
 }
 
-void dcn21_link_encoder_get_max_link_cap(struct link_encoder *enc,
-	struct dc_link_settings *link_settings)
-{
-	struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
-	uint32_t value;
-
-	REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, &value);
-
-	if (!value && link_settings->lane_count > LANE_COUNT_TWO)
-		link_settings->lane_count = LANE_COUNT_TWO;
-}
-
-bool dcn21_link_encoder_is_in_alt_mode(struct link_encoder *enc)
-{
-	struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
-	uint32_t value;
-
-	REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &value);
-
-	// if value == 1 alt mode is disabled, otherwise it is enabled
-	return !value;
-}
-
 bool dcn21_link_encoder_acquire_phy(struct link_encoder *enc)
 {
 	struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
@@ -348,8 +325,8 @@ static const struct link_encoder_funcs dcn21_link_enc_funcs = {
 	.fec_set_ready = enc2_fec_set_ready,
 	.fec_is_active = enc2_fec_is_active,
 	.get_dig_frontend = dcn10_get_dig_frontend,
-	.is_in_alt_mode = dcn21_link_encoder_is_in_alt_mode,
-	.get_max_link_cap = dcn21_link_encoder_get_max_link_cap,
+	.is_in_alt_mode = dcn20_link_encoder_is_in_alt_mode,
+	.get_max_link_cap = dcn20_link_encoder_get_max_link_cap,
 };
 
 void dcn21_link_encoder_construct(
diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
index b25484aa8222..0e638a77b5ee 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
@@ -85,6 +85,7 @@
 #include "vm_helper.h"
 #include "dcn20/dcn20_vmid.h"
 #include "dce/dmub_psr.h"
+#include "dce/dmub_abm.h"
 
 #define SOC_BOUNDING_BOX_VALID false
 #define DC_LOGGER_INIT(logger)
@@ -991,9 +992,12 @@ static void dcn21_resource_destruct(struct dcn21_resource_pool *pool)
 		pool->base.dp_clock_source = NULL;
 	}
 
-
-	if (pool->base.abm != NULL)
-		dce_abm_destroy(&pool->base.abm);
+	if (pool->base.abm != NULL) {
+		if (pool->base.abm->ctx->dc->config.disable_dmcu)
+			dmub_abm_destroy(&pool->base.abm);
+		else
+			dce_abm_destroy(&pool->base.abm);
+	}
 
 	if (pool->base.dmcu != NULL)
 		dce_dmcu_destroy(&pool->base.dmcu);
@@ -1842,17 +1846,19 @@ static bool dcn21_resource_construct(
 		goto create_fail;
 	}
 
-	pool->base.dmcu = dcn21_dmcu_create(ctx,
-			&dmcu_regs,
-			&dmcu_shift,
-			&dmcu_mask);
-	if (pool->base.dmcu == NULL) {
-		dm_error("DC: failed to create dmcu!\n");
-		BREAK_TO_DEBUGGER();
-		goto create_fail;
+	if (!dc->config.disable_dmcu) {
+		pool->base.dmcu = dcn21_dmcu_create(ctx,
+				&dmcu_regs,
+				&dmcu_shift,
+				&dmcu_mask);
+		if (pool->base.dmcu == NULL) {
+			dm_error("DC: failed to create dmcu!\n");
+			BREAK_TO_DEBUGGER();
+			goto create_fail;
+		}
 	}
 
-	if (dc->debug.disable_dmcu) {
+	if (dc->config.disable_dmcu) {
 		pool->base.psr = dmub_psr_create(ctx);
 
 		if (pool->base.psr == NULL) {
@@ -1862,15 +1868,16 @@ static bool dcn21_resource_construct(
 		}
 	}
 
-	pool->base.abm = dce_abm_create(ctx,
+	if (dc->config.disable_dmcu)
+		pool->base.abm = dmub_abm_create(ctx,
+			&abm_regs,
+			&abm_shift,
+			&abm_mask);
+	else
+		pool->base.abm = dce_abm_create(ctx,
 			&abm_regs,
 			&abm_shift,
 			&abm_mask);
-	if (pool->base.abm == NULL) {
-		dm_error("DC: failed to create abm!\n");
-		BREAK_TO_DEBUGGER();
-		goto create_fail;
-	}
 
 	pool->base.pp_smu = dcn21_pp_smu_create(ctx);
 
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c
index 5bbbafacc720..922ab7169e52 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c
@@ -2614,6 +2614,7 @@ static void dml20v2_DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndP
 
 	if (mode_lib->vba.DRAMClockChangeSupportsVActive &&
 			mode_lib->vba.MinActiveDRAMClockChangeMargin > 60) {
+		mode_lib->vba.DRAMClockChangeWatermark += 25;
 
 		for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
 			if (mode_lib->vba.PrefetchMode[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb] == 0) {
@@ -2622,7 +2623,7 @@ static void dml20v2_DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndP
 					mode_lib->vba.MinTTUVBlank[k] += 25;
 			}
 		}
-		mode_lib->vba.DRAMClockChangeWatermark += 25;
+
 		mode_lib->vba.DRAMClockChangeSupport[0][0] = dm_dram_clock_change_vactive;
 	} else if (mode_lib->vba.DummyPStateCheck &&
 			mode_lib->vba.MinActiveDRAMClockChangeMargin > 0) {
diff --git a/drivers/gpu/drm/amd/display/dc/hdcp/hdcp_msg.c b/drivers/gpu/drm/amd/display/dc/hdcp/hdcp_msg.c
index 6f730b5bfe42..5e384a8a83dc 100644
--- a/drivers/gpu/drm/amd/display/dc/hdcp/hdcp_msg.c
+++ b/drivers/gpu/drm/amd/display/dc/hdcp/hdcp_msg.c
@@ -322,3 +322,92 @@ static const struct protection_properties dp_11_protection = {
 	.process_transaction = dp_11_process_transaction
 };
 
+static const struct protection_properties *get_protection_properties_by_signal(
+	struct dc_link *link,
+	enum signal_type st,
+	enum hdcp_version version)
+{
+	switch (version) {
+	case HDCP_VERSION_14:
+		switch (st) {
+		case SIGNAL_TYPE_DVI_SINGLE_LINK:
+		case SIGNAL_TYPE_DVI_DUAL_LINK:
+		case SIGNAL_TYPE_HDMI_TYPE_A:
+			return &hdmi_14_protection;
+		case SIGNAL_TYPE_DISPLAY_PORT:
+			if (link &&
+				(link->dpcd_caps.dongle_type == DISPLAY_DONGLE_DP_VGA_CONVERTER ||
+				link->dpcd_caps.dongle_caps.dongle_type == DISPLAY_DONGLE_DP_VGA_CONVERTER)) {
+				return &non_supported_protection;
+			}
+			return &dp_11_protection;
+		case SIGNAL_TYPE_DISPLAY_PORT_MST:
+		case SIGNAL_TYPE_EDP:
+			return &dp_11_protection;
+		default:
+			return &non_supported_protection;
+		}
+		break;
+	case HDCP_VERSION_22:
+		switch (st) {
+		case SIGNAL_TYPE_DVI_SINGLE_LINK:
+		case SIGNAL_TYPE_DVI_DUAL_LINK:
+		case SIGNAL_TYPE_HDMI_TYPE_A:
+			return &hdmi_14_protection; //todo version2.2
+		case SIGNAL_TYPE_DISPLAY_PORT:
+		case SIGNAL_TYPE_DISPLAY_PORT_MST:
+		case SIGNAL_TYPE_EDP:
+			return &dp_11_protection;  //todo version2.2
+		default:
+			return &non_supported_protection;
+		}
+		break;
+	default:
+		return &non_supported_protection;
+	}
+}
+
+enum hdcp_message_status dc_process_hdcp_msg(
+	enum signal_type signal,
+	struct dc_link *link,
+	struct hdcp_protection_message *message_info)
+{
+	enum hdcp_message_status status = HDCP_MESSAGE_FAILURE;
+	uint32_t i = 0;
+
+	const struct protection_properties *protection_props;
+
+	if (!message_info)
+		return HDCP_MESSAGE_UNSUPPORTED;
+
+	if (message_info->msg_id < HDCP_MESSAGE_ID_READ_BKSV ||
+		message_info->msg_id >= HDCP_MESSAGE_ID_MAX)
+		return HDCP_MESSAGE_UNSUPPORTED;
+
+	protection_props =
+		get_protection_properties_by_signal(
+			link,
+			signal,
+			message_info->version);
+
+	if (!protection_props->supported)
+		return HDCP_MESSAGE_UNSUPPORTED;
+
+	if (protection_props->process_transaction(
+		link,
+		message_info)) {
+		status = HDCP_MESSAGE_SUCCESS;
+	} else {
+		for (i = 0; i < message_info->max_retries; i++) {
+			if (protection_props->process_transaction(
+						link,
+						message_info)) {
+				status = HDCP_MESSAGE_SUCCESS;
+				break;
+			}
+		}
+	}
+
+	return status;
+}
+
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h b/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h
index d607b3191954..0cae258a903e 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h
@@ -60,6 +60,9 @@ struct abm_funcs {
 
 	unsigned int (*get_current_backlight)(struct abm *abm);
 	unsigned int (*get_target_backlight)(struct abm *abm);
+	bool (*init_abm_config)(struct abm *abm,
+			const char *src,
+			unsigned int bytes);
 };
 
 #endif
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h b/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h
index fecc80c47c26..2947d1b15512 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h
@@ -173,6 +173,8 @@ struct scaler_data {
 	struct scaling_taps taps;
 	struct rect viewport;
 	struct rect viewport_c;
+	struct rect viewport_unadjusted;
+	struct rect viewport_c_unadjusted;
 	struct rect recout;
 	struct scaling_ratios ratios;
 	struct scl_inits inits;
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
index d4c1fb242c63..9380721f28b8 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
@@ -75,9 +75,13 @@ struct hw_sequencer_funcs {
 	void (*wait_for_mpcc_disconnect)(struct dc *dc,
 			struct resource_pool *res_pool,
 			struct pipe_ctx *pipe_ctx);
+	void (*edp_backlight_control)(
+			struct dc_link *link,
+			bool enable);
 	void (*program_triplebuffer)(const struct dc *dc,
 		struct pipe_ctx *pipe_ctx, bool enableTripleBuffer);
 	void (*update_pending_status)(struct pipe_ctx *pipe_ctx);
+	void (*power_down)(struct dc *dc);
 
 	/* Pipe Lock Related */
 	void (*pipe_control_lock)(struct dc *dc,
diff --git a/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c b/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c
index 3464b2d5b89a..348e9a600a72 100644
--- a/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c
@@ -84,6 +84,14 @@ static void virtual_link_encoder_destroy(struct link_encoder **enc)
 	*enc = NULL;
 }
 
+static void virtual_link_encoder_get_max_link_cap(struct link_encoder *enc,
+		struct dc_link_settings *link_settings)
+{
+	/* Set Default link settings */
+	struct dc_link_settings max_link_cap = {LANE_COUNT_FOUR, LINK_RATE_HIGH,
+				LINK_SPREAD_05_DOWNSPREAD_30KHZ, false, 0};
+	*link_settings = max_link_cap;
+}
 
 static const struct link_encoder_funcs virtual_lnk_enc_funcs = {
 	.validate_output_with_stream =
@@ -94,6 +102,7 @@ static const struct link_encoder_funcs virtual_lnk_enc_funcs = {
 	.enable_dp_output = virtual_link_encoder_enable_dp_output,
 	.enable_dp_mst_output = virtual_link_encoder_enable_dp_mst_output,
 	.disable_output = virtual_link_encoder_disable_output,
+	.get_max_link_cap = virtual_link_encoder_get_max_link_cap,
 	.dp_set_lane_settings = virtual_link_encoder_dp_set_lane_settings,
 	.dp_set_phy_pattern = virtual_link_encoder_dp_set_phy_pattern,
 	.update_mst_stream_allocation_table =
diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
index 10b5fa9d2588..0a996e575b9f 100644
--- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
+++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
@@ -303,6 +303,16 @@ struct dmub_rb_cmd_abm_set_pwm_frac {
 	struct dmub_cmd_abm_set_pwm_frac_data abm_set_pwm_frac_data;
 };
 
+struct dmub_cmd_abm_init_config_data {
+	union dmub_addr src;
+	uint16_t bytes;
+};
+
+struct dmub_rb_cmd_abm_init_config {
+	struct dmub_cmd_header header;
+	struct dmub_cmd_abm_init_config_data abm_init_config_data;
+};
+
 union dmub_rb_cmd {
 	struct dmub_rb_cmd_read_modify_write read_modify_write;
 	struct dmub_rb_cmd_reg_field_update_sequence reg_field_update_seq;
@@ -324,6 +334,7 @@ union dmub_rb_cmd {
 	struct dmub_rb_cmd_abm_set_level abm_set_level;
 	struct dmub_rb_cmd_abm_set_ambient_level abm_set_ambient_level;
 	struct dmub_rb_cmd_abm_set_pwm_frac abm_set_pwm_frac;
+	struct dmub_rb_cmd_abm_init_config abm_init_config;
 };
 
 #pragma pack(pop)
diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd_dal.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd_dal.h
index d37535d21928..cb52ebad0ef9 100644
--- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd_dal.h
+++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd_dal.h
@@ -32,17 +32,15 @@
  */
 
 enum dmub_cmd_psr_type {
-	DMUB_CMD__PSR_SET_VERSION	= 0,
-	DMUB_CMD__PSR_COPY_SETTINGS	= 1,
-	DMUB_CMD__PSR_ENABLE		= 2,
-	DMUB_CMD__PSR_DISABLE		= 3,
-	DMUB_CMD__PSR_SET_LEVEL		= 4,
+	DMUB_CMD__PSR_SET_VERSION		= 0,
+	DMUB_CMD__PSR_COPY_SETTINGS		= 1,
+	DMUB_CMD__PSR_ENABLE			= 2,
+	DMUB_CMD__PSR_DISABLE			= 3,
+	DMUB_CMD__PSR_SET_LEVEL			= 4,
 };
 
 enum psr_version {
-	PSR_VERSION_1			= 0x10, // PSR Version 1
-	PSR_VERSION_2			= 0x20, // PSR Version 2, includes selective update
-	PSR_VERSION_2_1			= 0x21, // PSR Version 2, includes Y-coordinate support for SU
+	PSR_VERSION_1				= 0,
 };
 
 enum dmub_cmd_abm_type {
diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_srv.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_srv.h
index c2671f2616c8..e40d1cdbcfaa 100644
--- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_srv.h
+++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_srv.h
@@ -151,6 +151,7 @@ struct dmub_srv_region_params {
 	uint32_t inst_const_size;
 	uint32_t bss_data_size;
 	uint32_t vbios_size;
+	const uint8_t *fw_inst_const;
 	const uint8_t *fw_bss_data;
 };
 
@@ -565,6 +566,16 @@ dmub_srv_send_gpint_command(struct dmub_srv *dmub,
 enum dmub_status dmub_srv_get_gpint_response(struct dmub_srv *dmub,
 					     uint32_t *response);
 
+/**
+ * dmub_flush_buffer_mem() - Read back entire frame buffer region.
+ * This ensures that the write from x86 has been flushed and will not
+ * hang the DMCUB.
+ * @fb: frame buffer to flush
+ *
+ * Can be called after software initialization.
+ */
+void dmub_flush_buffer_mem(const struct dmub_fb *fb);
+
 #if defined(__cplusplus)
 }
 #endif
diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c
index 63bb9e2c81de..45638d61b73d 100644
--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c
+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c
@@ -186,14 +186,22 @@ void dmub_dcn20_setup_windows(struct dmub_srv *dmub,
 
 	dmub_dcn20_get_fb_base_offset(dmub, &fb_base, &fb_offset);
 
-	dmub_dcn20_translate_addr(&cw2->offset, fb_base, fb_offset, &offset);
-
-	REG_WRITE(DMCUB_REGION3_CW2_OFFSET, offset.u.low_part);
-	REG_WRITE(DMCUB_REGION3_CW2_OFFSET_HIGH, offset.u.high_part);
-	REG_WRITE(DMCUB_REGION3_CW2_BASE_ADDRESS, cw2->region.base);
-	REG_SET_2(DMCUB_REGION3_CW2_TOP_ADDRESS, 0,
-		  DMCUB_REGION3_CW2_TOP_ADDRESS, cw2->region.top,
-		  DMCUB_REGION3_CW2_ENABLE, 1);
+	if (cw2->region.base != cw2->region.top) {
+		dmub_dcn20_translate_addr(&cw2->offset, fb_base, fb_offset,
+					  &offset);
+
+		REG_WRITE(DMCUB_REGION3_CW2_OFFSET, offset.u.low_part);
+		REG_WRITE(DMCUB_REGION3_CW2_OFFSET_HIGH, offset.u.high_part);
+		REG_WRITE(DMCUB_REGION3_CW2_BASE_ADDRESS, cw2->region.base);
+		REG_SET_2(DMCUB_REGION3_CW2_TOP_ADDRESS, 0,
+			  DMCUB_REGION3_CW2_TOP_ADDRESS, cw2->region.top,
+			  DMCUB_REGION3_CW2_ENABLE, 1);
+	} else {
+		REG_WRITE(DMCUB_REGION3_CW2_OFFSET, 0);
+		REG_WRITE(DMCUB_REGION3_CW2_OFFSET_HIGH, 0);
+		REG_WRITE(DMCUB_REGION3_CW2_BASE_ADDRESS, 0);
+		REG_WRITE(DMCUB_REGION3_CW2_TOP_ADDRESS, 0);
+	}
 
 	dmub_dcn20_translate_addr(&cw3->offset, fb_base, fb_offset, &offset);
 
diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
index ce32cc7933c4..0a1a851741c5 100644
--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
@@ -70,7 +70,7 @@ static inline uint32_t dmub_align(uint32_t val, uint32_t factor)
 	return (val + factor - 1) / factor * factor;
 }
 
-static void dmub_flush_buffer_mem(const struct dmub_fb *fb)
+void dmub_flush_buffer_mem(const struct dmub_fb *fb)
 {
 	const uint8_t *base = (const uint8_t *)fb->cpu_addr;
 	uint8_t buf[64];
@@ -91,17 +91,29 @@ static void dmub_flush_buffer_mem(const struct dmub_fb *fb)
 }
 
 static const struct dmub_fw_meta_info *
-dmub_get_fw_meta_info(const uint8_t *fw_bss_data, uint32_t fw_bss_data_size)
+dmub_get_fw_meta_info(const struct dmub_srv_region_params *params)
 {
 	const union dmub_fw_meta *meta;
+	const uint8_t *blob = NULL;
+	uint32_t blob_size = 0;
+
+	if (params->fw_bss_data) {
+		/* Legacy metadata region. */
+		blob = params->fw_bss_data;
+		blob_size = params->bss_data_size;
+	} else if (params->fw_inst_const) {
+		/* Combined metadata region. */
+		blob = params->fw_inst_const;
+		blob_size = params->inst_const_size;
+	}
 
-	if (fw_bss_data == NULL)
+	if (!blob || !blob_size)
 		return NULL;
 
-	if (fw_bss_data_size < sizeof(union dmub_fw_meta) + DMUB_FW_META_OFFSET)
+	if (blob_size < sizeof(union dmub_fw_meta) + DMUB_FW_META_OFFSET)
 		return NULL;
 
-	meta = (const union dmub_fw_meta *)(fw_bss_data + fw_bss_data_size -
+	meta = (const union dmub_fw_meta *)(blob + blob_size -
 					    DMUB_FW_META_OFFSET -
 					    sizeof(union dmub_fw_meta));
 
@@ -247,8 +259,7 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub,
 	mail->base = dmub_align(bios->top, 256);
 	mail->top = mail->base + DMUB_MAILBOX_SIZE;
 
-	fw_info = dmub_get_fw_meta_info(params->fw_bss_data,
-					params->bss_data_size);
+	fw_info = dmub_get_fw_meta_info(params);
 
 	if (fw_info) {
 		fw_state_size = fw_info->fw_region_size;
diff --git a/drivers/gpu/drm/amd/display/include/hdcp_types.h b/drivers/gpu/drm/amd/display/include/hdcp_types.h
index f31e6befc8d6..42229b4effdc 100644
--- a/drivers/gpu/drm/amd/display/include/hdcp_types.h
+++ b/drivers/gpu/drm/amd/display/include/hdcp_types.h
@@ -83,6 +83,12 @@ enum hdcp_link {
 	HDCP_LINK_SECONDARY
 };
 
+enum hdcp_message_status {
+	HDCP_MESSAGE_SUCCESS,
+	HDCP_MESSAGE_FAILURE,
+	HDCP_MESSAGE_UNSUPPORTED
+};
+
 struct hdcp_protection_message {
 	enum hdcp_version version;
 	/* relevant only for DVI */
@@ -91,6 +97,7 @@ struct hdcp_protection_message {
 	uint32_t length;
 	uint8_t max_retries;
 	uint8_t *data;
+	enum hdcp_message_status status;
 };
 
 #endif
diff --git a/drivers/gpu/drm/amd/display/include/logger_interface.h b/drivers/gpu/drm/amd/display/include/logger_interface.h
index 6e008de25629..02c23b04d34b 100644
--- a/drivers/gpu/drm/amd/display/include/logger_interface.h
+++ b/drivers/gpu/drm/amd/display/include/logger_interface.h
@@ -40,8 +40,6 @@ struct dc_state;
  *
  */
 
-void dc_conn_log_hex_linux(const uint8_t *hex_data, int hex_data_count);
-
 void pre_surface_trace(
 		struct dc *dc,
 		const struct dc_plane_state *const *plane_states,
@@ -102,14 +100,12 @@ void context_clock_trace(
 #define CONN_DATA_DETECT(link, hex_data, hex_len, ...) \
 		do { \
 			(void)(link); \
-			dc_conn_log_hex_linux(hex_data, hex_len); \
 			DC_LOG_EVENT_DETECTION(__VA_ARGS__); \
 		} while (0)
 
 #define CONN_DATA_LINK_LOSS(link, hex_data, hex_len, ...) \
 		do { \
 			(void)(link); \
-			dc_conn_log_hex_linux(hex_data, hex_len); \
 			DC_LOG_EVENT_LINK_LOSS(__VA_ARGS__); \
 		} while (0)
 
diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c
index cc1d3f470b99..e9fbd94f8635 100644
--- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c
+++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c
@@ -328,7 +328,8 @@ enum mod_hdcp_status mod_hdcp_add_display(struct mod_hdcp *hdcp,
 	/* add display to connection */
 	hdcp->connection.link = *link;
 	*display_container = *display;
-	status = mod_hdcp_add_display_to_topology(hdcp, display->index);
+	status = mod_hdcp_add_display_to_topology(hdcp, display_container);
+
 	if (status != MOD_HDCP_STATUS_SUCCESS)
 		goto out;
 
@@ -374,7 +375,7 @@ enum mod_hdcp_status mod_hdcp_remove_display(struct mod_hdcp *hdcp,
 	status = mod_hdcp_remove_display_from_topology(hdcp, index);
 	if (status != MOD_HDCP_STATUS_SUCCESS)
 		goto out;
-	display->state = MOD_HDCP_DISPLAY_INACTIVE;
+	memset(display, 0, sizeof(struct mod_hdcp_display));
 
 	/* request authentication when connection is not reset */
 	if (current_state(hdcp) != HDCP_UNINITIALIZED)
diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.h b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.h
index 5cb4546be0ef..b0cefed2eb02 100644
--- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.h
+++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.h
@@ -328,7 +328,7 @@ void mod_hdcp_dump_binary_message(uint8_t *msg, uint32_t msg_size,
 
 /* psp functions */
 enum mod_hdcp_status mod_hdcp_add_display_to_topology(
-		struct mod_hdcp *hdcp, uint8_t index);
+		struct mod_hdcp *hdcp, struct mod_hdcp_display *display);
 enum mod_hdcp_status mod_hdcp_remove_display_from_topology(
 		struct mod_hdcp *hdcp, uint8_t index);
 enum mod_hdcp_status mod_hdcp_hdcp1_create_session(struct mod_hdcp *hdcp);
@@ -357,8 +357,6 @@ enum mod_hdcp_status mod_hdcp_hdcp2_prepare_stream_management(
 		struct mod_hdcp *hdcp);
 enum mod_hdcp_status mod_hdcp_hdcp2_validate_stream_ready(
 		struct mod_hdcp *hdcp);
-enum mod_hdcp_status mod_hdcp_hdcp2_get_link_encryption_status(struct mod_hdcp *hdcp,
-							       enum mod_hdcp_encryption_status *encryption_status);
 
 /* ddc functions */
 enum mod_hdcp_status mod_hdcp_read_bksv(struct mod_hdcp *hdcp);
@@ -503,11 +501,6 @@ static inline uint8_t is_display_active(struct mod_hdcp_display *display)
 	return display->state >= MOD_HDCP_DISPLAY_ACTIVE;
 }
 
-static inline uint8_t is_display_added(struct mod_hdcp_display *display)
-{
-	return display->state >= MOD_HDCP_DISPLAY_ACTIVE_AND_ADDED;
-}
-
 static inline uint8_t is_display_encryption_enabled(struct mod_hdcp_display *display)
 {
 	return display->state >= MOD_HDCP_DISPLAY_ENCRYPTION_ENABLED;
@@ -515,34 +508,23 @@ static inline uint8_t is_display_encryption_enabled(struct mod_hdcp_display *dis
 
 static inline uint8_t get_active_display_count(struct mod_hdcp *hdcp)
 {
-	uint8_t added_count = 0;
+	uint8_t active_count = 0;
 	uint8_t i;
 
 	for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++)
 		if (is_display_active(&hdcp->displays[i]))
-			added_count++;
-	return added_count;
-}
-
-static inline uint8_t get_added_display_count(struct mod_hdcp *hdcp)
-{
-	uint8_t added_count = 0;
-	uint8_t i;
-
-	for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++)
-		if (is_display_added(&hdcp->displays[i]))
-			added_count++;
-	return added_count;
+			active_count++;
+	return active_count;
 }
 
-static inline struct mod_hdcp_display *get_first_added_display(
+static inline struct mod_hdcp_display *get_first_active_display(
 		struct mod_hdcp *hdcp)
 {
 	uint8_t i;
 	struct mod_hdcp_display *display = NULL;
 
 	for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++)
-		if (is_display_added(&hdcp->displays[i])) {
+		if (is_display_active(&hdcp->displays[i])) {
 			display = &hdcp->displays[i];
 			break;
 		}
diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c
index 37c8c05497d6..f244b72e74e0 100644
--- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c
+++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c
@@ -129,7 +129,7 @@ static inline uint8_t get_device_count(struct mod_hdcp *hdcp)
 static inline enum mod_hdcp_status check_device_count(struct mod_hdcp *hdcp)
 {
 	/* device count must be greater than or equal to tracked hdcp displays */
-	return (get_device_count(hdcp) < get_added_display_count(hdcp)) ?
+	return (get_device_count(hdcp) < get_active_display_count(hdcp)) ?
 			MOD_HDCP_STATUS_HDCP1_DEVICE_COUNT_MISMATCH_FAILURE :
 			MOD_HDCP_STATUS_SUCCESS;
 }
diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_execution.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_execution.c
index 491c00f48026..549c113abcf7 100644
--- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_execution.c
+++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_execution.c
@@ -208,7 +208,7 @@ static inline uint8_t get_device_count(struct mod_hdcp *hdcp)
 static enum mod_hdcp_status check_device_count(struct mod_hdcp *hdcp)
 {
 	/* device count must be greater than or equal to tracked hdcp displays */
-	return (get_device_count(hdcp) < get_added_display_count(hdcp)) ?
+	return (get_device_count(hdcp) < get_active_display_count(hdcp)) ?
 			MOD_HDCP_STATUS_HDCP2_DEVICE_COUNT_MISMATCH_FAILURE :
 			MOD_HDCP_STATUS_SUCCESS;
 }
diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_log.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_log.c
index 44956f9ba178..fb6a19d020f9 100644
--- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_log.c
+++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_log.c
@@ -98,8 +98,8 @@ char *mod_hdcp_status_to_str(int32_t status)
 		return "MOD_HDCP_STATUS_HDCP1_VALIDATE_KSV_LIST_FAILURE";
 	case MOD_HDCP_STATUS_HDCP1_KSV_LIST_REVOKED:
 		return "MOD_HDCP_STATUS_HDCP1_KSV_LIST_REVOKED";
-	case MOD_HDCP_STATUS_HDCP1_ENABLE_ENCRYPTION:
-		return "MOD_HDCP_STATUS_HDCP1_ENABLE_ENCRYPTION";
+	case MOD_HDCP_STATUS_HDCP1_ENABLE_ENCRYPTION_FAILURE:
+		return "MOD_HDCP_STATUS_HDCP1_ENABLE_ENCRYPTION_FAILURE";
 	case MOD_HDCP_STATUS_HDCP1_ENABLE_STREAM_ENCRYPTION_FAILURE:
 		return "MOD_HDCP_STATUS_HDCP1_ENABLE_STREAM_ENCRYPTION_FAILURE";
 	case MOD_HDCP_STATUS_HDCP1_MAX_CASCADE_EXCEEDED_FAILURE:
@@ -158,8 +158,8 @@ char *mod_hdcp_status_to_str(int32_t status)
 		return "MOD_HDCP_STATUS_HDCP2_RX_ID_LIST_REVOKED";
 	case MOD_HDCP_STATUS_HDCP2_RX_ID_LIST_NOT_READY:
 		return "MOD_HDCP_STATUS_HDCP2_RX_ID_LIST_NOT_READY";
-	case MOD_HDCP_STATUS_HDCP2_ENABLE_STREAM_ENCRYPTION:
-		return "MOD_HDCP_STATUS_HDCP2_ENABLE_STREAM_ENCRYPTION";
+	case MOD_HDCP_STATUS_HDCP2_ENABLE_STREAM_ENCRYPTION_FAILURE:
+		return "MOD_HDCP_STATUS_HDCP2_ENABLE_STREAM_ENCRYPTION_FAILURE";
 	case MOD_HDCP_STATUS_HDCP2_STREAM_READY_PENDING:
 		return "MOD_HDCP_STATUS_HDCP2_STREAM_READY_PENDING";
 	case MOD_HDCP_STATUS_HDCP2_VALIDATE_STREAM_READY_FAILURE:
diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c
index c2929815c3ee..fb1161dd7ea8 100644
--- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c
+++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c
@@ -51,12 +51,15 @@ enum mod_hdcp_status mod_hdcp_remove_display_from_topology(
  	struct ta_dtm_shared_memory *dtm_cmd;
 	struct mod_hdcp_display *display =
 			get_active_display_at_index(hdcp, index);
+	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
 
 	dtm_cmd = (struct ta_dtm_shared_memory *)psp->dtm_context.dtm_shared_buf;
 
-	if (!display || !is_display_added(display))
+	if (!display || !is_display_active(display))
 		return MOD_HDCP_STATUS_DISPLAY_NOT_FOUND;
 
+	mutex_lock(&psp->dtm_context.mutex);
+
 	memset(dtm_cmd, 0, sizeof(struct ta_dtm_shared_memory));
 
 	dtm_cmd->cmd_id = TA_DTM_COMMAND__TOPOLOGY_UPDATE_V2;
@@ -66,34 +69,33 @@ enum mod_hdcp_status mod_hdcp_remove_display_from_topology(
 
 	psp_dtm_invoke(psp, dtm_cmd->cmd_id);
 
-	if (dtm_cmd->dtm_status != TA_DTM_STATUS__SUCCESS)
-		return MOD_HDCP_STATUS_UPDATE_TOPOLOGY_FAILURE;
+	if (dtm_cmd->dtm_status != TA_DTM_STATUS__SUCCESS) {
+		status = MOD_HDCP_STATUS_UPDATE_TOPOLOGY_FAILURE;
+	} else {
+		display->state = MOD_HDCP_DISPLAY_ACTIVE;
+		HDCP_TOP_REMOVE_DISPLAY_TRACE(hdcp, display->index);
+	}
 
-	display->state = MOD_HDCP_DISPLAY_ACTIVE;
-	HDCP_TOP_REMOVE_DISPLAY_TRACE(hdcp, display->index);
- 
- 	return MOD_HDCP_STATUS_SUCCESS;
- 
+	mutex_unlock(&psp->dtm_context.mutex);
+	return status;
 }
 enum mod_hdcp_status mod_hdcp_add_display_to_topology(struct mod_hdcp *hdcp,
-						      uint8_t index)
+					       struct mod_hdcp_display *display)
 {
 	struct psp_context *psp = hdcp->config.psp.handle;
 	struct ta_dtm_shared_memory *dtm_cmd;
-	struct mod_hdcp_display *display =
-			get_active_display_at_index(hdcp, index);
 	struct mod_hdcp_link *link = &hdcp->connection.link;
+	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
 
 	if (!psp->dtm_context.dtm_initialized) {
 		DRM_ERROR("Failed to add display topology, DTM TA is not initialized.");
+		display->state = MOD_HDCP_DISPLAY_INACTIVE;
 		return MOD_HDCP_STATUS_FAILURE;
 	}
 
-	if (!display || is_display_added(display))
-		return MOD_HDCP_STATUS_UPDATE_TOPOLOGY_FAILURE;
-
 	dtm_cmd = (struct ta_dtm_shared_memory *)psp->dtm_context.dtm_shared_buf;
 
+	mutex_lock(&psp->dtm_context.mutex);
 	memset(dtm_cmd, 0, sizeof(struct ta_dtm_shared_memory));
 
 	dtm_cmd->cmd_id = TA_DTM_COMMAND__TOPOLOGY_UPDATE_V2;
@@ -113,21 +115,24 @@ enum mod_hdcp_status mod_hdcp_add_display_to_topology(struct mod_hdcp *hdcp,
 
 	psp_dtm_invoke(psp, dtm_cmd->cmd_id);
 
-	if (dtm_cmd->dtm_status != TA_DTM_STATUS__SUCCESS)
-		return MOD_HDCP_STATUS_UPDATE_TOPOLOGY_FAILURE;
-
-	display->state = MOD_HDCP_DISPLAY_ACTIVE_AND_ADDED;
-	HDCP_TOP_ADD_DISPLAY_TRACE(hdcp, display->index);
+	if (dtm_cmd->dtm_status != TA_DTM_STATUS__SUCCESS) {
+		display->state = MOD_HDCP_DISPLAY_INACTIVE;
+		status = MOD_HDCP_STATUS_UPDATE_TOPOLOGY_FAILURE;
+	} else {
+		HDCP_TOP_ADD_DISPLAY_TRACE(hdcp, display->index);
+	}
 
-	return MOD_HDCP_STATUS_SUCCESS;
+	mutex_unlock(&psp->dtm_context.mutex);
+	return status;
 }
 
 enum mod_hdcp_status mod_hdcp_hdcp1_create_session(struct mod_hdcp *hdcp)
 {
 
 	struct psp_context *psp = hdcp->config.psp.handle;
-	struct mod_hdcp_display *display = get_first_added_display(hdcp);
+	struct mod_hdcp_display *display = get_first_active_display(hdcp);
 	struct ta_hdcp_shared_memory *hdcp_cmd;
+	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
 
 	if (!psp->hdcp_context.hdcp_initialized) {
 		DRM_ERROR("Failed to create hdcp session. HDCP TA is not initialized.");
@@ -135,6 +140,8 @@ enum mod_hdcp_status mod_hdcp_hdcp1_create_session(struct mod_hdcp *hdcp)
 	}
 
 	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;
+
+	mutex_lock(&psp->hdcp_context.mutex);
 	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
 
 	hdcp_cmd->in_msg.hdcp1_create_session.display_handle = display->index;
@@ -144,16 +151,18 @@ enum mod_hdcp_status mod_hdcp_hdcp1_create_session(struct mod_hdcp *hdcp)
 
 	hdcp->auth.id = hdcp_cmd->out_msg.hdcp1_create_session.session_handle;
 
-	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS)
-		return MOD_HDCP_STATUS_HDCP1_CREATE_SESSION_FAILURE;
-
-	hdcp->auth.msg.hdcp1.ainfo = hdcp_cmd->out_msg.hdcp1_create_session.ainfo_primary;
-	memcpy(hdcp->auth.msg.hdcp1.aksv, hdcp_cmd->out_msg.hdcp1_create_session.aksv_primary,
-		sizeof(hdcp->auth.msg.hdcp1.aksv));
-	memcpy(hdcp->auth.msg.hdcp1.an, hdcp_cmd->out_msg.hdcp1_create_session.an_primary,
-		sizeof(hdcp->auth.msg.hdcp1.an));
+	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) {
+		status = MOD_HDCP_STATUS_HDCP1_CREATE_SESSION_FAILURE;
+	} else {
+		hdcp->auth.msg.hdcp1.ainfo = hdcp_cmd->out_msg.hdcp1_create_session.ainfo_primary;
+		memcpy(hdcp->auth.msg.hdcp1.aksv, hdcp_cmd->out_msg.hdcp1_create_session.aksv_primary,
+		       sizeof(hdcp->auth.msg.hdcp1.aksv));
+		memcpy(hdcp->auth.msg.hdcp1.an, hdcp_cmd->out_msg.hdcp1_create_session.an_primary,
+		       sizeof(hdcp->auth.msg.hdcp1.an));
+	}
 
-	return MOD_HDCP_STATUS_SUCCESS;
+	mutex_unlock(&psp->hdcp_context.mutex);
+	return status;
 }
 
 enum mod_hdcp_status mod_hdcp_hdcp1_destroy_session(struct mod_hdcp *hdcp)
@@ -162,7 +171,9 @@ enum mod_hdcp_status mod_hdcp_hdcp1_destroy_session(struct mod_hdcp *hdcp)
 	struct psp_context *psp = hdcp->config.psp.handle;
 	struct ta_hdcp_shared_memory *hdcp_cmd;
 	uint8_t i = 0;
+	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
 
+	mutex_lock(&psp->hdcp_context.mutex);
 	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;
 	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
 
@@ -171,27 +182,30 @@ enum mod_hdcp_status mod_hdcp_hdcp1_destroy_session(struct mod_hdcp *hdcp)
 
 	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
 
-	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS)
-		return MOD_HDCP_STATUS_HDCP1_DESTROY_SESSION_FAILURE;
-
-	HDCP_TOP_HDCP1_DESTROY_SESSION_TRACE(hdcp);
-	for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++)
-		if (is_display_encryption_enabled(
-				&hdcp->displays[i])) {
-			hdcp->displays[i].state =
-					MOD_HDCP_DISPLAY_ACTIVE_AND_ADDED;
-			HDCP_HDCP1_DISABLED_TRACE(hdcp,
-					hdcp->displays[i].index);
-		}
+	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) {
+		status = MOD_HDCP_STATUS_HDCP1_DESTROY_SESSION_FAILURE;
+	} else {
+		HDCP_TOP_HDCP1_DESTROY_SESSION_TRACE(hdcp);
+		for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++)
+			if (is_display_encryption_enabled(&hdcp->displays[i])) {
+				hdcp->displays[i].state =
+							MOD_HDCP_DISPLAY_ACTIVE;
+				HDCP_HDCP1_DISABLED_TRACE(
+					hdcp, hdcp->displays[i].index);
+			}
+	}
 
-	return MOD_HDCP_STATUS_SUCCESS;
+	mutex_unlock(&psp->hdcp_context.mutex);
+	return status;
 }
 
 enum mod_hdcp_status mod_hdcp_hdcp1_validate_rx(struct mod_hdcp *hdcp)
 {
 	struct psp_context *psp = hdcp->config.psp.handle;
 	struct ta_hdcp_shared_memory *hdcp_cmd;
+	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
 
+	mutex_lock(&psp->hdcp_context.mutex);
 	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;
 	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
 
@@ -206,10 +220,9 @@ enum mod_hdcp_status mod_hdcp_hdcp1_validate_rx(struct mod_hdcp *hdcp)
 
 	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
 
-	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS)
-		return MOD_HDCP_STATUS_HDCP1_VALIDATE_RX_FAILURE;
-
-	if (hdcp_cmd->out_msg.hdcp1_first_part_authentication.authentication_status ==
+	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) {
+		status = MOD_HDCP_STATUS_HDCP1_VALIDATE_RX_FAILURE;
+	} else if (hdcp_cmd->out_msg.hdcp1_first_part_authentication.authentication_status ==
 	    TA_HDCP_AUTHENTICATION_STATUS__HDCP1_FIRST_PART_COMPLETE) {
 		/* needs second part of authentication */
 		hdcp->connection.is_repeater = 1;
@@ -219,20 +232,22 @@ enum mod_hdcp_status mod_hdcp_hdcp1_validate_rx(struct mod_hdcp *hdcp)
 	} else if (hdcp_cmd->out_msg.hdcp1_first_part_authentication.authentication_status ==
 		   TA_HDCP_AUTHENTICATION_STATUS__HDCP1_KSV_REVOKED) {
 		hdcp->connection.is_hdcp1_revoked = 1;
-		return MOD_HDCP_STATUS_HDCP1_BKSV_REVOKED;
+		status = MOD_HDCP_STATUS_HDCP1_BKSV_REVOKED;
 	} else
-		return MOD_HDCP_STATUS_HDCP1_VALIDATE_RX_FAILURE;
-
+		status = MOD_HDCP_STATUS_HDCP1_VALIDATE_RX_FAILURE;
 
-	return MOD_HDCP_STATUS_SUCCESS;
+	mutex_unlock(&psp->hdcp_context.mutex);
+	return status;
 }
 
 enum mod_hdcp_status mod_hdcp_hdcp1_enable_encryption(struct mod_hdcp *hdcp)
 {
 	struct psp_context *psp = hdcp->config.psp.handle;
 	struct ta_hdcp_shared_memory *hdcp_cmd;
-	struct mod_hdcp_display *display = get_first_added_display(hdcp);
+	struct mod_hdcp_display *display = get_first_active_display(hdcp);
+	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
 
+	mutex_lock(&psp->hdcp_context.mutex);
 	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;
 	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
 
@@ -241,14 +256,15 @@ enum mod_hdcp_status mod_hdcp_hdcp1_enable_encryption(struct mod_hdcp *hdcp)
 
 	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
 
-	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS)
-		return MOD_HDCP_STATUS_HDCP1_ENABLE_ENCRYPTION;
-
-	if (!is_dp_mst_hdcp(hdcp)) {
+	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) {
+		status = MOD_HDCP_STATUS_HDCP1_ENABLE_ENCRYPTION_FAILURE;
+	} else if (!is_dp_mst_hdcp(hdcp)) {
 		display->state = MOD_HDCP_DISPLAY_ENCRYPTION_ENABLED;
 		HDCP_HDCP1_ENABLED_TRACE(hdcp, display->index);
 	}
-	return MOD_HDCP_STATUS_SUCCESS;
+
+	mutex_unlock(&psp->hdcp_context.mutex);
+	return status;
 }
 
 enum mod_hdcp_status mod_hdcp_hdcp1_validate_ksvlist_vp(struct mod_hdcp *hdcp)
@@ -257,6 +273,7 @@ enum mod_hdcp_status mod_hdcp_hdcp1_validate_ksvlist_vp(struct mod_hdcp *hdcp)
 	struct ta_hdcp_shared_memory *hdcp_cmd;
 	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
 
+	mutex_lock(&psp->hdcp_context.mutex);
 	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;
 	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
 
@@ -287,6 +304,7 @@ enum mod_hdcp_status mod_hdcp_hdcp1_validate_ksvlist_vp(struct mod_hdcp *hdcp)
 		status = MOD_HDCP_STATUS_HDCP1_VALIDATE_KSV_LIST_FAILURE;
 	}
 
+	mutex_unlock(&psp->hdcp_context.mutex);
 	return status;
 }
 
@@ -296,14 +314,15 @@ enum mod_hdcp_status mod_hdcp_hdcp1_enable_dp_stream_encryption(struct mod_hdcp
 	struct psp_context *psp = hdcp->config.psp.handle;
 	struct ta_hdcp_shared_memory *hdcp_cmd;
 	int i = 0;
+	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
 
+	mutex_lock(&psp->hdcp_context.mutex);
 	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;
 
 	for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++) {
 
-		if (hdcp->displays[i].state != MOD_HDCP_DISPLAY_ACTIVE_AND_ADDED ||
-		    hdcp->displays[i].adjust.disable)
-			continue;
+		if (hdcp->displays[i].adjust.disable || hdcp->displays[i].state != MOD_HDCP_DISPLAY_ACTIVE)
+				continue;
 
 		memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
 
@@ -313,21 +332,26 @@ enum mod_hdcp_status mod_hdcp_hdcp1_enable_dp_stream_encryption(struct mod_hdcp
 
 		psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
 
-		if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS)
-			return MOD_HDCP_STATUS_HDCP1_ENABLE_STREAM_ENCRYPTION_FAILURE;
+		if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) {
+			status = MOD_HDCP_STATUS_HDCP1_ENABLE_STREAM_ENCRYPTION_FAILURE;
+			break;
+		}
 
 		hdcp->displays[i].state = MOD_HDCP_DISPLAY_ENCRYPTION_ENABLED;
 		HDCP_HDCP1_ENABLED_TRACE(hdcp, hdcp->displays[i].index);
 	}
 
-	return MOD_HDCP_STATUS_SUCCESS;
+	mutex_unlock(&psp->hdcp_context.mutex);
+	return status;
 }
 
 enum mod_hdcp_status mod_hdcp_hdcp1_link_maintenance(struct mod_hdcp *hdcp)
 {
 	struct psp_context *psp = hdcp->config.psp.handle;
 	struct ta_hdcp_shared_memory *hdcp_cmd;
+	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
 
+	mutex_lock(&psp->hdcp_context.mutex);
 	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;
 
 	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
@@ -339,12 +363,12 @@ enum mod_hdcp_status mod_hdcp_hdcp1_link_maintenance(struct mod_hdcp *hdcp)
 
 	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
 
-	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS)
-		return MOD_HDCP_STATUS_HDCP1_LINK_MAINTENANCE_FAILURE;
+	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS ||
+			hdcp_cmd->out_msg.hdcp1_get_encryption_status.protection_level != 1)
+		status = MOD_HDCP_STATUS_HDCP1_LINK_MAINTENANCE_FAILURE;
 
-	return (hdcp_cmd->out_msg.hdcp1_get_encryption_status.protection_level == 1)
-		       ? MOD_HDCP_STATUS_SUCCESS
-		       : MOD_HDCP_STATUS_HDCP1_LINK_MAINTENANCE_FAILURE;
+	mutex_unlock(&psp->hdcp_context.mutex);
+	return status;
 }
 
 enum mod_hdcp_status mod_hdcp_hdcp1_get_link_encryption_status(struct mod_hdcp *hdcp,
@@ -364,19 +388,23 @@ enum mod_hdcp_status mod_hdcp_hdcp2_create_session(struct mod_hdcp *hdcp)
 {
 	struct psp_context *psp = hdcp->config.psp.handle;
 	struct ta_hdcp_shared_memory *hdcp_cmd;
-	struct mod_hdcp_display *display = get_first_added_display(hdcp);
+	struct mod_hdcp_display *display = get_first_active_display(hdcp);
+	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
+
 
 	if (!psp->hdcp_context.hdcp_initialized) {
 		DRM_ERROR("Failed to create hdcp session, HDCP TA is not initialized");
 		return MOD_HDCP_STATUS_FAILURE;
 	}
 
-	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;
-	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
-
 	if (!display)
 		return MOD_HDCP_STATUS_DISPLAY_NOT_FOUND;
 
+	mutex_lock(&psp->hdcp_context.mutex);
+
+	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;
+	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
+
 	hdcp_cmd->in_msg.hdcp2_create_session_v2.display_handle = display->index;
 
 	if (hdcp->connection.link.adjust.hdcp2.force_type == MOD_HDCP_FORCE_TYPE_0)
@@ -393,12 +421,14 @@ enum mod_hdcp_status mod_hdcp_hdcp2_create_session(struct mod_hdcp *hdcp)
 
 	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
 
-	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS)
-		return MOD_HDCP_STATUS_HDCP2_CREATE_SESSION_FAILURE;
 
-	hdcp->auth.id = hdcp_cmd->out_msg.hdcp2_create_session_v2.session_handle;
+	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS)
+		status = MOD_HDCP_STATUS_HDCP2_CREATE_SESSION_FAILURE;
+	else
+		hdcp->auth.id = hdcp_cmd->out_msg.hdcp2_create_session_v2.session_handle;
 
-	return MOD_HDCP_STATUS_SUCCESS;
+	mutex_unlock(&psp->hdcp_context.mutex);
+	return status;
 }
 
 enum mod_hdcp_status mod_hdcp_hdcp2_destroy_session(struct mod_hdcp *hdcp)
@@ -406,7 +436,9 @@ enum mod_hdcp_status mod_hdcp_hdcp2_destroy_session(struct mod_hdcp *hdcp)
 	struct psp_context *psp = hdcp->config.psp.handle;
 	struct ta_hdcp_shared_memory *hdcp_cmd;
 	uint8_t i = 0;
+	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
 
+	mutex_lock(&psp->hdcp_context.mutex);
 	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;
 	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
 
@@ -415,20 +447,21 @@ enum mod_hdcp_status mod_hdcp_hdcp2_destroy_session(struct mod_hdcp *hdcp)
 
 	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
 
-	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS)
-		return MOD_HDCP_STATUS_HDCP2_DESTROY_SESSION_FAILURE;
-
-	HDCP_TOP_HDCP2_DESTROY_SESSION_TRACE(hdcp);
-	for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++)
-		if (is_display_encryption_enabled(
-				&hdcp->displays[i])) {
-			hdcp->displays[i].state =
-					MOD_HDCP_DISPLAY_ACTIVE_AND_ADDED;
-			HDCP_HDCP2_DISABLED_TRACE(hdcp,
-					hdcp->displays[i].index);
-		}
+	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) {
+		status = MOD_HDCP_STATUS_HDCP2_DESTROY_SESSION_FAILURE;
+	} else {
+		HDCP_TOP_HDCP2_DESTROY_SESSION_TRACE(hdcp);
+		for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++)
+			if (is_display_encryption_enabled(&hdcp->displays[i])) {
+				hdcp->displays[i].state =
+							MOD_HDCP_DISPLAY_ACTIVE;
+				HDCP_HDCP2_DISABLED_TRACE(
+					hdcp, hdcp->displays[i].index);
+			}
+	}
 
-	return MOD_HDCP_STATUS_SUCCESS;
+	mutex_unlock(&psp->hdcp_context.mutex);
+	return status;
 }
 
 enum mod_hdcp_status mod_hdcp_hdcp2_prepare_ake_init(struct mod_hdcp *hdcp)
@@ -437,7 +470,9 @@ enum mod_hdcp_status mod_hdcp_hdcp2_prepare_ake_init(struct mod_hdcp *hdcp)
 	struct ta_hdcp_shared_memory *hdcp_cmd;
 	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;
 	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out;
+	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
 
+	mutex_lock(&psp->hdcp_context.mutex);
 	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;
 	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
 
@@ -452,12 +487,13 @@ enum mod_hdcp_status mod_hdcp_hdcp2_prepare_ake_init(struct mod_hdcp *hdcp)
 	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
 
 	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS)
-		return MOD_HDCP_STATUS_HDCP2_PREP_AKE_INIT_FAILURE;
-
-	memcpy(&hdcp->auth.msg.hdcp2.ake_init[0], &msg_out->prepare.transmitter_message[0],
-	       sizeof(hdcp->auth.msg.hdcp2.ake_init));
+		status = MOD_HDCP_STATUS_HDCP2_PREP_AKE_INIT_FAILURE;
+	else
+		memcpy(&hdcp->auth.msg.hdcp2.ake_init[0], &msg_out->prepare.transmitter_message[0],
+		       sizeof(hdcp->auth.msg.hdcp2.ake_init));
 
-	return MOD_HDCP_STATUS_SUCCESS;
+	mutex_unlock(&psp->hdcp_context.mutex);
+	return status;
 }
 
 enum mod_hdcp_status mod_hdcp_hdcp2_validate_ake_cert(struct mod_hdcp *hdcp)
@@ -466,7 +502,9 @@ enum mod_hdcp_status mod_hdcp_hdcp2_validate_ake_cert(struct mod_hdcp *hdcp)
 	struct ta_hdcp_shared_memory *hdcp_cmd;
 	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;
 	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out;
+	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
 
+	mutex_lock(&psp->hdcp_context.mutex);
 	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;
 	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
 
@@ -488,26 +526,32 @@ enum mod_hdcp_status mod_hdcp_hdcp2_validate_ake_cert(struct mod_hdcp *hdcp)
 
 	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
 
-	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS)
-		return MOD_HDCP_STATUS_HDCP2_VALIDATE_AKE_CERT_FAILURE;
-
-	memcpy(hdcp->auth.msg.hdcp2.ake_no_stored_km, &msg_out->prepare.transmitter_message[0],
-	       sizeof(hdcp->auth.msg.hdcp2.ake_no_stored_km));
-
-	memcpy(hdcp->auth.msg.hdcp2.ake_stored_km,
-	       &msg_out->prepare.transmitter_message[sizeof(hdcp->auth.msg.hdcp2.ake_no_stored_km)],
-	       sizeof(hdcp->auth.msg.hdcp2.ake_stored_km));
-
-	if (msg_out->process.msg1_status == TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS) {
-		hdcp->connection.is_km_stored = msg_out->process.is_km_stored ? 1 : 0;
-		hdcp->connection.is_repeater = msg_out->process.is_repeater ? 1 : 0;
-		return MOD_HDCP_STATUS_SUCCESS;
-	} else if (msg_out->process.msg1_status == TA_HDCP2_MSG_AUTHENTICATION_STATUS__RECEIVERID_REVOKED) {
-		hdcp->connection.is_hdcp2_revoked = 1;
-		return MOD_HDCP_STATUS_HDCP2_AKE_CERT_REVOKED;
+	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) {
+		status = MOD_HDCP_STATUS_HDCP2_VALIDATE_AKE_CERT_FAILURE;
+	} else {
+		memcpy(hdcp->auth.msg.hdcp2.ake_no_stored_km,
+		       &msg_out->prepare.transmitter_message[0],
+		       sizeof(hdcp->auth.msg.hdcp2.ake_no_stored_km));
+
+		memcpy(hdcp->auth.msg.hdcp2.ake_stored_km,
+		       &msg_out->prepare.transmitter_message[sizeof(hdcp->auth.msg.hdcp2.ake_no_stored_km)],
+		       sizeof(hdcp->auth.msg.hdcp2.ake_stored_km));
+
+		if (msg_out->process.msg1_status ==
+		    TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS) {
+			hdcp->connection.is_km_stored =
+				msg_out->process.is_km_stored ? 1 : 0;
+			hdcp->connection.is_repeater =
+				msg_out->process.is_repeater ? 1 : 0;
+			status = MOD_HDCP_STATUS_SUCCESS;
+		} else if (msg_out->process.msg1_status ==
+			   TA_HDCP2_MSG_AUTHENTICATION_STATUS__RECEIVERID_REVOKED) {
+			hdcp->connection.is_hdcp2_revoked = 1;
+			status = MOD_HDCP_STATUS_HDCP2_AKE_CERT_REVOKED;
+		}
 	}
-
-	return MOD_HDCP_STATUS_HDCP2_VALIDATE_AKE_CERT_FAILURE;
+	mutex_unlock(&psp->hdcp_context.mutex);
+	return status;
 }
 
 enum mod_hdcp_status mod_hdcp_hdcp2_validate_h_prime(struct mod_hdcp *hdcp)
@@ -516,7 +560,9 @@ enum mod_hdcp_status mod_hdcp_hdcp2_validate_h_prime(struct mod_hdcp *hdcp)
 	struct ta_hdcp_shared_memory *hdcp_cmd;
 	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;
 	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out;
+	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
 
+	mutex_lock(&psp->hdcp_context.mutex);
 	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;
 	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
 
@@ -543,16 +589,15 @@ enum mod_hdcp_status mod_hdcp_hdcp2_validate_h_prime(struct mod_hdcp *hdcp)
 	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
 
 	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS)
-		return MOD_HDCP_STATUS_HDCP2_VALIDATE_H_PRIME_FAILURE;
-
-	if (msg_out->process.msg1_status != TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS)
-		return MOD_HDCP_STATUS_HDCP2_VALIDATE_H_PRIME_FAILURE;
+		status = MOD_HDCP_STATUS_HDCP2_VALIDATE_H_PRIME_FAILURE;
+	else if (msg_out->process.msg1_status != TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS)
+		status = MOD_HDCP_STATUS_HDCP2_VALIDATE_H_PRIME_FAILURE;
 	else if (!hdcp->connection.is_km_stored &&
-		 msg_out->process.msg2_status != TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS)
-		return MOD_HDCP_STATUS_HDCP2_VALIDATE_PAIRING_INFO_FAILURE;
-
+		   msg_out->process.msg2_status != TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS)
+		status = MOD_HDCP_STATUS_HDCP2_VALIDATE_PAIRING_INFO_FAILURE;
 
-	return MOD_HDCP_STATUS_SUCCESS;
+	mutex_unlock(&psp->hdcp_context.mutex);
+	return status;
 }
 
 enum mod_hdcp_status mod_hdcp_hdcp2_prepare_lc_init(struct mod_hdcp *hdcp)
@@ -561,7 +606,9 @@ enum mod_hdcp_status mod_hdcp_hdcp2_prepare_lc_init(struct mod_hdcp *hdcp)
 	struct ta_hdcp_shared_memory *hdcp_cmd;
 	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;
 	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out;
+	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
 
+	mutex_lock(&psp->hdcp_context.mutex);
 	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;
 	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
 
@@ -577,12 +624,13 @@ enum mod_hdcp_status mod_hdcp_hdcp2_prepare_lc_init(struct mod_hdcp *hdcp)
 	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
 
 	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS)
-		return MOD_HDCP_STATUS_HDCP2_PREP_LC_INIT_FAILURE;
-
-	memcpy(hdcp->auth.msg.hdcp2.lc_init, &msg_out->prepare.transmitter_message[0],
-	       sizeof(hdcp->auth.msg.hdcp2.lc_init));
+		status = MOD_HDCP_STATUS_HDCP2_PREP_LC_INIT_FAILURE;
+	else
+		memcpy(hdcp->auth.msg.hdcp2.lc_init, &msg_out->prepare.transmitter_message[0],
+		       sizeof(hdcp->auth.msg.hdcp2.lc_init));
 
-	return MOD_HDCP_STATUS_SUCCESS;
+	mutex_unlock(&psp->hdcp_context.mutex);
+	return status;
 }
 
 enum mod_hdcp_status mod_hdcp_hdcp2_validate_l_prime(struct mod_hdcp *hdcp)
@@ -591,7 +639,9 @@ enum mod_hdcp_status mod_hdcp_hdcp2_validate_l_prime(struct mod_hdcp *hdcp)
 	struct ta_hdcp_shared_memory *hdcp_cmd;
 	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;
 	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out;
+	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
 
+	mutex_lock(&psp->hdcp_context.mutex);
 	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;
 	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
 
@@ -610,13 +660,12 @@ enum mod_hdcp_status mod_hdcp_hdcp2_validate_l_prime(struct mod_hdcp *hdcp)
 
 	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
 
-	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS)
-		return MOD_HDCP_STATUS_HDCP2_VALIDATE_L_PRIME_FAILURE;
-
-	if (msg_out->process.msg1_status != TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS)
-		return MOD_HDCP_STATUS_HDCP2_VALIDATE_L_PRIME_FAILURE;
+	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS ||
+			msg_out->process.msg1_status != TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS)
+		status = MOD_HDCP_STATUS_HDCP2_VALIDATE_L_PRIME_FAILURE;
 
-	return MOD_HDCP_STATUS_SUCCESS;
+	mutex_unlock(&psp->hdcp_context.mutex);
+	return status;
 }
 
 enum mod_hdcp_status mod_hdcp_hdcp2_prepare_eks(struct mod_hdcp *hdcp)
@@ -625,7 +674,9 @@ enum mod_hdcp_status mod_hdcp_hdcp2_prepare_eks(struct mod_hdcp *hdcp)
 	struct ta_hdcp_shared_memory *hdcp_cmd;
 	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;
 	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out;
+	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
 
+	mutex_lock(&psp->hdcp_context.mutex);
 	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;
 	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
 
@@ -642,48 +693,55 @@ enum mod_hdcp_status mod_hdcp_hdcp2_prepare_eks(struct mod_hdcp *hdcp)
 	hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_PREPARE_PROCESS_AUTHENTICATION_MSG_V2;
 	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
 
-	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS)
-		return MOD_HDCP_STATUS_HDCP2_PREP_EKS_FAILURE;
-
-	memcpy(hdcp->auth.msg.hdcp2.ske_eks, &msg_out->prepare.transmitter_message[0],
-	       sizeof(hdcp->auth.msg.hdcp2.ske_eks));
-	msg_out->prepare.msg1_desc.msg_size = sizeof(hdcp->auth.msg.hdcp2.ske_eks);
-
-	if (is_dp_hdcp(hdcp)) {
-		memcpy(hdcp->auth.msg.hdcp2.content_stream_type_dp,
-		       &msg_out->prepare.transmitter_message[sizeof(hdcp->auth.msg.hdcp2.ske_eks)],
-		       sizeof(hdcp->auth.msg.hdcp2.content_stream_type_dp));
+	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) {
+		status = MOD_HDCP_STATUS_HDCP2_PREP_EKS_FAILURE;
+	} else {
+		memcpy(hdcp->auth.msg.hdcp2.ske_eks,
+		       &msg_out->prepare.transmitter_message[0],
+		       sizeof(hdcp->auth.msg.hdcp2.ske_eks));
+		msg_out->prepare.msg1_desc.msg_size =
+			sizeof(hdcp->auth.msg.hdcp2.ske_eks);
+
+		if (is_dp_hdcp(hdcp)) {
+			memcpy(hdcp->auth.msg.hdcp2.content_stream_type_dp,
+			       &msg_out->prepare.transmitter_message[sizeof(hdcp->auth.msg.hdcp2.ske_eks)],
+			       sizeof(hdcp->auth.msg.hdcp2.content_stream_type_dp));
+		}
 	}
+	mutex_unlock(&psp->hdcp_context.mutex);
 
-	return MOD_HDCP_STATUS_SUCCESS;
+	return status;
 }
 
 enum mod_hdcp_status mod_hdcp_hdcp2_enable_encryption(struct mod_hdcp *hdcp)
 {
 	struct psp_context *psp = hdcp->config.psp.handle;
 	struct ta_hdcp_shared_memory *hdcp_cmd;
-	struct mod_hdcp_display *display = get_first_added_display(hdcp);
-
-	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;
-	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
+	struct mod_hdcp_display *display = get_first_active_display(hdcp);
+	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
 
 	if (!display)
 		return MOD_HDCP_STATUS_DISPLAY_NOT_FOUND;
 
+	mutex_lock(&psp->hdcp_context.mutex);
+
+	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;
+	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
+
 	hdcp_cmd->in_msg.hdcp2_set_encryption.session_handle = hdcp->auth.id;
 
 	hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_SET_ENCRYPTION;
 	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
 
-	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS)
-		return MOD_HDCP_STATUS_HDCP2_ENABLE_ENCRYPTION_FAILURE;
-
-	if (!is_dp_mst_hdcp(hdcp)) {
+	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) {
+		status = MOD_HDCP_STATUS_HDCP2_ENABLE_ENCRYPTION_FAILURE;
+	} else if (!is_dp_mst_hdcp(hdcp)) {
 		display->state = MOD_HDCP_DISPLAY_ENCRYPTION_ENABLED;
 		HDCP_HDCP2_ENABLED_TRACE(hdcp, display->index);
 	}
 
-	return MOD_HDCP_STATUS_SUCCESS;
+	mutex_unlock(&psp->hdcp_context.mutex);
+	return status;
 }
 
 enum mod_hdcp_status mod_hdcp_hdcp2_validate_rx_id_list(struct mod_hdcp *hdcp)
@@ -692,6 +750,9 @@ enum mod_hdcp_status mod_hdcp_hdcp2_validate_rx_id_list(struct mod_hdcp *hdcp)
 	struct ta_hdcp_shared_memory *hdcp_cmd;
 	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;
 	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out;
+	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
+
+	mutex_lock(&psp->hdcp_context.mutex);
 
 	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;
 	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
@@ -712,23 +773,26 @@ enum mod_hdcp_status mod_hdcp_hdcp2_validate_rx_id_list(struct mod_hdcp *hdcp)
 
 	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
 
-	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS)
-		return MOD_HDCP_STATUS_HDCP2_VALIDATE_RX_ID_LIST_FAILURE;
-
-	memcpy(hdcp->auth.msg.hdcp2.repeater_auth_ack, &msg_out->prepare.transmitter_message[0],
-	       sizeof(hdcp->auth.msg.hdcp2.repeater_auth_ack));
-
-	if (msg_out->process.msg1_status == TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS) {
-		hdcp->connection.is_km_stored = msg_out->process.is_km_stored ? 1 : 0;
-		hdcp->connection.is_repeater = msg_out->process.is_repeater ? 1 : 0;
-		return MOD_HDCP_STATUS_SUCCESS;
-	} else if (msg_out->process.msg1_status == TA_HDCP2_MSG_AUTHENTICATION_STATUS__RECEIVERID_REVOKED) {
-		hdcp->connection.is_hdcp2_revoked = 1;
-		return MOD_HDCP_STATUS_HDCP2_RX_ID_LIST_REVOKED;
+	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) {
+		status = MOD_HDCP_STATUS_HDCP2_VALIDATE_RX_ID_LIST_FAILURE;
+	} else {
+		memcpy(hdcp->auth.msg.hdcp2.repeater_auth_ack,
+		       &msg_out->prepare.transmitter_message[0],
+		       sizeof(hdcp->auth.msg.hdcp2.repeater_auth_ack));
+
+		if (msg_out->process.msg1_status ==
+		    TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS) {
+			hdcp->connection.is_km_stored = msg_out->process.is_km_stored ? 1 : 0;
+			hdcp->connection.is_repeater = msg_out->process.is_repeater ? 1 : 0;
+			status = MOD_HDCP_STATUS_SUCCESS;
+		} else if (msg_out->process.msg1_status ==
+			   TA_HDCP2_MSG_AUTHENTICATION_STATUS__RECEIVERID_REVOKED) {
+			hdcp->connection.is_hdcp2_revoked = 1;
+			status = MOD_HDCP_STATUS_HDCP2_RX_ID_LIST_REVOKED;
+		}
 	}
-
-
-	return MOD_HDCP_STATUS_HDCP2_VALIDATE_RX_ID_LIST_FAILURE;
+	mutex_unlock(&psp->hdcp_context.mutex);
+	return status;
 }
 
 enum mod_hdcp_status mod_hdcp_hdcp2_enable_dp_stream_encryption(struct mod_hdcp *hdcp)
@@ -737,7 +801,9 @@ enum mod_hdcp_status mod_hdcp_hdcp2_enable_dp_stream_encryption(struct mod_hdcp
 	struct ta_hdcp_shared_memory *hdcp_cmd;
 	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;
 	uint8_t i;
+	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
 
+	mutex_lock(&psp->hdcp_context.mutex);
 	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;
 	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
 
@@ -747,9 +813,9 @@ enum mod_hdcp_status mod_hdcp_hdcp2_enable_dp_stream_encryption(struct mod_hdcp
 
 
 	for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++) {
-		if (hdcp->displays[i].state != MOD_HDCP_DISPLAY_ACTIVE_AND_ADDED ||
-		    hdcp->displays[i].adjust.disable)
-			continue;
+		if (hdcp->displays[i].adjust.disable || hdcp->displays[i].state != MOD_HDCP_DISPLAY_ACTIVE)
+				continue;
+
 		hdcp_cmd->in_msg.hdcp2_enable_dp_stream_encryption.display_handle = hdcp->displays[i].index;
 		hdcp_cmd->in_msg.hdcp2_enable_dp_stream_encryption.session_handle = hdcp->auth.id;
 
@@ -763,8 +829,13 @@ enum mod_hdcp_status mod_hdcp_hdcp2_enable_dp_stream_encryption(struct mod_hdcp
 		HDCP_HDCP2_ENABLED_TRACE(hdcp, hdcp->displays[i].index);
 	}
 
-	return (hdcp_cmd->hdcp_status == TA_HDCP_STATUS__SUCCESS) ? MOD_HDCP_STATUS_SUCCESS
-								  : MOD_HDCP_STATUS_HDCP2_ENABLE_STREAM_ENCRYPTION;
+	if (hdcp_cmd->hdcp_status == TA_HDCP_STATUS__SUCCESS)
+		status = MOD_HDCP_STATUS_SUCCESS;
+	else
+		status = MOD_HDCP_STATUS_HDCP2_ENABLE_STREAM_ENCRYPTION_FAILURE;
+
+	mutex_unlock(&psp->hdcp_context.mutex);
+	return status;
 }
 
 enum mod_hdcp_status mod_hdcp_hdcp2_prepare_stream_management(struct mod_hdcp *hdcp)
@@ -774,7 +845,9 @@ enum mod_hdcp_status mod_hdcp_hdcp2_prepare_stream_management(struct mod_hdcp *h
 	struct ta_hdcp_shared_memory *hdcp_cmd;
 	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;
 	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out;
+	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
 
+	mutex_lock(&psp->hdcp_context.mutex);
 	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;
 	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
 
@@ -789,15 +862,17 @@ enum mod_hdcp_status mod_hdcp_hdcp2_prepare_stream_management(struct mod_hdcp *h
 	hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_PREPARE_PROCESS_AUTHENTICATION_MSG_V2;
 	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
 
-	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS)
-		return MOD_HDCP_STATUS_HDCP2_PREPARE_STREAM_MANAGEMENT_FAILURE;
-
-	hdcp->auth.msg.hdcp2.stream_manage_size = msg_out->prepare.msg1_desc.msg_size;
-
-	memcpy(hdcp->auth.msg.hdcp2.repeater_auth_stream_manage, &msg_out->prepare.transmitter_message[0],
-	       sizeof(hdcp->auth.msg.hdcp2.repeater_auth_stream_manage));
+	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) {
+		status = MOD_HDCP_STATUS_HDCP2_PREPARE_STREAM_MANAGEMENT_FAILURE;
+	} else {
+		hdcp->auth.msg.hdcp2.stream_manage_size = msg_out->prepare.msg1_desc.msg_size;
 
-	return MOD_HDCP_STATUS_SUCCESS;
+		memcpy(hdcp->auth.msg.hdcp2.repeater_auth_stream_manage,
+		       &msg_out->prepare.transmitter_message[0],
+		       sizeof(hdcp->auth.msg.hdcp2.repeater_auth_stream_manage));
+	}
+	mutex_unlock(&psp->hdcp_context.mutex);
+	return status;
 }
 
 enum mod_hdcp_status mod_hdcp_hdcp2_validate_stream_ready(struct mod_hdcp *hdcp)
@@ -806,7 +881,9 @@ enum mod_hdcp_status mod_hdcp_hdcp2_validate_stream_ready(struct mod_hdcp *hdcp)
 	struct ta_hdcp_shared_memory *hdcp_cmd;
 	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;
 	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out;
+	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
 
+	mutex_lock(&psp->hdcp_context.mutex);
 	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;
 	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
 
@@ -825,38 +902,13 @@ enum mod_hdcp_status mod_hdcp_hdcp2_validate_stream_ready(struct mod_hdcp *hdcp)
 	hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_PREPARE_PROCESS_AUTHENTICATION_MSG_V2;
 	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
 
-	return (hdcp_cmd->hdcp_status == TA_HDCP_STATUS__SUCCESS) &&
-			       (msg_out->process.msg1_status == TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS)
-		       ? MOD_HDCP_STATUS_SUCCESS
-		       : MOD_HDCP_STATUS_HDCP2_VALIDATE_STREAM_READY_FAILURE;
-}
-
-enum mod_hdcp_status mod_hdcp_hdcp2_get_link_encryption_status(struct mod_hdcp *hdcp,
-							       enum mod_hdcp_encryption_status *encryption_status)
-{
-	struct psp_context *psp = hdcp->config.psp.handle;
-	struct ta_hdcp_shared_memory *hdcp_cmd;
-
-	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;
-
-	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
-
-	hdcp_cmd->in_msg.hdcp2_get_encryption_status.session_handle = hdcp->auth.id;
-	hdcp_cmd->out_msg.hdcp2_get_encryption_status.protection_level = 0;
-	hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_GET_ENCRYPTION_STATUS;
-	*encryption_status = MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF;
-
-	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
-
-	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS)
-		return MOD_HDCP_STATUS_FAILURE;
-
-	if (hdcp_cmd->out_msg.hdcp2_get_encryption_status.protection_level == 1) {
-		if (hdcp_cmd->out_msg.hdcp2_get_encryption_status.hdcp2_type == TA_HDCP2_CONTENT_TYPE__TYPE1)
-			*encryption_status = MOD_HDCP_ENCRYPTION_STATUS_HDCP2_TYPE1_ON;
-		else
-			*encryption_status = MOD_HDCP_ENCRYPTION_STATUS_HDCP2_TYPE0_ON;
-	}
+	if (hdcp_cmd->hdcp_status == TA_HDCP_STATUS__SUCCESS &&
+	    msg_out->process.msg1_status == TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS)
+		status = MOD_HDCP_STATUS_SUCCESS;
+	else
+		status = MOD_HDCP_STATUS_HDCP2_VALIDATE_STREAM_READY_FAILURE;
 
-	return MOD_HDCP_STATUS_SUCCESS;
+	mutex_unlock(&psp->hdcp_context.mutex);
+	return status;
 }
+
diff --git a/drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h b/drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h
index c088602bc1a0..eed560eecbab 100644
--- a/drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h
+++ b/drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h
@@ -60,7 +60,7 @@ enum mod_hdcp_status {
 	MOD_HDCP_STATUS_HDCP1_KSV_LIST_NOT_READY,
 	MOD_HDCP_STATUS_HDCP1_VALIDATE_KSV_LIST_FAILURE,
 	MOD_HDCP_STATUS_HDCP1_KSV_LIST_REVOKED,
-	MOD_HDCP_STATUS_HDCP1_ENABLE_ENCRYPTION,
+	MOD_HDCP_STATUS_HDCP1_ENABLE_ENCRYPTION_FAILURE,
 	MOD_HDCP_STATUS_HDCP1_ENABLE_STREAM_ENCRYPTION_FAILURE,
 	MOD_HDCP_STATUS_HDCP1_MAX_CASCADE_EXCEEDED_FAILURE,
 	MOD_HDCP_STATUS_HDCP1_MAX_DEVS_EXCEEDED_FAILURE,
@@ -90,7 +90,7 @@ enum mod_hdcp_status {
 	MOD_HDCP_STATUS_HDCP2_RX_ID_LIST_NOT_READY,
 	MOD_HDCP_STATUS_HDCP2_VALIDATE_RX_ID_LIST_FAILURE,
 	MOD_HDCP_STATUS_HDCP2_RX_ID_LIST_REVOKED,
-	MOD_HDCP_STATUS_HDCP2_ENABLE_STREAM_ENCRYPTION,
+	MOD_HDCP_STATUS_HDCP2_ENABLE_STREAM_ENCRYPTION_FAILURE,
 	MOD_HDCP_STATUS_HDCP2_STREAM_READY_PENDING,
 	MOD_HDCP_STATUS_HDCP2_VALIDATE_STREAM_READY_FAILURE,
 	MOD_HDCP_STATUS_HDCP2_PREPARE_STREAM_MANAGEMENT_FAILURE,
@@ -117,7 +117,6 @@ enum mod_hdcp_operation_mode {
 enum mod_hdcp_display_state {
 	MOD_HDCP_DISPLAY_INACTIVE = 0,
 	MOD_HDCP_DISPLAY_ACTIVE,
-	MOD_HDCP_DISPLAY_ACTIVE_AND_ADDED,
 	MOD_HDCP_DISPLAY_ENCRYPTION_ENABLED
 };
 
diff --git a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c
index e75a4bb94488..dd1517684c90 100644
--- a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c
+++ b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c
@@ -24,6 +24,9 @@
 
 #include "power_helpers.h"
 #include "dc/inc/hw/dmcu.h"
+#include "dc/inc/hw/abm.h"
+#include "dc.h"
+#include "core_types.h"
 
 #define DIV_ROUNDUP(a, b) (((a)+((b)/2))/(b))
 
@@ -648,6 +651,24 @@ void fill_iram_v_2_3(struct iram_table_v_2_2 *ram_table, struct dmcu_iram_parame
 			params, ram_table);
 }
 
+bool dmub_init_abm_config(struct abm *abm,
+	struct dmcu_iram_parameters params)
+{
+	unsigned char ram_table[IRAM_SIZE];
+	bool result = false;
+
+	if (abm == NULL)
+		return false;
+
+	memset(&ram_table, 0, sizeof(ram_table));
+
+	fill_iram_v_2_3((struct iram_table_v_2_2 *)ram_table, params);
+	result = abm->funcs->init_abm_config(
+		abm, (char *)(&ram_table), IRAM_RESERVE_AREA_START_V2_2);
+
+	return result;
+}
+
 bool dmcu_load_iram(struct dmcu *dmcu,
 	struct dmcu_iram_parameters params)
 {
@@ -657,15 +678,15 @@ bool dmcu_load_iram(struct dmcu *dmcu,
 	if (dmcu == NULL)
 		return false;
 
-	if (!dmcu->funcs->is_dmcu_initialized(dmcu))
+	if (dmcu && !dmcu->funcs->is_dmcu_initialized(dmcu))
 		return true;
 
 	memset(&ram_table, 0, sizeof(ram_table));
 
 	if (dmcu->dmcu_version.abm_version == 0x24) {
 		fill_iram_v_2_3((struct iram_table_v_2_2 *)ram_table, params);
-		result = dmcu->funcs->load_iram(
-				dmcu, 0, (char *)(&ram_table), IRAM_RESERVE_AREA_START_V2_2);
+			result = dmcu->funcs->load_iram(
+					dmcu, 0, (char *)(&ram_table), IRAM_RESERVE_AREA_START_V2_2);
 	} else if (dmcu->dmcu_version.abm_version == 0x23) {
 		fill_iram_v_2_3((struct iram_table_v_2_2 *)ram_table, params);
 
diff --git a/drivers/gpu/drm/amd/display/modules/power/power_helpers.h b/drivers/gpu/drm/amd/display/modules/power/power_helpers.h
index e54157026330..46fbca2e2cd1 100644
--- a/drivers/gpu/drm/amd/display/modules/power/power_helpers.h
+++ b/drivers/gpu/drm/amd/display/modules/power/power_helpers.h
@@ -26,6 +26,7 @@
 #define MODULES_POWER_POWER_HELPERS_H_
 
 #include "dc/inc/hw/dmcu.h"
+#include "dc/inc/hw/abm.h"
 
 
 enum abm_defines {
@@ -44,5 +45,7 @@ struct dmcu_iram_parameters {
 
 bool dmcu_load_iram(struct dmcu *dmcu,
 		struct dmcu_iram_parameters params);
+bool dmub_init_abm_config(struct abm *abm,
+		struct dmcu_iram_parameters params);
 
 #endif /* MODULES_POWER_POWER_HELPERS_H_ */
diff --git a/drivers/gpu/drm/amd/include/asic_reg/nbif/nbif_6_1_offset.h b/drivers/gpu/drm/amd/include/asic_reg/nbif/nbif_6_1_offset.h
index 68d0ffad28c7..92fd27c26a77 100644
--- a/drivers/gpu/drm/amd/include/asic_reg/nbif/nbif_6_1_offset.h
+++ b/drivers/gpu/drm/amd/include/asic_reg/nbif/nbif_6_1_offset.h
@@ -1162,8 +1162,10 @@
 #define mmRCC_CONFIG_MEMSIZE_BASE_IDX                                                                  0
 #define mmRCC_CONFIG_RESERVED                                                                          0x0de4 // duplicate 
 #define mmRCC_CONFIG_RESERVED_BASE_IDX                                                                 0
+#ifndef mmRCC_IOV_FUNC_IDENTIFIER
 #define mmRCC_IOV_FUNC_IDENTIFIER                                                                      0x0de5 // duplicate 
 #define mmRCC_IOV_FUNC_IDENTIFIER_BASE_IDX                                                             0
+#endif
 
 
 // addressBlock: syshub_mmreg_ind_syshubdec
diff --git a/drivers/gpu/drm/amd/include/asic_reg/nbio/nbio_7_0_offset.h b/drivers/gpu/drm/amd/include/asic_reg/nbio/nbio_7_0_offset.h
index 435462294fbc..a7cd760ebf8f 100644
--- a/drivers/gpu/drm/amd/include/asic_reg/nbio/nbio_7_0_offset.h
+++ b/drivers/gpu/drm/amd/include/asic_reg/nbio/nbio_7_0_offset.h
@@ -4251,8 +4251,10 @@
 #define mmRCC_CONFIG_MEMSIZE_BASE_IDX                                                                  2
 #define mmRCC_CONFIG_RESERVED                                                                          0x00c4
 #define mmRCC_CONFIG_RESERVED_BASE_IDX                                                                 2
+#ifndef mmRCC_IOV_FUNC_IDENTIFIER
 #define mmRCC_IOV_FUNC_IDENTIFIER                                                                      0x00c5
 #define mmRCC_IOV_FUNC_IDENTIFIER_BASE_IDX                                                             2
+#endif
 
 
 // addressBlock: nbio_nbif0_rcc_dev0_BIFDEC1
diff --git a/drivers/gpu/drm/amd/include/asic_reg/nbio/nbio_7_4_offset.h b/drivers/gpu/drm/amd/include/asic_reg/nbio/nbio_7_4_offset.h
index ce5830ebe095..0c5a08bc034a 100644
--- a/drivers/gpu/drm/amd/include/asic_reg/nbio/nbio_7_4_offset.h
+++ b/drivers/gpu/drm/amd/include/asic_reg/nbio/nbio_7_4_offset.h
@@ -2687,8 +2687,10 @@
 #define mmRCC_CONFIG_MEMSIZE_BASE_IDX                                                                  2
 #define mmRCC_CONFIG_RESERVED                                                                          0x00c4
 #define mmRCC_CONFIG_RESERVED_BASE_IDX                                                                 2
+#ifndef mmRCC_IOV_FUNC_IDENTIFIER
 #define mmRCC_IOV_FUNC_IDENTIFIER                                                                      0x00c5
 #define mmRCC_IOV_FUNC_IDENTIFIER_BASE_IDX                                                             2
+#endif
 
 
 // addressBlock: nbio_nbif0_rcc_dev0_BIFDEC1
diff --git a/drivers/gpu/drm/amd/include/asic_reg/pwr/pwr_10_0_offset.h b/drivers/gpu/drm/amd/include/asic_reg/pwr/pwr_10_0_offset.h
new file mode 100644
index 000000000000..e87c359ea1fe
--- /dev/null
+++ b/drivers/gpu/drm/amd/include/asic_reg/pwr/pwr_10_0_offset.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2020  Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) 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 _pwr_10_0_OFFSET_HEADER
+#define _pwr_10_0_OFFSET_HEADER
+
+#define mmPWR_MISC_CNTL_STATUS                                                                         0x0183
+#define mmPWR_MISC_CNTL_STATUS_BASE_IDX                                                                0
+
+#endif
diff --git a/drivers/gpu/drm/amd/include/asic_reg/pwr/pwr_10_0_sh_mask.h b/drivers/gpu/drm/amd/include/asic_reg/pwr/pwr_10_0_sh_mask.h
new file mode 100644
index 000000000000..8a000c21651c
--- /dev/null
+++ b/drivers/gpu/drm/amd/include/asic_reg/pwr/pwr_10_0_sh_mask.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2020  Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) 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 _pwr_10_0_SH_MASK_HEADER
+#define _pwr_10_0_SH_MASK_HEADER
+
+//PWR_MISC_CNTL_STATUS
+#define PWR_MISC_CNTL_STATUS__PWR_GFX_RLC_CGPG_EN__SHIFT                                                      0x0
+#define PWR_MISC_CNTL_STATUS__PWR_GFXOFF_STATUS__SHIFT                                                        0x1
+#define PWR_MISC_CNTL_STATUS__PWR_GFX_RLC_CGPG_EN_MASK                                                        0x00000001L
+#define PWR_MISC_CNTL_STATUS__PWR_GFXOFF_STATUS_MASK                                                          0x00000006L
+
+#endif
diff --git a/drivers/gpu/drm/amd/include/asic_reg/smuio/smuio_12_0_0_offset.h b/drivers/gpu/drm/amd/include/asic_reg/smuio/smuio_12_0_0_offset.h
new file mode 100644
index 000000000000..9bf73284ad73
--- /dev/null
+++ b/drivers/gpu/drm/amd/include/asic_reg/smuio/smuio_12_0_0_offset.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2020  Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) 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 _smuio_12_0_0_OFFSET_HEADER
+#define _smuio_12_0_0_OFFSET_HEADER
+
+#define mmSMUIO_GFX_MISC_CNTL                                                                          0x00c8
+#define mmSMUIO_GFX_MISC_CNTL_BASE_IDX                                                                 0
+
+#define mmPWR_MISC_CNTL_STATUS                                                                         0x0183
+#define mmPWR_MISC_CNTL_STATUS_BASE_IDX                                                                1
+
+#endif
diff --git a/drivers/gpu/drm/amd/include/asic_reg/smuio/smuio_12_0_0_sh_mask.h b/drivers/gpu/drm/amd/include/asic_reg/smuio/smuio_12_0_0_sh_mask.h
new file mode 100644
index 000000000000..26556fa3d054
--- /dev/null
+++ b/drivers/gpu/drm/amd/include/asic_reg/smuio/smuio_12_0_0_sh_mask.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2020  Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) 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 _smuio_12_0_0_SH_MASK_HEADER
+#define _smuio_12_0_0_SH_MASK_HEADER
+
+//SMUIO_GFX_MISC_CNTL
+#define SMUIO_GFX_MISC_CNTL__PWR_GFXOFF_STATUS_MASK                                                           0x00000006L
+#define SMUIO_GFX_MISC_CNTL__PWR_GFXOFF_STATUS__SHIFT                                                         0x1
+//PWR_MISC_CNTL_STATUS
+#define PWR_MISC_CNTL_STATUS__PWR_GFX_RLC_CGPG_EN__SHIFT                                                      0x0
+#define PWR_MISC_CNTL_STATUS__PWR_GFXOFF_STATUS__SHIFT                                                        0x1
+#define PWR_MISC_CNTL_STATUS__PWR_GFX_RLC_CGPG_EN_MASK                                                        0x00000001L
+#define PWR_MISC_CNTL_STATUS__PWR_GFXOFF_STATUS_MASK                                                          0x00000006L
+
+#endif
diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h
index 70146518174c..a6f6e6bf5992 100644
--- a/drivers/gpu/drm/amd/include/atomfirmware.h
+++ b/drivers/gpu/drm/amd/include/atomfirmware.h
@@ -1876,6 +1876,108 @@ struct atom_smc_dpm_info_v4_6
   uint32_t   boardreserved[10];
 };
 
+struct atom_smc_dpm_info_v4_7
+{
+  struct   atom_common_table_header  table_header;
+    // SECTION: BOARD PARAMETERS
+    // I2C Control
+  struct smudpm_i2c_controller_config_v2  I2cControllers[8];
+
+  // SVI2 Board Parameters
+  uint16_t     MaxVoltageStepGfx; // In mV(Q2) Max voltage step that SMU will request. Multiple steps are taken if voltage change exceeds this value.
+  uint16_t     MaxVoltageStepSoc; // In mV(Q2) Max voltage step that SMU will request. Multiple steps are taken if voltage change exceeds this value.
+
+  uint8_t      VddGfxVrMapping;   // Use VR_MAPPING* bitfields
+  uint8_t      VddSocVrMapping;   // Use VR_MAPPING* bitfields
+  uint8_t      VddMem0VrMapping;  // Use VR_MAPPING* bitfields
+  uint8_t      VddMem1VrMapping;  // Use VR_MAPPING* bitfields
+
+  uint8_t      GfxUlvPhaseSheddingMask; // set this to 1 to set PSI0/1 to 1 in ULV mode
+  uint8_t      SocUlvPhaseSheddingMask; // set this to 1 to set PSI0/1 to 1 in ULV mode
+  uint8_t      ExternalSensorPresent; // External RDI connected to TMON (aka TEMP IN)
+  uint8_t      Padding8_V;
+
+  // Telemetry Settings
+  uint16_t     GfxMaxCurrent;   // in Amps
+  uint8_t      GfxOffset;       // in Amps
+  uint8_t      Padding_TelemetryGfx;
+  uint16_t     SocMaxCurrent;   // in Amps
+  uint8_t      SocOffset;       // in Amps
+  uint8_t      Padding_TelemetrySoc;
+
+  uint16_t     Mem0MaxCurrent;   // in Amps
+  uint8_t      Mem0Offset;       // in Amps
+  uint8_t      Padding_TelemetryMem0;
+
+  uint16_t     Mem1MaxCurrent;   // in Amps
+  uint8_t      Mem1Offset;       // in Amps
+  uint8_t      Padding_TelemetryMem1;
+
+  // GPIO Settings
+  uint8_t      AcDcGpio;        // GPIO pin configured for AC/DC switching
+  uint8_t      AcDcPolarity;    // GPIO polarity for AC/DC switching
+  uint8_t      VR0HotGpio;      // GPIO pin configured for VR0 HOT event
+  uint8_t      VR0HotPolarity;  // GPIO polarity for VR0 HOT event
+
+  uint8_t      VR1HotGpio;      // GPIO pin configured for VR1 HOT event
+  uint8_t      VR1HotPolarity;  // GPIO polarity for VR1 HOT event
+  uint8_t      GthrGpio;        // GPIO pin configured for GTHR Event
+  uint8_t      GthrPolarity;    // replace GPIO polarity for GTHR
+
+  // LED Display Settings
+  uint8_t      LedPin0;         // GPIO number for LedPin[0]
+  uint8_t      LedPin1;         // GPIO number for LedPin[1]
+  uint8_t      LedPin2;         // GPIO number for LedPin[2]
+  uint8_t      padding8_4;
+
+  // GFXCLK PLL Spread Spectrum
+  uint8_t      PllGfxclkSpreadEnabled;   // on or off
+  uint8_t      PllGfxclkSpreadPercent;   // Q4.4
+  uint16_t     PllGfxclkSpreadFreq;      // kHz
+
+  // GFXCLK DFLL Spread Spectrum
+  uint8_t      DfllGfxclkSpreadEnabled;   // on or off
+  uint8_t      DfllGfxclkSpreadPercent;   // Q4.4
+  uint16_t     DfllGfxclkSpreadFreq;      // kHz
+
+  // UCLK Spread Spectrum
+  uint8_t      UclkSpreadEnabled;   // on or off
+  uint8_t      UclkSpreadPercent;   // Q4.4
+  uint16_t     UclkSpreadFreq;      // kHz
+
+  // SOCCLK Spread Spectrum
+  uint8_t      SoclkSpreadEnabled;   // on or off
+  uint8_t      SocclkSpreadPercent;   // Q4.4
+  uint16_t     SocclkSpreadFreq;      // kHz
+
+  // Total board power
+  uint16_t     TotalBoardPower;     //Only needed for TCP Estimated case, where TCP = TGP+Total Board Power
+  uint16_t     BoardPadding;
+
+  // Mvdd Svi2 Div Ratio Setting
+  uint32_t     MvddRatio; // This is used for MVDD Vid workaround. It has 16 fractional bits (Q16.16)
+
+  // GPIO pins for I2C communications with 2nd controller for Input Telemetry Sequence
+  uint8_t      GpioI2cScl;          // Serial Clock
+  uint8_t      GpioI2cSda;          // Serial Data
+  uint16_t     GpioPadding;
+
+  // Additional LED Display Settings
+  uint8_t      LedPin3;         // GPIO number for LedPin[3] - PCIE GEN Speed
+  uint8_t      LedPin4;         // GPIO number for LedPin[4] - PMFW Error Status
+  uint16_t     LedEnableMask;
+
+  // Power Limit Scalars
+  uint8_t      PowerLimitScalar[4];    //[PPT_THROTTLER_COUNT]
+
+  uint8_t      MvddUlvPhaseSheddingMask;
+  uint8_t      VddciUlvPhaseSheddingMask;
+  uint8_t      Padding8_Psi1;
+  uint8_t      Padding8_Psi2;
+
+  uint32_t     BoardReserved[5];
+};
+
 /* 
   ***************************************************************************
     Data Table asic_profiling_info  structure
diff --git a/drivers/gpu/drm/amd/include/cgs_common.h b/drivers/gpu/drm/amd/include/cgs_common.h
index a69deb3a2ac0..60a6536ff656 100644
--- a/drivers/gpu/drm/amd/include/cgs_common.h
+++ b/drivers/gpu/drm/amd/include/cgs_common.h
@@ -32,7 +32,6 @@ struct cgs_device;
  * enum cgs_ind_reg - Indirect register spaces
  */
 enum cgs_ind_reg {
-	CGS_IND_REG__MMIO,
 	CGS_IND_REG__PCIE,
 	CGS_IND_REG__SMC,
 	CGS_IND_REG__UVD_CTX,
diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
index 2a12614a12c2..fdff3e1c5e95 100644
--- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
+++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
@@ -50,6 +50,7 @@ static int amd_powerplay_create(struct amdgpu_device *adev)
 	hwmgr->not_vf = !amdgpu_sriov_vf(adev);
 	hwmgr->device = amdgpu_cgs_create_device(adev);
 	mutex_init(&hwmgr->smu_lock);
+	mutex_init(&hwmgr->msg_lock);
 	hwmgr->chip_family = adev->family;
 	hwmgr->chip_id = adev->asic_type;
 	hwmgr->feature_mask = adev->pm.pp_feature;
@@ -64,6 +65,8 @@ static void amd_powerplay_destroy(struct amdgpu_device *adev)
 {
 	struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle;
 
+	mutex_destroy(&hwmgr->msg_lock);
+
 	kfree(hwmgr->hardcode_pp_table);
 	hwmgr->hardcode_pp_table = NULL;
 
diff --git a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
index e8b27fab6aa1..d4599fa6dc0b 100644
--- a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
+++ b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
@@ -62,6 +62,7 @@ const char *smu_get_feature_name(struct smu_context *smu, enum smu_feature_mask
 
 size_t smu_sys_get_pp_feature_mask(struct smu_context *smu, char *buf)
 {
+	struct amdgpu_device *adev = smu->adev;
 	size_t size = 0;
 	int ret = 0, i = 0;
 	uint32_t feature_mask[2] = { 0 };
@@ -70,6 +71,9 @@ size_t smu_sys_get_pp_feature_mask(struct smu_context *smu, char *buf)
 	uint32_t sort_feature[SMU_FEATURE_COUNT];
 	uint64_t hw_feature_count = 0;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	mutex_lock(&smu->mutex);
 
 	ret = smu_feature_get_enabled_mask(smu, feature_mask, 2);
@@ -110,9 +114,6 @@ static int smu_feature_update_enable_state(struct smu_context *smu,
 	uint32_t feature_low = 0, feature_high = 0;
 	int ret = 0;
 
-	if (!smu->pm_enabled)
-		return ret;
-
 	feature_low = (feature_mask >> 0 ) & 0xffffffff;
 	feature_high = (feature_mask >> 32) & 0xffffffff;
 
@@ -155,6 +156,10 @@ int smu_sys_set_pp_feature_mask(struct smu_context *smu, uint64_t new_mask)
 	uint64_t feature_2_enabled = 0;
 	uint64_t feature_2_disabled = 0;
 	uint64_t feature_enables = 0;
+	struct amdgpu_device *adev = smu->adev;
+
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
 
 	mutex_lock(&smu->mutex);
 
@@ -191,16 +196,31 @@ int smu_get_smc_version(struct smu_context *smu, uint32_t *if_version, uint32_t
 	if (!if_version && !smu_version)
 		return -EINVAL;
 
+	if (smu->smc_fw_if_version && smu->smc_fw_version)
+	{
+		if (if_version)
+			*if_version = smu->smc_fw_if_version;
+
+		if (smu_version)
+			*smu_version = smu->smc_fw_version;
+
+		return 0;
+	}
+
 	if (if_version) {
 		ret = smu_send_smc_msg(smu, SMU_MSG_GetDriverIfVersion, if_version);
 		if (ret)
 			return ret;
+
+		smu->smc_fw_if_version = *if_version;
 	}
 
 	if (smu_version) {
 		ret = smu_send_smc_msg(smu, SMU_MSG_GetSmuVersion, smu_version);
 		if (ret)
 			return ret;
+
+		smu->smc_fw_version = *smu_version;
 	}
 
 	return ret;
@@ -417,8 +437,12 @@ bool smu_clk_dpm_is_enabled(struct smu_context *smu, enum smu_clk_type clk_type)
 int smu_dpm_set_power_gate(struct smu_context *smu, uint32_t block_type,
 			   bool gate)
 {
+	struct amdgpu_device *adev = smu->adev;
 	int ret = 0;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	switch (block_type) {
 	case AMD_IP_BLOCK_TYPE_UVD:
 		ret = smu_dpm_set_uvd_enable(smu, !gate);
@@ -569,8 +593,12 @@ bool is_support_sw_smu_xgmi(struct amdgpu_device *adev)
 int smu_sys_get_pp_table(struct smu_context *smu, void **table)
 {
 	struct smu_table_context *smu_table = &smu->smu_table;
+	struct amdgpu_device *adev = smu->adev;
 	uint32_t powerplay_table_size;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	if (!smu_table->power_play_table && !smu_table->hardcode_pptable)
 		return -EINVAL;
 
@@ -591,11 +619,13 @@ int smu_sys_get_pp_table(struct smu_context *smu, void **table)
 int smu_sys_set_pp_table(struct smu_context *smu,  void *buf, size_t size)
 {
 	struct smu_table_context *smu_table = &smu->smu_table;
+	struct amdgpu_device *adev = smu->adev;
 	ATOM_COMMON_TABLE_HEADER *header = (ATOM_COMMON_TABLE_HEADER *)buf;
 	int ret = 0;
 
-	if (!smu->pm_enabled)
+	if (!adev->pm.dpm_enabled)
 		return -EINVAL;
+
 	if (header->usStructureSize != size) {
 		pr_err("pp table size not matched !\n");
 		return -EIO;
@@ -636,8 +666,6 @@ int smu_feature_init_dpm(struct smu_context *smu)
 	int ret = 0;
 	uint32_t allowed_feature_mask[SMU_FEATURE_MAX/32];
 
-	if (!smu->pm_enabled)
-		return ret;
 	mutex_lock(&feature->mutex);
 	bitmap_zero(feature->allowed, SMU_FEATURE_MAX);
 	mutex_unlock(&feature->mutex);
@@ -932,13 +960,6 @@ static int smu_sw_init(void *handle)
 		return ret;
 	}
 
-	if (adev->smu.ppt_funcs->i2c_eeprom_init) {
-		ret = smu_i2c_eeprom_init(smu, &adev->pm.smu_i2c);
-
-		if (ret)
-			return ret;
-	}
-
 	return 0;
 }
 
@@ -948,9 +969,6 @@ static int smu_sw_fini(void *handle)
 	struct smu_context *smu = &adev->smu;
 	int ret;
 
-	if (adev->smu.ppt_funcs->i2c_eeprom_fini)
-		smu_i2c_eeprom_fini(smu, &adev->pm.smu_i2c);
-
 	kfree(smu->irq_source);
 	smu->irq_source = NULL;
 
@@ -1366,10 +1384,11 @@ static int smu_hw_init(void *handle)
 	if (ret)
 		goto failed;
 
-	if (!smu->pm_enabled)
-		adev->pm.dpm_enabled = false;
-	else
-		adev->pm.dpm_enabled = true;	/* TODO: will set dpm_enabled flag while VCN and DAL DPM is workable */
+	ret = smu_i2c_eeprom_init(smu, &adev->pm.smu_i2c);
+	if (ret)
+		goto failed;
+
+	adev->pm.dpm_enabled = true;
 
 	pr_info("SMU is initialized successfully!\n");
 
@@ -1403,6 +1422,10 @@ static int smu_hw_fini(void *handle)
 	if (!smu->pm_enabled)
 		return 0;
 
+	adev->pm.dpm_enabled = false;
+
+	smu_i2c_eeprom_fini(smu, &adev->pm.smu_i2c);
+
 	if (!amdgpu_sriov_vf(adev)){
 		ret = smu_stop_thermal_control(smu);
 		if (ret) {
@@ -1542,6 +1565,10 @@ static int smu_suspend(void *handle)
 	if (!smu->pm_enabled)
 		return 0;
 
+	adev->pm.dpm_enabled = false;
+
+	smu_i2c_eeprom_fini(smu, &adev->pm.smu_i2c);
+
 	if(!amdgpu_sriov_vf(adev)) {
 		ret = smu_disable_dpm(smu);
 		if (ret)
@@ -1587,11 +1614,17 @@ static int smu_resume(void *handle)
 	if (ret)
 		goto failed;
 
+	ret = smu_i2c_eeprom_init(smu, &adev->pm.smu_i2c);
+	if (ret)
+		goto failed;
+
 	if (smu->is_apu)
 		smu_set_gfx_cgpg(&adev->smu, true);
 
 	smu->disable_uclk_switch = 0;
 
+	adev->pm.dpm_enabled = true;
+
 	pr_info("SMU is resumed successfully!\n");
 
 	return 0;
@@ -1603,10 +1636,14 @@ static int smu_resume(void *handle)
 int smu_display_configuration_change(struct smu_context *smu,
 				     const struct amd_pp_display_configuration *display_config)
 {
+	struct amdgpu_device *adev = smu->adev;
 	int index = 0;
 	int num_of_active_display = 0;
 
-	if (!smu->pm_enabled || !is_support_sw_smu(smu->adev))
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
+	if (!is_support_sw_smu(smu->adev))
 		return -EINVAL;
 
 	if (!display_config)
@@ -1668,12 +1705,16 @@ int smu_get_current_clocks(struct smu_context *smu,
 			   struct amd_pp_clock_info *clocks)
 {
 	struct amd_pp_simple_clock_info simple_clocks = {0};
+	struct amdgpu_device *adev = smu->adev;
 	struct smu_clock_info hw_clocks;
 	int ret = 0;
 
 	if (!is_support_sw_smu(smu->adev))
 		return -EINVAL;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	mutex_lock(&smu->mutex);
 
 	smu_get_dal_power_level(smu, &simple_clocks);
@@ -1736,7 +1777,7 @@ static int smu_enable_umd_pstate(void *handle,
 	struct smu_context *smu = (struct smu_context*)(handle);
 	struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
 
-	if (!smu->is_apu && (!smu->pm_enabled || !smu_dpm_ctx->dpm_context))
+	if (!smu->is_apu && !smu_dpm_ctx->dpm_context)
 		return -EINVAL;
 
 	if (!(smu_dpm_ctx->dpm_level & profile_mode_mask)) {
@@ -1778,9 +1819,6 @@ int smu_adjust_power_state_dynamic(struct smu_context *smu,
 	long workload;
 	struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
 
-	if (!smu->pm_enabled)
-		return -EINVAL;
-
 	if (!skip_display_settings) {
 		ret = smu_display_config_changed(smu);
 		if (ret) {
@@ -1831,8 +1869,12 @@ int smu_handle_task(struct smu_context *smu,
 		    enum amd_pp_task task_id,
 		    bool lock_needed)
 {
+	struct amdgpu_device *adev = smu->adev;
 	int ret = 0;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	if (lock_needed)
 		mutex_lock(&smu->mutex);
 
@@ -1866,10 +1908,11 @@ int smu_switch_power_profile(struct smu_context *smu,
 			     bool en)
 {
 	struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
+	struct amdgpu_device *adev = smu->adev;
 	long workload;
 	uint32_t index;
 
-	if (!smu->pm_enabled)
+	if (!adev->pm.dpm_enabled)
 		return -EINVAL;
 
 	if (!(type < PP_SMC_POWER_PROFILE_CUSTOM))
@@ -1900,8 +1943,12 @@ int smu_switch_power_profile(struct smu_context *smu,
 enum amd_dpm_forced_level smu_get_performance_level(struct smu_context *smu)
 {
 	struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
+	struct amdgpu_device *adev = smu->adev;
 	enum amd_dpm_forced_level level;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	if (!smu->is_apu && !smu_dpm_ctx->dpm_context)
 		return -EINVAL;
 
@@ -1915,8 +1962,12 @@ enum amd_dpm_forced_level smu_get_performance_level(struct smu_context *smu)
 int smu_force_performance_level(struct smu_context *smu, enum amd_dpm_forced_level level)
 {
 	struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
+	struct amdgpu_device *adev = smu->adev;
 	int ret = 0;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	if (!smu->is_apu && !smu_dpm_ctx->dpm_context)
 		return -EINVAL;
 
@@ -1939,8 +1990,12 @@ int smu_force_performance_level(struct smu_context *smu, enum amd_dpm_forced_lev
 
 int smu_set_display_count(struct smu_context *smu, uint32_t count)
 {
+	struct amdgpu_device *adev = smu->adev;
 	int ret = 0;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	mutex_lock(&smu->mutex);
 	ret = smu_init_display_count(smu, count);
 	mutex_unlock(&smu->mutex);
@@ -1954,8 +2009,12 @@ int smu_force_clk_levels(struct smu_context *smu,
 			 bool lock_needed)
 {
 	struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
+	struct amdgpu_device *adev = smu->adev;
 	int ret = 0;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) {
 		pr_debug("force clock level is for dpm manual mode only.\n");
 		return -EINVAL;
@@ -1973,20 +2032,19 @@ int smu_force_clk_levels(struct smu_context *smu,
 	return ret;
 }
 
+/*
+ * On system suspending or resetting, the dpm_enabled
+ * flag will be cleared. So that those SMU services which
+ * are not supported will be gated.
+ * However, the mp1 state setting should still be granted
+ * even if the dpm_enabled cleared.
+ */
 int smu_set_mp1_state(struct smu_context *smu,
 		      enum pp_mp1_state mp1_state)
 {
 	uint16_t msg;
 	int ret;
 
-	/*
-	 * The SMC is not fully ready. That may be
-	 * expected as the IP may be masked.
-	 * So, just return without error.
-	 */
-	if (!smu->pm_enabled)
-		return 0;
-
 	mutex_lock(&smu->mutex);
 
 	switch (mp1_state) {
@@ -2023,15 +2081,11 @@ int smu_set_mp1_state(struct smu_context *smu,
 int smu_set_df_cstate(struct smu_context *smu,
 		      enum pp_df_cstate state)
 {
+	struct amdgpu_device *adev = smu->adev;
 	int ret = 0;
 
-	/*
-	 * The SMC is not fully ready. That may be
-	 * expected as the IP may be masked.
-	 * So, just return without error.
-	 */
-	if (!smu->pm_enabled)
-		return 0;
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
 
 	if (!smu->ppt_funcs || !smu->ppt_funcs->set_df_cstate)
 		return 0;
@@ -2065,6 +2119,10 @@ int smu_set_watermarks_for_clock_ranges(struct smu_context *smu,
 		struct dm_pp_wm_sets_with_clock_ranges_soc15 *clock_ranges)
 {
 	void *table = smu->smu_table.watermarks_table;
+	struct amdgpu_device *adev = smu->adev;
+
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
 
 	if (!table)
 		return -EINVAL;
@@ -2089,8 +2147,12 @@ int smu_set_watermarks_for_clock_ranges(struct smu_context *smu,
 
 int smu_set_ac_dc(struct smu_context *smu)
 {
+	struct amdgpu_device *adev = smu->adev;
 	int ret = 0;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	/* controlled by firmware */
 	if (smu->dc_controlled_by_gpio)
 		return 0;
@@ -2149,8 +2211,12 @@ const struct amdgpu_ip_block_version smu_v12_0_ip_block =
 
 int smu_load_microcode(struct smu_context *smu)
 {
+	struct amdgpu_device *adev = smu->adev;
 	int ret = 0;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	mutex_lock(&smu->mutex);
 
 	if (smu->ppt_funcs->load_microcode)
@@ -2163,8 +2229,12 @@ int smu_load_microcode(struct smu_context *smu)
 
 int smu_check_fw_status(struct smu_context *smu)
 {
+	struct amdgpu_device *adev = smu->adev;
 	int ret = 0;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	mutex_lock(&smu->mutex);
 
 	if (smu->ppt_funcs->check_fw_status)
@@ -2191,8 +2261,12 @@ int smu_set_gfx_cgpg(struct smu_context *smu, bool enabled)
 
 int smu_set_fan_speed_rpm(struct smu_context *smu, uint32_t speed)
 {
+	struct amdgpu_device *adev = smu->adev;
 	int ret = 0;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	mutex_lock(&smu->mutex);
 
 	if (smu->ppt_funcs->set_fan_speed_rpm)
@@ -2208,10 +2282,15 @@ int smu_get_power_limit(struct smu_context *smu,
 			bool def,
 			bool lock_needed)
 {
+	struct amdgpu_device *adev = smu->adev;
 	int ret = 0;
 
-	if (lock_needed)
+	if (lock_needed) {
+		if (!adev->pm.dpm_enabled)
+			return -EINVAL;
+
 		mutex_lock(&smu->mutex);
+	}
 
 	if (smu->ppt_funcs->get_power_limit)
 		ret = smu->ppt_funcs->get_power_limit(smu, limit, def);
@@ -2224,8 +2303,12 @@ int smu_get_power_limit(struct smu_context *smu,
 
 int smu_set_power_limit(struct smu_context *smu, uint32_t limit)
 {
+	struct amdgpu_device *adev = smu->adev;
 	int ret = 0;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	mutex_lock(&smu->mutex);
 
 	if (smu->ppt_funcs->set_power_limit)
@@ -2238,8 +2321,12 @@ int smu_set_power_limit(struct smu_context *smu, uint32_t limit)
 
 int smu_print_clk_levels(struct smu_context *smu, enum smu_clk_type clk_type, char *buf)
 {
+	struct amdgpu_device *adev = smu->adev;
 	int ret = 0;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	mutex_lock(&smu->mutex);
 
 	if (smu->ppt_funcs->print_clk_levels)
@@ -2252,8 +2339,12 @@ int smu_print_clk_levels(struct smu_context *smu, enum smu_clk_type clk_type, ch
 
 int smu_get_od_percentage(struct smu_context *smu, enum smu_clk_type type)
 {
+	struct amdgpu_device *adev = smu->adev;
 	int ret = 0;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	mutex_lock(&smu->mutex);
 
 	if (smu->ppt_funcs->get_od_percentage)
@@ -2266,8 +2357,12 @@ int smu_get_od_percentage(struct smu_context *smu, enum smu_clk_type type)
 
 int smu_set_od_percentage(struct smu_context *smu, enum smu_clk_type type, uint32_t value)
 {
+	struct amdgpu_device *adev = smu->adev;
 	int ret = 0;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	mutex_lock(&smu->mutex);
 
 	if (smu->ppt_funcs->set_od_percentage)
@@ -2282,8 +2377,12 @@ int smu_od_edit_dpm_table(struct smu_context *smu,
 			  enum PP_OD_DPM_TABLE_COMMAND type,
 			  long *input, uint32_t size)
 {
+	struct amdgpu_device *adev = smu->adev;
 	int ret = 0;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	mutex_lock(&smu->mutex);
 
 	if (smu->ppt_funcs->od_edit_dpm_table)
@@ -2298,8 +2397,12 @@ int smu_read_sensor(struct smu_context *smu,
 		    enum amd_pp_sensors sensor,
 		    void *data, uint32_t *size)
 {
+	struct amdgpu_device *adev = smu->adev;
 	int ret = 0;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	mutex_lock(&smu->mutex);
 
 	if (smu->ppt_funcs->read_sensor)
@@ -2312,8 +2415,12 @@ int smu_read_sensor(struct smu_context *smu,
 
 int smu_get_power_profile_mode(struct smu_context *smu, char *buf)
 {
+	struct amdgpu_device *adev = smu->adev;
 	int ret = 0;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	mutex_lock(&smu->mutex);
 
 	if (smu->ppt_funcs->get_power_profile_mode)
@@ -2329,8 +2436,12 @@ int smu_set_power_profile_mode(struct smu_context *smu,
 			       uint32_t param_size,
 			       bool lock_needed)
 {
+	struct amdgpu_device *adev = smu->adev;
 	int ret = 0;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	if (lock_needed)
 		mutex_lock(&smu->mutex);
 
@@ -2346,8 +2457,12 @@ int smu_set_power_profile_mode(struct smu_context *smu,
 
 int smu_get_fan_control_mode(struct smu_context *smu)
 {
+	struct amdgpu_device *adev = smu->adev;
 	int ret = 0;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	mutex_lock(&smu->mutex);
 
 	if (smu->ppt_funcs->get_fan_control_mode)
@@ -2360,8 +2475,12 @@ int smu_get_fan_control_mode(struct smu_context *smu)
 
 int smu_set_fan_control_mode(struct smu_context *smu, int value)
 {
+	struct amdgpu_device *adev = smu->adev;
 	int ret = 0;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	mutex_lock(&smu->mutex);
 
 	if (smu->ppt_funcs->set_fan_control_mode)
@@ -2374,8 +2493,12 @@ int smu_set_fan_control_mode(struct smu_context *smu, int value)
 
 int smu_get_fan_speed_percent(struct smu_context *smu, uint32_t *speed)
 {
+	struct amdgpu_device *adev = smu->adev;
 	int ret = 0;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	mutex_lock(&smu->mutex);
 
 	if (smu->ppt_funcs->get_fan_speed_percent)
@@ -2388,8 +2511,12 @@ int smu_get_fan_speed_percent(struct smu_context *smu, uint32_t *speed)
 
 int smu_set_fan_speed_percent(struct smu_context *smu, uint32_t speed)
 {
+	struct amdgpu_device *adev = smu->adev;
 	int ret = 0;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	mutex_lock(&smu->mutex);
 
 	if (smu->ppt_funcs->set_fan_speed_percent)
@@ -2402,8 +2529,12 @@ int smu_set_fan_speed_percent(struct smu_context *smu, uint32_t speed)
 
 int smu_get_fan_speed_rpm(struct smu_context *smu, uint32_t *speed)
 {
+	struct amdgpu_device *adev = smu->adev;
 	int ret = 0;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	mutex_lock(&smu->mutex);
 
 	if (smu->ppt_funcs->get_fan_speed_rpm)
@@ -2416,8 +2547,12 @@ int smu_get_fan_speed_rpm(struct smu_context *smu, uint32_t *speed)
 
 int smu_set_deep_sleep_dcefclk(struct smu_context *smu, int clk)
 {
+	struct amdgpu_device *adev = smu->adev;
 	int ret = 0;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	mutex_lock(&smu->mutex);
 
 	if (smu->ppt_funcs->set_deep_sleep_dcefclk)
@@ -2430,8 +2565,12 @@ int smu_set_deep_sleep_dcefclk(struct smu_context *smu, int clk)
 
 int smu_set_active_display_count(struct smu_context *smu, uint32_t count)
 {
+	struct amdgpu_device *adev = smu->adev;
 	int ret = 0;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	if (smu->ppt_funcs->set_active_display_count)
 		ret = smu->ppt_funcs->set_active_display_count(smu, count);
 
@@ -2442,8 +2581,12 @@ int smu_get_clock_by_type(struct smu_context *smu,
 			  enum amd_pp_clock_type type,
 			  struct amd_pp_clocks *clocks)
 {
+	struct amdgpu_device *adev = smu->adev;
 	int ret = 0;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	mutex_lock(&smu->mutex);
 
 	if (smu->ppt_funcs->get_clock_by_type)
@@ -2457,8 +2600,12 @@ int smu_get_clock_by_type(struct smu_context *smu,
 int smu_get_max_high_clocks(struct smu_context *smu,
 			    struct amd_pp_simple_clock_info *clocks)
 {
+	struct amdgpu_device *adev = smu->adev;
 	int ret = 0;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	mutex_lock(&smu->mutex);
 
 	if (smu->ppt_funcs->get_max_high_clocks)
@@ -2473,8 +2620,12 @@ int smu_get_clock_by_type_with_latency(struct smu_context *smu,
 				       enum smu_clk_type clk_type,
 				       struct pp_clock_levels_with_latency *clocks)
 {
+	struct amdgpu_device *adev = smu->adev;
 	int ret = 0;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	mutex_lock(&smu->mutex);
 
 	if (smu->ppt_funcs->get_clock_by_type_with_latency)
@@ -2489,8 +2640,12 @@ int smu_get_clock_by_type_with_voltage(struct smu_context *smu,
 				       enum amd_pp_clock_type type,
 				       struct pp_clock_levels_with_voltage *clocks)
 {
+	struct amdgpu_device *adev = smu->adev;
 	int ret = 0;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	mutex_lock(&smu->mutex);
 
 	if (smu->ppt_funcs->get_clock_by_type_with_voltage)
@@ -2505,8 +2660,12 @@ int smu_get_clock_by_type_with_voltage(struct smu_context *smu,
 int smu_display_clock_voltage_request(struct smu_context *smu,
 				      struct pp_display_clock_request *clock_req)
 {
+	struct amdgpu_device *adev = smu->adev;
 	int ret = 0;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	mutex_lock(&smu->mutex);
 
 	if (smu->ppt_funcs->display_clock_voltage_request)
@@ -2520,8 +2679,12 @@ int smu_display_clock_voltage_request(struct smu_context *smu,
 
 int smu_display_disable_memory_clock_switch(struct smu_context *smu, bool disable_memory_clock_switch)
 {
+	struct amdgpu_device *adev = smu->adev;
 	int ret = -EINVAL;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	mutex_lock(&smu->mutex);
 
 	if (smu->ppt_funcs->display_disable_memory_clock_switch)
@@ -2534,8 +2697,12 @@ int smu_display_disable_memory_clock_switch(struct smu_context *smu, bool disabl
 
 int smu_notify_smu_enable_pwe(struct smu_context *smu)
 {
+	struct amdgpu_device *adev = smu->adev;
 	int ret = 0;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	mutex_lock(&smu->mutex);
 
 	if (smu->ppt_funcs->notify_smu_enable_pwe)
@@ -2549,8 +2716,12 @@ int smu_notify_smu_enable_pwe(struct smu_context *smu)
 int smu_set_xgmi_pstate(struct smu_context *smu,
 			uint32_t pstate)
 {
+	struct amdgpu_device *adev = smu->adev;
 	int ret = 0;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	mutex_lock(&smu->mutex);
 
 	if (smu->ppt_funcs->set_xgmi_pstate)
@@ -2563,8 +2734,12 @@ int smu_set_xgmi_pstate(struct smu_context *smu,
 
 int smu_set_azalia_d3_pme(struct smu_context *smu)
 {
+	struct amdgpu_device *adev = smu->adev;
 	int ret = 0;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	mutex_lock(&smu->mutex);
 
 	if (smu->ppt_funcs->set_azalia_d3_pme)
@@ -2575,6 +2750,14 @@ int smu_set_azalia_d3_pme(struct smu_context *smu)
 	return ret;
 }
 
+/*
+ * On system suspending or resetting, the dpm_enabled
+ * flag will be cleared. So that those SMU services which
+ * are not supported will be gated.
+ *
+ * However, the baco/mode1 reset should still be granted
+ * as they are still supported and necessary.
+ */
 bool smu_baco_is_support(struct smu_context *smu)
 {
 	bool ret = false;
@@ -2646,8 +2829,12 @@ int smu_mode2_reset(struct smu_context *smu)
 int smu_get_max_sustainable_clocks_by_dc(struct smu_context *smu,
 					 struct pp_smu_nv_clock_table *max_clocks)
 {
+	struct amdgpu_device *adev = smu->adev;
 	int ret = 0;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	mutex_lock(&smu->mutex);
 
 	if (smu->ppt_funcs->get_max_sustainable_clocks_by_dc)
@@ -2662,8 +2849,12 @@ int smu_get_uclk_dpm_states(struct smu_context *smu,
 			    unsigned int *clock_values_in_khz,
 			    unsigned int *num_states)
 {
+	struct amdgpu_device *adev = smu->adev;
 	int ret = 0;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	mutex_lock(&smu->mutex);
 
 	if (smu->ppt_funcs->get_uclk_dpm_states)
@@ -2677,6 +2868,10 @@ int smu_get_uclk_dpm_states(struct smu_context *smu,
 enum amd_pm_state_type smu_get_current_power_state(struct smu_context *smu)
 {
 	enum amd_pm_state_type pm_state = POWER_STATE_TYPE_DEFAULT;
+	struct amdgpu_device *adev = smu->adev;
+
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
 
 	mutex_lock(&smu->mutex);
 
@@ -2691,8 +2886,12 @@ enum amd_pm_state_type smu_get_current_power_state(struct smu_context *smu)
 int smu_get_dpm_clock_table(struct smu_context *smu,
 			    struct dpm_clocks *clock_table)
 {
+	struct amdgpu_device *adev = smu->adev;
 	int ret = 0;
 
+	if (!adev->pm.dpm_enabled)
+		return -EINVAL;
+
 	mutex_lock(&smu->mutex);
 
 	if (smu->ppt_funcs->get_dpm_clock_table)
diff --git a/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c b/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c
index 1ef0923f7190..1c66b7d7139c 100644
--- a/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c
@@ -2226,12 +2226,8 @@ static const struct i2c_algorithm arcturus_i2c_eeprom_i2c_algo = {
 static int arcturus_i2c_eeprom_control_init(struct i2c_adapter *control)
 {
 	struct amdgpu_device *adev = to_amdgpu_device(control);
-	struct smu_context *smu = &adev->smu;
 	int res;
 
-	if (!smu->pm_enabled)
-		return -EOPNOTSUPP;
-
 	control->owner = THIS_MODULE;
 	control->class = I2C_CLASS_SPD;
 	control->dev.parent = &adev->pdev->dev;
@@ -2247,12 +2243,6 @@ static int arcturus_i2c_eeprom_control_init(struct i2c_adapter *control)
 
 static void arcturus_i2c_eeprom_control_fini(struct i2c_adapter *control)
 {
-	struct amdgpu_device *adev = to_amdgpu_device(control);
-	struct smu_context *smu = &adev->smu;
-
-	if (!smu->pm_enabled)
-		return;
-
 	i2c_del_adapter(control);
 }
 
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c b/drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c
index 77c14671866c..719597c5d27d 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c
@@ -984,6 +984,32 @@ static int init_thermal_controller(
 			struct pp_hwmgr *hwmgr,
 			const ATOM_PPLIB_POWERPLAYTABLE *powerplay_table)
 {
+	hwmgr->thermal_controller.ucType =
+			powerplay_table->sThermalController.ucType;
+	hwmgr->thermal_controller.ucI2cLine =
+			powerplay_table->sThermalController.ucI2cLine;
+	hwmgr->thermal_controller.ucI2cAddress =
+			powerplay_table->sThermalController.ucI2cAddress;
+
+	hwmgr->thermal_controller.fanInfo.bNoFan =
+		(0 != (powerplay_table->sThermalController.ucFanParameters &
+			ATOM_PP_FANPARAMETERS_NOFAN));
+
+	hwmgr->thermal_controller.fanInfo.ucTachometerPulsesPerRevolution =
+		powerplay_table->sThermalController.ucFanParameters &
+		ATOM_PP_FANPARAMETERS_TACHOMETER_PULSES_PER_REVOLUTION_MASK;
+
+	hwmgr->thermal_controller.fanInfo.ulMinRPM
+		= powerplay_table->sThermalController.ucFanMinRPM * 100UL;
+	hwmgr->thermal_controller.fanInfo.ulMaxRPM
+		= powerplay_table->sThermalController.ucFanMaxRPM * 100UL;
+
+	set_hw_cap(hwmgr,
+		   ATOM_PP_THERMALCONTROLLER_NONE != hwmgr->thermal_controller.ucType,
+		   PHM_PlatformCaps_ThermalController);
+
+	hwmgr->thermal_controller.use_hw_fan_control = 1;
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c
index 689072a312a7..1cc30f750c26 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c
@@ -36,6 +36,8 @@
 #include "power_state.h"
 #include "soc15_common.h"
 #include "smu10.h"
+#include "asic_reg/pwr/pwr_10_0_offset.h"
+#include "asic_reg/pwr/pwr_10_0_sh_mask.h"
 
 #define SMU10_MAX_DEEPSLEEP_DIVIDER_ID     5
 #define SMU10_MINIMUM_ENGINE_CLOCK         800   /* 8Mhz, the low boundary of engine clock allowed on this chip */
@@ -43,13 +45,6 @@
 #define SMU10_DISPCLK_BYPASS_THRESHOLD     10000 /* 100Mhz */
 #define SMC_RAM_END                     0x40000
 
-#define mmPWR_MISC_CNTL_STATUS					0x0183
-#define mmPWR_MISC_CNTL_STATUS_BASE_IDX				0
-#define PWR_MISC_CNTL_STATUS__PWR_GFX_RLC_CGPG_EN__SHIFT	0x0
-#define PWR_MISC_CNTL_STATUS__PWR_GFXOFF_STATUS__SHIFT		0x1
-#define PWR_MISC_CNTL_STATUS__PWR_GFX_RLC_CGPG_EN_MASK		0x00000001L
-#define PWR_MISC_CNTL_STATUS__PWR_GFXOFF_STATUS_MASK		0x00000006L
-
 static const unsigned long SMU10_Magic = (unsigned long) PHM_Rv_Magic;
 
 
@@ -81,7 +76,7 @@ static int smu10_display_clock_voltage_request(struct pp_hwmgr *hwmgr,
 		pr_info("[DisplayClockVoltageRequest]Invalid Clock Type!");
 		return -EINVAL;
 	}
-	smum_send_msg_to_smc_with_parameter(hwmgr, msg, clk_freq);
+	smum_send_msg_to_smc_with_parameter(hwmgr, msg, clk_freq, NULL);
 
 	return 0;
 }
@@ -214,7 +209,8 @@ static int smu10_set_min_deep_sleep_dcefclk(struct pp_hwmgr *hwmgr, uint32_t clo
 		smu10_data->deep_sleep_dcefclk = clock;
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_SetMinDeepSleepDcefclk,
-					smu10_data->deep_sleep_dcefclk);
+					smu10_data->deep_sleep_dcefclk,
+					NULL);
 	}
 	return 0;
 }
@@ -228,7 +224,8 @@ static int smu10_set_hard_min_dcefclk_by_freq(struct pp_hwmgr *hwmgr, uint32_t c
 		smu10_data->dcf_actual_hard_min_freq = clock;
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_SetHardMinDcefclkByFreq,
-					smu10_data->dcf_actual_hard_min_freq);
+					smu10_data->dcf_actual_hard_min_freq,
+					NULL);
 	}
 	return 0;
 }
@@ -242,7 +239,8 @@ static int smu10_set_hard_min_fclk_by_freq(struct pp_hwmgr *hwmgr, uint32_t cloc
 		smu10_data->f_actual_hard_min_freq = clock;
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_SetHardMinFclkByFreq,
-					smu10_data->f_actual_hard_min_freq);
+					smu10_data->f_actual_hard_min_freq,
+					NULL);
 	}
 	return 0;
 }
@@ -255,7 +253,8 @@ static int smu10_set_active_display_count(struct pp_hwmgr *hwmgr, uint32_t count
 		smu10_data->num_active_display = count;
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_SetDisplayCount,
-				smu10_data->num_active_display);
+				smu10_data->num_active_display,
+				NULL);
 	}
 
 	return 0;
@@ -278,7 +277,8 @@ static int smu10_init_power_gate_state(struct pp_hwmgr *hwmgr)
 	if (adev->pg_flags & AMD_PG_SUPPORT_GFX_PG)
 		return smum_send_msg_to_smc_with_parameter(hwmgr,
 							   PPSMC_MSG_SetGfxCGPG,
-							   true);
+							   true,
+							   NULL);
 	else
 		return 0;
 }
@@ -324,7 +324,7 @@ static int smu10_disable_gfx_off(struct pp_hwmgr *hwmgr)
 	struct amdgpu_device *adev = hwmgr->adev;
 
 	if (adev->pm.pp_feature & PP_GFXOFF_MASK) {
-		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_DisableGfxOff);
+		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_DisableGfxOff, NULL);
 
 		/* confirm gfx is back to "on" state */
 		while (!smu10_is_gfx_on(hwmgr))
@@ -344,7 +344,7 @@ static int smu10_enable_gfx_off(struct pp_hwmgr *hwmgr)
 	struct amdgpu_device *adev = hwmgr->adev;
 
 	if (adev->pm.pp_feature & PP_GFXOFF_MASK)
-		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_EnableGfxOff);
+		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_EnableGfxOff, NULL);
 
 	return 0;
 }
@@ -479,12 +479,10 @@ static int smu10_populate_clock_table(struct pp_hwmgr *hwmgr)
 	smu10_get_clock_voltage_dependency_table(hwmgr, &pinfo->vdd_dep_on_phyclk,
 					ARRAY_SIZE(VddPhyClk), &VddPhyClk[0]);
 
-	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency);
-	result = smum_get_argument(hwmgr);
+	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency, &result);
 	smu10_data->gfx_min_freq_limit = result / 10 * 1000;
 
-	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxGfxclkFrequency);
-	result = smum_get_argument(hwmgr);
+	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxGfxclkFrequency, &result);
 	smu10_data->gfx_max_freq_limit = result / 10 * 1000;
 
 	return 0;
@@ -588,116 +586,148 @@ static int smu10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr,
 	case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK:
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetHardMinGfxClk,
-						data->gfx_max_freq_limit/100);
+						data->gfx_max_freq_limit/100,
+						NULL);
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetHardMinFclkByFreq,
-						SMU10_UMD_PSTATE_PEAK_FCLK);
+						SMU10_UMD_PSTATE_PEAK_FCLK,
+						NULL);
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetHardMinSocclkByFreq,
-						SMU10_UMD_PSTATE_PEAK_SOCCLK);
+						SMU10_UMD_PSTATE_PEAK_SOCCLK,
+						NULL);
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetHardMinVcn,
-						SMU10_UMD_PSTATE_VCE);
+						SMU10_UMD_PSTATE_VCE,
+						NULL);
 
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetSoftMaxGfxClk,
-						data->gfx_max_freq_limit/100);
+						data->gfx_max_freq_limit/100,
+						NULL);
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetSoftMaxFclkByFreq,
-						SMU10_UMD_PSTATE_PEAK_FCLK);
+						SMU10_UMD_PSTATE_PEAK_FCLK,
+						NULL);
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetSoftMaxSocclkByFreq,
-						SMU10_UMD_PSTATE_PEAK_SOCCLK);
+						SMU10_UMD_PSTATE_PEAK_SOCCLK,
+						NULL);
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetSoftMaxVcn,
-						SMU10_UMD_PSTATE_VCE);
+						SMU10_UMD_PSTATE_VCE,
+						NULL);
 		break;
 	case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK:
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetHardMinGfxClk,
-						min_sclk);
+						min_sclk,
+						NULL);
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetSoftMaxGfxClk,
-						min_sclk);
+						min_sclk,
+						NULL);
 		break;
 	case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK:
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetHardMinFclkByFreq,
-						min_mclk);
+						min_mclk,
+						NULL);
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetSoftMaxFclkByFreq,
-						min_mclk);
+						min_mclk,
+						NULL);
 		break;
 	case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD:
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetHardMinGfxClk,
-						SMU10_UMD_PSTATE_GFXCLK);
+						SMU10_UMD_PSTATE_GFXCLK,
+						NULL);
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetHardMinFclkByFreq,
-						SMU10_UMD_PSTATE_FCLK);
+						SMU10_UMD_PSTATE_FCLK,
+						NULL);
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetHardMinSocclkByFreq,
-						SMU10_UMD_PSTATE_SOCCLK);
+						SMU10_UMD_PSTATE_SOCCLK,
+						NULL);
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetHardMinVcn,
-						SMU10_UMD_PSTATE_VCE);
+						SMU10_UMD_PSTATE_VCE,
+						NULL);
 
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetSoftMaxGfxClk,
-						SMU10_UMD_PSTATE_GFXCLK);
+						SMU10_UMD_PSTATE_GFXCLK,
+						NULL);
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetSoftMaxFclkByFreq,
-						SMU10_UMD_PSTATE_FCLK);
+						SMU10_UMD_PSTATE_FCLK,
+						NULL);
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetSoftMaxSocclkByFreq,
-						SMU10_UMD_PSTATE_SOCCLK);
+						SMU10_UMD_PSTATE_SOCCLK,
+						NULL);
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetSoftMaxVcn,
-						SMU10_UMD_PSTATE_VCE);
+						SMU10_UMD_PSTATE_VCE,
+						NULL);
 		break;
 	case AMD_DPM_FORCED_LEVEL_AUTO:
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetHardMinGfxClk,
-						min_sclk);
+						min_sclk,
+						NULL);
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetHardMinFclkByFreq,
 						hwmgr->display_config->num_display > 3 ?
 						SMU10_UMD_PSTATE_PEAK_FCLK :
-						min_mclk);
+						min_mclk,
+						NULL);
 
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetHardMinSocclkByFreq,
-						SMU10_UMD_PSTATE_MIN_SOCCLK);
+						SMU10_UMD_PSTATE_MIN_SOCCLK,
+						NULL);
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetHardMinVcn,
-						SMU10_UMD_PSTATE_MIN_VCE);
+						SMU10_UMD_PSTATE_MIN_VCE,
+						NULL);
 
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetSoftMaxGfxClk,
-						data->gfx_max_freq_limit/100);
+						data->gfx_max_freq_limit/100,
+						NULL);
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetSoftMaxFclkByFreq,
-						SMU10_UMD_PSTATE_PEAK_FCLK);
+						SMU10_UMD_PSTATE_PEAK_FCLK,
+						NULL);
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetSoftMaxSocclkByFreq,
-						SMU10_UMD_PSTATE_PEAK_SOCCLK);
+						SMU10_UMD_PSTATE_PEAK_SOCCLK,
+						NULL);
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetSoftMaxVcn,
-						SMU10_UMD_PSTATE_VCE);
+						SMU10_UMD_PSTATE_VCE,
+						NULL);
 		break;
 	case AMD_DPM_FORCED_LEVEL_LOW:
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetHardMinGfxClk,
-						data->gfx_min_freq_limit/100);
+						data->gfx_min_freq_limit/100,
+						NULL);
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetSoftMaxGfxClk,
-						data->gfx_min_freq_limit/100);
+						data->gfx_min_freq_limit/100,
+						NULL);
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetHardMinFclkByFreq,
-						min_mclk);
+						min_mclk,
+						NULL);
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetSoftMaxFclkByFreq,
-						min_mclk);
+						min_mclk,
+						NULL);
 		break;
 	case AMD_DPM_FORCED_LEVEL_MANUAL:
 	case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT:
@@ -849,13 +879,15 @@ static int smu10_force_clock_level(struct pp_hwmgr *hwmgr,
 						PPSMC_MSG_SetHardMinGfxClk,
 						low == 2 ? data->gfx_max_freq_limit/100 :
 						low == 1 ? SMU10_UMD_PSTATE_GFXCLK :
-						data->gfx_min_freq_limit/100);
+						data->gfx_min_freq_limit/100,
+						NULL);
 
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetSoftMaxGfxClk,
 						high == 0 ? data->gfx_min_freq_limit/100 :
 						high == 1 ? SMU10_UMD_PSTATE_GFXCLK :
-						data->gfx_max_freq_limit/100);
+						data->gfx_max_freq_limit/100,
+						NULL);
 		break;
 
 	case PP_MCLK:
@@ -864,11 +896,13 @@ static int smu10_force_clock_level(struct pp_hwmgr *hwmgr,
 
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetHardMinFclkByFreq,
-						mclk_table->entries[low].clk/100);
+						mclk_table->entries[low].clk/100,
+						NULL);
 
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetSoftMaxFclkByFreq,
-						mclk_table->entries[high].clk/100);
+						mclk_table->entries[high].clk/100,
+						NULL);
 		break;
 
 	case PP_PCIE:
@@ -888,8 +922,7 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr,
 
 	switch (type) {
 	case PP_SCLK:
-		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetGfxclkFrequency);
-		now = smum_get_argument(hwmgr);
+		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetGfxclkFrequency, &now);
 
 	/* driver only know min/max gfx_clk, Add level 1 for all other gfx clks */
 		if (now == data->gfx_max_freq_limit/100)
@@ -910,8 +943,7 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr,
 					i == 2 ? "*" : "");
 		break;
 	case PP_MCLK:
-		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetFclkFrequency);
-		now = smum_get_argument(hwmgr);
+		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetFclkFrequency, &now);
 
 		for (i = 0; i < mclk_table->count; i++)
 			size += sprintf(buf + size, "%d: %uMhz %s\n",
@@ -1122,15 +1154,13 @@ static int smu10_read_sensor(struct pp_hwmgr *hwmgr, int idx,
 
 	switch (idx) {
 	case AMDGPU_PP_SENSOR_GFX_SCLK:
-		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetGfxclkFrequency);
-		sclk = smum_get_argument(hwmgr);
+		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetGfxclkFrequency, &sclk);
 			/* in units of 10KHZ */
 		*((uint32_t *)value) = sclk * 100;
 		*size = 4;
 		break;
 	case AMDGPU_PP_SENSOR_GFX_MCLK:
-		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetFclkFrequency);
-		mclk = smum_get_argument(hwmgr);
+		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetFclkFrequency, &mclk);
 			/* in units of 10KHZ */
 		*((uint32_t *)value) = mclk * 100;
 		*size = 4;
@@ -1166,20 +1196,20 @@ static int smu10_set_watermarks_for_clocks_ranges(struct pp_hwmgr *hwmgr,
 static int smu10_smus_notify_pwe(struct pp_hwmgr *hwmgr)
 {
 
-	return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_SetRccPfcPmeRestoreRegister);
+	return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_SetRccPfcPmeRestoreRegister, NULL);
 }
 
 static int smu10_powergate_mmhub(struct pp_hwmgr *hwmgr)
 {
-	return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_PowerGateMmHub);
+	return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_PowerGateMmHub, NULL);
 }
 
 static int smu10_powergate_sdma(struct pp_hwmgr *hwmgr, bool gate)
 {
 	if (gate)
-		return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_PowerDownSdma);
+		return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_PowerDownSdma, NULL);
 	else
-		return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_PowerUpSdma);
+		return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_PowerUpSdma, NULL);
 }
 
 static void smu10_powergate_vcn(struct pp_hwmgr *hwmgr, bool bgate)
@@ -1191,11 +1221,11 @@ static void smu10_powergate_vcn(struct pp_hwmgr *hwmgr, bool bgate)
 						AMD_IP_BLOCK_TYPE_VCN,
 						AMD_PG_STATE_GATE);
 		smum_send_msg_to_smc_with_parameter(hwmgr,
-					PPSMC_MSG_PowerDownVcn, 0);
+					PPSMC_MSG_PowerDownVcn, 0, NULL);
 		smu10_data->vcn_power_gated = true;
 	} else {
 		smum_send_msg_to_smc_with_parameter(hwmgr,
-						PPSMC_MSG_PowerUpVcn, 0);
+						PPSMC_MSG_PowerUpVcn, 0, NULL);
 		amdgpu_device_ip_set_powergating_state(hwmgr->adev,
 						AMD_IP_BLOCK_TYPE_VCN,
 						AMD_PG_STATE_UNGATE);
@@ -1304,7 +1334,8 @@ static int smu10_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, uin
 		hwmgr->gfxoff_state_changed_by_workload = true;
 	}
 	result = smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_ActiveProcessNotify,
-						1 << workload_type);
+						1 << workload_type,
+						NULL);
 	if (!result)
 		hwmgr->power_profile_mode = input[size];
 	if (workload_type && hwmgr->gfxoff_state_changed_by_workload) {
@@ -1319,7 +1350,8 @@ static int smu10_asic_reset(struct pp_hwmgr *hwmgr, enum SMU_ASIC_RESET_MODE mod
 {
 	return smum_send_msg_to_smc_with_parameter(hwmgr,
 						   PPSMC_MSG_DeviceDriverReset,
-						   mode);
+						   mode,
+						   NULL);
 }
 
 static const struct pp_hwmgr_func smu10_hwmgr_funcs = {
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_clockpowergating.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_clockpowergating.c
index 683b29a99366..f2bda3bcbbde 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_clockpowergating.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_clockpowergating.c
@@ -29,14 +29,16 @@ static int smu7_enable_disable_uvd_dpm(struct pp_hwmgr *hwmgr, bool enable)
 {
 	return smum_send_msg_to_smc(hwmgr, enable ?
 			PPSMC_MSG_UVDDPM_Enable :
-			PPSMC_MSG_UVDDPM_Disable);
+			PPSMC_MSG_UVDDPM_Disable,
+			NULL);
 }
 
 static int smu7_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable)
 {
 	return smum_send_msg_to_smc(hwmgr, enable ?
 			PPSMC_MSG_VCEDPM_Enable :
-			PPSMC_MSG_VCEDPM_Disable);
+			PPSMC_MSG_VCEDPM_Disable,
+			NULL);
 }
 
 static int smu7_update_uvd_dpm(struct pp_hwmgr *hwmgr, bool bgate)
@@ -57,7 +59,8 @@ int smu7_powerdown_uvd(struct pp_hwmgr *hwmgr)
 {
 	if (phm_cf_want_uvd_power_gating(hwmgr))
 		return smum_send_msg_to_smc(hwmgr,
-				PPSMC_MSG_UVDPowerOFF);
+				PPSMC_MSG_UVDPowerOFF,
+				NULL);
 	return 0;
 }
 
@@ -67,10 +70,10 @@ static int smu7_powerup_uvd(struct pp_hwmgr *hwmgr)
 		if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
 				  PHM_PlatformCaps_UVDDynamicPowerGating)) {
 			return smum_send_msg_to_smc_with_parameter(hwmgr,
-					PPSMC_MSG_UVDPowerON, 1);
+					PPSMC_MSG_UVDPowerON, 1, NULL);
 		} else {
 			return smum_send_msg_to_smc_with_parameter(hwmgr,
-					PPSMC_MSG_UVDPowerON, 0);
+					PPSMC_MSG_UVDPowerON, 0, NULL);
 		}
 	}
 
@@ -81,7 +84,8 @@ static int smu7_powerdown_vce(struct pp_hwmgr *hwmgr)
 {
 	if (phm_cf_want_vce_power_gating(hwmgr))
 		return smum_send_msg_to_smc(hwmgr,
-				PPSMC_MSG_VCEPowerOFF);
+				PPSMC_MSG_VCEPowerOFF,
+				NULL);
 	return 0;
 }
 
@@ -89,7 +93,8 @@ static int smu7_powerup_vce(struct pp_hwmgr *hwmgr)
 {
 	if (phm_cf_want_vce_power_gating(hwmgr))
 		return smum_send_msg_to_smc(hwmgr,
-				PPSMC_MSG_VCEPowerON);
+				PPSMC_MSG_VCEPowerON,
+				NULL);
 	return 0;
 }
 
@@ -181,7 +186,7 @@ int smu7_update_clock_gatings(struct pp_hwmgr *hwmgr,
 				value = CG_GFX_CGCG_MASK;
 
 				if (smum_send_msg_to_smc_with_parameter(
-						hwmgr, msg, value))
+						hwmgr, msg, value, NULL))
 					return -EINVAL;
 			}
 			if (PP_STATE_SUPPORT_LS & *msg_id) {
@@ -191,7 +196,7 @@ int smu7_update_clock_gatings(struct pp_hwmgr *hwmgr,
 				value = CG_GFX_CGLS_MASK;
 
 				if (smum_send_msg_to_smc_with_parameter(
-						hwmgr, msg, value))
+						hwmgr, msg, value, NULL))
 					return -EINVAL;
 			}
 			break;
@@ -204,7 +209,7 @@ int smu7_update_clock_gatings(struct pp_hwmgr *hwmgr,
 				value = CG_GFX_3DCG_MASK;
 
 				if (smum_send_msg_to_smc_with_parameter(
-						hwmgr, msg, value))
+						hwmgr, msg, value, NULL))
 					return -EINVAL;
 			}
 
@@ -215,7 +220,7 @@ int smu7_update_clock_gatings(struct pp_hwmgr *hwmgr,
 				value = CG_GFX_3DLS_MASK;
 
 				if (smum_send_msg_to_smc_with_parameter(
-						hwmgr, msg, value))
+						hwmgr, msg, value, NULL))
 					return -EINVAL;
 			}
 			break;
@@ -228,7 +233,7 @@ int smu7_update_clock_gatings(struct pp_hwmgr *hwmgr,
 				value = CG_GFX_RLC_LS_MASK;
 
 				if (smum_send_msg_to_smc_with_parameter(
-						hwmgr, msg, value))
+						hwmgr, msg, value, NULL))
 					return -EINVAL;
 			}
 			break;
@@ -241,7 +246,7 @@ int smu7_update_clock_gatings(struct pp_hwmgr *hwmgr,
 				value = CG_GFX_CP_LS_MASK;
 
 				if (smum_send_msg_to_smc_with_parameter(
-						hwmgr, msg, value))
+						hwmgr, msg, value, NULL))
 					return -EINVAL;
 			}
 			break;
@@ -255,7 +260,7 @@ int smu7_update_clock_gatings(struct pp_hwmgr *hwmgr,
 						CG_GFX_OTHERS_MGCG_MASK);
 
 				if (smum_send_msg_to_smc_with_parameter(
-						hwmgr, msg, value))
+						hwmgr, msg, value, NULL))
 					return -EINVAL;
 			}
 			break;
@@ -275,7 +280,7 @@ int smu7_update_clock_gatings(struct pp_hwmgr *hwmgr,
 				value = CG_SYS_BIF_MGCG_MASK;
 
 				if (smum_send_msg_to_smc_with_parameter(
-						hwmgr, msg, value))
+						hwmgr, msg, value, NULL))
 					return -EINVAL;
 			}
 			if  (PP_STATE_SUPPORT_LS & *msg_id) {
@@ -285,7 +290,7 @@ int smu7_update_clock_gatings(struct pp_hwmgr *hwmgr,
 				value = CG_SYS_BIF_MGLS_MASK;
 
 				if (smum_send_msg_to_smc_with_parameter(
-						hwmgr, msg, value))
+						hwmgr, msg, value, NULL))
 					return -EINVAL;
 			}
 			break;
@@ -298,7 +303,7 @@ int smu7_update_clock_gatings(struct pp_hwmgr *hwmgr,
 				value = CG_SYS_MC_MGCG_MASK;
 
 				if (smum_send_msg_to_smc_with_parameter(
-						hwmgr, msg, value))
+						hwmgr, msg, value, NULL))
 					return -EINVAL;
 			}
 
@@ -309,7 +314,7 @@ int smu7_update_clock_gatings(struct pp_hwmgr *hwmgr,
 				value = CG_SYS_MC_MGLS_MASK;
 
 				if (smum_send_msg_to_smc_with_parameter(
-						hwmgr, msg, value))
+						hwmgr, msg, value, NULL))
 					return -EINVAL;
 			}
 			break;
@@ -322,7 +327,7 @@ int smu7_update_clock_gatings(struct pp_hwmgr *hwmgr,
 				value = CG_SYS_DRM_MGCG_MASK;
 
 				if (smum_send_msg_to_smc_with_parameter(
-						hwmgr, msg, value))
+						hwmgr, msg, value, NULL))
 					return -EINVAL;
 			}
 			if (PP_STATE_SUPPORT_LS & *msg_id) {
@@ -332,7 +337,7 @@ int smu7_update_clock_gatings(struct pp_hwmgr *hwmgr,
 				value = CG_SYS_DRM_MGLS_MASK;
 
 				if (smum_send_msg_to_smc_with_parameter(
-						hwmgr, msg, value))
+						hwmgr, msg, value, NULL))
 					return -EINVAL;
 			}
 			break;
@@ -345,7 +350,7 @@ int smu7_update_clock_gatings(struct pp_hwmgr *hwmgr,
 				value = CG_SYS_HDP_MGCG_MASK;
 
 				if (smum_send_msg_to_smc_with_parameter(
-						hwmgr, msg, value))
+						hwmgr, msg, value, NULL))
 					return -EINVAL;
 			}
 
@@ -356,7 +361,7 @@ int smu7_update_clock_gatings(struct pp_hwmgr *hwmgr,
 				value = CG_SYS_HDP_MGLS_MASK;
 
 				if (smum_send_msg_to_smc_with_parameter(
-						hwmgr, msg, value))
+						hwmgr, msg, value, NULL))
 					return -EINVAL;
 			}
 			break;
@@ -369,7 +374,7 @@ int smu7_update_clock_gatings(struct pp_hwmgr *hwmgr,
 				value = CG_SYS_SDMA_MGCG_MASK;
 
 				if (smum_send_msg_to_smc_with_parameter(
-						hwmgr, msg, value))
+						hwmgr, msg, value, NULL))
 					return -EINVAL;
 			}
 
@@ -380,7 +385,7 @@ int smu7_update_clock_gatings(struct pp_hwmgr *hwmgr,
 				value = CG_SYS_SDMA_MGLS_MASK;
 
 				if (smum_send_msg_to_smc_with_parameter(
-						hwmgr, msg, value))
+						hwmgr, msg, value, NULL))
 					return -EINVAL;
 			}
 			break;
@@ -393,7 +398,7 @@ int smu7_update_clock_gatings(struct pp_hwmgr *hwmgr,
 				value = CG_SYS_ROM_MASK;
 
 				if (smum_send_msg_to_smc_with_parameter(
-						hwmgr, msg, value))
+						hwmgr, msg, value, NULL))
 					return -EINVAL;
 			}
 			break;
@@ -423,8 +428,10 @@ int smu7_powergate_gfx(struct pp_hwmgr *hwmgr, bool enable)
 	if (enable)
 		return smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_GFX_CU_PG_ENABLE,
-					adev->gfx.cu_info.number);
+					adev->gfx.cu_info.number,
+					NULL);
 	else
 		return smum_send_msg_to_smc(hwmgr,
-				PPSMC_MSG_GFX_CU_PG_DISABLE);
+				PPSMC_MSG_GFX_CU_PG_DISABLE,
+				NULL);
 }
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
index 7740488999df..753cb2cf6b77 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
@@ -186,7 +186,7 @@ static int smu7_enable_smc_voltage_controller(struct pp_hwmgr *hwmgr)
 	}
 
 	if (hwmgr->feature_mask & PP_SMC_VOLTAGE_CONTROL_MASK)
-		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_Voltage_Cntl_Enable);
+		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_Voltage_Cntl_Enable, NULL);
 
 	return 0;
 }
@@ -493,7 +493,7 @@ static int smu7_copy_and_switch_arb_sets(struct pp_hwmgr *hwmgr,
 
 static int smu7_reset_to_default(struct pp_hwmgr *hwmgr)
 {
-	return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ResetToDefaults);
+	return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ResetToDefaults, NULL);
 }
 
 /**
@@ -979,7 +979,8 @@ static int smu7_enable_vrhot_gpio_interrupt(struct pp_hwmgr *hwmgr)
 	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
 			PHM_PlatformCaps_RegulatorHot))
 		return smum_send_msg_to_smc(hwmgr,
-				PPSMC_MSG_EnableVRHotGPIOInterrupt);
+				PPSMC_MSG_EnableVRHotGPIOInterrupt,
+				NULL);
 
 	return 0;
 }
@@ -996,7 +997,7 @@ static int smu7_enable_ulv(struct pp_hwmgr *hwmgr)
 	struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
 
 	if (data->ulv_supported)
-		return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_EnableULV);
+		return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_EnableULV, NULL);
 
 	return 0;
 }
@@ -1006,7 +1007,7 @@ static int smu7_disable_ulv(struct pp_hwmgr *hwmgr)
 	struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
 
 	if (data->ulv_supported)
-		return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_DisableULV);
+		return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_DisableULV, NULL);
 
 	return 0;
 }
@@ -1015,13 +1016,14 @@ static int smu7_enable_deep_sleep_master_switch(struct pp_hwmgr *hwmgr)
 {
 	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
 			PHM_PlatformCaps_SclkDeepSleep)) {
-		if (smum_send_msg_to_smc(hwmgr, PPSMC_MSG_MASTER_DeepSleep_ON))
+		if (smum_send_msg_to_smc(hwmgr, PPSMC_MSG_MASTER_DeepSleep_ON, NULL))
 			PP_ASSERT_WITH_CODE(false,
 					"Attempt to enable Master Deep Sleep switch failed!",
 					return -EINVAL);
 	} else {
 		if (smum_send_msg_to_smc(hwmgr,
-				PPSMC_MSG_MASTER_DeepSleep_OFF)) {
+				PPSMC_MSG_MASTER_DeepSleep_OFF,
+				NULL)) {
 			PP_ASSERT_WITH_CODE(false,
 					"Attempt to disable Master Deep Sleep switch failed!",
 					return -EINVAL);
@@ -1036,7 +1038,8 @@ static int smu7_disable_deep_sleep_master_switch(struct pp_hwmgr *hwmgr)
 	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
 			PHM_PlatformCaps_SclkDeepSleep)) {
 		if (smum_send_msg_to_smc(hwmgr,
-				PPSMC_MSG_MASTER_DeepSleep_OFF)) {
+				PPSMC_MSG_MASTER_DeepSleep_OFF,
+				NULL)) {
 			PP_ASSERT_WITH_CODE(false,
 					"Attempt to disable Master Deep Sleep switch failed!",
 					return -EINVAL);
@@ -1089,7 +1092,7 @@ static int smu7_enable_sclk_mclk_dpm(struct pp_hwmgr *hwmgr)
 			smu7_disable_sclk_vce_handshake(hwmgr);
 
 		PP_ASSERT_WITH_CODE(
-		(0 == smum_send_msg_to_smc(hwmgr, PPSMC_MSG_DPM_Enable)),
+		(0 == smum_send_msg_to_smc(hwmgr, PPSMC_MSG_DPM_Enable, NULL)),
 		"Failed to enable SCLK DPM during DPM Start Function!",
 		return -EINVAL);
 	}
@@ -1101,7 +1104,8 @@ static int smu7_enable_sclk_mclk_dpm(struct pp_hwmgr *hwmgr)
 
 		PP_ASSERT_WITH_CODE(
 				(0 == smum_send_msg_to_smc(hwmgr,
-						PPSMC_MSG_MCLKDPM_Enable)),
+						PPSMC_MSG_MCLKDPM_Enable,
+						NULL)),
 				"Failed to enable MCLK DPM during DPM Start Function!",
 				return -EINVAL);
 
@@ -1172,7 +1176,8 @@ static int smu7_start_dpm(struct pp_hwmgr *hwmgr)
 	if (0 == data->pcie_dpm_key_disabled) {
 		PP_ASSERT_WITH_CODE(
 				(0 == smum_send_msg_to_smc(hwmgr,
-						PPSMC_MSG_PCIeDPM_Enable)),
+						PPSMC_MSG_PCIeDPM_Enable,
+						NULL)),
 				"Failed to enable pcie DPM during DPM Start Function!",
 				return -EINVAL);
 	}
@@ -1180,7 +1185,8 @@ static int smu7_start_dpm(struct pp_hwmgr *hwmgr)
 	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
 				PHM_PlatformCaps_Falcon_QuickTransition)) {
 		PP_ASSERT_WITH_CODE((0 == smum_send_msg_to_smc(hwmgr,
-				PPSMC_MSG_EnableACDCGPIOInterrupt)),
+				PPSMC_MSG_EnableACDCGPIOInterrupt,
+				NULL)),
 				"Failed to enable AC DC GPIO Interrupt!",
 				);
 	}
@@ -1197,7 +1203,7 @@ static int smu7_disable_sclk_mclk_dpm(struct pp_hwmgr *hwmgr)
 		PP_ASSERT_WITH_CODE(true == smum_is_dpm_running(hwmgr),
 				"Trying to disable SCLK DPM when DPM is disabled",
 				return 0);
-		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_DPM_Disable);
+		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_DPM_Disable, NULL);
 	}
 
 	/* disable MCLK dpm */
@@ -1205,7 +1211,7 @@ static int smu7_disable_sclk_mclk_dpm(struct pp_hwmgr *hwmgr)
 		PP_ASSERT_WITH_CODE(true == smum_is_dpm_running(hwmgr),
 				"Trying to disable MCLK DPM when DPM is disabled",
 				return 0);
-		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_MCLKDPM_Disable);
+		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_MCLKDPM_Disable, NULL);
 	}
 
 	return 0;
@@ -1226,7 +1232,8 @@ static int smu7_stop_dpm(struct pp_hwmgr *hwmgr)
 	if (!data->pcie_dpm_key_disabled) {
 		PP_ASSERT_WITH_CODE(
 				(smum_send_msg_to_smc(hwmgr,
-						PPSMC_MSG_PCIeDPM_Disable) == 0),
+						PPSMC_MSG_PCIeDPM_Disable,
+						NULL) == 0),
 				"Failed to disable pcie DPM during DPM Stop Function!",
 				return -EINVAL);
 	}
@@ -1237,7 +1244,7 @@ static int smu7_stop_dpm(struct pp_hwmgr *hwmgr)
 			"Trying to disable voltage DPM when DPM is disabled",
 			return 0);
 
-	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_Voltage_Cntl_Disable);
+	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_Voltage_Cntl_Disable, NULL);
 
 	return 0;
 }
@@ -1388,7 +1395,7 @@ static int smu7_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
 	PP_ASSERT_WITH_CODE((0 == tmp_result),
 			"Failed to enable VR hot GPIO interrupt!", result = tmp_result);
 
-	smum_send_msg_to_smc(hwmgr, (PPSMC_Msg)PPSMC_NoDisplay);
+	smum_send_msg_to_smc(hwmgr, (PPSMC_Msg)PPSMC_NoDisplay, NULL);
 
 	tmp_result = smu7_enable_sclk_control(hwmgr);
 	PP_ASSERT_WITH_CODE((0 == tmp_result),
@@ -1446,14 +1453,14 @@ static int smu7_avfs_control(struct pp_hwmgr *hwmgr, bool enable)
 		if (!PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device,
 				CGS_IND_REG__SMC, FEATURE_STATUS, AVS_ON)) {
 			PP_ASSERT_WITH_CODE(!smum_send_msg_to_smc(
-					hwmgr, PPSMC_MSG_EnableAvfs),
+					hwmgr, PPSMC_MSG_EnableAvfs, NULL),
 					"Failed to enable AVFS!",
 					return -EINVAL);
 		}
 	} else if (PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device,
 			CGS_IND_REG__SMC, FEATURE_STATUS, AVS_ON)) {
 		PP_ASSERT_WITH_CODE(!smum_send_msg_to_smc(
-				hwmgr, PPSMC_MSG_DisableAvfs),
+				hwmgr, PPSMC_MSG_DisableAvfs, NULL),
 				"Failed to disable AVFS!",
 				return -EINVAL);
 	}
@@ -2609,7 +2616,8 @@ static int smu7_force_dpm_highest(struct pp_hwmgr *hwmgr)
 
 			if (level)
 				smum_send_msg_to_smc_with_parameter(hwmgr,
-						PPSMC_MSG_PCIeDPM_ForceLevel, level);
+						PPSMC_MSG_PCIeDPM_ForceLevel, level,
+						NULL);
 		}
 	}
 
@@ -2623,7 +2631,8 @@ static int smu7_force_dpm_highest(struct pp_hwmgr *hwmgr)
 			if (level)
 				smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SCLKDPM_SetEnabledMask,
-						(1 << level));
+						(1 << level),
+						NULL);
 		}
 	}
 
@@ -2637,7 +2646,8 @@ static int smu7_force_dpm_highest(struct pp_hwmgr *hwmgr)
 			if (level)
 				smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_MCLKDPM_SetEnabledMask,
-						(1 << level));
+						(1 << level),
+						NULL);
 		}
 	}
 
@@ -2656,14 +2666,16 @@ static int smu7_upload_dpm_level_enable_mask(struct pp_hwmgr *hwmgr)
 		if (data->dpm_level_enable_mask.sclk_dpm_enable_mask)
 			smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_SCLKDPM_SetEnabledMask,
-					data->dpm_level_enable_mask.sclk_dpm_enable_mask);
+					data->dpm_level_enable_mask.sclk_dpm_enable_mask,
+					NULL);
 	}
 
 	if (!data->mclk_dpm_key_disabled) {
 		if (data->dpm_level_enable_mask.mclk_dpm_enable_mask)
 			smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_MCLKDPM_SetEnabledMask,
-					data->dpm_level_enable_mask.mclk_dpm_enable_mask);
+					data->dpm_level_enable_mask.mclk_dpm_enable_mask,
+					NULL);
 	}
 
 	return 0;
@@ -2678,7 +2690,8 @@ static int smu7_unforce_dpm_levels(struct pp_hwmgr *hwmgr)
 
 	if (!data->pcie_dpm_key_disabled) {
 		smum_send_msg_to_smc(hwmgr,
-				PPSMC_MSG_PCIeDPM_UnForceLevel);
+				PPSMC_MSG_PCIeDPM_UnForceLevel,
+				NULL);
 	}
 
 	return smu7_upload_dpm_level_enable_mask(hwmgr);
@@ -2696,7 +2709,8 @@ static int smu7_force_dpm_lowest(struct pp_hwmgr *hwmgr)
 							      data->dpm_level_enable_mask.sclk_dpm_enable_mask);
 			smum_send_msg_to_smc_with_parameter(hwmgr,
 							    PPSMC_MSG_SCLKDPM_SetEnabledMask,
-							    (1 << level));
+							    (1 << level),
+							    NULL);
 
 	}
 
@@ -2706,7 +2720,8 @@ static int smu7_force_dpm_lowest(struct pp_hwmgr *hwmgr)
 							      data->dpm_level_enable_mask.mclk_dpm_enable_mask);
 			smum_send_msg_to_smc_with_parameter(hwmgr,
 							    PPSMC_MSG_MCLKDPM_SetEnabledMask,
-							    (1 << level));
+							    (1 << level),
+							    NULL);
 		}
 	}
 
@@ -2716,7 +2731,8 @@ static int smu7_force_dpm_lowest(struct pp_hwmgr *hwmgr)
 							      data->dpm_level_enable_mask.pcie_dpm_enable_mask);
 			smum_send_msg_to_smc_with_parameter(hwmgr,
 							    PPSMC_MSG_PCIeDPM_ForceLevel,
-							    (level));
+							    (level),
+							    NULL);
 		}
 	}
 
@@ -3495,21 +3511,20 @@ static int smu7_get_gpu_power(struct pp_hwmgr *hwmgr, u32 *query)
 	    (adev->asic_type != CHIP_BONAIRE) &&
 	    (adev->asic_type != CHIP_FIJI) &&
 	    (adev->asic_type != CHIP_TONGA)) {
-		smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetCurrPkgPwr, 0);
-		tmp = cgs_read_register(hwmgr->device, mmSMC_MSG_ARG_0);
+		smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetCurrPkgPwr, 0, &tmp);
 		*query = tmp;
 
 		if (tmp != 0)
 			return 0;
 	}
 
-	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_PmStatusLogStart);
+	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_PmStatusLogStart, NULL);
 	cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
 							ixSMU_PM_STATUS_95, 0);
 
 	for (i = 0; i < 10; i++) {
 		msleep(500);
-		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_PmStatusLogSample);
+		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_PmStatusLogSample, NULL);
 		tmp = cgs_read_ind_register(hwmgr->device,
 						CGS_IND_REG__SMC,
 						ixSMU_PM_STATUS_95);
@@ -3534,14 +3549,12 @@ static int smu7_read_sensor(struct pp_hwmgr *hwmgr, int idx,
 
 	switch (idx) {
 	case AMDGPU_PP_SENSOR_GFX_SCLK:
-		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_API_GetSclkFrequency);
-		sclk = cgs_read_register(hwmgr->device, mmSMC_MSG_ARG_0);
+		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_API_GetSclkFrequency, &sclk);
 		*((uint32_t *)value) = sclk;
 		*size = 4;
 		return 0;
 	case AMDGPU_PP_SENSOR_GFX_MCLK:
-		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_API_GetMclkFrequency);
-		mclk = cgs_read_register(hwmgr->device, mmSMC_MSG_ARG_0);
+		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_API_GetMclkFrequency, &mclk);
 		*((uint32_t *)value) = mclk;
 		*size = 4;
 		return 0;
@@ -3730,7 +3743,8 @@ static int smu7_freeze_sclk_mclk_dpm(struct pp_hwmgr *hwmgr)
 				"Trying to freeze SCLK DPM when DPM is disabled",
 				);
 		PP_ASSERT_WITH_CODE(0 == smum_send_msg_to_smc(hwmgr,
-				PPSMC_MSG_SCLKDPM_FreezeLevel),
+				PPSMC_MSG_SCLKDPM_FreezeLevel,
+				NULL),
 				"Failed to freeze SCLK DPM during FreezeSclkMclkDPM Function!",
 				return -EINVAL);
 	}
@@ -3742,7 +3756,8 @@ static int smu7_freeze_sclk_mclk_dpm(struct pp_hwmgr *hwmgr)
 				"Trying to freeze MCLK DPM when DPM is disabled",
 				);
 		PP_ASSERT_WITH_CODE(0 == smum_send_msg_to_smc(hwmgr,
-				PPSMC_MSG_MCLKDPM_FreezeLevel),
+				PPSMC_MSG_MCLKDPM_FreezeLevel,
+				NULL),
 				"Failed to freeze MCLK DPM during FreezeSclkMclkDPM Function!",
 				return -EINVAL);
 	}
@@ -3804,9 +3819,12 @@ static int smu7_trim_single_dpm_states(struct pp_hwmgr *hwmgr,
 {
 	uint32_t i;
 
+	/* force the trim if mclk_switching is disabled to prevent flicker */
+	bool force_trim = (low_limit == high_limit);
 	for (i = 0; i < dpm_table->count; i++) {
 	/*skip the trim if od is enabled*/
-		if (!hwmgr->od_enabled && (dpm_table->dpm_levels[i].value < low_limit
+		if ((!hwmgr->od_enabled || force_trim)
+			&& (dpm_table->dpm_levels[i].value < low_limit
 			|| dpm_table->dpm_levels[i].value > high_limit))
 			dpm_table->dpm_levels[i].enabled = false;
 		else
@@ -3881,7 +3899,8 @@ static int smu7_unfreeze_sclk_mclk_dpm(struct pp_hwmgr *hwmgr)
 				"Trying to Unfreeze SCLK DPM when DPM is disabled",
 				);
 		PP_ASSERT_WITH_CODE(0 == smum_send_msg_to_smc(hwmgr,
-				PPSMC_MSG_SCLKDPM_UnfreezeLevel),
+				PPSMC_MSG_SCLKDPM_UnfreezeLevel,
+				NULL),
 			"Failed to unfreeze SCLK DPM during UnFreezeSclkMclkDPM Function!",
 			return -EINVAL);
 	}
@@ -3893,7 +3912,8 @@ static int smu7_unfreeze_sclk_mclk_dpm(struct pp_hwmgr *hwmgr)
 				"Trying to Unfreeze MCLK DPM when DPM is disabled",
 				);
 		PP_ASSERT_WITH_CODE(0 == smum_send_msg_to_smc(hwmgr,
-				PPSMC_MSG_MCLKDPM_UnfreezeLevel),
+				PPSMC_MSG_MCLKDPM_UnfreezeLevel,
+				NULL),
 		    "Failed to unfreeze MCLK DPM during UnFreezeSclkMclkDPM Function!",
 		    return -EINVAL);
 	}
@@ -3946,12 +3966,14 @@ static int smu7_notify_smc_display(struct pp_hwmgr *hwmgr)
 	if (hwmgr->feature_mask & PP_VBI_TIME_SUPPORT_MASK) {
 		if (hwmgr->chip_id == CHIP_VEGAM)
 			smum_send_msg_to_smc_with_parameter(hwmgr,
-					(PPSMC_Msg)PPSMC_MSG_SetVBITimeout_VEGAM, data->frame_time_x2);
+					(PPSMC_Msg)PPSMC_MSG_SetVBITimeout_VEGAM, data->frame_time_x2,
+					NULL);
 		else
 			smum_send_msg_to_smc_with_parameter(hwmgr,
-					(PPSMC_Msg)PPSMC_MSG_SetVBITimeout, data->frame_time_x2);
+					(PPSMC_Msg)PPSMC_MSG_SetVBITimeout, data->frame_time_x2,
+					NULL);
 	}
-	return (smum_send_msg_to_smc(hwmgr, (PPSMC_Msg)PPSMC_HasDisplay) == 0) ?  0 : -EINVAL;
+	return (smum_send_msg_to_smc(hwmgr, (PPSMC_Msg)PPSMC_HasDisplay, NULL) == 0) ?  0 : -EINVAL;
 }
 
 static int smu7_set_power_state_tasks(struct pp_hwmgr *hwmgr, const void *input)
@@ -4037,7 +4059,8 @@ static int smu7_set_max_fan_pwm_output(struct pp_hwmgr *hwmgr, uint16_t us_max_f
 	advanceFanControlParameters.usMaxFanPWM = us_max_fan_pwm;
 
 	return smum_send_msg_to_smc_with_parameter(hwmgr,
-			PPSMC_MSG_SetFanPwmMax, us_max_fan_pwm);
+			PPSMC_MSG_SetFanPwmMax, us_max_fan_pwm,
+			NULL);
 }
 
 static int
@@ -4045,7 +4068,7 @@ smu7_notify_smc_display_change(struct pp_hwmgr *hwmgr, bool has_display)
 {
 	PPSMC_Msg msg = has_display ? (PPSMC_Msg)PPSMC_HasDisplay : (PPSMC_Msg)PPSMC_NoDisplay;
 
-	return (smum_send_msg_to_smc(hwmgr, msg) == 0) ?  0 : -1;
+	return (smum_send_msg_to_smc(hwmgr, msg, NULL) == 0) ?  0 : -1;
 }
 
 static int
@@ -4129,7 +4152,8 @@ static int smu7_set_max_fan_rpm_output(struct pp_hwmgr *hwmgr, uint16_t us_max_f
 	advanceFanControlParameters.usMaxFanRPM = us_max_fan_rpm;
 
 	return smum_send_msg_to_smc_with_parameter(hwmgr,
-			PPSMC_MSG_SetFanRpmMax, us_max_fan_rpm);
+			PPSMC_MSG_SetFanRpmMax, us_max_fan_rpm,
+			NULL);
 }
 
 static const struct amdgpu_irq_src_funcs smu7_irq_funcs = {
@@ -4259,14 +4283,14 @@ static int smu7_check_mc_firmware(struct pp_hwmgr *hwmgr)
 		if ((hwmgr->chip_id == CHIP_POLARIS10) ||
 		    (hwmgr->chip_id == CHIP_POLARIS11) ||
 		    (hwmgr->chip_id == CHIP_POLARIS12))
-			smum_send_msg_to_smc(hwmgr, PPSMC_MSG_EnableFFC);
+			smum_send_msg_to_smc(hwmgr, PPSMC_MSG_EnableFFC, NULL);
 	} else {
 		data->mem_latency_high = 330;
 		data->mem_latency_low = 330;
 		if ((hwmgr->chip_id == CHIP_POLARIS10) ||
 		    (hwmgr->chip_id == CHIP_POLARIS11) ||
 		    (hwmgr->chip_id == CHIP_POLARIS12))
-			smum_send_msg_to_smc(hwmgr, PPSMC_MSG_DisableFFC);
+			smum_send_msg_to_smc(hwmgr, PPSMC_MSG_DisableFFC, NULL);
 	}
 
 	return 0;
@@ -4410,13 +4434,15 @@ static int smu7_force_clock_level(struct pp_hwmgr *hwmgr,
 		if (!data->sclk_dpm_key_disabled)
 			smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_SCLKDPM_SetEnabledMask,
-					data->dpm_level_enable_mask.sclk_dpm_enable_mask & mask);
+					data->dpm_level_enable_mask.sclk_dpm_enable_mask & mask,
+					NULL);
 		break;
 	case PP_MCLK:
 		if (!data->mclk_dpm_key_disabled)
 			smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_MCLKDPM_SetEnabledMask,
-					data->dpm_level_enable_mask.mclk_dpm_enable_mask & mask);
+					data->dpm_level_enable_mask.mclk_dpm_enable_mask & mask,
+					NULL);
 		break;
 	case PP_PCIE:
 	{
@@ -4424,11 +4450,13 @@ static int smu7_force_clock_level(struct pp_hwmgr *hwmgr,
 
 		if (!data->pcie_dpm_key_disabled) {
 			if (fls(tmp) != ffs(tmp))
-				smum_send_msg_to_smc(hwmgr, PPSMC_MSG_PCIeDPM_UnForceLevel);
+				smum_send_msg_to_smc(hwmgr, PPSMC_MSG_PCIeDPM_UnForceLevel,
+						NULL);
 			else
 				smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_PCIeDPM_ForceLevel,
-					fls(tmp) - 1);
+					fls(tmp) - 1,
+					NULL);
 		}
 		break;
 	}
@@ -4454,8 +4482,7 @@ static int smu7_print_clock_levels(struct pp_hwmgr *hwmgr,
 
 	switch (type) {
 	case PP_SCLK:
-		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_API_GetSclkFrequency);
-		clock = cgs_read_register(hwmgr->device, mmSMC_MSG_ARG_0);
+		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_API_GetSclkFrequency, &clock);
 
 		for (i = 0; i < sclk_table->count; i++) {
 			if (clock > sclk_table->dpm_levels[i].value)
@@ -4470,8 +4497,7 @@ static int smu7_print_clock_levels(struct pp_hwmgr *hwmgr,
 					(i == now) ? "*" : "");
 		break;
 	case PP_MCLK:
-		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_API_GetMclkFrequency);
-		clock = cgs_read_register(hwmgr->device, mmSMC_MSG_ARG_0);
+		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_API_GetMclkFrequency, &clock);
 
 		for (i = 0; i < mclk_table->count; i++) {
 			if (clock > mclk_table->dpm_levels[i].value)
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c
index 58f5589aaf12..5d4971576111 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c
@@ -887,7 +887,10 @@ static int smu7_enable_didt(struct pp_hwmgr *hwmgr, const bool enable)
 	didt_block |= block_en << TCP_Enable_SHIFT;
 
 	if (enable)
-		result = smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_Didt_Block_Function, didt_block);
+		result = smum_send_msg_to_smc_with_parameter(hwmgr,
+						PPSMC_MSG_Didt_Block_Function,
+						didt_block,
+						NULL);
 
 	return result;
 }
@@ -1009,7 +1012,8 @@ int smu7_enable_didt_config(struct pp_hwmgr *hwmgr)
 
 		if (hwmgr->chip_id == CHIP_POLARIS11) {
 			result = smum_send_msg_to_smc(hwmgr,
-						(uint16_t)(PPSMC_MSG_EnableDpmDidt));
+						(uint16_t)(PPSMC_MSG_EnableDpmDidt),
+						NULL);
 			PP_ASSERT_WITH_CODE((0 == result),
 					"Failed to enable DPM DIDT.", goto error);
 		}
@@ -1042,7 +1046,8 @@ int smu7_disable_didt_config(struct pp_hwmgr *hwmgr)
 				goto error);
 		if (hwmgr->chip_id == CHIP_POLARIS11) {
 			result = smum_send_msg_to_smc(hwmgr,
-						(uint16_t)(PPSMC_MSG_DisableDpmDidt));
+						(uint16_t)(PPSMC_MSG_DisableDpmDidt),
+						NULL);
 			PP_ASSERT_WITH_CODE((0 == result),
 					"Failed to disable DPM DIDT.", goto error);
 		}
@@ -1063,7 +1068,8 @@ int smu7_enable_smc_cac(struct pp_hwmgr *hwmgr)
 	if (PP_CAP(PHM_PlatformCaps_CAC)) {
 		int smc_result;
 		smc_result = smum_send_msg_to_smc(hwmgr,
-				(uint16_t)(PPSMC_MSG_EnableCac));
+				(uint16_t)(PPSMC_MSG_EnableCac),
+				NULL);
 		PP_ASSERT_WITH_CODE((0 == smc_result),
 				"Failed to enable CAC in SMC.", result = -1);
 
@@ -1079,7 +1085,8 @@ int smu7_disable_smc_cac(struct pp_hwmgr *hwmgr)
 
 	if (PP_CAP(PHM_PlatformCaps_CAC) && data->cac_enabled) {
 		int smc_result = smum_send_msg_to_smc(hwmgr,
-				(uint16_t)(PPSMC_MSG_DisableCac));
+				(uint16_t)(PPSMC_MSG_DisableCac),
+				NULL);
 		PP_ASSERT_WITH_CODE((smc_result == 0),
 				"Failed to disable CAC in SMC.", result = -1);
 
@@ -1095,7 +1102,9 @@ int smu7_set_power_limit(struct pp_hwmgr *hwmgr, uint32_t n)
 	if (data->power_containment_features &
 			POWERCONTAINMENT_FEATURE_PkgPwrLimit)
 		return smum_send_msg_to_smc_with_parameter(hwmgr,
-				PPSMC_MSG_PkgPwrSetLimit, n<<8);
+				PPSMC_MSG_PkgPwrSetLimit,
+				n<<8,
+				NULL);
 	return 0;
 }
 
@@ -1103,7 +1112,9 @@ static int smu7_set_overdriver_target_tdp(struct pp_hwmgr *hwmgr,
 						uint32_t target_tdp)
 {
 	return smum_send_msg_to_smc_with_parameter(hwmgr,
-			PPSMC_MSG_OverDriveSetTargetTdp, target_tdp);
+			PPSMC_MSG_OverDriveSetTargetTdp,
+			target_tdp,
+			NULL);
 }
 
 int smu7_enable_power_containment(struct pp_hwmgr *hwmgr)
@@ -1124,7 +1135,8 @@ int smu7_enable_power_containment(struct pp_hwmgr *hwmgr)
 	if (PP_CAP(PHM_PlatformCaps_PowerContainment)) {
 		if (data->enable_tdc_limit_feature) {
 			smc_result = smum_send_msg_to_smc(hwmgr,
-					(uint16_t)(PPSMC_MSG_TDCLimitEnable));
+					(uint16_t)(PPSMC_MSG_TDCLimitEnable),
+					NULL);
 			PP_ASSERT_WITH_CODE((0 == smc_result),
 					"Failed to enable TDCLimit in SMC.", result = -1;);
 			if (0 == smc_result)
@@ -1134,7 +1146,8 @@ int smu7_enable_power_containment(struct pp_hwmgr *hwmgr)
 
 		if (data->enable_pkg_pwr_tracking_feature) {
 			smc_result = smum_send_msg_to_smc(hwmgr,
-					(uint16_t)(PPSMC_MSG_PkgPwrLimitEnable));
+					(uint16_t)(PPSMC_MSG_PkgPwrLimitEnable),
+					NULL);
 			PP_ASSERT_WITH_CODE((0 == smc_result),
 					"Failed to enable PkgPwrTracking in SMC.", result = -1;);
 			if (0 == smc_result) {
@@ -1163,7 +1176,8 @@ int smu7_disable_power_containment(struct pp_hwmgr *hwmgr)
 		if (data->power_containment_features &
 				POWERCONTAINMENT_FEATURE_TDCLimit) {
 			smc_result = smum_send_msg_to_smc(hwmgr,
-					(uint16_t)(PPSMC_MSG_TDCLimitDisable));
+					(uint16_t)(PPSMC_MSG_TDCLimitDisable),
+					NULL);
 			PP_ASSERT_WITH_CODE((smc_result == 0),
 					"Failed to disable TDCLimit in SMC.",
 					result = smc_result);
@@ -1172,7 +1186,8 @@ int smu7_disable_power_containment(struct pp_hwmgr *hwmgr)
 		if (data->power_containment_features &
 				POWERCONTAINMENT_FEATURE_DTE) {
 			smc_result = smum_send_msg_to_smc(hwmgr,
-					(uint16_t)(PPSMC_MSG_DisableDTE));
+					(uint16_t)(PPSMC_MSG_DisableDTE),
+					NULL);
 			PP_ASSERT_WITH_CODE((smc_result == 0),
 					"Failed to disable DTE in SMC.",
 					result = smc_result);
@@ -1181,7 +1196,8 @@ int smu7_disable_power_containment(struct pp_hwmgr *hwmgr)
 		if (data->power_containment_features &
 				POWERCONTAINMENT_FEATURE_PkgPwrLimit) {
 			smc_result = smum_send_msg_to_smc(hwmgr,
-					(uint16_t)(PPSMC_MSG_PkgPwrLimitDisable));
+					(uint16_t)(PPSMC_MSG_PkgPwrLimitDisable),
+					NULL);
 			PP_ASSERT_WITH_CODE((smc_result == 0),
 					"Failed to disable PkgPwrTracking in SMC.",
 					result = smc_result);
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_thermal.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_thermal.c
index 5bdc0df5a9f4..0b30f73649a8 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_thermal.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_thermal.c
@@ -151,8 +151,8 @@ int smu7_fan_ctrl_start_smc_fan_control(struct pp_hwmgr *hwmgr)
 	int result;
 
 	if (PP_CAP(PHM_PlatformCaps_ODFuzzyFanControlSupport)) {
-		cgs_write_register(hwmgr->device, mmSMC_MSG_ARG_0, FAN_CONTROL_FUZZY);
-		result = smum_send_msg_to_smc(hwmgr, PPSMC_StartFanControl);
+		result = smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_StartFanControl,
+					FAN_CONTROL_FUZZY, NULL);
 
 		if (PP_CAP(PHM_PlatformCaps_FanSpeedInTableIsRPM))
 			hwmgr->hwmgr_func->set_max_fan_rpm_output(hwmgr,
@@ -164,8 +164,8 @@ int smu7_fan_ctrl_start_smc_fan_control(struct pp_hwmgr *hwmgr)
 					advanceFanControlParameters.usMaxFanPWM);
 
 	} else {
-		cgs_write_register(hwmgr->device, mmSMC_MSG_ARG_0, FAN_CONTROL_TABLE);
-		result = smum_send_msg_to_smc(hwmgr, PPSMC_StartFanControl);
+		result = smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_StartFanControl,
+					FAN_CONTROL_TABLE, NULL);
 	}
 
 	if (!result && hwmgr->thermal_controller.
@@ -173,7 +173,8 @@ int smu7_fan_ctrl_start_smc_fan_control(struct pp_hwmgr *hwmgr)
 		result = smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_SetFanTemperatureTarget,
 				hwmgr->thermal_controller.
-				advanceFanControlParameters.ucTargetTemperature);
+				advanceFanControlParameters.ucTargetTemperature,
+				NULL);
 	hwmgr->fan_ctrl_enabled = true;
 
 	return result;
@@ -183,7 +184,7 @@ int smu7_fan_ctrl_start_smc_fan_control(struct pp_hwmgr *hwmgr)
 int smu7_fan_ctrl_stop_smc_fan_control(struct pp_hwmgr *hwmgr)
 {
 	hwmgr->fan_ctrl_enabled = false;
-	return smum_send_msg_to_smc(hwmgr, PPSMC_StopFanControl);
+	return smum_send_msg_to_smc(hwmgr, PPSMC_StopFanControl, NULL);
 }
 
 /**
@@ -372,7 +373,7 @@ static void smu7_thermal_enable_alert(struct pp_hwmgr *hwmgr)
 			CG_THERMAL_INT, THERM_INT_MASK, alert);
 
 	/* send message to SMU to enable internal thermal interrupts */
-	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_Thermal_Cntl_Enable);
+	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_Thermal_Cntl_Enable, NULL);
 }
 
 /**
@@ -390,7 +391,7 @@ int smu7_thermal_disable_alert(struct pp_hwmgr *hwmgr)
 			CG_THERMAL_INT, THERM_INT_MASK, alert);
 
 	/* send message to SMU to disable internal thermal interrupts */
-	return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_Thermal_Cntl_Disable);
+	return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_Thermal_Cntl_Disable, NULL);
 }
 
 /**
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu8_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu8_hwmgr.c
index 019d6a206492..a6c6a793e98e 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu8_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu8_hwmgr.c
@@ -162,8 +162,10 @@ static uint32_t smu8_get_max_sclk_level(struct pp_hwmgr *hwmgr)
 	struct smu8_hwmgr *data = hwmgr->backend;
 
 	if (data->max_sclk_level == 0) {
-		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxSclkLevel);
-		data->max_sclk_level = smum_get_argument(hwmgr) + 1;
+		smum_send_msg_to_smc(hwmgr,
+				PPSMC_MSG_GetMaxSclkLevel,
+				&data->max_sclk_level);
+		data->max_sclk_level += 1;
 	}
 
 	return data->max_sclk_level;
@@ -580,7 +582,8 @@ static int smu8_init_uvd_limit(struct pp_hwmgr *hwmgr)
 	struct smu8_hwmgr *data = hwmgr->backend;
 	struct phm_uvd_clock_voltage_dependency_table *table =
 				hwmgr->dyn_state.uvd_clock_voltage_dependency_table;
-	unsigned long clock = 0, level;
+	unsigned long clock = 0;
+	uint32_t level;
 
 	if (NULL == table || table->count <= 0)
 		return -EINVAL;
@@ -588,8 +591,7 @@ static int smu8_init_uvd_limit(struct pp_hwmgr *hwmgr)
 	data->uvd_dpm.soft_min_clk = 0;
 	data->uvd_dpm.hard_min_clk = 0;
 
-	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxUvdLevel);
-	level = smum_get_argument(hwmgr);
+	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxUvdLevel, &level);
 
 	if (level < table->count)
 		clock = table->entries[level].vclk;
@@ -607,7 +609,8 @@ static int smu8_init_vce_limit(struct pp_hwmgr *hwmgr)
 	struct smu8_hwmgr *data = hwmgr->backend;
 	struct phm_vce_clock_voltage_dependency_table *table =
 				hwmgr->dyn_state.vce_clock_voltage_dependency_table;
-	unsigned long clock = 0, level;
+	unsigned long clock = 0;
+	uint32_t level;
 
 	if (NULL == table || table->count <= 0)
 		return -EINVAL;
@@ -615,8 +618,7 @@ static int smu8_init_vce_limit(struct pp_hwmgr *hwmgr)
 	data->vce_dpm.soft_min_clk = 0;
 	data->vce_dpm.hard_min_clk = 0;
 
-	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxEclkLevel);
-	level = smum_get_argument(hwmgr);
+	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxEclkLevel, &level);
 
 	if (level < table->count)
 		clock = table->entries[level].ecclk;
@@ -634,7 +636,8 @@ static int smu8_init_acp_limit(struct pp_hwmgr *hwmgr)
 	struct smu8_hwmgr *data = hwmgr->backend;
 	struct phm_acp_clock_voltage_dependency_table *table =
 				hwmgr->dyn_state.acp_clock_voltage_dependency_table;
-	unsigned long clock = 0, level;
+	unsigned long clock = 0;
+	uint32_t level;
 
 	if (NULL == table || table->count <= 0)
 		return -EINVAL;
@@ -642,8 +645,7 @@ static int smu8_init_acp_limit(struct pp_hwmgr *hwmgr)
 	data->acp_dpm.soft_min_clk = 0;
 	data->acp_dpm.hard_min_clk = 0;
 
-	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxAclkLevel);
-	level = smum_get_argument(hwmgr);
+	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxAclkLevel, &level);
 
 	if (level < table->count)
 		clock = table->entries[level].acpclk;
@@ -665,7 +667,7 @@ static void smu8_init_power_gate_state(struct pp_hwmgr *hwmgr)
 #ifdef CONFIG_DRM_AMD_ACP
 	data->acp_power_gated = false;
 #else
-	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ACPPowerOFF);
+	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ACPPowerOFF, NULL);
 	data->acp_power_gated = true;
 #endif
 
@@ -708,7 +710,8 @@ static int smu8_update_sclk_limit(struct pp_hwmgr *hwmgr)
 						PPSMC_MSG_SetSclkHardMin,
 						 smu8_get_sclk_level(hwmgr,
 					data->sclk_dpm.hard_min_clk,
-					     PPSMC_MSG_SetSclkHardMin));
+					     PPSMC_MSG_SetSclkHardMin),
+						 NULL);
 	}
 
 	clock = data->sclk_dpm.soft_min_clk;
@@ -731,7 +734,8 @@ static int smu8_update_sclk_limit(struct pp_hwmgr *hwmgr)
 						PPSMC_MSG_SetSclkSoftMin,
 						smu8_get_sclk_level(hwmgr,
 					data->sclk_dpm.soft_min_clk,
-					     PPSMC_MSG_SetSclkSoftMin));
+					     PPSMC_MSG_SetSclkSoftMin),
+						NULL);
 	}
 
 	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
@@ -742,7 +746,8 @@ static int smu8_update_sclk_limit(struct pp_hwmgr *hwmgr)
 						PPSMC_MSG_SetSclkSoftMax,
 						smu8_get_sclk_level(hwmgr,
 					data->sclk_dpm.soft_max_clk,
-					PPSMC_MSG_SetSclkSoftMax));
+					PPSMC_MSG_SetSclkSoftMax),
+						NULL);
 	}
 
 	return 0;
@@ -760,7 +765,8 @@ static int smu8_set_deep_sleep_sclk_threshold(struct pp_hwmgr *hwmgr)
 
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_SetMinDeepSleepSclk,
-				clks);
+				clks,
+				NULL);
 	}
 
 	return 0;
@@ -773,7 +779,8 @@ static int smu8_set_watermark_threshold(struct pp_hwmgr *hwmgr)
 
 	smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_SetWatermarkFrequency,
-					data->sclk_dpm.soft_max_clk);
+					data->sclk_dpm.soft_max_clk,
+					NULL);
 
 	return 0;
 }
@@ -788,13 +795,15 @@ static int smu8_nbdpm_pstate_enable_disable(struct pp_hwmgr *hwmgr, bool enable,
 
 			return smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_EnableLowMemoryPstate,
-						(lock ? 1 : 0));
+						(lock ? 1 : 0),
+						NULL);
 		} else {
 			PP_DBG_LOG("disable Low Memory PState.\n");
 
 			return smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_DisableLowMemoryPstate,
-						(lock ? 1 : 0));
+						(lock ? 1 : 0),
+						NULL);
 		}
 	}
 
@@ -814,7 +823,8 @@ static int smu8_disable_nb_dpm(struct pp_hwmgr *hwmgr)
 		ret = smum_send_msg_to_smc_with_parameter(
 							  hwmgr,
 							  PPSMC_MSG_DisableAllSmuFeatures,
-							  dpm_features);
+							  dpm_features,
+							  NULL);
 		if (ret == 0)
 			data->is_nb_dpm_enabled = false;
 	}
@@ -835,7 +845,8 @@ static int smu8_enable_nb_dpm(struct pp_hwmgr *hwmgr)
 		ret = smum_send_msg_to_smc_with_parameter(
 							  hwmgr,
 							  PPSMC_MSG_EnableAllSmuFeatures,
-							  dpm_features);
+							  dpm_features,
+							  NULL);
 		if (ret == 0)
 			data->is_nb_dpm_enabled = true;
 	}
@@ -953,7 +964,8 @@ static int smu8_start_dpm(struct pp_hwmgr *hwmgr)
 
 	return smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_EnableAllSmuFeatures,
-				SCLK_DPM_MASK);
+				SCLK_DPM_MASK,
+				NULL);
 }
 
 static int smu8_stop_dpm(struct pp_hwmgr *hwmgr)
@@ -967,7 +979,8 @@ static int smu8_stop_dpm(struct pp_hwmgr *hwmgr)
 		data->dpm_flags &= ~DPMFlags_SCLK_Enabled;
 		ret = smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_DisableAllSmuFeatures,
-					dpm_features);
+					dpm_features,
+					NULL);
 	}
 	return ret;
 }
@@ -983,13 +996,15 @@ static int smu8_program_bootup_state(struct pp_hwmgr *hwmgr)
 				PPSMC_MSG_SetSclkSoftMin,
 				smu8_get_sclk_level(hwmgr,
 				data->sclk_dpm.soft_min_clk,
-				PPSMC_MSG_SetSclkSoftMin));
+				PPSMC_MSG_SetSclkSoftMin),
+				NULL);
 
 	smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_SetSclkSoftMax,
 				smu8_get_sclk_level(hwmgr,
 				data->sclk_dpm.soft_max_clk,
-				PPSMC_MSG_SetSclkSoftMax));
+				PPSMC_MSG_SetSclkSoftMax),
+				NULL);
 
 	return 0;
 }
@@ -1127,13 +1142,15 @@ static int smu8_phm_force_dpm_highest(struct pp_hwmgr *hwmgr)
 					PPSMC_MSG_SetSclkSoftMin,
 					smu8_get_sclk_level(hwmgr,
 					data->sclk_dpm.soft_max_clk,
-					PPSMC_MSG_SetSclkSoftMin));
+					PPSMC_MSG_SetSclkSoftMin),
+					NULL);
 
 	smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_SetSclkSoftMax,
 				smu8_get_sclk_level(hwmgr,
 				data->sclk_dpm.soft_max_clk,
-				PPSMC_MSG_SetSclkSoftMax));
+				PPSMC_MSG_SetSclkSoftMax),
+				NULL);
 
 	return 0;
 }
@@ -1167,13 +1184,15 @@ static int smu8_phm_unforce_dpm_levels(struct pp_hwmgr *hwmgr)
 				PPSMC_MSG_SetSclkSoftMin,
 				smu8_get_sclk_level(hwmgr,
 				data->sclk_dpm.soft_min_clk,
-				PPSMC_MSG_SetSclkSoftMin));
+				PPSMC_MSG_SetSclkSoftMin),
+				NULL);
 
 	smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_SetSclkSoftMax,
 				smu8_get_sclk_level(hwmgr,
 				data->sclk_dpm.soft_max_clk,
-				PPSMC_MSG_SetSclkSoftMax));
+				PPSMC_MSG_SetSclkSoftMax),
+				NULL);
 
 	return 0;
 }
@@ -1186,13 +1205,15 @@ static int smu8_phm_force_dpm_lowest(struct pp_hwmgr *hwmgr)
 			PPSMC_MSG_SetSclkSoftMax,
 			smu8_get_sclk_level(hwmgr,
 			data->sclk_dpm.soft_min_clk,
-			PPSMC_MSG_SetSclkSoftMax));
+			PPSMC_MSG_SetSclkSoftMax),
+			NULL);
 
 	smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_SetSclkSoftMin,
 				smu8_get_sclk_level(hwmgr,
 				data->sclk_dpm.soft_min_clk,
-				PPSMC_MSG_SetSclkSoftMin));
+				PPSMC_MSG_SetSclkSoftMin),
+				NULL);
 
 	return 0;
 }
@@ -1227,7 +1248,7 @@ static int smu8_dpm_force_dpm_level(struct pp_hwmgr *hwmgr,
 static int smu8_dpm_powerdown_uvd(struct pp_hwmgr *hwmgr)
 {
 	if (PP_CAP(PHM_PlatformCaps_UVDPowerGating))
-		return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_UVDPowerOFF);
+		return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_UVDPowerOFF, NULL);
 	return 0;
 }
 
@@ -1237,7 +1258,8 @@ static int smu8_dpm_powerup_uvd(struct pp_hwmgr *hwmgr)
 		return smum_send_msg_to_smc_with_parameter(
 			hwmgr,
 			PPSMC_MSG_UVDPowerON,
-			PP_CAP(PHM_PlatformCaps_UVDDynamicPowerGating) ? 1 : 0);
+			PP_CAP(PHM_PlatformCaps_UVDDynamicPowerGating) ? 1 : 0,
+			NULL);
 	}
 
 	return 0;
@@ -1259,15 +1281,20 @@ static int  smu8_dpm_update_vce_dpm(struct pp_hwmgr *hwmgr)
 			PPSMC_MSG_SetEclkHardMin,
 			smu8_get_eclk_level(hwmgr,
 				data->vce_dpm.hard_min_clk,
-				PPSMC_MSG_SetEclkHardMin));
+				PPSMC_MSG_SetEclkHardMin),
+			NULL);
 	} else {
 
 		smum_send_msg_to_smc_with_parameter(hwmgr,
-					PPSMC_MSG_SetEclkHardMin, 0);
+					PPSMC_MSG_SetEclkHardMin,
+					0,
+					NULL);
 		/* disable ECLK DPM 0. Otherwise VCE could hang if
 		 * switching SCLK from DPM 0 to 6/7 */
 		smum_send_msg_to_smc_with_parameter(hwmgr,
-					PPSMC_MSG_SetEclkSoftMin, 1);
+					PPSMC_MSG_SetEclkSoftMin,
+					1,
+					NULL);
 	}
 	return 0;
 }
@@ -1276,7 +1303,8 @@ static int smu8_dpm_powerdown_vce(struct pp_hwmgr *hwmgr)
 {
 	if (PP_CAP(PHM_PlatformCaps_VCEPowerGating))
 		return smum_send_msg_to_smc(hwmgr,
-						     PPSMC_MSG_VCEPowerOFF);
+					    PPSMC_MSG_VCEPowerOFF,
+					    NULL);
 	return 0;
 }
 
@@ -1284,7 +1312,8 @@ static int smu8_dpm_powerup_vce(struct pp_hwmgr *hwmgr)
 {
 	if (PP_CAP(PHM_PlatformCaps_VCEPowerGating))
 		return smum_send_msg_to_smc(hwmgr,
-						     PPSMC_MSG_VCEPowerON);
+					    PPSMC_MSG_VCEPowerON,
+					    NULL);
 	return 0;
 }
 
@@ -1435,7 +1464,8 @@ static void smu8_hw_print_display_cfg(
 
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetDisplaySizePowerParams,
-						data);
+						data,
+						NULL);
 	}
 
 	return 0;
@@ -1497,10 +1527,12 @@ static int smu8_force_clock_level(struct pp_hwmgr *hwmgr,
 	case PP_SCLK:
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_SetSclkSoftMin,
-				mask);
+				mask,
+				NULL);
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_SetSclkSoftMax,
-				mask);
+				mask,
+				NULL);
 		break;
 	default:
 		break;
@@ -1753,9 +1785,10 @@ static int smu8_read_sensor(struct pp_hwmgr *hwmgr, int idx,
 		*((uint32_t *)value) = 0;
 		return 0;
 	case AMDGPU_PP_SENSOR_GPU_LOAD:
-		result = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetAverageGraphicsActivity);
+		result = smum_send_msg_to_smc(hwmgr,
+				PPSMC_MSG_GetAverageGraphicsActivity,
+				&activity_percent);
 		if (0 == result) {
-			activity_percent = cgs_read_register(hwmgr->device, mmSMU_MP1_SRBM2P_ARG_0);
 			activity_percent = activity_percent > 100 ? 100 : activity_percent;
 		} else {
 			activity_percent = 50;
@@ -1785,20 +1818,25 @@ static int smu8_notify_cac_buffer_info(struct pp_hwmgr *hwmgr,
 {
 	smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_DramAddrHiVirtual,
-					mc_addr_hi);
+					mc_addr_hi,
+					NULL);
 	smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_DramAddrLoVirtual,
-					mc_addr_low);
+					mc_addr_low,
+					NULL);
 	smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_DramAddrHiPhysical,
-					virtual_addr_hi);
+					virtual_addr_hi,
+					NULL);
 	smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_DramAddrLoPhysical,
-					virtual_addr_low);
+					virtual_addr_low,
+					NULL);
 
 	smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_DramBufferSize,
-					size);
+					size,
+					NULL);
 	return 0;
 }
 
@@ -1827,12 +1865,16 @@ static int smu8_enable_disable_uvd_dpm(struct pp_hwmgr *hwmgr, bool enable)
 		data->dpm_flags |= DPMFlags_UVD_Enabled;
 		dpm_features |= UVD_DPM_MASK;
 		smum_send_msg_to_smc_with_parameter(hwmgr,
-			    PPSMC_MSG_EnableAllSmuFeatures, dpm_features);
+			    PPSMC_MSG_EnableAllSmuFeatures,
+			    dpm_features,
+			    NULL);
 	} else {
 		dpm_features |= UVD_DPM_MASK;
 		data->dpm_flags &= ~DPMFlags_UVD_Enabled;
 		smum_send_msg_to_smc_with_parameter(hwmgr,
-			   PPSMC_MSG_DisableAllSmuFeatures, dpm_features);
+			   PPSMC_MSG_DisableAllSmuFeatures,
+			   dpm_features,
+			   NULL);
 	}
 	return 0;
 }
@@ -1854,7 +1896,8 @@ int smu8_dpm_update_uvd_dpm(struct pp_hwmgr *hwmgr, bool bgate)
 				PPSMC_MSG_SetUvdHardMin,
 				smu8_get_uvd_level(hwmgr,
 					data->uvd_dpm.hard_min_clk,
-					PPSMC_MSG_SetUvdHardMin));
+					PPSMC_MSG_SetUvdHardMin),
+				NULL);
 
 			smu8_enable_disable_uvd_dpm(hwmgr, true);
 		} else {
@@ -1878,12 +1921,16 @@ static int smu8_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable)
 		data->dpm_flags |= DPMFlags_VCE_Enabled;
 		dpm_features |= VCE_DPM_MASK;
 		smum_send_msg_to_smc_with_parameter(hwmgr,
-			    PPSMC_MSG_EnableAllSmuFeatures, dpm_features);
+			    PPSMC_MSG_EnableAllSmuFeatures,
+			    dpm_features,
+			    NULL);
 	} else {
 		dpm_features |= VCE_DPM_MASK;
 		data->dpm_flags &= ~DPMFlags_VCE_Enabled;
 		smum_send_msg_to_smc_with_parameter(hwmgr,
-			   PPSMC_MSG_DisableAllSmuFeatures, dpm_features);
+			   PPSMC_MSG_DisableAllSmuFeatures,
+			   dpm_features,
+			   NULL);
 	}
 
 	return 0;
@@ -1898,9 +1945,9 @@ static void smu8_dpm_powergate_acp(struct pp_hwmgr *hwmgr, bool bgate)
 		return;
 
 	if (bgate)
-		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ACPPowerOFF);
+		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ACPPowerOFF, NULL);
 	else
-		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ACPPowerON);
+		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ACPPowerON, NULL);
 }
 
 static void smu8_dpm_powergate_uvd(struct pp_hwmgr *hwmgr, bool bgate)
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.c
index d09690fca452..91b5d96db674 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.c
@@ -557,7 +557,9 @@ void phm_apply_dal_min_voltage_request(struct pp_hwmgr *hwmgr)
 		if (req_vddc <= vddc_table->entries[i].vddc) {
 			req_volt = (((uint32_t)vddc_table->entries[i].vddc) * VOLTAGE_SCALE);
 			smum_send_msg_to_smc_with_parameter(hwmgr,
-					PPSMC_MSG_VddC_Request, req_volt);
+					PPSMC_MSG_VddC_Request,
+					req_volt,
+					NULL);
 			return;
 		}
 	}
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_baco.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_baco.c
index d168af4a4d78..46bb16c29cf6 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_baco.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_baco.c
@@ -98,7 +98,7 @@ int vega10_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state)
 	if (state == BACO_STATE_IN) {
 		if (soc15_baco_program_registers(hwmgr, pre_baco_tbl,
 					     ARRAY_SIZE(pre_baco_tbl))) {
-			if (smum_send_msg_to_smc(hwmgr, PPSMC_MSG_EnterBaco))
+			if (smum_send_msg_to_smc(hwmgr, PPSMC_MSG_EnterBaco, NULL))
 				return -EINVAL;
 
 			if (soc15_baco_program_registers(hwmgr, enter_baco_tbl,
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
index f29f95be1e56..675c7cab7cfc 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
@@ -484,8 +484,9 @@ static void vega10_init_dpm_defaults(struct pp_hwmgr *hwmgr)
 	if (data->registry_data.vr0hot_enabled)
 		data->smu_features[GNLD_VR0HOT].supported = true;
 
-	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetSmuVersion);
-	hwmgr->smu_version = smum_get_argument(hwmgr);
+	smum_send_msg_to_smc(hwmgr,
+			PPSMC_MSG_GetSmuVersion,
+			&hwmgr->smu_version);
 		/* ACG firmware has major version 5 */
 	if ((hwmgr->smu_version & 0xff000000) == 0x5000000)
 		data->smu_features[GNLD_ACG].supported = true;
@@ -503,10 +504,8 @@ static void vega10_init_dpm_defaults(struct pp_hwmgr *hwmgr)
 		data->smu_features[GNLD_PCC_LIMIT].supported = true;
 
 	/* Get the SN to turn into a Unique ID */
-	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumTop32);
-	top32 = smum_get_argument(hwmgr);
-	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumBottom32);
-	bottom32 = smum_get_argument(hwmgr);
+	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumTop32, &top32);
+	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumBottom32, &bottom32);
 
 	adev->unique_id = ((uint64_t)bottom32 << 32) | top32;
 }
@@ -993,7 +992,10 @@ static int vega10_setup_asic_task(struct pp_hwmgr *hwmgr)
 			"Failed to set up led dpm config!",
 			return -EINVAL);
 
-	smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_NumOfDisplays, 0);
+	smum_send_msg_to_smc_with_parameter(hwmgr,
+				PPSMC_MSG_NumOfDisplays,
+				0,
+				NULL);
 
 	return 0;
 }
@@ -2303,16 +2305,15 @@ static int vega10_acg_enable(struct pp_hwmgr *hwmgr)
 					data->smu_features[GNLD_DPM_PREFETCHER].smu_feature_bitmap))
 			data->smu_features[GNLD_DPM_PREFETCHER].enabled = true;
 
-		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_InitializeAcg);
+		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_InitializeAcg, NULL);
 
-		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_RunAcgBtc);
-		agc_btc_response = smum_get_argument(hwmgr);
+		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_RunAcgBtc, &agc_btc_response);
 
 		if (1 == agc_btc_response) {
 			if (1 == data->acg_loop_state)
-				smum_send_msg_to_smc(hwmgr, PPSMC_MSG_RunAcgInClosedLoop);
+				smum_send_msg_to_smc(hwmgr, PPSMC_MSG_RunAcgInClosedLoop, NULL);
 			else if (2 == data->acg_loop_state)
-				smum_send_msg_to_smc(hwmgr, PPSMC_MSG_RunAcgInOpenLoop);
+				smum_send_msg_to_smc(hwmgr, PPSMC_MSG_RunAcgInOpenLoop, NULL);
 			if (0 == vega10_enable_smc_features(hwmgr, true,
 				data->smu_features[GNLD_ACG].smu_feature_bitmap))
 					data->smu_features[GNLD_ACG].enabled = true;
@@ -2429,11 +2430,9 @@ static int vega10_populate_and_upload_avfs_fuse_override(struct pp_hwmgr *hwmgr)
 	struct vega10_hwmgr *data = hwmgr->backend;
 	AvfsFuseOverride_t *avfs_fuse_table = &(data->smc_state_table.avfs_fuse_override_table);
 
-	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumTop32);
-	top32 = smum_get_argument(hwmgr);
+	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumTop32, &top32);
 
-	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumBottom32);
-	bottom32 = smum_get_argument(hwmgr);
+	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumBottom32, &bottom32);
 
 	serial_number = ((uint64_t)bottom32 << 32) | top32;
 
@@ -2610,14 +2609,16 @@ static int vega10_init_smc_table(struct pp_hwmgr *hwmgr)
 		if (0 != boot_up_values.usVddc) {
 			smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetFloorSocVoltage,
-						(boot_up_values.usVddc * 4));
+						(boot_up_values.usVddc * 4),
+						NULL);
 			data->vbios_boot_state.bsoc_vddc_lock = true;
 		} else {
 			data->vbios_boot_state.bsoc_vddc_lock = false;
 		}
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_SetMinDeepSleepDcefclk,
-			(uint32_t)(data->vbios_boot_state.dcef_clock / 100));
+			(uint32_t)(data->vbios_boot_state.dcef_clock / 100),
+				NULL);
 	}
 
 	result = vega10_populate_avfs_parameters(hwmgr);
@@ -2904,7 +2905,8 @@ static int vega10_start_dpm(struct pp_hwmgr *hwmgr, uint32_t bitmap)
 
 	if (data->vbios_boot_state.bsoc_vddc_lock) {
 		smum_send_msg_to_smc_with_parameter(hwmgr,
-						PPSMC_MSG_SetFloorSocVoltage, 0);
+						PPSMC_MSG_SetFloorSocVoltage, 0,
+						NULL);
 		data->vbios_boot_state.bsoc_vddc_lock = false;
 	}
 
@@ -2947,7 +2949,8 @@ static int vega10_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
 		vega10_enable_disable_PCC_limit_feature(hwmgr, true);
 
 		smum_send_msg_to_smc_with_parameter(hwmgr,
-			PPSMC_MSG_ConfigureTelemetry, data->config_telemetry);
+			PPSMC_MSG_ConfigureTelemetry, data->config_telemetry,
+			NULL);
 
 		tmp_result = vega10_construct_voltage_tables(hwmgr);
 		PP_ASSERT_WITH_CODE(!tmp_result,
@@ -3528,7 +3531,8 @@ static int vega10_upload_dpm_bootup_level(struct pp_hwmgr *hwmgr)
 				data->dpm_table.gfx_table.dpm_state.soft_min_level) {
 			smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_SetSoftMinGfxclkByIndex,
-				data->smc_state_table.gfx_boot_level);
+				data->smc_state_table.gfx_boot_level,
+				NULL);
 
 			data->dpm_table.gfx_table.dpm_state.soft_min_level =
 					data->smc_state_table.gfx_boot_level;
@@ -3543,11 +3547,13 @@ static int vega10_upload_dpm_bootup_level(struct pp_hwmgr *hwmgr)
 				socclk_idx = vega10_get_soc_index_for_max_uclk(hwmgr);
 				smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetSoftMinSocclkByIndex,
-						socclk_idx);
+						socclk_idx,
+						NULL);
 			} else {
 				smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SetSoftMinUclkByIndex,
-						data->smc_state_table.mem_boot_level);
+						data->smc_state_table.mem_boot_level,
+						NULL);
 			}
 			data->dpm_table.mem_table.dpm_state.soft_min_level =
 					data->smc_state_table.mem_boot_level;
@@ -3562,7 +3568,8 @@ static int vega10_upload_dpm_bootup_level(struct pp_hwmgr *hwmgr)
 				data->dpm_table.soc_table.dpm_state.soft_min_level) {
 			smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_SetSoftMinSocclkByIndex,
-				data->smc_state_table.soc_boot_level);
+				data->smc_state_table.soc_boot_level,
+				NULL);
 			data->dpm_table.soc_table.dpm_state.soft_min_level =
 					data->smc_state_table.soc_boot_level;
 		}
@@ -3582,7 +3589,8 @@ static int vega10_upload_dpm_max_level(struct pp_hwmgr *hwmgr)
 			data->dpm_table.gfx_table.dpm_state.soft_max_level) {
 			smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_SetSoftMaxGfxclkByIndex,
-				data->smc_state_table.gfx_max_level);
+				data->smc_state_table.gfx_max_level,
+				NULL);
 			data->dpm_table.gfx_table.dpm_state.soft_max_level =
 					data->smc_state_table.gfx_max_level;
 		}
@@ -3593,7 +3601,8 @@ static int vega10_upload_dpm_max_level(struct pp_hwmgr *hwmgr)
 			data->dpm_table.mem_table.dpm_state.soft_max_level) {
 			smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_SetSoftMaxUclkByIndex,
-					data->smc_state_table.mem_max_level);
+					data->smc_state_table.mem_max_level,
+					NULL);
 			data->dpm_table.mem_table.dpm_state.soft_max_level =
 					data->smc_state_table.mem_max_level;
 		}
@@ -3607,7 +3616,8 @@ static int vega10_upload_dpm_max_level(struct pp_hwmgr *hwmgr)
 			data->dpm_table.soc_table.dpm_state.soft_max_level) {
 			smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_SetSoftMaxSocclkByIndex,
-				data->smc_state_table.soc_max_level);
+				data->smc_state_table.soc_max_level,
+				NULL);
 			data->dpm_table.soc_table.dpm_state.soft_max_level =
 					data->smc_state_table.soc_max_level;
 		}
@@ -3694,7 +3704,8 @@ static int vega10_update_sclk_threshold(struct pp_hwmgr *hwmgr)
 		/* This message will also enable SmcToHost Interrupt */
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_SetLowGfxclkInterruptThreshold,
-				(uint32_t)low_sclk_interrupt_threshold);
+				(uint32_t)low_sclk_interrupt_threshold,
+				NULL);
 	}
 
 	return 0;
@@ -3801,8 +3812,7 @@ static int vega10_get_gpu_power(struct pp_hwmgr *hwmgr,
 	if (!query)
 		return -EINVAL;
 
-	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrPkgPwr);
-	value = smum_get_argument(hwmgr);
+	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrPkgPwr, &value);
 
 	/* SMC returning actual watts, keep consistent with legacy asics, low 8 bit as 8 fractional bits */
 	*query = value << 8;
@@ -3822,13 +3832,11 @@ static int vega10_read_sensor(struct pp_hwmgr *hwmgr, int idx,
 
 	switch (idx) {
 	case AMDGPU_PP_SENSOR_GFX_SCLK:
-		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetAverageGfxclkActualFrequency);
-		sclk_mhz = smum_get_argument(hwmgr);
+		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetAverageGfxclkActualFrequency, &sclk_mhz);
 		*((uint32_t *)value) = sclk_mhz * 100;
 		break;
 	case AMDGPU_PP_SENSOR_GFX_MCLK:
-		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentUclkIndex);
-		mclk_idx = smum_get_argument(hwmgr);
+		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentUclkIndex, &mclk_idx);
 		if (mclk_idx < dpm_table->mem_table.count) {
 			*((uint32_t *)value) = dpm_table->mem_table.dpm_levels[mclk_idx].value;
 			*size = 4;
@@ -3837,8 +3845,8 @@ static int vega10_read_sensor(struct pp_hwmgr *hwmgr, int idx,
 		}
 		break;
 	case AMDGPU_PP_SENSOR_GPU_LOAD:
-		smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetAverageGfxActivity, 0);
-		activity_percent = smum_get_argument(hwmgr);
+		smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetAverageGfxActivity, 0,
+						&activity_percent);
 		*((uint32_t *)value) = activity_percent > 100 ? 100 : activity_percent;
 		*size = 4;
 		break;
@@ -3847,14 +3855,14 @@ static int vega10_read_sensor(struct pp_hwmgr *hwmgr, int idx,
 		*size = 4;
 		break;
 	case AMDGPU_PP_SENSOR_HOTSPOT_TEMP:
-		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetTemperatureHotspot);
-		*((uint32_t *)value) = smum_get_argument(hwmgr) *
+		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetTemperatureHotspot, (uint32_t *)value);
+		*((uint32_t *)value) = *((uint32_t *)value) *
 			PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
 		*size = 4;
 		break;
 	case AMDGPU_PP_SENSOR_MEM_TEMP:
-		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetTemperatureHBM);
-		*((uint32_t *)value) = smum_get_argument(hwmgr) *
+		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetTemperatureHBM, (uint32_t *)value);
+		*((uint32_t *)value) = *((uint32_t *)value) *
 			PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
 		*size = 4;
 		break;
@@ -3893,7 +3901,8 @@ static void vega10_notify_smc_display_change(struct pp_hwmgr *hwmgr,
 {
 	smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_SetUclkFastSwitch,
-			has_disp ? 1 : 0);
+			has_disp ? 1 : 0,
+			NULL);
 }
 
 int vega10_display_clock_voltage_request(struct pp_hwmgr *hwmgr,
@@ -3928,7 +3937,8 @@ int vega10_display_clock_voltage_request(struct pp_hwmgr *hwmgr,
 		clk_request = (clk_freq << 16) | clk_select;
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_RequestDisplayClockByFreq,
-				clk_request);
+				clk_request,
+				NULL);
 	}
 
 	return result;
@@ -3990,7 +4000,8 @@ static int vega10_notify_smc_display_config_after_ps_adjustment(
 		if (!vega10_display_clock_voltage_request(hwmgr, &clock_req)) {
 			smum_send_msg_to_smc_with_parameter(
 					hwmgr, PPSMC_MSG_SetMinDeepSleepDcefclk,
-					min_clocks.dcefClockInSR / 100);
+					min_clocks.dcefClockInSR / 100,
+					NULL);
 		} else {
 			pr_info("Attempt to set Hard Min for DCEFCLK Failed!");
 		}
@@ -4000,7 +4011,8 @@ static int vega10_notify_smc_display_config_after_ps_adjustment(
 
 	if (min_clocks.memoryClock != 0) {
 		idx = vega10_get_uclk_index(hwmgr, mclk_table, min_clocks.memoryClock);
-		smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetSoftMinUclkByIndex, idx);
+		smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetSoftMinUclkByIndex, idx,
+						NULL);
 		data->dpm_table.mem_table.dpm_state.soft_min_level= idx;
 	}
 
@@ -4541,8 +4553,7 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
 		if (data->registry_data.sclk_dpm_key_disabled)
 			break;
 
-		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentGfxclkIndex);
-		now = smum_get_argument(hwmgr);
+		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentGfxclkIndex, &now);
 
 		if (hwmgr->pp_one_vf &&
 		    (hwmgr->dpm_level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK))
@@ -4558,8 +4569,7 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
 		if (data->registry_data.mclk_dpm_key_disabled)
 			break;
 
-		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentUclkIndex);
-		now = smum_get_argument(hwmgr);
+		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentUclkIndex, &now);
 
 		for (i = 0; i < mclk_table->count; i++)
 			size += sprintf(buf + size, "%d: %uMhz %s\n",
@@ -4570,8 +4580,7 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
 		if (data->registry_data.socclk_dpm_key_disabled)
 			break;
 
-		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentSocclkIndex);
-		now = smum_get_argument(hwmgr);
+		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentSocclkIndex, &now);
 
 		for (i = 0; i < soc_table->count; i++)
 			size += sprintf(buf + size, "%d: %uMhz %s\n",
@@ -4583,8 +4592,7 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
 			break;
 
 		smum_send_msg_to_smc_with_parameter(hwmgr,
-				PPSMC_MSG_GetClockFreqMHz, CLK_DCEFCLK);
-		now = smum_get_argument(hwmgr);
+				PPSMC_MSG_GetClockFreqMHz, CLK_DCEFCLK, &now);
 
 		for (i = 0; i < dcef_table->count; i++)
 			size += sprintf(buf + size, "%d: %uMhz %s\n",
@@ -4593,8 +4601,7 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
 					"*" : "");
 		break;
 	case PP_PCIE:
-		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentLinkIndex);
-		now = smum_get_argument(hwmgr);
+		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentLinkIndex, &now);
 
 		for (i = 0; i < pcie_table->count; i++)
 			size += sprintf(buf + size, "%d: %s %s\n", i,
@@ -4658,7 +4665,8 @@ static int vega10_display_configuration_changed_task(struct pp_hwmgr *hwmgr)
 
 	if (data->water_marks_bitmap & WaterMarksLoaded) {
 		smum_send_msg_to_smc_with_parameter(hwmgr,
-			PPSMC_MSG_NumOfDisplays, hwmgr->display_config->num_display);
+			PPSMC_MSG_NumOfDisplays, hwmgr->display_config->num_display,
+			NULL);
 	}
 
 	return result;
@@ -4924,21 +4932,26 @@ static int vega10_notify_cac_buffer_info(struct pp_hwmgr *hwmgr,
 {
 	smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_SetSystemVirtualDramAddrHigh,
-					virtual_addr_hi);
+					virtual_addr_hi,
+					NULL);
 	smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_SetSystemVirtualDramAddrLow,
-					virtual_addr_low);
+					virtual_addr_low,
+					NULL);
 	smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_DramLogSetDramAddrHigh,
-					mc_addr_hi);
+					mc_addr_hi,
+					NULL);
 
 	smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_DramLogSetDramAddrLow,
-					mc_addr_low);
+					mc_addr_low,
+					NULL);
 
 	smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_DramLogSetDramSize,
-					size);
+					size,
+					NULL);
 	return 0;
 }
 
@@ -5040,12 +5053,14 @@ static int vega10_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, ui
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_SetCustomGfxDpmParameters,
 					busy_set_point | FPS<<8 |
-					use_rlc_busy << 16 | min_active_level<<24);
+					use_rlc_busy << 16 | min_active_level<<24,
+					NULL);
 	}
 
 out:
 	smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetWorkloadMask,
-						1 << power_profile_mode);
+						1 << power_profile_mode,
+						NULL);
 	hwmgr->power_profile_mode = power_profile_mode;
 
 	return 0;
@@ -5302,7 +5317,7 @@ static int vega10_set_mp1_state(struct pp_hwmgr *hwmgr,
 		return 0;
 	}
 
-	PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc(hwmgr, msg)) == 0,
+	PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc(hwmgr, msg, NULL)) == 0,
 			    "[PrepareMp1] Failed!",
 			    return ret);
 
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c
index 0a677d4bc87b..ca9b23b5abc9 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c
@@ -925,7 +925,8 @@ static void vega10_didt_set_mask(struct pp_hwmgr *hwmgr, const bool enable)
 
 	/* For Vega10, SMC does not support any mask yet. */
 	if (enable)
-		smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_ConfigureGfxDidt, didt_block_info);
+		smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_ConfigureGfxDidt, didt_block_info,
+						NULL);
 
 }
 
@@ -1327,7 +1328,8 @@ int vega10_set_power_limit(struct pp_hwmgr *hwmgr, uint32_t n)
 
 	if (data->registry_data.enable_pkg_pwr_tracking_feature)
 		smum_send_msg_to_smc_with_parameter(hwmgr,
-				PPSMC_MSG_SetPptLimit, n);
+				PPSMC_MSG_SetPptLimit, n,
+				NULL);
 
 	return 0;
 }
@@ -1393,7 +1395,8 @@ static void vega10_set_overdrive_target_percentage(struct pp_hwmgr *hwmgr,
 		uint32_t adjust_percent)
 {
 	smum_send_msg_to_smc_with_parameter(hwmgr,
-			PPSMC_MSG_OverDriveSetPercentage, adjust_percent);
+			PPSMC_MSG_OverDriveSetPercentage, adjust_percent,
+			NULL);
 }
 
 int vega10_power_control_set_level(struct pp_hwmgr *hwmgr)
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c
index ba8763daa380..7783c7fd7ccb 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c
@@ -31,8 +31,7 @@
 
 static int vega10_get_current_rpm(struct pp_hwmgr *hwmgr, uint32_t *current_rpm)
 {
-	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentRpm);
-	*current_rpm = smum_get_argument(hwmgr);
+	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentRpm, current_rpm);
 	return 0;
 }
 
@@ -520,7 +519,8 @@ int vega10_thermal_setup_fan_table(struct pp_hwmgr *hwmgr)
 
 	smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_SetFanTemperatureTarget,
-				(uint32_t)table->FanTargetTemperature);
+				(uint32_t)table->FanTargetTemperature,
+				NULL);
 
 	table->FanPwmMin = hwmgr->thermal_controller.
 			advanceFanControlParameters.usPWMMin * 255 / 100;
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_baco.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_baco.c
index 9d8ca94a8f0c..bc53cce4f32d 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_baco.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_baco.c
@@ -96,7 +96,7 @@ int vega12_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state)
 	if (state == BACO_STATE_IN) {
 		if (soc15_baco_program_registers(hwmgr, pre_baco_tbl,
 					     ARRAY_SIZE(pre_baco_tbl))) {
-			if (smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_EnterBaco, 0))
+			if (smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_EnterBaco, 0, NULL))
 				return -EINVAL;
 
 			if (soc15_baco_program_registers(hwmgr, enter_baco_tbl,
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c
index aca61d1ff3c2..f4d1692cccf3 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c
@@ -357,10 +357,8 @@ static void vega12_init_dpm_defaults(struct pp_hwmgr *hwmgr)
 	}
 
 	/* Get the SN to turn into a Unique ID */
-	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumTop32);
-	top32 = smum_get_argument(hwmgr);
-	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumBottom32);
-	bottom32 = smum_get_argument(hwmgr);
+	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumTop32, &top32);
+	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumBottom32, &bottom32);
 
 	adev->unique_id = ((uint64_t)bottom32 << 32) | top32;
 }
@@ -483,16 +481,12 @@ static int vega12_get_number_of_dpm_level(struct pp_hwmgr *hwmgr,
 
 	ret = smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_GetDpmFreqByIndex,
-			(clk_id << 16 | 0xFF));
+			(clk_id << 16 | 0xFF),
+			num_of_levels);
 	PP_ASSERT_WITH_CODE(!ret,
 			"[GetNumOfDpmLevel] failed to get dpm levels!",
 			return ret);
 
-	*num_of_levels = smum_get_argument(hwmgr);
-	PP_ASSERT_WITH_CODE(*num_of_levels > 0,
-			"[GetNumOfDpmLevel] number of clk levels is invalid!",
-			return -EINVAL);
-
 	return ret;
 }
 
@@ -504,12 +498,11 @@ static int vega12_get_dpm_frequency_by_index(struct pp_hwmgr *hwmgr,
 	 *Lower 16 bits specify the level
 	 */
 	PP_ASSERT_WITH_CODE(smum_send_msg_to_smc_with_parameter(hwmgr,
-		PPSMC_MSG_GetDpmFreqByIndex, (clkID << 16 | index)) == 0,
+		PPSMC_MSG_GetDpmFreqByIndex, (clkID << 16 | index),
+		clock) == 0,
 		"[GetDpmFrequencyByIndex] Failed to get dpm frequency from SMU!",
 		return -EINVAL);
 
-	*clock = smum_get_argument(hwmgr);
-
 	return 0;
 }
 
@@ -749,7 +742,8 @@ static int vega12_init_smc_table(struct pp_hwmgr *hwmgr)
 		data->vbios_boot_state.vclock = boot_up_values.ulVClk;
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_SetMinDeepSleepDcefclk,
-			(uint32_t)(data->vbios_boot_state.dcef_clock / 100));
+			(uint32_t)(data->vbios_boot_state.dcef_clock / 100),
+				NULL);
 	}
 
 	memcpy(pp_table, pptable_information->smc_pptable, sizeof(PPTable_t));
@@ -767,11 +761,10 @@ static int vega12_run_acg_btc(struct pp_hwmgr *hwmgr)
 	uint32_t result;
 
 	PP_ASSERT_WITH_CODE(
-		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_RunAcgBtc) == 0,
+		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_RunAcgBtc, &result) == 0,
 		"[Run_ACG_BTC] Attempt to run ACG BTC failed!",
 		return -EINVAL);
 
-	result = smum_get_argument(hwmgr);
 	PP_ASSERT_WITH_CODE(result == 1,
 			"Failed to run ACG BTC!", return -EINVAL);
 
@@ -792,12 +785,14 @@ static int vega12_set_allowed_featuresmask(struct pp_hwmgr *hwmgr)
 				(allowed_features_low |= ((data->smu_features[i].smu_feature_bitmap >> SMU_FEATURES_LOW_SHIFT) & 0xFFFFFFFF));
 
 	PP_ASSERT_WITH_CODE(
-		smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetAllowedFeaturesMaskHigh, allowed_features_high) == 0,
+		smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetAllowedFeaturesMaskHigh, allowed_features_high,
+			NULL) == 0,
 		"[SetAllowedFeaturesMask] Attempt to set allowed features mask (high) failed!",
 		return -1);
 
 	PP_ASSERT_WITH_CODE(
-		smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetAllowedFeaturesMaskLow, allowed_features_low) == 0,
+		smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetAllowedFeaturesMaskLow, allowed_features_low,
+			NULL) == 0,
 		"[SetAllowedFeaturesMask] Attempt to set allowed features mask (low) failed!",
 		return -1);
 
@@ -828,7 +823,7 @@ static int vega12_enable_all_smu_features(struct pp_hwmgr *hwmgr)
 	bool enabled;
 
 	PP_ASSERT_WITH_CODE(
-		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_EnableAllSmuFeatures) == 0,
+		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_EnableAllSmuFeatures, NULL) == 0,
 		"[EnableAllSMUFeatures] Failed to enable all smu features!",
 		return -1);
 
@@ -854,7 +849,7 @@ static int vega12_disable_all_smu_features(struct pp_hwmgr *hwmgr)
 	bool enabled;
 
 	PP_ASSERT_WITH_CODE(
-		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_DisableAllSmuFeatures) == 0,
+		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_DisableAllSmuFeatures, NULL) == 0,
 		"[DisableAllSMUFeatures] Failed to disable all smu features!",
 		return -1);
 
@@ -879,7 +874,8 @@ static int vega12_set_overdrive_target_percentage(struct pp_hwmgr *hwmgr,
 		uint32_t adjust_percent)
 {
 	return smum_send_msg_to_smc_with_parameter(hwmgr,
-			PPSMC_MSG_OverDriveSetPercentage, adjust_percent);
+			PPSMC_MSG_OverDriveSetPercentage, adjust_percent,
+			NULL);
 }
 
 static int vega12_power_control_set_level(struct pp_hwmgr *hwmgr)
@@ -902,24 +898,24 @@ static int vega12_get_all_clock_ranges_helper(struct pp_hwmgr *hwmgr,
 {
 	/* AC Max */
 	PP_ASSERT_WITH_CODE(
-		smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetMaxDpmFreq, (clkid << 16)) == 0,
+		smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetMaxDpmFreq, (clkid << 16),
+			&(clock->ACMax)) == 0,
 		"[GetClockRanges] Failed to get max ac clock from SMC!",
 		return -EINVAL);
-	clock->ACMax = smum_get_argument(hwmgr);
 
 	/* AC Min */
 	PP_ASSERT_WITH_CODE(
-		smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetMinDpmFreq, (clkid << 16)) == 0,
+		smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetMinDpmFreq, (clkid << 16),
+			&(clock->ACMin)) == 0,
 		"[GetClockRanges] Failed to get min ac clock from SMC!",
 		return -EINVAL);
-	clock->ACMin = smum_get_argument(hwmgr);
 
 	/* DC Max */
 	PP_ASSERT_WITH_CODE(
-		smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetDcModeMaxDpmFreq, (clkid << 16)) == 0,
+		smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetDcModeMaxDpmFreq, (clkid << 16),
+			&(clock->DCMax)) == 0,
 		"[GetClockRanges] Failed to get max dc clock from SMC!",
 		return -EINVAL);
-	clock->DCMax = smum_get_argument(hwmgr);
 
 	return 0;
 }
@@ -944,7 +940,7 @@ static int vega12_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
 	int tmp_result, result = 0;
 
 	smum_send_msg_to_smc_with_parameter(hwmgr,
-			PPSMC_MSG_NumOfDisplays, 0);
+			PPSMC_MSG_NumOfDisplays, 0, NULL);
 
 	result = vega12_set_allowed_featuresmask(hwmgr);
 	PP_ASSERT_WITH_CODE(result == 0,
@@ -1043,7 +1039,8 @@ static int vega12_upload_dpm_min_level(struct pp_hwmgr *hwmgr)
 		min_freq = data->dpm_table.gfx_table.dpm_state.soft_min_level;
 		PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(
 					hwmgr, PPSMC_MSG_SetSoftMinByFreq,
-					(PPCLK_GFXCLK << 16) | (min_freq & 0xffff))),
+					(PPCLK_GFXCLK << 16) | (min_freq & 0xffff),
+					NULL)),
 					"Failed to set soft min gfxclk !",
 					return ret);
 	}
@@ -1052,14 +1049,16 @@ static int vega12_upload_dpm_min_level(struct pp_hwmgr *hwmgr)
 		min_freq = data->dpm_table.mem_table.dpm_state.soft_min_level;
 		PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(
 					hwmgr, PPSMC_MSG_SetSoftMinByFreq,
-					(PPCLK_UCLK << 16) | (min_freq & 0xffff))),
+					(PPCLK_UCLK << 16) | (min_freq & 0xffff),
+					NULL)),
 					"Failed to set soft min memclk !",
 					return ret);
 
 		min_freq = data->dpm_table.mem_table.dpm_state.hard_min_level;
 		PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(
 					hwmgr, PPSMC_MSG_SetHardMinByFreq,
-					(PPCLK_UCLK << 16) | (min_freq & 0xffff))),
+					(PPCLK_UCLK << 16) | (min_freq & 0xffff),
+					NULL)),
 					"Failed to set hard min memclk !",
 					return ret);
 	}
@@ -1069,7 +1068,8 @@ static int vega12_upload_dpm_min_level(struct pp_hwmgr *hwmgr)
 
 		PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(
 					hwmgr, PPSMC_MSG_SetSoftMinByFreq,
-					(PPCLK_VCLK << 16) | (min_freq & 0xffff))),
+					(PPCLK_VCLK << 16) | (min_freq & 0xffff),
+					NULL)),
 					"Failed to set soft min vclk!",
 					return ret);
 
@@ -1077,7 +1077,8 @@ static int vega12_upload_dpm_min_level(struct pp_hwmgr *hwmgr)
 
 		PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(
 					hwmgr, PPSMC_MSG_SetSoftMinByFreq,
-					(PPCLK_DCLK << 16) | (min_freq & 0xffff))),
+					(PPCLK_DCLK << 16) | (min_freq & 0xffff),
+					NULL)),
 					"Failed to set soft min dclk!",
 					return ret);
 	}
@@ -1087,7 +1088,8 @@ static int vega12_upload_dpm_min_level(struct pp_hwmgr *hwmgr)
 
 		PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(
 					hwmgr, PPSMC_MSG_SetSoftMinByFreq,
-					(PPCLK_ECLK << 16) | (min_freq & 0xffff))),
+					(PPCLK_ECLK << 16) | (min_freq & 0xffff),
+					NULL)),
 					"Failed to set soft min eclk!",
 					return ret);
 	}
@@ -1097,7 +1099,8 @@ static int vega12_upload_dpm_min_level(struct pp_hwmgr *hwmgr)
 
 		PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(
 					hwmgr, PPSMC_MSG_SetSoftMinByFreq,
-					(PPCLK_SOCCLK << 16) | (min_freq & 0xffff))),
+					(PPCLK_SOCCLK << 16) | (min_freq & 0xffff),
+					NULL)),
 					"Failed to set soft min socclk!",
 					return ret);
 	}
@@ -1107,7 +1110,8 @@ static int vega12_upload_dpm_min_level(struct pp_hwmgr *hwmgr)
 
 		PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(
 					hwmgr, PPSMC_MSG_SetHardMinByFreq,
-					(PPCLK_DCEFCLK << 16) | (min_freq & 0xffff))),
+					(PPCLK_DCEFCLK << 16) | (min_freq & 0xffff),
+					NULL)),
 					"Failed to set hard min dcefclk!",
 					return ret);
 	}
@@ -1127,7 +1131,8 @@ static int vega12_upload_dpm_max_level(struct pp_hwmgr *hwmgr)
 
 		PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(
 					hwmgr, PPSMC_MSG_SetSoftMaxByFreq,
-					(PPCLK_GFXCLK << 16) | (max_freq & 0xffff))),
+					(PPCLK_GFXCLK << 16) | (max_freq & 0xffff),
+					NULL)),
 					"Failed to set soft max gfxclk!",
 					return ret);
 	}
@@ -1137,7 +1142,8 @@ static int vega12_upload_dpm_max_level(struct pp_hwmgr *hwmgr)
 
 		PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(
 					hwmgr, PPSMC_MSG_SetSoftMaxByFreq,
-					(PPCLK_UCLK << 16) | (max_freq & 0xffff))),
+					(PPCLK_UCLK << 16) | (max_freq & 0xffff),
+					NULL)),
 					"Failed to set soft max memclk!",
 					return ret);
 	}
@@ -1147,14 +1153,16 @@ static int vega12_upload_dpm_max_level(struct pp_hwmgr *hwmgr)
 
 		PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(
 					hwmgr, PPSMC_MSG_SetSoftMaxByFreq,
-					(PPCLK_VCLK << 16) | (max_freq & 0xffff))),
+					(PPCLK_VCLK << 16) | (max_freq & 0xffff),
+					NULL)),
 					"Failed to set soft max vclk!",
 					return ret);
 
 		max_freq = data->dpm_table.dclk_table.dpm_state.soft_max_level;
 		PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(
 					hwmgr, PPSMC_MSG_SetSoftMaxByFreq,
-					(PPCLK_DCLK << 16) | (max_freq & 0xffff))),
+					(PPCLK_DCLK << 16) | (max_freq & 0xffff),
+					NULL)),
 					"Failed to set soft max dclk!",
 					return ret);
 	}
@@ -1164,7 +1172,8 @@ static int vega12_upload_dpm_max_level(struct pp_hwmgr *hwmgr)
 
 		PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(
 					hwmgr, PPSMC_MSG_SetSoftMaxByFreq,
-					(PPCLK_ECLK << 16) | (max_freq & 0xffff))),
+					(PPCLK_ECLK << 16) | (max_freq & 0xffff),
+					NULL)),
 					"Failed to set soft max eclk!",
 					return ret);
 	}
@@ -1174,7 +1183,8 @@ static int vega12_upload_dpm_max_level(struct pp_hwmgr *hwmgr)
 
 		PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(
 					hwmgr, PPSMC_MSG_SetSoftMaxByFreq,
-					(PPCLK_SOCCLK << 16) | (max_freq & 0xffff))),
+					(PPCLK_SOCCLK << 16) | (max_freq & 0xffff),
+					NULL)),
 					"Failed to set soft max socclk!",
 					return ret);
 	}
@@ -1287,10 +1297,10 @@ static int vega12_get_current_gfx_clk_freq(struct pp_hwmgr *hwmgr, uint32_t *gfx
 	*gfx_freq = 0;
 
 	PP_ASSERT_WITH_CODE(smum_send_msg_to_smc_with_parameter(hwmgr,
-			PPSMC_MSG_GetDpmClockFreq, (PPCLK_GFXCLK << 16)) == 0,
+			PPSMC_MSG_GetDpmClockFreq, (PPCLK_GFXCLK << 16),
+			&gfx_clk) == 0,
 			"[GetCurrentGfxClkFreq] Attempt to get Current GFXCLK Frequency Failed!",
 			return -EINVAL);
-	gfx_clk = smum_get_argument(hwmgr);
 
 	*gfx_freq = gfx_clk * 100;
 
@@ -1304,10 +1314,10 @@ static int vega12_get_current_mclk_freq(struct pp_hwmgr *hwmgr, uint32_t *mclk_f
 	*mclk_freq = 0;
 
 	PP_ASSERT_WITH_CODE(
-			smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetDpmClockFreq, (PPCLK_UCLK << 16)) == 0,
+			smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetDpmClockFreq, (PPCLK_UCLK << 16),
+				&mem_clk) == 0,
 			"[GetCurrentMClkFreq] Attempt to get Current MCLK Frequency Failed!",
 			return -EINVAL);
-	mem_clk = smum_get_argument(hwmgr);
 
 	*mclk_freq = mem_clk * 100;
 
@@ -1420,7 +1430,8 @@ static int vega12_notify_smc_display_change(struct pp_hwmgr *hwmgr,
 	if (data->smu_features[GNLD_DPM_UCLK].enabled)
 		return smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_SetUclkFastSwitch,
-			has_disp ? 1 : 0);
+			has_disp ? 1 : 0,
+			NULL);
 
 	return 0;
 }
@@ -1459,7 +1470,8 @@ int vega12_display_clock_voltage_request(struct pp_hwmgr *hwmgr,
 			clk_request = (clk_select << 16) | clk_freq;
 			result = smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_SetHardMinByFreq,
-					clk_request);
+					clk_request,
+					NULL);
 		}
 	}
 
@@ -1493,7 +1505,8 @@ static int vega12_notify_smc_display_config_after_ps_adjustment(
 				PP_ASSERT_WITH_CODE(
 					!smum_send_msg_to_smc_with_parameter(
 					hwmgr, PPSMC_MSG_SetMinDeepSleepDcefclk,
-					min_clocks.dcefClockInSR /100),
+					min_clocks.dcefClockInSR /100,
+					NULL),
 					"Attempt to set divider for DCEFCLK Failed!",
 					return -1);
 		} else {
@@ -2124,10 +2137,10 @@ static int vega12_print_clock_levels(struct pp_hwmgr *hwmgr,
 	case PP_SOCCLK:
 		PP_ASSERT_WITH_CODE(
 				smum_send_msg_to_smc_with_parameter(hwmgr,
-					PPSMC_MSG_GetDpmClockFreq, (PPCLK_SOCCLK << 16)) == 0,
+					PPSMC_MSG_GetDpmClockFreq, (PPCLK_SOCCLK << 16),
+					&now) == 0,
 				"Attempt to get Current SOCCLK Frequency Failed!",
 				return -EINVAL);
-		now = smum_get_argument(hwmgr);
 
 		PP_ASSERT_WITH_CODE(
 				vega12_get_socclocks(hwmgr, &clocks) == 0,
@@ -2142,10 +2155,10 @@ static int vega12_print_clock_levels(struct pp_hwmgr *hwmgr,
 	case PP_DCEFCLK:
 		PP_ASSERT_WITH_CODE(
 				smum_send_msg_to_smc_with_parameter(hwmgr,
-					PPSMC_MSG_GetDpmClockFreq, (PPCLK_DCEFCLK << 16)) == 0,
+					PPSMC_MSG_GetDpmClockFreq, (PPCLK_DCEFCLK << 16),
+					&now) == 0,
 				"Attempt to get Current DCEFCLK Frequency Failed!",
 				return -EINVAL);
-		now = smum_get_argument(hwmgr);
 
 		PP_ASSERT_WITH_CODE(
 				vega12_get_dcefclocks(hwmgr, &clocks) == 0,
@@ -2343,7 +2356,8 @@ static int vega12_set_uclk_to_highest_dpm_level(struct pp_hwmgr *hwmgr,
 		dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[dpm_table->count - 1].value;
 		PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_SetHardMinByFreq,
-				(PPCLK_UCLK << 16 ) | dpm_table->dpm_state.hard_min_level)),
+				(PPCLK_UCLK << 16 ) | dpm_table->dpm_state.hard_min_level,
+				NULL)),
 				"[SetUclkToHightestDpmLevel] Set hard min uclk failed!",
 				return ret);
 	}
@@ -2357,7 +2371,8 @@ static int vega12_pre_display_configuration_changed_task(struct pp_hwmgr *hwmgr)
 	int ret = 0;
 
 	smum_send_msg_to_smc_with_parameter(hwmgr,
-			PPSMC_MSG_NumOfDisplays, 0);
+			PPSMC_MSG_NumOfDisplays, 0,
+			NULL);
 
 	ret = vega12_set_uclk_to_highest_dpm_level(hwmgr,
 			&data->dpm_table.mem_table);
@@ -2383,7 +2398,8 @@ static int vega12_display_configuration_changed_task(struct pp_hwmgr *hwmgr)
 		data->smu_features[GNLD_DPM_DCEFCLK].supported &&
 		data->smu_features[GNLD_DPM_SOCCLK].supported)
 		smum_send_msg_to_smc_with_parameter(hwmgr,
-			PPSMC_MSG_NumOfDisplays, hwmgr->display_config->num_display);
+			PPSMC_MSG_NumOfDisplays, hwmgr->display_config->num_display,
+			NULL);
 
 	return result;
 }
@@ -2555,21 +2571,26 @@ static int vega12_notify_cac_buffer_info(struct pp_hwmgr *hwmgr,
 {
 	smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_SetSystemVirtualDramAddrHigh,
-					virtual_addr_hi);
+					virtual_addr_hi,
+					NULL);
 	smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_SetSystemVirtualDramAddrLow,
-					virtual_addr_low);
+					virtual_addr_low,
+					NULL);
 	smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_DramLogSetDramAddrHigh,
-					mc_addr_hi);
+					mc_addr_hi,
+					NULL);
 
 	smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_DramLogSetDramAddrLow,
-					mc_addr_low);
+					mc_addr_low,
+					NULL);
 
 	smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_DramLogSetDramSize,
-					size);
+					size,
+					NULL);
 	return 0;
 }
 
@@ -2605,7 +2626,7 @@ static int vega12_enable_gfx_off(struct pp_hwmgr *hwmgr)
 	int ret = 0;
 
 	if (data->gfxoff_controlled_by_driver)
-		ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_AllowGfxOff);
+		ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_AllowGfxOff, NULL);
 
 	return ret;
 }
@@ -2617,7 +2638,7 @@ static int vega12_disable_gfx_off(struct pp_hwmgr *hwmgr)
 	int ret = 0;
 
 	if (data->gfxoff_controlled_by_driver)
-		ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_DisallowGfxOff);
+		ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_DisallowGfxOff, NULL);
 
 	return ret;
 }
@@ -2654,7 +2675,7 @@ static int vega12_set_mp1_state(struct pp_hwmgr *hwmgr,
 		return 0;
 	}
 
-	PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc(hwmgr, msg)) == 0,
+	PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc(hwmgr, msg, NULL)) == 0,
 			    "[PrepareMp1] Failed!",
 			    return ret);
 
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_thermal.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_thermal.c
index 904eb2c9155b..c85806a6f62e 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_thermal.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_thermal.c
@@ -32,10 +32,10 @@
 static int vega12_get_current_rpm(struct pp_hwmgr *hwmgr, uint32_t *current_rpm)
 {
 	PP_ASSERT_WITH_CODE(!smum_send_msg_to_smc(hwmgr,
-				PPSMC_MSG_GetCurrentRpm),
+				PPSMC_MSG_GetCurrentRpm,
+				current_rpm),
 			"Attempt to get current RPM from SMC Failed!",
 			return -EINVAL);
-	*current_rpm = smum_get_argument(hwmgr);
 
 	return 0;
 }
@@ -259,7 +259,8 @@ int vega12_thermal_setup_fan_table(struct pp_hwmgr *hwmgr)
 
 	ret = smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_SetFanTemperatureTarget,
-				(uint32_t)table->FanTargetTemperature);
+				(uint32_t)table->FanTargetTemperature,
+				NULL);
 
 	return ret;
 }
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_baco.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_baco.c
index 9b5e72bdceca..2a28c9df15a0 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_baco.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_baco.c
@@ -91,16 +91,16 @@ int vega20_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state)
 			WREG32_SOC15(THM, 0, mmTHM_BACO_CNTL, data);
 
 			if(smum_send_msg_to_smc_with_parameter(hwmgr,
-					PPSMC_MSG_EnterBaco, 0))
+					PPSMC_MSG_EnterBaco, 0, NULL))
 				return -EINVAL;
 		} else {
 			if(smum_send_msg_to_smc_with_parameter(hwmgr,
-					PPSMC_MSG_EnterBaco, 1))
+					PPSMC_MSG_EnterBaco, 1, NULL))
 				return -EINVAL;
 		}
 
 	} else if (state == BACO_STATE_OUT) {
-		if (smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ExitBaco))
+		if (smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ExitBaco, NULL))
 			return -EINVAL;
 		if (!soc15_baco_program_registers(hwmgr, clean_baco_tbl,
 						     ARRAY_SIZE(clean_baco_tbl)))
@@ -118,5 +118,5 @@ int vega20_baco_apply_vdci_flush_workaround(struct pp_hwmgr *hwmgr)
 	if (ret)
 		return ret;
 
-	return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_BacoWorkAroundFlushVDCI);
+	return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_BacoWorkAroundFlushVDCI, NULL);
 }
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
index 08b6ba39a6d7..9ff470f1b826 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
@@ -92,8 +92,7 @@ static void vega20_set_default_registry_data(struct pp_hwmgr *hwmgr)
 	 */
 	data->registry_data.disallowed_features = 0xE0041C00;
 	/* ECC feature should be disabled on old SMUs */
-	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetSmuVersion);
-	hwmgr->smu_version = smum_get_argument(hwmgr);
+	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetSmuVersion, &hwmgr->smu_version);
 	if (hwmgr->smu_version < 0x282100)
 		data->registry_data.disallowed_features |= FEATURE_ECC_MASK;
 
@@ -400,10 +399,8 @@ static void vega20_init_dpm_defaults(struct pp_hwmgr *hwmgr)
 	}
 
 	/* Get the SN to turn into a Unique ID */
-	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumTop32);
-	top32 = smum_get_argument(hwmgr);
-	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumBottom32);
-	bottom32 = smum_get_argument(hwmgr);
+	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumTop32, &top32);
+	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumBottom32, &bottom32);
 
 	adev->unique_id = ((uint64_t)bottom32 << 32) | top32;
 }
@@ -527,16 +524,12 @@ static int vega20_get_number_of_dpm_level(struct pp_hwmgr *hwmgr,
 
 	ret = smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_GetDpmFreqByIndex,
-			(clk_id << 16 | 0xFF));
+			(clk_id << 16 | 0xFF),
+			num_of_levels);
 	PP_ASSERT_WITH_CODE(!ret,
 			"[GetNumOfDpmLevel] failed to get dpm levels!",
 			return ret);
 
-	*num_of_levels = smum_get_argument(hwmgr);
-	PP_ASSERT_WITH_CODE(*num_of_levels > 0,
-			"[GetNumOfDpmLevel] number of clk levels is invalid!",
-			return -EINVAL);
-
 	return ret;
 }
 
@@ -547,16 +540,12 @@ static int vega20_get_dpm_frequency_by_index(struct pp_hwmgr *hwmgr,
 
 	ret = smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_GetDpmFreqByIndex,
-			(clk_id << 16 | index));
+			(clk_id << 16 | index),
+			clk);
 	PP_ASSERT_WITH_CODE(!ret,
 			"[GetDpmFreqByIndex] failed to get dpm freq by index!",
 			return ret);
 
-	*clk = smum_get_argument(hwmgr);
-	PP_ASSERT_WITH_CODE(*clk,
-			"[GetDpmFreqByIndex] clk value is invalid!",
-			return -EINVAL);
-
 	return ret;
 }
 
@@ -813,7 +802,8 @@ static int vega20_init_smc_table(struct pp_hwmgr *hwmgr)
 
 	smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_SetMinDeepSleepDcefclk,
-		(uint32_t)(data->vbios_boot_state.dcef_clock / 100));
+		(uint32_t)(data->vbios_boot_state.dcef_clock / 100),
+			NULL);
 
 	memcpy(pp_table, pptable_information->smc_pptable, sizeof(PPTable_t));
 
@@ -868,7 +858,8 @@ static int vega20_override_pcie_parameters(struct pp_hwmgr *hwmgr)
 	 */
 	smu_pcie_arg = (1 << 16) | (pcie_gen << 8) | pcie_width;
 	ret = smum_send_msg_to_smc_with_parameter(hwmgr,
-			PPSMC_MSG_OverridePcieParameters, smu_pcie_arg);
+			PPSMC_MSG_OverridePcieParameters, smu_pcie_arg,
+			NULL);
 	PP_ASSERT_WITH_CODE(!ret,
 		"[OverridePcieParameters] Attempt to override pcie params failed!",
 		return ret);
@@ -899,13 +890,13 @@ static int vega20_set_allowed_featuresmask(struct pp_hwmgr *hwmgr)
 				  & 0xFFFFFFFF));
 
 	ret = smum_send_msg_to_smc_with_parameter(hwmgr,
-		PPSMC_MSG_SetAllowedFeaturesMaskHigh, allowed_features_high);
+		PPSMC_MSG_SetAllowedFeaturesMaskHigh, allowed_features_high, NULL);
 	PP_ASSERT_WITH_CODE(!ret,
 		"[SetAllowedFeaturesMask] Attempt to set allowed features mask(high) failed!",
 		return ret);
 
 	ret = smum_send_msg_to_smc_with_parameter(hwmgr,
-		PPSMC_MSG_SetAllowedFeaturesMaskLow, allowed_features_low);
+		PPSMC_MSG_SetAllowedFeaturesMaskLow, allowed_features_low, NULL);
 	PP_ASSERT_WITH_CODE(!ret,
 		"[SetAllowedFeaturesMask] Attempt to set allowed features mask (low) failed!",
 		return ret);
@@ -915,12 +906,12 @@ static int vega20_set_allowed_featuresmask(struct pp_hwmgr *hwmgr)
 
 static int vega20_run_btc(struct pp_hwmgr *hwmgr)
 {
-	return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_RunBtc);
+	return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_RunBtc, NULL);
 }
 
 static int vega20_run_btc_afll(struct pp_hwmgr *hwmgr)
 {
-	return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_RunAfllBtc);
+	return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_RunAfllBtc, NULL);
 }
 
 static int vega20_enable_all_smu_features(struct pp_hwmgr *hwmgr)
@@ -933,7 +924,8 @@ static int vega20_enable_all_smu_features(struct pp_hwmgr *hwmgr)
 	int ret = 0;
 
 	PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc(hwmgr,
-			PPSMC_MSG_EnableAllSmuFeatures)) == 0,
+			PPSMC_MSG_EnableAllSmuFeatures,
+			NULL)) == 0,
 			"[EnableAllSMUFeatures] Failed to enable all smu features!",
 			return ret);
 
@@ -966,7 +958,8 @@ static int vega20_notify_smc_display_change(struct pp_hwmgr *hwmgr)
 	if (data->smu_features[GNLD_DPM_UCLK].enabled)
 		return smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_SetUclkFastSwitch,
-			1);
+			1,
+			NULL);
 
 	return 0;
 }
@@ -978,7 +971,8 @@ static int vega20_send_clock_ratio(struct pp_hwmgr *hwmgr)
 
 	return smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_SetFclkGfxClkRatio,
-			data->registry_data.fclk_gfxclk_ratio);
+			data->registry_data.fclk_gfxclk_ratio,
+			NULL);
 }
 
 static int vega20_disable_all_smu_features(struct pp_hwmgr *hwmgr)
@@ -991,7 +985,8 @@ static int vega20_disable_all_smu_features(struct pp_hwmgr *hwmgr)
 	int ret = 0;
 
 	PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc(hwmgr,
-			PPSMC_MSG_DisableAllSmuFeatures)) == 0,
+			PPSMC_MSG_DisableAllSmuFeatures,
+			NULL)) == 0,
 			"[DisableAllSMUFeatures] Failed to disable all smu features!",
 			return ret);
 
@@ -1199,12 +1194,12 @@ static int vega20_od8_get_gfx_clock_base_voltage(
 
 	ret = smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_GetAVFSVoltageByDpm,
-			((AVFS_CURVE << 24) | (OD8_HOTCURVE_TEMPERATURE << 16) | freq));
+			((AVFS_CURVE << 24) | (OD8_HOTCURVE_TEMPERATURE << 16) | freq),
+			voltage);
 	PP_ASSERT_WITH_CODE(!ret,
 			"[GetBaseVoltage] failed to get GFXCLK AVFS voltage from SMU!",
 			return ret);
 
-	*voltage = smum_get_argument(hwmgr);
 	*voltage = *voltage / VOLTAGE_SCALE;
 
 	return 0;
@@ -1560,19 +1555,19 @@ static int vega20_get_max_sustainable_clock(struct pp_hwmgr *hwmgr,
 
 	PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_GetDcModeMaxDpmFreq,
-			(clock_select << 16))) == 0,
+			(clock_select << 16),
+			clock)) == 0,
 			"[GetMaxSustainableClock] Failed to get max DC clock from SMC!",
 			return ret);
-	*clock = smum_get_argument(hwmgr);
 
 	/* if DC limit is zero, return AC limit */
 	if (*clock == 0) {
 		PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_GetMaxDpmFreq,
-			(clock_select << 16))) == 0,
+			(clock_select << 16),
+			clock)) == 0,
 			"[GetMaxSustainableClock] failed to get max AC clock from SMC!",
 			return ret);
-		*clock = smum_get_argument(hwmgr);
 	}
 
 	return 0;
@@ -1641,7 +1636,8 @@ static int vega20_enable_mgpu_fan_boost(struct pp_hwmgr *hwmgr)
 	int result;
 
 	result = smum_send_msg_to_smc(hwmgr,
-		PPSMC_MSG_SetMGpuFanBoostLimitRpm);
+		PPSMC_MSG_SetMGpuFanBoostLimitRpm,
+		NULL);
 	PP_ASSERT_WITH_CODE(!result,
 			"[EnableMgpuFan] Failed to enable mgpu fan boost!",
 			return result);
@@ -1669,7 +1665,7 @@ static int vega20_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
 	int result = 0;
 
 	smum_send_msg_to_smc_with_parameter(hwmgr,
-			PPSMC_MSG_NumOfDisplays, 0);
+			PPSMC_MSG_NumOfDisplays, 0, NULL);
 
 	result = vega20_set_allowed_featuresmask(hwmgr);
 	PP_ASSERT_WITH_CODE(!result,
@@ -1740,12 +1736,12 @@ static int vega20_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
 			return result);
 
 	result = smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetPptLimit,
-			POWER_SOURCE_AC << 16);
+			POWER_SOURCE_AC << 16, &hwmgr->default_power_limit);
 	PP_ASSERT_WITH_CODE(!result,
 			"[GetPptLimit] get default PPT limit failed!",
 			return result);
 	hwmgr->power_limit =
-		hwmgr->default_power_limit = smum_get_argument(hwmgr);
+		hwmgr->default_power_limit;
 
 	return 0;
 }
@@ -1806,7 +1802,8 @@ static int vega20_upload_dpm_min_level(struct pp_hwmgr *hwmgr, uint32_t feature_
 		min_freq = data->dpm_table.gfx_table.dpm_state.soft_min_level;
 		PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(
 					hwmgr, PPSMC_MSG_SetSoftMinByFreq,
-					(PPCLK_GFXCLK << 16) | (min_freq & 0xffff))),
+					(PPCLK_GFXCLK << 16) | (min_freq & 0xffff),
+					NULL)),
 					"Failed to set soft min gfxclk !",
 					return ret);
 	}
@@ -1816,7 +1813,8 @@ static int vega20_upload_dpm_min_level(struct pp_hwmgr *hwmgr, uint32_t feature_
 		min_freq = data->dpm_table.mem_table.dpm_state.soft_min_level;
 		PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(
 					hwmgr, PPSMC_MSG_SetSoftMinByFreq,
-					(PPCLK_UCLK << 16) | (min_freq & 0xffff))),
+					(PPCLK_UCLK << 16) | (min_freq & 0xffff),
+					NULL)),
 					"Failed to set soft min memclk !",
 					return ret);
 	}
@@ -1827,7 +1825,8 @@ static int vega20_upload_dpm_min_level(struct pp_hwmgr *hwmgr, uint32_t feature_
 
 		PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(
 					hwmgr, PPSMC_MSG_SetSoftMinByFreq,
-					(PPCLK_VCLK << 16) | (min_freq & 0xffff))),
+					(PPCLK_VCLK << 16) | (min_freq & 0xffff),
+					NULL)),
 					"Failed to set soft min vclk!",
 					return ret);
 
@@ -1835,7 +1834,8 @@ static int vega20_upload_dpm_min_level(struct pp_hwmgr *hwmgr, uint32_t feature_
 
 		PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(
 					hwmgr, PPSMC_MSG_SetSoftMinByFreq,
-					(PPCLK_DCLK << 16) | (min_freq & 0xffff))),
+					(PPCLK_DCLK << 16) | (min_freq & 0xffff),
+					NULL)),
 					"Failed to set soft min dclk!",
 					return ret);
 	}
@@ -1846,7 +1846,8 @@ static int vega20_upload_dpm_min_level(struct pp_hwmgr *hwmgr, uint32_t feature_
 
 		PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(
 					hwmgr, PPSMC_MSG_SetSoftMinByFreq,
-					(PPCLK_ECLK << 16) | (min_freq & 0xffff))),
+					(PPCLK_ECLK << 16) | (min_freq & 0xffff),
+					NULL)),
 					"Failed to set soft min eclk!",
 					return ret);
 	}
@@ -1857,7 +1858,8 @@ static int vega20_upload_dpm_min_level(struct pp_hwmgr *hwmgr, uint32_t feature_
 
 		PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(
 					hwmgr, PPSMC_MSG_SetSoftMinByFreq,
-					(PPCLK_SOCCLK << 16) | (min_freq & 0xffff))),
+					(PPCLK_SOCCLK << 16) | (min_freq & 0xffff),
+					NULL)),
 					"Failed to set soft min socclk!",
 					return ret);
 	}
@@ -1868,7 +1870,8 @@ static int vega20_upload_dpm_min_level(struct pp_hwmgr *hwmgr, uint32_t feature_
 
 		PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(
 					hwmgr, PPSMC_MSG_SetSoftMinByFreq,
-					(PPCLK_FCLK << 16) | (min_freq & 0xffff))),
+					(PPCLK_FCLK << 16) | (min_freq & 0xffff),
+					NULL)),
 					"Failed to set soft min fclk!",
 					return ret);
 	}
@@ -1879,7 +1882,8 @@ static int vega20_upload_dpm_min_level(struct pp_hwmgr *hwmgr, uint32_t feature_
 
 		PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(
 					hwmgr, PPSMC_MSG_SetHardMinByFreq,
-					(PPCLK_DCEFCLK << 16) | (min_freq & 0xffff))),
+					(PPCLK_DCEFCLK << 16) | (min_freq & 0xffff),
+					NULL)),
 					"Failed to set hard min dcefclk!",
 					return ret);
 	}
@@ -1900,7 +1904,8 @@ static int vega20_upload_dpm_max_level(struct pp_hwmgr *hwmgr, uint32_t feature_
 
 		PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(
 					hwmgr, PPSMC_MSG_SetSoftMaxByFreq,
-					(PPCLK_GFXCLK << 16) | (max_freq & 0xffff))),
+					(PPCLK_GFXCLK << 16) | (max_freq & 0xffff),
+					NULL)),
 					"Failed to set soft max gfxclk!",
 					return ret);
 	}
@@ -1911,7 +1916,8 @@ static int vega20_upload_dpm_max_level(struct pp_hwmgr *hwmgr, uint32_t feature_
 
 		PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(
 					hwmgr, PPSMC_MSG_SetSoftMaxByFreq,
-					(PPCLK_UCLK << 16) | (max_freq & 0xffff))),
+					(PPCLK_UCLK << 16) | (max_freq & 0xffff),
+					NULL)),
 					"Failed to set soft max memclk!",
 					return ret);
 	}
@@ -1922,14 +1928,16 @@ static int vega20_upload_dpm_max_level(struct pp_hwmgr *hwmgr, uint32_t feature_
 
 		PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(
 					hwmgr, PPSMC_MSG_SetSoftMaxByFreq,
-					(PPCLK_VCLK << 16) | (max_freq & 0xffff))),
+					(PPCLK_VCLK << 16) | (max_freq & 0xffff),
+					NULL)),
 					"Failed to set soft max vclk!",
 					return ret);
 
 		max_freq = data->dpm_table.dclk_table.dpm_state.soft_max_level;
 		PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(
 					hwmgr, PPSMC_MSG_SetSoftMaxByFreq,
-					(PPCLK_DCLK << 16) | (max_freq & 0xffff))),
+					(PPCLK_DCLK << 16) | (max_freq & 0xffff),
+					NULL)),
 					"Failed to set soft max dclk!",
 					return ret);
 	}
@@ -1940,7 +1948,8 @@ static int vega20_upload_dpm_max_level(struct pp_hwmgr *hwmgr, uint32_t feature_
 
 		PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(
 					hwmgr, PPSMC_MSG_SetSoftMaxByFreq,
-					(PPCLK_ECLK << 16) | (max_freq & 0xffff))),
+					(PPCLK_ECLK << 16) | (max_freq & 0xffff),
+					NULL)),
 					"Failed to set soft max eclk!",
 					return ret);
 	}
@@ -1951,7 +1960,8 @@ static int vega20_upload_dpm_max_level(struct pp_hwmgr *hwmgr, uint32_t feature_
 
 		PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(
 					hwmgr, PPSMC_MSG_SetSoftMaxByFreq,
-					(PPCLK_SOCCLK << 16) | (max_freq & 0xffff))),
+					(PPCLK_SOCCLK << 16) | (max_freq & 0xffff),
+					NULL)),
 					"Failed to set soft max socclk!",
 					return ret);
 	}
@@ -1962,7 +1972,8 @@ static int vega20_upload_dpm_max_level(struct pp_hwmgr *hwmgr, uint32_t feature_
 
 		PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(
 					hwmgr, PPSMC_MSG_SetSoftMaxByFreq,
-					(PPCLK_FCLK << 16) | (max_freq & 0xffff))),
+					(PPCLK_FCLK << 16) | (max_freq & 0xffff),
+					NULL)),
 					"Failed to set soft max fclk!",
 					return ret);
 	}
@@ -2006,17 +2017,17 @@ static int vega20_get_clock_ranges(struct pp_hwmgr *hwmgr,
 
 	if (max) {
 		PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
-				PPSMC_MSG_GetMaxDpmFreq, (clock_select << 16))) == 0,
+				PPSMC_MSG_GetMaxDpmFreq, (clock_select << 16),
+				clock)) == 0,
 				"[GetClockRanges] Failed to get max clock from SMC!",
 				return ret);
-		*clock = smum_get_argument(hwmgr);
 	} else {
 		PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_GetMinDpmFreq,
-				(clock_select << 16))) == 0,
+				(clock_select << 16),
+				clock)) == 0,
 				"[GetClockRanges] Failed to get min clock from SMC!",
 				return ret);
-		*clock = smum_get_argument(hwmgr);
 	}
 
 	return 0;
@@ -2122,10 +2133,10 @@ static int vega20_get_current_clk_freq(struct pp_hwmgr *hwmgr,
 	*clk_freq = 0;
 
 	PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
-			PPSMC_MSG_GetDpmClockFreq, (clk_id << 16))) == 0,
+			PPSMC_MSG_GetDpmClockFreq, (clk_id << 16),
+			clk_freq)) == 0,
 			"[GetCurrentClkFreq] Attempt to get Current Frequency Failed!",
 			return ret);
-	*clk_freq = smum_get_argument(hwmgr);
 
 	*clk_freq = *clk_freq * 100;
 
@@ -2276,7 +2287,8 @@ int vega20_display_clock_voltage_request(struct pp_hwmgr *hwmgr,
 			clk_request = (clk_select << 16) | clk_freq;
 			result = smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_SetHardMinByFreq,
-					clk_request);
+					clk_request,
+					NULL);
 		}
 	}
 
@@ -2312,7 +2324,8 @@ static int vega20_notify_smc_display_config_after_ps_adjustment(
 			if (data->smu_features[GNLD_DS_DCEFCLK].supported)
 				PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(
 					hwmgr, PPSMC_MSG_SetMinDeepSleepDcefclk,
-					min_clocks.dcefClockInSR / 100)) == 0,
+					min_clocks.dcefClockInSR / 100,
+					NULL)) == 0,
 					"Attempt to set divider for DCEFCLK Failed!",
 					return ret);
 		} else {
@@ -2324,7 +2337,8 @@ static int vega20_notify_smc_display_config_after_ps_adjustment(
 		dpm_table->dpm_state.hard_min_level = min_clocks.memoryClock / 100;
 		PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_SetHardMinByFreq,
-				(PPCLK_UCLK << 16 ) | dpm_table->dpm_state.hard_min_level)),
+				(PPCLK_UCLK << 16 ) | dpm_table->dpm_state.hard_min_level,
+				NULL)),
 				"[SetHardMinFreq] Set hard min uclk failed!",
 				return ret);
 	}
@@ -2656,7 +2670,8 @@ static int vega20_force_clock_level(struct pp_hwmgr *hwmgr,
 			return -EINVAL;
 
 		ret = smum_send_msg_to_smc_with_parameter(hwmgr,
-			PPSMC_MSG_SetMinLinkDpmByIndex, soft_min_level);
+			PPSMC_MSG_SetMinLinkDpmByIndex, soft_min_level,
+			NULL);
 		PP_ASSERT_WITH_CODE(!ret,
 			"Failed to set min link dpm level!",
 			return ret);
@@ -3140,7 +3155,7 @@ static int vega20_set_mp1_state(struct pp_hwmgr *hwmgr,
 		return 0;
 	}
 
-	PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc(hwmgr, msg)) == 0,
+	PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc(hwmgr, msg, NULL)) == 0,
 			    "[PrepareMp1] Failed!",
 			    return ret);
 
@@ -3495,7 +3510,8 @@ static int vega20_set_uclk_to_highest_dpm_level(struct pp_hwmgr *hwmgr,
 		dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[dpm_table->count - 1].value;
 		PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_SetHardMinByFreq,
-				(PPCLK_UCLK << 16 ) | dpm_table->dpm_state.hard_min_level)),
+				(PPCLK_UCLK << 16 ) | dpm_table->dpm_state.hard_min_level,
+				NULL)),
 				"[SetUclkToHightestDpmLevel] Set hard min uclk failed!",
 				return ret);
 	}
@@ -3520,7 +3536,8 @@ static int vega20_set_fclk_to_highest_dpm_level(struct pp_hwmgr *hwmgr)
 		dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[dpm_table->count - 1].value;
 		PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_SetSoftMinByFreq,
-				(PPCLK_FCLK << 16 ) | dpm_table->dpm_state.soft_min_level)),
+				(PPCLK_FCLK << 16 ) | dpm_table->dpm_state.soft_min_level,
+				NULL)),
 				"[SetFclkToHightestDpmLevel] Set soft min fclk failed!",
 				return ret);
 	}
@@ -3534,7 +3551,7 @@ static int vega20_pre_display_configuration_changed_task(struct pp_hwmgr *hwmgr)
 	int ret = 0;
 
 	smum_send_msg_to_smc_with_parameter(hwmgr,
-			PPSMC_MSG_NumOfDisplays, 0);
+			PPSMC_MSG_NumOfDisplays, 0, NULL);
 
 	ret = vega20_set_uclk_to_highest_dpm_level(hwmgr,
 			&data->dpm_table.mem_table);
@@ -3565,7 +3582,8 @@ static int vega20_display_configuration_changed_task(struct pp_hwmgr *hwmgr)
 	    data->smu_features[GNLD_DPM_SOCCLK].supported) {
 		result = smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_NumOfDisplays,
-			hwmgr->display_config->num_display);
+			hwmgr->display_config->num_display,
+			NULL);
 	}
 
 	return result;
@@ -4082,7 +4100,8 @@ static int vega20_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, ui
 	workload_type =
 		conv_power_profile_to_pplib_workload(power_profile_mode);
 	smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetWorkloadMask,
-						1 << workload_type);
+						1 << workload_type,
+						NULL);
 
 	hwmgr->power_profile_mode = power_profile_mode;
 
@@ -4098,21 +4117,26 @@ static int vega20_notify_cac_buffer_info(struct pp_hwmgr *hwmgr,
 {
 	smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_SetSystemVirtualDramAddrHigh,
-					virtual_addr_hi);
+					virtual_addr_hi,
+					NULL);
 	smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_SetSystemVirtualDramAddrLow,
-					virtual_addr_low);
+					virtual_addr_low,
+					NULL);
 	smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_DramLogSetDramAddrHigh,
-					mc_addr_hi);
+					mc_addr_hi,
+					NULL);
 
 	smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_DramLogSetDramAddrLow,
-					mc_addr_low);
+					mc_addr_low,
+					NULL);
 
 	smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_DramLogSetDramSize,
-					size);
+					size,
+					NULL);
 	return 0;
 }
 
@@ -4153,7 +4177,8 @@ static int vega20_smu_i2c_bus_access(struct pp_hwmgr *hwmgr, bool acquire)
 						  (acquire ?
 						  PPSMC_MSG_RequestI2CBus :
 						  PPSMC_MSG_ReleaseI2CBus),
-						  0);
+						  0,
+						  NULL);
 
 	PP_ASSERT_WITH_CODE(!res, "[SmuI2CAccessBus] Failed to access bus!", return res);
 	return res;
@@ -4170,7 +4195,8 @@ static int vega20_set_df_cstate(struct pp_hwmgr *hwmgr,
 		return -EINVAL;
 	}
 
-	ret = smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_DFCstateControl, state);
+	ret = smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_DFCstateControl, state,
+				NULL);
 	if (ret)
 		pr_err("SetDfCstate failed!\n");
 
@@ -4184,7 +4210,8 @@ static int vega20_set_xgmi_pstate(struct pp_hwmgr *hwmgr,
 
 	ret = smum_send_msg_to_smc_with_parameter(hwmgr,
 						  PPSMC_MSG_SetXgmiMode,
-						  pstate ? XGMI_MODE_PSTATE_D0 : XGMI_MODE_PSTATE_D3);
+						  pstate ? XGMI_MODE_PSTATE_D0 : XGMI_MODE_PSTATE_D3,
+						  NULL);
 	if (ret)
 		pr_err("SetXgmiPstate failed!\n");
 
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_powertune.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_powertune.c
index a0bfb65cc5d6..d7cc3d2d9e17 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_powertune.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_powertune.c
@@ -36,7 +36,8 @@ int vega20_set_power_limit(struct pp_hwmgr *hwmgr, uint32_t n)
 
 	if (data->smu_features[GNLD_PPT].enabled)
 		return smum_send_msg_to_smc_with_parameter(hwmgr,
-				PPSMC_MSG_SetPptLimit, n);
+				PPSMC_MSG_SetPptLimit, n,
+				NULL);
 
 	return 0;
 }
@@ -51,7 +52,8 @@ static int vega20_set_overdrive_target_percentage(struct pp_hwmgr *hwmgr,
 		uint32_t adjust_percent)
 {
 	return smum_send_msg_to_smc_with_parameter(hwmgr,
-			PPSMC_MSG_OverDriveSetPercentage, adjust_percent);
+			PPSMC_MSG_OverDriveSetPercentage, adjust_percent,
+			NULL);
 }
 
 int vega20_power_control_set_level(struct pp_hwmgr *hwmgr)
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_thermal.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_thermal.c
index ede54e87e287..7add2f60f49c 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_thermal.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_thermal.c
@@ -106,10 +106,10 @@ static int vega20_get_current_rpm(struct pp_hwmgr *hwmgr, uint32_t *current_rpm)
 	int ret = 0;
 
 	PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc(hwmgr,
-				PPSMC_MSG_GetCurrentRpm)) == 0,
+				PPSMC_MSG_GetCurrentRpm,
+				current_rpm)) == 0,
 			"Attempt to get current RPM from SMC Failed!",
 			return ret);
-	*current_rpm = smum_get_argument(hwmgr);
 
 	return 0;
 }
@@ -329,7 +329,8 @@ static int vega20_thermal_setup_fan_table(struct pp_hwmgr *hwmgr)
 
 	ret = smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_SetFanTemperatureTarget,
-				(uint32_t)table->FanTargetTemperature);
+				(uint32_t)table->FanTargetTemperature,
+				NULL);
 
 	return ret;
 }
diff --git a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
index ae2c318dd6fa..928eed220f93 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
@@ -405,7 +405,9 @@ struct smu_context
 	bool pm_enabled;
 	bool is_apu;
 
-	uint32_t smc_if_version;
+	uint32_t smc_driver_if_version;
+	uint32_t smc_fw_if_version;
+	uint32_t smc_fw_version;
 
 	bool uploading_custom_pp_table;
 	bool dc_controlled_by_gpio;
@@ -580,11 +582,6 @@ int smu_check_fw_status(struct smu_context *smu);
 
 int smu_set_gfx_cgpg(struct smu_context *smu, bool enabled);
 
-#define smu_i2c_eeprom_init(smu, control) \
-		((smu)->ppt_funcs->i2c_eeprom_init ? (smu)->ppt_funcs->i2c_eeprom_init((control)) : -EINVAL)
-#define smu_i2c_eeprom_fini(smu, control) \
-		((smu)->ppt_funcs->i2c_eeprom_fini ? (smu)->ppt_funcs->i2c_eeprom_fini((control)) : -EINVAL)
-
 int smu_set_fan_speed_rpm(struct smu_context *smu, uint32_t speed);
 
 int smu_get_power_limit(struct smu_context *smu,
diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
index 2ffb666b97e6..15ed6cbdf366 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
@@ -743,6 +743,7 @@ struct pp_hwmgr {
 	bool pm_en;
 	bool pp_one_vf;
 	struct mutex smu_lock;
+	struct mutex msg_lock;
 
 	uint32_t pp_table_version;
 	void *device;
diff --git a/drivers/gpu/drm/amd/powerplay/inc/smu11_driver_if_arcturus.h b/drivers/gpu/drm/amd/powerplay/inc/smu11_driver_if_arcturus.h
index ce5b5011c122..8b82059d97e7 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/smu11_driver_if_arcturus.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/smu11_driver_if_arcturus.h
@@ -82,8 +82,8 @@
 // Other
 #define FEATURE_OUT_OF_BAND_MONITOR_BIT 24
 #define FEATURE_TEMP_DEPENDENT_VMIN_BIT 25
+#define FEATURE_PER_PART_VMIN_BIT       26
 
-#define FEATURE_SPARE_26_BIT            26
 #define FEATURE_SPARE_27_BIT            27
 #define FEATURE_SPARE_28_BIT            28
 #define FEATURE_SPARE_29_BIT            29
@@ -154,6 +154,7 @@
 
 #define FEATURE_OUT_OF_BAND_MONITOR_MASK  (1 << FEATURE_OUT_OF_BAND_MONITOR_BIT   )
 #define FEATURE_TEMP_DEPENDENT_VMIN_MASK  (1 << FEATURE_TEMP_DEPENDENT_VMIN_BIT )
+#define FEATURE_PER_PART_VMIN_MASK        (1 << FEATURE_PER_PART_VMIN_BIT        )
 
 
 //FIXME need updating
@@ -628,8 +629,14 @@ typedef struct {
   uint16_t BasePerformanceFrequencyCap;   //In Mhz
   uint16_t MaxPerformanceFrequencyCap;    //In Mhz
 
+  // Per-Part Vmin
+  uint16_t VDDGFX_VminLow;        // mv Q2
+  uint16_t VDDGFX_TVminLow;       //Celcius
+  uint16_t VDDGFX_VminLow_HiTemp; // mv Q2
+  uint16_t VDDGFX_VminLow_LoTemp; // mv Q2
+
   // SECTION: Reserved
-  uint32_t     Reserved[9];
+  uint32_t     Reserved[7];
 
   // SECTION: BOARD PARAMETERS
 
@@ -869,6 +876,10 @@ typedef struct {
   uint8_t   Mem_DownHystLimit;
   uint16_t  Mem_Fps;
 
+  uint32_t  BusyThreshold;                  // Q16
+  uint32_t  BusyHyst;
+  uint32_t  IdleHyst;
+
   uint32_t  MmHubPadding[8]; // SMU internal use
 } DpmActivityMonitorCoeffInt_t;
 
diff --git a/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h b/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h
index 674e426ed59b..6b3b451a8018 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h
@@ -27,8 +27,8 @@
 
 #define SMU11_DRIVER_IF_VERSION_INV 0xFFFFFFFF
 #define SMU11_DRIVER_IF_VERSION_VG20 0x13
-#define SMU11_DRIVER_IF_VERSION_ARCT 0x12
-#define SMU11_DRIVER_IF_VERSION_NV10 0x35
+#define SMU11_DRIVER_IF_VERSION_ARCT 0x14
+#define SMU11_DRIVER_IF_VERSION_NV10 0x36
 #define SMU11_DRIVER_IF_VERSION_NV12 0x33
 #define SMU11_DRIVER_IF_VERSION_NV14 0x36
 
@@ -37,7 +37,6 @@
 #define MP0_SRAM			0x03900000
 #define MP1_Public			0x03b00000
 #define MP1_SRAM			0x03c00004
-#define MP1_SMC_SIZE		0x40000
 
 /* address block */
 #define smnMP1_FIRMWARE_FLAGS		0x3010024
diff --git a/drivers/gpu/drm/amd/powerplay/inc/smumgr.h b/drivers/gpu/drm/amd/powerplay/inc/smumgr.h
index c5288831aa15..ad100b533d04 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/smumgr.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/smumgr.h
@@ -81,16 +81,15 @@ enum SMU10_TABLE_ID {
 	SMU10_CLOCKTABLE,
 };
 
-extern uint32_t smum_get_argument(struct pp_hwmgr *hwmgr);
-
 extern int smum_download_powerplay_table(struct pp_hwmgr *hwmgr, void **table);
 
 extern int smum_upload_powerplay_table(struct pp_hwmgr *hwmgr);
 
-extern int smum_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg);
+extern int smum_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg, uint32_t *resp);
 
 extern int smum_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr,
-					uint16_t msg, uint32_t parameter);
+					uint16_t msg, uint32_t parameter,
+					uint32_t *resp);
 
 extern int smum_update_sclk_threshold(struct pp_hwmgr *hwmgr);
 
diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
index 15030284b444..c94270f7c198 100644
--- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
@@ -423,6 +423,7 @@ static int navi10_append_powerplay_table(struct smu_context *smu)
 	struct smu_table_context *table_context = &smu->smu_table;
 	PPTable_t *smc_pptable = table_context->driver_pptable;
 	struct atom_smc_dpm_info_v4_5 *smc_dpm_table;
+	struct atom_smc_dpm_info_v4_7 *smc_dpm_table_v4_7;
 	int index, ret;
 
 	index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
@@ -433,77 +434,33 @@ static int navi10_append_powerplay_table(struct smu_context *smu)
 	if (ret)
 		return ret;
 
-	memcpy(smc_pptable->I2cControllers, smc_dpm_table->I2cControllers,
-	       sizeof(I2cControllerConfig_t) * NUM_I2C_CONTROLLERS);
-
-	/* SVI2 Board Parameters */
-	smc_pptable->MaxVoltageStepGfx = smc_dpm_table->MaxVoltageStepGfx;
-	smc_pptable->MaxVoltageStepSoc = smc_dpm_table->MaxVoltageStepSoc;
-	smc_pptable->VddGfxVrMapping = smc_dpm_table->VddGfxVrMapping;
-	smc_pptable->VddSocVrMapping = smc_dpm_table->VddSocVrMapping;
-	smc_pptable->VddMem0VrMapping = smc_dpm_table->VddMem0VrMapping;
-	smc_pptable->VddMem1VrMapping = smc_dpm_table->VddMem1VrMapping;
-	smc_pptable->GfxUlvPhaseSheddingMask = smc_dpm_table->GfxUlvPhaseSheddingMask;
-	smc_pptable->SocUlvPhaseSheddingMask = smc_dpm_table->SocUlvPhaseSheddingMask;
-	smc_pptable->ExternalSensorPresent = smc_dpm_table->ExternalSensorPresent;
-	smc_pptable->Padding8_V = smc_dpm_table->Padding8_V;
-
-	/* Telemetry Settings */
-	smc_pptable->GfxMaxCurrent = smc_dpm_table->GfxMaxCurrent;
-	smc_pptable->GfxOffset = smc_dpm_table->GfxOffset;
-	smc_pptable->Padding_TelemetryGfx = smc_dpm_table->Padding_TelemetryGfx;
-	smc_pptable->SocMaxCurrent = smc_dpm_table->SocMaxCurrent;
-	smc_pptable->SocOffset = smc_dpm_table->SocOffset;
-	smc_pptable->Padding_TelemetrySoc = smc_dpm_table->Padding_TelemetrySoc;
-	smc_pptable->Mem0MaxCurrent = smc_dpm_table->Mem0MaxCurrent;
-	smc_pptable->Mem0Offset = smc_dpm_table->Mem0Offset;
-	smc_pptable->Padding_TelemetryMem0 = smc_dpm_table->Padding_TelemetryMem0;
-	smc_pptable->Mem1MaxCurrent = smc_dpm_table->Mem1MaxCurrent;
-	smc_pptable->Mem1Offset = smc_dpm_table->Mem1Offset;
-	smc_pptable->Padding_TelemetryMem1 = smc_dpm_table->Padding_TelemetryMem1;
-
-	/* GPIO Settings */
-	smc_pptable->AcDcGpio = smc_dpm_table->AcDcGpio;
-	smc_pptable->AcDcPolarity = smc_dpm_table->AcDcPolarity;
-	smc_pptable->VR0HotGpio = smc_dpm_table->VR0HotGpio;
-	smc_pptable->VR0HotPolarity = smc_dpm_table->VR0HotPolarity;
-	smc_pptable->VR1HotGpio = smc_dpm_table->VR1HotGpio;
-	smc_pptable->VR1HotPolarity = smc_dpm_table->VR1HotPolarity;
-	smc_pptable->GthrGpio = smc_dpm_table->GthrGpio;
-	smc_pptable->GthrPolarity = smc_dpm_table->GthrPolarity;
-
-	/* LED Display Settings */
-	smc_pptable->LedPin0 = smc_dpm_table->LedPin0;
-	smc_pptable->LedPin1 = smc_dpm_table->LedPin1;
-	smc_pptable->LedPin2 = smc_dpm_table->LedPin2;
-	smc_pptable->padding8_4 = smc_dpm_table->padding8_4;
-
-	/* GFXCLK PLL Spread Spectrum */
-	smc_pptable->PllGfxclkSpreadEnabled = smc_dpm_table->PllGfxclkSpreadEnabled;
-	smc_pptable->PllGfxclkSpreadPercent = smc_dpm_table->PllGfxclkSpreadPercent;
-	smc_pptable->PllGfxclkSpreadFreq = smc_dpm_table->PllGfxclkSpreadFreq;
-
-	/* GFXCLK DFLL Spread Spectrum */
-	smc_pptable->DfllGfxclkSpreadEnabled = smc_dpm_table->DfllGfxclkSpreadEnabled;
-	smc_pptable->DfllGfxclkSpreadPercent = smc_dpm_table->DfllGfxclkSpreadPercent;
-	smc_pptable->DfllGfxclkSpreadFreq = smc_dpm_table->DfllGfxclkSpreadFreq;
-
-	/* UCLK Spread Spectrum */
-	smc_pptable->UclkSpreadEnabled = smc_dpm_table->UclkSpreadEnabled;
-	smc_pptable->UclkSpreadPercent = smc_dpm_table->UclkSpreadPercent;
-	smc_pptable->UclkSpreadFreq = smc_dpm_table->UclkSpreadFreq;
-
-	/* SOCCLK Spread Spectrum */
-	smc_pptable->SoclkSpreadEnabled = smc_dpm_table->SoclkSpreadEnabled;
-	smc_pptable->SocclkSpreadPercent = smc_dpm_table->SocclkSpreadPercent;
-	smc_pptable->SocclkSpreadFreq = smc_dpm_table->SocclkSpreadFreq;
-
-	/* Total board power */
-	smc_pptable->TotalBoardPower = smc_dpm_table->TotalBoardPower;
-	smc_pptable->BoardPadding = smc_dpm_table->BoardPadding;
-
-	/* Mvdd Svi2 Div Ratio Setting */
-	smc_pptable->MvddRatio = smc_dpm_table->MvddRatio;
+	pr_info("smc_dpm_info table revision(format.content): %d.%d\n",
+			smc_dpm_table->table_header.format_revision,
+			smc_dpm_table->table_header.content_revision);
+
+	if (smc_dpm_table->table_header.format_revision != 4) {
+		pr_err("smc_dpm_info table format revision is not 4!\n");
+		return -EINVAL;
+	}
+
+	switch (smc_dpm_table->table_header.content_revision) {
+	case 5: /* nv10 and nv14 */
+		memcpy(smc_pptable->I2cControllers, smc_dpm_table->I2cControllers,
+			sizeof(*smc_dpm_table) - sizeof(smc_dpm_table->table_header));
+		break;
+	case 7: /* nv12 */
+		ret = smu_get_atom_data_table(smu, index, NULL, NULL, NULL,
+					      (uint8_t **)&smc_dpm_table_v4_7);
+		if (ret)
+			return ret;
+		memcpy(smc_pptable->I2cControllers, smc_dpm_table_v4_7->I2cControllers,
+			sizeof(*smc_dpm_table_v4_7) - sizeof(smc_dpm_table_v4_7->table_header));
+		break;
+	default:
+		pr_err("smc_dpm_info with unsupported content revision %d!\n",
+				smc_dpm_table->table_header.content_revision);
+		return -EINVAL;
+	}
 
 	if (adev->pm.pp_feature & PP_GFXOFF_MASK) {
 		/* TODO: remove it once SMU fw fix it */
diff --git a/drivers/gpu/drm/amd/powerplay/renoir_ppt.c b/drivers/gpu/drm/amd/powerplay/renoir_ppt.c
index ff73a735b888..16ed32f76954 100644
--- a/drivers/gpu/drm/amd/powerplay/renoir_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/renoir_ppt.c
@@ -847,7 +847,7 @@ static int renoir_get_power_profile_mode(struct smu_context *smu,
 	uint32_t i, size = 0;
 	int16_t workload_type = 0;
 
-	if (!smu->pm_enabled || !buf)
+	if (!buf)
 		return -EINVAL;
 
 	for (i = 0; i <= PP_SMC_POWER_PROFILE_CUSTOM; i++) {
@@ -895,12 +895,17 @@ static int renoir_read_sensor(struct smu_context *smu,
 
 static bool renoir_is_dpm_running(struct smu_context *smu)
 {
+	struct amdgpu_device *adev = smu->adev;
+
 	/*
-	 * Util now, the pmfw hasn't exported the interface of SMU
+	 * Until now, the pmfw hasn't exported the interface of SMU
 	 * feature mask to APU SKU so just force on all the feature
 	 * at early initial stage.
 	 */
-	return true;
+	if (adev->in_suspend)
+		return false;
+	else
+		return true;
 
 }
 
@@ -950,6 +955,6 @@ static const struct pptable_funcs renoir_ppt_funcs = {
 void renoir_set_ppt_funcs(struct smu_context *smu)
 {
 	smu->ppt_funcs = &renoir_ppt_funcs;
-	smu->smc_if_version = SMU12_DRIVER_IF_VERSION;
+	smu->smc_driver_if_version = SMU12_DRIVER_IF_VERSION;
 	smu->is_apu = true;
 }
diff --git a/drivers/gpu/drm/amd/powerplay/smu_internal.h b/drivers/gpu/drm/amd/powerplay/smu_internal.h
index 40c35bcc5a0a..c97444841abc 100644
--- a/drivers/gpu/drm/amd/powerplay/smu_internal.h
+++ b/drivers/gpu/drm/amd/powerplay/smu_internal.h
@@ -214,4 +214,9 @@ static inline int smu_send_smc_msg(struct smu_context *smu, enum smu_message_typ
 #define smu_set_power_source(smu, power_src) \
 	((smu)->ppt_funcs->set_power_source ? (smu)->ppt_funcs->set_power_source((smu), (power_src)) : 0)
 
+#define smu_i2c_eeprom_init(smu, control) \
+		((smu)->ppt_funcs->i2c_eeprom_init ? (smu)->ppt_funcs->i2c_eeprom_init((control)) : 0)
+#define smu_i2c_eeprom_fini(smu, control) \
+		((smu)->ppt_funcs->i2c_eeprom_fini ? (smu)->ppt_funcs->i2c_eeprom_fini((control)) : 0)
+
 #endif
diff --git a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
index 541c932a6005..0045b54b19ed 100644
--- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
+++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
@@ -201,13 +201,15 @@ int smu_v11_0_load_microcode(struct smu_context *smu)
 	const struct smc_firmware_header_v1_0 *hdr;
 	uint32_t addr_start = MP1_SRAM;
 	uint32_t i;
+	uint32_t smc_fw_size;
 	uint32_t mp1_fw_flags;
 
 	hdr = (const struct smc_firmware_header_v1_0 *) adev->pm.fw->data;
 	src = (const uint32_t *)(adev->pm.fw->data +
 		le32_to_cpu(hdr->header.ucode_array_offset_bytes));
+	smc_fw_size = hdr->header.ucode_size_bytes;
 
-	for (i = 1; i < MP1_SMC_SIZE/4 - 1; i++) {
+	for (i = 1; i < smc_fw_size/4 - 1; i++) {
 		WREG32_PCIE(addr_start, src[i]);
 		addr_start += 4;
 	}
@@ -264,23 +266,23 @@ int smu_v11_0_check_fw_version(struct smu_context *smu)
 
 	switch (smu->adev->asic_type) {
 	case CHIP_VEGA20:
-		smu->smc_if_version = SMU11_DRIVER_IF_VERSION_VG20;
+		smu->smc_driver_if_version = SMU11_DRIVER_IF_VERSION_VG20;
 		break;
 	case CHIP_ARCTURUS:
-		smu->smc_if_version = SMU11_DRIVER_IF_VERSION_ARCT;
+		smu->smc_driver_if_version = SMU11_DRIVER_IF_VERSION_ARCT;
 		break;
 	case CHIP_NAVI10:
-		smu->smc_if_version = SMU11_DRIVER_IF_VERSION_NV10;
+		smu->smc_driver_if_version = SMU11_DRIVER_IF_VERSION_NV10;
 		break;
 	case CHIP_NAVI12:
-		smu->smc_if_version = SMU11_DRIVER_IF_VERSION_NV12;
+		smu->smc_driver_if_version = SMU11_DRIVER_IF_VERSION_NV12;
 		break;
 	case CHIP_NAVI14:
-		smu->smc_if_version = SMU11_DRIVER_IF_VERSION_NV14;
+		smu->smc_driver_if_version = SMU11_DRIVER_IF_VERSION_NV14;
 		break;
 	default:
 		pr_err("smu unsupported asic type:%d.\n", smu->adev->asic_type);
-		smu->smc_if_version = SMU11_DRIVER_IF_VERSION_INV;
+		smu->smc_driver_if_version = SMU11_DRIVER_IF_VERSION_INV;
 		break;
 	}
 
@@ -292,10 +294,10 @@ int smu_v11_0_check_fw_version(struct smu_context *smu)
 	 * Considering above, we just leave user a warning message instead
 	 * of halt driver loading.
 	 */
-	if (if_version != smu->smc_if_version) {
+	if (if_version != smu->smc_driver_if_version) {
 		pr_info("smu driver if version = 0x%08x, smu fw if version = 0x%08x, "
 			"smu fw version = 0x%08x (%d.%d.%d)\n",
-			smu->smc_if_version, if_version,
+			smu->smc_driver_if_version, if_version,
 			smu_version, smu_major, smu_minor, smu_debug);
 		pr_warn("SMU driver if version not matched\n");
 	}
@@ -479,8 +481,6 @@ int smu_v11_0_init_power(struct smu_context *smu)
 {
 	struct smu_power_context *smu_power = &smu->smu_power;
 
-	if (!smu->pm_enabled)
-		return 0;
 	if (smu_power->power_context || smu_power->power_context_size != 0)
 		return -EINVAL;
 
@@ -497,8 +497,6 @@ int smu_v11_0_fini_power(struct smu_context *smu)
 {
 	struct smu_power_context *smu_power = &smu->smu_power;
 
-	if (!smu->pm_enabled)
-		return 0;
 	if (!smu_power->power_context || smu_power->power_context_size == 0)
 		return -EINVAL;
 
@@ -783,8 +781,6 @@ int smu_v11_0_set_min_dcef_deep_sleep(struct smu_context *smu)
 {
 	struct smu_table_context *table_context = &smu->smu_table;
 
-	if (!smu->pm_enabled)
-		return 0;
 	if (!table_context)
 		return -EINVAL;
 
@@ -835,9 +831,6 @@ int smu_v11_0_init_display_count(struct smu_context *smu, uint32_t count)
 {
 	int ret = 0;
 
-	if (!smu->pm_enabled)
-		return ret;
-
 	ret = smu_send_smc_msg_with_param(smu, SMU_MSG_NumOfDisplays, count, NULL);
 	return ret;
 }
@@ -932,8 +925,6 @@ int smu_v11_0_notify_display_change(struct smu_context *smu)
 {
 	int ret = 0;
 
-	if (!smu->pm_enabled)
-		return ret;
 	if (smu_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT) &&
 	    smu->adev->gmc.vram_type == AMDGPU_VRAM_TYPE_HBM)
 		ret = smu_send_smc_msg_with_param(smu, SMU_MSG_SetUclkFastSwitch, 1, NULL);
@@ -948,9 +939,6 @@ smu_v11_0_get_max_sustainable_clock(struct smu_context *smu, uint32_t *clock,
 	int ret = 0;
 	int clk_id;
 
-	if (!smu->pm_enabled)
-		return ret;
-
 	if ((smu_msg_get_index(smu, SMU_MSG_GetDcModeMaxDpmFreq) < 0) ||
 	    (smu_msg_get_index(smu, SMU_MSG_GetMaxDpmFreq) < 0))
 		return 0;
@@ -1205,9 +1193,6 @@ int smu_v11_0_start_thermal_control(struct smu_context *smu)
 	struct smu_temperature_range range;
 	struct amdgpu_device *adev = smu->adev;
 
-	if (!smu->pm_enabled)
-		return ret;
-
 	memcpy(&range, &smu11_thermal_policy[0], sizeof(struct smu_temperature_range));
 
 	ret = smu_get_thermal_temperature_range(smu, &range);
@@ -1321,9 +1306,6 @@ smu_v11_0_display_clock_voltage_request(struct smu_context *smu,
 	enum smu_clk_type clk_select = 0;
 	uint32_t clk_freq = clock_req->clock_freq_in_khz / 1000;
 
-	if (!smu->pm_enabled)
-		return -EINVAL;
-
 	if (smu_feature_is_enabled(smu, SMU_FEATURE_DPM_DCEFCLK_BIT) ||
 		smu_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT)) {
 		switch (clk_type) {
@@ -1718,6 +1700,12 @@ int smu_v11_0_baco_set_state(struct smu_context *smu, enum smu_baco_state state)
 		if (ret)
 			goto out;
 
+		if (ras && ras->supported) {
+			ret = smu_send_smc_msg(smu, SMU_MSG_PrepareMp1ForUnload, NULL);
+			if (ret)
+				goto out;
+		}
+
 		/* clear vbios scratch 6 and 7 for coming asic reinit */
 		WREG32(adev->bios_scratch_reg_offset + 6, 0);
 		WREG32(adev->bios_scratch_reg_offset + 7, 0);
diff --git a/drivers/gpu/drm/amd/powerplay/smu_v12_0.c b/drivers/gpu/drm/amd/powerplay/smu_v12_0.c
index 169ebdad87b8..4023d10fb49b 100644
--- a/drivers/gpu/drm/amd/powerplay/smu_v12_0.c
+++ b/drivers/gpu/drm/amd/powerplay/smu_v12_0.c
@@ -32,13 +32,15 @@
 
 #include "asic_reg/mp/mp_12_0_0_offset.h"
 #include "asic_reg/mp/mp_12_0_0_sh_mask.h"
+#include "asic_reg/smuio/smuio_12_0_0_offset.h"
+#include "asic_reg/smuio/smuio_12_0_0_sh_mask.h"
 
-#define smnMP1_FIRMWARE_FLAGS                                0x3010024
+// because some SMU12 based ASICs use older ip offset tables
+// we should undefine this register from the smuio12 header
+// to prevent confusion down the road
+#undef mmPWR_MISC_CNTL_STATUS
 
-#define mmSMUIO_GFX_MISC_CNTL                                0x00c8
-#define mmSMUIO_GFX_MISC_CNTL_BASE_IDX                       0
-#define SMUIO_GFX_MISC_CNTL__PWR_GFXOFF_STATUS_MASK          0x00000006L
-#define SMUIO_GFX_MISC_CNTL__PWR_GFXOFF_STATUS__SHIFT        0x1
+#define smnMP1_FIRMWARE_FLAGS                                0x3010024
 
 int smu_v12_0_send_msg_without_waiting(struct smu_context *smu,
 					      uint16_t msg)
@@ -158,10 +160,10 @@ int smu_v12_0_check_fw_version(struct smu_context *smu)
 	 * Considering above, we just leave user a warning message instead
 	 * of halt driver loading.
 	 */
-	if (if_version != smu->smc_if_version) {
+	if (if_version != smu->smc_driver_if_version) {
 		pr_info("smu driver if version = 0x%08x, smu fw if version = 0x%08x, "
 			"smu fw version = 0x%08x (%d.%d.%d)\n",
-			smu->smc_if_version, if_version,
+			smu->smc_driver_if_version, if_version,
 			smu_version, smu_major, smu_minor, smu_debug);
 		pr_warn("SMU driver if version not matched\n");
 	}
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/ci_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/ci_smumgr.c
index 868e2d5f6e62..85e5b1ed22c2 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/ci_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/ci_smumgr.c
@@ -2780,7 +2780,7 @@ static int ci_update_dpm_settings(struct pp_hwmgr *hwmgr,
 
 	if (setting->bupdate_sclk) {
 		if (!data->sclk_dpm_key_disabled)
-			smum_send_msg_to_smc(hwmgr, PPSMC_MSG_SCLKDPM_FreezeLevel);
+			smum_send_msg_to_smc(hwmgr, PPSMC_MSG_SCLKDPM_FreezeLevel, NULL);
 		for (i = 0; i < smu_data->smc_state_table.GraphicsDpmLevelCount; i++) {
 			if (levels[i].ActivityLevel !=
 				cpu_to_be16(setting->sclk_activity)) {
@@ -2810,12 +2810,12 @@ static int ci_update_dpm_settings(struct pp_hwmgr *hwmgr,
 			}
 		}
 		if (!data->sclk_dpm_key_disabled)
-			smum_send_msg_to_smc(hwmgr, PPSMC_MSG_SCLKDPM_UnfreezeLevel);
+			smum_send_msg_to_smc(hwmgr, PPSMC_MSG_SCLKDPM_UnfreezeLevel, NULL);
 	}
 
 	if (setting->bupdate_mclk) {
 		if (!data->mclk_dpm_key_disabled)
-			smum_send_msg_to_smc(hwmgr, PPSMC_MSG_MCLKDPM_FreezeLevel);
+			smum_send_msg_to_smc(hwmgr, PPSMC_MSG_MCLKDPM_FreezeLevel, NULL);
 		for (i = 0; i < smu_data->smc_state_table.MemoryDpmLevelCount; i++) {
 			if (mclk_levels[i].ActivityLevel !=
 				cpu_to_be16(setting->mclk_activity)) {
@@ -2845,7 +2845,7 @@ static int ci_update_dpm_settings(struct pp_hwmgr *hwmgr,
 			}
 		}
 		if (!data->mclk_dpm_key_disabled)
-			smum_send_msg_to_smc(hwmgr, PPSMC_MSG_MCLKDPM_UnfreezeLevel);
+			smum_send_msg_to_smc(hwmgr, PPSMC_MSG_MCLKDPM_UnfreezeLevel, NULL);
 	}
 	return 0;
 }
@@ -2881,8 +2881,9 @@ static int ci_update_uvd_smc_table(struct pp_hwmgr *hwmgr)
 		if (hwmgr->dpm_level & profile_mode_mask || !PP_CAP(PHM_PlatformCaps_UVDDPM))
 			break;
 	}
-	ci_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_UVDDPM_SetEnabledMask,
-				data->dpm_level_enable_mask.uvd_dpm_enable_mask);
+	smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_UVDDPM_SetEnabledMask,
+				data->dpm_level_enable_mask.uvd_dpm_enable_mask,
+				NULL);
 
 	return 0;
 }
@@ -2912,8 +2913,9 @@ static int ci_update_vce_smc_table(struct pp_hwmgr *hwmgr)
 		if (hwmgr->dpm_level & profile_mode_mask || !PP_CAP(PHM_PlatformCaps_VCEDPM))
 			break;
 	}
-	ci_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_VCEDPM_SetEnabledMask,
-				data->dpm_level_enable_mask.vce_dpm_enable_mask);
+	smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_VCEDPM_SetEnabledMask,
+				data->dpm_level_enable_mask.vce_dpm_enable_mask,
+				NULL);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c
index 32ebb383c456..ecb9ee46d6b3 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c
@@ -137,9 +137,7 @@ static int fiji_start_smu_in_protection_mode(struct pp_hwmgr *hwmgr)
 	PHM_WAIT_VFPF_INDIRECT_FIELD(hwmgr, SMC_IND, RCU_UC_EVENTS,
 			INTERRUPTS_ENABLED, 1);
 
-	cgs_write_register(hwmgr->device, mmSMC_MSG_ARG_0, 0x20000);
-	cgs_write_register(hwmgr->device, mmSMC_MESSAGE_0, PPSMC_MSG_Test);
-	PHM_WAIT_FIELD_UNEQUAL(hwmgr, SMC_RESP_0, SMC_RESP, 0);
+	smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_Test, 0x20000, NULL);
 
 	/* Wait for done bit to be set */
 	PHM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(hwmgr, SMC_IND,
@@ -203,8 +201,9 @@ static int fiji_start_avfs_btc(struct pp_hwmgr *hwmgr)
 	struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(hwmgr->smu_backend);
 
 	if (0 != smu_data->avfs_btc_param) {
-		if (0 != smu7_send_msg_to_smc_with_parameter(hwmgr,
-				PPSMC_MSG_PerformBtc, smu_data->avfs_btc_param)) {
+		if (0 != smum_send_msg_to_smc_with_parameter(hwmgr,
+				PPSMC_MSG_PerformBtc, smu_data->avfs_btc_param,
+				NULL)) {
 			pr_info("[AVFS][Fiji_PerformBtc] PerformBTC SMU msg failed");
 			result = -EINVAL;
 		}
@@ -1913,7 +1912,8 @@ static int fiji_setup_dpm_led_config(struct pp_hwmgr *hwmgr)
 	if (mask)
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 						    PPSMC_MSG_LedConfig,
-						    mask);
+						    mask,
+						    NULL);
 	return 0;
 }
 
@@ -2220,14 +2220,16 @@ static int fiji_thermal_setup_fan_table(struct pp_hwmgr *hwmgr)
 		res = smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_SetFanMinPwm,
 				hwmgr->thermal_controller.
-				advanceFanControlParameters.ucMinimumPWMLimit);
+				advanceFanControlParameters.ucMinimumPWMLimit,
+				NULL);
 
 	if (!res && hwmgr->thermal_controller.
 			advanceFanControlParameters.ulMinFanSCLKAcousticLimit)
 		res = smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_SetFanSclkTarget,
 				hwmgr->thermal_controller.
-				advanceFanControlParameters.ulMinFanSCLKAcousticLimit);
+				advanceFanControlParameters.ulMinFanSCLKAcousticLimit,
+				NULL);
 
 	if (res)
 		phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
@@ -2242,7 +2244,7 @@ static int fiji_thermal_avfs_enable(struct pp_hwmgr *hwmgr)
 	if (!hwmgr->avfs_supported)
 		return 0;
 
-	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_EnableAvfs);
+	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_EnableAvfs, NULL);
 
 	return 0;
 }
@@ -2390,7 +2392,8 @@ static int fiji_update_uvd_smc_table(struct pp_hwmgr *hwmgr)
 			PHM_PlatformCaps_StablePState))
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_UVDDPM_SetEnabledMask,
-				(uint32_t)(1 << smu_data->smc_state_table.UvdBootLevel));
+				(uint32_t)(1 << smu_data->smc_state_table.UvdBootLevel),
+				NULL);
 	return 0;
 }
 
@@ -2422,7 +2425,8 @@ static int fiji_update_vce_smc_table(struct pp_hwmgr *hwmgr)
 	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_StablePState))
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_VCEDPM_SetEnabledMask,
-				(uint32_t)1 << smu_data->smc_state_table.VceBootLevel);
+				(uint32_t)1 << smu_data->smc_state_table.VceBootLevel,
+				NULL);
 	return 0;
 }
 
@@ -2569,7 +2573,7 @@ static int fiji_update_dpm_settings(struct pp_hwmgr *hwmgr,
 
 	if (setting->bupdate_sclk) {
 		if (!data->sclk_dpm_key_disabled)
-			smum_send_msg_to_smc(hwmgr, PPSMC_MSG_SCLKDPM_FreezeLevel);
+			smum_send_msg_to_smc(hwmgr, PPSMC_MSG_SCLKDPM_FreezeLevel, NULL);
 		for (i = 0; i < smu_data->smc_state_table.GraphicsDpmLevelCount; i++) {
 			if (levels[i].ActivityLevel !=
 				cpu_to_be16(setting->sclk_activity)) {
@@ -2599,12 +2603,12 @@ static int fiji_update_dpm_settings(struct pp_hwmgr *hwmgr,
 			}
 		}
 		if (!data->sclk_dpm_key_disabled)
-			smum_send_msg_to_smc(hwmgr, PPSMC_MSG_SCLKDPM_UnfreezeLevel);
+			smum_send_msg_to_smc(hwmgr, PPSMC_MSG_SCLKDPM_UnfreezeLevel, NULL);
 	}
 
 	if (setting->bupdate_mclk) {
 		if (!data->mclk_dpm_key_disabled)
-			smum_send_msg_to_smc(hwmgr, PPSMC_MSG_MCLKDPM_FreezeLevel);
+			smum_send_msg_to_smc(hwmgr, PPSMC_MSG_MCLKDPM_FreezeLevel, NULL);
 		for (i = 0; i < smu_data->smc_state_table.MemoryDpmLevelCount; i++) {
 			if (mclk_levels[i].ActivityLevel !=
 				cpu_to_be16(setting->mclk_activity)) {
@@ -2634,7 +2638,7 @@ static int fiji_update_dpm_settings(struct pp_hwmgr *hwmgr,
 			}
 		}
 		if (!data->mclk_dpm_key_disabled)
-			smum_send_msg_to_smc(hwmgr, PPSMC_MSG_MCLKDPM_UnfreezeLevel);
+			smum_send_msg_to_smc(hwmgr, PPSMC_MSG_MCLKDPM_UnfreezeLevel, NULL);
 	}
 	return 0;
 }
@@ -2649,6 +2653,7 @@ const struct pp_smumgr_func fiji_smu_funcs = {
 	.request_smu_load_specific_fw = NULL,
 	.send_msg_to_smc = &smu7_send_msg_to_smc,
 	.send_msg_to_smc_with_parameter = &smu7_send_msg_to_smc_with_parameter,
+	.get_argument = smu7_get_argument,
 	.download_pptable_settings = NULL,
 	.upload_pptable_settings = NULL,
 	.update_smc_table = fiji_update_smc_table,
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c
index 732005c03a82..431ad2fd38df 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c
@@ -2669,6 +2669,7 @@ const struct pp_smumgr_func iceland_smu_funcs = {
 	.request_smu_load_specific_fw = &iceland_request_smu_load_specific_fw,
 	.send_msg_to_smc = &smu7_send_msg_to_smc,
 	.send_msg_to_smc_with_parameter = &smu7_send_msg_to_smc_with_parameter,
+	.get_argument = smu7_get_argument,
 	.download_pptable_settings = NULL,
 	.upload_pptable_settings = NULL,
 	.get_offsetof = iceland_get_offsetof,
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c
index 23c12018dbc1..c3d2e6dcf62a 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c
@@ -99,7 +99,8 @@ static int polaris10_perform_btc(struct pp_hwmgr *hwmgr)
 	struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(hwmgr->smu_backend);
 
 	if (0 != smu_data->avfs_btc_param) {
-		if (0 != smu7_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_PerformBtc, smu_data->avfs_btc_param)) {
+		if (0 != smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_PerformBtc, smu_data->avfs_btc_param,
+					NULL)) {
 			pr_info("[AVFS][SmuPolaris10_PerformBtc] PerformBTC SMU msg failed");
 			result = -1;
 		}
@@ -2049,15 +2050,16 @@ int polaris10_thermal_avfs_enable(struct pp_hwmgr *hwmgr)
 		return 0;
 
 	smum_send_msg_to_smc_with_parameter(hwmgr,
-			PPSMC_MSG_SetGBDroopSettings, data->avfs_vdroop_override_setting);
+			PPSMC_MSG_SetGBDroopSettings, data->avfs_vdroop_override_setting,
+			NULL);
 
-	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_EnableAvfs);
+	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_EnableAvfs, NULL);
 
 	/* Apply avfs cks-off voltages to avoid the overshoot
 	 * when switching to the highest sclk frequency
 	 */
 	if (data->apply_avfs_cks_off_voltage)
-		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ApplyAvfsCksOffVoltage);
+		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ApplyAvfsCksOffVoltage, NULL);
 
 	return 0;
 }
@@ -2158,14 +2160,16 @@ static int polaris10_thermal_setup_fan_table(struct pp_hwmgr *hwmgr)
 		res = smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_SetFanMinPwm,
 				hwmgr->thermal_controller.
-				advanceFanControlParameters.ucMinimumPWMLimit);
+				advanceFanControlParameters.ucMinimumPWMLimit,
+				NULL);
 
 	if (!res && hwmgr->thermal_controller.
 			advanceFanControlParameters.ulMinFanSCLKAcousticLimit)
 		res = smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_SetFanSclkTarget,
 				hwmgr->thermal_controller.
-				advanceFanControlParameters.ulMinFanSCLKAcousticLimit);
+				advanceFanControlParameters.ulMinFanSCLKAcousticLimit,
+				NULL);
 
 	if (res)
 		phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
@@ -2202,7 +2206,8 @@ static int polaris10_update_uvd_smc_table(struct pp_hwmgr *hwmgr)
 			PHM_PlatformCaps_StablePState))
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_UVDDPM_SetEnabledMask,
-				(uint32_t)(1 << smu_data->smc_state_table.UvdBootLevel));
+				(uint32_t)(1 << smu_data->smc_state_table.UvdBootLevel),
+				NULL);
 	return 0;
 }
 
@@ -2234,7 +2239,8 @@ static int polaris10_update_vce_smc_table(struct pp_hwmgr *hwmgr)
 	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_StablePState))
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_VCEDPM_SetEnabledMask,
-				(uint32_t)1 << smu_data->smc_state_table.VceBootLevel);
+				(uint32_t)1 << smu_data->smc_state_table.VceBootLevel,
+				NULL);
 	return 0;
 }
 
@@ -2485,7 +2491,7 @@ static int polaris10_update_dpm_settings(struct pp_hwmgr *hwmgr,
 
 	if (setting->bupdate_sclk) {
 		if (!data->sclk_dpm_key_disabled)
-			smum_send_msg_to_smc(hwmgr, PPSMC_MSG_SCLKDPM_FreezeLevel);
+			smum_send_msg_to_smc(hwmgr, PPSMC_MSG_SCLKDPM_FreezeLevel, NULL);
 		for (i = 0; i < smu_data->smc_state_table.GraphicsDpmLevelCount; i++) {
 			if (levels[i].ActivityLevel !=
 				cpu_to_be16(setting->sclk_activity)) {
@@ -2515,12 +2521,12 @@ static int polaris10_update_dpm_settings(struct pp_hwmgr *hwmgr,
 			}
 		}
 		if (!data->sclk_dpm_key_disabled)
-			smum_send_msg_to_smc(hwmgr, PPSMC_MSG_SCLKDPM_UnfreezeLevel);
+			smum_send_msg_to_smc(hwmgr, PPSMC_MSG_SCLKDPM_UnfreezeLevel, NULL);
 	}
 
 	if (setting->bupdate_mclk) {
 		if (!data->mclk_dpm_key_disabled)
-			smum_send_msg_to_smc(hwmgr, PPSMC_MSG_MCLKDPM_FreezeLevel);
+			smum_send_msg_to_smc(hwmgr, PPSMC_MSG_MCLKDPM_FreezeLevel, NULL);
 		for (i = 0; i < smu_data->smc_state_table.MemoryDpmLevelCount; i++) {
 			if (mclk_levels[i].ActivityLevel !=
 				cpu_to_be16(setting->mclk_activity)) {
@@ -2550,7 +2556,7 @@ static int polaris10_update_dpm_settings(struct pp_hwmgr *hwmgr,
 			}
 		}
 		if (!data->mclk_dpm_key_disabled)
-			smum_send_msg_to_smc(hwmgr, PPSMC_MSG_MCLKDPM_UnfreezeLevel);
+			smum_send_msg_to_smc(hwmgr, PPSMC_MSG_MCLKDPM_UnfreezeLevel, NULL);
 	}
 	return 0;
 }
@@ -2565,6 +2571,7 @@ const struct pp_smumgr_func polaris10_smu_funcs = {
 	.request_smu_load_specific_fw = NULL,
 	.send_msg_to_smc = smu7_send_msg_to_smc,
 	.send_msg_to_smc_with_parameter = smu7_send_msg_to_smc_with_parameter,
+	.get_argument = smu7_get_argument,
 	.download_pptable_settings = NULL,
 	.upload_pptable_settings = NULL,
 	.update_smc_table = polaris10_update_smc_table,
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c
index 2319400a3fcb..801ba9ca6094 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c
@@ -126,15 +126,18 @@ static int smu10_copy_table_from_smc(struct pp_hwmgr *hwmgr,
 			"Invalid SMU Table version!", return -EINVAL;);
 	PP_ASSERT_WITH_CODE(priv->smu_tables.entry[table_id].size != 0,
 			"Invalid SMU Table Length!", return -EINVAL;);
-	smu10_send_msg_to_smc_with_parameter(hwmgr,
+	smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_SetDriverDramAddrHigh,
-			upper_32_bits(priv->smu_tables.entry[table_id].mc_addr));
-	smu10_send_msg_to_smc_with_parameter(hwmgr,
+			upper_32_bits(priv->smu_tables.entry[table_id].mc_addr),
+			NULL);
+	smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_SetDriverDramAddrLow,
-			lower_32_bits(priv->smu_tables.entry[table_id].mc_addr));
-	smu10_send_msg_to_smc_with_parameter(hwmgr,
+			lower_32_bits(priv->smu_tables.entry[table_id].mc_addr),
+			NULL);
+	smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_TransferTableSmu2Dram,
-			priv->smu_tables.entry[table_id].table_id);
+			priv->smu_tables.entry[table_id].table_id,
+			NULL);
 
 	/* flush hdp cache */
 	amdgpu_asic_flush_hdp(adev, NULL);
@@ -164,15 +167,18 @@ static int smu10_copy_table_to_smc(struct pp_hwmgr *hwmgr,
 
 	amdgpu_asic_flush_hdp(adev, NULL);
 
-	smu10_send_msg_to_smc_with_parameter(hwmgr,
+	smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_SetDriverDramAddrHigh,
-			upper_32_bits(priv->smu_tables.entry[table_id].mc_addr));
-	smu10_send_msg_to_smc_with_parameter(hwmgr,
+			upper_32_bits(priv->smu_tables.entry[table_id].mc_addr),
+			NULL);
+	smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_SetDriverDramAddrLow,
-			lower_32_bits(priv->smu_tables.entry[table_id].mc_addr));
-	smu10_send_msg_to_smc_with_parameter(hwmgr,
+			lower_32_bits(priv->smu_tables.entry[table_id].mc_addr),
+			NULL);
+	smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_TransferTableDram2Smu,
-			priv->smu_tables.entry[table_id].table_id);
+			priv->smu_tables.entry[table_id].table_id,
+			NULL);
 
 	return 0;
 }
@@ -181,9 +187,9 @@ static int smu10_verify_smc_interface(struct pp_hwmgr *hwmgr)
 {
 	uint32_t smc_driver_if_version;
 
-	smu10_send_msg_to_smc(hwmgr,
-			PPSMC_MSG_GetDriverIfVersion);
-	smc_driver_if_version = smu10_read_arg_from_smc(hwmgr);
+	smum_send_msg_to_smc(hwmgr,
+			PPSMC_MSG_GetDriverIfVersion,
+			&smc_driver_if_version);
 
 	if ((smc_driver_if_version != SMU10_DRIVER_IF_VERSION) &&
 	    (smc_driver_if_version != SMU10_DRIVER_IF_VERSION + 1)) {
@@ -217,8 +223,7 @@ static int smu10_start_smu(struct pp_hwmgr *hwmgr)
 {
 	struct amdgpu_device *adev = hwmgr->adev;
 
-	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetSmuVersion);
-	hwmgr->smu_version = smu10_read_arg_from_smc(hwmgr);
+	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetSmuVersion, &hwmgr->smu_version);
 	adev->pm.fw_version = hwmgr->smu_version >> 8;
 
 	if (adev->rev_id < 0x8 && adev->pdev->device != 0x15d8 &&
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c
index 3f51d545e8ff..aae25243eb10 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c
@@ -191,13 +191,6 @@ int smu7_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg)
 	return 0;
 }
 
-int smu7_send_msg_to_smc_without_waiting(struct pp_hwmgr *hwmgr, uint16_t msg)
-{
-	cgs_write_register(hwmgr->device, mmSMC_MESSAGE_0, msg);
-
-	return 0;
-}
-
 int smu7_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr, uint16_t msg, uint32_t parameter)
 {
 	PHM_WAIT_FIELD_UNEQUAL(hwmgr, SMC_RESP_0, SMC_RESP, 0);
@@ -207,25 +200,14 @@ int smu7_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr, uint16_t msg, ui
 	return smu7_send_msg_to_smc(hwmgr, msg);
 }
 
-int smu7_send_msg_to_smc_with_parameter_without_waiting(struct pp_hwmgr *hwmgr, uint16_t msg, uint32_t parameter)
+uint32_t smu7_get_argument(struct pp_hwmgr *hwmgr)
 {
-	cgs_write_register(hwmgr->device, mmSMC_MSG_ARG_0, parameter);
-
-	return smu7_send_msg_to_smc_without_waiting(hwmgr, msg);
+	return cgs_read_register(hwmgr->device, mmSMC_MSG_ARG_0);
 }
 
 int smu7_send_msg_to_smc_offset(struct pp_hwmgr *hwmgr)
 {
-	cgs_write_register(hwmgr->device, mmSMC_MSG_ARG_0, 0x20000);
-
-	cgs_write_register(hwmgr->device, mmSMC_MESSAGE_0, PPSMC_MSG_Test);
-
-	PHM_WAIT_FIELD_UNEQUAL(hwmgr, SMC_RESP_0, SMC_RESP, 0);
-
-	if (1 != PHM_READ_FIELD(hwmgr->device, SMC_RESP_0, SMC_RESP))
-		pr_info("Failed to send Message.\n");
-
-	return 0;
+	return smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_Test, 0x20000, NULL);
 }
 
 enum cgs_ucode_id smu7_convert_fw_type_to_cgs(uint32_t fw_type)
@@ -353,12 +335,14 @@ int smu7_request_smu_load_fw(struct pp_hwmgr *hwmgr)
 
 	if (hwmgr->chip_id > CHIP_TOPAZ) { /* add support for Topaz */
 		if (hwmgr->not_vf) {
-			smu7_send_msg_to_smc_with_parameter(hwmgr,
+			smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SMU_DRAM_ADDR_HI,
-						upper_32_bits(smu_data->smu_buffer.mc_addr));
-			smu7_send_msg_to_smc_with_parameter(hwmgr,
+						upper_32_bits(smu_data->smu_buffer.mc_addr),
+						NULL);
+			smum_send_msg_to_smc_with_parameter(hwmgr,
 						PPSMC_MSG_SMU_DRAM_ADDR_LO,
-						lower_32_bits(smu_data->smu_buffer.mc_addr));
+						lower_32_bits(smu_data->smu_buffer.mc_addr),
+						NULL);
 		}
 		fw_to_load = UCODE_ID_RLC_G_MASK
 			   + UCODE_ID_SDMA0_MASK
@@ -423,10 +407,16 @@ int smu7_request_smu_load_fw(struct pp_hwmgr *hwmgr)
 	}
 	memcpy_toio(smu_data->header_buffer.kaddr, smu_data->toc,
 		    sizeof(struct SMU_DRAMData_TOC));
-	smu7_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_DRV_DRAM_ADDR_HI, upper_32_bits(smu_data->header_buffer.mc_addr));
-	smu7_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_DRV_DRAM_ADDR_LO, lower_32_bits(smu_data->header_buffer.mc_addr));
-
-	smu7_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_LoadUcodes, fw_to_load);
+	smum_send_msg_to_smc_with_parameter(hwmgr,
+			PPSMC_MSG_DRV_DRAM_ADDR_HI,
+			upper_32_bits(smu_data->header_buffer.mc_addr),
+			NULL);
+	smum_send_msg_to_smc_with_parameter(hwmgr,
+			PPSMC_MSG_DRV_DRAM_ADDR_LO,
+			lower_32_bits(smu_data->header_buffer.mc_addr),
+			NULL);
+
+	smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_LoadUcodes, fw_to_load, NULL);
 
 	r = smu7_check_fw_load_finish(hwmgr, fw_to_load);
 	if (!r)
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h b/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h
index 01f0538fba6b..e7303dc8c260 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h
@@ -60,11 +60,9 @@ int smu7_copy_bytes_to_smc(struct pp_hwmgr *hwmgr, uint32_t smc_start_address,
 int smu7_program_jump_on_start(struct pp_hwmgr *hwmgr);
 bool smu7_is_smc_ram_running(struct pp_hwmgr *hwmgr);
 int smu7_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg);
-int smu7_send_msg_to_smc_without_waiting(struct pp_hwmgr *hwmgr, uint16_t msg);
 int smu7_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr, uint16_t msg,
 						uint32_t parameter);
-int smu7_send_msg_to_smc_with_parameter_without_waiting(struct pp_hwmgr *hwmgr,
-						uint16_t msg, uint32_t parameter);
+uint32_t smu7_get_argument(struct pp_hwmgr *hwmgr);
 int smu7_send_msg_to_smc_offset(struct pp_hwmgr *hwmgr);
 
 enum cgs_ucode_id smu7_convert_fw_type_to_cgs(uint32_t fw_type);
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c
index 7dca04a89217..76d4f12ceedf 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c
@@ -610,18 +610,21 @@ static int smu8_download_pptable_settings(struct pp_hwmgr *hwmgr, void **table)
 
 	*table = (struct SMU8_Fusion_ClkTable *)smu8_smu->scratch_buffer[i].kaddr;
 
-	smu8_send_msg_to_smc_with_parameter(hwmgr,
+	smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_SetClkTableAddrHi,
-				upper_32_bits(smu8_smu->scratch_buffer[i].mc_addr));
+				upper_32_bits(smu8_smu->scratch_buffer[i].mc_addr),
+				NULL);
 
-	smu8_send_msg_to_smc_with_parameter(hwmgr,
+	smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_SetClkTableAddrLo,
-				lower_32_bits(smu8_smu->scratch_buffer[i].mc_addr));
+				lower_32_bits(smu8_smu->scratch_buffer[i].mc_addr),
+				NULL);
 
-	smu8_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_ExecuteJob,
-				smu8_smu->toc_entry_clock_table);
+	smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_ExecuteJob,
+				smu8_smu->toc_entry_clock_table,
+				NULL);
 
-	smu8_send_msg_to_smc(hwmgr, PPSMC_MSG_ClkTableXferToDram);
+	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ClkTableXferToDram, NULL);
 
 	return 0;
 }
@@ -637,18 +640,21 @@ static int smu8_upload_pptable_settings(struct pp_hwmgr *hwmgr)
 			break;
 	}
 
-	smu8_send_msg_to_smc_with_parameter(hwmgr,
+	smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_SetClkTableAddrHi,
-				upper_32_bits(smu8_smu->scratch_buffer[i].mc_addr));
+				upper_32_bits(smu8_smu->scratch_buffer[i].mc_addr),
+				NULL);
 
-	smu8_send_msg_to_smc_with_parameter(hwmgr,
+	smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_SetClkTableAddrLo,
-				lower_32_bits(smu8_smu->scratch_buffer[i].mc_addr));
+				lower_32_bits(smu8_smu->scratch_buffer[i].mc_addr),
+				NULL);
 
-	smu8_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_ExecuteJob,
-				smu8_smu->toc_entry_clock_table);
+	smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_ExecuteJob,
+				smu8_smu->toc_entry_clock_table,
+				NULL);
 
-	smu8_send_msg_to_smc(hwmgr, PPSMC_MSG_ClkTableXferToSmu);
+	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ClkTableXferToSmu, NULL);
 
 	return 0;
 }
@@ -671,25 +677,30 @@ static int smu8_request_smu_load_fw(struct pp_hwmgr *hwmgr)
 
 	smu8_write_smc_sram_dword(hwmgr, smc_address, 0, smc_address+4);
 
-	smu8_send_msg_to_smc_with_parameter(hwmgr,
+	smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_DriverDramAddrHi,
-					upper_32_bits(smu8_smu->toc_buffer.mc_addr));
+					upper_32_bits(smu8_smu->toc_buffer.mc_addr),
+					NULL);
 
-	smu8_send_msg_to_smc_with_parameter(hwmgr,
+	smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_DriverDramAddrLo,
-					lower_32_bits(smu8_smu->toc_buffer.mc_addr));
+					lower_32_bits(smu8_smu->toc_buffer.mc_addr),
+					NULL);
 
-	smu8_send_msg_to_smc(hwmgr, PPSMC_MSG_InitJobs);
+	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_InitJobs, NULL);
 
-	smu8_send_msg_to_smc_with_parameter(hwmgr,
+	smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_ExecuteJob,
-					smu8_smu->toc_entry_aram);
-	smu8_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_ExecuteJob,
-				smu8_smu->toc_entry_power_profiling_index);
+					smu8_smu->toc_entry_aram,
+					NULL);
+	smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_ExecuteJob,
+				smu8_smu->toc_entry_power_profiling_index,
+				NULL);
 
-	smu8_send_msg_to_smc_with_parameter(hwmgr,
+	smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_ExecuteJob,
-					smu8_smu->toc_entry_initialize_index);
+					smu8_smu->toc_entry_initialize_index,
+					NULL);
 
 	fw_to_check = UCODE_ID_RLC_G_MASK |
 			UCODE_ID_SDMA0_MASK |
@@ -860,11 +871,13 @@ static bool smu8_dpm_check_smu_features(struct pp_hwmgr *hwmgr,
 				unsigned long check_feature)
 {
 	int result;
-	unsigned long features;
+	uint32_t features;
 
-	result = smu8_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetFeatureStatus, 0);
+	result = smum_send_msg_to_smc_with_parameter(hwmgr,
+				PPSMC_MSG_GetFeatureStatus,
+				0,
+				&features);
 	if (result == 0) {
-		features = smum_get_argument(hwmgr);
 		if (features & check_feature)
 			return true;
 	}
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c
index 4240aeec9000..b6fb48066841 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c
@@ -103,14 +103,6 @@ int smum_process_firmware_header(struct pp_hwmgr *hwmgr)
 	return 0;
 }
 
-uint32_t smum_get_argument(struct pp_hwmgr *hwmgr)
-{
-	if (NULL != hwmgr->smumgr_funcs->get_argument)
-		return hwmgr->smumgr_funcs->get_argument(hwmgr);
-
-	return 0;
-}
-
 uint32_t smum_get_mac_definition(struct pp_hwmgr *hwmgr, uint32_t value)
 {
 	if (NULL != hwmgr->smumgr_funcs->get_mac_definition)
@@ -135,22 +127,58 @@ int smum_upload_powerplay_table(struct pp_hwmgr *hwmgr)
 	return 0;
 }
 
-int smum_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg)
+int smum_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg, uint32_t *resp)
 {
-	if (hwmgr == NULL || hwmgr->smumgr_funcs->send_msg_to_smc == NULL)
+	int ret = 0;
+
+	if (hwmgr == NULL ||
+	    hwmgr->smumgr_funcs->send_msg_to_smc == NULL ||
+	    (resp && !hwmgr->smumgr_funcs->get_argument))
 		return -EINVAL;
 
-	return hwmgr->smumgr_funcs->send_msg_to_smc(hwmgr, msg);
+	mutex_lock(&hwmgr->msg_lock);
+
+	ret = hwmgr->smumgr_funcs->send_msg_to_smc(hwmgr, msg);
+	if (ret) {
+		mutex_unlock(&hwmgr->msg_lock);
+		return ret;
+	}
+
+	if (resp)
+		*resp = hwmgr->smumgr_funcs->get_argument(hwmgr);
+
+	mutex_unlock(&hwmgr->msg_lock);
+
+	return ret;
 }
 
 int smum_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr,
-					uint16_t msg, uint32_t parameter)
+					uint16_t msg,
+					uint32_t parameter,
+					uint32_t *resp)
 {
+	int ret = 0;
+
 	if (hwmgr == NULL ||
-		hwmgr->smumgr_funcs->send_msg_to_smc_with_parameter == NULL)
+	    hwmgr->smumgr_funcs->send_msg_to_smc_with_parameter == NULL ||
+	    (resp && !hwmgr->smumgr_funcs->get_argument))
 		return -EINVAL;
-	return hwmgr->smumgr_funcs->send_msg_to_smc_with_parameter(
+
+	mutex_lock(&hwmgr->msg_lock);
+
+	ret = hwmgr->smumgr_funcs->send_msg_to_smc_with_parameter(
 						hwmgr, msg, parameter);
+	if (ret) {
+		mutex_unlock(&hwmgr->msg_lock);
+		return ret;
+	}
+
+	if (resp)
+		*resp = hwmgr->smumgr_funcs->get_argument(hwmgr);
+
+	mutex_unlock(&hwmgr->msg_lock);
+
+	return ret;
 }
 
 int smum_init_smc_table(struct pp_hwmgr *hwmgr)
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c
index f19bac7ef7ba..398e7e3587de 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c
@@ -2702,7 +2702,8 @@ static int tonga_update_uvd_smc_table(struct pp_hwmgr *hwmgr)
 			PHM_PlatformCaps_StablePState))
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_UVDDPM_SetEnabledMask,
-				(uint32_t)(1 << smu_data->smc_state_table.UvdBootLevel));
+				(uint32_t)(1 << smu_data->smc_state_table.UvdBootLevel),
+				NULL);
 	return 0;
 }
 
@@ -2733,7 +2734,8 @@ static int tonga_update_vce_smc_table(struct pp_hwmgr *hwmgr)
 					PHM_PlatformCaps_StablePState))
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_VCEDPM_SetEnabledMask,
-				(uint32_t)1 << smu_data->smc_state_table.VceBootLevel);
+				(uint32_t)1 << smu_data->smc_state_table.VceBootLevel,
+				NULL);
 	return 0;
 }
 
@@ -3168,7 +3170,7 @@ static int tonga_update_dpm_settings(struct pp_hwmgr *hwmgr,
 
 	if (setting->bupdate_sclk) {
 		if (!data->sclk_dpm_key_disabled)
-			smum_send_msg_to_smc(hwmgr, PPSMC_MSG_SCLKDPM_FreezeLevel);
+			smum_send_msg_to_smc(hwmgr, PPSMC_MSG_SCLKDPM_FreezeLevel, NULL);
 		for (i = 0; i < smu_data->smc_state_table.GraphicsDpmLevelCount; i++) {
 			if (levels[i].ActivityLevel !=
 				cpu_to_be16(setting->sclk_activity)) {
@@ -3198,12 +3200,12 @@ static int tonga_update_dpm_settings(struct pp_hwmgr *hwmgr,
 			}
 		}
 		if (!data->sclk_dpm_key_disabled)
-			smum_send_msg_to_smc(hwmgr, PPSMC_MSG_SCLKDPM_UnfreezeLevel);
+			smum_send_msg_to_smc(hwmgr, PPSMC_MSG_SCLKDPM_UnfreezeLevel, NULL);
 	}
 
 	if (setting->bupdate_mclk) {
 		if (!data->mclk_dpm_key_disabled)
-			smum_send_msg_to_smc(hwmgr, PPSMC_MSG_MCLKDPM_FreezeLevel);
+			smum_send_msg_to_smc(hwmgr, PPSMC_MSG_MCLKDPM_FreezeLevel, NULL);
 		for (i = 0; i < smu_data->smc_state_table.MemoryDpmLevelCount; i++) {
 			if (mclk_levels[i].ActivityLevel !=
 				cpu_to_be16(setting->mclk_activity)) {
@@ -3233,7 +3235,7 @@ static int tonga_update_dpm_settings(struct pp_hwmgr *hwmgr,
 			}
 		}
 		if (!data->mclk_dpm_key_disabled)
-			smum_send_msg_to_smc(hwmgr, PPSMC_MSG_MCLKDPM_UnfreezeLevel);
+			smum_send_msg_to_smc(hwmgr, PPSMC_MSG_MCLKDPM_UnfreezeLevel, NULL);
 	}
 	return 0;
 }
@@ -3248,6 +3250,7 @@ const struct pp_smumgr_func tonga_smu_funcs = {
 	.request_smu_load_specific_fw = NULL,
 	.send_msg_to_smc = &smu7_send_msg_to_smc,
 	.send_msg_to_smc_with_parameter = &smu7_send_msg_to_smc_with_parameter,
+	.get_argument = smu7_get_argument,
 	.download_pptable_settings = NULL,
 	.upload_pptable_settings = NULL,
 	.update_smc_table = tonga_update_smc_table,
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/vega10_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/vega10_smumgr.c
index 715564009089..1e222c5d91a4 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/vega10_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/vega10_smumgr.c
@@ -47,15 +47,18 @@ static int vega10_copy_table_from_smc(struct pp_hwmgr *hwmgr,
 			"Invalid SMU Table version!", return -EINVAL);
 	PP_ASSERT_WITH_CODE(priv->smu_tables.entry[table_id].size != 0,
 			"Invalid SMU Table Length!", return -EINVAL);
-	smu9_send_msg_to_smc_with_parameter(hwmgr,
+	smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_SetDriverDramAddrHigh,
-			upper_32_bits(priv->smu_tables.entry[table_id].mc_addr));
-	smu9_send_msg_to_smc_with_parameter(hwmgr,
+			upper_32_bits(priv->smu_tables.entry[table_id].mc_addr),
+			NULL);
+	smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_SetDriverDramAddrLow,
-			lower_32_bits(priv->smu_tables.entry[table_id].mc_addr));
-	smu9_send_msg_to_smc_with_parameter(hwmgr,
+			lower_32_bits(priv->smu_tables.entry[table_id].mc_addr),
+			NULL);
+	smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_TransferTableSmu2Dram,
-			priv->smu_tables.entry[table_id].table_id);
+			priv->smu_tables.entry[table_id].table_id,
+			NULL);
 
 	/* flush hdp cache */
 	amdgpu_asic_flush_hdp(adev, NULL);
@@ -90,15 +93,18 @@ static int vega10_copy_table_to_smc(struct pp_hwmgr *hwmgr,
 
 	amdgpu_asic_flush_hdp(adev, NULL);
 
-	smu9_send_msg_to_smc_with_parameter(hwmgr,
+	smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_SetDriverDramAddrHigh,
-			upper_32_bits(priv->smu_tables.entry[table_id].mc_addr));
-	smu9_send_msg_to_smc_with_parameter(hwmgr,
+			upper_32_bits(priv->smu_tables.entry[table_id].mc_addr),
+			NULL);
+	smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_SetDriverDramAddrLow,
-			lower_32_bits(priv->smu_tables.entry[table_id].mc_addr));
-	smu9_send_msg_to_smc_with_parameter(hwmgr,
+			lower_32_bits(priv->smu_tables.entry[table_id].mc_addr),
+			NULL);
+	smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_TransferTableDram2Smu,
-			priv->smu_tables.entry[table_id].table_id);
+			priv->smu_tables.entry[table_id].table_id,
+			NULL);
 
 	return 0;
 }
@@ -118,17 +124,21 @@ int vega10_enable_smc_features(struct pp_hwmgr *hwmgr,
 		return 0;
 
 	return smum_send_msg_to_smc_with_parameter(hwmgr,
-			msg, feature_mask);
+			msg, feature_mask, NULL);
 }
 
 int vega10_get_enabled_smc_features(struct pp_hwmgr *hwmgr,
 			    uint64_t *features_enabled)
 {
+	uint32_t enabled_features;
+
 	if (features_enabled == NULL)
 		return -EINVAL;
 
-	smu9_send_msg_to_smc(hwmgr, PPSMC_MSG_GetEnabledSmuFeatures);
-	*features_enabled = smu9_get_argument(hwmgr);
+	smum_send_msg_to_smc(hwmgr,
+			PPSMC_MSG_GetEnabledSmuFeatures,
+			&enabled_features);
+	*features_enabled = enabled_features;
 
 	return 0;
 }
@@ -150,12 +160,14 @@ static int vega10_set_tools_address(struct pp_hwmgr *hwmgr)
 	struct vega10_smumgr *priv = hwmgr->smu_backend;
 
 	if (priv->smu_tables.entry[TOOLSTABLE].mc_addr) {
-		smu9_send_msg_to_smc_with_parameter(hwmgr,
+		smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_SetToolsDramAddrHigh,
-				upper_32_bits(priv->smu_tables.entry[TOOLSTABLE].mc_addr));
-		smu9_send_msg_to_smc_with_parameter(hwmgr,
+				upper_32_bits(priv->smu_tables.entry[TOOLSTABLE].mc_addr),
+				NULL);
+		smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_SetToolsDramAddrLow,
-				lower_32_bits(priv->smu_tables.entry[TOOLSTABLE].mc_addr));
+				lower_32_bits(priv->smu_tables.entry[TOOLSTABLE].mc_addr),
+				NULL);
 	}
 	return 0;
 }
@@ -167,11 +179,11 @@ static int vega10_verify_smc_interface(struct pp_hwmgr *hwmgr)
 	uint32_t dev_id;
 	uint32_t rev_id;
 
-	PP_ASSERT_WITH_CODE(!smu9_send_msg_to_smc(hwmgr,
-			PPSMC_MSG_GetDriverIfVersion),
+	PP_ASSERT_WITH_CODE(!smum_send_msg_to_smc(hwmgr,
+			PPSMC_MSG_GetDriverIfVersion,
+			&smc_driver_if_version),
 			"Attempt to get SMC IF Version Number Failed!",
 			return -EINVAL);
-	smc_driver_if_version = smu9_get_argument(hwmgr);
 
 	dev_id = adev->pdev->device;
 	rev_id = adev->pdev->revision;
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/vega12_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/vega12_smumgr.c
index 275dbf65f1a0..f54df76537e4 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/vega12_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/vega12_smumgr.c
@@ -50,18 +50,21 @@ static int vega12_copy_table_from_smc(struct pp_hwmgr *hwmgr,
 			"Invalid SMU Table version!", return -EINVAL);
 	PP_ASSERT_WITH_CODE(priv->smu_tables.entry[table_id].size != 0,
 			"Invalid SMU Table Length!", return -EINVAL);
-	PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc_with_parameter(hwmgr,
+	PP_ASSERT_WITH_CODE(smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_SetDriverDramAddrHigh,
-			upper_32_bits(priv->smu_tables.entry[table_id].mc_addr)) == 0,
+			upper_32_bits(priv->smu_tables.entry[table_id].mc_addr),
+			NULL) == 0,
 			"[CopyTableFromSMC] Attempt to Set Dram Addr High Failed!", return -EINVAL);
-	PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc_with_parameter(hwmgr,
+	PP_ASSERT_WITH_CODE(smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_SetDriverDramAddrLow,
-			lower_32_bits(priv->smu_tables.entry[table_id].mc_addr)) == 0,
+			lower_32_bits(priv->smu_tables.entry[table_id].mc_addr),
+			NULL) == 0,
 			"[CopyTableFromSMC] Attempt to Set Dram Addr Low Failed!",
 			return -EINVAL);
-	PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc_with_parameter(hwmgr,
+	PP_ASSERT_WITH_CODE(smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_TransferTableSmu2Dram,
-			table_id) == 0,
+			table_id,
+			NULL) == 0,
 			"[CopyTableFromSMC] Attempt to Transfer Table From SMU Failed!",
 			return -EINVAL);
 
@@ -98,19 +101,22 @@ static int vega12_copy_table_to_smc(struct pp_hwmgr *hwmgr,
 
 	amdgpu_asic_flush_hdp(adev, NULL);
 
-	PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc_with_parameter(hwmgr,
+	PP_ASSERT_WITH_CODE(smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_SetDriverDramAddrHigh,
-			upper_32_bits(priv->smu_tables.entry[table_id].mc_addr)) == 0,
+			upper_32_bits(priv->smu_tables.entry[table_id].mc_addr),
+			NULL) == 0,
 			"[CopyTableToSMC] Attempt to Set Dram Addr High Failed!",
 			return -EINVAL;);
-	PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc_with_parameter(hwmgr,
+	PP_ASSERT_WITH_CODE(smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_SetDriverDramAddrLow,
-			lower_32_bits(priv->smu_tables.entry[table_id].mc_addr)) == 0,
+			lower_32_bits(priv->smu_tables.entry[table_id].mc_addr),
+			NULL) == 0,
 			"[CopyTableToSMC] Attempt to Set Dram Addr Low Failed!",
 			return -EINVAL);
-	PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc_with_parameter(hwmgr,
+	PP_ASSERT_WITH_CODE(smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_TransferTableDram2Smu,
-			table_id) == 0,
+			table_id,
+			NULL) == 0,
 			"[CopyTableToSMC] Attempt to Transfer Table To SMU Failed!",
 			return -EINVAL);
 
@@ -126,21 +132,21 @@ int vega12_enable_smc_features(struct pp_hwmgr *hwmgr,
 	smu_features_high = (uint32_t)((feature_mask & SMU_FEATURES_HIGH_MASK) >> SMU_FEATURES_HIGH_SHIFT);
 
 	if (enable) {
-		PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc_with_parameter(hwmgr,
-				PPSMC_MSG_EnableSmuFeaturesLow, smu_features_low) == 0,
+		PP_ASSERT_WITH_CODE(smum_send_msg_to_smc_with_parameter(hwmgr,
+				PPSMC_MSG_EnableSmuFeaturesLow, smu_features_low, NULL) == 0,
 				"[EnableDisableSMCFeatures] Attempt to enable SMU features Low failed!",
 				return -EINVAL);
-		PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc_with_parameter(hwmgr,
-				PPSMC_MSG_EnableSmuFeaturesHigh, smu_features_high) == 0,
+		PP_ASSERT_WITH_CODE(smum_send_msg_to_smc_with_parameter(hwmgr,
+				PPSMC_MSG_EnableSmuFeaturesHigh, smu_features_high, NULL) == 0,
 				"[EnableDisableSMCFeatures] Attempt to enable SMU features High failed!",
 				return -EINVAL);
 	} else {
-		PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc_with_parameter(hwmgr,
-				PPSMC_MSG_DisableSmuFeaturesLow, smu_features_low) == 0,
+		PP_ASSERT_WITH_CODE(smum_send_msg_to_smc_with_parameter(hwmgr,
+				PPSMC_MSG_DisableSmuFeaturesLow, smu_features_low, NULL) == 0,
 				"[EnableDisableSMCFeatures] Attempt to disable SMU features Low failed!",
 				return -EINVAL);
-		PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc_with_parameter(hwmgr,
-				PPSMC_MSG_DisableSmuFeaturesHigh, smu_features_high) == 0,
+		PP_ASSERT_WITH_CODE(smum_send_msg_to_smc_with_parameter(hwmgr,
+				PPSMC_MSG_DisableSmuFeaturesHigh, smu_features_high, NULL) == 0,
 				"[EnableDisableSMCFeatures] Attempt to disable SMU features High failed!",
 				return -EINVAL);
 	}
@@ -156,17 +162,17 @@ int vega12_get_enabled_smc_features(struct pp_hwmgr *hwmgr,
 	if (features_enabled == NULL)
 		return -EINVAL;
 
-	PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc(hwmgr,
-			PPSMC_MSG_GetEnabledSmuFeaturesLow) == 0,
+	PP_ASSERT_WITH_CODE(smum_send_msg_to_smc(hwmgr,
+			PPSMC_MSG_GetEnabledSmuFeaturesLow,
+			&smc_features_low) == 0,
 			"[GetEnabledSMCFeatures] Attempt to get SMU features Low failed!",
 			return -EINVAL);
-	smc_features_low = smu9_get_argument(hwmgr);
 
-	PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc(hwmgr,
-			PPSMC_MSG_GetEnabledSmuFeaturesHigh) == 0,
+	PP_ASSERT_WITH_CODE(smum_send_msg_to_smc(hwmgr,
+			PPSMC_MSG_GetEnabledSmuFeaturesHigh,
+			&smc_features_high) == 0,
 			"[GetEnabledSMCFeatures] Attempt to get SMU features High failed!",
 			return -EINVAL);
-	smc_features_high = smu9_get_argument(hwmgr);
 
 	*features_enabled = ((((uint64_t)smc_features_low << SMU_FEATURES_LOW_SHIFT) & SMU_FEATURES_LOW_MASK) |
 			(((uint64_t)smc_features_high << SMU_FEATURES_HIGH_SHIFT) & SMU_FEATURES_HIGH_MASK));
@@ -192,12 +198,14 @@ static int vega12_set_tools_address(struct pp_hwmgr *hwmgr)
 			(struct vega12_smumgr *)(hwmgr->smu_backend);
 
 	if (priv->smu_tables.entry[TABLE_PMSTATUSLOG].mc_addr) {
-		if (!smu9_send_msg_to_smc_with_parameter(hwmgr,
+		if (!smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_SetToolsDramAddrHigh,
-				upper_32_bits(priv->smu_tables.entry[TABLE_PMSTATUSLOG].mc_addr)))
-			smu9_send_msg_to_smc_with_parameter(hwmgr,
+				upper_32_bits(priv->smu_tables.entry[TABLE_PMSTATUSLOG].mc_addr),
+				NULL))
+			smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_SetToolsDramAddrLow,
-					lower_32_bits(priv->smu_tables.entry[TABLE_PMSTATUSLOG].mc_addr));
+					lower_32_bits(priv->smu_tables.entry[TABLE_PMSTATUSLOG].mc_addr),
+					NULL);
 	}
 	return 0;
 }
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/vega20_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/vega20_smumgr.c
index 16aa171971d3..2fb97554134f 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/vega20_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/vega20_smumgr.c
@@ -175,18 +175,20 @@ static int vega20_copy_table_from_smc(struct pp_hwmgr *hwmgr,
 	PP_ASSERT_WITH_CODE(priv->smu_tables.entry[table_id].size != 0,
 			"Invalid SMU Table Length!", return -EINVAL);
 
-	PP_ASSERT_WITH_CODE((ret = vega20_send_msg_to_smc_with_parameter(hwmgr,
+	PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_SetDriverDramAddrHigh,
-			upper_32_bits(priv->smu_tables.entry[table_id].mc_addr))) == 0,
+			upper_32_bits(priv->smu_tables.entry[table_id].mc_addr),
+			NULL)) == 0,
 			"[CopyTableFromSMC] Attempt to Set Dram Addr High Failed!",
 			return ret);
-	PP_ASSERT_WITH_CODE((ret = vega20_send_msg_to_smc_with_parameter(hwmgr,
+	PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_SetDriverDramAddrLow,
-			lower_32_bits(priv->smu_tables.entry[table_id].mc_addr))) == 0,
+			lower_32_bits(priv->smu_tables.entry[table_id].mc_addr),
+			NULL)) == 0,
 			"[CopyTableFromSMC] Attempt to Set Dram Addr Low Failed!",
 			return ret);
-	PP_ASSERT_WITH_CODE((ret = vega20_send_msg_to_smc_with_parameter(hwmgr,
-			PPSMC_MSG_TransferTableSmu2Dram, table_id)) == 0,
+	PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
+			PPSMC_MSG_TransferTableSmu2Dram, table_id, NULL)) == 0,
 			"[CopyTableFromSMC] Attempt to Transfer Table From SMU Failed!",
 			return ret);
 
@@ -224,18 +226,20 @@ static int vega20_copy_table_to_smc(struct pp_hwmgr *hwmgr,
 
 	amdgpu_asic_flush_hdp(adev, NULL);
 
-	PP_ASSERT_WITH_CODE((ret = vega20_send_msg_to_smc_with_parameter(hwmgr,
+	PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_SetDriverDramAddrHigh,
-			upper_32_bits(priv->smu_tables.entry[table_id].mc_addr))) == 0,
+			upper_32_bits(priv->smu_tables.entry[table_id].mc_addr),
+			NULL)) == 0,
 			"[CopyTableToSMC] Attempt to Set Dram Addr High Failed!",
 			return ret);
-	PP_ASSERT_WITH_CODE((ret = vega20_send_msg_to_smc_with_parameter(hwmgr,
+	PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_SetDriverDramAddrLow,
-			lower_32_bits(priv->smu_tables.entry[table_id].mc_addr))) == 0,
+			lower_32_bits(priv->smu_tables.entry[table_id].mc_addr),
+			NULL)) == 0,
 			"[CopyTableToSMC] Attempt to Set Dram Addr Low Failed!",
 			return ret);
-	PP_ASSERT_WITH_CODE((ret = vega20_send_msg_to_smc_with_parameter(hwmgr,
-			PPSMC_MSG_TransferTableDram2Smu, table_id)) == 0,
+	PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
+			PPSMC_MSG_TransferTableDram2Smu, table_id, NULL)) == 0,
 			"[CopyTableToSMC] Attempt to Transfer Table To SMU Failed!",
 			return ret);
 
@@ -255,18 +259,22 @@ int vega20_set_activity_monitor_coeff(struct pp_hwmgr *hwmgr,
 
 	amdgpu_asic_flush_hdp(adev, NULL);
 
-	PP_ASSERT_WITH_CODE((ret = vega20_send_msg_to_smc_with_parameter(hwmgr,
+	PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_SetDriverDramAddrHigh,
-			upper_32_bits(priv->smu_tables.entry[TABLE_ACTIVITY_MONITOR_COEFF].mc_addr))) == 0,
+			upper_32_bits(priv->smu_tables.entry[TABLE_ACTIVITY_MONITOR_COEFF].mc_addr),
+			NULL)) == 0,
 			"[SetActivityMonitor] Attempt to Set Dram Addr High Failed!",
 			return ret);
-	PP_ASSERT_WITH_CODE((ret = vega20_send_msg_to_smc_with_parameter(hwmgr,
+	PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_SetDriverDramAddrLow,
-			lower_32_bits(priv->smu_tables.entry[TABLE_ACTIVITY_MONITOR_COEFF].mc_addr))) == 0,
+			lower_32_bits(priv->smu_tables.entry[TABLE_ACTIVITY_MONITOR_COEFF].mc_addr),
+			NULL)) == 0,
 			"[SetActivityMonitor] Attempt to Set Dram Addr Low Failed!",
 			return ret);
-	PP_ASSERT_WITH_CODE((ret = vega20_send_msg_to_smc_with_parameter(hwmgr,
-			PPSMC_MSG_TransferTableDram2Smu, TABLE_ACTIVITY_MONITOR_COEFF | (workload_type << 16))) == 0,
+	PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
+			PPSMC_MSG_TransferTableDram2Smu,
+			TABLE_ACTIVITY_MONITOR_COEFF | (workload_type << 16),
+			NULL)) == 0,
 			"[SetActivityMonitor] Attempt to Transfer Table To SMU Failed!",
 			return ret);
 
@@ -281,19 +289,21 @@ int vega20_get_activity_monitor_coeff(struct pp_hwmgr *hwmgr,
 	struct amdgpu_device *adev = hwmgr->adev;
 	int ret = 0;
 
-	PP_ASSERT_WITH_CODE((ret = vega20_send_msg_to_smc_with_parameter(hwmgr,
+	PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_SetDriverDramAddrHigh,
-			upper_32_bits(priv->smu_tables.entry[TABLE_ACTIVITY_MONITOR_COEFF].mc_addr))) == 0,
+			upper_32_bits(priv->smu_tables.entry[TABLE_ACTIVITY_MONITOR_COEFF].mc_addr),
+			NULL)) == 0,
 			"[GetActivityMonitor] Attempt to Set Dram Addr High Failed!",
 			return ret);
-	PP_ASSERT_WITH_CODE((ret = vega20_send_msg_to_smc_with_parameter(hwmgr,
+	PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_SetDriverDramAddrLow,
-			lower_32_bits(priv->smu_tables.entry[TABLE_ACTIVITY_MONITOR_COEFF].mc_addr))) == 0,
+			lower_32_bits(priv->smu_tables.entry[TABLE_ACTIVITY_MONITOR_COEFF].mc_addr),
+			NULL)) == 0,
 			"[GetActivityMonitor] Attempt to Set Dram Addr Low Failed!",
 			return ret);
-	PP_ASSERT_WITH_CODE((ret = vega20_send_msg_to_smc_with_parameter(hwmgr,
+	PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_TransferTableSmu2Dram,
-			TABLE_ACTIVITY_MONITOR_COEFF | (workload_type << 16))) == 0,
+			TABLE_ACTIVITY_MONITOR_COEFF | (workload_type << 16), NULL)) == 0,
 			"[GetActivityMonitor] Attempt to Transfer Table From SMU Failed!",
 			return ret);
 
@@ -316,21 +326,21 @@ int vega20_enable_smc_features(struct pp_hwmgr *hwmgr,
 	smu_features_high = (uint32_t)((feature_mask & SMU_FEATURES_HIGH_MASK) >> SMU_FEATURES_HIGH_SHIFT);
 
 	if (enable) {
-		PP_ASSERT_WITH_CODE((ret = vega20_send_msg_to_smc_with_parameter(hwmgr,
-				PPSMC_MSG_EnableSmuFeaturesLow, smu_features_low)) == 0,
+		PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
+				PPSMC_MSG_EnableSmuFeaturesLow, smu_features_low, NULL)) == 0,
 				"[EnableDisableSMCFeatures] Attempt to enable SMU features Low failed!",
 				return ret);
-		PP_ASSERT_WITH_CODE((ret = vega20_send_msg_to_smc_with_parameter(hwmgr,
-				PPSMC_MSG_EnableSmuFeaturesHigh, smu_features_high)) == 0,
+		PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
+				PPSMC_MSG_EnableSmuFeaturesHigh, smu_features_high, NULL)) == 0,
 				"[EnableDisableSMCFeatures] Attempt to enable SMU features High failed!",
 				return ret);
 	} else {
-		PP_ASSERT_WITH_CODE((ret = vega20_send_msg_to_smc_with_parameter(hwmgr,
-				PPSMC_MSG_DisableSmuFeaturesLow, smu_features_low)) == 0,
+		PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
+				PPSMC_MSG_DisableSmuFeaturesLow, smu_features_low, NULL)) == 0,
 				"[EnableDisableSMCFeatures] Attempt to disable SMU features Low failed!",
 				return ret);
-		PP_ASSERT_WITH_CODE((ret = vega20_send_msg_to_smc_with_parameter(hwmgr,
-				PPSMC_MSG_DisableSmuFeaturesHigh, smu_features_high)) == 0,
+		PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
+				PPSMC_MSG_DisableSmuFeaturesHigh, smu_features_high, NULL)) == 0,
 				"[EnableDisableSMCFeatures] Attempt to disable SMU features High failed!",
 				return ret);
 	}
@@ -347,16 +357,16 @@ int vega20_get_enabled_smc_features(struct pp_hwmgr *hwmgr,
 	if (features_enabled == NULL)
 		return -EINVAL;
 
-	PP_ASSERT_WITH_CODE((ret = vega20_send_msg_to_smc(hwmgr,
-			PPSMC_MSG_GetEnabledSmuFeaturesLow)) == 0,
+	PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc(hwmgr,
+			PPSMC_MSG_GetEnabledSmuFeaturesLow,
+			&smc_features_low)) == 0,
 			"[GetEnabledSMCFeatures] Attempt to get SMU features Low failed!",
 			return ret);
-	smc_features_low = vega20_get_argument(hwmgr);
-	PP_ASSERT_WITH_CODE((ret = vega20_send_msg_to_smc(hwmgr,
-			PPSMC_MSG_GetEnabledSmuFeaturesHigh)) == 0,
+	PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc(hwmgr,
+			PPSMC_MSG_GetEnabledSmuFeaturesHigh,
+			&smc_features_high)) == 0,
 			"[GetEnabledSMCFeatures] Attempt to get SMU features High failed!",
 			return ret);
-	smc_features_high = vega20_get_argument(hwmgr);
 
 	*features_enabled = ((((uint64_t)smc_features_low << SMU_FEATURES_LOW_SHIFT) & SMU_FEATURES_LOW_MASK) |
 			(((uint64_t)smc_features_high << SMU_FEATURES_HIGH_SHIFT) & SMU_FEATURES_HIGH_MASK));
@@ -371,13 +381,15 @@ static int vega20_set_tools_address(struct pp_hwmgr *hwmgr)
 	int ret = 0;
 
 	if (priv->smu_tables.entry[TABLE_PMSTATUSLOG].mc_addr) {
-		ret = vega20_send_msg_to_smc_with_parameter(hwmgr,
+		ret = smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_SetToolsDramAddrHigh,
-				upper_32_bits(priv->smu_tables.entry[TABLE_PMSTATUSLOG].mc_addr));
+				upper_32_bits(priv->smu_tables.entry[TABLE_PMSTATUSLOG].mc_addr),
+				NULL);
 		if (!ret)
-			ret = vega20_send_msg_to_smc_with_parameter(hwmgr,
+			ret = smum_send_msg_to_smc_with_parameter(hwmgr,
 					PPSMC_MSG_SetToolsDramAddrLow,
-					lower_32_bits(priv->smu_tables.entry[TABLE_PMSTATUSLOG].mc_addr));
+					lower_32_bits(priv->smu_tables.entry[TABLE_PMSTATUSLOG].mc_addr),
+					NULL);
 	}
 
 	return ret;
@@ -389,14 +401,16 @@ int vega20_set_pptable_driver_address(struct pp_hwmgr *hwmgr)
 			(struct vega20_smumgr *)(hwmgr->smu_backend);
 	int ret = 0;
 
-	PP_ASSERT_WITH_CODE((ret = vega20_send_msg_to_smc_with_parameter(hwmgr,
+	PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_SetDriverDramAddrHigh,
-			upper_32_bits(priv->smu_tables.entry[TABLE_PPTABLE].mc_addr))) == 0,
+			upper_32_bits(priv->smu_tables.entry[TABLE_PPTABLE].mc_addr),
+			NULL)) == 0,
 			"[SetPPtabeDriverAddress] Attempt to Set Dram Addr High Failed!",
 			return ret);
-	PP_ASSERT_WITH_CODE((ret = vega20_send_msg_to_smc_with_parameter(hwmgr,
+	PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
 			PPSMC_MSG_SetDriverDramAddrLow,
-			lower_32_bits(priv->smu_tables.entry[TABLE_PPTABLE].mc_addr))) == 0,
+			lower_32_bits(priv->smu_tables.entry[TABLE_PPTABLE].mc_addr),
+			NULL)) == 0,
 			"[SetPPtabeDriverAddress] Attempt to Set Dram Addr Low Failed!",
 			return ret);
 
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/vegam_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/vegam_smumgr.c
index b0e0d67cd54b..3da71a088b92 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/vegam_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/vegam_smumgr.c
@@ -356,7 +356,8 @@ static int vegam_update_uvd_smc_table(struct pp_hwmgr *hwmgr)
 			PHM_PlatformCaps_StablePState))
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_UVDDPM_SetEnabledMask,
-				(uint32_t)(1 << smu_data->smc_state_table.UvdBootLevel));
+				(uint32_t)(1 << smu_data->smc_state_table.UvdBootLevel),
+				NULL);
 	return 0;
 }
 
@@ -388,7 +389,8 @@ static int vegam_update_vce_smc_table(struct pp_hwmgr *hwmgr)
 	if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_StablePState))
 		smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_VCEDPM_SetEnabledMask,
-				(uint32_t)1 << smu_data->smc_state_table.VceBootLevel);
+				(uint32_t)1 << smu_data->smc_state_table.VceBootLevel,
+				NULL);
 	return 0;
 }
 
@@ -1906,7 +1908,8 @@ static int vegam_enable_reconfig_cus(struct pp_hwmgr *hwmgr)
 
 	smum_send_msg_to_smc_with_parameter(hwmgr,
 					    PPSMC_MSG_EnableModeSwitchRLCNotification,
-					    adev->gfx.cu_info.number);
+					    adev->gfx.cu_info.number,
+					    NULL);
 
 	return 0;
 }
@@ -2060,7 +2063,7 @@ static int vegam_init_smc_table(struct pp_hwmgr *hwmgr)
 		table->AcDcGpio = gpio_pin.uc_gpio_pin_bit_shift;
 		if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
 				PHM_PlatformCaps_AutomaticDCTransition) &&
-				!smum_send_msg_to_smc(hwmgr, PPSMC_MSG_UseNewGPIOScheme))
+				!smum_send_msg_to_smc(hwmgr, PPSMC_MSG_UseNewGPIOScheme, NULL))
 			phm_cap_set(hwmgr->platform_descriptor.platformCaps,
 					PHM_PlatformCaps_SMCtoPPLIBAcdcGpioScheme);
 	} else {
@@ -2250,10 +2253,12 @@ int vegam_thermal_avfs_enable(struct pp_hwmgr *hwmgr)
 	if (!hwmgr->avfs_supported)
 		return 0;
 
-	ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_EnableAvfs);
+	ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_EnableAvfs, NULL);
 	if (!ret) {
 		if (data->apply_avfs_cks_off_voltage)
-			ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ApplyAvfsCksOffVoltage);
+			ret = smum_send_msg_to_smc(hwmgr,
+					PPSMC_MSG_ApplyAvfsCksOffVoltage,
+					NULL);
 	}
 
 	return ret;
@@ -2279,6 +2284,7 @@ const struct pp_smumgr_func vegam_smu_funcs = {
 	.request_smu_load_specific_fw = NULL,
 	.send_msg_to_smc = smu7_send_msg_to_smc,
 	.send_msg_to_smc_with_parameter = smu7_send_msg_to_smc_with_parameter,
+	.get_argument = smu7_get_argument,
 	.process_firmware_header = vegam_process_firmware_header,
 	.is_dpm_running = vegam_is_dpm_running,
 	.get_mac_definition = vegam_get_mac_definition,
diff --git a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c
index 3f1044326dcb..61923530b2e4 100644
--- a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c
@@ -1796,7 +1796,7 @@ static int vega20_get_power_profile_mode(struct smu_context *smu, char *buf)
 			"PD_Data_error_rate_coeff"};
 	int result = 0;
 
-	if (!smu->pm_enabled || !buf)
+	if (!buf)
 		return -EINVAL;
 
 	size += sprintf(buf + size, "%16s %s %s %s %s %s %s %s %s %s %s\n",
@@ -1887,8 +1887,6 @@ static int vega20_set_power_profile_mode(struct smu_context *smu, long *input, u
 
 	smu->power_profile_mode = input[size];
 
-	if (!smu->pm_enabled)
-		return ret;
 	if (smu->power_profile_mode > PP_SMC_POWER_PROFILE_CUSTOM) {
 		pr_err("Invalid power profile mode %d\n", smu->power_profile_mode);
 		return -EINVAL;
diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c
index d6a6692db0ac..c05d001163e0 100644
--- a/drivers/gpu/drm/arc/arcpgu_drv.c
+++ b/drivers/gpu/drm/arc/arcpgu_drv.c
@@ -137,10 +137,11 @@ static struct drm_info_list arcpgu_debugfs_list[] = {
 	{ "clocks", arcpgu_show_pxlclock, 0 },
 };
 
-static int arcpgu_debugfs_init(struct drm_minor *minor)
+static void arcpgu_debugfs_init(struct drm_minor *minor)
 {
-	return drm_debugfs_create_files(arcpgu_debugfs_list,
-		ARRAY_SIZE(arcpgu_debugfs_list), minor->debugfs_root, minor);
+	drm_debugfs_create_files(arcpgu_debugfs_list,
+				 ARRAY_SIZE(arcpgu_debugfs_list),
+				 minor->debugfs_root, minor);
 }
 #endif
 
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
index 442d4656150a..16dfd5cdb66c 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
@@ -14,6 +14,7 @@
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
 #include <drm/drm_irq.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/drm_vblank.h>
 
@@ -271,6 +272,7 @@ struct komeda_kms_dev *komeda_kms_attach(struct komeda_dev *mdev)
 	err = drm_dev_init(drm, &komeda_kms_driver, mdev->dev);
 	if (err)
 		goto free_kms;
+	drmm_add_final_kfree(drm, kms);
 
 	drm->dev_private = mdev;
 
diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
index 2e053815b54a..194419f47c5e 100644
--- a/drivers/gpu/drm/arm/hdlcd_drv.c
+++ b/drivers/gpu/drm/arm/hdlcd_drv.c
@@ -224,10 +224,11 @@ static struct drm_info_list hdlcd_debugfs_list[] = {
 	{ "clocks", hdlcd_show_pxlclock, 0 },
 };
 
-static int hdlcd_debugfs_init(struct drm_minor *minor)
+static void hdlcd_debugfs_init(struct drm_minor *minor)
 {
-	return drm_debugfs_create_files(hdlcd_debugfs_list,
-		ARRAY_SIZE(hdlcd_debugfs_list),	minor->debugfs_root, minor);
+	drm_debugfs_create_files(hdlcd_debugfs_list,
+				 ARRAY_SIZE(hdlcd_debugfs_list),
+				 minor->debugfs_root, minor);
 }
 #endif
 
diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c
index 37d92a06318e..def8c9ffafca 100644
--- a/drivers/gpu/drm/arm/malidp_drv.c
+++ b/drivers/gpu/drm/arm/malidp_drv.c
@@ -548,7 +548,7 @@ static const struct file_operations malidp_debugfs_fops = {
 	.release = single_release,
 };
 
-static int malidp_debugfs_init(struct drm_minor *minor)
+static void malidp_debugfs_init(struct drm_minor *minor)
 {
 	struct malidp_drm *malidp = minor->dev->dev_private;
 
@@ -557,7 +557,6 @@ static int malidp_debugfs_init(struct drm_minor *minor)
 	spin_lock_init(&malidp->errors_lock);
 	debugfs_create_file("debug", S_IRUGO | S_IWUSR, minor->debugfs_root,
 			    minor->dev, &malidp_debugfs_fops);
-	return 0;
 }
 
 #endif //CONFIG_DEBUG_FS
diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c
index 197dca3fc84c..dd9ed71ed942 100644
--- a/drivers/gpu/drm/armada/armada_drv.c
+++ b/drivers/gpu/drm/armada/armada_drv.c
@@ -12,6 +12,7 @@
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_drv.h>
 #include <drm/drm_ioctl.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_prime.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/drm_fb_helper.h>
@@ -103,6 +104,7 @@ static int armada_drm_bind(struct device *dev)
 		kfree(priv);
 		return ret;
 	}
+	drmm_add_final_kfree(&priv->drm, priv);
 
 	/* Remove early framebuffers */
 	ret = drm_fb_helper_remove_conflicting_framebuffers(NULL,
diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c
index 30aa73a5d9b7..b7ba22dddcad 100644
--- a/drivers/gpu/drm/ast/ast_drv.c
+++ b/drivers/gpu/drm/ast/ast_drv.c
@@ -32,6 +32,7 @@
 
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_drv.h>
+#include <drm/drm_fb_helper.h>
 #include <drm/drm_gem_vram_helper.h>
 #include <drm/drm_probe_helper.h>
 
@@ -111,6 +112,8 @@ static int ast_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	if (ret)
 		goto err_ast_driver_unload;
 
+	drm_fbdev_generic_setup(dev, 32);
+
 	return 0;
 
 err_ast_driver_unload:
diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c
index 18a0a4ce00f6..e5398e3dabe7 100644
--- a/drivers/gpu/drm/ast/ast_main.c
+++ b/drivers/gpu/drm/ast/ast_main.c
@@ -30,7 +30,6 @@
 
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc_helper.h>
-#include <drm/drm_fb_helper.h>
 #include <drm/drm_gem.h>
 #include <drm/drm_gem_framebuffer_helper.h>
 #include <drm/drm_gem_vram_helper.h>
@@ -512,10 +511,6 @@ int ast_driver_load(struct drm_device *dev, unsigned long flags)
 
 	drm_mode_config_reset(dev);
 
-	ret = drm_fbdev_generic_setup(dev, 32);
-	if (ret)
-		goto out_free;
-
 	return 0;
 out_free:
 	kfree(ast);
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_output.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_output.c
index e2019fe97fff..43bc709e3523 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_output.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_output.c
@@ -11,9 +11,10 @@
 #include <linux/media-bus-format.h>
 #include <linux/of_graph.h>
 
+#include <drm/drm_bridge.h>
 #include <drm/drm_encoder.h>
 #include <drm/drm_of.h>
-#include <drm/drm_bridge.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "atmel_hlcdc_dc.h"
 
@@ -22,10 +23,6 @@ struct atmel_hlcdc_rgb_output {
 	int bus_fmt;
 };
 
-static const struct drm_encoder_funcs atmel_hlcdc_panel_encoder_funcs = {
-	.destroy = drm_encoder_cleanup,
-};
-
 static struct atmel_hlcdc_rgb_output *
 atmel_hlcdc_encoder_to_rgb_output(struct drm_encoder *encoder)
 {
@@ -98,9 +95,8 @@ static int atmel_hlcdc_attach_endpoint(struct drm_device *dev, int endpoint)
 		return -EINVAL;
 	}
 
-	ret = drm_encoder_init(dev, &output->encoder,
-			       &atmel_hlcdc_panel_encoder_funcs,
-			       DRM_MODE_ENCODER_NONE, NULL);
+	ret = drm_simple_encoder_init(dev, &output->encoder,
+				      DRM_MODE_ENCODER_NONE);
 	if (ret)
 		return ret;
 
diff --git a/drivers/gpu/drm/bochs/bochs.h b/drivers/gpu/drm/bochs/bochs.h
index 917767173ee6..e5bd1d517a18 100644
--- a/drivers/gpu/drm/bochs/bochs.h
+++ b/drivers/gpu/drm/bochs/bochs.h
@@ -92,7 +92,6 @@ void bochs_mm_fini(struct bochs_device *bochs);
 
 /* bochs_kms.c */
 int bochs_kms_init(struct bochs_device *bochs);
-void bochs_kms_fini(struct bochs_device *bochs);
 
 /* bochs_fbdev.c */
 extern const struct drm_mode_config_funcs bochs_mode_funcs;
diff --git a/drivers/gpu/drm/bochs/bochs_drv.c b/drivers/gpu/drm/bochs/bochs_drv.c
index addb0568c1af..e18c51de1196 100644
--- a/drivers/gpu/drm/bochs/bochs_drv.c
+++ b/drivers/gpu/drm/bochs/bochs_drv.c
@@ -7,6 +7,7 @@
 
 #include <drm/drm_drv.h>
 #include <drm/drm_atomic_helper.h>
+#include <drm/drm_managed.h>
 
 #include "bochs.h"
 
@@ -21,10 +22,7 @@ static void bochs_unload(struct drm_device *dev)
 {
 	struct bochs_device *bochs = dev->dev_private;
 
-	bochs_kms_fini(bochs);
 	bochs_mm_fini(bochs);
-	kfree(bochs);
-	dev->dev_private = NULL;
 }
 
 static int bochs_load(struct drm_device *dev)
@@ -32,7 +30,7 @@ static int bochs_load(struct drm_device *dev)
 	struct bochs_device *bochs;
 	int ret;
 
-	bochs = kzalloc(sizeof(*bochs), GFP_KERNEL);
+	bochs = drmm_kzalloc(dev, sizeof(*bochs), GFP_KERNEL);
 	if (bochs == NULL)
 		return -ENOMEM;
 	dev->dev_private = bochs;
diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c
index 8066d7d370d5..7f4bcfad87e9 100644
--- a/drivers/gpu/drm/bochs/bochs_kms.c
+++ b/drivers/gpu/drm/bochs/bochs_kms.c
@@ -134,7 +134,11 @@ const struct drm_mode_config_funcs bochs_mode_funcs = {
 
 int bochs_kms_init(struct bochs_device *bochs)
 {
-	drm_mode_config_init(bochs->dev);
+	int ret;
+
+	ret = drmm_mode_config_init(bochs->dev);
+	if (ret)
+		return ret;
 
 	bochs->dev->mode_config.max_width = 8192;
 	bochs->dev->mode_config.max_height = 8192;
@@ -160,12 +164,3 @@ int bochs_kms_init(struct bochs_device *bochs)
 
 	return 0;
 }
-
-void bochs_kms_fini(struct bochs_device *bochs)
-{
-	if (!bochs->dev->mode_config.num_connector)
-		return;
-
-	drm_atomic_helper_shutdown(bochs->dev);
-	drm_mode_config_cleanup(bochs->dev);
-}
diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index aaed2347ace9..6ec945f837b8 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -58,6 +58,22 @@ config DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW
 	  to DP++. This is used with the i.MX6 imx-ldb
 	  driver. You are likely to say N here.
 
+config DRM_NWL_MIPI_DSI
+	tristate "Northwest Logic MIPI DSI Host controller"
+	depends on DRM
+	depends on COMMON_CLK
+	depends on OF && HAS_IOMEM
+	select DRM_KMS_HELPER
+	select DRM_MIPI_DSI
+	select DRM_PANEL_BRIDGE
+	select GENERIC_PHY_MIPI_DPHY
+	select MFD_SYSCON
+	select MULTIPLEXER
+	select REGMAP_MMIO
+	help
+	  This enables the Northwest Logic MIPI DSI Host controller as
+	  for example found on NXP's i.MX8 Processors.
+
 config DRM_NXP_PTN3460
 	tristate "NXP PTN3460 DP/LVDS bridge"
 	depends on OF
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index 6fb062b5b0f0..b04ac2dfa22c 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/
 obj-$(CONFIG_DRM_TI_SN65DSI86) += ti-sn65dsi86.o
 obj-$(CONFIG_DRM_TI_TFP410) += ti-tfp410.o
 obj-$(CONFIG_DRM_TI_TPD12S015) += ti-tpd12s015.o
+obj-$(CONFIG_DRM_NWL_MIPI_DSI) += nwl-dsi.o
 
 obj-y += analogix/
 obj-y += synopsys/
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c b/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c
index a428185be2c1..f101dd2819b5 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c
@@ -19,13 +19,15 @@ static void adv7511_calc_cts_n(unsigned int f_tmds, unsigned int fs,
 {
 	switch (fs) {
 	case 32000:
-		*n = 4096;
+	case 48000:
+	case 96000:
+	case 192000:
+		*n = fs * 128 / 1000;
 		break;
 	case 44100:
-		*n = 6272;
-		break;
-	case 48000:
-		*n = 6144;
+	case 88200:
+	case 176400:
+		*n = fs * 128 / 900;
 		break;
 	}
 
@@ -119,6 +121,9 @@ int adv7511_hdmi_hw_params(struct device *dev, void *data,
 		audio_source = ADV7511_AUDIO_SOURCE_I2S;
 		i2s_format = ADV7511_I2S_FORMAT_LEFT_J;
 		break;
+	case HDMI_SPDIF:
+		audio_source = ADV7511_AUDIO_SOURCE_SPDIF;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -175,11 +180,21 @@ static int audio_startup(struct device *dev, void *data)
 	/* use Audio infoframe updated info */
 	regmap_update_bits(adv7511->regmap, ADV7511_REG_GC(1),
 				BIT(5), 0);
+	/* enable SPDIF receiver */
+	if (adv7511->audio_source == ADV7511_AUDIO_SOURCE_SPDIF)
+		regmap_update_bits(adv7511->regmap, ADV7511_REG_AUDIO_CONFIG,
+				   BIT(7), BIT(7));
+
 	return 0;
 }
 
 static void audio_shutdown(struct device *dev, void *data)
 {
+	struct adv7511 *adv7511 = dev_get_drvdata(dev);
+
+	if (adv7511->audio_source == ADV7511_AUDIO_SOURCE_SPDIF)
+		regmap_update_bits(adv7511->regmap, ADV7511_REG_AUDIO_CONFIG,
+				   BIT(7), 0);
 }
 
 static int adv7511_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
@@ -213,6 +228,7 @@ static const struct hdmi_codec_pdata codec_data = {
 	.ops = &adv7511_codec_ops,
 	.max_i2s_channels = 2,
 	.i2s = 1,
+	.spdif = 1,
 };
 
 int adv7511_audio_init(struct device *dev, struct adv7511 *adv7511)
diff --git a/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c b/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c
index 2bc6e4f85171..9af39ec958db 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c
@@ -485,6 +485,9 @@ static int anx6345_get_modes(struct drm_connector *connector)
 
 	num_modes += drm_add_edid_modes(connector, anx6345->edid);
 
+	/* Driver currently supports only 6bpc */
+	connector->display_info.bpc = 6;
+
 unlock:
 	if (power_off)
 		anx6345_poweroff(anx6345);
diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
new file mode 100644
index 000000000000..b14d725bf609
--- /dev/null
+++ b/drivers/gpu/drm/bridge/nwl-dsi.c
@@ -0,0 +1,1213 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * i.MX8 NWL MIPI DSI host driver
+ *
+ * Copyright (C) 2017 NXP
+ * Copyright (C) 2020 Purism SPC
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/irq.h>
+#include <linux/math64.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/mux/consumer.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/phy/phy.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <linux/sys_soc.h>
+#include <linux/time64.h>
+
+#include <drm/drm_bridge.h>
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_of.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_print.h>
+
+#include <video/mipi_display.h>
+
+#include "nwl-dsi.h"
+
+#define DRV_NAME "nwl-dsi"
+
+/* i.MX8 NWL quirks */
+/* i.MX8MQ errata E11418 */
+#define E11418_HS_MODE_QUIRK	BIT(0)
+
+#define NWL_DSI_MIPI_FIFO_TIMEOUT msecs_to_jiffies(500)
+
+enum transfer_direction {
+	DSI_PACKET_SEND,
+	DSI_PACKET_RECEIVE,
+};
+
+#define NWL_DSI_ENDPOINT_LCDIF 0
+#define NWL_DSI_ENDPOINT_DCSS 1
+
+struct nwl_dsi_plat_clk_config {
+	const char *id;
+	struct clk *clk;
+	bool present;
+};
+
+struct nwl_dsi_transfer {
+	const struct mipi_dsi_msg *msg;
+	struct mipi_dsi_packet packet;
+	struct completion completed;
+
+	int status; /* status of transmission */
+	enum transfer_direction direction;
+	bool need_bta;
+	u8 cmd;
+	u16 rx_word_count;
+	size_t tx_len; /* in bytes */
+	size_t rx_len; /* in bytes */
+};
+
+struct nwl_dsi {
+	struct drm_bridge bridge;
+	struct mipi_dsi_host dsi_host;
+	struct drm_bridge *panel_bridge;
+	struct device *dev;
+	struct phy *phy;
+	union phy_configure_opts phy_cfg;
+	unsigned int quirks;
+
+	struct regmap *regmap;
+	int irq;
+	/*
+	 * The DSI host controller needs this reset sequence according to NWL:
+	 * 1. Deassert pclk reset to get access to DSI regs
+	 * 2. Configure DSI Host and DPHY and enable DPHY
+	 * 3. Deassert ESC and BYTE resets to allow host TX operations)
+	 * 4. Send DSI cmds to configure peripheral (handled by panel drv)
+	 * 5. Deassert DPI reset so DPI receives pixels and starts sending
+	 *    DSI data
+	 *
+	 * TODO: Since panel_bridges do their DSI setup in enable we
+	 * currently have 4. and 5. swapped.
+	 */
+	struct reset_control *rst_byte;
+	struct reset_control *rst_esc;
+	struct reset_control *rst_dpi;
+	struct reset_control *rst_pclk;
+	struct mux_control *mux;
+
+	/* DSI clocks */
+	struct clk *phy_ref_clk;
+	struct clk *rx_esc_clk;
+	struct clk *tx_esc_clk;
+	struct clk *core_clk;
+	/*
+	 * hardware bug: the i.MX8MQ needs this clock on during reset
+	 * even when not using LCDIF.
+	 */
+	struct clk *lcdif_clk;
+
+	/* dsi lanes */
+	u32 lanes;
+	enum mipi_dsi_pixel_format format;
+	struct drm_display_mode mode;
+	unsigned long dsi_mode_flags;
+	int error;
+
+	struct nwl_dsi_transfer *xfer;
+};
+
+static const struct regmap_config nwl_dsi_regmap_config = {
+	.reg_bits = 16,
+	.val_bits = 32,
+	.reg_stride = 4,
+	.max_register = NWL_DSI_IRQ_MASK2,
+	.name = DRV_NAME,
+};
+
+static inline struct nwl_dsi *bridge_to_dsi(struct drm_bridge *bridge)
+{
+	return container_of(bridge, struct nwl_dsi, bridge);
+}
+
+static int nwl_dsi_clear_error(struct nwl_dsi *dsi)
+{
+	int ret = dsi->error;
+
+	dsi->error = 0;
+	return ret;
+}
+
+static void nwl_dsi_write(struct nwl_dsi *dsi, unsigned int reg, u32 val)
+{
+	int ret;
+
+	if (dsi->error)
+		return;
+
+	ret = regmap_write(dsi->regmap, reg, val);
+	if (ret < 0) {
+		DRM_DEV_ERROR(dsi->dev,
+			      "Failed to write NWL DSI reg 0x%x: %d\n", reg,
+			      ret);
+		dsi->error = ret;
+	}
+}
+
+static u32 nwl_dsi_read(struct nwl_dsi *dsi, u32 reg)
+{
+	unsigned int val;
+	int ret;
+
+	if (dsi->error)
+		return 0;
+
+	ret = regmap_read(dsi->regmap, reg, &val);
+	if (ret < 0) {
+		DRM_DEV_ERROR(dsi->dev, "Failed to read NWL DSI reg 0x%x: %d\n",
+			      reg, ret);
+		dsi->error = ret;
+	}
+	return val;
+}
+
+static int nwl_dsi_get_dpi_pixel_format(enum mipi_dsi_pixel_format format)
+{
+	switch (format) {
+	case MIPI_DSI_FMT_RGB565:
+		return NWL_DSI_PIXEL_FORMAT_16;
+	case MIPI_DSI_FMT_RGB666:
+		return NWL_DSI_PIXEL_FORMAT_18L;
+	case MIPI_DSI_FMT_RGB666_PACKED:
+		return NWL_DSI_PIXEL_FORMAT_18;
+	case MIPI_DSI_FMT_RGB888:
+		return NWL_DSI_PIXEL_FORMAT_24;
+	default:
+		return -EINVAL;
+	}
+}
+
+/*
+ * ps2bc - Picoseconds to byte clock cycles
+ */
+static u32 ps2bc(struct nwl_dsi *dsi, unsigned long long ps)
+{
+	u32 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
+
+	return DIV64_U64_ROUND_UP(ps * dsi->mode.clock * bpp,
+				  dsi->lanes * 8 * NSEC_PER_SEC);
+}
+
+/*
+ * ui2bc - UI time periods to byte clock cycles
+ */
+static u32 ui2bc(struct nwl_dsi *dsi, unsigned long long ui)
+{
+	u32 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
+
+	return DIV64_U64_ROUND_UP(ui * dsi->lanes,
+				  dsi->mode.clock * 1000 * bpp);
+}
+
+/*
+ * us2bc - micro seconds to lp clock cycles
+ */
+static u32 us2lp(u32 lp_clk_rate, unsigned long us)
+{
+	return DIV_ROUND_UP(us * lp_clk_rate, USEC_PER_SEC);
+}
+
+static int nwl_dsi_config_host(struct nwl_dsi *dsi)
+{
+	u32 cycles;
+	struct phy_configure_opts_mipi_dphy *cfg = &dsi->phy_cfg.mipi_dphy;
+
+	if (dsi->lanes < 1 || dsi->lanes > 4)
+		return -EINVAL;
+
+	DRM_DEV_DEBUG_DRIVER(dsi->dev, "DSI Lanes %d\n", dsi->lanes);
+	nwl_dsi_write(dsi, NWL_DSI_CFG_NUM_LANES, dsi->lanes - 1);
+
+	if (dsi->dsi_mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) {
+		nwl_dsi_write(dsi, NWL_DSI_CFG_NONCONTINUOUS_CLK, 0x01);
+		nwl_dsi_write(dsi, NWL_DSI_CFG_AUTOINSERT_EOTP, 0x01);
+	} else {
+		nwl_dsi_write(dsi, NWL_DSI_CFG_NONCONTINUOUS_CLK, 0x00);
+		nwl_dsi_write(dsi, NWL_DSI_CFG_AUTOINSERT_EOTP, 0x00);
+	}
+
+	/* values in byte clock cycles */
+	cycles = ui2bc(dsi, cfg->clk_pre);
+	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_pre: 0x%x\n", cycles);
+	nwl_dsi_write(dsi, NWL_DSI_CFG_T_PRE, cycles);
+	cycles = ps2bc(dsi, cfg->lpx + cfg->clk_prepare + cfg->clk_zero);
+	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_tx_gap (pre): 0x%x\n", cycles);
+	cycles += ui2bc(dsi, cfg->clk_pre);
+	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_post: 0x%x\n", cycles);
+	nwl_dsi_write(dsi, NWL_DSI_CFG_T_POST, cycles);
+	cycles = ps2bc(dsi, cfg->hs_exit);
+	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_tx_gap: 0x%x\n", cycles);
+	nwl_dsi_write(dsi, NWL_DSI_CFG_TX_GAP, cycles);
+
+	nwl_dsi_write(dsi, NWL_DSI_CFG_EXTRA_CMDS_AFTER_EOTP, 0x01);
+	nwl_dsi_write(dsi, NWL_DSI_CFG_HTX_TO_COUNT, 0x00);
+	nwl_dsi_write(dsi, NWL_DSI_CFG_LRX_H_TO_COUNT, 0x00);
+	nwl_dsi_write(dsi, NWL_DSI_CFG_BTA_H_TO_COUNT, 0x00);
+	/* In LP clock cycles */
+	cycles = us2lp(cfg->lp_clk_rate, cfg->wakeup);
+	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_twakeup: 0x%x\n", cycles);
+	nwl_dsi_write(dsi, NWL_DSI_CFG_TWAKEUP, cycles);
+
+	return nwl_dsi_clear_error(dsi);
+}
+
+static int nwl_dsi_config_dpi(struct nwl_dsi *dsi)
+{
+	u32 mode;
+	int color_format;
+	bool burst_mode;
+	int hfront_porch, hback_porch, vfront_porch, vback_porch;
+	int hsync_len, vsync_len;
+
+	hfront_porch = dsi->mode.hsync_start - dsi->mode.hdisplay;
+	hsync_len = dsi->mode.hsync_end - dsi->mode.hsync_start;
+	hback_porch = dsi->mode.htotal - dsi->mode.hsync_end;
+
+	vfront_porch = dsi->mode.vsync_start - dsi->mode.vdisplay;
+	vsync_len = dsi->mode.vsync_end - dsi->mode.vsync_start;
+	vback_porch = dsi->mode.vtotal - dsi->mode.vsync_end;
+
+	DRM_DEV_DEBUG_DRIVER(dsi->dev, "hfront_porch = %d\n", hfront_porch);
+	DRM_DEV_DEBUG_DRIVER(dsi->dev, "hback_porch = %d\n", hback_porch);
+	DRM_DEV_DEBUG_DRIVER(dsi->dev, "hsync_len = %d\n", hsync_len);
+	DRM_DEV_DEBUG_DRIVER(dsi->dev, "hdisplay = %d\n", dsi->mode.hdisplay);
+	DRM_DEV_DEBUG_DRIVER(dsi->dev, "vfront_porch = %d\n", vfront_porch);
+	DRM_DEV_DEBUG_DRIVER(dsi->dev, "vback_porch = %d\n", vback_porch);
+	DRM_DEV_DEBUG_DRIVER(dsi->dev, "vsync_len = %d\n", vsync_len);
+	DRM_DEV_DEBUG_DRIVER(dsi->dev, "vactive = %d\n", dsi->mode.vdisplay);
+	DRM_DEV_DEBUG_DRIVER(dsi->dev, "clock = %d kHz\n", dsi->mode.clock);
+
+	color_format = nwl_dsi_get_dpi_pixel_format(dsi->format);
+	if (color_format < 0) {
+		DRM_DEV_ERROR(dsi->dev, "Invalid color format 0x%x\n",
+			      dsi->format);
+		return color_format;
+	}
+	DRM_DEV_DEBUG_DRIVER(dsi->dev, "pixel fmt = %d\n", dsi->format);
+
+	nwl_dsi_write(dsi, NWL_DSI_INTERFACE_COLOR_CODING, NWL_DSI_DPI_24_BIT);
+	nwl_dsi_write(dsi, NWL_DSI_PIXEL_FORMAT, color_format);
+	/*
+	 * Adjusting input polarity based on the video mode results in
+	 * a black screen so always pick active low:
+	 */
+	nwl_dsi_write(dsi, NWL_DSI_VSYNC_POLARITY,
+		      NWL_DSI_VSYNC_POLARITY_ACTIVE_LOW);
+	nwl_dsi_write(dsi, NWL_DSI_HSYNC_POLARITY,
+		      NWL_DSI_HSYNC_POLARITY_ACTIVE_LOW);
+
+	burst_mode = (dsi->dsi_mode_flags & MIPI_DSI_MODE_VIDEO_BURST) &&
+		     !(dsi->dsi_mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE);
+
+	if (burst_mode) {
+		nwl_dsi_write(dsi, NWL_DSI_VIDEO_MODE, NWL_DSI_VM_BURST_MODE);
+		nwl_dsi_write(dsi, NWL_DSI_PIXEL_FIFO_SEND_LEVEL, 256);
+	} else {
+		mode = ((dsi->dsi_mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) ?
+				NWL_DSI_VM_BURST_MODE_WITH_SYNC_PULSES :
+				NWL_DSI_VM_NON_BURST_MODE_WITH_SYNC_EVENTS);
+		nwl_dsi_write(dsi, NWL_DSI_VIDEO_MODE, mode);
+		nwl_dsi_write(dsi, NWL_DSI_PIXEL_FIFO_SEND_LEVEL,
+			      dsi->mode.hdisplay);
+	}
+
+	nwl_dsi_write(dsi, NWL_DSI_HFP, hfront_porch);
+	nwl_dsi_write(dsi, NWL_DSI_HBP, hback_porch);
+	nwl_dsi_write(dsi, NWL_DSI_HSA, hsync_len);
+
+	nwl_dsi_write(dsi, NWL_DSI_ENABLE_MULT_PKTS, 0x0);
+	nwl_dsi_write(dsi, NWL_DSI_BLLP_MODE, 0x1);
+	nwl_dsi_write(dsi, NWL_DSI_USE_NULL_PKT_BLLP, 0x0);
+	nwl_dsi_write(dsi, NWL_DSI_VC, 0x0);
+
+	nwl_dsi_write(dsi, NWL_DSI_PIXEL_PAYLOAD_SIZE, dsi->mode.hdisplay);
+	nwl_dsi_write(dsi, NWL_DSI_VACTIVE, dsi->mode.vdisplay - 1);
+	nwl_dsi_write(dsi, NWL_DSI_VBP, vback_porch);
+	nwl_dsi_write(dsi, NWL_DSI_VFP, vfront_porch);
+
+	return nwl_dsi_clear_error(dsi);
+}
+
+static int nwl_dsi_init_interrupts(struct nwl_dsi *dsi)
+{
+	u32 irq_enable;
+
+	nwl_dsi_write(dsi, NWL_DSI_IRQ_MASK, 0xffffffff);
+	nwl_dsi_write(dsi, NWL_DSI_IRQ_MASK2, 0x7);
+
+	irq_enable = ~(u32)(NWL_DSI_TX_PKT_DONE_MASK |
+			    NWL_DSI_RX_PKT_HDR_RCVD_MASK |
+			    NWL_DSI_TX_FIFO_OVFLW_MASK |
+			    NWL_DSI_HS_TX_TIMEOUT_MASK);
+
+	nwl_dsi_write(dsi, NWL_DSI_IRQ_MASK, irq_enable);
+
+	return nwl_dsi_clear_error(dsi);
+}
+
+static int nwl_dsi_host_attach(struct mipi_dsi_host *dsi_host,
+			       struct mipi_dsi_device *device)
+{
+	struct nwl_dsi *dsi = container_of(dsi_host, struct nwl_dsi, dsi_host);
+	struct device *dev = dsi->dev;
+
+	DRM_DEV_INFO(dev, "lanes=%u, format=0x%x flags=0x%lx\n", device->lanes,
+		     device->format, device->mode_flags);
+
+	if (device->lanes < 1 || device->lanes > 4)
+		return -EINVAL;
+
+	dsi->lanes = device->lanes;
+	dsi->format = device->format;
+	dsi->dsi_mode_flags = device->mode_flags;
+
+	return 0;
+}
+
+static bool nwl_dsi_read_packet(struct nwl_dsi *dsi, u32 status)
+{
+	struct device *dev = dsi->dev;
+	struct nwl_dsi_transfer *xfer = dsi->xfer;
+	int err;
+	u8 *payload = xfer->msg->rx_buf;
+	u32 val;
+	u16 word_count;
+	u8 channel;
+	u8 data_type;
+
+	xfer->status = 0;
+
+	if (xfer->rx_word_count == 0) {
+		if (!(status & NWL_DSI_RX_PKT_HDR_RCVD))
+			return false;
+		/* Get the RX header and parse it */
+		val = nwl_dsi_read(dsi, NWL_DSI_RX_PKT_HEADER);
+		err = nwl_dsi_clear_error(dsi);
+		if (err)
+			xfer->status = err;
+		word_count = NWL_DSI_WC(val);
+		channel = NWL_DSI_RX_VC(val);
+		data_type = NWL_DSI_RX_DT(val);
+
+		if (channel != xfer->msg->channel) {
+			DRM_DEV_ERROR(dev,
+				      "[%02X] Channel mismatch (%u != %u)\n",
+				      xfer->cmd, channel, xfer->msg->channel);
+			xfer->status = -EINVAL;
+			return true;
+		}
+
+		switch (data_type) {
+		case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE:
+			fallthrough;
+		case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE:
+			if (xfer->msg->rx_len > 1) {
+				/* read second byte */
+				payload[1] = word_count >> 8;
+				++xfer->rx_len;
+			}
+			fallthrough;
+		case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE:
+			fallthrough;
+		case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE:
+			if (xfer->msg->rx_len > 0) {
+				/* read first byte */
+				payload[0] = word_count & 0xff;
+				++xfer->rx_len;
+			}
+			xfer->status = xfer->rx_len;
+			return true;
+		case MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT:
+			word_count &= 0xff;
+			DRM_DEV_ERROR(dev, "[%02X] DSI error report: 0x%02x\n",
+				      xfer->cmd, word_count);
+			xfer->status = -EPROTO;
+			return true;
+		}
+
+		if (word_count > xfer->msg->rx_len) {
+			DRM_DEV_ERROR(dev,
+				"[%02X] Receive buffer too small: %zu (< %u)\n",
+				xfer->cmd, xfer->msg->rx_len, word_count);
+			xfer->status = -EINVAL;
+			return true;
+		}
+
+		xfer->rx_word_count = word_count;
+	} else {
+		/* Set word_count from previous header read */
+		word_count = xfer->rx_word_count;
+	}
+
+	/* If RX payload is not yet received, wait for it */
+	if (!(status & NWL_DSI_RX_PKT_PAYLOAD_DATA_RCVD))
+		return false;
+
+	/* Read the RX payload */
+	while (word_count >= 4) {
+		val = nwl_dsi_read(dsi, NWL_DSI_RX_PAYLOAD);
+		payload[0] = (val >> 0) & 0xff;
+		payload[1] = (val >> 8) & 0xff;
+		payload[2] = (val >> 16) & 0xff;
+		payload[3] = (val >> 24) & 0xff;
+		payload += 4;
+		xfer->rx_len += 4;
+		word_count -= 4;
+	}
+
+	if (word_count > 0) {
+		val = nwl_dsi_read(dsi, NWL_DSI_RX_PAYLOAD);
+		switch (word_count) {
+		case 3:
+			payload[2] = (val >> 16) & 0xff;
+			++xfer->rx_len;
+			fallthrough;
+		case 2:
+			payload[1] = (val >> 8) & 0xff;
+			++xfer->rx_len;
+			fallthrough;
+		case 1:
+			payload[0] = (val >> 0) & 0xff;
+			++xfer->rx_len;
+			break;
+		}
+	}
+
+	xfer->status = xfer->rx_len;
+	err = nwl_dsi_clear_error(dsi);
+	if (err)
+		xfer->status = err;
+
+	return true;
+}
+
+static void nwl_dsi_finish_transmission(struct nwl_dsi *dsi, u32 status)
+{
+	struct nwl_dsi_transfer *xfer = dsi->xfer;
+	bool end_packet = false;
+
+	if (!xfer)
+		return;
+
+	if (xfer->direction == DSI_PACKET_SEND &&
+	    status & NWL_DSI_TX_PKT_DONE) {
+		xfer->status = xfer->tx_len;
+		end_packet = true;
+	} else if (status & NWL_DSI_DPHY_DIRECTION &&
+		   ((status & (NWL_DSI_RX_PKT_HDR_RCVD |
+			       NWL_DSI_RX_PKT_PAYLOAD_DATA_RCVD)))) {
+		end_packet = nwl_dsi_read_packet(dsi, status);
+	}
+
+	if (end_packet)
+		complete(&xfer->completed);
+}
+
+static void nwl_dsi_begin_transmission(struct nwl_dsi *dsi)
+{
+	struct nwl_dsi_transfer *xfer = dsi->xfer;
+	struct mipi_dsi_packet *pkt = &xfer->packet;
+	const u8 *payload;
+	size_t length;
+	u16 word_count;
+	u8 hs_mode;
+	u32 val;
+	u32 hs_workaround = 0;
+
+	/* Send the payload, if any */
+	length = pkt->payload_length;
+	payload = pkt->payload;
+
+	while (length >= 4) {
+		val = *(u32 *)payload;
+		hs_workaround |= !(val & 0xFFFF00);
+		nwl_dsi_write(dsi, NWL_DSI_TX_PAYLOAD, val);
+		payload += 4;
+		length -= 4;
+	}
+	/* Send the rest of the payload */
+	val = 0;
+	switch (length) {
+	case 3:
+		val |= payload[2] << 16;
+		fallthrough;
+	case 2:
+		val |= payload[1] << 8;
+		hs_workaround |= !(val & 0xFFFF00);
+		fallthrough;
+	case 1:
+		val |= payload[0];
+		nwl_dsi_write(dsi, NWL_DSI_TX_PAYLOAD, val);
+		break;
+	}
+	xfer->tx_len = pkt->payload_length;
+
+	/*
+	 * Send the header
+	 * header[0] = Virtual Channel + Data Type
+	 * header[1] = Word Count LSB (LP) or first param (SP)
+	 * header[2] = Word Count MSB (LP) or second param (SP)
+	 */
+	word_count = pkt->header[1] | (pkt->header[2] << 8);
+	if (hs_workaround && (dsi->quirks & E11418_HS_MODE_QUIRK)) {
+		DRM_DEV_DEBUG_DRIVER(dsi->dev,
+				     "Using hs mode workaround for cmd 0x%x\n",
+				     xfer->cmd);
+		hs_mode = 1;
+	} else {
+		hs_mode = (xfer->msg->flags & MIPI_DSI_MSG_USE_LPM) ? 0 : 1;
+	}
+	val = NWL_DSI_WC(word_count) | NWL_DSI_TX_VC(xfer->msg->channel) |
+	      NWL_DSI_TX_DT(xfer->msg->type) | NWL_DSI_HS_SEL(hs_mode) |
+	      NWL_DSI_BTA_TX(xfer->need_bta);
+	nwl_dsi_write(dsi, NWL_DSI_PKT_CONTROL, val);
+
+	/* Send packet command */
+	nwl_dsi_write(dsi, NWL_DSI_SEND_PACKET, 0x1);
+}
+
+static ssize_t nwl_dsi_host_transfer(struct mipi_dsi_host *dsi_host,
+				     const struct mipi_dsi_msg *msg)
+{
+	struct nwl_dsi *dsi = container_of(dsi_host, struct nwl_dsi, dsi_host);
+	struct nwl_dsi_transfer xfer;
+	ssize_t ret = 0;
+
+	/* Create packet to be sent */
+	dsi->xfer = &xfer;
+	ret = mipi_dsi_create_packet(&xfer.packet, msg);
+	if (ret < 0) {
+		dsi->xfer = NULL;
+		return ret;
+	}
+
+	if ((msg->type & MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM ||
+	     msg->type & MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM ||
+	     msg->type & MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM ||
+	     msg->type & MIPI_DSI_DCS_READ) &&
+	    msg->rx_len > 0 && msg->rx_buf)
+		xfer.direction = DSI_PACKET_RECEIVE;
+	else
+		xfer.direction = DSI_PACKET_SEND;
+
+	xfer.need_bta = (xfer.direction == DSI_PACKET_RECEIVE);
+	xfer.need_bta |= (msg->flags & MIPI_DSI_MSG_REQ_ACK) ? 1 : 0;
+	xfer.msg = msg;
+	xfer.status = -ETIMEDOUT;
+	xfer.rx_word_count = 0;
+	xfer.rx_len = 0;
+	xfer.cmd = 0x00;
+	if (msg->tx_len > 0)
+		xfer.cmd = ((u8 *)(msg->tx_buf))[0];
+	init_completion(&xfer.completed);
+
+	ret = clk_prepare_enable(dsi->rx_esc_clk);
+	if (ret < 0) {
+		DRM_DEV_ERROR(dsi->dev, "Failed to enable rx_esc clk: %zd\n",
+			      ret);
+		return ret;
+	}
+	DRM_DEV_DEBUG_DRIVER(dsi->dev, "Enabled rx_esc clk @%lu Hz\n",
+			     clk_get_rate(dsi->rx_esc_clk));
+
+	/* Initiate the DSI packet transmision */
+	nwl_dsi_begin_transmission(dsi);
+
+	if (!wait_for_completion_timeout(&xfer.completed,
+					 NWL_DSI_MIPI_FIFO_TIMEOUT)) {
+		DRM_DEV_ERROR(dsi_host->dev, "[%02X] DSI transfer timed out\n",
+			      xfer.cmd);
+		ret = -ETIMEDOUT;
+	} else {
+		ret = xfer.status;
+	}
+
+	clk_disable_unprepare(dsi->rx_esc_clk);
+
+	return ret;
+}
+
+static const struct mipi_dsi_host_ops nwl_dsi_host_ops = {
+	.attach = nwl_dsi_host_attach,
+	.transfer = nwl_dsi_host_transfer,
+};
+
+static irqreturn_t nwl_dsi_irq_handler(int irq, void *data)
+{
+	u32 irq_status;
+	struct nwl_dsi *dsi = data;
+
+	irq_status = nwl_dsi_read(dsi, NWL_DSI_IRQ_STATUS);
+
+	if (irq_status & NWL_DSI_TX_FIFO_OVFLW)
+		DRM_DEV_ERROR_RATELIMITED(dsi->dev, "tx fifo overflow\n");
+
+	if (irq_status & NWL_DSI_HS_TX_TIMEOUT)
+		DRM_DEV_ERROR_RATELIMITED(dsi->dev, "HS tx timeout\n");
+
+	if (irq_status & NWL_DSI_TX_PKT_DONE ||
+	    irq_status & NWL_DSI_RX_PKT_HDR_RCVD ||
+	    irq_status & NWL_DSI_RX_PKT_PAYLOAD_DATA_RCVD)
+		nwl_dsi_finish_transmission(dsi, irq_status);
+
+	return IRQ_HANDLED;
+}
+
+static int nwl_dsi_enable(struct nwl_dsi *dsi)
+{
+	struct device *dev = dsi->dev;
+	union phy_configure_opts *phy_cfg = &dsi->phy_cfg;
+	int ret;
+
+	if (!dsi->lanes) {
+		DRM_DEV_ERROR(dev, "Need DSI lanes: %d\n", dsi->lanes);
+		return -EINVAL;
+	}
+
+	ret = phy_init(dsi->phy);
+	if (ret < 0) {
+		DRM_DEV_ERROR(dev, "Failed to init DSI phy: %d\n", ret);
+		return ret;
+	}
+
+	ret = phy_configure(dsi->phy, phy_cfg);
+	if (ret < 0) {
+		DRM_DEV_ERROR(dev, "Failed to configure DSI phy: %d\n", ret);
+		goto uninit_phy;
+	}
+
+	ret = clk_prepare_enable(dsi->tx_esc_clk);
+	if (ret < 0) {
+		DRM_DEV_ERROR(dsi->dev, "Failed to enable tx_esc clk: %d\n",
+			      ret);
+		goto uninit_phy;
+	}
+	DRM_DEV_DEBUG_DRIVER(dsi->dev, "Enabled tx_esc clk @%lu Hz\n",
+			     clk_get_rate(dsi->tx_esc_clk));
+
+	ret = nwl_dsi_config_host(dsi);
+	if (ret < 0) {
+		DRM_DEV_ERROR(dev, "Failed to set up DSI: %d", ret);
+		goto disable_clock;
+	}
+
+	ret = nwl_dsi_config_dpi(dsi);
+	if (ret < 0) {
+		DRM_DEV_ERROR(dev, "Failed to set up DPI: %d", ret);
+		goto disable_clock;
+	}
+
+	ret = phy_power_on(dsi->phy);
+	if (ret < 0) {
+		DRM_DEV_ERROR(dev, "Failed to power on DPHY (%d)\n", ret);
+		goto disable_clock;
+	}
+
+	ret = nwl_dsi_init_interrupts(dsi);
+	if (ret < 0)
+		goto power_off_phy;
+
+	return ret;
+
+power_off_phy:
+	phy_power_off(dsi->phy);
+disable_clock:
+	clk_disable_unprepare(dsi->tx_esc_clk);
+uninit_phy:
+	phy_exit(dsi->phy);
+
+	return ret;
+}
+
+static int nwl_dsi_disable(struct nwl_dsi *dsi)
+{
+	struct device *dev = dsi->dev;
+
+	DRM_DEV_DEBUG_DRIVER(dev, "Disabling clocks and phy\n");
+
+	phy_power_off(dsi->phy);
+	phy_exit(dsi->phy);
+
+	/* Disabling the clock before the phy breaks enabling dsi again */
+	clk_disable_unprepare(dsi->tx_esc_clk);
+
+	return 0;
+}
+
+static void nwl_dsi_bridge_disable(struct drm_bridge *bridge)
+{
+	struct nwl_dsi *dsi = bridge_to_dsi(bridge);
+	int ret;
+
+	nwl_dsi_disable(dsi);
+
+	ret = reset_control_assert(dsi->rst_dpi);
+	if (ret < 0) {
+		DRM_DEV_ERROR(dsi->dev, "Failed to assert DPI: %d\n", ret);
+		return;
+	}
+	ret = reset_control_assert(dsi->rst_byte);
+	if (ret < 0) {
+		DRM_DEV_ERROR(dsi->dev, "Failed to assert ESC: %d\n", ret);
+		return;
+	}
+	ret = reset_control_assert(dsi->rst_esc);
+	if (ret < 0) {
+		DRM_DEV_ERROR(dsi->dev, "Failed to assert BYTE: %d\n", ret);
+		return;
+	}
+	ret = reset_control_assert(dsi->rst_pclk);
+	if (ret < 0) {
+		DRM_DEV_ERROR(dsi->dev, "Failed to assert PCLK: %d\n", ret);
+		return;
+	}
+
+	clk_disable_unprepare(dsi->core_clk);
+	clk_disable_unprepare(dsi->lcdif_clk);
+
+	pm_runtime_put(dsi->dev);
+}
+
+static int nwl_dsi_get_dphy_params(struct nwl_dsi *dsi,
+				   const struct drm_display_mode *mode,
+				   union phy_configure_opts *phy_opts)
+{
+	unsigned long rate;
+	int ret;
+
+	if (dsi->lanes < 1 || dsi->lanes > 4)
+		return -EINVAL;
+
+	/*
+	 * So far the DPHY spec minimal timings work for both mixel
+	 * dphy and nwl dsi host
+	 */
+	ret = phy_mipi_dphy_get_default_config(mode->clock * 1000,
+		mipi_dsi_pixel_format_to_bpp(dsi->format), dsi->lanes,
+		&phy_opts->mipi_dphy);
+	if (ret < 0)
+		return ret;
+
+	rate = clk_get_rate(dsi->tx_esc_clk);
+	DRM_DEV_DEBUG_DRIVER(dsi->dev, "LP clk is @%lu Hz\n", rate);
+	phy_opts->mipi_dphy.lp_clk_rate = rate;
+
+	return 0;
+}
+
+static bool nwl_dsi_bridge_mode_fixup(struct drm_bridge *bridge,
+				      const struct drm_display_mode *mode,
+				      struct drm_display_mode *adjusted_mode)
+{
+	/* At least LCDIF + NWL needs active high sync */
+	adjusted_mode->flags |= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
+	adjusted_mode->flags &= ~(DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC);
+
+	return true;
+}
+
+static enum drm_mode_status
+nwl_dsi_bridge_mode_valid(struct drm_bridge *bridge,
+			  const struct drm_display_mode *mode)
+{
+	struct nwl_dsi *dsi = bridge_to_dsi(bridge);
+	int bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
+
+	if (mode->clock * bpp > 15000000 * dsi->lanes)
+		return MODE_CLOCK_HIGH;
+
+	if (mode->clock * bpp < 80000 * dsi->lanes)
+		return MODE_CLOCK_LOW;
+
+	return MODE_OK;
+}
+
+static void
+nwl_dsi_bridge_mode_set(struct drm_bridge *bridge,
+			const struct drm_display_mode *mode,
+			const struct drm_display_mode *adjusted_mode)
+{
+	struct nwl_dsi *dsi = bridge_to_dsi(bridge);
+	struct device *dev = dsi->dev;
+	union phy_configure_opts new_cfg;
+	unsigned long phy_ref_rate;
+	int ret;
+
+	ret = nwl_dsi_get_dphy_params(dsi, adjusted_mode, &new_cfg);
+	if (ret < 0)
+		return;
+
+	/*
+	 * If hs clock is unchanged, we're all good - all parameters are
+	 * derived from it atm.
+	 */
+	if (new_cfg.mipi_dphy.hs_clk_rate == dsi->phy_cfg.mipi_dphy.hs_clk_rate)
+		return;
+
+	phy_ref_rate = clk_get_rate(dsi->phy_ref_clk);
+	DRM_DEV_DEBUG_DRIVER(dev, "PHY at ref rate: %lu\n", phy_ref_rate);
+	/* Save the new desired phy config */
+	memcpy(&dsi->phy_cfg, &new_cfg, sizeof(new_cfg));
+
+	memcpy(&dsi->mode, adjusted_mode, sizeof(dsi->mode));
+	drm_mode_debug_printmodeline(adjusted_mode);
+}
+
+static void nwl_dsi_bridge_pre_enable(struct drm_bridge *bridge)
+{
+	struct nwl_dsi *dsi = bridge_to_dsi(bridge);
+	int ret;
+
+	pm_runtime_get_sync(dsi->dev);
+
+	if (clk_prepare_enable(dsi->lcdif_clk) < 0)
+		return;
+	if (clk_prepare_enable(dsi->core_clk) < 0)
+		return;
+
+	/* Step 1 from DSI reset-out instructions */
+	ret = reset_control_deassert(dsi->rst_pclk);
+	if (ret < 0) {
+		DRM_DEV_ERROR(dsi->dev, "Failed to deassert PCLK: %d\n", ret);
+		return;
+	}
+
+	/* Step 2 from DSI reset-out instructions */
+	nwl_dsi_enable(dsi);
+
+	/* Step 3 from DSI reset-out instructions */
+	ret = reset_control_deassert(dsi->rst_esc);
+	if (ret < 0) {
+		DRM_DEV_ERROR(dsi->dev, "Failed to deassert ESC: %d\n", ret);
+		return;
+	}
+	ret = reset_control_deassert(dsi->rst_byte);
+	if (ret < 0) {
+		DRM_DEV_ERROR(dsi->dev, "Failed to deassert BYTE: %d\n", ret);
+		return;
+	}
+}
+
+static void nwl_dsi_bridge_enable(struct drm_bridge *bridge)
+{
+	struct nwl_dsi *dsi = bridge_to_dsi(bridge);
+	int ret;
+
+	/* Step 5 from DSI reset-out instructions */
+	ret = reset_control_deassert(dsi->rst_dpi);
+	if (ret < 0)
+		DRM_DEV_ERROR(dsi->dev, "Failed to deassert DPI: %d\n", ret);
+}
+
+static int nwl_dsi_bridge_attach(struct drm_bridge *bridge,
+				 enum drm_bridge_attach_flags flags)
+{
+	struct nwl_dsi *dsi = bridge_to_dsi(bridge);
+	struct drm_bridge *panel_bridge;
+	struct drm_panel *panel;
+	int ret;
+
+	if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
+		DRM_ERROR("Fix bridge driver to make connector optional!");
+		return -EINVAL;
+	}
+
+	ret = drm_of_find_panel_or_bridge(dsi->dev->of_node, 1, 0, &panel,
+					  &panel_bridge);
+	if (ret)
+		return ret;
+
+	if (panel) {
+		panel_bridge = drm_panel_bridge_add(panel);
+		if (IS_ERR(panel_bridge))
+			return PTR_ERR(panel_bridge);
+	}
+	dsi->panel_bridge = panel_bridge;
+
+	if (!dsi->panel_bridge)
+		return -EPROBE_DEFER;
+
+	return drm_bridge_attach(bridge->encoder, dsi->panel_bridge, bridge,
+				 flags);
+}
+
+static void nwl_dsi_bridge_detach(struct drm_bridge *bridge)
+{	struct nwl_dsi *dsi = bridge_to_dsi(bridge);
+
+	drm_of_panel_bridge_remove(dsi->dev->of_node, 1, 0);
+}
+
+static const struct drm_bridge_funcs nwl_dsi_bridge_funcs = {
+	.pre_enable = nwl_dsi_bridge_pre_enable,
+	.enable     = nwl_dsi_bridge_enable,
+	.disable    = nwl_dsi_bridge_disable,
+	.mode_fixup = nwl_dsi_bridge_mode_fixup,
+	.mode_set   = nwl_dsi_bridge_mode_set,
+	.mode_valid = nwl_dsi_bridge_mode_valid,
+	.attach	    = nwl_dsi_bridge_attach,
+	.detach	    = nwl_dsi_bridge_detach,
+};
+
+static int nwl_dsi_parse_dt(struct nwl_dsi *dsi)
+{
+	struct platform_device *pdev = to_platform_device(dsi->dev);
+	struct clk *clk;
+	void __iomem *base;
+	int ret;
+
+	dsi->phy = devm_phy_get(dsi->dev, "dphy");
+	if (IS_ERR(dsi->phy)) {
+		ret = PTR_ERR(dsi->phy);
+		if (ret != -EPROBE_DEFER)
+			DRM_DEV_ERROR(dsi->dev, "Could not get PHY: %d\n", ret);
+		return ret;
+	}
+
+	clk = devm_clk_get(dsi->dev, "lcdif");
+	if (IS_ERR(clk)) {
+		ret = PTR_ERR(clk);
+		DRM_DEV_ERROR(dsi->dev, "Failed to get lcdif clock: %d\n",
+			      ret);
+		return ret;
+	}
+	dsi->lcdif_clk = clk;
+
+	clk = devm_clk_get(dsi->dev, "core");
+	if (IS_ERR(clk)) {
+		ret = PTR_ERR(clk);
+		DRM_DEV_ERROR(dsi->dev, "Failed to get core clock: %d\n",
+			      ret);
+		return ret;
+	}
+	dsi->core_clk = clk;
+
+	clk = devm_clk_get(dsi->dev, "phy_ref");
+	if (IS_ERR(clk)) {
+		ret = PTR_ERR(clk);
+		DRM_DEV_ERROR(dsi->dev, "Failed to get phy_ref clock: %d\n",
+			      ret);
+		return ret;
+	}
+	dsi->phy_ref_clk = clk;
+
+	clk = devm_clk_get(dsi->dev, "rx_esc");
+	if (IS_ERR(clk)) {
+		ret = PTR_ERR(clk);
+		DRM_DEV_ERROR(dsi->dev, "Failed to get rx_esc clock: %d\n",
+			      ret);
+		return ret;
+	}
+	dsi->rx_esc_clk = clk;
+
+	clk = devm_clk_get(dsi->dev, "tx_esc");
+	if (IS_ERR(clk)) {
+		ret = PTR_ERR(clk);
+		DRM_DEV_ERROR(dsi->dev, "Failed to get tx_esc clock: %d\n",
+			      ret);
+		return ret;
+	}
+	dsi->tx_esc_clk = clk;
+
+	dsi->mux = devm_mux_control_get(dsi->dev, NULL);
+	if (IS_ERR(dsi->mux)) {
+		ret = PTR_ERR(dsi->mux);
+		if (ret != -EPROBE_DEFER)
+			DRM_DEV_ERROR(dsi->dev, "Failed to get mux: %d\n", ret);
+		return ret;
+	}
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	dsi->regmap =
+		devm_regmap_init_mmio(dsi->dev, base, &nwl_dsi_regmap_config);
+	if (IS_ERR(dsi->regmap)) {
+		ret = PTR_ERR(dsi->regmap);
+		DRM_DEV_ERROR(dsi->dev, "Failed to create NWL DSI regmap: %d\n",
+			      ret);
+		return ret;
+	}
+
+	dsi->irq = platform_get_irq(pdev, 0);
+	if (dsi->irq < 0) {
+		DRM_DEV_ERROR(dsi->dev, "Failed to get device IRQ: %d\n",
+			      dsi->irq);
+		return dsi->irq;
+	}
+
+	dsi->rst_pclk = devm_reset_control_get_exclusive(dsi->dev, "pclk");
+	if (IS_ERR(dsi->rst_pclk)) {
+		DRM_DEV_ERROR(dsi->dev, "Failed to get pclk reset: %ld\n",
+			      PTR_ERR(dsi->rst_pclk));
+		return PTR_ERR(dsi->rst_pclk);
+	}
+	dsi->rst_byte = devm_reset_control_get_exclusive(dsi->dev, "byte");
+	if (IS_ERR(dsi->rst_byte)) {
+		DRM_DEV_ERROR(dsi->dev, "Failed to get byte reset: %ld\n",
+			      PTR_ERR(dsi->rst_byte));
+		return PTR_ERR(dsi->rst_byte);
+	}
+	dsi->rst_esc = devm_reset_control_get_exclusive(dsi->dev, "esc");
+	if (IS_ERR(dsi->rst_esc)) {
+		DRM_DEV_ERROR(dsi->dev, "Failed to get esc reset: %ld\n",
+			      PTR_ERR(dsi->rst_esc));
+		return PTR_ERR(dsi->rst_esc);
+	}
+	dsi->rst_dpi = devm_reset_control_get_exclusive(dsi->dev, "dpi");
+	if (IS_ERR(dsi->rst_dpi)) {
+		DRM_DEV_ERROR(dsi->dev, "Failed to get dpi reset: %ld\n",
+			      PTR_ERR(dsi->rst_dpi));
+		return PTR_ERR(dsi->rst_dpi);
+	}
+	return 0;
+}
+
+static int nwl_dsi_select_input(struct nwl_dsi *dsi)
+{
+	struct device_node *remote;
+	u32 use_dcss = 1;
+	int ret;
+
+	remote = of_graph_get_remote_node(dsi->dev->of_node, 0,
+					  NWL_DSI_ENDPOINT_LCDIF);
+	if (remote) {
+		use_dcss = 0;
+	} else {
+		remote = of_graph_get_remote_node(dsi->dev->of_node, 0,
+						  NWL_DSI_ENDPOINT_DCSS);
+		if (!remote) {
+			DRM_DEV_ERROR(dsi->dev,
+				      "No valid input endpoint found\n");
+			return -EINVAL;
+		}
+	}
+
+	DRM_DEV_INFO(dsi->dev, "Using %s as input source\n",
+		     (use_dcss) ? "DCSS" : "LCDIF");
+	ret = mux_control_try_select(dsi->mux, use_dcss);
+	if (ret < 0)
+		DRM_DEV_ERROR(dsi->dev, "Failed to select input: %d\n", ret);
+
+	of_node_put(remote);
+	return ret;
+}
+
+static int nwl_dsi_deselect_input(struct nwl_dsi *dsi)
+{
+	int ret;
+
+	ret = mux_control_deselect(dsi->mux);
+	if (ret < 0)
+		DRM_DEV_ERROR(dsi->dev, "Failed to deselect input: %d\n", ret);
+
+	return ret;
+}
+
+static const struct drm_bridge_timings nwl_dsi_timings = {
+	.input_bus_flags = DRM_BUS_FLAG_DE_LOW,
+};
+
+static const struct of_device_id nwl_dsi_dt_ids[] = {
+	{ .compatible = "fsl,imx8mq-nwl-dsi", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, nwl_dsi_dt_ids);
+
+static const struct soc_device_attribute nwl_dsi_quirks_match[] = {
+	{ .soc_id = "i.MX8MQ", .revision = "2.0",
+	  .data = (void *)E11418_HS_MODE_QUIRK },
+	{ /* sentinel. */ },
+};
+
+static int nwl_dsi_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	const struct soc_device_attribute *attr;
+	struct nwl_dsi *dsi;
+	int ret;
+
+	dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);
+	if (!dsi)
+		return -ENOMEM;
+
+	dsi->dev = dev;
+
+	ret = nwl_dsi_parse_dt(dsi);
+	if (ret)
+		return ret;
+
+	ret = devm_request_irq(dev, dsi->irq, nwl_dsi_irq_handler, 0,
+			       dev_name(dev), dsi);
+	if (ret < 0) {
+		DRM_DEV_ERROR(dev, "Failed to request IRQ %d: %d\n", dsi->irq,
+			      ret);
+		return ret;
+	}
+
+	dsi->dsi_host.ops = &nwl_dsi_host_ops;
+	dsi->dsi_host.dev = dev;
+	ret = mipi_dsi_host_register(&dsi->dsi_host);
+	if (ret) {
+		DRM_DEV_ERROR(dev, "Failed to register MIPI host: %d\n", ret);
+		return ret;
+	}
+
+	attr = soc_device_match(nwl_dsi_quirks_match);
+	if (attr)
+		dsi->quirks = (uintptr_t)attr->data;
+
+	dsi->bridge.driver_private = dsi;
+	dsi->bridge.funcs = &nwl_dsi_bridge_funcs;
+	dsi->bridge.of_node = dev->of_node;
+	dsi->bridge.timings = &nwl_dsi_timings;
+
+	dev_set_drvdata(dev, dsi);
+	pm_runtime_enable(dev);
+
+	ret = nwl_dsi_select_input(dsi);
+	if (ret < 0) {
+		mipi_dsi_host_unregister(&dsi->dsi_host);
+		return ret;
+	}
+
+	drm_bridge_add(&dsi->bridge);
+	return 0;
+}
+
+static int nwl_dsi_remove(struct platform_device *pdev)
+{
+	struct nwl_dsi *dsi = platform_get_drvdata(pdev);
+
+	nwl_dsi_deselect_input(dsi);
+	mipi_dsi_host_unregister(&dsi->dsi_host);
+	drm_bridge_remove(&dsi->bridge);
+	pm_runtime_disable(&pdev->dev);
+	return 0;
+}
+
+static struct platform_driver nwl_dsi_driver = {
+	.probe		= nwl_dsi_probe,
+	.remove		= nwl_dsi_remove,
+	.driver		= {
+		.of_match_table = nwl_dsi_dt_ids,
+		.name	= DRV_NAME,
+	},
+};
+
+module_platform_driver(nwl_dsi_driver);
+
+MODULE_AUTHOR("NXP Semiconductor");
+MODULE_AUTHOR("Purism SPC");
+MODULE_DESCRIPTION("Northwest Logic MIPI-DSI driver");
+MODULE_LICENSE("GPL"); /* GPLv2 or later */
diff --git a/drivers/gpu/drm/bridge/nwl-dsi.h b/drivers/gpu/drm/bridge/nwl-dsi.h
new file mode 100644
index 000000000000..a247a8a11c7c
--- /dev/null
+++ b/drivers/gpu/drm/bridge/nwl-dsi.h
@@ -0,0 +1,144 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * NWL MIPI DSI host driver
+ *
+ * Copyright (C) 2017 NXP
+ * Copyright (C) 2019 Purism SPC
+ */
+#ifndef __NWL_DSI_H__
+#define __NWL_DSI_H__
+
+/* DSI HOST registers */
+#define NWL_DSI_CFG_NUM_LANES			0x0
+#define NWL_DSI_CFG_NONCONTINUOUS_CLK		0x4
+#define NWL_DSI_CFG_T_PRE			0x8
+#define NWL_DSI_CFG_T_POST			0xc
+#define NWL_DSI_CFG_TX_GAP			0x10
+#define NWL_DSI_CFG_AUTOINSERT_EOTP		0x14
+#define NWL_DSI_CFG_EXTRA_CMDS_AFTER_EOTP	0x18
+#define NWL_DSI_CFG_HTX_TO_COUNT		0x1c
+#define NWL_DSI_CFG_LRX_H_TO_COUNT		0x20
+#define NWL_DSI_CFG_BTA_H_TO_COUNT		0x24
+#define NWL_DSI_CFG_TWAKEUP			0x28
+#define NWL_DSI_CFG_STATUS_OUT			0x2c
+#define NWL_DSI_RX_ERROR_STATUS			0x30
+
+/* DSI DPI registers */
+#define NWL_DSI_PIXEL_PAYLOAD_SIZE		0x200
+#define NWL_DSI_PIXEL_FIFO_SEND_LEVEL		0x204
+#define NWL_DSI_INTERFACE_COLOR_CODING		0x208
+#define NWL_DSI_PIXEL_FORMAT			0x20c
+#define NWL_DSI_VSYNC_POLARITY			0x210
+#define NWL_DSI_VSYNC_POLARITY_ACTIVE_LOW	0
+#define NWL_DSI_VSYNC_POLARITY_ACTIVE_HIGH	BIT(1)
+
+#define NWL_DSI_HSYNC_POLARITY			0x214
+#define NWL_DSI_HSYNC_POLARITY_ACTIVE_LOW	0
+#define NWL_DSI_HSYNC_POLARITY_ACTIVE_HIGH	BIT(1)
+
+#define NWL_DSI_VIDEO_MODE			0x218
+#define NWL_DSI_HFP				0x21c
+#define NWL_DSI_HBP				0x220
+#define NWL_DSI_HSA				0x224
+#define NWL_DSI_ENABLE_MULT_PKTS		0x228
+#define NWL_DSI_VBP				0x22c
+#define NWL_DSI_VFP				0x230
+#define NWL_DSI_BLLP_MODE			0x234
+#define NWL_DSI_USE_NULL_PKT_BLLP		0x238
+#define NWL_DSI_VACTIVE				0x23c
+#define NWL_DSI_VC				0x240
+
+/* DSI APB PKT control */
+#define NWL_DSI_TX_PAYLOAD			0x280
+#define NWL_DSI_PKT_CONTROL			0x284
+#define NWL_DSI_SEND_PACKET			0x288
+#define NWL_DSI_PKT_STATUS			0x28c
+#define NWL_DSI_PKT_FIFO_WR_LEVEL		0x290
+#define NWL_DSI_PKT_FIFO_RD_LEVEL		0x294
+#define NWL_DSI_RX_PAYLOAD			0x298
+#define NWL_DSI_RX_PKT_HEADER			0x29c
+
+/* DSI IRQ handling */
+#define NWL_DSI_IRQ_STATUS			0x2a0
+#define NWL_DSI_SM_NOT_IDLE			BIT(0)
+#define NWL_DSI_TX_PKT_DONE			BIT(1)
+#define NWL_DSI_DPHY_DIRECTION			BIT(2)
+#define NWL_DSI_TX_FIFO_OVFLW			BIT(3)
+#define NWL_DSI_TX_FIFO_UDFLW			BIT(4)
+#define NWL_DSI_RX_FIFO_OVFLW			BIT(5)
+#define NWL_DSI_RX_FIFO_UDFLW			BIT(6)
+#define NWL_DSI_RX_PKT_HDR_RCVD			BIT(7)
+#define NWL_DSI_RX_PKT_PAYLOAD_DATA_RCVD	BIT(8)
+#define NWL_DSI_BTA_TIMEOUT			BIT(29)
+#define NWL_DSI_LP_RX_TIMEOUT			BIT(30)
+#define NWL_DSI_HS_TX_TIMEOUT			BIT(31)
+
+#define NWL_DSI_IRQ_STATUS2			0x2a4
+#define NWL_DSI_SINGLE_BIT_ECC_ERR		BIT(0)
+#define NWL_DSI_MULTI_BIT_ECC_ERR		BIT(1)
+#define NWL_DSI_CRC_ERR				BIT(2)
+
+#define NWL_DSI_IRQ_MASK			0x2a8
+#define NWL_DSI_SM_NOT_IDLE_MASK		BIT(0)
+#define NWL_DSI_TX_PKT_DONE_MASK		BIT(1)
+#define NWL_DSI_DPHY_DIRECTION_MASK		BIT(2)
+#define NWL_DSI_TX_FIFO_OVFLW_MASK		BIT(3)
+#define NWL_DSI_TX_FIFO_UDFLW_MASK		BIT(4)
+#define NWL_DSI_RX_FIFO_OVFLW_MASK		BIT(5)
+#define NWL_DSI_RX_FIFO_UDFLW_MASK		BIT(6)
+#define NWL_DSI_RX_PKT_HDR_RCVD_MASK		BIT(7)
+#define NWL_DSI_RX_PKT_PAYLOAD_DATA_RCVD_MASK	BIT(8)
+#define NWL_DSI_BTA_TIMEOUT_MASK		BIT(29)
+#define NWL_DSI_LP_RX_TIMEOUT_MASK		BIT(30)
+#define NWL_DSI_HS_TX_TIMEOUT_MASK		BIT(31)
+
+#define NWL_DSI_IRQ_MASK2			0x2ac
+#define NWL_DSI_SINGLE_BIT_ECC_ERR_MASK		BIT(0)
+#define NWL_DSI_MULTI_BIT_ECC_ERR_MASK		BIT(1)
+#define NWL_DSI_CRC_ERR_MASK			BIT(2)
+
+/*
+ * PKT_CONTROL format:
+ * [15: 0] - word count
+ * [17:16] - virtual channel
+ * [23:18] - data type
+ * [24]	   - LP or HS select (0 - LP, 1 - HS)
+ * [25]	   - perform BTA after packet is sent
+ * [26]	   - perform BTA only, no packet tx
+ */
+#define NWL_DSI_WC(x)		FIELD_PREP(GENMASK(15, 0), (x))
+#define NWL_DSI_TX_VC(x)	FIELD_PREP(GENMASK(17, 16), (x))
+#define NWL_DSI_TX_DT(x)	FIELD_PREP(GENMASK(23, 18), (x))
+#define NWL_DSI_HS_SEL(x)	FIELD_PREP(GENMASK(24, 24), (x))
+#define NWL_DSI_BTA_TX(x)	FIELD_PREP(GENMASK(25, 25), (x))
+#define NWL_DSI_BTA_NO_TX(x)	FIELD_PREP(GENMASK(26, 26), (x))
+
+/*
+ * RX_PKT_HEADER format:
+ * [15: 0] - word count
+ * [21:16] - data type
+ * [23:22] - virtual channel
+ */
+#define NWL_DSI_RX_DT(x)	FIELD_GET(GENMASK(21, 16), (x))
+#define NWL_DSI_RX_VC(x)	FIELD_GET(GENMASK(23, 22), (x))
+
+/* DSI Video mode */
+#define NWL_DSI_VM_BURST_MODE_WITH_SYNC_PULSES		0
+#define NWL_DSI_VM_NON_BURST_MODE_WITH_SYNC_EVENTS	BIT(0)
+#define NWL_DSI_VM_BURST_MODE				BIT(1)
+
+/* * DPI color coding */
+#define NWL_DSI_DPI_16_BIT_565_PACKED	0
+#define NWL_DSI_DPI_16_BIT_565_ALIGNED	1
+#define NWL_DSI_DPI_16_BIT_565_SHIFTED	2
+#define NWL_DSI_DPI_18_BIT_PACKED	3
+#define NWL_DSI_DPI_18_BIT_ALIGNED	4
+#define NWL_DSI_DPI_24_BIT		5
+
+/* * DPI Pixel format */
+#define NWL_DSI_PIXEL_FORMAT_16  0
+#define NWL_DSI_PIXEL_FORMAT_18  BIT(0)
+#define NWL_DSI_PIXEL_FORMAT_18L BIT(1)
+#define NWL_DSI_PIXEL_FORMAT_24  (BIT(0) | BIT(1))
+
+#endif /* __NWL_DSI_H__ */
diff --git a/drivers/gpu/drm/bridge/panel.c b/drivers/gpu/drm/bridge/panel.c
index 8461ee8304ba..e933f1c47f5d 100644
--- a/drivers/gpu/drm/bridge/panel.c
+++ b/drivers/gpu/drm/bridge/panel.c
@@ -311,6 +311,7 @@ EXPORT_SYMBOL(devm_drm_panel_bridge_add_typed);
 
 /**
  * drm_panel_bridge_connector - return the connector for the panel bridge
+ * @bridge: The drm_bridge.
  *
  * drm_panel_bridge creates the connector.
  * This function gives external access to the connector.
diff --git a/drivers/gpu/drm/bridge/sii9234.c b/drivers/gpu/drm/bridge/sii9234.c
index f81f81b7051f..b1258f0ed205 100644
--- a/drivers/gpu/drm/bridge/sii9234.c
+++ b/drivers/gpu/drm/bridge/sii9234.c
@@ -836,7 +836,8 @@ static int sii9234_init_resources(struct sii9234 *ctx,
 	ctx->supplies[3].supply = "cvcc12";
 	ret = devm_regulator_bulk_get(ctx->dev, 4, ctx->supplies);
 	if (ret) {
-		dev_err(ctx->dev, "regulator_bulk failed\n");
+		if (ret != -EPROBE_DEFER)
+			dev_err(ctx->dev, "regulator_bulk failed\n");
 		return ret;
 	}
 
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 383b1073d7de..30681398cfb0 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -92,6 +92,12 @@ static const u16 csc_coeff_rgb_in_eitu709[3][4] = {
 	{ 0x6756, 0x78ab, 0x2000, 0x0200 }
 };
 
+static const u16 csc_coeff_rgb_full_to_rgb_limited[3][4] = {
+	{ 0x1b7c, 0x0000, 0x0000, 0x0020 },
+	{ 0x0000, 0x1b7c, 0x0000, 0x0020 },
+	{ 0x0000, 0x0000, 0x1b7c, 0x0020 }
+};
+
 struct hdmi_vmode {
 	bool mdataenablepolarity;
 
@@ -109,6 +115,7 @@ struct hdmi_data_info {
 	unsigned int pix_repet_factor;
 	unsigned int hdcp_enable;
 	struct hdmi_vmode video_mode;
+	bool rgb_limited_range;
 };
 
 struct dw_hdmi_i2c {
@@ -956,7 +963,14 @@ static void hdmi_video_sample(struct dw_hdmi *hdmi)
 
 static int is_color_space_conversion(struct dw_hdmi *hdmi)
 {
-	return hdmi->hdmi_data.enc_in_bus_format != hdmi->hdmi_data.enc_out_bus_format;
+	struct hdmi_data_info *hdmi_data = &hdmi->hdmi_data;
+	bool is_input_rgb, is_output_rgb;
+
+	is_input_rgb = hdmi_bus_fmt_is_rgb(hdmi_data->enc_in_bus_format);
+	is_output_rgb = hdmi_bus_fmt_is_rgb(hdmi_data->enc_out_bus_format);
+
+	return (is_input_rgb != is_output_rgb) ||
+	       (is_input_rgb && is_output_rgb && hdmi_data->rgb_limited_range);
 }
 
 static int is_color_space_decimation(struct dw_hdmi *hdmi)
@@ -983,28 +997,37 @@ static int is_color_space_interpolation(struct dw_hdmi *hdmi)
 	return 0;
 }
 
+static bool is_csc_needed(struct dw_hdmi *hdmi)
+{
+	return is_color_space_conversion(hdmi) ||
+	       is_color_space_decimation(hdmi) ||
+	       is_color_space_interpolation(hdmi);
+}
+
 static void dw_hdmi_update_csc_coeffs(struct dw_hdmi *hdmi)
 {
 	const u16 (*csc_coeff)[3][4] = &csc_coeff_default;
+	bool is_input_rgb, is_output_rgb;
 	unsigned i;
 	u32 csc_scale = 1;
 
-	if (is_color_space_conversion(hdmi)) {
-		if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) {
-			if (hdmi->hdmi_data.enc_out_encoding ==
-						V4L2_YCBCR_ENC_601)
-				csc_coeff = &csc_coeff_rgb_out_eitu601;
-			else
-				csc_coeff = &csc_coeff_rgb_out_eitu709;
-		} else if (hdmi_bus_fmt_is_rgb(
-					hdmi->hdmi_data.enc_in_bus_format)) {
-			if (hdmi->hdmi_data.enc_out_encoding ==
-						V4L2_YCBCR_ENC_601)
-				csc_coeff = &csc_coeff_rgb_in_eitu601;
-			else
-				csc_coeff = &csc_coeff_rgb_in_eitu709;
-			csc_scale = 0;
-		}
+	is_input_rgb = hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_in_bus_format);
+	is_output_rgb = hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format);
+
+	if (!is_input_rgb && is_output_rgb) {
+		if (hdmi->hdmi_data.enc_out_encoding == V4L2_YCBCR_ENC_601)
+			csc_coeff = &csc_coeff_rgb_out_eitu601;
+		else
+			csc_coeff = &csc_coeff_rgb_out_eitu709;
+	} else if (is_input_rgb && !is_output_rgb) {
+		if (hdmi->hdmi_data.enc_out_encoding == V4L2_YCBCR_ENC_601)
+			csc_coeff = &csc_coeff_rgb_in_eitu601;
+		else
+			csc_coeff = &csc_coeff_rgb_in_eitu709;
+		csc_scale = 0;
+	} else if (is_input_rgb && is_output_rgb &&
+		   hdmi->hdmi_data.rgb_limited_range) {
+		csc_coeff = &csc_coeff_rgb_full_to_rgb_limited;
 	}
 
 	/* The CSC registers are sequential, alternating MSB then LSB */
@@ -1614,6 +1637,18 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
 	drm_hdmi_avi_infoframe_from_display_mode(&frame,
 						 &hdmi->connector, mode);
 
+	if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) {
+		drm_hdmi_avi_infoframe_quant_range(&frame, &hdmi->connector,
+						   mode,
+						   hdmi->hdmi_data.rgb_limited_range ?
+						   HDMI_QUANTIZATION_RANGE_LIMITED :
+						   HDMI_QUANTIZATION_RANGE_FULL);
+	} else {
+		frame.quantization_range = HDMI_QUANTIZATION_RANGE_DEFAULT;
+		frame.ycc_quantization_range =
+			HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
+	}
+
 	if (hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_out_bus_format))
 		frame.colorspace = HDMI_COLORSPACE_YUV444;
 	else if (hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format))
@@ -1654,8 +1689,6 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
 			HDMI_EXTENDED_COLORIMETRY_XV_YCC_601;
 	}
 
-	frame.scan_mode = HDMI_SCAN_MODE_NONE;
-
 	/*
 	 * The Designware IP uses a different byte format from standard
 	 * AVI info frames, though generally the bits are in the correct
@@ -2010,18 +2043,19 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
 	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
 
 	/* Enable csc path */
-	if (is_color_space_conversion(hdmi)) {
+	if (is_csc_needed(hdmi)) {
 		hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
 		hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
-	}
 
-	/* Enable color space conversion if needed */
-	if (is_color_space_conversion(hdmi))
 		hdmi_writeb(hdmi, HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH,
 			    HDMI_MC_FLOWCTRL);
-	else
+	} else {
+		hdmi->mc_clkdis |= HDMI_MC_CLKDIS_CSCCLK_DISABLE;
+		hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
+
 		hdmi_writeb(hdmi, HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS,
 			    HDMI_MC_FLOWCTRL);
+	}
 }
 
 /* Workaround to clear the overflow condition */
@@ -2119,6 +2153,10 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
 	if (hdmi->hdmi_data.enc_out_bus_format == MEDIA_BUS_FMT_FIXED)
 		hdmi->hdmi_data.enc_out_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
 
+	hdmi->hdmi_data.rgb_limited_range = hdmi->sink_is_hdmi &&
+		drm_default_rgb_quant_range(mode) ==
+		HDMI_QUANTIZATION_RANGE_LIMITED;
+
 	hdmi->hdmi_data.pix_repet_factor = 0;
 	hdmi->hdmi_data.hdcp_enable = 0;
 	hdmi->hdmi_data.video_mode.mdataenablepolarity = true;
diff --git a/drivers/gpu/drm/cirrus/cirrus.c b/drivers/gpu/drm/cirrus/cirrus.c
index d2ff63ce8eaf..a36269717c3b 100644
--- a/drivers/gpu/drm/cirrus/cirrus.c
+++ b/drivers/gpu/drm/cirrus/cirrus.c
@@ -35,6 +35,7 @@
 #include <drm/drm_gem_shmem_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
 #include <drm/drm_ioctl.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_modeset_helper_vtables.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/drm_simple_kms_helper.h>
@@ -509,11 +510,15 @@ static const struct drm_mode_config_funcs cirrus_mode_config_funcs = {
 	.atomic_commit = drm_atomic_helper_commit,
 };
 
-static void cirrus_mode_config_init(struct cirrus_device *cirrus)
+static int cirrus_mode_config_init(struct cirrus_device *cirrus)
 {
 	struct drm_device *dev = &cirrus->dev;
+	int ret;
+
+	ret = drmm_mode_config_init(dev);
+	if (ret)
+		return ret;
 
-	drm_mode_config_init(dev);
 	dev->mode_config.min_width = 0;
 	dev->mode_config.min_height = 0;
 	dev->mode_config.max_width = CIRRUS_MAX_PITCH / 2;
@@ -521,18 +526,12 @@ static void cirrus_mode_config_init(struct cirrus_device *cirrus)
 	dev->mode_config.preferred_depth = 16;
 	dev->mode_config.prefer_shadow = 0;
 	dev->mode_config.funcs = &cirrus_mode_config_funcs;
+
+	return 0;
 }
 
 /* ------------------------------------------------------------------ */
 
-static void cirrus_release(struct drm_device *dev)
-{
-	struct cirrus_device *cirrus = dev->dev_private;
-
-	drm_mode_config_cleanup(dev);
-	kfree(cirrus);
-}
-
 DEFINE_DRM_GEM_FOPS(cirrus_fops);
 
 static struct drm_driver cirrus_driver = {
@@ -546,7 +545,6 @@ static struct drm_driver cirrus_driver = {
 
 	.fops		 = &cirrus_fops,
 	DRM_GEM_SHMEM_DRIVER_OPS,
-	.release         = cirrus_release,
 };
 
 static int cirrus_pci_probe(struct pci_dev *pdev,
@@ -560,7 +558,7 @@ static int cirrus_pci_probe(struct pci_dev *pdev,
 	if (ret)
 		return ret;
 
-	ret = pci_enable_device(pdev);
+	ret = pcim_enable_device(pdev);
 	if (ret)
 		return ret;
 
@@ -571,34 +569,38 @@ static int cirrus_pci_probe(struct pci_dev *pdev,
 	ret = -ENOMEM;
 	cirrus = kzalloc(sizeof(*cirrus), GFP_KERNEL);
 	if (cirrus == NULL)
-		goto err_pci_release;
+		return ret;
 
 	dev = &cirrus->dev;
-	ret = drm_dev_init(dev, &cirrus_driver, &pdev->dev);
-	if (ret)
-		goto err_free_cirrus;
+	ret = devm_drm_dev_init(&pdev->dev, dev, &cirrus_driver);
+	if (ret) {
+		kfree(cirrus);
+		return ret;
+	}
 	dev->dev_private = cirrus;
+	drmm_add_final_kfree(dev, cirrus);
 
-	ret = -ENOMEM;
-	cirrus->vram = ioremap(pci_resource_start(pdev, 0),
-			       pci_resource_len(pdev, 0));
+	cirrus->vram = devm_ioremap(&pdev->dev, pci_resource_start(pdev, 0),
+				    pci_resource_len(pdev, 0));
 	if (cirrus->vram == NULL)
-		goto err_dev_put;
+		return -ENOMEM;
 
-	cirrus->mmio = ioremap(pci_resource_start(pdev, 1),
-			       pci_resource_len(pdev, 1));
+	cirrus->mmio = devm_ioremap(&pdev->dev, pci_resource_start(pdev, 1),
+				    pci_resource_len(pdev, 1));
 	if (cirrus->mmio == NULL)
-		goto err_unmap_vram;
+		return -ENOMEM;
 
-	cirrus_mode_config_init(cirrus);
+	ret = cirrus_mode_config_init(cirrus);
+	if (ret)
+		return ret;
 
 	ret = cirrus_conn_init(cirrus);
 	if (ret < 0)
-		goto err_cleanup;
+		return ret;
 
 	ret = cirrus_pipe_init(cirrus);
 	if (ret < 0)
-		goto err_cleanup;
+		return ret;
 
 	drm_mode_config_reset(dev);
 
@@ -606,36 +608,18 @@ static int cirrus_pci_probe(struct pci_dev *pdev,
 	pci_set_drvdata(pdev, dev);
 	ret = drm_dev_register(dev, 0);
 	if (ret)
-		goto err_cleanup;
+		return ret;
 
 	drm_fbdev_generic_setup(dev, dev->mode_config.preferred_depth);
 	return 0;
-
-err_cleanup:
-	drm_mode_config_cleanup(dev);
-	iounmap(cirrus->mmio);
-err_unmap_vram:
-	iounmap(cirrus->vram);
-err_dev_put:
-	drm_dev_put(dev);
-err_free_cirrus:
-	kfree(cirrus);
-err_pci_release:
-	pci_release_regions(pdev);
-	return ret;
 }
 
 static void cirrus_pci_remove(struct pci_dev *pdev)
 {
 	struct drm_device *dev = pci_get_drvdata(pdev);
-	struct cirrus_device *cirrus = dev->dev_private;
 
 	drm_dev_unplug(dev);
 	drm_atomic_helper_shutdown(dev);
-	iounmap(cirrus->mmio);
-	iounmap(cirrus->vram);
-	drm_dev_put(dev);
-	pci_release_regions(pdev);
 }
 
 static const struct pci_device_id pciidlist[] = {
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 9ccfbf213d72..965173fd0ac2 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1641,10 +1641,10 @@ static const struct drm_info_list drm_atomic_debugfs_list[] = {
 	{"state", drm_state_info, 0},
 };
 
-int drm_atomic_debugfs_init(struct drm_minor *minor)
+void drm_atomic_debugfs_init(struct drm_minor *minor)
 {
-	return drm_debugfs_create_files(drm_atomic_debugfs_list,
-			ARRAY_SIZE(drm_atomic_debugfs_list),
-			minor->debugfs_root, minor);
+	drm_debugfs_create_files(drm_atomic_debugfs_list,
+				 ARRAY_SIZE(drm_atomic_debugfs_list),
+				 minor->debugfs_root, minor);
 }
 #endif
diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
index 531b876d0ed8..800ac39f3213 100644
--- a/drivers/gpu/drm/drm_auth.c
+++ b/drivers/gpu/drm/drm_auth.c
@@ -135,6 +135,7 @@ static int drm_set_master(struct drm_device *dev, struct drm_file *fpriv,
 		}
 	}
 
+	fpriv->was_master = (ret == 0);
 	return ret;
 }
 
@@ -174,17 +175,77 @@ static int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv)
 	return ret;
 }
 
+/*
+ * In the olden days the SET/DROP_MASTER ioctls used to return EACCES when
+ * CAP_SYS_ADMIN was not set. This was used to prevent rogue applications
+ * from becoming master and/or failing to release it.
+ *
+ * At the same time, the first client (for a given VT) is _always_ master.
+ * Thus in order for the ioctls to succeed, one had to _explicitly_ run the
+ * application as root or flip the setuid bit.
+ *
+ * If the CAP_SYS_ADMIN was missing, no other client could become master...
+ * EVER :-( Leading to a) the graphics session dying badly or b) a completely
+ * locked session.
+ *
+ *
+ * As some point systemd-logind was introduced to orchestrate and delegate
+ * master as applicable. It does so by opening the fd and passing it to users
+ * while in itself logind a) does the set/drop master per users' request and
+ * b)  * implicitly drops master on VT switch.
+ *
+ * Even though logind looks like the future, there are a few issues:
+ *  - some platforms don't have equivalent (Android, CrOS, some BSDs) so
+ * root is required _solely_ for SET/DROP MASTER.
+ *  - applications may not be updated to use it,
+ *  - any client which fails to drop master* can DoS the application using
+ * logind, to a varying degree.
+ *
+ * * Either due missing CAP_SYS_ADMIN or simply not calling DROP_MASTER.
+ *
+ *
+ * Here we implement the next best thing:
+ *  - ensure the logind style of fd passing works unchanged, and
+ *  - allow a client to drop/set master, iff it is/was master at a given point
+ * in time.
+ *
+ * Note: DROP_MASTER cannot be free for all, as an arbitrator user could:
+ *  - DoS/crash the arbitrator - details would be implementation specific
+ *  - open the node, become master implicitly and cause issues
+ *
+ * As a result this fixes the following when using root-less build w/o logind
+ * - startx
+ * - weston
+ * - various compositors based on wlroots
+ */
+static int
+drm_master_check_perm(struct drm_device *dev, struct drm_file *file_priv)
+{
+	if (file_priv->pid == task_pid(current) && file_priv->was_master)
+		return 0;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EACCES;
+
+	return 0;
+}
+
 int drm_setmaster_ioctl(struct drm_device *dev, void *data,
 			struct drm_file *file_priv)
 {
 	int ret = 0;
 
 	mutex_lock(&dev->master_mutex);
+
+	ret = drm_master_check_perm(dev, file_priv);
+	if (ret)
+		goto out_unlock;
+
 	if (drm_is_current_master(file_priv))
 		goto out_unlock;
 
 	if (dev->master) {
-		ret = -EINVAL;
+		ret = -EBUSY;
 		goto out_unlock;
 	}
 
@@ -224,6 +285,12 @@ int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
 	int ret = -EINVAL;
 
 	mutex_lock(&dev->master_mutex);
+
+	ret = drm_master_check_perm(dev, file_priv);
+	if (ret)
+		goto out_unlock;
+
+	ret = -EINVAL;
 	if (!drm_is_current_master(file_priv))
 		goto out_unlock;
 
diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
index 121481f6aa71..88eedee018d3 100644
--- a/drivers/gpu/drm/drm_blend.c
+++ b/drivers/gpu/drm/drm_blend.c
@@ -183,6 +183,12 @@
  *		 plane does not expose the "alpha" property, then this is
  *		 assumed to be 1.0
  *
+ * IN_FORMATS:
+ *	Blob property which contains the set of buffer format and modifier
+ *	pairs supported by this plane. The blob is a drm_format_modifier_blob
+ *	struct. Without this property the plane doesn't support buffers with
+ *	modifiers. Userspace cannot change this property.
+ *
  * Note that all the property extensions described here apply either to the
  * plane or the CRTC (e.g. for the background color, which currently is not
  * exposed and assumed to be black).
diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c
index dcabf5698333..ef26ac57f039 100644
--- a/drivers/gpu/drm/drm_bufs.c
+++ b/drivers/gpu/drm/drm_bufs.c
@@ -33,6 +33,7 @@
 #include <linux/mm.h>
 #include <linux/mman.h>
 #include <linux/nospec.h>
+#include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/uaccess.h>
 #include <linux/vmalloc.h>
@@ -43,7 +44,6 @@
 #include <drm/drm_device.h>
 #include <drm/drm_drv.h>
 #include <drm/drm_file.h>
-#include <drm/drm_pci.h>
 #include <drm/drm_print.h>
 
 #include "drm_legacy.h"
diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c
index 6b0c6ef8b9b3..8cb93f5209a4 100644
--- a/drivers/gpu/drm/drm_client.c
+++ b/drivers/gpu/drm/drm_client.c
@@ -457,10 +457,10 @@ static const struct drm_info_list drm_client_debugfs_list[] = {
 	{ "internal_clients", drm_client_debugfs_internal_clients, 0 },
 };
 
-int drm_client_debugfs_init(struct drm_minor *minor)
+void drm_client_debugfs_init(struct drm_minor *minor)
 {
-	return drm_debugfs_create_files(drm_client_debugfs_list,
-					ARRAY_SIZE(drm_client_debugfs_list),
-					minor->debugfs_root, minor);
+	drm_debugfs_create_files(drm_client_debugfs_list,
+				 ARRAY_SIZE(drm_client_debugfs_list),
+				 minor->debugfs_root, minor);
 }
 #endif
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 644f0ad10671..b1099e1251a2 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1970,6 +1970,8 @@ int drm_connector_update_edid_property(struct drm_connector *connector,
 	else
 		drm_reset_display_info(connector);
 
+	drm_update_tile_info(connector, edid);
+
 	drm_object_property_set_value(&connector->base,
 				      dev->mode_config.non_desktop_property,
 				      connector->display_info.non_desktop);
@@ -2392,7 +2394,7 @@ EXPORT_SYMBOL(drm_mode_put_tile_group);
  * tile group or NULL if not found.
  */
 struct drm_tile_group *drm_mode_get_tile_group(struct drm_device *dev,
-					       char topology[8])
+					       const char topology[8])
 {
 	struct drm_tile_group *tg;
 	int id;
@@ -2422,7 +2424,7 @@ EXPORT_SYMBOL(drm_mode_get_tile_group);
  * new tile group or NULL.
  */
 struct drm_tile_group *drm_mode_create_tile_group(struct drm_device *dev,
-						  char topology[8])
+						  const char topology[8])
 {
 	struct drm_tile_group *tg;
 	int ret;
diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h
index 16f2413403aa..da96b2f64d7e 100644
--- a/drivers/gpu/drm/drm_crtc_internal.h
+++ b/drivers/gpu/drm/drm_crtc_internal.h
@@ -82,6 +82,7 @@ int drm_mode_setcrtc(struct drm_device *dev,
 /* drm_mode_config.c */
 int drm_modeset_register_all(struct drm_device *dev);
 void drm_modeset_unregister_all(struct drm_device *dev);
+void drm_mode_config_validate(struct drm_device *dev);
 
 /* drm_modes.c */
 const char *drm_get_mode_status_name(enum drm_mode_status status);
@@ -224,7 +225,7 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
 /* drm_atomic.c */
 #ifdef CONFIG_DEBUG_FS
 struct drm_minor;
-int drm_atomic_debugfs_init(struct drm_minor *minor);
+void drm_atomic_debugfs_init(struct drm_minor *minor);
 #endif
 
 int __drm_atomic_helper_disable_plane(struct drm_plane *plane,
@@ -278,3 +279,4 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
 void drm_mode_fixup_1366x768(struct drm_display_mode *mode);
 void drm_reset_display_info(struct drm_connector *connector);
 u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edid);
+void drm_update_tile_info(struct drm_connector *connector, const struct edid *edid);
diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
index 4e673d318503..2bea22130703 100644
--- a/drivers/gpu/drm/drm_debugfs.c
+++ b/drivers/gpu/drm/drm_debugfs.c
@@ -172,8 +172,8 @@ static const struct file_operations drm_debugfs_fops = {
  * &struct drm_info_list in the given root directory. These files will be removed
  * automatically on drm_debugfs_cleanup().
  */
-int drm_debugfs_create_files(const struct drm_info_list *files, int count,
-			     struct dentry *root, struct drm_minor *minor)
+void drm_debugfs_create_files(const struct drm_info_list *files, int count,
+			      struct dentry *root, struct drm_minor *minor)
 {
 	struct drm_device *dev = minor->dev;
 	struct drm_info_node *tmp;
@@ -199,7 +199,6 @@ int drm_debugfs_create_files(const struct drm_info_list *files, int count,
 		list_add(&tmp->list, &minor->debugfs_list);
 		mutex_unlock(&minor->debugfs_lock);
 	}
-	return 0;
 }
 EXPORT_SYMBOL(drm_debugfs_create_files);
 
@@ -208,52 +207,28 @@ int drm_debugfs_init(struct drm_minor *minor, int minor_id,
 {
 	struct drm_device *dev = minor->dev;
 	char name[64];
-	int ret;
 
 	INIT_LIST_HEAD(&minor->debugfs_list);
 	mutex_init(&minor->debugfs_lock);
 	sprintf(name, "%d", minor_id);
 	minor->debugfs_root = debugfs_create_dir(name, root);
 
-	ret = drm_debugfs_create_files(drm_debugfs_list, DRM_DEBUGFS_ENTRIES,
-				       minor->debugfs_root, minor);
-	if (ret) {
-		debugfs_remove(minor->debugfs_root);
-		minor->debugfs_root = NULL;
-		DRM_ERROR("Failed to create core drm debugfs files\n");
-		return ret;
-	}
+	drm_debugfs_create_files(drm_debugfs_list, DRM_DEBUGFS_ENTRIES,
+				 minor->debugfs_root, minor);
 
 	if (drm_drv_uses_atomic_modeset(dev)) {
-		ret = drm_atomic_debugfs_init(minor);
-		if (ret) {
-			DRM_ERROR("Failed to create atomic debugfs files\n");
-			return ret;
-		}
+		drm_atomic_debugfs_init(minor);
 	}
 
 	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
-		ret = drm_framebuffer_debugfs_init(minor);
-		if (ret) {
-			DRM_ERROR("Failed to create framebuffer debugfs file\n");
-			return ret;
-		}
+		drm_framebuffer_debugfs_init(minor);
 
-		ret = drm_client_debugfs_init(minor);
-		if (ret) {
-			DRM_ERROR("Failed to create client debugfs file\n");
-			return ret;
-		}
+		drm_client_debugfs_init(minor);
 	}
 
-	if (dev->driver->debugfs_init) {
-		ret = dev->driver->debugfs_init(minor);
-		if (ret) {
-			DRM_ERROR("DRM: Driver failed to initialize "
-				  "/sys/kernel/debug/dri.\n");
-			return ret;
-		}
-	}
+	if (dev->driver->debugfs_init)
+		dev->driver->debugfs_init(minor);
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/drm_dma.c b/drivers/gpu/drm/drm_dma.c
index a7add55a85b4..d07ba54ec945 100644
--- a/drivers/gpu/drm/drm_dma.c
+++ b/drivers/gpu/drm/drm_dma.c
@@ -34,9 +34,9 @@
  */
 
 #include <linux/export.h>
+#include <linux/pci.h>
 
 #include <drm/drm_drv.h>
-#include <drm/drm_pci.h>
 #include <drm/drm_print.h>
 
 #include "drm_legacy.h"
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index c6fbe6e6bc9d..612a59ec8116 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -1238,6 +1238,8 @@ static const struct dpcd_quirk dpcd_quirk_list[] = {
 	{ OUI(0x00, 0x00, 0x00), DEVICE_ID('C', 'H', '7', '5', '1', '1'), false, BIT(DP_DPCD_QUIRK_NO_SINK_COUNT) },
 	/* Synaptics DP1.4 MST hubs can support DSC without virtual DPCD */
 	{ OUI(0x90, 0xCC, 0x24), DEVICE_ID_ANY, true, BIT(DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD) },
+	/* Apple MacBookPro 2017 15 inch eDP Retina panel reports too low DP_MAX_LINK_RATE */
+	{ OUI(0x00, 0x10, 0xfa), DEVICE_ID(101, 68, 21, 101, 98, 97), false, BIT(DP_DPCD_QUIRK_CAN_DO_MAX_LINK_RATE_3_24_GBPS) },
 };
 
 #undef OUI
@@ -1533,3 +1535,97 @@ int drm_dp_dsc_sink_supported_input_bpcs(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_S
 	return num_bpc;
 }
 EXPORT_SYMBOL(drm_dp_dsc_sink_supported_input_bpcs);
+
+/**
+ * drm_dp_get_phy_test_pattern() - get the requested pattern from the sink.
+ * @aux: DisplayPort AUX channel
+ * @data: DP phy compliance test parameters.
+ *
+ * Returns 0 on success or a negative error code on failure.
+ */
+int drm_dp_get_phy_test_pattern(struct drm_dp_aux *aux,
+				struct drm_dp_phy_test_params *data)
+{
+	int err;
+	u8 rate, lanes;
+
+	err = drm_dp_dpcd_readb(aux, DP_TEST_LINK_RATE, &rate);
+	if (err < 0)
+		return err;
+	data->link_rate = drm_dp_bw_code_to_link_rate(rate);
+
+	err = drm_dp_dpcd_readb(aux, DP_TEST_LANE_COUNT, &lanes);
+	if (err < 0)
+		return err;
+	data->num_lanes = lanes & DP_MAX_LANE_COUNT_MASK;
+
+	if (lanes & DP_ENHANCED_FRAME_CAP)
+		data->enhanced_frame_cap = true;
+
+	err = drm_dp_dpcd_readb(aux, DP_PHY_TEST_PATTERN, &data->phy_pattern);
+	if (err < 0)
+		return err;
+
+	switch (data->phy_pattern) {
+	case DP_PHY_TEST_PATTERN_80BIT_CUSTOM:
+		err = drm_dp_dpcd_read(aux, DP_TEST_80BIT_CUSTOM_PATTERN_7_0,
+				       &data->custom80, sizeof(data->custom80));
+		if (err < 0)
+			return err;
+
+		break;
+	case DP_PHY_TEST_PATTERN_CP2520:
+		err = drm_dp_dpcd_read(aux, DP_TEST_HBR2_SCRAMBLER_RESET,
+				       &data->hbr2_reset,
+				       sizeof(data->hbr2_reset));
+		if (err < 0)
+			return err;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_dp_get_phy_test_pattern);
+
+/**
+ * drm_dp_set_phy_test_pattern() - set the pattern to the sink.
+ * @aux: DisplayPort AUX channel
+ * @data: DP phy compliance test parameters.
+ *
+ * Returns 0 on success or a negative error code on failure.
+ */
+int drm_dp_set_phy_test_pattern(struct drm_dp_aux *aux,
+				struct drm_dp_phy_test_params *data, u8 dp_rev)
+{
+	int err, i;
+	u8 link_config[2];
+	u8 test_pattern;
+
+	link_config[0] = drm_dp_link_rate_to_bw_code(data->link_rate);
+	link_config[1] = data->num_lanes;
+	if (data->enhanced_frame_cap)
+		link_config[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
+	err = drm_dp_dpcd_write(aux, DP_LINK_BW_SET, link_config, 2);
+	if (err < 0)
+		return err;
+
+	test_pattern = data->phy_pattern;
+	if (dp_rev < 0x12) {
+		test_pattern = (test_pattern << 2) &
+			       DP_LINK_QUAL_PATTERN_11_MASK;
+		err = drm_dp_dpcd_writeb(aux, DP_TRAINING_PATTERN_SET,
+					 test_pattern);
+		if (err < 0)
+			return err;
+	} else {
+		for (i = 0; i < data->num_lanes; i++) {
+			err = drm_dp_dpcd_writeb(aux,
+						 DP_LINK_QUAL_LANE0_SET + i,
+						 test_pattern);
+			if (err < 0)
+				return err;
+		}
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_dp_set_phy_test_pattern);
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index 70c4b7afed12..167e921ae010 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -27,6 +27,7 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/seq_file.h>
+#include <linux/iopoll.h>
 
 #if IS_ENABLED(CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS)
 #include <linux/stacktrace.h>
@@ -687,51 +688,45 @@ static void drm_dp_encode_sideband_reply(struct drm_dp_sideband_msg_reply_body *
 	raw->cur_len = idx;
 }
 
-/* this adds a chunk of msg to the builder to get the final msg */
-static bool drm_dp_sideband_msg_build(struct drm_dp_sideband_msg_rx *msg,
-				      u8 *replybuf, u8 replybuflen, bool hdr)
+static int drm_dp_sideband_msg_set_header(struct drm_dp_sideband_msg_rx *msg,
+					  struct drm_dp_sideband_msg_hdr *hdr,
+					  u8 hdrlen)
 {
-	int ret;
-	u8 crc4;
+	/*
+	 * ignore out-of-order messages or messages that are part of a
+	 * failed transaction
+	 */
+	if (!hdr->somt && !msg->have_somt)
+		return false;
 
-	if (hdr) {
-		u8 hdrlen;
-		struct drm_dp_sideband_msg_hdr recv_hdr;
-		ret = drm_dp_decode_sideband_msg_hdr(&recv_hdr, replybuf, replybuflen, &hdrlen);
-		if (ret == false) {
-			print_hex_dump(KERN_DEBUG, "failed hdr", DUMP_PREFIX_NONE, 16, 1, replybuf, replybuflen, false);
-			return false;
-		}
+	/* get length contained in this portion */
+	msg->curchunk_idx = 0;
+	msg->curchunk_len = hdr->msg_len;
+	msg->curchunk_hdrlen = hdrlen;
 
-		/*
-		 * ignore out-of-order messages or messages that are part of a
-		 * failed transaction
-		 */
-		if (!recv_hdr.somt && !msg->have_somt)
-			return false;
+	/* we have already gotten an somt - don't bother parsing */
+	if (hdr->somt && msg->have_somt)
+		return false;
 
-		/* get length contained in this portion */
-		msg->curchunk_len = recv_hdr.msg_len;
-		msg->curchunk_hdrlen = hdrlen;
+	if (hdr->somt) {
+		memcpy(&msg->initial_hdr, hdr,
+		       sizeof(struct drm_dp_sideband_msg_hdr));
+		msg->have_somt = true;
+	}
+	if (hdr->eomt)
+		msg->have_eomt = true;
 
-		/* we have already gotten an somt - don't bother parsing */
-		if (recv_hdr.somt && msg->have_somt)
-			return false;
+	return true;
+}
 
-		if (recv_hdr.somt) {
-			memcpy(&msg->initial_hdr, &recv_hdr, sizeof(struct drm_dp_sideband_msg_hdr));
-			msg->have_somt = true;
-		}
-		if (recv_hdr.eomt)
-			msg->have_eomt = true;
+/* this adds a chunk of msg to the builder to get the final msg */
+static bool drm_dp_sideband_append_payload(struct drm_dp_sideband_msg_rx *msg,
+					   u8 *replybuf, u8 replybuflen)
+{
+	u8 crc4;
 
-		/* copy the bytes for the remainder of this header chunk */
-		msg->curchunk_idx = min(msg->curchunk_len, (u8)(replybuflen - hdrlen));
-		memcpy(&msg->chunk[0], replybuf + hdrlen, msg->curchunk_idx);
-	} else {
-		memcpy(&msg->chunk[msg->curchunk_idx], replybuf, replybuflen);
-		msg->curchunk_idx += replybuflen;
-	}
+	memcpy(&msg->chunk[msg->curchunk_idx], replybuf, replybuflen);
+	msg->curchunk_idx += replybuflen;
 
 	if (msg->curchunk_idx >= msg->curchunk_len) {
 		/* do CRC */
@@ -1060,13 +1055,12 @@ static void build_link_address(struct drm_dp_sideband_msg_tx *msg)
 	drm_dp_encode_sideband_req(&req, msg);
 }
 
-static int build_clear_payload_id_table(struct drm_dp_sideband_msg_tx *msg)
+static void build_clear_payload_id_table(struct drm_dp_sideband_msg_tx *msg)
 {
 	struct drm_dp_sideband_msg_req_body req;
 
 	req.req_type = DP_CLEAR_PAYLOAD_ID_TABLE;
 	drm_dp_encode_sideband_req(&req, msg);
-	return 0;
 }
 
 static int build_enum_path_resources(struct drm_dp_sideband_msg_tx *msg,
@@ -1211,8 +1205,6 @@ static int drm_dp_mst_wait_tx_reply(struct drm_dp_mst_branch *mstb,
 		    txmsg->state == DRM_DP_SIDEBAND_TX_SENT) {
 			mstb->tx_slots[txmsg->seqno] = NULL;
 		}
-		mgr->is_waiting_for_dwn_reply = false;
-
 	}
 out:
 	if (unlikely(ret == -EIO) && drm_debug_enabled(DRM_UT_DP)) {
@@ -1222,7 +1214,6 @@ static int drm_dp_mst_wait_tx_reply(struct drm_dp_mst_branch *mstb,
 	}
 	mutex_unlock(&mgr->qlock);
 
-	drm_dp_mst_kick_tx(mgr);
 	return ret;
 }
 
@@ -2798,11 +2789,9 @@ static void process_single_down_tx_qlock(struct drm_dp_mst_topology_mgr *mgr)
 	ret = process_single_tx_qlock(mgr, txmsg, false);
 	if (ret == 1) {
 		/* txmsg is sent it should be in the slots now */
-		mgr->is_waiting_for_dwn_reply = true;
 		list_del(&txmsg->next);
 	} else if (ret) {
 		DRM_DEBUG_KMS("failed to send msg in q %d\n", ret);
-		mgr->is_waiting_for_dwn_reply = false;
 		list_del(&txmsg->next);
 		if (txmsg->seqno != -1)
 			txmsg->dst->tx_slots[txmsg->seqno] = NULL;
@@ -2842,8 +2831,7 @@ static void drm_dp_queue_down_tx(struct drm_dp_mst_topology_mgr *mgr,
 		drm_dp_mst_dump_sideband_msg_tx(&p, txmsg);
 	}
 
-	if (list_is_singular(&mgr->tx_msg_downq) &&
-	    !mgr->is_waiting_for_dwn_reply)
+	if (list_is_singular(&mgr->tx_msg_downq))
 		process_single_down_tx_qlock(mgr);
 	mutex_unlock(&mgr->qlock);
 }
@@ -3703,31 +3691,67 @@ int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr,
 }
 EXPORT_SYMBOL(drm_dp_mst_topology_mgr_resume);
 
-static bool drm_dp_get_one_sb_msg(struct drm_dp_mst_topology_mgr *mgr, bool up)
+static bool drm_dp_get_one_sb_msg(struct drm_dp_mst_topology_mgr *mgr, bool up,
+				  struct drm_dp_mst_branch **mstb, int *seqno)
 {
 	int len;
 	u8 replyblock[32];
 	int replylen, curreply;
 	int ret;
+	u8 hdrlen;
+	struct drm_dp_sideband_msg_hdr hdr;
 	struct drm_dp_sideband_msg_rx *msg;
-	int basereg = up ? DP_SIDEBAND_MSG_UP_REQ_BASE : DP_SIDEBAND_MSG_DOWN_REP_BASE;
-	msg = up ? &mgr->up_req_recv : &mgr->down_rep_recv;
+	int basereg = up ? DP_SIDEBAND_MSG_UP_REQ_BASE :
+			   DP_SIDEBAND_MSG_DOWN_REP_BASE;
+
+	if (!up)
+		*mstb = NULL;
+	*seqno = -1;
 
 	len = min(mgr->max_dpcd_transaction_bytes, 16);
-	ret = drm_dp_dpcd_read(mgr->aux, basereg,
-			       replyblock, len);
+	ret = drm_dp_dpcd_read(mgr->aux, basereg, replyblock, len);
 	if (ret != len) {
 		DRM_DEBUG_KMS("failed to read DPCD down rep %d %d\n", len, ret);
 		return false;
 	}
-	ret = drm_dp_sideband_msg_build(msg, replyblock, len, true);
+
+	ret = drm_dp_decode_sideband_msg_hdr(&hdr, replyblock, len, &hdrlen);
+	if (ret == false) {
+		print_hex_dump(KERN_DEBUG, "failed hdr", DUMP_PREFIX_NONE, 16,
+			       1, replyblock, len, false);
+		DRM_DEBUG_KMS("ERROR: failed header\n");
+		return false;
+	}
+
+	*seqno = hdr.seqno;
+
+	if (up) {
+		msg = &mgr->up_req_recv;
+	} else {
+		/* Caller is responsible for giving back this reference */
+		*mstb = drm_dp_get_mst_branch_device(mgr, hdr.lct, hdr.rad);
+		if (!*mstb) {
+			DRM_DEBUG_KMS("Got MST reply from unknown device %d\n",
+				      hdr.lct);
+			return false;
+		}
+		msg = &(*mstb)->down_rep_recv[hdr.seqno];
+	}
+
+	if (!drm_dp_sideband_msg_set_header(msg, &hdr, hdrlen)) {
+		DRM_DEBUG_KMS("sideband msg set header failed %d\n",
+			      replyblock[0]);
+		return false;
+	}
+
+	replylen = min(msg->curchunk_len, (u8)(len - hdrlen));
+	ret = drm_dp_sideband_append_payload(msg, replyblock + hdrlen, replylen);
 	if (!ret) {
 		DRM_DEBUG_KMS("sideband msg build failed %d\n", replyblock[0]);
 		return false;
 	}
-	replylen = msg->curchunk_len + msg->curchunk_hdrlen;
 
-	replylen -= len;
+	replylen = msg->curchunk_len + msg->curchunk_hdrlen - len;
 	curreply = len;
 	while (replylen > 0) {
 		len = min3(replylen, mgr->max_dpcd_transaction_bytes, 16);
@@ -3739,7 +3763,7 @@ static bool drm_dp_get_one_sb_msg(struct drm_dp_mst_topology_mgr *mgr, bool up)
 			return false;
 		}
 
-		ret = drm_dp_sideband_msg_build(msg, replyblock, len, false);
+		ret = drm_dp_sideband_append_payload(msg, replyblock, len);
 		if (!ret) {
 			DRM_DEBUG_KMS("failed to build sideband msg\n");
 			return false;
@@ -3754,67 +3778,63 @@ static bool drm_dp_get_one_sb_msg(struct drm_dp_mst_topology_mgr *mgr, bool up)
 static int drm_dp_mst_handle_down_rep(struct drm_dp_mst_topology_mgr *mgr)
 {
 	struct drm_dp_sideband_msg_tx *txmsg;
-	struct drm_dp_mst_branch *mstb;
-	struct drm_dp_sideband_msg_hdr *hdr = &mgr->down_rep_recv.initial_hdr;
-	int slot = -1;
+	struct drm_dp_mst_branch *mstb = NULL;
+	struct drm_dp_sideband_msg_rx *msg = NULL;
+	int seqno = -1;
 
-	if (!drm_dp_get_one_sb_msg(mgr, false))
-		goto clear_down_rep_recv;
+	if (!drm_dp_get_one_sb_msg(mgr, false, &mstb, &seqno))
+		goto out_clear_reply;
 
-	if (!mgr->down_rep_recv.have_eomt)
-		return 0;
+	msg = &mstb->down_rep_recv[seqno];
 
-	mstb = drm_dp_get_mst_branch_device(mgr, hdr->lct, hdr->rad);
-	if (!mstb) {
-		DRM_DEBUG_KMS("Got MST reply from unknown device %d\n",
-			      hdr->lct);
-		goto clear_down_rep_recv;
-	}
+	/* Multi-packet message transmission, don't clear the reply */
+	if (!msg->have_eomt)
+		goto out;
 
 	/* find the message */
-	slot = hdr->seqno;
 	mutex_lock(&mgr->qlock);
-	txmsg = mstb->tx_slots[slot];
+	txmsg = mstb->tx_slots[seqno];
 	/* remove from slots */
 	mutex_unlock(&mgr->qlock);
 
 	if (!txmsg) {
+		struct drm_dp_sideband_msg_hdr *hdr;
+		hdr = &msg->initial_hdr;
 		DRM_DEBUG_KMS("Got MST reply with no msg %p %d %d %02x %02x\n",
 			      mstb, hdr->seqno, hdr->lct, hdr->rad[0],
-			      mgr->down_rep_recv.msg[0]);
-		goto no_msg;
+			      msg->msg[0]);
+		goto out_clear_reply;
 	}
 
-	drm_dp_sideband_parse_reply(&mgr->down_rep_recv, &txmsg->reply);
+	drm_dp_sideband_parse_reply(msg, &txmsg->reply);
 
-	if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK)
+	if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK) {
 		DRM_DEBUG_KMS("Got NAK reply: req 0x%02x (%s), reason 0x%02x (%s), nak data 0x%02x\n",
 			      txmsg->reply.req_type,
 			      drm_dp_mst_req_type_str(txmsg->reply.req_type),
 			      txmsg->reply.u.nak.reason,
 			      drm_dp_mst_nak_reason_str(txmsg->reply.u.nak.reason),
 			      txmsg->reply.u.nak.nak_data);
+	}
 
-	memset(&mgr->down_rep_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
+	memset(msg, 0, sizeof(struct drm_dp_sideband_msg_rx));
 	drm_dp_mst_topology_put_mstb(mstb);
 
 	mutex_lock(&mgr->qlock);
 	txmsg->state = DRM_DP_SIDEBAND_TX_RX;
-	mstb->tx_slots[slot] = NULL;
-	mgr->is_waiting_for_dwn_reply = false;
+	mstb->tx_slots[seqno] = NULL;
 	mutex_unlock(&mgr->qlock);
 
 	wake_up_all(&mgr->tx_waitq);
 
 	return 0;
 
-no_msg:
-	drm_dp_mst_topology_put_mstb(mstb);
-clear_down_rep_recv:
-	mutex_lock(&mgr->qlock);
-	mgr->is_waiting_for_dwn_reply = false;
-	mutex_unlock(&mgr->qlock);
-	memset(&mgr->down_rep_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
+out_clear_reply:
+	if (msg)
+		memset(msg, 0, sizeof(struct drm_dp_sideband_msg_rx));
+out:
+	if (mstb)
+		drm_dp_mst_topology_put_mstb(mstb);
 
 	return 0;
 }
@@ -3890,11 +3910,10 @@ static void drm_dp_mst_up_req_work(struct work_struct *work)
 
 static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr)
 {
-	struct drm_dp_sideband_msg_hdr *hdr = &mgr->up_req_recv.initial_hdr;
 	struct drm_dp_pending_up_req *up_req;
-	bool seqno;
+	int seqno;
 
-	if (!drm_dp_get_one_sb_msg(mgr, true))
+	if (!drm_dp_get_one_sb_msg(mgr, true, NULL, &seqno))
 		goto out;
 
 	if (!mgr->up_req_recv.have_eomt)
@@ -3907,7 +3926,6 @@ static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr)
 	}
 	INIT_LIST_HEAD(&up_req->next);
 
-	seqno = hdr->seqno;
 	drm_dp_sideband_parse_req(&mgr->up_req_recv, &up_req->msg);
 
 	if (up_req->msg.req_type != DP_CONNECTION_STATUS_NOTIFY &&
@@ -3941,7 +3959,7 @@ static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr)
 			      res_stat->available_pbn);
 	}
 
-	up_req->hdr = *hdr;
+	up_req->hdr = mgr->up_req_recv.initial_hdr;
 	mutex_lock(&mgr->up_req_lock);
 	list_add_tail(&up_req->next, &mgr->up_req_list);
 	mutex_unlock(&mgr->up_req_lock);
@@ -4046,27 +4064,6 @@ drm_dp_mst_detect_port(struct drm_connector *connector,
 }
 EXPORT_SYMBOL(drm_dp_mst_detect_port);
 
-/**
- * drm_dp_mst_port_has_audio() - Check whether port has audio capability or not
- * @mgr: manager for this port
- * @port: unverified pointer to a port.
- *
- * This returns whether the port supports audio or not.
- */
-bool drm_dp_mst_port_has_audio(struct drm_dp_mst_topology_mgr *mgr,
-					struct drm_dp_mst_port *port)
-{
-	bool ret = false;
-
-	port = drm_dp_mst_topology_get_port_validated(mgr, port);
-	if (!port)
-		return ret;
-	ret = port->has_audio;
-	drm_dp_mst_topology_put_port(port);
-	return ret;
-}
-EXPORT_SYMBOL(drm_dp_mst_port_has_audio);
-
 /**
  * drm_dp_mst_get_edid() - get EDID for an MST port
  * @connector: toplevel connector to get EDID for
@@ -4443,42 +4440,58 @@ static int drm_dp_dpcd_write_payload(struct drm_dp_mst_topology_mgr *mgr,
 	return ret;
 }
 
+static int do_get_act_status(struct drm_dp_aux *aux)
+{
+	int ret;
+	u8 status;
+
+	ret = drm_dp_dpcd_readb(aux, DP_PAYLOAD_TABLE_UPDATE_STATUS, &status);
+	if (ret < 0)
+		return ret;
+
+	return status;
+}
 
 /**
- * drm_dp_check_act_status() - Check ACT handled status.
+ * drm_dp_check_act_status() - Polls for ACT handled status.
  * @mgr: manager to use
  *
- * Check the payload status bits in the DPCD for ACT handled completion.
+ * Tries waiting for the MST hub to finish updating it's payload table by
+ * polling for the ACT handled bit for up to 3 seconds (yes-some hubs really
+ * take that long).
+ *
+ * Returns:
+ * 0 if the ACT was handled in time, negative error code on failure.
  */
 int drm_dp_check_act_status(struct drm_dp_mst_topology_mgr *mgr)
 {
-	u8 status;
-	int ret;
-	int count = 0;
-
-	do {
-		ret = drm_dp_dpcd_readb(mgr->aux, DP_PAYLOAD_TABLE_UPDATE_STATUS, &status);
-
-		if (ret < 0) {
-			DRM_DEBUG_KMS("failed to read payload table status %d\n", ret);
-			goto fail;
-		}
-
-		if (status & DP_PAYLOAD_ACT_HANDLED)
-			break;
-		count++;
-		udelay(100);
-
-	} while (count < 30);
-
-	if (!(status & DP_PAYLOAD_ACT_HANDLED)) {
-		DRM_DEBUG_KMS("failed to get ACT bit %d after %d retries\n", status, count);
-		ret = -EINVAL;
-		goto fail;
+	/*
+	 * There doesn't seem to be any recommended retry count or timeout in
+	 * the MST specification. Since some hubs have been observed to take
+	 * over 1 second to update their payload allocations under certain
+	 * conditions, we use a rather large timeout value.
+	 */
+	const int timeout_ms = 3000;
+	int ret, status;
+
+	ret = readx_poll_timeout(do_get_act_status, mgr->aux, status,
+				 status & DP_PAYLOAD_ACT_HANDLED || status < 0,
+				 200, timeout_ms * USEC_PER_MSEC);
+	if (ret < 0 && status >= 0) {
+		DRM_ERROR("Failed to get ACT after %dms, last status: %02x\n",
+			  timeout_ms, status);
+		return -EINVAL;
+	} else if (status < 0) {
+		/*
+		 * Failure here isn't unexpected - the hub may have
+		 * just been unplugged
+		 */
+		DRM_DEBUG_KMS("Failed to read payload table status: %d\n",
+			      status);
+		return status;
 	}
+
 	return 0;
-fail:
-	return ret;
 }
 EXPORT_SYMBOL(drm_dp_check_act_status);
 
@@ -4669,28 +4682,18 @@ static void drm_dp_tx_work(struct work_struct *work)
 	struct drm_dp_mst_topology_mgr *mgr = container_of(work, struct drm_dp_mst_topology_mgr, tx_work);
 
 	mutex_lock(&mgr->qlock);
-	if (!list_empty(&mgr->tx_msg_downq) && !mgr->is_waiting_for_dwn_reply)
+	if (!list_empty(&mgr->tx_msg_downq))
 		process_single_down_tx_qlock(mgr);
 	mutex_unlock(&mgr->qlock);
 }
 
-static inline void drm_dp_destroy_connector(struct drm_dp_mst_port *port)
+static inline void
+drm_dp_delayed_destroy_port(struct drm_dp_mst_port *port)
 {
-	if (!port->connector)
-		return;
-
-	if (port->mgr->cbs->destroy_connector) {
-		port->mgr->cbs->destroy_connector(port->mgr, port->connector);
-	} else {
+	if (port->connector) {
 		drm_connector_unregister(port->connector);
 		drm_connector_put(port->connector);
 	}
-}
-
-static inline void
-drm_dp_delayed_destroy_port(struct drm_dp_mst_port *port)
-{
-	drm_dp_destroy_connector(port);
 
 	drm_dp_port_set_pdt(port, DP_PEER_DEVICE_NONE, port->mcs);
 	drm_dp_mst_put_port_malloc(port);
@@ -5494,7 +5497,7 @@ struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port)
 {
 	struct drm_dp_mst_port *immediate_upstream_port;
 	struct drm_dp_mst_port *fec_port;
-	struct drm_dp_desc desc = { 0 };
+	struct drm_dp_desc desc = { };
 	u8 endpoint_fec;
 	u8 endpoint_dsc;
 
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 7b1a628d1f6e..c15c9b4540e1 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -39,6 +39,7 @@
 #include <drm/drm_color_mgmt.h>
 #include <drm/drm_drv.h>
 #include <drm/drm_file.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_mode_object.h>
 #include <drm/drm_print.h>
 
@@ -92,13 +93,27 @@ static struct drm_minor **drm_minor_get_slot(struct drm_device *dev,
 	}
 }
 
+static void drm_minor_alloc_release(struct drm_device *dev, void *data)
+{
+	struct drm_minor *minor = data;
+	unsigned long flags;
+
+	WARN_ON(dev != minor->dev);
+
+	put_device(minor->kdev);
+
+	spin_lock_irqsave(&drm_minor_lock, flags);
+	idr_remove(&drm_minors_idr, minor->index);
+	spin_unlock_irqrestore(&drm_minor_lock, flags);
+}
+
 static int drm_minor_alloc(struct drm_device *dev, unsigned int type)
 {
 	struct drm_minor *minor;
 	unsigned long flags;
 	int r;
 
-	minor = kzalloc(sizeof(*minor), GFP_KERNEL);
+	minor = drmm_kzalloc(dev, sizeof(*minor), GFP_KERNEL);
 	if (!minor)
 		return -ENOMEM;
 
@@ -116,46 +131,20 @@ static int drm_minor_alloc(struct drm_device *dev, unsigned int type)
 	idr_preload_end();
 
 	if (r < 0)
-		goto err_free;
+		return r;
 
 	minor->index = r;
 
+	r = drmm_add_action_or_reset(dev, drm_minor_alloc_release, minor);
+	if (r)
+		return r;
+
 	minor->kdev = drm_sysfs_minor_alloc(minor);
-	if (IS_ERR(minor->kdev)) {
-		r = PTR_ERR(minor->kdev);
-		goto err_index;
-	}
+	if (IS_ERR(minor->kdev))
+		return PTR_ERR(minor->kdev);
 
 	*drm_minor_get_slot(dev, type) = minor;
 	return 0;
-
-err_index:
-	spin_lock_irqsave(&drm_minor_lock, flags);
-	idr_remove(&drm_minors_idr, minor->index);
-	spin_unlock_irqrestore(&drm_minor_lock, flags);
-err_free:
-	kfree(minor);
-	return r;
-}
-
-static void drm_minor_free(struct drm_device *dev, unsigned int type)
-{
-	struct drm_minor **slot, *minor;
-	unsigned long flags;
-
-	slot = drm_minor_get_slot(dev, type);
-	minor = *slot;
-	if (!minor)
-		return;
-
-	put_device(minor->kdev);
-
-	spin_lock_irqsave(&drm_minor_lock, flags);
-	idr_remove(&drm_minors_idr, minor->index);
-	spin_unlock_irqrestore(&drm_minor_lock, flags);
-
-	kfree(minor);
-	*slot = NULL;
 }
 
 static int drm_minor_register(struct drm_device *dev, unsigned int type)
@@ -270,17 +259,22 @@ void drm_minor_release(struct drm_minor *minor)
  * any other resources allocated at device initialization and drop the driver's
  * reference to &drm_device using drm_dev_put().
  *
- * Note that the lifetime rules for &drm_device instance has still a lot of
- * historical baggage. Hence use the reference counting provided by
- * drm_dev_get() and drm_dev_put() only carefully.
+ * Note that any allocation or resource which is visible to userspace must be
+ * released only when the final drm_dev_put() is called, and not when the
+ * driver is unbound from the underlying physical struct &device. Best to use
+ * &drm_device managed resources with drmm_add_action(), drmm_kmalloc() and
+ * related functions.
+ *
+ * devres managed resources like devm_kmalloc() can only be used for resources
+ * directly related to the underlying hardware device, and only used in code
+ * paths fully protected by drm_dev_enter() and drm_dev_exit().
  *
  * Display driver example
  * ~~~~~~~~~~~~~~~~~~~~~~
  *
  * The following example shows a typical structure of a DRM display driver.
  * The example focus on the probe() function and the other functions that is
- * almost always present and serves as a demonstration of devm_drm_dev_init()
- * usage with its accompanying drm_driver->release callback.
+ * almost always present and serves as a demonstration of devm_drm_dev_init().
  *
  * .. code-block:: c
  *
@@ -290,19 +284,8 @@ void drm_minor_release(struct drm_minor *minor)
  *		struct clk *pclk;
  *	};
  *
- *	static void driver_drm_release(struct drm_device *drm)
- *	{
- *		struct driver_device *priv = container_of(...);
- *
- *		drm_mode_config_cleanup(drm);
- *		drm_dev_fini(drm);
- *		kfree(priv->userspace_facing);
- *		kfree(priv);
- *	}
- *
  *	static struct drm_driver driver_drm_driver = {
  *		[...]
- *		.release = driver_drm_release,
  *	};
  *
  *	static int driver_probe(struct platform_device *pdev)
@@ -322,13 +305,16 @@ void drm_minor_release(struct drm_minor *minor)
  *
  *		ret = devm_drm_dev_init(&pdev->dev, drm, &driver_drm_driver);
  *		if (ret) {
- *			kfree(drm);
+ *			kfree(priv);
  *			return ret;
  *		}
+ *		drmm_add_final_kfree(drm, priv);
  *
- *		drm_mode_config_init(drm);
+ *		ret = drmm_mode_config_init(drm);
+ *		if (ret)
+ *			return ret;
  *
- *		priv->userspace_facing = kzalloc(..., GFP_KERNEL);
+ *		priv->userspace_facing = drmm_kzalloc(..., GFP_KERNEL);
  *		if (!priv->userspace_facing)
  *			return -ENOMEM;
  *
@@ -580,6 +566,23 @@ static void drm_fs_inode_free(struct inode *inode)
  *    used.
  */
 
+static void drm_dev_init_release(struct drm_device *dev, void *res)
+{
+	drm_legacy_ctxbitmap_cleanup(dev);
+	drm_legacy_remove_map_hash(dev);
+	drm_fs_inode_free(dev->anon_inode);
+
+	put_device(dev->dev);
+	/* Prevent use-after-free in drm_managed_release when debugging is
+	 * enabled. Slightly awkward, but can't really be helped. */
+	dev->dev = NULL;
+	mutex_destroy(&dev->master_mutex);
+	mutex_destroy(&dev->clientlist_mutex);
+	mutex_destroy(&dev->filelist_mutex);
+	mutex_destroy(&dev->struct_mutex);
+	drm_legacy_destroy_members(dev);
+}
+
 /**
  * drm_dev_init - Initialise new DRM device
  * @dev: DRM device
@@ -608,6 +611,9 @@ static void drm_fs_inode_free(struct inode *inode)
  * arbitrary offset, you must supply a &drm_driver.release callback and control
  * the finalization explicitly.
  *
+ * Note that drivers must call drmm_add_final_kfree() after this function has
+ * completed successfully.
+ *
  * RETURNS:
  * 0 on success, or error code on failure.
  */
@@ -629,6 +635,9 @@ int drm_dev_init(struct drm_device *dev,
 	dev->dev = get_device(parent);
 	dev->driver = driver;
 
+	INIT_LIST_HEAD(&dev->managed.resources);
+	spin_lock_init(&dev->managed.lock);
+
 	/* no per-device feature limits by default */
 	dev->driver_features = ~0u;
 
@@ -644,26 +653,30 @@ int drm_dev_init(struct drm_device *dev,
 	mutex_init(&dev->clientlist_mutex);
 	mutex_init(&dev->master_mutex);
 
+	ret = drmm_add_action(dev, drm_dev_init_release, NULL);
+	if (ret)
+		return ret;
+
 	dev->anon_inode = drm_fs_inode_new();
 	if (IS_ERR(dev->anon_inode)) {
 		ret = PTR_ERR(dev->anon_inode);
 		DRM_ERROR("Cannot allocate anonymous inode: %d\n", ret);
-		goto err_free;
+		goto err;
 	}
 
 	if (drm_core_check_feature(dev, DRIVER_RENDER)) {
 		ret = drm_minor_alloc(dev, DRM_MINOR_RENDER);
 		if (ret)
-			goto err_minors;
+			goto err;
 	}
 
 	ret = drm_minor_alloc(dev, DRM_MINOR_PRIMARY);
 	if (ret)
-		goto err_minors;
+		goto err;
 
 	ret = drm_legacy_create_map_hash(dev);
 	if (ret)
-		goto err_minors;
+		goto err;
 
 	drm_legacy_ctxbitmap_init(dev);
 
@@ -671,33 +684,19 @@ int drm_dev_init(struct drm_device *dev,
 		ret = drm_gem_init(dev);
 		if (ret) {
 			DRM_ERROR("Cannot initialize graphics execution manager (GEM)\n");
-			goto err_ctxbitmap;
+			goto err;
 		}
 	}
 
 	ret = drm_dev_set_unique(dev, dev_name(parent));
 	if (ret)
-		goto err_setunique;
+		goto err;
 
 	return 0;
 
-err_setunique:
-	if (drm_core_check_feature(dev, DRIVER_GEM))
-		drm_gem_destroy(dev);
-err_ctxbitmap:
-	drm_legacy_ctxbitmap_cleanup(dev);
-	drm_legacy_remove_map_hash(dev);
-err_minors:
-	drm_minor_free(dev, DRM_MINOR_PRIMARY);
-	drm_minor_free(dev, DRM_MINOR_RENDER);
-	drm_fs_inode_free(dev->anon_inode);
-err_free:
-	put_device(dev->dev);
-	mutex_destroy(&dev->master_mutex);
-	mutex_destroy(&dev->clientlist_mutex);
-	mutex_destroy(&dev->filelist_mutex);
-	mutex_destroy(&dev->struct_mutex);
-	drm_legacy_destroy_members(dev);
+err:
+	drm_managed_release(dev);
+
 	return ret;
 }
 EXPORT_SYMBOL(drm_dev_init);
@@ -714,8 +713,10 @@ static void devm_drm_dev_init_release(void *data)
  * @driver: DRM driver
  *
  * Managed drm_dev_init(). The DRM device initialized with this function is
- * automatically put on driver detach using drm_dev_put(). You must supply a
- * &drm_driver.release callback to control the finalization explicitly.
+ * automatically put on driver detach using drm_dev_put().
+ *
+ * Note that drivers must call drmm_add_final_kfree() after this function has
+ * completed successfully.
  *
  * RETURNS:
  * 0 on success, or error code on failure.
@@ -726,9 +727,6 @@ int devm_drm_dev_init(struct device *parent,
 {
 	int ret;
 
-	if (WARN_ON(!driver->release))
-		return -EINVAL;
-
 	ret = drm_dev_init(dev, driver, parent);
 	if (ret)
 		return ret;
@@ -741,43 +739,6 @@ int devm_drm_dev_init(struct device *parent,
 }
 EXPORT_SYMBOL(devm_drm_dev_init);
 
-/**
- * drm_dev_fini - Finalize a dead DRM device
- * @dev: DRM device
- *
- * Finalize a dead DRM device. This is the converse to drm_dev_init() and
- * frees up all data allocated by it. All driver private data should be
- * finalized first. Note that this function does not free the @dev, that is
- * left to the caller.
- *
- * The ref-count of @dev must be zero, and drm_dev_fini() should only be called
- * from a &drm_driver.release callback.
- */
-void drm_dev_fini(struct drm_device *dev)
-{
-	drm_vblank_cleanup(dev);
-
-	if (drm_core_check_feature(dev, DRIVER_GEM))
-		drm_gem_destroy(dev);
-
-	drm_legacy_ctxbitmap_cleanup(dev);
-	drm_legacy_remove_map_hash(dev);
-	drm_fs_inode_free(dev->anon_inode);
-
-	drm_minor_free(dev, DRM_MINOR_PRIMARY);
-	drm_minor_free(dev, DRM_MINOR_RENDER);
-
-	put_device(dev->dev);
-
-	mutex_destroy(&dev->master_mutex);
-	mutex_destroy(&dev->clientlist_mutex);
-	mutex_destroy(&dev->filelist_mutex);
-	mutex_destroy(&dev->struct_mutex);
-	drm_legacy_destroy_members(dev);
-	kfree(dev->unique);
-}
-EXPORT_SYMBOL(drm_dev_fini);
-
 /**
  * drm_dev_alloc - Allocate new DRM device
  * @driver: DRM driver to allocate device for
@@ -816,6 +777,8 @@ struct drm_device *drm_dev_alloc(struct drm_driver *driver,
 		return ERR_PTR(ret);
 	}
 
+	drmm_add_final_kfree(dev, dev);
+
 	return dev;
 }
 EXPORT_SYMBOL(drm_dev_alloc);
@@ -824,12 +787,13 @@ static void drm_dev_release(struct kref *ref)
 {
 	struct drm_device *dev = container_of(ref, struct drm_device, ref);
 
-	if (dev->driver->release) {
+	if (dev->driver->release)
 		dev->driver->release(dev);
-	} else {
-		drm_dev_fini(dev);
-		kfree(dev);
-	}
+
+	drm_managed_release(dev);
+
+	if (dev->managed.final_kfree)
+		kfree(dev->managed.final_kfree);
 }
 
 /**
@@ -946,6 +910,11 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags)
 	struct drm_driver *driver = dev->driver;
 	int ret;
 
+	if (!driver->load)
+		drm_mode_config_validate(dev);
+
+	WARN_ON(!dev->managed.final_kfree);
+
 	if (drm_dev_needs_global_mutex(dev))
 		mutex_lock(&drm_global_mutex);
 
@@ -1046,8 +1015,8 @@ EXPORT_SYMBOL(drm_dev_unregister);
  */
 int drm_dev_set_unique(struct drm_device *dev, const char *name)
 {
-	kfree(dev->unique);
-	dev->unique = kstrdup(name, GFP_KERNEL);
+	drmm_kfree(dev, dev->unique);
+	dev->unique = drmm_kstrdup(dev, name, GFP_KERNEL);
 
 	return dev->unique ? 0 : -ENOMEM;
 }
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 116451101426..43b6ca364daa 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1583,8 +1583,6 @@ module_param_named(edid_fixup, edid_fixup, int, 0400);
 MODULE_PARM_DESC(edid_fixup,
 		 "Minimum number of valid EDID header bytes (0-8, default 6)");
 
-static void drm_get_displayid(struct drm_connector *connector,
-			      struct edid *edid);
 static int validate_displayid(u8 *displayid, int length, int idx);
 
 static int drm_edid_block_checksum(const u8 *raw_edid)
@@ -2018,18 +2016,13 @@ EXPORT_SYMBOL(drm_probe_ddc);
 struct edid *drm_get_edid(struct drm_connector *connector,
 			  struct i2c_adapter *adapter)
 {
-	struct edid *edid;
-
 	if (connector->force == DRM_FORCE_OFF)
 		return NULL;
 
 	if (connector->force == DRM_FORCE_UNSPECIFIED && !drm_probe_ddc(adapter))
 		return NULL;
 
-	edid = drm_do_get_edid(connector, drm_do_probe_ddc_edid, adapter);
-	if (edid)
-		drm_get_displayid(connector, edid);
-	return edid;
+	return drm_do_get_edid(connector, drm_do_probe_ddc_edid, adapter);
 }
 EXPORT_SYMBOL(drm_get_edid);
 
@@ -3212,16 +3205,33 @@ static u8 *drm_find_edid_extension(const struct edid *edid, int ext_id)
 }
 
 
-static u8 *drm_find_displayid_extension(const struct edid *edid)
+static u8 *drm_find_displayid_extension(const struct edid *edid,
+					int *length, int *idx)
 {
-	return drm_find_edid_extension(edid, DISPLAYID_EXT);
+	u8 *displayid = drm_find_edid_extension(edid, DISPLAYID_EXT);
+	struct displayid_hdr *base;
+	int ret;
+
+	if (!displayid)
+		return NULL;
+
+	/* EDID extensions block checksum isn't for us */
+	*length = EDID_LENGTH - 1;
+	*idx = 1;
+
+	ret = validate_displayid(displayid, *length, *idx);
+	if (ret)
+		return NULL;
+
+	base = (struct displayid_hdr *)&displayid[*idx];
+	*length = *idx + sizeof(*base) + base->bytes;
+
+	return displayid;
 }
 
 static u8 *drm_find_cea_extension(const struct edid *edid)
 {
-	int ret;
-	int idx = 1;
-	int length = EDID_LENGTH;
+	int length, idx;
 	struct displayid_block *block;
 	u8 *cea;
 	u8 *displayid;
@@ -3232,14 +3242,10 @@ static u8 *drm_find_cea_extension(const struct edid *edid)
 		return cea;
 
 	/* CEA blocks can also be found embedded in a DisplayID block */
-	displayid = drm_find_displayid_extension(edid);
+	displayid = drm_find_displayid_extension(edid, &length, &idx);
 	if (!displayid)
 		return NULL;
 
-	ret = validate_displayid(displayid, length, idx);
-	if (ret)
-		return NULL;
-
 	idx += sizeof(struct displayid_hdr);
 	for_each_displayid_db(displayid, block, idx, length) {
 		if (block->tag == DATA_BLOCK_CTA) {
@@ -5084,7 +5090,7 @@ u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edi
 
 static int validate_displayid(u8 *displayid, int length, int idx)
 {
-	int i;
+	int i, dispid_length;
 	u8 csum = 0;
 	struct displayid_hdr *base;
 
@@ -5093,15 +5099,18 @@ static int validate_displayid(u8 *displayid, int length, int idx)
 	DRM_DEBUG_KMS("base revision 0x%x, length %d, %d %d\n",
 		      base->rev, base->bytes, base->prod_id, base->ext_count);
 
-	if (base->bytes + 5 > length - idx)
+	/* +1 for DispID checksum */
+	dispid_length = sizeof(*base) + base->bytes + 1;
+	if (dispid_length > length - idx)
 		return -EINVAL;
-	for (i = idx; i <= base->bytes + 5; i++) {
-		csum += displayid[i];
-	}
+
+	for (i = 0; i < dispid_length; i++)
+		csum += displayid[idx + i];
 	if (csum) {
 		DRM_NOTE("DisplayID checksum invalid, remainder is %d\n", csum);
 		return -EINVAL;
 	}
+
 	return 0;
 }
 
@@ -5180,20 +5189,14 @@ static int add_displayid_detailed_modes(struct drm_connector *connector,
 					struct edid *edid)
 {
 	u8 *displayid;
-	int ret;
-	int idx = 1;
-	int length = EDID_LENGTH;
+	int length, idx;
 	struct displayid_block *block;
 	int num_modes = 0;
 
-	displayid = drm_find_displayid_extension(edid);
+	displayid = drm_find_displayid_extension(edid, &length, &idx);
 	if (!displayid)
 		return 0;
 
-	ret = validate_displayid(displayid, length, idx);
-	if (ret)
-		return 0;
-
 	idx += sizeof(struct displayid_hdr);
 	for_each_displayid_db(displayid, block, idx, length) {
 		switch (block->tag) {
@@ -5782,9 +5785,9 @@ drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame,
 EXPORT_SYMBOL(drm_hdmi_vendor_infoframe_from_display_mode);
 
 static int drm_parse_tiled_block(struct drm_connector *connector,
-				 struct displayid_block *block)
+				 const struct displayid_block *block)
 {
-	struct displayid_tiled_block *tile = (struct displayid_tiled_block *)block;
+	const struct displayid_tiled_block *tile = (struct displayid_tiled_block *)block;
 	u16 w, h;
 	u8 tile_v_loc, tile_h_loc;
 	u8 num_v_tile, num_h_tile;
@@ -5835,22 +5838,12 @@ static int drm_parse_tiled_block(struct drm_connector *connector,
 	return 0;
 }
 
-static int drm_parse_display_id(struct drm_connector *connector,
-				u8 *displayid, int length,
-				bool is_edid_extension)
+static int drm_displayid_parse_tiled(struct drm_connector *connector,
+				     const u8 *displayid, int length, int idx)
 {
-	/* if this is an EDID extension the first byte will be 0x70 */
-	int idx = 0;
-	struct displayid_block *block;
+	const struct displayid_block *block;
 	int ret;
 
-	if (is_edid_extension)
-		idx = 1;
-
-	ret = validate_displayid(displayid, length, idx);
-	if (ret)
-		return ret;
-
 	idx += sizeof(struct displayid_hdr);
 	for_each_displayid_db(displayid, block, idx, length) {
 		DRM_DEBUG_KMS("block id 0x%x, rev %d, len %d\n",
@@ -5862,12 +5855,6 @@ static int drm_parse_display_id(struct drm_connector *connector,
 			if (ret)
 				return ret;
 			break;
-		case DATA_BLOCK_TYPE_1_DETAILED_TIMING:
-			/* handled in mode gathering code. */
-			break;
-		case DATA_BLOCK_CTA:
-			/* handled in the cea parser code. */
-			break;
 		default:
 			DRM_DEBUG_KMS("found DisplayID tag 0x%x, unhandled\n", block->tag);
 			break;
@@ -5876,19 +5863,21 @@ static int drm_parse_display_id(struct drm_connector *connector,
 	return 0;
 }
 
-static void drm_get_displayid(struct drm_connector *connector,
-			      struct edid *edid)
+void drm_update_tile_info(struct drm_connector *connector,
+			  const struct edid *edid)
 {
-	void *displayid = NULL;
+	const void *displayid = NULL;
+	int length, idx;
 	int ret;
+
 	connector->has_tile = false;
-	displayid = drm_find_displayid_extension(edid);
+	displayid = drm_find_displayid_extension(edid, &length, &idx);
 	if (!displayid) {
 		/* drop reference to any tile group we had */
 		goto out_drop_ref;
 	}
 
-	ret = drm_parse_display_id(connector, displayid, EDID_LENGTH, true);
+	ret = drm_displayid_parse_tiled(connector, displayid, length, idx);
 	if (ret < 0)
 		goto out_drop_ref;
 	if (!connector->has_tile)
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index a9771de4d17e..02fc24026872 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -514,6 +514,14 @@ struct fb_info *drm_fb_helper_alloc_fbi(struct drm_fb_helper *fb_helper)
 	if (ret)
 		goto err_release;
 
+	/*
+	 * TODO: We really should be smarter here and alloc an apperture
+	 * for each IORESOURCE_MEM resource helper->dev->dev has and also
+	 * init the ranges of the appertures based on the resources.
+	 * Note some drivers currently count on there being only 1 empty
+	 * aperture and fill this themselves, these will need to be dealt
+	 * with somehow when fixing this.
+	 */
 	info->apertures = alloc_apertures(1);
 	if (!info->apertures) {
 		ret = -ENOMEM;
@@ -2162,6 +2170,8 @@ static const struct drm_client_funcs drm_fbdev_client_funcs = {
  *
  * This function sets up generic fbdev emulation for drivers that supports
  * dumb buffers with a virtual address and that can be mmap'ed.
+ * drm_fbdev_generic_setup() shall be called after the DRM driver registered
+ * the new DRM device with drm_dev_register().
  *
  * Restore, hotplug events and teardown are all taken care of. Drivers that do
  * suspend/resume need to call drm_fb_helper_set_suspend_unlocked() themselves.
@@ -2178,29 +2188,30 @@ static const struct drm_client_funcs drm_fbdev_client_funcs = {
  * Setup will be retried on the next hotplug event.
  *
  * The fbdev is destroyed by drm_dev_unregister().
- *
- * Returns:
- * Zero on success or negative error code on failure.
  */
-int drm_fbdev_generic_setup(struct drm_device *dev, unsigned int preferred_bpp)
+void drm_fbdev_generic_setup(struct drm_device *dev,
+			     unsigned int preferred_bpp)
 {
 	struct drm_fb_helper *fb_helper;
 	int ret;
 
-	WARN(dev->fb_helper, "fb_helper is already set!\n");
+	drm_WARN(dev, !dev->registered, "Device has not been registered.\n");
+	drm_WARN(dev, dev->fb_helper, "fb_helper is already set!\n");
 
 	if (!drm_fbdev_emulation)
-		return 0;
+		return;
 
 	fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL);
-	if (!fb_helper)
-		return -ENOMEM;
+	if (!fb_helper) {
+		drm_err(dev, "Failed to allocate fb_helper\n");
+		return;
+	}
 
 	ret = drm_client_init(dev, &fb_helper->client, "fbdev", &drm_fbdev_client_funcs);
 	if (ret) {
 		kfree(fb_helper);
 		drm_err(dev, "Failed to register client: %d\n", ret);
-		return ret;
+		return;
 	}
 
 	if (!preferred_bpp)
@@ -2214,8 +2225,6 @@ int drm_fbdev_generic_setup(struct drm_device *dev, unsigned int preferred_bpp)
 		drm_dbg_kms(dev, "client hotplug ret=%d\n", ret);
 
 	drm_client_register(&fb_helper->client);
-
-	return 0;
 }
 EXPORT_SYMBOL(drm_fbdev_generic_setup);
 
diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c
index 57ac94ce9b9e..0375b3d7f8d0 100644
--- a/drivers/gpu/drm/drm_framebuffer.c
+++ b/drivers/gpu/drm/drm_framebuffer.c
@@ -1207,10 +1207,10 @@ static const struct drm_info_list drm_framebuffer_debugfs_list[] = {
 	{ "framebuffer", drm_framebuffer_info, 0 },
 };
 
-int drm_framebuffer_debugfs_init(struct drm_minor *minor)
+void drm_framebuffer_debugfs_init(struct drm_minor *minor)
 {
-	return drm_debugfs_create_files(drm_framebuffer_debugfs_list,
-				ARRAY_SIZE(drm_framebuffer_debugfs_list),
-				minor->debugfs_root, minor);
+	drm_debugfs_create_files(drm_framebuffer_debugfs_list,
+				 ARRAY_SIZE(drm_framebuffer_debugfs_list),
+				 minor->debugfs_root, minor);
 }
 #endif
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 37627d06fb06..7bf628e13023 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -44,6 +44,7 @@
 #include <drm/drm_drv.h>
 #include <drm/drm_file.h>
 #include <drm/drm_gem.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_print.h>
 #include <drm/drm_vma_manager.h>
 
@@ -77,6 +78,12 @@
  * up at a later date, and as our interface with shmfs for memory allocation.
  */
 
+static void
+drm_gem_init_release(struct drm_device *dev, void *ptr)
+{
+	drm_vma_offset_manager_destroy(dev->vma_offset_manager);
+}
+
 /**
  * drm_gem_init - Initialize the GEM device fields
  * @dev: drm_devic structure to initialize
@@ -89,7 +96,8 @@ drm_gem_init(struct drm_device *dev)
 	mutex_init(&dev->object_name_lock);
 	idr_init_base(&dev->object_name_idr, 1);
 
-	vma_offset_manager = kzalloc(sizeof(*vma_offset_manager), GFP_KERNEL);
+	vma_offset_manager = drmm_kzalloc(dev, sizeof(*vma_offset_manager),
+					  GFP_KERNEL);
 	if (!vma_offset_manager) {
 		DRM_ERROR("out of memory\n");
 		return -ENOMEM;
@@ -100,16 +108,7 @@ drm_gem_init(struct drm_device *dev)
 				    DRM_FILE_PAGE_OFFSET_START,
 				    DRM_FILE_PAGE_OFFSET_SIZE);
 
-	return 0;
-}
-
-void
-drm_gem_destroy(struct drm_device *dev)
-{
-
-	drm_vma_offset_manager_destroy(dev->vma_offset_manager);
-	kfree(dev->vma_offset_manager);
-	dev->vma_offset_manager = NULL;
+	return drmm_add_action(dev, drm_gem_init_release, NULL);
 }
 
 /**
@@ -432,7 +431,7 @@ drm_gem_handle_create_tail(struct drm_file *file_priv,
  * drm_gem_handle_create - create a gem handle for an object
  * @file_priv: drm file-private structure to register the handle for
  * @obj: object to register
- * @handlep: pionter to return the created handle to the caller
+ * @handlep: pointer to return the created handle to the caller
  *
  * Create a handle for this object. This adds a handle reference to the object,
  * which includes a regular reference count. Callers will likely want to
diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
index 3a7ace19a902..ccc2c71fa491 100644
--- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c
+++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
@@ -21,6 +21,13 @@
 #include <drm/drm_modeset_helper.h>
 #include <drm/drm_simple_kms_helper.h>
 
+#define AFBC_HEADER_SIZE		16
+#define AFBC_TH_LAYOUT_ALIGNMENT	8
+#define AFBC_HDR_ALIGN			64
+#define AFBC_SUPERBLOCK_PIXELS		256
+#define AFBC_SUPERBLOCK_ALIGNMENT	128
+#define AFBC_TH_BODY_START_ALIGNMENT	4096
+
 /**
  * DOC: overview
  *
@@ -54,32 +61,25 @@ struct drm_gem_object *drm_gem_fb_get_obj(struct drm_framebuffer *fb,
 }
 EXPORT_SYMBOL_GPL(drm_gem_fb_get_obj);
 
-static struct drm_framebuffer *
-drm_gem_fb_alloc(struct drm_device *dev,
+static int
+drm_gem_fb_init(struct drm_device *dev,
+		 struct drm_framebuffer *fb,
 		 const struct drm_mode_fb_cmd2 *mode_cmd,
 		 struct drm_gem_object **obj, unsigned int num_planes,
 		 const struct drm_framebuffer_funcs *funcs)
 {
-	struct drm_framebuffer *fb;
 	int ret, i;
 
-	fb = kzalloc(sizeof(*fb), GFP_KERNEL);
-	if (!fb)
-		return ERR_PTR(-ENOMEM);
-
 	drm_helper_mode_fill_fb_struct(dev, fb, mode_cmd);
 
 	for (i = 0; i < num_planes; i++)
 		fb->obj[i] = obj[i];
 
 	ret = drm_framebuffer_init(dev, fb, funcs);
-	if (ret) {
+	if (ret)
 		drm_err(dev, "Failed to init framebuffer: %d\n", ret);
-		kfree(fb);
-		return ERR_PTR(ret);
-	}
 
-	return fb;
+	return ret;
 }
 
 /**
@@ -123,10 +123,13 @@ int drm_gem_fb_create_handle(struct drm_framebuffer *fb, struct drm_file *file,
 EXPORT_SYMBOL(drm_gem_fb_create_handle);
 
 /**
- * drm_gem_fb_create_with_funcs() - Helper function for the
- *                                  &drm_mode_config_funcs.fb_create
- *                                  callback
+ * drm_gem_fb_init_with_funcs() - Helper function for implementing
+ *				  &drm_mode_config_funcs.fb_create
+ *				  callback in cases when the driver
+ *				  allocates a subclass of
+ *				  struct drm_framebuffer
  * @dev: DRM device
+ * @fb: framebuffer object
  * @file: DRM file that holds the GEM handle(s) backing the framebuffer
  * @mode_cmd: Metadata from the userspace framebuffer creation request
  * @funcs: vtable to be used for the new framebuffer object
@@ -134,23 +137,26 @@ EXPORT_SYMBOL(drm_gem_fb_create_handle);
  * This function can be used to set &drm_framebuffer_funcs for drivers that need
  * custom framebuffer callbacks. Use drm_gem_fb_create() if you don't need to
  * change &drm_framebuffer_funcs. The function does buffer size validation.
+ * The buffer size validation is for a general case, though, so users should
+ * pay attention to the checks being appropriate for them or, at least,
+ * non-conflicting.
  *
  * Returns:
- * Pointer to a &drm_framebuffer on success or an error pointer on failure.
+ * Zero or a negative error code.
  */
-struct drm_framebuffer *
-drm_gem_fb_create_with_funcs(struct drm_device *dev, struct drm_file *file,
-			     const struct drm_mode_fb_cmd2 *mode_cmd,
-			     const struct drm_framebuffer_funcs *funcs)
+int drm_gem_fb_init_with_funcs(struct drm_device *dev,
+			       struct drm_framebuffer *fb,
+			       struct drm_file *file,
+			       const struct drm_mode_fb_cmd2 *mode_cmd,
+			       const struct drm_framebuffer_funcs *funcs)
 {
 	const struct drm_format_info *info;
 	struct drm_gem_object *objs[4];
-	struct drm_framebuffer *fb;
 	int ret, i;
 
 	info = drm_get_format_info(dev, mode_cmd);
 	if (!info)
-		return ERR_PTR(-EINVAL);
+		return -EINVAL;
 
 	for (i = 0; i < info->num_planes; i++) {
 		unsigned int width = mode_cmd->width / (i ? info->hsub : 1);
@@ -175,19 +181,55 @@ drm_gem_fb_create_with_funcs(struct drm_device *dev, struct drm_file *file,
 		}
 	}
 
-	fb = drm_gem_fb_alloc(dev, mode_cmd, objs, i, funcs);
-	if (IS_ERR(fb)) {
-		ret = PTR_ERR(fb);
+	ret = drm_gem_fb_init(dev, fb, mode_cmd, objs, i, funcs);
+	if (ret)
 		goto err_gem_object_put;
-	}
 
-	return fb;
+	return 0;
 
 err_gem_object_put:
 	for (i--; i >= 0; i--)
 		drm_gem_object_put_unlocked(objs[i]);
 
-	return ERR_PTR(ret);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(drm_gem_fb_init_with_funcs);
+
+/**
+ * drm_gem_fb_create_with_funcs() - Helper function for the
+ *                                  &drm_mode_config_funcs.fb_create
+ *                                  callback
+ * @dev: DRM device
+ * @file: DRM file that holds the GEM handle(s) backing the framebuffer
+ * @mode_cmd: Metadata from the userspace framebuffer creation request
+ * @funcs: vtable to be used for the new framebuffer object
+ *
+ * This function can be used to set &drm_framebuffer_funcs for drivers that need
+ * custom framebuffer callbacks. Use drm_gem_fb_create() if you don't need to
+ * change &drm_framebuffer_funcs. The function does buffer size validation.
+ *
+ * Returns:
+ * Pointer to a &drm_framebuffer on success or an error pointer on failure.
+ */
+struct drm_framebuffer *
+drm_gem_fb_create_with_funcs(struct drm_device *dev, struct drm_file *file,
+			     const struct drm_mode_fb_cmd2 *mode_cmd,
+			     const struct drm_framebuffer_funcs *funcs)
+{
+	struct drm_framebuffer *fb;
+	int ret;
+
+	fb = kzalloc(sizeof(*fb), GFP_KERNEL);
+	if (!fb)
+		return ERR_PTR(-ENOMEM);
+
+	ret = drm_gem_fb_init_with_funcs(dev, fb, file, mode_cmd, funcs);
+	if (ret) {
+		kfree(fb);
+		return ERR_PTR(ret);
+	}
+
+	return fb;
 }
 EXPORT_SYMBOL_GPL(drm_gem_fb_create_with_funcs);
 
@@ -265,6 +307,132 @@ drm_gem_fb_create_with_dirty(struct drm_device *dev, struct drm_file *file,
 }
 EXPORT_SYMBOL_GPL(drm_gem_fb_create_with_dirty);
 
+static __u32 drm_gem_afbc_get_bpp(struct drm_device *dev,
+				  const struct drm_mode_fb_cmd2 *mode_cmd)
+{
+	const struct drm_format_info *info;
+
+	info = drm_get_format_info(dev, mode_cmd);
+
+	/* use whatever a driver has set */
+	if (info->cpp[0])
+		return info->cpp[0] * 8;
+
+	/* guess otherwise */
+	switch (info->format) {
+	case DRM_FORMAT_YUV420_8BIT:
+		return 12;
+	case DRM_FORMAT_YUV420_10BIT:
+		return 15;
+	case DRM_FORMAT_VUY101010:
+		return 30;
+	default:
+		break;
+	}
+
+	/* all attempts failed */
+	return 0;
+}
+
+static int drm_gem_afbc_min_size(struct drm_device *dev,
+				 const struct drm_mode_fb_cmd2 *mode_cmd,
+				 struct drm_afbc_framebuffer *afbc_fb)
+{
+	__u32 n_blocks, w_alignment, h_alignment, hdr_alignment;
+	/* remove bpp when all users properly encode cpp in drm_format_info */
+	__u32 bpp;
+
+	switch (mode_cmd->modifier[0] & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK) {
+	case AFBC_FORMAT_MOD_BLOCK_SIZE_16x16:
+		afbc_fb->block_width = 16;
+		afbc_fb->block_height = 16;
+		break;
+	case AFBC_FORMAT_MOD_BLOCK_SIZE_32x8:
+		afbc_fb->block_width = 32;
+		afbc_fb->block_height = 8;
+		break;
+	/* no user exists yet - fall through */
+	case AFBC_FORMAT_MOD_BLOCK_SIZE_64x4:
+	case AFBC_FORMAT_MOD_BLOCK_SIZE_32x8_64x4:
+	default:
+		drm_dbg_kms(dev, "Invalid AFBC_FORMAT_MOD_BLOCK_SIZE: %lld.\n",
+			    mode_cmd->modifier[0]
+			    & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK);
+		return -EINVAL;
+	}
+
+	/* tiled header afbc */
+	w_alignment = afbc_fb->block_width;
+	h_alignment = afbc_fb->block_height;
+	hdr_alignment = AFBC_HDR_ALIGN;
+	if (mode_cmd->modifier[0] & AFBC_FORMAT_MOD_TILED) {
+		w_alignment *= AFBC_TH_LAYOUT_ALIGNMENT;
+		h_alignment *= AFBC_TH_LAYOUT_ALIGNMENT;
+		hdr_alignment = AFBC_TH_BODY_START_ALIGNMENT;
+	}
+
+	afbc_fb->aligned_width = ALIGN(mode_cmd->width, w_alignment);
+	afbc_fb->aligned_height = ALIGN(mode_cmd->height, h_alignment);
+	afbc_fb->offset = mode_cmd->offsets[0];
+
+	bpp = drm_gem_afbc_get_bpp(dev, mode_cmd);
+	if (!bpp) {
+		drm_dbg_kms(dev, "Invalid AFBC bpp value: %d\n", bpp);
+		return -EINVAL;
+	}
+
+	n_blocks = (afbc_fb->aligned_width * afbc_fb->aligned_height)
+		   / AFBC_SUPERBLOCK_PIXELS;
+	afbc_fb->afbc_size = ALIGN(n_blocks * AFBC_HEADER_SIZE, hdr_alignment);
+	afbc_fb->afbc_size += n_blocks * ALIGN(bpp * AFBC_SUPERBLOCK_PIXELS / 8,
+					       AFBC_SUPERBLOCK_ALIGNMENT);
+
+	return 0;
+}
+
+/**
+ * drm_gem_fb_afbc_init() - Helper function for drivers using afbc to
+ *			    fill and validate all the afbc-specific
+ *			    struct drm_afbc_framebuffer members
+ *
+ * @dev: DRM device
+ * @afbc_fb: afbc-specific framebuffer
+ * @mode_cmd: Metadata from the userspace framebuffer creation request
+ * @afbc_fb: afbc framebuffer
+ *
+ * This function can be used by drivers which support afbc to complete
+ * the preparation of struct drm_afbc_framebuffer. It must be called after
+ * allocating the said struct and calling drm_gem_fb_init_with_funcs().
+ * It is caller's responsibility to put afbc_fb->base.obj objects in case
+ * the call is unsuccessful.
+ *
+ * Returns:
+ * Zero on success or a negative error value on failure.
+ */
+int drm_gem_fb_afbc_init(struct drm_device *dev,
+			 const struct drm_mode_fb_cmd2 *mode_cmd,
+			 struct drm_afbc_framebuffer *afbc_fb)
+{
+	const struct drm_format_info *info;
+	struct drm_gem_object **objs;
+	int ret;
+
+	objs = afbc_fb->base.obj;
+	info = drm_get_format_info(dev, mode_cmd);
+	if (!info)
+		return -EINVAL;
+
+	ret = drm_gem_afbc_min_size(dev, mode_cmd, afbc_fb);
+	if (ret < 0)
+		return ret;
+
+	if (objs[0]->size < afbc_fb->afbc_size)
+		return -EINVAL;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(drm_gem_fb_afbc_init);
+
 /**
  * drm_gem_fb_prepare_fb() - Prepare a GEM backed framebuffer
  * @plane: Plane
diff --git a/drivers/gpu/drm/drm_gem_vram_helper.c b/drivers/gpu/drm/drm_gem_vram_helper.c
index 92a11bb42365..8b2d5c945c95 100644
--- a/drivers/gpu/drm/drm_gem_vram_helper.c
+++ b/drivers/gpu/drm/drm_gem_vram_helper.c
@@ -1,10 +1,13 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 
+#include <linux/module.h>
+
 #include <drm/drm_debugfs.h>
 #include <drm/drm_device.h>
 #include <drm/drm_drv.h>
 #include <drm/drm_file.h>
 #include <drm/drm_framebuffer.h>
+#include <drm/drm_gem_framebuffer_helper.h>
 #include <drm/drm_gem_ttm_helper.h>
 #include <drm/drm_gem_vram_helper.h>
 #include <drm/drm_mode.h>
@@ -18,13 +21,93 @@ static const struct drm_gem_object_funcs drm_gem_vram_object_funcs;
 /**
  * DOC: overview
  *
- * This library provides a GEM buffer object that is backed by video RAM
- * (VRAM). It can be used for framebuffer devices with dedicated memory.
+ * This library provides &struct drm_gem_vram_object (GEM VRAM), a GEM
+ * buffer object that is backed by video RAM (VRAM). It can be used for
+ * framebuffer devices with dedicated memory.
  *
  * The data structure &struct drm_vram_mm and its helpers implement a memory
- * manager for simple framebuffer devices with dedicated video memory. Buffer
- * objects are either placed in video RAM or evicted to system memory. The rsp.
- * buffer object is provided by &struct drm_gem_vram_object.
+ * manager for simple framebuffer devices with dedicated video memory. GEM
+ * VRAM buffer objects are either placed in the video memory or remain evicted
+ * to system memory.
+ *
+ * With the GEM interface userspace applications create, manage and destroy
+ * graphics buffers, such as an on-screen framebuffer. GEM does not provide
+ * an implementation of these interfaces. It's up to the DRM driver to
+ * provide an implementation that suits the hardware. If the hardware device
+ * contains dedicated video memory, the DRM driver can use the VRAM helper
+ * library. Each active buffer object is stored in video RAM. Active
+ * buffer are used for drawing the current frame, typically something like
+ * the frame's scanout buffer or the cursor image. If there's no more space
+ * left in VRAM, inactive GEM objects can be moved to system memory.
+ *
+ * The easiest way to use the VRAM helper library is to call
+ * drm_vram_helper_alloc_mm(). The function allocates and initializes an
+ * instance of &struct drm_vram_mm in &struct drm_device.vram_mm . Use
+ * &DRM_GEM_VRAM_DRIVER to initialize &struct drm_driver and
+ * &DRM_VRAM_MM_FILE_OPERATIONS to initialize &struct file_operations;
+ * as illustrated below.
+ *
+ * .. code-block:: c
+ *
+ *	struct file_operations fops ={
+ *		.owner = THIS_MODULE,
+ *		DRM_VRAM_MM_FILE_OPERATION
+ *	};
+ *	struct drm_driver drv = {
+ *		.driver_feature = DRM_ ... ,
+ *		.fops = &fops,
+ *		DRM_GEM_VRAM_DRIVER
+ *	};
+ *
+ *	int init_drm_driver()
+ *	{
+ *		struct drm_device *dev;
+ *		uint64_t vram_base;
+ *		unsigned long vram_size;
+ *		int ret;
+ *
+ *		// setup device, vram base and size
+ *		// ...
+ *
+ *		ret = drm_vram_helper_alloc_mm(dev, vram_base, vram_size);
+ *		if (ret)
+ *			return ret;
+ *		return 0;
+ *	}
+ *
+ * This creates an instance of &struct drm_vram_mm, exports DRM userspace
+ * interfaces for GEM buffer management and initializes file operations to
+ * allow for accessing created GEM buffers. With this setup, the DRM driver
+ * manages an area of video RAM with VRAM MM and provides GEM VRAM objects
+ * to userspace.
+ *
+ * To clean up the VRAM memory management, call drm_vram_helper_release_mm()
+ * in the driver's clean-up code.
+ *
+ * .. code-block:: c
+ *
+ *	void fini_drm_driver()
+ *	{
+ *		struct drm_device *dev = ...;
+ *
+ *		drm_vram_helper_release_mm(dev);
+ *	}
+ *
+ * For drawing or scanout operations, buffer object have to be pinned in video
+ * RAM. Call drm_gem_vram_pin() with &DRM_GEM_VRAM_PL_FLAG_VRAM or
+ * &DRM_GEM_VRAM_PL_FLAG_SYSTEM to pin a buffer object in video RAM or system
+ * memory. Call drm_gem_vram_unpin() to release the pinned object afterwards.
+ *
+ * A buffer object that is pinned in video RAM has a fixed address within that
+ * memory region. Call drm_gem_vram_offset() to retrieve this value. Typically
+ * it's used to program the hardware's scanout engine for framebuffers, set
+ * the cursor overlay's image for a mouse cursor, or use it as input to the
+ * hardware's draing engine.
+ *
+ * To access a buffer object's memory from the DRM driver, call
+ * drm_gem_vram_kmap(). It (optionally) maps the buffer into kernel address
+ * space and returns the memory address. Use drm_gem_vram_kunmap() to
+ * release the mapping.
  */
 
 /*
@@ -670,9 +753,9 @@ EXPORT_SYMBOL(drm_gem_vram_driver_dumb_mmap_offset);
  * @plane:	a DRM plane
  * @new_state:	the plane's new state
  *
- * During plane updates, this function pins the GEM VRAM
- * objects of the plane's new framebuffer to VRAM. Call
- * drm_gem_vram_plane_helper_cleanup_fb() to unpin them.
+ * During plane updates, this function sets the plane's fence and
+ * pins the GEM VRAM objects of the plane's new framebuffer to VRAM.
+ * Call drm_gem_vram_plane_helper_cleanup_fb() to unpin them.
  *
  * Returns:
  *	0 on success, or
@@ -698,6 +781,10 @@ drm_gem_vram_plane_helper_prepare_fb(struct drm_plane *plane,
 			goto err_drm_gem_vram_unpin;
 	}
 
+	ret = drm_gem_fb_prepare_fb(plane, new_state);
+	if (ret)
+		goto err_drm_gem_vram_unpin;
+
 	return 0;
 
 err_drm_gem_vram_unpin:
@@ -1018,7 +1105,6 @@ static struct ttm_bo_driver bo_driver = {
  * struct drm_vram_mm
  */
 
-#if defined(CONFIG_DEBUG_FS)
 static int drm_vram_mm_debugfs(struct seq_file *m, void *data)
 {
 	struct drm_info_node *node = (struct drm_info_node *) m->private;
@@ -1035,27 +1121,18 @@ static int drm_vram_mm_debugfs(struct seq_file *m, void *data)
 static const struct drm_info_list drm_vram_mm_debugfs_list[] = {
 	{ "vram-mm", drm_vram_mm_debugfs, 0, NULL },
 };
-#endif
 
 /**
  * drm_vram_mm_debugfs_init() - Register VRAM MM debugfs file.
  *
  * @minor: drm minor device.
  *
- * Returns:
- * 0 on success, or
- * a negative error code otherwise.
  */
-int drm_vram_mm_debugfs_init(struct drm_minor *minor)
+void drm_vram_mm_debugfs_init(struct drm_minor *minor)
 {
-	int ret = 0;
-
-#if defined(CONFIG_DEBUG_FS)
-	ret = drm_debugfs_create_files(drm_vram_mm_debugfs_list,
-				       ARRAY_SIZE(drm_vram_mm_debugfs_list),
-				       minor->debugfs_root, minor);
-#endif
-	return ret;
+	drm_debugfs_create_files(drm_vram_mm_debugfs_list,
+				 ARRAY_SIZE(drm_vram_mm_debugfs_list),
+				 minor->debugfs_root, minor);
 }
 EXPORT_SYMBOL(drm_vram_mm_debugfs_init);
 
@@ -1202,3 +1279,6 @@ drm_vram_helper_mode_valid(struct drm_device *dev,
 	return drm_vram_helper_mode_valid_internal(dev, mode, max_bpp);
 }
 EXPORT_SYMBOL(drm_vram_helper_mode_valid);
+
+MODULE_DESCRIPTION("DRM VRAM memory-management helpers");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
index 5714a78365ac..2470a352730b 100644
--- a/drivers/gpu/drm/drm_internal.h
+++ b/drivers/gpu/drm/drm_internal.h
@@ -89,9 +89,11 @@ void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private *prime_fpr
 struct drm_minor *drm_minor_acquire(unsigned int minor_id);
 void drm_minor_release(struct drm_minor *minor);
 
+/* drm_managed.c */
+void drm_managed_release(struct drm_device *dev);
+
 /* drm_vblank.c */
 void drm_vblank_disable_and_save(struct drm_device *dev, unsigned int pipe);
-void drm_vblank_cleanup(struct drm_device *dev);
 
 /* IOCTLS */
 int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
@@ -141,7 +143,6 @@ void drm_sysfs_lease_event(struct drm_device *dev);
 /* drm_gem.c */
 struct drm_gem_object;
 int drm_gem_init(struct drm_device *dev);
-void drm_gem_destroy(struct drm_device *dev);
 int drm_gem_handle_create_tail(struct drm_file *file_priv,
 			       struct drm_gem_object *obj,
 			       u32 *handlep);
@@ -235,4 +236,4 @@ int drm_syncobj_query_ioctl(struct drm_device *dev, void *data,
 /* drm_framebuffer.c */
 void drm_framebuffer_print_info(struct drm_printer *p, unsigned int indent,
 				const struct drm_framebuffer *fb);
-int drm_framebuffer_debugfs_init(struct drm_minor *minor);
+void drm_framebuffer_debugfs_init(struct drm_minor *minor);
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 9e41972c4bbc..73e31dd4e442 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -599,8 +599,8 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
 	DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_SET_SAREA_CTX, drm_legacy_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
 	DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_GET_SAREA_CTX, drm_legacy_getsareactx, DRM_AUTH),
 
-	DRM_IOCTL_DEF(DRM_IOCTL_SET_MASTER, drm_setmaster_ioctl, DRM_ROOT_ONLY),
-	DRM_IOCTL_DEF(DRM_IOCTL_DROP_MASTER, drm_dropmaster_ioctl, DRM_ROOT_ONLY),
+	DRM_IOCTL_DEF(DRM_IOCTL_SET_MASTER, drm_setmaster_ioctl, 0),
+	DRM_IOCTL_DEF(DRM_IOCTL_DROP_MASTER, drm_dropmaster_ioctl, 0),
 
 	DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_ADD_CTX, drm_legacy_addctx, DRM_AUTH|DRM_ROOT_ONLY),
 	DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_RM_CTX, drm_legacy_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
diff --git a/drivers/gpu/drm/drm_managed.c b/drivers/gpu/drm/drm_managed.c
new file mode 100644
index 000000000000..9cebfe370a65
--- /dev/null
+++ b/drivers/gpu/drm/drm_managed.c
@@ -0,0 +1,275 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 Intel
+ *
+ * Based on drivers/base/devres.c
+ */
+
+#include <drm/drm_managed.h>
+
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+#include <drm/drm_device.h>
+#include <drm/drm_print.h>
+
+/**
+ * DOC: managed resources
+ *
+ * Inspired by struct &device managed resources, but tied to the lifetime of
+ * struct &drm_device, which can outlive the underlying physical device, usually
+ * when userspace has some open files and other handles to resources still open.
+ *
+ * Release actions can be added with drmm_add_action(), memory allocations can
+ * be done directly with drmm_kmalloc() and the related functions. Everything
+ * will be released on the final drm_dev_put() in reverse order of how the
+ * release actions have been added and memory has been allocated since driver
+ * loading started with drm_dev_init().
+ *
+ * Note that release actions and managed memory can also be added and removed
+ * during the lifetime of the driver, all the functions are fully concurrent
+ * safe. But it is recommended to use managed resources only for resources that
+ * change rarely, if ever, during the lifetime of the &drm_device instance.
+ */
+
+struct drmres_node {
+	struct list_head	entry;
+	drmres_release_t	release;
+	const char		*name;
+	size_t			size;
+};
+
+struct drmres {
+	struct drmres_node		node;
+	/*
+	 * Some archs want to perform DMA into kmalloc caches
+	 * and need a guaranteed alignment larger than
+	 * the alignment of a 64-bit integer.
+	 * Thus we use ARCH_KMALLOC_MINALIGN here and get exactly the same
+	 * buffer alignment as if it was allocated by plain kmalloc().
+	 */
+	u8 __aligned(ARCH_KMALLOC_MINALIGN) data[];
+};
+
+static void free_dr(struct drmres *dr)
+{
+	kfree_const(dr->node.name);
+	kfree(dr);
+}
+
+void drm_managed_release(struct drm_device *dev)
+{
+	struct drmres *dr, *tmp;
+
+	drm_dbg_drmres(dev, "drmres release begin\n");
+	list_for_each_entry_safe(dr, tmp, &dev->managed.resources, node.entry) {
+		drm_dbg_drmres(dev, "REL %p %s (%zu bytes)\n",
+			       dr, dr->node.name, dr->node.size);
+
+		if (dr->node.release)
+			dr->node.release(dev, dr->node.size ? *(void **)&dr->data : NULL);
+
+		list_del(&dr->node.entry);
+		free_dr(dr);
+	}
+	drm_dbg_drmres(dev, "drmres release end\n");
+}
+
+/*
+ * Always inline so that kmalloc_track_caller tracks the actual interesting
+ * caller outside of drm_managed.c.
+ */
+static __always_inline struct drmres * alloc_dr(drmres_release_t release,
+						size_t size, gfp_t gfp, int nid)
+{
+	size_t tot_size;
+	struct drmres *dr;
+
+	/* We must catch any near-SIZE_MAX cases that could overflow. */
+	if (unlikely(check_add_overflow(sizeof(*dr), size, &tot_size)))
+		return NULL;
+
+	dr = kmalloc_node_track_caller(tot_size, gfp, nid);
+	if (unlikely(!dr))
+		return NULL;
+
+	memset(dr, 0, offsetof(struct drmres, data));
+
+	INIT_LIST_HEAD(&dr->node.entry);
+	dr->node.release = release;
+	dr->node.size = size;
+
+	return dr;
+}
+
+static void del_dr(struct drm_device *dev, struct drmres *dr)
+{
+	list_del_init(&dr->node.entry);
+
+	drm_dbg_drmres(dev, "DEL %p %s (%lu bytes)\n",
+		       dr, dr->node.name, (unsigned long) dr->node.size);
+}
+
+static void add_dr(struct drm_device *dev, struct drmres *dr)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev->managed.lock, flags);
+	list_add(&dr->node.entry, &dev->managed.resources);
+	spin_unlock_irqrestore(&dev->managed.lock, flags);
+
+	drm_dbg_drmres(dev, "ADD %p %s (%lu bytes)\n",
+		       dr, dr->node.name, (unsigned long) dr->node.size);
+}
+
+/**
+ * drmm_add_final_kfree - add release action for the final kfree()
+ * @dev: DRM device
+ * @container: pointer to the kmalloc allocation containing @dev
+ *
+ * Since the allocation containing the struct &drm_device must be allocated
+ * before it can be initialized with drm_dev_init() there's no way to allocate
+ * that memory with drmm_kmalloc(). To side-step this chicken-egg problem the
+ * pointer for this final kfree() must be specified by calling this function. It
+ * will be released in the final drm_dev_put() for @dev, after all other release
+ * actions installed through drmm_add_action() have been processed.
+ */
+void drmm_add_final_kfree(struct drm_device *dev, void *container)
+{
+	WARN_ON(dev->managed.final_kfree);
+	WARN_ON(dev < (struct drm_device *) container);
+	WARN_ON(dev + 1 > (struct drm_device *) (container + ksize(container)));
+	dev->managed.final_kfree = container;
+}
+EXPORT_SYMBOL(drmm_add_final_kfree);
+
+int __drmm_add_action(struct drm_device *dev,
+		      drmres_release_t action,
+		      void *data, const char *name)
+{
+	struct drmres *dr;
+	void **void_ptr;
+
+	dr = alloc_dr(action, data ? sizeof(void*) : 0,
+		      GFP_KERNEL | __GFP_ZERO,
+		      dev_to_node(dev->dev));
+	if (!dr) {
+		drm_dbg_drmres(dev, "failed to add action %s for %p\n",
+			       name, data);
+		return -ENOMEM;
+	}
+
+	dr->node.name = kstrdup_const(name, GFP_KERNEL);
+	if (data) {
+		void_ptr = (void **)&dr->data;
+		*void_ptr = data;
+	}
+
+	add_dr(dev, dr);
+
+	return 0;
+}
+EXPORT_SYMBOL(__drmm_add_action);
+
+int __drmm_add_action_or_reset(struct drm_device *dev,
+			       drmres_release_t action,
+			       void *data, const char *name)
+{
+	int ret;
+
+	ret = __drmm_add_action(dev, action, data, name);
+	if (ret)
+		action(dev, data);
+
+	return ret;
+}
+EXPORT_SYMBOL(__drmm_add_action_or_reset);
+
+/**
+ * drmm_kmalloc - &drm_device managed kmalloc()
+ * @dev: DRM device
+ * @size: size of the memory allocation
+ * @gfp: GFP allocation flags
+ *
+ * This is a &drm_device managed version of kmalloc(). The allocated memory is
+ * automatically freed on the final drm_dev_put(). Memory can also be freed
+ * before the final drm_dev_put() by calling drmm_kfree().
+ */
+void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp)
+{
+	struct drmres *dr;
+
+	dr = alloc_dr(NULL, size, gfp, dev_to_node(dev->dev));
+	if (!dr) {
+		drm_dbg_drmres(dev, "failed to allocate %zu bytes, %u flags\n",
+			       size, gfp);
+		return NULL;
+	}
+	dr->node.name = kstrdup_const("kmalloc", GFP_KERNEL);
+
+	add_dr(dev, dr);
+
+	return dr->data;
+}
+EXPORT_SYMBOL(drmm_kmalloc);
+
+/**
+ * drmm_kstrdup - &drm_device managed kstrdup()
+ * @dev: DRM device
+ * @s: 0-terminated string to be duplicated
+ * @gfp: GFP allocation flags
+ *
+ * This is a &drm_device managed version of kstrdup(). The allocated memory is
+ * automatically freed on the final drm_dev_put() and works exactly like a
+ * memory allocation obtained by drmm_kmalloc().
+ */
+char *drmm_kstrdup(struct drm_device *dev, const char *s, gfp_t gfp)
+{
+	size_t size;
+	char *buf;
+
+	if (!s)
+		return NULL;
+
+	size = strlen(s) + 1;
+	buf = drmm_kmalloc(dev, size, gfp);
+	if (buf)
+		memcpy(buf, s, size);
+	return buf;
+}
+EXPORT_SYMBOL_GPL(drmm_kstrdup);
+
+/**
+ * drmm_kfree - &drm_device managed kfree()
+ * @dev: DRM device
+ * @data: memory allocation to be freed
+ *
+ * This is a &drm_device managed version of kfree() which can be used to
+ * release memory allocated through drmm_kmalloc() or any of its related
+ * functions before the final drm_dev_put() of @dev.
+ */
+void drmm_kfree(struct drm_device *dev, void *data)
+{
+	struct drmres *dr_match = NULL, *dr;
+	unsigned long flags;
+
+	if (!data)
+		return;
+
+	spin_lock_irqsave(&dev->managed.lock, flags);
+	list_for_each_entry(dr, &dev->managed.resources, node.entry) {
+		if (dr->data == data) {
+			dr_match = dr;
+			del_dr(dev, dr_match);
+			break;
+		}
+	}
+	spin_unlock_irqrestore(&dev->managed.lock, flags);
+
+	if (WARN_ON(!dr_match))
+		return;
+
+	free_dr(dr_match);
+}
+EXPORT_SYMBOL(drmm_kfree);
diff --git a/drivers/gpu/drm/drm_mipi_dbi.c b/drivers/gpu/drm/drm_mipi_dbi.c
index 558baf989f5a..bb27c82757f1 100644
--- a/drivers/gpu/drm/drm_mipi_dbi.c
+++ b/drivers/gpu/drm/drm_mipi_dbi.c
@@ -169,7 +169,8 @@ int mipi_dbi_command_buf(struct mipi_dbi *dbi, u8 cmd, u8 *data, size_t len)
 EXPORT_SYMBOL(mipi_dbi_command_buf);
 
 /* This should only be used by mipi_dbi_command() */
-int mipi_dbi_command_stackbuf(struct mipi_dbi *dbi, u8 cmd, u8 *data, size_t len)
+int mipi_dbi_command_stackbuf(struct mipi_dbi *dbi, u8 cmd, const u8 *data,
+			      size_t len)
 {
 	u8 *buf;
 	int ret;
@@ -510,6 +511,10 @@ int mipi_dbi_dev_init_with_formats(struct mipi_dbi_dev *dbidev,
 	if (!dbidev->dbi.command)
 		return -EINVAL;
 
+	ret = drmm_mode_config_init(drm);
+	if (ret)
+		return ret;
+
 	dbidev->tx_buf = devm_kmalloc(drm->dev, tx_buf_size, GFP_KERNEL);
 	if (!dbidev->tx_buf)
 		return -ENOMEM;
@@ -578,26 +583,6 @@ int mipi_dbi_dev_init(struct mipi_dbi_dev *dbidev,
 }
 EXPORT_SYMBOL(mipi_dbi_dev_init);
 
-/**
- * mipi_dbi_release - DRM driver release helper
- * @drm: DRM device
- *
- * This function finalizes and frees &mipi_dbi.
- *
- * Drivers can use this as their &drm_driver->release callback.
- */
-void mipi_dbi_release(struct drm_device *drm)
-{
-	struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(drm);
-
-	DRM_DEBUG_DRIVER("\n");
-
-	drm_mode_config_cleanup(drm);
-	drm_dev_fini(drm);
-	kfree(dbidev);
-}
-EXPORT_SYMBOL(mipi_dbi_release);
-
 /**
  * mipi_dbi_hw_reset - Hardware reset of controller
  * @dbi: MIPI DBI structure
@@ -1308,10 +1293,8 @@ static const struct file_operations mipi_dbi_debugfs_command_fops = {
  * controller or getting the read command values.
  * Drivers can use this as their &drm_driver->debugfs_init callback.
  *
- * Returns:
- * Zero on success, negative error code on failure.
  */
-int mipi_dbi_debugfs_init(struct drm_minor *minor)
+void mipi_dbi_debugfs_init(struct drm_minor *minor)
 {
 	struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(minor->dev);
 	umode_t mode = S_IFREG | S_IWUSR;
@@ -1320,8 +1303,6 @@ int mipi_dbi_debugfs_init(struct drm_minor *minor)
 		mode |= S_IRUGO;
 	debugfs_create_file("command", mode, minor->debugfs_root, dbidev,
 			    &mipi_dbi_debugfs_command_fops);
-
-	return 0;
 }
 EXPORT_SYMBOL(mipi_dbi_debugfs_init);
 
diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
index 08e6eff6a179..5761f838a057 100644
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -25,6 +25,7 @@
 #include <drm/drm_drv.h>
 #include <drm/drm_encoder.h>
 #include <drm/drm_file.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_mode_config.h>
 #include <drm/drm_print.h>
 #include <linux/dma-resv.h>
@@ -373,8 +374,14 @@ static int drm_mode_create_standard_properties(struct drm_device *dev)
 	return 0;
 }
 
+static void drm_mode_config_init_release(struct drm_device *dev, void *ptr)
+{
+	drm_mode_config_cleanup(dev);
+}
+
 /**
- * drm_mode_config_init - initialize DRM mode_configuration structure
+ * drmm_mode_config_init - managed DRM mode_configuration structure
+ * 	initialization
  * @dev: DRM device
  *
  * Initialize @dev's mode_config structure, used for tracking the graphics
@@ -384,8 +391,12 @@ static int drm_mode_create_standard_properties(struct drm_device *dev)
  * problem, since this should happen single threaded at init time. It is the
  * driver's problem to ensure this guarantee.
  *
+ * Cleanup is automatically handled through registering drm_mode_config_cleanup
+ * with drmm_add_action().
+ *
+ * Returns: 0 on success, negative error value on failure.
  */
-void drm_mode_config_init(struct drm_device *dev)
+int drmm_mode_config_init(struct drm_device *dev)
 {
 	mutex_init(&dev->mode_config.mutex);
 	drm_modeset_lock_init(&dev->mode_config.connection_mutex);
@@ -443,8 +454,11 @@ void drm_mode_config_init(struct drm_device *dev)
 		drm_modeset_acquire_fini(&modeset_ctx);
 		dma_resv_fini(&resv);
 	}
+
+	return drmm_add_action_or_reset(dev, drm_mode_config_init_release,
+					NULL);
 }
-EXPORT_SYMBOL(drm_mode_config_init);
+EXPORT_SYMBOL(drmm_mode_config_init);
 
 /**
  * drm_mode_config_cleanup - free up DRM mode_config info
@@ -456,6 +470,9 @@ EXPORT_SYMBOL(drm_mode_config_init);
  * Note that since this /should/ happen single-threaded at driver/device
  * teardown time, no locking is required. It's the driver's job to ensure that
  * this guarantee actually holds true.
+ *
+ * FIXME: With the managed drmm_mode_config_init() it is no longer necessary for
+ * drivers to explicitly call this function.
  */
 void drm_mode_config_cleanup(struct drm_device *dev)
 {
@@ -532,3 +549,90 @@ void drm_mode_config_cleanup(struct drm_device *dev)
 	drm_modeset_lock_fini(&dev->mode_config.connection_mutex);
 }
 EXPORT_SYMBOL(drm_mode_config_cleanup);
+
+static u32 full_encoder_mask(struct drm_device *dev)
+{
+	struct drm_encoder *encoder;
+	u32 encoder_mask = 0;
+
+	drm_for_each_encoder(encoder, dev)
+		encoder_mask |= drm_encoder_mask(encoder);
+
+	return encoder_mask;
+}
+
+/*
+ * For some reason we want the encoder itself included in
+ * possible_clones. Make life easy for drivers by allowing them
+ * to leave possible_clones unset if no cloning is possible.
+ */
+static void fixup_encoder_possible_clones(struct drm_encoder *encoder)
+{
+	if (encoder->possible_clones == 0)
+		encoder->possible_clones = drm_encoder_mask(encoder);
+}
+
+static void validate_encoder_possible_clones(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	u32 encoder_mask = full_encoder_mask(dev);
+	struct drm_encoder *other;
+
+	drm_for_each_encoder(other, dev) {
+		WARN(!!(encoder->possible_clones & drm_encoder_mask(other)) !=
+		     !!(other->possible_clones & drm_encoder_mask(encoder)),
+		     "possible_clones mismatch: "
+		     "[ENCODER:%d:%s] mask=0x%x possible_clones=0x%x vs. "
+		     "[ENCODER:%d:%s] mask=0x%x possible_clones=0x%x\n",
+		     encoder->base.id, encoder->name,
+		     drm_encoder_mask(encoder), encoder->possible_clones,
+		     other->base.id, other->name,
+		     drm_encoder_mask(other), other->possible_clones);
+	}
+
+	WARN((encoder->possible_clones & drm_encoder_mask(encoder)) == 0 ||
+	     (encoder->possible_clones & ~encoder_mask) != 0,
+	     "Bogus possible_clones: "
+	     "[ENCODER:%d:%s] possible_clones=0x%x (full encoder mask=0x%x)\n",
+	     encoder->base.id, encoder->name,
+	     encoder->possible_clones, encoder_mask);
+}
+
+static u32 full_crtc_mask(struct drm_device *dev)
+{
+	struct drm_crtc *crtc;
+	u32 crtc_mask = 0;
+
+	drm_for_each_crtc(crtc, dev)
+		crtc_mask |= drm_crtc_mask(crtc);
+
+	return crtc_mask;
+}
+
+static void validate_encoder_possible_crtcs(struct drm_encoder *encoder)
+{
+	u32 crtc_mask = full_crtc_mask(encoder->dev);
+
+	WARN((encoder->possible_crtcs & crtc_mask) == 0 ||
+	     (encoder->possible_crtcs & ~crtc_mask) != 0,
+	     "Bogus possible_crtcs: "
+	     "[ENCODER:%d:%s] possible_crtcs=0x%x (full crtc mask=0x%x)\n",
+	     encoder->base.id, encoder->name,
+	     encoder->possible_crtcs, crtc_mask);
+}
+
+void drm_mode_config_validate(struct drm_device *dev)
+{
+	struct drm_encoder *encoder;
+
+	if (!drm_core_check_feature(dev, DRIVER_MODESET))
+		return;
+
+	drm_for_each_encoder(encoder, dev)
+		fixup_encoder_possible_clones(encoder);
+
+	drm_for_each_encoder(encoder, dev) {
+		validate_encoder_possible_clones(encoder);
+		validate_encoder_possible_crtcs(encoder);
+	}
+}
diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c
index 81aa21561982..75e2b7053f35 100644
--- a/drivers/gpu/drm/drm_pci.c
+++ b/drivers/gpu/drm/drm_pci.c
@@ -30,12 +30,13 @@
 #include <drm/drm.h>
 #include <drm/drm_agpsupport.h>
 #include <drm/drm_drv.h>
-#include <drm/drm_pci.h>
 #include <drm/drm_print.h>
 
 #include "drm_internal.h"
 #include "drm_legacy.h"
 
+#ifdef CONFIG_DRM_LEGACY
+
 /**
  * drm_pci_alloc - Allocate a PCI consistent memory block, for DMA.
  * @dev: DRM device
@@ -93,6 +94,7 @@ void drm_pci_free(struct drm_device * dev, drm_dma_handle_t * dmah)
 }
 
 EXPORT_SYMBOL(drm_pci_free);
+#endif
 
 static int drm_get_pci_domain(struct drm_device *dev)
 {
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index da7b0b0c1090..758bf74e1cab 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -30,6 +30,7 @@
 #include <drm/drm_crtc.h>
 #include <drm/drm_drv.h>
 #include <drm/drm_framebuffer.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_modeset_helper_vtables.h>
 #include <drm/drm_print.h>
 #include <drm/drm_vblank.h>
@@ -40,6 +41,69 @@
 /**
  * DOC: vblank handling
  *
+ * From the computer's perspective, every time the monitor displays
+ * a new frame the scanout engine has "scanned out" the display image
+ * from top to bottom, one row of pixels at a time. The current row
+ * of pixels is referred to as the current scanline.
+ *
+ * In addition to the display's visible area, there's usually a couple of
+ * extra scanlines which aren't actually displayed on the screen.
+ * These extra scanlines don't contain image data and are occasionally used
+ * for features like audio and infoframes. The region made up of these
+ * scanlines is referred to as the vertical blanking region, or vblank for
+ * short.
+ *
+ * For historical reference, the vertical blanking period was designed to
+ * give the electron gun (on CRTs) enough time to move back to the top of
+ * the screen to start scanning out the next frame. Similar for horizontal
+ * blanking periods. They were designed to give the electron gun enough
+ * time to move back to the other side of the screen to start scanning the
+ * next scanline.
+ *
+ * ::
+ *
+ *
+ *    physical →   ⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽
+ *    top of      |                                        |
+ *    display     |                                        |
+ *                |               New frame                |
+ *                |                                        |
+ *                |↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓|
+ *                |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| ← Scanline,
+ *                |↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓|   updates the
+ *                |                                        |   frame as it
+ *                |                                        |   travels down
+ *                |                                        |   ("sacn out")
+ *                |               Old frame                |
+ *                |                                        |
+ *                |                                        |
+ *                |                                        |
+ *                |                                        |   physical
+ *                |                                        |   bottom of
+ *    vertical    |⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽| ← display
+ *    blanking    ┆xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx┆
+ *    region   →  ┆xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx┆
+ *                ┆xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx┆
+ *    start of →   ⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽
+ *    new frame
+ *
+ * "Physical top of display" is the reference point for the high-precision/
+ * corrected timestamp.
+ *
+ * On a lot of display hardware, programming needs to take effect during the
+ * vertical blanking period so that settings like gamma, the image buffer
+ * buffer to be scanned out, etc. can safely be changed without showing
+ * any visual artifacts on the screen. In some unforgiving hardware, some of
+ * this programming has to both start and end in the same vblank. To help
+ * with the timing of the hardware programming, an interrupt is usually
+ * available to notify the driver when it can start the updating of registers.
+ * The interrupt is in this context named the vblank interrupt.
+ *
+ * The vblank interrupt may be fired at different points depending on the
+ * hardware. Some hardware implementations will fire the interrupt when the
+ * new frame start, other implementations will fire the interrupt at different
+ * points in time.
+ *
  * Vertical blanking plays a major role in graphics rendering. To achieve
  * tear-free display, users must synchronize page flips and/or rendering to
  * vertical blanking. The DRM API offers ioctls to perform page flips
@@ -425,14 +489,10 @@ static void vblank_disable_fn(struct timer_list *t)
 	spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
 }
 
-void drm_vblank_cleanup(struct drm_device *dev)
+static void drm_vblank_init_release(struct drm_device *dev, void *ptr)
 {
 	unsigned int pipe;
 
-	/* Bail if the driver didn't call drm_vblank_init() */
-	if (dev->num_crtcs == 0)
-		return;
-
 	for (pipe = 0; pipe < dev->num_crtcs; pipe++) {
 		struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
 
@@ -441,10 +501,6 @@ void drm_vblank_cleanup(struct drm_device *dev)
 
 		del_timer_sync(&vblank->disable_timer);
 	}
-
-	kfree(dev->vblank);
-
-	dev->num_crtcs = 0;
 }
 
 /**
@@ -453,25 +509,29 @@ void drm_vblank_cleanup(struct drm_device *dev)
  * @num_crtcs: number of CRTCs supported by @dev
  *
  * This function initializes vblank support for @num_crtcs display pipelines.
- * Cleanup is handled by the DRM core, or through calling drm_dev_fini() for
- * drivers with a &drm_driver.release callback.
+ * Cleanup is handled automatically through a cleanup function added with
+ * drmm_add_action().
  *
  * Returns:
  * Zero on success or a negative error code on failure.
  */
 int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs)
 {
-	int ret = -ENOMEM;
+	int ret;
 	unsigned int i;
 
 	spin_lock_init(&dev->vbl_lock);
 	spin_lock_init(&dev->vblank_time_lock);
 
+	dev->vblank = drmm_kcalloc(dev, num_crtcs, sizeof(*dev->vblank), GFP_KERNEL);
+	if (!dev->vblank)
+		return -ENOMEM;
+
 	dev->num_crtcs = num_crtcs;
 
-	dev->vblank = kcalloc(num_crtcs, sizeof(*dev->vblank), GFP_KERNEL);
-	if (!dev->vblank)
-		goto err;
+	ret = drmm_add_action(dev, drm_vblank_init_release, NULL);
+	if (ret)
+		return ret;
 
 	for (i = 0; i < num_crtcs; i++) {
 		struct drm_vblank_crtc *vblank = &dev->vblank[i];
@@ -486,10 +546,6 @@ int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs)
 	DRM_INFO("Supports vblank timestamp caching Rev 2 (21.10.2013).\n");
 
 	return 0;
-
-err:
-	dev->num_crtcs = 0;
-	return ret;
 }
 EXPORT_SYMBOL(drm_vblank_init);
 
diff --git a/drivers/gpu/drm/drm_vm.c b/drivers/gpu/drm/drm_vm.c
index aa88911bbc06..56197ae0b2f9 100644
--- a/drivers/gpu/drm/drm_vm.c
+++ b/drivers/gpu/drm/drm_vm.c
@@ -595,8 +595,8 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
 			vma->vm_ops = &drm_vm_ops;
 			break;
 		}
+		fallthrough;	/* to _DRM_FRAME_BUFFER... */
 #endif
-		/* fall through - to _DRM_FRAME_BUFFER... */
 	case _DRM_FRAME_BUFFER:
 	case _DRM_REGISTERS:
 		offset = drm_core_get_reg_ofs(dev);
@@ -621,7 +621,7 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
 		    vma->vm_end - vma->vm_start, vma->vm_page_prot))
 			return -EAGAIN;
 		vma->vm_page_prot = drm_dma_prot(map->type, vma);
-		/* fall through - to _DRM_SHM */
+		fallthrough;	/* to _DRM_SHM */
 	case _DRM_SHM:
 		vma->vm_ops = &drm_vm_shm_ops;
 		vma->vm_private_data = (void *)map;
diff --git a/drivers/gpu/drm/drm_vram_helper_common.c b/drivers/gpu/drm/drm_vram_helper_common.c
deleted file mode 100644
index 2000d9b33fd5..000000000000
--- a/drivers/gpu/drm/drm_vram_helper_common.c
+++ /dev/null
@@ -1,94 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include <linux/module.h>
-
-/**
- * DOC: overview
- *
- * This library provides &struct drm_gem_vram_object (GEM VRAM), a GEM
- * buffer object that is backed by video RAM. It can be used for
- * framebuffer devices with dedicated memory. The video RAM is managed
- * by &struct drm_vram_mm (VRAM MM).
- *
- * With the GEM interface userspace applications create, manage and destroy
- * graphics buffers, such as an on-screen framebuffer. GEM does not provide
- * an implementation of these interfaces. It's up to the DRM driver to
- * provide an implementation that suits the hardware. If the hardware device
- * contains dedicated video memory, the DRM driver can use the VRAM helper
- * library. Each active buffer object is stored in video RAM. Active
- * buffer are used for drawing the current frame, typically something like
- * the frame's scanout buffer or the cursor image. If there's no more space
- * left in VRAM, inactive GEM objects can be moved to system memory.
- *
- * The easiest way to use the VRAM helper library is to call
- * drm_vram_helper_alloc_mm(). The function allocates and initializes an
- * instance of &struct drm_vram_mm in &struct drm_device.vram_mm . Use
- * &DRM_GEM_VRAM_DRIVER to initialize &struct drm_driver and
- * &DRM_VRAM_MM_FILE_OPERATIONS to initialize &struct file_operations;
- * as illustrated below.
- *
- * .. code-block:: c
- *
- *	struct file_operations fops ={
- *		.owner = THIS_MODULE,
- *		DRM_VRAM_MM_FILE_OPERATION
- *	};
- *	struct drm_driver drv = {
- *		.driver_feature = DRM_ ... ,
- *		.fops = &fops,
- *		DRM_GEM_VRAM_DRIVER
- *	};
- *
- *	int init_drm_driver()
- *	{
- *		struct drm_device *dev;
- *		uint64_t vram_base;
- *		unsigned long vram_size;
- *		int ret;
- *
- *		// setup device, vram base and size
- *		// ...
- *
- *		ret = drm_vram_helper_alloc_mm(dev, vram_base, vram_size);
- *		if (ret)
- *			return ret;
- *		return 0;
- *	}
- *
- * This creates an instance of &struct drm_vram_mm, exports DRM userspace
- * interfaces for GEM buffer management and initializes file operations to
- * allow for accessing created GEM buffers. With this setup, the DRM driver
- * manages an area of video RAM with VRAM MM and provides GEM VRAM objects
- * to userspace.
- *
- * To clean up the VRAM memory management, call drm_vram_helper_release_mm()
- * in the driver's clean-up code.
- *
- * .. code-block:: c
- *
- *	void fini_drm_driver()
- *	{
- *		struct drm_device *dev = ...;
- *
- *		drm_vram_helper_release_mm(dev);
- *	}
- *
- * For drawing or scanout operations, buffer object have to be pinned in video
- * RAM. Call drm_gem_vram_pin() with &DRM_GEM_VRAM_PL_FLAG_VRAM or
- * &DRM_GEM_VRAM_PL_FLAG_SYSTEM to pin a buffer object in video RAM or system
- * memory. Call drm_gem_vram_unpin() to release the pinned object afterwards.
- *
- * A buffer object that is pinned in video RAM has a fixed address within that
- * memory region. Call drm_gem_vram_offset() to retrieve this value. Typically
- * it's used to program the hardware's scanout engine for framebuffers, set
- * the cursor overlay's image for a mouse cursor, or use it as input to the
- * hardware's draing engine.
- *
- * To access a buffer object's memory from the DRM driver, call
- * drm_gem_vram_kmap(). It (optionally) maps the buffer into kernel address
- * space and returns the memory address. Use drm_gem_vram_kunmap() to
- * release the mapping.
- */
-
-MODULE_DESCRIPTION("DRM VRAM memory-management helpers");
-MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
index a8685b2e1803..27c948f5dfeb 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
@@ -231,21 +231,11 @@ static struct drm_info_list etnaviv_debugfs_list[] = {
 		{"ring", show_each_gpu, 0, etnaviv_ring_show},
 };
 
-static int etnaviv_debugfs_init(struct drm_minor *minor)
+static void etnaviv_debugfs_init(struct drm_minor *minor)
 {
-	struct drm_device *dev = minor->dev;
-	int ret;
-
-	ret = drm_debugfs_create_files(etnaviv_debugfs_list,
-			ARRAY_SIZE(etnaviv_debugfs_list),
-			minor->debugfs_root, minor);
-
-	if (ret) {
-		dev_err(dev->dev, "could not install etnaviv_debugfs_list\n");
-		return ret;
-	}
-
-	return ret;
+	drm_debugfs_create_files(etnaviv_debugfs_list,
+				 ARRAY_SIZE(etnaviv_debugfs_list),
+				 minor->debugfs_root, minor);
 }
 #endif
 
diff --git a/drivers/gpu/drm/exynos/exynos_dp.c b/drivers/gpu/drm/exynos/exynos_dp.c
index 5ee090691390..9ac51b6ab34b 100644
--- a/drivers/gpu/drm/exynos/exynos_dp.c
+++ b/drivers/gpu/drm/exynos/exynos_dp.c
@@ -25,6 +25,7 @@
 #include <drm/drm_panel.h>
 #include <drm/drm_print.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 #include <drm/exynos_drm.h>
 
 #include "exynos_drm_crtc.h"
@@ -135,10 +136,6 @@ static const struct drm_encoder_helper_funcs exynos_dp_encoder_helper_funcs = {
 	.disable = exynos_dp_nop,
 };
 
-static const struct drm_encoder_funcs exynos_dp_encoder_funcs = {
-	.destroy = drm_encoder_cleanup,
-};
-
 static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp)
 {
 	int ret;
@@ -167,8 +164,7 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
 			return ret;
 	}
 
-	drm_encoder_init(drm_dev, encoder, &exynos_dp_encoder_funcs,
-			 DRM_MODE_ENCODER_TMDS, NULL);
+	drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_TMDS);
 
 	drm_encoder_helper_add(encoder, &exynos_dp_encoder_helper_funcs);
 
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dpi.c b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
index 43fa0f26c052..7ba5354e7d94 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dpi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
@@ -14,6 +14,7 @@
 #include <drm/drm_panel.h>
 #include <drm/drm_print.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include <video/of_videomode.h>
 #include <video/videomode.h>
@@ -149,10 +150,6 @@ static const struct drm_encoder_helper_funcs exynos_dpi_encoder_helper_funcs = {
 	.disable = exynos_dpi_disable,
 };
 
-static const struct drm_encoder_funcs exynos_dpi_encoder_funcs = {
-	.destroy = drm_encoder_cleanup,
-};
-
 enum {
 	FIMD_PORT_IN0,
 	FIMD_PORT_IN1,
@@ -201,8 +198,7 @@ int exynos_dpi_bind(struct drm_device *dev, struct drm_encoder *encoder)
 {
 	int ret;
 
-	drm_encoder_init(dev, encoder, &exynos_dpi_encoder_funcs,
-			 DRM_MODE_ENCODER_TMDS, NULL);
+	drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_TMDS);
 
 	drm_encoder_helper_add(encoder, &exynos_dpi_encoder_helper_funcs);
 
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index e080aa92338c..902938d2568f 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -30,6 +30,7 @@
 #include <drm/drm_panel.h>
 #include <drm/drm_print.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "exynos_drm_crtc.h"
 #include "exynos_drm_drv.h"
@@ -1523,10 +1524,6 @@ static const struct drm_encoder_helper_funcs exynos_dsi_encoder_helper_funcs = {
 	.disable = exynos_dsi_disable,
 };
 
-static const struct drm_encoder_funcs exynos_dsi_encoder_funcs = {
-	.destroy = drm_encoder_cleanup,
-};
-
 MODULE_DEVICE_TABLE(of, exynos_dsi_of_match);
 
 static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
@@ -1704,8 +1701,7 @@ static int exynos_dsi_bind(struct device *dev, struct device *master,
 	struct drm_bridge *in_bridge;
 	int ret;
 
-	drm_encoder_init(drm_dev, encoder, &exynos_dsi_encoder_funcs,
-			 DRM_MODE_ENCODER_TMDS, NULL);
+	drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_TMDS);
 
 	drm_encoder_helper_add(encoder, &exynos_dsi_encoder_helper_funcs);
 
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
index b320b3a21ad4..282467121699 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
@@ -14,6 +14,7 @@
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_edid.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 #include <drm/drm_vblank.h>
 #include <drm/exynos_drm.h>
 
@@ -369,10 +370,6 @@ static const struct drm_encoder_helper_funcs exynos_vidi_encoder_helper_funcs =
 	.disable = exynos_vidi_disable,
 };
 
-static const struct drm_encoder_funcs exynos_vidi_encoder_funcs = {
-	.destroy = drm_encoder_cleanup,
-};
-
 static int vidi_bind(struct device *dev, struct device *master, void *data)
 {
 	struct vidi_context *ctx = dev_get_drvdata(dev);
@@ -406,8 +403,7 @@ static int vidi_bind(struct device *dev, struct device *master, void *data)
 		return PTR_ERR(ctx->crtc);
 	}
 
-	drm_encoder_init(drm_dev, encoder, &exynos_vidi_encoder_funcs,
-			 DRM_MODE_ENCODER_TMDS, NULL);
+	drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_TMDS);
 
 	drm_encoder_helper_add(encoder, &exynos_vidi_encoder_helper_funcs);
 
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 1a7c828fc41d..95dd399aa9cc 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -38,6 +38,7 @@
 #include <drm/drm_edid.h>
 #include <drm/drm_print.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "exynos_drm_crtc.h"
 #include "regs-hdmi.h"
@@ -1559,10 +1560,6 @@ static const struct drm_encoder_helper_funcs exynos_hdmi_encoder_helper_funcs =
 	.disable	= hdmi_disable,
 };
 
-static const struct drm_encoder_funcs exynos_hdmi_encoder_funcs = {
-	.destroy = drm_encoder_cleanup,
-};
-
 static void hdmi_audio_shutdown(struct device *dev, void *data)
 {
 	struct hdmi_context *hdata = dev_get_drvdata(dev);
@@ -1843,8 +1840,7 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data)
 
 	hdata->phy_clk.enable = hdmiphy_clk_enable;
 
-	drm_encoder_init(drm_dev, encoder, &exynos_hdmi_encoder_funcs,
-			 DRM_MODE_ENCODER_TMDS, NULL);
+	drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_TMDS);
 
 	drm_encoder_helper_add(encoder, &exynos_hdmi_encoder_helper_funcs);
 
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
index cff344367f81..9b0c4736c21a 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
@@ -13,19 +13,11 @@
 #include <drm/drm_of.h>
 #include <drm/drm_panel.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "fsl_dcu_drm_drv.h"
 #include "fsl_tcon.h"
 
-static void fsl_dcu_drm_encoder_destroy(struct drm_encoder *encoder)
-{
-	drm_encoder_cleanup(encoder);
-}
-
-static const struct drm_encoder_funcs encoder_funcs = {
-	.destroy = fsl_dcu_drm_encoder_destroy,
-};
-
 int fsl_dcu_drm_encoder_create(struct fsl_dcu_drm_device *fsl_dev,
 			       struct drm_crtc *crtc)
 {
@@ -38,8 +30,8 @@ int fsl_dcu_drm_encoder_create(struct fsl_dcu_drm_device *fsl_dev,
 	if (fsl_dev->tcon)
 		fsl_tcon_bypass_enable(fsl_dev->tcon);
 
-	ret = drm_encoder_init(fsl_dev->drm, encoder, &encoder_funcs,
-			       DRM_MODE_ENCODER_LVDS, NULL);
+	ret = drm_simple_encoder_init(fsl_dev->drm, encoder,
+				      DRM_MODE_ENCODER_LVDS);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/gpu/drm/gma500/cdv_intel_crt.c b/drivers/gpu/drm/gma500/cdv_intel_crt.c
index 29c36d63b20e..88535f5aacc5 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_crt.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_crt.c
@@ -28,6 +28,8 @@
 #include <linux/i2c.h>
 #include <linux/pm_runtime.h>
 
+#include <drm/drm_simple_kms_helper.h>
+
 #include "cdv_device.h"
 #include "intel_bios.h"
 #include "power.h"
@@ -237,15 +239,6 @@ static const struct drm_connector_helper_funcs
 	.best_encoder = gma_best_encoder,
 };
 
-static void cdv_intel_crt_enc_destroy(struct drm_encoder *encoder)
-{
-	drm_encoder_cleanup(encoder);
-}
-
-static const struct drm_encoder_funcs cdv_intel_crt_enc_funcs = {
-	.destroy = cdv_intel_crt_enc_destroy,
-};
-
 void cdv_intel_crt_init(struct drm_device *dev,
 			struct psb_intel_mode_device *mode_dev)
 {
@@ -271,8 +264,7 @@ void cdv_intel_crt_init(struct drm_device *dev,
 		&cdv_intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA);
 
 	encoder = &gma_encoder->base;
-	drm_encoder_init(dev, encoder,
-		&cdv_intel_crt_enc_funcs, DRM_MODE_ENCODER_DAC, NULL);
+	drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_DAC);
 
 	gma_connector_attach_encoder(gma_connector, gma_encoder);
 
diff --git a/drivers/gpu/drm/gma500/cdv_intel_dp.c b/drivers/gpu/drm/gma500/cdv_intel_dp.c
index 5772b2dce0d6..13947ec06dbb 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_dp.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_dp.c
@@ -32,6 +32,7 @@
 #include <drm/drm_crtc.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_dp_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "gma_display.h"
 #include "psb_drv.h"
@@ -1908,11 +1909,6 @@ cdv_intel_dp_destroy(struct drm_connector *connector)
 	kfree(connector);
 }
 
-static void cdv_intel_dp_encoder_destroy(struct drm_encoder *encoder)
-{
-	drm_encoder_cleanup(encoder);
-}
-
 static const struct drm_encoder_helper_funcs cdv_intel_dp_helper_funcs = {
 	.dpms = cdv_intel_dp_dpms,
 	.mode_fixup = cdv_intel_dp_mode_fixup,
@@ -1935,11 +1931,6 @@ static const struct drm_connector_helper_funcs cdv_intel_dp_connector_helper_fun
 	.best_encoder = gma_best_encoder,
 };
 
-static const struct drm_encoder_funcs cdv_intel_dp_enc_funcs = {
-	.destroy = cdv_intel_dp_encoder_destroy,
-};
-
-
 static void cdv_intel_dp_add_properties(struct drm_connector *connector)
 {
 	cdv_intel_attach_force_audio_property(connector);
@@ -2016,8 +2007,7 @@ cdv_intel_dp_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev
 	encoder = &gma_encoder->base;
 
 	drm_connector_init(dev, connector, &cdv_intel_dp_connector_funcs, type);
-	drm_encoder_init(dev, encoder, &cdv_intel_dp_enc_funcs,
-			 DRM_MODE_ENCODER_TMDS, NULL);
+	drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_TMDS);
 
 	gma_connector_attach_encoder(gma_connector, gma_encoder);
 
@@ -2120,7 +2110,7 @@ cdv_intel_dp_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev
 		if (ret == 0) {
 			/* if this fails, presume the device is a ghost */
 			DRM_INFO("failed to retrieve link info, disabling eDP\n");
-			cdv_intel_dp_encoder_destroy(encoder);
+			drm_encoder_cleanup(encoder);
 			cdv_intel_dp_destroy(connector);
 			goto err_priv;
 		} else {
diff --git a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
index 1711a41acc16..0d12c6ffbc40 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
@@ -32,6 +32,7 @@
 #include <drm/drm.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_edid.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "cdv_device.h"
 #include "psb_drv.h"
@@ -311,8 +312,7 @@ void cdv_hdmi_init(struct drm_device *dev,
 			   &cdv_hdmi_connector_funcs,
 			   DRM_MODE_CONNECTOR_DVID);
 
-	drm_encoder_init(dev, encoder, &psb_intel_lvds_enc_funcs,
-			 DRM_MODE_ENCODER_TMDS, NULL);
+	drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_TMDS);
 
 	gma_connector_attach_encoder(gma_connector, gma_encoder);
 	gma_encoder->type = INTEL_OUTPUT_HDMI;
diff --git a/drivers/gpu/drm/gma500/cdv_intel_lvds.c b/drivers/gpu/drm/gma500/cdv_intel_lvds.c
index ea0a5d9a0acc..18de10e9ff9a 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_lvds.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_lvds.c
@@ -12,6 +12,8 @@
 #include <linux/i2c.h>
 #include <linux/pm_runtime.h>
 
+#include <drm/drm_simple_kms_helper.h>
+
 #include "cdv_device.h"
 #include "intel_bios.h"
 #include "power.h"
@@ -499,16 +501,6 @@ static const struct drm_connector_funcs cdv_intel_lvds_connector_funcs = {
 	.destroy = cdv_intel_lvds_destroy,
 };
 
-
-static void cdv_intel_lvds_enc_destroy(struct drm_encoder *encoder)
-{
-	drm_encoder_cleanup(encoder);
-}
-
-static const struct drm_encoder_funcs cdv_intel_lvds_enc_funcs = {
-	.destroy = cdv_intel_lvds_enc_destroy,
-};
-
 /*
  * Enumerate the child dev array parsed from VBT to check whether
  * the LVDS is present.
@@ -616,10 +608,7 @@ void cdv_intel_lvds_init(struct drm_device *dev,
 			   &cdv_intel_lvds_connector_funcs,
 			   DRM_MODE_CONNECTOR_LVDS);
 
-	drm_encoder_init(dev, encoder,
-			 &cdv_intel_lvds_enc_funcs,
-			 DRM_MODE_ENCODER_LVDS, NULL);
-
+	drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_LVDS);
 
 	gma_connector_attach_encoder(gma_connector, gma_encoder);
 	gma_encoder->type = INTEL_OUTPUT_LVDS;
diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c
index 1d8f67e4795a..23a78d755382 100644
--- a/drivers/gpu/drm/gma500/framebuffer.c
+++ b/drivers/gpu/drm/gma500/framebuffer.c
@@ -577,31 +577,31 @@ static void psb_setup_outputs(struct drm_device *dev)
 			break;
 		case INTEL_OUTPUT_SDVO:
 			crtc_mask = dev_priv->ops->sdvo_mask;
-			clone_mask = (1 << INTEL_OUTPUT_SDVO);
+			clone_mask = 0;
 			break;
 		case INTEL_OUTPUT_LVDS:
-		        crtc_mask = dev_priv->ops->lvds_mask;
-			clone_mask = (1 << INTEL_OUTPUT_LVDS);
+			crtc_mask = dev_priv->ops->lvds_mask;
+			clone_mask = 0;
 			break;
 		case INTEL_OUTPUT_MIPI:
 			crtc_mask = (1 << 0);
-			clone_mask = (1 << INTEL_OUTPUT_MIPI);
+			clone_mask = 0;
 			break;
 		case INTEL_OUTPUT_MIPI2:
 			crtc_mask = (1 << 2);
-			clone_mask = (1 << INTEL_OUTPUT_MIPI2);
+			clone_mask = 0;
 			break;
 		case INTEL_OUTPUT_HDMI:
-		        crtc_mask = dev_priv->ops->hdmi_mask;
+			crtc_mask = dev_priv->ops->hdmi_mask;
 			clone_mask = (1 << INTEL_OUTPUT_HDMI);
 			break;
 		case INTEL_OUTPUT_DISPLAYPORT:
 			crtc_mask = (1 << 0) | (1 << 1);
-			clone_mask = (1 << INTEL_OUTPUT_DISPLAYPORT);
+			clone_mask = 0;
 			break;
 		case INTEL_OUTPUT_EDP:
 			crtc_mask = (1 << 1);
-			clone_mask = (1 << INTEL_OUTPUT_EDP);
+			clone_mask = 0;
 		}
 		encoder->possible_crtcs = crtc_mask;
 		encoder->possible_clones =
diff --git a/drivers/gpu/drm/gma500/mdfld_dsi_dpi.c b/drivers/gpu/drm/gma500/mdfld_dsi_dpi.c
index d4c65f268922..c976a9dd9240 100644
--- a/drivers/gpu/drm/gma500/mdfld_dsi_dpi.c
+++ b/drivers/gpu/drm/gma500/mdfld_dsi_dpi.c
@@ -27,6 +27,8 @@
 
 #include <linux/delay.h>
 
+#include <drm/drm_simple_kms_helper.h>
+
 #include "mdfld_dsi_dpi.h"
 #include "mdfld_dsi_pkg_sender.h"
 #include "mdfld_output.h"
@@ -993,10 +995,7 @@ struct mdfld_dsi_encoder *mdfld_dsi_dpi_init(struct drm_device *dev,
 	/*create drm encoder object*/
 	connector = &dsi_connector->base.base;
 	encoder = &dpi_output->base.base.base;
-	drm_encoder_init(dev,
-			encoder,
-			p_funcs->encoder_funcs,
-			DRM_MODE_ENCODER_LVDS, NULL);
+	drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_LVDS);
 	drm_encoder_helper_add(encoder,
 				p_funcs->encoder_helper_funcs);
 
@@ -1006,10 +1005,10 @@ struct mdfld_dsi_encoder *mdfld_dsi_dpi_init(struct drm_device *dev,
 	/*set possible crtcs and clones*/
 	if (dsi_connector->pipe) {
 		encoder->possible_crtcs = (1 << 2);
-		encoder->possible_clones = (1 << 1);
+		encoder->possible_clones = 0;
 	} else {
 		encoder->possible_crtcs = (1 << 0);
-		encoder->possible_clones = (1 << 0);
+		encoder->possible_clones = 0;
 	}
 
 	dsi_connector->base.encoder = &dpi_output->base.base;
diff --git a/drivers/gpu/drm/gma500/mdfld_output.h b/drivers/gpu/drm/gma500/mdfld_output.h
index ab2b27c0f037..17a944d70add 100644
--- a/drivers/gpu/drm/gma500/mdfld_output.h
+++ b/drivers/gpu/drm/gma500/mdfld_output.h
@@ -51,7 +51,6 @@ struct panel_info {
 };
 
 struct panel_funcs {
-	const struct drm_encoder_funcs *encoder_funcs;
 	const struct drm_encoder_helper_funcs *encoder_helper_funcs;
 	struct drm_display_mode * (*get_config_mode)(struct drm_device *);
 	int (*get_panel_info)(struct drm_device *, int, struct panel_info *);
diff --git a/drivers/gpu/drm/gma500/mdfld_tmd_vid.c b/drivers/gpu/drm/gma500/mdfld_tmd_vid.c
index 49c92debb7b2..25e897b98f86 100644
--- a/drivers/gpu/drm/gma500/mdfld_tmd_vid.c
+++ b/drivers/gpu/drm/gma500/mdfld_tmd_vid.c
@@ -188,13 +188,7 @@ static const struct drm_encoder_helper_funcs
 	.commit = mdfld_dsi_dpi_commit,
 };
 
-/*TPO DPI encoder funcs*/
-static const struct drm_encoder_funcs mdfld_tpo_dpi_encoder_funcs = {
-	.destroy = drm_encoder_cleanup,
-};
-
 const struct panel_funcs mdfld_tmd_vid_funcs = {
-	.encoder_funcs = &mdfld_tpo_dpi_encoder_funcs,
 	.encoder_helper_funcs = &mdfld_tpo_dpi_encoder_helper_funcs,
 	.get_config_mode = &tmd_vid_get_config_mode,
 	.get_panel_info = tmd_vid_get_panel_info,
diff --git a/drivers/gpu/drm/gma500/mdfld_tpo_vid.c b/drivers/gpu/drm/gma500/mdfld_tpo_vid.c
index a9420bf9a419..11845978fb0a 100644
--- a/drivers/gpu/drm/gma500/mdfld_tpo_vid.c
+++ b/drivers/gpu/drm/gma500/mdfld_tpo_vid.c
@@ -76,13 +76,7 @@ static const struct drm_encoder_helper_funcs
 	.commit = mdfld_dsi_dpi_commit,
 };
 
-/*TPO DPI encoder funcs*/
-static const struct drm_encoder_funcs mdfld_tpo_dpi_encoder_funcs = {
-	.destroy = drm_encoder_cleanup,
-};
-
 const struct panel_funcs mdfld_tpo_vid_funcs = {
-	.encoder_funcs = &mdfld_tpo_dpi_encoder_funcs,
 	.encoder_helper_funcs = &mdfld_tpo_dpi_encoder_helper_funcs,
 	.get_config_mode = &tpo_vid_get_config_mode,
 	.get_panel_info = tpo_vid_get_panel_info,
diff --git a/drivers/gpu/drm/gma500/oaktrail_hdmi.c b/drivers/gpu/drm/gma500/oaktrail_hdmi.c
index f4370232767d..b25086f252ae 100644
--- a/drivers/gpu/drm/gma500/oaktrail_hdmi.c
+++ b/drivers/gpu/drm/gma500/oaktrail_hdmi.c
@@ -27,6 +27,7 @@
 #include <linux/delay.h>
 
 #include <drm/drm.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "psb_drv.h"
 #include "psb_intel_drv.h"
@@ -620,15 +621,6 @@ static const struct drm_connector_funcs oaktrail_hdmi_connector_funcs = {
 	.destroy = oaktrail_hdmi_destroy,
 };
 
-static void oaktrail_hdmi_enc_destroy(struct drm_encoder *encoder)
-{
-	drm_encoder_cleanup(encoder);
-}
-
-static const struct drm_encoder_funcs oaktrail_hdmi_enc_funcs = {
-	.destroy = oaktrail_hdmi_enc_destroy,
-};
-
 void oaktrail_hdmi_init(struct drm_device *dev,
 					struct psb_intel_mode_device *mode_dev)
 {
@@ -651,9 +643,7 @@ void oaktrail_hdmi_init(struct drm_device *dev,
 			   &oaktrail_hdmi_connector_funcs,
 			   DRM_MODE_CONNECTOR_DVID);
 
-	drm_encoder_init(dev, encoder,
-			 &oaktrail_hdmi_enc_funcs,
-			 DRM_MODE_ENCODER_TMDS, NULL);
+	drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_TMDS);
 
 	gma_connector_attach_encoder(gma_connector, gma_encoder);
 
diff --git a/drivers/gpu/drm/gma500/oaktrail_lvds.c b/drivers/gpu/drm/gma500/oaktrail_lvds.c
index 582e09597500..2828360153d1 100644
--- a/drivers/gpu/drm/gma500/oaktrail_lvds.c
+++ b/drivers/gpu/drm/gma500/oaktrail_lvds.c
@@ -13,6 +13,8 @@
 
 #include <asm/intel-mid.h>
 
+#include <drm/drm_simple_kms_helper.h>
+
 #include "intel_bios.h"
 #include "power.h"
 #include "psb_drv.h"
@@ -311,8 +313,7 @@ void oaktrail_lvds_init(struct drm_device *dev,
 			   &psb_intel_lvds_connector_funcs,
 			   DRM_MODE_CONNECTOR_LVDS);
 
-	drm_encoder_init(dev, encoder, &psb_intel_lvds_enc_funcs,
-			 DRM_MODE_ENCODER_LVDS, NULL);
+	drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_LVDS);
 
 	gma_connector_attach_encoder(gma_connector, gma_encoder);
 	gma_encoder->type = INTEL_OUTPUT_LVDS;
diff --git a/drivers/gpu/drm/gma500/psb_intel_drv.h b/drivers/gpu/drm/gma500/psb_intel_drv.h
index 16c6136f778b..fb601983cef0 100644
--- a/drivers/gpu/drm/gma500/psb_intel_drv.h
+++ b/drivers/gpu/drm/gma500/psb_intel_drv.h
@@ -252,7 +252,6 @@ extern int psb_intel_lvds_set_property(struct drm_connector *connector,
 					struct drm_property *property,
 					uint64_t value);
 extern void psb_intel_lvds_destroy(struct drm_connector *connector);
-extern const struct drm_encoder_funcs psb_intel_lvds_enc_funcs;
 
 /* intel_gmbus.c */
 extern void gma_intel_i2c_reset(struct drm_device *dev);
diff --git a/drivers/gpu/drm/gma500/psb_intel_lvds.c b/drivers/gpu/drm/gma500/psb_intel_lvds.c
index afaebab7bc17..063c66bb946d 100644
--- a/drivers/gpu/drm/gma500/psb_intel_lvds.c
+++ b/drivers/gpu/drm/gma500/psb_intel_lvds.c
@@ -11,6 +11,8 @@
 #include <linux/i2c.h>
 #include <linux/pm_runtime.h>
 
+#include <drm/drm_simple_kms_helper.h>
+
 #include "intel_bios.h"
 #include "power.h"
 #include "psb_drv.h"
@@ -621,18 +623,6 @@ const struct drm_connector_funcs psb_intel_lvds_connector_funcs = {
 	.destroy = psb_intel_lvds_destroy,
 };
 
-
-static void psb_intel_lvds_enc_destroy(struct drm_encoder *encoder)
-{
-	drm_encoder_cleanup(encoder);
-}
-
-const struct drm_encoder_funcs psb_intel_lvds_enc_funcs = {
-	.destroy = psb_intel_lvds_enc_destroy,
-};
-
-
-
 /**
  * psb_intel_lvds_init - setup LVDS connectors on this device
  * @dev: drm device
@@ -683,9 +673,7 @@ void psb_intel_lvds_init(struct drm_device *dev,
 			   &psb_intel_lvds_connector_funcs,
 			   DRM_MODE_CONNECTOR_LVDS);
 
-	drm_encoder_init(dev, encoder,
-			 &psb_intel_lvds_enc_funcs,
-			 DRM_MODE_ENCODER_LVDS, NULL);
+	drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_LVDS);
 
 	gma_connector_attach_encoder(gma_connector, gma_encoder);
 	gma_encoder->type = INTEL_OUTPUT_LVDS;
diff --git a/drivers/gpu/drm/gma500/tc35876x-dsi-lvds.c b/drivers/gpu/drm/gma500/tc35876x-dsi-lvds.c
index 9e8224456ea2..e5bdd99ad453 100644
--- a/drivers/gpu/drm/gma500/tc35876x-dsi-lvds.c
+++ b/drivers/gpu/drm/gma500/tc35876x-dsi-lvds.c
@@ -747,11 +747,11 @@ static int cmi_lcd_hack_create_device(void)
 		return -EINVAL;
 	}
 
-	client = i2c_new_device(adapter, &info);
-	if (!client) {
-		pr_err("%s: i2c_new_device() failed\n", __func__);
+	client = i2c_new_client_device(adapter, &info);
+	if (IS_ERR(client)) {
+		pr_err("%s: creating I2C device failed\n", __func__);
 		i2c_put_adapter(adapter);
-		return -EINVAL;
+		return PTR_ERR(client);
 	}
 
 	return 0;
@@ -765,12 +765,7 @@ static const struct drm_encoder_helper_funcs tc35876x_encoder_helper_funcs = {
 	.commit = mdfld_dsi_dpi_commit,
 };
 
-static const struct drm_encoder_funcs tc35876x_encoder_funcs = {
-	.destroy = drm_encoder_cleanup,
-};
-
 const struct panel_funcs mdfld_tc35876x_funcs = {
-	.encoder_funcs = &tc35876x_encoder_funcs,
 	.encoder_helper_funcs = &tc35876x_encoder_helper_funcs,
 	.get_config_mode = tc35876x_get_config_mode,
 	.get_panel_info = tc35876x_get_panel_info,
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c
index 55b46a7150a5..cc70e836522f 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c
@@ -94,6 +94,10 @@ static int hibmc_plane_atomic_check(struct drm_plane *plane,
 		return -EINVAL;
 	}
 
+	if (state->fb->pitches[0] % 128 != 0) {
+		DRM_DEBUG_ATOMIC("wrong stride with 128-byte aligned\n");
+		return -EINVAL;
+	}
 	return 0;
 }
 
@@ -119,11 +123,8 @@ static void hibmc_plane_atomic_update(struct drm_plane *plane,
 	writel(gpu_addr, priv->mmio + HIBMC_CRT_FB_ADDRESS);
 
 	reg = state->fb->width * (state->fb->format->cpp[0]);
-	/* now line_pad is 16 */
-	reg = PADDING(16, reg);
 
-	line_l = state->fb->width * state->fb->format->cpp[0];
-	line_l = PADDING(16, line_l);
+	line_l = state->fb->pitches[0];
 	writel(HIBMC_FIELD(HIBMC_CRT_FB_WIDTH_WIDTH, reg) |
 	       HIBMC_FIELD(HIBMC_CRT_FB_WIDTH_OFFS, line_l),
 	       priv->mmio + HIBMC_CRT_FB_WIDTH);
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
index 222356a4f9a8..a6fd0c29e5b8 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
@@ -94,7 +94,7 @@ static int hibmc_kms_init(struct hibmc_drm_private *priv)
 	priv->dev->mode_config.max_height = 1200;
 
 	priv->dev->mode_config.fb_base = priv->fb_base;
-	priv->dev->mode_config.preferred_depth = 24;
+	priv->dev->mode_config.preferred_depth = 32;
 	priv->dev->mode_config.prefer_shadow = 1;
 
 	priv->dev->mode_config.funcs = (void *)&hibmc_mode_funcs;
@@ -307,11 +307,7 @@ static int hibmc_load(struct drm_device *dev)
 	/* reset all the states of crtc/plane/encoder/connector */
 	drm_mode_config_reset(dev);
 
-	ret = drm_fbdev_generic_setup(dev, 16);
-	if (ret) {
-		DRM_ERROR("failed to initialize fbdev: %d\n", ret);
-		goto err;
-	}
+	drm_fbdev_generic_setup(dev, dev->mode_config.preferred_depth);
 
 	return 0;
 
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c
index 99397ac3b363..322bd542e89d 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c
@@ -50,7 +50,7 @@ void hibmc_mm_fini(struct hibmc_drm_private *hibmc)
 int hibmc_dumb_create(struct drm_file *file, struct drm_device *dev,
 		      struct drm_mode_create_dumb *args)
 {
-	return drm_gem_vram_fill_create_dumb(file, dev, 0, 16, args);
+	return drm_gem_vram_fill_create_dumb(file, dev, 0, 128, args);
 }
 
 const struct drm_mode_config_funcs hibmc_mode_funcs = {
diff --git a/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c b/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c
index f31068d74b18..00e87c290796 100644
--- a/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c
+++ b/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c
@@ -20,11 +20,11 @@
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_bridge.h>
 #include <drm/drm_device.h>
-#include <drm/drm_encoder_slave.h>
 #include <drm/drm_mipi_dsi.h>
 #include <drm/drm_of.h>
 #include <drm/drm_print.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "dw_dsi_reg.h"
 
@@ -696,10 +696,6 @@ static const struct drm_encoder_helper_funcs dw_encoder_helper_funcs = {
 	.disable	= dsi_encoder_disable
 };
 
-static const struct drm_encoder_funcs dw_encoder_funcs = {
-	.destroy = drm_encoder_cleanup,
-};
-
 static int dw_drm_encoder_init(struct device *dev,
 			       struct drm_device *drm_dev,
 			       struct drm_encoder *encoder)
@@ -713,8 +709,7 @@ static int dw_drm_encoder_init(struct device *dev,
 	}
 
 	encoder->possible_crtcs = crtc_mask;
-	ret = drm_encoder_init(drm_dev, encoder, &dw_encoder_funcs,
-			       DRM_MODE_ENCODER_DSI, NULL);
+	ret = drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_DSI);
 	if (ret) {
 		DRM_ERROR("failed to init dsi encoder\n");
 		return ret;
diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
index 86000127d4ee..c339e632522a 100644
--- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
+++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
@@ -940,7 +940,6 @@ static struct drm_driver ade_driver = {
 };
 
 struct kirin_drm_data ade_driver_data = {
-	.register_connects = false,
 	.num_planes = ADE_CH_NUM,
 	.prim_plane = ADE_CH1,
 	.channel_formats = channel_formats,
diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c
index d3145ae877d7..4349da3e2379 100644
--- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c
+++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c
@@ -219,40 +219,6 @@ static int kirin_drm_kms_cleanup(struct drm_device *dev)
 	return 0;
 }
 
-static int kirin_drm_connectors_register(struct drm_device *dev)
-{
-	struct drm_connector *connector;
-	struct drm_connector *failed_connector;
-	struct drm_connector_list_iter conn_iter;
-	int ret;
-
-	mutex_lock(&dev->mode_config.mutex);
-	drm_connector_list_iter_begin(dev, &conn_iter);
-	drm_for_each_connector_iter(connector, &conn_iter) {
-		ret = drm_connector_register(connector);
-		if (ret) {
-			failed_connector = connector;
-			goto err;
-		}
-	}
-	drm_connector_list_iter_end(&conn_iter);
-	mutex_unlock(&dev->mode_config.mutex);
-
-	return 0;
-
-err:
-	drm_connector_list_iter_begin(dev, &conn_iter);
-	drm_for_each_connector_iter(connector, &conn_iter) {
-		if (failed_connector == connector)
-			break;
-		drm_connector_unregister(connector);
-	}
-	drm_connector_list_iter_end(&conn_iter);
-	mutex_unlock(&dev->mode_config.mutex);
-
-	return ret;
-}
-
 static int kirin_drm_bind(struct device *dev)
 {
 	struct kirin_drm_data *driver_data;
@@ -279,17 +245,8 @@ static int kirin_drm_bind(struct device *dev)
 
 	drm_fbdev_generic_setup(drm_dev, 32);
 
-	/* connectors should be registered after drm device register */
-	if (driver_data->register_connects) {
-		ret = kirin_drm_connectors_register(drm_dev);
-		if (ret)
-			goto err_drm_dev_unregister;
-	}
-
 	return 0;
 
-err_drm_dev_unregister:
-	drm_dev_unregister(drm_dev);
 err_kms_cleanup:
 	kirin_drm_kms_cleanup(drm_dev);
 err_drm_dev_put:
diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.h b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.h
index 4d5c05a24065..dee8ec2f7f2e 100644
--- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.h
+++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.h
@@ -37,7 +37,6 @@ struct kirin_drm_data {
 	u32 channel_formats_cnt;
 	int config_max_width;
 	int config_max_height;
-	bool register_connects;
 	u32 num_planes;
 	u32 prim_plane;
 
diff --git a/drivers/gpu/drm/i2c/sil164_drv.c b/drivers/gpu/drm/i2c/sil164_drv.c
index a839f78a4c8a..741886b54419 100644
--- a/drivers/gpu/drm/i2c/sil164_drv.c
+++ b/drivers/gpu/drm/i2c/sil164_drv.c
@@ -393,7 +393,7 @@ sil164_detect_slave(struct i2c_client *client)
 		return NULL;
 	}
 
-	return i2c_new_device(adap, &info);
+	return i2c_new_client_device(adap, &info);
 }
 
 static int
@@ -402,6 +402,7 @@ sil164_encoder_init(struct i2c_client *client,
 		    struct drm_encoder_slave *encoder)
 {
 	struct sil164_priv *priv;
+	struct i2c_client *slave_client;
 
 	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 	if (!priv)
@@ -410,7 +411,9 @@ sil164_encoder_init(struct i2c_client *client,
 	encoder->slave_priv = priv;
 	encoder->slave_funcs = &sil164_encoder_funcs;
 
-	priv->duallink_slave = sil164_detect_slave(client);
+	slave_client = sil164_detect_slave(client);
+	if (!IS_ERR(slave_client))
+		priv->duallink_slave = slave_client;
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index c3332209f27a..3c90d7ae09d6 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -19,6 +19,7 @@
 #include <drm/drm_of.h>
 #include <drm/drm_print.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 #include <drm/i2c/tda998x.h>
 
 #include <media/cec-notifier.h>
@@ -1949,9 +1950,9 @@ static int tda998x_create(struct device *dev)
 	cec_info.platform_data = &priv->cec_glue;
 	cec_info.irq = client->irq;
 
-	priv->cec = i2c_new_device(client->adapter, &cec_info);
-	if (!priv->cec) {
-		ret = -ENODEV;
+	priv->cec = i2c_new_client_device(client->adapter, &cec_info);
+	if (IS_ERR(priv->cec)) {
+		ret = PTR_ERR(priv->cec);
 		goto fail;
 	}
 
@@ -1997,15 +1998,6 @@ static int tda998x_create(struct device *dev)
 
 /* DRM encoder functions */
 
-static void tda998x_encoder_destroy(struct drm_encoder *encoder)
-{
-	drm_encoder_cleanup(encoder);
-}
-
-static const struct drm_encoder_funcs tda998x_encoder_funcs = {
-	.destroy = tda998x_encoder_destroy,
-};
-
 static int tda998x_encoder_init(struct device *dev, struct drm_device *drm)
 {
 	struct tda998x_priv *priv = dev_get_drvdata(dev);
@@ -2023,8 +2015,8 @@ static int tda998x_encoder_init(struct device *dev, struct drm_device *drm)
 
 	priv->encoder.possible_crtcs = crtcs;
 
-	ret = drm_encoder_init(drm, &priv->encoder, &tda998x_encoder_funcs,
-			       DRM_MODE_ENCODER_TMDS, NULL);
+	ret = drm_simple_encoder_init(drm, &priv->encoder,
+				      DRM_MODE_ENCODER_TMDS);
 	if (ret)
 		goto err_encoder;
 
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 6cd1f6253814..44c506b7e117 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -89,6 +89,7 @@ gt-y += \
 	gt/intel_engine_pool.o \
 	gt/intel_engine_user.o \
 	gt/intel_ggtt.o \
+	gt/intel_ggtt_fencing.o \
 	gt/intel_gt.o \
 	gt/intel_gt_irq.o \
 	gt/intel_gt_pm.o \
@@ -150,7 +151,6 @@ i915-y += \
 	  i915_buddy.o \
 	  i915_cmd_parser.o \
 	  i915_gem_evict.o \
-	  i915_gem_fence_reg.o \
 	  i915_gem_gtt.o \
 	  i915_gem.o \
 	  i915_globals.o \
@@ -164,14 +164,18 @@ i915-y += \
 
 # general-purpose microcontroller (GuC) support
 i915-y += gt/uc/intel_uc.o \
+	  gt/uc/intel_uc_debugfs.o \
 	  gt/uc/intel_uc_fw.o \
 	  gt/uc/intel_guc.o \
 	  gt/uc/intel_guc_ads.o \
 	  gt/uc/intel_guc_ct.o \
+	  gt/uc/intel_guc_debugfs.o \
 	  gt/uc/intel_guc_fw.o \
 	  gt/uc/intel_guc_log.o \
+	  gt/uc/intel_guc_log_debugfs.o \
 	  gt/uc/intel_guc_submission.o \
 	  gt/uc/intel_huc.o \
+	  gt/uc/intel_huc_debugfs.o \
 	  gt/uc/intel_huc_fw.o
 
 # modesetting core code
@@ -240,23 +244,6 @@ i915-y += \
 	display/vlv_dsi.o \
 	display/vlv_dsi_pll.o
 
-# perf code
-i915-y += \
-	oa/i915_oa_hsw.o \
-	oa/i915_oa_bdw.o \
-	oa/i915_oa_chv.o \
-	oa/i915_oa_sklgt2.o \
-	oa/i915_oa_sklgt3.o \
-	oa/i915_oa_sklgt4.o \
-	oa/i915_oa_bxt.o \
-	oa/i915_oa_kblgt2.o \
-	oa/i915_oa_kblgt3.o \
-	oa/i915_oa_glk.o \
-	oa/i915_oa_cflgt2.o \
-	oa/i915_oa_cflgt3.o \
-	oa/i915_oa_cnl.o \
-	oa/i915_oa_icl.o \
-	oa/i915_oa_tgl.o
 i915-y += i915_perf.o
 
 # Post-mortem debug and GPU hang state capture
diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
index 17cee6f80d8b..99a25c0bb08f 100644
--- a/drivers/gpu/drm/i915/display/icl_dsi.c
+++ b/drivers/gpu/drm/i915/display/icl_dsi.c
@@ -186,16 +186,19 @@ static int dsi_send_pkt_hdr(struct intel_dsi_host *host,
 static int dsi_send_pkt_payld(struct intel_dsi_host *host,
 			      struct mipi_dsi_packet pkt)
 {
+	struct intel_dsi *intel_dsi = host->intel_dsi;
+	struct drm_i915_private *i915 = to_i915(intel_dsi->base.base.dev);
+
 	/* payload queue can accept *256 bytes*, check limit */
 	if (pkt.payload_length > MAX_PLOAD_CREDIT * 4) {
-		DRM_ERROR("payload size exceeds max queue limit\n");
+		drm_err(&i915->drm, "payload size exceeds max queue limit\n");
 		return -1;
 	}
 
 	/* load data into command payload queue */
 	if (!add_payld_to_queue(host, pkt.payload,
 				pkt.payload_length)) {
-		DRM_ERROR("adding payload to queue failed\n");
+		drm_err(&i915->drm, "adding payload to queue failed\n");
 		return -1;
 	}
 
@@ -744,6 +747,18 @@ gen11_dsi_configure_transcoder(struct intel_encoder *encoder,
 				tmp |= VIDEO_MODE_SYNC_PULSE;
 				break;
 			}
+		} else {
+			/*
+			 * FIXME: Retrieve this info from VBT.
+			 * As per the spec when dsi transcoder is operating
+			 * in TE GATE mode, TE comes from GPIO
+			 * which is UTIL PIN for DSI 0.
+			 * Also this GPIO would not be used for other
+			 * purposes is an assumption.
+			 */
+			tmp &= ~OP_MODE_MASK;
+			tmp |= CMD_MODE_TE_GATE;
+			tmp |= TE_SOURCE_GPIO;
 		}
 
 		intel_de_write(dev_priv, DSI_TRANS_FUNC_CONF(dsi_trans), tmp);
@@ -837,14 +852,33 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder,
 	}
 
 	hactive = adjusted_mode->crtc_hdisplay;
-	htotal = DIV_ROUND_UP(adjusted_mode->crtc_htotal * mul, div);
+
+	if (is_vid_mode(intel_dsi))
+		htotal = DIV_ROUND_UP(adjusted_mode->crtc_htotal * mul, div);
+	else
+		htotal = DIV_ROUND_UP((hactive + 160) * mul, div);
+
 	hsync_start = DIV_ROUND_UP(adjusted_mode->crtc_hsync_start * mul, div);
 	hsync_end = DIV_ROUND_UP(adjusted_mode->crtc_hsync_end * mul, div);
 	hsync_size  = hsync_end - hsync_start;
 	hback_porch = (adjusted_mode->crtc_htotal -
 		       adjusted_mode->crtc_hsync_end);
 	vactive = adjusted_mode->crtc_vdisplay;
-	vtotal = adjusted_mode->crtc_vtotal;
+
+	if (is_vid_mode(intel_dsi)) {
+		vtotal = adjusted_mode->crtc_vtotal;
+	} else {
+		int bpp, line_time_us, byte_clk_period_ns;
+
+		if (crtc_state->dsc.compression_enable)
+			bpp = crtc_state->dsc.compressed_bpp;
+		else
+			bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format);
+
+		byte_clk_period_ns = 1000000 / afe_clk(encoder, crtc_state);
+		line_time_us = (htotal * (bpp / 8) * byte_clk_period_ns) / (1000 * intel_dsi->lane_count);
+		vtotal = vactive + DIV_ROUND_UP(400, line_time_us);
+	}
 	vsync_start = adjusted_mode->crtc_vsync_start;
 	vsync_end = adjusted_mode->crtc_vsync_end;
 	vsync_shift = hsync_start - htotal / 2;
@@ -873,7 +907,7 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder,
 	}
 
 	/* TRANS_HSYNC register to be programmed only for video mode */
-	if (intel_dsi->operation_mode == INTEL_DSI_VIDEO_MODE) {
+	if (is_vid_mode(intel_dsi)) {
 		if (intel_dsi->video_mode_format ==
 		    VIDEO_MODE_NON_BURST_WITH_SYNC_PULSE) {
 			/* BSPEC: hsync size should be atleast 16 pixels */
@@ -916,22 +950,27 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder,
 	if (vsync_start < vactive)
 		drm_err(&dev_priv->drm, "vsync_start less than vactive\n");
 
-	/* program TRANS_VSYNC register */
-	for_each_dsi_port(port, intel_dsi->ports) {
-		dsi_trans = dsi_port_to_transcoder(port);
-		intel_de_write(dev_priv, VSYNC(dsi_trans),
-			       (vsync_start - 1) | ((vsync_end - 1) << 16));
+	/* program TRANS_VSYNC register for video mode only */
+	if (is_vid_mode(intel_dsi)) {
+		for_each_dsi_port(port, intel_dsi->ports) {
+			dsi_trans = dsi_port_to_transcoder(port);
+			intel_de_write(dev_priv, VSYNC(dsi_trans),
+				       (vsync_start - 1) | ((vsync_end - 1) << 16));
+		}
 	}
 
 	/*
-	 * FIXME: It has to be programmed only for interlaced
+	 * FIXME: It has to be programmed only for video modes and interlaced
 	 * modes. Put the check condition here once interlaced
 	 * info available as described above.
 	 * program TRANS_VSYNCSHIFT register
 	 */
-	for_each_dsi_port(port, intel_dsi->ports) {
-		dsi_trans = dsi_port_to_transcoder(port);
-		intel_de_write(dev_priv, VSYNCSHIFT(dsi_trans), vsync_shift);
+	if (is_vid_mode(intel_dsi)) {
+		for_each_dsi_port(port, intel_dsi->ports) {
+			dsi_trans = dsi_port_to_transcoder(port);
+			intel_de_write(dev_priv, VSYNCSHIFT(dsi_trans),
+				       vsync_shift);
+		}
 	}
 
 	/* program TRANS_VBLANK register, should be same as vtotal programmed */
@@ -1016,6 +1055,32 @@ static void gen11_dsi_setup_timeouts(struct intel_encoder *encoder,
 	}
 }
 
+static void gen11_dsi_config_util_pin(struct intel_encoder *encoder,
+				      bool enable)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+	u32 tmp;
+
+	/*
+	 * used as TE i/p for DSI0,
+	 * for dual link/DSI1 TE is from slave DSI1
+	 * through GPIO.
+	 */
+	if (is_vid_mode(intel_dsi) || (intel_dsi->ports & BIT(PORT_B)))
+		return;
+
+	tmp = intel_de_read(dev_priv, UTIL_PIN_CTL);
+
+	if (enable) {
+		tmp |= UTIL_PIN_DIRECTION_INPUT;
+		tmp |= UTIL_PIN_ENABLE;
+	} else {
+		tmp &= ~UTIL_PIN_ENABLE;
+	}
+	intel_de_write(dev_priv, UTIL_PIN_CTL, tmp);
+}
+
 static void
 gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder,
 			      const struct intel_crtc_state *crtc_state)
@@ -1037,6 +1102,9 @@ gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder,
 	/* setup D-PHY timings */
 	gen11_dsi_setup_dphy_timings(encoder, crtc_state);
 
+	/* Since transcoder is configured to take events from GPIO */
+	gen11_dsi_config_util_pin(encoder, true);
+
 	/* step 4h: setup DSI protocol timeouts */
 	gen11_dsi_setup_timeouts(encoder, crtc_state);
 
@@ -1088,7 +1156,8 @@ static void gen11_dsi_powerup_panel(struct intel_encoder *encoder)
 	wait_for_cmds_dispatched_to_panel(encoder);
 }
 
-static void gen11_dsi_pre_pll_enable(struct intel_encoder *encoder,
+static void gen11_dsi_pre_pll_enable(struct intel_atomic_state *state,
+				     struct intel_encoder *encoder,
 				     const struct intel_crtc_state *crtc_state,
 				     const struct drm_connector_state *conn_state)
 {
@@ -1099,7 +1168,8 @@ static void gen11_dsi_pre_pll_enable(struct intel_encoder *encoder,
 	gen11_dsi_program_esc_clk_div(encoder, crtc_state);
 }
 
-static void gen11_dsi_pre_enable(struct intel_encoder *encoder,
+static void gen11_dsi_pre_enable(struct intel_atomic_state *state,
+				 struct intel_encoder *encoder,
 				 const struct intel_crtc_state *pipe_config,
 				 const struct drm_connector_state *conn_state)
 {
@@ -1118,7 +1188,8 @@ static void gen11_dsi_pre_enable(struct intel_encoder *encoder,
 	gen11_dsi_set_transcoder_timings(encoder, pipe_config);
 }
 
-static void gen11_dsi_enable(struct intel_encoder *encoder,
+static void gen11_dsi_enable(struct intel_atomic_state *state,
+			     struct intel_encoder *encoder,
 			     const struct intel_crtc_state *crtc_state,
 			     const struct drm_connector_state *conn_state)
 {
@@ -1180,6 +1251,15 @@ static void gen11_dsi_deconfigure_trancoder(struct intel_encoder *encoder)
 	enum transcoder dsi_trans;
 	u32 tmp;
 
+	/* disable periodic update mode */
+	if (is_cmd_mode(intel_dsi)) {
+		for_each_dsi_port(port, intel_dsi->ports) {
+			tmp = intel_de_read(dev_priv, DSI_CMD_FRMCTL(port));
+			tmp &= ~DSI_PERIODIC_FRAME_UPDATE_ENABLE;
+			intel_de_write(dev_priv, DSI_CMD_FRMCTL(port), tmp);
+		}
+	}
+
 	/* put dsi link in ULPS */
 	for_each_dsi_port(port, intel_dsi->ports) {
 		dsi_trans = dsi_port_to_transcoder(port);
@@ -1264,7 +1344,8 @@ static void gen11_dsi_disable_io_power(struct intel_encoder *encoder)
 	}
 }
 
-static void gen11_dsi_disable(struct intel_encoder *encoder,
+static void gen11_dsi_disable(struct intel_atomic_state *state,
+			      struct intel_encoder *encoder,
 			      const struct intel_crtc_state *old_crtc_state,
 			      const struct drm_connector_state *old_conn_state)
 {
@@ -1286,11 +1367,14 @@ static void gen11_dsi_disable(struct intel_encoder *encoder,
 	/* step3: disable port */
 	gen11_dsi_disable_port(encoder);
 
+	gen11_dsi_config_util_pin(encoder, false);
+
 	/* step4: disable IO power */
 	gen11_dsi_disable_io_power(encoder);
 }
 
-static void gen11_dsi_post_disable(struct intel_encoder *encoder,
+static void gen11_dsi_post_disable(struct intel_atomic_state *state,
+				   struct intel_encoder *encoder,
 				   const struct intel_crtc_state *old_crtc_state,
 				   const struct drm_connector_state *old_conn_state)
 {
@@ -1347,6 +1431,22 @@ static void gen11_dsi_get_timings(struct intel_encoder *encoder,
 	adjusted_mode->crtc_vblank_end = adjusted_mode->crtc_vtotal;
 }
 
+static bool gen11_dsi_is_periodic_cmd_mode(struct intel_dsi *intel_dsi)
+{
+	struct drm_device *dev = intel_dsi->base.base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	enum transcoder dsi_trans;
+	u32 val;
+
+	if (intel_dsi->ports == BIT(PORT_B))
+		dsi_trans = TRANSCODER_DSI_1;
+	else
+		dsi_trans = TRANSCODER_DSI_0;
+
+	val = intel_de_read(dev_priv, DSI_TRANS_FUNC_CONF(dsi_trans));
+	return (val & DSI_PERIODIC_FRAME_UPDATE_ENABLE);
+}
+
 static void gen11_dsi_get_config(struct intel_encoder *encoder,
 				 struct intel_crtc_state *pipe_config)
 {
@@ -1367,6 +1467,10 @@ static void gen11_dsi_get_config(struct intel_encoder *encoder,
 	gen11_dsi_get_timings(encoder, pipe_config);
 	pipe_config->output_types |= BIT(INTEL_OUTPUT_DSI);
 	pipe_config->pipe_bpp = bdw_get_pipemisc_bpp(crtc);
+
+	if (gen11_dsi_is_periodic_cmd_mode(intel_dsi))
+		pipe_config->hw.adjusted_mode.private_flags |=
+					I915_MODE_FLAG_DSI_PERIODIC_CMD_MODE;
 }
 
 static int gen11_dsi_dsc_compute_config(struct intel_encoder *encoder,
@@ -1417,6 +1521,7 @@ static int gen11_dsi_compute_config(struct intel_encoder *encoder,
 				    struct intel_crtc_state *pipe_config,
 				    struct drm_connector_state *conn_state)
 {
+	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
 	struct intel_dsi *intel_dsi = container_of(encoder, struct intel_dsi,
 						   base);
 	struct intel_connector *intel_connector = intel_dsi->attached_connector;
@@ -1446,10 +1551,32 @@ static int gen11_dsi_compute_config(struct intel_encoder *encoder,
 	pipe_config->clock_set = true;
 
 	if (gen11_dsi_dsc_compute_config(encoder, pipe_config))
-		DRM_DEBUG_KMS("Attempting to use DSC failed\n");
+		drm_dbg_kms(&i915->drm, "Attempting to use DSC failed\n");
 
 	pipe_config->port_clock = afe_clk(encoder, pipe_config) / 5;
 
+	/* We would not operate in periodic command mode */
+	pipe_config->hw.adjusted_mode.private_flags &=
+					~I915_MODE_FLAG_DSI_PERIODIC_CMD_MODE;
+
+	/*
+	 * In case of TE GATE cmd mode, we
+	 * receive TE from the slave if
+	 * dual link is enabled
+	 */
+	if (is_cmd_mode(intel_dsi)) {
+		if (intel_dsi->ports == (BIT(PORT_B) | BIT(PORT_A)))
+			pipe_config->hw.adjusted_mode.private_flags |=
+						I915_MODE_FLAG_DSI_USE_TE1 |
+						I915_MODE_FLAG_DSI_USE_TE0;
+		else if (intel_dsi->ports == BIT(PORT_B))
+			pipe_config->hw.adjusted_mode.private_flags |=
+						I915_MODE_FLAG_DSI_USE_TE1;
+		else
+			pipe_config->hw.adjusted_mode.private_flags |=
+						I915_MODE_FLAG_DSI_USE_TE0;
+	}
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index 457b258683d3..25dfeb3197aa 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -264,6 +264,20 @@ void intel_plane_copy_uapi_to_hw_state(struct intel_plane_state *plane_state,
 	plane_state->hw.color_range = from_plane_state->uapi.color_range;
 }
 
+void intel_plane_set_invisible(struct intel_crtc_state *crtc_state,
+			       struct intel_plane_state *plane_state)
+{
+	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
+
+	crtc_state->active_planes &= ~BIT(plane->id);
+	crtc_state->nv12_planes &= ~BIT(plane->id);
+	crtc_state->c8_planes &= ~BIT(plane->id);
+	crtc_state->data_rate[plane->id] = 0;
+	crtc_state->min_cdclk[plane->id] = 0;
+
+	plane_state->uapi.visible = false;
+}
+
 int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_state,
 					struct intel_crtc_state *new_crtc_state,
 					const struct intel_plane_state *old_plane_state,
@@ -273,12 +287,7 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
 	const struct drm_framebuffer *fb = new_plane_state->hw.fb;
 	int ret;
 
-	new_crtc_state->active_planes &= ~BIT(plane->id);
-	new_crtc_state->nv12_planes &= ~BIT(plane->id);
-	new_crtc_state->c8_planes &= ~BIT(plane->id);
-	new_crtc_state->data_rate[plane->id] = 0;
-	new_crtc_state->min_cdclk[plane->id] = 0;
-	new_plane_state->uapi.visible = false;
+	intel_plane_set_invisible(new_crtc_state, new_plane_state);
 
 	if (!new_plane_state->hw.crtc && !old_plane_state->hw.crtc)
 		return 0;
diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
index a6bbf42bae1f..59dd1fbb02ea 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
@@ -52,5 +52,7 @@ int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_stat
 int intel_plane_calc_min_cdclk(struct intel_atomic_state *state,
 			       struct intel_plane *plane,
 			       bool *need_cdclk_calc);
+void intel_plane_set_invisible(struct intel_crtc_state *crtc_state,
+			       struct intel_plane_state *plane_state);
 
 #endif /* __INTEL_ATOMIC_PLANE_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c
index 62f234f641de..57b80971ae78 100644
--- a/drivers/gpu/drm/i915/display/intel_audio.c
+++ b/drivers/gpu/drm/i915/display/intel_audio.c
@@ -252,14 +252,16 @@ static u32 audio_config_hdmi_pixel_clock(const struct intel_crtc_state *crtc_sta
 		i = ARRAY_SIZE(hdmi_audio_clock);
 
 	if (i == ARRAY_SIZE(hdmi_audio_clock)) {
-		DRM_DEBUG_KMS("HDMI audio pixel clock setting for %d not found, falling back to defaults\n",
-			      adjusted_mode->crtc_clock);
+		drm_dbg_kms(&dev_priv->drm,
+			    "HDMI audio pixel clock setting for %d not found, falling back to defaults\n",
+			    adjusted_mode->crtc_clock);
 		i = 1;
 	}
 
-	DRM_DEBUG_KMS("Configuring HDMI audio for pixel clock %d (0x%08x)\n",
-		      hdmi_audio_clock[i].clock,
-		      hdmi_audio_clock[i].config);
+	drm_dbg_kms(&dev_priv->drm,
+		    "Configuring HDMI audio for pixel clock %d (0x%08x)\n",
+		    hdmi_audio_clock[i].clock,
+		    hdmi_audio_clock[i].config);
 
 	return hdmi_audio_clock[i].config;
 }
@@ -891,7 +893,7 @@ static unsigned long i915_audio_component_get_power(struct device *kdev)
 	ret = intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
 
 	if (dev_priv->audio_power_refcount++ == 0) {
-		if (IS_TIGERLAKE(dev_priv) || IS_ICELAKE(dev_priv)) {
+		if (INTEL_GEN(dev_priv) >= 9) {
 			intel_de_write(dev_priv, AUD_FREQ_CNTRL,
 				       dev_priv->audio_freq_cntrl);
 			drm_dbg_kms(&dev_priv->drm,
@@ -931,7 +933,7 @@ static void i915_audio_component_codec_wake_override(struct device *kdev,
 	unsigned long cookie;
 	u32 tmp;
 
-	if (!IS_GEN(dev_priv, 9))
+	if (INTEL_GEN(dev_priv) < 9)
 		return;
 
 	cookie = i915_audio_component_get_power(kdev);
@@ -1173,7 +1175,7 @@ static void i915_audio_component_init(struct drm_i915_private *dev_priv)
 		return;
 	}
 
-	if (IS_TIGERLAKE(dev_priv) || IS_ICELAKE(dev_priv)) {
+	if (INTEL_GEN(dev_priv) >= 9) {
 		dev_priv->audio_freq_cntrl = intel_de_read(dev_priv,
 							   AUD_FREQ_CNTRL);
 		drm_dbg_kms(&dev_priv->drm,
diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c
index 58b264bc318d..88f367eb28ea 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.c
+++ b/drivers/gpu/drm/i915/display/intel_bw.c
@@ -338,16 +338,17 @@ void intel_bw_crtc_update(struct intel_bw_state *bw_state,
 			  const struct intel_crtc_state *crtc_state)
 {
 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
 
 	bw_state->data_rate[crtc->pipe] =
 		intel_bw_crtc_data_rate(crtc_state);
 	bw_state->num_active_planes[crtc->pipe] =
 		intel_bw_crtc_num_active_planes(crtc_state);
 
-	DRM_DEBUG_KMS("pipe %c data rate %u num active planes %u\n",
-		      pipe_name(crtc->pipe),
-		      bw_state->data_rate[crtc->pipe],
-		      bw_state->num_active_planes[crtc->pipe]);
+	drm_dbg_kms(&i915->drm, "pipe %c data rate %u num active planes %u\n",
+		    pipe_name(crtc->pipe),
+		    bw_state->data_rate[crtc->pipe],
+		    bw_state->num_active_planes[crtc->pipe]);
 }
 
 static unsigned int intel_bw_num_active_planes(struct drm_i915_private *dev_priv,
diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c
index c1cce93a1c25..98ece9cd7cdd 100644
--- a/drivers/gpu/drm/i915/display/intel_color.c
+++ b/drivers/gpu/drm/i915/display/intel_color.c
@@ -460,6 +460,16 @@ static void ilk_lut_10_pack(struct drm_color_lut *entry, u32 val)
 	entry->blue = intel_color_lut_pack(REG_FIELD_GET(PREC_PALETTE_BLUE_MASK, val), 10);
 }
 
+static void icl_lut_multi_seg_pack(struct drm_color_lut *entry, u32 ldw, u32 udw)
+{
+	entry->red = REG_FIELD_GET(PAL_PREC_MULTI_SEG_RED_UDW_MASK, udw) << 6 |
+				   REG_FIELD_GET(PAL_PREC_MULTI_SEG_RED_LDW_MASK, ldw);
+	entry->green = REG_FIELD_GET(PAL_PREC_MULTI_SEG_GREEN_UDW_MASK, udw) << 6 |
+				     REG_FIELD_GET(PAL_PREC_MULTI_SEG_GREEN_LDW_MASK, ldw);
+	entry->blue = REG_FIELD_GET(PAL_PREC_MULTI_SEG_BLUE_UDW_MASK, udw) << 6 |
+				    REG_FIELD_GET(PAL_PREC_MULTI_SEG_BLUE_LDW_MASK, ldw);
+}
+
 static void i9xx_color_commit(const struct intel_crtc_state *crtc_state)
 {
 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
@@ -893,7 +903,7 @@ icl_load_gcmax(const struct intel_crtc_state *crtc_state,
 	struct intel_dsb *dsb = intel_dsb_get(crtc);
 	enum pipe pipe = crtc->pipe;
 
-	/* Fixme: LUT entries are 16 bit only, so we can prog 0xFFFF max */
+	/* FIXME LUT entries are 16 bit only, so we can prog 0xFFFF max */
 	intel_dsb_reg_write(dsb, PREC_PAL_GC_MAX(pipe, 0), color->red);
 	intel_dsb_reg_write(dsb, PREC_PAL_GC_MAX(pipe, 1), color->green);
 	intel_dsb_reg_write(dsb, PREC_PAL_GC_MAX(pipe, 2), color->blue);
@@ -1630,6 +1640,24 @@ static int glk_gamma_precision(const struct intel_crtc_state *crtc_state)
 	}
 }
 
+static int icl_gamma_precision(const struct intel_crtc_state *crtc_state)
+{
+	if ((crtc_state->gamma_mode & POST_CSC_GAMMA_ENABLE) == 0)
+		return 0;
+
+	switch (crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) {
+	case GAMMA_MODE_MODE_8BIT:
+		return 8;
+	case GAMMA_MODE_MODE_10BIT:
+		return 10;
+	case GAMMA_MODE_MODE_12BIT_MULTI_SEGMENTED:
+		return 16;
+	default:
+		MISSING_CASE(crtc_state->gamma_mode);
+		return 0;
+	}
+}
+
 int intel_color_get_gamma_bit_precision(const struct intel_crtc_state *crtc_state)
 {
 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
@@ -1641,7 +1669,9 @@ int intel_color_get_gamma_bit_precision(const struct intel_crtc_state *crtc_stat
 		else
 			return i9xx_gamma_precision(crtc_state);
 	} else {
-		if (IS_CANNONLAKE(dev_priv) || IS_GEMINILAKE(dev_priv))
+		if (INTEL_GEN(dev_priv) >= 11)
+			return icl_gamma_precision(crtc_state);
+		else if (IS_CANNONLAKE(dev_priv) || IS_GEMINILAKE(dev_priv))
 			return glk_gamma_precision(crtc_state);
 		else if (IS_IRONLAKE(dev_priv))
 			return ilk_gamma_precision(crtc_state);
@@ -1658,9 +1688,9 @@ static bool err_check(struct drm_color_lut *lut1,
 		((abs((long)lut2->green - lut1->green)) <= err);
 }
 
-static bool intel_color_lut_entry_equal(struct drm_color_lut *lut1,
-					struct drm_color_lut *lut2,
-					int lut_size, u32 err)
+static bool intel_color_lut_entries_equal(struct drm_color_lut *lut1,
+					  struct drm_color_lut *lut2,
+					  int lut_size, u32 err)
 {
 	int i;
 
@@ -1690,16 +1720,8 @@ bool intel_color_lut_equal(struct drm_property_blob *blob1,
 	lut_size2 = drm_color_lut_size(blob2);
 
 	/* check sw and hw lut size */
-	switch (gamma_mode) {
-	case GAMMA_MODE_MODE_8BIT:
-	case GAMMA_MODE_MODE_10BIT:
-		if (lut_size1 != lut_size2)
-			return false;
-		break;
-	default:
-		MISSING_CASE(gamma_mode);
-			return false;
-	}
+	if (lut_size1 != lut_size2)
+		return false;
 
 	lut1 = blob1->data;
 	lut2 = blob2->data;
@@ -1707,11 +1729,16 @@ bool intel_color_lut_equal(struct drm_property_blob *blob1,
 	err = 0xffff >> bit_precision;
 
 	/* check sw and hw lut entry to be equal */
-	switch (gamma_mode) {
+	switch (gamma_mode & GAMMA_MODE_MODE_MASK) {
 	case GAMMA_MODE_MODE_8BIT:
 	case GAMMA_MODE_MODE_10BIT:
-		if (!intel_color_lut_entry_equal(lut1, lut2,
-						 lut_size2, err))
+		if (!intel_color_lut_entries_equal(lut1, lut2,
+						   lut_size2, err))
+			return false;
+		break;
+	case GAMMA_MODE_MODE_12BIT_MULTI_SEGMENTED:
+		if (!intel_color_lut_entries_equal(lut1, lut2,
+						   9, err))
 			return false;
 		break;
 	default:
@@ -1946,6 +1973,63 @@ static void glk_read_luts(struct intel_crtc_state *crtc_state)
 		crtc_state->hw.gamma_lut = glk_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0));
 }
 
+static struct drm_property_blob *
+icl_read_lut_multi_segment(struct intel_crtc *crtc)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	int i, lut_size = INTEL_INFO(dev_priv)->color.gamma_lut_size;
+	enum pipe pipe = crtc->pipe;
+	struct drm_property_blob *blob;
+	struct drm_color_lut *lut;
+
+	blob = drm_property_create_blob(&dev_priv->drm,
+					sizeof(struct drm_color_lut) * lut_size,
+					NULL);
+	if (IS_ERR(blob))
+		return NULL;
+
+	lut = blob->data;
+
+	intel_de_write(dev_priv, PREC_PAL_MULTI_SEG_INDEX(pipe),
+		       PAL_PREC_AUTO_INCREMENT);
+
+	for (i = 0; i < 9; i++) {
+		u32 ldw = intel_de_read(dev_priv, PREC_PAL_MULTI_SEG_DATA(pipe));
+		u32 udw = intel_de_read(dev_priv, PREC_PAL_MULTI_SEG_DATA(pipe));
+
+		icl_lut_multi_seg_pack(&lut[i], ldw, udw);
+	}
+
+	intel_de_write(dev_priv, PREC_PAL_MULTI_SEG_INDEX(pipe), 0);
+
+	/*
+	 * FIXME readouts from PAL_PREC_DATA register aren't giving
+	 * correct values in the case of fine and coarse segments.
+	 * Restricting readouts only for super fine segment as of now.
+	 */
+
+	return blob;
+}
+
+static void icl_read_luts(struct intel_crtc_state *crtc_state)
+{
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+
+	if ((crtc_state->gamma_mode & POST_CSC_GAMMA_ENABLE) == 0)
+		return;
+
+	switch (crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) {
+	case GAMMA_MODE_MODE_8BIT:
+		crtc_state->hw.gamma_lut = ilk_read_lut_8(crtc);
+		break;
+	case GAMMA_MODE_MODE_12BIT_MULTI_SEGMENTED:
+		crtc_state->hw.gamma_lut = icl_read_lut_multi_segment(crtc);
+		break;
+	default:
+		crtc_state->hw.gamma_lut = glk_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0));
+	}
+}
+
 void intel_color_init(struct intel_crtc *crtc)
 {
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
@@ -1989,6 +2073,7 @@ void intel_color_init(struct intel_crtc *crtc)
 
 		if (INTEL_GEN(dev_priv) >= 11) {
 			dev_priv->display.load_luts = icl_load_luts;
+			dev_priv->display.read_luts = icl_read_luts;
 		} else if (IS_CANNONLAKE(dev_priv) || IS_GEMINILAKE(dev_priv)) {
 			dev_priv->display.load_luts = glk_load_luts;
 			dev_priv->display.read_luts = glk_read_luts;
diff --git a/drivers/gpu/drm/i915/display/intel_connector.c b/drivers/gpu/drm/i915/display/intel_connector.c
index 903e49659f56..98ec2ea86c7c 100644
--- a/drivers/gpu/drm/i915/display/intel_connector.c
+++ b/drivers/gpu/drm/i915/display/intel_connector.c
@@ -290,7 +290,7 @@ intel_attach_colorspace_property(struct drm_connector *connector)
 			return;
 		break;
 	default:
-		DRM_DEBUG_KMS("Colorspace property not supported\n");
+		MISSING_CASE(connector->connector_type);
 		return;
 	}
 
diff --git a/drivers/gpu/drm/i915/display/intel_crt.c b/drivers/gpu/drm/i915/display/intel_crt.c
index 78f9b6cde810..a59ecbed0004 100644
--- a/drivers/gpu/drm/i915/display/intel_crt.c
+++ b/drivers/gpu/drm/i915/display/intel_crt.c
@@ -203,27 +203,31 @@ static void intel_crt_set_dpms(struct intel_encoder *encoder,
 	intel_de_write(dev_priv, crt->adpa_reg, adpa);
 }
 
-static void intel_disable_crt(struct intel_encoder *encoder,
+static void intel_disable_crt(struct intel_atomic_state *state,
+			      struct intel_encoder *encoder,
 			      const struct intel_crtc_state *old_crtc_state,
 			      const struct drm_connector_state *old_conn_state)
 {
 	intel_crt_set_dpms(encoder, old_crtc_state, DRM_MODE_DPMS_OFF);
 }
 
-static void pch_disable_crt(struct intel_encoder *encoder,
+static void pch_disable_crt(struct intel_atomic_state *state,
+			    struct intel_encoder *encoder,
 			    const struct intel_crtc_state *old_crtc_state,
 			    const struct drm_connector_state *old_conn_state)
 {
 }
 
-static void pch_post_disable_crt(struct intel_encoder *encoder,
+static void pch_post_disable_crt(struct intel_atomic_state *state,
+				 struct intel_encoder *encoder,
 				 const struct intel_crtc_state *old_crtc_state,
 				 const struct drm_connector_state *old_conn_state)
 {
-	intel_disable_crt(encoder, old_crtc_state, old_conn_state);
+	intel_disable_crt(state, encoder, old_crtc_state, old_conn_state);
 }
 
-static void hsw_disable_crt(struct intel_encoder *encoder,
+static void hsw_disable_crt(struct intel_atomic_state *state,
+			    struct intel_encoder *encoder,
 			    const struct intel_crtc_state *old_crtc_state,
 			    const struct drm_connector_state *old_conn_state)
 {
@@ -234,7 +238,8 @@ static void hsw_disable_crt(struct intel_encoder *encoder,
 	intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false);
 }
 
-static void hsw_post_disable_crt(struct intel_encoder *encoder,
+static void hsw_post_disable_crt(struct intel_atomic_state *state,
+				 struct intel_encoder *encoder,
 				 const struct intel_crtc_state *old_crtc_state,
 				 const struct drm_connector_state *old_conn_state)
 {
@@ -250,19 +255,20 @@ static void hsw_post_disable_crt(struct intel_encoder *encoder,
 
 	intel_ddi_disable_pipe_clock(old_crtc_state);
 
-	pch_post_disable_crt(encoder, old_crtc_state, old_conn_state);
+	pch_post_disable_crt(state, encoder, old_crtc_state, old_conn_state);
 
 	lpt_disable_pch_transcoder(dev_priv);
 	lpt_disable_iclkip(dev_priv);
 
-	intel_ddi_fdi_post_disable(encoder, old_crtc_state, old_conn_state);
+	intel_ddi_fdi_post_disable(state, encoder, old_crtc_state, old_conn_state);
 
 	drm_WARN_ON(&dev_priv->drm, !old_crtc_state->has_pch_encoder);
 
 	intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true);
 }
 
-static void hsw_pre_pll_enable_crt(struct intel_encoder *encoder,
+static void hsw_pre_pll_enable_crt(struct intel_atomic_state *state,
+				   struct intel_encoder *encoder,
 				   const struct intel_crtc_state *crtc_state,
 				   const struct drm_connector_state *conn_state)
 {
@@ -273,7 +279,8 @@ static void hsw_pre_pll_enable_crt(struct intel_encoder *encoder,
 	intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false);
 }
 
-static void hsw_pre_enable_crt(struct intel_encoder *encoder,
+static void hsw_pre_enable_crt(struct intel_atomic_state *state,
+			       struct intel_encoder *encoder,
 			       const struct intel_crtc_state *crtc_state,
 			       const struct drm_connector_state *conn_state)
 {
@@ -290,7 +297,8 @@ static void hsw_pre_enable_crt(struct intel_encoder *encoder,
 	intel_ddi_enable_pipe_clock(crtc_state);
 }
 
-static void hsw_enable_crt(struct intel_encoder *encoder,
+static void hsw_enable_crt(struct intel_atomic_state *state,
+			   struct intel_encoder *encoder,
 			   const struct intel_crtc_state *crtc_state,
 			   const struct drm_connector_state *conn_state)
 {
@@ -314,7 +322,8 @@ static void hsw_enable_crt(struct intel_encoder *encoder,
 	intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true);
 }
 
-static void intel_enable_crt(struct intel_encoder *encoder,
+static void intel_enable_crt(struct intel_atomic_state *state,
+			     struct intel_encoder *encoder,
 			     const struct intel_crtc_state *crtc_state,
 			     const struct drm_connector_state *conn_state)
 {
@@ -594,7 +603,8 @@ static struct edid *intel_crt_get_edid(struct drm_connector *connector,
 	edid = drm_get_edid(connector, i2c);
 
 	if (!edid && !intel_gmbus_is_forced_bit(i2c)) {
-		DRM_DEBUG_KMS("CRT GMBUS EDID read failed, retry using GPIO bit-banging\n");
+		drm_dbg_kms(connector->dev,
+			    "CRT 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);
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 2c617c98db3a..be6c61bcbc9c 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -568,7 +568,7 @@ static const struct cnl_ddi_buf_trans icl_combo_phy_ddi_translations_hdmi[] = {
 	{ 0x6, 0x7F, 0x35, 0x00, 0x0A },	/* 600   850      3.0   */
 };
 
-static const struct cnl_ddi_buf_trans ehl_combo_phy_ddi_translations_hbr2_hbr3[] = {
+static const struct cnl_ddi_buf_trans ehl_combo_phy_ddi_translations_dp[] = {
 						/* NT mV Trans mV db    */
 	{ 0xA, 0x33, 0x3F, 0x00, 0x00 },	/* 350   350      0.0   */
 	{ 0xA, 0x47, 0x36, 0x00, 0x09 },	/* 350   500      3.1   */
@@ -583,23 +583,51 @@ static const struct cnl_ddi_buf_trans ehl_combo_phy_ddi_translations_hbr2_hbr3[]
 };
 
 struct icl_mg_phy_ddi_buf_trans {
-	u32 cri_txdeemph_override_5_0;
 	u32 cri_txdeemph_override_11_6;
+	u32 cri_txdeemph_override_5_0;
 	u32 cri_txdeemph_override_17_12;
 };
 
-static const struct icl_mg_phy_ddi_buf_trans icl_mg_phy_ddi_translations[] = {
+static const struct icl_mg_phy_ddi_buf_trans icl_mg_phy_ddi_translations_rbr_hbr[] = {
 				/* Voltage swing  pre-emphasis */
-	{ 0x0, 0x1B, 0x00 },	/* 0              0   */
-	{ 0x0, 0x23, 0x08 },	/* 0              1   */
-	{ 0x0, 0x2D, 0x12 },	/* 0              2   */
-	{ 0x0, 0x00, 0x00 },	/* 0              3   */
-	{ 0x0, 0x23, 0x00 },	/* 1              0   */
-	{ 0x0, 0x2B, 0x09 },	/* 1              1   */
-	{ 0x0, 0x2E, 0x11 },	/* 1              2   */
-	{ 0x0, 0x2F, 0x00 },	/* 2              0   */
-	{ 0x0, 0x33, 0x0C },	/* 2              1   */
-	{ 0x0, 0x00, 0x00 },	/* 3              0   */
+	{ 0x18, 0x00, 0x00 },	/* 0              0   */
+	{ 0x1D, 0x00, 0x05 },	/* 0              1   */
+	{ 0x24, 0x00, 0x0C },	/* 0              2   */
+	{ 0x2B, 0x00, 0x14 },	/* 0              3   */
+	{ 0x21, 0x00, 0x00 },	/* 1              0   */
+	{ 0x2B, 0x00, 0x08 },	/* 1              1   */
+	{ 0x30, 0x00, 0x0F },	/* 1              2   */
+	{ 0x31, 0x00, 0x03 },	/* 2              0   */
+	{ 0x34, 0x00, 0x0B },	/* 2              1   */
+	{ 0x3F, 0x00, 0x00 },	/* 3              0   */
+};
+
+static const struct icl_mg_phy_ddi_buf_trans icl_mg_phy_ddi_translations_hbr2_hbr3[] = {
+				/* Voltage swing  pre-emphasis */
+	{ 0x18, 0x00, 0x00 },	/* 0              0   */
+	{ 0x1D, 0x00, 0x05 },	/* 0              1   */
+	{ 0x24, 0x00, 0x0C },	/* 0              2   */
+	{ 0x2B, 0x00, 0x14 },	/* 0              3   */
+	{ 0x26, 0x00, 0x00 },	/* 1              0   */
+	{ 0x2C, 0x00, 0x07 },	/* 1              1   */
+	{ 0x33, 0x00, 0x0C },	/* 1              2   */
+	{ 0x2E, 0x00, 0x00 },	/* 2              0   */
+	{ 0x36, 0x00, 0x09 },	/* 2              1   */
+	{ 0x3F, 0x00, 0x00 },	/* 3              0   */
+};
+
+static const struct icl_mg_phy_ddi_buf_trans icl_mg_phy_ddi_translations_hdmi[] = {
+				/* HDMI Preset	VS	Pre-emph */
+	{ 0x1A, 0x0, 0x0 },	/* 1		400mV	0dB */
+	{ 0x20, 0x0, 0x0 },	/* 2		500mV	0dB */
+	{ 0x29, 0x0, 0x0 },	/* 3		650mV	0dB */
+	{ 0x32, 0x0, 0x0 },	/* 4		800mV	0dB */
+	{ 0x3F, 0x0, 0x0 },	/* 5		1000mV	0dB */
+	{ 0x3A, 0x0, 0x5 },	/* 6		Full	-1.5 dB */
+	{ 0x39, 0x0, 0x6 },	/* 7		Full	-1.8 dB */
+	{ 0x38, 0x0, 0x7 },	/* 8		Full	-2 dB */
+	{ 0x37, 0x0, 0x8 },	/* 9		Full	-2.5 dB */
+	{ 0x36, 0x0, 0x9 },	/* 10		Full	-3 dB */
 };
 
 struct tgl_dkl_phy_ddi_buf_trans {
@@ -943,14 +971,29 @@ icl_get_combo_buf_trans(struct drm_i915_private *dev_priv, int type, int rate,
 	return icl_combo_phy_ddi_translations_dp_hbr2;
 }
 
+static const struct icl_mg_phy_ddi_buf_trans *
+icl_get_mg_buf_trans(struct drm_i915_private *dev_priv, int type, int rate,
+		     int *n_entries)
+{
+	if (type == INTEL_OUTPUT_HDMI) {
+		*n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations_hdmi);
+		return icl_mg_phy_ddi_translations_hdmi;
+	} else if (rate > 270000) {
+		*n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations_hbr2_hbr3);
+		return icl_mg_phy_ddi_translations_hbr2_hbr3;
+	}
+
+	*n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations_rbr_hbr);
+	return icl_mg_phy_ddi_translations_rbr_hbr;
+}
+
 static const struct cnl_ddi_buf_trans *
 ehl_get_combo_buf_trans(struct drm_i915_private *dev_priv, int type, int rate,
 			int *n_entries)
 {
-	if (type != INTEL_OUTPUT_HDMI && type != INTEL_OUTPUT_EDP &&
-	    rate > 270000) {
-		*n_entries = ARRAY_SIZE(ehl_combo_phy_ddi_translations_hbr2_hbr3);
-		return ehl_combo_phy_ddi_translations_hbr2_hbr3;
+	if (type != INTEL_OUTPUT_HDMI && type != INTEL_OUTPUT_EDP) {
+		*n_entries = ARRAY_SIZE(ehl_combo_phy_ddi_translations_dp);
+		return ehl_combo_phy_ddi_translations_dp;
 	}
 
 	return icl_get_combo_buf_trans(dev_priv, type, rate, n_entries);
@@ -989,7 +1032,8 @@ static int intel_ddi_hdmi_level(struct intel_encoder *encoder)
 			icl_get_combo_buf_trans(dev_priv, INTEL_OUTPUT_HDMI,
 						0, &n_entries);
 		else
-			n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations);
+			icl_get_mg_buf_trans(dev_priv, INTEL_OUTPUT_HDMI, 0,
+					     &n_entries);
 		default_entry = n_entries - 1;
 	} else if (IS_CANNONLAKE(dev_priv)) {
 		cnl_get_buf_trans_hdmi(dev_priv, &n_entries);
@@ -1103,7 +1147,8 @@ static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
 		if (intel_de_read(dev_priv, reg) & DDI_BUF_IS_IDLE)
 			return;
 	}
-	DRM_ERROR("Timeout waiting for DDI BUF %c idle bit\n", port_name(port));
+	drm_err(&dev_priv->drm, "Timeout waiting for DDI BUF %c idle bit\n",
+		port_name(port));
 }
 
 static u32 hsw_pll_to_ddi_pll_sel(const struct intel_shared_dpll *pll)
@@ -1250,7 +1295,8 @@ void hsw_fdi_link_train(struct intel_encoder *encoder,
 
 		temp = intel_de_read(dev_priv, DP_TP_STATUS(PORT_E));
 		if (temp & DP_TP_STATUS_AUTOTRAIN_DONE) {
-			DRM_DEBUG_KMS("FDI link training done on step %d\n", i);
+			drm_dbg_kms(&dev_priv->drm,
+				    "FDI link training done on step %d\n", i);
 			break;
 		}
 
@@ -1259,7 +1305,7 @@ void hsw_fdi_link_train(struct intel_encoder *encoder,
 		 * Results in less fireworks from the state checker.
 		 */
 		if (i == ARRAY_SIZE(hsw_ddi_translations_fdi) * 2 - 1) {
-			DRM_ERROR("FDI link training failed!\n");
+			drm_err(&dev_priv->drm, "FDI link training failed!\n");
 			break;
 		}
 
@@ -1451,6 +1497,14 @@ void intel_ddi_set_dp_msa(const struct intel_crtc_state *crtc_state,
 	intel_de_write(dev_priv, TRANS_MSA_MISC(cpu_transcoder), temp);
 }
 
+static u32 bdw_trans_port_sync_master_select(enum transcoder master_transcoder)
+{
+	if (master_transcoder == TRANSCODER_EDP)
+		return 0;
+	else
+		return master_transcoder + 1;
+}
+
 /*
  * Returns the TRANS_DDI_FUNC_CTL value based on CRTC state.
  *
@@ -1551,6 +1605,15 @@ intel_ddi_transcoder_func_reg_val_get(const struct intel_crtc_state *crtc_state)
 		temp |= DDI_PORT_WIDTH(crtc_state->lane_count);
 	}
 
+	if (IS_GEN_RANGE(dev_priv, 8, 10) &&
+	    crtc_state->master_transcoder != INVALID_TRANSCODER) {
+		u8 master_select =
+			bdw_trans_port_sync_master_select(crtc_state->master_transcoder);
+
+		temp |= TRANS_DDI_PORT_SYNC_ENABLE |
+			TRANS_DDI_PORT_SYNC_MASTER_SELECT(master_select);
+	}
+
 	return temp;
 }
 
@@ -1559,12 +1622,28 @@ void intel_ddi_enable_transcoder_func(const struct intel_crtc_state *crtc_state)
 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
-	u32 temp;
+	u32 ctl;
+
+	if (INTEL_GEN(dev_priv) >= 11) {
+		enum transcoder master_transcoder = crtc_state->master_transcoder;
+		u32 ctl2 = 0;
+
+		if (master_transcoder != INVALID_TRANSCODER) {
+			u8 master_select =
+				bdw_trans_port_sync_master_select(master_transcoder);
+
+			ctl2 |= PORT_SYNC_MODE_ENABLE |
+				PORT_SYNC_MODE_MASTER_SELECT(master_select);
+		}
+
+		intel_de_write(dev_priv,
+			       TRANS_DDI_FUNC_CTL2(cpu_transcoder), ctl2);
+	}
 
-	temp = intel_ddi_transcoder_func_reg_val_get(crtc_state);
+	ctl = intel_ddi_transcoder_func_reg_val_get(crtc_state);
 	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST))
-		temp |= TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
-	intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
+		ctl |= TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
+	intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder), ctl);
 }
 
 /*
@@ -1577,11 +1656,11 @@ intel_ddi_config_transcoder_func(const struct intel_crtc_state *crtc_state)
 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
-	u32 temp;
+	u32 ctl;
 
-	temp = intel_ddi_transcoder_func_reg_val_get(crtc_state);
-	temp &= ~TRANS_DDI_FUNC_ENABLE;
-	intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
+	ctl = intel_ddi_transcoder_func_reg_val_get(crtc_state);
+	ctl &= ~TRANS_DDI_FUNC_ENABLE;
+	intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder), ctl);
 }
 
 void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state)
@@ -1589,24 +1668,35 @@ void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state
 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
-	u32 val;
+	u32 ctl;
+
+	if (INTEL_GEN(dev_priv) >= 11)
+		intel_de_write(dev_priv,
+			       TRANS_DDI_FUNC_CTL2(cpu_transcoder), 0);
 
-	val = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
-	val &= ~TRANS_DDI_FUNC_ENABLE;
+	ctl = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
+
+	ctl &= ~TRANS_DDI_FUNC_ENABLE;
+
+	if (IS_GEN_RANGE(dev_priv, 8, 10))
+		ctl &= ~(TRANS_DDI_PORT_SYNC_ENABLE |
+			 TRANS_DDI_PORT_SYNC_MASTER_SELECT_MASK);
 
 	if (INTEL_GEN(dev_priv) >= 12) {
 		if (!intel_dp_mst_is_master_trans(crtc_state)) {
-			val &= ~(TGL_TRANS_DDI_PORT_MASK |
+			ctl &= ~(TGL_TRANS_DDI_PORT_MASK |
 				 TRANS_DDI_MODE_SELECT_MASK);
 		}
 	} else {
-		val &= ~(TRANS_DDI_PORT_MASK | TRANS_DDI_MODE_SELECT_MASK);
+		ctl &= ~(TRANS_DDI_PORT_MASK | TRANS_DDI_MODE_SELECT_MASK);
 	}
-	intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder), val);
+
+	intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder), ctl);
 
 	if (dev_priv->quirks & QUIRK_INCREASE_DDI_DISABLED_TIME &&
 	    intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
-		DRM_DEBUG_KMS("Quirk Increase DDI disabled time\n");
+		drm_dbg_kms(&dev_priv->drm,
+			    "Quirk Increase DDI disabled time\n");
 		/* Quirk time at 100ms for reliable operation */
 		msleep(100);
 	}
@@ -1667,7 +1757,7 @@ bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
 		goto out;
 	}
 
-	if (HAS_TRANSCODER_EDP(dev_priv) && port == PORT_A)
+	if (HAS_TRANSCODER(dev_priv, TRANSCODER_EDP) && port == PORT_A)
 		cpu_transcoder = TRANSCODER_EDP;
 	else
 		cpu_transcoder = (enum transcoder) pipe;
@@ -1729,7 +1819,7 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder,
 	if (!(tmp & DDI_BUF_CTL_ENABLE))
 		goto out;
 
-	if (HAS_TRANSCODER_EDP(dev_priv) && port == PORT_A) {
+	if (HAS_TRANSCODER(dev_priv, TRANSCODER_EDP) && port == PORT_A) {
 		tmp = intel_de_read(dev_priv,
 				    TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
 
@@ -1787,20 +1877,23 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder,
 	}
 
 	if (!*pipe_mask)
-		DRM_DEBUG_KMS("No pipe for [ENCODER:%d:%s] found\n",
-			      encoder->base.base.id, encoder->base.name);
+		drm_dbg_kms(&dev_priv->drm,
+			    "No pipe for [ENCODER:%d:%s] found\n",
+			    encoder->base.base.id, encoder->base.name);
 
 	if (!mst_pipe_mask && hweight8(*pipe_mask) > 1) {
-		DRM_DEBUG_KMS("Multiple pipes for [ENCODER:%d:%s] (pipe_mask %02x)\n",
-			      encoder->base.base.id, encoder->base.name,
-			      *pipe_mask);
+		drm_dbg_kms(&dev_priv->drm,
+			    "Multiple pipes for [ENCODER:%d:%s] (pipe_mask %02x)\n",
+			    encoder->base.base.id, encoder->base.name,
+			    *pipe_mask);
 		*pipe_mask = BIT(ffs(*pipe_mask) - 1);
 	}
 
 	if (mst_pipe_mask && mst_pipe_mask != *pipe_mask)
-		DRM_DEBUG_KMS("Conflicting MST and non-MST state for [ENCODER:%d:%s] (pipe_mask %02x mst_pipe_mask %02x)\n",
-			      encoder->base.base.id, encoder->base.name,
-			      *pipe_mask, mst_pipe_mask);
+		drm_dbg_kms(&dev_priv->drm,
+			    "Conflicting MST and non-MST state for [ENCODER:%d:%s] (pipe_mask %02x mst_pipe_mask %02x)\n",
+			    encoder->base.base.id, encoder->base.name,
+			    *pipe_mask, mst_pipe_mask);
 	else
 		*is_dp_mst = mst_pipe_mask;
 
@@ -1810,9 +1903,9 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder,
 		if ((tmp & (BXT_PHY_CMNLANE_POWERDOWN_ACK |
 			    BXT_PHY_LANE_POWERDOWN_ACK |
 			    BXT_PHY_LANE_ENABLED)) != BXT_PHY_LANE_ENABLED)
-			DRM_ERROR("[ENCODER:%d:%s] enabled but PHY powered down? "
-				  "(PHY_CTL %08x)\n", encoder->base.base.id,
-				  encoder->base.name, tmp);
+			drm_err(&dev_priv->drm,
+				"[ENCODER:%d:%s] enabled but PHY powered down? (PHY_CTL %08x)\n",
+				encoder->base.base.id, encoder->base.name, tmp);
 	}
 
 	intel_display_power_put(dev_priv, encoder->power_domain, wakeref);
@@ -1978,7 +2071,7 @@ static void skl_ddi_set_iboost(struct intel_encoder *encoder,
 
 	/* Make sure that the requested I_boost is valid */
 	if (iboost && iboost != 0x1 && iboost != 0x3 && iboost != 0x7) {
-		DRM_ERROR("Invalid I_boost value %u\n", iboost);
+		drm_err(&dev_priv->drm, "Invalid I_boost value %u\n", iboost);
 		return;
 	}
 
@@ -2037,7 +2130,8 @@ u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder)
 			icl_get_combo_buf_trans(dev_priv, encoder->type,
 						intel_dp->link_rate, &n_entries);
 		else
-			n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations);
+			icl_get_mg_buf_trans(dev_priv, encoder->type,
+					     intel_dp->link_rate, &n_entries);
 	} else if (IS_CANNONLAKE(dev_priv)) {
 		if (encoder->type == INTEL_OUTPUT_EDP)
 			cnl_get_buf_trans_edp(dev_priv, &n_entries);
@@ -2237,7 +2331,9 @@ static void icl_ddi_combo_vswing_program(struct drm_i915_private *dev_priv,
 		return;
 
 	if (level >= n_entries) {
-		DRM_DEBUG_KMS("DDI translation not found for level %d. Using %d instead.", level, n_entries - 1);
+		drm_dbg_kms(&dev_priv->drm,
+			    "DDI translation not found for level %d. Using %d instead.",
+			    level, n_entries - 1);
 		level = n_entries - 1;
 	}
 
@@ -2350,21 +2446,28 @@ static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
 }
 
 static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
-					   int link_clock,
-					   u32 level)
+					   int link_clock, u32 level,
+					   enum intel_output_type type)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	enum tc_port tc_port = intel_port_to_tc(dev_priv, encoder->port);
 	const struct icl_mg_phy_ddi_buf_trans *ddi_translations;
 	u32 n_entries, val;
-	int ln;
+	int ln, rate = 0;
+
+	if (type != INTEL_OUTPUT_HDMI) {
+		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
 
-	n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations);
-	ddi_translations = icl_mg_phy_ddi_translations;
+		rate = intel_dp->link_rate;
+	}
+
+	ddi_translations = icl_get_mg_buf_trans(dev_priv, type, rate,
+						&n_entries);
 	/* The table does not have values for level 3 and level 9. */
 	if (level >= n_entries || level == 3 || level == 9) {
-		DRM_DEBUG_KMS("DDI translation not found for level %d. Using %d instead.",
-			      level, n_entries - 2);
+		drm_dbg_kms(&dev_priv->drm,
+			    "DDI translation not found for level %d. Using %d instead.",
+			    level, n_entries - 2);
 		level = n_entries - 2;
 	}
 
@@ -2483,7 +2586,8 @@ static void icl_ddi_vswing_sequence(struct intel_encoder *encoder,
 	if (intel_phy_is_combo(dev_priv, phy))
 		icl_combo_phy_ddi_vswing_sequence(encoder, level, type);
 	else
-		icl_mg_phy_ddi_vswing_sequence(encoder, link_clock, level);
+		icl_mg_phy_ddi_vswing_sequence(encoder, link_clock, level,
+					       type);
 }
 
 static void
@@ -2698,8 +2802,9 @@ static void icl_sanitize_port_clk_off(struct drm_i915_private *dev_priv,
 		if (drm_WARN_ON(&dev_priv->drm, ddi_clk_needed))
 			continue;
 
-		DRM_NOTE("PHY %c is disabled/in DSI mode with an ungated DDI clock, gate it\n",
-			 phy_name(phy));
+		drm_notice(&dev_priv->drm,
+			   "PHY %c is disabled/in DSI mode with an ungated DDI clock, gate it\n",
+			   phy_name(phy));
 		val |= icl_dpclka_cfgcr0_clk_off(dev_priv, phy);
 		intel_de_write(dev_priv, ICL_DPCLKA_CFGCR0, val);
 	}
@@ -2936,11 +3041,14 @@ icl_program_mg_dp_mode(struct intel_digital_port *intel_dig_port,
 static void intel_dp_sink_set_fec_ready(struct intel_dp *intel_dp,
 					const struct intel_crtc_state *crtc_state)
 {
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+
 	if (!crtc_state->fec_enable)
 		return;
 
 	if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_FEC_CONFIGURATION, DP_FEC_READY) <= 0)
-		DRM_DEBUG_KMS("Failed to set FEC_READY in the sink\n");
+		drm_dbg_kms(&i915->drm,
+			    "Failed to set FEC_READY in the sink\n");
 }
 
 static void intel_ddi_enable_fec(struct intel_encoder *encoder,
@@ -2960,7 +3068,8 @@ static void intel_ddi_enable_fec(struct intel_encoder *encoder,
 
 	if (intel_de_wait_for_set(dev_priv, intel_dp->regs.dp_tp_status,
 				  DP_TP_STATUS_FEC_ENABLE_LIVE, 1))
-		DRM_ERROR("Timed out waiting for FEC Enable Status\n");
+		drm_err(&dev_priv->drm,
+			"Timed out waiting for FEC Enable Status\n");
 }
 
 static void intel_ddi_disable_fec_state(struct intel_encoder *encoder,
@@ -2980,7 +3089,8 @@ static void intel_ddi_disable_fec_state(struct intel_encoder *encoder,
 	intel_de_posting_read(dev_priv, intel_dp->regs.dp_tp_ctl);
 }
 
-static void tgl_ddi_pre_enable_dp(struct intel_encoder *encoder,
+static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
+				  struct intel_encoder *encoder,
 				  const struct intel_crtc_state *crtc_state,
 				  const struct drm_connector_state *conn_state)
 {
@@ -3120,7 +3230,8 @@ static void tgl_ddi_pre_enable_dp(struct intel_encoder *encoder,
 	intel_dsc_enable(encoder, crtc_state);
 }
 
-static void hsw_ddi_pre_enable_dp(struct intel_encoder *encoder,
+static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
+				  struct intel_encoder *encoder,
 				  const struct intel_crtc_state *crtc_state,
 				  const struct drm_connector_state *conn_state)
 {
@@ -3193,16 +3304,17 @@ static void hsw_ddi_pre_enable_dp(struct intel_encoder *encoder,
 	intel_dsc_enable(encoder, crtc_state);
 }
 
-static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
+static void intel_ddi_pre_enable_dp(struct intel_atomic_state *state,
+				    struct intel_encoder *encoder,
 				    const struct intel_crtc_state *crtc_state,
 				    const struct drm_connector_state *conn_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 
 	if (INTEL_GEN(dev_priv) >= 12)
-		tgl_ddi_pre_enable_dp(encoder, crtc_state, conn_state);
+		tgl_ddi_pre_enable_dp(state, encoder, crtc_state, conn_state);
 	else
-		hsw_ddi_pre_enable_dp(encoder, crtc_state, conn_state);
+		hsw_ddi_pre_enable_dp(state, encoder, crtc_state, conn_state);
 
 	/* MST will call a setting of MSA after an allocating of Virtual Channel
 	 * from MST encoder pre_enable callback.
@@ -3214,7 +3326,8 @@ static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
 	}
 }
 
-static void intel_ddi_pre_enable_hdmi(struct intel_encoder *encoder,
+static void intel_ddi_pre_enable_hdmi(struct intel_atomic_state *state,
+				      struct intel_encoder *encoder,
 				      const struct intel_crtc_state *crtc_state,
 				      const struct drm_connector_state *conn_state)
 {
@@ -3254,7 +3367,8 @@ static void intel_ddi_pre_enable_hdmi(struct intel_encoder *encoder,
 				       crtc_state, conn_state);
 }
 
-static void intel_ddi_pre_enable(struct intel_encoder *encoder,
+static void intel_ddi_pre_enable(struct intel_atomic_state *state,
+				 struct intel_encoder *encoder,
 				 const struct intel_crtc_state *crtc_state,
 				 const struct drm_connector_state *conn_state)
 {
@@ -3283,12 +3397,14 @@ static void intel_ddi_pre_enable(struct intel_encoder *encoder,
 	intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
 
 	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
-		intel_ddi_pre_enable_hdmi(encoder, crtc_state, conn_state);
+		intel_ddi_pre_enable_hdmi(state, encoder, crtc_state,
+					  conn_state);
 	} else {
 		struct intel_lspcon *lspcon =
 				enc_to_intel_lspcon(encoder);
 
-		intel_ddi_pre_enable_dp(encoder, crtc_state, conn_state);
+		intel_ddi_pre_enable_dp(state, encoder, crtc_state,
+					conn_state);
 		if (lspcon->active) {
 			struct intel_digital_port *dig_port =
 					enc_to_dig_port(encoder);
@@ -3331,7 +3447,8 @@ static void intel_disable_ddi_buf(struct intel_encoder *encoder,
 		intel_wait_ddi_buf_idle(dev_priv, port);
 }
 
-static void intel_ddi_post_disable_dp(struct intel_encoder *encoder,
+static void intel_ddi_post_disable_dp(struct intel_atomic_state *state,
+				      struct intel_encoder *encoder,
 				      const struct intel_crtc_state *old_crtc_state,
 				      const struct drm_connector_state *old_conn_state)
 {
@@ -3387,7 +3504,8 @@ static void intel_ddi_post_disable_dp(struct intel_encoder *encoder,
 	intel_ddi_clk_disable(encoder);
 }
 
-static void intel_ddi_post_disable_hdmi(struct intel_encoder *encoder,
+static void intel_ddi_post_disable_hdmi(struct intel_atomic_state *state,
+					struct intel_encoder *encoder,
 					const struct intel_crtc_state *old_crtc_state,
 					const struct drm_connector_state *old_conn_state)
 {
@@ -3410,22 +3528,8 @@ static void intel_ddi_post_disable_hdmi(struct intel_encoder *encoder,
 	intel_dp_dual_mode_set_tmds_output(intel_hdmi, false);
 }
 
-static void icl_disable_transcoder_port_sync(const struct intel_crtc_state *old_crtc_state)
-{
-	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
-	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-
-	if (old_crtc_state->master_transcoder == INVALID_TRANSCODER)
-		return;
-
-	DRM_DEBUG_KMS("Disabling Transcoder Port Sync on Slave Transcoder %s\n",
-		      transcoder_name(old_crtc_state->cpu_transcoder));
-
-	intel_de_write(dev_priv,
-		       TRANS_DDI_FUNC_CTL2(old_crtc_state->cpu_transcoder), 0);
-}
-
-static void intel_ddi_post_disable(struct intel_encoder *encoder,
+static void intel_ddi_post_disable(struct intel_atomic_state *state,
+				   struct intel_encoder *encoder,
 				   const struct intel_crtc_state *old_crtc_state,
 				   const struct drm_connector_state *old_conn_state)
 {
@@ -3439,9 +3543,6 @@ static void intel_ddi_post_disable(struct intel_encoder *encoder,
 
 		intel_disable_pipe(old_crtc_state);
 
-		if (INTEL_GEN(dev_priv) >= 11)
-			icl_disable_transcoder_port_sync(old_crtc_state);
-
 		intel_ddi_disable_transcoder_func(old_crtc_state);
 
 		intel_dsc_disable(old_crtc_state);
@@ -3466,11 +3567,11 @@ static void intel_ddi_post_disable(struct intel_encoder *encoder,
 	 */
 
 	if (intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_HDMI))
-		intel_ddi_post_disable_hdmi(encoder,
-					    old_crtc_state, old_conn_state);
+		intel_ddi_post_disable_hdmi(state, encoder, old_crtc_state,
+					    old_conn_state);
 	else
-		intel_ddi_post_disable_dp(encoder,
-					  old_crtc_state, old_conn_state);
+		intel_ddi_post_disable_dp(state, encoder, old_crtc_state,
+					  old_conn_state);
 
 	if (INTEL_GEN(dev_priv) >= 11)
 		icl_unmap_plls_to_ports(encoder);
@@ -3483,7 +3584,8 @@ static void intel_ddi_post_disable(struct intel_encoder *encoder,
 		intel_tc_port_put_link(dig_port);
 }
 
-void intel_ddi_fdi_post_disable(struct intel_encoder *encoder,
+void intel_ddi_fdi_post_disable(struct intel_atomic_state *state,
+				struct intel_encoder *encoder,
 				const struct intel_crtc_state *old_crtc_state,
 				const struct drm_connector_state *old_conn_state)
 {
@@ -3517,7 +3619,43 @@ void intel_ddi_fdi_post_disable(struct intel_encoder *encoder,
 	intel_de_write(dev_priv, FDI_RX_CTL(PIPE_A), val);
 }
 
-static void intel_enable_ddi_dp(struct intel_encoder *encoder,
+static void trans_port_sync_stop_link_train(struct intel_atomic_state *state,
+					    struct intel_encoder *encoder,
+					    const struct intel_crtc_state *crtc_state)
+{
+	const struct drm_connector_state *conn_state;
+	struct drm_connector *conn;
+	int i;
+
+	if (!crtc_state->sync_mode_slaves_mask)
+		return;
+
+	for_each_new_connector_in_state(&state->base, conn, conn_state, i) {
+		struct intel_encoder *slave_encoder =
+			to_intel_encoder(conn_state->best_encoder);
+		struct intel_crtc *slave_crtc = to_intel_crtc(conn_state->crtc);
+		const struct intel_crtc_state *slave_crtc_state;
+
+		if (!slave_crtc)
+			continue;
+
+		slave_crtc_state =
+			intel_atomic_get_new_crtc_state(state, slave_crtc);
+
+		if (slave_crtc_state->master_transcoder !=
+		    crtc_state->cpu_transcoder)
+			continue;
+
+		intel_dp_stop_link_train(enc_to_intel_dp(slave_encoder));
+	}
+
+	usleep_range(200, 400);
+
+	intel_dp_stop_link_train(enc_to_intel_dp(encoder));
+}
+
+static void intel_enable_ddi_dp(struct intel_atomic_state *state,
+				struct intel_encoder *encoder,
 				const struct intel_crtc_state *crtc_state,
 				const struct drm_connector_state *conn_state)
 {
@@ -3536,6 +3674,8 @@ static void intel_enable_ddi_dp(struct intel_encoder *encoder,
 
 	if (crtc_state->has_audio)
 		intel_audio_codec_enable(encoder, crtc_state, conn_state);
+
+	trans_port_sync_stop_link_train(state, encoder, crtc_state);
 }
 
 static i915_reg_t
@@ -3558,7 +3698,8 @@ gen9_chicken_trans_reg_by_port(struct drm_i915_private *dev_priv,
 	return CHICKEN_TRANS(trans[port]);
 }
 
-static void intel_enable_ddi_hdmi(struct intel_encoder *encoder,
+static void intel_enable_ddi_hdmi(struct intel_atomic_state *state,
+				  struct intel_encoder *encoder,
 				  const struct intel_crtc_state *crtc_state,
 				  const struct drm_connector_state *conn_state)
 {
@@ -3570,9 +3711,9 @@ static void intel_enable_ddi_hdmi(struct intel_encoder *encoder,
 	if (!intel_hdmi_handle_sink_scrambling(encoder, connector,
 					       crtc_state->hdmi_high_tmds_clock_ratio,
 					       crtc_state->hdmi_scrambling))
-		DRM_DEBUG_KMS("[CONNECTOR:%d:%s] Failed to configure sink "
-			      "scrambling/TMDS bit clock ratio\n",
-			       connector->base.id, connector->name);
+		drm_dbg_kms(&dev_priv->drm,
+			    "[CONNECTOR:%d:%s] Failed to configure sink scrambling/TMDS bit clock ratio\n",
+			    connector->base.id, connector->name);
 
 	/* Display WA #1143: skl,kbl,cfl */
 	if (IS_GEN9_BC(dev_priv)) {
@@ -3620,7 +3761,8 @@ static void intel_enable_ddi_hdmi(struct intel_encoder *encoder,
 		intel_audio_codec_enable(encoder, crtc_state, conn_state);
 }
 
-static void intel_enable_ddi(struct intel_encoder *encoder,
+static void intel_enable_ddi(struct intel_atomic_state *state,
+			     struct intel_encoder *encoder,
 			     const struct intel_crtc_state *crtc_state,
 			     const struct drm_connector_state *conn_state)
 {
@@ -3631,9 +3773,9 @@ static void intel_enable_ddi(struct intel_encoder *encoder,
 	intel_crtc_vblank_on(crtc_state);
 
 	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
-		intel_enable_ddi_hdmi(encoder, crtc_state, conn_state);
+		intel_enable_ddi_hdmi(state, encoder, crtc_state, conn_state);
 	else
-		intel_enable_ddi_dp(encoder, crtc_state, conn_state);
+		intel_enable_ddi_dp(state, encoder, crtc_state, conn_state);
 
 	/* Enable hdcp if it's desired */
 	if (conn_state->content_protection ==
@@ -3643,7 +3785,8 @@ static void intel_enable_ddi(struct intel_encoder *encoder,
 				  (u8)conn_state->hdcp_content_type);
 }
 
-static void intel_disable_ddi_dp(struct intel_encoder *encoder,
+static void intel_disable_ddi_dp(struct intel_atomic_state *state,
+				 struct intel_encoder *encoder,
 				 const struct intel_crtc_state *old_crtc_state,
 				 const struct drm_connector_state *old_conn_state)
 {
@@ -3663,10 +3806,12 @@ static void intel_disable_ddi_dp(struct intel_encoder *encoder,
 					      false);
 }
 
-static void intel_disable_ddi_hdmi(struct intel_encoder *encoder,
+static void intel_disable_ddi_hdmi(struct intel_atomic_state *state,
+				   struct intel_encoder *encoder,
 				   const struct intel_crtc_state *old_crtc_state,
 				   const struct drm_connector_state *old_conn_state)
 {
+	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
 	struct drm_connector *connector = old_conn_state->connector;
 
 	if (old_crtc_state->has_audio)
@@ -3675,23 +3820,28 @@ static void intel_disable_ddi_hdmi(struct intel_encoder *encoder,
 
 	if (!intel_hdmi_handle_sink_scrambling(encoder, connector,
 					       false, false))
-		DRM_DEBUG_KMS("[CONNECTOR:%d:%s] Failed to reset sink scrambling/TMDS bit clock ratio\n",
-			      connector->base.id, connector->name);
+		drm_dbg_kms(&i915->drm,
+			    "[CONNECTOR:%d:%s] Failed to reset sink scrambling/TMDS bit clock ratio\n",
+			    connector->base.id, connector->name);
 }
 
-static void intel_disable_ddi(struct intel_encoder *encoder,
+static void intel_disable_ddi(struct intel_atomic_state *state,
+			      struct intel_encoder *encoder,
 			      const struct intel_crtc_state *old_crtc_state,
 			      const struct drm_connector_state *old_conn_state)
 {
 	intel_hdcp_disable(to_intel_connector(old_conn_state->connector));
 
 	if (intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_HDMI))
-		intel_disable_ddi_hdmi(encoder, old_crtc_state, old_conn_state);
+		intel_disable_ddi_hdmi(state, encoder, old_crtc_state,
+				       old_conn_state);
 	else
-		intel_disable_ddi_dp(encoder, old_crtc_state, old_conn_state);
+		intel_disable_ddi_dp(state, encoder, old_crtc_state,
+				     old_conn_state);
 }
 
-static void intel_ddi_update_pipe_dp(struct intel_encoder *encoder,
+static void intel_ddi_update_pipe_dp(struct intel_atomic_state *state,
+				     struct intel_encoder *encoder,
 				     const struct intel_crtc_state *crtc_state,
 				     const struct drm_connector_state *conn_state)
 {
@@ -3702,18 +3852,20 @@ static void intel_ddi_update_pipe_dp(struct intel_encoder *encoder,
 	intel_psr_update(intel_dp, crtc_state);
 	intel_edp_drrs_enable(intel_dp, crtc_state);
 
-	intel_panel_update_backlight(encoder, crtc_state, conn_state);
+	intel_panel_update_backlight(state, encoder, crtc_state, conn_state);
 }
 
-static void intel_ddi_update_pipe(struct intel_encoder *encoder,
+static void intel_ddi_update_pipe(struct intel_atomic_state *state,
+				  struct intel_encoder *encoder,
 				  const struct intel_crtc_state *crtc_state,
 				  const struct drm_connector_state *conn_state)
 {
 
 	if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
-		intel_ddi_update_pipe_dp(encoder, crtc_state, conn_state);
+		intel_ddi_update_pipe_dp(state, encoder, crtc_state,
+					 conn_state);
 
-	intel_hdcp_update_pipe(encoder, crtc_state, conn_state);
+	intel_hdcp_update_pipe(state, encoder, crtc_state, conn_state);
 }
 
 static void
@@ -3742,7 +3894,8 @@ intel_ddi_update_complete(struct intel_atomic_state *state,
 }
 
 static void
-intel_ddi_pre_pll_enable(struct intel_encoder *encoder,
+intel_ddi_pre_pll_enable(struct intel_atomic_state *state,
+			 struct intel_encoder *encoder,
 			 const struct intel_crtc_state *crtc_state,
 			 const struct drm_connector_state *conn_state)
 {
@@ -3842,6 +3995,66 @@ void intel_ddi_compute_min_voltage_level(struct drm_i915_private *dev_priv,
 		crtc_state->min_voltage_level = 2;
 }
 
+static enum transcoder bdw_transcoder_master_readout(struct drm_i915_private *dev_priv,
+						     enum transcoder cpu_transcoder)
+{
+	u32 master_select;
+
+	if (INTEL_GEN(dev_priv) >= 11) {
+		u32 ctl2 = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL2(cpu_transcoder));
+
+		if ((ctl2 & PORT_SYNC_MODE_ENABLE) == 0)
+			return INVALID_TRANSCODER;
+
+		master_select = REG_FIELD_GET(PORT_SYNC_MODE_MASTER_SELECT_MASK, ctl2);
+	} else {
+		u32 ctl = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
+
+		if ((ctl & TRANS_DDI_PORT_SYNC_ENABLE) == 0)
+			return INVALID_TRANSCODER;
+
+		master_select = REG_FIELD_GET(TRANS_DDI_PORT_SYNC_MASTER_SELECT_MASK, ctl);
+	}
+
+	if (master_select == 0)
+		return TRANSCODER_EDP;
+	else
+		return master_select - 1;
+}
+
+static void bdw_get_trans_port_sync_config(struct intel_crtc_state *crtc_state)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
+	u32 transcoders = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
+		BIT(TRANSCODER_C) | BIT(TRANSCODER_D);
+	enum transcoder cpu_transcoder;
+
+	crtc_state->master_transcoder =
+		bdw_transcoder_master_readout(dev_priv, crtc_state->cpu_transcoder);
+
+	for_each_cpu_transcoder_masked(dev_priv, cpu_transcoder, transcoders) {
+		enum intel_display_power_domain power_domain;
+		intel_wakeref_t trans_wakeref;
+
+		power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder);
+		trans_wakeref = intel_display_power_get_if_enabled(dev_priv,
+								   power_domain);
+
+		if (!trans_wakeref)
+			continue;
+
+		if (bdw_transcoder_master_readout(dev_priv, cpu_transcoder) ==
+		    crtc_state->cpu_transcoder)
+			crtc_state->sync_mode_slaves_mask |= BIT(cpu_transcoder);
+
+		intel_display_power_put(dev_priv, power_domain, trans_wakeref);
+	}
+
+	drm_WARN_ON(&dev_priv->drm,
+		    crtc_state->master_transcoder != INVALID_TRANSCODER &&
+		    crtc_state->sync_mode_slaves_mask);
+}
+
 void intel_ddi_get_config(struct intel_encoder *encoder,
 			  struct intel_crtc_state *pipe_config)
 {
@@ -3927,9 +4140,10 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
 			pipe_config->fec_enable =
 				intel_de_read(dev_priv, dp_tp_ctl) & DP_TP_CTL_FEC_ENABLE;
 
-			DRM_DEBUG_KMS("[ENCODER:%d:%s] Fec status: %u\n",
-				      encoder->base.base.id, encoder->base.name,
-				      pipe_config->fec_enable);
+			drm_dbg_kms(&dev_priv->drm,
+				    "[ENCODER:%d:%s] Fec status: %u\n",
+				    encoder->base.base.id, encoder->base.name,
+				    pipe_config->fec_enable);
 		}
 
 		break;
@@ -3966,8 +4180,9 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
 		 * up by the BIOS, and thus we can't get the mode at module
 		 * load.
 		 */
-		DRM_DEBUG_KMS("pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n",
-			      pipe_config->pipe_bpp, dev_priv->vbt.edp.bpp);
+		drm_dbg_kms(&dev_priv->drm,
+			    "pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n",
+			    pipe_config->pipe_bpp, dev_priv->vbt.edp.bpp);
 		dev_priv->vbt.edp.bpp = pipe_config->pipe_bpp;
 	}
 
@@ -3993,6 +4208,9 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
 	intel_read_infoframe(encoder, pipe_config,
 			     HDMI_INFOFRAME_TYPE_DRM,
 			     &pipe_config->infoframes.drm);
+
+	if (INTEL_GEN(dev_priv) >= 8)
+		bdw_get_trans_port_sync_config(pipe_config);
 }
 
 static enum intel_output_type
@@ -4022,7 +4240,7 @@ static int intel_ddi_compute_config(struct intel_encoder *encoder,
 	enum port port = encoder->port;
 	int ret;
 
-	if (HAS_TRANSCODER_EDP(dev_priv) && port == PORT_A)
+	if (HAS_TRANSCODER(dev_priv, TRANSCODER_EDP) && port == PORT_A)
 		pipe_config->cpu_transcoder = TRANSCODER_EDP;
 
 	if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_HDMI)) {
@@ -4094,7 +4312,11 @@ intel_ddi_port_sync_transcoders(const struct intel_crtc_state *ref_crtc_state,
 	u8 transcoders = 0;
 	int i;
 
-	if (INTEL_GEN(dev_priv) < 11)
+	/*
+	 * We don't enable port sync on BDW due to missing w/as and
+	 * due to not having adjusted the modeset sequence appropriately.
+	 */
+	if (INTEL_GEN(dev_priv) < 9)
 		return 0;
 
 	if (!intel_crtc_has_type(ref_crtc_state, INTEL_OUTPUT_DP))
@@ -4126,12 +4348,13 @@ static int intel_ddi_compute_config_late(struct intel_encoder *encoder,
 					 struct intel_crtc_state *crtc_state,
 					 struct drm_connector_state *conn_state)
 {
+	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
 	struct drm_connector *connector = conn_state->connector;
 	u8 port_sync_transcoders = 0;
 
-	DRM_DEBUG_KMS("[ENCODER:%d:%s] [CRTC:%d:%s]",
-		      encoder->base.base.id, encoder->base.name,
-		      crtc_state->uapi.crtc->base.id, crtc_state->uapi.crtc->name);
+	drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s] [CRTC:%d:%s]",
+		    encoder->base.base.id, encoder->base.name,
+		    crtc_state->uapi.crtc->base.id, crtc_state->uapi.crtc->name);
 
 	if (connector->has_tile)
 		port_sync_transcoders = intel_ddi_port_sync_transcoders(crtc_state,
@@ -4270,7 +4493,8 @@ static int intel_hdmi_reset_link(struct intel_encoder *encoder,
 
 	ret = drm_scdc_readb(adapter, SCDC_TMDS_CONFIG, &config);
 	if (ret < 0) {
-		DRM_ERROR("Failed to read TMDS config: %d\n", ret);
+		drm_err(&dev_priv->drm, "Failed to read TMDS config: %d\n",
+			ret);
 		return 0;
 	}
 
@@ -4294,15 +4518,17 @@ static int intel_hdmi_reset_link(struct intel_encoder *encoder,
 
 static enum intel_hotplug_state
 intel_ddi_hotplug(struct intel_encoder *encoder,
-		  struct intel_connector *connector,
-		  bool irq_received)
+		  struct intel_connector *connector)
 {
+	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
 	struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
+	enum phy phy = intel_port_to_phy(i915, encoder->port);
+	bool is_tc = intel_phy_is_tc(i915, phy);
 	struct drm_modeset_acquire_ctx ctx;
 	enum intel_hotplug_state state;
 	int ret;
 
-	state = intel_encoder_hotplug(encoder, connector, irq_received);
+	state = intel_encoder_hotplug(encoder, connector);
 
 	drm_modeset_acquire_init(&ctx, 0);
 
@@ -4340,8 +4566,15 @@ intel_ddi_hotplug(struct intel_encoder *encoder,
 	 * valid EDID. To solve this schedule another detection cycle if this
 	 * time around we didn't detect any change in the sink's connection
 	 * status.
+	 *
+	 * Type-c connectors which get their HPD signal deasserted then
+	 * reasserted, without unplugging/replugging the sink from the
+	 * connector, introduce a delay until the AUX channel communication
+	 * becomes functional. Retry the detection for 5 seconds on type-c
+	 * connectors to account for this delay.
 	 */
-	if (state == INTEL_HOTPLUG_UNCHANGED && irq_received &&
+	if (state == INTEL_HOTPLUG_UNCHANGED &&
+	    connector->hotplug_retries < (is_tc ? 5 : 1) &&
 	    !dig_port->dp.is_mst)
 		state = INTEL_HOTPLUG_RETRY;
 
@@ -4416,7 +4649,8 @@ intel_ddi_max_lanes(struct intel_digital_port *intel_dport)
 	 * so we use the proper lane count for our calculations.
 	 */
 	if (intel_ddi_a_force_4_lanes(intel_dport)) {
-		DRM_DEBUG_KMS("Forcing DDI_A_4_LANES for port A\n");
+		drm_dbg_kms(&dev_priv->drm,
+			    "Forcing DDI_A_4_LANES for port A\n");
 		intel_dport->saved_port_bits |= DDI_A_4_LANES;
 		max_lanes = 4;
 	}
@@ -4444,12 +4678,14 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
 		init_dp = true;
 		init_lspcon = true;
 		init_hdmi = false;
-		DRM_DEBUG_KMS("VBT says port %c has lspcon\n", port_name(port));
+		drm_dbg_kms(&dev_priv->drm, "VBT says port %c has lspcon\n",
+			    port_name(port));
 	}
 
 	if (!init_dp && !init_hdmi) {
-		DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, respect it\n",
-			      port_name(port));
+		drm_dbg_kms(&dev_priv->drm,
+			    "VBT says port %c is not DVI/HDMI/DP compatible, respect it\n",
+			    port_name(port));
 		return;
 	}
 
@@ -4528,14 +4764,16 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
 	if (init_lspcon) {
 		if (lspcon_init(intel_dig_port))
 			/* TODO: handle hdmi info frame part */
-			DRM_DEBUG_KMS("LSPCON init success on port %c\n",
-				port_name(port));
+			drm_dbg_kms(&dev_priv->drm,
+				    "LSPCON init success on port %c\n",
+				    port_name(port));
 		else
 			/*
 			 * LSPCON init faied, but DP init was success, so
 			 * lets try to drive as DP++ port.
 			 */
-			DRM_ERROR("LSPCON init failed on port %c\n",
+			drm_err(&dev_priv->drm,
+				"LSPCON init failed on port %c\n",
 				port_name(port));
 	}
 
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.h b/drivers/gpu/drm/i915/display/intel_ddi.h
index 55fd72b901fe..de4cd877c002 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.h
+++ b/drivers/gpu/drm/i915/display/intel_ddi.h
@@ -17,7 +17,8 @@ struct intel_dp;
 struct intel_dpll_hw_state;
 struct intel_encoder;
 
-void intel_ddi_fdi_post_disable(struct intel_encoder *intel_encoder,
+void intel_ddi_fdi_post_disable(struct intel_atomic_state *state,
+				struct intel_encoder *intel_encoder,
 				const struct intel_crtc_state *old_crtc_state,
 				const struct drm_connector_state *old_conn_state);
 void hsw_fdi_link_train(struct intel_encoder *encoder,
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 346846609f45..af5b4055b38a 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -525,7 +525,7 @@ skl_wa_827(struct drm_i915_private *dev_priv, enum pipe pipe, bool enable)
 		               intel_de_read(dev_priv, CLKGATE_DIS_PSL(pipe)) & ~(DUPS1_GATING_DIS | DUPS2_GATING_DIS));
 }
 
-/* Wa_2006604312:icl */
+/* Wa_2006604312:icl,ehl */
 static void
 icl_wa_scalerclkgating(struct drm_i915_private *dev_priv, enum pipe pipe,
 		       bool enable)
@@ -544,17 +544,23 @@ needs_modeset(const struct intel_crtc_state *state)
 	return drm_atomic_crtc_needs_modeset(&state->uapi);
 }
 
-bool
-is_trans_port_sync_mode(const struct intel_crtc_state *crtc_state)
+static bool
+is_trans_port_sync_slave(const struct intel_crtc_state *crtc_state)
 {
-	return (crtc_state->master_transcoder != INVALID_TRANSCODER ||
-		crtc_state->sync_mode_slaves_mask);
+	return crtc_state->master_transcoder != INVALID_TRANSCODER;
 }
 
 static bool
-is_trans_port_sync_slave(const struct intel_crtc_state *crtc_state)
+is_trans_port_sync_master(const struct intel_crtc_state *crtc_state)
 {
-	return crtc_state->master_transcoder != INVALID_TRANSCODER;
+	return crtc_state->sync_mode_slaves_mask != 0;
+}
+
+bool
+is_trans_port_sync_mode(const struct intel_crtc_state *crtc_state)
+{
+	return is_trans_port_sync_master(crtc_state) ||
+		is_trans_port_sync_slave(crtc_state);
 }
 
 /*
@@ -620,45 +626,43 @@ int chv_calc_dpll_params(int refclk, struct dpll *clock)
 	return clock->dot / 5;
 }
 
-#define INTELPllInvalid(s)   do { /* DRM_DEBUG(s); */ return false; } while (0)
-
 /*
  * Returns whether the given set of divisors are valid for a given refclk with
  * the given connectors.
  */
-static bool intel_PLL_is_valid(struct drm_i915_private *dev_priv,
+static bool intel_pll_is_valid(struct drm_i915_private *dev_priv,
 			       const struct intel_limit *limit,
 			       const struct dpll *clock)
 {
-	if (clock->n   < limit->n.min   || limit->n.max   < clock->n)
-		INTELPllInvalid("n out of range\n");
-	if (clock->p1  < limit->p1.min  || limit->p1.max  < clock->p1)
-		INTELPllInvalid("p1 out of range\n");
-	if (clock->m2  < limit->m2.min  || limit->m2.max  < clock->m2)
-		INTELPllInvalid("m2 out of range\n");
-	if (clock->m1  < limit->m1.min  || limit->m1.max  < clock->m1)
-		INTELPllInvalid("m1 out of range\n");
+	if (clock->n < limit->n.min || limit->n.max < clock->n)
+		return false;
+	if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1)
+		return false;
+	if (clock->m2 < limit->m2.min || limit->m2.max < clock->m2)
+		return false;
+	if (clock->m1 < limit->m1.min || limit->m1.max < clock->m1)
+		return false;
 
 	if (!IS_PINEVIEW(dev_priv) && !IS_VALLEYVIEW(dev_priv) &&
 	    !IS_CHERRYVIEW(dev_priv) && !IS_GEN9_LP(dev_priv))
 		if (clock->m1 <= clock->m2)
-			INTELPllInvalid("m1 <= m2\n");
+			return false;
 
 	if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv) &&
 	    !IS_GEN9_LP(dev_priv)) {
 		if (clock->p < limit->p.min || limit->p.max < clock->p)
-			INTELPllInvalid("p out of range\n");
+			return false;
 		if (clock->m < limit->m.min || limit->m.max < clock->m)
-			INTELPllInvalid("m out of range\n");
+			return false;
 	}
 
 	if (clock->vco < limit->vco.min || limit->vco.max < clock->vco)
-		INTELPllInvalid("vco out of range\n");
+		return false;
 	/* XXX: We may need to be checking "Dot clock" depending on the multiplier,
 	 * connector, etc., rather than just a single range.
 	 */
 	if (clock->dot < limit->dot.min || limit->dot.max < clock->dot)
-		INTELPllInvalid("dot out of range\n");
+		return false;
 
 	return true;
 }
@@ -725,7 +729,7 @@ i9xx_find_best_dpll(const struct intel_limit *limit,
 					int this_err;
 
 					i9xx_calc_dpll_params(refclk, &clock);
-					if (!intel_PLL_is_valid(to_i915(dev),
+					if (!intel_pll_is_valid(to_i915(dev),
 								limit,
 								&clock))
 						continue;
@@ -781,7 +785,7 @@ pnv_find_best_dpll(const struct intel_limit *limit,
 					int this_err;
 
 					pnv_calc_dpll_params(refclk, &clock);
-					if (!intel_PLL_is_valid(to_i915(dev),
+					if (!intel_pll_is_valid(to_i915(dev),
 								limit,
 								&clock))
 						continue;
@@ -842,7 +846,7 @@ g4x_find_best_dpll(const struct intel_limit *limit,
 					int this_err;
 
 					i9xx_calc_dpll_params(refclk, &clock);
-					if (!intel_PLL_is_valid(to_i915(dev),
+					if (!intel_pll_is_valid(to_i915(dev),
 								limit,
 								&clock))
 						continue;
@@ -939,7 +943,7 @@ vlv_find_best_dpll(const struct intel_limit *limit,
 
 					vlv_calc_dpll_params(refclk, &clock);
 
-					if (!intel_PLL_is_valid(to_i915(dev),
+					if (!intel_pll_is_valid(to_i915(dev),
 								limit,
 								&clock))
 						continue;
@@ -1008,7 +1012,7 @@ chv_find_best_dpll(const struct intel_limit *limit,
 
 			chv_calc_dpll_params(refclk, &clock);
 
-			if (!intel_PLL_is_valid(to_i915(dev), limit, &clock))
+			if (!intel_pll_is_valid(to_i915(dev), limit, &clock))
 				continue;
 
 			if (!vlv_PLL_is_optimal(dev, target, &clock, best_clock,
@@ -2910,6 +2914,7 @@ intel_fb_plane_get_subsampling(int *hsub, int *vsub,
 static int
 intel_fb_check_ccs_xy(struct drm_framebuffer *fb, int ccs_plane, int x, int y)
 {
+	struct drm_i915_private *i915 = to_i915(fb->dev);
 	struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
 	int main_plane;
 	int hsub, vsub;
@@ -2938,7 +2943,8 @@ intel_fb_check_ccs_xy(struct drm_framebuffer *fb, int ccs_plane, int x, int y)
 	 * x/y offsets must match between CCS and the main surface.
 	 */
 	if (main_x != ccs_x || main_y != ccs_y) {
-		DRM_DEBUG_KMS("Bad CCS x/y (main %d,%d ccs %d,%d) full (main %d,%d ccs %d,%d)\n",
+		drm_dbg_kms(&i915->drm,
+			      "Bad CCS x/y (main %d,%d ccs %d,%d) full (main %d,%d ccs %d,%d)\n",
 			      main_x, main_y,
 			      ccs_x, ccs_y,
 			      intel_fb->normal[main_plane].x,
@@ -3336,6 +3342,8 @@ int skl_format_to_fourcc(int format, bool rgb_order, bool alpha)
 		return DRM_FORMAT_RGB565;
 	case PLANE_CTL_FORMAT_NV12:
 		return DRM_FORMAT_NV12;
+	case PLANE_CTL_FORMAT_XYUV:
+		return DRM_FORMAT_XYUV8888;
 	case PLANE_CTL_FORMAT_P010:
 		return DRM_FORMAT_P010;
 	case PLANE_CTL_FORMAT_P012:
@@ -4580,6 +4588,8 @@ static u32 skl_plane_ctl_format(u32 pixel_format)
 	case DRM_FORMAT_XRGB16161616F:
 	case DRM_FORMAT_ARGB16161616F:
 		return PLANE_CTL_FORMAT_XRGB_16161616F;
+	case DRM_FORMAT_XYUV8888:
+		return PLANE_CTL_FORMAT_XYUV;
 	case DRM_FORMAT_YUYV:
 		return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YUYV;
 	case DRM_FORMAT_YVYU:
@@ -4998,37 +5008,6 @@ static void icl_set_pipe_chicken(struct intel_crtc *crtc)
 	intel_de_write(dev_priv, PIPE_CHICKEN(pipe), tmp);
 }
 
-static void icl_enable_trans_port_sync(const struct intel_crtc_state *crtc_state)
-{
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
-	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-	u32 trans_ddi_func_ctl2_val;
-	u8 master_select;
-
-	/*
-	 * Configure the master select and enable Transcoder Port Sync for
-	 * Slave CRTCs transcoder.
-	 */
-	if (crtc_state->master_transcoder == INVALID_TRANSCODER)
-		return;
-
-	if (crtc_state->master_transcoder == TRANSCODER_EDP)
-		master_select = 0;
-	else
-		master_select = crtc_state->master_transcoder + 1;
-
-	/* Set the master select bits for Tranascoder Port Sync */
-	trans_ddi_func_ctl2_val = (PORT_SYNC_MODE_MASTER_SELECT(master_select) &
-				   PORT_SYNC_MODE_MASTER_SELECT_MASK) <<
-		PORT_SYNC_MODE_MASTER_SELECT_SHIFT;
-	/* Enable Transcoder Port Sync */
-	trans_ddi_func_ctl2_val |= PORT_SYNC_MODE_ENABLE;
-
-	intel_de_write(dev_priv,
-		       TRANS_DDI_FUNC_CTL2(crtc_state->cpu_transcoder),
-		       trans_ddi_func_ctl2_val);
-}
-
 static void intel_fdi_normal_train(struct intel_crtc *crtc)
 {
 	struct drm_device *dev = crtc->base.dev;
@@ -6200,6 +6179,7 @@ static int skl_update_scaler_plane(struct intel_crtc_state *crtc_state,
 	case DRM_FORMAT_UYVY:
 	case DRM_FORMAT_VYUY:
 	case DRM_FORMAT_NV12:
+	case DRM_FORMAT_XYUV8888:
 	case DRM_FORMAT_P010:
 	case DRM_FORMAT_P012:
 	case DRM_FORMAT_P016:
@@ -6463,8 +6443,8 @@ static bool needs_scalerclk_wa(const struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
 
-	/* Wa_2006604312:icl */
-	if (crtc_state->scaler_state.scaler_users > 0 && IS_ICELAKE(dev_priv))
+	/* Wa_2006604312:icl,ehl */
+	if (crtc_state->scaler_state.scaler_users > 0 && IS_GEN(dev_priv, 11))
 		return true;
 
 	return false;
@@ -6534,7 +6514,7 @@ static void intel_pre_plane_update(struct intel_atomic_state *state,
 	    needs_nv12_wa(new_crtc_state))
 		skl_wa_827(dev_priv, pipe, true);
 
-	/* Wa_2006604312:icl */
+	/* Wa_2006604312:icl,ehl */
 	if (!needs_scalerclk_wa(old_crtc_state) &&
 	    needs_scalerclk_wa(new_crtc_state))
 		icl_wa_scalerclkgating(dev_priv, pipe, true);
@@ -6720,7 +6700,8 @@ static void intel_encoders_pre_pll_enable(struct intel_atomic_state *state,
 			continue;
 
 		if (encoder->pre_pll_enable)
-			encoder->pre_pll_enable(encoder, crtc_state, conn_state);
+			encoder->pre_pll_enable(state, encoder,
+						crtc_state, conn_state);
 	}
 }
 
@@ -6741,7 +6722,8 @@ static void intel_encoders_pre_enable(struct intel_atomic_state *state,
 			continue;
 
 		if (encoder->pre_enable)
-			encoder->pre_enable(encoder, crtc_state, conn_state);
+			encoder->pre_enable(state, encoder,
+					    crtc_state, conn_state);
 	}
 }
 
@@ -6762,7 +6744,8 @@ static void intel_encoders_enable(struct intel_atomic_state *state,
 			continue;
 
 		if (encoder->enable)
-			encoder->enable(encoder, crtc_state, conn_state);
+			encoder->enable(state, encoder,
+					crtc_state, conn_state);
 		intel_opregion_notify_encoder(encoder, true);
 	}
 }
@@ -6785,7 +6768,8 @@ static void intel_encoders_disable(struct intel_atomic_state *state,
 
 		intel_opregion_notify_encoder(encoder, false);
 		if (encoder->disable)
-			encoder->disable(encoder, old_crtc_state, old_conn_state);
+			encoder->disable(state, encoder,
+					 old_crtc_state, old_conn_state);
 	}
 }
 
@@ -6806,7 +6790,8 @@ static void intel_encoders_post_disable(struct intel_atomic_state *state,
 			continue;
 
 		if (encoder->post_disable)
-			encoder->post_disable(encoder, old_crtc_state, old_conn_state);
+			encoder->post_disable(state, encoder,
+					      old_crtc_state, old_conn_state);
 	}
 }
 
@@ -6827,7 +6812,8 @@ static void intel_encoders_post_pll_disable(struct intel_atomic_state *state,
 			continue;
 
 		if (encoder->post_pll_disable)
-			encoder->post_pll_disable(encoder, old_crtc_state, old_conn_state);
+			encoder->post_pll_disable(state, encoder,
+						  old_crtc_state, old_conn_state);
 	}
 }
 
@@ -6848,7 +6834,8 @@ static void intel_encoders_update_pipe(struct intel_atomic_state *state,
 			continue;
 
 		if (encoder->update_pipe)
-			encoder->update_pipe(encoder, crtc_state, conn_state);
+			encoder->update_pipe(state, encoder,
+					     crtc_state, conn_state);
 	}
 }
 
@@ -7037,9 +7024,6 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,
 	if (!transcoder_is_dsi(cpu_transcoder))
 		intel_set_pipe_timings(new_crtc_state);
 
-	if (INTEL_GEN(dev_priv) >= 11)
-		icl_enable_trans_port_sync(new_crtc_state);
-
 	intel_set_pipe_src_size(new_crtc_state);
 
 	if (cpu_transcoder != TRANSCODER_EDP &&
@@ -9398,7 +9382,6 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
 	pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
 	pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;
 	pipe_config->shared_dpll = NULL;
-	pipe_config->master_transcoder = INVALID_TRANSCODER;
 
 	ret = false;
 
@@ -10622,7 +10605,6 @@ static bool ilk_get_pipe_config(struct intel_crtc *crtc,
 
 	pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;
 	pipe_config->shared_dpll = NULL;
-	pipe_config->master_transcoder = INVALID_TRANSCODER;
 
 	ret = false;
 	tmp = intel_de_read(dev_priv, PIPECONF(crtc->pipe));
@@ -10891,7 +10873,7 @@ static bool hsw_get_transcoder_state(struct intel_crtc *crtc,
 		panel_transcoder_mask |=
 			BIT(TRANSCODER_DSI_0) | BIT(TRANSCODER_DSI_1);
 
-	if (HAS_TRANSCODER_EDP(dev_priv))
+	if (HAS_TRANSCODER(dev_priv, TRANSCODER_EDP))
 		panel_transcoder_mask |= BIT(TRANSCODER_EDP);
 
 	/*
@@ -11085,61 +11067,6 @@ static void hsw_get_ddi_port_state(struct intel_crtc *crtc,
 	}
 }
 
-static enum transcoder transcoder_master_readout(struct drm_i915_private *dev_priv,
-						 enum transcoder cpu_transcoder)
-{
-	u32 trans_port_sync, master_select;
-
-	trans_port_sync = intel_de_read(dev_priv,
-				        TRANS_DDI_FUNC_CTL2(cpu_transcoder));
-
-	if ((trans_port_sync & PORT_SYNC_MODE_ENABLE) == 0)
-		return INVALID_TRANSCODER;
-
-	master_select = trans_port_sync &
-			PORT_SYNC_MODE_MASTER_SELECT_MASK;
-	if (master_select == 0)
-		return TRANSCODER_EDP;
-	else
-		return master_select - 1;
-}
-
-static void icl_get_trans_port_sync_config(struct intel_crtc_state *crtc_state)
-{
-	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
-	u32 transcoders;
-	enum transcoder cpu_transcoder;
-
-	crtc_state->master_transcoder = transcoder_master_readout(dev_priv,
-								  crtc_state->cpu_transcoder);
-
-	transcoders = BIT(TRANSCODER_A) |
-		BIT(TRANSCODER_B) |
-		BIT(TRANSCODER_C) |
-		BIT(TRANSCODER_D);
-	for_each_cpu_transcoder_masked(dev_priv, cpu_transcoder, transcoders) {
-		enum intel_display_power_domain power_domain;
-		intel_wakeref_t trans_wakeref;
-
-		power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder);
-		trans_wakeref = intel_display_power_get_if_enabled(dev_priv,
-								   power_domain);
-
-		if (!trans_wakeref)
-			continue;
-
-		if (transcoder_master_readout(dev_priv, cpu_transcoder) ==
-		    crtc_state->cpu_transcoder)
-			crtc_state->sync_mode_slaves_mask |= BIT(cpu_transcoder);
-
-		intel_display_power_put(dev_priv, power_domain, trans_wakeref);
-	}
-
-	drm_WARN_ON(&dev_priv->drm,
-		    crtc_state->master_transcoder != INVALID_TRANSCODER &&
-		    crtc_state->sync_mode_slaves_mask);
-}
-
 static bool hsw_get_pipe_config(struct intel_crtc *crtc,
 				struct intel_crtc_state *pipe_config)
 {
@@ -11271,10 +11198,6 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
 		pipe_config->pixel_multiplier = 1;
 	}
 
-	if (INTEL_GEN(dev_priv) >= 11 &&
-	    !transcoder_is_dsi(pipe_config->cpu_transcoder))
-		icl_get_trans_port_sync_config(pipe_config);
-
 out:
 	for_each_power_domain(power_domain, power_domain_mask)
 		intel_display_power_put(dev_priv,
@@ -12377,10 +12300,8 @@ int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_stat
 	 * only combine the results from all planes in the current place?
 	 */
 	if (!is_crtc_enabled) {
-		plane_state->uapi.visible = visible = false;
-		crtc_state->active_planes &= ~BIT(plane->id);
-		crtc_state->data_rate[plane->id] = 0;
-		crtc_state->min_cdclk[plane->id] = 0;
+		intel_plane_set_invisible(crtc_state, plane_state);
+		visible = false;
 	}
 
 	if (!was_visible && !visible)
@@ -12886,16 +12807,17 @@ compute_baseline_pipe_bpp(struct intel_crtc *crtc,
 	return 0;
 }
 
-static void intel_dump_crtc_timings(const struct drm_display_mode *mode)
+static void intel_dump_crtc_timings(struct drm_i915_private *i915,
+				    const struct drm_display_mode *mode)
 {
-	DRM_DEBUG_KMS("crtc timings: %d %d %d %d %d %d %d %d %d, "
-		      "type: 0x%x flags: 0x%x\n",
-		      mode->crtc_clock,
-		      mode->crtc_hdisplay, mode->crtc_hsync_start,
-		      mode->crtc_hsync_end, mode->crtc_htotal,
-		      mode->crtc_vdisplay, mode->crtc_vsync_start,
-		      mode->crtc_vsync_end, mode->crtc_vtotal,
-		      mode->type, mode->flags);
+	drm_dbg_kms(&i915->drm, "crtc timings: %d %d %d %d %d %d %d %d %d, "
+		    "type: 0x%x flags: 0x%x\n",
+		    mode->crtc_clock,
+		    mode->crtc_hdisplay, mode->crtc_hsync_start,
+		    mode->crtc_hsync_end, mode->crtc_htotal,
+		    mode->crtc_vdisplay, mode->crtc_vsync_start,
+		    mode->crtc_vsync_end, mode->crtc_vtotal,
+		    mode->type, mode->flags);
 }
 
 static inline void
@@ -13042,6 +12964,11 @@ static void intel_dump_pipe_config(const struct intel_crtc_state *pipe_config,
 		    transcoder_name(pipe_config->cpu_transcoder),
 		    pipe_config->pipe_bpp, pipe_config->dither);
 
+	drm_dbg_kms(&dev_priv->drm,
+		    "port sync: master transcoder: %s, slave transcoder bitmask = 0x%x\n",
+		    transcoder_name(pipe_config->master_transcoder),
+		    pipe_config->sync_mode_slaves_mask);
+
 	if (pipe_config->has_pch_encoder)
 		intel_dump_m_n_config(pipe_config, "fdi",
 				      pipe_config->fdi_lanes,
@@ -13079,7 +13006,7 @@ static void intel_dump_pipe_config(const struct intel_crtc_state *pipe_config,
 	drm_mode_debug_printmodeline(&pipe_config->hw.mode);
 	drm_dbg_kms(&dev_priv->drm, "adjusted mode:\n");
 	drm_mode_debug_printmodeline(&pipe_config->hw.adjusted_mode);
-	intel_dump_crtc_timings(&pipe_config->hw.adjusted_mode);
+	intel_dump_crtc_timings(dev_priv, &pipe_config->hw.adjusted_mode);
 	drm_dbg_kms(&dev_priv->drm,
 		    "port clock: %d, pipe src size: %dx%d, pixel rate %d\n",
 		    pipe_config->port_clock,
@@ -14999,11 +14926,13 @@ static void intel_pipe_fastset(const struct intel_crtc_state *old_crtc_state,
 }
 
 static void commit_pipe_config(struct intel_atomic_state *state,
-			       struct intel_crtc_state *old_crtc_state,
-			       struct intel_crtc_state *new_crtc_state)
+			       struct intel_crtc *crtc)
 {
-	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+	const struct intel_crtc_state *old_crtc_state =
+		intel_atomic_get_old_crtc_state(state, crtc);
+	const struct intel_crtc_state *new_crtc_state =
+		intel_atomic_get_new_crtc_state(state, crtc);
 	bool modeset = needs_modeset(new_crtc_state);
 
 	/*
@@ -15029,22 +14958,35 @@ static void commit_pipe_config(struct intel_atomic_state *state,
 		dev_priv->display.atomic_update_watermarks(state, crtc);
 }
 
-static void intel_update_crtc(struct intel_crtc *crtc,
-			      struct intel_atomic_state *state,
-			      struct intel_crtc_state *old_crtc_state,
-			      struct intel_crtc_state *new_crtc_state)
+static void intel_enable_crtc(struct intel_atomic_state *state,
+			      struct intel_crtc *crtc)
 {
 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
-	bool modeset = needs_modeset(new_crtc_state);
+	const struct intel_crtc_state *new_crtc_state =
+		intel_atomic_get_new_crtc_state(state, crtc);
 
-	if (modeset) {
-		intel_crtc_update_active_timings(new_crtc_state);
+	if (!needs_modeset(new_crtc_state))
+		return;
 
-		dev_priv->display.crtc_enable(state, crtc);
+	intel_crtc_update_active_timings(new_crtc_state);
 
-		/* vblanks work again, re-enable pipe CRC. */
-		intel_crtc_enable_pipe_crc(crtc);
-	} else {
+	dev_priv->display.crtc_enable(state, crtc);
+
+	/* vblanks work again, re-enable pipe CRC. */
+	intel_crtc_enable_pipe_crc(crtc);
+}
+
+static void intel_update_crtc(struct intel_atomic_state *state,
+			      struct intel_crtc *crtc)
+{
+	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+	const struct intel_crtc_state *old_crtc_state =
+		intel_atomic_get_old_crtc_state(state, crtc);
+	struct intel_crtc_state *new_crtc_state =
+		intel_atomic_get_new_crtc_state(state, crtc);
+	bool modeset = needs_modeset(new_crtc_state);
+
+	if (!modeset) {
 		if (new_crtc_state->preload_luts &&
 		    (new_crtc_state->uapi.color_mgmt_changed ||
 		     new_crtc_state->update_pipe))
@@ -15064,7 +15006,7 @@ static void intel_update_crtc(struct intel_crtc *crtc,
 	/* Perform vblank evasion around commit operation */
 	intel_pipe_update_start(new_crtc_state);
 
-	commit_pipe_config(state, old_crtc_state, new_crtc_state);
+	commit_pipe_config(state, crtc);
 
 	if (INTEL_GEN(dev_priv) >= 9)
 		skl_update_planes_on_crtc(state, crtc);
@@ -15084,18 +15026,6 @@ static void intel_update_crtc(struct intel_crtc *crtc,
 		intel_crtc_arm_fifo_underrun(crtc, new_crtc_state);
 }
 
-static struct intel_crtc *intel_get_slave_crtc(const struct intel_crtc_state *new_crtc_state)
-{
-	struct drm_i915_private *dev_priv = to_i915(new_crtc_state->uapi.crtc->dev);
-	enum transcoder slave_transcoder;
-
-	drm_WARN_ON(&dev_priv->drm,
-		    !is_power_of_2(new_crtc_state->sync_mode_slaves_mask));
-
-	slave_transcoder = ffs(new_crtc_state->sync_mode_slaves_mask) - 1;
-	return intel_get_crtc_for_pipe(dev_priv,
-				       (enum pipe)slave_transcoder);
-}
 
 static void intel_old_crtc_state_disables(struct intel_atomic_state *state,
 					  struct intel_crtc_state *old_crtc_state,
@@ -15171,129 +15101,19 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
 
 static void intel_commit_modeset_enables(struct intel_atomic_state *state)
 {
+	struct intel_crtc_state *new_crtc_state;
 	struct intel_crtc *crtc;
-	struct intel_crtc_state *old_crtc_state, *new_crtc_state;
 	int i;
 
-	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
+	for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
 		if (!new_crtc_state->hw.active)
 			continue;
 
-		intel_update_crtc(crtc, state, old_crtc_state,
-				  new_crtc_state);
+		intel_enable_crtc(state, crtc);
+		intel_update_crtc(state, crtc);
 	}
 }
 
-static void intel_crtc_enable_trans_port_sync(struct intel_crtc *crtc,
-					      struct intel_atomic_state *state,
-					      struct intel_crtc_state *new_crtc_state)
-{
-	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
-
-	intel_crtc_update_active_timings(new_crtc_state);
-	dev_priv->display.crtc_enable(state, crtc);
-	intel_crtc_enable_pipe_crc(crtc);
-}
-
-static void intel_set_dp_tp_ctl_normal(struct intel_crtc *crtc,
-				       struct intel_atomic_state *state)
-{
-	struct drm_connector *uninitialized_var(conn);
-	struct drm_connector_state *conn_state;
-	struct intel_dp *intel_dp;
-	int i;
-
-	for_each_new_connector_in_state(&state->base, conn, conn_state, i) {
-		if (conn_state->crtc == &crtc->base)
-			break;
-	}
-	intel_dp = intel_attached_dp(to_intel_connector(conn));
-	intel_dp_stop_link_train(intel_dp);
-}
-
-/*
- * TODO: This is only called from port sync and it is identical to what will be
- * executed again in intel_update_crtc() over port sync pipes
- */
-static void intel_post_crtc_enable_updates(struct intel_crtc *crtc,
-					   struct intel_atomic_state *state)
-{
-	struct intel_crtc_state *new_crtc_state =
-		intel_atomic_get_new_crtc_state(state, crtc);
-	struct intel_crtc_state *old_crtc_state =
-		intel_atomic_get_old_crtc_state(state, crtc);
-	bool modeset = needs_modeset(new_crtc_state);
-
-	if (new_crtc_state->update_pipe && !new_crtc_state->enable_fbc)
-		intel_fbc_disable(crtc);
-	else
-		intel_fbc_enable(state, crtc);
-
-	/* Perform vblank evasion around commit operation */
-	intel_pipe_update_start(new_crtc_state);
-	commit_pipe_config(state, old_crtc_state, new_crtc_state);
-	skl_update_planes_on_crtc(state, crtc);
-	intel_pipe_update_end(new_crtc_state);
-
-	/*
-	 * We usually enable FIFO underrun interrupts as part of the
-	 * CRTC enable sequence during modesets.  But when we inherit a
-	 * valid pipe configuration from the BIOS we need to take care
-	 * of enabling them on the CRTC's first fastset.
-	 */
-	if (new_crtc_state->update_pipe && !modeset &&
-	    old_crtc_state->hw.mode.private_flags & I915_MODE_FLAG_INHERITED)
-		intel_crtc_arm_fifo_underrun(crtc, new_crtc_state);
-}
-
-static void intel_update_trans_port_sync_crtcs(struct intel_crtc *crtc,
-					       struct intel_atomic_state *state,
-					       struct intel_crtc_state *old_crtc_state,
-					       struct intel_crtc_state *new_crtc_state)
-{
-	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
-	struct intel_crtc *slave_crtc = intel_get_slave_crtc(new_crtc_state);
-	struct intel_crtc_state *new_slave_crtc_state =
-		intel_atomic_get_new_crtc_state(state, slave_crtc);
-	struct intel_crtc_state *old_slave_crtc_state =
-		intel_atomic_get_old_crtc_state(state, slave_crtc);
-
-	drm_WARN_ON(&i915->drm, !slave_crtc || !new_slave_crtc_state ||
-		    !old_slave_crtc_state);
-
-	drm_dbg_kms(&i915->drm,
-		    "Updating Transcoder Port Sync Master CRTC = %d %s and Slave CRTC %d %s\n",
-		    crtc->base.base.id, crtc->base.name,
-		    slave_crtc->base.base.id, slave_crtc->base.name);
-
-	/* Enable seq for slave with with DP_TP_CTL left Idle until the
-	 * master is ready
-	 */
-	intel_crtc_enable_trans_port_sync(slave_crtc,
-					  state,
-					  new_slave_crtc_state);
-
-	/* Enable seq for master with with DP_TP_CTL left Idle */
-	intel_crtc_enable_trans_port_sync(crtc,
-					  state,
-					  new_crtc_state);
-
-	/* Set Slave's DP_TP_CTL to Normal */
-	intel_set_dp_tp_ctl_normal(slave_crtc,
-				   state);
-
-	/* Set Master's DP_TP_CTL To Normal */
-	usleep_range(200, 400);
-	intel_set_dp_tp_ctl_normal(crtc,
-				   state);
-
-	/* Now do the post crtc enable for all master and slaves */
-	intel_post_crtc_enable_updates(slave_crtc,
-				       state);
-	intel_post_crtc_enable_updates(crtc,
-				       state);
-}
-
 static void icl_dbuf_slice_pre_update(struct intel_atomic_state *state)
 {
 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
@@ -15365,8 +15185,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
 			entries[pipe] = new_crtc_state->wm.skl.ddb;
 			update_pipes &= ~BIT(pipe);
 
-			intel_update_crtc(crtc, state, old_crtc_state,
-					  new_crtc_state);
+			intel_update_crtc(state, crtc);
 
 			/*
 			 * If this is an already active pipe, it's DDB changed,
@@ -15381,67 +15200,62 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
 		}
 	}
 
+	update_pipes = modeset_pipes;
+
 	/*
 	 * Enable all pipes that needs a modeset and do not depends on other
 	 * pipes
 	 */
-	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
-					    new_crtc_state, i) {
+	for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
 		enum pipe pipe = crtc->pipe;
 
 		if ((modeset_pipes & BIT(pipe)) == 0)
 			continue;
 
 		if (intel_dp_mst_is_slave_trans(new_crtc_state) ||
-		    is_trans_port_sync_slave(new_crtc_state))
+		    is_trans_port_sync_master(new_crtc_state))
 			continue;
 
-		drm_WARN_ON(&dev_priv->drm, skl_ddb_allocation_overlaps(&new_crtc_state->wm.skl.ddb,
-									entries, I915_MAX_PIPES, pipe));
-
-		entries[pipe] = new_crtc_state->wm.skl.ddb;
 		modeset_pipes &= ~BIT(pipe);
 
-		if (is_trans_port_sync_mode(new_crtc_state)) {
-			struct intel_crtc *slave_crtc;
+		intel_enable_crtc(state, crtc);
+	}
 
-			intel_update_trans_port_sync_crtcs(crtc, state,
-							   old_crtc_state,
-							   new_crtc_state);
+	/*
+	 * Then we enable all remaining pipes that depend on other
+	 * pipes: MST slaves and port sync masters.
+	 */
+	for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
+		enum pipe pipe = crtc->pipe;
 
-			slave_crtc = intel_get_slave_crtc(new_crtc_state);
-			/* TODO: update entries[] of slave */
-			modeset_pipes &= ~BIT(slave_crtc->pipe);
+		if ((modeset_pipes & BIT(pipe)) == 0)
+			continue;
 
-		} else {
-			intel_update_crtc(crtc, state, old_crtc_state,
-					  new_crtc_state);
-		}
+		modeset_pipes &= ~BIT(pipe);
+
+		intel_enable_crtc(state, crtc);
 	}
 
 	/*
-	 * Finally enable all pipes that needs a modeset and depends on
-	 * other pipes, right now it is only MST slaves as both port sync slave
-	 * and master are enabled together
+	 * Finally we do the plane updates/etc. for all pipes that got enabled.
 	 */
-	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
-					    new_crtc_state, i) {
+	for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
 		enum pipe pipe = crtc->pipe;
 
-		if ((modeset_pipes & BIT(pipe)) == 0)
+		if ((update_pipes & BIT(pipe)) == 0)
 			continue;
 
 		drm_WARN_ON(&dev_priv->drm, skl_ddb_allocation_overlaps(&new_crtc_state->wm.skl.ddb,
 									entries, I915_MAX_PIPES, pipe));
 
 		entries[pipe] = new_crtc_state->wm.skl.ddb;
-		modeset_pipes &= ~BIT(pipe);
+		update_pipes &= ~BIT(pipe);
 
-		intel_update_crtc(crtc, state, old_crtc_state, new_crtc_state);
+		intel_update_crtc(state, crtc);
 	}
 
 	drm_WARN_ON(&dev_priv->drm, modeset_pipes);
-
+	drm_WARN_ON(&dev_priv->drm, update_pipes);
 }
 
 static void intel_atomic_helper_free_state(struct drm_i915_private *dev_priv)
@@ -18261,11 +18075,12 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder)
 			best_encoder = connector->base.state->best_encoder;
 			connector->base.state->best_encoder = &encoder->base;
 
+			/* FIXME NULL atomic state passed! */
 			if (encoder->disable)
-				encoder->disable(encoder, crtc_state,
+				encoder->disable(NULL, encoder, crtc_state,
 						 connector->base.state);
 			if (encoder->post_disable)
-				encoder->post_disable(encoder, crtc_state,
+				encoder->post_disable(NULL, encoder, crtc_state,
 						      connector->base.state);
 
 			connector->base.state->best_encoder = best_encoder;
@@ -18802,15 +18617,6 @@ void intel_modeset_driver_remove_noirq(struct drm_i915_private *i915)
 
 #if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR)
 
-static bool
-has_transcoder(struct drm_i915_private *dev_priv, enum transcoder cpu_transcoder)
-{
-	if (cpu_transcoder == TRANSCODER_EDP)
-		return HAS_TRANSCODER_EDP(dev_priv);
-	else
-		return INTEL_INFO(dev_priv)->pipe_mask & BIT(cpu_transcoder);
-}
-
 struct intel_display_error_state {
 
 	u32 power_well_driver;
@@ -18919,7 +18725,7 @@ intel_display_capture_error_state(struct drm_i915_private *dev_priv)
 	for (i = 0; i < ARRAY_SIZE(error->transcoder); i++) {
 		enum transcoder cpu_transcoder = transcoders[i];
 
-		if (!has_transcoder(dev_priv, cpu_transcoder))
+		if (!HAS_TRANSCODER(dev_priv, cpu_transcoder))
 			continue;
 
 		error->transcoder[i].available = true;
diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
index adb1225a3480..cc7f287804d7 100644
--- a/drivers/gpu/drm/i915/display/intel_display.h
+++ b/drivers/gpu/drm/i915/display/intel_display.h
@@ -320,9 +320,13 @@ enum phy_fia {
 	for_each_pipe(__dev_priv, __p) \
 		for_each_if((__mask) & BIT(__p))
 
-#define for_each_cpu_transcoder_masked(__dev_priv, __t, __mask) \
+#define for_each_cpu_transcoder(__dev_priv, __t) \
 	for ((__t) = 0; (__t) < I915_MAX_TRANSCODERS; (__t)++)	\
-		for_each_if ((__mask) & (1 << (__t)))
+		for_each_if (INTEL_INFO(__dev_priv)->cpu_transcoder_mask & BIT(__t))
+
+#define for_each_cpu_transcoder_masked(__dev_priv, __t, __mask) \
+	for_each_cpu_transcoder(__dev_priv, __t) \
+		for_each_if ((__mask) & BIT(__t))
 
 #define for_each_universal_plane(__dev_priv, __pipe, __p)		\
 	for ((__p) = 0;							\
diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
index 1e6eb7f2f72d..bdeea2e02642 100644
--- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
+++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
@@ -631,15 +631,9 @@ static void intel_dp_info(struct seq_file *m,
 }
 
 static void intel_dp_mst_info(struct seq_file *m,
-			  struct intel_connector *intel_connector)
+			      struct intel_connector *intel_connector)
 {
-	struct intel_encoder *intel_encoder = intel_attached_encoder(intel_connector);
-	struct intel_dp_mst_encoder *intel_mst =
-		enc_to_mst(intel_encoder);
-	struct intel_digital_port *intel_dig_port = intel_mst->primary;
-	struct intel_dp *intel_dp = &intel_dig_port->dp;
-	bool has_audio = drm_dp_mst_port_has_audio(&intel_dp->mst_mgr,
-					intel_connector->port);
+	bool has_audio = intel_connector->port->has_audio;
 
 	seq_printf(m, "\taudio support: %s\n", yesno(has_audio));
 }
@@ -1326,6 +1320,16 @@ static int i915_displayport_test_data_show(struct seq_file *m, void *data)
 					   intel_dp->compliance.test_data.vdisplay);
 				seq_printf(m, "bpc: %u\n",
 					   intel_dp->compliance.test_data.bpc);
+			} else if (intel_dp->compliance.test_type ==
+				   DP_TEST_LINK_PHY_TEST_PATTERN) {
+				seq_printf(m, "pattern: %d\n",
+					   intel_dp->compliance.test_data.phytest.phy_pattern);
+				seq_printf(m, "Number of lanes: %d\n",
+					   intel_dp->compliance.test_data.phytest.num_lanes);
+				seq_printf(m, "Link Rate: %d\n",
+					   intel_dp->compliance.test_data.phytest.link_rate);
+				seq_printf(m, "level: %02x\n",
+					   intel_dp->train_set[0]);
 			}
 		} else
 			seq_puts(m, "0");
@@ -1358,7 +1362,7 @@ static int i915_displayport_test_type_show(struct seq_file *m, void *data)
 
 		if (encoder && connector->status == connector_status_connected) {
 			intel_dp = enc_to_intel_dp(encoder);
-			seq_printf(m, "%02lx", intel_dp->compliance.test_type);
+			seq_printf(m, "%02lx\n", intel_dp->compliance.test_type);
 		} else
 			seq_puts(m, "0");
 	}
@@ -1927,7 +1931,7 @@ static const struct {
 	{"i915_edp_psr_debug", &i915_edp_psr_debug_fops},
 };
 
-int intel_display_debugfs_register(struct drm_i915_private *i915)
+void intel_display_debugfs_register(struct drm_i915_private *i915)
 {
 	struct drm_minor *minor = i915->drm.primary;
 	int i;
@@ -1940,9 +1944,9 @@ int intel_display_debugfs_register(struct drm_i915_private *i915)
 				    intel_display_debugfs_files[i].fops);
 	}
 
-	return drm_debugfs_create_files(intel_display_debugfs_list,
-					ARRAY_SIZE(intel_display_debugfs_list),
-					minor->debugfs_root, minor);
+	drm_debugfs_create_files(intel_display_debugfs_list,
+				 ARRAY_SIZE(intel_display_debugfs_list),
+				 minor->debugfs_root, minor);
 }
 
 static int i915_panel_show(struct seq_file *m, void *data)
diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.h b/drivers/gpu/drm/i915/display/intel_display_debugfs.h
index a3bea1ce04c2..c922c1745bfe 100644
--- a/drivers/gpu/drm/i915/display/intel_display_debugfs.h
+++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.h
@@ -10,10 +10,10 @@ struct drm_connector;
 struct drm_i915_private;
 
 #ifdef CONFIG_DEBUG_FS
-int intel_display_debugfs_register(struct drm_i915_private *i915);
+void intel_display_debugfs_register(struct drm_i915_private *i915);
 int intel_connector_debugfs_add(struct drm_connector *connector);
 #else
-static inline int intel_display_debugfs_register(struct drm_i915_private *i915) { return 0; }
+static inline void intel_display_debugfs_register(struct drm_i915_private *i915) {}
 static inline int intel_connector_debugfs_add(struct drm_connector *connector) { return 0; }
 #endif
 
diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c
index 246e406bb385..6cc0e23ca566 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power.c
@@ -1873,20 +1873,27 @@ __async_put_domains_state_ok(struct i915_power_domains *power_domains)
 static void print_power_domains(struct i915_power_domains *power_domains,
 				const char *prefix, u64 mask)
 {
+	struct drm_i915_private *i915 = container_of(power_domains,
+						     struct drm_i915_private,
+						     power_domains);
 	enum intel_display_power_domain domain;
 
-	DRM_DEBUG_DRIVER("%s (%lu):\n", prefix, hweight64(mask));
+	drm_dbg(&i915->drm, "%s (%lu):\n", prefix, hweight64(mask));
 	for_each_power_domain(domain, mask)
-		DRM_DEBUG_DRIVER("%s use_count %d\n",
-				 intel_display_power_domain_str(domain),
-				 power_domains->domain_use_count[domain]);
+		drm_dbg(&i915->drm, "%s use_count %d\n",
+			intel_display_power_domain_str(domain),
+			power_domains->domain_use_count[domain]);
 }
 
 static void
 print_async_put_domains_state(struct i915_power_domains *power_domains)
 {
-	DRM_DEBUG_DRIVER("async_put_wakeref %u\n",
-			 power_domains->async_put_wakeref);
+	struct drm_i915_private *i915 = container_of(power_domains,
+						     struct drm_i915_private,
+						     power_domains);
+
+	drm_dbg(&i915->drm, "async_put_wakeref %u\n",
+		power_domains->async_put_wakeref);
 
 	print_power_domains(power_domains, "async_put_domains[0]",
 			    power_domains->async_put_domains[0]);
@@ -4480,7 +4487,8 @@ void icl_dbuf_slices_update(struct drm_i915_private *dev_priv,
 	drm_WARN(&dev_priv->drm, hweight8(req_slices) > max_slices,
 		 "Invalid number of dbuf slices requested\n");
 
-	DRM_DEBUG_KMS("Updating dbuf slices to 0x%x\n", req_slices);
+	drm_dbg_kms(&dev_priv->drm, "Updating dbuf slices to 0x%x\n",
+		    req_slices);
 
 	/*
 	 * Might be running this in parallel to gen9_dc_off_power_well_enable
@@ -5016,7 +5024,7 @@ static void tgl_bw_buddy_init(struct drm_i915_private *dev_priv)
 	const struct buddy_page_mask *table;
 	int i;
 
-	if (IS_TGL_REVID(dev_priv, TGL_REVID_A0, TGL_REVID_A0))
+	if (IS_TGL_REVID(dev_priv, TGL_REVID_A0, TGL_REVID_B0))
 		/* Wa_1409767108: tgl */
 		table = wa_1409767108_buddy_page_masks;
 	else
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 5e00e611f077..ba8c08145c88 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -132,8 +132,7 @@ struct intel_encoder {
 	u16 cloneable;
 	u8 pipe_mask;
 	enum intel_hotplug_state (*hotplug)(struct intel_encoder *encoder,
-					    struct intel_connector *connector,
-					    bool irq_received);
+					    struct intel_connector *connector);
 	enum intel_output_type (*compute_output_type)(struct intel_encoder *,
 						      struct intel_crtc_state *,
 						      struct drm_connector_state *);
@@ -146,28 +145,35 @@ struct intel_encoder {
 	void (*update_prepare)(struct intel_atomic_state *,
 			       struct intel_encoder *,
 			       struct intel_crtc *);
-	void (*pre_pll_enable)(struct intel_encoder *,
+	void (*pre_pll_enable)(struct intel_atomic_state *,
+			       struct intel_encoder *,
 			       const struct intel_crtc_state *,
 			       const struct drm_connector_state *);
-	void (*pre_enable)(struct intel_encoder *,
+	void (*pre_enable)(struct intel_atomic_state *,
+			   struct intel_encoder *,
 			   const struct intel_crtc_state *,
 			   const struct drm_connector_state *);
-	void (*enable)(struct intel_encoder *,
+	void (*enable)(struct intel_atomic_state *,
+		       struct intel_encoder *,
 		       const struct intel_crtc_state *,
 		       const struct drm_connector_state *);
 	void (*update_complete)(struct intel_atomic_state *,
 				struct intel_encoder *,
 				struct intel_crtc *);
-	void (*disable)(struct intel_encoder *,
+	void (*disable)(struct intel_atomic_state *,
+			struct intel_encoder *,
 			const struct intel_crtc_state *,
 			const struct drm_connector_state *);
-	void (*post_disable)(struct intel_encoder *,
+	void (*post_disable)(struct intel_atomic_state *,
+			     struct intel_encoder *,
 			     const struct intel_crtc_state *,
 			     const struct drm_connector_state *);
-	void (*post_pll_disable)(struct intel_encoder *,
+	void (*post_pll_disable)(struct intel_atomic_state *,
+				 struct intel_encoder *,
 				 const struct intel_crtc_state *,
 				 const struct drm_connector_state *);
-	void (*update_pipe)(struct intel_encoder *,
+	void (*update_pipe)(struct intel_atomic_state *,
+			    struct intel_encoder *,
 			    const struct intel_crtc_state *,
 			    const struct drm_connector_state *);
 	/* Read out the current hw state of this connector, returning true if
@@ -425,11 +431,14 @@ struct intel_connector {
 	struct edid *edid;
 	struct edid *detect_edid;
 
+	/* Number of times hotplug detection was tried after an HPD interrupt */
+	int hotplug_retries;
+
 	/* since POLL and HPD connectors may use the same HPD line keep the native
 	   state of connector->polled in case hotplug storm detection changes it */
 	u8 polled;
 
-	void *port; /* store this opaque as its illegal to dereference it */
+	struct drm_dp_mst_port *port;
 
 	struct intel_dp *mst_port;
 
@@ -640,6 +649,16 @@ struct intel_crtc_scaler_state {
 #define I915_MODE_FLAG_GET_SCANLINE_FROM_TIMESTAMP (1<<1)
 /* Flag to use the scanline counter instead of the pixel counter */
 #define I915_MODE_FLAG_USE_SCANLINE_COUNTER (1<<2)
+/*
+ * TE0 or TE1 flag is set if the crtc has a DSI encoder which
+ * is operating in command mode.
+ * Flag to use TE from DSI0 instead of VBI in command mode
+ */
+#define I915_MODE_FLAG_DSI_USE_TE0 (1<<3)
+/* Flag to use TE from DSI1 instead of VBI in command mode */
+#define I915_MODE_FLAG_DSI_USE_TE1 (1<<4)
+/* Flag to indicate mipi dsi periodic command mode where we do not get TE */
+#define I915_MODE_FLAG_DSI_PERIODIC_CMD_MODE (1<<5)
 
 struct intel_wm_level {
 	bool enable;
@@ -1015,6 +1034,7 @@ struct intel_crtc_state {
 		union hdmi_infoframe spd;
 		union hdmi_infoframe hdmi;
 		union hdmi_infoframe drm;
+		struct drm_dp_vsc_sdp vsc;
 	} infoframes;
 
 	/* HDMI scrambling status */
@@ -1238,6 +1258,7 @@ struct intel_dp_compliance_data {
 	u8 video_pattern;
 	u16 hdisplay, vdisplay;
 	u8 bpc;
+	struct drm_dp_phy_test_params phytest;
 };
 
 struct intel_dp_compliance {
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 804b1d966f66..d4fcc9583869 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -164,6 +164,17 @@ static void intel_dp_set_sink_rates(struct intel_dp *intel_dp)
 	};
 	int i, max_rate;
 
+	if (drm_dp_has_quirk(&intel_dp->desc, 0,
+			     DP_DPCD_QUIRK_CAN_DO_MAX_LINK_RATE_3_24_GBPS)) {
+		/* Needed, e.g., for Apple MBP 2017, 15 inch eDP Retina panel */
+		static const int quirk_rates[] = { 162000, 270000, 324000 };
+
+		memcpy(intel_dp->sink_rates, quirk_rates, sizeof(quirk_rates));
+		intel_dp->num_sink_rates = ARRAY_SIZE(quirk_rates);
+
+		return;
+	}
+
 	max_rate = drm_dp_bw_code_to_link_rate(intel_dp->dpcd[DP_MAX_LINK_RATE]);
 
 	for (i = 0; i < ARRAY_SIZE(dp_rates); i++) {
@@ -452,6 +463,7 @@ static bool intel_dp_can_link_train_fallback_for_edp(struct intel_dp *intel_dp,
 int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
 					    int link_rate, u8 lane_count)
 {
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	int index;
 
 	index = intel_dp_rate_index(intel_dp->common_rates,
@@ -462,7 +474,8 @@ int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
 		    !intel_dp_can_link_train_fallback_for_edp(intel_dp,
 							      intel_dp->common_rates[index - 1],
 							      lane_count)) {
-			DRM_DEBUG_KMS("Retrying Link training for eDP with same parameters\n");
+			drm_dbg_kms(&i915->drm,
+				    "Retrying Link training for eDP with same parameters\n");
 			return 0;
 		}
 		intel_dp->max_link_rate = intel_dp->common_rates[index - 1];
@@ -472,13 +485,14 @@ int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
 		    !intel_dp_can_link_train_fallback_for_edp(intel_dp,
 							      intel_dp_max_common_rate(intel_dp),
 							      lane_count >> 1)) {
-			DRM_DEBUG_KMS("Retrying Link training for eDP with same parameters\n");
+			drm_dbg_kms(&i915->drm,
+				    "Retrying Link training for eDP with same parameters\n");
 			return 0;
 		}
 		intel_dp->max_link_rate = intel_dp_max_common_rate(intel_dp);
 		intel_dp->max_link_lane_count = lane_count >> 1;
 	} else {
-		DRM_ERROR("Link Training Unsuccessful\n");
+		drm_err(&i915->drm, "Link Training Unsuccessful\n");
 		return -1;
 	}
 
@@ -553,6 +567,7 @@ static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,
 static u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
 				       int mode_clock, int mode_hdisplay)
 {
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	u8 min_slice_count, i;
 	int max_slice_width;
 
@@ -565,8 +580,9 @@ static u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
 
 	max_slice_width = drm_dp_dsc_sink_max_slice_width(intel_dp->dsc_dpcd);
 	if (max_slice_width < DP_DSC_MIN_SLICE_WIDTH_VALUE) {
-		DRM_DEBUG_KMS("Unsupported slice width %d by DP DSC Sink device\n",
-			      max_slice_width);
+		drm_dbg_kms(&i915->drm,
+			    "Unsupported slice width %d by DP DSC Sink device\n",
+			    max_slice_width);
 		return 0;
 	}
 	/* Also take into account max slice width */
@@ -584,7 +600,8 @@ static u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
 			return valid_dsc_slicecount[i];
 	}
 
-	DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count);
+	drm_dbg_kms(&i915->drm, "Unsupported Slice Count %d\n",
+		    min_slice_count);
 	return 0;
 }
 
@@ -1832,6 +1849,7 @@ static void snprintf_int_array(char *str, size_t len,
 
 static void intel_dp_print_rates(struct intel_dp *intel_dp)
 {
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	char str[128]; /* FIXME: too big for stack? */
 
 	if (!drm_debug_enabled(DRM_UT_KMS))
@@ -1839,15 +1857,15 @@ static void intel_dp_print_rates(struct intel_dp *intel_dp)
 
 	snprintf_int_array(str, sizeof(str),
 			   intel_dp->source_rates, intel_dp->num_source_rates);
-	DRM_DEBUG_KMS("source rates: %s\n", str);
+	drm_dbg_kms(&i915->drm, "source rates: %s\n", str);
 
 	snprintf_int_array(str, sizeof(str),
 			   intel_dp->sink_rates, intel_dp->num_sink_rates);
-	DRM_DEBUG_KMS("sink rates: %s\n", str);
+	drm_dbg_kms(&i915->drm, "sink rates: %s\n", str);
 
 	snprintf_int_array(str, sizeof(str),
 			   intel_dp->common_rates, intel_dp->num_common_rates);
-	DRM_DEBUG_KMS("common rates: %s\n", str);
+	drm_dbg_kms(&i915->drm, "common rates: %s\n", str);
 }
 
 int
@@ -1954,6 +1972,8 @@ intel_dp_adjust_compliance_config(struct intel_dp *intel_dp,
 				  struct intel_crtc_state *pipe_config,
 				  struct link_config_limits *limits)
 {
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+
 	/* For DP Compliance we override the computed bpp for the pipe */
 	if (intel_dp->compliance.test_data.bpc != 0) {
 		int bpp = 3 * intel_dp->compliance.test_data.bpc;
@@ -1961,7 +1981,7 @@ intel_dp_adjust_compliance_config(struct intel_dp *intel_dp,
 		limits->min_bpp = limits->max_bpp = bpp;
 		pipe_config->dither_force_disable = bpp == 6 * 3;
 
-		DRM_DEBUG_KMS("Setting pipe_bpp to %d\n", bpp);
+		drm_dbg_kms(&i915->drm, "Setting pipe_bpp to %d\n", bpp);
 	}
 
 	/* Use values requested by Compliance Test Request */
@@ -2055,6 +2075,7 @@ static int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc)
 static int intel_dp_dsc_compute_params(struct intel_encoder *encoder,
 				       struct intel_crtc_state *crtc_state)
 {
+	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
 	struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
 	u8 line_buf_depth;
@@ -2089,7 +2110,8 @@ static int intel_dp_dsc_compute_params(struct intel_encoder *encoder,
 
 	line_buf_depth = drm_dp_dsc_sink_line_buf_depth(intel_dp->dsc_dpcd);
 	if (!line_buf_depth) {
-		DRM_DEBUG_KMS("DSC Sink Line Buffer Depth invalid\n");
+		drm_dbg_kms(&i915->drm,
+			    "DSC Sink Line Buffer Depth invalid\n");
 		return -EINVAL;
 	}
 
@@ -2114,7 +2136,8 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
 {
 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
 	struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
-	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
+	const struct drm_display_mode *adjusted_mode =
+		&pipe_config->hw.adjusted_mode;
 	u8 dsc_max_bpc;
 	int pipe_bpp;
 	int ret;
@@ -2229,7 +2252,9 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
 			     struct intel_crtc_state *pipe_config,
 			     struct drm_connector_state *conn_state)
 {
-	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
+	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+	const struct drm_display_mode *adjusted_mode =
+		&pipe_config->hw.adjusted_mode;
 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
 	struct link_config_limits limits;
 	int common_len;
@@ -2264,11 +2289,11 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
 
 	intel_dp_adjust_compliance_config(intel_dp, pipe_config, &limits);
 
-	DRM_DEBUG_KMS("DP link computation with max lane count %i "
-		      "max rate %d max bpp %d pixel clock %iKHz\n",
-		      limits.max_lane_count,
-		      intel_dp->common_rates[limits.max_clock],
-		      limits.max_bpp, adjusted_mode->crtc_clock);
+	drm_dbg_kms(&i915->drm, "DP link computation with max lane count %i "
+		    "max rate %d max bpp %d pixel clock %iKHz\n",
+		    limits.max_lane_count,
+		    intel_dp->common_rates[limits.max_clock],
+		    limits.max_bpp, adjusted_mode->crtc_clock);
 
 	/*
 	 * Optimize for slow and wide. This is the place to add alternative
@@ -2277,7 +2302,7 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
 	ret = intel_dp_compute_link_config_wide(intel_dp, pipe_config, &limits);
 
 	/* enable compression if the mode doesn't fit available BW */
-	DRM_DEBUG_KMS("Force DSC en = %d\n", intel_dp->force_dsc_en);
+	drm_dbg_kms(&i915->drm, "Force DSC en = %d\n", intel_dp->force_dsc_en);
 	if (ret || intel_dp->force_dsc_en) {
 		ret = intel_dp_dsc_compute_config(intel_dp, pipe_config,
 						  conn_state, &limits);
@@ -2286,26 +2311,29 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
 	}
 
 	if (pipe_config->dsc.compression_enable) {
-		DRM_DEBUG_KMS("DP lane count %d clock %d Input bpp %d Compressed bpp %d\n",
-			      pipe_config->lane_count, pipe_config->port_clock,
-			      pipe_config->pipe_bpp,
-			      pipe_config->dsc.compressed_bpp);
-
-		DRM_DEBUG_KMS("DP link rate required %i available %i\n",
-			      intel_dp_link_required(adjusted_mode->crtc_clock,
-						     pipe_config->dsc.compressed_bpp),
-			      intel_dp_max_data_rate(pipe_config->port_clock,
-						     pipe_config->lane_count));
+		drm_dbg_kms(&i915->drm,
+			    "DP lane count %d clock %d Input bpp %d Compressed bpp %d\n",
+			    pipe_config->lane_count, pipe_config->port_clock,
+			    pipe_config->pipe_bpp,
+			    pipe_config->dsc.compressed_bpp);
+
+		drm_dbg_kms(&i915->drm,
+			    "DP link rate required %i available %i\n",
+			    intel_dp_link_required(adjusted_mode->crtc_clock,
+						   pipe_config->dsc.compressed_bpp),
+			    intel_dp_max_data_rate(pipe_config->port_clock,
+						   pipe_config->lane_count));
 	} else {
-		DRM_DEBUG_KMS("DP lane count %d clock %d bpp %d\n",
-			      pipe_config->lane_count, pipe_config->port_clock,
-			      pipe_config->pipe_bpp);
+		drm_dbg_kms(&i915->drm, "DP lane count %d clock %d bpp %d\n",
+			    pipe_config->lane_count, pipe_config->port_clock,
+			    pipe_config->pipe_bpp);
 
-		DRM_DEBUG_KMS("DP link rate required %i available %i\n",
-			      intel_dp_link_required(adjusted_mode->crtc_clock,
-						     pipe_config->pipe_bpp),
-			      intel_dp_max_data_rate(pipe_config->port_clock,
-						     pipe_config->lane_count));
+		drm_dbg_kms(&i915->drm,
+			    "DP link rate required %i available %i\n",
+			    intel_dp_link_required(adjusted_mode->crtc_clock,
+						   pipe_config->pipe_bpp),
+			    intel_dp_max_data_rate(pipe_config->port_clock,
+						   pipe_config->lane_count));
 	}
 	return 0;
 }
@@ -2315,6 +2343,7 @@ intel_dp_ycbcr420_config(struct intel_dp *intel_dp,
 			 struct drm_connector *connector,
 			 struct intel_crtc_state *crtc_state)
 {
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	const struct drm_display_info *info = &connector->display_info;
 	const struct drm_display_mode *adjusted_mode =
 		&crtc_state->hw.adjusted_mode;
@@ -2331,7 +2360,8 @@ intel_dp_ycbcr420_config(struct intel_dp *intel_dp,
 	/* YCBCR 420 output conversion needs a scaler */
 	ret = skl_update_scaler_crtc(crtc_state);
 	if (ret) {
-		DRM_DEBUG_KMS("Scaler allocation for output failed\n");
+		drm_dbg_kms(&i915->drm,
+			    "Scaler allocation for output failed\n");
 		return ret;
 	}
 
@@ -2384,6 +2414,128 @@ static bool intel_dp_port_has_audio(struct drm_i915_private *dev_priv,
 	return true;
 }
 
+static void intel_dp_compute_vsc_colorimetry(const struct intel_crtc_state *crtc_state,
+					     const struct drm_connector_state *conn_state,
+					     struct drm_dp_vsc_sdp *vsc)
+{
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+
+	/*
+	 * Prepare VSC Header for SU as per DP 1.4 spec, Table 2-118
+	 * VSC SDP supporting 3D stereo, PSR2, and Pixel Encoding/
+	 * Colorimetry Format indication.
+	 */
+	vsc->revision = 0x5;
+	vsc->length = 0x13;
+
+	/* DP 1.4a spec, Table 2-120 */
+	switch (crtc_state->output_format) {
+	case INTEL_OUTPUT_FORMAT_YCBCR444:
+		vsc->pixelformat = DP_PIXELFORMAT_YUV444;
+		break;
+	case INTEL_OUTPUT_FORMAT_YCBCR420:
+		vsc->pixelformat = DP_PIXELFORMAT_YUV420;
+		break;
+	case INTEL_OUTPUT_FORMAT_RGB:
+	default:
+		vsc->pixelformat = DP_PIXELFORMAT_RGB;
+	}
+
+	switch (conn_state->colorspace) {
+	case DRM_MODE_COLORIMETRY_BT709_YCC:
+		vsc->colorimetry = DP_COLORIMETRY_BT709_YCC;
+		break;
+	case DRM_MODE_COLORIMETRY_XVYCC_601:
+		vsc->colorimetry = DP_COLORIMETRY_XVYCC_601;
+		break;
+	case DRM_MODE_COLORIMETRY_XVYCC_709:
+		vsc->colorimetry = DP_COLORIMETRY_XVYCC_709;
+		break;
+	case DRM_MODE_COLORIMETRY_SYCC_601:
+		vsc->colorimetry = DP_COLORIMETRY_SYCC_601;
+		break;
+	case DRM_MODE_COLORIMETRY_OPYCC_601:
+		vsc->colorimetry = DP_COLORIMETRY_OPYCC_601;
+		break;
+	case DRM_MODE_COLORIMETRY_BT2020_CYCC:
+		vsc->colorimetry = DP_COLORIMETRY_BT2020_CYCC;
+		break;
+	case DRM_MODE_COLORIMETRY_BT2020_RGB:
+		vsc->colorimetry = DP_COLORIMETRY_BT2020_RGB;
+		break;
+	case DRM_MODE_COLORIMETRY_BT2020_YCC:
+		vsc->colorimetry = DP_COLORIMETRY_BT2020_YCC;
+		break;
+	case DRM_MODE_COLORIMETRY_DCI_P3_RGB_D65:
+	case DRM_MODE_COLORIMETRY_DCI_P3_RGB_THEATER:
+		vsc->colorimetry = DP_COLORIMETRY_DCI_P3_RGB;
+		break;
+	default:
+		/*
+		 * RGB->YCBCR color conversion uses the BT.709
+		 * color space.
+		 */
+		if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
+			vsc->colorimetry = DP_COLORIMETRY_BT709_YCC;
+		else
+			vsc->colorimetry = DP_COLORIMETRY_DEFAULT;
+		break;
+	}
+
+	vsc->bpc = crtc_state->pipe_bpp / 3;
+
+	/* only RGB pixelformat supports 6 bpc */
+	drm_WARN_ON(&dev_priv->drm,
+		    vsc->bpc == 6 && vsc->pixelformat != DP_PIXELFORMAT_RGB);
+
+	/* all YCbCr are always limited range */
+	vsc->dynamic_range = DP_DYNAMIC_RANGE_CTA;
+	vsc->content_type = DP_CONTENT_TYPE_NOT_DEFINED;
+}
+
+static void intel_dp_compute_vsc_sdp(struct intel_dp *intel_dp,
+				     struct intel_crtc_state *crtc_state,
+				     const struct drm_connector_state *conn_state)
+{
+	struct drm_dp_vsc_sdp *vsc = &crtc_state->infoframes.vsc;
+
+	/* When PSR is enabled, VSC SDP is handled by PSR routine */
+	if (intel_psr_enabled(intel_dp))
+		return;
+
+	if (!intel_dp_needs_vsc_sdp(crtc_state, conn_state))
+		return;
+
+	crtc_state->infoframes.enable |= intel_hdmi_infoframe_enable(DP_SDP_VSC);
+	vsc->sdp_type = DP_SDP_VSC;
+	intel_dp_compute_vsc_colorimetry(crtc_state, conn_state,
+					 &crtc_state->infoframes.vsc);
+}
+
+static void
+intel_dp_compute_hdr_metadata_infoframe_sdp(struct intel_dp *intel_dp,
+					    struct intel_crtc_state *crtc_state,
+					    const struct drm_connector_state *conn_state)
+{
+	int ret;
+	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+	struct hdmi_drm_infoframe *drm_infoframe = &crtc_state->infoframes.drm.drm;
+
+	if (!conn_state->hdr_output_metadata)
+		return;
+
+	ret = drm_hdmi_infoframe_set_hdr_metadata(drm_infoframe, conn_state);
+
+	if (ret) {
+		drm_dbg_kms(&dev_priv->drm, "couldn't set HDR metadata in infoframe\n");
+		return;
+	}
+
+	crtc_state->infoframes.enable |=
+		intel_hdmi_infoframe_enable(HDMI_PACKET_TYPE_GAMUT_METADATA);
+}
+
 int
 intel_dp_compute_config(struct intel_encoder *encoder,
 			struct intel_crtc_state *pipe_config,
@@ -2489,6 +2641,8 @@ intel_dp_compute_config(struct intel_encoder *encoder,
 		intel_dp_set_clock(encoder, pipe_config);
 
 	intel_psr_compute_config(intel_dp, pipe_config);
+	intel_dp_compute_vsc_sdp(intel_dp, pipe_config, conn_state);
+	intel_dp_compute_hdr_metadata_infoframe_sdp(intel_dp, pipe_config, conn_state);
 
 	return 0;
 }
@@ -2633,22 +2787,27 @@ static void wait_panel_status(struct intel_dp *intel_dp,
 
 static void wait_panel_on(struct intel_dp *intel_dp)
 {
-	DRM_DEBUG_KMS("Wait for panel power on\n");
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+
+	drm_dbg_kms(&i915->drm, "Wait for panel power on\n");
 	wait_panel_status(intel_dp, IDLE_ON_MASK, IDLE_ON_VALUE);
 }
 
 static void wait_panel_off(struct intel_dp *intel_dp)
 {
-	DRM_DEBUG_KMS("Wait for panel power off time\n");
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+
+	drm_dbg_kms(&i915->drm, "Wait for panel power off time\n");
 	wait_panel_status(intel_dp, IDLE_OFF_MASK, IDLE_OFF_VALUE);
 }
 
 static void wait_panel_power_cycle(struct intel_dp *intel_dp)
 {
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	ktime_t panel_power_on_time;
 	s64 panel_power_off_duration;
 
-	DRM_DEBUG_KMS("Wait for panel power cycle\n");
+	drm_dbg_kms(&i915->drm, "Wait for panel power cycle\n");
 
 	/* take the difference of currrent time and panel power off time
 	 * and then make panel wait for t11_t12 if needed. */
@@ -3012,11 +3171,12 @@ void intel_edp_backlight_on(const struct intel_crtc_state *crtc_state,
 			    const struct drm_connector_state *conn_state)
 {
 	struct intel_dp *intel_dp = enc_to_intel_dp(to_intel_encoder(conn_state->best_encoder));
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 
 	if (!intel_dp_is_edp(intel_dp))
 		return;
 
-	DRM_DEBUG_KMS("\n");
+	drm_dbg_kms(&i915->drm, "\n");
 
 	intel_panel_enable_backlight(crtc_state, conn_state);
 	_intel_edp_backlight_on(intel_dp);
@@ -3050,11 +3210,12 @@ static void _intel_edp_backlight_off(struct intel_dp *intel_dp)
 void intel_edp_backlight_off(const struct drm_connector_state *old_conn_state)
 {
 	struct intel_dp *intel_dp = enc_to_intel_dp(to_intel_encoder(old_conn_state->best_encoder));
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 
 	if (!intel_dp_is_edp(intel_dp))
 		return;
 
-	DRM_DEBUG_KMS("\n");
+	drm_dbg_kms(&i915->drm, "\n");
 
 	_intel_edp_backlight_off(intel_dp);
 	intel_panel_disable_backlight(old_conn_state);
@@ -3067,6 +3228,7 @@ void intel_edp_backlight_off(const struct drm_connector_state *old_conn_state)
 static void intel_edp_backlight_power(struct intel_connector *connector,
 				      bool enable)
 {
+	struct drm_i915_private *i915 = to_i915(connector->base.dev);
 	struct intel_dp *intel_dp = intel_attached_dp(connector);
 	intel_wakeref_t wakeref;
 	bool is_enabled;
@@ -3077,8 +3239,8 @@ static void intel_edp_backlight_power(struct intel_connector *connector,
 	if (is_enabled == enable)
 		return;
 
-	DRM_DEBUG_KMS("panel power control backlight %s\n",
-		      enable ? "enable" : "disable");
+	drm_dbg_kms(&i915->drm, "panel power control backlight %s\n",
+		    enable ? "enable" : "disable");
 
 	if (enable)
 		_intel_edp_backlight_on(intel_dp);
@@ -3188,6 +3350,7 @@ void intel_dp_sink_set_decompression_state(struct intel_dp *intel_dp,
 					   const struct intel_crtc_state *crtc_state,
 					   bool enable)
 {
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	int ret;
 
 	if (!crtc_state->dsc.compression_enable)
@@ -3196,13 +3359,15 @@ void intel_dp_sink_set_decompression_state(struct intel_dp *intel_dp,
 	ret = drm_dp_dpcd_writeb(&intel_dp->aux, DP_DSC_ENABLE,
 				 enable ? DP_DECOMPRESSION_EN : 0);
 	if (ret < 0)
-		DRM_DEBUG_KMS("Failed to %s sink decompression state\n",
-			      enable ? "enable" : "disable");
+		drm_dbg_kms(&i915->drm,
+			    "Failed to %s sink decompression state\n",
+			    enable ? "enable" : "disable");
 }
 
 /* If the sink supports it, try to set the power state appropriately */
 void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode)
 {
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	int ret, i;
 
 	/* Should have a valid DPCD by this point */
@@ -3235,8 +3400,8 @@ void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode)
 	}
 
 	if (ret != 1)
-		DRM_DEBUG_KMS("failed to %s sink power state\n",
-			      mode == DRM_MODE_DPMS_ON ? "enable" : "disable");
+		drm_dbg_kms(&i915->drm, "failed to %s sink power state\n",
+			    mode == DRM_MODE_DPMS_ON ? "enable" : "disable");
 }
 
 static bool cpt_dp_port_selected(struct drm_i915_private *dev_priv,
@@ -3393,7 +3558,8 @@ static void intel_dp_get_config(struct intel_encoder *encoder,
 	}
 }
 
-static void intel_disable_dp(struct intel_encoder *encoder,
+static void intel_disable_dp(struct intel_atomic_state *state,
+			     struct intel_encoder *encoder,
 			     const struct intel_crtc_state *old_crtc_state,
 			     const struct drm_connector_state *old_conn_state)
 {
@@ -3413,21 +3579,24 @@ static void intel_disable_dp(struct intel_encoder *encoder,
 	intel_edp_panel_off(intel_dp);
 }
 
-static void g4x_disable_dp(struct intel_encoder *encoder,
+static void g4x_disable_dp(struct intel_atomic_state *state,
+			   struct intel_encoder *encoder,
 			   const struct intel_crtc_state *old_crtc_state,
 			   const struct drm_connector_state *old_conn_state)
 {
-	intel_disable_dp(encoder, old_crtc_state, old_conn_state);
+	intel_disable_dp(state, encoder, old_crtc_state, old_conn_state);
 }
 
-static void vlv_disable_dp(struct intel_encoder *encoder,
+static void vlv_disable_dp(struct intel_atomic_state *state,
+			   struct intel_encoder *encoder,
 			   const struct intel_crtc_state *old_crtc_state,
 			   const struct drm_connector_state *old_conn_state)
 {
-	intel_disable_dp(encoder, old_crtc_state, old_conn_state);
+	intel_disable_dp(state, encoder, old_crtc_state, old_conn_state);
 }
 
-static void g4x_post_disable_dp(struct intel_encoder *encoder,
+static void g4x_post_disable_dp(struct intel_atomic_state *state,
+				struct intel_encoder *encoder,
 				const struct intel_crtc_state *old_crtc_state,
 				const struct drm_connector_state *old_conn_state)
 {
@@ -3447,14 +3616,16 @@ static void g4x_post_disable_dp(struct intel_encoder *encoder,
 		ilk_edp_pll_off(intel_dp, old_crtc_state);
 }
 
-static void vlv_post_disable_dp(struct intel_encoder *encoder,
+static void vlv_post_disable_dp(struct intel_atomic_state *state,
+				struct intel_encoder *encoder,
 				const struct intel_crtc_state *old_crtc_state,
 				const struct drm_connector_state *old_conn_state)
 {
 	intel_dp_link_down(encoder, old_crtc_state);
 }
 
-static void chv_post_disable_dp(struct intel_encoder *encoder,
+static void chv_post_disable_dp(struct intel_atomic_state *state,
+				struct intel_encoder *encoder,
 				const struct intel_crtc_state *old_crtc_state,
 				const struct drm_connector_state *old_conn_state)
 {
@@ -3580,7 +3751,8 @@ static void intel_dp_enable_port(struct intel_dp *intel_dp,
 	intel_de_posting_read(dev_priv, intel_dp->output_reg);
 }
 
-static void intel_enable_dp(struct intel_encoder *encoder,
+static void intel_enable_dp(struct intel_atomic_state *state,
+			    struct intel_encoder *encoder,
 			    const struct intel_crtc_state *pipe_config,
 			    const struct drm_connector_state *conn_state)
 {
@@ -3626,22 +3798,25 @@ static void intel_enable_dp(struct intel_encoder *encoder,
 	}
 }
 
-static void g4x_enable_dp(struct intel_encoder *encoder,
+static void g4x_enable_dp(struct intel_atomic_state *state,
+			  struct intel_encoder *encoder,
 			  const struct intel_crtc_state *pipe_config,
 			  const struct drm_connector_state *conn_state)
 {
-	intel_enable_dp(encoder, pipe_config, conn_state);
+	intel_enable_dp(state, encoder, pipe_config, conn_state);
 	intel_edp_backlight_on(pipe_config, conn_state);
 }
 
-static void vlv_enable_dp(struct intel_encoder *encoder,
+static void vlv_enable_dp(struct intel_atomic_state *state,
+			  struct intel_encoder *encoder,
 			  const struct intel_crtc_state *pipe_config,
 			  const struct drm_connector_state *conn_state)
 {
 	intel_edp_backlight_on(pipe_config, conn_state);
 }
 
-static void g4x_pre_enable_dp(struct intel_encoder *encoder,
+static void g4x_pre_enable_dp(struct intel_atomic_state *state,
+			      struct intel_encoder *encoder,
 			      const struct intel_crtc_state *pipe_config,
 			      const struct drm_connector_state *conn_state)
 {
@@ -3761,16 +3936,18 @@ static void vlv_init_panel_power_sequencer(struct intel_encoder *encoder,
 	intel_dp_init_panel_power_sequencer_registers(intel_dp, true);
 }
 
-static void vlv_pre_enable_dp(struct intel_encoder *encoder,
+static void vlv_pre_enable_dp(struct intel_atomic_state *state,
+			      struct intel_encoder *encoder,
 			      const struct intel_crtc_state *pipe_config,
 			      const struct drm_connector_state *conn_state)
 {
 	vlv_phy_pre_encoder_enable(encoder, pipe_config);
 
-	intel_enable_dp(encoder, pipe_config, conn_state);
+	intel_enable_dp(state, encoder, pipe_config, conn_state);
 }
 
-static void vlv_dp_pre_pll_enable(struct intel_encoder *encoder,
+static void vlv_dp_pre_pll_enable(struct intel_atomic_state *state,
+				  struct intel_encoder *encoder,
 				  const struct intel_crtc_state *pipe_config,
 				  const struct drm_connector_state *conn_state)
 {
@@ -3779,19 +3956,21 @@ static void vlv_dp_pre_pll_enable(struct intel_encoder *encoder,
 	vlv_phy_pre_pll_enable(encoder, pipe_config);
 }
 
-static void chv_pre_enable_dp(struct intel_encoder *encoder,
+static void chv_pre_enable_dp(struct intel_atomic_state *state,
+			      struct intel_encoder *encoder,
 			      const struct intel_crtc_state *pipe_config,
 			      const struct drm_connector_state *conn_state)
 {
 	chv_phy_pre_encoder_enable(encoder, pipe_config);
 
-	intel_enable_dp(encoder, pipe_config, conn_state);
+	intel_enable_dp(state, encoder, pipe_config, conn_state);
 
 	/* Second common lane will stay alive on its own now */
 	chv_phy_release_cl2_override(encoder);
 }
 
-static void chv_dp_pre_pll_enable(struct intel_encoder *encoder,
+static void chv_dp_pre_pll_enable(struct intel_atomic_state *state,
+				  struct intel_encoder *encoder,
 				  const struct intel_crtc_state *pipe_config,
 				  const struct drm_connector_state *conn_state)
 {
@@ -3800,7 +3979,8 @@ static void chv_dp_pre_pll_enable(struct intel_encoder *encoder,
 	chv_phy_pre_pll_enable(encoder, pipe_config);
 }
 
-static void chv_dp_post_pll_disable(struct intel_encoder *encoder,
+static void chv_dp_post_pll_disable(struct intel_atomic_state *state,
+				    struct intel_encoder *encoder,
 				    const struct intel_crtc_state *old_crtc_state,
 				    const struct drm_connector_state *old_conn_state)
 {
@@ -4319,6 +4499,7 @@ intel_dp_link_down(struct intel_encoder *encoder,
 static void
 intel_dp_extended_receiver_capabilities(struct intel_dp *intel_dp)
 {
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	u8 dpcd_ext[6];
 
 	/*
@@ -4334,20 +4515,22 @@ intel_dp_extended_receiver_capabilities(struct intel_dp *intel_dp)
 
 	if (drm_dp_dpcd_read(&intel_dp->aux, DP_DP13_DPCD_REV,
 			     &dpcd_ext, sizeof(dpcd_ext)) != sizeof(dpcd_ext)) {
-		DRM_ERROR("DPCD failed read at extended capabilities\n");
+		drm_err(&i915->drm,
+			"DPCD failed read at extended capabilities\n");
 		return;
 	}
 
 	if (intel_dp->dpcd[DP_DPCD_REV] > dpcd_ext[DP_DPCD_REV]) {
-		DRM_DEBUG_KMS("DPCD extended DPCD rev less than base DPCD rev\n");
+		drm_dbg_kms(&i915->drm,
+			    "DPCD extended DPCD rev less than base DPCD rev\n");
 		return;
 	}
 
 	if (!memcmp(intel_dp->dpcd, dpcd_ext, sizeof(dpcd_ext)))
 		return;
 
-	DRM_DEBUG_KMS("Base DPCD: %*ph\n",
-		      (int)sizeof(intel_dp->dpcd), intel_dp->dpcd);
+	drm_dbg_kms(&i915->drm, "Base DPCD: %*ph\n",
+		    (int)sizeof(intel_dp->dpcd), intel_dp->dpcd);
 
 	memcpy(intel_dp->dpcd, dpcd_ext, sizeof(dpcd_ext));
 }
@@ -4355,13 +4538,16 @@ intel_dp_extended_receiver_capabilities(struct intel_dp *intel_dp)
 bool
 intel_dp_read_dpcd(struct intel_dp *intel_dp)
 {
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+
 	if (drm_dp_dpcd_read(&intel_dp->aux, 0x000, intel_dp->dpcd,
 			     sizeof(intel_dp->dpcd)) < 0)
 		return false; /* aux transfer failed */
 
 	intel_dp_extended_receiver_capabilities(intel_dp);
 
-	DRM_DEBUG_KMS("DPCD: %*ph\n", (int) sizeof(intel_dp->dpcd), intel_dp->dpcd);
+	drm_dbg_kms(&i915->drm, "DPCD: %*ph\n", (int)sizeof(intel_dp->dpcd),
+		    intel_dp->dpcd);
 
 	return intel_dp->dpcd[DP_DPCD_REV] != 0;
 }
@@ -4378,6 +4564,8 @@ bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp)
 
 static void intel_dp_get_dsc_sink_cap(struct intel_dp *intel_dp)
 {
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+
 	/*
 	 * Clear the cached register set to avoid using stale values
 	 * for the sinks that do not support DSC.
@@ -4393,20 +4581,23 @@ static void intel_dp_get_dsc_sink_cap(struct intel_dp *intel_dp)
 		if (drm_dp_dpcd_read(&intel_dp->aux, DP_DSC_SUPPORT,
 				     intel_dp->dsc_dpcd,
 				     sizeof(intel_dp->dsc_dpcd)) < 0)
-			DRM_ERROR("Failed to read DPCD register 0x%x\n",
-				  DP_DSC_SUPPORT);
+			drm_err(&i915->drm,
+				"Failed to read DPCD register 0x%x\n",
+				DP_DSC_SUPPORT);
 
-		DRM_DEBUG_KMS("DSC DPCD: %*ph\n",
-			      (int)sizeof(intel_dp->dsc_dpcd),
-			      intel_dp->dsc_dpcd);
+		drm_dbg_kms(&i915->drm, "DSC DPCD: %*ph\n",
+			    (int)sizeof(intel_dp->dsc_dpcd),
+			    intel_dp->dsc_dpcd);
 
 		/* FEC is supported only on DP 1.4 */
 		if (!intel_dp_is_edp(intel_dp) &&
 		    drm_dp_dpcd_readb(&intel_dp->aux, DP_FEC_CAPABILITY,
 				      &intel_dp->fec_capable) < 0)
-			DRM_ERROR("Failed to read FEC DPCD register\n");
+			drm_err(&i915->drm,
+				"Failed to read FEC DPCD register\n");
 
-		DRM_DEBUG_KMS("FEC CAPABILITY: %x\n", intel_dp->fec_capable);
+		drm_dbg_kms(&i915->drm, "FEC CAPABILITY: %x\n",
+			    intel_dp->fec_capable);
 	}
 }
 
@@ -4580,14 +4771,16 @@ intel_dp_can_mst(struct intel_dp *intel_dp)
 static void
 intel_dp_configure_mst(struct intel_dp *intel_dp)
 {
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	struct intel_encoder *encoder =
 		&dp_to_dig_port(intel_dp)->base;
 	bool sink_can_mst = intel_dp_sink_can_mst(intel_dp);
 
-	DRM_DEBUG_KMS("[ENCODER:%d:%s] MST support: port: %s, sink: %s, modparam: %s\n",
-		      encoder->base.base.id, encoder->base.name,
-		      yesno(intel_dp->can_mst), yesno(sink_can_mst),
-		      yesno(i915_modparams.enable_dp_mst));
+	drm_dbg_kms(&i915->drm,
+		    "[ENCODER:%d:%s] MST support: port: %s, sink: %s, modparam: %s\n",
+		    encoder->base.base.id, encoder->base.name,
+		    yesno(intel_dp->can_mst), yesno(sink_can_mst),
+		    yesno(i915_modparams.enable_dp_mst));
 
 	if (!intel_dp->can_mst)
 		return;
@@ -4633,6 +4826,205 @@ intel_dp_needs_vsc_sdp(const struct intel_crtc_state *crtc_state,
 	return false;
 }
 
+static ssize_t intel_dp_vsc_sdp_pack(const struct drm_dp_vsc_sdp *vsc,
+				     struct dp_sdp *sdp, size_t size)
+{
+	size_t length = sizeof(struct dp_sdp);
+
+	if (size < length)
+		return -ENOSPC;
+
+	memset(sdp, 0, size);
+
+	/*
+	 * Prepare VSC Header for SU as per DP 1.4a spec, Table 2-119
+	 * VSC SDP Header Bytes
+	 */
+	sdp->sdp_header.HB0 = 0; /* Secondary-Data Packet ID = 0 */
+	sdp->sdp_header.HB1 = vsc->sdp_type; /* Secondary-data Packet Type */
+	sdp->sdp_header.HB2 = vsc->revision; /* Revision Number */
+	sdp->sdp_header.HB3 = vsc->length; /* Number of Valid Data Bytes */
+
+	/* VSC SDP Payload for DB16 through DB18 */
+	/* Pixel Encoding and Colorimetry Formats  */
+	sdp->db[16] = (vsc->pixelformat & 0xf) << 4; /* DB16[7:4] */
+	sdp->db[16] |= vsc->colorimetry & 0xf; /* DB16[3:0] */
+
+	switch (vsc->bpc) {
+	case 6:
+		/* 6bpc: 0x0 */
+		break;
+	case 8:
+		sdp->db[17] = 0x1; /* DB17[3:0] */
+		break;
+	case 10:
+		sdp->db[17] = 0x2;
+		break;
+	case 12:
+		sdp->db[17] = 0x3;
+		break;
+	case 16:
+		sdp->db[17] = 0x4;
+		break;
+	default:
+		MISSING_CASE(vsc->bpc);
+		break;
+	}
+	/* Dynamic Range and Component Bit Depth */
+	if (vsc->dynamic_range == DP_DYNAMIC_RANGE_CTA)
+		sdp->db[17] |= 0x80;  /* DB17[7] */
+
+	/* Content Type */
+	sdp->db[18] = vsc->content_type & 0x7;
+
+	return length;
+}
+
+static ssize_t
+intel_dp_hdr_metadata_infoframe_sdp_pack(const struct hdmi_drm_infoframe *drm_infoframe,
+					 struct dp_sdp *sdp,
+					 size_t size)
+{
+	size_t length = sizeof(struct dp_sdp);
+	const int infoframe_size = HDMI_INFOFRAME_HEADER_SIZE + HDMI_DRM_INFOFRAME_SIZE;
+	unsigned char buf[HDMI_INFOFRAME_HEADER_SIZE + HDMI_DRM_INFOFRAME_SIZE];
+	ssize_t len;
+
+	if (size < length)
+		return -ENOSPC;
+
+	memset(sdp, 0, size);
+
+	len = hdmi_drm_infoframe_pack_only(drm_infoframe, buf, sizeof(buf));
+	if (len < 0) {
+		DRM_DEBUG_KMS("buffer size is smaller than hdr metadata infoframe\n");
+		return -ENOSPC;
+	}
+
+	if (len != infoframe_size) {
+		DRM_DEBUG_KMS("wrong static hdr metadata size\n");
+		return -ENOSPC;
+	}
+
+	/*
+	 * Set up the infoframe sdp packet for HDR static metadata.
+	 * Prepare VSC Header for SU as per DP 1.4a spec,
+	 * Table 2-100 and Table 2-101
+	 */
+
+	/* Secondary-Data Packet ID, 00h for non-Audio INFOFRAME */
+	sdp->sdp_header.HB0 = 0;
+	/*
+	 * Packet Type 80h + Non-audio INFOFRAME Type value
+	 * HDMI_INFOFRAME_TYPE_DRM: 0x87
+	 * - 80h + Non-audio INFOFRAME Type value
+	 * - InfoFrame Type: 0x07
+	 *    [CTA-861-G Table-42 Dynamic Range and Mastering InfoFrame]
+	 */
+	sdp->sdp_header.HB1 = drm_infoframe->type;
+	/*
+	 * Least Significant Eight Bits of (Data Byte Count – 1)
+	 * infoframe_size - 1
+	 */
+	sdp->sdp_header.HB2 = 0x1D;
+	/* INFOFRAME SDP Version Number */
+	sdp->sdp_header.HB3 = (0x13 << 2);
+	/* CTA Header Byte 2 (INFOFRAME Version Number) */
+	sdp->db[0] = drm_infoframe->version;
+	/* CTA Header Byte 3 (Length of INFOFRAME): HDMI_DRM_INFOFRAME_SIZE */
+	sdp->db[1] = drm_infoframe->length;
+	/*
+	 * Copy HDMI_DRM_INFOFRAME_SIZE size from a buffer after
+	 * HDMI_INFOFRAME_HEADER_SIZE
+	 */
+	BUILD_BUG_ON(sizeof(sdp->db) < HDMI_DRM_INFOFRAME_SIZE + 2);
+	memcpy(&sdp->db[2], &buf[HDMI_INFOFRAME_HEADER_SIZE],
+	       HDMI_DRM_INFOFRAME_SIZE);
+
+	/*
+	 * Size of DP infoframe sdp packet for HDR static metadata consists of
+	 * - DP SDP Header(struct dp_sdp_header): 4 bytes
+	 * - Two Data Blocks: 2 bytes
+	 *    CTA Header Byte2 (INFOFRAME Version Number)
+	 *    CTA Header Byte3 (Length of INFOFRAME)
+	 * - HDMI_DRM_INFOFRAME_SIZE: 26 bytes
+	 *
+	 * Prior to GEN11's GMP register size is identical to DP HDR static metadata
+	 * infoframe size. But GEN11+ has larger than that size, write_infoframe
+	 * will pad rest of the size.
+	 */
+	return sizeof(struct dp_sdp_header) + 2 + HDMI_DRM_INFOFRAME_SIZE;
+}
+
+static void intel_write_dp_sdp(struct intel_encoder *encoder,
+			       const struct intel_crtc_state *crtc_state,
+			       unsigned int type)
+{
+	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	struct dp_sdp sdp = {};
+	ssize_t len;
+
+	if ((crtc_state->infoframes.enable &
+	     intel_hdmi_infoframe_enable(type)) == 0)
+		return;
+
+	switch (type) {
+	case DP_SDP_VSC:
+		len = intel_dp_vsc_sdp_pack(&crtc_state->infoframes.vsc, &sdp,
+					    sizeof(sdp));
+		break;
+	case HDMI_PACKET_TYPE_GAMUT_METADATA:
+		len = intel_dp_hdr_metadata_infoframe_sdp_pack(&crtc_state->infoframes.drm.drm,
+							       &sdp, sizeof(sdp));
+		break;
+	default:
+		MISSING_CASE(type);
+		return;
+	}
+
+	if (drm_WARN_ON(&dev_priv->drm, len < 0))
+		return;
+
+	intel_dig_port->write_infoframe(encoder, crtc_state, type, &sdp, len);
+}
+
+void intel_dp_set_infoframes(struct intel_encoder *encoder,
+			     bool enable,
+			     const struct intel_crtc_state *crtc_state,
+			     const struct drm_connector_state *conn_state)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+	i915_reg_t reg = HSW_TVIDEO_DIP_CTL(crtc_state->cpu_transcoder);
+	u32 dip_enable = VIDEO_DIP_ENABLE_AVI_HSW | VIDEO_DIP_ENABLE_GCP_HSW |
+			 VIDEO_DIP_ENABLE_VS_HSW | VIDEO_DIP_ENABLE_GMP_HSW |
+			 VIDEO_DIP_ENABLE_SPD_HSW | VIDEO_DIP_ENABLE_DRM_GLK;
+	u32 val = intel_de_read(dev_priv, reg);
+
+	/* TODO: Add DSC case (DIP_ENABLE_PPS) */
+	/* When PSR is enabled, this routine doesn't disable VSC DIP */
+	if (intel_psr_enabled(intel_dp))
+		val &= ~dip_enable;
+	else
+		val &= ~(dip_enable | VIDEO_DIP_ENABLE_VSC_HSW);
+
+	if (!enable) {
+		intel_de_write(dev_priv, reg, val);
+		intel_de_posting_read(dev_priv, reg);
+		return;
+	}
+
+	intel_de_write(dev_priv, reg, val);
+	intel_de_posting_read(dev_priv, reg);
+
+	/* When PSR is enabled, VSC SDP is handled by PSR routine */
+	if (!intel_psr_enabled(intel_dp))
+		intel_write_dp_sdp(encoder, crtc_state, DP_SDP_VSC);
+
+	intel_write_dp_sdp(encoder, crtc_state, HDMI_PACKET_TYPE_GAMUT_METADATA);
+}
+
 static void
 intel_dp_setup_vsc_sdp(struct intel_dp *intel_dp,
 		       const struct intel_crtc_state *crtc_state,
@@ -4762,6 +5154,7 @@ intel_dp_setup_hdr_metadata_infoframe_sdp(struct intel_dp *intel_dp,
 					  const struct intel_crtc_state *crtc_state,
 					  const struct drm_connector_state *conn_state)
 {
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 	struct dp_sdp infoframe_sdp = {};
 	struct hdmi_drm_infoframe drm_infoframe = {};
@@ -4772,18 +5165,20 @@ intel_dp_setup_hdr_metadata_infoframe_sdp(struct intel_dp *intel_dp,
 
 	ret = drm_hdmi_infoframe_set_hdr_metadata(&drm_infoframe, conn_state);
 	if (ret) {
-		DRM_DEBUG_KMS("couldn't set HDR metadata in infoframe\n");
+		drm_dbg_kms(&i915->drm,
+			    "couldn't set HDR metadata in infoframe\n");
 		return;
 	}
 
 	len = hdmi_drm_infoframe_pack_only(&drm_infoframe, buf, sizeof(buf));
 	if (len < 0) {
-		DRM_DEBUG_KMS("buffer size is smaller than hdr metadata infoframe\n");
+		drm_dbg_kms(&i915->drm,
+			    "buffer size is smaller than hdr metadata infoframe\n");
 		return;
 	}
 
 	if (len != infoframe_size) {
-		DRM_DEBUG_KMS("wrong static hdr metadata size\n");
+		drm_dbg_kms(&i915->drm, "wrong static hdr metadata size\n");
 		return;
 	}
 
@@ -4861,6 +5256,7 @@ void intel_dp_hdr_metadata_enable(struct intel_dp *intel_dp,
 
 static u8 intel_dp_autotest_link_training(struct intel_dp *intel_dp)
 {
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	int status = 0;
 	int test_link_rate;
 	u8 test_lane_count, test_link_bw;
@@ -4872,7 +5268,7 @@ static u8 intel_dp_autotest_link_training(struct intel_dp *intel_dp)
 				   &test_lane_count);
 
 	if (status <= 0) {
-		DRM_DEBUG_KMS("Lane count read failed\n");
+		drm_dbg_kms(&i915->drm, "Lane count read failed\n");
 		return DP_TEST_NAK;
 	}
 	test_lane_count &= DP_MAX_LANE_COUNT_MASK;
@@ -4880,7 +5276,7 @@ static u8 intel_dp_autotest_link_training(struct intel_dp *intel_dp)
 	status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_LINK_RATE,
 				   &test_link_bw);
 	if (status <= 0) {
-		DRM_DEBUG_KMS("Link Rate read failed\n");
+		drm_dbg_kms(&i915->drm, "Link Rate read failed\n");
 		return DP_TEST_NAK;
 	}
 	test_link_rate = drm_dp_bw_code_to_link_rate(test_link_bw);
@@ -4898,6 +5294,7 @@ static u8 intel_dp_autotest_link_training(struct intel_dp *intel_dp)
 
 static u8 intel_dp_autotest_video_pattern(struct intel_dp *intel_dp)
 {
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	u8 test_pattern;
 	u8 test_misc;
 	__be16 h_width, v_height;
@@ -4907,7 +5304,7 @@ static u8 intel_dp_autotest_video_pattern(struct intel_dp *intel_dp)
 	status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_PATTERN,
 				   &test_pattern);
 	if (status <= 0) {
-		DRM_DEBUG_KMS("Test pattern read failed\n");
+		drm_dbg_kms(&i915->drm, "Test pattern read failed\n");
 		return DP_TEST_NAK;
 	}
 	if (test_pattern != DP_COLOR_RAMP)
@@ -4916,21 +5313,21 @@ static u8 intel_dp_autotest_video_pattern(struct intel_dp *intel_dp)
 	status = drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_H_WIDTH_HI,
 				  &h_width, 2);
 	if (status <= 0) {
-		DRM_DEBUG_KMS("H Width read failed\n");
+		drm_dbg_kms(&i915->drm, "H Width read failed\n");
 		return DP_TEST_NAK;
 	}
 
 	status = drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_V_HEIGHT_HI,
 				  &v_height, 2);
 	if (status <= 0) {
-		DRM_DEBUG_KMS("V Height read failed\n");
+		drm_dbg_kms(&i915->drm, "V Height read failed\n");
 		return DP_TEST_NAK;
 	}
 
 	status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_MISC0,
 				   &test_misc);
 	if (status <= 0) {
-		DRM_DEBUG_KMS("TEST MISC read failed\n");
+		drm_dbg_kms(&i915->drm, "TEST MISC read failed\n");
 		return DP_TEST_NAK;
 	}
 	if ((test_misc & DP_TEST_COLOR_FORMAT_MASK) != DP_COLOR_FORMAT_RGB)
@@ -4959,6 +5356,7 @@ static u8 intel_dp_autotest_video_pattern(struct intel_dp *intel_dp)
 
 static u8 intel_dp_autotest_edid(struct intel_dp *intel_dp)
 {
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	u8 test_result = DP_TEST_ACK;
 	struct intel_connector *intel_connector = intel_dp->attached_connector;
 	struct drm_connector *connector = &intel_connector->base;
@@ -4975,9 +5373,10 @@ static u8 intel_dp_autotest_edid(struct intel_dp *intel_dp)
 		 */
 		if (intel_dp->aux.i2c_nack_count > 0 ||
 			intel_dp->aux.i2c_defer_count > 0)
-			DRM_DEBUG_KMS("EDID read had %d NACKs, %d DEFERs\n",
-				      intel_dp->aux.i2c_nack_count,
-				      intel_dp->aux.i2c_defer_count);
+			drm_dbg_kms(&i915->drm,
+				    "EDID read had %d NACKs, %d DEFERs\n",
+				    intel_dp->aux.i2c_nack_count,
+				    intel_dp->aux.i2c_defer_count);
 		intel_dp->compliance.test_data.edid = INTEL_DP_RESOLUTION_FAILSAFE;
 	} else {
 		struct edid *block = intel_connector->detect_edid;
@@ -4989,7 +5388,8 @@ static u8 intel_dp_autotest_edid(struct intel_dp *intel_dp)
 
 		if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_EDID_CHECKSUM,
 				       block->checksum) <= 0)
-			DRM_DEBUG_KMS("Failed to write EDID checksum\n");
+			drm_dbg_kms(&i915->drm,
+				    "Failed to write EDID checksum\n");
 
 		test_result = DP_TEST_ACK | DP_TEST_EDID_CHECKSUM_WRITE;
 		intel_dp->compliance.test_data.edid = INTEL_DP_RESOLUTION_PREFERRED;
@@ -5001,43 +5401,217 @@ static u8 intel_dp_autotest_edid(struct intel_dp *intel_dp)
 	return test_result;
 }
 
+static u8 intel_dp_prepare_phytest(struct intel_dp *intel_dp)
+{
+	struct drm_dp_phy_test_params *data =
+		&intel_dp->compliance.test_data.phytest;
+
+	if (drm_dp_get_phy_test_pattern(&intel_dp->aux, data)) {
+		DRM_DEBUG_KMS("DP Phy Test pattern AUX read failure\n");
+		return DP_TEST_NAK;
+	}
+
+	/*
+	 * link_mst is set to false to avoid executing mst related code
+	 * during compliance testing.
+	 */
+	intel_dp->link_mst = false;
+
+	return DP_TEST_ACK;
+}
+
+static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp)
+{
+	struct drm_i915_private *dev_priv =
+			to_i915(dp_to_dig_port(intel_dp)->base.base.dev);
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct drm_dp_phy_test_params *data =
+			&intel_dp->compliance.test_data.phytest;
+	struct intel_crtc *crtc = to_intel_crtc(intel_dig_port->base.base.crtc);
+	enum pipe pipe = crtc->pipe;
+	u32 pattern_val;
+
+	switch (data->phy_pattern) {
+	case DP_PHY_TEST_PATTERN_NONE:
+		DRM_DEBUG_KMS("Disable Phy Test Pattern\n");
+		intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe), 0x0);
+		break;
+	case DP_PHY_TEST_PATTERN_D10_2:
+		DRM_DEBUG_KMS("Set D10.2 Phy Test Pattern\n");
+		intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe),
+			       DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_D10_2);
+		break;
+	case DP_PHY_TEST_PATTERN_ERROR_COUNT:
+		DRM_DEBUG_KMS("Set Error Count Phy Test Pattern\n");
+		intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe),
+			       DDI_DP_COMP_CTL_ENABLE |
+			       DDI_DP_COMP_CTL_SCRAMBLED_0);
+		break;
+	case DP_PHY_TEST_PATTERN_PRBS7:
+		DRM_DEBUG_KMS("Set PRBS7 Phy Test Pattern\n");
+		intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe),
+			       DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_PRBS7);
+		break;
+	case DP_PHY_TEST_PATTERN_80BIT_CUSTOM:
+		/*
+		 * FIXME: Ideally pattern should come from DPCD 0x250. As
+		 * current firmware of DPR-100 could not set it, so hardcoding
+		 * now for complaince test.
+		 */
+		DRM_DEBUG_KMS("Set 80Bit Custom Phy Test Pattern 0x3e0f83e0 0x0f83e0f8 0x0000f83e\n");
+		pattern_val = 0x3e0f83e0;
+		intel_de_write(dev_priv, DDI_DP_COMP_PAT(pipe, 0), pattern_val);
+		pattern_val = 0x0f83e0f8;
+		intel_de_write(dev_priv, DDI_DP_COMP_PAT(pipe, 1), pattern_val);
+		pattern_val = 0x0000f83e;
+		intel_de_write(dev_priv, DDI_DP_COMP_PAT(pipe, 2), pattern_val);
+		intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe),
+			       DDI_DP_COMP_CTL_ENABLE |
+			       DDI_DP_COMP_CTL_CUSTOM80);
+		break;
+	case DP_PHY_TEST_PATTERN_CP2520:
+		/*
+		 * FIXME: Ideally pattern should come from DPCD 0x24A. As
+		 * current firmware of DPR-100 could not set it, so hardcoding
+		 * now for complaince test.
+		 */
+		DRM_DEBUG_KMS("Set HBR2 compliance Phy Test Pattern\n");
+		pattern_val = 0xFB;
+		intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe),
+			       DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_HBR2 |
+			       pattern_val);
+		break;
+	default:
+		WARN(1, "Invalid Phy Test Pattern\n");
+	}
+}
+
+static void
+intel_dp_autotest_phy_ddi_disable(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = intel_dig_port->base.base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct intel_crtc *crtc = to_intel_crtc(intel_dig_port->base.base.crtc);
+	enum pipe pipe = crtc->pipe;
+	u32 trans_ddi_func_ctl_value, trans_conf_value, dp_tp_ctl_value;
+
+	trans_ddi_func_ctl_value = intel_de_read(dev_priv,
+						 TRANS_DDI_FUNC_CTL(pipe));
+	trans_conf_value = intel_de_read(dev_priv, PIPECONF(pipe));
+	dp_tp_ctl_value = intel_de_read(dev_priv, TGL_DP_TP_CTL(pipe));
+
+	trans_ddi_func_ctl_value &= ~(TRANS_DDI_FUNC_ENABLE |
+				      TGL_TRANS_DDI_PORT_MASK);
+	trans_conf_value &= ~PIPECONF_ENABLE;
+	dp_tp_ctl_value &= ~DP_TP_CTL_ENABLE;
+
+	intel_de_write(dev_priv, PIPECONF(pipe), trans_conf_value);
+	intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(pipe),
+		       trans_ddi_func_ctl_value);
+	intel_de_write(dev_priv, TGL_DP_TP_CTL(pipe), dp_tp_ctl_value);
+}
+
+static void
+intel_dp_autotest_phy_ddi_enable(struct intel_dp *intel_dp, uint8_t lane_cnt)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = intel_dig_port->base.base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	enum port port = intel_dig_port->base.port;
+	struct intel_crtc *crtc = to_intel_crtc(intel_dig_port->base.base.crtc);
+	enum pipe pipe = crtc->pipe;
+	u32 trans_ddi_func_ctl_value, trans_conf_value, dp_tp_ctl_value;
+
+	trans_ddi_func_ctl_value = intel_de_read(dev_priv,
+						 TRANS_DDI_FUNC_CTL(pipe));
+	trans_conf_value = intel_de_read(dev_priv, PIPECONF(pipe));
+	dp_tp_ctl_value = intel_de_read(dev_priv, TGL_DP_TP_CTL(pipe));
+
+	trans_ddi_func_ctl_value |= TRANS_DDI_FUNC_ENABLE |
+				    TGL_TRANS_DDI_SELECT_PORT(port);
+	trans_conf_value |= PIPECONF_ENABLE;
+	dp_tp_ctl_value |= DP_TP_CTL_ENABLE;
+
+	intel_de_write(dev_priv, PIPECONF(pipe), trans_conf_value);
+	intel_de_write(dev_priv, TGL_DP_TP_CTL(pipe), dp_tp_ctl_value);
+	intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(pipe),
+		       trans_ddi_func_ctl_value);
+}
+
+void intel_dp_process_phy_request(struct intel_dp *intel_dp)
+{
+	struct drm_dp_phy_test_params *data =
+		&intel_dp->compliance.test_data.phytest;
+	u8 link_status[DP_LINK_STATUS_SIZE];
+
+	if (!intel_dp_get_link_status(intel_dp, link_status)) {
+		DRM_DEBUG_KMS("failed to get link status\n");
+		return;
+	}
+
+	/* retrieve vswing & pre-emphasis setting */
+	intel_dp_get_adjust_train(intel_dp, link_status);
+
+	intel_dp_autotest_phy_ddi_disable(intel_dp);
+
+	intel_dp_set_signal_levels(intel_dp);
+
+	intel_dp_phy_pattern_update(intel_dp);
+
+	intel_dp_autotest_phy_ddi_enable(intel_dp, data->num_lanes);
+
+	drm_dp_set_phy_test_pattern(&intel_dp->aux, data,
+				    link_status[DP_DPCD_REV]);
+}
+
 static u8 intel_dp_autotest_phy_pattern(struct intel_dp *intel_dp)
 {
 	u8 test_result = DP_TEST_NAK;
+
+	test_result = intel_dp_prepare_phytest(intel_dp);
+	if (test_result != DP_TEST_ACK)
+		DRM_ERROR("Phy test preparation failed\n");
+
+	intel_dp_process_phy_request(intel_dp);
+
 	return test_result;
 }
 
 static void intel_dp_handle_test_request(struct intel_dp *intel_dp)
 {
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	u8 response = DP_TEST_NAK;
 	u8 request = 0;
 	int status;
 
 	status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_REQUEST, &request);
 	if (status <= 0) {
-		DRM_DEBUG_KMS("Could not read test request from sink\n");
+		drm_dbg_kms(&i915->drm,
+			    "Could not read test request from sink\n");
 		goto update_status;
 	}
 
 	switch (request) {
 	case DP_TEST_LINK_TRAINING:
-		DRM_DEBUG_KMS("LINK_TRAINING test requested\n");
+		drm_dbg_kms(&i915->drm, "LINK_TRAINING test requested\n");
 		response = intel_dp_autotest_link_training(intel_dp);
 		break;
 	case DP_TEST_LINK_VIDEO_PATTERN:
-		DRM_DEBUG_KMS("TEST_PATTERN test requested\n");
+		drm_dbg_kms(&i915->drm, "TEST_PATTERN test requested\n");
 		response = intel_dp_autotest_video_pattern(intel_dp);
 		break;
 	case DP_TEST_LINK_EDID_READ:
-		DRM_DEBUG_KMS("EDID test requested\n");
+		drm_dbg_kms(&i915->drm, "EDID test requested\n");
 		response = intel_dp_autotest_edid(intel_dp);
 		break;
 	case DP_TEST_LINK_PHY_TEST_PATTERN:
-		DRM_DEBUG_KMS("PHY_PATTERN test requested\n");
+		drm_dbg_kms(&i915->drm, "PHY_PATTERN test requested\n");
 		response = intel_dp_autotest_phy_pattern(intel_dp);
 		break;
 	default:
-		DRM_DEBUG_KMS("Invalid test request '%02x'\n", request);
+		drm_dbg_kms(&i915->drm, "Invalid test request '%02x'\n",
+			    request);
 		break;
 	}
 
@@ -5047,12 +5621,14 @@ static void intel_dp_handle_test_request(struct intel_dp *intel_dp)
 update_status:
 	status = drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_RESPONSE, response);
 	if (status <= 0)
-		DRM_DEBUG_KMS("Could not write test response to sink\n");
+		drm_dbg_kms(&i915->drm,
+			    "Could not write test response to sink\n");
 }
 
 static int
 intel_dp_check_mst_status(struct intel_dp *intel_dp)
 {
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	bool bret;
 
 	if (intel_dp->is_mst) {
@@ -5069,12 +5645,13 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp)
 			/* check link status - esi[10] = 0x200c */
 			if (intel_dp->active_mst_links > 0 &&
 			    !drm_dp_channel_eq_ok(&esi[10], intel_dp->lane_count)) {
-				DRM_DEBUG_KMS("channel EQ not ok, retraining\n");
+				drm_dbg_kms(&i915->drm,
+					    "channel EQ not ok, retraining\n");
 				intel_dp_start_link_train(intel_dp);
 				intel_dp_stop_link_train(intel_dp);
 			}
 
-			DRM_DEBUG_KMS("got esi %3ph\n", esi);
+			drm_dbg_kms(&i915->drm, "got esi %3ph\n", esi);
 			ret = drm_dp_mst_hpd_irq(&intel_dp->mst_mgr, esi, &handled);
 
 			if (handled) {
@@ -5090,7 +5667,8 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp)
 
 				bret = intel_dp_get_sink_irq_esi(intel_dp, esi);
 				if (bret == true) {
-					DRM_DEBUG_KMS("got esi2 %3ph\n", esi);
+					drm_dbg_kms(&i915->drm,
+						    "got esi2 %3ph\n", esi);
 					goto go_again;
 				}
 			} else
@@ -5098,7 +5676,8 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp)
 
 			return ret;
 		} else {
-			DRM_DEBUG_KMS("failed to get ESI - device may have failed\n");
+			drm_dbg_kms(&i915->drm,
+				    "failed to get ESI - device may have failed\n");
 			intel_dp->is_mst = false;
 			drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr,
 							intel_dp->is_mst);
@@ -5220,14 +5799,13 @@ int intel_dp_retrain_link(struct intel_encoder *encoder,
  */
 static enum intel_hotplug_state
 intel_dp_hotplug(struct intel_encoder *encoder,
-		 struct intel_connector *connector,
-		 bool irq_received)
+		 struct intel_connector *connector)
 {
 	struct drm_modeset_acquire_ctx ctx;
 	enum intel_hotplug_state state;
 	int ret;
 
-	state = intel_encoder_hotplug(encoder, connector, irq_received);
+	state = intel_encoder_hotplug(encoder, connector);
 
 	drm_modeset_acquire_init(&ctx, 0);
 
@@ -5251,7 +5829,7 @@ intel_dp_hotplug(struct intel_encoder *encoder,
 	 * Keeping it consistent with intel_ddi_hotplug() and
 	 * intel_hdmi_hotplug().
 	 */
-	if (state == INTEL_HOTPLUG_UNCHANGED && irq_received)
+	if (state == INTEL_HOTPLUG_UNCHANGED && !connector->hotplug_retries)
 		state = INTEL_HOTPLUG_RETRY;
 
 	return state;
@@ -5259,6 +5837,7 @@ intel_dp_hotplug(struct intel_encoder *encoder,
 
 static void intel_dp_check_service_irq(struct intel_dp *intel_dp)
 {
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	u8 val;
 
 	if (intel_dp->dpcd[DP_DPCD_REV] < 0x11)
@@ -5277,7 +5856,7 @@ static void intel_dp_check_service_irq(struct intel_dp *intel_dp)
 		intel_hdcp_handle_cp_irq(intel_dp->attached_connector);
 
 	if (val & DP_SINK_SPECIFIC_IRQ)
-		DRM_DEBUG_DRIVER("Sink specific irq unhandled\n");
+		drm_dbg_kms(&i915->drm, "Sink specific irq unhandled\n");
 }
 
 /*
@@ -5344,6 +5923,7 @@ intel_dp_short_pulse(struct intel_dp *intel_dp)
 static enum drm_connector_status
 intel_dp_detect_dpcd(struct intel_dp *intel_dp)
 {
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	struct intel_lspcon *lspcon = dp_to_lspcon(intel_dp);
 	u8 *dpcd = intel_dp->dpcd;
 	u8 type;
@@ -5391,7 +5971,7 @@ intel_dp_detect_dpcd(struct intel_dp *intel_dp)
 	}
 
 	/* Anything else is out of spec, warn and ignore */
-	DRM_DEBUG_KMS("Broken DP branch device, ignoring\n");
+	drm_dbg_kms(&i915->drm, "Broken DP branch device, ignoring\n");
 	return connector_status_disconnected;
 }
 
@@ -5863,6 +6443,7 @@ static int intel_dp_get_modes(struct drm_connector *connector)
 static int
 intel_dp_connector_register(struct drm_connector *connector)
 {
+	struct drm_i915_private *i915 = to_i915(connector->dev);
 	struct intel_dp *intel_dp = intel_attached_dp(to_intel_connector(connector));
 	int ret;
 
@@ -5872,8 +6453,8 @@ intel_dp_connector_register(struct drm_connector *connector)
 
 	intel_connector_debugfs_add(connector);
 
-	DRM_DEBUG_KMS("registering %s bus for %s\n",
-		      intel_dp->aux.name, connector->kdev->kobj.name);
+	drm_dbg_kms(&i915->drm, "registering %s bus for %s\n",
+		    intel_dp->aux.name, connector->kdev->kobj.name);
 
 	intel_dp->aux.dev = connector->kdev;
 	ret = drm_dp_aux_register(&intel_dp->aux);
@@ -5959,6 +6540,7 @@ static
 int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port,
 				u8 *an)
 {
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
 	struct intel_dp *intel_dp = enc_to_intel_dp(to_intel_encoder(&intel_dig_port->base.base));
 	static const struct drm_dp_aux_msg msg = {
 		.request = DP_AUX_NATIVE_WRITE,
@@ -5973,8 +6555,9 @@ int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port,
 	dpcd_ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux, DP_AUX_HDCP_AN,
 				     an, DRM_HDCP_AN_LEN);
 	if (dpcd_ret != DRM_HDCP_AN_LEN) {
-		DRM_DEBUG_KMS("Failed to write An over DP/AUX (%zd)\n",
-			      dpcd_ret);
+		drm_dbg_kms(&i915->drm,
+			    "Failed to write An over DP/AUX (%zd)\n",
+			    dpcd_ret);
 		return dpcd_ret >= 0 ? -EIO : dpcd_ret;
 	}
 
@@ -5990,17 +6573,19 @@ int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port,
 				rxbuf, sizeof(rxbuf),
 				DP_AUX_CH_CTL_AUX_AKSV_SELECT);
 	if (ret < 0) {
-		DRM_DEBUG_KMS("Write Aksv over DP/AUX failed (%d)\n", ret);
+		drm_dbg_kms(&i915->drm,
+			    "Write Aksv over DP/AUX failed (%d)\n", ret);
 		return ret;
 	} else if (ret == 0) {
-		DRM_DEBUG_KMS("Aksv write over DP/AUX was empty\n");
+		drm_dbg_kms(&i915->drm, "Aksv write over DP/AUX was empty\n");
 		return -EIO;
 	}
 
 	reply = (rxbuf[0] >> 4) & DP_AUX_NATIVE_REPLY_MASK;
 	if (reply != DP_AUX_NATIVE_REPLY_ACK) {
-		DRM_DEBUG_KMS("Aksv write: no DP_AUX_NATIVE_REPLY_ACK %x\n",
-			      reply);
+		drm_dbg_kms(&i915->drm,
+			    "Aksv write: no DP_AUX_NATIVE_REPLY_ACK %x\n",
+			    reply);
 		return -EIO;
 	}
 	return 0;
@@ -6009,11 +6594,14 @@ int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port,
 static int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port,
 				   u8 *bksv)
 {
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
 	ssize_t ret;
+
 	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BKSV, bksv,
 			       DRM_HDCP_KSV_LEN);
 	if (ret != DRM_HDCP_KSV_LEN) {
-		DRM_DEBUG_KMS("Read Bksv from DP/AUX failed (%zd)\n", ret);
+		drm_dbg_kms(&i915->drm,
+			    "Read Bksv from DP/AUX failed (%zd)\n", ret);
 		return ret >= 0 ? -EIO : ret;
 	}
 	return 0;
@@ -6022,7 +6610,9 @@ static int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port,
 static int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
 				      u8 *bstatus)
 {
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
 	ssize_t ret;
+
 	/*
 	 * For some reason the HDMI and DP HDCP specs call this register
 	 * definition by different names. In the HDMI spec, it's called BSTATUS,
@@ -6031,7 +6621,8 @@ static int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
 	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BINFO,
 			       bstatus, DRM_HDCP_BSTATUS_LEN);
 	if (ret != DRM_HDCP_BSTATUS_LEN) {
-		DRM_DEBUG_KMS("Read bstatus from DP/AUX failed (%zd)\n", ret);
+		drm_dbg_kms(&i915->drm,
+			    "Read bstatus from DP/AUX failed (%zd)\n", ret);
 		return ret >= 0 ? -EIO : ret;
 	}
 	return 0;
@@ -6041,12 +6632,14 @@ static
 int intel_dp_hdcp_read_bcaps(struct intel_digital_port *intel_dig_port,
 			     u8 *bcaps)
 {
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
 	ssize_t ret;
 
 	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BCAPS,
 			       bcaps, 1);
 	if (ret != 1) {
-		DRM_DEBUG_KMS("Read bcaps from DP/AUX failed (%zd)\n", ret);
+		drm_dbg_kms(&i915->drm,
+			    "Read bcaps from DP/AUX failed (%zd)\n", ret);
 		return ret >= 0 ? -EIO : ret;
 	}
 
@@ -6072,11 +6665,14 @@ static
 int intel_dp_hdcp_read_ri_prime(struct intel_digital_port *intel_dig_port,
 				u8 *ri_prime)
 {
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
 	ssize_t ret;
+
 	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_RI_PRIME,
 			       ri_prime, DRM_HDCP_RI_LEN);
 	if (ret != DRM_HDCP_RI_LEN) {
-		DRM_DEBUG_KMS("Read Ri' from DP/AUX failed (%zd)\n", ret);
+		drm_dbg_kms(&i915->drm, "Read Ri' from DP/AUX failed (%zd)\n",
+			    ret);
 		return ret >= 0 ? -EIO : ret;
 	}
 	return 0;
@@ -6086,12 +6682,15 @@ static
 int intel_dp_hdcp_read_ksv_ready(struct intel_digital_port *intel_dig_port,
 				 bool *ksv_ready)
 {
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
 	ssize_t ret;
 	u8 bstatus;
+
 	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BSTATUS,
 			       &bstatus, 1);
 	if (ret != 1) {
-		DRM_DEBUG_KMS("Read bstatus from DP/AUX failed (%zd)\n", ret);
+		drm_dbg_kms(&i915->drm,
+			    "Read bstatus from DP/AUX failed (%zd)\n", ret);
 		return ret >= 0 ? -EIO : ret;
 	}
 	*ksv_ready = bstatus & DP_BSTATUS_READY;
@@ -6102,6 +6701,7 @@ static
 int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *intel_dig_port,
 				int num_downstream, u8 *ksv_fifo)
 {
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
 	ssize_t ret;
 	int i;
 
@@ -6113,8 +6713,9 @@ int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *intel_dig_port,
 				       ksv_fifo + i * DRM_HDCP_KSV_LEN,
 				       len);
 		if (ret != len) {
-			DRM_DEBUG_KMS("Read ksv[%d] from DP/AUX failed (%zd)\n",
-				      i, ret);
+			drm_dbg_kms(&i915->drm,
+				    "Read ksv[%d] from DP/AUX failed (%zd)\n",
+				    i, ret);
 			return ret >= 0 ? -EIO : ret;
 		}
 	}
@@ -6125,6 +6726,7 @@ static
 int intel_dp_hdcp_read_v_prime_part(struct intel_digital_port *intel_dig_port,
 				    int i, u32 *part)
 {
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
 	ssize_t ret;
 
 	if (i >= DRM_HDCP_V_PRIME_NUM_PARTS)
@@ -6134,7 +6736,8 @@ int intel_dp_hdcp_read_v_prime_part(struct intel_digital_port *intel_dig_port,
 			       DP_AUX_HDCP_V_PRIME(i), part,
 			       DRM_HDCP_V_PRIME_PART_LEN);
 	if (ret != DRM_HDCP_V_PRIME_PART_LEN) {
-		DRM_DEBUG_KMS("Read v'[%d] from DP/AUX failed (%zd)\n", i, ret);
+		drm_dbg_kms(&i915->drm,
+			    "Read v'[%d] from DP/AUX failed (%zd)\n", i, ret);
 		return ret >= 0 ? -EIO : ret;
 	}
 	return 0;
@@ -6151,13 +6754,15 @@ int intel_dp_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
 static
 bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port)
 {
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
 	ssize_t ret;
 	u8 bstatus;
 
 	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BSTATUS,
 			       &bstatus, 1);
 	if (ret != 1) {
-		DRM_DEBUG_KMS("Read bstatus from DP/AUX failed (%zd)\n", ret);
+		drm_dbg_kms(&i915->drm,
+			    "Read bstatus from DP/AUX failed (%zd)\n", ret);
 		return false;
 	}
 
@@ -6232,13 +6837,15 @@ static inline
 int intel_dp_hdcp2_read_rx_status(struct intel_digital_port *intel_dig_port,
 				  u8 *rx_status)
 {
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
 	ssize_t ret;
 
 	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
 			       DP_HDCP_2_2_REG_RXSTATUS_OFFSET, rx_status,
 			       HDCP_2_2_DP_RXSTATUS_LEN);
 	if (ret != HDCP_2_2_DP_RXSTATUS_LEN) {
-		DRM_DEBUG_KMS("Read bstatus from DP/AUX failed (%zd)\n", ret);
+		drm_dbg_kms(&i915->drm,
+			    "Read bstatus from DP/AUX failed (%zd)\n", ret);
 		return ret >= 0 ? -EIO : ret;
 	}
 
@@ -6282,6 +6889,7 @@ static ssize_t
 intel_dp_hdcp2_wait_for_msg(struct intel_digital_port *intel_dig_port,
 			    const struct hdcp2_dp_msg_data *hdcp2_msg_data)
 {
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
 	struct intel_dp *dp = &intel_dig_port->dp;
 	struct intel_hdcp *hdcp = &dp->attached_connector->hdcp;
 	u8 msg_id = hdcp2_msg_data->msg_id;
@@ -6313,8 +6921,9 @@ intel_dp_hdcp2_wait_for_msg(struct intel_digital_port *intel_dig_port,
 	}
 
 	if (ret)
-		DRM_DEBUG_KMS("msg_id %d, ret %d, timeout(mSec): %d\n",
-			      hdcp2_msg_data->msg_id, ret, timeout);
+		drm_dbg_kms(&i915->drm,
+			    "msg_id %d, ret %d, timeout(mSec): %d\n",
+			    hdcp2_msg_data->msg_id, ret, timeout);
 
 	return ret;
 }
@@ -6400,6 +7009,7 @@ static
 int intel_dp_hdcp2_read_msg(struct intel_digital_port *intel_dig_port,
 			    u8 msg_id, void *buf, size_t size)
 {
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
 	unsigned int offset;
 	u8 *byte = buf;
 	ssize_t ret, bytes_to_recv, len;
@@ -6433,7 +7043,8 @@ int intel_dp_hdcp2_read_msg(struct intel_digital_port *intel_dig_port,
 		ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, offset,
 				       (void *)byte, len);
 		if (ret < 0) {
-			DRM_DEBUG_KMS("msg_id %d, ret %zd\n", msg_id, ret);
+			drm_dbg_kms(&i915->drm, "msg_id %d, ret %zd\n",
+				    msg_id, ret);
 			return ret;
 		}
 
@@ -6724,7 +7335,11 @@ static int intel_dp_connector_atomic_check(struct drm_connector *conn,
 	if (ret)
 		return ret;
 
-	if (INTEL_GEN(dev_priv) < 11)
+	/*
+	 * We don't enable port sync on BDW due to missing w/as and
+	 * due to not having adjusted the modeset sequence appropriately.
+	 */
+	if (INTEL_GEN(dev_priv) < 9)
 		return 0;
 
 	if (!intel_connector_needs_modeset(state, conn))
@@ -6763,28 +7378,45 @@ static const struct drm_encoder_funcs intel_dp_enc_funcs = {
 	.destroy = intel_dp_encoder_destroy,
 };
 
+static bool intel_edp_have_power(struct intel_dp *intel_dp)
+{
+	intel_wakeref_t wakeref;
+	bool have_power = false;
+
+	with_pps_lock(intel_dp, wakeref) {
+		have_power = edp_have_panel_power(intel_dp) &&
+						  edp_have_panel_vdd(intel_dp);
+	}
+
+	return have_power;
+}
+
 enum irqreturn
 intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
 {
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
 	struct intel_dp *intel_dp = &intel_dig_port->dp;
 
-	if (long_hpd && intel_dig_port->base.type == INTEL_OUTPUT_EDP) {
+	if (intel_dig_port->base.type == INTEL_OUTPUT_EDP &&
+	    (long_hpd || !intel_edp_have_power(intel_dp))) {
 		/*
-		 * vdd off can generate a long pulse on eDP which
+		 * vdd off can generate a long/short pulse on eDP which
 		 * would require vdd on to handle it, and thus we
 		 * would end up in an endless cycle of
-		 * "vdd off -> long hpd -> vdd on -> detect -> vdd off -> ..."
+		 * "vdd off -> long/short hpd -> vdd on -> detect -> vdd off -> ..."
 		 */
-		DRM_DEBUG_KMS("ignoring long hpd on eDP [ENCODER:%d:%s]\n",
-			      intel_dig_port->base.base.base.id,
-			      intel_dig_port->base.base.name);
+		drm_dbg_kms(&i915->drm,
+			    "ignoring %s hpd on eDP [ENCODER:%d:%s]\n",
+			    long_hpd ? "long" : "short",
+			    intel_dig_port->base.base.base.id,
+			    intel_dig_port->base.base.name);
 		return IRQ_HANDLED;
 	}
 
-	DRM_DEBUG_KMS("got hpd irq on [ENCODER:%d:%s] - %s\n",
-		      intel_dig_port->base.base.base.id,
-		      intel_dig_port->base.base.name,
-		      long_hpd ? "long" : "short");
+	drm_dbg_kms(&i915->drm, "got hpd irq on [ENCODER:%d:%s] - %s\n",
+		    intel_dig_port->base.base.base.id,
+		    intel_dig_port->base.base.name,
+		    long_hpd ? "long" : "short");
 
 	if (long_hpd) {
 		intel_dp->reset_link_params = true;
@@ -6797,8 +7429,10 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
 			 * If we were in MST mode, and device is not
 			 * there, get out of MST mode
 			 */
-			DRM_DEBUG_KMS("MST device may have disappeared %d vs %d\n",
-				      intel_dp->is_mst, intel_dp->mst_mgr.mst_state);
+			drm_dbg_kms(&i915->drm,
+				    "MST device may have disappeared %d vs %d\n",
+				    intel_dp->is_mst,
+				    intel_dp->mst_mgr.mst_state);
 			intel_dp->is_mst = false;
 			drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr,
 							intel_dp->is_mst);
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index 0c7be8ed1423..6659ce15a693 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -114,7 +114,11 @@ void intel_dp_vsc_enable(struct intel_dp *intel_dp,
 void intel_dp_hdr_metadata_enable(struct intel_dp *intel_dp,
 				  const struct intel_crtc_state *crtc_state,
 				  const struct drm_connector_state *conn_state);
+void intel_dp_set_infoframes(struct intel_encoder *encoder, bool enable,
+			     const struct intel_crtc_state *crtc_state,
+			     const struct drm_connector_state *conn_state);
 bool intel_digital_port_connected(struct intel_encoder *encoder);
+void intel_dp_process_phy_request(struct intel_dp *intel_dp);
 
 static inline unsigned int intel_dp_unused_lane_mask(int lane_count)
 {
diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
index 3e706bb850a8..4b916468540f 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
@@ -27,6 +27,7 @@
 
 static void set_aux_backlight_enable(struct intel_dp *intel_dp, bool enable)
 {
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	u8 reg_val = 0;
 
 	/* Early return when display use other mechanism to enable backlight. */
@@ -35,8 +36,8 @@ static void set_aux_backlight_enable(struct intel_dp *intel_dp, bool enable)
 
 	if (drm_dp_dpcd_readb(&intel_dp->aux, DP_EDP_DISPLAY_CONTROL_REGISTER,
 			      &reg_val) < 0) {
-		DRM_DEBUG_KMS("Failed to read DPCD register 0x%x\n",
-			      DP_EDP_DISPLAY_CONTROL_REGISTER);
+		drm_dbg_kms(&i915->drm, "Failed to read DPCD register 0x%x\n",
+			    DP_EDP_DISPLAY_CONTROL_REGISTER);
 		return;
 	}
 	if (enable)
@@ -46,8 +47,8 @@ static void set_aux_backlight_enable(struct intel_dp *intel_dp, bool enable)
 
 	if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_EDP_DISPLAY_CONTROL_REGISTER,
 			       reg_val) != 1) {
-		DRM_DEBUG_KMS("Failed to %s aux backlight\n",
-			      enable ? "enable" : "disable");
+		drm_dbg_kms(&i915->drm, "Failed to %s aux backlight\n",
+			    enable ? "enable" : "disable");
 	}
 }
 
@@ -58,6 +59,7 @@ static void set_aux_backlight_enable(struct intel_dp *intel_dp, bool enable)
 static u32 intel_dp_aux_get_backlight(struct intel_connector *connector)
 {
 	struct intel_dp *intel_dp = intel_attached_dp(connector);
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	u8 read_val[2] = { 0x0 };
 	u8 mode_reg;
 	u16 level = 0;
@@ -65,8 +67,9 @@ static u32 intel_dp_aux_get_backlight(struct intel_connector *connector)
 	if (drm_dp_dpcd_readb(&intel_dp->aux,
 			      DP_EDP_BACKLIGHT_MODE_SET_REGISTER,
 			      &mode_reg) != 1) {
-		DRM_DEBUG_KMS("Failed to read the DPCD register 0x%x\n",
-			      DP_EDP_BACKLIGHT_MODE_SET_REGISTER);
+		drm_dbg_kms(&i915->drm,
+			    "Failed to read the DPCD register 0x%x\n",
+			    DP_EDP_BACKLIGHT_MODE_SET_REGISTER);
 		return 0;
 	}
 
@@ -80,8 +83,8 @@ static u32 intel_dp_aux_get_backlight(struct intel_connector *connector)
 
 	if (drm_dp_dpcd_read(&intel_dp->aux, DP_EDP_BACKLIGHT_BRIGHTNESS_MSB,
 			     &read_val, sizeof(read_val)) < 0) {
-		DRM_DEBUG_KMS("Failed to read DPCD register 0x%x\n",
-			      DP_EDP_BACKLIGHT_BRIGHTNESS_MSB);
+		drm_dbg_kms(&i915->drm, "Failed to read DPCD register 0x%x\n",
+			    DP_EDP_BACKLIGHT_BRIGHTNESS_MSB);
 		return 0;
 	}
 	level = read_val[0];
@@ -100,6 +103,7 @@ intel_dp_aux_set_backlight(const struct drm_connector_state *conn_state, u32 lev
 {
 	struct intel_connector *connector = to_intel_connector(conn_state->connector);
 	struct intel_dp *intel_dp = intel_attached_dp(connector);
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	u8 vals[2] = { 0x0 };
 
 	vals[0] = level;
@@ -111,7 +115,8 @@ intel_dp_aux_set_backlight(const struct drm_connector_state *conn_state, u32 lev
 	}
 	if (drm_dp_dpcd_write(&intel_dp->aux, DP_EDP_BACKLIGHT_BRIGHTNESS_MSB,
 			      vals, sizeof(vals)) < 0) {
-		DRM_DEBUG_KMS("Failed to write aux backlight level\n");
+		drm_dbg_kms(&i915->drm,
+			    "Failed to write aux backlight level\n");
 		return;
 	}
 }
@@ -133,7 +138,8 @@ static bool intel_dp_aux_set_pwm_freq(struct intel_connector *connector)
 
 	freq = dev_priv->vbt.backlight.pwm_freq_hz;
 	if (!freq) {
-		DRM_DEBUG_KMS("Use panel default backlight frequency\n");
+		drm_dbg_kms(&dev_priv->drm,
+			    "Use panel default backlight frequency\n");
 		return false;
 	}
 
@@ -146,13 +152,14 @@ static bool intel_dp_aux_set_pwm_freq(struct intel_connector *connector)
 	fxp_max = DIV_ROUND_CLOSEST(fxp * 5, 4);
 
 	if (fxp_min > fxp_actual || fxp_actual > fxp_max) {
-		DRM_DEBUG_KMS("Actual frequency out of range\n");
+		drm_dbg_kms(&dev_priv->drm, "Actual frequency out of range\n");
 		return false;
 	}
 
 	if (drm_dp_dpcd_writeb(&intel_dp->aux,
 			       DP_EDP_BACKLIGHT_FREQ_SET, (u8) f) < 0) {
-		DRM_DEBUG_KMS("Failed to write aux backlight freq\n");
+		drm_dbg_kms(&dev_priv->drm,
+			    "Failed to write aux backlight freq\n");
 		return false;
 	}
 	return true;
@@ -163,13 +170,14 @@ static void intel_dp_aux_enable_backlight(const struct intel_crtc_state *crtc_st
 {
 	struct intel_connector *connector = to_intel_connector(conn_state->connector);
 	struct intel_dp *intel_dp = intel_attached_dp(connector);
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	struct intel_panel *panel = &connector->panel;
 	u8 dpcd_buf, new_dpcd_buf, edp_backlight_mode;
 
 	if (drm_dp_dpcd_readb(&intel_dp->aux,
 			DP_EDP_BACKLIGHT_MODE_SET_REGISTER, &dpcd_buf) != 1) {
-		DRM_DEBUG_KMS("Failed to read DPCD register 0x%x\n",
-			      DP_EDP_BACKLIGHT_MODE_SET_REGISTER);
+		drm_dbg_kms(&i915->drm, "Failed to read DPCD register 0x%x\n",
+			    DP_EDP_BACKLIGHT_MODE_SET_REGISTER);
 		return;
 	}
 
@@ -186,7 +194,8 @@ static void intel_dp_aux_enable_backlight(const struct intel_crtc_state *crtc_st
 		if (drm_dp_dpcd_writeb(&intel_dp->aux,
 				       DP_EDP_PWMGEN_BIT_COUNT,
 				       panel->backlight.pwmgen_bit_count) < 0)
-			DRM_DEBUG_KMS("Failed to write aux pwmgen bit count\n");
+			drm_dbg_kms(&i915->drm,
+				    "Failed to write aux pwmgen bit count\n");
 
 		break;
 
@@ -203,7 +212,8 @@ static void intel_dp_aux_enable_backlight(const struct intel_crtc_state *crtc_st
 	if (new_dpcd_buf != dpcd_buf) {
 		if (drm_dp_dpcd_writeb(&intel_dp->aux,
 			DP_EDP_BACKLIGHT_MODE_SET_REGISTER, new_dpcd_buf) < 0) {
-			DRM_DEBUG_KMS("Failed to write aux backlight mode\n");
+			drm_dbg_kms(&i915->drm,
+				    "Failed to write aux backlight mode\n");
 		}
 	}
 
@@ -237,9 +247,11 @@ static u32 intel_dp_aux_calc_max_backlight(struct intel_connector *connector)
 	 * minimum value will applied automatically. So no need to check that.
 	 */
 	freq = i915->vbt.backlight.pwm_freq_hz;
-	DRM_DEBUG_KMS("VBT defined backlight frequency %u Hz\n", freq);
+	drm_dbg_kms(&i915->drm, "VBT defined backlight frequency %u Hz\n",
+		    freq);
 	if (!freq) {
-		DRM_DEBUG_KMS("Use panel default backlight frequency\n");
+		drm_dbg_kms(&i915->drm,
+			    "Use panel default backlight frequency\n");
 		return max_backlight;
 	}
 
@@ -254,12 +266,14 @@ static u32 intel_dp_aux_calc_max_backlight(struct intel_connector *connector)
 	 */
 	if (drm_dp_dpcd_readb(&intel_dp->aux,
 			      DP_EDP_PWMGEN_BIT_COUNT_CAP_MIN, &pn_min) != 1) {
-		DRM_DEBUG_KMS("Failed to read pwmgen bit count cap min\n");
+		drm_dbg_kms(&i915->drm,
+			    "Failed to read pwmgen bit count cap min\n");
 		return max_backlight;
 	}
 	if (drm_dp_dpcd_readb(&intel_dp->aux,
 			      DP_EDP_PWMGEN_BIT_COUNT_CAP_MAX, &pn_max) != 1) {
-		DRM_DEBUG_KMS("Failed to read pwmgen bit count cap max\n");
+		drm_dbg_kms(&i915->drm,
+			    "Failed to read pwmgen bit count cap max\n");
 		return max_backlight;
 	}
 	pn_min &= DP_EDP_PWMGEN_BIT_COUNT_MASK;
@@ -268,7 +282,8 @@ static u32 intel_dp_aux_calc_max_backlight(struct intel_connector *connector)
 	fxp_min = DIV_ROUND_CLOSEST(fxp * 3, 4);
 	fxp_max = DIV_ROUND_CLOSEST(fxp * 5, 4);
 	if (fxp_min < (1 << pn_min) || (255 << pn_max) < fxp_max) {
-		DRM_DEBUG_KMS("VBT defined backlight frequency out of range\n");
+		drm_dbg_kms(&i915->drm,
+			    "VBT defined backlight frequency out of range\n");
 		return max_backlight;
 	}
 
@@ -279,10 +294,11 @@ static u32 intel_dp_aux_calc_max_backlight(struct intel_connector *connector)
 			break;
 	}
 
-	DRM_DEBUG_KMS("Using eDP pwmgen bit count of %d\n", pn);
+	drm_dbg_kms(&i915->drm, "Using eDP pwmgen bit count of %d\n", pn);
 	if (drm_dp_dpcd_writeb(&intel_dp->aux,
 			       DP_EDP_PWMGEN_BIT_COUNT, pn) < 0) {
-		DRM_DEBUG_KMS("Failed to write aux pwmgen bit count\n");
+		drm_dbg_kms(&i915->drm,
+			    "Failed to write aux pwmgen bit count\n");
 		return max_backlight;
 	}
 	panel->backlight.pwmgen_bit_count = pn;
@@ -312,6 +328,7 @@ static bool
 intel_dp_aux_display_control_capable(struct intel_connector *connector)
 {
 	struct intel_dp *intel_dp = intel_attached_dp(connector);
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 
 	/* Check the eDP Display control capabilities registers to determine if
 	 * the panel can support backlight control over the aux channel
@@ -319,7 +336,7 @@ intel_dp_aux_display_control_capable(struct intel_connector *connector)
 	if (intel_dp->edp_dpcd[1] & DP_EDP_TCON_BACKLIGHT_ADJUSTMENT_CAP &&
 	    (intel_dp->edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_AUX_SET_CAP) &&
 	    !(intel_dp->edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_PWM_PIN_CAP)) {
-		DRM_DEBUG_KMS("AUX Backlight Control Supported!\n");
+		drm_dbg_kms(&i915->drm, "AUX Backlight Control Supported!\n");
 		return true;
 	}
 	return false;
@@ -329,8 +346,7 @@ int intel_dp_aux_init_backlight_funcs(struct intel_connector *intel_connector)
 {
 	struct intel_panel *panel = &intel_connector->panel;
 	struct intel_dp *intel_dp = enc_to_intel_dp(intel_connector->encoder);
-	struct drm_device *dev = intel_connector->base.dev;
-	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 
 	if (i915_modparams.enable_dpcd_backlight == 0 ||
 	    !intel_dp_aux_display_control_capable(intel_connector))
@@ -340,17 +356,17 @@ int intel_dp_aux_init_backlight_funcs(struct intel_connector *intel_connector)
 	 * There are a lot of machines that don't advertise the backlight
 	 * control interface to use properly in their VBIOS, :\
 	 */
-	if (dev_priv->vbt.backlight.type !=
+	if (i915->vbt.backlight.type !=
 	    INTEL_BACKLIGHT_VESA_EDP_AUX_INTERFACE &&
 	    !drm_dp_has_quirk(&intel_dp->desc, intel_dp->edid_quirks,
 			      DP_QUIRK_FORCE_DPCD_BACKLIGHT)) {
-		DRM_DEV_INFO(dev->dev,
-			     "Panel advertises DPCD backlight support, but "
-			     "VBT disagrees. If your backlight controls "
-			     "don't work try booting with "
-			     "i915.enable_dpcd_backlight=1. If your machine "
-			     "needs this, please file a _new_ bug report on "
-			     "drm/i915, see " FDO_BUG_URL " for details.\n");
+		drm_info(&i915->drm,
+			 "Panel advertises DPCD backlight support, but "
+			 "VBT disagrees. If your backlight controls "
+			 "don't work try booting with "
+			 "i915.enable_dpcd_backlight=1. If your machine "
+			 "needs this, please file a _new_ bug report on "
+			 "drm/i915, see " FDO_BUG_URL " for details.\n");
 		return -ENODEV;
 	}
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
index a7defb37ab00..e4f1843170b7 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
@@ -34,9 +34,8 @@ intel_dp_dump_link_status(const u8 link_status[DP_LINK_STATUS_SIZE])
 		      link_status[3], link_status[4], link_status[5]);
 }
 
-static void
-intel_get_adjust_train(struct intel_dp *intel_dp,
-		       const u8 link_status[DP_LINK_STATUS_SIZE])
+void intel_dp_get_adjust_train(struct intel_dp *intel_dp,
+			       const u8 link_status[DP_LINK_STATUS_SIZE])
 {
 	u8 v = 0;
 	u8 p = 0;
@@ -219,7 +218,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
 		voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
 
 		/* Update training set as requested by target */
-		intel_get_adjust_train(intel_dp, link_status);
+		intel_dp_get_adjust_train(intel_dp, link_status);
 		if (!intel_dp_update_link_train(intel_dp)) {
 			drm_err(&i915->drm,
 				"failed to update link training\n");
@@ -338,7 +337,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
 		}
 
 		/* Update training set as requested by target */
-		intel_get_adjust_train(intel_dp, link_status);
+		intel_dp_get_adjust_train(intel_dp, link_status);
 		if (!intel_dp_update_link_train(intel_dp)) {
 			drm_err(&i915->drm,
 				"failed to update link training\n");
diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.h b/drivers/gpu/drm/i915/display/intel_dp_link_training.h
index 174566adcc92..01f1dabbb060 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.h
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.h
@@ -6,8 +6,12 @@
 #ifndef __INTEL_DP_LINK_TRAINING_H__
 #define __INTEL_DP_LINK_TRAINING_H__
 
+#include <drm/drm_dp_helper.h>
+
 struct intel_dp;
 
+void intel_dp_get_adjust_train(struct intel_dp *intel_dp,
+			       const u8 link_status[DP_LINK_STATUS_SIZE]);
 void intel_dp_start_link_train(struct intel_dp *intel_dp);
 void intel_dp_stop_link_train(struct intel_dp *intel_dp);
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 44f3fd251ca1..a83f910d8e15 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -47,9 +47,9 @@ static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
 	struct intel_dp *intel_dp = &intel_mst->primary->dp;
 	struct intel_connector *connector =
 		to_intel_connector(conn_state->connector);
+	struct drm_i915_private *i915 = to_i915(connector->base.dev);
 	const struct drm_display_mode *adjusted_mode =
 		&crtc_state->hw.adjusted_mode;
-	void *port = connector->port;
 	bool constant_n = drm_dp_has_quirk(&intel_dp->desc, 0,
 					   DP_DPCD_QUIRK_CONSTANT_N);
 	int bpp, slots = -EINVAL;
@@ -65,7 +65,8 @@ static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
 						       false);
 
 		slots = drm_dp_atomic_find_vcpi_slots(state, &intel_dp->mst_mgr,
-						      port, crtc_state->pbn, 0);
+						      connector->port,
+						      crtc_state->pbn, 0);
 		if (slots == -EDEADLK)
 			return slots;
 		if (slots >= 0)
@@ -73,7 +74,8 @@ static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
 	}
 
 	if (slots < 0) {
-		DRM_DEBUG_KMS("failed finding vcpi slots:%d\n", slots);
+		drm_dbg_kms(&i915->drm, "failed finding vcpi slots:%d\n",
+			    slots);
 		return slots;
 	}
 
@@ -88,56 +90,10 @@ static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
 	return 0;
 }
 
-/*
- * Iterate over all connectors and return the smallest transcoder in the MST
- * stream
- */
-static enum transcoder
-intel_dp_mst_master_trans_compute(struct intel_atomic_state *state,
-				  struct intel_dp *mst_port)
-{
-	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
-	struct intel_digital_connector_state *conn_state;
-	struct intel_connector *connector;
-	enum pipe ret = I915_MAX_PIPES;
-	int i;
-
-	if (INTEL_GEN(dev_priv) < 12)
-		return INVALID_TRANSCODER;
-
-	for_each_new_intel_connector_in_state(state, connector, conn_state, i) {
-		struct intel_crtc_state *crtc_state;
-		struct intel_crtc *crtc;
-
-		if (connector->mst_port != mst_port || !conn_state->base.crtc)
-			continue;
-
-		crtc = to_intel_crtc(conn_state->base.crtc);
-		crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
-		if (!crtc_state->uapi.active)
-			continue;
-
-		/*
-		 * Using crtc->pipe because crtc_state->cpu_transcoder is
-		 * computed, so others CRTCs could have non-computed
-		 * cpu_transcoder
-		 */
-		if (crtc->pipe < ret)
-			ret = crtc->pipe;
-	}
-
-	if (ret == I915_MAX_PIPES)
-		return INVALID_TRANSCODER;
-
-	/* Simple cast works because TGL don't have a eDP transcoder */
-	return (enum transcoder)ret;
-}
-
 static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
 				       struct intel_crtc_state *pipe_config,
 				       struct drm_connector_state *conn_state)
 {
-	struct intel_atomic_state *state = to_intel_atomic_state(conn_state->state);
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder);
 	struct intel_dp *intel_dp = &intel_mst->primary->dp;
@@ -147,7 +103,6 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
 		to_intel_digital_connector_state(conn_state);
 	const struct drm_display_mode *adjusted_mode =
 		&pipe_config->hw.adjusted_mode;
-	void *port = connector->port;
 	struct link_config_limits limits;
 	int ret;
 
@@ -158,8 +113,7 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
 	pipe_config->has_pch_encoder = false;
 
 	if (intel_conn_state->force_audio == HDMI_AUDIO_AUTO)
-		pipe_config->has_audio =
-			drm_dp_mst_port_has_audio(&intel_dp->mst_mgr, port);
+		pipe_config->has_audio = connector->port->has_audio;
 	else
 		pipe_config->has_audio =
 			intel_conn_state->force_audio == HDMI_AUDIO_ON;
@@ -201,7 +155,56 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
 
 	intel_ddi_compute_min_voltage_level(dev_priv, pipe_config);
 
-	pipe_config->mst_master_transcoder = intel_dp_mst_master_trans_compute(state, intel_dp);
+	return 0;
+}
+
+/*
+ * Iterate over all connectors and return a mask of
+ * all CPU transcoders streaming over the same DP link.
+ */
+static unsigned int
+intel_dp_mst_transcoder_mask(struct intel_atomic_state *state,
+			     struct intel_dp *mst_port)
+{
+	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+	const struct intel_digital_connector_state *conn_state;
+	struct intel_connector *connector;
+	u8 transcoders = 0;
+	int i;
+
+	if (INTEL_GEN(dev_priv) < 12)
+		return 0;
+
+	for_each_new_intel_connector_in_state(state, connector, conn_state, i) {
+		const struct intel_crtc_state *crtc_state;
+		struct intel_crtc *crtc;
+
+		if (connector->mst_port != mst_port || !conn_state->base.crtc)
+			continue;
+
+		crtc = to_intel_crtc(conn_state->base.crtc);
+		crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
+
+		if (!crtc_state->hw.active)
+			continue;
+
+		transcoders |= BIT(crtc_state->cpu_transcoder);
+	}
+
+	return transcoders;
+}
+
+static int intel_dp_mst_compute_config_late(struct intel_encoder *encoder,
+					    struct intel_crtc_state *crtc_state,
+					    struct drm_connector_state *conn_state)
+{
+	struct intel_atomic_state *state = to_intel_atomic_state(conn_state->state);
+	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder);
+	struct intel_dp *intel_dp = &intel_mst->primary->dp;
+
+	/* lowest numbered transcoder will be designated master */
+	crtc_state->mst_master_transcoder =
+		ffs(intel_dp_mst_transcoder_mask(state, intel_dp)) - 1;
 
 	return 0;
 }
@@ -313,7 +316,8 @@ intel_dp_mst_atomic_check(struct drm_connector *connector,
 	return ret;
 }
 
-static void intel_mst_disable_dp(struct intel_encoder *encoder,
+static void intel_mst_disable_dp(struct intel_atomic_state *state,
+				 struct intel_encoder *encoder,
 				 const struct intel_crtc_state *old_crtc_state,
 				 const struct drm_connector_state *old_conn_state)
 {
@@ -322,22 +326,25 @@ static void intel_mst_disable_dp(struct intel_encoder *encoder,
 	struct intel_dp *intel_dp = &intel_dig_port->dp;
 	struct intel_connector *connector =
 		to_intel_connector(old_conn_state->connector);
+	struct drm_i915_private *i915 = to_i915(connector->base.dev);
 	int ret;
 
-	DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links);
+	drm_dbg_kms(&i915->drm, "active links %d\n",
+		    intel_dp->active_mst_links);
 
 	drm_dp_mst_reset_vcpi_slots(&intel_dp->mst_mgr, connector->port);
 
 	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
 	if (ret) {
-		DRM_DEBUG_KMS("failed to update payload %d\n", ret);
+		drm_dbg_kms(&i915->drm, "failed to update payload %d\n", ret);
 	}
 	if (old_crtc_state->has_audio)
 		intel_audio_codec_disable(encoder,
 					  old_crtc_state, old_conn_state);
 }
 
-static void intel_mst_post_disable_dp(struct intel_encoder *encoder,
+static void intel_mst_post_disable_dp(struct intel_atomic_state *state,
+				      struct intel_encoder *encoder,
 				      const struct intel_crtc_state *old_crtc_state,
 				      const struct drm_connector_state *old_conn_state)
 {
@@ -371,7 +378,8 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder,
 
 	if (intel_de_wait_for_set(dev_priv, intel_dp->regs.dp_tp_status,
 				  DP_TP_STATUS_ACT_SENT, 1))
-		DRM_ERROR("Timed out waiting for ACT sent when disabling\n");
+		drm_err(&dev_priv->drm,
+			"Timed out waiting for ACT sent when disabling\n");
 	drm_dp_check_act_status(&intel_dp->mst_mgr);
 
 	drm_dp_mst_deallocate_vcpi(&intel_dp->mst_mgr, connector->port);
@@ -402,13 +410,15 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder,
 
 	intel_mst->connector = NULL;
 	if (last_mst_stream)
-		intel_dig_port->base.post_disable(&intel_dig_port->base,
+		intel_dig_port->base.post_disable(state, &intel_dig_port->base,
 						  old_crtc_state, NULL);
 
-	DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links);
+	drm_dbg_kms(&dev_priv->drm, "active links %d\n",
+		    intel_dp->active_mst_links);
 }
 
-static void intel_mst_pre_pll_enable_dp(struct intel_encoder *encoder,
+static void intel_mst_pre_pll_enable_dp(struct intel_atomic_state *state,
+					struct intel_encoder *encoder,
 					const struct intel_crtc_state *pipe_config,
 					const struct drm_connector_state *conn_state)
 {
@@ -417,11 +427,12 @@ static void intel_mst_pre_pll_enable_dp(struct intel_encoder *encoder,
 	struct intel_dp *intel_dp = &intel_dig_port->dp;
 
 	if (intel_dp->active_mst_links == 0)
-		intel_dig_port->base.pre_pll_enable(&intel_dig_port->base,
+		intel_dig_port->base.pre_pll_enable(state, &intel_dig_port->base,
 						    pipe_config, NULL);
 }
 
-static void intel_mst_pre_enable_dp(struct intel_encoder *encoder,
+static void intel_mst_pre_enable_dp(struct intel_atomic_state *state,
+				    struct intel_encoder *encoder,
 				    const struct intel_crtc_state *pipe_config,
 				    const struct drm_connector_state *conn_state)
 {
@@ -445,7 +456,8 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder,
 		    INTEL_GEN(dev_priv) >= 12 && first_mst_stream &&
 		    !intel_dp_mst_is_master_trans(pipe_config));
 
-	DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links);
+	drm_dbg_kms(&dev_priv->drm, "active links %d\n",
+		    intel_dp->active_mst_links);
 
 	if (first_mst_stream)
 		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
@@ -453,7 +465,7 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder,
 	drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port, true);
 
 	if (first_mst_stream)
-		intel_dig_port->base.pre_enable(&intel_dig_port->base,
+		intel_dig_port->base.pre_enable(state, &intel_dig_port->base,
 						pipe_config, NULL);
 
 	ret = drm_dp_mst_allocate_vcpi(&intel_dp->mst_mgr,
@@ -461,7 +473,7 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder,
 				       pipe_config->pbn,
 				       pipe_config->dp_m_n.tu);
 	if (!ret)
-		DRM_ERROR("failed to allocate vcpi\n");
+		drm_err(&dev_priv->drm, "failed to allocate vcpi\n");
 
 	intel_dp->active_mst_links++;
 	temp = intel_de_read(dev_priv, intel_dp->regs.dp_tp_status);
@@ -484,7 +496,8 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder,
 	intel_dp_set_m_n(pipe_config, M1_N1);
 }
 
-static void intel_mst_enable_dp(struct intel_encoder *encoder,
+static void intel_mst_enable_dp(struct intel_atomic_state *state,
+				struct intel_encoder *encoder,
 				const struct intel_crtc_state *pipe_config,
 				const struct drm_connector_state *conn_state)
 {
@@ -499,11 +512,12 @@ static void intel_mst_enable_dp(struct intel_encoder *encoder,
 
 	intel_crtc_vblank_on(pipe_config);
 
-	DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links);
+	drm_dbg_kms(&dev_priv->drm, "active links %d\n",
+		    intel_dp->active_mst_links);
 
 	if (intel_de_wait_for_set(dev_priv, intel_dp->regs.dp_tp_status,
 				  DP_TP_STATUS_ACT_SENT, 1))
-		DRM_ERROR("Timed out waiting for ACT sent\n");
+		drm_err(&dev_priv->drm, "Timed out waiting for ACT sent\n");
 
 	drm_dp_check_act_status(&intel_dp->mst_mgr);
 
@@ -786,6 +800,7 @@ intel_dp_create_fake_mst_encoder(struct intel_digital_port *intel_dig_port, enum
 	intel_encoder->pipe_mask = ~0;
 
 	intel_encoder->compute_config = intel_dp_mst_compute_config;
+	intel_encoder->compute_config_late = intel_dp_mst_compute_config_late;
 	intel_encoder->disable = intel_mst_disable_dp;
 	intel_encoder->post_disable = intel_mst_post_disable_dp;
 	intel_encoder->pre_pll_enable = intel_mst_pre_pll_enable_dp;
diff --git a/drivers/gpu/drm/i915/display/intel_dsi.c b/drivers/gpu/drm/i915/display/intel_dsi.c
index a2a937109a5a..afa4e6817e8c 100644
--- a/drivers/gpu/drm/i915/display/intel_dsi.c
+++ b/drivers/gpu/drm/i915/display/intel_dsi.c
@@ -31,20 +31,21 @@ int intel_dsi_tlpx_ns(const struct intel_dsi *intel_dsi)
 
 int intel_dsi_get_modes(struct drm_connector *connector)
 {
+	struct drm_i915_private *i915 = to_i915(connector->dev);
 	struct intel_connector *intel_connector = to_intel_connector(connector);
 	struct drm_display_mode *mode;
 
-	DRM_DEBUG_KMS("\n");
+	drm_dbg_kms(&i915->drm, "\n");
 
 	if (!intel_connector->panel.fixed_mode) {
-		DRM_DEBUG_KMS("no fixed mode\n");
+		drm_dbg_kms(&i915->drm, "no fixed mode\n");
 		return 0;
 	}
 
 	mode = drm_mode_duplicate(connector->dev,
 				  intel_connector->panel.fixed_mode);
 	if (!mode) {
-		DRM_DEBUG_KMS("drm_mode_duplicate failed\n");
+		drm_dbg_kms(&i915->drm, "drm_mode_duplicate failed\n");
 		return 0;
 	}
 
@@ -60,7 +61,7 @@ enum drm_mode_status intel_dsi_mode_valid(struct drm_connector *connector,
 	const struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode;
 	int max_dotclk = to_i915(connector->dev)->max_dotclk_freq;
 
-	DRM_DEBUG_KMS("\n");
+	drm_dbg_kms(&dev_priv->drm, "\n");
 
 	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
 		return MODE_NO_DBLESCAN;
diff --git a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
index 574dcfec9577..3c9c05478a03 100644
--- a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
+++ b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
@@ -453,8 +453,7 @@ static inline void i2c_acpi_find_adapter(struct intel_dsi *intel_dsi,
 
 static const u8 *mipi_exec_i2c(struct intel_dsi *intel_dsi, const u8 *data)
 {
-	struct drm_device *drm_dev = intel_dsi->base.base.dev;
-	struct device *dev = &drm_dev->pdev->dev;
+	struct drm_i915_private *i915 = to_i915(intel_dsi->base.base.dev);
 	struct i2c_adapter *adapter;
 	struct i2c_msg msg;
 	int ret;
@@ -471,7 +470,7 @@ static const u8 *mipi_exec_i2c(struct intel_dsi *intel_dsi, const u8 *data)
 
 	adapter = i2c_get_adapter(intel_dsi->i2c_bus_num);
 	if (!adapter) {
-		DRM_DEV_ERROR(dev, "Cannot find a valid i2c bus for xfer\n");
+		drm_err(&i915->drm, "Cannot find a valid i2c bus for xfer\n");
 		goto err_bus;
 	}
 
@@ -489,9 +488,9 @@ static const u8 *mipi_exec_i2c(struct intel_dsi *intel_dsi, const u8 *data)
 
 	ret = i2c_transfer(adapter, &msg, 1);
 	if (ret < 0)
-		DRM_DEV_ERROR(dev,
-			      "Failed to xfer payload of size (%u) to reg (%u)\n",
-			      payload_size, reg_offset);
+		drm_err(&i915->drm,
+			"Failed to xfer payload of size (%u) to reg (%u)\n",
+			payload_size, reg_offset);
 
 	kfree(payload_data);
 err_alloc:
diff --git a/drivers/gpu/drm/i915/display/intel_dvo.c b/drivers/gpu/drm/i915/display/intel_dvo.c
index 341d5ce8b062..5cd09034519b 100644
--- a/drivers/gpu/drm/i915/display/intel_dvo.c
+++ b/drivers/gpu/drm/i915/display/intel_dvo.c
@@ -183,7 +183,8 @@ static void intel_dvo_get_config(struct intel_encoder *encoder,
 	pipe_config->hw.adjusted_mode.crtc_clock = pipe_config->port_clock;
 }
 
-static void intel_disable_dvo(struct intel_encoder *encoder,
+static void intel_disable_dvo(struct intel_atomic_state *state,
+			      struct intel_encoder *encoder,
 			      const struct intel_crtc_state *old_crtc_state,
 			      const struct drm_connector_state *old_conn_state)
 {
@@ -197,7 +198,8 @@ static void intel_disable_dvo(struct intel_encoder *encoder,
 	intel_de_read(dev_priv, dvo_reg);
 }
 
-static void intel_enable_dvo(struct intel_encoder *encoder,
+static void intel_enable_dvo(struct intel_atomic_state *state,
+			     struct intel_encoder *encoder,
 			     const struct intel_crtc_state *pipe_config,
 			     const struct drm_connector_state *conn_state)
 {
@@ -272,7 +274,8 @@ static int intel_dvo_compute_config(struct intel_encoder *encoder,
 	return 0;
 }
 
-static void intel_dvo_pre_enable(struct intel_encoder *encoder,
+static void intel_dvo_pre_enable(struct intel_atomic_state *state,
+				 struct intel_encoder *encoder,
 				 const struct intel_crtc_state *pipe_config,
 				 const struct drm_connector_state *conn_state)
 {
diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c
index 2e5d835a9eaa..56bcd6c52a02 100644
--- a/drivers/gpu/drm/i915/display/intel_fbc.c
+++ b/drivers/gpu/drm/i915/display/intel_fbc.c
@@ -104,7 +104,7 @@ static void i8xx_fbc_deactivate(struct drm_i915_private *dev_priv)
 	/* Wait for compressing bit to clear */
 	if (intel_de_wait_for_clear(dev_priv, FBC_STATUS,
 				    FBC_STAT_COMPRESSING, 10)) {
-		DRM_DEBUG_KMS("FBC idle timed out\n");
+		drm_dbg_kms(&dev_priv->drm, "FBC idle timed out\n");
 		return;
 	}
 }
@@ -485,7 +485,8 @@ static int intel_fbc_alloc_cfb(struct drm_i915_private *dev_priv,
 	if (!ret)
 		goto err_llb;
 	else if (ret > 1) {
-		DRM_INFO("Reducing the compressed framebuffer size. This may lead to less power savings than a non-reduced-size. Try to increase stolen memory size if available in BIOS.\n");
+		drm_info(&dev_priv->drm,
+			 "Reducing the compressed framebuffer size. This may lead to less power savings than a non-reduced-size. Try to increase stolen memory size if available in BIOS.\n");
 
 	}
 
@@ -521,8 +522,9 @@ static int intel_fbc_alloc_cfb(struct drm_i915_private *dev_priv,
 			       dev_priv->dsm.start + compressed_llb->start);
 	}
 
-	DRM_DEBUG_KMS("reserved %llu bytes of contiguous stolen space for FBC, threshold: %d\n",
-		      fbc->compressed_fb.size, fbc->threshold);
+	drm_dbg_kms(&dev_priv->drm,
+		    "reserved %llu bytes of contiguous stolen space for FBC, threshold: %d\n",
+		    fbc->compressed_fb.size, fbc->threshold);
 
 	return 0;
 
@@ -531,7 +533,7 @@ static int intel_fbc_alloc_cfb(struct drm_i915_private *dev_priv,
 	i915_gem_stolen_remove_node(dev_priv, &fbc->compressed_fb);
 err_llb:
 	if (drm_mm_initialized(&dev_priv->mm.stolen))
-		pr_info_once("drm: not enough stolen space for compressed buffer (need %d more bytes), disabling. Hint: you may be able to increase stolen memory size in the BIOS to avoid this.\n", size);
+		drm_info_once(&dev_priv->drm, "not enough stolen space for compressed buffer (need %d more bytes), disabling. Hint: you may be able to increase stolen memory size in the BIOS to avoid this.\n", size);
 	return -ENOSPC;
 }
 
@@ -606,6 +608,19 @@ static bool pixel_format_is_valid(struct drm_i915_private *dev_priv,
 	}
 }
 
+static bool rotation_is_valid(struct drm_i915_private *dev_priv,
+			      u32 pixel_format, unsigned int rotation)
+{
+	if (INTEL_GEN(dev_priv) >= 9 && pixel_format == DRM_FORMAT_RGB565 &&
+	    drm_rotation_90_or_270(rotation))
+		return false;
+	else if (INTEL_GEN(dev_priv) <= 4 && !IS_G4X(dev_priv) &&
+		 rotation != DRM_MODE_ROTATE_0)
+		return false;
+
+	return true;
+}
+
 /*
  * For some reason, the hardware tracking starts looking at whatever we
  * programmed as the display plane base address register. It does not look at
@@ -640,6 +655,22 @@ static bool intel_fbc_hw_tracking_covers_screen(struct intel_crtc *crtc)
 	return effective_w <= max_w && effective_h <= max_h;
 }
 
+static bool tiling_is_valid(struct drm_i915_private *dev_priv,
+			    uint64_t modifier)
+{
+	switch (modifier) {
+	case DRM_FORMAT_MOD_LINEAR:
+		if (INTEL_GEN(dev_priv) >= 9)
+			return true;
+		return false;
+	case I915_FORMAT_MOD_X_TILED:
+	case I915_FORMAT_MOD_Y_TILED:
+		return true;
+	default:
+		return false;
+	}
+}
+
 static void intel_fbc_update_state_cache(struct intel_crtc *crtc,
 					 const struct intel_crtc_state *crtc_state,
 					 const struct intel_plane_state *plane_state)
@@ -673,6 +704,7 @@ static void intel_fbc_update_state_cache(struct intel_crtc *crtc,
 
 	cache->fb.format = fb->format;
 	cache->fb.stride = fb->pitches[0];
+	cache->fb.modifier = fb->modifier;
 
 	drm_WARN_ON(&dev_priv->drm, plane_state->flags & PLANE_HAS_FENCE &&
 		    !plane_state->vma->fence);
@@ -746,29 +778,39 @@ static bool intel_fbc_can_activate(struct intel_crtc *crtc)
 		return false;
 	}
 
-	/* The use of a CPU fence is mandatory in order to detect writes
-	 * by the CPU to the scanout and trigger updates to the FBC.
+	/* The use of a CPU fence is one of two ways to detect writes by the
+	 * CPU to the scanout and trigger updates to the FBC.
+	 *
+	 * The other method is by software tracking (see
+	 * intel_fbc_invalidate/flush()), it will manually notify FBC and nuke
+	 * the current compressed buffer and recompress it.
 	 *
 	 * Note that is possible for a tiled surface to be unmappable (and
-	 * so have no fence associated with it) due to aperture constaints
+	 * so have no fence associated with it) due to aperture constraints
 	 * at the time of pinning.
 	 *
 	 * FIXME with 90/270 degree rotation we should use the fence on
 	 * the normal GTT view (the rotated view doesn't even have a
 	 * fence). Would need changes to the FBC fence Y offset as well.
-	 * For now this will effecively disable FBC with 90/270 degree
+	 * For now this will effectively disable FBC with 90/270 degree
 	 * rotation.
 	 */
-	if (cache->fence_id < 0) {
+	if (INTEL_GEN(dev_priv) < 9 && cache->fence_id < 0) {
 		fbc->no_fbc_reason = "framebuffer not tiled or fenced";
 		return false;
 	}
-	if (INTEL_GEN(dev_priv) <= 4 && !IS_G4X(dev_priv) &&
-	    cache->plane.rotation != DRM_MODE_ROTATE_0) {
+
+	if (!rotation_is_valid(dev_priv, cache->fb.format->format,
+			       cache->plane.rotation)) {
 		fbc->no_fbc_reason = "rotation unsupported";
 		return false;
 	}
 
+	if (!tiling_is_valid(dev_priv, cache->fb.modifier)) {
+		fbc->no_fbc_reason = "tiling unsupported";
+		return false;
+	}
+
 	if (!stride_is_valid(dev_priv, cache->fb.stride)) {
 		fbc->no_fbc_reason = "framebuffer stride not supported";
 		return false;
@@ -948,7 +990,8 @@ static void __intel_fbc_disable(struct drm_i915_private *dev_priv)
 	drm_WARN_ON(&dev_priv->drm, !fbc->crtc);
 	drm_WARN_ON(&dev_priv->drm, fbc->active);
 
-	DRM_DEBUG_KMS("Disabling FBC on pipe %c\n", pipe_name(crtc->pipe));
+	drm_dbg_kms(&dev_priv->drm, "Disabling FBC on pipe %c\n",
+		    pipe_name(crtc->pipe));
 
 	__intel_fbc_cleanup_cfb(dev_priv);
 
@@ -1176,7 +1219,8 @@ void intel_fbc_enable(struct intel_atomic_state *state,
 	else
 		cache->gen9_wa_cfb_stride = 0;
 
-	DRM_DEBUG_KMS("Enabling FBC on pipe %c\n", pipe_name(crtc->pipe));
+	drm_dbg_kms(&dev_priv->drm, "Enabling FBC on pipe %c\n",
+		    pipe_name(crtc->pipe));
 	fbc->no_fbc_reason = "FBC enabled but not active yet\n";
 
 	fbc->crtc = crtc;
@@ -1238,7 +1282,7 @@ static void intel_fbc_underrun_work_fn(struct work_struct *work)
 	if (fbc->underrun_detected || !fbc->crtc)
 		goto out;
 
-	DRM_DEBUG_KMS("Disabling FBC due to FIFO underrun.\n");
+	drm_dbg_kms(&dev_priv->drm, "Disabling FBC due to FIFO underrun.\n");
 	fbc->underrun_detected = true;
 
 	intel_fbc_deactivate(dev_priv, "FIFO underrun");
@@ -1264,7 +1308,8 @@ int intel_fbc_reset_underrun(struct drm_i915_private *dev_priv)
 		return ret;
 
 	if (dev_priv->fbc.underrun_detected) {
-		DRM_DEBUG_KMS("Re-allowing FBC after fifo underrun\n");
+		drm_dbg_kms(&dev_priv->drm,
+			    "Re-allowing FBC after fifo underrun\n");
 		dev_priv->fbc.no_fbc_reason = "FIFO underrun cleared";
 	}
 
@@ -1335,7 +1380,8 @@ static bool need_fbc_vtd_wa(struct drm_i915_private *dev_priv)
 	/* WaFbcTurnOffFbcWhenHyperVisorIsUsed:skl,bxt */
 	if (intel_vtd_active() &&
 	    (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv))) {
-		DRM_INFO("Disabling framebuffer compression (FBC) to prevent screen flicker with VT-d enabled\n");
+		drm_info(&dev_priv->drm,
+			 "Disabling framebuffer compression (FBC) to prevent screen flicker with VT-d enabled\n");
 		return true;
 	}
 
@@ -1363,8 +1409,8 @@ void intel_fbc_init(struct drm_i915_private *dev_priv)
 		mkwrite_device_info(dev_priv)->display.has_fbc = false;
 
 	i915_modparams.enable_fbc = intel_sanitize_fbc_option(dev_priv);
-	DRM_DEBUG_KMS("Sanitized enable_fbc value: %d\n",
-		      i915_modparams.enable_fbc);
+	drm_dbg_kms(&dev_priv->drm, "Sanitized enable_fbc value: %d\n",
+		    i915_modparams.enable_fbc);
 
 	if (!HAS_FBC(dev_priv)) {
 		fbc->no_fbc_reason = "unsupported by this chipset";
diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c
index 3bc804212a99..bd39eb6a21b8 100644
--- a/drivers/gpu/drm/i915/display/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/display/intel_fbdev.c
@@ -146,7 +146,7 @@ static int intelfb_alloc(struct drm_fb_helper *helper,
 	if (IS_ERR(obj))
 		obj = i915_gem_object_create_shmem(dev_priv, size);
 	if (IS_ERR(obj)) {
-		DRM_ERROR("failed to allocate framebuffer\n");
+		drm_err(&dev_priv->drm, "failed to allocate framebuffer\n");
 		return PTR_ERR(obj);
 	}
 
@@ -183,21 +183,23 @@ static int intelfb_create(struct drm_fb_helper *helper,
 	if (intel_fb &&
 	    (sizes->fb_width > intel_fb->base.width ||
 	     sizes->fb_height > intel_fb->base.height)) {
-		DRM_DEBUG_KMS("BIOS fb too small (%dx%d), we require (%dx%d),"
-			      " releasing it\n",
-			      intel_fb->base.width, intel_fb->base.height,
-			      sizes->fb_width, sizes->fb_height);
+		drm_dbg_kms(&dev_priv->drm,
+			    "BIOS fb too small (%dx%d), we require (%dx%d),"
+			    " releasing it\n",
+			    intel_fb->base.width, intel_fb->base.height,
+			    sizes->fb_width, sizes->fb_height);
 		drm_framebuffer_put(&intel_fb->base);
 		intel_fb = ifbdev->fb = NULL;
 	}
 	if (!intel_fb || drm_WARN_ON(dev, !intel_fb_obj(&intel_fb->base))) {
-		DRM_DEBUG_KMS("no BIOS fb, allocating a new one\n");
+		drm_dbg_kms(&dev_priv->drm,
+			    "no BIOS fb, allocating a new one\n");
 		ret = intelfb_alloc(helper, sizes);
 		if (ret)
 			return ret;
 		intel_fb = ifbdev->fb;
 	} else {
-		DRM_DEBUG_KMS("re-using BIOS fb\n");
+		drm_dbg_kms(&dev_priv->drm, "re-using BIOS fb\n");
 		prealloc = true;
 		sizes->fb_width = intel_fb->base.width;
 		sizes->fb_height = intel_fb->base.height;
@@ -220,7 +222,7 @@ static int intelfb_create(struct drm_fb_helper *helper,
 
 	info = drm_fb_helper_alloc_fbi(helper);
 	if (IS_ERR(info)) {
-		DRM_ERROR("Failed to allocate fb_info\n");
+		drm_err(&dev_priv->drm, "Failed to allocate fb_info\n");
 		ret = PTR_ERR(info);
 		goto out_unpin;
 	}
@@ -240,7 +242,8 @@ static int intelfb_create(struct drm_fb_helper *helper,
 
 	vaddr = i915_vma_pin_iomap(vma);
 	if (IS_ERR(vaddr)) {
-		DRM_ERROR("Failed to remap framebuffer into virtual memory\n");
+		drm_err(&dev_priv->drm,
+			"Failed to remap framebuffer into virtual memory\n");
 		ret = PTR_ERR(vaddr);
 		goto out_unpin;
 	}
@@ -258,9 +261,9 @@ static int intelfb_create(struct drm_fb_helper *helper,
 
 	/* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
 
-	DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08x\n",
-		      ifbdev->fb->base.width, ifbdev->fb->base.height,
-		      i915_ggtt_offset(vma));
+	drm_dbg_kms(&dev_priv->drm, "allocated %dx%d fb: 0x%08x\n",
+		    ifbdev->fb->base.width, ifbdev->fb->base.height,
+		    i915_ggtt_offset(vma));
 	ifbdev->vma = vma;
 	ifbdev->vma_flags = flags;
 
@@ -309,6 +312,7 @@ static void intel_fbdev_destroy(struct intel_fbdev *ifbdev)
 static bool intel_fbdev_init_bios(struct drm_device *dev,
 				 struct intel_fbdev *ifbdev)
 {
+	struct drm_i915_private *i915 = to_i915(dev);
 	struct intel_framebuffer *fb = NULL;
 	struct drm_crtc *crtc;
 	struct intel_crtc *intel_crtc;
@@ -321,21 +325,24 @@ static bool intel_fbdev_init_bios(struct drm_device *dev,
 		intel_crtc = to_intel_crtc(crtc);
 
 		if (!crtc->state->active || !obj) {
-			DRM_DEBUG_KMS("pipe %c not active or no fb, skipping\n",
-				      pipe_name(intel_crtc->pipe));
+			drm_dbg_kms(&i915->drm,
+				    "pipe %c not active or no fb, skipping\n",
+				    pipe_name(intel_crtc->pipe));
 			continue;
 		}
 
 		if (obj->base.size > max_size) {
-			DRM_DEBUG_KMS("found possible fb from plane %c\n",
-				      pipe_name(intel_crtc->pipe));
+			drm_dbg_kms(&i915->drm,
+				    "found possible fb from plane %c\n",
+				    pipe_name(intel_crtc->pipe));
 			fb = to_intel_framebuffer(crtc->primary->state->fb);
 			max_size = obj->base.size;
 		}
 	}
 
 	if (!fb) {
-		DRM_DEBUG_KMS("no active fbs found, not using BIOS config\n");
+		drm_dbg_kms(&i915->drm,
+			    "no active fbs found, not using BIOS config\n");
 		goto out;
 	}
 
@@ -346,13 +353,14 @@ static bool intel_fbdev_init_bios(struct drm_device *dev,
 		intel_crtc = to_intel_crtc(crtc);
 
 		if (!crtc->state->active) {
-			DRM_DEBUG_KMS("pipe %c not active, skipping\n",
-				      pipe_name(intel_crtc->pipe));
+			drm_dbg_kms(&i915->drm,
+				    "pipe %c not active, skipping\n",
+				    pipe_name(intel_crtc->pipe));
 			continue;
 		}
 
-		DRM_DEBUG_KMS("checking plane %c for BIOS fb\n",
-			      pipe_name(intel_crtc->pipe));
+		drm_dbg_kms(&i915->drm, "checking plane %c for BIOS fb\n",
+			    pipe_name(intel_crtc->pipe));
 
 		/*
 		 * See if the plane fb we found above will fit on this
@@ -362,9 +370,10 @@ static bool intel_fbdev_init_bios(struct drm_device *dev,
 		cur_size = crtc->state->adjusted_mode.crtc_hdisplay;
 		cur_size = cur_size * fb->base.format->cpp[0];
 		if (fb->base.pitches[0] < cur_size) {
-			DRM_DEBUG_KMS("fb not wide enough for plane %c (%d vs %d)\n",
-				      pipe_name(intel_crtc->pipe),
-				      cur_size, fb->base.pitches[0]);
+			drm_dbg_kms(&i915->drm,
+				    "fb not wide enough for plane %c (%d vs %d)\n",
+				    pipe_name(intel_crtc->pipe),
+				    cur_size, fb->base.pitches[0]);
 			fb = NULL;
 			break;
 		}
@@ -372,28 +381,32 @@ static bool intel_fbdev_init_bios(struct drm_device *dev,
 		cur_size = crtc->state->adjusted_mode.crtc_vdisplay;
 		cur_size = intel_fb_align_height(&fb->base, 0, cur_size);
 		cur_size *= fb->base.pitches[0];
-		DRM_DEBUG_KMS("pipe %c area: %dx%d, bpp: %d, size: %d\n",
-			      pipe_name(intel_crtc->pipe),
-			      crtc->state->adjusted_mode.crtc_hdisplay,
-			      crtc->state->adjusted_mode.crtc_vdisplay,
-			      fb->base.format->cpp[0] * 8,
-			      cur_size);
+		drm_dbg_kms(&i915->drm,
+			    "pipe %c area: %dx%d, bpp: %d, size: %d\n",
+			    pipe_name(intel_crtc->pipe),
+			    crtc->state->adjusted_mode.crtc_hdisplay,
+			    crtc->state->adjusted_mode.crtc_vdisplay,
+			    fb->base.format->cpp[0] * 8,
+			    cur_size);
 
 		if (cur_size > max_size) {
-			DRM_DEBUG_KMS("fb not big enough for plane %c (%d vs %d)\n",
-				      pipe_name(intel_crtc->pipe),
-				      cur_size, max_size);
+			drm_dbg_kms(&i915->drm,
+				    "fb not big enough for plane %c (%d vs %d)\n",
+				    pipe_name(intel_crtc->pipe),
+				    cur_size, max_size);
 			fb = NULL;
 			break;
 		}
 
-		DRM_DEBUG_KMS("fb big enough for plane %c (%d >= %d)\n",
-			      pipe_name(intel_crtc->pipe),
-			      max_size, cur_size);
+		drm_dbg_kms(&i915->drm,
+			    "fb big enough for plane %c (%d >= %d)\n",
+			    pipe_name(intel_crtc->pipe),
+			    max_size, cur_size);
 	}
 
 	if (!fb) {
-		DRM_DEBUG_KMS("BIOS fb not suitable for all pipes, not using\n");
+		drm_dbg_kms(&i915->drm,
+			    "BIOS fb not suitable for all pipes, not using\n");
 		goto out;
 	}
 
@@ -415,7 +428,7 @@ static bool intel_fbdev_init_bios(struct drm_device *dev,
 	}
 
 
-	DRM_DEBUG_KMS("using BIOS fb for initial console\n");
+	drm_dbg_kms(&i915->drm, "using BIOS fb for initial console\n");
 	return true;
 
 out:
@@ -522,8 +535,9 @@ void intel_fbdev_fini(struct drm_i915_private *dev_priv)
  * processing, fbdev will perform a full connector reprobe if a hotplug event
  * was received while HPD was suspended.
  */
-static void intel_fbdev_hpd_set_suspend(struct intel_fbdev *ifbdev, int state)
+static void intel_fbdev_hpd_set_suspend(struct drm_i915_private *i915, int state)
 {
+	struct intel_fbdev *ifbdev = i915->fbdev;
 	bool send_hpd = false;
 
 	mutex_lock(&ifbdev->hpd_lock);
@@ -533,7 +547,7 @@ static void intel_fbdev_hpd_set_suspend(struct intel_fbdev *ifbdev, int state)
 	mutex_unlock(&ifbdev->hpd_lock);
 
 	if (send_hpd) {
-		DRM_DEBUG_KMS("Handling delayed fbcon HPD event\n");
+		drm_dbg_kms(&i915->drm, "Handling delayed fbcon HPD event\n");
 		drm_fb_helper_hotplug_event(&ifbdev->helper);
 	}
 }
@@ -588,7 +602,7 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous
 	drm_fb_helper_set_suspend(&ifbdev->helper, state);
 	console_unlock();
 
-	intel_fbdev_hpd_set_suspend(ifbdev, state);
+	intel_fbdev_hpd_set_suspend(dev_priv, state);
 }
 
 void intel_fbdev_output_poll_changed(struct drm_device *dev)
diff --git a/drivers/gpu/drm/i915/display/intel_global_state.c b/drivers/gpu/drm/i915/display/intel_global_state.c
index a0cc894c3868..6f72feb14f3e 100644
--- a/drivers/gpu/drm/i915/display/intel_global_state.c
+++ b/drivers/gpu/drm/i915/display/intel_global_state.c
@@ -71,6 +71,7 @@ struct intel_global_state *
 intel_atomic_get_global_obj_state(struct intel_atomic_state *state,
 				  struct intel_global_obj *obj)
 {
+	struct drm_i915_private *i915 = to_i915(state->base.dev);
 	int index, num_objs, i;
 	size_t size;
 	struct __intel_global_objs_state *arr;
@@ -106,8 +107,8 @@ intel_atomic_get_global_obj_state(struct intel_atomic_state *state,
 
 	state->num_global_objs = num_objs;
 
-	DRM_DEBUG_ATOMIC("Added new global object %p state %p to %p\n",
-			 obj, obj_state, state);
+	drm_dbg_atomic(&i915->drm, "Added new global object %p state %p to %p\n",
+		       obj, obj_state, state);
 
 	return obj_state;
 }
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
index ee0f27ea2810..d3ad10653b2e 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -1391,6 +1391,7 @@ static
 int hdcp2_propagate_stream_management_info(struct intel_connector *connector)
 {
 	struct intel_digital_port *intel_dig_port = intel_attached_dig_port(connector);
+	struct drm_i915_private *i915 = to_i915(connector->base.dev);
 	struct intel_hdcp *hdcp = &connector->hdcp;
 	union {
 		struct hdcp2_rep_stream_manage stream_manage;
@@ -1431,7 +1432,7 @@ int hdcp2_propagate_stream_management_info(struct intel_connector *connector)
 	hdcp->seq_num_m++;
 
 	if (hdcp->seq_num_m > HDCP_2_2_SEQ_NUM_MAX) {
-		DRM_DEBUG_KMS("seq_num_m roll over.\n");
+		drm_dbg_kms(&i915->drm, "seq_num_m roll over.\n");
 		return -1;
 	}
 
@@ -2075,7 +2076,8 @@ int intel_hdcp_disable(struct intel_connector *connector)
 	return ret;
 }
 
-void intel_hdcp_update_pipe(struct intel_encoder *encoder,
+void intel_hdcp_update_pipe(struct intel_atomic_state *state,
+			    struct intel_encoder *encoder,
 			    const struct intel_crtc_state *crtc_state,
 			    const struct drm_connector_state *conn_state)
 {
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.h b/drivers/gpu/drm/i915/display/intel_hdcp.h
index 7c12ad609b1f..86bbaec120cc 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.h
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.h
@@ -11,6 +11,7 @@
 struct drm_connector;
 struct drm_connector_state;
 struct drm_i915_private;
+struct intel_atomic_state;
 struct intel_connector;
 struct intel_crtc_state;
 struct intel_encoder;
@@ -26,7 +27,8 @@ int intel_hdcp_init(struct intel_connector *connector,
 int intel_hdcp_enable(struct intel_connector *connector,
 		      enum transcoder cpu_transcoder, u8 content_type);
 int intel_hdcp_disable(struct intel_connector *connector);
-void intel_hdcp_update_pipe(struct intel_encoder *encoder,
+void intel_hdcp_update_pipe(struct intel_atomic_state *state,
+			    struct intel_encoder *encoder,
 			    const struct intel_crtc_state *crtc_state,
 			    const struct drm_connector_state *conn_state);
 bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port);
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index 39930232b253..6b1bc955124c 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -707,13 +707,15 @@ void intel_read_infoframe(struct intel_encoder *encoder,
 	/* see comment above for the reason for this offset */
 	ret = hdmi_infoframe_unpack(frame, buffer + 1, sizeof(buffer) - 1);
 	if (ret) {
-		DRM_DEBUG_KMS("Failed to unpack infoframe type 0x%02x\n", type);
+		drm_dbg_kms(encoder->base.dev,
+			    "Failed to unpack infoframe type 0x%02x\n", type);
 		return;
 	}
 
 	if (frame->any.type != type)
-		DRM_DEBUG_KMS("Found the wrong infoframe type 0x%x (expected 0x%02x)\n",
-			      frame->any.type, type);
+		drm_dbg_kms(encoder->base.dev,
+			    "Found the wrong infoframe type 0x%x (expected 0x%02x)\n",
+			    frame->any.type, type);
 }
 
 static bool
@@ -853,7 +855,8 @@ intel_hdmi_compute_drm_infoframe(struct intel_encoder *encoder,
 
 	ret = drm_hdmi_infoframe_set_hdr_metadata(frame, conn_state);
 	if (ret < 0) {
-		DRM_DEBUG_KMS("couldn't set HDR metadata in infoframe\n");
+		drm_dbg_kms(&dev_priv->drm,
+			    "couldn't set HDR metadata in infoframe\n");
 		return false;
 	}
 
@@ -893,8 +896,9 @@ static void g4x_set_infoframes(struct intel_encoder *encoder,
 		if (!(val & VIDEO_DIP_ENABLE))
 			return;
 		if (port != (val & VIDEO_DIP_PORT_MASK)) {
-			DRM_DEBUG_KMS("video DIP still enabled on port %c\n",
-				      (val & VIDEO_DIP_PORT_MASK) >> 29);
+			drm_dbg_kms(&dev_priv->drm,
+				    "video DIP still enabled on port %c\n",
+				    (val & VIDEO_DIP_PORT_MASK) >> 29);
 			return;
 		}
 		val &= ~(VIDEO_DIP_ENABLE | VIDEO_DIP_ENABLE_AVI |
@@ -906,8 +910,9 @@ static void g4x_set_infoframes(struct intel_encoder *encoder,
 
 	if (port != (val & VIDEO_DIP_PORT_MASK)) {
 		if (val & VIDEO_DIP_ENABLE) {
-			DRM_DEBUG_KMS("video DIP already enabled on port %c\n",
-				      (val & VIDEO_DIP_PORT_MASK) >> 29);
+			drm_dbg_kms(&dev_priv->drm,
+				    "video DIP already enabled on port %c\n",
+				    (val & VIDEO_DIP_PORT_MASK) >> 29);
 			return;
 		}
 		val &= ~VIDEO_DIP_PORT_MASK;
@@ -1264,8 +1269,8 @@ void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable)
 	if (hdmi->dp_dual_mode.type < DRM_DP_DUAL_MODE_TYPE2_DVI)
 		return;
 
-	DRM_DEBUG_KMS("%s DP dual mode adaptor TMDS output\n",
-		      enable ? "Enabling" : "Disabling");
+	drm_dbg_kms(&dev_priv->drm, "%s DP dual mode adaptor TMDS output\n",
+		    enable ? "Enabling" : "Disabling");
 
 	drm_dp_dual_mode_set_tmds_output(hdmi->dp_dual_mode.type,
 					 adapter, enable);
@@ -1346,13 +1351,14 @@ int intel_hdmi_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port,
 	ret = intel_hdmi_hdcp_write(intel_dig_port, DRM_HDCP_DDC_AN, an,
 				    DRM_HDCP_AN_LEN);
 	if (ret) {
-		DRM_DEBUG_KMS("Write An over DDC failed (%d)\n", ret);
+		drm_dbg_kms(&i915->drm, "Write An over DDC failed (%d)\n",
+			    ret);
 		return ret;
 	}
 
 	ret = intel_gmbus_output_aksv(adapter);
 	if (ret < 0) {
-		DRM_DEBUG_KMS("Failed to output aksv (%d)\n", ret);
+		drm_dbg_kms(&i915->drm, "Failed to output aksv (%d)\n", ret);
 		return ret;
 	}
 	return 0;
@@ -1361,11 +1367,14 @@ int intel_hdmi_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port,
 static int intel_hdmi_hdcp_read_bksv(struct intel_digital_port *intel_dig_port,
 				     u8 *bksv)
 {
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
+
 	int ret;
 	ret = intel_hdmi_hdcp_read(intel_dig_port, DRM_HDCP_DDC_BKSV, bksv,
 				   DRM_HDCP_KSV_LEN);
 	if (ret)
-		DRM_DEBUG_KMS("Read Bksv over DDC failed (%d)\n", ret);
+		drm_dbg_kms(&i915->drm, "Read Bksv over DDC failed (%d)\n",
+			    ret);
 	return ret;
 }
 
@@ -1373,11 +1382,14 @@ static
 int intel_hdmi_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
 				 u8 *bstatus)
 {
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
+
 	int ret;
 	ret = intel_hdmi_hdcp_read(intel_dig_port, DRM_HDCP_DDC_BSTATUS,
 				   bstatus, DRM_HDCP_BSTATUS_LEN);
 	if (ret)
-		DRM_DEBUG_KMS("Read bstatus over DDC failed (%d)\n", ret);
+		drm_dbg_kms(&i915->drm, "Read bstatus over DDC failed (%d)\n",
+			    ret);
 	return ret;
 }
 
@@ -1385,12 +1397,14 @@ static
 int intel_hdmi_hdcp_repeater_present(struct intel_digital_port *intel_dig_port,
 				     bool *repeater_present)
 {
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
 	int ret;
 	u8 val;
 
 	ret = intel_hdmi_hdcp_read(intel_dig_port, DRM_HDCP_DDC_BCAPS, &val, 1);
 	if (ret) {
-		DRM_DEBUG_KMS("Read bcaps over DDC failed (%d)\n", ret);
+		drm_dbg_kms(&i915->drm, "Read bcaps over DDC failed (%d)\n",
+			    ret);
 		return ret;
 	}
 	*repeater_present = val & DRM_HDCP_DDC_BCAPS_REPEATER_PRESENT;
@@ -1401,11 +1415,14 @@ static
 int intel_hdmi_hdcp_read_ri_prime(struct intel_digital_port *intel_dig_port,
 				  u8 *ri_prime)
 {
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
+
 	int ret;
 	ret = intel_hdmi_hdcp_read(intel_dig_port, DRM_HDCP_DDC_RI_PRIME,
 				   ri_prime, DRM_HDCP_RI_LEN);
 	if (ret)
-		DRM_DEBUG_KMS("Read Ri' over DDC failed (%d)\n", ret);
+		drm_dbg_kms(&i915->drm, "Read Ri' over DDC failed (%d)\n",
+			    ret);
 	return ret;
 }
 
@@ -1413,12 +1430,14 @@ static
 int intel_hdmi_hdcp_read_ksv_ready(struct intel_digital_port *intel_dig_port,
 				   bool *ksv_ready)
 {
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
 	int ret;
 	u8 val;
 
 	ret = intel_hdmi_hdcp_read(intel_dig_port, DRM_HDCP_DDC_BCAPS, &val, 1);
 	if (ret) {
-		DRM_DEBUG_KMS("Read bcaps over DDC failed (%d)\n", ret);
+		drm_dbg_kms(&i915->drm, "Read bcaps over DDC failed (%d)\n",
+			    ret);
 		return ret;
 	}
 	*ksv_ready = val & DRM_HDCP_DDC_BCAPS_KSV_FIFO_READY;
@@ -1429,11 +1448,13 @@ static
 int intel_hdmi_hdcp_read_ksv_fifo(struct intel_digital_port *intel_dig_port,
 				  int num_downstream, u8 *ksv_fifo)
 {
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
 	int ret;
 	ret = intel_hdmi_hdcp_read(intel_dig_port, DRM_HDCP_DDC_KSV_FIFO,
 				   ksv_fifo, num_downstream * DRM_HDCP_KSV_LEN);
 	if (ret) {
-		DRM_DEBUG_KMS("Read ksv fifo over DDC failed (%d)\n", ret);
+		drm_dbg_kms(&i915->drm,
+			    "Read ksv fifo over DDC failed (%d)\n", ret);
 		return ret;
 	}
 	return 0;
@@ -1443,6 +1464,7 @@ static
 int intel_hdmi_hdcp_read_v_prime_part(struct intel_digital_port *intel_dig_port,
 				      int i, u32 *part)
 {
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
 	int ret;
 
 	if (i >= DRM_HDCP_V_PRIME_NUM_PARTS)
@@ -1451,7 +1473,8 @@ int intel_hdmi_hdcp_read_v_prime_part(struct intel_digital_port *intel_dig_port,
 	ret = intel_hdmi_hdcp_read(intel_dig_port, DRM_HDCP_DDC_V_PRIME(i),
 				   part, DRM_HDCP_V_PRIME_PART_LEN);
 	if (ret)
-		DRM_DEBUG_KMS("Read V'[%d] over DDC failed (%d)\n", i, ret);
+		drm_dbg_kms(&i915->drm, "Read V'[%d] over DDC failed (%d)\n",
+			    i, ret);
 	return ret;
 }
 
@@ -1474,12 +1497,14 @@ static int kbl_repositioning_enc_en_signal(struct intel_connector *connector)
 
 	ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base, false);
 	if (ret) {
-		DRM_ERROR("Disable HDCP signalling failed (%d)\n", ret);
+		drm_err(&dev_priv->drm,
+			"Disable HDCP signalling failed (%d)\n", ret);
 		return ret;
 	}
 	ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base, true);
 	if (ret) {
-		DRM_ERROR("Enable HDCP signalling failed (%d)\n", ret);
+		drm_err(&dev_priv->drm,
+			"Enable HDCP signalling failed (%d)\n", ret);
 		return ret;
 	}
 
@@ -1500,8 +1525,8 @@ int intel_hdmi_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
 
 	ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base, enable);
 	if (ret) {
-		DRM_ERROR("%s HDCP signalling failed (%d)\n",
-			  enable ? "Enable" : "Disable", ret);
+		drm_err(&dev_priv->drm, "%s HDCP signalling failed (%d)\n",
+			enable ? "Enable" : "Disable", ret);
 		return ret;
 	}
 
@@ -1536,10 +1561,13 @@ bool intel_hdmi_hdcp_check_link(struct intel_digital_port *intel_dig_port)
 	intel_de_write(i915, HDCP_RPRIME(i915, cpu_transcoder, port), ri.reg);
 
 	/* Wait for Ri prime match */
-	if (wait_for(intel_de_read(i915, HDCP_STATUS(i915, cpu_transcoder, port)) &
+	if (wait_for((intel_de_read(i915, HDCP_STATUS(i915, cpu_transcoder, port)) &
+		      (HDCP_STATUS_RI_MATCH | HDCP_STATUS_ENC)) ==
 		     (HDCP_STATUS_RI_MATCH | HDCP_STATUS_ENC), 1)) {
-		DRM_ERROR("Ri' mismatch detected, link check failed (%x)\n",
-			  intel_de_read(i915, HDCP_STATUS(i915, cpu_transcoder, port)));
+		drm_err(&i915->drm,
+			"Ri' mismatch detected, link check failed (%x)\n",
+			intel_de_read(i915, HDCP_STATUS(i915, cpu_transcoder,
+							port)));
 		return false;
 	}
 	return true;
@@ -1588,16 +1616,18 @@ static int get_hdcp2_msg_timeout(u8 msg_id, bool is_paired)
 }
 
 static inline
-int hdcp2_detect_msg_availability(struct intel_digital_port *intel_digital_port,
+int hdcp2_detect_msg_availability(struct intel_digital_port *intel_dig_port,
 				  u8 msg_id, bool *msg_ready,
 				  ssize_t *msg_sz)
 {
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
 	u8 rx_status[HDCP_2_2_HDMI_RXSTATUS_LEN];
 	int ret;
 
-	ret = intel_hdmi_hdcp2_read_rx_status(intel_digital_port, rx_status);
+	ret = intel_hdmi_hdcp2_read_rx_status(intel_dig_port, rx_status);
 	if (ret < 0) {
-		DRM_DEBUG_KMS("rx_status read failed. Err %d\n", ret);
+		drm_dbg_kms(&i915->drm, "rx_status read failed. Err %d\n",
+			    ret);
 		return ret;
 	}
 
@@ -1617,6 +1647,7 @@ static ssize_t
 intel_hdmi_hdcp2_wait_for_msg(struct intel_digital_port *intel_dig_port,
 			      u8 msg_id, bool paired)
 {
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
 	bool msg_ready = false;
 	int timeout, ret;
 	ssize_t msg_sz = 0;
@@ -1631,8 +1662,8 @@ intel_hdmi_hdcp2_wait_for_msg(struct intel_digital_port *intel_dig_port,
 			 !ret && msg_ready && msg_sz, timeout * 1000,
 			 1000, 5 * 1000);
 	if (ret)
-		DRM_DEBUG_KMS("msg_id: %d, ret: %d, timeout: %d\n",
-			      msg_id, ret, timeout);
+		drm_dbg_kms(&i915->drm, "msg_id: %d, ret: %d, timeout: %d\n",
+			    msg_id, ret, timeout);
 
 	return ret ? ret : msg_sz;
 }
@@ -1651,6 +1682,7 @@ static
 int intel_hdmi_hdcp2_read_msg(struct intel_digital_port *intel_dig_port,
 			      u8 msg_id, void *buf, size_t size)
 {
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
 	struct intel_hdmi *hdmi = &intel_dig_port->hdmi;
 	struct intel_hdcp *hdcp = &hdmi->attached_connector->hdcp;
 	unsigned int offset;
@@ -1666,15 +1698,17 @@ int intel_hdmi_hdcp2_read_msg(struct intel_digital_port *intel_dig_port,
 	 * available buffer.
 	 */
 	if (ret > size) {
-		DRM_DEBUG_KMS("msg_sz(%zd) is more than exp size(%zu)\n",
-			      ret, size);
+		drm_dbg_kms(&i915->drm,
+			    "msg_sz(%zd) is more than exp size(%zu)\n",
+			    ret, size);
 		return -1;
 	}
 
 	offset = HDCP_2_2_HDMI_REG_RD_MSG_OFFSET;
 	ret = intel_hdmi_hdcp_read(intel_dig_port, offset, buf, ret);
 	if (ret)
-		DRM_DEBUG_KMS("Failed to read msg_id: %d(%zd)\n", msg_id, ret);
+		drm_dbg_kms(&i915->drm, "Failed to read msg_id: %d(%zd)\n",
+			    msg_id, ret);
 
 	return ret;
 }
@@ -1870,15 +1904,17 @@ static void intel_enable_hdmi_audio(struct intel_encoder *encoder,
 				    const struct intel_crtc_state *pipe_config,
 				    const struct drm_connector_state *conn_state)
 {
+	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
 	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
 
-	drm_WARN_ON(encoder->base.dev, !pipe_config->has_hdmi_sink);
-	DRM_DEBUG_DRIVER("Enabling HDMI audio on pipe %c\n",
-			 pipe_name(crtc->pipe));
+	drm_WARN_ON(&i915->drm, !pipe_config->has_hdmi_sink);
+	drm_dbg_kms(&i915->drm, "Enabling HDMI audio on pipe %c\n",
+		    pipe_name(crtc->pipe));
 	intel_audio_codec_enable(encoder, pipe_config, conn_state);
 }
 
-static void g4x_enable_hdmi(struct intel_encoder *encoder,
+static void g4x_enable_hdmi(struct intel_atomic_state *state,
+			    struct intel_encoder *encoder,
 			    const struct intel_crtc_state *pipe_config,
 			    const struct drm_connector_state *conn_state)
 {
@@ -1900,7 +1936,8 @@ static void g4x_enable_hdmi(struct intel_encoder *encoder,
 		intel_enable_hdmi_audio(encoder, pipe_config, conn_state);
 }
 
-static void ibx_enable_hdmi(struct intel_encoder *encoder,
+static void ibx_enable_hdmi(struct intel_atomic_state *state,
+			    struct intel_encoder *encoder,
 			    const struct intel_crtc_state *pipe_config,
 			    const struct drm_connector_state *conn_state)
 {
@@ -1951,7 +1988,8 @@ static void ibx_enable_hdmi(struct intel_encoder *encoder,
 		intel_enable_hdmi_audio(encoder, pipe_config, conn_state);
 }
 
-static void cpt_enable_hdmi(struct intel_encoder *encoder,
+static void cpt_enable_hdmi(struct intel_atomic_state *state,
+			    struct intel_encoder *encoder,
 			    const struct intel_crtc_state *pipe_config,
 			    const struct drm_connector_state *conn_state)
 {
@@ -2004,13 +2042,15 @@ static void cpt_enable_hdmi(struct intel_encoder *encoder,
 		intel_enable_hdmi_audio(encoder, pipe_config, conn_state);
 }
 
-static void vlv_enable_hdmi(struct intel_encoder *encoder,
+static void vlv_enable_hdmi(struct intel_atomic_state *state,
+			    struct intel_encoder *encoder,
 			    const struct intel_crtc_state *pipe_config,
 			    const struct drm_connector_state *conn_state)
 {
 }
 
-static void intel_disable_hdmi(struct intel_encoder *encoder,
+static void intel_disable_hdmi(struct intel_atomic_state *state,
+			       struct intel_encoder *encoder,
 			       const struct intel_crtc_state *old_crtc_state,
 			       const struct drm_connector_state *old_conn_state)
 {
@@ -2068,7 +2108,8 @@ static void intel_disable_hdmi(struct intel_encoder *encoder,
 	intel_dp_dual_mode_set_tmds_output(intel_hdmi, false);
 }
 
-static void g4x_disable_hdmi(struct intel_encoder *encoder,
+static void g4x_disable_hdmi(struct intel_atomic_state *state,
+			     struct intel_encoder *encoder,
 			     const struct intel_crtc_state *old_crtc_state,
 			     const struct drm_connector_state *old_conn_state)
 {
@@ -2076,10 +2117,11 @@ static void g4x_disable_hdmi(struct intel_encoder *encoder,
 		intel_audio_codec_disable(encoder,
 					  old_crtc_state, old_conn_state);
 
-	intel_disable_hdmi(encoder, old_crtc_state, old_conn_state);
+	intel_disable_hdmi(state, encoder, old_crtc_state, old_conn_state);
 }
 
-static void pch_disable_hdmi(struct intel_encoder *encoder,
+static void pch_disable_hdmi(struct intel_atomic_state *state,
+			     struct intel_encoder *encoder,
 			     const struct intel_crtc_state *old_crtc_state,
 			     const struct drm_connector_state *old_conn_state)
 {
@@ -2088,11 +2130,12 @@ static void pch_disable_hdmi(struct intel_encoder *encoder,
 					  old_crtc_state, old_conn_state);
 }
 
-static void pch_post_disable_hdmi(struct intel_encoder *encoder,
+static void pch_post_disable_hdmi(struct intel_atomic_state *state,
+				  struct intel_encoder *encoder,
 				  const struct intel_crtc_state *old_crtc_state,
 				  const struct drm_connector_state *old_conn_state)
 {
-	intel_disable_hdmi(encoder, old_crtc_state, old_conn_state);
+	intel_disable_hdmi(state, encoder, old_crtc_state, old_conn_state);
 }
 
 static int intel_hdmi_source_max_tmds_clock(struct intel_encoder *encoder)
@@ -2289,10 +2332,12 @@ static bool
 intel_hdmi_ycbcr420_config(struct drm_connector *connector,
 			   struct intel_crtc_state *config)
 {
+	struct drm_i915_private *i915 = to_i915(connector->dev);
 	struct intel_crtc *intel_crtc = to_intel_crtc(config->uapi.crtc);
 
 	if (!connector->ycbcr_420_allowed) {
-		DRM_ERROR("Platform doesn't support YCBCR420 output\n");
+		drm_err(&i915->drm,
+			"Platform doesn't support YCBCR420 output\n");
 		return false;
 	}
 
@@ -2300,7 +2345,8 @@ intel_hdmi_ycbcr420_config(struct drm_connector *connector,
 
 	/* YCBCR 420 output conversion needs a scaler */
 	if (skl_update_scaler_crtc(config)) {
-		DRM_DEBUG_KMS("Scaler allocation for output failed\n");
+		drm_dbg_kms(&i915->drm,
+			    "Scaler allocation for output failed\n");
 		return false;
 	}
 
@@ -2341,6 +2387,7 @@ static int intel_hdmi_compute_bpc(struct intel_encoder *encoder,
 static int intel_hdmi_compute_clock(struct intel_encoder *encoder,
 				    struct intel_crtc_state *crtc_state)
 {
+	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
 	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
 	const struct drm_display_mode *adjusted_mode =
 		&crtc_state->hw.adjusted_mode;
@@ -2365,13 +2412,15 @@ static int intel_hdmi_compute_clock(struct intel_encoder *encoder,
 	if (crtc_state->pipe_bpp > bpc * 3)
 		crtc_state->pipe_bpp = bpc * 3;
 
-	DRM_DEBUG_KMS("picking %d bpc for HDMI output (pipe bpp: %d)\n",
-		      bpc, crtc_state->pipe_bpp);
+	drm_dbg_kms(&i915->drm,
+		    "picking %d bpc for HDMI output (pipe bpp: %d)\n",
+		    bpc, crtc_state->pipe_bpp);
 
 	if (hdmi_port_clock_valid(intel_hdmi, crtc_state->port_clock,
 				  false, crtc_state->has_hdmi_sink) != MODE_OK) {
-		DRM_DEBUG_KMS("unsupported HDMI clock (%d kHz), rejecting mode\n",
-			      crtc_state->port_clock);
+		drm_dbg_kms(&i915->drm,
+			    "unsupported HDMI clock (%d kHz), rejecting mode\n",
+			    crtc_state->port_clock);
 		return -EINVAL;
 	}
 
@@ -2434,7 +2483,8 @@ int intel_hdmi_compute_config(struct intel_encoder *encoder,
 
 	if (drm_mode_is_420_only(&connector->display_info, adjusted_mode)) {
 		if (!intel_hdmi_ycbcr420_config(connector, pipe_config)) {
-			DRM_ERROR("Can't support YCBCR420 output\n");
+			drm_err(&dev_priv->drm,
+				"Can't support YCBCR420 output\n");
 			return -EINVAL;
 		}
 	}
@@ -2474,25 +2524,26 @@ int intel_hdmi_compute_config(struct intel_encoder *encoder,
 		}
 	}
 
-	intel_hdmi_compute_gcp_infoframe(encoder, pipe_config, conn_state);
+	intel_hdmi_compute_gcp_infoframe(encoder, pipe_config,
+					 conn_state);
 
 	if (!intel_hdmi_compute_avi_infoframe(encoder, pipe_config, conn_state)) {
-		DRM_DEBUG_KMS("bad AVI infoframe\n");
+		drm_dbg_kms(&dev_priv->drm, "bad AVI infoframe\n");
 		return -EINVAL;
 	}
 
 	if (!intel_hdmi_compute_spd_infoframe(encoder, pipe_config, conn_state)) {
-		DRM_DEBUG_KMS("bad SPD infoframe\n");
+		drm_dbg_kms(&dev_priv->drm, "bad SPD infoframe\n");
 		return -EINVAL;
 	}
 
 	if (!intel_hdmi_compute_hdmi_infoframe(encoder, pipe_config, conn_state)) {
-		DRM_DEBUG_KMS("bad HDMI infoframe\n");
+		drm_dbg_kms(&dev_priv->drm, "bad HDMI infoframe\n");
 		return -EINVAL;
 	}
 
 	if (!intel_hdmi_compute_drm_infoframe(encoder, pipe_config, conn_state)) {
-		DRM_DEBUG_KMS("bad DRM infoframe\n");
+		drm_dbg_kms(&dev_priv->drm, "bad DRM infoframe\n");
 		return -EINVAL;
 	}
 
@@ -2542,7 +2593,8 @@ intel_hdmi_dp_dual_mode_detect(struct drm_connector *connector, bool has_edid)
 		 */
 		if (has_edid && !connector->override_edid &&
 		    intel_bios_is_port_dp_dual_mode(dev_priv, port)) {
-			DRM_DEBUG_KMS("Assuming DP dual mode adaptor presence based on VBT\n");
+			drm_dbg_kms(&dev_priv->drm,
+				    "Assuming DP dual mode adaptor presence based on VBT\n");
 			type = DRM_DP_DUAL_MODE_TYPE1_DVI;
 		} else {
 			type = DRM_DP_DUAL_MODE_NONE;
@@ -2556,9 +2608,10 @@ intel_hdmi_dp_dual_mode_detect(struct drm_connector *connector, bool has_edid)
 	hdmi->dp_dual_mode.max_tmds_clock =
 		drm_dp_dual_mode_max_tmds_clock(type, adapter);
 
-	DRM_DEBUG_KMS("DP dual mode adaptor (%s) detected (max TMDS clock: %d kHz)\n",
-		      drm_dp_get_dual_mode_type_name(type),
-		      hdmi->dp_dual_mode.max_tmds_clock);
+	drm_dbg_kms(&dev_priv->drm,
+		    "DP dual mode adaptor (%s) detected (max TMDS clock: %d kHz)\n",
+		    drm_dp_get_dual_mode_type_name(type),
+		    hdmi->dp_dual_mode.max_tmds_clock);
 }
 
 static bool
@@ -2578,7 +2631,8 @@ intel_hdmi_set_edid(struct drm_connector *connector)
 	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");
+		drm_dbg_kms(&dev_priv->drm,
+			    "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);
@@ -2610,8 +2664,8 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
 	struct intel_encoder *encoder = &hdmi_to_dig_port(intel_hdmi)->base;
 	intel_wakeref_t wakeref;
 
-	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
-		      connector->base.id, connector->name);
+	drm_dbg_kms(&dev_priv->drm, "[CONNECTOR:%d:%s]\n",
+		    connector->base.id, connector->name);
 
 	wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
 
@@ -2642,8 +2696,10 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
 static void
 intel_hdmi_force(struct drm_connector *connector)
 {
-	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
-		      connector->base.id, connector->name);
+	struct drm_i915_private *i915 = to_i915(connector->dev);
+
+	drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s]\n",
+		    connector->base.id, connector->name);
 
 	intel_hdmi_unset_edid(connector);
 
@@ -2664,7 +2720,8 @@ static int intel_hdmi_get_modes(struct drm_connector *connector)
 	return intel_connector_update_modes(connector, edid);
 }
 
-static void intel_hdmi_pre_enable(struct intel_encoder *encoder,
+static void intel_hdmi_pre_enable(struct intel_atomic_state *state,
+				  struct intel_encoder *encoder,
 				  const struct intel_crtc_state *pipe_config,
 				  const struct drm_connector_state *conn_state)
 {
@@ -2678,7 +2735,8 @@ static void intel_hdmi_pre_enable(struct intel_encoder *encoder,
 				       pipe_config, conn_state);
 }
 
-static void vlv_hdmi_pre_enable(struct intel_encoder *encoder,
+static void vlv_hdmi_pre_enable(struct intel_atomic_state *state,
+				struct intel_encoder *encoder,
 				const struct intel_crtc_state *pipe_config,
 				const struct drm_connector_state *conn_state)
 {
@@ -2695,12 +2753,13 @@ static void vlv_hdmi_pre_enable(struct intel_encoder *encoder,
 			      pipe_config->has_infoframe,
 			      pipe_config, conn_state);
 
-	g4x_enable_hdmi(encoder, pipe_config, conn_state);
+	g4x_enable_hdmi(state, encoder, pipe_config, conn_state);
 
 	vlv_wait_port_ready(dev_priv, dport, 0x0);
 }
 
-static void vlv_hdmi_pre_pll_enable(struct intel_encoder *encoder,
+static void vlv_hdmi_pre_pll_enable(struct intel_atomic_state *state,
+				    struct intel_encoder *encoder,
 				    const struct intel_crtc_state *pipe_config,
 				    const struct drm_connector_state *conn_state)
 {
@@ -2709,7 +2768,8 @@ static void vlv_hdmi_pre_pll_enable(struct intel_encoder *encoder,
 	vlv_phy_pre_pll_enable(encoder, pipe_config);
 }
 
-static void chv_hdmi_pre_pll_enable(struct intel_encoder *encoder,
+static void chv_hdmi_pre_pll_enable(struct intel_atomic_state *state,
+				    struct intel_encoder *encoder,
 				    const struct intel_crtc_state *pipe_config,
 				    const struct drm_connector_state *conn_state)
 {
@@ -2718,14 +2778,16 @@ static void chv_hdmi_pre_pll_enable(struct intel_encoder *encoder,
 	chv_phy_pre_pll_enable(encoder, pipe_config);
 }
 
-static void chv_hdmi_post_pll_disable(struct intel_encoder *encoder,
+static void chv_hdmi_post_pll_disable(struct intel_atomic_state *state,
+				      struct intel_encoder *encoder,
 				      const struct intel_crtc_state *old_crtc_state,
 				      const struct drm_connector_state *old_conn_state)
 {
 	chv_phy_post_pll_disable(encoder, old_crtc_state);
 }
 
-static void vlv_hdmi_post_disable(struct intel_encoder *encoder,
+static void vlv_hdmi_post_disable(struct intel_atomic_state *state,
+				  struct intel_encoder *encoder,
 				  const struct intel_crtc_state *old_crtc_state,
 				  const struct drm_connector_state *old_conn_state)
 {
@@ -2733,7 +2795,8 @@ static void vlv_hdmi_post_disable(struct intel_encoder *encoder,
 	vlv_phy_reset_lanes(encoder, old_crtc_state);
 }
 
-static void chv_hdmi_post_disable(struct intel_encoder *encoder,
+static void chv_hdmi_post_disable(struct intel_atomic_state *state,
+				  struct intel_encoder *encoder,
 				  const struct intel_crtc_state *old_crtc_state,
 				  const struct drm_connector_state *old_conn_state)
 {
@@ -2748,7 +2811,8 @@ static void chv_hdmi_post_disable(struct intel_encoder *encoder,
 	vlv_dpio_put(dev_priv);
 }
 
-static void chv_hdmi_pre_enable(struct intel_encoder *encoder,
+static void chv_hdmi_pre_enable(struct intel_atomic_state *state,
+				struct intel_encoder *encoder,
 				const struct intel_crtc_state *pipe_config,
 				const struct drm_connector_state *conn_state)
 {
@@ -2766,7 +2830,7 @@ static void chv_hdmi_pre_enable(struct intel_encoder *encoder,
 			      pipe_config->has_infoframe,
 			      pipe_config, conn_state);
 
-	g4x_enable_hdmi(encoder, pipe_config, conn_state);
+	g4x_enable_hdmi(state, encoder, pipe_config, conn_state);
 
 	vlv_wait_port_ready(dev_priv, dport, 0x0);
 
@@ -2785,6 +2849,7 @@ intel_hdmi_get_i2c_adapter(struct drm_connector *connector)
 
 static void intel_hdmi_create_i2c_symlink(struct drm_connector *connector)
 {
+	struct drm_i915_private *i915 = to_i915(connector->dev);
 	struct i2c_adapter *adapter = intel_hdmi_get_i2c_adapter(connector);
 	struct kobject *i2c_kobj = &adapter->dev.kobj;
 	struct kobject *connector_kobj = &connector->kdev->kobj;
@@ -2792,7 +2857,7 @@ static void intel_hdmi_create_i2c_symlink(struct drm_connector *connector)
 
 	ret = sysfs_create_link(connector_kobj, i2c_kobj, i2c_kobj->name);
 	if (ret)
-		DRM_ERROR("Failed to create i2c symlink (%d)\n", ret);
+		drm_err(&i915->drm, "Failed to create i2c symlink (%d)\n", ret);
 }
 
 static void intel_hdmi_remove_i2c_symlink(struct drm_connector *connector)
@@ -2921,9 +2986,10 @@ bool intel_hdmi_handle_sink_scrambling(struct intel_encoder *encoder,
 	if (!sink_scrambling->supported)
 		return true;
 
-	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] scrambling=%s, TMDS bit clock ratio=1/%d\n",
-		      connector->base.id, connector->name,
-		      yesno(scrambling), high_tmds_clock_ratio ? 40 : 10);
+	drm_dbg_kms(&dev_priv->drm,
+		    "[CONNECTOR:%d:%s] scrambling=%s, TMDS bit clock ratio=1/%d\n",
+		    connector->base.id, connector->name,
+		    yesno(scrambling), high_tmds_clock_ratio ? 40 : 10);
 
 	/* Set TMDS bit clock ratio to 1/40 or 1/10, and enable/disable scrambling */
 	return drm_scdc_set_high_tmds_clock_ratio(adapter,
@@ -3065,8 +3131,9 @@ static u8 intel_hdmi_ddc_pin(struct intel_encoder *encoder)
 
 	ddc_pin = intel_bios_alternate_ddc_pin(encoder);
 	if (ddc_pin) {
-		DRM_DEBUG_KMS("Using DDC pin 0x%x for port %c (VBT)\n",
-			      ddc_pin, port_name(port));
+		drm_dbg_kms(&dev_priv->drm,
+			    "Using DDC pin 0x%x for port %c (VBT)\n",
+			    ddc_pin, port_name(port));
 		return ddc_pin;
 	}
 
@@ -3083,8 +3150,9 @@ static u8 intel_hdmi_ddc_pin(struct intel_encoder *encoder)
 	else
 		ddc_pin = g4x_port_to_ddc_pin(dev_priv, port);
 
-	DRM_DEBUG_KMS("Using DDC pin 0x%x for port %c (platform default)\n",
-		      ddc_pin, port_name(port));
+	drm_dbg_kms(&dev_priv->drm,
+		    "Using DDC pin 0x%x for port %c (platform default)\n",
+		    ddc_pin, port_name(port));
 
 	return ddc_pin;
 }
@@ -3141,8 +3209,9 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
 	enum port port = intel_encoder->port;
 	struct cec_connector_info conn_info;
 
-	DRM_DEBUG_KMS("Adding HDMI connector on [ENCODER:%d:%s]\n",
-		      intel_encoder->base.base.id, intel_encoder->base.name);
+	drm_dbg_kms(&dev_priv->drm,
+		    "Adding HDMI connector on [ENCODER:%d:%s]\n",
+		    intel_encoder->base.base.id, intel_encoder->base.name);
 
 	if (INTEL_GEN(dev_priv) < 12 && drm_WARN_ON(dev, port == PORT_A))
 		return;
@@ -3186,7 +3255,8 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
 		int ret = intel_hdcp_init(intel_connector,
 					  &intel_hdmi_hdcp_shim);
 		if (ret)
-			DRM_DEBUG_KMS("HDCP init failed, skipping.\n");
+			drm_dbg_kms(&dev_priv->drm,
+				    "HDCP init failed, skipping.\n");
 	}
 
 	/* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written
@@ -3205,16 +3275,16 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
 		cec_notifier_conn_register(dev->dev, port_identifier(port),
 					   &conn_info);
 	if (!intel_hdmi->cec_notifier)
-		DRM_DEBUG_KMS("CEC notifier get failed\n");
+		drm_dbg_kms(&dev_priv->drm, "CEC notifier get failed\n");
 }
 
 static enum intel_hotplug_state
 intel_hdmi_hotplug(struct intel_encoder *encoder,
-		   struct intel_connector *connector, bool irq_received)
+		   struct intel_connector *connector)
 {
 	enum intel_hotplug_state state;
 
-	state = intel_encoder_hotplug(encoder, connector, irq_received);
+	state = intel_encoder_hotplug(encoder, connector);
 
 	/*
 	 * On many platforms the HDMI live state signal is known to be
@@ -3228,7 +3298,7 @@ intel_hdmi_hotplug(struct intel_encoder *encoder,
 	 * time around we didn't detect any change in the sink's connection
 	 * status.
 	 */
-	if (state == INTEL_HOTPLUG_UNCHANGED && irq_received)
+	if (state == INTEL_HOTPLUG_UNCHANGED && !connector->hotplug_retries)
 		state = INTEL_HOTPLUG_RETRY;
 
 	return state;
diff --git a/drivers/gpu/drm/i915/display/intel_hotplug.c b/drivers/gpu/drm/i915/display/intel_hotplug.c
index a091442efba4..4f6f560e093e 100644
--- a/drivers/gpu/drm/i915/display/intel_hotplug.c
+++ b/drivers/gpu/drm/i915/display/intel_hotplug.c
@@ -270,8 +270,7 @@ static void intel_hpd_irq_storm_reenable_work(struct work_struct *work)
 
 enum intel_hotplug_state
 intel_encoder_hotplug(struct intel_encoder *encoder,
-		      struct intel_connector *connector,
-		      bool irq_received)
+		      struct intel_connector *connector)
 {
 	struct drm_device *dev = connector->base.dev;
 	enum drm_connector_status old_status;
@@ -392,12 +391,17 @@ static void i915_hotplug_work_func(struct work_struct *work)
 			struct intel_encoder *encoder =
 				intel_attached_encoder(connector);
 
+			if (hpd_event_bits & hpd_bit)
+				connector->hotplug_retries = 0;
+			else
+				connector->hotplug_retries++;
+
 			drm_dbg_kms(&dev_priv->drm,
-				    "Connector %s (pin %i) received hotplug event.\n",
-				    connector->base.name, pin);
+				    "Connector %s (pin %i) received hotplug event. (retry %d)\n",
+				    connector->base.name, pin,
+				    connector->hotplug_retries);
 
-			switch (encoder->hotplug(encoder, connector,
-						 hpd_event_bits & hpd_bit)) {
+			switch (encoder->hotplug(encoder, connector)) {
 			case INTEL_HOTPLUG_UNCHANGED:
 				break;
 			case INTEL_HOTPLUG_CHANGED:
diff --git a/drivers/gpu/drm/i915/display/intel_hotplug.h b/drivers/gpu/drm/i915/display/intel_hotplug.h
index 1e6b4fda2900..777b0743257e 100644
--- a/drivers/gpu/drm/i915/display/intel_hotplug.h
+++ b/drivers/gpu/drm/i915/display/intel_hotplug.h
@@ -15,8 +15,7 @@ enum port;
 
 void intel_hpd_poll_init(struct drm_i915_private *dev_priv);
 enum intel_hotplug_state intel_encoder_hotplug(struct intel_encoder *encoder,
-					       struct intel_connector *connector,
-					       bool irq_received);
+					       struct intel_connector *connector);
 void intel_hpd_irq_handler(struct drm_i915_private *dev_priv,
 			   u32 pin_mask, u32 long_mask);
 void intel_hpd_init(struct drm_i915_private *dev_priv);
diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c
index 9a067effcfa0..fe591f82163e 100644
--- a/drivers/gpu/drm/i915/display/intel_lvds.c
+++ b/drivers/gpu/drm/i915/display/intel_lvds.c
@@ -220,7 +220,8 @@ static void intel_lvds_pps_init_hw(struct drm_i915_private *dev_priv,
 		       REG_FIELD_PREP(PP_REFERENCE_DIVIDER_MASK, pps->divider) | REG_FIELD_PREP(PANEL_POWER_CYCLE_DELAY_MASK, DIV_ROUND_UP(pps->t4, 1000) + 1));
 }
 
-static void intel_pre_enable_lvds(struct intel_encoder *encoder,
+static void intel_pre_enable_lvds(struct intel_atomic_state *state,
+				  struct intel_encoder *encoder,
 				  const struct intel_crtc_state *pipe_config,
 				  const struct drm_connector_state *conn_state)
 {
@@ -301,7 +302,8 @@ static void intel_pre_enable_lvds(struct intel_encoder *encoder,
 /*
  * Sets the power state for the panel.
  */
-static void intel_enable_lvds(struct intel_encoder *encoder,
+static void intel_enable_lvds(struct intel_atomic_state *state,
+			      struct intel_encoder *encoder,
 			      const struct intel_crtc_state *pipe_config,
 			      const struct drm_connector_state *conn_state)
 {
@@ -323,7 +325,8 @@ static void intel_enable_lvds(struct intel_encoder *encoder,
 	intel_panel_enable_backlight(pipe_config, conn_state);
 }
 
-static void intel_disable_lvds(struct intel_encoder *encoder,
+static void intel_disable_lvds(struct intel_atomic_state *state,
+			       struct intel_encoder *encoder,
 			       const struct intel_crtc_state *old_crtc_state,
 			       const struct drm_connector_state *old_conn_state)
 {
@@ -341,28 +344,31 @@ static void intel_disable_lvds(struct intel_encoder *encoder,
 	intel_de_posting_read(dev_priv, lvds_encoder->reg);
 }
 
-static void gmch_disable_lvds(struct intel_encoder *encoder,
+static void gmch_disable_lvds(struct intel_atomic_state *state,
+			      struct intel_encoder *encoder,
 			      const struct intel_crtc_state *old_crtc_state,
 			      const struct drm_connector_state *old_conn_state)
 
 {
 	intel_panel_disable_backlight(old_conn_state);
 
-	intel_disable_lvds(encoder, old_crtc_state, old_conn_state);
+	intel_disable_lvds(state, encoder, old_crtc_state, old_conn_state);
 }
 
-static void pch_disable_lvds(struct intel_encoder *encoder,
+static void pch_disable_lvds(struct intel_atomic_state *state,
+			     struct intel_encoder *encoder,
 			     const struct intel_crtc_state *old_crtc_state,
 			     const struct drm_connector_state *old_conn_state)
 {
 	intel_panel_disable_backlight(old_conn_state);
 }
 
-static void pch_post_disable_lvds(struct intel_encoder *encoder,
+static void pch_post_disable_lvds(struct intel_atomic_state *state,
+				  struct intel_encoder *encoder,
 				  const struct intel_crtc_state *old_crtc_state,
 				  const struct drm_connector_state *old_conn_state)
 {
-	intel_disable_lvds(encoder, old_crtc_state, old_conn_state);
+	intel_disable_lvds(state, encoder, old_crtc_state, old_conn_state);
 }
 
 static enum drm_mode_status
diff --git a/drivers/gpu/drm/i915/display/intel_overlay.c b/drivers/gpu/drm/i915/display/intel_overlay.c
index 481187223101..6e1d66323223 100644
--- a/drivers/gpu/drm/i915/display/intel_overlay.c
+++ b/drivers/gpu/drm/i915/display/intel_overlay.c
@@ -1342,7 +1342,7 @@ void intel_overlay_setup(struct drm_i915_private *dev_priv)
 	if (!HAS_OVERLAY(dev_priv))
 		return;
 
-	engine = dev_priv->engine[RCS0];
+	engine = dev_priv->gt.engine[RCS0];
 	if (!engine || !engine->kernel_context)
 		return;
 
diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_panel.c
index 276f43870802..08bfecfbe681 100644
--- a/drivers/gpu/drm/i915/display/intel_panel.c
+++ b/drivers/gpu/drm/i915/display/intel_panel.c
@@ -684,9 +684,10 @@ static void
 intel_panel_actually_set_backlight(const struct drm_connector_state *conn_state, u32 level)
 {
 	struct intel_connector *connector = to_intel_connector(conn_state->connector);
+	struct drm_i915_private *i915 = to_i915(connector->base.dev);
 	struct intel_panel *panel = &connector->panel;
 
-	DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level);
+	drm_dbg_kms(&i915->drm, "set backlight PWM = %d\n", level);
 
 	level = intel_panel_compute_brightness(connector, level);
 	panel->backlight.set(conn_state, level);
@@ -867,8 +868,8 @@ void intel_panel_disable_backlight(const struct drm_connector_state *old_conn_st
 	 * another client is not activated.
 	 */
 	if (dev_priv->drm.switch_power_state == DRM_SWITCH_POWER_CHANGING) {
-		drm_dbg(&dev_priv->drm,
-			"Skipping backlight disable on vga switch\n");
+		drm_dbg_kms(&dev_priv->drm,
+			    "Skipping backlight disable on vga switch\n");
 		return;
 	}
 
@@ -1244,7 +1245,7 @@ static u32 intel_panel_get_backlight(struct intel_connector *connector)
 
 	mutex_unlock(&dev_priv->backlight_lock);
 
-	drm_dbg(&dev_priv->drm, "get backlight PWM = %d\n", val);
+	drm_dbg_kms(&dev_priv->drm, "get backlight PWM = %d\n", val);
 	return val;
 }
 
@@ -1335,6 +1336,7 @@ static const struct backlight_ops intel_backlight_device_ops = {
 
 int intel_backlight_device_register(struct intel_connector *connector)
 {
+	struct drm_i915_private *i915 = to_i915(connector->base.dev);
 	struct intel_panel *panel = &connector->panel;
 	struct backlight_properties props;
 
@@ -1374,14 +1376,15 @@ int intel_backlight_device_register(struct intel_connector *connector)
 					  &intel_backlight_device_ops, &props);
 
 	if (IS_ERR(panel->backlight.device)) {
-		DRM_ERROR("Failed to register backlight: %ld\n",
-			  PTR_ERR(panel->backlight.device));
+		drm_err(&i915->drm, "Failed to register backlight: %ld\n",
+			PTR_ERR(panel->backlight.device));
 		panel->backlight.device = NULL;
 		return -ENODEV;
 	}
 
-	DRM_DEBUG_KMS("Connector %s backlight sysfs interface registered\n",
-		      connector->base.name);
+	drm_dbg_kms(&i915->drm,
+		    "Connector %s backlight sysfs interface registered\n",
+		    connector->base.name);
 
 	return 0;
 }
@@ -1931,7 +1934,8 @@ static int pwm_setup_backlight(struct intel_connector *connector,
 	return 0;
 }
 
-void intel_panel_update_backlight(struct intel_encoder *encoder,
+void intel_panel_update_backlight(struct intel_atomic_state *state,
+				  struct intel_encoder *encoder,
 				  const struct intel_crtc_state *crtc_state,
 				  const struct drm_connector_state *conn_state)
 {
diff --git a/drivers/gpu/drm/i915/display/intel_panel.h b/drivers/gpu/drm/i915/display/intel_panel.h
index cedeea443336..11f2f6b628d8 100644
--- a/drivers/gpu/drm/i915/display/intel_panel.h
+++ b/drivers/gpu/drm/i915/display/intel_panel.h
@@ -37,7 +37,8 @@ int intel_panel_setup_backlight(struct drm_connector *connector,
 				enum pipe pipe);
 void intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state,
 				  const struct drm_connector_state *conn_state);
-void intel_panel_update_backlight(struct intel_encoder *encoder,
+void intel_panel_update_backlight(struct intel_atomic_state *state,
+				  struct intel_encoder *encoder,
 				  const struct intel_crtc_state *crtc_state,
 				  const struct drm_connector_state *conn_state);
 void intel_panel_disable_backlight(const struct drm_connector_state *old_conn_state);
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index fd9b146e3aba..a0569fdfeb16 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -137,41 +137,42 @@ static void psr_irq_control(struct drm_i915_private *dev_priv)
 	intel_de_write(dev_priv, imr_reg, val);
 }
 
-static void psr_event_print(u32 val, bool psr2_enabled)
+static void psr_event_print(struct drm_i915_private *i915,
+			    u32 val, bool psr2_enabled)
 {
-	DRM_DEBUG_KMS("PSR exit events: 0x%x\n", val);
+	drm_dbg_kms(&i915->drm, "PSR exit events: 0x%x\n", val);
 	if (val & PSR_EVENT_PSR2_WD_TIMER_EXPIRE)
-		DRM_DEBUG_KMS("\tPSR2 watchdog timer expired\n");
+		drm_dbg_kms(&i915->drm, "\tPSR2 watchdog timer expired\n");
 	if ((val & PSR_EVENT_PSR2_DISABLED) && psr2_enabled)
-		DRM_DEBUG_KMS("\tPSR2 disabled\n");
+		drm_dbg_kms(&i915->drm, "\tPSR2 disabled\n");
 	if (val & PSR_EVENT_SU_DIRTY_FIFO_UNDERRUN)
-		DRM_DEBUG_KMS("\tSU dirty FIFO underrun\n");
+		drm_dbg_kms(&i915->drm, "\tSU dirty FIFO underrun\n");
 	if (val & PSR_EVENT_SU_CRC_FIFO_UNDERRUN)
-		DRM_DEBUG_KMS("\tSU CRC FIFO underrun\n");
+		drm_dbg_kms(&i915->drm, "\tSU CRC FIFO underrun\n");
 	if (val & PSR_EVENT_GRAPHICS_RESET)
-		DRM_DEBUG_KMS("\tGraphics reset\n");
+		drm_dbg_kms(&i915->drm, "\tGraphics reset\n");
 	if (val & PSR_EVENT_PCH_INTERRUPT)
-		DRM_DEBUG_KMS("\tPCH interrupt\n");
+		drm_dbg_kms(&i915->drm, "\tPCH interrupt\n");
 	if (val & PSR_EVENT_MEMORY_UP)
-		DRM_DEBUG_KMS("\tMemory up\n");
+		drm_dbg_kms(&i915->drm, "\tMemory up\n");
 	if (val & PSR_EVENT_FRONT_BUFFER_MODIFY)
-		DRM_DEBUG_KMS("\tFront buffer modification\n");
+		drm_dbg_kms(&i915->drm, "\tFront buffer modification\n");
 	if (val & PSR_EVENT_WD_TIMER_EXPIRE)
-		DRM_DEBUG_KMS("\tPSR watchdog timer expired\n");
+		drm_dbg_kms(&i915->drm, "\tPSR watchdog timer expired\n");
 	if (val & PSR_EVENT_PIPE_REGISTERS_UPDATE)
-		DRM_DEBUG_KMS("\tPIPE registers updated\n");
+		drm_dbg_kms(&i915->drm, "\tPIPE registers updated\n");
 	if (val & PSR_EVENT_REGISTER_UPDATE)
-		DRM_DEBUG_KMS("\tRegister updated\n");
+		drm_dbg_kms(&i915->drm, "\tRegister updated\n");
 	if (val & PSR_EVENT_HDCP_ENABLE)
-		DRM_DEBUG_KMS("\tHDCP enabled\n");
+		drm_dbg_kms(&i915->drm, "\tHDCP enabled\n");
 	if (val & PSR_EVENT_KVMR_SESSION_ENABLE)
-		DRM_DEBUG_KMS("\tKVMR session enabled\n");
+		drm_dbg_kms(&i915->drm, "\tKVMR session enabled\n");
 	if (val & PSR_EVENT_VBI_ENABLE)
-		DRM_DEBUG_KMS("\tVBI enabled\n");
+		drm_dbg_kms(&i915->drm, "\tVBI enabled\n");
 	if (val & PSR_EVENT_LPSP_MODE_EXIT)
-		DRM_DEBUG_KMS("\tLPSP mode exited\n");
+		drm_dbg_kms(&i915->drm, "\tLPSP mode exited\n");
 	if ((val & PSR_EVENT_PSR_DISABLE) && !psr2_enabled)
-		DRM_DEBUG_KMS("\tPSR disabled\n");
+		drm_dbg_kms(&i915->drm, "\tPSR disabled\n");
 }
 
 void intel_psr_irq_handler(struct drm_i915_private *dev_priv, u32 psr_iir)
@@ -209,7 +210,7 @@ void intel_psr_irq_handler(struct drm_i915_private *dev_priv, u32 psr_iir)
 
 			intel_de_write(dev_priv, PSR_EVENT(cpu_transcoder),
 				       val);
-			psr_event_print(val, psr2_enabled);
+			psr_event_print(dev_priv, val, psr2_enabled);
 		}
 	}
 
@@ -249,18 +250,21 @@ static bool intel_dp_get_alpm_status(struct intel_dp *intel_dp)
 
 static u8 intel_dp_get_sink_sync_latency(struct intel_dp *intel_dp)
 {
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	u8 val = 8; /* assume the worst if we can't read the value */
 
 	if (drm_dp_dpcd_readb(&intel_dp->aux,
 			      DP_SYNCHRONIZATION_LATENCY_IN_SINK, &val) == 1)
 		val &= DP_MAX_RESYNC_FRAME_COUNT_MASK;
 	else
-		DRM_DEBUG_KMS("Unable to get sink synchronization latency, assuming 8 frames\n");
+		drm_dbg_kms(&i915->drm,
+			    "Unable to get sink synchronization latency, assuming 8 frames\n");
 	return val;
 }
 
 static u16 intel_dp_get_su_x_granulartiy(struct intel_dp *intel_dp)
 {
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	u16 val;
 	ssize_t r;
 
@@ -273,7 +277,8 @@ static u16 intel_dp_get_su_x_granulartiy(struct intel_dp *intel_dp)
 
 	r = drm_dp_dpcd_read(&intel_dp->aux, DP_PSR2_SU_X_GRANULARITY, &val, 2);
 	if (r != 2)
-		DRM_DEBUG_KMS("Unable to read DP_PSR2_SU_X_GRANULARITY\n");
+		drm_dbg_kms(&i915->drm,
+			    "Unable to read DP_PSR2_SU_X_GRANULARITY\n");
 
 	/*
 	 * Spec says that if the value read is 0 the default granularity should
diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c b/drivers/gpu/drm/i915/display/intel_sdvo.c
index 637d8fe2f8c2..bc6c26818e15 100644
--- a/drivers/gpu/drm/i915/display/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/display/intel_sdvo.c
@@ -1430,7 +1430,8 @@ static void intel_sdvo_update_props(struct intel_sdvo *intel_sdvo,
 #undef UPDATE_PROPERTY
 }
 
-static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder,
+static void intel_sdvo_pre_enable(struct intel_atomic_state *state,
+				  struct intel_encoder *intel_encoder,
 				  const struct intel_crtc_state *crtc_state,
 				  const struct drm_connector_state *conn_state)
 {
@@ -1727,7 +1728,8 @@ static void intel_sdvo_enable_audio(struct intel_sdvo *intel_sdvo,
 				   SDVO_AUDIO_PRESENCE_DETECT);
 }
 
-static void intel_disable_sdvo(struct intel_encoder *encoder,
+static void intel_disable_sdvo(struct intel_atomic_state *state,
+			       struct intel_encoder *encoder,
 			       const struct intel_crtc_state *old_crtc_state,
 			       const struct drm_connector_state *conn_state)
 {
@@ -1775,20 +1777,23 @@ static void intel_disable_sdvo(struct intel_encoder *encoder,
 	}
 }
 
-static void pch_disable_sdvo(struct intel_encoder *encoder,
+static void pch_disable_sdvo(struct intel_atomic_state *state,
+			     struct intel_encoder *encoder,
 			     const struct intel_crtc_state *old_crtc_state,
 			     const struct drm_connector_state *old_conn_state)
 {
 }
 
-static void pch_post_disable_sdvo(struct intel_encoder *encoder,
+static void pch_post_disable_sdvo(struct intel_atomic_state *state,
+				  struct intel_encoder *encoder,
 				  const struct intel_crtc_state *old_crtc_state,
 				  const struct drm_connector_state *old_conn_state)
 {
-	intel_disable_sdvo(encoder, old_crtc_state, old_conn_state);
+	intel_disable_sdvo(state, encoder, old_crtc_state, old_conn_state);
 }
 
-static void intel_enable_sdvo(struct intel_encoder *encoder,
+static void intel_enable_sdvo(struct intel_atomic_state *state,
+			      struct intel_encoder *encoder,
 			      const struct intel_crtc_state *pipe_config,
 			      const struct drm_connector_state *conn_state)
 {
@@ -1934,12 +1939,11 @@ static void intel_sdvo_enable_hotplug(struct intel_encoder *encoder)
 
 static enum intel_hotplug_state
 intel_sdvo_hotplug(struct intel_encoder *encoder,
-		   struct intel_connector *connector,
-		   bool irq_received)
+		   struct intel_connector *connector)
 {
 	intel_sdvo_enable_hotplug(encoder);
 
-	return intel_encoder_hotplug(encoder, connector, irq_received);
+	return intel_encoder_hotplug(encoder, connector);
 }
 
 static bool
diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
index deda351719db..0000ec7055f7 100644
--- a/drivers/gpu/drm/i915/display/intel_sprite.c
+++ b/drivers/gpu/drm/i915/display/intel_sprite.c
@@ -2503,6 +2503,7 @@ static const u32 skl_plane_formats[] = {
 	DRM_FORMAT_YVYU,
 	DRM_FORMAT_UYVY,
 	DRM_FORMAT_VYUY,
+	DRM_FORMAT_XYUV8888,
 };
 
 static const u32 skl_planar_formats[] = {
@@ -2521,6 +2522,7 @@ static const u32 skl_planar_formats[] = {
 	DRM_FORMAT_UYVY,
 	DRM_FORMAT_VYUY,
 	DRM_FORMAT_NV12,
+	DRM_FORMAT_XYUV8888,
 };
 
 static const u32 glk_planar_formats[] = {
@@ -2539,6 +2541,7 @@ static const u32 glk_planar_formats[] = {
 	DRM_FORMAT_UYVY,
 	DRM_FORMAT_VYUY,
 	DRM_FORMAT_NV12,
+	DRM_FORMAT_XYUV8888,
 	DRM_FORMAT_P010,
 	DRM_FORMAT_P012,
 	DRM_FORMAT_P016,
@@ -2562,6 +2565,7 @@ static const u32 icl_sdr_y_plane_formats[] = {
 	DRM_FORMAT_Y210,
 	DRM_FORMAT_Y212,
 	DRM_FORMAT_Y216,
+	DRM_FORMAT_XYUV8888,
 	DRM_FORMAT_XVYU2101010,
 	DRM_FORMAT_XVYU12_16161616,
 	DRM_FORMAT_XVYU16161616,
@@ -2589,6 +2593,7 @@ static const u32 icl_sdr_uv_plane_formats[] = {
 	DRM_FORMAT_Y210,
 	DRM_FORMAT_Y212,
 	DRM_FORMAT_Y216,
+	DRM_FORMAT_XYUV8888,
 	DRM_FORMAT_XVYU2101010,
 	DRM_FORMAT_XVYU12_16161616,
 	DRM_FORMAT_XVYU16161616,
@@ -2620,6 +2625,7 @@ static const u32 icl_hdr_plane_formats[] = {
 	DRM_FORMAT_Y210,
 	DRM_FORMAT_Y212,
 	DRM_FORMAT_Y216,
+	DRM_FORMAT_XYUV8888,
 	DRM_FORMAT_XVYU2101010,
 	DRM_FORMAT_XVYU12_16161616,
 	DRM_FORMAT_XVYU16161616,
@@ -2790,6 +2796,7 @@ static bool skl_plane_format_mod_supported(struct drm_plane *_plane,
 	case DRM_FORMAT_UYVY:
 	case DRM_FORMAT_VYUY:
 	case DRM_FORMAT_NV12:
+	case DRM_FORMAT_XYUV8888:
 	case DRM_FORMAT_P010:
 	case DRM_FORMAT_P012:
 	case DRM_FORMAT_P016:
@@ -2817,19 +2824,25 @@ static bool skl_plane_format_mod_supported(struct drm_plane *_plane,
 	}
 }
 
-static bool gen12_plane_supports_mc_ccs(enum plane_id plane_id)
+static bool gen12_plane_supports_mc_ccs(struct drm_i915_private *dev_priv,
+					enum plane_id plane_id)
 {
+	/* Wa_14010477008:tgl[a0..c0] */
+	if (IS_TGL_REVID(dev_priv, TGL_REVID_A0, TGL_REVID_C0))
+		return false;
+
 	return plane_id < PLANE_SPRITE4;
 }
 
 static bool gen12_plane_format_mod_supported(struct drm_plane *_plane,
 					     u32 format, u64 modifier)
 {
+	struct drm_i915_private *dev_priv = to_i915(_plane->dev);
 	struct intel_plane *plane = to_intel_plane(_plane);
 
 	switch (modifier) {
 	case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
-		if (!gen12_plane_supports_mc_ccs(plane->id))
+		if (!gen12_plane_supports_mc_ccs(dev_priv, plane->id))
 			return false;
 		/* fall through */
 	case DRM_FORMAT_MOD_LINEAR:
@@ -2854,6 +2867,7 @@ static bool gen12_plane_format_mod_supported(struct drm_plane *_plane,
 	case DRM_FORMAT_UYVY:
 	case DRM_FORMAT_VYUY:
 	case DRM_FORMAT_NV12:
+	case DRM_FORMAT_XYUV8888:
 	case DRM_FORMAT_P010:
 	case DRM_FORMAT_P012:
 	case DRM_FORMAT_P016:
@@ -2998,9 +3012,10 @@ static const u32 *icl_get_plane_formats(struct drm_i915_private *dev_priv,
 	}
 }
 
-static const u64 *gen12_get_plane_modifiers(enum plane_id plane_id)
+static const u64 *gen12_get_plane_modifiers(struct drm_i915_private *dev_priv,
+					    enum plane_id plane_id)
 {
-	if (gen12_plane_supports_mc_ccs(plane_id))
+	if (gen12_plane_supports_mc_ccs(dev_priv, plane_id))
 		return gen12_plane_format_modifiers_mc_ccs;
 	else
 		return gen12_plane_format_modifiers_rc_ccs;
@@ -3070,7 +3085,7 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv,
 
 	plane->has_ccs = skl_plane_has_ccs(dev_priv, pipe, plane_id);
 	if (INTEL_GEN(dev_priv) >= 12) {
-		modifiers = gen12_get_plane_modifiers(plane_id);
+		modifiers = gen12_get_plane_modifiers(dev_priv, plane_id);
 		plane_funcs = &gen12_plane_funcs;
 	} else {
 		if (plane->has_ccs)
diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c
index 9b850c11aa78..275618bedf32 100644
--- a/drivers/gpu/drm/i915/display/intel_tc.c
+++ b/drivers/gpu/drm/i915/display/intel_tc.c
@@ -152,6 +152,7 @@ void intel_tc_port_set_fia_lane_count(struct intel_digital_port *dig_port,
 static void tc_port_fixup_legacy_flag(struct intel_digital_port *dig_port,
 				      u32 live_status_mask)
 {
+	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
 	u32 valid_hpd_mask;
 
 	if (dig_port->tc_legacy_port)
@@ -164,8 +165,9 @@ static void tc_port_fixup_legacy_flag(struct intel_digital_port *dig_port,
 		return;
 
 	/* If live status mismatches the VBT flag, trust the live status. */
-	DRM_ERROR("Port %s: live status %08x mismatches the legacy port flag, fix flag\n",
-		  dig_port->tc_port_name, live_status_mask);
+	drm_err(&i915->drm,
+		"Port %s: live status %08x mismatches the legacy port flag, fix flag\n",
+		dig_port->tc_port_name, live_status_mask);
 
 	dig_port->tc_legacy_port = !dig_port->tc_legacy_port;
 }
@@ -233,8 +235,7 @@ static bool icl_tc_phy_set_safe_mode(struct intel_digital_port *dig_port,
 	if (val == 0xffffffff) {
 		drm_dbg_kms(&i915->drm,
 			    "Port %s: PHY in TCCOLD, can't set safe-mode to %s\n",
-			    dig_port->tc_port_name,
-			      enableddisabled(enable));
+			    dig_port->tc_port_name, enableddisabled(enable));
 
 		return false;
 	}
@@ -286,11 +287,12 @@ static bool icl_tc_phy_is_in_safe_mode(struct intel_digital_port *dig_port)
 static void icl_tc_phy_connect(struct intel_digital_port *dig_port,
 			       int required_lanes)
 {
+	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
 	int max_lanes;
 
 	if (!icl_tc_phy_status_complete(dig_port)) {
-		DRM_DEBUG_KMS("Port %s: PHY not ready\n",
-			      dig_port->tc_port_name);
+		drm_dbg_kms(&i915->drm, "Port %s: PHY not ready\n",
+			    dig_port->tc_port_name);
 		goto out_set_tbt_alt_mode;
 	}
 
@@ -311,15 +313,16 @@ static void icl_tc_phy_connect(struct intel_digital_port *dig_port,
 	 * became disconnected. Not necessary for legacy mode.
 	 */
 	if (!(tc_port_live_status_mask(dig_port) & BIT(TC_PORT_DP_ALT))) {
-		DRM_DEBUG_KMS("Port %s: PHY sudden disconnect\n",
-			      dig_port->tc_port_name);
+		drm_dbg_kms(&i915->drm, "Port %s: PHY sudden disconnect\n",
+			    dig_port->tc_port_name);
 		goto out_set_safe_mode;
 	}
 
 	if (max_lanes < required_lanes) {
-		DRM_DEBUG_KMS("Port %s: PHY max lanes %d < required lanes %d\n",
-			      dig_port->tc_port_name,
-			      max_lanes, required_lanes);
+		drm_dbg_kms(&i915->drm,
+			    "Port %s: PHY max lanes %d < required lanes %d\n",
+			    dig_port->tc_port_name,
+			    max_lanes, required_lanes);
 		goto out_set_safe_mode;
 	}
 
@@ -357,15 +360,17 @@ static void icl_tc_phy_disconnect(struct intel_digital_port *dig_port)
 
 static bool icl_tc_phy_is_connected(struct intel_digital_port *dig_port)
 {
+	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
+
 	if (!icl_tc_phy_status_complete(dig_port)) {
-		DRM_DEBUG_KMS("Port %s: PHY status not complete\n",
-			      dig_port->tc_port_name);
+		drm_dbg_kms(&i915->drm, "Port %s: PHY status not complete\n",
+			    dig_port->tc_port_name);
 		return dig_port->tc_mode == TC_PORT_TBT_ALT;
 	}
 
 	if (icl_tc_phy_is_in_safe_mode(dig_port)) {
-		DRM_DEBUG_KMS("Port %s: PHY still in safe mode\n",
-			      dig_port->tc_port_name);
+		drm_dbg_kms(&i915->drm, "Port %s: PHY still in safe mode\n",
+			    dig_port->tc_port_name);
 
 		return false;
 	}
@@ -438,6 +443,7 @@ intel_tc_port_link_init_refcount(struct intel_digital_port *dig_port,
 
 void intel_tc_port_sanitize(struct intel_digital_port *dig_port)
 {
+	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
 	struct intel_encoder *encoder = &dig_port->base;
 	int active_links = 0;
 
@@ -451,8 +457,9 @@ void intel_tc_port_sanitize(struct intel_digital_port *dig_port)
 
 	if (active_links) {
 		if (!icl_tc_phy_is_connected(dig_port))
-			DRM_DEBUG_KMS("Port %s: PHY disconnected with %d active link(s)\n",
-				      dig_port->tc_port_name, active_links);
+			drm_dbg_kms(&i915->drm,
+				    "Port %s: PHY disconnected with %d active link(s)\n",
+				    dig_port->tc_port_name, active_links);
 		intel_tc_port_link_init_refcount(dig_port, active_links);
 
 		goto out;
@@ -462,9 +469,9 @@ void intel_tc_port_sanitize(struct intel_digital_port *dig_port)
 		icl_tc_phy_connect(dig_port, 1);
 
 out:
-	DRM_DEBUG_KMS("Port %s: sanitize mode (%s)\n",
-		      dig_port->tc_port_name,
-		      tc_port_mode_name(dig_port->tc_mode));
+	drm_dbg_kms(&i915->drm, "Port %s: sanitize mode (%s)\n",
+		    dig_port->tc_port_name,
+		    tc_port_mode_name(dig_port->tc_mode));
 
 	mutex_unlock(&dig_port->tc_lock);
 }
diff --git a/drivers/gpu/drm/i915/display/intel_tv.c b/drivers/gpu/drm/i915/display/intel_tv.c
index d2e3a3a323e9..fbe12aad7d58 100644
--- a/drivers/gpu/drm/i915/display/intel_tv.c
+++ b/drivers/gpu/drm/i915/display/intel_tv.c
@@ -914,7 +914,8 @@ intel_tv_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe)
 }
 
 static void
-intel_enable_tv(struct intel_encoder *encoder,
+intel_enable_tv(struct intel_atomic_state *state,
+		struct intel_encoder *encoder,
 		const struct intel_crtc_state *pipe_config,
 		const struct drm_connector_state *conn_state)
 {
@@ -930,7 +931,8 @@ intel_enable_tv(struct intel_encoder *encoder,
 }
 
 static void
-intel_disable_tv(struct intel_encoder *encoder,
+intel_disable_tv(struct intel_atomic_state *state,
+		 struct intel_encoder *encoder,
 		 const struct intel_crtc_state *old_crtc_state,
 		 const struct drm_connector_state *old_conn_state)
 {
@@ -1414,7 +1416,8 @@ static void set_color_conversion(struct drm_i915_private *dev_priv,
 		       (color_conversion->bv << 16) | color_conversion->av);
 }
 
-static void intel_tv_pre_enable(struct intel_encoder *encoder,
+static void intel_tv_pre_enable(struct intel_atomic_state *state,
+				struct intel_encoder *encoder,
 				const struct intel_crtc_state *pipe_config,
 				const struct drm_connector_state *conn_state)
 {
@@ -1698,13 +1701,13 @@ intel_tv_detect(struct drm_connector *connector,
 		struct drm_modeset_acquire_ctx *ctx,
 		bool force)
 {
+	struct drm_i915_private *i915 = to_i915(connector->dev);
 	struct intel_tv *intel_tv = intel_attached_tv(to_intel_connector(connector));
 	enum drm_connector_status status;
 	int type;
 
-	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] force=%d\n",
-		      connector->base.id, connector->name,
-		      force);
+	drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] force=%d\n",
+		    connector->base.id, connector->name, force);
 
 	if (force) {
 		struct intel_load_detect_pipe tmp;
diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c
index f4c362dc6e15..4e18d4627065 100644
--- a/drivers/gpu/drm/i915/display/vlv_dsi.c
+++ b/drivers/gpu/drm/i915/display/vlv_dsi.c
@@ -759,7 +759,8 @@ static void intel_dsi_unprepare(struct intel_encoder *encoder);
  * DSI port enable has to be done before pipe and plane enable, so we do it in
  * the pre_enable hook instead of the enable hook.
  */
-static void intel_dsi_pre_enable(struct intel_encoder *encoder,
+static void intel_dsi_pre_enable(struct intel_atomic_state *state,
+				 struct intel_encoder *encoder,
 				 const struct intel_crtc_state *pipe_config,
 				 const struct drm_connector_state *conn_state)
 {
@@ -858,7 +859,8 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder,
 	intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_ON);
 }
 
-static void bxt_dsi_enable(struct intel_encoder *encoder,
+static void bxt_dsi_enable(struct intel_atomic_state *state,
+			   struct intel_encoder *encoder,
 			   const struct intel_crtc_state *crtc_state,
 			   const struct drm_connector_state *conn_state)
 {
@@ -871,14 +873,16 @@ static void bxt_dsi_enable(struct intel_encoder *encoder,
  * DSI port disable has to be done after pipe and plane disable, so we do it in
  * the post_disable hook.
  */
-static void intel_dsi_disable(struct intel_encoder *encoder,
+static void intel_dsi_disable(struct intel_atomic_state *state,
+			      struct intel_encoder *encoder,
 			      const struct intel_crtc_state *old_crtc_state,
 			      const struct drm_connector_state *old_conn_state)
 {
+	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
 	struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
 	enum port port;
 
-	DRM_DEBUG_KMS("\n");
+	drm_dbg_kms(&i915->drm, "\n");
 
 	intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_OFF);
 	intel_panel_disable_backlight(old_conn_state);
@@ -906,7 +910,8 @@ static void intel_dsi_clear_device_ready(struct intel_encoder *encoder)
 		vlv_dsi_clear_device_ready(encoder);
 }
 
-static void intel_dsi_post_disable(struct intel_encoder *encoder,
+static void intel_dsi_post_disable(struct intel_atomic_state *state,
+				   struct intel_encoder *encoder,
 				   const struct intel_crtc_state *old_crtc_state,
 				   const struct drm_connector_state *old_conn_state)
 {
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
index 68326ad3b2e0..11d9135cf21a 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
@@ -570,23 +570,19 @@ static void engines_idle_release(struct i915_gem_context *ctx,
 	engines->ctx = i915_gem_context_get(ctx);
 
 	for_each_gem_engine(ce, engines, it) {
-		struct dma_fence *fence;
-		int err = 0;
+		int err;
 
 		/* serialises with execbuf */
 		set_bit(CONTEXT_CLOSED_BIT, &ce->flags);
 		if (!intel_context_pin_if_active(ce))
 			continue;
 
-		fence = i915_active_fence_get(&ce->timeline->last_request);
-		if (fence) {
-			err = i915_sw_fence_await_dma_fence(&engines->fence,
-							    fence, 0,
-							    GFP_KERNEL);
-			dma_fence_put(fence);
-		}
+		/* Wait until context is finally scheduled out and retired */
+		err = i915_sw_fence_await_active(&engines->fence,
+						 &ce->active,
+						 I915_ACTIVE_AWAIT_BARRIER);
 		intel_context_unpin(ce);
-		if (err < 0)
+		if (err)
 			goto kill;
 	}
 
@@ -757,21 +753,46 @@ __create_context(struct drm_i915_private *i915)
 	return ERR_PTR(err);
 }
 
+static inline struct i915_gem_engines *
+__context_engines_await(const struct i915_gem_context *ctx)
+{
+	struct i915_gem_engines *engines;
+
+	rcu_read_lock();
+	do {
+		engines = rcu_dereference(ctx->engines);
+		GEM_BUG_ON(!engines);
+
+		if (unlikely(!i915_sw_fence_await(&engines->fence)))
+			continue;
+
+		if (likely(engines == rcu_access_pointer(ctx->engines)))
+			break;
+
+		i915_sw_fence_complete(&engines->fence);
+	} while (1);
+	rcu_read_unlock();
+
+	return engines;
+}
+
 static int
 context_apply_all(struct i915_gem_context *ctx,
 		  int (*fn)(struct intel_context *ce, void *data),
 		  void *data)
 {
 	struct i915_gem_engines_iter it;
+	struct i915_gem_engines *e;
 	struct intel_context *ce;
 	int err = 0;
 
-	for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it) {
+	e = __context_engines_await(ctx);
+	for_each_gem_engine(ce, e, it) {
 		err = fn(ce, data);
 		if (err)
 			break;
 	}
-	i915_gem_context_unlock_engines(ctx);
+	i915_sw_fence_complete(&e->fence);
 
 	return err;
 }
@@ -786,11 +807,13 @@ static int __apply_ppgtt(struct intel_context *ce, void *vm)
 static struct i915_address_space *
 __set_ppgtt(struct i915_gem_context *ctx, struct i915_address_space *vm)
 {
-	struct i915_address_space *old = i915_gem_context_vm(ctx);
+	struct i915_address_space *old;
 
+	old = rcu_replace_pointer(ctx->vm,
+				  i915_vm_open(vm),
+				  lockdep_is_held(&ctx->mutex));
 	GEM_BUG_ON(old && i915_vm_is_4lvl(vm) != i915_vm_is_4lvl(old));
 
-	rcu_assign_pointer(ctx->vm, i915_vm_open(vm));
 	context_apply_all(ctx, __apply_ppgtt, vm);
 
 	return old;
@@ -1069,30 +1092,6 @@ static void cb_retire(struct i915_active *base)
 	kfree(cb);
 }
 
-static inline struct i915_gem_engines *
-__context_engines_await(const struct i915_gem_context *ctx)
-{
-	struct i915_gem_engines *engines;
-
-	rcu_read_lock();
-	do {
-		engines = rcu_dereference(ctx->engines);
-		if (unlikely(!engines))
-			break;
-
-		if (unlikely(!i915_sw_fence_await(&engines->fence)))
-			continue;
-
-		if (likely(engines == rcu_access_pointer(ctx->engines)))
-			break;
-
-		i915_sw_fence_complete(&engines->fence);
-	} while (1);
-	rcu_read_unlock();
-
-	return engines;
-}
-
 I915_SELFTEST_DECLARE(static intel_engine_mask_t context_barrier_inject_fault);
 static int context_barrier_task(struct i915_gem_context *ctx,
 				intel_engine_mask_t engines,
@@ -1401,10 +1400,10 @@ static int get_ringsize(struct i915_gem_context *ctx,
 	return 0;
 }
 
-static int
-user_to_context_sseu(struct drm_i915_private *i915,
-		     const struct drm_i915_gem_context_param_sseu *user,
-		     struct intel_sseu *context)
+int
+i915_gem_user_to_context_sseu(struct drm_i915_private *i915,
+			      const struct drm_i915_gem_context_param_sseu *user,
+			      struct intel_sseu *context)
 {
 	const struct sseu_dev_info *device = &RUNTIME_INFO(i915)->sseu;
 
@@ -1539,7 +1538,7 @@ static int set_sseu(struct i915_gem_context *ctx,
 		goto out_ce;
 	}
 
-	ret = user_to_context_sseu(i915, &user_sseu, &sseu);
+	ret = i915_gem_user_to_context_sseu(i915, &user_sseu, &sseu);
 	if (ret)
 		goto out_ce;
 
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.h b/drivers/gpu/drm/i915/gem/i915_gem_context.h
index f1d884d304bd..3702b2fb27ab 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.h
@@ -225,4 +225,8 @@ i915_gem_engines_iter_next(struct i915_gem_engines_iter *it);
 struct i915_lut_handle *i915_lut_handle_alloc(void);
 void i915_lut_handle_free(struct i915_lut_handle *lut);
 
+int i915_gem_user_to_context_sseu(struct drm_i915_private *i915,
+				  const struct drm_i915_gem_context_param_sseu *user,
+				  struct intel_sseu *context);
+
 #endif /* !__I915_GEM_CONTEXT_H__ */
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_domain.c b/drivers/gpu/drm/i915/gem/i915_gem_domain.c
index 0cc40e77bbd2..af43e82f45c7 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_domain.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_domain.c
@@ -369,7 +369,7 @@ static void i915_gem_object_bump_inactive_ggtt(struct drm_i915_gem_object *obj)
 	struct i915_vma *vma;
 
 	GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj));
-	if (!atomic_read(&obj->bind_count))
+	if (list_empty(&obj->vma.list))
 		return;
 
 	mutex_lock(&i915->ggtt.vm.mutex);
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index b7440f06c5e2..517898aa634c 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -40,6 +40,11 @@ struct eb_vma {
 	u32 handle;
 };
 
+struct eb_vma_array {
+	struct kref kref;
+	struct eb_vma vma[];
+};
+
 enum {
 	FORCE_CPU_RELOC = 1,
 	FORCE_GTT_RELOC,
@@ -52,7 +57,6 @@ enum {
 #define __EXEC_OBJECT_NEEDS_MAP		BIT(29)
 #define __EXEC_OBJECT_NEEDS_BIAS	BIT(28)
 #define __EXEC_OBJECT_INTERNAL_FLAGS	(~0u << 28) /* all of the above */
-#define __EXEC_OBJECT_RESERVED (__EXEC_OBJECT_HAS_PIN | __EXEC_OBJECT_HAS_FENCE)
 
 #define __EXEC_HAS_RELOC	BIT(31)
 #define __EXEC_INTERNAL_FLAGS	(~0u << 31)
@@ -283,6 +287,7 @@ struct i915_execbuffer {
 	 */
 	int lut_size;
 	struct hlist_head *buckets; /** ht for relocation handles */
+	struct eb_vma_array *array;
 };
 
 static inline bool eb_use_cmdparser(const struct i915_execbuffer *eb)
@@ -292,8 +297,62 @@ static inline bool eb_use_cmdparser(const struct i915_execbuffer *eb)
 		 eb->args->batch_len);
 }
 
+static struct eb_vma_array *eb_vma_array_create(unsigned int count)
+{
+	struct eb_vma_array *arr;
+
+	arr = kvmalloc(struct_size(arr, vma, count), GFP_KERNEL | __GFP_NOWARN);
+	if (!arr)
+		return NULL;
+
+	kref_init(&arr->kref);
+	arr->vma[0].vma = NULL;
+
+	return arr;
+}
+
+static inline void eb_unreserve_vma(struct eb_vma *ev)
+{
+	struct i915_vma *vma = ev->vma;
+
+	if (unlikely(ev->flags & __EXEC_OBJECT_HAS_FENCE))
+		__i915_vma_unpin_fence(vma);
+
+	if (ev->flags & __EXEC_OBJECT_HAS_PIN)
+		__i915_vma_unpin(vma);
+
+	ev->flags &= ~(__EXEC_OBJECT_HAS_PIN |
+		       __EXEC_OBJECT_HAS_FENCE);
+}
+
+static void eb_vma_array_destroy(struct kref *kref)
+{
+	struct eb_vma_array *arr = container_of(kref, typeof(*arr), kref);
+	struct eb_vma *ev = arr->vma;
+
+	while (ev->vma) {
+		eb_unreserve_vma(ev);
+		i915_vma_put(ev->vma);
+		ev++;
+	}
+
+	kvfree(arr);
+}
+
+static void eb_vma_array_put(struct eb_vma_array *arr)
+{
+	kref_put(&arr->kref, eb_vma_array_destroy);
+}
+
 static int eb_create(struct i915_execbuffer *eb)
 {
+	/* Allocate an extra slot for use by the command parser + sentinel */
+	eb->array = eb_vma_array_create(eb->buffer_count + 2);
+	if (!eb->array)
+		return -ENOMEM;
+
+	eb->vma = eb->array->vma;
+
 	if (!(eb->args->flags & I915_EXEC_HANDLE_LUT)) {
 		unsigned int size = 1 + ilog2(eb->buffer_count);
 
@@ -327,8 +386,10 @@ static int eb_create(struct i915_execbuffer *eb)
 				break;
 		} while (--size);
 
-		if (unlikely(!size))
+		if (unlikely(!size)) {
+			eb_vma_array_put(eb->array);
 			return -ENOMEM;
+		}
 
 		eb->lut_size = size;
 	} else {
@@ -368,6 +429,32 @@ eb_vma_misplaced(const struct drm_i915_gem_exec_object2 *entry,
 	return false;
 }
 
+static u64 eb_pin_flags(const struct drm_i915_gem_exec_object2 *entry,
+			unsigned int exec_flags)
+{
+	u64 pin_flags = 0;
+
+	if (exec_flags & EXEC_OBJECT_NEEDS_GTT)
+		pin_flags |= PIN_GLOBAL;
+
+	/*
+	 * Wa32bitGeneralStateOffset & Wa32bitInstructionBaseOffset,
+	 * limit address to the first 4GBs for unflagged objects.
+	 */
+	if (!(exec_flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS))
+		pin_flags |= PIN_ZONE_4G;
+
+	if (exec_flags & __EXEC_OBJECT_NEEDS_MAP)
+		pin_flags |= PIN_MAPPABLE;
+
+	if (exec_flags & EXEC_OBJECT_PINNED)
+		pin_flags |= entry->offset | PIN_OFFSET_FIXED;
+	else if (exec_flags & __EXEC_OBJECT_NEEDS_BIAS)
+		pin_flags |= BATCH_OFFSET_BIAS | PIN_OFFSET_BIAS;
+
+	return pin_flags;
+}
+
 static inline bool
 eb_pin_vma(struct i915_execbuffer *eb,
 	   const struct drm_i915_gem_exec_object2 *entry,
@@ -385,8 +472,19 @@ eb_pin_vma(struct i915_execbuffer *eb,
 	if (unlikely(ev->flags & EXEC_OBJECT_NEEDS_GTT))
 		pin_flags |= PIN_GLOBAL;
 
-	if (unlikely(i915_vma_pin(vma, 0, 0, pin_flags)))
-		return false;
+	/* Attempt to reuse the current location if available */
+	if (unlikely(i915_vma_pin(vma, 0, 0, pin_flags))) {
+		if (entry->flags & EXEC_OBJECT_PINNED)
+			return false;
+
+		/* Failing that pick any _free_ space if suitable */
+		if (unlikely(i915_vma_pin(vma,
+					  entry->pad_to_size,
+					  entry->alignment,
+					  eb_pin_flags(entry, ev->flags) |
+					  PIN_USER | PIN_NOEVICT)))
+			return false;
+	}
 
 	if (unlikely(ev->flags & EXEC_OBJECT_NEEDS_FENCE)) {
 		if (unlikely(i915_vma_pin_fence(vma))) {
@@ -402,26 +500,6 @@ eb_pin_vma(struct i915_execbuffer *eb,
 	return !eb_vma_misplaced(entry, vma, ev->flags);
 }
 
-static inline void __eb_unreserve_vma(struct i915_vma *vma, unsigned int flags)
-{
-	GEM_BUG_ON(!(flags & __EXEC_OBJECT_HAS_PIN));
-
-	if (unlikely(flags & __EXEC_OBJECT_HAS_FENCE))
-		__i915_vma_unpin_fence(vma);
-
-	__i915_vma_unpin(vma);
-}
-
-static inline void
-eb_unreserve_vma(struct eb_vma *ev)
-{
-	if (!(ev->flags & __EXEC_OBJECT_HAS_PIN))
-		return;
-
-	__eb_unreserve_vma(ev->vma, ev->flags);
-	ev->flags &= ~__EXEC_OBJECT_RESERVED;
-}
-
 static int
 eb_validate_vma(struct i915_execbuffer *eb,
 		struct drm_i915_gem_exec_object2 *entry,
@@ -481,7 +559,7 @@ eb_add_vma(struct i915_execbuffer *eb,
 
 	GEM_BUG_ON(i915_vma_is_closed(vma));
 
-	ev->vma = i915_vma_get(vma);
+	ev->vma = vma;
 	ev->exec = entry;
 	ev->flags = entry->flags;
 
@@ -547,28 +625,9 @@ static int eb_reserve_vma(const struct i915_execbuffer *eb,
 			  u64 pin_flags)
 {
 	struct drm_i915_gem_exec_object2 *entry = ev->exec;
-	unsigned int exec_flags = ev->flags;
 	struct i915_vma *vma = ev->vma;
 	int err;
 
-	if (exec_flags & EXEC_OBJECT_NEEDS_GTT)
-		pin_flags |= PIN_GLOBAL;
-
-	/*
-	 * Wa32bitGeneralStateOffset & Wa32bitInstructionBaseOffset,
-	 * limit address to the first 4GBs for unflagged objects.
-	 */
-	if (!(exec_flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS))
-		pin_flags |= PIN_ZONE_4G;
-
-	if (exec_flags & __EXEC_OBJECT_NEEDS_MAP)
-		pin_flags |= PIN_MAPPABLE;
-
-	if (exec_flags & EXEC_OBJECT_PINNED)
-		pin_flags |= entry->offset | PIN_OFFSET_FIXED;
-	else if (exec_flags & __EXEC_OBJECT_NEEDS_BIAS)
-		pin_flags |= BATCH_OFFSET_BIAS | PIN_OFFSET_BIAS;
-
 	if (drm_mm_node_allocated(&vma->node) &&
 	    eb_vma_misplaced(entry, vma, ev->flags)) {
 		err = i915_vma_unbind(vma);
@@ -578,7 +637,7 @@ static int eb_reserve_vma(const struct i915_execbuffer *eb,
 
 	err = i915_vma_pin(vma,
 			   entry->pad_to_size, entry->alignment,
-			   pin_flags);
+			   eb_pin_flags(entry, ev->flags) | pin_flags);
 	if (err)
 		return err;
 
@@ -587,7 +646,7 @@ static int eb_reserve_vma(const struct i915_execbuffer *eb,
 		eb->args->flags |= __EXEC_HAS_RELOC;
 	}
 
-	if (unlikely(exec_flags & EXEC_OBJECT_NEEDS_FENCE)) {
+	if (unlikely(ev->flags & EXEC_OBJECT_NEEDS_FENCE)) {
 		err = i915_vma_pin_fence(vma);
 		if (unlikely(err)) {
 			i915_vma_unpin(vma);
@@ -595,10 +654,10 @@ static int eb_reserve_vma(const struct i915_execbuffer *eb,
 		}
 
 		if (vma->fence)
-			exec_flags |= __EXEC_OBJECT_HAS_FENCE;
+			ev->flags |= __EXEC_OBJECT_HAS_FENCE;
 	}
 
-	ev->flags = exec_flags | __EXEC_OBJECT_HAS_PIN;
+	ev->flags |= __EXEC_OBJECT_HAS_PIN;
 	GEM_BUG_ON(eb_vma_misplaced(entry, vma, ev->flags));
 
 	return 0;
@@ -728,77 +787,117 @@ static int eb_select_context(struct i915_execbuffer *eb)
 	return 0;
 }
 
-static int eb_lookup_vmas(struct i915_execbuffer *eb)
+static int __eb_add_lut(struct i915_execbuffer *eb,
+			u32 handle, struct i915_vma *vma)
 {
-	struct radix_tree_root *handles_vma = &eb->gem_context->handles_vma;
-	struct drm_i915_gem_object *obj;
-	unsigned int i, batch;
+	struct i915_gem_context *ctx = eb->gem_context;
+	struct i915_lut_handle *lut;
 	int err;
 
-	if (unlikely(i915_gem_context_is_closed(eb->gem_context)))
-		return -ENOENT;
+	lut = i915_lut_handle_alloc();
+	if (unlikely(!lut))
+		return -ENOMEM;
 
-	INIT_LIST_HEAD(&eb->relocs);
-	INIT_LIST_HEAD(&eb->unbound);
+	i915_vma_get(vma);
+	if (!atomic_fetch_inc(&vma->open_count))
+		i915_vma_reopen(vma);
+	lut->handle = handle;
+	lut->ctx = ctx;
+
+	/* Check that the context hasn't been closed in the meantime */
+	err = -EINTR;
+	if (!mutex_lock_interruptible(&ctx->mutex)) {
+		err = -ENOENT;
+		if (likely(!i915_gem_context_is_closed(ctx)))
+			err = radix_tree_insert(&ctx->handles_vma, handle, vma);
+		if (err == 0) { /* And nor has this handle */
+			struct drm_i915_gem_object *obj = vma->obj;
+
+			i915_gem_object_lock(obj);
+			if (idr_find(&eb->file->object_idr, handle) == obj) {
+				list_add(&lut->obj_link, &obj->lut_list);
+			} else {
+				radix_tree_delete(&ctx->handles_vma, handle);
+				err = -ENOENT;
+			}
+			i915_gem_object_unlock(obj);
+		}
+		mutex_unlock(&ctx->mutex);
+	}
+	if (unlikely(err))
+		goto err;
 
-	batch = eb_batch_index(eb);
+	return 0;
 
-	for (i = 0; i < eb->buffer_count; i++) {
-		u32 handle = eb->exec[i].handle;
-		struct i915_lut_handle *lut;
+err:
+	atomic_dec(&vma->open_count);
+	i915_vma_put(vma);
+	i915_lut_handle_free(lut);
+	return err;
+}
+
+static struct i915_vma *eb_lookup_vma(struct i915_execbuffer *eb, u32 handle)
+{
+	do {
+		struct drm_i915_gem_object *obj;
 		struct i915_vma *vma;
+		int err;
 
-		vma = radix_tree_lookup(handles_vma, handle);
+		rcu_read_lock();
+		vma = radix_tree_lookup(&eb->gem_context->handles_vma, handle);
+		if (likely(vma))
+			vma = i915_vma_tryget(vma);
+		rcu_read_unlock();
 		if (likely(vma))
-			goto add_vma;
+			return vma;
 
 		obj = i915_gem_object_lookup(eb->file, handle);
-		if (unlikely(!obj)) {
-			err = -ENOENT;
-			goto err_vma;
-		}
+		if (unlikely(!obj))
+			return ERR_PTR(-ENOENT);
 
 		vma = i915_vma_instance(obj, eb->context->vm, NULL);
 		if (IS_ERR(vma)) {
-			err = PTR_ERR(vma);
-			goto err_obj;
+			i915_gem_object_put(obj);
+			return vma;
 		}
 
-		lut = i915_lut_handle_alloc();
-		if (unlikely(!lut)) {
-			err = -ENOMEM;
-			goto err_obj;
-		}
+		err = __eb_add_lut(eb, handle, vma);
+		if (likely(!err))
+			return vma;
 
-		err = radix_tree_insert(handles_vma, handle, vma);
-		if (unlikely(err)) {
-			i915_lut_handle_free(lut);
-			goto err_obj;
-		}
+		i915_gem_object_put(obj);
+		if (err != -EEXIST)
+			return ERR_PTR(err);
+	} while (1);
+}
 
-		/* transfer ref to lut */
-		if (!atomic_fetch_inc(&vma->open_count))
-			i915_vma_reopen(vma);
-		lut->handle = handle;
-		lut->ctx = eb->gem_context;
+static int eb_lookup_vmas(struct i915_execbuffer *eb)
+{
+	unsigned int batch = eb_batch_index(eb);
+	unsigned int i;
+	int err = 0;
 
-		i915_gem_object_lock(obj);
-		list_add(&lut->obj_link, &obj->lut_list);
-		i915_gem_object_unlock(obj);
+	INIT_LIST_HEAD(&eb->relocs);
+	INIT_LIST_HEAD(&eb->unbound);
+
+	for (i = 0; i < eb->buffer_count; i++) {
+		struct i915_vma *vma;
+
+		vma = eb_lookup_vma(eb, eb->exec[i].handle);
+		if (IS_ERR(vma)) {
+			err = PTR_ERR(vma);
+			break;
+		}
 
-add_vma:
 		err = eb_validate_vma(eb, &eb->exec[i], vma);
-		if (unlikely(err))
-			goto err_vma;
+		if (unlikely(err)) {
+			i915_vma_put(vma);
+			break;
+		}
 
 		eb_add_vma(eb, i, batch, vma);
 	}
 
-	return 0;
-
-err_obj:
-	i915_gem_object_put(obj);
-err_vma:
 	eb->vma[i].vma = NULL;
 	return err;
 }
@@ -823,31 +922,13 @@ eb_get_vma(const struct i915_execbuffer *eb, unsigned long handle)
 	}
 }
 
-static void eb_release_vmas(const struct i915_execbuffer *eb)
-{
-	const unsigned int count = eb->buffer_count;
-	unsigned int i;
-
-	for (i = 0; i < count; i++) {
-		struct eb_vma *ev = &eb->vma[i];
-		struct i915_vma *vma = ev->vma;
-
-		if (!vma)
-			break;
-
-		eb->vma[i].vma = NULL;
-
-		if (ev->flags & __EXEC_OBJECT_HAS_PIN)
-			__eb_unreserve_vma(vma, ev->flags);
-
-		i915_vma_put(vma);
-	}
-}
-
 static void eb_destroy(const struct i915_execbuffer *eb)
 {
 	GEM_BUG_ON(eb->reloc_cache.rq);
 
+	if (eb->array)
+		eb_vma_array_put(eb->array);
+
 	if (eb->lut_size > 0)
 		kfree(eb->buckets);
 }
@@ -1220,6 +1301,17 @@ static u32 *reloc_gpu(struct i915_execbuffer *eb,
 	return cmd;
 }
 
+static inline bool use_reloc_gpu(struct i915_vma *vma)
+{
+	if (DBG_FORCE_RELOC == FORCE_GPU_RELOC)
+		return true;
+
+	if (DBG_FORCE_RELOC)
+		return false;
+
+	return !dma_resv_test_signaled_rcu(vma->resv, true);
+}
+
 static u64
 relocate_entry(struct i915_vma *vma,
 	       const struct drm_i915_gem_relocation_entry *reloc,
@@ -1231,9 +1323,7 @@ relocate_entry(struct i915_vma *vma,
 	bool wide = eb->reloc_cache.use_64bit_reloc;
 	void *vaddr;
 
-	if (!eb->reloc_cache.vaddr &&
-	    (DBG_FORCE_RELOC == FORCE_GPU_RELOC ||
-	     !dma_resv_test_signaled_rcu(vma->resv, true))) {
+	if (!eb->reloc_cache.vaddr && use_reloc_gpu(vma)) {
 		const unsigned int gen = eb->reloc_cache.gen;
 		unsigned int len;
 		u32 *batch;
@@ -1411,12 +1501,11 @@ static int eb_relocate_vma(struct i915_execbuffer *eb, struct eb_vma *ev)
 {
 #define N_RELOC(x) ((x) / sizeof(struct drm_i915_gem_relocation_entry))
 	struct drm_i915_gem_relocation_entry stack[N_RELOC(512)];
-	struct drm_i915_gem_relocation_entry __user *urelocs;
 	const struct drm_i915_gem_exec_object2 *entry = ev->exec;
-	unsigned int remain;
+	struct drm_i915_gem_relocation_entry __user *urelocs =
+		u64_to_user_ptr(entry->relocs_ptr);
+	unsigned long remain = entry->relocation_count;
 
-	urelocs = u64_to_user_ptr(entry->relocs_ptr);
-	remain = entry->relocation_count;
 	if (unlikely(remain > N_RELOC(ULONG_MAX)))
 		return -EINVAL;
 
@@ -1425,13 +1514,13 @@ static int eb_relocate_vma(struct i915_execbuffer *eb, struct eb_vma *ev)
 	 * to read. However, if the array is not writable the user loses
 	 * the updated relocation values.
 	 */
-	if (unlikely(!access_ok(urelocs, remain*sizeof(*urelocs))))
+	if (unlikely(!access_ok(urelocs, remain * sizeof(*urelocs))))
 		return -EFAULT;
 
 	do {
 		struct drm_i915_gem_relocation_entry *r = stack;
 		unsigned int count =
-			min_t(unsigned int, remain, ARRAY_SIZE(stack));
+			min_t(unsigned long, remain, ARRAY_SIZE(stack));
 		unsigned int copied;
 
 		/*
@@ -1494,9 +1583,7 @@ static int eb_relocate(struct i915_execbuffer *eb)
 {
 	int err;
 
-	mutex_lock(&eb->gem_context->mutex);
 	err = eb_lookup_vmas(eb);
-	mutex_unlock(&eb->gem_context->mutex);
 	if (err)
 		return err;
 
@@ -1597,19 +1684,15 @@ static int eb_move_to_gpu(struct i915_execbuffer *eb)
 			err = i915_vma_move_to_active(vma, eb->request, flags);
 
 		i915_vma_unlock(vma);
-
-		__eb_unreserve_vma(vma, flags);
-		i915_vma_put(vma);
-
-		ev->vma = NULL;
+		eb_unreserve_vma(ev);
 	}
 	ww_acquire_fini(&acquire);
 
+	eb_vma_array_put(fetch_and_zero(&eb->array));
+
 	if (unlikely(err))
 		goto err_skip;
 
-	eb->exec = NULL;
-
 	/* Unconditionally flush any chipset caches (for streaming writes). */
 	intel_gt_chipset_flush(eb->engine->gt);
 	return 0;
@@ -1784,7 +1867,7 @@ static int eb_parse_pipeline(struct i915_execbuffer *eb,
 	dma_resv_add_excl_fence(shadow->resv, &pw->base.dma);
 	dma_resv_unlock(shadow->resv);
 
-	dma_fence_work_commit(&pw->base);
+	dma_fence_work_commit_imm(&pw->base);
 	return 0;
 
 err_batch_unlock:
@@ -1861,6 +1944,7 @@ static int eb_parse(struct i915_execbuffer *eb)
 	eb->vma[eb->buffer_count].vma = i915_vma_get(shadow);
 	eb->vma[eb->buffer_count].flags = __EXEC_OBJECT_HAS_PIN;
 	eb->batch = &eb->vma[eb->buffer_count++];
+	eb->vma[eb->buffer_count].vma = NULL;
 
 	eb->trampoline = trampoline;
 	eb->batch_start_offset = 0;
@@ -2348,9 +2432,7 @@ static void eb_request_add(struct i915_execbuffer *eb)
 		__i915_request_skip(rq);
 	}
 
-	local_bh_disable();
 	__i915_request_queue(rq, &attr);
-	local_bh_enable(); /* Kick the execlists tasklet if just scheduled */
 
 	/* Try to clean up the client's timeline after submitting the request */
 	if (prev)
@@ -2386,8 +2468,6 @@ i915_gem_do_execbuffer(struct drm_device *dev,
 		args->flags |= __EXEC_HAS_RELOC;
 
 	eb.exec = exec;
-	eb.vma = (struct eb_vma *)(exec + args->buffer_count + 1);
-	eb.vma[0].vma = NULL;
 
 	eb.invalid_flags = __EXEC_OBJECT_UNKNOWN_FLAGS;
 	reloc_cache_init(&eb.reloc_cache, eb.i915);
@@ -2594,8 +2674,6 @@ i915_gem_do_execbuffer(struct drm_device *dev,
 	if (batch->private)
 		intel_engine_pool_put(batch->private);
 err_vma:
-	if (eb.exec)
-		eb_release_vmas(&eb);
 	if (eb.trampoline)
 		i915_vma_unpin(eb.trampoline);
 	eb_unpin_engine(&eb);
@@ -2615,7 +2693,7 @@ i915_gem_do_execbuffer(struct drm_device *dev,
 
 static size_t eb_element_size(void)
 {
-	return sizeof(struct drm_i915_gem_exec_object2) + sizeof(struct eb_vma);
+	return sizeof(struct drm_i915_gem_exec_object2);
 }
 
 static bool check_buffer_count(size_t count)
@@ -2671,7 +2749,7 @@ i915_gem_execbuffer_ioctl(struct drm_device *dev, void *data,
 	/* Copy in the exec list from userland */
 	exec_list = kvmalloc_array(count, sizeof(*exec_list),
 				   __GFP_NOWARN | GFP_KERNEL);
-	exec2_list = kvmalloc_array(count + 1, eb_element_size(),
+	exec2_list = kvmalloc_array(count, eb_element_size(),
 				    __GFP_NOWARN | GFP_KERNEL);
 	if (exec_list == NULL || exec2_list == NULL) {
 		drm_dbg(&i915->drm,
@@ -2749,8 +2827,7 @@ i915_gem_execbuffer2_ioctl(struct drm_device *dev, void *data,
 	if (err)
 		return err;
 
-	/* Allocate an extra slot for use by the command parser */
-	exec2_list = kvmalloc_array(count + 1, eb_element_size(),
+	exec2_list = kvmalloc_array(count, eb_element_size(),
 				    __GFP_NOWARN | GFP_KERNEL);
 	if (exec2_list == NULL) {
 		drm_dbg(&i915->drm, "Failed to allocate exec list for %zd buffers\n",
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c
index 5da9f9e534b9..3f01cdd1a39b 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
@@ -206,7 +206,6 @@ static void __i915_gem_free_objects(struct drm_i915_private *i915,
 		}
 		obj->mmo.offsets = RB_ROOT;
 
-		GEM_BUG_ON(atomic_read(&obj->bind_count));
 		GEM_BUG_ON(obj->userfault_count);
 		GEM_BUG_ON(!list_empty(&obj->lut_list));
 
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
index a0b10bcd8d8a..54ee658bb168 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
@@ -179,9 +179,6 @@ struct drm_i915_gem_object {
 #define TILING_MASK (FENCE_MINIMUM_STRIDE - 1)
 #define STRIDE_MASK (~TILING_MASK)
 
-	/** Count of VMA actually bound by this object */
-	atomic_t bind_count;
-
 	struct {
 		/*
 		 * Protects the pages and their use. Do not use directly, but
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
index 24f4cadea114..5d855fcd5c0f 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
@@ -199,8 +199,6 @@ int __i915_gem_object_put_pages(struct drm_i915_gem_object *obj)
 	if (i915_gem_object_has_pinned_pages(obj))
 		return -EBUSY;
 
-	GEM_BUG_ON(atomic_read(&obj->bind_count));
-
 	/* May be called by shrinker from within get_pages() (on another bo) */
 	mutex_lock(&obj->mm.lock);
 	if (unlikely(atomic_read(&obj->mm.pages_pin_count))) {
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_phys.c b/drivers/gpu/drm/i915/gem/i915_gem_phys.c
index 698e22420dc5..7fe9831aa9ba 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_phys.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_phys.c
@@ -10,8 +10,6 @@
 
 #include <drm/drm.h> /* for drm_legacy.h! */
 #include <drm/drm_cache.h>
-#include <drm/drm_legacy.h> /* for drm_pci.h! */
-#include <drm/drm_pci.h>
 
 #include "gt/intel_gt.h"
 #include "i915_drv.h"
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
index 03e5eb4c99d1..5b65ce738b16 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
@@ -26,18 +26,6 @@ static bool can_release_pages(struct drm_i915_gem_object *obj)
 	if (!i915_gem_object_is_shrinkable(obj))
 		return false;
 
-	/*
-	 * Only report true if by unbinding the object and putting its pages
-	 * we can actually make forward progress towards freeing physical
-	 * pages.
-	 *
-	 * If the pages are pinned for any other reason than being bound
-	 * to the GPU, simply unbinding from the GPU is not going to succeed
-	 * in releasing our pin count on the pages themselves.
-	 */
-	if (atomic_read(&obj->mm.pages_pin_count) > atomic_read(&obj->bind_count))
-		return false;
-
 	/*
 	 * We can only return physical pages to the system if we can either
 	 * discard the contents (because the user has marked them as being
@@ -54,6 +42,8 @@ static bool unsafe_drop_pages(struct drm_i915_gem_object *obj,
 	flags = 0;
 	if (shrink & I915_SHRINK_ACTIVE)
 		flags = I915_GEM_OBJECT_UNBIND_ACTIVE;
+	if (!(shrink & I915_SHRINK_BOUND))
+		flags = I915_GEM_OBJECT_UNBIND_TEST;
 
 	if (i915_gem_object_unbind(obj, flags) == 0)
 		__i915_gem_object_put_pages(obj);
@@ -194,10 +184,6 @@ i915_gem_shrink(struct drm_i915_private *i915,
 			    i915_gem_object_is_framebuffer(obj))
 				continue;
 
-			if (!(shrink & I915_SHRINK_BOUND) &&
-			    atomic_read(&obj->bind_count))
-				continue;
-
 			if (!can_release_pages(obj))
 				continue;
 
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
index 5557dfa83a7b..dc250278bd2c 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
@@ -381,14 +381,14 @@ static int i915_gem_init_stolen(struct drm_i915_private *i915)
 	mutex_init(&i915->mm.stolen_lock);
 
 	if (intel_vgpu_active(i915)) {
-		dev_notice(i915->drm.dev,
+		drm_notice(&i915->drm,
 			   "%s, disabling use of stolen memory\n",
 			   "iGVT-g active");
 		return 0;
 	}
 
 	if (intel_vtd_active() && INTEL_GEN(i915) < 8) {
-		dev_notice(i915->drm.dev,
+		drm_notice(&i915->drm,
 			   "%s, disabling use of stolen memory\n",
 			   "DMAR active");
 		return 0;
diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_gem_object.c b/drivers/gpu/drm/i915/gem/selftests/huge_gem_object.c
index fa16f2c3f3ac..2b46c6530da9 100644
--- a/drivers/gpu/drm/i915/gem/selftests/huge_gem_object.c
+++ b/drivers/gpu/drm/i915/gem/selftests/huge_gem_object.c
@@ -88,8 +88,7 @@ static void huge_put_pages(struct drm_i915_gem_object *obj,
 }
 
 static const struct drm_i915_gem_object_ops huge_ops = {
-	.flags = I915_GEM_OBJECT_HAS_STRUCT_PAGE |
-		 I915_GEM_OBJECT_IS_SHRINKABLE,
+	.flags = I915_GEM_OBJECT_HAS_STRUCT_PAGE,
 	.get_pages = huge_get_pages,
 	.put_pages = huge_put_pages,
 };
diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c
index 54b86cf7f5d2..f4f933240b39 100644
--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c
@@ -1925,7 +1925,7 @@ static int mock_context_barrier(void *arg)
 		goto out;
 	}
 
-	rq = igt_request_alloc(ctx, i915->engine[RCS0]);
+	rq = igt_request_alloc(ctx, i915->gt.engine[RCS0]);
 	if (IS_ERR(rq)) {
 		pr_err("Request allocation failed!\n");
 		goto out;
diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
index 43912e9b683d..ef7abcb3f4ee 100644
--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
@@ -1156,9 +1156,6 @@ static int __igt_mmap_revoke(struct drm_i915_private *i915,
 	if (err)
 		goto out_unmap;
 
-	GEM_BUG_ON(mmo->mmap_type == I915_MMAP_TYPE_GTT &&
-		   !atomic_read(&obj->bind_count));
-
 	err = check_present(addr, obj->base.size);
 	if (err) {
 		pr_err("%s: was not present\n", obj->mm.region->name);
@@ -1175,7 +1172,6 @@ static int __igt_mmap_revoke(struct drm_i915_private *i915,
 		pr_err("Failed to unbind object!\n");
 		goto out_unmap;
 	}
-	GEM_BUG_ON(atomic_read(&obj->bind_count));
 
 	if (type != I915_MMAP_TYPE_GTT) {
 		__i915_gem_object_put_pages(obj);
diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_object.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_object.c
index 2b6db6f799de..faa5b6d91795 100644
--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_object.c
+++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_object.c
@@ -14,7 +14,7 @@ static int igt_gem_object(void *arg)
 {
 	struct drm_i915_private *i915 = arg;
 	struct drm_i915_gem_object *obj;
-	int err = -ENOMEM;
+	int err;
 
 	/* Basic test to ensure we can create an object */
 
diff --git a/drivers/gpu/drm/i915/gt/debugfs_engines.c b/drivers/gpu/drm/i915/gt/debugfs_engines.c
index 6a5e9ab20b94..5e3725e62241 100644
--- a/drivers/gpu/drm/i915/gt/debugfs_engines.c
+++ b/drivers/gpu/drm/i915/gt/debugfs_engines.c
@@ -32,5 +32,5 @@ void debugfs_engines_register(struct intel_gt *gt, struct dentry *root)
 		{ "engines", &engines_fops },
 	};
 
-	debugfs_gt_register_files(gt, root, files, ARRAY_SIZE(files));
+	intel_gt_debugfs_register_files(root, files, ARRAY_SIZE(files), gt);
 }
diff --git a/drivers/gpu/drm/i915/gt/debugfs_gt.c b/drivers/gpu/drm/i915/gt/debugfs_gt.c
index 75255aaacaed..1de5fbaa1cf9 100644
--- a/drivers/gpu/drm/i915/gt/debugfs_gt.c
+++ b/drivers/gpu/drm/i915/gt/debugfs_gt.c
@@ -9,6 +9,7 @@
 #include "debugfs_engines.h"
 #include "debugfs_gt.h"
 #include "debugfs_gt_pm.h"
+#include "uc/intel_uc_debugfs.h"
 #include "i915_drv.h"
 
 void debugfs_gt_register(struct intel_gt *gt)
@@ -24,17 +25,19 @@ void debugfs_gt_register(struct intel_gt *gt)
 
 	debugfs_engines_register(gt, root);
 	debugfs_gt_pm_register(gt, root);
+
+	intel_uc_debugfs_register(&gt->uc, root);
 }
 
-void debugfs_gt_register_files(struct intel_gt *gt,
-			       struct dentry *root,
-			       const struct debugfs_gt_file *files,
-			       unsigned long count)
+void intel_gt_debugfs_register_files(struct dentry *root,
+				     const struct debugfs_gt_file *files,
+				     unsigned long count, void *data)
 {
 	while (count--) {
-		if (!files->eval || files->eval(gt))
+		umode_t mode = files->fops->write ? 0644 : 0444;
+		if (!files->eval || files->eval(data))
 			debugfs_create_file(files->name,
-					    0444, root, gt,
+					    mode, root, data,
 					    files->fops);
 
 		files++;
diff --git a/drivers/gpu/drm/i915/gt/debugfs_gt.h b/drivers/gpu/drm/i915/gt/debugfs_gt.h
index 4ea0f06cda8f..f77540f727e9 100644
--- a/drivers/gpu/drm/i915/gt/debugfs_gt.h
+++ b/drivers/gpu/drm/i915/gt/debugfs_gt.h
@@ -28,12 +28,11 @@ void debugfs_gt_register(struct intel_gt *gt);
 struct debugfs_gt_file {
 	const char *name;
 	const struct file_operations *fops;
-	bool (*eval)(const struct intel_gt *gt);
+	bool (*eval)(void *data);
 };
 
-void debugfs_gt_register_files(struct intel_gt *gt,
-			       struct dentry *root,
-			       const struct debugfs_gt_file *files,
-			       unsigned long count);
+void intel_gt_debugfs_register_files(struct dentry *root,
+				     const struct debugfs_gt_file *files,
+				     unsigned long count, void *data);
 
 #endif /* DEBUGFS_GT_H */
diff --git a/drivers/gpu/drm/i915/gt/debugfs_gt_pm.c b/drivers/gpu/drm/i915/gt/debugfs_gt_pm.c
index 059c9e5c002e..aab30d908072 100644
--- a/drivers/gpu/drm/i915/gt/debugfs_gt_pm.c
+++ b/drivers/gpu/drm/i915/gt/debugfs_gt_pm.c
@@ -506,8 +506,10 @@ static int llc_show(struct seq_file *m, void *data)
 	return 0;
 }
 
-static bool llc_eval(const struct intel_gt *gt)
+static bool llc_eval(void *data)
 {
+	struct intel_gt *gt = data;
+
 	return HAS_LLC(gt->i915);
 }
 
@@ -580,8 +582,10 @@ static int rps_boost_show(struct seq_file *m, void *data)
 	return 0;
 }
 
-static bool rps_eval(const struct intel_gt *gt)
+static bool rps_eval(void *data)
 {
+	struct intel_gt *gt = data;
+
 	return HAS_RPS(gt->i915);
 }
 
@@ -597,5 +601,5 @@ void debugfs_gt_pm_register(struct intel_gt *gt, struct dentry *root)
 		{ "rps_boost", &rps_boost_fops, rps_eval },
 	};
 
-	debugfs_gt_register_files(gt, root, files, ARRAY_SIZE(files));
+	intel_gt_debugfs_register_files(root, files, ARRAY_SIZE(files), gt);
 }
diff --git a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
index cbad7fe722ce..cbedba857d43 100644
--- a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
+++ b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
@@ -64,7 +64,7 @@ static void __intel_breadcrumbs_disarm_irq(struct intel_breadcrumbs *b)
 	if (!--b->irq_enabled)
 		irq_disable(engine);
 
-	b->irq_armed = false;
+	WRITE_ONCE(b->irq_armed, false);
 	intel_gt_pm_put_async(engine->gt);
 }
 
@@ -73,7 +73,7 @@ void intel_engine_disarm_breadcrumbs(struct intel_engine_cs *engine)
 	struct intel_breadcrumbs *b = &engine->breadcrumbs;
 	unsigned long flags;
 
-	if (!b->irq_armed)
+	if (!READ_ONCE(b->irq_armed))
 		return;
 
 	spin_lock_irqsave(&b->irq_lock, flags);
@@ -233,7 +233,7 @@ static bool __intel_breadcrumbs_arm_irq(struct intel_breadcrumbs *b)
 	 * which we can add a new waiter and avoid the cost of re-enabling
 	 * the irq.
 	 */
-	b->irq_armed = true;
+	WRITE_ONCE(b->irq_armed, true);
 
 	/*
 	 * Since we are waiting on a request, the GPU should be busy
diff --git a/drivers/gpu/drm/i915/gt/intel_context.c b/drivers/gpu/drm/i915/gt/intel_context.c
index aea992e46c42..74ddb49b2941 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -114,6 +114,11 @@ int __intel_context_do_pin(struct intel_context *ce)
 		goto out_release;
 	}
 
+	if (unlikely(intel_context_is_closed(ce))) {
+		err = -ENOENT;
+		goto out_unlock;
+	}
+
 	if (likely(!atomic_add_unless(&ce->pin_count, 1, 0))) {
 		err = intel_context_active_acquire(ce);
 		if (unlikely(err))
diff --git a/drivers/gpu/drm/i915/gt/intel_engine.h b/drivers/gpu/drm/i915/gt/intel_engine.h
index b469de0dd9b6..d9ee64e2ef79 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine.h
@@ -199,6 +199,8 @@ void intel_engine_cleanup(struct intel_engine_cs *engine);
 int intel_engines_init_mmio(struct intel_gt *gt);
 int intel_engines_init(struct intel_gt *gt);
 
+void intel_engine_free_request_pool(struct intel_engine_cs *engine);
+
 void intel_engines_release(struct intel_gt *gt);
 void intel_engines_free(struct intel_gt *gt);
 
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
index 3aa8a652c16d..b1f8527f02c8 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -347,8 +347,6 @@ static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id)
 	gt->engine_class[info->class][info->instance] = engine;
 	gt->engine[id] = engine;
 
-	i915->engine[id] = engine;
-
 	return 0;
 }
 
@@ -425,17 +423,27 @@ void intel_engines_release(struct intel_gt *gt)
 		engine->release = NULL;
 
 		memset(&engine->reset, 0, sizeof(engine->reset));
-
-		gt->i915->engine[id] = NULL;
 	}
 }
 
+void intel_engine_free_request_pool(struct intel_engine_cs *engine)
+{
+	if (!engine->request_pool)
+		return;
+
+	kmem_cache_free(i915_request_slab_cache(), engine->request_pool);
+}
+
 void intel_engines_free(struct intel_gt *gt)
 {
 	struct intel_engine_cs *engine;
 	enum intel_engine_id id;
 
+	/* Free the requests! dma-resv keeps fences around for an eternity */
+	rcu_barrier();
+
 	for_each_engine(engine, gt, id) {
+		intel_engine_free_request_pool(engine);
 		kfree(engine);
 		gt->engine[id] = NULL;
 	}
@@ -1225,6 +1233,49 @@ static void print_request(struct drm_printer *m,
 		   name);
 }
 
+static struct intel_timeline *get_timeline(struct i915_request *rq)
+{
+	struct intel_timeline *tl;
+
+	/*
+	 * Even though we are holding the engine->active.lock here, there
+	 * is no control over the submission queue per-se and we are
+	 * inspecting the active state at a random point in time, with an
+	 * unknown queue. Play safe and make sure the timeline remains valid.
+	 * (Only being used for pretty printing, one extra kref shouldn't
+	 * cause a camel stampede!)
+	 */
+	rcu_read_lock();
+	tl = rcu_dereference(rq->timeline);
+	if (!kref_get_unless_zero(&tl->kref))
+		tl = NULL;
+	rcu_read_unlock();
+
+	return tl;
+}
+
+static int print_ring(char *buf, int sz, struct i915_request *rq)
+{
+	int len = 0;
+
+	if (!i915_request_signaled(rq)) {
+		struct intel_timeline *tl = get_timeline(rq);
+
+		len = scnprintf(buf, sz,
+				"ring:{start:%08x, hwsp:%08x, seqno:%08x, runtime:%llums}, ",
+				i915_ggtt_offset(rq->ring->vma),
+				tl ? tl->hwsp_offset : 0,
+				hwsp_seqno(rq),
+				DIV_ROUND_CLOSEST_ULL(intel_context_get_total_runtime_ns(rq->context),
+						      1000 * 1000));
+
+		if (tl)
+			intel_timeline_put(tl);
+	}
+
+	return len;
+}
+
 static void hexdump(struct drm_printer *m, const void *buf, size_t len)
 {
 	const size_t rowsize = 8 * sizeof(u32);
@@ -1254,27 +1305,6 @@ static void hexdump(struct drm_printer *m, const void *buf, size_t len)
 	}
 }
 
-static struct intel_timeline *get_timeline(struct i915_request *rq)
-{
-	struct intel_timeline *tl;
-
-	/*
-	 * Even though we are holding the engine->active.lock here, there
-	 * is no control over the submission queue per-se and we are
-	 * inspecting the active state at a random point in time, with an
-	 * unknown queue. Play safe and make sure the timeline remains valid.
-	 * (Only being used for pretty printing, one extra kref shouldn't
-	 * cause a camel stampede!)
-	 */
-	rcu_read_lock();
-	tl = rcu_dereference(rq->timeline);
-	if (!kref_get_unless_zero(&tl->kref))
-		tl = NULL;
-	rcu_read_unlock();
-
-	return tl;
-}
-
 static const char *repr_timer(const struct timer_list *t)
 {
 	if (!READ_ONCE(t->expires))
@@ -1295,6 +1325,12 @@ static void intel_engine_print_registers(struct intel_engine_cs *engine,
 
 	if (engine->id == RENDER_CLASS && IS_GEN_RANGE(dev_priv, 4, 7))
 		drm_printf(m, "\tCCID: 0x%08x\n", ENGINE_READ(engine, CCID));
+	if (HAS_EXECLISTS(dev_priv)) {
+		drm_printf(m, "\tEL_STAT_HI: 0x%08x\n",
+			   ENGINE_READ(engine, RING_EXECLIST_STATUS_HI));
+		drm_printf(m, "\tEL_STAT_LO: 0x%08x\n",
+			   ENGINE_READ(engine, RING_EXECLIST_STATUS_LO));
+	}
 	drm_printf(m, "\tRING_START: 0x%08x\n",
 		   ENGINE_READ(engine, RING_START));
 	drm_printf(m, "\tRING_HEAD:  0x%08x\n",
@@ -1387,39 +1423,24 @@ static void intel_engine_print_registers(struct intel_engine_cs *engine,
 			int len;
 
 			len = scnprintf(hdr, sizeof(hdr),
-					"\t\tActive[%d]: ",
-					(int)(port - execlists->active));
-			if (!i915_request_signaled(rq)) {
-				struct intel_timeline *tl = get_timeline(rq);
-
-				len += scnprintf(hdr + len, sizeof(hdr) - len,
-						 "ring:{start:%08x, hwsp:%08x, seqno:%08x, runtime:%llums}, ",
-						 i915_ggtt_offset(rq->ring->vma),
-						 tl ? tl->hwsp_offset : 0,
-						 hwsp_seqno(rq),
-						 DIV_ROUND_CLOSEST_ULL(intel_context_get_total_runtime_ns(rq->context),
-								       1000 * 1000));
-
-				if (tl)
-					intel_timeline_put(tl);
-			}
+					"\t\tActive[%d]:  ccid:%08x, ",
+					(int)(port - execlists->active),
+					upper_32_bits(rq->context->lrc_desc));
+			len += print_ring(hdr + len, sizeof(hdr) - len, rq);
 			scnprintf(hdr + len, sizeof(hdr) - len, "rq: ");
 			print_request(m, rq, hdr);
 		}
 		for (port = execlists->pending; (rq = *port); port++) {
-			struct intel_timeline *tl = get_timeline(rq);
-			char hdr[80];
-
-			snprintf(hdr, sizeof(hdr),
-				 "\t\tPending[%d] ring:{start:%08x, hwsp:%08x, seqno:%08x}, rq: ",
-				 (int)(port - execlists->pending),
-				 i915_ggtt_offset(rq->ring->vma),
-				 tl ? tl->hwsp_offset : 0,
-				 hwsp_seqno(rq));
-			print_request(m, rq, hdr);
+			char hdr[160];
+			int len;
 
-			if (tl)
-				intel_timeline_put(tl);
+			len = scnprintf(hdr, sizeof(hdr),
+					"\t\tPending[%d]: ccid:%08x, ",
+					(int)(port - execlists->pending),
+					upper_32_bits(rq->context->lrc_desc));
+			len += print_ring(hdr + len, sizeof(hdr) - len, rq);
+			scnprintf(hdr + len, sizeof(hdr) - len, "rq: ");
+			print_request(m, rq, hdr);
 		}
 		rcu_read_unlock();
 		execlists_active_unlock_bh(execlists);
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_heartbeat.c b/drivers/gpu/drm/i915/gt/intel_engine_heartbeat.c
index dd825718e4e5..5136c8bf112d 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_heartbeat.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_heartbeat.c
@@ -31,7 +31,7 @@ static bool next_heartbeat(struct intel_engine_cs *engine)
 	delay = msecs_to_jiffies_timeout(delay);
 	if (delay >= HZ)
 		delay = round_jiffies_up_relative(delay);
-	schedule_delayed_work(&engine->heartbeat.work, delay);
+	mod_delayed_work(system_wq, &engine->heartbeat.work, delay);
 
 	return true;
 }
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_pm.c b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
index b6cf284e3a2d..3be679741d22 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
@@ -181,7 +181,7 @@ static bool switch_to_kernel_context(struct intel_engine_cs *engine)
 	 * Ergo, if we put ourselves on the timelines.active_list
 	 * (se intel_timeline_enter()) before we increment the
 	 * engine->wakeref.count, we may see the request completion and retire
-	 * it causing an undeflow of the engine->wakeref.
+	 * it causing an underflow of the engine->wakeref.
 	 */
 	flags = __timeline_mark_lock(ce);
 	GEM_BUG_ON(atomic_read(&ce->timeline->active_count) < 0);
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_pm.h b/drivers/gpu/drm/i915/gt/intel_engine_pm.h
index e52c2b0cb245..418df0a13145 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_pm.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine_pm.h
@@ -37,6 +37,12 @@ static inline void intel_engine_pm_put_async(struct intel_engine_cs *engine)
 	intel_wakeref_put_async(&engine->wakeref);
 }
 
+static inline void intel_engine_pm_put_delay(struct intel_engine_cs *engine,
+					     unsigned long delay)
+{
+	intel_wakeref_put_delay(&engine->wakeref, delay);
+}
+
 static inline void intel_engine_pm_flush(struct intel_engine_cs *engine)
 {
 	intel_wakeref_unlock_wait(&engine->wakeref);
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h b/drivers/gpu/drm/i915/gt/intel_engine_types.h
index 80cdde712842..01d4bd781a2f 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
@@ -156,6 +156,15 @@ struct intel_engine_execlists {
 	 */
 	struct i915_priolist default_priolist;
 
+	/**
+	 * @yield: CCID at the time of the last semaphore-wait interrupt.
+	 *
+	 * Instead of leaving a semaphore busy-spinning on an engine, we would
+	 * like to switch to another ready context, i.e. yielding the semaphore
+	 * timeslice.
+	 */
+	u32 yield;
+
 	/**
 	 * @error_interrupt: CS Master EIR
 	 *
@@ -308,6 +317,9 @@ struct intel_engine_cs {
 		struct list_head hold; /* ready requests, but on hold */
 	} active;
 
+	/* keep a request in reserve for a [pm] barrier under oom */
+	struct i915_request *request_pool;
+
 	struct llist_head barrier_tasks;
 
 	struct intel_context *kernel_context; /* pinned */
diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c
index 4c5a209cb669..eebd1190506f 100644
--- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
@@ -65,7 +65,7 @@ static int ggtt_init_hw(struct i915_ggtt *ggtt)
 					      ggtt->mappable_end);
 	}
 
-	i915_ggtt_init_fences(ggtt);
+	intel_ggtt_init_fences(ggtt);
 
 	return 0;
 }
@@ -715,11 +715,13 @@ static void ggtt_cleanup_hw(struct i915_ggtt *ggtt)
  */
 void i915_ggtt_driver_release(struct drm_i915_private *i915)
 {
+	struct i915_ggtt *ggtt = &i915->ggtt;
 	struct pagevec *pvec;
 
-	fini_aliasing_ppgtt(&i915->ggtt);
+	fini_aliasing_ppgtt(ggtt);
 
-	ggtt_cleanup_hw(&i915->ggtt);
+	intel_ggtt_fini_fences(ggtt);
+	ggtt_cleanup_hw(ggtt);
 
 	pvec = &i915->mm.wc_stash.pvec;
 	if (pvec->nr) {
@@ -784,13 +786,13 @@ static int ggtt_probe_common(struct i915_ggtt *ggtt, u64 size)
 	else
 		ggtt->gsm = ioremap_wc(phys_addr, size);
 	if (!ggtt->gsm) {
-		DRM_ERROR("Failed to map the ggtt page table\n");
+		drm_err(&i915->drm, "Failed to map the ggtt page table\n");
 		return -ENOMEM;
 	}
 
 	ret = setup_scratch_page(&ggtt->vm, GFP_DMA32);
 	if (ret) {
-		DRM_ERROR("Scratch setup failed\n");
+		drm_err(&i915->drm, "Scratch setup failed\n");
 		/* iounmap will also get called at remove, but meh */
 		iounmap(ggtt->gsm);
 		return ret;
@@ -850,7 +852,8 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt)
 	if (!err)
 		err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(39));
 	if (err)
-		DRM_ERROR("Can't set DMA mask/consistent mask (%d)\n", err);
+		drm_err(&i915->drm,
+			"Can't set DMA mask/consistent mask (%d)\n", err);
 
 	pci_read_config_word(pdev, SNB_GMCH_CTRL, &snb_gmch_ctl);
 	if (IS_CHERRYVIEW(i915))
@@ -997,7 +1000,8 @@ static int gen6_gmch_probe(struct i915_ggtt *ggtt)
 	 * just a coarse sanity check.
 	 */
 	if (ggtt->mappable_end < (64<<20) || ggtt->mappable_end > (512<<20)) {
-		DRM_ERROR("Unknown GMADR size (%pa)\n", &ggtt->mappable_end);
+		drm_err(&i915->drm, "Unknown GMADR size (%pa)\n",
+			&ggtt->mappable_end);
 		return -ENXIO;
 	}
 
@@ -1005,7 +1009,8 @@ static int gen6_gmch_probe(struct i915_ggtt *ggtt)
 	if (!err)
 		err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(40));
 	if (err)
-		DRM_ERROR("Can't set DMA mask/consistent mask (%d)\n", err);
+		drm_err(&i915->drm,
+			"Can't set DMA mask/consistent mask (%d)\n", err);
 	pci_read_config_word(pdev, SNB_GMCH_CTRL, &snb_gmch_ctl);
 
 	size = gen6_get_total_gtt_size(snb_gmch_ctl);
@@ -1052,7 +1057,7 @@ static int i915_gmch_probe(struct i915_ggtt *ggtt)
 
 	ret = intel_gmch_probe(i915->bridge_dev, i915->drm.pdev, NULL);
 	if (!ret) {
-		DRM_ERROR("failed to set up gmch\n");
+		drm_err(&i915->drm, "failed to set up gmch\n");
 		return -EIO;
 	}
 
@@ -1075,7 +1080,7 @@ static int i915_gmch_probe(struct i915_ggtt *ggtt)
 	ggtt->vm.vma_ops.clear_pages = clear_pages;
 
 	if (unlikely(ggtt->do_idle_maps))
-		dev_notice(i915->drm.dev,
+		drm_notice(&i915->drm,
 			   "Applying Ironlake quirks for intel_iommu\n");
 
 	return 0;
@@ -1100,26 +1105,29 @@ static int ggtt_probe_hw(struct i915_ggtt *ggtt, struct intel_gt *gt)
 		return ret;
 
 	if ((ggtt->vm.total - 1) >> 32) {
-		DRM_ERROR("We never expected a Global GTT with more than 32bits"
-			  " of address space! Found %lldM!\n",
-			  ggtt->vm.total >> 20);
+		drm_err(&i915->drm,
+			"We never expected a Global GTT with more than 32bits"
+			" of address space! Found %lldM!\n",
+			ggtt->vm.total >> 20);
 		ggtt->vm.total = 1ULL << 32;
 		ggtt->mappable_end =
 			min_t(u64, ggtt->mappable_end, ggtt->vm.total);
 	}
 
 	if (ggtt->mappable_end > ggtt->vm.total) {
-		DRM_ERROR("mappable aperture extends past end of GGTT,"
-			  " aperture=%pa, total=%llx\n",
-			  &ggtt->mappable_end, ggtt->vm.total);
+		drm_err(&i915->drm,
+			"mappable aperture extends past end of GGTT,"
+			" aperture=%pa, total=%llx\n",
+			&ggtt->mappable_end, ggtt->vm.total);
 		ggtt->mappable_end = ggtt->vm.total;
 	}
 
 	/* GMADR is the PCI mmio aperture into the global GTT. */
-	DRM_DEBUG_DRIVER("GGTT size = %lluM\n", ggtt->vm.total >> 20);
-	DRM_DEBUG_DRIVER("GMADR size = %lluM\n", (u64)ggtt->mappable_end >> 20);
-	DRM_DEBUG_DRIVER("DSM size = %lluM\n",
-			 (u64)resource_size(&intel_graphics_stolen_res) >> 20);
+	drm_dbg(&i915->drm, "GGTT size = %lluM\n", ggtt->vm.total >> 20);
+	drm_dbg(&i915->drm, "GMADR size = %lluM\n",
+		(u64)ggtt->mappable_end >> 20);
+	drm_dbg(&i915->drm, "DSM size = %lluM\n",
+		(u64)resource_size(&intel_graphics_stolen_res) >> 20);
 
 	return 0;
 }
@@ -1137,7 +1145,7 @@ int i915_ggtt_probe_hw(struct drm_i915_private *i915)
 		return ret;
 
 	if (intel_vtd_active())
-		dev_info(i915->drm.dev, "VT-d active for gfx access\n");
+		drm_info(&i915->drm, "VT-d active for gfx access\n");
 
 	return 0;
 }
@@ -1212,6 +1220,8 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 
 	if (INTEL_GEN(ggtt->vm.i915) >= 8)
 		setup_private_pat(ggtt->vm.gt->uncore);
+
+	intel_ggtt_restore_fences(ggtt);
 }
 
 static struct scatterlist *
diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c b/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c
new file mode 100644
index 000000000000..7fb36b12fe7a
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c
@@ -0,0 +1,909 @@
+/*
+ * Copyright © 2008-2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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 "i915_drv.h"
+#include "i915_scatterlist.h"
+#include "i915_pvinfo.h"
+#include "i915_vgpu.h"
+
+/**
+ * DOC: fence register handling
+ *
+ * Important to avoid confusions: "fences" in the i915 driver are not execution
+ * fences used to track command completion but hardware detiler objects which
+ * wrap a given range of the global GTT. Each platform has only a fairly limited
+ * set of these objects.
+ *
+ * Fences are used to detile GTT memory mappings. They're also connected to the
+ * hardware frontbuffer render tracking and hence interact with frontbuffer
+ * compression. Furthermore on older platforms fences are required for tiled
+ * objects used by the display engine. They can also be used by the render
+ * engine - they're required for blitter commands and are optional for render
+ * commands. But on gen4+ both display (with the exception of fbc) and rendering
+ * have their own tiling state bits and don't need fences.
+ *
+ * Also note that fences only support X and Y tiling and hence can't be used for
+ * the fancier new tiling formats like W, Ys and Yf.
+ *
+ * Finally note that because fences are such a restricted resource they're
+ * dynamically associated with objects. Furthermore fence state is committed to
+ * the hardware lazily to avoid unnecessary stalls on gen2/3. Therefore code must
+ * explicitly call i915_gem_object_get_fence() to synchronize fencing status
+ * for cpu access. Also note that some code wants an unfenced view, for those
+ * cases the fence can be removed forcefully with i915_gem_object_put_fence().
+ *
+ * Internally these functions will synchronize with userspace access by removing
+ * CPU ptes into GTT mmaps (not the GTT ptes themselves) as needed.
+ */
+
+#define pipelined 0
+
+static struct drm_i915_private *fence_to_i915(struct i915_fence_reg *fence)
+{
+	return fence->ggtt->vm.i915;
+}
+
+static struct intel_uncore *fence_to_uncore(struct i915_fence_reg *fence)
+{
+	return fence->ggtt->vm.gt->uncore;
+}
+
+static void i965_write_fence_reg(struct i915_fence_reg *fence)
+{
+	i915_reg_t fence_reg_lo, fence_reg_hi;
+	int fence_pitch_shift;
+	u64 val;
+
+	if (INTEL_GEN(fence_to_i915(fence)) >= 6) {
+		fence_reg_lo = FENCE_REG_GEN6_LO(fence->id);
+		fence_reg_hi = FENCE_REG_GEN6_HI(fence->id);
+		fence_pitch_shift = GEN6_FENCE_PITCH_SHIFT;
+
+	} else {
+		fence_reg_lo = FENCE_REG_965_LO(fence->id);
+		fence_reg_hi = FENCE_REG_965_HI(fence->id);
+		fence_pitch_shift = I965_FENCE_PITCH_SHIFT;
+	}
+
+	val = 0;
+	if (fence->tiling) {
+		unsigned int stride = fence->stride;
+
+		GEM_BUG_ON(!IS_ALIGNED(stride, 128));
+
+		val = fence->start + fence->size - I965_FENCE_PAGE;
+		val <<= 32;
+		val |= fence->start;
+		val |= (u64)((stride / 128) - 1) << fence_pitch_shift;
+		if (fence->tiling == I915_TILING_Y)
+			val |= BIT(I965_FENCE_TILING_Y_SHIFT);
+		val |= I965_FENCE_REG_VALID;
+	}
+
+	if (!pipelined) {
+		struct intel_uncore *uncore = fence_to_uncore(fence);
+
+		/*
+		 * To w/a incoherency with non-atomic 64-bit register updates,
+		 * we split the 64-bit update into two 32-bit writes. In order
+		 * for a partial fence not to be evaluated between writes, we
+		 * precede the update with write to turn off the fence register,
+		 * and only enable the fence as the last step.
+		 *
+		 * For extra levels of paranoia, we make sure each step lands
+		 * before applying the next step.
+		 */
+		intel_uncore_write_fw(uncore, fence_reg_lo, 0);
+		intel_uncore_posting_read_fw(uncore, fence_reg_lo);
+
+		intel_uncore_write_fw(uncore, fence_reg_hi, upper_32_bits(val));
+		intel_uncore_write_fw(uncore, fence_reg_lo, lower_32_bits(val));
+		intel_uncore_posting_read_fw(uncore, fence_reg_lo);
+	}
+}
+
+static void i915_write_fence_reg(struct i915_fence_reg *fence)
+{
+	u32 val;
+
+	val = 0;
+	if (fence->tiling) {
+		unsigned int stride = fence->stride;
+		unsigned int tiling = fence->tiling;
+		bool is_y_tiled = tiling == I915_TILING_Y;
+
+		if (is_y_tiled && HAS_128_BYTE_Y_TILING(fence_to_i915(fence)))
+			stride /= 128;
+		else
+			stride /= 512;
+		GEM_BUG_ON(!is_power_of_2(stride));
+
+		val = fence->start;
+		if (is_y_tiled)
+			val |= BIT(I830_FENCE_TILING_Y_SHIFT);
+		val |= I915_FENCE_SIZE_BITS(fence->size);
+		val |= ilog2(stride) << I830_FENCE_PITCH_SHIFT;
+
+		val |= I830_FENCE_REG_VALID;
+	}
+
+	if (!pipelined) {
+		struct intel_uncore *uncore = fence_to_uncore(fence);
+		i915_reg_t reg = FENCE_REG(fence->id);
+
+		intel_uncore_write_fw(uncore, reg, val);
+		intel_uncore_posting_read_fw(uncore, reg);
+	}
+}
+
+static void i830_write_fence_reg(struct i915_fence_reg *fence)
+{
+	u32 val;
+
+	val = 0;
+	if (fence->tiling) {
+		unsigned int stride = fence->stride;
+
+		val = fence->start;
+		if (fence->tiling == I915_TILING_Y)
+			val |= BIT(I830_FENCE_TILING_Y_SHIFT);
+		val |= I830_FENCE_SIZE_BITS(fence->size);
+		val |= ilog2(stride / 128) << I830_FENCE_PITCH_SHIFT;
+		val |= I830_FENCE_REG_VALID;
+	}
+
+	if (!pipelined) {
+		struct intel_uncore *uncore = fence_to_uncore(fence);
+		i915_reg_t reg = FENCE_REG(fence->id);
+
+		intel_uncore_write_fw(uncore, reg, val);
+		intel_uncore_posting_read_fw(uncore, reg);
+	}
+}
+
+static void fence_write(struct i915_fence_reg *fence)
+{
+	struct drm_i915_private *i915 = fence_to_i915(fence);
+
+	/*
+	 * Previous access through the fence register is marshalled by
+	 * the mb() inside the fault handlers (i915_gem_release_mmaps)
+	 * and explicitly managed for internal users.
+	 */
+
+	if (IS_GEN(i915, 2))
+		i830_write_fence_reg(fence);
+	else if (IS_GEN(i915, 3))
+		i915_write_fence_reg(fence);
+	else
+		i965_write_fence_reg(fence);
+
+	/*
+	 * Access through the fenced region afterwards is
+	 * ordered by the posting reads whilst writing the registers.
+	 */
+}
+
+static bool gpu_uses_fence_registers(struct i915_fence_reg *fence)
+{
+	return INTEL_GEN(fence_to_i915(fence)) < 4;
+}
+
+static int fence_update(struct i915_fence_reg *fence,
+			struct i915_vma *vma)
+{
+	struct i915_ggtt *ggtt = fence->ggtt;
+	struct intel_uncore *uncore = fence_to_uncore(fence);
+	intel_wakeref_t wakeref;
+	struct i915_vma *old;
+	int ret;
+
+	fence->tiling = 0;
+	if (vma) {
+		GEM_BUG_ON(!i915_gem_object_get_stride(vma->obj) ||
+			   !i915_gem_object_get_tiling(vma->obj));
+
+		if (!i915_vma_is_map_and_fenceable(vma))
+			return -EINVAL;
+
+		if (gpu_uses_fence_registers(fence)) {
+			/* implicit 'unfenced' GPU blits */
+			ret = i915_vma_sync(vma);
+			if (ret)
+				return ret;
+		}
+
+		fence->start = vma->node.start;
+		fence->size = vma->fence_size;
+		fence->stride = i915_gem_object_get_stride(vma->obj);
+		fence->tiling = i915_gem_object_get_tiling(vma->obj);
+	}
+	WRITE_ONCE(fence->dirty, false);
+
+	old = xchg(&fence->vma, NULL);
+	if (old) {
+		/* XXX Ideally we would move the waiting to outside the mutex */
+		ret = i915_active_wait(&fence->active);
+		if (ret) {
+			fence->vma = old;
+			return ret;
+		}
+
+		i915_vma_flush_writes(old);
+
+		/*
+		 * Ensure that all userspace CPU access is completed before
+		 * stealing the fence.
+		 */
+		if (old != vma) {
+			GEM_BUG_ON(old->fence != fence);
+			i915_vma_revoke_mmap(old);
+			old->fence = NULL;
+		}
+
+		list_move(&fence->link, &ggtt->fence_list);
+	}
+
+	/*
+	 * We only need to update the register itself if the device is awake.
+	 * If the device is currently powered down, we will defer the write
+	 * to the runtime resume, see intel_ggtt_restore_fences().
+	 *
+	 * This only works for removing the fence register, on acquisition
+	 * the caller must hold the rpm wakeref. The fence register must
+	 * be cleared before we can use any other fences to ensure that
+	 * the new fences do not overlap the elided clears, confusing HW.
+	 */
+	wakeref = intel_runtime_pm_get_if_in_use(uncore->rpm);
+	if (!wakeref) {
+		GEM_BUG_ON(vma);
+		return 0;
+	}
+
+	WRITE_ONCE(fence->vma, vma);
+	fence_write(fence);
+
+	if (vma) {
+		vma->fence = fence;
+		list_move_tail(&fence->link, &ggtt->fence_list);
+	}
+
+	intel_runtime_pm_put(uncore->rpm, wakeref);
+	return 0;
+}
+
+/**
+ * i915_vma_revoke_fence - force-remove fence for a VMA
+ * @vma: vma to map linearly (not through a fence reg)
+ *
+ * This function force-removes any fence from the given object, which is useful
+ * if the kernel wants to do untiled GTT access.
+ */
+void i915_vma_revoke_fence(struct i915_vma *vma)
+{
+	struct i915_fence_reg *fence = vma->fence;
+	intel_wakeref_t wakeref;
+
+	lockdep_assert_held(&vma->vm->mutex);
+	if (!fence)
+		return;
+
+	GEM_BUG_ON(fence->vma != vma);
+	GEM_BUG_ON(!i915_active_is_idle(&fence->active));
+	GEM_BUG_ON(atomic_read(&fence->pin_count));
+
+	fence->tiling = 0;
+	WRITE_ONCE(fence->vma, NULL);
+	vma->fence = NULL;
+
+	with_intel_runtime_pm_if_in_use(fence_to_uncore(fence)->rpm, wakeref)
+		fence_write(fence);
+}
+
+static struct i915_fence_reg *fence_find(struct i915_ggtt *ggtt)
+{
+	struct i915_fence_reg *fence;
+
+	list_for_each_entry(fence, &ggtt->fence_list, link) {
+		GEM_BUG_ON(fence->vma && fence->vma->fence != fence);
+
+		if (atomic_read(&fence->pin_count))
+			continue;
+
+		return fence;
+	}
+
+	/* Wait for completion of pending flips which consume fences */
+	if (intel_has_pending_fb_unpin(ggtt->vm.i915))
+		return ERR_PTR(-EAGAIN);
+
+	return ERR_PTR(-EDEADLK);
+}
+
+int __i915_vma_pin_fence(struct i915_vma *vma)
+{
+	struct i915_ggtt *ggtt = i915_vm_to_ggtt(vma->vm);
+	struct i915_fence_reg *fence;
+	struct i915_vma *set = i915_gem_object_is_tiled(vma->obj) ? vma : NULL;
+	int err;
+
+	lockdep_assert_held(&vma->vm->mutex);
+
+	/* Just update our place in the LRU if our fence is getting reused. */
+	if (vma->fence) {
+		fence = vma->fence;
+		GEM_BUG_ON(fence->vma != vma);
+		atomic_inc(&fence->pin_count);
+		if (!fence->dirty) {
+			list_move_tail(&fence->link, &ggtt->fence_list);
+			return 0;
+		}
+	} else if (set) {
+		fence = fence_find(ggtt);
+		if (IS_ERR(fence))
+			return PTR_ERR(fence);
+
+		GEM_BUG_ON(atomic_read(&fence->pin_count));
+		atomic_inc(&fence->pin_count);
+	} else {
+		return 0;
+	}
+
+	err = fence_update(fence, set);
+	if (err)
+		goto out_unpin;
+
+	GEM_BUG_ON(fence->vma != set);
+	GEM_BUG_ON(vma->fence != (set ? fence : NULL));
+
+	if (set)
+		return 0;
+
+out_unpin:
+	atomic_dec(&fence->pin_count);
+	return err;
+}
+
+/**
+ * i915_vma_pin_fence - set up fencing for a vma
+ * @vma: vma to map through a fence reg
+ *
+ * When mapping objects through the GTT, userspace wants to be able to write
+ * to them without having to worry about swizzling if the object is tiled.
+ * This function walks the fence regs looking for a free one for @obj,
+ * stealing one if it can't find any.
+ *
+ * It then sets up the reg based on the object's properties: address, pitch
+ * and tiling format.
+ *
+ * For an untiled surface, this removes any existing fence.
+ *
+ * Returns:
+ *
+ * 0 on success, negative error code on failure.
+ */
+int i915_vma_pin_fence(struct i915_vma *vma)
+{
+	int err;
+
+	if (!vma->fence && !i915_gem_object_is_tiled(vma->obj))
+		return 0;
+
+	/*
+	 * Note that we revoke fences on runtime suspend. Therefore the user
+	 * must keep the device awake whilst using the fence.
+	 */
+	assert_rpm_wakelock_held(vma->vm->gt->uncore->rpm);
+	GEM_BUG_ON(!i915_vma_is_pinned(vma));
+	GEM_BUG_ON(!i915_vma_is_ggtt(vma));
+
+	err = mutex_lock_interruptible(&vma->vm->mutex);
+	if (err)
+		return err;
+
+	err = __i915_vma_pin_fence(vma);
+	mutex_unlock(&vma->vm->mutex);
+
+	return err;
+}
+
+/**
+ * i915_reserve_fence - Reserve a fence for vGPU
+ * @ggtt: Global GTT
+ *
+ * This function walks the fence regs looking for a free one and remove
+ * it from the fence_list. It is used to reserve fence for vGPU to use.
+ */
+struct i915_fence_reg *i915_reserve_fence(struct i915_ggtt *ggtt)
+{
+	struct i915_fence_reg *fence;
+	int count;
+	int ret;
+
+	lockdep_assert_held(&ggtt->vm.mutex);
+
+	/* Keep at least one fence available for the display engine. */
+	count = 0;
+	list_for_each_entry(fence, &ggtt->fence_list, link)
+		count += !atomic_read(&fence->pin_count);
+	if (count <= 1)
+		return ERR_PTR(-ENOSPC);
+
+	fence = fence_find(ggtt);
+	if (IS_ERR(fence))
+		return fence;
+
+	if (fence->vma) {
+		/* Force-remove fence from VMA */
+		ret = fence_update(fence, NULL);
+		if (ret)
+			return ERR_PTR(ret);
+	}
+
+	list_del(&fence->link);
+
+	return fence;
+}
+
+/**
+ * i915_unreserve_fence - Reclaim a reserved fence
+ * @fence: the fence reg
+ *
+ * This function add a reserved fence register from vGPU to the fence_list.
+ */
+void i915_unreserve_fence(struct i915_fence_reg *fence)
+{
+	struct i915_ggtt *ggtt = fence->ggtt;
+
+	lockdep_assert_held(&ggtt->vm.mutex);
+
+	list_add(&fence->link, &ggtt->fence_list);
+}
+
+/**
+ * intel_ggtt_restore_fences - restore fence state
+ * @ggtt: Global GTT
+ *
+ * Restore the hw fence state to match the software tracking again, to be called
+ * after a gpu reset and on resume. Note that on runtime suspend we only cancel
+ * the fences, to be reacquired by the user later.
+ */
+void intel_ggtt_restore_fences(struct i915_ggtt *ggtt)
+{
+	int i;
+
+	for (i = 0; i < ggtt->num_fences; i++)
+		fence_write(&ggtt->fence_regs[i]);
+}
+
+/**
+ * DOC: tiling swizzling details
+ *
+ * The idea behind tiling is to increase cache hit rates by rearranging
+ * pixel data so that a group of pixel accesses are in the same cacheline.
+ * Performance improvement from doing this on the back/depth buffer are on
+ * the order of 30%.
+ *
+ * Intel architectures make this somewhat more complicated, though, by
+ * adjustments made to addressing of data when the memory is in interleaved
+ * mode (matched pairs of DIMMS) to improve memory bandwidth.
+ * For interleaved memory, the CPU sends every sequential 64 bytes
+ * to an alternate memory channel so it can get the bandwidth from both.
+ *
+ * The GPU also rearranges its accesses for increased bandwidth to interleaved
+ * memory, and it matches what the CPU does for non-tiled.  However, when tiled
+ * it does it a little differently, since one walks addresses not just in the
+ * X direction but also Y.  So, along with alternating channels when bit
+ * 6 of the address flips, it also alternates when other bits flip --  Bits 9
+ * (every 512 bytes, an X tile scanline) and 10 (every two X tile scanlines)
+ * are common to both the 915 and 965-class hardware.
+ *
+ * The CPU also sometimes XORs in higher bits as well, to improve
+ * bandwidth doing strided access like we do so frequently in graphics.  This
+ * is called "Channel XOR Randomization" in the MCH documentation.  The result
+ * is that the CPU is XORing in either bit 11 or bit 17 to bit 6 of its address
+ * decode.
+ *
+ * All of this bit 6 XORing has an effect on our memory management,
+ * as we need to make sure that the 3d driver can correctly address object
+ * contents.
+ *
+ * If we don't have interleaved memory, all tiling is safe and no swizzling is
+ * required.
+ *
+ * When bit 17 is XORed in, we simply refuse to tile at all.  Bit
+ * 17 is not just a page offset, so as we page an object out and back in,
+ * individual pages in it will have different bit 17 addresses, resulting in
+ * each 64 bytes being swapped with its neighbor!
+ *
+ * Otherwise, if interleaved, we have to tell the 3d driver what the address
+ * swizzling it needs to do is, since it's writing with the CPU to the pages
+ * (bit 6 and potentially bit 11 XORed in), and the GPU is reading from the
+ * pages (bit 6, 9, and 10 XORed in), resulting in a cumulative bit swizzling
+ * required by the CPU of XORing in bit 6, 9, 10, and potentially 11, in order
+ * to match what the GPU expects.
+ */
+
+/**
+ * detect_bit_6_swizzle - detect bit 6 swizzling pattern
+ * @ggtt: Global GGTT
+ *
+ * Detects bit 6 swizzling of address lookup between IGD access and CPU
+ * access through main memory.
+ */
+static void detect_bit_6_swizzle(struct i915_ggtt *ggtt)
+{
+	struct intel_uncore *uncore = ggtt->vm.gt->uncore;
+	struct drm_i915_private *i915 = ggtt->vm.i915;
+	u32 swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
+	u32 swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
+
+	if (INTEL_GEN(i915) >= 8 || IS_VALLEYVIEW(i915)) {
+		/*
+		 * On BDW+, swizzling is not used. We leave the CPU memory
+		 * controller in charge of optimizing memory accesses without
+		 * the extra address manipulation GPU side.
+		 *
+		 * VLV and CHV don't have GPU swizzling.
+		 */
+		swizzle_x = I915_BIT_6_SWIZZLE_NONE;
+		swizzle_y = I915_BIT_6_SWIZZLE_NONE;
+	} else if (INTEL_GEN(i915) >= 6) {
+		if (i915->preserve_bios_swizzle) {
+			if (intel_uncore_read(uncore, DISP_ARB_CTL) &
+			    DISP_TILE_SURFACE_SWIZZLING) {
+				swizzle_x = I915_BIT_6_SWIZZLE_9_10;
+				swizzle_y = I915_BIT_6_SWIZZLE_9;
+			} else {
+				swizzle_x = I915_BIT_6_SWIZZLE_NONE;
+				swizzle_y = I915_BIT_6_SWIZZLE_NONE;
+			}
+		} else {
+			u32 dimm_c0, dimm_c1;
+			dimm_c0 = intel_uncore_read(uncore, MAD_DIMM_C0);
+			dimm_c1 = intel_uncore_read(uncore, MAD_DIMM_C1);
+			dimm_c0 &= MAD_DIMM_A_SIZE_MASK | MAD_DIMM_B_SIZE_MASK;
+			dimm_c1 &= MAD_DIMM_A_SIZE_MASK | MAD_DIMM_B_SIZE_MASK;
+			/*
+			 * Enable swizzling when the channels are populated
+			 * with identically sized dimms. We don't need to check
+			 * the 3rd channel because no cpu with gpu attached
+			 * ships in that configuration. Also, swizzling only
+			 * makes sense for 2 channels anyway.
+			 */
+			if (dimm_c0 == dimm_c1) {
+				swizzle_x = I915_BIT_6_SWIZZLE_9_10;
+				swizzle_y = I915_BIT_6_SWIZZLE_9;
+			} else {
+				swizzle_x = I915_BIT_6_SWIZZLE_NONE;
+				swizzle_y = I915_BIT_6_SWIZZLE_NONE;
+			}
+		}
+	} else if (IS_GEN(i915, 5)) {
+		/*
+		 * On Ironlake whatever DRAM config, GPU always do
+		 * same swizzling setup.
+		 */
+		swizzle_x = I915_BIT_6_SWIZZLE_9_10;
+		swizzle_y = I915_BIT_6_SWIZZLE_9;
+	} else if (IS_GEN(i915, 2)) {
+		/*
+		 * As far as we know, the 865 doesn't have these bit 6
+		 * swizzling issues.
+		 */
+		swizzle_x = I915_BIT_6_SWIZZLE_NONE;
+		swizzle_y = I915_BIT_6_SWIZZLE_NONE;
+	} else if (IS_G45(i915) || IS_I965G(i915) || IS_G33(i915)) {
+		/*
+		 * The 965, G33, and newer, have a very flexible memory
+		 * configuration.  It will enable dual-channel mode
+		 * (interleaving) on as much memory as it can, and the GPU
+		 * will additionally sometimes enable different bit 6
+		 * swizzling for tiled objects from the CPU.
+		 *
+		 * Here's what I found on the G965:
+		 *    slot fill         memory size  swizzling
+		 * 0A   0B   1A   1B    1-ch   2-ch
+		 * 512  0    0    0     512    0     O
+		 * 512  0    512  0     16     1008  X
+		 * 512  0    0    512   16     1008  X
+		 * 0    512  0    512   16     1008  X
+		 * 1024 1024 1024 0     2048   1024  O
+		 *
+		 * We could probably detect this based on either the DRB
+		 * matching, which was the case for the swizzling required in
+		 * the table above, or from the 1-ch value being less than
+		 * the minimum size of a rank.
+		 *
+		 * Reports indicate that the swizzling actually
+		 * varies depending upon page placement inside the
+		 * channels, i.e. we see swizzled pages where the
+		 * banks of memory are paired and unswizzled on the
+		 * uneven portion, so leave that as unknown.
+		 */
+		if (intel_uncore_read(uncore, C0DRB3) ==
+		    intel_uncore_read(uncore, C1DRB3)) {
+			swizzle_x = I915_BIT_6_SWIZZLE_9_10;
+			swizzle_y = I915_BIT_6_SWIZZLE_9;
+		}
+	} else {
+		u32 dcc = intel_uncore_read(uncore, DCC);
+
+		/*
+		 * On 9xx chipsets, channel interleave by the CPU is
+		 * determined by DCC.  For single-channel, neither the CPU
+		 * nor the GPU do swizzling.  For dual channel interleaved,
+		 * the GPU's interleave is bit 9 and 10 for X tiled, and bit
+		 * 9 for Y tiled.  The CPU's interleave is independent, and
+		 * can be based on either bit 11 (haven't seen this yet) or
+		 * bit 17 (common).
+		 */
+		switch (dcc & DCC_ADDRESSING_MODE_MASK) {
+		case DCC_ADDRESSING_MODE_SINGLE_CHANNEL:
+		case DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC:
+			swizzle_x = I915_BIT_6_SWIZZLE_NONE;
+			swizzle_y = I915_BIT_6_SWIZZLE_NONE;
+			break;
+		case DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED:
+			if (dcc & DCC_CHANNEL_XOR_DISABLE) {
+				/*
+				 * This is the base swizzling by the GPU for
+				 * tiled buffers.
+				 */
+				swizzle_x = I915_BIT_6_SWIZZLE_9_10;
+				swizzle_y = I915_BIT_6_SWIZZLE_9;
+			} else if ((dcc & DCC_CHANNEL_XOR_BIT_17) == 0) {
+				/* Bit 11 swizzling by the CPU in addition. */
+				swizzle_x = I915_BIT_6_SWIZZLE_9_10_11;
+				swizzle_y = I915_BIT_6_SWIZZLE_9_11;
+			} else {
+				/* Bit 17 swizzling by the CPU in addition. */
+				swizzle_x = I915_BIT_6_SWIZZLE_9_10_17;
+				swizzle_y = I915_BIT_6_SWIZZLE_9_17;
+			}
+			break;
+		}
+
+		/* check for L-shaped memory aka modified enhanced addressing */
+		if (IS_GEN(i915, 4) &&
+		    !(intel_uncore_read(uncore, DCC2) & DCC2_MODIFIED_ENHANCED_DISABLE)) {
+			swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
+			swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
+		}
+
+		if (dcc == 0xffffffff) {
+			drm_err(&i915->drm, "Couldn't read from MCHBAR.  "
+				  "Disabling tiling.\n");
+			swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
+			swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
+		}
+	}
+
+	if (swizzle_x == I915_BIT_6_SWIZZLE_UNKNOWN ||
+	    swizzle_y == I915_BIT_6_SWIZZLE_UNKNOWN) {
+		/*
+		 * Userspace likes to explode if it sees unknown swizzling,
+		 * so lie. We will finish the lie when reporting through
+		 * the get-tiling-ioctl by reporting the physical swizzle
+		 * mode as unknown instead.
+		 *
+		 * As we don't strictly know what the swizzling is, it may be
+		 * bit17 dependent, and so we need to also prevent the pages
+		 * from being moved.
+		 */
+		i915->quirks |= QUIRK_PIN_SWIZZLED_PAGES;
+		swizzle_x = I915_BIT_6_SWIZZLE_NONE;
+		swizzle_y = I915_BIT_6_SWIZZLE_NONE;
+	}
+
+	i915->ggtt.bit_6_swizzle_x = swizzle_x;
+	i915->ggtt.bit_6_swizzle_y = swizzle_y;
+}
+
+/*
+ * Swap every 64 bytes of this page around, to account for it having a new
+ * bit 17 of its physical address and therefore being interpreted differently
+ * by the GPU.
+ */
+static void swizzle_page(struct page *page)
+{
+	char temp[64];
+	char *vaddr;
+	int i;
+
+	vaddr = kmap(page);
+
+	for (i = 0; i < PAGE_SIZE; i += 128) {
+		memcpy(temp, &vaddr[i], 64);
+		memcpy(&vaddr[i], &vaddr[i + 64], 64);
+		memcpy(&vaddr[i + 64], temp, 64);
+	}
+
+	kunmap(page);
+}
+
+/**
+ * i915_gem_object_do_bit_17_swizzle - fixup bit 17 swizzling
+ * @obj: i915 GEM buffer object
+ * @pages: the scattergather list of physical pages
+ *
+ * This function fixes up the swizzling in case any page frame number for this
+ * object has changed in bit 17 since that state has been saved with
+ * i915_gem_object_save_bit_17_swizzle().
+ *
+ * This is called when pinning backing storage again, since the kernel is free
+ * to move unpinned backing storage around (either by directly moving pages or
+ * by swapping them out and back in again).
+ */
+void
+i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj,
+				  struct sg_table *pages)
+{
+	struct sgt_iter sgt_iter;
+	struct page *page;
+	int i;
+
+	if (obj->bit_17 == NULL)
+		return;
+
+	i = 0;
+	for_each_sgt_page(page, sgt_iter, pages) {
+		char new_bit_17 = page_to_phys(page) >> 17;
+		if ((new_bit_17 & 0x1) != (test_bit(i, obj->bit_17) != 0)) {
+			swizzle_page(page);
+			set_page_dirty(page);
+		}
+		i++;
+	}
+}
+
+/**
+ * i915_gem_object_save_bit_17_swizzle - save bit 17 swizzling
+ * @obj: i915 GEM buffer object
+ * @pages: the scattergather list of physical pages
+ *
+ * This function saves the bit 17 of each page frame number so that swizzling
+ * can be fixed up later on with i915_gem_object_do_bit_17_swizzle(). This must
+ * be called before the backing storage can be unpinned.
+ */
+void
+i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj,
+				    struct sg_table *pages)
+{
+	const unsigned int page_count = obj->base.size >> PAGE_SHIFT;
+	struct sgt_iter sgt_iter;
+	struct page *page;
+	int i;
+
+	if (obj->bit_17 == NULL) {
+		obj->bit_17 = bitmap_zalloc(page_count, GFP_KERNEL);
+		if (obj->bit_17 == NULL) {
+			DRM_ERROR("Failed to allocate memory for bit 17 "
+				  "record\n");
+			return;
+		}
+	}
+
+	i = 0;
+
+	for_each_sgt_page(page, sgt_iter, pages) {
+		if (page_to_phys(page) & (1 << 17))
+			__set_bit(i, obj->bit_17);
+		else
+			__clear_bit(i, obj->bit_17);
+		i++;
+	}
+}
+
+void intel_ggtt_init_fences(struct i915_ggtt *ggtt)
+{
+	struct drm_i915_private *i915 = ggtt->vm.i915;
+	struct intel_uncore *uncore = ggtt->vm.gt->uncore;
+	int num_fences;
+	int i;
+
+	INIT_LIST_HEAD(&ggtt->fence_list);
+	INIT_LIST_HEAD(&ggtt->userfault_list);
+	intel_wakeref_auto_init(&ggtt->userfault_wakeref, uncore->rpm);
+
+	detect_bit_6_swizzle(ggtt);
+
+	if (!i915_ggtt_has_aperture(ggtt))
+		num_fences = 0;
+	else if (INTEL_GEN(i915) >= 7 &&
+		 !(IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)))
+		num_fences = 32;
+	else if (INTEL_GEN(i915) >= 4 ||
+		 IS_I945G(i915) || IS_I945GM(i915) ||
+		 IS_G33(i915) || IS_PINEVIEW(i915))
+		num_fences = 16;
+	else
+		num_fences = 8;
+
+	if (intel_vgpu_active(i915))
+		num_fences = intel_uncore_read(uncore,
+					       vgtif_reg(avail_rs.fence_num));
+	ggtt->fence_regs = kcalloc(num_fences,
+				   sizeof(*ggtt->fence_regs),
+				   GFP_KERNEL);
+	if (!ggtt->fence_regs)
+		num_fences = 0;
+
+	/* Initialize fence registers to zero */
+	for (i = 0; i < num_fences; i++) {
+		struct i915_fence_reg *fence = &ggtt->fence_regs[i];
+
+		i915_active_init(&fence->active, NULL, NULL);
+		fence->ggtt = ggtt;
+		fence->id = i;
+		list_add_tail(&fence->link, &ggtt->fence_list);
+	}
+	ggtt->num_fences = num_fences;
+
+	intel_ggtt_restore_fences(ggtt);
+}
+
+void intel_ggtt_fini_fences(struct i915_ggtt *ggtt)
+{
+	int i;
+
+	for (i = 0; i < ggtt->num_fences; i++) {
+		struct i915_fence_reg *fence = &ggtt->fence_regs[i];
+
+		i915_active_fini(&fence->active);
+	}
+
+	kfree(ggtt->fence_regs);
+}
+
+void intel_gt_init_swizzling(struct intel_gt *gt)
+{
+	struct drm_i915_private *i915 = gt->i915;
+	struct intel_uncore *uncore = gt->uncore;
+
+	if (INTEL_GEN(i915) < 5 ||
+	    i915->ggtt.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_NONE)
+		return;
+
+	intel_uncore_rmw(uncore, DISP_ARB_CTL, 0, DISP_TILE_SURFACE_SWIZZLING);
+
+	if (IS_GEN(i915, 5))
+		return;
+
+	intel_uncore_rmw(uncore, TILECTL, 0, TILECTL_SWZCTL);
+
+	if (IS_GEN(i915, 6))
+		intel_uncore_write(uncore,
+				   ARB_MODE,
+				   _MASKED_BIT_ENABLE(ARB_MODE_SWIZZLE_SNB));
+	else if (IS_GEN(i915, 7))
+		intel_uncore_write(uncore,
+				   ARB_MODE,
+				   _MASKED_BIT_ENABLE(ARB_MODE_SWIZZLE_IVB));
+	else if (IS_GEN(i915, 8))
+		intel_uncore_write(uncore,
+				   GAMTARBMODE,
+				   _MASKED_BIT_ENABLE(ARB_MODE_SWIZZLE_BDW));
+	else
+		MISSING_CASE(INTEL_GEN(i915));
+}
diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.h b/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.h
new file mode 100644
index 000000000000..9eef679e1311
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright © 2016 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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 __INTEL_GGTT_FENCING_H__
+#define __INTEL_GGTT_FENCING_H__
+
+#include <linux/list.h>
+#include <linux/types.h>
+
+#include "i915_active.h"
+
+struct drm_i915_gem_object;
+struct i915_ggtt;
+struct i915_vma;
+struct intel_gt;
+struct sg_table;
+
+#define I965_FENCE_PAGE 4096UL
+
+struct i915_fence_reg {
+	struct list_head link;
+	struct i915_ggtt *ggtt;
+	struct i915_vma *vma;
+	atomic_t pin_count;
+	struct i915_active active;
+	int id;
+	/**
+	 * Whether the tiling parameters for the currently
+	 * associated fence register have changed. Note that
+	 * for the purposes of tracking tiling changes we also
+	 * treat the unfenced register, the register slot that
+	 * the object occupies whilst it executes a fenced
+	 * command (such as BLT on gen2/3), as a "fence".
+	 */
+	bool dirty;
+	u32 start;
+	u32 size;
+	u32 tiling;
+	u32 stride;
+};
+
+struct i915_fence_reg *i915_reserve_fence(struct i915_ggtt *ggtt);
+void i915_unreserve_fence(struct i915_fence_reg *fence);
+
+void intel_ggtt_restore_fences(struct i915_ggtt *ggtt);
+
+void i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj,
+				       struct sg_table *pages);
+void i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj,
+					 struct sg_table *pages);
+
+void intel_ggtt_init_fences(struct i915_ggtt *ggtt);
+void intel_ggtt_fini_fences(struct i915_ggtt *ggtt);
+
+void intel_gt_init_swizzling(struct intel_gt *gt);
+
+#endif
diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c
index d09f7596cb98..1c99cc72305a 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt.c
@@ -635,8 +635,7 @@ void intel_gt_driver_remove(struct intel_gt *gt)
 {
 	__intel_gt_disable(gt);
 
-	intel_uc_fini_hw(&gt->uc);
-	intel_uc_fini(&gt->uc);
+	intel_uc_driver_remove(&gt->uc);
 
 	intel_engines_release(gt);
 }
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_irq.c b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
index f0e7fd95165a..0cc7dd54f4f9 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_irq.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
@@ -39,6 +39,15 @@ cs_irq_handler(struct intel_engine_cs *engine, u32 iir)
 		}
 	}
 
+	if (iir & GT_WAIT_SEMAPHORE_INTERRUPT) {
+		WRITE_ONCE(engine->execlists.yield,
+			   ENGINE_READ_FW(engine, RING_EXECLIST_STATUS_HI));
+		ENGINE_TRACE(engine, "semaphore yield: %08x\n",
+			     engine->execlists.yield);
+		if (del_timer(&engine->execlists.timer))
+			tasklet = true;
+	}
+
 	if (iir & GT_CONTEXT_SWITCH_INTERRUPT)
 		tasklet = true;
 
@@ -228,7 +237,8 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
 	const u32 irqs =
 		GT_CS_MASTER_ERROR_INTERRUPT |
 		GT_RENDER_USER_INTERRUPT |
-		GT_CONTEXT_SWITCH_INTERRUPT;
+		GT_CONTEXT_SWITCH_INTERRUPT |
+		GT_WAIT_SEMAPHORE_INTERRUPT;
 	struct intel_uncore *uncore = gt->uncore;
 	const u32 dmask = irqs << 16 | irqs;
 	const u32 smask = irqs << 16;
@@ -366,7 +376,8 @@ void gen8_gt_irq_postinstall(struct intel_gt *gt)
 	const u32 irqs =
 		GT_CS_MASTER_ERROR_INTERRUPT |
 		GT_RENDER_USER_INTERRUPT |
-		GT_CONTEXT_SWITCH_INTERRUPT;
+		GT_CONTEXT_SWITCH_INTERRUPT |
+		GT_WAIT_SEMAPHORE_INTERRUPT;
 	const u32 gt_interrupts[] = {
 		irqs << GEN8_RCS_IRQ_SHIFT | irqs << GEN8_BCS_IRQ_SHIFT,
 		irqs << GEN8_VCS0_IRQ_SHIFT | irqs << GEN8_VCS1_IRQ_SHIFT,
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.c b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
index 8b653c0f5e5f..3e8a56c7d818 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
@@ -204,7 +204,7 @@ int intel_gt_resume(struct intel_gt *gt)
 	/* Only when the HW is re-initialised, can we replay the requests */
 	err = intel_gt_init_hw(gt);
 	if (err) {
-		dev_err(gt->i915->drm.dev,
+		drm_err(&gt->i915->drm,
 			"Failed to initialize GPU, declaring it wedged!\n");
 		goto err_wedged;
 	}
@@ -220,7 +220,7 @@ int intel_gt_resume(struct intel_gt *gt)
 
 		intel_engine_pm_put(engine);
 		if (err) {
-			dev_err(gt->i915->drm.dev,
+			drm_err(&gt->i915->drm,
 				"Failed to restart %s (%d)\n",
 				engine->name, err);
 			goto err_wedged;
@@ -324,6 +324,7 @@ int intel_gt_runtime_resume(struct intel_gt *gt)
 {
 	GT_TRACE(gt, "\n");
 	intel_gt_init_swizzling(gt);
+	intel_ggtt_restore_fences(gt->ggtt);
 
 	return intel_uc_runtime_resume(&gt->uc);
 }
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_requests.c b/drivers/gpu/drm/i915/gt/intel_gt_requests.c
index 24c99d0838af..835ec184763e 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_requests.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_requests.c
@@ -38,7 +38,7 @@ static bool flush_submission(struct intel_gt *gt)
 	for_each_engine(engine, gt, id) {
 		intel_engine_flush_submission(engine);
 		active |= flush_work(&engine->retire_work);
-		active |= flush_work(&engine->wakeref.work);
+		active |= flush_delayed_work(&engine->wakeref.work);
 	}
 
 	return active;
diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.h b/drivers/gpu/drm/i915/gt/intel_gtt.h
index b3116fe8d180..d93ebdf3fa0e 100644
--- a/drivers/gpu/drm/i915/gt/intel_gtt.h
+++ b/drivers/gpu/drm/i915/gt/intel_gtt.h
@@ -26,7 +26,6 @@
 #include <drm/drm_mm.h>
 
 #include "gt/intel_reset.h"
-#include "i915_gem_fence_reg.h"
 #include "i915_selftest.h"
 #include "i915_vma_types.h"
 
@@ -135,6 +134,8 @@ typedef u64 gen8_pte_t;
 #define GEN8_PDE_IPS_64K BIT(11)
 #define GEN8_PDE_PS_2M   BIT(7)
 
+struct i915_fence_reg;
+
 #define for_each_sgt_daddr(__dp, __iter, __sgt) \
 	__for_each_sgt_daddr(__dp, __iter, __sgt, I915_GTT_PAGE_SIZE)
 
@@ -333,7 +334,7 @@ struct i915_ggtt {
 	u32 pin_bias;
 
 	unsigned int num_fences;
-	struct i915_fence_reg fence_regs[I915_MAX_NUM_FENCES];
+	struct i915_fence_reg *fence_regs;
 	struct list_head fence_list;
 
 	/**
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c
index 683014e7bc51..6fbad5e2343f 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -238,6 +238,17 @@ __execlists_update_reg_state(const struct intel_context *ce,
 			     const struct intel_engine_cs *engine,
 			     u32 head);
 
+static u32 intel_context_get_runtime(const struct intel_context *ce)
+{
+	/*
+	 * We can use either ppHWSP[16] which is recorded before the context
+	 * switch (and so excludes the cost of context switches) or use the
+	 * value from the context image itself, which is saved/restored earlier
+	 * and so includes the cost of the save.
+	 */
+	return READ_ONCE(ce->lrc_reg_state[CTX_TIMESTAMP]);
+}
+
 static void mark_eio(struct i915_request *rq)
 {
 	if (i915_request_completed(rq))
@@ -1154,6 +1165,7 @@ static void restore_default_state(struct intel_context *ce,
 		       engine->context_size - PAGE_SIZE);
 
 	execlists_init_reg_state(regs, ce, engine, ce->ring, false);
+	ce->runtime.last = intel_context_get_runtime(ce);
 }
 
 static void reset_active(struct i915_request *rq,
@@ -1195,17 +1207,6 @@ static void reset_active(struct i915_request *rq,
 	ce->lrc_desc |= CTX_DESC_FORCE_RESTORE;
 }
 
-static u32 intel_context_get_runtime(const struct intel_context *ce)
-{
-	/*
-	 * We can use either ppHWSP[16] which is recorded before the context
-	 * switch (and so excludes the cost of context switches) or use the
-	 * value from the context image itself, which is saved/restored earlier
-	 * and so includes the cost of the save.
-	 */
-	return READ_ONCE(ce->lrc_reg_state[CTX_TIMESTAMP]);
-}
-
 static void st_update_runtime_underflow(struct intel_context *ce, s32 dt)
 {
 #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
@@ -1415,6 +1416,23 @@ static inline void write_desc(struct intel_engine_execlists *execlists, u64 desc
 	}
 }
 
+static __maybe_unused char *
+dump_port(char *buf, int buflen, const char *prefix, struct i915_request *rq)
+{
+	if (!rq)
+		return "";
+
+	snprintf(buf, buflen, "%s%llx:%lld%s prio %d",
+		 prefix,
+		 rq->fence.context, rq->fence.seqno,
+		 i915_request_completed(rq) ? "!" :
+		 i915_request_started(rq) ? "*" :
+		 "",
+		 rq_prio(rq));
+
+	return buf;
+}
+
 static __maybe_unused void
 trace_ports(const struct intel_engine_execlists *execlists,
 	    const char *msg,
@@ -1422,18 +1440,14 @@ trace_ports(const struct intel_engine_execlists *execlists,
 {
 	const struct intel_engine_cs *engine =
 		container_of(execlists, typeof(*engine), execlists);
+	char __maybe_unused p0[40], p1[40];
 
 	if (!ports[0])
 		return;
 
-	ENGINE_TRACE(engine, "%s { %llx:%lld%s, %llx:%lld }\n", msg,
-		     ports[0]->fence.context,
-		     ports[0]->fence.seqno,
-		     i915_request_completed(ports[0]) ? "!" :
-		     i915_request_started(ports[0]) ? "*" :
-		     "",
-		     ports[1] ? ports[1]->fence.context : 0,
-		     ports[1] ? ports[1]->fence.seqno : 0);
+	ENGINE_TRACE(engine, "%s { %s%s }\n", msg,
+		     dump_port(p0, sizeof(p0), "", ports[0]),
+		     dump_port(p1, sizeof(p1), ", ", ports[1]));
 }
 
 static inline bool
@@ -1754,7 +1768,8 @@ static void defer_active(struct intel_engine_cs *engine)
 }
 
 static bool
-need_timeslice(struct intel_engine_cs *engine, const struct i915_request *rq)
+need_timeslice(const struct intel_engine_cs *engine,
+	       const struct i915_request *rq)
 {
 	int hint;
 
@@ -1768,6 +1783,32 @@ need_timeslice(struct intel_engine_cs *engine, const struct i915_request *rq)
 	return hint >= effective_prio(rq);
 }
 
+static bool
+timeslice_yield(const struct intel_engine_execlists *el,
+		const struct i915_request *rq)
+{
+	/*
+	 * Once bitten, forever smitten!
+	 *
+	 * If the active context ever busy-waited on a semaphore,
+	 * it will be treated as a hog until the end of its timeslice (i.e.
+	 * until it is scheduled out and replaced by a new submission,
+	 * possibly even its own lite-restore). The HW only sends an interrupt
+	 * on the first miss, and we do know if that semaphore has been
+	 * signaled, or even if it is now stuck on another semaphore. Play
+	 * safe, yield if it might be stuck -- it will be given a fresh
+	 * timeslice in the near future.
+	 */
+	return upper_32_bits(rq->context->lrc_desc) == READ_ONCE(el->yield);
+}
+
+static bool
+timeslice_expired(const struct intel_engine_execlists *el,
+		  const struct i915_request *rq)
+{
+	return timer_expired(&el->timer) || timeslice_yield(el, rq);
+}
+
 static int
 switch_prio(struct intel_engine_cs *engine, const struct i915_request *rq)
 {
@@ -1783,8 +1824,7 @@ timeslice(const struct intel_engine_cs *engine)
 	return READ_ONCE(engine->props.timeslice_duration_ms);
 }
 
-static unsigned long
-active_timeslice(const struct intel_engine_cs *engine)
+static unsigned long active_timeslice(const struct intel_engine_cs *engine)
 {
 	const struct intel_engine_execlists *execlists = &engine->execlists;
 	const struct i915_request *rq = *execlists->active;
@@ -1800,16 +1840,25 @@ active_timeslice(const struct intel_engine_cs *engine)
 
 static void set_timeslice(struct intel_engine_cs *engine)
 {
+	unsigned long duration;
+
 	if (!intel_engine_has_timeslices(engine))
 		return;
 
-	set_timer_ms(&engine->execlists.timer, active_timeslice(engine));
+	duration = active_timeslice(engine);
+	ENGINE_TRACE(engine, "bump timeslicing, interval:%lu", duration);
+
+	set_timer_ms(&engine->execlists.timer, duration);
 }
 
 static void start_timeslice(struct intel_engine_cs *engine)
 {
 	struct intel_engine_execlists *execlists = &engine->execlists;
-	int prio = queue_prio(execlists);
+	const int prio = queue_prio(execlists);
+	unsigned long duration;
+
+	if (!intel_engine_has_timeslices(engine))
+		return;
 
 	WRITE_ONCE(execlists->switch_priority_hint, prio);
 	if (prio == INT_MIN)
@@ -1818,7 +1867,12 @@ static void start_timeslice(struct intel_engine_cs *engine)
 	if (timer_pending(&execlists->timer))
 		return;
 
-	set_timer_ms(&execlists->timer, timeslice(engine));
+	duration = timeslice(engine);
+	ENGINE_TRACE(engine,
+		     "start timeslicing, prio:%d, interval:%lu",
+		     prio, duration);
+
+	set_timer_ms(&execlists->timer, duration);
 }
 
 static void record_preemption(struct intel_engine_execlists *execlists)
@@ -1915,11 +1969,26 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
 	 * of trouble.
 	 */
 	active = READ_ONCE(execlists->active);
-	while ((last = *active) && i915_request_completed(last))
-		active++;
 
-	if (last) {
+	/*
+	 * In theory we can skip over completed contexts that have not
+	 * yet been processed by events (as those events are in flight):
+	 *
+	 * while ((last = *active) && i915_request_completed(last))
+	 *	active++;
+	 *
+	 * However, the GPU cannot handle this as it will ultimately
+	 * find itself trying to jump back into a context it has just
+	 * completed and barf.
+	 */
+
+	if ((last = *active)) {
 		if (need_preempt(engine, last, rb)) {
+			if (i915_request_completed(last)) {
+				tasklet_hi_schedule(&execlists->tasklet);
+				return;
+			}
+
 			ENGINE_TRACE(engine,
 				     "preempting last=%llx:%lld, prio=%d, hint=%d\n",
 				     last->fence.context,
@@ -1946,13 +2015,19 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
 
 			last = NULL;
 		} else if (need_timeslice(engine, last) &&
-			   timer_expired(&engine->execlists.timer)) {
+			   timeslice_expired(execlists, last)) {
+			if (i915_request_completed(last)) {
+				tasklet_hi_schedule(&execlists->tasklet);
+				return;
+			}
+
 			ENGINE_TRACE(engine,
-				     "expired last=%llx:%lld, prio=%d, hint=%d\n",
+				     "expired last=%llx:%lld, prio=%d, hint=%d, yield?=%s\n",
 				     last->fence.context,
 				     last->fence.seqno,
 				     last->sched.attr.priority,
-				     execlists->queue_priority_hint);
+				     execlists->queue_priority_hint,
+				     yesno(timeslice_yield(execlists, last)));
 
 			ring_set_paused(engine, 1);
 			defer_active(engine);
@@ -2213,6 +2288,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
 		}
 		clear_ports(port + 1, last_port - port);
 
+		WRITE_ONCE(execlists->yield, -1);
 		execlists_submit_ports(engine);
 		set_preempt_timeout(engine, *active);
 	} else {
@@ -2308,6 +2384,13 @@ gen8_csb_parse(const struct intel_engine_execlists *execlists, const u32 *csb)
 	return *csb & (GEN8_CTX_STATUS_IDLE_ACTIVE | GEN8_CTX_STATUS_PREEMPTED);
 }
 
+static inline void flush_hwsp(const struct i915_request *rq)
+{
+	mb();
+	clflush((void *)READ_ONCE(rq->hwsp_seqno));
+	mb();
+}
+
 static void process_csb(struct intel_engine_cs *engine)
 {
 	struct intel_engine_execlists * const execlists = &engine->execlists;
@@ -2384,8 +2467,6 @@ static void process_csb(struct intel_engine_cs *engine)
 		if (promote) {
 			struct i915_request * const *old = execlists->active;
 
-			GEM_BUG_ON(!assert_pending_valid(execlists, "promote"));
-
 			ring_set_paused(engine, 0);
 
 			/* Point active to the new ELSP; prevent overwriting */
@@ -2398,6 +2479,7 @@ static void process_csb(struct intel_engine_cs *engine)
 				execlists_schedule_out(*old++);
 
 			/* switch pending to inflight */
+			GEM_BUG_ON(!assert_pending_valid(execlists, "promote"));
 			memcpy(execlists->inflight,
 			       execlists->pending,
 			       execlists_num_ports(execlists) *
@@ -2419,13 +2501,24 @@ static void process_csb(struct intel_engine_cs *engine)
 			 * user interrupt and CSB is processed.
 			 */
 			if (GEM_SHOW_DEBUG() &&
-			    !i915_request_completed(*execlists->active) &&
-			    !reset_in_progress(execlists)) {
-				struct i915_request *rq __maybe_unused =
-					*execlists->active;
+			    !i915_request_completed(*execlists->active)) {
+				struct i915_request *rq = *execlists->active;
 				const u32 *regs __maybe_unused =
 					rq->context->lrc_reg_state;
 
+				/*
+				 * Flush the breadcrumb before crying foul.
+				 *
+				 * Since we have hit this on icl and seen the
+				 * breadcrumb advance as we print out the debug
+				 * info (so the problem corrected itself without
+				 * lasting damage), and we know that icl suffers
+				 * from missing global observation points in
+				 * execlists, presume that affects even more
+				 * coherency.
+				 */
+				flush_hwsp(rq);
+
 				ENGINE_TRACE(engine,
 					     "ring:{start:0x%08x, head:%04x, tail:%04x, ctl:%08x, mode:%08x}\n",
 					     ENGINE_READ(engine, RING_START),
@@ -2446,7 +2539,10 @@ static void process_csb(struct intel_engine_cs *engine)
 					     regs[CTX_RING_HEAD],
 					     regs[CTX_RING_TAIL]);
 
-				GEM_BUG_ON("context completed before request");
+				/* Still? Declare it caput! */
+				if (!i915_request_completed(rq) &&
+				    !reset_in_progress(execlists))
+					GEM_BUG_ON("context completed before request");
 			}
 
 			execlists_schedule_out(*execlists->active++);
@@ -2736,6 +2832,45 @@ static struct execlists_capture *capture_regs(struct intel_engine_cs *engine)
 	return NULL;
 }
 
+static struct i915_request *
+active_context(struct intel_engine_cs *engine, u32 ccid)
+{
+	const struct intel_engine_execlists * const el = &engine->execlists;
+	struct i915_request * const *port, *rq;
+
+	/*
+	 * Use the most recent result from process_csb(), but just in case
+	 * we trigger an error (via interrupt) before the first CS event has
+	 * been written, peek at the next submission.
+	 */
+
+	for (port = el->active; (rq = *port); port++) {
+		if (upper_32_bits(rq->context->lrc_desc) == ccid) {
+			ENGINE_TRACE(engine,
+				     "ccid found at active:%zd\n",
+				     port - el->active);
+			return rq;
+		}
+	}
+
+	for (port = el->pending; (rq = *port); port++) {
+		if (upper_32_bits(rq->context->lrc_desc) == ccid) {
+			ENGINE_TRACE(engine,
+				     "ccid found at pending:%zd\n",
+				     port - el->pending);
+			return rq;
+		}
+	}
+
+	ENGINE_TRACE(engine, "ccid:%x not found\n", ccid);
+	return NULL;
+}
+
+static u32 active_ccid(struct intel_engine_cs *engine)
+{
+	return ENGINE_READ_FW(engine, RING_EXECLIST_STATUS_HI);
+}
+
 static bool execlists_capture(struct intel_engine_cs *engine)
 {
 	struct execlists_capture *cap;
@@ -2753,7 +2888,7 @@ static bool execlists_capture(struct intel_engine_cs *engine)
 		return true;
 
 	spin_lock_irq(&engine->active.lock);
-	cap->rq = execlists_active(&engine->execlists);
+	cap->rq = active_context(engine, active_ccid(engine));
 	if (cap->rq) {
 		cap->rq = active_request(cap->rq->context->timeline, cap->rq);
 		cap->rq = i915_request_get_rcu(cap->rq);
@@ -2901,10 +3036,14 @@ static void __submit_queue_imm(struct intel_engine_cs *engine)
 	if (reset_in_progress(execlists))
 		return; /* defer until we restart the engine following reset */
 
-	if (execlists->tasklet.func == execlists_submission_tasklet)
-		__execlists_submission_tasklet(engine);
-	else
-		tasklet_hi_schedule(&execlists->tasklet);
+	/* Hopefully we clear execlists->pending[] to let us through */
+	if (READ_ONCE(execlists->pending[0]) &&
+	    tasklet_trylock(&execlists->tasklet)) {
+		process_csb(engine);
+		tasklet_unlock(&execlists->tasklet);
+	}
+
+	__execlists_submission_tasklet(engine);
 }
 
 static void submit_queue(struct intel_engine_cs *engine,
@@ -2990,7 +3129,7 @@ check_redzone(const void *vaddr, const struct intel_engine_cs *engine)
 	vaddr += engine->context_size;
 
 	if (memchr_inv(vaddr, CONTEXT_REDZONE, I915_GTT_PAGE_SIZE))
-		dev_err_once(engine->i915->drm.dev,
+		drm_err_once(&engine->i915->drm,
 			     "%s context redzone overwritten!\n",
 			     engine->name);
 }
@@ -3442,7 +3581,8 @@ static int intel_init_workaround_bb(struct intel_engine_cs *engine)
 
 	ret = lrc_setup_wa_ctx(engine);
 	if (ret) {
-		DRM_DEBUG_DRIVER("Failed to setup context WA page: %d\n", ret);
+		drm_dbg(&engine->i915->drm,
+			"Failed to setup context WA page: %d\n", ret);
 		return ret;
 	}
 
@@ -3485,7 +3625,7 @@ static void enable_error_interrupt(struct intel_engine_cs *engine)
 
 	status = ENGINE_READ(engine, RING_ESR);
 	if (unlikely(status)) {
-		dev_err(engine->i915->drm.dev,
+		drm_err(&engine->i915->drm,
 			"engine '%s' resumed still in error: %08x\n",
 			engine->name, status);
 		__intel_gt_reset(engine->gt, engine->mask);
@@ -3549,7 +3689,8 @@ static bool unexpected_starting_state(struct intel_engine_cs *engine)
 	bool unexpected = false;
 
 	if (ENGINE_READ_FW(engine, RING_MI_MODE) & STOP_RING) {
-		DRM_DEBUG_DRIVER("STOP_RING still set in RING_MI_MODE\n");
+		drm_dbg(&engine->i915->drm,
+			"STOP_RING still set in RING_MI_MODE\n");
 		unexpected = true;
 	}
 
@@ -3609,6 +3750,7 @@ static void execlists_reset_prepare(struct intel_engine_cs *engine)
 	 *
 	 * FIXME: Wa for more modern gens needs to be validated
 	 */
+	ring_set_paused(engine, 1);
 	intel_engine_stop_cs(engine);
 }
 
@@ -4449,6 +4591,7 @@ logical_ring_default_irqs(struct intel_engine_cs *engine)
 	engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT << shift;
 	engine->irq_keep_mask = GT_CONTEXT_SWITCH_INTERRUPT << shift;
 	engine->irq_keep_mask |= GT_CS_MASTER_ERROR_INTERRUPT << shift;
+	engine->irq_keep_mask |= GT_WAIT_SEMAPHORE_INTERRUPT << shift;
 }
 
 static void rcs_submission_override(struct intel_engine_cs *engine)
@@ -4493,7 +4636,7 @@ int intel_execlists_submission_setup(struct intel_engine_cs *engine)
 		 * because we only expect rare glitches but nothing
 		 * critical to prevent us from using GPU
 		 */
-		DRM_ERROR("WA batch buffer initialization failed\n");
+		drm_err(&i915->drm, "WA batch buffer initialization failed\n");
 
 	if (HAS_LOGICAL_RING_ELSQ(i915)) {
 		execlists->submit_reg = uncore->regs +
@@ -4575,6 +4718,7 @@ static void init_common_reg_state(u32 * const regs,
 	regs[CTX_CONTEXT_CONTROL] = ctl;
 
 	regs[CTX_RING_CTL] = RING_CTL_SIZE(ring->size) | RING_VALID;
+	regs[CTX_TIMESTAMP] = 0;
 }
 
 static void init_wa_bb_reg_state(u32 * const regs,
@@ -4668,7 +4812,8 @@ populate_lr_context(struct intel_context *ce,
 	vaddr = i915_gem_object_pin_map(ctx_obj, I915_MAP_WB);
 	if (IS_ERR(vaddr)) {
 		ret = PTR_ERR(vaddr);
-		DRM_DEBUG_DRIVER("Could not map object pages! (%d)\n", ret);
+		drm_dbg(&engine->i915->drm,
+			"Could not map object pages! (%d)\n", ret);
 		return ret;
 	}
 
@@ -4761,7 +4906,8 @@ static int __execlists_context_alloc(struct intel_context *ce,
 
 	ret = populate_lr_context(ce, ctx_obj, engine, ring);
 	if (ret) {
-		DRM_DEBUG_DRIVER("Failed to populate LRC: %d\n", ret);
+		drm_dbg(&engine->i915->drm,
+			"Failed to populate LRC: %d\n", ret);
 		goto error_ring_free;
 	}
 
@@ -4814,6 +4960,8 @@ static void virtual_context_destroy(struct kref *kref)
 		__execlists_context_fini(&ve->context);
 	intel_context_fini(&ve->context);
 
+	intel_engine_free_request_pool(&ve->base);
+
 	kfree(ve->bonds);
 	kfree(ve);
 }
@@ -4994,10 +5142,8 @@ static void virtual_submission_tasklet(unsigned long data)
 submit_engine:
 		GEM_BUG_ON(RB_EMPTY_NODE(&node->rb));
 		node->prio = prio;
-		if (first && prio > sibling->execlists.queue_priority_hint) {
-			sibling->execlists.queue_priority_hint = prio;
+		if (first && prio > sibling->execlists.queue_priority_hint)
 			tasklet_hi_schedule(&sibling->execlists.tasklet);
-		}
 
 		spin_unlock(&sibling->active.lock);
 	}
diff --git a/drivers/gpu/drm/i915/gt/intel_rc6.c b/drivers/gpu/drm/i915/gt/intel_rc6.c
index 3847ee44b181..1c1923ec8be7 100644
--- a/drivers/gpu/drm/i915/gt/intel_rc6.c
+++ b/drivers/gpu/drm/i915/gt/intel_rc6.c
@@ -246,16 +246,18 @@ static void gen6_rc6_enable(struct intel_rc6 *rc6)
 	ret = sandybridge_pcode_read(i915, GEN6_PCODE_READ_RC6VIDS,
 				     &rc6vids, NULL);
 	if (IS_GEN(i915, 6) && ret) {
-		DRM_DEBUG_DRIVER("Couldn't check for BIOS workaround\n");
+		drm_dbg(&i915->drm, "Couldn't check for BIOS workaround\n");
 	} else if (IS_GEN(i915, 6) &&
 		   (GEN6_DECODE_RC6_VID(rc6vids & 0xff) < 450)) {
-		DRM_DEBUG_DRIVER("You should update your BIOS. Correcting minimum rc6 voltage (%dmV->%dmV)\n",
-				 GEN6_DECODE_RC6_VID(rc6vids & 0xff), 450);
+		drm_dbg(&i915->drm,
+			"You should update your BIOS. Correcting minimum rc6 voltage (%dmV->%dmV)\n",
+			GEN6_DECODE_RC6_VID(rc6vids & 0xff), 450);
 		rc6vids &= 0xffff00;
 		rc6vids |= GEN6_ENCODE_RC6_VID(450);
 		ret = sandybridge_pcode_write(i915, GEN6_PCODE_WRITE_RC6VIDS, rc6vids);
 		if (ret)
-			DRM_ERROR("Couldn't fix incorrect rc6 voltage\n");
+			drm_err(&i915->drm,
+				"Couldn't fix incorrect rc6 voltage\n");
 	}
 }
 
@@ -263,14 +265,15 @@ static void gen6_rc6_enable(struct intel_rc6 *rc6)
 static int chv_rc6_init(struct intel_rc6 *rc6)
 {
 	struct intel_uncore *uncore = rc6_to_uncore(rc6);
+	struct drm_i915_private *i915 = rc6_to_i915(rc6);
 	resource_size_t pctx_paddr, paddr;
 	resource_size_t pctx_size = 32 * SZ_1K;
 	u32 pcbr;
 
 	pcbr = intel_uncore_read(uncore, VLV_PCBR);
 	if ((pcbr >> VLV_PCBR_ADDR_SHIFT) == 0) {
-		DRM_DEBUG_DRIVER("BIOS didn't set up PCBR, fixing up\n");
-		paddr = rc6_to_i915(rc6)->dsm.end + 1 - pctx_size;
+		drm_dbg(&i915->drm, "BIOS didn't set up PCBR, fixing up\n");
+		paddr = i915->dsm.end + 1 - pctx_size;
 		GEM_BUG_ON(paddr > U32_MAX);
 
 		pctx_paddr = (paddr & ~4095);
@@ -304,7 +307,7 @@ static int vlv_rc6_init(struct intel_rc6 *rc6)
 		goto out;
 	}
 
-	DRM_DEBUG_DRIVER("BIOS didn't set up PCBR, fixing up\n");
+	drm_dbg(&i915->drm, "BIOS didn't set up PCBR, fixing up\n");
 
 	/*
 	 * From the Gunit register HAS:
@@ -316,7 +319,8 @@ static int vlv_rc6_init(struct intel_rc6 *rc6)
 	 */
 	pctx = i915_gem_object_create_stolen(i915, pctx_size);
 	if (IS_ERR(pctx)) {
-		DRM_DEBUG("not enough stolen space for PCTX, disabling\n");
+		drm_dbg(&i915->drm,
+			"not enough stolen space for PCTX, disabling\n");
 		return PTR_ERR(pctx);
 	}
 
@@ -398,14 +402,14 @@ static bool bxt_check_bios_rc6_setup(struct intel_rc6 *rc6)
 	rc_sw_target = intel_uncore_read(uncore, GEN6_RC_STATE);
 	rc_sw_target &= RC_SW_TARGET_STATE_MASK;
 	rc_sw_target >>= RC_SW_TARGET_STATE_SHIFT;
-	DRM_DEBUG_DRIVER("BIOS enabled RC states: "
+	drm_dbg(&i915->drm, "BIOS enabled RC states: "
 			 "HW_CTRL %s HW_RC6 %s SW_TARGET_STATE %x\n",
 			 onoff(rc_ctl & GEN6_RC_CTL_HW_ENABLE),
 			 onoff(rc_ctl & GEN6_RC_CTL_RC6_ENABLE),
 			 rc_sw_target);
 
 	if (!(intel_uncore_read(uncore, RC6_LOCATION) & RC6_CTX_IN_DRAM)) {
-		DRM_DEBUG_DRIVER("RC6 Base location not set properly.\n");
+		drm_dbg(&i915->drm, "RC6 Base location not set properly.\n");
 		enable_rc6 = false;
 	}
 
@@ -417,7 +421,7 @@ static bool bxt_check_bios_rc6_setup(struct intel_rc6 *rc6)
 		intel_uncore_read(uncore, RC6_CTX_BASE) & RC6_CTX_BASE_MASK;
 	if (!(rc6_ctx_base >= i915->dsm_reserved.start &&
 	      rc6_ctx_base + PAGE_SIZE < i915->dsm_reserved.end)) {
-		DRM_DEBUG_DRIVER("RC6 Base address not as expected.\n");
+		drm_dbg(&i915->drm, "RC6 Base address not as expected.\n");
 		enable_rc6 = false;
 	}
 
@@ -425,24 +429,25 @@ static bool bxt_check_bios_rc6_setup(struct intel_rc6 *rc6)
 	      (intel_uncore_read(uncore, PWRCTX_MAXCNT_VCSUNIT0) & IDLE_TIME_MASK) > 1 &&
 	      (intel_uncore_read(uncore, PWRCTX_MAXCNT_BCSUNIT) & IDLE_TIME_MASK) > 1 &&
 	      (intel_uncore_read(uncore, PWRCTX_MAXCNT_VECSUNIT) & IDLE_TIME_MASK) > 1)) {
-		DRM_DEBUG_DRIVER("Engine Idle wait time not set properly.\n");
+		drm_dbg(&i915->drm,
+			"Engine Idle wait time not set properly.\n");
 		enable_rc6 = false;
 	}
 
 	if (!intel_uncore_read(uncore, GEN8_PUSHBUS_CONTROL) ||
 	    !intel_uncore_read(uncore, GEN8_PUSHBUS_ENABLE) ||
 	    !intel_uncore_read(uncore, GEN8_PUSHBUS_SHIFT)) {
-		DRM_DEBUG_DRIVER("Pushbus not setup properly.\n");
+		drm_dbg(&i915->drm, "Pushbus not setup properly.\n");
 		enable_rc6 = false;
 	}
 
 	if (!intel_uncore_read(uncore, GEN6_GFXPAUSE)) {
-		DRM_DEBUG_DRIVER("GFX pause not setup properly.\n");
+		drm_dbg(&i915->drm, "GFX pause not setup properly.\n");
 		enable_rc6 = false;
 	}
 
 	if (!intel_uncore_read(uncore, GEN8_MISC_CTRL0)) {
-		DRM_DEBUG_DRIVER("GPM control not setup properly.\n");
+		drm_dbg(&i915->drm, "GPM control not setup properly.\n");
 		enable_rc6 = false;
 	}
 
@@ -463,7 +468,7 @@ static bool rc6_supported(struct intel_rc6 *rc6)
 		return false;
 
 	if (IS_GEN9_LP(i915) && !bxt_check_bios_rc6_setup(rc6)) {
-		dev_notice(i915->drm.dev,
+		drm_notice(&i915->drm,
 			   "RC6 and powersaving disabled by BIOS\n");
 		return false;
 	}
@@ -495,7 +500,7 @@ static bool pctx_corrupted(struct intel_rc6 *rc6)
 	if (intel_uncore_read(rc6_to_uncore(rc6), GEN8_RC6_CTX_INFO))
 		return false;
 
-	dev_notice(i915->drm.dev,
+	drm_notice(&i915->drm,
 		   "RC6 context corruption, disabling runtime power management\n");
 	return true;
 }
diff --git a/drivers/gpu/drm/i915/gt/intel_renderstate.c b/drivers/gpu/drm/i915/gt/intel_renderstate.c
index 5954ecc3207f..26e78db33675 100644
--- a/drivers/gpu/drm/i915/gt/intel_renderstate.c
+++ b/drivers/gpu/drm/i915/gt/intel_renderstate.c
@@ -102,7 +102,7 @@ static int render_state_setup(struct intel_renderstate *so,
 	}
 
 	if (rodata->reloc[reloc_index] != -1) {
-		DRM_ERROR("only %d relocs resolved\n", reloc_index);
+		drm_err(&i915->drm, "only %d relocs resolved\n", reloc_index);
 		goto err;
 	}
 
diff --git a/drivers/gpu/drm/i915/gt/intel_reset.c b/drivers/gpu/drm/i915/gt/intel_reset.c
index 80db3c9d785e..39070b514e65 100644
--- a/drivers/gpu/drm/i915/gt/intel_reset.c
+++ b/drivers/gpu/drm/i915/gt/intel_reset.c
@@ -109,7 +109,7 @@ static bool mark_guilty(struct i915_request *rq)
 		goto out;
 	}
 
-	dev_notice(ctx->i915->drm.dev,
+	drm_notice(&ctx->i915->drm,
 		   "%s context reset due to GPU hang\n",
 		   ctx->name);
 
@@ -755,7 +755,7 @@ static int gt_reset(struct intel_gt *gt, intel_engine_mask_t stalled_mask)
 	for_each_engine(engine, gt, id)
 		__intel_engine_reset(engine, stalled_mask & engine->mask);
 
-	i915_gem_restore_fences(gt->ggtt);
+	intel_ggtt_restore_fences(gt->ggtt);
 
 	return err;
 }
@@ -1031,7 +1031,7 @@ void intel_gt_reset(struct intel_gt *gt,
 		goto unlock;
 
 	if (reason)
-		dev_notice(gt->i915->drm.dev,
+		drm_notice(&gt->i915->drm,
 			   "Resetting chip for %s\n", reason);
 	atomic_inc(&gt->i915->gpu_error.reset_count);
 
@@ -1039,7 +1039,7 @@ void intel_gt_reset(struct intel_gt *gt,
 
 	if (!intel_has_gpu_reset(gt)) {
 		if (i915_modparams.reset)
-			dev_err(gt->i915->drm.dev, "GPU reset not supported\n");
+			drm_err(&gt->i915->drm, "GPU reset not supported\n");
 		else
 			drm_dbg(&gt->i915->drm, "GPU reset disabled\n");
 		goto error;
@@ -1049,7 +1049,7 @@ void intel_gt_reset(struct intel_gt *gt,
 		intel_runtime_pm_disable_interrupts(gt->i915);
 
 	if (do_reset(gt, stalled_mask)) {
-		dev_err(gt->i915->drm.dev, "Failed to reset chip\n");
+		drm_err(&gt->i915->drm, "Failed to reset chip\n");
 		goto taint;
 	}
 
@@ -1111,7 +1111,7 @@ static inline int intel_gt_reset_engine(struct intel_engine_cs *engine)
 /**
  * intel_engine_reset - reset GPU engine to recover from a hang
  * @engine: engine to reset
- * @msg: reason for GPU reset; or NULL for no dev_notice()
+ * @msg: reason for GPU reset; or NULL for no drm_notice()
  *
  * Reset a specific GPU engine. Useful if a hang is detected.
  * Returns zero on successful reset or otherwise an error code.
@@ -1136,7 +1136,7 @@ int intel_engine_reset(struct intel_engine_cs *engine, const char *msg)
 	reset_prepare_engine(engine);
 
 	if (msg)
-		dev_notice(engine->i915->drm.dev,
+		drm_notice(&engine->i915->drm,
 			   "Resetting %s for %s\n", engine->name, msg);
 	atomic_inc(&engine->i915->gpu_error.reset_engine_count[engine->uabi_class]);
 
@@ -1381,7 +1381,7 @@ static void intel_wedge_me(struct work_struct *work)
 {
 	struct intel_wedge_me *w = container_of(work, typeof(*w), work.work);
 
-	dev_err(w->gt->i915->drm.dev,
+	drm_err(&w->gt->i915->drm,
 		"%s timed out, cancelling all in-flight rendering.\n",
 		w->name);
 	intel_gt_set_wedged(w->gt);
diff --git a/drivers/gpu/drm/i915/gt/intel_ring.h b/drivers/gpu/drm/i915/gt/intel_ring.h
index 5bdce24994aa..cc0ebca65167 100644
--- a/drivers/gpu/drm/i915/gt/intel_ring.h
+++ b/drivers/gpu/drm/i915/gt/intel_ring.h
@@ -88,6 +88,8 @@ static inline u32 intel_ring_offset(const struct i915_request *rq, void *addr)
 static inline void
 assert_ring_tail_valid(const struct intel_ring *ring, unsigned int tail)
 {
+	unsigned int head = READ_ONCE(ring->head);
+
 	GEM_BUG_ON(!intel_ring_offset_valid(ring, tail));
 
 	/*
@@ -105,8 +107,7 @@ assert_ring_tail_valid(const struct intel_ring *ring, unsigned int tail)
 	 * into the same cacheline as ring->head.
 	 */
 #define cacheline(a) round_down(a, CACHELINE_BYTES)
-	GEM_BUG_ON(cacheline(tail) == cacheline(ring->head) &&
-		   tail < ring->head);
+	GEM_BUG_ON(cacheline(tail) == cacheline(head) && tail < head);
 #undef cacheline
 }
 
diff --git a/drivers/gpu/drm/i915/gt/intel_ring_submission.c b/drivers/gpu/drm/i915/gt/intel_ring_submission.c
index fdc3f10e12aa..d015f7b8b28e 100644
--- a/drivers/gpu/drm/i915/gt/intel_ring_submission.c
+++ b/drivers/gpu/drm/i915/gt/intel_ring_submission.c
@@ -577,8 +577,9 @@ static void flush_cs_tlb(struct intel_engine_cs *engine)
 				    RING_INSTPM(engine->mmio_base),
 				    INSTPM_SYNC_FLUSH, 0,
 				    1000))
-		DRM_ERROR("%s: wait for SyncFlush to complete for TLB invalidation timed out\n",
-			  engine->name);
+		drm_err(&dev_priv->drm,
+			"%s: wait for SyncFlush to complete for TLB invalidation timed out\n",
+			engine->name);
 }
 
 static void ring_setup_status_page(struct intel_engine_cs *engine)
@@ -601,8 +602,9 @@ static bool stop_ring(struct intel_engine_cs *engine)
 					    MODE_IDLE,
 					    MODE_IDLE,
 					    1000)) {
-			DRM_ERROR("%s : timed out trying to stop ring\n",
-				  engine->name);
+			drm_err(&dev_priv->drm,
+				"%s : timed out trying to stop ring\n",
+				engine->name);
 
 			/*
 			 * Sometimes we observe that the idle flag is not
@@ -661,22 +663,23 @@ static int xcs_resume(struct intel_engine_cs *engine)
 	/* WaClearRingBufHeadRegAtInit:ctg,elk */
 	if (!stop_ring(engine)) {
 		/* G45 ring initialization often fails to reset head to zero */
-		DRM_DEBUG_DRIVER("%s head not reset to zero "
+		drm_dbg(&dev_priv->drm, "%s head not reset to zero "
+			"ctl %08x head %08x tail %08x start %08x\n",
+			engine->name,
+			ENGINE_READ(engine, RING_CTL),
+			ENGINE_READ(engine, RING_HEAD),
+			ENGINE_READ(engine, RING_TAIL),
+			ENGINE_READ(engine, RING_START));
+
+		if (!stop_ring(engine)) {
+			drm_err(&dev_priv->drm,
+				"failed to set %s head to zero "
 				"ctl %08x head %08x tail %08x start %08x\n",
 				engine->name,
 				ENGINE_READ(engine, RING_CTL),
 				ENGINE_READ(engine, RING_HEAD),
 				ENGINE_READ(engine, RING_TAIL),
 				ENGINE_READ(engine, RING_START));
-
-		if (!stop_ring(engine)) {
-			DRM_ERROR("failed to set %s head to zero "
-				  "ctl %08x head %08x tail %08x start %08x\n",
-				  engine->name,
-				  ENGINE_READ(engine, RING_CTL),
-				  ENGINE_READ(engine, RING_HEAD),
-				  ENGINE_READ(engine, RING_TAIL),
-				  ENGINE_READ(engine, RING_START));
 			ret = -EIO;
 			goto out;
 		}
@@ -719,7 +722,7 @@ static int xcs_resume(struct intel_engine_cs *engine)
 				    RING_CTL(engine->mmio_base),
 				    RING_VALID, RING_VALID,
 				    50)) {
-		DRM_ERROR("%s initialization failed "
+		drm_err(&dev_priv->drm, "%s initialization failed "
 			  "ctl %08x (valid? %d) head %08x [%08x] tail %08x [%08x] start %08x [expected %08x]\n",
 			  engine->name,
 			  ENGINE_READ(engine, RING_CTL),
diff --git a/drivers/gpu/drm/i915/gt/intel_rps.c b/drivers/gpu/drm/i915/gt/intel_rps.c
index cfaf141bac4d..4dcfae16a7ce 100644
--- a/drivers/gpu/drm/i915/gt/intel_rps.c
+++ b/drivers/gpu/drm/i915/gt/intel_rps.c
@@ -81,13 +81,14 @@ static void rps_enable_interrupts(struct intel_rps *rps)
 		events = (GEN6_PM_RP_UP_THRESHOLD |
 			  GEN6_PM_RP_DOWN_THRESHOLD |
 			  GEN6_PM_RP_DOWN_TIMEOUT);
-
 	WRITE_ONCE(rps->pm_events, events);
+
 	spin_lock_irq(&gt->irq_lock);
 	gen6_gt_pm_enable_irq(gt, rps->pm_events);
 	spin_unlock_irq(&gt->irq_lock);
 
-	set(gt->uncore, GEN6_PMINTRMSK, rps_pm_mask(rps, rps->cur_freq));
+	intel_uncore_write(gt->uncore,
+			   GEN6_PMINTRMSK, rps_pm_mask(rps, rps->last_freq));
 }
 
 static void gen6_rps_reset_interrupts(struct intel_rps *rps)
@@ -120,7 +121,9 @@ static void rps_disable_interrupts(struct intel_rps *rps)
 	struct intel_gt *gt = rps_to_gt(rps);
 
 	WRITE_ONCE(rps->pm_events, 0);
-	set(gt->uncore, GEN6_PMINTRMSK, rps_pm_sanitize_mask(rps, ~0u));
+
+	intel_uncore_write(gt->uncore,
+			   GEN6_PMINTRMSK, rps_pm_sanitize_mask(rps, ~0u));
 
 	spin_lock_irq(&gt->irq_lock);
 	gen6_gt_pm_disable_irq(gt, GEN6_PM_RPS_EVENTS);
@@ -183,14 +186,12 @@ static void gen5_rps_init(struct intel_rps *rps)
 	fmin = (rgvmodectl & MEMMODE_FMIN_MASK);
 	fstart = (rgvmodectl & MEMMODE_FSTART_MASK) >>
 		MEMMODE_FSTART_SHIFT;
-	DRM_DEBUG_DRIVER("fmax: %d, fmin: %d, fstart: %d\n",
-			 fmax, fmin, fstart);
+	drm_dbg(&i915->drm, "fmax: %d, fmin: %d, fstart: %d\n",
+		fmax, fmin, fstart);
 
 	rps->min_freq = fmax;
+	rps->efficient_freq = fstart;
 	rps->max_freq = fmin;
-
-	rps->idle_freq = rps->min_freq;
-	rps->cur_freq = rps->idle_freq;
 }
 
 static unsigned long
@@ -453,7 +454,8 @@ static bool gen5_rps_enable(struct intel_rps *rps)
 
 	if (wait_for_atomic((intel_uncore_read(uncore, MEMSWCTL) &
 			     MEMCTL_CMD_STS) == 0, 10))
-		DRM_ERROR("stuck trying to change perf mode\n");
+		drm_err(&uncore->i915->drm,
+			"stuck trying to change perf mode\n");
 	mdelay(1);
 
 	gen5_rps_set(rps, rps->cur_freq);
@@ -712,8 +714,6 @@ static int rps_set(struct intel_rps *rps, u8 val, bool update)
 
 void intel_rps_unpark(struct intel_rps *rps)
 {
-	u8 freq;
-
 	if (!rps->enabled)
 		return;
 
@@ -725,9 +725,10 @@ void intel_rps_unpark(struct intel_rps *rps)
 
 	WRITE_ONCE(rps->active, true);
 
-	freq = max(rps->cur_freq, rps->efficient_freq),
-	freq = clamp(freq, rps->min_freq_softlimit, rps->max_freq_softlimit);
-	intel_rps_set(rps, freq);
+	intel_rps_set(rps,
+		      clamp(rps->cur_freq,
+			    rps->min_freq_softlimit,
+			    rps->max_freq_softlimit));
 
 	rps->last_adj = 0;
 
@@ -893,12 +894,13 @@ static void gen6_rps_init(struct intel_rps *rps)
 
 static bool rps_reset(struct intel_rps *rps)
 {
+	struct drm_i915_private *i915 = rps_to_i915(rps);
 	/* force a reset */
 	rps->power.mode = -1;
 	rps->last_freq = -1;
 
 	if (rps_set(rps, rps->min_freq, true)) {
-		DRM_ERROR("Failed to reset RPS to initial values\n");
+		drm_err(&i915->drm, "Failed to reset RPS to initial values\n");
 		return false;
 	}
 
@@ -1049,8 +1051,8 @@ static bool chv_rps_enable(struct intel_rps *rps)
 	drm_WARN_ONCE(&i915->drm, (val & GPLLENABLE) == 0,
 		      "GPLL not enabled\n");
 
-	DRM_DEBUG_DRIVER("GPLL enabled? %s\n", yesno(val & GPLLENABLE));
-	DRM_DEBUG_DRIVER("GPU status: 0x%08x\n", val);
+	drm_dbg(&i915->drm, "GPLL enabled? %s\n", yesno(val & GPLLENABLE));
+	drm_dbg(&i915->drm, "GPU status: 0x%08x\n", val);
 
 	return rps_reset(rps);
 }
@@ -1147,8 +1149,8 @@ static bool vlv_rps_enable(struct intel_rps *rps)
 	drm_WARN_ONCE(&i915->drm, (val & GPLLENABLE) == 0,
 		      "GPLL not enabled\n");
 
-	DRM_DEBUG_DRIVER("GPLL enabled? %s\n", yesno(val & GPLLENABLE));
-	DRM_DEBUG_DRIVER("GPU status: 0x%08x\n", val);
+	drm_dbg(&i915->drm, "GPLL enabled? %s\n", yesno(val & GPLLENABLE));
+	drm_dbg(&i915->drm, "GPU status: 0x%08x\n", val);
 
 	return rps_reset(rps);
 }
@@ -1305,7 +1307,8 @@ static void vlv_init_gpll_ref_freq(struct intel_rps *rps)
 				  CCK_GPLL_CLOCK_CONTROL,
 				  i915->czclk_freq);
 
-	DRM_DEBUG_DRIVER("GPLL reference freq: %d kHz\n", rps->gpll_ref_freq);
+	drm_dbg(&i915->drm, "GPLL reference freq: %d kHz\n",
+		rps->gpll_ref_freq);
 }
 
 static void vlv_rps_init(struct intel_rps *rps)
@@ -1333,28 +1336,24 @@ static void vlv_rps_init(struct intel_rps *rps)
 		i915->mem_freq = 1333;
 		break;
 	}
-	DRM_DEBUG_DRIVER("DDR speed: %d MHz\n", i915->mem_freq);
+	drm_dbg(&i915->drm, "DDR speed: %d MHz\n", i915->mem_freq);
 
 	rps->max_freq = vlv_rps_max_freq(rps);
 	rps->rp0_freq = rps->max_freq;
-	DRM_DEBUG_DRIVER("max GPU freq: %d MHz (%u)\n",
-			 intel_gpu_freq(rps, rps->max_freq),
-			 rps->max_freq);
+	drm_dbg(&i915->drm, "max GPU freq: %d MHz (%u)\n",
+		intel_gpu_freq(rps, rps->max_freq), rps->max_freq);
 
 	rps->efficient_freq = vlv_rps_rpe_freq(rps);
-	DRM_DEBUG_DRIVER("RPe GPU freq: %d MHz (%u)\n",
-			 intel_gpu_freq(rps, rps->efficient_freq),
-			 rps->efficient_freq);
+	drm_dbg(&i915->drm, "RPe GPU freq: %d MHz (%u)\n",
+		intel_gpu_freq(rps, rps->efficient_freq), rps->efficient_freq);
 
 	rps->rp1_freq = vlv_rps_guar_freq(rps);
-	DRM_DEBUG_DRIVER("RP1(Guar Freq) GPU freq: %d MHz (%u)\n",
-			 intel_gpu_freq(rps, rps->rp1_freq),
-			 rps->rp1_freq);
+	drm_dbg(&i915->drm, "RP1(Guar Freq) GPU freq: %d MHz (%u)\n",
+		intel_gpu_freq(rps, rps->rp1_freq), rps->rp1_freq);
 
 	rps->min_freq = vlv_rps_min_freq(rps);
-	DRM_DEBUG_DRIVER("min GPU freq: %d MHz (%u)\n",
-			 intel_gpu_freq(rps, rps->min_freq),
-			 rps->min_freq);
+	drm_dbg(&i915->drm, "min GPU freq: %d MHz (%u)\n",
+		intel_gpu_freq(rps, rps->min_freq), rps->min_freq);
 
 	vlv_iosf_sb_put(i915,
 			BIT(VLV_IOSF_SB_PUNIT) |
@@ -1384,28 +1383,24 @@ static void chv_rps_init(struct intel_rps *rps)
 		i915->mem_freq = 1600;
 		break;
 	}
-	DRM_DEBUG_DRIVER("DDR speed: %d MHz\n", i915->mem_freq);
+	drm_dbg(&i915->drm, "DDR speed: %d MHz\n", i915->mem_freq);
 
 	rps->max_freq = chv_rps_max_freq(rps);
 	rps->rp0_freq = rps->max_freq;
-	DRM_DEBUG_DRIVER("max GPU freq: %d MHz (%u)\n",
-			 intel_gpu_freq(rps, rps->max_freq),
-			 rps->max_freq);
+	drm_dbg(&i915->drm, "max GPU freq: %d MHz (%u)\n",
+		intel_gpu_freq(rps, rps->max_freq), rps->max_freq);
 
 	rps->efficient_freq = chv_rps_rpe_freq(rps);
-	DRM_DEBUG_DRIVER("RPe GPU freq: %d MHz (%u)\n",
-			 intel_gpu_freq(rps, rps->efficient_freq),
-			 rps->efficient_freq);
+	drm_dbg(&i915->drm, "RPe GPU freq: %d MHz (%u)\n",
+		intel_gpu_freq(rps, rps->efficient_freq), rps->efficient_freq);
 
 	rps->rp1_freq = chv_rps_guar_freq(rps);
-	DRM_DEBUG_DRIVER("RP1(Guar) GPU freq: %d MHz (%u)\n",
-			 intel_gpu_freq(rps, rps->rp1_freq),
-			 rps->rp1_freq);
+	drm_dbg(&i915->drm, "RP1(Guar) GPU freq: %d MHz (%u)\n",
+		intel_gpu_freq(rps, rps->rp1_freq), rps->rp1_freq);
 
 	rps->min_freq = chv_rps_min_freq(rps);
-	DRM_DEBUG_DRIVER("min GPU freq: %d MHz (%u)\n",
-			 intel_gpu_freq(rps, rps->min_freq),
-			 rps->min_freq);
+	drm_dbg(&i915->drm, "min GPU freq: %d MHz (%u)\n",
+		intel_gpu_freq(rps, rps->min_freq), rps->min_freq);
 
 	vlv_iosf_sb_put(i915,
 			BIT(VLV_IOSF_SB_PUNIT) |
@@ -1468,6 +1463,7 @@ static void rps_work(struct work_struct *work)
 {
 	struct intel_rps *rps = container_of(work, typeof(*rps), work);
 	struct intel_gt *gt = rps_to_gt(rps);
+	struct drm_i915_private *i915 = rps_to_i915(rps);
 	bool client_boost = false;
 	int new_freq, adj, min, max;
 	u32 pm_iir = 0;
@@ -1543,7 +1539,7 @@ static void rps_work(struct work_struct *work)
 	new_freq = clamp_t(int, new_freq, min, max);
 
 	if (intel_rps_set(rps, new_freq)) {
-		DRM_DEBUG_DRIVER("Failed to set new GPU frequency\n");
+		drm_dbg(&i915->drm, "Failed to set new GPU frequency\n");
 		rps->last_adj = 0;
 	}
 
@@ -1665,9 +1661,10 @@ void intel_rps_init(struct intel_rps *rps)
 		sandybridge_pcode_read(i915, GEN6_READ_OC_PARAMS,
 				       &params, NULL);
 		if (params & BIT(31)) { /* OC supported */
-			DRM_DEBUG_DRIVER("Overclocking supported, max: %dMHz, overclock: %dMHz\n",
-					 (rps->max_freq & 0xff) * 50,
-					 (params & 0xff) * 50);
+			drm_dbg(&i915->drm,
+				"Overclocking supported, max: %dMHz, overclock: %dMHz\n",
+				(rps->max_freq & 0xff) * 50,
+				(params & 0xff) * 50);
 			rps->max_freq = params & 0xff;
 		}
 	}
@@ -1675,7 +1672,9 @@ void intel_rps_init(struct intel_rps *rps)
 	/* Finally allow us to boost to max by default */
 	rps->boost_freq = rps->max_freq;
 	rps->idle_freq = rps->min_freq;
-	rps->cur_freq = rps->idle_freq;
+
+	/* Start in the middle, from here we will autotune based on workload */
+	rps->cur_freq = rps->efficient_freq;
 
 	rps->pm_intrmsk_mbz = 0;
 
@@ -1927,3 +1926,7 @@ bool i915_gpu_turbo_disable(void)
 	return ret;
 }
 EXPORT_SYMBOL_GPL(i915_gpu_turbo_disable);
+
+#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
+#include "selftest_rps.c"
+#endif
diff --git a/drivers/gpu/drm/i915/gt/intel_sseu.c b/drivers/gpu/drm/i915/gt/intel_sseu.c
index 74f793423231..d173271c7397 100644
--- a/drivers/gpu/drm/i915/gt/intel_sseu.c
+++ b/drivers/gpu/drm/i915/gt/intel_sseu.c
@@ -65,7 +65,6 @@ u32 intel_sseu_make_rpcs(struct drm_i915_private *i915,
 {
 	const struct sseu_dev_info *sseu = &RUNTIME_INFO(i915)->sseu;
 	bool subslice_pg = sseu->has_subslice_pg;
-	struct intel_sseu ctx_sseu;
 	u8 slices, subslices;
 	u32 rpcs = 0;
 
@@ -78,31 +77,13 @@ u32 intel_sseu_make_rpcs(struct drm_i915_private *i915,
 
 	/*
 	 * If i915/perf is active, we want a stable powergating configuration
-	 * on the system.
-	 *
-	 * We could choose full enablement, but on ICL we know there are use
-	 * cases which disable slices for functional, apart for performance
-	 * reasons. So in this case we select a known stable subset.
+	 * on the system. Use the configuration pinned by i915/perf.
 	 */
-	if (!i915->perf.exclusive_stream) {
-		ctx_sseu = *req_sseu;
-	} else {
-		ctx_sseu = intel_sseu_from_device_info(sseu);
-
-		if (IS_GEN(i915, 11)) {
-			/*
-			 * We only need subslice count so it doesn't matter
-			 * which ones we select - just turn off low bits in the
-			 * amount of half of all available subslices per slice.
-			 */
-			ctx_sseu.subslice_mask =
-				~(~0 << (hweight8(ctx_sseu.subslice_mask) / 2));
-			ctx_sseu.slice_mask = 0x1;
-		}
-	}
+	if (i915->perf.exclusive_stream)
+		req_sseu = &i915->perf.sseu;
 
-	slices = hweight8(ctx_sseu.slice_mask);
-	subslices = hweight8(ctx_sseu.subslice_mask);
+	slices = hweight8(req_sseu->slice_mask);
+	subslices = hweight8(req_sseu->subslice_mask);
 
 	/*
 	 * Since the SScount bitfield in GEN8_R_PWR_CLK_STATE is only three bits
@@ -175,13 +156,13 @@ u32 intel_sseu_make_rpcs(struct drm_i915_private *i915,
 	if (sseu->has_eu_pg) {
 		u32 val;
 
-		val = ctx_sseu.min_eus_per_subslice << GEN8_RPCS_EU_MIN_SHIFT;
+		val = req_sseu->min_eus_per_subslice << GEN8_RPCS_EU_MIN_SHIFT;
 		GEM_BUG_ON(val & ~GEN8_RPCS_EU_MIN_MASK);
 		val &= GEN8_RPCS_EU_MIN_MASK;
 
 		rpcs |= val;
 
-		val = ctx_sseu.max_eus_per_subslice << GEN8_RPCS_EU_MAX_SHIFT;
+		val = req_sseu->max_eus_per_subslice << GEN8_RPCS_EU_MAX_SHIFT;
 		GEM_BUG_ON(val & ~GEN8_RPCS_EU_MAX_MASK);
 		val &= GEN8_RPCS_EU_MAX_MASK;
 
diff --git a/drivers/gpu/drm/i915/gt/intel_timeline.c b/drivers/gpu/drm/i915/gt/intel_timeline.c
index 91debbc97c9a..3779c2ae0d65 100644
--- a/drivers/gpu/drm/i915/gt/intel_timeline.c
+++ b/drivers/gpu/drm/i915/gt/intel_timeline.c
@@ -119,6 +119,15 @@ static void __idle_hwsp_free(struct intel_timeline_hwsp *hwsp, int cacheline)
 	spin_unlock_irqrestore(&gt->hwsp_lock, flags);
 }
 
+static void __rcu_cacheline_free(struct rcu_head *rcu)
+{
+	struct intel_timeline_cacheline *cl =
+		container_of(rcu, typeof(*cl), rcu);
+
+	i915_active_fini(&cl->active);
+	kfree(cl);
+}
+
 static void __idle_cacheline_free(struct intel_timeline_cacheline *cl)
 {
 	GEM_BUG_ON(!i915_active_is_idle(&cl->active));
@@ -127,8 +136,7 @@ static void __idle_cacheline_free(struct intel_timeline_cacheline *cl)
 	i915_vma_put(cl->hwsp->vma);
 	__idle_hwsp_free(cl->hwsp, ptr_unmask_bits(cl->vaddr, CACHELINE_BITS));
 
-	i915_active_fini(&cl->active);
-	kfree_rcu(cl, rcu);
+	call_rcu(&cl->rcu, __rcu_cacheline_free);
 }
 
 __i915_active_call
diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c b/drivers/gpu/drm/i915/gt/intel_workarounds.c
index 5176ad1a3976..adddc5c93b48 100644
--- a/drivers/gpu/drm/i915/gt/intel_workarounds.c
+++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c
@@ -837,7 +837,7 @@ wa_init_mcr(struct drm_i915_private *i915, struct i915_wa_list *wal)
 			intel_uncore_read(&i915->uncore, GEN10_MIRROR_FUSE3) &
 			GEN10_L3BANK_MASK;
 
-		DRM_DEBUG_DRIVER("L3 fuse = %x\n", l3_fuse);
+		drm_dbg(&i915->drm, "L3 fuse = %x\n", l3_fuse);
 		l3_en = ~(l3_fuse << GEN10_L3BANK_PAIR_COUNT | l3_fuse);
 	} else {
 		l3_en = ~0;
@@ -846,7 +846,8 @@ wa_init_mcr(struct drm_i915_private *i915, struct i915_wa_list *wal)
 	slice = fls(sseu->slice_mask) - 1;
 	subslice = fls(l3_en & intel_sseu_get_subslices(sseu, slice));
 	if (!subslice) {
-		DRM_WARN("No common index found between subslice mask %x and L3 bank mask %x!\n",
+		drm_warn(&i915->drm,
+			 "No common index found between subslice mask %x and L3 bank mask %x!\n",
 			 intel_sseu_get_subslices(sseu, slice), l3_en);
 		subslice = fls(l3_en);
 		drm_WARN_ON(&i915->drm, !subslice);
@@ -861,7 +862,7 @@ wa_init_mcr(struct drm_i915_private *i915, struct i915_wa_list *wal)
 		mcr_mask = GEN8_MCR_SLICE_MASK | GEN8_MCR_SUBSLICE_MASK;
 	}
 
-	DRM_DEBUG_DRIVER("MCR slice/subslice = %x\n", mcr);
+	drm_dbg(&i915->drm, "MCR slice/subslice = %x\n", mcr);
 
 	wa_write_masked_or(wal, GEN8_MCR_SELECTOR, mcr_mask, mcr);
 }
@@ -942,6 +943,8 @@ icl_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal)
 static void
 tgl_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal)
 {
+	wa_init_mcr(i915, wal);
+
 	/* Wa_1409420604:tgl */
 	if (IS_TGL_REVID(i915, TGL_REVID_A0, TGL_REVID_A0))
 		wa_write_or(wal,
@@ -1379,12 +1382,6 @@ rcs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal)
 			    GEN7_FF_THREAD_MODE,
 			    GEN12_FF_TESSELATION_DOP_GATE_DISABLE);
 
-		/*
-		 * Wa_1409085225:tgl
-		 * Wa_14010229206:tgl
-		 */
-		wa_masked_en(wal, GEN9_ROW_CHICKEN4, GEN12_DISABLE_TDL_PUSH);
-
 		/* Wa_1408615072:tgl */
 		wa_write_or(wal, UNSLICE_UNIT_LEVEL_CLKGATE2,
 			    VSUNIT_CLKGATE_DIS_TGL);
@@ -1402,6 +1399,12 @@ rcs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal)
 		wa_masked_en(wal,
 			     GEN9_CS_DEBUG_MODE1,
 			     FF_DOP_CLOCK_GATE_DISABLE);
+
+		/*
+		 * Wa_1409085225:tgl
+		 * Wa_14010229206:tgl
+		 */
+		wa_masked_en(wal, GEN9_ROW_CHICKEN4, GEN12_DISABLE_TDL_PUSH);
 	}
 
 	if (IS_GEN(i915, 11)) {
diff --git a/drivers/gpu/drm/i915/gt/selftest_gt_pm.c b/drivers/gpu/drm/i915/gt/selftest_gt_pm.c
index 09ff8e4f88af..c50bb502fe03 100644
--- a/drivers/gpu/drm/i915/gt/selftest_gt_pm.c
+++ b/drivers/gpu/drm/i915/gt/selftest_gt_pm.c
@@ -7,6 +7,7 @@
 
 #include "selftest_llc.h"
 #include "selftest_rc6.h"
+#include "selftest_rps.h"
 
 static int live_gt_resume(void *arg)
 {
@@ -52,6 +53,7 @@ int intel_gt_pm_live_selftests(struct drm_i915_private *i915)
 {
 	static const struct i915_subtest tests[] = {
 		SUBTEST(live_rc6_manual),
+		SUBTEST(live_rps_interrupt),
 		SUBTEST(live_gt_resume),
 	};
 
diff --git a/drivers/gpu/drm/i915/gt/selftest_lrc.c b/drivers/gpu/drm/i915/gt/selftest_lrc.c
index 6f06ba750a0a..6f5e35afe1b2 100644
--- a/drivers/gpu/drm/i915/gt/selftest_lrc.c
+++ b/drivers/gpu/drm/i915/gt/selftest_lrc.c
@@ -68,26 +68,41 @@ static void engine_heartbeat_enable(struct intel_engine_cs *engine,
 	engine->props.heartbeat_interval_ms = saved;
 }
 
+static bool is_active(struct i915_request *rq)
+{
+	if (i915_request_is_active(rq))
+		return true;
+
+	if (i915_request_on_hold(rq))
+		return true;
+
+	if (i915_request_started(rq))
+		return true;
+
+	return false;
+}
+
 static int wait_for_submit(struct intel_engine_cs *engine,
 			   struct i915_request *rq,
 			   unsigned long timeout)
 {
 	timeout += jiffies;
 	do {
-		cond_resched();
-		intel_engine_flush_submission(engine);
-
-		if (READ_ONCE(engine->execlists.pending[0]))
-			continue;
+		bool done = time_after(jiffies, timeout);
 
-		if (i915_request_is_active(rq))
+		if (i915_request_completed(rq)) /* that was quick! */
 			return 0;
 
-		if (i915_request_started(rq)) /* that was quick! */
+		/* Wait until the HW has acknowleged the submission (or err) */
+		intel_engine_flush_submission(engine);
+		if (!READ_ONCE(engine->execlists.pending[0]) && is_active(rq))
 			return 0;
-	} while (time_before(jiffies, timeout));
 
-	return -ETIME;
+		if (done)
+			return -ETIME;
+
+		cond_resched();
+	} while (1);
 }
 
 static int wait_for_reset(struct intel_engine_cs *engine,
@@ -634,9 +649,9 @@ static int live_error_interrupt(void *arg)
 						 error_repr(p->error[i]));
 
 				if (!i915_request_started(client[i])) {
-					pr_debug("%s: %s request not stated!\n",
-						 engine->name,
-						 error_repr(p->error[i]));
+					pr_err("%s: %s request not started!\n",
+					       engine->name,
+					       error_repr(p->error[i]));
 					err = -ETIME;
 					goto out;
 				}
@@ -644,9 +659,10 @@ static int live_error_interrupt(void *arg)
 				/* Kick the tasklet to process the error */
 				intel_engine_flush_submission(engine);
 				if (client[i]->fence.error != p->error[i]) {
-					pr_err("%s: %s request completed with wrong error code: %d\n",
+					pr_err("%s: %s request (%s) with wrong error code: %d\n",
 					       engine->name,
 					       error_repr(p->error[i]),
+					       i915_request_completed(client[i]) ? "completed" : "running",
 					       client[i]->fence.error);
 					err = -EINVAL;
 					goto out;
@@ -929,7 +945,7 @@ create_rewinder(struct intel_context *ce,
 			goto err;
 	}
 
-	cs = intel_ring_begin(rq, 10);
+	cs = intel_ring_begin(rq, 14);
 	if (IS_ERR(cs)) {
 		err = PTR_ERR(cs);
 		goto err;
@@ -941,8 +957,8 @@ create_rewinder(struct intel_context *ce,
 	*cs++ = MI_SEMAPHORE_WAIT |
 		MI_SEMAPHORE_GLOBAL_GTT |
 		MI_SEMAPHORE_POLL |
-		MI_SEMAPHORE_SAD_NEQ_SDD;
-	*cs++ = 0;
+		MI_SEMAPHORE_SAD_GTE_SDD;
+	*cs++ = idx;
 	*cs++ = offset;
 	*cs++ = 0;
 
@@ -951,6 +967,11 @@ create_rewinder(struct intel_context *ce,
 	*cs++ = offset + idx * sizeof(u32);
 	*cs++ = 0;
 
+	*cs++ = MI_STORE_DWORD_IMM_GEN4 | MI_USE_GGTT;
+	*cs++ = offset;
+	*cs++ = 0;
+	*cs++ = idx + 1;
+
 	intel_ring_advance(rq, cs);
 
 	rq->sched.attr.priority = I915_PRIORITY_MASK;
@@ -984,7 +1005,7 @@ static int live_timeslice_rewind(void *arg)
 
 	for_each_engine(engine, gt, id) {
 		enum { A1, A2, B1 };
-		enum { X = 1, Y, Z };
+		enum { X = 1, Z, Y };
 		struct i915_request *rq[3] = {};
 		struct intel_context *ce;
 		unsigned long heartbeat;
@@ -1017,13 +1038,13 @@ static int live_timeslice_rewind(void *arg)
 			goto err;
 		}
 
-		rq[0] = create_rewinder(ce, NULL, slot, 1);
+		rq[0] = create_rewinder(ce, NULL, slot, X);
 		if (IS_ERR(rq[0])) {
 			intel_context_put(ce);
 			goto err;
 		}
 
-		rq[1] = create_rewinder(ce, NULL, slot, 2);
+		rq[1] = create_rewinder(ce, NULL, slot, Y);
 		intel_context_put(ce);
 		if (IS_ERR(rq[1]))
 			goto err;
@@ -1041,7 +1062,7 @@ static int live_timeslice_rewind(void *arg)
 			goto err;
 		}
 
-		rq[2] = create_rewinder(ce, rq[0], slot, 3);
+		rq[2] = create_rewinder(ce, rq[0], slot, Z);
 		intel_context_put(ce);
 		if (IS_ERR(rq[2]))
 			goto err;
@@ -1052,18 +1073,14 @@ static int live_timeslice_rewind(void *arg)
 			       engine->name);
 			goto err;
 		}
-		GEM_BUG_ON(!timer_pending(&engine->execlists.timer));
 
 		/* ELSP[] = { { A:rq1, A:rq2 }, { B:rq1 } } */
-		GEM_BUG_ON(!i915_request_is_active(rq[A1]));
-		GEM_BUG_ON(!i915_request_is_active(rq[A2]));
-		GEM_BUG_ON(!i915_request_is_active(rq[B1]));
-
-		/* Wait for the timeslice to kick in */
-		del_timer(&engine->execlists.timer);
-		tasklet_hi_schedule(&engine->execlists.tasklet);
-		intel_engine_flush_submission(engine);
-
+		if (i915_request_is_active(rq[A2])) { /* semaphore yielded! */
+			/* Wait for the timeslice to kick in */
+			del_timer(&engine->execlists.timer);
+			tasklet_hi_schedule(&engine->execlists.tasklet);
+			intel_engine_flush_submission(engine);
+		}
 		/* -> ELSP[] = { { A:rq1 }, { B:rq1 } } */
 		GEM_BUG_ON(!i915_request_is_active(rq[A1]));
 		GEM_BUG_ON(!i915_request_is_active(rq[B1]));
@@ -1228,8 +1245,14 @@ static int live_timeslice_queue(void *arg)
 		if (err)
 			goto err_rq;
 
-		intel_engine_flush_submission(engine);
+		/* Wait until we ack the release_queue and start timeslicing */
+		do {
+			cond_resched();
+			intel_engine_flush_submission(engine);
+		} while (READ_ONCE(engine->execlists.pending[0]));
+
 		if (!READ_ONCE(engine->execlists.timer.expires) &&
+		    execlists_active(&engine->execlists) == rq &&
 		    !i915_request_completed(rq)) {
 			struct drm_printer p =
 				drm_info_printer(gt->i915->drm.dev);
@@ -2030,6 +2053,9 @@ static int __cancel_hostile(struct live_preempt_cancel *arg)
 	if (!IS_ACTIVE(CONFIG_DRM_I915_PREEMPT_TIMEOUT))
 		return 0;
 
+	if (!intel_has_reset_engine(arg->engine->gt))
+		return 0;
+
 	GEM_TRACE("%s(%s)\n", __func__, arg->engine->name);
 	rq = spinner_create_request(&arg->a.spin,
 				    arg->a.ctx, arg->engine,
@@ -2630,7 +2656,7 @@ static int create_gang(struct intel_engine_cs *engine,
 	if (IS_ERR(rq))
 		goto err_obj;
 
-	rq->batch = vma;
+	rq->batch = i915_vma_get(vma);
 	i915_request_get(rq);
 
 	i915_vma_lock(vma);
@@ -2654,6 +2680,7 @@ static int create_gang(struct intel_engine_cs *engine,
 	return 0;
 
 err_rq:
+	i915_vma_put(rq->batch);
 	i915_request_put(rq);
 err_obj:
 	i915_gem_object_put(obj);
@@ -2750,6 +2777,7 @@ static int live_preempt_gang(void *arg)
 				err = -ETIME;
 			}
 
+			i915_vma_put(rq->batch);
 			i915_request_put(rq);
 			rq = n;
 		}
@@ -5155,7 +5183,6 @@ static int compare_isolation(struct intel_engine_cs *engine,
 					       A[0][x], B[0][x], B[1][x],
 					       poison, lrc[dw + 1]);
 					err = -EINVAL;
-					break;
 				}
 			}
 			dw += 2;
@@ -5294,6 +5321,7 @@ static int live_lrc_isolation(void *arg)
 		0xffffffff,
 		0xffff0000,
 	};
+	int err = 0;
 
 	/*
 	 * Our goal is try and verify that per-context state cannot be
@@ -5304,7 +5332,6 @@ static int live_lrc_isolation(void *arg)
 	 */
 
 	for_each_engine(engine, gt, id) {
-		int err = 0;
 		int i;
 
 		/* Just don't even ask */
@@ -5315,23 +5342,25 @@ static int live_lrc_isolation(void *arg)
 		intel_engine_pm_get(engine);
 		if (engine->pinned_default_state) {
 			for (i = 0; i < ARRAY_SIZE(poison); i++) {
-				err = __lrc_isolation(engine, poison[i]);
-				if (err)
-					break;
+				int result;
 
-				err = __lrc_isolation(engine, ~poison[i]);
-				if (err)
-					break;
+				result = __lrc_isolation(engine, poison[i]);
+				if (result && !err)
+					err = result;
+
+				result = __lrc_isolation(engine, ~poison[i]);
+				if (result && !err)
+					err = result;
 			}
 		}
 		intel_engine_pm_put(engine);
-		if (igt_flush_test(gt->i915))
+		if (igt_flush_test(gt->i915)) {
 			err = -EIO;
-		if (err)
-			return err;
+			break;
+		}
 	}
 
-	return 0;
+	return err;
 }
 
 static void garbage_reset(struct intel_engine_cs *engine,
diff --git a/drivers/gpu/drm/i915/gt/selftest_rc6.c b/drivers/gpu/drm/i915/gt/selftest_rc6.c
index 95b165faeba7..08c3dbd41b12 100644
--- a/drivers/gpu/drm/i915/gt/selftest_rc6.c
+++ b/drivers/gpu/drm/i915/gt/selftest_rc6.c
@@ -12,6 +12,22 @@
 
 #include "selftests/i915_random.h"
 
+static u64 energy_uJ(struct intel_rc6 *rc6)
+{
+	unsigned long long power;
+	u32 units;
+
+	if (rdmsrl_safe(MSR_RAPL_POWER_UNIT, &power))
+		return 0;
+
+	units = (power & 0x1f00) >> 8;
+
+	if (rdmsrl_safe(MSR_PP1_ENERGY_STATUS, &power))
+		return 0;
+
+	return (1000000 * power) >> units; /* convert to uJ */
+}
+
 static u64 rc6_residency(struct intel_rc6 *rc6)
 {
 	u64 result;
@@ -31,7 +47,9 @@ int live_rc6_manual(void *arg)
 {
 	struct intel_gt *gt = arg;
 	struct intel_rc6 *rc6 = &gt->rc6;
+	u64 rc0_power, rc6_power;
 	intel_wakeref_t wakeref;
+	ktime_t dt;
 	u64 res[2];
 	int err = 0;
 
@@ -54,7 +72,12 @@ int live_rc6_manual(void *arg)
 	msleep(1); /* wakeup is not immediate, takes about 100us on icl */
 
 	res[0] = rc6_residency(rc6);
+
+	dt = ktime_get();
+	rc0_power = energy_uJ(rc6);
 	msleep(250);
+	rc0_power = energy_uJ(rc6) - rc0_power;
+	dt = ktime_sub(ktime_get(), dt);
 	res[1] = rc6_residency(rc6);
 	if ((res[1] - res[0]) >> 10) {
 		pr_err("RC6 residency increased by %lldus while disabled for 250ms!\n",
@@ -63,13 +86,24 @@ int live_rc6_manual(void *arg)
 		goto out_unlock;
 	}
 
+	rc0_power = div64_u64(NSEC_PER_SEC * rc0_power, ktime_to_ns(dt));
+	if (!rc0_power) {
+		pr_err("No power measured while in RC0\n");
+		err = -EINVAL;
+		goto out_unlock;
+	}
+
 	/* Manually enter RC6 */
 	intel_rc6_park(rc6);
 
 	res[0] = rc6_residency(rc6);
+	intel_uncore_forcewake_flush(rc6_to_uncore(rc6), FORCEWAKE_ALL);
+	dt = ktime_get();
+	rc6_power = energy_uJ(rc6);
 	msleep(100);
+	rc6_power = energy_uJ(rc6) - rc6_power;
+	dt = ktime_sub(ktime_get(), dt);
 	res[1] = rc6_residency(rc6);
-
 	if (res[1] == res[0]) {
 		pr_err("Did not enter RC6! RC6_STATE=%08x, RC6_CONTROL=%08x, residency=%lld\n",
 		       intel_uncore_read_fw(gt->uncore, GEN6_RC_STATE),
@@ -78,6 +112,15 @@ int live_rc6_manual(void *arg)
 		err = -EINVAL;
 	}
 
+	rc6_power = div64_u64(NSEC_PER_SEC * rc6_power, ktime_to_ns(dt));
+	pr_info("GPU consumed %llduW in RC0 and %llduW in RC6\n",
+		rc0_power, rc6_power);
+	if (2 * rc6_power > rc0_power) {
+		pr_err("GPU leaked energy while in RC6!\n");
+		err = -EINVAL;
+		goto out_unlock;
+	}
+
 	/* Restore what should have been the original state! */
 	intel_rc6_unpark(rc6);
 
diff --git a/drivers/gpu/drm/i915/gt/selftest_rps.c b/drivers/gpu/drm/i915/gt/selftest_rps.c
new file mode 100644
index 000000000000..26aadc2ae3be
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/selftest_rps.c
@@ -0,0 +1,223 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2020 Intel Corporation
+ */
+
+#include "intel_engine_pm.h"
+#include "intel_gt_pm.h"
+#include "intel_rc6.h"
+#include "selftest_rps.h"
+#include "selftests/igt_flush_test.h"
+#include "selftests/igt_spinner.h"
+
+static void dummy_rps_work(struct work_struct *wrk)
+{
+}
+
+static int __rps_up_interrupt(struct intel_rps *rps,
+			      struct intel_engine_cs *engine,
+			      struct igt_spinner *spin)
+{
+	struct intel_uncore *uncore = engine->uncore;
+	struct i915_request *rq;
+	u32 timeout;
+
+	if (!intel_engine_can_store_dword(engine))
+		return 0;
+
+	intel_gt_pm_wait_for_idle(engine->gt);
+	GEM_BUG_ON(rps->active);
+
+	rps->pm_iir = 0;
+	rps->cur_freq = rps->min_freq;
+
+	rq = igt_spinner_create_request(spin, engine->kernel_context, MI_NOOP);
+	if (IS_ERR(rq))
+		return PTR_ERR(rq);
+
+	i915_request_get(rq);
+	i915_request_add(rq);
+
+	if (!igt_wait_for_spinner(spin, rq)) {
+		pr_err("%s: RPS spinner did not start\n",
+		       engine->name);
+		i915_request_put(rq);
+		intel_gt_set_wedged(engine->gt);
+		return -EIO;
+	}
+
+	if (!rps->active) {
+		pr_err("%s: RPS not enabled on starting spinner\n",
+		       engine->name);
+		igt_spinner_end(spin);
+		i915_request_put(rq);
+		return -EINVAL;
+	}
+
+	if (!(rps->pm_events & GEN6_PM_RP_UP_THRESHOLD)) {
+		pr_err("%s: RPS did not register UP interrupt\n",
+		       engine->name);
+		i915_request_put(rq);
+		return -EINVAL;
+	}
+
+	if (rps->last_freq != rps->min_freq) {
+		pr_err("%s: RPS did not program min frequency\n",
+		       engine->name);
+		i915_request_put(rq);
+		return -EINVAL;
+	}
+
+	timeout = intel_uncore_read(uncore, GEN6_RP_UP_EI);
+	timeout = GT_PM_INTERVAL_TO_US(engine->i915, timeout);
+
+	usleep_range(2 * timeout, 3 * timeout);
+	GEM_BUG_ON(i915_request_completed(rq));
+
+	igt_spinner_end(spin);
+	i915_request_put(rq);
+
+	if (rps->cur_freq != rps->min_freq) {
+		pr_err("%s: Frequency unexpectedly changed [up], now %d!\n",
+		       engine->name, intel_rps_read_actual_frequency(rps));
+		return -EINVAL;
+	}
+
+	if (!(rps->pm_iir & GEN6_PM_RP_UP_THRESHOLD)) {
+		pr_err("%s: UP interrupt not recorded for spinner, pm_iir:%x, prev_up:%x, up_threshold:%x, up_ei:%x\n",
+		       engine->name, rps->pm_iir,
+		       intel_uncore_read(uncore, GEN6_RP_PREV_UP),
+		       intel_uncore_read(uncore, GEN6_RP_UP_THRESHOLD),
+		       intel_uncore_read(uncore, GEN6_RP_UP_EI));
+		return -EINVAL;
+	}
+
+	intel_gt_pm_wait_for_idle(engine->gt);
+	return 0;
+}
+
+static int __rps_down_interrupt(struct intel_rps *rps,
+				struct intel_engine_cs *engine)
+{
+	struct intel_uncore *uncore = engine->uncore;
+	u32 timeout;
+
+	mutex_lock(&rps->lock);
+	GEM_BUG_ON(!rps->active);
+	intel_rps_set(rps, rps->max_freq);
+	mutex_unlock(&rps->lock);
+
+	if (!(rps->pm_events & GEN6_PM_RP_DOWN_THRESHOLD)) {
+		pr_err("%s: RPS did not register DOWN interrupt\n",
+		       engine->name);
+		return -EINVAL;
+	}
+
+	if (rps->last_freq != rps->max_freq) {
+		pr_err("%s: RPS did not program max frequency\n",
+		       engine->name);
+		return -EINVAL;
+	}
+
+	timeout = intel_uncore_read(uncore, GEN6_RP_DOWN_EI);
+	timeout = GT_PM_INTERVAL_TO_US(engine->i915, timeout);
+
+	/* Flush any previous EI */
+	usleep_range(timeout, 2 * timeout);
+
+	/* Reset the interrupt status */
+	rps_disable_interrupts(rps);
+	GEM_BUG_ON(rps->pm_iir);
+	rps_enable_interrupts(rps);
+
+	/* And then wait for the timeout, for real this time */
+	usleep_range(2 * timeout, 3 * timeout);
+
+	if (rps->cur_freq != rps->max_freq) {
+		pr_err("%s: Frequency unexpectedly changed [down], now %d!\n",
+		       engine->name,
+		       intel_rps_read_actual_frequency(rps));
+		return -EINVAL;
+	}
+
+	if (!(rps->pm_iir & (GEN6_PM_RP_DOWN_THRESHOLD | GEN6_PM_RP_DOWN_TIMEOUT))) {
+		pr_err("%s: DOWN interrupt not recorded for idle, pm_iir:%x, prev_down:%x, down_threshold:%x, down_ei:%x [prev_up:%x, up_threshold:%x, up_ei:%x]\n",
+		       engine->name, rps->pm_iir,
+		       intel_uncore_read(uncore, GEN6_RP_PREV_DOWN),
+		       intel_uncore_read(uncore, GEN6_RP_DOWN_THRESHOLD),
+		       intel_uncore_read(uncore, GEN6_RP_DOWN_EI),
+		       intel_uncore_read(uncore, GEN6_RP_PREV_UP),
+		       intel_uncore_read(uncore, GEN6_RP_UP_THRESHOLD),
+		       intel_uncore_read(uncore, GEN6_RP_UP_EI));
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int live_rps_interrupt(void *arg)
+{
+	struct intel_gt *gt = arg;
+	struct intel_rps *rps = &gt->rps;
+	void (*saved_work)(struct work_struct *wrk);
+	struct intel_engine_cs *engine;
+	enum intel_engine_id id;
+	struct igt_spinner spin;
+	u32 pm_events;
+	int err = 0;
+
+	/*
+	 * First, let's check whether or not we are receiving interrupts.
+	 */
+
+	if (!rps->enabled || rps->max_freq <= rps->min_freq)
+		return 0;
+
+	intel_gt_pm_get(gt);
+	pm_events = rps->pm_events;
+	intel_gt_pm_put(gt);
+	if (!pm_events) {
+		pr_err("No RPS PM events registered, but RPS is enabled?\n");
+		return -ENODEV;
+	}
+
+	if (igt_spinner_init(&spin, gt))
+		return -ENOMEM;
+
+	intel_gt_pm_wait_for_idle(gt);
+	saved_work = rps->work.func;
+	rps->work.func = dummy_rps_work;
+
+	for_each_engine(engine, gt, id) {
+		/* Keep the engine busy with a spinner; expect an UP! */
+		if (pm_events & GEN6_PM_RP_UP_THRESHOLD) {
+			err = __rps_up_interrupt(rps, engine, &spin);
+			if (err)
+				goto out;
+		}
+
+		/* Keep the engine awake but idle and check for DOWN */
+		if (pm_events & GEN6_PM_RP_DOWN_THRESHOLD) {
+			intel_engine_pm_get(engine);
+			intel_rc6_disable(&gt->rc6);
+
+			err = __rps_down_interrupt(rps, engine);
+
+			intel_rc6_enable(&gt->rc6);
+			intel_engine_pm_put(engine);
+			if (err)
+				goto out;
+		}
+	}
+
+out:
+	if (igt_flush_test(gt->i915))
+		err = -EIO;
+
+	igt_spinner_fini(&spin);
+
+	intel_gt_pm_wait_for_idle(gt);
+	rps->work.func = saved_work;
+
+	return err;
+}
diff --git a/drivers/gpu/drm/i915/gt/selftest_rps.h b/drivers/gpu/drm/i915/gt/selftest_rps.h
new file mode 100644
index 000000000000..abba66420996
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/selftest_rps.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2020 Intel Corporation
+ */
+
+#ifndef SELFTEST_RPS_H
+#define SELFTEST_RPS_H
+
+int live_rps_interrupt(void *arg);
+
+#endif /* SELFTEST_RPS_H */
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
index 819f09ef51fc..861657897c0f 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -169,7 +169,7 @@ void intel_guc_init_early(struct intel_guc *guc)
 {
 	struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
 
-	intel_guc_fw_init_early(guc);
+	intel_uc_fw_init_early(&guc->fw, INTEL_UC_FW_TYPE_GUC);
 	intel_guc_ct_init_early(&guc->ct);
 	intel_guc_log_init_early(&guc->log);
 	intel_guc_submission_init_early(guc);
@@ -723,3 +723,47 @@ int intel_guc_allocate_and_map_vma(struct intel_guc *guc, u32 size,
 
 	return 0;
 }
+
+/**
+ * intel_guc_load_status - dump information about GuC load status
+ * @guc: the GuC
+ * @p: the &drm_printer
+ *
+ * Pretty printer for GuC load status.
+ */
+void intel_guc_load_status(struct intel_guc *guc, struct drm_printer *p)
+{
+	struct intel_gt *gt = guc_to_gt(guc);
+	struct intel_uncore *uncore = gt->uncore;
+	intel_wakeref_t wakeref;
+
+	if (!intel_guc_is_supported(guc)) {
+		drm_printf(p, "GuC not supported\n");
+		return;
+	}
+
+	if (!intel_guc_is_wanted(guc)) {
+		drm_printf(p, "GuC disabled\n");
+		return;
+	}
+
+	intel_uc_fw_dump(&guc->fw, p);
+
+	with_intel_runtime_pm(uncore->rpm, wakeref) {
+		u32 status = intel_uncore_read(uncore, GUC_STATUS);
+		u32 i;
+
+		drm_printf(p, "\nGuC status 0x%08x:\n", status);
+		drm_printf(p, "\tBootrom status = 0x%x\n",
+			   (status & GS_BOOTROM_MASK) >> GS_BOOTROM_SHIFT);
+		drm_printf(p, "\tuKernel status = 0x%x\n",
+			   (status & GS_UKERNEL_MASK) >> GS_UKERNEL_SHIFT);
+		drm_printf(p, "\tMIA Core status = 0x%x\n",
+			   (status & GS_MIA_MASK) >> GS_MIA_SHIFT);
+		drm_puts(p, "\nScratch registers:\n");
+		for (i = 0; i < 16; i++) {
+			drm_printf(p, "\t%2d: \t0x%x\n",
+				   i, intel_uncore_read(uncore, SOFT_SCRATCH(i)));
+		}
+	}
+}
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index 4594ccbeaa34..e84ab67b317d 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -74,6 +74,11 @@ struct intel_guc {
 	struct mutex send_mutex;
 };
 
+static inline struct intel_guc *log_to_guc(struct intel_guc_log *log)
+{
+	return container_of(log, struct intel_guc, log);
+}
+
 static
 inline int intel_guc_send(struct intel_guc *guc, const u32 *action, u32 len)
 {
@@ -190,4 +195,6 @@ static inline void intel_guc_disable_msg(struct intel_guc *guc, u32 mask)
 int intel_guc_reset_engine(struct intel_guc *guc,
 			   struct intel_engine_cs *engine);
 
+void intel_guc_load_status(struct intel_guc *guc, struct drm_printer *p);
+
 #endif
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_debugfs.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_debugfs.c
new file mode 100644
index 000000000000..fe7cb7b29a1e
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_debugfs.c
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2020 Intel Corporation
+ */
+
+#include <drm/drm_print.h>
+
+#include "gt/debugfs_gt.h"
+#include "intel_guc.h"
+#include "intel_guc_debugfs.h"
+#include "intel_guc_log_debugfs.h"
+
+static int guc_info_show(struct seq_file *m, void *data)
+{
+	struct intel_guc *guc = m->private;
+	struct drm_printer p = drm_seq_file_printer(m);
+
+	if (!intel_guc_is_supported(guc))
+		return -ENODEV;
+
+	intel_guc_load_status(guc, &p);
+	drm_puts(&p, "\n");
+	intel_guc_log_info(&guc->log, &p);
+
+	/* Add more as required ... */
+
+	return 0;
+}
+DEFINE_GT_DEBUGFS_ATTRIBUTE(guc_info);
+
+void intel_guc_debugfs_register(struct intel_guc *guc, struct dentry *root)
+{
+	static const struct debugfs_gt_file files[] = {
+		{ "guc_info", &guc_info_fops, NULL },
+	};
+
+	if (!intel_guc_is_supported(guc))
+		return;
+
+	intel_gt_debugfs_register_files(root, files, ARRAY_SIZE(files), guc);
+	intel_guc_log_debugfs_register(&guc->log, root);
+}
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_debugfs.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_debugfs.h
new file mode 100644
index 000000000000..424c26665cf1
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_debugfs.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2020 Intel Corporation
+ */
+
+#ifndef DEBUGFS_GUC_H
+#define DEBUGFS_GUC_H
+
+struct intel_guc;
+struct dentry;
+
+void intel_guc_debugfs_register(struct intel_guc *guc, struct dentry *root);
+
+#endif /* DEBUGFS_GUC_H */
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
index 3a1c47d600ea..d4a87f4c9421 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
@@ -13,20 +13,6 @@
 #include "intel_guc_fw.h"
 #include "i915_drv.h"
 
-/**
- * intel_guc_fw_init_early() - initializes GuC firmware struct
- * @guc: intel_guc struct
- *
- * On platforms with GuC selects firmware for uploading
- */
-void intel_guc_fw_init_early(struct intel_guc *guc)
-{
-	struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
-
-	intel_uc_fw_init_early(&guc->fw, INTEL_UC_FW_TYPE_GUC, HAS_GT_UC(i915),
-			       INTEL_INFO(i915)->platform, INTEL_REVID(i915));
-}
-
 static void guc_prepare_xfer(struct intel_uncore *uncore)
 {
 	u32 shim_flags = GUC_DISABLE_SRAM_INIT_TO_ZEROES |
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.h
index b5ab639d7259..0b4d2a9c9435 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.h
@@ -8,7 +8,6 @@
 
 struct intel_guc;
 
-void intel_guc_fw_init_early(struct intel_guc *guc);
 int intel_guc_fw_upload(struct intel_guc *guc);
 
 #endif
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
index caed0d57e704..fb10f3597ea5 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
@@ -55,11 +55,6 @@ static int guc_action_control_log(struct intel_guc *guc, bool enable,
 	return intel_guc_send(guc, action, ARRAY_SIZE(action));
 }
 
-static inline struct intel_guc *log_to_guc(struct intel_guc_log *log)
-{
-	return container_of(log, struct intel_guc, log);
-}
-
 static void guc_log_enable_flush_events(struct intel_guc_log *log)
 {
 	intel_guc_enable_msg(log_to_guc(log),
@@ -672,3 +667,95 @@ void intel_guc_log_handle_flush_event(struct intel_guc_log *log)
 {
 	queue_work(system_highpri_wq, &log->relay.flush_work);
 }
+
+static const char *
+stringify_guc_log_type(enum guc_log_buffer_type type)
+{
+	switch (type) {
+	case GUC_ISR_LOG_BUFFER:
+		return "ISR";
+	case GUC_DPC_LOG_BUFFER:
+		return "DPC";
+	case GUC_CRASH_DUMP_LOG_BUFFER:
+		return "CRASH";
+	default:
+		MISSING_CASE(type);
+	}
+
+	return "";
+}
+
+/**
+ * intel_guc_log_info - dump information about GuC log relay
+ * @log: the GuC log
+ * @p: the &drm_printer
+ *
+ * Pretty printer for GuC log info
+ */
+void intel_guc_log_info(struct intel_guc_log *log, struct drm_printer *p)
+{
+	enum guc_log_buffer_type type;
+
+	if (!intel_guc_log_relay_created(log)) {
+		drm_puts(p, "GuC log relay not created\n");
+		return;
+	}
+
+	drm_puts(p, "GuC logging stats:\n");
+
+	drm_printf(p, "\tRelay full count: %u\n", log->relay.full_count);
+
+	for (type = GUC_ISR_LOG_BUFFER; type < GUC_MAX_LOG_BUFFER; type++) {
+		drm_printf(p, "\t%s:\tflush count %10u, overflow count %10u\n",
+			   stringify_guc_log_type(type),
+			   log->stats[type].flush,
+			   log->stats[type].sampled_overflow);
+	}
+}
+
+/**
+ * intel_guc_log_dump - dump the contents of the GuC log
+ * @log: the GuC log
+ * @p: the &drm_printer
+ * @dump_load_err: dump the log saved on GuC load error
+ *
+ * Pretty printer for the GuC log
+ */
+int intel_guc_log_dump(struct intel_guc_log *log, struct drm_printer *p,
+		       bool dump_load_err)
+{
+	struct intel_guc *guc = log_to_guc(log);
+	struct intel_uc *uc = container_of(guc, struct intel_uc, guc);
+	struct drm_i915_gem_object *obj = NULL;
+	u32 *map;
+	int i = 0;
+
+	if (!intel_guc_is_supported(guc))
+		return -ENODEV;
+
+	if (dump_load_err)
+		obj = uc->load_err_log;
+	else if (guc->log.vma)
+		obj = guc->log.vma->obj;
+
+	if (!obj)
+		return 0;
+
+	map = i915_gem_object_pin_map(obj, I915_MAP_WC);
+	if (IS_ERR(map)) {
+		DRM_DEBUG("Failed to pin object\n");
+		drm_puts(p, "(log data unaccessible)\n");
+		return PTR_ERR(map);
+	}
+
+	for (i = 0; i < obj->base.size / sizeof(u32); i += 4)
+		drm_printf(p, "0x%08x 0x%08x 0x%08x 0x%08x\n",
+			   *(map + i), *(map + i + 1),
+			   *(map + i + 2), *(map + i + 3));
+
+	drm_puts(p, "\n");
+
+	i915_gem_object_unpin_map(obj);
+
+	return 0;
+}
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
index c252c022c5fc..11fccd0b2294 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
@@ -79,4 +79,8 @@ static inline u32 intel_guc_log_get_level(struct intel_guc_log *log)
 	return log->level;
 }
 
+void intel_guc_log_info(struct intel_guc_log *log, struct drm_printer *p);
+int intel_guc_log_dump(struct intel_guc_log *log, struct drm_printer *p,
+		       bool dump_load_err);
+
 #endif
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log_debugfs.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_log_debugfs.c
new file mode 100644
index 000000000000..129e0cf7dfe2
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log_debugfs.c
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2020 Intel Corporation
+ */
+
+#include <linux/fs.h>
+#include <drm/drm_print.h>
+
+#include "gt/debugfs_gt.h"
+#include "intel_guc.h"
+#include "intel_guc_log.h"
+#include "intel_guc_log_debugfs.h"
+
+static int guc_log_dump_show(struct seq_file *m, void *data)
+{
+	struct drm_printer p = drm_seq_file_printer(m);
+
+	return intel_guc_log_dump(m->private, &p, false);
+}
+DEFINE_GT_DEBUGFS_ATTRIBUTE(guc_log_dump);
+
+static int guc_load_err_log_dump_show(struct seq_file *m, void *data)
+{
+	struct drm_printer p = drm_seq_file_printer(m);
+
+	return intel_guc_log_dump(m->private, &p, true);
+}
+DEFINE_GT_DEBUGFS_ATTRIBUTE(guc_load_err_log_dump);
+
+static int guc_log_level_get(void *data, u64 *val)
+{
+	struct intel_guc_log *log = data;
+
+	if (!intel_guc_is_used(log_to_guc(log)))
+		return -ENODEV;
+
+	*val = intel_guc_log_get_level(log);
+
+	return 0;
+}
+
+static int guc_log_level_set(void *data, u64 val)
+{
+	struct intel_guc_log *log = data;
+
+	if (!intel_guc_is_used(log_to_guc(log)))
+		return -ENODEV;
+
+	return intel_guc_log_set_level(log, val);
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(guc_log_level_fops,
+			guc_log_level_get, guc_log_level_set,
+			"%lld\n");
+
+static int guc_log_relay_open(struct inode *inode, struct file *file)
+{
+	struct intel_guc_log *log = inode->i_private;
+
+	if (!intel_guc_is_ready(log_to_guc(log)))
+		return -ENODEV;
+
+	file->private_data = log;
+
+	return intel_guc_log_relay_open(log);
+}
+
+static ssize_t
+guc_log_relay_write(struct file *filp,
+		    const char __user *ubuf,
+		    size_t cnt,
+		    loff_t *ppos)
+{
+	struct intel_guc_log *log = filp->private_data;
+	int val;
+	int ret;
+
+	ret = kstrtoint_from_user(ubuf, cnt, 0, &val);
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * Enable and start the guc log relay on value of 1.
+	 * Flush log relay for any other value.
+	 */
+	if (val == 1)
+		ret = intel_guc_log_relay_start(log);
+	else
+		intel_guc_log_relay_flush(log);
+
+	return ret ?: cnt;
+}
+
+static int guc_log_relay_release(struct inode *inode, struct file *file)
+{
+	struct intel_guc_log *log = inode->i_private;
+
+	intel_guc_log_relay_close(log);
+	return 0;
+}
+
+static const struct file_operations guc_log_relay_fops = {
+	.owner = THIS_MODULE,
+	.open = guc_log_relay_open,
+	.write = guc_log_relay_write,
+	.release = guc_log_relay_release,
+};
+
+void intel_guc_log_debugfs_register(struct intel_guc_log *log,
+				    struct dentry *root)
+{
+	static const struct debugfs_gt_file files[] = {
+		{ "guc_log_dump", &guc_log_dump_fops, NULL },
+		{ "guc_load_err_log_dump", &guc_load_err_log_dump_fops, NULL },
+		{ "guc_log_level", &guc_log_level_fops, NULL },
+		{ "guc_log_relay", &guc_log_relay_fops, NULL },
+	};
+
+	if (!intel_guc_is_supported(log_to_guc(log)))
+		return;
+
+	intel_gt_debugfs_register_files(root, files, ARRAY_SIZE(files), log);
+}
+
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log_debugfs.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_log_debugfs.h
new file mode 100644
index 000000000000..e8900e3d74ea
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log_debugfs.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2020 Intel Corporation
+ */
+
+#ifndef DEBUGFS_GUC_LOG_H
+#define DEBUGFS_GUC_LOG_H
+
+struct intel_guc_log;
+struct dentry;
+
+void intel_guc_log_debugfs_register(struct intel_guc_log *log,
+				    struct dentry *root);
+
+#endif /* DEBUGFS_GUC_LOG_H */
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
index a74b65694512..65eeb44b397d 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -41,7 +41,7 @@ void intel_huc_init_early(struct intel_huc *huc)
 {
 	struct drm_i915_private *i915 = huc_to_gt(huc)->i915;
 
-	intel_huc_fw_init_early(huc);
+	intel_uc_fw_init_early(&huc->fw, INTEL_UC_FW_TYPE_HUC);
 
 	if (INTEL_GEN(i915) >= 11) {
 		huc->status.reg = GEN11_HUC_KERNEL_LOAD_INFO;
@@ -200,9 +200,13 @@ int intel_huc_auth(struct intel_huc *huc)
  * This function reads status register to verify if HuC
  * firmware was successfully loaded.
  *
- * Returns: 1 if HuC firmware is loaded and verified,
- * 0 if HuC firmware is not loaded and -ENODEV if HuC
- * is not present on this platform.
+ * Returns:
+ *  * -ENODEV if HuC is not present on this platform,
+ *  * -EOPNOTSUPP if HuC firmware is disabled,
+ *  * -ENOPKG if HuC firmware was not installed,
+ *  * -ENOEXEC if HuC firmware is invalid or mismatched,
+ *  * 0 if HuC firmware is not running,
+ *  * 1 if HuC firmware is authenticated and running.
  */
 int intel_huc_check_status(struct intel_huc *huc)
 {
@@ -210,11 +214,50 @@ int intel_huc_check_status(struct intel_huc *huc)
 	intel_wakeref_t wakeref;
 	u32 status = 0;
 
-	if (!intel_huc_is_supported(huc))
+	switch (__intel_uc_fw_status(&huc->fw)) {
+	case INTEL_UC_FIRMWARE_NOT_SUPPORTED:
 		return -ENODEV;
+	case INTEL_UC_FIRMWARE_DISABLED:
+		return -EOPNOTSUPP;
+	case INTEL_UC_FIRMWARE_MISSING:
+		return -ENOPKG;
+	case INTEL_UC_FIRMWARE_ERROR:
+		return -ENOEXEC;
+	default:
+		break;
+	}
 
 	with_intel_runtime_pm(gt->uncore->rpm, wakeref)
 		status = intel_uncore_read(gt->uncore, huc->status.reg);
 
 	return (status & huc->status.mask) == huc->status.value;
 }
+
+/**
+ * intel_huc_load_status - dump information about HuC load status
+ * @huc: the HuC
+ * @p: the &drm_printer
+ *
+ * Pretty printer for HuC load status.
+ */
+void intel_huc_load_status(struct intel_huc *huc, struct drm_printer *p)
+{
+	struct intel_gt *gt = huc_to_gt(huc);
+	intel_wakeref_t wakeref;
+
+	if (!intel_huc_is_supported(huc)) {
+		drm_printf(p, "HuC not supported\n");
+		return;
+	}
+
+	if (!intel_huc_is_wanted(huc)) {
+		drm_printf(p, "HuC disabled\n");
+		return;
+	}
+
+	intel_uc_fw_dump(&huc->fw, p);
+
+	with_intel_runtime_pm(gt->uncore->rpm, wakeref)
+		drm_printf(p, "HuC status: 0x%08x\n",
+			   intel_uncore_read(gt->uncore, huc->status.reg));
+}
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.h b/drivers/gpu/drm/i915/gt/uc/intel_huc.h
index a40b9cfc6c22..daee43b661d4 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.h
@@ -57,4 +57,6 @@ static inline bool intel_huc_is_authenticated(struct intel_huc *huc)
 	return intel_uc_fw_is_running(&huc->fw);
 }
 
+void intel_huc_load_status(struct intel_huc *huc, struct drm_printer *p);
+
 #endif
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc_debugfs.c b/drivers/gpu/drm/i915/gt/uc/intel_huc_debugfs.c
new file mode 100644
index 000000000000..5733c15fd123
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc_debugfs.c
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2020 Intel Corporation
+ */
+
+#include <drm/drm_print.h>
+
+#include "gt/debugfs_gt.h"
+#include "intel_huc.h"
+#include "intel_huc_debugfs.h"
+
+static int huc_info_show(struct seq_file *m, void *data)
+{
+	struct intel_huc *huc = m->private;
+	struct drm_printer p = drm_seq_file_printer(m);
+
+	if (!intel_huc_is_supported(huc))
+		return -ENODEV;
+
+	intel_huc_load_status(huc, &p);
+
+	return 0;
+}
+DEFINE_GT_DEBUGFS_ATTRIBUTE(huc_info);
+
+void intel_huc_debugfs_register(struct intel_huc *huc, struct dentry *root)
+{
+	static const struct debugfs_gt_file files[] = {
+		{ "huc_info", &huc_info_fops, NULL },
+	};
+
+	if (!intel_huc_is_supported(huc))
+		return;
+
+	intel_gt_debugfs_register_files(root, files, ARRAY_SIZE(files), huc);
+}
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc_debugfs.h b/drivers/gpu/drm/i915/gt/uc/intel_huc_debugfs.h
new file mode 100644
index 000000000000..be79e992f976
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc_debugfs.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2020 Intel Corporation
+ */
+
+#ifndef DEBUGFS_HUC_H
+#define DEBUGFS_HUC_H
+
+struct intel_huc;
+struct dentry;
+
+void intel_huc_debugfs_register(struct intel_huc *huc, struct dentry *root);
+
+#endif /* DEBUGFS_HUC_H */
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
index 9cdf4cbe691c..e5ef509c70e8 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
@@ -7,23 +7,6 @@
 #include "intel_huc_fw.h"
 #include "i915_drv.h"
 
-/**
- * intel_huc_fw_init_early() - initializes HuC firmware struct
- * @huc: intel_huc struct
- *
- * On platforms with HuC selects firmware for uploading
- */
-void intel_huc_fw_init_early(struct intel_huc *huc)
-{
-	struct intel_gt *gt = huc_to_gt(huc);
-	struct intel_uc *uc = &gt->uc;
-	struct drm_i915_private *i915 = gt->i915;
-
-	intel_uc_fw_init_early(&huc->fw, INTEL_UC_FW_TYPE_HUC,
-			       intel_uc_wants_guc(uc),
-			       INTEL_INFO(i915)->platform, INTEL_REVID(i915));
-}
-
 /**
  * intel_huc_fw_upload() - load HuC uCode to device
  * @huc: intel_huc structure
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h
index b791269ce923..12f264ee3e0b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h
@@ -8,7 +8,6 @@
 
 struct intel_huc;
 
-void intel_huc_fw_init_early(struct intel_huc *huc);
 int intel_huc_fw_upload(struct intel_huc *huc);
 
 #endif
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
index a4cbe06e06bd..f518fe05c6f9 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
@@ -45,12 +45,12 @@ static void __confirm_options(struct intel_uc *uc)
 {
 	struct drm_i915_private *i915 = uc_to_gt(uc)->i915;
 
-	DRM_DEV_DEBUG_DRIVER(i915->drm.dev,
-			     "enable_guc=%d (guc:%s submission:%s huc:%s)\n",
-			     i915_modparams.enable_guc,
-			     yesno(intel_uc_wants_guc(uc)),
-			     yesno(intel_uc_wants_guc_submission(uc)),
-			     yesno(intel_uc_wants_huc(uc)));
+	drm_dbg(&i915->drm,
+		"enable_guc=%d (guc:%s submission:%s huc:%s)\n",
+		i915_modparams.enable_guc,
+		yesno(intel_uc_wants_guc(uc)),
+		yesno(intel_uc_wants_guc_submission(uc)),
+		yesno(intel_uc_wants_huc(uc)));
 
 	if (i915_modparams.enable_guc == -1)
 		return;
@@ -63,25 +63,25 @@ static void __confirm_options(struct intel_uc *uc)
 	}
 
 	if (!intel_uc_supports_guc(uc))
-		dev_info(i915->drm.dev,
+		drm_info(&i915->drm,
 			 "Incompatible option enable_guc=%d - %s\n",
 			 i915_modparams.enable_guc, "GuC is not supported!");
 
 	if (i915_modparams.enable_guc & ENABLE_GUC_LOAD_HUC &&
 	    !intel_uc_supports_huc(uc))
-		dev_info(i915->drm.dev,
+		drm_info(&i915->drm,
 			 "Incompatible option enable_guc=%d - %s\n",
 			 i915_modparams.enable_guc, "HuC is not supported!");
 
 	if (i915_modparams.enable_guc & ENABLE_GUC_SUBMISSION &&
 	    !intel_uc_supports_guc_submission(uc))
-		dev_info(i915->drm.dev,
+		drm_info(&i915->drm,
 			 "Incompatible option enable_guc=%d - %s\n",
 			 i915_modparams.enable_guc, "GuC submission is N/A");
 
 	if (i915_modparams.enable_guc & ~(ENABLE_GUC_SUBMISSION |
 					  ENABLE_GUC_LOAD_HUC))
-		dev_info(i915->drm.dev,
+		drm_info(&i915->drm,
 			 "Incompatible option enable_guc=%d - %s\n",
 			 i915_modparams.enable_guc, "undocumented flag");
 }
@@ -131,6 +131,13 @@ static void __uc_free_load_err_log(struct intel_uc *uc)
 		i915_gem_object_put(log);
 }
 
+void intel_uc_driver_remove(struct intel_uc *uc)
+{
+	intel_uc_fini_hw(uc);
+	intel_uc_fini(uc);
+	__uc_free_load_err_log(uc);
+}
+
 static inline bool guc_communication_enabled(struct intel_guc *guc)
 {
 	return intel_guc_ct_enabled(&guc->ct);
@@ -311,8 +318,6 @@ static void __uc_fini(struct intel_uc *uc)
 {
 	intel_huc_fini(&uc->huc);
 	intel_guc_fini(&uc->guc);
-
-	__uc_free_load_err_log(uc);
 }
 
 static int __uc_sanitize(struct intel_uc *uc)
@@ -475,14 +480,14 @@ static int __uc_init_hw(struct intel_uc *uc)
 	if (intel_uc_uses_guc_submission(uc))
 		intel_guc_submission_enable(guc);
 
-	dev_info(i915->drm.dev, "%s firmware %s version %u.%u %s:%s\n",
+	drm_info(&i915->drm, "%s firmware %s version %u.%u %s:%s\n",
 		 intel_uc_fw_type_repr(INTEL_UC_FW_TYPE_GUC), guc->fw.path,
 		 guc->fw.major_ver_found, guc->fw.minor_ver_found,
 		 "submission",
 		 enableddisabled(intel_uc_uses_guc_submission(uc)));
 
 	if (intel_uc_uses_huc(uc)) {
-		dev_info(i915->drm.dev, "%s firmware %s version %u.%u %s:%s\n",
+		drm_info(&i915->drm, "%s firmware %s version %u.%u %s:%s\n",
 			 intel_uc_fw_type_repr(INTEL_UC_FW_TYPE_HUC),
 			 huc->fw.path,
 			 huc->fw.major_ver_found, huc->fw.minor_ver_found,
@@ -503,7 +508,7 @@ static int __uc_init_hw(struct intel_uc *uc)
 	__uc_sanitize(uc);
 
 	if (!ret) {
-		dev_notice(i915->drm.dev, "GuC is uninitialized\n");
+		drm_notice(&i915->drm, "GuC is uninitialized\n");
 		/* We want to run without GuC submission */
 		return 0;
 	}
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.h b/drivers/gpu/drm/i915/gt/uc/intel_uc.h
index 5ae7b50b7dc1..9c954c589edf 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.h
@@ -34,6 +34,7 @@ struct intel_uc {
 
 void intel_uc_init_early(struct intel_uc *uc);
 void intel_uc_driver_late_release(struct intel_uc *uc);
+void intel_uc_driver_remove(struct intel_uc *uc);
 void intel_uc_init_mmio(struct intel_uc *uc);
 void intel_uc_reset_prepare(struct intel_uc *uc);
 void intel_uc_suspend(struct intel_uc *uc);
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_debugfs.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_debugfs.c
new file mode 100644
index 000000000000..9d16b784aa0d
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_debugfs.c
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2020 Intel Corporation
+ */
+
+#include <linux/debugfs.h>
+
+#include "intel_guc_debugfs.h"
+#include "intel_huc_debugfs.h"
+#include "intel_uc.h"
+#include "intel_uc_debugfs.h"
+
+void intel_uc_debugfs_register(struct intel_uc *uc, struct dentry *gt_root)
+{
+	struct dentry *root;
+
+	if (!gt_root)
+		return;
+
+	/* GuC and HuC go always in pair, no need to check both */
+	if (!intel_uc_supports_guc(uc))
+		return;
+
+	root = debugfs_create_dir("uc", gt_root);
+	if (IS_ERR(root))
+		return;
+
+	intel_guc_debugfs_register(&uc->guc, root);
+	intel_huc_debugfs_register(&uc->huc, root);
+}
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_debugfs.h b/drivers/gpu/drm/i915/gt/uc/intel_uc_debugfs.h
new file mode 100644
index 000000000000..010ce250d223
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_debugfs.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2020 Intel Corporation
+ */
+
+#ifndef DEBUGFS_UC_H
+#define DEBUGFS_UC_H
+
+struct intel_uc;
+struct dentry;
+
+void intel_uc_debugfs_register(struct intel_uc *uc, struct dentry *gt_root);
+
+#endif /* DEBUGFS_UC_H */
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
index 18c755203688..e1caae93996d 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -11,26 +11,32 @@
 #include "intel_uc_fw_abi.h"
 #include "i915_drv.h"
 
-static inline struct intel_gt *__uc_fw_to_gt(struct intel_uc_fw *uc_fw)
+static inline struct intel_gt *
+____uc_fw_to_gt(struct intel_uc_fw *uc_fw, enum intel_uc_fw_type type)
 {
-	GEM_BUG_ON(uc_fw->status == INTEL_UC_FIRMWARE_UNINITIALIZED);
-	if (uc_fw->type == INTEL_UC_FW_TYPE_GUC)
+	if (type == INTEL_UC_FW_TYPE_GUC)
 		return container_of(uc_fw, struct intel_gt, uc.guc.fw);
 
-	GEM_BUG_ON(uc_fw->type != INTEL_UC_FW_TYPE_HUC);
+	GEM_BUG_ON(type != INTEL_UC_FW_TYPE_HUC);
 	return container_of(uc_fw, struct intel_gt, uc.huc.fw);
 }
 
+static inline struct intel_gt *__uc_fw_to_gt(struct intel_uc_fw *uc_fw)
+{
+	GEM_BUG_ON(uc_fw->status == INTEL_UC_FIRMWARE_UNINITIALIZED);
+	return ____uc_fw_to_gt(uc_fw, uc_fw->type);
+}
+
 #ifdef CONFIG_DRM_I915_DEBUG_GUC
 void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
 			       enum intel_uc_fw_status status)
 {
 	uc_fw->__status =  status;
-	DRM_DEV_DEBUG_DRIVER(__uc_fw_to_gt(uc_fw)->i915->drm.dev,
-			     "%s firmware -> %s\n",
-			     intel_uc_fw_type_repr(uc_fw->type),
-			     status == INTEL_UC_FIRMWARE_SELECTED ?
-			     uc_fw->path : intel_uc_fw_status_repr(status));
+	drm_dbg(&__uc_fw_to_gt(uc_fw)->i915->drm,
+		"%s firmware -> %s\n",
+		intel_uc_fw_type_repr(uc_fw->type),
+		status == INTEL_UC_FIRMWARE_SELECTED ?
+		uc_fw->path : intel_uc_fw_status_repr(status));
 }
 #endif
 
@@ -187,17 +193,15 @@ static void __uc_fw_user_override(struct intel_uc_fw *uc_fw)
  * intel_uc_fw_init_early - initialize the uC object and select the firmware
  * @uc_fw: uC firmware
  * @type: type of uC
- * @supported: is uC support possible
- * @platform: platform identifier
- * @rev: hardware revision
  *
  * Initialize the state of our uC object and relevant tracking and select the
  * firmware to fetch and load.
  */
 void intel_uc_fw_init_early(struct intel_uc_fw *uc_fw,
-			    enum intel_uc_fw_type type, bool supported,
-			    enum intel_platform platform, u8 rev)
+			    enum intel_uc_fw_type type)
 {
+	struct drm_i915_private *i915 = ____uc_fw_to_gt(uc_fw, type)->i915;
+
 	/*
 	 * we use FIRMWARE_UNINITIALIZED to detect checks against uc_fw->status
 	 * before we're looked at the HW caps to see if we have uc support
@@ -208,8 +212,10 @@ void intel_uc_fw_init_early(struct intel_uc_fw *uc_fw,
 
 	uc_fw->type = type;
 
-	if (supported) {
-		__uc_fw_auto_select(uc_fw, platform, rev);
+	if (HAS_GT_UC(i915)) {
+		__uc_fw_auto_select(uc_fw,
+				    INTEL_INFO(i915)->platform,
+				    INTEL_REVID(i915));
 		__uc_fw_user_override(uc_fw);
 	}
 
@@ -290,7 +296,7 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
 
 	/* Check the size of the blob before examining buffer contents */
 	if (unlikely(fw->size < sizeof(struct uc_css_header))) {
-		dev_warn(dev, "%s firmware %s: invalid size: %zu < %zu\n",
+		drm_warn(&i915->drm, "%s firmware %s: invalid size: %zu < %zu\n",
 			 intel_uc_fw_type_repr(uc_fw->type), uc_fw->path,
 			 fw->size, sizeof(struct uc_css_header));
 		err = -ENODATA;
@@ -303,7 +309,7 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
 	size = (css->header_size_dw - css->key_size_dw - css->modulus_size_dw -
 		css->exponent_size_dw) * sizeof(u32);
 	if (unlikely(size != sizeof(struct uc_css_header))) {
-		dev_warn(dev,
+		drm_warn(&i915->drm,
 			 "%s firmware %s: unexpected header size: %zu != %zu\n",
 			 intel_uc_fw_type_repr(uc_fw->type), uc_fw->path,
 			 fw->size, sizeof(struct uc_css_header));
@@ -316,7 +322,7 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
 
 	/* now RSA */
 	if (unlikely(css->key_size_dw != UOS_RSA_SCRATCH_COUNT)) {
-		dev_warn(dev, "%s firmware %s: unexpected key size: %u != %u\n",
+		drm_warn(&i915->drm, "%s firmware %s: unexpected key size: %u != %u\n",
 			 intel_uc_fw_type_repr(uc_fw->type), uc_fw->path,
 			 css->key_size_dw, UOS_RSA_SCRATCH_COUNT);
 		err = -EPROTO;
@@ -327,7 +333,7 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
 	/* At least, it should have header, uCode and RSA. Size of all three. */
 	size = sizeof(struct uc_css_header) + uc_fw->ucode_size + uc_fw->rsa_size;
 	if (unlikely(fw->size < size)) {
-		dev_warn(dev, "%s firmware %s: invalid size: %zu < %zu\n",
+		drm_warn(&i915->drm, "%s firmware %s: invalid size: %zu < %zu\n",
 			 intel_uc_fw_type_repr(uc_fw->type), uc_fw->path,
 			 fw->size, size);
 		err = -ENOEXEC;
@@ -337,7 +343,7 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
 	/* Sanity check whether this fw is not larger than whole WOPCM memory */
 	size = __intel_uc_fw_get_upload_size(uc_fw);
 	if (unlikely(size >= i915->wopcm.size)) {
-		dev_warn(dev, "%s firmware %s: invalid size: %zu > %zu\n",
+		drm_warn(&i915->drm, "%s firmware %s: invalid size: %zu > %zu\n",
 			 intel_uc_fw_type_repr(uc_fw->type), uc_fw->path,
 			 size, (size_t)i915->wopcm.size);
 		err = -E2BIG;
@@ -352,7 +358,7 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
 
 	if (uc_fw->major_ver_found != uc_fw->major_ver_wanted ||
 	    uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) {
-		dev_notice(dev, "%s firmware %s: unexpected version: %u.%u != %u.%u\n",
+		drm_notice(&i915->drm, "%s firmware %s: unexpected version: %u.%u != %u.%u\n",
 			   intel_uc_fw_type_repr(uc_fw->type), uc_fw->path,
 			   uc_fw->major_ver_found, uc_fw->minor_ver_found,
 			   uc_fw->major_ver_wanted, uc_fw->minor_ver_wanted);
@@ -380,9 +386,9 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
 				  INTEL_UC_FIRMWARE_MISSING :
 				  INTEL_UC_FIRMWARE_ERROR);
 
-	dev_notice(dev, "%s firmware %s: fetch failed with error %d\n",
+	drm_notice(&i915->drm, "%s firmware %s: fetch failed with error %d\n",
 		   intel_uc_fw_type_repr(uc_fw->type), uc_fw->path, err);
-	dev_info(dev, "%s firmware(s) can be downloaded from %s\n",
+	drm_info(&i915->drm, "%s firmware(s) can be downloaded from %s\n",
 		 intel_uc_fw_type_repr(uc_fw->type), INTEL_UC_FIRMWARE_URL);
 
 	release_firmware(fw);		/* OK even if fw is NULL */
@@ -467,7 +473,7 @@ static int uc_fw_xfer(struct intel_uc_fw *uc_fw, u32 dst_offset, u32 dma_flags)
 	/* Wait for DMA to finish */
 	ret = intel_wait_for_register_fw(uncore, DMA_CTRL, START_DMA, 0, 100);
 	if (ret)
-		dev_err(gt->i915->drm.dev, "DMA for %s fw failed, DMA_CTRL=%u\n",
+		drm_err(&gt->i915->drm, "DMA for %s fw failed, DMA_CTRL=%u\n",
 			intel_uc_fw_type_repr(uc_fw->type),
 			intel_uncore_read_fw(uncore, DMA_CTRL));
 
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
index 888ff0de0244..23d3a423ac0f 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
@@ -239,8 +239,7 @@ static inline u32 intel_uc_fw_get_upload_size(struct intel_uc_fw *uc_fw)
 }
 
 void intel_uc_fw_init_early(struct intel_uc_fw *uc_fw,
-			    enum intel_uc_fw_type type, bool supported,
-			    enum intel_platform platform, u8 rev);
+			    enum intel_uc_fw_type type);
 int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw);
 void intel_uc_fw_cleanup_fetch(struct intel_uc_fw *uc_fw);
 int intel_uc_fw_upload(struct intel_uc_fw *uc_fw, u32 offset, u32 dma_flags);
diff --git a/drivers/gpu/drm/i915/gvt/aperture_gm.c b/drivers/gpu/drm/i915/gvt/aperture_gm.c
index 8b13f091cee2..0d6d59871308 100644
--- a/drivers/gpu/drm/i915/gvt/aperture_gm.c
+++ b/drivers/gpu/drm/i915/gvt/aperture_gm.c
@@ -35,7 +35,7 @@
  */
 
 #include "i915_drv.h"
-#include "i915_gem_fence_reg.h"
+#include "gt/intel_ggtt_fencing.h"
 #include "gvt.h"
 
 static int alloc_gm(struct intel_vgpu *vgpu, bool high_gm)
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 074c4efb58eb..eee530453aa6 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -131,6 +131,7 @@ struct kvmgt_vdev {
 	struct work_struct release_work;
 	atomic_t released;
 	struct vfio_device *vfio_device;
+	struct vfio_group *vfio_group;
 };
 
 static inline struct kvmgt_vdev *kvmgt_vdev(struct intel_vgpu *vgpu)
@@ -151,6 +152,7 @@ static void gvt_unpin_guest_page(struct intel_vgpu *vgpu, unsigned long gfn,
 		unsigned long size)
 {
 	struct drm_i915_private *i915 = vgpu->gvt->gt->i915;
+	struct kvmgt_vdev *vdev = kvmgt_vdev(vgpu);
 	int total_pages;
 	int npage;
 	int ret;
@@ -160,7 +162,7 @@ static void gvt_unpin_guest_page(struct intel_vgpu *vgpu, unsigned long gfn,
 	for (npage = 0; npage < total_pages; npage++) {
 		unsigned long cur_gfn = gfn + npage;
 
-		ret = vfio_unpin_pages(mdev_dev(kvmgt_vdev(vgpu)->mdev), &cur_gfn, 1);
+		ret = vfio_group_unpin_pages(vdev->vfio_group, &cur_gfn, 1);
 		drm_WARN_ON(&i915->drm, ret != 1);
 	}
 }
@@ -169,6 +171,7 @@ static void gvt_unpin_guest_page(struct intel_vgpu *vgpu, unsigned long gfn,
 static int gvt_pin_guest_page(struct intel_vgpu *vgpu, unsigned long gfn,
 		unsigned long size, struct page **page)
 {
+	struct kvmgt_vdev *vdev = kvmgt_vdev(vgpu);
 	unsigned long base_pfn = 0;
 	int total_pages;
 	int npage;
@@ -183,8 +186,8 @@ static int gvt_pin_guest_page(struct intel_vgpu *vgpu, unsigned long gfn,
 		unsigned long cur_gfn = gfn + npage;
 		unsigned long pfn;
 
-		ret = vfio_pin_pages(mdev_dev(kvmgt_vdev(vgpu)->mdev), &cur_gfn, 1,
-				     IOMMU_READ | IOMMU_WRITE, &pfn);
+		ret = vfio_group_pin_pages(vdev->vfio_group, &cur_gfn, 1,
+					   IOMMU_READ | IOMMU_WRITE, &pfn);
 		if (ret != 1) {
 			gvt_vgpu_err("vfio_pin_pages failed for gfn 0x%lx, ret %d\n",
 				     cur_gfn, ret);
@@ -792,6 +795,7 @@ static int intel_vgpu_open(struct mdev_device *mdev)
 	struct kvmgt_vdev *vdev = kvmgt_vdev(vgpu);
 	unsigned long events;
 	int ret;
+	struct vfio_group *vfio_group;
 
 	vdev->iommu_notifier.notifier_call = intel_vgpu_iommu_notifier;
 	vdev->group_notifier.notifier_call = intel_vgpu_group_notifier;
@@ -814,6 +818,14 @@ static int intel_vgpu_open(struct mdev_device *mdev)
 		goto undo_iommu;
 	}
 
+	vfio_group = vfio_group_get_external_user_from_dev(mdev_dev(mdev));
+	if (IS_ERR_OR_NULL(vfio_group)) {
+		ret = !vfio_group ? -EFAULT : PTR_ERR(vfio_group);
+		gvt_vgpu_err("vfio_group_get_external_user_from_dev failed\n");
+		goto undo_register;
+	}
+	vdev->vfio_group = vfio_group;
+
 	/* Take a module reference as mdev core doesn't take
 	 * a reference for vendor driver.
 	 */
@@ -830,6 +842,10 @@ static int intel_vgpu_open(struct mdev_device *mdev)
 	return ret;
 
 undo_group:
+	vfio_group_put_external_user(vdev->vfio_group);
+	vdev->vfio_group = NULL;
+
+undo_register:
 	vfio_unregister_notifier(mdev_dev(mdev), VFIO_GROUP_NOTIFY,
 					&vdev->group_notifier);
 
@@ -884,6 +900,7 @@ static void __intel_vgpu_release(struct intel_vgpu *vgpu)
 	kvmgt_guest_exit(info);
 
 	intel_vgpu_release_msi_eventfd_ctx(vgpu);
+	vfio_group_put_external_user(vdev->vfio_group);
 
 	vdev->kvm = NULL;
 	vgpu->handle = 0;
@@ -2035,33 +2052,14 @@ static int kvmgt_rw_gpa(unsigned long handle, unsigned long gpa,
 			void *buf, unsigned long len, bool write)
 {
 	struct kvmgt_guest_info *info;
-	struct kvm *kvm;
-	int idx, ret;
-	bool kthread = current->mm == NULL;
 
 	if (!handle_valid(handle))
 		return -ESRCH;
 
 	info = (struct kvmgt_guest_info *)handle;
-	kvm = info->kvm;
-
-	if (kthread) {
-		if (!mmget_not_zero(kvm->mm))
-			return -EFAULT;
-		use_mm(kvm->mm);
-	}
-
-	idx = srcu_read_lock(&kvm->srcu);
-	ret = write ? kvm_write_guest(kvm, gpa, buf, len) :
-		      kvm_read_guest(kvm, gpa, buf, len);
-	srcu_read_unlock(&kvm->srcu, idx);
-
-	if (kthread) {
-		unuse_mm(kvm->mm);
-		mmput(kvm->mm);
-	}
 
-	return ret;
+	return vfio_dma_rw(kvmgt_vdev(info->vgpu)->vfio_group,
+			   gpa, buf, len, write);
 }
 
 static int kvmgt_read_gpa(unsigned long handle, unsigned long gpa,
diff --git a/drivers/gpu/drm/i915/i915_active.c b/drivers/gpu/drm/i915/i915_active.c
index c4048628188a..d960d0be5bd2 100644
--- a/drivers/gpu/drm/i915/i915_active.c
+++ b/drivers/gpu/drm/i915/i915_active.c
@@ -496,7 +496,7 @@ static int flush_lazy_signals(struct i915_active *ref)
 	return err;
 }
 
-int i915_active_wait(struct i915_active *ref)
+int __i915_active_wait(struct i915_active *ref, int state)
 {
 	int err;
 
@@ -511,7 +511,9 @@ int i915_active_wait(struct i915_active *ref)
 	if (err)
 		return err;
 
-	if (wait_var_event_interruptible(ref, i915_active_is_idle(ref)))
+	if (!i915_active_is_idle(ref) &&
+	    ___wait_var_event(ref, i915_active_is_idle(ref),
+			      state, 0, 0, schedule()))
 		return -EINTR;
 
 	flush_work(&ref->work);
@@ -540,34 +542,88 @@ static int __await_active(struct i915_active_fence *active,
 	return 0;
 }
 
+struct wait_barrier {
+	struct wait_queue_entry base;
+	struct i915_active *ref;
+};
+
+static int
+barrier_wake(wait_queue_entry_t *wq, unsigned int mode, int flags, void *key)
+{
+	struct wait_barrier *wb = container_of(wq, typeof(*wb), base);
+
+	if (i915_active_is_idle(wb->ref)) {
+		list_del(&wq->entry);
+		i915_sw_fence_complete(wq->private);
+		kfree(wq);
+	}
+
+	return 0;
+}
+
+static int __await_barrier(struct i915_active *ref, struct i915_sw_fence *fence)
+{
+	struct wait_barrier *wb;
+
+	wb = kmalloc(sizeof(*wb), GFP_KERNEL);
+	if (unlikely(!wb))
+		return -ENOMEM;
+
+	GEM_BUG_ON(i915_active_is_idle(ref));
+	if (!i915_sw_fence_await(fence)) {
+		kfree(wb);
+		return -EINVAL;
+	}
+
+	wb->base.flags = 0;
+	wb->base.func = barrier_wake;
+	wb->base.private = fence;
+	wb->ref = ref;
+
+	add_wait_queue(__var_waitqueue(ref), &wb->base);
+	return 0;
+}
+
 static int await_active(struct i915_active *ref,
 			unsigned int flags,
 			int (*fn)(void *arg, struct dma_fence *fence),
-			void *arg)
+			void *arg, struct i915_sw_fence *barrier)
 {
 	int err = 0;
 
-	/* We must always wait for the exclusive fence! */
-	if (rcu_access_pointer(ref->excl.fence)) {
+	if (!i915_active_acquire_if_busy(ref))
+		return 0;
+
+	if (flags & I915_ACTIVE_AWAIT_EXCL &&
+	    rcu_access_pointer(ref->excl.fence)) {
 		err = __await_active(&ref->excl, fn, arg);
 		if (err)
-			return err;
+			goto out;
 	}
 
-	if (flags & I915_ACTIVE_AWAIT_ALL && i915_active_acquire_if_busy(ref)) {
+	if (flags & I915_ACTIVE_AWAIT_ACTIVE) {
 		struct active_node *it, *n;
 
 		rbtree_postorder_for_each_entry_safe(it, n, &ref->tree, node) {
 			err = __await_active(&it->base, fn, arg);
 			if (err)
-				break;
+				goto out;
 		}
-		i915_active_release(ref);
+	}
+
+	if (flags & I915_ACTIVE_AWAIT_BARRIER) {
+		err = flush_lazy_signals(ref);
 		if (err)
-			return err;
+			goto out;
+
+		err = __await_barrier(ref, barrier);
+		if (err)
+			goto out;
 	}
 
-	return 0;
+out:
+	i915_active_release(ref);
+	return err;
 }
 
 static int rq_await_fence(void *arg, struct dma_fence *fence)
@@ -579,7 +635,7 @@ int i915_request_await_active(struct i915_request *rq,
 			      struct i915_active *ref,
 			      unsigned int flags)
 {
-	return await_active(ref, flags, rq_await_fence, rq);
+	return await_active(ref, flags, rq_await_fence, rq, &rq->submit);
 }
 
 static int sw_await_fence(void *arg, struct dma_fence *fence)
@@ -592,7 +648,7 @@ int i915_sw_fence_await_active(struct i915_sw_fence *fence,
 			       struct i915_active *ref,
 			       unsigned int flags)
 {
-	return await_active(ref, flags, sw_await_fence, fence);
+	return await_active(ref, flags, sw_await_fence, fence, fence);
 }
 
 #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)
@@ -818,7 +874,7 @@ void i915_active_acquire_barrier(struct i915_active *ref)
 
 		GEM_BUG_ON(!intel_engine_pm_is_awake(engine));
 		llist_add(barrier_to_ll(node), &engine->barrier_tasks);
-		intel_engine_pm_put(engine);
+		intel_engine_pm_put_delay(engine, 1);
 	}
 }
 
@@ -937,6 +993,59 @@ void i915_active_noop(struct dma_fence *fence, struct dma_fence_cb *cb)
 	active_fence_cb(fence, cb);
 }
 
+struct auto_active {
+	struct i915_active base;
+	struct kref ref;
+};
+
+struct i915_active *i915_active_get(struct i915_active *ref)
+{
+	struct auto_active *aa = container_of(ref, typeof(*aa), base);
+
+	kref_get(&aa->ref);
+	return &aa->base;
+}
+
+static void auto_release(struct kref *ref)
+{
+	struct auto_active *aa = container_of(ref, typeof(*aa), ref);
+
+	i915_active_fini(&aa->base);
+	kfree(aa);
+}
+
+void i915_active_put(struct i915_active *ref)
+{
+	struct auto_active *aa = container_of(ref, typeof(*aa), base);
+
+	kref_put(&aa->ref, auto_release);
+}
+
+static int auto_active(struct i915_active *ref)
+{
+	i915_active_get(ref);
+	return 0;
+}
+
+static void auto_retire(struct i915_active *ref)
+{
+	i915_active_put(ref);
+}
+
+struct i915_active *i915_active_create(void)
+{
+	struct auto_active *aa;
+
+	aa = kmalloc(sizeof(*aa), GFP_KERNEL);
+	if (!aa)
+		return NULL;
+
+	kref_init(&aa->ref);
+	i915_active_init(&aa->base, auto_active, auto_retire);
+
+	return &aa->base;
+}
+
 #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
 #include "selftests/i915_active.c"
 #endif
diff --git a/drivers/gpu/drm/i915/i915_active.h b/drivers/gpu/drm/i915/i915_active.h
index b3282ae7913c..cf4058150966 100644
--- a/drivers/gpu/drm/i915/i915_active.h
+++ b/drivers/gpu/drm/i915/i915_active.h
@@ -181,7 +181,11 @@ static inline bool i915_active_has_exclusive(struct i915_active *ref)
 	return rcu_access_pointer(ref->excl.fence);
 }
 
-int i915_active_wait(struct i915_active *ref);
+int __i915_active_wait(struct i915_active *ref, int state);
+static inline int i915_active_wait(struct i915_active *ref)
+{
+	return __i915_active_wait(ref, TASK_INTERRUPTIBLE);
+}
 
 int i915_sw_fence_await_active(struct i915_sw_fence *fence,
 			       struct i915_active *ref,
@@ -189,7 +193,9 @@ int i915_sw_fence_await_active(struct i915_sw_fence *fence,
 int i915_request_await_active(struct i915_request *rq,
 			      struct i915_active *ref,
 			      unsigned int flags);
-#define I915_ACTIVE_AWAIT_ALL BIT(0)
+#define I915_ACTIVE_AWAIT_EXCL BIT(0)
+#define I915_ACTIVE_AWAIT_ACTIVE BIT(1)
+#define I915_ACTIVE_AWAIT_BARRIER BIT(2)
 
 int i915_active_acquire(struct i915_active *ref);
 bool i915_active_acquire_if_busy(struct i915_active *ref);
@@ -221,4 +227,8 @@ void i915_request_add_active_barriers(struct i915_request *rq);
 void i915_active_print(struct i915_active *ref, struct drm_printer *m);
 void i915_active_unlock_wait(struct i915_active *ref);
 
+struct i915_active *i915_active_create(void);
+struct i915_active *i915_active_get(struct i915_active *ref);
+void i915_active_put(struct i915_active *ref);
+
 #endif /* _I915_ACTIVE_H_ */
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 6ca797128aa1..aa35a59f1c7d 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -37,7 +37,6 @@
 #include "gt/intel_reset.h"
 #include "gt/intel_rc6.h"
 #include "gt/intel_rps.h"
-#include "gt/uc/intel_guc_submission.h"
 
 #include "i915_debugfs.h"
 #include "i915_debugfs_params.h"
@@ -218,7 +217,7 @@ i915_debugfs_describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
 struct file_stats {
 	struct i915_address_space *vm;
 	unsigned long count;
-	u64 total, unbound;
+	u64 total;
 	u64 active, inactive;
 	u64 closed;
 };
@@ -234,8 +233,6 @@ static int per_file_stats(int id, void *ptr, void *data)
 
 	stats->count++;
 	stats->total += obj->base.size;
-	if (!atomic_read(&obj->bind_count))
-		stats->unbound += obj->base.size;
 
 	spin_lock(&obj->vma.lock);
 	if (!stats->vm) {
@@ -285,13 +282,12 @@ static int per_file_stats(int id, void *ptr, void *data)
 
 #define print_file_stats(m, name, stats) do { \
 	if (stats.count) \
-		seq_printf(m, "%s: %lu objects, %llu bytes (%llu active, %llu inactive, %llu unbound, %llu closed)\n", \
+		seq_printf(m, "%s: %lu objects, %llu bytes (%llu active, %llu inactive, %llu closed)\n", \
 			   name, \
 			   stats.count, \
 			   stats.total, \
 			   stats.active, \
 			   stats.inactive, \
-			   stats.unbound, \
 			   stats.closed); \
 } while (0)
 
@@ -745,7 +741,7 @@ i915_error_state_write(struct file *filp,
 	if (!error)
 		return 0;
 
-	DRM_DEBUG_DRIVER("Resetting error state\n");
+	drm_dbg(&error->i915->drm, "Resetting error state\n");
 	i915_reset_error_state(error->i915);
 
 	return cnt;
@@ -1251,286 +1247,6 @@ static int i915_llc(struct seq_file *m, void *data)
 	return 0;
 }
 
-static int i915_huc_load_status_info(struct seq_file *m, void *data)
-{
-	struct drm_i915_private *dev_priv = node_to_i915(m->private);
-	intel_wakeref_t wakeref;
-	struct drm_printer p;
-
-	if (!HAS_GT_UC(dev_priv))
-		return -ENODEV;
-
-	p = drm_seq_file_printer(m);
-	intel_uc_fw_dump(&dev_priv->gt.uc.huc.fw, &p);
-
-	with_intel_runtime_pm(&dev_priv->runtime_pm, wakeref)
-		seq_printf(m, "\nHuC status 0x%08x:\n", I915_READ(HUC_STATUS2));
-
-	return 0;
-}
-
-static int i915_guc_load_status_info(struct seq_file *m, void *data)
-{
-	struct drm_i915_private *dev_priv = node_to_i915(m->private);
-	intel_wakeref_t wakeref;
-	struct drm_printer p;
-
-	if (!HAS_GT_UC(dev_priv))
-		return -ENODEV;
-
-	p = drm_seq_file_printer(m);
-	intel_uc_fw_dump(&dev_priv->gt.uc.guc.fw, &p);
-
-	with_intel_runtime_pm(&dev_priv->runtime_pm, wakeref) {
-		u32 tmp = I915_READ(GUC_STATUS);
-		u32 i;
-
-		seq_printf(m, "\nGuC status 0x%08x:\n", tmp);
-		seq_printf(m, "\tBootrom status = 0x%x\n",
-			   (tmp & GS_BOOTROM_MASK) >> GS_BOOTROM_SHIFT);
-		seq_printf(m, "\tuKernel status = 0x%x\n",
-			   (tmp & GS_UKERNEL_MASK) >> GS_UKERNEL_SHIFT);
-		seq_printf(m, "\tMIA Core status = 0x%x\n",
-			   (tmp & GS_MIA_MASK) >> GS_MIA_SHIFT);
-		seq_puts(m, "\nScratch registers:\n");
-		for (i = 0; i < 16; i++) {
-			seq_printf(m, "\t%2d: \t0x%x\n",
-				   i, I915_READ(SOFT_SCRATCH(i)));
-		}
-	}
-
-	return 0;
-}
-
-static const char *
-stringify_guc_log_type(enum guc_log_buffer_type type)
-{
-	switch (type) {
-	case GUC_ISR_LOG_BUFFER:
-		return "ISR";
-	case GUC_DPC_LOG_BUFFER:
-		return "DPC";
-	case GUC_CRASH_DUMP_LOG_BUFFER:
-		return "CRASH";
-	default:
-		MISSING_CASE(type);
-	}
-
-	return "";
-}
-
-static void i915_guc_log_info(struct seq_file *m, struct intel_guc_log *log)
-{
-	enum guc_log_buffer_type type;
-
-	if (!intel_guc_log_relay_created(log)) {
-		seq_puts(m, "GuC log relay not created\n");
-		return;
-	}
-
-	seq_puts(m, "GuC logging stats:\n");
-
-	seq_printf(m, "\tRelay full count: %u\n",
-		   log->relay.full_count);
-
-	for (type = GUC_ISR_LOG_BUFFER; type < GUC_MAX_LOG_BUFFER; type++) {
-		seq_printf(m, "\t%s:\tflush count %10u, overflow count %10u\n",
-			   stringify_guc_log_type(type),
-			   log->stats[type].flush,
-			   log->stats[type].sampled_overflow);
-	}
-}
-
-static int i915_guc_info(struct seq_file *m, void *data)
-{
-	struct drm_i915_private *dev_priv = node_to_i915(m->private);
-	struct intel_uc *uc = &dev_priv->gt.uc;
-
-	if (!intel_uc_uses_guc(uc))
-		return -ENODEV;
-
-	i915_guc_log_info(m, &uc->guc.log);
-
-	/* Add more as required ... */
-
-	return 0;
-}
-
-static int i915_guc_stage_pool(struct seq_file *m, void *data)
-{
-	struct drm_i915_private *dev_priv = node_to_i915(m->private);
-	struct intel_uc *uc = &dev_priv->gt.uc;
-	struct guc_stage_desc *desc = uc->guc.stage_desc_pool_vaddr;
-	int index;
-
-	if (!intel_uc_uses_guc_submission(uc))
-		return -ENODEV;
-
-	for (index = 0; index < GUC_MAX_STAGE_DESCRIPTORS; index++, desc++) {
-		struct intel_engine_cs *engine;
-
-		if (!(desc->attribute & GUC_STAGE_DESC_ATTR_ACTIVE))
-			continue;
-
-		seq_printf(m, "GuC stage descriptor %u:\n", index);
-		seq_printf(m, "\tIndex: %u\n", desc->stage_id);
-		seq_printf(m, "\tAttribute: 0x%x\n", desc->attribute);
-		seq_printf(m, "\tPriority: %d\n", desc->priority);
-		seq_printf(m, "\tDoorbell id: %d\n", desc->db_id);
-		seq_printf(m, "\tEngines used: 0x%x\n",
-			   desc->engines_used);
-		seq_printf(m, "\tDoorbell trigger phy: 0x%llx, cpu: 0x%llx, uK: 0x%x\n",
-			   desc->db_trigger_phy,
-			   desc->db_trigger_cpu,
-			   desc->db_trigger_uk);
-		seq_printf(m, "\tProcess descriptor: 0x%x\n",
-			   desc->process_desc);
-		seq_printf(m, "\tWorkqueue address: 0x%x, size: 0x%x\n",
-			   desc->wq_addr, desc->wq_size);
-		seq_putc(m, '\n');
-
-		for_each_uabi_engine(engine, dev_priv) {
-			u32 guc_engine_id = engine->guc_id;
-			struct guc_execlist_context *lrc =
-						&desc->lrc[guc_engine_id];
-
-			seq_printf(m, "\t%s LRC:\n", engine->name);
-			seq_printf(m, "\t\tContext desc: 0x%x\n",
-				   lrc->context_desc);
-			seq_printf(m, "\t\tContext id: 0x%x\n", lrc->context_id);
-			seq_printf(m, "\t\tLRCA: 0x%x\n", lrc->ring_lrca);
-			seq_printf(m, "\t\tRing begin: 0x%x\n", lrc->ring_begin);
-			seq_printf(m, "\t\tRing end: 0x%x\n", lrc->ring_end);
-			seq_putc(m, '\n');
-		}
-	}
-
-	return 0;
-}
-
-static int i915_guc_log_dump(struct seq_file *m, void *data)
-{
-	struct drm_info_node *node = m->private;
-	struct drm_i915_private *dev_priv = node_to_i915(node);
-	bool dump_load_err = !!node->info_ent->data;
-	struct drm_i915_gem_object *obj = NULL;
-	u32 *log;
-	int i = 0;
-
-	if (!HAS_GT_UC(dev_priv))
-		return -ENODEV;
-
-	if (dump_load_err)
-		obj = dev_priv->gt.uc.load_err_log;
-	else if (dev_priv->gt.uc.guc.log.vma)
-		obj = dev_priv->gt.uc.guc.log.vma->obj;
-
-	if (!obj)
-		return 0;
-
-	log = i915_gem_object_pin_map(obj, I915_MAP_WC);
-	if (IS_ERR(log)) {
-		DRM_DEBUG("Failed to pin object\n");
-		seq_puts(m, "(log data unaccessible)\n");
-		return PTR_ERR(log);
-	}
-
-	for (i = 0; i < obj->base.size / sizeof(u32); i += 4)
-		seq_printf(m, "0x%08x 0x%08x 0x%08x 0x%08x\n",
-			   *(log + i), *(log + i + 1),
-			   *(log + i + 2), *(log + i + 3));
-
-	seq_putc(m, '\n');
-
-	i915_gem_object_unpin_map(obj);
-
-	return 0;
-}
-
-static int i915_guc_log_level_get(void *data, u64 *val)
-{
-	struct drm_i915_private *dev_priv = data;
-	struct intel_uc *uc = &dev_priv->gt.uc;
-
-	if (!intel_uc_uses_guc(uc))
-		return -ENODEV;
-
-	*val = intel_guc_log_get_level(&uc->guc.log);
-
-	return 0;
-}
-
-static int i915_guc_log_level_set(void *data, u64 val)
-{
-	struct drm_i915_private *dev_priv = data;
-	struct intel_uc *uc = &dev_priv->gt.uc;
-
-	if (!intel_uc_uses_guc(uc))
-		return -ENODEV;
-
-	return intel_guc_log_set_level(&uc->guc.log, val);
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(i915_guc_log_level_fops,
-			i915_guc_log_level_get, i915_guc_log_level_set,
-			"%lld\n");
-
-static int i915_guc_log_relay_open(struct inode *inode, struct file *file)
-{
-	struct drm_i915_private *i915 = inode->i_private;
-	struct intel_guc *guc = &i915->gt.uc.guc;
-	struct intel_guc_log *log = &guc->log;
-
-	if (!intel_guc_is_ready(guc))
-		return -ENODEV;
-
-	file->private_data = log;
-
-	return intel_guc_log_relay_open(log);
-}
-
-static ssize_t
-i915_guc_log_relay_write(struct file *filp,
-			 const char __user *ubuf,
-			 size_t cnt,
-			 loff_t *ppos)
-{
-	struct intel_guc_log *log = filp->private_data;
-	int val;
-	int ret;
-
-	ret = kstrtoint_from_user(ubuf, cnt, 0, &val);
-	if (ret < 0)
-		return ret;
-
-	/*
-	 * Enable and start the guc log relay on value of 1.
-	 * Flush log relay for any other value.
-	 */
-	if (val == 1)
-		ret = intel_guc_log_relay_start(log);
-	else
-		intel_guc_log_relay_flush(log);
-
-	return ret ?: cnt;
-}
-
-static int i915_guc_log_relay_release(struct inode *inode, struct file *file)
-{
-	struct drm_i915_private *i915 = inode->i_private;
-	struct intel_guc *guc = &i915->gt.uc.guc;
-
-	intel_guc_log_relay_close(&guc->log);
-	return 0;
-}
-
-static const struct file_operations i915_guc_log_relay_fops = {
-	.owner = THIS_MODULE,
-	.open = i915_guc_log_relay_open,
-	.write = i915_guc_log_relay_write,
-	.release = i915_guc_log_relay_release,
-};
-
 static int i915_runtime_pm_status(struct seq_file *m, void *unused)
 {
 	struct drm_i915_private *dev_priv = node_to_i915(m->private);
@@ -2139,12 +1855,6 @@ static const struct drm_info_list i915_debugfs_list[] = {
 	{"i915_gem_objects", i915_gem_object_info, 0},
 	{"i915_gem_fence_regs", i915_gem_fence_regs_info, 0},
 	{"i915_gem_interrupt", i915_interrupt_info, 0},
-	{"i915_guc_info", i915_guc_info, 0},
-	{"i915_guc_load_status", i915_guc_load_status_info, 0},
-	{"i915_guc_log_dump", i915_guc_log_dump, 0},
-	{"i915_guc_load_err_log_dump", i915_guc_log_dump, 0, (void *)1},
-	{"i915_guc_stage_pool", i915_guc_stage_pool, 0},
-	{"i915_huc_load_status", i915_huc_load_status_info, 0},
 	{"i915_frequency_info", i915_frequency_info, 0},
 	{"i915_ring_freq_table", i915_ring_freq_table, 0},
 	{"i915_context_status", i915_context_status, 0},
@@ -2172,11 +1882,9 @@ static const struct i915_debugfs_files {
 	{"i915_error_state", &i915_error_state_fops},
 	{"i915_gpu_info", &i915_gpu_info_fops},
 #endif
-	{"i915_guc_log_level", &i915_guc_log_level_fops},
-	{"i915_guc_log_relay", &i915_guc_log_relay_fops},
 };
 
-int i915_debugfs_register(struct drm_i915_private *dev_priv)
+void i915_debugfs_register(struct drm_i915_private *dev_priv)
 {
 	struct drm_minor *minor = dev_priv->drm.primary;
 	int i;
@@ -2193,7 +1901,7 @@ int i915_debugfs_register(struct drm_i915_private *dev_priv)
 				    i915_debugfs_files[i].fops);
 	}
 
-	return drm_debugfs_create_files(i915_debugfs_list,
-					I915_DEBUGFS_ENTRIES,
-					minor->debugfs_root, minor);
+	drm_debugfs_create_files(i915_debugfs_list,
+				 I915_DEBUGFS_ENTRIES,
+				 minor->debugfs_root, minor);
 }
diff --git a/drivers/gpu/drm/i915/i915_debugfs.h b/drivers/gpu/drm/i915/i915_debugfs.h
index 6da39c76ab5e..1de2736f1248 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.h
+++ b/drivers/gpu/drm/i915/i915_debugfs.h
@@ -12,10 +12,10 @@ struct drm_i915_private;
 struct seq_file;
 
 #ifdef CONFIG_DEBUG_FS
-int i915_debugfs_register(struct drm_i915_private *dev_priv);
+void i915_debugfs_register(struct drm_i915_private *dev_priv);
 void i915_debugfs_describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj);
 #else
-static inline int i915_debugfs_register(struct drm_i915_private *dev_priv) { return 0; }
+static inline void i915_debugfs_register(struct drm_i915_private *dev_priv) {}
 static inline void i915_debugfs_describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) {}
 #endif
 
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 81a4621853db..641f5e03b661 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -43,6 +43,7 @@
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_ioctl.h>
 #include <drm/drm_irq.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_probe_helper.h>
 
 #include "display/intel_acpi.h"
@@ -888,6 +889,8 @@ i915_driver_create(struct pci_dev *pdev, const struct pci_device_id *ent)
 		return ERR_PTR(err);
 	}
 
+	drmm_add_final_kfree(&i915->drm, i915);
+
 	i915->drm.pdev = pdev;
 	pci_set_drvdata(pdev, i915);
 
@@ -901,17 +904,6 @@ i915_driver_create(struct pci_dev *pdev, const struct pci_device_id *ent)
 	return i915;
 }
 
-static void i915_driver_destroy(struct drm_i915_private *i915)
-{
-	struct pci_dev *pdev = i915->drm.pdev;
-
-	drm_dev_fini(&i915->drm);
-	kfree(i915);
-
-	/* And make sure we never chase our dangling pointer from pci_dev */
-	pci_set_drvdata(pdev, NULL);
-}
-
 /**
  * i915_driver_probe - setup chip and create an initial config
  * @pdev: PCI device
@@ -993,6 +985,8 @@ int i915_driver_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 	i915_welcome_messages(i915);
 
+	i915->do_release = true;
+
 	return 0;
 
 out_cleanup_irq:
@@ -1012,7 +1006,7 @@ int i915_driver_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	pci_disable_device(pdev);
 out_fini:
 	i915_probe_error(i915, "Device initialization failed (%d)\n", ret);
-	i915_driver_destroy(i915);
+	drm_dev_put(&i915->drm);
 	return ret;
 }
 
@@ -1052,6 +1046,9 @@ static void i915_driver_release(struct drm_device *dev)
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct intel_runtime_pm *rpm = &dev_priv->runtime_pm;
 
+	if (!dev_priv->do_release)
+		return;
+
 	disable_rpm_wakeref_asserts(rpm);
 
 	i915_gem_driver_release(dev_priv);
@@ -1065,7 +1062,6 @@ static void i915_driver_release(struct drm_device *dev)
 	intel_runtime_pm_driver_release(rpm);
 
 	i915_driver_late_release(dev_priv);
-	i915_driver_destroy(dev_priv);
 }
 
 static int i915_driver_open(struct drm_device *dev, struct drm_file *file)
@@ -1286,7 +1282,6 @@ static int i915_drm_resume(struct drm_device *dev)
 		drm_err(&dev_priv->drm, "failed to re-enable GGTT\n");
 
 	i915_ggtt_resume(&dev_priv->ggtt);
-	i915_gem_restore_fences(&dev_priv->ggtt);
 
 	intel_csr_ucode_resume(dev_priv);
 
@@ -1604,8 +1599,6 @@ static int intel_runtime_suspend(struct device *kdev)
 
 		intel_gt_runtime_resume(&dev_priv->gt);
 
-		i915_gem_restore_fences(&dev_priv->ggtt);
-
 		enable_rpm_wakeref_asserts(rpm);
 
 		return ret;
@@ -1685,7 +1678,6 @@ static int intel_runtime_resume(struct device *kdev)
 	 * we can do is to hope that things will still work (and disable RPM).
 	 */
 	intel_gt_runtime_resume(&dev_priv->gt);
-	i915_gem_restore_fences(&dev_priv->ggtt);
 
 	/*
 	 * On VLV/CHV display interrupts are part of the display
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 1f5b9a584f71..e256b6be5d79 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -92,7 +92,6 @@
 #include "intel_wopcm.h"
 
 #include "i915_gem.h"
-#include "i915_gem_fence_reg.h"
 #include "i915_gem_gtt.h"
 #include "i915_gpu_error.h"
 #include "i915_perf_types.h"
@@ -417,6 +416,7 @@ struct intel_fbc {
 		struct {
 			const struct drm_format_info *format;
 			unsigned int stride;
+			u64 modifier;
 		} fb;
 		u16 gen9_wa_cfb_stride;
 		s8 fence_id;
@@ -540,7 +540,6 @@ struct i915_suspend_saved_registers {
 	u32 saveSWF0[16];
 	u32 saveSWF1[16];
 	u32 saveSWF3[3];
-	u64 saveFENCE[I915_MAX_NUM_FENCES];
 	u32 savePCH_PORT_HOTPLUG;
 	u16 saveGCDGMBUS;
 };
@@ -823,6 +822,9 @@ struct i915_selftest_stash {
 struct drm_i915_private {
 	struct drm_device drm;
 
+	/* FIXME: Device release actions should all be moved to drmm_ */
+	bool do_release;
+
 	const struct intel_device_info __info; /* Use INTEL_INFO() to access. */
 	struct intel_runtime_info __runtime; /* Use RUNTIME_INFO() to access. */
 	struct intel_driver_caps caps;
@@ -885,7 +887,6 @@ struct drm_i915_private {
 
 	struct pci_dev *bridge_dev;
 
-	struct intel_engine_cs *engine[I915_NUM_ENGINES];
 	struct rb_root uabi_engines;
 
 	struct resource mch_res;
@@ -1507,6 +1508,8 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
 	(IS_ICELAKE(p) && IS_REVID(p, since, until))
 
 #define TGL_REVID_A0		0x0
+#define TGL_REVID_B0		0x1
+#define TGL_REVID_C0		0x2
 
 #define IS_TGL_REVID(p, since, until) \
 	(IS_TIGERLAKE(p) && IS_REVID(p, since, until))
@@ -1604,7 +1607,7 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
 #define HAS_DDI(dev_priv)		 (INTEL_INFO(dev_priv)->display.has_ddi)
 #define HAS_FPGA_DBG_UNCLAIMED(dev_priv) (INTEL_INFO(dev_priv)->has_fpga_dbg)
 #define HAS_PSR(dev_priv)		 (INTEL_INFO(dev_priv)->display.has_psr)
-#define HAS_TRANSCODER_EDP(dev_priv)	 (INTEL_INFO(dev_priv)->trans_offsets[TRANSCODER_EDP] != 0)
+#define HAS_TRANSCODER(dev_priv, trans)	 ((INTEL_INFO(dev_priv)->cpu_transcoder_mask & BIT(trans)) != 0)
 
 #define HAS_RC6(dev_priv)		 (INTEL_INFO(dev_priv)->has_rc6)
 #define HAS_RC6p(dev_priv)		 (INTEL_INFO(dev_priv)->has_rc6p)
@@ -1738,6 +1741,7 @@ int i915_gem_object_unbind(struct drm_i915_gem_object *obj,
 			   unsigned long flags);
 #define I915_GEM_OBJECT_UNBIND_ACTIVE BIT(0)
 #define I915_GEM_OBJECT_UNBIND_BARRIER BIT(1)
+#define I915_GEM_OBJECT_UNBIND_TEST BIT(2)
 
 void i915_gem_runtime_suspend(struct drm_i915_private *dev_priv);
 
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index ca5420012a22..0cbcb9f54e7d 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -118,7 +118,7 @@ int i915_gem_object_unbind(struct drm_i915_gem_object *obj,
 	struct i915_vma *vma;
 	int ret;
 
-	if (!atomic_read(&obj->bind_count))
+	if (list_empty(&obj->vma.list))
 		return 0;
 
 	/*
@@ -141,6 +141,11 @@ int i915_gem_object_unbind(struct drm_i915_gem_object *obj,
 		if (!i915_vma_is_bound(vma, I915_VMA_BIND_MASK))
 			continue;
 
+		if (flags & I915_GEM_OBJECT_UNBIND_TEST) {
+			ret = -EBUSY;
+			break;
+		}
+
 		ret = -EAGAIN;
 		if (!i915_vm_tryopen(vm))
 			break;
@@ -993,18 +998,16 @@ i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj,
 			return ERR_PTR(ret);
 	}
 
+	ret = i915_vma_pin(vma, size, alignment, flags | PIN_GLOBAL);
+	if (ret)
+		return ERR_PTR(ret);
+
 	if (vma->fence && !i915_gem_object_is_tiled(obj)) {
 		mutex_lock(&ggtt->vm.mutex);
-		ret = i915_vma_revoke_fence(vma);
+		i915_vma_revoke_fence(vma);
 		mutex_unlock(&ggtt->vm.mutex);
-		if (ret)
-			return ERR_PTR(ret);
 	}
 
-	ret = i915_vma_pin(vma, size, alignment, flags | PIN_GLOBAL);
-	if (ret)
-		return ERR_PTR(ret);
-
 	ret = i915_vma_wait_for_bind(vma);
 	if (ret) {
 		i915_vma_unpin(vma);
@@ -1156,7 +1159,6 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
 		/* Minimal basic recovery for KMS */
 		ret = i915_ggtt_enable_hw(dev_priv);
 		i915_ggtt_resume(&dev_priv->ggtt);
-		i915_gem_restore_fences(&dev_priv->ggtt);
 		intel_init_clock_gating(dev_priv);
 	}
 
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c
index 4518b9b35c3d..0ba7b1e881c0 100644
--- a/drivers/gpu/drm/i915/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/i915_gem_evict.c
@@ -228,7 +228,12 @@ i915_gem_evict_something(struct i915_address_space *vm,
 
 	while (ret == 0 && (node = drm_mm_scan_color_evict(&scan))) {
 		vma = container_of(node, struct i915_vma, node);
-		ret = __i915_vma_unbind(vma);
+
+		/* If we find any non-objects (!vma), we cannot evict them */
+		if (vma->node.color != I915_COLOR_UNEVICTABLE)
+			ret = __i915_vma_unbind(vma);
+		else
+			ret = -ENOSPC; /* XXX search failed, try again? */
 	}
 
 	return ret;
diff --git a/drivers/gpu/drm/i915/i915_gem_fence_reg.c b/drivers/gpu/drm/i915/i915_gem_fence_reg.c
deleted file mode 100644
index d152b648c73c..000000000000
--- a/drivers/gpu/drm/i915/i915_gem_fence_reg.c
+++ /dev/null
@@ -1,911 +0,0 @@
-/*
- * Copyright © 2008-2015 Intel Corporation
- *
- * 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 (including the next
- * paragraph) 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 "i915_drv.h"
-#include "i915_scatterlist.h"
-#include "i915_pvinfo.h"
-#include "i915_vgpu.h"
-
-/**
- * DOC: fence register handling
- *
- * Important to avoid confusions: "fences" in the i915 driver are not execution
- * fences used to track command completion but hardware detiler objects which
- * wrap a given range of the global GTT. Each platform has only a fairly limited
- * set of these objects.
- *
- * Fences are used to detile GTT memory mappings. They're also connected to the
- * hardware frontbuffer render tracking and hence interact with frontbuffer
- * compression. Furthermore on older platforms fences are required for tiled
- * objects used by the display engine. They can also be used by the render
- * engine - they're required for blitter commands and are optional for render
- * commands. But on gen4+ both display (with the exception of fbc) and rendering
- * have their own tiling state bits and don't need fences.
- *
- * Also note that fences only support X and Y tiling and hence can't be used for
- * the fancier new tiling formats like W, Ys and Yf.
- *
- * Finally note that because fences are such a restricted resource they're
- * dynamically associated with objects. Furthermore fence state is committed to
- * the hardware lazily to avoid unnecessary stalls on gen2/3. Therefore code must
- * explicitly call i915_gem_object_get_fence() to synchronize fencing status
- * for cpu access. Also note that some code wants an unfenced view, for those
- * cases the fence can be removed forcefully with i915_gem_object_put_fence().
- *
- * Internally these functions will synchronize with userspace access by removing
- * CPU ptes into GTT mmaps (not the GTT ptes themselves) as needed.
- */
-
-#define pipelined 0
-
-static struct drm_i915_private *fence_to_i915(struct i915_fence_reg *fence)
-{
-	return fence->ggtt->vm.i915;
-}
-
-static struct intel_uncore *fence_to_uncore(struct i915_fence_reg *fence)
-{
-	return fence->ggtt->vm.gt->uncore;
-}
-
-static void i965_write_fence_reg(struct i915_fence_reg *fence,
-				 struct i915_vma *vma)
-{
-	i915_reg_t fence_reg_lo, fence_reg_hi;
-	int fence_pitch_shift;
-	u64 val;
-
-	if (INTEL_GEN(fence_to_i915(fence)) >= 6) {
-		fence_reg_lo = FENCE_REG_GEN6_LO(fence->id);
-		fence_reg_hi = FENCE_REG_GEN6_HI(fence->id);
-		fence_pitch_shift = GEN6_FENCE_PITCH_SHIFT;
-
-	} else {
-		fence_reg_lo = FENCE_REG_965_LO(fence->id);
-		fence_reg_hi = FENCE_REG_965_HI(fence->id);
-		fence_pitch_shift = I965_FENCE_PITCH_SHIFT;
-	}
-
-	val = 0;
-	if (vma) {
-		unsigned int stride = i915_gem_object_get_stride(vma->obj);
-
-		GEM_BUG_ON(!i915_vma_is_map_and_fenceable(vma));
-		GEM_BUG_ON(!IS_ALIGNED(vma->node.start, I965_FENCE_PAGE));
-		GEM_BUG_ON(!IS_ALIGNED(vma->fence_size, I965_FENCE_PAGE));
-		GEM_BUG_ON(!IS_ALIGNED(stride, 128));
-
-		val = (vma->node.start + vma->fence_size - I965_FENCE_PAGE) << 32;
-		val |= vma->node.start;
-		val |= (u64)((stride / 128) - 1) << fence_pitch_shift;
-		if (i915_gem_object_get_tiling(vma->obj) == I915_TILING_Y)
-			val |= BIT(I965_FENCE_TILING_Y_SHIFT);
-		val |= I965_FENCE_REG_VALID;
-	}
-
-	if (!pipelined) {
-		struct intel_uncore *uncore = fence_to_uncore(fence);
-
-		/*
-		 * To w/a incoherency with non-atomic 64-bit register updates,
-		 * we split the 64-bit update into two 32-bit writes. In order
-		 * for a partial fence not to be evaluated between writes, we
-		 * precede the update with write to turn off the fence register,
-		 * and only enable the fence as the last step.
-		 *
-		 * For extra levels of paranoia, we make sure each step lands
-		 * before applying the next step.
-		 */
-		intel_uncore_write_fw(uncore, fence_reg_lo, 0);
-		intel_uncore_posting_read_fw(uncore, fence_reg_lo);
-
-		intel_uncore_write_fw(uncore, fence_reg_hi, upper_32_bits(val));
-		intel_uncore_write_fw(uncore, fence_reg_lo, lower_32_bits(val));
-		intel_uncore_posting_read_fw(uncore, fence_reg_lo);
-	}
-}
-
-static void i915_write_fence_reg(struct i915_fence_reg *fence,
-				 struct i915_vma *vma)
-{
-	u32 val;
-
-	val = 0;
-	if (vma) {
-		unsigned int tiling = i915_gem_object_get_tiling(vma->obj);
-		bool is_y_tiled = tiling == I915_TILING_Y;
-		unsigned int stride = i915_gem_object_get_stride(vma->obj);
-
-		GEM_BUG_ON(!i915_vma_is_map_and_fenceable(vma));
-		GEM_BUG_ON(vma->node.start & ~I915_FENCE_START_MASK);
-		GEM_BUG_ON(!is_power_of_2(vma->fence_size));
-		GEM_BUG_ON(!IS_ALIGNED(vma->node.start, vma->fence_size));
-
-		if (is_y_tiled && HAS_128_BYTE_Y_TILING(fence_to_i915(fence)))
-			stride /= 128;
-		else
-			stride /= 512;
-		GEM_BUG_ON(!is_power_of_2(stride));
-
-		val = vma->node.start;
-		if (is_y_tiled)
-			val |= BIT(I830_FENCE_TILING_Y_SHIFT);
-		val |= I915_FENCE_SIZE_BITS(vma->fence_size);
-		val |= ilog2(stride) << I830_FENCE_PITCH_SHIFT;
-
-		val |= I830_FENCE_REG_VALID;
-	}
-
-	if (!pipelined) {
-		struct intel_uncore *uncore = fence_to_uncore(fence);
-		i915_reg_t reg = FENCE_REG(fence->id);
-
-		intel_uncore_write_fw(uncore, reg, val);
-		intel_uncore_posting_read_fw(uncore, reg);
-	}
-}
-
-static void i830_write_fence_reg(struct i915_fence_reg *fence,
-				 struct i915_vma *vma)
-{
-	u32 val;
-
-	val = 0;
-	if (vma) {
-		unsigned int stride = i915_gem_object_get_stride(vma->obj);
-
-		GEM_BUG_ON(!i915_vma_is_map_and_fenceable(vma));
-		GEM_BUG_ON(vma->node.start & ~I830_FENCE_START_MASK);
-		GEM_BUG_ON(!is_power_of_2(vma->fence_size));
-		GEM_BUG_ON(!is_power_of_2(stride / 128));
-		GEM_BUG_ON(!IS_ALIGNED(vma->node.start, vma->fence_size));
-
-		val = vma->node.start;
-		if (i915_gem_object_get_tiling(vma->obj) == I915_TILING_Y)
-			val |= BIT(I830_FENCE_TILING_Y_SHIFT);
-		val |= I830_FENCE_SIZE_BITS(vma->fence_size);
-		val |= ilog2(stride / 128) << I830_FENCE_PITCH_SHIFT;
-		val |= I830_FENCE_REG_VALID;
-	}
-
-	if (!pipelined) {
-		struct intel_uncore *uncore = fence_to_uncore(fence);
-		i915_reg_t reg = FENCE_REG(fence->id);
-
-		intel_uncore_write_fw(uncore, reg, val);
-		intel_uncore_posting_read_fw(uncore, reg);
-	}
-}
-
-static void fence_write(struct i915_fence_reg *fence,
-			struct i915_vma *vma)
-{
-	struct drm_i915_private *i915 = fence_to_i915(fence);
-
-	/*
-	 * Previous access through the fence register is marshalled by
-	 * the mb() inside the fault handlers (i915_gem_release_mmaps)
-	 * and explicitly managed for internal users.
-	 */
-
-	if (IS_GEN(i915, 2))
-		i830_write_fence_reg(fence, vma);
-	else if (IS_GEN(i915, 3))
-		i915_write_fence_reg(fence, vma);
-	else
-		i965_write_fence_reg(fence, vma);
-
-	/*
-	 * Access through the fenced region afterwards is
-	 * ordered by the posting reads whilst writing the registers.
-	 */
-
-	fence->dirty = false;
-}
-
-static int fence_update(struct i915_fence_reg *fence,
-			struct i915_vma *vma)
-{
-	struct i915_ggtt *ggtt = fence->ggtt;
-	struct intel_uncore *uncore = fence_to_uncore(fence);
-	intel_wakeref_t wakeref;
-	struct i915_vma *old;
-	int ret;
-
-	if (vma) {
-		if (!i915_vma_is_map_and_fenceable(vma))
-			return -EINVAL;
-
-		if (drm_WARN(&uncore->i915->drm,
-			     !i915_gem_object_get_stride(vma->obj) ||
-			     !i915_gem_object_get_tiling(vma->obj),
-			     "bogus fence setup with stride: 0x%x, tiling mode: %i\n",
-			     i915_gem_object_get_stride(vma->obj),
-			     i915_gem_object_get_tiling(vma->obj)))
-			return -EINVAL;
-
-		ret = i915_vma_sync(vma);
-		if (ret)
-			return ret;
-	}
-
-	old = xchg(&fence->vma, NULL);
-	if (old) {
-		/* XXX Ideally we would move the waiting to outside the mutex */
-		ret = i915_vma_sync(old);
-		if (ret) {
-			fence->vma = old;
-			return ret;
-		}
-
-		i915_vma_flush_writes(old);
-
-		/*
-		 * Ensure that all userspace CPU access is completed before
-		 * stealing the fence.
-		 */
-		if (old != vma) {
-			GEM_BUG_ON(old->fence != fence);
-			i915_vma_revoke_mmap(old);
-			old->fence = NULL;
-		}
-
-		list_move(&fence->link, &ggtt->fence_list);
-	}
-
-	/*
-	 * We only need to update the register itself if the device is awake.
-	 * If the device is currently powered down, we will defer the write
-	 * to the runtime resume, see i915_gem_restore_fences().
-	 *
-	 * This only works for removing the fence register, on acquisition
-	 * the caller must hold the rpm wakeref. The fence register must
-	 * be cleared before we can use any other fences to ensure that
-	 * the new fences do not overlap the elided clears, confusing HW.
-	 */
-	wakeref = intel_runtime_pm_get_if_in_use(uncore->rpm);
-	if (!wakeref) {
-		GEM_BUG_ON(vma);
-		return 0;
-	}
-
-	WRITE_ONCE(fence->vma, vma);
-	fence_write(fence, vma);
-
-	if (vma) {
-		vma->fence = fence;
-		list_move_tail(&fence->link, &ggtt->fence_list);
-	}
-
-	intel_runtime_pm_put(uncore->rpm, wakeref);
-	return 0;
-}
-
-/**
- * i915_vma_revoke_fence - force-remove fence for a VMA
- * @vma: vma to map linearly (not through a fence reg)
- *
- * This function force-removes any fence from the given object, which is useful
- * if the kernel wants to do untiled GTT access.
- *
- * Returns:
- *
- * 0 on success, negative error code on failure.
- */
-int i915_vma_revoke_fence(struct i915_vma *vma)
-{
-	struct i915_fence_reg *fence = vma->fence;
-
-	lockdep_assert_held(&vma->vm->mutex);
-	if (!fence)
-		return 0;
-
-	if (atomic_read(&fence->pin_count))
-		return -EBUSY;
-
-	return fence_update(fence, NULL);
-}
-
-static struct i915_fence_reg *fence_find(struct i915_ggtt *ggtt)
-{
-	struct i915_fence_reg *fence;
-
-	list_for_each_entry(fence, &ggtt->fence_list, link) {
-		GEM_BUG_ON(fence->vma && fence->vma->fence != fence);
-
-		if (atomic_read(&fence->pin_count))
-			continue;
-
-		return fence;
-	}
-
-	/* Wait for completion of pending flips which consume fences */
-	if (intel_has_pending_fb_unpin(ggtt->vm.i915))
-		return ERR_PTR(-EAGAIN);
-
-	return ERR_PTR(-EDEADLK);
-}
-
-int __i915_vma_pin_fence(struct i915_vma *vma)
-{
-	struct i915_ggtt *ggtt = i915_vm_to_ggtt(vma->vm);
-	struct i915_fence_reg *fence;
-	struct i915_vma *set = i915_gem_object_is_tiled(vma->obj) ? vma : NULL;
-	int err;
-
-	lockdep_assert_held(&vma->vm->mutex);
-
-	/* Just update our place in the LRU if our fence is getting reused. */
-	if (vma->fence) {
-		fence = vma->fence;
-		GEM_BUG_ON(fence->vma != vma);
-		atomic_inc(&fence->pin_count);
-		if (!fence->dirty) {
-			list_move_tail(&fence->link, &ggtt->fence_list);
-			return 0;
-		}
-	} else if (set) {
-		fence = fence_find(ggtt);
-		if (IS_ERR(fence))
-			return PTR_ERR(fence);
-
-		GEM_BUG_ON(atomic_read(&fence->pin_count));
-		atomic_inc(&fence->pin_count);
-	} else {
-		return 0;
-	}
-
-	err = fence_update(fence, set);
-	if (err)
-		goto out_unpin;
-
-	GEM_BUG_ON(fence->vma != set);
-	GEM_BUG_ON(vma->fence != (set ? fence : NULL));
-
-	if (set)
-		return 0;
-
-out_unpin:
-	atomic_dec(&fence->pin_count);
-	return err;
-}
-
-/**
- * i915_vma_pin_fence - set up fencing for a vma
- * @vma: vma to map through a fence reg
- *
- * When mapping objects through the GTT, userspace wants to be able to write
- * to them without having to worry about swizzling if the object is tiled.
- * This function walks the fence regs looking for a free one for @obj,
- * stealing one if it can't find any.
- *
- * It then sets up the reg based on the object's properties: address, pitch
- * and tiling format.
- *
- * For an untiled surface, this removes any existing fence.
- *
- * Returns:
- *
- * 0 on success, negative error code on failure.
- */
-int i915_vma_pin_fence(struct i915_vma *vma)
-{
-	int err;
-
-	if (!vma->fence && !i915_gem_object_is_tiled(vma->obj))
-		return 0;
-
-	/*
-	 * Note that we revoke fences on runtime suspend. Therefore the user
-	 * must keep the device awake whilst using the fence.
-	 */
-	assert_rpm_wakelock_held(vma->vm->gt->uncore->rpm);
-	GEM_BUG_ON(!i915_vma_is_pinned(vma));
-	GEM_BUG_ON(!i915_vma_is_ggtt(vma));
-
-	err = mutex_lock_interruptible(&vma->vm->mutex);
-	if (err)
-		return err;
-
-	err = __i915_vma_pin_fence(vma);
-	mutex_unlock(&vma->vm->mutex);
-
-	return err;
-}
-
-/**
- * i915_reserve_fence - Reserve a fence for vGPU
- * @ggtt: Global GTT
- *
- * This function walks the fence regs looking for a free one and remove
- * it from the fence_list. It is used to reserve fence for vGPU to use.
- */
-struct i915_fence_reg *i915_reserve_fence(struct i915_ggtt *ggtt)
-{
-	struct i915_fence_reg *fence;
-	int count;
-	int ret;
-
-	lockdep_assert_held(&ggtt->vm.mutex);
-
-	/* Keep at least one fence available for the display engine. */
-	count = 0;
-	list_for_each_entry(fence, &ggtt->fence_list, link)
-		count += !atomic_read(&fence->pin_count);
-	if (count <= 1)
-		return ERR_PTR(-ENOSPC);
-
-	fence = fence_find(ggtt);
-	if (IS_ERR(fence))
-		return fence;
-
-	if (fence->vma) {
-		/* Force-remove fence from VMA */
-		ret = fence_update(fence, NULL);
-		if (ret)
-			return ERR_PTR(ret);
-	}
-
-	list_del(&fence->link);
-
-	return fence;
-}
-
-/**
- * i915_unreserve_fence - Reclaim a reserved fence
- * @fence: the fence reg
- *
- * This function add a reserved fence register from vGPU to the fence_list.
- */
-void i915_unreserve_fence(struct i915_fence_reg *fence)
-{
-	struct i915_ggtt *ggtt = fence->ggtt;
-
-	lockdep_assert_held(&ggtt->vm.mutex);
-
-	list_add(&fence->link, &ggtt->fence_list);
-}
-
-/**
- * i915_gem_restore_fences - restore fence state
- * @ggtt: Global GTT
- *
- * Restore the hw fence state to match the software tracking again, to be called
- * after a gpu reset and on resume. Note that on runtime suspend we only cancel
- * the fences, to be reacquired by the user later.
- */
-void i915_gem_restore_fences(struct i915_ggtt *ggtt)
-{
-	int i;
-
-	rcu_read_lock(); /* keep obj alive as we dereference */
-	for (i = 0; i < ggtt->num_fences; i++) {
-		struct i915_fence_reg *reg = &ggtt->fence_regs[i];
-		struct i915_vma *vma = READ_ONCE(reg->vma);
-
-		GEM_BUG_ON(vma && vma->fence != reg);
-
-		/*
-		 * Commit delayed tiling changes if we have an object still
-		 * attached to the fence, otherwise just clear the fence.
-		 */
-		if (vma && !i915_gem_object_is_tiled(vma->obj))
-			vma = NULL;
-
-		fence_write(reg, vma);
-	}
-	rcu_read_unlock();
-}
-
-/**
- * DOC: tiling swizzling details
- *
- * The idea behind tiling is to increase cache hit rates by rearranging
- * pixel data so that a group of pixel accesses are in the same cacheline.
- * Performance improvement from doing this on the back/depth buffer are on
- * the order of 30%.
- *
- * Intel architectures make this somewhat more complicated, though, by
- * adjustments made to addressing of data when the memory is in interleaved
- * mode (matched pairs of DIMMS) to improve memory bandwidth.
- * For interleaved memory, the CPU sends every sequential 64 bytes
- * to an alternate memory channel so it can get the bandwidth from both.
- *
- * The GPU also rearranges its accesses for increased bandwidth to interleaved
- * memory, and it matches what the CPU does for non-tiled.  However, when tiled
- * it does it a little differently, since one walks addresses not just in the
- * X direction but also Y.  So, along with alternating channels when bit
- * 6 of the address flips, it also alternates when other bits flip --  Bits 9
- * (every 512 bytes, an X tile scanline) and 10 (every two X tile scanlines)
- * are common to both the 915 and 965-class hardware.
- *
- * The CPU also sometimes XORs in higher bits as well, to improve
- * bandwidth doing strided access like we do so frequently in graphics.  This
- * is called "Channel XOR Randomization" in the MCH documentation.  The result
- * is that the CPU is XORing in either bit 11 or bit 17 to bit 6 of its address
- * decode.
- *
- * All of this bit 6 XORing has an effect on our memory management,
- * as we need to make sure that the 3d driver can correctly address object
- * contents.
- *
- * If we don't have interleaved memory, all tiling is safe and no swizzling is
- * required.
- *
- * When bit 17 is XORed in, we simply refuse to tile at all.  Bit
- * 17 is not just a page offset, so as we page an object out and back in,
- * individual pages in it will have different bit 17 addresses, resulting in
- * each 64 bytes being swapped with its neighbor!
- *
- * Otherwise, if interleaved, we have to tell the 3d driver what the address
- * swizzling it needs to do is, since it's writing with the CPU to the pages
- * (bit 6 and potentially bit 11 XORed in), and the GPU is reading from the
- * pages (bit 6, 9, and 10 XORed in), resulting in a cumulative bit swizzling
- * required by the CPU of XORing in bit 6, 9, 10, and potentially 11, in order
- * to match what the GPU expects.
- */
-
-/**
- * detect_bit_6_swizzle - detect bit 6 swizzling pattern
- * @ggtt: Global GGTT
- *
- * Detects bit 6 swizzling of address lookup between IGD access and CPU
- * access through main memory.
- */
-static void detect_bit_6_swizzle(struct i915_ggtt *ggtt)
-{
-	struct intel_uncore *uncore = ggtt->vm.gt->uncore;
-	struct drm_i915_private *i915 = ggtt->vm.i915;
-	u32 swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
-	u32 swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
-
-	if (INTEL_GEN(i915) >= 8 || IS_VALLEYVIEW(i915)) {
-		/*
-		 * On BDW+, swizzling is not used. We leave the CPU memory
-		 * controller in charge of optimizing memory accesses without
-		 * the extra address manipulation GPU side.
-		 *
-		 * VLV and CHV don't have GPU swizzling.
-		 */
-		swizzle_x = I915_BIT_6_SWIZZLE_NONE;
-		swizzle_y = I915_BIT_6_SWIZZLE_NONE;
-	} else if (INTEL_GEN(i915) >= 6) {
-		if (i915->preserve_bios_swizzle) {
-			if (intel_uncore_read(uncore, DISP_ARB_CTL) &
-			    DISP_TILE_SURFACE_SWIZZLING) {
-				swizzle_x = I915_BIT_6_SWIZZLE_9_10;
-				swizzle_y = I915_BIT_6_SWIZZLE_9;
-			} else {
-				swizzle_x = I915_BIT_6_SWIZZLE_NONE;
-				swizzle_y = I915_BIT_6_SWIZZLE_NONE;
-			}
-		} else {
-			u32 dimm_c0, dimm_c1;
-			dimm_c0 = intel_uncore_read(uncore, MAD_DIMM_C0);
-			dimm_c1 = intel_uncore_read(uncore, MAD_DIMM_C1);
-			dimm_c0 &= MAD_DIMM_A_SIZE_MASK | MAD_DIMM_B_SIZE_MASK;
-			dimm_c1 &= MAD_DIMM_A_SIZE_MASK | MAD_DIMM_B_SIZE_MASK;
-			/*
-			 * Enable swizzling when the channels are populated
-			 * with identically sized dimms. We don't need to check
-			 * the 3rd channel because no cpu with gpu attached
-			 * ships in that configuration. Also, swizzling only
-			 * makes sense for 2 channels anyway.
-			 */
-			if (dimm_c0 == dimm_c1) {
-				swizzle_x = I915_BIT_6_SWIZZLE_9_10;
-				swizzle_y = I915_BIT_6_SWIZZLE_9;
-			} else {
-				swizzle_x = I915_BIT_6_SWIZZLE_NONE;
-				swizzle_y = I915_BIT_6_SWIZZLE_NONE;
-			}
-		}
-	} else if (IS_GEN(i915, 5)) {
-		/*
-		 * On Ironlake whatever DRAM config, GPU always do
-		 * same swizzling setup.
-		 */
-		swizzle_x = I915_BIT_6_SWIZZLE_9_10;
-		swizzle_y = I915_BIT_6_SWIZZLE_9;
-	} else if (IS_GEN(i915, 2)) {
-		/*
-		 * As far as we know, the 865 doesn't have these bit 6
-		 * swizzling issues.
-		 */
-		swizzle_x = I915_BIT_6_SWIZZLE_NONE;
-		swizzle_y = I915_BIT_6_SWIZZLE_NONE;
-	} else if (IS_G45(i915) || IS_I965G(i915) || IS_G33(i915)) {
-		/*
-		 * The 965, G33, and newer, have a very flexible memory
-		 * configuration.  It will enable dual-channel mode
-		 * (interleaving) on as much memory as it can, and the GPU
-		 * will additionally sometimes enable different bit 6
-		 * swizzling for tiled objects from the CPU.
-		 *
-		 * Here's what I found on the G965:
-		 *    slot fill         memory size  swizzling
-		 * 0A   0B   1A   1B    1-ch   2-ch
-		 * 512  0    0    0     512    0     O
-		 * 512  0    512  0     16     1008  X
-		 * 512  0    0    512   16     1008  X
-		 * 0    512  0    512   16     1008  X
-		 * 1024 1024 1024 0     2048   1024  O
-		 *
-		 * We could probably detect this based on either the DRB
-		 * matching, which was the case for the swizzling required in
-		 * the table above, or from the 1-ch value being less than
-		 * the minimum size of a rank.
-		 *
-		 * Reports indicate that the swizzling actually
-		 * varies depending upon page placement inside the
-		 * channels, i.e. we see swizzled pages where the
-		 * banks of memory are paired and unswizzled on the
-		 * uneven portion, so leave that as unknown.
-		 */
-		if (intel_uncore_read(uncore, C0DRB3) ==
-		    intel_uncore_read(uncore, C1DRB3)) {
-			swizzle_x = I915_BIT_6_SWIZZLE_9_10;
-			swizzle_y = I915_BIT_6_SWIZZLE_9;
-		}
-	} else {
-		u32 dcc = intel_uncore_read(uncore, DCC);
-
-		/*
-		 * On 9xx chipsets, channel interleave by the CPU is
-		 * determined by DCC.  For single-channel, neither the CPU
-		 * nor the GPU do swizzling.  For dual channel interleaved,
-		 * the GPU's interleave is bit 9 and 10 for X tiled, and bit
-		 * 9 for Y tiled.  The CPU's interleave is independent, and
-		 * can be based on either bit 11 (haven't seen this yet) or
-		 * bit 17 (common).
-		 */
-		switch (dcc & DCC_ADDRESSING_MODE_MASK) {
-		case DCC_ADDRESSING_MODE_SINGLE_CHANNEL:
-		case DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC:
-			swizzle_x = I915_BIT_6_SWIZZLE_NONE;
-			swizzle_y = I915_BIT_6_SWIZZLE_NONE;
-			break;
-		case DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED:
-			if (dcc & DCC_CHANNEL_XOR_DISABLE) {
-				/*
-				 * This is the base swizzling by the GPU for
-				 * tiled buffers.
-				 */
-				swizzle_x = I915_BIT_6_SWIZZLE_9_10;
-				swizzle_y = I915_BIT_6_SWIZZLE_9;
-			} else if ((dcc & DCC_CHANNEL_XOR_BIT_17) == 0) {
-				/* Bit 11 swizzling by the CPU in addition. */
-				swizzle_x = I915_BIT_6_SWIZZLE_9_10_11;
-				swizzle_y = I915_BIT_6_SWIZZLE_9_11;
-			} else {
-				/* Bit 17 swizzling by the CPU in addition. */
-				swizzle_x = I915_BIT_6_SWIZZLE_9_10_17;
-				swizzle_y = I915_BIT_6_SWIZZLE_9_17;
-			}
-			break;
-		}
-
-		/* check for L-shaped memory aka modified enhanced addressing */
-		if (IS_GEN(i915, 4) &&
-		    !(intel_uncore_read(uncore, DCC2) & DCC2_MODIFIED_ENHANCED_DISABLE)) {
-			swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
-			swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
-		}
-
-		if (dcc == 0xffffffff) {
-			drm_err(&i915->drm, "Couldn't read from MCHBAR.  "
-				  "Disabling tiling.\n");
-			swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
-			swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
-		}
-	}
-
-	if (swizzle_x == I915_BIT_6_SWIZZLE_UNKNOWN ||
-	    swizzle_y == I915_BIT_6_SWIZZLE_UNKNOWN) {
-		/*
-		 * Userspace likes to explode if it sees unknown swizzling,
-		 * so lie. We will finish the lie when reporting through
-		 * the get-tiling-ioctl by reporting the physical swizzle
-		 * mode as unknown instead.
-		 *
-		 * As we don't strictly know what the swizzling is, it may be
-		 * bit17 dependent, and so we need to also prevent the pages
-		 * from being moved.
-		 */
-		i915->quirks |= QUIRK_PIN_SWIZZLED_PAGES;
-		swizzle_x = I915_BIT_6_SWIZZLE_NONE;
-		swizzle_y = I915_BIT_6_SWIZZLE_NONE;
-	}
-
-	i915->ggtt.bit_6_swizzle_x = swizzle_x;
-	i915->ggtt.bit_6_swizzle_y = swizzle_y;
-}
-
-/*
- * Swap every 64 bytes of this page around, to account for it having a new
- * bit 17 of its physical address and therefore being interpreted differently
- * by the GPU.
- */
-static void i915_gem_swizzle_page(struct page *page)
-{
-	char temp[64];
-	char *vaddr;
-	int i;
-
-	vaddr = kmap(page);
-
-	for (i = 0; i < PAGE_SIZE; i += 128) {
-		memcpy(temp, &vaddr[i], 64);
-		memcpy(&vaddr[i], &vaddr[i + 64], 64);
-		memcpy(&vaddr[i + 64], temp, 64);
-	}
-
-	kunmap(page);
-}
-
-/**
- * i915_gem_object_do_bit_17_swizzle - fixup bit 17 swizzling
- * @obj: i915 GEM buffer object
- * @pages: the scattergather list of physical pages
- *
- * This function fixes up the swizzling in case any page frame number for this
- * object has changed in bit 17 since that state has been saved with
- * i915_gem_object_save_bit_17_swizzle().
- *
- * This is called when pinning backing storage again, since the kernel is free
- * to move unpinned backing storage around (either by directly moving pages or
- * by swapping them out and back in again).
- */
-void
-i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj,
-				  struct sg_table *pages)
-{
-	struct sgt_iter sgt_iter;
-	struct page *page;
-	int i;
-
-	if (obj->bit_17 == NULL)
-		return;
-
-	i = 0;
-	for_each_sgt_page(page, sgt_iter, pages) {
-		char new_bit_17 = page_to_phys(page) >> 17;
-		if ((new_bit_17 & 0x1) != (test_bit(i, obj->bit_17) != 0)) {
-			i915_gem_swizzle_page(page);
-			set_page_dirty(page);
-		}
-		i++;
-	}
-}
-
-/**
- * i915_gem_object_save_bit_17_swizzle - save bit 17 swizzling
- * @obj: i915 GEM buffer object
- * @pages: the scattergather list of physical pages
- *
- * This function saves the bit 17 of each page frame number so that swizzling
- * can be fixed up later on with i915_gem_object_do_bit_17_swizzle(). This must
- * be called before the backing storage can be unpinned.
- */
-void
-i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj,
-				    struct sg_table *pages)
-{
-	const unsigned int page_count = obj->base.size >> PAGE_SHIFT;
-	struct sgt_iter sgt_iter;
-	struct page *page;
-	int i;
-
-	if (obj->bit_17 == NULL) {
-		obj->bit_17 = bitmap_zalloc(page_count, GFP_KERNEL);
-		if (obj->bit_17 == NULL) {
-			DRM_ERROR("Failed to allocate memory for bit 17 "
-				  "record\n");
-			return;
-		}
-	}
-
-	i = 0;
-
-	for_each_sgt_page(page, sgt_iter, pages) {
-		if (page_to_phys(page) & (1 << 17))
-			__set_bit(i, obj->bit_17);
-		else
-			__clear_bit(i, obj->bit_17);
-		i++;
-	}
-}
-
-void i915_ggtt_init_fences(struct i915_ggtt *ggtt)
-{
-	struct drm_i915_private *i915 = ggtt->vm.i915;
-	struct intel_uncore *uncore = ggtt->vm.gt->uncore;
-	int num_fences;
-	int i;
-
-	INIT_LIST_HEAD(&ggtt->fence_list);
-	INIT_LIST_HEAD(&ggtt->userfault_list);
-	intel_wakeref_auto_init(&ggtt->userfault_wakeref, uncore->rpm);
-
-	detect_bit_6_swizzle(ggtt);
-
-	if (!i915_ggtt_has_aperture(ggtt))
-		num_fences = 0;
-	else if (INTEL_GEN(i915) >= 7 &&
-		 !(IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)))
-		num_fences = 32;
-	else if (INTEL_GEN(i915) >= 4 ||
-		 IS_I945G(i915) || IS_I945GM(i915) ||
-		 IS_G33(i915) || IS_PINEVIEW(i915))
-		num_fences = 16;
-	else
-		num_fences = 8;
-
-	if (intel_vgpu_active(i915))
-		num_fences = intel_uncore_read(uncore,
-					       vgtif_reg(avail_rs.fence_num));
-
-	/* Initialize fence registers to zero */
-	for (i = 0; i < num_fences; i++) {
-		struct i915_fence_reg *fence = &ggtt->fence_regs[i];
-
-		fence->ggtt = ggtt;
-		fence->id = i;
-		list_add_tail(&fence->link, &ggtt->fence_list);
-	}
-	ggtt->num_fences = num_fences;
-
-	i915_gem_restore_fences(ggtt);
-}
-
-void intel_gt_init_swizzling(struct intel_gt *gt)
-{
-	struct drm_i915_private *i915 = gt->i915;
-	struct intel_uncore *uncore = gt->uncore;
-
-	if (INTEL_GEN(i915) < 5 ||
-	    i915->ggtt.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_NONE)
-		return;
-
-	intel_uncore_rmw(uncore, DISP_ARB_CTL, 0, DISP_TILE_SURFACE_SWIZZLING);
-
-	if (IS_GEN(i915, 5))
-		return;
-
-	intel_uncore_rmw(uncore, TILECTL, 0, TILECTL_SWZCTL);
-
-	if (IS_GEN(i915, 6))
-		intel_uncore_write(uncore,
-				   ARB_MODE,
-				   _MASKED_BIT_ENABLE(ARB_MODE_SWIZZLE_SNB));
-	else if (IS_GEN(i915, 7))
-		intel_uncore_write(uncore,
-				   ARB_MODE,
-				   _MASKED_BIT_ENABLE(ARB_MODE_SWIZZLE_IVB));
-	else if (IS_GEN(i915, 8))
-		intel_uncore_write(uncore,
-				   GAMTARBMODE,
-				   _MASKED_BIT_ENABLE(ARB_MODE_SWIZZLE_BDW));
-	else
-		MISSING_CASE(INTEL_GEN(i915));
-}
diff --git a/drivers/gpu/drm/i915/i915_gem_fence_reg.h b/drivers/gpu/drm/i915/i915_gem_fence_reg.h
deleted file mode 100644
index 7bd521cd7cd7..000000000000
--- a/drivers/gpu/drm/i915/i915_gem_fence_reg.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright © 2016 Intel Corporation
- *
- * 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 (including the next
- * paragraph) 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 __I915_FENCE_REG_H__
-#define __I915_FENCE_REG_H__
-
-#include <linux/list.h>
-#include <linux/types.h>
-
-struct drm_i915_gem_object;
-struct i915_ggtt;
-struct i915_vma;
-struct intel_gt;
-struct sg_table;
-
-#define I965_FENCE_PAGE 4096UL
-
-struct i915_fence_reg {
-	struct list_head link;
-	struct i915_ggtt *ggtt;
-	struct i915_vma *vma;
-	atomic_t pin_count;
-	int id;
-	/**
-	 * Whether the tiling parameters for the currently
-	 * associated fence register have changed. Note that
-	 * for the purposes of tracking tiling changes we also
-	 * treat the unfenced register, the register slot that
-	 * the object occupies whilst it executes a fenced
-	 * command (such as BLT on gen2/3), as a "fence".
-	 */
-	bool dirty;
-};
-
-/* i915_gem_fence_reg.c */
-struct i915_fence_reg *i915_reserve_fence(struct i915_ggtt *ggtt);
-void i915_unreserve_fence(struct i915_fence_reg *fence);
-
-void i915_gem_restore_fences(struct i915_ggtt *ggtt);
-
-void i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj,
-				       struct sg_table *pages);
-void i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj,
-					 struct sg_table *pages);
-
-void i915_ggtt_init_fences(struct i915_ggtt *ggtt);
-
-void intel_gt_init_swizzling(struct intel_gt *gt);
-
-#endif
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index 2a4cd0ba5464..424ad975a360 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -1858,7 +1858,7 @@ void i915_error_state_store(struct i915_gpu_coredump *error)
 		return;
 
 	i915 = error->i915;
-	dev_info(i915->drm.dev, "%s\n", error_msg(error));
+	drm_info(&i915->drm, "%s\n", error_msg(error));
 
 	if (error->simulated ||
 	    cmpxchg(&i915->gpu_error.first_error, NULL, error))
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 9f0653cf0510..1502ab44f1a5 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -3658,7 +3658,7 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg)
 		intel_uncore_write16(&dev_priv->uncore, GEN2_IIR, iir);
 
 		if (iir & I915_USER_INTERRUPT)
-			intel_engine_signal_breadcrumbs(dev_priv->engine[RCS0]);
+			intel_engine_signal_breadcrumbs(dev_priv->gt.engine[RCS0]);
 
 		if (iir & I915_MASTER_ERROR_INTERRUPT)
 			i8xx_error_irq_handler(dev_priv, eir, eir_stuck);
@@ -3763,7 +3763,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
 		I915_WRITE(GEN2_IIR, iir);
 
 		if (iir & I915_USER_INTERRUPT)
-			intel_engine_signal_breadcrumbs(dev_priv->engine[RCS0]);
+			intel_engine_signal_breadcrumbs(dev_priv->gt.engine[RCS0]);
 
 		if (iir & I915_MASTER_ERROR_INTERRUPT)
 			i9xx_error_irq_handler(dev_priv, eir, eir_stuck);
@@ -3905,10 +3905,10 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
 		I915_WRITE(GEN2_IIR, iir);
 
 		if (iir & I915_USER_INTERRUPT)
-			intel_engine_signal_breadcrumbs(dev_priv->engine[RCS0]);
+			intel_engine_signal_breadcrumbs(dev_priv->gt.engine[RCS0]);
 
 		if (iir & I915_BSD_USER_INTERRUPT)
-			intel_engine_signal_breadcrumbs(dev_priv->engine[VCS0]);
+			intel_engine_signal_breadcrumbs(dev_priv->gt.engine[VCS0]);
 
 		if (iir & I915_MASTER_ERROR_INTERRUPT)
 			i9xx_error_irq_handler(dev_priv, eir, eir_stuck);
diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index 2c80a0194c80..66738f2c4f28 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -160,6 +160,7 @@
 	GEN(2), \
 	.is_mobile = 1, \
 	.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \
+	.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B), \
 	.display.has_overlay = 1, \
 	.display.cursor_needs_physical = 1, \
 	.display.overlay_needs_physical = 1, \
@@ -179,6 +180,7 @@
 #define I845_FEATURES \
 	GEN(2), \
 	.pipe_mask = BIT(PIPE_A), \
+	.cpu_transcoder_mask = BIT(TRANSCODER_A), \
 	.display.has_overlay = 1, \
 	.display.overlay_needs_physical = 1, \
 	.display.has_gmch = 1, \
@@ -218,6 +220,7 @@ static const struct intel_device_info i865g_info = {
 #define GEN3_FEATURES \
 	GEN(3), \
 	.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \
+	.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B), \
 	.display.has_gmch = 1, \
 	.gpu_reset_clobbers_display = true, \
 	.engine_mask = BIT(RCS0), \
@@ -303,6 +306,7 @@ static const struct intel_device_info pnv_m_info = {
 #define GEN4_FEATURES \
 	GEN(4), \
 	.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \
+	.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B), \
 	.display.has_hotplug = 1, \
 	.display.has_gmch = 1, \
 	.gpu_reset_clobbers_display = true, \
@@ -354,6 +358,7 @@ static const struct intel_device_info gm45_info = {
 #define GEN5_FEATURES \
 	GEN(5), \
 	.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \
+	.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B), \
 	.display.has_hotplug = 1, \
 	.engine_mask = BIT(RCS0) | BIT(VCS0), \
 	.has_snoop = true, \
@@ -381,6 +386,7 @@ static const struct intel_device_info ilk_m_info = {
 #define GEN6_FEATURES \
 	GEN(6), \
 	.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \
+	.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B), \
 	.display.has_hotplug = 1, \
 	.display.has_fbc = 1, \
 	.engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0), \
@@ -430,6 +436,7 @@ static const struct intel_device_info snb_m_gt2_info = {
 #define GEN7_FEATURES  \
 	GEN(7), \
 	.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C), \
+	.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C), \
 	.display.has_hotplug = 1, \
 	.display.has_fbc = 1, \
 	.engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0), \
@@ -482,6 +489,7 @@ static const struct intel_device_info ivb_q_info = {
 	PLATFORM(INTEL_IVYBRIDGE),
 	.gt = 2,
 	.pipe_mask = 0, /* legal, last one wins */
+	.cpu_transcoder_mask = 0,
 	.has_l3_dpf = 1,
 };
 
@@ -490,6 +498,7 @@ static const struct intel_device_info vlv_info = {
 	GEN(7),
 	.is_lp = 1,
 	.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B),
+	.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B),
 	.has_runtime_pm = 1,
 	.has_rc6 = 1,
 	.has_rps = true,
@@ -511,6 +520,8 @@ static const struct intel_device_info vlv_info = {
 #define G75_FEATURES  \
 	GEN7_FEATURES, \
 	.engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0) | BIT(VECS0), \
+	.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | \
+		BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP), \
 	.display.has_ddi = 1, \
 	.has_fpga_dbg = 1, \
 	.display.has_psr = 1, \
@@ -581,6 +592,7 @@ static const struct intel_device_info chv_info = {
 	PLATFORM(INTEL_CHERRYVIEW),
 	GEN(8),
 	.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
+	.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C),
 	.display.has_hotplug = 1,
 	.is_lp = 1,
 	.engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0) | BIT(VECS0),
@@ -656,6 +668,9 @@ static const struct intel_device_info skl_gt4_info = {
 	.display.has_hotplug = 1, \
 	.engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0) | BIT(VECS0), \
 	.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C), \
+	.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | \
+		BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP) | \
+		BIT(TRANSCODER_DSI_A) | BIT(TRANSCODER_DSI_C), \
 	.has_64bit_reloc = 1, \
 	.display.has_ddi = 1, \
 	.has_fpga_dbg = 1, \
@@ -759,6 +774,9 @@ static const struct intel_device_info cnl_info = {
 #define GEN11_FEATURES \
 	GEN10_FEATURES, \
 	GEN11_DEFAULT_PAGE_SIZES, \
+	.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | \
+		BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP) | \
+		BIT(TRANSCODER_DSI_0) | BIT(TRANSCODER_DSI_1), \
 	.pipe_offsets = { \
 		[TRANSCODER_A] = PIPE_A_OFFSET, \
 		[TRANSCODER_B] = PIPE_B_OFFSET, \
@@ -799,6 +817,10 @@ static const struct intel_device_info ehl_info = {
 #define GEN12_FEATURES \
 	GEN11_FEATURES, \
 	GEN(12), \
+	.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D), \
+	.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | \
+		BIT(TRANSCODER_C) | BIT(TRANSCODER_D) | \
+		BIT(TRANSCODER_DSI_0) | BIT(TRANSCODER_DSI_1), \
 	.pipe_offsets = { \
 		[TRANSCODER_A] = PIPE_A_OFFSET, \
 		[TRANSCODER_B] = PIPE_B_OFFSET, \
@@ -822,7 +844,6 @@ static const struct intel_device_info ehl_info = {
 static const struct intel_device_info tgl_info = {
 	GEN12_FEATURES,
 	PLATFORM(INTEL_TIGERLAKE),
-	.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D),
 	.display.has_modular_fia = 1,
 	.engine_mask =
 		BIT(RCS0) | BIT(BCS0) | BIT(VECS0) | BIT(VCS0) | BIT(VCS2),
diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c
index 551be589d6f4..5cde3e4e7be6 100644
--- a/drivers/gpu/drm/i915/i915_perf.c
+++ b/drivers/gpu/drm/i915/i915_perf.c
@@ -204,21 +204,6 @@
 
 #include "i915_drv.h"
 #include "i915_perf.h"
-#include "oa/i915_oa_hsw.h"
-#include "oa/i915_oa_bdw.h"
-#include "oa/i915_oa_chv.h"
-#include "oa/i915_oa_sklgt2.h"
-#include "oa/i915_oa_sklgt3.h"
-#include "oa/i915_oa_sklgt4.h"
-#include "oa/i915_oa_bxt.h"
-#include "oa/i915_oa_kblgt2.h"
-#include "oa/i915_oa_kblgt3.h"
-#include "oa/i915_oa_glk.h"
-#include "oa/i915_oa_cflgt2.h"
-#include "oa/i915_oa_cflgt3.h"
-#include "oa/i915_oa_cnl.h"
-#include "oa/i915_oa_icl.h"
-#include "oa/i915_oa_tgl.h"
 
 /* HW requires this to be a power of two, between 128k and 16M, though driver
  * is currently generally designed assuming the largest 16M size is used such
@@ -238,26 +223,17 @@
  *
  * Although this can be observed explicitly while copying reports to userspace
  * by checking for a zeroed report-id field in tail reports, we want to account
- * for this earlier, as part of the oa_buffer_check to avoid lots of redundant
- * read() attempts.
- *
- * In effect we define a tail pointer for reading that lags the real tail
- * pointer by at least %OA_TAIL_MARGIN_NSEC nanoseconds, which gives enough
- * time for the corresponding reports to become visible to the CPU.
- *
- * To manage this we actually track two tail pointers:
- *  1) An 'aging' tail with an associated timestamp that is tracked until we
- *     can trust the corresponding data is visible to the CPU; at which point
- *     it is considered 'aged'.
- *  2) An 'aged' tail that can be used for read()ing.
- *
- * The two separate pointers let us decouple read()s from tail pointer aging.
- *
- * The tail pointers are checked and updated at a limited rate within a hrtimer
- * callback (the same callback that is used for delivering EPOLLIN events)
- *
- * Initially the tails are marked invalid with %INVALID_TAIL_PTR which
- * indicates that an updated tail pointer is needed.
+ * for this earlier, as part of the oa_buffer_check_unlocked to avoid lots of
+ * redundant read() attempts.
+ *
+ * We workaround this issue in oa_buffer_check_unlocked() by reading the reports
+ * in the OA buffer, starting from the tail reported by the HW until we find a
+ * report with its first 2 dwords not 0 meaning its previous report is
+ * completely in memory and ready to be read. Those dwords are also set to 0
+ * once read and the whole buffer is cleared upon OA buffer initialization. The
+ * first dword is the reason for this report while the second is the timestamp,
+ * making the chances of having those 2 fields at 0 fairly unlikely. A more
+ * detailed explanation is available in oa_buffer_check_unlocked().
  *
  * Most of the implementation details for this workaround are in
  * oa_buffer_check_unlocked() and _append_oa_reports()
@@ -272,11 +248,11 @@
 #define OA_TAIL_MARGIN_NSEC	100000ULL
 #define INVALID_TAIL_PTR	0xffffffff
 
-/* frequency for checking whether the OA unit has written new reports to the
- * circular OA buffer...
+/* The default frequency for checking whether the OA unit has written new
+ * reports to the circular OA buffer...
  */
-#define POLL_FREQUENCY 200
-#define POLL_PERIOD (NSEC_PER_SEC / POLL_FREQUENCY)
+#define DEFAULT_POLL_FREQUENCY_HZ 200
+#define DEFAULT_POLL_PERIOD_NS (NSEC_PER_SEC / DEFAULT_POLL_FREQUENCY_HZ)
 
 /* for sysctl proc_dointvec_minmax of dev.i915.perf_stream_paranoid */
 static u32 i915_perf_stream_paranoid = true;
@@ -359,6 +335,12 @@ static const struct i915_oa_format gen12_oa_formats[I915_OA_FORMAT_MAX] = {
  * @oa_periodic: Whether to enable periodic OA unit sampling
  * @oa_period_exponent: The OA unit sampling period is derived from this
  * @engine: The engine (typically rcs0) being monitored by the OA unit
+ * @has_sseu: Whether @sseu was specified by userspace
+ * @sseu: internal SSEU configuration computed either from the userspace
+ *        specified configuration in the opening parameters or a default value
+ *        (see get_default_sseu_config())
+ * @poll_oa_period: The period in nanoseconds at which the CPU will check for OA
+ * data availability
  *
  * As read_properties_unlocked() enumerates and validates the properties given
  * to open a stream of metrics the configuration is built up in the structure
@@ -378,6 +360,11 @@ struct perf_open_properties {
 	int oa_period_exponent;
 
 	struct intel_engine_cs *engine;
+
+	bool has_sseu;
+	struct intel_sseu sseu;
+
+	u64 poll_oa_period;
 };
 
 struct i915_oa_config_bo {
@@ -409,10 +396,7 @@ i915_perf_get_oa_config(struct i915_perf *perf, int metrics_set)
 	struct i915_oa_config *oa_config;
 
 	rcu_read_lock();
-	if (metrics_set == 1)
-		oa_config = &perf->test_config;
-	else
-		oa_config = idr_find(&perf->metrics_idr, metrics_set);
+	oa_config = idr_find(&perf->metrics_idr, metrics_set);
 	if (oa_config)
 		oa_config = i915_oa_config_get(oa_config);
 	rcu_read_unlock();
@@ -465,8 +449,8 @@ static u32 gen7_oa_hw_tail_read(struct i915_perf_stream *stream)
  * (See description of OA_TAIL_MARGIN_NSEC above for further details.)
  *
  * Besides returning true when there is data available to read() this function
- * also has the side effect of updating the oa_buffer.tails[], .aging_timestamp
- * and .aged_tail_idx state used for reading.
+ * also updates the tail, aging_tail and aging_timestamp in the oa_buffer
+ * object.
  *
  * Note: It's safe to read OA config state here unlocked, assuming that this is
  * only called while the stream is enabled, while the global OA configuration
@@ -476,28 +460,19 @@ static u32 gen7_oa_hw_tail_read(struct i915_perf_stream *stream)
  */
 static bool oa_buffer_check_unlocked(struct i915_perf_stream *stream)
 {
+	u32 gtt_offset = i915_ggtt_offset(stream->oa_buffer.vma);
 	int report_size = stream->oa_buffer.format_size;
 	unsigned long flags;
-	unsigned int aged_idx;
-	u32 head, hw_tail, aged_tail, aging_tail;
+	bool pollin;
+	u32 hw_tail;
 	u64 now;
 
 	/* We have to consider the (unlikely) possibility that read() errors
-	 * could result in an OA buffer reset which might reset the head,
-	 * tails[] and aged_tail state.
+	 * could result in an OA buffer reset which might reset the head and
+	 * tail state.
 	 */
 	spin_lock_irqsave(&stream->oa_buffer.ptr_lock, flags);
 
-	/* NB: The head we observe here might effectively be a little out of
-	 * date (between head and tails[aged_idx].offset if there is currently
-	 * a read() in progress.
-	 */
-	head = stream->oa_buffer.head;
-
-	aged_idx = stream->oa_buffer.aged_tail_idx;
-	aged_tail = stream->oa_buffer.tails[aged_idx].offset;
-	aging_tail = stream->oa_buffer.tails[!aged_idx].offset;
-
 	hw_tail = stream->perf->ops.oa_hw_tail_read(stream);
 
 	/* The tail pointer increases in 64 byte increments,
@@ -507,64 +482,63 @@ static bool oa_buffer_check_unlocked(struct i915_perf_stream *stream)
 
 	now = ktime_get_mono_fast_ns();
 
-	/* Update the aged tail
-	 *
-	 * Flip the tail pointer available for read()s once the aging tail is
-	 * old enough to trust that the corresponding data will be visible to
-	 * the CPU...
-	 *
-	 * Do this before updating the aging pointer in case we may be able to
-	 * immediately start aging a new pointer too (if new data has become
-	 * available) without needing to wait for a later hrtimer callback.
-	 */
-	if (aging_tail != INVALID_TAIL_PTR &&
-	    ((now - stream->oa_buffer.aging_timestamp) >
-	     OA_TAIL_MARGIN_NSEC)) {
-
-		aged_idx ^= 1;
-		stream->oa_buffer.aged_tail_idx = aged_idx;
+	if (hw_tail == stream->oa_buffer.aging_tail &&
+	    (now - stream->oa_buffer.aging_timestamp) > OA_TAIL_MARGIN_NSEC) {
+		/* If the HW tail hasn't move since the last check and the HW
+		 * tail has been aging for long enough, declare it the new
+		 * tail.
+		 */
+		stream->oa_buffer.tail = stream->oa_buffer.aging_tail;
+	} else {
+		u32 head, tail, aged_tail;
 
-		aged_tail = aging_tail;
+		/* NB: The head we observe here might effectively be a little
+		 * out of date. If a read() is in progress, the head could be
+		 * anywhere between this head and stream->oa_buffer.tail.
+		 */
+		head = stream->oa_buffer.head - gtt_offset;
+		aged_tail = stream->oa_buffer.tail - gtt_offset;
+
+		hw_tail -= gtt_offset;
+		tail = hw_tail;
+
+		/* Walk the stream backward until we find a report with dword 0
+		 * & 1 not at 0. Since the circular buffer pointers progress by
+		 * increments of 64 bytes and that reports can be up to 256
+		 * bytes long, we can't tell whether a report has fully landed
+		 * in memory before the first 2 dwords of the following report
+		 * have effectively landed.
+		 *
+		 * This is assuming that the writes of the OA unit land in
+		 * memory in the order they were written to.
+		 * If not : (╯°□°）╯︵ ┻━┻
+		 */
+		while (OA_TAKEN(tail, aged_tail) >= report_size) {
+			u32 *report32 = (void *)(stream->oa_buffer.vaddr + tail);
 
-		/* Mark that we need a new pointer to start aging... */
-		stream->oa_buffer.tails[!aged_idx].offset = INVALID_TAIL_PTR;
-		aging_tail = INVALID_TAIL_PTR;
-	}
+			if (report32[0] != 0 || report32[1] != 0)
+				break;
 
-	/* Update the aging tail
-	 *
-	 * We throttle aging tail updates until we have a new tail that
-	 * represents >= one report more data than is already available for
-	 * reading. This ensures there will be enough data for a successful
-	 * read once this new pointer has aged and ensures we will give the new
-	 * pointer time to age.
-	 */
-	if (aging_tail == INVALID_TAIL_PTR &&
-	    (aged_tail == INVALID_TAIL_PTR ||
-	     OA_TAKEN(hw_tail, aged_tail) >= report_size)) {
-		struct i915_vma *vma = stream->oa_buffer.vma;
-		u32 gtt_offset = i915_ggtt_offset(vma);
-
-		/* Be paranoid and do a bounds check on the pointer read back
-		 * from hardware, just in case some spurious hardware condition
-		 * could put the tail out of bounds...
-		 */
-		if (hw_tail >= gtt_offset &&
-		    hw_tail < (gtt_offset + OA_BUFFER_SIZE)) {
-			stream->oa_buffer.tails[!aged_idx].offset =
-				aging_tail = hw_tail;
-			stream->oa_buffer.aging_timestamp = now;
-		} else {
-			drm_err(&stream->perf->i915->drm,
-				"Ignoring spurious out of range OA buffer tail pointer = %x\n",
-				hw_tail);
+			tail = (tail - report_size) & (OA_BUFFER_SIZE - 1);
 		}
+
+		if (OA_TAKEN(hw_tail, tail) > report_size &&
+		    __ratelimit(&stream->perf->tail_pointer_race))
+			DRM_NOTE("unlanded report(s) head=0x%x "
+				 "tail=0x%x hw_tail=0x%x\n",
+				 head, tail, hw_tail);
+
+		stream->oa_buffer.tail = gtt_offset + tail;
+		stream->oa_buffer.aging_tail = gtt_offset + hw_tail;
+		stream->oa_buffer.aging_timestamp = now;
 	}
 
+	pollin = OA_TAKEN(stream->oa_buffer.tail - gtt_offset,
+			  stream->oa_buffer.head - gtt_offset) >= report_size;
+
 	spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags);
 
-	return aged_tail == INVALID_TAIL_PTR ?
-		false : OA_TAKEN(aged_tail, head) >= report_size;
+	return pollin;
 }
 
 /**
@@ -682,7 +656,6 @@ static int gen8_append_oa_reports(struct i915_perf_stream *stream,
 	u32 mask = (OA_BUFFER_SIZE - 1);
 	size_t start_offset = *offset;
 	unsigned long flags;
-	unsigned int aged_tail_idx;
 	u32 head, tail;
 	u32 taken;
 	int ret = 0;
@@ -693,18 +666,10 @@ static int gen8_append_oa_reports(struct i915_perf_stream *stream,
 	spin_lock_irqsave(&stream->oa_buffer.ptr_lock, flags);
 
 	head = stream->oa_buffer.head;
-	aged_tail_idx = stream->oa_buffer.aged_tail_idx;
-	tail = stream->oa_buffer.tails[aged_tail_idx].offset;
+	tail = stream->oa_buffer.tail;
 
 	spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags);
 
-	/*
-	 * An invalid tail pointer here means we're still waiting for the poll
-	 * hrtimer callback to give us a pointer
-	 */
-	if (tail == INVALID_TAIL_PTR)
-		return -EAGAIN;
-
 	/*
 	 * NB: oa_buffer.head/tail include the gtt_offset which we don't want
 	 * while indexing relative to oa_buf_base.
@@ -838,13 +803,11 @@ static int gen8_append_oa_reports(struct i915_perf_stream *stream,
 		}
 
 		/*
-		 * The above reason field sanity check is based on
-		 * the assumption that the OA buffer is initially
-		 * zeroed and we reset the field after copying so the
-		 * check is still meaningful once old reports start
-		 * being overwritten.
+		 * Clear out the first 2 dword as a mean to detect unlanded
+		 * reports.
 		 */
 		report32[0] = 0;
+		report32[1] = 0;
 	}
 
 	if (start_offset != *offset) {
@@ -985,7 +948,6 @@ static int gen7_append_oa_reports(struct i915_perf_stream *stream,
 	u32 mask = (OA_BUFFER_SIZE - 1);
 	size_t start_offset = *offset;
 	unsigned long flags;
-	unsigned int aged_tail_idx;
 	u32 head, tail;
 	u32 taken;
 	int ret = 0;
@@ -996,17 +958,10 @@ static int gen7_append_oa_reports(struct i915_perf_stream *stream,
 	spin_lock_irqsave(&stream->oa_buffer.ptr_lock, flags);
 
 	head = stream->oa_buffer.head;
-	aged_tail_idx = stream->oa_buffer.aged_tail_idx;
-	tail = stream->oa_buffer.tails[aged_tail_idx].offset;
+	tail = stream->oa_buffer.tail;
 
 	spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags);
 
-	/* An invalid tail pointer here means we're still waiting for the poll
-	 * hrtimer callback to give us a pointer
-	 */
-	if (tail == INVALID_TAIL_PTR)
-		return -EAGAIN;
-
 	/* NB: oa_buffer.head/tail include the gtt_offset which we don't want
 	 * while indexing relative to oa_buf_base.
 	 */
@@ -1064,13 +1019,11 @@ static int gen7_append_oa_reports(struct i915_perf_stream *stream,
 		if (ret)
 			break;
 
-		/* The above report-id field sanity check is based on
-		 * the assumption that the OA buffer is initially
-		 * zeroed and we reset the field after copying so the
-		 * check is still meaningful once old reports start
-		 * being overwritten.
+		/* Clear out the first 2 dwords as a mean to detect unlanded
+		 * reports.
 		 */
 		report32[0] = 0;
+		report32[1] = 0;
 	}
 
 	if (start_offset != *offset) {
@@ -1449,8 +1402,8 @@ static void gen7_init_oa_buffer(struct i915_perf_stream *stream)
 			   gtt_offset | OABUFFER_SIZE_16M);
 
 	/* Mark that we need updated tail pointers to read from... */
-	stream->oa_buffer.tails[0].offset = INVALID_TAIL_PTR;
-	stream->oa_buffer.tails[1].offset = INVALID_TAIL_PTR;
+	stream->oa_buffer.aging_tail = INVALID_TAIL_PTR;
+	stream->oa_buffer.tail = gtt_offset;
 
 	spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags);
 
@@ -1472,8 +1425,6 @@ static void gen7_init_oa_buffer(struct i915_perf_stream *stream)
 	 * memory...
 	 */
 	memset(stream->oa_buffer.vaddr, 0, OA_BUFFER_SIZE);
-
-	stream->pollin = false;
 }
 
 static void gen8_init_oa_buffer(struct i915_perf_stream *stream)
@@ -1503,8 +1454,8 @@ static void gen8_init_oa_buffer(struct i915_perf_stream *stream)
 	intel_uncore_write(uncore, GEN8_OATAILPTR, gtt_offset & GEN8_OATAILPTR_MASK);
 
 	/* Mark that we need updated tail pointers to read from... */
-	stream->oa_buffer.tails[0].offset = INVALID_TAIL_PTR;
-	stream->oa_buffer.tails[1].offset = INVALID_TAIL_PTR;
+	stream->oa_buffer.aging_tail = INVALID_TAIL_PTR;
+	stream->oa_buffer.tail = gtt_offset;
 
 	/*
 	 * Reset state used to recognise context switches, affecting which
@@ -1528,8 +1479,6 @@ static void gen8_init_oa_buffer(struct i915_perf_stream *stream)
 	 * memory...
 	 */
 	memset(stream->oa_buffer.vaddr, 0, OA_BUFFER_SIZE);
-
-	stream->pollin = false;
 }
 
 static void gen12_init_oa_buffer(struct i915_perf_stream *stream)
@@ -1559,8 +1508,8 @@ static void gen12_init_oa_buffer(struct i915_perf_stream *stream)
 			   gtt_offset & GEN12_OAG_OATAILPTR_MASK);
 
 	/* Mark that we need updated tail pointers to read from... */
-	stream->oa_buffer.tails[0].offset = INVALID_TAIL_PTR;
-	stream->oa_buffer.tails[1].offset = INVALID_TAIL_PTR;
+	stream->oa_buffer.aging_tail = INVALID_TAIL_PTR;
+	stream->oa_buffer.tail = gtt_offset;
 
 	/*
 	 * Reset state used to recognise context switches, affecting which
@@ -1585,8 +1534,6 @@ static void gen12_init_oa_buffer(struct i915_perf_stream *stream)
 	 */
 	memset(stream->oa_buffer.vaddr, 0,
 	       stream->oa_buffer.vma->size);
-
-	stream->pollin = false;
 }
 
 static int alloc_oa_buffer(struct i915_perf_stream *stream)
@@ -1972,10 +1919,11 @@ get_oa_vma(struct i915_perf_stream *stream, struct i915_oa_config *oa_config)
 	return i915_vma_get(oa_bo->vma);
 }
 
-static struct i915_request *
+static int
 emit_oa_config(struct i915_perf_stream *stream,
 	       struct i915_oa_config *oa_config,
-	       struct intel_context *ce)
+	       struct intel_context *ce,
+	       struct i915_active *active)
 {
 	struct i915_request *rq;
 	struct i915_vma *vma;
@@ -1983,7 +1931,7 @@ emit_oa_config(struct i915_perf_stream *stream,
 
 	vma = get_oa_vma(stream, oa_config);
 	if (IS_ERR(vma))
-		return ERR_CAST(vma);
+		return PTR_ERR(vma);
 
 	err = i915_vma_pin(vma, 0, 0, PIN_GLOBAL | PIN_HIGH);
 	if (err)
@@ -1997,6 +1945,18 @@ emit_oa_config(struct i915_perf_stream *stream,
 		goto err_vma_unpin;
 	}
 
+	if (!IS_ERR_OR_NULL(active)) {
+		/* After all individual context modifications */
+		err = i915_request_await_active(rq, active,
+						I915_ACTIVE_AWAIT_ACTIVE);
+		if (err)
+			goto err_add_request;
+
+		err = i915_active_add_request(active, rq);
+		if (err)
+			goto err_add_request;
+	}
+
 	i915_vma_lock(vma);
 	err = i915_request_await_object(rq, vma->obj, 0);
 	if (!err)
@@ -2011,14 +1971,13 @@ emit_oa_config(struct i915_perf_stream *stream,
 	if (err)
 		goto err_add_request;
 
-	i915_request_get(rq);
 err_add_request:
 	i915_request_add(rq);
 err_vma_unpin:
 	i915_vma_unpin(vma);
 err_vma_put:
 	i915_vma_put(vma);
-	return err ? ERR_PTR(err) : rq;
+	return err;
 }
 
 static struct intel_context *oa_context(struct i915_perf_stream *stream)
@@ -2026,8 +1985,9 @@ static struct intel_context *oa_context(struct i915_perf_stream *stream)
 	return stream->pinned_ctx ?: stream->engine->kernel_context;
 }
 
-static struct i915_request *
-hsw_enable_metric_set(struct i915_perf_stream *stream)
+static int
+hsw_enable_metric_set(struct i915_perf_stream *stream,
+		      struct i915_active *active)
 {
 	struct intel_uncore *uncore = stream->uncore;
 
@@ -2046,7 +2006,9 @@ hsw_enable_metric_set(struct i915_perf_stream *stream)
 	intel_uncore_rmw(uncore, GEN6_UCGCTL1,
 			 0, GEN6_CSUNIT_CLOCK_GATE_DISABLE);
 
-	return emit_oa_config(stream, stream->oa_config, oa_context(stream));
+	return emit_oa_config(stream,
+			      stream->oa_config, oa_context(stream),
+			      active);
 }
 
 static void hsw_disable_metric_set(struct i915_perf_stream *stream)
@@ -2116,9 +2078,6 @@ gen8_update_reg_state_unlocked(const struct intel_context *ce,
 	for (i = 0; i < ARRAY_SIZE(flex_regs); i++)
 		reg_state[ctx_flexeu0 + i * 2 + 1] =
 			oa_config_flex_reg(stream->oa_config, flex_regs[i]);
-
-	reg_state[CTX_R_PWR_CLK_STATE] =
-		intel_sseu_make_rpcs(ce->engine->i915, &ce->sseu);
 }
 
 struct flex {
@@ -2196,8 +2155,10 @@ static int gen8_modify_context(struct intel_context *ce,
 	return err;
 }
 
-static int gen8_modify_self(struct intel_context *ce,
-			    const struct flex *flex, unsigned int count)
+static int
+gen8_modify_self(struct intel_context *ce,
+		 const struct flex *flex, unsigned int count,
+		 struct i915_active *active)
 {
 	struct i915_request *rq;
 	int err;
@@ -2208,8 +2169,17 @@ static int gen8_modify_self(struct intel_context *ce,
 	if (IS_ERR(rq))
 		return PTR_ERR(rq);
 
+	if (!IS_ERR_OR_NULL(active)) {
+		err = i915_active_add_request(active, rq);
+		if (err)
+			goto err_add_request;
+	}
+
 	err = gen8_load_flex(rq, ce, flex, count);
+	if (err)
+		goto err_add_request;
 
+err_add_request:
 	i915_request_add(rq);
 	return err;
 }
@@ -2243,7 +2213,8 @@ static int gen8_configure_context(struct i915_gem_context *ctx,
 	return err;
 }
 
-static int gen12_configure_oar_context(struct i915_perf_stream *stream, bool enable)
+static int gen12_configure_oar_context(struct i915_perf_stream *stream,
+				       struct i915_active *active)
 {
 	int err;
 	struct intel_context *ce = stream->pinned_ctx;
@@ -2252,7 +2223,7 @@ static int gen12_configure_oar_context(struct i915_perf_stream *stream, bool ena
 		{
 			GEN8_OACTXCONTROL,
 			stream->perf->ctx_oactxctrl_offset + 1,
-			enable ? GEN8_OA_COUNTER_RESUME : 0,
+			active ? GEN8_OA_COUNTER_RESUME : 0,
 		},
 	};
 	/* Offsets in regs_lri are not used since this configuration is only
@@ -2264,13 +2235,13 @@ static int gen12_configure_oar_context(struct i915_perf_stream *stream, bool ena
 			GEN12_OAR_OACONTROL,
 			GEN12_OAR_OACONTROL_OFFSET + 1,
 			(format << GEN12_OAR_OACONTROL_COUNTER_FORMAT_SHIFT) |
-			(enable ? GEN12_OAR_OACONTROL_COUNTER_ENABLE : 0)
+			(active ? GEN12_OAR_OACONTROL_COUNTER_ENABLE : 0)
 		},
 		{
 			RING_CONTEXT_CONTROL(ce->engine->mmio_base),
 			CTX_CONTEXT_CONTROL,
 			_MASKED_FIELD(GEN12_CTX_CTRL_OAR_CONTEXT_ENABLE,
-				      enable ?
+				      active ?
 				      GEN12_CTX_CTRL_OAR_CONTEXT_ENABLE :
 				      0)
 		},
@@ -2287,7 +2258,7 @@ static int gen12_configure_oar_context(struct i915_perf_stream *stream, bool ena
 		return err;
 
 	/* Apply regs_lri using LRI with pinned context */
-	return gen8_modify_self(ce, regs_lri, ARRAY_SIZE(regs_lri));
+	return gen8_modify_self(ce, regs_lri, ARRAY_SIZE(regs_lri), active);
 }
 
 /*
@@ -2315,9 +2286,11 @@ static int gen12_configure_oar_context(struct i915_perf_stream *stream, bool ena
  * Note: it's only the RCS/Render context that has any OA state.
  * Note: the first flex register passed must always be R_PWR_CLK_STATE
  */
-static int oa_configure_all_contexts(struct i915_perf_stream *stream,
-				     struct flex *regs,
-				     size_t num_regs)
+static int
+oa_configure_all_contexts(struct i915_perf_stream *stream,
+			  struct flex *regs,
+			  size_t num_regs,
+			  struct i915_active *active)
 {
 	struct drm_i915_private *i915 = stream->perf->i915;
 	struct intel_engine_cs *engine;
@@ -2374,7 +2347,7 @@ static int oa_configure_all_contexts(struct i915_perf_stream *stream,
 
 		regs[0].value = intel_sseu_make_rpcs(i915, &ce->sseu);
 
-		err = gen8_modify_self(ce, regs, num_regs);
+		err = gen8_modify_self(ce, regs, num_regs, active);
 		if (err)
 			return err;
 	}
@@ -2382,8 +2355,10 @@ static int oa_configure_all_contexts(struct i915_perf_stream *stream,
 	return 0;
 }
 
-static int gen12_configure_all_contexts(struct i915_perf_stream *stream,
-					const struct i915_oa_config *oa_config)
+static int
+gen12_configure_all_contexts(struct i915_perf_stream *stream,
+			     const struct i915_oa_config *oa_config,
+			     struct i915_active *active)
 {
 	struct flex regs[] = {
 		{
@@ -2392,11 +2367,15 @@ static int gen12_configure_all_contexts(struct i915_perf_stream *stream,
 		},
 	};
 
-	return oa_configure_all_contexts(stream, regs, ARRAY_SIZE(regs));
+	return oa_configure_all_contexts(stream,
+					 regs, ARRAY_SIZE(regs),
+					 active);
 }
 
-static int lrc_configure_all_contexts(struct i915_perf_stream *stream,
-				      const struct i915_oa_config *oa_config)
+static int
+lrc_configure_all_contexts(struct i915_perf_stream *stream,
+			   const struct i915_oa_config *oa_config,
+			   struct i915_active *active)
 {
 	/* The MMIO offsets for Flex EU registers aren't contiguous */
 	const u32 ctx_flexeu0 = stream->perf->ctx_flexeu0_offset;
@@ -2429,11 +2408,14 @@ static int lrc_configure_all_contexts(struct i915_perf_stream *stream,
 	for (i = 2; i < ARRAY_SIZE(regs); i++)
 		regs[i].value = oa_config_flex_reg(oa_config, regs[i].reg);
 
-	return oa_configure_all_contexts(stream, regs, ARRAY_SIZE(regs));
+	return oa_configure_all_contexts(stream,
+					 regs, ARRAY_SIZE(regs),
+					 active);
 }
 
-static struct i915_request *
-gen8_enable_metric_set(struct i915_perf_stream *stream)
+static int
+gen8_enable_metric_set(struct i915_perf_stream *stream,
+		       struct i915_active *active)
 {
 	struct intel_uncore *uncore = stream->uncore;
 	struct i915_oa_config *oa_config = stream->oa_config;
@@ -2473,11 +2455,13 @@ gen8_enable_metric_set(struct i915_perf_stream *stream)
 	 * to make sure all slices/subslices are ON before writing to NOA
 	 * registers.
 	 */
-	ret = lrc_configure_all_contexts(stream, oa_config);
+	ret = lrc_configure_all_contexts(stream, oa_config, active);
 	if (ret)
-		return ERR_PTR(ret);
+		return ret;
 
-	return emit_oa_config(stream, oa_config, oa_context(stream));
+	return emit_oa_config(stream,
+			      stream->oa_config, oa_context(stream),
+			      active);
 }
 
 static u32 oag_report_ctx_switches(const struct i915_perf_stream *stream)
@@ -2487,8 +2471,9 @@ static u32 oag_report_ctx_switches(const struct i915_perf_stream *stream)
 			     0 : GEN12_OAG_OA_DEBUG_DISABLE_CTX_SWITCH_REPORTS);
 }
 
-static struct i915_request *
-gen12_enable_metric_set(struct i915_perf_stream *stream)
+static int
+gen12_enable_metric_set(struct i915_perf_stream *stream,
+			struct i915_active *active)
 {
 	struct intel_uncore *uncore = stream->uncore;
 	struct i915_oa_config *oa_config = stream->oa_config;
@@ -2517,9 +2502,9 @@ gen12_enable_metric_set(struct i915_perf_stream *stream)
 	 * to make sure all slices/subslices are ON before writing to NOA
 	 * registers.
 	 */
-	ret = gen12_configure_all_contexts(stream, oa_config);
+	ret = gen12_configure_all_contexts(stream, oa_config, active);
 	if (ret)
-		return ERR_PTR(ret);
+		return ret;
 
 	/*
 	 * For Gen12, performance counters are context
@@ -2527,12 +2512,14 @@ gen12_enable_metric_set(struct i915_perf_stream *stream)
 	 * requested this.
 	 */
 	if (stream->ctx) {
-		ret = gen12_configure_oar_context(stream, true);
+		ret = gen12_configure_oar_context(stream, active);
 		if (ret)
-			return ERR_PTR(ret);
+			return ret;
 	}
 
-	return emit_oa_config(stream, oa_config, oa_context(stream));
+	return emit_oa_config(stream,
+			      stream->oa_config, oa_context(stream),
+			      active);
 }
 
 static void gen8_disable_metric_set(struct i915_perf_stream *stream)
@@ -2540,7 +2527,7 @@ static void gen8_disable_metric_set(struct i915_perf_stream *stream)
 	struct intel_uncore *uncore = stream->uncore;
 
 	/* Reset all contexts' slices/subslices configurations. */
-	lrc_configure_all_contexts(stream, NULL);
+	lrc_configure_all_contexts(stream, NULL, NULL);
 
 	intel_uncore_rmw(uncore, GDT_CHICKEN_BITS, GT_NOA_ENABLE, 0);
 }
@@ -2550,7 +2537,7 @@ static void gen10_disable_metric_set(struct i915_perf_stream *stream)
 	struct intel_uncore *uncore = stream->uncore;
 
 	/* Reset all contexts' slices/subslices configurations. */
-	lrc_configure_all_contexts(stream, NULL);
+	lrc_configure_all_contexts(stream, NULL, NULL);
 
 	/* Make sure we disable noa to save power. */
 	intel_uncore_rmw(uncore, RPM_CONFIG1, GEN10_GT_NOA_ENABLE, 0);
@@ -2561,11 +2548,11 @@ static void gen12_disable_metric_set(struct i915_perf_stream *stream)
 	struct intel_uncore *uncore = stream->uncore;
 
 	/* Reset all contexts' slices/subslices configurations. */
-	gen12_configure_all_contexts(stream, NULL);
+	gen12_configure_all_contexts(stream, NULL, NULL);
 
 	/* disable the context save/restore or OAR counters */
 	if (stream->ctx)
-		gen12_configure_oar_context(stream, false);
+		gen12_configure_oar_context(stream, NULL);
 
 	/* Make sure we disable noa to save power. */
 	intel_uncore_rmw(uncore, RPM_CONFIG1, GEN10_GT_NOA_ENABLE, 0);
@@ -2657,11 +2644,13 @@ static void gen12_oa_enable(struct i915_perf_stream *stream)
  */
 static void i915_oa_stream_enable(struct i915_perf_stream *stream)
 {
+	stream->pollin = false;
+
 	stream->perf->ops.oa_enable(stream);
 
 	if (stream->periodic)
 		hrtimer_start(&stream->poll_check_timer,
-			      ns_to_ktime(POLL_PERIOD),
+			      ns_to_ktime(stream->poll_oa_period),
 			      HRTIMER_MODE_REL_PINNED);
 }
 
@@ -2737,16 +2726,52 @@ static const struct i915_perf_stream_ops i915_oa_stream_ops = {
 
 static int i915_perf_stream_enable_sync(struct i915_perf_stream *stream)
 {
-	struct i915_request *rq;
+	struct i915_active *active;
+	int err;
 
-	rq = stream->perf->ops.enable_metric_set(stream);
-	if (IS_ERR(rq))
-		return PTR_ERR(rq);
+	active = i915_active_create();
+	if (!active)
+		return -ENOMEM;
 
-	i915_request_wait(rq, 0, MAX_SCHEDULE_TIMEOUT);
-	i915_request_put(rq);
+	err = stream->perf->ops.enable_metric_set(stream, active);
+	if (err == 0)
+		__i915_active_wait(active, TASK_UNINTERRUPTIBLE);
 
-	return 0;
+	i915_active_put(active);
+	return err;
+}
+
+static void
+get_default_sseu_config(struct intel_sseu *out_sseu,
+			struct intel_engine_cs *engine)
+{
+	const struct sseu_dev_info *devinfo_sseu =
+		&RUNTIME_INFO(engine->i915)->sseu;
+
+	*out_sseu = intel_sseu_from_device_info(devinfo_sseu);
+
+	if (IS_GEN(engine->i915, 11)) {
+		/*
+		 * We only need subslice count so it doesn't matter which ones
+		 * we select - just turn off low bits in the amount of half of
+		 * all available subslices per slice.
+		 */
+		out_sseu->subslice_mask =
+			~(~0 << (hweight8(out_sseu->subslice_mask) / 2));
+		out_sseu->slice_mask = 0x1;
+	}
+}
+
+static int
+get_sseu_config(struct intel_sseu *out_sseu,
+		struct intel_engine_cs *engine,
+		const struct drm_i915_gem_context_param_sseu *drm_sseu)
+{
+	if (drm_sseu->engine.engine_class != engine->uabi_class ||
+	    drm_sseu->engine.engine_instance != engine->uabi_instance)
+		return -EINVAL;
+
+	return i915_gem_user_to_context_sseu(engine->i915, drm_sseu, out_sseu);
 }
 
 /**
@@ -2881,6 +2906,8 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
 		goto err_oa_buf_alloc;
 
 	stream->ops = &i915_oa_stream_ops;
+
+	perf->sseu = props->sseu;
 	WRITE_ONCE(perf->exclusive_stream, stream);
 
 	ret = i915_perf_stream_enable_sync(stream);
@@ -2932,57 +2959,10 @@ void i915_oa_init_reg_state(const struct intel_context *ce,
 
 	/* perf.exclusive_stream serialised by lrc_configure_all_contexts() */
 	stream = READ_ONCE(engine->i915->perf.exclusive_stream);
-	/*
-	 * For gen12, only CTX_R_PWR_CLK_STATE needs update, but the caller
-	 * is already doing that, so nothing to be done for gen12 here.
-	 */
 	if (stream && INTEL_GEN(stream->perf->i915) < 12)
 		gen8_update_reg_state_unlocked(ce, stream);
 }
 
-/**
- * i915_perf_read_locked - &i915_perf_stream_ops->read with error normalisation
- * @stream: An i915 perf stream
- * @file: An i915 perf stream file
- * @buf: destination buffer given by userspace
- * @count: the number of bytes userspace wants to read
- * @ppos: (inout) file seek position (unused)
- *
- * Besides wrapping &i915_perf_stream_ops->read this provides a common place to
- * ensure that if we've successfully copied any data then reporting that takes
- * precedence over any internal error status, so the data isn't lost.
- *
- * For example ret will be -ENOSPC whenever there is more buffered data than
- * can be copied to userspace, but that's only interesting if we weren't able
- * to copy some data because it implies the userspace buffer is too small to
- * receive a single record (and we never split records).
- *
- * Another case with ret == -EFAULT is more of a grey area since it would seem
- * like bad form for userspace to ask us to overrun its buffer, but the user
- * knows best:
- *
- *   http://yarchive.net/comp/linux/partial_reads_writes.html
- *
- * Returns: The number of bytes copied or a negative error code on failure.
- */
-static ssize_t i915_perf_read_locked(struct i915_perf_stream *stream,
-				     struct file *file,
-				     char __user *buf,
-				     size_t count,
-				     loff_t *ppos)
-{
-	/* Note we keep the offset (aka bytes read) separate from any
-	 * error status so that the final check for whether we return
-	 * the bytes read with a higher precedence than any error (see
-	 * comment below) doesn't need to be handled/duplicated in
-	 * stream->ops->read() implementations.
-	 */
-	size_t offset = 0;
-	int ret = stream->ops->read(stream, buf, count, &offset);
-
-	return offset ?: (ret ?: -EAGAIN);
-}
-
 /**
  * i915_perf_read - handles read() FOP for i915 perf stream FDs
  * @file: An i915 perf stream file
@@ -3008,7 +2988,8 @@ static ssize_t i915_perf_read(struct file *file,
 {
 	struct i915_perf_stream *stream = file->private_data;
 	struct i915_perf *perf = stream->perf;
-	ssize_t ret;
+	size_t offset = 0;
+	int ret;
 
 	/* To ensure it's handled consistently we simply treat all reads of a
 	 * disabled stream as an error. In particular it might otherwise lead
@@ -3031,13 +3012,12 @@ static ssize_t i915_perf_read(struct file *file,
 				return ret;
 
 			mutex_lock(&perf->lock);
-			ret = i915_perf_read_locked(stream, file,
-						    buf, count, ppos);
+			ret = stream->ops->read(stream, buf, count, &offset);
 			mutex_unlock(&perf->lock);
-		} while (ret == -EAGAIN);
+		} while (!offset && !ret);
 	} else {
 		mutex_lock(&perf->lock);
-		ret = i915_perf_read_locked(stream, file, buf, count, ppos);
+		ret = stream->ops->read(stream, buf, count, &offset);
 		mutex_unlock(&perf->lock);
 	}
 
@@ -3048,15 +3028,15 @@ static ssize_t i915_perf_read(struct file *file,
 	 * and read() returning -EAGAIN. Clearing the oa.pollin state here
 	 * effectively ensures we back off until the next hrtimer callback
 	 * before reporting another EPOLLIN event.
+	 * The exception to this is if ops->read() returned -ENOSPC which means
+	 * that more OA data is available than could fit in the user provided
+	 * buffer. In this case we want the next poll() call to not block.
 	 */
-	if (ret >= 0 || ret == -EAGAIN) {
-		/* Maybe make ->pollin per-stream state if we support multiple
-		 * concurrent streams in the future.
-		 */
+	if (ret != -ENOSPC)
 		stream->pollin = false;
-	}
 
-	return ret;
+	/* Possible values for ret are 0, -EFAULT, -ENOSPC, -EIO, ... */
+	return offset ?: (ret ?: -EAGAIN);
 }
 
 static enum hrtimer_restart oa_poll_check_timer_cb(struct hrtimer *hrtimer)
@@ -3069,7 +3049,8 @@ static enum hrtimer_restart oa_poll_check_timer_cb(struct hrtimer *hrtimer)
 		wake_up(&stream->poll_wq);
 	}
 
-	hrtimer_forward_now(hrtimer, ns_to_ktime(POLL_PERIOD));
+	hrtimer_forward_now(hrtimer,
+			    ns_to_ktime(stream->poll_oa_period));
 
 	return HRTIMER_RESTART;
 }
@@ -3200,7 +3181,7 @@ static long i915_perf_config_locked(struct i915_perf_stream *stream,
 		return -EINVAL;
 
 	if (config != stream->oa_config) {
-		struct i915_request *rq;
+		int err;
 
 		/*
 		 * If OA is bound to a specific context, emit the
@@ -3211,13 +3192,11 @@ static long i915_perf_config_locked(struct i915_perf_stream *stream,
 		 * When set globally, we use a low priority kernel context,
 		 * so it will effectively take effect when idle.
 		 */
-		rq = emit_oa_config(stream, config, oa_context(stream));
-		if (!IS_ERR(rq)) {
+		err = emit_oa_config(stream, config, oa_context(stream), NULL);
+		if (!err)
 			config = xchg(&stream->oa_config, config);
-			i915_request_put(rq);
-		} else {
-			ret = PTR_ERR(rq);
-		}
+		else
+			ret = err;
 	}
 
 	i915_oa_config_put(config);
@@ -3430,6 +3409,14 @@ i915_perf_open_ioctl_locked(struct i915_perf *perf,
 		privileged_op = true;
 	}
 
+	/*
+	 * Asking for SSEU configuration is a priviliged operation.
+	 */
+	if (props->has_sseu)
+		privileged_op = true;
+	else
+		get_default_sseu_config(&props->sseu, props->engine);
+
 	/* Similar to perf's kernel.perf_paranoid_cpu sysctl option
 	 * we check a dev.i915.perf_stream_paranoid sysctl option
 	 * to determine if it's ok to access system wide OA counters
@@ -3450,6 +3437,7 @@ i915_perf_open_ioctl_locked(struct i915_perf *perf,
 
 	stream->perf = perf;
 	stream->ctx = specific_ctx;
+	stream->poll_oa_period = props->poll_oa_period;
 
 	ret = i915_oa_stream_init(stream, param, props);
 	if (ret)
@@ -3525,8 +3513,10 @@ static int read_properties_unlocked(struct i915_perf *perf,
 {
 	u64 __user *uprop = uprops;
 	u32 i;
+	int ret;
 
 	memset(props, 0, sizeof(struct perf_open_properties));
+	props->poll_oa_period = DEFAULT_POLL_PERIOD_NS;
 
 	if (!n_props) {
 		DRM_DEBUG("No i915 perf properties given\n");
@@ -3556,7 +3546,6 @@ static int read_properties_unlocked(struct i915_perf *perf,
 	for (i = 0; i < n_props; i++) {
 		u64 oa_period, oa_freq_hz;
 		u64 id, value;
-		int ret;
 
 		ret = get_user(id, uprop);
 		if (ret)
@@ -3642,6 +3631,32 @@ static int read_properties_unlocked(struct i915_perf *perf,
 		case DRM_I915_PERF_PROP_HOLD_PREEMPTION:
 			props->hold_preemption = !!value;
 			break;
+		case DRM_I915_PERF_PROP_GLOBAL_SSEU: {
+			struct drm_i915_gem_context_param_sseu user_sseu;
+
+			if (copy_from_user(&user_sseu,
+					   u64_to_user_ptr(value),
+					   sizeof(user_sseu))) {
+				DRM_DEBUG("Unable to copy global sseu parameter\n");
+				return -EFAULT;
+			}
+
+			ret = get_sseu_config(&props->sseu, props->engine, &user_sseu);
+			if (ret) {
+				DRM_DEBUG("Invalid SSEU configuration\n");
+				return ret;
+			}
+			props->has_sseu = true;
+			break;
+		}
+		case DRM_I915_PERF_PROP_POLL_OA_PERIOD:
+			if (value < 100000 /* 100us */) {
+				DRM_DEBUG("OA availability timer too small (%lluns < 100us)\n",
+					  value);
+				return -EINVAL;
+			}
+			props->poll_oa_period = value;
+			break;
 		case DRM_I915_PERF_PROP_MAX:
 			MISSING_CASE(id);
 			return -EINVAL;
@@ -3724,7 +3739,6 @@ int i915_perf_open_ioctl(struct drm_device *dev, void *data,
 void i915_perf_register(struct drm_i915_private *i915)
 {
 	struct i915_perf *perf = &i915->perf;
-	int ret;
 
 	if (!perf->i915)
 		return;
@@ -3738,64 +3752,7 @@ void i915_perf_register(struct drm_i915_private *i915)
 	perf->metrics_kobj =
 		kobject_create_and_add("metrics",
 				       &i915->drm.primary->kdev->kobj);
-	if (!perf->metrics_kobj)
-		goto exit;
-
-	sysfs_attr_init(&perf->test_config.sysfs_metric_id.attr);
-
-	if (IS_TIGERLAKE(i915)) {
-		i915_perf_load_test_config_tgl(i915);
-	} else if (INTEL_GEN(i915) >= 11) {
-		i915_perf_load_test_config_icl(i915);
-	} else if (IS_CANNONLAKE(i915)) {
-		i915_perf_load_test_config_cnl(i915);
-	} else if (IS_COFFEELAKE(i915)) {
-		if (IS_CFL_GT2(i915))
-			i915_perf_load_test_config_cflgt2(i915);
-		if (IS_CFL_GT3(i915))
-			i915_perf_load_test_config_cflgt3(i915);
-	} else if (IS_GEMINILAKE(i915)) {
-		i915_perf_load_test_config_glk(i915);
-	} else if (IS_KABYLAKE(i915)) {
-		if (IS_KBL_GT2(i915))
-			i915_perf_load_test_config_kblgt2(i915);
-		else if (IS_KBL_GT3(i915))
-			i915_perf_load_test_config_kblgt3(i915);
-	} else if (IS_BROXTON(i915)) {
-		i915_perf_load_test_config_bxt(i915);
-	} else if (IS_SKYLAKE(i915)) {
-		if (IS_SKL_GT2(i915))
-			i915_perf_load_test_config_sklgt2(i915);
-		else if (IS_SKL_GT3(i915))
-			i915_perf_load_test_config_sklgt3(i915);
-		else if (IS_SKL_GT4(i915))
-			i915_perf_load_test_config_sklgt4(i915);
-	} else if (IS_CHERRYVIEW(i915)) {
-		i915_perf_load_test_config_chv(i915);
-	} else if (IS_BROADWELL(i915)) {
-		i915_perf_load_test_config_bdw(i915);
-	} else if (IS_HASWELL(i915)) {
-		i915_perf_load_test_config_hsw(i915);
-	}
-
-	if (perf->test_config.id == 0)
-		goto sysfs_error;
-
-	ret = sysfs_create_group(perf->metrics_kobj,
-				 &perf->test_config.sysfs_metric);
-	if (ret)
-		goto sysfs_error;
-
-	perf->test_config.perf = perf;
-	kref_init(&perf->test_config.ref);
 
-	goto exit;
-
-sysfs_error:
-	kobject_put(perf->metrics_kobj);
-	perf->metrics_kobj = NULL;
-
-exit:
 	mutex_unlock(&perf->lock);
 }
 
@@ -3815,9 +3772,6 @@ void i915_perf_unregister(struct drm_i915_private *i915)
 	if (!perf->metrics_kobj)
 		return;
 
-	sysfs_remove_group(perf->metrics_kobj,
-			   &perf->test_config.sysfs_metric);
-
 	kobject_put(perf->metrics_kobj);
 	perf->metrics_kobj = NULL;
 }
@@ -4416,6 +4370,11 @@ void i915_perf_init(struct drm_i915_private *i915)
 		ratelimit_set_flags(&perf->spurious_report_rs,
 				    RATELIMIT_MSG_ON_RELEASE);
 
+		ratelimit_state_init(&perf->tail_pointer_race,
+				     5 * HZ, 10);
+		ratelimit_set_flags(&perf->tail_pointer_race,
+				    RATELIMIT_MSG_ON_RELEASE);
+
 		atomic64_set(&perf->noa_programming_delay,
 			     500 * 1000 /* 500us */);
 
@@ -4476,8 +4435,15 @@ int i915_perf_ioctl_version(void)
 	 *    preemption on a particular context so that performance data is
 	 *    accessible from a delta of MI_RPC reports without looking at the
 	 *    OA buffer.
+	 *
+	 * 4: Add DRM_I915_PERF_PROP_ALLOWED_SSEU to limit what contexts can
+	 *    be run for the duration of the performance recording based on
+	 *    their SSEU configuration.
+	 *
+	 * 5: Add DRM_I915_PERF_PROP_POLL_OA_PERIOD parameter that controls the
+	 *    interval for the hrtimer used to check for OA data.
 	 */
-	return 3;
+	return 5;
 }
 
 #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
diff --git a/drivers/gpu/drm/i915/i915_perf_types.h b/drivers/gpu/drm/i915/i915_perf_types.h
index a0e22f00f6cf..a36a455ae336 100644
--- a/drivers/gpu/drm/i915/i915_perf_types.h
+++ b/drivers/gpu/drm/i915/i915_perf_types.h
@@ -16,11 +16,13 @@
 #include <linux/uuid.h>
 #include <linux/wait.h>
 
+#include "gt/intel_sseu.h"
 #include "i915_reg.h"
 #include "intel_wakeref.h"
 
 struct drm_i915_private;
 struct file;
+struct i915_active;
 struct i915_gem_context;
 struct i915_perf;
 struct i915_vma;
@@ -272,21 +274,10 @@ struct i915_perf_stream {
 		spinlock_t ptr_lock;
 
 		/**
-		 * @tails: One 'aging' tail pointer and one 'aged' tail pointer ready to
-		 * used for reading.
-		 *
-		 * Initial values of 0xffffffff are invalid and imply that an
-		 * update is required (and should be ignored by an attempted
-		 * read)
-		 */
-		struct {
-			u32 offset;
-		} tails[2];
-
-		/**
-		 * @aged_tail_idx: Index for the aged tail ready to read() data up to.
+		 * @aging_tail: The last HW tail reported by HW. The data
+		 * might not have made it to memory yet though.
 		 */
-		unsigned int aged_tail_idx;
+		u32 aging_tail;
 
 		/**
 		 * @aging_timestamp: A monotonic timestamp for when the current aging tail pointer
@@ -302,6 +293,11 @@ struct i915_perf_stream {
 		 * OA buffer data to userspace.
 		 */
 		u32 head;
+
+		/**
+		 * @tail: The last verified tail that can be read by userspace.
+		 */
+		u32 tail;
 	} oa_buffer;
 
 	/**
@@ -309,6 +305,12 @@ struct i915_perf_stream {
 	 * reprogrammed.
 	 */
 	struct i915_vma *noa_wait;
+
+	/**
+	 * @poll_oa_period: The period in nanoseconds at which the OA
+	 * buffer should be checked for available data.
+	 */
+	u64 poll_oa_period;
 };
 
 /**
@@ -339,8 +341,8 @@ struct i915_oa_ops {
 	 * counter reports being sampled. May apply system constraints such as
 	 * disabling EU clock gating as required.
 	 */
-	struct i915_request *
-		(*enable_metric_set)(struct i915_perf_stream *stream);
+	int (*enable_metric_set)(struct i915_perf_stream *stream,
+				 struct i915_active *active);
 
 	/**
 	 * @disable_metric_set: Remove system constraints associated with using
@@ -407,13 +409,23 @@ struct i915_perf {
 	 */
 	struct i915_perf_stream *exclusive_stream;
 
+	/**
+	 * @sseu: sseu configuration selected to run while perf is active,
+	 * applies to all contexts.
+	 */
+	struct intel_sseu sseu;
+
 	/**
 	 * For rate limiting any notifications of spurious
 	 * invalid OA reports
 	 */
 	struct ratelimit_state spurious_report_rs;
 
-	struct i915_oa_config test_config;
+	/**
+	 * For rate limiting any notifications of tail pointer
+	 * race.
+	 */
+	struct ratelimit_state tail_pointer_race;
 
 	u32 gen7_latched_oastatus1;
 	u32 ctx_oactxctrl_offset;
diff --git a/drivers/gpu/drm/i915/i915_pmu.c b/drivers/gpu/drm/i915/i915_pmu.c
index 2c062534eac1..230e9256ab30 100644
--- a/drivers/gpu/drm/i915/i915_pmu.c
+++ b/drivers/gpu/drm/i915/i915_pmu.c
@@ -1115,7 +1115,7 @@ void i915_pmu_register(struct drm_i915_private *i915)
 	int ret = -ENOMEM;
 
 	if (INTEL_GEN(i915) <= 2) {
-		dev_info(i915->drm.dev, "PMU not supported for this GPU.");
+		drm_info(&i915->drm, "PMU not supported for this GPU.");
 		return;
 	}
 
@@ -1178,7 +1178,7 @@ void i915_pmu_register(struct drm_i915_private *i915)
 	if (!is_igp(i915))
 		kfree(pmu->name);
 err:
-	dev_notice(i915->drm.dev, "Failed to register PMU!\n");
+	drm_notice(&i915->drm, "Failed to register PMU!\n");
 }
 
 void i915_pmu_unregister(struct drm_i915_private *i915)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 59e64acc2c56..edda3f29c8aa 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -3094,6 +3094,7 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
 #define GT_BSD_CS_ERROR_INTERRUPT		(1 << 15)
 #define GT_BSD_USER_INTERRUPT			(1 << 12)
 #define GT_RENDER_L3_PARITY_ERROR_INTERRUPT_S1	(1 << 11) /* hsw+; rsvd on snb, ivb, vlv */
+#define GT_WAIT_SEMAPHORE_INTERRUPT		REG_BIT(11) /* bdw+ */
 #define GT_CONTEXT_SWITCH_INTERRUPT		(1 <<  8)
 #define GT_RENDER_L3_PARITY_ERROR_INTERRUPT	(1 <<  5) /* !snb */
 #define GT_RENDER_PIPECTL_NOTIFY_INTERRUPT	(1 <<  4)
@@ -4324,6 +4325,96 @@ enum {
 #define   EXITLINE_MASK		REG_GENMASK(12, 0)
 #define   EXITLINE_SHIFT	0
 
+/* VRR registers */
+#define _TRANS_VRR_CTL_A		0x60420
+#define _TRANS_VRR_CTL_B		0x61420
+#define _TRANS_VRR_CTL_C		0x62420
+#define _TRANS_VRR_CTL_D		0x63420
+#define TRANS_VRR_CTL(trans)		_MMIO_TRANS2(trans, _TRANS_VRR_CTL_A)
+#define   VRR_CTL_VRR_ENABLE		REG_BIT(31)
+#define   VRR_CTL_IGN_MAX_SHIFT		REG_BIT(30)
+#define   VRR_CTL_FLIP_LINE_EN		REG_BIT(29)
+#define   VRR_CTL_LINE_COUNT_MASK	REG_GENMASK(10, 3)
+#define   VRR_CTL_SW_FULLLINE_COUNT	REG_BIT(0)
+
+#define _TRANS_VRR_VMAX_A		0x60424
+#define _TRANS_VRR_VMAX_B		0x61424
+#define _TRANS_VRR_VMAX_C		0x62424
+#define _TRANS_VRR_VMAX_D		0x63424
+#define TRANS_VRR_VMAX(trans)		_MMIO_TRANS2(trans, _TRANS_VRR_VMAX_A)
+#define   VRR_VMAX_MASK			REG_GENMASK(19, 0)
+
+#define _TRANS_VRR_VMIN_A		0x60434
+#define _TRANS_VRR_VMIN_B		0x61434
+#define _TRANS_VRR_VMIN_C		0x62434
+#define _TRANS_VRR_VMIN_D		0x63434
+#define TRANS_VRR_VMIN(trans)		_MMIO_TRANS2(trans, _TRANS_VRR_VMIN_A)
+#define   VRR_VMIN_MASK			REG_GENMASK(15, 0)
+
+#define _TRANS_VRR_VMAXSHIFT_A		0x60428
+#define _TRANS_VRR_VMAXSHIFT_B		0x61428
+#define _TRANS_VRR_VMAXSHIFT_C		0x62428
+#define _TRANS_VRR_VMAXSHIFT_D		0x63428
+#define TRANS_VRR_VMAXSHIFT(trans)	_MMIO_TRANS2(trans, \
+					_TRANS_VRR_VMAXSHIFT_A)
+#define   VRR_VMAXSHIFT_DEC_MASK	REG_GENMASK(29, 16)
+#define   VRR_VMAXSHIFT_DEC		REG_BIT(16)
+#define   VRR_VMAXSHIFT_INC_MASK	REG_GENMASK(12, 0)
+
+#define _TRANS_VRR_STATUS_A		0x6042C
+#define _TRANS_VRR_STATUS_B		0x6142C
+#define _TRANS_VRR_STATUS_C		0x6242C
+#define _TRANS_VRR_STATUS_D		0x6342C
+#define TRANS_VRR_STATUS(trans)		_MMIO_TRANS2(trans, _TRANS_VRR_STATUS_A)
+#define   VRR_STATUS_VMAX_REACHED	REG_BIT(31)
+#define   VRR_STATUS_NOFLIP_TILL_BNDR	REG_BIT(30)
+#define   VRR_STATUS_FLIP_BEF_BNDR	REG_BIT(29)
+#define   VRR_STATUS_NO_FLIP_FRAME	REG_BIT(28)
+#define   VRR_STATUS_VRR_EN_LIVE	REG_BIT(27)
+#define   VRR_STATUS_FLIPS_SERVICED	REG_BIT(26)
+#define   VRR_STATUS_VBLANK_MASK	REG_GENMASK(22, 20)
+#define   STATUS_FSM_IDLE		REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 0)
+#define   STATUS_FSM_WAIT_TILL_FDB	REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 1)
+#define   STATUS_FSM_WAIT_TILL_FS	REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 2)
+#define   STATUS_FSM_WAIT_TILL_FLIP	REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 3)
+#define   STATUS_FSM_PIPELINE_FILL	REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 4)
+#define   STATUS_FSM_ACTIVE		REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 5)
+#define   STATUS_FSM_LEGACY_VBLANK	REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 6)
+
+#define _TRANS_VRR_VTOTAL_PREV_A	0x60480
+#define _TRANS_VRR_VTOTAL_PREV_B	0x61480
+#define _TRANS_VRR_VTOTAL_PREV_C	0x62480
+#define _TRANS_VRR_VTOTAL_PREV_D	0x63480
+#define TRANS_VRR_VTOTAL_PREV(trans)	_MMIO_TRANS2(trans, \
+					_TRANS_VRR_VTOTAL_PREV_A)
+#define   VRR_VTOTAL_FLIP_BEFR_BNDR	REG_BIT(31)
+#define   VRR_VTOTAL_FLIP_AFTER_BNDR	REG_BIT(30)
+#define   VRR_VTOTAL_FLIP_AFTER_DBLBUF	REG_BIT(29)
+#define   VRR_VTOTAL_PREV_FRAME_MASK	REG_GENMASK(19, 0)
+
+#define _TRANS_VRR_FLIPLINE_A		0x60438
+#define _TRANS_VRR_FLIPLINE_B		0x61438
+#define _TRANS_VRR_FLIPLINE_C		0x62438
+#define _TRANS_VRR_FLIPLINE_D		0x63438
+#define TRANS_VRR_FLIPLINE(trans)	_MMIO_TRANS2(trans, \
+					_TRANS_VRR_FLIPLINE_A)
+#define   VRR_FLIPLINE_MASK		REG_GENMASK(19, 0)
+
+#define _TRANS_VRR_STATUS2_A		0x6043C
+#define _TRANS_VRR_STATUS2_B		0x6143C
+#define _TRANS_VRR_STATUS2_C		0x6243C
+#define _TRANS_VRR_STATUS2_D		0x6343C
+#define TRANS_VRR_STATUS2(trans)	_MMIO_TRANS2(trans, _TRANS_VRR_STATUS2_A)
+#define   VRR_STATUS2_VERT_LN_CNT_MASK	REG_GENMASK(19, 0)
+
+#define _TRANS_PUSH_A			0x60A70
+#define _TRANS_PUSH_B			0x61A70
+#define _TRANS_PUSH_C			0x62A70
+#define _TRANS_PUSH_D			0x63A70
+#define TRANS_PUSH(trans)		_MMIO_TRANS2(trans, _TRANS_PUSH_A)
+#define   TRANS_PUSH_EN			REG_BIT(31)
+#define   TRANS_PUSH_SEND		REG_BIT(30)
+
 /*
  * HSW+ eDP PSR registers
  *
@@ -6764,7 +6855,7 @@ enum {
 #define   PLANE_CTL_FORMAT_P012			(5 << 24)
 #define   PLANE_CTL_FORMAT_XRGB_16161616F	(6 << 24)
 #define   PLANE_CTL_FORMAT_P016			(7 << 24)
-#define   PLANE_CTL_FORMAT_AYUV			(8 << 24)
+#define   PLANE_CTL_FORMAT_XYUV			(8 << 24)
 #define   PLANE_CTL_FORMAT_INDEXED		(12 << 24)
 #define   PLANE_CTL_FORMAT_RGB_565		(14 << 24)
 #define   ICL_PLANE_CTL_FORMAT_MASK		(0x1f << 23)
@@ -9700,8 +9791,11 @@ enum skl_power_gate {
 #define  TRANS_DDI_BPC_10		(1 << 20)
 #define  TRANS_DDI_BPC_6		(2 << 20)
 #define  TRANS_DDI_BPC_12		(3 << 20)
+#define  TRANS_DDI_PORT_SYNC_MASTER_SELECT_MASK	REG_GENMASK(19, 18) /* bdw-cnl */
+#define  TRANS_DDI_PORT_SYNC_MASTER_SELECT(x)	REG_FIELD_PREP(TRANS_DDI_PORT_SYNC_MASTER_SELECT_MASK, (x))
 #define  TRANS_DDI_PVSYNC		(1 << 17)
 #define  TRANS_DDI_PHSYNC		(1 << 16)
+#define  TRANS_DDI_PORT_SYNC_ENABLE	REG_BIT(15) /* bdw-cnl */
 #define  TRANS_DDI_EDP_INPUT_MASK	(7 << 12)
 #define  TRANS_DDI_EDP_INPUT_A_ON	(0 << 12)
 #define  TRANS_DDI_EDP_INPUT_A_ONOFF	(4 << 12)
@@ -9728,12 +9822,10 @@ enum skl_power_gate {
 #define _TRANS_DDI_FUNC_CTL2_EDP	0x6f404
 #define _TRANS_DDI_FUNC_CTL2_DSI0	0x6b404
 #define _TRANS_DDI_FUNC_CTL2_DSI1	0x6bc04
-#define TRANS_DDI_FUNC_CTL2(tran)	_MMIO_TRANS2(tran, \
-						     _TRANS_DDI_FUNC_CTL2_A)
-#define  PORT_SYNC_MODE_ENABLE			(1 << 4)
-#define  PORT_SYNC_MODE_MASTER_SELECT(x)	((x) << 0)
-#define  PORT_SYNC_MODE_MASTER_SELECT_MASK	(0x7 << 0)
-#define  PORT_SYNC_MODE_MASTER_SELECT_SHIFT	0
+#define TRANS_DDI_FUNC_CTL2(tran)	_MMIO_TRANS2(tran, _TRANS_DDI_FUNC_CTL2_A)
+#define  PORT_SYNC_MODE_ENABLE			REG_BIT(4)
+#define  PORT_SYNC_MODE_MASTER_SELECT_MASK	REG_GENMASK(2, 0)
+#define  PORT_SYNC_MODE_MASTER_SELECT(x)	REG_FIELD_PREP(PORT_SYNC_MODE_MASTER_SELECT_MASK, (x))
 
 /* DisplayPort Transport Control */
 #define _DP_TP_CTL_A			0x64040
@@ -9794,6 +9886,24 @@ enum skl_power_gate {
 #define  DDI_BUF_BALANCE_LEG_ENABLE	(1 << 31)
 #define DDI_BUF_TRANS_HI(port, i)	_MMIO(_PORT(port, _DDI_BUF_TRANS_A, _DDI_BUF_TRANS_B) + (i) * 8 + 4)
 
+/* DDI DP Compliance Control */
+#define _DDI_DP_COMP_CTL_A			0x605F0
+#define _DDI_DP_COMP_CTL_B			0x615F0
+#define DDI_DP_COMP_CTL(pipe)			_MMIO_PIPE(pipe, _DDI_DP_COMP_CTL_A, _DDI_DP_COMP_CTL_B)
+#define   DDI_DP_COMP_CTL_ENABLE		(1 << 31)
+#define   DDI_DP_COMP_CTL_D10_2			(0 << 28)
+#define   DDI_DP_COMP_CTL_SCRAMBLED_0		(1 << 28)
+#define   DDI_DP_COMP_CTL_PRBS7			(2 << 28)
+#define   DDI_DP_COMP_CTL_CUSTOM80		(3 << 28)
+#define   DDI_DP_COMP_CTL_HBR2			(4 << 28)
+#define   DDI_DP_COMP_CTL_SCRAMBLED_1		(5 << 28)
+#define   DDI_DP_COMP_CTL_HBR2_RESET		(0xFC << 0)
+
+/* DDI DP Compliance Pattern */
+#define _DDI_DP_COMP_PAT_A			0x605F4
+#define _DDI_DP_COMP_PAT_B			0x615F4
+#define DDI_DP_COMP_PAT(pipe, i)		_MMIO(_PIPE(pipe, _DDI_DP_COMP_PAT_A, _DDI_DP_COMP_PAT_B) + (i) * 4)
+
 /* Sideband Interface (SBI) is programmed indirectly, via
  * SBI_ADDR, which contains the register offset; and SBI_DATA,
  * which contains the payload */
@@ -10741,6 +10851,12 @@ enum skl_power_gate {
 
 #define _PAL_PREC_MULTI_SEG_DATA_A	0x4A40C
 #define _PAL_PREC_MULTI_SEG_DATA_B	0x4AC0C
+#define  PAL_PREC_MULTI_SEG_RED_LDW_MASK   REG_GENMASK(29, 24)
+#define  PAL_PREC_MULTI_SEG_RED_UDW_MASK   REG_GENMASK(29, 20)
+#define  PAL_PREC_MULTI_SEG_GREEN_LDW_MASK REG_GENMASK(19, 14)
+#define  PAL_PREC_MULTI_SEG_GREEN_UDW_MASK REG_GENMASK(19, 10)
+#define  PAL_PREC_MULTI_SEG_BLUE_LDW_MASK  REG_GENMASK(9, 4)
+#define  PAL_PREC_MULTI_SEG_BLUE_UDW_MASK  REG_GENMASK(9, 0)
 
 #define PREC_PAL_MULTI_SEG_INDEX(pipe)	_MMIO_PIPE(pipe, \
 					_PAL_PREC_MULTI_SEG_INDEX_A, \
diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c
index c0df71d7d0ff..22635bbabf06 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -101,6 +101,11 @@ static signed long i915_fence_wait(struct dma_fence *fence,
 				 timeout);
 }
 
+struct kmem_cache *i915_request_slab_cache(void)
+{
+	return global.slab_requests;
+}
+
 static void i915_fence_release(struct dma_fence *fence)
 {
 	struct i915_request *rq = to_request(fence);
@@ -115,6 +120,10 @@ static void i915_fence_release(struct dma_fence *fence)
 	i915_sw_fence_fini(&rq->submit);
 	i915_sw_fence_fini(&rq->semaphore);
 
+	/* Keep one request on each engine for reserved use under mempressure */
+	if (!cmpxchg(&rq->engine->request_pool, NULL, rq))
+		return;
+
 	kmem_cache_free(global.slab_requests, rq);
 }
 
@@ -629,14 +638,22 @@ static void retire_requests(struct intel_timeline *tl)
 }
 
 static noinline struct i915_request *
-request_alloc_slow(struct intel_timeline *tl, gfp_t gfp)
+request_alloc_slow(struct intel_timeline *tl,
+		   struct i915_request **rsvd,
+		   gfp_t gfp)
 {
 	struct i915_request *rq;
 
-	if (list_empty(&tl->requests))
-		goto out;
+	/* If we cannot wait, dip into our reserves */
+	if (!gfpflags_allow_blocking(gfp)) {
+		rq = xchg(rsvd, NULL);
+		if (!rq) /* Use the normal failure path for one final WARN */
+			goto out;
 
-	if (!gfpflags_allow_blocking(gfp))
+		return rq;
+	}
+
+	if (list_empty(&tl->requests))
 		goto out;
 
 	/* Move our oldest request to the slab-cache (if not in use!) */
@@ -721,7 +738,7 @@ __i915_request_create(struct intel_context *ce, gfp_t gfp)
 	rq = kmem_cache_alloc(global.slab_requests,
 			      gfp | __GFP_RETRY_MAYFAIL | __GFP_NOWARN);
 	if (unlikely(!rq)) {
-		rq = request_alloc_slow(tl, gfp);
+		rq = request_alloc_slow(tl, &ce->engine->request_pool, gfp);
 		if (!rq) {
 			ret = -ENOMEM;
 			goto err_unreserve;
@@ -1444,9 +1461,7 @@ void i915_request_add(struct i915_request *rq)
 	if (list_empty(&rq->sched.signalers_list))
 		attr.priority |= I915_PRIORITY_WAIT;
 
-	local_bh_disable();
 	__i915_request_queue(rq, &attr);
-	local_bh_enable(); /* Kick the execlists tasklet if just scheduled */
 
 	mutex_unlock(&tl->mutex);
 }
diff --git a/drivers/gpu/drm/i915/i915_request.h b/drivers/gpu/drm/i915/i915_request.h
index 3c552bfea67a..d8ce908e1346 100644
--- a/drivers/gpu/drm/i915/i915_request.h
+++ b/drivers/gpu/drm/i915/i915_request.h
@@ -300,6 +300,8 @@ static inline bool dma_fence_is_i915(const struct dma_fence *fence)
 	return fence->ops == &i915_fence_ops;
 }
 
+struct kmem_cache *i915_request_slab_cache(void);
+
 struct i915_request * __must_check
 __i915_request_create(struct intel_context *ce, gfp_t gfp);
 struct i915_request * __must_check
diff --git a/drivers/gpu/drm/i915/i915_scheduler.c b/drivers/gpu/drm/i915/i915_scheduler.c
index 68b06a7ba667..37cfcf5b321b 100644
--- a/drivers/gpu/drm/i915/i915_scheduler.c
+++ b/drivers/gpu/drm/i915/i915_scheduler.c
@@ -209,6 +209,12 @@ static void kick_submission(struct intel_engine_cs *engine,
 	if (!inflight)
 		goto unlock;
 
+	ENGINE_TRACE(engine,
+		     "bumping queue-priority-hint:%d for rq:%llx:%lld, inflight:%llx:%lld prio %d\n",
+		     prio,
+		     rq->fence.context, rq->fence.seqno,
+		     inflight->fence.context, inflight->fence.seqno,
+		     inflight->sched.attr.priority);
 	engine->execlists.queue_priority_hint = prio;
 
 	/*
@@ -464,11 +470,15 @@ int i915_sched_node_add_dependency(struct i915_sched_node *node,
 	if (!dep)
 		return -ENOMEM;
 
+	local_bh_disable();
+
 	if (!__i915_sched_node_add_dependency(node, signal, dep,
 					      I915_DEPENDENCY_EXTERNAL |
 					      I915_DEPENDENCY_ALLOC))
 		i915_dependency_free(dep);
 
+	local_bh_enable(); /* kick submission tasklet */
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/i915/i915_sw_fence.c b/drivers/gpu/drm/i915/i915_sw_fence.c
index a3d38e089b6e..7daf81f55c90 100644
--- a/drivers/gpu/drm/i915/i915_sw_fence.c
+++ b/drivers/gpu/drm/i915/i915_sw_fence.c
@@ -421,7 +421,7 @@ static void timer_i915_sw_fence_wake(struct timer_list *t)
 	if (!fence)
 		return;
 
-	pr_notice("Asynchronous wait on fence %s:%s:%llx timed out (hint:%pS)\n",
+	pr_notice("Asynchronous wait on fence %s:%s:%llx timed out (hint:%ps)\n",
 		  cb->dma->ops->get_driver_name(cb->dma),
 		  cb->dma->ops->get_timeline_name(cb->dma),
 		  cb->dma->seqno,
diff --git a/drivers/gpu/drm/i915/i915_sw_fence_work.c b/drivers/gpu/drm/i915/i915_sw_fence_work.c
index 997b2998f1f2..a3a81bb8f2c3 100644
--- a/drivers/gpu/drm/i915/i915_sw_fence_work.c
+++ b/drivers/gpu/drm/i915/i915_sw_fence_work.c
@@ -38,7 +38,10 @@ fence_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state)
 
 		if (!f->dma.error) {
 			dma_fence_get(&f->dma);
-			queue_work(system_unbound_wq, &f->work);
+			if (test_bit(DMA_FENCE_WORK_IMM, &f->dma.flags))
+				fence_work(&f->work);
+			else
+				queue_work(system_unbound_wq, &f->work);
 		} else {
 			fence_complete(f);
 		}
diff --git a/drivers/gpu/drm/i915/i915_sw_fence_work.h b/drivers/gpu/drm/i915/i915_sw_fence_work.h
index 3a22b287e201..2c409f11c5c5 100644
--- a/drivers/gpu/drm/i915/i915_sw_fence_work.h
+++ b/drivers/gpu/drm/i915/i915_sw_fence_work.h
@@ -32,6 +32,10 @@ struct dma_fence_work {
 	const struct dma_fence_work_ops *ops;
 };
 
+enum {
+	DMA_FENCE_WORK_IMM = DMA_FENCE_FLAG_USER_BITS,
+};
+
 void dma_fence_work_init(struct dma_fence_work *f,
 			 const struct dma_fence_work_ops *ops);
 int dma_fence_work_chain(struct dma_fence_work *f, struct dma_fence *signal);
@@ -41,4 +45,23 @@ static inline void dma_fence_work_commit(struct dma_fence_work *f)
 	i915_sw_fence_commit(&f->chain);
 }
 
+/**
+ * dma_fence_work_commit_imm: Commit the fence, and if possible execute locally.
+ * @f: the fenced worker
+ *
+ * Instead of always scheduling a worker to execute the callback (see
+ * dma_fence_work_commit()), we try to execute the callback immediately in
+ * the local context. It is required that the fence be committed before it
+ * is published, and that no other threads try to tamper with the number
+ * of asynchronous waits on the fence (or else the callback will be
+ * executed in the wrong context, i.e. not the callers).
+ */
+static inline void dma_fence_work_commit_imm(struct dma_fence_work *f)
+{
+	if (atomic_read(&f->chain.pending) <= 1)
+		__set_bit(DMA_FENCE_WORK_IMM, &f->dma.flags);
+
+	dma_fence_work_commit(f);
+}
+
 #endif /* I915_SW_FENCE_WORK_H */
diff --git a/drivers/gpu/drm/i915/i915_switcheroo.c b/drivers/gpu/drm/i915/i915_switcheroo.c
index ed69b5d4a375..b3a24eac21f1 100644
--- a/drivers/gpu/drm/i915/i915_switcheroo.c
+++ b/drivers/gpu/drm/i915/i915_switcheroo.c
@@ -20,14 +20,14 @@ static void i915_switcheroo_set_state(struct pci_dev *pdev,
 	}
 
 	if (state == VGA_SWITCHEROO_ON) {
-		pr_info("switched on\n");
+		drm_info(&i915->drm, "switched on\n");
 		i915->drm.switch_power_state = DRM_SWITCH_POWER_CHANGING;
 		/* i915 resume handler doesn't set to D0 */
 		pci_set_power_state(pdev, PCI_D0);
 		i915_resume_switcheroo(i915);
 		i915->drm.switch_power_state = DRM_SWITCH_POWER_ON;
 	} else {
-		pr_info("switched off\n");
+		drm_info(&i915->drm, "switched off\n");
 		i915->drm.switch_power_state = DRM_SWITCH_POWER_CHANGING;
 		i915_suspend_switcheroo(i915, pmm);
 		i915->drm.switch_power_state = DRM_SWITCH_POWER_OFF;
diff --git a/drivers/gpu/drm/i915/i915_utils.c b/drivers/gpu/drm/i915/i915_utils.c
index 029854ae65fc..e28eae4a8f70 100644
--- a/drivers/gpu/drm/i915/i915_utils.c
+++ b/drivers/gpu/drm/i915/i915_utils.c
@@ -101,5 +101,6 @@ void set_timer_ms(struct timer_list *t, unsigned long timeout)
 	 */
 	barrier();
 
-	mod_timer(t, jiffies + timeout);
+	/* Keep t->expires = 0 reserved to indicate a canceled timer. */
+	mod_timer(t, jiffies + timeout ?: 1);
 }
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 08699fa069aa..f0383a68c981 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -608,18 +608,6 @@ bool i915_gem_valid_gtt_space(struct i915_vma *vma, unsigned long color)
 	return true;
 }
 
-static void assert_bind_count(const struct drm_i915_gem_object *obj)
-{
-	/*
-	 * Combine the assertion that the object is bound and that we have
-	 * pinned its pages. But we should never have bound the object
-	 * more than we have pinned its pages. (For complete accuracy, we
-	 * assume that no else is pinning the pages, but as a rough assertion
-	 * that we will not run into problems later, this will do!)
-	 */
-	GEM_BUG_ON(atomic_read(&obj->mm.pages_pin_count) < atomic_read(&obj->bind_count));
-}
-
 /**
  * i915_vma_insert - finds a slot for the vma in its address space
  * @vma: the vma
@@ -738,12 +726,6 @@ i915_vma_insert(struct i915_vma *vma, u64 size, u64 alignment, u64 flags)
 	GEM_BUG_ON(!drm_mm_node_allocated(&vma->node));
 	GEM_BUG_ON(!i915_gem_valid_gtt_space(vma, color));
 
-	if (vma->obj) {
-		struct drm_i915_gem_object *obj = vma->obj;
-
-		atomic_inc(&obj->bind_count);
-		assert_bind_count(obj);
-	}
 	list_add_tail(&vma->vm_link, &vma->vm->bound_list);
 
 	return 0;
@@ -761,12 +743,6 @@ i915_vma_detach(struct i915_vma *vma)
 	 * it to be reaped by the shrinker.
 	 */
 	list_del(&vma->vm_link);
-	if (vma->obj) {
-		struct drm_i915_gem_object *obj = vma->obj;
-
-		assert_bind_count(obj);
-		atomic_dec(&obj->bind_count);
-	}
 }
 
 static bool try_qad_pin(struct i915_vma *vma, unsigned int flags)
@@ -913,11 +889,30 @@ int i915_vma_pin(struct i915_vma *vma, u64 size, u64 alignment, u64 flags)
 	if (flags & PIN_GLOBAL)
 		wakeref = intel_runtime_pm_get(&vma->vm->i915->runtime_pm);
 
-	/* No more allocations allowed once we hold vm->mutex */
-	err = mutex_lock_interruptible(&vma->vm->mutex);
+	/*
+	 * Differentiate between user/kernel vma inside the aliasing-ppgtt.
+	 *
+	 * We conflate the Global GTT with the user's vma when using the
+	 * aliasing-ppgtt, but it is still vitally important to try and
+	 * keep the use cases distinct. For example, userptr objects are
+	 * not allowed inside the Global GTT as that will cause lock
+	 * inversions when we have to evict them the mmu_notifier callbacks -
+	 * but they are allowed to be part of the user ppGTT which can never
+	 * be mapped. As such we try to give the distinct users of the same
+	 * mutex, distinct lockclasses [equivalent to how we keep i915_ggtt
+	 * and i915_ppgtt separate].
+	 *
+	 * NB this may cause us to mask real lock inversions -- while the
+	 * code is safe today, lockdep may not be able to spot future
+	 * transgressions.
+	 */
+	err = mutex_lock_interruptible_nested(&vma->vm->mutex,
+					      !(flags & PIN_GLOBAL));
 	if (err)
 		goto err_fence;
 
+	/* No more allocations allowed now we hold vm->mutex */
+
 	if (unlikely(i915_vma_is_closed(vma))) {
 		err = -ENOENT;
 		goto err_unlock;
@@ -980,7 +975,7 @@ int i915_vma_pin(struct i915_vma *vma, u64 size, u64 alignment, u64 flags)
 	mutex_unlock(&vma->vm->mutex);
 err_fence:
 	if (work)
-		dma_fence_work_commit(&work->base);
+		dma_fence_work_commit_imm(&work->base);
 	if (wakeref)
 		intel_runtime_pm_put(&vma->vm->i915->runtime_pm, wakeref);
 err_pages:
@@ -1172,7 +1167,8 @@ int __i915_vma_move_to_active(struct i915_vma *vma, struct i915_request *rq)
 	GEM_BUG_ON(!i915_vma_is_pinned(vma));
 
 	/* Wait for the vma to be bound before we start! */
-	err = i915_request_await_active(rq, &vma->active, 0);
+	err = i915_request_await_active(rq, &vma->active,
+					I915_ACTIVE_AWAIT_EXCL);
 	if (err)
 		return err;
 
@@ -1213,6 +1209,10 @@ int i915_vma_move_to_active(struct i915_vma *vma,
 		dma_resv_add_shared_fence(vma->resv, &rq->fence);
 		obj->write_domain = 0;
 	}
+
+	if (flags & EXEC_OBJECT_NEEDS_FENCE && vma->fence)
+		i915_active_add_request(&vma->fence->active, rq);
+
 	obj->read_domains |= I915_GEM_GPU_DOMAINS;
 	obj->mm.dirty = true;
 
@@ -1226,18 +1226,6 @@ int __i915_vma_unbind(struct i915_vma *vma)
 
 	lockdep_assert_held(&vma->vm->mutex);
 
-	/*
-	 * First wait upon any activity as retiring the request may
-	 * have side-effects such as unpinning or even unbinding this vma.
-	 *
-	 * XXX Actually waiting under the vm->mutex is a hinderance and
-	 * should be pipelined wherever possible. In cases where that is
-	 * unavoidable, we should lift the wait to before the mutex.
-	 */
-	ret = i915_vma_sync(vma);
-	if (ret)
-		return ret;
-
 	if (i915_vma_is_pinned(vma)) {
 		vma_print_allocator(vma, "is pinned");
 		return -EAGAIN;
@@ -1259,6 +1247,9 @@ int __i915_vma_unbind(struct i915_vma *vma)
 	GEM_BUG_ON(i915_vma_is_active(vma));
 
 	if (i915_vma_is_map_and_fenceable(vma)) {
+		/* Force a pagefault for domain tracking on next user access */
+		i915_vma_revoke_mmap(vma);
+
 		/*
 		 * Check that we have flushed all writes through the GGTT
 		 * before the unbind, other due to non-strict nature of those
@@ -1275,12 +1266,7 @@ int __i915_vma_unbind(struct i915_vma *vma)
 		i915_vma_flush_writes(vma);
 
 		/* release the fence reg _after_ flushing */
-		ret = i915_vma_revoke_fence(vma);
-		if (ret)
-			return ret;
-
-		/* Force a pagefault for domain tracking on next user access */
-		i915_vma_revoke_mmap(vma);
+		i915_vma_revoke_fence(vma);
 
 		__i915_vma_iounmap(vma);
 		clear_bit(I915_VMA_CAN_FENCE_BIT, __i915_vma_flags(vma));
@@ -1311,16 +1297,21 @@ int i915_vma_unbind(struct i915_vma *vma)
 	if (!drm_mm_node_allocated(&vma->node))
 		return 0;
 
-	if (i915_vma_is_bound(vma, I915_VMA_GLOBAL_BIND))
-		/* XXX not always required: nop_clear_range */
-		wakeref = intel_runtime_pm_get(&vm->i915->runtime_pm);
-
 	/* Optimistic wait before taking the mutex */
 	err = i915_vma_sync(vma);
 	if (err)
 		goto out_rpm;
 
-	err = mutex_lock_interruptible(&vm->mutex);
+	if (i915_vma_is_pinned(vma)) {
+		vma_print_allocator(vma, "is pinned");
+		return -EAGAIN;
+	}
+
+	if (i915_vma_is_bound(vma, I915_VMA_GLOBAL_BIND))
+		/* XXX not always required: nop_clear_range */
+		wakeref = intel_runtime_pm_get(&vm->i915->runtime_pm);
+
+	err = mutex_lock_interruptible_nested(&vma->vm->mutex, !wakeref);
 	if (err)
 		goto out_rpm;
 
diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
index e1ced1df13e1..8ad1daabcd58 100644
--- a/drivers/gpu/drm/i915/i915_vma.h
+++ b/drivers/gpu/drm/i915/i915_vma.h
@@ -30,10 +30,10 @@
 
 #include <drm/drm_mm.h>
 
+#include "gt/intel_ggtt_fencing.h"
 #include "gem/i915_gem_object.h"
 
 #include "i915_gem_gtt.h"
-#include "i915_gem_fence_reg.h"
 
 #include "i915_active.h"
 #include "i915_request.h"
@@ -326,7 +326,7 @@ static inline struct page *i915_vma_first_page(struct i915_vma *vma)
  * True if the vma has a fence, false otherwise.
  */
 int __must_check i915_vma_pin_fence(struct i915_vma *vma);
-int __must_check i915_vma_revoke_fence(struct i915_vma *vma);
+void i915_vma_revoke_fence(struct i915_vma *vma);
 
 int __i915_vma_pin_fence(struct i915_vma *vma);
 
diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c
index d7fe12734db8..db8496b4c38d 100644
--- a/drivers/gpu/drm/i915/intel_device_info.c
+++ b/drivers/gpu/drm/i915/intel_device_info.c
@@ -980,35 +980,32 @@ void intel_device_info_runtime_init(struct drm_i915_private *dev_priv)
 			drm_info(&dev_priv->drm,
 				 "Display fused off, disabling\n");
 			info->pipe_mask = 0;
+			info->cpu_transcoder_mask = 0;
 		} else if (fuse_strap & IVB_PIPE_C_DISABLE) {
 			drm_info(&dev_priv->drm, "PipeC fused off\n");
 			info->pipe_mask &= ~BIT(PIPE_C);
+			info->cpu_transcoder_mask &= ~BIT(TRANSCODER_C);
 		}
 	} else if (HAS_DISPLAY(dev_priv) && INTEL_GEN(dev_priv) >= 9) {
 		u32 dfsm = I915_READ(SKL_DFSM);
-		u8 enabled_mask = info->pipe_mask;
-
-		if (dfsm & SKL_DFSM_PIPE_A_DISABLE)
-			enabled_mask &= ~BIT(PIPE_A);
-		if (dfsm & SKL_DFSM_PIPE_B_DISABLE)
-			enabled_mask &= ~BIT(PIPE_B);
-		if (dfsm & SKL_DFSM_PIPE_C_DISABLE)
-			enabled_mask &= ~BIT(PIPE_C);
-		if (INTEL_GEN(dev_priv) >= 12 &&
-		    (dfsm & TGL_DFSM_PIPE_D_DISABLE))
-			enabled_mask &= ~BIT(PIPE_D);
 
-		/*
-		 * At least one pipe should be enabled and if there are
-		 * disabled pipes, they should be the last ones, with no holes
-		 * in the mask.
-		 */
-		if (enabled_mask == 0 || !is_power_of_2(enabled_mask + 1))
-			drm_err(&dev_priv->drm,
-				"invalid pipe fuse configuration: enabled_mask=0x%x\n",
-				enabled_mask);
-		else
-			info->pipe_mask = enabled_mask;
+		if (dfsm & SKL_DFSM_PIPE_A_DISABLE) {
+			info->pipe_mask &= ~BIT(PIPE_A);
+			info->cpu_transcoder_mask &= ~BIT(TRANSCODER_A);
+		}
+		if (dfsm & SKL_DFSM_PIPE_B_DISABLE) {
+			info->pipe_mask &= ~BIT(PIPE_B);
+			info->cpu_transcoder_mask &= ~BIT(TRANSCODER_B);
+		}
+		if (dfsm & SKL_DFSM_PIPE_C_DISABLE) {
+			info->pipe_mask &= ~BIT(PIPE_C);
+			info->cpu_transcoder_mask &= ~BIT(TRANSCODER_C);
+		}
+		if (INTEL_GEN(dev_priv) >= 12 &&
+		    (dfsm & TGL_DFSM_PIPE_D_DISABLE)) {
+			info->pipe_mask &= ~BIT(PIPE_D);
+			info->cpu_transcoder_mask &= ~BIT(TRANSCODER_D);
+		}
 
 		if (dfsm & SKL_DFSM_DISPLAY_HDCP_DISABLE)
 			info->display.has_hdcp = 0;
diff --git a/drivers/gpu/drm/i915/intel_device_info.h b/drivers/gpu/drm/i915/intel_device_info.h
index 1ecb9df2de91..cce6a72c5ebc 100644
--- a/drivers/gpu/drm/i915/intel_device_info.h
+++ b/drivers/gpu/drm/i915/intel_device_info.h
@@ -168,6 +168,7 @@ struct intel_device_info {
 	u32 display_mmio_offset;
 
 	u8 pipe_mask;
+	u8 cpu_transcoder_mask;
 
 #define DEFINE_FLAG(name) u8 name:1
 	DEV_INFO_FOR_EACH_FLAG(DEFINE_FLAG);
diff --git a/drivers/gpu/drm/i915/intel_dram.c b/drivers/gpu/drm/i915/intel_dram.c
index 6b922efb1d7c..8aa12cad93ce 100644
--- a/drivers/gpu/drm/i915/intel_dram.c
+++ b/drivers/gpu/drm/i915/intel_dram.c
@@ -495,6 +495,5 @@ void intel_dram_edram_detect(struct drm_i915_private *i915)
 	else
 		i915->edram_size_mb = gen9_edram_size_mb(i915, edram_cap);
 
-	dev_info(i915->drm.dev,
-		 "Found %uMB of eDRAM\n", i915->edram_size_mb);
+	drm_info(&i915->drm, "Found %uMB of eDRAM\n", i915->edram_size_mb);
 }
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 8375054ba27d..b632b6bb9c3e 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -4016,6 +4016,7 @@ static int skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
 				 int color_plane);
 static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state,
 				 int level,
+				 unsigned int latency,
 				 const struct skl_wm_params *wp,
 				 const struct skl_wm_level *result_prev,
 				 struct skl_wm_level *result /* out */);
@@ -4038,7 +4039,9 @@ skl_cursor_allocation(const struct intel_crtc_state *crtc_state,
 	drm_WARN_ON(&dev_priv->drm, ret);
 
 	for (level = 0; level <= max_level; level++) {
-		skl_compute_plane_wm(crtc_state, level, &wp, &wm, &wm);
+		unsigned int latency = dev_priv->wm.skl_latency[level];
+
+		skl_compute_plane_wm(crtc_state, level, latency, &wp, &wm, &wm);
 		if (wm.min_ddb_alloc == U16_MAX)
 			break;
 
@@ -4972,12 +4975,12 @@ static bool skl_wm_has_lines(struct drm_i915_private *dev_priv, int level)
 
 static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state,
 				 int level,
+				 unsigned int latency,
 				 const struct skl_wm_params *wp,
 				 const struct skl_wm_level *result_prev,
 				 struct skl_wm_level *result /* out */)
 {
 	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
-	u32 latency = dev_priv->wm.skl_latency[level];
 	uint_fixed_16_16_t method1, method2;
 	uint_fixed_16_16_t selected_result;
 	u32 res_blocks, res_lines, min_ddb_alloc = 0;
@@ -5106,9 +5109,10 @@ skl_compute_wm_levels(const struct intel_crtc_state *crtc_state,
 
 	for (level = 0; level <= max_level; level++) {
 		struct skl_wm_level *result = &levels[level];
+		unsigned int latency = dev_priv->wm.skl_latency[level];
 
-		skl_compute_plane_wm(crtc_state, level, wm_params,
-				     result_prev, result);
+		skl_compute_plane_wm(crtc_state, level, latency,
+				     wm_params, result_prev, result);
 
 		result_prev = result;
 	}
diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index abb18b90d7c3..fa86b7ab2d99 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -665,7 +665,7 @@ void intel_uncore_forcewake_user_put(struct intel_uncore *uncore)
 		mmio_debug_resume(uncore->debug);
 
 		if (check_for_unclaimed_mmio(uncore))
-			dev_info(uncore->i915->drm.dev,
+			drm_info(&uncore->i915->drm,
 				 "Invalid mmio detected during user access\n");
 		spin_unlock(&uncore->debug->lock);
 
@@ -734,6 +734,28 @@ void intel_uncore_forcewake_put(struct intel_uncore *uncore,
 	spin_unlock_irqrestore(&uncore->lock, irqflags);
 }
 
+/**
+ * intel_uncore_forcewake_flush - flush the delayed release
+ * @uncore: the intel_uncore structure
+ * @fw_domains: forcewake domains to flush
+ */
+void intel_uncore_forcewake_flush(struct intel_uncore *uncore,
+				  enum forcewake_domains fw_domains)
+{
+	struct intel_uncore_forcewake_domain *domain;
+	unsigned int tmp;
+
+	if (!uncore->funcs.force_wake_put)
+		return;
+
+	fw_domains &= uncore->fw_domains;
+	for_each_fw_domain_masked(domain, fw_domains, uncore, tmp) {
+		WRITE_ONCE(domain->active, false);
+		if (hrtimer_cancel(&domain->timer))
+			intel_uncore_fw_release_timer(&domain->timer);
+	}
+}
+
 /**
  * intel_uncore_forcewake_put__locked - grab forcewake domain references
  * @uncore: the intel_uncore structure
diff --git a/drivers/gpu/drm/i915/intel_uncore.h b/drivers/gpu/drm/i915/intel_uncore.h
index dcfa243892c6..8d3aa8b9acf9 100644
--- a/drivers/gpu/drm/i915/intel_uncore.h
+++ b/drivers/gpu/drm/i915/intel_uncore.h
@@ -209,7 +209,11 @@ void intel_uncore_forcewake_get(struct intel_uncore *uncore,
 				enum forcewake_domains domains);
 void intel_uncore_forcewake_put(struct intel_uncore *uncore,
 				enum forcewake_domains domains);
-/* Like above but the caller must manage the uncore.lock itself.
+void intel_uncore_forcewake_flush(struct intel_uncore *uncore,
+				  enum forcewake_domains fw_domains);
+
+/*
+ * Like above but the caller must manage the uncore.lock itself.
  * Must be used with I915_READ_FW and friends.
  */
 void intel_uncore_forcewake_get__locked(struct intel_uncore *uncore,
diff --git a/drivers/gpu/drm/i915/intel_wakeref.c b/drivers/gpu/drm/i915/intel_wakeref.c
index 8fbf6f4d3f26..dfd87d082218 100644
--- a/drivers/gpu/drm/i915/intel_wakeref.c
+++ b/drivers/gpu/drm/i915/intel_wakeref.c
@@ -70,11 +70,12 @@ static void ____intel_wakeref_put_last(struct intel_wakeref *wf)
 
 void __intel_wakeref_put_last(struct intel_wakeref *wf, unsigned long flags)
 {
-	INTEL_WAKEREF_BUG_ON(work_pending(&wf->work));
+	INTEL_WAKEREF_BUG_ON(delayed_work_pending(&wf->work));
 
 	/* Assume we are not in process context and so cannot sleep. */
 	if (flags & INTEL_WAKEREF_PUT_ASYNC || !mutex_trylock(&wf->mutex)) {
-		schedule_work(&wf->work);
+		mod_delayed_work(system_wq, &wf->work,
+				 FIELD_GET(INTEL_WAKEREF_PUT_DELAY, flags));
 		return;
 	}
 
@@ -83,7 +84,7 @@ void __intel_wakeref_put_last(struct intel_wakeref *wf, unsigned long flags)
 
 static void __intel_wakeref_put_work(struct work_struct *wrk)
 {
-	struct intel_wakeref *wf = container_of(wrk, typeof(*wf), work);
+	struct intel_wakeref *wf = container_of(wrk, typeof(*wf), work.work);
 
 	if (atomic_add_unless(&wf->count, -1, 1))
 		return;
@@ -104,8 +105,9 @@ void __intel_wakeref_init(struct intel_wakeref *wf,
 	atomic_set(&wf->count, 0);
 	wf->wakeref = 0;
 
-	INIT_WORK(&wf->work, __intel_wakeref_put_work);
-	lockdep_init_map(&wf->work.lockdep_map, "wakeref.work", &key->work, 0);
+	INIT_DELAYED_WORK(&wf->work, __intel_wakeref_put_work);
+	lockdep_init_map(&wf->work.work.lockdep_map,
+			 "wakeref.work", &key->work, 0);
 }
 
 int intel_wakeref_wait_for_idle(struct intel_wakeref *wf)
diff --git a/drivers/gpu/drm/i915/intel_wakeref.h b/drivers/gpu/drm/i915/intel_wakeref.h
index 7d1e676b71ef..545c8f277c46 100644
--- a/drivers/gpu/drm/i915/intel_wakeref.h
+++ b/drivers/gpu/drm/i915/intel_wakeref.h
@@ -8,6 +8,7 @@
 #define INTEL_WAKEREF_H
 
 #include <linux/atomic.h>
+#include <linux/bitfield.h>
 #include <linux/bits.h>
 #include <linux/lockdep.h>
 #include <linux/mutex.h>
@@ -41,7 +42,7 @@ struct intel_wakeref {
 	struct intel_runtime_pm *rpm;
 	const struct intel_wakeref_ops *ops;
 
-	struct work_struct work;
+	struct delayed_work work;
 };
 
 struct intel_wakeref_lockclass {
@@ -117,6 +118,11 @@ intel_wakeref_get_if_active(struct intel_wakeref *wf)
 	return atomic_inc_not_zero(&wf->count);
 }
 
+enum {
+	INTEL_WAKEREF_PUT_ASYNC_BIT = 0,
+	__INTEL_WAKEREF_PUT_LAST_BIT__
+};
+
 /**
  * intel_wakeref_put_flags: Release the wakeref
  * @wf: the wakeref
@@ -134,7 +140,9 @@ intel_wakeref_get_if_active(struct intel_wakeref *wf)
  */
 static inline void
 __intel_wakeref_put(struct intel_wakeref *wf, unsigned long flags)
-#define INTEL_WAKEREF_PUT_ASYNC BIT(0)
+#define INTEL_WAKEREF_PUT_ASYNC BIT(INTEL_WAKEREF_PUT_ASYNC_BIT)
+#define INTEL_WAKEREF_PUT_DELAY \
+	GENMASK(BITS_PER_LONG - 1, __INTEL_WAKEREF_PUT_LAST_BIT__)
 {
 	INTEL_WAKEREF_BUG_ON(atomic_read(&wf->count) <= 0);
 	if (unlikely(!atomic_add_unless(&wf->count, -1, 1)))
@@ -154,6 +162,14 @@ intel_wakeref_put_async(struct intel_wakeref *wf)
 	__intel_wakeref_put(wf, INTEL_WAKEREF_PUT_ASYNC);
 }
 
+static inline void
+intel_wakeref_put_delay(struct intel_wakeref *wf, unsigned long delay)
+{
+	__intel_wakeref_put(wf,
+			    INTEL_WAKEREF_PUT_ASYNC |
+			    FIELD_PREP(INTEL_WAKEREF_PUT_DELAY, delay));
+}
+
 /**
  * intel_wakeref_lock: Lock the wakeref (mutex)
  * @wf: the wakeref
@@ -194,7 +210,7 @@ intel_wakeref_unlock_wait(struct intel_wakeref *wf)
 {
 	mutex_lock(&wf->mutex);
 	mutex_unlock(&wf->mutex);
-	flush_work(&wf->work);
+	flush_delayed_work(&wf->work);
 }
 
 /**
diff --git a/drivers/gpu/drm/i915/intel_wopcm.c b/drivers/gpu/drm/i915/intel_wopcm.c
index 2bb9f9f9a50a..2186386a45c8 100644
--- a/drivers/gpu/drm/i915/intel_wopcm.c
+++ b/drivers/gpu/drm/i915/intel_wopcm.c
@@ -86,7 +86,7 @@ void intel_wopcm_init_early(struct intel_wopcm *wopcm)
 	else
 		wopcm->size = GEN9_WOPCM_SIZE;
 
-	DRM_DEV_DEBUG_DRIVER(i915->drm.dev, "WOPCM: %uK\n", wopcm->size / 1024);
+	drm_dbg(&i915->drm, "WOPCM: %uK\n", wopcm->size / 1024);
 }
 
 static inline u32 context_reserved_size(struct drm_i915_private *i915)
@@ -112,7 +112,7 @@ static inline bool gen9_check_dword_gap(struct drm_i915_private *i915,
 	offset = guc_wopcm_base + GEN9_GUC_WOPCM_OFFSET;
 	if (offset > guc_wopcm_size ||
 	    (guc_wopcm_size - offset) < sizeof(u32)) {
-		dev_err(i915->drm.dev,
+		drm_err(&i915->drm,
 			"WOPCM: invalid GuC region size: %uK < %uK\n",
 			guc_wopcm_size / SZ_1K,
 			(u32)(offset + sizeof(u32)) / SZ_1K);
@@ -131,7 +131,7 @@ static inline bool gen9_check_huc_fw_fits(struct drm_i915_private *i915,
 	 * firmware uploading would fail.
 	 */
 	if (huc_fw_size > guc_wopcm_size - GUC_WOPCM_RESERVED) {
-		dev_err(i915->drm.dev, "WOPCM: no space for %s: %uK < %uK\n",
+		drm_err(&i915->drm, "WOPCM: no space for %s: %uK < %uK\n",
 			intel_uc_fw_type_repr(INTEL_UC_FW_TYPE_HUC),
 			(guc_wopcm_size - GUC_WOPCM_RESERVED) / SZ_1K,
 			huc_fw_size / 1024);
@@ -166,7 +166,7 @@ static inline bool __check_layout(struct drm_i915_private *i915, u32 wopcm_size,
 
 	size = wopcm_size - ctx_rsvd;
 	if (unlikely(range_overflows(guc_wopcm_base, guc_wopcm_size, size))) {
-		dev_err(i915->drm.dev,
+		drm_err(&i915->drm,
 			"WOPCM: invalid GuC region layout: %uK + %uK > %uK\n",
 			guc_wopcm_base / SZ_1K, guc_wopcm_size / SZ_1K,
 			size / SZ_1K);
@@ -175,7 +175,7 @@ static inline bool __check_layout(struct drm_i915_private *i915, u32 wopcm_size,
 
 	size = guc_fw_size + GUC_WOPCM_RESERVED + GUC_WOPCM_STACK_RESERVED;
 	if (unlikely(guc_wopcm_size < size)) {
-		dev_err(i915->drm.dev, "WOPCM: no space for %s: %uK < %uK\n",
+		drm_err(&i915->drm, "WOPCM: no space for %s: %uK < %uK\n",
 			intel_uc_fw_type_repr(INTEL_UC_FW_TYPE_GUC),
 			guc_wopcm_size / SZ_1K, size / SZ_1K);
 		return false;
@@ -183,7 +183,7 @@ static inline bool __check_layout(struct drm_i915_private *i915, u32 wopcm_size,
 
 	size = huc_fw_size + WOPCM_RESERVED_SIZE;
 	if (unlikely(guc_wopcm_base < size)) {
-		dev_err(i915->drm.dev, "WOPCM: no space for %s: %uK < %uK\n",
+		drm_err(&i915->drm, "WOPCM: no space for %s: %uK < %uK\n",
 			intel_uc_fw_type_repr(INTEL_UC_FW_TYPE_HUC),
 			guc_wopcm_base / SZ_1K, size / SZ_1K);
 		return false;
@@ -242,10 +242,8 @@ void intel_wopcm_init(struct intel_wopcm *wopcm)
 		return;
 
 	if (__wopcm_regs_locked(gt->uncore, &guc_wopcm_base, &guc_wopcm_size)) {
-		DRM_DEV_DEBUG_DRIVER(i915->drm.dev,
-				     "GuC WOPCM is already locked [%uK, %uK)\n",
-				     guc_wopcm_base / SZ_1K,
-				     guc_wopcm_size / SZ_1K);
+		drm_dbg(&i915->drm, "GuC WOPCM is already locked [%uK, %uK)\n",
+			guc_wopcm_base / SZ_1K, guc_wopcm_size / SZ_1K);
 		goto check;
 	}
 
@@ -266,8 +264,8 @@ void intel_wopcm_init(struct intel_wopcm *wopcm)
 	guc_wopcm_size = wopcm->size - ctx_rsvd - guc_wopcm_base;
 	guc_wopcm_size &= GUC_WOPCM_SIZE_MASK;
 
-	DRM_DEV_DEBUG_DRIVER(i915->drm.dev, "Calculated GuC WOPCM [%uK, %uK)\n",
-			     guc_wopcm_base / SZ_1K, guc_wopcm_size / SZ_1K);
+	drm_dbg(&i915->drm, "Calculated GuC WOPCM [%uK, %uK)\n",
+		guc_wopcm_base / SZ_1K, guc_wopcm_size / SZ_1K);
 
 check:
 	if (__check_layout(i915, wopcm->size, guc_wopcm_base, guc_wopcm_size,
diff --git a/drivers/gpu/drm/i915/oa/i915_oa_bdw.c b/drivers/gpu/drm/i915/oa/i915_oa_bdw.c
deleted file mode 100644
index 14da5c3b569d..000000000000
--- a/drivers/gpu/drm/i915/oa/i915_oa_bdw.c
+++ /dev/null
@@ -1,90 +0,0 @@
-// SPDX-License-Identifier: MIT
-/*
- * Copyright © 2018-2019 Intel Corporation
- *
- * Autogenerated file by GPU Top : https://github.com/rib/gputop
- * DO NOT EDIT manually!
- */
-
-#include <linux/sysfs.h>
-
-#include "i915_drv.h"
-#include "i915_oa_bdw.h"
-
-static const struct i915_oa_reg b_counter_config_test_oa[] = {
-	{ _MMIO(0x2740), 0x00000000 },
-	{ _MMIO(0x2744), 0x00800000 },
-	{ _MMIO(0x2714), 0xf0800000 },
-	{ _MMIO(0x2710), 0x00000000 },
-	{ _MMIO(0x2724), 0xf0800000 },
-	{ _MMIO(0x2720), 0x00000000 },
-	{ _MMIO(0x2770), 0x00000004 },
-	{ _MMIO(0x2774), 0x00000000 },
-	{ _MMIO(0x2778), 0x00000003 },
-	{ _MMIO(0x277c), 0x00000000 },
-	{ _MMIO(0x2780), 0x00000007 },
-	{ _MMIO(0x2784), 0x00000000 },
-	{ _MMIO(0x2788), 0x00100002 },
-	{ _MMIO(0x278c), 0x0000fff7 },
-	{ _MMIO(0x2790), 0x00100002 },
-	{ _MMIO(0x2794), 0x0000ffcf },
-	{ _MMIO(0x2798), 0x00100082 },
-	{ _MMIO(0x279c), 0x0000ffef },
-	{ _MMIO(0x27a0), 0x001000c2 },
-	{ _MMIO(0x27a4), 0x0000ffe7 },
-	{ _MMIO(0x27a8), 0x00100001 },
-	{ _MMIO(0x27ac), 0x0000ffe7 },
-};
-
-static const struct i915_oa_reg flex_eu_config_test_oa[] = {
-};
-
-static const struct i915_oa_reg mux_config_test_oa[] = {
-	{ _MMIO(0x9840), 0x000000a0 },
-	{ _MMIO(0x9888), 0x198b0000 },
-	{ _MMIO(0x9888), 0x078b0066 },
-	{ _MMIO(0x9888), 0x118b0000 },
-	{ _MMIO(0x9888), 0x258b0000 },
-	{ _MMIO(0x9888), 0x21850008 },
-	{ _MMIO(0x9888), 0x0d834000 },
-	{ _MMIO(0x9888), 0x07844000 },
-	{ _MMIO(0x9888), 0x17804000 },
-	{ _MMIO(0x9888), 0x21800000 },
-	{ _MMIO(0x9888), 0x4f800000 },
-	{ _MMIO(0x9888), 0x41800000 },
-	{ _MMIO(0x9888), 0x31800000 },
-	{ _MMIO(0x9840), 0x00000080 },
-};
-
-static ssize_t
-show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
-	return sprintf(buf, "1\n");
-}
-
-void
-i915_perf_load_test_config_bdw(struct drm_i915_private *dev_priv)
-{
-	strlcpy(dev_priv->perf.test_config.uuid,
-		"d6de6f55-e526-4f79-a6a6-d7315c09044e",
-		sizeof(dev_priv->perf.test_config.uuid));
-	dev_priv->perf.test_config.id = 1;
-
-	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
-	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
-
-	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
-	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
-
-	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
-	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
-
-	dev_priv->perf.test_config.sysfs_metric.name = "d6de6f55-e526-4f79-a6a6-d7315c09044e";
-	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
-
-	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
-
-	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
-	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
-	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
-}
diff --git a/drivers/gpu/drm/i915/oa/i915_oa_bdw.h b/drivers/gpu/drm/i915/oa/i915_oa_bdw.h
deleted file mode 100644
index 0cee3334f0a6..000000000000
--- a/drivers/gpu/drm/i915/oa/i915_oa_bdw.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright © 2018-2019 Intel Corporation
- *
- * Autogenerated file by GPU Top : https://github.com/rib/gputop
- * DO NOT EDIT manually!
- */
-
-#ifndef __I915_OA_BDW_H__
-#define __I915_OA_BDW_H__
-
-struct drm_i915_private;
-
-void i915_perf_load_test_config_bdw(struct drm_i915_private *dev_priv);
-
-#endif
diff --git a/drivers/gpu/drm/i915/oa/i915_oa_bxt.c b/drivers/gpu/drm/i915/oa/i915_oa_bxt.c
deleted file mode 100644
index 3e785bafcf99..000000000000
--- a/drivers/gpu/drm/i915/oa/i915_oa_bxt.c
+++ /dev/null
@@ -1,88 +0,0 @@
-// SPDX-License-Identifier: MIT
-/*
- * Copyright © 2018-2019 Intel Corporation
- *
- * Autogenerated file by GPU Top : https://github.com/rib/gputop
- * DO NOT EDIT manually!
- */
-
-#include <linux/sysfs.h>
-
-#include "i915_drv.h"
-#include "i915_oa_bxt.h"
-
-static const struct i915_oa_reg b_counter_config_test_oa[] = {
-	{ _MMIO(0x2740), 0x00000000 },
-	{ _MMIO(0x2744), 0x00800000 },
-	{ _MMIO(0x2714), 0xf0800000 },
-	{ _MMIO(0x2710), 0x00000000 },
-	{ _MMIO(0x2724), 0xf0800000 },
-	{ _MMIO(0x2720), 0x00000000 },
-	{ _MMIO(0x2770), 0x00000004 },
-	{ _MMIO(0x2774), 0x00000000 },
-	{ _MMIO(0x2778), 0x00000003 },
-	{ _MMIO(0x277c), 0x00000000 },
-	{ _MMIO(0x2780), 0x00000007 },
-	{ _MMIO(0x2784), 0x00000000 },
-	{ _MMIO(0x2788), 0x00100002 },
-	{ _MMIO(0x278c), 0x0000fff7 },
-	{ _MMIO(0x2790), 0x00100002 },
-	{ _MMIO(0x2794), 0x0000ffcf },
-	{ _MMIO(0x2798), 0x00100082 },
-	{ _MMIO(0x279c), 0x0000ffef },
-	{ _MMIO(0x27a0), 0x001000c2 },
-	{ _MMIO(0x27a4), 0x0000ffe7 },
-	{ _MMIO(0x27a8), 0x00100001 },
-	{ _MMIO(0x27ac), 0x0000ffe7 },
-};
-
-static const struct i915_oa_reg flex_eu_config_test_oa[] = {
-};
-
-static const struct i915_oa_reg mux_config_test_oa[] = {
-	{ _MMIO(0x9840), 0x00000080 },
-	{ _MMIO(0x9888), 0x19800000 },
-	{ _MMIO(0x9888), 0x07800063 },
-	{ _MMIO(0x9888), 0x11800000 },
-	{ _MMIO(0x9888), 0x23810008 },
-	{ _MMIO(0x9888), 0x1d950400 },
-	{ _MMIO(0x9888), 0x0f922000 },
-	{ _MMIO(0x9888), 0x1f908000 },
-	{ _MMIO(0x9888), 0x37900000 },
-	{ _MMIO(0x9888), 0x55900000 },
-	{ _MMIO(0x9888), 0x47900000 },
-	{ _MMIO(0x9888), 0x33900000 },
-};
-
-static ssize_t
-show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
-	return sprintf(buf, "1\n");
-}
-
-void
-i915_perf_load_test_config_bxt(struct drm_i915_private *dev_priv)
-{
-	strlcpy(dev_priv->perf.test_config.uuid,
-		"5ee72f5c-092f-421e-8b70-225f7c3e9612",
-		sizeof(dev_priv->perf.test_config.uuid));
-	dev_priv->perf.test_config.id = 1;
-
-	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
-	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
-
-	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
-	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
-
-	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
-	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
-
-	dev_priv->perf.test_config.sysfs_metric.name = "5ee72f5c-092f-421e-8b70-225f7c3e9612";
-	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
-
-	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
-
-	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
-	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
-	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
-}
diff --git a/drivers/gpu/drm/i915/oa/i915_oa_bxt.h b/drivers/gpu/drm/i915/oa/i915_oa_bxt.h
deleted file mode 100644
index 0bdf391323ec..000000000000
--- a/drivers/gpu/drm/i915/oa/i915_oa_bxt.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright © 2018-2019 Intel Corporation
- *
- * Autogenerated file by GPU Top : https://github.com/rib/gputop
- * DO NOT EDIT manually!
- */
-
-#ifndef __I915_OA_BXT_H__
-#define __I915_OA_BXT_H__
-
-struct drm_i915_private;
-
-void i915_perf_load_test_config_bxt(struct drm_i915_private *dev_priv);
-
-#endif
diff --git a/drivers/gpu/drm/i915/oa/i915_oa_cflgt2.c b/drivers/gpu/drm/i915/oa/i915_oa_cflgt2.c
deleted file mode 100644
index 0ea86f70a06c..000000000000
--- a/drivers/gpu/drm/i915/oa/i915_oa_cflgt2.c
+++ /dev/null
@@ -1,89 +0,0 @@
-// SPDX-License-Identifier: MIT
-/*
- * Copyright © 2018-2019 Intel Corporation
- *
- * Autogenerated file by GPU Top : https://github.com/rib/gputop
- * DO NOT EDIT manually!
- */
-
-#include <linux/sysfs.h>
-
-#include "i915_drv.h"
-#include "i915_oa_cflgt2.h"
-
-static const struct i915_oa_reg b_counter_config_test_oa[] = {
-	{ _MMIO(0x2740), 0x00000000 },
-	{ _MMIO(0x2744), 0x00800000 },
-	{ _MMIO(0x2714), 0xf0800000 },
-	{ _MMIO(0x2710), 0x00000000 },
-	{ _MMIO(0x2724), 0xf0800000 },
-	{ _MMIO(0x2720), 0x00000000 },
-	{ _MMIO(0x2770), 0x00000004 },
-	{ _MMIO(0x2774), 0x00000000 },
-	{ _MMIO(0x2778), 0x00000003 },
-	{ _MMIO(0x277c), 0x00000000 },
-	{ _MMIO(0x2780), 0x00000007 },
-	{ _MMIO(0x2784), 0x00000000 },
-	{ _MMIO(0x2788), 0x00100002 },
-	{ _MMIO(0x278c), 0x0000fff7 },
-	{ _MMIO(0x2790), 0x00100002 },
-	{ _MMIO(0x2794), 0x0000ffcf },
-	{ _MMIO(0x2798), 0x00100082 },
-	{ _MMIO(0x279c), 0x0000ffef },
-	{ _MMIO(0x27a0), 0x001000c2 },
-	{ _MMIO(0x27a4), 0x0000ffe7 },
-	{ _MMIO(0x27a8), 0x00100001 },
-	{ _MMIO(0x27ac), 0x0000ffe7 },
-};
-
-static const struct i915_oa_reg flex_eu_config_test_oa[] = {
-};
-
-static const struct i915_oa_reg mux_config_test_oa[] = {
-	{ _MMIO(0x9840), 0x00000080 },
-	{ _MMIO(0x9888), 0x11810000 },
-	{ _MMIO(0x9888), 0x07810013 },
-	{ _MMIO(0x9888), 0x1f810000 },
-	{ _MMIO(0x9888), 0x1d810000 },
-	{ _MMIO(0x9888), 0x1b930040 },
-	{ _MMIO(0x9888), 0x07e54000 },
-	{ _MMIO(0x9888), 0x1f908000 },
-	{ _MMIO(0x9888), 0x11900000 },
-	{ _MMIO(0x9888), 0x37900000 },
-	{ _MMIO(0x9888), 0x53900000 },
-	{ _MMIO(0x9888), 0x45900000 },
-	{ _MMIO(0x9888), 0x33900000 },
-};
-
-static ssize_t
-show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
-	return sprintf(buf, "1\n");
-}
-
-void
-i915_perf_load_test_config_cflgt2(struct drm_i915_private *dev_priv)
-{
-	strlcpy(dev_priv->perf.test_config.uuid,
-		"74fb4902-d3d3-4237-9e90-cbdc68d0a446",
-		sizeof(dev_priv->perf.test_config.uuid));
-	dev_priv->perf.test_config.id = 1;
-
-	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
-	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
-
-	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
-	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
-
-	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
-	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
-
-	dev_priv->perf.test_config.sysfs_metric.name = "74fb4902-d3d3-4237-9e90-cbdc68d0a446";
-	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
-
-	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
-
-	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
-	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
-	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
-}
diff --git a/drivers/gpu/drm/i915/oa/i915_oa_cflgt2.h b/drivers/gpu/drm/i915/oa/i915_oa_cflgt2.h
deleted file mode 100644
index 6b862280ab78..000000000000
--- a/drivers/gpu/drm/i915/oa/i915_oa_cflgt2.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright © 2018-2019 Intel Corporation
- *
- * Autogenerated file by GPU Top : https://github.com/rib/gputop
- * DO NOT EDIT manually!
- */
-
-#ifndef __I915_OA_CFLGT2_H__
-#define __I915_OA_CFLGT2_H__
-
-struct drm_i915_private;
-
-void i915_perf_load_test_config_cflgt2(struct drm_i915_private *dev_priv);
-
-#endif
diff --git a/drivers/gpu/drm/i915/oa/i915_oa_cflgt3.c b/drivers/gpu/drm/i915/oa/i915_oa_cflgt3.c
deleted file mode 100644
index fc632dd890bf..000000000000
--- a/drivers/gpu/drm/i915/oa/i915_oa_cflgt3.c
+++ /dev/null
@@ -1,89 +0,0 @@
-// SPDX-License-Identifier: MIT
-/*
- * Copyright © 2018-2019 Intel Corporation
- *
- * Autogenerated file by GPU Top : https://github.com/rib/gputop
- * DO NOT EDIT manually!
- */
-
-#include <linux/sysfs.h>
-
-#include "i915_drv.h"
-#include "i915_oa_cflgt3.h"
-
-static const struct i915_oa_reg b_counter_config_test_oa[] = {
-	{ _MMIO(0x2740), 0x00000000 },
-	{ _MMIO(0x2744), 0x00800000 },
-	{ _MMIO(0x2714), 0xf0800000 },
-	{ _MMIO(0x2710), 0x00000000 },
-	{ _MMIO(0x2724), 0xf0800000 },
-	{ _MMIO(0x2720), 0x00000000 },
-	{ _MMIO(0x2770), 0x00000004 },
-	{ _MMIO(0x2774), 0x00000000 },
-	{ _MMIO(0x2778), 0x00000003 },
-	{ _MMIO(0x277c), 0x00000000 },
-	{ _MMIO(0x2780), 0x00000007 },
-	{ _MMIO(0x2784), 0x00000000 },
-	{ _MMIO(0x2788), 0x00100002 },
-	{ _MMIO(0x278c), 0x0000fff7 },
-	{ _MMIO(0x2790), 0x00100002 },
-	{ _MMIO(0x2794), 0x0000ffcf },
-	{ _MMIO(0x2798), 0x00100082 },
-	{ _MMIO(0x279c), 0x0000ffef },
-	{ _MMIO(0x27a0), 0x001000c2 },
-	{ _MMIO(0x27a4), 0x0000ffe7 },
-	{ _MMIO(0x27a8), 0x00100001 },
-	{ _MMIO(0x27ac), 0x0000ffe7 },
-};
-
-static const struct i915_oa_reg flex_eu_config_test_oa[] = {
-};
-
-static const struct i915_oa_reg mux_config_test_oa[] = {
-	{ _MMIO(0x9840), 0x00000080 },
-	{ _MMIO(0x9888), 0x11810000 },
-	{ _MMIO(0x9888), 0x07810013 },
-	{ _MMIO(0x9888), 0x1f810000 },
-	{ _MMIO(0x9888), 0x1d810000 },
-	{ _MMIO(0x9888), 0x1b930040 },
-	{ _MMIO(0x9888), 0x07e54000 },
-	{ _MMIO(0x9888), 0x1f908000 },
-	{ _MMIO(0x9888), 0x11900000 },
-	{ _MMIO(0x9888), 0x37900000 },
-	{ _MMIO(0x9888), 0x53900000 },
-	{ _MMIO(0x9888), 0x45900000 },
-	{ _MMIO(0x9888), 0x33900000 },
-};
-
-static ssize_t
-show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
-	return sprintf(buf, "1\n");
-}
-
-void
-i915_perf_load_test_config_cflgt3(struct drm_i915_private *dev_priv)
-{
-	strlcpy(dev_priv->perf.test_config.uuid,
-		"577e8e2c-3fa0-4875-8743-3538d585e3b0",
-		sizeof(dev_priv->perf.test_config.uuid));
-	dev_priv->perf.test_config.id = 1;
-
-	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
-	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
-
-	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
-	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
-
-	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
-	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
-
-	dev_priv->perf.test_config.sysfs_metric.name = "577e8e2c-3fa0-4875-8743-3538d585e3b0";
-	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
-
-	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
-
-	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
-	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
-	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
-}
diff --git a/drivers/gpu/drm/i915/oa/i915_oa_cflgt3.h b/drivers/gpu/drm/i915/oa/i915_oa_cflgt3.h
deleted file mode 100644
index 4ca9d8f89b2f..000000000000
--- a/drivers/gpu/drm/i915/oa/i915_oa_cflgt3.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright © 2018-2019 Intel Corporation
- *
- * Autogenerated file by GPU Top : https://github.com/rib/gputop
- * DO NOT EDIT manually!
- */
-
-#ifndef __I915_OA_CFLGT3_H__
-#define __I915_OA_CFLGT3_H__
-
-struct drm_i915_private;
-
-void i915_perf_load_test_config_cflgt3(struct drm_i915_private *dev_priv);
-
-#endif
diff --git a/drivers/gpu/drm/i915/oa/i915_oa_chv.c b/drivers/gpu/drm/i915/oa/i915_oa_chv.c
deleted file mode 100644
index 6cd4e9921a8a..000000000000
--- a/drivers/gpu/drm/i915/oa/i915_oa_chv.c
+++ /dev/null
@@ -1,89 +0,0 @@
-// SPDX-License-Identifier: MIT
-/*
- * Copyright © 2018-2019 Intel Corporation
- *
- * Autogenerated file by GPU Top : https://github.com/rib/gputop
- * DO NOT EDIT manually!
- */
-
-#include <linux/sysfs.h>
-
-#include "i915_drv.h"
-#include "i915_oa_chv.h"
-
-static const struct i915_oa_reg b_counter_config_test_oa[] = {
-	{ _MMIO(0x2740), 0x00000000 },
-	{ _MMIO(0x2744), 0x00800000 },
-	{ _MMIO(0x2714), 0xf0800000 },
-	{ _MMIO(0x2710), 0x00000000 },
-	{ _MMIO(0x2724), 0xf0800000 },
-	{ _MMIO(0x2720), 0x00000000 },
-	{ _MMIO(0x2770), 0x00000004 },
-	{ _MMIO(0x2774), 0x00000000 },
-	{ _MMIO(0x2778), 0x00000003 },
-	{ _MMIO(0x277c), 0x00000000 },
-	{ _MMIO(0x2780), 0x00000007 },
-	{ _MMIO(0x2784), 0x00000000 },
-	{ _MMIO(0x2788), 0x00100002 },
-	{ _MMIO(0x278c), 0x0000fff7 },
-	{ _MMIO(0x2790), 0x00100002 },
-	{ _MMIO(0x2794), 0x0000ffcf },
-	{ _MMIO(0x2798), 0x00100082 },
-	{ _MMIO(0x279c), 0x0000ffef },
-	{ _MMIO(0x27a0), 0x001000c2 },
-	{ _MMIO(0x27a4), 0x0000ffe7 },
-	{ _MMIO(0x27a8), 0x00100001 },
-	{ _MMIO(0x27ac), 0x0000ffe7 },
-};
-
-static const struct i915_oa_reg flex_eu_config_test_oa[] = {
-};
-
-static const struct i915_oa_reg mux_config_test_oa[] = {
-	{ _MMIO(0x9840), 0x000000a0 },
-	{ _MMIO(0x9888), 0x59800000 },
-	{ _MMIO(0x9888), 0x59800001 },
-	{ _MMIO(0x9888), 0x338b0000 },
-	{ _MMIO(0x9888), 0x258b0066 },
-	{ _MMIO(0x9888), 0x058b0000 },
-	{ _MMIO(0x9888), 0x038b0000 },
-	{ _MMIO(0x9888), 0x03844000 },
-	{ _MMIO(0x9888), 0x47800080 },
-	{ _MMIO(0x9888), 0x57800000 },
-	{ _MMIO(0x1823a4), 0x00000000 },
-	{ _MMIO(0x9888), 0x59800000 },
-	{ _MMIO(0x9840), 0x00000080 },
-};
-
-static ssize_t
-show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
-	return sprintf(buf, "1\n");
-}
-
-void
-i915_perf_load_test_config_chv(struct drm_i915_private *dev_priv)
-{
-	strlcpy(dev_priv->perf.test_config.uuid,
-		"4a534b07-cba3-414d-8d60-874830e883aa",
-		sizeof(dev_priv->perf.test_config.uuid));
-	dev_priv->perf.test_config.id = 1;
-
-	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
-	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
-
-	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
-	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
-
-	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
-	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
-
-	dev_priv->perf.test_config.sysfs_metric.name = "4a534b07-cba3-414d-8d60-874830e883aa";
-	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
-
-	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
-
-	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
-	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
-	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
-}
diff --git a/drivers/gpu/drm/i915/oa/i915_oa_chv.h b/drivers/gpu/drm/i915/oa/i915_oa_chv.h
deleted file mode 100644
index 3cac7bbc9c71..000000000000
--- a/drivers/gpu/drm/i915/oa/i915_oa_chv.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright © 2018-2019 Intel Corporation
- *
- * Autogenerated file by GPU Top : https://github.com/rib/gputop
- * DO NOT EDIT manually!
- */
-
-#ifndef __I915_OA_CHV_H__
-#define __I915_OA_CHV_H__
-
-struct drm_i915_private;
-
-void i915_perf_load_test_config_chv(struct drm_i915_private *dev_priv);
-
-#endif
diff --git a/drivers/gpu/drm/i915/oa/i915_oa_cnl.c b/drivers/gpu/drm/i915/oa/i915_oa_cnl.c
deleted file mode 100644
index 1041e8914993..000000000000
--- a/drivers/gpu/drm/i915/oa/i915_oa_cnl.c
+++ /dev/null
@@ -1,101 +0,0 @@
-// SPDX-License-Identifier: MIT
-/*
- * Copyright © 2018-2019 Intel Corporation
- *
- * Autogenerated file by GPU Top : https://github.com/rib/gputop
- * DO NOT EDIT manually!
- */
-
-#include <linux/sysfs.h>
-
-#include "i915_drv.h"
-#include "i915_oa_cnl.h"
-
-static const struct i915_oa_reg b_counter_config_test_oa[] = {
-	{ _MMIO(0x2740), 0x00000000 },
-	{ _MMIO(0x2710), 0x00000000 },
-	{ _MMIO(0x2714), 0xf0800000 },
-	{ _MMIO(0x2720), 0x00000000 },
-	{ _MMIO(0x2724), 0xf0800000 },
-	{ _MMIO(0x2770), 0x00000004 },
-	{ _MMIO(0x2774), 0x0000ffff },
-	{ _MMIO(0x2778), 0x00000003 },
-	{ _MMIO(0x277c), 0x0000ffff },
-	{ _MMIO(0x2780), 0x00000007 },
-	{ _MMIO(0x2784), 0x0000ffff },
-	{ _MMIO(0x2788), 0x00100002 },
-	{ _MMIO(0x278c), 0x0000fff7 },
-	{ _MMIO(0x2790), 0x00100002 },
-	{ _MMIO(0x2794), 0x0000ffcf },
-	{ _MMIO(0x2798), 0x00100082 },
-	{ _MMIO(0x279c), 0x0000ffef },
-	{ _MMIO(0x27a0), 0x001000c2 },
-	{ _MMIO(0x27a4), 0x0000ffe7 },
-	{ _MMIO(0x27a8), 0x00100001 },
-	{ _MMIO(0x27ac), 0x0000ffe7 },
-};
-
-static const struct i915_oa_reg flex_eu_config_test_oa[] = {
-};
-
-static const struct i915_oa_reg mux_config_test_oa[] = {
-	{ _MMIO(0xd04), 0x00000200 },
-	{ _MMIO(0x9884), 0x00000007 },
-	{ _MMIO(0x9888), 0x17060000 },
-	{ _MMIO(0x9840), 0x00000000 },
-	{ _MMIO(0x9884), 0x00000007 },
-	{ _MMIO(0x9888), 0x13034000 },
-	{ _MMIO(0x9884), 0x00000007 },
-	{ _MMIO(0x9888), 0x07060066 },
-	{ _MMIO(0x9884), 0x00000007 },
-	{ _MMIO(0x9888), 0x05060000 },
-	{ _MMIO(0x9884), 0x00000007 },
-	{ _MMIO(0x9888), 0x0f080040 },
-	{ _MMIO(0x9884), 0x00000007 },
-	{ _MMIO(0x9888), 0x07091000 },
-	{ _MMIO(0x9884), 0x00000007 },
-	{ _MMIO(0x9888), 0x0f041000 },
-	{ _MMIO(0x9884), 0x00000007 },
-	{ _MMIO(0x9888), 0x1d004000 },
-	{ _MMIO(0x9884), 0x00000007 },
-	{ _MMIO(0x9888), 0x35000000 },
-	{ _MMIO(0x9884), 0x00000007 },
-	{ _MMIO(0x9888), 0x49000000 },
-	{ _MMIO(0x9884), 0x00000007 },
-	{ _MMIO(0x9888), 0x3d000000 },
-	{ _MMIO(0x9884), 0x00000007 },
-	{ _MMIO(0x9888), 0x31000000 },
-};
-
-static ssize_t
-show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
-	return sprintf(buf, "1\n");
-}
-
-void
-i915_perf_load_test_config_cnl(struct drm_i915_private *dev_priv)
-{
-	strlcpy(dev_priv->perf.test_config.uuid,
-		"db41edd4-d8e7-4730-ad11-b9a2d6833503",
-		sizeof(dev_priv->perf.test_config.uuid));
-	dev_priv->perf.test_config.id = 1;
-
-	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
-	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
-
-	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
-	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
-
-	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
-	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
-
-	dev_priv->perf.test_config.sysfs_metric.name = "db41edd4-d8e7-4730-ad11-b9a2d6833503";
-	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
-
-	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
-
-	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
-	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
-	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
-}
diff --git a/drivers/gpu/drm/i915/oa/i915_oa_cnl.h b/drivers/gpu/drm/i915/oa/i915_oa_cnl.h
deleted file mode 100644
index db379f5fcbb9..000000000000
--- a/drivers/gpu/drm/i915/oa/i915_oa_cnl.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright © 2018-2019 Intel Corporation
- *
- * Autogenerated file by GPU Top : https://github.com/rib/gputop
- * DO NOT EDIT manually!
- */
-
-#ifndef __I915_OA_CNL_H__
-#define __I915_OA_CNL_H__
-
-struct drm_i915_private;
-
-void i915_perf_load_test_config_cnl(struct drm_i915_private *dev_priv);
-
-#endif
diff --git a/drivers/gpu/drm/i915/oa/i915_oa_glk.c b/drivers/gpu/drm/i915/oa/i915_oa_glk.c
deleted file mode 100644
index bd15ebe9aeeb..000000000000
--- a/drivers/gpu/drm/i915/oa/i915_oa_glk.c
+++ /dev/null
@@ -1,88 +0,0 @@
-// SPDX-License-Identifier: MIT
-/*
- * Copyright © 2018-2019 Intel Corporation
- *
- * Autogenerated file by GPU Top : https://github.com/rib/gputop
- * DO NOT EDIT manually!
- */
-
-#include <linux/sysfs.h>
-
-#include "i915_drv.h"
-#include "i915_oa_glk.h"
-
-static const struct i915_oa_reg b_counter_config_test_oa[] = {
-	{ _MMIO(0x2740), 0x00000000 },
-	{ _MMIO(0x2744), 0x00800000 },
-	{ _MMIO(0x2714), 0xf0800000 },
-	{ _MMIO(0x2710), 0x00000000 },
-	{ _MMIO(0x2724), 0xf0800000 },
-	{ _MMIO(0x2720), 0x00000000 },
-	{ _MMIO(0x2770), 0x00000004 },
-	{ _MMIO(0x2774), 0x00000000 },
-	{ _MMIO(0x2778), 0x00000003 },
-	{ _MMIO(0x277c), 0x00000000 },
-	{ _MMIO(0x2780), 0x00000007 },
-	{ _MMIO(0x2784), 0x00000000 },
-	{ _MMIO(0x2788), 0x00100002 },
-	{ _MMIO(0x278c), 0x0000fff7 },
-	{ _MMIO(0x2790), 0x00100002 },
-	{ _MMIO(0x2794), 0x0000ffcf },
-	{ _MMIO(0x2798), 0x00100082 },
-	{ _MMIO(0x279c), 0x0000ffef },
-	{ _MMIO(0x27a0), 0x001000c2 },
-	{ _MMIO(0x27a4), 0x0000ffe7 },
-	{ _MMIO(0x27a8), 0x00100001 },
-	{ _MMIO(0x27ac), 0x0000ffe7 },
-};
-
-static const struct i915_oa_reg flex_eu_config_test_oa[] = {
-};
-
-static const struct i915_oa_reg mux_config_test_oa[] = {
-	{ _MMIO(0x9840), 0x00000080 },
-	{ _MMIO(0x9888), 0x19800000 },
-	{ _MMIO(0x9888), 0x07800063 },
-	{ _MMIO(0x9888), 0x11800000 },
-	{ _MMIO(0x9888), 0x23810008 },
-	{ _MMIO(0x9888), 0x1d950400 },
-	{ _MMIO(0x9888), 0x0f922000 },
-	{ _MMIO(0x9888), 0x1f908000 },
-	{ _MMIO(0x9888), 0x37900000 },
-	{ _MMIO(0x9888), 0x55900000 },
-	{ _MMIO(0x9888), 0x47900000 },
-	{ _MMIO(0x9888), 0x33900000 },
-};
-
-static ssize_t
-show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
-	return sprintf(buf, "1\n");
-}
-
-void
-i915_perf_load_test_config_glk(struct drm_i915_private *dev_priv)
-{
-	strlcpy(dev_priv->perf.test_config.uuid,
-		"dd3fd789-e783-4204-8cd0-b671bbccb0cf",
-		sizeof(dev_priv->perf.test_config.uuid));
-	dev_priv->perf.test_config.id = 1;
-
-	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
-	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
-
-	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
-	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
-
-	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
-	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
-
-	dev_priv->perf.test_config.sysfs_metric.name = "dd3fd789-e783-4204-8cd0-b671bbccb0cf";
-	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
-
-	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
-
-	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
-	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
-	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
-}
diff --git a/drivers/gpu/drm/i915/oa/i915_oa_glk.h b/drivers/gpu/drm/i915/oa/i915_oa_glk.h
deleted file mode 100644
index 779f343efd11..000000000000
--- a/drivers/gpu/drm/i915/oa/i915_oa_glk.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright © 2018-2019 Intel Corporation
- *
- * Autogenerated file by GPU Top : https://github.com/rib/gputop
- * DO NOT EDIT manually!
- */
-
-#ifndef __I915_OA_GLK_H__
-#define __I915_OA_GLK_H__
-
-struct drm_i915_private;
-
-void i915_perf_load_test_config_glk(struct drm_i915_private *dev_priv);
-
-#endif
diff --git a/drivers/gpu/drm/i915/oa/i915_oa_hsw.c b/drivers/gpu/drm/i915/oa/i915_oa_hsw.c
deleted file mode 100644
index 133721a8619f..000000000000
--- a/drivers/gpu/drm/i915/oa/i915_oa_hsw.c
+++ /dev/null
@@ -1,118 +0,0 @@
-// SPDX-License-Identifier: MIT
-/*
- * Copyright © 2018-2019 Intel Corporation
- *
- * Autogenerated file by GPU Top : https://github.com/rib/gputop
- * DO NOT EDIT manually!
- */
-
-#include <linux/sysfs.h>
-
-#include "i915_drv.h"
-#include "i915_oa_hsw.h"
-
-static const struct i915_oa_reg b_counter_config_render_basic[] = {
-	{ _MMIO(0x2724), 0x00800000 },
-	{ _MMIO(0x2720), 0x00000000 },
-	{ _MMIO(0x2714), 0x00800000 },
-	{ _MMIO(0x2710), 0x00000000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_render_basic[] = {
-};
-
-static const struct i915_oa_reg mux_config_render_basic[] = {
-	{ _MMIO(0x9840), 0x00000080 },
-	{ _MMIO(0x253a4), 0x01600000 },
-	{ _MMIO(0x25440), 0x00100000 },
-	{ _MMIO(0x25128), 0x00000000 },
-	{ _MMIO(0x2691c), 0x00000800 },
-	{ _MMIO(0x26aa0), 0x01500000 },
-	{ _MMIO(0x26b9c), 0x00006000 },
-	{ _MMIO(0x2791c), 0x00000800 },
-	{ _MMIO(0x27aa0), 0x01500000 },
-	{ _MMIO(0x27b9c), 0x00006000 },
-	{ _MMIO(0x2641c), 0x00000400 },
-	{ _MMIO(0x25380), 0x00000010 },
-	{ _MMIO(0x2538c), 0x00000000 },
-	{ _MMIO(0x25384), 0x0800aaaa },
-	{ _MMIO(0x25400), 0x00000004 },
-	{ _MMIO(0x2540c), 0x06029000 },
-	{ _MMIO(0x25410), 0x00000002 },
-	{ _MMIO(0x25404), 0x5c30ffff },
-	{ _MMIO(0x25100), 0x00000016 },
-	{ _MMIO(0x25110), 0x00000400 },
-	{ _MMIO(0x25104), 0x00000000 },
-	{ _MMIO(0x26804), 0x00001211 },
-	{ _MMIO(0x26884), 0x00000100 },
-	{ _MMIO(0x26900), 0x00000002 },
-	{ _MMIO(0x26908), 0x00700000 },
-	{ _MMIO(0x26904), 0x00000000 },
-	{ _MMIO(0x26984), 0x00001022 },
-	{ _MMIO(0x26a04), 0x00000011 },
-	{ _MMIO(0x26a80), 0x00000006 },
-	{ _MMIO(0x26a88), 0x00000c02 },
-	{ _MMIO(0x26a84), 0x00000000 },
-	{ _MMIO(0x26b04), 0x00001000 },
-	{ _MMIO(0x26b80), 0x00000002 },
-	{ _MMIO(0x26b8c), 0x00000007 },
-	{ _MMIO(0x26b84), 0x00000000 },
-	{ _MMIO(0x27804), 0x00004844 },
-	{ _MMIO(0x27884), 0x00000400 },
-	{ _MMIO(0x27900), 0x00000002 },
-	{ _MMIO(0x27908), 0x0e000000 },
-	{ _MMIO(0x27904), 0x00000000 },
-	{ _MMIO(0x27984), 0x00004088 },
-	{ _MMIO(0x27a04), 0x00000044 },
-	{ _MMIO(0x27a80), 0x00000006 },
-	{ _MMIO(0x27a88), 0x00018040 },
-	{ _MMIO(0x27a84), 0x00000000 },
-	{ _MMIO(0x27b04), 0x00004000 },
-	{ _MMIO(0x27b80), 0x00000002 },
-	{ _MMIO(0x27b8c), 0x000000e0 },
-	{ _MMIO(0x27b84), 0x00000000 },
-	{ _MMIO(0x26104), 0x00002222 },
-	{ _MMIO(0x26184), 0x0c006666 },
-	{ _MMIO(0x26284), 0x04000000 },
-	{ _MMIO(0x26304), 0x04000000 },
-	{ _MMIO(0x26400), 0x00000002 },
-	{ _MMIO(0x26410), 0x000000a0 },
-	{ _MMIO(0x26404), 0x00000000 },
-	{ _MMIO(0x25420), 0x04108020 },
-	{ _MMIO(0x25424), 0x1284a420 },
-	{ _MMIO(0x2541c), 0x00000000 },
-	{ _MMIO(0x25428), 0x00042049 },
-};
-
-static ssize_t
-show_render_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
-	return sprintf(buf, "1\n");
-}
-
-void
-i915_perf_load_test_config_hsw(struct drm_i915_private *dev_priv)
-{
-	strlcpy(dev_priv->perf.test_config.uuid,
-		"403d8832-1a27-4aa6-a64e-f5389ce7b212",
-		sizeof(dev_priv->perf.test_config.uuid));
-	dev_priv->perf.test_config.id = 1;
-
-	dev_priv->perf.test_config.mux_regs = mux_config_render_basic;
-	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_render_basic);
-
-	dev_priv->perf.test_config.b_counter_regs = b_counter_config_render_basic;
-	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_render_basic);
-
-	dev_priv->perf.test_config.flex_regs = flex_eu_config_render_basic;
-	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_render_basic);
-
-	dev_priv->perf.test_config.sysfs_metric.name = "403d8832-1a27-4aa6-a64e-f5389ce7b212";
-	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
-
-	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
-
-	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
-	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
-	dev_priv->perf.test_config.sysfs_metric_id.show = show_render_basic_id;
-}
diff --git a/drivers/gpu/drm/i915/oa/i915_oa_hsw.h b/drivers/gpu/drm/i915/oa/i915_oa_hsw.h
deleted file mode 100644
index ba97f732f136..000000000000
--- a/drivers/gpu/drm/i915/oa/i915_oa_hsw.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright © 2018-2019 Intel Corporation
- *
- * Autogenerated file by GPU Top : https://github.com/rib/gputop
- * DO NOT EDIT manually!
- */
-
-#ifndef __I915_OA_HSW_H__
-#define __I915_OA_HSW_H__
-
-struct drm_i915_private;
-
-void i915_perf_load_test_config_hsw(struct drm_i915_private *dev_priv);
-
-#endif
diff --git a/drivers/gpu/drm/i915/oa/i915_oa_icl.c b/drivers/gpu/drm/i915/oa/i915_oa_icl.c
deleted file mode 100644
index 2d92041b754f..000000000000
--- a/drivers/gpu/drm/i915/oa/i915_oa_icl.c
+++ /dev/null
@@ -1,98 +0,0 @@
-// SPDX-License-Identifier: MIT
-/*
- * Copyright © 2018-2019 Intel Corporation
- *
- * Autogenerated file by GPU Top : https://github.com/rib/gputop
- * DO NOT EDIT manually!
- */
-
-#include <linux/sysfs.h>
-
-#include "i915_drv.h"
-#include "i915_oa_icl.h"
-
-static const struct i915_oa_reg b_counter_config_test_oa[] = {
-	{ _MMIO(0x2740), 0x00000000 },
-	{ _MMIO(0x2710), 0x00000000 },
-	{ _MMIO(0x2714), 0xf0800000 },
-	{ _MMIO(0x2720), 0x00000000 },
-	{ _MMIO(0x2724), 0xf0800000 },
-	{ _MMIO(0x2770), 0x00000004 },
-	{ _MMIO(0x2774), 0x0000ffff },
-	{ _MMIO(0x2778), 0x00000003 },
-	{ _MMIO(0x277c), 0x0000ffff },
-	{ _MMIO(0x2780), 0x00000007 },
-	{ _MMIO(0x2784), 0x0000ffff },
-	{ _MMIO(0x2788), 0x00100002 },
-	{ _MMIO(0x278c), 0x0000fff7 },
-	{ _MMIO(0x2790), 0x00100002 },
-	{ _MMIO(0x2794), 0x0000ffcf },
-	{ _MMIO(0x2798), 0x00100082 },
-	{ _MMIO(0x279c), 0x0000ffef },
-	{ _MMIO(0x27a0), 0x001000c2 },
-	{ _MMIO(0x27a4), 0x0000ffe7 },
-	{ _MMIO(0x27a8), 0x00100001 },
-	{ _MMIO(0x27ac), 0x0000ffe7 },
-};
-
-static const struct i915_oa_reg flex_eu_config_test_oa[] = {
-};
-
-static const struct i915_oa_reg mux_config_test_oa[] = {
-	{ _MMIO(0xd04), 0x00000200 },
-	{ _MMIO(0x9840), 0x00000000 },
-	{ _MMIO(0x9884), 0x00000000 },
-	{ _MMIO(0x9888), 0x10060000 },
-	{ _MMIO(0x9888), 0x22060000 },
-	{ _MMIO(0x9888), 0x16060000 },
-	{ _MMIO(0x9888), 0x24060000 },
-	{ _MMIO(0x9888), 0x18060000 },
-	{ _MMIO(0x9888), 0x1a060000 },
-	{ _MMIO(0x9888), 0x12060000 },
-	{ _MMIO(0x9888), 0x14060000 },
-	{ _MMIO(0x9888), 0x10060000 },
-	{ _MMIO(0x9888), 0x22060000 },
-	{ _MMIO(0x9884), 0x00000003 },
-	{ _MMIO(0x9888), 0x16130000 },
-	{ _MMIO(0x9888), 0x24000001 },
-	{ _MMIO(0x9888), 0x0e130056 },
-	{ _MMIO(0x9888), 0x10130000 },
-	{ _MMIO(0x9888), 0x1a130000 },
-	{ _MMIO(0x9888), 0x541f0001 },
-	{ _MMIO(0x9888), 0x181f0000 },
-	{ _MMIO(0x9888), 0x4c1f0000 },
-	{ _MMIO(0x9888), 0x301f0000 },
-};
-
-static ssize_t
-show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
-	return sprintf(buf, "1\n");
-}
-
-void
-i915_perf_load_test_config_icl(struct drm_i915_private *dev_priv)
-{
-	strlcpy(dev_priv->perf.test_config.uuid,
-		"a291665e-244b-4b76-9b9a-01de9d3c8068",
-		sizeof(dev_priv->perf.test_config.uuid));
-	dev_priv->perf.test_config.id = 1;
-
-	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
-	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
-
-	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
-	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
-
-	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
-	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
-
-	dev_priv->perf.test_config.sysfs_metric.name = "a291665e-244b-4b76-9b9a-01de9d3c8068";
-	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
-
-	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
-
-	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
-	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
-	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
-}
diff --git a/drivers/gpu/drm/i915/oa/i915_oa_icl.h b/drivers/gpu/drm/i915/oa/i915_oa_icl.h
deleted file mode 100644
index 5c64112d720e..000000000000
--- a/drivers/gpu/drm/i915/oa/i915_oa_icl.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright © 2018-2019 Intel Corporation
- *
- * Autogenerated file by GPU Top : https://github.com/rib/gputop
- * DO NOT EDIT manually!
- */
-
-#ifndef __I915_OA_ICL_H__
-#define __I915_OA_ICL_H__
-
-struct drm_i915_private;
-
-void i915_perf_load_test_config_icl(struct drm_i915_private *dev_priv);
-
-#endif
diff --git a/drivers/gpu/drm/i915/oa/i915_oa_kblgt2.c b/drivers/gpu/drm/i915/oa/i915_oa_kblgt2.c
deleted file mode 100644
index 1c3a67c9cfe0..000000000000
--- a/drivers/gpu/drm/i915/oa/i915_oa_kblgt2.c
+++ /dev/null
@@ -1,89 +0,0 @@
-// SPDX-License-Identifier: MIT
-/*
- * Copyright © 2018-2019 Intel Corporation
- *
- * Autogenerated file by GPU Top : https://github.com/rib/gputop
- * DO NOT EDIT manually!
- */
-
-#include <linux/sysfs.h>
-
-#include "i915_drv.h"
-#include "i915_oa_kblgt2.h"
-
-static const struct i915_oa_reg b_counter_config_test_oa[] = {
-	{ _MMIO(0x2740), 0x00000000 },
-	{ _MMIO(0x2744), 0x00800000 },
-	{ _MMIO(0x2714), 0xf0800000 },
-	{ _MMIO(0x2710), 0x00000000 },
-	{ _MMIO(0x2724), 0xf0800000 },
-	{ _MMIO(0x2720), 0x00000000 },
-	{ _MMIO(0x2770), 0x00000004 },
-	{ _MMIO(0x2774), 0x00000000 },
-	{ _MMIO(0x2778), 0x00000003 },
-	{ _MMIO(0x277c), 0x00000000 },
-	{ _MMIO(0x2780), 0x00000007 },
-	{ _MMIO(0x2784), 0x00000000 },
-	{ _MMIO(0x2788), 0x00100002 },
-	{ _MMIO(0x278c), 0x0000fff7 },
-	{ _MMIO(0x2790), 0x00100002 },
-	{ _MMIO(0x2794), 0x0000ffcf },
-	{ _MMIO(0x2798), 0x00100082 },
-	{ _MMIO(0x279c), 0x0000ffef },
-	{ _MMIO(0x27a0), 0x001000c2 },
-	{ _MMIO(0x27a4), 0x0000ffe7 },
-	{ _MMIO(0x27a8), 0x00100001 },
-	{ _MMIO(0x27ac), 0x0000ffe7 },
-};
-
-static const struct i915_oa_reg flex_eu_config_test_oa[] = {
-};
-
-static const struct i915_oa_reg mux_config_test_oa[] = {
-	{ _MMIO(0x9840), 0x00000080 },
-	{ _MMIO(0x9888), 0x11810000 },
-	{ _MMIO(0x9888), 0x07810013 },
-	{ _MMIO(0x9888), 0x1f810000 },
-	{ _MMIO(0x9888), 0x1d810000 },
-	{ _MMIO(0x9888), 0x1b930040 },
-	{ _MMIO(0x9888), 0x07e54000 },
-	{ _MMIO(0x9888), 0x1f908000 },
-	{ _MMIO(0x9888), 0x11900000 },
-	{ _MMIO(0x9888), 0x37900000 },
-	{ _MMIO(0x9888), 0x53900000 },
-	{ _MMIO(0x9888), 0x45900000 },
-	{ _MMIO(0x9888), 0x33900000 },
-};
-
-static ssize_t
-show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
-	return sprintf(buf, "1\n");
-}
-
-void
-i915_perf_load_test_config_kblgt2(struct drm_i915_private *dev_priv)
-{
-	strlcpy(dev_priv->perf.test_config.uuid,
-		"baa3c7e4-52b6-4b85-801e-465a94b746dd",
-		sizeof(dev_priv->perf.test_config.uuid));
-	dev_priv->perf.test_config.id = 1;
-
-	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
-	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
-
-	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
-	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
-
-	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
-	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
-
-	dev_priv->perf.test_config.sysfs_metric.name = "baa3c7e4-52b6-4b85-801e-465a94b746dd";
-	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
-
-	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
-
-	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
-	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
-	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
-}
diff --git a/drivers/gpu/drm/i915/oa/i915_oa_kblgt2.h b/drivers/gpu/drm/i915/oa/i915_oa_kblgt2.h
deleted file mode 100644
index 810532fa6b63..000000000000
--- a/drivers/gpu/drm/i915/oa/i915_oa_kblgt2.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright © 2018-2019 Intel Corporation
- *
- * Autogenerated file by GPU Top : https://github.com/rib/gputop
- * DO NOT EDIT manually!
- */
-
-#ifndef __I915_OA_KBLGT2_H__
-#define __I915_OA_KBLGT2_H__
-
-struct drm_i915_private;
-
-void i915_perf_load_test_config_kblgt2(struct drm_i915_private *dev_priv);
-
-#endif
diff --git a/drivers/gpu/drm/i915/oa/i915_oa_kblgt3.c b/drivers/gpu/drm/i915/oa/i915_oa_kblgt3.c
deleted file mode 100644
index ebbe5a9c9fdc..000000000000
--- a/drivers/gpu/drm/i915/oa/i915_oa_kblgt3.c
+++ /dev/null
@@ -1,89 +0,0 @@
-// SPDX-License-Identifier: MIT
-/*
- * Copyright © 2018-2019 Intel Corporation
- *
- * Autogenerated file by GPU Top : https://github.com/rib/gputop
- * DO NOT EDIT manually!
- */
-
-#include <linux/sysfs.h>
-
-#include "i915_drv.h"
-#include "i915_oa_kblgt3.h"
-
-static const struct i915_oa_reg b_counter_config_test_oa[] = {
-	{ _MMIO(0x2740), 0x00000000 },
-	{ _MMIO(0x2744), 0x00800000 },
-	{ _MMIO(0x2714), 0xf0800000 },
-	{ _MMIO(0x2710), 0x00000000 },
-	{ _MMIO(0x2724), 0xf0800000 },
-	{ _MMIO(0x2720), 0x00000000 },
-	{ _MMIO(0x2770), 0x00000004 },
-	{ _MMIO(0x2774), 0x00000000 },
-	{ _MMIO(0x2778), 0x00000003 },
-	{ _MMIO(0x277c), 0x00000000 },
-	{ _MMIO(0x2780), 0x00000007 },
-	{ _MMIO(0x2784), 0x00000000 },
-	{ _MMIO(0x2788), 0x00100002 },
-	{ _MMIO(0x278c), 0x0000fff7 },
-	{ _MMIO(0x2790), 0x00100002 },
-	{ _MMIO(0x2794), 0x0000ffcf },
-	{ _MMIO(0x2798), 0x00100082 },
-	{ _MMIO(0x279c), 0x0000ffef },
-	{ _MMIO(0x27a0), 0x001000c2 },
-	{ _MMIO(0x27a4), 0x0000ffe7 },
-	{ _MMIO(0x27a8), 0x00100001 },
-	{ _MMIO(0x27ac), 0x0000ffe7 },
-};
-
-static const struct i915_oa_reg flex_eu_config_test_oa[] = {
-};
-
-static const struct i915_oa_reg mux_config_test_oa[] = {
-	{ _MMIO(0x9840), 0x00000080 },
-	{ _MMIO(0x9888), 0x11810000 },
-	{ _MMIO(0x9888), 0x07810013 },
-	{ _MMIO(0x9888), 0x1f810000 },
-	{ _MMIO(0x9888), 0x1d810000 },
-	{ _MMIO(0x9888), 0x1b930040 },
-	{ _MMIO(0x9888), 0x07e54000 },
-	{ _MMIO(0x9888), 0x1f908000 },
-	{ _MMIO(0x9888), 0x11900000 },
-	{ _MMIO(0x9888), 0x37900000 },
-	{ _MMIO(0x9888), 0x53900000 },
-	{ _MMIO(0x9888), 0x45900000 },
-	{ _MMIO(0x9888), 0x33900000 },
-};
-
-static ssize_t
-show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
-	return sprintf(buf, "1\n");
-}
-
-void
-i915_perf_load_test_config_kblgt3(struct drm_i915_private *dev_priv)
-{
-	strlcpy(dev_priv->perf.test_config.uuid,
-		"f1792f32-6db2-4b50-b4b2-557128f1688d",
-		sizeof(dev_priv->perf.test_config.uuid));
-	dev_priv->perf.test_config.id = 1;
-
-	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
-	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
-
-	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
-	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
-
-	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
-	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
-
-	dev_priv->perf.test_config.sysfs_metric.name = "f1792f32-6db2-4b50-b4b2-557128f1688d";
-	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
-
-	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
-
-	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
-	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
-	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
-}
diff --git a/drivers/gpu/drm/i915/oa/i915_oa_kblgt3.h b/drivers/gpu/drm/i915/oa/i915_oa_kblgt3.h
deleted file mode 100644
index 13d70456fabd..000000000000
--- a/drivers/gpu/drm/i915/oa/i915_oa_kblgt3.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright © 2018-2019 Intel Corporation
- *
- * Autogenerated file by GPU Top : https://github.com/rib/gputop
- * DO NOT EDIT manually!
- */
-
-#ifndef __I915_OA_KBLGT3_H__
-#define __I915_OA_KBLGT3_H__
-
-struct drm_i915_private;
-
-void i915_perf_load_test_config_kblgt3(struct drm_i915_private *dev_priv);
-
-#endif
diff --git a/drivers/gpu/drm/i915/oa/i915_oa_sklgt2.c b/drivers/gpu/drm/i915/oa/i915_oa_sklgt2.c
deleted file mode 100644
index 1bc359ed34e8..000000000000
--- a/drivers/gpu/drm/i915/oa/i915_oa_sklgt2.c
+++ /dev/null
@@ -1,88 +0,0 @@
-// SPDX-License-Identifier: MIT
-/*
- * Copyright © 2018-2019 Intel Corporation
- *
- * Autogenerated file by GPU Top : https://github.com/rib/gputop
- * DO NOT EDIT manually!
- */
-
-#include <linux/sysfs.h>
-
-#include "i915_drv.h"
-#include "i915_oa_sklgt2.h"
-
-static const struct i915_oa_reg b_counter_config_test_oa[] = {
-	{ _MMIO(0x2740), 0x00000000 },
-	{ _MMIO(0x2714), 0xf0800000 },
-	{ _MMIO(0x2710), 0x00000000 },
-	{ _MMIO(0x2724), 0xf0800000 },
-	{ _MMIO(0x2720), 0x00000000 },
-	{ _MMIO(0x2770), 0x00000004 },
-	{ _MMIO(0x2774), 0x00000000 },
-	{ _MMIO(0x2778), 0x00000003 },
-	{ _MMIO(0x277c), 0x00000000 },
-	{ _MMIO(0x2780), 0x00000007 },
-	{ _MMIO(0x2784), 0x00000000 },
-	{ _MMIO(0x2788), 0x00100002 },
-	{ _MMIO(0x278c), 0x0000fff7 },
-	{ _MMIO(0x2790), 0x00100002 },
-	{ _MMIO(0x2794), 0x0000ffcf },
-	{ _MMIO(0x2798), 0x00100082 },
-	{ _MMIO(0x279c), 0x0000ffef },
-	{ _MMIO(0x27a0), 0x001000c2 },
-	{ _MMIO(0x27a4), 0x0000ffe7 },
-	{ _MMIO(0x27a8), 0x00100001 },
-	{ _MMIO(0x27ac), 0x0000ffe7 },
-};
-
-static const struct i915_oa_reg flex_eu_config_test_oa[] = {
-};
-
-static const struct i915_oa_reg mux_config_test_oa[] = {
-	{ _MMIO(0x9840), 0x00000080 },
-	{ _MMIO(0x9888), 0x11810000 },
-	{ _MMIO(0x9888), 0x07810016 },
-	{ _MMIO(0x9888), 0x1f810000 },
-	{ _MMIO(0x9888), 0x1d810000 },
-	{ _MMIO(0x9888), 0x1b930040 },
-	{ _MMIO(0x9888), 0x07e54000 },
-	{ _MMIO(0x9888), 0x1f908000 },
-	{ _MMIO(0x9888), 0x11900000 },
-	{ _MMIO(0x9888), 0x37900000 },
-	{ _MMIO(0x9888), 0x53900000 },
-	{ _MMIO(0x9888), 0x45900000 },
-	{ _MMIO(0x9888), 0x33900000 },
-};
-
-static ssize_t
-show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
-	return sprintf(buf, "1\n");
-}
-
-void
-i915_perf_load_test_config_sklgt2(struct drm_i915_private *dev_priv)
-{
-	strlcpy(dev_priv->perf.test_config.uuid,
-		"1651949f-0ac0-4cb1-a06f-dafd74a407d1",
-		sizeof(dev_priv->perf.test_config.uuid));
-	dev_priv->perf.test_config.id = 1;
-
-	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
-	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
-
-	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
-	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
-
-	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
-	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
-
-	dev_priv->perf.test_config.sysfs_metric.name = "1651949f-0ac0-4cb1-a06f-dafd74a407d1";
-	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
-
-	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
-
-	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
-	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
-	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
-}
diff --git a/drivers/gpu/drm/i915/oa/i915_oa_sklgt2.h b/drivers/gpu/drm/i915/oa/i915_oa_sklgt2.h
deleted file mode 100644
index fda70c51a6ec..000000000000
--- a/drivers/gpu/drm/i915/oa/i915_oa_sklgt2.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright © 2018-2019 Intel Corporation
- *
- * Autogenerated file by GPU Top : https://github.com/rib/gputop
- * DO NOT EDIT manually!
- */
-
-#ifndef __I915_OA_SKLGT2_H__
-#define __I915_OA_SKLGT2_H__
-
-struct drm_i915_private;
-
-void i915_perf_load_test_config_sklgt2(struct drm_i915_private *dev_priv);
-
-#endif
diff --git a/drivers/gpu/drm/i915/oa/i915_oa_sklgt3.c b/drivers/gpu/drm/i915/oa/i915_oa_sklgt3.c
deleted file mode 100644
index 6e352f881310..000000000000
--- a/drivers/gpu/drm/i915/oa/i915_oa_sklgt3.c
+++ /dev/null
@@ -1,89 +0,0 @@
-// SPDX-License-Identifier: MIT
-/*
- * Copyright © 2018-2019 Intel Corporation
- *
- * Autogenerated file by GPU Top : https://github.com/rib/gputop
- * DO NOT EDIT manually!
- */
-
-#include <linux/sysfs.h>
-
-#include "i915_drv.h"
-#include "i915_oa_sklgt3.h"
-
-static const struct i915_oa_reg b_counter_config_test_oa[] = {
-	{ _MMIO(0x2740), 0x00000000 },
-	{ _MMIO(0x2744), 0x00800000 },
-	{ _MMIO(0x2714), 0xf0800000 },
-	{ _MMIO(0x2710), 0x00000000 },
-	{ _MMIO(0x2724), 0xf0800000 },
-	{ _MMIO(0x2720), 0x00000000 },
-	{ _MMIO(0x2770), 0x00000004 },
-	{ _MMIO(0x2774), 0x00000000 },
-	{ _MMIO(0x2778), 0x00000003 },
-	{ _MMIO(0x277c), 0x00000000 },
-	{ _MMIO(0x2780), 0x00000007 },
-	{ _MMIO(0x2784), 0x00000000 },
-	{ _MMIO(0x2788), 0x00100002 },
-	{ _MMIO(0x278c), 0x0000fff7 },
-	{ _MMIO(0x2790), 0x00100002 },
-	{ _MMIO(0x2794), 0x0000ffcf },
-	{ _MMIO(0x2798), 0x00100082 },
-	{ _MMIO(0x279c), 0x0000ffef },
-	{ _MMIO(0x27a0), 0x001000c2 },
-	{ _MMIO(0x27a4), 0x0000ffe7 },
-	{ _MMIO(0x27a8), 0x00100001 },
-	{ _MMIO(0x27ac), 0x0000ffe7 },
-};
-
-static const struct i915_oa_reg flex_eu_config_test_oa[] = {
-};
-
-static const struct i915_oa_reg mux_config_test_oa[] = {
-	{ _MMIO(0x9840), 0x00000080 },
-	{ _MMIO(0x9888), 0x11810000 },
-	{ _MMIO(0x9888), 0x07810013 },
-	{ _MMIO(0x9888), 0x1f810000 },
-	{ _MMIO(0x9888), 0x1d810000 },
-	{ _MMIO(0x9888), 0x1b930040 },
-	{ _MMIO(0x9888), 0x07e54000 },
-	{ _MMIO(0x9888), 0x1f908000 },
-	{ _MMIO(0x9888), 0x11900000 },
-	{ _MMIO(0x9888), 0x37900000 },
-	{ _MMIO(0x9888), 0x53900000 },
-	{ _MMIO(0x9888), 0x45900000 },
-	{ _MMIO(0x9888), 0x33900000 },
-};
-
-static ssize_t
-show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
-	return sprintf(buf, "1\n");
-}
-
-void
-i915_perf_load_test_config_sklgt3(struct drm_i915_private *dev_priv)
-{
-	strlcpy(dev_priv->perf.test_config.uuid,
-		"2b985803-d3c9-4629-8a4f-634bfecba0e8",
-		sizeof(dev_priv->perf.test_config.uuid));
-	dev_priv->perf.test_config.id = 1;
-
-	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
-	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
-
-	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
-	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
-
-	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
-	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
-
-	dev_priv->perf.test_config.sysfs_metric.name = "2b985803-d3c9-4629-8a4f-634bfecba0e8";
-	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
-
-	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
-
-	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
-	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
-	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
-}
diff --git a/drivers/gpu/drm/i915/oa/i915_oa_sklgt3.h b/drivers/gpu/drm/i915/oa/i915_oa_sklgt3.h
deleted file mode 100644
index df74eba5799e..000000000000
--- a/drivers/gpu/drm/i915/oa/i915_oa_sklgt3.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright © 2018-2019 Intel Corporation
- *
- * Autogenerated file by GPU Top : https://github.com/rib/gputop
- * DO NOT EDIT manually!
- */
-
-#ifndef __I915_OA_SKLGT3_H__
-#define __I915_OA_SKLGT3_H__
-
-struct drm_i915_private;
-
-void i915_perf_load_test_config_sklgt3(struct drm_i915_private *dev_priv);
-
-#endif
diff --git a/drivers/gpu/drm/i915/oa/i915_oa_sklgt4.c b/drivers/gpu/drm/i915/oa/i915_oa_sklgt4.c
deleted file mode 100644
index 8f345115a306..000000000000
--- a/drivers/gpu/drm/i915/oa/i915_oa_sklgt4.c
+++ /dev/null
@@ -1,89 +0,0 @@
-// SPDX-License-Identifier: MIT
-/*
- * Copyright © 2018-2019 Intel Corporation
- *
- * Autogenerated file by GPU Top : https://github.com/rib/gputop
- * DO NOT EDIT manually!
- */
-
-#include <linux/sysfs.h>
-
-#include "i915_drv.h"
-#include "i915_oa_sklgt4.h"
-
-static const struct i915_oa_reg b_counter_config_test_oa[] = {
-	{ _MMIO(0x2740), 0x00000000 },
-	{ _MMIO(0x2744), 0x00800000 },
-	{ _MMIO(0x2714), 0xf0800000 },
-	{ _MMIO(0x2710), 0x00000000 },
-	{ _MMIO(0x2724), 0xf0800000 },
-	{ _MMIO(0x2720), 0x00000000 },
-	{ _MMIO(0x2770), 0x00000004 },
-	{ _MMIO(0x2774), 0x00000000 },
-	{ _MMIO(0x2778), 0x00000003 },
-	{ _MMIO(0x277c), 0x00000000 },
-	{ _MMIO(0x2780), 0x00000007 },
-	{ _MMIO(0x2784), 0x00000000 },
-	{ _MMIO(0x2788), 0x00100002 },
-	{ _MMIO(0x278c), 0x0000fff7 },
-	{ _MMIO(0x2790), 0x00100002 },
-	{ _MMIO(0x2794), 0x0000ffcf },
-	{ _MMIO(0x2798), 0x00100082 },
-	{ _MMIO(0x279c), 0x0000ffef },
-	{ _MMIO(0x27a0), 0x001000c2 },
-	{ _MMIO(0x27a4), 0x0000ffe7 },
-	{ _MMIO(0x27a8), 0x00100001 },
-	{ _MMIO(0x27ac), 0x0000ffe7 },
-};
-
-static const struct i915_oa_reg flex_eu_config_test_oa[] = {
-};
-
-static const struct i915_oa_reg mux_config_test_oa[] = {
-	{ _MMIO(0x9840), 0x00000080 },
-	{ _MMIO(0x9888), 0x11810000 },
-	{ _MMIO(0x9888), 0x07810013 },
-	{ _MMIO(0x9888), 0x1f810000 },
-	{ _MMIO(0x9888), 0x1d810000 },
-	{ _MMIO(0x9888), 0x1b930040 },
-	{ _MMIO(0x9888), 0x07e54000 },
-	{ _MMIO(0x9888), 0x1f908000 },
-	{ _MMIO(0x9888), 0x11900000 },
-	{ _MMIO(0x9888), 0x37900000 },
-	{ _MMIO(0x9888), 0x53900000 },
-	{ _MMIO(0x9888), 0x45900000 },
-	{ _MMIO(0x9888), 0x33900000 },
-};
-
-static ssize_t
-show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
-	return sprintf(buf, "1\n");
-}
-
-void
-i915_perf_load_test_config_sklgt4(struct drm_i915_private *dev_priv)
-{
-	strlcpy(dev_priv->perf.test_config.uuid,
-		"882fa433-1f4a-4a67-a962-c741888fe5f5",
-		sizeof(dev_priv->perf.test_config.uuid));
-	dev_priv->perf.test_config.id = 1;
-
-	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
-	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
-
-	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
-	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
-
-	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
-	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
-
-	dev_priv->perf.test_config.sysfs_metric.name = "882fa433-1f4a-4a67-a962-c741888fe5f5";
-	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
-
-	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
-
-	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
-	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
-	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
-}
diff --git a/drivers/gpu/drm/i915/oa/i915_oa_sklgt4.h b/drivers/gpu/drm/i915/oa/i915_oa_sklgt4.h
deleted file mode 100644
index 378ab7ab78d5..000000000000
--- a/drivers/gpu/drm/i915/oa/i915_oa_sklgt4.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright © 2018-2019 Intel Corporation
- *
- * Autogenerated file by GPU Top : https://github.com/rib/gputop
- * DO NOT EDIT manually!
- */
-
-#ifndef __I915_OA_SKLGT4_H__
-#define __I915_OA_SKLGT4_H__
-
-struct drm_i915_private;
-
-void i915_perf_load_test_config_sklgt4(struct drm_i915_private *dev_priv);
-
-#endif
diff --git a/drivers/gpu/drm/i915/oa/i915_oa_tgl.c b/drivers/gpu/drm/i915/oa/i915_oa_tgl.c
deleted file mode 100644
index a29d93707345..000000000000
--- a/drivers/gpu/drm/i915/oa/i915_oa_tgl.c
+++ /dev/null
@@ -1,121 +0,0 @@
-// SPDX-License-Identifier: MIT
-/*
- * Copyright © 2018 Intel Corporation
- *
- * Autogenerated file by GPU Top : https://github.com/rib/gputop
- * DO NOT EDIT manually!
- */
-
-#include <linux/sysfs.h>
-
-#include "i915_drv.h"
-#include "i915_oa_tgl.h"
-
-static const struct i915_oa_reg b_counter_config_test_oa[] = {
-	{ _MMIO(0xD920), 0x00000000 },
-	{ _MMIO(0xD900), 0x00000000 },
-	{ _MMIO(0xD904), 0xF0800000 },
-	{ _MMIO(0xD910), 0x00000000 },
-	{ _MMIO(0xD914), 0xF0800000 },
-	{ _MMIO(0xDC40), 0x00FF0000 },
-	{ _MMIO(0xD940), 0x00000004 },
-	{ _MMIO(0xD944), 0x0000FFFF },
-	{ _MMIO(0xDC00), 0x00000004 },
-	{ _MMIO(0xDC04), 0x0000FFFF },
-	{ _MMIO(0xD948), 0x00000003 },
-	{ _MMIO(0xD94C), 0x0000FFFF },
-	{ _MMIO(0xDC08), 0x00000003 },
-	{ _MMIO(0xDC0C), 0x0000FFFF },
-	{ _MMIO(0xD950), 0x00000007 },
-	{ _MMIO(0xD954), 0x0000FFFF },
-	{ _MMIO(0xDC10), 0x00000007 },
-	{ _MMIO(0xDC14), 0x0000FFFF },
-	{ _MMIO(0xD958), 0x00100002 },
-	{ _MMIO(0xD95C), 0x0000FFF7 },
-	{ _MMIO(0xDC18), 0x00100002 },
-	{ _MMIO(0xDC1C), 0x0000FFF7 },
-	{ _MMIO(0xD960), 0x00100002 },
-	{ _MMIO(0xD964), 0x0000FFCF },
-	{ _MMIO(0xDC20), 0x00100002 },
-	{ _MMIO(0xDC24), 0x0000FFCF },
-	{ _MMIO(0xD968), 0x00100082 },
-	{ _MMIO(0xD96C), 0x0000FFEF },
-	{ _MMIO(0xDC28), 0x00100082 },
-	{ _MMIO(0xDC2C), 0x0000FFEF },
-	{ _MMIO(0xD970), 0x001000C2 },
-	{ _MMIO(0xD974), 0x0000FFE7 },
-	{ _MMIO(0xDC30), 0x001000C2 },
-	{ _MMIO(0xDC34), 0x0000FFE7 },
-	{ _MMIO(0xD978), 0x00100001 },
-	{ _MMIO(0xD97C), 0x0000FFE7 },
-	{ _MMIO(0xDC38), 0x00100001 },
-	{ _MMIO(0xDC3C), 0x0000FFE7 },
-};
-
-static const struct i915_oa_reg flex_eu_config_test_oa[] = {
-};
-
-static const struct i915_oa_reg mux_config_test_oa[] = {
-	{ _MMIO(0x0D04), 0x00000200 },
-	{ _MMIO(0x9840), 0x00000000 },
-	{ _MMIO(0x9884), 0x00000000 },
-	{ _MMIO(0x9888), 0x280E0000 },
-	{ _MMIO(0x9888), 0x1E0E0147 },
-	{ _MMIO(0x9888), 0x180E0000 },
-	{ _MMIO(0x9888), 0x160E0000 },
-	{ _MMIO(0x9888), 0x1E0F1000 },
-	{ _MMIO(0x9888), 0x1E104000 },
-	{ _MMIO(0x9888), 0x2E020100 },
-	{ _MMIO(0x9888), 0x2C030004 },
-	{ _MMIO(0x9888), 0x38003000 },
-	{ _MMIO(0x9888), 0x1E0A8000 },
-	{ _MMIO(0x9884), 0x00000003 },
-	{ _MMIO(0x9888), 0x49110000 },
-	{ _MMIO(0x9888), 0x5D101400 },
-	{ _MMIO(0x9888), 0x1D140020 },
-	{ _MMIO(0x9888), 0x1D1103A3 },
-	{ _MMIO(0x9888), 0x01110000 },
-	{ _MMIO(0x9888), 0x61111000 },
-	{ _MMIO(0x9888), 0x1F128000 },
-	{ _MMIO(0x9888), 0x17100000 },
-	{ _MMIO(0x9888), 0x55100630 },
-	{ _MMIO(0x9888), 0x57100000 },
-	{ _MMIO(0x9888), 0x31100000 },
-	{ _MMIO(0x9884), 0x00000003 },
-	{ _MMIO(0x9888), 0x65100002 },
-	{ _MMIO(0x9884), 0x00000000 },
-	{ _MMIO(0x9888), 0x42000001 },
-};
-
-static ssize_t
-show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
-	return sprintf(buf, "1\n");
-}
-
-void
-i915_perf_load_test_config_tgl(struct drm_i915_private *dev_priv)
-{
-	strlcpy(dev_priv->perf.test_config.uuid,
-		"80a833f0-2504-4321-8894-e9277844ce7b",
-		sizeof(dev_priv->perf.test_config.uuid));
-	dev_priv->perf.test_config.id = 1;
-
-	dev_priv->perf.test_config.mux_regs = mux_config_test_oa;
-	dev_priv->perf.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
-
-	dev_priv->perf.test_config.b_counter_regs = b_counter_config_test_oa;
-	dev_priv->perf.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
-
-	dev_priv->perf.test_config.flex_regs = flex_eu_config_test_oa;
-	dev_priv->perf.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
-
-	dev_priv->perf.test_config.sysfs_metric.name = "80a833f0-2504-4321-8894-e9277844ce7b";
-	dev_priv->perf.test_config.sysfs_metric.attrs = dev_priv->perf.test_config.attrs;
-
-	dev_priv->perf.test_config.attrs[0] = &dev_priv->perf.test_config.sysfs_metric_id.attr;
-
-	dev_priv->perf.test_config.sysfs_metric_id.attr.name = "id";
-	dev_priv->perf.test_config.sysfs_metric_id.attr.mode = 0444;
-	dev_priv->perf.test_config.sysfs_metric_id.show = show_test_oa_id;
-}
diff --git a/drivers/gpu/drm/i915/oa/i915_oa_tgl.h b/drivers/gpu/drm/i915/oa/i915_oa_tgl.h
deleted file mode 100644
index 4c25f0be825c..000000000000
--- a/drivers/gpu/drm/i915/oa/i915_oa_tgl.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright © 2018 Intel Corporation
- *
- * Autogenerated file by GPU Top : https://github.com/rib/gputop
- * DO NOT EDIT manually!
- */
-
-#ifndef __I915_OA_TGL_H__
-#define __I915_OA_TGL_H__
-
-struct drm_i915_private;
-
-void i915_perf_load_test_config_tgl(struct drm_i915_private *dev_priv);
-
-#endif
diff --git a/drivers/gpu/drm/i915/selftests/i915_active.c b/drivers/gpu/drm/i915/selftests/i915_active.c
index 68bbb1580162..4002c984c2e0 100644
--- a/drivers/gpu/drm/i915/selftests/i915_active.c
+++ b/drivers/gpu/drm/i915/selftests/i915_active.c
@@ -153,7 +153,7 @@ static int live_active_wait(void *arg)
 	if (IS_ERR(active))
 		return PTR_ERR(active);
 
-	i915_active_wait(&active->base);
+	__i915_active_wait(&active->base, TASK_UNINTERRUPTIBLE);
 	if (!READ_ONCE(active->retired)) {
 		struct drm_printer p = drm_err_printer(__func__);
 
@@ -228,11 +228,11 @@ static int live_active_barrier(void *arg)
 	}
 
 	i915_active_release(&active->base);
+	if (err)
+		goto out;
 
-	if (err == 0)
-		err = i915_active_wait(&active->base);
-
-	if (err == 0 && !READ_ONCE(active->retired)) {
+	__i915_active_wait(&active->base, TASK_UNINTERRUPTIBLE);
+	if (!READ_ONCE(active->retired)) {
 		pr_err("i915_active not retired after flushing barriers!\n");
 		err = -EINVAL;
 	}
@@ -277,7 +277,7 @@ static struct intel_engine_cs *node_to_barrier(struct active_node *it)
 
 void i915_active_print(struct i915_active *ref, struct drm_printer *m)
 {
-	drm_printf(m, "active %pS:%pS\n", ref->active, ref->retire);
+	drm_printf(m, "active %ps:%ps\n", ref->active, ref->retire);
 	drm_printf(m, "\tcount: %d\n", atomic_read(&ref->count));
 	drm_printf(m, "\tpreallocated barriers? %s\n",
 		   yesno(!llist_empty(&ref->preallocated_barriers)));
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem.c b/drivers/gpu/drm/i915/selftests/i915_gem.c
index 623759b73bb4..88d400b9df88 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem.c
@@ -125,8 +125,6 @@ static void pm_resume(struct drm_i915_private *i915)
 	 */
 	with_intel_runtime_pm(&i915->runtime_pm, wakeref) {
 		i915_ggtt_resume(&i915->ggtt);
-		i915_gem_restore_fences(&i915->ggtt);
-
 		i915_gem_resume(i915);
 	}
 }
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_evict.c b/drivers/gpu/drm/i915/selftests/i915_gem_evict.c
index 06ef88510209..028baae9631f 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_evict.c
@@ -45,8 +45,8 @@ static void quirk_add(struct drm_i915_gem_object *obj,
 
 static int populate_ggtt(struct i915_ggtt *ggtt, struct list_head *objects)
 {
-	unsigned long unbound, bound, count;
 	struct drm_i915_gem_object *obj;
+	unsigned long count;
 
 	count = 0;
 	do {
@@ -72,30 +72,6 @@ static int populate_ggtt(struct i915_ggtt *ggtt, struct list_head *objects)
 	pr_debug("Filled GGTT with %lu pages [%llu total]\n",
 		 count, ggtt->vm.total / PAGE_SIZE);
 
-	bound = 0;
-	unbound = 0;
-	list_for_each_entry(obj, objects, st_link) {
-		GEM_BUG_ON(!obj->mm.quirked);
-
-		if (atomic_read(&obj->bind_count))
-			bound++;
-		else
-			unbound++;
-	}
-	GEM_BUG_ON(bound + unbound != count);
-
-	if (unbound) {
-		pr_err("%s: Found %lu objects unbound, expected %u!\n",
-		       __func__, unbound, 0);
-		return -EINVAL;
-	}
-
-	if (bound != count) {
-		pr_err("%s: Found %lu objects bound, expected %lu!\n",
-		       __func__, bound, count);
-		return -EINVAL;
-	}
-
 	if (list_empty(&ggtt->vm.bound_list)) {
 		pr_err("No objects on the GGTT inactive list!\n");
 		return -EINVAL;
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
index b342bef5e7c9..5d2a02fcf595 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
@@ -1229,7 +1229,6 @@ static void track_vma_bind(struct i915_vma *vma)
 {
 	struct drm_i915_gem_object *obj = vma->obj;
 
-	atomic_inc(&obj->bind_count); /* track for eviction later */
 	__i915_gem_object_pin_pages(obj);
 
 	GEM_BUG_ON(vma->pages);
diff --git a/drivers/gpu/drm/i915/selftests/i915_perf.c b/drivers/gpu/drm/i915/selftests/i915_perf.c
index d1a1568c47ba..5608fab98d5d 100644
--- a/drivers/gpu/drm/i915/selftests/i915_perf.c
+++ b/drivers/gpu/drm/i915/selftests/i915_perf.c
@@ -14,10 +14,85 @@
 #include "igt_flush_test.h"
 #include "lib_sw_fence.h"
 
+#define TEST_OA_CONFIG_UUID "12345678-1234-1234-1234-1234567890ab"
+
+static int
+alloc_empty_config(struct i915_perf *perf)
+{
+	struct i915_oa_config *oa_config;
+
+	oa_config = kzalloc(sizeof(*oa_config), GFP_KERNEL);
+	if (!oa_config)
+		return -ENOMEM;
+
+	oa_config->perf = perf;
+	kref_init(&oa_config->ref);
+
+	strlcpy(oa_config->uuid, TEST_OA_CONFIG_UUID, sizeof(oa_config->uuid));
+
+	mutex_lock(&perf->metrics_lock);
+
+	oa_config->id = idr_alloc(&perf->metrics_idr, oa_config, 2, 0, GFP_KERNEL);
+	if (oa_config->id < 0)  {
+		mutex_unlock(&perf->metrics_lock);
+		i915_oa_config_put(oa_config);
+		return -ENOMEM;
+	}
+
+	mutex_unlock(&perf->metrics_lock);
+
+	return 0;
+}
+
+static void
+destroy_empty_config(struct i915_perf *perf)
+{
+	struct i915_oa_config *oa_config = NULL, *tmp;
+	int id;
+
+	mutex_lock(&perf->metrics_lock);
+
+	idr_for_each_entry(&perf->metrics_idr, tmp, id) {
+		if (!strcmp(tmp->uuid, TEST_OA_CONFIG_UUID)) {
+			oa_config = tmp;
+			break;
+		}
+	}
+
+	if (oa_config)
+		idr_remove(&perf->metrics_idr, oa_config->id);
+
+	mutex_unlock(&perf->metrics_lock);
+
+	if (oa_config)
+		i915_oa_config_put(oa_config);
+}
+
+static struct i915_oa_config *
+get_empty_config(struct i915_perf *perf)
+{
+	struct i915_oa_config *oa_config = NULL, *tmp;
+	int id;
+
+	mutex_lock(&perf->metrics_lock);
+
+	idr_for_each_entry(&perf->metrics_idr, tmp, id) {
+		if (!strcmp(tmp->uuid, TEST_OA_CONFIG_UUID)) {
+			oa_config = i915_oa_config_get(tmp);
+			break;
+		}
+	}
+
+	mutex_unlock(&perf->metrics_lock);
+
+	return oa_config;
+}
+
 static struct i915_perf_stream *
 test_stream(struct i915_perf *perf)
 {
 	struct drm_i915_perf_open_param param = {};
+	struct i915_oa_config *oa_config = get_empty_config(perf);
 	struct perf_open_properties props = {
 		.engine = intel_engine_lookup_user(perf->i915,
 						   I915_ENGINE_CLASS_RENDER,
@@ -25,13 +100,19 @@ test_stream(struct i915_perf *perf)
 		.sample_flags = SAMPLE_OA_REPORT,
 		.oa_format = IS_GEN(perf->i915, 12) ?
 		I915_OA_FORMAT_A32u40_A4u32_B8_C8 : I915_OA_FORMAT_C4_B8,
-		.metrics_set = 1,
 	};
 	struct i915_perf_stream *stream;
 
+	if (!oa_config)
+		return NULL;
+
+	props.metrics_set = oa_config->id;
+
 	stream = kzalloc(sizeof(*stream), GFP_KERNEL);
-	if (!stream)
+	if (!stream) {
+		i915_oa_config_put(oa_config);
 		return NULL;
+	}
 
 	stream->perf = perf;
 
@@ -42,6 +123,8 @@ test_stream(struct i915_perf *perf)
 	}
 	mutex_unlock(&perf->lock);
 
+	i915_oa_config_put(oa_config);
+
 	return stream;
 }
 
@@ -206,6 +289,7 @@ int i915_perf_live_selftests(struct drm_i915_private *i915)
 		SUBTEST(live_noa_delay),
 	};
 	struct i915_perf *perf = &i915->perf;
+	int err;
 
 	if (!perf->metrics_kobj || !perf->ops.enable_metric_set)
 		return 0;
@@ -213,5 +297,13 @@ int i915_perf_live_selftests(struct drm_i915_private *i915)
 	if (intel_gt_is_wedged(&i915->gt))
 		return 0;
 
-	return i915_subtests(tests, i915);
+	err = alloc_empty_config(&i915->perf);
+	if (err)
+		return err;
+
+	err = i915_subtests(tests, i915);
+
+	destroy_empty_config(&i915->perf);
+
+	return err;
 }
diff --git a/drivers/gpu/drm/i915/selftests/i915_request.c b/drivers/gpu/drm/i915/selftests/i915_request.c
index f89d9c42f1fa..1dab0360f76a 100644
--- a/drivers/gpu/drm/i915/selftests/i915_request.c
+++ b/drivers/gpu/drm/i915/selftests/i915_request.c
@@ -28,6 +28,7 @@
 #include "gem/selftests/mock_context.h"
 
 #include "gt/intel_engine_pm.h"
+#include "gt/intel_engine_user.h"
 #include "gt/intel_gt.h"
 
 #include "i915_random.h"
@@ -51,6 +52,11 @@ static unsigned int num_uabi_engines(struct drm_i915_private *i915)
 	return count;
 }
 
+static struct intel_engine_cs *rcs0(struct drm_i915_private *i915)
+{
+	return intel_engine_lookup_user(i915, I915_ENGINE_CLASS_RENDER, 0);
+}
+
 static int igt_add_request(void *arg)
 {
 	struct drm_i915_private *i915 = arg;
@@ -58,7 +64,7 @@ static int igt_add_request(void *arg)
 
 	/* Basic preliminary test to create a request and let it loose! */
 
-	request = mock_request(i915->engine[RCS0]->kernel_context, HZ / 10);
+	request = mock_request(rcs0(i915)->kernel_context, HZ / 10);
 	if (!request)
 		return -ENOMEM;
 
@@ -76,7 +82,7 @@ static int igt_wait_request(void *arg)
 
 	/* Submit a request, then wait upon it */
 
-	request = mock_request(i915->engine[RCS0]->kernel_context, T);
+	request = mock_request(rcs0(i915)->kernel_context, T);
 	if (!request)
 		return -ENOMEM;
 
@@ -145,7 +151,7 @@ static int igt_fence_wait(void *arg)
 
 	/* Submit a request, treat it as a fence and wait upon it */
 
-	request = mock_request(i915->engine[RCS0]->kernel_context, T);
+	request = mock_request(rcs0(i915)->kernel_context, T);
 	if (!request)
 		return -ENOMEM;
 
@@ -420,7 +426,7 @@ static int mock_breadcrumbs_smoketest(void *arg)
 {
 	struct drm_i915_private *i915 = arg;
 	struct smoketest t = {
-		.engine = i915->engine[RCS0],
+		.engine = rcs0(i915),
 		.ncontexts = 1024,
 		.max_batch = 1024,
 		.request_alloc = __mock_request_alloc
@@ -1233,7 +1239,7 @@ static int live_parallel_engines(void *arg)
 		struct igt_live_test t;
 		unsigned int idx;
 
-		snprintf(name, sizeof(name), "%pS", fn);
+		snprintf(name, sizeof(name), "%ps", fn);
 		err = igt_live_test_begin(&t, i915, __func__, name);
 		if (err)
 			break;
diff --git a/drivers/gpu/drm/i915/selftests/intel_memory_region.c b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
index 2a1d4ba1f9f3..6e80d99048e4 100644
--- a/drivers/gpu/drm/i915/selftests/intel_memory_region.c
+++ b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
@@ -594,8 +594,11 @@ create_region_for_mapping(struct intel_memory_region *mr, u64 size, u32 type,
 	void *addr;
 
 	obj = i915_gem_object_create_region(mr, size, 0);
-	if (IS_ERR(obj))
+	if (IS_ERR(obj)) {
+		if (PTR_ERR(obj) == -ENOSPC) /* Stolen memory */
+			return ERR_PTR(-ENODEV);
 		return obj;
+	}
 
 	addr = i915_gem_object_pin_map(obj, type);
 	if (IS_ERR(addr)) {
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index 754d0eb6beaa..9b105b811f1f 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -25,6 +25,8 @@
 #include <linux/pm_domain.h>
 #include <linux/pm_runtime.h>
 
+#include <drm/drm_managed.h>
+
 #include "gt/intel_gt.h"
 #include "gt/intel_gt_requests.h"
 #include "gt/mock_engine.h"
@@ -55,6 +57,9 @@ static void mock_device_release(struct drm_device *dev)
 {
 	struct drm_i915_private *i915 = to_i915(dev);
 
+	if (!i915->do_release)
+		goto out;
+
 	mock_device_flush(i915);
 	intel_gt_driver_remove(&i915->gt);
 
@@ -71,8 +76,9 @@ static void mock_device_release(struct drm_device *dev)
 
 	drm_mode_config_cleanup(&i915->drm);
 
-	drm_dev_fini(&i915->drm);
+out:
 	put_device(&i915->drm.pdev->dev);
+	i915->drm.pdev = NULL;
 }
 
 static struct drm_driver mock_driver = {
@@ -114,9 +120,14 @@ struct drm_i915_private *mock_gem_device(void)
 	struct pci_dev *pdev;
 	int err;
 
-	pdev = kzalloc(sizeof(*pdev) + sizeof(*i915), GFP_KERNEL);
+	pdev = kzalloc(sizeof(*pdev), GFP_KERNEL);
 	if (!pdev)
-		goto err;
+		return NULL;
+	i915 = kzalloc(sizeof(*i915), GFP_KERNEL);
+	if (!i915) {
+		kfree(pdev);
+		return NULL;
+	}
 
 	device_initialize(&pdev->dev);
 	pdev->class = PCI_BASE_CLASS_DISPLAY << 16;
@@ -129,7 +140,6 @@ struct drm_i915_private *mock_gem_device(void)
 	pdev->dev.archdata.iommu = (void *)-1;
 #endif
 
-	i915 = (struct drm_i915_private *)(pdev + 1);
 	pci_set_drvdata(pdev, i915);
 
 	dev_pm_domain_set(&pdev->dev, &pm_domain);
@@ -141,9 +151,13 @@ struct drm_i915_private *mock_gem_device(void)
 	err = drm_dev_init(&i915->drm, &mock_driver, &pdev->dev);
 	if (err) {
 		pr_err("Failed to initialise mock GEM device: err=%d\n", err);
-		goto put_device;
+		put_device(&pdev->dev);
+		kfree(i915);
+
+		return NULL;
 	}
 	i915->drm.pdev = pdev;
+	drmm_add_final_kfree(&i915->drm, i915);
 
 	intel_runtime_pm_init_early(&i915->runtime_pm);
 
@@ -178,16 +192,18 @@ struct drm_i915_private *mock_gem_device(void)
 
 	mkwrite_device_info(i915)->engine_mask = BIT(0);
 
-	i915->engine[RCS0] = mock_engine(i915, "mock", RCS0);
-	if (!i915->engine[RCS0])
+	i915->gt.engine[RCS0] = mock_engine(i915, "mock", RCS0);
+	if (!i915->gt.engine[RCS0])
 		goto err_unlock;
 
-	if (mock_engine_init(i915->engine[RCS0]))
+	if (mock_engine_init(i915->gt.engine[RCS0]))
 		goto err_context;
 
 	__clear_bit(I915_WEDGED, &i915->gt.reset.flags);
 	intel_engines_driver_register(i915);
 
+	i915->do_release = true;
+
 	return i915;
 
 err_context:
@@ -198,9 +214,7 @@ struct drm_i915_private *mock_gem_device(void)
 	intel_gt_driver_late_release(&i915->gt);
 	intel_memory_regions_driver_release(i915);
 	drm_mode_config_cleanup(&i915->drm);
-	drm_dev_fini(&i915->drm);
-put_device:
-	put_device(&pdev->dev);
-err:
+	drm_dev_put(&i915->drm);
+
 	return NULL;
 }
diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c b/drivers/gpu/drm/imx/dw_hdmi-imx.c
index f22cfbf9353e..ba4ca17fd4d8 100644
--- a/drivers/gpu/drm/imx/dw_hdmi-imx.c
+++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c
@@ -18,6 +18,7 @@
 #include <drm/drm_edid.h>
 #include <drm/drm_encoder.h>
 #include <drm/drm_of.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "imx-drm.h"
 
@@ -143,10 +144,6 @@ static const struct drm_encoder_helper_funcs dw_hdmi_imx_encoder_helper_funcs =
 	.atomic_check = dw_hdmi_imx_atomic_check,
 };
 
-static const struct drm_encoder_funcs dw_hdmi_imx_encoder_funcs = {
-	.destroy = drm_encoder_cleanup,
-};
-
 static enum drm_mode_status
 imx6q_hdmi_mode_valid(struct drm_connector *con,
 		      const struct drm_display_mode *mode)
@@ -236,8 +233,7 @@ static int dw_hdmi_imx_bind(struct device *dev, struct device *master,
 		return ret;
 
 	drm_encoder_helper_add(encoder, &dw_hdmi_imx_encoder_helper_funcs);
-	drm_encoder_init(drm, encoder, &dw_hdmi_imx_encoder_funcs,
-			 DRM_MODE_ENCODER_TMDS, NULL);
+	drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
 
 	platform_set_drvdata(pdev, hdmi);
 
diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c
index da87c70e413b..2e38f1a5cf8d 100644
--- a/drivers/gpu/drm/imx/imx-drm-core.c
+++ b/drivers/gpu/drm/imx/imx-drm-core.c
@@ -42,12 +42,6 @@ void imx_drm_connector_destroy(struct drm_connector *connector)
 }
 EXPORT_SYMBOL_GPL(imx_drm_connector_destroy);
 
-void imx_drm_encoder_destroy(struct drm_encoder *encoder)
-{
-	drm_encoder_cleanup(encoder);
-}
-EXPORT_SYMBOL_GPL(imx_drm_encoder_destroy);
-
 static int imx_drm_atomic_check(struct drm_device *dev,
 				struct drm_atomic_state *state)
 {
@@ -139,8 +133,8 @@ int imx_drm_encoder_parse_of(struct drm_device *drm,
 
 	encoder->possible_crtcs = crtc_mask;
 
-	/* FIXME: this is the mask of outputs which can clone this output. */
-	encoder->possible_clones = ~0;
+	/* FIXME: cloning support not clear, disable it all for now */
+	encoder->possible_clones = 0;
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/imx/imx-drm.h b/drivers/gpu/drm/imx/imx-drm.h
index ab9c6f706eb3..c3e1a3f14d30 100644
--- a/drivers/gpu/drm/imx/imx-drm.h
+++ b/drivers/gpu/drm/imx/imx-drm.h
@@ -38,7 +38,6 @@ int imx_drm_encoder_parse_of(struct drm_device *drm,
 	struct drm_encoder *encoder, struct device_node *np);
 
 void imx_drm_connector_destroy(struct drm_connector *connector);
-void imx_drm_encoder_destroy(struct drm_encoder *encoder);
 
 int ipu_planes_assign_pre(struct drm_device *dev,
 			  struct drm_atomic_state *state);
diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c
index 4da22a94790c..66ea68e8da87 100644
--- a/drivers/gpu/drm/imx/imx-ldb.c
+++ b/drivers/gpu/drm/imx/imx-ldb.c
@@ -26,6 +26,7 @@
 #include <drm/drm_panel.h>
 #include <drm/drm_print.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "imx-drm.h"
 
@@ -393,10 +394,6 @@ static const struct drm_connector_helper_funcs imx_ldb_connector_helper_funcs =
 	.best_encoder = imx_ldb_connector_best_encoder,
 };
 
-static const struct drm_encoder_funcs imx_ldb_encoder_funcs = {
-	.destroy = imx_drm_encoder_destroy,
-};
-
 static const struct drm_encoder_helper_funcs imx_ldb_encoder_helper_funcs = {
 	.atomic_mode_set = imx_ldb_encoder_atomic_mode_set,
 	.enable = imx_ldb_encoder_enable,
@@ -441,8 +438,7 @@ static int imx_ldb_register(struct drm_device *drm,
 	}
 
 	drm_encoder_helper_add(encoder, &imx_ldb_encoder_helper_funcs);
-	drm_encoder_init(drm, encoder, &imx_ldb_encoder_funcs,
-			 DRM_MODE_ENCODER_LVDS, NULL);
+	drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_LVDS);
 
 	if (imx_ldb_ch->bridge) {
 		ret = drm_bridge_attach(&imx_ldb_ch->encoder,
diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c
index 5bbfaa2cd0f4..ee63782c77e9 100644
--- a/drivers/gpu/drm/imx/imx-tve.c
+++ b/drivers/gpu/drm/imx/imx-tve.c
@@ -21,6 +21,7 @@
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "imx-drm.h"
 
@@ -348,10 +349,6 @@ static const struct drm_connector_helper_funcs imx_tve_connector_helper_funcs =
 	.mode_valid = imx_tve_connector_mode_valid,
 };
 
-static const struct drm_encoder_funcs imx_tve_encoder_funcs = {
-	.destroy = imx_drm_encoder_destroy,
-};
-
 static const struct drm_encoder_helper_funcs imx_tve_encoder_helper_funcs = {
 	.mode_set = imx_tve_encoder_mode_set,
 	.enable = imx_tve_encoder_enable,
@@ -479,8 +476,7 @@ static int imx_tve_register(struct drm_device *drm, struct imx_tve *tve)
 		return ret;
 
 	drm_encoder_helper_add(&tve->encoder, &imx_tve_encoder_helper_funcs);
-	drm_encoder_init(drm, &tve->encoder, &imx_tve_encoder_funcs,
-			 encoder_type, NULL);
+	drm_simple_encoder_init(drm, &tve->encoder, encoder_type);
 
 	drm_connector_helper_add(&tve->connector,
 			&imx_tve_connector_helper_funcs);
diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c
index 08fafa4bf8c2..4465e9c602f8 100644
--- a/drivers/gpu/drm/imx/parallel-display.c
+++ b/drivers/gpu/drm/imx/parallel-display.c
@@ -18,6 +18,7 @@
 #include <drm/drm_of.h>
 #include <drm/drm_panel.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "imx-drm.h"
 
@@ -216,7 +217,7 @@ static int imx_pd_bridge_atomic_check(struct drm_bridge *bridge,
 
 	if (next_bridge_state)
 		bus_flags = next_bridge_state->input_bus_cfg.flags;
-	else if (!imxpd->bus_format && di->num_bus_formats)
+	else if (di->num_bus_formats)
 		bus_flags = di->bus_flags;
 	else
 		bus_flags = imxpd->bus_flags;
@@ -256,10 +257,6 @@ static const struct drm_connector_helper_funcs imx_pd_connector_helper_funcs = {
 	.best_encoder = imx_pd_connector_best_encoder,
 };
 
-static const struct drm_encoder_funcs imx_pd_encoder_funcs = {
-	.destroy = imx_drm_encoder_destroy,
-};
-
 static const struct drm_bridge_funcs imx_pd_bridge_funcs = {
 	.enable = imx_pd_bridge_enable,
 	.disable = imx_pd_bridge_disable,
@@ -288,8 +285,7 @@ static int imx_pd_register(struct drm_device *drm,
 	 */
 	imxpd->connector.dpms = DRM_MODE_DPMS_OFF;
 
-	drm_encoder_init(drm, encoder, &imx_pd_encoder_funcs,
-			 DRM_MODE_ENCODER_NONE, NULL);
+	drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_NONE);
 
 	imxpd->bridge.funcs = &imx_pd_bridge_funcs;
 	drm_bridge_attach(encoder, &imxpd->bridge, NULL, 0);
diff --git a/drivers/gpu/drm/ingenic/ingenic-drm.c b/drivers/gpu/drm/ingenic/ingenic-drm.c
index 9dfe7cb530e1..24cc3587cea5 100644
--- a/drivers/gpu/drm/ingenic/ingenic-drm.c
+++ b/drivers/gpu/drm/ingenic/ingenic-drm.c
@@ -23,11 +23,13 @@
 #include <drm/drm_fourcc.h>
 #include <drm/drm_gem_framebuffer_helper.h>
 #include <drm/drm_irq.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_of.h>
 #include <drm/drm_panel.h>
 #include <drm/drm_plane.h>
 #include <drm/drm_plane_helper.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 #include <drm/drm_vblank.h>
 
 #define JZ_REG_LCD_CFG				0x00
@@ -488,15 +490,6 @@ static irqreturn_t ingenic_drm_irq_handler(int irq, void *arg)
 	return IRQ_HANDLED;
 }
 
-static void ingenic_drm_release(struct drm_device *drm)
-{
-	struct ingenic_drm *priv = drm_device_get_priv(drm);
-
-	drm_mode_config_cleanup(drm);
-	drm_dev_fini(drm);
-	kfree(priv);
-}
-
 static int ingenic_drm_enable_vblank(struct drm_crtc *crtc)
 {
 	struct ingenic_drm *priv = drm_crtc_get_priv(crtc);
@@ -540,7 +533,6 @@ static struct drm_driver ingenic_drm_driver_data = {
 	.gem_prime_mmap		= drm_gem_cma_prime_mmap,
 
 	.irq_handler		= ingenic_drm_irq_handler,
-	.release		= ingenic_drm_release,
 };
 
 static const struct drm_plane_funcs ingenic_drm_primary_plane_funcs = {
@@ -592,10 +584,6 @@ static const struct drm_mode_config_funcs ingenic_drm_mode_config_funcs = {
 	.atomic_commit		= drm_atomic_helper_commit,
 };
 
-static const struct drm_encoder_funcs ingenic_drm_encoder_funcs = {
-	.destroy		= drm_encoder_cleanup,
-};
-
 static void ingenic_drm_free_dma_hwdesc(void *d)
 {
 	struct ingenic_drm *priv = d;
@@ -639,8 +627,12 @@ static int ingenic_drm_probe(struct platform_device *pdev)
 		kfree(priv);
 		return ret;
 	}
+	drmm_add_final_kfree(drm, priv);
+
+	ret = drmm_mode_config_init(drm);
+	if (ret)
+		return ret;
 
-	drm_mode_config_init(drm);
 	drm->mode_config.min_width = 0;
 	drm->mode_config.min_height = 0;
 	drm->mode_config.max_width = soc_info->max_width;
@@ -661,10 +653,8 @@ static int ingenic_drm_probe(struct platform_device *pdev)
 	}
 
 	irq = platform_get_irq(pdev, 0);
-	if (irq < 0) {
-		dev_err(dev, "Failed to get platform irq");
+	if (irq < 0)
 		return irq;
-	}
 
 	if (soc_info->needs_dev_clk) {
 		priv->lcd_clk = devm_clk_get(dev, "lcd");
@@ -730,8 +720,8 @@ static int ingenic_drm_probe(struct platform_device *pdev)
 	drm_encoder_helper_add(&priv->encoder,
 			       &ingenic_drm_encoder_helper_funcs);
 
-	ret = drm_encoder_init(drm, &priv->encoder, &ingenic_drm_encoder_funcs,
-			       DRM_MODE_ENCODER_DPI, NULL);
+	ret = drm_simple_encoder_init(drm, &priv->encoder,
+				      DRM_MODE_ENCODER_DPI);
 	if (ret) {
 		dev_err(dev, "Failed to init encoder: %i", ret);
 		return ret;
@@ -791,9 +781,7 @@ static int ingenic_drm_probe(struct platform_device *pdev)
 		goto err_devclk_disable;
 	}
 
-	ret = drm_fbdev_generic_setup(drm, 32);
-	if (ret)
-		dev_warn(dev, "Unable to start fbdev emulation: %i", ret);
+	drm_fbdev_generic_setup(drm, 32);
 
 	return 0;
 
diff --git a/drivers/gpu/drm/lima/Kconfig b/drivers/gpu/drm/lima/Kconfig
index d589f09d04d9..fa1d4f5df31e 100644
--- a/drivers/gpu/drm/lima/Kconfig
+++ b/drivers/gpu/drm/lima/Kconfig
@@ -10,5 +10,7 @@ config DRM_LIMA
        depends on OF
        select DRM_SCHED
        select DRM_GEM_SHMEM_HELPER
+       select PM_DEVFREQ
+       select DEVFREQ_GOV_SIMPLE_ONDEMAND
        help
 	 DRM driver for ARM Mali 400/450 GPUs.
diff --git a/drivers/gpu/drm/lima/Makefile b/drivers/gpu/drm/lima/Makefile
index a85444b0a1d4..ca2097b8e1ad 100644
--- a/drivers/gpu/drm/lima/Makefile
+++ b/drivers/gpu/drm/lima/Makefile
@@ -14,6 +14,8 @@ lima-y := \
 	lima_sched.o \
 	lima_ctx.o \
 	lima_dlbu.o \
-	lima_bcast.o
+	lima_bcast.o \
+	lima_trace.o \
+	lima_devfreq.o
 
 obj-$(CONFIG_DRM_LIMA) += lima.o
diff --git a/drivers/gpu/drm/lima/lima_ctx.c b/drivers/gpu/drm/lima/lima_ctx.c
index 22fff6caa961..891d5cd5019a 100644
--- a/drivers/gpu/drm/lima/lima_ctx.c
+++ b/drivers/gpu/drm/lima/lima_ctx.c
@@ -27,6 +27,9 @@ int lima_ctx_create(struct lima_device *dev, struct lima_ctx_mgr *mgr, u32 *id)
 	if (err < 0)
 		goto err_out0;
 
+	ctx->pid = task_pid_nr(current);
+	get_task_comm(ctx->pname, current);
+
 	return 0;
 
 err_out0:
diff --git a/drivers/gpu/drm/lima/lima_ctx.h b/drivers/gpu/drm/lima/lima_ctx.h
index 6154e5c9bfe4..74e2be09090f 100644
--- a/drivers/gpu/drm/lima/lima_ctx.h
+++ b/drivers/gpu/drm/lima/lima_ctx.h
@@ -5,6 +5,7 @@
 #define __LIMA_CTX_H__
 
 #include <linux/xarray.h>
+#include <linux/sched.h>
 
 #include "lima_device.h"
 
@@ -13,6 +14,10 @@ struct lima_ctx {
 	struct lima_device *dev;
 	struct lima_sched_context context[lima_pipe_num];
 	atomic_t guilty;
+
+	/* debug info */
+	char pname[TASK_COMM_LEN];
+	pid_t pid;
 };
 
 struct lima_ctx_mgr {
diff --git a/drivers/gpu/drm/lima/lima_devfreq.c b/drivers/gpu/drm/lima/lima_devfreq.c
new file mode 100644
index 000000000000..8c4d21d07529
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_devfreq.c
@@ -0,0 +1,234 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+ *
+ * Based on panfrost_devfreq.c:
+ *   Copyright 2019 Collabora ltd.
+ */
+#include <linux/clk.h>
+#include <linux/devfreq.h>
+#include <linux/devfreq_cooling.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_opp.h>
+#include <linux/property.h>
+
+#include "lima_device.h"
+#include "lima_devfreq.h"
+
+static void lima_devfreq_update_utilization(struct lima_devfreq *devfreq)
+{
+	ktime_t now, last;
+
+	now = ktime_get();
+	last = devfreq->time_last_update;
+
+	if (devfreq->busy_count > 0)
+		devfreq->busy_time += ktime_sub(now, last);
+	else
+		devfreq->idle_time += ktime_sub(now, last);
+
+	devfreq->time_last_update = now;
+}
+
+static int lima_devfreq_target(struct device *dev, unsigned long *freq,
+			       u32 flags)
+{
+	struct dev_pm_opp *opp;
+	int err;
+
+	opp = devfreq_recommended_opp(dev, freq, flags);
+	if (IS_ERR(opp))
+		return PTR_ERR(opp);
+	dev_pm_opp_put(opp);
+
+	err = dev_pm_opp_set_rate(dev, *freq);
+	if (err)
+		return err;
+
+	return 0;
+}
+
+static void lima_devfreq_reset(struct lima_devfreq *devfreq)
+{
+	devfreq->busy_time = 0;
+	devfreq->idle_time = 0;
+	devfreq->time_last_update = ktime_get();
+}
+
+static int lima_devfreq_get_dev_status(struct device *dev,
+				       struct devfreq_dev_status *status)
+{
+	struct lima_device *ldev = dev_get_drvdata(dev);
+	struct lima_devfreq *devfreq = &ldev->devfreq;
+	unsigned long irqflags;
+
+	status->current_frequency = clk_get_rate(ldev->clk_gpu);
+
+	spin_lock_irqsave(&devfreq->lock, irqflags);
+
+	lima_devfreq_update_utilization(devfreq);
+
+	status->total_time = ktime_to_ns(ktime_add(devfreq->busy_time,
+						   devfreq->idle_time));
+	status->busy_time = ktime_to_ns(devfreq->busy_time);
+
+	lima_devfreq_reset(devfreq);
+
+	spin_unlock_irqrestore(&devfreq->lock, irqflags);
+
+	dev_dbg(ldev->dev, "busy %lu total %lu %lu %% freq %lu MHz\n",
+		status->busy_time, status->total_time,
+		status->busy_time / (status->total_time / 100),
+		status->current_frequency / 1000 / 1000);
+
+	return 0;
+}
+
+static struct devfreq_dev_profile lima_devfreq_profile = {
+	.polling_ms = 50, /* ~3 frames */
+	.target = lima_devfreq_target,
+	.get_dev_status = lima_devfreq_get_dev_status,
+};
+
+void lima_devfreq_fini(struct lima_device *ldev)
+{
+	struct lima_devfreq *devfreq = &ldev->devfreq;
+
+	if (devfreq->cooling) {
+		devfreq_cooling_unregister(devfreq->cooling);
+		devfreq->cooling = NULL;
+	}
+
+	if (devfreq->devfreq) {
+		devm_devfreq_remove_device(&ldev->pdev->dev,
+					   devfreq->devfreq);
+		devfreq->devfreq = NULL;
+	}
+
+	if (devfreq->opp_of_table_added) {
+		dev_pm_opp_of_remove_table(&ldev->pdev->dev);
+		devfreq->opp_of_table_added = false;
+	}
+
+	if (devfreq->regulators_opp_table) {
+		dev_pm_opp_put_regulators(devfreq->regulators_opp_table);
+		devfreq->regulators_opp_table = NULL;
+	}
+
+	if (devfreq->clkname_opp_table) {
+		dev_pm_opp_put_clkname(devfreq->clkname_opp_table);
+		devfreq->clkname_opp_table = NULL;
+	}
+}
+
+int lima_devfreq_init(struct lima_device *ldev)
+{
+	struct thermal_cooling_device *cooling;
+	struct device *dev = &ldev->pdev->dev;
+	struct opp_table *opp_table;
+	struct devfreq *devfreq;
+	struct lima_devfreq *ldevfreq = &ldev->devfreq;
+	struct dev_pm_opp *opp;
+	unsigned long cur_freq;
+	int ret;
+
+	if (!device_property_present(dev, "operating-points-v2"))
+		/* Optional, continue without devfreq */
+		return 0;
+
+	spin_lock_init(&ldevfreq->lock);
+
+	opp_table = dev_pm_opp_set_clkname(dev, "core");
+	if (IS_ERR(opp_table)) {
+		ret = PTR_ERR(opp_table);
+		goto err_fini;
+	}
+
+	ldevfreq->clkname_opp_table = opp_table;
+
+	opp_table = dev_pm_opp_set_regulators(dev,
+					      (const char *[]){ "mali" },
+					      1);
+	if (IS_ERR(opp_table)) {
+		ret = PTR_ERR(opp_table);
+
+		/* Continue if the optional regulator is missing */
+		if (ret != -ENODEV)
+			goto err_fini;
+	} else {
+		ldevfreq->regulators_opp_table = opp_table;
+	}
+
+	ret = dev_pm_opp_of_add_table(dev);
+	if (ret)
+		goto err_fini;
+	ldevfreq->opp_of_table_added = true;
+
+	lima_devfreq_reset(ldevfreq);
+
+	cur_freq = clk_get_rate(ldev->clk_gpu);
+
+	opp = devfreq_recommended_opp(dev, &cur_freq, 0);
+	if (IS_ERR(opp)) {
+		ret = PTR_ERR(opp);
+		goto err_fini;
+	}
+
+	lima_devfreq_profile.initial_freq = cur_freq;
+	dev_pm_opp_put(opp);
+
+	devfreq = devm_devfreq_add_device(dev, &lima_devfreq_profile,
+					  DEVFREQ_GOV_SIMPLE_ONDEMAND, NULL);
+	if (IS_ERR(devfreq)) {
+		dev_err(dev, "Couldn't initialize GPU devfreq\n");
+		ret = PTR_ERR(devfreq);
+		goto err_fini;
+	}
+
+	ldevfreq->devfreq = devfreq;
+
+	cooling = of_devfreq_cooling_register(dev->of_node, devfreq);
+	if (IS_ERR(cooling))
+		dev_info(dev, "Failed to register cooling device\n");
+	else
+		ldevfreq->cooling = cooling;
+
+	return 0;
+
+err_fini:
+	lima_devfreq_fini(ldev);
+	return ret;
+}
+
+void lima_devfreq_record_busy(struct lima_devfreq *devfreq)
+{
+	unsigned long irqflags;
+
+	if (!devfreq->devfreq)
+		return;
+
+	spin_lock_irqsave(&devfreq->lock, irqflags);
+
+	lima_devfreq_update_utilization(devfreq);
+
+	devfreq->busy_count++;
+
+	spin_unlock_irqrestore(&devfreq->lock, irqflags);
+}
+
+void lima_devfreq_record_idle(struct lima_devfreq *devfreq)
+{
+	unsigned long irqflags;
+
+	if (!devfreq->devfreq)
+		return;
+
+	spin_lock_irqsave(&devfreq->lock, irqflags);
+
+	lima_devfreq_update_utilization(devfreq);
+
+	WARN_ON(--devfreq->busy_count < 0);
+
+	spin_unlock_irqrestore(&devfreq->lock, irqflags);
+}
diff --git a/drivers/gpu/drm/lima/lima_devfreq.h b/drivers/gpu/drm/lima/lima_devfreq.h
new file mode 100644
index 000000000000..8d71ba9fb22a
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_devfreq.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright 2020 Martin Blumenstingl <martin.blumenstingl@googlemail.com> */
+
+#ifndef __LIMA_DEVFREQ_H__
+#define __LIMA_DEVFREQ_H__
+
+#include <linux/spinlock.h>
+#include <linux/ktime.h>
+
+struct devfreq;
+struct opp_table;
+struct thermal_cooling_device;
+
+struct lima_device;
+
+struct lima_devfreq {
+	struct devfreq *devfreq;
+	struct opp_table *clkname_opp_table;
+	struct opp_table *regulators_opp_table;
+	struct thermal_cooling_device *cooling;
+	bool opp_of_table_added;
+
+	ktime_t busy_time;
+	ktime_t idle_time;
+	ktime_t time_last_update;
+	int busy_count;
+	/*
+	 * Protect busy_time, idle_time, time_last_update and busy_count
+	 * because these can be updated concurrently, for example by the GP
+	 * and PP interrupts.
+	 */
+	spinlock_t lock;
+};
+
+int lima_devfreq_init(struct lima_device *ldev);
+void lima_devfreq_fini(struct lima_device *ldev);
+
+void lima_devfreq_record_busy(struct lima_devfreq *devfreq);
+void lima_devfreq_record_idle(struct lima_devfreq *devfreq);
+
+#endif
diff --git a/drivers/gpu/drm/lima/lima_device.c b/drivers/gpu/drm/lima/lima_device.c
index 19829b543024..247f51fd40a2 100644
--- a/drivers/gpu/drm/lima/lima_device.c
+++ b/drivers/gpu/drm/lima/lima_device.c
@@ -214,6 +214,8 @@ static int lima_init_gp_pipe(struct lima_device *dev)
 	struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_gp;
 	int err;
 
+	pipe->ldev = dev;
+
 	err = lima_sched_pipe_init(pipe, "gp");
 	if (err)
 		return err;
@@ -244,6 +246,8 @@ static int lima_init_pp_pipe(struct lima_device *dev)
 	struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp;
 	int err, i;
 
+	pipe->ldev = dev;
+
 	err = lima_sched_pipe_init(pipe, "pp");
 	if (err)
 		return err;
@@ -344,6 +348,12 @@ int lima_device_init(struct lima_device *ldev)
 	if (err)
 		goto err_out5;
 
+	ldev->dump.magic = LIMA_DUMP_MAGIC;
+	ldev->dump.version_major = LIMA_DUMP_MAJOR;
+	ldev->dump.version_minor = LIMA_DUMP_MINOR;
+	INIT_LIST_HEAD(&ldev->error_task_list);
+	mutex_init(&ldev->error_task_list_lock);
+
 	dev_info(ldev->dev, "bus rate = %lu\n", clk_get_rate(ldev->clk_bus));
 	dev_info(ldev->dev, "mod rate = %lu", clk_get_rate(ldev->clk_gpu));
 
@@ -370,6 +380,13 @@ int lima_device_init(struct lima_device *ldev)
 void lima_device_fini(struct lima_device *ldev)
 {
 	int i;
+	struct lima_sched_error_task *et, *tmp;
+
+	list_for_each_entry_safe(et, tmp, &ldev->error_task_list, list) {
+		list_del(&et->list);
+		kvfree(et);
+	}
+	mutex_destroy(&ldev->error_task_list_lock);
 
 	lima_fini_pp_pipe(ldev);
 	lima_fini_gp_pipe(ldev);
diff --git a/drivers/gpu/drm/lima/lima_device.h b/drivers/gpu/drm/lima/lima_device.h
index 31158d86271c..06fd9636dd72 100644
--- a/drivers/gpu/drm/lima/lima_device.h
+++ b/drivers/gpu/drm/lima/lima_device.h
@@ -6,8 +6,12 @@
 
 #include <drm/drm_device.h>
 #include <linux/delay.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
 
 #include "lima_sched.h"
+#include "lima_dump.h"
+#include "lima_devfreq.h"
 
 enum lima_gpu_id {
 	lima_gpu_mali400 = 0,
@@ -94,6 +98,13 @@ struct lima_device {
 
 	u32 *dlbu_cpu;
 	dma_addr_t dlbu_dma;
+
+	struct lima_devfreq devfreq;
+
+	/* debug info */
+	struct lima_dump_head dump;
+	struct list_head error_task_list;
+	struct mutex error_task_list_lock;
 };
 
 static inline struct lima_device *
diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c
index 2daac64d8955..bbbdc8455e2f 100644
--- a/drivers/gpu/drm/lima/lima_drv.c
+++ b/drivers/gpu/drm/lima/lima_drv.c
@@ -10,12 +10,14 @@
 #include <drm/drm_prime.h>
 #include <drm/lima_drm.h>
 
+#include "lima_device.h"
 #include "lima_drv.h"
 #include "lima_gem.h"
 #include "lima_vm.h"
 
 int lima_sched_timeout_ms;
 uint lima_heap_init_nr_pages = 8;
+uint lima_max_error_tasks;
 
 MODULE_PARM_DESC(sched_timeout_ms, "task run timeout in ms");
 module_param_named(sched_timeout_ms, lima_sched_timeout_ms, int, 0444);
@@ -23,6 +25,9 @@ module_param_named(sched_timeout_ms, lima_sched_timeout_ms, int, 0444);
 MODULE_PARM_DESC(heap_init_nr_pages, "heap buffer init number of pages");
 module_param_named(heap_init_nr_pages, lima_heap_init_nr_pages, uint, 0444);
 
+MODULE_PARM_DESC(max_error_tasks, "max number of error tasks to save");
+module_param_named(max_error_tasks, lima_max_error_tasks, uint, 0644);
+
 static int lima_ioctl_get_param(struct drm_device *dev, void *data, struct drm_file *file)
 {
 	struct drm_lima_get_param *args = data;
@@ -272,6 +277,93 @@ static struct drm_driver lima_drm_driver = {
 	.gem_prime_mmap = drm_gem_prime_mmap,
 };
 
+struct lima_block_reader {
+	void *dst;
+	size_t base;
+	size_t count;
+	size_t off;
+	ssize_t read;
+};
+
+static bool lima_read_block(struct lima_block_reader *reader,
+			    void *src, size_t src_size)
+{
+	size_t max_off = reader->base + src_size;
+
+	if (reader->off < max_off) {
+		size_t size = min_t(size_t, max_off - reader->off,
+				    reader->count);
+
+		memcpy(reader->dst, src + (reader->off - reader->base), size);
+
+		reader->dst += size;
+		reader->off += size;
+		reader->read += size;
+		reader->count -= size;
+	}
+
+	reader->base = max_off;
+
+	return !!reader->count;
+}
+
+static ssize_t lima_error_state_read(struct file *filp, struct kobject *kobj,
+				     struct bin_attribute *attr, char *buf,
+				     loff_t off, size_t count)
+{
+	struct device *dev = kobj_to_dev(kobj);
+	struct lima_device *ldev = dev_get_drvdata(dev);
+	struct lima_sched_error_task *et;
+	struct lima_block_reader reader = {
+		.dst = buf,
+		.count = count,
+		.off = off,
+	};
+
+	mutex_lock(&ldev->error_task_list_lock);
+
+	if (lima_read_block(&reader, &ldev->dump, sizeof(ldev->dump))) {
+		list_for_each_entry(et, &ldev->error_task_list, list) {
+			if (!lima_read_block(&reader, et->data, et->size))
+				break;
+		}
+	}
+
+	mutex_unlock(&ldev->error_task_list_lock);
+	return reader.read;
+}
+
+static ssize_t lima_error_state_write(struct file *file, struct kobject *kobj,
+				      struct bin_attribute *attr, char *buf,
+				      loff_t off, size_t count)
+{
+	struct device *dev = kobj_to_dev(kobj);
+	struct lima_device *ldev = dev_get_drvdata(dev);
+	struct lima_sched_error_task *et, *tmp;
+
+	mutex_lock(&ldev->error_task_list_lock);
+
+	list_for_each_entry_safe(et, tmp, &ldev->error_task_list, list) {
+		list_del(&et->list);
+		kvfree(et);
+	}
+
+	ldev->dump.size = 0;
+	ldev->dump.num_tasks = 0;
+
+	mutex_unlock(&ldev->error_task_list_lock);
+
+	return count;
+}
+
+static const struct bin_attribute lima_error_state_attr = {
+	.attr.name = "error",
+	.attr.mode = 0600,
+	.size = 0,
+	.read = lima_error_state_read,
+	.write = lima_error_state_write,
+};
+
 static int lima_pdev_probe(struct platform_device *pdev)
 {
 	struct lima_device *ldev;
@@ -306,18 +398,31 @@ static int lima_pdev_probe(struct platform_device *pdev)
 	if (err)
 		goto err_out1;
 
+	err = lima_devfreq_init(ldev);
+	if (err) {
+		dev_err(&pdev->dev, "Fatal error during devfreq init\n");
+		goto err_out2;
+	}
+
 	/*
 	 * Register the DRM device with the core and the connectors with
 	 * sysfs.
 	 */
 	err = drm_dev_register(ddev, 0);
 	if (err < 0)
-		goto err_out2;
+		goto err_out3;
+
+	platform_set_drvdata(pdev, ldev);
+
+	if (sysfs_create_bin_file(&ldev->dev->kobj, &lima_error_state_attr))
+		dev_warn(ldev->dev, "fail to create error state sysfs\n");
 
 	return 0;
 
-err_out2:
+err_out3:
 	lima_device_fini(ldev);
+err_out2:
+	lima_devfreq_fini(ldev);
 err_out1:
 	drm_dev_put(ddev);
 err_out0:
@@ -330,7 +435,10 @@ static int lima_pdev_remove(struct platform_device *pdev)
 	struct lima_device *ldev = platform_get_drvdata(pdev);
 	struct drm_device *ddev = ldev->ddev;
 
+	sysfs_remove_bin_file(&ldev->dev->kobj, &lima_error_state_attr);
+	platform_set_drvdata(pdev, NULL);
 	drm_dev_unregister(ddev);
+	lima_devfreq_fini(ldev);
 	lima_device_fini(ldev);
 	drm_dev_put(ddev);
 	lima_sched_slab_fini();
diff --git a/drivers/gpu/drm/lima/lima_drv.h b/drivers/gpu/drm/lima/lima_drv.h
index f492ecc6a5d9..fdbd4077c768 100644
--- a/drivers/gpu/drm/lima/lima_drv.h
+++ b/drivers/gpu/drm/lima/lima_drv.h
@@ -10,6 +10,7 @@
 
 extern int lima_sched_timeout_ms;
 extern uint lima_heap_init_nr_pages;
+extern uint lima_max_error_tasks;
 
 struct lima_vm;
 struct lima_bo;
diff --git a/drivers/gpu/drm/lima/lima_dump.h b/drivers/gpu/drm/lima/lima_dump.h
new file mode 100644
index 000000000000..ca243d99c51b
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_dump.h
@@ -0,0 +1,77 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/* Copyright 2020 Qiang Yu <yuq825@gmail.com> */
+
+#ifndef __LIMA_DUMP_H__
+#define __LIMA_DUMP_H__
+
+#include <linux/types.h>
+
+/**
+ * dump file format for all the information to start a lima task
+ *
+ * top level format
+ * | magic code "LIMA" | format version | num tasks | data size |
+ * | reserved | reserved | reserved | reserved |
+ * | task 1 ID | task 1 size | num chunks | reserved | task 1 data |
+ * | task 2 ID | task 2 size | num chunks | reserved | task 2 data |
+ * ...
+ *
+ * task data format
+ * | chunk 1 ID | chunk 1 size | reserved | reserved | chunk 1 data |
+ * | chunk 2 ID | chunk 2 size | reserved | reserved | chunk 2 data |
+ * ...
+ *
+ */
+
+#define LIMA_DUMP_MAJOR 1
+#define LIMA_DUMP_MINOR 0
+
+#define LIMA_DUMP_MAGIC 0x414d494c
+
+struct lima_dump_head {
+	__u32 magic;
+	__u16 version_major;
+	__u16 version_minor;
+	__u32 num_tasks;
+	__u32 size;
+	__u32 reserved[4];
+};
+
+#define LIMA_DUMP_TASK_GP   0
+#define LIMA_DUMP_TASK_PP   1
+#define LIMA_DUMP_TASK_NUM  2
+
+struct lima_dump_task {
+	__u32 id;
+	__u32 size;
+	__u32 num_chunks;
+	__u32 reserved;
+};
+
+#define LIMA_DUMP_CHUNK_FRAME         0
+#define LIMA_DUMP_CHUNK_BUFFER        1
+#define LIMA_DUMP_CHUNK_PROCESS_NAME  2
+#define LIMA_DUMP_CHUNK_PROCESS_ID    3
+#define LIMA_DUMP_CHUNK_NUM           4
+
+struct lima_dump_chunk {
+	__u32 id;
+	__u32 size;
+	__u32 reserved[2];
+};
+
+struct lima_dump_chunk_buffer {
+	__u32 id;
+	__u32 size;
+	__u32 va;
+	__u32 reserved;
+};
+
+struct lima_dump_chunk_pid {
+	__u32 id;
+	__u32 size;
+	__u32 pid;
+	__u32 reserved;
+};
+
+#endif
diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c
index 3886999b4533..a2db1c937424 100644
--- a/drivers/gpu/drm/lima/lima_sched.c
+++ b/drivers/gpu/drm/lima/lima_sched.c
@@ -3,14 +3,16 @@
 
 #include <linux/kthread.h>
 #include <linux/slab.h>
-#include <linux/xarray.h>
+#include <linux/vmalloc.h>
 
+#include "lima_devfreq.h"
 #include "lima_drv.h"
 #include "lima_sched.h"
 #include "lima_vm.h"
 #include "lima_mmu.h"
 #include "lima_l2_cache.h"
 #include "lima_gem.h"
+#include "lima_trace.h"
 
 struct lima_fence {
 	struct dma_fence base;
@@ -176,6 +178,7 @@ struct dma_fence *lima_sched_context_queue_task(struct lima_sched_context *conte
 {
 	struct dma_fence *fence = dma_fence_get(&task->base.s_fence->finished);
 
+	trace_lima_task_submit(task);
 	drm_sched_entity_push_job(&task->base, &context->base);
 	return fence;
 }
@@ -214,6 +217,8 @@ static struct dma_fence *lima_sched_run_job(struct drm_sched_job *job)
 	 */
 	ret = dma_fence_get(task->fence);
 
+	lima_devfreq_record_busy(&pipe->ldev->devfreq);
+
 	pipe->current_task = task;
 
 	/* this is needed for MMU to work correctly, otherwise GP/PP
@@ -250,12 +255,141 @@ static struct dma_fence *lima_sched_run_job(struct drm_sched_job *job)
 	if (last_vm)
 		lima_vm_put(last_vm);
 
+	trace_lima_task_run(task);
+
 	pipe->error = false;
 	pipe->task_run(pipe, task);
 
 	return task->fence;
 }
 
+static void lima_sched_build_error_task_list(struct lima_sched_task *task)
+{
+	struct lima_sched_error_task *et;
+	struct lima_sched_pipe *pipe = to_lima_pipe(task->base.sched);
+	struct lima_ip *ip = pipe->processor[0];
+	int pipe_id = ip->id == lima_ip_gp ? lima_pipe_gp : lima_pipe_pp;
+	struct lima_device *dev = ip->dev;
+	struct lima_sched_context *sched_ctx =
+		container_of(task->base.entity,
+			     struct lima_sched_context, base);
+	struct lima_ctx *ctx =
+		container_of(sched_ctx, struct lima_ctx, context[pipe_id]);
+	struct lima_dump_task *dt;
+	struct lima_dump_chunk *chunk;
+	struct lima_dump_chunk_pid *pid_chunk;
+	struct lima_dump_chunk_buffer *buffer_chunk;
+	u32 size, task_size, mem_size;
+	int i;
+
+	mutex_lock(&dev->error_task_list_lock);
+
+	if (dev->dump.num_tasks >= lima_max_error_tasks) {
+		dev_info(dev->dev, "fail to save task state: error task list is full\n");
+		goto out;
+	}
+
+	/* frame chunk */
+	size = sizeof(struct lima_dump_chunk) + pipe->frame_size;
+	/* process name chunk */
+	size += sizeof(struct lima_dump_chunk) + sizeof(ctx->pname);
+	/* pid chunk */
+	size += sizeof(struct lima_dump_chunk);
+	/* buffer chunks */
+	for (i = 0; i < task->num_bos; i++) {
+		struct lima_bo *bo = task->bos[i];
+
+		size += sizeof(struct lima_dump_chunk);
+		size += bo->heap_size ? bo->heap_size : lima_bo_size(bo);
+	}
+
+	task_size = size + sizeof(struct lima_dump_task);
+	mem_size = task_size + sizeof(*et);
+	et = kvmalloc(mem_size, GFP_KERNEL);
+	if (!et) {
+		dev_err(dev->dev, "fail to alloc task dump buffer of size %x\n",
+			mem_size);
+		goto out;
+	}
+
+	et->data = et + 1;
+	et->size = task_size;
+
+	dt = et->data;
+	memset(dt, 0, sizeof(*dt));
+	dt->id = pipe_id;
+	dt->size = size;
+
+	chunk = (struct lima_dump_chunk *)(dt + 1);
+	memset(chunk, 0, sizeof(*chunk));
+	chunk->id = LIMA_DUMP_CHUNK_FRAME;
+	chunk->size = pipe->frame_size;
+	memcpy(chunk + 1, task->frame, pipe->frame_size);
+	dt->num_chunks++;
+
+	chunk = (void *)(chunk + 1) + chunk->size;
+	memset(chunk, 0, sizeof(*chunk));
+	chunk->id = LIMA_DUMP_CHUNK_PROCESS_NAME;
+	chunk->size = sizeof(ctx->pname);
+	memcpy(chunk + 1, ctx->pname, sizeof(ctx->pname));
+	dt->num_chunks++;
+
+	pid_chunk = (void *)(chunk + 1) + chunk->size;
+	memset(pid_chunk, 0, sizeof(*pid_chunk));
+	pid_chunk->id = LIMA_DUMP_CHUNK_PROCESS_ID;
+	pid_chunk->pid = ctx->pid;
+	dt->num_chunks++;
+
+	buffer_chunk = (void *)(pid_chunk + 1) + pid_chunk->size;
+	for (i = 0; i < task->num_bos; i++) {
+		struct lima_bo *bo = task->bos[i];
+		void *data;
+
+		memset(buffer_chunk, 0, sizeof(*buffer_chunk));
+		buffer_chunk->id = LIMA_DUMP_CHUNK_BUFFER;
+		buffer_chunk->va = lima_vm_get_va(task->vm, bo);
+
+		if (bo->heap_size) {
+			buffer_chunk->size = bo->heap_size;
+
+			data = vmap(bo->base.pages, bo->heap_size >> PAGE_SHIFT,
+				    VM_MAP, pgprot_writecombine(PAGE_KERNEL));
+			if (!data) {
+				kvfree(et);
+				goto out;
+			}
+
+			memcpy(buffer_chunk + 1, data, buffer_chunk->size);
+
+			vunmap(data);
+		} else {
+			buffer_chunk->size = lima_bo_size(bo);
+
+			data = drm_gem_shmem_vmap(&bo->base.base);
+			if (IS_ERR_OR_NULL(data)) {
+				kvfree(et);
+				goto out;
+			}
+
+			memcpy(buffer_chunk + 1, data, buffer_chunk->size);
+
+			drm_gem_shmem_vunmap(&bo->base.base, data);
+		}
+
+		buffer_chunk = (void *)(buffer_chunk + 1) + buffer_chunk->size;
+		dt->num_chunks++;
+	}
+
+	list_add(&et->list, &dev->error_task_list);
+	dev->dump.size += et->size;
+	dev->dump.num_tasks++;
+
+	dev_info(dev->dev, "save error task state success\n");
+
+out:
+	mutex_unlock(&dev->error_task_list_lock);
+}
+
 static void lima_sched_timedout_job(struct drm_sched_job *job)
 {
 	struct lima_sched_pipe *pipe = to_lima_pipe(job->sched);
@@ -268,6 +402,8 @@ static void lima_sched_timedout_job(struct drm_sched_job *job)
 
 	drm_sched_increase_karma(&task->base);
 
+	lima_sched_build_error_task_list(task);
+
 	pipe->task_error(pipe);
 
 	if (pipe->bcast_mmu)
@@ -285,6 +421,8 @@ static void lima_sched_timedout_job(struct drm_sched_job *job)
 	pipe->current_vm = NULL;
 	pipe->current_task = NULL;
 
+	lima_devfreq_record_idle(&pipe->ldev->devfreq);
+
 	drm_sched_resubmit_jobs(&pipe->base);
 	drm_sched_start(&pipe->base, true);
 }
@@ -364,5 +502,7 @@ void lima_sched_pipe_task_done(struct lima_sched_pipe *pipe)
 	} else {
 		pipe->task_fini(pipe);
 		dma_fence_signal(task->fence);
+
+		lima_devfreq_record_idle(&pipe->ldev->devfreq);
 	}
 }
diff --git a/drivers/gpu/drm/lima/lima_sched.h b/drivers/gpu/drm/lima/lima_sched.h
index d64393fb50a9..90f03c48ef4a 100644
--- a/drivers/gpu/drm/lima/lima_sched.h
+++ b/drivers/gpu/drm/lima/lima_sched.h
@@ -5,9 +5,18 @@
 #define __LIMA_SCHED_H__
 
 #include <drm/gpu_scheduler.h>
+#include <linux/list.h>
+#include <linux/xarray.h>
 
+struct lima_device;
 struct lima_vm;
 
+struct lima_sched_error_task {
+	struct list_head list;
+	void *data;
+	u32 size;
+};
+
 struct lima_sched_task {
 	struct drm_sched_job base;
 
@@ -44,6 +53,8 @@ struct lima_sched_pipe {
 	u32 fence_seqno;
 	spinlock_t fence_lock;
 
+	struct lima_device *ldev;
+
 	struct lima_sched_task *current_task;
 	struct lima_vm *current_vm;
 
diff --git a/drivers/gpu/drm/lima/lima_trace.c b/drivers/gpu/drm/lima/lima_trace.c
new file mode 100644
index 000000000000..ea1c7289bebc
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_trace.c
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/* Copyright 2020 Qiang Yu <yuq825@gmail.com> */
+
+#include "lima_sched.h"
+
+#define CREATE_TRACE_POINTS
+#include "lima_trace.h"
diff --git a/drivers/gpu/drm/lima/lima_trace.h b/drivers/gpu/drm/lima/lima_trace.h
new file mode 100644
index 000000000000..3a430e93d384
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_trace.h
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/* Copyright 2020 Qiang Yu <yuq825@gmail.com> */
+
+#if !defined(_LIMA_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _LIMA_TRACE_H_
+
+#include <linux/tracepoint.h>
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM lima
+#define TRACE_INCLUDE_FILE lima_trace
+
+DECLARE_EVENT_CLASS(lima_task,
+	TP_PROTO(struct lima_sched_task *task),
+	TP_ARGS(task),
+	TP_STRUCT__entry(
+		__field(uint64_t, task_id)
+		__field(unsigned int, context)
+		__field(unsigned int, seqno)
+		__string(pipe, task->base.sched->name)
+		),
+
+	TP_fast_assign(
+		__entry->task_id = task->base.id;
+		__entry->context = task->base.s_fence->finished.context;
+		__entry->seqno = task->base.s_fence->finished.seqno;
+		__assign_str(pipe, task->base.sched->name)
+		),
+
+	TP_printk("task=%llu, context=%u seqno=%u pipe=%s",
+		  __entry->task_id, __entry->context, __entry->seqno,
+		  __get_str(pipe))
+);
+
+DEFINE_EVENT(lima_task, lima_task_submit,
+	     TP_PROTO(struct lima_sched_task *task),
+	     TP_ARGS(task)
+);
+
+DEFINE_EVENT(lima_task, lima_task_run,
+	     TP_PROTO(struct lima_sched_task *task),
+	     TP_ARGS(task)
+);
+
+#endif
+
+/* This part must be outside protection */
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH ../../drivers/gpu/drm/lima
+#include <trace/define_trace.h>
diff --git a/drivers/gpu/drm/mcde/mcde_drv.c b/drivers/gpu/drm/mcde/mcde_drv.c
index f28cb7a576ba..88cc6b4a7a64 100644
--- a/drivers/gpu/drm/mcde/mcde_drv.c
+++ b/drivers/gpu/drm/mcde/mcde_drv.c
@@ -72,6 +72,7 @@
 #include <drm/drm_gem.h>
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_of.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/drm_panel.h>
@@ -183,13 +184,13 @@ static int mcde_modeset_init(struct drm_device *drm)
 	ret = drm_vblank_init(drm, 1);
 	if (ret) {
 		dev_err(drm->dev, "failed to init vblank\n");
-		goto out_config;
+		return ret;
 	}
 
 	ret = mcde_display_init(drm);
 	if (ret) {
 		dev_err(drm->dev, "failed to init display\n");
-		goto out_config;
+		return ret;
 	}
 
 	/*
@@ -203,7 +204,7 @@ static int mcde_modeset_init(struct drm_device *drm)
 						    mcde->bridge);
 	if (ret) {
 		dev_err(drm->dev, "failed to attach display output bridge\n");
-		goto out_config;
+		return ret;
 	}
 
 	drm_mode_config_reset(drm);
@@ -211,19 +212,6 @@ static int mcde_modeset_init(struct drm_device *drm)
 	drm_fbdev_generic_setup(drm, 32);
 
 	return 0;
-
-out_config:
-	drm_mode_config_cleanup(drm);
-	return ret;
-}
-
-static void mcde_release(struct drm_device *drm)
-{
-	struct mcde *mcde = drm->dev_private;
-
-	drm_mode_config_cleanup(drm);
-	drm_dev_fini(drm);
-	kfree(mcde);
 }
 
 DEFINE_DRM_GEM_CMA_FOPS(drm_fops);
@@ -231,7 +219,6 @@ DEFINE_DRM_GEM_CMA_FOPS(drm_fops);
 static struct drm_driver mcde_drm_driver = {
 	.driver_features =
 		DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
-	.release = mcde_release,
 	.lastclose = drm_fb_helper_lastclose,
 	.ioctls = NULL,
 	.fops = &drm_fops,
@@ -259,7 +246,9 @@ static int mcde_drm_bind(struct device *dev)
 	struct drm_device *drm = dev_get_drvdata(dev);
 	int ret;
 
-	drm_mode_config_init(drm);
+	ret = drmm_mode_config_init(drm);
+	if (ret)
+		return ret;
 
 	ret = component_bind_all(drm->dev, drm);
 	if (ret) {
@@ -323,13 +312,14 @@ static int mcde_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	mcde->dev = dev;
 
-	ret = drm_dev_init(&mcde->drm, &mcde_drm_driver, dev);
+	ret = devm_drm_dev_init(dev, &mcde->drm, &mcde_drm_driver);
 	if (ret) {
 		kfree(mcde);
 		return ret;
 	}
 	drm = &mcde->drm;
 	drm->dev_private = mcde;
+	drmm_add_final_kfree(drm, mcde);
 	platform_set_drvdata(pdev, drm);
 
 	/* Enable continuous updates: this is what Linux' framebuffer expects */
@@ -341,12 +331,12 @@ static int mcde_probe(struct platform_device *pdev)
 	if (IS_ERR(mcde->epod)) {
 		ret = PTR_ERR(mcde->epod);
 		dev_err(dev, "can't get EPOD regulator\n");
-		goto dev_unref;
+		return ret;
 	}
 	ret = regulator_enable(mcde->epod);
 	if (ret) {
 		dev_err(dev, "can't enable EPOD regulator\n");
-		goto dev_unref;
+		return ret;
 	}
 	mcde->vana = devm_regulator_get(dev, "vana");
 	if (IS_ERR(mcde->vana)) {
@@ -497,8 +487,6 @@ static int mcde_probe(struct platform_device *pdev)
 	regulator_disable(mcde->vana);
 regulator_epod_off:
 	regulator_disable(mcde->epod);
-dev_unref:
-	drm_dev_put(drm);
 	return ret;
 
 }
@@ -512,7 +500,6 @@ static int mcde_remove(struct platform_device *pdev)
 	clk_disable_unprepare(mcde->mcde_clk);
 	regulator_disable(mcde->vana);
 	regulator_disable(mcde->epod);
-	drm_dev_put(drm);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/mediatek/Kconfig b/drivers/gpu/drm/mediatek/Kconfig
index fa5ffc4fe823..c420f5a3d33b 100644
--- a/drivers/gpu/drm/mediatek/Kconfig
+++ b/drivers/gpu/drm/mediatek/Kconfig
@@ -11,6 +11,7 @@ config DRM_MEDIATEK
 	select DRM_MIPI_DSI
 	select DRM_PANEL
 	select MEMORY
+	select MTK_MMSYS
 	select MTK_SMI
 	select VIDEOMODE_HELPERS
 	help
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_color.c b/drivers/gpu/drm/mediatek/mtk_disp_color.c
index 6fb0d6983a4a..3ae9c810845b 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_color.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_color.c
@@ -119,7 +119,10 @@ static int mtk_disp_color_probe(struct platform_device *pdev)
 	ret = mtk_ddp_comp_init(dev, dev->of_node, &priv->ddp_comp, comp_id,
 				&mtk_disp_color_funcs);
 	if (ret) {
-		dev_err(dev, "Failed to initialize component: %d\n", ret);
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "Failed to initialize component: %d\n",
+				ret);
+
 		return ret;
 	}
 
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 891d80c73e04..28651bc579bc 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -386,7 +386,10 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev)
 	ret = mtk_ddp_comp_init(dev, dev->of_node, &priv->ddp_comp, comp_id,
 				&mtk_disp_ovl_funcs);
 	if (ret) {
-		dev_err(dev, "Failed to initialize component: %d\n", ret);
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "Failed to initialize component: %d\n",
+				ret);
+
 		return ret;
 	}
 
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
index 0cb848d64206..e04319fedf46 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
@@ -294,7 +294,10 @@ static int mtk_disp_rdma_probe(struct platform_device *pdev)
 	ret = mtk_ddp_comp_init(dev, dev->of_node, &priv->ddp_comp, comp_id,
 				&mtk_disp_rdma_funcs);
 	if (ret) {
-		dev_err(dev, "Failed to initialize component: %d\n", ret);
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "Failed to initialize component: %d\n",
+				ret);
+
 		return ret;
 	}
 
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 4f0ce4cd5b8c..e290407db166 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -20,6 +20,7 @@
 #include <drm/drm_bridge.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_of.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "mtk_dpi_regs.h"
 #include "mtk_drm_ddp_comp.h"
@@ -509,15 +510,6 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 	return 0;
 }
 
-static void mtk_dpi_encoder_destroy(struct drm_encoder *encoder)
-{
-	drm_encoder_cleanup(encoder);
-}
-
-static const struct drm_encoder_funcs mtk_dpi_encoder_funcs = {
-	.destroy = mtk_dpi_encoder_destroy,
-};
-
 static bool mtk_dpi_encoder_mode_fixup(struct drm_encoder *encoder,
 				       const struct drm_display_mode *mode,
 				       struct drm_display_mode *adjusted_mode)
@@ -596,8 +588,8 @@ static int mtk_dpi_bind(struct device *dev, struct device *master, void *data)
 		return ret;
 	}
 
-	ret = drm_encoder_init(drm_dev, &dpi->encoder, &mtk_dpi_encoder_funcs,
-			       DRM_MODE_ENCODER_TMDS, NULL);
+	ret = drm_simple_encoder_init(drm_dev, &dpi->encoder,
+				      DRM_MODE_ENCODER_TMDS);
 	if (ret) {
 		dev_err(dev, "Failed to initialize decoder: %d\n", ret);
 		goto err_unregister;
@@ -716,21 +708,27 @@ static int mtk_dpi_probe(struct platform_device *pdev)
 	dpi->engine_clk = devm_clk_get(dev, "engine");
 	if (IS_ERR(dpi->engine_clk)) {
 		ret = PTR_ERR(dpi->engine_clk);
-		dev_err(dev, "Failed to get engine clock: %d\n", ret);
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "Failed to get engine clock: %d\n", ret);
+
 		return ret;
 	}
 
 	dpi->pixel_clk = devm_clk_get(dev, "pixel");
 	if (IS_ERR(dpi->pixel_clk)) {
 		ret = PTR_ERR(dpi->pixel_clk);
-		dev_err(dev, "Failed to get pixel clock: %d\n", ret);
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "Failed to get pixel clock: %d\n", ret);
+
 		return ret;
 	}
 
 	dpi->tvd_clk = devm_clk_get(dev, "pll");
 	if (IS_ERR(dpi->tvd_clk)) {
 		ret = PTR_ERR(dpi->tvd_clk);
-		dev_err(dev, "Failed to get tvdpll clock: %d\n", ret);
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "Failed to get tvdpll clock: %d\n", ret);
+
 		return ret;
 	}
 
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index fe85e487e477..fe46c4bac64d 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -6,6 +6,7 @@
 #include <linux/clk.h>
 #include <linux/pm_runtime.h>
 #include <linux/soc/mediatek/mtk-cmdq.h>
+#include <linux/soc/mediatek/mtk-mmsys.h>
 
 #include <asm/barrier.h>
 #include <soc/mediatek/smi.h>
@@ -28,7 +29,7 @@
  * @enabled: records whether crtc_enable succeeded
  * @planes: array of 4 drm_plane structures, one for each overlay plane
  * @pending_planes: whether any plane has pending changes to be applied
- * @config_regs: memory mapped mmsys configuration register space
+ * @mmsys_dev: pointer to the mmsys device for configuration registers
  * @mutex: handle to one of the ten disp_mutex streams
  * @ddp_comp_nr: number of components in ddp_comp
  * @ddp_comp: array of pointers the mtk_ddp_comp structures used by this crtc
@@ -50,7 +51,7 @@ struct mtk_drm_crtc {
 	u32				cmdq_event;
 #endif
 
-	void __iomem			*config_regs;
+	struct device			*mmsys_dev;
 	struct mtk_disp_mutex		*mutex;
 	unsigned int			ddp_comp_nr;
 	struct mtk_ddp_comp		**ddp_comp;
@@ -300,9 +301,9 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc)
 
 	DRM_DEBUG_DRIVER("mediatek_ddp_ddp_path_setup\n");
 	for (i = 0; i < mtk_crtc->ddp_comp_nr - 1; i++) {
-		mtk_ddp_add_comp_to_path(mtk_crtc->config_regs,
-					 mtk_crtc->ddp_comp[i]->id,
-					 mtk_crtc->ddp_comp[i + 1]->id);
+		mtk_mmsys_ddp_connect(mtk_crtc->mmsys_dev,
+				      mtk_crtc->ddp_comp[i]->id,
+				      mtk_crtc->ddp_comp[i + 1]->id);
 		mtk_disp_mutex_add_comp(mtk_crtc->mutex,
 					mtk_crtc->ddp_comp[i]->id);
 	}
@@ -360,9 +361,9 @@ static void mtk_crtc_ddp_hw_fini(struct mtk_drm_crtc *mtk_crtc)
 					   mtk_crtc->ddp_comp[i]->id);
 	mtk_disp_mutex_disable(mtk_crtc->mutex);
 	for (i = 0; i < mtk_crtc->ddp_comp_nr - 1; i++) {
-		mtk_ddp_remove_comp_from_path(mtk_crtc->config_regs,
-					      mtk_crtc->ddp_comp[i]->id,
-					      mtk_crtc->ddp_comp[i + 1]->id);
+		mtk_mmsys_ddp_disconnect(mtk_crtc->mmsys_dev,
+					 mtk_crtc->ddp_comp[i]->id,
+					 mtk_crtc->ddp_comp[i + 1]->id);
 		mtk_disp_mutex_remove_comp(mtk_crtc->mutex,
 					   mtk_crtc->ddp_comp[i]->id);
 	}
@@ -766,7 +767,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
 	if (!mtk_crtc)
 		return -ENOMEM;
 
-	mtk_crtc->config_regs = priv->config_regs;
+	mtk_crtc->mmsys_dev = priv->mmsys_dev;
 	mtk_crtc->ddp_comp_nr = path_len;
 	mtk_crtc->ddp_comp = devm_kmalloc_array(dev, mtk_crtc->ddp_comp_nr,
 						sizeof(*mtk_crtc->ddp_comp),
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
index 13035c906035..014c1bbe1df2 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
@@ -13,26 +13,6 @@
 #include "mtk_drm_ddp.h"
 #include "mtk_drm_ddp_comp.h"
 
-#define DISP_REG_CONFIG_DISP_OVL0_MOUT_EN	0x040
-#define DISP_REG_CONFIG_DISP_OVL1_MOUT_EN	0x044
-#define DISP_REG_CONFIG_DISP_OD_MOUT_EN		0x048
-#define DISP_REG_CONFIG_DISP_GAMMA_MOUT_EN	0x04c
-#define DISP_REG_CONFIG_DISP_UFOE_MOUT_EN	0x050
-#define DISP_REG_CONFIG_DISP_COLOR0_SEL_IN	0x084
-#define DISP_REG_CONFIG_DISP_COLOR1_SEL_IN	0x088
-#define DISP_REG_CONFIG_DSIE_SEL_IN		0x0a4
-#define DISP_REG_CONFIG_DSIO_SEL_IN		0x0a8
-#define DISP_REG_CONFIG_DPI_SEL_IN		0x0ac
-#define DISP_REG_CONFIG_DISP_RDMA2_SOUT		0x0b8
-#define DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN	0x0c4
-#define DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN	0x0c8
-#define DISP_REG_CONFIG_MMSYS_CG_CON0		0x100
-
-#define DISP_REG_CONFIG_DISP_OVL_MOUT_EN	0x030
-#define DISP_REG_CONFIG_OUT_SEL			0x04c
-#define DISP_REG_CONFIG_DSI_SEL			0x050
-#define DISP_REG_CONFIG_DPI_SEL			0x064
-
 #define MT2701_DISP_MUTEX0_MOD0			0x2c
 #define MT2701_DISP_MUTEX0_SOF0			0x30
 
@@ -94,48 +74,6 @@
 #define MUTEX_SOF_DSI2			5
 #define MUTEX_SOF_DSI3			6
 
-#define OVL0_MOUT_EN_COLOR0		0x1
-#define OD_MOUT_EN_RDMA0		0x1
-#define OD1_MOUT_EN_RDMA1		BIT(16)
-#define UFOE_MOUT_EN_DSI0		0x1
-#define COLOR0_SEL_IN_OVL0		0x1
-#define OVL1_MOUT_EN_COLOR1		0x1
-#define GAMMA_MOUT_EN_RDMA1		0x1
-#define RDMA0_SOUT_DPI0			0x2
-#define RDMA0_SOUT_DPI1			0x3
-#define RDMA0_SOUT_DSI1			0x1
-#define RDMA0_SOUT_DSI2			0x4
-#define RDMA0_SOUT_DSI3			0x5
-#define RDMA1_SOUT_DPI0			0x2
-#define RDMA1_SOUT_DPI1			0x3
-#define RDMA1_SOUT_DSI1			0x1
-#define RDMA1_SOUT_DSI2			0x4
-#define RDMA1_SOUT_DSI3			0x5
-#define RDMA2_SOUT_DPI0			0x2
-#define RDMA2_SOUT_DPI1			0x3
-#define RDMA2_SOUT_DSI1			0x1
-#define RDMA2_SOUT_DSI2			0x4
-#define RDMA2_SOUT_DSI3			0x5
-#define DPI0_SEL_IN_RDMA1		0x1
-#define DPI0_SEL_IN_RDMA2		0x3
-#define DPI1_SEL_IN_RDMA1		(0x1 << 8)
-#define DPI1_SEL_IN_RDMA2		(0x3 << 8)
-#define DSI0_SEL_IN_RDMA1		0x1
-#define DSI0_SEL_IN_RDMA2		0x4
-#define DSI1_SEL_IN_RDMA1		0x1
-#define DSI1_SEL_IN_RDMA2		0x4
-#define DSI2_SEL_IN_RDMA1		(0x1 << 16)
-#define DSI2_SEL_IN_RDMA2		(0x4 << 16)
-#define DSI3_SEL_IN_RDMA1		(0x1 << 16)
-#define DSI3_SEL_IN_RDMA2		(0x4 << 16)
-#define COLOR1_SEL_IN_OVL1		0x1
-
-#define OVL_MOUT_EN_RDMA		0x1
-#define BLS_TO_DSI_RDMA1_TO_DPI1	0x8
-#define BLS_TO_DPI_RDMA1_TO_DSI		0x2
-#define DSI_SEL_IN_BLS			0x0
-#define DPI_SEL_IN_BLS			0x0
-#define DSI_SEL_IN_RDMA			0x1
 
 struct mtk_disp_mutex {
 	int id;
@@ -246,200 +184,6 @@ static const struct mtk_ddp_data mt8173_ddp_driver_data = {
 	.mutex_sof_reg = MT2701_DISP_MUTEX0_SOF0,
 };
 
-static unsigned int mtk_ddp_mout_en(enum mtk_ddp_comp_id cur,
-				    enum mtk_ddp_comp_id next,
-				    unsigned int *addr)
-{
-	unsigned int value;
-
-	if (cur == DDP_COMPONENT_OVL0 && next == DDP_COMPONENT_COLOR0) {
-		*addr = DISP_REG_CONFIG_DISP_OVL0_MOUT_EN;
-		value = OVL0_MOUT_EN_COLOR0;
-	} else if (cur == DDP_COMPONENT_OVL0 && next == DDP_COMPONENT_RDMA0) {
-		*addr = DISP_REG_CONFIG_DISP_OVL_MOUT_EN;
-		value = OVL_MOUT_EN_RDMA;
-	} else if (cur == DDP_COMPONENT_OD0 && next == DDP_COMPONENT_RDMA0) {
-		*addr = DISP_REG_CONFIG_DISP_OD_MOUT_EN;
-		value = OD_MOUT_EN_RDMA0;
-	} else if (cur == DDP_COMPONENT_UFOE && next == DDP_COMPONENT_DSI0) {
-		*addr = DISP_REG_CONFIG_DISP_UFOE_MOUT_EN;
-		value = UFOE_MOUT_EN_DSI0;
-	} else if (cur == DDP_COMPONENT_OVL1 && next == DDP_COMPONENT_COLOR1) {
-		*addr = DISP_REG_CONFIG_DISP_OVL1_MOUT_EN;
-		value = OVL1_MOUT_EN_COLOR1;
-	} else if (cur == DDP_COMPONENT_GAMMA && next == DDP_COMPONENT_RDMA1) {
-		*addr = DISP_REG_CONFIG_DISP_GAMMA_MOUT_EN;
-		value = GAMMA_MOUT_EN_RDMA1;
-	} else if (cur == DDP_COMPONENT_OD1 && next == DDP_COMPONENT_RDMA1) {
-		*addr = DISP_REG_CONFIG_DISP_OD_MOUT_EN;
-		value = OD1_MOUT_EN_RDMA1;
-	} else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DPI0) {
-		*addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
-		value = RDMA0_SOUT_DPI0;
-	} else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DPI1) {
-		*addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
-		value = RDMA0_SOUT_DPI1;
-	} else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DSI1) {
-		*addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
-		value = RDMA0_SOUT_DSI1;
-	} else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DSI2) {
-		*addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
-		value = RDMA0_SOUT_DSI2;
-	} else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DSI3) {
-		*addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
-		value = RDMA0_SOUT_DSI3;
-	} else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI1) {
-		*addr = DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN;
-		value = RDMA1_SOUT_DSI1;
-	} else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI2) {
-		*addr = DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN;
-		value = RDMA1_SOUT_DSI2;
-	} else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI3) {
-		*addr = DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN;
-		value = RDMA1_SOUT_DSI3;
-	} else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DPI0) {
-		*addr = DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN;
-		value = RDMA1_SOUT_DPI0;
-	} else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DPI1) {
-		*addr = DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN;
-		value = RDMA1_SOUT_DPI1;
-	} else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DPI0) {
-		*addr = DISP_REG_CONFIG_DISP_RDMA2_SOUT;
-		value = RDMA2_SOUT_DPI0;
-	} else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DPI1) {
-		*addr = DISP_REG_CONFIG_DISP_RDMA2_SOUT;
-		value = RDMA2_SOUT_DPI1;
-	} else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI1) {
-		*addr = DISP_REG_CONFIG_DISP_RDMA2_SOUT;
-		value = RDMA2_SOUT_DSI1;
-	} else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI2) {
-		*addr = DISP_REG_CONFIG_DISP_RDMA2_SOUT;
-		value = RDMA2_SOUT_DSI2;
-	} else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI3) {
-		*addr = DISP_REG_CONFIG_DISP_RDMA2_SOUT;
-		value = RDMA2_SOUT_DSI3;
-	} else {
-		value = 0;
-	}
-
-	return value;
-}
-
-static unsigned int mtk_ddp_sel_in(enum mtk_ddp_comp_id cur,
-				   enum mtk_ddp_comp_id next,
-				   unsigned int *addr)
-{
-	unsigned int value;
-
-	if (cur == DDP_COMPONENT_OVL0 && next == DDP_COMPONENT_COLOR0) {
-		*addr = DISP_REG_CONFIG_DISP_COLOR0_SEL_IN;
-		value = COLOR0_SEL_IN_OVL0;
-	} else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DPI0) {
-		*addr = DISP_REG_CONFIG_DPI_SEL_IN;
-		value = DPI0_SEL_IN_RDMA1;
-	} else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DPI1) {
-		*addr = DISP_REG_CONFIG_DPI_SEL_IN;
-		value = DPI1_SEL_IN_RDMA1;
-	} else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI0) {
-		*addr = DISP_REG_CONFIG_DSIE_SEL_IN;
-		value = DSI0_SEL_IN_RDMA1;
-	} else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI1) {
-		*addr = DISP_REG_CONFIG_DSIO_SEL_IN;
-		value = DSI1_SEL_IN_RDMA1;
-	} else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI2) {
-		*addr = DISP_REG_CONFIG_DSIE_SEL_IN;
-		value = DSI2_SEL_IN_RDMA1;
-	} else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI3) {
-		*addr = DISP_REG_CONFIG_DSIO_SEL_IN;
-		value = DSI3_SEL_IN_RDMA1;
-	} else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DPI0) {
-		*addr = DISP_REG_CONFIG_DPI_SEL_IN;
-		value = DPI0_SEL_IN_RDMA2;
-	} else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DPI1) {
-		*addr = DISP_REG_CONFIG_DPI_SEL_IN;
-		value = DPI1_SEL_IN_RDMA2;
-	} else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI0) {
-		*addr = DISP_REG_CONFIG_DSIE_SEL_IN;
-		value = DSI0_SEL_IN_RDMA2;
-	} else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI1) {
-		*addr = DISP_REG_CONFIG_DSIO_SEL_IN;
-		value = DSI1_SEL_IN_RDMA2;
-	} else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI2) {
-		*addr = DISP_REG_CONFIG_DSIE_SEL_IN;
-		value = DSI2_SEL_IN_RDMA2;
-	} else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI3) {
-		*addr = DISP_REG_CONFIG_DSIE_SEL_IN;
-		value = DSI3_SEL_IN_RDMA2;
-	} else if (cur == DDP_COMPONENT_OVL1 && next == DDP_COMPONENT_COLOR1) {
-		*addr = DISP_REG_CONFIG_DISP_COLOR1_SEL_IN;
-		value = COLOR1_SEL_IN_OVL1;
-	} else if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DSI0) {
-		*addr = DISP_REG_CONFIG_DSI_SEL;
-		value = DSI_SEL_IN_BLS;
-	} else {
-		value = 0;
-	}
-
-	return value;
-}
-
-static void mtk_ddp_sout_sel(void __iomem *config_regs,
-			     enum mtk_ddp_comp_id cur,
-			     enum mtk_ddp_comp_id next)
-{
-	if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DSI0) {
-		writel_relaxed(BLS_TO_DSI_RDMA1_TO_DPI1,
-			       config_regs + DISP_REG_CONFIG_OUT_SEL);
-	} else if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DPI0) {
-		writel_relaxed(BLS_TO_DPI_RDMA1_TO_DSI,
-			       config_regs + DISP_REG_CONFIG_OUT_SEL);
-		writel_relaxed(DSI_SEL_IN_RDMA,
-			       config_regs + DISP_REG_CONFIG_DSI_SEL);
-		writel_relaxed(DPI_SEL_IN_BLS,
-			       config_regs + DISP_REG_CONFIG_DPI_SEL);
-	}
-}
-
-void mtk_ddp_add_comp_to_path(void __iomem *config_regs,
-			      enum mtk_ddp_comp_id cur,
-			      enum mtk_ddp_comp_id next)
-{
-	unsigned int addr, value, reg;
-
-	value = mtk_ddp_mout_en(cur, next, &addr);
-	if (value) {
-		reg = readl_relaxed(config_regs + addr) | value;
-		writel_relaxed(reg, config_regs + addr);
-	}
-
-	mtk_ddp_sout_sel(config_regs, cur, next);
-
-	value = mtk_ddp_sel_in(cur, next, &addr);
-	if (value) {
-		reg = readl_relaxed(config_regs + addr) | value;
-		writel_relaxed(reg, config_regs + addr);
-	}
-}
-
-void mtk_ddp_remove_comp_from_path(void __iomem *config_regs,
-				   enum mtk_ddp_comp_id cur,
-				   enum mtk_ddp_comp_id next)
-{
-	unsigned int addr, value, reg;
-
-	value = mtk_ddp_mout_en(cur, next, &addr);
-	if (value) {
-		reg = readl_relaxed(config_regs + addr) & ~value;
-		writel_relaxed(reg, config_regs + addr);
-	}
-
-	value = mtk_ddp_sel_in(cur, next, &addr);
-	if (value) {
-		reg = readl_relaxed(config_regs + addr) & ~value;
-		writel_relaxed(reg, config_regs + addr);
-	}
-}
-
 struct mtk_disp_mutex *mtk_disp_mutex_get(struct device *dev, unsigned int id)
 {
 	struct mtk_ddp *ddp = dev_get_drvdata(dev);
@@ -628,7 +372,8 @@ static int mtk_ddp_probe(struct platform_device *pdev)
 	if (!ddp->data->no_clk) {
 		ddp->clk = devm_clk_get(dev, NULL);
 		if (IS_ERR(ddp->clk)) {
-			dev_err(dev, "Failed to get clock\n");
+			if (PTR_ERR(ddp->clk) != -EPROBE_DEFER)
+				dev_err(dev, "Failed to get clock\n");
 			return PTR_ERR(ddp->clk);
 		}
 	}
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp.h
index 827be424a148..6b691a57be4a 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp.h
@@ -12,13 +12,6 @@ struct regmap;
 struct device;
 struct mtk_disp_mutex;
 
-void mtk_ddp_add_comp_to_path(void __iomem *config_regs,
-			      enum mtk_ddp_comp_id cur,
-			      enum mtk_ddp_comp_id next);
-void mtk_ddp_remove_comp_from_path(void __iomem *config_regs,
-				   enum mtk_ddp_comp_id cur,
-				   enum mtk_ddp_comp_id next);
-
 struct mtk_disp_mutex *mtk_disp_mutex_get(struct device *dev, unsigned int id);
 int mtk_disp_mutex_prepare(struct mtk_disp_mutex *mutex);
 void mtk_disp_mutex_add_comp(struct mtk_disp_mutex *mutex,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 0563c6813333..6bd369434d9d 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -10,6 +10,7 @@
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/pm_runtime.h>
+#include <linux/soc/mediatek/mtk-mmsys.h>
 #include <linux/dma-mapping.h>
 
 #include <drm/drm_atomic.h>
@@ -162,7 +163,9 @@ static int mtk_drm_kms_init(struct drm_device *drm)
 	}
 	private->mutex_dev = &pdev->dev;
 
-	drm_mode_config_init(drm);
+	ret = drmm_mode_config_init(drm);
+	if (ret)
+		return ret;
 
 	drm->mode_config.min_width = 64;
 	drm->mode_config.min_height = 64;
@@ -179,7 +182,7 @@ static int mtk_drm_kms_init(struct drm_device *drm)
 
 	ret = component_bind_all(drm->dev, drm);
 	if (ret)
-		goto err_config_cleanup;
+		return ret;
 
 	/*
 	 * We currently support two fixed data streams, each optional,
@@ -255,8 +258,6 @@ static int mtk_drm_kms_init(struct drm_device *drm)
 		dma_dev->dma_parms = NULL;
 err_component_unbind:
 	component_unbind_all(drm->dev, drm);
-err_config_cleanup:
-	drm_mode_config_cleanup(drm);
 
 	return ret;
 }
@@ -272,7 +273,6 @@ static void mtk_drm_kms_deinit(struct drm_device *drm)
 		private->dma_dev->dma_parms = NULL;
 
 	component_unbind_all(drm->dev, drm);
-	drm_mode_config_cleanup(drm);
 }
 
 static const struct file_operations mtk_drm_fops = {
@@ -348,9 +348,7 @@ static int mtk_drm_bind(struct device *dev)
 	if (ret < 0)
 		goto err_deinit;
 
-	ret = drm_fbdev_generic_setup(drm, 32);
-	if (ret)
-		DRM_ERROR("Failed to initialize fbdev: %d\n", ret);
+	drm_fbdev_generic_setup(drm, 32);
 
 	return 0;
 
@@ -421,11 +419,22 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	{ }
 };
 
+static const struct of_device_id mtk_drm_of_ids[] = {
+	{ .compatible = "mediatek,mt2701-mmsys",
+	  .data = &mt2701_mmsys_driver_data},
+	{ .compatible = "mediatek,mt2712-mmsys",
+	  .data = &mt2712_mmsys_driver_data},
+	{ .compatible = "mediatek,mt8173-mmsys",
+	  .data = &mt8173_mmsys_driver_data},
+	{ }
+};
+
 static int mtk_drm_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
+	struct device_node *phandle = dev->parent->of_node;
+	const struct of_device_id *of_id;
 	struct mtk_drm_private *private;
-	struct resource *mem;
 	struct device_node *node;
 	struct component_match *match = NULL;
 	int ret;
@@ -436,18 +445,20 @@ static int mtk_drm_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	private->data = of_device_get_match_data(dev);
-
-	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	private->config_regs = devm_ioremap_resource(dev, mem);
-	if (IS_ERR(private->config_regs)) {
-		ret = PTR_ERR(private->config_regs);
-		dev_err(dev, "Failed to ioremap mmsys-config resource: %d\n",
-			ret);
-		return ret;
+	private->mmsys_dev = dev->parent;
+	if (!private->mmsys_dev) {
+		dev_err(dev, "Failed to get MMSYS device\n");
+		return -ENODEV;
 	}
 
+	of_id = of_match_node(mtk_drm_of_ids, phandle);
+	if (!of_id)
+		return -ENODEV;
+
+	private->data = of_id->data;
+
 	/* Iterate over sibling DISP function blocks */
-	for_each_child_of_node(dev->of_node->parent, node) {
+	for_each_child_of_node(phandle->parent, node) {
 		const struct of_device_id *of_id;
 		enum mtk_ddp_comp_type comp_type;
 		int comp_id;
@@ -581,22 +592,11 @@ static int mtk_drm_sys_resume(struct device *dev)
 static SIMPLE_DEV_PM_OPS(mtk_drm_pm_ops, mtk_drm_sys_suspend,
 			 mtk_drm_sys_resume);
 
-static const struct of_device_id mtk_drm_of_ids[] = {
-	{ .compatible = "mediatek,mt2701-mmsys",
-	  .data = &mt2701_mmsys_driver_data},
-	{ .compatible = "mediatek,mt2712-mmsys",
-	  .data = &mt2712_mmsys_driver_data},
-	{ .compatible = "mediatek,mt8173-mmsys",
-	  .data = &mt8173_mmsys_driver_data},
-	{ }
-};
-
 static struct platform_driver mtk_drm_platform_driver = {
 	.probe	= mtk_drm_probe,
 	.remove	= mtk_drm_remove,
 	.driver	= {
 		.name	= "mediatek-drm",
-		.of_match_table = mtk_drm_of_ids,
 		.pm     = &mtk_drm_pm_ops,
 	},
 };
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
index 17bc99b9f5d4..b5be63e53176 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
@@ -39,7 +39,7 @@ struct mtk_drm_private {
 
 	struct device_node *mutex_node;
 	struct device *mutex_dev;
-	void __iomem *config_regs;
+	struct device *mmsys_dev;
 	struct device_node *comp_node[DDP_COMPONENT_ID_MAX];
 	struct mtk_ddp_comp *ddp_comp[DDP_COMPONENT_ID_MAX];
 	const struct mtk_mmsys_driver_data *data;
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 0ede69830a9d..270bf22c98fe 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -22,6 +22,7 @@
 #include <drm/drm_panel.h>
 #include <drm/drm_print.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "mtk_drm_ddp_comp.h"
 
@@ -787,15 +788,6 @@ static void mtk_output_dsi_disable(struct mtk_dsi *dsi)
 	dsi->enabled = false;
 }
 
-static void mtk_dsi_encoder_destroy(struct drm_encoder *encoder)
-{
-	drm_encoder_cleanup(encoder);
-}
-
-static const struct drm_encoder_funcs mtk_dsi_encoder_funcs = {
-	.destroy = mtk_dsi_encoder_destroy,
-};
-
 static bool mtk_dsi_encoder_mode_fixup(struct drm_encoder *encoder,
 				       const struct drm_display_mode *mode,
 				       struct drm_display_mode *adjusted_mode)
@@ -888,8 +880,8 @@ static int mtk_dsi_create_conn_enc(struct drm_device *drm, struct mtk_dsi *dsi)
 {
 	int ret;
 
-	ret = drm_encoder_init(drm, &dsi->encoder, &mtk_dsi_encoder_funcs,
-			       DRM_MODE_ENCODER_DSI, NULL);
+	ret = drm_simple_encoder_init(drm, &dsi->encoder,
+				      DRM_MODE_ENCODER_DSI);
 	if (ret) {
 		DRM_ERROR("Failed to encoder init to drm\n");
 		return ret;
@@ -1194,14 +1186,18 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 	dsi->engine_clk = devm_clk_get(dev, "engine");
 	if (IS_ERR(dsi->engine_clk)) {
 		ret = PTR_ERR(dsi->engine_clk);
-		dev_err(dev, "Failed to get engine clock: %d\n", ret);
+
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "Failed to get engine clock: %d\n", ret);
 		goto err_unregister_host;
 	}
 
 	dsi->digital_clk = devm_clk_get(dev, "digital");
 	if (IS_ERR(dsi->digital_clk)) {
 		ret = PTR_ERR(dsi->digital_clk);
-		dev_err(dev, "Failed to get digital clock: %d\n", ret);
+
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "Failed to get digital clock: %d\n", ret);
 		goto err_unregister_host;
 	}
 
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index ff43a3d80410..b0555a7cb3b4 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -1474,7 +1474,9 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,
 
 	ret = mtk_hdmi_get_all_clk(hdmi, np);
 	if (ret) {
-		dev_err(dev, "Failed to get clocks: %d\n", ret);
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "Failed to get clocks: %d\n", ret);
+
 		return ret;
 	}
 
diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
index b5f5eb7b4bb9..6f29fab79952 100644
--- a/drivers/gpu/drm/meson/meson_drv.c
+++ b/drivers/gpu/drm/meson/meson_drv.c
@@ -284,7 +284,9 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
 	/* Remove early framebuffers (ie. simplefb) */
 	meson_remove_framebuffers();
 
-	drm_mode_config_init(drm);
+	ret = drmm_mode_config_init(drm);
+	if (ret)
+		goto free_drm;
 	drm->mode_config.max_width = 3840;
 	drm->mode_config.max_height = 2160;
 	drm->mode_config.funcs = &meson_mode_config_funcs;
@@ -379,7 +381,6 @@ static void meson_drv_unbind(struct device *dev)
 	drm_dev_unregister(drm);
 	drm_irq_uninstall(drm);
 	drm_kms_helper_poll_fini(drm);
-	drm_mode_config_cleanup(drm);
 	drm_dev_put(drm);
 }
 
diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c
index e8c94915a4fc..64cb6ba4bc42 100644
--- a/drivers/gpu/drm/meson/meson_dw_hdmi.c
+++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c
@@ -1034,10 +1034,8 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master,
 		return PTR_ERR(dw_plat_data->regm);
 
 	irq = platform_get_irq(pdev, 0);
-	if (irq < 0) {
-		dev_err(dev, "Failed to get hdmi top irq\n");
+	if (irq < 0)
 		return irq;
-	}
 
 	ret = devm_request_threaded_irq(dev, irq, dw_hdmi_top_irq,
 					dw_hdmi_top_thread_irq, IRQF_SHARED,
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c
index 7a5bad2f57d7..3298b7ef18b0 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.c
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.c
@@ -77,6 +77,8 @@ static int mga_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	if (ret)
 		goto err_mgag200_driver_unload;
 
+	drm_fbdev_generic_setup(dev, 0);
+
 	return 0;
 
 err_mgag200_driver_unload:
diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c
index e278b6a547bd..b680cf47cbb9 100644
--- a/drivers/gpu/drm/mgag200/mgag200_main.c
+++ b/drivers/gpu/drm/mgag200/mgag200_main.c
@@ -181,10 +181,6 @@ int mgag200_driver_load(struct drm_device *dev, unsigned long flags)
 		dev_warn(&dev->pdev->dev,
 			"Could not initialize cursors. Not doing hardware cursors.\n");
 
-	r = drm_fbdev_generic_setup(mdev->dev, 0);
-	if (r)
-		goto err_modeset;
-
 	return 0;
 
 err_modeset:
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_debugfs.c b/drivers/gpu/drm/msm/adreno/a5xx_debugfs.c
index 075ecce4b5e0..8cae2ca4af6b 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_debugfs.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_debugfs.c
@@ -148,27 +148,19 @@ reset_set(void *data, u64 val)
 DEFINE_SIMPLE_ATTRIBUTE(reset_fops, NULL, reset_set, "%llx\n");
 
 
-int a5xx_debugfs_init(struct msm_gpu *gpu, struct drm_minor *minor)
+void a5xx_debugfs_init(struct msm_gpu *gpu, struct drm_minor *minor)
 {
 	struct drm_device *dev;
-	int ret;
 
 	if (!minor)
-		return 0;
+		return;
 
 	dev = minor->dev;
 
-	ret = drm_debugfs_create_files(a5xx_debugfs_list,
-			ARRAY_SIZE(a5xx_debugfs_list),
-			minor->debugfs_root, minor);
-
-	if (ret) {
-		DRM_DEV_ERROR(dev->dev, "could not install a5xx_debugfs_list\n");
-		return ret;
-	}
+	drm_debugfs_create_files(a5xx_debugfs_list,
+				 ARRAY_SIZE(a5xx_debugfs_list),
+				 minor->debugfs_root, minor);
 
 	debugfs_create_file("reset", S_IWUGO, minor->debugfs_root, dev,
 			    &reset_fops);
-
-	return 0;
 }
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h
index 833468ce6b6d..54868d4e3958 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h
@@ -41,7 +41,7 @@ struct a5xx_gpu {
 #define to_a5xx_gpu(x) container_of(x, struct a5xx_gpu, base)
 
 #ifdef CONFIG_DEBUG_FS
-int a5xx_debugfs_init(struct msm_gpu *gpu, struct drm_minor *minor);
+void a5xx_debugfs_init(struct msm_gpu *gpu, struct drm_minor *minor);
 #endif
 
 /*
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
index 47b989834af1..c902c6503675 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
@@ -259,17 +259,9 @@ static struct drm_info_list mdp5_debugfs_list[] = {
 
 static int mdp5_kms_debugfs_init(struct msm_kms *kms, struct drm_minor *minor)
 {
-	struct drm_device *dev = minor->dev;
-	int ret;
-
-	ret = drm_debugfs_create_files(mdp5_debugfs_list,
-			ARRAY_SIZE(mdp5_debugfs_list),
-			minor->debugfs_root, minor);
-
-	if (ret) {
-		DRM_DEV_ERROR(dev->dev, "could not install mdp5_debugfs_list\n");
-		return ret;
-	}
+	drm_debugfs_create_files(mdp5_debugfs_list,
+				 ARRAY_SIZE(mdp5_debugfs_list),
+				 minor->debugfs_root, minor);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/msm/msm_debugfs.c b/drivers/gpu/drm/msm/msm_debugfs.c
index 1c74381a4fc9..ee2e270f464c 100644
--- a/drivers/gpu/drm/msm/msm_debugfs.c
+++ b/drivers/gpu/drm/msm/msm_debugfs.c
@@ -214,31 +214,20 @@ int msm_debugfs_late_init(struct drm_device *dev)
 	return ret;
 }
 
-int msm_debugfs_init(struct drm_minor *minor)
+void msm_debugfs_init(struct drm_minor *minor)
 {
 	struct drm_device *dev = minor->dev;
 	struct msm_drm_private *priv = dev->dev_private;
-	int ret;
-
-	ret = drm_debugfs_create_files(msm_debugfs_list,
-			ARRAY_SIZE(msm_debugfs_list),
-			minor->debugfs_root, minor);
 
-	if (ret) {
-		DRM_DEV_ERROR(dev->dev, "could not install msm_debugfs_list\n");
-		return ret;
-	}
+	drm_debugfs_create_files(msm_debugfs_list,
+				 ARRAY_SIZE(msm_debugfs_list),
+				 minor->debugfs_root, minor);
 
 	debugfs_create_file("gpu", S_IRUSR, minor->debugfs_root,
 		dev, &msm_gpu_fops);
 
-	if (priv->kms && priv->kms->funcs->debugfs_init) {
-		ret = priv->kms->funcs->debugfs_init(priv->kms, minor);
-		if (ret)
-			return ret;
-	}
-
-	return ret;
+	if (priv->kms && priv->kms->funcs->debugfs_init)
+		priv->kms->funcs->debugfs_init(priv->kms, minor);
 }
 #endif
 
diff --git a/drivers/gpu/drm/msm/msm_debugfs.h b/drivers/gpu/drm/msm/msm_debugfs.h
index 2b91f8c178ad..ef58f66abbb3 100644
--- a/drivers/gpu/drm/msm/msm_debugfs.h
+++ b/drivers/gpu/drm/msm/msm_debugfs.h
@@ -8,7 +8,7 @@
 #define __MSM_DEBUGFS_H__
 
 #ifdef CONFIG_DEBUG_FS
-int msm_debugfs_init(struct drm_minor *minor);
+void msm_debugfs_init(struct drm_minor *minor);
 #endif
 
 #endif /* __MSM_DEBUGFS_H__ */
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index be5bc2e8425c..6ccae4ba905c 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -57,7 +57,7 @@ struct msm_gpu_funcs {
 	void (*show)(struct msm_gpu *gpu, struct msm_gpu_state *state,
 			struct drm_printer *p);
 	/* for generation specific debugfs: */
-	int (*debugfs_init)(struct msm_gpu *gpu, struct drm_minor *minor);
+	void (*debugfs_init)(struct msm_gpu *gpu, struct drm_minor *minor);
 #endif
 	unsigned long (*gpu_busy)(struct msm_gpu *gpu);
 	struct msm_gpu_state *(*gpu_state_get)(struct msm_gpu *gpu);
diff --git a/drivers/gpu/drm/nouveau/nouveau_debugfs.c b/drivers/gpu/drm/nouveau/nouveau_debugfs.c
index 15a3d40edf02..63cb5e432f8a 100644
--- a/drivers/gpu/drm/nouveau/nouveau_debugfs.c
+++ b/drivers/gpu/drm/nouveau/nouveau_debugfs.c
@@ -217,7 +217,7 @@ static const struct nouveau_debugfs_files {
 	{"pstate", &nouveau_pstate_fops},
 };
 
-int
+void
 nouveau_drm_debugfs_init(struct drm_minor *minor)
 {
 	struct nouveau_drm *drm = nouveau_drm(minor->dev);
@@ -240,12 +240,10 @@ nouveau_drm_debugfs_init(struct drm_minor *minor)
 	 */
 	dentry = debugfs_lookup("vbios.rom", minor->debugfs_root);
 	if (!dentry)
-		return 0;
+		return;
 
 	d_inode(dentry)->i_size = drm->vbios.length;
 	dput(dentry);
-
-	return 0;
 }
 
 int
diff --git a/drivers/gpu/drm/nouveau/nouveau_debugfs.h b/drivers/gpu/drm/nouveau/nouveau_debugfs.h
index 8909c010e8ea..77f0323b38ba 100644
--- a/drivers/gpu/drm/nouveau/nouveau_debugfs.h
+++ b/drivers/gpu/drm/nouveau/nouveau_debugfs.h
@@ -18,15 +18,13 @@ nouveau_debugfs(struct drm_device *dev)
 	return nouveau_drm(dev)->debugfs;
 }
 
-extern int  nouveau_drm_debugfs_init(struct drm_minor *);
+extern void  nouveau_drm_debugfs_init(struct drm_minor *);
 extern int  nouveau_debugfs_init(struct nouveau_drm *);
 extern void nouveau_debugfs_fini(struct nouveau_drm *);
 #else
-static inline int
+static inline void
 nouveau_drm_debugfs_init(struct drm_minor *minor)
-{
-       return 0;
-}
+{}
 
 static inline int
 nouveau_debugfs_init(struct nouveau_drm *drm)
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/sec2/gp108.c b/drivers/gpu/drm/nouveau/nvkm/engine/sec2/gp108.c
index 232a9d7c51e5..e770c9497871 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/sec2/gp108.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/sec2/gp108.c
@@ -25,6 +25,9 @@
 MODULE_FIRMWARE("nvidia/gp108/sec2/desc.bin");
 MODULE_FIRMWARE("nvidia/gp108/sec2/image.bin");
 MODULE_FIRMWARE("nvidia/gp108/sec2/sig.bin");
+MODULE_FIRMWARE("nvidia/gv100/sec2/desc.bin");
+MODULE_FIRMWARE("nvidia/gv100/sec2/image.bin");
+MODULE_FIRMWARE("nvidia/gv100/sec2/sig.bin");
 
 static const struct nvkm_sec2_fwif
 gp108_sec2_fwif[] = {
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/sec2/tu102.c b/drivers/gpu/drm/nouveau/nvkm/engine/sec2/tu102.c
index b6ebd95c9ba1..a8295653ceab 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/sec2/tu102.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/sec2/tu102.c
@@ -56,6 +56,22 @@ tu102_sec2_nofw(struct nvkm_sec2 *sec2, int ver,
 	return 0;
 }
 
+MODULE_FIRMWARE("nvidia/tu102/sec2/desc.bin");
+MODULE_FIRMWARE("nvidia/tu102/sec2/image.bin");
+MODULE_FIRMWARE("nvidia/tu102/sec2/sig.bin");
+MODULE_FIRMWARE("nvidia/tu104/sec2/desc.bin");
+MODULE_FIRMWARE("nvidia/tu104/sec2/image.bin");
+MODULE_FIRMWARE("nvidia/tu104/sec2/sig.bin");
+MODULE_FIRMWARE("nvidia/tu106/sec2/desc.bin");
+MODULE_FIRMWARE("nvidia/tu106/sec2/image.bin");
+MODULE_FIRMWARE("nvidia/tu106/sec2/sig.bin");
+MODULE_FIRMWARE("nvidia/tu116/sec2/desc.bin");
+MODULE_FIRMWARE("nvidia/tu116/sec2/image.bin");
+MODULE_FIRMWARE("nvidia/tu116/sec2/sig.bin");
+MODULE_FIRMWARE("nvidia/tu117/sec2/desc.bin");
+MODULE_FIRMWARE("nvidia/tu117/sec2/image.bin");
+MODULE_FIRMWARE("nvidia/tu117/sec2/sig.bin");
+
 static const struct nvkm_sec2_fwif
 tu102_sec2_fwif[] = {
 	{  0, gp102_sec2_load, &tu102_sec2, &gp102_sec2_acr_1 },
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/ic.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/ic.c
index 03b355dabab3..abf3eda683f0 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/ic.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/ic.c
@@ -36,8 +36,8 @@ probe_monitoring_device(struct nvkm_i2c_bus *bus,
 
 	request_module("%s%s", I2C_MODULE_PREFIX, info->type);
 
-	client = i2c_new_device(&bus->i2c, info);
-	if (!client)
+	client = i2c_new_client_device(&bus->i2c, info);
+	if (IS_ERR(client))
 		return false;
 
 	if (!client->dev.driver ||
diff --git a/drivers/gpu/drm/omapdrm/omap_debugfs.c b/drivers/gpu/drm/omapdrm/omap_debugfs.c
index 34dfb33145b4..b57fbe8a0ac2 100644
--- a/drivers/gpu/drm/omapdrm/omap_debugfs.c
+++ b/drivers/gpu/drm/omapdrm/omap_debugfs.c
@@ -80,31 +80,16 @@ static struct drm_info_list omap_dmm_debugfs_list[] = {
 	{"tiler_map", tiler_map_show, 0},
 };
 
-int omap_debugfs_init(struct drm_minor *minor)
+void omap_debugfs_init(struct drm_minor *minor)
 {
-	struct drm_device *dev = minor->dev;
-	int ret;
-
-	ret = drm_debugfs_create_files(omap_debugfs_list,
-			ARRAY_SIZE(omap_debugfs_list),
-			minor->debugfs_root, minor);
-
-	if (ret) {
-		dev_err(dev->dev, "could not install omap_debugfs_list\n");
-		return ret;
-	}
+	drm_debugfs_create_files(omap_debugfs_list,
+				 ARRAY_SIZE(omap_debugfs_list),
+				 minor->debugfs_root, minor);
 
 	if (dmm_is_available())
-		ret = drm_debugfs_create_files(omap_dmm_debugfs_list,
-				ARRAY_SIZE(omap_dmm_debugfs_list),
-				minor->debugfs_root, minor);
-
-	if (ret) {
-		dev_err(dev->dev, "could not install omap_dmm_debugfs_list\n");
-		return ret;
-	}
-
-	return ret;
+		drm_debugfs_create_files(omap_dmm_debugfs_list,
+					 ARRAY_SIZE(omap_dmm_debugfs_list),
+					 minor->debugfs_root, minor);
 }
 
 #endif
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h
index 7c4b66efcaa7..8a1fac680138 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -82,6 +82,6 @@ struct omap_drm_private {
 };
 
 
-int omap_debugfs_init(struct drm_minor *minor);
+void omap_debugfs_init(struct drm_minor *minor);
 
 #endif /* __OMAPDRM_DRV_H__ */
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index a1723c1b5fbf..d56258b9fcaf 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -137,6 +137,17 @@ config DRM_PANEL_KINGDISPLAY_KD097D04
 	  24 bit RGB per pixel. It provides a MIPI DSI interface to
 	  the host and has a built-in LED backlight.
 
+config DRM_PANEL_LEADTEK_LTK050H3146W
+	tristate "Leadtek LTK050H3146W panel"
+	depends on OF
+	depends on DRM_MIPI_DSI
+	depends on BACKLIGHT_CLASS_DEVICE
+	help
+	  Say Y here if you want to enable support for Leadtek LTK050H3146W
+	  TFT-LCD modules. The panel has a 720x1280 resolution and uses
+	  24 bit RGB per pixel. It provides a MIPI DSI interface to
+	  the host and has a built-in LED backlight.
+
 config DRM_PANEL_LEADTEK_LTK500HD1829
 	tristate "Leadtek LTK500HD1829 panel"
 	depends on OF
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index 96a883cd6630..2335a1e32ae0 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9881C) += panel-ilitek-ili9881c.o
 obj-$(CONFIG_DRM_PANEL_INNOLUX_P079ZCA) += panel-innolux-p079zca.o
 obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.o
 obj-$(CONFIG_DRM_PANEL_KINGDISPLAY_KD097D04) += panel-kingdisplay-kd097d04.o
+obj-$(CONFIG_DRM_PANEL_LEADTEK_LTK050H3146W) += panel-leadtek-ltk050h3146w.o
 obj-$(CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829) += panel-leadtek-ltk500hd1829.o
 obj-$(CONFIG_DRM_PANEL_LG_LB035Q02) += panel-lg-lb035q02.o
 obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o
diff --git a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
index 48a164257d18..f89861c8598a 100644
--- a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
+++ b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
@@ -696,6 +696,34 @@ static const struct panel_desc auo_b101uan08_3_desc = {
 	.init_cmds = auo_b101uan08_3_init_cmd,
 };
 
+static const struct drm_display_mode boe_tv105wum_nw0_default_mode = {
+	.clock = 159260,
+	.hdisplay = 1200,
+	.hsync_start = 1200 + 80,
+	.hsync_end = 1200 + 80 + 24,
+	.htotal = 1200 + 80 + 24 + 60,
+	.vdisplay = 1920,
+	.vsync_start = 1920 + 10,
+	.vsync_end = 1920 + 10 + 2,
+	.vtotal = 1920 + 10 + 2 + 14,
+	.vrefresh = 60,
+	.type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
+};
+
+static const struct panel_desc boe_tv105wum_nw0_desc = {
+	.modes = &boe_tv105wum_nw0_default_mode,
+	.bpc = 8,
+	.size = {
+		.width_mm = 141,
+		.height_mm = 226,
+	},
+	.lanes = 4,
+	.format = MIPI_DSI_FMT_RGB888,
+	.mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
+		      MIPI_DSI_MODE_LPM,
+	.init_cmds = boe_init_cmd,
+};
+
 static int boe_panel_get_modes(struct drm_panel *panel,
 			       struct drm_connector *connector)
 {
@@ -834,6 +862,9 @@ static const struct of_device_id boe_of_match[] = {
 	{ .compatible = "auo,b101uan08.3",
 	  .data = &auo_b101uan08_3_desc
 	},
+	{ .compatible = "boe,tv105wum-nw0",
+	  .data = &boe_tv105wum_nw0_desc
+	},
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, boe_of_match);
diff --git a/drivers/gpu/drm/panel/panel-leadtek-ltk050h3146w.c b/drivers/gpu/drm/panel/panel-leadtek-ltk050h3146w.c
new file mode 100644
index 000000000000..5a7a31c8513e
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-leadtek-ltk050h3146w.c
@@ -0,0 +1,691 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 Theobroma Systems Design und Consulting GmbH
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/media-bus-format.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/regulator/consumer.h>
+
+#include <video/display_timing.h>
+#include <video/mipi_display.h>
+
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_modes.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_print.h>
+
+struct ltk050h3146w_cmd {
+	char cmd;
+	char data;
+};
+
+struct ltk050h3146w;
+struct ltk050h3146w_desc {
+	const struct drm_display_mode *mode;
+	int (*init)(struct ltk050h3146w *ctx);
+};
+
+struct ltk050h3146w {
+	struct device *dev;
+	struct drm_panel panel;
+	struct gpio_desc *reset_gpio;
+	struct regulator *vci;
+	struct regulator *iovcc;
+	const struct ltk050h3146w_desc *panel_desc;
+	bool prepared;
+};
+
+static const struct ltk050h3146w_cmd page1_cmds[] = {
+	{ 0x22, 0x0A }, /* BGR SS GS */
+	{ 0x31, 0x00 }, /* column inversion */
+	{ 0x53, 0xA2 }, /* VCOM1 */
+	{ 0x55, 0xA2 }, /* VCOM2 */
+	{ 0x50, 0x81 }, /* VREG1OUT=5V */
+	{ 0x51, 0x85 }, /* VREG2OUT=-5V */
+	{ 0x62, 0x0D }, /* EQT Time setting */
+/*
+ * The vendor init selected page 1 here _again_
+ * Is this supposed to be page 2?
+ */
+	{ 0xA0, 0x00 },
+	{ 0xA1, 0x1A },
+	{ 0xA2, 0x28 },
+	{ 0xA3, 0x13 },
+	{ 0xA4, 0x16 },
+	{ 0xA5, 0x29 },
+	{ 0xA6, 0x1D },
+	{ 0xA7, 0x1E },
+	{ 0xA8, 0x84 },
+	{ 0xA9, 0x1C },
+	{ 0xAA, 0x28 },
+	{ 0xAB, 0x75 },
+	{ 0xAC, 0x1A },
+	{ 0xAD, 0x19 },
+	{ 0xAE, 0x4D },
+	{ 0xAF, 0x22 },
+	{ 0xB0, 0x28 },
+	{ 0xB1, 0x54 },
+	{ 0xB2, 0x66 },
+	{ 0xB3, 0x39 },
+	{ 0xC0, 0x00 },
+	{ 0xC1, 0x1A },
+	{ 0xC2, 0x28 },
+	{ 0xC3, 0x13 },
+	{ 0xC4, 0x16 },
+	{ 0xC5, 0x29 },
+	{ 0xC6, 0x1D },
+	{ 0xC7, 0x1E },
+	{ 0xC8, 0x84 },
+	{ 0xC9, 0x1C },
+	{ 0xCA, 0x28 },
+	{ 0xCB, 0x75 },
+	{ 0xCC, 0x1A },
+	{ 0xCD, 0x19 },
+	{ 0xCE, 0x4D },
+	{ 0xCF, 0x22 },
+	{ 0xD0, 0x28 },
+	{ 0xD1, 0x54 },
+	{ 0xD2, 0x66 },
+	{ 0xD3, 0x39 },
+};
+
+static const struct ltk050h3146w_cmd page3_cmds[] = {
+	{ 0x01, 0x00 },
+	{ 0x02, 0x00 },
+	{ 0x03, 0x73 },
+	{ 0x04, 0x00 },
+	{ 0x05, 0x00 },
+	{ 0x06, 0x0a },
+	{ 0x07, 0x00 },
+	{ 0x08, 0x00 },
+	{ 0x09, 0x01 },
+	{ 0x0a, 0x00 },
+	{ 0x0b, 0x00 },
+	{ 0x0c, 0x01 },
+	{ 0x0d, 0x00 },
+	{ 0x0e, 0x00 },
+	{ 0x0f, 0x1d },
+	{ 0x10, 0x1d },
+	{ 0x11, 0x00 },
+	{ 0x12, 0x00 },
+	{ 0x13, 0x00 },
+	{ 0x14, 0x00 },
+	{ 0x15, 0x00 },
+	{ 0x16, 0x00 },
+	{ 0x17, 0x00 },
+	{ 0x18, 0x00 },
+	{ 0x19, 0x00 },
+	{ 0x1a, 0x00 },
+	{ 0x1b, 0x00 },
+	{ 0x1c, 0x00 },
+	{ 0x1d, 0x00 },
+	{ 0x1e, 0x40 },
+	{ 0x1f, 0x80 },
+	{ 0x20, 0x06 },
+	{ 0x21, 0x02 },
+	{ 0x22, 0x00 },
+	{ 0x23, 0x00 },
+	{ 0x24, 0x00 },
+	{ 0x25, 0x00 },
+	{ 0x26, 0x00 },
+	{ 0x27, 0x00 },
+	{ 0x28, 0x33 },
+	{ 0x29, 0x03 },
+	{ 0x2a, 0x00 },
+	{ 0x2b, 0x00 },
+	{ 0x2c, 0x00 },
+	{ 0x2d, 0x00 },
+	{ 0x2e, 0x00 },
+	{ 0x2f, 0x00 },
+	{ 0x30, 0x00 },
+	{ 0x31, 0x00 },
+	{ 0x32, 0x00 },
+	{ 0x33, 0x00 },
+	{ 0x34, 0x04 },
+	{ 0x35, 0x00 },
+	{ 0x36, 0x00 },
+	{ 0x37, 0x00 },
+	{ 0x38, 0x3C },
+	{ 0x39, 0x35 },
+	{ 0x3A, 0x01 },
+	{ 0x3B, 0x40 },
+	{ 0x3C, 0x00 },
+	{ 0x3D, 0x01 },
+	{ 0x3E, 0x00 },
+	{ 0x3F, 0x00 },
+	{ 0x40, 0x00 },
+	{ 0x41, 0x88 },
+	{ 0x42, 0x00 },
+	{ 0x43, 0x00 },
+	{ 0x44, 0x1F },
+	{ 0x50, 0x01 },
+	{ 0x51, 0x23 },
+	{ 0x52, 0x45 },
+	{ 0x53, 0x67 },
+	{ 0x54, 0x89 },
+	{ 0x55, 0xab },
+	{ 0x56, 0x01 },
+	{ 0x57, 0x23 },
+	{ 0x58, 0x45 },
+	{ 0x59, 0x67 },
+	{ 0x5a, 0x89 },
+	{ 0x5b, 0xab },
+	{ 0x5c, 0xcd },
+	{ 0x5d, 0xef },
+	{ 0x5e, 0x11 },
+	{ 0x5f, 0x01 },
+	{ 0x60, 0x00 },
+	{ 0x61, 0x15 },
+	{ 0x62, 0x14 },
+	{ 0x63, 0x0E },
+	{ 0x64, 0x0F },
+	{ 0x65, 0x0C },
+	{ 0x66, 0x0D },
+	{ 0x67, 0x06 },
+	{ 0x68, 0x02 },
+	{ 0x69, 0x07 },
+	{ 0x6a, 0x02 },
+	{ 0x6b, 0x02 },
+	{ 0x6c, 0x02 },
+	{ 0x6d, 0x02 },
+	{ 0x6e, 0x02 },
+	{ 0x6f, 0x02 },
+	{ 0x70, 0x02 },
+	{ 0x71, 0x02 },
+	{ 0x72, 0x02 },
+	{ 0x73, 0x02 },
+	{ 0x74, 0x02 },
+	{ 0x75, 0x01 },
+	{ 0x76, 0x00 },
+	{ 0x77, 0x14 },
+	{ 0x78, 0x15 },
+	{ 0x79, 0x0E },
+	{ 0x7a, 0x0F },
+	{ 0x7b, 0x0C },
+	{ 0x7c, 0x0D },
+	{ 0x7d, 0x06 },
+	{ 0x7e, 0x02 },
+	{ 0x7f, 0x07 },
+	{ 0x80, 0x02 },
+	{ 0x81, 0x02 },
+	{ 0x82, 0x02 },
+	{ 0x83, 0x02 },
+	{ 0x84, 0x02 },
+	{ 0x85, 0x02 },
+	{ 0x86, 0x02 },
+	{ 0x87, 0x02 },
+	{ 0x88, 0x02 },
+	{ 0x89, 0x02 },
+	{ 0x8A, 0x02 },
+};
+
+static const struct ltk050h3146w_cmd page4_cmds[] = {
+	{ 0x70, 0x00 },
+	{ 0x71, 0x00 },
+	{ 0x82, 0x0F }, /* VGH_MOD clamp level=15v */
+	{ 0x84, 0x0F }, /* VGH clamp level 15V */
+	{ 0x85, 0x0D }, /* VGL clamp level (-10V) */
+	{ 0x32, 0xAC },
+	{ 0x8C, 0x80 },
+	{ 0x3C, 0xF5 },
+	{ 0xB5, 0x07 }, /* GAMMA OP */
+	{ 0x31, 0x45 }, /* SOURCE OP */
+	{ 0x3A, 0x24 }, /* PS_EN OFF */
+	{ 0x88, 0x33 }, /* LVD */
+};
+
+static inline
+struct ltk050h3146w *panel_to_ltk050h3146w(struct drm_panel *panel)
+{
+	return container_of(panel, struct ltk050h3146w, panel);
+}
+
+#define dsi_dcs_write_seq(dsi, cmd, seq...) do {			\
+		static const u8 d[] = { seq };				\
+		int ret;						\
+		ret = mipi_dsi_dcs_write(dsi, cmd, d, ARRAY_SIZE(d));	\
+		if (ret < 0)						\
+			return ret;					\
+	} while (0)
+
+static int ltk050h3146w_init_sequence(struct ltk050h3146w *ctx)
+{
+	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+	int ret;
+
+	/*
+	 * Init sequence was supplied by the panel vendor without much
+	 * documentation.
+	 */
+	dsi_dcs_write_seq(dsi, 0xdf, 0x93, 0x65, 0xf8);
+	dsi_dcs_write_seq(dsi, 0xb0, 0x01, 0x03, 0x02, 0x00, 0x64, 0x06,
+			  0x01);
+	dsi_dcs_write_seq(dsi, 0xb2, 0x00, 0xb5);
+	dsi_dcs_write_seq(dsi, 0xb3, 0x00, 0xb5);
+	dsi_dcs_write_seq(dsi, 0xb7, 0x00, 0xbf, 0x00, 0x00, 0xbf, 0x00);
+
+	dsi_dcs_write_seq(dsi, 0xb9, 0x00, 0xc4, 0x23, 0x07);
+	dsi_dcs_write_seq(dsi, 0xbb, 0x02, 0x01, 0x24, 0x00, 0x28, 0x0f,
+			  0x28, 0x04, 0xcc, 0xcc, 0xcc);
+	dsi_dcs_write_seq(dsi, 0xbc, 0x0f, 0x04);
+	dsi_dcs_write_seq(dsi, 0xbe, 0x1e, 0xf2);
+	dsi_dcs_write_seq(dsi, 0xc0, 0x26, 0x03);
+	dsi_dcs_write_seq(dsi, 0xc1, 0x00, 0x12);
+	dsi_dcs_write_seq(dsi, 0xc3, 0x04, 0x02, 0x02, 0x76, 0x01, 0x80,
+			  0x80);
+	dsi_dcs_write_seq(dsi, 0xc4, 0x24, 0x80, 0xb4, 0x81, 0x12, 0x0f,
+			  0x16, 0x00, 0x00);
+	dsi_dcs_write_seq(dsi, 0xc8, 0x7f, 0x72, 0x67, 0x5d, 0x5d, 0x50,
+			  0x56, 0x41, 0x59, 0x57, 0x55, 0x70, 0x5b, 0x5f,
+			  0x4f, 0x47, 0x38, 0x23, 0x08, 0x7f, 0x72, 0x67,
+			  0x5d, 0x5d, 0x50, 0x56, 0x41, 0x59, 0x57, 0x55,
+			  0x70, 0x5b, 0x5f, 0x4f, 0x47, 0x38, 0x23, 0x08);
+	dsi_dcs_write_seq(dsi, 0xd0, 0x1e, 0x1f, 0x57, 0x58, 0x48, 0x4a,
+			  0x44, 0x46, 0x40, 0x1f, 0x42, 0x1f, 0x1f, 0x1f,
+			  0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f);
+	dsi_dcs_write_seq(dsi, 0xd1, 0x1e, 0x1f, 0x57, 0x58, 0x49, 0x4b,
+			  0x45, 0x47, 0x41, 0x1f, 0x43, 0x1f, 0x1f, 0x1f,
+			  0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f);
+	dsi_dcs_write_seq(dsi, 0xd2, 0x1f, 0x1e, 0x17, 0x18, 0x07, 0x05,
+			  0x0b, 0x09, 0x03, 0x1f, 0x01, 0x1f, 0x1f, 0x1f,
+			  0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f);
+	dsi_dcs_write_seq(dsi, 0xd3, 0x1f, 0x1e, 0x17, 0x18, 0x06, 0x04,
+			  0x0a, 0x08, 0x02, 0x1f, 0x00, 0x1f, 0x1f, 0x1f,
+			  0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f);
+	dsi_dcs_write_seq(dsi, 0xd4, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x20,
+			  0x01, 0x02, 0x00, 0x60, 0x15, 0xb0, 0x30, 0x03,
+			  0x04, 0x00, 0x60, 0x72, 0x0a, 0x00, 0x60, 0x08);
+	dsi_dcs_write_seq(dsi, 0xd5, 0x00, 0x06, 0x06, 0x00, 0x30, 0x00,
+			  0x00, 0x00, 0x00, 0x00, 0xbc, 0x50, 0x00, 0x05,
+			  0x21, 0x00, 0x60);
+	dsi_dcs_write_seq(dsi, 0xdd, 0x2c, 0xa3, 0x00);
+	dsi_dcs_write_seq(dsi, 0xde, 0x02);
+	dsi_dcs_write_seq(dsi, 0xb2, 0x32, 0x1c);
+	dsi_dcs_write_seq(dsi, 0xb7, 0x3b, 0x70, 0x00, 0x04);
+	dsi_dcs_write_seq(dsi, 0xc1, 0x11);
+	dsi_dcs_write_seq(dsi, 0xbb, 0x21, 0x22, 0x23, 0x24, 0x36, 0x37);
+	dsi_dcs_write_seq(dsi, 0xc2, 0x20, 0x38, 0x1e, 0x84);
+	dsi_dcs_write_seq(dsi, 0xde, 0x00);
+
+	ret = mipi_dsi_dcs_set_tear_on(dsi, 1);
+	if (ret < 0) {
+		DRM_DEV_ERROR(ctx->dev, "failed to set tear on: %d\n",
+			      ret);
+		return ret;
+	}
+
+	msleep(60);
+
+	return 0;
+}
+
+static const struct drm_display_mode ltk050h3146w_mode = {
+	.hdisplay	= 720,
+	.hsync_start	= 720 + 42,
+	.hsync_end	= 720 + 42 + 8,
+	.htotal		= 720 + 42 + 8 + 42,
+	.vdisplay	= 1280,
+	.vsync_start	= 1280 + 12,
+	.vsync_end	= 1280 + 12 + 4,
+	.vtotal		= 1280 + 12 + 4 + 18,
+	.clock		= 64018,
+	.width_mm	= 62,
+	.height_mm	= 110,
+};
+
+static const struct ltk050h3146w_desc ltk050h3146w_data = {
+	.mode = &ltk050h3146w_mode,
+	.init = ltk050h3146w_init_sequence,
+};
+
+static int ltk050h3146w_a2_select_page(struct ltk050h3146w *ctx, int page)
+{
+	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+	u8 d[3] = { 0x98, 0x81, page };
+
+	return mipi_dsi_dcs_write(dsi, 0xff, d, ARRAY_SIZE(d));
+}
+
+static int ltk050h3146w_a2_write_page(struct ltk050h3146w *ctx, int page,
+				      const struct ltk050h3146w_cmd *cmds,
+				      int num)
+{
+	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+	int i, ret;
+
+	ret = ltk050h3146w_a2_select_page(ctx, page);
+	if (ret < 0) {
+		DRM_DEV_ERROR(ctx->dev, "failed to select page %d: %d\n",
+			      page, ret);
+		return ret;
+	}
+
+	for (i = 0; i < num; i++) {
+		ret = mipi_dsi_generic_write(dsi, &cmds[i],
+					     sizeof(struct ltk050h3146w_cmd));
+		if (ret < 0) {
+			DRM_DEV_ERROR(ctx->dev,
+				      "failed to write page %d init cmds: %d\n",
+				       page, ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int ltk050h3146w_a2_init_sequence(struct ltk050h3146w *ctx)
+{
+	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+	int ret;
+
+	/*
+	 * Init sequence was supplied by the panel vendor without much
+	 * documentation.
+	 */
+	ret = ltk050h3146w_a2_write_page(ctx, 3, page3_cmds,
+					 ARRAY_SIZE(page3_cmds));
+	if (ret < 0)
+		return ret;
+
+	ret = ltk050h3146w_a2_write_page(ctx, 4, page4_cmds,
+					 ARRAY_SIZE(page4_cmds));
+	if (ret < 0)
+		return ret;
+
+	ret = ltk050h3146w_a2_write_page(ctx, 1, page1_cmds,
+					 ARRAY_SIZE(page1_cmds));
+	if (ret < 0)
+		return ret;
+
+	ret = ltk050h3146w_a2_select_page(ctx, 0);
+	if (ret < 0) {
+		DRM_DEV_ERROR(ctx->dev, "failed to select page 0: %d\n", ret);
+		return ret;
+	}
+
+	/* vendor code called this without param, where there should be one */
+	ret = mipi_dsi_dcs_set_tear_on(dsi, 0);
+	if (ret < 0) {
+		DRM_DEV_ERROR(ctx->dev, "failed to set tear on: %d\n",
+			      ret);
+		return ret;
+	}
+
+	msleep(60);
+
+	return 0;
+}
+
+static const struct drm_display_mode ltk050h3146w_a2_mode = {
+	.hdisplay	= 720,
+	.hsync_start	= 720 + 42,
+	.hsync_end	= 720 + 42 + 10,
+	.htotal		= 720 + 42 + 10 + 60,
+	.vdisplay	= 1280,
+	.vsync_start	= 1280 + 18,
+	.vsync_end	= 1280 + 18 + 4,
+	.vtotal		= 1280 + 18 + 4 + 12,
+	.clock		= 65595,
+	.width_mm	= 62,
+	.height_mm	= 110,
+};
+
+static const struct ltk050h3146w_desc ltk050h3146w_a2_data = {
+	.mode = &ltk050h3146w_a2_mode,
+	.init = ltk050h3146w_a2_init_sequence,
+};
+
+static int ltk050h3146w_unprepare(struct drm_panel *panel)
+{
+	struct ltk050h3146w *ctx = panel_to_ltk050h3146w(panel);
+	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+	int ret;
+
+	if (!ctx->prepared)
+		return 0;
+
+	ret = mipi_dsi_dcs_set_display_off(dsi);
+	if (ret < 0) {
+		DRM_DEV_ERROR(ctx->dev, "failed to set display off: %d\n",
+			      ret);
+		return ret;
+	}
+
+	mipi_dsi_dcs_enter_sleep_mode(dsi);
+	if (ret < 0) {
+		DRM_DEV_ERROR(ctx->dev, "failed to enter sleep mode: %d\n",
+			      ret);
+		return ret;
+	}
+
+	regulator_disable(ctx->iovcc);
+	regulator_disable(ctx->vci);
+
+	ctx->prepared = false;
+
+	return 0;
+}
+
+static int ltk050h3146w_prepare(struct drm_panel *panel)
+{
+	struct ltk050h3146w *ctx = panel_to_ltk050h3146w(panel);
+	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+	int ret;
+
+	if (ctx->prepared)
+		return 0;
+
+	DRM_DEV_DEBUG_DRIVER(ctx->dev, "Resetting the panel\n");
+	ret = regulator_enable(ctx->vci);
+	if (ret < 0) {
+		DRM_DEV_ERROR(ctx->dev,
+			      "Failed to enable vci supply: %d\n", ret);
+		return ret;
+	}
+	ret = regulator_enable(ctx->iovcc);
+	if (ret < 0) {
+		DRM_DEV_ERROR(ctx->dev,
+			      "Failed to enable iovcc supply: %d\n", ret);
+		goto disable_vci;
+	}
+
+	gpiod_set_value_cansleep(ctx->reset_gpio, 1);
+	usleep_range(5000, 6000);
+	gpiod_set_value_cansleep(ctx->reset_gpio, 0);
+	msleep(20);
+
+	ret = ctx->panel_desc->init(ctx);
+	if (ret < 0) {
+		DRM_DEV_ERROR(ctx->dev, "Panel init sequence failed: %d\n",
+			      ret);
+		goto disable_iovcc;
+	}
+
+	ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
+	if (ret < 0) {
+		DRM_DEV_ERROR(ctx->dev, "Failed to exit sleep mode: %d\n", ret);
+		goto disable_iovcc;
+	}
+
+	/* T9: 120ms */
+	msleep(120);
+
+	ret = mipi_dsi_dcs_set_display_on(dsi);
+	if (ret < 0) {
+		DRM_DEV_ERROR(ctx->dev, "Failed to set display on: %d\n", ret);
+		goto disable_iovcc;
+	}
+
+	msleep(50);
+
+	ctx->prepared = true;
+
+	return 0;
+
+disable_iovcc:
+	regulator_disable(ctx->iovcc);
+disable_vci:
+	regulator_disable(ctx->vci);
+	return ret;
+}
+
+static int ltk050h3146w_get_modes(struct drm_panel *panel,
+				  struct drm_connector *connector)
+{
+	struct ltk050h3146w *ctx = panel_to_ltk050h3146w(panel);
+	struct drm_display_mode *mode;
+
+	mode = drm_mode_duplicate(connector->dev, ctx->panel_desc->mode);
+	if (!mode)
+		return -ENOMEM;
+
+	drm_mode_set_name(mode);
+
+	mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
+	connector->display_info.width_mm = mode->width_mm;
+	connector->display_info.height_mm = mode->height_mm;
+	drm_mode_probed_add(connector, mode);
+
+	return 1;
+}
+
+static const struct drm_panel_funcs ltk050h3146w_funcs = {
+	.unprepare	= ltk050h3146w_unprepare,
+	.prepare	= ltk050h3146w_prepare,
+	.get_modes	= ltk050h3146w_get_modes,
+};
+
+static int ltk050h3146w_probe(struct mipi_dsi_device *dsi)
+{
+	struct device *dev = &dsi->dev;
+	struct ltk050h3146w *ctx;
+	int ret;
+
+	ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
+	if (!ctx)
+		return -ENOMEM;
+
+	ctx->panel_desc = of_device_get_match_data(dev);
+	if (!ctx->panel_desc)
+		return -EINVAL;
+
+	ctx->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
+	if (IS_ERR(ctx->reset_gpio)) {
+		DRM_DEV_ERROR(dev, "cannot get reset gpio\n");
+		return PTR_ERR(ctx->reset_gpio);
+	}
+
+	ctx->vci = devm_regulator_get(dev, "vci");
+	if (IS_ERR(ctx->vci)) {
+		ret = PTR_ERR(ctx->vci);
+		if (ret != -EPROBE_DEFER)
+			DRM_DEV_ERROR(dev,
+				      "Failed to request vci regulator: %d\n",
+				      ret);
+		return ret;
+	}
+
+	ctx->iovcc = devm_regulator_get(dev, "iovcc");
+	if (IS_ERR(ctx->iovcc)) {
+		ret = PTR_ERR(ctx->iovcc);
+		if (ret != -EPROBE_DEFER)
+			DRM_DEV_ERROR(dev,
+				      "Failed to request iovcc regulator: %d\n",
+				      ret);
+		return ret;
+	}
+
+	mipi_dsi_set_drvdata(dsi, ctx);
+
+	ctx->dev = dev;
+
+	dsi->lanes = 4;
+	dsi->format = MIPI_DSI_FMT_RGB888;
+	dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
+			  MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_EOT_PACKET;
+
+	drm_panel_init(&ctx->panel, &dsi->dev, &ltk050h3146w_funcs,
+		       DRM_MODE_CONNECTOR_DSI);
+
+	ret = drm_panel_of_backlight(&ctx->panel);
+	if (ret)
+		return ret;
+
+	drm_panel_add(&ctx->panel);
+
+	ret = mipi_dsi_attach(dsi);
+	if (ret < 0) {
+		DRM_DEV_ERROR(dev, "mipi_dsi_attach failed: %d\n", ret);
+		drm_panel_remove(&ctx->panel);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void ltk050h3146w_shutdown(struct mipi_dsi_device *dsi)
+{
+	struct ltk050h3146w *ctx = mipi_dsi_get_drvdata(dsi);
+	int ret;
+
+	ret = drm_panel_unprepare(&ctx->panel);
+	if (ret < 0)
+		DRM_DEV_ERROR(&dsi->dev, "Failed to unprepare panel: %d\n",
+			      ret);
+
+	ret = drm_panel_disable(&ctx->panel);
+	if (ret < 0)
+		DRM_DEV_ERROR(&dsi->dev, "Failed to disable panel: %d\n",
+			      ret);
+}
+
+static int ltk050h3146w_remove(struct mipi_dsi_device *dsi)
+{
+	struct ltk050h3146w *ctx = mipi_dsi_get_drvdata(dsi);
+	int ret;
+
+	ltk050h3146w_shutdown(dsi);
+
+	ret = mipi_dsi_detach(dsi);
+	if (ret < 0)
+		DRM_DEV_ERROR(&dsi->dev, "Failed to detach from DSI host: %d\n",
+			      ret);
+
+	drm_panel_remove(&ctx->panel);
+
+	return 0;
+}
+
+static const struct of_device_id ltk050h3146w_of_match[] = {
+	{
+		.compatible = "leadtek,ltk050h3146w",
+		.data = &ltk050h3146w_data,
+	},
+	{
+		.compatible = "leadtek,ltk050h3146w-a2",
+		.data = &ltk050h3146w_a2_data,
+	},
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, ltk050h3146w_of_match);
+
+static struct mipi_dsi_driver ltk050h3146w_driver = {
+	.driver = {
+		.name = "panel-leadtek-ltk050h3146w",
+		.of_match_table = ltk050h3146w_of_match,
+	},
+	.probe	= ltk050h3146w_probe,
+	.remove = ltk050h3146w_remove,
+	.shutdown = ltk050h3146w_shutdown,
+};
+module_mipi_dsi_driver(ltk050h3146w_driver);
+
+MODULE_AUTHOR("Heiko Stuebner <heiko.stuebner@theobroma-systems.com>");
+MODULE_DESCRIPTION("DRM driver for Leadtek LTK050H3146W MIPI DSI panel");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/panel/panel-leadtek-ltk500hd1829.c b/drivers/gpu/drm/panel/panel-leadtek-ltk500hd1829.c
index 76ecf2de9c44..113ab9c0396b 100644
--- a/drivers/gpu/drm/panel/panel-leadtek-ltk500hd1829.c
+++ b/drivers/gpu/drm/panel/panel-leadtek-ltk500hd1829.c
@@ -377,7 +377,7 @@ static const struct drm_display_mode default_mode = {
 	.vsync_end	= 1280 + 30 + 4,
 	.vtotal		= 1280 + 30 + 4 + 12,
 	.vrefresh	= 60,
-	.clock		= 41600,
+	.clock		= 69217,
 	.width_mm	= 62,
 	.height_mm	= 110,
 };
diff --git a/drivers/gpu/drm/panel/panel-novatek-nt39016.c b/drivers/gpu/drm/panel/panel-novatek-nt39016.c
index a470810f7dbe..05cae8d62d56 100644
--- a/drivers/gpu/drm/panel/panel-novatek-nt39016.c
+++ b/drivers/gpu/drm/panel/panel-novatek-nt39016.c
@@ -49,7 +49,8 @@ enum nt39016_regs {
 #define NT39016_SYSTEM_STANDBY	BIT(1)
 
 struct nt39016_panel_info {
-	struct drm_display_mode display_mode;
+	const struct drm_display_mode *display_modes;
+	unsigned int num_modes;
 	u16 width_mm, height_mm;
 	u32 bus_format, bus_flags;
 };
@@ -212,15 +213,22 @@ static int nt39016_get_modes(struct drm_panel *drm_panel,
 	struct nt39016 *panel = to_nt39016(drm_panel);
 	const struct nt39016_panel_info *panel_info = panel->panel_info;
 	struct drm_display_mode *mode;
+	unsigned int i;
 
-	mode = drm_mode_duplicate(connector->dev, &panel_info->display_mode);
-	if (!mode)
-		return -ENOMEM;
+	for (i = 0; i < panel_info->num_modes; i++) {
+		mode = drm_mode_duplicate(connector->dev,
+					  &panel_info->display_modes[i]);
+		if (!mode)
+			return -ENOMEM;
+
+		drm_mode_set_name(mode);
 
-	drm_mode_set_name(mode);
+		mode->type = DRM_MODE_TYPE_DRIVER;
+		if (panel_info->num_modes == 1)
+			mode->type |= DRM_MODE_TYPE_PREFERRED;
 
-	mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
-	drm_mode_probed_add(connector, mode);
+		drm_mode_probed_add(connector, mode);
+	}
 
 	connector->display_info.bpc = 8;
 	connector->display_info.width_mm = panel_info->width_mm;
@@ -230,7 +238,7 @@ static int nt39016_get_modes(struct drm_panel *drm_panel,
 					 &panel_info->bus_format, 1);
 	connector->display_info.bus_flags = panel_info->bus_flags;
 
-	return 1;
+	return panel_info->num_modes;
 }
 
 static const struct drm_panel_funcs nt39016_funcs = {
@@ -316,8 +324,8 @@ static int nt39016_remove(struct spi_device *spi)
 	return 0;
 }
 
-static const struct nt39016_panel_info kd035g6_info = {
-	.display_mode = {
+static const struct drm_display_mode kd035g6_display_modes[] = {
+	{	/* 60 Hz */
 		.clock = 6000,
 		.hdisplay = 320,
 		.hsync_start = 320 + 10,
@@ -330,6 +338,24 @@ static const struct nt39016_panel_info kd035g6_info = {
 		.vrefresh = 60,
 		.flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
 	},
+	{	/* 50 Hz */
+		.clock = 5400,
+		.hdisplay = 320,
+		.hsync_start = 320 + 42,
+		.hsync_end = 320 + 42 + 50,
+		.htotal = 320 + 42 + 50 + 20,
+		.vdisplay = 240,
+		.vsync_start = 240 + 5,
+		.vsync_end = 240 + 5 + 1,
+		.vtotal = 240 + 5 + 1 + 4,
+		.vrefresh = 50,
+		.flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
+	},
+};
+
+static const struct nt39016_panel_info kd035g6_info = {
+	.display_modes = kd035g6_display_modes,
+	.num_modes = ARRAY_SIZE(kd035g6_display_modes),
 	.width_mm = 71,
 	.height_mm = 53,
 	.bus_format = MEDIA_BUS_FMT_RGB888_1X24,
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
index 3ad828eaefe1..003b54ea90d5 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -3065,6 +3065,32 @@ static const struct panel_desc shelly_sca07010_bfn_lnn = {
 	.bus_format = MEDIA_BUS_FMT_RGB666_1X18,
 };
 
+static const struct drm_display_mode starry_kr070pe2t_mode = {
+	.clock = 33000,
+	.hdisplay = 800,
+	.hsync_start = 800 + 209,
+	.hsync_end = 800 + 209 + 1,
+	.htotal = 800 + 209 + 1 + 45,
+	.vdisplay = 480,
+	.vsync_start = 480 + 22,
+	.vsync_end = 480 + 22 + 1,
+	.vtotal = 480 + 22 + 1 + 22,
+	.vrefresh = 60,
+};
+
+static const struct panel_desc starry_kr070pe2t = {
+	.modes = &starry_kr070pe2t_mode,
+	.num_modes = 1,
+	.bpc = 8,
+	.size = {
+		.width = 152,
+		.height = 86,
+	},
+	.bus_format = MEDIA_BUS_FMT_RGB888_1X24,
+	.bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE,
+	.connector_type = DRM_MODE_CONNECTOR_LVDS,
+};
+
 static const struct drm_display_mode starry_kr122ea0sra_mode = {
 	.clock = 147000,
 	.hdisplay = 1920,
@@ -3715,6 +3741,9 @@ static const struct of_device_id platform_of_match[] = {
 	}, {
 		.compatible = "shelly,sca07010-bfn-lnn",
 		.data = &shelly_sca07010_bfn_lnn,
+	}, {
+		.compatible = "starry,kr070pe2t",
+		.data = &starry_kr070pe2t,
 	}, {
 		.compatible = "starry,kr122ea0sra",
 		.data = &starry_kr122ea0sra,
diff --git a/drivers/gpu/drm/pl111/pl111_debugfs.c b/drivers/gpu/drm/pl111/pl111_debugfs.c
index 3c8e82016854..26ca8cdf3e60 100644
--- a/drivers/gpu/drm/pl111/pl111_debugfs.c
+++ b/drivers/gpu/drm/pl111/pl111_debugfs.c
@@ -51,10 +51,10 @@ static const struct drm_info_list pl111_debugfs_list[] = {
 	{"regs", pl111_debugfs_regs, 0},
 };
 
-int
+void
 pl111_debugfs_init(struct drm_minor *minor)
 {
-	return drm_debugfs_create_files(pl111_debugfs_list,
-					ARRAY_SIZE(pl111_debugfs_list),
-					minor->debugfs_root, minor);
+	drm_debugfs_create_files(pl111_debugfs_list,
+				 ARRAY_SIZE(pl111_debugfs_list),
+				 minor->debugfs_root, minor);
 }
diff --git a/drivers/gpu/drm/pl111/pl111_drm.h b/drivers/gpu/drm/pl111/pl111_drm.h
index 77d2da9a8a7c..ba399bcb792f 100644
--- a/drivers/gpu/drm/pl111/pl111_drm.h
+++ b/drivers/gpu/drm/pl111/pl111_drm.h
@@ -84,6 +84,6 @@ struct pl111_drm_dev_private {
 
 int pl111_display_init(struct drm_device *dev);
 irqreturn_t pl111_irq(int irq, void *data);
-int pl111_debugfs_init(struct drm_minor *minor);
+void pl111_debugfs_init(struct drm_minor *minor);
 
 #endif /* _PL111_DRM_H_ */
diff --git a/drivers/gpu/drm/pl111/pl111_drv.c b/drivers/gpu/drm/pl111/pl111_drv.c
index aa8aa8d9e405..f9ca0f3edbbb 100644
--- a/drivers/gpu/drm/pl111/pl111_drv.c
+++ b/drivers/gpu/drm/pl111/pl111_drv.c
@@ -90,10 +90,13 @@ static int pl111_modeset_init(struct drm_device *dev)
 	struct drm_panel *panel = NULL;
 	struct drm_bridge *bridge = NULL;
 	bool defer = false;
-	int ret = 0;
+	int ret;
 	int i;
 
-	drm_mode_config_init(dev);
+	ret = drmm_mode_config_init(dev);
+	if (ret)
+		return ret;
+
 	mode_config = &dev->mode_config;
 	mode_config->funcs = &mode_config_funcs;
 	mode_config->min_width = 1;
@@ -154,7 +157,7 @@ static int pl111_modeset_init(struct drm_device *dev)
 						    DRM_MODE_CONNECTOR_Unknown);
 		if (IS_ERR(bridge)) {
 			ret = PTR_ERR(bridge);
-			goto out_config;
+			goto finish;
 		}
 	} else if (bridge) {
 		dev_info(dev->dev, "Using non-panel bridge\n");
@@ -197,8 +200,6 @@ static int pl111_modeset_init(struct drm_device *dev)
 out_bridge:
 	if (panel)
 		drm_panel_bridge_remove(bridge);
-out_config:
-	drm_mode_config_cleanup(dev);
 finish:
 	return ret;
 }
@@ -343,7 +344,6 @@ static int pl111_amba_remove(struct amba_device *amba_dev)
 	drm_dev_unregister(drm);
 	if (priv->panel)
 		drm_panel_bridge_remove(priv->bridge);
-	drm_mode_config_cleanup(drm);
 	drm_dev_put(drm);
 	of_reserved_mem_device_release(dev);
 
diff --git a/drivers/gpu/drm/qxl/qxl_debugfs.c b/drivers/gpu/drm/qxl/qxl_debugfs.c
index a4f4175bbdbe..88123047fdd4 100644
--- a/drivers/gpu/drm/qxl/qxl_debugfs.c
+++ b/drivers/gpu/drm/qxl/qxl_debugfs.c
@@ -79,36 +79,30 @@ static struct drm_info_list qxl_debugfs_list[] = {
 #define QXL_DEBUGFS_ENTRIES ARRAY_SIZE(qxl_debugfs_list)
 #endif
 
-int
+void
 qxl_debugfs_init(struct drm_minor *minor)
 {
 #if defined(CONFIG_DEBUG_FS)
-	int r;
 	struct qxl_device *dev =
 		(struct qxl_device *) minor->dev->dev_private;
 
 	drm_debugfs_create_files(qxl_debugfs_list, QXL_DEBUGFS_ENTRIES,
 				 minor->debugfs_root, minor);
 
-	r = qxl_ttm_debugfs_init(dev);
-	if (r) {
-		DRM_ERROR("Failed to init TTM debugfs\n");
-		return r;
-	}
+	qxl_ttm_debugfs_init(dev);
 #endif
-	return 0;
 }
 
-int qxl_debugfs_add_files(struct qxl_device *qdev,
-			  struct drm_info_list *files,
-			  unsigned int nfiles)
+void qxl_debugfs_add_files(struct qxl_device *qdev,
+			   struct drm_info_list *files,
+			   unsigned int nfiles)
 {
 	unsigned int i;
 
 	for (i = 0; i < qdev->debugfs_count; i++) {
 		if (qdev->debugfs[i].files == files) {
 			/* Already registered */
-			return 0;
+			return;
 		}
 	}
 
@@ -116,7 +110,7 @@ int qxl_debugfs_add_files(struct qxl_device *qdev,
 	if (i > QXL_DEBUGFS_MAX_COMPONENTS) {
 		DRM_ERROR("Reached maximum number of debugfs components.\n");
 		DRM_ERROR("Report so we increase QXL_DEBUGFS_MAX_COMPONENTS.\n");
-		return -EINVAL;
+		return;
 	}
 	qdev->debugfs[qdev->debugfs_count].files = files;
 	qdev->debugfs[qdev->debugfs_count].num_files = nfiles;
@@ -126,5 +120,4 @@ int qxl_debugfs_add_files(struct qxl_device *qdev,
 				 qdev->ddev.primary->debugfs_root,
 				 qdev->ddev.primary);
 #endif
-	return 0;
 }
diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c
index 4fda3f9b29f4..09102e2efabc 100644
--- a/drivers/gpu/drm/qxl/qxl_drv.c
+++ b/drivers/gpu/drm/qxl/qxl_drv.c
@@ -144,8 +144,6 @@ static void qxl_drm_release(struct drm_device *dev)
 	 */
 	qxl_modeset_fini(qdev);
 	qxl_device_fini(qdev);
-	dev->dev_private = NULL;
-	kfree(qdev);
 }
 
 static void
diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h
index 27e45a2d6b52..435126facc9b 100644
--- a/drivers/gpu/drm/qxl/qxl_drv.h
+++ b/drivers/gpu/drm/qxl/qxl_drv.h
@@ -190,9 +190,6 @@ struct qxl_debugfs {
 	unsigned int num_files;
 };
 
-int qxl_debugfs_add_files(struct qxl_device *rdev,
-			     struct drm_info_list *files,
-			     unsigned int nfiles);
 int qxl_debugfs_fence_init(struct qxl_device *rdev);
 
 struct qxl_device;
@@ -442,8 +439,8 @@ int qxl_garbage_collect(struct qxl_device *qdev);
 
 /* debugfs */
 
-int qxl_debugfs_init(struct drm_minor *minor);
-int qxl_ttm_debugfs_init(struct qxl_device *qdev);
+void qxl_debugfs_init(struct drm_minor *minor);
+void qxl_ttm_debugfs_init(struct qxl_device *qdev);
 
 /* qxl_prime.c */
 int qxl_gem_prime_pin(struct drm_gem_object *obj);
@@ -461,9 +458,9 @@ int qxl_gem_prime_mmap(struct drm_gem_object *obj,
 int qxl_irq_init(struct qxl_device *qdev);
 irqreturn_t qxl_irq_handler(int irq, void *arg);
 
-int qxl_debugfs_add_files(struct qxl_device *qdev,
-			  struct drm_info_list *files,
-			  unsigned int nfiles);
+void qxl_debugfs_add_files(struct qxl_device *qdev,
+			   struct drm_info_list *files,
+			   unsigned int nfiles);
 
 int qxl_surface_id_alloc(struct qxl_device *qdev,
 			 struct qxl_bo *surf);
diff --git a/drivers/gpu/drm/qxl/qxl_kms.c b/drivers/gpu/drm/qxl/qxl_kms.c
index 70b20ee4741a..9eed1a375f24 100644
--- a/drivers/gpu/drm/qxl/qxl_kms.c
+++ b/drivers/gpu/drm/qxl/qxl_kms.c
@@ -27,6 +27,7 @@
 #include <linux/pci.h>
 
 #include <drm/drm_drv.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_probe_helper.h>
 
 #include "qxl_drv.h"
@@ -121,6 +122,7 @@ int qxl_device_init(struct qxl_device *qdev,
 	qdev->ddev.pdev = pdev;
 	pci_set_drvdata(pdev, &qdev->ddev);
 	qdev->ddev.dev_private = qdev;
+	drmm_add_final_kfree(&qdev->ddev, qdev);
 
 	mutex_init(&qdev->gem.mutex);
 	mutex_init(&qdev->update_area_mutex);
@@ -218,7 +220,7 @@ int qxl_device_init(struct qxl_device *qdev,
 				&(qdev->ram_header->cursor_ring_hdr),
 				sizeof(struct qxl_command),
 				QXL_CURSOR_RING_SIZE,
-				qdev->io_base + QXL_IO_NOTIFY_CMD,
+				qdev->io_base + QXL_IO_NOTIFY_CURSOR,
 				false,
 				&qdev->cursor_event);
 
diff --git a/drivers/gpu/drm/qxl/qxl_ttm.c b/drivers/gpu/drm/qxl/qxl_ttm.c
index 62a5e424971b..93a2eb14844b 100644
--- a/drivers/gpu/drm/qxl/qxl_ttm.c
+++ b/drivers/gpu/drm/qxl/qxl_ttm.c
@@ -322,7 +322,7 @@ static int qxl_mm_dump_table(struct seq_file *m, void *data)
 }
 #endif
 
-int qxl_ttm_debugfs_init(struct qxl_device *qdev)
+void qxl_ttm_debugfs_init(struct qxl_device *qdev)
 {
 #if defined(CONFIG_DEBUG_FS)
 	static struct drm_info_list qxl_mem_types_list[QXL_DEBUGFS_MEM_TYPES];
@@ -343,8 +343,6 @@ int qxl_ttm_debugfs_init(struct qxl_device *qdev)
 			qxl_mem_types_list[i].data = qdev->mman.bdev.man[TTM_PL_PRIV].priv;
 
 	}
-	return qxl_debugfs_add_files(qdev, qxl_mem_types_list, i);
-#else
-	return 0;
+	qxl_debugfs_add_files(qdev, qxl_mem_types_list, i);
 #endif
 }
diff --git a/drivers/gpu/drm/r128/ati_pcigart.c b/drivers/gpu/drm/r128/ati_pcigart.c
index 9b4072f97215..3e76ae5a17ee 100644
--- a/drivers/gpu/drm/r128/ati_pcigart.c
+++ b/drivers/gpu/drm/r128/ati_pcigart.c
@@ -32,9 +32,10 @@
  */
 
 #include <linux/export.h>
+#include <linux/pci.h>
 
 #include <drm/drm_device.h>
-#include <drm/drm_pci.h>
+#include <drm/drm_legacy.h>
 #include <drm/drm_print.h>
 
 #include "ati_pcigart.h"
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
index c693b2ca0329..11c97edde54d 100644
--- a/drivers/gpu/drm/radeon/Makefile
+++ b/drivers/gpu/drm/radeon/Makefile
@@ -3,42 +3,13 @@
 # Makefile for the drm device driver.  This driver provides support for the
 # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
 
-ccflags-y := -Idrivers/gpu/drm/amd/include
-
 hostprogs := mkregtable
-clean-files := rn50_reg_safe.h r100_reg_safe.h r200_reg_safe.h rv515_reg_safe.h r300_reg_safe.h r420_reg_safe.h rs600_reg_safe.h r600_reg_safe.h evergreen_reg_safe.h cayman_reg_safe.h
+targets := rn50_reg_safe.h r100_reg_safe.h r200_reg_safe.h rv515_reg_safe.h r300_reg_safe.h r420_reg_safe.h rs600_reg_safe.h r600_reg_safe.h evergreen_reg_safe.h cayman_reg_safe.h
 
-quiet_cmd_mkregtable = MKREGTABLE $@
+quiet_cmd_mkregtable = MKREG   $@
       cmd_mkregtable = $(obj)/mkregtable $< > $@
 
-$(obj)/rn50_reg_safe.h: $(src)/reg_srcs/rn50 $(obj)/mkregtable
-	$(call if_changed,mkregtable)
-
-$(obj)/r100_reg_safe.h: $(src)/reg_srcs/r100 $(obj)/mkregtable
-	$(call if_changed,mkregtable)
-
-$(obj)/r200_reg_safe.h: $(src)/reg_srcs/r200 $(obj)/mkregtable
-	$(call if_changed,mkregtable)
-
-$(obj)/rv515_reg_safe.h: $(src)/reg_srcs/rv515 $(obj)/mkregtable
-	$(call if_changed,mkregtable)
-
-$(obj)/r300_reg_safe.h: $(src)/reg_srcs/r300 $(obj)/mkregtable
-	$(call if_changed,mkregtable)
-
-$(obj)/r420_reg_safe.h: $(src)/reg_srcs/r420 $(obj)/mkregtable
-	$(call if_changed,mkregtable)
-
-$(obj)/rs600_reg_safe.h: $(src)/reg_srcs/rs600 $(obj)/mkregtable
-	$(call if_changed,mkregtable)
-
-$(obj)/r600_reg_safe.h: $(src)/reg_srcs/r600 $(obj)/mkregtable
-	$(call if_changed,mkregtable)
-
-$(obj)/evergreen_reg_safe.h: $(src)/reg_srcs/evergreen $(obj)/mkregtable
-	$(call if_changed,mkregtable)
-
-$(obj)/cayman_reg_safe.h: $(src)/reg_srcs/cayman $(obj)/mkregtable
+$(obj)/%_reg_safe.h: $(src)/reg_srcs/% $(obj)/mkregtable FORCE
 	$(call if_changed,mkregtable)
 
 $(obj)/r100.o: $(obj)/r100_reg_safe.h $(obj)/rn50_reg_safe.h
diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c
index a9257bed3484..134aa2b01f90 100644
--- a/drivers/gpu/drm/radeon/ci_dpm.c
+++ b/drivers/gpu/drm/radeon/ci_dpm.c
@@ -65,13 +65,6 @@ static const struct ci_pt_defaults defaults_bonaire_xt =
 	{ 0x17C, 0x172, 0x180, 0x1BC, 0x1B3, 0x1BD, 0x206, 0x200, 0x203, 0x25D, 0x25A, 0x255, 0x2C3, 0x2C5, 0x2B4 }
 };
 
-static const struct ci_pt_defaults defaults_bonaire_pro =
-{
-	1, 0xF, 0xFD, 0x19, 5, 45, 0, 0x65062,
-	{ 0x8C,  0x23F, 0x244, 0xA6,  0x83,  0x85,  0x86,  0x86,  0x83,  0xDB,  0xDB,  0xDA,  0x67,  0x60,  0x5F  },
-	{ 0x187, 0x193, 0x193, 0x1C7, 0x1D1, 0x1D1, 0x210, 0x219, 0x219, 0x266, 0x26C, 0x26C, 0x2C9, 0x2CB, 0x2CB }
-};
-
 static const struct ci_pt_defaults defaults_saturn_xt =
 {
 	1, 0xF, 0xFD, 0x19, 5, 55, 0, 0x70000,
@@ -79,13 +72,6 @@ static const struct ci_pt_defaults defaults_saturn_xt =
 	{ 0x187, 0x187, 0x187, 0x1C7, 0x1C7, 0x1C7, 0x210, 0x210, 0x210, 0x266, 0x266, 0x266, 0x2C9, 0x2C9, 0x2C9 }
 };
 
-static const struct ci_pt_defaults defaults_saturn_pro =
-{
-	1, 0xF, 0xFD, 0x19, 5, 55, 0, 0x30000,
-	{ 0x96,  0x21D, 0x23B, 0xA1,  0x85,  0x87,  0x83,  0x84,  0x81,  0xE6,  0xE6,  0xE6,  0x71,  0x6A,  0x6A  },
-	{ 0x193, 0x19E, 0x19E, 0x1D2, 0x1DC, 0x1DC, 0x21A, 0x223, 0x223, 0x26E, 0x27E, 0x274, 0x2CF, 0x2D2, 0x2D2 }
-};
-
 static const struct ci_pt_config_reg didt_config_ci[] =
 {
 	{ 0x10, 0x000000ff, 0, 0x0, CISLANDS_CONFIGREG_DIDT_IND },
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index 848ef68d9086..5d2591725189 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -2111,7 +2111,7 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)
 								    ucOverdriveThermalController];
 			info.addr = power_info->info.ucOverdriveControllerAddress >> 1;
 			strlcpy(info.type, name, sizeof(info.type));
-			i2c_new_device(&rdev->pm.i2c_bus->adapter, &info);
+			i2c_new_client_device(&rdev->pm.i2c_bus->adapter, &info);
 		}
 	}
 	num_modes = power_info->info.ucNumOfPowerModeEntries;
@@ -2351,7 +2351,7 @@ static void radeon_atombios_add_pplib_thermal_controller(struct radeon_device *r
 				const char *name = pp_lib_thermal_controller_names[controller->ucType];
 				info.addr = controller->ucI2cAddress >> 1;
 				strlcpy(info.type, name, sizeof(info.type));
-				i2c_new_device(&rdev->pm.i2c_bus->adapter, &info);
+				i2c_new_client_device(&rdev->pm.i2c_bus->adapter, &info);
 			}
 		} else {
 			DRM_INFO("Unknown thermal controller type %d at 0x%02x %s fan control\n",
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c
index c3e49c973812..d3c04df7e75d 100644
--- a/drivers/gpu/drm/radeon/radeon_combios.c
+++ b/drivers/gpu/drm/radeon/radeon_combios.c
@@ -2704,7 +2704,7 @@ void radeon_combios_get_power_modes(struct radeon_device *rdev)
 				const char *name = thermal_controller_names[thermal_controller];
 				info.addr = i2c_addr >> 1;
 				strlcpy(info.type, name, sizeof(info.type));
-				i2c_new_device(&rdev->pm.i2c_bus->adapter, &info);
+				i2c_new_client_device(&rdev->pm.i2c_bus->adapter, &info);
 			}
 		}
 	} else {
@@ -2721,7 +2721,7 @@ void radeon_combios_get_power_modes(struct radeon_device *rdev)
 				const char *name = "f75375";
 				info.addr = 0x28;
 				strlcpy(info.type, name, sizeof(info.type));
-				i2c_new_device(&rdev->pm.i2c_bus->adapter, &info);
+				i2c_new_client_device(&rdev->pm.i2c_bus->adapter, &info);
 				DRM_INFO("Possible %s thermal controller at 0x%02x\n",
 					 name, info.addr);
 			}
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index 59f8186a2415..bbb0883e8ce6 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -36,6 +36,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/vga_switcheroo.h>
 #include <linux/mmu_notifier.h>
+#include <linux/pci.h>
 
 #include <drm/drm_agpsupport.h>
 #include <drm/drm_crtc_helper.h>
@@ -44,7 +45,6 @@
 #include <drm/drm_file.h>
 #include <drm/drm_gem.h>
 #include <drm/drm_ioctl.h>
-#include <drm/drm_pci.h>
 #include <drm/drm_pciids.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/drm_vblank.h>
diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c
index 2cb85dbe728f..a167e1c36d24 100644
--- a/drivers/gpu/drm/radeon/si_dpm.c
+++ b/drivers/gpu/drm/radeon/si_dpm.c
@@ -252,24 +252,6 @@ static const struct si_dte_data dte_data_tahiti =
 	false
 };
 
-static const struct si_dte_data dte_data_tahiti_le =
-{
-	{ 0x1E8480, 0x7A1200, 0x2160EC0, 0x3938700, 0 },
-	{ 0x7D, 0x7D, 0x4E4, 0xB00, 0 },
-	0x5,
-	0xAFC8,
-	0x64,
-	0x32,
-	1,
-	0,
-	0x10,
-	{ 0x78, 0x7C, 0x82, 0x88, 0x8E, 0x94, 0x9A, 0xA0, 0xA6, 0xAC, 0xB0, 0xB4, 0xB8, 0xBC, 0xC0, 0xC4 },
-	{ 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700 },
-	{ 0x2AF8, 0x2AF8, 0x29BB, 0x27F9, 0x2637, 0x2475, 0x22B3, 0x20F1, 0x1F2F, 0x1D6D, 0x1734, 0x1414, 0x10F4, 0xDD4, 0xAB4, 0x794 },
-	85,
-	true
-};
-
 static const struct si_dte_data dte_data_tahiti_pro =
 {
 	{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
index 654e2dd08146..3e67cf70f040 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
@@ -530,7 +530,6 @@ static int rcar_du_remove(struct platform_device *pdev)
 	drm_dev_unregister(ddev);
 
 	drm_kms_helper_poll_fini(ddev);
-	drm_mode_config_cleanup(ddev);
 
 	drm_dev_put(ddev);
 
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
index c07c6a88aff0..b0335da0c161 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
@@ -13,6 +13,7 @@
 #include <drm/drm_crtc.h>
 #include <drm/drm_modeset_helper_vtables.h>
 #include <drm/drm_panel.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "rcar_du_drv.h"
 #include "rcar_du_encoder.h"
@@ -23,13 +24,6 @@
  * Encoder
  */
 
-static const struct drm_encoder_helper_funcs encoder_helper_funcs = {
-};
-
-static const struct drm_encoder_funcs encoder_funcs = {
-	.destroy = drm_encoder_cleanup,
-};
-
 static unsigned int rcar_du_encoder_count_ports(struct device_node *node)
 {
 	struct device_node *ports;
@@ -110,13 +104,11 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu,
 		}
 	}
 
-	ret = drm_encoder_init(rcdu->ddev, encoder, &encoder_funcs,
-			       DRM_MODE_ENCODER_NONE, NULL);
+	ret = drm_simple_encoder_init(rcdu->ddev, encoder,
+				      DRM_MODE_ENCODER_NONE);
 	if (ret < 0)
 		goto done;
 
-	drm_encoder_helper_add(encoder, &encoder_helper_funcs);
-
 	/*
 	 * Attach the bridge to the encoder. The bridge will create the
 	 * connector.
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
index fcfd916227d1..482329102f19 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
@@ -712,7 +712,9 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
 	unsigned int i;
 	int ret;
 
-	drm_mode_config_init(dev);
+	ret = drmm_mode_config_init(dev);
+	if (ret)
+		return ret;
 
 	dev->mode_config.min_width = 0;
 	dev->mode_config.min_height = 0;
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index ce98c08aa8b4..ade2327a10e2 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -26,6 +26,7 @@
 #include <drm/drm_of.h>
 #include <drm/drm_panel.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "rockchip_drm_drv.h"
 #include "rockchip_drm_vop.h"
@@ -258,10 +259,6 @@ static struct drm_encoder_helper_funcs rockchip_dp_encoder_helper_funcs = {
 	.atomic_check = rockchip_dp_drm_encoder_atomic_check,
 };
 
-static struct drm_encoder_funcs rockchip_dp_encoder_funcs = {
-	.destroy = drm_encoder_cleanup,
-};
-
 static int rockchip_dp_of_probe(struct rockchip_dp_device *dp)
 {
 	struct device *dev = dp->dev;
@@ -309,8 +306,8 @@ static int rockchip_dp_drm_create_encoder(struct rockchip_dp_device *dp)
 							     dev->of_node);
 	DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
 
-	ret = drm_encoder_init(drm_dev, encoder, &rockchip_dp_encoder_funcs,
-			       DRM_MODE_ENCODER_TMDS, NULL);
+	ret = drm_simple_encoder_init(drm_dev, encoder,
+				      DRM_MODE_ENCODER_TMDS);
 	if (ret) {
 		DRM_ERROR("failed to initialize encoder with drm\n");
 		return ret;
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index eed594bd38d3..06f85138b51b 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -20,6 +20,7 @@
 #include <drm/drm_edid.h>
 #include <drm/drm_of.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "cdn-dp-core.h"
 #include "cdn-dp-reg.h"
@@ -689,10 +690,6 @@ static const struct drm_encoder_helper_funcs cdn_dp_encoder_helper_funcs = {
 	.atomic_check = cdn_dp_encoder_atomic_check,
 };
 
-static const struct drm_encoder_funcs cdn_dp_encoder_funcs = {
-	.destroy = drm_encoder_cleanup,
-};
-
 static int cdn_dp_parse_dt(struct cdn_dp_device *dp)
 {
 	struct device *dev = dp->dev;
@@ -1030,8 +1027,8 @@ static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
 							     dev->of_node);
 	DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
 
-	ret = drm_encoder_init(drm_dev, encoder, &cdn_dp_encoder_funcs,
-			       DRM_MODE_ENCODER_TMDS, NULL);
+	ret = drm_simple_encoder_init(drm_dev, encoder,
+				      DRM_MODE_ENCODER_TMDS);
 	if (ret) {
 		DRM_ERROR("failed to initialize encoder with drm\n");
 		return ret;
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
index 6e1270e45f97..3feff0c45b3f 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
@@ -21,6 +21,7 @@
 #include <drm/bridge/dw_mipi_dsi.h>
 #include <drm/drm_mipi_dsi.h>
 #include <drm/drm_of.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "rockchip_drm_drv.h"
 #include "rockchip_drm_vop.h"
@@ -789,10 +790,6 @@ dw_mipi_dsi_encoder_helper_funcs = {
 	.disable = dw_mipi_dsi_encoder_disable,
 };
 
-static const struct drm_encoder_funcs dw_mipi_dsi_encoder_funcs = {
-	.destroy = drm_encoder_cleanup,
-};
-
 static int rockchip_dsi_drm_create_encoder(struct dw_mipi_dsi_rockchip *dsi,
 					   struct drm_device *drm_dev)
 {
@@ -802,8 +799,7 @@ static int rockchip_dsi_drm_create_encoder(struct dw_mipi_dsi_rockchip *dsi,
 	encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev,
 							     dsi->dev->of_node);
 
-	ret = drm_encoder_init(drm_dev, encoder, &dw_mipi_dsi_encoder_funcs,
-			       DRM_MODE_ENCODER_DSI, NULL);
+	ret = drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_DSI);
 	if (ret) {
 		DRM_ERROR("Failed to initialize encoder with drm\n");
 		return ret;
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index 7f56d8c3491d..121aa8a63a76 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -14,6 +14,7 @@
 #include <drm/drm_edid.h>
 #include <drm/drm_of.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "rockchip_drm_drv.h"
 #include "rockchip_drm_vop.h"
@@ -237,10 +238,6 @@ dw_hdmi_rockchip_mode_valid(struct drm_connector *connector,
 	return (valid) ? MODE_OK : MODE_BAD;
 }
 
-static const struct drm_encoder_funcs dw_hdmi_rockchip_encoder_funcs = {
-	.destroy = drm_encoder_cleanup,
-};
-
 static void dw_hdmi_rockchip_encoder_disable(struct drm_encoder *encoder)
 {
 }
@@ -546,8 +543,7 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
 	}
 
 	drm_encoder_helper_add(encoder, &dw_hdmi_rockchip_encoder_helper_funcs);
-	drm_encoder_init(drm, encoder, &dw_hdmi_rockchip_encoder_funcs,
-			 DRM_MODE_ENCODER_TMDS, NULL);
+	drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
 
 	platform_set_drvdata(pdev, hdmi);
 
diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
index e5864e823020..7afdc54eb3ec 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -19,6 +19,7 @@
 #include <drm/drm_edid.h>
 #include <drm/drm_of.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "rockchip_drm_drv.h"
 #include "rockchip_drm_vop.h"
@@ -532,10 +533,6 @@ static struct drm_encoder_helper_funcs inno_hdmi_encoder_helper_funcs = {
 	.atomic_check = inno_hdmi_encoder_atomic_check,
 };
 
-static struct drm_encoder_funcs inno_hdmi_encoder_funcs = {
-	.destroy = drm_encoder_cleanup,
-};
-
 static enum drm_connector_status
 inno_hdmi_connector_detect(struct drm_connector *connector, bool force)
 {
@@ -617,8 +614,7 @@ static int inno_hdmi_register(struct drm_device *drm, struct inno_hdmi *hdmi)
 		return -EPROBE_DEFER;
 
 	drm_encoder_helper_add(encoder, &inno_hdmi_encoder_helper_funcs);
-	drm_encoder_init(drm, encoder, &inno_hdmi_encoder_funcs,
-			 DRM_MODE_ENCODER_TMDS, NULL);
+	drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
 
 	hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD;
 
diff --git a/drivers/gpu/drm/rockchip/rk3066_hdmi.c b/drivers/gpu/drm/rockchip/rk3066_hdmi.c
index fe203d38664e..1c546c3a8998 100644
--- a/drivers/gpu/drm/rockchip/rk3066_hdmi.c
+++ b/drivers/gpu/drm/rockchip/rk3066_hdmi.c
@@ -6,6 +6,7 @@
 
 #include <drm/drm_of.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include <linux/clk.h>
 #include <linux/mfd/syscon.h>
@@ -451,10 +452,6 @@ struct drm_encoder_helper_funcs rk3066_hdmi_encoder_helper_funcs = {
 	.atomic_check = rk3066_hdmi_encoder_atomic_check,
 };
 
-static const struct drm_encoder_funcs rk3066_hdmi_encoder_funcs = {
-	.destroy = drm_encoder_cleanup,
-};
-
 static enum drm_connector_status
 rk3066_hdmi_connector_detect(struct drm_connector *connector, bool force)
 {
@@ -557,8 +554,7 @@ rk3066_hdmi_register(struct drm_device *drm, struct rk3066_hdmi *hdmi)
 		return -EPROBE_DEFER;
 
 	drm_encoder_helper_add(encoder, &rk3066_hdmi_encoder_helper_funcs);
-	drm_encoder_init(drm, encoder, &rk3066_hdmi_encoder_funcs,
-			 DRM_MODE_ENCODER_TMDS, NULL);
+	drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
 
 	hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD;
 
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index 20ecb1508a22..0f3eb392fe39 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -135,14 +135,16 @@ static int rockchip_drm_bind(struct device *dev)
 	if (ret)
 		goto err_free;
 
-	drm_mode_config_init(drm_dev);
+	ret = drmm_mode_config_init(drm_dev);
+	if (ret)
+		goto err_iommu_cleanup;
 
 	rockchip_drm_mode_config_init(drm_dev);
 
 	/* Try to bind all sub drivers. */
 	ret = component_bind_all(dev, drm_dev);
 	if (ret)
-		goto err_mode_config_cleanup;
+		goto err_iommu_cleanup;
 
 	ret = drm_vblank_init(drm_dev, drm_dev->mode_config.num_crtc);
 	if (ret)
@@ -173,12 +175,9 @@ static int rockchip_drm_bind(struct device *dev)
 	rockchip_drm_fbdev_fini(drm_dev);
 err_unbind_all:
 	component_unbind_all(dev, drm_dev);
-err_mode_config_cleanup:
-	drm_mode_config_cleanup(drm_dev);
+err_iommu_cleanup:
 	rockchip_iommu_cleanup(drm_dev);
 err_free:
-	drm_dev->dev_private = NULL;
-	dev_set_drvdata(dev, NULL);
 	drm_dev_put(drm_dev);
 	return ret;
 }
@@ -194,11 +193,8 @@ static void rockchip_drm_unbind(struct device *dev)
 
 	drm_atomic_helper_shutdown(drm_dev);
 	component_unbind_all(dev, drm_dev);
-	drm_mode_config_cleanup(drm_dev);
 	rockchip_iommu_cleanup(drm_dev);
 
-	drm_dev->dev_private = NULL;
-	dev_set_drvdata(dev, NULL);
 	drm_dev_put(drm_dev);
 }
 
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index c5b06048124e..e33c2dcd0d4b 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -30,6 +30,7 @@ struct rockchip_crtc_state {
 	int output_mode;
 	int output_bpc;
 	int output_flags;
+	bool enable_afbc;
 };
 #define to_rockchip_crtc_state(s) \
 		container_of(s, struct rockchip_crtc_state, base)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
index 221e72e71432..9b13c784b347 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
@@ -57,8 +57,49 @@ static const struct drm_mode_config_helper_funcs rockchip_mode_config_helpers =
 	.atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
 };
 
+static struct drm_framebuffer *
+rockchip_fb_create(struct drm_device *dev, struct drm_file *file,
+		   const struct drm_mode_fb_cmd2 *mode_cmd)
+{
+	struct drm_afbc_framebuffer *afbc_fb;
+	const struct drm_format_info *info;
+	int ret;
+
+	info = drm_get_format_info(dev, mode_cmd);
+	if (!info)
+		return ERR_PTR(-ENOMEM);
+
+	afbc_fb = kzalloc(sizeof(*afbc_fb), GFP_KERNEL);
+	if (!afbc_fb)
+		return ERR_PTR(-ENOMEM);
+
+	ret = drm_gem_fb_init_with_funcs(dev, &afbc_fb->base, file, mode_cmd,
+					 &rockchip_drm_fb_funcs);
+	if (ret) {
+		kfree(afbc_fb);
+		return ERR_PTR(ret);
+	}
+
+	if (drm_is_afbc(mode_cmd->modifier[0])) {
+		int ret, i;
+
+		ret = drm_gem_fb_afbc_init(dev, mode_cmd, afbc_fb);
+		if (ret) {
+			struct drm_gem_object **obj = afbc_fb->base.obj;
+
+			for (i = 0; i < info->num_planes; ++i)
+				drm_gem_object_put_unlocked(obj[i]);
+
+			kfree(afbc_fb);
+			return ERR_PTR(ret);
+		}
+	}
+
+	return &afbc_fb->base;
+}
+
 static const struct drm_mode_config_funcs rockchip_drm_mode_config_funcs = {
-	.fb_create = drm_gem_fb_create_with_dirty,
+	.fb_create = rockchip_fb_create,
 	.output_poll_changed = drm_fb_helper_output_poll_changed,
 	.atomic_check = drm_atomic_helper_check,
 	.atomic_commit = drm_atomic_helper_commit,
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index cecb2cc781f5..33463b79a37b 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -91,9 +91,22 @@
 #define VOP_WIN_TO_INDEX(vop_win) \
 	((vop_win) - (vop_win)->vop->win)
 
+#define VOP_AFBC_SET(vop, name, v) \
+	do { \
+		if ((vop)->data->afbc) \
+			vop_reg_set((vop), &(vop)->data->afbc->name, \
+				    0, ~0, v, #name); \
+	} while (0)
+
 #define to_vop(x) container_of(x, struct vop, crtc)
 #define to_vop_win(x) container_of(x, struct vop_win, base)
 
+#define AFBC_FMT_RGB565		0x0
+#define AFBC_FMT_U8U8U8U8	0x5
+#define AFBC_FMT_U8U8U8		0x4
+
+#define AFBC_TILE_16x16		BIT(4)
+
 /*
  * The coefficients of the following matrix are all fixed points.
  * The format is S2.10 for the 3x3 part of the matrix, and S9.12 for the offsets.
@@ -274,6 +287,29 @@ static enum vop_data_format vop_convert_format(uint32_t format)
 	}
 }
 
+static int vop_convert_afbc_format(uint32_t format)
+{
+	switch (format) {
+	case DRM_FORMAT_XRGB8888:
+	case DRM_FORMAT_ARGB8888:
+	case DRM_FORMAT_XBGR8888:
+	case DRM_FORMAT_ABGR8888:
+		return AFBC_FMT_U8U8U8U8;
+	case DRM_FORMAT_RGB888:
+	case DRM_FORMAT_BGR888:
+		return AFBC_FMT_U8U8U8;
+	case DRM_FORMAT_RGB565:
+	case DRM_FORMAT_BGR565:
+		return AFBC_FMT_RGB565;
+	/* either of the below should not be reachable */
+	default:
+		DRM_WARN_ONCE("unsupported AFBC format[%08x]\n", format);
+		return -EINVAL;
+	}
+
+	return -EINVAL;
+}
+
 static uint16_t scl_vop_cal_scale(enum scale_mode mode, uint32_t src,
 				  uint32_t dst, bool is_horizontal,
 				  int vsu_mode, int *vskiplines)
@@ -598,6 +634,17 @@ static int vop_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_state)
 			vop_win_disable(vop, vop_win);
 		}
 	}
+
+	if (vop->data->afbc) {
+		struct rockchip_crtc_state *s;
+		/*
+		 * Disable AFBC and forget there was a vop window with AFBC
+		 */
+		VOP_AFBC_SET(vop, enable, 0);
+		s = to_rockchip_crtc_state(crtc->state);
+		s->enable_afbc = false;
+	}
+
 	spin_unlock(&vop->reg_lock);
 
 	vop_cfg_done(vop);
@@ -710,6 +757,26 @@ static void vop_plane_destroy(struct drm_plane *plane)
 	drm_plane_cleanup(plane);
 }
 
+static inline bool rockchip_afbc(u64 modifier)
+{
+	return modifier == ROCKCHIP_AFBC_MOD;
+}
+
+static bool rockchip_mod_supported(struct drm_plane *plane,
+				   u32 format, u64 modifier)
+{
+	if (modifier == DRM_FORMAT_MOD_LINEAR)
+		return true;
+
+	if (!rockchip_afbc(modifier)) {
+		DRM_DEBUG_KMS("Unsupported format modifier 0x%llx\n", modifier);
+
+		return false;
+	}
+
+	return vop_convert_afbc_format(format) >= 0;
+}
+
 static int vop_plane_atomic_check(struct drm_plane *plane,
 			   struct drm_plane_state *state)
 {
@@ -758,6 +825,30 @@ static int vop_plane_atomic_check(struct drm_plane *plane,
 		return -EINVAL;
 	}
 
+	if (rockchip_afbc(fb->modifier)) {
+		struct vop *vop = to_vop(crtc);
+
+		if (!vop->data->afbc) {
+			DRM_ERROR("vop does not support AFBC\n");
+			return -EINVAL;
+		}
+
+		ret = vop_convert_afbc_format(fb->format->format);
+		if (ret < 0)
+			return ret;
+
+		if (state->src.x1 || state->src.y1) {
+			DRM_ERROR("AFBC does not support offset display, xpos=%d, ypos=%d, offset=%d\n", state->src.x1, state->src.y1, fb->offsets[0]);
+			return -EINVAL;
+		}
+
+		if (state->rotation && state->rotation != DRM_MODE_ROTATE_0) {
+			DRM_ERROR("No rotation support in AFBC, rotation=%d\n",
+				  state->rotation);
+			return -EINVAL;
+		}
+	}
+
 	return 0;
 }
 
@@ -846,6 +937,16 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
 
 	spin_lock(&vop->reg_lock);
 
+	if (rockchip_afbc(fb->modifier)) {
+		int afbc_format = vop_convert_afbc_format(fb->format->format);
+
+		VOP_AFBC_SET(vop, format, afbc_format | AFBC_TILE_16x16);
+		VOP_AFBC_SET(vop, hreg_block_split, 0);
+		VOP_AFBC_SET(vop, win_sel, VOP_WIN_TO_INDEX(vop_win));
+		VOP_AFBC_SET(vop, hdr_ptr, dma_addr);
+		VOP_AFBC_SET(vop, pic_size, act_info);
+	}
+
 	VOP_WIN_SET(vop, win, format, format);
 	VOP_WIN_SET(vop, win, yrgb_vir, DIV_ROUND_UP(fb->pitches[0], 4));
 	VOP_WIN_SET(vop, win, yrgb_mst, dma_addr);
@@ -1001,6 +1102,7 @@ static const struct drm_plane_funcs vop_plane_funcs = {
 	.reset = drm_atomic_helper_plane_reset,
 	.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
 	.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
+	.format_mod_supported = rockchip_mod_supported,
 };
 
 static int vop_crtc_enable_vblank(struct drm_crtc *crtc)
@@ -1310,6 +1412,10 @@ static int vop_crtc_atomic_check(struct drm_crtc *crtc,
 				 struct drm_crtc_state *crtc_state)
 {
 	struct vop *vop = to_vop(crtc);
+	struct drm_plane *plane;
+	struct drm_plane_state *plane_state;
+	struct rockchip_crtc_state *s;
+	int afbc_planes = 0;
 
 	if (vop->lut_regs && crtc_state->color_mgmt_changed &&
 	    crtc_state->gamma_lut) {
@@ -1323,6 +1429,27 @@ static int vop_crtc_atomic_check(struct drm_crtc *crtc,
 		}
 	}
 
+	drm_atomic_crtc_state_for_each_plane(plane, crtc_state) {
+		plane_state =
+			drm_atomic_get_plane_state(crtc_state->state, plane);
+		if (IS_ERR(plane_state)) {
+			DRM_DEBUG_KMS("Cannot get plane state for plane %s\n",
+				      plane->name);
+			return PTR_ERR(plane_state);
+		}
+
+		if (drm_is_afbc(plane_state->fb->modifier))
+			++afbc_planes;
+	}
+
+	if (afbc_planes > 1) {
+		DRM_DEBUG_KMS("Invalid number of AFBC planes; got %d, expected at most 1\n", afbc_planes);
+		return -EINVAL;
+	}
+
+	s = to_rockchip_crtc_state(crtc_state);
+	s->enable_afbc = afbc_planes > 0;
+
 	return 0;
 }
 
@@ -1333,6 +1460,7 @@ static void vop_crtc_atomic_flush(struct drm_crtc *crtc,
 	struct drm_plane_state *old_plane_state, *new_plane_state;
 	struct vop *vop = to_vop(crtc);
 	struct drm_plane *plane;
+	struct rockchip_crtc_state *s;
 	int i;
 
 	if (WARN_ON(!vop->is_enabled))
@@ -1340,6 +1468,9 @@ static void vop_crtc_atomic_flush(struct drm_crtc *crtc,
 
 	spin_lock(&vop->reg_lock);
 
+	/* Enable AFBC if there is some AFBC window, disable otherwise. */
+	s = to_rockchip_crtc_state(crtc->state);
+	VOP_AFBC_SET(vop, enable, s->enable_afbc);
 	vop_cfg_done(vop);
 
 	spin_unlock(&vop->reg_lock);
@@ -1634,7 +1765,8 @@ static int vop_create_crtc(struct vop *vop)
 					       0, &vop_plane_funcs,
 					       win_data->phy->data_formats,
 					       win_data->phy->nformats,
-					       NULL, win_data->type, NULL);
+					       win_data->phy->format_modifiers,
+					       win_data->type, NULL);
 		if (ret) {
 			DRM_DEV_ERROR(vop->dev, "failed to init plane %d\n",
 				      ret);
@@ -1678,7 +1810,8 @@ static int vop_create_crtc(struct vop *vop)
 					       &vop_plane_funcs,
 					       win_data->phy->data_formats,
 					       win_data->phy->nformats,
-					       NULL, win_data->type, NULL);
+					       win_data->phy->format_modifiers,
+					       win_data->type, NULL);
 		if (ret) {
 			DRM_DEV_ERROR(vop->dev, "failed to init overlay %d\n",
 				      ret);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
index cc672620d6e0..d03bdb531ef2 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
@@ -17,6 +17,11 @@
 
 #define NUM_YUV2YUV_COEFFICIENTS 12
 
+#define ROCKCHIP_AFBC_MOD \
+	DRM_FORMAT_MOD_ARM_AFBC( \
+		AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | AFBC_FORMAT_MOD_SPARSE \
+	)
+
 enum vop_data_format {
 	VOP_FMT_ARGB8888 = 0,
 	VOP_FMT_RGB888,
@@ -34,6 +39,16 @@ struct vop_reg {
 	bool relaxed;
 };
 
+struct vop_afbc {
+	struct vop_reg enable;
+	struct vop_reg win_sel;
+	struct vop_reg format;
+	struct vop_reg hreg_block_split;
+	struct vop_reg pic_size;
+	struct vop_reg hdr_ptr;
+	struct vop_reg rstn;
+};
+
 struct vop_modeset {
 	struct vop_reg htotal_pw;
 	struct vop_reg hact_st_end;
@@ -134,6 +149,7 @@ struct vop_win_phy {
 	const struct vop_scl_regs *scl;
 	const uint32_t *data_formats;
 	uint32_t nformats;
+	const uint64_t *format_modifiers;
 
 	struct vop_reg enable;
 	struct vop_reg gate;
@@ -173,6 +189,7 @@ struct vop_data {
 	const struct vop_misc *misc;
 	const struct vop_modeset *modeset;
 	const struct vop_output *output;
+	const struct vop_afbc *afbc;
 	const struct vop_win_yuv2yuv_data *win_yuv2yuv;
 	const struct vop_win_data *win;
 	unsigned int win_size;
diff --git a/drivers/gpu/drm/rockchip/rockchip_lvds.c b/drivers/gpu/drm/rockchip/rockchip_lvds.c
index 449a62908d21..63f967902c2d 100644
--- a/drivers/gpu/drm/rockchip/rockchip_lvds.c
+++ b/drivers/gpu/drm/rockchip/rockchip_lvds.c
@@ -16,13 +16,14 @@
 #include <linux/pm_runtime.h>
 #include <linux/regmap.h>
 #include <linux/reset.h>
+
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_bridge.h>
-
 #include <drm/drm_dp_helper.h>
 #include <drm/drm_of.h>
 #include <drm/drm_panel.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "rockchip_drm_drv.h"
 #include "rockchip_drm_vop.h"
@@ -435,10 +436,6 @@ struct drm_encoder_helper_funcs px30_lvds_encoder_helper_funcs = {
 	.atomic_check = rockchip_lvds_encoder_atomic_check,
 };
 
-static const struct drm_encoder_funcs rockchip_lvds_encoder_funcs = {
-	.destroy = drm_encoder_cleanup,
-};
-
 static int rk3288_lvds_probe(struct platform_device *pdev,
 			     struct rockchip_lvds *lvds)
 {
@@ -607,8 +604,7 @@ static int rockchip_lvds_bind(struct device *dev, struct device *master,
 	encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev,
 							     dev->of_node);
 
-	ret = drm_encoder_init(drm_dev, encoder, &rockchip_lvds_encoder_funcs,
-			       DRM_MODE_ENCODER_LVDS, NULL);
+	ret = drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_LVDS);
 	if (ret < 0) {
 		DRM_DEV_ERROR(drm_dev->dev,
 			      "failed to initialize encoder: %d\n", ret);
diff --git a/drivers/gpu/drm/rockchip/rockchip_rgb.c b/drivers/gpu/drm/rockchip/rockchip_rgb.c
index 90784781e515..9a771af5d0c9 100644
--- a/drivers/gpu/drm/rockchip/rockchip_rgb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_rgb.c
@@ -14,6 +14,7 @@
 #include <drm/drm_of.h>
 #include <drm/drm_panel.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "rockchip_drm_drv.h"
 #include "rockchip_drm_vop.h"
@@ -67,10 +68,6 @@ struct drm_encoder_helper_funcs rockchip_rgb_encoder_helper_funcs = {
 	.atomic_check = rockchip_rgb_encoder_atomic_check,
 };
 
-static const struct drm_encoder_funcs rockchip_rgb_encoder_funcs = {
-	.destroy = drm_encoder_cleanup,
-};
-
 struct rockchip_rgb *rockchip_rgb_init(struct device *dev,
 				       struct drm_crtc *crtc,
 				       struct drm_device *drm_dev)
@@ -126,8 +123,7 @@ struct rockchip_rgb *rockchip_rgb_init(struct device *dev,
 	encoder = &rgb->encoder;
 	encoder->possible_crtcs = drm_crtc_mask(crtc);
 
-	ret = drm_encoder_init(drm_dev, encoder, &rockchip_rgb_encoder_funcs,
-			       DRM_MODE_ENCODER_NONE, NULL);
+	ret = drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_NONE);
 	if (ret < 0) {
 		DRM_DEV_ERROR(drm_dev->dev,
 			      "failed to initialize encoder: %d\n", ret);
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index 7a9d979c8d5d..2413deded22c 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -50,6 +50,17 @@ static const uint32_t formats_win_full[] = {
 	DRM_FORMAT_NV24,
 };
 
+static const uint64_t format_modifiers_win_full[] = {
+	DRM_FORMAT_MOD_LINEAR,
+	DRM_FORMAT_MOD_INVALID,
+};
+
+static const uint64_t format_modifiers_win_full_afbc[] = {
+	ROCKCHIP_AFBC_MOD,
+	DRM_FORMAT_MOD_LINEAR,
+	DRM_FORMAT_MOD_INVALID,
+};
+
 static const uint32_t formats_win_lite[] = {
 	DRM_FORMAT_XRGB8888,
 	DRM_FORMAT_ARGB8888,
@@ -61,6 +72,11 @@ static const uint32_t formats_win_lite[] = {
 	DRM_FORMAT_BGR565,
 };
 
+static const uint64_t format_modifiers_win_lite[] = {
+	DRM_FORMAT_MOD_LINEAR,
+	DRM_FORMAT_MOD_INVALID,
+};
+
 static const struct vop_scl_regs rk3036_win_scl = {
 	.scale_yrgb_x = VOP_REG(RK3036_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
 	.scale_yrgb_y = VOP_REG(RK3036_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
@@ -72,6 +88,7 @@ static const struct vop_win_phy rk3036_win0_data = {
 	.scl = &rk3036_win_scl,
 	.data_formats = formats_win_full,
 	.nformats = ARRAY_SIZE(formats_win_full),
+	.format_modifiers = format_modifiers_win_full,
 	.enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 0),
 	.format = VOP_REG(RK3036_SYS_CTRL, 0x7, 3),
 	.rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 15),
@@ -87,6 +104,7 @@ static const struct vop_win_phy rk3036_win0_data = {
 static const struct vop_win_phy rk3036_win1_data = {
 	.data_formats = formats_win_lite,
 	.nformats = ARRAY_SIZE(formats_win_lite),
+	.format_modifiers = format_modifiers_win_lite,
 	.enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 1),
 	.format = VOP_REG(RK3036_SYS_CTRL, 0x7, 6),
 	.rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 19),
@@ -153,6 +171,7 @@ static const struct vop_data rk3036_vop = {
 static const struct vop_win_phy rk3126_win1_data = {
 	.data_formats = formats_win_lite,
 	.nformats = ARRAY_SIZE(formats_win_lite),
+	.format_modifiers = format_modifiers_win_lite,
 	.enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 1),
 	.format = VOP_REG(RK3036_SYS_CTRL, 0x7, 6),
 	.rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 19),
@@ -234,6 +253,7 @@ static const struct vop_win_phy px30_win0_data = {
 	.scl = &px30_win_scl,
 	.data_formats = formats_win_full,
 	.nformats = ARRAY_SIZE(formats_win_full),
+	.format_modifiers = format_modifiers_win_full,
 	.enable = VOP_REG(PX30_WIN0_CTRL0, 0x1, 0),
 	.format = VOP_REG(PX30_WIN0_CTRL0, 0x7, 1),
 	.rb_swap = VOP_REG(PX30_WIN0_CTRL0, 0x1, 12),
@@ -249,6 +269,7 @@ static const struct vop_win_phy px30_win0_data = {
 static const struct vop_win_phy px30_win1_data = {
 	.data_formats = formats_win_lite,
 	.nformats = ARRAY_SIZE(formats_win_lite),
+	.format_modifiers = format_modifiers_win_lite,
 	.enable = VOP_REG(PX30_WIN1_CTRL0, 0x1, 0),
 	.format = VOP_REG(PX30_WIN1_CTRL0, 0x7, 4),
 	.rb_swap = VOP_REG(PX30_WIN1_CTRL0, 0x1, 12),
@@ -261,6 +282,7 @@ static const struct vop_win_phy px30_win1_data = {
 static const struct vop_win_phy px30_win2_data = {
 	.data_formats = formats_win_lite,
 	.nformats = ARRAY_SIZE(formats_win_lite),
+	.format_modifiers = format_modifiers_win_lite,
 	.gate = VOP_REG(PX30_WIN2_CTRL0, 0x1, 4),
 	.enable = VOP_REG(PX30_WIN2_CTRL0, 0x1, 0),
 	.format = VOP_REG(PX30_WIN2_CTRL0, 0x3, 5),
@@ -316,6 +338,7 @@ static const struct vop_win_phy rk3066_win0_data = {
 	.scl = &rk3066_win_scl,
 	.data_formats = formats_win_full,
 	.nformats = ARRAY_SIZE(formats_win_full),
+	.format_modifiers = format_modifiers_win_full,
 	.enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 0),
 	.format = VOP_REG(RK3066_SYS_CTRL0, 0x7, 4),
 	.rb_swap = VOP_REG(RK3066_SYS_CTRL0, 0x1, 19),
@@ -332,6 +355,7 @@ static const struct vop_win_phy rk3066_win1_data = {
 	.scl = &rk3066_win_scl,
 	.data_formats = formats_win_full,
 	.nformats = ARRAY_SIZE(formats_win_full),
+	.format_modifiers = format_modifiers_win_full,
 	.enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 1),
 	.format = VOP_REG(RK3066_SYS_CTRL0, 0x7, 7),
 	.rb_swap = VOP_REG(RK3066_SYS_CTRL0, 0x1, 23),
@@ -347,6 +371,7 @@ static const struct vop_win_phy rk3066_win1_data = {
 static const struct vop_win_phy rk3066_win2_data = {
 	.data_formats = formats_win_lite,
 	.nformats = ARRAY_SIZE(formats_win_lite),
+	.format_modifiers = format_modifiers_win_lite,
 	.enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 2),
 	.format = VOP_REG(RK3066_SYS_CTRL0, 0x7, 10),
 	.rb_swap = VOP_REG(RK3066_SYS_CTRL0, 0x1, 27),
@@ -426,6 +451,7 @@ static const struct vop_win_phy rk3188_win0_data = {
 	.scl = &rk3188_win_scl,
 	.data_formats = formats_win_full,
 	.nformats = ARRAY_SIZE(formats_win_full),
+	.format_modifiers = format_modifiers_win_full,
 	.enable = VOP_REG(RK3188_SYS_CTRL, 0x1, 0),
 	.format = VOP_REG(RK3188_SYS_CTRL, 0x7, 3),
 	.rb_swap = VOP_REG(RK3188_SYS_CTRL, 0x1, 15),
@@ -440,6 +466,7 @@ static const struct vop_win_phy rk3188_win0_data = {
 static const struct vop_win_phy rk3188_win1_data = {
 	.data_formats = formats_win_lite,
 	.nformats = ARRAY_SIZE(formats_win_lite),
+	.format_modifiers = format_modifiers_win_lite,
 	.enable = VOP_REG(RK3188_SYS_CTRL, 0x1, 1),
 	.format = VOP_REG(RK3188_SYS_CTRL, 0x7, 6),
 	.rb_swap = VOP_REG(RK3188_SYS_CTRL, 0x1, 19),
@@ -545,6 +572,7 @@ static const struct vop_win_phy rk3288_win01_data = {
 	.scl = &rk3288_win_full_scl,
 	.data_formats = formats_win_full,
 	.nformats = ARRAY_SIZE(formats_win_full),
+	.format_modifiers = format_modifiers_win_full,
 	.enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
 	.format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
 	.rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
@@ -563,6 +591,7 @@ static const struct vop_win_phy rk3288_win01_data = {
 static const struct vop_win_phy rk3288_win23_data = {
 	.data_formats = formats_win_lite,
 	.nformats = ARRAY_SIZE(formats_win_lite),
+	.format_modifiers = format_modifiers_win_lite,
 	.enable = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 4),
 	.gate = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 0),
 	.format = VOP_REG(RK3288_WIN2_CTRL0, 0x7, 1),
@@ -677,6 +706,7 @@ static const struct vop_win_phy rk3368_win01_data = {
 	.scl = &rk3288_win_full_scl,
 	.data_formats = formats_win_full,
 	.nformats = ARRAY_SIZE(formats_win_full),
+	.format_modifiers = format_modifiers_win_full,
 	.enable = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 0),
 	.format = VOP_REG(RK3368_WIN0_CTRL0, 0x7, 1),
 	.rb_swap = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 12),
@@ -697,6 +727,7 @@ static const struct vop_win_phy rk3368_win01_data = {
 static const struct vop_win_phy rk3368_win23_data = {
 	.data_formats = formats_win_lite,
 	.nformats = ARRAY_SIZE(formats_win_lite),
+	.format_modifiers = format_modifiers_win_lite,
 	.gate = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 0),
 	.enable = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 4),
 	.format = VOP_REG(RK3368_WIN2_CTRL0, 0x3, 5),
@@ -817,6 +848,53 @@ static const struct vop_win_yuv2yuv_data rk3399_vop_big_win_yuv2yuv_data[] = {
 	  .y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 9) },
 	{ .base = 0xC0, .phy = &rk3399_yuv2yuv_win23_data },
 	{ .base = 0x120, .phy = &rk3399_yuv2yuv_win23_data },
+
+};
+
+static const struct vop_win_phy rk3399_win01_data = {
+	.scl = &rk3288_win_full_scl,
+	.data_formats = formats_win_full,
+	.nformats = ARRAY_SIZE(formats_win_full),
+	.format_modifiers = format_modifiers_win_full_afbc,
+	.enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
+	.format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
+	.rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
+	.y_mir_en = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 22),
+	.act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0),
+	.dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0),
+	.dsp_st = VOP_REG(RK3288_WIN0_DSP_ST, 0x1fff1fff, 0),
+	.yrgb_mst = VOP_REG(RK3288_WIN0_YRGB_MST, 0xffffffff, 0),
+	.uv_mst = VOP_REG(RK3288_WIN0_CBR_MST, 0xffffffff, 0),
+	.yrgb_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 0),
+	.uv_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 16),
+	.src_alpha_ctl = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xff, 0),
+	.dst_alpha_ctl = VOP_REG(RK3288_WIN0_DST_ALPHA_CTRL, 0xff, 0),
+};
+
+/*
+ * rk3399 vop big windows register layout is same as rk3288, but we
+ * have a separate rk3399 win data array here so that we can advertise
+ * AFBC on the primary plane.
+ */
+static const struct vop_win_data rk3399_vop_win_data[] = {
+	{ .base = 0x00, .phy = &rk3399_win01_data,
+	  .type = DRM_PLANE_TYPE_PRIMARY },
+	{ .base = 0x40, .phy = &rk3288_win01_data,
+	  .type = DRM_PLANE_TYPE_OVERLAY },
+	{ .base = 0x00, .phy = &rk3288_win23_data,
+	  .type = DRM_PLANE_TYPE_OVERLAY },
+	{ .base = 0x50, .phy = &rk3288_win23_data,
+	  .type = DRM_PLANE_TYPE_CURSOR },
+};
+
+static const struct vop_afbc rk3399_vop_afbc = {
+	.rstn = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 3),
+	.enable = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 0),
+	.win_sel = VOP_REG(RK3399_AFBCD0_CTRL, 0x3, 1),
+	.format = VOP_REG(RK3399_AFBCD0_CTRL, 0x1f, 16),
+	.hreg_block_split = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 21),
+	.hdr_ptr = VOP_REG(RK3399_AFBCD0_HDR_PTR, 0xffffffff, 0),
+	.pic_size = VOP_REG(RK3399_AFBCD0_PIC_SIZE, 0xffffffff, 0),
 };
 
 static const struct vop_data rk3399_vop_big = {
@@ -826,9 +904,10 @@ static const struct vop_data rk3399_vop_big = {
 	.common = &rk3288_common,
 	.modeset = &rk3288_modeset,
 	.output = &rk3399_output,
+	.afbc = &rk3399_vop_afbc,
 	.misc = &rk3368_misc,
-	.win = rk3368_vop_win_data,
-	.win_size = ARRAY_SIZE(rk3368_vop_win_data),
+	.win = rk3399_vop_win_data,
+	.win_size = ARRAY_SIZE(rk3399_vop_win_data),
 	.win_yuv2yuv = rk3399_vop_big_win_yuv2yuv_data,
 };
 
diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c
index 8e731ed0d9d9..2f319102ae9f 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -676,7 +676,7 @@ drm_sched_get_cleanup_job(struct drm_gpu_scheduler *sched)
 	 */
 	if ((sched->timeout != MAX_SCHEDULE_TIMEOUT &&
 	    !cancel_delayed_work(&sched->work_tdr)) ||
-	    __kthread_should_park(sched->thread))
+	    kthread_should_park())
 		return NULL;
 
 	spin_lock(&sched->job_list_lock);
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/shmobile/shmob_drm_crtc.c
index 75a752d59ef1..03556dbfcafb 100644
--- a/drivers/gpu/drm/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/shmobile/shmob_drm_crtc.c
@@ -17,6 +17,7 @@
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/drm_plane_helper.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 #include <drm/drm_vblank.h>
 
 #include "shmob_drm_backlight.h"
@@ -558,15 +559,6 @@ static const struct drm_encoder_helper_funcs encoder_helper_funcs = {
 	.mode_set = shmob_drm_encoder_mode_set,
 };
 
-static void shmob_drm_encoder_destroy(struct drm_encoder *encoder)
-{
-	drm_encoder_cleanup(encoder);
-}
-
-static const struct drm_encoder_funcs encoder_funcs = {
-	.destroy = shmob_drm_encoder_destroy,
-};
-
 int shmob_drm_encoder_create(struct shmob_drm_device *sdev)
 {
 	struct drm_encoder *encoder = &sdev->encoder.encoder;
@@ -576,8 +568,8 @@ int shmob_drm_encoder_create(struct shmob_drm_device *sdev)
 
 	encoder->possible_crtcs = 1;
 
-	ret = drm_encoder_init(sdev->ddev, encoder, &encoder_funcs,
-			       DRM_MODE_ENCODER_LVDS, NULL);
+	ret = drm_simple_encoder_init(sdev->ddev, encoder,
+				      DRM_MODE_ENCODER_LVDS);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/shmobile/shmob_drm_drv.c
index b8c0930959c7..ae9d6b8d3ca8 100644
--- a/drivers/gpu/drm/shmobile/shmob_drm_drv.c
+++ b/drivers/gpu/drm/shmobile/shmob_drm_drv.c
@@ -192,7 +192,6 @@ static int shmob_drm_remove(struct platform_device *pdev)
 
 	drm_dev_unregister(ddev);
 	drm_kms_helper_poll_fini(ddev);
-	drm_mode_config_cleanup(ddev);
 	drm_irq_uninstall(ddev);
 	drm_dev_put(ddev);
 
@@ -288,7 +287,6 @@ static int shmob_drm_probe(struct platform_device *pdev)
 	drm_irq_uninstall(ddev);
 err_modeset_cleanup:
 	drm_kms_helper_poll_fini(ddev);
-	drm_mode_config_cleanup(ddev);
 err_free_drm_dev:
 	drm_dev_put(ddev);
 
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_kms.c b/drivers/gpu/drm/shmobile/shmob_drm_kms.c
index c51197b6fd85..7a866d6ce6bb 100644
--- a/drivers/gpu/drm/shmobile/shmob_drm_kms.c
+++ b/drivers/gpu/drm/shmobile/shmob_drm_kms.c
@@ -126,7 +126,11 @@ static const struct drm_mode_config_funcs shmob_drm_mode_config_funcs = {
 
 int shmob_drm_modeset_init(struct shmob_drm_device *sdev)
 {
-	drm_mode_config_init(sdev->ddev);
+	int ret;
+
+	ret = drmm_mode_config_init(sdev->ddev);
+	if (ret)
+		return ret;
 
 	shmob_drm_crtc_create(sdev);
 	shmob_drm_encoder_create(sdev);
diff --git a/drivers/gpu/drm/sti/sti_compositor.c b/drivers/gpu/drm/sti/sti_compositor.c
index c7652584255d..319962a2c17b 100644
--- a/drivers/gpu/drm/sti/sti_compositor.c
+++ b/drivers/gpu/drm/sti/sti_compositor.c
@@ -42,8 +42,8 @@ static const struct sti_compositor_data stih407_compositor_data = {
 	},
 };
 
-int sti_compositor_debugfs_init(struct sti_compositor *compo,
-				struct drm_minor *minor)
+void sti_compositor_debugfs_init(struct sti_compositor *compo,
+				 struct drm_minor *minor)
 {
 	unsigned int i;
 
@@ -54,8 +54,6 @@ int sti_compositor_debugfs_init(struct sti_compositor *compo,
 	for (i = 0; i < STI_MAX_MIXER; i++)
 		if (compo->mixer[i])
 			sti_mixer_debugfs_init(compo->mixer[i], minor);
-
-	return 0;
 }
 
 static int sti_compositor_bind(struct device *dev,
diff --git a/drivers/gpu/drm/sti/sti_compositor.h b/drivers/gpu/drm/sti/sti_compositor.h
index ac4bb3834810..25bb01bdd013 100644
--- a/drivers/gpu/drm/sti/sti_compositor.h
+++ b/drivers/gpu/drm/sti/sti_compositor.h
@@ -79,7 +79,7 @@ struct sti_compositor {
 	struct notifier_block vtg_vblank_nb[STI_MAX_MIXER];
 };
 
-int sti_compositor_debugfs_init(struct sti_compositor *compo,
-				struct drm_minor *minor);
+void sti_compositor_debugfs_init(struct sti_compositor *compo,
+				 struct drm_minor *minor);
 
 #endif
diff --git a/drivers/gpu/drm/sti/sti_crtc.c b/drivers/gpu/drm/sti/sti_crtc.c
index 49e6cb8f5836..6f37c104c46f 100644
--- a/drivers/gpu/drm/sti/sti_crtc.c
+++ b/drivers/gpu/drm/sti/sti_crtc.c
@@ -319,7 +319,7 @@ static int sti_crtc_late_register(struct drm_crtc *crtc)
 	struct sti_compositor *compo = dev_get_drvdata(mixer->dev);
 
 	if (drm_crtc_index(crtc) == 0)
-		return sti_compositor_debugfs_init(compo, crtc->dev->primary);
+		sti_compositor_debugfs_init(compo, crtc->dev->primary);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/sti/sti_cursor.c b/drivers/gpu/drm/sti/sti_cursor.c
index ea64c1dcaf63..a98057431023 100644
--- a/drivers/gpu/drm/sti/sti_cursor.c
+++ b/drivers/gpu/drm/sti/sti_cursor.c
@@ -131,17 +131,17 @@ static struct drm_info_list cursor_debugfs_files[] = {
 	{ "cursor", cursor_dbg_show, 0, NULL },
 };
 
-static int cursor_debugfs_init(struct sti_cursor *cursor,
-			       struct drm_minor *minor)
+static void cursor_debugfs_init(struct sti_cursor *cursor,
+				struct drm_minor *minor)
 {
 	unsigned int i;
 
 	for (i = 0; i < ARRAY_SIZE(cursor_debugfs_files); i++)
 		cursor_debugfs_files[i].data = cursor;
 
-	return drm_debugfs_create_files(cursor_debugfs_files,
-					ARRAY_SIZE(cursor_debugfs_files),
-					minor->debugfs_root, minor);
+	drm_debugfs_create_files(cursor_debugfs_files,
+				 ARRAY_SIZE(cursor_debugfs_files),
+				 minor->debugfs_root, minor);
 }
 
 static void sti_cursor_argb8888_to_clut8(struct sti_cursor *cursor, u32 *src)
@@ -342,7 +342,9 @@ static int sti_cursor_late_register(struct drm_plane *drm_plane)
 	struct sti_plane *plane = to_sti_plane(drm_plane);
 	struct sti_cursor *cursor = to_sti_cursor(plane);
 
-	return cursor_debugfs_init(cursor, drm_plane->dev->primary);
+	cursor_debugfs_init(cursor, drm_plane->dev->primary);
+
+	return 0;
 }
 
 static const struct drm_plane_funcs sti_cursor_plane_helpers_funcs = {
diff --git a/drivers/gpu/drm/sti/sti_drv.c b/drivers/gpu/drm/sti/sti_drv.c
index 50870d8cbb76..3f9db3e3f397 100644
--- a/drivers/gpu/drm/sti/sti_drv.c
+++ b/drivers/gpu/drm/sti/sti_drv.c
@@ -92,24 +92,16 @@ static struct drm_info_list sti_drm_dbg_list[] = {
 	{"fps_get", sti_drm_fps_dbg_show, 0},
 };
 
-static int sti_drm_dbg_init(struct drm_minor *minor)
+static void sti_drm_dbg_init(struct drm_minor *minor)
 {
-	int ret;
-
-	ret = drm_debugfs_create_files(sti_drm_dbg_list,
-				       ARRAY_SIZE(sti_drm_dbg_list),
-				       minor->debugfs_root, minor);
-	if (ret)
-		goto err;
+	drm_debugfs_create_files(sti_drm_dbg_list,
+				 ARRAY_SIZE(sti_drm_dbg_list),
+				 minor->debugfs_root, minor);
 
 	debugfs_create_file("fps_show", S_IRUGO | S_IWUSR, minor->debugfs_root,
 			    minor->dev, &sti_drm_fps_fops);
 
 	DRM_INFO("%s: debugfs installed\n", DRIVER_NAME);
-	return 0;
-err:
-	DRM_ERROR("%s: cannot install debugfs\n", DRIVER_NAME);
-	return ret;
 }
 
 static const struct drm_mode_config_funcs sti_mode_config_funcs = {
diff --git a/drivers/gpu/drm/sti/sti_dvo.c b/drivers/gpu/drm/sti/sti_dvo.c
index 3d04bfca21a0..de4af7735c46 100644
--- a/drivers/gpu/drm/sti/sti_dvo.c
+++ b/drivers/gpu/drm/sti/sti_dvo.c
@@ -196,16 +196,16 @@ static struct drm_info_list dvo_debugfs_files[] = {
 	{ "dvo", dvo_dbg_show, 0, NULL },
 };
 
-static int dvo_debugfs_init(struct sti_dvo *dvo, struct drm_minor *minor)
+static void dvo_debugfs_init(struct sti_dvo *dvo, struct drm_minor *minor)
 {
 	unsigned int i;
 
 	for (i = 0; i < ARRAY_SIZE(dvo_debugfs_files); i++)
 		dvo_debugfs_files[i].data = dvo;
 
-	return drm_debugfs_create_files(dvo_debugfs_files,
-					ARRAY_SIZE(dvo_debugfs_files),
-					minor->debugfs_root, minor);
+	drm_debugfs_create_files(dvo_debugfs_files,
+				 ARRAY_SIZE(dvo_debugfs_files),
+				 minor->debugfs_root, minor);
 }
 
 static void sti_dvo_disable(struct drm_bridge *bridge)
@@ -405,10 +405,7 @@ static int sti_dvo_late_register(struct drm_connector *connector)
 		= to_sti_dvo_connector(connector);
 	struct sti_dvo *dvo = dvo_connector->dvo;
 
-	if (dvo_debugfs_init(dvo, dvo->drm_dev->primary)) {
-		DRM_ERROR("DVO debugfs setup failed\n");
-		return -EINVAL;
-	}
+	dvo_debugfs_init(dvo, dvo->drm_dev->primary);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/sti/sti_gdp.c b/drivers/gpu/drm/sti/sti_gdp.c
index 11595c748844..2d5a2b5b78b8 100644
--- a/drivers/gpu/drm/sti/sti_gdp.c
+++ b/drivers/gpu/drm/sti/sti_gdp.c
@@ -343,9 +343,10 @@ static int gdp_debugfs_init(struct sti_gdp *gdp, struct drm_minor *minor)
 	for (i = 0; i < nb_files; i++)
 		gdp_debugfs_files[i].data = gdp;
 
-	return drm_debugfs_create_files(gdp_debugfs_files,
-					nb_files,
-					minor->debugfs_root, minor);
+	drm_debugfs_create_files(gdp_debugfs_files,
+				 nb_files,
+				 minor->debugfs_root, minor);
+	return 0;
 }
 
 static int sti_gdp_fourcc2format(int fourcc)
diff --git a/drivers/gpu/drm/sti/sti_hda.c b/drivers/gpu/drm/sti/sti_hda.c
index f3f28d79b0e4..a1ec891eaf3a 100644
--- a/drivers/gpu/drm/sti/sti_hda.c
+++ b/drivers/gpu/drm/sti/sti_hda.c
@@ -367,16 +367,16 @@ static struct drm_info_list hda_debugfs_files[] = {
 	{ "hda", hda_dbg_show, 0, NULL },
 };
 
-static int hda_debugfs_init(struct sti_hda *hda, struct drm_minor *minor)
+static void hda_debugfs_init(struct sti_hda *hda, struct drm_minor *minor)
 {
 	unsigned int i;
 
 	for (i = 0; i < ARRAY_SIZE(hda_debugfs_files); i++)
 		hda_debugfs_files[i].data = hda;
 
-	return drm_debugfs_create_files(hda_debugfs_files,
-					ARRAY_SIZE(hda_debugfs_files),
-					minor->debugfs_root, minor);
+	drm_debugfs_create_files(hda_debugfs_files,
+				 ARRAY_SIZE(hda_debugfs_files),
+				 minor->debugfs_root, minor);
 }
 
 /**
@@ -643,10 +643,7 @@ static int sti_hda_late_register(struct drm_connector *connector)
 		= to_sti_hda_connector(connector);
 	struct sti_hda *hda = hda_connector->hda;
 
-	if (hda_debugfs_init(hda, hda->drm_dev->primary)) {
-		DRM_ERROR("HDA debugfs setup failed\n");
-		return -EINVAL;
-	}
+	hda_debugfs_init(hda, hda->drm_dev->primary);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c
index 18eaf786ffa4..5b15c4974e6b 100644
--- a/drivers/gpu/drm/sti/sti_hdmi.c
+++ b/drivers/gpu/drm/sti/sti_hdmi.c
@@ -727,16 +727,16 @@ static struct drm_info_list hdmi_debugfs_files[] = {
 	{ "hdmi", hdmi_dbg_show, 0, NULL },
 };
 
-static int hdmi_debugfs_init(struct sti_hdmi *hdmi, struct drm_minor *minor)
+static void hdmi_debugfs_init(struct sti_hdmi *hdmi, struct drm_minor *minor)
 {
 	unsigned int i;
 
 	for (i = 0; i < ARRAY_SIZE(hdmi_debugfs_files); i++)
 		hdmi_debugfs_files[i].data = hdmi;
 
-	return drm_debugfs_create_files(hdmi_debugfs_files,
-					ARRAY_SIZE(hdmi_debugfs_files),
-					minor->debugfs_root, minor);
+	drm_debugfs_create_files(hdmi_debugfs_files,
+				 ARRAY_SIZE(hdmi_debugfs_files),
+				 minor->debugfs_root, minor);
 }
 
 static void sti_hdmi_disable(struct drm_bridge *bridge)
@@ -1113,10 +1113,7 @@ static int sti_hdmi_late_register(struct drm_connector *connector)
 		= to_sti_hdmi_connector(connector);
 	struct sti_hdmi *hdmi = hdmi_connector->hdmi;
 
-	if (hdmi_debugfs_init(hdmi, hdmi->drm_dev->primary)) {
-		DRM_ERROR("HDMI debugfs setup failed\n");
-		return -EINVAL;
-	}
+	hdmi_debugfs_init(hdmi, hdmi->drm_dev->primary);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/sti/sti_hqvdp.c b/drivers/gpu/drm/sti/sti_hqvdp.c
index 1015abe0ce08..5a4e12194a77 100644
--- a/drivers/gpu/drm/sti/sti_hqvdp.c
+++ b/drivers/gpu/drm/sti/sti_hqvdp.c
@@ -639,16 +639,16 @@ static struct drm_info_list hqvdp_debugfs_files[] = {
 	{ "hqvdp", hqvdp_dbg_show, 0, NULL },
 };
 
-static int hqvdp_debugfs_init(struct sti_hqvdp *hqvdp, struct drm_minor *minor)
+static void hqvdp_debugfs_init(struct sti_hqvdp *hqvdp, struct drm_minor *minor)
 {
 	unsigned int i;
 
 	for (i = 0; i < ARRAY_SIZE(hqvdp_debugfs_files); i++)
 		hqvdp_debugfs_files[i].data = hqvdp;
 
-	return drm_debugfs_create_files(hqvdp_debugfs_files,
-					ARRAY_SIZE(hqvdp_debugfs_files),
-					minor->debugfs_root, minor);
+	drm_debugfs_create_files(hqvdp_debugfs_files,
+				 ARRAY_SIZE(hqvdp_debugfs_files),
+				 minor->debugfs_root, minor);
 }
 
 /**
@@ -1274,7 +1274,9 @@ static int sti_hqvdp_late_register(struct drm_plane *drm_plane)
 	struct sti_plane *plane = to_sti_plane(drm_plane);
 	struct sti_hqvdp *hqvdp = to_sti_hqvdp(plane);
 
-	return hqvdp_debugfs_init(hqvdp, drm_plane->dev->primary);
+	hqvdp_debugfs_init(hqvdp, drm_plane->dev->primary);
+
+	return 0;
 }
 
 static const struct drm_plane_funcs sti_hqvdp_plane_helpers_funcs = {
diff --git a/drivers/gpu/drm/sti/sti_mixer.c b/drivers/gpu/drm/sti/sti_mixer.c
index c3a3e1e5fc8a..7e5f14646625 100644
--- a/drivers/gpu/drm/sti/sti_mixer.c
+++ b/drivers/gpu/drm/sti/sti_mixer.c
@@ -178,7 +178,7 @@ static struct drm_info_list mixer1_debugfs_files[] = {
 	{ "mixer_aux", mixer_dbg_show, 0, NULL },
 };
 
-int sti_mixer_debugfs_init(struct sti_mixer *mixer, struct drm_minor *minor)
+void sti_mixer_debugfs_init(struct sti_mixer *mixer, struct drm_minor *minor)
 {
 	unsigned int i;
 	struct drm_info_list *mixer_debugfs_files;
@@ -194,15 +194,15 @@ int sti_mixer_debugfs_init(struct sti_mixer *mixer, struct drm_minor *minor)
 		nb_files = ARRAY_SIZE(mixer1_debugfs_files);
 		break;
 	default:
-		return -EINVAL;
+		return;
 	}
 
 	for (i = 0; i < nb_files; i++)
 		mixer_debugfs_files[i].data = mixer;
 
-	return drm_debugfs_create_files(mixer_debugfs_files,
-					nb_files,
-					minor->debugfs_root, minor);
+	drm_debugfs_create_files(mixer_debugfs_files,
+				 nb_files,
+				 minor->debugfs_root, minor);
 }
 
 void sti_mixer_set_background_status(struct sti_mixer *mixer, bool enable)
diff --git a/drivers/gpu/drm/sti/sti_mixer.h b/drivers/gpu/drm/sti/sti_mixer.h
index d9544246913a..ab06beb7b258 100644
--- a/drivers/gpu/drm/sti/sti_mixer.h
+++ b/drivers/gpu/drm/sti/sti_mixer.h
@@ -58,7 +58,7 @@ int sti_mixer_active_video_area(struct sti_mixer *mixer,
 
 void sti_mixer_set_background_status(struct sti_mixer *mixer, bool enable);
 
-int sti_mixer_debugfs_init(struct sti_mixer *mixer, struct drm_minor *minor);
+void sti_mixer_debugfs_init(struct sti_mixer *mixer, struct drm_minor *minor);
 
 /* depth in Cross-bar control = z order */
 #define GAM_MIXER_NB_DEPTH_LEVEL 6
diff --git a/drivers/gpu/drm/sti/sti_tvout.c b/drivers/gpu/drm/sti/sti_tvout.c
index c36a8da373cb..df3817f0fd30 100644
--- a/drivers/gpu/drm/sti/sti_tvout.c
+++ b/drivers/gpu/drm/sti/sti_tvout.c
@@ -570,16 +570,16 @@ static struct drm_info_list tvout_debugfs_files[] = {
 	{ "tvout", tvout_dbg_show, 0, NULL },
 };
 
-static int tvout_debugfs_init(struct sti_tvout *tvout, struct drm_minor *minor)
+static void tvout_debugfs_init(struct sti_tvout *tvout, struct drm_minor *minor)
 {
 	unsigned int i;
 
 	for (i = 0; i < ARRAY_SIZE(tvout_debugfs_files); i++)
 		tvout_debugfs_files[i].data = tvout;
 
-	return drm_debugfs_create_files(tvout_debugfs_files,
-					ARRAY_SIZE(tvout_debugfs_files),
-					minor->debugfs_root, minor);
+	drm_debugfs_create_files(tvout_debugfs_files,
+				 ARRAY_SIZE(tvout_debugfs_files),
+				 minor->debugfs_root, minor);
 }
 
 static void sti_tvout_encoder_dpms(struct drm_encoder *encoder, int mode)
@@ -603,14 +603,11 @@ static void sti_tvout_encoder_destroy(struct drm_encoder *encoder)
 static int sti_tvout_late_register(struct drm_encoder *encoder)
 {
 	struct sti_tvout *tvout = to_sti_tvout(encoder);
-	int ret;
 
 	if (tvout->debugfs_registered)
 		return 0;
 
-	ret = tvout_debugfs_init(tvout, encoder->dev->primary);
-	if (ret)
-		return ret;
+	tvout_debugfs_init(tvout, encoder->dev->primary);
 
 	tvout->debugfs_registered = true;
 	return 0;
diff --git a/drivers/gpu/drm/sti/sti_vid.c b/drivers/gpu/drm/sti/sti_vid.c
index 2d4230410464..2d818397918d 100644
--- a/drivers/gpu/drm/sti/sti_vid.c
+++ b/drivers/gpu/drm/sti/sti_vid.c
@@ -124,16 +124,16 @@ static struct drm_info_list vid_debugfs_files[] = {
 	{ "vid", vid_dbg_show, 0, NULL },
 };
 
-int vid_debugfs_init(struct sti_vid *vid, struct drm_minor *minor)
+void vid_debugfs_init(struct sti_vid *vid, struct drm_minor *minor)
 {
 	unsigned int i;
 
 	for (i = 0; i < ARRAY_SIZE(vid_debugfs_files); i++)
 		vid_debugfs_files[i].data = vid;
 
-	return drm_debugfs_create_files(vid_debugfs_files,
-					ARRAY_SIZE(vid_debugfs_files),
-					minor->debugfs_root, minor);
+	drm_debugfs_create_files(vid_debugfs_files,
+				 ARRAY_SIZE(vid_debugfs_files),
+				 minor->debugfs_root, minor);
 }
 
 void sti_vid_commit(struct sti_vid *vid,
diff --git a/drivers/gpu/drm/sti/sti_vid.h b/drivers/gpu/drm/sti/sti_vid.h
index 9dbd78461de1..991849ba50b5 100644
--- a/drivers/gpu/drm/sti/sti_vid.h
+++ b/drivers/gpu/drm/sti/sti_vid.h
@@ -26,6 +26,6 @@ void sti_vid_disable(struct sti_vid *vid);
 struct sti_vid *sti_vid_create(struct device *dev, struct drm_device *drm_dev,
 			       int id, void __iomem *baseaddr);
 
-int vid_debugfs_init(struct sti_vid *vid, struct drm_minor *minor);
+void vid_debugfs_init(struct sti_vid *vid, struct drm_minor *minor);
 
 #endif
diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c
index ea9fcbdc68b3..0f85dd86cafa 100644
--- a/drivers/gpu/drm/stm/drv.c
+++ b/drivers/gpu/drm/stm/drv.c
@@ -88,7 +88,9 @@ static int drv_load(struct drm_device *ddev)
 
 	ddev->dev_private = (void *)ldev;
 
-	drm_mode_config_init(ddev);
+	ret = drmm_mode_config_init(ddev);
+	if (ret)
+		return ret;
 
 	/*
 	 * set max width and height as default value.
@@ -103,7 +105,7 @@ static int drv_load(struct drm_device *ddev)
 
 	ret = ltdc_load(ddev);
 	if (ret)
-		goto err;
+		return ret;
 
 	drm_mode_config_reset(ddev);
 	drm_kms_helper_poll_init(ddev);
@@ -111,9 +113,6 @@ static int drv_load(struct drm_device *ddev)
 	platform_set_drvdata(pdev, ddev);
 
 	return 0;
-err:
-	drm_mode_config_cleanup(ddev);
-	return ret;
 }
 
 static void drv_unload(struct drm_device *ddev)
@@ -122,7 +121,6 @@ static void drv_unload(struct drm_device *ddev)
 
 	drm_kms_helper_poll_fini(ddev);
 	ltdc_unload(ddev);
-	drm_mode_config_cleanup(ddev);
 }
 
 static __maybe_unused int drv_suspend(struct device *dev)
diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
index 68d4644ac2dc..e324d7db7b7d 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
@@ -22,6 +22,7 @@
 #include <drm/drm_panel.h>
 #include <drm/drm_print.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "sun4i_backend.h"
 #include "sun4i_crtc.h"
@@ -204,10 +205,6 @@ static const struct drm_encoder_helper_funcs sun4i_hdmi_helper_funcs = {
 	.mode_valid	= sun4i_hdmi_mode_valid,
 };
 
-static const struct drm_encoder_funcs sun4i_hdmi_funcs = {
-	.destroy	= drm_encoder_cleanup,
-};
-
 static int sun4i_hdmi_get_modes(struct drm_connector *connector)
 {
 	struct sun4i_hdmi *hdmi = drm_connector_to_sun4i_hdmi(connector);
@@ -611,11 +608,8 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master,
 
 	drm_encoder_helper_add(&hdmi->encoder,
 			       &sun4i_hdmi_helper_funcs);
-	ret = drm_encoder_init(drm,
-			       &hdmi->encoder,
-			       &sun4i_hdmi_funcs,
-			       DRM_MODE_ENCODER_TMDS,
-			       NULL);
+	ret = drm_simple_encoder_init(drm, &hdmi->encoder,
+				      DRM_MODE_ENCODER_TMDS);
 	if (ret) {
 		dev_err(dev, "Couldn't initialise the HDMI encoder\n");
 		goto err_put_ddc_i2c;
diff --git a/drivers/gpu/drm/sun4i/sun4i_lvds.c b/drivers/gpu/drm/sun4i/sun4i_lvds.c
index 26e5c7ceb8ff..ffda3184aa12 100644
--- a/drivers/gpu/drm/sun4i/sun4i_lvds.c
+++ b/drivers/gpu/drm/sun4i/sun4i_lvds.c
@@ -12,6 +12,7 @@
 #include <drm/drm_panel.h>
 #include <drm/drm_print.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "sun4i_crtc.h"
 #include "sun4i_tcon.h"
@@ -96,10 +97,6 @@ static const struct drm_encoder_helper_funcs sun4i_lvds_enc_helper_funcs = {
 	.enable		= sun4i_lvds_encoder_enable,
 };
 
-static const struct drm_encoder_funcs sun4i_lvds_enc_funcs = {
-	.destroy	= drm_encoder_cleanup,
-};
-
 int sun4i_lvds_init(struct drm_device *drm, struct sun4i_tcon *tcon)
 {
 	struct drm_encoder *encoder;
@@ -121,11 +118,8 @@ int sun4i_lvds_init(struct drm_device *drm, struct sun4i_tcon *tcon)
 
 	drm_encoder_helper_add(&lvds->encoder,
 			       &sun4i_lvds_enc_helper_funcs);
-	ret = drm_encoder_init(drm,
-			       &lvds->encoder,
-			       &sun4i_lvds_enc_funcs,
-			       DRM_MODE_ENCODER_LVDS,
-			       NULL);
+	ret = drm_simple_encoder_init(drm, &lvds->encoder,
+				      DRM_MODE_ENCODER_LVDS);
 	if (ret) {
 		dev_err(drm->dev, "Couldn't initialise the lvds encoder\n");
 		goto err_out;
diff --git a/drivers/gpu/drm/sun4i/sun4i_rgb.c b/drivers/gpu/drm/sun4i/sun4i_rgb.c
index 3b23d5be3cf3..5a7d43939ae6 100644
--- a/drivers/gpu/drm/sun4i/sun4i_rgb.c
+++ b/drivers/gpu/drm/sun4i/sun4i_rgb.c
@@ -14,6 +14,7 @@
 #include <drm/drm_panel.h>
 #include <drm/drm_print.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "sun4i_crtc.h"
 #include "sun4i_tcon.h"
@@ -188,15 +189,6 @@ static struct drm_encoder_helper_funcs sun4i_rgb_enc_helper_funcs = {
 	.mode_valid	= sun4i_rgb_mode_valid,
 };
 
-static void sun4i_rgb_enc_destroy(struct drm_encoder *encoder)
-{
-	drm_encoder_cleanup(encoder);
-}
-
-static struct drm_encoder_funcs sun4i_rgb_enc_funcs = {
-	.destroy	= sun4i_rgb_enc_destroy,
-};
-
 int sun4i_rgb_init(struct drm_device *drm, struct sun4i_tcon *tcon)
 {
 	struct drm_encoder *encoder;
@@ -218,11 +210,8 @@ int sun4i_rgb_init(struct drm_device *drm, struct sun4i_tcon *tcon)
 
 	drm_encoder_helper_add(&rgb->encoder,
 			       &sun4i_rgb_enc_helper_funcs);
-	ret = drm_encoder_init(drm,
-			       &rgb->encoder,
-			       &sun4i_rgb_enc_funcs,
-			       DRM_MODE_ENCODER_NONE,
-			       NULL);
+	ret = drm_simple_encoder_init(drm, &rgb->encoder,
+				      DRM_MODE_ENCODER_NONE);
 	if (ret) {
 		dev_err(drm->dev, "Couldn't initialise the rgb encoder\n");
 		goto err_out;
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index 624437b27cdc..359b56e43b83 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -812,10 +812,8 @@ static int sun4i_tcon_init_irq(struct device *dev,
 	int irq, ret;
 
 	irq = platform_get_irq(pdev, 0);
-	if (irq < 0) {
-		dev_err(dev, "Couldn't retrieve the TCON interrupt\n");
+	if (irq < 0)
 		return irq;
-	}
 
 	ret = devm_request_irq(dev, irq, sun4i_tcon_handler, 0,
 			       dev_name(dev), tcon);
diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c b/drivers/gpu/drm/sun4i/sun4i_tv.c
index 39c15282e448..63f4428ac3bf 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tv.c
@@ -19,6 +19,7 @@
 #include <drm/drm_panel.h>
 #include <drm/drm_print.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "sun4i_crtc.h"
 #include "sun4i_drv.h"
@@ -473,15 +474,6 @@ static struct drm_encoder_helper_funcs sun4i_tv_helper_funcs = {
 	.mode_set	= sun4i_tv_mode_set,
 };
 
-static void sun4i_tv_destroy(struct drm_encoder *encoder)
-{
-	drm_encoder_cleanup(encoder);
-}
-
-static struct drm_encoder_funcs sun4i_tv_funcs = {
-	.destroy	= sun4i_tv_destroy,
-};
-
 static int sun4i_tv_comp_get_modes(struct drm_connector *connector)
 {
 	int i;
@@ -592,11 +584,8 @@ static int sun4i_tv_bind(struct device *dev, struct device *master,
 
 	drm_encoder_helper_add(&tv->encoder,
 			       &sun4i_tv_helper_funcs);
-	ret = drm_encoder_init(drm,
-			       &tv->encoder,
-			       &sun4i_tv_funcs,
-			       DRM_MODE_ENCODER_TVDAC,
-			       NULL);
+	ret = drm_simple_encoder_init(drm, &tv->encoder,
+				      DRM_MODE_ENCODER_TVDAC);
 	if (ret) {
 		dev_err(dev, "Couldn't initialise the TV encoder\n");
 		goto err_disable_clk;
diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
index 059939789730..f6c67dd87a05 100644
--- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
+++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
@@ -24,6 +24,7 @@
 #include <drm/drm_panel.h>
 #include <drm/drm_print.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "sun4i_crtc.h"
 #include "sun4i_tcon.h"
@@ -846,10 +847,6 @@ static const struct drm_encoder_helper_funcs sun6i_dsi_enc_helper_funcs = {
 	.enable		= sun6i_dsi_encoder_enable,
 };
 
-static const struct drm_encoder_funcs sun6i_dsi_enc_funcs = {
-	.destroy	= drm_encoder_cleanup,
-};
-
 static u32 sun6i_dsi_dcs_build_pkt_hdr(struct sun6i_dsi *dsi,
 				       const struct mipi_dsi_msg *msg)
 {
@@ -1062,11 +1059,8 @@ static int sun6i_dsi_bind(struct device *dev, struct device *master,
 
 	drm_encoder_helper_add(&dsi->encoder,
 			       &sun6i_dsi_enc_helper_funcs);
-	ret = drm_encoder_init(drm,
-			       &dsi->encoder,
-			       &sun6i_dsi_enc_funcs,
-			       DRM_MODE_ENCODER_DSI,
-			       NULL);
+	ret = drm_simple_encoder_init(drm, &dsi->encoder,
+				      DRM_MODE_ENCODER_DSI);
 	if (ret) {
 		dev_err(dsi->dev, "Couldn't initialise the DSI encoder\n");
 		return ret;
diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
index e8a317d5ba19..972682bb8000 100644
--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
@@ -10,6 +10,7 @@
 
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_of.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "sun8i_dw_hdmi.h"
 #include "sun8i_tcon_top.h"
@@ -29,10 +30,6 @@ sun8i_dw_hdmi_encoder_helper_funcs = {
 	.mode_set = sun8i_dw_hdmi_encoder_mode_set,
 };
 
-static const struct drm_encoder_funcs sun8i_dw_hdmi_encoder_funcs = {
-	.destroy = drm_encoder_cleanup,
-};
-
 static enum drm_mode_status
 sun8i_dw_hdmi_mode_valid_a83t(struct drm_connector *connector,
 			      const struct drm_display_mode *mode)
@@ -220,8 +217,7 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master,
 	}
 
 	drm_encoder_helper_add(encoder, &sun8i_dw_hdmi_encoder_helper_funcs);
-	drm_encoder_init(drm, encoder, &sun8i_dw_hdmi_encoder_funcs,
-			 DRM_MODE_ENCODER_TMDS, NULL);
+	drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
 
 	sun8i_hdmi_phy_init(hdmi->phy);
 
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c
index 4a64f7ae437a..56cc037fd312 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
@@ -27,314 +27,225 @@
 #include "sun8i_vi_layer.h"
 #include "sunxi_engine.h"
 
+struct de2_fmt_info {
+	u32	drm_fmt;
+	u32	de2_fmt;
+};
+
 static const struct de2_fmt_info de2_formats[] = {
 	{
 		.drm_fmt = DRM_FORMAT_ARGB8888,
 		.de2_fmt = SUN8I_MIXER_FBFMT_ARGB8888,
-		.rgb = true,
-		.csc = SUN8I_CSC_MODE_OFF,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_ABGR8888,
 		.de2_fmt = SUN8I_MIXER_FBFMT_ABGR8888,
-		.rgb = true,
-		.csc = SUN8I_CSC_MODE_OFF,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_RGBA8888,
 		.de2_fmt = SUN8I_MIXER_FBFMT_RGBA8888,
-		.rgb = true,
-		.csc = SUN8I_CSC_MODE_OFF,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_BGRA8888,
 		.de2_fmt = SUN8I_MIXER_FBFMT_BGRA8888,
-		.rgb = true,
-		.csc = SUN8I_CSC_MODE_OFF,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_XRGB8888,
 		.de2_fmt = SUN8I_MIXER_FBFMT_XRGB8888,
-		.rgb = true,
-		.csc = SUN8I_CSC_MODE_OFF,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_XBGR8888,
 		.de2_fmt = SUN8I_MIXER_FBFMT_XBGR8888,
-		.rgb = true,
-		.csc = SUN8I_CSC_MODE_OFF,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_RGBX8888,
 		.de2_fmt = SUN8I_MIXER_FBFMT_RGBX8888,
-		.rgb = true,
-		.csc = SUN8I_CSC_MODE_OFF,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_BGRX8888,
 		.de2_fmt = SUN8I_MIXER_FBFMT_BGRX8888,
-		.rgb = true,
-		.csc = SUN8I_CSC_MODE_OFF,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_RGB888,
 		.de2_fmt = SUN8I_MIXER_FBFMT_RGB888,
-		.rgb = true,
-		.csc = SUN8I_CSC_MODE_OFF,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_BGR888,
 		.de2_fmt = SUN8I_MIXER_FBFMT_BGR888,
-		.rgb = true,
-		.csc = SUN8I_CSC_MODE_OFF,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_RGB565,
 		.de2_fmt = SUN8I_MIXER_FBFMT_RGB565,
-		.rgb = true,
-		.csc = SUN8I_CSC_MODE_OFF,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_BGR565,
 		.de2_fmt = SUN8I_MIXER_FBFMT_BGR565,
-		.rgb = true,
-		.csc = SUN8I_CSC_MODE_OFF,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_ARGB4444,
 		.de2_fmt = SUN8I_MIXER_FBFMT_ARGB4444,
-		.rgb = true,
-		.csc = SUN8I_CSC_MODE_OFF,
 	},
 	{
 		/* for DE2 VI layer which ignores alpha */
 		.drm_fmt = DRM_FORMAT_XRGB4444,
 		.de2_fmt = SUN8I_MIXER_FBFMT_ARGB4444,
-		.rgb = true,
-		.csc = SUN8I_CSC_MODE_OFF,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_ABGR4444,
 		.de2_fmt = SUN8I_MIXER_FBFMT_ABGR4444,
-		.rgb = true,
-		.csc = SUN8I_CSC_MODE_OFF,
 	},
 	{
 		/* for DE2 VI layer which ignores alpha */
 		.drm_fmt = DRM_FORMAT_XBGR4444,
 		.de2_fmt = SUN8I_MIXER_FBFMT_ABGR4444,
-		.rgb = true,
-		.csc = SUN8I_CSC_MODE_OFF,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_RGBA4444,
 		.de2_fmt = SUN8I_MIXER_FBFMT_RGBA4444,
-		.rgb = true,
-		.csc = SUN8I_CSC_MODE_OFF,
 	},
 	{
 		/* for DE2 VI layer which ignores alpha */
 		.drm_fmt = DRM_FORMAT_RGBX4444,
 		.de2_fmt = SUN8I_MIXER_FBFMT_RGBA4444,
-		.rgb = true,
-		.csc = SUN8I_CSC_MODE_OFF,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_BGRA4444,
 		.de2_fmt = SUN8I_MIXER_FBFMT_BGRA4444,
-		.rgb = true,
-		.csc = SUN8I_CSC_MODE_OFF,
 	},
 	{
 		/* for DE2 VI layer which ignores alpha */
 		.drm_fmt = DRM_FORMAT_BGRX4444,
 		.de2_fmt = SUN8I_MIXER_FBFMT_BGRA4444,
-		.rgb = true,
-		.csc = SUN8I_CSC_MODE_OFF,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_ARGB1555,
 		.de2_fmt = SUN8I_MIXER_FBFMT_ARGB1555,
-		.rgb = true,
-		.csc = SUN8I_CSC_MODE_OFF,
 	},
 	{
 		/* for DE2 VI layer which ignores alpha */
 		.drm_fmt = DRM_FORMAT_XRGB1555,
 		.de2_fmt = SUN8I_MIXER_FBFMT_ARGB1555,
-		.rgb = true,
-		.csc = SUN8I_CSC_MODE_OFF,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_ABGR1555,
 		.de2_fmt = SUN8I_MIXER_FBFMT_ABGR1555,
-		.rgb = true,
-		.csc = SUN8I_CSC_MODE_OFF,
 	},
 	{
 		/* for DE2 VI layer which ignores alpha */
 		.drm_fmt = DRM_FORMAT_XBGR1555,
 		.de2_fmt = SUN8I_MIXER_FBFMT_ABGR1555,
-		.rgb = true,
-		.csc = SUN8I_CSC_MODE_OFF,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_RGBA5551,
 		.de2_fmt = SUN8I_MIXER_FBFMT_RGBA5551,
-		.rgb = true,
-		.csc = SUN8I_CSC_MODE_OFF,
 	},
 	{
 		/* for DE2 VI layer which ignores alpha */
 		.drm_fmt = DRM_FORMAT_RGBX5551,
 		.de2_fmt = SUN8I_MIXER_FBFMT_RGBA5551,
-		.rgb = true,
-		.csc = SUN8I_CSC_MODE_OFF,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_BGRA5551,
 		.de2_fmt = SUN8I_MIXER_FBFMT_BGRA5551,
-		.rgb = true,
-		.csc = SUN8I_CSC_MODE_OFF,
 	},
 	{
 		/* for DE2 VI layer which ignores alpha */
 		.drm_fmt = DRM_FORMAT_BGRX5551,
 		.de2_fmt = SUN8I_MIXER_FBFMT_BGRA5551,
-		.rgb = true,
-		.csc = SUN8I_CSC_MODE_OFF,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_ARGB2101010,
 		.de2_fmt = SUN8I_MIXER_FBFMT_ARGB2101010,
-		.rgb = true,
-		.csc = SUN8I_CSC_MODE_OFF,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_ABGR2101010,
 		.de2_fmt = SUN8I_MIXER_FBFMT_ABGR2101010,
-		.rgb = true,
-		.csc = SUN8I_CSC_MODE_OFF,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_RGBA1010102,
 		.de2_fmt = SUN8I_MIXER_FBFMT_RGBA1010102,
-		.rgb = true,
-		.csc = SUN8I_CSC_MODE_OFF,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_BGRA1010102,
 		.de2_fmt = SUN8I_MIXER_FBFMT_BGRA1010102,
-		.rgb = true,
-		.csc = SUN8I_CSC_MODE_OFF,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_UYVY,
 		.de2_fmt = SUN8I_MIXER_FBFMT_UYVY,
-		.rgb = false,
-		.csc = SUN8I_CSC_MODE_YUV2RGB,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_VYUY,
 		.de2_fmt = SUN8I_MIXER_FBFMT_VYUY,
-		.rgb = false,
-		.csc = SUN8I_CSC_MODE_YUV2RGB,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_YUYV,
 		.de2_fmt = SUN8I_MIXER_FBFMT_YUYV,
-		.rgb = false,
-		.csc = SUN8I_CSC_MODE_YUV2RGB,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_YVYU,
 		.de2_fmt = SUN8I_MIXER_FBFMT_YVYU,
-		.rgb = false,
-		.csc = SUN8I_CSC_MODE_YUV2RGB,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_NV16,
 		.de2_fmt = SUN8I_MIXER_FBFMT_NV16,
-		.rgb = false,
-		.csc = SUN8I_CSC_MODE_YUV2RGB,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_NV61,
 		.de2_fmt = SUN8I_MIXER_FBFMT_NV61,
-		.rgb = false,
-		.csc = SUN8I_CSC_MODE_YUV2RGB,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_NV12,
 		.de2_fmt = SUN8I_MIXER_FBFMT_NV12,
-		.rgb = false,
-		.csc = SUN8I_CSC_MODE_YUV2RGB,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_NV21,
 		.de2_fmt = SUN8I_MIXER_FBFMT_NV21,
-		.rgb = false,
-		.csc = SUN8I_CSC_MODE_YUV2RGB,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_YUV422,
 		.de2_fmt = SUN8I_MIXER_FBFMT_YUV422,
-		.rgb = false,
-		.csc = SUN8I_CSC_MODE_YUV2RGB,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_YUV420,
 		.de2_fmt = SUN8I_MIXER_FBFMT_YUV420,
-		.rgb = false,
-		.csc = SUN8I_CSC_MODE_YUV2RGB,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_YUV411,
 		.de2_fmt = SUN8I_MIXER_FBFMT_YUV411,
-		.rgb = false,
-		.csc = SUN8I_CSC_MODE_YUV2RGB,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_YVU422,
 		.de2_fmt = SUN8I_MIXER_FBFMT_YUV422,
-		.rgb = false,
-		.csc = SUN8I_CSC_MODE_YVU2RGB,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_YVU420,
 		.de2_fmt = SUN8I_MIXER_FBFMT_YUV420,
-		.rgb = false,
-		.csc = SUN8I_CSC_MODE_YVU2RGB,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_YVU411,
 		.de2_fmt = SUN8I_MIXER_FBFMT_YUV411,
-		.rgb = false,
-		.csc = SUN8I_CSC_MODE_YVU2RGB,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_P010,
 		.de2_fmt = SUN8I_MIXER_FBFMT_P010_YUV,
-		.rgb = false,
-		.csc = SUN8I_CSC_MODE_YUV2RGB,
 	},
 	{
 		.drm_fmt = DRM_FORMAT_P210,
 		.de2_fmt = SUN8I_MIXER_FBFMT_P210_YUV,
-		.rgb = false,
-		.csc = SUN8I_CSC_MODE_YUV2RGB,
 	},
 };
 
-const struct de2_fmt_info *sun8i_mixer_format_info(u32 format)
+int sun8i_mixer_drm_format_to_hw(u32 format, u32 *hw_format)
 {
 	unsigned int i;
 
 	for (i = 0; i < ARRAY_SIZE(de2_formats); ++i)
-		if (de2_formats[i].drm_fmt == format)
-			return &de2_formats[i];
+		if (de2_formats[i].drm_fmt == format) {
+			*hw_format = de2_formats[i].de2_fmt;
+			return 0;
+		}
 
-	return NULL;
+	return -EINVAL;
 }
 
 static void sun8i_mixer_commit(struct sunxi_engine *engine)
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h
index 345b28b0a80a..7576b523fdbb 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
@@ -10,7 +10,6 @@
 #include <linux/regmap.h>
 #include <linux/reset.h>
 
-#include "sun8i_csc.h"
 #include "sunxi_engine.h"
 
 #define SUN8I_MIXER_SIZE(w, h)			(((h) - 1) << 16 | ((w) - 1))
@@ -144,13 +143,6 @@
 #define SUN50I_MIXER_CDC0_EN			0xd0000
 #define SUN50I_MIXER_CDC1_EN			0xd8000
 
-struct de2_fmt_info {
-	u32			drm_fmt;
-	u32			de2_fmt;
-	bool			rgb;
-	enum sun8i_csc_mode	csc;
-};
-
 /**
  * struct sun8i_mixer_cfg - mixer HW configuration
  * @vi_num: number of VI channels
@@ -210,5 +202,5 @@ sun8i_channel_base(struct sun8i_mixer *mixer, int channel)
 		return DE2_CH_BASE + channel * DE2_CH_SIZE;
 }
 
-const struct de2_fmt_info *sun8i_mixer_format_info(u32 format);
+int sun8i_mixer_drm_format_to_hw(u32 format, u32 *hw_format);
 #endif /* _SUN8I_MIXER_H_ */
diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
index c87fd842918e..54f937a7d5e7 100644
--- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
@@ -19,8 +19,8 @@
 #include <drm/drm_plane_helper.h>
 #include <drm/drm_probe_helper.h>
 
-#include "sun8i_ui_layer.h"
 #include "sun8i_mixer.h"
+#include "sun8i_ui_layer.h"
 #include "sun8i_ui_scaler.h"
 
 static void sun8i_ui_layer_enable(struct sun8i_mixer *mixer, int channel,
@@ -174,18 +174,20 @@ static int sun8i_ui_layer_update_formats(struct sun8i_mixer *mixer, int channel,
 					 int overlay, struct drm_plane *plane)
 {
 	struct drm_plane_state *state = plane->state;
-	const struct de2_fmt_info *fmt_info;
-	u32 val, ch_base;
+	const struct drm_format_info *fmt;
+	u32 val, ch_base, hw_fmt;
+	int ret;
 
 	ch_base = sun8i_channel_base(mixer, channel);
 
-	fmt_info = sun8i_mixer_format_info(state->fb->format->format);
-	if (!fmt_info || !fmt_info->rgb) {
+	fmt = state->fb->format;
+	ret = sun8i_mixer_drm_format_to_hw(fmt->format, &hw_fmt);
+	if (ret || fmt->is_yuv) {
 		DRM_DEBUG_DRIVER("Invalid format\n");
 		return -EINVAL;
 	}
 
-	val = fmt_info->de2_fmt << SUN8I_MIXER_CHAN_UI_LAYER_ATTR_FBFMT_OFFSET;
+	val = hw_fmt << SUN8I_MIXER_CHAN_UI_LAYER_ATTR_FBFMT_OFFSET;
 	regmap_update_bits(mixer->engine.regs,
 			   SUN8I_MIXER_CHAN_UI_LAYER_ATTR(ch_base, overlay),
 			   SUN8I_MIXER_CHAN_UI_LAYER_ATTR_FBFMT_MASK, val);
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
index b8398ca18b0f..22c8c5375d0d 100644
--- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
@@ -12,8 +12,9 @@
 #include <drm/drm_plane_helper.h>
 #include <drm/drm_probe_helper.h>
 
-#include "sun8i_vi_layer.h"
+#include "sun8i_csc.h"
 #include "sun8i_mixer.h"
+#include "sun8i_vi_layer.h"
 #include "sun8i_vi_scaler.h"
 
 static void sun8i_vi_layer_enable(struct sun8i_mixer *mixer, int channel,
@@ -210,28 +211,47 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel,
 	return 0;
 }
 
+static bool sun8i_vi_layer_get_csc_mode(const struct drm_format_info *format)
+{
+	if (!format->is_yuv)
+		return SUN8I_CSC_MODE_OFF;
+
+	switch (format->format) {
+	case DRM_FORMAT_YVU411:
+	case DRM_FORMAT_YVU420:
+	case DRM_FORMAT_YVU422:
+	case DRM_FORMAT_YVU444:
+		return SUN8I_CSC_MODE_YVU2RGB;
+	default:
+		return SUN8I_CSC_MODE_YUV2RGB;
+	}
+}
+
 static int sun8i_vi_layer_update_formats(struct sun8i_mixer *mixer, int channel,
 					 int overlay, struct drm_plane *plane)
 {
 	struct drm_plane_state *state = plane->state;
-	const struct de2_fmt_info *fmt_info;
-	u32 val, ch_base;
+	u32 val, ch_base, csc_mode, hw_fmt;
+	const struct drm_format_info *fmt;
+	int ret;
 
 	ch_base = sun8i_channel_base(mixer, channel);
 
-	fmt_info = sun8i_mixer_format_info(state->fb->format->format);
-	if (!fmt_info) {
+	fmt = state->fb->format;
+	ret = sun8i_mixer_drm_format_to_hw(fmt->format, &hw_fmt);
+	if (ret) {
 		DRM_DEBUG_DRIVER("Invalid format\n");
-		return -EINVAL;
+		return ret;
 	}
 
-	val = fmt_info->de2_fmt << SUN8I_MIXER_CHAN_VI_LAYER_ATTR_FBFMT_OFFSET;
+	val = hw_fmt << SUN8I_MIXER_CHAN_VI_LAYER_ATTR_FBFMT_OFFSET;
 	regmap_update_bits(mixer->engine.regs,
 			   SUN8I_MIXER_CHAN_VI_LAYER_ATTR(ch_base, overlay),
 			   SUN8I_MIXER_CHAN_VI_LAYER_ATTR_FBFMT_MASK, val);
 
-	if (fmt_info->csc != SUN8I_CSC_MODE_OFF) {
-		sun8i_csc_set_ccsc_coefficients(mixer, channel, fmt_info->csc,
+	csc_mode = sun8i_vi_layer_get_csc_mode(fmt);
+	if (csc_mode != SUN8I_CSC_MODE_OFF) {
+		sun8i_csc_set_ccsc_coefficients(mixer, channel, csc_mode,
 						state->color_encoding,
 						state->color_range);
 		sun8i_csc_enable_ccsc(mixer, channel, true);
@@ -239,7 +259,7 @@ static int sun8i_vi_layer_update_formats(struct sun8i_mixer *mixer, int channel,
 		sun8i_csc_enable_ccsc(mixer, channel, false);
 	}
 
-	if (fmt_info->rgb)
+	if (!fmt->is_yuv)
 		val = SUN8I_MIXER_CHAN_VI_LAYER_ATTR_RGB_MODE;
 	else
 		val = 0;
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index 1a7b08f35776..83f31c6e891c 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -1496,7 +1496,6 @@ static int tegra_dc_late_register(struct drm_crtc *crtc)
 	struct drm_minor *minor = crtc->dev->primary;
 	struct dentry *root;
 	struct tegra_dc *dc = to_tegra_dc(crtc);
-	int err;
 
 #ifdef CONFIG_DEBUG_FS
 	root = crtc->debugfs_entry;
@@ -1512,17 +1511,9 @@ static int tegra_dc_late_register(struct drm_crtc *crtc)
 	for (i = 0; i < count; i++)
 		dc->debugfs_files[i].data = dc;
 
-	err = drm_debugfs_create_files(dc->debugfs_files, count, root, minor);
-	if (err < 0)
-		goto free;
+	drm_debugfs_create_files(dc->debugfs_files, count, root, minor);
 
 	return 0;
-
-free:
-	kfree(dc->debugfs_files);
-	dc->debugfs_files = NULL;
-
-	return err;
 }
 
 static void tegra_dc_early_unregister(struct drm_crtc *crtc)
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index bd268028fb3d..d4f51b5c7ee5 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -839,11 +839,11 @@ static struct drm_info_list tegra_debugfs_list[] = {
 	{ "iova", tegra_debugfs_iova, 0 },
 };
 
-static int tegra_debugfs_init(struct drm_minor *minor)
+static void tegra_debugfs_init(struct drm_minor *minor)
 {
-	return drm_debugfs_create_files(tegra_debugfs_list,
-					ARRAY_SIZE(tegra_debugfs_list),
-					minor->debugfs_root, minor);
+	drm_debugfs_create_files(tegra_debugfs_list,
+				 ARRAY_SIZE(tegra_debugfs_list),
+				 minor->debugfs_root, minor);
 }
 #endif
 
diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h
index ed99b67deb29..804869799305 100644
--- a/drivers/gpu/drm/tegra/drm.h
+++ b/drivers/gpu/drm/tegra/drm.h
@@ -152,8 +152,6 @@ enum drm_connector_status
 tegra_output_connector_detect(struct drm_connector *connector, bool force);
 void tegra_output_connector_destroy(struct drm_connector *connector);
 
-void tegra_output_encoder_destroy(struct drm_encoder *encoder);
-
 /* from dpaux.c */
 struct drm_dp_aux *drm_dp_aux_find_by_of_node(struct device_node *np);
 enum drm_connector_status drm_dp_aux_detect(struct drm_dp_aux *aux);
diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c
index 88b9d64c77bf..38beab9ab4f8 100644
--- a/drivers/gpu/drm/tegra/dsi.c
+++ b/drivers/gpu/drm/tegra/dsi.c
@@ -22,6 +22,7 @@
 #include <drm/drm_file.h>
 #include <drm/drm_mipi_dsi.h>
 #include <drm/drm_panel.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "dc.h"
 #include "drm.h"
@@ -234,7 +235,6 @@ static int tegra_dsi_late_register(struct drm_connector *connector)
 	struct drm_minor *minor = connector->dev->primary;
 	struct dentry *root = connector->debugfs_entry;
 	struct tegra_dsi *dsi = to_dsi(output);
-	int err;
 
 	dsi->debugfs_files = kmemdup(debugfs_files, sizeof(debugfs_files),
 				     GFP_KERNEL);
@@ -244,17 +244,9 @@ static int tegra_dsi_late_register(struct drm_connector *connector)
 	for (i = 0; i < count; i++)
 		dsi->debugfs_files[i].data = dsi;
 
-	err = drm_debugfs_create_files(dsi->debugfs_files, count, root, minor);
-	if (err < 0)
-		goto free;
+	drm_debugfs_create_files(dsi->debugfs_files, count, root, minor);
 
 	return 0;
-
-free:
-	kfree(dsi->debugfs_files);
-	dsi->debugfs_files = NULL;
-
-	return err;
 }
 
 static void tegra_dsi_early_unregister(struct drm_connector *connector)
@@ -824,10 +816,6 @@ static const struct drm_connector_helper_funcs tegra_dsi_connector_helper_funcs
 	.mode_valid = tegra_dsi_connector_mode_valid,
 };
 
-static const struct drm_encoder_funcs tegra_dsi_encoder_funcs = {
-	.destroy = tegra_output_encoder_destroy,
-};
-
 static void tegra_dsi_unprepare(struct tegra_dsi *dsi)
 {
 	int err;
@@ -1058,9 +1046,8 @@ static int tegra_dsi_init(struct host1x_client *client)
 					 &tegra_dsi_connector_helper_funcs);
 		dsi->output.connector.dpms = DRM_MODE_DPMS_OFF;
 
-		drm_encoder_init(drm, &dsi->output.encoder,
-				 &tegra_dsi_encoder_funcs,
-				 DRM_MODE_ENCODER_DSI, NULL);
+		drm_simple_encoder_init(drm, &dsi->output.encoder,
+					DRM_MODE_ENCODER_DSI);
 		drm_encoder_helper_add(&dsi->output.encoder,
 				       &tegra_dsi_encoder_helper_funcs);
 
diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c
index 38252c0f068d..c4c8348df090 100644
--- a/drivers/gpu/drm/tegra/hdmi.c
+++ b/drivers/gpu/drm/tegra/hdmi.c
@@ -22,6 +22,7 @@
 #include <drm/drm_file.h>
 #include <drm/drm_fourcc.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "hda.h"
 #include "hdmi.h"
@@ -1064,7 +1065,6 @@ static int tegra_hdmi_late_register(struct drm_connector *connector)
 	struct drm_minor *minor = connector->dev->primary;
 	struct dentry *root = connector->debugfs_entry;
 	struct tegra_hdmi *hdmi = to_hdmi(output);
-	int err;
 
 	hdmi->debugfs_files = kmemdup(debugfs_files, sizeof(debugfs_files),
 				      GFP_KERNEL);
@@ -1074,17 +1074,9 @@ static int tegra_hdmi_late_register(struct drm_connector *connector)
 	for (i = 0; i < count; i++)
 		hdmi->debugfs_files[i].data = hdmi;
 
-	err = drm_debugfs_create_files(hdmi->debugfs_files, count, root, minor);
-	if (err < 0)
-		goto free;
+	drm_debugfs_create_files(hdmi->debugfs_files, count, root, minor);
 
 	return 0;
-
-free:
-	kfree(hdmi->debugfs_files);
-	hdmi->debugfs_files = NULL;
-
-	return err;
 }
 
 static void tegra_hdmi_early_unregister(struct drm_connector *connector)
@@ -1136,10 +1128,6 @@ tegra_hdmi_connector_helper_funcs = {
 	.mode_valid = tegra_hdmi_connector_mode_valid,
 };
 
-static const struct drm_encoder_funcs tegra_hdmi_encoder_funcs = {
-	.destroy = tegra_output_encoder_destroy,
-};
-
 static void tegra_hdmi_encoder_disable(struct drm_encoder *encoder)
 {
 	struct tegra_output *output = encoder_to_output(encoder);
@@ -1445,8 +1433,8 @@ static int tegra_hdmi_init(struct host1x_client *client)
 				 &tegra_hdmi_connector_helper_funcs);
 	hdmi->output.connector.dpms = DRM_MODE_DPMS_OFF;
 
-	drm_encoder_init(drm, &hdmi->output.encoder, &tegra_hdmi_encoder_funcs,
-			 DRM_MODE_ENCODER_TMDS, NULL);
+	drm_simple_encoder_init(drm, &hdmi->output.encoder,
+				DRM_MODE_ENCODER_TMDS);
 	drm_encoder_helper_add(&hdmi->output.encoder,
 			       &tegra_hdmi_encoder_helper_funcs);
 
diff --git a/drivers/gpu/drm/tegra/output.c b/drivers/gpu/drm/tegra/output.c
index a264259b97a2..e36e5e7c2f69 100644
--- a/drivers/gpu/drm/tegra/output.c
+++ b/drivers/gpu/drm/tegra/output.c
@@ -6,6 +6,7 @@
 
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_panel.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "drm.h"
 #include "dc.h"
@@ -79,11 +80,6 @@ void tegra_output_connector_destroy(struct drm_connector *connector)
 	drm_connector_cleanup(connector);
 }
 
-void tegra_output_encoder_destroy(struct drm_encoder *encoder)
-{
-	drm_encoder_cleanup(encoder);
-}
-
 static irqreturn_t hpd_irq(int irq, void *data)
 {
 	struct tegra_output *output = data;
diff --git a/drivers/gpu/drm/tegra/rgb.c b/drivers/gpu/drm/tegra/rgb.c
index 4be4dfd4a68a..0562a7eb793f 100644
--- a/drivers/gpu/drm/tegra/rgb.c
+++ b/drivers/gpu/drm/tegra/rgb.c
@@ -8,6 +8,7 @@
 
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_panel.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "drm.h"
 #include "dc.h"
@@ -110,10 +111,6 @@ static const struct drm_connector_helper_funcs tegra_rgb_connector_helper_funcs
 	.mode_valid = tegra_rgb_connector_mode_valid,
 };
 
-static const struct drm_encoder_funcs tegra_rgb_encoder_funcs = {
-	.destroy = tegra_output_encoder_destroy,
-};
-
 static void tegra_rgb_encoder_disable(struct drm_encoder *encoder)
 {
 	struct tegra_output *output = encoder_to_output(encoder);
@@ -281,8 +278,7 @@ int tegra_dc_rgb_init(struct drm_device *drm, struct tegra_dc *dc)
 				 &tegra_rgb_connector_helper_funcs);
 	output->connector.dpms = DRM_MODE_DPMS_OFF;
 
-	drm_encoder_init(drm, &output->encoder, &tegra_rgb_encoder_funcs,
-			 DRM_MODE_ENCODER_LVDS, NULL);
+	drm_simple_encoder_init(drm, &output->encoder, DRM_MODE_ENCODER_LVDS);
 	drm_encoder_helper_add(&output->encoder,
 			       &tegra_rgb_encoder_helper_funcs);
 
diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c
index 81226a4953c1..8495ea921b3c 100644
--- a/drivers/gpu/drm/tegra/sor.c
+++ b/drivers/gpu/drm/tegra/sor.c
@@ -23,6 +23,7 @@
 #include <drm/drm_file.h>
 #include <drm/drm_panel.h>
 #include <drm/drm_scdc_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "dc.h"
 #include "dp.h"
@@ -1687,7 +1688,6 @@ static int tegra_sor_late_register(struct drm_connector *connector)
 	struct drm_minor *minor = connector->dev->primary;
 	struct dentry *root = connector->debugfs_entry;
 	struct tegra_sor *sor = to_sor(output);
-	int err;
 
 	sor->debugfs_files = kmemdup(debugfs_files, sizeof(debugfs_files),
 				     GFP_KERNEL);
@@ -1697,17 +1697,9 @@ static int tegra_sor_late_register(struct drm_connector *connector)
 	for (i = 0; i < count; i++)
 		sor->debugfs_files[i].data = sor;
 
-	err = drm_debugfs_create_files(sor->debugfs_files, count, root, minor);
-	if (err < 0)
-		goto free;
+	drm_debugfs_create_files(sor->debugfs_files, count, root, minor);
 
 	return 0;
-
-free:
-	kfree(sor->debugfs_files);
-	sor->debugfs_files = NULL;
-
-	return err;
 }
 
 static void tegra_sor_early_unregister(struct drm_connector *connector)
@@ -1805,10 +1797,6 @@ static const struct drm_connector_helper_funcs tegra_sor_connector_helper_funcs
 	.mode_valid = tegra_sor_connector_mode_valid,
 };
 
-static const struct drm_encoder_funcs tegra_sor_encoder_funcs = {
-	.destroy = tegra_output_encoder_destroy,
-};
-
 static int
 tegra_sor_encoder_atomic_check(struct drm_encoder *encoder,
 			       struct drm_crtc_state *crtc_state,
@@ -3102,8 +3090,7 @@ static int tegra_sor_init(struct host1x_client *client)
 				 &tegra_sor_connector_helper_funcs);
 	sor->output.connector.dpms = DRM_MODE_DPMS_OFF;
 
-	drm_encoder_init(drm, &sor->output.encoder, &tegra_sor_encoder_funcs,
-			 encoder, NULL);
+	drm_simple_encoder_init(drm, &sor->output.encoder, encoder);
 	drm_encoder_helper_add(&sor->output.encoder, helpers);
 
 	drm_connector_attach_encoder(&sor->output.connector,
diff --git a/drivers/gpu/drm/tidss/tidss_drv.c b/drivers/gpu/drm/tidss/tidss_drv.c
index d95e4be2c7b9..ad449d104306 100644
--- a/drivers/gpu/drm/tidss/tidss_drv.c
+++ b/drivers/gpu/drm/tidss/tidss_drv.c
@@ -17,6 +17,7 @@
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/drm_irq.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_probe_helper.h>
 
 #include "tidss_dispc.h"
@@ -102,15 +103,7 @@ static const struct dev_pm_ops tidss_pm_ops = {
 
 static void tidss_release(struct drm_device *ddev)
 {
-	struct tidss_device *tidss = ddev->dev_private;
-
 	drm_kms_helper_poll_fini(ddev);
-
-	tidss_modeset_cleanup(tidss);
-
-	drm_dev_fini(ddev);
-
-	kfree(tidss);
 }
 
 DEFINE_DRM_GEM_CMA_FOPS(tidss_fops);
@@ -154,6 +147,7 @@ static int tidss_probe(struct platform_device *pdev)
 		kfree(ddev);
 		return ret;
 	}
+	drmm_add_final_kfree(ddev, tidss);
 
 	tidss->dev = dev;
 	tidss->feat = of_device_get_match_data(dev);
diff --git a/drivers/gpu/drm/tidss/tidss_encoder.c b/drivers/gpu/drm/tidss/tidss_encoder.c
index 83785b0a66a9..4c0558286f5e 100644
--- a/drivers/gpu/drm/tidss/tidss_encoder.c
+++ b/drivers/gpu/drm/tidss/tidss_encoder.c
@@ -8,8 +8,9 @@
 
 #include <drm/drm_crtc.h>
 #include <drm/drm_crtc_helper.h>
-#include <drm/drm_panel.h>
 #include <drm/drm_of.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "tidss_crtc.h"
 #include "tidss_drv.h"
@@ -59,10 +60,6 @@ static const struct drm_encoder_helper_funcs encoder_helper_funcs = {
 	.atomic_check = tidss_encoder_atomic_check,
 };
 
-static const struct drm_encoder_funcs encoder_funcs = {
-	.destroy = drm_encoder_cleanup,
-};
-
 struct drm_encoder *tidss_encoder_create(struct tidss_device *tidss,
 					 u32 encoder_type, u32 possible_crtcs)
 {
@@ -75,8 +72,7 @@ struct drm_encoder *tidss_encoder_create(struct tidss_device *tidss,
 
 	enc->possible_crtcs = possible_crtcs;
 
-	ret = drm_encoder_init(&tidss->ddev, enc, &encoder_funcs,
-			       encoder_type, NULL);
+	ret = drm_simple_encoder_init(&tidss->ddev, enc, encoder_type);
 	if (ret < 0)
 		return ERR_PTR(ret);
 
diff --git a/drivers/gpu/drm/tidss/tidss_kms.c b/drivers/gpu/drm/tidss/tidss_kms.c
index 7d419960b030..4bd339a467a4 100644
--- a/drivers/gpu/drm/tidss/tidss_kms.c
+++ b/drivers/gpu/drm/tidss/tidss_kms.c
@@ -258,7 +258,9 @@ int tidss_modeset_init(struct tidss_device *tidss)
 
 	dev_dbg(tidss->dev, "%s\n", __func__);
 
-	drm_mode_config_init(ddev);
+	ret = drmm_mode_config_init(ddev);
+	if (ret)
+		return ret;
 
 	ddev->mode_config.min_width = 8;
 	ddev->mode_config.min_height = 8;
@@ -270,11 +272,11 @@ int tidss_modeset_init(struct tidss_device *tidss)
 
 	ret = tidss_dispc_modeset_init(tidss);
 	if (ret)
-		goto err_mode_config_cleanup;
+		return ret;
 
 	ret = drm_vblank_init(ddev, tidss->num_crtcs);
 	if (ret)
-		goto err_mode_config_cleanup;
+		return ret;
 
 	/* Start with vertical blanking interrupt reporting disabled. */
 	for (i = 0; i < tidss->num_crtcs; ++i)
@@ -285,15 +287,4 @@ int tidss_modeset_init(struct tidss_device *tidss)
 	dev_dbg(tidss->dev, "%s done\n", __func__);
 
 	return 0;
-
-err_mode_config_cleanup:
-	drm_mode_config_cleanup(ddev);
-	return ret;
-}
-
-void tidss_modeset_cleanup(struct tidss_device *tidss)
-{
-	struct drm_device *ddev = &tidss->ddev;
-
-	drm_mode_config_cleanup(ddev);
 }
diff --git a/drivers/gpu/drm/tidss/tidss_kms.h b/drivers/gpu/drm/tidss/tidss_kms.h
index dda5625d0128..99aaff099f22 100644
--- a/drivers/gpu/drm/tidss/tidss_kms.h
+++ b/drivers/gpu/drm/tidss/tidss_kms.h
@@ -10,6 +10,5 @@
 struct tidss_device;
 
 int tidss_modeset_init(struct tidss_device *tidss);
-void tidss_modeset_cleanup(struct tidss_device *tidss);
 
 #endif
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index 0791a0200cc3..a5e9ee4c7fbf 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -390,10 +390,9 @@ static int tilcdc_init(struct drm_driver *ddrv, struct device *dev)
 	ret = drm_dev_register(ddev, 0);
 	if (ret)
 		goto init_failed;
+	priv->is_registered = true;
 
 	drm_fbdev_generic_setup(ddev, bpp);
-
-	priv->is_registered = true;
 	return 0;
 
 init_failed:
@@ -478,26 +477,17 @@ static struct drm_info_list tilcdc_debugfs_list[] = {
 		{ "mm",   tilcdc_mm_show,   0 },
 };
 
-static int tilcdc_debugfs_init(struct drm_minor *minor)
+static void tilcdc_debugfs_init(struct drm_minor *minor)
 {
-	struct drm_device *dev = minor->dev;
 	struct tilcdc_module *mod;
-	int ret;
 
-	ret = drm_debugfs_create_files(tilcdc_debugfs_list,
-			ARRAY_SIZE(tilcdc_debugfs_list),
-			minor->debugfs_root, minor);
+	drm_debugfs_create_files(tilcdc_debugfs_list,
+				 ARRAY_SIZE(tilcdc_debugfs_list),
+				 minor->debugfs_root, minor);
 
 	list_for_each_entry(mod, &module_list, list)
 		if (mod->funcs->debugfs_init)
 			mod->funcs->debugfs_init(mod, minor);
-
-	if (ret) {
-		dev_err(dev->dev, "could not install tilcdc_debugfs_list\n");
-		return ret;
-	}
-
-	return ret;
 }
 #endif
 
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_external.c b/drivers/gpu/drm/tilcdc/tilcdc_external.c
index 28b7f703236e..b177525588c1 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_external.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_external.c
@@ -10,6 +10,7 @@
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_bridge.h>
 #include <drm/drm_of.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "tilcdc_drv.h"
 #include "tilcdc_external.h"
@@ -83,10 +84,6 @@ int tilcdc_add_component_encoder(struct drm_device *ddev)
 	return 0;
 }
 
-static const struct drm_encoder_funcs tilcdc_external_encoder_funcs = {
-	.destroy	= drm_encoder_cleanup,
-};
-
 static
 int tilcdc_attach_bridge(struct drm_device *ddev, struct drm_bridge *bridge)
 {
@@ -131,9 +128,8 @@ int tilcdc_attach_external_device(struct drm_device *ddev)
 	if (!priv->external_encoder)
 		return -ENOMEM;
 
-	ret = drm_encoder_init(ddev, priv->external_encoder,
-			       &tilcdc_external_encoder_funcs,
-			       DRM_MODE_ENCODER_NONE, NULL);
+	ret = drm_simple_encoder_init(ddev, priv->external_encoder,
+				      DRM_MODE_ENCODER_NONE);
 	if (ret) {
 		dev_err(ddev->dev, "drm_encoder_init() failed %d\n", ret);
 		return ret;
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/drivers/gpu/drm/tilcdc/tilcdc_panel.c
index 5584e656b857..12823d60c4e8 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c
@@ -16,6 +16,7 @@
 #include <drm/drm_connector.h>
 #include <drm/drm_modeset_helper_vtables.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "tilcdc_drv.h"
 #include "tilcdc_panel.h"
@@ -74,10 +75,6 @@ static void panel_encoder_mode_set(struct drm_encoder *encoder,
 	/* nothing needed */
 }
 
-static const struct drm_encoder_funcs panel_encoder_funcs = {
-		.destroy        = drm_encoder_cleanup,
-};
-
 static const struct drm_encoder_helper_funcs panel_encoder_helper_funcs = {
 		.dpms           = panel_encoder_dpms,
 		.prepare        = panel_encoder_prepare,
@@ -102,8 +99,7 @@ static struct drm_encoder *panel_encoder_create(struct drm_device *dev,
 	encoder = &panel_encoder->base;
 	encoder->possible_crtcs = 1;
 
-	ret = drm_encoder_init(dev, encoder, &panel_encoder_funcs,
-			DRM_MODE_ENCODER_LVDS, NULL);
+	ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_LVDS);
 	if (ret < 0)
 		goto fail;
 
diff --git a/drivers/gpu/drm/tiny/gm12u320.c b/drivers/gpu/drm/tiny/gm12u320.c
index a48173441ae0..6f0ea2827d62 100644
--- a/drivers/gpu/drm/tiny/gm12u320.c
+++ b/drivers/gpu/drm/tiny/gm12u320.c
@@ -19,6 +19,7 @@
 #include <drm/drm_gem_shmem_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
 #include <drm/drm_ioctl.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_modeset_helper_vtables.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/drm_simple_kms_helper.h>
@@ -87,15 +88,13 @@ struct gm12u320_device {
 	struct usb_device               *udev;
 	unsigned char                   *cmd_buf;
 	unsigned char                   *data_buf[GM12U320_BLOCK_COUNT];
-	bool                             pipe_enabled;
 	struct {
-		bool                     run;
-		struct workqueue_struct *workq;
-		struct work_struct       work;
-		wait_queue_head_t        waitq;
+		struct delayed_work       work;
 		struct mutex             lock;
 		struct drm_framebuffer  *fb;
 		struct drm_rect          rect;
+		int frame;
+		int draw_status_timeout;
 	} fb_update;
 };
 
@@ -159,7 +158,7 @@ static int gm12u320_usb_alloc(struct gm12u320_device *gm12u320)
 	int i, block_size;
 	const char *hdr;
 
-	gm12u320->cmd_buf = kmalloc(CMD_SIZE, GFP_KERNEL);
+	gm12u320->cmd_buf = drmm_kmalloc(&gm12u320->dev, CMD_SIZE, GFP_KERNEL);
 	if (!gm12u320->cmd_buf)
 		return -ENOMEM;
 
@@ -172,7 +171,8 @@ static int gm12u320_usb_alloc(struct gm12u320_device *gm12u320)
 			hdr = data_block_header;
 		}
 
-		gm12u320->data_buf[i] = kzalloc(block_size, GFP_KERNEL);
+		gm12u320->data_buf[i] = drmm_kzalloc(&gm12u320->dev,
+						     block_size, GFP_KERNEL);
 		if (!gm12u320->data_buf[i])
 			return -ENOMEM;
 
@@ -182,26 +182,9 @@ static int gm12u320_usb_alloc(struct gm12u320_device *gm12u320)
 		       data_block_footer, DATA_BLOCK_FOOTER_SIZE);
 	}
 
-	gm12u320->fb_update.workq = create_singlethread_workqueue(DRIVER_NAME);
-	if (!gm12u320->fb_update.workq)
-		return -ENOMEM;
-
 	return 0;
 }
 
-static void gm12u320_usb_free(struct gm12u320_device *gm12u320)
-{
-	int i;
-
-	if (gm12u320->fb_update.workq)
-		destroy_workqueue(gm12u320->fb_update.workq);
-
-	for (i = 0; i < GM12U320_BLOCK_COUNT; i++)
-		kfree(gm12u320->data_buf[i]);
-
-	kfree(gm12u320->cmd_buf);
-}
-
 static int gm12u320_misc_request(struct gm12u320_device *gm12u320,
 				 u8 req_a, u8 req_b,
 				 u8 arg_a, u8 arg_b, u8 arg_c, u8 arg_d)
@@ -344,80 +327,77 @@ static void gm12u320_copy_fb_to_blocks(struct gm12u320_device *gm12u320)
 static void gm12u320_fb_update_work(struct work_struct *work)
 {
 	struct gm12u320_device *gm12u320 =
-		container_of(work, struct gm12u320_device, fb_update.work);
-	int draw_status_timeout = FIRST_FRAME_TIMEOUT;
+		container_of(to_delayed_work(work), struct gm12u320_device,
+			     fb_update.work);
 	int block, block_size, len;
-	int frame = 0;
 	int ret = 0;
 
-	while (gm12u320->fb_update.run) {
-		gm12u320_copy_fb_to_blocks(gm12u320);
-
-		for (block = 0; block < GM12U320_BLOCK_COUNT; block++) {
-			if (block == GM12U320_BLOCK_COUNT - 1)
-				block_size = DATA_LAST_BLOCK_SIZE;
-			else
-				block_size = DATA_BLOCK_SIZE;
-
-			/* Send data command to device */
-			memcpy(gm12u320->cmd_buf, cmd_data, CMD_SIZE);
-			gm12u320->cmd_buf[8] = block_size & 0xff;
-			gm12u320->cmd_buf[9] = block_size >> 8;
-			gm12u320->cmd_buf[20] = 0xfc - block * 4;
-			gm12u320->cmd_buf[21] = block | (frame << 7);
-
-			ret = usb_bulk_msg(gm12u320->udev,
-				usb_sndbulkpipe(gm12u320->udev, DATA_SND_EPT),
-				gm12u320->cmd_buf, CMD_SIZE, &len,
-				CMD_TIMEOUT);
-			if (ret || len != CMD_SIZE)
-				goto err;
-
-			/* Send data block to device */
-			ret = usb_bulk_msg(gm12u320->udev,
-				usb_sndbulkpipe(gm12u320->udev, DATA_SND_EPT),
-				gm12u320->data_buf[block], block_size,
-				&len, DATA_TIMEOUT);
-			if (ret || len != block_size)
-				goto err;
-
-			/* Read status */
-			ret = usb_bulk_msg(gm12u320->udev,
-				usb_rcvbulkpipe(gm12u320->udev, DATA_RCV_EPT),
-				gm12u320->cmd_buf, READ_STATUS_SIZE, &len,
-				CMD_TIMEOUT);
-			if (ret || len != READ_STATUS_SIZE)
-				goto err;
-		}
+	gm12u320_copy_fb_to_blocks(gm12u320);
+
+	for (block = 0; block < GM12U320_BLOCK_COUNT; block++) {
+		if (block == GM12U320_BLOCK_COUNT - 1)
+			block_size = DATA_LAST_BLOCK_SIZE;
+		else
+			block_size = DATA_BLOCK_SIZE;
+
+		/* Send data command to device */
+		memcpy(gm12u320->cmd_buf, cmd_data, CMD_SIZE);
+		gm12u320->cmd_buf[8] = block_size & 0xff;
+		gm12u320->cmd_buf[9] = block_size >> 8;
+		gm12u320->cmd_buf[20] = 0xfc - block * 4;
+		gm12u320->cmd_buf[21] =
+			block | (gm12u320->fb_update.frame << 7);
 
-		/* Send draw command to device */
-		memcpy(gm12u320->cmd_buf, cmd_draw, CMD_SIZE);
 		ret = usb_bulk_msg(gm12u320->udev,
 			usb_sndbulkpipe(gm12u320->udev, DATA_SND_EPT),
-			gm12u320->cmd_buf, CMD_SIZE, &len, CMD_TIMEOUT);
+			gm12u320->cmd_buf, CMD_SIZE, &len,
+			CMD_TIMEOUT);
 		if (ret || len != CMD_SIZE)
 			goto err;
 
+		/* Send data block to device */
+		ret = usb_bulk_msg(gm12u320->udev,
+			usb_sndbulkpipe(gm12u320->udev, DATA_SND_EPT),
+			gm12u320->data_buf[block], block_size,
+			&len, DATA_TIMEOUT);
+		if (ret || len != block_size)
+			goto err;
+
 		/* Read status */
 		ret = usb_bulk_msg(gm12u320->udev,
 			usb_rcvbulkpipe(gm12u320->udev, DATA_RCV_EPT),
 			gm12u320->cmd_buf, READ_STATUS_SIZE, &len,
-			draw_status_timeout);
+			CMD_TIMEOUT);
 		if (ret || len != READ_STATUS_SIZE)
 			goto err;
-
-		draw_status_timeout = CMD_TIMEOUT;
-		frame = !frame;
-
-		/*
-		 * We must draw a frame every 2s otherwise the projector
-		 * switches back to showing its logo.
-		 */
-		wait_event_timeout(gm12u320->fb_update.waitq,
-				   !gm12u320->fb_update.run ||
-					gm12u320->fb_update.fb != NULL,
-				   IDLE_TIMEOUT);
 	}
+
+	/* Send draw command to device */
+	memcpy(gm12u320->cmd_buf, cmd_draw, CMD_SIZE);
+	ret = usb_bulk_msg(gm12u320->udev,
+		usb_sndbulkpipe(gm12u320->udev, DATA_SND_EPT),
+		gm12u320->cmd_buf, CMD_SIZE, &len, CMD_TIMEOUT);
+	if (ret || len != CMD_SIZE)
+		goto err;
+
+	/* Read status */
+	ret = usb_bulk_msg(gm12u320->udev,
+		usb_rcvbulkpipe(gm12u320->udev, DATA_RCV_EPT),
+		gm12u320->cmd_buf, READ_STATUS_SIZE, &len,
+		gm12u320->fb_update.draw_status_timeout);
+	if (ret || len != READ_STATUS_SIZE)
+		goto err;
+
+	gm12u320->fb_update.draw_status_timeout = CMD_TIMEOUT;
+	gm12u320->fb_update.frame = !gm12u320->fb_update.frame;
+
+	/*
+	 * We must draw a frame every 2s otherwise the projector
+	 * switches back to showing its logo.
+	 */
+	queue_delayed_work(system_long_wq, &gm12u320->fb_update.work,
+			   IDLE_TIMEOUT);
+
 	return;
 err:
 	/* Do not log errors caused by module unload or device unplug */
@@ -452,36 +432,24 @@ static void gm12u320_fb_mark_dirty(struct drm_framebuffer *fb,
 	mutex_unlock(&gm12u320->fb_update.lock);
 
 	if (wakeup)
-		wake_up(&gm12u320->fb_update.waitq);
+		mod_delayed_work(system_long_wq, &gm12u320->fb_update.work, 0);
 
 	if (old_fb)
 		drm_framebuffer_put(old_fb);
 }
 
-static void gm12u320_start_fb_update(struct gm12u320_device *gm12u320)
-{
-	mutex_lock(&gm12u320->fb_update.lock);
-	gm12u320->fb_update.run = true;
-	mutex_unlock(&gm12u320->fb_update.lock);
-
-	queue_work(gm12u320->fb_update.workq, &gm12u320->fb_update.work);
-}
-
 static void gm12u320_stop_fb_update(struct gm12u320_device *gm12u320)
 {
-	mutex_lock(&gm12u320->fb_update.lock);
-	gm12u320->fb_update.run = false;
-	mutex_unlock(&gm12u320->fb_update.lock);
+	struct drm_framebuffer *old_fb;
 
-	wake_up(&gm12u320->fb_update.waitq);
-	cancel_work_sync(&gm12u320->fb_update.work);
+	cancel_delayed_work_sync(&gm12u320->fb_update.work);
 
 	mutex_lock(&gm12u320->fb_update.lock);
-	if (gm12u320->fb_update.fb) {
-		drm_framebuffer_put(gm12u320->fb_update.fb);
-		gm12u320->fb_update.fb = NULL;
-	}
+	old_fb = gm12u320->fb_update.fb;
+	gm12u320->fb_update.fb = NULL;
 	mutex_unlock(&gm12u320->fb_update.lock);
+
+	drm_framebuffer_put(old_fb);
 }
 
 static int gm12u320_set_ecomode(struct gm12u320_device *gm12u320)
@@ -589,12 +557,11 @@ static void gm12u320_pipe_enable(struct drm_simple_display_pipe *pipe,
 				 struct drm_crtc_state *crtc_state,
 				 struct drm_plane_state *plane_state)
 {
-	struct gm12u320_device *gm12u320 = pipe->crtc.dev->dev_private;
 	struct drm_rect rect = { 0, 0, GM12U320_USER_WIDTH, GM12U320_HEIGHT };
+	struct gm12u320_device *gm12u320 = pipe->crtc.dev->dev_private;
 
+	gm12u320->fb_update.draw_status_timeout = FIRST_FRAME_TIMEOUT;
 	gm12u320_fb_mark_dirty(plane_state->fb, &rect);
-	gm12u320_start_fb_update(gm12u320);
-	gm12u320->pipe_enabled = true;
 }
 
 static void gm12u320_pipe_disable(struct drm_simple_display_pipe *pipe)
@@ -602,7 +569,6 @@ static void gm12u320_pipe_disable(struct drm_simple_display_pipe *pipe)
 	struct gm12u320_device *gm12u320 = pipe->crtc.dev->dev_private;
 
 	gm12u320_stop_fb_update(gm12u320);
-	gm12u320->pipe_enabled = false;
 }
 
 static void gm12u320_pipe_update(struct drm_simple_display_pipe *pipe,
@@ -630,16 +596,6 @@ static const uint64_t gm12u320_pipe_modifiers[] = {
 	DRM_FORMAT_MOD_INVALID
 };
 
-static void gm12u320_driver_release(struct drm_device *dev)
-{
-	struct gm12u320_device *gm12u320 = dev->dev_private;
-
-	gm12u320_usb_free(gm12u320);
-	drm_mode_config_cleanup(dev);
-	drm_dev_fini(dev);
-	kfree(gm12u320);
-}
-
 DEFINE_DRM_GEM_FOPS(gm12u320_fops);
 
 static struct drm_driver gm12u320_drm_driver = {
@@ -651,7 +607,6 @@ static struct drm_driver gm12u320_drm_driver = {
 	.major		 = DRIVER_MAJOR,
 	.minor		 = DRIVER_MINOR,
 
-	.release	 = gm12u320_driver_release,
 	.fops		 = &gm12u320_fops,
 	DRM_GEM_SHMEM_DRIVER_OPS,
 };
@@ -681,19 +636,22 @@ static int gm12u320_usb_probe(struct usb_interface *interface,
 		return -ENOMEM;
 
 	gm12u320->udev = interface_to_usbdev(interface);
-	INIT_WORK(&gm12u320->fb_update.work, gm12u320_fb_update_work);
+	INIT_DELAYED_WORK(&gm12u320->fb_update.work, gm12u320_fb_update_work);
 	mutex_init(&gm12u320->fb_update.lock);
-	init_waitqueue_head(&gm12u320->fb_update.waitq);
 
 	dev = &gm12u320->dev;
-	ret = drm_dev_init(dev, &gm12u320_drm_driver, &interface->dev);
+	ret = devm_drm_dev_init(&interface->dev, dev, &gm12u320_drm_driver);
 	if (ret) {
 		kfree(gm12u320);
 		return ret;
 	}
 	dev->dev_private = gm12u320;
+	drmm_add_final_kfree(dev, gm12u320);
+
+	ret = drmm_mode_config_init(dev);
+	if (ret)
+		return ret;
 
-	drm_mode_config_init(dev);
 	dev->mode_config.min_width = GM12U320_USER_WIDTH;
 	dev->mode_config.max_width = GM12U320_USER_WIDTH;
 	dev->mode_config.min_height = GM12U320_HEIGHT;
@@ -702,15 +660,15 @@ static int gm12u320_usb_probe(struct usb_interface *interface,
 
 	ret = gm12u320_usb_alloc(gm12u320);
 	if (ret)
-		goto err_put;
+		return ret;
 
 	ret = gm12u320_set_ecomode(gm12u320);
 	if (ret)
-		goto err_put;
+		return ret;
 
 	ret = gm12u320_conn_init(gm12u320);
 	if (ret)
-		goto err_put;
+		return ret;
 
 	ret = drm_simple_display_pipe_init(&gm12u320->dev,
 					   &gm12u320->pipe,
@@ -720,44 +678,34 @@ static int gm12u320_usb_probe(struct usb_interface *interface,
 					   gm12u320_pipe_modifiers,
 					   &gm12u320->conn);
 	if (ret)
-		goto err_put;
+		return ret;
 
 	drm_mode_config_reset(dev);
 
 	usb_set_intfdata(interface, dev);
 	ret = drm_dev_register(dev, 0);
 	if (ret)
-		goto err_put;
+		return ret;
 
 	drm_fbdev_generic_setup(dev, 0);
 
 	return 0;
-
-err_put:
-	drm_dev_put(dev);
-	return ret;
 }
 
 static void gm12u320_usb_disconnect(struct usb_interface *interface)
 {
 	struct drm_device *dev = usb_get_intfdata(interface);
-	struct gm12u320_device *gm12u320 = dev->dev_private;
 
-	gm12u320_stop_fb_update(gm12u320);
 	drm_dev_unplug(dev);
-	drm_dev_put(dev);
+	drm_atomic_helper_shutdown(dev);
 }
 
 static __maybe_unused int gm12u320_suspend(struct usb_interface *interface,
 					   pm_message_t message)
 {
 	struct drm_device *dev = usb_get_intfdata(interface);
-	struct gm12u320_device *gm12u320 = dev->dev_private;
 
-	if (gm12u320->pipe_enabled)
-		gm12u320_stop_fb_update(gm12u320);
-
-	return 0;
+	return drm_mode_config_helper_suspend(dev);
 }
 
 static __maybe_unused int gm12u320_resume(struct usb_interface *interface)
@@ -766,10 +714,8 @@ static __maybe_unused int gm12u320_resume(struct usb_interface *interface)
 	struct gm12u320_device *gm12u320 = dev->dev_private;
 
 	gm12u320_set_ecomode(gm12u320);
-	if (gm12u320->pipe_enabled)
-		gm12u320_start_fb_update(gm12u320);
 
-	return 0;
+	return drm_mode_config_helper_resume(dev);
 }
 
 static const struct usb_device_id id_table[] = {
diff --git a/drivers/gpu/drm/tiny/hx8357d.c b/drivers/gpu/drm/tiny/hx8357d.c
index 9af8ff84974f..af7f3d10aac3 100644
--- a/drivers/gpu/drm/tiny/hx8357d.c
+++ b/drivers/gpu/drm/tiny/hx8357d.c
@@ -21,6 +21,7 @@
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_mipi_dbi.h>
 #include <drm/drm_modeset_helper.h>
 #include <video/mipi_display.h>
@@ -195,7 +196,6 @@ DEFINE_DRM_GEM_CMA_FOPS(hx8357d_fops);
 static struct drm_driver hx8357d_driver = {
 	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
 	.fops			= &hx8357d_fops,
-	.release		= mipi_dbi_release,
 	DRM_GEM_CMA_VMAP_DRIVER_OPS,
 	.debugfs_init		= mipi_dbi_debugfs_init,
 	.name			= "hx8357d",
@@ -236,8 +236,7 @@ static int hx8357d_probe(struct spi_device *spi)
 		kfree(dbidev);
 		return ret;
 	}
-
-	drm_mode_config_init(drm);
+	drmm_add_final_kfree(drm, dbidev);
 
 	dc = devm_gpiod_get(dev, "dc", GPIOD_OUT_LOW);
 	if (IS_ERR(dc)) {
diff --git a/drivers/gpu/drm/tiny/ili9225.c b/drivers/gpu/drm/tiny/ili9225.c
index 802fb8dde1b6..118477af4491 100644
--- a/drivers/gpu/drm/tiny/ili9225.c
+++ b/drivers/gpu/drm/tiny/ili9225.c
@@ -24,6 +24,7 @@
 #include <drm/drm_fourcc.h>
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_mipi_dbi.h>
 #include <drm/drm_rect.h>
 
@@ -345,7 +346,6 @@ DEFINE_DRM_GEM_CMA_FOPS(ili9225_fops);
 static struct drm_driver ili9225_driver = {
 	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
 	.fops			= &ili9225_fops,
-	.release		= mipi_dbi_release,
 	DRM_GEM_CMA_VMAP_DRIVER_OPS,
 	.name			= "ili9225",
 	.desc			= "Ilitek ILI9225",
@@ -387,8 +387,7 @@ static int ili9225_probe(struct spi_device *spi)
 		kfree(dbidev);
 		return ret;
 	}
-
-	drm_mode_config_init(drm);
+	drmm_add_final_kfree(drm, dbidev);
 
 	dbi->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
 	if (IS_ERR(dbi->reset)) {
diff --git a/drivers/gpu/drm/tiny/ili9341.c b/drivers/gpu/drm/tiny/ili9341.c
index 33b51dc7faa8..e152de369019 100644
--- a/drivers/gpu/drm/tiny/ili9341.c
+++ b/drivers/gpu/drm/tiny/ili9341.c
@@ -20,6 +20,7 @@
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_mipi_dbi.h>
 #include <drm/drm_modeset_helper.h>
 #include <video/mipi_display.h>
@@ -151,7 +152,6 @@ DEFINE_DRM_GEM_CMA_FOPS(ili9341_fops);
 static struct drm_driver ili9341_driver = {
 	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
 	.fops			= &ili9341_fops,
-	.release		= mipi_dbi_release,
 	DRM_GEM_CMA_VMAP_DRIVER_OPS,
 	.debugfs_init		= mipi_dbi_debugfs_init,
 	.name			= "ili9341",
@@ -194,8 +194,7 @@ static int ili9341_probe(struct spi_device *spi)
 		kfree(dbidev);
 		return ret;
 	}
-
-	drm_mode_config_init(drm);
+	drmm_add_final_kfree(drm, dbidev);
 
 	dbi->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
 	if (IS_ERR(dbi->reset)) {
diff --git a/drivers/gpu/drm/tiny/ili9486.c b/drivers/gpu/drm/tiny/ili9486.c
index 532560aebb1e..c4079bf9e2c8 100644
--- a/drivers/gpu/drm/tiny/ili9486.c
+++ b/drivers/gpu/drm/tiny/ili9486.c
@@ -19,6 +19,7 @@
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_mipi_dbi.h>
 #include <drm/drm_modeset_helper.h>
 
@@ -164,7 +165,6 @@ DEFINE_DRM_GEM_CMA_FOPS(ili9486_fops);
 static struct drm_driver ili9486_driver = {
 	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
 	.fops			= &ili9486_fops,
-	.release		= mipi_dbi_release,
 	DRM_GEM_CMA_VMAP_DRIVER_OPS,
 	.debugfs_init		= mipi_dbi_debugfs_init,
 	.name			= "ili9486",
@@ -208,8 +208,7 @@ static int ili9486_probe(struct spi_device *spi)
 		kfree(dbidev);
 		return ret;
 	}
-
-	drm_mode_config_init(drm);
+	drmm_add_final_kfree(drm, dbidev);
 
 	dbi->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
 	if (IS_ERR(dbi->reset)) {
diff --git a/drivers/gpu/drm/tiny/mi0283qt.c b/drivers/gpu/drm/tiny/mi0283qt.c
index e2cfd9a17143..decaf57053ff 100644
--- a/drivers/gpu/drm/tiny/mi0283qt.c
+++ b/drivers/gpu/drm/tiny/mi0283qt.c
@@ -18,6 +18,7 @@
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_mipi_dbi.h>
 #include <drm/drm_modeset_helper.h>
 #include <video/mipi_display.h>
@@ -155,7 +156,6 @@ DEFINE_DRM_GEM_CMA_FOPS(mi0283qt_fops);
 static struct drm_driver mi0283qt_driver = {
 	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
 	.fops			= &mi0283qt_fops,
-	.release		= mipi_dbi_release,
 	DRM_GEM_CMA_VMAP_DRIVER_OPS,
 	.debugfs_init		= mipi_dbi_debugfs_init,
 	.name			= "mi0283qt",
@@ -198,8 +198,7 @@ static int mi0283qt_probe(struct spi_device *spi)
 		kfree(dbidev);
 		return ret;
 	}
-
-	drm_mode_config_init(drm);
+	drmm_add_final_kfree(drm, dbidev);
 
 	dbi->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
 	if (IS_ERR(dbi->reset)) {
diff --git a/drivers/gpu/drm/tiny/repaper.c b/drivers/gpu/drm/tiny/repaper.c
index f5ebcaf7ee3a..862c3ee6055d 100644
--- a/drivers/gpu/drm/tiny/repaper.c
+++ b/drivers/gpu/drm/tiny/repaper.c
@@ -31,6 +31,7 @@
 #include <drm/drm_format_helper.h>
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_modes.h>
 #include <drm/drm_rect.h>
 #include <drm/drm_probe_helper.h>
@@ -908,17 +909,6 @@ static const struct drm_mode_config_funcs repaper_mode_config_funcs = {
 	.atomic_commit = drm_atomic_helper_commit,
 };
 
-static void repaper_release(struct drm_device *drm)
-{
-	struct repaper_epd *epd = drm_to_epd(drm);
-
-	DRM_DEBUG_DRIVER("\n");
-
-	drm_mode_config_cleanup(drm);
-	drm_dev_fini(drm);
-	kfree(epd);
-}
-
 static const uint32_t repaper_formats[] = {
 	DRM_FORMAT_XRGB8888,
 };
@@ -956,7 +946,6 @@ DEFINE_DRM_GEM_CMA_FOPS(repaper_fops);
 static struct drm_driver repaper_driver = {
 	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
 	.fops			= &repaper_fops,
-	.release		= repaper_release,
 	DRM_GEM_CMA_VMAP_DRIVER_OPS,
 	.name			= "repaper",
 	.desc			= "Pervasive Displays RePaper e-ink panels",
@@ -1024,8 +1013,11 @@ static int repaper_probe(struct spi_device *spi)
 		kfree(epd);
 		return ret;
 	}
+	drmm_add_final_kfree(drm, epd);
 
-	drm_mode_config_init(drm);
+	ret = drmm_mode_config_init(drm);
+	if (ret)
+		return ret;
 	drm->mode_config.funcs = &repaper_mode_config_funcs;
 
 	epd->spi = spi;
diff --git a/drivers/gpu/drm/tiny/st7586.c b/drivers/gpu/drm/tiny/st7586.c
index 9ef559dd3191..c3295c717ba6 100644
--- a/drivers/gpu/drm/tiny/st7586.c
+++ b/drivers/gpu/drm/tiny/st7586.c
@@ -21,6 +21,7 @@
 #include <drm/drm_format_helper.h>
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_mipi_dbi.h>
 #include <drm/drm_rect.h>
 
@@ -284,7 +285,6 @@ DEFINE_DRM_GEM_CMA_FOPS(st7586_fops);
 static struct drm_driver st7586_driver = {
 	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
 	.fops			= &st7586_fops,
-	.release		= mipi_dbi_release,
 	DRM_GEM_CMA_VMAP_DRIVER_OPS,
 	.debugfs_init		= mipi_dbi_debugfs_init,
 	.name			= "st7586",
@@ -328,8 +328,7 @@ static int st7586_probe(struct spi_device *spi)
 		kfree(dbidev);
 		return ret;
 	}
-
-	drm_mode_config_init(drm);
+	drmm_add_final_kfree(drm, dbidev);
 
 	bufsize = (st7586_mode.vdisplay + 2) / 3 * st7586_mode.hdisplay;
 
diff --git a/drivers/gpu/drm/tiny/st7735r.c b/drivers/gpu/drm/tiny/st7735r.c
index 3cd9b8d9888d..c2c7dc0224dd 100644
--- a/drivers/gpu/drm/tiny/st7735r.c
+++ b/drivers/gpu/drm/tiny/st7735r.c
@@ -21,6 +21,7 @@
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_mipi_dbi.h>
 
 #define ST7735R_FRMCTR1		0xb1
@@ -156,7 +157,6 @@ DEFINE_DRM_GEM_CMA_FOPS(st7735r_fops);
 static struct drm_driver st7735r_driver = {
 	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
 	.fops			= &st7735r_fops,
-	.release		= mipi_dbi_release,
 	DRM_GEM_CMA_VMAP_DRIVER_OPS,
 	.debugfs_init		= mipi_dbi_debugfs_init,
 	.name			= "st7735r",
@@ -209,8 +209,7 @@ static int st7735r_probe(struct spi_device *spi)
 		kfree(dbidev);
 		return ret;
 	}
-
-	drm_mode_config_init(drm);
+	drmm_add_final_kfree(drm, dbidev);
 
 	dbi->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
 	if (IS_ERR(dbi->reset)) {
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 9e07c3f75156..46d0d068cd65 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -518,7 +518,7 @@ static bool ttm_bo_delayed_delete(struct ttm_bo_device *bdev, bool remove_all)
 	INIT_LIST_HEAD(&removed);
 
 	spin_lock(&glob->lru_lock);
-	while (!list_empty(&bdev->ddestroy)) {
+	while (!list_empty(&bdev->ddestroy) && !need_resched()) {
 		struct ttm_buffer_object *bo;
 
 		bo = list_first_entry(&bdev->ddestroy, struct ttm_buffer_object,
@@ -588,7 +588,8 @@ static void ttm_bo_release(struct kref *kref)
 		ttm_mem_io_unlock(man);
 	}
 
-	if (!dma_resv_test_signaled_rcu(bo->base.resv, true)) {
+	if (!dma_resv_test_signaled_rcu(bo->base.resv, true) ||
+	    !dma_resv_trylock(bo->base.resv)) {
 		/* The BO is not idle, resurrect it for delayed destroy */
 		ttm_bo_flush_all_fences(bo);
 		bo->deleted = true;
@@ -621,6 +622,7 @@ static void ttm_bo_release(struct kref *kref)
 	spin_unlock(&ttm_bo_glob.lru_lock);
 
 	ttm_bo_cleanup_memtype_use(bo);
+	dma_resv_unlock(bo->base.resv);
 
 	BUG_ON(bo->mem.mm_node != NULL);
 	atomic_dec(&ttm_bo_glob.bo_count);
diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
index e6c1cd77d4d4..9cc6d075cb40 100644
--- a/drivers/gpu/drm/udl/udl_drv.c
+++ b/drivers/gpu/drm/udl/udl_drv.c
@@ -10,6 +10,7 @@
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_file.h>
 #include <drm/drm_gem_shmem_helper.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_ioctl.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/drm_print.h>
@@ -33,17 +34,8 @@ static int udl_usb_resume(struct usb_interface *interface)
 
 DEFINE_DRM_GEM_FOPS(udl_driver_fops);
 
-static void udl_driver_release(struct drm_device *dev)
-{
-	udl_fini(dev);
-	udl_modeset_cleanup(dev);
-	drm_dev_fini(dev);
-	kfree(dev);
-}
-
 static struct drm_driver driver = {
 	.driver_features = DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET,
-	.release = udl_driver_release,
 
 	/* gem hooks */
 	.gem_create_object = udl_driver_gem_create_object,
@@ -77,11 +69,11 @@ static struct udl_device *udl_driver_create(struct usb_interface *interface)
 
 	udl->udev = udev;
 	udl->drm.dev_private = udl;
+	drmm_add_final_kfree(&udl->drm, udl);
 
 	r = udl_init(udl);
 	if (r) {
-		drm_dev_fini(&udl->drm);
-		kfree(udl);
+		drm_dev_put(&udl->drm);
 		return ERR_PTR(r);
 	}
 
@@ -105,14 +97,10 @@ static int udl_usb_probe(struct usb_interface *interface,
 
 	DRM_INFO("Initialized udl on minor %d\n", udl->drm.primary->index);
 
-	r = drm_fbdev_generic_setup(&udl->drm, 0);
-	if (r)
-		goto err_drm_dev_unregister;
+	drm_fbdev_generic_setup(&udl->drm, 0);
 
 	return 0;
 
-err_drm_dev_unregister:
-	drm_dev_unregister(&udl->drm);
 err_free:
 	drm_dev_put(&udl->drm);
 	return r;
@@ -122,7 +110,7 @@ static void udl_usb_disconnect(struct usb_interface *interface)
 {
 	struct drm_device *dev = usb_get_intfdata(interface);
 
-	drm_kms_helper_poll_disable(dev);
+	drm_kms_helper_poll_fini(dev);
 	udl_drop_usb(dev);
 	drm_dev_unplug(dev);
 	drm_dev_put(dev);
diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h
index e67227c44cc4..2642f94a63fc 100644
--- a/drivers/gpu/drm/udl/udl_drv.h
+++ b/drivers/gpu/drm/udl/udl_drv.h
@@ -68,7 +68,6 @@ struct udl_device {
 
 /* modeset */
 int udl_modeset_init(struct drm_device *dev);
-void udl_modeset_cleanup(struct drm_device *dev);
 struct drm_connector *udl_connector_init(struct drm_device *dev);
 
 struct urb *udl_get_urb(struct drm_device *dev);
@@ -77,7 +76,6 @@ int udl_submit_urb(struct drm_device *dev, struct urb *urb, size_t len);
 void udl_urb_completion(struct urb *urb);
 
 int udl_init(struct udl_device *udl);
-void udl_fini(struct drm_device *dev);
 
 int udl_render_hline(struct drm_device *dev, int log_bpp, struct urb **urb_ptr,
 		     const char *front, char **urb_buf_ptr,
diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c
index 538718919916..f5d27f2a5654 100644
--- a/drivers/gpu/drm/udl/udl_main.c
+++ b/drivers/gpu/drm/udl/udl_main.c
@@ -351,13 +351,3 @@ int udl_drop_usb(struct drm_device *dev)
 	udl_free_urb_list(dev);
 	return 0;
 }
-
-void udl_fini(struct drm_device *dev)
-{
-	struct udl_device *udl = to_udl(dev);
-
-	drm_kms_helper_poll_fini(dev);
-
-	if (udl->urbs.count)
-		udl_free_urb_list(dev);
-}
diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c
index d59ebac70b15..8cad01f3d163 100644
--- a/drivers/gpu/drm/udl/udl_modeset.c
+++ b/drivers/gpu/drm/udl/udl_modeset.c
@@ -468,7 +468,9 @@ int udl_modeset_init(struct drm_device *dev)
 	struct drm_connector *connector;
 	int ret;
 
-	drm_mode_config_init(dev);
+	ret = drmm_mode_config_init(dev);
+	if (ret)
+		return ret;
 
 	dev->mode_config.min_width = 640;
 	dev->mode_config.min_height = 480;
@@ -482,10 +484,8 @@ int udl_modeset_init(struct drm_device *dev)
 	dev->mode_config.funcs = &udl_mode_funcs;
 
 	connector = udl_connector_init(dev);
-	if (IS_ERR(connector)) {
-		ret = PTR_ERR(connector);
-		goto err_drm_mode_config_cleanup;
-	}
+	if (IS_ERR(connector))
+		return PTR_ERR(connector);
 
 	format_count = ARRAY_SIZE(udl_simple_display_pipe_formats);
 
@@ -494,18 +494,9 @@ int udl_modeset_init(struct drm_device *dev)
 					   udl_simple_display_pipe_formats,
 					   format_count, NULL, connector);
 	if (ret)
-		goto err_drm_mode_config_cleanup;
+		return ret;
 
 	drm_mode_config_reset(dev);
 
 	return 0;
-
-err_drm_mode_config_cleanup:
-	drm_mode_config_cleanup(dev);
-	return ret;
-}
-
-void udl_modeset_cleanup(struct drm_device *dev)
-{
-	drm_mode_config_cleanup(dev);
 }
diff --git a/drivers/gpu/drm/v3d/v3d_debugfs.c b/drivers/gpu/drm/v3d/v3d_debugfs.c
index 9e953ce64ef7..2b0ea5f8febd 100644
--- a/drivers/gpu/drm/v3d/v3d_debugfs.c
+++ b/drivers/gpu/drm/v3d/v3d_debugfs.c
@@ -258,10 +258,10 @@ static const struct drm_info_list v3d_debugfs_list[] = {
 	{"bo_stats", v3d_debugfs_bo_stats, 0},
 };
 
-int
+void
 v3d_debugfs_init(struct drm_minor *minor)
 {
-	return drm_debugfs_create_files(v3d_debugfs_list,
-					ARRAY_SIZE(v3d_debugfs_list),
-					minor->debugfs_root, minor);
+	drm_debugfs_create_files(v3d_debugfs_list,
+				 ARRAY_SIZE(v3d_debugfs_list),
+				 minor->debugfs_root, minor);
 }
diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c
index eaa8e9682373..8d0c0daaac81 100644
--- a/drivers/gpu/drm/v3d/v3d_drv.c
+++ b/drivers/gpu/drm/v3d/v3d_drv.c
@@ -25,6 +25,7 @@
 #include <drm/drm_drv.h>
 #include <drm/drm_fb_cma_helper.h>
 #include <drm/drm_fb_helper.h>
+#include <drm/drm_managed.h>
 #include <uapi/drm/v3d_drm.h>
 
 #include "v3d_drv.h"
@@ -257,13 +258,23 @@ static int v3d_platform_drm_probe(struct platform_device *pdev)
 	v3d->pdev = pdev;
 	drm = &v3d->drm;
 
+	ret = drm_dev_init(&v3d->drm, &v3d_drm_driver, dev);
+	if (ret) {
+		kfree(v3d);
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, drm);
+	drm->dev_private = v3d;
+	drmm_add_final_kfree(drm, v3d);
+
 	ret = map_regs(v3d, &v3d->hub_regs, "hub");
 	if (ret)
-		goto dev_free;
+		goto dev_destroy;
 
 	ret = map_regs(v3d, &v3d->core_regs[0], "core0");
 	if (ret)
-		goto dev_free;
+		goto dev_destroy;
 
 	mmu_debug = V3D_READ(V3D_MMU_DEBUG_INFO);
 	dev->coherent_dma_mask =
@@ -281,21 +292,21 @@ static int v3d_platform_drm_probe(struct platform_device *pdev)
 		ret = PTR_ERR(v3d->reset);
 
 		if (ret == -EPROBE_DEFER)
-			goto dev_free;
+			goto dev_destroy;
 
 		v3d->reset = NULL;
 		ret = map_regs(v3d, &v3d->bridge_regs, "bridge");
 		if (ret) {
 			dev_err(dev,
 				"Failed to get reset control or bridge regs\n");
-			goto dev_free;
+			goto dev_destroy;
 		}
 	}
 
 	if (v3d->ver < 41) {
 		ret = map_regs(v3d, &v3d->gca_regs, "gca");
 		if (ret)
-			goto dev_free;
+			goto dev_destroy;
 	}
 
 	v3d->mmu_scratch = dma_alloc_wc(dev, 4096, &v3d->mmu_scratch_paddr,
@@ -303,23 +314,16 @@ static int v3d_platform_drm_probe(struct platform_device *pdev)
 	if (!v3d->mmu_scratch) {
 		dev_err(dev, "Failed to allocate MMU scratch page\n");
 		ret = -ENOMEM;
-		goto dev_free;
+		goto dev_destroy;
 	}
 
 	pm_runtime_use_autosuspend(dev);
 	pm_runtime_set_autosuspend_delay(dev, 50);
 	pm_runtime_enable(dev);
 
-	ret = drm_dev_init(&v3d->drm, &v3d_drm_driver, dev);
-	if (ret)
-		goto dma_free;
-
-	platform_set_drvdata(pdev, drm);
-	drm->dev_private = v3d;
-
 	ret = v3d_gem_init(drm);
 	if (ret)
-		goto dev_destroy;
+		goto dma_free;
 
 	ret = v3d_irq_init(v3d);
 	if (ret)
@@ -335,12 +339,10 @@ static int v3d_platform_drm_probe(struct platform_device *pdev)
 	v3d_irq_disable(v3d);
 gem_destroy:
 	v3d_gem_destroy(drm);
-dev_destroy:
-	drm_dev_put(drm);
 dma_free:
 	dma_free_wc(dev, 4096, v3d->mmu_scratch, v3d->mmu_scratch_paddr);
-dev_free:
-	kfree(v3d);
+dev_destroy:
+	drm_dev_put(drm);
 	return ret;
 }
 
diff --git a/drivers/gpu/drm/v3d/v3d_drv.h b/drivers/gpu/drm/v3d/v3d_drv.h
index ac2603334587..e0775c884553 100644
--- a/drivers/gpu/drm/v3d/v3d_drv.h
+++ b/drivers/gpu/drm/v3d/v3d_drv.h
@@ -316,7 +316,7 @@ struct drm_gem_object *v3d_prime_import_sg_table(struct drm_device *dev,
 						 struct sg_table *sgt);
 
 /* v3d_debugfs.c */
-int v3d_debugfs_init(struct drm_minor *minor);
+void v3d_debugfs_init(struct drm_minor *minor);
 
 /* v3d_fence.c */
 extern const struct dma_fence_ops v3d_fence_ops;
diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.c b/drivers/gpu/drm/vboxvideo/vbox_drv.c
index ac8f75db2ecd..282348e071fe 100644
--- a/drivers/gpu/drm/vboxvideo/vbox_drv.c
+++ b/drivers/gpu/drm/vboxvideo/vbox_drv.c
@@ -17,6 +17,7 @@
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_file.h>
 #include <drm/drm_ioctl.h>
+#include <drm/drm_managed.h>
 
 #include "vbox_drv.h"
 
@@ -58,6 +59,7 @@ static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	vbox->ddev.pdev = pdev;
 	vbox->ddev.dev_private = vbox;
 	pci_set_drvdata(pdev, vbox);
+	drmm_add_final_kfree(&vbox->ddev, vbox);
 	mutex_init(&vbox->hw_mutex);
 
 	ret = pci_enable_device(pdev);
@@ -80,14 +82,12 @@ static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	if (ret)
 		goto err_mode_fini;
 
-	ret = drm_fbdev_generic_setup(&vbox->ddev, 32);
-	if (ret)
-		goto err_irq_fini;
-
 	ret = drm_dev_register(&vbox->ddev, 0);
 	if (ret)
 		goto err_irq_fini;
 
+	drm_fbdev_generic_setup(&vbox->ddev, 32);
+
 	return 0;
 
 err_irq_fini:
diff --git a/drivers/gpu/drm/vc4/vc4_debugfs.c b/drivers/gpu/drm/vc4/vc4_debugfs.c
index b61b2d3407b5..4fbbf980a299 100644
--- a/drivers/gpu/drm/vc4/vc4_debugfs.c
+++ b/drivers/gpu/drm/vc4/vc4_debugfs.c
@@ -20,7 +20,7 @@ struct vc4_debugfs_info_entry {
  * Called at drm_dev_register() time on each of the minors registered
  * by the DRM device, to attach the debugfs files.
  */
-int
+void
 vc4_debugfs_init(struct drm_minor *minor)
 {
 	struct vc4_dev *vc4 = to_vc4_dev(minor->dev);
@@ -30,14 +30,9 @@ vc4_debugfs_init(struct drm_minor *minor)
 			    minor->debugfs_root, &vc4->load_tracker_enabled);
 
 	list_for_each_entry(entry, &vc4->debugfs_list, link) {
-		int ret = drm_debugfs_create_files(&entry->info, 1,
-						   minor->debugfs_root, minor);
-
-		if (ret)
-			return ret;
+		drm_debugfs_create_files(&entry->info, 1,
+					 minor->debugfs_root, minor);
 	}
-
-	return 0;
 }
 
 static int vc4_debugfs_regset32(struct seq_file *m, void *unused)
diff --git a/drivers/gpu/drm/vc4/vc4_dpi.c b/drivers/gpu/drm/vc4/vc4_dpi.c
index 6dfede03396e..a90f2545baee 100644
--- a/drivers/gpu/drm/vc4/vc4_dpi.c
+++ b/drivers/gpu/drm/vc4/vc4_dpi.c
@@ -17,6 +17,7 @@
 #include <drm/drm_of.h>
 #include <drm/drm_panel.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 #include <linux/clk.h>
 #include <linux/component.h>
 #include <linux/of_graph.h>
@@ -114,10 +115,6 @@ static const struct debugfs_reg32 dpi_regs[] = {
 	VC4_REG32(DPI_ID),
 };
 
-static const struct drm_encoder_funcs vc4_dpi_encoder_funcs = {
-	.destroy = drm_encoder_cleanup,
-};
-
 static void vc4_dpi_encoder_disable(struct drm_encoder *encoder)
 {
 	struct vc4_dpi_encoder *vc4_encoder = to_vc4_dpi_encoder(encoder);
@@ -309,8 +306,7 @@ static int vc4_dpi_bind(struct device *dev, struct device *master, void *data)
 	if (ret)
 		DRM_ERROR("Failed to turn on core clock: %d\n", ret);
 
-	drm_encoder_init(drm, dpi->encoder, &vc4_dpi_encoder_funcs,
-			 DRM_MODE_ENCODER_DPI, NULL);
+	drm_simple_encoder_init(drm, dpi->encoder, DRM_MODE_ENCODER_DPI);
 	drm_encoder_helper_add(dpi->encoder, &vc4_dpi_encoder_helper_funcs);
 
 	ret = vc4_dpi_init_bridge(dpi);
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 139d25a8328e..3b1f02efefbe 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -759,7 +759,7 @@ void vc4_crtc_get_margins(struct drm_crtc_state *state,
 			  unsigned int *top, unsigned int *bottom);
 
 /* vc4_debugfs.c */
-int vc4_debugfs_init(struct drm_minor *minor);
+void vc4_debugfs_init(struct drm_minor *minor);
 #ifdef CONFIG_DEBUG_FS
 void vc4_debugfs_add_file(struct drm_device *drm,
 			  const char *filename,
diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c
index d99b1d526651..eaf276978ee7 100644
--- a/drivers/gpu/drm/vc4/vc4_dsi.c
+++ b/drivers/gpu/drm/vc4/vc4_dsi.c
@@ -37,6 +37,7 @@
 #include <drm/drm_of.h>
 #include <drm/drm_panel.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "vc4_drv.h"
 #include "vc4_regs.h"
@@ -652,15 +653,6 @@ static const struct debugfs_reg32 dsi1_regs[] = {
 	VC4_REG32(DSI1_ID),
 };
 
-static void vc4_dsi_encoder_destroy(struct drm_encoder *encoder)
-{
-	drm_encoder_cleanup(encoder);
-}
-
-static const struct drm_encoder_funcs vc4_dsi_encoder_funcs = {
-	.destroy = vc4_dsi_encoder_destroy,
-};
-
 static void vc4_dsi_latch_ulps(struct vc4_dsi *dsi, bool latch)
 {
 	u32 afec0 = DSI_PORT_READ(PHY_AFEC0);
@@ -1615,8 +1607,7 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data)
 	if (dsi->port == 1)
 		vc4->dsi1 = dsi;
 
-	drm_encoder_init(drm, dsi->encoder, &vc4_dsi_encoder_funcs,
-			 DRM_MODE_ENCODER_DSI, NULL);
+	drm_simple_encoder_init(drm, dsi->encoder, DRM_MODE_ENCODER_DSI);
 	drm_encoder_helper_add(dsi->encoder, &vc4_dsi_encoder_helper_funcs);
 
 	ret = drm_bridge_attach(dsi->encoder, dsi->bridge, NULL, 0);
@@ -1656,7 +1647,7 @@ static void vc4_dsi_unbind(struct device *dev, struct device *master,
 	 * normally.
 	 */
 	list_splice_init(&dsi->bridge_chain, &dsi->encoder->bridge_chain);
-	vc4_dsi_encoder_destroy(dsi->encoder);
+	drm_encoder_cleanup(dsi->encoder);
 
 	if (dsi->port == 1)
 		vc4->dsi1 = NULL;
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 340719238753..625bfcf52dc4 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -34,6 +34,7 @@
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_edid.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 #include <linux/clk.h>
 #include <linux/component.h>
 #include <linux/i2c.h>
@@ -306,15 +307,6 @@ static struct drm_connector *vc4_hdmi_connector_init(struct drm_device *dev,
 	return connector;
 }
 
-static void vc4_hdmi_encoder_destroy(struct drm_encoder *encoder)
-{
-	drm_encoder_cleanup(encoder);
-}
-
-static const struct drm_encoder_funcs vc4_hdmi_encoder_funcs = {
-	.destroy = vc4_hdmi_encoder_destroy,
-};
-
 static int vc4_hdmi_stop_packet(struct drm_encoder *encoder,
 				enum hdmi_infoframe_type type)
 {
@@ -1406,8 +1398,7 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
 	}
 	pm_runtime_enable(dev);
 
-	drm_encoder_init(drm, hdmi->encoder, &vc4_hdmi_encoder_funcs,
-			 DRM_MODE_ENCODER_TMDS, NULL);
+	drm_simple_encoder_init(drm, hdmi->encoder, DRM_MODE_ENCODER_TMDS);
 	drm_encoder_helper_add(hdmi->encoder, &vc4_hdmi_encoder_helper_funcs);
 
 	hdmi->connector =
@@ -1465,7 +1456,7 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
 	vc4_hdmi_connector_destroy(hdmi->connector);
 #endif
 err_destroy_encoder:
-	vc4_hdmi_encoder_destroy(hdmi->encoder);
+	drm_encoder_cleanup(hdmi->encoder);
 err_unprepare_hsm:
 	clk_disable_unprepare(hdmi->hsm_clock);
 	pm_runtime_disable(dev);
@@ -1484,7 +1475,7 @@ static void vc4_hdmi_unbind(struct device *dev, struct device *master,
 
 	cec_unregister_adapter(hdmi->cec_adap);
 	vc4_hdmi_connector_destroy(hdmi->connector);
-	vc4_hdmi_encoder_destroy(hdmi->encoder);
+	drm_encoder_cleanup(hdmi->encoder);
 
 	clk_disable_unprepare(hdmi->hsm_clock);
 	pm_runtime_disable(dev);
diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
index 7402bc768664..bd5b8eb58b18 100644
--- a/drivers/gpu/drm/vc4/vc4_vec.c
+++ b/drivers/gpu/drm/vc4/vc4_vec.c
@@ -17,6 +17,7 @@
 #include <drm/drm_edid.h>
 #include <drm/drm_panel.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 #include <linux/clk.h>
 #include <linux/component.h>
 #include <linux/of_graph.h>
@@ -374,10 +375,6 @@ static struct drm_connector *vc4_vec_connector_init(struct drm_device *dev,
 	return connector;
 }
 
-static const struct drm_encoder_funcs vc4_vec_encoder_funcs = {
-	.destroy = drm_encoder_cleanup,
-};
-
 static void vc4_vec_encoder_disable(struct drm_encoder *encoder)
 {
 	struct vc4_vec_encoder *vc4_vec_encoder = to_vc4_vec_encoder(encoder);
@@ -566,8 +563,7 @@ static int vc4_vec_bind(struct device *dev, struct device *master, void *data)
 
 	pm_runtime_enable(dev);
 
-	drm_encoder_init(drm, vec->encoder, &vc4_vec_encoder_funcs,
-			 DRM_MODE_ENCODER_TVDAC, NULL);
+	drm_simple_encoder_init(drm, vec->encoder, DRM_MODE_ENCODER_TVDAC);
 	drm_encoder_helper_add(vec->encoder, &vc4_vec_encoder_helper_funcs);
 
 	vec->connector = vc4_vec_connector_init(drm, vec);
diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c
index 909eba43664a..ec1a8ebb6f1b 100644
--- a/drivers/gpu/drm/vgem/vgem_drv.c
+++ b/drivers/gpu/drm/vgem/vgem_drv.c
@@ -39,6 +39,7 @@
 #include <drm/drm_drv.h>
 #include <drm/drm_file.h>
 #include <drm/drm_ioctl.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_prime.h>
 
 #include "vgem_drv.h"
@@ -431,9 +432,6 @@ static void vgem_release(struct drm_device *dev)
 	struct vgem_device *vgem = container_of(dev, typeof(*vgem), drm);
 
 	platform_device_unregister(vgem->platform);
-	drm_dev_fini(&vgem->drm);
-
-	kfree(vgem);
 }
 
 static struct drm_driver vgem_driver = {
@@ -489,16 +487,19 @@ static int __init vgem_init(void)
 			   &vgem_device->platform->dev);
 	if (ret)
 		goto out_unregister;
+	drmm_add_final_kfree(&vgem_device->drm, vgem_device);
 
 	/* Final step: expose the device/driver to userspace */
-	ret  = drm_dev_register(&vgem_device->drm, 0);
+	ret = drm_dev_register(&vgem_device->drm, 0);
 	if (ret)
-		goto out_fini;
+		goto out_put;
 
 	return 0;
 
-out_fini:
-	drm_dev_fini(&vgem_device->drm);
+out_put:
+	drm_dev_put(&vgem_device->drm);
+	return ret;
+
 out_unregister:
 	platform_device_unregister(vgem_device->platform);
 out_free:
diff --git a/drivers/gpu/drm/virtio/virtgpu_debugfs.c b/drivers/gpu/drm/virtio/virtgpu_debugfs.c
index e27120d512b0..3221520f61f0 100644
--- a/drivers/gpu/drm/virtio/virtgpu_debugfs.c
+++ b/drivers/gpu/drm/virtio/virtgpu_debugfs.c
@@ -72,11 +72,10 @@ static struct drm_info_list virtio_gpu_debugfs_list[] = {
 
 #define VIRTIO_GPU_DEBUGFS_ENTRIES ARRAY_SIZE(virtio_gpu_debugfs_list)
 
-int
+void
 virtio_gpu_debugfs_init(struct drm_minor *minor)
 {
 	drm_debugfs_create_files(virtio_gpu_debugfs_list,
 				 VIRTIO_GPU_DEBUGFS_ENTRIES,
 				 minor->debugfs_root, minor);
-	return 0;
 }
diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c
index 2b7e6ae65546..cc7fd957a307 100644
--- a/drivers/gpu/drm/virtio/virtgpu_display.c
+++ b/drivers/gpu/drm/virtio/virtgpu_display.c
@@ -30,6 +30,7 @@
 #include <drm/drm_fourcc.h>
 #include <drm/drm_gem_framebuffer_helper.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "virtgpu_drv.h"
 
@@ -240,10 +241,6 @@ static const struct drm_connector_funcs virtio_gpu_connector_funcs = {
 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 };
 
-static const struct drm_encoder_funcs virtio_gpu_enc_funcs = {
-	.destroy = drm_encoder_cleanup,
-};
-
 static int vgdev_output_init(struct virtio_gpu_device *vgdev, int index)
 {
 	struct drm_device *dev = vgdev->ddev;
@@ -276,8 +273,7 @@ static int vgdev_output_init(struct virtio_gpu_device *vgdev, int index)
 	if (vgdev->has_edid)
 		drm_connector_attach_edid_property(connector);
 
-	drm_encoder_init(dev, encoder, &virtio_gpu_enc_funcs,
-			 DRM_MODE_ENCODER_VIRTUAL, NULL);
+	drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_VIRTUAL);
 	drm_encoder_helper_add(encoder, &virtio_gpu_enc_helper_funcs);
 	encoder->possible_crtcs = 1 << index;
 
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h
index c1824bdf2418..49bebdee6d91 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -218,26 +218,18 @@ struct virtio_gpu_fpriv {
 	struct mutex context_lock;
 };
 
-/* virtio_ioctl.c */
+/* virtgpu_ioctl.c */
 #define DRM_VIRTIO_NUM_IOCTLS 10
 extern struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS];
 
-/* virtio_kms.c */
+/* virtgpu_kms.c */
 int virtio_gpu_init(struct drm_device *dev);
 void virtio_gpu_deinit(struct drm_device *dev);
 void virtio_gpu_release(struct drm_device *dev);
 int virtio_gpu_driver_open(struct drm_device *dev, struct drm_file *file);
 void virtio_gpu_driver_postclose(struct drm_device *dev, struct drm_file *file);
 
-/* virtio_gem.c */
-void virtio_gpu_gem_free_object(struct drm_gem_object *gem_obj);
-int virtio_gpu_gem_init(struct virtio_gpu_device *vgdev);
-void virtio_gpu_gem_fini(struct virtio_gpu_device *vgdev);
-int virtio_gpu_gem_create(struct drm_file *file,
-			  struct drm_device *dev,
-			  struct virtio_gpu_object_params *params,
-			  struct drm_gem_object **obj_p,
-			  uint32_t *handle_p);
+/* virtgpu_gem.c */
 int virtio_gpu_gem_object_open(struct drm_gem_object *obj,
 			       struct drm_file *file);
 void virtio_gpu_gem_object_close(struct drm_gem_object *obj,
@@ -263,7 +255,7 @@ void virtio_gpu_array_put_free_delayed(struct virtio_gpu_device *vgdev,
 				       struct virtio_gpu_object_array *objs);
 void virtio_gpu_array_put_free_work(struct work_struct *work);
 
-/* virtio vg */
+/* virtgpu_vq.c */
 int virtio_gpu_alloc_vbufs(struct virtio_gpu_device *vgdev);
 void virtio_gpu_free_vbufs(struct virtio_gpu_device *vgdev);
 void virtio_gpu_cmd_create_resource(struct virtio_gpu_device *vgdev,
@@ -287,10 +279,10 @@ void virtio_gpu_cmd_set_scanout(struct virtio_gpu_device *vgdev,
 				uint32_t scanout_id, uint32_t resource_id,
 				uint32_t width, uint32_t height,
 				uint32_t x, uint32_t y);
-int virtio_gpu_object_attach(struct virtio_gpu_device *vgdev,
-			     struct virtio_gpu_object *obj,
-			     struct virtio_gpu_mem_entry *ents,
-			     unsigned int nents);
+void virtio_gpu_object_attach(struct virtio_gpu_device *vgdev,
+			      struct virtio_gpu_object *obj,
+			      struct virtio_gpu_mem_entry *ents,
+			      unsigned int nents);
 int virtio_gpu_attach_status_page(struct virtio_gpu_device *vgdev);
 int virtio_gpu_detach_status_page(struct virtio_gpu_device *vgdev);
 void virtio_gpu_cursor_ping(struct virtio_gpu_device *vgdev,
@@ -343,17 +335,17 @@ void virtio_gpu_dequeue_fence_func(struct work_struct *work);
 
 void virtio_gpu_notify(struct virtio_gpu_device *vgdev);
 
-/* virtio_gpu_display.c */
+/* virtgpu_display.c */
 void virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev);
 void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev);
 
-/* virtio_gpu_plane.c */
+/* virtgpu_plane.c */
 uint32_t virtio_gpu_translate_format(uint32_t drm_fourcc);
 struct drm_plane *virtio_gpu_plane_init(struct virtio_gpu_device *vgdev,
 					enum drm_plane_type type,
 					int index);
 
-/* virtio_gpu_fence.c */
+/* virtgpu_fence.c */
 struct virtio_gpu_fence *virtio_gpu_fence_alloc(
 	struct virtio_gpu_device *vgdev);
 void virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev,
@@ -362,7 +354,7 @@ void virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev,
 void virtio_gpu_fence_event_process(struct virtio_gpu_device *vdev,
 				    u64 last_seq);
 
-/* virtio_gpu_object */
+/* virtgpu_object.c */
 void virtio_gpu_cleanup_object(struct virtio_gpu_object *bo);
 struct drm_gem_object *virtio_gpu_create_object(struct drm_device *dev,
 						size_t size);
@@ -378,7 +370,7 @@ struct drm_gem_object *virtgpu_gem_prime_import_sg_table(
 	struct drm_device *dev, struct dma_buf_attachment *attach,
 	struct sg_table *sgt);
 
-/* virgl debugfs */
-int virtio_gpu_debugfs_init(struct drm_minor *minor);
+/* virtgpu_debugfs.c */
+void virtio_gpu_debugfs_init(struct drm_minor *minor);
 
 #endif
diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c b/drivers/gpu/drm/virtio/virtgpu_gem.c
index 0d6152c99a27..1025658be4df 100644
--- a/drivers/gpu/drm/virtio/virtgpu_gem.c
+++ b/drivers/gpu/drm/virtio/virtgpu_gem.c
@@ -28,11 +28,11 @@
 
 #include "virtgpu_drv.h"
 
-int virtio_gpu_gem_create(struct drm_file *file,
-			  struct drm_device *dev,
-			  struct virtio_gpu_object_params *params,
-			  struct drm_gem_object **obj_p,
-			  uint32_t *handle_p)
+static int virtio_gpu_gem_create(struct drm_file *file,
+				 struct drm_device *dev,
+				 struct virtio_gpu_object_params *params,
+				 struct drm_gem_object **obj_p,
+				 uint32_t *handle_p)
 {
 	struct virtio_gpu_device *vgdev = dev->dev_private;
 	struct virtio_gpu_object *obj;
@@ -114,7 +114,7 @@ int virtio_gpu_gem_object_open(struct drm_gem_object *obj,
 	struct virtio_gpu_object_array *objs;
 
 	if (!vgdev->has_virgl_3d)
-		return 0;
+		goto out_notify;
 
 	objs = virtio_gpu_array_alloc(1);
 	if (!objs)
@@ -123,6 +123,7 @@ int virtio_gpu_gem_object_open(struct drm_gem_object *obj,
 
 	virtio_gpu_cmd_context_attach_resource(vgdev, vfpriv->ctx_id,
 					       objs);
+out_notify:
 	virtio_gpu_notify(vgdev);
 	return 0;
 }
diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
index 336cc9143205..4625d557862b 100644
--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
@@ -27,6 +27,7 @@
 
 #include <linux/file.h>
 #include <linux/sync_file.h>
+#include <linux/uaccess.h>
 
 #include <drm/drm_file.h>
 #include <drm/virtgpu_drm.h>
@@ -47,7 +48,6 @@ static void virtio_gpu_create_context(struct drm_device *dev,
 	get_task_comm(dbgname, current);
 	virtio_gpu_cmd_context_create(vgdev, vfpriv->ctx_id,
 				      strlen(dbgname), dbgname);
-	virtio_gpu_notify(vgdev);
 	vfpriv->context_created = true;
 
 out_unlock:
diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c
index 023a030ca7b9..f4ea4cef5e23 100644
--- a/drivers/gpu/drm/virtio/virtgpu_kms.c
+++ b/drivers/gpu/drm/virtio/virtgpu_kms.c
@@ -25,6 +25,7 @@
 
 #include <linux/virtio.h>
 #include <linux/virtio_config.h>
+#include <linux/virtio_ring.h>
 
 #include <drm/drm_file.h>
 
diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c
index d9039bb7c5e3..6ccbd01cd888 100644
--- a/drivers/gpu/drm/virtio/virtgpu_object.c
+++ b/drivers/gpu/drm/virtio/virtgpu_object.c
@@ -235,13 +235,8 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev,
 		return ret;
 	}
 
-	ret = virtio_gpu_object_attach(vgdev, bo, ents, nents);
-	if (ret != 0) {
-		virtio_gpu_free_object(&shmem_obj->base);
-		return ret;
-	}
+	virtio_gpu_object_attach(vgdev, bo, ents, nents);
 
-	virtio_gpu_notify(vgdev);
 	*bo_ptr = bo;
 	return 0;
 
diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c
index 73854915ec34..9e663a5d9952 100644
--- a/drivers/gpu/drm/virtio/virtgpu_vq.c
+++ b/drivers/gpu/drm/virtio/virtgpu_vq.c
@@ -1087,14 +1087,13 @@ void virtio_gpu_cmd_submit(struct virtio_gpu_device *vgdev,
 	virtio_gpu_queue_fenced_ctrl_buffer(vgdev, vbuf, fence);
 }
 
-int virtio_gpu_object_attach(struct virtio_gpu_device *vgdev,
-			     struct virtio_gpu_object *obj,
-			     struct virtio_gpu_mem_entry *ents,
-			     unsigned int nents)
+void virtio_gpu_object_attach(struct virtio_gpu_device *vgdev,
+			      struct virtio_gpu_object *obj,
+			      struct virtio_gpu_mem_entry *ents,
+			      unsigned int nents)
 {
 	virtio_gpu_cmd_resource_attach_backing(vgdev, obj->hw_res_handle,
 					       ents, nents, NULL);
-	return 0;
 }
 
 void virtio_gpu_cursor_ping(struct virtio_gpu_device *vgdev,
diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c
index 860de052e820..eef85f1a0ce5 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.c
+++ b/drivers/gpu/drm/vkms/vkms_drv.c
@@ -21,6 +21,7 @@
 #include <drm/drm_file.h>
 #include <drm/drm_gem_framebuffer_helper.h>
 #include <drm/drm_ioctl.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/drm_vblank.h>
 
@@ -63,7 +64,6 @@ static void vkms_release(struct drm_device *dev)
 	platform_device_unregister(vkms->platform);
 	drm_atomic_helper_shutdown(&vkms->drm);
 	drm_mode_config_cleanup(&vkms->drm);
-	drm_dev_fini(&vkms->drm);
 	destroy_workqueue(vkms->output.composer_workq);
 }
 
@@ -158,13 +158,14 @@ static int __init vkms_init(void)
 			   &vkms_device->platform->dev);
 	if (ret)
 		goto out_unregister;
+	drmm_add_final_kfree(&vkms_device->drm, vkms_device);
 
 	ret = dma_coerce_mask_and_coherent(vkms_device->drm.dev,
 					   DMA_BIT_MASK(64));
 
 	if (ret) {
 		DRM_ERROR("Could not initialize DMA support\n");
-		goto out_fini;
+		goto out_put;
 	}
 
 	vkms_device->drm.irq_enabled = true;
@@ -172,25 +173,25 @@ static int __init vkms_init(void)
 	ret = drm_vblank_init(&vkms_device->drm, 1);
 	if (ret) {
 		DRM_ERROR("Failed to vblank\n");
-		goto out_fini;
+		goto out_put;
 	}
 
 	ret = vkms_modeset_init(vkms_device);
 	if (ret)
-		goto out_fini;
+		goto out_put;
 
 	ret = drm_dev_register(&vkms_device->drm, 0);
 	if (ret)
-		goto out_fini;
+		goto out_put;
 
 	return 0;
 
-out_fini:
-	drm_dev_fini(&vkms_device->drm);
+out_put:
+	drm_dev_put(&vkms_device->drm);
+	return ret;
 
 out_unregister:
 	platform_device_unregister(vkms_device->platform);
-
 out_free:
 	kfree(vkms_device);
 	return ret;
@@ -205,8 +206,6 @@ static void __exit vkms_exit(void)
 
 	drm_dev_unregister(&vkms_device->drm);
 	drm_dev_put(&vkms_device->drm);
-
-	kfree(vkms_device);
 }
 
 module_init(vkms_init);
diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c
index fb1941a6522c..85afb77e97f0 100644
--- a/drivers/gpu/drm/vkms/vkms_output.c
+++ b/drivers/gpu/drm/vkms/vkms_output.c
@@ -3,6 +3,7 @@
 #include "vkms_drv.h"
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 
 static void vkms_connector_destroy(struct drm_connector *connector)
 {
@@ -17,10 +18,6 @@ static const struct drm_connector_funcs vkms_connector_funcs = {
 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 };
 
-static const struct drm_encoder_funcs vkms_encoder_funcs = {
-	.destroy = drm_encoder_cleanup,
-};
-
 static int vkms_conn_get_modes(struct drm_connector *connector)
 {
 	int count;
@@ -70,8 +67,7 @@ int vkms_output_init(struct vkms_device *vkmsdev, int index)
 
 	drm_connector_helper_add(connector, &vkms_conn_helper_funcs);
 
-	ret = drm_encoder_init(dev, encoder, &vkms_encoder_funcs,
-			       DRM_MODE_ENCODER_VIRTUAL, NULL);
+	ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_VIRTUAL);
 	if (ret) {
 		DRM_ERROR("Failed to init encoder\n");
 		goto err_encoder;
diff --git a/drivers/gpu/drm/xen/xen_drm_front.c b/drivers/gpu/drm/xen/xen_drm_front.c
index 374142018171..1fd458e877ca 100644
--- a/drivers/gpu/drm/xen/xen_drm_front.c
+++ b/drivers/gpu/drm/xen/xen_drm_front.c
@@ -460,9 +460,6 @@ static void xen_drm_drv_release(struct drm_device *dev)
 	drm_atomic_helper_shutdown(dev);
 	drm_mode_config_cleanup(dev);
 
-	drm_dev_fini(dev);
-	kfree(dev);
-
 	if (front_info->cfg.be_alloc)
 		xenbus_switch_state(front_info->xb_dev,
 				    XenbusStateInitialising);
@@ -561,6 +558,7 @@ static int xen_drm_drv_init(struct xen_drm_front_info *front_info)
 fail_modeset:
 	drm_kms_helper_poll_fini(drm_dev);
 	drm_mode_config_cleanup(drm_dev);
+	drm_dev_put(drm_dev);
 fail:
 	kfree(drm_info);
 	return ret;
diff --git a/drivers/gpu/drm/zte/zx_hdmi.c b/drivers/gpu/drm/zte/zx_hdmi.c
index b98a1420dcd3..76a16d997a23 100644
--- a/drivers/gpu/drm/zte/zx_hdmi.c
+++ b/drivers/gpu/drm/zte/zx_hdmi.c
@@ -20,6 +20,7 @@
 #include <drm/drm_of.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/drm_print.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include <sound/hdmi-codec.h>
 
@@ -254,10 +255,6 @@ static const struct drm_encoder_helper_funcs zx_hdmi_encoder_helper_funcs = {
 	.mode_set = zx_hdmi_encoder_mode_set,
 };
 
-static const struct drm_encoder_funcs zx_hdmi_encoder_funcs = {
-	.destroy = drm_encoder_cleanup,
-};
-
 static int zx_hdmi_connector_get_modes(struct drm_connector *connector)
 {
 	struct zx_hdmi *hdmi = to_zx_hdmi(connector);
@@ -313,8 +310,7 @@ static int zx_hdmi_register(struct drm_device *drm, struct zx_hdmi *hdmi)
 
 	encoder->possible_crtcs = VOU_CRTC_MASK;
 
-	drm_encoder_init(drm, encoder, &zx_hdmi_encoder_funcs,
-			 DRM_MODE_ENCODER_TMDS, NULL);
+	drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
 	drm_encoder_helper_add(encoder, &zx_hdmi_encoder_helper_funcs);
 
 	hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD;
diff --git a/drivers/gpu/drm/zte/zx_tvenc.c b/drivers/gpu/drm/zte/zx_tvenc.c
index c598b7daf1f1..d8a89ba383bc 100644
--- a/drivers/gpu/drm/zte/zx_tvenc.c
+++ b/drivers/gpu/drm/zte/zx_tvenc.c
@@ -14,6 +14,7 @@
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_print.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "zx_drm_drv.h"
 #include "zx_tvenc_regs.h"
@@ -218,10 +219,6 @@ static const struct drm_encoder_helper_funcs zx_tvenc_encoder_helper_funcs = {
 	.mode_set = zx_tvenc_encoder_mode_set,
 };
 
-static const struct drm_encoder_funcs zx_tvenc_encoder_funcs = {
-	.destroy = drm_encoder_cleanup,
-};
-
 static int zx_tvenc_connector_get_modes(struct drm_connector *connector)
 {
 	struct zx_tvenc *tvenc = to_zx_tvenc(connector);
@@ -285,8 +282,7 @@ static int zx_tvenc_register(struct drm_device *drm, struct zx_tvenc *tvenc)
 	 */
 	encoder->possible_crtcs = BIT(1);
 
-	drm_encoder_init(drm, encoder, &zx_tvenc_encoder_funcs,
-			 DRM_MODE_ENCODER_TVDAC, NULL);
+	drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TVDAC);
 	drm_encoder_helper_add(encoder, &zx_tvenc_encoder_helper_funcs);
 
 	connector->interlace_allowed = true;
diff --git a/drivers/gpu/drm/zte/zx_vga.c b/drivers/gpu/drm/zte/zx_vga.c
index c4fa3bbaba78..a7ed7f5ca837 100644
--- a/drivers/gpu/drm/zte/zx_vga.c
+++ b/drivers/gpu/drm/zte/zx_vga.c
@@ -14,6 +14,7 @@
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_print.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "zx_drm_drv.h"
 #include "zx_vga_regs.h"
@@ -72,10 +73,6 @@ static const struct drm_encoder_helper_funcs zx_vga_encoder_helper_funcs = {
 	.disable = zx_vga_encoder_disable,
 };
 
-static const struct drm_encoder_funcs zx_vga_encoder_funcs = {
-	.destroy = drm_encoder_cleanup,
-};
-
 static int zx_vga_connector_get_modes(struct drm_connector *connector)
 {
 	struct zx_vga *vga = to_zx_vga(connector);
@@ -154,8 +151,7 @@ static int zx_vga_register(struct drm_device *drm, struct zx_vga *vga)
 
 	encoder->possible_crtcs = VOU_CRTC_MASK;
 
-	ret = drm_encoder_init(drm, encoder, &zx_vga_encoder_funcs,
-			       DRM_MODE_ENCODER_DAC, NULL);
+	ret = drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_DAC);
 	if (ret) {
 		DRM_DEV_ERROR(dev, "failed to init encoder: %d\n", ret);
 		return ret;
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 7c89edbd6c5a..008bf44bc2c3 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -42,7 +42,7 @@ config HIDRAW
 	---help---
 	Say Y here if you want to support HID devices (from the USB
 	specification standpoint) that aren't strictly user interface
-	devices, like monitor controls and Uninterruptable Power Supplies.
+	devices, like monitor controls and Uninterruptible Power Supplies.
 
 	This module supports these devices separately using a separate
 	event interface on /dev/hidraw.
@@ -538,14 +538,14 @@ config HID_LOGITECH
 	Support for Logitech devices that are not fully compliant with HID standard.
 
 config HID_LOGITECH_DJ
-	tristate "Logitech Unifying receivers full support"
+	tristate "Logitech receivers full support"
 	depends on USB_HID
 	depends on HIDRAW
 	depends on HID_LOGITECH
 	select HID_LOGITECH_HIDPP
 	---help---
-	Say Y if you want support for Logitech Unifying receivers and devices.
-	Unifying receivers are capable of pairing up to 6 Logitech compliant
+	Say Y if you want support for Logitech receivers and devices.
+	Logitech receivers are capable of pairing multiple Logitech compliant
 	devices to the same receiver. Without this driver it will be handled by
 	generic USB_HID driver and all incoming events will be multiplexed
 	into a single mouse and a single keyboard device.
@@ -1140,7 +1140,7 @@ config HID_SENSOR_CUSTOM_SENSOR
 	  to decide how to interpret these special sensor ids and process in
 	  the user space. Currently some manufacturers are using these ids for
 	  sensor calibration and debugging other sensors. Manufacturers
-	  should't use these special custom sensor ids to export any of the
+	  shouldn't use these special custom sensor ids to export any of the
 	  standard sensors.
 	  Select this config option for custom/generic sensor support.
 
diff --git a/drivers/hid/hid-alps.c b/drivers/hid/hid-alps.c
index fa704153cb00..b2ad319a74b9 100644
--- a/drivers/hid/hid-alps.c
+++ b/drivers/hid/hid-alps.c
@@ -802,6 +802,7 @@ static int alps_probe(struct hid_device *hdev, const struct hid_device_id *id)
 		break;
 	case HID_DEVICE_ID_ALPS_U1_DUAL:
 	case HID_DEVICE_ID_ALPS_U1:
+	case HID_DEVICE_ID_ALPS_U1_UNICORN_LEGACY:
 		data->dev_type = U1;
 		break;
 	default:
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index b18b13147a6f..6eb25b9e8575 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -79,10 +79,10 @@
 #define HID_DEVICE_ID_ALPS_U1_DUAL_PTP	0x121F
 #define HID_DEVICE_ID_ALPS_U1_DUAL_3BTN_PTP	0x1220
 #define HID_DEVICE_ID_ALPS_U1		0x1215
+#define HID_DEVICE_ID_ALPS_U1_UNICORN_LEGACY         0x121E
 #define HID_DEVICE_ID_ALPS_T4_BTNLESS	0x120C
 #define HID_DEVICE_ID_ALPS_1222		0x1222
 
-
 #define USB_VENDOR_ID_AMI		0x046b
 #define USB_DEVICE_ID_AMI_VIRT_KEYBOARD_AND_MOUSE	0xff10
 
@@ -385,6 +385,7 @@
 #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7349	0x7349
 #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_73F7	0x73f7
 #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001	0xa001
+#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_C002	0xc002
 
 #define USB_VENDOR_ID_ELAN		0x04f3
 #define USB_DEVICE_ID_TOSHIBA_CLICK_L9W	0x0401
@@ -759,6 +760,7 @@
 #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2	0xc218
 #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2	0xc219
 #define USB_DEVICE_ID_LOGITECH_G15_LCD		0xc222
+#define USB_DEVICE_ID_LOGITECH_G11		0xc225
 #define USB_DEVICE_ID_LOGITECH_G15_V2_LCD	0xc227
 #define USB_DEVICE_ID_LOGITECH_G510		0xc22d
 #define USB_DEVICE_ID_LOGITECH_G510_USB_AUDIO	0xc22e
diff --git a/drivers/hid/hid-lg-g15.c b/drivers/hid/hid-lg-g15.c
index ad4b5412a9f4..ef0cbcd7540d 100644
--- a/drivers/hid/hid-lg-g15.c
+++ b/drivers/hid/hid-lg-g15.c
@@ -872,6 +872,10 @@ static int lg_g15_probe(struct hid_device *hdev, const struct hid_device_id *id)
 }
 
 static const struct hid_device_id lg_g15_devices[] = {
+	/* The G11 is a G15 without the LCD, treat it as a G15 */
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
+		USB_DEVICE_ID_LOGITECH_G11),
+		.driver_data = LG_G15 },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
 			 USB_DEVICE_ID_LOGITECH_G15_LCD),
 		.driver_data = LG_G15 },
diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
index ed9b1c1f460d..48dff5d6b605 100644
--- a/drivers/hid/hid-logitech-dj.c
+++ b/drivers/hid/hid-logitech-dj.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- *  HID driver for Logitech Unifying receivers
+ *  HID driver for Logitech receivers
  *
  *  Copyright (c) 2011 Logitech
  */
@@ -701,7 +701,7 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev,
 			type_str, dj_hiddev->product);
 	} else {
 		snprintf(dj_hiddev->name, sizeof(dj_hiddev->name),
-			"Logitech Unifying Device. Wireless PID:%04x",
+			"Logitech Wireless Device PID:%04x",
 			dj_hiddev->product);
 	}
 
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
index 094f4f1b6555..1e1cf8eae649 100644
--- a/drivers/hid/hid-logitech-hidpp.c
+++ b/drivers/hid/hid-logitech-hidpp.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- *  HIDPP protocol for Logitech Unifying receivers
+ *  HIDPP protocol for Logitech receivers
  *
  *  Copyright (c) 2011 Logitech (c)
  *  Copyright (c) 2012-2013 Google (c)
diff --git a/drivers/hid/hid-mcp2221.c b/drivers/hid/hid-mcp2221.c
index d958475f8c81..e1b93ce32e01 100644
--- a/drivers/hid/hid-mcp2221.c
+++ b/drivers/hid/hid-mcp2221.c
@@ -15,6 +15,7 @@
 #include <linux/hid.h>
 #include <linux/hidraw.h>
 #include <linux/i2c.h>
+#include <linux/gpio/driver.h>
 #include "hid-ids.h"
 
 /* Commands codes in a raw output report */
@@ -27,6 +28,8 @@ enum {
 	MCP2221_I2C_PARAM_OR_STATUS	= 0x10,
 	MCP2221_I2C_SET_SPEED = 0x20,
 	MCP2221_I2C_CANCEL = 0x10,
+	MCP2221_GPIO_SET = 0x50,
+	MCP2221_GPIO_GET = 0x51,
 };
 
 /* Response codes in a raw input report */
@@ -42,6 +45,8 @@ enum {
 	MCP2221_I2C_WRADDRL_SEND = 0x21,
 	MCP2221_I2C_ADDR_NACK = 0x25,
 	MCP2221_I2C_READ_COMPL = 0x55,
+	MCP2221_ALT_F_NOT_GPIOV = 0xEE,
+	MCP2221_ALT_F_NOT_GPIOD = 0xEF,
 };
 
 /*
@@ -59,6 +64,9 @@ struct mcp2221 {
 	int rxbuf_idx;
 	int status;
 	u8 cur_i2c_clk_div;
+	struct gpio_chip *gc;
+	u8 gp_idx;
+	u8 gpio_dir;
 };
 
 /*
@@ -526,6 +534,110 @@ static const struct i2c_algorithm mcp_i2c_algo = {
 	.functionality = mcp_i2c_func,
 };
 
+static int mcp_gpio_get(struct gpio_chip *gc,
+				unsigned int offset)
+{
+	int ret;
+	struct mcp2221 *mcp = gpiochip_get_data(gc);
+
+	mcp->txbuf[0] = MCP2221_GPIO_GET;
+
+	mcp->gp_idx = (offset + 1) * 2;
+
+	mutex_lock(&mcp->lock);
+	ret = mcp_send_data_req_status(mcp, mcp->txbuf, 1);
+	mutex_unlock(&mcp->lock);
+
+	return ret;
+}
+
+static void mcp_gpio_set(struct gpio_chip *gc,
+				unsigned int offset, int value)
+{
+	struct mcp2221 *mcp = gpiochip_get_data(gc);
+
+	memset(mcp->txbuf, 0, 18);
+	mcp->txbuf[0] = MCP2221_GPIO_SET;
+
+	mcp->gp_idx = ((offset + 1) * 4) - 1;
+
+	mcp->txbuf[mcp->gp_idx - 1] = 1;
+	mcp->txbuf[mcp->gp_idx] = !!value;
+
+	mutex_lock(&mcp->lock);
+	mcp_send_data_req_status(mcp, mcp->txbuf, 18);
+	mutex_unlock(&mcp->lock);
+}
+
+static int mcp_gpio_dir_set(struct mcp2221 *mcp,
+				unsigned int offset, u8 val)
+{
+	memset(mcp->txbuf, 0, 18);
+	mcp->txbuf[0] = MCP2221_GPIO_SET;
+
+	mcp->gp_idx = (offset + 1) * 5;
+
+	mcp->txbuf[mcp->gp_idx - 1] = 1;
+	mcp->txbuf[mcp->gp_idx] = val;
+
+	return mcp_send_data_req_status(mcp, mcp->txbuf, 18);
+}
+
+static int mcp_gpio_direction_input(struct gpio_chip *gc,
+				unsigned int offset)
+{
+	int ret;
+	struct mcp2221 *mcp = gpiochip_get_data(gc);
+
+	mutex_lock(&mcp->lock);
+	ret = mcp_gpio_dir_set(mcp, offset, 0);
+	mutex_unlock(&mcp->lock);
+
+	return ret;
+}
+
+static int mcp_gpio_direction_output(struct gpio_chip *gc,
+				unsigned int offset, int value)
+{
+	int ret;
+	struct mcp2221 *mcp = gpiochip_get_data(gc);
+
+	mutex_lock(&mcp->lock);
+	ret = mcp_gpio_dir_set(mcp, offset, 1);
+	mutex_unlock(&mcp->lock);
+
+	/* Can't configure as output, bailout early */
+	if (ret)
+		return ret;
+
+	mcp_gpio_set(gc, offset, value);
+
+	return 0;
+}
+
+static int mcp_gpio_get_direction(struct gpio_chip *gc,
+				unsigned int offset)
+{
+	int ret;
+	struct mcp2221 *mcp = gpiochip_get_data(gc);
+
+	mcp->txbuf[0] = MCP2221_GPIO_GET;
+
+	mcp->gp_idx = (offset + 1) * 2;
+
+	mutex_lock(&mcp->lock);
+	ret = mcp_send_data_req_status(mcp, mcp->txbuf, 1);
+	mutex_unlock(&mcp->lock);
+
+	if (ret)
+		return ret;
+
+	if (mcp->gpio_dir)
+		return GPIO_LINE_DIRECTION_IN;
+
+	return GPIO_LINE_DIRECTION_OUT;
+}
+
 /* Gives current state of i2c engine inside mcp2221 */
 static int mcp_get_i2c_eng_state(struct mcp2221 *mcp,
 				u8 *data, u8 idx)
@@ -638,6 +750,39 @@ static int mcp2221_raw_event(struct hid_device *hdev,
 		complete(&mcp->wait_in_report);
 		break;
 
+	case MCP2221_GPIO_GET:
+		switch (data[1]) {
+		case MCP2221_SUCCESS:
+			if ((data[mcp->gp_idx] == MCP2221_ALT_F_NOT_GPIOV) ||
+				(data[mcp->gp_idx + 1] == MCP2221_ALT_F_NOT_GPIOD)) {
+				mcp->status = -ENOENT;
+			} else {
+				mcp->status = !!data[mcp->gp_idx];
+				mcp->gpio_dir = !!data[mcp->gp_idx + 1];
+			}
+			break;
+		default:
+			mcp->status = -EAGAIN;
+		}
+		complete(&mcp->wait_in_report);
+		break;
+
+	case MCP2221_GPIO_SET:
+		switch (data[1]) {
+		case MCP2221_SUCCESS:
+			if ((data[mcp->gp_idx] == MCP2221_ALT_F_NOT_GPIOV) ||
+				(data[mcp->gp_idx - 1] == MCP2221_ALT_F_NOT_GPIOV)) {
+				mcp->status = -ENOENT;
+			} else {
+				mcp->status = 0;
+			}
+			break;
+		default:
+			mcp->status = -EAGAIN;
+		}
+		complete(&mcp->wait_in_report);
+		break;
+
 	default:
 		mcp->status = -EIO;
 		complete(&mcp->wait_in_report);
@@ -702,8 +847,32 @@ static int mcp2221_probe(struct hid_device *hdev,
 	}
 	i2c_set_adapdata(&mcp->adapter, mcp);
 
+	/* Setup GPIO chip */
+	mcp->gc = devm_kzalloc(&hdev->dev, sizeof(*mcp->gc), GFP_KERNEL);
+	if (!mcp->gc) {
+		ret = -ENOMEM;
+		goto err_gc;
+	}
+
+	mcp->gc->label = "mcp2221_gpio";
+	mcp->gc->direction_input = mcp_gpio_direction_input;
+	mcp->gc->direction_output = mcp_gpio_direction_output;
+	mcp->gc->get_direction = mcp_gpio_get_direction;
+	mcp->gc->set = mcp_gpio_set;
+	mcp->gc->get = mcp_gpio_get;
+	mcp->gc->ngpio = 4;
+	mcp->gc->base = -1;
+	mcp->gc->can_sleep = 1;
+	mcp->gc->parent = &hdev->dev;
+
+	ret = devm_gpiochip_add_data(&hdev->dev, mcp->gc, mcp);
+	if (ret)
+		goto err_gc;
+
 	return 0;
 
+err_gc:
+	i2c_del_adapter(&mcp->adapter);
 err_i2c:
 	hid_hw_close(mcp->hdev);
 err_hstop:
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 362805ddf377..03c720b47306 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -1922,6 +1922,9 @@ static const struct hid_device_id mt_devices[] = {
 	{ .driver_data = MT_CLS_EGALAX_SERIAL,
 		MT_USB_DEVICE(USB_VENDOR_ID_DWAV,
 			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001) },
+	{ .driver_data = MT_CLS_EGALAX,
+		MT_USB_DEVICE(USB_VENDOR_ID_DWAV,
+			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_C002) },
 
 	/* Elitegroup panel */
 	{ .driver_data = MT_CLS_SERIAL,
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
index 5ded94b7bf68..cd71e7133944 100644
--- a/drivers/hid/wacom_sys.c
+++ b/drivers/hid/wacom_sys.c
@@ -319,9 +319,11 @@ static void wacom_feature_mapping(struct hid_device *hdev,
 			data[0] = field->report->id;
 			ret = wacom_get_report(hdev, HID_FEATURE_REPORT,
 					       data, n, WAC_CMD_RETRIES);
-			if (ret == n) {
+			if (ret == n && features->type == HID_GENERIC) {
 				ret = hid_report_raw_event(hdev,
 					HID_FEATURE_REPORT, data, n, 0);
+			} else if (ret == 2 && features->type != HID_GENERIC) {
+				features->touch_max = data[1];
 			} else {
 				features->touch_max = 16;
 				hid_warn(hdev, "wacom_feature_mapping: "
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index d99a9d407671..96d00eba99c0 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -2637,9 +2637,25 @@ static void wacom_wac_finger_pre_report(struct hid_device *hdev,
 			case HID_DG_TIPSWITCH:
 				hid_data->last_slot_field = equivalent_usage;
 				break;
+			case HID_DG_CONTACTCOUNT:
+				hid_data->cc_report = report->id;
+				hid_data->cc_index = i;
+				hid_data->cc_value_index = j;
+				break;
 			}
 		}
 	}
+
+	if (hid_data->cc_report != 0 &&
+	    hid_data->cc_index >= 0) {
+		struct hid_field *field = report->field[hid_data->cc_index];
+		int value = field->value[hid_data->cc_value_index];
+		if (value)
+			hid_data->num_expected = value;
+	}
+	else {
+		hid_data->num_expected = wacom_wac->features.touch_max;
+	}
 }
 
 static void wacom_wac_finger_report(struct hid_device *hdev,
@@ -2649,7 +2665,6 @@ static void wacom_wac_finger_report(struct hid_device *hdev,
 	struct wacom_wac *wacom_wac = &wacom->wacom_wac;
 	struct input_dev *input = wacom_wac->touch_input;
 	unsigned touch_max = wacom_wac->features.touch_max;
-	struct hid_data *hid_data = &wacom_wac->hid_data;
 
 	/* If more packets of data are expected, give us a chance to
 	 * process them rather than immediately syncing a partial
@@ -2663,7 +2678,6 @@ static void wacom_wac_finger_report(struct hid_device *hdev,
 
 	input_sync(input);
 	wacom_wac->hid_data.num_received = 0;
-	hid_data->num_expected = 0;
 
 	/* keep touch state for pen event */
 	wacom_wac->shared->touch_down = wacom_wac_finger_count_touches(wacom_wac);
@@ -2738,73 +2752,12 @@ static void wacom_report_events(struct hid_device *hdev,
 	}
 }
 
-static void wacom_set_num_expected(struct hid_device *hdev,
-				   struct hid_report *report,
-				   int collection_index,
-				   struct hid_field *field,
-				   int field_index)
-{
-	struct wacom *wacom = hid_get_drvdata(hdev);
-	struct wacom_wac *wacom_wac = &wacom->wacom_wac;
-	struct hid_data *hid_data = &wacom_wac->hid_data;
-	unsigned int original_collection_level =
-		hdev->collection[collection_index].level;
-	bool end_collection = false;
-	int i;
-
-	if (hid_data->num_expected)
-		return;
-
-	// find the contact count value for this segment
-	for (i = field_index; i < report->maxfield && !end_collection; i++) {
-		struct hid_field *field = report->field[i];
-		unsigned int field_level =
-			hdev->collection[field->usage[0].collection_index].level;
-		unsigned int j;
-
-		if (field_level != original_collection_level)
-			continue;
-
-		for (j = 0; j < field->maxusage; j++) {
-			struct hid_usage *usage = &field->usage[j];
-
-			if (usage->collection_index != collection_index) {
-				end_collection = true;
-				break;
-			}
-			if (wacom_equivalent_usage(usage->hid) == HID_DG_CONTACTCOUNT) {
-				hid_data->cc_report = report->id;
-				hid_data->cc_index = i;
-				hid_data->cc_value_index = j;
-
-				if (hid_data->cc_report != 0 &&
-				    hid_data->cc_index >= 0) {
-
-					struct hid_field *field =
-						report->field[hid_data->cc_index];
-					int value =
-						field->value[hid_data->cc_value_index];
-
-					if (value)
-						hid_data->num_expected = value;
-				}
-			}
-		}
-	}
-
-	if (hid_data->cc_report == 0 || hid_data->cc_index < 0)
-		hid_data->num_expected = wacom_wac->features.touch_max;
-}
-
 static int wacom_wac_collection(struct hid_device *hdev, struct hid_report *report,
 			 int collection_index, struct hid_field *field,
 			 int field_index)
 {
 	struct wacom *wacom = hid_get_drvdata(hdev);
 
-	if (WACOM_FINGER_FIELD(field))
-		wacom_set_num_expected(hdev, report, collection_index, field,
-				       field_index);
 	wacom_report_events(hdev, report, collection_index, field_index);
 
 	/*
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index 23f358cb7f49..90070b337c10 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -289,6 +289,34 @@ int vmbus_send_tl_connect_request(const guid_t *shv_guest_servie_id,
 }
 EXPORT_SYMBOL_GPL(vmbus_send_tl_connect_request);
 
+/*
+ * Set/change the vCPU (@target_vp) the channel (@child_relid) will interrupt.
+ *
+ * CHANNELMSG_MODIFYCHANNEL messages are aynchronous.  Also, Hyper-V does not
+ * ACK such messages.  IOW we can't know when the host will stop interrupting
+ * the "old" vCPU and start interrupting the "new" vCPU for the given channel.
+ *
+ * The CHANNELMSG_MODIFYCHANNEL message type is supported since VMBus version
+ * VERSION_WIN10_V4_1.
+ */
+int vmbus_send_modifychannel(u32 child_relid, u32 target_vp)
+{
+	struct vmbus_channel_modifychannel conn_msg;
+	int ret;
+
+	memset(&conn_msg, 0, sizeof(conn_msg));
+	conn_msg.header.msgtype = CHANNELMSG_MODIFYCHANNEL;
+	conn_msg.child_relid = child_relid;
+	conn_msg.target_vp = target_vp;
+
+	ret = vmbus_post_msg(&conn_msg, sizeof(conn_msg), true);
+
+	trace_vmbus_send_modifychannel(&conn_msg, ret);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(vmbus_send_modifychannel);
+
 /*
  * create_gpadl_header - Creates a gpadl for the specified buffer
  */
@@ -594,35 +622,31 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle)
 }
 EXPORT_SYMBOL_GPL(vmbus_teardown_gpadl);
 
-static void reset_channel_cb(void *arg)
-{
-	struct vmbus_channel *channel = arg;
-
-	channel->onchannel_callback = NULL;
-}
-
 void vmbus_reset_channel_cb(struct vmbus_channel *channel)
 {
+	unsigned long flags;
+
 	/*
 	 * vmbus_on_event(), running in the per-channel tasklet, can race
 	 * with vmbus_close_internal() in the case of SMP guest, e.g., when
 	 * the former is accessing channel->inbound.ring_buffer, the latter
 	 * could be freeing the ring_buffer pages, so here we must stop it
 	 * first.
+	 *
+	 * vmbus_chan_sched() might call the netvsc driver callback function
+	 * that ends up scheduling NAPI work that accesses the ring buffer.
+	 * At this point, we have to ensure that any such work is completed
+	 * and that the channel ring buffer is no longer being accessed, cf.
+	 * the calls to napi_disable() in netvsc_device_remove().
 	 */
 	tasklet_disable(&channel->callback_event);
 
-	channel->sc_creation_callback = NULL;
+	/* See the inline comments in vmbus_chan_sched(). */
+	spin_lock_irqsave(&channel->sched_lock, flags);
+	channel->onchannel_callback = NULL;
+	spin_unlock_irqrestore(&channel->sched_lock, flags);
 
-	/* Stop the callback asap */
-	if (channel->target_cpu != get_cpu()) {
-		put_cpu();
-		smp_call_function_single(channel->target_cpu, reset_channel_cb,
-					 channel, true);
-	} else {
-		reset_channel_cb(channel);
-		put_cpu();
-	}
+	channel->sc_creation_callback = NULL;
 
 	/* Re-enable tasklet for use on re-open */
 	tasklet_enable(&channel->callback_event);
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index 0370364169c4..fde806d6525b 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -18,6 +18,7 @@
 #include <linux/module.h>
 #include <linux/completion.h>
 #include <linux/delay.h>
+#include <linux/cpu.h>
 #include <linux/hyperv.h>
 #include <asm/mshyperv.h>
 
@@ -315,11 +316,11 @@ static struct vmbus_channel *alloc_channel(void)
 	if (!channel)
 		return NULL;
 
+	spin_lock_init(&channel->sched_lock);
 	spin_lock_init(&channel->lock);
 	init_completion(&channel->rescind_event);
 
 	INIT_LIST_HEAD(&channel->sc_list);
-	INIT_LIST_HEAD(&channel->percpu_list);
 
 	tasklet_init(&channel->callback_event,
 		     vmbus_on_event, (unsigned long)channel);
@@ -340,23 +341,49 @@ static void free_channel(struct vmbus_channel *channel)
 	kobject_put(&channel->kobj);
 }
 
-static void percpu_channel_enq(void *arg)
+void vmbus_channel_map_relid(struct vmbus_channel *channel)
 {
-	struct vmbus_channel *channel = arg;
-	struct hv_per_cpu_context *hv_cpu
-		= this_cpu_ptr(hv_context.cpu_context);
-
-	list_add_tail_rcu(&channel->percpu_list, &hv_cpu->chan_list);
+	if (WARN_ON(channel->offermsg.child_relid >= MAX_CHANNEL_RELIDS))
+		return;
+	/*
+	 * The mapping of the channel's relid is visible from the CPUs that
+	 * execute vmbus_chan_sched() by the time that vmbus_chan_sched() will
+	 * execute:
+	 *
+	 *  (a) In the "normal (i.e., not resuming from hibernation)" path,
+	 *      the full barrier in smp_store_mb() guarantees that the store
+	 *      is propagated to all CPUs before the add_channel_work work
+	 *      is queued.  In turn, add_channel_work is queued before the
+	 *      channel's ring buffer is allocated/initialized and the
+	 *      OPENCHANNEL message for the channel is sent in vmbus_open().
+	 *      Hyper-V won't start sending the interrupts for the channel
+	 *      before the OPENCHANNEL message is acked.  The memory barrier
+	 *      in vmbus_chan_sched() -> sync_test_and_clear_bit() ensures
+	 *      that vmbus_chan_sched() must find the channel's relid in
+	 *      recv_int_page before retrieving the channel pointer from the
+	 *      array of channels.
+	 *
+	 *  (b) In the "resuming from hibernation" path, the smp_store_mb()
+	 *      guarantees that the store is propagated to all CPUs before
+	 *      the VMBus connection is marked as ready for the resume event
+	 *      (cf. check_ready_for_resume_event()).  The interrupt handler
+	 *      of the VMBus driver and vmbus_chan_sched() can not run before
+	 *      vmbus_bus_resume() has completed execution (cf. resume_noirq).
+	 */
+	smp_store_mb(
+		vmbus_connection.channels[channel->offermsg.child_relid],
+		channel);
 }
 
-static void percpu_channel_deq(void *arg)
+void vmbus_channel_unmap_relid(struct vmbus_channel *channel)
 {
-	struct vmbus_channel *channel = arg;
-
-	list_del_rcu(&channel->percpu_list);
+	if (WARN_ON(channel->offermsg.child_relid >= MAX_CHANNEL_RELIDS))
+		return;
+	WRITE_ONCE(
+		vmbus_connection.channels[channel->offermsg.child_relid],
+		NULL);
 }
 
-
 static void vmbus_release_relid(u32 relid)
 {
 	struct vmbus_channel_relid_released msg;
@@ -373,40 +400,37 @@ static void vmbus_release_relid(u32 relid)
 
 void hv_process_channel_removal(struct vmbus_channel *channel)
 {
-	struct vmbus_channel *primary_channel;
 	unsigned long flags;
 
-	BUG_ON(!mutex_is_locked(&vmbus_connection.channel_mutex));
+	lockdep_assert_held(&vmbus_connection.channel_mutex);
 	BUG_ON(!channel->rescind);
 
-	if (channel->target_cpu != get_cpu()) {
-		put_cpu();
-		smp_call_function_single(channel->target_cpu,
-					 percpu_channel_deq, channel, true);
-	} else {
-		percpu_channel_deq(channel);
-		put_cpu();
-	}
+	/*
+	 * hv_process_channel_removal() could find INVALID_RELID only for
+	 * hv_sock channels.  See the inline comments in vmbus_onoffer().
+	 */
+	WARN_ON(channel->offermsg.child_relid == INVALID_RELID &&
+		!is_hvsock_channel(channel));
+
+	/*
+	 * Upon suspend, an in-use hv_sock channel is removed from the array of
+	 * channels and the relid is invalidated.  After hibernation, when the
+	 * user-space appplication destroys the channel, it's unnecessary and
+	 * unsafe to remove the channel from the array of channels.  See also
+	 * the inline comments before the call of vmbus_release_relid() below.
+	 */
+	if (channel->offermsg.child_relid != INVALID_RELID)
+		vmbus_channel_unmap_relid(channel);
 
 	if (channel->primary_channel == NULL) {
 		list_del(&channel->listentry);
-
-		primary_channel = channel;
 	} else {
-		primary_channel = channel->primary_channel;
+		struct vmbus_channel *primary_channel = channel->primary_channel;
 		spin_lock_irqsave(&primary_channel->lock, flags);
 		list_del(&channel->sc_list);
 		spin_unlock_irqrestore(&primary_channel->lock, flags);
 	}
 
-	/*
-	 * We need to free the bit for init_vp_index() to work in the case
-	 * of sub-channel, when we reload drivers like hv_netvsc.
-	 */
-	if (channel->affinity_policy == HV_LOCALIZED)
-		cpumask_clear_cpu(channel->target_cpu,
-				  &primary_channel->alloced_cpus_in_node);
-
 	/*
 	 * Upon suspend, an in-use hv_sock channel is marked as "rescinded" and
 	 * the relid is invalidated; after hibernation, when the user-space app
@@ -440,23 +464,8 @@ static void vmbus_add_channel_work(struct work_struct *work)
 		container_of(work, struct vmbus_channel, add_channel_work);
 	struct vmbus_channel *primary_channel = newchannel->primary_channel;
 	unsigned long flags;
-	u16 dev_type;
 	int ret;
 
-	dev_type = hv_get_dev_type(newchannel);
-
-	init_vp_index(newchannel, dev_type);
-
-	if (newchannel->target_cpu != get_cpu()) {
-		put_cpu();
-		smp_call_function_single(newchannel->target_cpu,
-					 percpu_channel_enq,
-					 newchannel, true);
-	} else {
-		percpu_channel_enq(newchannel);
-		put_cpu();
-	}
-
 	/*
 	 * This state is used to indicate a successful open
 	 * so that when we do close the channel normally, we
@@ -488,7 +497,7 @@ static void vmbus_add_channel_work(struct work_struct *work)
 	if (!newchannel->device_obj)
 		goto err_deq_chan;
 
-	newchannel->device_obj->device_id = dev_type;
+	newchannel->device_obj->device_id = hv_get_dev_type(newchannel);
 	/*
 	 * Add the new device to the bus. This will kick off device-driver
 	 * binding which eventually invokes the device driver's AddDevice()
@@ -523,17 +532,10 @@ static void vmbus_add_channel_work(struct work_struct *work)
 		spin_unlock_irqrestore(&primary_channel->lock, flags);
 	}
 
-	mutex_unlock(&vmbus_connection.channel_mutex);
+	/* vmbus_process_offer() has mapped the channel. */
+	vmbus_channel_unmap_relid(newchannel);
 
-	if (newchannel->target_cpu != get_cpu()) {
-		put_cpu();
-		smp_call_function_single(newchannel->target_cpu,
-					 percpu_channel_deq,
-					 newchannel, true);
-	} else {
-		percpu_channel_deq(newchannel);
-		put_cpu();
-	}
+	mutex_unlock(&vmbus_connection.channel_mutex);
 
 	vmbus_release_relid(newchannel->offermsg.child_relid);
 
@@ -551,6 +553,25 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
 	unsigned long flags;
 	bool fnew = true;
 
+	/*
+	 * Initialize the target_CPU before inserting the channel in
+	 * the chn_list and sc_list lists, within the channel_mutex
+	 * critical section:
+	 *
+	 * CPU1				CPU2
+	 *
+	 * [vmbus_process_offer()]	[hv_syninc_cleanup()]
+	 *
+	 * STORE target_cpu		LOCK channel_mutex
+	 * LOCK channel_mutex		SEARCH chn_list
+	 * INSERT chn_list		LOAD target_cpu
+	 * UNLOCK channel_mutex		UNLOCK channel_mutex
+	 *
+	 * Forbids: CPU2's SEARCH from seeing CPU1's INSERT &&
+	 * 		CPU2's LOAD from *not* seing CPU1's STORE
+	 */
+	init_vp_index(newchannel, hv_get_dev_type(newchannel));
+
 	mutex_lock(&vmbus_connection.channel_mutex);
 
 	/* Remember the channels that should be cleaned up upon suspend. */
@@ -599,6 +620,8 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
 		spin_unlock_irqrestore(&channel->lock, flags);
 	}
 
+	vmbus_channel_map_relid(newchannel);
+
 	mutex_unlock(&vmbus_connection.channel_mutex);
 
 	/*
@@ -643,62 +666,64 @@ static DEFINE_SPINLOCK(bind_channel_to_cpu_lock);
 /*
  * Starting with Win8, we can statically distribute the incoming
  * channel interrupt load by binding a channel to VCPU.
- * We distribute the interrupt loads to one or more NUMA nodes based on
- * the channel's affinity_policy.
  *
  * For pre-win8 hosts or non-performance critical channels we assign the
- * first CPU in the first NUMA node.
+ * VMBUS_CONNECT_CPU.
+ *
+ * Starting with win8, performance critical channels will be distributed
+ * evenly among all the available NUMA nodes.  Once the node is assigned,
+ * we will assign the CPU based on a simple round robin scheme.
  */
 static void init_vp_index(struct vmbus_channel *channel, u16 dev_type)
 {
-	u32 cur_cpu;
 	bool perf_chn = vmbus_devs[dev_type].perf_device;
-	struct vmbus_channel *primary = channel->primary_channel;
-	int next_node;
 	cpumask_var_t available_mask;
 	struct cpumask *alloced_mask;
+	u32 target_cpu;
+	int numa_node;
 
 	if ((vmbus_proto_version == VERSION_WS2008) ||
 	    (vmbus_proto_version == VERSION_WIN7) || (!perf_chn) ||
 	    !alloc_cpumask_var(&available_mask, GFP_KERNEL)) {
 		/*
 		 * Prior to win8, all channel interrupts are
-		 * delivered on cpu 0.
+		 * delivered on VMBUS_CONNECT_CPU.
 		 * Also if the channel is not a performance critical
-		 * channel, bind it to cpu 0.
-		 * In case alloc_cpumask_var() fails, bind it to cpu 0.
+		 * channel, bind it to VMBUS_CONNECT_CPU.
+		 * In case alloc_cpumask_var() fails, bind it to
+		 * VMBUS_CONNECT_CPU.
 		 */
-		channel->numa_node = 0;
-		channel->target_cpu = 0;
-		channel->target_vp = hv_cpu_number_to_vp_number(0);
+		channel->numa_node = cpu_to_node(VMBUS_CONNECT_CPU);
+		channel->target_cpu = VMBUS_CONNECT_CPU;
+		channel->target_vp =
+			hv_cpu_number_to_vp_number(VMBUS_CONNECT_CPU);
 		return;
 	}
 
-	spin_lock(&bind_channel_to_cpu_lock);
+	/* No CPUs can come up or down during this. */
+	cpus_read_lock();
 
 	/*
-	 * Based on the channel affinity policy, we will assign the NUMA
-	 * nodes.
+	 * Serializes the accesses to the global variable next_numa_node_id.
+	 * See also the header comment of the spin lock declaration.
 	 */
+	spin_lock(&bind_channel_to_cpu_lock);
 
-	if ((channel->affinity_policy == HV_BALANCED) || (!primary)) {
-		while (true) {
-			next_node = next_numa_node_id++;
-			if (next_node == nr_node_ids) {
-				next_node = next_numa_node_id = 0;
-				continue;
-			}
-			if (cpumask_empty(cpumask_of_node(next_node)))
-				continue;
-			break;
+	while (true) {
+		numa_node = next_numa_node_id++;
+		if (numa_node == nr_node_ids) {
+			next_numa_node_id = 0;
+			continue;
 		}
-		channel->numa_node = next_node;
-		primary = channel;
+		if (cpumask_empty(cpumask_of_node(numa_node)))
+			continue;
+		break;
 	}
-	alloced_mask = &hv_context.hv_numa_map[primary->numa_node];
+	channel->numa_node = numa_node;
+	alloced_mask = &hv_context.hv_numa_map[numa_node];
 
 	if (cpumask_weight(alloced_mask) ==
-	    cpumask_weight(cpumask_of_node(primary->numa_node))) {
+	    cpumask_weight(cpumask_of_node(numa_node))) {
 		/*
 		 * We have cycled through all the CPUs in the node;
 		 * reset the alloced map.
@@ -706,59 +731,16 @@ static void init_vp_index(struct vmbus_channel *channel, u16 dev_type)
 		cpumask_clear(alloced_mask);
 	}
 
-	cpumask_xor(available_mask, alloced_mask,
-		    cpumask_of_node(primary->numa_node));
-
-	cur_cpu = -1;
+	cpumask_xor(available_mask, alloced_mask, cpumask_of_node(numa_node));
 
-	if (primary->affinity_policy == HV_LOCALIZED) {
-		/*
-		 * Normally Hyper-V host doesn't create more subchannels
-		 * than there are VCPUs on the node but it is possible when not
-		 * all present VCPUs on the node are initialized by guest.
-		 * Clear the alloced_cpus_in_node to start over.
-		 */
-		if (cpumask_equal(&primary->alloced_cpus_in_node,
-				  cpumask_of_node(primary->numa_node)))
-			cpumask_clear(&primary->alloced_cpus_in_node);
-	}
+	target_cpu = cpumask_first(available_mask);
+	cpumask_set_cpu(target_cpu, alloced_mask);
 
-	while (true) {
-		cur_cpu = cpumask_next(cur_cpu, available_mask);
-		if (cur_cpu >= nr_cpu_ids) {
-			cur_cpu = -1;
-			cpumask_copy(available_mask,
-				     cpumask_of_node(primary->numa_node));
-			continue;
-		}
-
-		if (primary->affinity_policy == HV_LOCALIZED) {
-			/*
-			 * NOTE: in the case of sub-channel, we clear the
-			 * sub-channel related bit(s) in
-			 * primary->alloced_cpus_in_node in
-			 * hv_process_channel_removal(), so when we
-			 * reload drivers like hv_netvsc in SMP guest, here
-			 * we're able to re-allocate
-			 * bit from primary->alloced_cpus_in_node.
-			 */
-			if (!cpumask_test_cpu(cur_cpu,
-					      &primary->alloced_cpus_in_node)) {
-				cpumask_set_cpu(cur_cpu,
-						&primary->alloced_cpus_in_node);
-				cpumask_set_cpu(cur_cpu, alloced_mask);
-				break;
-			}
-		} else {
-			cpumask_set_cpu(cur_cpu, alloced_mask);
-			break;
-		}
-	}
-
-	channel->target_cpu = cur_cpu;
-	channel->target_vp = hv_cpu_number_to_vp_number(cur_cpu);
+	channel->target_cpu = target_cpu;
+	channel->target_vp = hv_cpu_number_to_vp_number(target_cpu);
 
 	spin_unlock(&bind_channel_to_cpu_lock);
+	cpus_read_unlock();
 
 	free_cpumask_var(available_mask);
 }
@@ -839,6 +821,9 @@ void vmbus_initiate_unload(bool crash)
 {
 	struct vmbus_channel_message_header hdr;
 
+	if (xchg(&vmbus_connection.conn_state, DISCONNECTED) == DISCONNECTED)
+		return;
+
 	/* Pre-Win2012R2 hosts don't support reconnect */
 	if (vmbus_proto_version < VERSION_WIN8_1)
 		return;
@@ -937,8 +922,6 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr)
 	oldchannel = find_primary_channel_by_offer(offer);
 
 	if (oldchannel != NULL) {
-		atomic_dec(&vmbus_connection.offer_in_progress);
-
 		/*
 		 * We're resuming from hibernation: all the sub-channel and
 		 * hv_sock channels we had before the hibernation should have
@@ -946,36 +929,65 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr)
 		 * primary channel that we had before the hibernation.
 		 */
 
+		/*
+		 * { Initially: channel relid = INVALID_RELID,
+		 *		channels[valid_relid] = NULL }
+		 *
+		 * CPU1					CPU2
+		 *
+		 * [vmbus_onoffer()]			[vmbus_device_release()]
+		 *
+		 * LOCK channel_mutex			LOCK channel_mutex
+		 * STORE channel relid = valid_relid	LOAD r1 = channel relid
+		 * MAP_RELID channel			if (r1 != INVALID_RELID)
+		 * UNLOCK channel_mutex			  UNMAP_RELID channel
+		 *					UNLOCK channel_mutex
+		 *
+		 * Forbids: r1 == valid_relid &&
+		 * 		channels[valid_relid] == channel
+		 *
+		 * Note.  r1 can be INVALID_RELID only for an hv_sock channel.
+		 * None of the hv_sock channels which were present before the
+		 * suspend are re-offered upon the resume.  See the WARN_ON()
+		 * in hv_process_channel_removal().
+		 */
+		mutex_lock(&vmbus_connection.channel_mutex);
+
+		atomic_dec(&vmbus_connection.offer_in_progress);
+
 		WARN_ON(oldchannel->offermsg.child_relid != INVALID_RELID);
 		/* Fix up the relid. */
 		oldchannel->offermsg.child_relid = offer->child_relid;
 
 		offer_sz = sizeof(*offer);
-		if (memcmp(offer, &oldchannel->offermsg, offer_sz) == 0) {
-			check_ready_for_resume_event();
-			return;
+		if (memcmp(offer, &oldchannel->offermsg, offer_sz) != 0) {
+			/*
+			 * This is not an error, since the host can also change
+			 * the other field(s) of the offer, e.g. on WS RS5
+			 * (Build 17763), the offer->connection_id of the
+			 * Mellanox VF vmbus device can change when the host
+			 * reoffers the device upon resume.
+			 */
+			pr_debug("vmbus offer changed: relid=%d\n",
+				 offer->child_relid);
+
+			print_hex_dump_debug("Old vmbus offer: ",
+					     DUMP_PREFIX_OFFSET, 16, 4,
+					     &oldchannel->offermsg, offer_sz,
+					     false);
+			print_hex_dump_debug("New vmbus offer: ",
+					     DUMP_PREFIX_OFFSET, 16, 4,
+					     offer, offer_sz, false);
+
+			/* Fix up the old channel. */
+			vmbus_setup_channel_state(oldchannel, offer);
 		}
 
-		/*
-		 * This is not an error, since the host can also change the
-		 * other field(s) of the offer, e.g. on WS RS5 (Build 17763),
-		 * the offer->connection_id of the Mellanox VF vmbus device
-		 * can change when the host reoffers the device upon resume.
-		 */
-		pr_debug("vmbus offer changed: relid=%d\n",
-			 offer->child_relid);
-
-		print_hex_dump_debug("Old vmbus offer: ", DUMP_PREFIX_OFFSET,
-				     16, 4, &oldchannel->offermsg, offer_sz,
-				     false);
-		print_hex_dump_debug("New vmbus offer: ", DUMP_PREFIX_OFFSET,
-				     16, 4, offer, offer_sz, false);
-
-		/* Fix up the old channel. */
-		vmbus_setup_channel_state(oldchannel, offer);
-
+		/* Add the channel back to the array of channels. */
+		vmbus_channel_map_relid(oldchannel);
 		check_ready_for_resume_event();
 
+		mutex_unlock(&vmbus_connection.channel_mutex);
 		return;
 	}
 
@@ -1025,11 +1037,22 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
 	 * offer comes in first and then the rescind.
 	 * Since we process these events in work elements,
 	 * and with preemption, we may end up processing
-	 * the events out of order. Given that we handle these
-	 * work elements on the same CPU, this is possible only
-	 * in the case of preemption. In any case wait here
-	 * until the offer processing has moved beyond the
-	 * point where the channel is discoverable.
+	 * the events out of order.  We rely on the synchronization
+	 * provided by offer_in_progress and by channel_mutex for
+	 * ordering these events:
+	 *
+	 * { Initially: offer_in_progress = 1 }
+	 *
+	 * CPU1				CPU2
+	 *
+	 * [vmbus_onoffer()]		[vmbus_onoffer_rescind()]
+	 *
+	 * LOCK channel_mutex		WAIT_ON offer_in_progress == 0
+	 * DECREMENT offer_in_progress	LOCK channel_mutex
+	 * STORE channels[]		LOAD channels[]
+	 * UNLOCK channel_mutex		UNLOCK channel_mutex
+	 *
+	 * Forbids: CPU2's LOAD from *not* seeing CPU1's STORE
 	 */
 
 	while (atomic_read(&vmbus_connection.offer_in_progress) != 0) {
@@ -1329,30 +1352,36 @@ static void vmbus_onversion_response(
 /* Channel message dispatch table */
 const struct vmbus_channel_message_table_entry
 channel_message_table[CHANNELMSG_COUNT] = {
-	{ CHANNELMSG_INVALID,			0, NULL },
-	{ CHANNELMSG_OFFERCHANNEL,		0, vmbus_onoffer },
-	{ CHANNELMSG_RESCIND_CHANNELOFFER,	0, vmbus_onoffer_rescind },
-	{ CHANNELMSG_REQUESTOFFERS,		0, NULL },
-	{ CHANNELMSG_ALLOFFERS_DELIVERED,	1, vmbus_onoffers_delivered },
-	{ CHANNELMSG_OPENCHANNEL,		0, NULL },
-	{ CHANNELMSG_OPENCHANNEL_RESULT,	1, vmbus_onopen_result },
-	{ CHANNELMSG_CLOSECHANNEL,		0, NULL },
-	{ CHANNELMSG_GPADL_HEADER,		0, NULL },
-	{ CHANNELMSG_GPADL_BODY,		0, NULL },
-	{ CHANNELMSG_GPADL_CREATED,		1, vmbus_ongpadl_created },
-	{ CHANNELMSG_GPADL_TEARDOWN,		0, NULL },
-	{ CHANNELMSG_GPADL_TORNDOWN,		1, vmbus_ongpadl_torndown },
-	{ CHANNELMSG_RELID_RELEASED,		0, NULL },
-	{ CHANNELMSG_INITIATE_CONTACT,		0, NULL },
-	{ CHANNELMSG_VERSION_RESPONSE,		1, vmbus_onversion_response },
-	{ CHANNELMSG_UNLOAD,			0, NULL },
-	{ CHANNELMSG_UNLOAD_RESPONSE,		1, vmbus_unload_response },
-	{ CHANNELMSG_18,			0, NULL },
-	{ CHANNELMSG_19,			0, NULL },
-	{ CHANNELMSG_20,			0, NULL },
-	{ CHANNELMSG_TL_CONNECT_REQUEST,	0, NULL },
-	{ CHANNELMSG_22,			0, NULL },
-	{ CHANNELMSG_TL_CONNECT_RESULT,		0, NULL },
+	{ CHANNELMSG_INVALID,			0, NULL, 0},
+	{ CHANNELMSG_OFFERCHANNEL,		0, vmbus_onoffer,
+		sizeof(struct vmbus_channel_offer_channel)},
+	{ CHANNELMSG_RESCIND_CHANNELOFFER,	0, vmbus_onoffer_rescind,
+		sizeof(struct vmbus_channel_rescind_offer) },
+	{ CHANNELMSG_REQUESTOFFERS,		0, NULL, 0},
+	{ CHANNELMSG_ALLOFFERS_DELIVERED,	1, vmbus_onoffers_delivered, 0},
+	{ CHANNELMSG_OPENCHANNEL,		0, NULL, 0},
+	{ CHANNELMSG_OPENCHANNEL_RESULT,	1, vmbus_onopen_result,
+		sizeof(struct vmbus_channel_open_result)},
+	{ CHANNELMSG_CLOSECHANNEL,		0, NULL, 0},
+	{ CHANNELMSG_GPADL_HEADER,		0, NULL, 0},
+	{ CHANNELMSG_GPADL_BODY,		0, NULL, 0},
+	{ CHANNELMSG_GPADL_CREATED,		1, vmbus_ongpadl_created,
+		sizeof(struct vmbus_channel_gpadl_created)},
+	{ CHANNELMSG_GPADL_TEARDOWN,		0, NULL, 0},
+	{ CHANNELMSG_GPADL_TORNDOWN,		1, vmbus_ongpadl_torndown,
+		sizeof(struct vmbus_channel_gpadl_torndown) },
+	{ CHANNELMSG_RELID_RELEASED,		0, NULL, 0},
+	{ CHANNELMSG_INITIATE_CONTACT,		0, NULL, 0},
+	{ CHANNELMSG_VERSION_RESPONSE,		1, vmbus_onversion_response,
+		sizeof(struct vmbus_channel_version_response)},
+	{ CHANNELMSG_UNLOAD,			0, NULL, 0},
+	{ CHANNELMSG_UNLOAD_RESPONSE,		1, vmbus_unload_response, 0},
+	{ CHANNELMSG_18,			0, NULL, 0},
+	{ CHANNELMSG_19,			0, NULL, 0},
+	{ CHANNELMSG_20,			0, NULL, 0},
+	{ CHANNELMSG_TL_CONNECT_REQUEST,	0, NULL, 0},
+	{ CHANNELMSG_MODIFYCHANNEL,		0, NULL, 0},
+	{ CHANNELMSG_TL_CONNECT_RESULT,		0, NULL, 0},
 };
 
 /*
@@ -1360,13 +1389,8 @@ channel_message_table[CHANNELMSG_COUNT] = {
  *
  * This is invoked in the vmbus worker thread context.
  */
-void vmbus_onmessage(void *context)
+void vmbus_onmessage(struct vmbus_channel_message_header *hdr)
 {
-	struct hv_message *msg = context;
-	struct vmbus_channel_message_header *hdr;
-
-	hdr = (struct vmbus_channel_message_header *)msg->u.payload;
-
 	trace_vmbus_on_message(hdr);
 
 	/*
diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
index 74e77de89b4f..11170d9a2e1a 100644
--- a/drivers/hv/connection.c
+++ b/drivers/hv/connection.c
@@ -69,7 +69,6 @@ MODULE_PARM_DESC(max_version,
 int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo, u32 version)
 {
 	int ret = 0;
-	unsigned int cur_cpu;
 	struct vmbus_channel_initiate_contact *msg;
 	unsigned long flags;
 
@@ -102,24 +101,7 @@ int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo, u32 version)
 
 	msg->monitor_page1 = virt_to_phys(vmbus_connection.monitor_pages[0]);
 	msg->monitor_page2 = virt_to_phys(vmbus_connection.monitor_pages[1]);
-	/*
-	 * We want all channel messages to be delivered on CPU 0.
-	 * This has been the behavior pre-win8. This is not
-	 * perf issue and having all channel messages delivered on CPU 0
-	 * would be ok.
-	 * For post win8 hosts, we support receiving channel messagges on
-	 * all the CPUs. This is needed for kexec to work correctly where
-	 * the CPU attempting to connect may not be CPU 0.
-	 */
-	if (version >= VERSION_WIN8_1) {
-		cur_cpu = get_cpu();
-		msg->target_vcpu = hv_cpu_number_to_vp_number(cur_cpu);
-		vmbus_connection.connect_cpu = cur_cpu;
-		put_cpu();
-	} else {
-		msg->target_vcpu = 0;
-		vmbus_connection.connect_cpu = 0;
-	}
+	msg->target_vcpu = hv_cpu_number_to_vp_number(VMBUS_CONNECT_CPU);
 
 	/*
 	 * Add to list before we send the request since we may
@@ -266,6 +248,14 @@ int vmbus_connect(void)
 	pr_info("Vmbus version:%d.%d\n",
 		version >> 16, version & 0xFFFF);
 
+	vmbus_connection.channels = kcalloc(MAX_CHANNEL_RELIDS,
+					    sizeof(struct vmbus_channel *),
+					    GFP_KERNEL);
+	if (vmbus_connection.channels == NULL) {
+		ret = -ENOMEM;
+		goto cleanup;
+	}
+
 	kfree(msginfo);
 	return 0;
 
@@ -313,33 +303,9 @@ void vmbus_disconnect(void)
  */
 struct vmbus_channel *relid2channel(u32 relid)
 {
-	struct vmbus_channel *channel;
-	struct vmbus_channel *found_channel  = NULL;
-	struct list_head *cur, *tmp;
-	struct vmbus_channel *cur_sc;
-
-	BUG_ON(!mutex_is_locked(&vmbus_connection.channel_mutex));
-
-	list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) {
-		if (channel->offermsg.child_relid == relid) {
-			found_channel = channel;
-			break;
-		} else if (!list_empty(&channel->sc_list)) {
-			/*
-			 * Deal with sub-channels.
-			 */
-			list_for_each_safe(cur, tmp, &channel->sc_list) {
-				cur_sc = list_entry(cur, struct vmbus_channel,
-							sc_list);
-				if (cur_sc->offermsg.child_relid == relid) {
-					found_channel = cur_sc;
-					break;
-				}
-			}
-		}
-	}
-
-	return found_channel;
+	if (WARN_ON(relid >= MAX_CHANNEL_RELIDS))
+		return NULL;
+	return READ_ONCE(vmbus_connection.channels[relid]);
 }
 
 /*
diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index 6098e0cbdb4b..188b42b07f07 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -117,8 +117,6 @@ int hv_synic_alloc(void)
 			pr_err("Unable to allocate post msg page\n");
 			goto err;
 		}
-
-		INIT_LIST_HEAD(&hv_cpu->chan_list);
 	}
 
 	return 0;
@@ -249,11 +247,19 @@ int hv_synic_cleanup(unsigned int cpu)
 	bool channel_found = false;
 	unsigned long flags;
 
+	/*
+	 * Hyper-V does not provide a way to change the connect CPU once
+	 * it is set; we must prevent the connect CPU from going offline.
+	 */
+	if (cpu == VMBUS_CONNECT_CPU)
+		return -EBUSY;
+
 	/*
 	 * Search for channels which are bound to the CPU we're about to
-	 * cleanup. In case we find one and vmbus is still connected we need to
-	 * fail, this will effectively prevent CPU offlining. There is no way
-	 * we can re-bind channels to different CPUs for now.
+	 * cleanup.  In case we find one and vmbus is still connected, we
+	 * fail; this will effectively prevent CPU offlining.
+	 *
+	 * TODO: Re-bind the channels to different CPUs.
 	 */
 	mutex_lock(&vmbus_connection.channel_mutex);
 	list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) {
diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c
index 32e3bc0aa665..1c3d7ce19e15 100644
--- a/drivers/hv/hv_balloon.c
+++ b/drivers/hv/hv_balloon.c
@@ -1702,6 +1702,7 @@ static int balloon_probe(struct hv_device *dev,
 	set_online_page_callback(&hv_online_page);
 	init_completion(&dm_device.ol_waitevent);
 	register_memory_notifier(&hv_memory_nb);
+	init_completion(&dm_device.ol_waitevent);
 #endif
 
 	hv_set_drvdata(dev, &dm_device);
diff --git a/drivers/hv/hv_debugfs.c b/drivers/hv/hv_debugfs.c
index 8a2878573582..ccf752b6659a 100644
--- a/drivers/hv/hv_debugfs.c
+++ b/drivers/hv/hv_debugfs.c
@@ -11,7 +11,7 @@
 
 #include "hyperv_vmbus.h"
 
-struct dentry *hv_debug_root;
+static struct dentry *hv_debug_root;
 
 static int hv_debugfs_delay_get(void *data, u64 *val)
 {
diff --git a/drivers/hv/hv_fcopy.c b/drivers/hv/hv_fcopy.c
index bb9ba3f7c794..5040d7e0cd9e 100644
--- a/drivers/hv/hv_fcopy.c
+++ b/drivers/hv/hv_fcopy.c
@@ -71,7 +71,7 @@ static void fcopy_poll_wrapper(void *channel)
 {
 	/* Transaction is finished, reset the state here to avoid races. */
 	fcopy_transaction.state = HVUTIL_READY;
-	hv_fcopy_onchannelcallback(channel);
+	tasklet_schedule(&((struct vmbus_channel *)channel)->callback_event);
 }
 
 static void fcopy_timeout_func(struct work_struct *dummy)
diff --git a/drivers/hv/hv_snapshot.c b/drivers/hv/hv_snapshot.c
index 1c75b38f0d6d..783779e4cc1a 100644
--- a/drivers/hv/hv_snapshot.c
+++ b/drivers/hv/hv_snapshot.c
@@ -80,7 +80,7 @@ static void vss_poll_wrapper(void *channel)
 {
 	/* Transaction is finished, reset the state here to avoid races. */
 	vss_transaction.state = HVUTIL_READY;
-	hv_vss_onchannelcallback(channel);
+	tasklet_schedule(&((struct vmbus_channel *)channel)->callback_event);
 }
 
 /*
diff --git a/drivers/hv/hv_trace.h b/drivers/hv/hv_trace.h
index e70783e33680..a43bc76c2d5d 100644
--- a/drivers/hv/hv_trace.h
+++ b/drivers/hv/hv_trace.h
@@ -296,6 +296,25 @@ TRACE_EVENT(vmbus_send_tl_connect_request,
 		    )
 	);
 
+TRACE_EVENT(vmbus_send_modifychannel,
+	    TP_PROTO(const struct vmbus_channel_modifychannel *msg,
+		     int ret),
+	    TP_ARGS(msg, ret),
+	    TP_STRUCT__entry(
+		    __field(u32, child_relid)
+		    __field(u32, target_vp)
+		    __field(int, ret)
+		    ),
+	    TP_fast_assign(
+		    __entry->child_relid = msg->child_relid;
+		    __entry->target_vp = msg->target_vp;
+		    __entry->ret = ret;
+		    ),
+	    TP_printk("binding child_relid 0x%x to target_vp 0x%x, ret %d",
+		      __entry->child_relid, __entry->target_vp, __entry->ret
+		    )
+	);
+
 DECLARE_EVENT_CLASS(vmbus_channel,
 	TP_PROTO(const struct vmbus_channel *channel),
 	TP_ARGS(channel),
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index f5fa3b3c9baf..5e5cebe5d048 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -132,12 +132,6 @@ struct hv_per_cpu_context {
 	 * basis.
 	 */
 	struct tasklet_struct msg_dpc;
-
-	/*
-	 * To optimize the mapping of relid to channel, maintain
-	 * per-cpu list of the channels based on their CPU affinity.
-	 */
-	struct list_head chan_list;
 };
 
 struct hv_context {
@@ -202,6 +196,8 @@ int hv_ringbuffer_read(struct vmbus_channel *channel,
 /* TODO: Need to make this configurable */
 #define MAX_NUM_CHANNELS_SUPPORTED	256
 
+#define MAX_CHANNEL_RELIDS					\
+	max(MAX_NUM_CHANNELS_SUPPORTED, HV_EVENT_FLAGS_COUNT)
 
 enum vmbus_connect_state {
 	DISCONNECTED,
@@ -212,12 +208,13 @@ enum vmbus_connect_state {
 
 #define MAX_SIZE_CHANNEL_MESSAGE	HV_MESSAGE_PAYLOAD_BYTE_COUNT
 
-struct vmbus_connection {
-	/*
-	 * CPU on which the initial host contact was made.
-	 */
-	int connect_cpu;
+/*
+ * The CPU that Hyper-V will interrupt for VMBUS messages, such as
+ * CHANNELMSG_OFFERCHANNEL and CHANNELMSG_RESCIND_CHANNELOFFER.
+ */
+#define VMBUS_CONNECT_CPU	0
 
+struct vmbus_connection {
 	u32 msg_conn_id;
 
 	atomic_t offer_in_progress;
@@ -250,6 +247,9 @@ struct vmbus_connection {
 	struct list_head chn_list;
 	struct mutex channel_mutex;
 
+	/* Array of channels */
+	struct vmbus_channel **channels;
+
 	/*
 	 * An offer message is handled first on the work_queue, and then
 	 * is further handled on handle_primary_chan_wq or
@@ -292,7 +292,7 @@ struct vmbus_msginfo {
 	struct list_head msglist_entry;
 
 	/* The message itself */
-	unsigned char msg[0];
+	unsigned char msg[];
 };
 
 
@@ -317,6 +317,7 @@ struct vmbus_channel_message_table_entry {
 	enum vmbus_channel_message_type message_type;
 	enum vmbus_message_handler_type handler_type;
 	void (*message_handler)(struct vmbus_channel_message_header *msg);
+	u32 min_payload_len;
 };
 
 extern const struct vmbus_channel_message_table_entry
@@ -336,6 +337,9 @@ int vmbus_add_channel_kobj(struct hv_device *device_obj,
 
 void vmbus_remove_channel_attr_group(struct vmbus_channel *channel);
 
+void vmbus_channel_map_relid(struct vmbus_channel *channel);
+void vmbus_channel_unmap_relid(struct vmbus_channel *channel);
+
 struct vmbus_channel *relid2channel(u32 relid);
 
 void vmbus_free_channels(void);
@@ -374,12 +378,7 @@ static inline void hv_poll_channel(struct vmbus_channel *channel,
 {
 	if (!channel)
 		return;
-
-	if (in_interrupt() && (channel->target_cpu == smp_processor_id())) {
-		cb(channel);
-		return;
-	}
-	smp_call_function_single(channel->target_cpu, cb, channel, true);
+	cb(channel);
 }
 
 enum hvutil_device_state {
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 029378c27421..84c9985d8391 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -31,6 +31,7 @@
 #include <linux/kdebug.h>
 #include <linux/efi.h>
 #include <linux/random.h>
+#include <linux/kernel.h>
 #include <linux/syscore_ops.h>
 #include <clocksource/hyperv_timer.h>
 #include "hyperv_vmbus.h"
@@ -48,14 +49,35 @@ static int hyperv_cpuhp_online;
 
 static void *hv_panic_page;
 
+/*
+ * Boolean to control whether to report panic messages over Hyper-V.
+ *
+ * It can be set via /proc/sys/kernel/hyperv/record_panic_msg
+ */
+static int sysctl_record_panic_msg = 1;
+
+static int hyperv_report_reg(void)
+{
+	return !sysctl_record_panic_msg || !hv_panic_page;
+}
+
 static int hyperv_panic_event(struct notifier_block *nb, unsigned long val,
 			      void *args)
 {
 	struct pt_regs *regs;
 
-	regs = current_pt_regs();
+	vmbus_initiate_unload(true);
 
-	hyperv_report_panic(regs, val);
+	/*
+	 * Hyper-V should be notified only once about a panic.  If we will be
+	 * doing hyperv_report_panic_msg() later with kmsg data, don't do
+	 * the notification here.
+	 */
+	if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE
+	    && hyperv_report_reg()) {
+		regs = current_pt_regs();
+		hyperv_report_panic(regs, val, false);
+	}
 	return NOTIFY_DONE;
 }
 
@@ -65,7 +87,13 @@ static int hyperv_die_event(struct notifier_block *nb, unsigned long val,
 	struct die_args *die = (struct die_args *)args;
 	struct pt_regs *regs = die->regs;
 
-	hyperv_report_panic(regs, val);
+	/*
+	 * Hyper-V should be notified only once about a panic.  If we will be
+	 * doing hyperv_report_panic_msg() later with kmsg data, don't do
+	 * the notification here.
+	 */
+	if (hyperv_report_reg())
+		hyperv_report_panic(regs, val, true);
 	return NOTIFY_DONE;
 }
 
@@ -950,6 +978,9 @@ static int vmbus_resume(struct device *child_device)
 
 	return drv->resume(dev);
 }
+#else
+#define vmbus_suspend NULL
+#define vmbus_resume NULL
 #endif /* CONFIG_PM_SLEEP */
 
 /*
@@ -969,11 +1000,22 @@ static void vmbus_device_release(struct device *device)
 }
 
 /*
- * Note: we must use SET_NOIRQ_SYSTEM_SLEEP_PM_OPS rather than
- * SET_SYSTEM_SLEEP_PM_OPS: see the comment before vmbus_bus_pm.
+ * Note: we must use the "noirq" ops: see the comment before vmbus_bus_pm.
+ *
+ * suspend_noirq/resume_noirq are set to NULL to support Suspend-to-Idle: we
+ * shouldn't suspend the vmbus devices upon Suspend-to-Idle, otherwise there
+ * is no way to wake up a Generation-2 VM.
+ *
+ * The other 4 ops are for hibernation.
  */
+
 static const struct dev_pm_ops vmbus_pm = {
-	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(vmbus_suspend, vmbus_resume)
+	.suspend_noirq	= NULL,
+	.resume_noirq	= NULL,
+	.freeze_noirq	= vmbus_suspend,
+	.thaw_noirq	= vmbus_resume,
+	.poweroff_noirq	= vmbus_suspend,
+	.restore_noirq	= vmbus_resume,
 };
 
 /* The one and only one */
@@ -991,7 +1033,10 @@ static struct bus_type  hv_bus = {
 
 struct onmessage_work_context {
 	struct work_struct work;
-	struct hv_message msg;
+	struct {
+		struct hv_message_header header;
+		u8 payload[];
+	} msg;
 };
 
 static void vmbus_onmessage_work(struct work_struct *work)
@@ -1004,7 +1049,8 @@ static void vmbus_onmessage_work(struct work_struct *work)
 
 	ctx = container_of(work, struct onmessage_work_context,
 			   work);
-	vmbus_onmessage(&ctx->msg);
+	vmbus_onmessage((struct vmbus_channel_message_header *)
+			&ctx->msg.payload);
 	kfree(ctx);
 }
 
@@ -1019,6 +1065,13 @@ void vmbus_on_msg_dpc(unsigned long data)
 	struct onmessage_work_context *ctx;
 	u32 message_type = msg->header.message_type;
 
+	/*
+	 * 'enum vmbus_channel_message_type' is supposed to always be 'u32' as
+	 * it is being used in 'struct vmbus_channel_message_header' definition
+	 * which is supposed to match hypervisor ABI.
+	 */
+	BUILD_BUG_ON(sizeof(enum vmbus_channel_message_type) != sizeof(u32));
+
 	if (message_type == HVMSG_NONE)
 		/* no msg */
 		return;
@@ -1032,41 +1085,88 @@ void vmbus_on_msg_dpc(unsigned long data)
 		goto msg_handled;
 	}
 
+	if (msg->header.payload_size > HV_MESSAGE_PAYLOAD_BYTE_COUNT) {
+		WARN_ONCE(1, "payload size is too large (%d)\n",
+			  msg->header.payload_size);
+		goto msg_handled;
+	}
+
 	entry = &channel_message_table[hdr->msgtype];
 
 	if (!entry->message_handler)
 		goto msg_handled;
 
+	if (msg->header.payload_size < entry->min_payload_len) {
+		WARN_ONCE(1, "message too short: msgtype=%d len=%d\n",
+			  hdr->msgtype, msg->header.payload_size);
+		goto msg_handled;
+	}
+
 	if (entry->handler_type	== VMHT_BLOCKING) {
-		ctx = kmalloc(sizeof(*ctx), GFP_ATOMIC);
+		ctx = kmalloc(sizeof(*ctx) + msg->header.payload_size,
+			      GFP_ATOMIC);
 		if (ctx == NULL)
 			return;
 
 		INIT_WORK(&ctx->work, vmbus_onmessage_work);
-		memcpy(&ctx->msg, msg, sizeof(*msg));
+		memcpy(&ctx->msg, msg, sizeof(msg->header) +
+		       msg->header.payload_size);
 
 		/*
 		 * The host can generate a rescind message while we
 		 * may still be handling the original offer. We deal with
-		 * this condition by ensuring the processing is done on the
-		 * same CPU.
+		 * this condition by relying on the synchronization provided
+		 * by offer_in_progress and by channel_mutex.  See also the
+		 * inline comments in vmbus_onoffer_rescind().
 		 */
 		switch (hdr->msgtype) {
 		case CHANNELMSG_RESCIND_CHANNELOFFER:
 			/*
 			 * If we are handling the rescind message;
 			 * schedule the work on the global work queue.
+			 *
+			 * The OFFER message and the RESCIND message should
+			 * not be handled by the same serialized work queue,
+			 * because the OFFER handler may call vmbus_open(),
+			 * which tries to open the channel by sending an
+			 * OPEN_CHANNEL message to the host and waits for
+			 * the host's response; however, if the host has
+			 * rescinded the channel before it receives the
+			 * OPEN_CHANNEL message, the host just silently
+			 * ignores the OPEN_CHANNEL message; as a result,
+			 * the guest's OFFER handler hangs for ever, if we
+			 * handle the RESCIND message in the same serialized
+			 * work queue: the RESCIND handler can not start to
+			 * run before the OFFER handler finishes.
 			 */
-			schedule_work_on(vmbus_connection.connect_cpu,
-					 &ctx->work);
+			schedule_work(&ctx->work);
 			break;
 
 		case CHANNELMSG_OFFERCHANNEL:
+			/*
+			 * The host sends the offer message of a given channel
+			 * before sending the rescind message of the same
+			 * channel.  These messages are sent to the guest's
+			 * connect CPU; the guest then starts processing them
+			 * in the tasklet handler on this CPU:
+			 *
+			 * VMBUS_CONNECT_CPU
+			 *
+			 * [vmbus_on_msg_dpc()]
+			 * atomic_inc()  // CHANNELMSG_OFFERCHANNEL
+			 * queue_work()
+			 * ...
+			 * [vmbus_on_msg_dpc()]
+			 * schedule_work()  // CHANNELMSG_RESCIND_CHANNELOFFER
+			 *
+			 * We rely on the memory-ordering properties of the
+			 * queue_work() and schedule_work() primitives, which
+			 * guarantee that the atomic increment will be visible
+			 * to the CPUs which will execute the offer & rescind
+			 * works by the time these works will start execution.
+			 */
 			atomic_inc(&vmbus_connection.offer_in_progress);
-			queue_work_on(vmbus_connection.connect_cpu,
-				      vmbus_connection.work_queue,
-				      &ctx->work);
-			break;
+			fallthrough;
 
 		default:
 			queue_work(vmbus_connection.work_queue, &ctx->work);
@@ -1091,10 +1191,11 @@ static void vmbus_force_channel_rescinded(struct vmbus_channel *channel)
 	WARN_ON(!is_hvsock_channel(channel));
 
 	/*
-	 * sizeof(*ctx) is small and the allocation should really not fail,
+	 * Allocation size is small and the allocation should really not fail,
 	 * otherwise the state of the hv_sock connections ends up in limbo.
 	 */
-	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL | __GFP_NOFAIL);
+	ctx = kzalloc(sizeof(*ctx) + sizeof(*rescind),
+		      GFP_KERNEL | __GFP_NOFAIL);
 
 	/*
 	 * So far, these are not really used by Linux. Just set them to the
@@ -1104,30 +1205,16 @@ static void vmbus_force_channel_rescinded(struct vmbus_channel *channel)
 	ctx->msg.header.payload_size = sizeof(*rescind);
 
 	/* These values are actually used by Linux. */
-	rescind = (struct vmbus_channel_rescind_offer *)ctx->msg.u.payload;
+	rescind = (struct vmbus_channel_rescind_offer *)ctx->msg.payload;
 	rescind->header.msgtype = CHANNELMSG_RESCIND_CHANNELOFFER;
 	rescind->child_relid = channel->offermsg.child_relid;
 
 	INIT_WORK(&ctx->work, vmbus_onmessage_work);
 
-	queue_work_on(vmbus_connection.connect_cpu,
-		      vmbus_connection.work_queue,
-		      &ctx->work);
+	queue_work(vmbus_connection.work_queue, &ctx->work);
 }
 #endif /* CONFIG_PM_SLEEP */
 
-/*
- * Direct callback for channels using other deferred processing
- */
-static void vmbus_channel_isr(struct vmbus_channel *channel)
-{
-	void (*callback_fn)(void *);
-
-	callback_fn = READ_ONCE(channel->onchannel_callback);
-	if (likely(callback_fn != NULL))
-		(*callback_fn)(channel->channel_callback_context);
-}
-
 /*
  * Schedule all channels with events pending
  */
@@ -1158,6 +1245,7 @@ static void vmbus_chan_sched(struct hv_per_cpu_context *hv_cpu)
 		return;
 
 	for_each_set_bit(relid, recv_int_page, maxbits) {
+		void (*callback_fn)(void *context);
 		struct vmbus_channel *channel;
 
 		if (!sync_test_and_clear_bit(relid, recv_int_page))
@@ -1167,33 +1255,54 @@ static void vmbus_chan_sched(struct hv_per_cpu_context *hv_cpu)
 		if (relid == 0)
 			continue;
 
+		/*
+		 * Pairs with the kfree_rcu() in vmbus_chan_release().
+		 * Guarantees that the channel data structure doesn't
+		 * get freed while the channel pointer below is being
+		 * dereferenced.
+		 */
 		rcu_read_lock();
 
 		/* Find channel based on relid */
-		list_for_each_entry_rcu(channel, &hv_cpu->chan_list, percpu_list) {
-			if (channel->offermsg.child_relid != relid)
-				continue;
+		channel = relid2channel(relid);
+		if (channel == NULL)
+			goto sched_unlock_rcu;
 
-			if (channel->rescind)
-				continue;
+		if (channel->rescind)
+			goto sched_unlock_rcu;
+
+		/*
+		 * Make sure that the ring buffer data structure doesn't get
+		 * freed while we dereference the ring buffer pointer.  Test
+		 * for the channel's onchannel_callback being NULL within a
+		 * sched_lock critical section.  See also the inline comments
+		 * in vmbus_reset_channel_cb().
+		 */
+		spin_lock(&channel->sched_lock);
 
-			trace_vmbus_chan_sched(channel);
+		callback_fn = channel->onchannel_callback;
+		if (unlikely(callback_fn == NULL))
+			goto sched_unlock;
 
-			++channel->interrupts;
+		trace_vmbus_chan_sched(channel);
 
-			switch (channel->callback_mode) {
-			case HV_CALL_ISR:
-				vmbus_channel_isr(channel);
-				break;
+		++channel->interrupts;
 
-			case HV_CALL_BATCHED:
-				hv_begin_read(&channel->inbound);
-				/* fallthrough */
-			case HV_CALL_DIRECT:
-				tasklet_schedule(&channel->callback_event);
-			}
+		switch (channel->callback_mode) {
+		case HV_CALL_ISR:
+			(*callback_fn)(channel->channel_callback_context);
+			break;
+
+		case HV_CALL_BATCHED:
+			hv_begin_read(&channel->inbound);
+			fallthrough;
+		case HV_CALL_DIRECT:
+			tasklet_schedule(&channel->callback_event);
 		}
 
+sched_unlock:
+		spin_unlock(&channel->sched_lock);
+sched_unlock_rcu:
 		rcu_read_unlock();
 	}
 }
@@ -1252,13 +1361,6 @@ static void vmbus_isr(void)
 	add_interrupt_randomness(HYPERVISOR_CALLBACK_VECTOR, 0);
 }
 
-/*
- * Boolean to control whether to report panic messages over Hyper-V.
- *
- * It can be set via /proc/sys/kernel/hyperv/record_panic_msg
- */
-static int sysctl_record_panic_msg = 1;
-
 /*
  * Callback from kmsg_dump. Grab as much as possible from the end of the kmsg
  * buffer and call into Hyper-V to transfer the data.
@@ -1382,19 +1484,29 @@ static int vmbus_bus_init(void)
 			hv_panic_page = (void *)hv_alloc_hyperv_zeroed_page();
 			if (hv_panic_page) {
 				ret = kmsg_dump_register(&hv_kmsg_dumper);
-				if (ret)
+				if (ret) {
 					pr_err("Hyper-V: kmsg dump register "
 						"error 0x%x\n", ret);
+					hv_free_hyperv_page(
+					    (unsigned long)hv_panic_page);
+					hv_panic_page = NULL;
+				}
 			} else
 				pr_err("Hyper-V: panic message page memory "
 					"allocation failed");
 		}
 
 		register_die_notifier(&hyperv_die_block);
-		atomic_notifier_chain_register(&panic_notifier_list,
-					       &hyperv_panic_block);
 	}
 
+	/*
+	 * Always register the panic notifier because we need to unload
+	 * the VMbus channel connection to prevent any VMbus
+	 * activity after the VM panics.
+	 */
+	atomic_notifier_chain_register(&panic_notifier_list,
+			       &hyperv_panic_block);
+
 	vmbus_request_offers();
 
 	return 0;
@@ -1407,7 +1519,6 @@ static int vmbus_bus_init(void)
 	hv_remove_vmbus_irq();
 
 	bus_unregister(&hv_bus);
-	hv_free_hyperv_page((unsigned long)hv_panic_page);
 	unregister_sysctl_table(hv_ctl_table_hdr);
 	hv_ctl_table_hdr = NULL;
 	return ret;
@@ -1509,8 +1620,24 @@ static ssize_t vmbus_chan_attr_show(struct kobject *kobj,
 	return attribute->show(chan, buf);
 }
 
+static ssize_t vmbus_chan_attr_store(struct kobject *kobj,
+				     struct attribute *attr, const char *buf,
+				     size_t count)
+{
+	const struct vmbus_chan_attribute *attribute
+		= container_of(attr, struct vmbus_chan_attribute, attr);
+	struct vmbus_channel *chan
+		= container_of(kobj, struct vmbus_channel, kobj);
+
+	if (!attribute->store)
+		return -EIO;
+
+	return attribute->store(chan, buf, count);
+}
+
 static const struct sysfs_ops vmbus_chan_sysfs_ops = {
 	.show = vmbus_chan_attr_show,
+	.store = vmbus_chan_attr_store,
 };
 
 static ssize_t out_mask_show(struct vmbus_channel *channel, char *buf)
@@ -1581,11 +1708,103 @@ static ssize_t write_avail_show(struct vmbus_channel *channel, char *buf)
 }
 static VMBUS_CHAN_ATTR_RO(write_avail);
 
-static ssize_t show_target_cpu(struct vmbus_channel *channel, char *buf)
+static ssize_t target_cpu_show(struct vmbus_channel *channel, char *buf)
 {
 	return sprintf(buf, "%u\n", channel->target_cpu);
 }
-static VMBUS_CHAN_ATTR(cpu, S_IRUGO, show_target_cpu, NULL);
+static ssize_t target_cpu_store(struct vmbus_channel *channel,
+				const char *buf, size_t count)
+{
+	ssize_t ret = count;
+	u32 target_cpu;
+
+	if (vmbus_proto_version < VERSION_WIN10_V4_1)
+		return -EIO;
+
+	if (sscanf(buf, "%uu", &target_cpu) != 1)
+		return -EIO;
+
+	/* Validate target_cpu for the cpumask_test_cpu() operation below. */
+	if (target_cpu >= nr_cpumask_bits)
+		return -EINVAL;
+
+	/* No CPUs should come up or down during this. */
+	cpus_read_lock();
+
+	if (!cpumask_test_cpu(target_cpu, cpu_online_mask)) {
+		cpus_read_unlock();
+		return -EINVAL;
+	}
+
+	/*
+	 * Synchronizes target_cpu_store() and channel closure:
+	 *
+	 * { Initially: state = CHANNEL_OPENED }
+	 *
+	 * CPU1				CPU2
+	 *
+	 * [target_cpu_store()]		[vmbus_disconnect_ring()]
+	 *
+	 * LOCK channel_mutex		LOCK channel_mutex
+	 * LOAD r1 = state		LOAD r2 = state
+	 * IF (r1 == CHANNEL_OPENED)	IF (r2 == CHANNEL_OPENED)
+	 *   SEND MODIFYCHANNEL		  STORE state = CHANNEL_OPEN
+	 *   [...]			  SEND CLOSECHANNEL
+	 * UNLOCK channel_mutex		UNLOCK channel_mutex
+	 *
+	 * Forbids: r1 == r2 == CHANNEL_OPENED (i.e., CPU1's LOCK precedes
+	 * 		CPU2's LOCK) && CPU2's SEND precedes CPU1's SEND
+	 *
+	 * Note.  The host processes the channel messages "sequentially", in
+	 * the order in which they are received on a per-partition basis.
+	 */
+	mutex_lock(&vmbus_connection.channel_mutex);
+
+	/*
+	 * Hyper-V will ignore MODIFYCHANNEL messages for "non-open" channels;
+	 * avoid sending the message and fail here for such channels.
+	 */
+	if (channel->state != CHANNEL_OPENED_STATE) {
+		ret = -EIO;
+		goto cpu_store_unlock;
+	}
+
+	if (channel->target_cpu == target_cpu)
+		goto cpu_store_unlock;
+
+	if (vmbus_send_modifychannel(channel->offermsg.child_relid,
+				     hv_cpu_number_to_vp_number(target_cpu))) {
+		ret = -EIO;
+		goto cpu_store_unlock;
+	}
+
+	/*
+	 * Warning.  At this point, there is *no* guarantee that the host will
+	 * have successfully processed the vmbus_send_modifychannel() request.
+	 * See the header comment of vmbus_send_modifychannel() for more info.
+	 *
+	 * Lags in the processing of the above vmbus_send_modifychannel() can
+	 * result in missed interrupts if the "old" target CPU is taken offline
+	 * before Hyper-V starts sending interrupts to the "new" target CPU.
+	 * But apart from this offlining scenario, the code tolerates such
+	 * lags.  It will function correctly even if a channel interrupt comes
+	 * in on a CPU that is different from the channel target_cpu value.
+	 */
+
+	if (channel->change_target_cpu_callback)
+		(*channel->change_target_cpu_callback)(channel,
+				channel->target_cpu, target_cpu);
+
+	channel->target_cpu = target_cpu;
+	channel->target_vp = hv_cpu_number_to_vp_number(target_cpu);
+	channel->numa_node = cpu_to_node(target_cpu);
+
+cpu_store_unlock:
+	mutex_unlock(&vmbus_connection.channel_mutex);
+	cpus_read_unlock();
+	return ret;
+}
+static VMBUS_CHAN_ATTR(cpu, 0644, target_cpu_show, target_cpu_store);
 
 static ssize_t channel_pending_show(struct vmbus_channel *channel,
 				    char *buf)
@@ -2177,9 +2396,12 @@ static int vmbus_bus_suspend(struct device *dev)
 
 	list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) {
 		/*
-		 * Invalidate the field. Upon resume, vmbus_onoffer() will fix
-		 * up the field, and the other fields (if necessary).
+		 * Remove the channel from the array of channels and invalidate
+		 * the channel's relid.  Upon resume, vmbus_onoffer() will fix
+		 * up the relid (and other fields, if necessary) and add the
+		 * channel back to the array.
 		 */
+		vmbus_channel_unmap_relid(channel);
 		channel->offermsg.child_relid = INVALID_RELID;
 
 		if (is_hvsock_channel(channel)) {
@@ -2204,8 +2426,6 @@ static int vmbus_bus_suspend(struct device *dev)
 
 	vmbus_initiate_unload(false);
 
-	vmbus_connection.conn_state = DISCONNECTED;
-
 	/* Reset the event for the next resume. */
 	reinit_completion(&vmbus_connection.ready_for_resume_event);
 
@@ -2253,6 +2473,9 @@ static int vmbus_bus_resume(struct device *dev)
 
 	return 0;
 }
+#else
+#define vmbus_bus_suspend NULL
+#define vmbus_bus_resume NULL
 #endif /* CONFIG_PM_SLEEP */
 
 static const struct acpi_device_id vmbus_acpi_device_ids[] = {
@@ -2263,16 +2486,24 @@ static const struct acpi_device_id vmbus_acpi_device_ids[] = {
 MODULE_DEVICE_TABLE(acpi, vmbus_acpi_device_ids);
 
 /*
- * Note: we must use SET_NOIRQ_SYSTEM_SLEEP_PM_OPS rather than
- * SET_SYSTEM_SLEEP_PM_OPS, otherwise NIC SR-IOV can not work, because the
- * "pci_dev_pm_ops" uses the "noirq" callbacks: in the resume path, the
- * pci "noirq" restore callback runs before "non-noirq" callbacks (see
+ * Note: we must use the "no_irq" ops, otherwise hibernation can not work with
+ * PCI device assignment, because "pci_dev_pm_ops" uses the "noirq" ops: in
+ * the resume path, the pci "noirq" restore op runs before "non-noirq" op (see
  * resume_target_kernel() -> dpm_resume_start(), and hibernation_restore() ->
  * dpm_resume_end()). This means vmbus_bus_resume() and the pci-hyperv's
- * resume callback must also run via the "noirq" callbacks.
+ * resume callback must also run via the "noirq" ops.
+ *
+ * Set suspend_noirq/resume_noirq to NULL for Suspend-to-Idle: see the comment
+ * earlier in this file before vmbus_pm.
  */
+
 static const struct dev_pm_ops vmbus_bus_pm = {
-	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(vmbus_bus_suspend, vmbus_bus_resume)
+	.suspend_noirq	= NULL,
+	.resume_noirq	= NULL,
+	.freeze_noirq	= vmbus_bus_suspend,
+	.thaw_noirq	= vmbus_bus_resume,
+	.poweroff_noirq	= vmbus_bus_suspend,
+	.restore_noirq	= vmbus_bus_resume
 };
 
 static struct acpi_driver vmbus_acpi_driver = {
@@ -2289,7 +2520,6 @@ static void hv_kexec_handler(void)
 {
 	hv_stimer_global_cleanup();
 	vmbus_initiate_unload(false);
-	vmbus_connection.conn_state = DISCONNECTED;
 	/* Make sure conn_state is set as hv_synic_cleanup checks for it */
 	mb();
 	cpuhp_remove_state(hyperv_cpuhp_online);
@@ -2306,7 +2536,6 @@ static void hv_crash_handler(struct pt_regs *regs)
 	 * doing the cleanup for current CPU only. This should be sufficient
 	 * for kdump.
 	 */
-	vmbus_connection.conn_state = DISCONNECTED;
 	cpu = smp_processor_id();
 	hv_stimer_cleanup(cpu);
 	hv_synic_disable_regs(cpu);
@@ -2419,6 +2648,7 @@ static void __exit vmbus_exit(void)
 	hv_debug_rm_all_dir();
 
 	vmbus_free_channels();
+	kfree(vmbus_connection.channels);
 
 	if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) {
 		kmsg_dump_unregister(&hv_kmsg_dumper);
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 05a30832c6ba..a08765c80a49 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -412,7 +412,7 @@ config SENSORS_DRIVETEMP
 	  hard disk drives.
 
 	  This driver can also be built as a module. If so, the module
-	  will be called satatemp.
+	  will be called drivetemp.
 
 config SENSORS_DS620
 	tristate "Dallas Semiconductor DS620"
@@ -1340,10 +1340,12 @@ config SENSORS_NCT7802
 
 config SENSORS_NCT7904
 	tristate "Nuvoton NCT7904"
-	depends on I2C
+	depends on I2C && WATCHDOG
+	select WATCHDOG_CORE
 	help
 	  If you say yes here you get support for the Nuvoton NCT7904
-	  hardware monitoring chip, including manual fan speed control.
+	  hardware monitoring chip, including manual fan speed control
+	  and support for the integrated watchdog.
 
 	  This driver can also be built as a module. If so, the module
 	  will be called nct7904.
diff --git a/drivers/hwmon/dell-smm-hwmon.c b/drivers/hwmon/dell-smm-hwmon.c
index ab719d372b0d..16be012a95ed 100644
--- a/drivers/hwmon/dell-smm-hwmon.c
+++ b/drivers/hwmon/dell-smm-hwmon.c
@@ -1072,13 +1072,6 @@ static const struct dmi_system_id i8k_dmi_table[] __initconst = {
 			DMI_MATCH(DMI_PRODUCT_NAME, "Vostro"),
 		},
 	},
-	{
-		.ident = "Dell XPS421",
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "XPS L421X"),
-		},
-	},
 	{
 		.ident = "Dell Studio",
 		.matches = {
@@ -1087,14 +1080,6 @@ static const struct dmi_system_id i8k_dmi_table[] __initconst = {
 		},
 		.driver_data = (void *)&i8k_config_data[DELL_STUDIO],
 	},
-	{
-		.ident = "Dell XPS 13",
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "XPS13"),
-		},
-		.driver_data = (void *)&i8k_config_data[DELL_XPS],
-	},
 	{
 		.ident = "Dell XPS M140",
 		.matches = {
@@ -1104,17 +1089,10 @@ static const struct dmi_system_id i8k_dmi_table[] __initconst = {
 		.driver_data = (void *)&i8k_config_data[DELL_XPS],
 	},
 	{
-		.ident = "Dell XPS 15 9560",
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "XPS 15 9560"),
-		},
-	},
-	{
-		.ident = "Dell XPS 15 9570",
+		.ident = "Dell XPS",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "XPS 15 9570"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "XPS"),
 		},
 	},
 	{ }
diff --git a/drivers/hwmon/drivetemp.c b/drivers/hwmon/drivetemp.c
index 370d0c74eb01..9179460c2d9d 100644
--- a/drivers/hwmon/drivetemp.c
+++ b/drivers/hwmon/drivetemp.c
@@ -264,12 +264,18 @@ static int drivetemp_get_scttemp(struct drivetemp_data *st, u32 attr, long *val)
 		return err;
 	switch (attr) {
 	case hwmon_temp_input:
+		if (!temp_is_valid(buf[SCT_STATUS_TEMP]))
+			return -ENODATA;
 		*val = temp_from_sct(buf[SCT_STATUS_TEMP]);
 		break;
 	case hwmon_temp_lowest:
+		if (!temp_is_valid(buf[SCT_STATUS_TEMP_LOWEST]))
+			return -ENODATA;
 		*val = temp_from_sct(buf[SCT_STATUS_TEMP_LOWEST]);
 		break;
 	case hwmon_temp_highest:
+		if (!temp_is_valid(buf[SCT_STATUS_TEMP_HIGHEST]))
+			return -ENODATA;
 		*val = temp_from_sct(buf[SCT_STATUS_TEMP_HIGHEST]);
 		break;
 	default:
diff --git a/drivers/hwmon/k10temp.c b/drivers/hwmon/k10temp.c
index 3f37d5d81fe4..9915578533bb 100644
--- a/drivers/hwmon/k10temp.c
+++ b/drivers/hwmon/k10temp.c
@@ -186,7 +186,7 @@ static long get_raw_temp(struct k10temp_data *data)
 	return temp;
 }
 
-const char *k10temp_temp_label[] = {
+static const char *k10temp_temp_label[] = {
 	"Tctl",
 	"Tdie",
 	"Tccd1",
@@ -199,12 +199,12 @@ const char *k10temp_temp_label[] = {
 	"Tccd8",
 };
 
-const char *k10temp_in_label[] = {
+static const char *k10temp_in_label[] = {
 	"Vcore",
 	"Vsoc",
 };
 
-const char *k10temp_curr_label[] = {
+static const char *k10temp_curr_label[] = {
 	"Icore",
 	"Isoc",
 };
diff --git a/drivers/hwmon/nct7904.c b/drivers/hwmon/nct7904.c
index 1f5743d68984..571a6491a21f 100644
--- a/drivers/hwmon/nct7904.c
+++ b/drivers/hwmon/nct7904.c
@@ -8,6 +8,9 @@
  * Copyright (c) 2019 Advantech
  * Author: Amy.Shih <amy.shih@advantech.com.tw>
  *
+ * Copyright (c) 2020 Advantech
+ * Author: Yuechao Zhao <yuechao.zhao@advantech.com.cn>
+ *
  * Supports the following chips:
  *
  * Chip        #vin  #fan  #pwm  #temp  #dts  chip ID
@@ -20,6 +23,7 @@
 #include <linux/i2c.h>
 #include <linux/mutex.h>
 #include <linux/hwmon.h>
+#include <linux/watchdog.h>
 
 #define VENDOR_ID_REG		0x7A	/* Any bank */
 #define NUVOTON_ID		0x50
@@ -87,18 +91,42 @@
 #define FANCTL1_FMR_REG		0x00	/* Bank 3; 1 reg per channel */
 #define FANCTL1_OUT_REG		0x10	/* Bank 3; 1 reg per channel */
 
+#define WDT_LOCK_REG		0xE0	/* W/O Lock Watchdog Register */
+#define WDT_EN_REG		0xE1	/* R/O Watchdog Enable Register */
+#define WDT_STS_REG		0xE2	/* R/O Watchdog Status Register */
+#define WDT_TIMER_REG		0xE3	/* R/W Watchdog Timer Register */
+#define WDT_SOFT_EN		0x55	/* Enable soft watchdog timer */
+#define WDT_SOFT_DIS		0xAA	/* Disable soft watchdog timer */
+
 #define VOLT_MONITOR_MODE	0x0
 #define THERMAL_DIODE_MODE	0x1
 #define THERMISTOR_MODE		0x3
 
 #define ENABLE_TSI	BIT(1)
 
+#define WATCHDOG_TIMEOUT	1	/* 1 minute default timeout */
+
+/*The timeout range is 1-255 minutes*/
+#define MIN_TIMEOUT		(1 * 60)
+#define MAX_TIMEOUT		(255 * 60)
+
+static int timeout = WATCHDOG_TIMEOUT;
+module_param(timeout, int, 0);
+MODULE_PARM_DESC(timeout, "Watchdog timeout in minutes. 1 <= timeout <= 255, default="
+			__MODULE_STRING(WATCHODOG_TIMEOUT) ".");
+
+static bool nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, bool, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started once started (default="
+			__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+
 static const unsigned short normal_i2c[] = {
 	0x2d, 0x2e, I2C_CLIENT_END
 };
 
 struct nct7904_data {
 	struct i2c_client *client;
+	struct watchdog_device wdt;
 	struct mutex bank_lock;
 	int bank_sel;
 	u32 fanin_mask;
@@ -889,6 +917,95 @@ static const struct hwmon_chip_info nct7904_chip_info = {
 	.info = nct7904_info,
 };
 
+/*
+ * Watchdog Function
+ */
+static int nct7904_wdt_start(struct watchdog_device *wdt)
+{
+	struct nct7904_data *data = watchdog_get_drvdata(wdt);
+
+	/* Enable soft watchdog timer */
+	return nct7904_write_reg(data, BANK_0, WDT_LOCK_REG, WDT_SOFT_EN);
+}
+
+static int nct7904_wdt_stop(struct watchdog_device *wdt)
+{
+	struct nct7904_data *data = watchdog_get_drvdata(wdt);
+
+	return nct7904_write_reg(data, BANK_0, WDT_LOCK_REG, WDT_SOFT_DIS);
+}
+
+static int nct7904_wdt_set_timeout(struct watchdog_device *wdt,
+				   unsigned int timeout)
+{
+	struct nct7904_data *data = watchdog_get_drvdata(wdt);
+	/*
+	 * The NCT7904 is very special in watchdog function.
+	 * Its minimum unit is minutes. And wdt->timeout needs
+	 * to match the actual timeout selected. So, this needs
+	 * to be: wdt->timeout = timeout / 60 * 60.
+	 * For example, if the user configures a timeout of
+	 * 119 seconds, the actual timeout will be 60 seconds.
+	 * So, wdt->timeout must then be set to 60 seconds.
+	 */
+	wdt->timeout = timeout / 60 * 60;
+
+	return nct7904_write_reg(data, BANK_0, WDT_TIMER_REG,
+				 wdt->timeout / 60);
+}
+
+static int nct7904_wdt_ping(struct watchdog_device *wdt)
+{
+	/*
+	 * Note:
+	 * NCT7904 does not support refreshing WDT_TIMER_REG register when
+	 * the watchdog is active. Please disable watchdog before feeding
+	 * the watchdog and enable it again.
+	 */
+	struct nct7904_data *data = watchdog_get_drvdata(wdt);
+	int ret;
+
+	/* Disable soft watchdog timer */
+	ret = nct7904_write_reg(data, BANK_0, WDT_LOCK_REG, WDT_SOFT_DIS);
+	if (ret < 0)
+		return ret;
+
+	/* feed watchdog */
+	ret = nct7904_write_reg(data, BANK_0, WDT_TIMER_REG, wdt->timeout / 60);
+	if (ret < 0)
+		return ret;
+
+	/* Enable soft watchdog timer */
+	return nct7904_write_reg(data, BANK_0, WDT_TIMER_REG, WDT_SOFT_EN);
+}
+
+static unsigned int nct7904_wdt_get_timeleft(struct watchdog_device *wdt)
+{
+	struct nct7904_data *data = watchdog_get_drvdata(wdt);
+	int ret;
+
+	ret = nct7904_read_reg(data, BANK_0, WDT_TIMER_REG);
+	if (ret < 0)
+		return 0;
+
+	return ret * 60;
+}
+
+static const struct watchdog_info nct7904_wdt_info = {
+	.options	= WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
+				WDIOF_MAGICCLOSE,
+	.identity	= "nct7904 watchdog",
+};
+
+static const struct watchdog_ops nct7904_wdt_ops = {
+	.owner		= THIS_MODULE,
+	.start		= nct7904_wdt_start,
+	.stop		= nct7904_wdt_stop,
+	.ping		= nct7904_wdt_ping,
+	.set_timeout	= nct7904_wdt_set_timeout,
+	.get_timeleft	= nct7904_wdt_get_timeleft,
+};
+
 static int nct7904_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id)
 {
@@ -1012,7 +1129,26 @@ static int nct7904_probe(struct i2c_client *client,
 	hwmon_dev =
 		devm_hwmon_device_register_with_info(dev, client->name, data,
 						     &nct7904_chip_info, NULL);
-	return PTR_ERR_OR_ZERO(hwmon_dev);
+	ret = PTR_ERR_OR_ZERO(hwmon_dev);
+	if (ret)
+		return ret;
+
+	/* Watchdog initialization */
+	data->wdt.ops = &nct7904_wdt_ops;
+	data->wdt.info = &nct7904_wdt_info;
+
+	data->wdt.timeout = timeout * 60; /* in seconds */
+	data->wdt.min_timeout = MIN_TIMEOUT;
+	data->wdt.max_timeout = MAX_TIMEOUT;
+	data->wdt.parent = &client->dev;
+
+	watchdog_init_timeout(&data->wdt, timeout * 60, &client->dev);
+	watchdog_set_nowayout(&data->wdt, nowayout);
+	watchdog_set_drvdata(&data->wdt, data);
+
+	watchdog_stop_on_unregister(&data->wdt);
+
+	return devm_watchdog_register_device(dev, &data->wdt);
 }
 
 static const struct i2c_device_id nct7904_id[] = {
diff --git a/drivers/hwmon/pmbus/isl68137.c b/drivers/hwmon/pmbus/isl68137.c
index 4d2315208bb5..0c622711ef7e 100644
--- a/drivers/hwmon/pmbus/isl68137.c
+++ b/drivers/hwmon/pmbus/isl68137.c
@@ -21,8 +21,50 @@
 #define ISL68137_VOUT_AVS	0x30
 #define RAA_DMPVR2_READ_VMON	0xc8
 
-enum versions {
+enum chips {
 	isl68137,
+	isl68220,
+	isl68221,
+	isl68222,
+	isl68223,
+	isl68224,
+	isl68225,
+	isl68226,
+	isl68227,
+	isl68229,
+	isl68233,
+	isl68239,
+	isl69222,
+	isl69223,
+	isl69224,
+	isl69225,
+	isl69227,
+	isl69228,
+	isl69234,
+	isl69236,
+	isl69239,
+	isl69242,
+	isl69243,
+	isl69247,
+	isl69248,
+	isl69254,
+	isl69255,
+	isl69256,
+	isl69259,
+	isl69260,
+	isl69268,
+	isl69269,
+	isl69298,
+	raa228000,
+	raa228004,
+	raa228006,
+	raa228228,
+	raa229001,
+	raa229004,
+};
+
+enum variants {
+	raa_dmpvr1_2rail,
 	raa_dmpvr2_1rail,
 	raa_dmpvr2_2rail,
 	raa_dmpvr2_3rail,
@@ -186,7 +228,7 @@ static int isl68137_probe(struct i2c_client *client,
 	memcpy(info, &raa_dmpvr_info, sizeof(*info));
 
 	switch (id->driver_data) {
-	case isl68137:
+	case raa_dmpvr1_2rail:
 		info->pages = 2;
 		info->R[PSC_VOLTAGE_IN] = 3;
 		info->func[0] &= ~PMBUS_HAVE_VMON;
@@ -224,11 +266,47 @@ static int isl68137_probe(struct i2c_client *client,
 }
 
 static const struct i2c_device_id raa_dmpvr_id[] = {
-	{"isl68137", isl68137},
-	{"raa_dmpvr2_1rail", raa_dmpvr2_1rail},
-	{"raa_dmpvr2_2rail", raa_dmpvr2_2rail},
-	{"raa_dmpvr2_3rail", raa_dmpvr2_3rail},
-	{"raa_dmpvr2_hv", raa_dmpvr2_hv},
+	{"isl68137", raa_dmpvr1_2rail},
+	{"isl68220", raa_dmpvr2_2rail},
+	{"isl68221", raa_dmpvr2_3rail},
+	{"isl68222", raa_dmpvr2_2rail},
+	{"isl68223", raa_dmpvr2_2rail},
+	{"isl68224", raa_dmpvr2_3rail},
+	{"isl68225", raa_dmpvr2_2rail},
+	{"isl68226", raa_dmpvr2_3rail},
+	{"isl68227", raa_dmpvr2_1rail},
+	{"isl68229", raa_dmpvr2_3rail},
+	{"isl68233", raa_dmpvr2_2rail},
+	{"isl68239", raa_dmpvr2_3rail},
+
+	{"isl69222", raa_dmpvr2_2rail},
+	{"isl69223", raa_dmpvr2_3rail},
+	{"isl69224", raa_dmpvr2_2rail},
+	{"isl69225", raa_dmpvr2_2rail},
+	{"isl69227", raa_dmpvr2_3rail},
+	{"isl69228", raa_dmpvr2_3rail},
+	{"isl69234", raa_dmpvr2_2rail},
+	{"isl69236", raa_dmpvr2_2rail},
+	{"isl69239", raa_dmpvr2_3rail},
+	{"isl69242", raa_dmpvr2_2rail},
+	{"isl69243", raa_dmpvr2_1rail},
+	{"isl69247", raa_dmpvr2_2rail},
+	{"isl69248", raa_dmpvr2_2rail},
+	{"isl69254", raa_dmpvr2_2rail},
+	{"isl69255", raa_dmpvr2_2rail},
+	{"isl69256", raa_dmpvr2_2rail},
+	{"isl69259", raa_dmpvr2_2rail},
+	{"isl69260", raa_dmpvr2_2rail},
+	{"isl69268", raa_dmpvr2_2rail},
+	{"isl69269", raa_dmpvr2_3rail},
+	{"isl69298", raa_dmpvr2_2rail},
+
+	{"raa228000", raa_dmpvr2_hv},
+	{"raa228004", raa_dmpvr2_hv},
+	{"raa228006", raa_dmpvr2_hv},
+	{"raa228228", raa_dmpvr2_2rail},
+	{"raa229001", raa_dmpvr2_2rail},
+	{"raa229004", raa_dmpvr2_2rail},
 	{}
 };
 
diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile
index 0e3e72f0f510..19497d1d92bf 100644
--- a/drivers/hwtracing/coresight/Makefile
+++ b/drivers/hwtracing/coresight/Makefile
@@ -2,7 +2,8 @@
 #
 # Makefile for CoreSight drivers.
 #
-obj-$(CONFIG_CORESIGHT) += coresight.o coresight-etm-perf.o coresight-platform.o
+obj-$(CONFIG_CORESIGHT) += coresight.o coresight-etm-perf.o \
+			   coresight-platform.o coresight-sysfs.o
 obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o \
 					     coresight-tmc-etf.o \
 					     coresight-tmc-etr.o
diff --git a/drivers/hwtracing/coresight/coresight-cti.c b/drivers/hwtracing/coresight/coresight-cti.c
index aa6e0249bd70..7fc1fc8d7738 100644
--- a/drivers/hwtracing/coresight/coresight-cti.c
+++ b/drivers/hwtracing/coresight/coresight-cti.c
@@ -19,7 +19,7 @@
  */
 
 /* net of CTI devices connected via CTM */
-LIST_HEAD(ect_net);
+static LIST_HEAD(ect_net);
 
 /* protect the list */
 static DEFINE_MUTEX(ect_mutex);
@@ -442,6 +442,34 @@ int cti_channel_setop(struct device *dev, enum cti_chan_set_op op,
 	return err;
 }
 
+static bool cti_add_sysfs_link(struct cti_drvdata *drvdata,
+			       struct cti_trig_con *tc)
+{
+	struct coresight_sysfs_link link_info;
+	int link_err = 0;
+
+	link_info.orig = drvdata->csdev;
+	link_info.orig_name = tc->con_dev_name;
+	link_info.target = tc->con_dev;
+	link_info.target_name = dev_name(&drvdata->csdev->dev);
+
+	link_err = coresight_add_sysfs_link(&link_info);
+	if (link_err)
+		dev_warn(&drvdata->csdev->dev,
+			 "Failed to set CTI sysfs link %s<=>%s\n",
+			 link_info.orig_name, link_info.target_name);
+	return !link_err;
+}
+
+static void cti_remove_sysfs_link(struct cti_trig_con *tc)
+{
+	struct coresight_sysfs_link link_info;
+
+	link_info.orig_name = tc->con_dev_name;
+	link_info.target = tc->con_dev;
+	coresight_remove_sysfs_link(&link_info);
+}
+
 /*
  * Look for a matching connection device name in the list of connections.
  * If found then swap in the csdev name, set trig con association pointer
@@ -452,6 +480,8 @@ cti_match_fixup_csdev(struct cti_device *ctidev, const char *node_name,
 		      struct coresight_device *csdev)
 {
 	struct cti_trig_con *tc;
+	struct cti_drvdata *drvdata = container_of(ctidev, struct cti_drvdata,
+						   ctidev);
 
 	list_for_each_entry(tc, &ctidev->trig_cons, node) {
 		if (tc->con_dev_name) {
@@ -459,7 +489,12 @@ cti_match_fixup_csdev(struct cti_device *ctidev, const char *node_name,
 				/* match: so swap in csdev name & dev */
 				tc->con_dev_name = dev_name(&csdev->dev);
 				tc->con_dev = csdev;
-				return true;
+				/* try to set sysfs link */
+				if (cti_add_sysfs_link(drvdata, tc))
+					return true;
+				/* link failed - remove CTI reference */
+				tc->con_dev = NULL;
+				break;
 			}
 		}
 	}
@@ -522,6 +557,7 @@ void cti_remove_assoc_from_csdev(struct coresight_device *csdev)
 		ctidev = &ctidrv->ctidev;
 		list_for_each_entry(tc, &ctidev->trig_cons, node) {
 			if (tc->con_dev == csdev->ect_dev) {
+				cti_remove_sysfs_link(tc);
 				tc->con_dev = NULL;
 				break;
 			}
@@ -543,10 +579,16 @@ static void cti_update_conn_xrefs(struct cti_drvdata *drvdata)
 	struct cti_device *ctidev = &drvdata->ctidev;
 
 	list_for_each_entry(tc, &ctidev->trig_cons, node) {
-		if (tc->con_dev)
-			/* set tc->con_dev->ect_dev */
-			coresight_set_assoc_ectdev_mutex(tc->con_dev,
+		if (tc->con_dev) {
+			/* if we can set the sysfs link */
+			if (cti_add_sysfs_link(drvdata, tc))
+				/* set the CTI/csdev association */
+				coresight_set_assoc_ectdev_mutex(tc->con_dev,
 							 drvdata->csdev);
+			else
+				/* otherwise remove reference from CTI */
+				tc->con_dev = NULL;
+		}
 	}
 }
 
@@ -559,6 +601,8 @@ static void cti_remove_conn_xrefs(struct cti_drvdata *drvdata)
 		if (tc->con_dev) {
 			coresight_set_assoc_ectdev_mutex(tc->con_dev,
 							 NULL);
+			cti_remove_sysfs_link(tc);
+			tc->con_dev = NULL;
 		}
 	}
 }
@@ -578,12 +622,12 @@ int cti_disable(struct coresight_device *csdev)
 	return cti_disable_hw(drvdata);
 }
 
-const struct coresight_ops_ect cti_ops_ect = {
+static const struct coresight_ops_ect cti_ops_ect = {
 	.enable = cti_enable,
 	.disable = cti_disable,
 };
 
-const struct coresight_ops cti_ops = {
+static const struct coresight_ops cti_ops = {
 	.ect_ops = &cti_ops_ect,
 };
 
diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c
index 3810290e6d07..03e3f2590191 100644
--- a/drivers/hwtracing/coresight/coresight-etb10.c
+++ b/drivers/hwtracing/coresight/coresight-etb10.c
@@ -717,7 +717,7 @@ static const struct attribute_group coresight_etb_mgmt_group = {
 	.name = "mgmt",
 };
 
-const struct attribute_group *coresight_etb_groups[] = {
+static const struct attribute_group *coresight_etb_groups[] = {
 	&coresight_etb_group,
 	&coresight_etb_mgmt_group,
 	NULL,
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
index a90d757f7043..94c5f204998e 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -1554,8 +1554,10 @@ static const struct amba_id etm4_ids[] = {
 	CS_AMBA_UCI_ID(0x000bb9da, uci_id_etm4),/* Cortex-A35 */
 	CS_AMBA_UCI_ID(0x000f0205, uci_id_etm4),/* Qualcomm Kryo */
 	CS_AMBA_UCI_ID(0x000f0211, uci_id_etm4),/* Qualcomm Kryo */
-	CS_AMBA_ID(0x000bb802),			/* Qualcomm Kryo 385 Cortex-A55 */
-	CS_AMBA_ID(0x000bb803),			/* Qualcomm Kryo 385 Cortex-A75 */
+	CS_AMBA_UCI_ID(0x000bb802, uci_id_etm4),/* Qualcomm Kryo 385 Cortex-A55 */
+	CS_AMBA_UCI_ID(0x000bb803, uci_id_etm4),/* Qualcomm Kryo 385 Cortex-A75 */
+	CS_AMBA_UCI_ID(0x000bb805, uci_id_etm4),/* Qualcomm Kryo 4XX Cortex-A55 */
+	CS_AMBA_UCI_ID(0x000bb804, uci_id_etm4),/* Qualcomm Kryo 4XX Cortex-A76 */
 	CS_AMBA_UCI_ID(0x000cc0af, uci_id_etm4),/* Marvell ThunderX2 */
 	{},
 };
diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c
index 43418a2126ff..d58dcd0ab514 100644
--- a/drivers/hwtracing/coresight/coresight-platform.c
+++ b/drivers/hwtracing/coresight/coresight-platform.c
@@ -87,6 +87,7 @@ static void of_coresight_get_ports_legacy(const struct device_node *node,
 					  int *nr_inport, int *nr_outport)
 {
 	struct device_node *ep = NULL;
+	struct of_endpoint endpoint;
 	int in = 0, out = 0;
 
 	do {
@@ -94,10 +95,16 @@ static void of_coresight_get_ports_legacy(const struct device_node *node,
 		if (!ep)
 			break;
 
-		if (of_coresight_legacy_ep_is_input(ep))
-			in++;
-		else
-			out++;
+		if (of_graph_parse_endpoint(ep, &endpoint))
+			continue;
+
+		if (of_coresight_legacy_ep_is_input(ep)) {
+			in = (endpoint.port + 1 > in) ?
+				endpoint.port + 1 : in;
+		} else {
+			out = (endpoint.port + 1) > out ?
+				endpoint.port + 1 : out;
+		}
 
 	} while (ep);
 
@@ -137,9 +144,16 @@ of_coresight_count_ports(struct device_node *port_parent)
 {
 	int i = 0;
 	struct device_node *ep = NULL;
+	struct of_endpoint endpoint;
+
+	while ((ep = of_graph_get_next_endpoint(port_parent, ep))) {
+		/* Defer error handling to parsing */
+		if (of_graph_parse_endpoint(ep, &endpoint))
+			continue;
+		if (endpoint.port + 1 > i)
+			i = endpoint.port + 1;
+	}
 
-	while ((ep = of_graph_get_next_endpoint(port_parent, ep)))
-		i++;
 	return i;
 }
 
@@ -191,14 +205,12 @@ static int of_coresight_get_cpu(struct device *dev)
  * Parses the local port, remote device name and the remote port.
  *
  * Returns :
- *	 1	- If the parsing is successful and a connection record
- *		  was created for an output connection.
  *	 0	- If the parsing completed without any fatal errors.
  *	-Errno	- Fatal error, abort the scanning.
  */
 static int of_coresight_parse_endpoint(struct device *dev,
 				       struct device_node *ep,
-				       struct coresight_connection *conn)
+				       struct coresight_platform_data *pdata)
 {
 	int ret = 0;
 	struct of_endpoint endpoint, rendpoint;
@@ -206,6 +218,7 @@ static int of_coresight_parse_endpoint(struct device *dev,
 	struct device_node *rep = NULL;
 	struct device *rdev = NULL;
 	struct fwnode_handle *rdev_fwnode;
+	struct coresight_connection *conn;
 
 	do {
 		/* Parse the local port details */
@@ -232,6 +245,13 @@ static int of_coresight_parse_endpoint(struct device *dev,
 			break;
 		}
 
+		conn = &pdata->conns[endpoint.port];
+		if (conn->child_fwnode) {
+			dev_warn(dev, "Duplicate output port %d\n",
+				 endpoint.port);
+			ret = -EINVAL;
+			break;
+		}
 		conn->outport = endpoint.port;
 		/*
 		 * Hold the refcount to the target device. This could be
@@ -244,7 +264,6 @@ static int of_coresight_parse_endpoint(struct device *dev,
 		conn->child_fwnode = fwnode_handle_get(rdev_fwnode);
 		conn->child_port = rendpoint.port;
 		/* Connection record updated */
-		ret = 1;
 	} while (0);
 
 	of_node_put(rparent);
@@ -258,7 +277,6 @@ static int of_get_coresight_platform_data(struct device *dev,
 					  struct coresight_platform_data *pdata)
 {
 	int ret = 0;
-	struct coresight_connection *conn;
 	struct device_node *ep = NULL;
 	const struct device_node *parent = NULL;
 	bool legacy_binding = false;
@@ -287,8 +305,6 @@ static int of_get_coresight_platform_data(struct device *dev,
 		dev_warn_once(dev, "Uses obsolete Coresight DT bindings\n");
 	}
 
-	conn = pdata->conns;
-
 	/* Iterate through each output port to discover topology */
 	while ((ep = of_graph_get_next_endpoint(parent, ep))) {
 		/*
@@ -300,15 +316,9 @@ static int of_get_coresight_platform_data(struct device *dev,
 		if (legacy_binding && of_coresight_legacy_ep_is_input(ep))
 			continue;
 
-		ret = of_coresight_parse_endpoint(dev, ep, conn);
-		switch (ret) {
-		case 1:
-			conn++;		/* Fall through */
-		case 0:
-			break;
-		default:
+		ret = of_coresight_parse_endpoint(dev, ep, pdata);
+		if (ret)
 			return ret;
-		}
 	}
 
 	return 0;
@@ -647,6 +657,16 @@ static int acpi_coresight_parse_link(struct acpi_device *adev,
 		 *    coresight_remove_match().
 		 */
 		conn->child_fwnode = fwnode_handle_get(&r_adev->fwnode);
+	} else if (dir == ACPI_CORESIGHT_LINK_SLAVE) {
+		/*
+		 * We are only interested in the port number
+		 * for the input ports at this component.
+		 * Store the port number in child_port.
+		 */
+		conn->child_port = fields[0].integer.value;
+	} else {
+		/* Invalid direction */
+		return -EINVAL;
 	}
 
 	return dir;
@@ -692,10 +712,20 @@ static int acpi_coresight_parse_graph(struct acpi_device *adev,
 			return dir;
 
 		if (dir == ACPI_CORESIGHT_LINK_MASTER) {
-			pdata->nr_outport++;
+			if (ptr->outport > pdata->nr_outport)
+				pdata->nr_outport = ptr->outport;
 			ptr++;
 		} else {
-			pdata->nr_inport++;
+			WARN_ON(pdata->nr_inport == ptr->child_port);
+			/*
+			 * We do not track input port connections for a device.
+			 * However we need the highest port number described,
+			 * which can be recorded now and reuse this connection
+			 * record for an output connection. Hence, do not move
+			 * the ptr for input connections
+			 */
+			if (ptr->child_port > pdata->nr_inport)
+				pdata->nr_inport = ptr->child_port;
 		}
 	}
 
@@ -704,8 +734,13 @@ static int acpi_coresight_parse_graph(struct acpi_device *adev,
 		return rc;
 
 	/* Copy the connection information to the final location */
-	for (i = 0; i < pdata->nr_outport; i++)
-		pdata->conns[i] = conns[i];
+	for (i = 0; conns + i < ptr; i++) {
+		int port = conns[i].outport;
+
+		/* Duplicate output port */
+		WARN_ON(pdata->conns[port].child_fwnode);
+		pdata->conns[port] = conns[i];
+	}
 
 	devm_kfree(&adev->dev, conns);
 	return 0;
@@ -822,7 +857,7 @@ coresight_get_platform_data(struct device *dev)
 error:
 	if (!IS_ERR_OR_NULL(pdata))
 		/* Cleanup the connection information */
-		coresight_release_platform_data(pdata);
+		coresight_release_platform_data(NULL, pdata);
 	return ERR_PTR(ret);
 }
 EXPORT_SYMBOL_GPL(coresight_get_platform_data);
diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
index 890f9a5c97c6..5a36f0f50899 100644
--- a/drivers/hwtracing/coresight/coresight-priv.h
+++ b/drivers/hwtracing/coresight/coresight-priv.h
@@ -153,6 +153,15 @@ struct coresight_device *coresight_get_sink_by_id(u32 id);
 struct list_head *coresight_build_path(struct coresight_device *csdev,
 				       struct coresight_device *sink);
 void coresight_release_path(struct list_head *path);
+int coresight_add_sysfs_link(struct coresight_sysfs_link *info);
+void coresight_remove_sysfs_link(struct coresight_sysfs_link *info);
+int coresight_create_conns_sysfs_group(struct coresight_device *csdev);
+void coresight_remove_conns_sysfs_group(struct coresight_device *csdev);
+int coresight_make_links(struct coresight_device *orig,
+			 struct coresight_connection *conn,
+			 struct coresight_device *target);
+void coresight_remove_links(struct coresight_device *orig,
+			    struct coresight_connection *conn);
 
 #ifdef CONFIG_CORESIGHT_SOURCE_ETM3X
 extern int etm_readl_cp14(u32 off, unsigned int *val);
@@ -211,7 +220,8 @@ static inline void *coresight_get_uci_data(const struct amba_id *id)
 	return 0;
 }
 
-void coresight_release_platform_data(struct coresight_platform_data *pdata);
+void coresight_release_platform_data(struct coresight_device *csdev,
+				     struct coresight_platform_data *pdata);
 struct coresight_device *
 coresight_find_csdev_by_fwnode(struct fwnode_handle *r_fwnode);
 void coresight_set_assoc_ectdev_mutex(struct coresight_device *csdev,
diff --git a/drivers/hwtracing/coresight/coresight-sysfs.c b/drivers/hwtracing/coresight/coresight-sysfs.c
new file mode 100644
index 000000000000..82afeaf2ccc4
--- /dev/null
+++ b/drivers/hwtracing/coresight/coresight-sysfs.c
@@ -0,0 +1,204 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019, Linaro Limited, All rights reserved.
+ * Author: Mike Leach <mike.leach@linaro.org>
+ */
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+
+#include "coresight-priv.h"
+
+/*
+ * Connections group - links attribute.
+ * Count of created links between coresight components in the group.
+ */
+static ssize_t nr_links_show(struct device *dev,
+			     struct device_attribute *attr,
+			     char *buf)
+{
+	struct coresight_device *csdev = to_coresight_device(dev);
+
+	return sprintf(buf, "%d\n", csdev->nr_links);
+}
+static DEVICE_ATTR_RO(nr_links);
+
+static struct attribute *coresight_conns_attrs[] = {
+	&dev_attr_nr_links.attr,
+	NULL,
+};
+
+static struct attribute_group coresight_conns_group = {
+	.attrs = coresight_conns_attrs,
+	.name = "connections",
+};
+
+/*
+ * Create connections group for CoreSight devices.
+ * This group will then be used to collate the sysfs links between
+ * devices.
+ */
+int coresight_create_conns_sysfs_group(struct coresight_device *csdev)
+{
+	int ret = 0;
+
+	if (!csdev)
+		return -EINVAL;
+
+	ret = sysfs_create_group(&csdev->dev.kobj, &coresight_conns_group);
+	if (ret)
+		return ret;
+
+	csdev->has_conns_grp = true;
+	return ret;
+}
+
+void coresight_remove_conns_sysfs_group(struct coresight_device *csdev)
+{
+	if (!csdev)
+		return;
+
+	if (csdev->has_conns_grp) {
+		sysfs_remove_group(&csdev->dev.kobj, &coresight_conns_group);
+		csdev->has_conns_grp = false;
+	}
+}
+
+int coresight_add_sysfs_link(struct coresight_sysfs_link *info)
+{
+	int ret = 0;
+
+	if (!info)
+		return -EINVAL;
+	if (!info->orig || !info->target ||
+	    !info->orig_name || !info->target_name)
+		return -EINVAL;
+	if (!info->orig->has_conns_grp || !info->target->has_conns_grp)
+		return -EINVAL;
+
+	/* first link orig->target */
+	ret = sysfs_add_link_to_group(&info->orig->dev.kobj,
+				      coresight_conns_group.name,
+				      &info->target->dev.kobj,
+				      info->orig_name);
+	if (ret)
+		return ret;
+
+	/* second link target->orig */
+	ret = sysfs_add_link_to_group(&info->target->dev.kobj,
+				      coresight_conns_group.name,
+				      &info->orig->dev.kobj,
+				      info->target_name);
+
+	/* error in second link - remove first - otherwise inc counts */
+	if (ret) {
+		sysfs_remove_link_from_group(&info->orig->dev.kobj,
+					     coresight_conns_group.name,
+					     info->orig_name);
+	} else {
+		info->orig->nr_links++;
+		info->target->nr_links++;
+	}
+
+	return ret;
+}
+
+void coresight_remove_sysfs_link(struct coresight_sysfs_link *info)
+{
+	if (!info)
+		return;
+	if (!info->orig || !info->target ||
+	    !info->orig_name || !info->target_name)
+		return;
+
+	sysfs_remove_link_from_group(&info->orig->dev.kobj,
+				     coresight_conns_group.name,
+				     info->orig_name);
+
+	sysfs_remove_link_from_group(&info->target->dev.kobj,
+				     coresight_conns_group.name,
+				     info->target_name);
+
+	info->orig->nr_links--;
+	info->target->nr_links--;
+}
+
+/*
+ * coresight_make_links: Make a link for a connection from a @orig
+ * device to @target, represented by @conn.
+ *
+ *   e.g, for devOrig[output_X] -> devTarget[input_Y] is represented
+ *   as two symbolic links :
+ *
+ *	/sys/.../devOrig/out:X	-> /sys/.../devTarget/
+ *	/sys/.../devTarget/in:Y	-> /sys/.../devOrig/
+ *
+ * The link names are allocated for a device where it appears. i.e, the
+ * "out" link on the master and "in" link on the slave device.
+ * The link info is stored in the connection record for avoiding
+ * the reconstruction of names for removal.
+ */
+int coresight_make_links(struct coresight_device *orig,
+			 struct coresight_connection *conn,
+			 struct coresight_device *target)
+{
+	int ret = -ENOMEM;
+	char *outs = NULL, *ins = NULL;
+	struct coresight_sysfs_link *link = NULL;
+
+	do {
+		outs = devm_kasprintf(&orig->dev, GFP_KERNEL,
+				      "out:%d", conn->outport);
+		if (!outs)
+			break;
+		ins = devm_kasprintf(&target->dev, GFP_KERNEL,
+				     "in:%d", conn->child_port);
+		if (!ins)
+			break;
+		link = devm_kzalloc(&orig->dev,
+				    sizeof(struct coresight_sysfs_link),
+				    GFP_KERNEL);
+		if (!link)
+			break;
+
+		link->orig = orig;
+		link->target = target;
+		link->orig_name = outs;
+		link->target_name = ins;
+
+		ret = coresight_add_sysfs_link(link);
+		if (ret)
+			break;
+
+		conn->link = link;
+
+		/*
+		 * Install the device connection. This also indicates that
+		 * the links are operational on both ends.
+		 */
+		conn->child_dev = target;
+		return 0;
+	} while (0);
+
+	return ret;
+}
+
+/*
+ * coresight_remove_links: Remove the sysfs links for a given connection @conn,
+ * from @orig device to @target device. See coresight_make_links() for more
+ * details.
+ */
+void coresight_remove_links(struct coresight_device *orig,
+			    struct coresight_connection *conn)
+{
+	if (!orig || !conn->link)
+		return;
+
+	coresight_remove_sysfs_link(conn->link);
+
+	devm_kfree(&conn->child_dev->dev, conn->link->target_name);
+	devm_kfree(&orig->dev, conn->link->orig_name);
+	devm_kfree(&orig->dev, conn->link);
+	conn->link = NULL;
+	conn->child_dev = NULL;
+}
diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c
index c71553c09f8e..f3efbb3b2b4d 100644
--- a/drivers/hwtracing/coresight/coresight.c
+++ b/drivers/hwtracing/coresight/coresight.c
@@ -1031,7 +1031,7 @@ static void coresight_device_release(struct device *dev)
 
 static int coresight_orphan_match(struct device *dev, void *data)
 {
-	int i;
+	int i, ret = 0;
 	bool still_orphan = false;
 	struct coresight_device *csdev, *i_csdev;
 	struct coresight_connection *conn;
@@ -1053,49 +1053,62 @@ static int coresight_orphan_match(struct device *dev, void *data)
 	for (i = 0; i < i_csdev->pdata->nr_outport; i++) {
 		conn = &i_csdev->pdata->conns[i];
 
+		/* Skip the port if FW doesn't describe it */
+		if (!conn->child_fwnode)
+			continue;
 		/* We have found at least one orphan connection */
 		if (conn->child_dev == NULL) {
 			/* Does it match this newly added device? */
-			if (conn->child_fwnode == csdev->dev.fwnode)
-				conn->child_dev = csdev;
-			else
+			if (conn->child_fwnode == csdev->dev.fwnode) {
+				ret = coresight_make_links(i_csdev,
+							   conn, csdev);
+				if (ret)
+					return ret;
+			} else {
 				/* This component still has an orphan */
 				still_orphan = true;
+			}
 		}
 	}
 
 	i_csdev->orphan = still_orphan;
 
 	/*
-	 * Returning '0' ensures that all known component on the
-	 * bus will be checked.
+	 * Returning '0' in case we didn't encounter any error,
+	 * ensures that all known component on the bus will be checked.
 	 */
 	return 0;
 }
 
-static void coresight_fixup_orphan_conns(struct coresight_device *csdev)
+static int coresight_fixup_orphan_conns(struct coresight_device *csdev)
 {
-	/*
-	 * No need to check for a return value as orphan connection(s)
-	 * are hooked-up with each newly added component.
-	 */
-	bus_for_each_dev(&coresight_bustype, NULL,
+	return bus_for_each_dev(&coresight_bustype, NULL,
 			 csdev, coresight_orphan_match);
 }
 
 
-static void coresight_fixup_device_conns(struct coresight_device *csdev)
+static int coresight_fixup_device_conns(struct coresight_device *csdev)
 {
-	int i;
+	int i, ret = 0;
 
 	for (i = 0; i < csdev->pdata->nr_outport; i++) {
 		struct coresight_connection *conn = &csdev->pdata->conns[i];
 
+		if (!conn->child_fwnode)
+			continue;
 		conn->child_dev =
 			coresight_find_csdev_by_fwnode(conn->child_fwnode);
-		if (!conn->child_dev)
+		if (conn->child_dev) {
+			ret = coresight_make_links(csdev, conn,
+						   conn->child_dev);
+			if (ret)
+				break;
+		} else {
 			csdev->orphan = true;
+		}
 	}
+
+	return 0;
 }
 
 static int coresight_remove_match(struct device *dev, void *data)
@@ -1118,12 +1131,12 @@ static int coresight_remove_match(struct device *dev, void *data)
 	for (i = 0; i < iterator->pdata->nr_outport; i++) {
 		conn = &iterator->pdata->conns[i];
 
-		if (conn->child_dev == NULL)
+		if (conn->child_dev == NULL || conn->child_fwnode == NULL)
 			continue;
 
 		if (csdev->dev.fwnode == conn->child_fwnode) {
 			iterator->orphan = true;
-			conn->child_dev = NULL;
+			coresight_remove_links(iterator, conn);
 			/*
 			 * Drop the reference to the handle for the remote
 			 * device acquired in parsing the connections from
@@ -1213,16 +1226,27 @@ postcore_initcall(coresight_init);
  * coresight_release_platform_data: Release references to the devices connected
  * to the output port of this device.
  */
-void coresight_release_platform_data(struct coresight_platform_data *pdata)
+void coresight_release_platform_data(struct coresight_device *csdev,
+				     struct coresight_platform_data *pdata)
 {
 	int i;
+	struct coresight_connection *conns = pdata->conns;
 
 	for (i = 0; i < pdata->nr_outport; i++) {
-		if (pdata->conns[i].child_fwnode) {
-			fwnode_handle_put(pdata->conns[i].child_fwnode);
+		/* If we have made the links, remove them now */
+		if (csdev && conns[i].child_dev)
+			coresight_remove_links(csdev, &conns[i]);
+		/*
+		 * Drop the refcount and clear the handle as this device
+		 * is going away
+		 */
+		if (conns[i].child_fwnode) {
+			fwnode_handle_put(conns[i].child_fwnode);
 			pdata->conns[i].child_fwnode = NULL;
 		}
 	}
+	if (csdev)
+		coresight_remove_conns_sysfs_group(csdev);
 }
 
 struct coresight_device *coresight_register(struct coresight_desc *desc)
@@ -1304,11 +1328,19 @@ struct coresight_device *coresight_register(struct coresight_desc *desc)
 
 	mutex_lock(&coresight_mutex);
 
-	coresight_fixup_device_conns(csdev);
-	coresight_fixup_orphan_conns(csdev);
-	cti_add_assoc_to_csdev(csdev);
+	ret = coresight_create_conns_sysfs_group(csdev);
+	if (!ret)
+		ret = coresight_fixup_device_conns(csdev);
+	if (!ret)
+		ret = coresight_fixup_orphan_conns(csdev);
+	if (!ret)
+		cti_add_assoc_to_csdev(csdev);
 
 	mutex_unlock(&coresight_mutex);
+	if (ret) {
+		coresight_unregister(csdev);
+		return ERR_PTR(ret);
+	}
 
 	return csdev;
 
@@ -1316,7 +1348,7 @@ struct coresight_device *coresight_register(struct coresight_desc *desc)
 	kfree(csdev);
 err_out:
 	/* Cleanup the connection information */
-	coresight_release_platform_data(desc->pdata);
+	coresight_release_platform_data(NULL, desc->pdata);
 	return ERR_PTR(ret);
 }
 EXPORT_SYMBOL_GPL(coresight_register);
@@ -1326,7 +1358,7 @@ void coresight_unregister(struct coresight_device *csdev)
 	etm_perf_del_symlink_sink(csdev);
 	/* Remove references of that device in the topology */
 	coresight_remove_conns(csdev);
-	coresight_release_platform_data(csdev->pdata);
+	coresight_release_platform_data(csdev, csdev->pdata);
 	device_unregister(&csdev->dev);
 }
 EXPORT_SYMBOL_GPL(coresight_unregister);
diff --git a/drivers/i2c/busses/i2c-altera.c b/drivers/i2c/busses/i2c-altera.c
index 20ef63820c77..8f62ba10215d 100644
--- a/drivers/i2c/busses/i2c-altera.c
+++ b/drivers/i2c/busses/i2c-altera.c
@@ -382,16 +382,13 @@ static const struct i2c_algorithm altr_i2c_algo = {
 static int altr_i2c_probe(struct platform_device *pdev)
 {
 	struct altr_i2c_dev *idev = NULL;
-	struct resource *res;
 	int irq, ret;
-	u32 val;
 
 	idev = devm_kzalloc(&pdev->dev, sizeof(*idev), GFP_KERNEL);
 	if (!idev)
 		return -ENOMEM;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	idev->base = devm_ioremap_resource(&pdev->dev, res);
+	idev->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(idev->base))
 		return PTR_ERR(idev->base);
 
@@ -411,17 +408,17 @@ static int altr_i2c_probe(struct platform_device *pdev)
 	init_completion(&idev->msg_complete);
 	spin_lock_init(&idev->lock);
 
-	val = device_property_read_u32(idev->dev, "fifo-size",
+	ret = device_property_read_u32(idev->dev, "fifo-size",
 				       &idev->fifo_size);
-	if (val) {
+	if (ret) {
 		dev_err(&pdev->dev, "FIFO size set to default of %d\n",
 			ALTR_I2C_DFLT_FIFO_SZ);
 		idev->fifo_size = ALTR_I2C_DFLT_FIFO_SZ;
 	}
 
-	val = device_property_read_u32(idev->dev, "clock-frequency",
+	ret = device_property_read_u32(idev->dev, "clock-frequency",
 				       &idev->bus_clk_rate);
-	if (val) {
+	if (ret) {
 		dev_err(&pdev->dev, "Default to 100kHz\n");
 		idev->bus_clk_rate = I2C_MAX_STANDARD_MODE_FREQ;	/* default clock rate */
 	}
diff --git a/drivers/i2c/busses/i2c-axxia.c b/drivers/i2c/busses/i2c-axxia.c
index be3681d08a8d..d45e2290c3f7 100644
--- a/drivers/i2c/busses/i2c-axxia.c
+++ b/drivers/i2c/busses/i2c-axxia.c
@@ -734,7 +734,6 @@ static int axxia_i2c_probe(struct platform_device *pdev)
 {
 	struct device_node *np = pdev->dev.of_node;
 	struct axxia_i2c_dev *idev = NULL;
-	struct resource *res;
 	void __iomem *base;
 	int ret = 0;
 
@@ -742,8 +741,7 @@ static int axxia_i2c_probe(struct platform_device *pdev)
 	if (!idev)
 		return -ENOMEM;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	base = devm_ioremap_resource(&pdev->dev, res);
+	base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(base))
 		return PTR_ERR(base);
 
diff --git a/drivers/i2c/busses/i2c-bcm-kona.c b/drivers/i2c/busses/i2c-bcm-kona.c
index 572aebbb254e..3e63f706f66b 100644
--- a/drivers/i2c/busses/i2c-bcm-kona.c
+++ b/drivers/i2c/busses/i2c-bcm-kona.c
@@ -750,7 +750,6 @@ static int bcm_kona_i2c_probe(struct platform_device *pdev)
 	int rc = 0;
 	struct bcm_kona_i2c_dev *dev;
 	struct i2c_adapter *adap;
-	struct resource *iomem;
 
 	/* Allocate memory for private data structure */
 	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
@@ -762,8 +761,7 @@ static int bcm_kona_i2c_probe(struct platform_device *pdev)
 	init_completion(&dev->done);
 
 	/* Map hardware registers */
-	iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	dev->base = devm_ioremap_resource(dev->device, iomem);
+	dev->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(dev->base))
 		return -ENOMEM;
 
diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c
index 89d58f7d2a25..4b72398af505 100644
--- a/drivers/i2c/busses/i2c-cadence.c
+++ b/drivers/i2c/busses/i2c-cadence.c
@@ -23,6 +23,7 @@
 #define CDNS_I2C_ISR_OFFSET		0x10 /* IRQ Status Register, RW */
 #define CDNS_I2C_XFER_SIZE_OFFSET	0x14 /* Transfer Size Register, RW */
 #define CDNS_I2C_TIME_OUT_OFFSET	0x1C /* Time Out Register, RW */
+#define CDNS_I2C_IMR_OFFSET		0x20 /* IRQ Mask Register, RO */
 #define CDNS_I2C_IER_OFFSET		0x24 /* IRQ Enable Register, WO */
 #define CDNS_I2C_IDR_OFFSET		0x28 /* IRQ Disable Register, WO */
 
@@ -40,9 +41,17 @@
 #define CDNS_I2C_CR_DIVB_SHIFT		8
 #define CDNS_I2C_CR_DIVB_MASK		(0x3f << CDNS_I2C_CR_DIVB_SHIFT)
 
+#define CDNS_I2C_CR_MASTER_EN_MASK	(CDNS_I2C_CR_NEA | \
+					 CDNS_I2C_CR_ACK_EN | \
+					 CDNS_I2C_CR_MS)
+
+#define CDNS_I2C_CR_SLAVE_EN_MASK	~CDNS_I2C_CR_MASTER_EN_MASK
+
 /* Status Register Bit mask definitions */
 #define CDNS_I2C_SR_BA		BIT(8)
+#define CDNS_I2C_SR_TXDV	BIT(6)
 #define CDNS_I2C_SR_RXDV	BIT(5)
+#define CDNS_I2C_SR_RXRW	BIT(3)
 
 /*
  * I2C Address Register Bit mask definitions
@@ -91,6 +100,14 @@
 					 CDNS_I2C_IXR_DATA | \
 					 CDNS_I2C_IXR_COMP)
 
+#define CDNS_I2C_IXR_SLAVE_INTR_MASK	(CDNS_I2C_IXR_RX_UNF | \
+					 CDNS_I2C_IXR_TX_OVF | \
+					 CDNS_I2C_IXR_RX_OVF | \
+					 CDNS_I2C_IXR_TO | \
+					 CDNS_I2C_IXR_NACK | \
+					 CDNS_I2C_IXR_DATA | \
+					 CDNS_I2C_IXR_COMP)
+
 #define CDNS_I2C_TIMEOUT		msecs_to_jiffies(1000)
 /* timeout for pm runtime autosuspend */
 #define CNDS_I2C_PM_TIMEOUT		1000	/* ms */
@@ -114,6 +131,32 @@
 #define cdns_i2c_readreg(offset)       readl_relaxed(id->membase + offset)
 #define cdns_i2c_writereg(val, offset) writel_relaxed(val, id->membase + offset)
 
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+/**
+ * enum cdns_i2c_mode - I2C Controller current operating mode
+ *
+ * @CDNS_I2C_MODE_SLAVE:       I2C controller operating in slave mode
+ * @CDNS_I2C_MODE_MASTER:      I2C Controller operating in master mode
+ */
+enum cdns_i2c_mode {
+	CDNS_I2C_MODE_SLAVE,
+	CDNS_I2C_MODE_MASTER,
+};
+
+/**
+ * enum cdns_i2c_slave_mode - Slave state when I2C is operating in slave mode
+ *
+ * @CDNS_I2C_SLAVE_STATE_IDLE: I2C slave idle
+ * @CDNS_I2C_SLAVE_STATE_SEND: I2C slave sending data to master
+ * @CDNS_I2C_SLAVE_STATE_RECV: I2C slave receiving data from master
+ */
+enum cdns_i2c_slave_state {
+	CDNS_I2C_SLAVE_STATE_IDLE,
+	CDNS_I2C_SLAVE_STATE_SEND,
+	CDNS_I2C_SLAVE_STATE_RECV,
+};
+#endif
+
 /**
  * struct cdns_i2c - I2C device private data structure
  *
@@ -135,6 +178,10 @@
  * @clk:		Pointer to struct clk
  * @clk_rate_change_nb:	Notifier block for clock rate changes
  * @quirks:		flag for broken hold bit usage in r1p10
+ * @ctrl_reg_diva_divb: value of fields DIV_A and DIV_B from CR register
+ * @slave:		Registered slave instance.
+ * @dev_mode:		I2C operating role(master/slave).
+ * @slave_state:	I2C Slave state(idle/read/write).
  */
 struct cdns_i2c {
 	struct device		*dev;
@@ -155,6 +202,12 @@ struct cdns_i2c {
 	struct clk *clk;
 	struct notifier_block clk_rate_change_nb;
 	u32 quirks;
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+	u16 ctrl_reg_diva_divb;
+	struct i2c_client *slave;
+	enum cdns_i2c_mode dev_mode;
+	enum cdns_i2c_slave_state slave_state;
+#endif
 };
 
 struct cdns_platform_data {
@@ -183,17 +236,155 @@ static inline bool cdns_is_holdquirk(struct cdns_i2c *id, bool hold_wrkaround)
 		(id->curr_recv_count == CDNS_I2C_FIFO_DEPTH + 1));
 }
 
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+static void cdns_i2c_set_mode(enum cdns_i2c_mode mode, struct cdns_i2c *id)
+{
+	/* Disable all interrupts */
+	cdns_i2c_writereg(CDNS_I2C_IXR_ALL_INTR_MASK, CDNS_I2C_IDR_OFFSET);
+
+	/* Clear FIFO and transfer size */
+	cdns_i2c_writereg(CDNS_I2C_CR_CLR_FIFO, CDNS_I2C_CR_OFFSET);
+
+	/* Update device mode and state */
+	id->dev_mode = mode;
+	id->slave_state = CDNS_I2C_SLAVE_STATE_IDLE;
+
+	switch (mode) {
+	case CDNS_I2C_MODE_MASTER:
+		/* Enable i2c master */
+		cdns_i2c_writereg(id->ctrl_reg_diva_divb |
+				  CDNS_I2C_CR_MASTER_EN_MASK,
+				  CDNS_I2C_CR_OFFSET);
+		/*
+		 * This delay is needed to give the IP some time to switch to
+		 * the master mode. With lower values(like 110 us) i2cdetect
+		 * will not detect any slave and without this delay, the IP will
+		 * trigger a timeout interrupt.
+		 */
+		usleep_range(115, 125);
+		break;
+	case CDNS_I2C_MODE_SLAVE:
+		/* Enable i2c slave */
+		cdns_i2c_writereg(id->ctrl_reg_diva_divb &
+				  CDNS_I2C_CR_SLAVE_EN_MASK,
+				  CDNS_I2C_CR_OFFSET);
+
+		/* Setting slave address */
+		cdns_i2c_writereg(id->slave->addr & CDNS_I2C_ADDR_MASK,
+				  CDNS_I2C_ADDR_OFFSET);
+
+		/* Enable slave send/receive interrupts */
+		cdns_i2c_writereg(CDNS_I2C_IXR_SLAVE_INTR_MASK,
+				  CDNS_I2C_IER_OFFSET);
+		break;
+	}
+}
+
+static void cdns_i2c_slave_rcv_data(struct cdns_i2c *id)
+{
+	u8 bytes;
+	unsigned char data;
+
+	/* Prepare backend for data reception */
+	if (id->slave_state == CDNS_I2C_SLAVE_STATE_IDLE) {
+		id->slave_state = CDNS_I2C_SLAVE_STATE_RECV;
+		i2c_slave_event(id->slave, I2C_SLAVE_WRITE_REQUESTED, NULL);
+	}
+
+	/* Fetch number of bytes to receive */
+	bytes = cdns_i2c_readreg(CDNS_I2C_XFER_SIZE_OFFSET);
+
+	/* Read data and send to backend */
+	while (bytes--) {
+		data = cdns_i2c_readreg(CDNS_I2C_DATA_OFFSET);
+		i2c_slave_event(id->slave, I2C_SLAVE_WRITE_RECEIVED, &data);
+	}
+}
+
+static void cdns_i2c_slave_send_data(struct cdns_i2c *id)
+{
+	u8 data;
+
+	/* Prepare backend for data transmission */
+	if (id->slave_state == CDNS_I2C_SLAVE_STATE_IDLE) {
+		id->slave_state = CDNS_I2C_SLAVE_STATE_SEND;
+		i2c_slave_event(id->slave, I2C_SLAVE_READ_REQUESTED, &data);
+	} else {
+		i2c_slave_event(id->slave, I2C_SLAVE_READ_PROCESSED, &data);
+	}
+
+	/* Send data over bus */
+	cdns_i2c_writereg(data, CDNS_I2C_DATA_OFFSET);
+}
+
 /**
- * cdns_i2c_isr - Interrupt handler for the I2C device
- * @irq:	irq number for the I2C device
- * @ptr:	void pointer to cdns_i2c structure
+ * cdns_i2c_slave_isr - Interrupt handler for the I2C device in slave role
+ * @ptr:       Pointer to I2C device private data
+ *
+ * This function handles the data interrupt and transfer complete interrupt of
+ * the I2C device in slave role.
+ *
+ * Return: IRQ_HANDLED always
+ */
+static irqreturn_t cdns_i2c_slave_isr(void *ptr)
+{
+	struct cdns_i2c *id = ptr;
+	unsigned int isr_status, i2c_status;
+
+	/* Fetch the interrupt status */
+	isr_status = cdns_i2c_readreg(CDNS_I2C_ISR_OFFSET);
+	cdns_i2c_writereg(isr_status, CDNS_I2C_ISR_OFFSET);
+
+	/* Ignore masked interrupts */
+	isr_status &= ~cdns_i2c_readreg(CDNS_I2C_IMR_OFFSET);
+
+	/* Fetch transfer mode (send/receive) */
+	i2c_status = cdns_i2c_readreg(CDNS_I2C_SR_OFFSET);
+
+	/* Handle data send/receive */
+	if (i2c_status & CDNS_I2C_SR_RXRW) {
+		/* Send data to master */
+		if (isr_status & CDNS_I2C_IXR_DATA)
+			cdns_i2c_slave_send_data(id);
+
+		if (isr_status & CDNS_I2C_IXR_COMP) {
+			id->slave_state = CDNS_I2C_SLAVE_STATE_IDLE;
+			i2c_slave_event(id->slave, I2C_SLAVE_STOP, NULL);
+		}
+	} else {
+		/* Receive data from master */
+		if (isr_status & CDNS_I2C_IXR_DATA)
+			cdns_i2c_slave_rcv_data(id);
+
+		if (isr_status & CDNS_I2C_IXR_COMP) {
+			cdns_i2c_slave_rcv_data(id);
+			id->slave_state = CDNS_I2C_SLAVE_STATE_IDLE;
+			i2c_slave_event(id->slave, I2C_SLAVE_STOP, NULL);
+		}
+	}
+
+	/* Master indicated xfer stop or fifo underflow/overflow */
+	if (isr_status & (CDNS_I2C_IXR_NACK | CDNS_I2C_IXR_RX_OVF |
+			  CDNS_I2C_IXR_RX_UNF | CDNS_I2C_IXR_TX_OVF)) {
+		id->slave_state = CDNS_I2C_SLAVE_STATE_IDLE;
+		i2c_slave_event(id->slave, I2C_SLAVE_STOP, NULL);
+		cdns_i2c_writereg(CDNS_I2C_CR_CLR_FIFO, CDNS_I2C_CR_OFFSET);
+	}
+
+	return IRQ_HANDLED;
+}
+#endif
+
+/**
+ * cdns_i2c_master_isr - Interrupt handler for the I2C device in master role
+ * @ptr:       Pointer to I2C device private data
  *
  * This function handles the data interrupt, transfer complete interrupt and
- * the error interrupts of the I2C device.
+ * the error interrupts of the I2C device in master role.
  *
  * Return: IRQ_HANDLED always
  */
-static irqreturn_t cdns_i2c_isr(int irq, void *ptr)
+static irqreturn_t cdns_i2c_master_isr(void *ptr)
 {
 	unsigned int isr_status, avail_bytes, updatetx;
 	unsigned int bytes_to_send;
@@ -357,6 +548,27 @@ static irqreturn_t cdns_i2c_isr(int irq, void *ptr)
 	return status;
 }
 
+/**
+ * cdns_i2c_isr - Interrupt handler for the I2C device
+ * @irq:	irq number for the I2C device
+ * @ptr:	void pointer to cdns_i2c structure
+ *
+ * This function passes the control to slave/master based on current role of
+ * i2c controller.
+ *
+ * Return: IRQ_HANDLED always
+ */
+static irqreturn_t cdns_i2c_isr(int irq, void *ptr)
+{
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+	struct cdns_i2c *id = ptr;
+
+	if (id->dev_mode == CDNS_I2C_MODE_SLAVE)
+		return cdns_i2c_slave_isr(ptr);
+#endif
+	return cdns_i2c_master_isr(ptr);
+}
+
 /**
  * cdns_i2c_mrecv - Prepare and start a master receive operation
  * @id:		pointer to the i2c device structure
@@ -577,10 +789,28 @@ static int cdns_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
 	u32 reg;
 	struct cdns_i2c *id = adap->algo_data;
 	bool hold_quirk;
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+	bool change_role = false;
+#endif
 
 	ret = pm_runtime_get_sync(id->dev);
 	if (ret < 0)
 		return ret;
+
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+	/* Check i2c operating mode and switch if possible */
+	if (id->dev_mode == CDNS_I2C_MODE_SLAVE) {
+		if (id->slave_state != CDNS_I2C_SLAVE_STATE_IDLE)
+			return -EAGAIN;
+
+		/* Set mode to master */
+		cdns_i2c_set_mode(CDNS_I2C_MODE_MASTER, id);
+
+		/* Mark flag to change role once xfer is completed */
+		change_role = true;
+	}
+#endif
+
 	/* Check if the bus is free */
 	if (cdns_i2c_readreg(CDNS_I2C_SR_OFFSET) & CDNS_I2C_SR_BA) {
 		ret = -EAGAIN;
@@ -639,7 +869,15 @@ static int cdns_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
 	}
 
 	ret = num;
+
 out:
+
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+	/* Switch i2c mode to slave */
+	if (change_role)
+		cdns_i2c_set_mode(CDNS_I2C_MODE_SLAVE, id);
+#endif
+
 	pm_runtime_mark_last_busy(id->dev);
 	pm_runtime_put_autosuspend(id->dev);
 	return ret;
@@ -653,14 +891,67 @@ static int cdns_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
  */
 static u32 cdns_i2c_func(struct i2c_adapter *adap)
 {
-	return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR |
-		(I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK) |
-		I2C_FUNC_SMBUS_BLOCK_DATA;
+	u32 func = I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR |
+			(I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK) |
+			I2C_FUNC_SMBUS_BLOCK_DATA;
+
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+	func |= I2C_FUNC_SLAVE;
+#endif
+
+	return func;
 }
 
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+static int cdns_reg_slave(struct i2c_client *slave)
+{
+	int ret;
+	struct cdns_i2c *id = container_of(slave->adapter, struct cdns_i2c,
+									adap);
+
+	if (id->slave)
+		return -EBUSY;
+
+	if (slave->flags & I2C_CLIENT_TEN)
+		return -EAFNOSUPPORT;
+
+	ret = pm_runtime_get_sync(id->dev);
+	if (ret < 0)
+		return ret;
+
+	/* Store slave information */
+	id->slave = slave;
+
+	/* Enable I2C slave */
+	cdns_i2c_set_mode(CDNS_I2C_MODE_SLAVE, id);
+
+	return 0;
+}
+
+static int cdns_unreg_slave(struct i2c_client *slave)
+{
+	struct cdns_i2c *id = container_of(slave->adapter, struct cdns_i2c,
+									adap);
+
+	pm_runtime_put(id->dev);
+
+	/* Remove slave information */
+	id->slave = NULL;
+
+	/* Enable I2C master */
+	cdns_i2c_set_mode(CDNS_I2C_MODE_MASTER, id);
+
+	return 0;
+}
+#endif
+
 static const struct i2c_algorithm cdns_i2c_algo = {
 	.master_xfer	= cdns_i2c_master_xfer,
 	.functionality	= cdns_i2c_func,
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+	.reg_slave	= cdns_reg_slave,
+	.unreg_slave	= cdns_unreg_slave,
+#endif
 };
 
 /**
@@ -755,7 +1046,10 @@ static int cdns_i2c_setclk(unsigned long clk_in, struct cdns_i2c *id)
 	ctrl_reg |= ((div_a << CDNS_I2C_CR_DIVA_SHIFT) |
 			(div_b << CDNS_I2C_CR_DIVB_SHIFT));
 	cdns_i2c_writereg(ctrl_reg, CDNS_I2C_CR_OFFSET);
-
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+	id->ctrl_reg_diva_divb = ctrl_reg & (CDNS_I2C_CR_DIVA_MASK |
+				 CDNS_I2C_CR_DIVB_MASK);
+#endif
 	return 0;
 }
 
@@ -906,8 +1200,7 @@ static int cdns_i2c_probe(struct platform_device *pdev)
 		id->quirks = data->quirks;
 	}
 
-	r_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	id->membase = devm_ioremap_resource(&pdev->dev, r_mem);
+	id->membase = devm_platform_get_and_ioremap_resource(pdev, 0, &r_mem);
 	if (IS_ERR(id->membase))
 		return PTR_ERR(id->membase);
 
@@ -949,8 +1242,12 @@ static int cdns_i2c_probe(struct platform_device *pdev)
 	if (ret || (id->i2c_clk > I2C_MAX_FAST_MODE_FREQ))
 		id->i2c_clk = I2C_MAX_STANDARD_MODE_FREQ;
 
-	cdns_i2c_writereg(CDNS_I2C_CR_ACK_EN | CDNS_I2C_CR_NEA | CDNS_I2C_CR_MS,
-			  CDNS_I2C_CR_OFFSET);
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+	/* Set initial mode to master */
+	id->dev_mode = CDNS_I2C_MODE_MASTER;
+	id->slave_state = CDNS_I2C_SLAVE_STATE_IDLE;
+#endif
+	cdns_i2c_writereg(CDNS_I2C_CR_MASTER_EN_MASK, CDNS_I2C_CR_OFFSET);
 
 	ret = cdns_i2c_setclk(id->input_clk, id);
 	if (ret) {
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
index e3ceb256a380..232a7679b69b 100644
--- a/drivers/i2c/busses/i2c-davinci.c
+++ b/drivers/i2c/busses/i2c-davinci.c
@@ -761,7 +761,6 @@ static int davinci_i2c_probe(struct platform_device *pdev)
 {
 	struct davinci_i2c_dev *dev;
 	struct i2c_adapter *adap;
-	struct resource *mem;
 	struct i2c_bus_recovery_info *rinfo;
 	int r, irq;
 
@@ -814,8 +813,7 @@ static int davinci_i2c_probe(struct platform_device *pdev)
 	if (IS_ERR(dev->clk))
 		return PTR_ERR(dev->clk);
 
-	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	dev->base = devm_ioremap_resource(&pdev->dev, mem);
+	dev->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(dev->base)) {
 		return PTR_ERR(dev->base);
 	}
diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c
index 3a58eef20936..b6c17b550d31 100644
--- a/drivers/i2c/busses/i2c-designware-master.c
+++ b/drivers/i2c/busses/i2c-designware-master.c
@@ -76,14 +76,27 @@ static int i2c_dw_set_timings_master(struct dw_i2c_dev *dev)
 	 */
 	if (t->bus_freq_hz == 1000000) {
 		/*
-		 * Check are fast mode plus parameters available and use
-		 * fast mode if not.
+		 * Check are Fast Mode Plus parameters available. Calculate
+		 * SCL timing parameters for Fast Mode Plus if not set.
 		 */
 		if (dev->fp_hcnt && dev->fp_lcnt) {
 			dev->fs_hcnt = dev->fp_hcnt;
 			dev->fs_lcnt = dev->fp_lcnt;
-			fp_str = " Plus";
+		} else {
+			ic_clk = i2c_dw_clk_rate(dev);
+			dev->fs_hcnt =
+				i2c_dw_scl_hcnt(ic_clk,
+						260,	/* tHIGH = 260 ns */
+						sda_falling_time,
+						0,	/* DW default */
+						0);	/* No offset */
+			dev->fs_lcnt =
+				i2c_dw_scl_lcnt(ic_clk,
+						500,	/* tLOW = 500 ns */
+						scl_falling_time,
+						0);	/* No offset */
 		}
+		fp_str = " Plus";
 	}
 	/*
 	 * Calculate SCL timing parameters for fast mode if not set. They are
@@ -116,10 +129,22 @@ static int i2c_dw_set_timings_master(struct dw_i2c_dev *dev)
 			dev->master_cfg |= DW_IC_CON_SPEED_FAST;
 			dev->hs_hcnt = 0;
 			dev->hs_lcnt = 0;
-		} else if (dev->hs_hcnt && dev->hs_lcnt) {
-			dev_dbg(dev->dev, "High Speed Mode HCNT:LCNT = %d:%d\n",
-				dev->hs_hcnt, dev->hs_lcnt);
+		} else if (!dev->hs_hcnt || !dev->hs_lcnt) {
+			ic_clk = i2c_dw_clk_rate(dev);
+			dev->hs_hcnt =
+				i2c_dw_scl_hcnt(ic_clk,
+						160,	/* tHIGH = 160 ns */
+						sda_falling_time,
+						0,	/* DW default */
+						0);	/* No offset */
+			dev->hs_lcnt =
+				i2c_dw_scl_lcnt(ic_clk,
+						320,	/* tLOW = 320 ns */
+						scl_falling_time,
+						0);	/* No offset */
 		}
+		dev_dbg(dev->dev, "High Speed Mode HCNT:LCNT = %d:%d\n",
+			dev->hs_hcnt, dev->hs_lcnt);
 	}
 
 	ret = i2c_dw_set_sda_hold(dev);
diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c
index c98befe2a92e..5536673060cc 100644
--- a/drivers/i2c/busses/i2c-designware-platdrv.c
+++ b/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -354,10 +354,16 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
 	adap->dev.of_node = pdev->dev.of_node;
 	adap->nr = -1;
 
-	dev_pm_set_driver_flags(&pdev->dev,
-				DPM_FLAG_SMART_PREPARE |
-				DPM_FLAG_SMART_SUSPEND |
-				DPM_FLAG_LEAVE_SUSPENDED);
+	if (dev->flags & ACCESS_NO_IRQ_SUSPEND) {
+		dev_pm_set_driver_flags(&pdev->dev,
+					DPM_FLAG_SMART_PREPARE |
+					DPM_FLAG_LEAVE_SUSPENDED);
+	} else {
+		dev_pm_set_driver_flags(&pdev->dev,
+					DPM_FLAG_SMART_PREPARE |
+					DPM_FLAG_SMART_SUSPEND |
+					DPM_FLAG_LEAVE_SUSPENDED);
+	}
 
 	/* The code below assumes runtime PM to be disabled. */
 	WARN_ON(pm_runtime_enabled(&pdev->dev));
diff --git a/drivers/i2c/busses/i2c-digicolor.c b/drivers/i2c/busses/i2c-digicolor.c
index 056a5c4f0833..332f00437479 100644
--- a/drivers/i2c/busses/i2c-digicolor.c
+++ b/drivers/i2c/busses/i2c-digicolor.c
@@ -290,7 +290,6 @@ static int dc_i2c_probe(struct platform_device *pdev)
 {
 	struct device_node *np = pdev->dev.of_node;
 	struct dc_i2c *i2c;
-	struct resource *r;
 	int ret = 0, irq;
 
 	i2c = devm_kzalloc(&pdev->dev, sizeof(struct dc_i2c), GFP_KERNEL);
@@ -311,8 +310,7 @@ static int dc_i2c_probe(struct platform_device *pdev)
 	if (IS_ERR(i2c->clk))
 		return PTR_ERR(i2c->clk);
 
-	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	i2c->regs = devm_ioremap_resource(&pdev->dev, r);
+	i2c->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(i2c->regs))
 		return PTR_ERR(i2c->regs);
 
diff --git a/drivers/i2c/busses/i2c-emev2.c b/drivers/i2c/busses/i2c-emev2.c
index 959d4912ec0d..1a319352e51b 100644
--- a/drivers/i2c/busses/i2c-emev2.c
+++ b/drivers/i2c/busses/i2c-emev2.c
@@ -361,15 +361,13 @@ static const struct i2c_algorithm em_i2c_algo = {
 static int em_i2c_probe(struct platform_device *pdev)
 {
 	struct em_i2c_device *priv;
-	struct resource *r;
 	int ret;
 
 	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
 
-	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	priv->base = devm_ioremap_resource(&pdev->dev, r);
+	priv->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(priv->base))
 		return PTR_ERR(priv->base);
 
diff --git a/drivers/i2c/busses/i2c-exynos5.c b/drivers/i2c/busses/i2c-exynos5.c
index 527030953ba1..ba7033c9e157 100644
--- a/drivers/i2c/busses/i2c-exynos5.c
+++ b/drivers/i2c/busses/i2c-exynos5.c
@@ -736,7 +736,6 @@ static int exynos5_i2c_probe(struct platform_device *pdev)
 {
 	struct device_node *np = pdev->dev.of_node;
 	struct exynos5_i2c *i2c;
-	struct resource *mem;
 	int ret;
 
 	i2c = devm_kzalloc(&pdev->dev, sizeof(struct exynos5_i2c), GFP_KERNEL);
@@ -762,8 +761,7 @@ static int exynos5_i2c_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	i2c->regs = devm_ioremap_resource(&pdev->dev, mem);
+	i2c->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(i2c->regs)) {
 		ret = PTR_ERR(i2c->regs);
 		goto err_clk;
diff --git a/drivers/i2c/busses/i2c-hix5hd2.c b/drivers/i2c/busses/i2c-hix5hd2.c
index 6610304b6dc6..ab15b1ec2ab3 100644
--- a/drivers/i2c/busses/i2c-hix5hd2.c
+++ b/drivers/i2c/busses/i2c-hix5hd2.c
@@ -388,7 +388,6 @@ static int hix5hd2_i2c_probe(struct platform_device *pdev)
 {
 	struct device_node *np = pdev->dev.of_node;
 	struct hix5hd2_i2c_priv *priv;
-	struct resource *mem;
 	unsigned int freq;
 	int irq, ret;
 
@@ -409,8 +408,7 @@ static int hix5hd2_i2c_probe(struct platform_device *pdev)
 		}
 	}
 
-	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	priv->regs = devm_ioremap_resource(&pdev->dev, mem);
+	priv->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(priv->regs))
 		return PTR_ERR(priv->regs);
 
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index a9c03f5c3482..4f333889489c 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -1439,9 +1439,9 @@ static int i801_add_mux(struct i801_priv *priv)
 		return -ENOMEM;
 	lookup->dev_id = "i2c-mux-gpio";
 	for (i = 0; i < mux_config->n_gpios; i++) {
-		lookup->table[i].chip_label = mux_config->gpio_chip;
-		lookup->table[i].chip_hwnum = mux_config->gpios[i];
-		lookup->table[i].con_id = "mux";
+		lookup->table[i] = (struct gpiod_lookup)
+			GPIO_LOOKUP(mux_config->gpio_chip,
+				    mux_config->gpios[i], "mux", 0);
 	}
 	gpiod_add_lookup_table(lookup);
 	priv->lookup = lookup;
diff --git a/drivers/i2c/busses/i2c-img-scb.c b/drivers/i2c/busses/i2c-img-scb.c
index 422097a31c95..c937ea79300c 100644
--- a/drivers/i2c/busses/i2c-img-scb.c
+++ b/drivers/i2c/busses/i2c-img-scb.c
@@ -1330,7 +1330,6 @@ static int img_i2c_probe(struct platform_device *pdev)
 {
 	struct device_node *node = pdev->dev.of_node;
 	struct img_i2c *i2c;
-	struct resource *res;
 	int irq, ret;
 	u32 val;
 
@@ -1338,8 +1337,7 @@ static int img_i2c_probe(struct platform_device *pdev)
 	if (!i2c)
 		return -ENOMEM;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	i2c->base = devm_ioremap_resource(&pdev->dev, res);
+	i2c->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(i2c->base))
 		return PTR_ERR(i2c->base);
 
diff --git a/drivers/i2c/busses/i2c-jz4780.c b/drivers/i2c/busses/i2c-jz4780.c
index b426fc956938..ba831df6661e 100644
--- a/drivers/i2c/busses/i2c-jz4780.c
+++ b/drivers/i2c/busses/i2c-jz4780.c
@@ -763,7 +763,6 @@ static int jz4780_i2c_probe(struct platform_device *pdev)
 	int ret = 0;
 	unsigned int clk_freq = 0;
 	unsigned short tmp;
-	struct resource *r;
 	struct jz4780_i2c *i2c;
 
 	i2c = devm_kzalloc(&pdev->dev, sizeof(struct jz4780_i2c), GFP_KERNEL);
@@ -787,8 +786,7 @@ static int jz4780_i2c_probe(struct platform_device *pdev)
 	init_completion(&i2c->trans_waitq);
 	spin_lock_init(&i2c->lock);
 
-	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	i2c->iomem = devm_ioremap_resource(&pdev->dev, r);
+	i2c->iomem = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(i2c->iomem))
 		return PTR_ERR(i2c->iomem);
 
diff --git a/drivers/i2c/busses/i2c-lpc2k.c b/drivers/i2c/busses/i2c-lpc2k.c
index 13b0c12e2dba..197cb64b2a42 100644
--- a/drivers/i2c/busses/i2c-lpc2k.c
+++ b/drivers/i2c/busses/i2c-lpc2k.c
@@ -346,7 +346,6 @@ static const struct i2c_algorithm i2c_lpc2k_algorithm = {
 static int i2c_lpc2k_probe(struct platform_device *pdev)
 {
 	struct lpc2k_i2c *i2c;
-	struct resource *res;
 	u32 bus_clk_rate;
 	u32 scl_high;
 	u32 clkrate;
@@ -356,8 +355,7 @@ static int i2c_lpc2k_probe(struct platform_device *pdev)
 	if (!i2c)
 		return -ENOMEM;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	i2c->base = devm_ioremap_resource(&pdev->dev, res);
+	i2c->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(i2c->base))
 		return PTR_ERR(i2c->base);
 
diff --git a/drivers/i2c/busses/i2c-meson.c b/drivers/i2c/busses/i2c-meson.c
index 06b3bed78421..b3bd869281d3 100644
--- a/drivers/i2c/busses/i2c-meson.c
+++ b/drivers/i2c/busses/i2c-meson.c
@@ -397,7 +397,6 @@ static int meson_i2c_probe(struct platform_device *pdev)
 {
 	struct device_node *np = pdev->dev.of_node;
 	struct meson_i2c *i2c;
-	struct resource *mem;
 	struct i2c_timings timings;
 	int irq, ret = 0;
 
@@ -422,8 +421,7 @@ static int meson_i2c_probe(struct platform_device *pdev)
 		return PTR_ERR(i2c->clk);
 	}
 
-	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	i2c->regs = devm_ioremap_resource(&pdev->dev, mem);
+	i2c->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(i2c->regs))
 		return PTR_ERR(i2c->regs);
 
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index 9b8f1d8552ea..829b8c98ae51 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -877,7 +877,6 @@ mv64xxx_i2c_probe(struct platform_device *pd)
 {
 	struct mv64xxx_i2c_data		*drv_data;
 	struct mv64xxx_i2c_pdata	*pdata = dev_get_platdata(&pd->dev);
-	struct resource	*r;
 	int	rc;
 
 	if ((!pdata && !pd->dev.of_node))
@@ -888,8 +887,7 @@ mv64xxx_i2c_probe(struct platform_device *pd)
 	if (!drv_data)
 		return -ENOMEM;
 
-	r = platform_get_resource(pd, IORESOURCE_MEM, 0);
-	drv_data->reg_base = devm_ioremap_resource(&pd->dev, r);
+	drv_data->reg_base = devm_platform_ioremap_resource(pd, 0);
 	if (IS_ERR(drv_data->reg_base))
 		return PTR_ERR(drv_data->reg_base);
 
diff --git a/drivers/i2c/busses/i2c-octeon-platdrv.c b/drivers/i2c/busses/i2c-octeon-platdrv.c
index 64bda83e65ac..0c227963c8d6 100644
--- a/drivers/i2c/busses/i2c-octeon-platdrv.c
+++ b/drivers/i2c/busses/i2c-octeon-platdrv.c
@@ -136,7 +136,6 @@ static int octeon_i2c_probe(struct platform_device *pdev)
 {
 	struct device_node *node = pdev->dev.of_node;
 	int irq, result = 0, hlc_irq = 0;
-	struct resource *res_mem;
 	struct octeon_i2c *i2c;
 	bool cn78xx_style;
 
@@ -167,8 +166,7 @@ static int octeon_i2c_probe(struct platform_device *pdev)
 	i2c->roff.twsi_int = 0x10;
 	i2c->roff.sw_twsi_ext = 0x18;
 
-	res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	i2c->twsi_base = devm_ioremap_resource(&pdev->dev, res_mem);
+	i2c->twsi_base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(i2c->twsi_base)) {
 		result = PTR_ERR(i2c->twsi_base);
 		goto out;
diff --git a/drivers/i2c/busses/i2c-owl.c b/drivers/i2c/busses/i2c-owl.c
index 3ab8be62c581..fba6efc1dca8 100644
--- a/drivers/i2c/busses/i2c-owl.c
+++ b/drivers/i2c/busses/i2c-owl.c
@@ -396,15 +396,13 @@ static int owl_i2c_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct owl_i2c_dev *i2c_dev;
-	struct resource *res;
 	int ret, irq;
 
 	i2c_dev = devm_kzalloc(dev, sizeof(*i2c_dev), GFP_KERNEL);
 	if (!i2c_dev)
 		return -ENOMEM;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	i2c_dev->base = devm_ioremap_resource(dev, res);
+	i2c_dev->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(i2c_dev->base))
 		return PTR_ERR(i2c_dev->base);
 
diff --git a/drivers/i2c/busses/i2c-pca-platform.c b/drivers/i2c/busses/i2c-pca-platform.c
index 635dd697ac0b..546426a470cc 100644
--- a/drivers/i2c/busses/i2c-pca-platform.c
+++ b/drivers/i2c/busses/i2c-pca-platform.c
@@ -149,8 +149,7 @@ static int i2c_pca_pf_probe(struct platform_device *pdev)
 	if (!i2c)
 		return -ENOMEM;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	i2c->reg_base = devm_ioremap_resource(&pdev->dev, res);
+	i2c->reg_base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
 	if (IS_ERR(i2c->reg_base))
 		return PTR_ERR(i2c->reg_base);
 
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index 30ded6422e7b..69740a4ff1db 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -977,7 +977,8 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
 	}
 
 	if (dev->vendor == PCI_VENDOR_ID_AMD &&
-	    dev->device == PCI_DEVICE_ID_AMD_HUDSON2_SMBUS) {
+	    (dev->device == PCI_DEVICE_ID_AMD_HUDSON2_SMBUS ||
+	     dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS)) {
 		retval = piix4_setup_sb800(dev, id, 1);
 	}
 
diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c
index 748872a9b0fc..155dcde70fc9 100644
--- a/drivers/i2c/busses/i2c-qup.c
+++ b/drivers/i2c/busses/i2c-qup.c
@@ -1660,7 +1660,6 @@ static int qup_i2c_probe(struct platform_device *pdev)
 	static const int blk_sizes[] = {4, 16, 32};
 	struct qup_i2c_dev *qup;
 	unsigned long one_bit_t;
-	struct resource *res;
 	u32 io_mode, hw_ver, size;
 	int ret, fs_div, hs_div;
 	u32 src_clk_freq = DEFAULT_SRC_CLK;
@@ -1757,8 +1756,7 @@ static int qup_i2c_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	qup->base = devm_ioremap_resource(qup->dev, res);
+	qup->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(qup->base))
 		return PTR_ERR(qup->base);
 
diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c
index 3b5397aa4ca6..a45c4bf1ec01 100644
--- a/drivers/i2c/busses/i2c-rcar.c
+++ b/drivers/i2c/busses/i2c-rcar.c
@@ -938,9 +938,7 @@ static int rcar_i2c_probe(struct platform_device *pdev)
 		return PTR_ERR(priv->clk);
 	}
 
-	priv->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-
-	priv->io = devm_ioremap_resource(dev, priv->res);
+	priv->io = devm_platform_get_and_ioremap_resource(pdev, 0, &priv->res);
 	if (IS_ERR(priv->io))
 		return PTR_ERR(priv->io);
 
diff --git a/drivers/i2c/busses/i2c-rk3x.c b/drivers/i2c/busses/i2c-rk3x.c
index 73272d4296bb..fbe41c8cc126 100644
--- a/drivers/i2c/busses/i2c-rk3x.c
+++ b/drivers/i2c/busses/i2c-rk3x.c
@@ -1193,7 +1193,6 @@ static int rk3x_i2c_probe(struct platform_device *pdev)
 	struct device_node *np = pdev->dev.of_node;
 	const struct of_device_id *match;
 	struct rk3x_i2c *i2c;
-	struct resource *mem;
 	int ret = 0;
 	int bus_nr;
 	u32 value;
@@ -1223,8 +1222,7 @@ static int rk3x_i2c_probe(struct platform_device *pdev)
 	spin_lock_init(&i2c->lock);
 	init_waitqueue_head(&i2c->wait);
 
-	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	i2c->regs = devm_ioremap_resource(&pdev->dev, mem);
+	i2c->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(i2c->regs))
 		return PTR_ERR(i2c->regs);
 
diff --git a/drivers/i2c/busses/i2c-sirf.c b/drivers/i2c/busses/i2c-sirf.c
index a459e00c6851..d7f72ec331e8 100644
--- a/drivers/i2c/busses/i2c-sirf.c
+++ b/drivers/i2c/busses/i2c-sirf.c
@@ -271,7 +271,6 @@ static int i2c_sirfsoc_probe(struct platform_device *pdev)
 {
 	struct sirfsoc_i2c *siic;
 	struct i2c_adapter *adap;
-	struct resource *mem_res;
 	struct clk *clk;
 	int bitrate;
 	int ctrl_speed;
@@ -309,8 +308,7 @@ static int i2c_sirfsoc_probe(struct platform_device *pdev)
 	adap = &siic->adapter;
 	adap->class = I2C_CLASS_DEPRECATED;
 
-	mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	siic->base = devm_ioremap_resource(&pdev->dev, mem_res);
+	siic->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(siic->base)) {
 		err = PTR_ERR(siic->base);
 		goto out;
diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c
index 330ffed011e0..8102e33a6753 100644
--- a/drivers/i2c/busses/i2c-stm32f7.c
+++ b/drivers/i2c/busses/i2c-stm32f7.c
@@ -1462,7 +1462,8 @@ static irqreturn_t stm32f7_i2c_isr_event(int irq, void *data)
 
 	/* NACK received */
 	if (status & STM32F7_I2C_ISR_NACKF) {
-		dev_dbg(i2c_dev->dev, "<%s>: Receive NACK\n", __func__);
+		dev_dbg(i2c_dev->dev, "<%s>: Receive NACK (addr %x)\n",
+			__func__, f7_msg->addr);
 		writel_relaxed(STM32F7_I2C_ICR_NACKCF, base + STM32F7_I2C_ICR);
 		f7_msg->result = -ENXIO;
 	}
@@ -1940,8 +1941,7 @@ static int stm32f7_i2c_probe(struct platform_device *pdev)
 	if (!i2c_dev)
 		return -ENOMEM;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	i2c_dev->base = devm_ioremap_resource(&pdev->dev, res);
+	i2c_dev->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
 	if (IS_ERR(i2c_dev->base))
 		return PTR_ERR(i2c_dev->base);
 	phy_addr = (dma_addr_t)res->start;
diff --git a/drivers/i2c/busses/i2c-stu300.c b/drivers/i2c/busses/i2c-stu300.c
index ba6b60caa45e..64d739baf480 100644
--- a/drivers/i2c/busses/i2c-stu300.c
+++ b/drivers/i2c/busses/i2c-stu300.c
@@ -860,7 +860,6 @@ static int stu300_probe(struct platform_device *pdev)
 {
 	struct stu300_dev *dev;
 	struct i2c_adapter *adap;
-	struct resource *res;
 	int bus_nr;
 	int ret = 0;
 
@@ -876,8 +875,7 @@ static int stu300_probe(struct platform_device *pdev)
 	}
 
 	dev->pdev = pdev;
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	dev->virtbase = devm_ioremap_resource(&pdev->dev, res);
+	dev->virtbase = devm_platform_ioremap_resource(pdev, 0);
 	dev_dbg(&pdev->dev, "initialize bus device I2C%d on virtual "
 		"base %p\n", bus_nr, dev->virtbase);
 	if (IS_ERR(dev->virtbase))
diff --git a/drivers/i2c/busses/i2c-sun6i-p2wi.c b/drivers/i2c/busses/i2c-sun6i-p2wi.c
index e5293f0b3318..17c27f79029b 100644
--- a/drivers/i2c/busses/i2c-sun6i-p2wi.c
+++ b/drivers/i2c/busses/i2c-sun6i-p2wi.c
@@ -187,7 +187,6 @@ static int p2wi_probe(struct platform_device *pdev)
 	struct device_node *childnp;
 	unsigned long parent_clk_freq;
 	u32 clk_freq = I2C_MAX_STANDARD_MODE_FREQ;
-	struct resource *r;
 	struct p2wi *p2wi;
 	u32 slave_addr;
 	int clk_div;
@@ -231,8 +230,7 @@ static int p2wi_probe(struct platform_device *pdev)
 		p2wi->slave_addr = slave_addr;
 	}
 
-	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	p2wi->regs = devm_ioremap_resource(dev, r);
+	p2wi->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(p2wi->regs))
 		return PTR_ERR(p2wi->regs);
 
diff --git a/drivers/i2c/busses/i2c-synquacer.c b/drivers/i2c/busses/i2c-synquacer.c
index 9099d0a67ace..8cc91a8da5a0 100644
--- a/drivers/i2c/busses/i2c-synquacer.c
+++ b/drivers/i2c/busses/i2c-synquacer.c
@@ -536,7 +536,6 @@ static const struct i2c_adapter synquacer_i2c_ops = {
 static int synquacer_i2c_probe(struct platform_device *pdev)
 {
 	struct synquacer_i2c *i2c;
-	struct resource *r;
 	u32 bus_speed;
 	int ret;
 
@@ -574,8 +573,7 @@ static int synquacer_i2c_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
-	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	i2c->base = devm_ioremap_resource(&pdev->dev, r);
+	i2c->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(i2c->base))
 		return PTR_ERR(i2c->base);
 
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 4c4d17ddc96b..8280ac7cc1b7 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -996,14 +996,13 @@ tegra_i2c_poll_completion_timeout(struct tegra_i2c_dev *i2c_dev,
 	do {
 		u32 status = i2c_readl(i2c_dev, I2C_INT_STATUS);
 
-		if (status) {
+		if (status)
 			tegra_i2c_isr(i2c_dev->irq, i2c_dev);
 
-			if (completion_done(complete)) {
-				s64 delta = ktime_ms_delta(ktimeout, ktime);
+		if (completion_done(complete)) {
+			s64 delta = ktime_ms_delta(ktimeout, ktime);
 
-				return msecs_to_jiffies(delta) ?: 1;
-			}
+			return msecs_to_jiffies(delta) ?: 1;
 		}
 
 		ktime = ktime_get();
@@ -1030,14 +1029,18 @@ tegra_i2c_wait_completion_timeout(struct tegra_i2c_dev *i2c_dev,
 		disable_irq(i2c_dev->irq);
 
 		/*
-		 * There is a chance that completion may happen after IRQ
-		 * synchronization, which is done by disable_irq().
+		 * Under some rare circumstances (like running KASAN +
+		 * NFS root) CPU, which handles interrupt, may stuck in
+		 * uninterruptible state for a significant time.  In this
+		 * case we will get timeout if I2C transfer is running on
+		 * a sibling CPU, despite of IRQ being raised.
+		 *
+		 * In order to handle this rare condition, the IRQ status
+		 * needs to be checked after timeout.
 		 */
-		if (ret == 0 && completion_done(complete)) {
-			dev_warn(i2c_dev->dev,
-				 "completion done after timeout\n");
-			ret = 1;
-		}
+		if (ret == 0)
+			ret = tegra_i2c_poll_completion_timeout(i2c_dev,
+								complete, 0);
 	}
 
 	return ret;
@@ -1216,6 +1219,15 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 		time_left = tegra_i2c_wait_completion_timeout(
 				i2c_dev, &i2c_dev->dma_complete, xfer_time);
 
+		/*
+		 * Synchronize DMA first, since dmaengine_terminate_sync()
+		 * performs synchronization after the transfer's termination
+		 * and we want to get a completion if transfer succeeded.
+		 */
+		dmaengine_synchronize(i2c_dev->msg_read ?
+				      i2c_dev->rx_dma_chan :
+				      i2c_dev->tx_dma_chan);
+
 		dmaengine_terminate_sync(i2c_dev->msg_read ?
 					 i2c_dev->rx_dma_chan :
 					 i2c_dev->tx_dma_chan);
diff --git a/drivers/i2c/busses/i2c-xlp9xx.c b/drivers/i2c/busses/i2c-xlp9xx.c
index 391c878a7cdc..286faa9c855e 100644
--- a/drivers/i2c/busses/i2c-xlp9xx.c
+++ b/drivers/i2c/busses/i2c-xlp9xx.c
@@ -506,15 +506,13 @@ static int xlp9xx_i2c_smbus_setup(struct xlp9xx_i2c_dev *priv,
 static int xlp9xx_i2c_probe(struct platform_device *pdev)
 {
 	struct xlp9xx_i2c_dev *priv;
-	struct resource *res;
 	int err = 0;
 
 	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	priv->base = devm_ioremap_resource(&pdev->dev, res);
+	priv->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(priv->base))
 		return PTR_ERR(priv->base);
 
diff --git a/drivers/i2c/busses/i2c-xlr.c b/drivers/i2c/busses/i2c-xlr.c
index 282f161a8b08..126d1393e548 100644
--- a/drivers/i2c/busses/i2c-xlr.c
+++ b/drivers/i2c/busses/i2c-xlr.c
@@ -362,7 +362,6 @@ static int xlr_i2c_probe(struct platform_device *pdev)
 {
 	const struct of_device_id *match;
 	struct xlr_i2c_private  *priv;
-	struct resource *res;
 	struct clk *clk;
 	unsigned long clk_rate;
 	unsigned long clk_div;
@@ -380,8 +379,7 @@ static int xlr_i2c_probe(struct platform_device *pdev)
 	else
 		priv->cfg = &xlr_i2c_config_default;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	priv->iobase = devm_ioremap_resource(&pdev->dev, res);
+	priv->iobase = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(priv->iobase))
 		return PTR_ERR(priv->iobase);
 
diff --git a/drivers/i2c/busses/i2c-zx2967.c b/drivers/i2c/busses/i2c-zx2967.c
index 5f3318559b8d..8db9519695a6 100644
--- a/drivers/i2c/busses/i2c-zx2967.c
+++ b/drivers/i2c/busses/i2c-zx2967.c
@@ -502,7 +502,6 @@ static int zx2967_i2c_probe(struct platform_device *pdev)
 {
 	struct zx2967_i2c *i2c;
 	void __iomem *reg_base;
-	struct resource *res;
 	struct clk *clk;
 	int ret;
 
@@ -510,8 +509,7 @@ static int zx2967_i2c_probe(struct platform_device *pdev)
 	if (!i2c)
 		return -ENOMEM;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	reg_base = devm_ioremap_resource(&pdev->dev, res);
+	reg_base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(reg_base))
 		return PTR_ERR(reg_base);
 
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
index 5cc0b0ec5570..139aea351ffb 100644
--- a/drivers/i2c/i2c-core-base.c
+++ b/drivers/i2c/i2c-core-base.c
@@ -1588,6 +1588,18 @@ void i2c_del_adapter(struct i2c_adapter *adap)
 }
 EXPORT_SYMBOL(i2c_del_adapter);
 
+static void i2c_parse_timing(struct device *dev, char *prop_name, u32 *cur_val_p,
+			    u32 def_val, bool use_def)
+{
+	int ret;
+
+	ret = device_property_read_u32(dev, prop_name, cur_val_p);
+	if (ret && use_def)
+		*cur_val_p = def_val;
+
+	dev_dbg(dev, "%s: %u\n", prop_name, *cur_val_p);
+}
+
 /**
  * i2c_parse_fw_timings - get I2C related timing parameters from firmware
  * @dev: The device to scan for I2C timing properties
@@ -1606,49 +1618,28 @@ EXPORT_SYMBOL(i2c_del_adapter);
  */
 void i2c_parse_fw_timings(struct device *dev, struct i2c_timings *t, bool use_defaults)
 {
-	int ret;
+	bool u = use_defaults;
+	u32 d;
 
-	ret = device_property_read_u32(dev, "clock-frequency", &t->bus_freq_hz);
-	if (ret && use_defaults)
-		t->bus_freq_hz = I2C_MAX_STANDARD_MODE_FREQ;
+	i2c_parse_timing(dev, "clock-frequency", &t->bus_freq_hz,
+			 I2C_MAX_STANDARD_MODE_FREQ, u);
 
-	ret = device_property_read_u32(dev, "i2c-scl-rising-time-ns", &t->scl_rise_ns);
-	if (ret && use_defaults) {
-		if (t->bus_freq_hz <= I2C_MAX_STANDARD_MODE_FREQ)
-			t->scl_rise_ns = 1000;
-		else if (t->bus_freq_hz <= I2C_MAX_FAST_MODE_FREQ)
-			t->scl_rise_ns = 300;
-		else
-			t->scl_rise_ns = 120;
-	}
+	d = t->bus_freq_hz <= I2C_MAX_STANDARD_MODE_FREQ ? 1000 :
+	    t->bus_freq_hz <= I2C_MAX_FAST_MODE_FREQ ? 300 : 120;
+	i2c_parse_timing(dev, "i2c-scl-rising-time-ns", &t->scl_rise_ns, d, u);
 
-	ret = device_property_read_u32(dev, "i2c-scl-falling-time-ns", &t->scl_fall_ns);
-	if (ret && use_defaults) {
-		if (t->bus_freq_hz <= I2C_MAX_FAST_MODE_FREQ)
-			t->scl_fall_ns = 300;
-		else
-			t->scl_fall_ns = 120;
-	}
+	d = t->bus_freq_hz <= I2C_MAX_FAST_MODE_FREQ ? 300 : 120;
+	i2c_parse_timing(dev, "i2c-scl-falling-time-ns", &t->scl_fall_ns, d, u);
 
-	ret = device_property_read_u32(dev, "i2c-scl-internal-delay-ns", &t->scl_int_delay_ns);
-	if (ret && use_defaults)
-		t->scl_int_delay_ns = 0;
-
-	ret = device_property_read_u32(dev, "i2c-sda-falling-time-ns", &t->sda_fall_ns);
-	if (ret && use_defaults)
-		t->sda_fall_ns = t->scl_fall_ns;
-
-	ret = device_property_read_u32(dev, "i2c-sda-hold-time-ns", &t->sda_hold_ns);
-	if (ret && use_defaults)
-		t->sda_hold_ns = 0;
-
-	ret = device_property_read_u32(dev, "i2c-digital-filter-width-ns", &t->digital_filter_width_ns);
-	if (ret && use_defaults)
-		t->digital_filter_width_ns = 0;
-
-	ret = device_property_read_u32(dev, "i2c-analog-filter-cutoff-frequency", &t->analog_filter_cutoff_freq_hz);
-	if (ret && use_defaults)
-		t->analog_filter_cutoff_freq_hz = 0;
+	i2c_parse_timing(dev, "i2c-scl-internal-delay-ns",
+			 &t->scl_int_delay_ns, 0, u);
+	i2c_parse_timing(dev, "i2c-sda-falling-time-ns", &t->sda_fall_ns,
+			 t->scl_fall_ns, u);
+	i2c_parse_timing(dev, "i2c-sda-hold-time-ns", &t->sda_hold_ns, 0, u);
+	i2c_parse_timing(dev, "i2c-digital-filter-width-ns",
+			 &t->digital_filter_width_ns, 0, u);
+	i2c_parse_timing(dev, "i2c-analog-filter-cutoff-frequency",
+			 &t->analog_filter_cutoff_freq_hz, 0, u);
 }
 EXPORT_SYMBOL_GPL(i2c_parse_fw_timings);
 
@@ -2273,19 +2264,6 @@ i2c_new_scanned_device(struct i2c_adapter *adap,
 }
 EXPORT_SYMBOL_GPL(i2c_new_scanned_device);
 
-struct i2c_client *
-i2c_new_probed_device(struct i2c_adapter *adap,
-		      struct i2c_board_info *info,
-		      unsigned short const *addr_list,
-		      int (*probe)(struct i2c_adapter *adap, unsigned short addr))
-{
-	struct i2c_client *client;
-
-	client = i2c_new_scanned_device(adap, info, addr_list, probe);
-	return IS_ERR(client) ? NULL : client;
-}
-EXPORT_SYMBOL_GPL(i2c_new_probed_device);
-
 struct i2c_adapter *i2c_get_adapter(int nr)
 {
 	struct i2c_adapter *adapter;
diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
index d0b3d35ad3e4..8abc72d889d1 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -158,11 +158,7 @@ static void *xan_find_marked(struct xarray *xa, unsigned long *indexp,
 	void *entry;
 
 	rcu_read_lock();
-	do {
-		entry = xas_find_marked(&xas, ULONG_MAX, filter);
-		if (xa_is_zero(entry))
-			break;
-	} while (xas_retry(&xas, entry));
+	entry = xas_find_marked(&xas, ULONG_MAX, filter);
 	rcu_read_unlock();
 
 	if (entry) {
diff --git a/drivers/input/touchscreen/elants_i2c.c b/drivers/input/touchscreen/elants_i2c.c
index 14c577c16b16..2289f9638116 100644
--- a/drivers/input/touchscreen/elants_i2c.c
+++ b/drivers/input/touchscreen/elants_i2c.c
@@ -19,6 +19,7 @@
  */
 
 
+#include <linux/bits.h>
 #include <linux/module.h>
 #include <linux/input.h>
 #include <linux/interrupt.h>
@@ -73,6 +74,7 @@
 #define FW_POS_STATE		1
 #define FW_POS_TOTAL		2
 #define FW_POS_XY		3
+#define FW_POS_TOOL_TYPE	33
 #define FW_POS_CHECKSUM		34
 #define FW_POS_WIDTH		35
 #define FW_POS_PRESSURE		45
@@ -842,6 +844,7 @@ static void elants_i2c_mt_event(struct elants_data *ts, u8 *buf)
 {
 	struct input_dev *input = ts->input;
 	unsigned int n_fingers;
+	unsigned int tool_type;
 	u16 finger_state;
 	int i;
 
@@ -852,6 +855,10 @@ static void elants_i2c_mt_event(struct elants_data *ts, u8 *buf)
 	dev_dbg(&ts->client->dev,
 		"n_fingers: %u, state: %04x\n",  n_fingers, finger_state);
 
+	/* Note: all fingers have the same tool type */
+	tool_type = buf[FW_POS_TOOL_TYPE] & BIT(0) ?
+			MT_TOOL_FINGER : MT_TOOL_PALM;
+
 	for (i = 0; i < MAX_CONTACT_NUM && n_fingers; i++) {
 		if (finger_state & 1) {
 			unsigned int x, y, p, w;
@@ -867,7 +874,7 @@ static void elants_i2c_mt_event(struct elants_data *ts, u8 *buf)
 				i, x, y, p, w);
 
 			input_mt_slot(input, i);
-			input_mt_report_slot_state(input, MT_TOOL_FINGER, true);
+			input_mt_report_slot_state(input, tool_type, true);
 			input_event(input, EV_ABS, ABS_MT_POSITION_X, x);
 			input_event(input, EV_ABS, ABS_MT_POSITION_Y, y);
 			input_event(input, EV_ABS, ABS_MT_PRESSURE, p);
@@ -1307,6 +1314,8 @@ static int elants_i2c_probe(struct i2c_client *client,
 	input_set_abs_params(ts->input, ABS_MT_POSITION_Y, 0, ts->y_max, 0, 0);
 	input_set_abs_params(ts->input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
 	input_set_abs_params(ts->input, ABS_MT_PRESSURE, 0, 255, 0, 0);
+	input_set_abs_params(ts->input, ABS_MT_TOOL_TYPE,
+			     0, MT_TOOL_PALM, 0, 0);
 	input_abs_set_res(ts->input, ABS_MT_POSITION_X, ts->x_res);
 	input_abs_set_res(ts->input, ABS_MT_POSITION_Y, ts->y_res);
 	input_abs_set_res(ts->input, ABS_MT_TOUCH_MAJOR, 1);
diff --git a/drivers/input/touchscreen/mms114.c b/drivers/input/touchscreen/mms114.c
index 69c6d559eeb0..2ef1adaed9af 100644
--- a/drivers/input/touchscreen/mms114.c
+++ b/drivers/input/touchscreen/mms114.c
@@ -91,15 +91,15 @@ static int __mms114_read_reg(struct mms114_data *data, unsigned int reg,
 	if (reg <= MMS114_MODE_CONTROL && reg + len > MMS114_MODE_CONTROL)
 		BUG();
 
-	/* Write register: use repeated start */
+	/* Write register */
 	xfer[0].addr = client->addr;
-	xfer[0].flags = I2C_M_TEN | I2C_M_NOSTART;
+	xfer[0].flags = client->flags & I2C_M_TEN;
 	xfer[0].len = 1;
 	xfer[0].buf = &buf;
 
 	/* Read data */
 	xfer[1].addr = client->addr;
-	xfer[1].flags = I2C_M_RD;
+	xfer[1].flags = (client->flags & I2C_M_TEN) | I2C_M_RD;
 	xfer[1].len = len;
 	xfer[1].buf = val;
 
@@ -428,10 +428,8 @@ static int mms114_probe(struct i2c_client *client,
 	const void *match_data;
 	int error;
 
-	if (!i2c_check_functionality(client->adapter,
-				I2C_FUNC_PROTOCOL_MANGLING)) {
-		dev_err(&client->dev,
-			"Need i2c bus that supports protocol mangling\n");
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		dev_err(&client->dev, "Not supported I2C adapter\n");
 		return -ENODEV;
 	}
 
diff --git a/drivers/irqchip/irq-renesas-h8300h.c b/drivers/irqchip/irq-renesas-h8300h.c
index 1054d74b7edd..42e2918eee2f 100644
--- a/drivers/irqchip/irq-renesas-h8300h.c
+++ b/drivers/irqchip/irq-renesas-h8300h.c
@@ -24,7 +24,10 @@ static const char ipr_bit[] = {
 
 static void __iomem *intc_baseaddr;
 
-#define IPR (intc_baseaddr + 6)
+#define ICSR (intc_baseaddr + 2)
+#define IER  (intc_baseaddr + 3)
+#define ISR  (intc_baseaddr + 4)
+#define IPR  (intc_baseaddr + 6)
 
 static void h8300h_disable_irq(struct irq_data *data)
 {
@@ -38,6 +41,8 @@ static void h8300h_disable_irq(struct irq_data *data)
 		else
 			ctrl_bclr(bit & 7, (IPR+1));
 	}
+	if (irq < 6)
+		ctrl_bclr(irq, IER);
 }
 
 static void h8300h_enable_irq(struct irq_data *data)
@@ -52,12 +57,24 @@ static void h8300h_enable_irq(struct irq_data *data)
 		else
 			ctrl_bset(bit & 7, (IPR+1));
 	}
+	if (irq < 6)
+		ctrl_bset(irq, IER);
+}
+
+static void h8300h_ack_irq(struct irq_data *data)
+{
+	int bit;
+	int irq = data->irq - 12;
+
+	if (irq < 6)
+		ctrl_bclr(irq, ISR);
 }
 
 struct irq_chip h8300h_irq_chip = {
 	.name		= "H8/300H-INTC",
 	.irq_enable	= h8300h_enable_irq,
 	.irq_disable	= h8300h_disable_irq,
+	.irq_eoi	= h8300h_ack_irq,
 };
 
 static int irq_map(struct irq_domain *h, unsigned int virq,
diff --git a/drivers/irqchip/irq-renesas-h8s.c b/drivers/irqchip/irq-renesas-h8s.c
index 4e2461bae944..0b8d9d7ef2ee 100644
--- a/drivers/irqchip/irq-renesas-h8s.c
+++ b/drivers/irqchip/irq-renesas-h8s.c
@@ -11,8 +11,11 @@
 #include <linux/of_irq.h>
 #include <asm/io.h>
 
-static void *intc_baseaddr;
-#define IPRA (intc_baseaddr)
+static void *ipr_base;
+static void *icr_base;
+#define IPRA (ipr_base)
+#define IER  (icr_base + 2)
+#define ISR  (icr_base + 4)
 
 static const unsigned char ipr_table[] = {
 	0x03, 0x02, 0x01, 0x00, 0x13, 0x12, 0x11, 0x10, /* 16 - 23 */
@@ -36,13 +39,22 @@ static void h8s_disable_irq(struct irq_data *data)
 	int pos;
 	void __iomem *addr;
 	unsigned short pri;
-	int irq = data->irq;
+	int irq = data->irq - 16;
+	unsigned short ier;
+
+	if (irq < 0)
+		return;
 
-	addr = IPRA + ((ipr_table[irq - 16] & 0xf0) >> 3);
-	pos = (ipr_table[irq - 16] & 0x0f) * 4;
+	addr = IPRA + ((ipr_table[irq] & 0xf0) >> 3);
+	pos = (ipr_table[irq] & 0x0f) * 4;
 	pri = ~(0x000f << pos);
-	pri &= readw(addr);
-	writew(pri, addr);
+	pri &= __raw_readw(addr);
+	__raw_writew(pri, addr);
+	if (irq < 16) {
+		ier = __raw_readw(IER);
+		ier &= ~(1 << irq);
+		__raw_writew(ier, IER);
+	}
 }
 
 static void h8s_enable_irq(struct irq_data *data)
@@ -50,20 +62,43 @@ static void h8s_enable_irq(struct irq_data *data)
 	int pos;
 	void __iomem *addr;
 	unsigned short pri;
-	int irq = data->irq;
+	int irq = data->irq - 16;
+	unsigned short ier;
+
+	if (irq < 0)
+		return;
 
-	addr = IPRA + ((ipr_table[irq - 16] & 0xf0) >> 3);
-	pos = (ipr_table[irq - 16] & 0x0f) * 4;
+	addr = IPRA + ((ipr_table[irq] & 0xf0) >> 3);
+	pos = (ipr_table[irq] & 0x0f) * 4;
 	pri = ~(0x000f << pos);
-	pri &= readw(addr);
+	pri &= __raw_readw(addr);
 	pri |= 1 << pos;
-	writew(pri, addr);
+	__raw_writew(pri, addr);
+	if (irq < 16) {
+		ier = __raw_readw(IER);
+		ier &= ~(1 << irq);
+		__raw_writew(ier, IER);
+	}
+}
+
+static void h8s_ack_irq(struct irq_data *data)
+{
+	int irq = data->irq;
+	uint16_t isr;
+
+	if (irq >= 16 && irq < 32) {
+		irq -= 16;
+		isr = __raw_readw(ISR);
+		isr &= ~(1 << irq);
+		__raw_writew(isr, ISR);
+	}
 }
 
 struct irq_chip h8s_irq_chip = {
 	.name		= "H8S-INTC",
 	.irq_enable	= h8s_enable_irq,
 	.irq_disable	= h8s_disable_irq,
+	.irq_ack	= h8s_ack_irq,
 };
 
 static __init int irq_map(struct irq_domain *h, unsigned int virq,
@@ -85,14 +120,16 @@ static int __init h8s_intc_of_init(struct device_node *intc,
 	struct irq_domain *domain;
 	int n;
 
-	intc_baseaddr = of_iomap(intc, 0);
-	BUG_ON(!intc_baseaddr);
+	ipr_base = of_iomap(intc, 0);
+	icr_base = of_iomap(intc, 1);
+	BUG_ON(!ipr_base || !icr_base);
 
 	/* All interrupt priority is 0 (disable) */
 	/* IPRA to IPRK */
 	for (n = 0; n <= 'k' - 'a'; n++)
-		writew(0x0000, IPRA + (n * 2));
+		__raw_writew(0x0000, IPRA + (n * 2));
 
+	__raw_writew(0xffff, IER);
 	domain = irq_domain_add_linear(intc, NR_IRQS, &irq_ops, NULL);
 	BUG_ON(!domain);
 	irq_set_default_host(domain);
diff --git a/drivers/isdn/hardware/mISDN/mISDNisar.c b/drivers/isdn/hardware/mISDN/mISDNisar.c
index e325e87c0593..11e8c7d8b6e8 100644
--- a/drivers/isdn/hardware/mISDN/mISDNisar.c
+++ b/drivers/isdn/hardware/mISDN/mISDNisar.c
@@ -743,10 +743,10 @@ check_send(struct isar_hw *isar, u8 rdm)
 	}
 }
 
-const char *dmril[] = {"NO SPEED", "1200/75", "NODEF2", "75/1200", "NODEF4",
+static const char *dmril[] = {"NO SPEED", "1200/75", "NODEF2", "75/1200", "NODEF4",
 		       "300", "600", "1200", "2400", "4800", "7200",
 		       "9600nt", "9600t", "12000", "14400", "WRONG"};
-const char *dmrim[] = {"NO MOD", "NO DEF", "V32/V32b", "V22", "V21",
+static const char *dmrim[] = {"NO MOD", "NO DEF", "V32/V32b", "V22", "V21",
 		       "Bell103", "V23", "Bell202", "V17", "V29", "V27ter"};
 
 static void
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index c664d84e1667..7599dbee8de1 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -145,6 +145,20 @@ config LEDS_EL15203000
 	  To compile this driver as a module, choose M here: the module
 	  will be called leds-el15203000.
 
+config LEDS_TURRIS_OMNIA
+	tristate "LED support for CZ.NIC's Turris Omnia"
+	depends on LEDS_CLASS
+	depends on I2C
+	depends on MACH_ARMADA_38X || COMPILE_TEST
+	depends on OF
+	help
+	  This option enables basic support for the LEDs found on the front
+	  side of CZ.NIC's Turris Omnia router. There are 12 RGB LEDs on the
+	  front panel.
+	  This driver does not currently support setting LED colors, only
+	  brightness. Also HW triggering is disabled when the controller is
+	  probed by this driver.
+
 config LEDS_LM3530
 	tristate "LCD Backlight driver for LM3530"
 	depends on LEDS_CLASS
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 45235d5fb218..fd61421f7d40 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -83,6 +83,7 @@ obj-$(CONFIG_LEDS_TCA6507)		+= leds-tca6507.o
 obj-$(CONFIG_LEDS_TI_LMU_COMMON)	+= leds-ti-lmu-common.o
 obj-$(CONFIG_LEDS_TLC591XX)		+= leds-tlc591xx.o
 obj-$(CONFIG_LEDS_TPS6105X)		+= leds-tps6105x.o
+obj-$(CONFIG_LEDS_TURRIS_OMNIA)		+= leds-turris-omnia.o
 obj-$(CONFIG_LEDS_WM831X_STATUS)	+= leds-wm831x-status.o
 obj-$(CONFIG_LEDS_WM8350)		+= leds-wm8350.o
 obj-$(CONFIG_LEDS_WRAP)			+= leds-wrap.o
diff --git a/drivers/leds/leds-turris-omnia.c b/drivers/leds/leds-turris-omnia.c
new file mode 100644
index 000000000000..7e8345b2ac4f
--- /dev/null
+++ b/drivers/leds/leds-turris-omnia.c
@@ -0,0 +1,295 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// CZ.NIC's Turris Omnia LEDs driver
+//
+// 2020 by Marek Behun <marek.behun@nic.cz>
+
+#include <linux/i2c.h>
+#include <linux/leds.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <uapi/linux/uleds.h>
+#include "leds.h"
+
+#define OMNIA_BOARD_LEDS		12
+
+#define CMD_LED_MODE			3
+#define CMD_LED_MODE_LED(l)		((l) & 0x0f)
+#define CMD_LED_MODE_USER		0x10
+
+#define CMD_LED_STATE			4
+#define CMD_LED_STATE_LED(l)		((l) & 0x0f)
+#define CMD_LED_STATE_ON		0x10
+
+#define CMD_LED_COLOR			5
+#define CMD_LED_SET_BRIGHTNESS		7
+#define CMD_LED_GET_BRIGHTNESS		8
+
+#define OMNIA_CMD			0
+
+#define OMNIA_CMD_LED_COLOR_LED		1
+#define OMNIA_CMD_LED_COLOR_R		2
+#define OMNIA_CMD_LED_COLOR_G		3
+#define OMNIA_CMD_LED_COLOR_B		4
+#define OMNIA_CMD_LED_COLOR_LEN		5
+
+struct omnia_led {
+	struct led_classdev cdev;
+	int reg, color;
+};
+
+#define to_omnia_led(l)	container_of(l, struct omnia_led, cdev)
+
+struct omnia_leds {
+	struct i2c_client *client;
+	struct mutex lock;
+	u8 cache[OMNIA_BOARD_LEDS][3];
+	int nleds;
+	struct omnia_led leds[0];
+};
+
+static int omnia_led_brightness_set_blocking(struct led_classdev *cdev,
+					     enum led_brightness brightness)
+{
+	static const u8 color2cmd[] = {
+		[LED_COLOR_ID_RED] = OMNIA_CMD_LED_COLOR_R,
+		[LED_COLOR_ID_GREEN] = OMNIA_CMD_LED_COLOR_G,
+		[LED_COLOR_ID_BLUE] = OMNIA_CMD_LED_COLOR_B,
+	};
+	struct omnia_leds *leds = dev_get_drvdata(cdev->dev->parent);
+	struct omnia_led *led = to_omnia_led(cdev);
+	u8 buf[OMNIA_CMD_LED_COLOR_LEN], state;
+	int ret;
+
+	mutex_lock(&leds->lock);
+
+	buf[OMNIA_CMD] = CMD_LED_COLOR;
+	buf[OMNIA_CMD_LED_COLOR_LED] = led->reg;
+
+	if (led->color == LED_COLOR_ID_WHITE) {
+		buf[OMNIA_CMD_LED_COLOR_R] = brightness;
+		buf[OMNIA_CMD_LED_COLOR_G] = brightness;
+		buf[OMNIA_CMD_LED_COLOR_B] = brightness;
+	} else {
+		buf[OMNIA_CMD_LED_COLOR_R] = leds->cache[led->reg][0];
+		buf[OMNIA_CMD_LED_COLOR_G] = leds->cache[led->reg][1];
+		buf[OMNIA_CMD_LED_COLOR_B] = leds->cache[led->reg][2];
+		buf[color2cmd[led->color]] = brightness;
+	}
+
+	state = CMD_LED_STATE_LED(led->reg);
+	if (buf[OMNIA_CMD_LED_COLOR_R] || buf[OMNIA_CMD_LED_COLOR_G] ||
+	    buf[OMNIA_CMD_LED_COLOR_B])
+		state |= CMD_LED_STATE_ON;
+
+	ret = i2c_smbus_write_byte_data(leds->client, CMD_LED_STATE, state);
+	if (ret >= 0 && (state & CMD_LED_STATE_ON))
+		ret = i2c_master_send(leds->client, buf, 5);
+
+	leds->cache[led->reg][0] = buf[OMNIA_CMD_LED_COLOR_R];
+	leds->cache[led->reg][1] = buf[OMNIA_CMD_LED_COLOR_G];
+	leds->cache[led->reg][2] = buf[OMNIA_CMD_LED_COLOR_B];
+
+	mutex_unlock(&leds->lock);
+
+	return ret;
+}
+
+static int omnia_led_register(struct omnia_leds *leds,
+			      struct fwnode_handle *node)
+{
+	struct i2c_client *client = leds->client;
+	struct led_init_data init_data = {};
+	struct device *dev = &client->dev;
+	struct omnia_led *led;
+	int ret, nsources, color;
+	u32 reg, led_sources[3];
+
+	led = &leds->leds[leds->nleds];
+
+	ret = fwnode_property_read_u32(node, "reg", &reg);
+	if (ret) {
+		dev_err(dev, "Node %pfw: 'reg' read failed!\n", node);
+		return ret;
+	}
+
+	if (reg >= OMNIA_BOARD_LEDS) {
+		dev_warn(dev, "Node %pfw: invalid 'reg' value %u\n", node, reg);
+		return 0;
+	}
+
+	nsources = fwnode_property_count_u32(node, "led-sources");
+	if (nsources != 1 && nsources != 3) {
+		dev_warn(dev, "Node %pfw: either 1 or 3 'led-sources' must be specified!\n",
+			 node);
+		return 0;
+	}
+
+	ret = fwnode_property_read_u32_array(node, "led-sources", led_sources,
+					     nsources);
+	if (ret) {
+		dev_err(dev, "Node %pfw: 'led-sources' read failed: %i\n",
+			node, ret);
+		return ret;
+	}
+
+	ret = fwnode_property_read_u32(node, "color", &led->color);
+	if (ret) {
+		dev_warn(dev, "Node %pfw: 'color' read failed!\n",
+			 node);
+		return 0;
+	}
+
+	if (nsources == 3) {
+		if (led_sources[0] != 3 * reg ||
+		    led_sources[1] != 3 * reg + 1 ||
+		    led_sources[2] != 3 * reg + 2) {
+			dev_warn(dev, "Node %pfw has invalid 'led-sources'!\n",
+				 node);
+			return 0;
+		}
+
+		color = LED_COLOR_ID_WHITE;
+	} else {
+		const int led_source_to_color[3] = {
+			LED_COLOR_ID_RED,
+			LED_COLOR_ID_GREEN,
+			LED_COLOR_ID_BLUE
+		};
+		color = led_source_to_color[led_sources[0] % 3];
+
+		if (led_sources[0] < 3 * reg || led_sources[0] > 3 * reg + 2) {
+			dev_warn(dev, "Node %pfw has invalid 'led-sources'!\n",
+				 node);
+			return 0;
+		}
+	}
+
+	if (led->color != color) {
+		dev_warn(dev, "Node %pfw: 'color' should be %s!\n", node,
+			 led_colors[color]);
+		return 0;
+	}
+
+	init_data.devicename = "omnia";
+	init_data.fwnode = node;
+	init_data.devname_mandatory = true;
+
+	led->reg = reg;
+	led->cdev.max_brightness = 255;
+	led->cdev.brightness_set_blocking = omnia_led_brightness_set_blocking;
+
+	fwnode_property_read_string(node, "linux,default-trigger",
+				    &led->cdev.default_trigger);
+
+	/* put the LED into software mode */
+	ret = i2c_smbus_write_byte_data(client, CMD_LED_MODE,
+					CMD_LED_MODE_LED(reg) |
+					CMD_LED_MODE_USER);
+	if (ret < 0) {
+		dev_err(dev, "Cannot set LED %pfw to software mode: %i\n", node,
+			ret);
+		return ret;
+	}
+
+	/* disable the LED */
+	ret = i2c_smbus_write_byte_data(client, CMD_LED_STATE,
+						CMD_LED_STATE_LED(reg));
+	if (ret < 0) {
+		dev_err(dev, "Cannot set LED %pfw brightness: %i\n", node, ret);
+		return ret;
+	}
+
+	ret = devm_led_classdev_register_ext(dev, &led->cdev, &init_data);
+	if (ret < 0) {
+		dev_err(dev, "Cannot register LED %pfw: %i\n", node, ret);
+		return ret;
+	}
+
+	++leds->nleds;
+
+	return 0;
+}
+
+static int omnia_leds_probe(struct i2c_client *client,
+			    const struct i2c_device_id *id)
+{
+	struct device *dev = &client->dev;
+	struct device_node *np = dev->of_node, *child;
+	struct omnia_leds *leds;
+	int ret, count;
+
+	count = of_get_available_child_count(np);
+	if (!count) {
+		dev_err(dev, "LEDs are not defined in device tree!\n");
+		return -ENODEV;
+	} else if (count > 3 * OMNIA_BOARD_LEDS) {
+		dev_err(dev, "Too many LEDs defined in device tree!\n");
+		return -EINVAL;
+	}
+
+	leds = devm_kzalloc(dev, sizeof(*leds) + count * sizeof(leds->leds[0]),
+			    GFP_KERNEL);
+	if (!leds)
+		return -ENOMEM;
+
+	leds->client = client;
+	i2c_set_clientdata(client, leds);
+
+	mutex_init(&leds->lock);
+
+	for_each_available_child_of_node(np, child) {
+		ret = omnia_led_register(leds, &child->fwnode);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int omnia_leds_remove(struct i2c_client *client)
+{
+	u8 buf[OMNIA_CMD_LED_COLOR_LEN];
+
+	/* put all LEDs into default (HW triggered) mode */
+	i2c_smbus_write_byte_data(client, CMD_LED_MODE,
+				  CMD_LED_MODE_LED(OMNIA_BOARD_LEDS));
+
+	/* set all LEDs color to [255, 255, 255] */
+	buf[OMNIA_CMD] = CMD_LED_COLOR;
+	buf[OMNIA_CMD_LED_COLOR_LED] = OMNIA_BOARD_LEDS;
+	buf[OMNIA_CMD_LED_COLOR_R] = 255;
+	buf[OMNIA_CMD_LED_COLOR_G] = 255;
+	buf[OMNIA_CMD_LED_COLOR_B] = 255;
+
+	i2c_master_send(client, buf, 5);
+
+	return 0;
+}
+
+static const struct of_device_id of_omnia_leds_match[] = {
+	{ .compatible = "cznic,turris-omnia-leds", },
+	{},
+};
+
+static const struct i2c_device_id omnia_id[] = {
+	{ "omnia", 0 },
+	{ }
+};
+
+static struct i2c_driver omnia_leds_driver = {
+	.probe		= omnia_leds_probe,
+	.remove		= omnia_leds_remove,
+	.id_table	= omnia_id,
+	.driver		= {
+		.name	= "leds-turris-omnia",
+		.of_match_table = of_omnia_leds_match,
+	},
+};
+
+module_i2c_driver(omnia_leds_driver);
+
+MODULE_AUTHOR("Marek Behun <marek.behun@nic.cz>");
+MODULE_DESCRIPTION("CZ.NIC's Turris Omnia LEDs");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/md/dm-verity-fec.c b/drivers/md/dm-verity-fec.c
index 49147e634046..fb41b4f23c48 100644
--- a/drivers/md/dm-verity-fec.c
+++ b/drivers/md/dm-verity-fec.c
@@ -435,7 +435,7 @@ int verity_fec_decode(struct dm_verity *v, struct dm_verity_io *io,
 	fio->level++;
 
 	if (type == DM_VERITY_BLOCK_TYPE_METADATA)
-		block += v->data_blocks;
+		block = block - v->hash_start + v->data_blocks;
 
 	/*
 	 * For RS(M, N), the continuous FEC data is divided into blocks of N
diff --git a/drivers/md/dm-writecache.c b/drivers/md/dm-writecache.c
index 114927da9cc9..613c171b1b6d 100644
--- a/drivers/md/dm-writecache.c
+++ b/drivers/md/dm-writecache.c
@@ -931,6 +931,24 @@ static int writecache_alloc_entries(struct dm_writecache *wc)
 	return 0;
 }
 
+static int writecache_read_metadata(struct dm_writecache *wc, sector_t n_sectors)
+{
+	struct dm_io_region region;
+	struct dm_io_request req;
+
+	region.bdev = wc->ssd_dev->bdev;
+	region.sector = wc->start_sector;
+	region.count = n_sectors;
+	req.bi_op = REQ_OP_READ;
+	req.bi_op_flags = REQ_SYNC;
+	req.mem.type = DM_IO_VMA;
+	req.mem.ptr.vma = (char *)wc->memory_map;
+	req.client = wc->dm_io;
+	req.notify.fn = NULL;
+
+	return dm_io(&req, 1, &region, NULL);
+}
+
 static void writecache_resume(struct dm_target *ti)
 {
 	struct dm_writecache *wc = ti->private;
@@ -941,8 +959,18 @@ static void writecache_resume(struct dm_target *ti)
 
 	wc_lock(wc);
 
-	if (WC_MODE_PMEM(wc))
+	if (WC_MODE_PMEM(wc)) {
 		persistent_memory_invalidate_cache(wc->memory_map, wc->memory_map_size);
+	} else {
+		r = writecache_read_metadata(wc, wc->metadata_sectors);
+		if (r) {
+			size_t sb_entries_offset;
+			writecache_error(wc, r, "unable to read metadata: %d", r);
+			sb_entries_offset = offsetof(struct wc_memory_superblock, entries);
+			memset((char *)wc->memory_map + sb_entries_offset, -1,
+			       (wc->metadata_sectors << SECTOR_SHIFT) - sb_entries_offset);
+		}
+	}
 
 	wc->tree = RB_ROOT;
 	INIT_LIST_HEAD(&wc->lru);
@@ -2102,6 +2130,12 @@ static int writecache_ctr(struct dm_target *ti, unsigned argc, char **argv)
 		ti->error = "Invalid block size";
 		goto bad;
 	}
+	if (wc->block_size < bdev_logical_block_size(wc->dev->bdev) ||
+	    wc->block_size < bdev_logical_block_size(wc->ssd_dev->bdev)) {
+		r = -EINVAL;
+		ti->error = "Block size is smaller than device logical block size";
+		goto bad;
+	}
 	wc->block_size_bits = __ffs(wc->block_size);
 
 	wc->max_writeback_jobs = MAX_WRITEBACK_JOBS;
@@ -2200,8 +2234,6 @@ static int writecache_ctr(struct dm_target *ti, unsigned argc, char **argv)
 			goto bad;
 		}
 	} else {
-		struct dm_io_region region;
-		struct dm_io_request req;
 		size_t n_blocks, n_metadata_blocks;
 		uint64_t n_bitmap_bits;
 
@@ -2258,19 +2290,9 @@ static int writecache_ctr(struct dm_target *ti, unsigned argc, char **argv)
 			goto bad;
 		}
 
-		region.bdev = wc->ssd_dev->bdev;
-		region.sector = wc->start_sector;
-		region.count = wc->metadata_sectors;
-		req.bi_op = REQ_OP_READ;
-		req.bi_op_flags = REQ_SYNC;
-		req.mem.type = DM_IO_VMA;
-		req.mem.ptr.vma = (char *)wc->memory_map;
-		req.client = wc->dm_io;
-		req.notify.fn = NULL;
-
-		r = dm_io(&req, 1, &region, NULL);
+		r = writecache_read_metadata(wc, wc->block_size >> SECTOR_SHIFT);
 		if (r) {
-			ti->error = "Unable to read metadata";
+			ti->error = "Unable to read first block of metadata";
 			goto bad;
 		}
 	}
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig
index 9dfea5c4b6ab..a6d073f2e036 100644
--- a/drivers/media/Kconfig
+++ b/drivers/media/Kconfig
@@ -3,42 +3,81 @@
 # Multimedia device configuration
 #
 
-config CEC_CORE
-	tristate
-
-config CEC_NOTIFIER
-	bool
-
-config CEC_PIN
-	bool
-
+#
+# NOTE: CEC and Remote Controller support should not depend on MEDIA_SUPPORT
+#
 source "drivers/media/rc/Kconfig"
+source "drivers/media/cec/Kconfig"
 
 menuconfig MEDIA_SUPPORT
 	tristate "Multimedia support"
 	depends on HAS_IOMEM
 	help
-	  If you want to use Webcams, Video grabber devices and/or TV devices
-	  enable this option and other options below.
+	  If you want to use media devices, including Webcams, Video grabber
+	  devices and/or TV devices, V4L2 codecs, etc, enable this option
+	  and other options below.
+
 	  Additional info and docs are available on the web at
 	  <https://linuxtv.org>
 
 if MEDIA_SUPPORT
 
-comment "Multimedia core support"
+config MEDIA_SUPPORT_FILTER
+	bool "Filter media drivers"
+	depends on MEDIA_SUPPORT
+	default y if !EMBEDDED && !EXPERT
+	help
+	   Configuring the media subsystem can be complex, as there are
+	   hundreds of drivers and other config options.
+
+	   This menu offers option that will help the Kernel's config
+	   system to hide drivers that are out of the scope of the
+	   user needs, and disabling core support for unused APIs.
+
+	   If not selected, all non-optional media core functionality
+	   needed to support media drivers will be enabled. Also, all
+	   media device drivers should be shown.
+
+config MEDIA_SUBDRV_AUTOSELECT
+	bool "Autoselect ancillary drivers (tuners, sensors, i2c, spi, frontends)"
+	depends on HAS_IOMEM
+	select I2C
+	select I2C_MUX
+	default y if MEDIA_SUPPORT_FILTER
+	help
+	  By default, a media driver auto-selects all possible ancillary
+	  devices such as tuners, sensors, video encoders/decoders and
+	  frontends, that are used by any of the supported devices.
+
+	  This is generally the right thing to do, except when there
+	  are strict constraints with regards to the kernel size,
+	  like on embedded systems.
+
+	  Use this option with care, as deselecting ancillary drivers which
+	  are, in fact, necessary will result in the lack of the needed
+	  functionality for your device (it may not tune or may not have
+	  the needed demodulators).
+
+	  If unsure say Y.
+
+menu "Media device types"
 
 #
 # Multimedia support - automatically enable V4L2 and DVB core
 #
 config MEDIA_CAMERA_SUPPORT
-	bool "Cameras/video grabbers support"
+	bool
+	prompt "Cameras and video grabbers" if MEDIA_SUPPORT_FILTER
+	default y if !MEDIA_SUPPORT_FILTER
 	help
 	  Enable support for webcams and video grabbers.
 
 	  Say Y when you have a webcam or a video capture grabber board.
 
 config MEDIA_ANALOG_TV_SUPPORT
-	bool "Analog TV support"
+	bool
+	prompt "Analog TV" if MEDIA_SUPPORT_FILTER
+	default y if !MEDIA_SUPPORT_FILTER
 	help
 	  Enable analog TV support.
 
@@ -50,7 +89,9 @@ config MEDIA_ANALOG_TV_SUPPORT
 		will disable support for them.
 
 config MEDIA_DIGITAL_TV_SUPPORT
-	bool "Digital TV support"
+	bool
+	prompt "Digital TV" if MEDIA_SUPPORT_FILTER
+	default y if !MEDIA_SUPPORT_FILTER
 	help
 	  Enable digital TV support.
 
@@ -58,7 +99,9 @@ config MEDIA_DIGITAL_TV_SUPPORT
 	  hybrid digital TV and analog TV.
 
 config MEDIA_RADIO_SUPPORT
-	bool "AM/FM radio receivers/transmitters support"
+	bool
+	prompt "AM/FM radio receivers/transmitters" if MEDIA_SUPPORT_FILTER
+	default y if !MEDIA_SUPPORT_FILTER
 	help
 	  Enable AM/FM radio support.
 
@@ -72,47 +115,65 @@ config MEDIA_RADIO_SUPPORT
 		disable support for them.
 
 config MEDIA_SDR_SUPPORT
-	bool "Software defined radio support"
+	bool
+	prompt "Software defined radio" if MEDIA_SUPPORT_FILTER
+	default y if !MEDIA_SUPPORT_FILTER
 	help
 	  Enable software defined radio support.
 
 	  Say Y when you have a software defined radio device.
 
-config MEDIA_CEC_SUPPORT
-	bool "HDMI CEC support"
+config MEDIA_PLATFORM_SUPPORT
+	bool
+	prompt "Platform-specific devices" if MEDIA_SUPPORT_FILTER
+	default y if !MEDIA_SUPPORT_FILTER
 	help
-	  Enable support for HDMI CEC (Consumer Electronics Control),
-	  which is an optional HDMI feature.
+	  Enable support for complex cameras, codecs, and other hardware
+	  that are integrated at the CPU, GPU or on Image Signalling Processor
+	  and don't use PCI, USB or Firewire buses.
 
-	  Say Y when you have an HDMI receiver, transmitter or a USB CEC
-	  adapter that supports HDMI CEC.
+	  This is found on Embedded hardware (SoC), on V4L2 codecs and
+	  on some GPU and newer CPU chipsets.
 
-source "drivers/media/cec/Kconfig"
+	  Say Y when you want to be able so see such devices.
 
-source "drivers/media/mc/Kconfig"
+config MEDIA_TEST_SUPPORT
+	bool
+	prompt "Test drivers" if MEDIA_SUPPORT_FILTER
+	default y if !MEDIA_SUPPORT_FILTER
+	help
+	  Those drivers should not be used on production Kernels, but
+	  can be useful on debug ones. It enables several dummy drivers
+	  that simulate a real hardware. Very useful to test userspace
+	  applications and to validate if the subsystem core is doesn't
+	  have regressions.
 
-#
-# Video4Linux support
-#	Only enables if one of the V4L2 types (ATV, webcam, radio) is selected
-#
+	  Say Y if you want to use some virtual test driver.
+
+	  In case of doubts, say N.
+	  Say Y when you have a software defined radio device.
+endmenu # media device types
+
+
+menu "Media core support"
+	visible if !MEDIA_SUPPORT_FILTER
 
 config VIDEO_DEV
-	tristate
-	depends on MEDIA_SUPPORT
-	depends on MEDIA_CAMERA_SUPPORT || MEDIA_ANALOG_TV_SUPPORT || MEDIA_RADIO_SUPPORT || MEDIA_SDR_SUPPORT
-	default y
+	tristate "Video4Linux core"
+	default MEDIA_CAMERA_SUPPORT || MEDIA_ANALOG_TV_SUPPORT || MEDIA_RADIO_SUPPORT || MEDIA_SDR_SUPPORT || MEDIA_PLATFORM_SUPPORT || MEDIA_TEST_SUPPORT
+	help
+	  Enables the V4L2 API, used by cameras, analog TV, video grabbers,
+	  radio devices and by some input devices.
 
-config VIDEO_V4L2_SUBDEV_API
-	bool "V4L2 sub-device userspace API"
-	depends on VIDEO_DEV && MEDIA_CONTROLLER
+config MEDIA_CONTROLLER
+	bool "Media Controller API"
+	default MEDIA_CAMERA_SUPPORT || MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT || MEDIA_PLATFORM_SUPPORT
 	help
-	  Enables the V4L2 sub-device pad-level userspace API used to configure
-	  video format, size and frame rate between hardware blocks.
+	  Enable the media controller API used to query media devices internal
+	  topology and configure it dynamically.
 
 	  This API is mostly used by camera interfaces in embedded platforms.
 
-source "drivers/media/v4l2-core/Kconfig"
-
 #
 # DVB Core
 #	Only enables if one of DTV is selected
@@ -120,98 +181,73 @@ source "drivers/media/v4l2-core/Kconfig"
 
 config DVB_CORE
 	tristate
-	depends on MEDIA_SUPPORT
 	depends on MEDIA_DIGITAL_TV_SUPPORT
 	depends on (I2C || I2C=n)
-	default y
+	default MEDIA_DIGITAL_TV_SUPPORT
 	select CRC32
-
-config DVB_MMAP
-	bool "Enable DVB memory-mapped API (EXPERIMENTAL)"
-	depends on DVB_CORE
-	depends on VIDEO_V4L2=y || VIDEO_V4L2=DVB_CORE
-	select VIDEOBUF2_VMALLOC
 	help
-	  This option enables DVB experimental memory-mapped API, which
-	  reduces the number of context switches to read DVB buffers, as
-	  the buffers can use mmap() syscalls.
+	  Enables the DVB API, used by Digital TV devices. Supports several
+	  standards, including DVB, ATSC, ISDB and CMDB.
 
-	  Support for it is experimental. Use with care. If unsure,
-	  say N.
+endmenu # Media core support
 
-config DVB_NET
-	bool "DVB Network Support"
-	default (NET && INET)
-	depends on NET && INET && DVB_CORE
-	help
-	  This option enables DVB Network Support which is a part of the DVB
-	  standard. It is used, for example, by automatic firmware updates used
-	  on Set-Top-Boxes. It can also be used to access the Internet via the
-	  DVB card, if the network provider supports it.
+#
+# Extra per-media API core functionality
 
-	  You may want to disable the network support on embedded devices. If
-	  unsure say Y.
+menu "Video4Linux options"
+	visible if VIDEO_DEV
 
-# This Kconfig option is used by both PCI and USB drivers
-config TTPCI_EEPROM
-	tristate
-	depends on I2C
+source "drivers/media/v4l2-core/Kconfig"
+endmenu
+
+menu "Media controller options"
+	visible if MEDIA_CONTROLLER
+
+source "drivers/media/mc/Kconfig"
+endmenu
+
+menu "Digital TV options"
+	visible if DVB_CORE
 
 source "drivers/media/dvb-core/Kconfig"
+endmenu
 
-comment "Media drivers"
+menu "Media drivers"
 
-#
-# V4L platform/mem2mem drivers
-#
+comment "Drivers filtered as selected at 'Filter media drivers'"
+	depends on MEDIA_SUPPORT_FILTER
 
 source "drivers/media/usb/Kconfig"
 source "drivers/media/pci/Kconfig"
-source "drivers/media/platform/Kconfig"
-source "drivers/media/mmc/Kconfig"
 source "drivers/media/radio/Kconfig"
 
-comment "Supported FireWire (IEEE 1394) Adapters"
-	depends on DVB_CORE && FIREWIRE
-source "drivers/media/firewire/Kconfig"
-
 # Common driver options
 source "drivers/media/common/Kconfig"
 
-comment "Media ancillary drivers (tuners, sensors, i2c, spi, frontends)"
-
-#
-# Ancillary drivers (tuners, i2c, spi, frontends)
-#
+if MEDIA_PLATFORM_SUPPORT
+source "drivers/media/platform/Kconfig"
+source "drivers/media/mmc/Kconfig"
+endif
 
-config MEDIA_SUBDRV_AUTOSELECT
-	bool "Autoselect ancillary drivers (tuners, sensors, i2c, spi, frontends)"
-	depends on MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT || MEDIA_CAMERA_SUPPORT || MEDIA_SDR_SUPPORT
-	depends on HAS_IOMEM
-	select I2C
-	select I2C_MUX
-	default y if !EMBEDDED
-	help
-	  By default, a media driver auto-selects all possible ancillary
-	  devices such as tuners, sensors, video encoders/decoders and
-	  frontends, that are used by any of the supported devices.
+if MEDIA_TEST_SUPPORT
+source "drivers/media/test-drivers/Kconfig"
+endif
 
-	  This is generally the right thing to do, except when there
-	  are strict constraints with regards to the kernel size,
-	  like on embedded systems.
+source "drivers/media/firewire/Kconfig"
 
-	  Use this option with care, as deselecting ancillary drivers which
-	  are, in fact, necessary will result in the lack of the needed
-	  functionality for your device (it may not tune or may not have
-	  the needed demodulators).
+endmenu
 
-	  If unsure say Y.
+#
+# Ancillary drivers (tuners, i2c, spi, frontends)
+#
 
 config MEDIA_HIDE_ANCILLARY_SUBDRV
 	bool
 	depends on MEDIA_SUBDRV_AUTOSELECT && !COMPILE_TEST && !EXPERT
 	default y
 
+menu "Media ancillary drivers"
+
 config MEDIA_ATTACH
 	bool
 	depends on MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT || MEDIA_RADIO_SUPPORT
@@ -223,4 +259,6 @@ source "drivers/media/spi/Kconfig"
 source "drivers/media/tuners/Kconfig"
 source "drivers/media/dvb-frontends/Kconfig"
 
+endmenu
+
 endif # MEDIA_SUPPORT
diff --git a/drivers/media/Makefile b/drivers/media/Makefile
index f215f0a89f9e..d18357bf1346 100644
--- a/drivers/media/Makefile
+++ b/drivers/media/Makefile
@@ -29,6 +29,6 @@ obj-$(CONFIG_CEC_CORE) += cec/
 # Finally, merge the drivers that require the core
 #
 
-obj-y += common/ platform/ pci/ usb/ mmc/ firewire/ spi/
+obj-y += common/ platform/ pci/ usb/ mmc/ firewire/ spi/ test-drivers/
 obj-$(CONFIG_VIDEO_DEV) += radio/
 
diff --git a/drivers/media/cec/Kconfig b/drivers/media/cec/Kconfig
index c01919713ab9..eea74b7cfa8c 100644
--- a/drivers/media/cec/Kconfig
+++ b/drivers/media/cec/Kconfig
@@ -1,4 +1,13 @@
 # SPDX-License-Identifier: GPL-2.0-only
+config CEC_CORE
+	tristate
+
+config CEC_NOTIFIER
+	bool
+
+config CEC_PIN
+	bool
+
 config MEDIA_CEC_RC
 	bool "HDMI CEC RC integration"
 	depends on CEC_CORE && RC_CORE
@@ -11,3 +20,19 @@ config CEC_PIN_ERROR_INJ
 	depends on CEC_PIN && DEBUG_FS
 	help
 	  This option enables CEC error injection using debugfs.
+
+menuconfig MEDIA_CEC_SUPPORT
+	bool
+	prompt "HDMI CEC drivers"
+	default y if !MEDIA_SUPPORT_FILTER
+	help
+	  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.
+
+if MEDIA_CEC_SUPPORT
+source "drivers/media/cec/platform/Kconfig"
+source "drivers/media/cec/usb/Kconfig"
+endif
diff --git a/drivers/media/cec/Makefile b/drivers/media/cec/Makefile
index ad8677d8c896..74e80e1b3571 100644
--- a/drivers/media/cec/Makefile
+++ b/drivers/media/cec/Makefile
@@ -1,16 +1,2 @@
 # SPDX-License-Identifier: GPL-2.0
-cec-objs := cec-core.o cec-adap.o cec-api.o
-
-ifeq ($(CONFIG_CEC_NOTIFIER),y)
-  cec-objs += cec-notifier.o
-endif
-
-ifeq ($(CONFIG_CEC_PIN),y)
-  cec-objs += cec-pin.o
-endif
-
-ifeq ($(CONFIG_CEC_PIN_ERROR_INJ),y)
-  cec-objs += cec-pin-error-inj.o
-endif
-
-obj-$(CONFIG_CEC_CORE) += cec.o
+obj-y += core/ platform/ usb/
diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c
deleted file mode 100644
index 6c95dc471d4c..000000000000
--- a/drivers/media/cec/cec-adap.c
+++ /dev/null
@@ -1,2199 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * cec-adap.c - HDMI Consumer Electronics Control framework - CEC adapter
- *
- * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/kmod.h>
-#include <linux/ktime.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/types.h>
-
-#include <drm/drm_connector.h>
-#include <drm/drm_device.h>
-#include <drm/drm_edid.h>
-#include <drm/drm_file.h>
-
-#include "cec-priv.h"
-
-static void cec_fill_msg_report_features(struct cec_adapter *adap,
-					 struct cec_msg *msg,
-					 unsigned int la_idx);
-
-/*
- * 400 ms is the time it takes for one 16 byte message to be
- * transferred and 5 is the maximum number of retries. Add
- * another 100 ms as a margin. So if the transmit doesn't
- * finish before that time something is really wrong and we
- * have to time out.
- *
- * This is a sign that something it really wrong and a warning
- * will be issued.
- */
-#define CEC_XFER_TIMEOUT_MS (5 * 400 + 100)
-
-#define call_op(adap, op, arg...) \
-	(adap->ops->op ? adap->ops->op(adap, ## arg) : 0)
-
-#define call_void_op(adap, op, arg...)			\
-	do {						\
-		if (adap->ops->op)			\
-			adap->ops->op(adap, ## arg);	\
-	} while (0)
-
-static int cec_log_addr2idx(const struct cec_adapter *adap, u8 log_addr)
-{
-	int i;
-
-	for (i = 0; i < adap->log_addrs.num_log_addrs; i++)
-		if (adap->log_addrs.log_addr[i] == log_addr)
-			return i;
-	return -1;
-}
-
-static unsigned int cec_log_addr2dev(const struct cec_adapter *adap, u8 log_addr)
-{
-	int i = cec_log_addr2idx(adap, log_addr);
-
-	return adap->log_addrs.primary_device_type[i < 0 ? 0 : i];
-}
-
-u16 cec_get_edid_phys_addr(const u8 *edid, unsigned int size,
-			   unsigned int *offset)
-{
-	unsigned int loc = cec_get_edid_spa_location(edid, size);
-
-	if (offset)
-		*offset = loc;
-	if (loc == 0)
-		return CEC_PHYS_ADDR_INVALID;
-	return (edid[loc] << 8) | edid[loc + 1];
-}
-EXPORT_SYMBOL_GPL(cec_get_edid_phys_addr);
-
-void cec_fill_conn_info_from_drm(struct cec_connector_info *conn_info,
-				 const struct drm_connector *connector)
-{
-	memset(conn_info, 0, sizeof(*conn_info));
-	conn_info->type = CEC_CONNECTOR_TYPE_DRM;
-	conn_info->drm.card_no = connector->dev->primary->index;
-	conn_info->drm.connector_id = connector->base.id;
-}
-EXPORT_SYMBOL_GPL(cec_fill_conn_info_from_drm);
-
-/*
- * Queue a new event for this filehandle. If ts == 0, then set it
- * to the current time.
- *
- * We keep a queue of at most max_event events where max_event differs
- * per event. If the queue becomes full, then drop the oldest event and
- * keep track of how many events we've dropped.
- */
-void cec_queue_event_fh(struct cec_fh *fh,
-			const struct cec_event *new_ev, u64 ts)
-{
-	static const u16 max_events[CEC_NUM_EVENTS] = {
-		1, 1, 800, 800, 8, 8, 8, 8
-	};
-	struct cec_event_entry *entry;
-	unsigned int ev_idx = new_ev->event - 1;
-
-	if (WARN_ON(ev_idx >= ARRAY_SIZE(fh->events)))
-		return;
-
-	if (ts == 0)
-		ts = ktime_get_ns();
-
-	mutex_lock(&fh->lock);
-	if (ev_idx < CEC_NUM_CORE_EVENTS)
-		entry = &fh->core_events[ev_idx];
-	else
-		entry = kmalloc(sizeof(*entry), GFP_KERNEL);
-	if (entry) {
-		if (new_ev->event == CEC_EVENT_LOST_MSGS &&
-		    fh->queued_events[ev_idx]) {
-			entry->ev.lost_msgs.lost_msgs +=
-				new_ev->lost_msgs.lost_msgs;
-			goto unlock;
-		}
-		entry->ev = *new_ev;
-		entry->ev.ts = ts;
-
-		if (fh->queued_events[ev_idx] < max_events[ev_idx]) {
-			/* Add new msg at the end of the queue */
-			list_add_tail(&entry->list, &fh->events[ev_idx]);
-			fh->queued_events[ev_idx]++;
-			fh->total_queued_events++;
-			goto unlock;
-		}
-
-		if (ev_idx >= CEC_NUM_CORE_EVENTS) {
-			list_add_tail(&entry->list, &fh->events[ev_idx]);
-			/* drop the oldest event */
-			entry = list_first_entry(&fh->events[ev_idx],
-						 struct cec_event_entry, list);
-			list_del(&entry->list);
-			kfree(entry);
-		}
-	}
-	/* Mark that events were lost */
-	entry = list_first_entry_or_null(&fh->events[ev_idx],
-					 struct cec_event_entry, list);
-	if (entry)
-		entry->ev.flags |= CEC_EVENT_FL_DROPPED_EVENTS;
-
-unlock:
-	mutex_unlock(&fh->lock);
-	wake_up_interruptible(&fh->wait);
-}
-
-/* Queue a new event for all open filehandles. */
-static void cec_queue_event(struct cec_adapter *adap,
-			    const struct cec_event *ev)
-{
-	u64 ts = ktime_get_ns();
-	struct cec_fh *fh;
-
-	mutex_lock(&adap->devnode.lock);
-	list_for_each_entry(fh, &adap->devnode.fhs, list)
-		cec_queue_event_fh(fh, ev, ts);
-	mutex_unlock(&adap->devnode.lock);
-}
-
-/* Notify userspace that the CEC pin changed state at the given time. */
-void cec_queue_pin_cec_event(struct cec_adapter *adap, bool is_high,
-			     bool dropped_events, ktime_t ts)
-{
-	struct cec_event ev = {
-		.event = is_high ? CEC_EVENT_PIN_CEC_HIGH :
-				   CEC_EVENT_PIN_CEC_LOW,
-		.flags = dropped_events ? CEC_EVENT_FL_DROPPED_EVENTS : 0,
-	};
-	struct cec_fh *fh;
-
-	mutex_lock(&adap->devnode.lock);
-	list_for_each_entry(fh, &adap->devnode.fhs, list)
-		if (fh->mode_follower == CEC_MODE_MONITOR_PIN)
-			cec_queue_event_fh(fh, &ev, ktime_to_ns(ts));
-	mutex_unlock(&adap->devnode.lock);
-}
-EXPORT_SYMBOL_GPL(cec_queue_pin_cec_event);
-
-/* Notify userspace that the HPD pin changed state at the given time. */
-void cec_queue_pin_hpd_event(struct cec_adapter *adap, bool is_high, ktime_t ts)
-{
-	struct cec_event ev = {
-		.event = is_high ? CEC_EVENT_PIN_HPD_HIGH :
-				   CEC_EVENT_PIN_HPD_LOW,
-	};
-	struct cec_fh *fh;
-
-	mutex_lock(&adap->devnode.lock);
-	list_for_each_entry(fh, &adap->devnode.fhs, list)
-		cec_queue_event_fh(fh, &ev, ktime_to_ns(ts));
-	mutex_unlock(&adap->devnode.lock);
-}
-EXPORT_SYMBOL_GPL(cec_queue_pin_hpd_event);
-
-/* Notify userspace that the 5V pin changed state at the given time. */
-void cec_queue_pin_5v_event(struct cec_adapter *adap, bool is_high, ktime_t ts)
-{
-	struct cec_event ev = {
-		.event = is_high ? CEC_EVENT_PIN_5V_HIGH :
-				   CEC_EVENT_PIN_5V_LOW,
-	};
-	struct cec_fh *fh;
-
-	mutex_lock(&adap->devnode.lock);
-	list_for_each_entry(fh, &adap->devnode.fhs, list)
-		cec_queue_event_fh(fh, &ev, ktime_to_ns(ts));
-	mutex_unlock(&adap->devnode.lock);
-}
-EXPORT_SYMBOL_GPL(cec_queue_pin_5v_event);
-
-/*
- * Queue a new message for this filehandle.
- *
- * We keep a queue of at most CEC_MAX_MSG_RX_QUEUE_SZ messages. If the
- * queue becomes full, then drop the oldest message and keep track
- * of how many messages we've dropped.
- */
-static void cec_queue_msg_fh(struct cec_fh *fh, const struct cec_msg *msg)
-{
-	static const struct cec_event ev_lost_msgs = {
-		.event = CEC_EVENT_LOST_MSGS,
-		.flags = 0,
-		{
-			.lost_msgs = { 1 },
-		},
-	};
-	struct cec_msg_entry *entry;
-
-	mutex_lock(&fh->lock);
-	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
-	if (entry) {
-		entry->msg = *msg;
-		/* Add new msg at the end of the queue */
-		list_add_tail(&entry->list, &fh->msgs);
-
-		if (fh->queued_msgs < CEC_MAX_MSG_RX_QUEUE_SZ) {
-			/* All is fine if there is enough room */
-			fh->queued_msgs++;
-			mutex_unlock(&fh->lock);
-			wake_up_interruptible(&fh->wait);
-			return;
-		}
-
-		/*
-		 * if the message queue is full, then drop the oldest one and
-		 * send a lost message event.
-		 */
-		entry = list_first_entry(&fh->msgs, struct cec_msg_entry, list);
-		list_del(&entry->list);
-		kfree(entry);
-	}
-	mutex_unlock(&fh->lock);
-
-	/*
-	 * We lost a message, either because kmalloc failed or the queue
-	 * was full.
-	 */
-	cec_queue_event_fh(fh, &ev_lost_msgs, ktime_get_ns());
-}
-
-/*
- * Queue the message for those filehandles that are in monitor mode.
- * If valid_la is true (this message is for us or was sent by us),
- * then pass it on to any monitoring filehandle. If this message
- * isn't for us or from us, then only give it to filehandles that
- * are in MONITOR_ALL mode.
- *
- * This can only happen if the CEC_CAP_MONITOR_ALL capability is
- * set and the CEC adapter was placed in 'monitor all' mode.
- */
-static void cec_queue_msg_monitor(struct cec_adapter *adap,
-				  const struct cec_msg *msg,
-				  bool valid_la)
-{
-	struct cec_fh *fh;
-	u32 monitor_mode = valid_la ? CEC_MODE_MONITOR :
-				      CEC_MODE_MONITOR_ALL;
-
-	mutex_lock(&adap->devnode.lock);
-	list_for_each_entry(fh, &adap->devnode.fhs, list) {
-		if (fh->mode_follower >= monitor_mode)
-			cec_queue_msg_fh(fh, msg);
-	}
-	mutex_unlock(&adap->devnode.lock);
-}
-
-/*
- * Queue the message for follower filehandles.
- */
-static void cec_queue_msg_followers(struct cec_adapter *adap,
-				    const struct cec_msg *msg)
-{
-	struct cec_fh *fh;
-
-	mutex_lock(&adap->devnode.lock);
-	list_for_each_entry(fh, &adap->devnode.fhs, list) {
-		if (fh->mode_follower == CEC_MODE_FOLLOWER)
-			cec_queue_msg_fh(fh, msg);
-	}
-	mutex_unlock(&adap->devnode.lock);
-}
-
-/* Notify userspace of an adapter state change. */
-static void cec_post_state_event(struct cec_adapter *adap)
-{
-	struct cec_event ev = {
-		.event = CEC_EVENT_STATE_CHANGE,
-	};
-
-	ev.state_change.phys_addr = adap->phys_addr;
-	ev.state_change.log_addr_mask = adap->log_addrs.log_addr_mask;
-	ev.state_change.have_conn_info =
-		adap->conn_info.type != CEC_CONNECTOR_TYPE_NO_CONNECTOR;
-	cec_queue_event(adap, &ev);
-}
-
-/*
- * A CEC transmit (and a possible wait for reply) completed.
- * If this was in blocking mode, then complete it, otherwise
- * queue the message for userspace to dequeue later.
- *
- * This function is called with adap->lock held.
- */
-static void cec_data_completed(struct cec_data *data)
-{
-	/*
-	 * Delete this transmit from the filehandle's xfer_list since
-	 * we're done with it.
-	 *
-	 * Note that if the filehandle is closed before this transmit
-	 * finished, then the release() function will set data->fh to NULL.
-	 * Without that we would be referring to a closed filehandle.
-	 */
-	if (data->fh)
-		list_del(&data->xfer_list);
-
-	if (data->blocking) {
-		/*
-		 * Someone is blocking so mark the message as completed
-		 * and call complete.
-		 */
-		data->completed = true;
-		complete(&data->c);
-	} else {
-		/*
-		 * No blocking, so just queue the message if needed and
-		 * free the memory.
-		 */
-		if (data->fh)
-			cec_queue_msg_fh(data->fh, &data->msg);
-		kfree(data);
-	}
-}
-
-/*
- * A pending CEC transmit needs to be cancelled, either because the CEC
- * adapter is disabled or the transmit takes an impossibly long time to
- * finish.
- *
- * This function is called with adap->lock held.
- */
-static void cec_data_cancel(struct cec_data *data, u8 tx_status)
-{
-	/*
-	 * It's either the current transmit, or it is a pending
-	 * transmit. Take the appropriate action to clear it.
-	 */
-	if (data->adap->transmitting == data) {
-		data->adap->transmitting = NULL;
-	} else {
-		list_del_init(&data->list);
-		if (!(data->msg.tx_status & CEC_TX_STATUS_OK))
-			if (!WARN_ON(!data->adap->transmit_queue_sz))
-				data->adap->transmit_queue_sz--;
-	}
-
-	if (data->msg.tx_status & CEC_TX_STATUS_OK) {
-		data->msg.rx_ts = ktime_get_ns();
-		data->msg.rx_status = CEC_RX_STATUS_ABORTED;
-	} else {
-		data->msg.tx_ts = ktime_get_ns();
-		data->msg.tx_status |= tx_status |
-				       CEC_TX_STATUS_MAX_RETRIES;
-		data->msg.tx_error_cnt++;
-		data->attempts = 0;
-	}
-
-	/* Queue transmitted message for monitoring purposes */
-	cec_queue_msg_monitor(data->adap, &data->msg, 1);
-
-	cec_data_completed(data);
-}
-
-/*
- * Flush all pending transmits and cancel any pending timeout work.
- *
- * This function is called with adap->lock held.
- */
-static void cec_flush(struct cec_adapter *adap)
-{
-	struct cec_data *data, *n;
-
-	/*
-	 * If the adapter is disabled, or we're asked to stop,
-	 * then cancel any pending transmits.
-	 */
-	while (!list_empty(&adap->transmit_queue)) {
-		data = list_first_entry(&adap->transmit_queue,
-					struct cec_data, list);
-		cec_data_cancel(data, CEC_TX_STATUS_ABORTED);
-	}
-	if (adap->transmitting)
-		cec_data_cancel(adap->transmitting, CEC_TX_STATUS_ABORTED);
-
-	/* Cancel the pending timeout work. */
-	list_for_each_entry_safe(data, n, &adap->wait_queue, list) {
-		if (cancel_delayed_work(&data->work))
-			cec_data_cancel(data, CEC_TX_STATUS_OK);
-		/*
-		 * If cancel_delayed_work returned false, then
-		 * the cec_wait_timeout function is running,
-		 * which will call cec_data_completed. So no
-		 * need to do anything special in that case.
-		 */
-	}
-	/*
-	 * If something went wrong and this counter isn't what it should
-	 * be, then this will reset it back to 0. Warn if it is not 0,
-	 * since it indicates a bug, either in this framework or in a
-	 * CEC driver.
-	 */
-	if (WARN_ON(adap->transmit_queue_sz))
-		adap->transmit_queue_sz = 0;
-}
-
-/*
- * Main CEC state machine
- *
- * Wait until the thread should be stopped, or we are not transmitting and
- * a new transmit message is queued up, in which case we start transmitting
- * that message. When the adapter finished transmitting the message it will
- * call cec_transmit_done().
- *
- * If the adapter is disabled, then remove all queued messages instead.
- *
- * If the current transmit times out, then cancel that transmit.
- */
-int cec_thread_func(void *_adap)
-{
-	struct cec_adapter *adap = _adap;
-
-	for (;;) {
-		unsigned int signal_free_time;
-		struct cec_data *data;
-		bool timeout = false;
-		u8 attempts;
-
-		if (adap->transmit_in_progress) {
-			int err;
-
-			/*
-			 * We are transmitting a message, so add a timeout
-			 * to prevent the state machine to get stuck waiting
-			 * for this message to finalize and add a check to
-			 * see if the adapter is disabled in which case the
-			 * transmit should be canceled.
-			 */
-			err = wait_event_interruptible_timeout(adap->kthread_waitq,
-				(adap->needs_hpd &&
-				 (!adap->is_configured && !adap->is_configuring)) ||
-				kthread_should_stop() ||
-				(!adap->transmit_in_progress &&
-				 !list_empty(&adap->transmit_queue)),
-				msecs_to_jiffies(CEC_XFER_TIMEOUT_MS));
-			timeout = err == 0;
-		} else {
-			/* Otherwise we just wait for something to happen. */
-			wait_event_interruptible(adap->kthread_waitq,
-				kthread_should_stop() ||
-				(!adap->transmit_in_progress &&
-				 !list_empty(&adap->transmit_queue)));
-		}
-
-		mutex_lock(&adap->lock);
-
-		if ((adap->needs_hpd &&
-		     (!adap->is_configured && !adap->is_configuring)) ||
-		    kthread_should_stop()) {
-			cec_flush(adap);
-			goto unlock;
-		}
-
-		if (adap->transmit_in_progress && timeout) {
-			/*
-			 * If we timeout, then log that. Normally this does
-			 * not happen and it is an indication of a faulty CEC
-			 * adapter driver, or the CEC bus is in some weird
-			 * state. On rare occasions it can happen if there is
-			 * so much traffic on the bus that the adapter was
-			 * unable to transmit for CEC_XFER_TIMEOUT_MS (2.1s).
-			 */
-			if (adap->transmitting) {
-				pr_warn("cec-%s: message %*ph timed out\n", adap->name,
-					adap->transmitting->msg.len,
-					adap->transmitting->msg.msg);
-				/* Just give up on this. */
-				cec_data_cancel(adap->transmitting,
-						CEC_TX_STATUS_TIMEOUT);
-			} else {
-				pr_warn("cec-%s: transmit timed out\n", adap->name);
-			}
-			adap->transmit_in_progress = false;
-			adap->tx_timeouts++;
-			goto unlock;
-		}
-
-		/*
-		 * If we are still transmitting, or there is nothing new to
-		 * transmit, then just continue waiting.
-		 */
-		if (adap->transmit_in_progress || list_empty(&adap->transmit_queue))
-			goto unlock;
-
-		/* Get a new message to transmit */
-		data = list_first_entry(&adap->transmit_queue,
-					struct cec_data, list);
-		list_del_init(&data->list);
-		if (!WARN_ON(!data->adap->transmit_queue_sz))
-			adap->transmit_queue_sz--;
-
-		/* Make this the current transmitting message */
-		adap->transmitting = data;
-
-		/*
-		 * Suggested number of attempts as per the CEC 2.0 spec:
-		 * 4 attempts is the default, except for 'secondary poll
-		 * messages', i.e. poll messages not sent during the adapter
-		 * configuration phase when it allocates logical addresses.
-		 */
-		if (data->msg.len == 1 && adap->is_configured)
-			attempts = 2;
-		else
-			attempts = 4;
-
-		/* Set the suggested signal free time */
-		if (data->attempts) {
-			/* should be >= 3 data bit periods for a retry */
-			signal_free_time = CEC_SIGNAL_FREE_TIME_RETRY;
-		} else if (adap->last_initiator !=
-			   cec_msg_initiator(&data->msg)) {
-			/* should be >= 5 data bit periods for new initiator */
-			signal_free_time = CEC_SIGNAL_FREE_TIME_NEW_INITIATOR;
-			adap->last_initiator = cec_msg_initiator(&data->msg);
-		} else {
-			/*
-			 * should be >= 7 data bit periods for sending another
-			 * frame immediately after another.
-			 */
-			signal_free_time = CEC_SIGNAL_FREE_TIME_NEXT_XFER;
-		}
-		if (data->attempts == 0)
-			data->attempts = attempts;
-
-		/* Tell the adapter to transmit, cancel on error */
-		if (adap->ops->adap_transmit(adap, data->attempts,
-					     signal_free_time, &data->msg))
-			cec_data_cancel(data, CEC_TX_STATUS_ABORTED);
-		else
-			adap->transmit_in_progress = true;
-
-unlock:
-		mutex_unlock(&adap->lock);
-
-		if (kthread_should_stop())
-			break;
-	}
-	return 0;
-}
-
-/*
- * Called by the CEC adapter if a transmit finished.
- */
-void cec_transmit_done_ts(struct cec_adapter *adap, u8 status,
-			  u8 arb_lost_cnt, u8 nack_cnt, u8 low_drive_cnt,
-			  u8 error_cnt, ktime_t ts)
-{
-	struct cec_data *data;
-	struct cec_msg *msg;
-	unsigned int attempts_made = arb_lost_cnt + nack_cnt +
-				     low_drive_cnt + error_cnt;
-
-	dprintk(2, "%s: status 0x%02x\n", __func__, status);
-	if (attempts_made < 1)
-		attempts_made = 1;
-
-	mutex_lock(&adap->lock);
-	data = adap->transmitting;
-	if (!data) {
-		/*
-		 * This might happen if a transmit was issued and the cable is
-		 * unplugged while the transmit is ongoing. Ignore this
-		 * transmit in that case.
-		 */
-		if (!adap->transmit_in_progress)
-			dprintk(1, "%s was called without an ongoing transmit!\n",
-				__func__);
-		adap->transmit_in_progress = false;
-		goto wake_thread;
-	}
-	adap->transmit_in_progress = false;
-
-	msg = &data->msg;
-
-	/* Drivers must fill in the status! */
-	WARN_ON(status == 0);
-	msg->tx_ts = ktime_to_ns(ts);
-	msg->tx_status |= status;
-	msg->tx_arb_lost_cnt += arb_lost_cnt;
-	msg->tx_nack_cnt += nack_cnt;
-	msg->tx_low_drive_cnt += low_drive_cnt;
-	msg->tx_error_cnt += error_cnt;
-
-	/* Mark that we're done with this transmit */
-	adap->transmitting = NULL;
-
-	/*
-	 * If there are still retry attempts left and there was an error and
-	 * the hardware didn't signal that it retried itself (by setting
-	 * CEC_TX_STATUS_MAX_RETRIES), then we will retry ourselves.
-	 */
-	if (data->attempts > attempts_made &&
-	    !(status & (CEC_TX_STATUS_MAX_RETRIES | CEC_TX_STATUS_OK))) {
-		/* Retry this message */
-		data->attempts -= attempts_made;
-		if (msg->timeout)
-			dprintk(2, "retransmit: %*ph (attempts: %d, wait for 0x%02x)\n",
-				msg->len, msg->msg, data->attempts, msg->reply);
-		else
-			dprintk(2, "retransmit: %*ph (attempts: %d)\n",
-				msg->len, msg->msg, data->attempts);
-		/* Add the message in front of the transmit queue */
-		list_add(&data->list, &adap->transmit_queue);
-		adap->transmit_queue_sz++;
-		goto wake_thread;
-	}
-
-	data->attempts = 0;
-
-	/* Always set CEC_TX_STATUS_MAX_RETRIES on error */
-	if (!(status & CEC_TX_STATUS_OK))
-		msg->tx_status |= CEC_TX_STATUS_MAX_RETRIES;
-
-	/* Queue transmitted message for monitoring purposes */
-	cec_queue_msg_monitor(adap, msg, 1);
-
-	if ((status & CEC_TX_STATUS_OK) && adap->is_configured &&
-	    msg->timeout) {
-		/*
-		 * Queue the message into the wait queue if we want to wait
-		 * for a reply.
-		 */
-		list_add_tail(&data->list, &adap->wait_queue);
-		schedule_delayed_work(&data->work,
-				      msecs_to_jiffies(msg->timeout));
-	} else {
-		/* Otherwise we're done */
-		cec_data_completed(data);
-	}
-
-wake_thread:
-	/*
-	 * Wake up the main thread to see if another message is ready
-	 * for transmitting or to retry the current message.
-	 */
-	wake_up_interruptible(&adap->kthread_waitq);
-	mutex_unlock(&adap->lock);
-}
-EXPORT_SYMBOL_GPL(cec_transmit_done_ts);
-
-void cec_transmit_attempt_done_ts(struct cec_adapter *adap,
-				  u8 status, ktime_t ts)
-{
-	switch (status & ~CEC_TX_STATUS_MAX_RETRIES) {
-	case CEC_TX_STATUS_OK:
-		cec_transmit_done_ts(adap, status, 0, 0, 0, 0, ts);
-		return;
-	case CEC_TX_STATUS_ARB_LOST:
-		cec_transmit_done_ts(adap, status, 1, 0, 0, 0, ts);
-		return;
-	case CEC_TX_STATUS_NACK:
-		cec_transmit_done_ts(adap, status, 0, 1, 0, 0, ts);
-		return;
-	case CEC_TX_STATUS_LOW_DRIVE:
-		cec_transmit_done_ts(adap, status, 0, 0, 1, 0, ts);
-		return;
-	case CEC_TX_STATUS_ERROR:
-		cec_transmit_done_ts(adap, status, 0, 0, 0, 1, ts);
-		return;
-	default:
-		/* Should never happen */
-		WARN(1, "cec-%s: invalid status 0x%02x\n", adap->name, status);
-		return;
-	}
-}
-EXPORT_SYMBOL_GPL(cec_transmit_attempt_done_ts);
-
-/*
- * Called when waiting for a reply times out.
- */
-static void cec_wait_timeout(struct work_struct *work)
-{
-	struct cec_data *data = container_of(work, struct cec_data, work.work);
-	struct cec_adapter *adap = data->adap;
-
-	mutex_lock(&adap->lock);
-	/*
-	 * Sanity check in case the timeout and the arrival of the message
-	 * happened at the same time.
-	 */
-	if (list_empty(&data->list))
-		goto unlock;
-
-	/* Mark the message as timed out */
-	list_del_init(&data->list);
-	data->msg.rx_ts = ktime_get_ns();
-	data->msg.rx_status = CEC_RX_STATUS_TIMEOUT;
-	cec_data_completed(data);
-unlock:
-	mutex_unlock(&adap->lock);
-}
-
-/*
- * Transmit a message. The fh argument may be NULL if the transmit is not
- * associated with a specific filehandle.
- *
- * This function is called with adap->lock held.
- */
-int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg,
-			struct cec_fh *fh, bool block)
-{
-	struct cec_data *data;
-	bool is_raw = msg_is_raw(msg);
-
-	msg->rx_ts = 0;
-	msg->tx_ts = 0;
-	msg->rx_status = 0;
-	msg->tx_status = 0;
-	msg->tx_arb_lost_cnt = 0;
-	msg->tx_nack_cnt = 0;
-	msg->tx_low_drive_cnt = 0;
-	msg->tx_error_cnt = 0;
-	msg->sequence = 0;
-
-	if (msg->reply && msg->timeout == 0) {
-		/* Make sure the timeout isn't 0. */
-		msg->timeout = 1000;
-	}
-	msg->flags &= CEC_MSG_FL_REPLY_TO_FOLLOWERS | CEC_MSG_FL_RAW;
-
-	if (!msg->timeout)
-		msg->flags &= ~CEC_MSG_FL_REPLY_TO_FOLLOWERS;
-
-	/* Sanity checks */
-	if (msg->len == 0 || msg->len > CEC_MAX_MSG_SIZE) {
-		dprintk(1, "%s: invalid length %d\n", __func__, msg->len);
-		return -EINVAL;
-	}
-
-	memset(msg->msg + msg->len, 0, sizeof(msg->msg) - msg->len);
-
-	if (msg->timeout)
-		dprintk(2, "%s: %*ph (wait for 0x%02x%s)\n",
-			__func__, msg->len, msg->msg, msg->reply,
-			!block ? ", nb" : "");
-	else
-		dprintk(2, "%s: %*ph%s\n",
-			__func__, msg->len, msg->msg, !block ? " (nb)" : "");
-
-	if (msg->timeout && msg->len == 1) {
-		dprintk(1, "%s: can't reply to poll msg\n", __func__);
-		return -EINVAL;
-	}
-
-	if (is_raw) {
-		if (!capable(CAP_SYS_RAWIO))
-			return -EPERM;
-	} else {
-		/* A CDC-Only device can only send CDC messages */
-		if ((adap->log_addrs.flags & CEC_LOG_ADDRS_FL_CDC_ONLY) &&
-		    (msg->len == 1 || msg->msg[1] != CEC_MSG_CDC_MESSAGE)) {
-			dprintk(1, "%s: not a CDC message\n", __func__);
-			return -EINVAL;
-		}
-
-		if (msg->len >= 4 && msg->msg[1] == CEC_MSG_CDC_MESSAGE) {
-			msg->msg[2] = adap->phys_addr >> 8;
-			msg->msg[3] = adap->phys_addr & 0xff;
-		}
-
-		if (msg->len == 1) {
-			if (cec_msg_destination(msg) == 0xf) {
-				dprintk(1, "%s: invalid poll message\n",
-					__func__);
-				return -EINVAL;
-			}
-			if (cec_has_log_addr(adap, cec_msg_destination(msg))) {
-				/*
-				 * If the destination is a logical address our
-				 * adapter has already claimed, then just NACK
-				 * this. It depends on the hardware what it will
-				 * do with a POLL to itself (some OK this), so
-				 * it is just as easy to handle it here so the
-				 * behavior will be consistent.
-				 */
-				msg->tx_ts = ktime_get_ns();
-				msg->tx_status = CEC_TX_STATUS_NACK |
-					CEC_TX_STATUS_MAX_RETRIES;
-				msg->tx_nack_cnt = 1;
-				msg->sequence = ++adap->sequence;
-				if (!msg->sequence)
-					msg->sequence = ++adap->sequence;
-				return 0;
-			}
-		}
-		if (msg->len > 1 && !cec_msg_is_broadcast(msg) &&
-		    cec_has_log_addr(adap, cec_msg_destination(msg))) {
-			dprintk(1, "%s: destination is the adapter itself\n",
-				__func__);
-			return -EINVAL;
-		}
-		if (msg->len > 1 && adap->is_configured &&
-		    !cec_has_log_addr(adap, cec_msg_initiator(msg))) {
-			dprintk(1, "%s: initiator has unknown logical address %d\n",
-				__func__, cec_msg_initiator(msg));
-			return -EINVAL;
-		}
-		/*
-		 * Special case: allow Ping and IMAGE/TEXT_VIEW_ON to be
-		 * transmitted to a TV, even if the adapter is unconfigured.
-		 * This makes it possible to detect or wake up displays that
-		 * pull down the HPD when in standby.
-		 */
-		if (!adap->is_configured && !adap->is_configuring &&
-		    (msg->len > 2 ||
-		     cec_msg_destination(msg) != CEC_LOG_ADDR_TV ||
-		     (msg->len == 2 && msg->msg[1] != CEC_MSG_IMAGE_VIEW_ON &&
-		      msg->msg[1] != CEC_MSG_TEXT_VIEW_ON))) {
-			dprintk(1, "%s: adapter is unconfigured\n", __func__);
-			return -ENONET;
-		}
-	}
-
-	if (!adap->is_configured && !adap->is_configuring) {
-		if (adap->needs_hpd) {
-			dprintk(1, "%s: adapter is unconfigured and needs HPD\n",
-				__func__);
-			return -ENONET;
-		}
-		if (msg->reply) {
-			dprintk(1, "%s: invalid msg->reply\n", __func__);
-			return -EINVAL;
-		}
-	}
-
-	if (adap->transmit_queue_sz >= CEC_MAX_MSG_TX_QUEUE_SZ) {
-		dprintk(2, "%s: transmit queue full\n", __func__);
-		return -EBUSY;
-	}
-
-	data = kzalloc(sizeof(*data), GFP_KERNEL);
-	if (!data)
-		return -ENOMEM;
-
-	msg->sequence = ++adap->sequence;
-	if (!msg->sequence)
-		msg->sequence = ++adap->sequence;
-
-	data->msg = *msg;
-	data->fh = fh;
-	data->adap = adap;
-	data->blocking = block;
-
-	init_completion(&data->c);
-	INIT_DELAYED_WORK(&data->work, cec_wait_timeout);
-
-	if (fh)
-		list_add_tail(&data->xfer_list, &fh->xfer_list);
-
-	list_add_tail(&data->list, &adap->transmit_queue);
-	adap->transmit_queue_sz++;
-	if (!adap->transmitting)
-		wake_up_interruptible(&adap->kthread_waitq);
-
-	/* All done if we don't need to block waiting for completion */
-	if (!block)
-		return 0;
-
-	/*
-	 * Release the lock and wait, retake the lock afterwards.
-	 */
-	mutex_unlock(&adap->lock);
-	wait_for_completion_killable(&data->c);
-	if (!data->completed)
-		cancel_delayed_work_sync(&data->work);
-	mutex_lock(&adap->lock);
-
-	/* Cancel the transmit if it was interrupted */
-	if (!data->completed)
-		cec_data_cancel(data, CEC_TX_STATUS_ABORTED);
-
-	/* The transmit completed (possibly with an error) */
-	*msg = data->msg;
-	kfree(data);
-	return 0;
-}
-
-/* Helper function to be used by drivers and this framework. */
-int cec_transmit_msg(struct cec_adapter *adap, struct cec_msg *msg,
-		     bool block)
-{
-	int ret;
-
-	mutex_lock(&adap->lock);
-	ret = cec_transmit_msg_fh(adap, msg, NULL, block);
-	mutex_unlock(&adap->lock);
-	return ret;
-}
-EXPORT_SYMBOL_GPL(cec_transmit_msg);
-
-/*
- * I don't like forward references but without this the low-level
- * cec_received_msg() function would come after a bunch of high-level
- * CEC protocol handling functions. That was very confusing.
- */
-static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg,
-			      bool is_reply);
-
-#define DIRECTED	0x80
-#define BCAST1_4	0x40
-#define BCAST2_0	0x20	/* broadcast only allowed for >= 2.0 */
-#define BCAST		(BCAST1_4 | BCAST2_0)
-#define BOTH		(BCAST | DIRECTED)
-
-/*
- * Specify minimum length and whether the message is directed, broadcast
- * or both. Messages that do not match the criteria are ignored as per
- * the CEC specification.
- */
-static const u8 cec_msg_size[256] = {
-	[CEC_MSG_ACTIVE_SOURCE] = 4 | BCAST,
-	[CEC_MSG_IMAGE_VIEW_ON] = 2 | DIRECTED,
-	[CEC_MSG_TEXT_VIEW_ON] = 2 | DIRECTED,
-	[CEC_MSG_INACTIVE_SOURCE] = 4 | DIRECTED,
-	[CEC_MSG_REQUEST_ACTIVE_SOURCE] = 2 | BCAST,
-	[CEC_MSG_ROUTING_CHANGE] = 6 | BCAST,
-	[CEC_MSG_ROUTING_INFORMATION] = 4 | BCAST,
-	[CEC_MSG_SET_STREAM_PATH] = 4 | BCAST,
-	[CEC_MSG_STANDBY] = 2 | BOTH,
-	[CEC_MSG_RECORD_OFF] = 2 | DIRECTED,
-	[CEC_MSG_RECORD_ON] = 3 | DIRECTED,
-	[CEC_MSG_RECORD_STATUS] = 3 | DIRECTED,
-	[CEC_MSG_RECORD_TV_SCREEN] = 2 | DIRECTED,
-	[CEC_MSG_CLEAR_ANALOGUE_TIMER] = 13 | DIRECTED,
-	[CEC_MSG_CLEAR_DIGITAL_TIMER] = 16 | DIRECTED,
-	[CEC_MSG_CLEAR_EXT_TIMER] = 13 | DIRECTED,
-	[CEC_MSG_SET_ANALOGUE_TIMER] = 13 | DIRECTED,
-	[CEC_MSG_SET_DIGITAL_TIMER] = 16 | DIRECTED,
-	[CEC_MSG_SET_EXT_TIMER] = 13 | DIRECTED,
-	[CEC_MSG_SET_TIMER_PROGRAM_TITLE] = 2 | DIRECTED,
-	[CEC_MSG_TIMER_CLEARED_STATUS] = 3 | DIRECTED,
-	[CEC_MSG_TIMER_STATUS] = 3 | DIRECTED,
-	[CEC_MSG_CEC_VERSION] = 3 | DIRECTED,
-	[CEC_MSG_GET_CEC_VERSION] = 2 | DIRECTED,
-	[CEC_MSG_GIVE_PHYSICAL_ADDR] = 2 | DIRECTED,
-	[CEC_MSG_GET_MENU_LANGUAGE] = 2 | DIRECTED,
-	[CEC_MSG_REPORT_PHYSICAL_ADDR] = 5 | BCAST,
-	[CEC_MSG_SET_MENU_LANGUAGE] = 5 | BCAST,
-	[CEC_MSG_REPORT_FEATURES] = 6 | BCAST,
-	[CEC_MSG_GIVE_FEATURES] = 2 | DIRECTED,
-	[CEC_MSG_DECK_CONTROL] = 3 | DIRECTED,
-	[CEC_MSG_DECK_STATUS] = 3 | DIRECTED,
-	[CEC_MSG_GIVE_DECK_STATUS] = 3 | DIRECTED,
-	[CEC_MSG_PLAY] = 3 | DIRECTED,
-	[CEC_MSG_GIVE_TUNER_DEVICE_STATUS] = 3 | DIRECTED,
-	[CEC_MSG_SELECT_ANALOGUE_SERVICE] = 6 | DIRECTED,
-	[CEC_MSG_SELECT_DIGITAL_SERVICE] = 9 | DIRECTED,
-	[CEC_MSG_TUNER_DEVICE_STATUS] = 7 | DIRECTED,
-	[CEC_MSG_TUNER_STEP_DECREMENT] = 2 | DIRECTED,
-	[CEC_MSG_TUNER_STEP_INCREMENT] = 2 | DIRECTED,
-	[CEC_MSG_DEVICE_VENDOR_ID] = 5 | BCAST,
-	[CEC_MSG_GIVE_DEVICE_VENDOR_ID] = 2 | DIRECTED,
-	[CEC_MSG_VENDOR_COMMAND] = 2 | DIRECTED,
-	[CEC_MSG_VENDOR_COMMAND_WITH_ID] = 5 | BOTH,
-	[CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN] = 2 | BOTH,
-	[CEC_MSG_VENDOR_REMOTE_BUTTON_UP] = 2 | BOTH,
-	[CEC_MSG_SET_OSD_STRING] = 3 | DIRECTED,
-	[CEC_MSG_GIVE_OSD_NAME] = 2 | DIRECTED,
-	[CEC_MSG_SET_OSD_NAME] = 2 | DIRECTED,
-	[CEC_MSG_MENU_REQUEST] = 3 | DIRECTED,
-	[CEC_MSG_MENU_STATUS] = 3 | DIRECTED,
-	[CEC_MSG_USER_CONTROL_PRESSED] = 3 | DIRECTED,
-	[CEC_MSG_USER_CONTROL_RELEASED] = 2 | DIRECTED,
-	[CEC_MSG_GIVE_DEVICE_POWER_STATUS] = 2 | DIRECTED,
-	[CEC_MSG_REPORT_POWER_STATUS] = 3 | DIRECTED | BCAST2_0,
-	[CEC_MSG_FEATURE_ABORT] = 4 | DIRECTED,
-	[CEC_MSG_ABORT] = 2 | DIRECTED,
-	[CEC_MSG_GIVE_AUDIO_STATUS] = 2 | DIRECTED,
-	[CEC_MSG_GIVE_SYSTEM_AUDIO_MODE_STATUS] = 2 | DIRECTED,
-	[CEC_MSG_REPORT_AUDIO_STATUS] = 3 | DIRECTED,
-	[CEC_MSG_REPORT_SHORT_AUDIO_DESCRIPTOR] = 2 | DIRECTED,
-	[CEC_MSG_REQUEST_SHORT_AUDIO_DESCRIPTOR] = 2 | DIRECTED,
-	[CEC_MSG_SET_SYSTEM_AUDIO_MODE] = 3 | BOTH,
-	[CEC_MSG_SYSTEM_AUDIO_MODE_REQUEST] = 2 | DIRECTED,
-	[CEC_MSG_SYSTEM_AUDIO_MODE_STATUS] = 3 | DIRECTED,
-	[CEC_MSG_SET_AUDIO_RATE] = 3 | DIRECTED,
-	[CEC_MSG_INITIATE_ARC] = 2 | DIRECTED,
-	[CEC_MSG_REPORT_ARC_INITIATED] = 2 | DIRECTED,
-	[CEC_MSG_REPORT_ARC_TERMINATED] = 2 | DIRECTED,
-	[CEC_MSG_REQUEST_ARC_INITIATION] = 2 | DIRECTED,
-	[CEC_MSG_REQUEST_ARC_TERMINATION] = 2 | DIRECTED,
-	[CEC_MSG_TERMINATE_ARC] = 2 | DIRECTED,
-	[CEC_MSG_REQUEST_CURRENT_LATENCY] = 4 | BCAST,
-	[CEC_MSG_REPORT_CURRENT_LATENCY] = 6 | BCAST,
-	[CEC_MSG_CDC_MESSAGE] = 2 | BCAST,
-};
-
-/* Called by the CEC adapter if a message is received */
-void cec_received_msg_ts(struct cec_adapter *adap,
-			 struct cec_msg *msg, ktime_t ts)
-{
-	struct cec_data *data;
-	u8 msg_init = cec_msg_initiator(msg);
-	u8 msg_dest = cec_msg_destination(msg);
-	u8 cmd = msg->msg[1];
-	bool is_reply = false;
-	bool valid_la = true;
-	u8 min_len = 0;
-
-	if (WARN_ON(!msg->len || msg->len > CEC_MAX_MSG_SIZE))
-		return;
-
-	/*
-	 * Some CEC adapters will receive the messages that they transmitted.
-	 * This test filters out those messages by checking if we are the
-	 * initiator, and just returning in that case.
-	 *
-	 * Note that this won't work if this is an Unregistered device.
-	 *
-	 * It is bad practice if the hardware receives the message that it
-	 * transmitted and luckily most CEC adapters behave correctly in this
-	 * respect.
-	 */
-	if (msg_init != CEC_LOG_ADDR_UNREGISTERED &&
-	    cec_has_log_addr(adap, msg_init))
-		return;
-
-	msg->rx_ts = ktime_to_ns(ts);
-	msg->rx_status = CEC_RX_STATUS_OK;
-	msg->sequence = msg->reply = msg->timeout = 0;
-	msg->tx_status = 0;
-	msg->tx_ts = 0;
-	msg->tx_arb_lost_cnt = 0;
-	msg->tx_nack_cnt = 0;
-	msg->tx_low_drive_cnt = 0;
-	msg->tx_error_cnt = 0;
-	msg->flags = 0;
-	memset(msg->msg + msg->len, 0, sizeof(msg->msg) - msg->len);
-
-	mutex_lock(&adap->lock);
-	dprintk(2, "%s: %*ph\n", __func__, msg->len, msg->msg);
-
-	adap->last_initiator = 0xff;
-
-	/* Check if this message was for us (directed or broadcast). */
-	if (!cec_msg_is_broadcast(msg))
-		valid_la = cec_has_log_addr(adap, msg_dest);
-
-	/*
-	 * Check if the length is not too short or if the message is a
-	 * broadcast message where a directed message was expected or
-	 * vice versa. If so, then the message has to be ignored (according
-	 * to section CEC 7.3 and CEC 12.2).
-	 */
-	if (valid_la && msg->len > 1 && cec_msg_size[cmd]) {
-		u8 dir_fl = cec_msg_size[cmd] & BOTH;
-
-		min_len = cec_msg_size[cmd] & 0x1f;
-		if (msg->len < min_len)
-			valid_la = false;
-		else if (!cec_msg_is_broadcast(msg) && !(dir_fl & DIRECTED))
-			valid_la = false;
-		else if (cec_msg_is_broadcast(msg) && !(dir_fl & BCAST))
-			valid_la = false;
-		else if (cec_msg_is_broadcast(msg) &&
-			 adap->log_addrs.cec_version < CEC_OP_CEC_VERSION_2_0 &&
-			 !(dir_fl & BCAST1_4))
-			valid_la = false;
-	}
-	if (valid_la && min_len) {
-		/* These messages have special length requirements */
-		switch (cmd) {
-		case CEC_MSG_TIMER_STATUS:
-			if (msg->msg[2] & 0x10) {
-				switch (msg->msg[2] & 0xf) {
-				case CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE:
-				case CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE:
-					if (msg->len < 5)
-						valid_la = false;
-					break;
-				}
-			} else if ((msg->msg[2] & 0xf) == CEC_OP_PROG_ERROR_DUPLICATE) {
-				if (msg->len < 5)
-					valid_la = false;
-			}
-			break;
-		case CEC_MSG_RECORD_ON:
-			switch (msg->msg[2]) {
-			case CEC_OP_RECORD_SRC_OWN:
-				break;
-			case CEC_OP_RECORD_SRC_DIGITAL:
-				if (msg->len < 10)
-					valid_la = false;
-				break;
-			case CEC_OP_RECORD_SRC_ANALOG:
-				if (msg->len < 7)
-					valid_la = false;
-				break;
-			case CEC_OP_RECORD_SRC_EXT_PLUG:
-				if (msg->len < 4)
-					valid_la = false;
-				break;
-			case CEC_OP_RECORD_SRC_EXT_PHYS_ADDR:
-				if (msg->len < 5)
-					valid_la = false;
-				break;
-			}
-			break;
-		}
-	}
-
-	/* It's a valid message and not a poll or CDC message */
-	if (valid_la && msg->len > 1 && cmd != CEC_MSG_CDC_MESSAGE) {
-		bool abort = cmd == CEC_MSG_FEATURE_ABORT;
-
-		/* The aborted command is in msg[2] */
-		if (abort)
-			cmd = msg->msg[2];
-
-		/*
-		 * Walk over all transmitted messages that are waiting for a
-		 * reply.
-		 */
-		list_for_each_entry(data, &adap->wait_queue, list) {
-			struct cec_msg *dst = &data->msg;
-
-			/*
-			 * The *only* CEC message that has two possible replies
-			 * is CEC_MSG_INITIATE_ARC.
-			 * In this case allow either of the two replies.
-			 */
-			if (!abort && dst->msg[1] == CEC_MSG_INITIATE_ARC &&
-			    (cmd == CEC_MSG_REPORT_ARC_INITIATED ||
-			     cmd == CEC_MSG_REPORT_ARC_TERMINATED) &&
-			    (dst->reply == CEC_MSG_REPORT_ARC_INITIATED ||
-			     dst->reply == CEC_MSG_REPORT_ARC_TERMINATED))
-				dst->reply = cmd;
-
-			/* Does the command match? */
-			if ((abort && cmd != dst->msg[1]) ||
-			    (!abort && cmd != dst->reply))
-				continue;
-
-			/* Does the addressing match? */
-			if (msg_init != cec_msg_destination(dst) &&
-			    !cec_msg_is_broadcast(dst))
-				continue;
-
-			/* We got a reply */
-			memcpy(dst->msg, msg->msg, msg->len);
-			dst->len = msg->len;
-			dst->rx_ts = msg->rx_ts;
-			dst->rx_status = msg->rx_status;
-			if (abort)
-				dst->rx_status |= CEC_RX_STATUS_FEATURE_ABORT;
-			msg->flags = dst->flags;
-			/* Remove it from the wait_queue */
-			list_del_init(&data->list);
-
-			/* Cancel the pending timeout work */
-			if (!cancel_delayed_work(&data->work)) {
-				mutex_unlock(&adap->lock);
-				flush_scheduled_work();
-				mutex_lock(&adap->lock);
-			}
-			/*
-			 * Mark this as a reply, provided someone is still
-			 * waiting for the answer.
-			 */
-			if (data->fh)
-				is_reply = true;
-			cec_data_completed(data);
-			break;
-		}
-	}
-	mutex_unlock(&adap->lock);
-
-	/* Pass the message on to any monitoring filehandles */
-	cec_queue_msg_monitor(adap, msg, valid_la);
-
-	/* We're done if it is not for us or a poll message */
-	if (!valid_la || msg->len <= 1)
-		return;
-
-	if (adap->log_addrs.log_addr_mask == 0)
-		return;
-
-	/*
-	 * Process the message on the protocol level. If is_reply is true,
-	 * then cec_receive_notify() won't pass on the reply to the listener(s)
-	 * since that was already done by cec_data_completed() above.
-	 */
-	cec_receive_notify(adap, msg, is_reply);
-}
-EXPORT_SYMBOL_GPL(cec_received_msg_ts);
-
-/* Logical Address Handling */
-
-/*
- * Attempt to claim a specific logical address.
- *
- * This function is called with adap->lock held.
- */
-static int cec_config_log_addr(struct cec_adapter *adap,
-			       unsigned int idx,
-			       unsigned int log_addr)
-{
-	struct cec_log_addrs *las = &adap->log_addrs;
-	struct cec_msg msg = { };
-	const unsigned int max_retries = 2;
-	unsigned int i;
-	int err;
-
-	if (cec_has_log_addr(adap, log_addr))
-		return 0;
-
-	/* Send poll message */
-	msg.len = 1;
-	msg.msg[0] = (log_addr << 4) | log_addr;
-
-	for (i = 0; i < max_retries; i++) {
-		err = cec_transmit_msg_fh(adap, &msg, NULL, true);
-
-		/*
-		 * While trying to poll the physical address was reset
-		 * and the adapter was unconfigured, so bail out.
-		 */
-		if (!adap->is_configuring)
-			return -EINTR;
-
-		if (err)
-			return err;
-
-		/*
-		 * The message was aborted due to a disconnect or
-		 * unconfigure, just bail out.
-		 */
-		if (msg.tx_status & CEC_TX_STATUS_ABORTED)
-			return -EINTR;
-		if (msg.tx_status & CEC_TX_STATUS_OK)
-			return 0;
-		if (msg.tx_status & CEC_TX_STATUS_NACK)
-			break;
-		/*
-		 * Retry up to max_retries times if the message was neither
-		 * OKed or NACKed. This can happen due to e.g. a Lost
-		 * Arbitration condition.
-		 */
-	}
-
-	/*
-	 * If we are unable to get an OK or a NACK after max_retries attempts
-	 * (and note that each attempt already consists of four polls), then
-	 * then we assume that something is really weird and that it is not a
-	 * good idea to try and claim this logical address.
-	 */
-	if (i == max_retries)
-		return 0;
-
-	/*
-	 * Message not acknowledged, so this logical
-	 * address is free to use.
-	 */
-	err = adap->ops->adap_log_addr(adap, log_addr);
-	if (err)
-		return err;
-
-	las->log_addr[idx] = log_addr;
-	las->log_addr_mask |= 1 << log_addr;
-	adap->phys_addrs[log_addr] = adap->phys_addr;
-	return 1;
-}
-
-/*
- * Unconfigure the adapter: clear all logical addresses and send
- * the state changed event.
- *
- * This function is called with adap->lock held.
- */
-static void cec_adap_unconfigure(struct cec_adapter *adap)
-{
-	if (!adap->needs_hpd ||
-	    adap->phys_addr != CEC_PHYS_ADDR_INVALID)
-		WARN_ON(adap->ops->adap_log_addr(adap, CEC_LOG_ADDR_INVALID));
-	adap->log_addrs.log_addr_mask = 0;
-	adap->is_configuring = false;
-	adap->is_configured = false;
-	memset(adap->phys_addrs, 0xff, sizeof(adap->phys_addrs));
-	cec_flush(adap);
-	wake_up_interruptible(&adap->kthread_waitq);
-	cec_post_state_event(adap);
-}
-
-/*
- * Attempt to claim the required logical addresses.
- */
-static int cec_config_thread_func(void *arg)
-{
-	/* The various LAs for each type of device */
-	static const u8 tv_log_addrs[] = {
-		CEC_LOG_ADDR_TV, CEC_LOG_ADDR_SPECIFIC,
-		CEC_LOG_ADDR_INVALID
-	};
-	static const u8 record_log_addrs[] = {
-		CEC_LOG_ADDR_RECORD_1, CEC_LOG_ADDR_RECORD_2,
-		CEC_LOG_ADDR_RECORD_3,
-		CEC_LOG_ADDR_BACKUP_1, CEC_LOG_ADDR_BACKUP_2,
-		CEC_LOG_ADDR_INVALID
-	};
-	static const u8 tuner_log_addrs[] = {
-		CEC_LOG_ADDR_TUNER_1, CEC_LOG_ADDR_TUNER_2,
-		CEC_LOG_ADDR_TUNER_3, CEC_LOG_ADDR_TUNER_4,
-		CEC_LOG_ADDR_BACKUP_1, CEC_LOG_ADDR_BACKUP_2,
-		CEC_LOG_ADDR_INVALID
-	};
-	static const u8 playback_log_addrs[] = {
-		CEC_LOG_ADDR_PLAYBACK_1, CEC_LOG_ADDR_PLAYBACK_2,
-		CEC_LOG_ADDR_PLAYBACK_3,
-		CEC_LOG_ADDR_BACKUP_1, CEC_LOG_ADDR_BACKUP_2,
-		CEC_LOG_ADDR_INVALID
-	};
-	static const u8 audiosystem_log_addrs[] = {
-		CEC_LOG_ADDR_AUDIOSYSTEM,
-		CEC_LOG_ADDR_INVALID
-	};
-	static const u8 specific_use_log_addrs[] = {
-		CEC_LOG_ADDR_SPECIFIC,
-		CEC_LOG_ADDR_BACKUP_1, CEC_LOG_ADDR_BACKUP_2,
-		CEC_LOG_ADDR_INVALID
-	};
-	static const u8 *type2addrs[6] = {
-		[CEC_LOG_ADDR_TYPE_TV] = tv_log_addrs,
-		[CEC_LOG_ADDR_TYPE_RECORD] = record_log_addrs,
-		[CEC_LOG_ADDR_TYPE_TUNER] = tuner_log_addrs,
-		[CEC_LOG_ADDR_TYPE_PLAYBACK] = playback_log_addrs,
-		[CEC_LOG_ADDR_TYPE_AUDIOSYSTEM] = audiosystem_log_addrs,
-		[CEC_LOG_ADDR_TYPE_SPECIFIC] = specific_use_log_addrs,
-	};
-	static const u16 type2mask[] = {
-		[CEC_LOG_ADDR_TYPE_TV] = CEC_LOG_ADDR_MASK_TV,
-		[CEC_LOG_ADDR_TYPE_RECORD] = CEC_LOG_ADDR_MASK_RECORD,
-		[CEC_LOG_ADDR_TYPE_TUNER] = CEC_LOG_ADDR_MASK_TUNER,
-		[CEC_LOG_ADDR_TYPE_PLAYBACK] = CEC_LOG_ADDR_MASK_PLAYBACK,
-		[CEC_LOG_ADDR_TYPE_AUDIOSYSTEM] = CEC_LOG_ADDR_MASK_AUDIOSYSTEM,
-		[CEC_LOG_ADDR_TYPE_SPECIFIC] = CEC_LOG_ADDR_MASK_SPECIFIC,
-	};
-	struct cec_adapter *adap = arg;
-	struct cec_log_addrs *las = &adap->log_addrs;
-	int err;
-	int i, j;
-
-	mutex_lock(&adap->lock);
-	dprintk(1, "physical address: %x.%x.%x.%x, claim %d logical addresses\n",
-		cec_phys_addr_exp(adap->phys_addr), las->num_log_addrs);
-	las->log_addr_mask = 0;
-
-	if (las->log_addr_type[0] == CEC_LOG_ADDR_TYPE_UNREGISTERED)
-		goto configured;
-
-	for (i = 0; i < las->num_log_addrs; i++) {
-		unsigned int type = las->log_addr_type[i];
-		const u8 *la_list;
-		u8 last_la;
-
-		/*
-		 * The TV functionality can only map to physical address 0.
-		 * For any other address, try the Specific functionality
-		 * instead as per the spec.
-		 */
-		if (adap->phys_addr && type == CEC_LOG_ADDR_TYPE_TV)
-			type = CEC_LOG_ADDR_TYPE_SPECIFIC;
-
-		la_list = type2addrs[type];
-		last_la = las->log_addr[i];
-		las->log_addr[i] = CEC_LOG_ADDR_INVALID;
-		if (last_la == CEC_LOG_ADDR_INVALID ||
-		    last_la == CEC_LOG_ADDR_UNREGISTERED ||
-		    !((1 << last_la) & type2mask[type]))
-			last_la = la_list[0];
-
-		err = cec_config_log_addr(adap, i, last_la);
-		if (err > 0) /* Reused last LA */
-			continue;
-
-		if (err < 0)
-			goto unconfigure;
-
-		for (j = 0; la_list[j] != CEC_LOG_ADDR_INVALID; j++) {
-			/* Tried this one already, skip it */
-			if (la_list[j] == last_la)
-				continue;
-			/* The backup addresses are CEC 2.0 specific */
-			if ((la_list[j] == CEC_LOG_ADDR_BACKUP_1 ||
-			     la_list[j] == CEC_LOG_ADDR_BACKUP_2) &&
-			    las->cec_version < CEC_OP_CEC_VERSION_2_0)
-				continue;
-
-			err = cec_config_log_addr(adap, i, la_list[j]);
-			if (err == 0) /* LA is in use */
-				continue;
-			if (err < 0)
-				goto unconfigure;
-			/* Done, claimed an LA */
-			break;
-		}
-
-		if (la_list[j] == CEC_LOG_ADDR_INVALID)
-			dprintk(1, "could not claim LA %d\n", i);
-	}
-
-	if (adap->log_addrs.log_addr_mask == 0 &&
-	    !(las->flags & CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK))
-		goto unconfigure;
-
-configured:
-	if (adap->log_addrs.log_addr_mask == 0) {
-		/* Fall back to unregistered */
-		las->log_addr[0] = CEC_LOG_ADDR_UNREGISTERED;
-		las->log_addr_mask = 1 << las->log_addr[0];
-		for (i = 1; i < las->num_log_addrs; i++)
-			las->log_addr[i] = CEC_LOG_ADDR_INVALID;
-	}
-	for (i = las->num_log_addrs; i < CEC_MAX_LOG_ADDRS; i++)
-		las->log_addr[i] = CEC_LOG_ADDR_INVALID;
-	adap->is_configured = true;
-	adap->is_configuring = false;
-	cec_post_state_event(adap);
-
-	/*
-	 * Now post the Report Features and Report Physical Address broadcast
-	 * messages. Note that these are non-blocking transmits, meaning that
-	 * they are just queued up and once adap->lock is unlocked the main
-	 * thread will kick in and start transmitting these.
-	 *
-	 * If after this function is done (but before one or more of these
-	 * messages are actually transmitted) the CEC adapter is unconfigured,
-	 * then any remaining messages will be dropped by the main thread.
-	 */
-	for (i = 0; i < las->num_log_addrs; i++) {
-		struct cec_msg msg = {};
-
-		if (las->log_addr[i] == CEC_LOG_ADDR_INVALID ||
-		    (las->flags & CEC_LOG_ADDRS_FL_CDC_ONLY))
-			continue;
-
-		msg.msg[0] = (las->log_addr[i] << 4) | 0x0f;
-
-		/* Report Features must come first according to CEC 2.0 */
-		if (las->log_addr[i] != CEC_LOG_ADDR_UNREGISTERED &&
-		    adap->log_addrs.cec_version >= CEC_OP_CEC_VERSION_2_0) {
-			cec_fill_msg_report_features(adap, &msg, i);
-			cec_transmit_msg_fh(adap, &msg, NULL, false);
-		}
-
-		/* Report Physical Address */
-		cec_msg_report_physical_addr(&msg, adap->phys_addr,
-					     las->primary_device_type[i]);
-		dprintk(1, "config: la %d pa %x.%x.%x.%x\n",
-			las->log_addr[i],
-			cec_phys_addr_exp(adap->phys_addr));
-		cec_transmit_msg_fh(adap, &msg, NULL, false);
-
-		/* Report Vendor ID */
-		if (adap->log_addrs.vendor_id != CEC_VENDOR_ID_NONE) {
-			cec_msg_device_vendor_id(&msg,
-						 adap->log_addrs.vendor_id);
-			cec_transmit_msg_fh(adap, &msg, NULL, false);
-		}
-	}
-	adap->kthread_config = NULL;
-	complete(&adap->config_completion);
-	mutex_unlock(&adap->lock);
-	return 0;
-
-unconfigure:
-	for (i = 0; i < las->num_log_addrs; i++)
-		las->log_addr[i] = CEC_LOG_ADDR_INVALID;
-	cec_adap_unconfigure(adap);
-	adap->kthread_config = NULL;
-	mutex_unlock(&adap->lock);
-	complete(&adap->config_completion);
-	return 0;
-}
-
-/*
- * Called from either __cec_s_phys_addr or __cec_s_log_addrs to claim the
- * logical addresses.
- *
- * This function is called with adap->lock held.
- */
-static void cec_claim_log_addrs(struct cec_adapter *adap, bool block)
-{
-	if (WARN_ON(adap->is_configuring || adap->is_configured))
-		return;
-
-	init_completion(&adap->config_completion);
-
-	/* Ready to kick off the thread */
-	adap->is_configuring = true;
-	adap->kthread_config = kthread_run(cec_config_thread_func, adap,
-					   "ceccfg-%s", adap->name);
-	if (IS_ERR(adap->kthread_config)) {
-		adap->kthread_config = NULL;
-	} else if (block) {
-		mutex_unlock(&adap->lock);
-		wait_for_completion(&adap->config_completion);
-		mutex_lock(&adap->lock);
-	}
-}
-
-/* Set a new physical address and send an event notifying userspace of this.
- *
- * This function is called with adap->lock held.
- */
-void __cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block)
-{
-	if (phys_addr == adap->phys_addr)
-		return;
-	if (phys_addr != CEC_PHYS_ADDR_INVALID && adap->devnode.unregistered)
-		return;
-
-	dprintk(1, "new physical address %x.%x.%x.%x\n",
-		cec_phys_addr_exp(phys_addr));
-	if (phys_addr == CEC_PHYS_ADDR_INVALID ||
-	    adap->phys_addr != CEC_PHYS_ADDR_INVALID) {
-		adap->phys_addr = CEC_PHYS_ADDR_INVALID;
-		cec_post_state_event(adap);
-		cec_adap_unconfigure(adap);
-		/* Disabling monitor all mode should always succeed */
-		if (adap->monitor_all_cnt)
-			WARN_ON(call_op(adap, adap_monitor_all_enable, false));
-		mutex_lock(&adap->devnode.lock);
-		if (adap->needs_hpd || list_empty(&adap->devnode.fhs)) {
-			WARN_ON(adap->ops->adap_enable(adap, false));
-			adap->transmit_in_progress = false;
-			wake_up_interruptible(&adap->kthread_waitq);
-		}
-		mutex_unlock(&adap->devnode.lock);
-		if (phys_addr == CEC_PHYS_ADDR_INVALID)
-			return;
-	}
-
-	mutex_lock(&adap->devnode.lock);
-	adap->last_initiator = 0xff;
-	adap->transmit_in_progress = false;
-
-	if ((adap->needs_hpd || list_empty(&adap->devnode.fhs)) &&
-	    adap->ops->adap_enable(adap, true)) {
-		mutex_unlock(&adap->devnode.lock);
-		return;
-	}
-
-	if (adap->monitor_all_cnt &&
-	    call_op(adap, adap_monitor_all_enable, true)) {
-		if (adap->needs_hpd || list_empty(&adap->devnode.fhs))
-			WARN_ON(adap->ops->adap_enable(adap, false));
-		mutex_unlock(&adap->devnode.lock);
-		return;
-	}
-	mutex_unlock(&adap->devnode.lock);
-
-	adap->phys_addr = phys_addr;
-	cec_post_state_event(adap);
-	if (adap->log_addrs.num_log_addrs)
-		cec_claim_log_addrs(adap, block);
-}
-
-void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block)
-{
-	if (IS_ERR_OR_NULL(adap))
-		return;
-
-	mutex_lock(&adap->lock);
-	__cec_s_phys_addr(adap, phys_addr, block);
-	mutex_unlock(&adap->lock);
-}
-EXPORT_SYMBOL_GPL(cec_s_phys_addr);
-
-void cec_s_phys_addr_from_edid(struct cec_adapter *adap,
-			       const struct edid *edid)
-{
-	u16 pa = CEC_PHYS_ADDR_INVALID;
-
-	if (edid && edid->extensions)
-		pa = cec_get_edid_phys_addr((const u8 *)edid,
-				EDID_LENGTH * (edid->extensions + 1), NULL);
-	cec_s_phys_addr(adap, pa, false);
-}
-EXPORT_SYMBOL_GPL(cec_s_phys_addr_from_edid);
-
-void cec_s_conn_info(struct cec_adapter *adap,
-		     const struct cec_connector_info *conn_info)
-{
-	if (IS_ERR_OR_NULL(adap))
-		return;
-
-	if (!(adap->capabilities & CEC_CAP_CONNECTOR_INFO))
-		return;
-
-	mutex_lock(&adap->lock);
-	if (conn_info)
-		adap->conn_info = *conn_info;
-	else
-		memset(&adap->conn_info, 0, sizeof(adap->conn_info));
-	cec_post_state_event(adap);
-	mutex_unlock(&adap->lock);
-}
-EXPORT_SYMBOL_GPL(cec_s_conn_info);
-
-/*
- * Called from either the ioctl or a driver to set the logical addresses.
- *
- * This function is called with adap->lock held.
- */
-int __cec_s_log_addrs(struct cec_adapter *adap,
-		      struct cec_log_addrs *log_addrs, bool block)
-{
-	u16 type_mask = 0;
-	int i;
-
-	if (adap->devnode.unregistered)
-		return -ENODEV;
-
-	if (!log_addrs || log_addrs->num_log_addrs == 0) {
-		cec_adap_unconfigure(adap);
-		adap->log_addrs.num_log_addrs = 0;
-		for (i = 0; i < CEC_MAX_LOG_ADDRS; i++)
-			adap->log_addrs.log_addr[i] = CEC_LOG_ADDR_INVALID;
-		adap->log_addrs.osd_name[0] = '\0';
-		adap->log_addrs.vendor_id = CEC_VENDOR_ID_NONE;
-		adap->log_addrs.cec_version = CEC_OP_CEC_VERSION_2_0;
-		return 0;
-	}
-
-	if (log_addrs->flags & CEC_LOG_ADDRS_FL_CDC_ONLY) {
-		/*
-		 * Sanitize log_addrs fields if a CDC-Only device is
-		 * requested.
-		 */
-		log_addrs->num_log_addrs = 1;
-		log_addrs->osd_name[0] = '\0';
-		log_addrs->vendor_id = CEC_VENDOR_ID_NONE;
-		log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_UNREGISTERED;
-		/*
-		 * This is just an internal convention since a CDC-Only device
-		 * doesn't have to be a switch. But switches already use
-		 * unregistered, so it makes some kind of sense to pick this
-		 * as the primary device. Since a CDC-Only device never sends
-		 * any 'normal' CEC messages this primary device type is never
-		 * sent over the CEC bus.
-		 */
-		log_addrs->primary_device_type[0] = CEC_OP_PRIM_DEVTYPE_SWITCH;
-		log_addrs->all_device_types[0] = 0;
-		log_addrs->features[0][0] = 0;
-		log_addrs->features[0][1] = 0;
-	}
-
-	/* Ensure the osd name is 0-terminated */
-	log_addrs->osd_name[sizeof(log_addrs->osd_name) - 1] = '\0';
-
-	/* Sanity checks */
-	if (log_addrs->num_log_addrs > adap->available_log_addrs) {
-		dprintk(1, "num_log_addrs > %d\n", adap->available_log_addrs);
-		return -EINVAL;
-	}
-
-	/*
-	 * Vendor ID is a 24 bit number, so check if the value is
-	 * within the correct range.
-	 */
-	if (log_addrs->vendor_id != CEC_VENDOR_ID_NONE &&
-	    (log_addrs->vendor_id & 0xff000000) != 0) {
-		dprintk(1, "invalid vendor ID\n");
-		return -EINVAL;
-	}
-
-	if (log_addrs->cec_version != CEC_OP_CEC_VERSION_1_4 &&
-	    log_addrs->cec_version != CEC_OP_CEC_VERSION_2_0) {
-		dprintk(1, "invalid CEC version\n");
-		return -EINVAL;
-	}
-
-	if (log_addrs->num_log_addrs > 1)
-		for (i = 0; i < log_addrs->num_log_addrs; i++)
-			if (log_addrs->log_addr_type[i] ==
-					CEC_LOG_ADDR_TYPE_UNREGISTERED) {
-				dprintk(1, "num_log_addrs > 1 can't be combined with unregistered LA\n");
-				return -EINVAL;
-			}
-
-	for (i = 0; i < log_addrs->num_log_addrs; i++) {
-		const u8 feature_sz = ARRAY_SIZE(log_addrs->features[0]);
-		u8 *features = log_addrs->features[i];
-		bool op_is_dev_features = false;
-		unsigned j;
-
-		log_addrs->log_addr[i] = CEC_LOG_ADDR_INVALID;
-		if (type_mask & (1 << log_addrs->log_addr_type[i])) {
-			dprintk(1, "duplicate logical address type\n");
-			return -EINVAL;
-		}
-		type_mask |= 1 << log_addrs->log_addr_type[i];
-		if ((type_mask & (1 << CEC_LOG_ADDR_TYPE_RECORD)) &&
-		    (type_mask & (1 << CEC_LOG_ADDR_TYPE_PLAYBACK))) {
-			/* Record already contains the playback functionality */
-			dprintk(1, "invalid record + playback combination\n");
-			return -EINVAL;
-		}
-		if (log_addrs->primary_device_type[i] >
-					CEC_OP_PRIM_DEVTYPE_PROCESSOR) {
-			dprintk(1, "unknown primary device type\n");
-			return -EINVAL;
-		}
-		if (log_addrs->primary_device_type[i] == 2) {
-			dprintk(1, "invalid primary device type\n");
-			return -EINVAL;
-		}
-		if (log_addrs->log_addr_type[i] > CEC_LOG_ADDR_TYPE_UNREGISTERED) {
-			dprintk(1, "unknown logical address type\n");
-			return -EINVAL;
-		}
-		for (j = 0; j < feature_sz; j++) {
-			if ((features[j] & 0x80) == 0) {
-				if (op_is_dev_features)
-					break;
-				op_is_dev_features = true;
-			}
-		}
-		if (!op_is_dev_features || j == feature_sz) {
-			dprintk(1, "malformed features\n");
-			return -EINVAL;
-		}
-		/* Zero unused part of the feature array */
-		memset(features + j + 1, 0, feature_sz - j - 1);
-	}
-
-	if (log_addrs->cec_version >= CEC_OP_CEC_VERSION_2_0) {
-		if (log_addrs->num_log_addrs > 2) {
-			dprintk(1, "CEC 2.0 allows no more than 2 logical addresses\n");
-			return -EINVAL;
-		}
-		if (log_addrs->num_log_addrs == 2) {
-			if (!(type_mask & ((1 << CEC_LOG_ADDR_TYPE_AUDIOSYSTEM) |
-					   (1 << CEC_LOG_ADDR_TYPE_TV)))) {
-				dprintk(1, "two LAs is only allowed for audiosystem and TV\n");
-				return -EINVAL;
-			}
-			if (!(type_mask & ((1 << CEC_LOG_ADDR_TYPE_PLAYBACK) |
-					   (1 << CEC_LOG_ADDR_TYPE_RECORD)))) {
-				dprintk(1, "an audiosystem/TV can only be combined with record or playback\n");
-				return -EINVAL;
-			}
-		}
-	}
-
-	/* Zero unused LAs */
-	for (i = log_addrs->num_log_addrs; i < CEC_MAX_LOG_ADDRS; i++) {
-		log_addrs->primary_device_type[i] = 0;
-		log_addrs->log_addr_type[i] = 0;
-		log_addrs->all_device_types[i] = 0;
-		memset(log_addrs->features[i], 0,
-		       sizeof(log_addrs->features[i]));
-	}
-
-	log_addrs->log_addr_mask = adap->log_addrs.log_addr_mask;
-	adap->log_addrs = *log_addrs;
-	if (adap->phys_addr != CEC_PHYS_ADDR_INVALID)
-		cec_claim_log_addrs(adap, block);
-	return 0;
-}
-
-int cec_s_log_addrs(struct cec_adapter *adap,
-		    struct cec_log_addrs *log_addrs, bool block)
-{
-	int err;
-
-	mutex_lock(&adap->lock);
-	err = __cec_s_log_addrs(adap, log_addrs, block);
-	mutex_unlock(&adap->lock);
-	return err;
-}
-EXPORT_SYMBOL_GPL(cec_s_log_addrs);
-
-/* High-level core CEC message handling */
-
-/* Fill in the Report Features message */
-static void cec_fill_msg_report_features(struct cec_adapter *adap,
-					 struct cec_msg *msg,
-					 unsigned int la_idx)
-{
-	const struct cec_log_addrs *las = &adap->log_addrs;
-	const u8 *features = las->features[la_idx];
-	bool op_is_dev_features = false;
-	unsigned int idx;
-
-	/* Report Features */
-	msg->msg[0] = (las->log_addr[la_idx] << 4) | 0x0f;
-	msg->len = 4;
-	msg->msg[1] = CEC_MSG_REPORT_FEATURES;
-	msg->msg[2] = adap->log_addrs.cec_version;
-	msg->msg[3] = las->all_device_types[la_idx];
-
-	/* Write RC Profiles first, then Device Features */
-	for (idx = 0; idx < ARRAY_SIZE(las->features[0]); idx++) {
-		msg->msg[msg->len++] = features[idx];
-		if ((features[idx] & CEC_OP_FEAT_EXT) == 0) {
-			if (op_is_dev_features)
-				break;
-			op_is_dev_features = true;
-		}
-	}
-}
-
-/* Transmit the Feature Abort message */
-static int cec_feature_abort_reason(struct cec_adapter *adap,
-				    struct cec_msg *msg, u8 reason)
-{
-	struct cec_msg tx_msg = { };
-
-	/*
-	 * Don't reply with CEC_MSG_FEATURE_ABORT to a CEC_MSG_FEATURE_ABORT
-	 * message!
-	 */
-	if (msg->msg[1] == CEC_MSG_FEATURE_ABORT)
-		return 0;
-	/* Don't Feature Abort messages from 'Unregistered' */
-	if (cec_msg_initiator(msg) == CEC_LOG_ADDR_UNREGISTERED)
-		return 0;
-	cec_msg_set_reply_to(&tx_msg, msg);
-	cec_msg_feature_abort(&tx_msg, msg->msg[1], reason);
-	return cec_transmit_msg(adap, &tx_msg, false);
-}
-
-static int cec_feature_abort(struct cec_adapter *adap, struct cec_msg *msg)
-{
-	return cec_feature_abort_reason(adap, msg,
-					CEC_OP_ABORT_UNRECOGNIZED_OP);
-}
-
-static int cec_feature_refused(struct cec_adapter *adap, struct cec_msg *msg)
-{
-	return cec_feature_abort_reason(adap, msg,
-					CEC_OP_ABORT_REFUSED);
-}
-
-/*
- * Called when a CEC message is received. This function will do any
- * necessary core processing. The is_reply bool is true if this message
- * is a reply to an earlier transmit.
- *
- * The message is either a broadcast message or a valid directed message.
- */
-static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg,
-			      bool is_reply)
-{
-	bool is_broadcast = cec_msg_is_broadcast(msg);
-	u8 dest_laddr = cec_msg_destination(msg);
-	u8 init_laddr = cec_msg_initiator(msg);
-	u8 devtype = cec_log_addr2dev(adap, dest_laddr);
-	int la_idx = cec_log_addr2idx(adap, dest_laddr);
-	bool from_unregistered = init_laddr == 0xf;
-	struct cec_msg tx_cec_msg = { };
-
-	dprintk(2, "%s: %*ph\n", __func__, msg->len, msg->msg);
-
-	/* If this is a CDC-Only device, then ignore any non-CDC messages */
-	if (cec_is_cdc_only(&adap->log_addrs) &&
-	    msg->msg[1] != CEC_MSG_CDC_MESSAGE)
-		return 0;
-
-	if (adap->ops->received) {
-		/* Allow drivers to process the message first */
-		if (adap->ops->received(adap, msg) != -ENOMSG)
-			return 0;
-	}
-
-	/*
-	 * REPORT_PHYSICAL_ADDR, CEC_MSG_USER_CONTROL_PRESSED and
-	 * CEC_MSG_USER_CONTROL_RELEASED messages always have to be
-	 * handled by the CEC core, even if the passthrough mode is on.
-	 * The others are just ignored if passthrough mode is on.
-	 */
-	switch (msg->msg[1]) {
-	case CEC_MSG_GET_CEC_VERSION:
-	case CEC_MSG_ABORT:
-	case CEC_MSG_GIVE_DEVICE_POWER_STATUS:
-	case CEC_MSG_GIVE_OSD_NAME:
-		/*
-		 * These messages reply with a directed message, so ignore if
-		 * the initiator is Unregistered.
-		 */
-		if (!adap->passthrough && from_unregistered)
-			return 0;
-		/* Fall through */
-	case CEC_MSG_GIVE_DEVICE_VENDOR_ID:
-	case CEC_MSG_GIVE_FEATURES:
-	case CEC_MSG_GIVE_PHYSICAL_ADDR:
-		/*
-		 * Skip processing these messages if the passthrough mode
-		 * is on.
-		 */
-		if (adap->passthrough)
-			goto skip_processing;
-		/* Ignore if addressing is wrong */
-		if (is_broadcast)
-			return 0;
-		break;
-
-	case CEC_MSG_USER_CONTROL_PRESSED:
-	case CEC_MSG_USER_CONTROL_RELEASED:
-		/* Wrong addressing mode: don't process */
-		if (is_broadcast || from_unregistered)
-			goto skip_processing;
-		break;
-
-	case CEC_MSG_REPORT_PHYSICAL_ADDR:
-		/*
-		 * This message is always processed, regardless of the
-		 * passthrough setting.
-		 *
-		 * Exception: don't process if wrong addressing mode.
-		 */
-		if (!is_broadcast)
-			goto skip_processing;
-		break;
-
-	default:
-		break;
-	}
-
-	cec_msg_set_reply_to(&tx_cec_msg, msg);
-
-	switch (msg->msg[1]) {
-	/* The following messages are processed but still passed through */
-	case CEC_MSG_REPORT_PHYSICAL_ADDR: {
-		u16 pa = (msg->msg[2] << 8) | msg->msg[3];
-
-		if (!from_unregistered)
-			adap->phys_addrs[init_laddr] = pa;
-		dprintk(1, "reported physical address %x.%x.%x.%x for logical address %d\n",
-			cec_phys_addr_exp(pa), init_laddr);
-		break;
-	}
-
-	case CEC_MSG_USER_CONTROL_PRESSED:
-		if (!(adap->capabilities & CEC_CAP_RC) ||
-		    !(adap->log_addrs.flags & CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU))
-			break;
-
-#ifdef CONFIG_MEDIA_CEC_RC
-		switch (msg->msg[2]) {
-		/*
-		 * Play function, this message can have variable length
-		 * depending on the specific play function that is used.
-		 */
-		case CEC_OP_UI_CMD_PLAY_FUNCTION:
-			if (msg->len == 2)
-				rc_keydown(adap->rc, RC_PROTO_CEC,
-					   msg->msg[2], 0);
-			else
-				rc_keydown(adap->rc, RC_PROTO_CEC,
-					   msg->msg[2] << 8 | msg->msg[3], 0);
-			break;
-		/*
-		 * Other function messages that are not handled.
-		 * Currently the RC framework does not allow to supply an
-		 * additional parameter to a keypress. These "keys" contain
-		 * other information such as channel number, an input number
-		 * etc.
-		 * For the time being these messages are not processed by the
-		 * framework and are simply forwarded to the user space.
-		 */
-		case CEC_OP_UI_CMD_SELECT_BROADCAST_TYPE:
-		case CEC_OP_UI_CMD_SELECT_SOUND_PRESENTATION:
-		case CEC_OP_UI_CMD_TUNE_FUNCTION:
-		case CEC_OP_UI_CMD_SELECT_MEDIA_FUNCTION:
-		case CEC_OP_UI_CMD_SELECT_AV_INPUT_FUNCTION:
-		case CEC_OP_UI_CMD_SELECT_AUDIO_INPUT_FUNCTION:
-			break;
-		default:
-			rc_keydown(adap->rc, RC_PROTO_CEC, msg->msg[2], 0);
-			break;
-		}
-#endif
-		break;
-
-	case CEC_MSG_USER_CONTROL_RELEASED:
-		if (!(adap->capabilities & CEC_CAP_RC) ||
-		    !(adap->log_addrs.flags & CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU))
-			break;
-#ifdef CONFIG_MEDIA_CEC_RC
-		rc_keyup(adap->rc);
-#endif
-		break;
-
-	/*
-	 * The remaining messages are only processed if the passthrough mode
-	 * is off.
-	 */
-	case CEC_MSG_GET_CEC_VERSION:
-		cec_msg_cec_version(&tx_cec_msg, adap->log_addrs.cec_version);
-		return cec_transmit_msg(adap, &tx_cec_msg, false);
-
-	case CEC_MSG_GIVE_PHYSICAL_ADDR:
-		/* Do nothing for CEC switches using addr 15 */
-		if (devtype == CEC_OP_PRIM_DEVTYPE_SWITCH && dest_laddr == 15)
-			return 0;
-		cec_msg_report_physical_addr(&tx_cec_msg, adap->phys_addr, devtype);
-		return cec_transmit_msg(adap, &tx_cec_msg, false);
-
-	case CEC_MSG_GIVE_DEVICE_VENDOR_ID:
-		if (adap->log_addrs.vendor_id == CEC_VENDOR_ID_NONE)
-			return cec_feature_abort(adap, msg);
-		cec_msg_device_vendor_id(&tx_cec_msg, adap->log_addrs.vendor_id);
-		return cec_transmit_msg(adap, &tx_cec_msg, false);
-
-	case CEC_MSG_ABORT:
-		/* Do nothing for CEC switches */
-		if (devtype == CEC_OP_PRIM_DEVTYPE_SWITCH)
-			return 0;
-		return cec_feature_refused(adap, msg);
-
-	case CEC_MSG_GIVE_OSD_NAME: {
-		if (adap->log_addrs.osd_name[0] == 0)
-			return cec_feature_abort(adap, msg);
-		cec_msg_set_osd_name(&tx_cec_msg, adap->log_addrs.osd_name);
-		return cec_transmit_msg(adap, &tx_cec_msg, false);
-	}
-
-	case CEC_MSG_GIVE_FEATURES:
-		if (adap->log_addrs.cec_version < CEC_OP_CEC_VERSION_2_0)
-			return cec_feature_abort(adap, msg);
-		cec_fill_msg_report_features(adap, &tx_cec_msg, la_idx);
-		return cec_transmit_msg(adap, &tx_cec_msg, false);
-
-	default:
-		/*
-		 * Unprocessed messages are aborted if userspace isn't doing
-		 * any processing either.
-		 */
-		if (!is_broadcast && !is_reply && !adap->follower_cnt &&
-		    !adap->cec_follower && msg->msg[1] != CEC_MSG_FEATURE_ABORT)
-			return cec_feature_abort(adap, msg);
-		break;
-	}
-
-skip_processing:
-	/* If this was a reply, then we're done, unless otherwise specified */
-	if (is_reply && !(msg->flags & CEC_MSG_FL_REPLY_TO_FOLLOWERS))
-		return 0;
-
-	/*
-	 * Send to the exclusive follower if there is one, otherwise send
-	 * to all followers.
-	 */
-	if (adap->cec_follower)
-		cec_queue_msg_fh(adap->cec_follower, msg);
-	else
-		cec_queue_msg_followers(adap, msg);
-	return 0;
-}
-
-/*
- * Helper functions to keep track of the 'monitor all' use count.
- *
- * These functions are called with adap->lock held.
- */
-int cec_monitor_all_cnt_inc(struct cec_adapter *adap)
-{
-	int ret = 0;
-
-	if (adap->monitor_all_cnt == 0)
-		ret = call_op(adap, adap_monitor_all_enable, 1);
-	if (ret == 0)
-		adap->monitor_all_cnt++;
-	return ret;
-}
-
-void cec_monitor_all_cnt_dec(struct cec_adapter *adap)
-{
-	adap->monitor_all_cnt--;
-	if (adap->monitor_all_cnt == 0)
-		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.
- * Very useful for debugging.
- */
-int cec_adap_status(struct seq_file *file, void *priv)
-{
-	struct cec_adapter *adap = dev_get_drvdata(file->private);
-	struct cec_data *data;
-
-	mutex_lock(&adap->lock);
-	seq_printf(file, "configured: %d\n", adap->is_configured);
-	seq_printf(file, "configuring: %d\n", adap->is_configuring);
-	seq_printf(file, "phys_addr: %x.%x.%x.%x\n",
-		   cec_phys_addr_exp(adap->phys_addr));
-	seq_printf(file, "number of LAs: %d\n", adap->log_addrs.num_log_addrs);
-	seq_printf(file, "LA mask: 0x%04x\n", adap->log_addrs.log_addr_mask);
-	if (adap->cec_follower)
-		seq_printf(file, "has CEC follower%s\n",
-			   adap->passthrough ? " (in passthrough mode)" : "");
-	if (adap->cec_initiator)
-		seq_puts(file, "has CEC initiator\n");
-	if (adap->monitor_all_cnt)
-		seq_printf(file, "file handles in Monitor All mode: %u\n",
-			   adap->monitor_all_cnt);
-	if (adap->tx_timeouts) {
-		seq_printf(file, "transmit timeouts: %u\n",
-			   adap->tx_timeouts);
-		adap->tx_timeouts = 0;
-	}
-	data = adap->transmitting;
-	if (data)
-		seq_printf(file, "transmitting message: %*ph (reply: %02x, timeout: %ums)\n",
-			   data->msg.len, data->msg.msg, data->msg.reply,
-			   data->msg.timeout);
-	seq_printf(file, "pending transmits: %u\n", adap->transmit_queue_sz);
-	list_for_each_entry(data, &adap->transmit_queue, list) {
-		seq_printf(file, "queued tx message: %*ph (reply: %02x, timeout: %ums)\n",
-			   data->msg.len, data->msg.msg, data->msg.reply,
-			   data->msg.timeout);
-	}
-	list_for_each_entry(data, &adap->wait_queue, list) {
-		seq_printf(file, "message waiting for reply: %*ph (reply: %02x, timeout: %ums)\n",
-			   data->msg.len, data->msg.msg, data->msg.reply,
-			   data->msg.timeout);
-	}
-
-	call_void_op(adap, adap_status, file);
-	mutex_unlock(&adap->lock);
-	return 0;
-}
-#endif
diff --git a/drivers/media/cec/cec-api.c b/drivers/media/cec/cec-api.c
deleted file mode 100644
index 17d1cb2e5f97..000000000000
--- a/drivers/media/cec/cec-api.c
+++ /dev/null
@@ -1,701 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * cec-api.c - HDMI Consumer Electronics Control framework - API
- *
- * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/kmod.h>
-#include <linux/ktime.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/uaccess.h>
-#include <linux/version.h>
-
-#include <media/cec-pin.h>
-#include "cec-priv.h"
-#include "cec-pin-priv.h"
-
-static inline struct cec_devnode *cec_devnode_data(struct file *filp)
-{
-	struct cec_fh *fh = filp->private_data;
-
-	return &fh->adap->devnode;
-}
-
-/* CEC file operations */
-
-static __poll_t cec_poll(struct file *filp,
-			     struct poll_table_struct *poll)
-{
-	struct cec_fh *fh = filp->private_data;
-	struct cec_adapter *adap = fh->adap;
-	__poll_t res = 0;
-
-	poll_wait(filp, &fh->wait, poll);
-	if (!cec_is_registered(adap))
-		return EPOLLERR | EPOLLHUP;
-	mutex_lock(&adap->lock);
-	if (adap->is_configured &&
-	    adap->transmit_queue_sz < CEC_MAX_MSG_TX_QUEUE_SZ)
-		res |= EPOLLOUT | EPOLLWRNORM;
-	if (fh->queued_msgs)
-		res |= EPOLLIN | EPOLLRDNORM;
-	if (fh->total_queued_events)
-		res |= EPOLLPRI;
-	mutex_unlock(&adap->lock);
-	return res;
-}
-
-static bool cec_is_busy(const struct cec_adapter *adap,
-			const struct cec_fh *fh)
-{
-	bool valid_initiator = adap->cec_initiator && adap->cec_initiator == fh;
-	bool valid_follower = adap->cec_follower && adap->cec_follower == fh;
-
-	/*
-	 * Exclusive initiators and followers can always access the CEC adapter
-	 */
-	if (valid_initiator || valid_follower)
-		return false;
-	/*
-	 * All others can only access the CEC adapter if there is no
-	 * exclusive initiator and they are in INITIATOR mode.
-	 */
-	return adap->cec_initiator ||
-	       fh->mode_initiator == CEC_MODE_NO_INITIATOR;
-}
-
-static long cec_adap_g_caps(struct cec_adapter *adap,
-			    struct cec_caps __user *parg)
-{
-	struct cec_caps caps = {};
-
-	strscpy(caps.driver, adap->devnode.dev.parent->driver->name,
-		sizeof(caps.driver));
-	strscpy(caps.name, adap->name, sizeof(caps.name));
-	caps.available_log_addrs = adap->available_log_addrs;
-	caps.capabilities = adap->capabilities;
-	caps.version = LINUX_VERSION_CODE;
-	if (copy_to_user(parg, &caps, sizeof(caps)))
-		return -EFAULT;
-	return 0;
-}
-
-static long cec_adap_g_phys_addr(struct cec_adapter *adap,
-				 __u16 __user *parg)
-{
-	u16 phys_addr;
-
-	mutex_lock(&adap->lock);
-	phys_addr = adap->phys_addr;
-	mutex_unlock(&adap->lock);
-	if (copy_to_user(parg, &phys_addr, sizeof(phys_addr)))
-		return -EFAULT;
-	return 0;
-}
-
-static int cec_validate_phys_addr(u16 phys_addr)
-{
-	int i;
-
-	if (phys_addr == CEC_PHYS_ADDR_INVALID)
-		return 0;
-	for (i = 0; i < 16; i += 4)
-		if (phys_addr & (0xf << i))
-			break;
-	if (i == 16)
-		return 0;
-	for (i += 4; i < 16; i += 4)
-		if ((phys_addr & (0xf << i)) == 0)
-			return -EINVAL;
-	return 0;
-}
-
-static long cec_adap_s_phys_addr(struct cec_adapter *adap, struct cec_fh *fh,
-				 bool block, __u16 __user *parg)
-{
-	u16 phys_addr;
-	long err;
-
-	if (!(adap->capabilities & CEC_CAP_PHYS_ADDR))
-		return -ENOTTY;
-	if (copy_from_user(&phys_addr, parg, sizeof(phys_addr)))
-		return -EFAULT;
-
-	err = cec_validate_phys_addr(phys_addr);
-	if (err)
-		return err;
-	mutex_lock(&adap->lock);
-	if (cec_is_busy(adap, fh))
-		err = -EBUSY;
-	else
-		__cec_s_phys_addr(adap, phys_addr, block);
-	mutex_unlock(&adap->lock);
-	return err;
-}
-
-static long cec_adap_g_log_addrs(struct cec_adapter *adap,
-				 struct cec_log_addrs __user *parg)
-{
-	struct cec_log_addrs log_addrs;
-
-	mutex_lock(&adap->lock);
-	log_addrs = adap->log_addrs;
-	if (!adap->is_configured)
-		memset(log_addrs.log_addr, CEC_LOG_ADDR_INVALID,
-		       sizeof(log_addrs.log_addr));
-	mutex_unlock(&adap->lock);
-
-	if (copy_to_user(parg, &log_addrs, sizeof(log_addrs)))
-		return -EFAULT;
-	return 0;
-}
-
-static long cec_adap_s_log_addrs(struct cec_adapter *adap, struct cec_fh *fh,
-				 bool block, struct cec_log_addrs __user *parg)
-{
-	struct cec_log_addrs log_addrs;
-	long err = -EBUSY;
-
-	if (!(adap->capabilities & CEC_CAP_LOG_ADDRS))
-		return -ENOTTY;
-	if (copy_from_user(&log_addrs, parg, sizeof(log_addrs)))
-		return -EFAULT;
-	log_addrs.flags &= CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK |
-			   CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU |
-			   CEC_LOG_ADDRS_FL_CDC_ONLY;
-	mutex_lock(&adap->lock);
-	if (!adap->is_configuring &&
-	    (!log_addrs.num_log_addrs || !adap->is_configured) &&
-	    !cec_is_busy(adap, fh)) {
-		err = __cec_s_log_addrs(adap, &log_addrs, block);
-		if (!err)
-			log_addrs = adap->log_addrs;
-	}
-	mutex_unlock(&adap->lock);
-	if (err)
-		return err;
-	if (copy_to_user(parg, &log_addrs, sizeof(log_addrs)))
-		return -EFAULT;
-	return 0;
-}
-
-static long cec_adap_g_connector_info(struct cec_adapter *adap,
-				      struct cec_log_addrs __user *parg)
-{
-	int ret = 0;
-
-	if (!(adap->capabilities & CEC_CAP_CONNECTOR_INFO))
-		return -ENOTTY;
-
-	mutex_lock(&adap->lock);
-	if (copy_to_user(parg, &adap->conn_info, sizeof(adap->conn_info)))
-		ret = -EFAULT;
-	mutex_unlock(&adap->lock);
-	return ret;
-}
-
-static long cec_transmit(struct cec_adapter *adap, struct cec_fh *fh,
-			 bool block, struct cec_msg __user *parg)
-{
-	struct cec_msg msg = {};
-	long err = 0;
-
-	if (!(adap->capabilities & CEC_CAP_TRANSMIT))
-		return -ENOTTY;
-	if (copy_from_user(&msg, parg, sizeof(msg)))
-		return -EFAULT;
-
-	mutex_lock(&adap->lock);
-	if (adap->log_addrs.num_log_addrs == 0)
-		err = -EPERM;
-	else if (adap->is_configuring)
-		err = -ENONET;
-	else if (cec_is_busy(adap, fh))
-		err = -EBUSY;
-	else
-		err = cec_transmit_msg_fh(adap, &msg, fh, block);
-	mutex_unlock(&adap->lock);
-	if (err)
-		return err;
-	if (copy_to_user(parg, &msg, sizeof(msg)))
-		return -EFAULT;
-	return 0;
-}
-
-/* Called by CEC_RECEIVE: wait for a message to arrive */
-static int cec_receive_msg(struct cec_fh *fh, struct cec_msg *msg, bool block)
-{
-	u32 timeout = msg->timeout;
-	int res;
-
-	do {
-		mutex_lock(&fh->lock);
-		/* Are there received messages queued up? */
-		if (fh->queued_msgs) {
-			/* Yes, return the first one */
-			struct cec_msg_entry *entry =
-				list_first_entry(&fh->msgs,
-						 struct cec_msg_entry, list);
-
-			list_del(&entry->list);
-			*msg = entry->msg;
-			kfree(entry);
-			fh->queued_msgs--;
-			mutex_unlock(&fh->lock);
-			/* restore original timeout value */
-			msg->timeout = timeout;
-			return 0;
-		}
-
-		/* No, return EAGAIN in non-blocking mode or wait */
-		mutex_unlock(&fh->lock);
-
-		/* Return when in non-blocking mode */
-		if (!block)
-			return -EAGAIN;
-
-		if (msg->timeout) {
-			/* The user specified a timeout */
-			res = wait_event_interruptible_timeout(fh->wait,
-							       fh->queued_msgs,
-				msecs_to_jiffies(msg->timeout));
-			if (res == 0)
-				res = -ETIMEDOUT;
-			else if (res > 0)
-				res = 0;
-		} else {
-			/* Wait indefinitely */
-			res = wait_event_interruptible(fh->wait,
-						       fh->queued_msgs);
-		}
-		/* Exit on error, otherwise loop to get the new message */
-	} while (!res);
-	return res;
-}
-
-static long cec_receive(struct cec_adapter *adap, struct cec_fh *fh,
-			bool block, struct cec_msg __user *parg)
-{
-	struct cec_msg msg = {};
-	long err;
-
-	if (copy_from_user(&msg, parg, sizeof(msg)))
-		return -EFAULT;
-
-	err = cec_receive_msg(fh, &msg, block);
-	if (err)
-		return err;
-	msg.flags = 0;
-	if (copy_to_user(parg, &msg, sizeof(msg)))
-		return -EFAULT;
-	return 0;
-}
-
-static long cec_dqevent(struct cec_adapter *adap, struct cec_fh *fh,
-			bool block, struct cec_event __user *parg)
-{
-	struct cec_event_entry *ev = NULL;
-	u64 ts = ~0ULL;
-	unsigned int i;
-	unsigned int ev_idx;
-	long err = 0;
-
-	mutex_lock(&fh->lock);
-	while (!fh->total_queued_events && block) {
-		mutex_unlock(&fh->lock);
-		err = wait_event_interruptible(fh->wait,
-					       fh->total_queued_events);
-		if (err)
-			return err;
-		mutex_lock(&fh->lock);
-	}
-
-	/* Find the oldest event */
-	for (i = 0; i < CEC_NUM_EVENTS; i++) {
-		struct cec_event_entry *entry =
-			list_first_entry_or_null(&fh->events[i],
-						 struct cec_event_entry, list);
-
-		if (entry && entry->ev.ts <= ts) {
-			ev = entry;
-			ev_idx = i;
-			ts = ev->ev.ts;
-		}
-	}
-
-	if (!ev) {
-		err = -EAGAIN;
-		goto unlock;
-	}
-	list_del(&ev->list);
-
-	if (copy_to_user(parg, &ev->ev, sizeof(ev->ev)))
-		err = -EFAULT;
-	if (ev_idx >= CEC_NUM_CORE_EVENTS)
-		kfree(ev);
-	fh->queued_events[ev_idx]--;
-	fh->total_queued_events--;
-
-unlock:
-	mutex_unlock(&fh->lock);
-	return err;
-}
-
-static long cec_g_mode(struct cec_adapter *adap, struct cec_fh *fh,
-		       u32 __user *parg)
-{
-	u32 mode = fh->mode_initiator | fh->mode_follower;
-
-	if (copy_to_user(parg, &mode, sizeof(mode)))
-		return -EFAULT;
-	return 0;
-}
-
-static long cec_s_mode(struct cec_adapter *adap, struct cec_fh *fh,
-		       u32 __user *parg)
-{
-	u32 mode;
-	u8 mode_initiator;
-	u8 mode_follower;
-	bool send_pin_event = false;
-	long err = 0;
-
-	if (copy_from_user(&mode, parg, sizeof(mode)))
-		return -EFAULT;
-	if (mode & ~(CEC_MODE_INITIATOR_MSK | CEC_MODE_FOLLOWER_MSK)) {
-		dprintk(1, "%s: invalid mode bits set\n", __func__);
-		return -EINVAL;
-	}
-
-	mode_initiator = mode & CEC_MODE_INITIATOR_MSK;
-	mode_follower = mode & CEC_MODE_FOLLOWER_MSK;
-
-	if (mode_initiator > CEC_MODE_EXCL_INITIATOR ||
-	    mode_follower > CEC_MODE_MONITOR_ALL) {
-		dprintk(1, "%s: unknown mode\n", __func__);
-		return -EINVAL;
-	}
-
-	if (mode_follower == CEC_MODE_MONITOR_ALL &&
-	    !(adap->capabilities & CEC_CAP_MONITOR_ALL)) {
-		dprintk(1, "%s: MONITOR_ALL not supported\n", __func__);
-		return -EINVAL;
-	}
-
-	if (mode_follower == CEC_MODE_MONITOR_PIN &&
-	    !(adap->capabilities & CEC_CAP_MONITOR_PIN)) {
-		dprintk(1, "%s: MONITOR_PIN not supported\n", __func__);
-		return -EINVAL;
-	}
-
-	/* Follower modes should always be able to send CEC messages */
-	if ((mode_initiator == CEC_MODE_NO_INITIATOR ||
-	     !(adap->capabilities & CEC_CAP_TRANSMIT)) &&
-	    mode_follower >= CEC_MODE_FOLLOWER &&
-	    mode_follower <= CEC_MODE_EXCL_FOLLOWER_PASSTHRU) {
-		dprintk(1, "%s: cannot transmit\n", __func__);
-		return -EINVAL;
-	}
-
-	/* Monitor modes require CEC_MODE_NO_INITIATOR */
-	if (mode_initiator && mode_follower >= CEC_MODE_MONITOR_PIN) {
-		dprintk(1, "%s: monitor modes require NO_INITIATOR\n",
-			__func__);
-		return -EINVAL;
-	}
-
-	/* Monitor modes require CAP_NET_ADMIN */
-	if (mode_follower >= CEC_MODE_MONITOR_PIN && !capable(CAP_NET_ADMIN))
-		return -EPERM;
-
-	mutex_lock(&adap->lock);
-	/*
-	 * You can't become exclusive follower if someone else already
-	 * has that job.
-	 */
-	if ((mode_follower == CEC_MODE_EXCL_FOLLOWER ||
-	     mode_follower == CEC_MODE_EXCL_FOLLOWER_PASSTHRU) &&
-	    adap->cec_follower && adap->cec_follower != fh)
-		err = -EBUSY;
-	/*
-	 * You can't become exclusive initiator if someone else already
-	 * has that job.
-	 */
-	if (mode_initiator == CEC_MODE_EXCL_INITIATOR &&
-	    adap->cec_initiator && adap->cec_initiator != fh)
-		err = -EBUSY;
-
-	if (!err) {
-		bool old_mon_all = fh->mode_follower == CEC_MODE_MONITOR_ALL;
-		bool new_mon_all = mode_follower == CEC_MODE_MONITOR_ALL;
-
-		if (old_mon_all != new_mon_all) {
-			if (new_mon_all)
-				err = cec_monitor_all_cnt_inc(adap);
-			else
-				cec_monitor_all_cnt_dec(adap);
-		}
-	}
-
-	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;
-	}
-
-	if (fh->mode_follower == CEC_MODE_FOLLOWER)
-		adap->follower_cnt--;
-	if (mode_follower == CEC_MODE_FOLLOWER)
-		adap->follower_cnt++;
-	if (send_pin_event) {
-		struct cec_event ev = {
-			.flags = CEC_EVENT_FL_INITIAL_STATE,
-		};
-
-		ev.event = adap->cec_pin_is_high ? CEC_EVENT_PIN_CEC_HIGH :
-						   CEC_EVENT_PIN_CEC_LOW;
-		cec_queue_event_fh(fh, &ev, 0);
-	}
-	if (mode_follower == CEC_MODE_EXCL_FOLLOWER ||
-	    mode_follower == CEC_MODE_EXCL_FOLLOWER_PASSTHRU) {
-		adap->passthrough =
-			mode_follower == CEC_MODE_EXCL_FOLLOWER_PASSTHRU;
-		adap->cec_follower = fh;
-	} else if (adap->cec_follower == fh) {
-		adap->passthrough = false;
-		adap->cec_follower = NULL;
-	}
-	if (mode_initiator == CEC_MODE_EXCL_INITIATOR)
-		adap->cec_initiator = fh;
-	else if (adap->cec_initiator == fh)
-		adap->cec_initiator = NULL;
-	fh->mode_initiator = mode_initiator;
-	fh->mode_follower = mode_follower;
-	mutex_unlock(&adap->lock);
-	return 0;
-}
-
-static long cec_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
-{
-	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 (!cec_is_registered(adap))
-		return -ENODEV;
-
-	switch (cmd) {
-	case CEC_ADAP_G_CAPS:
-		return cec_adap_g_caps(adap, parg);
-
-	case CEC_ADAP_G_PHYS_ADDR:
-		return cec_adap_g_phys_addr(adap, parg);
-
-	case CEC_ADAP_S_PHYS_ADDR:
-		return cec_adap_s_phys_addr(adap, fh, block, parg);
-
-	case CEC_ADAP_G_LOG_ADDRS:
-		return cec_adap_g_log_addrs(adap, parg);
-
-	case CEC_ADAP_S_LOG_ADDRS:
-		return cec_adap_s_log_addrs(adap, fh, block, parg);
-
-	case CEC_ADAP_G_CONNECTOR_INFO:
-		return cec_adap_g_connector_info(adap, parg);
-
-	case CEC_TRANSMIT:
-		return cec_transmit(adap, fh, block, parg);
-
-	case CEC_RECEIVE:
-		return cec_receive(adap, fh, block, parg);
-
-	case CEC_DQEVENT:
-		return cec_dqevent(adap, fh, block, parg);
-
-	case CEC_G_MODE:
-		return cec_g_mode(adap, fh, parg);
-
-	case CEC_S_MODE:
-		return cec_s_mode(adap, fh, parg);
-
-	default:
-		return -ENOTTY;
-	}
-}
-
-static int cec_open(struct inode *inode, struct file *filp)
-{
-	struct cec_devnode *devnode =
-		container_of(inode->i_cdev, struct cec_devnode, cdev);
-	struct cec_adapter *adap = to_cec_adapter(devnode);
-	struct cec_fh *fh = kzalloc(sizeof(*fh), GFP_KERNEL);
-	/*
-	 * Initial events that are automatically sent when the cec device is
-	 * opened.
-	 */
-	struct cec_event ev = {
-		.event = CEC_EVENT_STATE_CHANGE,
-		.flags = CEC_EVENT_FL_INITIAL_STATE,
-	};
-	unsigned int i;
-	int err;
-
-	if (!fh)
-		return -ENOMEM;
-
-	INIT_LIST_HEAD(&fh->msgs);
-	INIT_LIST_HEAD(&fh->xfer_list);
-	for (i = 0; i < CEC_NUM_EVENTS; i++)
-		INIT_LIST_HEAD(&fh->events[i]);
-	mutex_init(&fh->lock);
-	init_waitqueue_head(&fh->wait);
-
-	fh->mode_initiator = CEC_MODE_INITIATOR;
-	fh->adap = adap;
-
-	err = cec_get_device(devnode);
-	if (err) {
-		kfree(fh);
-		return err;
-	}
-
-	mutex_lock(&devnode->lock);
-	if (list_empty(&devnode->fhs) &&
-	    !adap->needs_hpd &&
-	    adap->phys_addr == CEC_PHYS_ADDR_INVALID) {
-		err = adap->ops->adap_enable(adap, true);
-		if (err) {
-			mutex_unlock(&devnode->lock);
-			kfree(fh);
-			return err;
-		}
-	}
-	filp->private_data = fh;
-
-	/* Queue up initial state events */
-	ev.state_change.phys_addr = adap->phys_addr;
-	ev.state_change.log_addr_mask = adap->log_addrs.log_addr_mask;
-	ev.state_change.have_conn_info =
-		adap->conn_info.type != CEC_CONNECTOR_TYPE_NO_CONNECTOR;
-	cec_queue_event_fh(fh, &ev, 0);
-#ifdef CONFIG_CEC_PIN
-	if (adap->pin && adap->pin->ops->read_hpd) {
-		err = adap->pin->ops->read_hpd(adap);
-		if (err >= 0) {
-			ev.event = err ? CEC_EVENT_PIN_HPD_HIGH :
-					 CEC_EVENT_PIN_HPD_LOW;
-			cec_queue_event_fh(fh, &ev, 0);
-		}
-	}
-	if (adap->pin && adap->pin->ops->read_5v) {
-		err = adap->pin->ops->read_5v(adap);
-		if (err >= 0) {
-			ev.event = err ? CEC_EVENT_PIN_5V_HIGH :
-					 CEC_EVENT_PIN_5V_LOW;
-			cec_queue_event_fh(fh, &ev, 0);
-		}
-	}
-#endif
-
-	list_add(&fh->list, &devnode->fhs);
-	mutex_unlock(&devnode->lock);
-
-	return 0;
-}
-
-/* Override for the release function */
-static int cec_release(struct inode *inode, struct file *filp)
-{
-	struct cec_devnode *devnode = cec_devnode_data(filp);
-	struct cec_adapter *adap = to_cec_adapter(devnode);
-	struct cec_fh *fh = filp->private_data;
-	unsigned int i;
-
-	mutex_lock(&adap->lock);
-	if (adap->cec_initiator == fh)
-		adap->cec_initiator = NULL;
-	if (adap->cec_follower == fh) {
-		adap->cec_follower = NULL;
-		adap->passthrough = false;
-	}
-	if (fh->mode_follower == CEC_MODE_FOLLOWER)
-		adap->follower_cnt--;
-	if (fh->mode_follower == CEC_MODE_MONITOR_PIN)
-		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 (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);
-
-	/* Unhook pending transmits from this filehandle. */
-	mutex_lock(&adap->lock);
-	while (!list_empty(&fh->xfer_list)) {
-		struct cec_data *data =
-			list_first_entry(&fh->xfer_list, struct cec_data, xfer_list);
-
-		data->blocking = false;
-		data->fh = NULL;
-		list_del(&data->xfer_list);
-	}
-	mutex_unlock(&adap->lock);
-	while (!list_empty(&fh->msgs)) {
-		struct cec_msg_entry *entry =
-			list_first_entry(&fh->msgs, struct cec_msg_entry, list);
-
-		list_del(&entry->list);
-		kfree(entry);
-	}
-	for (i = CEC_NUM_CORE_EVENTS; i < CEC_NUM_EVENTS; i++) {
-		while (!list_empty(&fh->events[i])) {
-			struct cec_event_entry *entry =
-				list_first_entry(&fh->events[i],
-						 struct cec_event_entry, list);
-
-			list_del(&entry->list);
-			kfree(entry);
-		}
-	}
-	kfree(fh);
-
-	cec_put_device(devnode);
-	filp->private_data = NULL;
-	return 0;
-}
-
-const struct file_operations cec_devnode_fops = {
-	.owner = THIS_MODULE,
-	.open = cec_open,
-	.unlocked_ioctl = cec_ioctl,
-	.compat_ioctl = cec_ioctl,
-	.release = cec_release,
-	.poll = cec_poll,
-	.llseek = no_llseek,
-};
diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c
deleted file mode 100644
index 0c52e1bb3910..000000000000
--- a/drivers/media/cec/cec-core.c
+++ /dev/null
@@ -1,465 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * cec-core.c - HDMI Consumer Electronics Control framework - Core
- *
- * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/kmod.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/types.h>
-
-#include "cec-priv.h"
-
-#define CEC_NUM_DEVICES	256
-#define CEC_NAME	"cec"
-
-int cec_debug;
-module_param_named(debug, cec_debug, int, 0644);
-MODULE_PARM_DESC(debug, "debug level (0-2)");
-
-static bool debug_phys_addr;
-module_param(debug_phys_addr, bool, 0644);
-MODULE_PARM_DESC(debug_phys_addr, "add CEC_CAP_PHYS_ADDR if set");
-
-static dev_t cec_dev_t;
-
-/* Active devices */
-static DEFINE_MUTEX(cec_devnode_lock);
-static DECLARE_BITMAP(cec_devnode_nums, CEC_NUM_DEVICES);
-
-static struct dentry *top_cec_dir;
-
-/* dev to cec_devnode */
-#define to_cec_devnode(cd) container_of(cd, struct cec_devnode, dev)
-
-int cec_get_device(struct cec_devnode *devnode)
-{
-	/*
-	 * Check if the cec device is available. This needs to be done with
-	 * the devnode->lock held to prevent an open/unregister race:
-	 * without the lock, the device could be unregistered and freed between
-	 * the devnode->registered check and get_device() calls, leading to
-	 * a crash.
-	 */
-	mutex_lock(&devnode->lock);
-	/*
-	 * return ENXIO if the cec device has been removed
-	 * already or if it is not registered anymore.
-	 */
-	if (!devnode->registered) {
-		mutex_unlock(&devnode->lock);
-		return -ENXIO;
-	}
-	/* and increase the device refcount */
-	get_device(&devnode->dev);
-	mutex_unlock(&devnode->lock);
-	return 0;
-}
-
-void cec_put_device(struct cec_devnode *devnode)
-{
-	put_device(&devnode->dev);
-}
-
-/* Called when the last user of the cec device exits. */
-static void cec_devnode_release(struct device *cd)
-{
-	struct cec_devnode *devnode = to_cec_devnode(cd);
-
-	mutex_lock(&cec_devnode_lock);
-	/* Mark device node number as free */
-	clear_bit(devnode->minor, cec_devnode_nums);
-	mutex_unlock(&cec_devnode_lock);
-
-	cec_delete_adapter(to_cec_adapter(devnode));
-}
-
-static struct bus_type cec_bus_type = {
-	.name = CEC_NAME,
-};
-
-/*
- * Register a cec device node
- *
- * The registration code assigns minor numbers and registers the new device node
- * with the kernel. An error is returned if no free minor number can be found,
- * or if the registration of the device node fails.
- *
- * Zero is returned on success.
- *
- * Note that if the cec_devnode_register call fails, the release() callback of
- * the cec_devnode structure is *not* called, so the caller is responsible for
- * freeing any data.
- */
-static int __must_check cec_devnode_register(struct cec_devnode *devnode,
-					     struct module *owner)
-{
-	int minor;
-	int ret;
-
-	/* Part 1: Find a free minor number */
-	mutex_lock(&cec_devnode_lock);
-	minor = find_next_zero_bit(cec_devnode_nums, CEC_NUM_DEVICES, 0);
-	if (minor == CEC_NUM_DEVICES) {
-		mutex_unlock(&cec_devnode_lock);
-		pr_err("could not get a free minor\n");
-		return -ENFILE;
-	}
-
-	set_bit(minor, cec_devnode_nums);
-	mutex_unlock(&cec_devnode_lock);
-
-	devnode->minor = minor;
-	devnode->dev.bus = &cec_bus_type;
-	devnode->dev.devt = MKDEV(MAJOR(cec_dev_t), minor);
-	devnode->dev.release = cec_devnode_release;
-	dev_set_name(&devnode->dev, "cec%d", devnode->minor);
-	device_initialize(&devnode->dev);
-
-	/* Part 2: Initialize and register the character device */
-	cdev_init(&devnode->cdev, &cec_devnode_fops);
-	devnode->cdev.owner = owner;
-	kobject_set_name(&devnode->cdev.kobj, "cec%d", devnode->minor);
-
-	devnode->registered = true;
-	ret = cdev_device_add(&devnode->cdev, &devnode->dev);
-	if (ret) {
-		devnode->registered = false;
-		pr_err("%s: cdev_device_add failed\n", __func__);
-		goto clr_bit;
-	}
-
-	return 0;
-
-clr_bit:
-	mutex_lock(&cec_devnode_lock);
-	clear_bit(devnode->minor, cec_devnode_nums);
-	mutex_unlock(&cec_devnode_lock);
-	return ret;
-}
-
-/*
- * Unregister a cec device node
- *
- * This unregisters the passed device. Future open calls will be met with
- * errors.
- *
- * 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_adapter *adap)
-{
-	struct cec_devnode *devnode = &adap->devnode;
-	struct cec_fh *fh;
-
-	mutex_lock(&devnode->lock);
-
-	/* Check if devnode was never registered or already unregistered */
-	if (!devnode->registered || devnode->unregistered) {
-		mutex_unlock(&devnode->lock);
-		return;
-	}
-
-	list_for_each_entry(fh, &devnode->fhs, list)
-		wake_up_interruptible(&fh->wait);
-
-	devnode->registered = false;
-	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);
-}
-
-#ifdef CONFIG_DEBUG_FS
-static ssize_t cec_error_inj_write(struct file *file,
-	const char __user *ubuf, size_t count, loff_t *ppos)
-{
-	struct seq_file *sf = file->private_data;
-	struct cec_adapter *adap = sf->private;
-	char *buf;
-	char *line;
-	char *p;
-
-	buf = memdup_user_nul(ubuf, min_t(size_t, PAGE_SIZE, count));
-	if (IS_ERR(buf))
-		return PTR_ERR(buf);
-	p = buf;
-	while (p && *p) {
-		p = skip_spaces(p);
-		line = strsep(&p, "\n");
-		if (!*line || *line == '#')
-			continue;
-		if (!adap->ops->error_inj_parse_line(adap, line)) {
-			kfree(buf);
-			return -EINVAL;
-		}
-	}
-	kfree(buf);
-	return count;
-}
-
-static int cec_error_inj_show(struct seq_file *sf, void *unused)
-{
-	struct cec_adapter *adap = sf->private;
-
-	return adap->ops->error_inj_show(adap, sf);
-}
-
-static int cec_error_inj_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, cec_error_inj_show, inode->i_private);
-}
-
-static const struct file_operations cec_error_inj_fops = {
-	.open = cec_error_inj_open,
-	.write = cec_error_inj_write,
-	.read = seq_read,
-	.llseek = seq_lseek,
-	.release = single_release,
-};
-#endif
-
-struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
-					 void *priv, const char *name, u32 caps,
-					 u8 available_las)
-{
-	struct cec_adapter *adap;
-	int res;
-
-#ifndef CONFIG_MEDIA_CEC_RC
-	caps &= ~CEC_CAP_RC;
-#endif
-
-	if (WARN_ON(!caps))
-		return ERR_PTR(-EINVAL);
-	if (WARN_ON(!ops))
-		return ERR_PTR(-EINVAL);
-	if (WARN_ON(!available_las || available_las > CEC_MAX_LOG_ADDRS))
-		return ERR_PTR(-EINVAL);
-	adap = kzalloc(sizeof(*adap), GFP_KERNEL);
-	if (!adap)
-		return ERR_PTR(-ENOMEM);
-	strscpy(adap->name, name, sizeof(adap->name));
-	adap->phys_addr = CEC_PHYS_ADDR_INVALID;
-	adap->cec_pin_is_high = true;
-	adap->log_addrs.cec_version = CEC_OP_CEC_VERSION_2_0;
-	adap->log_addrs.vendor_id = CEC_VENDOR_ID_NONE;
-	adap->capabilities = caps;
-	if (debug_phys_addr)
-		adap->capabilities |= CEC_CAP_PHYS_ADDR;
-	adap->needs_hpd = caps & CEC_CAP_NEEDS_HPD;
-	adap->available_log_addrs = available_las;
-	adap->sequence = 0;
-	adap->ops = ops;
-	adap->priv = priv;
-	memset(adap->phys_addrs, 0xff, sizeof(adap->phys_addrs));
-	mutex_init(&adap->lock);
-	INIT_LIST_HEAD(&adap->transmit_queue);
-	INIT_LIST_HEAD(&adap->wait_queue);
-	init_waitqueue_head(&adap->kthread_waitq);
-
-	/* adap->devnode initialization */
-	INIT_LIST_HEAD(&adap->devnode.fhs);
-	mutex_init(&adap->devnode.lock);
-
-	adap->kthread = kthread_run(cec_thread_func, adap, "cec-%s", name);
-	if (IS_ERR(adap->kthread)) {
-		pr_err("cec-%s: kernel_thread() failed\n", name);
-		res = PTR_ERR(adap->kthread);
-		kfree(adap);
-		return ERR_PTR(res);
-	}
-
-#ifdef CONFIG_MEDIA_CEC_RC
-	if (!(caps & CEC_CAP_RC))
-		return adap;
-
-	/* Prepare the RC input device */
-	adap->rc = rc_allocate_device(RC_DRIVER_SCANCODE);
-	if (!adap->rc) {
-		pr_err("cec-%s: failed to allocate memory for rc_dev\n",
-		       name);
-		kthread_stop(adap->kthread);
-		kfree(adap);
-		return ERR_PTR(-ENOMEM);
-	}
-
-	snprintf(adap->input_phys, sizeof(adap->input_phys),
-		 "%s/input0", adap->name);
-
-	adap->rc->device_name = adap->name;
-	adap->rc->input_phys = adap->input_phys;
-	adap->rc->input_id.bustype = BUS_CEC;
-	adap->rc->input_id.vendor = 0;
-	adap->rc->input_id.product = 0;
-	adap->rc->input_id.version = 1;
-	adap->rc->driver_name = CEC_NAME;
-	adap->rc->allowed_protocols = RC_PROTO_BIT_CEC;
-	adap->rc->priv = adap;
-	adap->rc->map_name = RC_MAP_CEC;
-	adap->rc->timeout = MS_TO_NS(550);
-#endif
-	return adap;
-}
-EXPORT_SYMBOL_GPL(cec_allocate_adapter);
-
-int cec_register_adapter(struct cec_adapter *adap,
-			 struct device *parent)
-{
-	int res;
-
-	if (IS_ERR_OR_NULL(adap))
-		return 0;
-
-	if (WARN_ON(!parent))
-		return -EINVAL;
-
-	adap->owner = parent->driver->owner;
-	adap->devnode.dev.parent = parent;
-
-#ifdef CONFIG_MEDIA_CEC_RC
-	if (adap->capabilities & CEC_CAP_RC) {
-		adap->rc->dev.parent = parent;
-		res = rc_register_device(adap->rc);
-
-		if (res) {
-			pr_err("cec-%s: failed to prepare input device\n",
-			       adap->name);
-			rc_free_device(adap->rc);
-			adap->rc = NULL;
-			return res;
-		}
-	}
-#endif
-
-	res = cec_devnode_register(&adap->devnode, adap->owner);
-	if (res) {
-#ifdef CONFIG_MEDIA_CEC_RC
-		/* Note: rc_unregister also calls rc_free */
-		rc_unregister_device(adap->rc);
-		adap->rc = NULL;
-#endif
-		return res;
-	}
-
-	dev_set_drvdata(&adap->devnode.dev, adap);
-#ifdef CONFIG_DEBUG_FS
-	if (!top_cec_dir)
-		return 0;
-
-	adap->cec_dir = debugfs_create_dir(dev_name(&adap->devnode.dev), top_cec_dir);
-	if (IS_ERR_OR_NULL(adap->cec_dir)) {
-		pr_warn("cec-%s: Failed to create debugfs dir\n", adap->name);
-		return 0;
-	}
-	adap->status_file = debugfs_create_devm_seqfile(&adap->devnode.dev,
-		"status", adap->cec_dir, cec_adap_status);
-	if (IS_ERR_OR_NULL(adap->status_file)) {
-		pr_warn("cec-%s: Failed to create status file\n", adap->name);
-		debugfs_remove_recursive(adap->cec_dir);
-		adap->cec_dir = NULL;
-		return 0;
-	}
-	if (!adap->ops->error_inj_show || !adap->ops->error_inj_parse_line)
-		return 0;
-	adap->error_inj_file = debugfs_create_file("error-inj", 0644,
-						   adap->cec_dir, adap,
-						   &cec_error_inj_fops);
-	if (IS_ERR_OR_NULL(adap->error_inj_file))
-		pr_warn("cec-%s: Failed to create error-inj file\n",
-			adap->name);
-#endif
-	return 0;
-}
-EXPORT_SYMBOL_GPL(cec_register_adapter);
-
-void cec_unregister_adapter(struct cec_adapter *adap)
-{
-	if (IS_ERR_OR_NULL(adap))
-		return;
-
-#ifdef CONFIG_MEDIA_CEC_RC
-	/* Note: rc_unregister also calls rc_free */
-	rc_unregister_device(adap->rc);
-	adap->rc = NULL;
-#endif
-	debugfs_remove_recursive(adap->cec_dir);
-#ifdef CONFIG_CEC_NOTIFIER
-	cec_notifier_cec_adap_unregister(adap->notifier, adap);
-#endif
-	cec_devnode_unregister(adap);
-}
-EXPORT_SYMBOL_GPL(cec_unregister_adapter);
-
-void cec_delete_adapter(struct cec_adapter *adap)
-{
-	if (IS_ERR_OR_NULL(adap))
-		return;
-	kthread_stop(adap->kthread);
-	if (adap->kthread_config)
-		kthread_stop(adap->kthread_config);
-	if (adap->ops->adap_free)
-		adap->ops->adap_free(adap);
-#ifdef CONFIG_MEDIA_CEC_RC
-	rc_free_device(adap->rc);
-#endif
-	kfree(adap);
-}
-EXPORT_SYMBOL_GPL(cec_delete_adapter);
-
-/*
- *	Initialise cec for linux
- */
-static int __init cec_devnode_init(void)
-{
-	int ret = alloc_chrdev_region(&cec_dev_t, 0, CEC_NUM_DEVICES, CEC_NAME);
-
-	if (ret < 0) {
-		pr_warn("cec: unable to allocate major\n");
-		return ret;
-	}
-
-#ifdef CONFIG_DEBUG_FS
-	top_cec_dir = debugfs_create_dir("cec", NULL);
-	if (IS_ERR_OR_NULL(top_cec_dir)) {
-		pr_warn("cec: Failed to create debugfs cec dir\n");
-		top_cec_dir = NULL;
-	}
-#endif
-
-	ret = bus_register(&cec_bus_type);
-	if (ret < 0) {
-		unregister_chrdev_region(cec_dev_t, CEC_NUM_DEVICES);
-		pr_warn("cec: bus_register failed\n");
-		return -EIO;
-	}
-
-	return 0;
-}
-
-static void __exit cec_devnode_exit(void)
-{
-	debugfs_remove_recursive(top_cec_dir);
-	bus_unregister(&cec_bus_type);
-	unregister_chrdev_region(cec_dev_t, CEC_NUM_DEVICES);
-}
-
-subsys_initcall(cec_devnode_init);
-module_exit(cec_devnode_exit)
-
-MODULE_AUTHOR("Hans Verkuil <hans.verkuil@cisco.com>");
-MODULE_DESCRIPTION("Device node registration for cec drivers");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/cec/cec-notifier.c b/drivers/media/cec/cec-notifier.c
deleted file mode 100644
index e748cd54b45d..000000000000
--- a/drivers/media/cec/cec-notifier.c
+++ /dev/null
@@ -1,236 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * cec-notifier.c - notify CEC drivers of physical address changes
- *
- * Copyright 2016 Russell King <rmk+kernel@arm.linux.org.uk>
- * Copyright 2016-2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#include <linux/export.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/list.h>
-#include <linux/kref.h>
-#include <linux/of_platform.h>
-
-#include <media/cec.h>
-#include <media/cec-notifier.h>
-#include <drm/drm_edid.h>
-
-struct cec_notifier {
-	struct mutex lock;
-	struct list_head head;
-	struct kref kref;
-	struct device *hdmi_dev;
-	struct cec_connector_info conn_info;
-	const char *port_name;
-	struct cec_adapter *cec_adap;
-
-	u16 phys_addr;
-};
-
-static LIST_HEAD(cec_notifiers);
-static DEFINE_MUTEX(cec_notifiers_lock);
-
-/**
- * cec_notifier_get_conn - find or create a new cec_notifier for the given
- * device and connector tuple.
- * @hdmi_dev: device that sends the events.
- * @port_name: the connector name from which the event occurs
- *
- * If a notifier for device @dev already exists, then increase the refcount
- * and return that notifier.
- *
- * If it doesn't exist, then allocate a new notifier struct and return a
- * pointer to that new struct.
- *
- * Return NULL if the memory could not be allocated.
- */
-static struct cec_notifier *
-cec_notifier_get_conn(struct device *hdmi_dev, const char *port_name)
-{
-	struct cec_notifier *n;
-
-	mutex_lock(&cec_notifiers_lock);
-	list_for_each_entry(n, &cec_notifiers, head) {
-		if (n->hdmi_dev == hdmi_dev &&
-		    (!port_name ||
-		     (n->port_name && !strcmp(n->port_name, port_name)))) {
-			kref_get(&n->kref);
-			mutex_unlock(&cec_notifiers_lock);
-			return n;
-		}
-	}
-	n = kzalloc(sizeof(*n), GFP_KERNEL);
-	if (!n)
-		goto unlock;
-	n->hdmi_dev = hdmi_dev;
-	if (port_name) {
-		n->port_name = kstrdup(port_name, GFP_KERNEL);
-		if (!n->port_name) {
-			kfree(n);
-			n = NULL;
-			goto unlock;
-		}
-	}
-	n->phys_addr = CEC_PHYS_ADDR_INVALID;
-
-	mutex_init(&n->lock);
-	kref_init(&n->kref);
-	list_add_tail(&n->head, &cec_notifiers);
-unlock:
-	mutex_unlock(&cec_notifiers_lock);
-	return n;
-}
-
-static void cec_notifier_release(struct kref *kref)
-{
-	struct cec_notifier *n =
-		container_of(kref, struct cec_notifier, kref);
-
-	list_del(&n->head);
-	kfree(n->port_name);
-	kfree(n);
-}
-
-static void cec_notifier_put(struct cec_notifier *n)
-{
-	mutex_lock(&cec_notifiers_lock);
-	kref_put(&n->kref, cec_notifier_release);
-	mutex_unlock(&cec_notifiers_lock);
-}
-
-struct cec_notifier *
-cec_notifier_conn_register(struct device *hdmi_dev, const char *port_name,
-			   const struct cec_connector_info *conn_info)
-{
-	struct cec_notifier *n = cec_notifier_get_conn(hdmi_dev, port_name);
-
-	if (!n)
-		return n;
-
-	mutex_lock(&n->lock);
-	n->phys_addr = CEC_PHYS_ADDR_INVALID;
-	if (conn_info)
-		n->conn_info = *conn_info;
-	else
-		memset(&n->conn_info, 0, sizeof(n->conn_info));
-	if (n->cec_adap) {
-		cec_phys_addr_invalidate(n->cec_adap);
-		cec_s_conn_info(n->cec_adap, conn_info);
-	}
-	mutex_unlock(&n->lock);
-	return n;
-}
-EXPORT_SYMBOL_GPL(cec_notifier_conn_register);
-
-void cec_notifier_conn_unregister(struct cec_notifier *n)
-{
-	if (!n)
-		return;
-
-	mutex_lock(&n->lock);
-	memset(&n->conn_info, 0, sizeof(n->conn_info));
-	n->phys_addr = CEC_PHYS_ADDR_INVALID;
-	if (n->cec_adap) {
-		cec_phys_addr_invalidate(n->cec_adap);
-		cec_s_conn_info(n->cec_adap, NULL);
-	}
-	mutex_unlock(&n->lock);
-	cec_notifier_put(n);
-}
-EXPORT_SYMBOL_GPL(cec_notifier_conn_unregister);
-
-struct cec_notifier *
-cec_notifier_cec_adap_register(struct device *hdmi_dev, const char *port_name,
-			       struct cec_adapter *adap)
-{
-	struct cec_notifier *n;
-
-	if (WARN_ON(!adap))
-		return NULL;
-
-	n = cec_notifier_get_conn(hdmi_dev, port_name);
-	if (!n)
-		return n;
-
-	mutex_lock(&n->lock);
-	n->cec_adap = adap;
-	adap->conn_info = n->conn_info;
-	adap->notifier = n;
-	cec_s_phys_addr(adap, n->phys_addr, false);
-	mutex_unlock(&n->lock);
-	return n;
-}
-EXPORT_SYMBOL_GPL(cec_notifier_cec_adap_register);
-
-void cec_notifier_cec_adap_unregister(struct cec_notifier *n,
-				      struct cec_adapter *adap)
-{
-	if (!n)
-		return;
-
-	mutex_lock(&n->lock);
-	adap->notifier = NULL;
-	n->cec_adap = NULL;
-	mutex_unlock(&n->lock);
-	cec_notifier_put(n);
-}
-EXPORT_SYMBOL_GPL(cec_notifier_cec_adap_unregister);
-
-void cec_notifier_set_phys_addr(struct cec_notifier *n, u16 pa)
-{
-	if (n == NULL)
-		return;
-
-	mutex_lock(&n->lock);
-	n->phys_addr = pa;
-	if (n->cec_adap)
-		cec_s_phys_addr(n->cec_adap, n->phys_addr, false);
-	mutex_unlock(&n->lock);
-}
-EXPORT_SYMBOL_GPL(cec_notifier_set_phys_addr);
-
-void cec_notifier_set_phys_addr_from_edid(struct cec_notifier *n,
-					  const struct edid *edid)
-{
-	u16 pa = CEC_PHYS_ADDR_INVALID;
-
-	if (n == NULL)
-		return;
-
-	if (edid && edid->extensions)
-		pa = cec_get_edid_phys_addr((const u8 *)edid,
-				EDID_LENGTH * (edid->extensions + 1), NULL);
-	cec_notifier_set_phys_addr(n, pa);
-}
-EXPORT_SYMBOL_GPL(cec_notifier_set_phys_addr_from_edid);
-
-struct device *cec_notifier_parse_hdmi_phandle(struct device *dev)
-{
-	struct platform_device *hdmi_pdev;
-	struct device *hdmi_dev = NULL;
-	struct device_node *np;
-
-	np = of_parse_phandle(dev->of_node, "hdmi-phandle", 0);
-
-	if (!np) {
-		dev_err(dev, "Failed to find HDMI node in device tree\n");
-		return ERR_PTR(-ENODEV);
-	}
-	hdmi_pdev = of_find_device_by_node(np);
-	of_node_put(np);
-	if (hdmi_pdev) {
-		hdmi_dev = &hdmi_pdev->dev;
-		/*
-		 * Note that the device struct is only used as a key into the
-		 * cec_notifiers list, it is never actually accessed.
-		 * So we decrement the reference here so we don't leak
-		 * memory.
-		 */
-		put_device(hdmi_dev);
-		return hdmi_dev;
-	}
-	return ERR_PTR(-EPROBE_DEFER);
-}
-EXPORT_SYMBOL_GPL(cec_notifier_parse_hdmi_phandle);
diff --git a/drivers/media/cec/cec-pin-error-inj.c b/drivers/media/cec/cec-pin-error-inj.c
deleted file mode 100644
index c0088d3b8e3d..000000000000
--- a/drivers/media/cec/cec-pin-error-inj.c
+++ /dev/null
@@ -1,345 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/sched/types.h>
-
-#include <media/cec-pin.h>
-#include "cec-pin-priv.h"
-
-struct cec_error_inj_cmd {
-	unsigned int mode_offset;
-	int arg_idx;
-	const char *cmd;
-};
-
-static const struct cec_error_inj_cmd cec_error_inj_cmds[] = {
-	{ CEC_ERROR_INJ_RX_NACK_OFFSET, -1, "rx-nack" },
-	{ CEC_ERROR_INJ_RX_LOW_DRIVE_OFFSET,
-	  CEC_ERROR_INJ_RX_LOW_DRIVE_ARG_IDX, "rx-low-drive" },
-	{ CEC_ERROR_INJ_RX_ADD_BYTE_OFFSET, -1, "rx-add-byte" },
-	{ CEC_ERROR_INJ_RX_REMOVE_BYTE_OFFSET, -1, "rx-remove-byte" },
-	{ CEC_ERROR_INJ_RX_ARB_LOST_OFFSET,
-	  CEC_ERROR_INJ_RX_ARB_LOST_ARG_IDX, "rx-arb-lost" },
-
-	{ CEC_ERROR_INJ_TX_NO_EOM_OFFSET, -1, "tx-no-eom" },
-	{ CEC_ERROR_INJ_TX_EARLY_EOM_OFFSET, -1, "tx-early-eom" },
-	{ CEC_ERROR_INJ_TX_ADD_BYTES_OFFSET,
-	  CEC_ERROR_INJ_TX_ADD_BYTES_ARG_IDX, "tx-add-bytes" },
-	{ CEC_ERROR_INJ_TX_REMOVE_BYTE_OFFSET, -1, "tx-remove-byte" },
-	{ CEC_ERROR_INJ_TX_SHORT_BIT_OFFSET,
-	  CEC_ERROR_INJ_TX_SHORT_BIT_ARG_IDX, "tx-short-bit" },
-	{ CEC_ERROR_INJ_TX_LONG_BIT_OFFSET,
-	  CEC_ERROR_INJ_TX_LONG_BIT_ARG_IDX, "tx-long-bit" },
-	{ CEC_ERROR_INJ_TX_CUSTOM_BIT_OFFSET,
-	  CEC_ERROR_INJ_TX_CUSTOM_BIT_ARG_IDX, "tx-custom-bit" },
-	{ CEC_ERROR_INJ_TX_SHORT_START_OFFSET, -1, "tx-short-start" },
-	{ CEC_ERROR_INJ_TX_LONG_START_OFFSET, -1, "tx-long-start" },
-	{ CEC_ERROR_INJ_TX_CUSTOM_START_OFFSET, -1, "tx-custom-start" },
-	{ CEC_ERROR_INJ_TX_LAST_BIT_OFFSET,
-	  CEC_ERROR_INJ_TX_LAST_BIT_ARG_IDX, "tx-last-bit" },
-	{ CEC_ERROR_INJ_TX_LOW_DRIVE_OFFSET,
-	  CEC_ERROR_INJ_TX_LOW_DRIVE_ARG_IDX, "tx-low-drive" },
-	{ 0, -1, NULL }
-};
-
-u16 cec_pin_rx_error_inj(struct cec_pin *pin)
-{
-	u16 cmd = CEC_ERROR_INJ_OP_ANY;
-
-	/* Only when 18 bits have been received do we have a valid cmd */
-	if (!(pin->error_inj[cmd] & CEC_ERROR_INJ_RX_MASK) &&
-	    pin->rx_bit >= 18)
-		cmd = pin->rx_msg.msg[1];
-	return (pin->error_inj[cmd] & CEC_ERROR_INJ_RX_MASK) ? cmd :
-		CEC_ERROR_INJ_OP_ANY;
-}
-
-u16 cec_pin_tx_error_inj(struct cec_pin *pin)
-{
-	u16 cmd = CEC_ERROR_INJ_OP_ANY;
-
-	if (!(pin->error_inj[cmd] & CEC_ERROR_INJ_TX_MASK) &&
-	    pin->tx_msg.len > 1)
-		cmd = pin->tx_msg.msg[1];
-	return (pin->error_inj[cmd] & CEC_ERROR_INJ_TX_MASK) ? cmd :
-		CEC_ERROR_INJ_OP_ANY;
-}
-
-bool cec_pin_error_inj_parse_line(struct cec_adapter *adap, char *line)
-{
-	static const char *delims = " \t\r";
-	struct cec_pin *pin = adap->pin;
-	unsigned int i;
-	bool has_pos = false;
-	char *p = line;
-	char *token;
-	char *comma;
-	u64 *error;
-	u8 *args;
-	bool has_op;
-	u8 op;
-	u8 mode;
-	u8 pos;
-
-	p = skip_spaces(p);
-	token = strsep(&p, delims);
-	if (!strcmp(token, "clear")) {
-		memset(pin->error_inj, 0, sizeof(pin->error_inj));
-		pin->rx_toggle = pin->tx_toggle = false;
-		pin->tx_ignore_nack_until_eom = false;
-		pin->tx_custom_pulse = false;
-		pin->tx_custom_low_usecs = CEC_TIM_CUSTOM_DEFAULT;
-		pin->tx_custom_high_usecs = CEC_TIM_CUSTOM_DEFAULT;
-		return true;
-	}
-	if (!strcmp(token, "rx-clear")) {
-		for (i = 0; i <= CEC_ERROR_INJ_OP_ANY; i++)
-			pin->error_inj[i] &= ~CEC_ERROR_INJ_RX_MASK;
-		pin->rx_toggle = false;
-		return true;
-	}
-	if (!strcmp(token, "tx-clear")) {
-		for (i = 0; i <= CEC_ERROR_INJ_OP_ANY; i++)
-			pin->error_inj[i] &= ~CEC_ERROR_INJ_TX_MASK;
-		pin->tx_toggle = false;
-		pin->tx_ignore_nack_until_eom = false;
-		pin->tx_custom_pulse = false;
-		pin->tx_custom_low_usecs = CEC_TIM_CUSTOM_DEFAULT;
-		pin->tx_custom_high_usecs = CEC_TIM_CUSTOM_DEFAULT;
-		return true;
-	}
-	if (!strcmp(token, "tx-ignore-nack-until-eom")) {
-		pin->tx_ignore_nack_until_eom = true;
-		return true;
-	}
-	if (!strcmp(token, "tx-custom-pulse")) {
-		pin->tx_custom_pulse = true;
-		cec_pin_start_timer(pin);
-		return true;
-	}
-	if (!p)
-		return false;
-
-	p = skip_spaces(p);
-	if (!strcmp(token, "tx-custom-low-usecs")) {
-		u32 usecs;
-
-		if (kstrtou32(p, 0, &usecs) || usecs > 10000000)
-			return false;
-		pin->tx_custom_low_usecs = usecs;
-		return true;
-	}
-	if (!strcmp(token, "tx-custom-high-usecs")) {
-		u32 usecs;
-
-		if (kstrtou32(p, 0, &usecs) || usecs > 10000000)
-			return false;
-		pin->tx_custom_high_usecs = usecs;
-		return true;
-	}
-
-	comma = strchr(token, ',');
-	if (comma)
-		*comma++ = '\0';
-	if (!strcmp(token, "any")) {
-		has_op = false;
-		error = pin->error_inj + CEC_ERROR_INJ_OP_ANY;
-		args = pin->error_inj_args[CEC_ERROR_INJ_OP_ANY];
-	} else if (!kstrtou8(token, 0, &op)) {
-		has_op = true;
-		error = pin->error_inj + op;
-		args = pin->error_inj_args[op];
-	} else {
-		return false;
-	}
-
-	mode = CEC_ERROR_INJ_MODE_ONCE;
-	if (comma) {
-		if (!strcmp(comma, "off"))
-			mode = CEC_ERROR_INJ_MODE_OFF;
-		else if (!strcmp(comma, "once"))
-			mode = CEC_ERROR_INJ_MODE_ONCE;
-		else if (!strcmp(comma, "always"))
-			mode = CEC_ERROR_INJ_MODE_ALWAYS;
-		else if (!strcmp(comma, "toggle"))
-			mode = CEC_ERROR_INJ_MODE_TOGGLE;
-		else
-			return false;
-	}
-
-	token = strsep(&p, delims);
-	if (p) {
-		p = skip_spaces(p);
-		has_pos = !kstrtou8(p, 0, &pos);
-	}
-
-	if (!strcmp(token, "clear")) {
-		*error = 0;
-		return true;
-	}
-	if (!strcmp(token, "rx-clear")) {
-		*error &= ~CEC_ERROR_INJ_RX_MASK;
-		return true;
-	}
-	if (!strcmp(token, "tx-clear")) {
-		*error &= ~CEC_ERROR_INJ_TX_MASK;
-		return true;
-	}
-
-	for (i = 0; cec_error_inj_cmds[i].cmd; i++) {
-		const char *cmd = cec_error_inj_cmds[i].cmd;
-		unsigned int mode_offset;
-		u64 mode_mask;
-		int arg_idx;
-		bool is_bit_pos = true;
-
-		if (strcmp(token, cmd))
-			continue;
-
-		mode_offset = cec_error_inj_cmds[i].mode_offset;
-		mode_mask = CEC_ERROR_INJ_MODE_MASK << mode_offset;
-		arg_idx = cec_error_inj_cmds[i].arg_idx;
-
-		if (mode_offset == CEC_ERROR_INJ_RX_ARB_LOST_OFFSET) {
-			if (has_op)
-				return false;
-			if (!has_pos)
-				pos = 0x0f;
-			is_bit_pos = false;
-		} else if (mode_offset == CEC_ERROR_INJ_TX_ADD_BYTES_OFFSET) {
-			if (!has_pos || !pos)
-				return false;
-			is_bit_pos = false;
-		}
-
-		if (arg_idx >= 0 && is_bit_pos) {
-			if (!has_pos || pos >= 160)
-				return false;
-			if (has_op && pos < 10 + 8)
-				return false;
-			/* Invalid bit position may not be the Ack bit */
-			if ((mode_offset == CEC_ERROR_INJ_TX_SHORT_BIT_OFFSET ||
-			     mode_offset == CEC_ERROR_INJ_TX_LONG_BIT_OFFSET ||
-			     mode_offset == CEC_ERROR_INJ_TX_CUSTOM_BIT_OFFSET) &&
-			    (pos % 10) == 9)
-				return false;
-		}
-		*error &= ~mode_mask;
-		*error |= (u64)mode << mode_offset;
-		if (arg_idx >= 0)
-			args[arg_idx] = pos;
-		return true;
-	}
-	return false;
-}
-
-static void cec_pin_show_cmd(struct seq_file *sf, u32 cmd, u8 mode)
-{
-	if (cmd == CEC_ERROR_INJ_OP_ANY)
-		seq_puts(sf, "any,");
-	else
-		seq_printf(sf, "0x%02x,", cmd);
-	switch (mode) {
-	case CEC_ERROR_INJ_MODE_ONCE:
-		seq_puts(sf, "once ");
-		break;
-	case CEC_ERROR_INJ_MODE_ALWAYS:
-		seq_puts(sf, "always ");
-		break;
-	case CEC_ERROR_INJ_MODE_TOGGLE:
-		seq_puts(sf, "toggle ");
-		break;
-	default:
-		seq_puts(sf, "off ");
-		break;
-	}
-}
-
-int cec_pin_error_inj_show(struct cec_adapter *adap, struct seq_file *sf)
-{
-	struct cec_pin *pin = adap->pin;
-	unsigned int i, j;
-
-	seq_puts(sf, "# Clear error injections:\n");
-	seq_puts(sf, "#   clear          clear all rx and tx error injections\n");
-	seq_puts(sf, "#   rx-clear       clear all rx error injections\n");
-	seq_puts(sf, "#   tx-clear       clear all tx error injections\n");
-	seq_puts(sf, "#   <op> clear     clear all rx and tx error injections for <op>\n");
-	seq_puts(sf, "#   <op> rx-clear  clear all rx error injections for <op>\n");
-	seq_puts(sf, "#   <op> tx-clear  clear all tx error injections for <op>\n");
-	seq_puts(sf, "#\n");
-	seq_puts(sf, "# RX error injection:\n");
-	seq_puts(sf, "#   <op>[,<mode>] rx-nack              NACK the message instead of sending an ACK\n");
-	seq_puts(sf, "#   <op>[,<mode>] rx-low-drive <bit>   force a low-drive condition at this bit position\n");
-	seq_puts(sf, "#   <op>[,<mode>] rx-add-byte          add a spurious byte to the received CEC message\n");
-	seq_puts(sf, "#   <op>[,<mode>] rx-remove-byte       remove the last byte from the received CEC message\n");
-	seq_puts(sf, "#   <op>[,<mode>] rx-arb-lost <poll>   generate a POLL message to trigger an arbitration lost\n");
-	seq_puts(sf, "#\n");
-	seq_puts(sf, "# TX error injection settings:\n");
-	seq_puts(sf, "#   tx-ignore-nack-until-eom           ignore early NACKs until EOM\n");
-	seq_puts(sf, "#   tx-custom-low-usecs <usecs>        define the 'low' time for the custom pulse\n");
-	seq_puts(sf, "#   tx-custom-high-usecs <usecs>       define the 'high' time for the custom pulse\n");
-	seq_puts(sf, "#   tx-custom-pulse                    transmit the custom pulse once the bus is idle\n");
-	seq_puts(sf, "#\n");
-	seq_puts(sf, "# TX error injection:\n");
-	seq_puts(sf, "#   <op>[,<mode>] tx-no-eom            don't set the EOM bit\n");
-	seq_puts(sf, "#   <op>[,<mode>] tx-early-eom         set the EOM bit one byte too soon\n");
-	seq_puts(sf, "#   <op>[,<mode>] tx-add-bytes <num>   append <num> (1-255) spurious bytes to the message\n");
-	seq_puts(sf, "#   <op>[,<mode>] tx-remove-byte       drop the last byte from the message\n");
-	seq_puts(sf, "#   <op>[,<mode>] tx-short-bit <bit>   make this bit shorter than allowed\n");
-	seq_puts(sf, "#   <op>[,<mode>] tx-long-bit <bit>    make this bit longer than allowed\n");
-	seq_puts(sf, "#   <op>[,<mode>] tx-custom-bit <bit>  send the custom pulse instead of this bit\n");
-	seq_puts(sf, "#   <op>[,<mode>] tx-short-start       send a start pulse that's too short\n");
-	seq_puts(sf, "#   <op>[,<mode>] tx-long-start        send a start pulse that's too long\n");
-	seq_puts(sf, "#   <op>[,<mode>] tx-custom-start      send the custom pulse instead of the start pulse\n");
-	seq_puts(sf, "#   <op>[,<mode>] tx-last-bit <bit>    stop sending after this bit\n");
-	seq_puts(sf, "#   <op>[,<mode>] tx-low-drive <bit>   force a low-drive condition at this bit position\n");
-	seq_puts(sf, "#\n");
-	seq_puts(sf, "# <op>       CEC message opcode (0-255) or 'any'\n");
-	seq_puts(sf, "# <mode>     'once' (default), 'always', 'toggle' or 'off'\n");
-	seq_puts(sf, "# <bit>      CEC message bit (0-159)\n");
-	seq_puts(sf, "#            10 bits per 'byte': bits 0-7: data, bit 8: EOM, bit 9: ACK\n");
-	seq_puts(sf, "# <poll>     CEC poll message used to test arbitration lost (0x00-0xff, default 0x0f)\n");
-	seq_puts(sf, "# <usecs>    microseconds (0-10000000, default 1000)\n");
-
-	seq_puts(sf, "\nclear\n");
-
-	for (i = 0; i < ARRAY_SIZE(pin->error_inj); i++) {
-		u64 e = pin->error_inj[i];
-
-		for (j = 0; cec_error_inj_cmds[j].cmd; j++) {
-			const char *cmd = cec_error_inj_cmds[j].cmd;
-			unsigned int mode;
-			unsigned int mode_offset;
-			int arg_idx;
-
-			mode_offset = cec_error_inj_cmds[j].mode_offset;
-			arg_idx = cec_error_inj_cmds[j].arg_idx;
-			mode = (e >> mode_offset) & CEC_ERROR_INJ_MODE_MASK;
-			if (!mode)
-				continue;
-			cec_pin_show_cmd(sf, i, mode);
-			seq_puts(sf, cmd);
-			if (arg_idx >= 0)
-				seq_printf(sf, " %u",
-					   pin->error_inj_args[i][arg_idx]);
-			seq_puts(sf, "\n");
-		}
-	}
-
-	if (pin->tx_ignore_nack_until_eom)
-		seq_puts(sf, "tx-ignore-nack-until-eom\n");
-	if (pin->tx_custom_pulse)
-		seq_puts(sf, "tx-custom-pulse\n");
-	if (pin->tx_custom_low_usecs != CEC_TIM_CUSTOM_DEFAULT)
-		seq_printf(sf, "tx-custom-low-usecs %u\n",
-			   pin->tx_custom_low_usecs);
-	if (pin->tx_custom_high_usecs != CEC_TIM_CUSTOM_DEFAULT)
-		seq_printf(sf, "tx-custom-high-usecs %u\n",
-			   pin->tx_custom_high_usecs);
-	return 0;
-}
diff --git a/drivers/media/cec/cec-pin-priv.h b/drivers/media/cec/cec-pin-priv.h
deleted file mode 100644
index f423db8855d9..000000000000
--- a/drivers/media/cec/cec-pin-priv.h
+++ /dev/null
@@ -1,241 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * cec-pin-priv.h - internal cec-pin header
- *
- * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#ifndef LINUX_CEC_PIN_PRIV_H
-#define LINUX_CEC_PIN_PRIV_H
-
-#include <linux/types.h>
-#include <linux/atomic.h>
-#include <media/cec-pin.h>
-
-enum cec_pin_state {
-	/* CEC is off */
-	CEC_ST_OFF,
-	/* CEC is idle, waiting for Rx or Tx */
-	CEC_ST_IDLE,
-
-	/* Tx states */
-
-	/* Pending Tx, waiting for Signal Free Time to expire */
-	CEC_ST_TX_WAIT,
-	/* Low-drive was detected, wait for bus to go high */
-	CEC_ST_TX_WAIT_FOR_HIGH,
-	/* Drive CEC low for the start bit */
-	CEC_ST_TX_START_BIT_LOW,
-	/* Drive CEC high for the start bit */
-	CEC_ST_TX_START_BIT_HIGH,
-	/* Generate a start bit period that is too short */
-	CEC_ST_TX_START_BIT_HIGH_SHORT,
-	/* Generate a start bit period that is too long */
-	CEC_ST_TX_START_BIT_HIGH_LONG,
-	/* Drive CEC low for the start bit using the custom timing */
-	CEC_ST_TX_START_BIT_LOW_CUSTOM,
-	/* Drive CEC high for the start bit using the custom timing */
-	CEC_ST_TX_START_BIT_HIGH_CUSTOM,
-	/* Drive CEC low for the 0 bit */
-	CEC_ST_TX_DATA_BIT_0_LOW,
-	/* Drive CEC high for the 0 bit */
-	CEC_ST_TX_DATA_BIT_0_HIGH,
-	/* Generate a bit period that is too short */
-	CEC_ST_TX_DATA_BIT_0_HIGH_SHORT,
-	/* Generate a bit period that is too long */
-	CEC_ST_TX_DATA_BIT_0_HIGH_LONG,
-	/* Drive CEC low for the 1 bit */
-	CEC_ST_TX_DATA_BIT_1_LOW,
-	/* Drive CEC high for the 1 bit */
-	CEC_ST_TX_DATA_BIT_1_HIGH,
-	/* Generate a bit period that is too short */
-	CEC_ST_TX_DATA_BIT_1_HIGH_SHORT,
-	/* Generate a bit period that is too long */
-	CEC_ST_TX_DATA_BIT_1_HIGH_LONG,
-	/*
-	 * Wait for start of sample time to check for Ack bit or first
-	 * four initiator bits to check for Arbitration Lost.
-	 */
-	CEC_ST_TX_DATA_BIT_1_HIGH_PRE_SAMPLE,
-	/* Wait for end of bit period after sampling */
-	CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE,
-	/* Generate a bit period that is too short */
-	CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE_SHORT,
-	/* Generate a bit period that is too long */
-	CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE_LONG,
-	/* Drive CEC low for a data bit using the custom timing */
-	CEC_ST_TX_DATA_BIT_LOW_CUSTOM,
-	/* Drive CEC high for a data bit using the custom timing */
-	CEC_ST_TX_DATA_BIT_HIGH_CUSTOM,
-	/* Drive CEC low for a standalone pulse using the custom timing */
-	CEC_ST_TX_PULSE_LOW_CUSTOM,
-	/* Drive CEC high for a standalone pulse using the custom timing */
-	CEC_ST_TX_PULSE_HIGH_CUSTOM,
-	/* Start low drive */
-	CEC_ST_TX_LOW_DRIVE,
-
-	/* Rx states */
-
-	/* Start bit low detected */
-	CEC_ST_RX_START_BIT_LOW,
-	/* Start bit high detected */
-	CEC_ST_RX_START_BIT_HIGH,
-	/* Wait for bit sample time */
-	CEC_ST_RX_DATA_SAMPLE,
-	/* Wait for earliest end of bit period after sampling */
-	CEC_ST_RX_DATA_POST_SAMPLE,
-	/* Wait for CEC to go low (i.e. end of bit period) */
-	CEC_ST_RX_DATA_WAIT_FOR_LOW,
-	/* Drive CEC low to send 0 Ack bit */
-	CEC_ST_RX_ACK_LOW,
-	/* End of 0 Ack time, wait for earliest end of bit period */
-	CEC_ST_RX_ACK_LOW_POST,
-	/* Wait for CEC to go high (i.e. end of bit period */
-	CEC_ST_RX_ACK_HIGH_POST,
-	/* Wait for earliest end of bit period and end of message */
-	CEC_ST_RX_ACK_FINISH,
-	/* Start low drive */
-	CEC_ST_RX_LOW_DRIVE,
-
-	/* Monitor pin using interrupts */
-	CEC_ST_RX_IRQ,
-
-	/* Total number of pin states */
-	CEC_PIN_STATES
-};
-
-/* Error Injection */
-
-/* Error injection modes */
-#define CEC_ERROR_INJ_MODE_OFF				0
-#define CEC_ERROR_INJ_MODE_ONCE				1
-#define CEC_ERROR_INJ_MODE_ALWAYS			2
-#define CEC_ERROR_INJ_MODE_TOGGLE			3
-#define CEC_ERROR_INJ_MODE_MASK				3ULL
-
-/* Receive error injection options */
-#define CEC_ERROR_INJ_RX_NACK_OFFSET			0
-#define CEC_ERROR_INJ_RX_LOW_DRIVE_OFFSET		2
-#define CEC_ERROR_INJ_RX_ADD_BYTE_OFFSET		4
-#define CEC_ERROR_INJ_RX_REMOVE_BYTE_OFFSET		6
-#define CEC_ERROR_INJ_RX_ARB_LOST_OFFSET		8
-#define CEC_ERROR_INJ_RX_MASK				0xffffULL
-
-/* Transmit error injection options */
-#define CEC_ERROR_INJ_TX_NO_EOM_OFFSET			16
-#define CEC_ERROR_INJ_TX_EARLY_EOM_OFFSET		18
-#define CEC_ERROR_INJ_TX_SHORT_BIT_OFFSET		20
-#define CEC_ERROR_INJ_TX_LONG_BIT_OFFSET		22
-#define CEC_ERROR_INJ_TX_CUSTOM_BIT_OFFSET		24
-#define CEC_ERROR_INJ_TX_SHORT_START_OFFSET		26
-#define CEC_ERROR_INJ_TX_LONG_START_OFFSET		28
-#define CEC_ERROR_INJ_TX_CUSTOM_START_OFFSET		30
-#define CEC_ERROR_INJ_TX_LAST_BIT_OFFSET		32
-#define CEC_ERROR_INJ_TX_ADD_BYTES_OFFSET		34
-#define CEC_ERROR_INJ_TX_REMOVE_BYTE_OFFSET		36
-#define CEC_ERROR_INJ_TX_LOW_DRIVE_OFFSET		38
-#define CEC_ERROR_INJ_TX_MASK				0xffffffffffff0000ULL
-
-#define CEC_ERROR_INJ_RX_LOW_DRIVE_ARG_IDX		0
-#define CEC_ERROR_INJ_RX_ARB_LOST_ARG_IDX		1
-
-#define CEC_ERROR_INJ_TX_ADD_BYTES_ARG_IDX		2
-#define CEC_ERROR_INJ_TX_SHORT_BIT_ARG_IDX		3
-#define CEC_ERROR_INJ_TX_LONG_BIT_ARG_IDX		4
-#define CEC_ERROR_INJ_TX_CUSTOM_BIT_ARG_IDX		5
-#define CEC_ERROR_INJ_TX_LAST_BIT_ARG_IDX		6
-#define CEC_ERROR_INJ_TX_LOW_DRIVE_ARG_IDX		7
-#define CEC_ERROR_INJ_NUM_ARGS				8
-
-/* Special CEC op values */
-#define CEC_ERROR_INJ_OP_ANY				0x00000100
-
-/* The default for the low/high time of the custom pulse */
-#define CEC_TIM_CUSTOM_DEFAULT				1000
-
-#define CEC_NUM_PIN_EVENTS				128
-#define CEC_PIN_EVENT_FL_IS_HIGH			(1 << 0)
-#define CEC_PIN_EVENT_FL_DROPPED			(1 << 1)
-
-#define CEC_PIN_IRQ_UNCHANGED	0
-#define CEC_PIN_IRQ_DISABLE	1
-#define CEC_PIN_IRQ_ENABLE	2
-
-struct cec_pin {
-	struct cec_adapter		*adap;
-	const struct cec_pin_ops	*ops;
-	struct task_struct		*kthread;
-	wait_queue_head_t		kthread_waitq;
-	struct hrtimer			timer;
-	ktime_t				ts;
-	unsigned int			wait_usecs;
-	u16				la_mask;
-	bool				enabled;
-	bool				monitor_all;
-	bool				rx_eom;
-	bool				enable_irq_failed;
-	enum cec_pin_state		state;
-	struct cec_msg			tx_msg;
-	u32				tx_bit;
-	bool				tx_nacked;
-	u32				tx_signal_free_time;
-	bool				tx_toggle;
-	struct cec_msg			rx_msg;
-	u32				rx_bit;
-	bool				rx_toggle;
-	u32				rx_start_bit_low_too_short_cnt;
-	u64				rx_start_bit_low_too_short_ts;
-	u32				rx_start_bit_low_too_short_delta;
-	u32				rx_start_bit_too_short_cnt;
-	u64				rx_start_bit_too_short_ts;
-	u32				rx_start_bit_too_short_delta;
-	u32				rx_start_bit_too_long_cnt;
-	u32				rx_data_bit_too_short_cnt;
-	u64				rx_data_bit_too_short_ts;
-	u32				rx_data_bit_too_short_delta;
-	u32				rx_data_bit_too_long_cnt;
-	u32				rx_low_drive_cnt;
-
-	struct cec_msg			work_rx_msg;
-	u8				work_tx_status;
-	ktime_t				work_tx_ts;
-	atomic_t			work_irq_change;
-	atomic_t			work_pin_num_events;
-	unsigned int			work_pin_events_wr;
-	unsigned int			work_pin_events_rd;
-	ktime_t				work_pin_ts[CEC_NUM_PIN_EVENTS];
-	u8				work_pin_events[CEC_NUM_PIN_EVENTS];
-	bool				work_pin_events_dropped;
-	u32				work_pin_events_dropped_cnt;
-	ktime_t				timer_ts;
-	u32				timer_cnt;
-	u32				timer_100ms_overruns;
-	u32				timer_300ms_overruns;
-	u32				timer_max_overrun;
-	u32				timer_sum_overrun;
-
-	u32				tx_custom_low_usecs;
-	u32				tx_custom_high_usecs;
-	bool				tx_ignore_nack_until_eom;
-	bool				tx_custom_pulse;
-	bool				tx_generated_poll;
-	bool				tx_post_eom;
-	u8				tx_extra_bytes;
-	u32				tx_low_drive_cnt;
-#ifdef CONFIG_CEC_PIN_ERROR_INJ
-	u64				error_inj[CEC_ERROR_INJ_OP_ANY + 1];
-	u8				error_inj_args[CEC_ERROR_INJ_OP_ANY + 1][CEC_ERROR_INJ_NUM_ARGS];
-#endif
-};
-
-void cec_pin_start_timer(struct cec_pin *pin);
-
-#ifdef CONFIG_CEC_PIN_ERROR_INJ
-bool cec_pin_error_inj_parse_line(struct cec_adapter *adap, char *line);
-int cec_pin_error_inj_show(struct cec_adapter *adap, struct seq_file *sf);
-
-u16 cec_pin_rx_error_inj(struct cec_pin *pin);
-u16 cec_pin_tx_error_inj(struct cec_pin *pin);
-#endif
-
-#endif
diff --git a/drivers/media/cec/cec-pin.c b/drivers/media/cec/cec-pin.c
deleted file mode 100644
index 660fe111f540..000000000000
--- a/drivers/media/cec/cec-pin.c
+++ /dev/null
@@ -1,1345 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/sched/types.h>
-
-#include <media/cec-pin.h>
-#include "cec-pin-priv.h"
-
-/* All timings are in microseconds */
-
-/* start bit timings */
-#define CEC_TIM_START_BIT_LOW		3700
-#define CEC_TIM_START_BIT_LOW_MIN	3500
-#define CEC_TIM_START_BIT_LOW_MAX	3900
-#define CEC_TIM_START_BIT_TOTAL		4500
-#define CEC_TIM_START_BIT_TOTAL_MIN	4300
-#define CEC_TIM_START_BIT_TOTAL_MAX	4700
-
-/* data bit timings */
-#define CEC_TIM_DATA_BIT_0_LOW		1500
-#define CEC_TIM_DATA_BIT_0_LOW_MIN	1300
-#define CEC_TIM_DATA_BIT_0_LOW_MAX	1700
-#define CEC_TIM_DATA_BIT_1_LOW		600
-#define CEC_TIM_DATA_BIT_1_LOW_MIN	400
-#define CEC_TIM_DATA_BIT_1_LOW_MAX	800
-#define CEC_TIM_DATA_BIT_TOTAL		2400
-#define CEC_TIM_DATA_BIT_TOTAL_MIN	2050
-#define CEC_TIM_DATA_BIT_TOTAL_MAX	2750
-/* earliest safe time to sample the bit state */
-#define CEC_TIM_DATA_BIT_SAMPLE		850
-/* earliest time the bit is back to 1 (T7 + 50) */
-#define CEC_TIM_DATA_BIT_HIGH		1750
-
-/* when idle, sample once per millisecond */
-#define CEC_TIM_IDLE_SAMPLE		1000
-/* when processing the start bit, sample twice per millisecond */
-#define CEC_TIM_START_BIT_SAMPLE	500
-/* when polling for a state change, sample once every 50 microseconds */
-#define CEC_TIM_SAMPLE			50
-
-#define CEC_TIM_LOW_DRIVE_ERROR		(1.5 * CEC_TIM_DATA_BIT_TOTAL)
-
-/*
- * Total data bit time that is too short/long for a valid bit,
- * used for error injection.
- */
-#define CEC_TIM_DATA_BIT_TOTAL_SHORT	1800
-#define CEC_TIM_DATA_BIT_TOTAL_LONG	2900
-
-/*
- * Total start bit time that is too short/long for a valid bit,
- * used for error injection.
- */
-#define CEC_TIM_START_BIT_TOTAL_SHORT	4100
-#define CEC_TIM_START_BIT_TOTAL_LONG	5000
-
-/* Data bits are 0-7, EOM is bit 8 and ACK is bit 9 */
-#define EOM_BIT				8
-#define ACK_BIT				9
-
-struct cec_state {
-	const char * const name;
-	unsigned int usecs;
-};
-
-static const struct cec_state states[CEC_PIN_STATES] = {
-	{ "Off",		   0 },
-	{ "Idle",		   CEC_TIM_IDLE_SAMPLE },
-	{ "Tx Wait",		   CEC_TIM_SAMPLE },
-	{ "Tx Wait for High",	   CEC_TIM_IDLE_SAMPLE },
-	{ "Tx Start Bit Low",	   CEC_TIM_START_BIT_LOW },
-	{ "Tx Start Bit High",	   CEC_TIM_START_BIT_TOTAL - CEC_TIM_START_BIT_LOW },
-	{ "Tx Start Bit High Short", CEC_TIM_START_BIT_TOTAL_SHORT - CEC_TIM_START_BIT_LOW },
-	{ "Tx Start Bit High Long", CEC_TIM_START_BIT_TOTAL_LONG - CEC_TIM_START_BIT_LOW },
-	{ "Tx Start Bit Low Custom", 0 },
-	{ "Tx Start Bit High Custom", 0 },
-	{ "Tx Data 0 Low",	   CEC_TIM_DATA_BIT_0_LOW },
-	{ "Tx Data 0 High",	   CEC_TIM_DATA_BIT_TOTAL - CEC_TIM_DATA_BIT_0_LOW },
-	{ "Tx Data 0 High Short",  CEC_TIM_DATA_BIT_TOTAL_SHORT - CEC_TIM_DATA_BIT_0_LOW },
-	{ "Tx Data 0 High Long",   CEC_TIM_DATA_BIT_TOTAL_LONG - CEC_TIM_DATA_BIT_0_LOW },
-	{ "Tx Data 1 Low",	   CEC_TIM_DATA_BIT_1_LOW },
-	{ "Tx Data 1 High",	   CEC_TIM_DATA_BIT_TOTAL - CEC_TIM_DATA_BIT_1_LOW },
-	{ "Tx Data 1 High Short",  CEC_TIM_DATA_BIT_TOTAL_SHORT - CEC_TIM_DATA_BIT_1_LOW },
-	{ "Tx Data 1 High Long",   CEC_TIM_DATA_BIT_TOTAL_LONG - CEC_TIM_DATA_BIT_1_LOW },
-	{ "Tx Data 1 High Pre Sample", CEC_TIM_DATA_BIT_SAMPLE - CEC_TIM_DATA_BIT_1_LOW },
-	{ "Tx Data 1 High Post Sample", CEC_TIM_DATA_BIT_TOTAL - CEC_TIM_DATA_BIT_SAMPLE },
-	{ "Tx Data 1 High Post Sample Short", CEC_TIM_DATA_BIT_TOTAL_SHORT - CEC_TIM_DATA_BIT_SAMPLE },
-	{ "Tx Data 1 High Post Sample Long", CEC_TIM_DATA_BIT_TOTAL_LONG - CEC_TIM_DATA_BIT_SAMPLE },
-	{ "Tx Data Bit Low Custom", 0 },
-	{ "Tx Data Bit High Custom", 0 },
-	{ "Tx Pulse Low Custom",   0 },
-	{ "Tx Pulse High Custom",  0 },
-	{ "Tx Low Drive",	   CEC_TIM_LOW_DRIVE_ERROR },
-	{ "Rx Start Bit Low",	   CEC_TIM_SAMPLE },
-	{ "Rx Start Bit High",	   CEC_TIM_SAMPLE },
-	{ "Rx Data Sample",	   CEC_TIM_DATA_BIT_SAMPLE },
-	{ "Rx Data Post Sample",   CEC_TIM_DATA_BIT_HIGH - CEC_TIM_DATA_BIT_SAMPLE },
-	{ "Rx Data Wait for Low",  CEC_TIM_SAMPLE },
-	{ "Rx Ack Low",		   CEC_TIM_DATA_BIT_0_LOW },
-	{ "Rx Ack Low Post",	   CEC_TIM_DATA_BIT_HIGH - CEC_TIM_DATA_BIT_0_LOW },
-	{ "Rx Ack High Post",	   CEC_TIM_DATA_BIT_HIGH },
-	{ "Rx Ack Finish",	   CEC_TIM_DATA_BIT_TOTAL_MIN - CEC_TIM_DATA_BIT_HIGH },
-	{ "Rx Low Drive",	   CEC_TIM_LOW_DRIVE_ERROR },
-	{ "Rx Irq",		   0 },
-};
-
-static void cec_pin_update(struct cec_pin *pin, bool v, bool force)
-{
-	if (!force && v == pin->adap->cec_pin_is_high)
-		return;
-
-	pin->adap->cec_pin_is_high = v;
-	if (atomic_read(&pin->work_pin_num_events) < CEC_NUM_PIN_EVENTS) {
-		u8 ev = v;
-
-		if (pin->work_pin_events_dropped) {
-			pin->work_pin_events_dropped = false;
-			ev |= CEC_PIN_EVENT_FL_DROPPED;
-		}
-		pin->work_pin_events[pin->work_pin_events_wr] = ev;
-		pin->work_pin_ts[pin->work_pin_events_wr] = ktime_get();
-		pin->work_pin_events_wr =
-			(pin->work_pin_events_wr + 1) % CEC_NUM_PIN_EVENTS;
-		atomic_inc(&pin->work_pin_num_events);
-	} else {
-		pin->work_pin_events_dropped = true;
-		pin->work_pin_events_dropped_cnt++;
-	}
-	wake_up_interruptible(&pin->kthread_waitq);
-}
-
-static bool cec_pin_read(struct cec_pin *pin)
-{
-	bool v = pin->ops->read(pin->adap);
-
-	cec_pin_update(pin, v, false);
-	return v;
-}
-
-static void cec_pin_low(struct cec_pin *pin)
-{
-	pin->ops->low(pin->adap);
-	cec_pin_update(pin, false, false);
-}
-
-static bool cec_pin_high(struct cec_pin *pin)
-{
-	pin->ops->high(pin->adap);
-	return cec_pin_read(pin);
-}
-
-static bool rx_error_inj(struct cec_pin *pin, unsigned int mode_offset,
-			 int arg_idx, u8 *arg)
-{
-#ifdef CONFIG_CEC_PIN_ERROR_INJ
-	u16 cmd = cec_pin_rx_error_inj(pin);
-	u64 e = pin->error_inj[cmd];
-	unsigned int mode = (e >> mode_offset) & CEC_ERROR_INJ_MODE_MASK;
-
-	if (arg_idx >= 0) {
-		u8 pos = pin->error_inj_args[cmd][arg_idx];
-
-		if (arg)
-			*arg = pos;
-		else if (pos != pin->rx_bit)
-			return false;
-	}
-
-	switch (mode) {
-	case CEC_ERROR_INJ_MODE_ONCE:
-		pin->error_inj[cmd] &=
-			~(CEC_ERROR_INJ_MODE_MASK << mode_offset);
-		return true;
-	case CEC_ERROR_INJ_MODE_ALWAYS:
-		return true;
-	case CEC_ERROR_INJ_MODE_TOGGLE:
-		return pin->rx_toggle;
-	default:
-		return false;
-	}
-#else
-	return false;
-#endif
-}
-
-static bool rx_nack(struct cec_pin *pin)
-{
-	return rx_error_inj(pin, CEC_ERROR_INJ_RX_NACK_OFFSET, -1, NULL);
-}
-
-static bool rx_low_drive(struct cec_pin *pin)
-{
-	return rx_error_inj(pin, CEC_ERROR_INJ_RX_LOW_DRIVE_OFFSET,
-			    CEC_ERROR_INJ_RX_LOW_DRIVE_ARG_IDX, NULL);
-}
-
-static bool rx_add_byte(struct cec_pin *pin)
-{
-	return rx_error_inj(pin, CEC_ERROR_INJ_RX_ADD_BYTE_OFFSET, -1, NULL);
-}
-
-static bool rx_remove_byte(struct cec_pin *pin)
-{
-	return rx_error_inj(pin, CEC_ERROR_INJ_RX_REMOVE_BYTE_OFFSET, -1, NULL);
-}
-
-static bool rx_arb_lost(struct cec_pin *pin, u8 *poll)
-{
-	return pin->tx_msg.len == 0 &&
-		rx_error_inj(pin, CEC_ERROR_INJ_RX_ARB_LOST_OFFSET,
-			     CEC_ERROR_INJ_RX_ARB_LOST_ARG_IDX, poll);
-}
-
-static bool tx_error_inj(struct cec_pin *pin, unsigned int mode_offset,
-			 int arg_idx, u8 *arg)
-{
-#ifdef CONFIG_CEC_PIN_ERROR_INJ
-	u16 cmd = cec_pin_tx_error_inj(pin);
-	u64 e = pin->error_inj[cmd];
-	unsigned int mode = (e >> mode_offset) & CEC_ERROR_INJ_MODE_MASK;
-
-	if (arg_idx >= 0) {
-		u8 pos = pin->error_inj_args[cmd][arg_idx];
-
-		if (arg)
-			*arg = pos;
-		else if (pos != pin->tx_bit)
-			return false;
-	}
-
-	switch (mode) {
-	case CEC_ERROR_INJ_MODE_ONCE:
-		pin->error_inj[cmd] &=
-			~(CEC_ERROR_INJ_MODE_MASK << mode_offset);
-		return true;
-	case CEC_ERROR_INJ_MODE_ALWAYS:
-		return true;
-	case CEC_ERROR_INJ_MODE_TOGGLE:
-		return pin->tx_toggle;
-	default:
-		return false;
-	}
-#else
-	return false;
-#endif
-}
-
-static bool tx_no_eom(struct cec_pin *pin)
-{
-	return tx_error_inj(pin, CEC_ERROR_INJ_TX_NO_EOM_OFFSET, -1, NULL);
-}
-
-static bool tx_early_eom(struct cec_pin *pin)
-{
-	return tx_error_inj(pin, CEC_ERROR_INJ_TX_EARLY_EOM_OFFSET, -1, NULL);
-}
-
-static bool tx_short_bit(struct cec_pin *pin)
-{
-	return tx_error_inj(pin, CEC_ERROR_INJ_TX_SHORT_BIT_OFFSET,
-			    CEC_ERROR_INJ_TX_SHORT_BIT_ARG_IDX, NULL);
-}
-
-static bool tx_long_bit(struct cec_pin *pin)
-{
-	return tx_error_inj(pin, CEC_ERROR_INJ_TX_LONG_BIT_OFFSET,
-			    CEC_ERROR_INJ_TX_LONG_BIT_ARG_IDX, NULL);
-}
-
-static bool tx_custom_bit(struct cec_pin *pin)
-{
-	return tx_error_inj(pin, CEC_ERROR_INJ_TX_CUSTOM_BIT_OFFSET,
-			    CEC_ERROR_INJ_TX_CUSTOM_BIT_ARG_IDX, NULL);
-}
-
-static bool tx_short_start(struct cec_pin *pin)
-{
-	return tx_error_inj(pin, CEC_ERROR_INJ_TX_SHORT_START_OFFSET, -1, NULL);
-}
-
-static bool tx_long_start(struct cec_pin *pin)
-{
-	return tx_error_inj(pin, CEC_ERROR_INJ_TX_LONG_START_OFFSET, -1, NULL);
-}
-
-static bool tx_custom_start(struct cec_pin *pin)
-{
-	return tx_error_inj(pin, CEC_ERROR_INJ_TX_CUSTOM_START_OFFSET,
-			    -1, NULL);
-}
-
-static bool tx_last_bit(struct cec_pin *pin)
-{
-	return tx_error_inj(pin, CEC_ERROR_INJ_TX_LAST_BIT_OFFSET,
-			    CEC_ERROR_INJ_TX_LAST_BIT_ARG_IDX, NULL);
-}
-
-static u8 tx_add_bytes(struct cec_pin *pin)
-{
-	u8 bytes;
-
-	if (tx_error_inj(pin, CEC_ERROR_INJ_TX_ADD_BYTES_OFFSET,
-			 CEC_ERROR_INJ_TX_ADD_BYTES_ARG_IDX, &bytes))
-		return bytes;
-	return 0;
-}
-
-static bool tx_remove_byte(struct cec_pin *pin)
-{
-	return tx_error_inj(pin, CEC_ERROR_INJ_TX_REMOVE_BYTE_OFFSET, -1, NULL);
-}
-
-static bool tx_low_drive(struct cec_pin *pin)
-{
-	return tx_error_inj(pin, CEC_ERROR_INJ_TX_LOW_DRIVE_OFFSET,
-			    CEC_ERROR_INJ_TX_LOW_DRIVE_ARG_IDX, NULL);
-}
-
-static void cec_pin_to_idle(struct cec_pin *pin)
-{
-	/*
-	 * Reset all status fields, release the bus and
-	 * go to idle state.
-	 */
-	pin->rx_bit = pin->tx_bit = 0;
-	pin->rx_msg.len = 0;
-	memset(pin->rx_msg.msg, 0, sizeof(pin->rx_msg.msg));
-	pin->ts = ns_to_ktime(0);
-	pin->tx_generated_poll = false;
-	pin->tx_post_eom = false;
-	if (pin->state >= CEC_ST_TX_WAIT &&
-	    pin->state <= CEC_ST_TX_LOW_DRIVE)
-		pin->tx_toggle ^= 1;
-	if (pin->state >= CEC_ST_RX_START_BIT_LOW &&
-	    pin->state <= CEC_ST_RX_LOW_DRIVE)
-		pin->rx_toggle ^= 1;
-	pin->state = CEC_ST_IDLE;
-}
-
-/*
- * Handle Transmit-related states
- *
- * Basic state changes when transmitting:
- *
- * Idle -> Tx Wait (waiting for the end of signal free time) ->
- *	Tx Start Bit Low -> Tx Start Bit High ->
- *
- *   Regular data bits + EOM:
- *	Tx Data 0 Low -> Tx Data 0 High ->
- *   or:
- *	Tx Data 1 Low -> Tx Data 1 High ->
- *
- *   First 4 data bits or Ack bit:
- *	Tx Data 0 Low -> Tx Data 0 High ->
- *   or:
- *	Tx Data 1 Low -> Tx Data 1 High -> Tx Data 1 Pre Sample ->
- *		Tx Data 1 Post Sample ->
- *
- *   After the last Ack go to Idle.
- *
- * If it detects a Low Drive condition then:
- *	Tx Wait For High -> Idle
- *
- * If it loses arbitration, then it switches to state Rx Data Post Sample.
- */
-static void cec_pin_tx_states(struct cec_pin *pin, ktime_t ts)
-{
-	bool v;
-	bool is_ack_bit, ack;
-
-	switch (pin->state) {
-	case CEC_ST_TX_WAIT_FOR_HIGH:
-		if (cec_pin_read(pin))
-			cec_pin_to_idle(pin);
-		break;
-
-	case CEC_ST_TX_START_BIT_LOW:
-		if (tx_short_start(pin)) {
-			/*
-			 * Error Injection: send an invalid (too short)
-			 * start pulse.
-			 */
-			pin->state = CEC_ST_TX_START_BIT_HIGH_SHORT;
-		} else if (tx_long_start(pin)) {
-			/*
-			 * Error Injection: send an invalid (too long)
-			 * start pulse.
-			 */
-			pin->state = CEC_ST_TX_START_BIT_HIGH_LONG;
-		} else {
-			pin->state = CEC_ST_TX_START_BIT_HIGH;
-		}
-		/* Generate start bit */
-		cec_pin_high(pin);
-		break;
-
-	case CEC_ST_TX_START_BIT_LOW_CUSTOM:
-		pin->state = CEC_ST_TX_START_BIT_HIGH_CUSTOM;
-		/* Generate start bit */
-		cec_pin_high(pin);
-		break;
-
-	case CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE:
-	case CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE_SHORT:
-	case CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE_LONG:
-		if (pin->tx_nacked) {
-			cec_pin_to_idle(pin);
-			pin->tx_msg.len = 0;
-			if (pin->tx_generated_poll)
-				break;
-			pin->work_tx_ts = ts;
-			pin->work_tx_status = CEC_TX_STATUS_NACK;
-			wake_up_interruptible(&pin->kthread_waitq);
-			break;
-		}
-		/* fall through */
-	case CEC_ST_TX_DATA_BIT_0_HIGH:
-	case CEC_ST_TX_DATA_BIT_0_HIGH_SHORT:
-	case CEC_ST_TX_DATA_BIT_0_HIGH_LONG:
-	case CEC_ST_TX_DATA_BIT_1_HIGH:
-	case CEC_ST_TX_DATA_BIT_1_HIGH_SHORT:
-	case CEC_ST_TX_DATA_BIT_1_HIGH_LONG:
-		/*
-		 * If the read value is 1, then all is OK, otherwise we have a
-		 * low drive condition.
-		 *
-		 * Special case: when we generate a poll message due to an
-		 * Arbitration Lost error injection, then ignore this since
-		 * the pin can actually be low in that case.
-		 */
-		if (!cec_pin_read(pin) && !pin->tx_generated_poll) {
-			/*
-			 * It's 0, so someone detected an error and pulled the
-			 * line low for 1.5 times the nominal bit period.
-			 */
-			pin->tx_msg.len = 0;
-			pin->state = CEC_ST_TX_WAIT_FOR_HIGH;
-			pin->work_tx_ts = ts;
-			pin->work_tx_status = CEC_TX_STATUS_LOW_DRIVE;
-			pin->tx_low_drive_cnt++;
-			wake_up_interruptible(&pin->kthread_waitq);
-			break;
-		}
-		/* fall through */
-	case CEC_ST_TX_DATA_BIT_HIGH_CUSTOM:
-		if (tx_last_bit(pin)) {
-			/* Error Injection: just stop sending after this bit */
-			cec_pin_to_idle(pin);
-			pin->tx_msg.len = 0;
-			if (pin->tx_generated_poll)
-				break;
-			pin->work_tx_ts = ts;
-			pin->work_tx_status = CEC_TX_STATUS_OK;
-			wake_up_interruptible(&pin->kthread_waitq);
-			break;
-		}
-		pin->tx_bit++;
-		/* fall through */
-	case CEC_ST_TX_START_BIT_HIGH:
-	case CEC_ST_TX_START_BIT_HIGH_SHORT:
-	case CEC_ST_TX_START_BIT_HIGH_LONG:
-	case CEC_ST_TX_START_BIT_HIGH_CUSTOM:
-		if (tx_low_drive(pin)) {
-			/* Error injection: go to low drive */
-			cec_pin_low(pin);
-			pin->state = CEC_ST_TX_LOW_DRIVE;
-			pin->tx_msg.len = 0;
-			if (pin->tx_generated_poll)
-				break;
-			pin->work_tx_ts = ts;
-			pin->work_tx_status = CEC_TX_STATUS_LOW_DRIVE;
-			pin->tx_low_drive_cnt++;
-			wake_up_interruptible(&pin->kthread_waitq);
-			break;
-		}
-		if (pin->tx_bit / 10 >= pin->tx_msg.len + pin->tx_extra_bytes) {
-			cec_pin_to_idle(pin);
-			pin->tx_msg.len = 0;
-			if (pin->tx_generated_poll)
-				break;
-			pin->work_tx_ts = ts;
-			pin->work_tx_status = CEC_TX_STATUS_OK;
-			wake_up_interruptible(&pin->kthread_waitq);
-			break;
-		}
-
-		switch (pin->tx_bit % 10) {
-		default: {
-			/*
-			 * In the CEC_ERROR_INJ_TX_ADD_BYTES case we transmit
-			 * extra bytes, so pin->tx_bit / 10 can become >= 16.
-			 * Generate bit values for those extra bytes instead
-			 * of reading them from the transmit buffer.
-			 */
-			unsigned int idx = (pin->tx_bit / 10);
-			u8 val = idx;
-
-			if (idx < pin->tx_msg.len)
-				val = pin->tx_msg.msg[idx];
-			v = val & (1 << (7 - (pin->tx_bit % 10)));
-
-			pin->state = v ? CEC_ST_TX_DATA_BIT_1_LOW :
-					 CEC_ST_TX_DATA_BIT_0_LOW;
-			break;
-		}
-		case EOM_BIT: {
-			unsigned int tot_len = pin->tx_msg.len +
-					       pin->tx_extra_bytes;
-			unsigned int tx_byte_idx = pin->tx_bit / 10;
-
-			v = !pin->tx_post_eom && tx_byte_idx == tot_len - 1;
-			if (tot_len > 1 && tx_byte_idx == tot_len - 2 &&
-			    tx_early_eom(pin)) {
-				/* Error injection: set EOM one byte early */
-				v = true;
-				pin->tx_post_eom = true;
-			} else if (v && tx_no_eom(pin)) {
-				/* Error injection: no EOM */
-				v = false;
-			}
-			pin->state = v ? CEC_ST_TX_DATA_BIT_1_LOW :
-					 CEC_ST_TX_DATA_BIT_0_LOW;
-			break;
-		}
-		case ACK_BIT:
-			pin->state = CEC_ST_TX_DATA_BIT_1_LOW;
-			break;
-		}
-		if (tx_custom_bit(pin))
-			pin->state = CEC_ST_TX_DATA_BIT_LOW_CUSTOM;
-		cec_pin_low(pin);
-		break;
-
-	case CEC_ST_TX_DATA_BIT_0_LOW:
-	case CEC_ST_TX_DATA_BIT_1_LOW:
-		v = pin->state == CEC_ST_TX_DATA_BIT_1_LOW;
-		is_ack_bit = pin->tx_bit % 10 == ACK_BIT;
-		if (v && (pin->tx_bit < 4 || is_ack_bit)) {
-			pin->state = CEC_ST_TX_DATA_BIT_1_HIGH_PRE_SAMPLE;
-		} else if (!is_ack_bit && tx_short_bit(pin)) {
-			/* Error Injection: send an invalid (too short) bit */
-			pin->state = v ? CEC_ST_TX_DATA_BIT_1_HIGH_SHORT :
-					 CEC_ST_TX_DATA_BIT_0_HIGH_SHORT;
-		} else if (!is_ack_bit && tx_long_bit(pin)) {
-			/* Error Injection: send an invalid (too long) bit */
-			pin->state = v ? CEC_ST_TX_DATA_BIT_1_HIGH_LONG :
-					 CEC_ST_TX_DATA_BIT_0_HIGH_LONG;
-		} else {
-			pin->state = v ? CEC_ST_TX_DATA_BIT_1_HIGH :
-					 CEC_ST_TX_DATA_BIT_0_HIGH;
-		}
-		cec_pin_high(pin);
-		break;
-
-	case CEC_ST_TX_DATA_BIT_LOW_CUSTOM:
-		pin->state = CEC_ST_TX_DATA_BIT_HIGH_CUSTOM;
-		cec_pin_high(pin);
-		break;
-
-	case CEC_ST_TX_DATA_BIT_1_HIGH_PRE_SAMPLE:
-		/* Read the CEC value at the sample time */
-		v = cec_pin_read(pin);
-		is_ack_bit = pin->tx_bit % 10 == ACK_BIT;
-		/*
-		 * If v == 0 and we're within the first 4 bits
-		 * of the initiator, then someone else started
-		 * transmitting and we lost the arbitration
-		 * (i.e. the logical address of the other
-		 * transmitter has more leading 0 bits in the
-		 * initiator).
-		 */
-		if (!v && !is_ack_bit && !pin->tx_generated_poll) {
-			pin->tx_msg.len = 0;
-			pin->work_tx_ts = ts;
-			pin->work_tx_status = CEC_TX_STATUS_ARB_LOST;
-			wake_up_interruptible(&pin->kthread_waitq);
-			pin->rx_bit = pin->tx_bit;
-			pin->tx_bit = 0;
-			memset(pin->rx_msg.msg, 0, sizeof(pin->rx_msg.msg));
-			pin->rx_msg.msg[0] = pin->tx_msg.msg[0];
-			pin->rx_msg.msg[0] &= (0xff << (8 - pin->rx_bit));
-			pin->rx_msg.len = 0;
-			pin->ts = ktime_sub_us(ts, CEC_TIM_DATA_BIT_SAMPLE);
-			pin->state = CEC_ST_RX_DATA_POST_SAMPLE;
-			pin->rx_bit++;
-			break;
-		}
-		pin->state = CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE;
-		if (!is_ack_bit && tx_short_bit(pin)) {
-			/* Error Injection: send an invalid (too short) bit */
-			pin->state = CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE_SHORT;
-		} else if (!is_ack_bit && tx_long_bit(pin)) {
-			/* Error Injection: send an invalid (too long) bit */
-			pin->state = CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE_LONG;
-		}
-		if (!is_ack_bit)
-			break;
-		/* Was the message ACKed? */
-		ack = cec_msg_is_broadcast(&pin->tx_msg) ? v : !v;
-		if (!ack && (!pin->tx_ignore_nack_until_eom ||
-		    pin->tx_bit / 10 == pin->tx_msg.len - 1) &&
-		    !pin->tx_post_eom) {
-			/*
-			 * Note: the CEC spec is ambiguous regarding
-			 * what action to take when a NACK appears
-			 * before the last byte of the payload was
-			 * transmitted: either stop transmitting
-			 * immediately, or wait until the last byte
-			 * was transmitted.
-			 *
-			 * Most CEC implementations appear to stop
-			 * immediately, and that's what we do here
-			 * as well.
-			 */
-			pin->tx_nacked = true;
-		}
-		break;
-
-	case CEC_ST_TX_PULSE_LOW_CUSTOM:
-		cec_pin_high(pin);
-		pin->state = CEC_ST_TX_PULSE_HIGH_CUSTOM;
-		break;
-
-	case CEC_ST_TX_PULSE_HIGH_CUSTOM:
-		cec_pin_to_idle(pin);
-		break;
-
-	default:
-		break;
-	}
-}
-
-/*
- * Handle Receive-related states
- *
- * Basic state changes when receiving:
- *
- *	Rx Start Bit Low -> Rx Start Bit High ->
- *   Regular data bits + EOM:
- *	Rx Data Sample -> Rx Data Post Sample -> Rx Data High ->
- *   Ack bit 0:
- *	Rx Ack Low -> Rx Ack Low Post -> Rx Data High ->
- *   Ack bit 1:
- *	Rx Ack High Post -> Rx Data High ->
- *   Ack bit 0 && EOM:
- *	Rx Ack Low -> Rx Ack Low Post -> Rx Ack Finish -> Idle
- */
-static void cec_pin_rx_states(struct cec_pin *pin, ktime_t ts)
-{
-	s32 delta;
-	bool v;
-	bool ack;
-	bool bcast, for_us;
-	u8 dest;
-	u8 poll;
-
-	switch (pin->state) {
-	/* Receive states */
-	case CEC_ST_RX_START_BIT_LOW:
-		v = cec_pin_read(pin);
-		if (!v)
-			break;
-		pin->state = CEC_ST_RX_START_BIT_HIGH;
-		delta = ktime_us_delta(ts, pin->ts);
-		/* Start bit low is too short, go back to idle */
-		if (delta < CEC_TIM_START_BIT_LOW_MIN - CEC_TIM_IDLE_SAMPLE) {
-			if (!pin->rx_start_bit_low_too_short_cnt++) {
-				pin->rx_start_bit_low_too_short_ts = ktime_to_ns(pin->ts);
-				pin->rx_start_bit_low_too_short_delta = delta;
-			}
-			cec_pin_to_idle(pin);
-			break;
-		}
-		if (rx_arb_lost(pin, &poll)) {
-			cec_msg_init(&pin->tx_msg, poll >> 4, poll & 0xf);
-			pin->tx_generated_poll = true;
-			pin->tx_extra_bytes = 0;
-			pin->state = CEC_ST_TX_START_BIT_HIGH;
-			pin->ts = ts;
-		}
-		break;
-
-	case CEC_ST_RX_START_BIT_HIGH:
-		v = cec_pin_read(pin);
-		delta = ktime_us_delta(ts, pin->ts);
-		/*
-		 * Unfortunately the spec does not specify when to give up
-		 * and go to idle. We just pick TOTAL_LONG.
-		 */
-		if (v && delta > CEC_TIM_START_BIT_TOTAL_LONG) {
-			pin->rx_start_bit_too_long_cnt++;
-			cec_pin_to_idle(pin);
-			break;
-		}
-		if (v)
-			break;
-		/* Start bit is too short, go back to idle */
-		if (delta < CEC_TIM_START_BIT_TOTAL_MIN - CEC_TIM_IDLE_SAMPLE) {
-			if (!pin->rx_start_bit_too_short_cnt++) {
-				pin->rx_start_bit_too_short_ts = ktime_to_ns(pin->ts);
-				pin->rx_start_bit_too_short_delta = delta;
-			}
-			cec_pin_to_idle(pin);
-			break;
-		}
-		if (rx_low_drive(pin)) {
-			/* Error injection: go to low drive */
-			cec_pin_low(pin);
-			pin->state = CEC_ST_RX_LOW_DRIVE;
-			pin->rx_low_drive_cnt++;
-			break;
-		}
-		pin->state = CEC_ST_RX_DATA_SAMPLE;
-		pin->ts = ts;
-		pin->rx_eom = false;
-		break;
-
-	case CEC_ST_RX_DATA_SAMPLE:
-		v = cec_pin_read(pin);
-		pin->state = CEC_ST_RX_DATA_POST_SAMPLE;
-		switch (pin->rx_bit % 10) {
-		default:
-			if (pin->rx_bit / 10 < CEC_MAX_MSG_SIZE)
-				pin->rx_msg.msg[pin->rx_bit / 10] |=
-					v << (7 - (pin->rx_bit % 10));
-			break;
-		case EOM_BIT:
-			pin->rx_eom = v;
-			pin->rx_msg.len = pin->rx_bit / 10 + 1;
-			break;
-		case ACK_BIT:
-			break;
-		}
-		pin->rx_bit++;
-		break;
-
-	case CEC_ST_RX_DATA_POST_SAMPLE:
-		pin->state = CEC_ST_RX_DATA_WAIT_FOR_LOW;
-		break;
-
-	case CEC_ST_RX_DATA_WAIT_FOR_LOW:
-		v = cec_pin_read(pin);
-		delta = ktime_us_delta(ts, pin->ts);
-		/*
-		 * Unfortunately the spec does not specify when to give up
-		 * and go to idle. We just pick TOTAL_LONG.
-		 */
-		if (v && delta > CEC_TIM_DATA_BIT_TOTAL_LONG) {
-			pin->rx_data_bit_too_long_cnt++;
-			cec_pin_to_idle(pin);
-			break;
-		}
-		if (v)
-			break;
-
-		if (rx_low_drive(pin)) {
-			/* Error injection: go to low drive */
-			cec_pin_low(pin);
-			pin->state = CEC_ST_RX_LOW_DRIVE;
-			pin->rx_low_drive_cnt++;
-			break;
-		}
-
-		/*
-		 * Go to low drive state when the total bit time is
-		 * too short.
-		 */
-		if (delta < CEC_TIM_DATA_BIT_TOTAL_MIN) {
-			if (!pin->rx_data_bit_too_short_cnt++) {
-				pin->rx_data_bit_too_short_ts = ktime_to_ns(pin->ts);
-				pin->rx_data_bit_too_short_delta = delta;
-			}
-			cec_pin_low(pin);
-			pin->state = CEC_ST_RX_LOW_DRIVE;
-			pin->rx_low_drive_cnt++;
-			break;
-		}
-		pin->ts = ts;
-		if (pin->rx_bit % 10 != 9) {
-			pin->state = CEC_ST_RX_DATA_SAMPLE;
-			break;
-		}
-
-		dest = cec_msg_destination(&pin->rx_msg);
-		bcast = dest == CEC_LOG_ADDR_BROADCAST;
-		/* for_us == broadcast or directed to us */
-		for_us = bcast || (pin->la_mask & (1 << dest));
-		/* ACK bit value */
-		ack = bcast ? 1 : !for_us;
-
-		if (for_us && rx_nack(pin)) {
-			/* Error injection: toggle the ACK bit */
-			ack = !ack;
-		}
-
-		if (ack) {
-			/* No need to write to the bus, just wait */
-			pin->state = CEC_ST_RX_ACK_HIGH_POST;
-			break;
-		}
-		cec_pin_low(pin);
-		pin->state = CEC_ST_RX_ACK_LOW;
-		break;
-
-	case CEC_ST_RX_ACK_LOW:
-		cec_pin_high(pin);
-		pin->state = CEC_ST_RX_ACK_LOW_POST;
-		break;
-
-	case CEC_ST_RX_ACK_LOW_POST:
-	case CEC_ST_RX_ACK_HIGH_POST:
-		v = cec_pin_read(pin);
-		if (v && pin->rx_eom) {
-			pin->work_rx_msg = pin->rx_msg;
-			pin->work_rx_msg.rx_ts = ktime_to_ns(ts);
-			wake_up_interruptible(&pin->kthread_waitq);
-			pin->ts = ts;
-			pin->state = CEC_ST_RX_ACK_FINISH;
-			break;
-		}
-		pin->rx_bit++;
-		pin->state = CEC_ST_RX_DATA_WAIT_FOR_LOW;
-		break;
-
-	case CEC_ST_RX_ACK_FINISH:
-		cec_pin_to_idle(pin);
-		break;
-
-	default:
-		break;
-	}
-}
-
-/*
- * Main timer function
- *
- */
-static enum hrtimer_restart cec_pin_timer(struct hrtimer *timer)
-{
-	struct cec_pin *pin = container_of(timer, struct cec_pin, timer);
-	struct cec_adapter *adap = pin->adap;
-	ktime_t ts;
-	s32 delta;
-	u32 usecs;
-
-	ts = ktime_get();
-	if (ktime_to_ns(pin->timer_ts)) {
-		delta = ktime_us_delta(ts, pin->timer_ts);
-		pin->timer_cnt++;
-		if (delta > 100 && pin->state != CEC_ST_IDLE) {
-			/* Keep track of timer overruns */
-			pin->timer_sum_overrun += delta;
-			pin->timer_100ms_overruns++;
-			if (delta > 300)
-				pin->timer_300ms_overruns++;
-			if (delta > pin->timer_max_overrun)
-				pin->timer_max_overrun = delta;
-		}
-	}
-	if (adap->monitor_pin_cnt)
-		cec_pin_read(pin);
-
-	if (pin->wait_usecs) {
-		/*
-		 * If we are monitoring the pin, then we have to
-		 * sample at regular intervals.
-		 */
-		if (pin->wait_usecs > 150) {
-			pin->wait_usecs -= 100;
-			pin->timer_ts = ktime_add_us(ts, 100);
-			hrtimer_forward_now(timer, ns_to_ktime(100000));
-			return HRTIMER_RESTART;
-		}
-		if (pin->wait_usecs > 100) {
-			pin->wait_usecs /= 2;
-			pin->timer_ts = ktime_add_us(ts, pin->wait_usecs);
-			hrtimer_forward_now(timer,
-					ns_to_ktime(pin->wait_usecs * 1000));
-			return HRTIMER_RESTART;
-		}
-		pin->timer_ts = ktime_add_us(ts, pin->wait_usecs);
-		hrtimer_forward_now(timer,
-				    ns_to_ktime(pin->wait_usecs * 1000));
-		pin->wait_usecs = 0;
-		return HRTIMER_RESTART;
-	}
-
-	switch (pin->state) {
-	/* Transmit states */
-	case CEC_ST_TX_WAIT_FOR_HIGH:
-	case CEC_ST_TX_START_BIT_LOW:
-	case CEC_ST_TX_START_BIT_HIGH:
-	case CEC_ST_TX_START_BIT_HIGH_SHORT:
-	case CEC_ST_TX_START_BIT_HIGH_LONG:
-	case CEC_ST_TX_START_BIT_LOW_CUSTOM:
-	case CEC_ST_TX_START_BIT_HIGH_CUSTOM:
-	case CEC_ST_TX_DATA_BIT_0_LOW:
-	case CEC_ST_TX_DATA_BIT_0_HIGH:
-	case CEC_ST_TX_DATA_BIT_0_HIGH_SHORT:
-	case CEC_ST_TX_DATA_BIT_0_HIGH_LONG:
-	case CEC_ST_TX_DATA_BIT_1_LOW:
-	case CEC_ST_TX_DATA_BIT_1_HIGH:
-	case CEC_ST_TX_DATA_BIT_1_HIGH_SHORT:
-	case CEC_ST_TX_DATA_BIT_1_HIGH_LONG:
-	case CEC_ST_TX_DATA_BIT_1_HIGH_PRE_SAMPLE:
-	case CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE:
-	case CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE_SHORT:
-	case CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE_LONG:
-	case CEC_ST_TX_DATA_BIT_LOW_CUSTOM:
-	case CEC_ST_TX_DATA_BIT_HIGH_CUSTOM:
-	case CEC_ST_TX_PULSE_LOW_CUSTOM:
-	case CEC_ST_TX_PULSE_HIGH_CUSTOM:
-		cec_pin_tx_states(pin, ts);
-		break;
-
-	/* Receive states */
-	case CEC_ST_RX_START_BIT_LOW:
-	case CEC_ST_RX_START_BIT_HIGH:
-	case CEC_ST_RX_DATA_SAMPLE:
-	case CEC_ST_RX_DATA_POST_SAMPLE:
-	case CEC_ST_RX_DATA_WAIT_FOR_LOW:
-	case CEC_ST_RX_ACK_LOW:
-	case CEC_ST_RX_ACK_LOW_POST:
-	case CEC_ST_RX_ACK_HIGH_POST:
-	case CEC_ST_RX_ACK_FINISH:
-		cec_pin_rx_states(pin, ts);
-		break;
-
-	case CEC_ST_IDLE:
-	case CEC_ST_TX_WAIT:
-		if (!cec_pin_high(pin)) {
-			/* Start bit, switch to receive state */
-			pin->ts = ts;
-			pin->state = CEC_ST_RX_START_BIT_LOW;
-			/*
-			 * If a transmit is pending, then that transmit should
-			 * use a signal free time of no more than
-			 * CEC_SIGNAL_FREE_TIME_NEW_INITIATOR since it will
-			 * have a new initiator due to the receive that is now
-			 * starting.
-			 */
-			if (pin->tx_msg.len && pin->tx_signal_free_time >
-			    CEC_SIGNAL_FREE_TIME_NEW_INITIATOR)
-				pin->tx_signal_free_time =
-					CEC_SIGNAL_FREE_TIME_NEW_INITIATOR;
-			break;
-		}
-		if (ktime_to_ns(pin->ts) == 0)
-			pin->ts = ts;
-		if (pin->tx_msg.len) {
-			/*
-			 * Check if the bus has been free for long enough
-			 * so we can kick off the pending transmit.
-			 */
-			delta = ktime_us_delta(ts, pin->ts);
-			if (delta / CEC_TIM_DATA_BIT_TOTAL >
-			    pin->tx_signal_free_time) {
-				pin->tx_nacked = false;
-				if (tx_custom_start(pin))
-					pin->state = CEC_ST_TX_START_BIT_LOW_CUSTOM;
-				else
-					pin->state = CEC_ST_TX_START_BIT_LOW;
-				/* Generate start bit */
-				cec_pin_low(pin);
-				break;
-			}
-			if (delta / CEC_TIM_DATA_BIT_TOTAL >
-			    pin->tx_signal_free_time - 1)
-				pin->state = CEC_ST_TX_WAIT;
-			break;
-		}
-		if (pin->tx_custom_pulse && pin->state == CEC_ST_IDLE) {
-			pin->tx_custom_pulse = false;
-			/* Generate custom pulse */
-			cec_pin_low(pin);
-			pin->state = CEC_ST_TX_PULSE_LOW_CUSTOM;
-			break;
-		}
-		if (pin->state != CEC_ST_IDLE || pin->ops->enable_irq == NULL ||
-		    pin->enable_irq_failed || adap->is_configuring ||
-		    adap->is_configured || adap->monitor_all_cnt)
-			break;
-		/* Switch to interrupt mode */
-		atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_ENABLE);
-		pin->state = CEC_ST_RX_IRQ;
-		wake_up_interruptible(&pin->kthread_waitq);
-		return HRTIMER_NORESTART;
-
-	case CEC_ST_TX_LOW_DRIVE:
-	case CEC_ST_RX_LOW_DRIVE:
-		cec_pin_high(pin);
-		cec_pin_to_idle(pin);
-		break;
-
-	default:
-		break;
-	}
-
-	switch (pin->state) {
-	case CEC_ST_TX_START_BIT_LOW_CUSTOM:
-	case CEC_ST_TX_DATA_BIT_LOW_CUSTOM:
-	case CEC_ST_TX_PULSE_LOW_CUSTOM:
-		usecs = pin->tx_custom_low_usecs;
-		break;
-	case CEC_ST_TX_START_BIT_HIGH_CUSTOM:
-	case CEC_ST_TX_DATA_BIT_HIGH_CUSTOM:
-	case CEC_ST_TX_PULSE_HIGH_CUSTOM:
-		usecs = pin->tx_custom_high_usecs;
-		break;
-	default:
-		usecs = states[pin->state].usecs;
-		break;
-	}
-
-	if (!adap->monitor_pin_cnt || usecs <= 150) {
-		pin->wait_usecs = 0;
-		pin->timer_ts = ktime_add_us(ts, usecs);
-		hrtimer_forward_now(timer,
-				ns_to_ktime(usecs * 1000));
-		return HRTIMER_RESTART;
-	}
-	pin->wait_usecs = usecs - 100;
-	pin->timer_ts = ktime_add_us(ts, 100);
-	hrtimer_forward_now(timer, ns_to_ktime(100000));
-	return HRTIMER_RESTART;
-}
-
-static int cec_pin_thread_func(void *_adap)
-{
-	struct cec_adapter *adap = _adap;
-	struct cec_pin *pin = adap->pin;
-
-	for (;;) {
-		wait_event_interruptible(pin->kthread_waitq,
-			kthread_should_stop() ||
-			pin->work_rx_msg.len ||
-			pin->work_tx_status ||
-			atomic_read(&pin->work_irq_change) ||
-			atomic_read(&pin->work_pin_num_events));
-
-		if (pin->work_rx_msg.len) {
-			struct cec_msg *msg = &pin->work_rx_msg;
-
-			if (msg->len > 1 && msg->len < CEC_MAX_MSG_SIZE &&
-			    rx_add_byte(pin)) {
-				/* Error injection: add byte to the message */
-				msg->msg[msg->len++] = 0x55;
-			}
-			if (msg->len > 2 && rx_remove_byte(pin)) {
-				/* Error injection: remove byte from message */
-				msg->len--;
-			}
-			if (msg->len > CEC_MAX_MSG_SIZE)
-				msg->len = CEC_MAX_MSG_SIZE;
-			cec_received_msg_ts(adap, msg,
-				ns_to_ktime(pin->work_rx_msg.rx_ts));
-			msg->len = 0;
-		}
-		if (pin->work_tx_status) {
-			unsigned int tx_status = pin->work_tx_status;
-
-			pin->work_tx_status = 0;
-			cec_transmit_attempt_done_ts(adap, tx_status,
-						     pin->work_tx_ts);
-		}
-
-		while (atomic_read(&pin->work_pin_num_events)) {
-			unsigned int idx = pin->work_pin_events_rd;
-			u8 v = pin->work_pin_events[idx];
-
-			cec_queue_pin_cec_event(adap,
-						v & CEC_PIN_EVENT_FL_IS_HIGH,
-						v & CEC_PIN_EVENT_FL_DROPPED,
-						pin->work_pin_ts[idx]);
-			pin->work_pin_events_rd = (idx + 1) % CEC_NUM_PIN_EVENTS;
-			atomic_dec(&pin->work_pin_num_events);
-		}
-
-		switch (atomic_xchg(&pin->work_irq_change,
-				    CEC_PIN_IRQ_UNCHANGED)) {
-		case CEC_PIN_IRQ_DISABLE:
-			pin->ops->disable_irq(adap);
-			cec_pin_high(pin);
-			cec_pin_to_idle(pin);
-			hrtimer_start(&pin->timer, ns_to_ktime(0),
-				      HRTIMER_MODE_REL);
-			break;
-		case CEC_PIN_IRQ_ENABLE:
-			pin->enable_irq_failed = !pin->ops->enable_irq(adap);
-			if (pin->enable_irq_failed) {
-				cec_pin_to_idle(pin);
-				hrtimer_start(&pin->timer, ns_to_ktime(0),
-					      HRTIMER_MODE_REL);
-			}
-			break;
-		default:
-			break;
-		}
-
-		if (kthread_should_stop())
-			break;
-	}
-	return 0;
-}
-
-static int cec_pin_adap_enable(struct cec_adapter *adap, bool enable)
-{
-	struct cec_pin *pin = adap->pin;
-
-	pin->enabled = enable;
-	if (enable) {
-		atomic_set(&pin->work_pin_num_events, 0);
-		pin->work_pin_events_rd = pin->work_pin_events_wr = 0;
-		pin->work_pin_events_dropped = false;
-		cec_pin_read(pin);
-		cec_pin_to_idle(pin);
-		pin->tx_msg.len = 0;
-		pin->timer_ts = ns_to_ktime(0);
-		atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_UNCHANGED);
-		pin->kthread = kthread_run(cec_pin_thread_func, adap,
-					   "cec-pin");
-		if (IS_ERR(pin->kthread)) {
-			pr_err("cec-pin: kernel_thread() failed\n");
-			return PTR_ERR(pin->kthread);
-		}
-		hrtimer_start(&pin->timer, ns_to_ktime(0),
-			      HRTIMER_MODE_REL);
-	} else {
-		if (pin->ops->disable_irq)
-			pin->ops->disable_irq(adap);
-		hrtimer_cancel(&pin->timer);
-		kthread_stop(pin->kthread);
-		cec_pin_read(pin);
-		cec_pin_to_idle(pin);
-		pin->state = CEC_ST_OFF;
-	}
-	return 0;
-}
-
-static int cec_pin_adap_log_addr(struct cec_adapter *adap, u8 log_addr)
-{
-	struct cec_pin *pin = adap->pin;
-
-	if (log_addr == CEC_LOG_ADDR_INVALID)
-		pin->la_mask = 0;
-	else
-		pin->la_mask |= (1 << log_addr);
-	return 0;
-}
-
-void cec_pin_start_timer(struct cec_pin *pin)
-{
-	if (pin->state != CEC_ST_RX_IRQ)
-		return;
-
-	atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_UNCHANGED);
-	pin->ops->disable_irq(pin->adap);
-	cec_pin_high(pin);
-	cec_pin_to_idle(pin);
-	hrtimer_start(&pin->timer, ns_to_ktime(0), HRTIMER_MODE_REL);
-}
-
-static int cec_pin_adap_transmit(struct cec_adapter *adap, u8 attempts,
-				      u32 signal_free_time, struct cec_msg *msg)
-{
-	struct cec_pin *pin = adap->pin;
-
-	/*
-	 * If a receive is in progress, then this transmit should use
-	 * a signal free time of max CEC_SIGNAL_FREE_TIME_NEW_INITIATOR
-	 * since when it starts transmitting it will have a new initiator.
-	 */
-	if (pin->state != CEC_ST_IDLE &&
-	    signal_free_time > CEC_SIGNAL_FREE_TIME_NEW_INITIATOR)
-		signal_free_time = CEC_SIGNAL_FREE_TIME_NEW_INITIATOR;
-
-	pin->tx_signal_free_time = signal_free_time;
-	pin->tx_extra_bytes = 0;
-	pin->tx_msg = *msg;
-	if (msg->len > 1) {
-		/* Error injection: add byte to the message */
-		pin->tx_extra_bytes = tx_add_bytes(pin);
-	}
-	if (msg->len > 2 && tx_remove_byte(pin)) {
-		/* Error injection: remove byte from the message */
-		pin->tx_msg.len--;
-	}
-	pin->work_tx_status = 0;
-	pin->tx_bit = 0;
-	cec_pin_start_timer(pin);
-	return 0;
-}
-
-static void cec_pin_adap_status(struct cec_adapter *adap,
-				       struct seq_file *file)
-{
-	struct cec_pin *pin = adap->pin;
-
-	seq_printf(file, "state: %s\n", states[pin->state].name);
-	seq_printf(file, "tx_bit: %d\n", pin->tx_bit);
-	seq_printf(file, "rx_bit: %d\n", pin->rx_bit);
-	seq_printf(file, "cec pin: %d\n", pin->ops->read(adap));
-	seq_printf(file, "cec pin events dropped: %u\n",
-		   pin->work_pin_events_dropped_cnt);
-	seq_printf(file, "irq failed: %d\n", pin->enable_irq_failed);
-	if (pin->timer_100ms_overruns) {
-		seq_printf(file, "timer overruns > 100ms: %u of %u\n",
-			   pin->timer_100ms_overruns, pin->timer_cnt);
-		seq_printf(file, "timer overruns > 300ms: %u of %u\n",
-			   pin->timer_300ms_overruns, pin->timer_cnt);
-		seq_printf(file, "max timer overrun: %u usecs\n",
-			   pin->timer_max_overrun);
-		seq_printf(file, "avg timer overrun: %u usecs\n",
-			   pin->timer_sum_overrun / pin->timer_100ms_overruns);
-	}
-	if (pin->rx_start_bit_low_too_short_cnt)
-		seq_printf(file,
-			   "rx start bit low too short: %u (delta %u, ts %llu)\n",
-			   pin->rx_start_bit_low_too_short_cnt,
-			   pin->rx_start_bit_low_too_short_delta,
-			   pin->rx_start_bit_low_too_short_ts);
-	if (pin->rx_start_bit_too_short_cnt)
-		seq_printf(file,
-			   "rx start bit too short: %u (delta %u, ts %llu)\n",
-			   pin->rx_start_bit_too_short_cnt,
-			   pin->rx_start_bit_too_short_delta,
-			   pin->rx_start_bit_too_short_ts);
-	if (pin->rx_start_bit_too_long_cnt)
-		seq_printf(file, "rx start bit too long: %u\n",
-			   pin->rx_start_bit_too_long_cnt);
-	if (pin->rx_data_bit_too_short_cnt)
-		seq_printf(file,
-			   "rx data bit too short: %u (delta %u, ts %llu)\n",
-			   pin->rx_data_bit_too_short_cnt,
-			   pin->rx_data_bit_too_short_delta,
-			   pin->rx_data_bit_too_short_ts);
-	if (pin->rx_data_bit_too_long_cnt)
-		seq_printf(file, "rx data bit too long: %u\n",
-			   pin->rx_data_bit_too_long_cnt);
-	seq_printf(file, "rx initiated low drive: %u\n", pin->rx_low_drive_cnt);
-	seq_printf(file, "tx detected low drive: %u\n", pin->tx_low_drive_cnt);
-	pin->work_pin_events_dropped_cnt = 0;
-	pin->timer_cnt = 0;
-	pin->timer_100ms_overruns = 0;
-	pin->timer_300ms_overruns = 0;
-	pin->timer_max_overrun = 0;
-	pin->timer_sum_overrun = 0;
-	pin->rx_start_bit_low_too_short_cnt = 0;
-	pin->rx_start_bit_too_short_cnt = 0;
-	pin->rx_start_bit_too_long_cnt = 0;
-	pin->rx_data_bit_too_short_cnt = 0;
-	pin->rx_data_bit_too_long_cnt = 0;
-	pin->rx_low_drive_cnt = 0;
-	pin->tx_low_drive_cnt = 0;
-	if (pin->ops->status)
-		pin->ops->status(adap, file);
-}
-
-static int cec_pin_adap_monitor_all_enable(struct cec_adapter *adap,
-						  bool enable)
-{
-	struct cec_pin *pin = adap->pin;
-
-	pin->monitor_all = enable;
-	return 0;
-}
-
-static void cec_pin_adap_free(struct cec_adapter *adap)
-{
-	struct cec_pin *pin = adap->pin;
-
-	if (pin->ops->free)
-		pin->ops->free(adap);
-	adap->pin = NULL;
-	kfree(pin);
-}
-
-static int cec_pin_received(struct cec_adapter *adap, struct cec_msg *msg)
-{
-	struct cec_pin *pin = adap->pin;
-
-	if (pin->ops->received)
-		return pin->ops->received(adap, msg);
-	return -ENOMSG;
-}
-
-void cec_pin_changed(struct cec_adapter *adap, bool value)
-{
-	struct cec_pin *pin = adap->pin;
-
-	cec_pin_update(pin, value, false);
-	if (!value && (adap->is_configuring || adap->is_configured ||
-		       adap->monitor_all_cnt))
-		atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_DISABLE);
-}
-EXPORT_SYMBOL_GPL(cec_pin_changed);
-
-static const struct cec_adap_ops cec_pin_adap_ops = {
-	.adap_enable = cec_pin_adap_enable,
-	.adap_monitor_all_enable = cec_pin_adap_monitor_all_enable,
-	.adap_log_addr = cec_pin_adap_log_addr,
-	.adap_transmit = cec_pin_adap_transmit,
-	.adap_status = cec_pin_adap_status,
-	.adap_free = cec_pin_adap_free,
-#ifdef CONFIG_CEC_PIN_ERROR_INJ
-	.error_inj_parse_line = cec_pin_error_inj_parse_line,
-	.error_inj_show = cec_pin_error_inj_show,
-#endif
-	.received = cec_pin_received,
-};
-
-struct cec_adapter *cec_pin_allocate_adapter(const struct cec_pin_ops *pin_ops,
-					void *priv, const char *name, u32 caps)
-{
-	struct cec_adapter *adap;
-	struct cec_pin *pin = kzalloc(sizeof(*pin), GFP_KERNEL);
-
-	if (pin == NULL)
-		return ERR_PTR(-ENOMEM);
-	pin->ops = pin_ops;
-	hrtimer_init(&pin->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
-	pin->timer.function = cec_pin_timer;
-	init_waitqueue_head(&pin->kthread_waitq);
-	pin->tx_custom_low_usecs = CEC_TIM_CUSTOM_DEFAULT;
-	pin->tx_custom_high_usecs = CEC_TIM_CUSTOM_DEFAULT;
-
-	adap = cec_allocate_adapter(&cec_pin_adap_ops, priv, name,
-			    caps | CEC_CAP_MONITOR_ALL | CEC_CAP_MONITOR_PIN,
-			    CEC_MAX_LOG_ADDRS);
-
-	if (IS_ERR(adap)) {
-		kfree(pin);
-		return adap;
-	}
-
-	adap->pin = pin;
-	pin->adap = adap;
-	cec_pin_update(pin, cec_pin_high(pin), true);
-	return adap;
-}
-EXPORT_SYMBOL_GPL(cec_pin_allocate_adapter);
diff --git a/drivers/media/cec/cec-priv.h b/drivers/media/cec/cec-priv.h
deleted file mode 100644
index 9bbd05053d42..000000000000
--- a/drivers/media/cec/cec-priv.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * cec-priv.h - HDMI Consumer Electronics Control internal header
- *
- * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#ifndef _CEC_PRIV_H
-#define _CEC_PRIV_H
-
-#include <linux/cec-funcs.h>
-#include <media/cec-notifier.h>
-
-#define dprintk(lvl, fmt, arg...)					\
-	do {								\
-		if (lvl <= cec_debug)					\
-			pr_info("cec-%s: " fmt, adap->name, ## arg);	\
-	} while (0)
-
-/* devnode to cec_adapter */
-#define to_cec_adapter(node) container_of(node, struct cec_adapter, devnode)
-
-static inline bool msg_is_raw(const struct cec_msg *msg)
-{
-	return msg->flags & CEC_MSG_FL_RAW;
-}
-
-/* cec-core.c */
-extern int cec_debug;
-int cec_get_device(struct cec_devnode *devnode);
-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);
-int __cec_s_log_addrs(struct cec_adapter *adap,
-		      struct cec_log_addrs *log_addrs, bool block);
-int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg,
-			struct cec_fh *fh, bool block);
-void cec_queue_event_fh(struct cec_fh *fh,
-			const struct cec_event *new_ev, u64 ts);
-
-/* cec-api.c */
-extern const struct file_operations cec_devnode_fops;
-
-#endif
diff --git a/drivers/media/cec/core/Makefile b/drivers/media/cec/core/Makefile
new file mode 100644
index 000000000000..ad8677d8c896
--- /dev/null
+++ b/drivers/media/cec/core/Makefile
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: GPL-2.0
+cec-objs := cec-core.o cec-adap.o cec-api.o
+
+ifeq ($(CONFIG_CEC_NOTIFIER),y)
+  cec-objs += cec-notifier.o
+endif
+
+ifeq ($(CONFIG_CEC_PIN),y)
+  cec-objs += cec-pin.o
+endif
+
+ifeq ($(CONFIG_CEC_PIN_ERROR_INJ),y)
+  cec-objs += cec-pin-error-inj.o
+endif
+
+obj-$(CONFIG_CEC_CORE) += cec.o
diff --git a/drivers/media/cec/core/cec-adap.c b/drivers/media/cec/core/cec-adap.c
new file mode 100644
index 000000000000..6c95dc471d4c
--- /dev/null
+++ b/drivers/media/cec/core/cec-adap.c
@@ -0,0 +1,2199 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * cec-adap.c - HDMI Consumer Electronics Control framework - CEC adapter
+ *
+ * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/kmod.h>
+#include <linux/ktime.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/types.h>
+
+#include <drm/drm_connector.h>
+#include <drm/drm_device.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_file.h>
+
+#include "cec-priv.h"
+
+static void cec_fill_msg_report_features(struct cec_adapter *adap,
+					 struct cec_msg *msg,
+					 unsigned int la_idx);
+
+/*
+ * 400 ms is the time it takes for one 16 byte message to be
+ * transferred and 5 is the maximum number of retries. Add
+ * another 100 ms as a margin. So if the transmit doesn't
+ * finish before that time something is really wrong and we
+ * have to time out.
+ *
+ * This is a sign that something it really wrong and a warning
+ * will be issued.
+ */
+#define CEC_XFER_TIMEOUT_MS (5 * 400 + 100)
+
+#define call_op(adap, op, arg...) \
+	(adap->ops->op ? adap->ops->op(adap, ## arg) : 0)
+
+#define call_void_op(adap, op, arg...)			\
+	do {						\
+		if (adap->ops->op)			\
+			adap->ops->op(adap, ## arg);	\
+	} while (0)
+
+static int cec_log_addr2idx(const struct cec_adapter *adap, u8 log_addr)
+{
+	int i;
+
+	for (i = 0; i < adap->log_addrs.num_log_addrs; i++)
+		if (adap->log_addrs.log_addr[i] == log_addr)
+			return i;
+	return -1;
+}
+
+static unsigned int cec_log_addr2dev(const struct cec_adapter *adap, u8 log_addr)
+{
+	int i = cec_log_addr2idx(adap, log_addr);
+
+	return adap->log_addrs.primary_device_type[i < 0 ? 0 : i];
+}
+
+u16 cec_get_edid_phys_addr(const u8 *edid, unsigned int size,
+			   unsigned int *offset)
+{
+	unsigned int loc = cec_get_edid_spa_location(edid, size);
+
+	if (offset)
+		*offset = loc;
+	if (loc == 0)
+		return CEC_PHYS_ADDR_INVALID;
+	return (edid[loc] << 8) | edid[loc + 1];
+}
+EXPORT_SYMBOL_GPL(cec_get_edid_phys_addr);
+
+void cec_fill_conn_info_from_drm(struct cec_connector_info *conn_info,
+				 const struct drm_connector *connector)
+{
+	memset(conn_info, 0, sizeof(*conn_info));
+	conn_info->type = CEC_CONNECTOR_TYPE_DRM;
+	conn_info->drm.card_no = connector->dev->primary->index;
+	conn_info->drm.connector_id = connector->base.id;
+}
+EXPORT_SYMBOL_GPL(cec_fill_conn_info_from_drm);
+
+/*
+ * Queue a new event for this filehandle. If ts == 0, then set it
+ * to the current time.
+ *
+ * We keep a queue of at most max_event events where max_event differs
+ * per event. If the queue becomes full, then drop the oldest event and
+ * keep track of how many events we've dropped.
+ */
+void cec_queue_event_fh(struct cec_fh *fh,
+			const struct cec_event *new_ev, u64 ts)
+{
+	static const u16 max_events[CEC_NUM_EVENTS] = {
+		1, 1, 800, 800, 8, 8, 8, 8
+	};
+	struct cec_event_entry *entry;
+	unsigned int ev_idx = new_ev->event - 1;
+
+	if (WARN_ON(ev_idx >= ARRAY_SIZE(fh->events)))
+		return;
+
+	if (ts == 0)
+		ts = ktime_get_ns();
+
+	mutex_lock(&fh->lock);
+	if (ev_idx < CEC_NUM_CORE_EVENTS)
+		entry = &fh->core_events[ev_idx];
+	else
+		entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+	if (entry) {
+		if (new_ev->event == CEC_EVENT_LOST_MSGS &&
+		    fh->queued_events[ev_idx]) {
+			entry->ev.lost_msgs.lost_msgs +=
+				new_ev->lost_msgs.lost_msgs;
+			goto unlock;
+		}
+		entry->ev = *new_ev;
+		entry->ev.ts = ts;
+
+		if (fh->queued_events[ev_idx] < max_events[ev_idx]) {
+			/* Add new msg at the end of the queue */
+			list_add_tail(&entry->list, &fh->events[ev_idx]);
+			fh->queued_events[ev_idx]++;
+			fh->total_queued_events++;
+			goto unlock;
+		}
+
+		if (ev_idx >= CEC_NUM_CORE_EVENTS) {
+			list_add_tail(&entry->list, &fh->events[ev_idx]);
+			/* drop the oldest event */
+			entry = list_first_entry(&fh->events[ev_idx],
+						 struct cec_event_entry, list);
+			list_del(&entry->list);
+			kfree(entry);
+		}
+	}
+	/* Mark that events were lost */
+	entry = list_first_entry_or_null(&fh->events[ev_idx],
+					 struct cec_event_entry, list);
+	if (entry)
+		entry->ev.flags |= CEC_EVENT_FL_DROPPED_EVENTS;
+
+unlock:
+	mutex_unlock(&fh->lock);
+	wake_up_interruptible(&fh->wait);
+}
+
+/* Queue a new event for all open filehandles. */
+static void cec_queue_event(struct cec_adapter *adap,
+			    const struct cec_event *ev)
+{
+	u64 ts = ktime_get_ns();
+	struct cec_fh *fh;
+
+	mutex_lock(&adap->devnode.lock);
+	list_for_each_entry(fh, &adap->devnode.fhs, list)
+		cec_queue_event_fh(fh, ev, ts);
+	mutex_unlock(&adap->devnode.lock);
+}
+
+/* Notify userspace that the CEC pin changed state at the given time. */
+void cec_queue_pin_cec_event(struct cec_adapter *adap, bool is_high,
+			     bool dropped_events, ktime_t ts)
+{
+	struct cec_event ev = {
+		.event = is_high ? CEC_EVENT_PIN_CEC_HIGH :
+				   CEC_EVENT_PIN_CEC_LOW,
+		.flags = dropped_events ? CEC_EVENT_FL_DROPPED_EVENTS : 0,
+	};
+	struct cec_fh *fh;
+
+	mutex_lock(&adap->devnode.lock);
+	list_for_each_entry(fh, &adap->devnode.fhs, list)
+		if (fh->mode_follower == CEC_MODE_MONITOR_PIN)
+			cec_queue_event_fh(fh, &ev, ktime_to_ns(ts));
+	mutex_unlock(&adap->devnode.lock);
+}
+EXPORT_SYMBOL_GPL(cec_queue_pin_cec_event);
+
+/* Notify userspace that the HPD pin changed state at the given time. */
+void cec_queue_pin_hpd_event(struct cec_adapter *adap, bool is_high, ktime_t ts)
+{
+	struct cec_event ev = {
+		.event = is_high ? CEC_EVENT_PIN_HPD_HIGH :
+				   CEC_EVENT_PIN_HPD_LOW,
+	};
+	struct cec_fh *fh;
+
+	mutex_lock(&adap->devnode.lock);
+	list_for_each_entry(fh, &adap->devnode.fhs, list)
+		cec_queue_event_fh(fh, &ev, ktime_to_ns(ts));
+	mutex_unlock(&adap->devnode.lock);
+}
+EXPORT_SYMBOL_GPL(cec_queue_pin_hpd_event);
+
+/* Notify userspace that the 5V pin changed state at the given time. */
+void cec_queue_pin_5v_event(struct cec_adapter *adap, bool is_high, ktime_t ts)
+{
+	struct cec_event ev = {
+		.event = is_high ? CEC_EVENT_PIN_5V_HIGH :
+				   CEC_EVENT_PIN_5V_LOW,
+	};
+	struct cec_fh *fh;
+
+	mutex_lock(&adap->devnode.lock);
+	list_for_each_entry(fh, &adap->devnode.fhs, list)
+		cec_queue_event_fh(fh, &ev, ktime_to_ns(ts));
+	mutex_unlock(&adap->devnode.lock);
+}
+EXPORT_SYMBOL_GPL(cec_queue_pin_5v_event);
+
+/*
+ * Queue a new message for this filehandle.
+ *
+ * We keep a queue of at most CEC_MAX_MSG_RX_QUEUE_SZ messages. If the
+ * queue becomes full, then drop the oldest message and keep track
+ * of how many messages we've dropped.
+ */
+static void cec_queue_msg_fh(struct cec_fh *fh, const struct cec_msg *msg)
+{
+	static const struct cec_event ev_lost_msgs = {
+		.event = CEC_EVENT_LOST_MSGS,
+		.flags = 0,
+		{
+			.lost_msgs = { 1 },
+		},
+	};
+	struct cec_msg_entry *entry;
+
+	mutex_lock(&fh->lock);
+	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+	if (entry) {
+		entry->msg = *msg;
+		/* Add new msg at the end of the queue */
+		list_add_tail(&entry->list, &fh->msgs);
+
+		if (fh->queued_msgs < CEC_MAX_MSG_RX_QUEUE_SZ) {
+			/* All is fine if there is enough room */
+			fh->queued_msgs++;
+			mutex_unlock(&fh->lock);
+			wake_up_interruptible(&fh->wait);
+			return;
+		}
+
+		/*
+		 * if the message queue is full, then drop the oldest one and
+		 * send a lost message event.
+		 */
+		entry = list_first_entry(&fh->msgs, struct cec_msg_entry, list);
+		list_del(&entry->list);
+		kfree(entry);
+	}
+	mutex_unlock(&fh->lock);
+
+	/*
+	 * We lost a message, either because kmalloc failed or the queue
+	 * was full.
+	 */
+	cec_queue_event_fh(fh, &ev_lost_msgs, ktime_get_ns());
+}
+
+/*
+ * Queue the message for those filehandles that are in monitor mode.
+ * If valid_la is true (this message is for us or was sent by us),
+ * then pass it on to any monitoring filehandle. If this message
+ * isn't for us or from us, then only give it to filehandles that
+ * are in MONITOR_ALL mode.
+ *
+ * This can only happen if the CEC_CAP_MONITOR_ALL capability is
+ * set and the CEC adapter was placed in 'monitor all' mode.
+ */
+static void cec_queue_msg_monitor(struct cec_adapter *adap,
+				  const struct cec_msg *msg,
+				  bool valid_la)
+{
+	struct cec_fh *fh;
+	u32 monitor_mode = valid_la ? CEC_MODE_MONITOR :
+				      CEC_MODE_MONITOR_ALL;
+
+	mutex_lock(&adap->devnode.lock);
+	list_for_each_entry(fh, &adap->devnode.fhs, list) {
+		if (fh->mode_follower >= monitor_mode)
+			cec_queue_msg_fh(fh, msg);
+	}
+	mutex_unlock(&adap->devnode.lock);
+}
+
+/*
+ * Queue the message for follower filehandles.
+ */
+static void cec_queue_msg_followers(struct cec_adapter *adap,
+				    const struct cec_msg *msg)
+{
+	struct cec_fh *fh;
+
+	mutex_lock(&adap->devnode.lock);
+	list_for_each_entry(fh, &adap->devnode.fhs, list) {
+		if (fh->mode_follower == CEC_MODE_FOLLOWER)
+			cec_queue_msg_fh(fh, msg);
+	}
+	mutex_unlock(&adap->devnode.lock);
+}
+
+/* Notify userspace of an adapter state change. */
+static void cec_post_state_event(struct cec_adapter *adap)
+{
+	struct cec_event ev = {
+		.event = CEC_EVENT_STATE_CHANGE,
+	};
+
+	ev.state_change.phys_addr = adap->phys_addr;
+	ev.state_change.log_addr_mask = adap->log_addrs.log_addr_mask;
+	ev.state_change.have_conn_info =
+		adap->conn_info.type != CEC_CONNECTOR_TYPE_NO_CONNECTOR;
+	cec_queue_event(adap, &ev);
+}
+
+/*
+ * A CEC transmit (and a possible wait for reply) completed.
+ * If this was in blocking mode, then complete it, otherwise
+ * queue the message for userspace to dequeue later.
+ *
+ * This function is called with adap->lock held.
+ */
+static void cec_data_completed(struct cec_data *data)
+{
+	/*
+	 * Delete this transmit from the filehandle's xfer_list since
+	 * we're done with it.
+	 *
+	 * Note that if the filehandle is closed before this transmit
+	 * finished, then the release() function will set data->fh to NULL.
+	 * Without that we would be referring to a closed filehandle.
+	 */
+	if (data->fh)
+		list_del(&data->xfer_list);
+
+	if (data->blocking) {
+		/*
+		 * Someone is blocking so mark the message as completed
+		 * and call complete.
+		 */
+		data->completed = true;
+		complete(&data->c);
+	} else {
+		/*
+		 * No blocking, so just queue the message if needed and
+		 * free the memory.
+		 */
+		if (data->fh)
+			cec_queue_msg_fh(data->fh, &data->msg);
+		kfree(data);
+	}
+}
+
+/*
+ * A pending CEC transmit needs to be cancelled, either because the CEC
+ * adapter is disabled or the transmit takes an impossibly long time to
+ * finish.
+ *
+ * This function is called with adap->lock held.
+ */
+static void cec_data_cancel(struct cec_data *data, u8 tx_status)
+{
+	/*
+	 * It's either the current transmit, or it is a pending
+	 * transmit. Take the appropriate action to clear it.
+	 */
+	if (data->adap->transmitting == data) {
+		data->adap->transmitting = NULL;
+	} else {
+		list_del_init(&data->list);
+		if (!(data->msg.tx_status & CEC_TX_STATUS_OK))
+			if (!WARN_ON(!data->adap->transmit_queue_sz))
+				data->adap->transmit_queue_sz--;
+	}
+
+	if (data->msg.tx_status & CEC_TX_STATUS_OK) {
+		data->msg.rx_ts = ktime_get_ns();
+		data->msg.rx_status = CEC_RX_STATUS_ABORTED;
+	} else {
+		data->msg.tx_ts = ktime_get_ns();
+		data->msg.tx_status |= tx_status |
+				       CEC_TX_STATUS_MAX_RETRIES;
+		data->msg.tx_error_cnt++;
+		data->attempts = 0;
+	}
+
+	/* Queue transmitted message for monitoring purposes */
+	cec_queue_msg_monitor(data->adap, &data->msg, 1);
+
+	cec_data_completed(data);
+}
+
+/*
+ * Flush all pending transmits and cancel any pending timeout work.
+ *
+ * This function is called with adap->lock held.
+ */
+static void cec_flush(struct cec_adapter *adap)
+{
+	struct cec_data *data, *n;
+
+	/*
+	 * If the adapter is disabled, or we're asked to stop,
+	 * then cancel any pending transmits.
+	 */
+	while (!list_empty(&adap->transmit_queue)) {
+		data = list_first_entry(&adap->transmit_queue,
+					struct cec_data, list);
+		cec_data_cancel(data, CEC_TX_STATUS_ABORTED);
+	}
+	if (adap->transmitting)
+		cec_data_cancel(adap->transmitting, CEC_TX_STATUS_ABORTED);
+
+	/* Cancel the pending timeout work. */
+	list_for_each_entry_safe(data, n, &adap->wait_queue, list) {
+		if (cancel_delayed_work(&data->work))
+			cec_data_cancel(data, CEC_TX_STATUS_OK);
+		/*
+		 * If cancel_delayed_work returned false, then
+		 * the cec_wait_timeout function is running,
+		 * which will call cec_data_completed. So no
+		 * need to do anything special in that case.
+		 */
+	}
+	/*
+	 * If something went wrong and this counter isn't what it should
+	 * be, then this will reset it back to 0. Warn if it is not 0,
+	 * since it indicates a bug, either in this framework or in a
+	 * CEC driver.
+	 */
+	if (WARN_ON(adap->transmit_queue_sz))
+		adap->transmit_queue_sz = 0;
+}
+
+/*
+ * Main CEC state machine
+ *
+ * Wait until the thread should be stopped, or we are not transmitting and
+ * a new transmit message is queued up, in which case we start transmitting
+ * that message. When the adapter finished transmitting the message it will
+ * call cec_transmit_done().
+ *
+ * If the adapter is disabled, then remove all queued messages instead.
+ *
+ * If the current transmit times out, then cancel that transmit.
+ */
+int cec_thread_func(void *_adap)
+{
+	struct cec_adapter *adap = _adap;
+
+	for (;;) {
+		unsigned int signal_free_time;
+		struct cec_data *data;
+		bool timeout = false;
+		u8 attempts;
+
+		if (adap->transmit_in_progress) {
+			int err;
+
+			/*
+			 * We are transmitting a message, so add a timeout
+			 * to prevent the state machine to get stuck waiting
+			 * for this message to finalize and add a check to
+			 * see if the adapter is disabled in which case the
+			 * transmit should be canceled.
+			 */
+			err = wait_event_interruptible_timeout(adap->kthread_waitq,
+				(adap->needs_hpd &&
+				 (!adap->is_configured && !adap->is_configuring)) ||
+				kthread_should_stop() ||
+				(!adap->transmit_in_progress &&
+				 !list_empty(&adap->transmit_queue)),
+				msecs_to_jiffies(CEC_XFER_TIMEOUT_MS));
+			timeout = err == 0;
+		} else {
+			/* Otherwise we just wait for something to happen. */
+			wait_event_interruptible(adap->kthread_waitq,
+				kthread_should_stop() ||
+				(!adap->transmit_in_progress &&
+				 !list_empty(&adap->transmit_queue)));
+		}
+
+		mutex_lock(&adap->lock);
+
+		if ((adap->needs_hpd &&
+		     (!adap->is_configured && !adap->is_configuring)) ||
+		    kthread_should_stop()) {
+			cec_flush(adap);
+			goto unlock;
+		}
+
+		if (adap->transmit_in_progress && timeout) {
+			/*
+			 * If we timeout, then log that. Normally this does
+			 * not happen and it is an indication of a faulty CEC
+			 * adapter driver, or the CEC bus is in some weird
+			 * state. On rare occasions it can happen if there is
+			 * so much traffic on the bus that the adapter was
+			 * unable to transmit for CEC_XFER_TIMEOUT_MS (2.1s).
+			 */
+			if (adap->transmitting) {
+				pr_warn("cec-%s: message %*ph timed out\n", adap->name,
+					adap->transmitting->msg.len,
+					adap->transmitting->msg.msg);
+				/* Just give up on this. */
+				cec_data_cancel(adap->transmitting,
+						CEC_TX_STATUS_TIMEOUT);
+			} else {
+				pr_warn("cec-%s: transmit timed out\n", adap->name);
+			}
+			adap->transmit_in_progress = false;
+			adap->tx_timeouts++;
+			goto unlock;
+		}
+
+		/*
+		 * If we are still transmitting, or there is nothing new to
+		 * transmit, then just continue waiting.
+		 */
+		if (adap->transmit_in_progress || list_empty(&adap->transmit_queue))
+			goto unlock;
+
+		/* Get a new message to transmit */
+		data = list_first_entry(&adap->transmit_queue,
+					struct cec_data, list);
+		list_del_init(&data->list);
+		if (!WARN_ON(!data->adap->transmit_queue_sz))
+			adap->transmit_queue_sz--;
+
+		/* Make this the current transmitting message */
+		adap->transmitting = data;
+
+		/*
+		 * Suggested number of attempts as per the CEC 2.0 spec:
+		 * 4 attempts is the default, except for 'secondary poll
+		 * messages', i.e. poll messages not sent during the adapter
+		 * configuration phase when it allocates logical addresses.
+		 */
+		if (data->msg.len == 1 && adap->is_configured)
+			attempts = 2;
+		else
+			attempts = 4;
+
+		/* Set the suggested signal free time */
+		if (data->attempts) {
+			/* should be >= 3 data bit periods for a retry */
+			signal_free_time = CEC_SIGNAL_FREE_TIME_RETRY;
+		} else if (adap->last_initiator !=
+			   cec_msg_initiator(&data->msg)) {
+			/* should be >= 5 data bit periods for new initiator */
+			signal_free_time = CEC_SIGNAL_FREE_TIME_NEW_INITIATOR;
+			adap->last_initiator = cec_msg_initiator(&data->msg);
+		} else {
+			/*
+			 * should be >= 7 data bit periods for sending another
+			 * frame immediately after another.
+			 */
+			signal_free_time = CEC_SIGNAL_FREE_TIME_NEXT_XFER;
+		}
+		if (data->attempts == 0)
+			data->attempts = attempts;
+
+		/* Tell the adapter to transmit, cancel on error */
+		if (adap->ops->adap_transmit(adap, data->attempts,
+					     signal_free_time, &data->msg))
+			cec_data_cancel(data, CEC_TX_STATUS_ABORTED);
+		else
+			adap->transmit_in_progress = true;
+
+unlock:
+		mutex_unlock(&adap->lock);
+
+		if (kthread_should_stop())
+			break;
+	}
+	return 0;
+}
+
+/*
+ * Called by the CEC adapter if a transmit finished.
+ */
+void cec_transmit_done_ts(struct cec_adapter *adap, u8 status,
+			  u8 arb_lost_cnt, u8 nack_cnt, u8 low_drive_cnt,
+			  u8 error_cnt, ktime_t ts)
+{
+	struct cec_data *data;
+	struct cec_msg *msg;
+	unsigned int attempts_made = arb_lost_cnt + nack_cnt +
+				     low_drive_cnt + error_cnt;
+
+	dprintk(2, "%s: status 0x%02x\n", __func__, status);
+	if (attempts_made < 1)
+		attempts_made = 1;
+
+	mutex_lock(&adap->lock);
+	data = adap->transmitting;
+	if (!data) {
+		/*
+		 * This might happen if a transmit was issued and the cable is
+		 * unplugged while the transmit is ongoing. Ignore this
+		 * transmit in that case.
+		 */
+		if (!adap->transmit_in_progress)
+			dprintk(1, "%s was called without an ongoing transmit!\n",
+				__func__);
+		adap->transmit_in_progress = false;
+		goto wake_thread;
+	}
+	adap->transmit_in_progress = false;
+
+	msg = &data->msg;
+
+	/* Drivers must fill in the status! */
+	WARN_ON(status == 0);
+	msg->tx_ts = ktime_to_ns(ts);
+	msg->tx_status |= status;
+	msg->tx_arb_lost_cnt += arb_lost_cnt;
+	msg->tx_nack_cnt += nack_cnt;
+	msg->tx_low_drive_cnt += low_drive_cnt;
+	msg->tx_error_cnt += error_cnt;
+
+	/* Mark that we're done with this transmit */
+	adap->transmitting = NULL;
+
+	/*
+	 * If there are still retry attempts left and there was an error and
+	 * the hardware didn't signal that it retried itself (by setting
+	 * CEC_TX_STATUS_MAX_RETRIES), then we will retry ourselves.
+	 */
+	if (data->attempts > attempts_made &&
+	    !(status & (CEC_TX_STATUS_MAX_RETRIES | CEC_TX_STATUS_OK))) {
+		/* Retry this message */
+		data->attempts -= attempts_made;
+		if (msg->timeout)
+			dprintk(2, "retransmit: %*ph (attempts: %d, wait for 0x%02x)\n",
+				msg->len, msg->msg, data->attempts, msg->reply);
+		else
+			dprintk(2, "retransmit: %*ph (attempts: %d)\n",
+				msg->len, msg->msg, data->attempts);
+		/* Add the message in front of the transmit queue */
+		list_add(&data->list, &adap->transmit_queue);
+		adap->transmit_queue_sz++;
+		goto wake_thread;
+	}
+
+	data->attempts = 0;
+
+	/* Always set CEC_TX_STATUS_MAX_RETRIES on error */
+	if (!(status & CEC_TX_STATUS_OK))
+		msg->tx_status |= CEC_TX_STATUS_MAX_RETRIES;
+
+	/* Queue transmitted message for monitoring purposes */
+	cec_queue_msg_monitor(adap, msg, 1);
+
+	if ((status & CEC_TX_STATUS_OK) && adap->is_configured &&
+	    msg->timeout) {
+		/*
+		 * Queue the message into the wait queue if we want to wait
+		 * for a reply.
+		 */
+		list_add_tail(&data->list, &adap->wait_queue);
+		schedule_delayed_work(&data->work,
+				      msecs_to_jiffies(msg->timeout));
+	} else {
+		/* Otherwise we're done */
+		cec_data_completed(data);
+	}
+
+wake_thread:
+	/*
+	 * Wake up the main thread to see if another message is ready
+	 * for transmitting or to retry the current message.
+	 */
+	wake_up_interruptible(&adap->kthread_waitq);
+	mutex_unlock(&adap->lock);
+}
+EXPORT_SYMBOL_GPL(cec_transmit_done_ts);
+
+void cec_transmit_attempt_done_ts(struct cec_adapter *adap,
+				  u8 status, ktime_t ts)
+{
+	switch (status & ~CEC_TX_STATUS_MAX_RETRIES) {
+	case CEC_TX_STATUS_OK:
+		cec_transmit_done_ts(adap, status, 0, 0, 0, 0, ts);
+		return;
+	case CEC_TX_STATUS_ARB_LOST:
+		cec_transmit_done_ts(adap, status, 1, 0, 0, 0, ts);
+		return;
+	case CEC_TX_STATUS_NACK:
+		cec_transmit_done_ts(adap, status, 0, 1, 0, 0, ts);
+		return;
+	case CEC_TX_STATUS_LOW_DRIVE:
+		cec_transmit_done_ts(adap, status, 0, 0, 1, 0, ts);
+		return;
+	case CEC_TX_STATUS_ERROR:
+		cec_transmit_done_ts(adap, status, 0, 0, 0, 1, ts);
+		return;
+	default:
+		/* Should never happen */
+		WARN(1, "cec-%s: invalid status 0x%02x\n", adap->name, status);
+		return;
+	}
+}
+EXPORT_SYMBOL_GPL(cec_transmit_attempt_done_ts);
+
+/*
+ * Called when waiting for a reply times out.
+ */
+static void cec_wait_timeout(struct work_struct *work)
+{
+	struct cec_data *data = container_of(work, struct cec_data, work.work);
+	struct cec_adapter *adap = data->adap;
+
+	mutex_lock(&adap->lock);
+	/*
+	 * Sanity check in case the timeout and the arrival of the message
+	 * happened at the same time.
+	 */
+	if (list_empty(&data->list))
+		goto unlock;
+
+	/* Mark the message as timed out */
+	list_del_init(&data->list);
+	data->msg.rx_ts = ktime_get_ns();
+	data->msg.rx_status = CEC_RX_STATUS_TIMEOUT;
+	cec_data_completed(data);
+unlock:
+	mutex_unlock(&adap->lock);
+}
+
+/*
+ * Transmit a message. The fh argument may be NULL if the transmit is not
+ * associated with a specific filehandle.
+ *
+ * This function is called with adap->lock held.
+ */
+int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg,
+			struct cec_fh *fh, bool block)
+{
+	struct cec_data *data;
+	bool is_raw = msg_is_raw(msg);
+
+	msg->rx_ts = 0;
+	msg->tx_ts = 0;
+	msg->rx_status = 0;
+	msg->tx_status = 0;
+	msg->tx_arb_lost_cnt = 0;
+	msg->tx_nack_cnt = 0;
+	msg->tx_low_drive_cnt = 0;
+	msg->tx_error_cnt = 0;
+	msg->sequence = 0;
+
+	if (msg->reply && msg->timeout == 0) {
+		/* Make sure the timeout isn't 0. */
+		msg->timeout = 1000;
+	}
+	msg->flags &= CEC_MSG_FL_REPLY_TO_FOLLOWERS | CEC_MSG_FL_RAW;
+
+	if (!msg->timeout)
+		msg->flags &= ~CEC_MSG_FL_REPLY_TO_FOLLOWERS;
+
+	/* Sanity checks */
+	if (msg->len == 0 || msg->len > CEC_MAX_MSG_SIZE) {
+		dprintk(1, "%s: invalid length %d\n", __func__, msg->len);
+		return -EINVAL;
+	}
+
+	memset(msg->msg + msg->len, 0, sizeof(msg->msg) - msg->len);
+
+	if (msg->timeout)
+		dprintk(2, "%s: %*ph (wait for 0x%02x%s)\n",
+			__func__, msg->len, msg->msg, msg->reply,
+			!block ? ", nb" : "");
+	else
+		dprintk(2, "%s: %*ph%s\n",
+			__func__, msg->len, msg->msg, !block ? " (nb)" : "");
+
+	if (msg->timeout && msg->len == 1) {
+		dprintk(1, "%s: can't reply to poll msg\n", __func__);
+		return -EINVAL;
+	}
+
+	if (is_raw) {
+		if (!capable(CAP_SYS_RAWIO))
+			return -EPERM;
+	} else {
+		/* A CDC-Only device can only send CDC messages */
+		if ((adap->log_addrs.flags & CEC_LOG_ADDRS_FL_CDC_ONLY) &&
+		    (msg->len == 1 || msg->msg[1] != CEC_MSG_CDC_MESSAGE)) {
+			dprintk(1, "%s: not a CDC message\n", __func__);
+			return -EINVAL;
+		}
+
+		if (msg->len >= 4 && msg->msg[1] == CEC_MSG_CDC_MESSAGE) {
+			msg->msg[2] = adap->phys_addr >> 8;
+			msg->msg[3] = adap->phys_addr & 0xff;
+		}
+
+		if (msg->len == 1) {
+			if (cec_msg_destination(msg) == 0xf) {
+				dprintk(1, "%s: invalid poll message\n",
+					__func__);
+				return -EINVAL;
+			}
+			if (cec_has_log_addr(adap, cec_msg_destination(msg))) {
+				/*
+				 * If the destination is a logical address our
+				 * adapter has already claimed, then just NACK
+				 * this. It depends on the hardware what it will
+				 * do with a POLL to itself (some OK this), so
+				 * it is just as easy to handle it here so the
+				 * behavior will be consistent.
+				 */
+				msg->tx_ts = ktime_get_ns();
+				msg->tx_status = CEC_TX_STATUS_NACK |
+					CEC_TX_STATUS_MAX_RETRIES;
+				msg->tx_nack_cnt = 1;
+				msg->sequence = ++adap->sequence;
+				if (!msg->sequence)
+					msg->sequence = ++adap->sequence;
+				return 0;
+			}
+		}
+		if (msg->len > 1 && !cec_msg_is_broadcast(msg) &&
+		    cec_has_log_addr(adap, cec_msg_destination(msg))) {
+			dprintk(1, "%s: destination is the adapter itself\n",
+				__func__);
+			return -EINVAL;
+		}
+		if (msg->len > 1 && adap->is_configured &&
+		    !cec_has_log_addr(adap, cec_msg_initiator(msg))) {
+			dprintk(1, "%s: initiator has unknown logical address %d\n",
+				__func__, cec_msg_initiator(msg));
+			return -EINVAL;
+		}
+		/*
+		 * Special case: allow Ping and IMAGE/TEXT_VIEW_ON to be
+		 * transmitted to a TV, even if the adapter is unconfigured.
+		 * This makes it possible to detect or wake up displays that
+		 * pull down the HPD when in standby.
+		 */
+		if (!adap->is_configured && !adap->is_configuring &&
+		    (msg->len > 2 ||
+		     cec_msg_destination(msg) != CEC_LOG_ADDR_TV ||
+		     (msg->len == 2 && msg->msg[1] != CEC_MSG_IMAGE_VIEW_ON &&
+		      msg->msg[1] != CEC_MSG_TEXT_VIEW_ON))) {
+			dprintk(1, "%s: adapter is unconfigured\n", __func__);
+			return -ENONET;
+		}
+	}
+
+	if (!adap->is_configured && !adap->is_configuring) {
+		if (adap->needs_hpd) {
+			dprintk(1, "%s: adapter is unconfigured and needs HPD\n",
+				__func__);
+			return -ENONET;
+		}
+		if (msg->reply) {
+			dprintk(1, "%s: invalid msg->reply\n", __func__);
+			return -EINVAL;
+		}
+	}
+
+	if (adap->transmit_queue_sz >= CEC_MAX_MSG_TX_QUEUE_SZ) {
+		dprintk(2, "%s: transmit queue full\n", __func__);
+		return -EBUSY;
+	}
+
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	msg->sequence = ++adap->sequence;
+	if (!msg->sequence)
+		msg->sequence = ++adap->sequence;
+
+	data->msg = *msg;
+	data->fh = fh;
+	data->adap = adap;
+	data->blocking = block;
+
+	init_completion(&data->c);
+	INIT_DELAYED_WORK(&data->work, cec_wait_timeout);
+
+	if (fh)
+		list_add_tail(&data->xfer_list, &fh->xfer_list);
+
+	list_add_tail(&data->list, &adap->transmit_queue);
+	adap->transmit_queue_sz++;
+	if (!adap->transmitting)
+		wake_up_interruptible(&adap->kthread_waitq);
+
+	/* All done if we don't need to block waiting for completion */
+	if (!block)
+		return 0;
+
+	/*
+	 * Release the lock and wait, retake the lock afterwards.
+	 */
+	mutex_unlock(&adap->lock);
+	wait_for_completion_killable(&data->c);
+	if (!data->completed)
+		cancel_delayed_work_sync(&data->work);
+	mutex_lock(&adap->lock);
+
+	/* Cancel the transmit if it was interrupted */
+	if (!data->completed)
+		cec_data_cancel(data, CEC_TX_STATUS_ABORTED);
+
+	/* The transmit completed (possibly with an error) */
+	*msg = data->msg;
+	kfree(data);
+	return 0;
+}
+
+/* Helper function to be used by drivers and this framework. */
+int cec_transmit_msg(struct cec_adapter *adap, struct cec_msg *msg,
+		     bool block)
+{
+	int ret;
+
+	mutex_lock(&adap->lock);
+	ret = cec_transmit_msg_fh(adap, msg, NULL, block);
+	mutex_unlock(&adap->lock);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cec_transmit_msg);
+
+/*
+ * I don't like forward references but without this the low-level
+ * cec_received_msg() function would come after a bunch of high-level
+ * CEC protocol handling functions. That was very confusing.
+ */
+static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg,
+			      bool is_reply);
+
+#define DIRECTED	0x80
+#define BCAST1_4	0x40
+#define BCAST2_0	0x20	/* broadcast only allowed for >= 2.0 */
+#define BCAST		(BCAST1_4 | BCAST2_0)
+#define BOTH		(BCAST | DIRECTED)
+
+/*
+ * Specify minimum length and whether the message is directed, broadcast
+ * or both. Messages that do not match the criteria are ignored as per
+ * the CEC specification.
+ */
+static const u8 cec_msg_size[256] = {
+	[CEC_MSG_ACTIVE_SOURCE] = 4 | BCAST,
+	[CEC_MSG_IMAGE_VIEW_ON] = 2 | DIRECTED,
+	[CEC_MSG_TEXT_VIEW_ON] = 2 | DIRECTED,
+	[CEC_MSG_INACTIVE_SOURCE] = 4 | DIRECTED,
+	[CEC_MSG_REQUEST_ACTIVE_SOURCE] = 2 | BCAST,
+	[CEC_MSG_ROUTING_CHANGE] = 6 | BCAST,
+	[CEC_MSG_ROUTING_INFORMATION] = 4 | BCAST,
+	[CEC_MSG_SET_STREAM_PATH] = 4 | BCAST,
+	[CEC_MSG_STANDBY] = 2 | BOTH,
+	[CEC_MSG_RECORD_OFF] = 2 | DIRECTED,
+	[CEC_MSG_RECORD_ON] = 3 | DIRECTED,
+	[CEC_MSG_RECORD_STATUS] = 3 | DIRECTED,
+	[CEC_MSG_RECORD_TV_SCREEN] = 2 | DIRECTED,
+	[CEC_MSG_CLEAR_ANALOGUE_TIMER] = 13 | DIRECTED,
+	[CEC_MSG_CLEAR_DIGITAL_TIMER] = 16 | DIRECTED,
+	[CEC_MSG_CLEAR_EXT_TIMER] = 13 | DIRECTED,
+	[CEC_MSG_SET_ANALOGUE_TIMER] = 13 | DIRECTED,
+	[CEC_MSG_SET_DIGITAL_TIMER] = 16 | DIRECTED,
+	[CEC_MSG_SET_EXT_TIMER] = 13 | DIRECTED,
+	[CEC_MSG_SET_TIMER_PROGRAM_TITLE] = 2 | DIRECTED,
+	[CEC_MSG_TIMER_CLEARED_STATUS] = 3 | DIRECTED,
+	[CEC_MSG_TIMER_STATUS] = 3 | DIRECTED,
+	[CEC_MSG_CEC_VERSION] = 3 | DIRECTED,
+	[CEC_MSG_GET_CEC_VERSION] = 2 | DIRECTED,
+	[CEC_MSG_GIVE_PHYSICAL_ADDR] = 2 | DIRECTED,
+	[CEC_MSG_GET_MENU_LANGUAGE] = 2 | DIRECTED,
+	[CEC_MSG_REPORT_PHYSICAL_ADDR] = 5 | BCAST,
+	[CEC_MSG_SET_MENU_LANGUAGE] = 5 | BCAST,
+	[CEC_MSG_REPORT_FEATURES] = 6 | BCAST,
+	[CEC_MSG_GIVE_FEATURES] = 2 | DIRECTED,
+	[CEC_MSG_DECK_CONTROL] = 3 | DIRECTED,
+	[CEC_MSG_DECK_STATUS] = 3 | DIRECTED,
+	[CEC_MSG_GIVE_DECK_STATUS] = 3 | DIRECTED,
+	[CEC_MSG_PLAY] = 3 | DIRECTED,
+	[CEC_MSG_GIVE_TUNER_DEVICE_STATUS] = 3 | DIRECTED,
+	[CEC_MSG_SELECT_ANALOGUE_SERVICE] = 6 | DIRECTED,
+	[CEC_MSG_SELECT_DIGITAL_SERVICE] = 9 | DIRECTED,
+	[CEC_MSG_TUNER_DEVICE_STATUS] = 7 | DIRECTED,
+	[CEC_MSG_TUNER_STEP_DECREMENT] = 2 | DIRECTED,
+	[CEC_MSG_TUNER_STEP_INCREMENT] = 2 | DIRECTED,
+	[CEC_MSG_DEVICE_VENDOR_ID] = 5 | BCAST,
+	[CEC_MSG_GIVE_DEVICE_VENDOR_ID] = 2 | DIRECTED,
+	[CEC_MSG_VENDOR_COMMAND] = 2 | DIRECTED,
+	[CEC_MSG_VENDOR_COMMAND_WITH_ID] = 5 | BOTH,
+	[CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN] = 2 | BOTH,
+	[CEC_MSG_VENDOR_REMOTE_BUTTON_UP] = 2 | BOTH,
+	[CEC_MSG_SET_OSD_STRING] = 3 | DIRECTED,
+	[CEC_MSG_GIVE_OSD_NAME] = 2 | DIRECTED,
+	[CEC_MSG_SET_OSD_NAME] = 2 | DIRECTED,
+	[CEC_MSG_MENU_REQUEST] = 3 | DIRECTED,
+	[CEC_MSG_MENU_STATUS] = 3 | DIRECTED,
+	[CEC_MSG_USER_CONTROL_PRESSED] = 3 | DIRECTED,
+	[CEC_MSG_USER_CONTROL_RELEASED] = 2 | DIRECTED,
+	[CEC_MSG_GIVE_DEVICE_POWER_STATUS] = 2 | DIRECTED,
+	[CEC_MSG_REPORT_POWER_STATUS] = 3 | DIRECTED | BCAST2_0,
+	[CEC_MSG_FEATURE_ABORT] = 4 | DIRECTED,
+	[CEC_MSG_ABORT] = 2 | DIRECTED,
+	[CEC_MSG_GIVE_AUDIO_STATUS] = 2 | DIRECTED,
+	[CEC_MSG_GIVE_SYSTEM_AUDIO_MODE_STATUS] = 2 | DIRECTED,
+	[CEC_MSG_REPORT_AUDIO_STATUS] = 3 | DIRECTED,
+	[CEC_MSG_REPORT_SHORT_AUDIO_DESCRIPTOR] = 2 | DIRECTED,
+	[CEC_MSG_REQUEST_SHORT_AUDIO_DESCRIPTOR] = 2 | DIRECTED,
+	[CEC_MSG_SET_SYSTEM_AUDIO_MODE] = 3 | BOTH,
+	[CEC_MSG_SYSTEM_AUDIO_MODE_REQUEST] = 2 | DIRECTED,
+	[CEC_MSG_SYSTEM_AUDIO_MODE_STATUS] = 3 | DIRECTED,
+	[CEC_MSG_SET_AUDIO_RATE] = 3 | DIRECTED,
+	[CEC_MSG_INITIATE_ARC] = 2 | DIRECTED,
+	[CEC_MSG_REPORT_ARC_INITIATED] = 2 | DIRECTED,
+	[CEC_MSG_REPORT_ARC_TERMINATED] = 2 | DIRECTED,
+	[CEC_MSG_REQUEST_ARC_INITIATION] = 2 | DIRECTED,
+	[CEC_MSG_REQUEST_ARC_TERMINATION] = 2 | DIRECTED,
+	[CEC_MSG_TERMINATE_ARC] = 2 | DIRECTED,
+	[CEC_MSG_REQUEST_CURRENT_LATENCY] = 4 | BCAST,
+	[CEC_MSG_REPORT_CURRENT_LATENCY] = 6 | BCAST,
+	[CEC_MSG_CDC_MESSAGE] = 2 | BCAST,
+};
+
+/* Called by the CEC adapter if a message is received */
+void cec_received_msg_ts(struct cec_adapter *adap,
+			 struct cec_msg *msg, ktime_t ts)
+{
+	struct cec_data *data;
+	u8 msg_init = cec_msg_initiator(msg);
+	u8 msg_dest = cec_msg_destination(msg);
+	u8 cmd = msg->msg[1];
+	bool is_reply = false;
+	bool valid_la = true;
+	u8 min_len = 0;
+
+	if (WARN_ON(!msg->len || msg->len > CEC_MAX_MSG_SIZE))
+		return;
+
+	/*
+	 * Some CEC adapters will receive the messages that they transmitted.
+	 * This test filters out those messages by checking if we are the
+	 * initiator, and just returning in that case.
+	 *
+	 * Note that this won't work if this is an Unregistered device.
+	 *
+	 * It is bad practice if the hardware receives the message that it
+	 * transmitted and luckily most CEC adapters behave correctly in this
+	 * respect.
+	 */
+	if (msg_init != CEC_LOG_ADDR_UNREGISTERED &&
+	    cec_has_log_addr(adap, msg_init))
+		return;
+
+	msg->rx_ts = ktime_to_ns(ts);
+	msg->rx_status = CEC_RX_STATUS_OK;
+	msg->sequence = msg->reply = msg->timeout = 0;
+	msg->tx_status = 0;
+	msg->tx_ts = 0;
+	msg->tx_arb_lost_cnt = 0;
+	msg->tx_nack_cnt = 0;
+	msg->tx_low_drive_cnt = 0;
+	msg->tx_error_cnt = 0;
+	msg->flags = 0;
+	memset(msg->msg + msg->len, 0, sizeof(msg->msg) - msg->len);
+
+	mutex_lock(&adap->lock);
+	dprintk(2, "%s: %*ph\n", __func__, msg->len, msg->msg);
+
+	adap->last_initiator = 0xff;
+
+	/* Check if this message was for us (directed or broadcast). */
+	if (!cec_msg_is_broadcast(msg))
+		valid_la = cec_has_log_addr(adap, msg_dest);
+
+	/*
+	 * Check if the length is not too short or if the message is a
+	 * broadcast message where a directed message was expected or
+	 * vice versa. If so, then the message has to be ignored (according
+	 * to section CEC 7.3 and CEC 12.2).
+	 */
+	if (valid_la && msg->len > 1 && cec_msg_size[cmd]) {
+		u8 dir_fl = cec_msg_size[cmd] & BOTH;
+
+		min_len = cec_msg_size[cmd] & 0x1f;
+		if (msg->len < min_len)
+			valid_la = false;
+		else if (!cec_msg_is_broadcast(msg) && !(dir_fl & DIRECTED))
+			valid_la = false;
+		else if (cec_msg_is_broadcast(msg) && !(dir_fl & BCAST))
+			valid_la = false;
+		else if (cec_msg_is_broadcast(msg) &&
+			 adap->log_addrs.cec_version < CEC_OP_CEC_VERSION_2_0 &&
+			 !(dir_fl & BCAST1_4))
+			valid_la = false;
+	}
+	if (valid_la && min_len) {
+		/* These messages have special length requirements */
+		switch (cmd) {
+		case CEC_MSG_TIMER_STATUS:
+			if (msg->msg[2] & 0x10) {
+				switch (msg->msg[2] & 0xf) {
+				case CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE:
+				case CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE:
+					if (msg->len < 5)
+						valid_la = false;
+					break;
+				}
+			} else if ((msg->msg[2] & 0xf) == CEC_OP_PROG_ERROR_DUPLICATE) {
+				if (msg->len < 5)
+					valid_la = false;
+			}
+			break;
+		case CEC_MSG_RECORD_ON:
+			switch (msg->msg[2]) {
+			case CEC_OP_RECORD_SRC_OWN:
+				break;
+			case CEC_OP_RECORD_SRC_DIGITAL:
+				if (msg->len < 10)
+					valid_la = false;
+				break;
+			case CEC_OP_RECORD_SRC_ANALOG:
+				if (msg->len < 7)
+					valid_la = false;
+				break;
+			case CEC_OP_RECORD_SRC_EXT_PLUG:
+				if (msg->len < 4)
+					valid_la = false;
+				break;
+			case CEC_OP_RECORD_SRC_EXT_PHYS_ADDR:
+				if (msg->len < 5)
+					valid_la = false;
+				break;
+			}
+			break;
+		}
+	}
+
+	/* It's a valid message and not a poll or CDC message */
+	if (valid_la && msg->len > 1 && cmd != CEC_MSG_CDC_MESSAGE) {
+		bool abort = cmd == CEC_MSG_FEATURE_ABORT;
+
+		/* The aborted command is in msg[2] */
+		if (abort)
+			cmd = msg->msg[2];
+
+		/*
+		 * Walk over all transmitted messages that are waiting for a
+		 * reply.
+		 */
+		list_for_each_entry(data, &adap->wait_queue, list) {
+			struct cec_msg *dst = &data->msg;
+
+			/*
+			 * The *only* CEC message that has two possible replies
+			 * is CEC_MSG_INITIATE_ARC.
+			 * In this case allow either of the two replies.
+			 */
+			if (!abort && dst->msg[1] == CEC_MSG_INITIATE_ARC &&
+			    (cmd == CEC_MSG_REPORT_ARC_INITIATED ||
+			     cmd == CEC_MSG_REPORT_ARC_TERMINATED) &&
+			    (dst->reply == CEC_MSG_REPORT_ARC_INITIATED ||
+			     dst->reply == CEC_MSG_REPORT_ARC_TERMINATED))
+				dst->reply = cmd;
+
+			/* Does the command match? */
+			if ((abort && cmd != dst->msg[1]) ||
+			    (!abort && cmd != dst->reply))
+				continue;
+
+			/* Does the addressing match? */
+			if (msg_init != cec_msg_destination(dst) &&
+			    !cec_msg_is_broadcast(dst))
+				continue;
+
+			/* We got a reply */
+			memcpy(dst->msg, msg->msg, msg->len);
+			dst->len = msg->len;
+			dst->rx_ts = msg->rx_ts;
+			dst->rx_status = msg->rx_status;
+			if (abort)
+				dst->rx_status |= CEC_RX_STATUS_FEATURE_ABORT;
+			msg->flags = dst->flags;
+			/* Remove it from the wait_queue */
+			list_del_init(&data->list);
+
+			/* Cancel the pending timeout work */
+			if (!cancel_delayed_work(&data->work)) {
+				mutex_unlock(&adap->lock);
+				flush_scheduled_work();
+				mutex_lock(&adap->lock);
+			}
+			/*
+			 * Mark this as a reply, provided someone is still
+			 * waiting for the answer.
+			 */
+			if (data->fh)
+				is_reply = true;
+			cec_data_completed(data);
+			break;
+		}
+	}
+	mutex_unlock(&adap->lock);
+
+	/* Pass the message on to any monitoring filehandles */
+	cec_queue_msg_monitor(adap, msg, valid_la);
+
+	/* We're done if it is not for us or a poll message */
+	if (!valid_la || msg->len <= 1)
+		return;
+
+	if (adap->log_addrs.log_addr_mask == 0)
+		return;
+
+	/*
+	 * Process the message on the protocol level. If is_reply is true,
+	 * then cec_receive_notify() won't pass on the reply to the listener(s)
+	 * since that was already done by cec_data_completed() above.
+	 */
+	cec_receive_notify(adap, msg, is_reply);
+}
+EXPORT_SYMBOL_GPL(cec_received_msg_ts);
+
+/* Logical Address Handling */
+
+/*
+ * Attempt to claim a specific logical address.
+ *
+ * This function is called with adap->lock held.
+ */
+static int cec_config_log_addr(struct cec_adapter *adap,
+			       unsigned int idx,
+			       unsigned int log_addr)
+{
+	struct cec_log_addrs *las = &adap->log_addrs;
+	struct cec_msg msg = { };
+	const unsigned int max_retries = 2;
+	unsigned int i;
+	int err;
+
+	if (cec_has_log_addr(adap, log_addr))
+		return 0;
+
+	/* Send poll message */
+	msg.len = 1;
+	msg.msg[0] = (log_addr << 4) | log_addr;
+
+	for (i = 0; i < max_retries; i++) {
+		err = cec_transmit_msg_fh(adap, &msg, NULL, true);
+
+		/*
+		 * While trying to poll the physical address was reset
+		 * and the adapter was unconfigured, so bail out.
+		 */
+		if (!adap->is_configuring)
+			return -EINTR;
+
+		if (err)
+			return err;
+
+		/*
+		 * The message was aborted due to a disconnect or
+		 * unconfigure, just bail out.
+		 */
+		if (msg.tx_status & CEC_TX_STATUS_ABORTED)
+			return -EINTR;
+		if (msg.tx_status & CEC_TX_STATUS_OK)
+			return 0;
+		if (msg.tx_status & CEC_TX_STATUS_NACK)
+			break;
+		/*
+		 * Retry up to max_retries times if the message was neither
+		 * OKed or NACKed. This can happen due to e.g. a Lost
+		 * Arbitration condition.
+		 */
+	}
+
+	/*
+	 * If we are unable to get an OK or a NACK after max_retries attempts
+	 * (and note that each attempt already consists of four polls), then
+	 * then we assume that something is really weird and that it is not a
+	 * good idea to try and claim this logical address.
+	 */
+	if (i == max_retries)
+		return 0;
+
+	/*
+	 * Message not acknowledged, so this logical
+	 * address is free to use.
+	 */
+	err = adap->ops->adap_log_addr(adap, log_addr);
+	if (err)
+		return err;
+
+	las->log_addr[idx] = log_addr;
+	las->log_addr_mask |= 1 << log_addr;
+	adap->phys_addrs[log_addr] = adap->phys_addr;
+	return 1;
+}
+
+/*
+ * Unconfigure the adapter: clear all logical addresses and send
+ * the state changed event.
+ *
+ * This function is called with adap->lock held.
+ */
+static void cec_adap_unconfigure(struct cec_adapter *adap)
+{
+	if (!adap->needs_hpd ||
+	    adap->phys_addr != CEC_PHYS_ADDR_INVALID)
+		WARN_ON(adap->ops->adap_log_addr(adap, CEC_LOG_ADDR_INVALID));
+	adap->log_addrs.log_addr_mask = 0;
+	adap->is_configuring = false;
+	adap->is_configured = false;
+	memset(adap->phys_addrs, 0xff, sizeof(adap->phys_addrs));
+	cec_flush(adap);
+	wake_up_interruptible(&adap->kthread_waitq);
+	cec_post_state_event(adap);
+}
+
+/*
+ * Attempt to claim the required logical addresses.
+ */
+static int cec_config_thread_func(void *arg)
+{
+	/* The various LAs for each type of device */
+	static const u8 tv_log_addrs[] = {
+		CEC_LOG_ADDR_TV, CEC_LOG_ADDR_SPECIFIC,
+		CEC_LOG_ADDR_INVALID
+	};
+	static const u8 record_log_addrs[] = {
+		CEC_LOG_ADDR_RECORD_1, CEC_LOG_ADDR_RECORD_2,
+		CEC_LOG_ADDR_RECORD_3,
+		CEC_LOG_ADDR_BACKUP_1, CEC_LOG_ADDR_BACKUP_2,
+		CEC_LOG_ADDR_INVALID
+	};
+	static const u8 tuner_log_addrs[] = {
+		CEC_LOG_ADDR_TUNER_1, CEC_LOG_ADDR_TUNER_2,
+		CEC_LOG_ADDR_TUNER_3, CEC_LOG_ADDR_TUNER_4,
+		CEC_LOG_ADDR_BACKUP_1, CEC_LOG_ADDR_BACKUP_2,
+		CEC_LOG_ADDR_INVALID
+	};
+	static const u8 playback_log_addrs[] = {
+		CEC_LOG_ADDR_PLAYBACK_1, CEC_LOG_ADDR_PLAYBACK_2,
+		CEC_LOG_ADDR_PLAYBACK_3,
+		CEC_LOG_ADDR_BACKUP_1, CEC_LOG_ADDR_BACKUP_2,
+		CEC_LOG_ADDR_INVALID
+	};
+	static const u8 audiosystem_log_addrs[] = {
+		CEC_LOG_ADDR_AUDIOSYSTEM,
+		CEC_LOG_ADDR_INVALID
+	};
+	static const u8 specific_use_log_addrs[] = {
+		CEC_LOG_ADDR_SPECIFIC,
+		CEC_LOG_ADDR_BACKUP_1, CEC_LOG_ADDR_BACKUP_2,
+		CEC_LOG_ADDR_INVALID
+	};
+	static const u8 *type2addrs[6] = {
+		[CEC_LOG_ADDR_TYPE_TV] = tv_log_addrs,
+		[CEC_LOG_ADDR_TYPE_RECORD] = record_log_addrs,
+		[CEC_LOG_ADDR_TYPE_TUNER] = tuner_log_addrs,
+		[CEC_LOG_ADDR_TYPE_PLAYBACK] = playback_log_addrs,
+		[CEC_LOG_ADDR_TYPE_AUDIOSYSTEM] = audiosystem_log_addrs,
+		[CEC_LOG_ADDR_TYPE_SPECIFIC] = specific_use_log_addrs,
+	};
+	static const u16 type2mask[] = {
+		[CEC_LOG_ADDR_TYPE_TV] = CEC_LOG_ADDR_MASK_TV,
+		[CEC_LOG_ADDR_TYPE_RECORD] = CEC_LOG_ADDR_MASK_RECORD,
+		[CEC_LOG_ADDR_TYPE_TUNER] = CEC_LOG_ADDR_MASK_TUNER,
+		[CEC_LOG_ADDR_TYPE_PLAYBACK] = CEC_LOG_ADDR_MASK_PLAYBACK,
+		[CEC_LOG_ADDR_TYPE_AUDIOSYSTEM] = CEC_LOG_ADDR_MASK_AUDIOSYSTEM,
+		[CEC_LOG_ADDR_TYPE_SPECIFIC] = CEC_LOG_ADDR_MASK_SPECIFIC,
+	};
+	struct cec_adapter *adap = arg;
+	struct cec_log_addrs *las = &adap->log_addrs;
+	int err;
+	int i, j;
+
+	mutex_lock(&adap->lock);
+	dprintk(1, "physical address: %x.%x.%x.%x, claim %d logical addresses\n",
+		cec_phys_addr_exp(adap->phys_addr), las->num_log_addrs);
+	las->log_addr_mask = 0;
+
+	if (las->log_addr_type[0] == CEC_LOG_ADDR_TYPE_UNREGISTERED)
+		goto configured;
+
+	for (i = 0; i < las->num_log_addrs; i++) {
+		unsigned int type = las->log_addr_type[i];
+		const u8 *la_list;
+		u8 last_la;
+
+		/*
+		 * The TV functionality can only map to physical address 0.
+		 * For any other address, try the Specific functionality
+		 * instead as per the spec.
+		 */
+		if (adap->phys_addr && type == CEC_LOG_ADDR_TYPE_TV)
+			type = CEC_LOG_ADDR_TYPE_SPECIFIC;
+
+		la_list = type2addrs[type];
+		last_la = las->log_addr[i];
+		las->log_addr[i] = CEC_LOG_ADDR_INVALID;
+		if (last_la == CEC_LOG_ADDR_INVALID ||
+		    last_la == CEC_LOG_ADDR_UNREGISTERED ||
+		    !((1 << last_la) & type2mask[type]))
+			last_la = la_list[0];
+
+		err = cec_config_log_addr(adap, i, last_la);
+		if (err > 0) /* Reused last LA */
+			continue;
+
+		if (err < 0)
+			goto unconfigure;
+
+		for (j = 0; la_list[j] != CEC_LOG_ADDR_INVALID; j++) {
+			/* Tried this one already, skip it */
+			if (la_list[j] == last_la)
+				continue;
+			/* The backup addresses are CEC 2.0 specific */
+			if ((la_list[j] == CEC_LOG_ADDR_BACKUP_1 ||
+			     la_list[j] == CEC_LOG_ADDR_BACKUP_2) &&
+			    las->cec_version < CEC_OP_CEC_VERSION_2_0)
+				continue;
+
+			err = cec_config_log_addr(adap, i, la_list[j]);
+			if (err == 0) /* LA is in use */
+				continue;
+			if (err < 0)
+				goto unconfigure;
+			/* Done, claimed an LA */
+			break;
+		}
+
+		if (la_list[j] == CEC_LOG_ADDR_INVALID)
+			dprintk(1, "could not claim LA %d\n", i);
+	}
+
+	if (adap->log_addrs.log_addr_mask == 0 &&
+	    !(las->flags & CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK))
+		goto unconfigure;
+
+configured:
+	if (adap->log_addrs.log_addr_mask == 0) {
+		/* Fall back to unregistered */
+		las->log_addr[0] = CEC_LOG_ADDR_UNREGISTERED;
+		las->log_addr_mask = 1 << las->log_addr[0];
+		for (i = 1; i < las->num_log_addrs; i++)
+			las->log_addr[i] = CEC_LOG_ADDR_INVALID;
+	}
+	for (i = las->num_log_addrs; i < CEC_MAX_LOG_ADDRS; i++)
+		las->log_addr[i] = CEC_LOG_ADDR_INVALID;
+	adap->is_configured = true;
+	adap->is_configuring = false;
+	cec_post_state_event(adap);
+
+	/*
+	 * Now post the Report Features and Report Physical Address broadcast
+	 * messages. Note that these are non-blocking transmits, meaning that
+	 * they are just queued up and once adap->lock is unlocked the main
+	 * thread will kick in and start transmitting these.
+	 *
+	 * If after this function is done (but before one or more of these
+	 * messages are actually transmitted) the CEC adapter is unconfigured,
+	 * then any remaining messages will be dropped by the main thread.
+	 */
+	for (i = 0; i < las->num_log_addrs; i++) {
+		struct cec_msg msg = {};
+
+		if (las->log_addr[i] == CEC_LOG_ADDR_INVALID ||
+		    (las->flags & CEC_LOG_ADDRS_FL_CDC_ONLY))
+			continue;
+
+		msg.msg[0] = (las->log_addr[i] << 4) | 0x0f;
+
+		/* Report Features must come first according to CEC 2.0 */
+		if (las->log_addr[i] != CEC_LOG_ADDR_UNREGISTERED &&
+		    adap->log_addrs.cec_version >= CEC_OP_CEC_VERSION_2_0) {
+			cec_fill_msg_report_features(adap, &msg, i);
+			cec_transmit_msg_fh(adap, &msg, NULL, false);
+		}
+
+		/* Report Physical Address */
+		cec_msg_report_physical_addr(&msg, adap->phys_addr,
+					     las->primary_device_type[i]);
+		dprintk(1, "config: la %d pa %x.%x.%x.%x\n",
+			las->log_addr[i],
+			cec_phys_addr_exp(adap->phys_addr));
+		cec_transmit_msg_fh(adap, &msg, NULL, false);
+
+		/* Report Vendor ID */
+		if (adap->log_addrs.vendor_id != CEC_VENDOR_ID_NONE) {
+			cec_msg_device_vendor_id(&msg,
+						 adap->log_addrs.vendor_id);
+			cec_transmit_msg_fh(adap, &msg, NULL, false);
+		}
+	}
+	adap->kthread_config = NULL;
+	complete(&adap->config_completion);
+	mutex_unlock(&adap->lock);
+	return 0;
+
+unconfigure:
+	for (i = 0; i < las->num_log_addrs; i++)
+		las->log_addr[i] = CEC_LOG_ADDR_INVALID;
+	cec_adap_unconfigure(adap);
+	adap->kthread_config = NULL;
+	mutex_unlock(&adap->lock);
+	complete(&adap->config_completion);
+	return 0;
+}
+
+/*
+ * Called from either __cec_s_phys_addr or __cec_s_log_addrs to claim the
+ * logical addresses.
+ *
+ * This function is called with adap->lock held.
+ */
+static void cec_claim_log_addrs(struct cec_adapter *adap, bool block)
+{
+	if (WARN_ON(adap->is_configuring || adap->is_configured))
+		return;
+
+	init_completion(&adap->config_completion);
+
+	/* Ready to kick off the thread */
+	adap->is_configuring = true;
+	adap->kthread_config = kthread_run(cec_config_thread_func, adap,
+					   "ceccfg-%s", adap->name);
+	if (IS_ERR(adap->kthread_config)) {
+		adap->kthread_config = NULL;
+	} else if (block) {
+		mutex_unlock(&adap->lock);
+		wait_for_completion(&adap->config_completion);
+		mutex_lock(&adap->lock);
+	}
+}
+
+/* Set a new physical address and send an event notifying userspace of this.
+ *
+ * This function is called with adap->lock held.
+ */
+void __cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block)
+{
+	if (phys_addr == adap->phys_addr)
+		return;
+	if (phys_addr != CEC_PHYS_ADDR_INVALID && adap->devnode.unregistered)
+		return;
+
+	dprintk(1, "new physical address %x.%x.%x.%x\n",
+		cec_phys_addr_exp(phys_addr));
+	if (phys_addr == CEC_PHYS_ADDR_INVALID ||
+	    adap->phys_addr != CEC_PHYS_ADDR_INVALID) {
+		adap->phys_addr = CEC_PHYS_ADDR_INVALID;
+		cec_post_state_event(adap);
+		cec_adap_unconfigure(adap);
+		/* Disabling monitor all mode should always succeed */
+		if (adap->monitor_all_cnt)
+			WARN_ON(call_op(adap, adap_monitor_all_enable, false));
+		mutex_lock(&adap->devnode.lock);
+		if (adap->needs_hpd || list_empty(&adap->devnode.fhs)) {
+			WARN_ON(adap->ops->adap_enable(adap, false));
+			adap->transmit_in_progress = false;
+			wake_up_interruptible(&adap->kthread_waitq);
+		}
+		mutex_unlock(&adap->devnode.lock);
+		if (phys_addr == CEC_PHYS_ADDR_INVALID)
+			return;
+	}
+
+	mutex_lock(&adap->devnode.lock);
+	adap->last_initiator = 0xff;
+	adap->transmit_in_progress = false;
+
+	if ((adap->needs_hpd || list_empty(&adap->devnode.fhs)) &&
+	    adap->ops->adap_enable(adap, true)) {
+		mutex_unlock(&adap->devnode.lock);
+		return;
+	}
+
+	if (adap->monitor_all_cnt &&
+	    call_op(adap, adap_monitor_all_enable, true)) {
+		if (adap->needs_hpd || list_empty(&adap->devnode.fhs))
+			WARN_ON(adap->ops->adap_enable(adap, false));
+		mutex_unlock(&adap->devnode.lock);
+		return;
+	}
+	mutex_unlock(&adap->devnode.lock);
+
+	adap->phys_addr = phys_addr;
+	cec_post_state_event(adap);
+	if (adap->log_addrs.num_log_addrs)
+		cec_claim_log_addrs(adap, block);
+}
+
+void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block)
+{
+	if (IS_ERR_OR_NULL(adap))
+		return;
+
+	mutex_lock(&adap->lock);
+	__cec_s_phys_addr(adap, phys_addr, block);
+	mutex_unlock(&adap->lock);
+}
+EXPORT_SYMBOL_GPL(cec_s_phys_addr);
+
+void cec_s_phys_addr_from_edid(struct cec_adapter *adap,
+			       const struct edid *edid)
+{
+	u16 pa = CEC_PHYS_ADDR_INVALID;
+
+	if (edid && edid->extensions)
+		pa = cec_get_edid_phys_addr((const u8 *)edid,
+				EDID_LENGTH * (edid->extensions + 1), NULL);
+	cec_s_phys_addr(adap, pa, false);
+}
+EXPORT_SYMBOL_GPL(cec_s_phys_addr_from_edid);
+
+void cec_s_conn_info(struct cec_adapter *adap,
+		     const struct cec_connector_info *conn_info)
+{
+	if (IS_ERR_OR_NULL(adap))
+		return;
+
+	if (!(adap->capabilities & CEC_CAP_CONNECTOR_INFO))
+		return;
+
+	mutex_lock(&adap->lock);
+	if (conn_info)
+		adap->conn_info = *conn_info;
+	else
+		memset(&adap->conn_info, 0, sizeof(adap->conn_info));
+	cec_post_state_event(adap);
+	mutex_unlock(&adap->lock);
+}
+EXPORT_SYMBOL_GPL(cec_s_conn_info);
+
+/*
+ * Called from either the ioctl or a driver to set the logical addresses.
+ *
+ * This function is called with adap->lock held.
+ */
+int __cec_s_log_addrs(struct cec_adapter *adap,
+		      struct cec_log_addrs *log_addrs, bool block)
+{
+	u16 type_mask = 0;
+	int i;
+
+	if (adap->devnode.unregistered)
+		return -ENODEV;
+
+	if (!log_addrs || log_addrs->num_log_addrs == 0) {
+		cec_adap_unconfigure(adap);
+		adap->log_addrs.num_log_addrs = 0;
+		for (i = 0; i < CEC_MAX_LOG_ADDRS; i++)
+			adap->log_addrs.log_addr[i] = CEC_LOG_ADDR_INVALID;
+		adap->log_addrs.osd_name[0] = '\0';
+		adap->log_addrs.vendor_id = CEC_VENDOR_ID_NONE;
+		adap->log_addrs.cec_version = CEC_OP_CEC_VERSION_2_0;
+		return 0;
+	}
+
+	if (log_addrs->flags & CEC_LOG_ADDRS_FL_CDC_ONLY) {
+		/*
+		 * Sanitize log_addrs fields if a CDC-Only device is
+		 * requested.
+		 */
+		log_addrs->num_log_addrs = 1;
+		log_addrs->osd_name[0] = '\0';
+		log_addrs->vendor_id = CEC_VENDOR_ID_NONE;
+		log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_UNREGISTERED;
+		/*
+		 * This is just an internal convention since a CDC-Only device
+		 * doesn't have to be a switch. But switches already use
+		 * unregistered, so it makes some kind of sense to pick this
+		 * as the primary device. Since a CDC-Only device never sends
+		 * any 'normal' CEC messages this primary device type is never
+		 * sent over the CEC bus.
+		 */
+		log_addrs->primary_device_type[0] = CEC_OP_PRIM_DEVTYPE_SWITCH;
+		log_addrs->all_device_types[0] = 0;
+		log_addrs->features[0][0] = 0;
+		log_addrs->features[0][1] = 0;
+	}
+
+	/* Ensure the osd name is 0-terminated */
+	log_addrs->osd_name[sizeof(log_addrs->osd_name) - 1] = '\0';
+
+	/* Sanity checks */
+	if (log_addrs->num_log_addrs > adap->available_log_addrs) {
+		dprintk(1, "num_log_addrs > %d\n", adap->available_log_addrs);
+		return -EINVAL;
+	}
+
+	/*
+	 * Vendor ID is a 24 bit number, so check if the value is
+	 * within the correct range.
+	 */
+	if (log_addrs->vendor_id != CEC_VENDOR_ID_NONE &&
+	    (log_addrs->vendor_id & 0xff000000) != 0) {
+		dprintk(1, "invalid vendor ID\n");
+		return -EINVAL;
+	}
+
+	if (log_addrs->cec_version != CEC_OP_CEC_VERSION_1_4 &&
+	    log_addrs->cec_version != CEC_OP_CEC_VERSION_2_0) {
+		dprintk(1, "invalid CEC version\n");
+		return -EINVAL;
+	}
+
+	if (log_addrs->num_log_addrs > 1)
+		for (i = 0; i < log_addrs->num_log_addrs; i++)
+			if (log_addrs->log_addr_type[i] ==
+					CEC_LOG_ADDR_TYPE_UNREGISTERED) {
+				dprintk(1, "num_log_addrs > 1 can't be combined with unregistered LA\n");
+				return -EINVAL;
+			}
+
+	for (i = 0; i < log_addrs->num_log_addrs; i++) {
+		const u8 feature_sz = ARRAY_SIZE(log_addrs->features[0]);
+		u8 *features = log_addrs->features[i];
+		bool op_is_dev_features = false;
+		unsigned j;
+
+		log_addrs->log_addr[i] = CEC_LOG_ADDR_INVALID;
+		if (type_mask & (1 << log_addrs->log_addr_type[i])) {
+			dprintk(1, "duplicate logical address type\n");
+			return -EINVAL;
+		}
+		type_mask |= 1 << log_addrs->log_addr_type[i];
+		if ((type_mask & (1 << CEC_LOG_ADDR_TYPE_RECORD)) &&
+		    (type_mask & (1 << CEC_LOG_ADDR_TYPE_PLAYBACK))) {
+			/* Record already contains the playback functionality */
+			dprintk(1, "invalid record + playback combination\n");
+			return -EINVAL;
+		}
+		if (log_addrs->primary_device_type[i] >
+					CEC_OP_PRIM_DEVTYPE_PROCESSOR) {
+			dprintk(1, "unknown primary device type\n");
+			return -EINVAL;
+		}
+		if (log_addrs->primary_device_type[i] == 2) {
+			dprintk(1, "invalid primary device type\n");
+			return -EINVAL;
+		}
+		if (log_addrs->log_addr_type[i] > CEC_LOG_ADDR_TYPE_UNREGISTERED) {
+			dprintk(1, "unknown logical address type\n");
+			return -EINVAL;
+		}
+		for (j = 0; j < feature_sz; j++) {
+			if ((features[j] & 0x80) == 0) {
+				if (op_is_dev_features)
+					break;
+				op_is_dev_features = true;
+			}
+		}
+		if (!op_is_dev_features || j == feature_sz) {
+			dprintk(1, "malformed features\n");
+			return -EINVAL;
+		}
+		/* Zero unused part of the feature array */
+		memset(features + j + 1, 0, feature_sz - j - 1);
+	}
+
+	if (log_addrs->cec_version >= CEC_OP_CEC_VERSION_2_0) {
+		if (log_addrs->num_log_addrs > 2) {
+			dprintk(1, "CEC 2.0 allows no more than 2 logical addresses\n");
+			return -EINVAL;
+		}
+		if (log_addrs->num_log_addrs == 2) {
+			if (!(type_mask & ((1 << CEC_LOG_ADDR_TYPE_AUDIOSYSTEM) |
+					   (1 << CEC_LOG_ADDR_TYPE_TV)))) {
+				dprintk(1, "two LAs is only allowed for audiosystem and TV\n");
+				return -EINVAL;
+			}
+			if (!(type_mask & ((1 << CEC_LOG_ADDR_TYPE_PLAYBACK) |
+					   (1 << CEC_LOG_ADDR_TYPE_RECORD)))) {
+				dprintk(1, "an audiosystem/TV can only be combined with record or playback\n");
+				return -EINVAL;
+			}
+		}
+	}
+
+	/* Zero unused LAs */
+	for (i = log_addrs->num_log_addrs; i < CEC_MAX_LOG_ADDRS; i++) {
+		log_addrs->primary_device_type[i] = 0;
+		log_addrs->log_addr_type[i] = 0;
+		log_addrs->all_device_types[i] = 0;
+		memset(log_addrs->features[i], 0,
+		       sizeof(log_addrs->features[i]));
+	}
+
+	log_addrs->log_addr_mask = adap->log_addrs.log_addr_mask;
+	adap->log_addrs = *log_addrs;
+	if (adap->phys_addr != CEC_PHYS_ADDR_INVALID)
+		cec_claim_log_addrs(adap, block);
+	return 0;
+}
+
+int cec_s_log_addrs(struct cec_adapter *adap,
+		    struct cec_log_addrs *log_addrs, bool block)
+{
+	int err;
+
+	mutex_lock(&adap->lock);
+	err = __cec_s_log_addrs(adap, log_addrs, block);
+	mutex_unlock(&adap->lock);
+	return err;
+}
+EXPORT_SYMBOL_GPL(cec_s_log_addrs);
+
+/* High-level core CEC message handling */
+
+/* Fill in the Report Features message */
+static void cec_fill_msg_report_features(struct cec_adapter *adap,
+					 struct cec_msg *msg,
+					 unsigned int la_idx)
+{
+	const struct cec_log_addrs *las = &adap->log_addrs;
+	const u8 *features = las->features[la_idx];
+	bool op_is_dev_features = false;
+	unsigned int idx;
+
+	/* Report Features */
+	msg->msg[0] = (las->log_addr[la_idx] << 4) | 0x0f;
+	msg->len = 4;
+	msg->msg[1] = CEC_MSG_REPORT_FEATURES;
+	msg->msg[2] = adap->log_addrs.cec_version;
+	msg->msg[3] = las->all_device_types[la_idx];
+
+	/* Write RC Profiles first, then Device Features */
+	for (idx = 0; idx < ARRAY_SIZE(las->features[0]); idx++) {
+		msg->msg[msg->len++] = features[idx];
+		if ((features[idx] & CEC_OP_FEAT_EXT) == 0) {
+			if (op_is_dev_features)
+				break;
+			op_is_dev_features = true;
+		}
+	}
+}
+
+/* Transmit the Feature Abort message */
+static int cec_feature_abort_reason(struct cec_adapter *adap,
+				    struct cec_msg *msg, u8 reason)
+{
+	struct cec_msg tx_msg = { };
+
+	/*
+	 * Don't reply with CEC_MSG_FEATURE_ABORT to a CEC_MSG_FEATURE_ABORT
+	 * message!
+	 */
+	if (msg->msg[1] == CEC_MSG_FEATURE_ABORT)
+		return 0;
+	/* Don't Feature Abort messages from 'Unregistered' */
+	if (cec_msg_initiator(msg) == CEC_LOG_ADDR_UNREGISTERED)
+		return 0;
+	cec_msg_set_reply_to(&tx_msg, msg);
+	cec_msg_feature_abort(&tx_msg, msg->msg[1], reason);
+	return cec_transmit_msg(adap, &tx_msg, false);
+}
+
+static int cec_feature_abort(struct cec_adapter *adap, struct cec_msg *msg)
+{
+	return cec_feature_abort_reason(adap, msg,
+					CEC_OP_ABORT_UNRECOGNIZED_OP);
+}
+
+static int cec_feature_refused(struct cec_adapter *adap, struct cec_msg *msg)
+{
+	return cec_feature_abort_reason(adap, msg,
+					CEC_OP_ABORT_REFUSED);
+}
+
+/*
+ * Called when a CEC message is received. This function will do any
+ * necessary core processing. The is_reply bool is true if this message
+ * is a reply to an earlier transmit.
+ *
+ * The message is either a broadcast message or a valid directed message.
+ */
+static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg,
+			      bool is_reply)
+{
+	bool is_broadcast = cec_msg_is_broadcast(msg);
+	u8 dest_laddr = cec_msg_destination(msg);
+	u8 init_laddr = cec_msg_initiator(msg);
+	u8 devtype = cec_log_addr2dev(adap, dest_laddr);
+	int la_idx = cec_log_addr2idx(adap, dest_laddr);
+	bool from_unregistered = init_laddr == 0xf;
+	struct cec_msg tx_cec_msg = { };
+
+	dprintk(2, "%s: %*ph\n", __func__, msg->len, msg->msg);
+
+	/* If this is a CDC-Only device, then ignore any non-CDC messages */
+	if (cec_is_cdc_only(&adap->log_addrs) &&
+	    msg->msg[1] != CEC_MSG_CDC_MESSAGE)
+		return 0;
+
+	if (adap->ops->received) {
+		/* Allow drivers to process the message first */
+		if (adap->ops->received(adap, msg) != -ENOMSG)
+			return 0;
+	}
+
+	/*
+	 * REPORT_PHYSICAL_ADDR, CEC_MSG_USER_CONTROL_PRESSED and
+	 * CEC_MSG_USER_CONTROL_RELEASED messages always have to be
+	 * handled by the CEC core, even if the passthrough mode is on.
+	 * The others are just ignored if passthrough mode is on.
+	 */
+	switch (msg->msg[1]) {
+	case CEC_MSG_GET_CEC_VERSION:
+	case CEC_MSG_ABORT:
+	case CEC_MSG_GIVE_DEVICE_POWER_STATUS:
+	case CEC_MSG_GIVE_OSD_NAME:
+		/*
+		 * These messages reply with a directed message, so ignore if
+		 * the initiator is Unregistered.
+		 */
+		if (!adap->passthrough && from_unregistered)
+			return 0;
+		/* Fall through */
+	case CEC_MSG_GIVE_DEVICE_VENDOR_ID:
+	case CEC_MSG_GIVE_FEATURES:
+	case CEC_MSG_GIVE_PHYSICAL_ADDR:
+		/*
+		 * Skip processing these messages if the passthrough mode
+		 * is on.
+		 */
+		if (adap->passthrough)
+			goto skip_processing;
+		/* Ignore if addressing is wrong */
+		if (is_broadcast)
+			return 0;
+		break;
+
+	case CEC_MSG_USER_CONTROL_PRESSED:
+	case CEC_MSG_USER_CONTROL_RELEASED:
+		/* Wrong addressing mode: don't process */
+		if (is_broadcast || from_unregistered)
+			goto skip_processing;
+		break;
+
+	case CEC_MSG_REPORT_PHYSICAL_ADDR:
+		/*
+		 * This message is always processed, regardless of the
+		 * passthrough setting.
+		 *
+		 * Exception: don't process if wrong addressing mode.
+		 */
+		if (!is_broadcast)
+			goto skip_processing;
+		break;
+
+	default:
+		break;
+	}
+
+	cec_msg_set_reply_to(&tx_cec_msg, msg);
+
+	switch (msg->msg[1]) {
+	/* The following messages are processed but still passed through */
+	case CEC_MSG_REPORT_PHYSICAL_ADDR: {
+		u16 pa = (msg->msg[2] << 8) | msg->msg[3];
+
+		if (!from_unregistered)
+			adap->phys_addrs[init_laddr] = pa;
+		dprintk(1, "reported physical address %x.%x.%x.%x for logical address %d\n",
+			cec_phys_addr_exp(pa), init_laddr);
+		break;
+	}
+
+	case CEC_MSG_USER_CONTROL_PRESSED:
+		if (!(adap->capabilities & CEC_CAP_RC) ||
+		    !(adap->log_addrs.flags & CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU))
+			break;
+
+#ifdef CONFIG_MEDIA_CEC_RC
+		switch (msg->msg[2]) {
+		/*
+		 * Play function, this message can have variable length
+		 * depending on the specific play function that is used.
+		 */
+		case CEC_OP_UI_CMD_PLAY_FUNCTION:
+			if (msg->len == 2)
+				rc_keydown(adap->rc, RC_PROTO_CEC,
+					   msg->msg[2], 0);
+			else
+				rc_keydown(adap->rc, RC_PROTO_CEC,
+					   msg->msg[2] << 8 | msg->msg[3], 0);
+			break;
+		/*
+		 * Other function messages that are not handled.
+		 * Currently the RC framework does not allow to supply an
+		 * additional parameter to a keypress. These "keys" contain
+		 * other information such as channel number, an input number
+		 * etc.
+		 * For the time being these messages are not processed by the
+		 * framework and are simply forwarded to the user space.
+		 */
+		case CEC_OP_UI_CMD_SELECT_BROADCAST_TYPE:
+		case CEC_OP_UI_CMD_SELECT_SOUND_PRESENTATION:
+		case CEC_OP_UI_CMD_TUNE_FUNCTION:
+		case CEC_OP_UI_CMD_SELECT_MEDIA_FUNCTION:
+		case CEC_OP_UI_CMD_SELECT_AV_INPUT_FUNCTION:
+		case CEC_OP_UI_CMD_SELECT_AUDIO_INPUT_FUNCTION:
+			break;
+		default:
+			rc_keydown(adap->rc, RC_PROTO_CEC, msg->msg[2], 0);
+			break;
+		}
+#endif
+		break;
+
+	case CEC_MSG_USER_CONTROL_RELEASED:
+		if (!(adap->capabilities & CEC_CAP_RC) ||
+		    !(adap->log_addrs.flags & CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU))
+			break;
+#ifdef CONFIG_MEDIA_CEC_RC
+		rc_keyup(adap->rc);
+#endif
+		break;
+
+	/*
+	 * The remaining messages are only processed if the passthrough mode
+	 * is off.
+	 */
+	case CEC_MSG_GET_CEC_VERSION:
+		cec_msg_cec_version(&tx_cec_msg, adap->log_addrs.cec_version);
+		return cec_transmit_msg(adap, &tx_cec_msg, false);
+
+	case CEC_MSG_GIVE_PHYSICAL_ADDR:
+		/* Do nothing for CEC switches using addr 15 */
+		if (devtype == CEC_OP_PRIM_DEVTYPE_SWITCH && dest_laddr == 15)
+			return 0;
+		cec_msg_report_physical_addr(&tx_cec_msg, adap->phys_addr, devtype);
+		return cec_transmit_msg(adap, &tx_cec_msg, false);
+
+	case CEC_MSG_GIVE_DEVICE_VENDOR_ID:
+		if (adap->log_addrs.vendor_id == CEC_VENDOR_ID_NONE)
+			return cec_feature_abort(adap, msg);
+		cec_msg_device_vendor_id(&tx_cec_msg, adap->log_addrs.vendor_id);
+		return cec_transmit_msg(adap, &tx_cec_msg, false);
+
+	case CEC_MSG_ABORT:
+		/* Do nothing for CEC switches */
+		if (devtype == CEC_OP_PRIM_DEVTYPE_SWITCH)
+			return 0;
+		return cec_feature_refused(adap, msg);
+
+	case CEC_MSG_GIVE_OSD_NAME: {
+		if (adap->log_addrs.osd_name[0] == 0)
+			return cec_feature_abort(adap, msg);
+		cec_msg_set_osd_name(&tx_cec_msg, adap->log_addrs.osd_name);
+		return cec_transmit_msg(adap, &tx_cec_msg, false);
+	}
+
+	case CEC_MSG_GIVE_FEATURES:
+		if (adap->log_addrs.cec_version < CEC_OP_CEC_VERSION_2_0)
+			return cec_feature_abort(adap, msg);
+		cec_fill_msg_report_features(adap, &tx_cec_msg, la_idx);
+		return cec_transmit_msg(adap, &tx_cec_msg, false);
+
+	default:
+		/*
+		 * Unprocessed messages are aborted if userspace isn't doing
+		 * any processing either.
+		 */
+		if (!is_broadcast && !is_reply && !adap->follower_cnt &&
+		    !adap->cec_follower && msg->msg[1] != CEC_MSG_FEATURE_ABORT)
+			return cec_feature_abort(adap, msg);
+		break;
+	}
+
+skip_processing:
+	/* If this was a reply, then we're done, unless otherwise specified */
+	if (is_reply && !(msg->flags & CEC_MSG_FL_REPLY_TO_FOLLOWERS))
+		return 0;
+
+	/*
+	 * Send to the exclusive follower if there is one, otherwise send
+	 * to all followers.
+	 */
+	if (adap->cec_follower)
+		cec_queue_msg_fh(adap->cec_follower, msg);
+	else
+		cec_queue_msg_followers(adap, msg);
+	return 0;
+}
+
+/*
+ * Helper functions to keep track of the 'monitor all' use count.
+ *
+ * These functions are called with adap->lock held.
+ */
+int cec_monitor_all_cnt_inc(struct cec_adapter *adap)
+{
+	int ret = 0;
+
+	if (adap->monitor_all_cnt == 0)
+		ret = call_op(adap, adap_monitor_all_enable, 1);
+	if (ret == 0)
+		adap->monitor_all_cnt++;
+	return ret;
+}
+
+void cec_monitor_all_cnt_dec(struct cec_adapter *adap)
+{
+	adap->monitor_all_cnt--;
+	if (adap->monitor_all_cnt == 0)
+		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.
+ * Very useful for debugging.
+ */
+int cec_adap_status(struct seq_file *file, void *priv)
+{
+	struct cec_adapter *adap = dev_get_drvdata(file->private);
+	struct cec_data *data;
+
+	mutex_lock(&adap->lock);
+	seq_printf(file, "configured: %d\n", adap->is_configured);
+	seq_printf(file, "configuring: %d\n", adap->is_configuring);
+	seq_printf(file, "phys_addr: %x.%x.%x.%x\n",
+		   cec_phys_addr_exp(adap->phys_addr));
+	seq_printf(file, "number of LAs: %d\n", adap->log_addrs.num_log_addrs);
+	seq_printf(file, "LA mask: 0x%04x\n", adap->log_addrs.log_addr_mask);
+	if (adap->cec_follower)
+		seq_printf(file, "has CEC follower%s\n",
+			   adap->passthrough ? " (in passthrough mode)" : "");
+	if (adap->cec_initiator)
+		seq_puts(file, "has CEC initiator\n");
+	if (adap->monitor_all_cnt)
+		seq_printf(file, "file handles in Monitor All mode: %u\n",
+			   adap->monitor_all_cnt);
+	if (adap->tx_timeouts) {
+		seq_printf(file, "transmit timeouts: %u\n",
+			   adap->tx_timeouts);
+		adap->tx_timeouts = 0;
+	}
+	data = adap->transmitting;
+	if (data)
+		seq_printf(file, "transmitting message: %*ph (reply: %02x, timeout: %ums)\n",
+			   data->msg.len, data->msg.msg, data->msg.reply,
+			   data->msg.timeout);
+	seq_printf(file, "pending transmits: %u\n", adap->transmit_queue_sz);
+	list_for_each_entry(data, &adap->transmit_queue, list) {
+		seq_printf(file, "queued tx message: %*ph (reply: %02x, timeout: %ums)\n",
+			   data->msg.len, data->msg.msg, data->msg.reply,
+			   data->msg.timeout);
+	}
+	list_for_each_entry(data, &adap->wait_queue, list) {
+		seq_printf(file, "message waiting for reply: %*ph (reply: %02x, timeout: %ums)\n",
+			   data->msg.len, data->msg.msg, data->msg.reply,
+			   data->msg.timeout);
+	}
+
+	call_void_op(adap, adap_status, file);
+	mutex_unlock(&adap->lock);
+	return 0;
+}
+#endif
diff --git a/drivers/media/cec/core/cec-api.c b/drivers/media/cec/core/cec-api.c
new file mode 100644
index 000000000000..17d1cb2e5f97
--- /dev/null
+++ b/drivers/media/cec/core/cec-api.c
@@ -0,0 +1,701 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * cec-api.c - HDMI Consumer Electronics Control framework - API
+ *
+ * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/kmod.h>
+#include <linux/ktime.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/uaccess.h>
+#include <linux/version.h>
+
+#include <media/cec-pin.h>
+#include "cec-priv.h"
+#include "cec-pin-priv.h"
+
+static inline struct cec_devnode *cec_devnode_data(struct file *filp)
+{
+	struct cec_fh *fh = filp->private_data;
+
+	return &fh->adap->devnode;
+}
+
+/* CEC file operations */
+
+static __poll_t cec_poll(struct file *filp,
+			     struct poll_table_struct *poll)
+{
+	struct cec_fh *fh = filp->private_data;
+	struct cec_adapter *adap = fh->adap;
+	__poll_t res = 0;
+
+	poll_wait(filp, &fh->wait, poll);
+	if (!cec_is_registered(adap))
+		return EPOLLERR | EPOLLHUP;
+	mutex_lock(&adap->lock);
+	if (adap->is_configured &&
+	    adap->transmit_queue_sz < CEC_MAX_MSG_TX_QUEUE_SZ)
+		res |= EPOLLOUT | EPOLLWRNORM;
+	if (fh->queued_msgs)
+		res |= EPOLLIN | EPOLLRDNORM;
+	if (fh->total_queued_events)
+		res |= EPOLLPRI;
+	mutex_unlock(&adap->lock);
+	return res;
+}
+
+static bool cec_is_busy(const struct cec_adapter *adap,
+			const struct cec_fh *fh)
+{
+	bool valid_initiator = adap->cec_initiator && adap->cec_initiator == fh;
+	bool valid_follower = adap->cec_follower && adap->cec_follower == fh;
+
+	/*
+	 * Exclusive initiators and followers can always access the CEC adapter
+	 */
+	if (valid_initiator || valid_follower)
+		return false;
+	/*
+	 * All others can only access the CEC adapter if there is no
+	 * exclusive initiator and they are in INITIATOR mode.
+	 */
+	return adap->cec_initiator ||
+	       fh->mode_initiator == CEC_MODE_NO_INITIATOR;
+}
+
+static long cec_adap_g_caps(struct cec_adapter *adap,
+			    struct cec_caps __user *parg)
+{
+	struct cec_caps caps = {};
+
+	strscpy(caps.driver, adap->devnode.dev.parent->driver->name,
+		sizeof(caps.driver));
+	strscpy(caps.name, adap->name, sizeof(caps.name));
+	caps.available_log_addrs = adap->available_log_addrs;
+	caps.capabilities = adap->capabilities;
+	caps.version = LINUX_VERSION_CODE;
+	if (copy_to_user(parg, &caps, sizeof(caps)))
+		return -EFAULT;
+	return 0;
+}
+
+static long cec_adap_g_phys_addr(struct cec_adapter *adap,
+				 __u16 __user *parg)
+{
+	u16 phys_addr;
+
+	mutex_lock(&adap->lock);
+	phys_addr = adap->phys_addr;
+	mutex_unlock(&adap->lock);
+	if (copy_to_user(parg, &phys_addr, sizeof(phys_addr)))
+		return -EFAULT;
+	return 0;
+}
+
+static int cec_validate_phys_addr(u16 phys_addr)
+{
+	int i;
+
+	if (phys_addr == CEC_PHYS_ADDR_INVALID)
+		return 0;
+	for (i = 0; i < 16; i += 4)
+		if (phys_addr & (0xf << i))
+			break;
+	if (i == 16)
+		return 0;
+	for (i += 4; i < 16; i += 4)
+		if ((phys_addr & (0xf << i)) == 0)
+			return -EINVAL;
+	return 0;
+}
+
+static long cec_adap_s_phys_addr(struct cec_adapter *adap, struct cec_fh *fh,
+				 bool block, __u16 __user *parg)
+{
+	u16 phys_addr;
+	long err;
+
+	if (!(adap->capabilities & CEC_CAP_PHYS_ADDR))
+		return -ENOTTY;
+	if (copy_from_user(&phys_addr, parg, sizeof(phys_addr)))
+		return -EFAULT;
+
+	err = cec_validate_phys_addr(phys_addr);
+	if (err)
+		return err;
+	mutex_lock(&adap->lock);
+	if (cec_is_busy(adap, fh))
+		err = -EBUSY;
+	else
+		__cec_s_phys_addr(adap, phys_addr, block);
+	mutex_unlock(&adap->lock);
+	return err;
+}
+
+static long cec_adap_g_log_addrs(struct cec_adapter *adap,
+				 struct cec_log_addrs __user *parg)
+{
+	struct cec_log_addrs log_addrs;
+
+	mutex_lock(&adap->lock);
+	log_addrs = adap->log_addrs;
+	if (!adap->is_configured)
+		memset(log_addrs.log_addr, CEC_LOG_ADDR_INVALID,
+		       sizeof(log_addrs.log_addr));
+	mutex_unlock(&adap->lock);
+
+	if (copy_to_user(parg, &log_addrs, sizeof(log_addrs)))
+		return -EFAULT;
+	return 0;
+}
+
+static long cec_adap_s_log_addrs(struct cec_adapter *adap, struct cec_fh *fh,
+				 bool block, struct cec_log_addrs __user *parg)
+{
+	struct cec_log_addrs log_addrs;
+	long err = -EBUSY;
+
+	if (!(adap->capabilities & CEC_CAP_LOG_ADDRS))
+		return -ENOTTY;
+	if (copy_from_user(&log_addrs, parg, sizeof(log_addrs)))
+		return -EFAULT;
+	log_addrs.flags &= CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK |
+			   CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU |
+			   CEC_LOG_ADDRS_FL_CDC_ONLY;
+	mutex_lock(&adap->lock);
+	if (!adap->is_configuring &&
+	    (!log_addrs.num_log_addrs || !adap->is_configured) &&
+	    !cec_is_busy(adap, fh)) {
+		err = __cec_s_log_addrs(adap, &log_addrs, block);
+		if (!err)
+			log_addrs = adap->log_addrs;
+	}
+	mutex_unlock(&adap->lock);
+	if (err)
+		return err;
+	if (copy_to_user(parg, &log_addrs, sizeof(log_addrs)))
+		return -EFAULT;
+	return 0;
+}
+
+static long cec_adap_g_connector_info(struct cec_adapter *adap,
+				      struct cec_log_addrs __user *parg)
+{
+	int ret = 0;
+
+	if (!(adap->capabilities & CEC_CAP_CONNECTOR_INFO))
+		return -ENOTTY;
+
+	mutex_lock(&adap->lock);
+	if (copy_to_user(parg, &adap->conn_info, sizeof(adap->conn_info)))
+		ret = -EFAULT;
+	mutex_unlock(&adap->lock);
+	return ret;
+}
+
+static long cec_transmit(struct cec_adapter *adap, struct cec_fh *fh,
+			 bool block, struct cec_msg __user *parg)
+{
+	struct cec_msg msg = {};
+	long err = 0;
+
+	if (!(adap->capabilities & CEC_CAP_TRANSMIT))
+		return -ENOTTY;
+	if (copy_from_user(&msg, parg, sizeof(msg)))
+		return -EFAULT;
+
+	mutex_lock(&adap->lock);
+	if (adap->log_addrs.num_log_addrs == 0)
+		err = -EPERM;
+	else if (adap->is_configuring)
+		err = -ENONET;
+	else if (cec_is_busy(adap, fh))
+		err = -EBUSY;
+	else
+		err = cec_transmit_msg_fh(adap, &msg, fh, block);
+	mutex_unlock(&adap->lock);
+	if (err)
+		return err;
+	if (copy_to_user(parg, &msg, sizeof(msg)))
+		return -EFAULT;
+	return 0;
+}
+
+/* Called by CEC_RECEIVE: wait for a message to arrive */
+static int cec_receive_msg(struct cec_fh *fh, struct cec_msg *msg, bool block)
+{
+	u32 timeout = msg->timeout;
+	int res;
+
+	do {
+		mutex_lock(&fh->lock);
+		/* Are there received messages queued up? */
+		if (fh->queued_msgs) {
+			/* Yes, return the first one */
+			struct cec_msg_entry *entry =
+				list_first_entry(&fh->msgs,
+						 struct cec_msg_entry, list);
+
+			list_del(&entry->list);
+			*msg = entry->msg;
+			kfree(entry);
+			fh->queued_msgs--;
+			mutex_unlock(&fh->lock);
+			/* restore original timeout value */
+			msg->timeout = timeout;
+			return 0;
+		}
+
+		/* No, return EAGAIN in non-blocking mode or wait */
+		mutex_unlock(&fh->lock);
+
+		/* Return when in non-blocking mode */
+		if (!block)
+			return -EAGAIN;
+
+		if (msg->timeout) {
+			/* The user specified a timeout */
+			res = wait_event_interruptible_timeout(fh->wait,
+							       fh->queued_msgs,
+				msecs_to_jiffies(msg->timeout));
+			if (res == 0)
+				res = -ETIMEDOUT;
+			else if (res > 0)
+				res = 0;
+		} else {
+			/* Wait indefinitely */
+			res = wait_event_interruptible(fh->wait,
+						       fh->queued_msgs);
+		}
+		/* Exit on error, otherwise loop to get the new message */
+	} while (!res);
+	return res;
+}
+
+static long cec_receive(struct cec_adapter *adap, struct cec_fh *fh,
+			bool block, struct cec_msg __user *parg)
+{
+	struct cec_msg msg = {};
+	long err;
+
+	if (copy_from_user(&msg, parg, sizeof(msg)))
+		return -EFAULT;
+
+	err = cec_receive_msg(fh, &msg, block);
+	if (err)
+		return err;
+	msg.flags = 0;
+	if (copy_to_user(parg, &msg, sizeof(msg)))
+		return -EFAULT;
+	return 0;
+}
+
+static long cec_dqevent(struct cec_adapter *adap, struct cec_fh *fh,
+			bool block, struct cec_event __user *parg)
+{
+	struct cec_event_entry *ev = NULL;
+	u64 ts = ~0ULL;
+	unsigned int i;
+	unsigned int ev_idx;
+	long err = 0;
+
+	mutex_lock(&fh->lock);
+	while (!fh->total_queued_events && block) {
+		mutex_unlock(&fh->lock);
+		err = wait_event_interruptible(fh->wait,
+					       fh->total_queued_events);
+		if (err)
+			return err;
+		mutex_lock(&fh->lock);
+	}
+
+	/* Find the oldest event */
+	for (i = 0; i < CEC_NUM_EVENTS; i++) {
+		struct cec_event_entry *entry =
+			list_first_entry_or_null(&fh->events[i],
+						 struct cec_event_entry, list);
+
+		if (entry && entry->ev.ts <= ts) {
+			ev = entry;
+			ev_idx = i;
+			ts = ev->ev.ts;
+		}
+	}
+
+	if (!ev) {
+		err = -EAGAIN;
+		goto unlock;
+	}
+	list_del(&ev->list);
+
+	if (copy_to_user(parg, &ev->ev, sizeof(ev->ev)))
+		err = -EFAULT;
+	if (ev_idx >= CEC_NUM_CORE_EVENTS)
+		kfree(ev);
+	fh->queued_events[ev_idx]--;
+	fh->total_queued_events--;
+
+unlock:
+	mutex_unlock(&fh->lock);
+	return err;
+}
+
+static long cec_g_mode(struct cec_adapter *adap, struct cec_fh *fh,
+		       u32 __user *parg)
+{
+	u32 mode = fh->mode_initiator | fh->mode_follower;
+
+	if (copy_to_user(parg, &mode, sizeof(mode)))
+		return -EFAULT;
+	return 0;
+}
+
+static long cec_s_mode(struct cec_adapter *adap, struct cec_fh *fh,
+		       u32 __user *parg)
+{
+	u32 mode;
+	u8 mode_initiator;
+	u8 mode_follower;
+	bool send_pin_event = false;
+	long err = 0;
+
+	if (copy_from_user(&mode, parg, sizeof(mode)))
+		return -EFAULT;
+	if (mode & ~(CEC_MODE_INITIATOR_MSK | CEC_MODE_FOLLOWER_MSK)) {
+		dprintk(1, "%s: invalid mode bits set\n", __func__);
+		return -EINVAL;
+	}
+
+	mode_initiator = mode & CEC_MODE_INITIATOR_MSK;
+	mode_follower = mode & CEC_MODE_FOLLOWER_MSK;
+
+	if (mode_initiator > CEC_MODE_EXCL_INITIATOR ||
+	    mode_follower > CEC_MODE_MONITOR_ALL) {
+		dprintk(1, "%s: unknown mode\n", __func__);
+		return -EINVAL;
+	}
+
+	if (mode_follower == CEC_MODE_MONITOR_ALL &&
+	    !(adap->capabilities & CEC_CAP_MONITOR_ALL)) {
+		dprintk(1, "%s: MONITOR_ALL not supported\n", __func__);
+		return -EINVAL;
+	}
+
+	if (mode_follower == CEC_MODE_MONITOR_PIN &&
+	    !(adap->capabilities & CEC_CAP_MONITOR_PIN)) {
+		dprintk(1, "%s: MONITOR_PIN not supported\n", __func__);
+		return -EINVAL;
+	}
+
+	/* Follower modes should always be able to send CEC messages */
+	if ((mode_initiator == CEC_MODE_NO_INITIATOR ||
+	     !(adap->capabilities & CEC_CAP_TRANSMIT)) &&
+	    mode_follower >= CEC_MODE_FOLLOWER &&
+	    mode_follower <= CEC_MODE_EXCL_FOLLOWER_PASSTHRU) {
+		dprintk(1, "%s: cannot transmit\n", __func__);
+		return -EINVAL;
+	}
+
+	/* Monitor modes require CEC_MODE_NO_INITIATOR */
+	if (mode_initiator && mode_follower >= CEC_MODE_MONITOR_PIN) {
+		dprintk(1, "%s: monitor modes require NO_INITIATOR\n",
+			__func__);
+		return -EINVAL;
+	}
+
+	/* Monitor modes require CAP_NET_ADMIN */
+	if (mode_follower >= CEC_MODE_MONITOR_PIN && !capable(CAP_NET_ADMIN))
+		return -EPERM;
+
+	mutex_lock(&adap->lock);
+	/*
+	 * You can't become exclusive follower if someone else already
+	 * has that job.
+	 */
+	if ((mode_follower == CEC_MODE_EXCL_FOLLOWER ||
+	     mode_follower == CEC_MODE_EXCL_FOLLOWER_PASSTHRU) &&
+	    adap->cec_follower && adap->cec_follower != fh)
+		err = -EBUSY;
+	/*
+	 * You can't become exclusive initiator if someone else already
+	 * has that job.
+	 */
+	if (mode_initiator == CEC_MODE_EXCL_INITIATOR &&
+	    adap->cec_initiator && adap->cec_initiator != fh)
+		err = -EBUSY;
+
+	if (!err) {
+		bool old_mon_all = fh->mode_follower == CEC_MODE_MONITOR_ALL;
+		bool new_mon_all = mode_follower == CEC_MODE_MONITOR_ALL;
+
+		if (old_mon_all != new_mon_all) {
+			if (new_mon_all)
+				err = cec_monitor_all_cnt_inc(adap);
+			else
+				cec_monitor_all_cnt_dec(adap);
+		}
+	}
+
+	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;
+	}
+
+	if (fh->mode_follower == CEC_MODE_FOLLOWER)
+		adap->follower_cnt--;
+	if (mode_follower == CEC_MODE_FOLLOWER)
+		adap->follower_cnt++;
+	if (send_pin_event) {
+		struct cec_event ev = {
+			.flags = CEC_EVENT_FL_INITIAL_STATE,
+		};
+
+		ev.event = adap->cec_pin_is_high ? CEC_EVENT_PIN_CEC_HIGH :
+						   CEC_EVENT_PIN_CEC_LOW;
+		cec_queue_event_fh(fh, &ev, 0);
+	}
+	if (mode_follower == CEC_MODE_EXCL_FOLLOWER ||
+	    mode_follower == CEC_MODE_EXCL_FOLLOWER_PASSTHRU) {
+		adap->passthrough =
+			mode_follower == CEC_MODE_EXCL_FOLLOWER_PASSTHRU;
+		adap->cec_follower = fh;
+	} else if (adap->cec_follower == fh) {
+		adap->passthrough = false;
+		adap->cec_follower = NULL;
+	}
+	if (mode_initiator == CEC_MODE_EXCL_INITIATOR)
+		adap->cec_initiator = fh;
+	else if (adap->cec_initiator == fh)
+		adap->cec_initiator = NULL;
+	fh->mode_initiator = mode_initiator;
+	fh->mode_follower = mode_follower;
+	mutex_unlock(&adap->lock);
+	return 0;
+}
+
+static long cec_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	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 (!cec_is_registered(adap))
+		return -ENODEV;
+
+	switch (cmd) {
+	case CEC_ADAP_G_CAPS:
+		return cec_adap_g_caps(adap, parg);
+
+	case CEC_ADAP_G_PHYS_ADDR:
+		return cec_adap_g_phys_addr(adap, parg);
+
+	case CEC_ADAP_S_PHYS_ADDR:
+		return cec_adap_s_phys_addr(adap, fh, block, parg);
+
+	case CEC_ADAP_G_LOG_ADDRS:
+		return cec_adap_g_log_addrs(adap, parg);
+
+	case CEC_ADAP_S_LOG_ADDRS:
+		return cec_adap_s_log_addrs(adap, fh, block, parg);
+
+	case CEC_ADAP_G_CONNECTOR_INFO:
+		return cec_adap_g_connector_info(adap, parg);
+
+	case CEC_TRANSMIT:
+		return cec_transmit(adap, fh, block, parg);
+
+	case CEC_RECEIVE:
+		return cec_receive(adap, fh, block, parg);
+
+	case CEC_DQEVENT:
+		return cec_dqevent(adap, fh, block, parg);
+
+	case CEC_G_MODE:
+		return cec_g_mode(adap, fh, parg);
+
+	case CEC_S_MODE:
+		return cec_s_mode(adap, fh, parg);
+
+	default:
+		return -ENOTTY;
+	}
+}
+
+static int cec_open(struct inode *inode, struct file *filp)
+{
+	struct cec_devnode *devnode =
+		container_of(inode->i_cdev, struct cec_devnode, cdev);
+	struct cec_adapter *adap = to_cec_adapter(devnode);
+	struct cec_fh *fh = kzalloc(sizeof(*fh), GFP_KERNEL);
+	/*
+	 * Initial events that are automatically sent when the cec device is
+	 * opened.
+	 */
+	struct cec_event ev = {
+		.event = CEC_EVENT_STATE_CHANGE,
+		.flags = CEC_EVENT_FL_INITIAL_STATE,
+	};
+	unsigned int i;
+	int err;
+
+	if (!fh)
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&fh->msgs);
+	INIT_LIST_HEAD(&fh->xfer_list);
+	for (i = 0; i < CEC_NUM_EVENTS; i++)
+		INIT_LIST_HEAD(&fh->events[i]);
+	mutex_init(&fh->lock);
+	init_waitqueue_head(&fh->wait);
+
+	fh->mode_initiator = CEC_MODE_INITIATOR;
+	fh->adap = adap;
+
+	err = cec_get_device(devnode);
+	if (err) {
+		kfree(fh);
+		return err;
+	}
+
+	mutex_lock(&devnode->lock);
+	if (list_empty(&devnode->fhs) &&
+	    !adap->needs_hpd &&
+	    adap->phys_addr == CEC_PHYS_ADDR_INVALID) {
+		err = adap->ops->adap_enable(adap, true);
+		if (err) {
+			mutex_unlock(&devnode->lock);
+			kfree(fh);
+			return err;
+		}
+	}
+	filp->private_data = fh;
+
+	/* Queue up initial state events */
+	ev.state_change.phys_addr = adap->phys_addr;
+	ev.state_change.log_addr_mask = adap->log_addrs.log_addr_mask;
+	ev.state_change.have_conn_info =
+		adap->conn_info.type != CEC_CONNECTOR_TYPE_NO_CONNECTOR;
+	cec_queue_event_fh(fh, &ev, 0);
+#ifdef CONFIG_CEC_PIN
+	if (adap->pin && adap->pin->ops->read_hpd) {
+		err = adap->pin->ops->read_hpd(adap);
+		if (err >= 0) {
+			ev.event = err ? CEC_EVENT_PIN_HPD_HIGH :
+					 CEC_EVENT_PIN_HPD_LOW;
+			cec_queue_event_fh(fh, &ev, 0);
+		}
+	}
+	if (adap->pin && adap->pin->ops->read_5v) {
+		err = adap->pin->ops->read_5v(adap);
+		if (err >= 0) {
+			ev.event = err ? CEC_EVENT_PIN_5V_HIGH :
+					 CEC_EVENT_PIN_5V_LOW;
+			cec_queue_event_fh(fh, &ev, 0);
+		}
+	}
+#endif
+
+	list_add(&fh->list, &devnode->fhs);
+	mutex_unlock(&devnode->lock);
+
+	return 0;
+}
+
+/* Override for the release function */
+static int cec_release(struct inode *inode, struct file *filp)
+{
+	struct cec_devnode *devnode = cec_devnode_data(filp);
+	struct cec_adapter *adap = to_cec_adapter(devnode);
+	struct cec_fh *fh = filp->private_data;
+	unsigned int i;
+
+	mutex_lock(&adap->lock);
+	if (adap->cec_initiator == fh)
+		adap->cec_initiator = NULL;
+	if (adap->cec_follower == fh) {
+		adap->cec_follower = NULL;
+		adap->passthrough = false;
+	}
+	if (fh->mode_follower == CEC_MODE_FOLLOWER)
+		adap->follower_cnt--;
+	if (fh->mode_follower == CEC_MODE_MONITOR_PIN)
+		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 (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);
+
+	/* Unhook pending transmits from this filehandle. */
+	mutex_lock(&adap->lock);
+	while (!list_empty(&fh->xfer_list)) {
+		struct cec_data *data =
+			list_first_entry(&fh->xfer_list, struct cec_data, xfer_list);
+
+		data->blocking = false;
+		data->fh = NULL;
+		list_del(&data->xfer_list);
+	}
+	mutex_unlock(&adap->lock);
+	while (!list_empty(&fh->msgs)) {
+		struct cec_msg_entry *entry =
+			list_first_entry(&fh->msgs, struct cec_msg_entry, list);
+
+		list_del(&entry->list);
+		kfree(entry);
+	}
+	for (i = CEC_NUM_CORE_EVENTS; i < CEC_NUM_EVENTS; i++) {
+		while (!list_empty(&fh->events[i])) {
+			struct cec_event_entry *entry =
+				list_first_entry(&fh->events[i],
+						 struct cec_event_entry, list);
+
+			list_del(&entry->list);
+			kfree(entry);
+		}
+	}
+	kfree(fh);
+
+	cec_put_device(devnode);
+	filp->private_data = NULL;
+	return 0;
+}
+
+const struct file_operations cec_devnode_fops = {
+	.owner = THIS_MODULE,
+	.open = cec_open,
+	.unlocked_ioctl = cec_ioctl,
+	.compat_ioctl = cec_ioctl,
+	.release = cec_release,
+	.poll = cec_poll,
+	.llseek = no_llseek,
+};
diff --git a/drivers/media/cec/core/cec-core.c b/drivers/media/cec/core/cec-core.c
new file mode 100644
index 000000000000..0c52e1bb3910
--- /dev/null
+++ b/drivers/media/cec/core/cec-core.c
@@ -0,0 +1,465 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * cec-core.c - HDMI Consumer Electronics Control framework - Core
+ *
+ * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/kmod.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/types.h>
+
+#include "cec-priv.h"
+
+#define CEC_NUM_DEVICES	256
+#define CEC_NAME	"cec"
+
+int cec_debug;
+module_param_named(debug, cec_debug, int, 0644);
+MODULE_PARM_DESC(debug, "debug level (0-2)");
+
+static bool debug_phys_addr;
+module_param(debug_phys_addr, bool, 0644);
+MODULE_PARM_DESC(debug_phys_addr, "add CEC_CAP_PHYS_ADDR if set");
+
+static dev_t cec_dev_t;
+
+/* Active devices */
+static DEFINE_MUTEX(cec_devnode_lock);
+static DECLARE_BITMAP(cec_devnode_nums, CEC_NUM_DEVICES);
+
+static struct dentry *top_cec_dir;
+
+/* dev to cec_devnode */
+#define to_cec_devnode(cd) container_of(cd, struct cec_devnode, dev)
+
+int cec_get_device(struct cec_devnode *devnode)
+{
+	/*
+	 * Check if the cec device is available. This needs to be done with
+	 * the devnode->lock held to prevent an open/unregister race:
+	 * without the lock, the device could be unregistered and freed between
+	 * the devnode->registered check and get_device() calls, leading to
+	 * a crash.
+	 */
+	mutex_lock(&devnode->lock);
+	/*
+	 * return ENXIO if the cec device has been removed
+	 * already or if it is not registered anymore.
+	 */
+	if (!devnode->registered) {
+		mutex_unlock(&devnode->lock);
+		return -ENXIO;
+	}
+	/* and increase the device refcount */
+	get_device(&devnode->dev);
+	mutex_unlock(&devnode->lock);
+	return 0;
+}
+
+void cec_put_device(struct cec_devnode *devnode)
+{
+	put_device(&devnode->dev);
+}
+
+/* Called when the last user of the cec device exits. */
+static void cec_devnode_release(struct device *cd)
+{
+	struct cec_devnode *devnode = to_cec_devnode(cd);
+
+	mutex_lock(&cec_devnode_lock);
+	/* Mark device node number as free */
+	clear_bit(devnode->minor, cec_devnode_nums);
+	mutex_unlock(&cec_devnode_lock);
+
+	cec_delete_adapter(to_cec_adapter(devnode));
+}
+
+static struct bus_type cec_bus_type = {
+	.name = CEC_NAME,
+};
+
+/*
+ * Register a cec device node
+ *
+ * The registration code assigns minor numbers and registers the new device node
+ * with the kernel. An error is returned if no free minor number can be found,
+ * or if the registration of the device node fails.
+ *
+ * Zero is returned on success.
+ *
+ * Note that if the cec_devnode_register call fails, the release() callback of
+ * the cec_devnode structure is *not* called, so the caller is responsible for
+ * freeing any data.
+ */
+static int __must_check cec_devnode_register(struct cec_devnode *devnode,
+					     struct module *owner)
+{
+	int minor;
+	int ret;
+
+	/* Part 1: Find a free minor number */
+	mutex_lock(&cec_devnode_lock);
+	minor = find_next_zero_bit(cec_devnode_nums, CEC_NUM_DEVICES, 0);
+	if (minor == CEC_NUM_DEVICES) {
+		mutex_unlock(&cec_devnode_lock);
+		pr_err("could not get a free minor\n");
+		return -ENFILE;
+	}
+
+	set_bit(minor, cec_devnode_nums);
+	mutex_unlock(&cec_devnode_lock);
+
+	devnode->minor = minor;
+	devnode->dev.bus = &cec_bus_type;
+	devnode->dev.devt = MKDEV(MAJOR(cec_dev_t), minor);
+	devnode->dev.release = cec_devnode_release;
+	dev_set_name(&devnode->dev, "cec%d", devnode->minor);
+	device_initialize(&devnode->dev);
+
+	/* Part 2: Initialize and register the character device */
+	cdev_init(&devnode->cdev, &cec_devnode_fops);
+	devnode->cdev.owner = owner;
+	kobject_set_name(&devnode->cdev.kobj, "cec%d", devnode->minor);
+
+	devnode->registered = true;
+	ret = cdev_device_add(&devnode->cdev, &devnode->dev);
+	if (ret) {
+		devnode->registered = false;
+		pr_err("%s: cdev_device_add failed\n", __func__);
+		goto clr_bit;
+	}
+
+	return 0;
+
+clr_bit:
+	mutex_lock(&cec_devnode_lock);
+	clear_bit(devnode->minor, cec_devnode_nums);
+	mutex_unlock(&cec_devnode_lock);
+	return ret;
+}
+
+/*
+ * Unregister a cec device node
+ *
+ * This unregisters the passed device. Future open calls will be met with
+ * errors.
+ *
+ * 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_adapter *adap)
+{
+	struct cec_devnode *devnode = &adap->devnode;
+	struct cec_fh *fh;
+
+	mutex_lock(&devnode->lock);
+
+	/* Check if devnode was never registered or already unregistered */
+	if (!devnode->registered || devnode->unregistered) {
+		mutex_unlock(&devnode->lock);
+		return;
+	}
+
+	list_for_each_entry(fh, &devnode->fhs, list)
+		wake_up_interruptible(&fh->wait);
+
+	devnode->registered = false;
+	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);
+}
+
+#ifdef CONFIG_DEBUG_FS
+static ssize_t cec_error_inj_write(struct file *file,
+	const char __user *ubuf, size_t count, loff_t *ppos)
+{
+	struct seq_file *sf = file->private_data;
+	struct cec_adapter *adap = sf->private;
+	char *buf;
+	char *line;
+	char *p;
+
+	buf = memdup_user_nul(ubuf, min_t(size_t, PAGE_SIZE, count));
+	if (IS_ERR(buf))
+		return PTR_ERR(buf);
+	p = buf;
+	while (p && *p) {
+		p = skip_spaces(p);
+		line = strsep(&p, "\n");
+		if (!*line || *line == '#')
+			continue;
+		if (!adap->ops->error_inj_parse_line(adap, line)) {
+			kfree(buf);
+			return -EINVAL;
+		}
+	}
+	kfree(buf);
+	return count;
+}
+
+static int cec_error_inj_show(struct seq_file *sf, void *unused)
+{
+	struct cec_adapter *adap = sf->private;
+
+	return adap->ops->error_inj_show(adap, sf);
+}
+
+static int cec_error_inj_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, cec_error_inj_show, inode->i_private);
+}
+
+static const struct file_operations cec_error_inj_fops = {
+	.open = cec_error_inj_open,
+	.write = cec_error_inj_write,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+#endif
+
+struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
+					 void *priv, const char *name, u32 caps,
+					 u8 available_las)
+{
+	struct cec_adapter *adap;
+	int res;
+
+#ifndef CONFIG_MEDIA_CEC_RC
+	caps &= ~CEC_CAP_RC;
+#endif
+
+	if (WARN_ON(!caps))
+		return ERR_PTR(-EINVAL);
+	if (WARN_ON(!ops))
+		return ERR_PTR(-EINVAL);
+	if (WARN_ON(!available_las || available_las > CEC_MAX_LOG_ADDRS))
+		return ERR_PTR(-EINVAL);
+	adap = kzalloc(sizeof(*adap), GFP_KERNEL);
+	if (!adap)
+		return ERR_PTR(-ENOMEM);
+	strscpy(adap->name, name, sizeof(adap->name));
+	adap->phys_addr = CEC_PHYS_ADDR_INVALID;
+	adap->cec_pin_is_high = true;
+	adap->log_addrs.cec_version = CEC_OP_CEC_VERSION_2_0;
+	adap->log_addrs.vendor_id = CEC_VENDOR_ID_NONE;
+	adap->capabilities = caps;
+	if (debug_phys_addr)
+		adap->capabilities |= CEC_CAP_PHYS_ADDR;
+	adap->needs_hpd = caps & CEC_CAP_NEEDS_HPD;
+	adap->available_log_addrs = available_las;
+	adap->sequence = 0;
+	adap->ops = ops;
+	adap->priv = priv;
+	memset(adap->phys_addrs, 0xff, sizeof(adap->phys_addrs));
+	mutex_init(&adap->lock);
+	INIT_LIST_HEAD(&adap->transmit_queue);
+	INIT_LIST_HEAD(&adap->wait_queue);
+	init_waitqueue_head(&adap->kthread_waitq);
+
+	/* adap->devnode initialization */
+	INIT_LIST_HEAD(&adap->devnode.fhs);
+	mutex_init(&adap->devnode.lock);
+
+	adap->kthread = kthread_run(cec_thread_func, adap, "cec-%s", name);
+	if (IS_ERR(adap->kthread)) {
+		pr_err("cec-%s: kernel_thread() failed\n", name);
+		res = PTR_ERR(adap->kthread);
+		kfree(adap);
+		return ERR_PTR(res);
+	}
+
+#ifdef CONFIG_MEDIA_CEC_RC
+	if (!(caps & CEC_CAP_RC))
+		return adap;
+
+	/* Prepare the RC input device */
+	adap->rc = rc_allocate_device(RC_DRIVER_SCANCODE);
+	if (!adap->rc) {
+		pr_err("cec-%s: failed to allocate memory for rc_dev\n",
+		       name);
+		kthread_stop(adap->kthread);
+		kfree(adap);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	snprintf(adap->input_phys, sizeof(adap->input_phys),
+		 "%s/input0", adap->name);
+
+	adap->rc->device_name = adap->name;
+	adap->rc->input_phys = adap->input_phys;
+	adap->rc->input_id.bustype = BUS_CEC;
+	adap->rc->input_id.vendor = 0;
+	adap->rc->input_id.product = 0;
+	adap->rc->input_id.version = 1;
+	adap->rc->driver_name = CEC_NAME;
+	adap->rc->allowed_protocols = RC_PROTO_BIT_CEC;
+	adap->rc->priv = adap;
+	adap->rc->map_name = RC_MAP_CEC;
+	adap->rc->timeout = MS_TO_NS(550);
+#endif
+	return adap;
+}
+EXPORT_SYMBOL_GPL(cec_allocate_adapter);
+
+int cec_register_adapter(struct cec_adapter *adap,
+			 struct device *parent)
+{
+	int res;
+
+	if (IS_ERR_OR_NULL(adap))
+		return 0;
+
+	if (WARN_ON(!parent))
+		return -EINVAL;
+
+	adap->owner = parent->driver->owner;
+	adap->devnode.dev.parent = parent;
+
+#ifdef CONFIG_MEDIA_CEC_RC
+	if (adap->capabilities & CEC_CAP_RC) {
+		adap->rc->dev.parent = parent;
+		res = rc_register_device(adap->rc);
+
+		if (res) {
+			pr_err("cec-%s: failed to prepare input device\n",
+			       adap->name);
+			rc_free_device(adap->rc);
+			adap->rc = NULL;
+			return res;
+		}
+	}
+#endif
+
+	res = cec_devnode_register(&adap->devnode, adap->owner);
+	if (res) {
+#ifdef CONFIG_MEDIA_CEC_RC
+		/* Note: rc_unregister also calls rc_free */
+		rc_unregister_device(adap->rc);
+		adap->rc = NULL;
+#endif
+		return res;
+	}
+
+	dev_set_drvdata(&adap->devnode.dev, adap);
+#ifdef CONFIG_DEBUG_FS
+	if (!top_cec_dir)
+		return 0;
+
+	adap->cec_dir = debugfs_create_dir(dev_name(&adap->devnode.dev), top_cec_dir);
+	if (IS_ERR_OR_NULL(adap->cec_dir)) {
+		pr_warn("cec-%s: Failed to create debugfs dir\n", adap->name);
+		return 0;
+	}
+	adap->status_file = debugfs_create_devm_seqfile(&adap->devnode.dev,
+		"status", adap->cec_dir, cec_adap_status);
+	if (IS_ERR_OR_NULL(adap->status_file)) {
+		pr_warn("cec-%s: Failed to create status file\n", adap->name);
+		debugfs_remove_recursive(adap->cec_dir);
+		adap->cec_dir = NULL;
+		return 0;
+	}
+	if (!adap->ops->error_inj_show || !adap->ops->error_inj_parse_line)
+		return 0;
+	adap->error_inj_file = debugfs_create_file("error-inj", 0644,
+						   adap->cec_dir, adap,
+						   &cec_error_inj_fops);
+	if (IS_ERR_OR_NULL(adap->error_inj_file))
+		pr_warn("cec-%s: Failed to create error-inj file\n",
+			adap->name);
+#endif
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cec_register_adapter);
+
+void cec_unregister_adapter(struct cec_adapter *adap)
+{
+	if (IS_ERR_OR_NULL(adap))
+		return;
+
+#ifdef CONFIG_MEDIA_CEC_RC
+	/* Note: rc_unregister also calls rc_free */
+	rc_unregister_device(adap->rc);
+	adap->rc = NULL;
+#endif
+	debugfs_remove_recursive(adap->cec_dir);
+#ifdef CONFIG_CEC_NOTIFIER
+	cec_notifier_cec_adap_unregister(adap->notifier, adap);
+#endif
+	cec_devnode_unregister(adap);
+}
+EXPORT_SYMBOL_GPL(cec_unregister_adapter);
+
+void cec_delete_adapter(struct cec_adapter *adap)
+{
+	if (IS_ERR_OR_NULL(adap))
+		return;
+	kthread_stop(adap->kthread);
+	if (adap->kthread_config)
+		kthread_stop(adap->kthread_config);
+	if (adap->ops->adap_free)
+		adap->ops->adap_free(adap);
+#ifdef CONFIG_MEDIA_CEC_RC
+	rc_free_device(adap->rc);
+#endif
+	kfree(adap);
+}
+EXPORT_SYMBOL_GPL(cec_delete_adapter);
+
+/*
+ *	Initialise cec for linux
+ */
+static int __init cec_devnode_init(void)
+{
+	int ret = alloc_chrdev_region(&cec_dev_t, 0, CEC_NUM_DEVICES, CEC_NAME);
+
+	if (ret < 0) {
+		pr_warn("cec: unable to allocate major\n");
+		return ret;
+	}
+
+#ifdef CONFIG_DEBUG_FS
+	top_cec_dir = debugfs_create_dir("cec", NULL);
+	if (IS_ERR_OR_NULL(top_cec_dir)) {
+		pr_warn("cec: Failed to create debugfs cec dir\n");
+		top_cec_dir = NULL;
+	}
+#endif
+
+	ret = bus_register(&cec_bus_type);
+	if (ret < 0) {
+		unregister_chrdev_region(cec_dev_t, CEC_NUM_DEVICES);
+		pr_warn("cec: bus_register failed\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static void __exit cec_devnode_exit(void)
+{
+	debugfs_remove_recursive(top_cec_dir);
+	bus_unregister(&cec_bus_type);
+	unregister_chrdev_region(cec_dev_t, CEC_NUM_DEVICES);
+}
+
+subsys_initcall(cec_devnode_init);
+module_exit(cec_devnode_exit)
+
+MODULE_AUTHOR("Hans Verkuil <hans.verkuil@cisco.com>");
+MODULE_DESCRIPTION("Device node registration for cec drivers");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/cec/core/cec-notifier.c b/drivers/media/cec/core/cec-notifier.c
new file mode 100644
index 000000000000..e748cd54b45d
--- /dev/null
+++ b/drivers/media/cec/core/cec-notifier.c
@@ -0,0 +1,236 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * cec-notifier.c - notify CEC drivers of physical address changes
+ *
+ * Copyright 2016 Russell King <rmk+kernel@arm.linux.org.uk>
+ * Copyright 2016-2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#include <linux/export.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/kref.h>
+#include <linux/of_platform.h>
+
+#include <media/cec.h>
+#include <media/cec-notifier.h>
+#include <drm/drm_edid.h>
+
+struct cec_notifier {
+	struct mutex lock;
+	struct list_head head;
+	struct kref kref;
+	struct device *hdmi_dev;
+	struct cec_connector_info conn_info;
+	const char *port_name;
+	struct cec_adapter *cec_adap;
+
+	u16 phys_addr;
+};
+
+static LIST_HEAD(cec_notifiers);
+static DEFINE_MUTEX(cec_notifiers_lock);
+
+/**
+ * cec_notifier_get_conn - find or create a new cec_notifier for the given
+ * device and connector tuple.
+ * @hdmi_dev: device that sends the events.
+ * @port_name: the connector name from which the event occurs
+ *
+ * If a notifier for device @dev already exists, then increase the refcount
+ * and return that notifier.
+ *
+ * If it doesn't exist, then allocate a new notifier struct and return a
+ * pointer to that new struct.
+ *
+ * Return NULL if the memory could not be allocated.
+ */
+static struct cec_notifier *
+cec_notifier_get_conn(struct device *hdmi_dev, const char *port_name)
+{
+	struct cec_notifier *n;
+
+	mutex_lock(&cec_notifiers_lock);
+	list_for_each_entry(n, &cec_notifiers, head) {
+		if (n->hdmi_dev == hdmi_dev &&
+		    (!port_name ||
+		     (n->port_name && !strcmp(n->port_name, port_name)))) {
+			kref_get(&n->kref);
+			mutex_unlock(&cec_notifiers_lock);
+			return n;
+		}
+	}
+	n = kzalloc(sizeof(*n), GFP_KERNEL);
+	if (!n)
+		goto unlock;
+	n->hdmi_dev = hdmi_dev;
+	if (port_name) {
+		n->port_name = kstrdup(port_name, GFP_KERNEL);
+		if (!n->port_name) {
+			kfree(n);
+			n = NULL;
+			goto unlock;
+		}
+	}
+	n->phys_addr = CEC_PHYS_ADDR_INVALID;
+
+	mutex_init(&n->lock);
+	kref_init(&n->kref);
+	list_add_tail(&n->head, &cec_notifiers);
+unlock:
+	mutex_unlock(&cec_notifiers_lock);
+	return n;
+}
+
+static void cec_notifier_release(struct kref *kref)
+{
+	struct cec_notifier *n =
+		container_of(kref, struct cec_notifier, kref);
+
+	list_del(&n->head);
+	kfree(n->port_name);
+	kfree(n);
+}
+
+static void cec_notifier_put(struct cec_notifier *n)
+{
+	mutex_lock(&cec_notifiers_lock);
+	kref_put(&n->kref, cec_notifier_release);
+	mutex_unlock(&cec_notifiers_lock);
+}
+
+struct cec_notifier *
+cec_notifier_conn_register(struct device *hdmi_dev, const char *port_name,
+			   const struct cec_connector_info *conn_info)
+{
+	struct cec_notifier *n = cec_notifier_get_conn(hdmi_dev, port_name);
+
+	if (!n)
+		return n;
+
+	mutex_lock(&n->lock);
+	n->phys_addr = CEC_PHYS_ADDR_INVALID;
+	if (conn_info)
+		n->conn_info = *conn_info;
+	else
+		memset(&n->conn_info, 0, sizeof(n->conn_info));
+	if (n->cec_adap) {
+		cec_phys_addr_invalidate(n->cec_adap);
+		cec_s_conn_info(n->cec_adap, conn_info);
+	}
+	mutex_unlock(&n->lock);
+	return n;
+}
+EXPORT_SYMBOL_GPL(cec_notifier_conn_register);
+
+void cec_notifier_conn_unregister(struct cec_notifier *n)
+{
+	if (!n)
+		return;
+
+	mutex_lock(&n->lock);
+	memset(&n->conn_info, 0, sizeof(n->conn_info));
+	n->phys_addr = CEC_PHYS_ADDR_INVALID;
+	if (n->cec_adap) {
+		cec_phys_addr_invalidate(n->cec_adap);
+		cec_s_conn_info(n->cec_adap, NULL);
+	}
+	mutex_unlock(&n->lock);
+	cec_notifier_put(n);
+}
+EXPORT_SYMBOL_GPL(cec_notifier_conn_unregister);
+
+struct cec_notifier *
+cec_notifier_cec_adap_register(struct device *hdmi_dev, const char *port_name,
+			       struct cec_adapter *adap)
+{
+	struct cec_notifier *n;
+
+	if (WARN_ON(!adap))
+		return NULL;
+
+	n = cec_notifier_get_conn(hdmi_dev, port_name);
+	if (!n)
+		return n;
+
+	mutex_lock(&n->lock);
+	n->cec_adap = adap;
+	adap->conn_info = n->conn_info;
+	adap->notifier = n;
+	cec_s_phys_addr(adap, n->phys_addr, false);
+	mutex_unlock(&n->lock);
+	return n;
+}
+EXPORT_SYMBOL_GPL(cec_notifier_cec_adap_register);
+
+void cec_notifier_cec_adap_unregister(struct cec_notifier *n,
+				      struct cec_adapter *adap)
+{
+	if (!n)
+		return;
+
+	mutex_lock(&n->lock);
+	adap->notifier = NULL;
+	n->cec_adap = NULL;
+	mutex_unlock(&n->lock);
+	cec_notifier_put(n);
+}
+EXPORT_SYMBOL_GPL(cec_notifier_cec_adap_unregister);
+
+void cec_notifier_set_phys_addr(struct cec_notifier *n, u16 pa)
+{
+	if (n == NULL)
+		return;
+
+	mutex_lock(&n->lock);
+	n->phys_addr = pa;
+	if (n->cec_adap)
+		cec_s_phys_addr(n->cec_adap, n->phys_addr, false);
+	mutex_unlock(&n->lock);
+}
+EXPORT_SYMBOL_GPL(cec_notifier_set_phys_addr);
+
+void cec_notifier_set_phys_addr_from_edid(struct cec_notifier *n,
+					  const struct edid *edid)
+{
+	u16 pa = CEC_PHYS_ADDR_INVALID;
+
+	if (n == NULL)
+		return;
+
+	if (edid && edid->extensions)
+		pa = cec_get_edid_phys_addr((const u8 *)edid,
+				EDID_LENGTH * (edid->extensions + 1), NULL);
+	cec_notifier_set_phys_addr(n, pa);
+}
+EXPORT_SYMBOL_GPL(cec_notifier_set_phys_addr_from_edid);
+
+struct device *cec_notifier_parse_hdmi_phandle(struct device *dev)
+{
+	struct platform_device *hdmi_pdev;
+	struct device *hdmi_dev = NULL;
+	struct device_node *np;
+
+	np = of_parse_phandle(dev->of_node, "hdmi-phandle", 0);
+
+	if (!np) {
+		dev_err(dev, "Failed to find HDMI node in device tree\n");
+		return ERR_PTR(-ENODEV);
+	}
+	hdmi_pdev = of_find_device_by_node(np);
+	of_node_put(np);
+	if (hdmi_pdev) {
+		hdmi_dev = &hdmi_pdev->dev;
+		/*
+		 * Note that the device struct is only used as a key into the
+		 * cec_notifiers list, it is never actually accessed.
+		 * So we decrement the reference here so we don't leak
+		 * memory.
+		 */
+		put_device(hdmi_dev);
+		return hdmi_dev;
+	}
+	return ERR_PTR(-EPROBE_DEFER);
+}
+EXPORT_SYMBOL_GPL(cec_notifier_parse_hdmi_phandle);
diff --git a/drivers/media/cec/core/cec-pin-error-inj.c b/drivers/media/cec/core/cec-pin-error-inj.c
new file mode 100644
index 000000000000..c0088d3b8e3d
--- /dev/null
+++ b/drivers/media/cec/core/cec-pin-error-inj.c
@@ -0,0 +1,345 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/sched/types.h>
+
+#include <media/cec-pin.h>
+#include "cec-pin-priv.h"
+
+struct cec_error_inj_cmd {
+	unsigned int mode_offset;
+	int arg_idx;
+	const char *cmd;
+};
+
+static const struct cec_error_inj_cmd cec_error_inj_cmds[] = {
+	{ CEC_ERROR_INJ_RX_NACK_OFFSET, -1, "rx-nack" },
+	{ CEC_ERROR_INJ_RX_LOW_DRIVE_OFFSET,
+	  CEC_ERROR_INJ_RX_LOW_DRIVE_ARG_IDX, "rx-low-drive" },
+	{ CEC_ERROR_INJ_RX_ADD_BYTE_OFFSET, -1, "rx-add-byte" },
+	{ CEC_ERROR_INJ_RX_REMOVE_BYTE_OFFSET, -1, "rx-remove-byte" },
+	{ CEC_ERROR_INJ_RX_ARB_LOST_OFFSET,
+	  CEC_ERROR_INJ_RX_ARB_LOST_ARG_IDX, "rx-arb-lost" },
+
+	{ CEC_ERROR_INJ_TX_NO_EOM_OFFSET, -1, "tx-no-eom" },
+	{ CEC_ERROR_INJ_TX_EARLY_EOM_OFFSET, -1, "tx-early-eom" },
+	{ CEC_ERROR_INJ_TX_ADD_BYTES_OFFSET,
+	  CEC_ERROR_INJ_TX_ADD_BYTES_ARG_IDX, "tx-add-bytes" },
+	{ CEC_ERROR_INJ_TX_REMOVE_BYTE_OFFSET, -1, "tx-remove-byte" },
+	{ CEC_ERROR_INJ_TX_SHORT_BIT_OFFSET,
+	  CEC_ERROR_INJ_TX_SHORT_BIT_ARG_IDX, "tx-short-bit" },
+	{ CEC_ERROR_INJ_TX_LONG_BIT_OFFSET,
+	  CEC_ERROR_INJ_TX_LONG_BIT_ARG_IDX, "tx-long-bit" },
+	{ CEC_ERROR_INJ_TX_CUSTOM_BIT_OFFSET,
+	  CEC_ERROR_INJ_TX_CUSTOM_BIT_ARG_IDX, "tx-custom-bit" },
+	{ CEC_ERROR_INJ_TX_SHORT_START_OFFSET, -1, "tx-short-start" },
+	{ CEC_ERROR_INJ_TX_LONG_START_OFFSET, -1, "tx-long-start" },
+	{ CEC_ERROR_INJ_TX_CUSTOM_START_OFFSET, -1, "tx-custom-start" },
+	{ CEC_ERROR_INJ_TX_LAST_BIT_OFFSET,
+	  CEC_ERROR_INJ_TX_LAST_BIT_ARG_IDX, "tx-last-bit" },
+	{ CEC_ERROR_INJ_TX_LOW_DRIVE_OFFSET,
+	  CEC_ERROR_INJ_TX_LOW_DRIVE_ARG_IDX, "tx-low-drive" },
+	{ 0, -1, NULL }
+};
+
+u16 cec_pin_rx_error_inj(struct cec_pin *pin)
+{
+	u16 cmd = CEC_ERROR_INJ_OP_ANY;
+
+	/* Only when 18 bits have been received do we have a valid cmd */
+	if (!(pin->error_inj[cmd] & CEC_ERROR_INJ_RX_MASK) &&
+	    pin->rx_bit >= 18)
+		cmd = pin->rx_msg.msg[1];
+	return (pin->error_inj[cmd] & CEC_ERROR_INJ_RX_MASK) ? cmd :
+		CEC_ERROR_INJ_OP_ANY;
+}
+
+u16 cec_pin_tx_error_inj(struct cec_pin *pin)
+{
+	u16 cmd = CEC_ERROR_INJ_OP_ANY;
+
+	if (!(pin->error_inj[cmd] & CEC_ERROR_INJ_TX_MASK) &&
+	    pin->tx_msg.len > 1)
+		cmd = pin->tx_msg.msg[1];
+	return (pin->error_inj[cmd] & CEC_ERROR_INJ_TX_MASK) ? cmd :
+		CEC_ERROR_INJ_OP_ANY;
+}
+
+bool cec_pin_error_inj_parse_line(struct cec_adapter *adap, char *line)
+{
+	static const char *delims = " \t\r";
+	struct cec_pin *pin = adap->pin;
+	unsigned int i;
+	bool has_pos = false;
+	char *p = line;
+	char *token;
+	char *comma;
+	u64 *error;
+	u8 *args;
+	bool has_op;
+	u8 op;
+	u8 mode;
+	u8 pos;
+
+	p = skip_spaces(p);
+	token = strsep(&p, delims);
+	if (!strcmp(token, "clear")) {
+		memset(pin->error_inj, 0, sizeof(pin->error_inj));
+		pin->rx_toggle = pin->tx_toggle = false;
+		pin->tx_ignore_nack_until_eom = false;
+		pin->tx_custom_pulse = false;
+		pin->tx_custom_low_usecs = CEC_TIM_CUSTOM_DEFAULT;
+		pin->tx_custom_high_usecs = CEC_TIM_CUSTOM_DEFAULT;
+		return true;
+	}
+	if (!strcmp(token, "rx-clear")) {
+		for (i = 0; i <= CEC_ERROR_INJ_OP_ANY; i++)
+			pin->error_inj[i] &= ~CEC_ERROR_INJ_RX_MASK;
+		pin->rx_toggle = false;
+		return true;
+	}
+	if (!strcmp(token, "tx-clear")) {
+		for (i = 0; i <= CEC_ERROR_INJ_OP_ANY; i++)
+			pin->error_inj[i] &= ~CEC_ERROR_INJ_TX_MASK;
+		pin->tx_toggle = false;
+		pin->tx_ignore_nack_until_eom = false;
+		pin->tx_custom_pulse = false;
+		pin->tx_custom_low_usecs = CEC_TIM_CUSTOM_DEFAULT;
+		pin->tx_custom_high_usecs = CEC_TIM_CUSTOM_DEFAULT;
+		return true;
+	}
+	if (!strcmp(token, "tx-ignore-nack-until-eom")) {
+		pin->tx_ignore_nack_until_eom = true;
+		return true;
+	}
+	if (!strcmp(token, "tx-custom-pulse")) {
+		pin->tx_custom_pulse = true;
+		cec_pin_start_timer(pin);
+		return true;
+	}
+	if (!p)
+		return false;
+
+	p = skip_spaces(p);
+	if (!strcmp(token, "tx-custom-low-usecs")) {
+		u32 usecs;
+
+		if (kstrtou32(p, 0, &usecs) || usecs > 10000000)
+			return false;
+		pin->tx_custom_low_usecs = usecs;
+		return true;
+	}
+	if (!strcmp(token, "tx-custom-high-usecs")) {
+		u32 usecs;
+
+		if (kstrtou32(p, 0, &usecs) || usecs > 10000000)
+			return false;
+		pin->tx_custom_high_usecs = usecs;
+		return true;
+	}
+
+	comma = strchr(token, ',');
+	if (comma)
+		*comma++ = '\0';
+	if (!strcmp(token, "any")) {
+		has_op = false;
+		error = pin->error_inj + CEC_ERROR_INJ_OP_ANY;
+		args = pin->error_inj_args[CEC_ERROR_INJ_OP_ANY];
+	} else if (!kstrtou8(token, 0, &op)) {
+		has_op = true;
+		error = pin->error_inj + op;
+		args = pin->error_inj_args[op];
+	} else {
+		return false;
+	}
+
+	mode = CEC_ERROR_INJ_MODE_ONCE;
+	if (comma) {
+		if (!strcmp(comma, "off"))
+			mode = CEC_ERROR_INJ_MODE_OFF;
+		else if (!strcmp(comma, "once"))
+			mode = CEC_ERROR_INJ_MODE_ONCE;
+		else if (!strcmp(comma, "always"))
+			mode = CEC_ERROR_INJ_MODE_ALWAYS;
+		else if (!strcmp(comma, "toggle"))
+			mode = CEC_ERROR_INJ_MODE_TOGGLE;
+		else
+			return false;
+	}
+
+	token = strsep(&p, delims);
+	if (p) {
+		p = skip_spaces(p);
+		has_pos = !kstrtou8(p, 0, &pos);
+	}
+
+	if (!strcmp(token, "clear")) {
+		*error = 0;
+		return true;
+	}
+	if (!strcmp(token, "rx-clear")) {
+		*error &= ~CEC_ERROR_INJ_RX_MASK;
+		return true;
+	}
+	if (!strcmp(token, "tx-clear")) {
+		*error &= ~CEC_ERROR_INJ_TX_MASK;
+		return true;
+	}
+
+	for (i = 0; cec_error_inj_cmds[i].cmd; i++) {
+		const char *cmd = cec_error_inj_cmds[i].cmd;
+		unsigned int mode_offset;
+		u64 mode_mask;
+		int arg_idx;
+		bool is_bit_pos = true;
+
+		if (strcmp(token, cmd))
+			continue;
+
+		mode_offset = cec_error_inj_cmds[i].mode_offset;
+		mode_mask = CEC_ERROR_INJ_MODE_MASK << mode_offset;
+		arg_idx = cec_error_inj_cmds[i].arg_idx;
+
+		if (mode_offset == CEC_ERROR_INJ_RX_ARB_LOST_OFFSET) {
+			if (has_op)
+				return false;
+			if (!has_pos)
+				pos = 0x0f;
+			is_bit_pos = false;
+		} else if (mode_offset == CEC_ERROR_INJ_TX_ADD_BYTES_OFFSET) {
+			if (!has_pos || !pos)
+				return false;
+			is_bit_pos = false;
+		}
+
+		if (arg_idx >= 0 && is_bit_pos) {
+			if (!has_pos || pos >= 160)
+				return false;
+			if (has_op && pos < 10 + 8)
+				return false;
+			/* Invalid bit position may not be the Ack bit */
+			if ((mode_offset == CEC_ERROR_INJ_TX_SHORT_BIT_OFFSET ||
+			     mode_offset == CEC_ERROR_INJ_TX_LONG_BIT_OFFSET ||
+			     mode_offset == CEC_ERROR_INJ_TX_CUSTOM_BIT_OFFSET) &&
+			    (pos % 10) == 9)
+				return false;
+		}
+		*error &= ~mode_mask;
+		*error |= (u64)mode << mode_offset;
+		if (arg_idx >= 0)
+			args[arg_idx] = pos;
+		return true;
+	}
+	return false;
+}
+
+static void cec_pin_show_cmd(struct seq_file *sf, u32 cmd, u8 mode)
+{
+	if (cmd == CEC_ERROR_INJ_OP_ANY)
+		seq_puts(sf, "any,");
+	else
+		seq_printf(sf, "0x%02x,", cmd);
+	switch (mode) {
+	case CEC_ERROR_INJ_MODE_ONCE:
+		seq_puts(sf, "once ");
+		break;
+	case CEC_ERROR_INJ_MODE_ALWAYS:
+		seq_puts(sf, "always ");
+		break;
+	case CEC_ERROR_INJ_MODE_TOGGLE:
+		seq_puts(sf, "toggle ");
+		break;
+	default:
+		seq_puts(sf, "off ");
+		break;
+	}
+}
+
+int cec_pin_error_inj_show(struct cec_adapter *adap, struct seq_file *sf)
+{
+	struct cec_pin *pin = adap->pin;
+	unsigned int i, j;
+
+	seq_puts(sf, "# Clear error injections:\n");
+	seq_puts(sf, "#   clear          clear all rx and tx error injections\n");
+	seq_puts(sf, "#   rx-clear       clear all rx error injections\n");
+	seq_puts(sf, "#   tx-clear       clear all tx error injections\n");
+	seq_puts(sf, "#   <op> clear     clear all rx and tx error injections for <op>\n");
+	seq_puts(sf, "#   <op> rx-clear  clear all rx error injections for <op>\n");
+	seq_puts(sf, "#   <op> tx-clear  clear all tx error injections for <op>\n");
+	seq_puts(sf, "#\n");
+	seq_puts(sf, "# RX error injection:\n");
+	seq_puts(sf, "#   <op>[,<mode>] rx-nack              NACK the message instead of sending an ACK\n");
+	seq_puts(sf, "#   <op>[,<mode>] rx-low-drive <bit>   force a low-drive condition at this bit position\n");
+	seq_puts(sf, "#   <op>[,<mode>] rx-add-byte          add a spurious byte to the received CEC message\n");
+	seq_puts(sf, "#   <op>[,<mode>] rx-remove-byte       remove the last byte from the received CEC message\n");
+	seq_puts(sf, "#   <op>[,<mode>] rx-arb-lost <poll>   generate a POLL message to trigger an arbitration lost\n");
+	seq_puts(sf, "#\n");
+	seq_puts(sf, "# TX error injection settings:\n");
+	seq_puts(sf, "#   tx-ignore-nack-until-eom           ignore early NACKs until EOM\n");
+	seq_puts(sf, "#   tx-custom-low-usecs <usecs>        define the 'low' time for the custom pulse\n");
+	seq_puts(sf, "#   tx-custom-high-usecs <usecs>       define the 'high' time for the custom pulse\n");
+	seq_puts(sf, "#   tx-custom-pulse                    transmit the custom pulse once the bus is idle\n");
+	seq_puts(sf, "#\n");
+	seq_puts(sf, "# TX error injection:\n");
+	seq_puts(sf, "#   <op>[,<mode>] tx-no-eom            don't set the EOM bit\n");
+	seq_puts(sf, "#   <op>[,<mode>] tx-early-eom         set the EOM bit one byte too soon\n");
+	seq_puts(sf, "#   <op>[,<mode>] tx-add-bytes <num>   append <num> (1-255) spurious bytes to the message\n");
+	seq_puts(sf, "#   <op>[,<mode>] tx-remove-byte       drop the last byte from the message\n");
+	seq_puts(sf, "#   <op>[,<mode>] tx-short-bit <bit>   make this bit shorter than allowed\n");
+	seq_puts(sf, "#   <op>[,<mode>] tx-long-bit <bit>    make this bit longer than allowed\n");
+	seq_puts(sf, "#   <op>[,<mode>] tx-custom-bit <bit>  send the custom pulse instead of this bit\n");
+	seq_puts(sf, "#   <op>[,<mode>] tx-short-start       send a start pulse that's too short\n");
+	seq_puts(sf, "#   <op>[,<mode>] tx-long-start        send a start pulse that's too long\n");
+	seq_puts(sf, "#   <op>[,<mode>] tx-custom-start      send the custom pulse instead of the start pulse\n");
+	seq_puts(sf, "#   <op>[,<mode>] tx-last-bit <bit>    stop sending after this bit\n");
+	seq_puts(sf, "#   <op>[,<mode>] tx-low-drive <bit>   force a low-drive condition at this bit position\n");
+	seq_puts(sf, "#\n");
+	seq_puts(sf, "# <op>       CEC message opcode (0-255) or 'any'\n");
+	seq_puts(sf, "# <mode>     'once' (default), 'always', 'toggle' or 'off'\n");
+	seq_puts(sf, "# <bit>      CEC message bit (0-159)\n");
+	seq_puts(sf, "#            10 bits per 'byte': bits 0-7: data, bit 8: EOM, bit 9: ACK\n");
+	seq_puts(sf, "# <poll>     CEC poll message used to test arbitration lost (0x00-0xff, default 0x0f)\n");
+	seq_puts(sf, "# <usecs>    microseconds (0-10000000, default 1000)\n");
+
+	seq_puts(sf, "\nclear\n");
+
+	for (i = 0; i < ARRAY_SIZE(pin->error_inj); i++) {
+		u64 e = pin->error_inj[i];
+
+		for (j = 0; cec_error_inj_cmds[j].cmd; j++) {
+			const char *cmd = cec_error_inj_cmds[j].cmd;
+			unsigned int mode;
+			unsigned int mode_offset;
+			int arg_idx;
+
+			mode_offset = cec_error_inj_cmds[j].mode_offset;
+			arg_idx = cec_error_inj_cmds[j].arg_idx;
+			mode = (e >> mode_offset) & CEC_ERROR_INJ_MODE_MASK;
+			if (!mode)
+				continue;
+			cec_pin_show_cmd(sf, i, mode);
+			seq_puts(sf, cmd);
+			if (arg_idx >= 0)
+				seq_printf(sf, " %u",
+					   pin->error_inj_args[i][arg_idx]);
+			seq_puts(sf, "\n");
+		}
+	}
+
+	if (pin->tx_ignore_nack_until_eom)
+		seq_puts(sf, "tx-ignore-nack-until-eom\n");
+	if (pin->tx_custom_pulse)
+		seq_puts(sf, "tx-custom-pulse\n");
+	if (pin->tx_custom_low_usecs != CEC_TIM_CUSTOM_DEFAULT)
+		seq_printf(sf, "tx-custom-low-usecs %u\n",
+			   pin->tx_custom_low_usecs);
+	if (pin->tx_custom_high_usecs != CEC_TIM_CUSTOM_DEFAULT)
+		seq_printf(sf, "tx-custom-high-usecs %u\n",
+			   pin->tx_custom_high_usecs);
+	return 0;
+}
diff --git a/drivers/media/cec/core/cec-pin-priv.h b/drivers/media/cec/core/cec-pin-priv.h
new file mode 100644
index 000000000000..f423db8855d9
--- /dev/null
+++ b/drivers/media/cec/core/cec-pin-priv.h
@@ -0,0 +1,241 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * cec-pin-priv.h - internal cec-pin header
+ *
+ * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#ifndef LINUX_CEC_PIN_PRIV_H
+#define LINUX_CEC_PIN_PRIV_H
+
+#include <linux/types.h>
+#include <linux/atomic.h>
+#include <media/cec-pin.h>
+
+enum cec_pin_state {
+	/* CEC is off */
+	CEC_ST_OFF,
+	/* CEC is idle, waiting for Rx or Tx */
+	CEC_ST_IDLE,
+
+	/* Tx states */
+
+	/* Pending Tx, waiting for Signal Free Time to expire */
+	CEC_ST_TX_WAIT,
+	/* Low-drive was detected, wait for bus to go high */
+	CEC_ST_TX_WAIT_FOR_HIGH,
+	/* Drive CEC low for the start bit */
+	CEC_ST_TX_START_BIT_LOW,
+	/* Drive CEC high for the start bit */
+	CEC_ST_TX_START_BIT_HIGH,
+	/* Generate a start bit period that is too short */
+	CEC_ST_TX_START_BIT_HIGH_SHORT,
+	/* Generate a start bit period that is too long */
+	CEC_ST_TX_START_BIT_HIGH_LONG,
+	/* Drive CEC low for the start bit using the custom timing */
+	CEC_ST_TX_START_BIT_LOW_CUSTOM,
+	/* Drive CEC high for the start bit using the custom timing */
+	CEC_ST_TX_START_BIT_HIGH_CUSTOM,
+	/* Drive CEC low for the 0 bit */
+	CEC_ST_TX_DATA_BIT_0_LOW,
+	/* Drive CEC high for the 0 bit */
+	CEC_ST_TX_DATA_BIT_0_HIGH,
+	/* Generate a bit period that is too short */
+	CEC_ST_TX_DATA_BIT_0_HIGH_SHORT,
+	/* Generate a bit period that is too long */
+	CEC_ST_TX_DATA_BIT_0_HIGH_LONG,
+	/* Drive CEC low for the 1 bit */
+	CEC_ST_TX_DATA_BIT_1_LOW,
+	/* Drive CEC high for the 1 bit */
+	CEC_ST_TX_DATA_BIT_1_HIGH,
+	/* Generate a bit period that is too short */
+	CEC_ST_TX_DATA_BIT_1_HIGH_SHORT,
+	/* Generate a bit period that is too long */
+	CEC_ST_TX_DATA_BIT_1_HIGH_LONG,
+	/*
+	 * Wait for start of sample time to check for Ack bit or first
+	 * four initiator bits to check for Arbitration Lost.
+	 */
+	CEC_ST_TX_DATA_BIT_1_HIGH_PRE_SAMPLE,
+	/* Wait for end of bit period after sampling */
+	CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE,
+	/* Generate a bit period that is too short */
+	CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE_SHORT,
+	/* Generate a bit period that is too long */
+	CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE_LONG,
+	/* Drive CEC low for a data bit using the custom timing */
+	CEC_ST_TX_DATA_BIT_LOW_CUSTOM,
+	/* Drive CEC high for a data bit using the custom timing */
+	CEC_ST_TX_DATA_BIT_HIGH_CUSTOM,
+	/* Drive CEC low for a standalone pulse using the custom timing */
+	CEC_ST_TX_PULSE_LOW_CUSTOM,
+	/* Drive CEC high for a standalone pulse using the custom timing */
+	CEC_ST_TX_PULSE_HIGH_CUSTOM,
+	/* Start low drive */
+	CEC_ST_TX_LOW_DRIVE,
+
+	/* Rx states */
+
+	/* Start bit low detected */
+	CEC_ST_RX_START_BIT_LOW,
+	/* Start bit high detected */
+	CEC_ST_RX_START_BIT_HIGH,
+	/* Wait for bit sample time */
+	CEC_ST_RX_DATA_SAMPLE,
+	/* Wait for earliest end of bit period after sampling */
+	CEC_ST_RX_DATA_POST_SAMPLE,
+	/* Wait for CEC to go low (i.e. end of bit period) */
+	CEC_ST_RX_DATA_WAIT_FOR_LOW,
+	/* Drive CEC low to send 0 Ack bit */
+	CEC_ST_RX_ACK_LOW,
+	/* End of 0 Ack time, wait for earliest end of bit period */
+	CEC_ST_RX_ACK_LOW_POST,
+	/* Wait for CEC to go high (i.e. end of bit period */
+	CEC_ST_RX_ACK_HIGH_POST,
+	/* Wait for earliest end of bit period and end of message */
+	CEC_ST_RX_ACK_FINISH,
+	/* Start low drive */
+	CEC_ST_RX_LOW_DRIVE,
+
+	/* Monitor pin using interrupts */
+	CEC_ST_RX_IRQ,
+
+	/* Total number of pin states */
+	CEC_PIN_STATES
+};
+
+/* Error Injection */
+
+/* Error injection modes */
+#define CEC_ERROR_INJ_MODE_OFF				0
+#define CEC_ERROR_INJ_MODE_ONCE				1
+#define CEC_ERROR_INJ_MODE_ALWAYS			2
+#define CEC_ERROR_INJ_MODE_TOGGLE			3
+#define CEC_ERROR_INJ_MODE_MASK				3ULL
+
+/* Receive error injection options */
+#define CEC_ERROR_INJ_RX_NACK_OFFSET			0
+#define CEC_ERROR_INJ_RX_LOW_DRIVE_OFFSET		2
+#define CEC_ERROR_INJ_RX_ADD_BYTE_OFFSET		4
+#define CEC_ERROR_INJ_RX_REMOVE_BYTE_OFFSET		6
+#define CEC_ERROR_INJ_RX_ARB_LOST_OFFSET		8
+#define CEC_ERROR_INJ_RX_MASK				0xffffULL
+
+/* Transmit error injection options */
+#define CEC_ERROR_INJ_TX_NO_EOM_OFFSET			16
+#define CEC_ERROR_INJ_TX_EARLY_EOM_OFFSET		18
+#define CEC_ERROR_INJ_TX_SHORT_BIT_OFFSET		20
+#define CEC_ERROR_INJ_TX_LONG_BIT_OFFSET		22
+#define CEC_ERROR_INJ_TX_CUSTOM_BIT_OFFSET		24
+#define CEC_ERROR_INJ_TX_SHORT_START_OFFSET		26
+#define CEC_ERROR_INJ_TX_LONG_START_OFFSET		28
+#define CEC_ERROR_INJ_TX_CUSTOM_START_OFFSET		30
+#define CEC_ERROR_INJ_TX_LAST_BIT_OFFSET		32
+#define CEC_ERROR_INJ_TX_ADD_BYTES_OFFSET		34
+#define CEC_ERROR_INJ_TX_REMOVE_BYTE_OFFSET		36
+#define CEC_ERROR_INJ_TX_LOW_DRIVE_OFFSET		38
+#define CEC_ERROR_INJ_TX_MASK				0xffffffffffff0000ULL
+
+#define CEC_ERROR_INJ_RX_LOW_DRIVE_ARG_IDX		0
+#define CEC_ERROR_INJ_RX_ARB_LOST_ARG_IDX		1
+
+#define CEC_ERROR_INJ_TX_ADD_BYTES_ARG_IDX		2
+#define CEC_ERROR_INJ_TX_SHORT_BIT_ARG_IDX		3
+#define CEC_ERROR_INJ_TX_LONG_BIT_ARG_IDX		4
+#define CEC_ERROR_INJ_TX_CUSTOM_BIT_ARG_IDX		5
+#define CEC_ERROR_INJ_TX_LAST_BIT_ARG_IDX		6
+#define CEC_ERROR_INJ_TX_LOW_DRIVE_ARG_IDX		7
+#define CEC_ERROR_INJ_NUM_ARGS				8
+
+/* Special CEC op values */
+#define CEC_ERROR_INJ_OP_ANY				0x00000100
+
+/* The default for the low/high time of the custom pulse */
+#define CEC_TIM_CUSTOM_DEFAULT				1000
+
+#define CEC_NUM_PIN_EVENTS				128
+#define CEC_PIN_EVENT_FL_IS_HIGH			(1 << 0)
+#define CEC_PIN_EVENT_FL_DROPPED			(1 << 1)
+
+#define CEC_PIN_IRQ_UNCHANGED	0
+#define CEC_PIN_IRQ_DISABLE	1
+#define CEC_PIN_IRQ_ENABLE	2
+
+struct cec_pin {
+	struct cec_adapter		*adap;
+	const struct cec_pin_ops	*ops;
+	struct task_struct		*kthread;
+	wait_queue_head_t		kthread_waitq;
+	struct hrtimer			timer;
+	ktime_t				ts;
+	unsigned int			wait_usecs;
+	u16				la_mask;
+	bool				enabled;
+	bool				monitor_all;
+	bool				rx_eom;
+	bool				enable_irq_failed;
+	enum cec_pin_state		state;
+	struct cec_msg			tx_msg;
+	u32				tx_bit;
+	bool				tx_nacked;
+	u32				tx_signal_free_time;
+	bool				tx_toggle;
+	struct cec_msg			rx_msg;
+	u32				rx_bit;
+	bool				rx_toggle;
+	u32				rx_start_bit_low_too_short_cnt;
+	u64				rx_start_bit_low_too_short_ts;
+	u32				rx_start_bit_low_too_short_delta;
+	u32				rx_start_bit_too_short_cnt;
+	u64				rx_start_bit_too_short_ts;
+	u32				rx_start_bit_too_short_delta;
+	u32				rx_start_bit_too_long_cnt;
+	u32				rx_data_bit_too_short_cnt;
+	u64				rx_data_bit_too_short_ts;
+	u32				rx_data_bit_too_short_delta;
+	u32				rx_data_bit_too_long_cnt;
+	u32				rx_low_drive_cnt;
+
+	struct cec_msg			work_rx_msg;
+	u8				work_tx_status;
+	ktime_t				work_tx_ts;
+	atomic_t			work_irq_change;
+	atomic_t			work_pin_num_events;
+	unsigned int			work_pin_events_wr;
+	unsigned int			work_pin_events_rd;
+	ktime_t				work_pin_ts[CEC_NUM_PIN_EVENTS];
+	u8				work_pin_events[CEC_NUM_PIN_EVENTS];
+	bool				work_pin_events_dropped;
+	u32				work_pin_events_dropped_cnt;
+	ktime_t				timer_ts;
+	u32				timer_cnt;
+	u32				timer_100ms_overruns;
+	u32				timer_300ms_overruns;
+	u32				timer_max_overrun;
+	u32				timer_sum_overrun;
+
+	u32				tx_custom_low_usecs;
+	u32				tx_custom_high_usecs;
+	bool				tx_ignore_nack_until_eom;
+	bool				tx_custom_pulse;
+	bool				tx_generated_poll;
+	bool				tx_post_eom;
+	u8				tx_extra_bytes;
+	u32				tx_low_drive_cnt;
+#ifdef CONFIG_CEC_PIN_ERROR_INJ
+	u64				error_inj[CEC_ERROR_INJ_OP_ANY + 1];
+	u8				error_inj_args[CEC_ERROR_INJ_OP_ANY + 1][CEC_ERROR_INJ_NUM_ARGS];
+#endif
+};
+
+void cec_pin_start_timer(struct cec_pin *pin);
+
+#ifdef CONFIG_CEC_PIN_ERROR_INJ
+bool cec_pin_error_inj_parse_line(struct cec_adapter *adap, char *line);
+int cec_pin_error_inj_show(struct cec_adapter *adap, struct seq_file *sf);
+
+u16 cec_pin_rx_error_inj(struct cec_pin *pin);
+u16 cec_pin_tx_error_inj(struct cec_pin *pin);
+#endif
+
+#endif
diff --git a/drivers/media/cec/core/cec-pin.c b/drivers/media/cec/core/cec-pin.c
new file mode 100644
index 000000000000..660fe111f540
--- /dev/null
+++ b/drivers/media/cec/core/cec-pin.c
@@ -0,0 +1,1345 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/sched/types.h>
+
+#include <media/cec-pin.h>
+#include "cec-pin-priv.h"
+
+/* All timings are in microseconds */
+
+/* start bit timings */
+#define CEC_TIM_START_BIT_LOW		3700
+#define CEC_TIM_START_BIT_LOW_MIN	3500
+#define CEC_TIM_START_BIT_LOW_MAX	3900
+#define CEC_TIM_START_BIT_TOTAL		4500
+#define CEC_TIM_START_BIT_TOTAL_MIN	4300
+#define CEC_TIM_START_BIT_TOTAL_MAX	4700
+
+/* data bit timings */
+#define CEC_TIM_DATA_BIT_0_LOW		1500
+#define CEC_TIM_DATA_BIT_0_LOW_MIN	1300
+#define CEC_TIM_DATA_BIT_0_LOW_MAX	1700
+#define CEC_TIM_DATA_BIT_1_LOW		600
+#define CEC_TIM_DATA_BIT_1_LOW_MIN	400
+#define CEC_TIM_DATA_BIT_1_LOW_MAX	800
+#define CEC_TIM_DATA_BIT_TOTAL		2400
+#define CEC_TIM_DATA_BIT_TOTAL_MIN	2050
+#define CEC_TIM_DATA_BIT_TOTAL_MAX	2750
+/* earliest safe time to sample the bit state */
+#define CEC_TIM_DATA_BIT_SAMPLE		850
+/* earliest time the bit is back to 1 (T7 + 50) */
+#define CEC_TIM_DATA_BIT_HIGH		1750
+
+/* when idle, sample once per millisecond */
+#define CEC_TIM_IDLE_SAMPLE		1000
+/* when processing the start bit, sample twice per millisecond */
+#define CEC_TIM_START_BIT_SAMPLE	500
+/* when polling for a state change, sample once every 50 microseconds */
+#define CEC_TIM_SAMPLE			50
+
+#define CEC_TIM_LOW_DRIVE_ERROR		(1.5 * CEC_TIM_DATA_BIT_TOTAL)
+
+/*
+ * Total data bit time that is too short/long for a valid bit,
+ * used for error injection.
+ */
+#define CEC_TIM_DATA_BIT_TOTAL_SHORT	1800
+#define CEC_TIM_DATA_BIT_TOTAL_LONG	2900
+
+/*
+ * Total start bit time that is too short/long for a valid bit,
+ * used for error injection.
+ */
+#define CEC_TIM_START_BIT_TOTAL_SHORT	4100
+#define CEC_TIM_START_BIT_TOTAL_LONG	5000
+
+/* Data bits are 0-7, EOM is bit 8 and ACK is bit 9 */
+#define EOM_BIT				8
+#define ACK_BIT				9
+
+struct cec_state {
+	const char * const name;
+	unsigned int usecs;
+};
+
+static const struct cec_state states[CEC_PIN_STATES] = {
+	{ "Off",		   0 },
+	{ "Idle",		   CEC_TIM_IDLE_SAMPLE },
+	{ "Tx Wait",		   CEC_TIM_SAMPLE },
+	{ "Tx Wait for High",	   CEC_TIM_IDLE_SAMPLE },
+	{ "Tx Start Bit Low",	   CEC_TIM_START_BIT_LOW },
+	{ "Tx Start Bit High",	   CEC_TIM_START_BIT_TOTAL - CEC_TIM_START_BIT_LOW },
+	{ "Tx Start Bit High Short", CEC_TIM_START_BIT_TOTAL_SHORT - CEC_TIM_START_BIT_LOW },
+	{ "Tx Start Bit High Long", CEC_TIM_START_BIT_TOTAL_LONG - CEC_TIM_START_BIT_LOW },
+	{ "Tx Start Bit Low Custom", 0 },
+	{ "Tx Start Bit High Custom", 0 },
+	{ "Tx Data 0 Low",	   CEC_TIM_DATA_BIT_0_LOW },
+	{ "Tx Data 0 High",	   CEC_TIM_DATA_BIT_TOTAL - CEC_TIM_DATA_BIT_0_LOW },
+	{ "Tx Data 0 High Short",  CEC_TIM_DATA_BIT_TOTAL_SHORT - CEC_TIM_DATA_BIT_0_LOW },
+	{ "Tx Data 0 High Long",   CEC_TIM_DATA_BIT_TOTAL_LONG - CEC_TIM_DATA_BIT_0_LOW },
+	{ "Tx Data 1 Low",	   CEC_TIM_DATA_BIT_1_LOW },
+	{ "Tx Data 1 High",	   CEC_TIM_DATA_BIT_TOTAL - CEC_TIM_DATA_BIT_1_LOW },
+	{ "Tx Data 1 High Short",  CEC_TIM_DATA_BIT_TOTAL_SHORT - CEC_TIM_DATA_BIT_1_LOW },
+	{ "Tx Data 1 High Long",   CEC_TIM_DATA_BIT_TOTAL_LONG - CEC_TIM_DATA_BIT_1_LOW },
+	{ "Tx Data 1 High Pre Sample", CEC_TIM_DATA_BIT_SAMPLE - CEC_TIM_DATA_BIT_1_LOW },
+	{ "Tx Data 1 High Post Sample", CEC_TIM_DATA_BIT_TOTAL - CEC_TIM_DATA_BIT_SAMPLE },
+	{ "Tx Data 1 High Post Sample Short", CEC_TIM_DATA_BIT_TOTAL_SHORT - CEC_TIM_DATA_BIT_SAMPLE },
+	{ "Tx Data 1 High Post Sample Long", CEC_TIM_DATA_BIT_TOTAL_LONG - CEC_TIM_DATA_BIT_SAMPLE },
+	{ "Tx Data Bit Low Custom", 0 },
+	{ "Tx Data Bit High Custom", 0 },
+	{ "Tx Pulse Low Custom",   0 },
+	{ "Tx Pulse High Custom",  0 },
+	{ "Tx Low Drive",	   CEC_TIM_LOW_DRIVE_ERROR },
+	{ "Rx Start Bit Low",	   CEC_TIM_SAMPLE },
+	{ "Rx Start Bit High",	   CEC_TIM_SAMPLE },
+	{ "Rx Data Sample",	   CEC_TIM_DATA_BIT_SAMPLE },
+	{ "Rx Data Post Sample",   CEC_TIM_DATA_BIT_HIGH - CEC_TIM_DATA_BIT_SAMPLE },
+	{ "Rx Data Wait for Low",  CEC_TIM_SAMPLE },
+	{ "Rx Ack Low",		   CEC_TIM_DATA_BIT_0_LOW },
+	{ "Rx Ack Low Post",	   CEC_TIM_DATA_BIT_HIGH - CEC_TIM_DATA_BIT_0_LOW },
+	{ "Rx Ack High Post",	   CEC_TIM_DATA_BIT_HIGH },
+	{ "Rx Ack Finish",	   CEC_TIM_DATA_BIT_TOTAL_MIN - CEC_TIM_DATA_BIT_HIGH },
+	{ "Rx Low Drive",	   CEC_TIM_LOW_DRIVE_ERROR },
+	{ "Rx Irq",		   0 },
+};
+
+static void cec_pin_update(struct cec_pin *pin, bool v, bool force)
+{
+	if (!force && v == pin->adap->cec_pin_is_high)
+		return;
+
+	pin->adap->cec_pin_is_high = v;
+	if (atomic_read(&pin->work_pin_num_events) < CEC_NUM_PIN_EVENTS) {
+		u8 ev = v;
+
+		if (pin->work_pin_events_dropped) {
+			pin->work_pin_events_dropped = false;
+			ev |= CEC_PIN_EVENT_FL_DROPPED;
+		}
+		pin->work_pin_events[pin->work_pin_events_wr] = ev;
+		pin->work_pin_ts[pin->work_pin_events_wr] = ktime_get();
+		pin->work_pin_events_wr =
+			(pin->work_pin_events_wr + 1) % CEC_NUM_PIN_EVENTS;
+		atomic_inc(&pin->work_pin_num_events);
+	} else {
+		pin->work_pin_events_dropped = true;
+		pin->work_pin_events_dropped_cnt++;
+	}
+	wake_up_interruptible(&pin->kthread_waitq);
+}
+
+static bool cec_pin_read(struct cec_pin *pin)
+{
+	bool v = pin->ops->read(pin->adap);
+
+	cec_pin_update(pin, v, false);
+	return v;
+}
+
+static void cec_pin_low(struct cec_pin *pin)
+{
+	pin->ops->low(pin->adap);
+	cec_pin_update(pin, false, false);
+}
+
+static bool cec_pin_high(struct cec_pin *pin)
+{
+	pin->ops->high(pin->adap);
+	return cec_pin_read(pin);
+}
+
+static bool rx_error_inj(struct cec_pin *pin, unsigned int mode_offset,
+			 int arg_idx, u8 *arg)
+{
+#ifdef CONFIG_CEC_PIN_ERROR_INJ
+	u16 cmd = cec_pin_rx_error_inj(pin);
+	u64 e = pin->error_inj[cmd];
+	unsigned int mode = (e >> mode_offset) & CEC_ERROR_INJ_MODE_MASK;
+
+	if (arg_idx >= 0) {
+		u8 pos = pin->error_inj_args[cmd][arg_idx];
+
+		if (arg)
+			*arg = pos;
+		else if (pos != pin->rx_bit)
+			return false;
+	}
+
+	switch (mode) {
+	case CEC_ERROR_INJ_MODE_ONCE:
+		pin->error_inj[cmd] &=
+			~(CEC_ERROR_INJ_MODE_MASK << mode_offset);
+		return true;
+	case CEC_ERROR_INJ_MODE_ALWAYS:
+		return true;
+	case CEC_ERROR_INJ_MODE_TOGGLE:
+		return pin->rx_toggle;
+	default:
+		return false;
+	}
+#else
+	return false;
+#endif
+}
+
+static bool rx_nack(struct cec_pin *pin)
+{
+	return rx_error_inj(pin, CEC_ERROR_INJ_RX_NACK_OFFSET, -1, NULL);
+}
+
+static bool rx_low_drive(struct cec_pin *pin)
+{
+	return rx_error_inj(pin, CEC_ERROR_INJ_RX_LOW_DRIVE_OFFSET,
+			    CEC_ERROR_INJ_RX_LOW_DRIVE_ARG_IDX, NULL);
+}
+
+static bool rx_add_byte(struct cec_pin *pin)
+{
+	return rx_error_inj(pin, CEC_ERROR_INJ_RX_ADD_BYTE_OFFSET, -1, NULL);
+}
+
+static bool rx_remove_byte(struct cec_pin *pin)
+{
+	return rx_error_inj(pin, CEC_ERROR_INJ_RX_REMOVE_BYTE_OFFSET, -1, NULL);
+}
+
+static bool rx_arb_lost(struct cec_pin *pin, u8 *poll)
+{
+	return pin->tx_msg.len == 0 &&
+		rx_error_inj(pin, CEC_ERROR_INJ_RX_ARB_LOST_OFFSET,
+			     CEC_ERROR_INJ_RX_ARB_LOST_ARG_IDX, poll);
+}
+
+static bool tx_error_inj(struct cec_pin *pin, unsigned int mode_offset,
+			 int arg_idx, u8 *arg)
+{
+#ifdef CONFIG_CEC_PIN_ERROR_INJ
+	u16 cmd = cec_pin_tx_error_inj(pin);
+	u64 e = pin->error_inj[cmd];
+	unsigned int mode = (e >> mode_offset) & CEC_ERROR_INJ_MODE_MASK;
+
+	if (arg_idx >= 0) {
+		u8 pos = pin->error_inj_args[cmd][arg_idx];
+
+		if (arg)
+			*arg = pos;
+		else if (pos != pin->tx_bit)
+			return false;
+	}
+
+	switch (mode) {
+	case CEC_ERROR_INJ_MODE_ONCE:
+		pin->error_inj[cmd] &=
+			~(CEC_ERROR_INJ_MODE_MASK << mode_offset);
+		return true;
+	case CEC_ERROR_INJ_MODE_ALWAYS:
+		return true;
+	case CEC_ERROR_INJ_MODE_TOGGLE:
+		return pin->tx_toggle;
+	default:
+		return false;
+	}
+#else
+	return false;
+#endif
+}
+
+static bool tx_no_eom(struct cec_pin *pin)
+{
+	return tx_error_inj(pin, CEC_ERROR_INJ_TX_NO_EOM_OFFSET, -1, NULL);
+}
+
+static bool tx_early_eom(struct cec_pin *pin)
+{
+	return tx_error_inj(pin, CEC_ERROR_INJ_TX_EARLY_EOM_OFFSET, -1, NULL);
+}
+
+static bool tx_short_bit(struct cec_pin *pin)
+{
+	return tx_error_inj(pin, CEC_ERROR_INJ_TX_SHORT_BIT_OFFSET,
+			    CEC_ERROR_INJ_TX_SHORT_BIT_ARG_IDX, NULL);
+}
+
+static bool tx_long_bit(struct cec_pin *pin)
+{
+	return tx_error_inj(pin, CEC_ERROR_INJ_TX_LONG_BIT_OFFSET,
+			    CEC_ERROR_INJ_TX_LONG_BIT_ARG_IDX, NULL);
+}
+
+static bool tx_custom_bit(struct cec_pin *pin)
+{
+	return tx_error_inj(pin, CEC_ERROR_INJ_TX_CUSTOM_BIT_OFFSET,
+			    CEC_ERROR_INJ_TX_CUSTOM_BIT_ARG_IDX, NULL);
+}
+
+static bool tx_short_start(struct cec_pin *pin)
+{
+	return tx_error_inj(pin, CEC_ERROR_INJ_TX_SHORT_START_OFFSET, -1, NULL);
+}
+
+static bool tx_long_start(struct cec_pin *pin)
+{
+	return tx_error_inj(pin, CEC_ERROR_INJ_TX_LONG_START_OFFSET, -1, NULL);
+}
+
+static bool tx_custom_start(struct cec_pin *pin)
+{
+	return tx_error_inj(pin, CEC_ERROR_INJ_TX_CUSTOM_START_OFFSET,
+			    -1, NULL);
+}
+
+static bool tx_last_bit(struct cec_pin *pin)
+{
+	return tx_error_inj(pin, CEC_ERROR_INJ_TX_LAST_BIT_OFFSET,
+			    CEC_ERROR_INJ_TX_LAST_BIT_ARG_IDX, NULL);
+}
+
+static u8 tx_add_bytes(struct cec_pin *pin)
+{
+	u8 bytes;
+
+	if (tx_error_inj(pin, CEC_ERROR_INJ_TX_ADD_BYTES_OFFSET,
+			 CEC_ERROR_INJ_TX_ADD_BYTES_ARG_IDX, &bytes))
+		return bytes;
+	return 0;
+}
+
+static bool tx_remove_byte(struct cec_pin *pin)
+{
+	return tx_error_inj(pin, CEC_ERROR_INJ_TX_REMOVE_BYTE_OFFSET, -1, NULL);
+}
+
+static bool tx_low_drive(struct cec_pin *pin)
+{
+	return tx_error_inj(pin, CEC_ERROR_INJ_TX_LOW_DRIVE_OFFSET,
+			    CEC_ERROR_INJ_TX_LOW_DRIVE_ARG_IDX, NULL);
+}
+
+static void cec_pin_to_idle(struct cec_pin *pin)
+{
+	/*
+	 * Reset all status fields, release the bus and
+	 * go to idle state.
+	 */
+	pin->rx_bit = pin->tx_bit = 0;
+	pin->rx_msg.len = 0;
+	memset(pin->rx_msg.msg, 0, sizeof(pin->rx_msg.msg));
+	pin->ts = ns_to_ktime(0);
+	pin->tx_generated_poll = false;
+	pin->tx_post_eom = false;
+	if (pin->state >= CEC_ST_TX_WAIT &&
+	    pin->state <= CEC_ST_TX_LOW_DRIVE)
+		pin->tx_toggle ^= 1;
+	if (pin->state >= CEC_ST_RX_START_BIT_LOW &&
+	    pin->state <= CEC_ST_RX_LOW_DRIVE)
+		pin->rx_toggle ^= 1;
+	pin->state = CEC_ST_IDLE;
+}
+
+/*
+ * Handle Transmit-related states
+ *
+ * Basic state changes when transmitting:
+ *
+ * Idle -> Tx Wait (waiting for the end of signal free time) ->
+ *	Tx Start Bit Low -> Tx Start Bit High ->
+ *
+ *   Regular data bits + EOM:
+ *	Tx Data 0 Low -> Tx Data 0 High ->
+ *   or:
+ *	Tx Data 1 Low -> Tx Data 1 High ->
+ *
+ *   First 4 data bits or Ack bit:
+ *	Tx Data 0 Low -> Tx Data 0 High ->
+ *   or:
+ *	Tx Data 1 Low -> Tx Data 1 High -> Tx Data 1 Pre Sample ->
+ *		Tx Data 1 Post Sample ->
+ *
+ *   After the last Ack go to Idle.
+ *
+ * If it detects a Low Drive condition then:
+ *	Tx Wait For High -> Idle
+ *
+ * If it loses arbitration, then it switches to state Rx Data Post Sample.
+ */
+static void cec_pin_tx_states(struct cec_pin *pin, ktime_t ts)
+{
+	bool v;
+	bool is_ack_bit, ack;
+
+	switch (pin->state) {
+	case CEC_ST_TX_WAIT_FOR_HIGH:
+		if (cec_pin_read(pin))
+			cec_pin_to_idle(pin);
+		break;
+
+	case CEC_ST_TX_START_BIT_LOW:
+		if (tx_short_start(pin)) {
+			/*
+			 * Error Injection: send an invalid (too short)
+			 * start pulse.
+			 */
+			pin->state = CEC_ST_TX_START_BIT_HIGH_SHORT;
+		} else if (tx_long_start(pin)) {
+			/*
+			 * Error Injection: send an invalid (too long)
+			 * start pulse.
+			 */
+			pin->state = CEC_ST_TX_START_BIT_HIGH_LONG;
+		} else {
+			pin->state = CEC_ST_TX_START_BIT_HIGH;
+		}
+		/* Generate start bit */
+		cec_pin_high(pin);
+		break;
+
+	case CEC_ST_TX_START_BIT_LOW_CUSTOM:
+		pin->state = CEC_ST_TX_START_BIT_HIGH_CUSTOM;
+		/* Generate start bit */
+		cec_pin_high(pin);
+		break;
+
+	case CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE:
+	case CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE_SHORT:
+	case CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE_LONG:
+		if (pin->tx_nacked) {
+			cec_pin_to_idle(pin);
+			pin->tx_msg.len = 0;
+			if (pin->tx_generated_poll)
+				break;
+			pin->work_tx_ts = ts;
+			pin->work_tx_status = CEC_TX_STATUS_NACK;
+			wake_up_interruptible(&pin->kthread_waitq);
+			break;
+		}
+		/* fall through */
+	case CEC_ST_TX_DATA_BIT_0_HIGH:
+	case CEC_ST_TX_DATA_BIT_0_HIGH_SHORT:
+	case CEC_ST_TX_DATA_BIT_0_HIGH_LONG:
+	case CEC_ST_TX_DATA_BIT_1_HIGH:
+	case CEC_ST_TX_DATA_BIT_1_HIGH_SHORT:
+	case CEC_ST_TX_DATA_BIT_1_HIGH_LONG:
+		/*
+		 * If the read value is 1, then all is OK, otherwise we have a
+		 * low drive condition.
+		 *
+		 * Special case: when we generate a poll message due to an
+		 * Arbitration Lost error injection, then ignore this since
+		 * the pin can actually be low in that case.
+		 */
+		if (!cec_pin_read(pin) && !pin->tx_generated_poll) {
+			/*
+			 * It's 0, so someone detected an error and pulled the
+			 * line low for 1.5 times the nominal bit period.
+			 */
+			pin->tx_msg.len = 0;
+			pin->state = CEC_ST_TX_WAIT_FOR_HIGH;
+			pin->work_tx_ts = ts;
+			pin->work_tx_status = CEC_TX_STATUS_LOW_DRIVE;
+			pin->tx_low_drive_cnt++;
+			wake_up_interruptible(&pin->kthread_waitq);
+			break;
+		}
+		/* fall through */
+	case CEC_ST_TX_DATA_BIT_HIGH_CUSTOM:
+		if (tx_last_bit(pin)) {
+			/* Error Injection: just stop sending after this bit */
+			cec_pin_to_idle(pin);
+			pin->tx_msg.len = 0;
+			if (pin->tx_generated_poll)
+				break;
+			pin->work_tx_ts = ts;
+			pin->work_tx_status = CEC_TX_STATUS_OK;
+			wake_up_interruptible(&pin->kthread_waitq);
+			break;
+		}
+		pin->tx_bit++;
+		/* fall through */
+	case CEC_ST_TX_START_BIT_HIGH:
+	case CEC_ST_TX_START_BIT_HIGH_SHORT:
+	case CEC_ST_TX_START_BIT_HIGH_LONG:
+	case CEC_ST_TX_START_BIT_HIGH_CUSTOM:
+		if (tx_low_drive(pin)) {
+			/* Error injection: go to low drive */
+			cec_pin_low(pin);
+			pin->state = CEC_ST_TX_LOW_DRIVE;
+			pin->tx_msg.len = 0;
+			if (pin->tx_generated_poll)
+				break;
+			pin->work_tx_ts = ts;
+			pin->work_tx_status = CEC_TX_STATUS_LOW_DRIVE;
+			pin->tx_low_drive_cnt++;
+			wake_up_interruptible(&pin->kthread_waitq);
+			break;
+		}
+		if (pin->tx_bit / 10 >= pin->tx_msg.len + pin->tx_extra_bytes) {
+			cec_pin_to_idle(pin);
+			pin->tx_msg.len = 0;
+			if (pin->tx_generated_poll)
+				break;
+			pin->work_tx_ts = ts;
+			pin->work_tx_status = CEC_TX_STATUS_OK;
+			wake_up_interruptible(&pin->kthread_waitq);
+			break;
+		}
+
+		switch (pin->tx_bit % 10) {
+		default: {
+			/*
+			 * In the CEC_ERROR_INJ_TX_ADD_BYTES case we transmit
+			 * extra bytes, so pin->tx_bit / 10 can become >= 16.
+			 * Generate bit values for those extra bytes instead
+			 * of reading them from the transmit buffer.
+			 */
+			unsigned int idx = (pin->tx_bit / 10);
+			u8 val = idx;
+
+			if (idx < pin->tx_msg.len)
+				val = pin->tx_msg.msg[idx];
+			v = val & (1 << (7 - (pin->tx_bit % 10)));
+
+			pin->state = v ? CEC_ST_TX_DATA_BIT_1_LOW :
+					 CEC_ST_TX_DATA_BIT_0_LOW;
+			break;
+		}
+		case EOM_BIT: {
+			unsigned int tot_len = pin->tx_msg.len +
+					       pin->tx_extra_bytes;
+			unsigned int tx_byte_idx = pin->tx_bit / 10;
+
+			v = !pin->tx_post_eom && tx_byte_idx == tot_len - 1;
+			if (tot_len > 1 && tx_byte_idx == tot_len - 2 &&
+			    tx_early_eom(pin)) {
+				/* Error injection: set EOM one byte early */
+				v = true;
+				pin->tx_post_eom = true;
+			} else if (v && tx_no_eom(pin)) {
+				/* Error injection: no EOM */
+				v = false;
+			}
+			pin->state = v ? CEC_ST_TX_DATA_BIT_1_LOW :
+					 CEC_ST_TX_DATA_BIT_0_LOW;
+			break;
+		}
+		case ACK_BIT:
+			pin->state = CEC_ST_TX_DATA_BIT_1_LOW;
+			break;
+		}
+		if (tx_custom_bit(pin))
+			pin->state = CEC_ST_TX_DATA_BIT_LOW_CUSTOM;
+		cec_pin_low(pin);
+		break;
+
+	case CEC_ST_TX_DATA_BIT_0_LOW:
+	case CEC_ST_TX_DATA_BIT_1_LOW:
+		v = pin->state == CEC_ST_TX_DATA_BIT_1_LOW;
+		is_ack_bit = pin->tx_bit % 10 == ACK_BIT;
+		if (v && (pin->tx_bit < 4 || is_ack_bit)) {
+			pin->state = CEC_ST_TX_DATA_BIT_1_HIGH_PRE_SAMPLE;
+		} else if (!is_ack_bit && tx_short_bit(pin)) {
+			/* Error Injection: send an invalid (too short) bit */
+			pin->state = v ? CEC_ST_TX_DATA_BIT_1_HIGH_SHORT :
+					 CEC_ST_TX_DATA_BIT_0_HIGH_SHORT;
+		} else if (!is_ack_bit && tx_long_bit(pin)) {
+			/* Error Injection: send an invalid (too long) bit */
+			pin->state = v ? CEC_ST_TX_DATA_BIT_1_HIGH_LONG :
+					 CEC_ST_TX_DATA_BIT_0_HIGH_LONG;
+		} else {
+			pin->state = v ? CEC_ST_TX_DATA_BIT_1_HIGH :
+					 CEC_ST_TX_DATA_BIT_0_HIGH;
+		}
+		cec_pin_high(pin);
+		break;
+
+	case CEC_ST_TX_DATA_BIT_LOW_CUSTOM:
+		pin->state = CEC_ST_TX_DATA_BIT_HIGH_CUSTOM;
+		cec_pin_high(pin);
+		break;
+
+	case CEC_ST_TX_DATA_BIT_1_HIGH_PRE_SAMPLE:
+		/* Read the CEC value at the sample time */
+		v = cec_pin_read(pin);
+		is_ack_bit = pin->tx_bit % 10 == ACK_BIT;
+		/*
+		 * If v == 0 and we're within the first 4 bits
+		 * of the initiator, then someone else started
+		 * transmitting and we lost the arbitration
+		 * (i.e. the logical address of the other
+		 * transmitter has more leading 0 bits in the
+		 * initiator).
+		 */
+		if (!v && !is_ack_bit && !pin->tx_generated_poll) {
+			pin->tx_msg.len = 0;
+			pin->work_tx_ts = ts;
+			pin->work_tx_status = CEC_TX_STATUS_ARB_LOST;
+			wake_up_interruptible(&pin->kthread_waitq);
+			pin->rx_bit = pin->tx_bit;
+			pin->tx_bit = 0;
+			memset(pin->rx_msg.msg, 0, sizeof(pin->rx_msg.msg));
+			pin->rx_msg.msg[0] = pin->tx_msg.msg[0];
+			pin->rx_msg.msg[0] &= (0xff << (8 - pin->rx_bit));
+			pin->rx_msg.len = 0;
+			pin->ts = ktime_sub_us(ts, CEC_TIM_DATA_BIT_SAMPLE);
+			pin->state = CEC_ST_RX_DATA_POST_SAMPLE;
+			pin->rx_bit++;
+			break;
+		}
+		pin->state = CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE;
+		if (!is_ack_bit && tx_short_bit(pin)) {
+			/* Error Injection: send an invalid (too short) bit */
+			pin->state = CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE_SHORT;
+		} else if (!is_ack_bit && tx_long_bit(pin)) {
+			/* Error Injection: send an invalid (too long) bit */
+			pin->state = CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE_LONG;
+		}
+		if (!is_ack_bit)
+			break;
+		/* Was the message ACKed? */
+		ack = cec_msg_is_broadcast(&pin->tx_msg) ? v : !v;
+		if (!ack && (!pin->tx_ignore_nack_until_eom ||
+		    pin->tx_bit / 10 == pin->tx_msg.len - 1) &&
+		    !pin->tx_post_eom) {
+			/*
+			 * Note: the CEC spec is ambiguous regarding
+			 * what action to take when a NACK appears
+			 * before the last byte of the payload was
+			 * transmitted: either stop transmitting
+			 * immediately, or wait until the last byte
+			 * was transmitted.
+			 *
+			 * Most CEC implementations appear to stop
+			 * immediately, and that's what we do here
+			 * as well.
+			 */
+			pin->tx_nacked = true;
+		}
+		break;
+
+	case CEC_ST_TX_PULSE_LOW_CUSTOM:
+		cec_pin_high(pin);
+		pin->state = CEC_ST_TX_PULSE_HIGH_CUSTOM;
+		break;
+
+	case CEC_ST_TX_PULSE_HIGH_CUSTOM:
+		cec_pin_to_idle(pin);
+		break;
+
+	default:
+		break;
+	}
+}
+
+/*
+ * Handle Receive-related states
+ *
+ * Basic state changes when receiving:
+ *
+ *	Rx Start Bit Low -> Rx Start Bit High ->
+ *   Regular data bits + EOM:
+ *	Rx Data Sample -> Rx Data Post Sample -> Rx Data High ->
+ *   Ack bit 0:
+ *	Rx Ack Low -> Rx Ack Low Post -> Rx Data High ->
+ *   Ack bit 1:
+ *	Rx Ack High Post -> Rx Data High ->
+ *   Ack bit 0 && EOM:
+ *	Rx Ack Low -> Rx Ack Low Post -> Rx Ack Finish -> Idle
+ */
+static void cec_pin_rx_states(struct cec_pin *pin, ktime_t ts)
+{
+	s32 delta;
+	bool v;
+	bool ack;
+	bool bcast, for_us;
+	u8 dest;
+	u8 poll;
+
+	switch (pin->state) {
+	/* Receive states */
+	case CEC_ST_RX_START_BIT_LOW:
+		v = cec_pin_read(pin);
+		if (!v)
+			break;
+		pin->state = CEC_ST_RX_START_BIT_HIGH;
+		delta = ktime_us_delta(ts, pin->ts);
+		/* Start bit low is too short, go back to idle */
+		if (delta < CEC_TIM_START_BIT_LOW_MIN - CEC_TIM_IDLE_SAMPLE) {
+			if (!pin->rx_start_bit_low_too_short_cnt++) {
+				pin->rx_start_bit_low_too_short_ts = ktime_to_ns(pin->ts);
+				pin->rx_start_bit_low_too_short_delta = delta;
+			}
+			cec_pin_to_idle(pin);
+			break;
+		}
+		if (rx_arb_lost(pin, &poll)) {
+			cec_msg_init(&pin->tx_msg, poll >> 4, poll & 0xf);
+			pin->tx_generated_poll = true;
+			pin->tx_extra_bytes = 0;
+			pin->state = CEC_ST_TX_START_BIT_HIGH;
+			pin->ts = ts;
+		}
+		break;
+
+	case CEC_ST_RX_START_BIT_HIGH:
+		v = cec_pin_read(pin);
+		delta = ktime_us_delta(ts, pin->ts);
+		/*
+		 * Unfortunately the spec does not specify when to give up
+		 * and go to idle. We just pick TOTAL_LONG.
+		 */
+		if (v && delta > CEC_TIM_START_BIT_TOTAL_LONG) {
+			pin->rx_start_bit_too_long_cnt++;
+			cec_pin_to_idle(pin);
+			break;
+		}
+		if (v)
+			break;
+		/* Start bit is too short, go back to idle */
+		if (delta < CEC_TIM_START_BIT_TOTAL_MIN - CEC_TIM_IDLE_SAMPLE) {
+			if (!pin->rx_start_bit_too_short_cnt++) {
+				pin->rx_start_bit_too_short_ts = ktime_to_ns(pin->ts);
+				pin->rx_start_bit_too_short_delta = delta;
+			}
+			cec_pin_to_idle(pin);
+			break;
+		}
+		if (rx_low_drive(pin)) {
+			/* Error injection: go to low drive */
+			cec_pin_low(pin);
+			pin->state = CEC_ST_RX_LOW_DRIVE;
+			pin->rx_low_drive_cnt++;
+			break;
+		}
+		pin->state = CEC_ST_RX_DATA_SAMPLE;
+		pin->ts = ts;
+		pin->rx_eom = false;
+		break;
+
+	case CEC_ST_RX_DATA_SAMPLE:
+		v = cec_pin_read(pin);
+		pin->state = CEC_ST_RX_DATA_POST_SAMPLE;
+		switch (pin->rx_bit % 10) {
+		default:
+			if (pin->rx_bit / 10 < CEC_MAX_MSG_SIZE)
+				pin->rx_msg.msg[pin->rx_bit / 10] |=
+					v << (7 - (pin->rx_bit % 10));
+			break;
+		case EOM_BIT:
+			pin->rx_eom = v;
+			pin->rx_msg.len = pin->rx_bit / 10 + 1;
+			break;
+		case ACK_BIT:
+			break;
+		}
+		pin->rx_bit++;
+		break;
+
+	case CEC_ST_RX_DATA_POST_SAMPLE:
+		pin->state = CEC_ST_RX_DATA_WAIT_FOR_LOW;
+		break;
+
+	case CEC_ST_RX_DATA_WAIT_FOR_LOW:
+		v = cec_pin_read(pin);
+		delta = ktime_us_delta(ts, pin->ts);
+		/*
+		 * Unfortunately the spec does not specify when to give up
+		 * and go to idle. We just pick TOTAL_LONG.
+		 */
+		if (v && delta > CEC_TIM_DATA_BIT_TOTAL_LONG) {
+			pin->rx_data_bit_too_long_cnt++;
+			cec_pin_to_idle(pin);
+			break;
+		}
+		if (v)
+			break;
+
+		if (rx_low_drive(pin)) {
+			/* Error injection: go to low drive */
+			cec_pin_low(pin);
+			pin->state = CEC_ST_RX_LOW_DRIVE;
+			pin->rx_low_drive_cnt++;
+			break;
+		}
+
+		/*
+		 * Go to low drive state when the total bit time is
+		 * too short.
+		 */
+		if (delta < CEC_TIM_DATA_BIT_TOTAL_MIN) {
+			if (!pin->rx_data_bit_too_short_cnt++) {
+				pin->rx_data_bit_too_short_ts = ktime_to_ns(pin->ts);
+				pin->rx_data_bit_too_short_delta = delta;
+			}
+			cec_pin_low(pin);
+			pin->state = CEC_ST_RX_LOW_DRIVE;
+			pin->rx_low_drive_cnt++;
+			break;
+		}
+		pin->ts = ts;
+		if (pin->rx_bit % 10 != 9) {
+			pin->state = CEC_ST_RX_DATA_SAMPLE;
+			break;
+		}
+
+		dest = cec_msg_destination(&pin->rx_msg);
+		bcast = dest == CEC_LOG_ADDR_BROADCAST;
+		/* for_us == broadcast or directed to us */
+		for_us = bcast || (pin->la_mask & (1 << dest));
+		/* ACK bit value */
+		ack = bcast ? 1 : !for_us;
+
+		if (for_us && rx_nack(pin)) {
+			/* Error injection: toggle the ACK bit */
+			ack = !ack;
+		}
+
+		if (ack) {
+			/* No need to write to the bus, just wait */
+			pin->state = CEC_ST_RX_ACK_HIGH_POST;
+			break;
+		}
+		cec_pin_low(pin);
+		pin->state = CEC_ST_RX_ACK_LOW;
+		break;
+
+	case CEC_ST_RX_ACK_LOW:
+		cec_pin_high(pin);
+		pin->state = CEC_ST_RX_ACK_LOW_POST;
+		break;
+
+	case CEC_ST_RX_ACK_LOW_POST:
+	case CEC_ST_RX_ACK_HIGH_POST:
+		v = cec_pin_read(pin);
+		if (v && pin->rx_eom) {
+			pin->work_rx_msg = pin->rx_msg;
+			pin->work_rx_msg.rx_ts = ktime_to_ns(ts);
+			wake_up_interruptible(&pin->kthread_waitq);
+			pin->ts = ts;
+			pin->state = CEC_ST_RX_ACK_FINISH;
+			break;
+		}
+		pin->rx_bit++;
+		pin->state = CEC_ST_RX_DATA_WAIT_FOR_LOW;
+		break;
+
+	case CEC_ST_RX_ACK_FINISH:
+		cec_pin_to_idle(pin);
+		break;
+
+	default:
+		break;
+	}
+}
+
+/*
+ * Main timer function
+ *
+ */
+static enum hrtimer_restart cec_pin_timer(struct hrtimer *timer)
+{
+	struct cec_pin *pin = container_of(timer, struct cec_pin, timer);
+	struct cec_adapter *adap = pin->adap;
+	ktime_t ts;
+	s32 delta;
+	u32 usecs;
+
+	ts = ktime_get();
+	if (ktime_to_ns(pin->timer_ts)) {
+		delta = ktime_us_delta(ts, pin->timer_ts);
+		pin->timer_cnt++;
+		if (delta > 100 && pin->state != CEC_ST_IDLE) {
+			/* Keep track of timer overruns */
+			pin->timer_sum_overrun += delta;
+			pin->timer_100ms_overruns++;
+			if (delta > 300)
+				pin->timer_300ms_overruns++;
+			if (delta > pin->timer_max_overrun)
+				pin->timer_max_overrun = delta;
+		}
+	}
+	if (adap->monitor_pin_cnt)
+		cec_pin_read(pin);
+
+	if (pin->wait_usecs) {
+		/*
+		 * If we are monitoring the pin, then we have to
+		 * sample at regular intervals.
+		 */
+		if (pin->wait_usecs > 150) {
+			pin->wait_usecs -= 100;
+			pin->timer_ts = ktime_add_us(ts, 100);
+			hrtimer_forward_now(timer, ns_to_ktime(100000));
+			return HRTIMER_RESTART;
+		}
+		if (pin->wait_usecs > 100) {
+			pin->wait_usecs /= 2;
+			pin->timer_ts = ktime_add_us(ts, pin->wait_usecs);
+			hrtimer_forward_now(timer,
+					ns_to_ktime(pin->wait_usecs * 1000));
+			return HRTIMER_RESTART;
+		}
+		pin->timer_ts = ktime_add_us(ts, pin->wait_usecs);
+		hrtimer_forward_now(timer,
+				    ns_to_ktime(pin->wait_usecs * 1000));
+		pin->wait_usecs = 0;
+		return HRTIMER_RESTART;
+	}
+
+	switch (pin->state) {
+	/* Transmit states */
+	case CEC_ST_TX_WAIT_FOR_HIGH:
+	case CEC_ST_TX_START_BIT_LOW:
+	case CEC_ST_TX_START_BIT_HIGH:
+	case CEC_ST_TX_START_BIT_HIGH_SHORT:
+	case CEC_ST_TX_START_BIT_HIGH_LONG:
+	case CEC_ST_TX_START_BIT_LOW_CUSTOM:
+	case CEC_ST_TX_START_BIT_HIGH_CUSTOM:
+	case CEC_ST_TX_DATA_BIT_0_LOW:
+	case CEC_ST_TX_DATA_BIT_0_HIGH:
+	case CEC_ST_TX_DATA_BIT_0_HIGH_SHORT:
+	case CEC_ST_TX_DATA_BIT_0_HIGH_LONG:
+	case CEC_ST_TX_DATA_BIT_1_LOW:
+	case CEC_ST_TX_DATA_BIT_1_HIGH:
+	case CEC_ST_TX_DATA_BIT_1_HIGH_SHORT:
+	case CEC_ST_TX_DATA_BIT_1_HIGH_LONG:
+	case CEC_ST_TX_DATA_BIT_1_HIGH_PRE_SAMPLE:
+	case CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE:
+	case CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE_SHORT:
+	case CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE_LONG:
+	case CEC_ST_TX_DATA_BIT_LOW_CUSTOM:
+	case CEC_ST_TX_DATA_BIT_HIGH_CUSTOM:
+	case CEC_ST_TX_PULSE_LOW_CUSTOM:
+	case CEC_ST_TX_PULSE_HIGH_CUSTOM:
+		cec_pin_tx_states(pin, ts);
+		break;
+
+	/* Receive states */
+	case CEC_ST_RX_START_BIT_LOW:
+	case CEC_ST_RX_START_BIT_HIGH:
+	case CEC_ST_RX_DATA_SAMPLE:
+	case CEC_ST_RX_DATA_POST_SAMPLE:
+	case CEC_ST_RX_DATA_WAIT_FOR_LOW:
+	case CEC_ST_RX_ACK_LOW:
+	case CEC_ST_RX_ACK_LOW_POST:
+	case CEC_ST_RX_ACK_HIGH_POST:
+	case CEC_ST_RX_ACK_FINISH:
+		cec_pin_rx_states(pin, ts);
+		break;
+
+	case CEC_ST_IDLE:
+	case CEC_ST_TX_WAIT:
+		if (!cec_pin_high(pin)) {
+			/* Start bit, switch to receive state */
+			pin->ts = ts;
+			pin->state = CEC_ST_RX_START_BIT_LOW;
+			/*
+			 * If a transmit is pending, then that transmit should
+			 * use a signal free time of no more than
+			 * CEC_SIGNAL_FREE_TIME_NEW_INITIATOR since it will
+			 * have a new initiator due to the receive that is now
+			 * starting.
+			 */
+			if (pin->tx_msg.len && pin->tx_signal_free_time >
+			    CEC_SIGNAL_FREE_TIME_NEW_INITIATOR)
+				pin->tx_signal_free_time =
+					CEC_SIGNAL_FREE_TIME_NEW_INITIATOR;
+			break;
+		}
+		if (ktime_to_ns(pin->ts) == 0)
+			pin->ts = ts;
+		if (pin->tx_msg.len) {
+			/*
+			 * Check if the bus has been free for long enough
+			 * so we can kick off the pending transmit.
+			 */
+			delta = ktime_us_delta(ts, pin->ts);
+			if (delta / CEC_TIM_DATA_BIT_TOTAL >
+			    pin->tx_signal_free_time) {
+				pin->tx_nacked = false;
+				if (tx_custom_start(pin))
+					pin->state = CEC_ST_TX_START_BIT_LOW_CUSTOM;
+				else
+					pin->state = CEC_ST_TX_START_BIT_LOW;
+				/* Generate start bit */
+				cec_pin_low(pin);
+				break;
+			}
+			if (delta / CEC_TIM_DATA_BIT_TOTAL >
+			    pin->tx_signal_free_time - 1)
+				pin->state = CEC_ST_TX_WAIT;
+			break;
+		}
+		if (pin->tx_custom_pulse && pin->state == CEC_ST_IDLE) {
+			pin->tx_custom_pulse = false;
+			/* Generate custom pulse */
+			cec_pin_low(pin);
+			pin->state = CEC_ST_TX_PULSE_LOW_CUSTOM;
+			break;
+		}
+		if (pin->state != CEC_ST_IDLE || pin->ops->enable_irq == NULL ||
+		    pin->enable_irq_failed || adap->is_configuring ||
+		    adap->is_configured || adap->monitor_all_cnt)
+			break;
+		/* Switch to interrupt mode */
+		atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_ENABLE);
+		pin->state = CEC_ST_RX_IRQ;
+		wake_up_interruptible(&pin->kthread_waitq);
+		return HRTIMER_NORESTART;
+
+	case CEC_ST_TX_LOW_DRIVE:
+	case CEC_ST_RX_LOW_DRIVE:
+		cec_pin_high(pin);
+		cec_pin_to_idle(pin);
+		break;
+
+	default:
+		break;
+	}
+
+	switch (pin->state) {
+	case CEC_ST_TX_START_BIT_LOW_CUSTOM:
+	case CEC_ST_TX_DATA_BIT_LOW_CUSTOM:
+	case CEC_ST_TX_PULSE_LOW_CUSTOM:
+		usecs = pin->tx_custom_low_usecs;
+		break;
+	case CEC_ST_TX_START_BIT_HIGH_CUSTOM:
+	case CEC_ST_TX_DATA_BIT_HIGH_CUSTOM:
+	case CEC_ST_TX_PULSE_HIGH_CUSTOM:
+		usecs = pin->tx_custom_high_usecs;
+		break;
+	default:
+		usecs = states[pin->state].usecs;
+		break;
+	}
+
+	if (!adap->monitor_pin_cnt || usecs <= 150) {
+		pin->wait_usecs = 0;
+		pin->timer_ts = ktime_add_us(ts, usecs);
+		hrtimer_forward_now(timer,
+				ns_to_ktime(usecs * 1000));
+		return HRTIMER_RESTART;
+	}
+	pin->wait_usecs = usecs - 100;
+	pin->timer_ts = ktime_add_us(ts, 100);
+	hrtimer_forward_now(timer, ns_to_ktime(100000));
+	return HRTIMER_RESTART;
+}
+
+static int cec_pin_thread_func(void *_adap)
+{
+	struct cec_adapter *adap = _adap;
+	struct cec_pin *pin = adap->pin;
+
+	for (;;) {
+		wait_event_interruptible(pin->kthread_waitq,
+			kthread_should_stop() ||
+			pin->work_rx_msg.len ||
+			pin->work_tx_status ||
+			atomic_read(&pin->work_irq_change) ||
+			atomic_read(&pin->work_pin_num_events));
+
+		if (pin->work_rx_msg.len) {
+			struct cec_msg *msg = &pin->work_rx_msg;
+
+			if (msg->len > 1 && msg->len < CEC_MAX_MSG_SIZE &&
+			    rx_add_byte(pin)) {
+				/* Error injection: add byte to the message */
+				msg->msg[msg->len++] = 0x55;
+			}
+			if (msg->len > 2 && rx_remove_byte(pin)) {
+				/* Error injection: remove byte from message */
+				msg->len--;
+			}
+			if (msg->len > CEC_MAX_MSG_SIZE)
+				msg->len = CEC_MAX_MSG_SIZE;
+			cec_received_msg_ts(adap, msg,
+				ns_to_ktime(pin->work_rx_msg.rx_ts));
+			msg->len = 0;
+		}
+		if (pin->work_tx_status) {
+			unsigned int tx_status = pin->work_tx_status;
+
+			pin->work_tx_status = 0;
+			cec_transmit_attempt_done_ts(adap, tx_status,
+						     pin->work_tx_ts);
+		}
+
+		while (atomic_read(&pin->work_pin_num_events)) {
+			unsigned int idx = pin->work_pin_events_rd;
+			u8 v = pin->work_pin_events[idx];
+
+			cec_queue_pin_cec_event(adap,
+						v & CEC_PIN_EVENT_FL_IS_HIGH,
+						v & CEC_PIN_EVENT_FL_DROPPED,
+						pin->work_pin_ts[idx]);
+			pin->work_pin_events_rd = (idx + 1) % CEC_NUM_PIN_EVENTS;
+			atomic_dec(&pin->work_pin_num_events);
+		}
+
+		switch (atomic_xchg(&pin->work_irq_change,
+				    CEC_PIN_IRQ_UNCHANGED)) {
+		case CEC_PIN_IRQ_DISABLE:
+			pin->ops->disable_irq(adap);
+			cec_pin_high(pin);
+			cec_pin_to_idle(pin);
+			hrtimer_start(&pin->timer, ns_to_ktime(0),
+				      HRTIMER_MODE_REL);
+			break;
+		case CEC_PIN_IRQ_ENABLE:
+			pin->enable_irq_failed = !pin->ops->enable_irq(adap);
+			if (pin->enable_irq_failed) {
+				cec_pin_to_idle(pin);
+				hrtimer_start(&pin->timer, ns_to_ktime(0),
+					      HRTIMER_MODE_REL);
+			}
+			break;
+		default:
+			break;
+		}
+
+		if (kthread_should_stop())
+			break;
+	}
+	return 0;
+}
+
+static int cec_pin_adap_enable(struct cec_adapter *adap, bool enable)
+{
+	struct cec_pin *pin = adap->pin;
+
+	pin->enabled = enable;
+	if (enable) {
+		atomic_set(&pin->work_pin_num_events, 0);
+		pin->work_pin_events_rd = pin->work_pin_events_wr = 0;
+		pin->work_pin_events_dropped = false;
+		cec_pin_read(pin);
+		cec_pin_to_idle(pin);
+		pin->tx_msg.len = 0;
+		pin->timer_ts = ns_to_ktime(0);
+		atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_UNCHANGED);
+		pin->kthread = kthread_run(cec_pin_thread_func, adap,
+					   "cec-pin");
+		if (IS_ERR(pin->kthread)) {
+			pr_err("cec-pin: kernel_thread() failed\n");
+			return PTR_ERR(pin->kthread);
+		}
+		hrtimer_start(&pin->timer, ns_to_ktime(0),
+			      HRTIMER_MODE_REL);
+	} else {
+		if (pin->ops->disable_irq)
+			pin->ops->disable_irq(adap);
+		hrtimer_cancel(&pin->timer);
+		kthread_stop(pin->kthread);
+		cec_pin_read(pin);
+		cec_pin_to_idle(pin);
+		pin->state = CEC_ST_OFF;
+	}
+	return 0;
+}
+
+static int cec_pin_adap_log_addr(struct cec_adapter *adap, u8 log_addr)
+{
+	struct cec_pin *pin = adap->pin;
+
+	if (log_addr == CEC_LOG_ADDR_INVALID)
+		pin->la_mask = 0;
+	else
+		pin->la_mask |= (1 << log_addr);
+	return 0;
+}
+
+void cec_pin_start_timer(struct cec_pin *pin)
+{
+	if (pin->state != CEC_ST_RX_IRQ)
+		return;
+
+	atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_UNCHANGED);
+	pin->ops->disable_irq(pin->adap);
+	cec_pin_high(pin);
+	cec_pin_to_idle(pin);
+	hrtimer_start(&pin->timer, ns_to_ktime(0), HRTIMER_MODE_REL);
+}
+
+static int cec_pin_adap_transmit(struct cec_adapter *adap, u8 attempts,
+				      u32 signal_free_time, struct cec_msg *msg)
+{
+	struct cec_pin *pin = adap->pin;
+
+	/*
+	 * If a receive is in progress, then this transmit should use
+	 * a signal free time of max CEC_SIGNAL_FREE_TIME_NEW_INITIATOR
+	 * since when it starts transmitting it will have a new initiator.
+	 */
+	if (pin->state != CEC_ST_IDLE &&
+	    signal_free_time > CEC_SIGNAL_FREE_TIME_NEW_INITIATOR)
+		signal_free_time = CEC_SIGNAL_FREE_TIME_NEW_INITIATOR;
+
+	pin->tx_signal_free_time = signal_free_time;
+	pin->tx_extra_bytes = 0;
+	pin->tx_msg = *msg;
+	if (msg->len > 1) {
+		/* Error injection: add byte to the message */
+		pin->tx_extra_bytes = tx_add_bytes(pin);
+	}
+	if (msg->len > 2 && tx_remove_byte(pin)) {
+		/* Error injection: remove byte from the message */
+		pin->tx_msg.len--;
+	}
+	pin->work_tx_status = 0;
+	pin->tx_bit = 0;
+	cec_pin_start_timer(pin);
+	return 0;
+}
+
+static void cec_pin_adap_status(struct cec_adapter *adap,
+				       struct seq_file *file)
+{
+	struct cec_pin *pin = adap->pin;
+
+	seq_printf(file, "state: %s\n", states[pin->state].name);
+	seq_printf(file, "tx_bit: %d\n", pin->tx_bit);
+	seq_printf(file, "rx_bit: %d\n", pin->rx_bit);
+	seq_printf(file, "cec pin: %d\n", pin->ops->read(adap));
+	seq_printf(file, "cec pin events dropped: %u\n",
+		   pin->work_pin_events_dropped_cnt);
+	seq_printf(file, "irq failed: %d\n", pin->enable_irq_failed);
+	if (pin->timer_100ms_overruns) {
+		seq_printf(file, "timer overruns > 100ms: %u of %u\n",
+			   pin->timer_100ms_overruns, pin->timer_cnt);
+		seq_printf(file, "timer overruns > 300ms: %u of %u\n",
+			   pin->timer_300ms_overruns, pin->timer_cnt);
+		seq_printf(file, "max timer overrun: %u usecs\n",
+			   pin->timer_max_overrun);
+		seq_printf(file, "avg timer overrun: %u usecs\n",
+			   pin->timer_sum_overrun / pin->timer_100ms_overruns);
+	}
+	if (pin->rx_start_bit_low_too_short_cnt)
+		seq_printf(file,
+			   "rx start bit low too short: %u (delta %u, ts %llu)\n",
+			   pin->rx_start_bit_low_too_short_cnt,
+			   pin->rx_start_bit_low_too_short_delta,
+			   pin->rx_start_bit_low_too_short_ts);
+	if (pin->rx_start_bit_too_short_cnt)
+		seq_printf(file,
+			   "rx start bit too short: %u (delta %u, ts %llu)\n",
+			   pin->rx_start_bit_too_short_cnt,
+			   pin->rx_start_bit_too_short_delta,
+			   pin->rx_start_bit_too_short_ts);
+	if (pin->rx_start_bit_too_long_cnt)
+		seq_printf(file, "rx start bit too long: %u\n",
+			   pin->rx_start_bit_too_long_cnt);
+	if (pin->rx_data_bit_too_short_cnt)
+		seq_printf(file,
+			   "rx data bit too short: %u (delta %u, ts %llu)\n",
+			   pin->rx_data_bit_too_short_cnt,
+			   pin->rx_data_bit_too_short_delta,
+			   pin->rx_data_bit_too_short_ts);
+	if (pin->rx_data_bit_too_long_cnt)
+		seq_printf(file, "rx data bit too long: %u\n",
+			   pin->rx_data_bit_too_long_cnt);
+	seq_printf(file, "rx initiated low drive: %u\n", pin->rx_low_drive_cnt);
+	seq_printf(file, "tx detected low drive: %u\n", pin->tx_low_drive_cnt);
+	pin->work_pin_events_dropped_cnt = 0;
+	pin->timer_cnt = 0;
+	pin->timer_100ms_overruns = 0;
+	pin->timer_300ms_overruns = 0;
+	pin->timer_max_overrun = 0;
+	pin->timer_sum_overrun = 0;
+	pin->rx_start_bit_low_too_short_cnt = 0;
+	pin->rx_start_bit_too_short_cnt = 0;
+	pin->rx_start_bit_too_long_cnt = 0;
+	pin->rx_data_bit_too_short_cnt = 0;
+	pin->rx_data_bit_too_long_cnt = 0;
+	pin->rx_low_drive_cnt = 0;
+	pin->tx_low_drive_cnt = 0;
+	if (pin->ops->status)
+		pin->ops->status(adap, file);
+}
+
+static int cec_pin_adap_monitor_all_enable(struct cec_adapter *adap,
+						  bool enable)
+{
+	struct cec_pin *pin = adap->pin;
+
+	pin->monitor_all = enable;
+	return 0;
+}
+
+static void cec_pin_adap_free(struct cec_adapter *adap)
+{
+	struct cec_pin *pin = adap->pin;
+
+	if (pin->ops->free)
+		pin->ops->free(adap);
+	adap->pin = NULL;
+	kfree(pin);
+}
+
+static int cec_pin_received(struct cec_adapter *adap, struct cec_msg *msg)
+{
+	struct cec_pin *pin = adap->pin;
+
+	if (pin->ops->received)
+		return pin->ops->received(adap, msg);
+	return -ENOMSG;
+}
+
+void cec_pin_changed(struct cec_adapter *adap, bool value)
+{
+	struct cec_pin *pin = adap->pin;
+
+	cec_pin_update(pin, value, false);
+	if (!value && (adap->is_configuring || adap->is_configured ||
+		       adap->monitor_all_cnt))
+		atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_DISABLE);
+}
+EXPORT_SYMBOL_GPL(cec_pin_changed);
+
+static const struct cec_adap_ops cec_pin_adap_ops = {
+	.adap_enable = cec_pin_adap_enable,
+	.adap_monitor_all_enable = cec_pin_adap_monitor_all_enable,
+	.adap_log_addr = cec_pin_adap_log_addr,
+	.adap_transmit = cec_pin_adap_transmit,
+	.adap_status = cec_pin_adap_status,
+	.adap_free = cec_pin_adap_free,
+#ifdef CONFIG_CEC_PIN_ERROR_INJ
+	.error_inj_parse_line = cec_pin_error_inj_parse_line,
+	.error_inj_show = cec_pin_error_inj_show,
+#endif
+	.received = cec_pin_received,
+};
+
+struct cec_adapter *cec_pin_allocate_adapter(const struct cec_pin_ops *pin_ops,
+					void *priv, const char *name, u32 caps)
+{
+	struct cec_adapter *adap;
+	struct cec_pin *pin = kzalloc(sizeof(*pin), GFP_KERNEL);
+
+	if (pin == NULL)
+		return ERR_PTR(-ENOMEM);
+	pin->ops = pin_ops;
+	hrtimer_init(&pin->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+	pin->timer.function = cec_pin_timer;
+	init_waitqueue_head(&pin->kthread_waitq);
+	pin->tx_custom_low_usecs = CEC_TIM_CUSTOM_DEFAULT;
+	pin->tx_custom_high_usecs = CEC_TIM_CUSTOM_DEFAULT;
+
+	adap = cec_allocate_adapter(&cec_pin_adap_ops, priv, name,
+			    caps | CEC_CAP_MONITOR_ALL | CEC_CAP_MONITOR_PIN,
+			    CEC_MAX_LOG_ADDRS);
+
+	if (IS_ERR(adap)) {
+		kfree(pin);
+		return adap;
+	}
+
+	adap->pin = pin;
+	pin->adap = adap;
+	cec_pin_update(pin, cec_pin_high(pin), true);
+	return adap;
+}
+EXPORT_SYMBOL_GPL(cec_pin_allocate_adapter);
diff --git a/drivers/media/cec/core/cec-priv.h b/drivers/media/cec/core/cec-priv.h
new file mode 100644
index 000000000000..9bbd05053d42
--- /dev/null
+++ b/drivers/media/cec/core/cec-priv.h
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * cec-priv.h - HDMI Consumer Electronics Control internal header
+ *
+ * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _CEC_PRIV_H
+#define _CEC_PRIV_H
+
+#include <linux/cec-funcs.h>
+#include <media/cec-notifier.h>
+
+#define dprintk(lvl, fmt, arg...)					\
+	do {								\
+		if (lvl <= cec_debug)					\
+			pr_info("cec-%s: " fmt, adap->name, ## arg);	\
+	} while (0)
+
+/* devnode to cec_adapter */
+#define to_cec_adapter(node) container_of(node, struct cec_adapter, devnode)
+
+static inline bool msg_is_raw(const struct cec_msg *msg)
+{
+	return msg->flags & CEC_MSG_FL_RAW;
+}
+
+/* cec-core.c */
+extern int cec_debug;
+int cec_get_device(struct cec_devnode *devnode);
+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);
+int __cec_s_log_addrs(struct cec_adapter *adap,
+		      struct cec_log_addrs *log_addrs, bool block);
+int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg,
+			struct cec_fh *fh, bool block);
+void cec_queue_event_fh(struct cec_fh *fh,
+			const struct cec_event *new_ev, u64 ts);
+
+/* cec-api.c */
+extern const struct file_operations cec_devnode_fops;
+
+#endif
diff --git a/drivers/media/cec/platform/Kconfig b/drivers/media/cec/platform/Kconfig
new file mode 100644
index 000000000000..2c4dd7401dd8
--- /dev/null
+++ b/drivers/media/cec/platform/Kconfig
@@ -0,0 +1,121 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Platform drivers
+
+config CEC_CROS_EC
+	tristate "ChromeOS EC CEC driver"
+	depends on CROS_EC
+	select CEC_CORE
+	select CEC_NOTIFIER
+	select CROS_EC_PROTO
+	help
+	  If you say yes here you will get support for the
+	  ChromeOS Embedded Controller's CEC.
+	  The CEC bus is present in the HDMI connector and enables communication
+	  between compatible devices.
+
+config CEC_MESON_AO
+	tristate "Amlogic Meson AO CEC driver"
+	depends on ARCH_MESON || COMPILE_TEST
+	select CEC_CORE
+	select CEC_NOTIFIER
+	help
+	  This is a driver for Amlogic Meson SoCs AO CEC interface. It uses the
+	  generic CEC framework interface.
+	  CEC bus is present in the HDMI connector and enables communication
+
+config CEC_MESON_G12A_AO
+	tristate "Amlogic Meson G12A AO CEC driver"
+	depends on ARCH_MESON || COMPILE_TEST
+	depends on COMMON_CLK && OF
+	select REGMAP
+	select REGMAP_MMIO
+	select CEC_CORE
+	select CEC_NOTIFIER
+	---help---
+	  This is a driver for Amlogic Meson G12A SoCs AO CEC interface.
+	  This driver if for the new AO-CEC module found in G12A SoCs,
+	  usually named AO_CEC_B in documentation.
+	  It uses the generic CEC framework interface.
+	  CEC bus is present in the HDMI connector and enables communication
+	  between compatible devices.
+
+config CEC_GPIO
+	tristate "Generic GPIO-based CEC driver"
+	depends on PREEMPTION || COMPILE_TEST
+	select CEC_CORE
+	select CEC_PIN
+	select CEC_NOTIFIER
+	select GPIOLIB
+	help
+	  This is a generic GPIO-based CEC driver.
+	  The CEC bus is present in the HDMI connector and enables communication
+	  between compatible devices.
+
+config CEC_SAMSUNG_S5P
+	tristate "Samsung S5P CEC driver"
+	depends on ARCH_EXYNOS || COMPILE_TEST
+	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.
+
+config CEC_STI
+	tristate "STMicroelectronics STiH4xx HDMI CEC driver"
+	depends on ARCH_STI || COMPILE_TEST
+	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.
+
+config CEC_STM32
+	tristate "STMicroelectronics STM32 HDMI CEC driver"
+	depends on ARCH_STM32 || COMPILE_TEST
+	select REGMAP
+	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.
+
+config CEC_TEGRA
+	tristate "Tegra HDMI CEC driver"
+	depends on ARCH_TEGRA || COMPILE_TEST
+	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.
+
+config CEC_SECO
+	tristate "SECO Boards HDMI CEC driver"
+	depends on (X86 || IA64) || COMPILE_TEST
+	select PCI
+	select DMI
+	select CEC_CORE
+	select CEC_NOTIFIER
+	help
+	  This is a driver for SECO Boards integrated CEC interface.
+	  Selecting it will enable support for this device.
+	  CEC bus is present in the HDMI connector and enables communication
+	  between compatible devices.
+
+config CEC_SECO_RC
+	bool "SECO Boards IR RC5 support"
+	depends on CEC_SECO
+	depends on RC_CORE=y || RC_CORE = CEC_SECO
+	help
+	  If you say yes here you will get support for the
+	  SECO Boards Consumer-IR in seco-cec driver.
+	  The embedded controller supports RC5 protocol only, default mapping
+	  is set to rc-hauppauge.
diff --git a/drivers/media/cec/platform/Makefile b/drivers/media/cec/platform/Makefile
new file mode 100644
index 000000000000..3a947159b25a
--- /dev/null
+++ b/drivers/media/cec/platform/Makefile
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the CEC platform device drivers.
+#
+
+# Please keep it in alphabetic order
+obj-$(CONFIG_CEC_CROS_EC)	+= cros-ec/
+obj-$(CONFIG_CEC_GPIO)		+= cec-gpio/
+obj-$(CONFIG_CEC_MESON_AO)	+= meson/
+obj-$(CONFIG_CEC_SAMSUNG_S5P)	+= s5p/
+obj-$(CONFIG_CEC_SECO)		+= seco/
+obj-$(CONFIG_CEC_STI)		+= sti/
+obj-$(CONFIG_CEC_TEGRA)		+= tegra/
+
diff --git a/drivers/media/cec/platform/cec-gpio/Makefile b/drivers/media/cec/platform/cec-gpio/Makefile
new file mode 100644
index 000000000000..a40c621dbd24
--- /dev/null
+++ b/drivers/media/cec/platform/cec-gpio/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_CEC_GPIO) += cec-gpio.o
diff --git a/drivers/media/cec/platform/cec-gpio/cec-gpio.c b/drivers/media/cec/platform/cec-gpio/cec-gpio.c
new file mode 100644
index 000000000000..42d2c2cd9a78
--- /dev/null
+++ b/drivers/media/cec/platform/cec-gpio/cec-gpio.c
@@ -0,0 +1,298 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/gpio/consumer.h>
+#include <media/cec-notifier.h>
+#include <media/cec-pin.h>
+
+struct cec_gpio {
+	struct cec_adapter	*adap;
+	struct cec_notifier	*notifier;
+	struct device		*dev;
+
+	struct gpio_desc	*cec_gpio;
+	int			cec_irq;
+	bool			cec_is_low;
+
+	struct gpio_desc	*hpd_gpio;
+	int			hpd_irq;
+	bool			hpd_is_high;
+	ktime_t			hpd_ts;
+
+	struct gpio_desc	*v5_gpio;
+	int			v5_irq;
+	bool			v5_is_high;
+	ktime_t			v5_ts;
+};
+
+static bool cec_gpio_read(struct cec_adapter *adap)
+{
+	struct cec_gpio *cec = cec_get_drvdata(adap);
+
+	if (cec->cec_is_low)
+		return false;
+	return gpiod_get_value(cec->cec_gpio);
+}
+
+static void cec_gpio_high(struct cec_adapter *adap)
+{
+	struct cec_gpio *cec = cec_get_drvdata(adap);
+
+	if (!cec->cec_is_low)
+		return;
+	cec->cec_is_low = false;
+	gpiod_set_value(cec->cec_gpio, 1);
+}
+
+static void cec_gpio_low(struct cec_adapter *adap)
+{
+	struct cec_gpio *cec = cec_get_drvdata(adap);
+
+	if (cec->cec_is_low)
+		return;
+	cec->cec_is_low = true;
+	gpiod_set_value(cec->cec_gpio, 0);
+}
+
+static irqreturn_t cec_hpd_gpio_irq_handler_thread(int irq, void *priv)
+{
+	struct cec_gpio *cec = priv;
+
+	cec_queue_pin_hpd_event(cec->adap, cec->hpd_is_high, cec->hpd_ts);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t cec_5v_gpio_irq_handler(int irq, void *priv)
+{
+	struct cec_gpio *cec = priv;
+	bool is_high = gpiod_get_value(cec->v5_gpio);
+
+	if (is_high == cec->v5_is_high)
+		return IRQ_HANDLED;
+	cec->v5_ts = ktime_get();
+	cec->v5_is_high = is_high;
+	return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t cec_5v_gpio_irq_handler_thread(int irq, void *priv)
+{
+	struct cec_gpio *cec = priv;
+
+	cec_queue_pin_5v_event(cec->adap, cec->v5_is_high, cec->v5_ts);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t cec_hpd_gpio_irq_handler(int irq, void *priv)
+{
+	struct cec_gpio *cec = priv;
+	bool is_high = gpiod_get_value(cec->hpd_gpio);
+
+	if (is_high == cec->hpd_is_high)
+		return IRQ_HANDLED;
+	cec->hpd_ts = ktime_get();
+	cec->hpd_is_high = is_high;
+	return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t cec_gpio_irq_handler(int irq, void *priv)
+{
+	struct cec_gpio *cec = priv;
+
+	cec_pin_changed(cec->adap, gpiod_get_value(cec->cec_gpio));
+	return IRQ_HANDLED;
+}
+
+static bool cec_gpio_enable_irq(struct cec_adapter *adap)
+{
+	struct cec_gpio *cec = cec_get_drvdata(adap);
+
+	enable_irq(cec->cec_irq);
+	return true;
+}
+
+static void cec_gpio_disable_irq(struct cec_adapter *adap)
+{
+	struct cec_gpio *cec = cec_get_drvdata(adap);
+
+	disable_irq(cec->cec_irq);
+}
+
+static void cec_gpio_status(struct cec_adapter *adap, struct seq_file *file)
+{
+	struct cec_gpio *cec = cec_get_drvdata(adap);
+
+	seq_printf(file, "mode: %s\n", cec->cec_is_low ? "low-drive" : "read");
+	seq_printf(file, "using irq: %d\n", cec->cec_irq);
+	if (cec->hpd_gpio)
+		seq_printf(file, "hpd: %s\n",
+			   cec->hpd_is_high ? "high" : "low");
+	if (cec->v5_gpio)
+		seq_printf(file, "5V: %s\n",
+			   cec->v5_is_high ? "high" : "low");
+}
+
+static int cec_gpio_read_hpd(struct cec_adapter *adap)
+{
+	struct cec_gpio *cec = cec_get_drvdata(adap);
+
+	if (!cec->hpd_gpio)
+		return -ENOTTY;
+	return gpiod_get_value(cec->hpd_gpio);
+}
+
+static int cec_gpio_read_5v(struct cec_adapter *adap)
+{
+	struct cec_gpio *cec = cec_get_drvdata(adap);
+
+	if (!cec->v5_gpio)
+		return -ENOTTY;
+	return gpiod_get_value(cec->v5_gpio);
+}
+
+static void cec_gpio_free(struct cec_adapter *adap)
+{
+	cec_gpio_disable_irq(adap);
+}
+
+static const struct cec_pin_ops cec_gpio_pin_ops = {
+	.read = cec_gpio_read,
+	.low = cec_gpio_low,
+	.high = cec_gpio_high,
+	.enable_irq = cec_gpio_enable_irq,
+	.disable_irq = cec_gpio_disable_irq,
+	.status = cec_gpio_status,
+	.free = cec_gpio_free,
+	.read_hpd = cec_gpio_read_hpd,
+	.read_5v = cec_gpio_read_5v,
+};
+
+static int cec_gpio_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device *hdmi_dev;
+	struct cec_gpio *cec;
+	u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_MONITOR_ALL | CEC_CAP_MONITOR_PIN;
+	int ret;
+
+	hdmi_dev = cec_notifier_parse_hdmi_phandle(dev);
+	if (PTR_ERR(hdmi_dev) == -EPROBE_DEFER)
+		return PTR_ERR(hdmi_dev);
+	if (IS_ERR(hdmi_dev))
+		caps |= CEC_CAP_PHYS_ADDR;
+
+	cec = devm_kzalloc(dev, sizeof(*cec), GFP_KERNEL);
+	if (!cec)
+		return -ENOMEM;
+
+	cec->dev = dev;
+
+	cec->cec_gpio = devm_gpiod_get(dev, "cec", GPIOD_OUT_HIGH_OPEN_DRAIN);
+	if (IS_ERR(cec->cec_gpio))
+		return PTR_ERR(cec->cec_gpio);
+	cec->cec_irq = gpiod_to_irq(cec->cec_gpio);
+
+	cec->hpd_gpio = devm_gpiod_get_optional(dev, "hpd", GPIOD_IN);
+	if (IS_ERR(cec->hpd_gpio))
+		return PTR_ERR(cec->hpd_gpio);
+
+	cec->v5_gpio = devm_gpiod_get_optional(dev, "v5", GPIOD_IN);
+	if (IS_ERR(cec->v5_gpio))
+		return PTR_ERR(cec->v5_gpio);
+
+	cec->adap = cec_pin_allocate_adapter(&cec_gpio_pin_ops,
+					     cec, pdev->name, caps);
+	if (IS_ERR(cec->adap))
+		return PTR_ERR(cec->adap);
+
+	ret = devm_request_irq(dev, cec->cec_irq, cec_gpio_irq_handler,
+			       IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+			       cec->adap->name, cec);
+	if (ret)
+		goto del_adap;
+
+	cec_gpio_disable_irq(cec->adap);
+
+	if (cec->hpd_gpio) {
+		cec->hpd_irq = gpiod_to_irq(cec->hpd_gpio);
+		ret = devm_request_threaded_irq(dev, cec->hpd_irq,
+			cec_hpd_gpio_irq_handler,
+			cec_hpd_gpio_irq_handler_thread,
+			IRQF_ONESHOT |
+			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+			"hpd-gpio", cec);
+		if (ret)
+			goto del_adap;
+	}
+
+	if (cec->v5_gpio) {
+		cec->v5_irq = gpiod_to_irq(cec->v5_gpio);
+		ret = devm_request_threaded_irq(dev, cec->v5_irq,
+			cec_5v_gpio_irq_handler,
+			cec_5v_gpio_irq_handler_thread,
+			IRQF_ONESHOT |
+			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+			"v5-gpio", cec);
+		if (ret)
+			goto del_adap;
+	}
+
+	if (!IS_ERR(hdmi_dev)) {
+		cec->notifier = cec_notifier_cec_adap_register(hdmi_dev, NULL,
+							       cec->adap);
+		if (!cec->notifier) {
+			ret = -ENOMEM;
+			goto del_adap;
+		}
+	}
+
+	ret = cec_register_adapter(cec->adap, &pdev->dev);
+	if (ret)
+		goto unreg_notifier;
+
+	platform_set_drvdata(pdev, cec);
+	return 0;
+
+unreg_notifier:
+	cec_notifier_cec_adap_unregister(cec->notifier, cec->adap);
+del_adap:
+	cec_delete_adapter(cec->adap);
+	return ret;
+}
+
+static int cec_gpio_remove(struct platform_device *pdev)
+{
+	struct cec_gpio *cec = platform_get_drvdata(pdev);
+
+	cec_notifier_cec_adap_unregister(cec->notifier, cec->adap);
+	cec_unregister_adapter(cec->adap);
+	return 0;
+}
+
+static const struct of_device_id cec_gpio_match[] = {
+	{
+		.compatible	= "cec-gpio",
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, cec_gpio_match);
+
+static struct platform_driver cec_gpio_pdrv = {
+	.probe	= cec_gpio_probe,
+	.remove = cec_gpio_remove,
+	.driver = {
+		.name		= "cec-gpio",
+		.of_match_table	= cec_gpio_match,
+	},
+};
+
+module_platform_driver(cec_gpio_pdrv);
+
+MODULE_AUTHOR("Hans Verkuil <hans.verkuil@cisco.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("CEC GPIO driver");
diff --git a/drivers/media/cec/platform/cros-ec/Makefile b/drivers/media/cec/platform/cros-ec/Makefile
new file mode 100644
index 000000000000..d7e3511078ef
--- /dev/null
+++ b/drivers/media/cec/platform/cros-ec/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_CEC_CROS_EC) += cros-ec-cec.o
diff --git a/drivers/media/cec/platform/cros-ec/cros-ec-cec.c b/drivers/media/cec/platform/cros-ec/cros-ec-cec.c
new file mode 100644
index 000000000000..0e7e2772f08f
--- /dev/null
+++ b/drivers/media/cec/platform/cros-ec/cros-ec-cec.c
@@ -0,0 +1,359 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * CEC driver for ChromeOS Embedded Controller
+ *
+ * Copyright (c) 2018 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/dmi.h>
+#include <linux/pci.h>
+#include <linux/cec.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/platform_data/cros_ec_commands.h>
+#include <linux/platform_data/cros_ec_proto.h>
+#include <media/cec.h>
+#include <media/cec-notifier.h>
+
+#define DRV_NAME	"cros-ec-cec"
+
+/**
+ * struct cros_ec_cec - Driver data for EC CEC
+ *
+ * @cros_ec: Pointer to EC device
+ * @notifier: Notifier info for responding to EC events
+ * @adap: CEC adapter
+ * @notify: CEC notifier pointer
+ * @rx_msg: storage for a received message
+ */
+struct cros_ec_cec {
+	struct cros_ec_device *cros_ec;
+	struct notifier_block notifier;
+	struct cec_adapter *adap;
+	struct cec_notifier *notify;
+	struct cec_msg rx_msg;
+};
+
+static void handle_cec_message(struct cros_ec_cec *cros_ec_cec)
+{
+	struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec;
+	uint8_t *cec_message = cros_ec->event_data.data.cec_message;
+	unsigned int len = cros_ec->event_size;
+
+	cros_ec_cec->rx_msg.len = len;
+	memcpy(cros_ec_cec->rx_msg.msg, cec_message, len);
+
+	cec_received_msg(cros_ec_cec->adap, &cros_ec_cec->rx_msg);
+}
+
+static void handle_cec_event(struct cros_ec_cec *cros_ec_cec)
+{
+	struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec;
+	uint32_t events = cros_ec->event_data.data.cec_events;
+
+	if (events & EC_MKBP_CEC_SEND_OK)
+		cec_transmit_attempt_done(cros_ec_cec->adap,
+					  CEC_TX_STATUS_OK);
+
+	/* FW takes care of all retries, tell core to avoid more retries */
+	if (events & EC_MKBP_CEC_SEND_FAILED)
+		cec_transmit_attempt_done(cros_ec_cec->adap,
+					  CEC_TX_STATUS_MAX_RETRIES |
+					  CEC_TX_STATUS_NACK);
+}
+
+static int cros_ec_cec_event(struct notifier_block *nb,
+			     unsigned long queued_during_suspend,
+			     void *_notify)
+{
+	struct cros_ec_cec *cros_ec_cec;
+	struct cros_ec_device *cros_ec;
+
+	cros_ec_cec = container_of(nb, struct cros_ec_cec, notifier);
+	cros_ec = cros_ec_cec->cros_ec;
+
+	if (cros_ec->event_data.event_type == EC_MKBP_EVENT_CEC_EVENT) {
+		handle_cec_event(cros_ec_cec);
+		return NOTIFY_OK;
+	}
+
+	if (cros_ec->event_data.event_type == EC_MKBP_EVENT_CEC_MESSAGE) {
+		handle_cec_message(cros_ec_cec);
+		return NOTIFY_OK;
+	}
+
+	return NOTIFY_DONE;
+}
+
+static int cros_ec_cec_set_log_addr(struct cec_adapter *adap, u8 logical_addr)
+{
+	struct cros_ec_cec *cros_ec_cec = adap->priv;
+	struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec;
+	struct {
+		struct cros_ec_command msg;
+		struct ec_params_cec_set data;
+	} __packed msg = {};
+	int ret;
+
+	msg.msg.command = EC_CMD_CEC_SET;
+	msg.msg.outsize = sizeof(msg.data);
+	msg.data.cmd = CEC_CMD_LOGICAL_ADDRESS;
+	msg.data.val = logical_addr;
+
+	ret = cros_ec_cmd_xfer_status(cros_ec, &msg.msg);
+	if (ret < 0) {
+		dev_err(cros_ec->dev,
+			"error setting CEC logical address on EC: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int cros_ec_cec_transmit(struct cec_adapter *adap, u8 attempts,
+				u32 signal_free_time, struct cec_msg *cec_msg)
+{
+	struct cros_ec_cec *cros_ec_cec = adap->priv;
+	struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec;
+	struct {
+		struct cros_ec_command msg;
+		struct ec_params_cec_write data;
+	} __packed msg = {};
+	int ret;
+
+	msg.msg.command = EC_CMD_CEC_WRITE_MSG;
+	msg.msg.outsize = cec_msg->len;
+	memcpy(msg.data.msg, cec_msg->msg, cec_msg->len);
+
+	ret = cros_ec_cmd_xfer_status(cros_ec, &msg.msg);
+	if (ret < 0) {
+		dev_err(cros_ec->dev,
+			"error writing CEC msg on EC: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int cros_ec_cec_adap_enable(struct cec_adapter *adap, bool enable)
+{
+	struct cros_ec_cec *cros_ec_cec = adap->priv;
+	struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec;
+	struct {
+		struct cros_ec_command msg;
+		struct ec_params_cec_set data;
+	} __packed msg = {};
+	int ret;
+
+	msg.msg.command = EC_CMD_CEC_SET;
+	msg.msg.outsize = sizeof(msg.data);
+	msg.data.cmd = CEC_CMD_ENABLE;
+	msg.data.val = enable;
+
+	ret = cros_ec_cmd_xfer_status(cros_ec, &msg.msg);
+	if (ret < 0) {
+		dev_err(cros_ec->dev,
+			"error %sabling CEC on EC: %d\n",
+			(enable ? "en" : "dis"), ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct cec_adap_ops cros_ec_cec_ops = {
+	.adap_enable = cros_ec_cec_adap_enable,
+	.adap_log_addr = cros_ec_cec_set_log_addr,
+	.adap_transmit = cros_ec_cec_transmit,
+};
+
+#ifdef CONFIG_PM_SLEEP
+static int cros_ec_cec_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct cros_ec_cec *cros_ec_cec = dev_get_drvdata(&pdev->dev);
+
+	if (device_may_wakeup(dev))
+		enable_irq_wake(cros_ec_cec->cros_ec->irq);
+
+	return 0;
+}
+
+static int cros_ec_cec_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct cros_ec_cec *cros_ec_cec = dev_get_drvdata(&pdev->dev);
+
+	if (device_may_wakeup(dev))
+		disable_irq_wake(cros_ec_cec->cros_ec->irq);
+
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(cros_ec_cec_pm_ops,
+	cros_ec_cec_suspend, cros_ec_cec_resume);
+
+#if IS_ENABLED(CONFIG_PCI) && IS_ENABLED(CONFIG_DMI)
+
+/*
+ * The Firmware only handles a single CEC interface tied to a single HDMI
+ * connector we specify along with the DRM device name handling the HDMI output
+ */
+
+struct cec_dmi_match {
+	const char *sys_vendor;
+	const char *product_name;
+	const char *devname;
+	const char *conn;
+};
+
+static const struct cec_dmi_match cec_dmi_match_table[] = {
+	/* Google Fizz */
+	{ "Google", "Fizz", "0000:00:02.0", "Port B" },
+};
+
+static struct device *cros_ec_cec_find_hdmi_dev(struct device *dev,
+						const char **conn)
+{
+	int i;
+
+	for (i = 0 ; i < ARRAY_SIZE(cec_dmi_match_table) ; ++i) {
+		const struct cec_dmi_match *m = &cec_dmi_match_table[i];
+
+		if (dmi_match(DMI_SYS_VENDOR, m->sys_vendor) &&
+		    dmi_match(DMI_PRODUCT_NAME, m->product_name)) {
+			struct device *d;
+
+			/* Find the device, bail out if not yet registered */
+			d = bus_find_device_by_name(&pci_bus_type, NULL,
+						    m->devname);
+			if (!d)
+				return ERR_PTR(-EPROBE_DEFER);
+			put_device(d);
+			*conn = m->conn;
+			return d;
+		}
+	}
+
+	/* Hardware support must be added in the cec_dmi_match_table */
+	dev_warn(dev, "CEC notifier not configured for this hardware\n");
+
+	return ERR_PTR(-ENODEV);
+}
+
+#else
+
+static struct device *cros_ec_cec_find_hdmi_dev(struct device *dev,
+						const char **conn)
+{
+	return ERR_PTR(-ENODEV);
+}
+
+#endif
+
+static int cros_ec_cec_probe(struct platform_device *pdev)
+{
+	struct cros_ec_dev *ec_dev = dev_get_drvdata(pdev->dev.parent);
+	struct cros_ec_device *cros_ec = ec_dev->ec_dev;
+	struct cros_ec_cec *cros_ec_cec;
+	struct device *hdmi_dev;
+	const char *conn = NULL;
+	int ret;
+
+	hdmi_dev = cros_ec_cec_find_hdmi_dev(&pdev->dev, &conn);
+	if (IS_ERR(hdmi_dev))
+		return PTR_ERR(hdmi_dev);
+
+	cros_ec_cec = devm_kzalloc(&pdev->dev, sizeof(*cros_ec_cec),
+				   GFP_KERNEL);
+	if (!cros_ec_cec)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, cros_ec_cec);
+	cros_ec_cec->cros_ec = cros_ec;
+
+	ret = device_init_wakeup(&pdev->dev, 1);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to initialize wakeup\n");
+		return ret;
+	}
+
+	cros_ec_cec->adap = cec_allocate_adapter(&cros_ec_cec_ops, cros_ec_cec,
+						 DRV_NAME,
+						 CEC_CAP_DEFAULTS |
+						 CEC_CAP_CONNECTOR_INFO, 1);
+	if (IS_ERR(cros_ec_cec->adap))
+		return PTR_ERR(cros_ec_cec->adap);
+
+	cros_ec_cec->notify = cec_notifier_cec_adap_register(hdmi_dev, conn,
+							     cros_ec_cec->adap);
+	if (!cros_ec_cec->notify) {
+		ret = -ENOMEM;
+		goto out_probe_adapter;
+	}
+
+	/* Get CEC events from the EC. */
+	cros_ec_cec->notifier.notifier_call = cros_ec_cec_event;
+	ret = blocking_notifier_chain_register(&cros_ec->event_notifier,
+					       &cros_ec_cec->notifier);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to register notifier\n");
+		goto out_probe_notify;
+	}
+
+	ret = cec_register_adapter(cros_ec_cec->adap, &pdev->dev);
+	if (ret < 0)
+		goto out_probe_notify;
+
+	return 0;
+
+out_probe_notify:
+	cec_notifier_cec_adap_unregister(cros_ec_cec->notify,
+					 cros_ec_cec->adap);
+out_probe_adapter:
+	cec_delete_adapter(cros_ec_cec->adap);
+	return ret;
+}
+
+static int cros_ec_cec_remove(struct platform_device *pdev)
+{
+	struct cros_ec_cec *cros_ec_cec = platform_get_drvdata(pdev);
+	struct device *dev = &pdev->dev;
+	int ret;
+
+	ret = blocking_notifier_chain_unregister(
+			&cros_ec_cec->cros_ec->event_notifier,
+			&cros_ec_cec->notifier);
+
+	if (ret) {
+		dev_err(dev, "failed to unregister notifier\n");
+		return ret;
+	}
+
+	cec_notifier_cec_adap_unregister(cros_ec_cec->notify,
+					 cros_ec_cec->adap);
+	cec_unregister_adapter(cros_ec_cec->adap);
+
+	return 0;
+}
+
+static struct platform_driver cros_ec_cec_driver = {
+	.probe = cros_ec_cec_probe,
+	.remove  = cros_ec_cec_remove,
+	.driver = {
+		.name = DRV_NAME,
+		.pm = &cros_ec_cec_pm_ops,
+	},
+};
+
+module_platform_driver(cros_ec_cec_driver);
+
+MODULE_DESCRIPTION("CEC driver for ChromeOS ECs");
+MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/drivers/media/cec/platform/meson/Makefile b/drivers/media/cec/platform/meson/Makefile
new file mode 100644
index 000000000000..34fc5d444d0e
--- /dev/null
+++ b/drivers/media/cec/platform/meson/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_CEC_MESON_AO)	+= ao-cec.o
+obj-$(CONFIG_CEC_MESON_G12A_AO)	+= ao-cec-g12a.o
diff --git a/drivers/media/cec/platform/meson/ao-cec-g12a.c b/drivers/media/cec/platform/meson/ao-cec-g12a.c
new file mode 100644
index 000000000000..891533060d49
--- /dev/null
+++ b/drivers/media/cec/platform/meson/ao-cec-g12a.c
@@ -0,0 +1,796 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Driver for Amlogic Meson AO CEC G12A Controller
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved
+ * Copyright (C) 2019 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/reset.h>
+#include <linux/slab.h>
+#include <linux/regmap.h>
+#include <media/cec.h>
+#include <media/cec-notifier.h>
+#include <linux/clk-provider.h>
+
+/* CEC Registers */
+
+#define CECB_CLK_CNTL_REG0		0x00
+
+#define CECB_CLK_CNTL_N1		GENMASK(11, 0)
+#define CECB_CLK_CNTL_N2		GENMASK(23, 12)
+#define CECB_CLK_CNTL_DUAL_EN		BIT(28)
+#define CECB_CLK_CNTL_OUTPUT_EN		BIT(30)
+#define CECB_CLK_CNTL_INPUT_EN		BIT(31)
+
+#define CECB_CLK_CNTL_REG1		0x04
+
+#define CECB_CLK_CNTL_M1		GENMASK(11, 0)
+#define CECB_CLK_CNTL_M2		GENMASK(23, 12)
+#define CECB_CLK_CNTL_BYPASS_EN		BIT(24)
+
+/*
+ * [14:12] Filter_del. For glitch-filtering CEC line, ignore signal
+ *       change pulse width < filter_del * T(filter_tick) * 3.
+ * [9:8] Filter_tick_sel: Select which periodical pulse for
+ *       glitch-filtering CEC line signal.
+ *  - 0=Use T(xtal)*3 = 125ns;
+ *  - 1=Use once-per-1us pulse;
+ *  - 2=Use once-per-10us pulse;
+ *  - 3=Use once-per-100us pulse.
+ * [3]   Sysclk_en. 0=Disable system clock; 1=Enable system clock.
+ * [2:1] cntl_clk
+ *  - 0 = Disable clk (Power-off mode)
+ *  - 1 = Enable gated clock (Normal mode)
+ *  - 2 = Enable free-run clk (Debug mode)
+ * [0] SW_RESET 1=Apply reset; 0=No reset.
+ */
+#define CECB_GEN_CNTL_REG		0x08
+
+#define CECB_GEN_CNTL_RESET		BIT(0)
+#define CECB_GEN_CNTL_CLK_DISABLE	0
+#define CECB_GEN_CNTL_CLK_ENABLE	1
+#define CECB_GEN_CNTL_CLK_ENABLE_DBG	2
+#define CECB_GEN_CNTL_CLK_CTRL_MASK	GENMASK(2, 1)
+#define CECB_GEN_CNTL_SYS_CLK_EN	BIT(3)
+#define CECB_GEN_CNTL_FILTER_TICK_125NS	0
+#define CECB_GEN_CNTL_FILTER_TICK_1US	1
+#define CECB_GEN_CNTL_FILTER_TICK_10US	2
+#define CECB_GEN_CNTL_FILTER_TICK_100US	3
+#define CECB_GEN_CNTL_FILTER_TICK_SEL	GENMASK(9, 8)
+#define CECB_GEN_CNTL_FILTER_DEL	GENMASK(14, 12)
+
+/*
+ * [7:0] cec_reg_addr
+ * [15:8] cec_reg_wrdata
+ * [16] cec_reg_wr
+ *  - 0 = Read
+ *  - 1 = Write
+ * [31:24] cec_reg_rddata
+ */
+#define CECB_RW_REG			0x0c
+
+#define CECB_RW_ADDR			GENMASK(7, 0)
+#define CECB_RW_WR_DATA			GENMASK(15, 8)
+#define CECB_RW_WRITE_EN		BIT(16)
+#define CECB_RW_BUS_BUSY		BIT(23)
+#define CECB_RW_RD_DATA			GENMASK(31, 24)
+
+/*
+ * [0] DONE Interrupt
+ * [1] End Of Message Interrupt
+ * [2] Not Acknowlegde Interrupt
+ * [3] Arbitration Loss Interrupt
+ * [4] Initiator Error Interrupt
+ * [5] Follower Error Interrupt
+ * [6] Wake-Up Interrupt
+ */
+#define CECB_INTR_MASKN_REG		0x10
+#define CECB_INTR_CLR_REG		0x14
+#define CECB_INTR_STAT_REG		0x18
+
+#define CECB_INTR_DONE			BIT(0)
+#define CECB_INTR_EOM			BIT(1)
+#define CECB_INTR_NACK			BIT(2)
+#define CECB_INTR_ARB_LOSS		BIT(3)
+#define CECB_INTR_INITIATOR_ERR		BIT(4)
+#define CECB_INTR_FOLLOWER_ERR		BIT(5)
+#define CECB_INTR_WAKE_UP		BIT(6)
+
+/* CEC Commands */
+
+#define CECB_CTRL		0x00
+
+#define CECB_CTRL_SEND		BIT(0)
+#define CECB_CTRL_TYPE		GENMASK(2, 1)
+#define CECB_CTRL_TYPE_RETRY	0
+#define CECB_CTRL_TYPE_NEW	1
+#define CECB_CTRL_TYPE_NEXT	2
+
+#define CECB_CTRL2		0x01
+
+#define CECB_CTRL2_RISE_DEL_MAX	GENMASK(4, 0)
+
+#define CECB_INTR_MASK		0x02
+#define CECB_LADD_LOW		0x05
+#define CECB_LADD_HIGH		0x06
+#define CECB_TX_CNT		0x07
+#define CECB_RX_CNT		0x08
+#define CECB_STAT0		0x09
+#define CECB_TX_DATA00		0x10
+#define CECB_TX_DATA01		0x11
+#define CECB_TX_DATA02		0x12
+#define CECB_TX_DATA03		0x13
+#define CECB_TX_DATA04		0x14
+#define CECB_TX_DATA05		0x15
+#define CECB_TX_DATA06		0x16
+#define CECB_TX_DATA07		0x17
+#define CECB_TX_DATA08		0x18
+#define CECB_TX_DATA09		0x19
+#define CECB_TX_DATA10		0x1A
+#define CECB_TX_DATA11		0x1B
+#define CECB_TX_DATA12		0x1C
+#define CECB_TX_DATA13		0x1D
+#define CECB_TX_DATA14		0x1E
+#define CECB_TX_DATA15		0x1F
+#define CECB_RX_DATA00		0x20
+#define CECB_RX_DATA01		0x21
+#define CECB_RX_DATA02		0x22
+#define CECB_RX_DATA03		0x23
+#define CECB_RX_DATA04		0x24
+#define CECB_RX_DATA05		0x25
+#define CECB_RX_DATA06		0x26
+#define CECB_RX_DATA07		0x27
+#define CECB_RX_DATA08		0x28
+#define CECB_RX_DATA09		0x29
+#define CECB_RX_DATA10		0x2A
+#define CECB_RX_DATA11		0x2B
+#define CECB_RX_DATA12		0x2C
+#define CECB_RX_DATA13		0x2D
+#define CECB_RX_DATA14		0x2E
+#define CECB_RX_DATA15		0x2F
+#define CECB_LOCK_BUF		0x30
+
+#define CECB_LOCK_BUF_EN	BIT(0)
+
+#define CECB_WAKEUPCTRL		0x31
+
+struct meson_ao_cec_g12a_data {
+	/* Setup the internal CECB_CTRL2 register */
+	bool				ctrl2_setup;
+};
+
+struct meson_ao_cec_g12a_device {
+	struct platform_device		*pdev;
+	struct regmap			*regmap;
+	struct regmap			*regmap_cec;
+	spinlock_t			cec_reg_lock;
+	struct cec_notifier		*notify;
+	struct cec_adapter		*adap;
+	struct cec_msg			rx_msg;
+	struct clk			*oscin;
+	struct clk			*core;
+	const struct meson_ao_cec_g12a_data *data;
+};
+
+static const struct regmap_config meson_ao_cec_g12a_regmap_conf = {
+	.reg_bits = 8,
+	.val_bits = 32,
+	.reg_stride = 4,
+	.max_register = CECB_INTR_STAT_REG,
+};
+
+/*
+ * The AO-CECB embeds a dual/divider to generate a more precise
+ * 32,768KHz clock for CEC core clock.
+ *                      ______   ______
+ *                     |      | |      |
+ *         ______      | Div1 |-| Cnt1 |       ______
+ *        |      |    /|______| |______|\     |      |
+ * Xtal-->| Gate |---|  ______   ______  X-X--| Gate |-->
+ *        |______| |  \|      | |      |/  |  |______|
+ *                 |   | Div2 |-| Cnt2 |   |
+ *                 |   |______| |______|   |
+ *                 |_______________________|
+ *
+ * The dividing can be switched to single or dual, with a counter
+ * for each divider to set when the switching is done.
+ * The entire dividing mechanism can be also bypassed.
+ */
+
+struct meson_ao_cec_g12a_dualdiv_clk {
+	struct clk_hw hw;
+	struct regmap *regmap;
+};
+
+#define hw_to_meson_ao_cec_g12a_dualdiv_clk(_hw)			\
+	container_of(_hw, struct meson_ao_cec_g12a_dualdiv_clk, hw)	\
+
+static unsigned long
+meson_ao_cec_g12a_dualdiv_clk_recalc_rate(struct clk_hw *hw,
+					  unsigned long parent_rate)
+{
+	struct meson_ao_cec_g12a_dualdiv_clk *dualdiv_clk =
+		hw_to_meson_ao_cec_g12a_dualdiv_clk(hw);
+	unsigned long n1;
+	u32 reg0, reg1;
+
+	regmap_read(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0, &reg0);
+	regmap_read(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0, &reg1);
+
+	if (reg1 & CECB_CLK_CNTL_BYPASS_EN)
+		return parent_rate;
+
+	if (reg0 & CECB_CLK_CNTL_DUAL_EN) {
+		unsigned long n2, m1, m2, f1, f2, p1, p2;
+
+		n1 = FIELD_GET(CECB_CLK_CNTL_N1, reg0) + 1;
+		n2 = FIELD_GET(CECB_CLK_CNTL_N2, reg0) + 1;
+
+		m1 = FIELD_GET(CECB_CLK_CNTL_M1, reg1) + 1;
+		m2 = FIELD_GET(CECB_CLK_CNTL_M1, reg1) + 1;
+
+		f1 = DIV_ROUND_CLOSEST(parent_rate, n1);
+		f2 = DIV_ROUND_CLOSEST(parent_rate, n2);
+
+		p1 = DIV_ROUND_CLOSEST(100000000 * m1, f1 * (m1 + m2));
+		p2 = DIV_ROUND_CLOSEST(100000000 * m2, f2 * (m1 + m2));
+
+		return DIV_ROUND_UP(100000000, p1 + p2);
+	}
+
+	n1 = FIELD_GET(CECB_CLK_CNTL_N1, reg0) + 1;
+
+	return DIV_ROUND_CLOSEST(parent_rate, n1);
+}
+
+static int meson_ao_cec_g12a_dualdiv_clk_enable(struct clk_hw *hw)
+{
+	struct meson_ao_cec_g12a_dualdiv_clk *dualdiv_clk =
+		hw_to_meson_ao_cec_g12a_dualdiv_clk(hw);
+
+
+	/* Disable Input & Output */
+	regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0,
+			   CECB_CLK_CNTL_INPUT_EN | CECB_CLK_CNTL_OUTPUT_EN,
+			   0);
+
+	/* Set N1 & N2 */
+	regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0,
+			   CECB_CLK_CNTL_N1,
+			   FIELD_PREP(CECB_CLK_CNTL_N1, 733 - 1));
+
+	regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0,
+			   CECB_CLK_CNTL_N2,
+			   FIELD_PREP(CECB_CLK_CNTL_N2, 732 - 1));
+
+	/* Set M1 & M2 */
+	regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG1,
+			   CECB_CLK_CNTL_M1,
+			   FIELD_PREP(CECB_CLK_CNTL_M1, 8 - 1));
+
+	regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG1,
+			   CECB_CLK_CNTL_M2,
+			   FIELD_PREP(CECB_CLK_CNTL_M2, 11 - 1));
+
+	/* Enable Dual divisor */
+	regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0,
+			   CECB_CLK_CNTL_DUAL_EN, CECB_CLK_CNTL_DUAL_EN);
+
+	/* Disable divisor bypass */
+	regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG1,
+			   CECB_CLK_CNTL_BYPASS_EN, 0);
+
+	/* Enable Input & Output */
+	regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0,
+			   CECB_CLK_CNTL_INPUT_EN | CECB_CLK_CNTL_OUTPUT_EN,
+			   CECB_CLK_CNTL_INPUT_EN | CECB_CLK_CNTL_OUTPUT_EN);
+
+	return 0;
+}
+
+static void meson_ao_cec_g12a_dualdiv_clk_disable(struct clk_hw *hw)
+{
+	struct meson_ao_cec_g12a_dualdiv_clk *dualdiv_clk =
+		hw_to_meson_ao_cec_g12a_dualdiv_clk(hw);
+
+	regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0,
+			   CECB_CLK_CNTL_INPUT_EN | CECB_CLK_CNTL_OUTPUT_EN,
+			   0);
+}
+
+static int meson_ao_cec_g12a_dualdiv_clk_is_enabled(struct clk_hw *hw)
+{
+	struct meson_ao_cec_g12a_dualdiv_clk *dualdiv_clk =
+		hw_to_meson_ao_cec_g12a_dualdiv_clk(hw);
+	int val;
+
+	regmap_read(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0, &val);
+
+	return !!(val & (CECB_CLK_CNTL_INPUT_EN | CECB_CLK_CNTL_OUTPUT_EN));
+}
+
+static const struct clk_ops meson_ao_cec_g12a_dualdiv_clk_ops = {
+	.recalc_rate	= meson_ao_cec_g12a_dualdiv_clk_recalc_rate,
+	.is_enabled	= meson_ao_cec_g12a_dualdiv_clk_is_enabled,
+	.enable		= meson_ao_cec_g12a_dualdiv_clk_enable,
+	.disable	= meson_ao_cec_g12a_dualdiv_clk_disable,
+};
+
+static int meson_ao_cec_g12a_setup_clk(struct meson_ao_cec_g12a_device *ao_cec)
+{
+	struct meson_ao_cec_g12a_dualdiv_clk *dualdiv_clk;
+	struct device *dev = &ao_cec->pdev->dev;
+	struct clk_init_data init;
+	const char *parent_name;
+	struct clk *clk;
+	char *name;
+
+	dualdiv_clk = devm_kzalloc(dev, sizeof(*dualdiv_clk), GFP_KERNEL);
+	if (!dualdiv_clk)
+		return -ENOMEM;
+
+	name = kasprintf(GFP_KERNEL, "%s#dualdiv_clk", dev_name(dev));
+	if (!name)
+		return -ENOMEM;
+
+	parent_name = __clk_get_name(ao_cec->oscin);
+
+	init.name = name;
+	init.ops = &meson_ao_cec_g12a_dualdiv_clk_ops;
+	init.flags = 0;
+	init.parent_names = &parent_name;
+	init.num_parents = 1;
+	dualdiv_clk->regmap = ao_cec->regmap;
+	dualdiv_clk->hw.init = &init;
+
+	clk = devm_clk_register(dev, &dualdiv_clk->hw);
+	kfree(name);
+	if (IS_ERR(clk)) {
+		dev_err(dev, "failed to register clock\n");
+		return PTR_ERR(clk);
+	}
+
+	ao_cec->core = clk;
+
+	return 0;
+}
+
+static int meson_ao_cec_g12a_read(void *context, unsigned int addr,
+				  unsigned int *data)
+{
+	struct meson_ao_cec_g12a_device *ao_cec = context;
+	u32 reg = FIELD_PREP(CECB_RW_ADDR, addr);
+	int ret = 0;
+
+	ret = regmap_write(ao_cec->regmap, CECB_RW_REG, reg);
+	if (ret)
+		return ret;
+
+	ret = regmap_read_poll_timeout(ao_cec->regmap, CECB_RW_REG, reg,
+				       !(reg & CECB_RW_BUS_BUSY),
+				       5, 1000);
+	if (ret)
+		return ret;
+
+	ret = regmap_read(ao_cec->regmap, CECB_RW_REG, &reg);
+
+	*data = FIELD_GET(CECB_RW_RD_DATA, reg);
+
+	return ret;
+}
+
+static int meson_ao_cec_g12a_write(void *context, unsigned int addr,
+				   unsigned int data)
+{
+	struct meson_ao_cec_g12a_device *ao_cec = context;
+	u32 reg = FIELD_PREP(CECB_RW_ADDR, addr) |
+		  FIELD_PREP(CECB_RW_WR_DATA, data) |
+		  CECB_RW_WRITE_EN;
+
+	return regmap_write(ao_cec->regmap, CECB_RW_REG, reg);
+}
+
+static const struct regmap_config meson_ao_cec_g12a_cec_regmap_conf = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.reg_read = meson_ao_cec_g12a_read,
+	.reg_write = meson_ao_cec_g12a_write,
+	.max_register = 0xffff,
+};
+
+static inline void
+meson_ao_cec_g12a_irq_setup(struct meson_ao_cec_g12a_device *ao_cec,
+			    bool enable)
+{
+	u32 cfg = CECB_INTR_DONE | CECB_INTR_EOM | CECB_INTR_NACK |
+		  CECB_INTR_ARB_LOSS | CECB_INTR_INITIATOR_ERR |
+		  CECB_INTR_FOLLOWER_ERR;
+
+	regmap_write(ao_cec->regmap, CECB_INTR_MASKN_REG,
+		     enable ? cfg : 0);
+}
+
+static void meson_ao_cec_g12a_irq_rx(struct meson_ao_cec_g12a_device *ao_cec)
+{
+	int i, ret = 0;
+	u32 val;
+
+	ret = regmap_read(ao_cec->regmap_cec, CECB_RX_CNT, &val);
+
+	ao_cec->rx_msg.len = val;
+	if (ao_cec->rx_msg.len > CEC_MAX_MSG_SIZE)
+		ao_cec->rx_msg.len = CEC_MAX_MSG_SIZE;
+
+	for (i = 0; i < ao_cec->rx_msg.len; i++) {
+		ret |= regmap_read(ao_cec->regmap_cec,
+				   CECB_RX_DATA00 + i, &val);
+
+		ao_cec->rx_msg.msg[i] = val & 0xff;
+	}
+
+	ret |= regmap_write(ao_cec->regmap_cec, CECB_LOCK_BUF, 0);
+	if (ret)
+		return;
+
+	cec_received_msg(ao_cec->adap, &ao_cec->rx_msg);
+}
+
+static irqreturn_t meson_ao_cec_g12a_irq(int irq, void *data)
+{
+	struct meson_ao_cec_g12a_device *ao_cec = data;
+	u32 stat;
+
+	regmap_read(ao_cec->regmap, CECB_INTR_STAT_REG, &stat);
+	if (stat)
+		return IRQ_WAKE_THREAD;
+
+	return IRQ_NONE;
+}
+
+static irqreturn_t meson_ao_cec_g12a_irq_thread(int irq, void *data)
+{
+	struct meson_ao_cec_g12a_device *ao_cec = data;
+	u32 stat;
+
+	regmap_read(ao_cec->regmap, CECB_INTR_STAT_REG, &stat);
+	regmap_write(ao_cec->regmap, CECB_INTR_CLR_REG, stat);
+
+	if (stat & CECB_INTR_DONE)
+		cec_transmit_attempt_done(ao_cec->adap, CEC_TX_STATUS_OK);
+
+	if (stat & CECB_INTR_EOM)
+		meson_ao_cec_g12a_irq_rx(ao_cec);
+
+	if (stat & CECB_INTR_NACK)
+		cec_transmit_attempt_done(ao_cec->adap, CEC_TX_STATUS_NACK);
+
+	if (stat & CECB_INTR_ARB_LOSS) {
+		regmap_write(ao_cec->regmap_cec, CECB_TX_CNT, 0);
+		regmap_update_bits(ao_cec->regmap_cec, CECB_CTRL,
+				   CECB_CTRL_SEND | CECB_CTRL_TYPE, 0);
+		cec_transmit_attempt_done(ao_cec->adap, CEC_TX_STATUS_ARB_LOST);
+	}
+
+	/* Initiator reports an error on the CEC bus */
+	if (stat & CECB_INTR_INITIATOR_ERR)
+		cec_transmit_attempt_done(ao_cec->adap, CEC_TX_STATUS_ERROR);
+
+	/* Follower reports a receive error, just reset RX buffer */
+	if (stat & CECB_INTR_FOLLOWER_ERR)
+		regmap_write(ao_cec->regmap_cec, CECB_LOCK_BUF, 0);
+
+	return IRQ_HANDLED;
+}
+
+static int
+meson_ao_cec_g12a_set_log_addr(struct cec_adapter *adap, u8 logical_addr)
+{
+	struct meson_ao_cec_g12a_device *ao_cec = adap->priv;
+	int ret = 0;
+
+	if (logical_addr == CEC_LOG_ADDR_INVALID) {
+		/* Assume this will allways succeed */
+		regmap_write(ao_cec->regmap_cec, CECB_LADD_LOW, 0);
+		regmap_write(ao_cec->regmap_cec, CECB_LADD_HIGH, 0);
+
+		return 0;
+	} else if (logical_addr < 8) {
+		ret = regmap_update_bits(ao_cec->regmap_cec, CECB_LADD_LOW,
+					 BIT(logical_addr),
+					 BIT(logical_addr));
+	} else {
+		ret = regmap_update_bits(ao_cec->regmap_cec, CECB_LADD_HIGH,
+					 BIT(logical_addr - 8),
+					 BIT(logical_addr - 8));
+	}
+
+	/* Always set Broadcast/Unregistered 15 address */
+	ret |= regmap_update_bits(ao_cec->regmap_cec, CECB_LADD_HIGH,
+				  BIT(CEC_LOG_ADDR_UNREGISTERED - 8),
+				  BIT(CEC_LOG_ADDR_UNREGISTERED - 8));
+
+	return ret ? -EIO : 0;
+}
+
+static int meson_ao_cec_g12a_transmit(struct cec_adapter *adap, u8 attempts,
+				 u32 signal_free_time, struct cec_msg *msg)
+{
+	struct meson_ao_cec_g12a_device *ao_cec = adap->priv;
+	unsigned int type;
+	int ret = 0;
+	u32 val;
+	int i;
+
+	/* Check if RX is in progress */
+	ret = regmap_read(ao_cec->regmap_cec, CECB_LOCK_BUF, &val);
+	if (ret)
+		return ret;
+	if (val & CECB_LOCK_BUF_EN)
+		return -EBUSY;
+
+	/* Check if TX Busy */
+	ret = regmap_read(ao_cec->regmap_cec, CECB_CTRL, &val);
+	if (ret)
+		return ret;
+	if (val & CECB_CTRL_SEND)
+		return -EBUSY;
+
+	switch (signal_free_time) {
+	case CEC_SIGNAL_FREE_TIME_RETRY:
+		type = CECB_CTRL_TYPE_RETRY;
+		break;
+	case CEC_SIGNAL_FREE_TIME_NEXT_XFER:
+		type = CECB_CTRL_TYPE_NEXT;
+		break;
+	case CEC_SIGNAL_FREE_TIME_NEW_INITIATOR:
+	default:
+		type = CECB_CTRL_TYPE_NEW;
+		break;
+	}
+
+	for (i = 0; i < msg->len; i++)
+		ret |= regmap_write(ao_cec->regmap_cec, CECB_TX_DATA00 + i,
+				    msg->msg[i]);
+
+	ret |= regmap_write(ao_cec->regmap_cec, CECB_TX_CNT, msg->len);
+	if (ret)
+		return -EIO;
+
+	ret = regmap_update_bits(ao_cec->regmap_cec, CECB_CTRL,
+				 CECB_CTRL_SEND |
+				 CECB_CTRL_TYPE,
+				 CECB_CTRL_SEND |
+				 FIELD_PREP(CECB_CTRL_TYPE, type));
+
+	return ret;
+}
+
+static int meson_ao_cec_g12a_adap_enable(struct cec_adapter *adap, bool enable)
+{
+	struct meson_ao_cec_g12a_device *ao_cec = adap->priv;
+
+	meson_ao_cec_g12a_irq_setup(ao_cec, false);
+
+	regmap_update_bits(ao_cec->regmap, CECB_GEN_CNTL_REG,
+			   CECB_GEN_CNTL_RESET, CECB_GEN_CNTL_RESET);
+
+	if (!enable)
+		return 0;
+
+	/* Setup Filter */
+	regmap_update_bits(ao_cec->regmap, CECB_GEN_CNTL_REG,
+			   CECB_GEN_CNTL_FILTER_TICK_SEL |
+			   CECB_GEN_CNTL_FILTER_DEL,
+			   FIELD_PREP(CECB_GEN_CNTL_FILTER_TICK_SEL,
+				      CECB_GEN_CNTL_FILTER_TICK_1US) |
+			   FIELD_PREP(CECB_GEN_CNTL_FILTER_DEL, 7));
+
+	/* Enable System Clock */
+	regmap_update_bits(ao_cec->regmap, CECB_GEN_CNTL_REG,
+			   CECB_GEN_CNTL_SYS_CLK_EN,
+			   CECB_GEN_CNTL_SYS_CLK_EN);
+
+	/* Enable gated clock (Normal mode). */
+	regmap_update_bits(ao_cec->regmap, CECB_GEN_CNTL_REG,
+			   CECB_GEN_CNTL_CLK_CTRL_MASK,
+			    FIELD_PREP(CECB_GEN_CNTL_CLK_CTRL_MASK,
+				       CECB_GEN_CNTL_CLK_ENABLE));
+
+	/* Release Reset */
+	regmap_update_bits(ao_cec->regmap, CECB_GEN_CNTL_REG,
+			   CECB_GEN_CNTL_RESET, 0);
+
+	if (ao_cec->data->ctrl2_setup)
+		regmap_write(ao_cec->regmap_cec, CECB_CTRL2,
+			     FIELD_PREP(CECB_CTRL2_RISE_DEL_MAX, 2));
+
+	meson_ao_cec_g12a_irq_setup(ao_cec, true);
+
+	return 0;
+}
+
+static const struct cec_adap_ops meson_ao_cec_g12a_ops = {
+	.adap_enable = meson_ao_cec_g12a_adap_enable,
+	.adap_log_addr = meson_ao_cec_g12a_set_log_addr,
+	.adap_transmit = meson_ao_cec_g12a_transmit,
+};
+
+static int meson_ao_cec_g12a_probe(struct platform_device *pdev)
+{
+	struct meson_ao_cec_g12a_device *ao_cec;
+	struct device *hdmi_dev;
+	struct resource *res;
+	void __iomem *base;
+	int ret, irq;
+
+	hdmi_dev = cec_notifier_parse_hdmi_phandle(&pdev->dev);
+	if (IS_ERR(hdmi_dev))
+		return PTR_ERR(hdmi_dev);
+
+	ao_cec = devm_kzalloc(&pdev->dev, sizeof(*ao_cec), GFP_KERNEL);
+	if (!ao_cec)
+		return -ENOMEM;
+
+	ao_cec->data = of_device_get_match_data(&pdev->dev);
+	if (!ao_cec->data) {
+		dev_err(&pdev->dev, "failed to get match data\n");
+		return -ENODEV;
+	}
+
+	spin_lock_init(&ao_cec->cec_reg_lock);
+	ao_cec->pdev = pdev;
+
+	ao_cec->adap = cec_allocate_adapter(&meson_ao_cec_g12a_ops, ao_cec,
+					    "meson_g12a_ao_cec",
+					    CEC_CAP_DEFAULTS |
+					    CEC_CAP_CONNECTOR_INFO,
+					    CEC_MAX_LOG_ADDRS);
+	if (IS_ERR(ao_cec->adap))
+		return PTR_ERR(ao_cec->adap);
+
+	ao_cec->adap->owner = THIS_MODULE;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base)) {
+		ret = PTR_ERR(base);
+		goto out_probe_adapter;
+	}
+
+	ao_cec->regmap = devm_regmap_init_mmio(&pdev->dev, base,
+					       &meson_ao_cec_g12a_regmap_conf);
+	if (IS_ERR(ao_cec->regmap)) {
+		ret = PTR_ERR(ao_cec->regmap);
+		goto out_probe_adapter;
+	}
+
+	ao_cec->regmap_cec = devm_regmap_init(&pdev->dev, NULL, ao_cec,
+					   &meson_ao_cec_g12a_cec_regmap_conf);
+	if (IS_ERR(ao_cec->regmap_cec)) {
+		ret = PTR_ERR(ao_cec->regmap_cec);
+		goto out_probe_adapter;
+	}
+
+	irq = platform_get_irq(pdev, 0);
+	ret = devm_request_threaded_irq(&pdev->dev, irq,
+					meson_ao_cec_g12a_irq,
+					meson_ao_cec_g12a_irq_thread,
+					0, NULL, ao_cec);
+	if (ret) {
+		dev_err(&pdev->dev, "irq request failed\n");
+		goto out_probe_adapter;
+	}
+
+	ao_cec->oscin = devm_clk_get(&pdev->dev, "oscin");
+	if (IS_ERR(ao_cec->oscin)) {
+		dev_err(&pdev->dev, "oscin clock request failed\n");
+		ret = PTR_ERR(ao_cec->oscin);
+		goto out_probe_adapter;
+	}
+
+	ret = meson_ao_cec_g12a_setup_clk(ao_cec);
+	if (ret)
+		goto out_probe_adapter;
+
+	ret = clk_prepare_enable(ao_cec->core);
+	if (ret) {
+		dev_err(&pdev->dev, "core clock enable failed\n");
+		goto out_probe_adapter;
+	}
+
+	device_reset_optional(&pdev->dev);
+
+	platform_set_drvdata(pdev, ao_cec);
+
+	ao_cec->notify = cec_notifier_cec_adap_register(hdmi_dev, NULL,
+							ao_cec->adap);
+	if (!ao_cec->notify) {
+		ret = -ENOMEM;
+		goto out_probe_core_clk;
+	}
+
+	ret = cec_register_adapter(ao_cec->adap, &pdev->dev);
+	if (ret < 0)
+		goto out_probe_notify;
+
+	/* Setup Hardware */
+	regmap_write(ao_cec->regmap, CECB_GEN_CNTL_REG, CECB_GEN_CNTL_RESET);
+
+	return 0;
+
+out_probe_notify:
+	cec_notifier_cec_adap_unregister(ao_cec->notify, ao_cec->adap);
+
+out_probe_core_clk:
+	clk_disable_unprepare(ao_cec->core);
+
+out_probe_adapter:
+	cec_delete_adapter(ao_cec->adap);
+
+	dev_err(&pdev->dev, "CEC controller registration failed\n");
+
+	return ret;
+}
+
+static int meson_ao_cec_g12a_remove(struct platform_device *pdev)
+{
+	struct meson_ao_cec_g12a_device *ao_cec = platform_get_drvdata(pdev);
+
+	clk_disable_unprepare(ao_cec->core);
+
+	cec_notifier_cec_adap_unregister(ao_cec->notify, ao_cec->adap);
+
+	cec_unregister_adapter(ao_cec->adap);
+
+	return 0;
+}
+
+static const struct meson_ao_cec_g12a_data ao_cec_g12a_data = {
+	.ctrl2_setup = false,
+};
+
+static const struct meson_ao_cec_g12a_data ao_cec_sm1_data = {
+	.ctrl2_setup = true,
+};
+
+static const struct of_device_id meson_ao_cec_g12a_of_match[] = {
+	{
+		.compatible = "amlogic,meson-g12a-ao-cec",
+		.data = &ao_cec_g12a_data,
+	},
+	{
+		.compatible = "amlogic,meson-sm1-ao-cec",
+		.data = &ao_cec_sm1_data,
+	},
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, meson_ao_cec_g12a_of_match);
+
+static struct platform_driver meson_ao_cec_g12a_driver = {
+	.probe   = meson_ao_cec_g12a_probe,
+	.remove  = meson_ao_cec_g12a_remove,
+	.driver  = {
+		.name = "meson-ao-cec-g12a",
+		.of_match_table = of_match_ptr(meson_ao_cec_g12a_of_match),
+	},
+};
+
+module_platform_driver(meson_ao_cec_g12a_driver);
+
+MODULE_DESCRIPTION("Meson AO CEC G12A Controller driver");
+MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/cec/platform/meson/ao-cec.c b/drivers/media/cec/platform/meson/ao-cec.c
new file mode 100644
index 000000000000..09aff82c3773
--- /dev/null
+++ b/drivers/media/cec/platform/meson/ao-cec.c
@@ -0,0 +1,732 @@
+/*
+ * Driver for Amlogic Meson AO CEC Controller
+ *
+ * Copyright (C) 2015 Amlogic, Inc. All rights reserved
+ * Copyright (C) 2017 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/reset.h>
+#include <media/cec.h>
+#include <media/cec-notifier.h>
+
+/* CEC Registers */
+
+/*
+ * [2:1] cntl_clk
+ *  - 0 = Disable clk (Power-off mode)
+ *  - 1 = Enable gated clock (Normal mode)
+ *  - 2 = Enable free-run clk (Debug mode)
+ */
+#define CEC_GEN_CNTL_REG		0x00
+
+#define CEC_GEN_CNTL_RESET		BIT(0)
+#define CEC_GEN_CNTL_CLK_DISABLE	0
+#define CEC_GEN_CNTL_CLK_ENABLE		1
+#define CEC_GEN_CNTL_CLK_ENABLE_DBG	2
+#define CEC_GEN_CNTL_CLK_CTRL_MASK	GENMASK(2, 1)
+
+/*
+ * [7:0] cec_reg_addr
+ * [15:8] cec_reg_wrdata
+ * [16] cec_reg_wr
+ *  - 0 = Read
+ *  - 1 = Write
+ * [23] bus free
+ * [31:24] cec_reg_rddata
+ */
+#define CEC_RW_REG			0x04
+
+#define CEC_RW_ADDR			GENMASK(7, 0)
+#define CEC_RW_WR_DATA			GENMASK(15, 8)
+#define CEC_RW_WRITE_EN			BIT(16)
+#define CEC_RW_BUS_BUSY			BIT(23)
+#define CEC_RW_RD_DATA			GENMASK(31, 24)
+
+/*
+ * [1] tx intr
+ * [2] rx intr
+ */
+#define CEC_INTR_MASKN_REG		0x08
+#define CEC_INTR_CLR_REG		0x0c
+#define CEC_INTR_STAT_REG		0x10
+
+#define CEC_INTR_TX			BIT(1)
+#define CEC_INTR_RX			BIT(2)
+
+/* CEC Commands */
+
+#define CEC_TX_MSG_0_HEADER		0x00
+#define CEC_TX_MSG_1_OPCODE		0x01
+#define CEC_TX_MSG_2_OP1		0x02
+#define CEC_TX_MSG_3_OP2		0x03
+#define CEC_TX_MSG_4_OP3		0x04
+#define CEC_TX_MSG_5_OP4		0x05
+#define CEC_TX_MSG_6_OP5		0x06
+#define CEC_TX_MSG_7_OP6		0x07
+#define CEC_TX_MSG_8_OP7		0x08
+#define CEC_TX_MSG_9_OP8		0x09
+#define CEC_TX_MSG_A_OP9		0x0A
+#define CEC_TX_MSG_B_OP10		0x0B
+#define CEC_TX_MSG_C_OP11		0x0C
+#define CEC_TX_MSG_D_OP12		0x0D
+#define CEC_TX_MSG_E_OP13		0x0E
+#define CEC_TX_MSG_F_OP14		0x0F
+#define CEC_TX_MSG_LENGTH		0x10
+#define CEC_TX_MSG_CMD			0x11
+#define CEC_TX_WRITE_BUF		0x12
+#define CEC_TX_CLEAR_BUF		0x13
+#define CEC_RX_MSG_CMD			0x14
+#define CEC_RX_CLEAR_BUF		0x15
+#define CEC_LOGICAL_ADDR0		0x16
+#define CEC_LOGICAL_ADDR1		0x17
+#define CEC_LOGICAL_ADDR2		0x18
+#define CEC_LOGICAL_ADDR3		0x19
+#define CEC_LOGICAL_ADDR4		0x1A
+#define CEC_CLOCK_DIV_H			0x1B
+#define CEC_CLOCK_DIV_L			0x1C
+#define CEC_QUIESCENT_25MS_BIT7_0	0x20
+#define CEC_QUIESCENT_25MS_BIT11_8	0x21
+#define CEC_STARTBITMINL2H_3MS5_BIT7_0	0x22
+#define CEC_STARTBITMINL2H_3MS5_BIT8	0x23
+#define CEC_STARTBITMAXL2H_3MS9_BIT7_0	0x24
+#define CEC_STARTBITMAXL2H_3MS9_BIT8	0x25
+#define CEC_STARTBITMINH_0MS6_BIT7_0	0x26
+#define CEC_STARTBITMINH_0MS6_BIT8	0x27
+#define CEC_STARTBITMAXH_1MS0_BIT7_0	0x28
+#define CEC_STARTBITMAXH_1MS0_BIT8	0x29
+#define CEC_STARTBITMINTOT_4MS3_BIT7_0	0x2A
+#define CEC_STARTBITMINTOT_4MS3_BIT9_8	0x2B
+#define CEC_STARTBITMAXTOT_4MS7_BIT7_0	0x2C
+#define CEC_STARTBITMAXTOT_4MS7_BIT9_8	0x2D
+#define CEC_LOGIC1MINL2H_0MS4_BIT7_0	0x2E
+#define CEC_LOGIC1MINL2H_0MS4_BIT8	0x2F
+#define CEC_LOGIC1MAXL2H_0MS8_BIT7_0	0x30
+#define CEC_LOGIC1MAXL2H_0MS8_BIT8	0x31
+#define CEC_LOGIC0MINL2H_1MS3_BIT7_0	0x32
+#define CEC_LOGIC0MINL2H_1MS3_BIT8	0x33
+#define CEC_LOGIC0MAXL2H_1MS7_BIT7_0	0x34
+#define CEC_LOGIC0MAXL2H_1MS7_BIT8	0x35
+#define CEC_LOGICMINTOTAL_2MS05_BIT7_0	0x36
+#define CEC_LOGICMINTOTAL_2MS05_BIT9_8	0x37
+#define CEC_LOGICMAXHIGH_2MS8_BIT7_0	0x38
+#define CEC_LOGICMAXHIGH_2MS8_BIT8	0x39
+#define CEC_LOGICERRLOW_3MS4_BIT7_0	0x3A
+#define CEC_LOGICERRLOW_3MS4_BIT8	0x3B
+#define CEC_NOMSMPPOINT_1MS05		0x3C
+#define CEC_DELCNTR_LOGICERR		0x3E
+#define CEC_TXTIME_17MS_BIT7_0		0x40
+#define CEC_TXTIME_17MS_BIT10_8		0x41
+#define CEC_TXTIME_2BIT_BIT7_0		0x42
+#define CEC_TXTIME_2BIT_BIT10_8		0x43
+#define CEC_TXTIME_4BIT_BIT7_0		0x44
+#define CEC_TXTIME_4BIT_BIT10_8		0x45
+#define CEC_STARTBITNOML2H_3MS7_BIT7_0	0x46
+#define CEC_STARTBITNOML2H_3MS7_BIT8	0x47
+#define CEC_STARTBITNOMH_0MS8_BIT7_0	0x48
+#define CEC_STARTBITNOMH_0MS8_BIT8	0x49
+#define CEC_LOGIC1NOML2H_0MS6_BIT7_0	0x4A
+#define CEC_LOGIC1NOML2H_0MS6_BIT8	0x4B
+#define CEC_LOGIC0NOML2H_1MS5_BIT7_0	0x4C
+#define CEC_LOGIC0NOML2H_1MS5_BIT8	0x4D
+#define CEC_LOGIC1NOMH_1MS8_BIT7_0	0x4E
+#define CEC_LOGIC1NOMH_1MS8_BIT8	0x4F
+#define CEC_LOGIC0NOMH_0MS9_BIT7_0	0x50
+#define CEC_LOGIC0NOMH_0MS9_BIT8	0x51
+#define CEC_LOGICERRLOW_3MS6_BIT7_0	0x52
+#define CEC_LOGICERRLOW_3MS6_BIT8	0x53
+#define CEC_CHKCONTENTION_0MS1		0x54
+#define CEC_PREPARENXTBIT_0MS05_BIT7_0	0x56
+#define CEC_PREPARENXTBIT_0MS05_BIT8	0x57
+#define CEC_NOMSMPACKPOINT_0MS45	0x58
+#define CEC_ACK0NOML2H_1MS5_BIT7_0	0x5A
+#define CEC_ACK0NOML2H_1MS5_BIT8	0x5B
+#define CEC_BUGFIX_DISABLE_0		0x60
+#define CEC_BUGFIX_DISABLE_1		0x61
+#define CEC_RX_MSG_0_HEADER		0x80
+#define CEC_RX_MSG_1_OPCODE		0x81
+#define CEC_RX_MSG_2_OP1		0x82
+#define CEC_RX_MSG_3_OP2		0x83
+#define CEC_RX_MSG_4_OP3		0x84
+#define CEC_RX_MSG_5_OP4		0x85
+#define CEC_RX_MSG_6_OP5		0x86
+#define CEC_RX_MSG_7_OP6		0x87
+#define CEC_RX_MSG_8_OP7		0x88
+#define CEC_RX_MSG_9_OP8		0x89
+#define CEC_RX_MSG_A_OP9		0x8A
+#define CEC_RX_MSG_B_OP10		0x8B
+#define CEC_RX_MSG_C_OP11		0x8C
+#define CEC_RX_MSG_D_OP12		0x8D
+#define CEC_RX_MSG_E_OP13		0x8E
+#define CEC_RX_MSG_F_OP14		0x8F
+#define CEC_RX_MSG_LENGTH		0x90
+#define CEC_RX_MSG_STATUS		0x91
+#define CEC_RX_NUM_MSG			0x92
+#define CEC_TX_MSG_STATUS		0x93
+#define CEC_TX_NUM_MSG			0x94
+
+
+/* CEC_TX_MSG_CMD definition */
+#define TX_NO_OP	0  /* No transaction */
+#define TX_REQ_CURRENT	1  /* Transmit earliest message in buffer */
+#define TX_ABORT	2  /* Abort transmitting earliest message */
+#define TX_REQ_NEXT	3  /* Overwrite earliest msg, transmit next */
+
+/* tx_msg_status definition */
+#define TX_IDLE		0  /* No transaction */
+#define TX_BUSY		1  /* Transmitter is busy */
+#define TX_DONE		2  /* Message successfully transmitted */
+#define TX_ERROR	3  /* Message transmitted with error */
+
+/* rx_msg_cmd */
+#define RX_NO_OP	0  /* No transaction */
+#define RX_ACK_CURRENT	1  /* Read earliest message in buffer */
+#define RX_DISABLE	2  /* Disable receiving latest message */
+#define RX_ACK_NEXT	3  /* Clear earliest msg, read next */
+
+/* rx_msg_status */
+#define RX_IDLE		0  /* No transaction */
+#define RX_BUSY		1  /* Receiver is busy */
+#define RX_DONE		2  /* Message has been received successfully */
+#define RX_ERROR	3  /* Message has been received with error */
+
+/* RX_CLEAR_BUF options */
+#define CLEAR_START	1
+#define CLEAR_STOP	0
+
+/* CEC_LOGICAL_ADDRx options */
+#define LOGICAL_ADDR_MASK	0xf
+#define LOGICAL_ADDR_VALID	BIT(4)
+#define LOGICAL_ADDR_DISABLE	0
+
+#define CEC_CLK_RATE		32768
+
+struct meson_ao_cec_device {
+	struct platform_device		*pdev;
+	void __iomem			*base;
+	struct clk			*core;
+	spinlock_t			cec_reg_lock;
+	struct cec_notifier		*notify;
+	struct cec_adapter		*adap;
+	struct cec_msg			rx_msg;
+};
+
+#define writel_bits_relaxed(mask, val, addr) \
+	writel_relaxed((readl_relaxed(addr) & ~(mask)) | (val), addr)
+
+static inline int meson_ao_cec_wait_busy(struct meson_ao_cec_device *ao_cec)
+{
+	ktime_t timeout = ktime_add_us(ktime_get(), 5000);
+
+	while (readl_relaxed(ao_cec->base + CEC_RW_REG) & CEC_RW_BUS_BUSY) {
+		if (ktime_compare(ktime_get(), timeout) > 0)
+			return -ETIMEDOUT;
+	}
+
+	return 0;
+}
+
+static void meson_ao_cec_read(struct meson_ao_cec_device *ao_cec,
+			     unsigned long address, u8 *data,
+			     int *res)
+{
+	unsigned long flags;
+	u32 reg = FIELD_PREP(CEC_RW_ADDR, address);
+	int ret = 0;
+
+	if (res && *res)
+		return;
+
+	spin_lock_irqsave(&ao_cec->cec_reg_lock, flags);
+
+	ret = meson_ao_cec_wait_busy(ao_cec);
+	if (ret)
+		goto read_out;
+
+	writel_relaxed(reg, ao_cec->base + CEC_RW_REG);
+
+	ret = meson_ao_cec_wait_busy(ao_cec);
+	if (ret)
+		goto read_out;
+
+	*data = FIELD_GET(CEC_RW_RD_DATA,
+			  readl_relaxed(ao_cec->base + CEC_RW_REG));
+
+read_out:
+	spin_unlock_irqrestore(&ao_cec->cec_reg_lock, flags);
+
+	if (res)
+		*res = ret;
+}
+
+static void meson_ao_cec_write(struct meson_ao_cec_device *ao_cec,
+			       unsigned long address, u8 data,
+			       int *res)
+{
+	unsigned long flags;
+	u32 reg = FIELD_PREP(CEC_RW_ADDR, address) |
+		  FIELD_PREP(CEC_RW_WR_DATA, data) |
+		  CEC_RW_WRITE_EN;
+	int ret = 0;
+
+	if (res && *res)
+		return;
+
+	spin_lock_irqsave(&ao_cec->cec_reg_lock, flags);
+
+	ret = meson_ao_cec_wait_busy(ao_cec);
+	if (ret)
+		goto write_out;
+
+	writel_relaxed(reg, ao_cec->base + CEC_RW_REG);
+
+write_out:
+	spin_unlock_irqrestore(&ao_cec->cec_reg_lock, flags);
+
+	if (res)
+		*res = ret;
+}
+
+static inline void meson_ao_cec_irq_setup(struct meson_ao_cec_device *ao_cec,
+				      bool enable)
+{
+	u32 cfg = CEC_INTR_TX | CEC_INTR_RX;
+
+	writel_bits_relaxed(cfg, enable ? cfg : 0,
+			    ao_cec->base + CEC_INTR_MASKN_REG);
+}
+
+static inline int meson_ao_cec_clear(struct meson_ao_cec_device *ao_cec)
+{
+	int ret = 0;
+
+	meson_ao_cec_write(ao_cec, CEC_RX_MSG_CMD, RX_DISABLE, &ret);
+	meson_ao_cec_write(ao_cec, CEC_TX_MSG_CMD, TX_ABORT, &ret);
+	meson_ao_cec_write(ao_cec, CEC_RX_CLEAR_BUF, 1, &ret);
+	meson_ao_cec_write(ao_cec, CEC_TX_CLEAR_BUF, 1, &ret);
+	if (ret)
+		return ret;
+
+	udelay(100);
+
+	meson_ao_cec_write(ao_cec, CEC_RX_CLEAR_BUF, 0, &ret);
+	meson_ao_cec_write(ao_cec, CEC_TX_CLEAR_BUF, 0, &ret);
+	if (ret)
+		return ret;
+
+	udelay(100);
+
+	meson_ao_cec_write(ao_cec, CEC_RX_MSG_CMD, RX_NO_OP, &ret);
+	meson_ao_cec_write(ao_cec, CEC_TX_MSG_CMD, TX_NO_OP, &ret);
+
+	return ret;
+}
+
+static int meson_ao_cec_arbit_bit_time_set(struct meson_ao_cec_device *ao_cec,
+					   unsigned int bit_set,
+					   unsigned int time_set)
+{
+	int ret = 0;
+
+	switch (bit_set) {
+	case CEC_SIGNAL_FREE_TIME_RETRY:
+		meson_ao_cec_write(ao_cec, CEC_TXTIME_4BIT_BIT7_0,
+				   time_set & 0xff, &ret);
+		meson_ao_cec_write(ao_cec, CEC_TXTIME_4BIT_BIT10_8,
+				   (time_set >> 8) & 0x7, &ret);
+		break;
+
+	case CEC_SIGNAL_FREE_TIME_NEW_INITIATOR:
+		meson_ao_cec_write(ao_cec, CEC_TXTIME_2BIT_BIT7_0,
+				   time_set & 0xff, &ret);
+		meson_ao_cec_write(ao_cec, CEC_TXTIME_2BIT_BIT10_8,
+				   (time_set >> 8) & 0x7, &ret);
+		break;
+
+	case CEC_SIGNAL_FREE_TIME_NEXT_XFER:
+		meson_ao_cec_write(ao_cec, CEC_TXTIME_17MS_BIT7_0,
+				   time_set & 0xff, &ret);
+		meson_ao_cec_write(ao_cec, CEC_TXTIME_17MS_BIT10_8,
+				   (time_set >> 8) & 0x7, &ret);
+		break;
+	}
+
+	return ret;
+}
+
+static irqreturn_t meson_ao_cec_irq(int irq, void *data)
+{
+	struct meson_ao_cec_device *ao_cec = data;
+	u32 stat = readl_relaxed(ao_cec->base + CEC_INTR_STAT_REG);
+
+	if (stat)
+		return IRQ_WAKE_THREAD;
+
+	return IRQ_NONE;
+}
+
+static void meson_ao_cec_irq_tx(struct meson_ao_cec_device *ao_cec)
+{
+	unsigned long tx_status = 0;
+	u8 stat;
+	int ret = 0;
+
+	meson_ao_cec_read(ao_cec, CEC_TX_MSG_STATUS, &stat, &ret);
+	if (ret)
+		goto tx_reg_err;
+
+	switch (stat) {
+	case TX_DONE:
+		tx_status = CEC_TX_STATUS_OK;
+		break;
+
+	case TX_BUSY:
+		tx_status = CEC_TX_STATUS_ARB_LOST;
+		break;
+
+	case TX_IDLE:
+		tx_status = CEC_TX_STATUS_LOW_DRIVE;
+		break;
+
+	case TX_ERROR:
+	default:
+		tx_status = CEC_TX_STATUS_NACK;
+		break;
+	}
+
+	/* Clear Interruption */
+	writel_relaxed(CEC_INTR_TX, ao_cec->base + CEC_INTR_CLR_REG);
+
+	/* Stop TX */
+	meson_ao_cec_write(ao_cec, CEC_TX_MSG_CMD, TX_NO_OP, &ret);
+	if (ret)
+		goto tx_reg_err;
+
+	cec_transmit_attempt_done(ao_cec->adap, tx_status);
+	return;
+
+tx_reg_err:
+	cec_transmit_attempt_done(ao_cec->adap, CEC_TX_STATUS_ERROR);
+}
+
+static void meson_ao_cec_irq_rx(struct meson_ao_cec_device *ao_cec)
+{
+	int i, ret = 0;
+	u8 reg;
+
+	meson_ao_cec_read(ao_cec, CEC_RX_MSG_STATUS, &reg, &ret);
+	if (reg != RX_DONE)
+		goto rx_out;
+
+	meson_ao_cec_read(ao_cec, CEC_RX_NUM_MSG, &reg, &ret);
+	if (reg != 1)
+		goto rx_out;
+
+	meson_ao_cec_read(ao_cec, CEC_RX_MSG_LENGTH, &reg, &ret);
+
+	ao_cec->rx_msg.len = reg + 1;
+	if (ao_cec->rx_msg.len > CEC_MAX_MSG_SIZE)
+		ao_cec->rx_msg.len = CEC_MAX_MSG_SIZE;
+
+	for (i = 0; i < ao_cec->rx_msg.len; i++) {
+		u8 byte;
+
+		meson_ao_cec_read(ao_cec, CEC_RX_MSG_0_HEADER + i, &byte, &ret);
+
+		ao_cec->rx_msg.msg[i] = byte;
+	}
+
+	if (ret)
+		goto rx_out;
+
+	cec_received_msg(ao_cec->adap, &ao_cec->rx_msg);
+
+rx_out:
+	/* Clear Interruption */
+	writel_relaxed(CEC_INTR_RX, ao_cec->base + CEC_INTR_CLR_REG);
+
+	/* Ack RX message */
+	meson_ao_cec_write(ao_cec, CEC_RX_MSG_CMD, RX_ACK_CURRENT, &ret);
+	meson_ao_cec_write(ao_cec, CEC_RX_MSG_CMD, RX_NO_OP, &ret);
+
+	/* Clear RX buffer */
+	meson_ao_cec_write(ao_cec, CEC_RX_CLEAR_BUF, CLEAR_START, &ret);
+	meson_ao_cec_write(ao_cec, CEC_RX_CLEAR_BUF, CLEAR_STOP, &ret);
+}
+
+static irqreturn_t meson_ao_cec_irq_thread(int irq, void *data)
+{
+	struct meson_ao_cec_device *ao_cec = data;
+	u32 stat = readl_relaxed(ao_cec->base + CEC_INTR_STAT_REG);
+
+	if (stat & CEC_INTR_TX)
+		meson_ao_cec_irq_tx(ao_cec);
+
+	meson_ao_cec_irq_rx(ao_cec);
+
+	return IRQ_HANDLED;
+}
+
+static int meson_ao_cec_set_log_addr(struct cec_adapter *adap, u8 logical_addr)
+{
+	struct meson_ao_cec_device *ao_cec = adap->priv;
+	int ret = 0;
+
+	meson_ao_cec_write(ao_cec, CEC_LOGICAL_ADDR0,
+			   LOGICAL_ADDR_DISABLE, &ret);
+	if (ret)
+		return ret;
+
+	ret = meson_ao_cec_clear(ao_cec);
+	if (ret)
+		return ret;
+
+	if (logical_addr == CEC_LOG_ADDR_INVALID)
+		return 0;
+
+	meson_ao_cec_write(ao_cec, CEC_LOGICAL_ADDR0,
+			   logical_addr & LOGICAL_ADDR_MASK, &ret);
+	if (ret)
+		return ret;
+
+	udelay(100);
+
+	meson_ao_cec_write(ao_cec, CEC_LOGICAL_ADDR0,
+			   (logical_addr & LOGICAL_ADDR_MASK) |
+			   LOGICAL_ADDR_VALID, &ret);
+
+	return ret;
+}
+
+static int meson_ao_cec_transmit(struct cec_adapter *adap, u8 attempts,
+				 u32 signal_free_time, struct cec_msg *msg)
+{
+	struct meson_ao_cec_device *ao_cec = adap->priv;
+	int i, ret = 0;
+	u8 reg;
+
+	meson_ao_cec_read(ao_cec, CEC_TX_MSG_STATUS, &reg, &ret);
+	if (ret)
+		return ret;
+
+	if (reg == TX_BUSY) {
+		dev_dbg(&ao_cec->pdev->dev, "%s: busy TX: aborting\n",
+			__func__);
+		meson_ao_cec_write(ao_cec, CEC_TX_MSG_CMD, TX_ABORT, &ret);
+	}
+
+	for (i = 0; i < msg->len; i++) {
+		meson_ao_cec_write(ao_cec, CEC_TX_MSG_0_HEADER + i,
+				   msg->msg[i], &ret);
+	}
+
+	meson_ao_cec_write(ao_cec, CEC_TX_MSG_LENGTH, msg->len - 1, &ret);
+	meson_ao_cec_write(ao_cec, CEC_TX_MSG_CMD, TX_REQ_CURRENT, &ret);
+
+	return ret;
+}
+
+static int meson_ao_cec_adap_enable(struct cec_adapter *adap, bool enable)
+{
+	struct meson_ao_cec_device *ao_cec = adap->priv;
+	int ret;
+
+	meson_ao_cec_irq_setup(ao_cec, false);
+
+	writel_bits_relaxed(CEC_GEN_CNTL_RESET, CEC_GEN_CNTL_RESET,
+			    ao_cec->base + CEC_GEN_CNTL_REG);
+
+	if (!enable)
+		return 0;
+
+	/* Enable gated clock (Normal mode). */
+	writel_bits_relaxed(CEC_GEN_CNTL_CLK_CTRL_MASK,
+			    FIELD_PREP(CEC_GEN_CNTL_CLK_CTRL_MASK,
+				       CEC_GEN_CNTL_CLK_ENABLE),
+			    ao_cec->base + CEC_GEN_CNTL_REG);
+
+	udelay(100);
+
+	/* Release Reset */
+	writel_bits_relaxed(CEC_GEN_CNTL_RESET, 0,
+			    ao_cec->base + CEC_GEN_CNTL_REG);
+
+	/* Clear buffers */
+	ret = meson_ao_cec_clear(ao_cec);
+	if (ret)
+		return ret;
+
+	/* CEC arbitration 3/5/7 bit time set. */
+	ret = meson_ao_cec_arbit_bit_time_set(ao_cec,
+					CEC_SIGNAL_FREE_TIME_RETRY,
+					0x118);
+	if (ret)
+		return ret;
+	ret = meson_ao_cec_arbit_bit_time_set(ao_cec,
+					CEC_SIGNAL_FREE_TIME_NEW_INITIATOR,
+					0x000);
+	if (ret)
+		return ret;
+	ret = meson_ao_cec_arbit_bit_time_set(ao_cec,
+					CEC_SIGNAL_FREE_TIME_NEXT_XFER,
+					0x2aa);
+	if (ret)
+		return ret;
+
+	meson_ao_cec_irq_setup(ao_cec, true);
+
+	return 0;
+}
+
+static const struct cec_adap_ops meson_ao_cec_ops = {
+	.adap_enable = meson_ao_cec_adap_enable,
+	.adap_log_addr = meson_ao_cec_set_log_addr,
+	.adap_transmit = meson_ao_cec_transmit,
+};
+
+static int meson_ao_cec_probe(struct platform_device *pdev)
+{
+	struct meson_ao_cec_device *ao_cec;
+	struct device *hdmi_dev;
+	struct resource *res;
+	int ret, irq;
+
+	hdmi_dev = cec_notifier_parse_hdmi_phandle(&pdev->dev);
+
+	if (IS_ERR(hdmi_dev))
+		return PTR_ERR(hdmi_dev);
+
+	ao_cec = devm_kzalloc(&pdev->dev, sizeof(*ao_cec), GFP_KERNEL);
+	if (!ao_cec)
+		return -ENOMEM;
+
+	spin_lock_init(&ao_cec->cec_reg_lock);
+
+	ao_cec->adap = cec_allocate_adapter(&meson_ao_cec_ops, ao_cec,
+					    "meson_ao_cec",
+					    CEC_CAP_DEFAULTS |
+					    CEC_CAP_CONNECTOR_INFO,
+					    1); /* Use 1 for now */
+	if (IS_ERR(ao_cec->adap))
+		return PTR_ERR(ao_cec->adap);
+
+	ao_cec->adap->owner = THIS_MODULE;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	ao_cec->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(ao_cec->base)) {
+		ret = PTR_ERR(ao_cec->base);
+		goto out_probe_adapter;
+	}
+
+	irq = platform_get_irq(pdev, 0);
+	ret = devm_request_threaded_irq(&pdev->dev, irq,
+					meson_ao_cec_irq,
+					meson_ao_cec_irq_thread,
+					0, NULL, ao_cec);
+	if (ret) {
+		dev_err(&pdev->dev, "irq request failed\n");
+		goto out_probe_adapter;
+	}
+
+	ao_cec->core = devm_clk_get(&pdev->dev, "core");
+	if (IS_ERR(ao_cec->core)) {
+		dev_err(&pdev->dev, "core clock request failed\n");
+		ret = PTR_ERR(ao_cec->core);
+		goto out_probe_adapter;
+	}
+
+	ret = clk_prepare_enable(ao_cec->core);
+	if (ret) {
+		dev_err(&pdev->dev, "core clock enable failed\n");
+		goto out_probe_adapter;
+	}
+
+	ret = clk_set_rate(ao_cec->core, CEC_CLK_RATE);
+	if (ret) {
+		dev_err(&pdev->dev, "core clock set rate failed\n");
+		goto out_probe_clk;
+	}
+
+	device_reset_optional(&pdev->dev);
+
+	ao_cec->pdev = pdev;
+	platform_set_drvdata(pdev, ao_cec);
+
+	ao_cec->notify = cec_notifier_cec_adap_register(hdmi_dev, NULL,
+							ao_cec->adap);
+	if (!ao_cec->notify) {
+		ret = -ENOMEM;
+		goto out_probe_clk;
+	}
+
+	ret = cec_register_adapter(ao_cec->adap, &pdev->dev);
+	if (ret < 0)
+		goto out_probe_notify;
+
+	/* Setup Hardware */
+	writel_relaxed(CEC_GEN_CNTL_RESET,
+		       ao_cec->base + CEC_GEN_CNTL_REG);
+
+	return 0;
+
+out_probe_notify:
+	cec_notifier_cec_adap_unregister(ao_cec->notify, ao_cec->adap);
+
+out_probe_clk:
+	clk_disable_unprepare(ao_cec->core);
+
+out_probe_adapter:
+	cec_delete_adapter(ao_cec->adap);
+
+	dev_err(&pdev->dev, "CEC controller registration failed\n");
+
+	return ret;
+}
+
+static int meson_ao_cec_remove(struct platform_device *pdev)
+{
+	struct meson_ao_cec_device *ao_cec = platform_get_drvdata(pdev);
+
+	clk_disable_unprepare(ao_cec->core);
+
+	cec_notifier_cec_adap_unregister(ao_cec->notify, ao_cec->adap);
+	cec_unregister_adapter(ao_cec->adap);
+
+	return 0;
+}
+
+static const struct of_device_id meson_ao_cec_of_match[] = {
+	{ .compatible = "amlogic,meson-gx-ao-cec", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, meson_ao_cec_of_match);
+
+static struct platform_driver meson_ao_cec_driver = {
+	.probe   = meson_ao_cec_probe,
+	.remove  = meson_ao_cec_remove,
+	.driver  = {
+		.name = "meson-ao-cec",
+		.of_match_table = of_match_ptr(meson_ao_cec_of_match),
+	},
+};
+
+module_platform_driver(meson_ao_cec_driver);
+
+MODULE_DESCRIPTION("Meson AO CEC Controller driver");
+MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/cec/platform/s5p/Makefile b/drivers/media/cec/platform/s5p/Makefile
new file mode 100644
index 000000000000..92bf7b8557c5
--- /dev/null
+++ b/drivers/media/cec/platform/s5p/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_CEC_SAMSUNG_S5P)	+= s5p-cec.o
+s5p-cec-y += s5p_cec.o exynos_hdmi_cecctrl.o
diff --git a/drivers/media/cec/platform/s5p/exynos_hdmi_cec.h b/drivers/media/cec/platform/s5p/exynos_hdmi_cec.h
new file mode 100644
index 000000000000..325db8c432bd
--- /dev/null
+++ b/drivers/media/cec/platform/s5p/exynos_hdmi_cec.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* drivers/media/platform/s5p-cec/exynos_hdmi_cec.h
+ *
+ * Copyright (c) 2010, 2014 Samsung Electronics
+ *		http://www.samsung.com/
+ *
+ * Header file for interface of Samsung Exynos hdmi cec hardware
+ */
+
+#ifndef _EXYNOS_HDMI_CEC_H_
+#define _EXYNOS_HDMI_CEC_H_ __FILE__
+
+#include <linux/regmap.h>
+#include "s5p_cec.h"
+
+void s5p_cec_set_divider(struct s5p_cec_dev *cec);
+void s5p_cec_enable_rx(struct s5p_cec_dev *cec);
+void s5p_cec_mask_rx_interrupts(struct s5p_cec_dev *cec);
+void s5p_cec_unmask_rx_interrupts(struct s5p_cec_dev *cec);
+void s5p_cec_mask_tx_interrupts(struct s5p_cec_dev *cec);
+void s5p_cec_unmask_tx_interrupts(struct s5p_cec_dev *cec);
+void s5p_cec_reset(struct s5p_cec_dev *cec);
+void s5p_cec_tx_reset(struct s5p_cec_dev *cec);
+void s5p_cec_rx_reset(struct s5p_cec_dev *cec);
+void s5p_cec_threshold(struct s5p_cec_dev *cec);
+void s5p_cec_copy_packet(struct s5p_cec_dev *cec, char *data,
+			 size_t count, u8 retries);
+void s5p_cec_set_addr(struct s5p_cec_dev *cec, u32 addr);
+u32 s5p_cec_get_status(struct s5p_cec_dev *cec);
+void s5p_clr_pending_tx(struct s5p_cec_dev *cec);
+void s5p_clr_pending_rx(struct s5p_cec_dev *cec);
+void s5p_cec_get_rx_buf(struct s5p_cec_dev *cec, u32 size, u8 *buffer);
+
+#endif /* _EXYNOS_HDMI_CEC_H_ */
diff --git a/drivers/media/cec/platform/s5p/exynos_hdmi_cecctrl.c b/drivers/media/cec/platform/s5p/exynos_hdmi_cecctrl.c
new file mode 100644
index 000000000000..eb981ebce362
--- /dev/null
+++ b/drivers/media/cec/platform/s5p/exynos_hdmi_cecctrl.c
@@ -0,0 +1,206 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* drivers/media/platform/s5p-cec/exynos_hdmi_cecctrl.c
+ *
+ * Copyright (c) 2009, 2014 Samsung Electronics
+ *		http://www.samsung.com/
+ *
+ * cec ftn file for Samsung TVOUT driver
+ */
+
+#include <linux/io.h>
+#include <linux/device.h>
+
+#include "exynos_hdmi_cec.h"
+#include "regs-cec.h"
+
+#define S5P_HDMI_FIN			24000000
+#define CEC_DIV_RATIO			320000
+
+#define CEC_MESSAGE_BROADCAST_MASK	0x0F
+#define CEC_MESSAGE_BROADCAST		0x0F
+#define CEC_FILTER_THRESHOLD		0x15
+
+void s5p_cec_set_divider(struct s5p_cec_dev *cec)
+{
+	u32 div_ratio, div_val;
+	unsigned int reg;
+
+	div_ratio  = S5P_HDMI_FIN / CEC_DIV_RATIO - 1;
+
+	if (regmap_read(cec->pmu, EXYNOS_HDMI_PHY_CONTROL, &reg)) {
+		dev_err(cec->dev, "failed to read phy control\n");
+		return;
+	}
+
+	reg = (reg & ~(0x3FF << 16)) | (div_ratio << 16);
+
+	if (regmap_write(cec->pmu, EXYNOS_HDMI_PHY_CONTROL, reg)) {
+		dev_err(cec->dev, "failed to write phy control\n");
+		return;
+	}
+
+	div_val = CEC_DIV_RATIO * 0.00005 - 1;
+
+	writeb(0x0, cec->reg + S5P_CEC_DIVISOR_3);
+	writeb(0x0, cec->reg + S5P_CEC_DIVISOR_2);
+	writeb(0x0, cec->reg + S5P_CEC_DIVISOR_1);
+	writeb(div_val, cec->reg + S5P_CEC_DIVISOR_0);
+}
+
+void s5p_cec_enable_rx(struct s5p_cec_dev *cec)
+{
+	u8 reg;
+
+	reg = readb(cec->reg + S5P_CEC_RX_CTRL);
+	reg |= S5P_CEC_RX_CTRL_ENABLE;
+	writeb(reg, cec->reg + S5P_CEC_RX_CTRL);
+}
+
+void s5p_cec_mask_rx_interrupts(struct s5p_cec_dev *cec)
+{
+	u8 reg;
+
+	reg = readb(cec->reg + S5P_CEC_IRQ_MASK);
+	reg |= S5P_CEC_IRQ_RX_DONE;
+	reg |= S5P_CEC_IRQ_RX_ERROR;
+	writeb(reg, cec->reg + S5P_CEC_IRQ_MASK);
+}
+
+void s5p_cec_unmask_rx_interrupts(struct s5p_cec_dev *cec)
+{
+	u8 reg;
+
+	reg = readb(cec->reg + S5P_CEC_IRQ_MASK);
+	reg &= ~S5P_CEC_IRQ_RX_DONE;
+	reg &= ~S5P_CEC_IRQ_RX_ERROR;
+	writeb(reg, cec->reg + S5P_CEC_IRQ_MASK);
+}
+
+void s5p_cec_mask_tx_interrupts(struct s5p_cec_dev *cec)
+{
+	u8 reg;
+
+	reg = readb(cec->reg + S5P_CEC_IRQ_MASK);
+	reg |= S5P_CEC_IRQ_TX_DONE;
+	reg |= S5P_CEC_IRQ_TX_ERROR;
+	writeb(reg, cec->reg + S5P_CEC_IRQ_MASK);
+}
+
+void s5p_cec_unmask_tx_interrupts(struct s5p_cec_dev *cec)
+{
+	u8 reg;
+
+	reg = readb(cec->reg + S5P_CEC_IRQ_MASK);
+	reg &= ~S5P_CEC_IRQ_TX_DONE;
+	reg &= ~S5P_CEC_IRQ_TX_ERROR;
+	writeb(reg, cec->reg + S5P_CEC_IRQ_MASK);
+}
+
+void s5p_cec_reset(struct s5p_cec_dev *cec)
+{
+	u8 reg;
+
+	writeb(S5P_CEC_RX_CTRL_RESET, cec->reg + S5P_CEC_RX_CTRL);
+	writeb(S5P_CEC_TX_CTRL_RESET, cec->reg + S5P_CEC_TX_CTRL);
+
+	reg = readb(cec->reg + 0xc4);
+	reg &= ~0x1;
+	writeb(reg, cec->reg + 0xc4);
+}
+
+void s5p_cec_tx_reset(struct s5p_cec_dev *cec)
+{
+	writeb(S5P_CEC_TX_CTRL_RESET, cec->reg + S5P_CEC_TX_CTRL);
+}
+
+void s5p_cec_rx_reset(struct s5p_cec_dev *cec)
+{
+	u8 reg;
+
+	writeb(S5P_CEC_RX_CTRL_RESET, cec->reg + S5P_CEC_RX_CTRL);
+
+	reg = readb(cec->reg + 0xc4);
+	reg &= ~0x1;
+	writeb(reg, cec->reg + 0xc4);
+}
+
+void s5p_cec_threshold(struct s5p_cec_dev *cec)
+{
+	writeb(CEC_FILTER_THRESHOLD, cec->reg + S5P_CEC_RX_FILTER_TH);
+	writeb(0, cec->reg + S5P_CEC_RX_FILTER_CTRL);
+}
+
+void s5p_cec_copy_packet(struct s5p_cec_dev *cec, char *data,
+			 size_t count, u8 retries)
+{
+	int i = 0;
+	u8 reg;
+
+	while (i < count) {
+		writeb(data[i], cec->reg + (S5P_CEC_TX_BUFF0 + (i * 4)));
+		i++;
+	}
+
+	writeb(count, cec->reg + S5P_CEC_TX_BYTES);
+	reg = readb(cec->reg + S5P_CEC_TX_CTRL);
+	reg |= S5P_CEC_TX_CTRL_START;
+	reg &= ~0x70;
+	reg |= retries << 4;
+
+	if ((data[0] & CEC_MESSAGE_BROADCAST_MASK) == CEC_MESSAGE_BROADCAST) {
+		dev_dbg(cec->dev, "Broadcast");
+		reg |= S5P_CEC_TX_CTRL_BCAST;
+	} else {
+		dev_dbg(cec->dev, "No Broadcast");
+		reg &= ~S5P_CEC_TX_CTRL_BCAST;
+	}
+
+	writeb(reg, cec->reg + S5P_CEC_TX_CTRL);
+	dev_dbg(cec->dev, "cec-tx: cec count (%zu): %*ph", count,
+		(int)count, data);
+}
+
+void s5p_cec_set_addr(struct s5p_cec_dev *cec, u32 addr)
+{
+	writeb(addr & 0x0F, cec->reg + S5P_CEC_LOGIC_ADDR);
+}
+
+u32 s5p_cec_get_status(struct s5p_cec_dev *cec)
+{
+	u32 status = 0;
+
+	status = readb(cec->reg + S5P_CEC_STATUS_0) & 0xf;
+	status |= (readb(cec->reg + S5P_CEC_TX_STAT1) & 0xf) << 4;
+	status |= readb(cec->reg + S5P_CEC_STATUS_1) << 8;
+	status |= readb(cec->reg + S5P_CEC_STATUS_2) << 16;
+	status |= readb(cec->reg + S5P_CEC_STATUS_3) << 24;
+
+	dev_dbg(cec->dev, "status = 0x%x!\n", status);
+
+	return status;
+}
+
+void s5p_clr_pending_tx(struct s5p_cec_dev *cec)
+{
+	writeb(S5P_CEC_IRQ_TX_DONE | S5P_CEC_IRQ_TX_ERROR,
+	       cec->reg + S5P_CEC_IRQ_CLEAR);
+}
+
+void s5p_clr_pending_rx(struct s5p_cec_dev *cec)
+{
+	writeb(S5P_CEC_IRQ_RX_DONE | S5P_CEC_IRQ_RX_ERROR,
+	       cec->reg + S5P_CEC_IRQ_CLEAR);
+}
+
+void s5p_cec_get_rx_buf(struct s5p_cec_dev *cec, u32 size, u8 *buffer)
+{
+	u32 i = 0;
+	char debug[40];
+
+	while (i < size) {
+		buffer[i] = readb(cec->reg + S5P_CEC_RX_BUFF0 + (i * 4));
+		sprintf(debug + i * 2, "%02x ", buffer[i]);
+		i++;
+	}
+	dev_dbg(cec->dev, "cec-rx: cec size(%d): %s", size, debug);
+}
diff --git a/drivers/media/cec/platform/s5p/regs-cec.h b/drivers/media/cec/platform/s5p/regs-cec.h
new file mode 100644
index 000000000000..447f717028a2
--- /dev/null
+++ b/drivers/media/cec/platform/s5p/regs-cec.h
@@ -0,0 +1,93 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* drivers/media/platform/s5p-cec/regs-cec.h
+ *
+ * Copyright (c) 2010 Samsung Electronics
+ *		http://www.samsung.com/
+ *
+ *  register header file for Samsung TVOUT driver
+ */
+
+#ifndef __EXYNOS_REGS__H
+#define __EXYNOS_REGS__H
+
+/*
+ * Register part
+ */
+#define S5P_CEC_STATUS_0			(0x0000)
+#define S5P_CEC_STATUS_1			(0x0004)
+#define S5P_CEC_STATUS_2			(0x0008)
+#define S5P_CEC_STATUS_3			(0x000C)
+#define S5P_CEC_IRQ_MASK			(0x0010)
+#define S5P_CEC_IRQ_CLEAR			(0x0014)
+#define S5P_CEC_LOGIC_ADDR			(0x0020)
+#define S5P_CEC_DIVISOR_0			(0x0030)
+#define S5P_CEC_DIVISOR_1			(0x0034)
+#define S5P_CEC_DIVISOR_2			(0x0038)
+#define S5P_CEC_DIVISOR_3			(0x003C)
+
+#define S5P_CEC_TX_CTRL				(0x0040)
+#define S5P_CEC_TX_BYTES			(0x0044)
+#define S5P_CEC_TX_STAT0			(0x0060)
+#define S5P_CEC_TX_STAT1			(0x0064)
+#define S5P_CEC_TX_BUFF0			(0x0080)
+#define S5P_CEC_TX_BUFF1			(0x0084)
+#define S5P_CEC_TX_BUFF2			(0x0088)
+#define S5P_CEC_TX_BUFF3			(0x008C)
+#define S5P_CEC_TX_BUFF4			(0x0090)
+#define S5P_CEC_TX_BUFF5			(0x0094)
+#define S5P_CEC_TX_BUFF6			(0x0098)
+#define S5P_CEC_TX_BUFF7			(0x009C)
+#define S5P_CEC_TX_BUFF8			(0x00A0)
+#define S5P_CEC_TX_BUFF9			(0x00A4)
+#define S5P_CEC_TX_BUFF10			(0x00A8)
+#define S5P_CEC_TX_BUFF11			(0x00AC)
+#define S5P_CEC_TX_BUFF12			(0x00B0)
+#define S5P_CEC_TX_BUFF13			(0x00B4)
+#define S5P_CEC_TX_BUFF14			(0x00B8)
+#define S5P_CEC_TX_BUFF15			(0x00BC)
+
+#define S5P_CEC_RX_CTRL				(0x00C0)
+#define S5P_CEC_RX_STAT0			(0x00E0)
+#define S5P_CEC_RX_STAT1			(0x00E4)
+#define S5P_CEC_RX_BUFF0			(0x0100)
+#define S5P_CEC_RX_BUFF1			(0x0104)
+#define S5P_CEC_RX_BUFF2			(0x0108)
+#define S5P_CEC_RX_BUFF3			(0x010C)
+#define S5P_CEC_RX_BUFF4			(0x0110)
+#define S5P_CEC_RX_BUFF5			(0x0114)
+#define S5P_CEC_RX_BUFF6			(0x0118)
+#define S5P_CEC_RX_BUFF7			(0x011C)
+#define S5P_CEC_RX_BUFF8			(0x0120)
+#define S5P_CEC_RX_BUFF9			(0x0124)
+#define S5P_CEC_RX_BUFF10			(0x0128)
+#define S5P_CEC_RX_BUFF11			(0x012C)
+#define S5P_CEC_RX_BUFF12			(0x0130)
+#define S5P_CEC_RX_BUFF13			(0x0134)
+#define S5P_CEC_RX_BUFF14			(0x0138)
+#define S5P_CEC_RX_BUFF15			(0x013C)
+
+#define S5P_CEC_RX_FILTER_CTRL			(0x0180)
+#define S5P_CEC_RX_FILTER_TH			(0x0184)
+
+/*
+ * Bit definition part
+ */
+#define S5P_CEC_IRQ_TX_DONE			(1<<0)
+#define S5P_CEC_IRQ_TX_ERROR			(1<<1)
+#define S5P_CEC_IRQ_RX_DONE			(1<<4)
+#define S5P_CEC_IRQ_RX_ERROR			(1<<5)
+
+#define S5P_CEC_TX_CTRL_START			(1<<0)
+#define S5P_CEC_TX_CTRL_BCAST			(1<<1)
+#define S5P_CEC_TX_CTRL_RETRY			(0x04<<4)
+#define S5P_CEC_TX_CTRL_RESET			(1<<7)
+
+#define S5P_CEC_RX_CTRL_ENABLE			(1<<0)
+#define S5P_CEC_RX_CTRL_RESET			(1<<7)
+
+#define S5P_CEC_LOGIC_ADDR_MASK			(0xF)
+
+/* PMU Registers for PHY */
+#define EXYNOS_HDMI_PHY_CONTROL			0x700
+
+#endif	/* __EXYNOS_REGS__H	*/
diff --git a/drivers/media/cec/platform/s5p/s5p_cec.c b/drivers/media/cec/platform/s5p/s5p_cec.c
new file mode 100644
index 000000000000..2a3e7ffefe0a
--- /dev/null
+++ b/drivers/media/cec/platform/s5p/s5p_cec.c
@@ -0,0 +1,307 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/* drivers/media/platform/s5p-cec/s5p_cec.c
+ *
+ * Samsung S5P CEC driver
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * This driver is based on the "cec interface driver for exynos soc" by
+ * SangPil Moon.
+ */
+
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/timer.h>
+#include <linux/workqueue.h>
+#include <media/cec.h>
+#include <media/cec-notifier.h>
+
+#include "exynos_hdmi_cec.h"
+#include "regs-cec.h"
+#include "s5p_cec.h"
+
+#define CEC_NAME	"s5p-cec"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "debug level (0-2)");
+
+static int s5p_cec_adap_enable(struct cec_adapter *adap, bool enable)
+{
+	struct s5p_cec_dev *cec = cec_get_drvdata(adap);
+
+	if (enable) {
+		pm_runtime_get_sync(cec->dev);
+
+		s5p_cec_reset(cec);
+
+		s5p_cec_set_divider(cec);
+		s5p_cec_threshold(cec);
+
+		s5p_cec_unmask_tx_interrupts(cec);
+		s5p_cec_unmask_rx_interrupts(cec);
+		s5p_cec_enable_rx(cec);
+	} else {
+		s5p_cec_mask_tx_interrupts(cec);
+		s5p_cec_mask_rx_interrupts(cec);
+		pm_runtime_disable(cec->dev);
+	}
+
+	return 0;
+}
+
+static int s5p_cec_adap_log_addr(struct cec_adapter *adap, u8 addr)
+{
+	struct s5p_cec_dev *cec = cec_get_drvdata(adap);
+
+	s5p_cec_set_addr(cec, addr);
+	return 0;
+}
+
+static int s5p_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
+				 u32 signal_free_time, struct cec_msg *msg)
+{
+	struct s5p_cec_dev *cec = cec_get_drvdata(adap);
+
+	/*
+	 * Unclear if 0 retries are allowed by the hardware, so have 1 as
+	 * the minimum.
+	 */
+	s5p_cec_copy_packet(cec, msg->msg, msg->len, max(1, attempts - 1));
+	return 0;
+}
+
+static irqreturn_t s5p_cec_irq_handler(int irq, void *priv)
+{
+	struct s5p_cec_dev *cec = priv;
+	u32 status = 0;
+
+	status = s5p_cec_get_status(cec);
+
+	dev_dbg(cec->dev, "irq received\n");
+
+	if (status & CEC_STATUS_TX_DONE) {
+		if (status & CEC_STATUS_TX_NACK) {
+			dev_dbg(cec->dev, "CEC_STATUS_TX_NACK set\n");
+			cec->tx = STATE_NACK;
+		} else if (status & CEC_STATUS_TX_ERROR) {
+			dev_dbg(cec->dev, "CEC_STATUS_TX_ERROR set\n");
+			cec->tx = STATE_ERROR;
+		} else {
+			dev_dbg(cec->dev, "CEC_STATUS_TX_DONE\n");
+			cec->tx = STATE_DONE;
+		}
+		s5p_clr_pending_tx(cec);
+	}
+
+	if (status & CEC_STATUS_RX_DONE) {
+		if (status & CEC_STATUS_RX_ERROR) {
+			dev_dbg(cec->dev, "CEC_STATUS_RX_ERROR set\n");
+			s5p_cec_rx_reset(cec);
+			s5p_cec_enable_rx(cec);
+		} else {
+			dev_dbg(cec->dev, "CEC_STATUS_RX_DONE set\n");
+			if (cec->rx != STATE_IDLE)
+				dev_dbg(cec->dev, "Buffer overrun (worker did not process previous message)\n");
+			cec->rx = STATE_BUSY;
+			cec->msg.len = status >> 24;
+			cec->msg.rx_status = CEC_RX_STATUS_OK;
+			s5p_cec_get_rx_buf(cec, cec->msg.len,
+					cec->msg.msg);
+			cec->rx = STATE_DONE;
+			s5p_cec_enable_rx(cec);
+		}
+		/* Clear interrupt pending bit */
+		s5p_clr_pending_rx(cec);
+	}
+	return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t s5p_cec_irq_handler_thread(int irq, void *priv)
+{
+	struct s5p_cec_dev *cec = priv;
+
+	dev_dbg(cec->dev, "irq processing thread\n");
+	switch (cec->tx) {
+	case STATE_DONE:
+		cec_transmit_done(cec->adap, CEC_TX_STATUS_OK, 0, 0, 0, 0);
+		cec->tx = STATE_IDLE;
+		break;
+	case STATE_NACK:
+		cec_transmit_done(cec->adap,
+			CEC_TX_STATUS_MAX_RETRIES | CEC_TX_STATUS_NACK,
+			0, 1, 0, 0);
+		cec->tx = STATE_IDLE;
+		break;
+	case STATE_ERROR:
+		cec_transmit_done(cec->adap,
+			CEC_TX_STATUS_MAX_RETRIES | CEC_TX_STATUS_ERROR,
+			0, 0, 0, 1);
+		cec->tx = STATE_IDLE;
+		break;
+	case STATE_BUSY:
+		dev_err(cec->dev, "state set to busy, this should not occur here\n");
+		break;
+	default:
+		break;
+	}
+
+	switch (cec->rx) {
+	case STATE_DONE:
+		cec_received_msg(cec->adap, &cec->msg);
+		cec->rx = STATE_IDLE;
+		break;
+	default:
+		break;
+	}
+
+	return IRQ_HANDLED;
+}
+
+static const struct cec_adap_ops s5p_cec_adap_ops = {
+	.adap_enable = s5p_cec_adap_enable,
+	.adap_log_addr = s5p_cec_adap_log_addr,
+	.adap_transmit = s5p_cec_adap_transmit,
+};
+
+static int s5p_cec_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device *hdmi_dev;
+	struct resource *res;
+	struct s5p_cec_dev *cec;
+	bool needs_hpd = of_property_read_bool(pdev->dev.of_node, "needs-hpd");
+	int ret;
+
+	hdmi_dev = cec_notifier_parse_hdmi_phandle(dev);
+
+	if (IS_ERR(hdmi_dev))
+		return PTR_ERR(hdmi_dev);
+
+	cec = devm_kzalloc(&pdev->dev, sizeof(*cec), GFP_KERNEL);
+	if (!cec)
+		return -ENOMEM;
+
+	cec->dev = dev;
+
+	cec->irq = platform_get_irq(pdev, 0);
+	if (cec->irq < 0)
+		return cec->irq;
+
+	ret = devm_request_threaded_irq(dev, cec->irq, s5p_cec_irq_handler,
+		s5p_cec_irq_handler_thread, 0, pdev->name, cec);
+	if (ret)
+		return ret;
+
+	cec->clk = devm_clk_get(dev, "hdmicec");
+	if (IS_ERR(cec->clk))
+		return PTR_ERR(cec->clk);
+
+	cec->pmu = syscon_regmap_lookup_by_phandle(dev->of_node,
+						 "samsung,syscon-phandle");
+	if (IS_ERR(cec->pmu))
+		return -EPROBE_DEFER;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	cec->reg = devm_ioremap_resource(dev, res);
+	if (IS_ERR(cec->reg))
+		return PTR_ERR(cec->reg);
+
+	cec->adap = cec_allocate_adapter(&s5p_cec_adap_ops, cec, CEC_NAME,
+		CEC_CAP_DEFAULTS | (needs_hpd ? CEC_CAP_NEEDS_HPD : 0) |
+		CEC_CAP_CONNECTOR_INFO, 1);
+	ret = PTR_ERR_OR_ZERO(cec->adap);
+	if (ret)
+		return ret;
+
+	cec->notifier = cec_notifier_cec_adap_register(hdmi_dev, NULL,
+						       cec->adap);
+	if (!cec->notifier) {
+		ret = -ENOMEM;
+		goto err_delete_adapter;
+	}
+
+	ret = cec_register_adapter(cec->adap, &pdev->dev);
+	if (ret)
+		goto err_notifier;
+
+	platform_set_drvdata(pdev, cec);
+	pm_runtime_enable(dev);
+
+	dev_dbg(dev, "successfully probed\n");
+	return 0;
+
+err_notifier:
+	cec_notifier_cec_adap_unregister(cec->notifier, cec->adap);
+
+err_delete_adapter:
+	cec_delete_adapter(cec->adap);
+	return ret;
+}
+
+static int s5p_cec_remove(struct platform_device *pdev)
+{
+	struct s5p_cec_dev *cec = platform_get_drvdata(pdev);
+
+	cec_notifier_cec_adap_unregister(cec->notifier, cec->adap);
+	cec_unregister_adapter(cec->adap);
+	pm_runtime_disable(&pdev->dev);
+	return 0;
+}
+
+static int __maybe_unused s5p_cec_runtime_suspend(struct device *dev)
+{
+	struct s5p_cec_dev *cec = dev_get_drvdata(dev);
+
+	clk_disable_unprepare(cec->clk);
+	return 0;
+}
+
+static int __maybe_unused s5p_cec_runtime_resume(struct device *dev)
+{
+	struct s5p_cec_dev *cec = dev_get_drvdata(dev);
+	int ret;
+
+	ret = clk_prepare_enable(cec->clk);
+	if (ret < 0)
+		return ret;
+	return 0;
+}
+
+static const struct dev_pm_ops s5p_cec_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				pm_runtime_force_resume)
+	SET_RUNTIME_PM_OPS(s5p_cec_runtime_suspend, s5p_cec_runtime_resume,
+			   NULL)
+};
+
+static const struct of_device_id s5p_cec_match[] = {
+	{
+		.compatible	= "samsung,s5p-cec",
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, s5p_cec_match);
+
+static struct platform_driver s5p_cec_pdrv = {
+	.probe	= s5p_cec_probe,
+	.remove	= s5p_cec_remove,
+	.driver	= {
+		.name		= CEC_NAME,
+		.of_match_table	= s5p_cec_match,
+		.pm		= &s5p_cec_pm_ops,
+	},
+};
+
+module_platform_driver(s5p_cec_pdrv);
+
+MODULE_AUTHOR("Kamil Debski <kamil@wypas.org>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Samsung S5P CEC driver");
diff --git a/drivers/media/cec/platform/s5p/s5p_cec.h b/drivers/media/cec/platform/s5p/s5p_cec.h
new file mode 100644
index 000000000000..34d033b20f96
--- /dev/null
+++ b/drivers/media/cec/platform/s5p/s5p_cec.h
@@ -0,0 +1,76 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/* drivers/media/platform/s5p-cec/s5p_cec.h
+ *
+ * Samsung S5P HDMI CEC driver
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ */
+
+#ifndef _S5P_CEC_H_
+#define _S5P_CEC_H_ __FILE__
+
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/timer.h>
+#include <linux/workqueue.h>
+#include <media/cec.h>
+
+#include "exynos_hdmi_cec.h"
+#include "regs-cec.h"
+#include "s5p_cec.h"
+
+#define CEC_NAME	"s5p-cec"
+
+#define CEC_STATUS_TX_RUNNING		(1 << 0)
+#define CEC_STATUS_TX_TRANSFERRING	(1 << 1)
+#define CEC_STATUS_TX_DONE		(1 << 2)
+#define CEC_STATUS_TX_ERROR		(1 << 3)
+#define CEC_STATUS_TX_NACK		(1 << 4)
+#define CEC_STATUS_TX_BYTES		(0xFF << 8)
+#define CEC_STATUS_RX_RUNNING		(1 << 16)
+#define CEC_STATUS_RX_RECEIVING		(1 << 17)
+#define CEC_STATUS_RX_DONE		(1 << 18)
+#define CEC_STATUS_RX_ERROR		(1 << 19)
+#define CEC_STATUS_RX_BCAST		(1 << 20)
+#define CEC_STATUS_RX_BYTES		(0xFF << 24)
+
+#define CEC_WORKER_TX_DONE		(1 << 0)
+#define CEC_WORKER_RX_MSG		(1 << 1)
+
+/* CEC Rx buffer size */
+#define CEC_RX_BUFF_SIZE		16
+/* CEC Tx buffer size */
+#define CEC_TX_BUFF_SIZE		16
+
+enum cec_state {
+	STATE_IDLE,
+	STATE_BUSY,
+	STATE_DONE,
+	STATE_NACK,
+	STATE_ERROR
+};
+
+struct cec_notifier;
+
+struct s5p_cec_dev {
+	struct cec_adapter	*adap;
+	struct clk		*clk;
+	struct device		*dev;
+	struct mutex		lock;
+	struct regmap           *pmu;
+	struct cec_notifier	*notifier;
+	int			irq;
+	void __iomem		*reg;
+
+	enum cec_state		rx;
+	enum cec_state		tx;
+	struct cec_msg		msg;
+};
+
+#endif /* _S5P_CEC_H_ */
diff --git a/drivers/media/cec/platform/seco/Makefile b/drivers/media/cec/platform/seco/Makefile
new file mode 100644
index 000000000000..aa1ca8ccdb8b
--- /dev/null
+++ b/drivers/media/cec/platform/seco/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_CEC_SECO) += seco-cec.o
diff --git a/drivers/media/cec/platform/seco/seco-cec.c b/drivers/media/cec/platform/seco/seco-cec.c
new file mode 100644
index 000000000000..075dd79beb6f
--- /dev/null
+++ b/drivers/media/cec/platform/seco/seco-cec.c
@@ -0,0 +1,803 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/*
+ * CEC driver for SECO X86 Boards
+ *
+ * Author:  Ettore Chimenti <ek5.chimenti@gmail.com>
+ * Copyright (C) 2018, SECO SpA.
+ * Copyright (C) 2018, Aidilab Srl.
+ */
+
+#include <linux/module.h>
+#include <linux/acpi.h>
+#include <linux/delay.h>
+#include <linux/dmi.h>
+#include <linux/gpio/consumer.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+
+/* CEC Framework */
+#include <media/cec-notifier.h>
+
+#include "seco-cec.h"
+
+struct secocec_data {
+	struct device *dev;
+	struct platform_device *pdev;
+	struct cec_adapter *cec_adap;
+	struct cec_notifier *notifier;
+	struct rc_dev *ir;
+	char ir_input_phys[32];
+	int irq;
+};
+
+#define smb_wr16(cmd, data) smb_word_op(CMD_WORD_DATA, SECOCEC_MICRO_ADDRESS, \
+					     cmd, data, SMBUS_WRITE, NULL)
+#define smb_rd16(cmd, res) smb_word_op(CMD_WORD_DATA, SECOCEC_MICRO_ADDRESS, \
+				       cmd, 0, SMBUS_READ, res)
+
+static int smb_word_op(short data_format, u16 slave_addr, u8 cmd, u16 data,
+		       u8 operation, u16 *result)
+{
+	unsigned int count;
+	short _data_format;
+	int status = 0;
+
+	switch (data_format) {
+	case CMD_BYTE_DATA:
+		_data_format = BRA_SMB_CMD_BYTE_DATA;
+		break;
+	case CMD_WORD_DATA:
+		_data_format = BRA_SMB_CMD_WORD_DATA;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* Active wait until ready */
+	for (count = 0; count <= SMBTIMEOUT; ++count) {
+		if (!(inb(HSTS) & BRA_INUSE_STS))
+			break;
+		udelay(SMB_POLL_UDELAY);
+	}
+
+	if (count > SMBTIMEOUT)
+		/* Reset the lock instead of failing */
+		outb(0xff, HSTS);
+
+	outb(0x00, HCNT);
+	outb((u8)(slave_addr & 0xfe) | operation, XMIT_SLVA);
+	outb(cmd, HCMD);
+	inb(HCNT);
+
+	if (operation == SMBUS_WRITE) {
+		outb((u8)data, HDAT0);
+		outb((u8)(data >> 8), HDAT1);
+	}
+
+	outb(BRA_START + _data_format, HCNT);
+
+	for (count = 0; count <= SMBTIMEOUT; count++) {
+		if (!(inb(HSTS) & BRA_HOST_BUSY))
+			break;
+		udelay(SMB_POLL_UDELAY);
+	}
+
+	if (count > SMBTIMEOUT) {
+		status = -EBUSY;
+		goto err;
+	}
+
+	if (inb(HSTS) & BRA_HSTS_ERR_MASK) {
+		status = -EIO;
+		goto err;
+	}
+
+	if (operation == SMBUS_READ)
+		*result = ((inb(HDAT0) & 0xff) + ((inb(HDAT1) & 0xff) << 8));
+
+err:
+	outb(0xff, HSTS);
+	return status;
+}
+
+static int secocec_adap_enable(struct cec_adapter *adap, bool enable)
+{
+	struct secocec_data *cec = cec_get_drvdata(adap);
+	struct device *dev = cec->dev;
+	u16 val = 0;
+	int status;
+
+	if (enable) {
+		/* Clear the status register */
+		status = smb_rd16(SECOCEC_STATUS_REG_1, &val);
+		if (status)
+			goto err;
+
+		status = smb_wr16(SECOCEC_STATUS_REG_1, val);
+		if (status)
+			goto err;
+
+		/* Enable the interrupts */
+		status = smb_rd16(SECOCEC_ENABLE_REG_1, &val);
+		if (status)
+			goto err;
+
+		status = smb_wr16(SECOCEC_ENABLE_REG_1,
+				  val | SECOCEC_ENABLE_REG_1_CEC);
+		if (status)
+			goto err;
+
+		dev_dbg(dev, "Device enabled");
+	} else {
+		/* Clear the status register */
+		status = smb_rd16(SECOCEC_STATUS_REG_1, &val);
+		status = smb_wr16(SECOCEC_STATUS_REG_1, val);
+
+		/* Disable the interrupts */
+		status = smb_rd16(SECOCEC_ENABLE_REG_1, &val);
+		status = smb_wr16(SECOCEC_ENABLE_REG_1, val &
+				  ~SECOCEC_ENABLE_REG_1_CEC &
+				  ~SECOCEC_ENABLE_REG_1_IR);
+
+		dev_dbg(dev, "Device disabled");
+	}
+
+	return 0;
+err:
+	return status;
+}
+
+static int secocec_adap_log_addr(struct cec_adapter *adap, u8 logical_addr)
+{
+	u16 enable_val = 0;
+	int status;
+
+	/* Disable device */
+	status = smb_rd16(SECOCEC_ENABLE_REG_1, &enable_val);
+	if (status)
+		return status;
+
+	status = smb_wr16(SECOCEC_ENABLE_REG_1,
+			  enable_val & ~SECOCEC_ENABLE_REG_1_CEC);
+	if (status)
+		return status;
+
+	/* Write logical address
+	 * NOTE: CEC_LOG_ADDR_INVALID is mapped to the 'Unregistered' LA
+	 */
+	status = smb_wr16(SECOCEC_DEVICE_LA, logical_addr & 0xf);
+	if (status)
+		return status;
+
+	/* Re-enable device */
+	status = smb_wr16(SECOCEC_ENABLE_REG_1,
+			  enable_val | SECOCEC_ENABLE_REG_1_CEC);
+	if (status)
+		return status;
+
+	return 0;
+}
+
+static int secocec_adap_transmit(struct cec_adapter *adap, u8 attempts,
+				 u32 signal_free_time, struct cec_msg *msg)
+{
+	u16 payload_len, payload_id_len, destination, val = 0;
+	u8 *payload_msg;
+	int status;
+	u8 i;
+
+	/* Device msg len already accounts for header */
+	payload_id_len = msg->len - 1;
+
+	/* Send data length */
+	status = smb_wr16(SECOCEC_WRITE_DATA_LENGTH, payload_id_len);
+	if (status)
+		goto err;
+
+	/* Send Operation ID if present */
+	if (payload_id_len > 0) {
+		status = smb_wr16(SECOCEC_WRITE_OPERATION_ID, msg->msg[1]);
+		if (status)
+			goto err;
+	}
+	/* Send data if present */
+	if (payload_id_len > 1) {
+		/* Only data; */
+		payload_len = msg->len - 2;
+		payload_msg = &msg->msg[2];
+
+		/* Copy message into registers */
+		for (i = 0; i < payload_len; i += 2) {
+			/* hi byte */
+			val = payload_msg[i + 1] << 8;
+
+			/* lo byte */
+			val |= payload_msg[i];
+
+			status = smb_wr16(SECOCEC_WRITE_DATA_00 + i / 2, val);
+			if (status)
+				goto err;
+		}
+	}
+	/* Send msg source/destination and fire msg */
+	destination = msg->msg[0];
+	status = smb_wr16(SECOCEC_WRITE_BYTE0, destination);
+	if (status)
+		goto err;
+
+	return 0;
+
+err:
+	return status;
+}
+
+static void secocec_tx_done(struct cec_adapter *adap, u16 status_val)
+{
+	if (status_val & SECOCEC_STATUS_TX_ERROR_MASK) {
+		if (status_val & SECOCEC_STATUS_TX_NACK_ERROR)
+			cec_transmit_attempt_done(adap, CEC_TX_STATUS_NACK);
+		else
+			cec_transmit_attempt_done(adap, CEC_TX_STATUS_ERROR);
+	} else {
+		cec_transmit_attempt_done(adap, CEC_TX_STATUS_OK);
+	}
+
+	/* Reset status reg */
+	status_val = SECOCEC_STATUS_TX_ERROR_MASK |
+		SECOCEC_STATUS_MSG_SENT_MASK |
+		SECOCEC_STATUS_TX_NACK_ERROR;
+	smb_wr16(SECOCEC_STATUS, status_val);
+}
+
+static void secocec_rx_done(struct cec_adapter *adap, u16 status_val)
+{
+	struct secocec_data *cec = cec_get_drvdata(adap);
+	struct device *dev = cec->dev;
+	struct cec_msg msg = { };
+	bool flag_overflow = false;
+	u8 payload_len, i = 0;
+	u8 *payload_msg;
+	u16 val = 0;
+	int status;
+
+	if (status_val & SECOCEC_STATUS_RX_OVERFLOW_MASK) {
+		/* NOTE: Untested, it also might not be necessary */
+		dev_warn(dev, "Received more than 16 bytes. Discarding");
+		flag_overflow = true;
+	}
+
+	if (status_val & SECOCEC_STATUS_RX_ERROR_MASK) {
+		dev_warn(dev, "Message received with errors. Discarding");
+		status = -EIO;
+		goto rxerr;
+	}
+
+	/* Read message length */
+	status = smb_rd16(SECOCEC_READ_DATA_LENGTH, &val);
+	if (status)
+		return;
+
+	/* Device msg len already accounts for the header */
+	msg.len = min(val + 1, CEC_MAX_MSG_SIZE);
+
+	/* Read logical address */
+	status = smb_rd16(SECOCEC_READ_BYTE0, &val);
+	if (status)
+		return;
+
+	/* device stores source LA and destination */
+	msg.msg[0] = val;
+
+	/* Read operation ID */
+	status = smb_rd16(SECOCEC_READ_OPERATION_ID, &val);
+	if (status)
+		return;
+
+	msg.msg[1] = val;
+
+	/* Read data if present */
+	if (msg.len > 1) {
+		payload_len = msg.len - 2;
+		payload_msg = &msg.msg[2];
+
+		/* device stores 2 bytes in every 16-bit val */
+		for (i = 0; i < payload_len; i += 2) {
+			status = smb_rd16(SECOCEC_READ_DATA_00 + i / 2, &val);
+			if (status)
+				return;
+
+			/* low byte, skipping header */
+			payload_msg[i] = val & 0x00ff;
+
+			/* hi byte */
+			payload_msg[i + 1] = (val & 0xff00) >> 8;
+		}
+	}
+
+	cec_received_msg(cec->cec_adap, &msg);
+
+	/* Reset status reg */
+	status_val = SECOCEC_STATUS_MSG_RECEIVED_MASK;
+	if (flag_overflow)
+		status_val |= SECOCEC_STATUS_RX_OVERFLOW_MASK;
+
+	status = smb_wr16(SECOCEC_STATUS, status_val);
+
+	return;
+
+rxerr:
+	/* Reset error reg */
+	status_val = SECOCEC_STATUS_MSG_RECEIVED_MASK |
+		SECOCEC_STATUS_RX_ERROR_MASK;
+	if (flag_overflow)
+		status_val |= SECOCEC_STATUS_RX_OVERFLOW_MASK;
+	smb_wr16(SECOCEC_STATUS, status_val);
+}
+
+static const struct cec_adap_ops secocec_cec_adap_ops = {
+	/* Low-level callbacks */
+	.adap_enable = secocec_adap_enable,
+	.adap_log_addr = secocec_adap_log_addr,
+	.adap_transmit = secocec_adap_transmit,
+};
+
+#ifdef CONFIG_CEC_SECO_RC
+static int secocec_ir_probe(void *priv)
+{
+	struct secocec_data *cec = priv;
+	struct device *dev = cec->dev;
+	int status;
+	u16 val;
+
+	/* Prepare the RC input device */
+	cec->ir = devm_rc_allocate_device(dev, RC_DRIVER_SCANCODE);
+	if (!cec->ir)
+		return -ENOMEM;
+
+	snprintf(cec->ir_input_phys, sizeof(cec->ir_input_phys),
+		 "%s/input0", dev_name(dev));
+
+	cec->ir->device_name = dev_name(dev);
+	cec->ir->input_phys = cec->ir_input_phys;
+	cec->ir->input_id.bustype = BUS_HOST;
+	cec->ir->input_id.vendor = 0;
+	cec->ir->input_id.product = 0;
+	cec->ir->input_id.version = 1;
+	cec->ir->driver_name = SECOCEC_DEV_NAME;
+	cec->ir->allowed_protocols = RC_PROTO_BIT_RC5;
+	cec->ir->priv = cec;
+	cec->ir->map_name = RC_MAP_HAUPPAUGE;
+	cec->ir->timeout = MS_TO_NS(100);
+
+	/* Clear the status register */
+	status = smb_rd16(SECOCEC_STATUS_REG_1, &val);
+	if (status != 0)
+		goto err;
+
+	status = smb_wr16(SECOCEC_STATUS_REG_1, val);
+	if (status != 0)
+		goto err;
+
+	/* Enable the interrupts */
+	status = smb_rd16(SECOCEC_ENABLE_REG_1, &val);
+	if (status != 0)
+		goto err;
+
+	status = smb_wr16(SECOCEC_ENABLE_REG_1,
+			  val | SECOCEC_ENABLE_REG_1_IR);
+	if (status != 0)
+		goto err;
+
+	dev_dbg(dev, "IR enabled");
+
+	status = devm_rc_register_device(dev, cec->ir);
+
+	if (status) {
+		dev_err(dev, "Failed to prepare input device");
+		cec->ir = NULL;
+		goto err;
+	}
+
+	return 0;
+
+err:
+	smb_rd16(SECOCEC_ENABLE_REG_1, &val);
+
+	smb_wr16(SECOCEC_ENABLE_REG_1,
+		 val & ~SECOCEC_ENABLE_REG_1_IR);
+
+	dev_dbg(dev, "IR disabled");
+	return status;
+}
+
+static int secocec_ir_rx(struct secocec_data *priv)
+{
+	struct secocec_data *cec = priv;
+	struct device *dev = cec->dev;
+	u16 val, status, key, addr, toggle;
+
+	if (!cec->ir)
+		return -ENODEV;
+
+	status = smb_rd16(SECOCEC_IR_READ_DATA, &val);
+	if (status != 0)
+		goto err;
+
+	key = val & SECOCEC_IR_COMMAND_MASK;
+	addr = (val & SECOCEC_IR_ADDRESS_MASK) >> SECOCEC_IR_ADDRESS_SHL;
+	toggle = (val & SECOCEC_IR_TOGGLE_MASK) >> SECOCEC_IR_TOGGLE_SHL;
+
+	rc_keydown(cec->ir, RC_PROTO_RC5, RC_SCANCODE_RC5(addr, key), toggle);
+
+	dev_dbg(dev, "IR key pressed: 0x%02x addr 0x%02x toggle 0x%02x", key,
+		addr, toggle);
+
+	return 0;
+
+err:
+	dev_err(dev, "IR Receive message failed (%d)", status);
+	return -EIO;
+}
+#else
+static void secocec_ir_rx(struct secocec_data *priv)
+{
+}
+
+static int secocec_ir_probe(void *priv)
+{
+	return 0;
+}
+#endif
+
+static irqreturn_t secocec_irq_handler(int irq, void *priv)
+{
+	struct secocec_data *cec = priv;
+	struct device *dev = cec->dev;
+	u16 status_val, cec_val, val = 0;
+	int status;
+
+	/*  Read status register */
+	status = smb_rd16(SECOCEC_STATUS_REG_1, &status_val);
+	if (status)
+		goto err;
+
+	if (status_val & SECOCEC_STATUS_REG_1_CEC) {
+		/* Read CEC status register */
+		status = smb_rd16(SECOCEC_STATUS, &cec_val);
+		if (status)
+			goto err;
+
+		if (cec_val & SECOCEC_STATUS_MSG_RECEIVED_MASK)
+			secocec_rx_done(cec->cec_adap, cec_val);
+
+		if (cec_val & SECOCEC_STATUS_MSG_SENT_MASK)
+			secocec_tx_done(cec->cec_adap, cec_val);
+
+		if ((~cec_val & SECOCEC_STATUS_MSG_SENT_MASK) &&
+		    (~cec_val & SECOCEC_STATUS_MSG_RECEIVED_MASK))
+			dev_warn_once(dev,
+				      "Message not received or sent, but interrupt fired");
+
+		val = SECOCEC_STATUS_REG_1_CEC;
+	}
+
+	if (status_val & SECOCEC_STATUS_REG_1_IR) {
+		val |= SECOCEC_STATUS_REG_1_IR;
+
+		secocec_ir_rx(cec);
+	}
+
+	/*  Reset status register */
+	status = smb_wr16(SECOCEC_STATUS_REG_1, val);
+	if (status)
+		goto err;
+
+	return IRQ_HANDLED;
+
+err:
+	dev_err_once(dev, "IRQ: R/W SMBus operation failed (%d)", status);
+
+	/*  Reset status register */
+	val = SECOCEC_STATUS_REG_1_CEC | SECOCEC_STATUS_REG_1_IR;
+	smb_wr16(SECOCEC_STATUS_REG_1, val);
+
+	return IRQ_HANDLED;
+}
+
+struct cec_dmi_match {
+	const char *sys_vendor;
+	const char *product_name;
+	const char *devname;
+	const char *conn;
+};
+
+static const struct cec_dmi_match secocec_dmi_match_table[] = {
+	/* UDOO X86 */
+	{ "SECO", "UDOO x86", "0000:00:02.0", "Port B" },
+};
+
+static struct device *secocec_cec_find_hdmi_dev(struct device *dev,
+						const char **conn)
+{
+	int i;
+
+	for (i = 0 ; i < ARRAY_SIZE(secocec_dmi_match_table) ; ++i) {
+		const struct cec_dmi_match *m = &secocec_dmi_match_table[i];
+
+		if (dmi_match(DMI_SYS_VENDOR, m->sys_vendor) &&
+		    dmi_match(DMI_PRODUCT_NAME, m->product_name)) {
+			struct device *d;
+
+			/* Find the device, bail out if not yet registered */
+			d = bus_find_device_by_name(&pci_bus_type, NULL,
+						    m->devname);
+			if (!d)
+				return ERR_PTR(-EPROBE_DEFER);
+
+			put_device(d);
+			*conn = m->conn;
+			return d;
+		}
+	}
+
+	return ERR_PTR(-EINVAL);
+}
+
+static int secocec_acpi_probe(struct secocec_data *sdev)
+{
+	struct device *dev = sdev->dev;
+	struct gpio_desc *gpio;
+	int irq = 0;
+
+	gpio = devm_gpiod_get(dev, NULL, GPIOF_IN);
+	if (IS_ERR(gpio)) {
+		dev_err(dev, "Cannot request interrupt gpio");
+		return PTR_ERR(gpio);
+	}
+
+	irq = gpiod_to_irq(gpio);
+	if (irq < 0) {
+		dev_err(dev, "Cannot find valid irq");
+		return -ENODEV;
+	}
+	dev_dbg(dev, "irq-gpio is bound to IRQ %d", irq);
+
+	sdev->irq = irq;
+
+	return 0;
+}
+
+static int secocec_probe(struct platform_device *pdev)
+{
+	struct secocec_data *secocec;
+	struct device *dev = &pdev->dev;
+	struct device *hdmi_dev;
+	const char *conn = NULL;
+	int ret;
+	u16 val;
+
+	hdmi_dev = secocec_cec_find_hdmi_dev(&pdev->dev, &conn);
+	if (IS_ERR(hdmi_dev))
+		return PTR_ERR(hdmi_dev);
+
+	secocec = devm_kzalloc(dev, sizeof(*secocec), GFP_KERNEL);
+	if (!secocec)
+		return -ENOMEM;
+
+	dev_set_drvdata(dev, secocec);
+
+	/* Request SMBus regions */
+	if (!request_muxed_region(BRA_SMB_BASE_ADDR, 7, "CEC00001")) {
+		dev_err(dev, "Request memory region failed");
+		return -ENXIO;
+	}
+
+	secocec->pdev = pdev;
+	secocec->dev = dev;
+
+	if (!has_acpi_companion(dev)) {
+		dev_dbg(dev, "Cannot find any ACPI companion");
+		ret = -ENODEV;
+		goto err;
+	}
+
+	ret = secocec_acpi_probe(secocec);
+	if (ret) {
+		dev_err(dev, "Cannot assign gpio to IRQ");
+		ret = -ENODEV;
+		goto err;
+	}
+
+	/* Firmware version check */
+	ret = smb_rd16(SECOCEC_VERSION, &val);
+	if (ret) {
+		dev_err(dev, "Cannot check fw version");
+		goto err;
+	}
+	if (val < SECOCEC_LATEST_FW) {
+		dev_err(dev, "CEC Firmware not supported (v.%04x). Use ver > v.%04x",
+			val, SECOCEC_LATEST_FW);
+		ret = -EINVAL;
+		goto err;
+	}
+
+	ret = devm_request_threaded_irq(dev,
+					secocec->irq,
+					NULL,
+					secocec_irq_handler,
+					IRQF_TRIGGER_RISING | IRQF_ONESHOT,
+					dev_name(&pdev->dev), secocec);
+
+	if (ret) {
+		dev_err(dev, "Cannot request IRQ %d", secocec->irq);
+		ret = -EIO;
+		goto err;
+	}
+
+	/* Allocate CEC adapter */
+	secocec->cec_adap = cec_allocate_adapter(&secocec_cec_adap_ops,
+						 secocec,
+						 dev_name(dev),
+						 CEC_CAP_DEFAULTS |
+						 CEC_CAP_CONNECTOR_INFO,
+						 SECOCEC_MAX_ADDRS);
+
+	if (IS_ERR(secocec->cec_adap)) {
+		ret = PTR_ERR(secocec->cec_adap);
+		goto err;
+	}
+
+	secocec->notifier = cec_notifier_cec_adap_register(hdmi_dev, conn,
+							   secocec->cec_adap);
+	if (!secocec->notifier) {
+		ret = -ENOMEM;
+		goto err_delete_adapter;
+	}
+
+	ret = cec_register_adapter(secocec->cec_adap, dev);
+	if (ret)
+		goto err_notifier;
+
+	ret = secocec_ir_probe(secocec);
+	if (ret)
+		goto err_notifier;
+
+	platform_set_drvdata(pdev, secocec);
+
+	dev_dbg(dev, "Device registered");
+
+	return ret;
+
+err_notifier:
+	cec_notifier_cec_adap_unregister(secocec->notifier, secocec->cec_adap);
+err_delete_adapter:
+	cec_delete_adapter(secocec->cec_adap);
+err:
+	release_region(BRA_SMB_BASE_ADDR, 7);
+	dev_err(dev, "%s device probe failed\n", dev_name(dev));
+
+	return ret;
+}
+
+static int secocec_remove(struct platform_device *pdev)
+{
+	struct secocec_data *secocec = platform_get_drvdata(pdev);
+	u16 val;
+
+	if (secocec->ir) {
+		smb_rd16(SECOCEC_ENABLE_REG_1, &val);
+
+		smb_wr16(SECOCEC_ENABLE_REG_1, val & ~SECOCEC_ENABLE_REG_1_IR);
+
+		dev_dbg(&pdev->dev, "IR disabled");
+	}
+	cec_notifier_cec_adap_unregister(secocec->notifier, secocec->cec_adap);
+	cec_unregister_adapter(secocec->cec_adap);
+
+	release_region(BRA_SMB_BASE_ADDR, 7);
+
+	dev_dbg(&pdev->dev, "CEC device removed");
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int secocec_suspend(struct device *dev)
+{
+	int status;
+	u16 val;
+
+	dev_dbg(dev, "Device going to suspend, disabling");
+
+	/* Clear the status register */
+	status = smb_rd16(SECOCEC_STATUS_REG_1, &val);
+	if (status)
+		goto err;
+
+	status = smb_wr16(SECOCEC_STATUS_REG_1, val);
+	if (status)
+		goto err;
+
+	/* Disable the interrupts */
+	status = smb_rd16(SECOCEC_ENABLE_REG_1, &val);
+	if (status)
+		goto err;
+
+	status = smb_wr16(SECOCEC_ENABLE_REG_1, val &
+			  ~SECOCEC_ENABLE_REG_1_CEC & ~SECOCEC_ENABLE_REG_1_IR);
+	if (status)
+		goto err;
+
+	return 0;
+
+err:
+	dev_err(dev, "Suspend failed (err: %d)", status);
+	return status;
+}
+
+static int secocec_resume(struct device *dev)
+{
+	int status;
+	u16 val;
+
+	dev_dbg(dev, "Resuming device from suspend");
+
+	/* Clear the status register */
+	status = smb_rd16(SECOCEC_STATUS_REG_1, &val);
+	if (status)
+		goto err;
+
+	status = smb_wr16(SECOCEC_STATUS_REG_1, val);
+	if (status)
+		goto err;
+
+	/* Enable the interrupts */
+	status = smb_rd16(SECOCEC_ENABLE_REG_1, &val);
+	if (status)
+		goto err;
+
+	status = smb_wr16(SECOCEC_ENABLE_REG_1, val | SECOCEC_ENABLE_REG_1_CEC);
+	if (status)
+		goto err;
+
+	dev_dbg(dev, "Device resumed from suspend");
+
+	return 0;
+
+err:
+	dev_err(dev, "Resume failed (err: %d)", status);
+	return status;
+}
+
+static SIMPLE_DEV_PM_OPS(secocec_pm_ops, secocec_suspend, secocec_resume);
+#define SECOCEC_PM_OPS (&secocec_pm_ops)
+#else
+#define SECOCEC_PM_OPS NULL
+#endif
+
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id secocec_acpi_match[] = {
+	{"CEC00001", 0},
+	{},
+};
+
+MODULE_DEVICE_TABLE(acpi, secocec_acpi_match);
+#endif
+
+static struct platform_driver secocec_driver = {
+	.driver = {
+		   .name = SECOCEC_DEV_NAME,
+		   .acpi_match_table = ACPI_PTR(secocec_acpi_match),
+		   .pm = SECOCEC_PM_OPS,
+	},
+	.probe = secocec_probe,
+	.remove = secocec_remove,
+};
+
+module_platform_driver(secocec_driver);
+
+MODULE_DESCRIPTION("SECO CEC X86 Driver");
+MODULE_AUTHOR("Ettore Chimenti <ek5.chimenti@gmail.com>");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/media/cec/platform/seco/seco-cec.h b/drivers/media/cec/platform/seco/seco-cec.h
new file mode 100644
index 000000000000..843de8c7dfd4
--- /dev/null
+++ b/drivers/media/cec/platform/seco/seco-cec.h
@@ -0,0 +1,141 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+/*
+ * SECO X86 Boards CEC register defines
+ *
+ * Author:  Ettore Chimenti <ek5.chimenti@gmail.com>
+ * Copyright (C) 2018, SECO Spa.
+ * Copyright (C) 2018, Aidilab Srl.
+ */
+
+#ifndef __SECO_CEC_H__
+#define __SECO_CEC_H__
+
+#define SECOCEC_MAX_ADDRS		1
+#define SECOCEC_DEV_NAME		"secocec"
+#define SECOCEC_LATEST_FW		0x0f0b
+
+#define SMBTIMEOUT			0xfff
+#define SMB_POLL_UDELAY			10
+
+#define SMBUS_WRITE			0
+#define SMBUS_READ			1
+
+#define CMD_BYTE_DATA			0
+#define CMD_WORD_DATA			1
+
+/*
+ * SMBus definitons for Braswell
+ */
+
+#define BRA_DONE_STATUS			BIT(7)
+#define BRA_INUSE_STS			BIT(6)
+#define BRA_FAILED_OP			BIT(4)
+#define BRA_BUS_ERR			BIT(3)
+#define BRA_DEV_ERR			BIT(2)
+#define BRA_INTR			BIT(1)
+#define BRA_HOST_BUSY			BIT(0)
+#define BRA_HSTS_ERR_MASK   (BRA_FAILED_OP | BRA_BUS_ERR | BRA_DEV_ERR)
+
+#define BRA_PEC_EN			BIT(7)
+#define BRA_START			BIT(6)
+#define BRA_LAST__BYTE			BIT(5)
+#define BRA_INTREN			BIT(0)
+#define BRA_SMB_CMD			(7 << 2)
+#define BRA_SMB_CMD_QUICK		(0 << 2)
+#define BRA_SMB_CMD_BYTE		(1 << 2)
+#define BRA_SMB_CMD_BYTE_DATA		(2 << 2)
+#define BRA_SMB_CMD_WORD_DATA		(3 << 2)
+#define BRA_SMB_CMD_PROCESS_CALL	(4 << 2)
+#define BRA_SMB_CMD_BLOCK		(5 << 2)
+#define BRA_SMB_CMD_I2CREAD		(6 << 2)
+#define BRA_SMB_CMD_BLOCK_PROCESS	(7 << 2)
+
+#define BRA_SMB_BASE_ADDR  0x2040
+#define HSTS               (BRA_SMB_BASE_ADDR + 0)
+#define HCNT               (BRA_SMB_BASE_ADDR + 2)
+#define HCMD               (BRA_SMB_BASE_ADDR + 3)
+#define XMIT_SLVA          (BRA_SMB_BASE_ADDR + 4)
+#define HDAT0              (BRA_SMB_BASE_ADDR + 5)
+#define HDAT1              (BRA_SMB_BASE_ADDR + 6)
+
+/*
+ * Microcontroller Address
+ */
+
+#define SECOCEC_MICRO_ADDRESS		0x40
+
+/*
+ * STM32 SMBus Registers
+ */
+
+#define SECOCEC_VERSION			0x00
+#define SECOCEC_ENABLE_REG_1		0x01
+#define SECOCEC_ENABLE_REG_2		0x02
+#define SECOCEC_STATUS_REG_1		0x03
+#define SECOCEC_STATUS_REG_2		0x04
+
+#define SECOCEC_STATUS			0x28
+#define SECOCEC_DEVICE_LA		0x29
+#define SECOCEC_READ_OPERATION_ID	0x2a
+#define SECOCEC_READ_DATA_LENGTH	0x2b
+#define SECOCEC_READ_DATA_00		0x2c
+#define SECOCEC_READ_DATA_02		0x2d
+#define SECOCEC_READ_DATA_04		0x2e
+#define SECOCEC_READ_DATA_06		0x2f
+#define SECOCEC_READ_DATA_08		0x30
+#define SECOCEC_READ_DATA_10		0x31
+#define SECOCEC_READ_DATA_12		0x32
+#define SECOCEC_READ_BYTE0		0x33
+#define SECOCEC_WRITE_OPERATION_ID	0x34
+#define SECOCEC_WRITE_DATA_LENGTH	0x35
+#define SECOCEC_WRITE_DATA_00		0x36
+#define SECOCEC_WRITE_DATA_02		0x37
+#define SECOCEC_WRITE_DATA_04		0x38
+#define SECOCEC_WRITE_DATA_06		0x39
+#define SECOCEC_WRITE_DATA_08		0x3a
+#define SECOCEC_WRITE_DATA_10		0x3b
+#define SECOCEC_WRITE_DATA_12		0x3c
+#define SECOCEC_WRITE_BYTE0		0x3d
+
+#define SECOCEC_IR_READ_DATA		0x3e
+
+/*
+ * IR
+ */
+
+#define SECOCEC_IR_COMMAND_MASK		0x007F
+#define SECOCEC_IR_COMMAND_SHL		0
+#define SECOCEC_IR_ADDRESS_MASK		0x1F00
+#define SECOCEC_IR_ADDRESS_SHL		8
+#define SECOCEC_IR_TOGGLE_MASK		0x8000
+#define SECOCEC_IR_TOGGLE_SHL		15
+
+/*
+ * Enabling register
+ */
+
+#define SECOCEC_ENABLE_REG_1_CEC		0x1000
+#define SECOCEC_ENABLE_REG_1_IR			0x2000
+#define SECOCEC_ENABLE_REG_1_IR_PASSTHROUGH	0x4000
+
+/*
+ * Status register
+ */
+
+#define SECOCEC_STATUS_REG_1_CEC	SECOCEC_ENABLE_REG_1_CEC
+#define SECOCEC_STATUS_REG_1_IR		SECOCEC_ENABLE_REG_1_IR
+#define SECOCEC_STATUS_REG_1_IR_PASSTHR	SECOCEC_ENABLE_REG_1_IR_PASSTHR
+
+/*
+ * Status data
+ */
+
+#define SECOCEC_STATUS_MSG_RECEIVED_MASK	BIT(0)
+#define SECOCEC_STATUS_RX_ERROR_MASK		BIT(1)
+#define SECOCEC_STATUS_MSG_SENT_MASK		BIT(2)
+#define SECOCEC_STATUS_TX_ERROR_MASK		BIT(3)
+
+#define SECOCEC_STATUS_TX_NACK_ERROR		BIT(4)
+#define SECOCEC_STATUS_RX_OVERFLOW_MASK		BIT(5)
+
+#endif /* __SECO_CEC_H__ */
diff --git a/drivers/media/cec/platform/sti/Makefile b/drivers/media/cec/platform/sti/Makefile
new file mode 100644
index 000000000000..26ec5ba1c633
--- /dev/null
+++ b/drivers/media/cec/platform/sti/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_CEC_STI) += stih-cec.o
diff --git a/drivers/media/cec/platform/sti/stih-cec.c b/drivers/media/cec/platform/sti/stih-cec.c
new file mode 100644
index 000000000000..f0c73e64b586
--- /dev/null
+++ b/drivers/media/cec/platform/sti/stih-cec.c
@@ -0,0 +1,400 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * STIH4xx CEC driver
+ * Copyright (C) STMicroelectronics SA 2016
+ *
+ */
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+
+#include <media/cec.h>
+#include <media/cec-notifier.h>
+
+#define CEC_NAME	"stih-cec"
+
+/* CEC registers  */
+#define CEC_CLK_DIV           0x0
+#define CEC_CTRL              0x4
+#define CEC_IRQ_CTRL          0x8
+#define CEC_STATUS            0xC
+#define CEC_EXT_STATUS        0x10
+#define CEC_TX_CTRL           0x14
+#define CEC_FREE_TIME_THRESH  0x18
+#define CEC_BIT_TOUT_THRESH   0x1C
+#define CEC_BIT_PULSE_THRESH  0x20
+#define CEC_DATA              0x24
+#define CEC_TX_ARRAY_CTRL     0x28
+#define CEC_CTRL2             0x2C
+#define CEC_TX_ERROR_STS      0x30
+#define CEC_ADDR_TABLE        0x34
+#define CEC_DATA_ARRAY_CTRL   0x38
+#define CEC_DATA_ARRAY_STATUS 0x3C
+#define CEC_TX_DATA_BASE      0x40
+#define CEC_TX_DATA_TOP       0x50
+#define CEC_TX_DATA_SIZE      0x1
+#define CEC_RX_DATA_BASE      0x54
+#define CEC_RX_DATA_TOP       0x64
+#define CEC_RX_DATA_SIZE      0x1
+
+/* CEC_CTRL2 */
+#define CEC_LINE_INACTIVE_EN   BIT(0)
+#define CEC_AUTO_BUS_ERR_EN    BIT(1)
+#define CEC_STOP_ON_ARB_ERR_EN BIT(2)
+#define CEC_TX_REQ_WAIT_EN     BIT(3)
+
+/* CEC_DATA_ARRAY_CTRL */
+#define CEC_TX_ARRAY_EN          BIT(0)
+#define CEC_RX_ARRAY_EN          BIT(1)
+#define CEC_TX_ARRAY_RESET       BIT(2)
+#define CEC_RX_ARRAY_RESET       BIT(3)
+#define CEC_TX_N_OF_BYTES_IRQ_EN BIT(4)
+#define CEC_TX_STOP_ON_NACK      BIT(7)
+
+/* CEC_TX_ARRAY_CTRL */
+#define CEC_TX_N_OF_BYTES  0x1F
+#define CEC_TX_START       BIT(5)
+#define CEC_TX_AUTO_SOM_EN BIT(6)
+#define CEC_TX_AUTO_EOM_EN BIT(7)
+
+/* CEC_IRQ_CTRL */
+#define CEC_TX_DONE_IRQ_EN   BIT(0)
+#define CEC_ERROR_IRQ_EN     BIT(2)
+#define CEC_RX_DONE_IRQ_EN   BIT(3)
+#define CEC_RX_SOM_IRQ_EN    BIT(4)
+#define CEC_RX_EOM_IRQ_EN    BIT(5)
+#define CEC_FREE_TIME_IRQ_EN BIT(6)
+#define CEC_PIN_STS_IRQ_EN   BIT(7)
+
+/* CEC_CTRL */
+#define CEC_IN_FILTER_EN    BIT(0)
+#define CEC_PWR_SAVE_EN     BIT(1)
+#define CEC_EN              BIT(4)
+#define CEC_ACK_CTRL        BIT(5)
+#define CEC_RX_RESET_EN     BIT(6)
+#define CEC_IGNORE_RX_ERROR BIT(7)
+
+/* CEC_STATUS */
+#define CEC_TX_DONE_STS       BIT(0)
+#define CEC_TX_ACK_GET_STS    BIT(1)
+#define CEC_ERROR_STS         BIT(2)
+#define CEC_RX_DONE_STS       BIT(3)
+#define CEC_RX_SOM_STS        BIT(4)
+#define CEC_RX_EOM_STS        BIT(5)
+#define CEC_FREE_TIME_IRQ_STS BIT(6)
+#define CEC_PIN_STS           BIT(7)
+#define CEC_SBIT_TOUT_STS     BIT(8)
+#define CEC_DBIT_TOUT_STS     BIT(9)
+#define CEC_LPULSE_ERROR_STS  BIT(10)
+#define CEC_HPULSE_ERROR_STS  BIT(11)
+#define CEC_TX_ERROR          BIT(12)
+#define CEC_TX_ARB_ERROR      BIT(13)
+#define CEC_RX_ERROR_MIN      BIT(14)
+#define CEC_RX_ERROR_MAX      BIT(15)
+
+/* Signal free time in bit periods (2.4ms) */
+#define CEC_PRESENT_INIT_SFT 7
+#define CEC_NEW_INIT_SFT     5
+#define CEC_RETRANSMIT_SFT   3
+
+/* Constants for CEC_BIT_TOUT_THRESH register */
+#define CEC_SBIT_TOUT_47MS BIT(1)
+#define CEC_SBIT_TOUT_48MS (BIT(0) | BIT(1))
+#define CEC_SBIT_TOUT_50MS BIT(2)
+#define CEC_DBIT_TOUT_27MS BIT(0)
+#define CEC_DBIT_TOUT_28MS BIT(1)
+#define CEC_DBIT_TOUT_29MS (BIT(0) | BIT(1))
+
+/* Constants for CEC_BIT_PULSE_THRESH register */
+#define CEC_BIT_LPULSE_03MS BIT(1)
+#define CEC_BIT_HPULSE_03MS BIT(3)
+
+/* Constants for CEC_DATA_ARRAY_STATUS register */
+#define CEC_RX_N_OF_BYTES                     0x1F
+#define CEC_TX_N_OF_BYTES_SENT                BIT(5)
+#define CEC_RX_OVERRUN                        BIT(6)
+
+struct stih_cec {
+	struct cec_adapter	*adap;
+	struct device		*dev;
+	struct clk		*clk;
+	void __iomem		*regs;
+	int			irq;
+	u32			irq_status;
+	struct cec_notifier	*notifier;
+};
+
+static int stih_cec_adap_enable(struct cec_adapter *adap, bool enable)
+{
+	struct stih_cec *cec = cec_get_drvdata(adap);
+
+	if (enable) {
+		/* The doc says (input TCLK_PERIOD * CEC_CLK_DIV) = 0.1ms */
+		unsigned long clk_freq = clk_get_rate(cec->clk);
+		u32 cec_clk_div = clk_freq / 10000;
+
+		writel(cec_clk_div, cec->regs + CEC_CLK_DIV);
+
+		/* Configuration of the durations activating a timeout */
+		writel(CEC_SBIT_TOUT_47MS | (CEC_DBIT_TOUT_28MS << 4),
+		       cec->regs + CEC_BIT_TOUT_THRESH);
+
+		/* Configuration of the smallest allowed duration for pulses */
+		writel(CEC_BIT_LPULSE_03MS | CEC_BIT_HPULSE_03MS,
+		       cec->regs + CEC_BIT_PULSE_THRESH);
+
+		/* Minimum received bit period threshold */
+		writel(BIT(5) | BIT(7), cec->regs + CEC_TX_CTRL);
+
+		/* Configuration of transceiver data arrays */
+		writel(CEC_TX_ARRAY_EN | CEC_RX_ARRAY_EN | CEC_TX_STOP_ON_NACK,
+		       cec->regs + CEC_DATA_ARRAY_CTRL);
+
+		/* Configuration of the control bits for CEC Transceiver */
+		writel(CEC_IN_FILTER_EN | CEC_EN | CEC_RX_RESET_EN,
+		       cec->regs + CEC_CTRL);
+
+		/* Clear logical addresses */
+		writel(0, cec->regs + CEC_ADDR_TABLE);
+
+		/* Clear the status register */
+		writel(0x0, cec->regs + CEC_STATUS);
+
+		/* Enable the interrupts */
+		writel(CEC_TX_DONE_IRQ_EN | CEC_RX_DONE_IRQ_EN |
+		       CEC_RX_SOM_IRQ_EN | CEC_RX_EOM_IRQ_EN |
+		       CEC_ERROR_IRQ_EN,
+		       cec->regs + CEC_IRQ_CTRL);
+
+	} else {
+		/* Clear logical addresses */
+		writel(0, cec->regs + CEC_ADDR_TABLE);
+
+		/* Clear the status register */
+		writel(0x0, cec->regs + CEC_STATUS);
+
+		/* Disable the interrupts */
+		writel(0, cec->regs + CEC_IRQ_CTRL);
+	}
+
+	return 0;
+}
+
+static int stih_cec_adap_log_addr(struct cec_adapter *adap, u8 logical_addr)
+{
+	struct stih_cec *cec = cec_get_drvdata(adap);
+	u32 reg = readl(cec->regs + CEC_ADDR_TABLE);
+
+	reg |= 1 << logical_addr;
+
+	if (logical_addr == CEC_LOG_ADDR_INVALID)
+		reg = 0;
+
+	writel(reg, cec->regs + CEC_ADDR_TABLE);
+
+	return 0;
+}
+
+static int stih_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
+				  u32 signal_free_time, struct cec_msg *msg)
+{
+	struct stih_cec *cec = cec_get_drvdata(adap);
+	int i;
+
+	/* Copy message into registers */
+	for (i = 0; i < msg->len; i++)
+		writeb(msg->msg[i], cec->regs + CEC_TX_DATA_BASE + i);
+
+	/*
+	 * Start transmission, configure hardware to add start and stop bits
+	 * Signal free time is handled by the hardware
+	 */
+	writel(CEC_TX_AUTO_SOM_EN | CEC_TX_AUTO_EOM_EN | CEC_TX_START |
+	       msg->len, cec->regs + CEC_TX_ARRAY_CTRL);
+
+	return 0;
+}
+
+static void stih_tx_done(struct stih_cec *cec, u32 status)
+{
+	if (status & CEC_TX_ERROR) {
+		cec_transmit_attempt_done(cec->adap, CEC_TX_STATUS_ERROR);
+		return;
+	}
+
+	if (status & CEC_TX_ARB_ERROR) {
+		cec_transmit_attempt_done(cec->adap, CEC_TX_STATUS_ARB_LOST);
+		return;
+	}
+
+	if (!(status & CEC_TX_ACK_GET_STS)) {
+		cec_transmit_attempt_done(cec->adap, CEC_TX_STATUS_NACK);
+		return;
+	}
+
+	cec_transmit_attempt_done(cec->adap, CEC_TX_STATUS_OK);
+}
+
+static void stih_rx_done(struct stih_cec *cec, u32 status)
+{
+	struct cec_msg msg = {};
+	u8 i;
+
+	if (status & CEC_RX_ERROR_MIN)
+		return;
+
+	if (status & CEC_RX_ERROR_MAX)
+		return;
+
+	msg.len = readl(cec->regs + CEC_DATA_ARRAY_STATUS) & 0x1f;
+
+	if (!msg.len)
+		return;
+
+	if (msg.len > 16)
+		msg.len = 16;
+
+	for (i = 0; i < msg.len; i++)
+		msg.msg[i] = readl(cec->regs + CEC_RX_DATA_BASE + i);
+
+	cec_received_msg(cec->adap, &msg);
+}
+
+static irqreturn_t stih_cec_irq_handler_thread(int irq, void *priv)
+{
+	struct stih_cec *cec = priv;
+
+	if (cec->irq_status & CEC_TX_DONE_STS)
+		stih_tx_done(cec, cec->irq_status);
+
+	if (cec->irq_status & CEC_RX_DONE_STS)
+		stih_rx_done(cec, cec->irq_status);
+
+	cec->irq_status = 0;
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t stih_cec_irq_handler(int irq, void *priv)
+{
+	struct stih_cec *cec = priv;
+
+	cec->irq_status = readl(cec->regs + CEC_STATUS);
+	writel(cec->irq_status, cec->regs + CEC_STATUS);
+
+	return IRQ_WAKE_THREAD;
+}
+
+static const struct cec_adap_ops sti_cec_adap_ops = {
+	.adap_enable = stih_cec_adap_enable,
+	.adap_log_addr = stih_cec_adap_log_addr,
+	.adap_transmit = stih_cec_adap_transmit,
+};
+
+static int stih_cec_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	struct stih_cec *cec;
+	struct device *hdmi_dev;
+	int ret;
+
+	hdmi_dev = cec_notifier_parse_hdmi_phandle(dev);
+
+	if (IS_ERR(hdmi_dev))
+		return PTR_ERR(hdmi_dev);
+
+	cec = devm_kzalloc(dev, sizeof(*cec), GFP_KERNEL);
+	if (!cec)
+		return -ENOMEM;
+
+	cec->dev = dev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	cec->regs = devm_ioremap_resource(dev, res);
+	if (IS_ERR(cec->regs))
+		return PTR_ERR(cec->regs);
+
+	cec->irq = platform_get_irq(pdev, 0);
+	if (cec->irq < 0)
+		return cec->irq;
+
+	ret = devm_request_threaded_irq(dev, cec->irq, stih_cec_irq_handler,
+					stih_cec_irq_handler_thread, 0,
+					pdev->name, cec);
+	if (ret)
+		return ret;
+
+	cec->clk = devm_clk_get(dev, "cec-clk");
+	if (IS_ERR(cec->clk)) {
+		dev_err(dev, "Cannot get cec clock\n");
+		return PTR_ERR(cec->clk);
+	}
+
+	cec->adap = cec_allocate_adapter(&sti_cec_adap_ops, cec, CEC_NAME,
+					 CEC_CAP_DEFAULTS |
+					 CEC_CAP_CONNECTOR_INFO,
+					 CEC_MAX_LOG_ADDRS);
+	ret = PTR_ERR_OR_ZERO(cec->adap);
+	if (ret)
+		return ret;
+
+	cec->notifier = cec_notifier_cec_adap_register(hdmi_dev, NULL,
+						       cec->adap);
+	if (!cec->notifier) {
+		ret = -ENOMEM;
+		goto err_delete_adapter;
+	}
+
+	ret = cec_register_adapter(cec->adap, &pdev->dev);
+	if (ret)
+		goto err_notifier;
+
+	platform_set_drvdata(pdev, cec);
+	return 0;
+
+err_notifier:
+	cec_notifier_cec_adap_unregister(cec->notifier, cec->adap);
+
+err_delete_adapter:
+	cec_delete_adapter(cec->adap);
+	return ret;
+}
+
+static int stih_cec_remove(struct platform_device *pdev)
+{
+	struct stih_cec *cec = platform_get_drvdata(pdev);
+
+	cec_notifier_cec_adap_unregister(cec->notifier, cec->adap);
+	cec_unregister_adapter(cec->adap);
+
+	return 0;
+}
+
+static const struct of_device_id stih_cec_match[] = {
+	{
+		.compatible	= "st,stih-cec",
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, stih_cec_match);
+
+static struct platform_driver stih_cec_pdrv = {
+	.probe	= stih_cec_probe,
+	.remove = stih_cec_remove,
+	.driver = {
+		.name		= CEC_NAME,
+		.of_match_table	= stih_cec_match,
+	},
+};
+
+module_platform_driver(stih_cec_pdrv);
+
+MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@linaro.org>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("STIH4xx CEC driver");
diff --git a/drivers/media/cec/platform/stm32/Makefile b/drivers/media/cec/platform/stm32/Makefile
new file mode 100644
index 000000000000..b7597a00befa
--- /dev/null
+++ b/drivers/media/cec/platform/stm32/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_CEC_STM32) += stm32-cec.o
diff --git a/drivers/media/cec/platform/stm32/stm32-cec.c b/drivers/media/cec/platform/stm32/stm32-cec.c
new file mode 100644
index 000000000000..ea4b1ebfca99
--- /dev/null
+++ b/drivers/media/cec/platform/stm32/stm32-cec.c
@@ -0,0 +1,374 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * STM32 CEC driver
+ * Copyright (C) STMicroelectronics SA 2017
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <media/cec.h>
+
+#define CEC_NAME	"stm32-cec"
+
+/* CEC registers  */
+#define CEC_CR		0x0000 /* Control Register */
+#define CEC_CFGR	0x0004 /* ConFiGuration Register */
+#define CEC_TXDR	0x0008 /* Rx data Register */
+#define CEC_RXDR	0x000C /* Rx data Register */
+#define CEC_ISR		0x0010 /* Interrupt and status Register */
+#define CEC_IER		0x0014 /* Interrupt enable Register */
+
+#define TXEOM		BIT(2)
+#define TXSOM		BIT(1)
+#define CECEN		BIT(0)
+
+#define LSTN		BIT(31)
+#define OAR		GENMASK(30, 16)
+#define SFTOP		BIT(8)
+#define BRDNOGEN	BIT(7)
+#define LBPEGEN		BIT(6)
+#define BREGEN		BIT(5)
+#define BRESTP		BIT(4)
+#define RXTOL		BIT(3)
+#define SFT		GENMASK(2, 0)
+#define FULL_CFG	(LSTN | SFTOP | BRDNOGEN | LBPEGEN | BREGEN | BRESTP \
+			 | RXTOL)
+
+#define TXACKE		BIT(12)
+#define TXERR		BIT(11)
+#define TXUDR		BIT(10)
+#define TXEND		BIT(9)
+#define TXBR		BIT(8)
+#define ARBLST		BIT(7)
+#define RXACKE		BIT(6)
+#define RXOVR		BIT(2)
+#define RXEND		BIT(1)
+#define RXBR		BIT(0)
+
+#define ALL_TX_IT	(TXEND | TXBR | TXACKE | TXERR | TXUDR | ARBLST)
+#define ALL_RX_IT	(RXEND | RXBR | RXACKE | RXOVR)
+
+/*
+ * 400 ms is the time it takes for one 16 byte message to be
+ * transferred and 5 is the maximum number of retries. Add
+ * another 100 ms as a margin.
+ */
+#define CEC_XFER_TIMEOUT_MS (5 * 400 + 100)
+
+struct stm32_cec {
+	struct cec_adapter	*adap;
+	struct device		*dev;
+	struct clk		*clk_cec;
+	struct clk		*clk_hdmi_cec;
+	struct reset_control	*rstc;
+	struct regmap		*regmap;
+	int			irq;
+	u32			irq_status;
+	struct cec_msg		rx_msg;
+	struct cec_msg		tx_msg;
+	int			tx_cnt;
+};
+
+static void cec_hw_init(struct stm32_cec *cec)
+{
+	regmap_update_bits(cec->regmap, CEC_CR, TXEOM | TXSOM | CECEN, 0);
+
+	regmap_update_bits(cec->regmap, CEC_IER, ALL_TX_IT | ALL_RX_IT,
+			   ALL_TX_IT | ALL_RX_IT);
+
+	regmap_update_bits(cec->regmap, CEC_CFGR, FULL_CFG, FULL_CFG);
+}
+
+static void stm32_tx_done(struct stm32_cec *cec, u32 status)
+{
+	if (status & (TXERR | TXUDR)) {
+		cec_transmit_done(cec->adap, CEC_TX_STATUS_ERROR,
+				  0, 0, 0, 1);
+		return;
+	}
+
+	if (status & ARBLST) {
+		cec_transmit_done(cec->adap, CEC_TX_STATUS_ARB_LOST,
+				  1, 0, 0, 0);
+		return;
+	}
+
+	if (status & TXACKE) {
+		cec_transmit_done(cec->adap, CEC_TX_STATUS_NACK,
+				  0, 1, 0, 0);
+		return;
+	}
+
+	if (cec->irq_status & TXBR) {
+		/* send next byte */
+		if (cec->tx_cnt < cec->tx_msg.len)
+			regmap_write(cec->regmap, CEC_TXDR,
+				     cec->tx_msg.msg[cec->tx_cnt++]);
+
+		/* TXEOM is set to command transmission of the last byte */
+		if (cec->tx_cnt == cec->tx_msg.len)
+			regmap_update_bits(cec->regmap, CEC_CR, TXEOM, TXEOM);
+	}
+
+	if (cec->irq_status & TXEND)
+		cec_transmit_done(cec->adap, CEC_TX_STATUS_OK, 0, 0, 0, 0);
+}
+
+static void stm32_rx_done(struct stm32_cec *cec, u32 status)
+{
+	if (cec->irq_status & (RXACKE | RXOVR)) {
+		cec->rx_msg.len = 0;
+		return;
+	}
+
+	if (cec->irq_status & RXBR) {
+		u32 val;
+
+		regmap_read(cec->regmap, CEC_RXDR, &val);
+		cec->rx_msg.msg[cec->rx_msg.len++] = val & 0xFF;
+	}
+
+	if (cec->irq_status & RXEND) {
+		cec_received_msg(cec->adap, &cec->rx_msg);
+		cec->rx_msg.len = 0;
+	}
+}
+
+static irqreturn_t stm32_cec_irq_thread(int irq, void *arg)
+{
+	struct stm32_cec *cec = arg;
+
+	if (cec->irq_status & ALL_TX_IT)
+		stm32_tx_done(cec, cec->irq_status);
+
+	if (cec->irq_status & ALL_RX_IT)
+		stm32_rx_done(cec, cec->irq_status);
+
+	cec->irq_status = 0;
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t stm32_cec_irq_handler(int irq, void *arg)
+{
+	struct stm32_cec *cec = arg;
+
+	regmap_read(cec->regmap, CEC_ISR, &cec->irq_status);
+
+	regmap_update_bits(cec->regmap, CEC_ISR,
+			   ALL_TX_IT | ALL_RX_IT,
+			   ALL_TX_IT | ALL_RX_IT);
+
+	return IRQ_WAKE_THREAD;
+}
+
+static int stm32_cec_adap_enable(struct cec_adapter *adap, bool enable)
+{
+	struct stm32_cec *cec = adap->priv;
+	int ret = 0;
+
+	if (enable) {
+		ret = clk_enable(cec->clk_cec);
+		if (ret)
+			dev_err(cec->dev, "fail to enable cec clock\n");
+
+		clk_enable(cec->clk_hdmi_cec);
+		regmap_update_bits(cec->regmap, CEC_CR, CECEN, CECEN);
+	} else {
+		clk_disable(cec->clk_cec);
+		clk_disable(cec->clk_hdmi_cec);
+		regmap_update_bits(cec->regmap, CEC_CR, CECEN, 0);
+	}
+
+	return ret;
+}
+
+static int stm32_cec_adap_log_addr(struct cec_adapter *adap, u8 logical_addr)
+{
+	struct stm32_cec *cec = adap->priv;
+	u32 oar = (1 << logical_addr) << 16;
+	u32 val;
+
+	/* Poll every 100µs the register CEC_CR to wait end of transmission */
+	regmap_read_poll_timeout(cec->regmap, CEC_CR, val, !(val & TXSOM),
+				 100, CEC_XFER_TIMEOUT_MS * 1000);
+	regmap_update_bits(cec->regmap, CEC_CR, CECEN, 0);
+
+	if (logical_addr == CEC_LOG_ADDR_INVALID)
+		regmap_update_bits(cec->regmap, CEC_CFGR, OAR, 0);
+	else
+		regmap_update_bits(cec->regmap, CEC_CFGR, oar, oar);
+
+	regmap_update_bits(cec->regmap, CEC_CR, CECEN, CECEN);
+
+	return 0;
+}
+
+static int stm32_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
+				   u32 signal_free_time, struct cec_msg *msg)
+{
+	struct stm32_cec *cec = adap->priv;
+
+	/* Copy message */
+	cec->tx_msg = *msg;
+	cec->tx_cnt = 0;
+
+	/*
+	 * If the CEC message consists of only one byte,
+	 * TXEOM must be set before of TXSOM.
+	 */
+	if (cec->tx_msg.len == 1)
+		regmap_update_bits(cec->regmap, CEC_CR, TXEOM, TXEOM);
+
+	/* TXSOM is set to command transmission of the first byte */
+	regmap_update_bits(cec->regmap, CEC_CR, TXSOM, TXSOM);
+
+	/* Write the header (first byte of message) */
+	regmap_write(cec->regmap, CEC_TXDR, cec->tx_msg.msg[0]);
+	cec->tx_cnt++;
+
+	return 0;
+}
+
+static const struct cec_adap_ops stm32_cec_adap_ops = {
+	.adap_enable = stm32_cec_adap_enable,
+	.adap_log_addr = stm32_cec_adap_log_addr,
+	.adap_transmit = stm32_cec_adap_transmit,
+};
+
+static const struct regmap_config stm32_cec_regmap_cfg = {
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = sizeof(u32),
+	.max_register = 0x14,
+	.fast_io = true,
+};
+
+static int stm32_cec_probe(struct platform_device *pdev)
+{
+	u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_PHYS_ADDR | CEC_MODE_MONITOR_ALL;
+	struct resource *res;
+	struct stm32_cec *cec;
+	void __iomem *mmio;
+	int ret;
+
+	cec = devm_kzalloc(&pdev->dev, sizeof(*cec), GFP_KERNEL);
+	if (!cec)
+		return -ENOMEM;
+
+	cec->dev = &pdev->dev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	mmio = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(mmio))
+		return PTR_ERR(mmio);
+
+	cec->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "cec", mmio,
+						&stm32_cec_regmap_cfg);
+
+	if (IS_ERR(cec->regmap))
+		return PTR_ERR(cec->regmap);
+
+	cec->irq = platform_get_irq(pdev, 0);
+	if (cec->irq < 0)
+		return cec->irq;
+
+	ret = devm_request_threaded_irq(&pdev->dev, cec->irq,
+					stm32_cec_irq_handler,
+					stm32_cec_irq_thread,
+					0,
+					pdev->name, cec);
+	if (ret)
+		return ret;
+
+	cec->clk_cec = devm_clk_get(&pdev->dev, "cec");
+	if (IS_ERR(cec->clk_cec)) {
+		if (PTR_ERR(cec->clk_cec) != -EPROBE_DEFER)
+			dev_err(&pdev->dev, "Cannot get cec clock\n");
+
+		return PTR_ERR(cec->clk_cec);
+	}
+
+	ret = clk_prepare(cec->clk_cec);
+	if (ret) {
+		dev_err(&pdev->dev, "Unable to prepare cec clock\n");
+		return ret;
+	}
+
+	cec->clk_hdmi_cec = devm_clk_get(&pdev->dev, "hdmi-cec");
+	if (IS_ERR(cec->clk_hdmi_cec) &&
+	    PTR_ERR(cec->clk_hdmi_cec) == -EPROBE_DEFER)
+		return -EPROBE_DEFER;
+
+	if (!IS_ERR(cec->clk_hdmi_cec)) {
+		ret = clk_prepare(cec->clk_hdmi_cec);
+		if (ret) {
+			dev_err(&pdev->dev, "Can't prepare hdmi-cec clock\n");
+			return ret;
+		}
+	}
+
+	/*
+	 * CEC_CAP_PHYS_ADDR caps should be removed when a cec notifier is
+	 * available for example when a drm driver can provide edid
+	 */
+	cec->adap = cec_allocate_adapter(&stm32_cec_adap_ops, cec,
+			CEC_NAME, caps,	CEC_MAX_LOG_ADDRS);
+	ret = PTR_ERR_OR_ZERO(cec->adap);
+	if (ret)
+		return ret;
+
+	ret = cec_register_adapter(cec->adap, &pdev->dev);
+	if (ret) {
+		cec_delete_adapter(cec->adap);
+		return ret;
+	}
+
+	cec_hw_init(cec);
+
+	platform_set_drvdata(pdev, cec);
+
+	return 0;
+}
+
+static int stm32_cec_remove(struct platform_device *pdev)
+{
+	struct stm32_cec *cec = platform_get_drvdata(pdev);
+
+	clk_unprepare(cec->clk_cec);
+	clk_unprepare(cec->clk_hdmi_cec);
+
+	cec_unregister_adapter(cec->adap);
+
+	return 0;
+}
+
+static const struct of_device_id stm32_cec_of_match[] = {
+	{ .compatible = "st,stm32-cec" },
+	{ /* end node */ }
+};
+MODULE_DEVICE_TABLE(of, stm32_cec_of_match);
+
+static struct platform_driver stm32_cec_driver = {
+	.probe  = stm32_cec_probe,
+	.remove = stm32_cec_remove,
+	.driver = {
+		.name		= CEC_NAME,
+		.of_match_table = stm32_cec_of_match,
+	},
+};
+
+module_platform_driver(stm32_cec_driver);
+
+MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
+MODULE_AUTHOR("Yannick Fertre <yannick.fertre@st.com>");
+MODULE_DESCRIPTION("STMicroelectronics STM32 Consumer Electronics Control");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/cec/platform/tegra/Makefile b/drivers/media/cec/platform/tegra/Makefile
new file mode 100644
index 000000000000..275d1c019d49
--- /dev/null
+++ b/drivers/media/cec/platform/tegra/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_CEC_TEGRA)	+= tegra_cec.o
diff --git a/drivers/media/cec/platform/tegra/tegra_cec.c b/drivers/media/cec/platform/tegra/tegra_cec.c
new file mode 100644
index 000000000000..1ac0c70a5981
--- /dev/null
+++ b/drivers/media/cec/platform/tegra/tegra_cec.c
@@ -0,0 +1,481 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Tegra CEC implementation
+ *
+ * The original 3.10 CEC driver using a custom API:
+ *
+ * Copyright (c) 2012-2015, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * Conversion to the CEC framework and to the mainline kernel:
+ *
+ * Copyright 2016-2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/clk/tegra.h>
+
+#include <media/cec-notifier.h>
+
+#include "tegra_cec.h"
+
+#define TEGRA_CEC_NAME "tegra-cec"
+
+struct tegra_cec {
+	struct cec_adapter	*adap;
+	struct device		*dev;
+	struct clk		*clk;
+	void __iomem		*cec_base;
+	struct cec_notifier	*notifier;
+	int			tegra_cec_irq;
+	bool			rx_done;
+	bool			tx_done;
+	int			tx_status;
+	u8			rx_buf[CEC_MAX_MSG_SIZE];
+	u8			rx_buf_cnt;
+	u32			tx_buf[CEC_MAX_MSG_SIZE];
+	u8			tx_buf_cur;
+	u8			tx_buf_cnt;
+};
+
+static inline u32 cec_read(struct tegra_cec *cec, u32 reg)
+{
+	return readl(cec->cec_base + reg);
+}
+
+static inline void cec_write(struct tegra_cec *cec, u32 reg, u32 val)
+{
+	writel(val, cec->cec_base + reg);
+}
+
+static void tegra_cec_error_recovery(struct tegra_cec *cec)
+{
+	u32 hw_ctrl;
+
+	hw_ctrl = cec_read(cec, TEGRA_CEC_HW_CONTROL);
+	cec_write(cec, TEGRA_CEC_HW_CONTROL, 0);
+	cec_write(cec, TEGRA_CEC_INT_STAT, 0xffffffff);
+	cec_write(cec, TEGRA_CEC_HW_CONTROL, hw_ctrl);
+}
+
+static irqreturn_t tegra_cec_irq_thread_handler(int irq, void *data)
+{
+	struct device *dev = data;
+	struct tegra_cec *cec = dev_get_drvdata(dev);
+
+	if (cec->tx_done) {
+		cec_transmit_attempt_done(cec->adap, cec->tx_status);
+		cec->tx_done = false;
+	}
+	if (cec->rx_done) {
+		struct cec_msg msg = {};
+
+		msg.len = cec->rx_buf_cnt;
+		memcpy(msg.msg, cec->rx_buf, msg.len);
+		cec_received_msg(cec->adap, &msg);
+		cec->rx_done = false;
+		cec->rx_buf_cnt = 0;
+	}
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t tegra_cec_irq_handler(int irq, void *data)
+{
+	struct device *dev = data;
+	struct tegra_cec *cec = dev_get_drvdata(dev);
+	u32 status, mask;
+
+	status = cec_read(cec, TEGRA_CEC_INT_STAT);
+	mask = cec_read(cec, TEGRA_CEC_INT_MASK);
+
+	status &= mask;
+
+	if (!status)
+		return IRQ_HANDLED;
+
+	if (status & TEGRA_CEC_INT_STAT_TX_REGISTER_UNDERRUN) {
+		dev_err(dev, "TX underrun, interrupt timing issue!\n");
+
+		tegra_cec_error_recovery(cec);
+		cec_write(cec, TEGRA_CEC_INT_MASK,
+			  mask & ~TEGRA_CEC_INT_MASK_TX_REGISTER_EMPTY);
+
+		cec->tx_done = true;
+		cec->tx_status = CEC_TX_STATUS_ERROR;
+		return IRQ_WAKE_THREAD;
+	}
+
+	if ((status & TEGRA_CEC_INT_STAT_TX_ARBITRATION_FAILED) ||
+		   (status & TEGRA_CEC_INT_STAT_TX_BUS_ANOMALY_DETECTED)) {
+		tegra_cec_error_recovery(cec);
+		cec_write(cec, TEGRA_CEC_INT_MASK,
+			  mask & ~TEGRA_CEC_INT_MASK_TX_REGISTER_EMPTY);
+
+		cec->tx_done = true;
+		if (status & TEGRA_CEC_INT_STAT_TX_BUS_ANOMALY_DETECTED)
+			cec->tx_status = CEC_TX_STATUS_LOW_DRIVE;
+		else
+			cec->tx_status = CEC_TX_STATUS_ARB_LOST;
+		return IRQ_WAKE_THREAD;
+	}
+
+	if (status & TEGRA_CEC_INT_STAT_TX_FRAME_TRANSMITTED) {
+		cec_write(cec, TEGRA_CEC_INT_STAT,
+			  TEGRA_CEC_INT_STAT_TX_FRAME_TRANSMITTED);
+
+		if (status & TEGRA_CEC_INT_STAT_TX_FRAME_OR_BLOCK_NAKD) {
+			tegra_cec_error_recovery(cec);
+
+			cec->tx_done = true;
+			cec->tx_status = CEC_TX_STATUS_NACK;
+		} else {
+			cec->tx_done = true;
+			cec->tx_status = CEC_TX_STATUS_OK;
+		}
+		return IRQ_WAKE_THREAD;
+	}
+
+	if (status & TEGRA_CEC_INT_STAT_TX_FRAME_OR_BLOCK_NAKD)
+		dev_warn(dev, "TX NAKed on the fly!\n");
+
+	if (status & TEGRA_CEC_INT_STAT_TX_REGISTER_EMPTY) {
+		if (cec->tx_buf_cur == cec->tx_buf_cnt) {
+			cec_write(cec, TEGRA_CEC_INT_MASK,
+				  mask & ~TEGRA_CEC_INT_MASK_TX_REGISTER_EMPTY);
+		} else {
+			cec_write(cec, TEGRA_CEC_TX_REGISTER,
+				  cec->tx_buf[cec->tx_buf_cur++]);
+			cec_write(cec, TEGRA_CEC_INT_STAT,
+				  TEGRA_CEC_INT_STAT_TX_REGISTER_EMPTY);
+		}
+	}
+
+	if (status & TEGRA_CEC_INT_STAT_RX_START_BIT_DETECTED) {
+		cec_write(cec, TEGRA_CEC_INT_STAT,
+			  TEGRA_CEC_INT_STAT_RX_START_BIT_DETECTED);
+		cec->rx_done = false;
+		cec->rx_buf_cnt = 0;
+	}
+	if (status & TEGRA_CEC_INT_STAT_RX_REGISTER_FULL) {
+		u32 v;
+
+		cec_write(cec, TEGRA_CEC_INT_STAT,
+			  TEGRA_CEC_INT_STAT_RX_REGISTER_FULL);
+		v = cec_read(cec, TEGRA_CEC_RX_REGISTER);
+		if (cec->rx_buf_cnt < CEC_MAX_MSG_SIZE)
+			cec->rx_buf[cec->rx_buf_cnt++] = v & 0xff;
+		if (v & TEGRA_CEC_RX_REGISTER_EOM) {
+			cec->rx_done = true;
+			return IRQ_WAKE_THREAD;
+		}
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int tegra_cec_adap_enable(struct cec_adapter *adap, bool enable)
+{
+	struct tegra_cec *cec = adap->priv;
+
+	cec->rx_buf_cnt = 0;
+	cec->tx_buf_cnt = 0;
+	cec->tx_buf_cur = 0;
+
+	cec_write(cec, TEGRA_CEC_HW_CONTROL, 0);
+	cec_write(cec, TEGRA_CEC_INT_MASK, 0);
+	cec_write(cec, TEGRA_CEC_INT_STAT, 0xffffffff);
+	cec_write(cec, TEGRA_CEC_SW_CONTROL, 0);
+
+	if (!enable)
+		return 0;
+
+	cec_write(cec, TEGRA_CEC_INPUT_FILTER, (1U << 31) | 0x20);
+
+	cec_write(cec, TEGRA_CEC_RX_TIMING_0,
+		  (0x7a << TEGRA_CEC_RX_TIM0_START_BIT_MAX_LO_TIME_SHIFT) |
+		  (0x6d << TEGRA_CEC_RX_TIM0_START_BIT_MIN_LO_TIME_SHIFT) |
+		  (0x93 << TEGRA_CEC_RX_TIM0_START_BIT_MAX_DURATION_SHIFT) |
+		  (0x86 << TEGRA_CEC_RX_TIM0_START_BIT_MIN_DURATION_SHIFT));
+
+	cec_write(cec, TEGRA_CEC_RX_TIMING_1,
+		  (0x35 << TEGRA_CEC_RX_TIM1_DATA_BIT_MAX_LO_TIME_SHIFT) |
+		  (0x21 << TEGRA_CEC_RX_TIM1_DATA_BIT_SAMPLE_TIME_SHIFT) |
+		  (0x56 << TEGRA_CEC_RX_TIM1_DATA_BIT_MAX_DURATION_SHIFT) |
+		  (0x40 << TEGRA_CEC_RX_TIM1_DATA_BIT_MIN_DURATION_SHIFT));
+
+	cec_write(cec, TEGRA_CEC_RX_TIMING_2,
+		  (0x50 << TEGRA_CEC_RX_TIM2_END_OF_BLOCK_TIME_SHIFT));
+
+	cec_write(cec, TEGRA_CEC_TX_TIMING_0,
+		  (0x74 << TEGRA_CEC_TX_TIM0_START_BIT_LO_TIME_SHIFT) |
+		  (0x8d << TEGRA_CEC_TX_TIM0_START_BIT_DURATION_SHIFT) |
+		  (0x08 << TEGRA_CEC_TX_TIM0_BUS_XITION_TIME_SHIFT) |
+		  (0x71 << TEGRA_CEC_TX_TIM0_BUS_ERROR_LO_TIME_SHIFT));
+
+	cec_write(cec, TEGRA_CEC_TX_TIMING_1,
+		  (0x2f << TEGRA_CEC_TX_TIM1_LO_DATA_BIT_LO_TIME_SHIFT) |
+		  (0x13 << TEGRA_CEC_TX_TIM1_HI_DATA_BIT_LO_TIME_SHIFT) |
+		  (0x4b << TEGRA_CEC_TX_TIM1_DATA_BIT_DURATION_SHIFT) |
+		  (0x21 << TEGRA_CEC_TX_TIM1_ACK_NAK_BIT_SAMPLE_TIME_SHIFT));
+
+	cec_write(cec, TEGRA_CEC_TX_TIMING_2,
+		  (0x07 << TEGRA_CEC_TX_TIM2_BUS_IDLE_TIME_ADDITIONAL_FRAME_SHIFT) |
+		  (0x05 << TEGRA_CEC_TX_TIM2_BUS_IDLE_TIME_NEW_FRAME_SHIFT) |
+		  (0x03 << TEGRA_CEC_TX_TIM2_BUS_IDLE_TIME_RETRY_FRAME_SHIFT));
+
+	cec_write(cec, TEGRA_CEC_INT_MASK,
+		  TEGRA_CEC_INT_MASK_TX_REGISTER_UNDERRUN |
+		  TEGRA_CEC_INT_MASK_TX_FRAME_OR_BLOCK_NAKD |
+		  TEGRA_CEC_INT_MASK_TX_ARBITRATION_FAILED |
+		  TEGRA_CEC_INT_MASK_TX_BUS_ANOMALY_DETECTED |
+		  TEGRA_CEC_INT_MASK_TX_FRAME_TRANSMITTED |
+		  TEGRA_CEC_INT_MASK_RX_REGISTER_FULL |
+		  TEGRA_CEC_INT_MASK_RX_START_BIT_DETECTED);
+
+	cec_write(cec, TEGRA_CEC_HW_CONTROL, TEGRA_CEC_HWCTRL_TX_RX_MODE);
+	return 0;
+}
+
+static int tegra_cec_adap_log_addr(struct cec_adapter *adap, u8 logical_addr)
+{
+	struct tegra_cec *cec = adap->priv;
+	u32 state = cec_read(cec, TEGRA_CEC_HW_CONTROL);
+
+	if (logical_addr == CEC_LOG_ADDR_INVALID)
+		state &= ~TEGRA_CEC_HWCTRL_RX_LADDR_MASK;
+	else
+		state |= TEGRA_CEC_HWCTRL_RX_LADDR((1 << logical_addr));
+
+	cec_write(cec, TEGRA_CEC_HW_CONTROL, state);
+	return 0;
+}
+
+static int tegra_cec_adap_monitor_all_enable(struct cec_adapter *adap,
+					     bool enable)
+{
+	struct tegra_cec *cec = adap->priv;
+	u32 reg = cec_read(cec, TEGRA_CEC_HW_CONTROL);
+
+	if (enable)
+		reg |= TEGRA_CEC_HWCTRL_RX_SNOOP;
+	else
+		reg &= ~TEGRA_CEC_HWCTRL_RX_SNOOP;
+	cec_write(cec, TEGRA_CEC_HW_CONTROL, reg);
+	return 0;
+}
+
+static int tegra_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
+				   u32 signal_free_time_ms, struct cec_msg *msg)
+{
+	bool retry_xfer = signal_free_time_ms == CEC_SIGNAL_FREE_TIME_RETRY;
+	struct tegra_cec *cec = adap->priv;
+	unsigned int i;
+	u32 mode = 0;
+	u32 mask;
+
+	if (cec_msg_is_broadcast(msg))
+		mode = TEGRA_CEC_TX_REG_BCAST;
+
+	cec->tx_buf_cur = 0;
+	cec->tx_buf_cnt = msg->len;
+
+	for (i = 0; i < msg->len; i++) {
+		cec->tx_buf[i] = mode | msg->msg[i];
+		if (i == 0)
+			cec->tx_buf[i] |= TEGRA_CEC_TX_REG_START_BIT;
+		if (i == msg->len - 1)
+			cec->tx_buf[i] |= TEGRA_CEC_TX_REG_EOM;
+		if (i == 0 && retry_xfer)
+			cec->tx_buf[i] |= TEGRA_CEC_TX_REG_RETRY;
+	}
+
+	mask = cec_read(cec, TEGRA_CEC_INT_MASK);
+	cec_write(cec, TEGRA_CEC_INT_MASK,
+		  mask | TEGRA_CEC_INT_MASK_TX_REGISTER_EMPTY);
+
+	return 0;
+}
+
+static const struct cec_adap_ops tegra_cec_ops = {
+	.adap_enable = tegra_cec_adap_enable,
+	.adap_log_addr = tegra_cec_adap_log_addr,
+	.adap_transmit = tegra_cec_adap_transmit,
+	.adap_monitor_all_enable = tegra_cec_adap_monitor_all_enable,
+};
+
+static int tegra_cec_probe(struct platform_device *pdev)
+{
+	struct device *hdmi_dev;
+	struct tegra_cec *cec;
+	struct resource *res;
+	int ret = 0;
+
+	hdmi_dev = cec_notifier_parse_hdmi_phandle(&pdev->dev);
+
+	if (IS_ERR(hdmi_dev))
+		return PTR_ERR(hdmi_dev);
+
+	cec = devm_kzalloc(&pdev->dev, sizeof(struct tegra_cec), GFP_KERNEL);
+
+	if (!cec)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	if (!res) {
+		dev_err(&pdev->dev,
+			"Unable to allocate resources for device\n");
+		return -EBUSY;
+	}
+
+	if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res),
+		pdev->name)) {
+		dev_err(&pdev->dev,
+			"Unable to request mem region for device\n");
+		return -EBUSY;
+	}
+
+	cec->tegra_cec_irq = platform_get_irq(pdev, 0);
+
+	if (cec->tegra_cec_irq <= 0)
+		return -EBUSY;
+
+	cec->cec_base = devm_ioremap(&pdev->dev, res->start,
+					     resource_size(res));
+
+	if (!cec->cec_base) {
+		dev_err(&pdev->dev, "Unable to grab IOs for device\n");
+		return -EBUSY;
+	}
+
+	cec->clk = devm_clk_get(&pdev->dev, "cec");
+
+	if (IS_ERR_OR_NULL(cec->clk)) {
+		dev_err(&pdev->dev, "Can't get clock for CEC\n");
+		return -ENOENT;
+	}
+
+	clk_prepare_enable(cec->clk);
+
+	/* set context info. */
+	cec->dev = &pdev->dev;
+
+	platform_set_drvdata(pdev, cec);
+
+	ret = devm_request_threaded_irq(&pdev->dev, cec->tegra_cec_irq,
+		tegra_cec_irq_handler, tegra_cec_irq_thread_handler,
+		0, "cec_irq", &pdev->dev);
+
+	if (ret) {
+		dev_err(&pdev->dev,
+			"Unable to request interrupt for device\n");
+		goto err_clk;
+	}
+
+	cec->adap = cec_allocate_adapter(&tegra_cec_ops, cec, TEGRA_CEC_NAME,
+			CEC_CAP_DEFAULTS | CEC_CAP_MONITOR_ALL |
+			CEC_CAP_CONNECTOR_INFO,
+			CEC_MAX_LOG_ADDRS);
+	if (IS_ERR(cec->adap)) {
+		ret = -ENOMEM;
+		dev_err(&pdev->dev, "Couldn't create cec adapter\n");
+		goto err_clk;
+	}
+
+	cec->notifier = cec_notifier_cec_adap_register(hdmi_dev, NULL,
+						       cec->adap);
+	if (!cec->notifier) {
+		ret = -ENOMEM;
+		goto err_adapter;
+	}
+
+	ret = cec_register_adapter(cec->adap, &pdev->dev);
+	if (ret) {
+		dev_err(&pdev->dev, "Couldn't register device\n");
+		goto err_notifier;
+	}
+
+	return 0;
+
+err_notifier:
+	cec_notifier_cec_adap_unregister(cec->notifier, cec->adap);
+err_adapter:
+	cec_delete_adapter(cec->adap);
+err_clk:
+	clk_disable_unprepare(cec->clk);
+	return ret;
+}
+
+static int tegra_cec_remove(struct platform_device *pdev)
+{
+	struct tegra_cec *cec = platform_get_drvdata(pdev);
+
+	clk_disable_unprepare(cec->clk);
+
+	cec_notifier_cec_adap_unregister(cec->notifier, cec->adap);
+	cec_unregister_adapter(cec->adap);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int tegra_cec_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct tegra_cec *cec = platform_get_drvdata(pdev);
+
+	clk_disable_unprepare(cec->clk);
+
+	dev_notice(&pdev->dev, "suspended\n");
+	return 0;
+}
+
+static int tegra_cec_resume(struct platform_device *pdev)
+{
+	struct tegra_cec *cec = platform_get_drvdata(pdev);
+
+	dev_notice(&pdev->dev, "Resuming\n");
+
+	clk_prepare_enable(cec->clk);
+
+	return 0;
+}
+#endif
+
+static const struct of_device_id tegra_cec_of_match[] = {
+	{ .compatible = "nvidia,tegra114-cec", },
+	{ .compatible = "nvidia,tegra124-cec", },
+	{ .compatible = "nvidia,tegra210-cec", },
+	{},
+};
+
+static struct platform_driver tegra_cec_driver = {
+	.driver = {
+		.name = TEGRA_CEC_NAME,
+		.of_match_table = of_match_ptr(tegra_cec_of_match),
+	},
+	.probe = tegra_cec_probe,
+	.remove = tegra_cec_remove,
+
+#ifdef CONFIG_PM
+	.suspend = tegra_cec_suspend,
+	.resume = tegra_cec_resume,
+#endif
+};
+
+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/cec/platform/tegra/tegra_cec.h b/drivers/media/cec/platform/tegra/tegra_cec.h
new file mode 100644
index 000000000000..8c370be38e1e
--- /dev/null
+++ b/drivers/media/cec/platform/tegra/tegra_cec.h
@@ -0,0 +1,116 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Tegra CEC register definitions
+ *
+ * The original 3.10 CEC driver using a custom API:
+ *
+ * Copyright (c) 2012-2015, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * Conversion to the CEC framework and to the mainline kernel:
+ *
+ * Copyright 2016-2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#ifndef TEGRA_CEC_H
+#define TEGRA_CEC_H
+
+/* CEC registers */
+#define TEGRA_CEC_SW_CONTROL	0x000
+#define TEGRA_CEC_HW_CONTROL	0x004
+#define TEGRA_CEC_INPUT_FILTER	0x008
+#define TEGRA_CEC_TX_REGISTER	0x010
+#define TEGRA_CEC_RX_REGISTER	0x014
+#define TEGRA_CEC_RX_TIMING_0	0x018
+#define TEGRA_CEC_RX_TIMING_1	0x01c
+#define TEGRA_CEC_RX_TIMING_2	0x020
+#define TEGRA_CEC_TX_TIMING_0	0x024
+#define TEGRA_CEC_TX_TIMING_1	0x028
+#define TEGRA_CEC_TX_TIMING_2	0x02c
+#define TEGRA_CEC_INT_STAT	0x030
+#define TEGRA_CEC_INT_MASK	0x034
+#define TEGRA_CEC_HW_DEBUG_RX	0x038
+#define TEGRA_CEC_HW_DEBUG_TX	0x03c
+
+#define TEGRA_CEC_HWCTRL_RX_LADDR_MASK				0x7fff
+#define TEGRA_CEC_HWCTRL_RX_LADDR(x)	\
+	((x) & TEGRA_CEC_HWCTRL_RX_LADDR_MASK)
+#define TEGRA_CEC_HWCTRL_RX_SNOOP				BIT(15)
+#define TEGRA_CEC_HWCTRL_RX_NAK_MODE				BIT(16)
+#define TEGRA_CEC_HWCTRL_TX_NAK_MODE				BIT(24)
+#define TEGRA_CEC_HWCTRL_FAST_SIM_MODE				BIT(30)
+#define TEGRA_CEC_HWCTRL_TX_RX_MODE				BIT(31)
+
+#define TEGRA_CEC_INPUT_FILTER_MODE				BIT(31)
+#define TEGRA_CEC_INPUT_FILTER_FIFO_LENGTH_SHIFT		0
+
+#define TEGRA_CEC_TX_REG_DATA_SHIFT				0
+#define TEGRA_CEC_TX_REG_EOM					BIT(8)
+#define TEGRA_CEC_TX_REG_BCAST					BIT(12)
+#define TEGRA_CEC_TX_REG_START_BIT				BIT(16)
+#define TEGRA_CEC_TX_REG_RETRY					BIT(17)
+
+#define TEGRA_CEC_RX_REGISTER_SHIFT				0
+#define TEGRA_CEC_RX_REGISTER_EOM				BIT(8)
+#define TEGRA_CEC_RX_REGISTER_ACK				BIT(9)
+
+#define TEGRA_CEC_RX_TIM0_START_BIT_MAX_LO_TIME_SHIFT		0
+#define TEGRA_CEC_RX_TIM0_START_BIT_MIN_LO_TIME_SHIFT		8
+#define TEGRA_CEC_RX_TIM0_START_BIT_MAX_DURATION_SHIFT		16
+#define TEGRA_CEC_RX_TIM0_START_BIT_MIN_DURATION_SHIFT		24
+
+#define TEGRA_CEC_RX_TIM1_DATA_BIT_MAX_LO_TIME_SHIFT		0
+#define TEGRA_CEC_RX_TIM1_DATA_BIT_SAMPLE_TIME_SHIFT		8
+#define TEGRA_CEC_RX_TIM1_DATA_BIT_MAX_DURATION_SHIFT		16
+#define TEGRA_CEC_RX_TIM1_DATA_BIT_MIN_DURATION_SHIFT		24
+
+#define TEGRA_CEC_RX_TIM2_END_OF_BLOCK_TIME_SHIFT		0
+
+#define TEGRA_CEC_TX_TIM0_START_BIT_LO_TIME_SHIFT		0
+#define TEGRA_CEC_TX_TIM0_START_BIT_DURATION_SHIFT		8
+#define TEGRA_CEC_TX_TIM0_BUS_XITION_TIME_SHIFT			16
+#define TEGRA_CEC_TX_TIM0_BUS_ERROR_LO_TIME_SHIFT		24
+
+#define TEGRA_CEC_TX_TIM1_LO_DATA_BIT_LO_TIME_SHIFT		0
+#define TEGRA_CEC_TX_TIM1_HI_DATA_BIT_LO_TIME_SHIFT		8
+#define TEGRA_CEC_TX_TIM1_DATA_BIT_DURATION_SHIFT		16
+#define TEGRA_CEC_TX_TIM1_ACK_NAK_BIT_SAMPLE_TIME_SHIFT		24
+
+#define TEGRA_CEC_TX_TIM2_BUS_IDLE_TIME_ADDITIONAL_FRAME_SHIFT	0
+#define TEGRA_CEC_TX_TIM2_BUS_IDLE_TIME_NEW_FRAME_SHIFT		4
+#define TEGRA_CEC_TX_TIM2_BUS_IDLE_TIME_RETRY_FRAME_SHIFT	8
+
+#define TEGRA_CEC_INT_STAT_TX_REGISTER_EMPTY			BIT(0)
+#define TEGRA_CEC_INT_STAT_TX_REGISTER_UNDERRUN			BIT(1)
+#define TEGRA_CEC_INT_STAT_TX_FRAME_OR_BLOCK_NAKD		BIT(2)
+#define TEGRA_CEC_INT_STAT_TX_ARBITRATION_FAILED		BIT(3)
+#define TEGRA_CEC_INT_STAT_TX_BUS_ANOMALY_DETECTED		BIT(4)
+#define TEGRA_CEC_INT_STAT_TX_FRAME_TRANSMITTED			BIT(5)
+#define TEGRA_CEC_INT_STAT_RX_REGISTER_FULL			BIT(8)
+#define TEGRA_CEC_INT_STAT_RX_REGISTER_OVERRUN			BIT(9)
+#define TEGRA_CEC_INT_STAT_RX_START_BIT_DETECTED		BIT(10)
+#define TEGRA_CEC_INT_STAT_RX_BUS_ANOMALY_DETECTED		BIT(11)
+#define TEGRA_CEC_INT_STAT_RX_BUS_ERROR_DETECTED		BIT(12)
+#define TEGRA_CEC_INT_STAT_FILTERED_RX_DATA_PIN_TRANSITION_H2L	BIT(13)
+#define TEGRA_CEC_INT_STAT_FILTERED_RX_DATA_PIN_TRANSITION_L2H	BIT(14)
+
+#define TEGRA_CEC_INT_MASK_TX_REGISTER_EMPTY			BIT(0)
+#define TEGRA_CEC_INT_MASK_TX_REGISTER_UNDERRUN			BIT(1)
+#define TEGRA_CEC_INT_MASK_TX_FRAME_OR_BLOCK_NAKD		BIT(2)
+#define TEGRA_CEC_INT_MASK_TX_ARBITRATION_FAILED		BIT(3)
+#define TEGRA_CEC_INT_MASK_TX_BUS_ANOMALY_DETECTED		BIT(4)
+#define TEGRA_CEC_INT_MASK_TX_FRAME_TRANSMITTED			BIT(5)
+#define TEGRA_CEC_INT_MASK_RX_REGISTER_FULL			BIT(8)
+#define TEGRA_CEC_INT_MASK_RX_REGISTER_OVERRUN			BIT(9)
+#define TEGRA_CEC_INT_MASK_RX_START_BIT_DETECTED		BIT(10)
+#define TEGRA_CEC_INT_MASK_RX_BUS_ANOMALY_DETECTED		BIT(11)
+#define TEGRA_CEC_INT_MASK_RX_BUS_ERROR_DETECTED		BIT(12)
+#define TEGRA_CEC_INT_MASK_FILTERED_RX_DATA_PIN_TRANSITION_H2L	BIT(13)
+#define TEGRA_CEC_INT_MASK_FILTERED_RX_DATA_PIN_TRANSITION_L2H	BIT(14)
+
+#define TEGRA_CEC_HW_DEBUG_TX_DURATION_COUNT_SHIFT		0
+#define TEGRA_CEC_HW_DEBUG_TX_TXBIT_COUNT_SHIFT			17
+#define TEGRA_CEC_HW_DEBUG_TX_STATE_SHIFT			21
+#define TEGRA_CEC_HW_DEBUG_TX_FORCELOOUT			BIT(25)
+#define TEGRA_CEC_HW_DEBUG_TX_TXDATABIT_SAMPLE_TIMER		BIT(26)
+
+#endif /* TEGRA_CEC_H */
diff --git a/drivers/media/cec/usb/Kconfig b/drivers/media/cec/usb/Kconfig
new file mode 100644
index 000000000000..d3bbef464bdb
--- /dev/null
+++ b/drivers/media/cec/usb/Kconfig
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# USB drivers
+
+source "drivers/media/cec/usb/pulse8/Kconfig"
+source "drivers/media/cec/usb/rainshadow/Kconfig"
diff --git a/drivers/media/cec/usb/Makefile b/drivers/media/cec/usb/Makefile
new file mode 100644
index 000000000000..e4183d1bfa9a
--- /dev/null
+++ b/drivers/media/cec/usb/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the CEC USB device drivers.
+#
+obj-$(CONFIG_USB_PULSE8_CEC) += pulse8/
+obj-$(CONFIG_USB_RAINSHADOW_CEC) += rainshadow/
diff --git a/drivers/media/cec/usb/pulse8/Kconfig b/drivers/media/cec/usb/pulse8/Kconfig
new file mode 100644
index 000000000000..a0224ef80e6c
--- /dev/null
+++ b/drivers/media/cec/usb/pulse8/Kconfig
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config USB_PULSE8_CEC
+	tristate "Pulse Eight HDMI CEC"
+	select CEC_CORE
+	select USB
+	select USB_ACM
+	select SERIO
+	select SERIO_SERPORT
+	help
+	  This is a cec driver for the Pulse Eight HDMI CEC device.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called pulse8-cec.
diff --git a/drivers/media/cec/usb/pulse8/Makefile b/drivers/media/cec/usb/pulse8/Makefile
new file mode 100644
index 000000000000..7816c68bf928
--- /dev/null
+++ b/drivers/media/cec/usb/pulse8/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_USB_PULSE8_CEC) += pulse8-cec.o
diff --git a/drivers/media/cec/usb/pulse8/pulse8-cec.c b/drivers/media/cec/usb/pulse8/pulse8-cec.c
new file mode 100644
index 000000000000..0655aa9ecf28
--- /dev/null
+++ b/drivers/media/cec/usb/pulse8/pulse8-cec.c
@@ -0,0 +1,909 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Pulse Eight HDMI CEC driver
+ *
+ * Copyright 2016 Hans Verkuil <hverkuil@xs4all.nl
+ */
+
+/*
+ * Notes:
+ *
+ * - Devices with firmware version < 2 do not store their configuration in
+ *   EEPROM.
+ *
+ * - In autonomous mode, only messages from a TV will be acknowledged, even
+ *   polling messages. Upon receiving a message from a TV, the dongle will
+ *   respond to messages from any logical address.
+ *
+ * - In autonomous mode, the dongle will by default reply Feature Abort
+ *   [Unrecognized Opcode] when it receives Give Device Vendor ID. It will
+ *   however observe vendor ID's reported by other devices and possibly
+ *   alter this behavior. When TV's (and TV's only) report that their vendor ID
+ *   is LG (0x00e091), the dongle will itself reply that it has the same vendor
+ *   ID, and it will respond to at least one vendor specific command.
+ *
+ * - In autonomous mode, the dongle is known to attempt wakeup if it receives
+ *   <User Control Pressed> ["Power On"], ["Power] or ["Power Toggle"], or if it
+ *   receives <Set Stream Path> with its own physical address. It also does this
+ *   if it receives <Vendor Specific Command> [0x03 0x00] from an LG TV.
+ */
+
+#include <linux/completion.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/workqueue.h>
+#include <linux/serio.h>
+#include <linux/slab.h>
+#include <linux/time.h>
+#include <linux/delay.h>
+
+#include <media/cec.h>
+
+MODULE_AUTHOR("Hans Verkuil <hverkuil@xs4all.nl>");
+MODULE_DESCRIPTION("Pulse Eight HDMI CEC driver");
+MODULE_LICENSE("GPL");
+
+static int debug;
+static int persistent_config;
+module_param(debug, int, 0644);
+module_param(persistent_config, int, 0644);
+MODULE_PARM_DESC(debug, "debug level (0-2)");
+MODULE_PARM_DESC(persistent_config, "read config from persistent memory (0-1)");
+
+enum pulse8_msgcodes {
+	MSGCODE_NOTHING = 0,
+	MSGCODE_PING,
+	MSGCODE_TIMEOUT_ERROR,
+	MSGCODE_HIGH_ERROR,
+	MSGCODE_LOW_ERROR,
+	MSGCODE_FRAME_START,
+	MSGCODE_FRAME_DATA,
+	MSGCODE_RECEIVE_FAILED,
+	MSGCODE_COMMAND_ACCEPTED,	/* 0x08 */
+	MSGCODE_COMMAND_REJECTED,
+	MSGCODE_SET_ACK_MASK,
+	MSGCODE_TRANSMIT,
+	MSGCODE_TRANSMIT_EOM,
+	MSGCODE_TRANSMIT_IDLETIME,
+	MSGCODE_TRANSMIT_ACK_POLARITY,
+	MSGCODE_TRANSMIT_LINE_TIMEOUT,
+	MSGCODE_TRANSMIT_SUCCEEDED,	/* 0x10 */
+	MSGCODE_TRANSMIT_FAILED_LINE,
+	MSGCODE_TRANSMIT_FAILED_ACK,
+	MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA,
+	MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE,
+	MSGCODE_FIRMWARE_VERSION,
+	MSGCODE_START_BOOTLOADER,
+	MSGCODE_GET_BUILDDATE,
+	MSGCODE_SET_CONTROLLED,		/* 0x18 */
+	MSGCODE_GET_AUTO_ENABLED,
+	MSGCODE_SET_AUTO_ENABLED,
+	MSGCODE_GET_DEFAULT_LOGICAL_ADDRESS,
+	MSGCODE_SET_DEFAULT_LOGICAL_ADDRESS,
+	MSGCODE_GET_LOGICAL_ADDRESS_MASK,
+	MSGCODE_SET_LOGICAL_ADDRESS_MASK,
+	MSGCODE_GET_PHYSICAL_ADDRESS,
+	MSGCODE_SET_PHYSICAL_ADDRESS,	/* 0x20 */
+	MSGCODE_GET_DEVICE_TYPE,
+	MSGCODE_SET_DEVICE_TYPE,
+	MSGCODE_GET_HDMI_VERSION,
+	MSGCODE_SET_HDMI_VERSION,
+	MSGCODE_GET_OSD_NAME,
+	MSGCODE_SET_OSD_NAME,
+	MSGCODE_WRITE_EEPROM,
+	MSGCODE_GET_ADAPTER_TYPE,	/* 0x28 */
+	MSGCODE_SET_ACTIVE_SOURCE,
+
+	MSGCODE_FRAME_EOM = 0x80,
+	MSGCODE_FRAME_ACK = 0x40,
+};
+
+static const char * const pulse8_msgnames[] = {
+	"NOTHING",
+	"PING",
+	"TIMEOUT_ERROR",
+	"HIGH_ERROR",
+	"LOW_ERROR",
+	"FRAME_START",
+	"FRAME_DATA",
+	"RECEIVE_FAILED",
+	"COMMAND_ACCEPTED",
+	"COMMAND_REJECTED",
+	"SET_ACK_MASK",
+	"TRANSMIT",
+	"TRANSMIT_EOM",
+	"TRANSMIT_IDLETIME",
+	"TRANSMIT_ACK_POLARITY",
+	"TRANSMIT_LINE_TIMEOUT",
+	"TRANSMIT_SUCCEEDED",
+	"TRANSMIT_FAILED_LINE",
+	"TRANSMIT_FAILED_ACK",
+	"TRANSMIT_FAILED_TIMEOUT_DATA",
+	"TRANSMIT_FAILED_TIMEOUT_LINE",
+	"FIRMWARE_VERSION",
+	"START_BOOTLOADER",
+	"GET_BUILDDATE",
+	"SET_CONTROLLED",
+	"GET_AUTO_ENABLED",
+	"SET_AUTO_ENABLED",
+	"GET_DEFAULT_LOGICAL_ADDRESS",
+	"SET_DEFAULT_LOGICAL_ADDRESS",
+	"GET_LOGICAL_ADDRESS_MASK",
+	"SET_LOGICAL_ADDRESS_MASK",
+	"GET_PHYSICAL_ADDRESS",
+	"SET_PHYSICAL_ADDRESS",
+	"GET_DEVICE_TYPE",
+	"SET_DEVICE_TYPE",
+	"GET_HDMI_VERSION",
+	"SET_HDMI_VERSION",
+	"GET_OSD_NAME",
+	"SET_OSD_NAME",
+	"WRITE_EEPROM",
+	"GET_ADAPTER_TYPE",
+	"SET_ACTIVE_SOURCE",
+};
+
+static const char *pulse8_msgname(u8 cmd)
+{
+	static char unknown_msg[5];
+
+	if ((cmd & 0x3f) < ARRAY_SIZE(pulse8_msgnames))
+		return pulse8_msgnames[cmd & 0x3f];
+	snprintf(unknown_msg, sizeof(unknown_msg), "0x%02x", cmd);
+	return unknown_msg;
+}
+
+#define MSGSTART	0xff
+#define MSGEND		0xfe
+#define MSGESC		0xfd
+#define MSGOFFSET	3
+
+#define DATA_SIZE 256
+
+#define PING_PERIOD	(15 * HZ)
+
+#define NUM_MSGS 8
+
+struct pulse8 {
+	struct device *dev;
+	struct serio *serio;
+	struct cec_adapter *adap;
+	unsigned int vers;
+
+	struct delayed_work ping_eeprom_work;
+
+	struct work_struct irq_work;
+	struct cec_msg rx_msg[NUM_MSGS];
+	unsigned int rx_msg_cur_idx, rx_msg_num;
+	/* protect rx_msg_cur_idx and rx_msg_num */
+	spinlock_t msg_lock;
+	u8 new_rx_msg[CEC_MAX_MSG_SIZE];
+	u8 new_rx_msg_len;
+
+	struct work_struct tx_work;
+	u32 tx_done_status;
+	u32 tx_signal_free_time;
+	struct cec_msg tx_msg;
+	bool tx_msg_is_bcast;
+
+	struct completion cmd_done;
+	u8 data[DATA_SIZE];
+	unsigned int len;
+	u8 buf[DATA_SIZE];
+	unsigned int idx;
+	bool escape;
+	bool started;
+
+	/* locks access to the adapter */
+	struct mutex lock;
+	bool config_pending;
+	bool restoring_config;
+	bool autonomous;
+};
+
+static int pulse8_send(struct serio *serio, const u8 *command, u8 cmd_len)
+{
+	int err = 0;
+
+	err = serio_write(serio, MSGSTART);
+	if (err)
+		return err;
+	for (; !err && cmd_len; command++, cmd_len--) {
+		if (*command >= MSGESC) {
+			err = serio_write(serio, MSGESC);
+			if (!err)
+				err = serio_write(serio, *command - MSGOFFSET);
+		} else {
+			err = serio_write(serio, *command);
+		}
+	}
+	if (!err)
+		err = serio_write(serio, MSGEND);
+
+	return err;
+}
+
+static int pulse8_send_and_wait_once(struct pulse8 *pulse8,
+				     const u8 *cmd, u8 cmd_len,
+				     u8 response, u8 size)
+{
+	int err;
+
+	if (debug > 1)
+		dev_info(pulse8->dev, "transmit %s: %*ph\n",
+			 pulse8_msgname(cmd[0]), cmd_len, cmd);
+	init_completion(&pulse8->cmd_done);
+
+	err = pulse8_send(pulse8->serio, cmd, cmd_len);
+	if (err)
+		return err;
+
+	if (!wait_for_completion_timeout(&pulse8->cmd_done, HZ))
+		return -ETIMEDOUT;
+	if ((pulse8->data[0] & 0x3f) == MSGCODE_COMMAND_REJECTED &&
+	    cmd[0] != MSGCODE_SET_CONTROLLED &&
+	    cmd[0] != MSGCODE_SET_AUTO_ENABLED &&
+	    cmd[0] != MSGCODE_GET_BUILDDATE)
+		return -ENOTTY;
+	if (response &&
+	    ((pulse8->data[0] & 0x3f) != response || pulse8->len < size + 1)) {
+		dev_info(pulse8->dev, "transmit %s failed with %s\n",
+			 pulse8_msgname(cmd[0]),
+			 pulse8_msgname(pulse8->data[0]));
+		return -EIO;
+	}
+	return 0;
+}
+
+static int pulse8_send_and_wait(struct pulse8 *pulse8,
+				const u8 *cmd, u8 cmd_len, u8 response, u8 size)
+{
+	u8 cmd_sc[2];
+	int err;
+
+	err = pulse8_send_and_wait_once(pulse8, cmd, cmd_len, response, size);
+	if (err != -ENOTTY)
+		return err;
+
+	cmd_sc[0] = MSGCODE_SET_CONTROLLED;
+	cmd_sc[1] = 1;
+	err = pulse8_send_and_wait_once(pulse8, cmd_sc, 2,
+					MSGCODE_COMMAND_ACCEPTED, 1);
+	if (!err)
+		err = pulse8_send_and_wait_once(pulse8, cmd, cmd_len,
+						response, size);
+	return err == -ENOTTY ? -EIO : err;
+}
+
+static void pulse8_tx_work_handler(struct work_struct *work)
+{
+	struct pulse8 *pulse8 = container_of(work, struct pulse8, tx_work);
+	struct cec_msg *msg = &pulse8->tx_msg;
+	unsigned int i;
+	u8 cmd[2];
+	int err;
+
+	if (msg->len == 0)
+		return;
+
+	mutex_lock(&pulse8->lock);
+	cmd[0] = MSGCODE_TRANSMIT_IDLETIME;
+	cmd[1] = pulse8->tx_signal_free_time;
+	err = pulse8_send_and_wait(pulse8, cmd, 2,
+				   MSGCODE_COMMAND_ACCEPTED, 1);
+	cmd[0] = MSGCODE_TRANSMIT_ACK_POLARITY;
+	cmd[1] = cec_msg_is_broadcast(msg);
+	pulse8->tx_msg_is_bcast = cec_msg_is_broadcast(msg);
+	if (!err)
+		err = pulse8_send_and_wait(pulse8, cmd, 2,
+					   MSGCODE_COMMAND_ACCEPTED, 1);
+	cmd[0] = msg->len == 1 ? MSGCODE_TRANSMIT_EOM : MSGCODE_TRANSMIT;
+	cmd[1] = msg->msg[0];
+	if (!err)
+		err = pulse8_send_and_wait(pulse8, cmd, 2,
+					   MSGCODE_COMMAND_ACCEPTED, 1);
+	if (!err && msg->len > 1) {
+		for (i = 1; !err && i < msg->len; i++) {
+			cmd[0] = ((i == msg->len - 1)) ?
+				MSGCODE_TRANSMIT_EOM : MSGCODE_TRANSMIT;
+			cmd[1] = msg->msg[i];
+			err = pulse8_send_and_wait(pulse8, cmd, 2,
+						   MSGCODE_COMMAND_ACCEPTED, 1);
+		}
+	}
+	if (err && debug)
+		dev_info(pulse8->dev, "%s(0x%02x) failed with error %d for msg %*ph\n",
+			 pulse8_msgname(cmd[0]), cmd[1],
+			 err, msg->len, msg->msg);
+	msg->len = 0;
+	mutex_unlock(&pulse8->lock);
+	if (err)
+		cec_transmit_attempt_done(pulse8->adap, CEC_TX_STATUS_ERROR);
+}
+
+static void pulse8_irq_work_handler(struct work_struct *work)
+{
+	struct pulse8 *pulse8 =
+		container_of(work, struct pulse8, irq_work);
+	unsigned long flags;
+	u32 status;
+
+	spin_lock_irqsave(&pulse8->msg_lock, flags);
+	while (pulse8->rx_msg_num) {
+		spin_unlock_irqrestore(&pulse8->msg_lock, flags);
+		if (debug)
+			dev_info(pulse8->dev, "adap received %*ph\n",
+				 pulse8->rx_msg[pulse8->rx_msg_cur_idx].len,
+				 pulse8->rx_msg[pulse8->rx_msg_cur_idx].msg);
+		cec_received_msg(pulse8->adap,
+				 &pulse8->rx_msg[pulse8->rx_msg_cur_idx]);
+		spin_lock_irqsave(&pulse8->msg_lock, flags);
+		if (pulse8->rx_msg_num)
+			pulse8->rx_msg_num--;
+		pulse8->rx_msg_cur_idx =
+			(pulse8->rx_msg_cur_idx + 1) % NUM_MSGS;
+	}
+	spin_unlock_irqrestore(&pulse8->msg_lock, flags);
+
+	mutex_lock(&pulse8->lock);
+	status = pulse8->tx_done_status;
+	pulse8->tx_done_status = 0;
+	mutex_unlock(&pulse8->lock);
+	if (status)
+		cec_transmit_attempt_done(pulse8->adap, status);
+}
+
+static irqreturn_t pulse8_interrupt(struct serio *serio, unsigned char data,
+				    unsigned int flags)
+{
+	struct pulse8 *pulse8 = serio_get_drvdata(serio);
+	unsigned long irq_flags;
+	unsigned int idx;
+
+	if (!pulse8->started && data != MSGSTART)
+		return IRQ_HANDLED;
+	if (data == MSGESC) {
+		pulse8->escape = true;
+		return IRQ_HANDLED;
+	}
+	if (pulse8->escape) {
+		data += MSGOFFSET;
+		pulse8->escape = false;
+	} else if (data == MSGEND) {
+		u8 msgcode = pulse8->buf[0];
+
+		if (debug > 1)
+			dev_info(pulse8->dev, "received %s: %*ph\n",
+				 pulse8_msgname(msgcode),
+				 pulse8->idx, pulse8->buf);
+		switch (msgcode & 0x3f) {
+		case MSGCODE_FRAME_START:
+			/*
+			 * Test if we are receiving a new msg when a previous
+			 * message is still pending.
+			 */
+			if (!(msgcode & MSGCODE_FRAME_EOM)) {
+				pulse8->new_rx_msg_len = 1;
+				pulse8->new_rx_msg[0] = pulse8->buf[1];
+				break;
+			}
+			/* fall through */
+		case MSGCODE_FRAME_DATA:
+			if (pulse8->new_rx_msg_len < CEC_MAX_MSG_SIZE)
+				pulse8->new_rx_msg[pulse8->new_rx_msg_len++] =
+					pulse8->buf[1];
+			if (!(msgcode & MSGCODE_FRAME_EOM))
+				break;
+
+			spin_lock_irqsave(&pulse8->msg_lock, irq_flags);
+			idx = (pulse8->rx_msg_cur_idx + pulse8->rx_msg_num) %
+				NUM_MSGS;
+			if (pulse8->rx_msg_num == NUM_MSGS) {
+				dev_warn(pulse8->dev,
+					 "message queue is full, dropping %*ph\n",
+					 pulse8->new_rx_msg_len,
+					 pulse8->new_rx_msg);
+				spin_unlock_irqrestore(&pulse8->msg_lock,
+						       irq_flags);
+				pulse8->new_rx_msg_len = 0;
+				break;
+			}
+			pulse8->rx_msg_num++;
+			memcpy(pulse8->rx_msg[idx].msg, pulse8->new_rx_msg,
+			       pulse8->new_rx_msg_len);
+			pulse8->rx_msg[idx].len = pulse8->new_rx_msg_len;
+			spin_unlock_irqrestore(&pulse8->msg_lock, irq_flags);
+			schedule_work(&pulse8->irq_work);
+			pulse8->new_rx_msg_len = 0;
+			break;
+		case MSGCODE_TRANSMIT_SUCCEEDED:
+			WARN_ON(pulse8->tx_done_status);
+			pulse8->tx_done_status = CEC_TX_STATUS_OK;
+			schedule_work(&pulse8->irq_work);
+			break;
+		case MSGCODE_TRANSMIT_FAILED_ACK:
+			/*
+			 * A NACK for a broadcast message makes no sense, these
+			 * seem to be spurious messages and are skipped.
+			 */
+			if (pulse8->tx_msg_is_bcast)
+				break;
+			WARN_ON(pulse8->tx_done_status);
+			pulse8->tx_done_status = CEC_TX_STATUS_NACK;
+			schedule_work(&pulse8->irq_work);
+			break;
+		case MSGCODE_TRANSMIT_FAILED_LINE:
+		case MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA:
+		case MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE:
+			WARN_ON(pulse8->tx_done_status);
+			pulse8->tx_done_status = CEC_TX_STATUS_ERROR;
+			schedule_work(&pulse8->irq_work);
+			break;
+		case MSGCODE_HIGH_ERROR:
+		case MSGCODE_LOW_ERROR:
+		case MSGCODE_RECEIVE_FAILED:
+		case MSGCODE_TIMEOUT_ERROR:
+			pulse8->new_rx_msg_len = 0;
+			break;
+		case MSGCODE_COMMAND_ACCEPTED:
+		case MSGCODE_COMMAND_REJECTED:
+		default:
+			if (pulse8->idx == 0)
+				break;
+			memcpy(pulse8->data, pulse8->buf, pulse8->idx);
+			pulse8->len = pulse8->idx;
+			complete(&pulse8->cmd_done);
+			break;
+		}
+		pulse8->idx = 0;
+		pulse8->started = false;
+		return IRQ_HANDLED;
+	} else if (data == MSGSTART) {
+		pulse8->idx = 0;
+		pulse8->started = true;
+		return IRQ_HANDLED;
+	}
+
+	if (pulse8->idx >= DATA_SIZE) {
+		dev_dbg(pulse8->dev,
+			"throwing away %d bytes of garbage\n", pulse8->idx);
+		pulse8->idx = 0;
+	}
+	pulse8->buf[pulse8->idx++] = data;
+	return IRQ_HANDLED;
+}
+
+static int pulse8_cec_adap_enable(struct cec_adapter *adap, bool enable)
+{
+	struct pulse8 *pulse8 = cec_get_drvdata(adap);
+	u8 cmd[16];
+	int err;
+
+	mutex_lock(&pulse8->lock);
+	cmd[0] = MSGCODE_SET_CONTROLLED;
+	cmd[1] = enable;
+	err = pulse8_send_and_wait(pulse8, cmd, 2,
+				   MSGCODE_COMMAND_ACCEPTED, 1);
+	if (!enable) {
+		pulse8->rx_msg_num = 0;
+		pulse8->tx_done_status = 0;
+	}
+	mutex_unlock(&pulse8->lock);
+	return enable ? err : 0;
+}
+
+static int pulse8_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr)
+{
+	struct pulse8 *pulse8 = cec_get_drvdata(adap);
+	u16 mask = 0;
+	u16 pa = adap->phys_addr;
+	u8 cmd[16];
+	int err = 0;
+
+	mutex_lock(&pulse8->lock);
+	if (log_addr != CEC_LOG_ADDR_INVALID)
+		mask = 1 << log_addr;
+	cmd[0] = MSGCODE_SET_ACK_MASK;
+	cmd[1] = mask >> 8;
+	cmd[2] = mask & 0xff;
+	err = pulse8_send_and_wait(pulse8, cmd, 3,
+				   MSGCODE_COMMAND_ACCEPTED, 0);
+	if ((err && mask != 0) || pulse8->restoring_config)
+		goto unlock;
+
+	cmd[0] = MSGCODE_SET_AUTO_ENABLED;
+	cmd[1] = log_addr == CEC_LOG_ADDR_INVALID ? 0 : 1;
+	err = pulse8_send_and_wait(pulse8, cmd, 2,
+				   MSGCODE_COMMAND_ACCEPTED, 0);
+	if (err)
+		goto unlock;
+	pulse8->autonomous = cmd[1];
+	if (log_addr == CEC_LOG_ADDR_INVALID)
+		goto unlock;
+
+	cmd[0] = MSGCODE_SET_DEVICE_TYPE;
+	cmd[1] = adap->log_addrs.primary_device_type[0];
+	err = pulse8_send_and_wait(pulse8, cmd, 2,
+				   MSGCODE_COMMAND_ACCEPTED, 0);
+	if (err)
+		goto unlock;
+
+	switch (adap->log_addrs.primary_device_type[0]) {
+	case CEC_OP_PRIM_DEVTYPE_TV:
+		mask = CEC_LOG_ADDR_MASK_TV;
+		break;
+	case CEC_OP_PRIM_DEVTYPE_RECORD:
+		mask = CEC_LOG_ADDR_MASK_RECORD;
+		break;
+	case CEC_OP_PRIM_DEVTYPE_TUNER:
+		mask = CEC_LOG_ADDR_MASK_TUNER;
+		break;
+	case CEC_OP_PRIM_DEVTYPE_PLAYBACK:
+		mask = CEC_LOG_ADDR_MASK_PLAYBACK;
+		break;
+	case CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM:
+		mask = CEC_LOG_ADDR_MASK_AUDIOSYSTEM;
+		break;
+	case CEC_OP_PRIM_DEVTYPE_SWITCH:
+		mask = CEC_LOG_ADDR_MASK_UNREGISTERED;
+		break;
+	case CEC_OP_PRIM_DEVTYPE_PROCESSOR:
+		mask = CEC_LOG_ADDR_MASK_SPECIFIC;
+		break;
+	default:
+		mask = 0;
+		break;
+	}
+	cmd[0] = MSGCODE_SET_LOGICAL_ADDRESS_MASK;
+	cmd[1] = mask >> 8;
+	cmd[2] = mask & 0xff;
+	err = pulse8_send_and_wait(pulse8, cmd, 3,
+				   MSGCODE_COMMAND_ACCEPTED, 0);
+	if (err)
+		goto unlock;
+
+	cmd[0] = MSGCODE_SET_DEFAULT_LOGICAL_ADDRESS;
+	cmd[1] = log_addr;
+	err = pulse8_send_and_wait(pulse8, cmd, 2,
+				   MSGCODE_COMMAND_ACCEPTED, 0);
+	if (err)
+		goto unlock;
+
+	cmd[0] = MSGCODE_SET_PHYSICAL_ADDRESS;
+	cmd[1] = pa >> 8;
+	cmd[2] = pa & 0xff;
+	err = pulse8_send_and_wait(pulse8, cmd, 3,
+				   MSGCODE_COMMAND_ACCEPTED, 0);
+	if (err)
+		goto unlock;
+
+	cmd[0] = MSGCODE_SET_HDMI_VERSION;
+	cmd[1] = adap->log_addrs.cec_version;
+	err = pulse8_send_and_wait(pulse8, cmd, 2,
+				   MSGCODE_COMMAND_ACCEPTED, 0);
+	if (err)
+		goto unlock;
+
+	if (adap->log_addrs.osd_name[0]) {
+		size_t osd_len = strlen(adap->log_addrs.osd_name);
+		char *osd_str = cmd + 1;
+
+		cmd[0] = MSGCODE_SET_OSD_NAME;
+		strscpy(cmd + 1, adap->log_addrs.osd_name, sizeof(cmd) - 1);
+		if (osd_len < 4) {
+			memset(osd_str + osd_len, ' ', 4 - osd_len);
+			osd_len = 4;
+			osd_str[osd_len] = '\0';
+			strscpy(adap->log_addrs.osd_name, osd_str,
+				sizeof(adap->log_addrs.osd_name));
+		}
+		err = pulse8_send_and_wait(pulse8, cmd, 1 + osd_len,
+					   MSGCODE_COMMAND_ACCEPTED, 0);
+		if (err)
+			goto unlock;
+	}
+
+unlock:
+	if (pulse8->restoring_config)
+		pulse8->restoring_config = false;
+	else
+		pulse8->config_pending = true;
+	mutex_unlock(&pulse8->lock);
+	return log_addr == CEC_LOG_ADDR_INVALID ? 0 : err;
+}
+
+static int pulse8_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
+				    u32 signal_free_time, struct cec_msg *msg)
+{
+	struct pulse8 *pulse8 = cec_get_drvdata(adap);
+
+	pulse8->tx_msg = *msg;
+	if (debug)
+		dev_info(pulse8->dev, "adap transmit %*ph\n",
+			 msg->len, msg->msg);
+	pulse8->tx_signal_free_time = signal_free_time;
+	schedule_work(&pulse8->tx_work);
+	return 0;
+}
+
+static void pulse8_cec_adap_free(struct cec_adapter *adap)
+{
+	struct pulse8 *pulse8 = cec_get_drvdata(adap);
+
+	cancel_delayed_work_sync(&pulse8->ping_eeprom_work);
+	cancel_work_sync(&pulse8->irq_work);
+	cancel_work_sync(&pulse8->tx_work);
+	kfree(pulse8);
+}
+
+static const struct cec_adap_ops pulse8_cec_adap_ops = {
+	.adap_enable = pulse8_cec_adap_enable,
+	.adap_log_addr = pulse8_cec_adap_log_addr,
+	.adap_transmit = pulse8_cec_adap_transmit,
+	.adap_free = pulse8_cec_adap_free,
+};
+
+static void pulse8_disconnect(struct serio *serio)
+{
+	struct pulse8 *pulse8 = serio_get_drvdata(serio);
+
+	cec_unregister_adapter(pulse8->adap);
+	pulse8->serio = NULL;
+	serio_set_drvdata(serio, NULL);
+	serio_close(serio);
+}
+
+static int pulse8_setup(struct pulse8 *pulse8, struct serio *serio,
+			struct cec_log_addrs *log_addrs, u16 *pa)
+{
+	u8 *data = pulse8->data + 1;
+	u8 cmd[2];
+	int err;
+	struct tm tm;
+	time64_t date;
+
+	pulse8->vers = 0;
+
+	cmd[0] = MSGCODE_FIRMWARE_VERSION;
+	err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 2);
+	if (err)
+		return err;
+	pulse8->vers = (data[0] << 8) | data[1];
+	dev_info(pulse8->dev, "Firmware version %04x\n", pulse8->vers);
+	if (pulse8->vers < 2) {
+		*pa = CEC_PHYS_ADDR_INVALID;
+		return 0;
+	}
+
+	cmd[0] = MSGCODE_GET_BUILDDATE;
+	err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 4);
+	if (err)
+		return err;
+	date = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
+	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);
+
+	dev_dbg(pulse8->dev, "Persistent config:\n");
+	cmd[0] = MSGCODE_GET_AUTO_ENABLED;
+	err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 1);
+	if (err)
+		return err;
+	pulse8->autonomous = data[0];
+	dev_dbg(pulse8->dev, "Autonomous mode: %s",
+		data[0] ? "on" : "off");
+
+	cmd[0] = MSGCODE_GET_DEVICE_TYPE;
+	err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 1);
+	if (err)
+		return err;
+	log_addrs->primary_device_type[0] = data[0];
+	dev_dbg(pulse8->dev, "Primary device type: %d\n", data[0]);
+	switch (log_addrs->primary_device_type[0]) {
+	case CEC_OP_PRIM_DEVTYPE_TV:
+		log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_TV;
+		log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_TV;
+		break;
+	case CEC_OP_PRIM_DEVTYPE_RECORD:
+		log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_RECORD;
+		log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_RECORD;
+		break;
+	case CEC_OP_PRIM_DEVTYPE_TUNER:
+		log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_TUNER;
+		log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_TUNER;
+		break;
+	case CEC_OP_PRIM_DEVTYPE_PLAYBACK:
+		log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_PLAYBACK;
+		log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_PLAYBACK;
+		break;
+	case CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM:
+		log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_PLAYBACK;
+		log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_AUDIOSYSTEM;
+		break;
+	case CEC_OP_PRIM_DEVTYPE_SWITCH:
+		log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_UNREGISTERED;
+		log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_SWITCH;
+		break;
+	case CEC_OP_PRIM_DEVTYPE_PROCESSOR:
+		log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_SPECIFIC;
+		log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_SWITCH;
+		break;
+	default:
+		log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_UNREGISTERED;
+		log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_SWITCH;
+		dev_info(pulse8->dev, "Unknown Primary Device Type: %d\n",
+			 log_addrs->primary_device_type[0]);
+		break;
+	}
+
+	cmd[0] = MSGCODE_GET_LOGICAL_ADDRESS_MASK;
+	err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 2);
+	if (err)
+		return err;
+	log_addrs->log_addr_mask = (data[0] << 8) | data[1];
+	dev_dbg(pulse8->dev, "Logical address ACK mask: %x\n",
+		log_addrs->log_addr_mask);
+	if (log_addrs->log_addr_mask)
+		log_addrs->num_log_addrs = 1;
+
+	cmd[0] = MSGCODE_GET_PHYSICAL_ADDRESS;
+	err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 1);
+	if (err)
+		return err;
+	*pa = (data[0] << 8) | data[1];
+	dev_dbg(pulse8->dev, "Physical address: %x.%x.%x.%x\n",
+		cec_phys_addr_exp(*pa));
+
+	cmd[0] = MSGCODE_GET_HDMI_VERSION;
+	err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 1);
+	if (err)
+		return err;
+	log_addrs->cec_version = data[0];
+	dev_dbg(pulse8->dev, "CEC version: %d\n", log_addrs->cec_version);
+
+	cmd[0] = MSGCODE_GET_OSD_NAME;
+	err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 0);
+	if (err)
+		return err;
+	strscpy(log_addrs->osd_name, data, sizeof(log_addrs->osd_name));
+	dev_dbg(pulse8->dev, "OSD name: %s\n", log_addrs->osd_name);
+
+	return 0;
+}
+
+static int pulse8_apply_persistent_config(struct pulse8 *pulse8,
+					  struct cec_log_addrs *log_addrs,
+					  u16 pa)
+{
+	int err;
+
+	err = cec_s_log_addrs(pulse8->adap, log_addrs, false);
+	if (err)
+		return err;
+
+	cec_s_phys_addr(pulse8->adap, pa, false);
+
+	return 0;
+}
+
+static void pulse8_ping_eeprom_work_handler(struct work_struct *work)
+{
+	struct pulse8 *pulse8 =
+		container_of(work, struct pulse8, ping_eeprom_work.work);
+	u8 cmd;
+
+	mutex_lock(&pulse8->lock);
+	cmd = MSGCODE_PING;
+	pulse8_send_and_wait(pulse8, &cmd, 1,
+			     MSGCODE_COMMAND_ACCEPTED, 0);
+
+	if (pulse8->vers < 2)
+		goto unlock;
+
+	if (pulse8->config_pending && persistent_config) {
+		dev_dbg(pulse8->dev, "writing pending config to EEPROM\n");
+		cmd = MSGCODE_WRITE_EEPROM;
+		if (pulse8_send_and_wait(pulse8, &cmd, 1,
+					 MSGCODE_COMMAND_ACCEPTED, 0))
+			dev_info(pulse8->dev, "failed to write pending config to EEPROM\n");
+		else
+			pulse8->config_pending = false;
+	}
+unlock:
+	schedule_delayed_work(&pulse8->ping_eeprom_work, PING_PERIOD);
+	mutex_unlock(&pulse8->lock);
+}
+
+static int pulse8_connect(struct serio *serio, struct serio_driver *drv)
+{
+	u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_PHYS_ADDR | CEC_CAP_MONITOR_ALL;
+	struct pulse8 *pulse8;
+	int err = -ENOMEM;
+	struct cec_log_addrs log_addrs = {};
+	u16 pa = CEC_PHYS_ADDR_INVALID;
+
+	pulse8 = kzalloc(sizeof(*pulse8), GFP_KERNEL);
+
+	if (!pulse8)
+		return -ENOMEM;
+
+	pulse8->serio = serio;
+	pulse8->adap = cec_allocate_adapter(&pulse8_cec_adap_ops, pulse8,
+					    dev_name(&serio->dev), caps, 1);
+	err = PTR_ERR_OR_ZERO(pulse8->adap);
+	if (err < 0)
+		goto free_device;
+
+	pulse8->dev = &serio->dev;
+	serio_set_drvdata(serio, pulse8);
+	INIT_WORK(&pulse8->irq_work, pulse8_irq_work_handler);
+	INIT_WORK(&pulse8->tx_work, pulse8_tx_work_handler);
+	INIT_DELAYED_WORK(&pulse8->ping_eeprom_work,
+			  pulse8_ping_eeprom_work_handler);
+	mutex_init(&pulse8->lock);
+	spin_lock_init(&pulse8->msg_lock);
+	pulse8->config_pending = false;
+
+	err = serio_open(serio, drv);
+	if (err)
+		goto delete_adap;
+
+	err = pulse8_setup(pulse8, serio, &log_addrs, &pa);
+	if (err)
+		goto close_serio;
+
+	err = cec_register_adapter(pulse8->adap, &serio->dev);
+	if (err < 0)
+		goto close_serio;
+
+	pulse8->dev = &pulse8->adap->devnode.dev;
+
+	if (persistent_config && pulse8->autonomous) {
+		err = pulse8_apply_persistent_config(pulse8, &log_addrs, pa);
+		if (err)
+			goto close_serio;
+		pulse8->restoring_config = true;
+	}
+
+	schedule_delayed_work(&pulse8->ping_eeprom_work, PING_PERIOD);
+
+	return 0;
+
+close_serio:
+	pulse8->serio = NULL;
+	serio_set_drvdata(serio, NULL);
+	serio_close(serio);
+delete_adap:
+	cec_delete_adapter(pulse8->adap);
+free_device:
+	kfree(pulse8);
+	return err;
+}
+
+static const struct serio_device_id pulse8_serio_ids[] = {
+	{
+		.type	= SERIO_RS232,
+		.proto	= SERIO_PULSE8_CEC,
+		.id	= SERIO_ANY,
+		.extra	= SERIO_ANY,
+	},
+	{ 0 }
+};
+
+MODULE_DEVICE_TABLE(serio, pulse8_serio_ids);
+
+static struct serio_driver pulse8_drv = {
+	.driver		= {
+		.name	= "pulse8-cec",
+	},
+	.description	= "Pulse Eight HDMI CEC driver",
+	.id_table	= pulse8_serio_ids,
+	.interrupt	= pulse8_interrupt,
+	.connect	= pulse8_connect,
+	.disconnect	= pulse8_disconnect,
+};
+
+module_serio_driver(pulse8_drv);
diff --git a/drivers/media/cec/usb/rainshadow/Kconfig b/drivers/media/cec/usb/rainshadow/Kconfig
new file mode 100644
index 000000000000..c9ef2c192b17
--- /dev/null
+++ b/drivers/media/cec/usb/rainshadow/Kconfig
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config USB_RAINSHADOW_CEC
+	tristate "RainShadow Tech HDMI CEC"
+	select CEC_CORE
+	select USB
+	select USB_ACM
+	select SERIO
+	select SERIO_SERPORT
+	help
+	  This is a cec driver for the RainShadow Tech HDMI CEC device.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called rainshadow-cec.
diff --git a/drivers/media/cec/usb/rainshadow/Makefile b/drivers/media/cec/usb/rainshadow/Makefile
new file mode 100644
index 000000000000..47b33c574c3e
--- /dev/null
+++ b/drivers/media/cec/usb/rainshadow/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_USB_RAINSHADOW_CEC) += rainshadow-cec.o
diff --git a/drivers/media/cec/usb/rainshadow/rainshadow-cec.c b/drivers/media/cec/usb/rainshadow/rainshadow-cec.c
new file mode 100644
index 000000000000..ee870ea1a886
--- /dev/null
+++ b/drivers/media/cec/usb/rainshadow/rainshadow-cec.c
@@ -0,0 +1,380 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * RainShadow Tech HDMI CEC driver
+ *
+ * Copyright 2016 Hans Verkuil <hverkuil@xs4all.nl
+ */
+
+/*
+ * Notes:
+ *
+ * The higher level protocols are currently disabled. This can be added
+ * later, similar to how this is done for the Pulse Eight CEC driver.
+ *
+ * Documentation of the protocol is available here:
+ *
+ * http://rainshadowtech.com/doc/HDMICECtoUSBandRS232v2.0.pdf
+ */
+
+#include <linux/completion.h>
+#include <linux/ctype.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/serio.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/time.h>
+#include <linux/workqueue.h>
+
+#include <media/cec.h>
+
+MODULE_AUTHOR("Hans Verkuil <hverkuil@xs4all.nl>");
+MODULE_DESCRIPTION("RainShadow Tech HDMI CEC driver");
+MODULE_LICENSE("GPL");
+
+#define DATA_SIZE 256
+
+struct rain {
+	struct device *dev;
+	struct serio *serio;
+	struct cec_adapter *adap;
+	struct completion cmd_done;
+	struct work_struct work;
+
+	/* Low-level ringbuffer, collecting incoming characters */
+	char buf[DATA_SIZE];
+	unsigned int buf_rd_idx;
+	unsigned int buf_wr_idx;
+	unsigned int buf_len;
+	spinlock_t buf_lock;
+
+	/* command buffer */
+	char cmd[DATA_SIZE];
+	unsigned int cmd_idx;
+	bool cmd_started;
+
+	/* reply to a command, only used to store the firmware version */
+	char cmd_reply[DATA_SIZE];
+
+	struct mutex write_lock;
+};
+
+static void rain_process_msg(struct rain *rain)
+{
+	struct cec_msg msg = {};
+	const char *cmd = rain->cmd + 3;
+	int stat = -1;
+
+	for (; *cmd; cmd++) {
+		if (!isxdigit(*cmd))
+			continue;
+		if (isxdigit(cmd[0]) && isxdigit(cmd[1])) {
+			if (msg.len == CEC_MAX_MSG_SIZE)
+				break;
+			if (hex2bin(msg.msg + msg.len, cmd, 1))
+				continue;
+			msg.len++;
+			cmd++;
+			continue;
+		}
+		if (!cmd[1])
+			stat = hex_to_bin(cmd[0]);
+		break;
+	}
+
+	if (rain->cmd[0] == 'R') {
+		if (stat == 1 || stat == 2)
+			cec_received_msg(rain->adap, &msg);
+		return;
+	}
+
+	switch (stat) {
+	case 1:
+		cec_transmit_attempt_done(rain->adap, CEC_TX_STATUS_OK);
+		break;
+	case 2:
+		cec_transmit_attempt_done(rain->adap, CEC_TX_STATUS_NACK);
+		break;
+	default:
+		cec_transmit_attempt_done(rain->adap, CEC_TX_STATUS_LOW_DRIVE);
+		break;
+	}
+}
+
+static void rain_irq_work_handler(struct work_struct *work)
+{
+	struct rain *rain =
+		container_of(work, struct rain, work);
+
+	while (true) {
+		unsigned long flags;
+		char data;
+
+		spin_lock_irqsave(&rain->buf_lock, flags);
+		if (!rain->buf_len) {
+			spin_unlock_irqrestore(&rain->buf_lock, flags);
+			break;
+		}
+
+		data = rain->buf[rain->buf_rd_idx];
+		rain->buf_len--;
+		rain->buf_rd_idx = (rain->buf_rd_idx + 1) & 0xff;
+
+		spin_unlock_irqrestore(&rain->buf_lock, flags);
+
+		if (!rain->cmd_started && data != '?')
+			continue;
+
+		switch (data) {
+		case '\r':
+			rain->cmd[rain->cmd_idx] = '\0';
+			dev_dbg(rain->dev, "received: %s\n", rain->cmd);
+			if (!memcmp(rain->cmd, "REC", 3) ||
+			    !memcmp(rain->cmd, "STA", 3)) {
+				rain_process_msg(rain);
+			} else {
+				strscpy(rain->cmd_reply, rain->cmd,
+					sizeof(rain->cmd_reply));
+				complete(&rain->cmd_done);
+			}
+			rain->cmd_idx = 0;
+			rain->cmd_started = false;
+			break;
+
+		case '\n':
+			rain->cmd_idx = 0;
+			rain->cmd_started = false;
+			break;
+
+		case '?':
+			rain->cmd_idx = 0;
+			rain->cmd_started = true;
+			break;
+
+		default:
+			if (rain->cmd_idx >= DATA_SIZE - 1) {
+				dev_dbg(rain->dev,
+					"throwing away %d bytes of garbage\n", rain->cmd_idx);
+				rain->cmd_idx = 0;
+			}
+			rain->cmd[rain->cmd_idx++] = data;
+			break;
+		}
+	}
+}
+
+static irqreturn_t rain_interrupt(struct serio *serio, unsigned char data,
+				    unsigned int flags)
+{
+	struct rain *rain = serio_get_drvdata(serio);
+
+	if (rain->buf_len == DATA_SIZE) {
+		dev_warn_once(rain->dev, "buffer overflow\n");
+		return IRQ_HANDLED;
+	}
+	spin_lock(&rain->buf_lock);
+	rain->buf_len++;
+	rain->buf[rain->buf_wr_idx] = data;
+	rain->buf_wr_idx = (rain->buf_wr_idx + 1) & 0xff;
+	spin_unlock(&rain->buf_lock);
+	schedule_work(&rain->work);
+	return IRQ_HANDLED;
+}
+
+static void rain_disconnect(struct serio *serio)
+{
+	struct rain *rain = serio_get_drvdata(serio);
+
+	cancel_work_sync(&rain->work);
+	cec_unregister_adapter(rain->adap);
+	dev_info(&serio->dev, "disconnected\n");
+	serio_close(serio);
+	serio_set_drvdata(serio, NULL);
+	kfree(rain);
+}
+
+static int rain_send(struct rain *rain, const char *command)
+{
+	int err = serio_write(rain->serio, '!');
+
+	dev_dbg(rain->dev, "send: %s\n", command);
+	while (!err && *command)
+		err = serio_write(rain->serio, *command++);
+	if (!err)
+		err = serio_write(rain->serio, '~');
+
+	return err;
+}
+
+static int rain_send_and_wait(struct rain *rain,
+			      const char *cmd, const char *reply)
+{
+	int err;
+
+	init_completion(&rain->cmd_done);
+
+	mutex_lock(&rain->write_lock);
+	err = rain_send(rain, cmd);
+	if (err)
+		goto err;
+
+	if (!wait_for_completion_timeout(&rain->cmd_done, HZ)) {
+		err = -ETIMEDOUT;
+		goto err;
+	}
+	if (reply && strncmp(rain->cmd_reply, reply, strlen(reply))) {
+		dev_dbg(rain->dev,
+			 "transmit of '%s': received '%s' instead of '%s'\n",
+			 cmd, rain->cmd_reply, reply);
+		err = -EIO;
+	}
+err:
+	mutex_unlock(&rain->write_lock);
+	return err;
+}
+
+static int rain_setup(struct rain *rain, struct serio *serio,
+			struct cec_log_addrs *log_addrs, u16 *pa)
+{
+	int err;
+
+	err = rain_send_and_wait(rain, "R", "REV");
+	if (err)
+		return err;
+	dev_info(rain->dev, "Firmware version %s\n", rain->cmd_reply + 4);
+
+	err = rain_send_and_wait(rain, "Q 1", "QTY");
+	if (err)
+		return err;
+	err = rain_send_and_wait(rain, "c0000", "CFG");
+	if (err)
+		return err;
+	return rain_send_and_wait(rain, "A F 0000", "ADR");
+}
+
+static int rain_cec_adap_enable(struct cec_adapter *adap, bool enable)
+{
+	return 0;
+}
+
+static int rain_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr)
+{
+	struct rain *rain = cec_get_drvdata(adap);
+	u8 cmd[16];
+
+	if (log_addr == CEC_LOG_ADDR_INVALID)
+		log_addr = CEC_LOG_ADDR_UNREGISTERED;
+	snprintf(cmd, sizeof(cmd), "A %x", log_addr);
+	return rain_send_and_wait(rain, cmd, "ADR");
+}
+
+static int rain_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
+				    u32 signal_free_time, struct cec_msg *msg)
+{
+	struct rain *rain = cec_get_drvdata(adap);
+	char cmd[2 * CEC_MAX_MSG_SIZE + 16];
+	unsigned int i;
+	int err;
+
+	if (msg->len == 1) {
+		snprintf(cmd, sizeof(cmd), "x%x", cec_msg_destination(msg));
+	} else {
+		char hex[3];
+
+		snprintf(cmd, sizeof(cmd), "x%x %02x ",
+			 cec_msg_destination(msg), msg->msg[1]);
+		for (i = 2; i < msg->len; i++) {
+			snprintf(hex, sizeof(hex), "%02x", msg->msg[i]);
+			strlcat(cmd, hex, sizeof(cmd));
+		}
+	}
+	mutex_lock(&rain->write_lock);
+	err = rain_send(rain, cmd);
+	mutex_unlock(&rain->write_lock);
+	return err;
+}
+
+static const struct cec_adap_ops rain_cec_adap_ops = {
+	.adap_enable = rain_cec_adap_enable,
+	.adap_log_addr = rain_cec_adap_log_addr,
+	.adap_transmit = rain_cec_adap_transmit,
+};
+
+static int rain_connect(struct serio *serio, struct serio_driver *drv)
+{
+	u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_PHYS_ADDR | CEC_CAP_MONITOR_ALL;
+	struct rain *rain;
+	int err = -ENOMEM;
+	struct cec_log_addrs log_addrs = {};
+	u16 pa = CEC_PHYS_ADDR_INVALID;
+
+	rain = kzalloc(sizeof(*rain), GFP_KERNEL);
+
+	if (!rain)
+		return -ENOMEM;
+
+	rain->serio = serio;
+	rain->adap = cec_allocate_adapter(&rain_cec_adap_ops, rain,
+					  dev_name(&serio->dev), caps, 1);
+	err = PTR_ERR_OR_ZERO(rain->adap);
+	if (err < 0)
+		goto free_device;
+
+	rain->dev = &serio->dev;
+	serio_set_drvdata(serio, rain);
+	INIT_WORK(&rain->work, rain_irq_work_handler);
+	mutex_init(&rain->write_lock);
+	spin_lock_init(&rain->buf_lock);
+
+	err = serio_open(serio, drv);
+	if (err)
+		goto delete_adap;
+
+	err = rain_setup(rain, serio, &log_addrs, &pa);
+	if (err)
+		goto close_serio;
+
+	err = cec_register_adapter(rain->adap, &serio->dev);
+	if (err < 0)
+		goto close_serio;
+
+	rain->dev = &rain->adap->devnode.dev;
+	return 0;
+
+close_serio:
+	serio_close(serio);
+delete_adap:
+	cec_delete_adapter(rain->adap);
+	serio_set_drvdata(serio, NULL);
+free_device:
+	kfree(rain);
+	return err;
+}
+
+static const struct serio_device_id rain_serio_ids[] = {
+	{
+		.type	= SERIO_RS232,
+		.proto	= SERIO_RAINSHADOW_CEC,
+		.id	= SERIO_ANY,
+		.extra	= SERIO_ANY,
+	},
+	{ 0 }
+};
+
+MODULE_DEVICE_TABLE(serio, rain_serio_ids);
+
+static struct serio_driver rain_drv = {
+	.driver		= {
+		.name	= "rainshadow-cec",
+	},
+	.description	= "RainShadow Tech HDMI CEC driver",
+	.id_table	= rain_serio_ids,
+	.interrupt	= rain_interrupt,
+	.connect	= rain_connect,
+	.disconnect	= rain_disconnect,
+};
+
+module_serio_driver(rain_drv);
diff --git a/drivers/media/common/Kconfig b/drivers/media/common/Kconfig
index 1990b7f09454..4ea03b7899a8 100644
--- a/drivers/media/common/Kconfig
+++ b/drivers/media/common/Kconfig
@@ -14,7 +14,7 @@ config VIDEO_TVEEPROM
 	depends on I2C
 
 config CYPRESS_FIRMWARE
-	tristate "Cypress firmware helper routines"
+	tristate
 	depends on USB
 
 source "drivers/media/common/videobuf2/Kconfig"
diff --git a/drivers/media/dvb-core/Kconfig b/drivers/media/dvb-core/Kconfig
index 90e038d5ffd9..6ffac618417b 100644
--- a/drivers/media/dvb-core/Kconfig
+++ b/drivers/media/dvb-core/Kconfig
@@ -3,6 +3,32 @@
 # DVB device configuration
 #
 
+config DVB_MMAP
+	bool "Enable DVB memory-mapped API (EXPERIMENTAL)"
+	depends on DVB_CORE
+	depends on VIDEO_V4L2=y || VIDEO_V4L2=DVB_CORE
+	select VIDEOBUF2_VMALLOC
+	help
+	  This option enables DVB experimental memory-mapped API, which
+	  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)
+	depends on NET && INET && DVB_CORE
+	help
+	  This option enables DVB Network Support which is a part of the DVB
+	  standard. It is used, for example, by automatic firmware updates used
+	  on Set-Top-Boxes. It can also be used to access the Internet via the
+	  DVB card, if the network provider supports it.
+
+	  You may want to disable the network support on embedded devices. If
+	  unsure say Y.
+
 config DVB_MAX_ADAPTERS
 	int "maximum number of DVB/ATSC adapters"
 	depends on DVB_CORE
@@ -19,6 +45,7 @@ config DVB_MAX_ADAPTERS
 config DVB_DYNAMIC_MINORS
 	bool "Dynamic DVB minor allocation"
 	depends on DVB_CORE
+	default y
 	help
 	  If you say Y here, the DVB subsystem will use dynamic minor
 	  allocation for any device that uses the DVB major number.
diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig
index a29e9ddf9c82..fbadba9b328e 100644
--- a/drivers/media/dvb-frontends/Kconfig
+++ b/drivers/media/dvb-frontends/Kconfig
@@ -1,4 +1,8 @@
-comment "DVB Frontend drivers hidden by 'Autoselect ancillary drivers'"
+# SPDX-License-Identifier: GPL-2.0
+
+if MEDIA_DIGITAL_TV_SUPPORT
+
+comment "DVB Frontend drivers auto-selected by 'Autoselect ancillary drivers'"
 	depends on MEDIA_HIDE_ANCILLARY_SUBDRV
 
 menu "Customise DVB Frontends"
@@ -943,9 +947,16 @@ config DVB_SP2
 	help
 	  CIMaX SP2/SP2HF Common Interface module.
 
+endmenu # Customise DVB Frontends
+
+endif # MEDIA_DIGITAL_TV_SUPPORT
+
 comment "Tools to develop new frontends"
+	depends on MEDIA_TEST_SUPPORT
 
 config DVB_DUMMY_FE
 	tristate "Dummy frontend driver"
-	depends on DVB_CORE
-endmenu
+	depends on MEDIA_TEST_SUPPORT
+	select DVB_CORE
+	help
+	  Dummy skeleton frontend driver.
diff --git a/drivers/media/dvb-frontends/dib3000.h b/drivers/media/dvb-frontends/dib3000.h
index 9118a7a48ef2..3f129efa21de 100644
--- a/drivers/media/dvb-frontends/dib3000.h
+++ b/drivers/media/dvb-frontends/dib3000.h
@@ -14,7 +14,7 @@
  *  Amaury Demol from DiBcom for providing specs and driver
  *  sources, on which this driver (and the dvb-dibusb) are based.
  *
- * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+ * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
  */
 
 #ifndef DIB3000_H
diff --git a/drivers/media/dvb-frontends/dib3000mb.c b/drivers/media/dvb-frontends/dib3000mb.c
index 46ed0e20c8fa..0f0480d8576d 100644
--- a/drivers/media/dvb-frontends/dib3000mb.c
+++ b/drivers/media/dvb-frontends/dib3000mb.c
@@ -14,7 +14,7 @@
  *  Amaury Demol from DiBcom for providing specs and driver
  *  sources, on which this driver (and the dvb-dibusb) are based.
  *
- * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+ * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
diff --git a/drivers/media/dvb-frontends/eds1547.h b/drivers/media/dvb-frontends/eds1547.h
index 907254b85708..bb85a6e27076 100644
--- a/drivers/media/dvb-frontends/eds1547.h
+++ b/drivers/media/dvb-frontends/eds1547.h
@@ -3,7 +3,7 @@
 *
 * Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
 *
-* see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+* see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
 */
 
 #ifndef EDS1547
diff --git a/drivers/media/dvb-frontends/z0194a.h b/drivers/media/dvb-frontends/z0194a.h
index 21442905d116..3446ccbf3c1c 100644
--- a/drivers/media/dvb-frontends/z0194a.h
+++ b/drivers/media/dvb-frontends/z0194a.h
@@ -3,7 +3,7 @@
 *
 * Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
 *
-* see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+* see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
 */
 
 #ifndef Z0194A
diff --git a/drivers/media/firewire/Kconfig b/drivers/media/firewire/Kconfig
index e7837da5905b..0c1f326f581f 100644
--- a/drivers/media/firewire/Kconfig
+++ b/drivers/media/firewire/Kconfig
@@ -1,7 +1,9 @@
 # SPDX-License-Identifier: GPL-2.0-only
+if DVB_CORE && FIREWIRE
+comment "FireWire (IEEE 1394) Adapters"
+
 config DVB_FIREDTV
 	tristate "FireDTV and FloppyDTV"
-	depends on DVB_CORE && FIREWIRE
 	help
 	  Support for DVB receivers from Digital Everywhere
 	  which are connected via IEEE 1394 (FireWire).
@@ -18,3 +20,4 @@ config DVB_FIREDTV_INPUT
 	def_bool INPUT = y || (INPUT = m && DVB_FIREDTV = m)
 
 endif # DVB_FIREDTV
+endif # DVB_CORE && FIREWIRE
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 125d596c13dd..3abc80373ec0 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -5,6 +5,9 @@
 
 if VIDEO_V4L2
 
+comment "IR I2C driver auto-selected by 'Autoselect ancillary drivers'"
+	depends on MEDIA_SUBDRV_AUTOSELECT && I2C && RC_CORE
+
 config VIDEO_IR_I2C
 	tristate "I2C module for IR" if !MEDIA_SUBDRV_AUTOSELECT || EXPERT
 	depends on I2C && RC_CORE
@@ -19,17 +22,18 @@ config VIDEO_IR_I2C
 	  In doubt, say Y.
 
 #
-# Encoder / Decoder module configuration
+# V4L2 I2C drivers that aren't related with Camera support
 #
 
-comment "I2C drivers hidden by 'Autoselect ancillary drivers'"
+comment "audio, video and radio I2C drivers auto-selected by 'Autoselect ancillary drivers'"
 	depends on MEDIA_HIDE_ANCILLARY_SUBDRV
+#
+# Encoder / Decoder module configuration
+#
 
-menu "I2C Encoders, decoders, sensors and other helper chips"
+menu "Audio decoders, processors and mixers"
 	visible if !MEDIA_HIDE_ANCILLARY_SUBDRV
 
-comment "Audio decoders, processors and mixers"
-
 config VIDEO_TVAUDIO
 	tristate "Simple audio decoder chips"
 	depends on VIDEO_V4L2 && I2C
@@ -62,11 +66,13 @@ config VIDEO_TDA9840
 
 config VIDEO_TDA1997X
 	tristate "NXP TDA1997x HDMI receiver"
-	depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
+	depends on VIDEO_V4L2 && I2C
 	depends on SND_SOC
 	select HDMI
 	select SND_PCM
 	select V4L2_FWNODE
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	help
 	  V4L2 subdevice driver for the NXP TDA1997x HDMI receivers.
 
@@ -185,8 +191,10 @@ config VIDEO_SONY_BTF_MPX
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called sony-btf-mpx.
+endmenu
 
-comment "RDS decoders"
+menu "RDS decoders"
+	visible if !MEDIA_HIDE_ANCILLARY_SUBDRV
 
 config VIDEO_SAA6588
 	tristate "SAA6588 Radio Chip RDS decoder support"
@@ -199,12 +207,16 @@ config VIDEO_SAA6588
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called saa6588.
+endmenu
 
-comment "Video decoders"
+menu "Video decoders"
+	visible if !MEDIA_HIDE_ANCILLARY_SUBDRV
 
 config VIDEO_ADV7180
 	tristate "Analog Devices ADV7180 decoder"
-	depends on GPIOLIB && VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
+	depends on GPIOLIB && VIDEO_V4L2 && I2C
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	help
 	  Support for the Analog Devices ADV7180 video decoder.
 
@@ -223,8 +235,10 @@ config VIDEO_ADV7183
 
 config VIDEO_ADV748X
 	tristate "Analog Devices ADV748x decoder"
-	depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
+	depends on VIDEO_V4L2 && I2C
 	depends on OF
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select REGMAP_I2C
 	select V4L2_FWNODE
 	help
@@ -236,8 +250,10 @@ config VIDEO_ADV748X
 
 config VIDEO_ADV7604
 	tristate "Analog Devices ADV7604 decoder"
-	depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
+	depends on VIDEO_V4L2 && I2C
 	depends on GPIOLIB || COMPILE_TEST
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select REGMAP_I2C
 	select HDMI
 	select V4L2_FWNODE
@@ -260,7 +276,9 @@ config VIDEO_ADV7604_CEC
 
 config VIDEO_ADV7842
 	tristate "Analog Devices ADV7842 decoder"
-	depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
+	depends on VIDEO_V4L2 && I2C
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select HDMI
 	help
 	  Support for the Analog Devices ADV7842 video decoder.
@@ -347,7 +365,9 @@ config VIDEO_SAA711X
 
 config VIDEO_TC358743
 	tristate "Toshiba TC358743 decoder"
-	depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
+	depends on VIDEO_V4L2 && I2C
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select HDMI
 	select V4L2_FWNODE
 	help
@@ -457,7 +477,10 @@ config VIDEO_SAA717X
 
 source "drivers/media/i2c/cx25840/Kconfig"
 
-comment "Video encoders"
+endmenu
+
+menu "Video encoders"
+	visible if !MEDIA_HIDE_ANCILLARY_SUBDRV
 
 config VIDEO_SAA7127
 	tristate "Philips SAA7127/9 digital video encoders"
@@ -515,8 +538,10 @@ config VIDEO_ADV7393
 
 config VIDEO_ADV7511
 	tristate "Analog Devices ADV7511 encoder"
-	depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
+	depends on VIDEO_V4L2 && I2C
 	depends on DRM_I2C_ADV7511=n || COMPILE_TEST
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select HDMI
 	help
 	  Support for the Analog Devices ADV7511 video encoder.
@@ -536,7 +561,10 @@ config VIDEO_ADV7511_CEC
 
 config VIDEO_AD9389B
 	tristate "Analog Devices AD9389B encoder"
-	depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
+	depends on VIDEO_V4L2 && I2C
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
+
 	help
 	  Support for the Analog Devices AD9389B video encoder.
 
@@ -559,8 +587,124 @@ config VIDEO_THS8200
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called ths8200.
+endmenu
+
+menu "Video improvement chips"
+	visible if !MEDIA_HIDE_ANCILLARY_SUBDRV
+
+config VIDEO_UPD64031A
+	tristate "NEC Electronics uPD64031A Ghost Reduction"
+	depends on VIDEO_V4L2 && I2C
+	help
+	  Support for the NEC Electronics uPD64031A Ghost Reduction
+	  video chip. It is most often found in NTSC TV cards made for
+	  Japan and is used to reduce the 'ghosting' effect that can
+	  be present in analog TV broadcasts.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called upd64031a.
+
+config VIDEO_UPD64083
+	tristate "NEC Electronics uPD64083 3-Dimensional Y/C separation"
+	depends on VIDEO_V4L2 && I2C
+	help
+	  Support for the NEC Electronics uPD64083 3-Dimensional Y/C
+	  separation video chip. It is used to improve the quality of
+	  the colors of a composite signal.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called upd64083.
+endmenu
+
+menu "Audio/Video compression chips"
+	visible if !MEDIA_HIDE_ANCILLARY_SUBDRV
+
+config VIDEO_SAA6752HS
+	tristate "Philips SAA6752HS MPEG-2 Audio/Video Encoder"
+	depends on VIDEO_V4L2 && I2C
+	select CRC32
+	help
+	  Support for the Philips SAA6752HS MPEG-2 video and MPEG-audio/AC-3
+	  audio encoder with multiplexer.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called saa6752hs.
+
+endmenu
+
+menu "SDR tuner chips"
+	visible if !MEDIA_HIDE_ANCILLARY_SUBDRV
 
-comment "Camera sensor devices"
+config SDR_MAX2175
+	tristate "Maxim 2175 RF to Bits tuner"
+	depends on VIDEO_V4L2 && MEDIA_SDR_SUPPORT && I2C
+	select REGMAP_I2C
+	help
+	  Support for Maxim 2175 tuner. It is an advanced analog/digital
+	  radio receiver with RF-to-Bits front-end designed for SDR solutions.
+
+	  To compile this driver as a module, choose M here; the
+	  module will be called max2175.
+
+
+endmenu
+
+menu "Miscellaneous helper chips"
+	visible if !MEDIA_HIDE_ANCILLARY_SUBDRV
+
+config VIDEO_THS7303
+	tristate "THS7303/53 Video Amplifier"
+	depends on VIDEO_V4L2 && I2C
+	help
+	  Support for TI THS7303/53 video amplifier
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ths7303.
+
+config VIDEO_M52790
+	tristate "Mitsubishi M52790 A/V switch"
+	depends on VIDEO_V4L2 && I2C
+	help
+	 Support for the Mitsubishi M52790 A/V switch.
+
+	 To compile this driver as a module, choose M here: the
+	 module will be called m52790.
+
+config VIDEO_I2C
+	tristate "I2C transport video support"
+	depends on VIDEO_V4L2 && I2C
+	select VIDEOBUF2_VMALLOC
+	imply HWMON
+	help
+	  Enable the I2C transport video support which supports the
+	  following:
+	   * Panasonic AMG88xx Grid-Eye Sensors
+	   * Melexis MLX90640 Thermal Cameras
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called video-i2c
+
+config VIDEO_ST_MIPID02
+	tristate "STMicroelectronics MIPID02 CSI-2 to PARALLEL bridge"
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
+	select V4L2_FWNODE
+	help
+	  Support for STMicroelectronics MIPID02 CSI-2 to PARALLEL bridge.
+	  It is used to allow usage of CSI-2 sensor with PARALLEL port
+	  controller.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called st-mipid02.
+endmenu
+
+#
+# V4L2 I2C drivers that are related with Camera support
+#
+
+menu "Camera sensor devices"
+	visible if MEDIA_CAMERA_SUPPORT
 
 config VIDEO_APTINA_PLL
 	tristate
@@ -568,12 +712,11 @@ config VIDEO_APTINA_PLL
 config VIDEO_SMIAPP_PLL
 	tristate
 
-if MEDIA_CAMERA_SUPPORT
-
 config VIDEO_HI556
 	tristate "Hynix Hi-556 sensor support"
-	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
-	depends on MEDIA_CONTROLLER
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select V4L2_FWNODE
 	help
 	  This is a Video4Linux2 sensor driver for the Hynix
@@ -584,8 +727,10 @@ config VIDEO_HI556
 
 config VIDEO_IMX214
 	tristate "Sony IMX214 sensor support"
-	depends on GPIOLIB && I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on GPIOLIB && I2C && VIDEO_V4L2
 	depends on V4L2_FWNODE
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select REGMAP_I2C
 	help
 	  This is a Video4Linux2 sensor driver for the Sony
@@ -596,7 +741,9 @@ config VIDEO_IMX214
 
 config VIDEO_IMX219
 	tristate "Sony IMX219 sensor support"
-	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select V4L2_FWNODE
 	help
 	  This is a Video4Linux2 sensor driver for the Sony
@@ -607,7 +754,9 @@ config VIDEO_IMX219
 
 config VIDEO_IMX258
 	tristate "Sony IMX258 sensor support"
-	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	help
 	  This is a Video4Linux2 sensor driver for the Sony
 	  IMX258 camera.
@@ -617,7 +766,9 @@ config VIDEO_IMX258
 
 config VIDEO_IMX274
 	tristate "Sony IMX274 sensor support"
-	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select REGMAP_I2C
 	help
 	  This is a V4L2 sensor driver for the Sony IMX274
@@ -625,7 +776,9 @@ config VIDEO_IMX274
 
 config VIDEO_IMX290
 	tristate "Sony IMX290 sensor support"
-	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select REGMAP_I2C
 	select V4L2_FWNODE
 	help
@@ -637,7 +790,9 @@ config VIDEO_IMX290
 
 config VIDEO_IMX319
 	tristate "Sony IMX319 sensor support"
-	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	help
 	  This is a Video4Linux2 sensor driver for the Sony
 	  IMX319 camera.
@@ -647,7 +802,9 @@ config VIDEO_IMX319
 
 config VIDEO_IMX355
 	tristate "Sony IMX355 sensor support"
-	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	help
 	  This is a Video4Linux2 sensor driver for the Sony
 	  IMX355 camera.
@@ -678,7 +835,8 @@ config VIDEO_OV2659
 
 config VIDEO_OV2680
 	tristate "OmniVision OV2680 sensor support"
-	depends on VIDEO_V4L2 && I2C && MEDIA_CONTROLLER
+	depends on VIDEO_V4L2 && I2C
+	select MEDIA_CONTROLLER
 	select V4L2_FWNODE
 	help
 	  This is a Video4Linux2 sensor driver for the OmniVision
@@ -689,7 +847,8 @@ config VIDEO_OV2680
 
 config VIDEO_OV2685
 	tristate "OmniVision OV2685 sensor support"
-	depends on VIDEO_V4L2 && I2C && MEDIA_CONTROLLER
+	depends on VIDEO_V4L2 && I2C
+	select MEDIA_CONTROLLER
 	select V4L2_FWNODE
 	help
 	  This is a Video4Linux2 sensor driver for the OmniVision
@@ -701,7 +860,9 @@ config VIDEO_OV2685
 config VIDEO_OV5640
 	tristate "OmniVision OV5640 sensor support"
 	depends on OF
-	depends on GPIOLIB && VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
+	depends on GPIOLIB && VIDEO_V4L2 && I2C
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select V4L2_FWNODE
 	help
 	  This is a Video4Linux2 sensor driver for the Omnivision
@@ -710,7 +871,9 @@ config VIDEO_OV5640
 config VIDEO_OV5645
 	tristate "OmniVision OV5645 sensor support"
 	depends on OF
-	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select V4L2_FWNODE
 	help
 	  This is a Video4Linux2 sensor driver for the OmniVision
@@ -721,7 +884,9 @@ config VIDEO_OV5645
 
 config VIDEO_OV5647
 	tristate "OmniVision OV5647 sensor support"
-	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select V4L2_FWNODE
 	help
 	  This is a Video4Linux2 sensor driver for the OmniVision
@@ -742,8 +907,9 @@ config VIDEO_OV6650
 
 config VIDEO_OV5670
 	tristate "OmniVision OV5670 sensor support"
-	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
-	depends on MEDIA_CONTROLLER
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select V4L2_FWNODE
 	help
 	  This is a Video4Linux2 sensor driver for the OmniVision
@@ -754,8 +920,9 @@ config VIDEO_OV5670
 
 config VIDEO_OV5675
 	tristate "OmniVision OV5675 sensor support"
-	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
-	depends on MEDIA_CONTROLLER
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select V4L2_FWNODE
 	help
 	  This is a Video4Linux2 sensor driver for the OmniVision
@@ -777,7 +944,9 @@ config VIDEO_OV5695
 
 config VIDEO_OV7251
 	tristate "OmniVision OV7251 sensor support"
-	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select V4L2_FWNODE
 	help
 	  This is a Video4Linux2 sensor driver for the OmniVision
@@ -826,7 +995,9 @@ config VIDEO_OV7740
 
 config VIDEO_OV8856
 	tristate "OmniVision OV8856 sensor support"
-	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select V4L2_FWNODE
 	help
 	  This is a Video4Linux2 sensor driver for the OmniVision
@@ -844,7 +1015,9 @@ config VIDEO_OV9640
 
 config VIDEO_OV9650
 	tristate "OmniVision OV9650/OV9652 sensor support"
-	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select REGMAP_SCCB
 	help
 	  This is a V4L2 sensor driver for the Omnivision
@@ -852,7 +1025,9 @@ config VIDEO_OV9650
 
 config VIDEO_OV13858
 	tristate "OmniVision OV13858 sensor support"
-	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select V4L2_FWNODE
 	help
 	  This is a Video4Linux2 sensor driver for the OmniVision
@@ -870,14 +1045,18 @@ config VIDEO_VS6624
 
 config VIDEO_MT9M001
 	tristate "mt9m001 support"
-	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	help
 	  This driver supports MT9M001 cameras from Micron, monochrome
 	  and colour models.
 
 config VIDEO_MT9M032
 	tristate "MT9M032 camera sensor support"
-	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select VIDEO_APTINA_PLL
 	help
 	  This driver supports MT9M032 camera sensors from Aptina, monochrome
@@ -893,7 +1072,9 @@ config VIDEO_MT9M111
 
 config VIDEO_MT9P031
 	tristate "Aptina MT9P031 support"
-	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select VIDEO_APTINA_PLL
 	help
 	  This is a Video4Linux2 sensor driver for the Aptina
@@ -901,7 +1082,9 @@ config VIDEO_MT9P031
 
 config VIDEO_MT9T001
 	tristate "Aptina MT9T001 support"
-	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	help
 	  This is a Video4Linux2 sensor driver for the Aptina
 	  (Micron) mt0t001 3 Mpixel camera.
@@ -926,7 +1109,9 @@ config VIDEO_MT9V011
 
 config VIDEO_MT9V032
 	tristate "Micron MT9V032 sensor support"
-	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select REGMAP_I2C
 	select V4L2_FWNODE
 	help
@@ -951,7 +1136,9 @@ config VIDEO_SR030PC30
 
 config VIDEO_NOON010PC30
 	tristate "Siliconfile NOON010PC30 sensor support"
-	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	help
 	  This driver supports NOON010PC30 CIF camera from Siliconfile
 
@@ -969,21 +1156,27 @@ config VIDEO_RJ54N1
 
 config VIDEO_S5K6AA
 	tristate "Samsung S5K6AAFX sensor support"
-	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	help
 	  This is a V4L2 sensor driver for Samsung S5K6AA(FX) 1.3M
 	  camera sensor with an embedded SoC image signal processor.
 
 config VIDEO_S5K6A3
 	tristate "Samsung S5K6A3 sensor support"
-	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	help
 	  This is a V4L2 sensor driver for Samsung S5K6A3 raw
 	  camera sensor.
 
 config VIDEO_S5K4ECGX
 	tristate "Samsung S5K4ECGX sensor support"
-	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select CRC32
 	help
 	  This is a V4L2 sensor driver for Samsung S5K4ECGX 5M
@@ -991,7 +1184,9 @@ config VIDEO_S5K4ECGX
 
 config VIDEO_S5K5BAF
 	tristate "Samsung S5K5BAF sensor support"
-	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select V4L2_FWNODE
 	help
 	  This is a V4L2 sensor driver for Samsung S5K5BAF 2M
@@ -1002,28 +1197,32 @@ source "drivers/media/i2c/et8ek8/Kconfig"
 
 config VIDEO_S5C73M3
 	tristate "Samsung S5C73M3 sensor support"
-	depends on I2C && SPI && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on I2C && SPI && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select V4L2_FWNODE
 	help
 	  This is a V4L2 sensor driver for Samsung S5C73M3
 	  8 Mpixel camera.
-endif
 
-comment "Lens drivers"
+endmenu
 
-if MEDIA_CAMERA_SUPPORT
+menu "Lens drivers"
+	visible if MEDIA_CAMERA_SUPPORT
 
 config VIDEO_AD5820
 	tristate "AD5820 lens voice coil support"
-	depends on GPIOLIB && I2C && VIDEO_V4L2 && MEDIA_CONTROLLER
+	depends on GPIOLIB && I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
 	help
 	  This is a driver for the AD5820 camera lens voice coil.
 	  It is used for example in Nokia N900 (RX-51).
 
 config VIDEO_AK7375
 	tristate "AK7375 lens voice coil support"
-	depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER
-	depends on VIDEO_V4L2_SUBDEV_API
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	help
 	  This is a driver for the AK7375 camera lens voice coil.
 	  AK7375 is a 12 bit DAC with 120mA output current sink
@@ -1032,8 +1231,9 @@ config VIDEO_AK7375
 
 config VIDEO_DW9714
 	tristate "DW9714 lens voice coil support"
-	depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER
-	depends on VIDEO_V4L2_SUBDEV_API
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	help
 	  This is a driver for the DW9714 camera lens voice coil.
 	  DW9714 is a 10 bit DAC with 120mA output current sink
@@ -1042,30 +1242,32 @@ config VIDEO_DW9714
 
 config VIDEO_DW9807_VCM
 	tristate "DW9807 lens voice coil support"
-	depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER
-	depends on VIDEO_V4L2_SUBDEV_API
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	help
 	  This is a driver for the DW9807 camera lens voice coil.
 	  DW9807 is a 10 bit DAC with 100mA output current sink
 	  capability. This is designed for linear control of
 	  voice coil motors, controlled via I2C serial interface.
 
-endif
-
-comment "Flash devices"
+endmenu
 
-if MEDIA_CAMERA_SUPPORT
+menu "Flash devices"
+	visible if MEDIA_CAMERA_SUPPORT
 
 config VIDEO_ADP1653
 	tristate "ADP1653 flash support"
-	depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
 	help
 	  This is a driver for the ADP1653 flash controller. It is used for
 	  example in Nokia N900.
 
 config VIDEO_LM3560
 	tristate "LM3560 dual flash driver support"
-	depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
 	select REGMAP_I2C
 	help
 	  This is a driver for the lm3560 dual flash controllers. It controls
@@ -1073,112 +1275,12 @@ config VIDEO_LM3560
 
 config VIDEO_LM3646
 	tristate "LM3646 dual flash driver support"
-	depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
 	select REGMAP_I2C
 	help
 	  This is a driver for the lm3646 dual flash controllers. It controls
 	  flash, torch LEDs.
-
-endif
-
-comment "Video improvement chips"
-
-config VIDEO_UPD64031A
-	tristate "NEC Electronics uPD64031A Ghost Reduction"
-	depends on VIDEO_V4L2 && I2C
-	help
-	  Support for the NEC Electronics uPD64031A Ghost Reduction
-	  video chip. It is most often found in NTSC TV cards made for
-	  Japan and is used to reduce the 'ghosting' effect that can
-	  be present in analog TV broadcasts.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called upd64031a.
-
-config VIDEO_UPD64083
-	tristate "NEC Electronics uPD64083 3-Dimensional Y/C separation"
-	depends on VIDEO_V4L2 && I2C
-	help
-	  Support for the NEC Electronics uPD64083 3-Dimensional Y/C
-	  separation video chip. It is used to improve the quality of
-	  the colors of a composite signal.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called upd64083.
-
-comment "Audio/Video compression chips"
-
-config VIDEO_SAA6752HS
-	tristate "Philips SAA6752HS MPEG-2 Audio/Video Encoder"
-	depends on VIDEO_V4L2 && I2C
-	select CRC32
-	help
-	  Support for the Philips SAA6752HS MPEG-2 video and MPEG-audio/AC-3
-	  audio encoder with multiplexer.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called saa6752hs.
-
-comment "SDR tuner chips"
-
-config SDR_MAX2175
-	tristate "Maxim 2175 RF to Bits tuner"
-	depends on VIDEO_V4L2 && MEDIA_SDR_SUPPORT && I2C
-	select REGMAP_I2C
-	help
-	  Support for Maxim 2175 tuner. It is an advanced analog/digital
-	  radio receiver with RF-to-Bits front-end designed for SDR solutions.
-
-	  To compile this driver as a module, choose M here; the
-	  module will be called max2175.
-
-comment "Miscellaneous helper chips"
-
-config VIDEO_THS7303
-	tristate "THS7303/53 Video Amplifier"
-	depends on VIDEO_V4L2 && I2C
-	help
-	  Support for TI THS7303/53 video amplifier
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called ths7303.
-
-config VIDEO_M52790
-	tristate "Mitsubishi M52790 A/V switch"
-	depends on VIDEO_V4L2 && I2C
-	help
-	 Support for the Mitsubishi M52790 A/V switch.
-
-	 To compile this driver as a module, choose M here: the
-	 module will be called m52790.
-
-config VIDEO_I2C
-	tristate "I2C transport video support"
-	depends on VIDEO_V4L2 && I2C
-	select VIDEOBUF2_VMALLOC
-	imply HWMON
-	help
-	  Enable the I2C transport video support which supports the
-	  following:
-	   * Panasonic AMG88xx Grid-Eye Sensors
-	   * Melexis MLX90640 Thermal Cameras
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called video-i2c
-
-config VIDEO_ST_MIPID02
-	tristate "STMicroelectronics MIPID02 CSI-2 to PARALLEL bridge"
-	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
-	depends on MEDIA_CAMERA_SUPPORT
-	select V4L2_FWNODE
-	help
-	  Support for STMicroelectronics MIPID02 CSI-2 to PARALLEL bridge.
-	  It is used to allow usage of CSI-2 sensor with PARALLEL port
-	  controller.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called st-mipid02.
-
 endmenu
 
-endif
+endif # VIDEO_V4L2
diff --git a/drivers/media/i2c/et8ek8/Kconfig b/drivers/media/i2c/et8ek8/Kconfig
index 1c6909874d56..afcc4ea764f6 100644
--- a/drivers/media/i2c/et8ek8/Kconfig
+++ b/drivers/media/i2c/et8ek8/Kconfig
@@ -1,7 +1,9 @@
 # SPDX-License-Identifier: GPL-2.0-only
 config VIDEO_ET8EK8
 	tristate "ET8EK8 camera sensor support"
-	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select V4L2_FWNODE
 	help
 	  This is a driver for the Toshiba ET8EK8 5 MP camera sensor.
diff --git a/drivers/media/i2c/m5mols/Kconfig b/drivers/media/i2c/m5mols/Kconfig
index e573482f269f..6f0ef33b7ee1 100644
--- a/drivers/media/i2c/m5mols/Kconfig
+++ b/drivers/media/i2c/m5mols/Kconfig
@@ -1,7 +1,8 @@
 # SPDX-License-Identifier: GPL-2.0-only
 config VIDEO_M5MOLS
 	tristate "Fujitsu M-5MOLS 8MP sensor support"
-	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
-	depends on MEDIA_CAMERA_SUPPORT
+	depends on I2C && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	help
 	  This driver supports Fujitsu M-5MOLS camera sensor with ISP
diff --git a/drivers/media/i2c/max2175.c b/drivers/media/i2c/max2175.c
index 506a30e69ced..03b4ed3a61b8 100644
--- a/drivers/media/i2c/max2175.c
+++ b/drivers/media/i2c/max2175.c
@@ -1194,7 +1194,7 @@ static const struct v4l2_ctrl_ops max2175_ctrl_ops = {
 
 /*
  * I2S output enable/disable configuration. This is a private control.
- * Refer to Documentation/media/v4l-drivers/max2175.rst for more details.
+ * Refer to Documentation/userspace-api/media/drivers/max2175.rst for more details.
  */
 static const struct v4l2_ctrl_config max2175_i2s_en = {
 	.ops = &max2175_ctrl_ops,
@@ -1210,7 +1210,7 @@ static const struct v4l2_ctrl_config max2175_i2s_en = {
 
 /*
  * HSLS value control LO freq adjacent location configuration.
- * Refer to Documentation/media/v4l-drivers/max2175.rst for more details.
+ * Refer to Documentation/userspace-api/media/drivers/max2175.rst for more details.
  */
 static const struct v4l2_ctrl_config max2175_hsls = {
 	.ops = &max2175_ctrl_ops,
@@ -1226,7 +1226,7 @@ static const struct v4l2_ctrl_config max2175_hsls = {
 /*
  * Rx modes below are a set of preset configurations that decides the tuner's
  * sck and sample rate of transmission. They are separate for EU & NA regions.
- * Refer to Documentation/media/v4l-drivers/max2175.rst for more details.
+ * Refer to Documentation/userspace-api/media/drivers/max2175.rst for more details.
  */
 static const char * const max2175_ctrl_eu_rx_modes[] = {
 	[MAX2175_EU_FM_1_2]	= "EU FM 1.2",
diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c
index 854031f0b64a..2fe4a7ac0592 100644
--- a/drivers/media/i2c/ov5640.c
+++ b/drivers/media/i2c/ov5640.c
@@ -3093,8 +3093,8 @@ static int ov5640_probe(struct i2c_client *client)
 free_ctrls:
 	v4l2_ctrl_handler_free(&sensor->ctrls.handler);
 entity_cleanup:
-	mutex_destroy(&sensor->lock);
 	media_entity_cleanup(&sensor->sd.entity);
+	mutex_destroy(&sensor->lock);
 	return ret;
 }
 
@@ -3104,9 +3104,9 @@ static int ov5640_remove(struct i2c_client *client)
 	struct ov5640_dev *sensor = to_ov5640_dev(sd);
 
 	v4l2_async_unregister_subdev(&sensor->sd);
-	mutex_destroy(&sensor->lock);
 	media_entity_cleanup(&sensor->sd.entity);
 	v4l2_ctrl_handler_free(&sensor->ctrls.handler);
+	mutex_destroy(&sensor->lock);
 
 	return 0;
 }
diff --git a/drivers/media/i2c/smiapp/Kconfig b/drivers/media/i2c/smiapp/Kconfig
index fcaa7f9494a8..6893b532824f 100644
--- a/drivers/media/i2c/smiapp/Kconfig
+++ b/drivers/media/i2c/smiapp/Kconfig
@@ -1,8 +1,9 @@
 # SPDX-License-Identifier: GPL-2.0-only
 config VIDEO_SMIAPP
 	tristate "SMIA++/SMIA sensor support"
-	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && HAVE_CLK
-	depends on MEDIA_CAMERA_SUPPORT
+	depends on I2C && VIDEO_V4L2 && HAVE_CLK
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select VIDEO_SMIAPP_PLL
 	select V4L2_FWNODE
 	help
diff --git a/drivers/media/mc/Kconfig b/drivers/media/mc/Kconfig
index 3b9795cfcb36..7c9628f37196 100644
--- a/drivers/media/mc/Kconfig
+++ b/drivers/media/mc/Kconfig
@@ -1,17 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0
+
 #
 # Media controller
-#	Selectable only for webcam/grabbers, as other drivers don't use it
 #
 
-config MEDIA_CONTROLLER
-	bool "Media Controller API"
-	depends on MEDIA_CAMERA_SUPPORT || MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT
-	help
-	  Enable the media controller API used to query media devices internal
-	  topology and configure it dynamically.
-
-	  This API is mostly used by camera interfaces in embedded platforms.
-
 config MEDIA_CONTROLLER_DVB
 	bool "Enable Media controller for DVB (EXPERIMENTAL)"
 	depends on MEDIA_CONTROLLER && DVB_CORE
@@ -21,7 +13,7 @@ config MEDIA_CONTROLLER_DVB
 	  This is currently experimental.
 
 config MEDIA_CONTROLLER_REQUEST_API
-	bool "Enable Media controller Request API (EXPERIMENTAL)"
+	bool
 	depends on MEDIA_CONTROLLER && STAGING_MEDIA
 	help
 	  DO NOT ENABLE THIS OPTION UNLESS YOU KNOW WHAT YOU'RE DOING.
@@ -31,3 +23,6 @@ config MEDIA_CONTROLLER_REQUEST_API
 
 	  There is currently no intention to provide API or ABI stability for
 	  this new API as of yet.
+
+comment "Please notice that the enabled Media controller Request API is EXPERIMENTAL"
+	depends on MEDIA_CONTROLLER_REQUEST_API
diff --git a/drivers/media/mmc/Kconfig b/drivers/media/mmc/Kconfig
index de0528c6994a..75aa6de08d53 100644
--- a/drivers/media/mmc/Kconfig
+++ b/drivers/media/mmc/Kconfig
@@ -1,3 +1,2 @@
 # SPDX-License-Identifier: GPL-2.0-only
-comment "Supported MMC/SDIO adapters"
 source "drivers/media/mmc/siano/Kconfig"
diff --git a/drivers/media/mmc/siano/Kconfig b/drivers/media/mmc/siano/Kconfig
index 1919f6fea8b1..570696019a9e 100644
--- a/drivers/media/mmc/siano/Kconfig
+++ b/drivers/media/mmc/siano/Kconfig
@@ -2,6 +2,8 @@
 #
 # Siano Mobile Silicon Digital TV device configuration
 #
+comment "MMC/SDIO DVB adapters"
+	depends on DVB_CORE && HAS_DMA && MMC
 
 config SMS_SDIO_DRV
 	tristate "Siano SMS1xxx based MDTV via SDIO interface"
diff --git a/drivers/media/pci/Kconfig b/drivers/media/pci/Kconfig
index dcb3719f440e..2cd8e328dda9 100644
--- a/drivers/media/pci/Kconfig
+++ b/drivers/media/pci/Kconfig
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-only
-if PCI && MEDIA_SUPPORT
+
+if PCI
 
 menuconfig MEDIA_PCI_SUPPORT
 	bool "Media PCI Adapters"
@@ -56,5 +57,16 @@ endif
 
 source "drivers/media/pci/intel/ipu3/Kconfig"
 
+config VIDEO_PCI_SKELETON
+	tristate "Skeleton PCI V4L2 driver"
+	depends on SAMPLES
+	depends on MEDIA_TEST_SUPPORT
+	depends on PCI && VIDEO_V4L2
+	select VIDEOBUF2_MEMOPS
+	select VIDEOBUF2_DMA_CONTIG
+	help
+	  Enable build of the skeleton PCI driver, used as a reference
+	  when developing new drivers.
+
 endif #MEDIA_PCI_SUPPORT
 endif #PCI
diff --git a/drivers/media/pci/bt8xx/Kconfig b/drivers/media/pci/bt8xx/Kconfig
index 75d172a6f54c..3f56decbb681 100644
--- a/drivers/media/pci/bt8xx/Kconfig
+++ b/drivers/media/pci/bt8xx/Kconfig
@@ -17,7 +17,7 @@ config VIDEO_BT848
 	help
 	  Support for BT848 based frame grabber/overlay boards. This includes
 	  the Miro, Hauppauge and STB boards. Please read the material in
-	  <file:Documentation/media/v4l-drivers/bttv.rst> for more information.
+	  <file:Documentation/admin-guide/media/bttv.rst> for more information.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called bttv.
diff --git a/drivers/media/pci/cobalt/Kconfig b/drivers/media/pci/cobalt/Kconfig
index e0e7df460a92..d8d9ea6b09bc 100644
--- a/drivers/media/pci/cobalt/Kconfig
+++ b/drivers/media/pci/cobalt/Kconfig
@@ -1,11 +1,13 @@
 # SPDX-License-Identifier: GPL-2.0-only
 config VIDEO_COBALT
 	tristate "Cisco Cobalt support"
-	depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
+	depends on VIDEO_V4L2 && I2C
 	depends on PCI_MSI && MTD_COMPLEX_MAPPINGS
 	depends on (GPIOLIB && DRM_I2C_ADV7511=n) || COMPILE_TEST
 	depends on SND
 	depends on MTD
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select I2C_ALGOBIT
 	select SND_PCM
 	select VIDEO_ADV7604
diff --git a/drivers/media/pci/cx18/cx18-streams.c b/drivers/media/pci/cx18/cx18-streams.c
index 3178df3c4922..c41bae118415 100644
--- a/drivers/media/pci/cx18/cx18-streams.c
+++ b/drivers/media/pci/cx18/cx18-streams.c
@@ -845,7 +845,7 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
 
 		/*
 		 * Audio related reset according to
-		 * Documentation/media/v4l-drivers/cx2341x.rst
+		 * Documentation/driver-api/media/drivers/cx2341x-devel.rst
 		 */
 		if (atomic_read(&cx->ana_capturing) == 0)
 			cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2,
@@ -853,7 +853,7 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
 
 		/*
 		 * Number of lines for Field 1 & Field 2 according to
-		 * Documentation/media/v4l-drivers/cx2341x.rst
+		 * Documentation/driver-api/media/drivers/cx2341x-devel.rst
 		 * Field 1 is 312 for 625 line systems in BT.656
 		 * Field 2 is 313 for 625 line systems in BT.656
 		 */
diff --git a/drivers/media/pci/cx88/cx88-core.c b/drivers/media/pci/cx88/cx88-core.c
index dcadf78657d6..48c8a3429542 100644
--- a/drivers/media/pci/cx88/cx88-core.c
+++ b/drivers/media/pci/cx88/cx88-core.c
@@ -1070,8 +1070,7 @@ void cx88_core_put(struct cx88_core *core, struct pci_dev *pci)
 	mutex_lock(&devlist);
 	cx88_ir_fini(core);
 	if (core->i2c_rc == 0) {
-		if (core->i2c_rtc)
-			i2c_unregister_device(core->i2c_rtc);
+		i2c_unregister_device(core->i2c_rtc);
 		i2c_del_adapter(&core->i2c_adap);
 	}
 	list_del(&core->devlist);
diff --git a/drivers/media/pci/cx88/cx88-input.c b/drivers/media/pci/cx88/cx88-input.c
index c7c2acd55266..7e0fed9cd200 100644
--- a/drivers/media/pci/cx88/cx88-input.c
+++ b/drivers/media/pci/cx88/cx88-input.c
@@ -638,7 +638,7 @@ void cx88_i2c_init_ir(struct cx88_core *core)
 				   I2C_SMBUS_READ, 0,
 				   I2C_SMBUS_QUICK, NULL) >= 0) {
 			info.addr = *addrp;
-			i2c_new_device(&core->i2c_adap, &info);
+			i2c_new_client_device(&core->i2c_adap, &info);
 			break;
 		}
 	}
diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c
index 6aabc45aa93c..ba0e9660a047 100644
--- a/drivers/media/pci/cx88/cx88-video.c
+++ b/drivers/media/pci/cx88/cx88-video.c
@@ -1385,7 +1385,7 @@ static int cx8800_initdev(struct pci_dev *pci_dev,
 		};
 
 		request_module("rtc-isl1208");
-		core->i2c_rtc = i2c_new_device(&core->i2c_adap, &rtc_info);
+		core->i2c_rtc = i2c_new_client_device(&core->i2c_adap, &rtc_info);
 	}
 		/* fall-through */
 	case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
diff --git a/drivers/media/pci/ddbridge/Kconfig b/drivers/media/pci/ddbridge/Kconfig
index dab34fb85c09..169efd558e45 100644
--- a/drivers/media/pci/ddbridge/Kconfig
+++ b/drivers/media/pci/ddbridge/Kconfig
@@ -15,7 +15,6 @@ config DVB_DDBRIDGE
 	select MEDIA_TUNER_TDA18212 if MEDIA_SUBDRV_AUTOSELECT
 	select DVB_MXL5XX if MEDIA_SUBDRV_AUTOSELECT
 	select DVB_CXD2099 if MEDIA_SUBDRV_AUTOSELECT
-	select DVB_DUMMY_FE if MEDIA_SUBDRV_AUTOSELECT
 	help
 	  Support for cards with the Digital Devices PCI express bridge:
 	  - Octopus PCIe Bridge
diff --git a/drivers/media/pci/ddbridge/Makefile b/drivers/media/pci/ddbridge/Makefile
index 2b77c8d0eb2e..5e7eab81173b 100644
--- a/drivers/media/pci/ddbridge/Makefile
+++ b/drivers/media/pci/ddbridge/Makefile
@@ -7,7 +7,7 @@ ddbridge-objs := ddbridge-main.o ddbridge-core.o ddbridge-ci.o \
 		ddbridge-hw.o ddbridge-i2c.o ddbridge-max.o ddbridge-mci.o \
 		ddbridge-sx8.o
 
-obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o
+obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o ddbridge-dummy-fe.o
 
 ccflags-y += -I $(srctree)/drivers/media/dvb-frontends/
 ccflags-y += -I $(srctree)/drivers/media/tuners/
diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c
index 7a2d19682fe3..7cabb9e9ffe2 100644
--- a/drivers/media/pci/ddbridge/ddbridge-core.c
+++ b/drivers/media/pci/ddbridge/ddbridge-core.c
@@ -50,7 +50,7 @@
 #include "stv6111.h"
 #include "lnbh25.h"
 #include "cxd2099.h"
-#include "dvb_dummy_fe.h"
+#include "ddbridge-dummy-fe.h"
 
 /****************************************************************************/
 
@@ -1265,7 +1265,7 @@ static int demod_attach_dummy(struct ddb_input *input)
 	struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1];
 	struct device *dev = input->port->dev->dev;
 
-	dvb->fe = dvb_attach(dvb_dummy_fe_qam_attach);
+	dvb->fe = dvb_attach(ddbridge_dummy_fe_qam_attach);
 	if (!dvb->fe) {
 		dev_err(dev, "QAM dummy attach failed!\n");
 		return -ENODEV;
diff --git a/drivers/media/pci/ddbridge/ddbridge-dummy-fe.c b/drivers/media/pci/ddbridge/ddbridge-dummy-fe.c
new file mode 100644
index 000000000000..6868a0c4fc82
--- /dev/null
+++ b/drivers/media/pci/ddbridge/ddbridge-dummy-fe.c
@@ -0,0 +1,153 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ *  Driver for Dummy Frontend
+ *
+ *  Written by Emard <emard@softhome.net>
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
+#include <media/dvb_frontend.h>
+#include "ddbridge-dummy-fe.h"
+
+struct ddbridge_dummy_fe_state {
+	struct dvb_frontend frontend;
+};
+
+static int ddbridge_dummy_fe_read_status(struct dvb_frontend *fe,
+				    enum fe_status *status)
+{
+	*status = FE_HAS_SIGNAL
+		| FE_HAS_CARRIER
+		| FE_HAS_VITERBI
+		| FE_HAS_SYNC
+		| FE_HAS_LOCK;
+
+	return 0;
+}
+
+static int ddbridge_dummy_fe_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+	*ber = 0;
+	return 0;
+}
+
+static int ddbridge_dummy_fe_read_signal_strength(struct dvb_frontend *fe,
+					     u16 *strength)
+{
+	*strength = 0;
+	return 0;
+}
+
+static int ddbridge_dummy_fe_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+	*snr = 0;
+	return 0;
+}
+
+static int ddbridge_dummy_fe_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+	*ucblocks = 0;
+	return 0;
+}
+
+/*
+ * Should only be implemented if it actually reads something from the hardware.
+ * Also, it should check for the locks, in order to avoid report wrong data
+ * to userspace.
+ */
+static int ddbridge_dummy_fe_get_frontend(struct dvb_frontend *fe,
+				     struct dtv_frontend_properties *p)
+{
+	return 0;
+}
+
+static int ddbridge_dummy_fe_set_frontend(struct dvb_frontend *fe)
+{
+	if (fe->ops.tuner_ops.set_params) {
+		fe->ops.tuner_ops.set_params(fe);
+		if (fe->ops.i2c_gate_ctrl)
+			fe->ops.i2c_gate_ctrl(fe, 0);
+	}
+
+	return 0;
+}
+
+static int ddbridge_dummy_fe_sleep(struct dvb_frontend *fe)
+{
+	return 0;
+}
+
+static int ddbridge_dummy_fe_init(struct dvb_frontend *fe)
+{
+	return 0;
+}
+
+static void ddbridge_dummy_fe_release(struct dvb_frontend *fe)
+{
+	struct ddbridge_dummy_fe_state *state = fe->demodulator_priv;
+
+	kfree(state);
+}
+
+static const struct dvb_frontend_ops ddbridge_dummy_fe_qam_ops;
+
+struct dvb_frontend *ddbridge_dummy_fe_qam_attach(void)
+{
+	struct ddbridge_dummy_fe_state *state = NULL;
+
+	/* allocate memory for the internal state */
+	state = kzalloc(sizeof(struct ddbridge_dummy_fe_state), GFP_KERNEL);
+	if (!state)
+		return NULL;
+
+	/* create dvb_frontend */
+	memcpy(&state->frontend.ops,
+	       &ddbridge_dummy_fe_qam_ops,
+	       sizeof(struct dvb_frontend_ops));
+
+	state->frontend.demodulator_priv = state;
+	return &state->frontend;
+}
+EXPORT_SYMBOL(ddbridge_dummy_fe_qam_attach);
+
+static const struct dvb_frontend_ops ddbridge_dummy_fe_qam_ops = {
+	.delsys = { SYS_DVBC_ANNEX_A },
+	.info = {
+		.name			= "ddbridge dummy DVB-C",
+		.frequency_min_hz	=  51 * MHz,
+		.frequency_max_hz	= 858 * MHz,
+		.frequency_stepsize_hz	= 62500,
+		/* symbol_rate_min: SACLK/64 == (XIN/2)/64 */
+		.symbol_rate_min	= (57840000 / 2) / 64,
+		.symbol_rate_max	= (57840000 / 2) / 4,   /* SACLK/4 */
+		.caps = FE_CAN_QAM_16 |
+			FE_CAN_QAM_32 |
+			FE_CAN_QAM_64 |
+			FE_CAN_QAM_128 |
+			FE_CAN_QAM_256 |
+			FE_CAN_FEC_AUTO |
+			FE_CAN_INVERSION_AUTO
+	},
+
+	.release = ddbridge_dummy_fe_release,
+
+	.init = ddbridge_dummy_fe_init,
+	.sleep = ddbridge_dummy_fe_sleep,
+
+	.set_frontend = ddbridge_dummy_fe_set_frontend,
+	.get_frontend = ddbridge_dummy_fe_get_frontend,
+
+	.read_status = ddbridge_dummy_fe_read_status,
+	.read_ber = ddbridge_dummy_fe_read_ber,
+	.read_signal_strength = ddbridge_dummy_fe_read_signal_strength,
+	.read_snr = ddbridge_dummy_fe_read_snr,
+	.read_ucblocks = ddbridge_dummy_fe_read_ucblocks,
+};
+
+MODULE_DESCRIPTION("ddbridge dummy Frontend");
+MODULE_AUTHOR("Emard");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/pci/ddbridge/ddbridge-dummy-fe.h b/drivers/media/pci/ddbridge/ddbridge-dummy-fe.h
new file mode 100644
index 000000000000..ddf189c09524
--- /dev/null
+++ b/drivers/media/pci/ddbridge/ddbridge-dummy-fe.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ *  Driver for Dummy Frontend
+ *
+ *  Written by Emard <emard@softhome.net>
+ */
+
+#ifndef DDBRIDGE_DUMMY_FE_H
+#define DDBRIDGE_DUMMY_FE_H
+
+#include <linux/dvb/frontend.h>
+#include <media/dvb_frontend.h>
+
+struct dvb_frontend *ddbridge_dummy_fe_qam_attach(void);
+
+#endif // DDBRIDGE_DUMMY_FE_H
diff --git a/drivers/media/pci/intel/ipu3/Kconfig b/drivers/media/pci/intel/ipu3/Kconfig
index f35bba16b60e..82d7f17e6a02 100644
--- a/drivers/media/pci/intel/ipu3/Kconfig
+++ b/drivers/media/pci/intel/ipu3/Kconfig
@@ -2,9 +2,9 @@
 config VIDEO_IPU3_CIO2
 	tristate "Intel ipu3-cio2 driver"
 	depends on VIDEO_V4L2 && PCI
-	depends on VIDEO_V4L2_SUBDEV_API
 	depends on (X86 && ACPI) || COMPILE_TEST
-	depends on MEDIA_CONTROLLER
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select V4L2_FWNODE
 	select VIDEOBUF2_DMA_SG
 
diff --git a/drivers/media/pci/meye/Kconfig b/drivers/media/pci/meye/Kconfig
index b37da612dd0c..fed1f4a01817 100644
--- a/drivers/media/pci/meye/Kconfig
+++ b/drivers/media/pci/meye/Kconfig
@@ -7,7 +7,7 @@ config VIDEO_MEYE
 	help
 	  This is the video4linux driver for the Motion Eye camera found
 	  in the Vaio Picturebook laptops. Please read the material in
-	  <file:Documentation/media/v4l-drivers/meye.rst> for more information.
+	  <file:Documentation/admin-guide/media/meye.rst> for more information.
 
 	  If you say Y or M here, you need to say Y or M to "Sony Laptop
 	  Extras" in the misc device section.
diff --git a/drivers/media/pci/saa7134/saa7134-input.c b/drivers/media/pci/saa7134/saa7134-input.c
index 9aea7c30380b..8610eb473b39 100644
--- a/drivers/media/pci/saa7134/saa7134-input.c
+++ b/drivers/media/pci/saa7134/saa7134-input.c
@@ -982,7 +982,7 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
 
 	if (dev->init_data.name)
 		info.platform_data = &dev->init_data;
-	i2c_new_device(&dev->i2c_adap, &info);
+	i2c_new_client_device(&dev->i2c_adap, &info);
 }
 
 static int saa7134_raw_decode_irq(struct saa7134_dev *dev)
diff --git a/drivers/media/pci/sta2x11/Kconfig b/drivers/media/pci/sta2x11/Kconfig
index 011b766f0bff..4dd98f94a91e 100644
--- a/drivers/media/pci/sta2x11/Kconfig
+++ b/drivers/media/pci/sta2x11/Kconfig
@@ -1,12 +1,12 @@
 # SPDX-License-Identifier: GPL-2.0-only
 config STA2X11_VIP
 	tristate "STA2X11 VIP Video For Linux"
+	depends on PCI && VIDEO_V4L2 && VIRT_TO_BUS && I2C
 	depends on STA2X11 || COMPILE_TEST
 	select VIDEO_ADV7180 if MEDIA_SUBDRV_AUTOSELECT
 	select VIDEOBUF2_DMA_CONTIG
-	depends on PCI && VIDEO_V4L2 && VIRT_TO_BUS
-	depends on VIDEO_V4L2_SUBDEV_API
-	depends on I2C
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	help
 	  Say Y for support for STA2X11 VIP (Video Input Port) capture
 	  device.
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index e01bbb9dd1c1..b1ac9c6c9cdb 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -5,7 +5,6 @@
 
 menuconfig V4L_PLATFORM_DRIVERS
 	bool "V4L platform devices"
-	depends on MEDIA_CAMERA_SUPPORT
 	help
 	  Say Y here to enable support for platform-specific V4L drivers.
 
@@ -43,7 +42,6 @@ config VIDEO_ASPEED
 
 config VIDEO_SH_VOU
 	tristate "SuperH VOU video output driver"
-	depends on MEDIA_CAMERA_SUPPORT
 	depends on VIDEO_DEV && I2C
 	depends on ARCH_SHMOBILE || COMPILE_TEST
 	select VIDEOBUF2_DMA_CONTIG
@@ -65,7 +63,9 @@ config VIDEO_VIU
 config VIDEO_MUX
 	tristate "Video Multiplexer"
 	select MULTIPLEXER
-	depends on VIDEO_V4L2 && OF && VIDEO_V4L2_SUBDEV_API && MEDIA_CONTROLLER
+	depends on VIDEO_V4L2 && OF
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select REGMAP
 	select V4L2_FWNODE
 	help
@@ -73,10 +73,12 @@ config VIDEO_MUX
 
 config VIDEO_OMAP3
 	tristate "OMAP 3 Camera support"
-	depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
+	depends on VIDEO_V4L2 && I2C
 	depends on (ARCH_OMAP3 && OMAP_IOMMU) || COMPILE_TEST
 	depends on COMMON_CLK && OF
 	select ARM_DMA_USE_IOMMU if OMAP_IOMMU
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select VIDEOBUF2_DMA_CONTIG
 	select MFD_SYSCON
 	select V4L2_FWNODE
@@ -101,16 +103,19 @@ config VIDEO_PXA27x
 
 config VIDEO_QCOM_CAMSS
 	tristate "Qualcomm V4L2 Camera Subsystem driver"
-	depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on VIDEO_V4L2
 	depends on (ARCH_QCOM && IOMMU_DMA) || COMPILE_TEST
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select VIDEOBUF2_DMA_SG
 	select V4L2_FWNODE
 
 config VIDEO_S3C_CAMIF
 	tristate "Samsung S3C24XX/S3C64XX SoC Camera Interface driver"
-	depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
-	depends on PM
+	depends on VIDEO_V4L2 && I2C && PM
 	depends on ARCH_S3C64XX || PLAT_S3C24XX || COMPILE_TEST
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select VIDEOBUF2_DMA_CONTIG
 	help
 	  This is a v4l2 driver for s3c24xx and s3c64xx SoC series camera
@@ -121,9 +126,10 @@ config VIDEO_S3C_CAMIF
 
 config VIDEO_STM32_DCMI
 	tristate "STM32 Digital Camera Memory Interface (DCMI) support"
-	depends on VIDEO_V4L2 && OF && MEDIA_CONTROLLER
+	depends on VIDEO_V4L2 && OF
 	depends on ARCH_STM32 || COMPILE_TEST
 	select VIDEOBUF2_DMA_CONTIG
+	select MEDIA_CONTROLLER
 	select V4L2_FWNODE
 	help
 	  This module makes the STM32 Digital Camera Memory Interface (DCMI)
@@ -150,7 +156,9 @@ source "drivers/media/platform/sunxi/Kconfig"
 
 config VIDEO_TI_CAL
 	tristate "TI CAL (Camera Adaptation Layer) driver"
-	depends on VIDEO_DEV && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on VIDEO_DEV && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	depends on SOC_DRA7XX || ARCH_K3 || COMPILE_TEST
 	select VIDEOBUF2_DMA_CONTIG
 	select V4L2_FWNODE
@@ -165,7 +173,6 @@ endif # V4L_PLATFORM_DRIVERS
 menuconfig V4L_MEM2MEM_DRIVERS
 	bool "Memory-to-memory multimedia devices"
 	depends on VIDEO_V4L2
-	depends on MEDIA_CAMERA_SUPPORT
 	help
 	  Say Y here to enable selecting drivers for V4L devices that
 	  use system memory for both source and destination buffers, as opposed
@@ -180,6 +187,7 @@ config VIDEO_CODA
 	select SRAM
 	select VIDEOBUF2_DMA_CONTIG
 	select VIDEOBUF2_VMALLOC
+	select V4L2_JPEG_HELPER
 	select V4L2_MEM2MEM_DEV
 	select GENERIC_ALLOCATOR
 	help
@@ -435,9 +443,11 @@ config VIDEO_RENESAS_FCP
 
 config VIDEO_RENESAS_VSP1
 	tristate "Renesas VSP1 Video Processing Engine"
-	depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on VIDEO_V4L2
 	depends on ARCH_RENESAS || COMPILE_TEST
 	depends on (!ARM64 && !VIDEO_RENESAS_FCP) || VIDEO_RENESAS_FCP
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select VIDEOBUF2_DMA_CONTIG
 	select VIDEOBUF2_VMALLOC
 	help
@@ -532,29 +542,6 @@ config VIDEO_TI_SC
 config VIDEO_TI_CSC
 	tristate
 
-menuconfig V4L_TEST_DRIVERS
-	bool "Media test drivers"
-	depends on MEDIA_CAMERA_SUPPORT
-
-if V4L_TEST_DRIVERS
-
-source "drivers/media/platform/vimc/Kconfig"
-
-source "drivers/media/platform/vivid/Kconfig"
-
-config VIDEO_VIM2M
-	tristate "Virtual Memory-to-Memory Driver"
-	depends on VIDEO_DEV && VIDEO_V4L2
-	select VIDEOBUF2_VMALLOC
-	select V4L2_MEM2MEM_DEV
-	help
-	  This is a virtual test device for the memory-to-memory driver
-	  framework.
-
-source "drivers/media/platform/vicodec/Kconfig"
-
-endif #V4L_TEST_DRIVERS
-
 menuconfig DVB_PLATFORM_DRIVERS
 	bool "DVB platform devices"
 	depends on MEDIA_DIGITAL_TV_SUPPORT
@@ -565,131 +552,6 @@ if DVB_PLATFORM_DRIVERS
 source "drivers/media/platform/sti/c8sectpfe/Kconfig"
 endif #DVB_PLATFORM_DRIVERS
 
-menuconfig CEC_PLATFORM_DRIVERS
-	bool "CEC platform devices"
-	depends on MEDIA_CEC_SUPPORT
-
-if CEC_PLATFORM_DRIVERS
-
-config VIDEO_CROS_EC_CEC
-	tristate "ChromeOS EC CEC driver"
-	depends on CROS_EC
-	select CEC_CORE
-	select CEC_NOTIFIER
-	select CROS_EC_PROTO
-	help
-	  If you say yes here you will get support for the
-	  ChromeOS Embedded Controller's CEC.
-	  The CEC bus is present in the HDMI connector and enables communication
-	  between compatible devices.
-
-config VIDEO_MESON_AO_CEC
-	tristate "Amlogic Meson AO CEC driver"
-	depends on ARCH_MESON || COMPILE_TEST
-	select CEC_CORE
-	select CEC_NOTIFIER
-	help
-	  This is a driver for Amlogic Meson SoCs AO CEC interface. It uses the
-	  generic CEC framework interface.
-	  CEC bus is present in the HDMI connector and enables communication
-
-config VIDEO_MESON_G12A_AO_CEC
-	tristate "Amlogic Meson G12A AO CEC driver"
-	depends on ARCH_MESON || COMPILE_TEST
-	depends on COMMON_CLK && OF
-	select REGMAP
-	select REGMAP_MMIO
-	select CEC_CORE
-	select CEC_NOTIFIER
-	---help---
-	  This is a driver for Amlogic Meson G12A SoCs AO CEC interface.
-	  This driver if for the new AO-CEC module found in G12A SoCs,
-	  usually named AO_CEC_B in documentation.
-	  It uses the generic CEC framework interface.
-	  CEC bus is present in the HDMI connector and enables communication
-	  between compatible devices.
-
-config CEC_GPIO
-	tristate "Generic GPIO-based CEC driver"
-	depends on PREEMPTION || COMPILE_TEST
-	select CEC_CORE
-	select CEC_PIN
-	select CEC_NOTIFIER
-	select GPIOLIB
-	help
-	  This is a generic GPIO-based CEC driver.
-	  The CEC bus is present in the HDMI connector and enables communication
-	  between compatible devices.
-
-config VIDEO_SAMSUNG_S5P_CEC
-	tristate "Samsung S5P CEC driver"
-	depends on ARCH_EXYNOS || COMPILE_TEST
-	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.
-
-config VIDEO_STI_HDMI_CEC
-	tristate "STMicroelectronics STiH4xx HDMI CEC driver"
-	depends on ARCH_STI || COMPILE_TEST
-	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.
-
-config VIDEO_STM32_HDMI_CEC
-	tristate "STMicroelectronics STM32 HDMI CEC driver"
-	depends on ARCH_STM32 || COMPILE_TEST
-	select REGMAP
-	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.
-
-config VIDEO_TEGRA_HDMI_CEC
-	tristate "Tegra HDMI CEC driver"
-	depends on ARCH_TEGRA || COMPILE_TEST
-	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.
-
-config VIDEO_SECO_CEC
-	tristate "SECO Boards HDMI CEC driver"
-	depends on (X86 || IA64) || COMPILE_TEST
-	depends on PCI && DMI
-	select CEC_CORE
-	select CEC_NOTIFIER
-	help
-	  This is a driver for SECO Boards integrated CEC interface.
-	  Selecting it will enable support for this device.
-	  CEC bus is present in the HDMI connector and enables communication
-	  between compatible devices.
-
-config VIDEO_SECO_RC
-	bool "SECO Boards IR RC5 support"
-	depends on VIDEO_SECO_CEC
-	depends on RC_CORE=y || RC_CORE = VIDEO_SECO_CEC
-	help
-	  If you say yes here you will get support for the
-	  SECO Boards Consumer-IR in seco-cec driver.
-	  The embedded controller supports RC5 protocol only, default mapping
-	  is set to rc-hauppauge.
-
-endif #CEC_PLATFORM_DRIVERS
-
 menuconfig SDR_PLATFORM_DRIVERS
 	bool "SDR platform devices"
 	depends on MEDIA_SDR_SUPPORT
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index d13db96e3015..ac31d4748869 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -14,11 +14,6 @@ obj-$(CONFIG_VIDEO_PXA27x)	+= pxa_camera.o
 
 obj-$(CONFIG_VIDEO_VIU) += fsl-viu.o
 
-obj-$(CONFIG_VIDEO_VIMC)		+= vimc/
-obj-$(CONFIG_VIDEO_VIVID)		+= vivid/
-obj-$(CONFIG_VIDEO_VIM2M)		+= vim2m.o
-obj-$(CONFIG_VIDEO_VICODEC)		+= vicodec/
-
 obj-y	+= ti-vpe/
 
 obj-$(CONFIG_VIDEO_MX2_EMMAPRP)		+= mx2_emmaprp.o
@@ -28,8 +23,6 @@ obj-$(CONFIG_VIDEO_IMX_PXP)		+= imx-pxp.o
 
 obj-$(CONFIG_VIDEO_SH_VEU)		+= sh_veu.o
 
-obj-$(CONFIG_CEC_GPIO)			+= cec-gpio/
-
 obj-$(CONFIG_VIDEO_MEM2MEM_DEINTERLACE)	+= m2m-deinterlace.o
 
 obj-$(CONFIG_VIDEO_MUX)			+= video-mux.o
@@ -40,22 +33,16 @@ obj-$(CONFIG_VIDEO_SAMSUNG_S5P_JPEG)	+= s5p-jpeg/
 obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC)	+= s5p-mfc/
 
 obj-$(CONFIG_VIDEO_SAMSUNG_S5P_G2D)	+= s5p-g2d/
-obj-$(CONFIG_VIDEO_SAMSUNG_S5P_CEC)	+= s5p-cec/
 obj-$(CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC)	+= exynos-gsc/
 
 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_DELTA)		+= sti/delta/
 
-obj-$(CONFIG_VIDEO_TEGRA_HDMI_CEC)	+= tegra-cec/
-
 obj-y					+= stm32/
 
-obj-$(CONFIG_VIDEO_SECO_CEC)		+= seco-cec/
-
 obj-y					+= davinci/
 
 obj-$(CONFIG_VIDEO_SH_VOU)		+= sh_vou.o
@@ -94,8 +81,4 @@ obj-$(CONFIG_VIDEO_QCOM_CAMSS)		+= qcom/camss/
 
 obj-$(CONFIG_VIDEO_QCOM_VENUS)		+= qcom/venus/
 
-obj-y					+= meson/
-
-obj-y					+= cros-ec-cec/
-
 obj-y					+= sunxi/
diff --git a/drivers/media/platform/am437x/Kconfig b/drivers/media/platform/am437x/Kconfig
index d6f2e3d0cbef..9ef898f512de 100644
--- a/drivers/media/platform/am437x/Kconfig
+++ b/drivers/media/platform/am437x/Kconfig
@@ -1,8 +1,10 @@
 # SPDX-License-Identifier: GPL-2.0-only
 config VIDEO_AM437X_VPFE
 	tristate "TI AM437x VPFE video capture driver"
-	depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on VIDEO_V4L2
 	depends on SOC_AM43XX || COMPILE_TEST
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select VIDEOBUF2_DMA_CONTIG
 	select V4L2_FWNODE
 	help
diff --git a/drivers/media/platform/atmel/Kconfig b/drivers/media/platform/atmel/Kconfig
index 5ae3f60b81b1..1850fe7f9360 100644
--- a/drivers/media/platform/atmel/Kconfig
+++ b/drivers/media/platform/atmel/Kconfig
@@ -1,8 +1,10 @@
 # SPDX-License-Identifier: GPL-2.0-only
 config VIDEO_ATMEL_ISC
 	tristate "ATMEL Image Sensor Controller (ISC) support"
-	depends on VIDEO_V4L2 && COMMON_CLK && VIDEO_V4L2_SUBDEV_API
+	depends on VIDEO_V4L2 && COMMON_CLK
 	depends on ARCH_AT91 || COMPILE_TEST
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select VIDEOBUF2_DMA_CONTIG
 	select REGMAP_MMIO
 	select V4L2_FWNODE
diff --git a/drivers/media/platform/cadence/Kconfig b/drivers/media/platform/cadence/Kconfig
index c154e368d701..80cf601323ce 100644
--- a/drivers/media/platform/cadence/Kconfig
+++ b/drivers/media/platform/cadence/Kconfig
@@ -13,8 +13,8 @@ if VIDEO_CADENCE
 config VIDEO_CADENCE_CSI2RX
 	tristate "Cadence MIPI-CSI2 RX Controller"
 	depends on VIDEO_V4L2
-	depends on MEDIA_CONTROLLER
-	depends on VIDEO_V4L2_SUBDEV_API
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select V4L2_FWNODE
 	help
 	  Support for the Cadence MIPI CSI2 Receiver controller.
@@ -25,8 +25,8 @@ config VIDEO_CADENCE_CSI2RX
 config VIDEO_CADENCE_CSI2TX
 	tristate "Cadence MIPI-CSI2 TX Controller"
 	depends on VIDEO_V4L2
-	depends on MEDIA_CONTROLLER
-	depends on VIDEO_V4L2_SUBDEV_API
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select V4L2_FWNODE
 	help
 	  Support for the Cadence MIPI CSI2 Transceiver controller.
diff --git a/drivers/media/platform/cec-gpio/Makefile b/drivers/media/platform/cec-gpio/Makefile
deleted file mode 100644
index a40c621dbd24..000000000000
--- a/drivers/media/platform/cec-gpio/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_CEC_GPIO) += cec-gpio.o
diff --git a/drivers/media/platform/cec-gpio/cec-gpio.c b/drivers/media/platform/cec-gpio/cec-gpio.c
deleted file mode 100644
index 42d2c2cd9a78..000000000000
--- a/drivers/media/platform/cec-gpio/cec-gpio.c
+++ /dev/null
@@ -1,298 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include <linux/gpio/consumer.h>
-#include <media/cec-notifier.h>
-#include <media/cec-pin.h>
-
-struct cec_gpio {
-	struct cec_adapter	*adap;
-	struct cec_notifier	*notifier;
-	struct device		*dev;
-
-	struct gpio_desc	*cec_gpio;
-	int			cec_irq;
-	bool			cec_is_low;
-
-	struct gpio_desc	*hpd_gpio;
-	int			hpd_irq;
-	bool			hpd_is_high;
-	ktime_t			hpd_ts;
-
-	struct gpio_desc	*v5_gpio;
-	int			v5_irq;
-	bool			v5_is_high;
-	ktime_t			v5_ts;
-};
-
-static bool cec_gpio_read(struct cec_adapter *adap)
-{
-	struct cec_gpio *cec = cec_get_drvdata(adap);
-
-	if (cec->cec_is_low)
-		return false;
-	return gpiod_get_value(cec->cec_gpio);
-}
-
-static void cec_gpio_high(struct cec_adapter *adap)
-{
-	struct cec_gpio *cec = cec_get_drvdata(adap);
-
-	if (!cec->cec_is_low)
-		return;
-	cec->cec_is_low = false;
-	gpiod_set_value(cec->cec_gpio, 1);
-}
-
-static void cec_gpio_low(struct cec_adapter *adap)
-{
-	struct cec_gpio *cec = cec_get_drvdata(adap);
-
-	if (cec->cec_is_low)
-		return;
-	cec->cec_is_low = true;
-	gpiod_set_value(cec->cec_gpio, 0);
-}
-
-static irqreturn_t cec_hpd_gpio_irq_handler_thread(int irq, void *priv)
-{
-	struct cec_gpio *cec = priv;
-
-	cec_queue_pin_hpd_event(cec->adap, cec->hpd_is_high, cec->hpd_ts);
-	return IRQ_HANDLED;
-}
-
-static irqreturn_t cec_5v_gpio_irq_handler(int irq, void *priv)
-{
-	struct cec_gpio *cec = priv;
-	bool is_high = gpiod_get_value(cec->v5_gpio);
-
-	if (is_high == cec->v5_is_high)
-		return IRQ_HANDLED;
-	cec->v5_ts = ktime_get();
-	cec->v5_is_high = is_high;
-	return IRQ_WAKE_THREAD;
-}
-
-static irqreturn_t cec_5v_gpio_irq_handler_thread(int irq, void *priv)
-{
-	struct cec_gpio *cec = priv;
-
-	cec_queue_pin_5v_event(cec->adap, cec->v5_is_high, cec->v5_ts);
-	return IRQ_HANDLED;
-}
-
-static irqreturn_t cec_hpd_gpio_irq_handler(int irq, void *priv)
-{
-	struct cec_gpio *cec = priv;
-	bool is_high = gpiod_get_value(cec->hpd_gpio);
-
-	if (is_high == cec->hpd_is_high)
-		return IRQ_HANDLED;
-	cec->hpd_ts = ktime_get();
-	cec->hpd_is_high = is_high;
-	return IRQ_WAKE_THREAD;
-}
-
-static irqreturn_t cec_gpio_irq_handler(int irq, void *priv)
-{
-	struct cec_gpio *cec = priv;
-
-	cec_pin_changed(cec->adap, gpiod_get_value(cec->cec_gpio));
-	return IRQ_HANDLED;
-}
-
-static bool cec_gpio_enable_irq(struct cec_adapter *adap)
-{
-	struct cec_gpio *cec = cec_get_drvdata(adap);
-
-	enable_irq(cec->cec_irq);
-	return true;
-}
-
-static void cec_gpio_disable_irq(struct cec_adapter *adap)
-{
-	struct cec_gpio *cec = cec_get_drvdata(adap);
-
-	disable_irq(cec->cec_irq);
-}
-
-static void cec_gpio_status(struct cec_adapter *adap, struct seq_file *file)
-{
-	struct cec_gpio *cec = cec_get_drvdata(adap);
-
-	seq_printf(file, "mode: %s\n", cec->cec_is_low ? "low-drive" : "read");
-	seq_printf(file, "using irq: %d\n", cec->cec_irq);
-	if (cec->hpd_gpio)
-		seq_printf(file, "hpd: %s\n",
-			   cec->hpd_is_high ? "high" : "low");
-	if (cec->v5_gpio)
-		seq_printf(file, "5V: %s\n",
-			   cec->v5_is_high ? "high" : "low");
-}
-
-static int cec_gpio_read_hpd(struct cec_adapter *adap)
-{
-	struct cec_gpio *cec = cec_get_drvdata(adap);
-
-	if (!cec->hpd_gpio)
-		return -ENOTTY;
-	return gpiod_get_value(cec->hpd_gpio);
-}
-
-static int cec_gpio_read_5v(struct cec_adapter *adap)
-{
-	struct cec_gpio *cec = cec_get_drvdata(adap);
-
-	if (!cec->v5_gpio)
-		return -ENOTTY;
-	return gpiod_get_value(cec->v5_gpio);
-}
-
-static void cec_gpio_free(struct cec_adapter *adap)
-{
-	cec_gpio_disable_irq(adap);
-}
-
-static const struct cec_pin_ops cec_gpio_pin_ops = {
-	.read = cec_gpio_read,
-	.low = cec_gpio_low,
-	.high = cec_gpio_high,
-	.enable_irq = cec_gpio_enable_irq,
-	.disable_irq = cec_gpio_disable_irq,
-	.status = cec_gpio_status,
-	.free = cec_gpio_free,
-	.read_hpd = cec_gpio_read_hpd,
-	.read_5v = cec_gpio_read_5v,
-};
-
-static int cec_gpio_probe(struct platform_device *pdev)
-{
-	struct device *dev = &pdev->dev;
-	struct device *hdmi_dev;
-	struct cec_gpio *cec;
-	u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_MONITOR_ALL | CEC_CAP_MONITOR_PIN;
-	int ret;
-
-	hdmi_dev = cec_notifier_parse_hdmi_phandle(dev);
-	if (PTR_ERR(hdmi_dev) == -EPROBE_DEFER)
-		return PTR_ERR(hdmi_dev);
-	if (IS_ERR(hdmi_dev))
-		caps |= CEC_CAP_PHYS_ADDR;
-
-	cec = devm_kzalloc(dev, sizeof(*cec), GFP_KERNEL);
-	if (!cec)
-		return -ENOMEM;
-
-	cec->dev = dev;
-
-	cec->cec_gpio = devm_gpiod_get(dev, "cec", GPIOD_OUT_HIGH_OPEN_DRAIN);
-	if (IS_ERR(cec->cec_gpio))
-		return PTR_ERR(cec->cec_gpio);
-	cec->cec_irq = gpiod_to_irq(cec->cec_gpio);
-
-	cec->hpd_gpio = devm_gpiod_get_optional(dev, "hpd", GPIOD_IN);
-	if (IS_ERR(cec->hpd_gpio))
-		return PTR_ERR(cec->hpd_gpio);
-
-	cec->v5_gpio = devm_gpiod_get_optional(dev, "v5", GPIOD_IN);
-	if (IS_ERR(cec->v5_gpio))
-		return PTR_ERR(cec->v5_gpio);
-
-	cec->adap = cec_pin_allocate_adapter(&cec_gpio_pin_ops,
-					     cec, pdev->name, caps);
-	if (IS_ERR(cec->adap))
-		return PTR_ERR(cec->adap);
-
-	ret = devm_request_irq(dev, cec->cec_irq, cec_gpio_irq_handler,
-			       IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-			       cec->adap->name, cec);
-	if (ret)
-		goto del_adap;
-
-	cec_gpio_disable_irq(cec->adap);
-
-	if (cec->hpd_gpio) {
-		cec->hpd_irq = gpiod_to_irq(cec->hpd_gpio);
-		ret = devm_request_threaded_irq(dev, cec->hpd_irq,
-			cec_hpd_gpio_irq_handler,
-			cec_hpd_gpio_irq_handler_thread,
-			IRQF_ONESHOT |
-			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
-			"hpd-gpio", cec);
-		if (ret)
-			goto del_adap;
-	}
-
-	if (cec->v5_gpio) {
-		cec->v5_irq = gpiod_to_irq(cec->v5_gpio);
-		ret = devm_request_threaded_irq(dev, cec->v5_irq,
-			cec_5v_gpio_irq_handler,
-			cec_5v_gpio_irq_handler_thread,
-			IRQF_ONESHOT |
-			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
-			"v5-gpio", cec);
-		if (ret)
-			goto del_adap;
-	}
-
-	if (!IS_ERR(hdmi_dev)) {
-		cec->notifier = cec_notifier_cec_adap_register(hdmi_dev, NULL,
-							       cec->adap);
-		if (!cec->notifier) {
-			ret = -ENOMEM;
-			goto del_adap;
-		}
-	}
-
-	ret = cec_register_adapter(cec->adap, &pdev->dev);
-	if (ret)
-		goto unreg_notifier;
-
-	platform_set_drvdata(pdev, cec);
-	return 0;
-
-unreg_notifier:
-	cec_notifier_cec_adap_unregister(cec->notifier, cec->adap);
-del_adap:
-	cec_delete_adapter(cec->adap);
-	return ret;
-}
-
-static int cec_gpio_remove(struct platform_device *pdev)
-{
-	struct cec_gpio *cec = platform_get_drvdata(pdev);
-
-	cec_notifier_cec_adap_unregister(cec->notifier, cec->adap);
-	cec_unregister_adapter(cec->adap);
-	return 0;
-}
-
-static const struct of_device_id cec_gpio_match[] = {
-	{
-		.compatible	= "cec-gpio",
-	},
-	{},
-};
-MODULE_DEVICE_TABLE(of, cec_gpio_match);
-
-static struct platform_driver cec_gpio_pdrv = {
-	.probe	= cec_gpio_probe,
-	.remove = cec_gpio_remove,
-	.driver = {
-		.name		= "cec-gpio",
-		.of_match_table	= cec_gpio_match,
-	},
-};
-
-module_platform_driver(cec_gpio_pdrv);
-
-MODULE_AUTHOR("Hans Verkuil <hans.verkuil@cisco.com>");
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("CEC GPIO driver");
diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c
index d0d093dd8f7c..80ad2db3e9c9 100644
--- a/drivers/media/platform/coda/coda-common.c
+++ b/drivers/media/platform/coda/coda-common.c
@@ -159,6 +159,7 @@ static const struct coda_codec coda9_codecs[] = {
 	CODA_CODEC(CODA9_MODE_DECODE_H264, V4L2_PIX_FMT_H264,   V4L2_PIX_FMT_YUV420, 1920, 1088),
 	CODA_CODEC(CODA9_MODE_DECODE_MP2,  V4L2_PIX_FMT_MPEG2,  V4L2_PIX_FMT_YUV420, 1920, 1088),
 	CODA_CODEC(CODA9_MODE_DECODE_MP4,  V4L2_PIX_FMT_MPEG4,  V4L2_PIX_FMT_YUV420, 1920, 1088),
+	CODA_CODEC(CODA9_MODE_DECODE_MJPG, V4L2_PIX_FMT_JPEG,	V4L2_PIX_FMT_YUV420, 8192, 8192),
 };
 
 struct coda_video_device {
@@ -252,6 +253,22 @@ static const struct coda_video_device coda9_jpeg_encoder = {
 	},
 };
 
+static const struct coda_video_device coda9_jpeg_decoder = {
+	.name = "coda-jpeg-decoder",
+	.type = CODA_INST_DECODER,
+	.ops = &coda9_jpeg_decode_ops,
+	.direct = true,
+	.src_formats = {
+		V4L2_PIX_FMT_JPEG,
+	},
+	.dst_formats = {
+		V4L2_PIX_FMT_NV12,
+		V4L2_PIX_FMT_YUV420,
+		V4L2_PIX_FMT_YVU420,
+		V4L2_PIX_FMT_YUV422P,
+	},
+};
+
 static const struct coda_video_device *codadx6_video_devices[] = {
 	&coda_bit_encoder,
 };
@@ -270,6 +287,7 @@ static const struct coda_video_device *coda7_video_devices[] = {
 
 static const struct coda_video_device *coda9_video_devices[] = {
 	&coda9_jpeg_encoder,
+	&coda9_jpeg_decoder,
 	&coda_bit_encoder,
 	&coda_bit_decoder,
 };
@@ -411,6 +429,12 @@ static int coda_querycap(struct file *file, void *priv,
 	return 0;
 }
 
+static const u32 coda_formats_420[CODA_MAX_FORMATS] = {
+		V4L2_PIX_FMT_NV12,
+		V4L2_PIX_FMT_YUV420,
+		V4L2_PIX_FMT_YVU420,
+};
+
 static int coda_enum_fmt(struct file *file, void *priv,
 			 struct v4l2_fmtdesc *f)
 {
@@ -421,10 +445,33 @@ static int coda_enum_fmt(struct file *file, void *priv,
 
 	if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
 		formats = cvd->src_formats;
-	else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+	else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		struct coda_q_data *q_data_src;
+		struct vb2_queue *src_vq;
+
 		formats = cvd->dst_formats;
-	else
+
+		/*
+		 * If the source format is already fixed, only allow the same
+		 * chroma subsampling.
+		 */
+		q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+		src_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
+					 V4L2_BUF_TYPE_VIDEO_OUTPUT);
+		if (q_data_src->fourcc == V4L2_PIX_FMT_JPEG &&
+		    vb2_is_streaming(src_vq)) {
+			if (ctx->params.jpeg_chroma_subsampling ==
+			    V4L2_JPEG_CHROMA_SUBSAMPLING_420) {
+				formats = coda_formats_420;
+			} else if (ctx->params.jpeg_chroma_subsampling ==
+				   V4L2_JPEG_CHROMA_SUBSAMPLING_422) {
+				f->pixelformat = V4L2_PIX_FMT_YUV422P;
+				return f->index ? -EINVAL : 0;
+			}
+		}
+	} else {
 		return -EINVAL;
+	}
 
 	if (f->index >= CODA_MAX_FORMATS || formats[f->index] == 0)
 		return -EINVAL;
@@ -614,12 +661,23 @@ static int coda_try_fmt_vid_cap(struct file *file, void *priv,
 
 	/*
 	 * If the source format is already fixed, only allow the same output
-	 * resolution
+	 * resolution. When decoding JPEG images, we also have to make sure to
+	 * use the same chroma subsampling.
 	 */
 	src_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
 	if (vb2_is_streaming(src_vq)) {
 		f->fmt.pix.width = q_data_src->width;
 		f->fmt.pix.height = q_data_src->height;
+
+		if (q_data_src->fourcc == V4L2_PIX_FMT_JPEG) {
+			if (ctx->params.jpeg_chroma_subsampling ==
+			    V4L2_JPEG_CHROMA_SUBSAMPLING_420 &&
+			    f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUV422P)
+				f->fmt.pix.pixelformat = V4L2_PIX_FMT_NV12;
+			else if (ctx->params.jpeg_chroma_subsampling ==
+				 V4L2_JPEG_CHROMA_SUBSAMPLING_422)
+				f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P;
+		}
 	}
 
 	f->fmt.pix.colorspace = ctx->colorspace;
@@ -637,12 +695,18 @@ static int coda_try_fmt_vid_cap(struct file *file, void *priv,
 	if (ret < 0)
 		return ret;
 
-	/* The h.264 decoder only returns complete 16x16 macroblocks */
-	if (codec && codec->src_fourcc == V4L2_PIX_FMT_H264) {
-		f->fmt.pix.height = round_up(f->fmt.pix.height, 16);
+	/* The decoders always write complete macroblocks or MCUs */
+	if (ctx->inst_type == CODA_INST_DECODER) {
 		f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 16);
-		f->fmt.pix.sizeimage = f->fmt.pix.bytesperline *
-				       f->fmt.pix.height * 3 / 2;
+		f->fmt.pix.height = round_up(f->fmt.pix.height, 16);
+		if (codec->src_fourcc == V4L2_PIX_FMT_JPEG &&
+		    f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUV422P) {
+			f->fmt.pix.sizeimage = f->fmt.pix.bytesperline *
+					       f->fmt.pix.height * 2;
+		} else {
+			f->fmt.pix.sizeimage = f->fmt.pix.bytesperline *
+					       f->fmt.pix.height * 3 / 2;
+		}
 
 		ret = coda_try_fmt_vdoa(ctx, f, &use_vdoa);
 		if (ret < 0)
@@ -747,6 +811,7 @@ static int coda_s_fmt(struct coda_ctx *ctx, struct v4l2_format *f,
 		/* else fall through */
 	case V4L2_PIX_FMT_YUV420:
 	case V4L2_PIX_FMT_YVU420:
+	case V4L2_PIX_FMT_YUV422P:
 		ctx->tiled_map_type = GDI_LINEAR_FRAME_MAP;
 		break;
 	default:
@@ -1088,6 +1153,51 @@ static int coda_try_decoder_cmd(struct file *file, void *fh,
 	return v4l2_m2m_ioctl_try_decoder_cmd(file, fh, dc);
 }
 
+static bool coda_mark_last_meta(struct coda_ctx *ctx)
+{
+	struct coda_buffer_meta *meta;
+
+	coda_dbg(1, ctx, "marking last meta\n");
+
+	spin_lock(&ctx->buffer_meta_lock);
+	if (list_empty(&ctx->buffer_meta_list)) {
+		spin_unlock(&ctx->buffer_meta_lock);
+		return false;
+	}
+
+	meta = list_last_entry(&ctx->buffer_meta_list, struct coda_buffer_meta,
+			       list);
+	meta->last = true;
+
+	spin_unlock(&ctx->buffer_meta_lock);
+	return true;
+}
+
+static bool coda_mark_last_dst_buf(struct coda_ctx *ctx)
+{
+	struct vb2_v4l2_buffer *buf;
+	struct vb2_buffer *dst_vb;
+	struct vb2_queue *dst_vq;
+	unsigned long flags;
+
+	coda_dbg(1, ctx, "marking last capture buffer\n");
+
+	dst_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+	spin_lock_irqsave(&dst_vq->done_lock, flags);
+	if (list_empty(&dst_vq->done_list)) {
+		spin_unlock_irqrestore(&dst_vq->done_lock, flags);
+		return false;
+	}
+
+	dst_vb = list_last_entry(&dst_vq->done_list, struct vb2_buffer,
+				 done_entry);
+	buf = to_vb2_v4l2_buffer(dst_vb);
+	buf->flags |= V4L2_BUF_FLAG_LAST;
+
+	spin_unlock_irqrestore(&dst_vq->done_lock, flags);
+	return true;
+}
+
 static int coda_decoder_cmd(struct file *file, void *fh,
 			    struct v4l2_decoder_cmd *dc)
 {
@@ -1120,6 +1230,8 @@ static int coda_decoder_cmd(struct file *file, void *fh,
 		stream_end = false;
 		wakeup = false;
 
+		mutex_lock(&ctx->wakeup_mutex);
+
 		buf = v4l2_m2m_last_src_buf(ctx->fh.m2m_ctx);
 		if (buf) {
 			coda_dbg(1, ctx, "marking last pending buffer\n");
@@ -1132,22 +1244,14 @@ static int coda_decoder_cmd(struct file *file, void *fh,
 				stream_end = true;
 			}
 		} else {
-			coda_dbg(1, ctx, "marking last meta\n");
-
-			/* Mark last meta */
-			spin_lock(&ctx->buffer_meta_lock);
-			if (!list_empty(&ctx->buffer_meta_list)) {
-				struct coda_buffer_meta *meta;
-
-				meta = list_last_entry(&ctx->buffer_meta_list,
-						       struct coda_buffer_meta,
-						       list);
-				meta->last = true;
-				stream_end = true;
-			} else {
-				wakeup = true;
-			}
-			spin_unlock(&ctx->buffer_meta_lock);
+			if (ctx->use_bit)
+				if (coda_mark_last_meta(ctx))
+					stream_end = true;
+				else
+					wakeup = true;
+			else
+				if (!coda_mark_last_dst_buf(ctx))
+					wakeup = true;
 		}
 
 		if (stream_end) {
@@ -1164,6 +1268,7 @@ static int coda_decoder_cmd(struct file *file, void *fh,
 			coda_wake_up_capture_queue(ctx);
 		}
 
+		mutex_unlock(&ctx->wakeup_mutex);
 		break;
 	default:
 		return -EINVAL;
@@ -1894,6 +1999,42 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
 			}
 		}
 
+		/*
+		 * Check the first input JPEG buffer to determine chroma
+		 * subsampling.
+		 */
+		if (q_data_src->fourcc == V4L2_PIX_FMT_JPEG) {
+			buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
+			ret = coda_jpeg_decode_header(ctx, &buf->vb2_buf);
+			if (ret < 0) {
+				v4l2_err(v4l2_dev,
+					 "failed to decode JPEG header: %d\n",
+					 ret);
+				goto err;
+			}
+
+			q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+			q_data_dst->width = round_up(q_data_src->width, 16);
+			q_data_dst->height = round_up(q_data_src->height, 16);
+			q_data_dst->bytesperline = q_data_dst->width;
+			if (ctx->params.jpeg_chroma_subsampling ==
+			    V4L2_JPEG_CHROMA_SUBSAMPLING_420) {
+				q_data_dst->sizeimage =
+						q_data_dst->bytesperline *
+						q_data_dst->height * 3 / 2;
+				if (q_data_dst->fourcc != V4L2_PIX_FMT_YUV420)
+					q_data_dst->fourcc = V4L2_PIX_FMT_NV12;
+			} else {
+				q_data_dst->sizeimage =
+						q_data_dst->bytesperline *
+						q_data_dst->height * 2;
+				q_data_dst->fourcc = V4L2_PIX_FMT_YUV422P;
+			}
+			q_data_dst->rect.left = 0;
+			q_data_dst->rect.top = 0;
+			q_data_dst->rect.width = q_data_src->width;
+			q_data_dst->rect.height = q_data_src->height;
+		}
 		ctx->streamon_out = 1;
 	} else {
 		ctx->streamon_cap = 1;
diff --git a/drivers/media/platform/coda/coda-jpeg.c b/drivers/media/platform/coda/coda-jpeg.c
index 92234fd1f4fd..00d19859db50 100644
--- a/drivers/media/platform/coda/coda-jpeg.c
+++ b/drivers/media/platform/coda/coda-jpeg.c
@@ -15,6 +15,7 @@
 
 #include <media/v4l2-common.h>
 #include <media/v4l2-fh.h>
+#include <media/v4l2-jpeg.h>
 #include <media/v4l2-mem2mem.h>
 #include <media/videobuf2-core.h>
 #include <media/videobuf2-dma-contig.h>
@@ -23,10 +24,12 @@
 #include "trace.h"
 
 #define SOI_MARKER	0xffd8
+#define APP9_MARKER	0xffe9
 #define DRI_MARKER	0xffdd
 #define DQT_MARKER	0xffdb
 #define DHT_MARKER	0xffc4
 #define SOF_MARKER	0xffc0
+#define SOS_MARKER	0xffda
 #define EOI_MARKER	0xffd9
 
 enum {
@@ -37,6 +40,18 @@ enum {
 	CODA9_JPEG_FORMAT_400,
 };
 
+struct coda_huff_tab {
+	u8 luma_dc[16 + 12];
+	u8 chroma_dc[16 + 12];
+	u8 luma_ac[16 + 162];
+	u8 chroma_ac[16 + 162];
+
+	/* DC Luma, DC Chroma, AC Luma, AC Chroma */
+	s16	min[4 * 16];
+	s16	max[4 * 16];
+	s8	ptr[4 * 16];
+};
+
 #define CODA9_JPEG_ENC_HUFF_DATA_SIZE	(256 + 256 + 16 + 16)
 
 /*
@@ -247,6 +262,291 @@ bool coda_jpeg_check_buffer(struct coda_ctx *ctx, struct vb2_buffer *vb)
 	return false;
 }
 
+static int coda9_jpeg_gen_dec_huff_tab(struct coda_ctx *ctx, int tab_num);
+
+int coda_jpeg_decode_header(struct coda_ctx *ctx, struct vb2_buffer *vb)
+{
+	struct coda_dev *dev = ctx->dev;
+	u8 *buf = vb2_plane_vaddr(vb, 0);
+	size_t len = vb2_get_plane_payload(vb, 0);
+	struct v4l2_jpeg_scan_header scan_header;
+	struct v4l2_jpeg_reference quantization_tables[4] = { };
+	struct v4l2_jpeg_reference huffman_tables[4] = { };
+	struct v4l2_jpeg_header header = {
+		.scan = &scan_header,
+		.quantization_tables = quantization_tables,
+		.huffman_tables = huffman_tables,
+	};
+	struct coda_q_data *q_data_src;
+	struct coda_huff_tab *huff_tab;
+	int i, j, ret;
+
+	ret = v4l2_jpeg_parse_header(buf, len, &header);
+	if (ret < 0) {
+		v4l2_err(&dev->v4l2_dev, "failed to parse header\n");
+		return ret;
+	}
+
+	ctx->params.jpeg_restart_interval = header.restart_interval;
+
+	/* check frame header */
+	if (header.frame.height > ctx->codec->max_h ||
+	    header.frame.width > ctx->codec->max_w) {
+		v4l2_err(&dev->v4l2_dev, "invalid dimensions: %dx%d\n",
+			 header.frame.width, header.frame.height);
+		return -EINVAL;
+	}
+
+	q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+	if (header.frame.height != q_data_src->height ||
+	    header.frame.width != q_data_src->width) {
+		v4l2_err(&dev->v4l2_dev,
+			 "dimensions don't match format: %dx%d\n",
+			 header.frame.width, header.frame.height);
+		return -EINVAL;
+	}
+
+	if (header.frame.num_components != 3) {
+		v4l2_err(&dev->v4l2_dev,
+			 "unsupported number of components: %d\n",
+			 header.frame.num_components);
+		return -EINVAL;
+	}
+
+	/* install quantization tables */
+	if (quantization_tables[3].start) {
+		v4l2_err(&dev->v4l2_dev,
+			 "only 3 quantization tables supported\n");
+		return -EINVAL;
+	}
+	for (i = 0; i < 3; i++) {
+		if (!quantization_tables[i].start)
+			continue;
+		if (quantization_tables[i].length != 64) {
+			v4l2_err(&dev->v4l2_dev,
+				 "only 8-bit quantization tables supported\n");
+			continue;
+		}
+		if (!ctx->params.jpeg_qmat_tab[i])
+			ctx->params.jpeg_qmat_tab[i] = kmalloc(64, GFP_KERNEL);
+		memcpy(ctx->params.jpeg_qmat_tab[i],
+		       quantization_tables[i].start, 64);
+	}
+
+	/* install Huffman tables */
+	for (i = 0; i < 4; i++) {
+		if (!huffman_tables[i].start) {
+			v4l2_err(&dev->v4l2_dev, "missing Huffman table\n");
+			return -EINVAL;
+		}
+		/* AC tables should be between 17 -> 178, DC between 17 -> 28 */
+		if (huffman_tables[i].length < 17 ||
+		    huffman_tables[i].length > 178 ||
+		    ((i & 2) == 0 && huffman_tables[i].length > 28)) {
+			v4l2_err(&dev->v4l2_dev,
+				 "invalid Huffman table %d length: %zu\n",
+				 i, huffman_tables[i].length);
+			return -EINVAL;
+		}
+	}
+	huff_tab = ctx->params.jpeg_huff_tab;
+	if (!huff_tab) {
+		huff_tab = kzalloc(sizeof(struct coda_huff_tab), GFP_KERNEL);
+		if (!huff_tab)
+			return -ENOMEM;
+		ctx->params.jpeg_huff_tab = huff_tab;
+	}
+
+	memset(huff_tab, 0, sizeof(*huff_tab));
+	memcpy(huff_tab->luma_dc, huffman_tables[0].start, huffman_tables[0].length);
+	memcpy(huff_tab->chroma_dc, huffman_tables[1].start, huffman_tables[1].length);
+	memcpy(huff_tab->luma_ac, huffman_tables[2].start, huffman_tables[2].length);
+	memcpy(huff_tab->chroma_ac, huffman_tables[3].start, huffman_tables[3].length);
+
+	/* check scan header */
+	for (i = 0; i < scan_header.num_components; i++) {
+		struct v4l2_jpeg_scan_component_spec *scan_component;
+
+		scan_component = &scan_header.component[i];
+		for (j = 0; j < header.frame.num_components; j++) {
+			if (header.frame.component[j].component_identifier ==
+			    scan_component->component_selector)
+				break;
+		}
+		if (j == header.frame.num_components)
+			continue;
+
+		ctx->params.jpeg_huff_dc_index[j] =
+			scan_component->dc_entropy_coding_table_selector;
+		ctx->params.jpeg_huff_ac_index[j] =
+			scan_component->ac_entropy_coding_table_selector;
+	}
+
+	/* Generate Huffman table information */
+	for (i = 0; i < 4; i++)
+		coda9_jpeg_gen_dec_huff_tab(ctx, i);
+
+	/* start of entropy coded segment */
+	ctx->jpeg_ecs_offset = header.ecs_offset;
+
+	switch (header.frame.subsampling) {
+	case V4L2_JPEG_CHROMA_SUBSAMPLING_420:
+	case V4L2_JPEG_CHROMA_SUBSAMPLING_422:
+		ctx->params.jpeg_chroma_subsampling = header.frame.subsampling;
+		break;
+	default:
+		v4l2_err(&dev->v4l2_dev, "chroma subsampling not supported: %d",
+			 header.frame.subsampling);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static inline void coda9_jpeg_write_huff_values(struct coda_dev *dev, u8 *bits,
+						int num_values)
+{
+	s8 *values = (s8 *)(bits + 16);
+	int huff_length, i;
+
+	for (huff_length = 0, i = 0; i < 16; i++)
+		huff_length += bits[i];
+	for (i = huff_length; i < num_values; i++)
+		values[i] = -1;
+	for (i = 0; i < num_values; i++)
+		coda_write(dev, (s32)values[i], CODA9_REG_JPEG_HUFF_DATA);
+}
+
+static int coda9_jpeg_dec_huff_setup(struct coda_ctx *ctx)
+{
+	struct coda_huff_tab *huff_tab = ctx->params.jpeg_huff_tab;
+	struct coda_dev *dev = ctx->dev;
+	s16 *huff_min = huff_tab->min;
+	s16 *huff_max = huff_tab->max;
+	s8 *huff_ptr = huff_tab->ptr;
+	int i;
+
+	/* MIN Tables */
+	coda_write(dev, 0x003, CODA9_REG_JPEG_HUFF_CTRL);
+	coda_write(dev, 0x000, CODA9_REG_JPEG_HUFF_ADDR);
+	for (i = 0; i < 4 * 16; i++)
+		coda_write(dev, (s32)huff_min[i], CODA9_REG_JPEG_HUFF_DATA);
+
+	/* MAX Tables */
+	coda_write(dev, 0x403, CODA9_REG_JPEG_HUFF_CTRL);
+	coda_write(dev, 0x440, CODA9_REG_JPEG_HUFF_ADDR);
+	for (i = 0; i < 4 * 16; i++)
+		coda_write(dev, (s32)huff_max[i], CODA9_REG_JPEG_HUFF_DATA);
+
+	/* PTR Tables */
+	coda_write(dev, 0x803, CODA9_REG_JPEG_HUFF_CTRL);
+	coda_write(dev, 0x880, CODA9_REG_JPEG_HUFF_ADDR);
+	for (i = 0; i < 4 * 16; i++)
+		coda_write(dev, (s32)huff_ptr[i], CODA9_REG_JPEG_HUFF_DATA);
+
+	/* VAL Tables: DC Luma, DC Chroma, AC Luma, AC Chroma */
+	coda_write(dev, 0xc03, CODA9_REG_JPEG_HUFF_CTRL);
+	coda9_jpeg_write_huff_values(dev, huff_tab->luma_dc, 12);
+	coda9_jpeg_write_huff_values(dev, huff_tab->chroma_dc, 12);
+	coda9_jpeg_write_huff_values(dev, huff_tab->luma_ac, 162);
+	coda9_jpeg_write_huff_values(dev, huff_tab->chroma_ac, 162);
+	coda_write(dev, 0x000, CODA9_REG_JPEG_HUFF_CTRL);
+	return 0;
+}
+
+static inline void coda9_jpeg_write_qmat_tab(struct coda_dev *dev,
+					     u8 *qmat, int index)
+{
+	int i;
+
+	coda_write(dev, index | 0x3, CODA9_REG_JPEG_QMAT_CTRL);
+	for (i = 0; i < 64; i++)
+		coda_write(dev, qmat[i], CODA9_REG_JPEG_QMAT_DATA);
+	coda_write(dev, 0, CODA9_REG_JPEG_QMAT_CTRL);
+}
+
+static void coda9_jpeg_qmat_setup(struct coda_ctx *ctx)
+{
+	struct coda_dev *dev = ctx->dev;
+	int *qmat_index = ctx->params.jpeg_qmat_index;
+	u8 **qmat_tab = ctx->params.jpeg_qmat_tab;
+
+	coda9_jpeg_write_qmat_tab(dev, qmat_tab[qmat_index[0]], 0x00);
+	coda9_jpeg_write_qmat_tab(dev, qmat_tab[qmat_index[1]], 0x40);
+	coda9_jpeg_write_qmat_tab(dev, qmat_tab[qmat_index[2]], 0x80);
+}
+
+static void coda9_jpeg_dec_bbc_gbu_setup(struct coda_ctx *ctx,
+					 struct vb2_buffer *buf, u32 ecs_offset)
+{
+	struct coda_dev *dev = ctx->dev;
+	int page_ptr, word_ptr, bit_ptr;
+	u32 bbc_base_addr, end_addr;
+	int bbc_cur_pos;
+	int ret, val;
+
+	bbc_base_addr = vb2_dma_contig_plane_dma_addr(buf, 0);
+	end_addr = bbc_base_addr + vb2_get_plane_payload(buf, 0);
+
+	page_ptr = ecs_offset / 256;
+	word_ptr = (ecs_offset % 256) / 4;
+	if (page_ptr & 1)
+		word_ptr += 64;
+	bit_ptr = (ecs_offset % 4) * 8;
+	if (word_ptr & 1)
+		bit_ptr += 32;
+	word_ptr &= ~0x1;
+
+	coda_write(dev, end_addr, CODA9_REG_JPEG_BBC_WR_PTR);
+	coda_write(dev, bbc_base_addr, CODA9_REG_JPEG_BBC_BAS_ADDR);
+
+	/* Leave 3 256-byte page margin to avoid a BBC interrupt */
+	coda_write(dev, end_addr + 256 * 3 + 256, CODA9_REG_JPEG_BBC_END_ADDR);
+	val = DIV_ROUND_UP(vb2_plane_size(buf, 0), 256) + 3;
+	coda_write(dev, BIT(31) | val, CODA9_REG_JPEG_BBC_STRM_CTRL);
+
+	bbc_cur_pos = page_ptr;
+	coda_write(dev, bbc_cur_pos, CODA9_REG_JPEG_BBC_CUR_POS);
+	coda_write(dev, bbc_base_addr + (bbc_cur_pos << 8),
+			CODA9_REG_JPEG_BBC_EXT_ADDR);
+	coda_write(dev, (bbc_cur_pos & 1) << 6, CODA9_REG_JPEG_BBC_INT_ADDR);
+	coda_write(dev, 64, CODA9_REG_JPEG_BBC_DATA_CNT);
+	coda_write(dev, 0, CODA9_REG_JPEG_BBC_COMMAND);
+	do {
+		ret = coda_read(dev, CODA9_REG_JPEG_BBC_BUSY);
+	} while (ret == 1);
+
+	bbc_cur_pos++;
+	coda_write(dev, bbc_cur_pos, CODA9_REG_JPEG_BBC_CUR_POS);
+	coda_write(dev, bbc_base_addr + (bbc_cur_pos << 8),
+			CODA9_REG_JPEG_BBC_EXT_ADDR);
+	coda_write(dev, (bbc_cur_pos & 1) << 6, CODA9_REG_JPEG_BBC_INT_ADDR);
+	coda_write(dev, 64, CODA9_REG_JPEG_BBC_DATA_CNT);
+	coda_write(dev, 0, CODA9_REG_JPEG_BBC_COMMAND);
+	do {
+		ret = coda_read(dev, CODA9_REG_JPEG_BBC_BUSY);
+	} while (ret == 1);
+
+	bbc_cur_pos++;
+	coda_write(dev, bbc_cur_pos, CODA9_REG_JPEG_BBC_CUR_POS);
+	coda_write(dev, 1, CODA9_REG_JPEG_BBC_CTRL);
+
+	coda_write(dev, 0, CODA9_REG_JPEG_GBU_TT_CNT);
+	coda_write(dev, word_ptr, CODA9_REG_JPEG_GBU_WD_PTR);
+	coda_write(dev, 0, CODA9_REG_JPEG_GBU_BBSR);
+	coda_write(dev, 127, CODA9_REG_JPEG_GBU_BBER);
+	if (page_ptr & 1) {
+		coda_write(dev, 0, CODA9_REG_JPEG_GBU_BBIR);
+		coda_write(dev, 0, CODA9_REG_JPEG_GBU_BBHR);
+	} else {
+		coda_write(dev, 64, CODA9_REG_JPEG_GBU_BBIR);
+		coda_write(dev, 64, CODA9_REG_JPEG_GBU_BBHR);
+	}
+	coda_write(dev, 4, CODA9_REG_JPEG_GBU_CTRL);
+	coda_write(dev, bit_ptr, CODA9_REG_JPEG_GBU_FF_RPTR);
+	coda_write(dev, 3, CODA9_REG_JPEG_GBU_CTRL);
+}
+
 static const int bus_req_num[] = {
 	[CODA9_JPEG_FORMAT_420] = 2,
 	[CODA9_JPEG_FORMAT_422] = 3,
@@ -345,6 +645,71 @@ static int coda9_jpeg_gen_enc_huff_tab(struct coda_ctx *ctx, int tab_num,
 #define DC_TABLE_INDEX1		    2
 #define AC_TABLE_INDEX1		    3
 
+static u8 *coda9_jpeg_get_huff_bits(struct coda_ctx *ctx, int tab_num)
+{
+	struct coda_huff_tab *huff_tab = ctx->params.jpeg_huff_tab;
+
+	if (!huff_tab)
+		return NULL;
+
+	switch (tab_num) {
+	case DC_TABLE_INDEX0: return huff_tab->luma_dc;
+	case AC_TABLE_INDEX0: return huff_tab->luma_ac;
+	case DC_TABLE_INDEX1: return huff_tab->chroma_dc;
+	case AC_TABLE_INDEX1: return huff_tab->chroma_ac;
+	}
+
+	return NULL;
+}
+
+static int coda9_jpeg_gen_dec_huff_tab(struct coda_ctx *ctx, int tab_num)
+{
+	int ptr_cnt = 0, huff_code = 0, zero_flag = 0, data_flag = 0;
+	u8 *huff_bits;
+	s16 *huff_max;
+	s16 *huff_min;
+	s8 *huff_ptr;
+	int ofs;
+	int i;
+
+	huff_bits = coda9_jpeg_get_huff_bits(ctx, tab_num);
+	if (!huff_bits)
+		return -EINVAL;
+
+	/* DC/AC Luma, DC/AC Chroma -> DC Luma/Chroma, AC Luma/Chroma */
+	ofs = ((tab_num & 1) << 1) | ((tab_num >> 1) & 1);
+	ofs *= 16;
+
+	huff_ptr = ctx->params.jpeg_huff_tab->ptr + ofs;
+	huff_max = ctx->params.jpeg_huff_tab->max + ofs;
+	huff_min = ctx->params.jpeg_huff_tab->min + ofs;
+
+	for (i = 0; i < 16; i++) {
+		if (huff_bits[i]) {
+			huff_ptr[i] = ptr_cnt;
+			ptr_cnt += huff_bits[i];
+			huff_min[i] = huff_code;
+			huff_max[i] = huff_code + (huff_bits[i] - 1);
+			data_flag = 1;
+			zero_flag = 0;
+		} else {
+			huff_ptr[i] = -1;
+			huff_min[i] = -1;
+			huff_max[i] = -1;
+			zero_flag = 1;
+		}
+
+		if (data_flag == 1) {
+			if (zero_flag == 1)
+				huff_code <<= 1;
+			else
+				huff_code = (huff_max[i] + 1) << 1;
+		}
+	}
+
+	return 0;
+}
+
 static int coda9_jpeg_load_huff_tab(struct coda_ctx *ctx)
 {
 	struct {
@@ -880,6 +1245,13 @@ static void coda9_jpeg_finish_encode(struct coda_ctx *ctx)
 	coda_dbg(1, ctx, "job finished: encoded frame (%u)%s\n",
 		 dst_buf->sequence,
 		 (dst_buf->flags & V4L2_BUF_FLAG_LAST) ? " (last)" : "");
+
+	/*
+	 * Reset JPEG processing unit after each encode run to work
+	 * around hangups when switching context between encoder and
+	 * decoder.
+	 */
+	coda_hw_reset(ctx);
 }
 
 static void coda9_jpeg_release(struct coda_ctx *ctx)
@@ -893,6 +1265,7 @@ static void coda9_jpeg_release(struct coda_ctx *ctx)
 	for (i = 0; i < 3; i++)
 		kfree(ctx->params.jpeg_qmat_tab[i]);
 	kfree(ctx->params.jpeg_huff_data);
+	kfree(ctx->params.jpeg_huff_tab);
 }
 
 const struct coda_context_ops coda9_jpeg_encode_ops = {
@@ -903,6 +1276,210 @@ const struct coda_context_ops coda9_jpeg_encode_ops = {
 	.release = coda9_jpeg_release,
 };
 
+/*
+ * Decoder context operations
+ */
+
+static int coda9_jpeg_start_decoding(struct coda_ctx *ctx)
+{
+	ctx->params.jpeg_qmat_index[0] = 0;
+	ctx->params.jpeg_qmat_index[1] = 1;
+	ctx->params.jpeg_qmat_index[2] = 1;
+	ctx->params.jpeg_qmat_tab[0] = luma_q;
+	ctx->params.jpeg_qmat_tab[1] = chroma_q;
+	/* nothing more to do here */
+
+	/* TODO: we could already scan the first header to get the chroma
+	 * format.
+	 */
+
+	return 0;
+}
+
+static int coda9_jpeg_prepare_decode(struct coda_ctx *ctx)
+{
+	struct coda_dev *dev = ctx->dev;
+	int aligned_width, aligned_height;
+	int chroma_format;
+	int ret;
+	u32 val, dst_fourcc;
+	struct coda_q_data *q_data_src, *q_data_dst;
+	struct vb2_v4l2_buffer *src_buf, *dst_buf;
+	int chroma_interleave;
+
+	src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
+	dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
+	q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+	q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+	dst_fourcc = q_data_dst->fourcc;
+
+	if (vb2_get_plane_payload(&src_buf->vb2_buf, 0) == 0)
+		vb2_set_plane_payload(&src_buf->vb2_buf, 0,
+				      vb2_plane_size(&src_buf->vb2_buf, 0));
+
+	chroma_format = coda9_jpeg_chroma_format(q_data_dst->fourcc);
+	if (chroma_format < 0) {
+		v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->fh.m2m_ctx);
+		return chroma_format;
+	}
+
+	ret = coda_jpeg_decode_header(ctx, &src_buf->vb2_buf);
+	if (ret < 0) {
+		v4l2_err(&dev->v4l2_dev, "failed to decode JPEG header: %d\n",
+			 ret);
+
+		src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+		dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
+		v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
+		v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
+
+		v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->fh.m2m_ctx);
+		return ret;
+	}
+
+	/* Round image dimensions to multiple of MCU size */
+	aligned_width = round_up(q_data_src->width, width_align[chroma_format]);
+	aligned_height = round_up(q_data_src->height, height_align[chroma_format]);
+	if (aligned_width != q_data_dst->bytesperline) {
+		v4l2_err(&dev->v4l2_dev, "stride mismatch: %d != %d\n",
+			 aligned_width, q_data_dst->bytesperline);
+	}
+
+	coda_set_gdi_regs(ctx);
+
+	val = ctx->params.jpeg_huff_ac_index[0] << 12 |
+	      ctx->params.jpeg_huff_ac_index[1] << 11 |
+	      ctx->params.jpeg_huff_ac_index[2] << 10 |
+	      ctx->params.jpeg_huff_dc_index[0] << 9 |
+	      ctx->params.jpeg_huff_dc_index[1] << 8 |
+	      ctx->params.jpeg_huff_dc_index[2] << 7;
+	if (ctx->params.jpeg_huff_tab)
+		val |= CODA9_JPEG_PIC_CTRL_USER_HUFFMAN_EN;
+	coda_write(dev, val, CODA9_REG_JPEG_PIC_CTRL);
+
+	coda_write(dev, aligned_width << 16 | aligned_height,
+			CODA9_REG_JPEG_PIC_SIZE);
+
+	chroma_interleave = (dst_fourcc == V4L2_PIX_FMT_NV12);
+	coda_write(dev, 0, CODA9_REG_JPEG_ROT_INFO);
+	coda_write(dev, bus_req_num[chroma_format], CODA9_REG_JPEG_OP_INFO);
+	coda_write(dev, mcu_info[chroma_format], CODA9_REG_JPEG_MCU_INFO);
+	coda_write(dev, 0, CODA9_REG_JPEG_SCL_INFO);
+	coda_write(dev, chroma_interleave, CODA9_REG_JPEG_DPB_CONFIG);
+	coda_write(dev, ctx->params.jpeg_restart_interval,
+			CODA9_REG_JPEG_RST_INTVAL);
+
+	if (ctx->params.jpeg_huff_tab) {
+		ret = coda9_jpeg_dec_huff_setup(ctx);
+		if (ret < 0) {
+			v4l2_err(&dev->v4l2_dev,
+				 "failed to set up Huffman tables: %d\n", ret);
+			v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->fh.m2m_ctx);
+			return ret;
+		}
+	}
+
+	coda9_jpeg_qmat_setup(ctx);
+
+	coda9_jpeg_dec_bbc_gbu_setup(ctx, &src_buf->vb2_buf,
+				     ctx->jpeg_ecs_offset);
+
+	coda_write(dev, 0, CODA9_REG_JPEG_RST_INDEX);
+	coda_write(dev, 0, CODA9_REG_JPEG_RST_COUNT);
+
+	coda_write(dev, 0, CODA9_REG_JPEG_DPCM_DIFF_Y);
+	coda_write(dev, 0, CODA9_REG_JPEG_DPCM_DIFF_CB);
+	coda_write(dev, 0, CODA9_REG_JPEG_DPCM_DIFF_CR);
+
+	coda_write(dev, 0, CODA9_REG_JPEG_ROT_INFO);
+
+	coda_write(dev, 1, CODA9_GDI_CONTROL);
+	do {
+		ret = coda_read(dev, CODA9_GDI_STATUS);
+	} while (!ret);
+
+	val = (chroma_format << 17) | (chroma_interleave << 16) |
+	      q_data_dst->bytesperline;
+	if (ctx->tiled_map_type == GDI_TILED_FRAME_MB_RASTER_MAP)
+		val |= 3 << 20;
+	coda_write(dev, val, CODA9_GDI_INFO_CONTROL);
+
+	coda_write(dev, aligned_width << 16 | aligned_height,
+			CODA9_GDI_INFO_PIC_SIZE);
+
+	coda_write_base(ctx, q_data_dst, dst_buf, CODA9_GDI_INFO_BASE_Y);
+
+	coda_write(dev, 0, CODA9_REG_JPEG_DPB_BASE00);
+	coda_write(dev, 0, CODA9_GDI_CONTROL);
+	coda_write(dev, 1, CODA9_GDI_PIC_INIT_HOST);
+
+	trace_coda_jpeg_run(ctx, src_buf);
+
+	coda_write(dev, 1, CODA9_REG_JPEG_PIC_START);
+
+	return 0;
+}
+
+static void coda9_jpeg_finish_decode(struct coda_ctx *ctx)
+{
+	struct coda_dev *dev = ctx->dev;
+	struct vb2_v4l2_buffer *dst_buf, *src_buf;
+	struct coda_q_data *q_data_dst;
+	u32 err_mb;
+
+	err_mb = coda_read(dev, CODA9_REG_JPEG_PIC_ERRMB);
+	if (err_mb)
+		v4l2_err(&dev->v4l2_dev, "ERRMB: 0x%x\n", err_mb);
+
+	coda_write(dev, 0, CODA9_REG_JPEG_BBC_FLUSH_CMD);
+
+	/*
+	 * Lock to make sure that a decoder stop command running in parallel
+	 * will either already have marked src_buf as last, or it will wake up
+	 * the capture queue after the buffers are returned.
+	 */
+	mutex_lock(&ctx->wakeup_mutex);
+	src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+	dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
+	dst_buf->sequence = ctx->osequence++;
+
+	trace_coda_jpeg_done(ctx, dst_buf);
+
+	dst_buf->flags &= ~(V4L2_BUF_FLAG_PFRAME | V4L2_BUF_FLAG_LAST);
+	dst_buf->flags |= V4L2_BUF_FLAG_KEYFRAME;
+	dst_buf->flags |= src_buf->flags & V4L2_BUF_FLAG_LAST;
+
+	v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, false);
+
+	q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+	vb2_set_plane_payload(&dst_buf->vb2_buf, 0, q_data_dst->sizeimage);
+
+	v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
+	coda_m2m_buf_done(ctx, dst_buf, err_mb ? VB2_BUF_STATE_ERROR :
+						 VB2_BUF_STATE_DONE);
+
+	mutex_unlock(&ctx->wakeup_mutex);
+
+	coda_dbg(1, ctx, "job finished: decoded frame (%u)%s\n",
+		 dst_buf->sequence,
+		 (dst_buf->flags & V4L2_BUF_FLAG_LAST) ? " (last)" : "");
+
+	/*
+	 * Reset JPEG processing unit after each decode run to work
+	 * around hangups when switching context between encoder and
+	 * decoder.
+	 */
+	coda_hw_reset(ctx);
+}
+
+const struct coda_context_ops coda9_jpeg_decode_ops = {
+	.queue_init = coda_encoder_queue_init, /* non-bitstream operation */
+	.start_streaming = coda9_jpeg_start_decoding,
+	.prepare_run = coda9_jpeg_prepare_decode,
+	.finish_run = coda9_jpeg_finish_decode,
+	.release = coda9_jpeg_release,
+};
+
 irqreturn_t coda9_jpeg_irq_handler(int irq, void *data)
 {
 	struct coda_dev *dev = data;
diff --git a/drivers/media/platform/coda/coda.h b/drivers/media/platform/coda/coda.h
index 43bda175f517..af0f8252b0c6 100644
--- a/drivers/media/platform/coda/coda.h
+++ b/drivers/media/platform/coda/coda.h
@@ -69,7 +69,7 @@ struct coda_aux_buf {
 
 struct coda_dev {
 	struct v4l2_device	v4l2_dev;
-	struct video_device	vfd[5];
+	struct video_device	vfd[6];
 	struct device		*dev;
 	const struct coda_devtype *devtype;
 	int			firmware;
@@ -123,10 +123,15 @@ struct coda_params {
 	u8			mpeg4_inter_qp;
 	u8			gop_size;
 	int			intra_refresh;
+	enum v4l2_jpeg_chroma_subsampling jpeg_chroma_subsampling;
 	u8			jpeg_quality;
 	u8			jpeg_restart_interval;
 	u8			*jpeg_qmat_tab[3];
+	int			jpeg_qmat_index[3];
+	int			jpeg_huff_dc_index[3];
+	int			jpeg_huff_ac_index[3];
 	u32			*jpeg_huff_data;
+	struct coda_huff_tab	*jpeg_huff_tab;
 	int			codec_mode;
 	int			codec_mode_aux;
 	enum v4l2_mpeg_video_multi_slice_mode slice_mode;
@@ -238,6 +243,7 @@ struct coda_ctx {
 	struct v4l2_fh			fh;
 	int				gopcounter;
 	int				runcounter;
+	int				jpeg_ecs_offset;
 	char				vpu_header[3][64];
 	int				vpu_header_size[3];
 	struct kfifo			bitstream_fifo;
@@ -362,12 +368,14 @@ void coda_update_profile_level_ctrls(struct coda_ctx *ctx, u8 profile_idc,
 				     u8 level_idc);
 
 bool coda_jpeg_check_buffer(struct coda_ctx *ctx, struct vb2_buffer *vb);
+int coda_jpeg_decode_header(struct coda_ctx *ctx, struct vb2_buffer *vb);
 int coda_jpeg_write_tables(struct coda_ctx *ctx);
 void coda_set_jpeg_compression_quality(struct coda_ctx *ctx, int quality);
 
 extern const struct coda_context_ops coda_bit_encode_ops;
 extern const struct coda_context_ops coda_bit_decode_ops;
 extern const struct coda_context_ops coda9_jpeg_encode_ops;
+extern const struct coda_context_ops coda9_jpeg_decode_ops;
 
 irqreturn_t coda_irq_handler(int irq, void *data);
 irqreturn_t coda9_jpeg_irq_handler(int irq, void *data);
diff --git a/drivers/media/platform/cros-ec-cec/Makefile b/drivers/media/platform/cros-ec-cec/Makefile
deleted file mode 100644
index 2615cdc6e227..000000000000
--- a/drivers/media/platform/cros-ec-cec/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_VIDEO_CROS_EC_CEC) += cros-ec-cec.o
diff --git a/drivers/media/platform/cros-ec-cec/cros-ec-cec.c b/drivers/media/platform/cros-ec-cec/cros-ec-cec.c
deleted file mode 100644
index 0e7e2772f08f..000000000000
--- a/drivers/media/platform/cros-ec-cec/cros-ec-cec.c
+++ /dev/null
@@ -1,359 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * CEC driver for ChromeOS Embedded Controller
- *
- * Copyright (c) 2018 BayLibre, SAS
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/dmi.h>
-#include <linux/pci.h>
-#include <linux/cec.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/platform_data/cros_ec_commands.h>
-#include <linux/platform_data/cros_ec_proto.h>
-#include <media/cec.h>
-#include <media/cec-notifier.h>
-
-#define DRV_NAME	"cros-ec-cec"
-
-/**
- * struct cros_ec_cec - Driver data for EC CEC
- *
- * @cros_ec: Pointer to EC device
- * @notifier: Notifier info for responding to EC events
- * @adap: CEC adapter
- * @notify: CEC notifier pointer
- * @rx_msg: storage for a received message
- */
-struct cros_ec_cec {
-	struct cros_ec_device *cros_ec;
-	struct notifier_block notifier;
-	struct cec_adapter *adap;
-	struct cec_notifier *notify;
-	struct cec_msg rx_msg;
-};
-
-static void handle_cec_message(struct cros_ec_cec *cros_ec_cec)
-{
-	struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec;
-	uint8_t *cec_message = cros_ec->event_data.data.cec_message;
-	unsigned int len = cros_ec->event_size;
-
-	cros_ec_cec->rx_msg.len = len;
-	memcpy(cros_ec_cec->rx_msg.msg, cec_message, len);
-
-	cec_received_msg(cros_ec_cec->adap, &cros_ec_cec->rx_msg);
-}
-
-static void handle_cec_event(struct cros_ec_cec *cros_ec_cec)
-{
-	struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec;
-	uint32_t events = cros_ec->event_data.data.cec_events;
-
-	if (events & EC_MKBP_CEC_SEND_OK)
-		cec_transmit_attempt_done(cros_ec_cec->adap,
-					  CEC_TX_STATUS_OK);
-
-	/* FW takes care of all retries, tell core to avoid more retries */
-	if (events & EC_MKBP_CEC_SEND_FAILED)
-		cec_transmit_attempt_done(cros_ec_cec->adap,
-					  CEC_TX_STATUS_MAX_RETRIES |
-					  CEC_TX_STATUS_NACK);
-}
-
-static int cros_ec_cec_event(struct notifier_block *nb,
-			     unsigned long queued_during_suspend,
-			     void *_notify)
-{
-	struct cros_ec_cec *cros_ec_cec;
-	struct cros_ec_device *cros_ec;
-
-	cros_ec_cec = container_of(nb, struct cros_ec_cec, notifier);
-	cros_ec = cros_ec_cec->cros_ec;
-
-	if (cros_ec->event_data.event_type == EC_MKBP_EVENT_CEC_EVENT) {
-		handle_cec_event(cros_ec_cec);
-		return NOTIFY_OK;
-	}
-
-	if (cros_ec->event_data.event_type == EC_MKBP_EVENT_CEC_MESSAGE) {
-		handle_cec_message(cros_ec_cec);
-		return NOTIFY_OK;
-	}
-
-	return NOTIFY_DONE;
-}
-
-static int cros_ec_cec_set_log_addr(struct cec_adapter *adap, u8 logical_addr)
-{
-	struct cros_ec_cec *cros_ec_cec = adap->priv;
-	struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec;
-	struct {
-		struct cros_ec_command msg;
-		struct ec_params_cec_set data;
-	} __packed msg = {};
-	int ret;
-
-	msg.msg.command = EC_CMD_CEC_SET;
-	msg.msg.outsize = sizeof(msg.data);
-	msg.data.cmd = CEC_CMD_LOGICAL_ADDRESS;
-	msg.data.val = logical_addr;
-
-	ret = cros_ec_cmd_xfer_status(cros_ec, &msg.msg);
-	if (ret < 0) {
-		dev_err(cros_ec->dev,
-			"error setting CEC logical address on EC: %d\n", ret);
-		return ret;
-	}
-
-	return 0;
-}
-
-static int cros_ec_cec_transmit(struct cec_adapter *adap, u8 attempts,
-				u32 signal_free_time, struct cec_msg *cec_msg)
-{
-	struct cros_ec_cec *cros_ec_cec = adap->priv;
-	struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec;
-	struct {
-		struct cros_ec_command msg;
-		struct ec_params_cec_write data;
-	} __packed msg = {};
-	int ret;
-
-	msg.msg.command = EC_CMD_CEC_WRITE_MSG;
-	msg.msg.outsize = cec_msg->len;
-	memcpy(msg.data.msg, cec_msg->msg, cec_msg->len);
-
-	ret = cros_ec_cmd_xfer_status(cros_ec, &msg.msg);
-	if (ret < 0) {
-		dev_err(cros_ec->dev,
-			"error writing CEC msg on EC: %d\n", ret);
-		return ret;
-	}
-
-	return 0;
-}
-
-static int cros_ec_cec_adap_enable(struct cec_adapter *adap, bool enable)
-{
-	struct cros_ec_cec *cros_ec_cec = adap->priv;
-	struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec;
-	struct {
-		struct cros_ec_command msg;
-		struct ec_params_cec_set data;
-	} __packed msg = {};
-	int ret;
-
-	msg.msg.command = EC_CMD_CEC_SET;
-	msg.msg.outsize = sizeof(msg.data);
-	msg.data.cmd = CEC_CMD_ENABLE;
-	msg.data.val = enable;
-
-	ret = cros_ec_cmd_xfer_status(cros_ec, &msg.msg);
-	if (ret < 0) {
-		dev_err(cros_ec->dev,
-			"error %sabling CEC on EC: %d\n",
-			(enable ? "en" : "dis"), ret);
-		return ret;
-	}
-
-	return 0;
-}
-
-static const struct cec_adap_ops cros_ec_cec_ops = {
-	.adap_enable = cros_ec_cec_adap_enable,
-	.adap_log_addr = cros_ec_cec_set_log_addr,
-	.adap_transmit = cros_ec_cec_transmit,
-};
-
-#ifdef CONFIG_PM_SLEEP
-static int cros_ec_cec_suspend(struct device *dev)
-{
-	struct platform_device *pdev = to_platform_device(dev);
-	struct cros_ec_cec *cros_ec_cec = dev_get_drvdata(&pdev->dev);
-
-	if (device_may_wakeup(dev))
-		enable_irq_wake(cros_ec_cec->cros_ec->irq);
-
-	return 0;
-}
-
-static int cros_ec_cec_resume(struct device *dev)
-{
-	struct platform_device *pdev = to_platform_device(dev);
-	struct cros_ec_cec *cros_ec_cec = dev_get_drvdata(&pdev->dev);
-
-	if (device_may_wakeup(dev))
-		disable_irq_wake(cros_ec_cec->cros_ec->irq);
-
-	return 0;
-}
-#endif
-
-static SIMPLE_DEV_PM_OPS(cros_ec_cec_pm_ops,
-	cros_ec_cec_suspend, cros_ec_cec_resume);
-
-#if IS_ENABLED(CONFIG_PCI) && IS_ENABLED(CONFIG_DMI)
-
-/*
- * The Firmware only handles a single CEC interface tied to a single HDMI
- * connector we specify along with the DRM device name handling the HDMI output
- */
-
-struct cec_dmi_match {
-	const char *sys_vendor;
-	const char *product_name;
-	const char *devname;
-	const char *conn;
-};
-
-static const struct cec_dmi_match cec_dmi_match_table[] = {
-	/* Google Fizz */
-	{ "Google", "Fizz", "0000:00:02.0", "Port B" },
-};
-
-static struct device *cros_ec_cec_find_hdmi_dev(struct device *dev,
-						const char **conn)
-{
-	int i;
-
-	for (i = 0 ; i < ARRAY_SIZE(cec_dmi_match_table) ; ++i) {
-		const struct cec_dmi_match *m = &cec_dmi_match_table[i];
-
-		if (dmi_match(DMI_SYS_VENDOR, m->sys_vendor) &&
-		    dmi_match(DMI_PRODUCT_NAME, m->product_name)) {
-			struct device *d;
-
-			/* Find the device, bail out if not yet registered */
-			d = bus_find_device_by_name(&pci_bus_type, NULL,
-						    m->devname);
-			if (!d)
-				return ERR_PTR(-EPROBE_DEFER);
-			put_device(d);
-			*conn = m->conn;
-			return d;
-		}
-	}
-
-	/* Hardware support must be added in the cec_dmi_match_table */
-	dev_warn(dev, "CEC notifier not configured for this hardware\n");
-
-	return ERR_PTR(-ENODEV);
-}
-
-#else
-
-static struct device *cros_ec_cec_find_hdmi_dev(struct device *dev,
-						const char **conn)
-{
-	return ERR_PTR(-ENODEV);
-}
-
-#endif
-
-static int cros_ec_cec_probe(struct platform_device *pdev)
-{
-	struct cros_ec_dev *ec_dev = dev_get_drvdata(pdev->dev.parent);
-	struct cros_ec_device *cros_ec = ec_dev->ec_dev;
-	struct cros_ec_cec *cros_ec_cec;
-	struct device *hdmi_dev;
-	const char *conn = NULL;
-	int ret;
-
-	hdmi_dev = cros_ec_cec_find_hdmi_dev(&pdev->dev, &conn);
-	if (IS_ERR(hdmi_dev))
-		return PTR_ERR(hdmi_dev);
-
-	cros_ec_cec = devm_kzalloc(&pdev->dev, sizeof(*cros_ec_cec),
-				   GFP_KERNEL);
-	if (!cros_ec_cec)
-		return -ENOMEM;
-
-	platform_set_drvdata(pdev, cros_ec_cec);
-	cros_ec_cec->cros_ec = cros_ec;
-
-	ret = device_init_wakeup(&pdev->dev, 1);
-	if (ret) {
-		dev_err(&pdev->dev, "failed to initialize wakeup\n");
-		return ret;
-	}
-
-	cros_ec_cec->adap = cec_allocate_adapter(&cros_ec_cec_ops, cros_ec_cec,
-						 DRV_NAME,
-						 CEC_CAP_DEFAULTS |
-						 CEC_CAP_CONNECTOR_INFO, 1);
-	if (IS_ERR(cros_ec_cec->adap))
-		return PTR_ERR(cros_ec_cec->adap);
-
-	cros_ec_cec->notify = cec_notifier_cec_adap_register(hdmi_dev, conn,
-							     cros_ec_cec->adap);
-	if (!cros_ec_cec->notify) {
-		ret = -ENOMEM;
-		goto out_probe_adapter;
-	}
-
-	/* Get CEC events from the EC. */
-	cros_ec_cec->notifier.notifier_call = cros_ec_cec_event;
-	ret = blocking_notifier_chain_register(&cros_ec->event_notifier,
-					       &cros_ec_cec->notifier);
-	if (ret) {
-		dev_err(&pdev->dev, "failed to register notifier\n");
-		goto out_probe_notify;
-	}
-
-	ret = cec_register_adapter(cros_ec_cec->adap, &pdev->dev);
-	if (ret < 0)
-		goto out_probe_notify;
-
-	return 0;
-
-out_probe_notify:
-	cec_notifier_cec_adap_unregister(cros_ec_cec->notify,
-					 cros_ec_cec->adap);
-out_probe_adapter:
-	cec_delete_adapter(cros_ec_cec->adap);
-	return ret;
-}
-
-static int cros_ec_cec_remove(struct platform_device *pdev)
-{
-	struct cros_ec_cec *cros_ec_cec = platform_get_drvdata(pdev);
-	struct device *dev = &pdev->dev;
-	int ret;
-
-	ret = blocking_notifier_chain_unregister(
-			&cros_ec_cec->cros_ec->event_notifier,
-			&cros_ec_cec->notifier);
-
-	if (ret) {
-		dev_err(dev, "failed to unregister notifier\n");
-		return ret;
-	}
-
-	cec_notifier_cec_adap_unregister(cros_ec_cec->notify,
-					 cros_ec_cec->adap);
-	cec_unregister_adapter(cros_ec_cec->adap);
-
-	return 0;
-}
-
-static struct platform_driver cros_ec_cec_driver = {
-	.probe = cros_ec_cec_probe,
-	.remove  = cros_ec_cec_remove,
-	.driver = {
-		.name = DRV_NAME,
-		.pm = &cros_ec_cec_pm_ops,
-	},
-};
-
-module_platform_driver(cros_ec_cec_driver);
-
-MODULE_DESCRIPTION("CEC driver for ChromeOS ECs");
-MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/drivers/media/platform/exynos4-is/Kconfig b/drivers/media/platform/exynos4-is/Kconfig
index be4effcbfe7b..136d3b2a0fbb 100644
--- a/drivers/media/platform/exynos4-is/Kconfig
+++ b/drivers/media/platform/exynos4-is/Kconfig
@@ -2,9 +2,10 @@
 
 config VIDEO_SAMSUNG_EXYNOS4_IS
 	tristate "Samsung S5P/EXYNOS4 SoC series Camera Subsystem driver"
-	depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on VIDEO_V4L2 && OF && COMMON_CLK
 	depends on ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
-	depends on OF && COMMON_CLK
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select V4L2_FWNODE
 	help
 	  Say Y here to enable camera host interface devices for
diff --git a/drivers/media/platform/marvell-ccic/cafe-driver.c b/drivers/media/platform/marvell-ccic/cafe-driver.c
index 37fdcc53a1c4..9a09a10a3631 100644
--- a/drivers/media/platform/marvell-ccic/cafe-driver.c
+++ b/drivers/media/platform/marvell-ccic/cafe-driver.c
@@ -556,7 +556,7 @@ static int cafe_pci_probe(struct pci_dev *pdev,
 	clkdev_create(mcam->mclk, "xclk", "%d-%04x",
 		i2c_adapter_id(cam->i2c_adapter), ov7670_info.addr);
 
-	if (i2c_new_device(cam->i2c_adapter, &ov7670_info)) {
+	if (!IS_ERR(i2c_new_client_device(cam->i2c_adapter, &ov7670_info))) {
 		cam->registered = 1;
 		return 0;
 	}
diff --git a/drivers/media/platform/meson/Makefile b/drivers/media/platform/meson/Makefile
deleted file mode 100644
index 6bf728addbf8..000000000000
--- a/drivers/media/platform/meson/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_VIDEO_MESON_AO_CEC)	+= ao-cec.o
-obj-$(CONFIG_VIDEO_MESON_G12A_AO_CEC)	+= ao-cec-g12a.o
diff --git a/drivers/media/platform/meson/ao-cec-g12a.c b/drivers/media/platform/meson/ao-cec-g12a.c
deleted file mode 100644
index 891533060d49..000000000000
--- a/drivers/media/platform/meson/ao-cec-g12a.c
+++ /dev/null
@@ -1,796 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Driver for Amlogic Meson AO CEC G12A Controller
- *
- * Copyright (C) 2017 Amlogic, Inc. All rights reserved
- * Copyright (C) 2019 BayLibre, SAS
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- */
-
-#include <linux/bitfield.h>
-#include <linux/clk.h>
-#include <linux/device.h>
-#include <linux/io.h>
-#include <linux/delay.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/of_platform.h>
-#include <linux/platform_device.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/reset.h>
-#include <linux/slab.h>
-#include <linux/regmap.h>
-#include <media/cec.h>
-#include <media/cec-notifier.h>
-#include <linux/clk-provider.h>
-
-/* CEC Registers */
-
-#define CECB_CLK_CNTL_REG0		0x00
-
-#define CECB_CLK_CNTL_N1		GENMASK(11, 0)
-#define CECB_CLK_CNTL_N2		GENMASK(23, 12)
-#define CECB_CLK_CNTL_DUAL_EN		BIT(28)
-#define CECB_CLK_CNTL_OUTPUT_EN		BIT(30)
-#define CECB_CLK_CNTL_INPUT_EN		BIT(31)
-
-#define CECB_CLK_CNTL_REG1		0x04
-
-#define CECB_CLK_CNTL_M1		GENMASK(11, 0)
-#define CECB_CLK_CNTL_M2		GENMASK(23, 12)
-#define CECB_CLK_CNTL_BYPASS_EN		BIT(24)
-
-/*
- * [14:12] Filter_del. For glitch-filtering CEC line, ignore signal
- *       change pulse width < filter_del * T(filter_tick) * 3.
- * [9:8] Filter_tick_sel: Select which periodical pulse for
- *       glitch-filtering CEC line signal.
- *  - 0=Use T(xtal)*3 = 125ns;
- *  - 1=Use once-per-1us pulse;
- *  - 2=Use once-per-10us pulse;
- *  - 3=Use once-per-100us pulse.
- * [3]   Sysclk_en. 0=Disable system clock; 1=Enable system clock.
- * [2:1] cntl_clk
- *  - 0 = Disable clk (Power-off mode)
- *  - 1 = Enable gated clock (Normal mode)
- *  - 2 = Enable free-run clk (Debug mode)
- * [0] SW_RESET 1=Apply reset; 0=No reset.
- */
-#define CECB_GEN_CNTL_REG		0x08
-
-#define CECB_GEN_CNTL_RESET		BIT(0)
-#define CECB_GEN_CNTL_CLK_DISABLE	0
-#define CECB_GEN_CNTL_CLK_ENABLE	1
-#define CECB_GEN_CNTL_CLK_ENABLE_DBG	2
-#define CECB_GEN_CNTL_CLK_CTRL_MASK	GENMASK(2, 1)
-#define CECB_GEN_CNTL_SYS_CLK_EN	BIT(3)
-#define CECB_GEN_CNTL_FILTER_TICK_125NS	0
-#define CECB_GEN_CNTL_FILTER_TICK_1US	1
-#define CECB_GEN_CNTL_FILTER_TICK_10US	2
-#define CECB_GEN_CNTL_FILTER_TICK_100US	3
-#define CECB_GEN_CNTL_FILTER_TICK_SEL	GENMASK(9, 8)
-#define CECB_GEN_CNTL_FILTER_DEL	GENMASK(14, 12)
-
-/*
- * [7:0] cec_reg_addr
- * [15:8] cec_reg_wrdata
- * [16] cec_reg_wr
- *  - 0 = Read
- *  - 1 = Write
- * [31:24] cec_reg_rddata
- */
-#define CECB_RW_REG			0x0c
-
-#define CECB_RW_ADDR			GENMASK(7, 0)
-#define CECB_RW_WR_DATA			GENMASK(15, 8)
-#define CECB_RW_WRITE_EN		BIT(16)
-#define CECB_RW_BUS_BUSY		BIT(23)
-#define CECB_RW_RD_DATA			GENMASK(31, 24)
-
-/*
- * [0] DONE Interrupt
- * [1] End Of Message Interrupt
- * [2] Not Acknowlegde Interrupt
- * [3] Arbitration Loss Interrupt
- * [4] Initiator Error Interrupt
- * [5] Follower Error Interrupt
- * [6] Wake-Up Interrupt
- */
-#define CECB_INTR_MASKN_REG		0x10
-#define CECB_INTR_CLR_REG		0x14
-#define CECB_INTR_STAT_REG		0x18
-
-#define CECB_INTR_DONE			BIT(0)
-#define CECB_INTR_EOM			BIT(1)
-#define CECB_INTR_NACK			BIT(2)
-#define CECB_INTR_ARB_LOSS		BIT(3)
-#define CECB_INTR_INITIATOR_ERR		BIT(4)
-#define CECB_INTR_FOLLOWER_ERR		BIT(5)
-#define CECB_INTR_WAKE_UP		BIT(6)
-
-/* CEC Commands */
-
-#define CECB_CTRL		0x00
-
-#define CECB_CTRL_SEND		BIT(0)
-#define CECB_CTRL_TYPE		GENMASK(2, 1)
-#define CECB_CTRL_TYPE_RETRY	0
-#define CECB_CTRL_TYPE_NEW	1
-#define CECB_CTRL_TYPE_NEXT	2
-
-#define CECB_CTRL2		0x01
-
-#define CECB_CTRL2_RISE_DEL_MAX	GENMASK(4, 0)
-
-#define CECB_INTR_MASK		0x02
-#define CECB_LADD_LOW		0x05
-#define CECB_LADD_HIGH		0x06
-#define CECB_TX_CNT		0x07
-#define CECB_RX_CNT		0x08
-#define CECB_STAT0		0x09
-#define CECB_TX_DATA00		0x10
-#define CECB_TX_DATA01		0x11
-#define CECB_TX_DATA02		0x12
-#define CECB_TX_DATA03		0x13
-#define CECB_TX_DATA04		0x14
-#define CECB_TX_DATA05		0x15
-#define CECB_TX_DATA06		0x16
-#define CECB_TX_DATA07		0x17
-#define CECB_TX_DATA08		0x18
-#define CECB_TX_DATA09		0x19
-#define CECB_TX_DATA10		0x1A
-#define CECB_TX_DATA11		0x1B
-#define CECB_TX_DATA12		0x1C
-#define CECB_TX_DATA13		0x1D
-#define CECB_TX_DATA14		0x1E
-#define CECB_TX_DATA15		0x1F
-#define CECB_RX_DATA00		0x20
-#define CECB_RX_DATA01		0x21
-#define CECB_RX_DATA02		0x22
-#define CECB_RX_DATA03		0x23
-#define CECB_RX_DATA04		0x24
-#define CECB_RX_DATA05		0x25
-#define CECB_RX_DATA06		0x26
-#define CECB_RX_DATA07		0x27
-#define CECB_RX_DATA08		0x28
-#define CECB_RX_DATA09		0x29
-#define CECB_RX_DATA10		0x2A
-#define CECB_RX_DATA11		0x2B
-#define CECB_RX_DATA12		0x2C
-#define CECB_RX_DATA13		0x2D
-#define CECB_RX_DATA14		0x2E
-#define CECB_RX_DATA15		0x2F
-#define CECB_LOCK_BUF		0x30
-
-#define CECB_LOCK_BUF_EN	BIT(0)
-
-#define CECB_WAKEUPCTRL		0x31
-
-struct meson_ao_cec_g12a_data {
-	/* Setup the internal CECB_CTRL2 register */
-	bool				ctrl2_setup;
-};
-
-struct meson_ao_cec_g12a_device {
-	struct platform_device		*pdev;
-	struct regmap			*regmap;
-	struct regmap			*regmap_cec;
-	spinlock_t			cec_reg_lock;
-	struct cec_notifier		*notify;
-	struct cec_adapter		*adap;
-	struct cec_msg			rx_msg;
-	struct clk			*oscin;
-	struct clk			*core;
-	const struct meson_ao_cec_g12a_data *data;
-};
-
-static const struct regmap_config meson_ao_cec_g12a_regmap_conf = {
-	.reg_bits = 8,
-	.val_bits = 32,
-	.reg_stride = 4,
-	.max_register = CECB_INTR_STAT_REG,
-};
-
-/*
- * The AO-CECB embeds a dual/divider to generate a more precise
- * 32,768KHz clock for CEC core clock.
- *                      ______   ______
- *                     |      | |      |
- *         ______      | Div1 |-| Cnt1 |       ______
- *        |      |    /|______| |______|\     |      |
- * Xtal-->| Gate |---|  ______   ______  X-X--| Gate |-->
- *        |______| |  \|      | |      |/  |  |______|
- *                 |   | Div2 |-| Cnt2 |   |
- *                 |   |______| |______|   |
- *                 |_______________________|
- *
- * The dividing can be switched to single or dual, with a counter
- * for each divider to set when the switching is done.
- * The entire dividing mechanism can be also bypassed.
- */
-
-struct meson_ao_cec_g12a_dualdiv_clk {
-	struct clk_hw hw;
-	struct regmap *regmap;
-};
-
-#define hw_to_meson_ao_cec_g12a_dualdiv_clk(_hw)			\
-	container_of(_hw, struct meson_ao_cec_g12a_dualdiv_clk, hw)	\
-
-static unsigned long
-meson_ao_cec_g12a_dualdiv_clk_recalc_rate(struct clk_hw *hw,
-					  unsigned long parent_rate)
-{
-	struct meson_ao_cec_g12a_dualdiv_clk *dualdiv_clk =
-		hw_to_meson_ao_cec_g12a_dualdiv_clk(hw);
-	unsigned long n1;
-	u32 reg0, reg1;
-
-	regmap_read(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0, &reg0);
-	regmap_read(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0, &reg1);
-
-	if (reg1 & CECB_CLK_CNTL_BYPASS_EN)
-		return parent_rate;
-
-	if (reg0 & CECB_CLK_CNTL_DUAL_EN) {
-		unsigned long n2, m1, m2, f1, f2, p1, p2;
-
-		n1 = FIELD_GET(CECB_CLK_CNTL_N1, reg0) + 1;
-		n2 = FIELD_GET(CECB_CLK_CNTL_N2, reg0) + 1;
-
-		m1 = FIELD_GET(CECB_CLK_CNTL_M1, reg1) + 1;
-		m2 = FIELD_GET(CECB_CLK_CNTL_M1, reg1) + 1;
-
-		f1 = DIV_ROUND_CLOSEST(parent_rate, n1);
-		f2 = DIV_ROUND_CLOSEST(parent_rate, n2);
-
-		p1 = DIV_ROUND_CLOSEST(100000000 * m1, f1 * (m1 + m2));
-		p2 = DIV_ROUND_CLOSEST(100000000 * m2, f2 * (m1 + m2));
-
-		return DIV_ROUND_UP(100000000, p1 + p2);
-	}
-
-	n1 = FIELD_GET(CECB_CLK_CNTL_N1, reg0) + 1;
-
-	return DIV_ROUND_CLOSEST(parent_rate, n1);
-}
-
-static int meson_ao_cec_g12a_dualdiv_clk_enable(struct clk_hw *hw)
-{
-	struct meson_ao_cec_g12a_dualdiv_clk *dualdiv_clk =
-		hw_to_meson_ao_cec_g12a_dualdiv_clk(hw);
-
-
-	/* Disable Input & Output */
-	regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0,
-			   CECB_CLK_CNTL_INPUT_EN | CECB_CLK_CNTL_OUTPUT_EN,
-			   0);
-
-	/* Set N1 & N2 */
-	regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0,
-			   CECB_CLK_CNTL_N1,
-			   FIELD_PREP(CECB_CLK_CNTL_N1, 733 - 1));
-
-	regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0,
-			   CECB_CLK_CNTL_N2,
-			   FIELD_PREP(CECB_CLK_CNTL_N2, 732 - 1));
-
-	/* Set M1 & M2 */
-	regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG1,
-			   CECB_CLK_CNTL_M1,
-			   FIELD_PREP(CECB_CLK_CNTL_M1, 8 - 1));
-
-	regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG1,
-			   CECB_CLK_CNTL_M2,
-			   FIELD_PREP(CECB_CLK_CNTL_M2, 11 - 1));
-
-	/* Enable Dual divisor */
-	regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0,
-			   CECB_CLK_CNTL_DUAL_EN, CECB_CLK_CNTL_DUAL_EN);
-
-	/* Disable divisor bypass */
-	regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG1,
-			   CECB_CLK_CNTL_BYPASS_EN, 0);
-
-	/* Enable Input & Output */
-	regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0,
-			   CECB_CLK_CNTL_INPUT_EN | CECB_CLK_CNTL_OUTPUT_EN,
-			   CECB_CLK_CNTL_INPUT_EN | CECB_CLK_CNTL_OUTPUT_EN);
-
-	return 0;
-}
-
-static void meson_ao_cec_g12a_dualdiv_clk_disable(struct clk_hw *hw)
-{
-	struct meson_ao_cec_g12a_dualdiv_clk *dualdiv_clk =
-		hw_to_meson_ao_cec_g12a_dualdiv_clk(hw);
-
-	regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0,
-			   CECB_CLK_CNTL_INPUT_EN | CECB_CLK_CNTL_OUTPUT_EN,
-			   0);
-}
-
-static int meson_ao_cec_g12a_dualdiv_clk_is_enabled(struct clk_hw *hw)
-{
-	struct meson_ao_cec_g12a_dualdiv_clk *dualdiv_clk =
-		hw_to_meson_ao_cec_g12a_dualdiv_clk(hw);
-	int val;
-
-	regmap_read(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0, &val);
-
-	return !!(val & (CECB_CLK_CNTL_INPUT_EN | CECB_CLK_CNTL_OUTPUT_EN));
-}
-
-static const struct clk_ops meson_ao_cec_g12a_dualdiv_clk_ops = {
-	.recalc_rate	= meson_ao_cec_g12a_dualdiv_clk_recalc_rate,
-	.is_enabled	= meson_ao_cec_g12a_dualdiv_clk_is_enabled,
-	.enable		= meson_ao_cec_g12a_dualdiv_clk_enable,
-	.disable	= meson_ao_cec_g12a_dualdiv_clk_disable,
-};
-
-static int meson_ao_cec_g12a_setup_clk(struct meson_ao_cec_g12a_device *ao_cec)
-{
-	struct meson_ao_cec_g12a_dualdiv_clk *dualdiv_clk;
-	struct device *dev = &ao_cec->pdev->dev;
-	struct clk_init_data init;
-	const char *parent_name;
-	struct clk *clk;
-	char *name;
-
-	dualdiv_clk = devm_kzalloc(dev, sizeof(*dualdiv_clk), GFP_KERNEL);
-	if (!dualdiv_clk)
-		return -ENOMEM;
-
-	name = kasprintf(GFP_KERNEL, "%s#dualdiv_clk", dev_name(dev));
-	if (!name)
-		return -ENOMEM;
-
-	parent_name = __clk_get_name(ao_cec->oscin);
-
-	init.name = name;
-	init.ops = &meson_ao_cec_g12a_dualdiv_clk_ops;
-	init.flags = 0;
-	init.parent_names = &parent_name;
-	init.num_parents = 1;
-	dualdiv_clk->regmap = ao_cec->regmap;
-	dualdiv_clk->hw.init = &init;
-
-	clk = devm_clk_register(dev, &dualdiv_clk->hw);
-	kfree(name);
-	if (IS_ERR(clk)) {
-		dev_err(dev, "failed to register clock\n");
-		return PTR_ERR(clk);
-	}
-
-	ao_cec->core = clk;
-
-	return 0;
-}
-
-static int meson_ao_cec_g12a_read(void *context, unsigned int addr,
-				  unsigned int *data)
-{
-	struct meson_ao_cec_g12a_device *ao_cec = context;
-	u32 reg = FIELD_PREP(CECB_RW_ADDR, addr);
-	int ret = 0;
-
-	ret = regmap_write(ao_cec->regmap, CECB_RW_REG, reg);
-	if (ret)
-		return ret;
-
-	ret = regmap_read_poll_timeout(ao_cec->regmap, CECB_RW_REG, reg,
-				       !(reg & CECB_RW_BUS_BUSY),
-				       5, 1000);
-	if (ret)
-		return ret;
-
-	ret = regmap_read(ao_cec->regmap, CECB_RW_REG, &reg);
-
-	*data = FIELD_GET(CECB_RW_RD_DATA, reg);
-
-	return ret;
-}
-
-static int meson_ao_cec_g12a_write(void *context, unsigned int addr,
-				   unsigned int data)
-{
-	struct meson_ao_cec_g12a_device *ao_cec = context;
-	u32 reg = FIELD_PREP(CECB_RW_ADDR, addr) |
-		  FIELD_PREP(CECB_RW_WR_DATA, data) |
-		  CECB_RW_WRITE_EN;
-
-	return regmap_write(ao_cec->regmap, CECB_RW_REG, reg);
-}
-
-static const struct regmap_config meson_ao_cec_g12a_cec_regmap_conf = {
-	.reg_bits = 8,
-	.val_bits = 8,
-	.reg_read = meson_ao_cec_g12a_read,
-	.reg_write = meson_ao_cec_g12a_write,
-	.max_register = 0xffff,
-};
-
-static inline void
-meson_ao_cec_g12a_irq_setup(struct meson_ao_cec_g12a_device *ao_cec,
-			    bool enable)
-{
-	u32 cfg = CECB_INTR_DONE | CECB_INTR_EOM | CECB_INTR_NACK |
-		  CECB_INTR_ARB_LOSS | CECB_INTR_INITIATOR_ERR |
-		  CECB_INTR_FOLLOWER_ERR;
-
-	regmap_write(ao_cec->regmap, CECB_INTR_MASKN_REG,
-		     enable ? cfg : 0);
-}
-
-static void meson_ao_cec_g12a_irq_rx(struct meson_ao_cec_g12a_device *ao_cec)
-{
-	int i, ret = 0;
-	u32 val;
-
-	ret = regmap_read(ao_cec->regmap_cec, CECB_RX_CNT, &val);
-
-	ao_cec->rx_msg.len = val;
-	if (ao_cec->rx_msg.len > CEC_MAX_MSG_SIZE)
-		ao_cec->rx_msg.len = CEC_MAX_MSG_SIZE;
-
-	for (i = 0; i < ao_cec->rx_msg.len; i++) {
-		ret |= regmap_read(ao_cec->regmap_cec,
-				   CECB_RX_DATA00 + i, &val);
-
-		ao_cec->rx_msg.msg[i] = val & 0xff;
-	}
-
-	ret |= regmap_write(ao_cec->regmap_cec, CECB_LOCK_BUF, 0);
-	if (ret)
-		return;
-
-	cec_received_msg(ao_cec->adap, &ao_cec->rx_msg);
-}
-
-static irqreturn_t meson_ao_cec_g12a_irq(int irq, void *data)
-{
-	struct meson_ao_cec_g12a_device *ao_cec = data;
-	u32 stat;
-
-	regmap_read(ao_cec->regmap, CECB_INTR_STAT_REG, &stat);
-	if (stat)
-		return IRQ_WAKE_THREAD;
-
-	return IRQ_NONE;
-}
-
-static irqreturn_t meson_ao_cec_g12a_irq_thread(int irq, void *data)
-{
-	struct meson_ao_cec_g12a_device *ao_cec = data;
-	u32 stat;
-
-	regmap_read(ao_cec->regmap, CECB_INTR_STAT_REG, &stat);
-	regmap_write(ao_cec->regmap, CECB_INTR_CLR_REG, stat);
-
-	if (stat & CECB_INTR_DONE)
-		cec_transmit_attempt_done(ao_cec->adap, CEC_TX_STATUS_OK);
-
-	if (stat & CECB_INTR_EOM)
-		meson_ao_cec_g12a_irq_rx(ao_cec);
-
-	if (stat & CECB_INTR_NACK)
-		cec_transmit_attempt_done(ao_cec->adap, CEC_TX_STATUS_NACK);
-
-	if (stat & CECB_INTR_ARB_LOSS) {
-		regmap_write(ao_cec->regmap_cec, CECB_TX_CNT, 0);
-		regmap_update_bits(ao_cec->regmap_cec, CECB_CTRL,
-				   CECB_CTRL_SEND | CECB_CTRL_TYPE, 0);
-		cec_transmit_attempt_done(ao_cec->adap, CEC_TX_STATUS_ARB_LOST);
-	}
-
-	/* Initiator reports an error on the CEC bus */
-	if (stat & CECB_INTR_INITIATOR_ERR)
-		cec_transmit_attempt_done(ao_cec->adap, CEC_TX_STATUS_ERROR);
-
-	/* Follower reports a receive error, just reset RX buffer */
-	if (stat & CECB_INTR_FOLLOWER_ERR)
-		regmap_write(ao_cec->regmap_cec, CECB_LOCK_BUF, 0);
-
-	return IRQ_HANDLED;
-}
-
-static int
-meson_ao_cec_g12a_set_log_addr(struct cec_adapter *adap, u8 logical_addr)
-{
-	struct meson_ao_cec_g12a_device *ao_cec = adap->priv;
-	int ret = 0;
-
-	if (logical_addr == CEC_LOG_ADDR_INVALID) {
-		/* Assume this will allways succeed */
-		regmap_write(ao_cec->regmap_cec, CECB_LADD_LOW, 0);
-		regmap_write(ao_cec->regmap_cec, CECB_LADD_HIGH, 0);
-
-		return 0;
-	} else if (logical_addr < 8) {
-		ret = regmap_update_bits(ao_cec->regmap_cec, CECB_LADD_LOW,
-					 BIT(logical_addr),
-					 BIT(logical_addr));
-	} else {
-		ret = regmap_update_bits(ao_cec->regmap_cec, CECB_LADD_HIGH,
-					 BIT(logical_addr - 8),
-					 BIT(logical_addr - 8));
-	}
-
-	/* Always set Broadcast/Unregistered 15 address */
-	ret |= regmap_update_bits(ao_cec->regmap_cec, CECB_LADD_HIGH,
-				  BIT(CEC_LOG_ADDR_UNREGISTERED - 8),
-				  BIT(CEC_LOG_ADDR_UNREGISTERED - 8));
-
-	return ret ? -EIO : 0;
-}
-
-static int meson_ao_cec_g12a_transmit(struct cec_adapter *adap, u8 attempts,
-				 u32 signal_free_time, struct cec_msg *msg)
-{
-	struct meson_ao_cec_g12a_device *ao_cec = adap->priv;
-	unsigned int type;
-	int ret = 0;
-	u32 val;
-	int i;
-
-	/* Check if RX is in progress */
-	ret = regmap_read(ao_cec->regmap_cec, CECB_LOCK_BUF, &val);
-	if (ret)
-		return ret;
-	if (val & CECB_LOCK_BUF_EN)
-		return -EBUSY;
-
-	/* Check if TX Busy */
-	ret = regmap_read(ao_cec->regmap_cec, CECB_CTRL, &val);
-	if (ret)
-		return ret;
-	if (val & CECB_CTRL_SEND)
-		return -EBUSY;
-
-	switch (signal_free_time) {
-	case CEC_SIGNAL_FREE_TIME_RETRY:
-		type = CECB_CTRL_TYPE_RETRY;
-		break;
-	case CEC_SIGNAL_FREE_TIME_NEXT_XFER:
-		type = CECB_CTRL_TYPE_NEXT;
-		break;
-	case CEC_SIGNAL_FREE_TIME_NEW_INITIATOR:
-	default:
-		type = CECB_CTRL_TYPE_NEW;
-		break;
-	}
-
-	for (i = 0; i < msg->len; i++)
-		ret |= regmap_write(ao_cec->regmap_cec, CECB_TX_DATA00 + i,
-				    msg->msg[i]);
-
-	ret |= regmap_write(ao_cec->regmap_cec, CECB_TX_CNT, msg->len);
-	if (ret)
-		return -EIO;
-
-	ret = regmap_update_bits(ao_cec->regmap_cec, CECB_CTRL,
-				 CECB_CTRL_SEND |
-				 CECB_CTRL_TYPE,
-				 CECB_CTRL_SEND |
-				 FIELD_PREP(CECB_CTRL_TYPE, type));
-
-	return ret;
-}
-
-static int meson_ao_cec_g12a_adap_enable(struct cec_adapter *adap, bool enable)
-{
-	struct meson_ao_cec_g12a_device *ao_cec = adap->priv;
-
-	meson_ao_cec_g12a_irq_setup(ao_cec, false);
-
-	regmap_update_bits(ao_cec->regmap, CECB_GEN_CNTL_REG,
-			   CECB_GEN_CNTL_RESET, CECB_GEN_CNTL_RESET);
-
-	if (!enable)
-		return 0;
-
-	/* Setup Filter */
-	regmap_update_bits(ao_cec->regmap, CECB_GEN_CNTL_REG,
-			   CECB_GEN_CNTL_FILTER_TICK_SEL |
-			   CECB_GEN_CNTL_FILTER_DEL,
-			   FIELD_PREP(CECB_GEN_CNTL_FILTER_TICK_SEL,
-				      CECB_GEN_CNTL_FILTER_TICK_1US) |
-			   FIELD_PREP(CECB_GEN_CNTL_FILTER_DEL, 7));
-
-	/* Enable System Clock */
-	regmap_update_bits(ao_cec->regmap, CECB_GEN_CNTL_REG,
-			   CECB_GEN_CNTL_SYS_CLK_EN,
-			   CECB_GEN_CNTL_SYS_CLK_EN);
-
-	/* Enable gated clock (Normal mode). */
-	regmap_update_bits(ao_cec->regmap, CECB_GEN_CNTL_REG,
-			   CECB_GEN_CNTL_CLK_CTRL_MASK,
-			    FIELD_PREP(CECB_GEN_CNTL_CLK_CTRL_MASK,
-				       CECB_GEN_CNTL_CLK_ENABLE));
-
-	/* Release Reset */
-	regmap_update_bits(ao_cec->regmap, CECB_GEN_CNTL_REG,
-			   CECB_GEN_CNTL_RESET, 0);
-
-	if (ao_cec->data->ctrl2_setup)
-		regmap_write(ao_cec->regmap_cec, CECB_CTRL2,
-			     FIELD_PREP(CECB_CTRL2_RISE_DEL_MAX, 2));
-
-	meson_ao_cec_g12a_irq_setup(ao_cec, true);
-
-	return 0;
-}
-
-static const struct cec_adap_ops meson_ao_cec_g12a_ops = {
-	.adap_enable = meson_ao_cec_g12a_adap_enable,
-	.adap_log_addr = meson_ao_cec_g12a_set_log_addr,
-	.adap_transmit = meson_ao_cec_g12a_transmit,
-};
-
-static int meson_ao_cec_g12a_probe(struct platform_device *pdev)
-{
-	struct meson_ao_cec_g12a_device *ao_cec;
-	struct device *hdmi_dev;
-	struct resource *res;
-	void __iomem *base;
-	int ret, irq;
-
-	hdmi_dev = cec_notifier_parse_hdmi_phandle(&pdev->dev);
-	if (IS_ERR(hdmi_dev))
-		return PTR_ERR(hdmi_dev);
-
-	ao_cec = devm_kzalloc(&pdev->dev, sizeof(*ao_cec), GFP_KERNEL);
-	if (!ao_cec)
-		return -ENOMEM;
-
-	ao_cec->data = of_device_get_match_data(&pdev->dev);
-	if (!ao_cec->data) {
-		dev_err(&pdev->dev, "failed to get match data\n");
-		return -ENODEV;
-	}
-
-	spin_lock_init(&ao_cec->cec_reg_lock);
-	ao_cec->pdev = pdev;
-
-	ao_cec->adap = cec_allocate_adapter(&meson_ao_cec_g12a_ops, ao_cec,
-					    "meson_g12a_ao_cec",
-					    CEC_CAP_DEFAULTS |
-					    CEC_CAP_CONNECTOR_INFO,
-					    CEC_MAX_LOG_ADDRS);
-	if (IS_ERR(ao_cec->adap))
-		return PTR_ERR(ao_cec->adap);
-
-	ao_cec->adap->owner = THIS_MODULE;
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	base = devm_ioremap_resource(&pdev->dev, res);
-	if (IS_ERR(base)) {
-		ret = PTR_ERR(base);
-		goto out_probe_adapter;
-	}
-
-	ao_cec->regmap = devm_regmap_init_mmio(&pdev->dev, base,
-					       &meson_ao_cec_g12a_regmap_conf);
-	if (IS_ERR(ao_cec->regmap)) {
-		ret = PTR_ERR(ao_cec->regmap);
-		goto out_probe_adapter;
-	}
-
-	ao_cec->regmap_cec = devm_regmap_init(&pdev->dev, NULL, ao_cec,
-					   &meson_ao_cec_g12a_cec_regmap_conf);
-	if (IS_ERR(ao_cec->regmap_cec)) {
-		ret = PTR_ERR(ao_cec->regmap_cec);
-		goto out_probe_adapter;
-	}
-
-	irq = platform_get_irq(pdev, 0);
-	ret = devm_request_threaded_irq(&pdev->dev, irq,
-					meson_ao_cec_g12a_irq,
-					meson_ao_cec_g12a_irq_thread,
-					0, NULL, ao_cec);
-	if (ret) {
-		dev_err(&pdev->dev, "irq request failed\n");
-		goto out_probe_adapter;
-	}
-
-	ao_cec->oscin = devm_clk_get(&pdev->dev, "oscin");
-	if (IS_ERR(ao_cec->oscin)) {
-		dev_err(&pdev->dev, "oscin clock request failed\n");
-		ret = PTR_ERR(ao_cec->oscin);
-		goto out_probe_adapter;
-	}
-
-	ret = meson_ao_cec_g12a_setup_clk(ao_cec);
-	if (ret)
-		goto out_probe_adapter;
-
-	ret = clk_prepare_enable(ao_cec->core);
-	if (ret) {
-		dev_err(&pdev->dev, "core clock enable failed\n");
-		goto out_probe_adapter;
-	}
-
-	device_reset_optional(&pdev->dev);
-
-	platform_set_drvdata(pdev, ao_cec);
-
-	ao_cec->notify = cec_notifier_cec_adap_register(hdmi_dev, NULL,
-							ao_cec->adap);
-	if (!ao_cec->notify) {
-		ret = -ENOMEM;
-		goto out_probe_core_clk;
-	}
-
-	ret = cec_register_adapter(ao_cec->adap, &pdev->dev);
-	if (ret < 0)
-		goto out_probe_notify;
-
-	/* Setup Hardware */
-	regmap_write(ao_cec->regmap, CECB_GEN_CNTL_REG, CECB_GEN_CNTL_RESET);
-
-	return 0;
-
-out_probe_notify:
-	cec_notifier_cec_adap_unregister(ao_cec->notify, ao_cec->adap);
-
-out_probe_core_clk:
-	clk_disable_unprepare(ao_cec->core);
-
-out_probe_adapter:
-	cec_delete_adapter(ao_cec->adap);
-
-	dev_err(&pdev->dev, "CEC controller registration failed\n");
-
-	return ret;
-}
-
-static int meson_ao_cec_g12a_remove(struct platform_device *pdev)
-{
-	struct meson_ao_cec_g12a_device *ao_cec = platform_get_drvdata(pdev);
-
-	clk_disable_unprepare(ao_cec->core);
-
-	cec_notifier_cec_adap_unregister(ao_cec->notify, ao_cec->adap);
-
-	cec_unregister_adapter(ao_cec->adap);
-
-	return 0;
-}
-
-static const struct meson_ao_cec_g12a_data ao_cec_g12a_data = {
-	.ctrl2_setup = false,
-};
-
-static const struct meson_ao_cec_g12a_data ao_cec_sm1_data = {
-	.ctrl2_setup = true,
-};
-
-static const struct of_device_id meson_ao_cec_g12a_of_match[] = {
-	{
-		.compatible = "amlogic,meson-g12a-ao-cec",
-		.data = &ao_cec_g12a_data,
-	},
-	{
-		.compatible = "amlogic,meson-sm1-ao-cec",
-		.data = &ao_cec_sm1_data,
-	},
-	{ /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, meson_ao_cec_g12a_of_match);
-
-static struct platform_driver meson_ao_cec_g12a_driver = {
-	.probe   = meson_ao_cec_g12a_probe,
-	.remove  = meson_ao_cec_g12a_remove,
-	.driver  = {
-		.name = "meson-ao-cec-g12a",
-		.of_match_table = of_match_ptr(meson_ao_cec_g12a_of_match),
-	},
-};
-
-module_platform_driver(meson_ao_cec_g12a_driver);
-
-MODULE_DESCRIPTION("Meson AO CEC G12A Controller driver");
-MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/meson/ao-cec.c b/drivers/media/platform/meson/ao-cec.c
deleted file mode 100644
index 09aff82c3773..000000000000
--- a/drivers/media/platform/meson/ao-cec.c
+++ /dev/null
@@ -1,732 +0,0 @@
-/*
- * Driver for Amlogic Meson AO CEC Controller
- *
- * Copyright (C) 2015 Amlogic, Inc. All rights reserved
- * Copyright (C) 2017 BayLibre, SAS
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#include <linux/bitfield.h>
-#include <linux/clk.h>
-#include <linux/device.h>
-#include <linux/io.h>
-#include <linux/delay.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/of_platform.h>
-#include <linux/platform_device.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/reset.h>
-#include <media/cec.h>
-#include <media/cec-notifier.h>
-
-/* CEC Registers */
-
-/*
- * [2:1] cntl_clk
- *  - 0 = Disable clk (Power-off mode)
- *  - 1 = Enable gated clock (Normal mode)
- *  - 2 = Enable free-run clk (Debug mode)
- */
-#define CEC_GEN_CNTL_REG		0x00
-
-#define CEC_GEN_CNTL_RESET		BIT(0)
-#define CEC_GEN_CNTL_CLK_DISABLE	0
-#define CEC_GEN_CNTL_CLK_ENABLE		1
-#define CEC_GEN_CNTL_CLK_ENABLE_DBG	2
-#define CEC_GEN_CNTL_CLK_CTRL_MASK	GENMASK(2, 1)
-
-/*
- * [7:0] cec_reg_addr
- * [15:8] cec_reg_wrdata
- * [16] cec_reg_wr
- *  - 0 = Read
- *  - 1 = Write
- * [23] bus free
- * [31:24] cec_reg_rddata
- */
-#define CEC_RW_REG			0x04
-
-#define CEC_RW_ADDR			GENMASK(7, 0)
-#define CEC_RW_WR_DATA			GENMASK(15, 8)
-#define CEC_RW_WRITE_EN			BIT(16)
-#define CEC_RW_BUS_BUSY			BIT(23)
-#define CEC_RW_RD_DATA			GENMASK(31, 24)
-
-/*
- * [1] tx intr
- * [2] rx intr
- */
-#define CEC_INTR_MASKN_REG		0x08
-#define CEC_INTR_CLR_REG		0x0c
-#define CEC_INTR_STAT_REG		0x10
-
-#define CEC_INTR_TX			BIT(1)
-#define CEC_INTR_RX			BIT(2)
-
-/* CEC Commands */
-
-#define CEC_TX_MSG_0_HEADER		0x00
-#define CEC_TX_MSG_1_OPCODE		0x01
-#define CEC_TX_MSG_2_OP1		0x02
-#define CEC_TX_MSG_3_OP2		0x03
-#define CEC_TX_MSG_4_OP3		0x04
-#define CEC_TX_MSG_5_OP4		0x05
-#define CEC_TX_MSG_6_OP5		0x06
-#define CEC_TX_MSG_7_OP6		0x07
-#define CEC_TX_MSG_8_OP7		0x08
-#define CEC_TX_MSG_9_OP8		0x09
-#define CEC_TX_MSG_A_OP9		0x0A
-#define CEC_TX_MSG_B_OP10		0x0B
-#define CEC_TX_MSG_C_OP11		0x0C
-#define CEC_TX_MSG_D_OP12		0x0D
-#define CEC_TX_MSG_E_OP13		0x0E
-#define CEC_TX_MSG_F_OP14		0x0F
-#define CEC_TX_MSG_LENGTH		0x10
-#define CEC_TX_MSG_CMD			0x11
-#define CEC_TX_WRITE_BUF		0x12
-#define CEC_TX_CLEAR_BUF		0x13
-#define CEC_RX_MSG_CMD			0x14
-#define CEC_RX_CLEAR_BUF		0x15
-#define CEC_LOGICAL_ADDR0		0x16
-#define CEC_LOGICAL_ADDR1		0x17
-#define CEC_LOGICAL_ADDR2		0x18
-#define CEC_LOGICAL_ADDR3		0x19
-#define CEC_LOGICAL_ADDR4		0x1A
-#define CEC_CLOCK_DIV_H			0x1B
-#define CEC_CLOCK_DIV_L			0x1C
-#define CEC_QUIESCENT_25MS_BIT7_0	0x20
-#define CEC_QUIESCENT_25MS_BIT11_8	0x21
-#define CEC_STARTBITMINL2H_3MS5_BIT7_0	0x22
-#define CEC_STARTBITMINL2H_3MS5_BIT8	0x23
-#define CEC_STARTBITMAXL2H_3MS9_BIT7_0	0x24
-#define CEC_STARTBITMAXL2H_3MS9_BIT8	0x25
-#define CEC_STARTBITMINH_0MS6_BIT7_0	0x26
-#define CEC_STARTBITMINH_0MS6_BIT8	0x27
-#define CEC_STARTBITMAXH_1MS0_BIT7_0	0x28
-#define CEC_STARTBITMAXH_1MS0_BIT8	0x29
-#define CEC_STARTBITMINTOT_4MS3_BIT7_0	0x2A
-#define CEC_STARTBITMINTOT_4MS3_BIT9_8	0x2B
-#define CEC_STARTBITMAXTOT_4MS7_BIT7_0	0x2C
-#define CEC_STARTBITMAXTOT_4MS7_BIT9_8	0x2D
-#define CEC_LOGIC1MINL2H_0MS4_BIT7_0	0x2E
-#define CEC_LOGIC1MINL2H_0MS4_BIT8	0x2F
-#define CEC_LOGIC1MAXL2H_0MS8_BIT7_0	0x30
-#define CEC_LOGIC1MAXL2H_0MS8_BIT8	0x31
-#define CEC_LOGIC0MINL2H_1MS3_BIT7_0	0x32
-#define CEC_LOGIC0MINL2H_1MS3_BIT8	0x33
-#define CEC_LOGIC0MAXL2H_1MS7_BIT7_0	0x34
-#define CEC_LOGIC0MAXL2H_1MS7_BIT8	0x35
-#define CEC_LOGICMINTOTAL_2MS05_BIT7_0	0x36
-#define CEC_LOGICMINTOTAL_2MS05_BIT9_8	0x37
-#define CEC_LOGICMAXHIGH_2MS8_BIT7_0	0x38
-#define CEC_LOGICMAXHIGH_2MS8_BIT8	0x39
-#define CEC_LOGICERRLOW_3MS4_BIT7_0	0x3A
-#define CEC_LOGICERRLOW_3MS4_BIT8	0x3B
-#define CEC_NOMSMPPOINT_1MS05		0x3C
-#define CEC_DELCNTR_LOGICERR		0x3E
-#define CEC_TXTIME_17MS_BIT7_0		0x40
-#define CEC_TXTIME_17MS_BIT10_8		0x41
-#define CEC_TXTIME_2BIT_BIT7_0		0x42
-#define CEC_TXTIME_2BIT_BIT10_8		0x43
-#define CEC_TXTIME_4BIT_BIT7_0		0x44
-#define CEC_TXTIME_4BIT_BIT10_8		0x45
-#define CEC_STARTBITNOML2H_3MS7_BIT7_0	0x46
-#define CEC_STARTBITNOML2H_3MS7_BIT8	0x47
-#define CEC_STARTBITNOMH_0MS8_BIT7_0	0x48
-#define CEC_STARTBITNOMH_0MS8_BIT8	0x49
-#define CEC_LOGIC1NOML2H_0MS6_BIT7_0	0x4A
-#define CEC_LOGIC1NOML2H_0MS6_BIT8	0x4B
-#define CEC_LOGIC0NOML2H_1MS5_BIT7_0	0x4C
-#define CEC_LOGIC0NOML2H_1MS5_BIT8	0x4D
-#define CEC_LOGIC1NOMH_1MS8_BIT7_0	0x4E
-#define CEC_LOGIC1NOMH_1MS8_BIT8	0x4F
-#define CEC_LOGIC0NOMH_0MS9_BIT7_0	0x50
-#define CEC_LOGIC0NOMH_0MS9_BIT8	0x51
-#define CEC_LOGICERRLOW_3MS6_BIT7_0	0x52
-#define CEC_LOGICERRLOW_3MS6_BIT8	0x53
-#define CEC_CHKCONTENTION_0MS1		0x54
-#define CEC_PREPARENXTBIT_0MS05_BIT7_0	0x56
-#define CEC_PREPARENXTBIT_0MS05_BIT8	0x57
-#define CEC_NOMSMPACKPOINT_0MS45	0x58
-#define CEC_ACK0NOML2H_1MS5_BIT7_0	0x5A
-#define CEC_ACK0NOML2H_1MS5_BIT8	0x5B
-#define CEC_BUGFIX_DISABLE_0		0x60
-#define CEC_BUGFIX_DISABLE_1		0x61
-#define CEC_RX_MSG_0_HEADER		0x80
-#define CEC_RX_MSG_1_OPCODE		0x81
-#define CEC_RX_MSG_2_OP1		0x82
-#define CEC_RX_MSG_3_OP2		0x83
-#define CEC_RX_MSG_4_OP3		0x84
-#define CEC_RX_MSG_5_OP4		0x85
-#define CEC_RX_MSG_6_OP5		0x86
-#define CEC_RX_MSG_7_OP6		0x87
-#define CEC_RX_MSG_8_OP7		0x88
-#define CEC_RX_MSG_9_OP8		0x89
-#define CEC_RX_MSG_A_OP9		0x8A
-#define CEC_RX_MSG_B_OP10		0x8B
-#define CEC_RX_MSG_C_OP11		0x8C
-#define CEC_RX_MSG_D_OP12		0x8D
-#define CEC_RX_MSG_E_OP13		0x8E
-#define CEC_RX_MSG_F_OP14		0x8F
-#define CEC_RX_MSG_LENGTH		0x90
-#define CEC_RX_MSG_STATUS		0x91
-#define CEC_RX_NUM_MSG			0x92
-#define CEC_TX_MSG_STATUS		0x93
-#define CEC_TX_NUM_MSG			0x94
-
-
-/* CEC_TX_MSG_CMD definition */
-#define TX_NO_OP	0  /* No transaction */
-#define TX_REQ_CURRENT	1  /* Transmit earliest message in buffer */
-#define TX_ABORT	2  /* Abort transmitting earliest message */
-#define TX_REQ_NEXT	3  /* Overwrite earliest msg, transmit next */
-
-/* tx_msg_status definition */
-#define TX_IDLE		0  /* No transaction */
-#define TX_BUSY		1  /* Transmitter is busy */
-#define TX_DONE		2  /* Message successfully transmitted */
-#define TX_ERROR	3  /* Message transmitted with error */
-
-/* rx_msg_cmd */
-#define RX_NO_OP	0  /* No transaction */
-#define RX_ACK_CURRENT	1  /* Read earliest message in buffer */
-#define RX_DISABLE	2  /* Disable receiving latest message */
-#define RX_ACK_NEXT	3  /* Clear earliest msg, read next */
-
-/* rx_msg_status */
-#define RX_IDLE		0  /* No transaction */
-#define RX_BUSY		1  /* Receiver is busy */
-#define RX_DONE		2  /* Message has been received successfully */
-#define RX_ERROR	3  /* Message has been received with error */
-
-/* RX_CLEAR_BUF options */
-#define CLEAR_START	1
-#define CLEAR_STOP	0
-
-/* CEC_LOGICAL_ADDRx options */
-#define LOGICAL_ADDR_MASK	0xf
-#define LOGICAL_ADDR_VALID	BIT(4)
-#define LOGICAL_ADDR_DISABLE	0
-
-#define CEC_CLK_RATE		32768
-
-struct meson_ao_cec_device {
-	struct platform_device		*pdev;
-	void __iomem			*base;
-	struct clk			*core;
-	spinlock_t			cec_reg_lock;
-	struct cec_notifier		*notify;
-	struct cec_adapter		*adap;
-	struct cec_msg			rx_msg;
-};
-
-#define writel_bits_relaxed(mask, val, addr) \
-	writel_relaxed((readl_relaxed(addr) & ~(mask)) | (val), addr)
-
-static inline int meson_ao_cec_wait_busy(struct meson_ao_cec_device *ao_cec)
-{
-	ktime_t timeout = ktime_add_us(ktime_get(), 5000);
-
-	while (readl_relaxed(ao_cec->base + CEC_RW_REG) & CEC_RW_BUS_BUSY) {
-		if (ktime_compare(ktime_get(), timeout) > 0)
-			return -ETIMEDOUT;
-	}
-
-	return 0;
-}
-
-static void meson_ao_cec_read(struct meson_ao_cec_device *ao_cec,
-			     unsigned long address, u8 *data,
-			     int *res)
-{
-	unsigned long flags;
-	u32 reg = FIELD_PREP(CEC_RW_ADDR, address);
-	int ret = 0;
-
-	if (res && *res)
-		return;
-
-	spin_lock_irqsave(&ao_cec->cec_reg_lock, flags);
-
-	ret = meson_ao_cec_wait_busy(ao_cec);
-	if (ret)
-		goto read_out;
-
-	writel_relaxed(reg, ao_cec->base + CEC_RW_REG);
-
-	ret = meson_ao_cec_wait_busy(ao_cec);
-	if (ret)
-		goto read_out;
-
-	*data = FIELD_GET(CEC_RW_RD_DATA,
-			  readl_relaxed(ao_cec->base + CEC_RW_REG));
-
-read_out:
-	spin_unlock_irqrestore(&ao_cec->cec_reg_lock, flags);
-
-	if (res)
-		*res = ret;
-}
-
-static void meson_ao_cec_write(struct meson_ao_cec_device *ao_cec,
-			       unsigned long address, u8 data,
-			       int *res)
-{
-	unsigned long flags;
-	u32 reg = FIELD_PREP(CEC_RW_ADDR, address) |
-		  FIELD_PREP(CEC_RW_WR_DATA, data) |
-		  CEC_RW_WRITE_EN;
-	int ret = 0;
-
-	if (res && *res)
-		return;
-
-	spin_lock_irqsave(&ao_cec->cec_reg_lock, flags);
-
-	ret = meson_ao_cec_wait_busy(ao_cec);
-	if (ret)
-		goto write_out;
-
-	writel_relaxed(reg, ao_cec->base + CEC_RW_REG);
-
-write_out:
-	spin_unlock_irqrestore(&ao_cec->cec_reg_lock, flags);
-
-	if (res)
-		*res = ret;
-}
-
-static inline void meson_ao_cec_irq_setup(struct meson_ao_cec_device *ao_cec,
-				      bool enable)
-{
-	u32 cfg = CEC_INTR_TX | CEC_INTR_RX;
-
-	writel_bits_relaxed(cfg, enable ? cfg : 0,
-			    ao_cec->base + CEC_INTR_MASKN_REG);
-}
-
-static inline int meson_ao_cec_clear(struct meson_ao_cec_device *ao_cec)
-{
-	int ret = 0;
-
-	meson_ao_cec_write(ao_cec, CEC_RX_MSG_CMD, RX_DISABLE, &ret);
-	meson_ao_cec_write(ao_cec, CEC_TX_MSG_CMD, TX_ABORT, &ret);
-	meson_ao_cec_write(ao_cec, CEC_RX_CLEAR_BUF, 1, &ret);
-	meson_ao_cec_write(ao_cec, CEC_TX_CLEAR_BUF, 1, &ret);
-	if (ret)
-		return ret;
-
-	udelay(100);
-
-	meson_ao_cec_write(ao_cec, CEC_RX_CLEAR_BUF, 0, &ret);
-	meson_ao_cec_write(ao_cec, CEC_TX_CLEAR_BUF, 0, &ret);
-	if (ret)
-		return ret;
-
-	udelay(100);
-
-	meson_ao_cec_write(ao_cec, CEC_RX_MSG_CMD, RX_NO_OP, &ret);
-	meson_ao_cec_write(ao_cec, CEC_TX_MSG_CMD, TX_NO_OP, &ret);
-
-	return ret;
-}
-
-static int meson_ao_cec_arbit_bit_time_set(struct meson_ao_cec_device *ao_cec,
-					   unsigned int bit_set,
-					   unsigned int time_set)
-{
-	int ret = 0;
-
-	switch (bit_set) {
-	case CEC_SIGNAL_FREE_TIME_RETRY:
-		meson_ao_cec_write(ao_cec, CEC_TXTIME_4BIT_BIT7_0,
-				   time_set & 0xff, &ret);
-		meson_ao_cec_write(ao_cec, CEC_TXTIME_4BIT_BIT10_8,
-				   (time_set >> 8) & 0x7, &ret);
-		break;
-
-	case CEC_SIGNAL_FREE_TIME_NEW_INITIATOR:
-		meson_ao_cec_write(ao_cec, CEC_TXTIME_2BIT_BIT7_0,
-				   time_set & 0xff, &ret);
-		meson_ao_cec_write(ao_cec, CEC_TXTIME_2BIT_BIT10_8,
-				   (time_set >> 8) & 0x7, &ret);
-		break;
-
-	case CEC_SIGNAL_FREE_TIME_NEXT_XFER:
-		meson_ao_cec_write(ao_cec, CEC_TXTIME_17MS_BIT7_0,
-				   time_set & 0xff, &ret);
-		meson_ao_cec_write(ao_cec, CEC_TXTIME_17MS_BIT10_8,
-				   (time_set >> 8) & 0x7, &ret);
-		break;
-	}
-
-	return ret;
-}
-
-static irqreturn_t meson_ao_cec_irq(int irq, void *data)
-{
-	struct meson_ao_cec_device *ao_cec = data;
-	u32 stat = readl_relaxed(ao_cec->base + CEC_INTR_STAT_REG);
-
-	if (stat)
-		return IRQ_WAKE_THREAD;
-
-	return IRQ_NONE;
-}
-
-static void meson_ao_cec_irq_tx(struct meson_ao_cec_device *ao_cec)
-{
-	unsigned long tx_status = 0;
-	u8 stat;
-	int ret = 0;
-
-	meson_ao_cec_read(ao_cec, CEC_TX_MSG_STATUS, &stat, &ret);
-	if (ret)
-		goto tx_reg_err;
-
-	switch (stat) {
-	case TX_DONE:
-		tx_status = CEC_TX_STATUS_OK;
-		break;
-
-	case TX_BUSY:
-		tx_status = CEC_TX_STATUS_ARB_LOST;
-		break;
-
-	case TX_IDLE:
-		tx_status = CEC_TX_STATUS_LOW_DRIVE;
-		break;
-
-	case TX_ERROR:
-	default:
-		tx_status = CEC_TX_STATUS_NACK;
-		break;
-	}
-
-	/* Clear Interruption */
-	writel_relaxed(CEC_INTR_TX, ao_cec->base + CEC_INTR_CLR_REG);
-
-	/* Stop TX */
-	meson_ao_cec_write(ao_cec, CEC_TX_MSG_CMD, TX_NO_OP, &ret);
-	if (ret)
-		goto tx_reg_err;
-
-	cec_transmit_attempt_done(ao_cec->adap, tx_status);
-	return;
-
-tx_reg_err:
-	cec_transmit_attempt_done(ao_cec->adap, CEC_TX_STATUS_ERROR);
-}
-
-static void meson_ao_cec_irq_rx(struct meson_ao_cec_device *ao_cec)
-{
-	int i, ret = 0;
-	u8 reg;
-
-	meson_ao_cec_read(ao_cec, CEC_RX_MSG_STATUS, &reg, &ret);
-	if (reg != RX_DONE)
-		goto rx_out;
-
-	meson_ao_cec_read(ao_cec, CEC_RX_NUM_MSG, &reg, &ret);
-	if (reg != 1)
-		goto rx_out;
-
-	meson_ao_cec_read(ao_cec, CEC_RX_MSG_LENGTH, &reg, &ret);
-
-	ao_cec->rx_msg.len = reg + 1;
-	if (ao_cec->rx_msg.len > CEC_MAX_MSG_SIZE)
-		ao_cec->rx_msg.len = CEC_MAX_MSG_SIZE;
-
-	for (i = 0; i < ao_cec->rx_msg.len; i++) {
-		u8 byte;
-
-		meson_ao_cec_read(ao_cec, CEC_RX_MSG_0_HEADER + i, &byte, &ret);
-
-		ao_cec->rx_msg.msg[i] = byte;
-	}
-
-	if (ret)
-		goto rx_out;
-
-	cec_received_msg(ao_cec->adap, &ao_cec->rx_msg);
-
-rx_out:
-	/* Clear Interruption */
-	writel_relaxed(CEC_INTR_RX, ao_cec->base + CEC_INTR_CLR_REG);
-
-	/* Ack RX message */
-	meson_ao_cec_write(ao_cec, CEC_RX_MSG_CMD, RX_ACK_CURRENT, &ret);
-	meson_ao_cec_write(ao_cec, CEC_RX_MSG_CMD, RX_NO_OP, &ret);
-
-	/* Clear RX buffer */
-	meson_ao_cec_write(ao_cec, CEC_RX_CLEAR_BUF, CLEAR_START, &ret);
-	meson_ao_cec_write(ao_cec, CEC_RX_CLEAR_BUF, CLEAR_STOP, &ret);
-}
-
-static irqreturn_t meson_ao_cec_irq_thread(int irq, void *data)
-{
-	struct meson_ao_cec_device *ao_cec = data;
-	u32 stat = readl_relaxed(ao_cec->base + CEC_INTR_STAT_REG);
-
-	if (stat & CEC_INTR_TX)
-		meson_ao_cec_irq_tx(ao_cec);
-
-	meson_ao_cec_irq_rx(ao_cec);
-
-	return IRQ_HANDLED;
-}
-
-static int meson_ao_cec_set_log_addr(struct cec_adapter *adap, u8 logical_addr)
-{
-	struct meson_ao_cec_device *ao_cec = adap->priv;
-	int ret = 0;
-
-	meson_ao_cec_write(ao_cec, CEC_LOGICAL_ADDR0,
-			   LOGICAL_ADDR_DISABLE, &ret);
-	if (ret)
-		return ret;
-
-	ret = meson_ao_cec_clear(ao_cec);
-	if (ret)
-		return ret;
-
-	if (logical_addr == CEC_LOG_ADDR_INVALID)
-		return 0;
-
-	meson_ao_cec_write(ao_cec, CEC_LOGICAL_ADDR0,
-			   logical_addr & LOGICAL_ADDR_MASK, &ret);
-	if (ret)
-		return ret;
-
-	udelay(100);
-
-	meson_ao_cec_write(ao_cec, CEC_LOGICAL_ADDR0,
-			   (logical_addr & LOGICAL_ADDR_MASK) |
-			   LOGICAL_ADDR_VALID, &ret);
-
-	return ret;
-}
-
-static int meson_ao_cec_transmit(struct cec_adapter *adap, u8 attempts,
-				 u32 signal_free_time, struct cec_msg *msg)
-{
-	struct meson_ao_cec_device *ao_cec = adap->priv;
-	int i, ret = 0;
-	u8 reg;
-
-	meson_ao_cec_read(ao_cec, CEC_TX_MSG_STATUS, &reg, &ret);
-	if (ret)
-		return ret;
-
-	if (reg == TX_BUSY) {
-		dev_dbg(&ao_cec->pdev->dev, "%s: busy TX: aborting\n",
-			__func__);
-		meson_ao_cec_write(ao_cec, CEC_TX_MSG_CMD, TX_ABORT, &ret);
-	}
-
-	for (i = 0; i < msg->len; i++) {
-		meson_ao_cec_write(ao_cec, CEC_TX_MSG_0_HEADER + i,
-				   msg->msg[i], &ret);
-	}
-
-	meson_ao_cec_write(ao_cec, CEC_TX_MSG_LENGTH, msg->len - 1, &ret);
-	meson_ao_cec_write(ao_cec, CEC_TX_MSG_CMD, TX_REQ_CURRENT, &ret);
-
-	return ret;
-}
-
-static int meson_ao_cec_adap_enable(struct cec_adapter *adap, bool enable)
-{
-	struct meson_ao_cec_device *ao_cec = adap->priv;
-	int ret;
-
-	meson_ao_cec_irq_setup(ao_cec, false);
-
-	writel_bits_relaxed(CEC_GEN_CNTL_RESET, CEC_GEN_CNTL_RESET,
-			    ao_cec->base + CEC_GEN_CNTL_REG);
-
-	if (!enable)
-		return 0;
-
-	/* Enable gated clock (Normal mode). */
-	writel_bits_relaxed(CEC_GEN_CNTL_CLK_CTRL_MASK,
-			    FIELD_PREP(CEC_GEN_CNTL_CLK_CTRL_MASK,
-				       CEC_GEN_CNTL_CLK_ENABLE),
-			    ao_cec->base + CEC_GEN_CNTL_REG);
-
-	udelay(100);
-
-	/* Release Reset */
-	writel_bits_relaxed(CEC_GEN_CNTL_RESET, 0,
-			    ao_cec->base + CEC_GEN_CNTL_REG);
-
-	/* Clear buffers */
-	ret = meson_ao_cec_clear(ao_cec);
-	if (ret)
-		return ret;
-
-	/* CEC arbitration 3/5/7 bit time set. */
-	ret = meson_ao_cec_arbit_bit_time_set(ao_cec,
-					CEC_SIGNAL_FREE_TIME_RETRY,
-					0x118);
-	if (ret)
-		return ret;
-	ret = meson_ao_cec_arbit_bit_time_set(ao_cec,
-					CEC_SIGNAL_FREE_TIME_NEW_INITIATOR,
-					0x000);
-	if (ret)
-		return ret;
-	ret = meson_ao_cec_arbit_bit_time_set(ao_cec,
-					CEC_SIGNAL_FREE_TIME_NEXT_XFER,
-					0x2aa);
-	if (ret)
-		return ret;
-
-	meson_ao_cec_irq_setup(ao_cec, true);
-
-	return 0;
-}
-
-static const struct cec_adap_ops meson_ao_cec_ops = {
-	.adap_enable = meson_ao_cec_adap_enable,
-	.adap_log_addr = meson_ao_cec_set_log_addr,
-	.adap_transmit = meson_ao_cec_transmit,
-};
-
-static int meson_ao_cec_probe(struct platform_device *pdev)
-{
-	struct meson_ao_cec_device *ao_cec;
-	struct device *hdmi_dev;
-	struct resource *res;
-	int ret, irq;
-
-	hdmi_dev = cec_notifier_parse_hdmi_phandle(&pdev->dev);
-
-	if (IS_ERR(hdmi_dev))
-		return PTR_ERR(hdmi_dev);
-
-	ao_cec = devm_kzalloc(&pdev->dev, sizeof(*ao_cec), GFP_KERNEL);
-	if (!ao_cec)
-		return -ENOMEM;
-
-	spin_lock_init(&ao_cec->cec_reg_lock);
-
-	ao_cec->adap = cec_allocate_adapter(&meson_ao_cec_ops, ao_cec,
-					    "meson_ao_cec",
-					    CEC_CAP_DEFAULTS |
-					    CEC_CAP_CONNECTOR_INFO,
-					    1); /* Use 1 for now */
-	if (IS_ERR(ao_cec->adap))
-		return PTR_ERR(ao_cec->adap);
-
-	ao_cec->adap->owner = THIS_MODULE;
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	ao_cec->base = devm_ioremap_resource(&pdev->dev, res);
-	if (IS_ERR(ao_cec->base)) {
-		ret = PTR_ERR(ao_cec->base);
-		goto out_probe_adapter;
-	}
-
-	irq = platform_get_irq(pdev, 0);
-	ret = devm_request_threaded_irq(&pdev->dev, irq,
-					meson_ao_cec_irq,
-					meson_ao_cec_irq_thread,
-					0, NULL, ao_cec);
-	if (ret) {
-		dev_err(&pdev->dev, "irq request failed\n");
-		goto out_probe_adapter;
-	}
-
-	ao_cec->core = devm_clk_get(&pdev->dev, "core");
-	if (IS_ERR(ao_cec->core)) {
-		dev_err(&pdev->dev, "core clock request failed\n");
-		ret = PTR_ERR(ao_cec->core);
-		goto out_probe_adapter;
-	}
-
-	ret = clk_prepare_enable(ao_cec->core);
-	if (ret) {
-		dev_err(&pdev->dev, "core clock enable failed\n");
-		goto out_probe_adapter;
-	}
-
-	ret = clk_set_rate(ao_cec->core, CEC_CLK_RATE);
-	if (ret) {
-		dev_err(&pdev->dev, "core clock set rate failed\n");
-		goto out_probe_clk;
-	}
-
-	device_reset_optional(&pdev->dev);
-
-	ao_cec->pdev = pdev;
-	platform_set_drvdata(pdev, ao_cec);
-
-	ao_cec->notify = cec_notifier_cec_adap_register(hdmi_dev, NULL,
-							ao_cec->adap);
-	if (!ao_cec->notify) {
-		ret = -ENOMEM;
-		goto out_probe_clk;
-	}
-
-	ret = cec_register_adapter(ao_cec->adap, &pdev->dev);
-	if (ret < 0)
-		goto out_probe_notify;
-
-	/* Setup Hardware */
-	writel_relaxed(CEC_GEN_CNTL_RESET,
-		       ao_cec->base + CEC_GEN_CNTL_REG);
-
-	return 0;
-
-out_probe_notify:
-	cec_notifier_cec_adap_unregister(ao_cec->notify, ao_cec->adap);
-
-out_probe_clk:
-	clk_disable_unprepare(ao_cec->core);
-
-out_probe_adapter:
-	cec_delete_adapter(ao_cec->adap);
-
-	dev_err(&pdev->dev, "CEC controller registration failed\n");
-
-	return ret;
-}
-
-static int meson_ao_cec_remove(struct platform_device *pdev)
-{
-	struct meson_ao_cec_device *ao_cec = platform_get_drvdata(pdev);
-
-	clk_disable_unprepare(ao_cec->core);
-
-	cec_notifier_cec_adap_unregister(ao_cec->notify, ao_cec->adap);
-	cec_unregister_adapter(ao_cec->adap);
-
-	return 0;
-}
-
-static const struct of_device_id meson_ao_cec_of_match[] = {
-	{ .compatible = "amlogic,meson-gx-ao-cec", },
-	{ /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, meson_ao_cec_of_match);
-
-static struct platform_driver meson_ao_cec_driver = {
-	.probe   = meson_ao_cec_probe,
-	.remove  = meson_ao_cec_remove,
-	.driver  = {
-		.name = "meson-ao-cec",
-		.of_match_table = of_match_ptr(meson_ao_cec_of_match),
-	},
-};
-
-module_platform_driver(meson_ao_cec_driver);
-
-MODULE_DESCRIPTION("Meson AO CEC Controller driver");
-MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/pxa_camera.c b/drivers/media/platform/pxa_camera.c
index 70c85a2a10f5..3c5fe737d36f 100644
--- a/drivers/media/platform/pxa_camera.c
+++ b/drivers/media/platform/pxa_camera.c
@@ -1016,7 +1016,7 @@ static void pxa_camera_wakeup(struct pxa_camera_dev *pcdev,
  *  - a videobuffer is queued on the pcdev->capture list
  *
  * Please check the "DMA hot chaining timeslice issue" in
- *   Documentation/media/v4l-drivers/pxa_camera.rst
+ *   Documentation/driver-api/media/drivers/pxa_camera.rst
  *
  * Context: should only be called within the dma irq handler
  */
@@ -1438,7 +1438,7 @@ static void pxac_vb2_queue(struct vb2_buffer *vb)
 
 /*
  * Please check the DMA prepared buffer structure in :
- *   Documentation/media/v4l-drivers/pxa_camera.rst
+ *   Documentation/driver-api/media/drivers/pxa_camera.rst
  * Please check also in pxa_camera_check_link_miss() to understand why DMA chain
  * modification while DMA chain is running will work anyway.
  */
diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c
index 194b10b98767..4395cb96fb04 100644
--- a/drivers/media/platform/qcom/venus/core.c
+++ b/drivers/media/platform/qcom/venus/core.c
@@ -210,6 +210,8 @@ static int venus_probe(struct platform_device *pdev)
 	if (!core->res)
 		return -ENODEV;
 
+	mutex_init(&core->pm_lock);
+
 	core->pm_ops = venus_pm_get(core->res->hfi_version);
 	if (!core->pm_ops)
 		return -ENODEV;
@@ -242,10 +244,6 @@ static int venus_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	ret = icc_set_bw(core->cpucfg_path, 0, kbps_to_icc(1000));
-	if (ret)
-		return ret;
-
 	ret = hfi_create(core, &venus_core_ops);
 	if (ret)
 		return ret;
@@ -336,6 +334,7 @@ static int venus_remove(struct platform_device *pdev)
 	icc_put(core->cpucfg_path);
 
 	v4l2_device_unregister(&core->v4l2_dev);
+	mutex_destroy(&core->pm_lock);
 
 	return ret;
 }
@@ -350,6 +349,10 @@ static __maybe_unused int venus_runtime_suspend(struct device *dev)
 	if (ret)
 		return ret;
 
+	ret = icc_set_bw(core->cpucfg_path, 0, 0);
+	if (ret)
+		return ret;
+
 	if (pm_ops->core_power)
 		ret = pm_ops->core_power(dev, POWER_OFF);
 
@@ -368,6 +371,10 @@ static __maybe_unused int venus_runtime_resume(struct device *dev)
 			return ret;
 	}
 
+	ret = icc_set_bw(core->cpucfg_path, 0, kbps_to_icc(1000));
+	if (ret)
+		return ret;
+
 	return hfi_core_resume(core, false);
 }
 
diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h
index bd3ac6a4501f..3ab644a39786 100644
--- a/drivers/media/platform/qcom/venus/core.h
+++ b/drivers/media/platform/qcom/venus/core.h
@@ -128,6 +128,7 @@ struct venus_caps {
  * @error:	an error returned during last HFI sync operations
  * @sys_error:	an error flag that signal system error event
  * @core_ops:	the core operations
+ * @pm_lock:	a lock for PM operations
  * @enc_codecs:	encoders supported by this core
  * @dec_codecs:	decoders supported by this core
  * @max_sessions_supported:	holds the maximum number of sessions
@@ -168,6 +169,7 @@ struct venus_core {
 	bool sys_error;
 	const struct hfi_core_ops *core_ops;
 	const struct venus_pm_ops *pm_ops;
+	struct mutex pm_lock;
 	unsigned long enc_codecs;
 	unsigned long dec_codecs;
 	unsigned int max_sessions_supported;
diff --git a/drivers/media/platform/qcom/venus/hfi_cmds.h b/drivers/media/platform/qcom/venus/hfi_cmds.h
index cae9d5d61c0c..83705e237f1c 100644
--- a/drivers/media/platform/qcom/venus/hfi_cmds.h
+++ b/drivers/media/platform/qcom/venus/hfi_cmds.h
@@ -107,7 +107,7 @@ struct hfi_session_abort_pkt {
 struct hfi_session_set_property_pkt {
 	struct hfi_session_hdr_pkt shdr;
 	u32 num_properties;
-	u32 data[0];
+	u32 data[];
 };
 
 struct hfi_session_set_buffers_pkt {
diff --git a/drivers/media/platform/qcom/venus/hfi_msgs.h b/drivers/media/platform/qcom/venus/hfi_msgs.h
index 7694b1d25d9d..526d9f5b487b 100644
--- a/drivers/media/platform/qcom/venus/hfi_msgs.h
+++ b/drivers/media/platform/qcom/venus/hfi_msgs.h
@@ -155,7 +155,7 @@ struct hfi_msg_session_empty_buffer_done_pkt {
 	u32 input_tag;
 	u32 packet_buffer;
 	u32 extradata_buffer;
-	u32 data[0];
+	u32 data[];
 };
 
 struct hfi_msg_session_fbd_compressed_pkt {
@@ -175,7 +175,7 @@ struct hfi_msg_session_fbd_compressed_pkt {
 	u32 picture_type;
 	u32 packet_buffer;
 	u32 extradata_buffer;
-	u32 data[0];
+	u32 data[];
 };
 
 struct hfi_msg_session_fbd_uncompressed_plane0_pkt {
@@ -202,7 +202,7 @@ struct hfi_msg_session_fbd_uncompressed_plane0_pkt {
 	u32 picture_type;
 	u32 packet_buffer;
 	u32 extradata_buffer;
-	u32 data[0];
+	u32 data[];
 };
 
 struct hfi_msg_session_fbd_uncompressed_plane1_pkt {
@@ -211,7 +211,7 @@ struct hfi_msg_session_fbd_uncompressed_plane1_pkt {
 	u32 filled_len;
 	u32 offset;
 	u32 packet_buffer2;
-	u32 data[0];
+	u32 data[];
 };
 
 struct hfi_msg_session_fbd_uncompressed_plane2_pkt {
@@ -220,7 +220,7 @@ struct hfi_msg_session_fbd_uncompressed_plane2_pkt {
 	u32 filled_len;
 	u32 offset;
 	u32 packet_buffer3;
-	u32 data[0];
+	u32 data[];
 };
 
 struct hfi_msg_session_parse_sequence_header_done_pkt {
diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c
index 4ed2628585a1..e8e1ecf7cf4a 100644
--- a/drivers/media/platform/qcom/venus/vdec.c
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -545,6 +545,64 @@ static const struct v4l2_ioctl_ops vdec_ioctl_ops = {
 	.vidioc_decoder_cmd = vdec_decoder_cmd,
 };
 
+static int vdec_pm_get(struct venus_inst *inst)
+{
+	struct venus_core *core = inst->core;
+	struct device *dev = core->dev_dec;
+	int ret;
+
+	mutex_lock(&core->pm_lock);
+	ret = pm_runtime_get_sync(dev);
+	mutex_unlock(&core->pm_lock);
+
+	return ret < 0 ? ret : 0;
+}
+
+static int vdec_pm_put(struct venus_inst *inst, bool autosuspend)
+{
+	struct venus_core *core = inst->core;
+	struct device *dev = core->dev_dec;
+	int ret;
+
+	mutex_lock(&core->pm_lock);
+
+	if (autosuspend)
+		ret = pm_runtime_put_autosuspend(dev);
+	else
+		ret = pm_runtime_put_sync(dev);
+
+	mutex_unlock(&core->pm_lock);
+
+	return ret < 0 ? ret : 0;
+}
+
+static int vdec_pm_get_put(struct venus_inst *inst)
+{
+	struct venus_core *core = inst->core;
+	struct device *dev = core->dev_dec;
+	int ret = 0;
+
+	mutex_lock(&core->pm_lock);
+
+	if (pm_runtime_suspended(dev)) {
+		ret = pm_runtime_get_sync(dev);
+		if (ret < 0)
+			goto error;
+
+		ret = pm_runtime_put_autosuspend(dev);
+	}
+
+error:
+	mutex_unlock(&core->pm_lock);
+
+	return ret < 0 ? ret : 0;
+}
+
+static void vdec_pm_touch(struct venus_inst *inst)
+{
+	pm_runtime_mark_last_busy(inst->core->dev_dec);
+}
+
 static int vdec_set_properties(struct venus_inst *inst)
 {
 	struct vdec_controls *ctr = &inst->controls.dec;
@@ -746,11 +804,19 @@ static int vdec_queue_setup(struct vb2_queue *q,
 		return 0;
 	}
 
-	ret = vdec_session_init(inst);
+	ret = vdec_pm_get(inst);
 	if (ret)
 		return ret;
 
+	ret = vdec_session_init(inst);
+	if (ret)
+		goto put_power;
+
 	ret = vdec_num_buffers(inst, &in_num, &out_num);
+	if (ret)
+		goto put_power;
+
+	ret = vdec_pm_put(inst, false);
 	if (ret)
 		return ret;
 
@@ -786,6 +852,10 @@ static int vdec_queue_setup(struct vb2_queue *q,
 	}
 
 	return ret;
+
+put_power:
+	vdec_pm_put(inst, false);
+	return ret;
 }
 
 static int vdec_verify_conf(struct venus_inst *inst)
@@ -947,14 +1017,23 @@ static int vdec_start_streaming(struct vb2_queue *q, unsigned int count)
 
 	mutex_lock(&inst->lock);
 
-	ret = venus_pm_acquire_core(inst);
-	if (ret)
-		goto error;
-
-	if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+	if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
 		ret = vdec_start_capture(inst);
-	else
+	} else {
+		ret = vdec_pm_get(inst);
+		if (ret)
+			goto error;
+
+		ret = venus_pm_acquire_core(inst);
+		if (ret)
+			goto put_power;
+
+		ret = vdec_pm_put(inst, true);
+		if (ret)
+			goto error;
+
 		ret = vdec_start_output(inst);
+	}
 
 	if (ret)
 		goto error;
@@ -962,6 +1041,8 @@ static int vdec_start_streaming(struct vb2_queue *q, unsigned int count)
 	mutex_unlock(&inst->lock);
 	return 0;
 
+put_power:
+	vdec_pm_put(inst, false);
 error:
 	venus_helper_buffers_done(inst, VB2_BUF_STATE_QUEUED);
 	mutex_unlock(&inst->lock);
@@ -1055,8 +1136,9 @@ static void vdec_session_release(struct venus_inst *inst)
 	struct venus_core *core = inst->core;
 	int ret, abort = 0;
 
-	mutex_lock(&inst->lock);
+	vdec_pm_get(inst);
 
+	mutex_lock(&inst->lock);
 	inst->codec_state = VENUS_DEC_STATE_DEINIT;
 
 	ret = hfi_session_stop(inst);
@@ -1078,10 +1160,11 @@ static void vdec_session_release(struct venus_inst *inst)
 
 	venus_helper_free_dpb_bufs(inst);
 	venus_pm_load_scale(inst);
-	venus_pm_release_core(inst);
 	INIT_LIST_HEAD(&inst->registeredbufs);
-
 	mutex_unlock(&inst->lock);
+
+	venus_pm_release_core(inst);
+	vdec_pm_put(inst, false);
 }
 
 static int vdec_buf_init(struct vb2_buffer *vb)
@@ -1102,6 +1185,15 @@ static void vdec_buf_cleanup(struct vb2_buffer *vb)
 		vdec_session_release(inst);
 }
 
+static void vdec_vb2_buf_queue(struct vb2_buffer *vb)
+{
+	struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
+
+	vdec_pm_get_put(inst);
+
+	venus_helper_vb2_buf_queue(vb);
+}
+
 static const struct vb2_ops vdec_vb2_ops = {
 	.queue_setup = vdec_queue_setup,
 	.buf_init = vdec_buf_init,
@@ -1109,7 +1201,7 @@ static const struct vb2_ops vdec_vb2_ops = {
 	.buf_prepare = venus_helper_vb2_buf_prepare,
 	.start_streaming = vdec_start_streaming,
 	.stop_streaming = vdec_stop_streaming,
-	.buf_queue = venus_helper_vb2_buf_queue,
+	.buf_queue = vdec_vb2_buf_queue,
 };
 
 static void vdec_buf_done(struct venus_inst *inst, unsigned int buf_type,
@@ -1121,6 +1213,8 @@ static void vdec_buf_done(struct venus_inst *inst, unsigned int buf_type,
 	struct vb2_buffer *vb;
 	unsigned int type;
 
+	vdec_pm_touch(inst);
+
 	if (buf_type == HFI_BUFFER_INPUT)
 		type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
 	else
@@ -1227,6 +1321,8 @@ static void vdec_event_notify(struct venus_inst *inst, u32 event,
 	struct venus_core *core = inst->core;
 	struct device *dev = core->dev_dec;
 
+	vdec_pm_touch(inst);
+
 	switch (event) {
 	case EVT_SESSION_ERROR:
 		inst->session_error = true;
@@ -1347,13 +1443,9 @@ static int vdec_open(struct file *file)
 	init_waitqueue_head(&inst->reconf_wait);
 	venus_helper_init_instance(inst);
 
-	ret = pm_runtime_get_sync(core->dev_dec);
-	if (ret < 0)
-		goto err_free_inst;
-
 	ret = vdec_ctrl_init(inst);
 	if (ret)
-		goto err_put_sync;
+		goto err_free;
 
 	ret = hfi_session_create(inst, &vdec_hfi_ops);
 	if (ret)
@@ -1392,9 +1484,7 @@ static int vdec_open(struct file *file)
 	hfi_session_destroy(inst);
 err_ctrl_deinit:
 	vdec_ctrl_deinit(inst);
-err_put_sync:
-	pm_runtime_put_sync(core->dev_dec);
-err_free_inst:
+err_free:
 	kfree(inst);
 	return ret;
 }
@@ -1403,6 +1493,8 @@ static int vdec_close(struct file *file)
 {
 	struct venus_inst *inst = to_inst(file);
 
+	vdec_pm_get(inst);
+
 	v4l2_m2m_ctx_release(inst->m2m_ctx);
 	v4l2_m2m_release(inst->m2m_dev);
 	vdec_ctrl_deinit(inst);
@@ -1411,7 +1503,7 @@ static int vdec_close(struct file *file)
 	v4l2_fh_del(&inst->fh);
 	v4l2_fh_exit(&inst->fh);
 
-	pm_runtime_put_sync(inst->core->dev_dec);
+	vdec_pm_put(inst, false);
 
 	kfree(inst);
 	return 0;
@@ -1468,6 +1560,8 @@ static int vdec_probe(struct platform_device *pdev)
 	core->dev_dec = dev;
 
 	video_set_drvdata(vdev, core);
+	pm_runtime_set_autosuspend_delay(dev, 2000);
+	pm_runtime_use_autosuspend(dev);
 	pm_runtime_enable(dev);
 
 	return 0;
diff --git a/drivers/media/platform/rcar-vin/Kconfig b/drivers/media/platform/rcar-vin/Kconfig
index 240ac3f3c941..ca0d906dce2f 100644
--- a/drivers/media/platform/rcar-vin/Kconfig
+++ b/drivers/media/platform/rcar-vin/Kconfig
@@ -1,8 +1,10 @@
 # SPDX-License-Identifier: GPL-2.0
 config VIDEO_RCAR_CSI2
 	tristate "R-Car MIPI CSI-2 Receiver"
-	depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF
+	depends on VIDEO_V4L2 && OF
 	depends on ARCH_RENESAS || COMPILE_TEST
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select RESET_CONTROLLER
 	select V4L2_FWNODE
 	help
@@ -14,8 +16,10 @@ config VIDEO_RCAR_CSI2
 
 config VIDEO_RCAR_VIN
 	tristate "R-Car Video Input (VIN) Driver"
-	depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF && MEDIA_CONTROLLER
+	depends on VIDEO_V4L2 && OF
 	depends on ARCH_RENESAS || COMPILE_TEST
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select VIDEOBUF2_DMA_CONTIG
 	select V4L2_FWNODE
 	help
diff --git a/drivers/media/platform/s5p-cec/Makefile b/drivers/media/platform/s5p-cec/Makefile
deleted file mode 100644
index bd0103b91bee..000000000000
--- a/drivers/media/platform/s5p-cec/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_VIDEO_SAMSUNG_S5P_CEC)	+= s5p-cec.o
-s5p-cec-y += s5p_cec.o exynos_hdmi_cecctrl.o
diff --git a/drivers/media/platform/s5p-cec/exynos_hdmi_cec.h b/drivers/media/platform/s5p-cec/exynos_hdmi_cec.h
deleted file mode 100644
index 325db8c432bd..000000000000
--- a/drivers/media/platform/s5p-cec/exynos_hdmi_cec.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/* drivers/media/platform/s5p-cec/exynos_hdmi_cec.h
- *
- * Copyright (c) 2010, 2014 Samsung Electronics
- *		http://www.samsung.com/
- *
- * Header file for interface of Samsung Exynos hdmi cec hardware
- */
-
-#ifndef _EXYNOS_HDMI_CEC_H_
-#define _EXYNOS_HDMI_CEC_H_ __FILE__
-
-#include <linux/regmap.h>
-#include "s5p_cec.h"
-
-void s5p_cec_set_divider(struct s5p_cec_dev *cec);
-void s5p_cec_enable_rx(struct s5p_cec_dev *cec);
-void s5p_cec_mask_rx_interrupts(struct s5p_cec_dev *cec);
-void s5p_cec_unmask_rx_interrupts(struct s5p_cec_dev *cec);
-void s5p_cec_mask_tx_interrupts(struct s5p_cec_dev *cec);
-void s5p_cec_unmask_tx_interrupts(struct s5p_cec_dev *cec);
-void s5p_cec_reset(struct s5p_cec_dev *cec);
-void s5p_cec_tx_reset(struct s5p_cec_dev *cec);
-void s5p_cec_rx_reset(struct s5p_cec_dev *cec);
-void s5p_cec_threshold(struct s5p_cec_dev *cec);
-void s5p_cec_copy_packet(struct s5p_cec_dev *cec, char *data,
-			 size_t count, u8 retries);
-void s5p_cec_set_addr(struct s5p_cec_dev *cec, u32 addr);
-u32 s5p_cec_get_status(struct s5p_cec_dev *cec);
-void s5p_clr_pending_tx(struct s5p_cec_dev *cec);
-void s5p_clr_pending_rx(struct s5p_cec_dev *cec);
-void s5p_cec_get_rx_buf(struct s5p_cec_dev *cec, u32 size, u8 *buffer);
-
-#endif /* _EXYNOS_HDMI_CEC_H_ */
diff --git a/drivers/media/platform/s5p-cec/exynos_hdmi_cecctrl.c b/drivers/media/platform/s5p-cec/exynos_hdmi_cecctrl.c
deleted file mode 100644
index eb981ebce362..000000000000
--- a/drivers/media/platform/s5p-cec/exynos_hdmi_cecctrl.c
+++ /dev/null
@@ -1,206 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/* drivers/media/platform/s5p-cec/exynos_hdmi_cecctrl.c
- *
- * Copyright (c) 2009, 2014 Samsung Electronics
- *		http://www.samsung.com/
- *
- * cec ftn file for Samsung TVOUT driver
- */
-
-#include <linux/io.h>
-#include <linux/device.h>
-
-#include "exynos_hdmi_cec.h"
-#include "regs-cec.h"
-
-#define S5P_HDMI_FIN			24000000
-#define CEC_DIV_RATIO			320000
-
-#define CEC_MESSAGE_BROADCAST_MASK	0x0F
-#define CEC_MESSAGE_BROADCAST		0x0F
-#define CEC_FILTER_THRESHOLD		0x15
-
-void s5p_cec_set_divider(struct s5p_cec_dev *cec)
-{
-	u32 div_ratio, div_val;
-	unsigned int reg;
-
-	div_ratio  = S5P_HDMI_FIN / CEC_DIV_RATIO - 1;
-
-	if (regmap_read(cec->pmu, EXYNOS_HDMI_PHY_CONTROL, &reg)) {
-		dev_err(cec->dev, "failed to read phy control\n");
-		return;
-	}
-
-	reg = (reg & ~(0x3FF << 16)) | (div_ratio << 16);
-
-	if (regmap_write(cec->pmu, EXYNOS_HDMI_PHY_CONTROL, reg)) {
-		dev_err(cec->dev, "failed to write phy control\n");
-		return;
-	}
-
-	div_val = CEC_DIV_RATIO * 0.00005 - 1;
-
-	writeb(0x0, cec->reg + S5P_CEC_DIVISOR_3);
-	writeb(0x0, cec->reg + S5P_CEC_DIVISOR_2);
-	writeb(0x0, cec->reg + S5P_CEC_DIVISOR_1);
-	writeb(div_val, cec->reg + S5P_CEC_DIVISOR_0);
-}
-
-void s5p_cec_enable_rx(struct s5p_cec_dev *cec)
-{
-	u8 reg;
-
-	reg = readb(cec->reg + S5P_CEC_RX_CTRL);
-	reg |= S5P_CEC_RX_CTRL_ENABLE;
-	writeb(reg, cec->reg + S5P_CEC_RX_CTRL);
-}
-
-void s5p_cec_mask_rx_interrupts(struct s5p_cec_dev *cec)
-{
-	u8 reg;
-
-	reg = readb(cec->reg + S5P_CEC_IRQ_MASK);
-	reg |= S5P_CEC_IRQ_RX_DONE;
-	reg |= S5P_CEC_IRQ_RX_ERROR;
-	writeb(reg, cec->reg + S5P_CEC_IRQ_MASK);
-}
-
-void s5p_cec_unmask_rx_interrupts(struct s5p_cec_dev *cec)
-{
-	u8 reg;
-
-	reg = readb(cec->reg + S5P_CEC_IRQ_MASK);
-	reg &= ~S5P_CEC_IRQ_RX_DONE;
-	reg &= ~S5P_CEC_IRQ_RX_ERROR;
-	writeb(reg, cec->reg + S5P_CEC_IRQ_MASK);
-}
-
-void s5p_cec_mask_tx_interrupts(struct s5p_cec_dev *cec)
-{
-	u8 reg;
-
-	reg = readb(cec->reg + S5P_CEC_IRQ_MASK);
-	reg |= S5P_CEC_IRQ_TX_DONE;
-	reg |= S5P_CEC_IRQ_TX_ERROR;
-	writeb(reg, cec->reg + S5P_CEC_IRQ_MASK);
-}
-
-void s5p_cec_unmask_tx_interrupts(struct s5p_cec_dev *cec)
-{
-	u8 reg;
-
-	reg = readb(cec->reg + S5P_CEC_IRQ_MASK);
-	reg &= ~S5P_CEC_IRQ_TX_DONE;
-	reg &= ~S5P_CEC_IRQ_TX_ERROR;
-	writeb(reg, cec->reg + S5P_CEC_IRQ_MASK);
-}
-
-void s5p_cec_reset(struct s5p_cec_dev *cec)
-{
-	u8 reg;
-
-	writeb(S5P_CEC_RX_CTRL_RESET, cec->reg + S5P_CEC_RX_CTRL);
-	writeb(S5P_CEC_TX_CTRL_RESET, cec->reg + S5P_CEC_TX_CTRL);
-
-	reg = readb(cec->reg + 0xc4);
-	reg &= ~0x1;
-	writeb(reg, cec->reg + 0xc4);
-}
-
-void s5p_cec_tx_reset(struct s5p_cec_dev *cec)
-{
-	writeb(S5P_CEC_TX_CTRL_RESET, cec->reg + S5P_CEC_TX_CTRL);
-}
-
-void s5p_cec_rx_reset(struct s5p_cec_dev *cec)
-{
-	u8 reg;
-
-	writeb(S5P_CEC_RX_CTRL_RESET, cec->reg + S5P_CEC_RX_CTRL);
-
-	reg = readb(cec->reg + 0xc4);
-	reg &= ~0x1;
-	writeb(reg, cec->reg + 0xc4);
-}
-
-void s5p_cec_threshold(struct s5p_cec_dev *cec)
-{
-	writeb(CEC_FILTER_THRESHOLD, cec->reg + S5P_CEC_RX_FILTER_TH);
-	writeb(0, cec->reg + S5P_CEC_RX_FILTER_CTRL);
-}
-
-void s5p_cec_copy_packet(struct s5p_cec_dev *cec, char *data,
-			 size_t count, u8 retries)
-{
-	int i = 0;
-	u8 reg;
-
-	while (i < count) {
-		writeb(data[i], cec->reg + (S5P_CEC_TX_BUFF0 + (i * 4)));
-		i++;
-	}
-
-	writeb(count, cec->reg + S5P_CEC_TX_BYTES);
-	reg = readb(cec->reg + S5P_CEC_TX_CTRL);
-	reg |= S5P_CEC_TX_CTRL_START;
-	reg &= ~0x70;
-	reg |= retries << 4;
-
-	if ((data[0] & CEC_MESSAGE_BROADCAST_MASK) == CEC_MESSAGE_BROADCAST) {
-		dev_dbg(cec->dev, "Broadcast");
-		reg |= S5P_CEC_TX_CTRL_BCAST;
-	} else {
-		dev_dbg(cec->dev, "No Broadcast");
-		reg &= ~S5P_CEC_TX_CTRL_BCAST;
-	}
-
-	writeb(reg, cec->reg + S5P_CEC_TX_CTRL);
-	dev_dbg(cec->dev, "cec-tx: cec count (%zu): %*ph", count,
-		(int)count, data);
-}
-
-void s5p_cec_set_addr(struct s5p_cec_dev *cec, u32 addr)
-{
-	writeb(addr & 0x0F, cec->reg + S5P_CEC_LOGIC_ADDR);
-}
-
-u32 s5p_cec_get_status(struct s5p_cec_dev *cec)
-{
-	u32 status = 0;
-
-	status = readb(cec->reg + S5P_CEC_STATUS_0) & 0xf;
-	status |= (readb(cec->reg + S5P_CEC_TX_STAT1) & 0xf) << 4;
-	status |= readb(cec->reg + S5P_CEC_STATUS_1) << 8;
-	status |= readb(cec->reg + S5P_CEC_STATUS_2) << 16;
-	status |= readb(cec->reg + S5P_CEC_STATUS_3) << 24;
-
-	dev_dbg(cec->dev, "status = 0x%x!\n", status);
-
-	return status;
-}
-
-void s5p_clr_pending_tx(struct s5p_cec_dev *cec)
-{
-	writeb(S5P_CEC_IRQ_TX_DONE | S5P_CEC_IRQ_TX_ERROR,
-	       cec->reg + S5P_CEC_IRQ_CLEAR);
-}
-
-void s5p_clr_pending_rx(struct s5p_cec_dev *cec)
-{
-	writeb(S5P_CEC_IRQ_RX_DONE | S5P_CEC_IRQ_RX_ERROR,
-	       cec->reg + S5P_CEC_IRQ_CLEAR);
-}
-
-void s5p_cec_get_rx_buf(struct s5p_cec_dev *cec, u32 size, u8 *buffer)
-{
-	u32 i = 0;
-	char debug[40];
-
-	while (i < size) {
-		buffer[i] = readb(cec->reg + S5P_CEC_RX_BUFF0 + (i * 4));
-		sprintf(debug + i * 2, "%02x ", buffer[i]);
-		i++;
-	}
-	dev_dbg(cec->dev, "cec-rx: cec size(%d): %s", size, debug);
-}
diff --git a/drivers/media/platform/s5p-cec/regs-cec.h b/drivers/media/platform/s5p-cec/regs-cec.h
deleted file mode 100644
index 447f717028a2..000000000000
--- a/drivers/media/platform/s5p-cec/regs-cec.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/* drivers/media/platform/s5p-cec/regs-cec.h
- *
- * Copyright (c) 2010 Samsung Electronics
- *		http://www.samsung.com/
- *
- *  register header file for Samsung TVOUT driver
- */
-
-#ifndef __EXYNOS_REGS__H
-#define __EXYNOS_REGS__H
-
-/*
- * Register part
- */
-#define S5P_CEC_STATUS_0			(0x0000)
-#define S5P_CEC_STATUS_1			(0x0004)
-#define S5P_CEC_STATUS_2			(0x0008)
-#define S5P_CEC_STATUS_3			(0x000C)
-#define S5P_CEC_IRQ_MASK			(0x0010)
-#define S5P_CEC_IRQ_CLEAR			(0x0014)
-#define S5P_CEC_LOGIC_ADDR			(0x0020)
-#define S5P_CEC_DIVISOR_0			(0x0030)
-#define S5P_CEC_DIVISOR_1			(0x0034)
-#define S5P_CEC_DIVISOR_2			(0x0038)
-#define S5P_CEC_DIVISOR_3			(0x003C)
-
-#define S5P_CEC_TX_CTRL				(0x0040)
-#define S5P_CEC_TX_BYTES			(0x0044)
-#define S5P_CEC_TX_STAT0			(0x0060)
-#define S5P_CEC_TX_STAT1			(0x0064)
-#define S5P_CEC_TX_BUFF0			(0x0080)
-#define S5P_CEC_TX_BUFF1			(0x0084)
-#define S5P_CEC_TX_BUFF2			(0x0088)
-#define S5P_CEC_TX_BUFF3			(0x008C)
-#define S5P_CEC_TX_BUFF4			(0x0090)
-#define S5P_CEC_TX_BUFF5			(0x0094)
-#define S5P_CEC_TX_BUFF6			(0x0098)
-#define S5P_CEC_TX_BUFF7			(0x009C)
-#define S5P_CEC_TX_BUFF8			(0x00A0)
-#define S5P_CEC_TX_BUFF9			(0x00A4)
-#define S5P_CEC_TX_BUFF10			(0x00A8)
-#define S5P_CEC_TX_BUFF11			(0x00AC)
-#define S5P_CEC_TX_BUFF12			(0x00B0)
-#define S5P_CEC_TX_BUFF13			(0x00B4)
-#define S5P_CEC_TX_BUFF14			(0x00B8)
-#define S5P_CEC_TX_BUFF15			(0x00BC)
-
-#define S5P_CEC_RX_CTRL				(0x00C0)
-#define S5P_CEC_RX_STAT0			(0x00E0)
-#define S5P_CEC_RX_STAT1			(0x00E4)
-#define S5P_CEC_RX_BUFF0			(0x0100)
-#define S5P_CEC_RX_BUFF1			(0x0104)
-#define S5P_CEC_RX_BUFF2			(0x0108)
-#define S5P_CEC_RX_BUFF3			(0x010C)
-#define S5P_CEC_RX_BUFF4			(0x0110)
-#define S5P_CEC_RX_BUFF5			(0x0114)
-#define S5P_CEC_RX_BUFF6			(0x0118)
-#define S5P_CEC_RX_BUFF7			(0x011C)
-#define S5P_CEC_RX_BUFF8			(0x0120)
-#define S5P_CEC_RX_BUFF9			(0x0124)
-#define S5P_CEC_RX_BUFF10			(0x0128)
-#define S5P_CEC_RX_BUFF11			(0x012C)
-#define S5P_CEC_RX_BUFF12			(0x0130)
-#define S5P_CEC_RX_BUFF13			(0x0134)
-#define S5P_CEC_RX_BUFF14			(0x0138)
-#define S5P_CEC_RX_BUFF15			(0x013C)
-
-#define S5P_CEC_RX_FILTER_CTRL			(0x0180)
-#define S5P_CEC_RX_FILTER_TH			(0x0184)
-
-/*
- * Bit definition part
- */
-#define S5P_CEC_IRQ_TX_DONE			(1<<0)
-#define S5P_CEC_IRQ_TX_ERROR			(1<<1)
-#define S5P_CEC_IRQ_RX_DONE			(1<<4)
-#define S5P_CEC_IRQ_RX_ERROR			(1<<5)
-
-#define S5P_CEC_TX_CTRL_START			(1<<0)
-#define S5P_CEC_TX_CTRL_BCAST			(1<<1)
-#define S5P_CEC_TX_CTRL_RETRY			(0x04<<4)
-#define S5P_CEC_TX_CTRL_RESET			(1<<7)
-
-#define S5P_CEC_RX_CTRL_ENABLE			(1<<0)
-#define S5P_CEC_RX_CTRL_RESET			(1<<7)
-
-#define S5P_CEC_LOGIC_ADDR_MASK			(0xF)
-
-/* PMU Registers for PHY */
-#define EXYNOS_HDMI_PHY_CONTROL			0x700
-
-#endif	/* __EXYNOS_REGS__H	*/
diff --git a/drivers/media/platform/s5p-cec/s5p_cec.c b/drivers/media/platform/s5p-cec/s5p_cec.c
deleted file mode 100644
index 2a3e7ffefe0a..000000000000
--- a/drivers/media/platform/s5p-cec/s5p_cec.c
+++ /dev/null
@@ -1,307 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/* drivers/media/platform/s5p-cec/s5p_cec.c
- *
- * Samsung S5P CEC driver
- *
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * This driver is based on the "cec interface driver for exynos soc" by
- * SangPil Moon.
- */
-
-#include <linux/clk.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/mfd/syscon.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/of_platform.h>
-#include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
-#include <linux/timer.h>
-#include <linux/workqueue.h>
-#include <media/cec.h>
-#include <media/cec-notifier.h>
-
-#include "exynos_hdmi_cec.h"
-#include "regs-cec.h"
-#include "s5p_cec.h"
-
-#define CEC_NAME	"s5p-cec"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "debug level (0-2)");
-
-static int s5p_cec_adap_enable(struct cec_adapter *adap, bool enable)
-{
-	struct s5p_cec_dev *cec = cec_get_drvdata(adap);
-
-	if (enable) {
-		pm_runtime_get_sync(cec->dev);
-
-		s5p_cec_reset(cec);
-
-		s5p_cec_set_divider(cec);
-		s5p_cec_threshold(cec);
-
-		s5p_cec_unmask_tx_interrupts(cec);
-		s5p_cec_unmask_rx_interrupts(cec);
-		s5p_cec_enable_rx(cec);
-	} else {
-		s5p_cec_mask_tx_interrupts(cec);
-		s5p_cec_mask_rx_interrupts(cec);
-		pm_runtime_disable(cec->dev);
-	}
-
-	return 0;
-}
-
-static int s5p_cec_adap_log_addr(struct cec_adapter *adap, u8 addr)
-{
-	struct s5p_cec_dev *cec = cec_get_drvdata(adap);
-
-	s5p_cec_set_addr(cec, addr);
-	return 0;
-}
-
-static int s5p_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
-				 u32 signal_free_time, struct cec_msg *msg)
-{
-	struct s5p_cec_dev *cec = cec_get_drvdata(adap);
-
-	/*
-	 * Unclear if 0 retries are allowed by the hardware, so have 1 as
-	 * the minimum.
-	 */
-	s5p_cec_copy_packet(cec, msg->msg, msg->len, max(1, attempts - 1));
-	return 0;
-}
-
-static irqreturn_t s5p_cec_irq_handler(int irq, void *priv)
-{
-	struct s5p_cec_dev *cec = priv;
-	u32 status = 0;
-
-	status = s5p_cec_get_status(cec);
-
-	dev_dbg(cec->dev, "irq received\n");
-
-	if (status & CEC_STATUS_TX_DONE) {
-		if (status & CEC_STATUS_TX_NACK) {
-			dev_dbg(cec->dev, "CEC_STATUS_TX_NACK set\n");
-			cec->tx = STATE_NACK;
-		} else if (status & CEC_STATUS_TX_ERROR) {
-			dev_dbg(cec->dev, "CEC_STATUS_TX_ERROR set\n");
-			cec->tx = STATE_ERROR;
-		} else {
-			dev_dbg(cec->dev, "CEC_STATUS_TX_DONE\n");
-			cec->tx = STATE_DONE;
-		}
-		s5p_clr_pending_tx(cec);
-	}
-
-	if (status & CEC_STATUS_RX_DONE) {
-		if (status & CEC_STATUS_RX_ERROR) {
-			dev_dbg(cec->dev, "CEC_STATUS_RX_ERROR set\n");
-			s5p_cec_rx_reset(cec);
-			s5p_cec_enable_rx(cec);
-		} else {
-			dev_dbg(cec->dev, "CEC_STATUS_RX_DONE set\n");
-			if (cec->rx != STATE_IDLE)
-				dev_dbg(cec->dev, "Buffer overrun (worker did not process previous message)\n");
-			cec->rx = STATE_BUSY;
-			cec->msg.len = status >> 24;
-			cec->msg.rx_status = CEC_RX_STATUS_OK;
-			s5p_cec_get_rx_buf(cec, cec->msg.len,
-					cec->msg.msg);
-			cec->rx = STATE_DONE;
-			s5p_cec_enable_rx(cec);
-		}
-		/* Clear interrupt pending bit */
-		s5p_clr_pending_rx(cec);
-	}
-	return IRQ_WAKE_THREAD;
-}
-
-static irqreturn_t s5p_cec_irq_handler_thread(int irq, void *priv)
-{
-	struct s5p_cec_dev *cec = priv;
-
-	dev_dbg(cec->dev, "irq processing thread\n");
-	switch (cec->tx) {
-	case STATE_DONE:
-		cec_transmit_done(cec->adap, CEC_TX_STATUS_OK, 0, 0, 0, 0);
-		cec->tx = STATE_IDLE;
-		break;
-	case STATE_NACK:
-		cec_transmit_done(cec->adap,
-			CEC_TX_STATUS_MAX_RETRIES | CEC_TX_STATUS_NACK,
-			0, 1, 0, 0);
-		cec->tx = STATE_IDLE;
-		break;
-	case STATE_ERROR:
-		cec_transmit_done(cec->adap,
-			CEC_TX_STATUS_MAX_RETRIES | CEC_TX_STATUS_ERROR,
-			0, 0, 0, 1);
-		cec->tx = STATE_IDLE;
-		break;
-	case STATE_BUSY:
-		dev_err(cec->dev, "state set to busy, this should not occur here\n");
-		break;
-	default:
-		break;
-	}
-
-	switch (cec->rx) {
-	case STATE_DONE:
-		cec_received_msg(cec->adap, &cec->msg);
-		cec->rx = STATE_IDLE;
-		break;
-	default:
-		break;
-	}
-
-	return IRQ_HANDLED;
-}
-
-static const struct cec_adap_ops s5p_cec_adap_ops = {
-	.adap_enable = s5p_cec_adap_enable,
-	.adap_log_addr = s5p_cec_adap_log_addr,
-	.adap_transmit = s5p_cec_adap_transmit,
-};
-
-static int s5p_cec_probe(struct platform_device *pdev)
-{
-	struct device *dev = &pdev->dev;
-	struct device *hdmi_dev;
-	struct resource *res;
-	struct s5p_cec_dev *cec;
-	bool needs_hpd = of_property_read_bool(pdev->dev.of_node, "needs-hpd");
-	int ret;
-
-	hdmi_dev = cec_notifier_parse_hdmi_phandle(dev);
-
-	if (IS_ERR(hdmi_dev))
-		return PTR_ERR(hdmi_dev);
-
-	cec = devm_kzalloc(&pdev->dev, sizeof(*cec), GFP_KERNEL);
-	if (!cec)
-		return -ENOMEM;
-
-	cec->dev = dev;
-
-	cec->irq = platform_get_irq(pdev, 0);
-	if (cec->irq < 0)
-		return cec->irq;
-
-	ret = devm_request_threaded_irq(dev, cec->irq, s5p_cec_irq_handler,
-		s5p_cec_irq_handler_thread, 0, pdev->name, cec);
-	if (ret)
-		return ret;
-
-	cec->clk = devm_clk_get(dev, "hdmicec");
-	if (IS_ERR(cec->clk))
-		return PTR_ERR(cec->clk);
-
-	cec->pmu = syscon_regmap_lookup_by_phandle(dev->of_node,
-						 "samsung,syscon-phandle");
-	if (IS_ERR(cec->pmu))
-		return -EPROBE_DEFER;
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	cec->reg = devm_ioremap_resource(dev, res);
-	if (IS_ERR(cec->reg))
-		return PTR_ERR(cec->reg);
-
-	cec->adap = cec_allocate_adapter(&s5p_cec_adap_ops, cec, CEC_NAME,
-		CEC_CAP_DEFAULTS | (needs_hpd ? CEC_CAP_NEEDS_HPD : 0) |
-		CEC_CAP_CONNECTOR_INFO, 1);
-	ret = PTR_ERR_OR_ZERO(cec->adap);
-	if (ret)
-		return ret;
-
-	cec->notifier = cec_notifier_cec_adap_register(hdmi_dev, NULL,
-						       cec->adap);
-	if (!cec->notifier) {
-		ret = -ENOMEM;
-		goto err_delete_adapter;
-	}
-
-	ret = cec_register_adapter(cec->adap, &pdev->dev);
-	if (ret)
-		goto err_notifier;
-
-	platform_set_drvdata(pdev, cec);
-	pm_runtime_enable(dev);
-
-	dev_dbg(dev, "successfully probed\n");
-	return 0;
-
-err_notifier:
-	cec_notifier_cec_adap_unregister(cec->notifier, cec->adap);
-
-err_delete_adapter:
-	cec_delete_adapter(cec->adap);
-	return ret;
-}
-
-static int s5p_cec_remove(struct platform_device *pdev)
-{
-	struct s5p_cec_dev *cec = platform_get_drvdata(pdev);
-
-	cec_notifier_cec_adap_unregister(cec->notifier, cec->adap);
-	cec_unregister_adapter(cec->adap);
-	pm_runtime_disable(&pdev->dev);
-	return 0;
-}
-
-static int __maybe_unused s5p_cec_runtime_suspend(struct device *dev)
-{
-	struct s5p_cec_dev *cec = dev_get_drvdata(dev);
-
-	clk_disable_unprepare(cec->clk);
-	return 0;
-}
-
-static int __maybe_unused s5p_cec_runtime_resume(struct device *dev)
-{
-	struct s5p_cec_dev *cec = dev_get_drvdata(dev);
-	int ret;
-
-	ret = clk_prepare_enable(cec->clk);
-	if (ret < 0)
-		return ret;
-	return 0;
-}
-
-static const struct dev_pm_ops s5p_cec_pm_ops = {
-	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
-				pm_runtime_force_resume)
-	SET_RUNTIME_PM_OPS(s5p_cec_runtime_suspend, s5p_cec_runtime_resume,
-			   NULL)
-};
-
-static const struct of_device_id s5p_cec_match[] = {
-	{
-		.compatible	= "samsung,s5p-cec",
-	},
-	{},
-};
-MODULE_DEVICE_TABLE(of, s5p_cec_match);
-
-static struct platform_driver s5p_cec_pdrv = {
-	.probe	= s5p_cec_probe,
-	.remove	= s5p_cec_remove,
-	.driver	= {
-		.name		= CEC_NAME,
-		.of_match_table	= s5p_cec_match,
-		.pm		= &s5p_cec_pm_ops,
-	},
-};
-
-module_platform_driver(s5p_cec_pdrv);
-
-MODULE_AUTHOR("Kamil Debski <kamil@wypas.org>");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Samsung S5P CEC driver");
diff --git a/drivers/media/platform/s5p-cec/s5p_cec.h b/drivers/media/platform/s5p-cec/s5p_cec.h
deleted file mode 100644
index 34d033b20f96..000000000000
--- a/drivers/media/platform/s5p-cec/s5p_cec.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/* drivers/media/platform/s5p-cec/s5p_cec.h
- *
- * Samsung S5P HDMI CEC driver
- *
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- */
-
-#ifndef _S5P_CEC_H_
-#define _S5P_CEC_H_ __FILE__
-
-#include <linux/clk.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/mfd/syscon.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
-#include <linux/timer.h>
-#include <linux/workqueue.h>
-#include <media/cec.h>
-
-#include "exynos_hdmi_cec.h"
-#include "regs-cec.h"
-#include "s5p_cec.h"
-
-#define CEC_NAME	"s5p-cec"
-
-#define CEC_STATUS_TX_RUNNING		(1 << 0)
-#define CEC_STATUS_TX_TRANSFERRING	(1 << 1)
-#define CEC_STATUS_TX_DONE		(1 << 2)
-#define CEC_STATUS_TX_ERROR		(1 << 3)
-#define CEC_STATUS_TX_NACK		(1 << 4)
-#define CEC_STATUS_TX_BYTES		(0xFF << 8)
-#define CEC_STATUS_RX_RUNNING		(1 << 16)
-#define CEC_STATUS_RX_RECEIVING		(1 << 17)
-#define CEC_STATUS_RX_DONE		(1 << 18)
-#define CEC_STATUS_RX_ERROR		(1 << 19)
-#define CEC_STATUS_RX_BCAST		(1 << 20)
-#define CEC_STATUS_RX_BYTES		(0xFF << 24)
-
-#define CEC_WORKER_TX_DONE		(1 << 0)
-#define CEC_WORKER_RX_MSG		(1 << 1)
-
-/* CEC Rx buffer size */
-#define CEC_RX_BUFF_SIZE		16
-/* CEC Tx buffer size */
-#define CEC_TX_BUFF_SIZE		16
-
-enum cec_state {
-	STATE_IDLE,
-	STATE_BUSY,
-	STATE_DONE,
-	STATE_NACK,
-	STATE_ERROR
-};
-
-struct cec_notifier;
-
-struct s5p_cec_dev {
-	struct cec_adapter	*adap;
-	struct clk		*clk;
-	struct device		*dev;
-	struct mutex		lock;
-	struct regmap           *pmu;
-	struct cec_notifier	*notifier;
-	int			irq;
-	void __iomem		*reg;
-
-	enum cec_state		rx;
-	enum cec_state		tx;
-	struct cec_msg		msg;
-};
-
-#endif /* _S5P_CEC_H_ */
diff --git a/drivers/media/platform/seco-cec/Makefile b/drivers/media/platform/seco-cec/Makefile
deleted file mode 100644
index 79fde6947ff2..000000000000
--- a/drivers/media/platform/seco-cec/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_VIDEO_SECO_CEC) += seco-cec.o
diff --git a/drivers/media/platform/seco-cec/seco-cec.c b/drivers/media/platform/seco-cec/seco-cec.c
deleted file mode 100644
index 2ff62a488b27..000000000000
--- a/drivers/media/platform/seco-cec/seco-cec.c
+++ /dev/null
@@ -1,803 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
-/*
- * CEC driver for SECO X86 Boards
- *
- * Author:  Ettore Chimenti <ek5.chimenti@gmail.com>
- * Copyright (C) 2018, SECO SpA.
- * Copyright (C) 2018, Aidilab Srl.
- */
-
-#include <linux/module.h>
-#include <linux/acpi.h>
-#include <linux/delay.h>
-#include <linux/dmi.h>
-#include <linux/gpio/consumer.h>
-#include <linux/gpio.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/platform_device.h>
-
-/* CEC Framework */
-#include <media/cec-notifier.h>
-
-#include "seco-cec.h"
-
-struct secocec_data {
-	struct device *dev;
-	struct platform_device *pdev;
-	struct cec_adapter *cec_adap;
-	struct cec_notifier *notifier;
-	struct rc_dev *ir;
-	char ir_input_phys[32];
-	int irq;
-};
-
-#define smb_wr16(cmd, data) smb_word_op(CMD_WORD_DATA, SECOCEC_MICRO_ADDRESS, \
-					     cmd, data, SMBUS_WRITE, NULL)
-#define smb_rd16(cmd, res) smb_word_op(CMD_WORD_DATA, SECOCEC_MICRO_ADDRESS, \
-				       cmd, 0, SMBUS_READ, res)
-
-static int smb_word_op(short data_format, u16 slave_addr, u8 cmd, u16 data,
-		       u8 operation, u16 *result)
-{
-	unsigned int count;
-	short _data_format;
-	int status = 0;
-
-	switch (data_format) {
-	case CMD_BYTE_DATA:
-		_data_format = BRA_SMB_CMD_BYTE_DATA;
-		break;
-	case CMD_WORD_DATA:
-		_data_format = BRA_SMB_CMD_WORD_DATA;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	/* Active wait until ready */
-	for (count = 0; count <= SMBTIMEOUT; ++count) {
-		if (!(inb(HSTS) & BRA_INUSE_STS))
-			break;
-		udelay(SMB_POLL_UDELAY);
-	}
-
-	if (count > SMBTIMEOUT)
-		/* Reset the lock instead of failing */
-		outb(0xff, HSTS);
-
-	outb(0x00, HCNT);
-	outb((u8)(slave_addr & 0xfe) | operation, XMIT_SLVA);
-	outb(cmd, HCMD);
-	inb(HCNT);
-
-	if (operation == SMBUS_WRITE) {
-		outb((u8)data, HDAT0);
-		outb((u8)(data >> 8), HDAT1);
-	}
-
-	outb(BRA_START + _data_format, HCNT);
-
-	for (count = 0; count <= SMBTIMEOUT; count++) {
-		if (!(inb(HSTS) & BRA_HOST_BUSY))
-			break;
-		udelay(SMB_POLL_UDELAY);
-	}
-
-	if (count > SMBTIMEOUT) {
-		status = -EBUSY;
-		goto err;
-	}
-
-	if (inb(HSTS) & BRA_HSTS_ERR_MASK) {
-		status = -EIO;
-		goto err;
-	}
-
-	if (operation == SMBUS_READ)
-		*result = ((inb(HDAT0) & 0xff) + ((inb(HDAT1) & 0xff) << 8));
-
-err:
-	outb(0xff, HSTS);
-	return status;
-}
-
-static int secocec_adap_enable(struct cec_adapter *adap, bool enable)
-{
-	struct secocec_data *cec = cec_get_drvdata(adap);
-	struct device *dev = cec->dev;
-	u16 val = 0;
-	int status;
-
-	if (enable) {
-		/* Clear the status register */
-		status = smb_rd16(SECOCEC_STATUS_REG_1, &val);
-		if (status)
-			goto err;
-
-		status = smb_wr16(SECOCEC_STATUS_REG_1, val);
-		if (status)
-			goto err;
-
-		/* Enable the interrupts */
-		status = smb_rd16(SECOCEC_ENABLE_REG_1, &val);
-		if (status)
-			goto err;
-
-		status = smb_wr16(SECOCEC_ENABLE_REG_1,
-				  val | SECOCEC_ENABLE_REG_1_CEC);
-		if (status)
-			goto err;
-
-		dev_dbg(dev, "Device enabled");
-	} else {
-		/* Clear the status register */
-		status = smb_rd16(SECOCEC_STATUS_REG_1, &val);
-		status = smb_wr16(SECOCEC_STATUS_REG_1, val);
-
-		/* Disable the interrupts */
-		status = smb_rd16(SECOCEC_ENABLE_REG_1, &val);
-		status = smb_wr16(SECOCEC_ENABLE_REG_1, val &
-				  ~SECOCEC_ENABLE_REG_1_CEC &
-				  ~SECOCEC_ENABLE_REG_1_IR);
-
-		dev_dbg(dev, "Device disabled");
-	}
-
-	return 0;
-err:
-	return status;
-}
-
-static int secocec_adap_log_addr(struct cec_adapter *adap, u8 logical_addr)
-{
-	u16 enable_val = 0;
-	int status;
-
-	/* Disable device */
-	status = smb_rd16(SECOCEC_ENABLE_REG_1, &enable_val);
-	if (status)
-		return status;
-
-	status = smb_wr16(SECOCEC_ENABLE_REG_1,
-			  enable_val & ~SECOCEC_ENABLE_REG_1_CEC);
-	if (status)
-		return status;
-
-	/* Write logical address
-	 * NOTE: CEC_LOG_ADDR_INVALID is mapped to the 'Unregistered' LA
-	 */
-	status = smb_wr16(SECOCEC_DEVICE_LA, logical_addr & 0xf);
-	if (status)
-		return status;
-
-	/* Re-enable device */
-	status = smb_wr16(SECOCEC_ENABLE_REG_1,
-			  enable_val | SECOCEC_ENABLE_REG_1_CEC);
-	if (status)
-		return status;
-
-	return 0;
-}
-
-static int secocec_adap_transmit(struct cec_adapter *adap, u8 attempts,
-				 u32 signal_free_time, struct cec_msg *msg)
-{
-	u16 payload_len, payload_id_len, destination, val = 0;
-	u8 *payload_msg;
-	int status;
-	u8 i;
-
-	/* Device msg len already accounts for header */
-	payload_id_len = msg->len - 1;
-
-	/* Send data length */
-	status = smb_wr16(SECOCEC_WRITE_DATA_LENGTH, payload_id_len);
-	if (status)
-		goto err;
-
-	/* Send Operation ID if present */
-	if (payload_id_len > 0) {
-		status = smb_wr16(SECOCEC_WRITE_OPERATION_ID, msg->msg[1]);
-		if (status)
-			goto err;
-	}
-	/* Send data if present */
-	if (payload_id_len > 1) {
-		/* Only data; */
-		payload_len = msg->len - 2;
-		payload_msg = &msg->msg[2];
-
-		/* Copy message into registers */
-		for (i = 0; i < payload_len; i += 2) {
-			/* hi byte */
-			val = payload_msg[i + 1] << 8;
-
-			/* lo byte */
-			val |= payload_msg[i];
-
-			status = smb_wr16(SECOCEC_WRITE_DATA_00 + i / 2, val);
-			if (status)
-				goto err;
-		}
-	}
-	/* Send msg source/destination and fire msg */
-	destination = msg->msg[0];
-	status = smb_wr16(SECOCEC_WRITE_BYTE0, destination);
-	if (status)
-		goto err;
-
-	return 0;
-
-err:
-	return status;
-}
-
-static void secocec_tx_done(struct cec_adapter *adap, u16 status_val)
-{
-	if (status_val & SECOCEC_STATUS_TX_ERROR_MASK) {
-		if (status_val & SECOCEC_STATUS_TX_NACK_ERROR)
-			cec_transmit_attempt_done(adap, CEC_TX_STATUS_NACK);
-		else
-			cec_transmit_attempt_done(adap, CEC_TX_STATUS_ERROR);
-	} else {
-		cec_transmit_attempt_done(adap, CEC_TX_STATUS_OK);
-	}
-
-	/* Reset status reg */
-	status_val = SECOCEC_STATUS_TX_ERROR_MASK |
-		SECOCEC_STATUS_MSG_SENT_MASK |
-		SECOCEC_STATUS_TX_NACK_ERROR;
-	smb_wr16(SECOCEC_STATUS, status_val);
-}
-
-static void secocec_rx_done(struct cec_adapter *adap, u16 status_val)
-{
-	struct secocec_data *cec = cec_get_drvdata(adap);
-	struct device *dev = cec->dev;
-	struct cec_msg msg = { };
-	bool flag_overflow = false;
-	u8 payload_len, i = 0;
-	u8 *payload_msg;
-	u16 val = 0;
-	int status;
-
-	if (status_val & SECOCEC_STATUS_RX_OVERFLOW_MASK) {
-		/* NOTE: Untested, it also might not be necessary */
-		dev_warn(dev, "Received more than 16 bytes. Discarding");
-		flag_overflow = true;
-	}
-
-	if (status_val & SECOCEC_STATUS_RX_ERROR_MASK) {
-		dev_warn(dev, "Message received with errors. Discarding");
-		status = -EIO;
-		goto rxerr;
-	}
-
-	/* Read message length */
-	status = smb_rd16(SECOCEC_READ_DATA_LENGTH, &val);
-	if (status)
-		return;
-
-	/* Device msg len already accounts for the header */
-	msg.len = min(val + 1, CEC_MAX_MSG_SIZE);
-
-	/* Read logical address */
-	status = smb_rd16(SECOCEC_READ_BYTE0, &val);
-	if (status)
-		return;
-
-	/* device stores source LA and destination */
-	msg.msg[0] = val;
-
-	/* Read operation ID */
-	status = smb_rd16(SECOCEC_READ_OPERATION_ID, &val);
-	if (status)
-		return;
-
-	msg.msg[1] = val;
-
-	/* Read data if present */
-	if (msg.len > 1) {
-		payload_len = msg.len - 2;
-		payload_msg = &msg.msg[2];
-
-		/* device stores 2 bytes in every 16-bit val */
-		for (i = 0; i < payload_len; i += 2) {
-			status = smb_rd16(SECOCEC_READ_DATA_00 + i / 2, &val);
-			if (status)
-				return;
-
-			/* low byte, skipping header */
-			payload_msg[i] = val & 0x00ff;
-
-			/* hi byte */
-			payload_msg[i + 1] = (val & 0xff00) >> 8;
-		}
-	}
-
-	cec_received_msg(cec->cec_adap, &msg);
-
-	/* Reset status reg */
-	status_val = SECOCEC_STATUS_MSG_RECEIVED_MASK;
-	if (flag_overflow)
-		status_val |= SECOCEC_STATUS_RX_OVERFLOW_MASK;
-
-	status = smb_wr16(SECOCEC_STATUS, status_val);
-
-	return;
-
-rxerr:
-	/* Reset error reg */
-	status_val = SECOCEC_STATUS_MSG_RECEIVED_MASK |
-		SECOCEC_STATUS_RX_ERROR_MASK;
-	if (flag_overflow)
-		status_val |= SECOCEC_STATUS_RX_OVERFLOW_MASK;
-	smb_wr16(SECOCEC_STATUS, status_val);
-}
-
-static const struct cec_adap_ops secocec_cec_adap_ops = {
-	/* Low-level callbacks */
-	.adap_enable = secocec_adap_enable,
-	.adap_log_addr = secocec_adap_log_addr,
-	.adap_transmit = secocec_adap_transmit,
-};
-
-#ifdef CONFIG_VIDEO_SECO_RC
-static int secocec_ir_probe(void *priv)
-{
-	struct secocec_data *cec = priv;
-	struct device *dev = cec->dev;
-	int status;
-	u16 val;
-
-	/* Prepare the RC input device */
-	cec->ir = devm_rc_allocate_device(dev, RC_DRIVER_SCANCODE);
-	if (!cec->ir)
-		return -ENOMEM;
-
-	snprintf(cec->ir_input_phys, sizeof(cec->ir_input_phys),
-		 "%s/input0", dev_name(dev));
-
-	cec->ir->device_name = dev_name(dev);
-	cec->ir->input_phys = cec->ir_input_phys;
-	cec->ir->input_id.bustype = BUS_HOST;
-	cec->ir->input_id.vendor = 0;
-	cec->ir->input_id.product = 0;
-	cec->ir->input_id.version = 1;
-	cec->ir->driver_name = SECOCEC_DEV_NAME;
-	cec->ir->allowed_protocols = RC_PROTO_BIT_RC5;
-	cec->ir->priv = cec;
-	cec->ir->map_name = RC_MAP_HAUPPAUGE;
-	cec->ir->timeout = MS_TO_NS(100);
-
-	/* Clear the status register */
-	status = smb_rd16(SECOCEC_STATUS_REG_1, &val);
-	if (status != 0)
-		goto err;
-
-	status = smb_wr16(SECOCEC_STATUS_REG_1, val);
-	if (status != 0)
-		goto err;
-
-	/* Enable the interrupts */
-	status = smb_rd16(SECOCEC_ENABLE_REG_1, &val);
-	if (status != 0)
-		goto err;
-
-	status = smb_wr16(SECOCEC_ENABLE_REG_1,
-			  val | SECOCEC_ENABLE_REG_1_IR);
-	if (status != 0)
-		goto err;
-
-	dev_dbg(dev, "IR enabled");
-
-	status = devm_rc_register_device(dev, cec->ir);
-
-	if (status) {
-		dev_err(dev, "Failed to prepare input device");
-		cec->ir = NULL;
-		goto err;
-	}
-
-	return 0;
-
-err:
-	smb_rd16(SECOCEC_ENABLE_REG_1, &val);
-
-	smb_wr16(SECOCEC_ENABLE_REG_1,
-		 val & ~SECOCEC_ENABLE_REG_1_IR);
-
-	dev_dbg(dev, "IR disabled");
-	return status;
-}
-
-static int secocec_ir_rx(struct secocec_data *priv)
-{
-	struct secocec_data *cec = priv;
-	struct device *dev = cec->dev;
-	u16 val, status, key, addr, toggle;
-
-	if (!cec->ir)
-		return -ENODEV;
-
-	status = smb_rd16(SECOCEC_IR_READ_DATA, &val);
-	if (status != 0)
-		goto err;
-
-	key = val & SECOCEC_IR_COMMAND_MASK;
-	addr = (val & SECOCEC_IR_ADDRESS_MASK) >> SECOCEC_IR_ADDRESS_SHL;
-	toggle = (val & SECOCEC_IR_TOGGLE_MASK) >> SECOCEC_IR_TOGGLE_SHL;
-
-	rc_keydown(cec->ir, RC_PROTO_RC5, RC_SCANCODE_RC5(addr, key), toggle);
-
-	dev_dbg(dev, "IR key pressed: 0x%02x addr 0x%02x toggle 0x%02x", key,
-		addr, toggle);
-
-	return 0;
-
-err:
-	dev_err(dev, "IR Receive message failed (%d)", status);
-	return -EIO;
-}
-#else
-static void secocec_ir_rx(struct secocec_data *priv)
-{
-}
-
-static int secocec_ir_probe(void *priv)
-{
-	return 0;
-}
-#endif
-
-static irqreturn_t secocec_irq_handler(int irq, void *priv)
-{
-	struct secocec_data *cec = priv;
-	struct device *dev = cec->dev;
-	u16 status_val, cec_val, val = 0;
-	int status;
-
-	/*  Read status register */
-	status = smb_rd16(SECOCEC_STATUS_REG_1, &status_val);
-	if (status)
-		goto err;
-
-	if (status_val & SECOCEC_STATUS_REG_1_CEC) {
-		/* Read CEC status register */
-		status = smb_rd16(SECOCEC_STATUS, &cec_val);
-		if (status)
-			goto err;
-
-		if (cec_val & SECOCEC_STATUS_MSG_RECEIVED_MASK)
-			secocec_rx_done(cec->cec_adap, cec_val);
-
-		if (cec_val & SECOCEC_STATUS_MSG_SENT_MASK)
-			secocec_tx_done(cec->cec_adap, cec_val);
-
-		if ((~cec_val & SECOCEC_STATUS_MSG_SENT_MASK) &&
-		    (~cec_val & SECOCEC_STATUS_MSG_RECEIVED_MASK))
-			dev_warn_once(dev,
-				      "Message not received or sent, but interrupt fired");
-
-		val = SECOCEC_STATUS_REG_1_CEC;
-	}
-
-	if (status_val & SECOCEC_STATUS_REG_1_IR) {
-		val |= SECOCEC_STATUS_REG_1_IR;
-
-		secocec_ir_rx(cec);
-	}
-
-	/*  Reset status register */
-	status = smb_wr16(SECOCEC_STATUS_REG_1, val);
-	if (status)
-		goto err;
-
-	return IRQ_HANDLED;
-
-err:
-	dev_err_once(dev, "IRQ: R/W SMBus operation failed (%d)", status);
-
-	/*  Reset status register */
-	val = SECOCEC_STATUS_REG_1_CEC | SECOCEC_STATUS_REG_1_IR;
-	smb_wr16(SECOCEC_STATUS_REG_1, val);
-
-	return IRQ_HANDLED;
-}
-
-struct cec_dmi_match {
-	const char *sys_vendor;
-	const char *product_name;
-	const char *devname;
-	const char *conn;
-};
-
-static const struct cec_dmi_match secocec_dmi_match_table[] = {
-	/* UDOO X86 */
-	{ "SECO", "UDOO x86", "0000:00:02.0", "Port B" },
-};
-
-static struct device *secocec_cec_find_hdmi_dev(struct device *dev,
-						const char **conn)
-{
-	int i;
-
-	for (i = 0 ; i < ARRAY_SIZE(secocec_dmi_match_table) ; ++i) {
-		const struct cec_dmi_match *m = &secocec_dmi_match_table[i];
-
-		if (dmi_match(DMI_SYS_VENDOR, m->sys_vendor) &&
-		    dmi_match(DMI_PRODUCT_NAME, m->product_name)) {
-			struct device *d;
-
-			/* Find the device, bail out if not yet registered */
-			d = bus_find_device_by_name(&pci_bus_type, NULL,
-						    m->devname);
-			if (!d)
-				return ERR_PTR(-EPROBE_DEFER);
-
-			put_device(d);
-			*conn = m->conn;
-			return d;
-		}
-	}
-
-	return ERR_PTR(-EINVAL);
-}
-
-static int secocec_acpi_probe(struct secocec_data *sdev)
-{
-	struct device *dev = sdev->dev;
-	struct gpio_desc *gpio;
-	int irq = 0;
-
-	gpio = devm_gpiod_get(dev, NULL, GPIOF_IN);
-	if (IS_ERR(gpio)) {
-		dev_err(dev, "Cannot request interrupt gpio");
-		return PTR_ERR(gpio);
-	}
-
-	irq = gpiod_to_irq(gpio);
-	if (irq < 0) {
-		dev_err(dev, "Cannot find valid irq");
-		return -ENODEV;
-	}
-	dev_dbg(dev, "irq-gpio is bound to IRQ %d", irq);
-
-	sdev->irq = irq;
-
-	return 0;
-}
-
-static int secocec_probe(struct platform_device *pdev)
-{
-	struct secocec_data *secocec;
-	struct device *dev = &pdev->dev;
-	struct device *hdmi_dev;
-	const char *conn = NULL;
-	int ret;
-	u16 val;
-
-	hdmi_dev = secocec_cec_find_hdmi_dev(&pdev->dev, &conn);
-	if (IS_ERR(hdmi_dev))
-		return PTR_ERR(hdmi_dev);
-
-	secocec = devm_kzalloc(dev, sizeof(*secocec), GFP_KERNEL);
-	if (!secocec)
-		return -ENOMEM;
-
-	dev_set_drvdata(dev, secocec);
-
-	/* Request SMBus regions */
-	if (!request_muxed_region(BRA_SMB_BASE_ADDR, 7, "CEC00001")) {
-		dev_err(dev, "Request memory region failed");
-		return -ENXIO;
-	}
-
-	secocec->pdev = pdev;
-	secocec->dev = dev;
-
-	if (!has_acpi_companion(dev)) {
-		dev_dbg(dev, "Cannot find any ACPI companion");
-		ret = -ENODEV;
-		goto err;
-	}
-
-	ret = secocec_acpi_probe(secocec);
-	if (ret) {
-		dev_err(dev, "Cannot assign gpio to IRQ");
-		ret = -ENODEV;
-		goto err;
-	}
-
-	/* Firmware version check */
-	ret = smb_rd16(SECOCEC_VERSION, &val);
-	if (ret) {
-		dev_err(dev, "Cannot check fw version");
-		goto err;
-	}
-	if (val < SECOCEC_LATEST_FW) {
-		dev_err(dev, "CEC Firmware not supported (v.%04x). Use ver > v.%04x",
-			val, SECOCEC_LATEST_FW);
-		ret = -EINVAL;
-		goto err;
-	}
-
-	ret = devm_request_threaded_irq(dev,
-					secocec->irq,
-					NULL,
-					secocec_irq_handler,
-					IRQF_TRIGGER_RISING | IRQF_ONESHOT,
-					dev_name(&pdev->dev), secocec);
-
-	if (ret) {
-		dev_err(dev, "Cannot request IRQ %d", secocec->irq);
-		ret = -EIO;
-		goto err;
-	}
-
-	/* Allocate CEC adapter */
-	secocec->cec_adap = cec_allocate_adapter(&secocec_cec_adap_ops,
-						 secocec,
-						 dev_name(dev),
-						 CEC_CAP_DEFAULTS |
-						 CEC_CAP_CONNECTOR_INFO,
-						 SECOCEC_MAX_ADDRS);
-
-	if (IS_ERR(secocec->cec_adap)) {
-		ret = PTR_ERR(secocec->cec_adap);
-		goto err;
-	}
-
-	secocec->notifier = cec_notifier_cec_adap_register(hdmi_dev, conn,
-							   secocec->cec_adap);
-	if (!secocec->notifier) {
-		ret = -ENOMEM;
-		goto err_delete_adapter;
-	}
-
-	ret = cec_register_adapter(secocec->cec_adap, dev);
-	if (ret)
-		goto err_notifier;
-
-	ret = secocec_ir_probe(secocec);
-	if (ret)
-		goto err_notifier;
-
-	platform_set_drvdata(pdev, secocec);
-
-	dev_dbg(dev, "Device registered");
-
-	return ret;
-
-err_notifier:
-	cec_notifier_cec_adap_unregister(secocec->notifier, secocec->cec_adap);
-err_delete_adapter:
-	cec_delete_adapter(secocec->cec_adap);
-err:
-	release_region(BRA_SMB_BASE_ADDR, 7);
-	dev_err(dev, "%s device probe failed\n", dev_name(dev));
-
-	return ret;
-}
-
-static int secocec_remove(struct platform_device *pdev)
-{
-	struct secocec_data *secocec = platform_get_drvdata(pdev);
-	u16 val;
-
-	if (secocec->ir) {
-		smb_rd16(SECOCEC_ENABLE_REG_1, &val);
-
-		smb_wr16(SECOCEC_ENABLE_REG_1, val & ~SECOCEC_ENABLE_REG_1_IR);
-
-		dev_dbg(&pdev->dev, "IR disabled");
-	}
-	cec_notifier_cec_adap_unregister(secocec->notifier, secocec->cec_adap);
-	cec_unregister_adapter(secocec->cec_adap);
-
-	release_region(BRA_SMB_BASE_ADDR, 7);
-
-	dev_dbg(&pdev->dev, "CEC device removed");
-
-	return 0;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int secocec_suspend(struct device *dev)
-{
-	int status;
-	u16 val;
-
-	dev_dbg(dev, "Device going to suspend, disabling");
-
-	/* Clear the status register */
-	status = smb_rd16(SECOCEC_STATUS_REG_1, &val);
-	if (status)
-		goto err;
-
-	status = smb_wr16(SECOCEC_STATUS_REG_1, val);
-	if (status)
-		goto err;
-
-	/* Disable the interrupts */
-	status = smb_rd16(SECOCEC_ENABLE_REG_1, &val);
-	if (status)
-		goto err;
-
-	status = smb_wr16(SECOCEC_ENABLE_REG_1, val &
-			  ~SECOCEC_ENABLE_REG_1_CEC & ~SECOCEC_ENABLE_REG_1_IR);
-	if (status)
-		goto err;
-
-	return 0;
-
-err:
-	dev_err(dev, "Suspend failed (err: %d)", status);
-	return status;
-}
-
-static int secocec_resume(struct device *dev)
-{
-	int status;
-	u16 val;
-
-	dev_dbg(dev, "Resuming device from suspend");
-
-	/* Clear the status register */
-	status = smb_rd16(SECOCEC_STATUS_REG_1, &val);
-	if (status)
-		goto err;
-
-	status = smb_wr16(SECOCEC_STATUS_REG_1, val);
-	if (status)
-		goto err;
-
-	/* Enable the interrupts */
-	status = smb_rd16(SECOCEC_ENABLE_REG_1, &val);
-	if (status)
-		goto err;
-
-	status = smb_wr16(SECOCEC_ENABLE_REG_1, val | SECOCEC_ENABLE_REG_1_CEC);
-	if (status)
-		goto err;
-
-	dev_dbg(dev, "Device resumed from suspend");
-
-	return 0;
-
-err:
-	dev_err(dev, "Resume failed (err: %d)", status);
-	return status;
-}
-
-static SIMPLE_DEV_PM_OPS(secocec_pm_ops, secocec_suspend, secocec_resume);
-#define SECOCEC_PM_OPS (&secocec_pm_ops)
-#else
-#define SECOCEC_PM_OPS NULL
-#endif
-
-#ifdef CONFIG_ACPI
-static const struct acpi_device_id secocec_acpi_match[] = {
-	{"CEC00001", 0},
-	{},
-};
-
-MODULE_DEVICE_TABLE(acpi, secocec_acpi_match);
-#endif
-
-static struct platform_driver secocec_driver = {
-	.driver = {
-		   .name = SECOCEC_DEV_NAME,
-		   .acpi_match_table = ACPI_PTR(secocec_acpi_match),
-		   .pm = SECOCEC_PM_OPS,
-	},
-	.probe = secocec_probe,
-	.remove = secocec_remove,
-};
-
-module_platform_driver(secocec_driver);
-
-MODULE_DESCRIPTION("SECO CEC X86 Driver");
-MODULE_AUTHOR("Ettore Chimenti <ek5.chimenti@gmail.com>");
-MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/media/platform/seco-cec/seco-cec.h b/drivers/media/platform/seco-cec/seco-cec.h
deleted file mode 100644
index 843de8c7dfd4..000000000000
--- a/drivers/media/platform/seco-cec/seco-cec.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/*
- * SECO X86 Boards CEC register defines
- *
- * Author:  Ettore Chimenti <ek5.chimenti@gmail.com>
- * Copyright (C) 2018, SECO Spa.
- * Copyright (C) 2018, Aidilab Srl.
- */
-
-#ifndef __SECO_CEC_H__
-#define __SECO_CEC_H__
-
-#define SECOCEC_MAX_ADDRS		1
-#define SECOCEC_DEV_NAME		"secocec"
-#define SECOCEC_LATEST_FW		0x0f0b
-
-#define SMBTIMEOUT			0xfff
-#define SMB_POLL_UDELAY			10
-
-#define SMBUS_WRITE			0
-#define SMBUS_READ			1
-
-#define CMD_BYTE_DATA			0
-#define CMD_WORD_DATA			1
-
-/*
- * SMBus definitons for Braswell
- */
-
-#define BRA_DONE_STATUS			BIT(7)
-#define BRA_INUSE_STS			BIT(6)
-#define BRA_FAILED_OP			BIT(4)
-#define BRA_BUS_ERR			BIT(3)
-#define BRA_DEV_ERR			BIT(2)
-#define BRA_INTR			BIT(1)
-#define BRA_HOST_BUSY			BIT(0)
-#define BRA_HSTS_ERR_MASK   (BRA_FAILED_OP | BRA_BUS_ERR | BRA_DEV_ERR)
-
-#define BRA_PEC_EN			BIT(7)
-#define BRA_START			BIT(6)
-#define BRA_LAST__BYTE			BIT(5)
-#define BRA_INTREN			BIT(0)
-#define BRA_SMB_CMD			(7 << 2)
-#define BRA_SMB_CMD_QUICK		(0 << 2)
-#define BRA_SMB_CMD_BYTE		(1 << 2)
-#define BRA_SMB_CMD_BYTE_DATA		(2 << 2)
-#define BRA_SMB_CMD_WORD_DATA		(3 << 2)
-#define BRA_SMB_CMD_PROCESS_CALL	(4 << 2)
-#define BRA_SMB_CMD_BLOCK		(5 << 2)
-#define BRA_SMB_CMD_I2CREAD		(6 << 2)
-#define BRA_SMB_CMD_BLOCK_PROCESS	(7 << 2)
-
-#define BRA_SMB_BASE_ADDR  0x2040
-#define HSTS               (BRA_SMB_BASE_ADDR + 0)
-#define HCNT               (BRA_SMB_BASE_ADDR + 2)
-#define HCMD               (BRA_SMB_BASE_ADDR + 3)
-#define XMIT_SLVA          (BRA_SMB_BASE_ADDR + 4)
-#define HDAT0              (BRA_SMB_BASE_ADDR + 5)
-#define HDAT1              (BRA_SMB_BASE_ADDR + 6)
-
-/*
- * Microcontroller Address
- */
-
-#define SECOCEC_MICRO_ADDRESS		0x40
-
-/*
- * STM32 SMBus Registers
- */
-
-#define SECOCEC_VERSION			0x00
-#define SECOCEC_ENABLE_REG_1		0x01
-#define SECOCEC_ENABLE_REG_2		0x02
-#define SECOCEC_STATUS_REG_1		0x03
-#define SECOCEC_STATUS_REG_2		0x04
-
-#define SECOCEC_STATUS			0x28
-#define SECOCEC_DEVICE_LA		0x29
-#define SECOCEC_READ_OPERATION_ID	0x2a
-#define SECOCEC_READ_DATA_LENGTH	0x2b
-#define SECOCEC_READ_DATA_00		0x2c
-#define SECOCEC_READ_DATA_02		0x2d
-#define SECOCEC_READ_DATA_04		0x2e
-#define SECOCEC_READ_DATA_06		0x2f
-#define SECOCEC_READ_DATA_08		0x30
-#define SECOCEC_READ_DATA_10		0x31
-#define SECOCEC_READ_DATA_12		0x32
-#define SECOCEC_READ_BYTE0		0x33
-#define SECOCEC_WRITE_OPERATION_ID	0x34
-#define SECOCEC_WRITE_DATA_LENGTH	0x35
-#define SECOCEC_WRITE_DATA_00		0x36
-#define SECOCEC_WRITE_DATA_02		0x37
-#define SECOCEC_WRITE_DATA_04		0x38
-#define SECOCEC_WRITE_DATA_06		0x39
-#define SECOCEC_WRITE_DATA_08		0x3a
-#define SECOCEC_WRITE_DATA_10		0x3b
-#define SECOCEC_WRITE_DATA_12		0x3c
-#define SECOCEC_WRITE_BYTE0		0x3d
-
-#define SECOCEC_IR_READ_DATA		0x3e
-
-/*
- * IR
- */
-
-#define SECOCEC_IR_COMMAND_MASK		0x007F
-#define SECOCEC_IR_COMMAND_SHL		0
-#define SECOCEC_IR_ADDRESS_MASK		0x1F00
-#define SECOCEC_IR_ADDRESS_SHL		8
-#define SECOCEC_IR_TOGGLE_MASK		0x8000
-#define SECOCEC_IR_TOGGLE_SHL		15
-
-/*
- * Enabling register
- */
-
-#define SECOCEC_ENABLE_REG_1_CEC		0x1000
-#define SECOCEC_ENABLE_REG_1_IR			0x2000
-#define SECOCEC_ENABLE_REG_1_IR_PASSTHROUGH	0x4000
-
-/*
- * Status register
- */
-
-#define SECOCEC_STATUS_REG_1_CEC	SECOCEC_ENABLE_REG_1_CEC
-#define SECOCEC_STATUS_REG_1_IR		SECOCEC_ENABLE_REG_1_IR
-#define SECOCEC_STATUS_REG_1_IR_PASSTHR	SECOCEC_ENABLE_REG_1_IR_PASSTHR
-
-/*
- * Status data
- */
-
-#define SECOCEC_STATUS_MSG_RECEIVED_MASK	BIT(0)
-#define SECOCEC_STATUS_RX_ERROR_MASK		BIT(1)
-#define SECOCEC_STATUS_MSG_SENT_MASK		BIT(2)
-#define SECOCEC_STATUS_TX_ERROR_MASK		BIT(3)
-
-#define SECOCEC_STATUS_TX_NACK_ERROR		BIT(4)
-#define SECOCEC_STATUS_RX_OVERFLOW_MASK		BIT(5)
-
-#endif /* __SECO_CEC_H__ */
diff --git a/drivers/media/platform/sti/cec/Makefile b/drivers/media/platform/sti/cec/Makefile
deleted file mode 100644
index d0c6b4ae94d6..000000000000
--- a/drivers/media/platform/sti/cec/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_VIDEO_STI_HDMI_CEC) += stih-cec.o
diff --git a/drivers/media/platform/sti/cec/stih-cec.c b/drivers/media/platform/sti/cec/stih-cec.c
deleted file mode 100644
index f0c73e64b586..000000000000
--- a/drivers/media/platform/sti/cec/stih-cec.c
+++ /dev/null
@@ -1,400 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * STIH4xx CEC driver
- * Copyright (C) STMicroelectronics SA 2016
- *
- */
-#include <linux/clk.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/mfd/syscon.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/of_platform.h>
-#include <linux/platform_device.h>
-
-#include <media/cec.h>
-#include <media/cec-notifier.h>
-
-#define CEC_NAME	"stih-cec"
-
-/* CEC registers  */
-#define CEC_CLK_DIV           0x0
-#define CEC_CTRL              0x4
-#define CEC_IRQ_CTRL          0x8
-#define CEC_STATUS            0xC
-#define CEC_EXT_STATUS        0x10
-#define CEC_TX_CTRL           0x14
-#define CEC_FREE_TIME_THRESH  0x18
-#define CEC_BIT_TOUT_THRESH   0x1C
-#define CEC_BIT_PULSE_THRESH  0x20
-#define CEC_DATA              0x24
-#define CEC_TX_ARRAY_CTRL     0x28
-#define CEC_CTRL2             0x2C
-#define CEC_TX_ERROR_STS      0x30
-#define CEC_ADDR_TABLE        0x34
-#define CEC_DATA_ARRAY_CTRL   0x38
-#define CEC_DATA_ARRAY_STATUS 0x3C
-#define CEC_TX_DATA_BASE      0x40
-#define CEC_TX_DATA_TOP       0x50
-#define CEC_TX_DATA_SIZE      0x1
-#define CEC_RX_DATA_BASE      0x54
-#define CEC_RX_DATA_TOP       0x64
-#define CEC_RX_DATA_SIZE      0x1
-
-/* CEC_CTRL2 */
-#define CEC_LINE_INACTIVE_EN   BIT(0)
-#define CEC_AUTO_BUS_ERR_EN    BIT(1)
-#define CEC_STOP_ON_ARB_ERR_EN BIT(2)
-#define CEC_TX_REQ_WAIT_EN     BIT(3)
-
-/* CEC_DATA_ARRAY_CTRL */
-#define CEC_TX_ARRAY_EN          BIT(0)
-#define CEC_RX_ARRAY_EN          BIT(1)
-#define CEC_TX_ARRAY_RESET       BIT(2)
-#define CEC_RX_ARRAY_RESET       BIT(3)
-#define CEC_TX_N_OF_BYTES_IRQ_EN BIT(4)
-#define CEC_TX_STOP_ON_NACK      BIT(7)
-
-/* CEC_TX_ARRAY_CTRL */
-#define CEC_TX_N_OF_BYTES  0x1F
-#define CEC_TX_START       BIT(5)
-#define CEC_TX_AUTO_SOM_EN BIT(6)
-#define CEC_TX_AUTO_EOM_EN BIT(7)
-
-/* CEC_IRQ_CTRL */
-#define CEC_TX_DONE_IRQ_EN   BIT(0)
-#define CEC_ERROR_IRQ_EN     BIT(2)
-#define CEC_RX_DONE_IRQ_EN   BIT(3)
-#define CEC_RX_SOM_IRQ_EN    BIT(4)
-#define CEC_RX_EOM_IRQ_EN    BIT(5)
-#define CEC_FREE_TIME_IRQ_EN BIT(6)
-#define CEC_PIN_STS_IRQ_EN   BIT(7)
-
-/* CEC_CTRL */
-#define CEC_IN_FILTER_EN    BIT(0)
-#define CEC_PWR_SAVE_EN     BIT(1)
-#define CEC_EN              BIT(4)
-#define CEC_ACK_CTRL        BIT(5)
-#define CEC_RX_RESET_EN     BIT(6)
-#define CEC_IGNORE_RX_ERROR BIT(7)
-
-/* CEC_STATUS */
-#define CEC_TX_DONE_STS       BIT(0)
-#define CEC_TX_ACK_GET_STS    BIT(1)
-#define CEC_ERROR_STS         BIT(2)
-#define CEC_RX_DONE_STS       BIT(3)
-#define CEC_RX_SOM_STS        BIT(4)
-#define CEC_RX_EOM_STS        BIT(5)
-#define CEC_FREE_TIME_IRQ_STS BIT(6)
-#define CEC_PIN_STS           BIT(7)
-#define CEC_SBIT_TOUT_STS     BIT(8)
-#define CEC_DBIT_TOUT_STS     BIT(9)
-#define CEC_LPULSE_ERROR_STS  BIT(10)
-#define CEC_HPULSE_ERROR_STS  BIT(11)
-#define CEC_TX_ERROR          BIT(12)
-#define CEC_TX_ARB_ERROR      BIT(13)
-#define CEC_RX_ERROR_MIN      BIT(14)
-#define CEC_RX_ERROR_MAX      BIT(15)
-
-/* Signal free time in bit periods (2.4ms) */
-#define CEC_PRESENT_INIT_SFT 7
-#define CEC_NEW_INIT_SFT     5
-#define CEC_RETRANSMIT_SFT   3
-
-/* Constants for CEC_BIT_TOUT_THRESH register */
-#define CEC_SBIT_TOUT_47MS BIT(1)
-#define CEC_SBIT_TOUT_48MS (BIT(0) | BIT(1))
-#define CEC_SBIT_TOUT_50MS BIT(2)
-#define CEC_DBIT_TOUT_27MS BIT(0)
-#define CEC_DBIT_TOUT_28MS BIT(1)
-#define CEC_DBIT_TOUT_29MS (BIT(0) | BIT(1))
-
-/* Constants for CEC_BIT_PULSE_THRESH register */
-#define CEC_BIT_LPULSE_03MS BIT(1)
-#define CEC_BIT_HPULSE_03MS BIT(3)
-
-/* Constants for CEC_DATA_ARRAY_STATUS register */
-#define CEC_RX_N_OF_BYTES                     0x1F
-#define CEC_TX_N_OF_BYTES_SENT                BIT(5)
-#define CEC_RX_OVERRUN                        BIT(6)
-
-struct stih_cec {
-	struct cec_adapter	*adap;
-	struct device		*dev;
-	struct clk		*clk;
-	void __iomem		*regs;
-	int			irq;
-	u32			irq_status;
-	struct cec_notifier	*notifier;
-};
-
-static int stih_cec_adap_enable(struct cec_adapter *adap, bool enable)
-{
-	struct stih_cec *cec = cec_get_drvdata(adap);
-
-	if (enable) {
-		/* The doc says (input TCLK_PERIOD * CEC_CLK_DIV) = 0.1ms */
-		unsigned long clk_freq = clk_get_rate(cec->clk);
-		u32 cec_clk_div = clk_freq / 10000;
-
-		writel(cec_clk_div, cec->regs + CEC_CLK_DIV);
-
-		/* Configuration of the durations activating a timeout */
-		writel(CEC_SBIT_TOUT_47MS | (CEC_DBIT_TOUT_28MS << 4),
-		       cec->regs + CEC_BIT_TOUT_THRESH);
-
-		/* Configuration of the smallest allowed duration for pulses */
-		writel(CEC_BIT_LPULSE_03MS | CEC_BIT_HPULSE_03MS,
-		       cec->regs + CEC_BIT_PULSE_THRESH);
-
-		/* Minimum received bit period threshold */
-		writel(BIT(5) | BIT(7), cec->regs + CEC_TX_CTRL);
-
-		/* Configuration of transceiver data arrays */
-		writel(CEC_TX_ARRAY_EN | CEC_RX_ARRAY_EN | CEC_TX_STOP_ON_NACK,
-		       cec->regs + CEC_DATA_ARRAY_CTRL);
-
-		/* Configuration of the control bits for CEC Transceiver */
-		writel(CEC_IN_FILTER_EN | CEC_EN | CEC_RX_RESET_EN,
-		       cec->regs + CEC_CTRL);
-
-		/* Clear logical addresses */
-		writel(0, cec->regs + CEC_ADDR_TABLE);
-
-		/* Clear the status register */
-		writel(0x0, cec->regs + CEC_STATUS);
-
-		/* Enable the interrupts */
-		writel(CEC_TX_DONE_IRQ_EN | CEC_RX_DONE_IRQ_EN |
-		       CEC_RX_SOM_IRQ_EN | CEC_RX_EOM_IRQ_EN |
-		       CEC_ERROR_IRQ_EN,
-		       cec->regs + CEC_IRQ_CTRL);
-
-	} else {
-		/* Clear logical addresses */
-		writel(0, cec->regs + CEC_ADDR_TABLE);
-
-		/* Clear the status register */
-		writel(0x0, cec->regs + CEC_STATUS);
-
-		/* Disable the interrupts */
-		writel(0, cec->regs + CEC_IRQ_CTRL);
-	}
-
-	return 0;
-}
-
-static int stih_cec_adap_log_addr(struct cec_adapter *adap, u8 logical_addr)
-{
-	struct stih_cec *cec = cec_get_drvdata(adap);
-	u32 reg = readl(cec->regs + CEC_ADDR_TABLE);
-
-	reg |= 1 << logical_addr;
-
-	if (logical_addr == CEC_LOG_ADDR_INVALID)
-		reg = 0;
-
-	writel(reg, cec->regs + CEC_ADDR_TABLE);
-
-	return 0;
-}
-
-static int stih_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
-				  u32 signal_free_time, struct cec_msg *msg)
-{
-	struct stih_cec *cec = cec_get_drvdata(adap);
-	int i;
-
-	/* Copy message into registers */
-	for (i = 0; i < msg->len; i++)
-		writeb(msg->msg[i], cec->regs + CEC_TX_DATA_BASE + i);
-
-	/*
-	 * Start transmission, configure hardware to add start and stop bits
-	 * Signal free time is handled by the hardware
-	 */
-	writel(CEC_TX_AUTO_SOM_EN | CEC_TX_AUTO_EOM_EN | CEC_TX_START |
-	       msg->len, cec->regs + CEC_TX_ARRAY_CTRL);
-
-	return 0;
-}
-
-static void stih_tx_done(struct stih_cec *cec, u32 status)
-{
-	if (status & CEC_TX_ERROR) {
-		cec_transmit_attempt_done(cec->adap, CEC_TX_STATUS_ERROR);
-		return;
-	}
-
-	if (status & CEC_TX_ARB_ERROR) {
-		cec_transmit_attempt_done(cec->adap, CEC_TX_STATUS_ARB_LOST);
-		return;
-	}
-
-	if (!(status & CEC_TX_ACK_GET_STS)) {
-		cec_transmit_attempt_done(cec->adap, CEC_TX_STATUS_NACK);
-		return;
-	}
-
-	cec_transmit_attempt_done(cec->adap, CEC_TX_STATUS_OK);
-}
-
-static void stih_rx_done(struct stih_cec *cec, u32 status)
-{
-	struct cec_msg msg = {};
-	u8 i;
-
-	if (status & CEC_RX_ERROR_MIN)
-		return;
-
-	if (status & CEC_RX_ERROR_MAX)
-		return;
-
-	msg.len = readl(cec->regs + CEC_DATA_ARRAY_STATUS) & 0x1f;
-
-	if (!msg.len)
-		return;
-
-	if (msg.len > 16)
-		msg.len = 16;
-
-	for (i = 0; i < msg.len; i++)
-		msg.msg[i] = readl(cec->regs + CEC_RX_DATA_BASE + i);
-
-	cec_received_msg(cec->adap, &msg);
-}
-
-static irqreturn_t stih_cec_irq_handler_thread(int irq, void *priv)
-{
-	struct stih_cec *cec = priv;
-
-	if (cec->irq_status & CEC_TX_DONE_STS)
-		stih_tx_done(cec, cec->irq_status);
-
-	if (cec->irq_status & CEC_RX_DONE_STS)
-		stih_rx_done(cec, cec->irq_status);
-
-	cec->irq_status = 0;
-
-	return IRQ_HANDLED;
-}
-
-static irqreturn_t stih_cec_irq_handler(int irq, void *priv)
-{
-	struct stih_cec *cec = priv;
-
-	cec->irq_status = readl(cec->regs + CEC_STATUS);
-	writel(cec->irq_status, cec->regs + CEC_STATUS);
-
-	return IRQ_WAKE_THREAD;
-}
-
-static const struct cec_adap_ops sti_cec_adap_ops = {
-	.adap_enable = stih_cec_adap_enable,
-	.adap_log_addr = stih_cec_adap_log_addr,
-	.adap_transmit = stih_cec_adap_transmit,
-};
-
-static int stih_cec_probe(struct platform_device *pdev)
-{
-	struct device *dev = &pdev->dev;
-	struct resource *res;
-	struct stih_cec *cec;
-	struct device *hdmi_dev;
-	int ret;
-
-	hdmi_dev = cec_notifier_parse_hdmi_phandle(dev);
-
-	if (IS_ERR(hdmi_dev))
-		return PTR_ERR(hdmi_dev);
-
-	cec = devm_kzalloc(dev, sizeof(*cec), GFP_KERNEL);
-	if (!cec)
-		return -ENOMEM;
-
-	cec->dev = dev;
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	cec->regs = devm_ioremap_resource(dev, res);
-	if (IS_ERR(cec->regs))
-		return PTR_ERR(cec->regs);
-
-	cec->irq = platform_get_irq(pdev, 0);
-	if (cec->irq < 0)
-		return cec->irq;
-
-	ret = devm_request_threaded_irq(dev, cec->irq, stih_cec_irq_handler,
-					stih_cec_irq_handler_thread, 0,
-					pdev->name, cec);
-	if (ret)
-		return ret;
-
-	cec->clk = devm_clk_get(dev, "cec-clk");
-	if (IS_ERR(cec->clk)) {
-		dev_err(dev, "Cannot get cec clock\n");
-		return PTR_ERR(cec->clk);
-	}
-
-	cec->adap = cec_allocate_adapter(&sti_cec_adap_ops, cec, CEC_NAME,
-					 CEC_CAP_DEFAULTS |
-					 CEC_CAP_CONNECTOR_INFO,
-					 CEC_MAX_LOG_ADDRS);
-	ret = PTR_ERR_OR_ZERO(cec->adap);
-	if (ret)
-		return ret;
-
-	cec->notifier = cec_notifier_cec_adap_register(hdmi_dev, NULL,
-						       cec->adap);
-	if (!cec->notifier) {
-		ret = -ENOMEM;
-		goto err_delete_adapter;
-	}
-
-	ret = cec_register_adapter(cec->adap, &pdev->dev);
-	if (ret)
-		goto err_notifier;
-
-	platform_set_drvdata(pdev, cec);
-	return 0;
-
-err_notifier:
-	cec_notifier_cec_adap_unregister(cec->notifier, cec->adap);
-
-err_delete_adapter:
-	cec_delete_adapter(cec->adap);
-	return ret;
-}
-
-static int stih_cec_remove(struct platform_device *pdev)
-{
-	struct stih_cec *cec = platform_get_drvdata(pdev);
-
-	cec_notifier_cec_adap_unregister(cec->notifier, cec->adap);
-	cec_unregister_adapter(cec->adap);
-
-	return 0;
-}
-
-static const struct of_device_id stih_cec_match[] = {
-	{
-		.compatible	= "st,stih-cec",
-	},
-	{},
-};
-MODULE_DEVICE_TABLE(of, stih_cec_match);
-
-static struct platform_driver stih_cec_pdrv = {
-	.probe	= stih_cec_probe,
-	.remove = stih_cec_remove,
-	.driver = {
-		.name		= CEC_NAME,
-		.of_match_table	= stih_cec_match,
-	},
-};
-
-module_platform_driver(stih_cec_pdrv);
-
-MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@linaro.org>");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("STIH4xx CEC driver");
diff --git a/drivers/media/platform/sti/delta/delta-ipc.c b/drivers/media/platform/sti/delta/delta-ipc.c
index 186d88f02ecd..371429d81ea1 100644
--- a/drivers/media/platform/sti/delta/delta-ipc.c
+++ b/drivers/media/platform/sti/delta/delta-ipc.c
@@ -175,8 +175,8 @@ int delta_ipc_open(struct delta_ctx *pctx, const char *name,
 	msg.ipc_buf_size = ipc_buf_size;
 	msg.ipc_buf_paddr = ctx->ipc_buf->paddr;
 
-	memcpy(msg.name, name, sizeof(msg.name));
-	msg.name[sizeof(msg.name) - 1] = 0;
+	memset(msg.name, 0, sizeof(msg.name));
+	strcpy(msg.name, name);
 
 	msg.param_size = param->size;
 	memcpy(ctx->ipc_buf->vaddr, param->data, msg.param_size);
diff --git a/drivers/media/platform/stm32/Makefile b/drivers/media/platform/stm32/Makefile
index 5ed73599ca44..48b36db2c2e2 100644
--- a/drivers/media/platform/stm32/Makefile
+++ b/drivers/media/platform/stm32/Makefile
@@ -1,3 +1,2 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-$(CONFIG_VIDEO_STM32_DCMI) += stm32-dcmi.o
-obj-$(CONFIG_VIDEO_STM32_HDMI_CEC) += stm32-cec.o
diff --git a/drivers/media/platform/stm32/stm32-cec.c b/drivers/media/platform/stm32/stm32-cec.c
deleted file mode 100644
index ea4b1ebfca99..000000000000
--- a/drivers/media/platform/stm32/stm32-cec.c
+++ /dev/null
@@ -1,374 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * STM32 CEC driver
- * Copyright (C) STMicroelectronics SA 2017
- *
- */
-
-#include <linux/clk.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <linux/platform_device.h>
-#include <linux/regmap.h>
-
-#include <media/cec.h>
-
-#define CEC_NAME	"stm32-cec"
-
-/* CEC registers  */
-#define CEC_CR		0x0000 /* Control Register */
-#define CEC_CFGR	0x0004 /* ConFiGuration Register */
-#define CEC_TXDR	0x0008 /* Rx data Register */
-#define CEC_RXDR	0x000C /* Rx data Register */
-#define CEC_ISR		0x0010 /* Interrupt and status Register */
-#define CEC_IER		0x0014 /* Interrupt enable Register */
-
-#define TXEOM		BIT(2)
-#define TXSOM		BIT(1)
-#define CECEN		BIT(0)
-
-#define LSTN		BIT(31)
-#define OAR		GENMASK(30, 16)
-#define SFTOP		BIT(8)
-#define BRDNOGEN	BIT(7)
-#define LBPEGEN		BIT(6)
-#define BREGEN		BIT(5)
-#define BRESTP		BIT(4)
-#define RXTOL		BIT(3)
-#define SFT		GENMASK(2, 0)
-#define FULL_CFG	(LSTN | SFTOP | BRDNOGEN | LBPEGEN | BREGEN | BRESTP \
-			 | RXTOL)
-
-#define TXACKE		BIT(12)
-#define TXERR		BIT(11)
-#define TXUDR		BIT(10)
-#define TXEND		BIT(9)
-#define TXBR		BIT(8)
-#define ARBLST		BIT(7)
-#define RXACKE		BIT(6)
-#define RXOVR		BIT(2)
-#define RXEND		BIT(1)
-#define RXBR		BIT(0)
-
-#define ALL_TX_IT	(TXEND | TXBR | TXACKE | TXERR | TXUDR | ARBLST)
-#define ALL_RX_IT	(RXEND | RXBR | RXACKE | RXOVR)
-
-/*
- * 400 ms is the time it takes for one 16 byte message to be
- * transferred and 5 is the maximum number of retries. Add
- * another 100 ms as a margin.
- */
-#define CEC_XFER_TIMEOUT_MS (5 * 400 + 100)
-
-struct stm32_cec {
-	struct cec_adapter	*adap;
-	struct device		*dev;
-	struct clk		*clk_cec;
-	struct clk		*clk_hdmi_cec;
-	struct reset_control	*rstc;
-	struct regmap		*regmap;
-	int			irq;
-	u32			irq_status;
-	struct cec_msg		rx_msg;
-	struct cec_msg		tx_msg;
-	int			tx_cnt;
-};
-
-static void cec_hw_init(struct stm32_cec *cec)
-{
-	regmap_update_bits(cec->regmap, CEC_CR, TXEOM | TXSOM | CECEN, 0);
-
-	regmap_update_bits(cec->regmap, CEC_IER, ALL_TX_IT | ALL_RX_IT,
-			   ALL_TX_IT | ALL_RX_IT);
-
-	regmap_update_bits(cec->regmap, CEC_CFGR, FULL_CFG, FULL_CFG);
-}
-
-static void stm32_tx_done(struct stm32_cec *cec, u32 status)
-{
-	if (status & (TXERR | TXUDR)) {
-		cec_transmit_done(cec->adap, CEC_TX_STATUS_ERROR,
-				  0, 0, 0, 1);
-		return;
-	}
-
-	if (status & ARBLST) {
-		cec_transmit_done(cec->adap, CEC_TX_STATUS_ARB_LOST,
-				  1, 0, 0, 0);
-		return;
-	}
-
-	if (status & TXACKE) {
-		cec_transmit_done(cec->adap, CEC_TX_STATUS_NACK,
-				  0, 1, 0, 0);
-		return;
-	}
-
-	if (cec->irq_status & TXBR) {
-		/* send next byte */
-		if (cec->tx_cnt < cec->tx_msg.len)
-			regmap_write(cec->regmap, CEC_TXDR,
-				     cec->tx_msg.msg[cec->tx_cnt++]);
-
-		/* TXEOM is set to command transmission of the last byte */
-		if (cec->tx_cnt == cec->tx_msg.len)
-			regmap_update_bits(cec->regmap, CEC_CR, TXEOM, TXEOM);
-	}
-
-	if (cec->irq_status & TXEND)
-		cec_transmit_done(cec->adap, CEC_TX_STATUS_OK, 0, 0, 0, 0);
-}
-
-static void stm32_rx_done(struct stm32_cec *cec, u32 status)
-{
-	if (cec->irq_status & (RXACKE | RXOVR)) {
-		cec->rx_msg.len = 0;
-		return;
-	}
-
-	if (cec->irq_status & RXBR) {
-		u32 val;
-
-		regmap_read(cec->regmap, CEC_RXDR, &val);
-		cec->rx_msg.msg[cec->rx_msg.len++] = val & 0xFF;
-	}
-
-	if (cec->irq_status & RXEND) {
-		cec_received_msg(cec->adap, &cec->rx_msg);
-		cec->rx_msg.len = 0;
-	}
-}
-
-static irqreturn_t stm32_cec_irq_thread(int irq, void *arg)
-{
-	struct stm32_cec *cec = arg;
-
-	if (cec->irq_status & ALL_TX_IT)
-		stm32_tx_done(cec, cec->irq_status);
-
-	if (cec->irq_status & ALL_RX_IT)
-		stm32_rx_done(cec, cec->irq_status);
-
-	cec->irq_status = 0;
-
-	return IRQ_HANDLED;
-}
-
-static irqreturn_t stm32_cec_irq_handler(int irq, void *arg)
-{
-	struct stm32_cec *cec = arg;
-
-	regmap_read(cec->regmap, CEC_ISR, &cec->irq_status);
-
-	regmap_update_bits(cec->regmap, CEC_ISR,
-			   ALL_TX_IT | ALL_RX_IT,
-			   ALL_TX_IT | ALL_RX_IT);
-
-	return IRQ_WAKE_THREAD;
-}
-
-static int stm32_cec_adap_enable(struct cec_adapter *adap, bool enable)
-{
-	struct stm32_cec *cec = adap->priv;
-	int ret = 0;
-
-	if (enable) {
-		ret = clk_enable(cec->clk_cec);
-		if (ret)
-			dev_err(cec->dev, "fail to enable cec clock\n");
-
-		clk_enable(cec->clk_hdmi_cec);
-		regmap_update_bits(cec->regmap, CEC_CR, CECEN, CECEN);
-	} else {
-		clk_disable(cec->clk_cec);
-		clk_disable(cec->clk_hdmi_cec);
-		regmap_update_bits(cec->regmap, CEC_CR, CECEN, 0);
-	}
-
-	return ret;
-}
-
-static int stm32_cec_adap_log_addr(struct cec_adapter *adap, u8 logical_addr)
-{
-	struct stm32_cec *cec = adap->priv;
-	u32 oar = (1 << logical_addr) << 16;
-	u32 val;
-
-	/* Poll every 100µs the register CEC_CR to wait end of transmission */
-	regmap_read_poll_timeout(cec->regmap, CEC_CR, val, !(val & TXSOM),
-				 100, CEC_XFER_TIMEOUT_MS * 1000);
-	regmap_update_bits(cec->regmap, CEC_CR, CECEN, 0);
-
-	if (logical_addr == CEC_LOG_ADDR_INVALID)
-		regmap_update_bits(cec->regmap, CEC_CFGR, OAR, 0);
-	else
-		regmap_update_bits(cec->regmap, CEC_CFGR, oar, oar);
-
-	regmap_update_bits(cec->regmap, CEC_CR, CECEN, CECEN);
-
-	return 0;
-}
-
-static int stm32_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
-				   u32 signal_free_time, struct cec_msg *msg)
-{
-	struct stm32_cec *cec = adap->priv;
-
-	/* Copy message */
-	cec->tx_msg = *msg;
-	cec->tx_cnt = 0;
-
-	/*
-	 * If the CEC message consists of only one byte,
-	 * TXEOM must be set before of TXSOM.
-	 */
-	if (cec->tx_msg.len == 1)
-		regmap_update_bits(cec->regmap, CEC_CR, TXEOM, TXEOM);
-
-	/* TXSOM is set to command transmission of the first byte */
-	regmap_update_bits(cec->regmap, CEC_CR, TXSOM, TXSOM);
-
-	/* Write the header (first byte of message) */
-	regmap_write(cec->regmap, CEC_TXDR, cec->tx_msg.msg[0]);
-	cec->tx_cnt++;
-
-	return 0;
-}
-
-static const struct cec_adap_ops stm32_cec_adap_ops = {
-	.adap_enable = stm32_cec_adap_enable,
-	.adap_log_addr = stm32_cec_adap_log_addr,
-	.adap_transmit = stm32_cec_adap_transmit,
-};
-
-static const struct regmap_config stm32_cec_regmap_cfg = {
-	.reg_bits = 32,
-	.val_bits = 32,
-	.reg_stride = sizeof(u32),
-	.max_register = 0x14,
-	.fast_io = true,
-};
-
-static int stm32_cec_probe(struct platform_device *pdev)
-{
-	u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_PHYS_ADDR | CEC_MODE_MONITOR_ALL;
-	struct resource *res;
-	struct stm32_cec *cec;
-	void __iomem *mmio;
-	int ret;
-
-	cec = devm_kzalloc(&pdev->dev, sizeof(*cec), GFP_KERNEL);
-	if (!cec)
-		return -ENOMEM;
-
-	cec->dev = &pdev->dev;
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	mmio = devm_ioremap_resource(&pdev->dev, res);
-	if (IS_ERR(mmio))
-		return PTR_ERR(mmio);
-
-	cec->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "cec", mmio,
-						&stm32_cec_regmap_cfg);
-
-	if (IS_ERR(cec->regmap))
-		return PTR_ERR(cec->regmap);
-
-	cec->irq = platform_get_irq(pdev, 0);
-	if (cec->irq < 0)
-		return cec->irq;
-
-	ret = devm_request_threaded_irq(&pdev->dev, cec->irq,
-					stm32_cec_irq_handler,
-					stm32_cec_irq_thread,
-					0,
-					pdev->name, cec);
-	if (ret)
-		return ret;
-
-	cec->clk_cec = devm_clk_get(&pdev->dev, "cec");
-	if (IS_ERR(cec->clk_cec)) {
-		if (PTR_ERR(cec->clk_cec) != -EPROBE_DEFER)
-			dev_err(&pdev->dev, "Cannot get cec clock\n");
-
-		return PTR_ERR(cec->clk_cec);
-	}
-
-	ret = clk_prepare(cec->clk_cec);
-	if (ret) {
-		dev_err(&pdev->dev, "Unable to prepare cec clock\n");
-		return ret;
-	}
-
-	cec->clk_hdmi_cec = devm_clk_get(&pdev->dev, "hdmi-cec");
-	if (IS_ERR(cec->clk_hdmi_cec) &&
-	    PTR_ERR(cec->clk_hdmi_cec) == -EPROBE_DEFER)
-		return -EPROBE_DEFER;
-
-	if (!IS_ERR(cec->clk_hdmi_cec)) {
-		ret = clk_prepare(cec->clk_hdmi_cec);
-		if (ret) {
-			dev_err(&pdev->dev, "Can't prepare hdmi-cec clock\n");
-			return ret;
-		}
-	}
-
-	/*
-	 * CEC_CAP_PHYS_ADDR caps should be removed when a cec notifier is
-	 * available for example when a drm driver can provide edid
-	 */
-	cec->adap = cec_allocate_adapter(&stm32_cec_adap_ops, cec,
-			CEC_NAME, caps,	CEC_MAX_LOG_ADDRS);
-	ret = PTR_ERR_OR_ZERO(cec->adap);
-	if (ret)
-		return ret;
-
-	ret = cec_register_adapter(cec->adap, &pdev->dev);
-	if (ret) {
-		cec_delete_adapter(cec->adap);
-		return ret;
-	}
-
-	cec_hw_init(cec);
-
-	platform_set_drvdata(pdev, cec);
-
-	return 0;
-}
-
-static int stm32_cec_remove(struct platform_device *pdev)
-{
-	struct stm32_cec *cec = platform_get_drvdata(pdev);
-
-	clk_unprepare(cec->clk_cec);
-	clk_unprepare(cec->clk_hdmi_cec);
-
-	cec_unregister_adapter(cec->adap);
-
-	return 0;
-}
-
-static const struct of_device_id stm32_cec_of_match[] = {
-	{ .compatible = "st,stm32-cec" },
-	{ /* end node */ }
-};
-MODULE_DEVICE_TABLE(of, stm32_cec_of_match);
-
-static struct platform_driver stm32_cec_driver = {
-	.probe  = stm32_cec_probe,
-	.remove = stm32_cec_remove,
-	.driver = {
-		.name		= CEC_NAME,
-		.of_match_table = stm32_cec_of_match,
-	},
-};
-
-module_platform_driver(stm32_cec_driver);
-
-MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
-MODULE_AUTHOR("Yannick Fertre <yannick.fertre@st.com>");
-MODULE_DESCRIPTION("STMicroelectronics STM32 Consumer Electronics Control");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/sunxi/Kconfig b/drivers/media/platform/sunxi/Kconfig
index 71808e93ac2e..7151cc249afa 100644
--- a/drivers/media/platform/sunxi/Kconfig
+++ b/drivers/media/platform/sunxi/Kconfig
@@ -1,2 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+
 source "drivers/media/platform/sunxi/sun4i-csi/Kconfig"
 source "drivers/media/platform/sunxi/sun6i-csi/Kconfig"
diff --git a/drivers/media/platform/sunxi/Makefile b/drivers/media/platform/sunxi/Makefile
index ff0993f70dc3..fc537c9f5ca9 100644
--- a/drivers/media/platform/sunxi/Makefile
+++ b/drivers/media/platform/sunxi/Makefile
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
 obj-y		+= sun4i-csi/
 obj-y		+= sun6i-csi/
 obj-y		+= sun8i-di/
diff --git a/drivers/media/platform/sunxi/sun4i-csi/Kconfig b/drivers/media/platform/sunxi/sun4i-csi/Kconfig
index e86e29b6a603..903c6152f6e8 100644
--- a/drivers/media/platform/sunxi/sun4i-csi/Kconfig
+++ b/drivers/media/platform/sunxi/sun4i-csi/Kconfig
@@ -1,7 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0
+
 config VIDEO_SUN4I_CSI
 	tristate "Allwinner A10 CMOS Sensor Interface Support"
-	depends on VIDEO_V4L2 && COMMON_CLK && VIDEO_V4L2_SUBDEV_API && HAS_DMA
+	depends on VIDEO_V4L2 && COMMON_CLK  && HAS_DMA
 	depends on ARCH_SUNXI || COMPILE_TEST
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select VIDEOBUF2_DMA_CONTIG
 	select V4L2_FWNODE
 	help
diff --git a/drivers/media/platform/sunxi/sun4i-csi/Makefile b/drivers/media/platform/sunxi/sun4i-csi/Makefile
index 7c790a57f5ee..5062b006d63e 100644
--- a/drivers/media/platform/sunxi/sun4i-csi/Makefile
+++ b/drivers/media/platform/sunxi/sun4i-csi/Makefile
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
 sun4i-csi-y += sun4i_csi.o
 sun4i-csi-y += sun4i_dma.o
 sun4i-csi-y += sun4i_v4l2.o
diff --git a/drivers/media/platform/sunxi/sun6i-csi/Kconfig b/drivers/media/platform/sunxi/sun6i-csi/Kconfig
index 269b3ebf4f52..586e3fb3a80d 100644
--- a/drivers/media/platform/sunxi/sun6i-csi/Kconfig
+++ b/drivers/media/platform/sunxi/sun6i-csi/Kconfig
@@ -1,8 +1,10 @@
 # SPDX-License-Identifier: GPL-2.0-only
 config VIDEO_SUN6I_CSI
 	tristate "Allwinner V3s Camera Sensor Interface driver"
-	depends on VIDEO_V4L2 && COMMON_CLK && VIDEO_V4L2_SUBDEV_API && HAS_DMA
+	depends on VIDEO_V4L2 && COMMON_CLK  && HAS_DMA
 	depends on ARCH_SUNXI || COMPILE_TEST
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select VIDEOBUF2_DMA_CONTIG
 	select REGMAP_MMIO
 	select V4L2_FWNODE
diff --git a/drivers/media/platform/tegra-cec/Makefile b/drivers/media/platform/tegra-cec/Makefile
deleted file mode 100644
index 97e57c7493c0..000000000000
--- a/drivers/media/platform/tegra-cec/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_VIDEO_TEGRA_HDMI_CEC)	+= tegra_cec.o
diff --git a/drivers/media/platform/tegra-cec/tegra_cec.c b/drivers/media/platform/tegra-cec/tegra_cec.c
deleted file mode 100644
index 1ac0c70a5981..000000000000
--- a/drivers/media/platform/tegra-cec/tegra_cec.c
+++ /dev/null
@@ -1,481 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Tegra CEC implementation
- *
- * The original 3.10 CEC driver using a custom API:
- *
- * Copyright (c) 2012-2015, NVIDIA CORPORATION.  All rights reserved.
- *
- * Conversion to the CEC framework and to the mainline kernel:
- *
- * Copyright 2016-2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/err.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/of.h>
-#include <linux/of_platform.h>
-#include <linux/platform_device.h>
-#include <linux/clk/tegra.h>
-
-#include <media/cec-notifier.h>
-
-#include "tegra_cec.h"
-
-#define TEGRA_CEC_NAME "tegra-cec"
-
-struct tegra_cec {
-	struct cec_adapter	*adap;
-	struct device		*dev;
-	struct clk		*clk;
-	void __iomem		*cec_base;
-	struct cec_notifier	*notifier;
-	int			tegra_cec_irq;
-	bool			rx_done;
-	bool			tx_done;
-	int			tx_status;
-	u8			rx_buf[CEC_MAX_MSG_SIZE];
-	u8			rx_buf_cnt;
-	u32			tx_buf[CEC_MAX_MSG_SIZE];
-	u8			tx_buf_cur;
-	u8			tx_buf_cnt;
-};
-
-static inline u32 cec_read(struct tegra_cec *cec, u32 reg)
-{
-	return readl(cec->cec_base + reg);
-}
-
-static inline void cec_write(struct tegra_cec *cec, u32 reg, u32 val)
-{
-	writel(val, cec->cec_base + reg);
-}
-
-static void tegra_cec_error_recovery(struct tegra_cec *cec)
-{
-	u32 hw_ctrl;
-
-	hw_ctrl = cec_read(cec, TEGRA_CEC_HW_CONTROL);
-	cec_write(cec, TEGRA_CEC_HW_CONTROL, 0);
-	cec_write(cec, TEGRA_CEC_INT_STAT, 0xffffffff);
-	cec_write(cec, TEGRA_CEC_HW_CONTROL, hw_ctrl);
-}
-
-static irqreturn_t tegra_cec_irq_thread_handler(int irq, void *data)
-{
-	struct device *dev = data;
-	struct tegra_cec *cec = dev_get_drvdata(dev);
-
-	if (cec->tx_done) {
-		cec_transmit_attempt_done(cec->adap, cec->tx_status);
-		cec->tx_done = false;
-	}
-	if (cec->rx_done) {
-		struct cec_msg msg = {};
-
-		msg.len = cec->rx_buf_cnt;
-		memcpy(msg.msg, cec->rx_buf, msg.len);
-		cec_received_msg(cec->adap, &msg);
-		cec->rx_done = false;
-		cec->rx_buf_cnt = 0;
-	}
-	return IRQ_HANDLED;
-}
-
-static irqreturn_t tegra_cec_irq_handler(int irq, void *data)
-{
-	struct device *dev = data;
-	struct tegra_cec *cec = dev_get_drvdata(dev);
-	u32 status, mask;
-
-	status = cec_read(cec, TEGRA_CEC_INT_STAT);
-	mask = cec_read(cec, TEGRA_CEC_INT_MASK);
-
-	status &= mask;
-
-	if (!status)
-		return IRQ_HANDLED;
-
-	if (status & TEGRA_CEC_INT_STAT_TX_REGISTER_UNDERRUN) {
-		dev_err(dev, "TX underrun, interrupt timing issue!\n");
-
-		tegra_cec_error_recovery(cec);
-		cec_write(cec, TEGRA_CEC_INT_MASK,
-			  mask & ~TEGRA_CEC_INT_MASK_TX_REGISTER_EMPTY);
-
-		cec->tx_done = true;
-		cec->tx_status = CEC_TX_STATUS_ERROR;
-		return IRQ_WAKE_THREAD;
-	}
-
-	if ((status & TEGRA_CEC_INT_STAT_TX_ARBITRATION_FAILED) ||
-		   (status & TEGRA_CEC_INT_STAT_TX_BUS_ANOMALY_DETECTED)) {
-		tegra_cec_error_recovery(cec);
-		cec_write(cec, TEGRA_CEC_INT_MASK,
-			  mask & ~TEGRA_CEC_INT_MASK_TX_REGISTER_EMPTY);
-
-		cec->tx_done = true;
-		if (status & TEGRA_CEC_INT_STAT_TX_BUS_ANOMALY_DETECTED)
-			cec->tx_status = CEC_TX_STATUS_LOW_DRIVE;
-		else
-			cec->tx_status = CEC_TX_STATUS_ARB_LOST;
-		return IRQ_WAKE_THREAD;
-	}
-
-	if (status & TEGRA_CEC_INT_STAT_TX_FRAME_TRANSMITTED) {
-		cec_write(cec, TEGRA_CEC_INT_STAT,
-			  TEGRA_CEC_INT_STAT_TX_FRAME_TRANSMITTED);
-
-		if (status & TEGRA_CEC_INT_STAT_TX_FRAME_OR_BLOCK_NAKD) {
-			tegra_cec_error_recovery(cec);
-
-			cec->tx_done = true;
-			cec->tx_status = CEC_TX_STATUS_NACK;
-		} else {
-			cec->tx_done = true;
-			cec->tx_status = CEC_TX_STATUS_OK;
-		}
-		return IRQ_WAKE_THREAD;
-	}
-
-	if (status & TEGRA_CEC_INT_STAT_TX_FRAME_OR_BLOCK_NAKD)
-		dev_warn(dev, "TX NAKed on the fly!\n");
-
-	if (status & TEGRA_CEC_INT_STAT_TX_REGISTER_EMPTY) {
-		if (cec->tx_buf_cur == cec->tx_buf_cnt) {
-			cec_write(cec, TEGRA_CEC_INT_MASK,
-				  mask & ~TEGRA_CEC_INT_MASK_TX_REGISTER_EMPTY);
-		} else {
-			cec_write(cec, TEGRA_CEC_TX_REGISTER,
-				  cec->tx_buf[cec->tx_buf_cur++]);
-			cec_write(cec, TEGRA_CEC_INT_STAT,
-				  TEGRA_CEC_INT_STAT_TX_REGISTER_EMPTY);
-		}
-	}
-
-	if (status & TEGRA_CEC_INT_STAT_RX_START_BIT_DETECTED) {
-		cec_write(cec, TEGRA_CEC_INT_STAT,
-			  TEGRA_CEC_INT_STAT_RX_START_BIT_DETECTED);
-		cec->rx_done = false;
-		cec->rx_buf_cnt = 0;
-	}
-	if (status & TEGRA_CEC_INT_STAT_RX_REGISTER_FULL) {
-		u32 v;
-
-		cec_write(cec, TEGRA_CEC_INT_STAT,
-			  TEGRA_CEC_INT_STAT_RX_REGISTER_FULL);
-		v = cec_read(cec, TEGRA_CEC_RX_REGISTER);
-		if (cec->rx_buf_cnt < CEC_MAX_MSG_SIZE)
-			cec->rx_buf[cec->rx_buf_cnt++] = v & 0xff;
-		if (v & TEGRA_CEC_RX_REGISTER_EOM) {
-			cec->rx_done = true;
-			return IRQ_WAKE_THREAD;
-		}
-	}
-
-	return IRQ_HANDLED;
-}
-
-static int tegra_cec_adap_enable(struct cec_adapter *adap, bool enable)
-{
-	struct tegra_cec *cec = adap->priv;
-
-	cec->rx_buf_cnt = 0;
-	cec->tx_buf_cnt = 0;
-	cec->tx_buf_cur = 0;
-
-	cec_write(cec, TEGRA_CEC_HW_CONTROL, 0);
-	cec_write(cec, TEGRA_CEC_INT_MASK, 0);
-	cec_write(cec, TEGRA_CEC_INT_STAT, 0xffffffff);
-	cec_write(cec, TEGRA_CEC_SW_CONTROL, 0);
-
-	if (!enable)
-		return 0;
-
-	cec_write(cec, TEGRA_CEC_INPUT_FILTER, (1U << 31) | 0x20);
-
-	cec_write(cec, TEGRA_CEC_RX_TIMING_0,
-		  (0x7a << TEGRA_CEC_RX_TIM0_START_BIT_MAX_LO_TIME_SHIFT) |
-		  (0x6d << TEGRA_CEC_RX_TIM0_START_BIT_MIN_LO_TIME_SHIFT) |
-		  (0x93 << TEGRA_CEC_RX_TIM0_START_BIT_MAX_DURATION_SHIFT) |
-		  (0x86 << TEGRA_CEC_RX_TIM0_START_BIT_MIN_DURATION_SHIFT));
-
-	cec_write(cec, TEGRA_CEC_RX_TIMING_1,
-		  (0x35 << TEGRA_CEC_RX_TIM1_DATA_BIT_MAX_LO_TIME_SHIFT) |
-		  (0x21 << TEGRA_CEC_RX_TIM1_DATA_BIT_SAMPLE_TIME_SHIFT) |
-		  (0x56 << TEGRA_CEC_RX_TIM1_DATA_BIT_MAX_DURATION_SHIFT) |
-		  (0x40 << TEGRA_CEC_RX_TIM1_DATA_BIT_MIN_DURATION_SHIFT));
-
-	cec_write(cec, TEGRA_CEC_RX_TIMING_2,
-		  (0x50 << TEGRA_CEC_RX_TIM2_END_OF_BLOCK_TIME_SHIFT));
-
-	cec_write(cec, TEGRA_CEC_TX_TIMING_0,
-		  (0x74 << TEGRA_CEC_TX_TIM0_START_BIT_LO_TIME_SHIFT) |
-		  (0x8d << TEGRA_CEC_TX_TIM0_START_BIT_DURATION_SHIFT) |
-		  (0x08 << TEGRA_CEC_TX_TIM0_BUS_XITION_TIME_SHIFT) |
-		  (0x71 << TEGRA_CEC_TX_TIM0_BUS_ERROR_LO_TIME_SHIFT));
-
-	cec_write(cec, TEGRA_CEC_TX_TIMING_1,
-		  (0x2f << TEGRA_CEC_TX_TIM1_LO_DATA_BIT_LO_TIME_SHIFT) |
-		  (0x13 << TEGRA_CEC_TX_TIM1_HI_DATA_BIT_LO_TIME_SHIFT) |
-		  (0x4b << TEGRA_CEC_TX_TIM1_DATA_BIT_DURATION_SHIFT) |
-		  (0x21 << TEGRA_CEC_TX_TIM1_ACK_NAK_BIT_SAMPLE_TIME_SHIFT));
-
-	cec_write(cec, TEGRA_CEC_TX_TIMING_2,
-		  (0x07 << TEGRA_CEC_TX_TIM2_BUS_IDLE_TIME_ADDITIONAL_FRAME_SHIFT) |
-		  (0x05 << TEGRA_CEC_TX_TIM2_BUS_IDLE_TIME_NEW_FRAME_SHIFT) |
-		  (0x03 << TEGRA_CEC_TX_TIM2_BUS_IDLE_TIME_RETRY_FRAME_SHIFT));
-
-	cec_write(cec, TEGRA_CEC_INT_MASK,
-		  TEGRA_CEC_INT_MASK_TX_REGISTER_UNDERRUN |
-		  TEGRA_CEC_INT_MASK_TX_FRAME_OR_BLOCK_NAKD |
-		  TEGRA_CEC_INT_MASK_TX_ARBITRATION_FAILED |
-		  TEGRA_CEC_INT_MASK_TX_BUS_ANOMALY_DETECTED |
-		  TEGRA_CEC_INT_MASK_TX_FRAME_TRANSMITTED |
-		  TEGRA_CEC_INT_MASK_RX_REGISTER_FULL |
-		  TEGRA_CEC_INT_MASK_RX_START_BIT_DETECTED);
-
-	cec_write(cec, TEGRA_CEC_HW_CONTROL, TEGRA_CEC_HWCTRL_TX_RX_MODE);
-	return 0;
-}
-
-static int tegra_cec_adap_log_addr(struct cec_adapter *adap, u8 logical_addr)
-{
-	struct tegra_cec *cec = adap->priv;
-	u32 state = cec_read(cec, TEGRA_CEC_HW_CONTROL);
-
-	if (logical_addr == CEC_LOG_ADDR_INVALID)
-		state &= ~TEGRA_CEC_HWCTRL_RX_LADDR_MASK;
-	else
-		state |= TEGRA_CEC_HWCTRL_RX_LADDR((1 << logical_addr));
-
-	cec_write(cec, TEGRA_CEC_HW_CONTROL, state);
-	return 0;
-}
-
-static int tegra_cec_adap_monitor_all_enable(struct cec_adapter *adap,
-					     bool enable)
-{
-	struct tegra_cec *cec = adap->priv;
-	u32 reg = cec_read(cec, TEGRA_CEC_HW_CONTROL);
-
-	if (enable)
-		reg |= TEGRA_CEC_HWCTRL_RX_SNOOP;
-	else
-		reg &= ~TEGRA_CEC_HWCTRL_RX_SNOOP;
-	cec_write(cec, TEGRA_CEC_HW_CONTROL, reg);
-	return 0;
-}
-
-static int tegra_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
-				   u32 signal_free_time_ms, struct cec_msg *msg)
-{
-	bool retry_xfer = signal_free_time_ms == CEC_SIGNAL_FREE_TIME_RETRY;
-	struct tegra_cec *cec = adap->priv;
-	unsigned int i;
-	u32 mode = 0;
-	u32 mask;
-
-	if (cec_msg_is_broadcast(msg))
-		mode = TEGRA_CEC_TX_REG_BCAST;
-
-	cec->tx_buf_cur = 0;
-	cec->tx_buf_cnt = msg->len;
-
-	for (i = 0; i < msg->len; i++) {
-		cec->tx_buf[i] = mode | msg->msg[i];
-		if (i == 0)
-			cec->tx_buf[i] |= TEGRA_CEC_TX_REG_START_BIT;
-		if (i == msg->len - 1)
-			cec->tx_buf[i] |= TEGRA_CEC_TX_REG_EOM;
-		if (i == 0 && retry_xfer)
-			cec->tx_buf[i] |= TEGRA_CEC_TX_REG_RETRY;
-	}
-
-	mask = cec_read(cec, TEGRA_CEC_INT_MASK);
-	cec_write(cec, TEGRA_CEC_INT_MASK,
-		  mask | TEGRA_CEC_INT_MASK_TX_REGISTER_EMPTY);
-
-	return 0;
-}
-
-static const struct cec_adap_ops tegra_cec_ops = {
-	.adap_enable = tegra_cec_adap_enable,
-	.adap_log_addr = tegra_cec_adap_log_addr,
-	.adap_transmit = tegra_cec_adap_transmit,
-	.adap_monitor_all_enable = tegra_cec_adap_monitor_all_enable,
-};
-
-static int tegra_cec_probe(struct platform_device *pdev)
-{
-	struct device *hdmi_dev;
-	struct tegra_cec *cec;
-	struct resource *res;
-	int ret = 0;
-
-	hdmi_dev = cec_notifier_parse_hdmi_phandle(&pdev->dev);
-
-	if (IS_ERR(hdmi_dev))
-		return PTR_ERR(hdmi_dev);
-
-	cec = devm_kzalloc(&pdev->dev, sizeof(struct tegra_cec), GFP_KERNEL);
-
-	if (!cec)
-		return -ENOMEM;
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-
-	if (!res) {
-		dev_err(&pdev->dev,
-			"Unable to allocate resources for device\n");
-		return -EBUSY;
-	}
-
-	if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res),
-		pdev->name)) {
-		dev_err(&pdev->dev,
-			"Unable to request mem region for device\n");
-		return -EBUSY;
-	}
-
-	cec->tegra_cec_irq = platform_get_irq(pdev, 0);
-
-	if (cec->tegra_cec_irq <= 0)
-		return -EBUSY;
-
-	cec->cec_base = devm_ioremap(&pdev->dev, res->start,
-					     resource_size(res));
-
-	if (!cec->cec_base) {
-		dev_err(&pdev->dev, "Unable to grab IOs for device\n");
-		return -EBUSY;
-	}
-
-	cec->clk = devm_clk_get(&pdev->dev, "cec");
-
-	if (IS_ERR_OR_NULL(cec->clk)) {
-		dev_err(&pdev->dev, "Can't get clock for CEC\n");
-		return -ENOENT;
-	}
-
-	clk_prepare_enable(cec->clk);
-
-	/* set context info. */
-	cec->dev = &pdev->dev;
-
-	platform_set_drvdata(pdev, cec);
-
-	ret = devm_request_threaded_irq(&pdev->dev, cec->tegra_cec_irq,
-		tegra_cec_irq_handler, tegra_cec_irq_thread_handler,
-		0, "cec_irq", &pdev->dev);
-
-	if (ret) {
-		dev_err(&pdev->dev,
-			"Unable to request interrupt for device\n");
-		goto err_clk;
-	}
-
-	cec->adap = cec_allocate_adapter(&tegra_cec_ops, cec, TEGRA_CEC_NAME,
-			CEC_CAP_DEFAULTS | CEC_CAP_MONITOR_ALL |
-			CEC_CAP_CONNECTOR_INFO,
-			CEC_MAX_LOG_ADDRS);
-	if (IS_ERR(cec->adap)) {
-		ret = -ENOMEM;
-		dev_err(&pdev->dev, "Couldn't create cec adapter\n");
-		goto err_clk;
-	}
-
-	cec->notifier = cec_notifier_cec_adap_register(hdmi_dev, NULL,
-						       cec->adap);
-	if (!cec->notifier) {
-		ret = -ENOMEM;
-		goto err_adapter;
-	}
-
-	ret = cec_register_adapter(cec->adap, &pdev->dev);
-	if (ret) {
-		dev_err(&pdev->dev, "Couldn't register device\n");
-		goto err_notifier;
-	}
-
-	return 0;
-
-err_notifier:
-	cec_notifier_cec_adap_unregister(cec->notifier, cec->adap);
-err_adapter:
-	cec_delete_adapter(cec->adap);
-err_clk:
-	clk_disable_unprepare(cec->clk);
-	return ret;
-}
-
-static int tegra_cec_remove(struct platform_device *pdev)
-{
-	struct tegra_cec *cec = platform_get_drvdata(pdev);
-
-	clk_disable_unprepare(cec->clk);
-
-	cec_notifier_cec_adap_unregister(cec->notifier, cec->adap);
-	cec_unregister_adapter(cec->adap);
-
-	return 0;
-}
-
-#ifdef CONFIG_PM
-static int tegra_cec_suspend(struct platform_device *pdev, pm_message_t state)
-{
-	struct tegra_cec *cec = platform_get_drvdata(pdev);
-
-	clk_disable_unprepare(cec->clk);
-
-	dev_notice(&pdev->dev, "suspended\n");
-	return 0;
-}
-
-static int tegra_cec_resume(struct platform_device *pdev)
-{
-	struct tegra_cec *cec = platform_get_drvdata(pdev);
-
-	dev_notice(&pdev->dev, "Resuming\n");
-
-	clk_prepare_enable(cec->clk);
-
-	return 0;
-}
-#endif
-
-static const struct of_device_id tegra_cec_of_match[] = {
-	{ .compatible = "nvidia,tegra114-cec", },
-	{ .compatible = "nvidia,tegra124-cec", },
-	{ .compatible = "nvidia,tegra210-cec", },
-	{},
-};
-
-static struct platform_driver tegra_cec_driver = {
-	.driver = {
-		.name = TEGRA_CEC_NAME,
-		.of_match_table = of_match_ptr(tegra_cec_of_match),
-	},
-	.probe = tegra_cec_probe,
-	.remove = tegra_cec_remove,
-
-#ifdef CONFIG_PM
-	.suspend = tegra_cec_suspend,
-	.resume = tegra_cec_resume,
-#endif
-};
-
-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/tegra-cec/tegra_cec.h b/drivers/media/platform/tegra-cec/tegra_cec.h
deleted file mode 100644
index 8c370be38e1e..000000000000
--- a/drivers/media/platform/tegra-cec/tegra_cec.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Tegra CEC register definitions
- *
- * The original 3.10 CEC driver using a custom API:
- *
- * Copyright (c) 2012-2015, NVIDIA CORPORATION.  All rights reserved.
- *
- * Conversion to the CEC framework and to the mainline kernel:
- *
- * Copyright 2016-2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#ifndef TEGRA_CEC_H
-#define TEGRA_CEC_H
-
-/* CEC registers */
-#define TEGRA_CEC_SW_CONTROL	0x000
-#define TEGRA_CEC_HW_CONTROL	0x004
-#define TEGRA_CEC_INPUT_FILTER	0x008
-#define TEGRA_CEC_TX_REGISTER	0x010
-#define TEGRA_CEC_RX_REGISTER	0x014
-#define TEGRA_CEC_RX_TIMING_0	0x018
-#define TEGRA_CEC_RX_TIMING_1	0x01c
-#define TEGRA_CEC_RX_TIMING_2	0x020
-#define TEGRA_CEC_TX_TIMING_0	0x024
-#define TEGRA_CEC_TX_TIMING_1	0x028
-#define TEGRA_CEC_TX_TIMING_2	0x02c
-#define TEGRA_CEC_INT_STAT	0x030
-#define TEGRA_CEC_INT_MASK	0x034
-#define TEGRA_CEC_HW_DEBUG_RX	0x038
-#define TEGRA_CEC_HW_DEBUG_TX	0x03c
-
-#define TEGRA_CEC_HWCTRL_RX_LADDR_MASK				0x7fff
-#define TEGRA_CEC_HWCTRL_RX_LADDR(x)	\
-	((x) & TEGRA_CEC_HWCTRL_RX_LADDR_MASK)
-#define TEGRA_CEC_HWCTRL_RX_SNOOP				BIT(15)
-#define TEGRA_CEC_HWCTRL_RX_NAK_MODE				BIT(16)
-#define TEGRA_CEC_HWCTRL_TX_NAK_MODE				BIT(24)
-#define TEGRA_CEC_HWCTRL_FAST_SIM_MODE				BIT(30)
-#define TEGRA_CEC_HWCTRL_TX_RX_MODE				BIT(31)
-
-#define TEGRA_CEC_INPUT_FILTER_MODE				BIT(31)
-#define TEGRA_CEC_INPUT_FILTER_FIFO_LENGTH_SHIFT		0
-
-#define TEGRA_CEC_TX_REG_DATA_SHIFT				0
-#define TEGRA_CEC_TX_REG_EOM					BIT(8)
-#define TEGRA_CEC_TX_REG_BCAST					BIT(12)
-#define TEGRA_CEC_TX_REG_START_BIT				BIT(16)
-#define TEGRA_CEC_TX_REG_RETRY					BIT(17)
-
-#define TEGRA_CEC_RX_REGISTER_SHIFT				0
-#define TEGRA_CEC_RX_REGISTER_EOM				BIT(8)
-#define TEGRA_CEC_RX_REGISTER_ACK				BIT(9)
-
-#define TEGRA_CEC_RX_TIM0_START_BIT_MAX_LO_TIME_SHIFT		0
-#define TEGRA_CEC_RX_TIM0_START_BIT_MIN_LO_TIME_SHIFT		8
-#define TEGRA_CEC_RX_TIM0_START_BIT_MAX_DURATION_SHIFT		16
-#define TEGRA_CEC_RX_TIM0_START_BIT_MIN_DURATION_SHIFT		24
-
-#define TEGRA_CEC_RX_TIM1_DATA_BIT_MAX_LO_TIME_SHIFT		0
-#define TEGRA_CEC_RX_TIM1_DATA_BIT_SAMPLE_TIME_SHIFT		8
-#define TEGRA_CEC_RX_TIM1_DATA_BIT_MAX_DURATION_SHIFT		16
-#define TEGRA_CEC_RX_TIM1_DATA_BIT_MIN_DURATION_SHIFT		24
-
-#define TEGRA_CEC_RX_TIM2_END_OF_BLOCK_TIME_SHIFT		0
-
-#define TEGRA_CEC_TX_TIM0_START_BIT_LO_TIME_SHIFT		0
-#define TEGRA_CEC_TX_TIM0_START_BIT_DURATION_SHIFT		8
-#define TEGRA_CEC_TX_TIM0_BUS_XITION_TIME_SHIFT			16
-#define TEGRA_CEC_TX_TIM0_BUS_ERROR_LO_TIME_SHIFT		24
-
-#define TEGRA_CEC_TX_TIM1_LO_DATA_BIT_LO_TIME_SHIFT		0
-#define TEGRA_CEC_TX_TIM1_HI_DATA_BIT_LO_TIME_SHIFT		8
-#define TEGRA_CEC_TX_TIM1_DATA_BIT_DURATION_SHIFT		16
-#define TEGRA_CEC_TX_TIM1_ACK_NAK_BIT_SAMPLE_TIME_SHIFT		24
-
-#define TEGRA_CEC_TX_TIM2_BUS_IDLE_TIME_ADDITIONAL_FRAME_SHIFT	0
-#define TEGRA_CEC_TX_TIM2_BUS_IDLE_TIME_NEW_FRAME_SHIFT		4
-#define TEGRA_CEC_TX_TIM2_BUS_IDLE_TIME_RETRY_FRAME_SHIFT	8
-
-#define TEGRA_CEC_INT_STAT_TX_REGISTER_EMPTY			BIT(0)
-#define TEGRA_CEC_INT_STAT_TX_REGISTER_UNDERRUN			BIT(1)
-#define TEGRA_CEC_INT_STAT_TX_FRAME_OR_BLOCK_NAKD		BIT(2)
-#define TEGRA_CEC_INT_STAT_TX_ARBITRATION_FAILED		BIT(3)
-#define TEGRA_CEC_INT_STAT_TX_BUS_ANOMALY_DETECTED		BIT(4)
-#define TEGRA_CEC_INT_STAT_TX_FRAME_TRANSMITTED			BIT(5)
-#define TEGRA_CEC_INT_STAT_RX_REGISTER_FULL			BIT(8)
-#define TEGRA_CEC_INT_STAT_RX_REGISTER_OVERRUN			BIT(9)
-#define TEGRA_CEC_INT_STAT_RX_START_BIT_DETECTED		BIT(10)
-#define TEGRA_CEC_INT_STAT_RX_BUS_ANOMALY_DETECTED		BIT(11)
-#define TEGRA_CEC_INT_STAT_RX_BUS_ERROR_DETECTED		BIT(12)
-#define TEGRA_CEC_INT_STAT_FILTERED_RX_DATA_PIN_TRANSITION_H2L	BIT(13)
-#define TEGRA_CEC_INT_STAT_FILTERED_RX_DATA_PIN_TRANSITION_L2H	BIT(14)
-
-#define TEGRA_CEC_INT_MASK_TX_REGISTER_EMPTY			BIT(0)
-#define TEGRA_CEC_INT_MASK_TX_REGISTER_UNDERRUN			BIT(1)
-#define TEGRA_CEC_INT_MASK_TX_FRAME_OR_BLOCK_NAKD		BIT(2)
-#define TEGRA_CEC_INT_MASK_TX_ARBITRATION_FAILED		BIT(3)
-#define TEGRA_CEC_INT_MASK_TX_BUS_ANOMALY_DETECTED		BIT(4)
-#define TEGRA_CEC_INT_MASK_TX_FRAME_TRANSMITTED			BIT(5)
-#define TEGRA_CEC_INT_MASK_RX_REGISTER_FULL			BIT(8)
-#define TEGRA_CEC_INT_MASK_RX_REGISTER_OVERRUN			BIT(9)
-#define TEGRA_CEC_INT_MASK_RX_START_BIT_DETECTED		BIT(10)
-#define TEGRA_CEC_INT_MASK_RX_BUS_ANOMALY_DETECTED		BIT(11)
-#define TEGRA_CEC_INT_MASK_RX_BUS_ERROR_DETECTED		BIT(12)
-#define TEGRA_CEC_INT_MASK_FILTERED_RX_DATA_PIN_TRANSITION_H2L	BIT(13)
-#define TEGRA_CEC_INT_MASK_FILTERED_RX_DATA_PIN_TRANSITION_L2H	BIT(14)
-
-#define TEGRA_CEC_HW_DEBUG_TX_DURATION_COUNT_SHIFT		0
-#define TEGRA_CEC_HW_DEBUG_TX_TXBIT_COUNT_SHIFT			17
-#define TEGRA_CEC_HW_DEBUG_TX_STATE_SHIFT			21
-#define TEGRA_CEC_HW_DEBUG_TX_FORCELOOUT			BIT(25)
-#define TEGRA_CEC_HW_DEBUG_TX_TXDATABIT_SAMPLE_TIMER		BIT(26)
-
-#endif /* TEGRA_CEC_H */
diff --git a/drivers/media/platform/ti-vpe/cal.c b/drivers/media/platform/ti-vpe/cal.c
index 6c8f3702eac0..49204872e711 100644
--- a/drivers/media/platform/ti-vpe/cal.c
+++ b/drivers/media/platform/ti-vpe/cal.c
@@ -6,6 +6,7 @@
  * Benoit Parrot, <bparrot@ti.com>
  */
 
+#include <linux/clk.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/ioctl.h>
@@ -340,6 +341,7 @@ static const struct cal_data am654_cal_data = {
  * all instances.
  */
 struct cal_dev {
+	struct clk		*fclk;
 	int			irq;
 	void __iomem		*base;
 	struct resource		*res;
@@ -412,6 +414,8 @@ struct cal_ctx {
 	struct cal_buffer	*cur_frm;
 	/* Pointer pointing to next v4l2_buffer */
 	struct cal_buffer	*next_frm;
+
+	bool dma_act;
 };
 
 static const struct cal_fmt *find_format_by_pix(struct cal_ctx *ctx,
@@ -643,36 +647,12 @@ static void i913_errata(struct cal_dev *dev, unsigned int port)
 {
 	u32 reg10 = reg_read(dev->cc[port], CAL_CSI2_PHY_REG10);
 
-	set_field(&reg10, CAL_CSI2_PHY_REG0_HSCLOCKCONFIG_DISABLE,
-		  CAL_CSI2_PHY_REG10_I933_LDO_DISABLE_MASK);
+	set_field(&reg10, 1, CAL_CSI2_PHY_REG10_I933_LDO_DISABLE_MASK);
 
 	cal_dbg(1, dev, "CSI2_%d_REG10 = 0x%08x\n", port, reg10);
 	reg_write(dev->cc[port], CAL_CSI2_PHY_REG10, reg10);
 }
 
-static int cal_runtime_get(struct cal_dev *dev)
-{
-	int r;
-
-	r = pm_runtime_get_sync(&dev->pdev->dev);
-
-	if (dev->flags & DRA72_CAL_PRE_ES2_LDO_DISABLE) {
-		/*
-		 * Apply errata on both port eveytime we (re-)enable
-		 * the clock
-		 */
-		i913_errata(dev, 0);
-		i913_errata(dev, 1);
-	}
-
-	return r;
-}
-
-static inline void cal_runtime_put(struct cal_dev *dev)
-{
-	pm_runtime_put_sync(&dev->pdev->dev);
-}
-
 static void cal_quickdump_regs(struct cal_dev *dev)
 {
 	cal_info(dev, "CAL Registers @ 0x%pa:\n", &dev->res->start);
@@ -704,16 +684,31 @@ static void cal_quickdump_regs(struct cal_dev *dev)
  */
 static void enable_irqs(struct cal_ctx *ctx)
 {
+	u32 val;
+
+	const u32 cio_err_mask =
+		CAL_CSI2_COMPLEXIO_IRQ_LANE_ERRORS_MASK |
+		CAL_CSI2_COMPLEXIO_IRQ_FIFO_OVR_MASK |
+		CAL_CSI2_COMPLEXIO_IRQ_SHORT_PACKET_MASK |
+		CAL_CSI2_COMPLEXIO_IRQ_ECC_NO_CORRECTION_MASK;
+
+	/* Enable CIO error irqs */
+	reg_write(ctx->dev, CAL_HL_IRQENABLE_SET(1),
+		  CAL_HL_IRQ_CIO_MASK(ctx->csi2_port));
+	reg_write(ctx->dev, CAL_CSI2_COMPLEXIO_IRQENABLE(ctx->csi2_port),
+		  cio_err_mask);
+
+	/* Always enable OCPO error */
+	reg_write(ctx->dev, CAL_HL_IRQENABLE_SET(1), CAL_HL_IRQ_OCPO_ERR_MASK);
+
 	/* Enable IRQ_WDMA_END 0/1 */
-	reg_write_field(ctx->dev,
-			CAL_HL_IRQENABLE_SET(2),
-			CAL_HL_IRQ_ENABLE,
-			CAL_HL_IRQ_MASK(ctx->csi2_port));
+	val = 0;
+	set_field(&val, 1, CAL_HL_IRQ_MASK(ctx->csi2_port));
+	reg_write(ctx->dev, CAL_HL_IRQENABLE_SET(2), val);
 	/* Enable IRQ_WDMA_START 0/1 */
-	reg_write_field(ctx->dev,
-			CAL_HL_IRQENABLE_SET(3),
-			CAL_HL_IRQ_ENABLE,
-			CAL_HL_IRQ_MASK(ctx->csi2_port));
+	val = 0;
+	set_field(&val, 1, CAL_HL_IRQ_MASK(ctx->csi2_port));
+	reg_write(ctx->dev, CAL_HL_IRQENABLE_SET(3), val);
 	/* Todo: Add VC_IRQ and CSI2_COMPLEXIO_IRQ handling */
 	reg_write(ctx->dev, CAL_CSI2_VC_IRQENABLE(1), 0xFF000000);
 }
@@ -722,24 +717,59 @@ static void disable_irqs(struct cal_ctx *ctx)
 {
 	u32 val;
 
+	/* Disable CIO error irqs */
+	reg_write(ctx->dev, CAL_HL_IRQENABLE_CLR(1),
+		  CAL_HL_IRQ_CIO_MASK(ctx->csi2_port));
+	reg_write(ctx->dev, CAL_CSI2_COMPLEXIO_IRQENABLE(ctx->csi2_port),
+		  0);
+
 	/* Disable IRQ_WDMA_END 0/1 */
 	val = 0;
-	set_field(&val, CAL_HL_IRQ_CLEAR, CAL_HL_IRQ_MASK(ctx->csi2_port));
+	set_field(&val, 1, CAL_HL_IRQ_MASK(ctx->csi2_port));
 	reg_write(ctx->dev, CAL_HL_IRQENABLE_CLR(2), val);
 	/* Disable IRQ_WDMA_START 0/1 */
 	val = 0;
-	set_field(&val, CAL_HL_IRQ_CLEAR, CAL_HL_IRQ_MASK(ctx->csi2_port));
+	set_field(&val, 1, CAL_HL_IRQ_MASK(ctx->csi2_port));
 	reg_write(ctx->dev, CAL_HL_IRQENABLE_CLR(3), val);
 	/* Todo: Add VC_IRQ and CSI2_COMPLEXIO_IRQ handling */
 	reg_write(ctx->dev, CAL_CSI2_VC_IRQENABLE(1), 0);
 }
 
+static void csi2_cio_power(struct cal_ctx *ctx, bool enable)
+{
+	u32 target_state;
+	unsigned int i;
+
+	target_state = enable ? CAL_CSI2_COMPLEXIO_CFG_PWR_CMD_STATE_ON :
+		       CAL_CSI2_COMPLEXIO_CFG_PWR_CMD_STATE_OFF;
+
+	reg_write_field(ctx->dev, CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port),
+			target_state, CAL_CSI2_COMPLEXIO_CFG_PWR_CMD_MASK);
+
+	for (i = 0; i < 10; i++) {
+		u32 current_state;
+
+		current_state = reg_read_field(ctx->dev,
+					       CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port),
+					       CAL_CSI2_COMPLEXIO_CFG_PWR_STATUS_MASK);
+
+		if (current_state == target_state)
+			break;
+
+		usleep_range(1000, 1100);
+	}
+
+	if (i == 10)
+		ctx_err(ctx, "Failed to power %s complexio\n",
+			enable ? "up" : "down");
+}
+
 static void csi2_phy_config(struct cal_ctx *ctx);
 
 static void csi2_phy_init(struct cal_ctx *ctx)
 {
-	int i;
 	u32 val;
+	u32 sscounter;
 
 	/* Steps
 	 *  1. Configure D-PHY mode and enable required lanes
@@ -762,66 +792,90 @@ static void csi2_phy_init(struct cal_ctx *ctx)
 	camerarx_phy_enable(ctx);
 
 	/* 2. Reset complex IO - Do not wait for reset completion */
-	val = reg_read(ctx->dev, CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port));
-	set_field(&val, CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL_OPERATIONAL,
-		  CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL_MASK);
-	reg_write(ctx->dev, CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port), val);
+	reg_write_field(ctx->dev, CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port),
+			CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL_OPERATIONAL,
+			CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL_MASK);
 	ctx_dbg(3, ctx, "CAL_CSI2_COMPLEXIO_CFG(%d) = 0x%08x De-assert Complex IO Reset\n",
 		ctx->csi2_port,
 		reg_read(ctx->dev, CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port)));
 
-	/* Dummy read to allow SCP to complete */
-	val = reg_read(ctx->dev, CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port));
+	/* Dummy read to allow SCP reset to complete */
+	reg_read(ctx->cc, CAL_CSI2_PHY_REG0);
 
 	/* 3.A. Program Phy Timing Parameters */
 	csi2_phy_config(ctx);
 
 	/* 3.B. Program Stop States */
+	/*
+	 * The stop-state-counter is based on fclk cycles, and we always use
+	 * the x16 and x4 settings, so stop-state-timeout =
+	 * fclk-cycle * 16 * 4 * counter.
+	 *
+	 * Stop-state-timeout must be more than 100us as per CSI2 spec, so we
+	 * calculate a timeout that's 100us (rounding up).
+	 */
+	sscounter = DIV_ROUND_UP(clk_get_rate(ctx->dev->fclk), 10000 *  16 * 4);
+
 	val = reg_read(ctx->dev, CAL_CSI2_TIMING(ctx->csi2_port));
-	set_field(&val, CAL_GEN_ENABLE,
-		  CAL_CSI2_TIMING_STOP_STATE_X16_IO1_MASK);
-	set_field(&val, CAL_GEN_DISABLE,
-		  CAL_CSI2_TIMING_STOP_STATE_X4_IO1_MASK);
-	set_field(&val, 407, CAL_CSI2_TIMING_STOP_STATE_COUNTER_IO1_MASK);
+	set_field(&val, 1, CAL_CSI2_TIMING_STOP_STATE_X16_IO1_MASK);
+	set_field(&val, 1, CAL_CSI2_TIMING_STOP_STATE_X4_IO1_MASK);
+	set_field(&val, sscounter, CAL_CSI2_TIMING_STOP_STATE_COUNTER_IO1_MASK);
 	reg_write(ctx->dev, CAL_CSI2_TIMING(ctx->csi2_port), val);
 	ctx_dbg(3, ctx, "CAL_CSI2_TIMING(%d) = 0x%08x Stop States\n",
 		ctx->csi2_port,
 		reg_read(ctx->dev, CAL_CSI2_TIMING(ctx->csi2_port)));
 
 	/* 4. Force FORCERXMODE */
-	val = reg_read(ctx->dev, CAL_CSI2_TIMING(ctx->csi2_port));
-	set_field(&val, CAL_GEN_ENABLE,
-		  CAL_CSI2_TIMING_FORCE_RX_MODE_IO1_MASK);
-	reg_write(ctx->dev, CAL_CSI2_TIMING(ctx->csi2_port), val);
+	reg_write_field(ctx->dev, CAL_CSI2_TIMING(ctx->csi2_port),
+			1, CAL_CSI2_TIMING_FORCE_RX_MODE_IO1_MASK);
 	ctx_dbg(3, ctx, "CAL_CSI2_TIMING(%d) = 0x%08x Force RXMODE\n",
 		ctx->csi2_port,
 		reg_read(ctx->dev, CAL_CSI2_TIMING(ctx->csi2_port)));
 
 	/* E. Power up the PHY using the complex IO */
-	val = reg_read(ctx->dev, CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port));
-	set_field(&val, CAL_CSI2_COMPLEXIO_CFG_PWR_CMD_STATE_ON,
-		  CAL_CSI2_COMPLEXIO_CFG_PWR_CMD_MASK);
-	reg_write(ctx->dev, CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port), val);
+	csi2_cio_power(ctx, true);
+}
 
-	/* F. Wait for power up completion */
-	for (i = 0; i < 10; i++) {
+static void csi2_wait_complexio_reset(struct cal_ctx *ctx)
+{
+	unsigned long timeout;
+
+	timeout = jiffies + msecs_to_jiffies(750);
+	while (time_before(jiffies, timeout)) {
 		if (reg_read_field(ctx->dev,
 				   CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port),
-				   CAL_CSI2_COMPLEXIO_CFG_PWR_STATUS_MASK) ==
-		    CAL_CSI2_COMPLEXIO_CFG_PWR_STATUS_STATE_ON)
+				   CAL_CSI2_COMPLEXIO_CFG_RESET_DONE_MASK) ==
+		    CAL_CSI2_COMPLEXIO_CFG_RESET_DONE_RESETCOMPLETED)
 			break;
-		usleep_range(1000, 1100);
+		usleep_range(500, 5000);
 	}
-	ctx_dbg(3, ctx, "CAL_CSI2_COMPLEXIO_CFG(%d) = 0x%08x Powered UP %s\n",
-		ctx->csi2_port,
-		reg_read(ctx->dev, CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port)),
-		(i >= 10) ? "(timeout)" : "");
+
+	if (reg_read_field(ctx->dev, CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port),
+			   CAL_CSI2_COMPLEXIO_CFG_RESET_DONE_MASK) !=
+			   CAL_CSI2_COMPLEXIO_CFG_RESET_DONE_RESETCOMPLETED)
+		ctx_err(ctx, "Timeout waiting for Complex IO reset done\n");
 }
 
-static void csi2_wait_for_phy(struct cal_ctx *ctx)
+static void csi2_wait_stop_state(struct cal_ctx *ctx)
 {
-	int i;
+	unsigned long timeout;
 
+	timeout = jiffies + msecs_to_jiffies(750);
+	while (time_before(jiffies, timeout)) {
+		if (reg_read_field(ctx->dev,
+				   CAL_CSI2_TIMING(ctx->csi2_port),
+				   CAL_CSI2_TIMING_FORCE_RX_MODE_IO1_MASK) == 0)
+			break;
+		usleep_range(500, 5000);
+	}
+
+	if (reg_read_field(ctx->dev, CAL_CSI2_TIMING(ctx->csi2_port),
+			   CAL_CSI2_TIMING_FORCE_RX_MODE_IO1_MASK) != 0)
+		ctx_err(ctx, "Timeout waiting for stop state\n");
+}
+
+static void csi2_wait_for_phy(struct cal_ctx *ctx)
+{
 	/* Steps
 	 *  2. Wait for completion of reset
 	 *          Note if the external sensor is not sending byte clock,
@@ -832,32 +886,10 @@ static void csi2_wait_for_phy(struct cal_ctx *ctx)
 	 */
 
 	/* 2. Wait for reset completion */
-	for (i = 0; i < 250; i++) {
-		if (reg_read_field(ctx->dev,
-				   CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port),
-				   CAL_CSI2_COMPLEXIO_CFG_RESET_DONE_MASK) ==
-		    CAL_CSI2_COMPLEXIO_CFG_RESET_DONE_RESETCOMPLETED)
-			break;
-		usleep_range(1000, 1100);
-	}
-	ctx_dbg(3, ctx, "CAL_CSI2_COMPLEXIO_CFG(%d) = 0x%08x Complex IO Reset Done (%d) %s\n",
-		ctx->csi2_port,
-		reg_read(ctx->dev, CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port)), i,
-		(i >= 250) ? "(timeout)" : "");
+	csi2_wait_complexio_reset(ctx);
 
 	/* 4. G. Wait for all enabled lane to reach stop state */
-	for (i = 0; i < 10; i++) {
-		if (reg_read_field(ctx->dev,
-				   CAL_CSI2_TIMING(ctx->csi2_port),
-				   CAL_CSI2_TIMING_FORCE_RX_MODE_IO1_MASK) ==
-		    CAL_GEN_DISABLE)
-			break;
-		usleep_range(1000, 1100);
-	}
-	ctx_dbg(3, ctx, "CAL_CSI2_TIMING(%d) = 0x%08x Stop State Reached %s\n",
-		ctx->csi2_port,
-		reg_read(ctx->dev, CAL_CSI2_TIMING(ctx->csi2_port)),
-		(i >= 10) ? "(timeout)" : "");
+	csi2_wait_stop_state(ctx);
 
 	ctx_dbg(1, ctx, "CSI2_%d_REG1 = 0x%08x (Bit(31,28) should be set!)\n",
 		(ctx->csi2_port - 1), reg_read(ctx->cc, CAL_CSI2_PHY_REG1));
@@ -866,33 +898,13 @@ static void csi2_wait_for_phy(struct cal_ctx *ctx)
 static void csi2_phy_deinit(struct cal_ctx *ctx)
 {
 	int i;
-	u32 val;
 
-	/* Power down the PHY using the complex IO */
-	val = reg_read(ctx->dev, CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port));
-	set_field(&val, CAL_CSI2_COMPLEXIO_CFG_PWR_CMD_STATE_OFF,
-		  CAL_CSI2_COMPLEXIO_CFG_PWR_CMD_MASK);
-	reg_write(ctx->dev, CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port), val);
-
-	/* Wait for power down completion */
-	for (i = 0; i < 10; i++) {
-		if (reg_read_field(ctx->dev,
-				   CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port),
-				   CAL_CSI2_COMPLEXIO_CFG_PWR_STATUS_MASK) ==
-		    CAL_CSI2_COMPLEXIO_CFG_PWR_STATUS_STATE_OFF)
-			break;
-		usleep_range(1000, 1100);
-	}
-	ctx_dbg(3, ctx, "CAL_CSI2_COMPLEXIO_CFG(%d) = 0x%08x Powered Down %s\n",
-		ctx->csi2_port,
-		reg_read(ctx->dev, CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port)),
-		(i >= 10) ? "(timeout)" : "");
+	csi2_cio_power(ctx, false);
 
 	/* Assert Comple IO Reset */
-	val = reg_read(ctx->dev, CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port));
-	set_field(&val, CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL,
-		  CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL_MASK);
-	reg_write(ctx->dev, CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port), val);
+	reg_write_field(ctx->dev, CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port),
+			CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL,
+			CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL_MASK);
 
 	/* Wait for power down completion */
 	for (i = 0; i < 10; i++) {
@@ -942,14 +954,15 @@ static void csi2_lane_config(struct cal_ctx *ctx)
 
 static void csi2_ppi_enable(struct cal_ctx *ctx)
 {
+	reg_write(ctx->dev, CAL_CSI2_PPI_CTRL(ctx->csi2_port), BIT(3));
 	reg_write_field(ctx->dev, CAL_CSI2_PPI_CTRL(ctx->csi2_port),
-			CAL_GEN_ENABLE, CAL_CSI2_PPI_CTRL_IF_EN_MASK);
+			1, CAL_CSI2_PPI_CTRL_IF_EN_MASK);
 }
 
 static void csi2_ppi_disable(struct cal_ctx *ctx)
 {
 	reg_write_field(ctx->dev, CAL_CSI2_PPI_CTRL(ctx->csi2_port),
-			CAL_GEN_DISABLE, CAL_CSI2_PPI_CTRL_IF_EN_MASK);
+			0, CAL_CSI2_PPI_CTRL_IF_EN_MASK);
 }
 
 static void csi2_ctx_config(struct cal_ctx *ctx)
@@ -969,8 +982,7 @@ static void csi2_ctx_config(struct cal_ctx *ctx)
 	set_field(&val, 0x1, CAL_CSI2_CTX_DT_MASK);
 	/* Virtual Channel from the CSI2 sensor usually 0! */
 	set_field(&val, ctx->virtual_channel, CAL_CSI2_CTX_VC_MASK);
-	/* NUM_LINES_PER_FRAME => 0 means auto detect */
-	set_field(&val, 0, CAL_CSI2_CTX_LINES_MASK);
+	set_field(&val, ctx->v_fmt.fmt.pix.height, CAL_CSI2_CTX_LINES_MASK);
 	set_field(&val, CAL_CSI2_CTX_ATT_PIX, CAL_CSI2_CTX_ATT_MASK);
 	set_field(&val, CAL_CSI2_CTX_PACK_MODE_LINE,
 		  CAL_CSI2_CTX_PACK_MODE_MASK);
@@ -1024,7 +1036,7 @@ static void pix_proc_config(struct cal_ctx *ctx)
 	set_field(&val, CAL_PIX_PROC_DPCME_BYPASS, CAL_PIX_PROC_DPCME_MASK);
 	set_field(&val, pack, CAL_PIX_PROC_PACK_MASK);
 	set_field(&val, ctx->csi2_port, CAL_PIX_PROC_CPORT_MASK);
-	set_field(&val, CAL_GEN_ENABLE, CAL_PIX_PROC_EN_MASK);
+	set_field(&val, 1, CAL_PIX_PROC_EN_MASK);
 	reg_write(ctx->dev, CAL_PIX_PROC(ctx->csi2_port), val);
 	ctx_dbg(3, ctx, "CAL_PIX_PROC(%d) = 0x%08x\n", ctx->csi2_port,
 		reg_read(ctx->dev, CAL_PIX_PROC(ctx->csi2_port)));
@@ -1044,7 +1056,7 @@ static void cal_wr_dma_config(struct cal_ctx *ctx,
 		  CAL_WR_DMA_CTRL_MODE_MASK);
 	set_field(&val, CAL_WR_DMA_CTRL_PATTERN_LINEAR,
 		  CAL_WR_DMA_CTRL_PATTERN_MASK);
-	set_field(&val, CAL_GEN_ENABLE, CAL_WR_DMA_CTRL_STALL_RD_MASK);
+	set_field(&val, 1, CAL_WR_DMA_CTRL_STALL_RD_MASK);
 	reg_write(ctx->dev, CAL_WR_DMA_CTRL(ctx->csi2_port), val);
 	ctx_dbg(3, ctx, "CAL_WR_DMA_CTRL(%d) = 0x%08x\n", ctx->csi2_port,
 		reg_read(ctx->dev, CAL_WR_DMA_CTRL(ctx->csi2_port)));
@@ -1192,57 +1204,74 @@ static irqreturn_t cal_irq(int irq_cal, void *data)
 	struct cal_dev *dev = (struct cal_dev *)data;
 	struct cal_ctx *ctx;
 	struct cal_dmaqueue *dma_q;
-	u32 irqst2, irqst3;
+	u32 irqst1, irqst2, irqst3;
+
+	irqst1 = reg_read(dev, CAL_HL_IRQSTATUS(1));
+	if (irqst1) {
+		int i;
+
+		reg_write(dev, CAL_HL_IRQSTATUS(1), irqst1);
+
+		if (irqst1 & CAL_HL_IRQ_OCPO_ERR_MASK)
+			dev_err_ratelimited(&dev->pdev->dev, "OCPO ERROR\n");
+
+		for (i = 1; i <= 2; ++i) {
+			if (irqst1 & CAL_HL_IRQ_CIO_MASK(i)) {
+				u32 cio_stat = reg_read(dev,
+							CAL_CSI2_COMPLEXIO_IRQSTATUS(i));
+
+				dev_err_ratelimited(&dev->pdev->dev,
+						    "CIO%d error: %#08x\n", i, cio_stat);
+
+				reg_write(dev, CAL_CSI2_COMPLEXIO_IRQSTATUS(i),
+					  cio_stat);
+			}
+		}
+	}
 
 	/* Check which DMA just finished */
 	irqst2 = reg_read(dev, CAL_HL_IRQSTATUS(2));
 	if (irqst2) {
+		int i;
+
 		/* Clear Interrupt status */
 		reg_write(dev, CAL_HL_IRQSTATUS(2), irqst2);
 
-		/* Need to check both port */
-		if (isportirqset(irqst2, 1)) {
-			ctx = dev->ctx[0];
+		for (i = 1; i <= 2; ++i) {
+			if (isportirqset(irqst2, i)) {
+				ctx = dev->ctx[i - 1];
 
-			if (ctx->cur_frm != ctx->next_frm)
-				cal_process_buffer_complete(ctx);
-		}
+				spin_lock(&ctx->slock);
+				ctx->dma_act = false;
 
-		if (isportirqset(irqst2, 2)) {
-			ctx = dev->ctx[1];
+				if (ctx->cur_frm != ctx->next_frm)
+					cal_process_buffer_complete(ctx);
 
-			if (ctx->cur_frm != ctx->next_frm)
-				cal_process_buffer_complete(ctx);
+				spin_unlock(&ctx->slock);
+			}
 		}
 	}
 
 	/* Check which DMA just started */
 	irqst3 = reg_read(dev, CAL_HL_IRQSTATUS(3));
 	if (irqst3) {
+		int i;
+
 		/* Clear Interrupt status */
 		reg_write(dev, CAL_HL_IRQSTATUS(3), irqst3);
 
-		/* Need to check both port */
-		if (isportirqset(irqst3, 1)) {
-			ctx = dev->ctx[0];
-			dma_q = &ctx->vidq;
-
-			spin_lock(&ctx->slock);
-			if (!list_empty(&dma_q->active) &&
-			    ctx->cur_frm == ctx->next_frm)
-				cal_schedule_next_buffer(ctx);
-			spin_unlock(&ctx->slock);
-		}
-
-		if (isportirqset(irqst3, 2)) {
-			ctx = dev->ctx[1];
-			dma_q = &ctx->vidq;
-
-			spin_lock(&ctx->slock);
-			if (!list_empty(&dma_q->active) &&
-			    ctx->cur_frm == ctx->next_frm)
-				cal_schedule_next_buffer(ctx);
-			spin_unlock(&ctx->slock);
+		for (i = 1; i <= 2; ++i) {
+			if (isportirqset(irqst3, i)) {
+				ctx = dev->ctx[i - 1];
+				dma_q = &ctx->vidq;
+
+				spin_lock(&ctx->slock);
+				ctx->dma_act = true;
+				if (!list_empty(&dma_q->active) &&
+				    ctx->cur_frm == ctx->next_frm)
+					cal_schedule_next_buffer(ctx);
+				spin_unlock(&ctx->slock);
+			}
 		}
 	}
 
@@ -1665,7 +1694,7 @@ static int cal_start_streaming(struct vb2_queue *vq, unsigned int count)
 		goto err;
 	}
 
-	cal_runtime_get(ctx->dev);
+	pm_runtime_get_sync(&ctx->dev->pdev->dev);
 
 	csi2_ctx_config(ctx);
 	pix_proc_config(ctx);
@@ -1680,7 +1709,7 @@ static int cal_start_streaming(struct vb2_queue *vq, unsigned int count)
 	if (ret) {
 		v4l2_subdev_call(ctx->sensor, core, s_power, 0);
 		ctx_err(ctx, "stream on failed in subdev\n");
-		cal_runtime_put(ctx->dev);
+		pm_runtime_put_sync(&ctx->dev->pdev->dev);
 		goto err;
 	}
 
@@ -1711,10 +1740,27 @@ static void cal_stop_streaming(struct vb2_queue *vq)
 	struct cal_ctx *ctx = vb2_get_drv_priv(vq);
 	struct cal_dmaqueue *dma_q = &ctx->vidq;
 	struct cal_buffer *buf, *tmp;
+	unsigned long timeout;
 	unsigned long flags;
 	int ret;
+	bool dma_act;
 
 	csi2_ppi_disable(ctx);
+
+	/* wait for stream and dma to finish */
+	dma_act = true;
+	timeout = jiffies + msecs_to_jiffies(500);
+	while (dma_act && time_before(jiffies, timeout)) {
+		msleep(50);
+
+		spin_lock_irqsave(&ctx->slock, flags);
+		dma_act = ctx->dma_act;
+		spin_unlock_irqrestore(&ctx->slock, flags);
+	}
+
+	if (dma_act)
+		ctx_err(ctx, "failed to disable dma cleanly\n");
+
 	disable_irqs(ctx);
 	csi2_phy_deinit(ctx);
 
@@ -1743,7 +1789,7 @@ static void cal_stop_streaming(struct vb2_queue *vq)
 	ctx->next_frm = NULL;
 	spin_unlock_irqrestore(&ctx->slock, flags);
 
-	cal_runtime_put(ctx->dev);
+	pm_runtime_put_sync(&ctx->dev->pdev->dev);
 }
 
 static const struct vb2_ops cal_video_qops = {
@@ -2223,6 +2269,12 @@ static int cal_probe(struct platform_device *pdev)
 	/* save pdev pointer */
 	dev->pdev = pdev;
 
+	dev->fclk = devm_clk_get(&pdev->dev, "fck");
+	if (IS_ERR(dev->fclk)) {
+		dev_err(&pdev->dev, "cannot get CAL fclk\n");
+		return PTR_ERR(dev->fclk);
+	}
+
 	syscon_camerrx = syscon_regmap_lookup_by_phandle(parent,
 							 "ti,camerrx-control");
 	ret = of_property_read_u32_index(parent, "ti,camerrx-control", 1,
@@ -2296,20 +2348,24 @@ static int cal_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
+	vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
+
 	pm_runtime_enable(&pdev->dev);
 
-	ret = cal_runtime_get(dev);
+	ret = pm_runtime_get_sync(&pdev->dev);
 	if (ret)
 		goto runtime_disable;
 
 	/* Just check we can actually access the module */
 	cal_get_hwinfo(dev);
 
-	cal_runtime_put(dev);
+	pm_runtime_put_sync(&pdev->dev);
 
 	return 0;
 
 runtime_disable:
+	vb2_dma_contig_clear_max_seg_size(&pdev->dev);
+
 	pm_runtime_disable(&pdev->dev);
 	for (i = 0; i < CAL_NUM_CONTEXT; i++) {
 		ctx = dev->ctx[i];
@@ -2333,7 +2389,7 @@ static int cal_remove(struct platform_device *pdev)
 
 	cal_dbg(1, dev, "Removing %s\n", CAL_MODULE_NAME);
 
-	cal_runtime_get(dev);
+	pm_runtime_get_sync(&pdev->dev);
 
 	for (i = 0; i < CAL_NUM_CONTEXT; i++) {
 		ctx = dev->ctx[i];
@@ -2349,9 +2405,11 @@ static int cal_remove(struct platform_device *pdev)
 		}
 	}
 
-	cal_runtime_put(dev);
+	pm_runtime_put_sync(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 
+	vb2_dma_contig_clear_max_seg_size(&pdev->dev);
+
 	return 0;
 }
 
@@ -2378,11 +2436,32 @@ static const struct of_device_id cal_of_match[] = {
 MODULE_DEVICE_TABLE(of, cal_of_match);
 #endif
 
+static int cal_runtime_resume(struct device *dev)
+{
+	struct cal_dev *caldev = dev_get_drvdata(dev);
+
+	if (caldev->flags & DRA72_CAL_PRE_ES2_LDO_DISABLE) {
+		/*
+		 * Apply errata on both port everytime we (re-)enable
+		 * the clock
+		 */
+		i913_errata(caldev, 0);
+		i913_errata(caldev, 1);
+	}
+
+	return 0;
+}
+
+static const struct dev_pm_ops cal_pm_ops = {
+	.runtime_resume = cal_runtime_resume,
+};
+
 static struct platform_driver cal_pdrv = {
 	.probe		= cal_probe,
 	.remove		= cal_remove,
 	.driver		= {
 		.name	= CAL_MODULE_NAME,
+		.pm	= &cal_pm_ops,
 		.of_match_table = of_match_ptr(cal_of_match),
 	},
 };
diff --git a/drivers/media/platform/ti-vpe/cal_regs.h b/drivers/media/platform/ti-vpe/cal_regs.h
index 0b76d1186074..ac54a2fe7bb6 100644
--- a/drivers/media/platform/ti-vpe/cal_regs.h
+++ b/drivers/media/platform/ti-vpe/cal_regs.h
@@ -100,15 +100,6 @@
 /* CAL Control Module Core Camerrx Control register offsets */
 #define CM_CTRL_CORE_CAMERRX_CONTROL	0x000
 
-/*********************************************************************
-* Generic value used in various field below
-*********************************************************************/
-
-#define CAL_GEN_DISABLE			0
-#define CAL_GEN_ENABLE			1
-#define CAL_GEN_FALSE			0
-#define CAL_GEN_TRUE			1
-
 /*********************************************************************
 * Field Definition Macros
 *********************************************************************/
@@ -151,12 +142,11 @@
 #define CAL_HL_IRQ_EOI_LINE_NUMBER_EOI0			0
 
 #define CAL_HL_IRQ_MASK(m)			BIT((m) - 1)
-#define CAL_HL_IRQ_NOACTION				0x0
-#define CAL_HL_IRQ_ENABLE				0x1
-#define CAL_HL_IRQ_CLEAR				0x1
-#define CAL_HL_IRQ_DISABLED				0x0
-#define CAL_HL_IRQ_ENABLED				0x1
-#define CAL_HL_IRQ_PENDING				0x1
+
+#define CAL_HL_IRQ_OCPO_ERR_MASK		BIT(6)
+
+#define CAL_HL_IRQ_CIO_MASK(i)			BIT(16 + ((i) - 1) * 8)
+#define CAL_HL_IRQ_VC_MASK(i)			BIT(17 + ((i) - 1) * 8)
 
 #define CAL_PIX_PROC_EN_MASK			BIT(0)
 #define CAL_PIX_PROC_EXTRACT_MASK		GENMASK(4, 1)
@@ -414,6 +404,7 @@
 #define CAL_CSI2_COMPLEXIO_IRQ_ERRCONTROL3_MASK		BIT(17)
 #define CAL_CSI2_COMPLEXIO_IRQ_ERRCONTROL4_MASK		BIT(18)
 #define CAL_CSI2_COMPLEXIO_IRQ_ERRCONTROL5_MASK		BIT(19)
+#define CAL_CSI2_COMPLEXIO_IRQ_LANE_ERRORS_MASK		GENMASK(19, 0)
 #define CAL_CSI2_COMPLEXIO_IRQ_STATEULPM1_MASK		BIT(20)
 #define CAL_CSI2_COMPLEXIO_IRQ_STATEULPM2_MASK		BIT(21)
 #define CAL_CSI2_COMPLEXIO_IRQ_STATEULPM3_MASK		BIT(22)
diff --git a/drivers/media/platform/vicodec/Kconfig b/drivers/media/platform/vicodec/Kconfig
deleted file mode 100644
index 89456665cb16..000000000000
--- a/drivers/media/platform/vicodec/Kconfig
+++ /dev/null
@@ -1,13 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-config VIDEO_VICODEC
-	tristate "Virtual Codec Driver"
-	depends on VIDEO_DEV && VIDEO_V4L2
-	select VIDEOBUF2_VMALLOC
-	select V4L2_MEM2MEM_DEV
-	help
-	  Driver for a Virtual Codec
-
-	  This driver can be compared to the vim2m driver for emulating
-	  a video device node that exposes an emulated hardware codec.
-
-	  When in doubt, say N.
diff --git a/drivers/media/platform/vicodec/Makefile b/drivers/media/platform/vicodec/Makefile
deleted file mode 100644
index 01bf7e9308a6..000000000000
--- a/drivers/media/platform/vicodec/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-vicodec-objs := vicodec-core.o codec-fwht.o codec-v4l2-fwht.o
-
-obj-$(CONFIG_VIDEO_VICODEC) += vicodec.o
diff --git a/drivers/media/platform/vicodec/codec-fwht.c b/drivers/media/platform/vicodec/codec-fwht.c
deleted file mode 100644
index 31faf319e508..000000000000
--- a/drivers/media/platform/vicodec/codec-fwht.c
+++ /dev/null
@@ -1,958 +0,0 @@
-// SPDX-License-Identifier: LGPL-2.1+
-/*
- * Copyright 2016 Tom aan de Wiel
- * Copyright 2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- *
- * 8x8 Fast Walsh Hadamard Transform in sequency order based on the paper:
- *
- * A Recursive Algorithm for Sequency-Ordered Fast Walsh Transforms,
- * R.D. Brown, 1977
- */
-
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include "codec-fwht.h"
-
-#define OVERFLOW_BIT BIT(14)
-
-/*
- * Note: bit 0 of the header must always be 0. Otherwise it cannot
- * be guaranteed that the magic 8 byte sequence (see below) can
- * never occur in the rlc output.
- */
-#define PFRAME_BIT BIT(15)
-#define DUPS_MASK 0x1ffe
-
-#define PBLOCK 0
-#define IBLOCK 1
-
-#define ALL_ZEROS 15
-
-static const uint8_t zigzag[64] = {
-	0,
-	1,  8,
-	2,  9, 16,
-	3, 10, 17, 24,
-	4, 11, 18, 25, 32,
-	5, 12, 19, 26, 33, 40,
-	6, 13, 20, 27, 34, 41, 48,
-	7, 14, 21, 28, 35, 42, 49, 56,
-	15, 22, 29, 36, 43, 50, 57,
-	23, 30, 37, 44, 51, 58,
-	31, 38, 45, 52, 59,
-	39, 46, 53, 60,
-	47, 54, 61,
-	55, 62,
-	63,
-};
-
-/*
- * noinline_for_stack to work around
- * https://bugs.llvm.org/show_bug.cgi?id=38809
- */
-static int noinline_for_stack
-rlc(const s16 *in, __be16 *output, int blocktype)
-{
-	s16 block[8 * 8];
-	s16 *wp = block;
-	int i = 0;
-	int x, y;
-	int ret = 0;
-
-	/* read in block from framebuffer */
-	int lastzero_run = 0;
-	int to_encode;
-
-	for (y = 0; y < 8; y++) {
-		for (x = 0; x < 8; x++) {
-			*wp = in[x + y * 8];
-			wp++;
-		}
-	}
-
-	/* keep track of amount of trailing zeros */
-	for (i = 63; i >= 0 && !block[zigzag[i]]; i--)
-		lastzero_run++;
-
-	*output++ = (blocktype == PBLOCK ? htons(PFRAME_BIT) : 0);
-	ret++;
-
-	to_encode = 8 * 8 - (lastzero_run > 14 ? lastzero_run : 0);
-
-	i = 0;
-	while (i < to_encode) {
-		int cnt = 0;
-		int tmp;
-
-		/* count leading zeros */
-		while ((tmp = block[zigzag[i]]) == 0 && cnt < 14) {
-			cnt++;
-			i++;
-			if (i == to_encode) {
-				cnt--;
-				break;
-			}
-		}
-		/* 4 bits for run, 12 for coefficient (quantization by 4) */
-		*output++ = htons((cnt | tmp << 4));
-		i++;
-		ret++;
-	}
-	if (lastzero_run > 14) {
-		*output = htons(ALL_ZEROS | 0);
-		ret++;
-	}
-
-	return ret;
-}
-
-/*
- * This function will worst-case increase rlc_in by 65*2 bytes:
- * one s16 value for the header and 8 * 8 coefficients of type s16.
- */
-static noinline_for_stack u16
-derlc(const __be16 **rlc_in, s16 *dwht_out, const __be16 *end_of_input)
-{
-	/* header */
-	const __be16 *input = *rlc_in;
-	u16 stat;
-	int dec_count = 0;
-	s16 block[8 * 8 + 16];
-	s16 *wp = block;
-	int i;
-
-	if (input > end_of_input)
-		return OVERFLOW_BIT;
-	stat = ntohs(*input++);
-
-	/*
-	 * Now de-compress, it expands one byte to up to 15 bytes
-	 * (or fills the remainder of the 64 bytes with zeroes if it
-	 * is the last byte to expand).
-	 *
-	 * So block has to be 8 * 8 + 16 bytes, the '+ 16' is to
-	 * allow for overflow if the incoming data was malformed.
-	 */
-	while (dec_count < 8 * 8) {
-		s16 in;
-		int length;
-		int coeff;
-
-		if (input > end_of_input)
-			return OVERFLOW_BIT;
-		in = ntohs(*input++);
-		length = in & 0xf;
-		coeff = in >> 4;
-
-		/* fill remainder with zeros */
-		if (length == 15) {
-			for (i = 0; i < 64 - dec_count; i++)
-				*wp++ = 0;
-			break;
-		}
-
-		for (i = 0; i < length; i++)
-			*wp++ = 0;
-		*wp++ = coeff;
-		dec_count += length + 1;
-	}
-
-	wp = block;
-
-	for (i = 0; i < 64; i++) {
-		int pos = zigzag[i];
-		int y = pos / 8;
-		int x = pos % 8;
-
-		dwht_out[x + y * 8] = *wp++;
-	}
-	*rlc_in = input;
-	return stat;
-}
-
-static const int quant_table[] = {
-	2, 2, 2, 2, 2, 2,  2,  2,
-	2, 2, 2, 2, 2, 2,  2,  2,
-	2, 2, 2, 2, 2, 2,  2,  3,
-	2, 2, 2, 2, 2, 2,  3,  6,
-	2, 2, 2, 2, 2, 3,  6,  6,
-	2, 2, 2, 2, 3, 6,  6,  6,
-	2, 2, 2, 3, 6, 6,  6,  6,
-	2, 2, 3, 6, 6, 6,  6,  8,
-};
-
-static const int quant_table_p[] = {
-	3, 3, 3, 3, 3, 3,  3,  3,
-	3, 3, 3, 3, 3, 3,  3,  3,
-	3, 3, 3, 3, 3, 3,  3,  3,
-	3, 3, 3, 3, 3, 3,  3,  6,
-	3, 3, 3, 3, 3, 3,  6,  6,
-	3, 3, 3, 3, 3, 6,  6,  9,
-	3, 3, 3, 3, 6, 6,  9,  9,
-	3, 3, 3, 6, 6, 9,  9,  10,
-};
-
-static void quantize_intra(s16 *coeff, s16 *de_coeff, u16 qp)
-{
-	const int *quant = quant_table;
-	int i, j;
-
-	for (j = 0; j < 8; j++) {
-		for (i = 0; i < 8; i++, quant++, coeff++, de_coeff++) {
-			*coeff >>= *quant;
-			if (*coeff >= -qp && *coeff <= qp)
-				*coeff = *de_coeff = 0;
-			else
-				*de_coeff = *coeff << *quant;
-		}
-	}
-}
-
-static void dequantize_intra(s16 *coeff)
-{
-	const int *quant = quant_table;
-	int i, j;
-
-	for (j = 0; j < 8; j++)
-		for (i = 0; i < 8; i++, quant++, coeff++)
-			*coeff <<= *quant;
-}
-
-static void quantize_inter(s16 *coeff, s16 *de_coeff, u16 qp)
-{
-	const int *quant = quant_table_p;
-	int i, j;
-
-	for (j = 0; j < 8; j++) {
-		for (i = 0; i < 8; i++, quant++, coeff++, de_coeff++) {
-			*coeff >>= *quant;
-			if (*coeff >= -qp && *coeff <= qp)
-				*coeff = *de_coeff = 0;
-			else
-				*de_coeff = *coeff << *quant;
-		}
-	}
-}
-
-static void dequantize_inter(s16 *coeff)
-{
-	const int *quant = quant_table_p;
-	int i, j;
-
-	for (j = 0; j < 8; j++)
-		for (i = 0; i < 8; i++, quant++, coeff++)
-			*coeff <<= *quant;
-}
-
-static void noinline_for_stack fwht(const u8 *block, s16 *output_block,
-				    unsigned int stride,
-				    unsigned int input_step, bool intra)
-{
-	/* we'll need more than 8 bits for the transformed coefficients */
-	s32 workspace1[8], workspace2[8];
-	const u8 *tmp = block;
-	s16 *out = output_block;
-	int add = intra ? 256 : 0;
-	unsigned int i;
-
-	/* stage 1 */
-	for (i = 0; i < 8; i++, tmp += stride, out += 8) {
-		switch (input_step) {
-		case 1:
-			workspace1[0]  = tmp[0] + tmp[1] - add;
-			workspace1[1]  = tmp[0] - tmp[1];
-
-			workspace1[2]  = tmp[2] + tmp[3] - add;
-			workspace1[3]  = tmp[2] - tmp[3];
-
-			workspace1[4]  = tmp[4] + tmp[5] - add;
-			workspace1[5]  = tmp[4] - tmp[5];
-
-			workspace1[6]  = tmp[6] + tmp[7] - add;
-			workspace1[7]  = tmp[6] - tmp[7];
-			break;
-		case 2:
-			workspace1[0]  = tmp[0] + tmp[2] - add;
-			workspace1[1]  = tmp[0] - tmp[2];
-
-			workspace1[2]  = tmp[4] + tmp[6] - add;
-			workspace1[3]  = tmp[4] - tmp[6];
-
-			workspace1[4]  = tmp[8] + tmp[10] - add;
-			workspace1[5]  = tmp[8] - tmp[10];
-
-			workspace1[6]  = tmp[12] + tmp[14] - add;
-			workspace1[7]  = tmp[12] - tmp[14];
-			break;
-		case 3:
-			workspace1[0]  = tmp[0] + tmp[3] - add;
-			workspace1[1]  = tmp[0] - tmp[3];
-
-			workspace1[2]  = tmp[6] + tmp[9] - add;
-			workspace1[3]  = tmp[6] - tmp[9];
-
-			workspace1[4]  = tmp[12] + tmp[15] - add;
-			workspace1[5]  = tmp[12] - tmp[15];
-
-			workspace1[6]  = tmp[18] + tmp[21] - add;
-			workspace1[7]  = tmp[18] - tmp[21];
-			break;
-		default:
-			workspace1[0]  = tmp[0] + tmp[4] - add;
-			workspace1[1]  = tmp[0] - tmp[4];
-
-			workspace1[2]  = tmp[8] + tmp[12] - add;
-			workspace1[3]  = tmp[8] - tmp[12];
-
-			workspace1[4]  = tmp[16] + tmp[20] - add;
-			workspace1[5]  = tmp[16] - tmp[20];
-
-			workspace1[6]  = tmp[24] + tmp[28] - add;
-			workspace1[7]  = tmp[24] - tmp[28];
-			break;
-		}
-
-		/* stage 2 */
-		workspace2[0] = workspace1[0] + workspace1[2];
-		workspace2[1] = workspace1[0] - workspace1[2];
-		workspace2[2] = workspace1[1] - workspace1[3];
-		workspace2[3] = workspace1[1] + workspace1[3];
-
-		workspace2[4] = workspace1[4] + workspace1[6];
-		workspace2[5] = workspace1[4] - workspace1[6];
-		workspace2[6] = workspace1[5] - workspace1[7];
-		workspace2[7] = workspace1[5] + workspace1[7];
-
-		/* stage 3 */
-		out[0] = workspace2[0] + workspace2[4];
-		out[1] = workspace2[0] - workspace2[4];
-		out[2] = workspace2[1] - workspace2[5];
-		out[3] = workspace2[1] + workspace2[5];
-		out[4] = workspace2[2] + workspace2[6];
-		out[5] = workspace2[2] - workspace2[6];
-		out[6] = workspace2[3] - workspace2[7];
-		out[7] = workspace2[3] + workspace2[7];
-	}
-
-	out = output_block;
-
-	for (i = 0; i < 8; i++, out++) {
-		/* stage 1 */
-		workspace1[0]  = out[0] + out[1 * 8];
-		workspace1[1]  = out[0] - out[1 * 8];
-
-		workspace1[2]  = out[2 * 8] + out[3 * 8];
-		workspace1[3]  = out[2 * 8] - out[3 * 8];
-
-		workspace1[4]  = out[4 * 8] + out[5 * 8];
-		workspace1[5]  = out[4 * 8] - out[5 * 8];
-
-		workspace1[6]  = out[6 * 8] + out[7 * 8];
-		workspace1[7]  = out[6 * 8] - out[7 * 8];
-
-		/* stage 2 */
-		workspace2[0] = workspace1[0] + workspace1[2];
-		workspace2[1] = workspace1[0] - workspace1[2];
-		workspace2[2] = workspace1[1] - workspace1[3];
-		workspace2[3] = workspace1[1] + workspace1[3];
-
-		workspace2[4] = workspace1[4] + workspace1[6];
-		workspace2[5] = workspace1[4] - workspace1[6];
-		workspace2[6] = workspace1[5] - workspace1[7];
-		workspace2[7] = workspace1[5] + workspace1[7];
-		/* stage 3 */
-		out[0 * 8] = workspace2[0] + workspace2[4];
-		out[1 * 8] = workspace2[0] - workspace2[4];
-		out[2 * 8] = workspace2[1] - workspace2[5];
-		out[3 * 8] = workspace2[1] + workspace2[5];
-		out[4 * 8] = workspace2[2] + workspace2[6];
-		out[5 * 8] = workspace2[2] - workspace2[6];
-		out[6 * 8] = workspace2[3] - workspace2[7];
-		out[7 * 8] = workspace2[3] + workspace2[7];
-	}
-}
-
-/*
- * Not the nicest way of doing it, but P-blocks get twice the range of
- * that of the I-blocks. Therefore we need a type bigger than 8 bits.
- * Furthermore values can be negative... This is just a version that
- * works with 16 signed data
- */
-static void noinline_for_stack
-fwht16(const s16 *block, s16 *output_block, int stride, int intra)
-{
-	/* we'll need more than 8 bits for the transformed coefficients */
-	s32 workspace1[8], workspace2[8];
-	const s16 *tmp = block;
-	s16 *out = output_block;
-	int i;
-
-	for (i = 0; i < 8; i++, tmp += stride, out += 8) {
-		/* stage 1 */
-		workspace1[0]  = tmp[0] + tmp[1];
-		workspace1[1]  = tmp[0] - tmp[1];
-
-		workspace1[2]  = tmp[2] + tmp[3];
-		workspace1[3]  = tmp[2] - tmp[3];
-
-		workspace1[4]  = tmp[4] + tmp[5];
-		workspace1[5]  = tmp[4] - tmp[5];
-
-		workspace1[6]  = tmp[6] + tmp[7];
-		workspace1[7]  = tmp[6] - tmp[7];
-
-		/* stage 2 */
-		workspace2[0] = workspace1[0] + workspace1[2];
-		workspace2[1] = workspace1[0] - workspace1[2];
-		workspace2[2] = workspace1[1] - workspace1[3];
-		workspace2[3] = workspace1[1] + workspace1[3];
-
-		workspace2[4] = workspace1[4] + workspace1[6];
-		workspace2[5] = workspace1[4] - workspace1[6];
-		workspace2[6] = workspace1[5] - workspace1[7];
-		workspace2[7] = workspace1[5] + workspace1[7];
-
-		/* stage 3 */
-		out[0] = workspace2[0] + workspace2[4];
-		out[1] = workspace2[0] - workspace2[4];
-		out[2] = workspace2[1] - workspace2[5];
-		out[3] = workspace2[1] + workspace2[5];
-		out[4] = workspace2[2] + workspace2[6];
-		out[5] = workspace2[2] - workspace2[6];
-		out[6] = workspace2[3] - workspace2[7];
-		out[7] = workspace2[3] + workspace2[7];
-	}
-
-	out = output_block;
-
-	for (i = 0; i < 8; i++, out++) {
-		/* stage 1 */
-		workspace1[0]  = out[0] + out[1*8];
-		workspace1[1]  = out[0] - out[1*8];
-
-		workspace1[2]  = out[2*8] + out[3*8];
-		workspace1[3]  = out[2*8] - out[3*8];
-
-		workspace1[4]  = out[4*8] + out[5*8];
-		workspace1[5]  = out[4*8] - out[5*8];
-
-		workspace1[6]  = out[6*8] + out[7*8];
-		workspace1[7]  = out[6*8] - out[7*8];
-
-		/* stage 2 */
-		workspace2[0] = workspace1[0] + workspace1[2];
-		workspace2[1] = workspace1[0] - workspace1[2];
-		workspace2[2] = workspace1[1] - workspace1[3];
-		workspace2[3] = workspace1[1] + workspace1[3];
-
-		workspace2[4] = workspace1[4] + workspace1[6];
-		workspace2[5] = workspace1[4] - workspace1[6];
-		workspace2[6] = workspace1[5] - workspace1[7];
-		workspace2[7] = workspace1[5] + workspace1[7];
-
-		/* stage 3 */
-		out[0*8] = workspace2[0] + workspace2[4];
-		out[1*8] = workspace2[0] - workspace2[4];
-		out[2*8] = workspace2[1] - workspace2[5];
-		out[3*8] = workspace2[1] + workspace2[5];
-		out[4*8] = workspace2[2] + workspace2[6];
-		out[5*8] = workspace2[2] - workspace2[6];
-		out[6*8] = workspace2[3] - workspace2[7];
-		out[7*8] = workspace2[3] + workspace2[7];
-	}
-}
-
-static noinline_for_stack void
-ifwht(const s16 *block, s16 *output_block, int intra)
-{
-	/*
-	 * we'll need more than 8 bits for the transformed coefficients
-	 * use native unit of cpu
-	 */
-	int workspace1[8], workspace2[8];
-	int inter = intra ? 0 : 1;
-	const s16 *tmp = block;
-	s16 *out = output_block;
-	int i;
-
-	for (i = 0; i < 8; i++, tmp += 8, out += 8) {
-		/* stage 1 */
-		workspace1[0]  = tmp[0] + tmp[1];
-		workspace1[1]  = tmp[0] - tmp[1];
-
-		workspace1[2]  = tmp[2] + tmp[3];
-		workspace1[3]  = tmp[2] - tmp[3];
-
-		workspace1[4]  = tmp[4] + tmp[5];
-		workspace1[5]  = tmp[4] - tmp[5];
-
-		workspace1[6]  = tmp[6] + tmp[7];
-		workspace1[7]  = tmp[6] - tmp[7];
-
-		/* stage 2 */
-		workspace2[0] = workspace1[0] + workspace1[2];
-		workspace2[1] = workspace1[0] - workspace1[2];
-		workspace2[2] = workspace1[1] - workspace1[3];
-		workspace2[3] = workspace1[1] + workspace1[3];
-
-		workspace2[4] = workspace1[4] + workspace1[6];
-		workspace2[5] = workspace1[4] - workspace1[6];
-		workspace2[6] = workspace1[5] - workspace1[7];
-		workspace2[7] = workspace1[5] + workspace1[7];
-
-		/* stage 3 */
-		out[0] = workspace2[0] + workspace2[4];
-		out[1] = workspace2[0] - workspace2[4];
-		out[2] = workspace2[1] - workspace2[5];
-		out[3] = workspace2[1] + workspace2[5];
-		out[4] = workspace2[2] + workspace2[6];
-		out[5] = workspace2[2] - workspace2[6];
-		out[6] = workspace2[3] - workspace2[7];
-		out[7] = workspace2[3] + workspace2[7];
-	}
-
-	out = output_block;
-
-	for (i = 0; i < 8; i++, out++) {
-		/* stage 1 */
-		workspace1[0]  = out[0] + out[1 * 8];
-		workspace1[1]  = out[0] - out[1 * 8];
-
-		workspace1[2]  = out[2 * 8] + out[3 * 8];
-		workspace1[3]  = out[2 * 8] - out[3 * 8];
-
-		workspace1[4]  = out[4 * 8] + out[5 * 8];
-		workspace1[5]  = out[4 * 8] - out[5 * 8];
-
-		workspace1[6]  = out[6 * 8] + out[7 * 8];
-		workspace1[7]  = out[6 * 8] - out[7 * 8];
-
-		/* stage 2 */
-		workspace2[0] = workspace1[0] + workspace1[2];
-		workspace2[1] = workspace1[0] - workspace1[2];
-		workspace2[2] = workspace1[1] - workspace1[3];
-		workspace2[3] = workspace1[1] + workspace1[3];
-
-		workspace2[4] = workspace1[4] + workspace1[6];
-		workspace2[5] = workspace1[4] - workspace1[6];
-		workspace2[6] = workspace1[5] - workspace1[7];
-		workspace2[7] = workspace1[5] + workspace1[7];
-
-		/* stage 3 */
-		if (inter) {
-			int d;
-
-			out[0 * 8] = workspace2[0] + workspace2[4];
-			out[1 * 8] = workspace2[0] - workspace2[4];
-			out[2 * 8] = workspace2[1] - workspace2[5];
-			out[3 * 8] = workspace2[1] + workspace2[5];
-			out[4 * 8] = workspace2[2] + workspace2[6];
-			out[5 * 8] = workspace2[2] - workspace2[6];
-			out[6 * 8] = workspace2[3] - workspace2[7];
-			out[7 * 8] = workspace2[3] + workspace2[7];
-
-			for (d = 0; d < 8; d++)
-				out[8 * d] >>= 6;
-		} else {
-			int d;
-
-			out[0 * 8] = workspace2[0] + workspace2[4];
-			out[1 * 8] = workspace2[0] - workspace2[4];
-			out[2 * 8] = workspace2[1] - workspace2[5];
-			out[3 * 8] = workspace2[1] + workspace2[5];
-			out[4 * 8] = workspace2[2] + workspace2[6];
-			out[5 * 8] = workspace2[2] - workspace2[6];
-			out[6 * 8] = workspace2[3] - workspace2[7];
-			out[7 * 8] = workspace2[3] + workspace2[7];
-
-			for (d = 0; d < 8; d++) {
-				out[8 * d] >>= 6;
-				out[8 * d] += 128;
-			}
-		}
-	}
-}
-
-static void fill_encoder_block(const u8 *input, s16 *dst,
-			       unsigned int stride, unsigned int input_step)
-{
-	int i, j;
-
-	for (i = 0; i < 8; i++) {
-		for (j = 0; j < 8; j++, input += input_step)
-			*dst++ = *input;
-		input += stride - 8 * input_step;
-	}
-}
-
-static int var_intra(const s16 *input)
-{
-	int32_t mean = 0;
-	int32_t ret = 0;
-	const s16 *tmp = input;
-	int i;
-
-	for (i = 0; i < 8 * 8; i++, tmp++)
-		mean += *tmp;
-	mean /= 64;
-	tmp = input;
-	for (i = 0; i < 8 * 8; i++, tmp++)
-		ret += (*tmp - mean) < 0 ? -(*tmp - mean) : (*tmp - mean);
-	return ret;
-}
-
-static int var_inter(const s16 *old, const s16 *new)
-{
-	int32_t ret = 0;
-	int i;
-
-	for (i = 0; i < 8 * 8; i++, old++, new++)
-		ret += (*old - *new) < 0 ? -(*old - *new) : (*old - *new);
-	return ret;
-}
-
-static noinline_for_stack int
-decide_blocktype(const u8 *cur, const u8 *reference, s16 *deltablock,
-		 unsigned int stride, unsigned int input_step)
-{
-	s16 tmp[64];
-	s16 old[64];
-	s16 *work = tmp;
-	unsigned int k, l;
-	int vari;
-	int vard;
-
-	fill_encoder_block(cur, tmp, stride, input_step);
-	fill_encoder_block(reference, old, 8, 1);
-	vari = var_intra(tmp);
-
-	for (k = 0; k < 8; k++) {
-		for (l = 0; l < 8; l++) {
-			*deltablock = *work - *reference;
-			deltablock++;
-			work++;
-			reference++;
-		}
-	}
-	deltablock -= 64;
-	vard = var_inter(old, tmp);
-	return vari <= vard ? IBLOCK : PBLOCK;
-}
-
-static void fill_decoder_block(u8 *dst, const s16 *input, int stride,
-			       unsigned int dst_step)
-{
-	int i, j;
-
-	for (i = 0; i < 8; i++) {
-		for (j = 0; j < 8; j++, input++, dst += dst_step) {
-			if (*input < 0)
-				*dst = 0;
-			else if (*input > 255)
-				*dst = 255;
-			else
-				*dst = *input;
-		}
-		dst += stride - (8 * dst_step);
-	}
-}
-
-static void add_deltas(s16 *deltas, const u8 *ref, int stride,
-		       unsigned int ref_step)
-{
-	int k, l;
-
-	for (k = 0; k < 8; k++) {
-		for (l = 0; l < 8; l++) {
-			*deltas += *ref;
-			ref += ref_step;
-			/*
-			 * Due to quantizing, it might possible that the
-			 * decoded coefficients are slightly out of range
-			 */
-			if (*deltas < 0)
-				*deltas = 0;
-			else if (*deltas > 255)
-				*deltas = 255;
-			deltas++;
-		}
-		ref += stride - (8 * ref_step);
-	}
-}
-
-static u32 encode_plane(u8 *input, u8 *refp, __be16 **rlco, __be16 *rlco_max,
-			struct fwht_cframe *cf, u32 height, u32 width,
-			u32 stride, unsigned int input_step,
-			bool is_intra, bool next_is_intra)
-{
-	u8 *input_start = input;
-	__be16 *rlco_start = *rlco;
-	s16 deltablock[64];
-	__be16 pframe_bit = htons(PFRAME_BIT);
-	u32 encoding = 0;
-	unsigned int last_size = 0;
-	unsigned int i, j;
-
-	width = round_up(width, 8);
-	height = round_up(height, 8);
-
-	for (j = 0; j < height / 8; j++) {
-		input = input_start + j * 8 * stride;
-		for (i = 0; i < width / 8; i++) {
-			/* intra code, first frame is always intra coded. */
-			int blocktype = IBLOCK;
-			unsigned int size;
-
-			if (!is_intra)
-				blocktype = decide_blocktype(input, refp,
-					deltablock, stride, input_step);
-			if (blocktype == IBLOCK) {
-				fwht(input, cf->coeffs, stride, input_step, 1);
-				quantize_intra(cf->coeffs, cf->de_coeffs,
-					       cf->i_frame_qp);
-			} else {
-				/* inter code */
-				encoding |= FWHT_FRAME_PCODED;
-				fwht16(deltablock, cf->coeffs, 8, 0);
-				quantize_inter(cf->coeffs, cf->de_coeffs,
-					       cf->p_frame_qp);
-			}
-			if (!next_is_intra) {
-				ifwht(cf->de_coeffs, cf->de_fwht, blocktype);
-
-				if (blocktype == PBLOCK)
-					add_deltas(cf->de_fwht, refp, 8, 1);
-				fill_decoder_block(refp, cf->de_fwht, 8, 1);
-			}
-
-			input += 8 * input_step;
-			refp += 8 * 8;
-
-			size = rlc(cf->coeffs, *rlco, blocktype);
-			if (last_size == size &&
-			    !memcmp(*rlco + 1, *rlco - size + 1, 2 * size - 2)) {
-				__be16 *last_rlco = *rlco - size;
-				s16 hdr = ntohs(*last_rlco);
-
-				if (!((*last_rlco ^ **rlco) & pframe_bit) &&
-				    (hdr & DUPS_MASK) < DUPS_MASK)
-					*last_rlco = htons(hdr + 2);
-				else
-					*rlco += size;
-			} else {
-				*rlco += size;
-			}
-			if (*rlco >= rlco_max) {
-				encoding |= FWHT_FRAME_UNENCODED;
-				goto exit_loop;
-			}
-			last_size = size;
-		}
-	}
-
-exit_loop:
-	if (encoding & FWHT_FRAME_UNENCODED) {
-		u8 *out = (u8 *)rlco_start;
-		u8 *p;
-
-		input = input_start;
-		/*
-		 * The compressed stream should never contain the magic
-		 * header, so when we copy the YUV data we replace 0xff
-		 * by 0xfe. Since YUV is limited range such values
-		 * shouldn't appear anyway.
-		 */
-		for (j = 0; j < height; j++) {
-			for (i = 0, p = input; i < width; i++, p += input_step)
-				*out++ = (*p == 0xff) ? 0xfe : *p;
-			input += stride;
-		}
-		*rlco = (__be16 *)out;
-		encoding &= ~FWHT_FRAME_PCODED;
-	}
-	return encoding;
-}
-
-u32 fwht_encode_frame(struct fwht_raw_frame *frm,
-		      struct fwht_raw_frame *ref_frm,
-		      struct fwht_cframe *cf,
-		      bool is_intra, bool next_is_intra,
-		      unsigned int width, unsigned int height,
-		      unsigned int stride, unsigned int chroma_stride)
-{
-	unsigned int size = height * width;
-	__be16 *rlco = cf->rlc_data;
-	__be16 *rlco_max;
-	u32 encoding;
-
-	rlco_max = rlco + size / 2 - 256;
-	encoding = encode_plane(frm->luma, ref_frm->luma, &rlco, rlco_max, cf,
-				height, width, stride,
-				frm->luma_alpha_step, is_intra, next_is_intra);
-	if (encoding & FWHT_FRAME_UNENCODED)
-		encoding |= FWHT_LUMA_UNENCODED;
-	encoding &= ~FWHT_FRAME_UNENCODED;
-
-	if (frm->components_num >= 3) {
-		u32 chroma_h = height / frm->height_div;
-		u32 chroma_w = width / frm->width_div;
-		unsigned int chroma_size = chroma_h * chroma_w;
-
-		rlco_max = rlco + chroma_size / 2 - 256;
-		encoding |= encode_plane(frm->cb, ref_frm->cb, &rlco, rlco_max,
-					 cf, chroma_h, chroma_w,
-					 chroma_stride, frm->chroma_step,
-					 is_intra, next_is_intra);
-		if (encoding & FWHT_FRAME_UNENCODED)
-			encoding |= FWHT_CB_UNENCODED;
-		encoding &= ~FWHT_FRAME_UNENCODED;
-		rlco_max = rlco + chroma_size / 2 - 256;
-		encoding |= encode_plane(frm->cr, ref_frm->cr, &rlco, rlco_max,
-					 cf, chroma_h, chroma_w,
-					 chroma_stride, frm->chroma_step,
-					 is_intra, next_is_intra);
-		if (encoding & FWHT_FRAME_UNENCODED)
-			encoding |= FWHT_CR_UNENCODED;
-		encoding &= ~FWHT_FRAME_UNENCODED;
-	}
-
-	if (frm->components_num == 4) {
-		rlco_max = rlco + size / 2 - 256;
-		encoding |= encode_plane(frm->alpha, ref_frm->alpha, &rlco,
-					 rlco_max, cf, height, width,
-					 stride, frm->luma_alpha_step,
-					 is_intra, next_is_intra);
-		if (encoding & FWHT_FRAME_UNENCODED)
-			encoding |= FWHT_ALPHA_UNENCODED;
-		encoding &= ~FWHT_FRAME_UNENCODED;
-	}
-
-	cf->size = (rlco - cf->rlc_data) * sizeof(*rlco);
-	return encoding;
-}
-
-static bool decode_plane(struct fwht_cframe *cf, const __be16 **rlco,
-			 u32 height, u32 width, const u8 *ref, u32 ref_stride,
-			 unsigned int ref_step, u8 *dst,
-			 unsigned int dst_stride, unsigned int dst_step,
-			 bool uncompressed, const __be16 *end_of_rlco_buf)
-{
-	unsigned int copies = 0;
-	s16 copy[8 * 8];
-	u16 stat;
-	unsigned int i, j;
-	bool is_intra = !ref;
-
-	width = round_up(width, 8);
-	height = round_up(height, 8);
-
-	if (uncompressed) {
-		int i;
-
-		if (end_of_rlco_buf + 1 < *rlco + width * height / 2)
-			return false;
-		for (i = 0; i < height; i++) {
-			memcpy(dst, *rlco, width);
-			dst += dst_stride;
-			*rlco += width / 2;
-		}
-		return true;
-	}
-
-	/*
-	 * When decoding each macroblock the rlco pointer will be increased
-	 * by 65 * 2 bytes worst-case.
-	 * To avoid overflow the buffer has to be 65/64th of the actual raw
-	 * image size, just in case someone feeds it malicious data.
-	 */
-	for (j = 0; j < height / 8; j++) {
-		for (i = 0; i < width / 8; i++) {
-			const u8 *refp = ref + j * 8 * ref_stride +
-				i * 8 * ref_step;
-			u8 *dstp = dst + j * 8 * dst_stride + i * 8 * dst_step;
-
-			if (copies) {
-				memcpy(cf->de_fwht, copy, sizeof(copy));
-				if ((stat & PFRAME_BIT) && !is_intra)
-					add_deltas(cf->de_fwht, refp,
-						   ref_stride, ref_step);
-				fill_decoder_block(dstp, cf->de_fwht,
-						   dst_stride, dst_step);
-				copies--;
-				continue;
-			}
-
-			stat = derlc(rlco, cf->coeffs, end_of_rlco_buf);
-			if (stat & OVERFLOW_BIT)
-				return false;
-			if ((stat & PFRAME_BIT) && !is_intra)
-				dequantize_inter(cf->coeffs);
-			else
-				dequantize_intra(cf->coeffs);
-
-			ifwht(cf->coeffs, cf->de_fwht,
-			      ((stat & PFRAME_BIT) && !is_intra) ? 0 : 1);
-
-			copies = (stat & DUPS_MASK) >> 1;
-			if (copies)
-				memcpy(copy, cf->de_fwht, sizeof(copy));
-			if ((stat & PFRAME_BIT) && !is_intra)
-				add_deltas(cf->de_fwht, refp,
-					   ref_stride, ref_step);
-			fill_decoder_block(dstp, cf->de_fwht, dst_stride,
-					   dst_step);
-		}
-	}
-	return true;
-}
-
-bool fwht_decode_frame(struct fwht_cframe *cf, u32 hdr_flags,
-		       unsigned int components_num, unsigned int width,
-		       unsigned int height, const struct fwht_raw_frame *ref,
-		       unsigned int ref_stride, unsigned int ref_chroma_stride,
-		       struct fwht_raw_frame *dst, unsigned int dst_stride,
-		       unsigned int dst_chroma_stride)
-{
-	const __be16 *rlco = cf->rlc_data;
-	const __be16 *end_of_rlco_buf = cf->rlc_data +
-			(cf->size / sizeof(*rlco)) - 1;
-
-	if (!decode_plane(cf, &rlco, height, width, ref->luma, ref_stride,
-			  ref->luma_alpha_step, dst->luma, dst_stride,
-			  dst->luma_alpha_step,
-			  hdr_flags & FWHT_FL_LUMA_IS_UNCOMPRESSED,
-			  end_of_rlco_buf))
-		return false;
-
-	if (components_num >= 3) {
-		u32 h = height;
-		u32 w = width;
-
-		if (!(hdr_flags & FWHT_FL_CHROMA_FULL_HEIGHT))
-			h /= 2;
-		if (!(hdr_flags & FWHT_FL_CHROMA_FULL_WIDTH))
-			w /= 2;
-
-		if (!decode_plane(cf, &rlco, h, w, ref->cb, ref_chroma_stride,
-				  ref->chroma_step, dst->cb, dst_chroma_stride,
-				  dst->chroma_step,
-				  hdr_flags & FWHT_FL_CB_IS_UNCOMPRESSED,
-				  end_of_rlco_buf))
-			return false;
-		if (!decode_plane(cf, &rlco, h, w, ref->cr, ref_chroma_stride,
-				  ref->chroma_step, dst->cr, dst_chroma_stride,
-				  dst->chroma_step,
-				  hdr_flags & FWHT_FL_CR_IS_UNCOMPRESSED,
-				  end_of_rlco_buf))
-			return false;
-	}
-
-	if (components_num == 4)
-		if (!decode_plane(cf, &rlco, height, width, ref->alpha, ref_stride,
-				  ref->luma_alpha_step, dst->alpha, dst_stride,
-				  dst->luma_alpha_step,
-				  hdr_flags & FWHT_FL_ALPHA_IS_UNCOMPRESSED,
-				  end_of_rlco_buf))
-			return false;
-	return true;
-}
diff --git a/drivers/media/platform/vicodec/codec-fwht.h b/drivers/media/platform/vicodec/codec-fwht.h
deleted file mode 100644
index b6fec2b1cbca..000000000000
--- a/drivers/media/platform/vicodec/codec-fwht.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-/*
- * Copyright 2016 Tom aan de Wiel
- * Copyright 2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#ifndef CODEC_FWHT_H
-#define CODEC_FWHT_H
-
-#include <linux/types.h>
-#include <linux/bitops.h>
-#include <asm/byteorder.h>
-
-/*
- * The compressed format consists of a fwht_cframe_hdr struct followed by the
- * compressed frame data. The header contains the size of that data.
- * Each Y, Cb and Cr plane is compressed separately. If the compressed
- * size of each plane becomes larger than the uncompressed size, then
- * that plane is stored uncompressed and the corresponding bit is set
- * in the flags field of the header.
- *
- * Each compressed plane consists of macroblocks and each macroblock
- * is run-length-encoded. Each macroblock starts with a 16 bit value.
- * Bit 15 indicates if this is a P-coded macroblock (1) or not (0).
- * P-coded macroblocks contain a delta against the previous frame.
- *
- * Bits 1-12 contain a number. If non-zero, then this same macroblock
- * repeats that number of times. This results in a high degree of
- * compression for generated images like colorbars.
- *
- * Following this macroblock header the MB coefficients are run-length
- * encoded: the top 12 bits contain the coefficient, the bottom 4 bits
- * tell how many times this coefficient occurs. The value 0xf indicates
- * that the remainder of the macroblock should be filled with zeroes.
- *
- * All 16 and 32 bit values are stored in big-endian (network) order.
- *
- * Each fwht_cframe_hdr starts with an 8 byte magic header that is
- * guaranteed not to occur in the compressed frame data. This header
- * can be used to sync to the next frame.
- *
- * This codec uses the Fast Walsh Hadamard Transform. Tom aan de Wiel
- * developed this as part of a university project, specifically for use
- * with this driver. His project report can be found here:
- *
- * https://hverkuil.home.xs4all.nl/fwht.pdf
- */
-
-/*
- * This is a sequence of 8 bytes with the low 4 bits set to 0xf.
- *
- * This sequence cannot occur in the encoded data
- *
- * Note that these two magic values are symmetrical so endian issues here.
- */
-#define FWHT_MAGIC1 0x4f4f4f4f
-#define FWHT_MAGIC2 0xffffffff
-
-#define FWHT_VERSION 3
-
-/* Set if this is an interlaced format */
-#define FWHT_FL_IS_INTERLACED		BIT(0)
-/* Set if this is a bottom-first (NTSC) interlaced format */
-#define FWHT_FL_IS_BOTTOM_FIRST		BIT(1)
-/* Set if each 'frame' contains just one field */
-#define FWHT_FL_IS_ALTERNATE		BIT(2)
-/*
- * If FWHT_FL_IS_ALTERNATE was set, then this is set if this
- * 'frame' is the bottom field, else it is the top field.
- */
-#define FWHT_FL_IS_BOTTOM_FIELD		BIT(3)
-/* Set if this frame is uncompressed */
-#define FWHT_FL_LUMA_IS_UNCOMPRESSED	BIT(4)
-#define FWHT_FL_CB_IS_UNCOMPRESSED	BIT(5)
-#define FWHT_FL_CR_IS_UNCOMPRESSED	BIT(6)
-#define FWHT_FL_CHROMA_FULL_HEIGHT	BIT(7)
-#define FWHT_FL_CHROMA_FULL_WIDTH	BIT(8)
-#define FWHT_FL_ALPHA_IS_UNCOMPRESSED	BIT(9)
-#define FWHT_FL_I_FRAME			BIT(10)
-
-/* A 4-values flag - the number of components - 1 */
-#define FWHT_FL_COMPONENTS_NUM_MSK	GENMASK(18, 16)
-#define FWHT_FL_COMPONENTS_NUM_OFFSET	16
-
-#define FWHT_FL_PIXENC_MSK	GENMASK(20, 19)
-#define FWHT_FL_PIXENC_OFFSET	19
-#define FWHT_FL_PIXENC_YUV	(1 << FWHT_FL_PIXENC_OFFSET)
-#define FWHT_FL_PIXENC_RGB	(2 << FWHT_FL_PIXENC_OFFSET)
-#define FWHT_FL_PIXENC_HSV	(3 << FWHT_FL_PIXENC_OFFSET)
-
-/*
- * A macro to calculate the needed padding in order to make sure
- * both luma and chroma components resolutions are rounded up to
- * a multiple of 8
- */
-#define vic_round_dim(dim, div) (round_up((dim) / (div), 8) * (div))
-
-struct fwht_cframe_hdr {
-	u32 magic1;
-	u32 magic2;
-	__be32 version;
-	__be32 width, height;
-	__be32 flags;
-	__be32 colorspace;
-	__be32 xfer_func;
-	__be32 ycbcr_enc;
-	__be32 quantization;
-	__be32 size;
-};
-
-struct fwht_cframe {
-	u16 i_frame_qp;
-	u16 p_frame_qp;
-	__be16 *rlc_data;
-	s16 coeffs[8 * 8];
-	s16 de_coeffs[8 * 8];
-	s16 de_fwht[8 * 8];
-	u32 size;
-};
-
-struct fwht_raw_frame {
-	unsigned int width_div;
-	unsigned int height_div;
-	unsigned int luma_alpha_step;
-	unsigned int chroma_step;
-	unsigned int components_num;
-	u8 *buf;
-	u8 *luma, *cb, *cr, *alpha;
-};
-
-#define FWHT_FRAME_PCODED	BIT(0)
-#define FWHT_FRAME_UNENCODED	BIT(1)
-#define FWHT_LUMA_UNENCODED	BIT(2)
-#define FWHT_CB_UNENCODED	BIT(3)
-#define FWHT_CR_UNENCODED	BIT(4)
-#define FWHT_ALPHA_UNENCODED	BIT(5)
-
-u32 fwht_encode_frame(struct fwht_raw_frame *frm,
-		      struct fwht_raw_frame *ref_frm,
-		      struct fwht_cframe *cf,
-		      bool is_intra, bool next_is_intra,
-		      unsigned int width, unsigned int height,
-		      unsigned int stride, unsigned int chroma_stride);
-bool fwht_decode_frame(struct fwht_cframe *cf, u32 hdr_flags,
-		unsigned int components_num, unsigned int width,
-		unsigned int height, const struct fwht_raw_frame *ref,
-		unsigned int ref_stride, unsigned int ref_chroma_stride,
-		struct fwht_raw_frame *dst, unsigned int dst_stride,
-		unsigned int dst_chroma_stride);
-#endif
diff --git a/drivers/media/platform/vicodec/codec-v4l2-fwht.c b/drivers/media/platform/vicodec/codec-v4l2-fwht.c
deleted file mode 100644
index b6e39fbd8ad5..000000000000
--- a/drivers/media/platform/vicodec/codec-v4l2-fwht.c
+++ /dev/null
@@ -1,367 +0,0 @@
-// SPDX-License-Identifier: LGPL-2.1
-/*
- * A V4L2 frontend for the FWHT codec
- *
- * Copyright 2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/videodev2.h>
-#include "codec-v4l2-fwht.h"
-
-static const struct v4l2_fwht_pixfmt_info v4l2_fwht_pixfmts[] = {
-	{ V4L2_PIX_FMT_YUV420,  1, 3, 2, 1, 1, 2, 2, 3, 3, FWHT_FL_PIXENC_YUV},
-	{ V4L2_PIX_FMT_YVU420,  1, 3, 2, 1, 1, 2, 2, 3, 3, FWHT_FL_PIXENC_YUV},
-	{ V4L2_PIX_FMT_YUV422P, 1, 2, 1, 1, 1, 2, 1, 3, 3, FWHT_FL_PIXENC_YUV},
-	{ V4L2_PIX_FMT_NV12,    1, 3, 2, 1, 2, 2, 2, 3, 2, FWHT_FL_PIXENC_YUV},
-	{ V4L2_PIX_FMT_NV21,    1, 3, 2, 1, 2, 2, 2, 3, 2, FWHT_FL_PIXENC_YUV},
-	{ V4L2_PIX_FMT_NV16,    1, 2, 1, 1, 2, 2, 1, 3, 2, FWHT_FL_PIXENC_YUV},
-	{ V4L2_PIX_FMT_NV61,    1, 2, 1, 1, 2, 2, 1, 3, 2, FWHT_FL_PIXENC_YUV},
-	{ V4L2_PIX_FMT_NV24,    1, 3, 1, 1, 2, 1, 1, 3, 2, FWHT_FL_PIXENC_YUV},
-	{ V4L2_PIX_FMT_NV42,    1, 3, 1, 1, 2, 1, 1, 3, 2, FWHT_FL_PIXENC_YUV},
-	{ V4L2_PIX_FMT_YUYV,    2, 2, 1, 2, 4, 2, 1, 3, 1, FWHT_FL_PIXENC_YUV},
-	{ V4L2_PIX_FMT_YVYU,    2, 2, 1, 2, 4, 2, 1, 3, 1, FWHT_FL_PIXENC_YUV},
-	{ V4L2_PIX_FMT_UYVY,    2, 2, 1, 2, 4, 2, 1, 3, 1, FWHT_FL_PIXENC_YUV},
-	{ V4L2_PIX_FMT_VYUY,    2, 2, 1, 2, 4, 2, 1, 3, 1, FWHT_FL_PIXENC_YUV},
-	{ V4L2_PIX_FMT_BGR24,   3, 3, 1, 3, 3, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB},
-	{ V4L2_PIX_FMT_RGB24,   3, 3, 1, 3, 3, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB},
-	{ V4L2_PIX_FMT_HSV24,   3, 3, 1, 3, 3, 1, 1, 3, 1, FWHT_FL_PIXENC_HSV},
-	{ V4L2_PIX_FMT_BGR32,   4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB},
-	{ V4L2_PIX_FMT_XBGR32,  4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB},
-	{ V4L2_PIX_FMT_ABGR32,  4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB},
-	{ V4L2_PIX_FMT_RGB32,   4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB},
-	{ V4L2_PIX_FMT_XRGB32,  4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB},
-	{ V4L2_PIX_FMT_ARGB32,  4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB},
-	{ V4L2_PIX_FMT_BGRX32,  4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB},
-	{ V4L2_PIX_FMT_BGRA32,  4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB},
-	{ V4L2_PIX_FMT_RGBX32,  4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB},
-	{ V4L2_PIX_FMT_RGBA32,  4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB},
-	{ V4L2_PIX_FMT_HSV32,   4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_HSV},
-	{ V4L2_PIX_FMT_GREY,    1, 1, 1, 1, 0, 1, 1, 1, 1, FWHT_FL_PIXENC_RGB},
-};
-
-bool v4l2_fwht_validate_fmt(const struct v4l2_fwht_pixfmt_info *info,
-			    u32 width_div, u32 height_div, u32 components_num,
-			    u32 pixenc)
-{
-	if (info->width_div == width_div &&
-	    info->height_div == height_div &&
-	    (!pixenc || info->pixenc == pixenc) &&
-	    info->components_num == components_num)
-		return true;
-	return false;
-}
-
-const struct v4l2_fwht_pixfmt_info *v4l2_fwht_find_nth_fmt(u32 width_div,
-							  u32 height_div,
-							  u32 components_num,
-							  u32 pixenc,
-							  unsigned int start_idx)
-{
-	unsigned int i;
-
-	for (i = 0; i < ARRAY_SIZE(v4l2_fwht_pixfmts); i++) {
-		bool is_valid = v4l2_fwht_validate_fmt(&v4l2_fwht_pixfmts[i],
-						       width_div, height_div,
-						       components_num, pixenc);
-		if (is_valid) {
-			if (start_idx == 0)
-				return v4l2_fwht_pixfmts + i;
-			start_idx--;
-		}
-	}
-	return NULL;
-}
-
-const struct v4l2_fwht_pixfmt_info *v4l2_fwht_find_pixfmt(u32 pixelformat)
-{
-	unsigned int i;
-
-	for (i = 0; i < ARRAY_SIZE(v4l2_fwht_pixfmts); i++)
-		if (v4l2_fwht_pixfmts[i].id == pixelformat)
-			return v4l2_fwht_pixfmts + i;
-	return NULL;
-}
-
-const struct v4l2_fwht_pixfmt_info *v4l2_fwht_get_pixfmt(u32 idx)
-{
-	if (idx >= ARRAY_SIZE(v4l2_fwht_pixfmts))
-		return NULL;
-	return v4l2_fwht_pixfmts + idx;
-}
-
-static int prepare_raw_frame(struct fwht_raw_frame *rf,
-			 const struct v4l2_fwht_pixfmt_info *info, u8 *buf,
-			 unsigned int size)
-{
-	rf->luma = buf;
-	rf->width_div = info->width_div;
-	rf->height_div = info->height_div;
-	rf->luma_alpha_step = info->luma_alpha_step;
-	rf->chroma_step = info->chroma_step;
-	rf->alpha = NULL;
-	rf->components_num = info->components_num;
-
-	/*
-	 * The buffer is NULL if it is the reference
-	 * frame of an I-frame in the stateless decoder
-	 */
-	if (!buf) {
-		rf->luma = NULL;
-		rf->cb = NULL;
-		rf->cr = NULL;
-		rf->alpha = NULL;
-		return 0;
-	}
-	switch (info->id) {
-	case V4L2_PIX_FMT_GREY:
-		rf->cb = NULL;
-		rf->cr = NULL;
-		break;
-	case V4L2_PIX_FMT_YUV420:
-		rf->cb = rf->luma + size;
-		rf->cr = rf->cb + size / 4;
-		break;
-	case V4L2_PIX_FMT_YVU420:
-		rf->cr = rf->luma + size;
-		rf->cb = rf->cr + size / 4;
-		break;
-	case V4L2_PIX_FMT_YUV422P:
-		rf->cb = rf->luma + size;
-		rf->cr = rf->cb + size / 2;
-		break;
-	case V4L2_PIX_FMT_NV12:
-	case V4L2_PIX_FMT_NV16:
-	case V4L2_PIX_FMT_NV24:
-		rf->cb = rf->luma + size;
-		rf->cr = rf->cb + 1;
-		break;
-	case V4L2_PIX_FMT_NV21:
-	case V4L2_PIX_FMT_NV61:
-	case V4L2_PIX_FMT_NV42:
-		rf->cr = rf->luma + size;
-		rf->cb = rf->cr + 1;
-		break;
-	case V4L2_PIX_FMT_YUYV:
-		rf->cb = rf->luma + 1;
-		rf->cr = rf->cb + 2;
-		break;
-	case V4L2_PIX_FMT_YVYU:
-		rf->cr = rf->luma + 1;
-		rf->cb = rf->cr + 2;
-		break;
-	case V4L2_PIX_FMT_UYVY:
-		rf->cb = rf->luma;
-		rf->cr = rf->cb + 2;
-		rf->luma++;
-		break;
-	case V4L2_PIX_FMT_VYUY:
-		rf->cr = rf->luma;
-		rf->cb = rf->cr + 2;
-		rf->luma++;
-		break;
-	case V4L2_PIX_FMT_RGB24:
-	case V4L2_PIX_FMT_HSV24:
-		rf->cr = rf->luma;
-		rf->cb = rf->cr + 2;
-		rf->luma++;
-		break;
-	case V4L2_PIX_FMT_BGR24:
-		rf->cb = rf->luma;
-		rf->cr = rf->cb + 2;
-		rf->luma++;
-		break;
-	case V4L2_PIX_FMT_RGB32:
-	case V4L2_PIX_FMT_XRGB32:
-	case V4L2_PIX_FMT_HSV32:
-	case V4L2_PIX_FMT_ARGB32:
-		rf->alpha = rf->luma;
-		rf->cr = rf->luma + 1;
-		rf->cb = rf->cr + 2;
-		rf->luma += 2;
-		break;
-	case V4L2_PIX_FMT_BGR32:
-	case V4L2_PIX_FMT_XBGR32:
-	case V4L2_PIX_FMT_ABGR32:
-		rf->cb = rf->luma;
-		rf->cr = rf->cb + 2;
-		rf->luma++;
-		rf->alpha = rf->cr + 1;
-		break;
-	case V4L2_PIX_FMT_BGRX32:
-	case V4L2_PIX_FMT_BGRA32:
-		rf->alpha = rf->luma;
-		rf->cb = rf->luma + 1;
-		rf->cr = rf->cb + 2;
-		rf->luma += 2;
-		break;
-	case V4L2_PIX_FMT_RGBX32:
-	case V4L2_PIX_FMT_RGBA32:
-		rf->alpha = rf->luma + 3;
-		rf->cr = rf->luma;
-		rf->cb = rf->cr + 2;
-		rf->luma++;
-		break;
-	default:
-		return -EINVAL;
-	}
-	return 0;
-}
-
-int v4l2_fwht_encode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out)
-{
-	unsigned int size = state->stride * state->coded_height;
-	unsigned int chroma_stride = state->stride;
-	const struct v4l2_fwht_pixfmt_info *info = state->info;
-	struct fwht_cframe_hdr *p_hdr;
-	struct fwht_cframe cf;
-	struct fwht_raw_frame rf;
-	u32 encoding;
-	u32 flags = 0;
-
-	if (!info)
-		return -EINVAL;
-
-	if (prepare_raw_frame(&rf, info, p_in, size))
-		return -EINVAL;
-
-	if (info->planes_num == 3)
-		chroma_stride /= 2;
-
-	if (info->id == V4L2_PIX_FMT_NV24 ||
-	    info->id == V4L2_PIX_FMT_NV42)
-		chroma_stride *= 2;
-
-	cf.i_frame_qp = state->i_frame_qp;
-	cf.p_frame_qp = state->p_frame_qp;
-	cf.rlc_data = (__be16 *)(p_out + sizeof(*p_hdr));
-
-	encoding = fwht_encode_frame(&rf, &state->ref_frame, &cf,
-				     !state->gop_cnt,
-				     state->gop_cnt == state->gop_size - 1,
-				     state->visible_width,
-				     state->visible_height,
-				     state->stride, chroma_stride);
-	if (!(encoding & FWHT_FRAME_PCODED))
-		state->gop_cnt = 0;
-	if (++state->gop_cnt >= state->gop_size)
-		state->gop_cnt = 0;
-
-	p_hdr = (struct fwht_cframe_hdr *)p_out;
-	p_hdr->magic1 = FWHT_MAGIC1;
-	p_hdr->magic2 = FWHT_MAGIC2;
-	p_hdr->version = htonl(FWHT_VERSION);
-	p_hdr->width = htonl(state->visible_width);
-	p_hdr->height = htonl(state->visible_height);
-	flags |= (info->components_num - 1) << FWHT_FL_COMPONENTS_NUM_OFFSET;
-	flags |= info->pixenc;
-	if (encoding & FWHT_LUMA_UNENCODED)
-		flags |= FWHT_FL_LUMA_IS_UNCOMPRESSED;
-	if (encoding & FWHT_CB_UNENCODED)
-		flags |= FWHT_FL_CB_IS_UNCOMPRESSED;
-	if (encoding & FWHT_CR_UNENCODED)
-		flags |= FWHT_FL_CR_IS_UNCOMPRESSED;
-	if (encoding & FWHT_ALPHA_UNENCODED)
-		flags |= FWHT_FL_ALPHA_IS_UNCOMPRESSED;
-	if (!(encoding & FWHT_FRAME_PCODED))
-		flags |= FWHT_FL_I_FRAME;
-	if (rf.height_div == 1)
-		flags |= FWHT_FL_CHROMA_FULL_HEIGHT;
-	if (rf.width_div == 1)
-		flags |= FWHT_FL_CHROMA_FULL_WIDTH;
-	p_hdr->flags = htonl(flags);
-	p_hdr->colorspace = htonl(state->colorspace);
-	p_hdr->xfer_func = htonl(state->xfer_func);
-	p_hdr->ycbcr_enc = htonl(state->ycbcr_enc);
-	p_hdr->quantization = htonl(state->quantization);
-	p_hdr->size = htonl(cf.size);
-	return cf.size + sizeof(*p_hdr);
-}
-
-int v4l2_fwht_decode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out)
-{
-	u32 flags;
-	struct fwht_cframe cf;
-	unsigned int components_num = 3;
-	unsigned int version;
-	const struct v4l2_fwht_pixfmt_info *info;
-	unsigned int hdr_width_div, hdr_height_div;
-	struct fwht_raw_frame dst_rf;
-	unsigned int dst_chroma_stride = state->stride;
-	unsigned int ref_chroma_stride = state->ref_stride;
-	unsigned int dst_size = state->stride * state->coded_height;
-	unsigned int ref_size;
-
-	if (!state->info)
-		return -EINVAL;
-
-	info = state->info;
-
-	version = ntohl(state->header.version);
-	if (!version || version > FWHT_VERSION) {
-		pr_err("version %d is not supported, current version is %d\n",
-		       version, FWHT_VERSION);
-		return -EINVAL;
-	}
-
-	if (state->header.magic1 != FWHT_MAGIC1 ||
-	    state->header.magic2 != FWHT_MAGIC2)
-		return -EINVAL;
-
-	/* TODO: support resolution changes */
-	if (ntohl(state->header.width)  != state->visible_width ||
-	    ntohl(state->header.height) != state->visible_height)
-		return -EINVAL;
-
-	flags = ntohl(state->header.flags);
-
-	if (version >= 2) {
-		if ((flags & FWHT_FL_PIXENC_MSK) != info->pixenc)
-			return -EINVAL;
-		components_num = 1 + ((flags & FWHT_FL_COMPONENTS_NUM_MSK) >>
-				FWHT_FL_COMPONENTS_NUM_OFFSET);
-	}
-
-	if (components_num != info->components_num)
-		return -EINVAL;
-
-	state->colorspace = ntohl(state->header.colorspace);
-	state->xfer_func = ntohl(state->header.xfer_func);
-	state->ycbcr_enc = ntohl(state->header.ycbcr_enc);
-	state->quantization = ntohl(state->header.quantization);
-	cf.rlc_data = (__be16 *)p_in;
-	cf.size = ntohl(state->header.size);
-
-	hdr_width_div = (flags & FWHT_FL_CHROMA_FULL_WIDTH) ? 1 : 2;
-	hdr_height_div = (flags & FWHT_FL_CHROMA_FULL_HEIGHT) ? 1 : 2;
-	if (hdr_width_div != info->width_div ||
-	    hdr_height_div != info->height_div)
-		return -EINVAL;
-
-	if (prepare_raw_frame(&dst_rf, info, p_out, dst_size))
-		return -EINVAL;
-	if (info->planes_num == 3) {
-		dst_chroma_stride /= 2;
-		ref_chroma_stride /= 2;
-	}
-	if (info->id == V4L2_PIX_FMT_NV24 ||
-	    info->id == V4L2_PIX_FMT_NV42) {
-		dst_chroma_stride *= 2;
-		ref_chroma_stride *= 2;
-	}
-
-
-	ref_size = state->ref_stride * state->coded_height;
-
-	if (prepare_raw_frame(&state->ref_frame, info, state->ref_frame.buf,
-			      ref_size))
-		return -EINVAL;
-
-	if (!fwht_decode_frame(&cf, flags, components_num,
-			state->visible_width, state->visible_height,
-			&state->ref_frame, state->ref_stride, ref_chroma_stride,
-			&dst_rf, state->stride, dst_chroma_stride))
-		return -EINVAL;
-	return 0;
-}
diff --git a/drivers/media/platform/vicodec/codec-v4l2-fwht.h b/drivers/media/platform/vicodec/codec-v4l2-fwht.h
deleted file mode 100644
index 1a0d2a9f931a..000000000000
--- a/drivers/media/platform/vicodec/codec-v4l2-fwht.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1 */
-/*
- * Copyright 2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#ifndef CODEC_V4L2_FWHT_H
-#define CODEC_V4L2_FWHT_H
-
-#include "codec-fwht.h"
-
-struct v4l2_fwht_pixfmt_info {
-	u32 id;
-	unsigned int bytesperline_mult;
-	unsigned int sizeimage_mult;
-	unsigned int sizeimage_div;
-	unsigned int luma_alpha_step;
-	unsigned int chroma_step;
-	/* Chroma plane subsampling */
-	unsigned int width_div;
-	unsigned int height_div;
-	unsigned int components_num;
-	unsigned int planes_num;
-	unsigned int pixenc;
-};
-
-struct v4l2_fwht_state {
-	const struct v4l2_fwht_pixfmt_info *info;
-	unsigned int visible_width;
-	unsigned int visible_height;
-	unsigned int coded_width;
-	unsigned int coded_height;
-	unsigned int stride;
-	unsigned int ref_stride;
-	unsigned int gop_size;
-	unsigned int gop_cnt;
-	u16 i_frame_qp;
-	u16 p_frame_qp;
-
-	enum v4l2_colorspace colorspace;
-	enum v4l2_ycbcr_encoding ycbcr_enc;
-	enum v4l2_xfer_func xfer_func;
-	enum v4l2_quantization quantization;
-
-	struct fwht_raw_frame ref_frame;
-	struct fwht_cframe_hdr header;
-	u8 *compressed_frame;
-	u64 ref_frame_ts;
-};
-
-const struct v4l2_fwht_pixfmt_info *v4l2_fwht_find_pixfmt(u32 pixelformat);
-const struct v4l2_fwht_pixfmt_info *v4l2_fwht_get_pixfmt(u32 idx);
-bool v4l2_fwht_validate_fmt(const struct v4l2_fwht_pixfmt_info *info,
-			    u32 width_div, u32 height_div, u32 components_num,
-			    u32 pixenc);
-const struct v4l2_fwht_pixfmt_info *v4l2_fwht_find_nth_fmt(u32 width_div,
-							  u32 height_div,
-							  u32 components_num,
-							  u32 pixenc,
-							  unsigned int start_idx);
-
-int v4l2_fwht_encode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out);
-int v4l2_fwht_decode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out);
-
-#endif
diff --git a/drivers/media/platform/vicodec/vicodec-core.c b/drivers/media/platform/vicodec/vicodec-core.c
deleted file mode 100644
index 30ced1c21387..000000000000
--- a/drivers/media/platform/vicodec/vicodec-core.c
+++ /dev/null
@@ -1,2238 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * A virtual codec example device.
- *
- * Copyright 2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- *
- * This is a virtual codec device driver for testing the codec framework.
- * It simulates a device that uses memory buffers for both source and
- * destination and encodes or decodes the data.
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/fs.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-
-#include <linux/platform_device.h>
-#include <media/v4l2-mem2mem.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-event.h>
-#include <media/videobuf2-vmalloc.h>
-
-#include "codec-v4l2-fwht.h"
-
-MODULE_DESCRIPTION("Virtual codec device");
-MODULE_AUTHOR("Hans Verkuil <hans.verkuil@cisco.com>");
-MODULE_LICENSE("GPL v2");
-
-static bool multiplanar;
-module_param(multiplanar, bool, 0444);
-MODULE_PARM_DESC(multiplanar,
-		 " use multi-planar API instead of single-planar API");
-
-static unsigned int debug;
-module_param(debug, uint, 0644);
-MODULE_PARM_DESC(debug, " activates debug info");
-
-#define VICODEC_NAME		"vicodec"
-#define MAX_WIDTH		4096U
-#define MIN_WIDTH		640U
-#define MAX_HEIGHT		2160U
-#define MIN_HEIGHT		360U
-
-#define dprintk(dev, fmt, arg...) \
-	v4l2_dbg(1, debug, &dev->v4l2_dev, "%s: " fmt, __func__, ## arg)
-
-
-struct pixfmt_info {
-	u32 id;
-	unsigned int bytesperline_mult;
-	unsigned int sizeimage_mult;
-	unsigned int sizeimage_div;
-	unsigned int luma_step;
-	unsigned int chroma_step;
-	/* Chroma plane subsampling */
-	unsigned int width_div;
-	unsigned int height_div;
-};
-
-static const struct v4l2_fwht_pixfmt_info pixfmt_fwht = {
-	V4L2_PIX_FMT_FWHT, 0, 3, 1, 1, 1, 1, 1, 0, 1
-};
-
-static const struct v4l2_fwht_pixfmt_info pixfmt_stateless_fwht = {
-	V4L2_PIX_FMT_FWHT_STATELESS, 0, 3, 1, 1, 1, 1, 1, 0, 1
-};
-
-static void vicodec_dev_release(struct device *dev)
-{
-}
-
-static struct platform_device vicodec_pdev = {
-	.name		= VICODEC_NAME,
-	.dev.release	= vicodec_dev_release,
-};
-
-/* Per-queue, driver-specific private data */
-struct vicodec_q_data {
-	unsigned int		coded_width;
-	unsigned int		coded_height;
-	unsigned int		visible_width;
-	unsigned int		visible_height;
-	unsigned int		sizeimage;
-	unsigned int		vb2_sizeimage;
-	unsigned int		sequence;
-	const struct v4l2_fwht_pixfmt_info *info;
-};
-
-enum {
-	V4L2_M2M_SRC = 0,
-	V4L2_M2M_DST = 1,
-};
-
-struct vicodec_dev_instance {
-	struct video_device     vfd;
-	struct mutex            mutex;
-	spinlock_t              lock;
-	struct v4l2_m2m_dev     *m2m_dev;
-};
-
-struct vicodec_dev {
-	struct v4l2_device	v4l2_dev;
-	struct vicodec_dev_instance stateful_enc;
-	struct vicodec_dev_instance stateful_dec;
-	struct vicodec_dev_instance stateless_dec;
-#ifdef CONFIG_MEDIA_CONTROLLER
-	struct media_device	mdev;
-#endif
-
-};
-
-struct vicodec_ctx {
-	struct v4l2_fh		fh;
-	struct vicodec_dev	*dev;
-	bool			is_enc;
-	bool			is_stateless;
-	spinlock_t		*lock;
-
-	struct v4l2_ctrl_handler hdl;
-
-	/* Source and destination queue data */
-	struct vicodec_q_data   q_data[2];
-	struct v4l2_fwht_state	state;
-
-	u32			cur_buf_offset;
-	u32			comp_max_size;
-	u32			comp_size;
-	u32			header_size;
-	u32			comp_magic_cnt;
-	bool			comp_has_frame;
-	bool			comp_has_next_frame;
-	bool			first_source_change_sent;
-	bool			source_changed;
-};
-
-static const struct v4l2_event vicodec_eos_event = {
-	.type = V4L2_EVENT_EOS
-};
-
-static inline struct vicodec_ctx *file2ctx(struct file *file)
-{
-	return container_of(file->private_data, struct vicodec_ctx, fh);
-}
-
-static struct vicodec_q_data *get_q_data(struct vicodec_ctx *ctx,
-					 enum v4l2_buf_type type)
-{
-	switch (type) {
-	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
-		return &ctx->q_data[V4L2_M2M_SRC];
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
-		return &ctx->q_data[V4L2_M2M_DST];
-	default:
-		break;
-	}
-	return NULL;
-}
-
-static void copy_cap_to_ref(const u8 *cap, const struct v4l2_fwht_pixfmt_info *info,
-		struct v4l2_fwht_state *state)
-{
-	int plane_idx;
-	u8 *p_ref = state->ref_frame.buf;
-	unsigned int cap_stride = state->stride;
-	unsigned int ref_stride = state->ref_stride;
-
-	for (plane_idx = 0; plane_idx < info->planes_num; plane_idx++) {
-		int i;
-		unsigned int h_div = (plane_idx == 1 || plane_idx == 2) ?
-			info->height_div : 1;
-		const u8 *row_cap = cap;
-		u8 *row_ref = p_ref;
-
-		if (info->planes_num == 3 && plane_idx == 1) {
-			cap_stride /= 2;
-			ref_stride /= 2;
-		}
-
-		if (plane_idx == 1 &&
-		    (info->id == V4L2_PIX_FMT_NV24 ||
-		     info->id == V4L2_PIX_FMT_NV42)) {
-			cap_stride *= 2;
-			ref_stride *= 2;
-		}
-
-		for (i = 0; i < state->visible_height / h_div; i++) {
-			memcpy(row_ref, row_cap, ref_stride);
-			row_ref += ref_stride;
-			row_cap += cap_stride;
-		}
-		cap += cap_stride * (state->coded_height / h_div);
-		p_ref += ref_stride * (state->coded_height / h_div);
-	}
-}
-
-static bool validate_by_version(unsigned int flags, unsigned int version)
-{
-	if (!version || version > FWHT_VERSION)
-		return false;
-
-	if (version >= 2) {
-		unsigned int components_num = 1 +
-			((flags & FWHT_FL_COMPONENTS_NUM_MSK) >>
-			 FWHT_FL_COMPONENTS_NUM_OFFSET);
-		unsigned int pixenc = flags & FWHT_FL_PIXENC_MSK;
-
-		if (components_num == 0 || components_num > 4 || !pixenc)
-			return false;
-	}
-	return true;
-}
-
-static bool validate_stateless_params_flags(const struct v4l2_ctrl_fwht_params *params,
-					    const struct v4l2_fwht_pixfmt_info *cur_info)
-{
-	unsigned int width_div =
-		(params->flags & FWHT_FL_CHROMA_FULL_WIDTH) ? 1 : 2;
-	unsigned int height_div =
-		(params->flags & FWHT_FL_CHROMA_FULL_HEIGHT) ? 1 : 2;
-	unsigned int components_num = 3;
-	unsigned int pixenc = 0;
-
-	if (params->version < 3)
-		return false;
-
-	components_num = 1 + ((params->flags & FWHT_FL_COMPONENTS_NUM_MSK) >>
-			      FWHT_FL_COMPONENTS_NUM_OFFSET);
-	pixenc = (params->flags & FWHT_FL_PIXENC_MSK);
-	if (v4l2_fwht_validate_fmt(cur_info, width_div, height_div,
-				    components_num, pixenc))
-		return true;
-	return false;
-}
-
-
-static void update_state_from_header(struct vicodec_ctx *ctx)
-{
-	const struct fwht_cframe_hdr *p_hdr = &ctx->state.header;
-
-	ctx->state.visible_width = ntohl(p_hdr->width);
-	ctx->state.visible_height = ntohl(p_hdr->height);
-	ctx->state.colorspace = ntohl(p_hdr->colorspace);
-	ctx->state.xfer_func = ntohl(p_hdr->xfer_func);
-	ctx->state.ycbcr_enc = ntohl(p_hdr->ycbcr_enc);
-	ctx->state.quantization = ntohl(p_hdr->quantization);
-}
-
-static int device_process(struct vicodec_ctx *ctx,
-			  struct vb2_v4l2_buffer *src_vb,
-			  struct vb2_v4l2_buffer *dst_vb)
-{
-	struct vicodec_dev *dev = ctx->dev;
-	struct v4l2_fwht_state *state = &ctx->state;
-	u8 *p_src, *p_dst;
-	int ret = 0;
-
-	if (ctx->is_enc || ctx->is_stateless)
-		p_src = vb2_plane_vaddr(&src_vb->vb2_buf, 0);
-	else
-		p_src = state->compressed_frame;
-
-	if (ctx->is_stateless) {
-		struct media_request *src_req = src_vb->vb2_buf.req_obj.req;
-
-		ret = v4l2_ctrl_request_setup(src_req, &ctx->hdl);
-		if (ret)
-			return ret;
-		update_state_from_header(ctx);
-
-		ctx->state.header.size =
-			htonl(vb2_get_plane_payload(&src_vb->vb2_buf, 0));
-		/*
-		 * set the reference buffer from the reference timestamp
-		 * only if this is a P-frame
-		 */
-		if (!(ntohl(ctx->state.header.flags) & FWHT_FL_I_FRAME)) {
-			struct vb2_buffer *ref_vb2_buf;
-			int ref_buf_idx;
-			struct vb2_queue *vq_cap =
-				v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
-						V4L2_BUF_TYPE_VIDEO_CAPTURE);
-
-			ref_buf_idx = vb2_find_timestamp(vq_cap,
-							 ctx->state.ref_frame_ts, 0);
-			if (ref_buf_idx < 0)
-				return -EINVAL;
-
-			ref_vb2_buf = vq_cap->bufs[ref_buf_idx];
-			if (ref_vb2_buf->state == VB2_BUF_STATE_ERROR)
-				ret = -EINVAL;
-			ctx->state.ref_frame.buf =
-				vb2_plane_vaddr(ref_vb2_buf, 0);
-		} else {
-			ctx->state.ref_frame.buf = NULL;
-		}
-	}
-	p_dst = vb2_plane_vaddr(&dst_vb->vb2_buf, 0);
-	if (!p_src || !p_dst) {
-		v4l2_err(&dev->v4l2_dev,
-			 "Acquiring kernel pointers to buffers failed\n");
-		return -EFAULT;
-	}
-
-	if (ctx->is_enc) {
-		struct vicodec_q_data *q_src;
-		int comp_sz_or_errcode;
-
-		q_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
-		state->info = q_src->info;
-		comp_sz_or_errcode = v4l2_fwht_encode(state, p_src, p_dst);
-		if (comp_sz_or_errcode < 0)
-			return comp_sz_or_errcode;
-		vb2_set_plane_payload(&dst_vb->vb2_buf, 0, comp_sz_or_errcode);
-	} else {
-		struct vicodec_q_data *q_dst;
-		unsigned int comp_frame_size = ntohl(ctx->state.header.size);
-
-		q_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
-		if (comp_frame_size > ctx->comp_max_size)
-			return -EINVAL;
-		state->info = q_dst->info;
-		ret = v4l2_fwht_decode(state, p_src, p_dst);
-		if (ret < 0)
-			return ret;
-		if (!ctx->is_stateless)
-			copy_cap_to_ref(p_dst, ctx->state.info, &ctx->state);
-
-		vb2_set_plane_payload(&dst_vb->vb2_buf, 0, q_dst->sizeimage);
-		if (ntohl(ctx->state.header.flags) & FWHT_FL_I_FRAME)
-			dst_vb->flags |= V4L2_BUF_FLAG_KEYFRAME;
-		else
-			dst_vb->flags |= V4L2_BUF_FLAG_PFRAME;
-	}
-	return ret;
-}
-
-/*
- * mem2mem callbacks
- */
-static enum vb2_buffer_state get_next_header(struct vicodec_ctx *ctx,
-					     u8 **pp, u32 sz)
-{
-	static const u8 magic[] = {
-		0x4f, 0x4f, 0x4f, 0x4f, 0xff, 0xff, 0xff, 0xff
-	};
-	u8 *p = *pp;
-	u32 state;
-	u8 *header = (u8 *)&ctx->state.header;
-
-	state = VB2_BUF_STATE_DONE;
-
-	if (!ctx->header_size) {
-		state = VB2_BUF_STATE_ERROR;
-		for (; p < *pp + sz; p++) {
-			u32 copy;
-
-			p = memchr(p, magic[ctx->comp_magic_cnt],
-				   *pp + sz - p);
-			if (!p) {
-				ctx->comp_magic_cnt = 0;
-				p = *pp + sz;
-				break;
-			}
-			copy = sizeof(magic) - ctx->comp_magic_cnt;
-			if (*pp + sz - p < copy)
-				copy = *pp + sz - p;
-
-			memcpy(header + ctx->comp_magic_cnt, p, copy);
-			ctx->comp_magic_cnt += copy;
-			if (!memcmp(header, magic, ctx->comp_magic_cnt)) {
-				p += copy;
-				state = VB2_BUF_STATE_DONE;
-				break;
-			}
-			ctx->comp_magic_cnt = 0;
-		}
-		if (ctx->comp_magic_cnt < sizeof(magic)) {
-			*pp = p;
-			return state;
-		}
-		ctx->header_size = sizeof(magic);
-	}
-
-	if (ctx->header_size < sizeof(struct fwht_cframe_hdr)) {
-		u32 copy = sizeof(struct fwht_cframe_hdr) - ctx->header_size;
-
-		if (*pp + sz - p < copy)
-			copy = *pp + sz - p;
-
-		memcpy(header + ctx->header_size, p, copy);
-		p += copy;
-		ctx->header_size += copy;
-	}
-	*pp = p;
-	return state;
-}
-
-/* device_run() - prepares and starts the device */
-static void device_run(void *priv)
-{
-	struct vicodec_ctx *ctx = priv;
-	struct vicodec_dev *dev = ctx->dev;
-	struct vb2_v4l2_buffer *src_buf, *dst_buf;
-	struct vicodec_q_data *q_src, *q_dst;
-	u32 state;
-	struct media_request *src_req;
-
-	src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
-	dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
-	src_req = src_buf->vb2_buf.req_obj.req;
-
-	q_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
-	q_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
-
-	state = VB2_BUF_STATE_DONE;
-	if (device_process(ctx, src_buf, dst_buf))
-		state = VB2_BUF_STATE_ERROR;
-	else
-		dst_buf->sequence = q_dst->sequence++;
-	dst_buf->flags &= ~V4L2_BUF_FLAG_LAST;
-	v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, false);
-
-	spin_lock(ctx->lock);
-	if (!ctx->comp_has_next_frame &&
-	    v4l2_m2m_is_last_draining_src_buf(ctx->fh.m2m_ctx, src_buf)) {
-		dst_buf->flags |= V4L2_BUF_FLAG_LAST;
-		v4l2_event_queue_fh(&ctx->fh, &vicodec_eos_event);
-		v4l2_m2m_mark_stopped(ctx->fh.m2m_ctx);
-	}
-	if (ctx->is_enc || ctx->is_stateless) {
-		src_buf->sequence = q_src->sequence++;
-		src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
-		v4l2_m2m_buf_done(src_buf, state);
-	} else if (vb2_get_plane_payload(&src_buf->vb2_buf, 0) == ctx->cur_buf_offset) {
-		src_buf->sequence = q_src->sequence++;
-		src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
-		v4l2_m2m_buf_done(src_buf, state);
-		ctx->cur_buf_offset = 0;
-		ctx->comp_has_next_frame = false;
-	}
-	v4l2_m2m_buf_done(dst_buf, state);
-
-	ctx->comp_size = 0;
-	ctx->header_size = 0;
-	ctx->comp_magic_cnt = 0;
-	ctx->comp_has_frame = false;
-	spin_unlock(ctx->lock);
-	if (ctx->is_stateless && src_req)
-		v4l2_ctrl_request_complete(src_req, &ctx->hdl);
-
-	if (ctx->is_enc)
-		v4l2_m2m_job_finish(dev->stateful_enc.m2m_dev, ctx->fh.m2m_ctx);
-	else if (ctx->is_stateless)
-		v4l2_m2m_job_finish(dev->stateless_dec.m2m_dev,
-				    ctx->fh.m2m_ctx);
-	else
-		v4l2_m2m_job_finish(dev->stateful_dec.m2m_dev, ctx->fh.m2m_ctx);
-}
-
-static void job_remove_src_buf(struct vicodec_ctx *ctx, u32 state)
-{
-	struct vb2_v4l2_buffer *src_buf;
-	struct vicodec_q_data *q_src;
-
-	q_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
-	spin_lock(ctx->lock);
-	src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
-	src_buf->sequence = q_src->sequence++;
-	v4l2_m2m_buf_done(src_buf, state);
-	ctx->cur_buf_offset = 0;
-	spin_unlock(ctx->lock);
-}
-
-static const struct v4l2_fwht_pixfmt_info *
-info_from_header(const struct fwht_cframe_hdr *p_hdr)
-{
-	unsigned int flags = ntohl(p_hdr->flags);
-	unsigned int width_div = (flags & FWHT_FL_CHROMA_FULL_WIDTH) ? 1 : 2;
-	unsigned int height_div = (flags & FWHT_FL_CHROMA_FULL_HEIGHT) ? 1 : 2;
-	unsigned int components_num = 3;
-	unsigned int pixenc = 0;
-	unsigned int version = ntohl(p_hdr->version);
-
-	if (version >= 2) {
-		components_num = 1 + ((flags & FWHT_FL_COMPONENTS_NUM_MSK) >>
-				FWHT_FL_COMPONENTS_NUM_OFFSET);
-		pixenc = (flags & FWHT_FL_PIXENC_MSK);
-	}
-	return v4l2_fwht_find_nth_fmt(width_div, height_div,
-				     components_num, pixenc, 0);
-}
-
-static bool is_header_valid(const struct fwht_cframe_hdr *p_hdr)
-{
-	const struct v4l2_fwht_pixfmt_info *info;
-	unsigned int w = ntohl(p_hdr->width);
-	unsigned int h = ntohl(p_hdr->height);
-	unsigned int version = ntohl(p_hdr->version);
-	unsigned int flags = ntohl(p_hdr->flags);
-
-	if (w < MIN_WIDTH || w > MAX_WIDTH || h < MIN_HEIGHT || h > MAX_HEIGHT)
-		return false;
-
-	if (!validate_by_version(flags, version))
-		return false;
-
-	info = info_from_header(p_hdr);
-	if (!info)
-		return false;
-	return true;
-}
-
-static void update_capture_data_from_header(struct vicodec_ctx *ctx)
-{
-	struct vicodec_q_data *q_dst = get_q_data(ctx,
-						  V4L2_BUF_TYPE_VIDEO_CAPTURE);
-	const struct fwht_cframe_hdr *p_hdr = &ctx->state.header;
-	const struct v4l2_fwht_pixfmt_info *info = info_from_header(p_hdr);
-	unsigned int flags = ntohl(p_hdr->flags);
-	unsigned int hdr_width_div = (flags & FWHT_FL_CHROMA_FULL_WIDTH) ? 1 : 2;
-	unsigned int hdr_height_div = (flags & FWHT_FL_CHROMA_FULL_HEIGHT) ? 1 : 2;
-
-	/*
-	 * This function should not be used by a stateless codec since
-	 * it changes values in q_data that are not request specific
-	 */
-	WARN_ON(ctx->is_stateless);
-
-	q_dst->info = info;
-	q_dst->visible_width = ntohl(p_hdr->width);
-	q_dst->visible_height = ntohl(p_hdr->height);
-	q_dst->coded_width = vic_round_dim(q_dst->visible_width, hdr_width_div);
-	q_dst->coded_height = vic_round_dim(q_dst->visible_height,
-					    hdr_height_div);
-
-	q_dst->sizeimage = q_dst->coded_width * q_dst->coded_height *
-		q_dst->info->sizeimage_mult / q_dst->info->sizeimage_div;
-	ctx->state.colorspace = ntohl(p_hdr->colorspace);
-
-	ctx->state.xfer_func = ntohl(p_hdr->xfer_func);
-	ctx->state.ycbcr_enc = ntohl(p_hdr->ycbcr_enc);
-	ctx->state.quantization = ntohl(p_hdr->quantization);
-}
-
-static void set_last_buffer(struct vb2_v4l2_buffer *dst_buf,
-			    const struct vb2_v4l2_buffer *src_buf,
-			    struct vicodec_ctx *ctx)
-{
-	struct vicodec_q_data *q_dst = get_q_data(ctx,
-						  V4L2_BUF_TYPE_VIDEO_CAPTURE);
-
-	vb2_set_plane_payload(&dst_buf->vb2_buf, 0, 0);
-	dst_buf->sequence = q_dst->sequence++;
-
-	v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, !ctx->is_enc);
-	dst_buf->flags |= V4L2_BUF_FLAG_LAST;
-	v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
-}
-
-static int job_ready(void *priv)
-{
-	static const u8 magic[] = {
-		0x4f, 0x4f, 0x4f, 0x4f, 0xff, 0xff, 0xff, 0xff
-	};
-	struct vicodec_ctx *ctx = priv;
-	struct vb2_v4l2_buffer *src_buf;
-	u8 *p_src;
-	u8 *p;
-	u32 sz;
-	u32 state;
-	struct vicodec_q_data *q_dst = get_q_data(ctx,
-						  V4L2_BUF_TYPE_VIDEO_CAPTURE);
-	unsigned int flags;
-	unsigned int hdr_width_div;
-	unsigned int hdr_height_div;
-	unsigned int max_to_copy;
-	unsigned int comp_frame_size;
-
-	if (ctx->source_changed)
-		return 0;
-	if (ctx->is_stateless || ctx->is_enc || ctx->comp_has_frame)
-		return 1;
-
-restart:
-	ctx->comp_has_next_frame = false;
-	src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
-	if (!src_buf)
-		return 0;
-	p_src = vb2_plane_vaddr(&src_buf->vb2_buf, 0);
-	sz = vb2_get_plane_payload(&src_buf->vb2_buf, 0);
-	p = p_src + ctx->cur_buf_offset;
-
-	state = VB2_BUF_STATE_DONE;
-
-	if (ctx->header_size < sizeof(struct fwht_cframe_hdr)) {
-		state = get_next_header(ctx, &p, p_src + sz - p);
-		if (ctx->header_size < sizeof(struct fwht_cframe_hdr)) {
-			if (v4l2_m2m_is_last_draining_src_buf(ctx->fh.m2m_ctx,
-							      src_buf))
-				return 1;
-			job_remove_src_buf(ctx, state);
-			goto restart;
-		}
-	}
-
-	comp_frame_size = ntohl(ctx->state.header.size);
-
-	/*
-	 * The current scanned frame might be the first frame of a new
-	 * resolution so its size might be larger than ctx->comp_max_size.
-	 * In that case it is copied up to the current buffer capacity and
-	 * the copy will continue after allocating new large enough buffer
-	 * when restreaming
-	 */
-	max_to_copy = min(comp_frame_size, ctx->comp_max_size);
-
-	if (ctx->comp_size < max_to_copy) {
-		u32 copy = max_to_copy - ctx->comp_size;
-
-		if (copy > p_src + sz - p)
-			copy = p_src + sz - p;
-
-		memcpy(ctx->state.compressed_frame + ctx->comp_size,
-		       p, copy);
-		p += copy;
-		ctx->comp_size += copy;
-		if (ctx->comp_size < max_to_copy) {
-			if (v4l2_m2m_is_last_draining_src_buf(ctx->fh.m2m_ctx,
-							      src_buf))
-				return 1;
-			job_remove_src_buf(ctx, state);
-			goto restart;
-		}
-	}
-	ctx->cur_buf_offset = p - p_src;
-	if (ctx->comp_size == comp_frame_size)
-		ctx->comp_has_frame = true;
-	ctx->comp_has_next_frame = false;
-	if (ctx->comp_has_frame && sz - ctx->cur_buf_offset >=
-			sizeof(struct fwht_cframe_hdr)) {
-		struct fwht_cframe_hdr *p_hdr = (struct fwht_cframe_hdr *)p;
-		u32 frame_size = ntohl(p_hdr->size);
-		u32 remaining = sz - ctx->cur_buf_offset - sizeof(*p_hdr);
-
-		if (!memcmp(p, magic, sizeof(magic)))
-			ctx->comp_has_next_frame = remaining >= frame_size;
-	}
-	/*
-	 * if the header is invalid the device_run will just drop the frame
-	 * with an error
-	 */
-	if (!is_header_valid(&ctx->state.header) && ctx->comp_has_frame)
-		return 1;
-	flags = ntohl(ctx->state.header.flags);
-	hdr_width_div = (flags & FWHT_FL_CHROMA_FULL_WIDTH) ? 1 : 2;
-	hdr_height_div = (flags & FWHT_FL_CHROMA_FULL_HEIGHT) ? 1 : 2;
-
-	if (ntohl(ctx->state.header.width) != q_dst->visible_width ||
-	    ntohl(ctx->state.header.height) != q_dst->visible_height ||
-	    !q_dst->info ||
-	    hdr_width_div != q_dst->info->width_div ||
-	    hdr_height_div != q_dst->info->height_div) {
-		static const struct v4l2_event rs_event = {
-			.type = V4L2_EVENT_SOURCE_CHANGE,
-			.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION,
-		};
-
-		struct vb2_v4l2_buffer *dst_buf =
-			v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
-
-		update_capture_data_from_header(ctx);
-		v4l2_event_queue_fh(&ctx->fh, &rs_event);
-		set_last_buffer(dst_buf, src_buf, ctx);
-		ctx->source_changed = true;
-		return 0;
-	}
-	return 1;
-}
-
-/*
- * video ioctls
- */
-
-static const struct v4l2_fwht_pixfmt_info *find_fmt(u32 fmt)
-{
-	const struct v4l2_fwht_pixfmt_info *info =
-		v4l2_fwht_find_pixfmt(fmt);
-
-	if (!info)
-		info = v4l2_fwht_get_pixfmt(0);
-	return info;
-}
-
-static int vidioc_querycap(struct file *file, void *priv,
-			   struct v4l2_capability *cap)
-{
-	strscpy(cap->driver, VICODEC_NAME, sizeof(cap->driver));
-	strscpy(cap->card, VICODEC_NAME, sizeof(cap->card));
-	snprintf(cap->bus_info, sizeof(cap->bus_info),
-			"platform:%s", VICODEC_NAME);
-	return 0;
-}
-
-static int enum_fmt(struct v4l2_fmtdesc *f, struct vicodec_ctx *ctx,
-		    bool is_out)
-{
-	bool is_uncomp = (ctx->is_enc && is_out) || (!ctx->is_enc && !is_out);
-
-	if (V4L2_TYPE_IS_MULTIPLANAR(f->type) && !multiplanar)
-		return -EINVAL;
-	if (!V4L2_TYPE_IS_MULTIPLANAR(f->type) && multiplanar)
-		return -EINVAL;
-
-	if (is_uncomp) {
-		const struct v4l2_fwht_pixfmt_info *info =
-					get_q_data(ctx, f->type)->info;
-
-		if (ctx->is_enc ||
-		    !vb2_is_streaming(&ctx->fh.m2m_ctx->cap_q_ctx.q))
-			info = v4l2_fwht_get_pixfmt(f->index);
-		else
-			info = v4l2_fwht_find_nth_fmt(info->width_div,
-						     info->height_div,
-						     info->components_num,
-						     info->pixenc,
-						     f->index);
-		if (!info)
-			return -EINVAL;
-		f->pixelformat = info->id;
-	} else {
-		if (f->index)
-			return -EINVAL;
-		f->pixelformat = ctx->is_stateless ?
-			V4L2_PIX_FMT_FWHT_STATELESS : V4L2_PIX_FMT_FWHT;
-		if (!ctx->is_enc && !ctx->is_stateless)
-			f->flags = V4L2_FMT_FLAG_DYN_RESOLUTION |
-				   V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM;
-	}
-	return 0;
-}
-
-static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
-				   struct v4l2_fmtdesc *f)
-{
-	struct vicodec_ctx *ctx = file2ctx(file);
-
-	return enum_fmt(f, ctx, false);
-}
-
-static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
-				   struct v4l2_fmtdesc *f)
-{
-	struct vicodec_ctx *ctx = file2ctx(file);
-
-	return enum_fmt(f, ctx, true);
-}
-
-static int vidioc_g_fmt(struct vicodec_ctx *ctx, struct v4l2_format *f)
-{
-	struct vb2_queue *vq;
-	struct vicodec_q_data *q_data;
-	struct v4l2_pix_format_mplane *pix_mp;
-	struct v4l2_pix_format *pix;
-	const struct v4l2_fwht_pixfmt_info *info;
-
-	vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
-	if (!vq)
-		return -EINVAL;
-
-	q_data = get_q_data(ctx, f->type);
-	info = q_data->info;
-
-	switch (f->type) {
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-		if (multiplanar)
-			return -EINVAL;
-		pix = &f->fmt.pix;
-		pix->width = q_data->coded_width;
-		pix->height = q_data->coded_height;
-		pix->field = V4L2_FIELD_NONE;
-		pix->pixelformat = info->id;
-		pix->bytesperline = q_data->coded_width *
-					info->bytesperline_mult;
-		pix->sizeimage = q_data->sizeimage;
-		pix->colorspace = ctx->state.colorspace;
-		pix->xfer_func = ctx->state.xfer_func;
-		pix->ycbcr_enc = ctx->state.ycbcr_enc;
-		pix->quantization = ctx->state.quantization;
-		break;
-
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
-	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
-		if (!multiplanar)
-			return -EINVAL;
-		pix_mp = &f->fmt.pix_mp;
-		pix_mp->width = q_data->coded_width;
-		pix_mp->height = q_data->coded_height;
-		pix_mp->field = V4L2_FIELD_NONE;
-		pix_mp->pixelformat = info->id;
-		pix_mp->num_planes = 1;
-		pix_mp->plane_fmt[0].bytesperline =
-				q_data->coded_width * info->bytesperline_mult;
-		pix_mp->plane_fmt[0].sizeimage = q_data->sizeimage;
-		pix_mp->colorspace = ctx->state.colorspace;
-		pix_mp->xfer_func = ctx->state.xfer_func;
-		pix_mp->ycbcr_enc = ctx->state.ycbcr_enc;
-		pix_mp->quantization = ctx->state.quantization;
-		memset(pix_mp->reserved, 0, sizeof(pix_mp->reserved));
-		memset(pix_mp->plane_fmt[0].reserved, 0,
-		       sizeof(pix_mp->plane_fmt[0].reserved));
-		break;
-	default:
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static int vidioc_g_fmt_vid_out(struct file *file, void *priv,
-				struct v4l2_format *f)
-{
-	return vidioc_g_fmt(file2ctx(file), f);
-}
-
-static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
-				struct v4l2_format *f)
-{
-	return vidioc_g_fmt(file2ctx(file), f);
-}
-
-static int vidioc_try_fmt(struct vicodec_ctx *ctx, struct v4l2_format *f)
-{
-	struct v4l2_pix_format_mplane *pix_mp;
-	struct v4l2_pix_format *pix;
-	struct v4l2_plane_pix_format *plane;
-	const struct v4l2_fwht_pixfmt_info *info = ctx->is_stateless ?
-		&pixfmt_stateless_fwht : &pixfmt_fwht;
-
-	switch (f->type) {
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-		pix = &f->fmt.pix;
-		if (pix->pixelformat != V4L2_PIX_FMT_FWHT &&
-		    pix->pixelformat != V4L2_PIX_FMT_FWHT_STATELESS)
-			info = find_fmt(pix->pixelformat);
-
-		pix->width = clamp(pix->width, MIN_WIDTH, MAX_WIDTH);
-		pix->width = vic_round_dim(pix->width, info->width_div);
-
-		pix->height = clamp(pix->height, MIN_HEIGHT, MAX_HEIGHT);
-		pix->height = vic_round_dim(pix->height, info->height_div);
-
-		pix->field = V4L2_FIELD_NONE;
-		pix->bytesperline =
-			pix->width * info->bytesperline_mult;
-		pix->sizeimage = pix->width * pix->height *
-			info->sizeimage_mult / info->sizeimage_div;
-		if (pix->pixelformat == V4L2_PIX_FMT_FWHT)
-			pix->sizeimage += sizeof(struct fwht_cframe_hdr);
-		break;
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
-	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
-		pix_mp = &f->fmt.pix_mp;
-		plane = pix_mp->plane_fmt;
-		if (pix_mp->pixelformat != V4L2_PIX_FMT_FWHT &&
-		    pix_mp->pixelformat != V4L2_PIX_FMT_FWHT_STATELESS)
-			info = find_fmt(pix_mp->pixelformat);
-		pix_mp->num_planes = 1;
-
-		pix_mp->width = clamp(pix_mp->width, MIN_WIDTH, MAX_WIDTH);
-		pix_mp->width = vic_round_dim(pix_mp->width, info->width_div);
-
-		pix_mp->height = clamp(pix_mp->height, MIN_HEIGHT, MAX_HEIGHT);
-		pix_mp->height = vic_round_dim(pix_mp->height,
-					       info->height_div);
-
-		pix_mp->field = V4L2_FIELD_NONE;
-		plane->bytesperline =
-			pix_mp->width * info->bytesperline_mult;
-		plane->sizeimage = pix_mp->width * pix_mp->height *
-			info->sizeimage_mult / info->sizeimage_div;
-		if (pix_mp->pixelformat == V4L2_PIX_FMT_FWHT)
-			plane->sizeimage += sizeof(struct fwht_cframe_hdr);
-		memset(pix_mp->reserved, 0, sizeof(pix_mp->reserved));
-		memset(plane->reserved, 0, sizeof(plane->reserved));
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
-				  struct v4l2_format *f)
-{
-	struct vicodec_ctx *ctx = file2ctx(file);
-	struct v4l2_pix_format_mplane *pix_mp;
-	struct v4l2_pix_format *pix;
-
-	switch (f->type) {
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-		if (multiplanar)
-			return -EINVAL;
-		pix = &f->fmt.pix;
-		pix->pixelformat = ctx->is_enc ? V4L2_PIX_FMT_FWHT :
-				   find_fmt(f->fmt.pix.pixelformat)->id;
-		pix->colorspace = ctx->state.colorspace;
-		pix->xfer_func = ctx->state.xfer_func;
-		pix->ycbcr_enc = ctx->state.ycbcr_enc;
-		pix->quantization = ctx->state.quantization;
-		break;
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
-		if (!multiplanar)
-			return -EINVAL;
-		pix_mp = &f->fmt.pix_mp;
-		pix_mp->pixelformat = ctx->is_enc ? V4L2_PIX_FMT_FWHT :
-				      find_fmt(pix_mp->pixelformat)->id;
-		pix_mp->colorspace = ctx->state.colorspace;
-		pix_mp->xfer_func = ctx->state.xfer_func;
-		pix_mp->ycbcr_enc = ctx->state.ycbcr_enc;
-		pix_mp->quantization = ctx->state.quantization;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	return vidioc_try_fmt(ctx, f);
-}
-
-static int vidioc_try_fmt_vid_out(struct file *file, void *priv,
-				  struct v4l2_format *f)
-{
-	struct vicodec_ctx *ctx = file2ctx(file);
-	struct v4l2_pix_format_mplane *pix_mp;
-	struct v4l2_pix_format *pix;
-
-	switch (f->type) {
-	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-		if (multiplanar)
-			return -EINVAL;
-		pix = &f->fmt.pix;
-		if (ctx->is_enc)
-			pix->pixelformat = find_fmt(pix->pixelformat)->id;
-		else if (ctx->is_stateless)
-			pix->pixelformat = V4L2_PIX_FMT_FWHT_STATELESS;
-		else
-			pix->pixelformat = V4L2_PIX_FMT_FWHT;
-		if (!pix->colorspace)
-			pix->colorspace = V4L2_COLORSPACE_REC709;
-		break;
-	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
-		if (!multiplanar)
-			return -EINVAL;
-		pix_mp = &f->fmt.pix_mp;
-		if (ctx->is_enc)
-			pix_mp->pixelformat = find_fmt(pix_mp->pixelformat)->id;
-		else if (ctx->is_stateless)
-			pix_mp->pixelformat = V4L2_PIX_FMT_FWHT_STATELESS;
-		else
-			pix_mp->pixelformat = V4L2_PIX_FMT_FWHT;
-		if (!pix_mp->colorspace)
-			pix_mp->colorspace = V4L2_COLORSPACE_REC709;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	return vidioc_try_fmt(ctx, f);
-}
-
-static int vidioc_s_fmt(struct vicodec_ctx *ctx, struct v4l2_format *f)
-{
-	struct vicodec_q_data *q_data;
-	struct vb2_queue *vq;
-	bool fmt_changed = true;
-	struct v4l2_pix_format_mplane *pix_mp;
-	struct v4l2_pix_format *pix;
-
-	vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
-	if (!vq)
-		return -EINVAL;
-
-	q_data = get_q_data(ctx, f->type);
-	if (!q_data)
-		return -EINVAL;
-
-	switch (f->type) {
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-		pix = &f->fmt.pix;
-		if (ctx->is_enc && V4L2_TYPE_IS_OUTPUT(f->type))
-			fmt_changed =
-				!q_data->info ||
-				q_data->info->id != pix->pixelformat ||
-				q_data->coded_width != pix->width ||
-				q_data->coded_height != pix->height;
-
-		if (vb2_is_busy(vq) && fmt_changed)
-			return -EBUSY;
-
-		if (pix->pixelformat == V4L2_PIX_FMT_FWHT)
-			q_data->info = &pixfmt_fwht;
-		else if (pix->pixelformat == V4L2_PIX_FMT_FWHT_STATELESS)
-			q_data->info = &pixfmt_stateless_fwht;
-		else
-			q_data->info = find_fmt(pix->pixelformat);
-		q_data->coded_width = pix->width;
-		q_data->coded_height = pix->height;
-		q_data->sizeimage = pix->sizeimage;
-		break;
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
-	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
-		pix_mp = &f->fmt.pix_mp;
-		if (ctx->is_enc && V4L2_TYPE_IS_OUTPUT(f->type))
-			fmt_changed =
-				!q_data->info ||
-				q_data->info->id != pix_mp->pixelformat ||
-				q_data->coded_width != pix_mp->width ||
-				q_data->coded_height != pix_mp->height;
-
-		if (vb2_is_busy(vq) && fmt_changed)
-			return -EBUSY;
-
-		if (pix_mp->pixelformat == V4L2_PIX_FMT_FWHT)
-			q_data->info = &pixfmt_fwht;
-		else if (pix_mp->pixelformat == V4L2_PIX_FMT_FWHT_STATELESS)
-			q_data->info = &pixfmt_stateless_fwht;
-		else
-			q_data->info = find_fmt(pix_mp->pixelformat);
-		q_data->coded_width = pix_mp->width;
-		q_data->coded_height = pix_mp->height;
-		q_data->sizeimage = pix_mp->plane_fmt[0].sizeimage;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	dprintk(ctx->dev,
-		"Setting format for type %d, coded wxh: %dx%d, fourcc: 0x%08x\n",
-		f->type, q_data->coded_width, q_data->coded_height,
-		q_data->info->id);
-
-	return 0;
-}
-
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
-				struct v4l2_format *f)
-{
-	int ret;
-
-	ret = vidioc_try_fmt_vid_cap(file, priv, f);
-	if (ret)
-		return ret;
-
-	return vidioc_s_fmt(file2ctx(file), f);
-}
-
-static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
-				struct v4l2_format *f)
-{
-	struct vicodec_ctx *ctx = file2ctx(file);
-	struct vicodec_q_data *q_data;
-	struct vicodec_q_data *q_data_cap;
-	struct v4l2_pix_format *pix;
-	struct v4l2_pix_format_mplane *pix_mp;
-	u32 coded_w = 0, coded_h = 0;
-	unsigned int size = 0;
-	int ret;
-
-	q_data = get_q_data(ctx, f->type);
-	q_data_cap = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
-
-	ret = vidioc_try_fmt_vid_out(file, priv, f);
-	if (ret)
-		return ret;
-
-	if (ctx->is_enc) {
-		struct vb2_queue *vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
-		struct vb2_queue *vq_cap = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
-							   V4L2_BUF_TYPE_VIDEO_CAPTURE);
-		const struct v4l2_fwht_pixfmt_info *info = ctx->is_stateless ?
-			&pixfmt_stateless_fwht : &pixfmt_fwht;
-
-		if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
-			coded_w = f->fmt.pix.width;
-			coded_h = f->fmt.pix.height;
-		} else {
-			coded_w = f->fmt.pix_mp.width;
-			coded_h = f->fmt.pix_mp.height;
-		}
-		if (vb2_is_busy(vq) && (coded_w != q_data->coded_width ||
-					coded_h != q_data->coded_height))
-			return -EBUSY;
-		size = coded_w * coded_h *
-			info->sizeimage_mult / info->sizeimage_div;
-		if (!ctx->is_stateless)
-			size += sizeof(struct fwht_cframe_hdr);
-
-		if (vb2_is_busy(vq_cap) && size > q_data_cap->sizeimage)
-			return -EBUSY;
-	}
-
-	ret = vidioc_s_fmt(file2ctx(file), f);
-	if (!ret) {
-		if (ctx->is_enc) {
-			q_data->visible_width = coded_w;
-			q_data->visible_height = coded_h;
-			q_data_cap->coded_width = coded_w;
-			q_data_cap->coded_height = coded_h;
-			q_data_cap->sizeimage = size;
-		}
-
-		switch (f->type) {
-		case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-			pix = &f->fmt.pix;
-			ctx->state.colorspace = pix->colorspace;
-			ctx->state.xfer_func = pix->xfer_func;
-			ctx->state.ycbcr_enc = pix->ycbcr_enc;
-			ctx->state.quantization = pix->quantization;
-			break;
-		case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
-			pix_mp = &f->fmt.pix_mp;
-			ctx->state.colorspace = pix_mp->colorspace;
-			ctx->state.xfer_func = pix_mp->xfer_func;
-			ctx->state.ycbcr_enc = pix_mp->ycbcr_enc;
-			ctx->state.quantization = pix_mp->quantization;
-			break;
-		default:
-			break;
-		}
-	}
-	return ret;
-}
-
-static int vidioc_g_selection(struct file *file, void *priv,
-			      struct v4l2_selection *s)
-{
-	struct vicodec_ctx *ctx = file2ctx(file);
-	struct vicodec_q_data *q_data;
-
-	q_data = get_q_data(ctx, s->type);
-	if (!q_data)
-		return -EINVAL;
-	/*
-	 * encoder supports only cropping on the OUTPUT buffer
-	 * decoder supports only composing on the CAPTURE buffer
-	 */
-	if (ctx->is_enc && s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
-		switch (s->target) {
-		case V4L2_SEL_TGT_CROP:
-			s->r.left = 0;
-			s->r.top = 0;
-			s->r.width = q_data->visible_width;
-			s->r.height = q_data->visible_height;
-			return 0;
-		case V4L2_SEL_TGT_CROP_DEFAULT:
-		case V4L2_SEL_TGT_CROP_BOUNDS:
-			s->r.left = 0;
-			s->r.top = 0;
-			s->r.width = q_data->coded_width;
-			s->r.height = q_data->coded_height;
-			return 0;
-		}
-	} else if (!ctx->is_enc && s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-		switch (s->target) {
-		case V4L2_SEL_TGT_COMPOSE:
-			s->r.left = 0;
-			s->r.top = 0;
-			s->r.width = q_data->visible_width;
-			s->r.height = q_data->visible_height;
-			return 0;
-		case V4L2_SEL_TGT_COMPOSE_DEFAULT:
-		case V4L2_SEL_TGT_COMPOSE_BOUNDS:
-			s->r.left = 0;
-			s->r.top = 0;
-			s->r.width = q_data->coded_width;
-			s->r.height = q_data->coded_height;
-			return 0;
-		}
-	}
-	return -EINVAL;
-}
-
-static int vidioc_s_selection(struct file *file, void *priv,
-			      struct v4l2_selection *s)
-{
-	struct vicodec_ctx *ctx = file2ctx(file);
-	struct vicodec_q_data *q_data;
-
-	if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
-		return -EINVAL;
-
-	q_data = get_q_data(ctx, s->type);
-	if (!q_data)
-		return -EINVAL;
-
-	if (!ctx->is_enc || s->target != V4L2_SEL_TGT_CROP)
-		return -EINVAL;
-
-	s->r.left = 0;
-	s->r.top = 0;
-	q_data->visible_width = clamp(s->r.width, MIN_WIDTH,
-				      q_data->coded_width);
-	s->r.width = q_data->visible_width;
-	q_data->visible_height = clamp(s->r.height, MIN_HEIGHT,
-				       q_data->coded_height);
-	s->r.height = q_data->visible_height;
-	return 0;
-}
-
-static int vicodec_encoder_cmd(struct file *file, void *fh,
-			    struct v4l2_encoder_cmd *ec)
-{
-	struct vicodec_ctx *ctx = file2ctx(file);
-	int ret;
-
-	ret = v4l2_m2m_ioctl_try_encoder_cmd(file, fh, ec);
-	if (ret < 0)
-		return ret;
-
-	if (!vb2_is_streaming(&ctx->fh.m2m_ctx->cap_q_ctx.q) ||
-	    !vb2_is_streaming(&ctx->fh.m2m_ctx->out_q_ctx.q))
-		return 0;
-
-	ret = v4l2_m2m_ioctl_encoder_cmd(file, fh, ec);
-	if (ret < 0)
-		return ret;
-
-	if (ec->cmd == V4L2_ENC_CMD_STOP &&
-	    v4l2_m2m_has_stopped(ctx->fh.m2m_ctx))
-		v4l2_event_queue_fh(&ctx->fh, &vicodec_eos_event);
-
-	if (ec->cmd == V4L2_ENC_CMD_START &&
-	    v4l2_m2m_has_stopped(ctx->fh.m2m_ctx))
-		vb2_clear_last_buffer_dequeued(&ctx->fh.m2m_ctx->cap_q_ctx.q);
-
-	return 0;
-}
-
-static int vicodec_decoder_cmd(struct file *file, void *fh,
-			    struct v4l2_decoder_cmd *dc)
-{
-	struct vicodec_ctx *ctx = file2ctx(file);
-	int ret;
-
-	ret = v4l2_m2m_ioctl_try_decoder_cmd(file, fh, dc);
-	if (ret < 0)
-		return ret;
-
-	if (!vb2_is_streaming(&ctx->fh.m2m_ctx->cap_q_ctx.q) ||
-	    !vb2_is_streaming(&ctx->fh.m2m_ctx->out_q_ctx.q))
-		return 0;
-
-	ret = v4l2_m2m_ioctl_decoder_cmd(file, fh, dc);
-	if (ret < 0)
-		return ret;
-
-	if (dc->cmd == V4L2_DEC_CMD_STOP &&
-	    v4l2_m2m_has_stopped(ctx->fh.m2m_ctx))
-		v4l2_event_queue_fh(&ctx->fh, &vicodec_eos_event);
-
-	if (dc->cmd == V4L2_DEC_CMD_START &&
-	    v4l2_m2m_has_stopped(ctx->fh.m2m_ctx))
-		vb2_clear_last_buffer_dequeued(&ctx->fh.m2m_ctx->cap_q_ctx.q);
-
-	return 0;
-}
-
-static int vicodec_enum_framesizes(struct file *file, void *fh,
-				   struct v4l2_frmsizeenum *fsize)
-{
-	switch (fsize->pixel_format) {
-	case V4L2_PIX_FMT_FWHT_STATELESS:
-		break;
-	case V4L2_PIX_FMT_FWHT:
-		break;
-	default:
-		if (find_fmt(fsize->pixel_format)->id == fsize->pixel_format)
-			break;
-		return -EINVAL;
-	}
-
-	if (fsize->index)
-		return -EINVAL;
-
-	fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
-
-	fsize->stepwise.min_width = MIN_WIDTH;
-	fsize->stepwise.max_width = MAX_WIDTH;
-	fsize->stepwise.step_width = 8;
-	fsize->stepwise.min_height = MIN_HEIGHT;
-	fsize->stepwise.max_height = MAX_HEIGHT;
-	fsize->stepwise.step_height = 8;
-
-	return 0;
-}
-
-static int vicodec_subscribe_event(struct v4l2_fh *fh,
-				const struct v4l2_event_subscription *sub)
-{
-	struct vicodec_ctx *ctx = container_of(fh, struct vicodec_ctx, fh);
-
-	switch (sub->type) {
-	case V4L2_EVENT_SOURCE_CHANGE:
-		if (ctx->is_enc)
-			return -EINVAL;
-		/* fall through */
-	case V4L2_EVENT_EOS:
-		if (ctx->is_stateless)
-			return -EINVAL;
-		return v4l2_event_subscribe(fh, sub, 0, NULL);
-	default:
-		return v4l2_ctrl_subscribe_event(fh, sub);
-	}
-}
-
-static const struct v4l2_ioctl_ops vicodec_ioctl_ops = {
-	.vidioc_querycap	= vidioc_querycap,
-
-	.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
-	.vidioc_g_fmt_vid_cap	= vidioc_g_fmt_vid_cap,
-	.vidioc_try_fmt_vid_cap	= vidioc_try_fmt_vid_cap,
-	.vidioc_s_fmt_vid_cap	= vidioc_s_fmt_vid_cap,
-
-	.vidioc_g_fmt_vid_cap_mplane	= vidioc_g_fmt_vid_cap,
-	.vidioc_try_fmt_vid_cap_mplane	= vidioc_try_fmt_vid_cap,
-	.vidioc_s_fmt_vid_cap_mplane	= vidioc_s_fmt_vid_cap,
-
-	.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,
-
-	.vidioc_g_fmt_vid_out_mplane	= vidioc_g_fmt_vid_out,
-	.vidioc_try_fmt_vid_out_mplane	= vidioc_try_fmt_vid_out,
-	.vidioc_s_fmt_vid_out_mplane	= vidioc_s_fmt_vid_out,
-
-	.vidioc_reqbufs		= v4l2_m2m_ioctl_reqbufs,
-	.vidioc_querybuf	= v4l2_m2m_ioctl_querybuf,
-	.vidioc_qbuf		= v4l2_m2m_ioctl_qbuf,
-	.vidioc_dqbuf		= v4l2_m2m_ioctl_dqbuf,
-	.vidioc_prepare_buf	= v4l2_m2m_ioctl_prepare_buf,
-	.vidioc_create_bufs	= v4l2_m2m_ioctl_create_bufs,
-	.vidioc_expbuf		= v4l2_m2m_ioctl_expbuf,
-
-	.vidioc_streamon	= v4l2_m2m_ioctl_streamon,
-	.vidioc_streamoff	= v4l2_m2m_ioctl_streamoff,
-
-	.vidioc_g_selection	= vidioc_g_selection,
-	.vidioc_s_selection	= vidioc_s_selection,
-
-	.vidioc_try_encoder_cmd	= v4l2_m2m_ioctl_try_encoder_cmd,
-	.vidioc_encoder_cmd	= vicodec_encoder_cmd,
-	.vidioc_try_decoder_cmd	= v4l2_m2m_ioctl_try_decoder_cmd,
-	.vidioc_decoder_cmd	= vicodec_decoder_cmd,
-	.vidioc_enum_framesizes = vicodec_enum_framesizes,
-
-	.vidioc_subscribe_event = vicodec_subscribe_event,
-	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
-};
-
-
-/*
- * Queue operations
- */
-
-static int vicodec_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
-			       unsigned int *nplanes, unsigned int sizes[],
-			       struct device *alloc_devs[])
-{
-	struct vicodec_ctx *ctx = vb2_get_drv_priv(vq);
-	struct vicodec_q_data *q_data = get_q_data(ctx, vq->type);
-	unsigned int size = q_data->sizeimage;
-
-	if (*nplanes)
-		return sizes[0] < size ? -EINVAL : 0;
-
-	*nplanes = 1;
-	sizes[0] = size;
-	q_data->vb2_sizeimage = size;
-	return 0;
-}
-
-static int vicodec_buf_out_validate(struct vb2_buffer *vb)
-{
-	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-
-	vbuf->field = V4L2_FIELD_NONE;
-	return 0;
-}
-
-static int vicodec_buf_prepare(struct vb2_buffer *vb)
-{
-	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-	struct vicodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
-	struct vicodec_q_data *q_data;
-
-	dprintk(ctx->dev, "type: %d\n", vb->vb2_queue->type);
-
-	q_data = get_q_data(ctx, vb->vb2_queue->type);
-	if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
-		if (vbuf->field == V4L2_FIELD_ANY)
-			vbuf->field = V4L2_FIELD_NONE;
-		if (vbuf->field != V4L2_FIELD_NONE) {
-			dprintk(ctx->dev, "%s field isn't supported\n",
-					__func__);
-			return -EINVAL;
-		}
-	}
-
-	if (vb2_plane_size(vb, 0) < q_data->vb2_sizeimage) {
-		dprintk(ctx->dev,
-			"%s data will not fit into plane (%lu < %lu)\n",
-			__func__, vb2_plane_size(vb, 0),
-			(long)q_data->vb2_sizeimage);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static void vicodec_buf_queue(struct vb2_buffer *vb)
-{
-	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-	struct vicodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
-	unsigned int sz = vb2_get_plane_payload(&vbuf->vb2_buf, 0);
-	u8 *p_src = vb2_plane_vaddr(&vbuf->vb2_buf, 0);
-	u8 *p = p_src;
-	struct vb2_queue *vq_out = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
-						   V4L2_BUF_TYPE_VIDEO_OUTPUT);
-	struct vb2_queue *vq_cap = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
-						   V4L2_BUF_TYPE_VIDEO_CAPTURE);
-	bool header_valid = false;
-	static const struct v4l2_event rs_event = {
-		.type = V4L2_EVENT_SOURCE_CHANGE,
-		.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION,
-	};
-
-	if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type) &&
-	    vb2_is_streaming(vb->vb2_queue) &&
-	    v4l2_m2m_dst_buf_is_last(ctx->fh.m2m_ctx)) {
-		unsigned int i;
-
-		for (i = 0; i < vb->num_planes; i++)
-			vb->planes[i].bytesused = 0;
-
-		vbuf->field = V4L2_FIELD_NONE;
-		vbuf->sequence =
-			get_q_data(ctx, vb->vb2_queue->type)->sequence++;
-
-		v4l2_m2m_last_buffer_done(ctx->fh.m2m_ctx, vbuf);
-		v4l2_event_queue_fh(&ctx->fh, &vicodec_eos_event);
-		return;
-	}
-
-	/* buf_queue handles only the first source change event */
-	if (ctx->first_source_change_sent) {
-		v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
-		return;
-	}
-
-	/*
-	 * if both queues are streaming, the source change event is
-	 * handled in job_ready
-	 */
-	if (vb2_is_streaming(vq_cap) && vb2_is_streaming(vq_out)) {
-		v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
-		return;
-	}
-
-	/*
-	 * source change event is relevant only for the stateful decoder
-	 * in the compressed stream
-	 */
-	if (ctx->is_stateless || ctx->is_enc ||
-	    !V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
-		v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
-		return;
-	}
-
-	do {
-		enum vb2_buffer_state state =
-			get_next_header(ctx, &p, p_src + sz - p);
-
-		if (ctx->header_size < sizeof(struct fwht_cframe_hdr)) {
-			v4l2_m2m_buf_done(vbuf, state);
-			return;
-		}
-		header_valid = is_header_valid(&ctx->state.header);
-		/*
-		 * p points right after the end of the header in the
-		 * buffer. If the header is invalid we set p to point
-		 * to the next byte after the start of the header
-		 */
-		if (!header_valid) {
-			p = p - sizeof(struct fwht_cframe_hdr) + 1;
-			if (p < p_src)
-				p = p_src;
-			ctx->header_size = 0;
-			ctx->comp_magic_cnt = 0;
-		}
-
-	} while (!header_valid);
-
-	ctx->cur_buf_offset = p - p_src;
-	update_capture_data_from_header(ctx);
-	ctx->first_source_change_sent = true;
-	v4l2_event_queue_fh(&ctx->fh, &rs_event);
-	v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
-}
-
-static void vicodec_return_bufs(struct vb2_queue *q, u32 state)
-{
-	struct vicodec_ctx *ctx = vb2_get_drv_priv(q);
-	struct vb2_v4l2_buffer *vbuf;
-
-	for (;;) {
-		if (V4L2_TYPE_IS_OUTPUT(q->type))
-			vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
-		else
-			vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
-		if (vbuf == NULL)
-			return;
-		v4l2_ctrl_request_complete(vbuf->vb2_buf.req_obj.req,
-					   &ctx->hdl);
-		spin_lock(ctx->lock);
-		v4l2_m2m_buf_done(vbuf, state);
-		spin_unlock(ctx->lock);
-	}
-}
-
-static unsigned int total_frame_size(struct vicodec_q_data *q_data)
-{
-	unsigned int size;
-	unsigned int chroma_div;
-
-	if (!q_data->info) {
-		WARN_ON(1);
-		return 0;
-	}
-	size = q_data->coded_width * q_data->coded_height;
-	chroma_div = q_data->info->width_div * q_data->info->height_div;
-
-	if (q_data->info->components_num == 4)
-		return 2 * size + 2 * (size / chroma_div);
-	else if (q_data->info->components_num == 3)
-		return size + 2 * (size / chroma_div);
-	return size;
-}
-
-static int vicodec_start_streaming(struct vb2_queue *q,
-				   unsigned int count)
-{
-	struct vicodec_ctx *ctx = vb2_get_drv_priv(q);
-	struct vicodec_q_data *q_data = get_q_data(ctx, q->type);
-	struct v4l2_fwht_state *state = &ctx->state;
-	const struct v4l2_fwht_pixfmt_info *info = q_data->info;
-	unsigned int size = q_data->coded_width * q_data->coded_height;
-	unsigned int chroma_div;
-	unsigned int total_planes_size;
-	u8 *new_comp_frame = NULL;
-
-	chroma_div = info->width_div * info->height_div;
-	q_data->sequence = 0;
-
-	v4l2_m2m_update_start_streaming_state(ctx->fh.m2m_ctx, q);
-
-	state->gop_cnt = 0;
-
-	if ((V4L2_TYPE_IS_OUTPUT(q->type) && !ctx->is_enc) ||
-	    (!V4L2_TYPE_IS_OUTPUT(q->type) && ctx->is_enc))
-		return 0;
-
-	if (info->id == V4L2_PIX_FMT_FWHT ||
-	    info->id == V4L2_PIX_FMT_FWHT_STATELESS) {
-		vicodec_return_bufs(q, VB2_BUF_STATE_QUEUED);
-		return -EINVAL;
-	}
-	total_planes_size = total_frame_size(q_data);
-	ctx->comp_max_size = total_planes_size;
-
-	state->visible_width = q_data->visible_width;
-	state->visible_height = q_data->visible_height;
-	state->coded_width = q_data->coded_width;
-	state->coded_height = q_data->coded_height;
-	state->stride = q_data->coded_width *
-				info->bytesperline_mult;
-
-	if (ctx->is_stateless) {
-		state->ref_stride = state->stride;
-		return 0;
-	}
-	state->ref_stride = q_data->coded_width * info->luma_alpha_step;
-
-	state->ref_frame.buf = kvmalloc(total_planes_size, GFP_KERNEL);
-	state->ref_frame.luma = state->ref_frame.buf;
-	new_comp_frame = kvmalloc(ctx->comp_max_size, GFP_KERNEL);
-
-	if (!state->ref_frame.luma || !new_comp_frame) {
-		kvfree(state->ref_frame.luma);
-		kvfree(new_comp_frame);
-		vicodec_return_bufs(q, VB2_BUF_STATE_QUEUED);
-		return -ENOMEM;
-	}
-	/*
-	 * if state->compressed_frame was already allocated then
-	 * it contain data of the first frame of the new resolution
-	 */
-	if (state->compressed_frame) {
-		if (ctx->comp_size > ctx->comp_max_size)
-			ctx->comp_size = ctx->comp_max_size;
-
-		memcpy(new_comp_frame,
-		       state->compressed_frame, ctx->comp_size);
-	}
-
-	kvfree(state->compressed_frame);
-	state->compressed_frame = new_comp_frame;
-
-	if (info->components_num < 3) {
-		state->ref_frame.cb = NULL;
-		state->ref_frame.cr = NULL;
-		state->ref_frame.alpha = NULL;
-		return 0;
-	}
-
-	state->ref_frame.cb = state->ref_frame.luma + size;
-	state->ref_frame.cr = state->ref_frame.cb + size / chroma_div;
-
-	if (info->components_num == 4)
-		state->ref_frame.alpha =
-			state->ref_frame.cr + size / chroma_div;
-	else
-		state->ref_frame.alpha = NULL;
-
-	return 0;
-}
-
-static void vicodec_stop_streaming(struct vb2_queue *q)
-{
-	struct vicodec_ctx *ctx = vb2_get_drv_priv(q);
-
-	vicodec_return_bufs(q, VB2_BUF_STATE_ERROR);
-
-	v4l2_m2m_update_stop_streaming_state(ctx->fh.m2m_ctx, q);
-
-	if (V4L2_TYPE_IS_OUTPUT(q->type) &&
-	    v4l2_m2m_has_stopped(ctx->fh.m2m_ctx))
-		v4l2_event_queue_fh(&ctx->fh, &vicodec_eos_event);
-
-	if (!ctx->is_enc && V4L2_TYPE_IS_OUTPUT(q->type))
-		ctx->first_source_change_sent = false;
-
-	if ((!V4L2_TYPE_IS_OUTPUT(q->type) && !ctx->is_enc) ||
-	    (V4L2_TYPE_IS_OUTPUT(q->type) && ctx->is_enc)) {
-		if (!ctx->is_stateless)
-			kvfree(ctx->state.ref_frame.buf);
-		ctx->state.ref_frame.buf = NULL;
-		ctx->state.ref_frame.luma = NULL;
-		ctx->comp_max_size = 0;
-		ctx->source_changed = false;
-	}
-	if (V4L2_TYPE_IS_OUTPUT(q->type) && !ctx->is_enc) {
-		ctx->cur_buf_offset = 0;
-		ctx->comp_size = 0;
-		ctx->header_size = 0;
-		ctx->comp_magic_cnt = 0;
-		ctx->comp_has_frame = 0;
-		ctx->comp_has_next_frame = 0;
-	}
-}
-
-static void vicodec_buf_request_complete(struct vb2_buffer *vb)
-{
-	struct vicodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
-
-	v4l2_ctrl_request_complete(vb->req_obj.req, &ctx->hdl);
-}
-
-
-static const struct vb2_ops vicodec_qops = {
-	.queue_setup		= vicodec_queue_setup,
-	.buf_out_validate	= vicodec_buf_out_validate,
-	.buf_prepare		= vicodec_buf_prepare,
-	.buf_queue		= vicodec_buf_queue,
-	.buf_request_complete	= vicodec_buf_request_complete,
-	.start_streaming	= vicodec_start_streaming,
-	.stop_streaming		= vicodec_stop_streaming,
-	.wait_prepare		= vb2_ops_wait_prepare,
-	.wait_finish		= vb2_ops_wait_finish,
-};
-
-static int queue_init(void *priv, struct vb2_queue *src_vq,
-		      struct vb2_queue *dst_vq)
-{
-	struct vicodec_ctx *ctx = priv;
-	int ret;
-
-	src_vq->type = (multiplanar ?
-			V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE :
-			V4L2_BUF_TYPE_VIDEO_OUTPUT);
-	src_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
-	src_vq->drv_priv = ctx;
-	src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
-	src_vq->ops = &vicodec_qops;
-	src_vq->mem_ops = &vb2_vmalloc_memops;
-	src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
-	if (ctx->is_enc)
-		src_vq->lock = &ctx->dev->stateful_enc.mutex;
-	else if (ctx->is_stateless)
-		src_vq->lock = &ctx->dev->stateless_dec.mutex;
-	else
-		src_vq->lock = &ctx->dev->stateful_dec.mutex;
-	src_vq->supports_requests = ctx->is_stateless;
-	src_vq->requires_requests = ctx->is_stateless;
-	ret = vb2_queue_init(src_vq);
-	if (ret)
-		return ret;
-
-	dst_vq->type = (multiplanar ?
-			V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
-			V4L2_BUF_TYPE_VIDEO_CAPTURE);
-	dst_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
-	dst_vq->drv_priv = ctx;
-	dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
-	dst_vq->ops = &vicodec_qops;
-	dst_vq->mem_ops = &vb2_vmalloc_memops;
-	dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
-	dst_vq->lock = src_vq->lock;
-
-	return vb2_queue_init(dst_vq);
-}
-
-static int vicodec_try_ctrl(struct v4l2_ctrl *ctrl)
-{
-	struct vicodec_ctx *ctx = container_of(ctrl->handler,
-			struct vicodec_ctx, hdl);
-	const struct v4l2_ctrl_fwht_params *params;
-	struct vicodec_q_data *q_dst = get_q_data(ctx,
-			V4L2_BUF_TYPE_VIDEO_CAPTURE);
-
-	switch (ctrl->id) {
-	case V4L2_CID_MPEG_VIDEO_FWHT_PARAMS:
-		if (!q_dst->info)
-			return -EINVAL;
-		params = ctrl->p_new.p_fwht_params;
-		if (params->width > q_dst->coded_width ||
-		    params->width < MIN_WIDTH ||
-		    params->height > q_dst->coded_height ||
-		    params->height < MIN_HEIGHT)
-			return -EINVAL;
-		if (!validate_by_version(params->flags, params->version))
-			return -EINVAL;
-		if (!validate_stateless_params_flags(params, q_dst->info))
-			return -EINVAL;
-		return 0;
-	default:
-		return 0;
-	}
-	return 0;
-}
-
-static void update_header_from_stateless_params(struct vicodec_ctx *ctx,
-						const struct v4l2_ctrl_fwht_params *params)
-{
-	struct fwht_cframe_hdr *p_hdr = &ctx->state.header;
-
-	p_hdr->magic1 = FWHT_MAGIC1;
-	p_hdr->magic2 = FWHT_MAGIC2;
-	p_hdr->version = htonl(params->version);
-	p_hdr->width = htonl(params->width);
-	p_hdr->height = htonl(params->height);
-	p_hdr->flags = htonl(params->flags);
-	p_hdr->colorspace = htonl(params->colorspace);
-	p_hdr->xfer_func = htonl(params->xfer_func);
-	p_hdr->ycbcr_enc = htonl(params->ycbcr_enc);
-	p_hdr->quantization = htonl(params->quantization);
-}
-
-static int vicodec_s_ctrl(struct v4l2_ctrl *ctrl)
-{
-	struct vicodec_ctx *ctx = container_of(ctrl->handler,
-					       struct vicodec_ctx, hdl);
-	const struct v4l2_ctrl_fwht_params *params;
-
-	switch (ctrl->id) {
-	case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
-		ctx->state.gop_size = ctrl->val;
-		return 0;
-	case V4L2_CID_FWHT_I_FRAME_QP:
-		ctx->state.i_frame_qp = ctrl->val;
-		return 0;
-	case V4L2_CID_FWHT_P_FRAME_QP:
-		ctx->state.p_frame_qp = ctrl->val;
-		return 0;
-	case V4L2_CID_MPEG_VIDEO_FWHT_PARAMS:
-		params = ctrl->p_new.p_fwht_params;
-		update_header_from_stateless_params(ctx, params);
-		ctx->state.ref_frame_ts = params->backward_ref_ts;
-		return 0;
-	}
-	return -EINVAL;
-}
-
-static const struct v4l2_ctrl_ops vicodec_ctrl_ops = {
-	.s_ctrl = vicodec_s_ctrl,
-	.try_ctrl = vicodec_try_ctrl,
-};
-
-static const struct v4l2_ctrl_config vicodec_ctrl_stateless_state = {
-	.ops		= &vicodec_ctrl_ops,
-	.id		= V4L2_CID_MPEG_VIDEO_FWHT_PARAMS,
-	.elem_size      = sizeof(struct v4l2_ctrl_fwht_params),
-};
-
-/*
- * File operations
- */
-static int vicodec_open(struct file *file)
-{
-	const struct v4l2_fwht_pixfmt_info *info = v4l2_fwht_get_pixfmt(0);
-	struct video_device *vfd = video_devdata(file);
-	struct vicodec_dev *dev = video_drvdata(file);
-	struct vicodec_ctx *ctx = NULL;
-	struct v4l2_ctrl_handler *hdl;
-	unsigned int raw_size;
-	unsigned int comp_size;
-	int rc = 0;
-
-	if (mutex_lock_interruptible(vfd->lock))
-		return -ERESTARTSYS;
-	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
-	if (!ctx) {
-		rc = -ENOMEM;
-		goto open_unlock;
-	}
-
-	if (vfd == &dev->stateful_enc.vfd)
-		ctx->is_enc = true;
-	else if (vfd == &dev->stateless_dec.vfd)
-		ctx->is_stateless = true;
-
-	v4l2_fh_init(&ctx->fh, video_devdata(file));
-	file->private_data = &ctx->fh;
-	ctx->dev = dev;
-	hdl = &ctx->hdl;
-	v4l2_ctrl_handler_init(hdl, 5);
-	v4l2_ctrl_new_std(hdl, &vicodec_ctrl_ops, V4L2_CID_MPEG_VIDEO_GOP_SIZE,
-			  1, 16, 1, 10);
-	v4l2_ctrl_new_std(hdl, &vicodec_ctrl_ops, V4L2_CID_FWHT_I_FRAME_QP,
-			  1, 31, 1, 20);
-	v4l2_ctrl_new_std(hdl, &vicodec_ctrl_ops, V4L2_CID_FWHT_P_FRAME_QP,
-			  1, 31, 1, 20);
-	if (ctx->is_enc)
-		v4l2_ctrl_new_std(hdl, &vicodec_ctrl_ops,
-				  V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, 1, 1, 1, 1);
-	if (ctx->is_stateless)
-		v4l2_ctrl_new_custom(hdl, &vicodec_ctrl_stateless_state, NULL);
-	if (hdl->error) {
-		rc = hdl->error;
-		v4l2_ctrl_handler_free(hdl);
-		kfree(ctx);
-		goto open_unlock;
-	}
-	ctx->fh.ctrl_handler = hdl;
-	v4l2_ctrl_handler_setup(hdl);
-
-	if (ctx->is_enc)
-		ctx->q_data[V4L2_M2M_SRC].info = info;
-	else if (ctx->is_stateless)
-		ctx->q_data[V4L2_M2M_SRC].info = &pixfmt_stateless_fwht;
-	else
-		ctx->q_data[V4L2_M2M_SRC].info = &pixfmt_fwht;
-	ctx->q_data[V4L2_M2M_SRC].coded_width = 1280;
-	ctx->q_data[V4L2_M2M_SRC].coded_height = 720;
-	ctx->q_data[V4L2_M2M_SRC].visible_width = 1280;
-	ctx->q_data[V4L2_M2M_SRC].visible_height = 720;
-	raw_size = 1280 * 720 * info->sizeimage_mult / info->sizeimage_div;
-	comp_size = 1280 * 720 * pixfmt_fwht.sizeimage_mult /
-				 pixfmt_fwht.sizeimage_div;
-	if (ctx->is_enc)
-		ctx->q_data[V4L2_M2M_SRC].sizeimage = raw_size;
-	else if (ctx->is_stateless)
-		ctx->q_data[V4L2_M2M_SRC].sizeimage = comp_size;
-	else
-		ctx->q_data[V4L2_M2M_SRC].sizeimage =
-			comp_size + sizeof(struct fwht_cframe_hdr);
-	ctx->q_data[V4L2_M2M_DST] = ctx->q_data[V4L2_M2M_SRC];
-	if (ctx->is_enc) {
-		ctx->q_data[V4L2_M2M_DST].info = &pixfmt_fwht;
-		ctx->q_data[V4L2_M2M_DST].sizeimage =
-			comp_size + sizeof(struct fwht_cframe_hdr);
-	} else {
-		ctx->q_data[V4L2_M2M_DST].info = info;
-		ctx->q_data[V4L2_M2M_DST].sizeimage = raw_size;
-	}
-
-	ctx->state.colorspace = V4L2_COLORSPACE_REC709;
-
-	if (ctx->is_enc) {
-		ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->stateful_enc.m2m_dev,
-						    ctx, &queue_init);
-		ctx->lock = &dev->stateful_enc.lock;
-	} else if (ctx->is_stateless) {
-		ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->stateless_dec.m2m_dev,
-						    ctx, &queue_init);
-		ctx->lock = &dev->stateless_dec.lock;
-	} else {
-		ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->stateful_dec.m2m_dev,
-						    ctx, &queue_init);
-		ctx->lock = &dev->stateful_dec.lock;
-	}
-
-	if (IS_ERR(ctx->fh.m2m_ctx)) {
-		rc = PTR_ERR(ctx->fh.m2m_ctx);
-
-		v4l2_ctrl_handler_free(hdl);
-		v4l2_fh_exit(&ctx->fh);
-		kfree(ctx);
-		goto open_unlock;
-	}
-
-	v4l2_fh_add(&ctx->fh);
-
-open_unlock:
-	mutex_unlock(vfd->lock);
-	return rc;
-}
-
-static int vicodec_release(struct file *file)
-{
-	struct video_device *vfd = video_devdata(file);
-	struct vicodec_ctx *ctx = file2ctx(file);
-
-	mutex_lock(vfd->lock);
-	v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
-	mutex_unlock(vfd->lock);
-	v4l2_fh_del(&ctx->fh);
-	v4l2_fh_exit(&ctx->fh);
-	v4l2_ctrl_handler_free(&ctx->hdl);
-	kvfree(ctx->state.compressed_frame);
-	kfree(ctx);
-
-	return 0;
-}
-
-static int vicodec_request_validate(struct media_request *req)
-{
-	struct media_request_object *obj;
-	struct v4l2_ctrl_handler *parent_hdl, *hdl;
-	struct vicodec_ctx *ctx = NULL;
-	struct v4l2_ctrl *ctrl;
-	unsigned int count;
-
-	list_for_each_entry(obj, &req->objects, list) {
-		struct vb2_buffer *vb;
-
-		if (vb2_request_object_is_buffer(obj)) {
-			vb = container_of(obj, struct vb2_buffer, req_obj);
-			ctx = vb2_get_drv_priv(vb->vb2_queue);
-
-			break;
-		}
-	}
-
-	if (!ctx) {
-		pr_err("No buffer was provided with the request\n");
-		return -ENOENT;
-	}
-
-	count = vb2_request_buffer_cnt(req);
-	if (!count) {
-		v4l2_info(&ctx->dev->v4l2_dev,
-			  "No buffer was provided with the request\n");
-		return -ENOENT;
-	} else if (count > 1) {
-		v4l2_info(&ctx->dev->v4l2_dev,
-			  "More than one buffer was provided with the request\n");
-		return -EINVAL;
-	}
-
-	parent_hdl = &ctx->hdl;
-
-	hdl = v4l2_ctrl_request_hdl_find(req, parent_hdl);
-	if (!hdl) {
-		v4l2_info(&ctx->dev->v4l2_dev, "Missing codec control\n");
-		return -ENOENT;
-	}
-	ctrl = v4l2_ctrl_request_hdl_ctrl_find(hdl,
-					       vicodec_ctrl_stateless_state.id);
-	if (!ctrl) {
-		v4l2_info(&ctx->dev->v4l2_dev,
-			  "Missing required codec control\n");
-		return -ENOENT;
-	}
-
-	return vb2_request_validate(req);
-}
-
-static const struct v4l2_file_operations vicodec_fops = {
-	.owner		= THIS_MODULE,
-	.open		= vicodec_open,
-	.release	= vicodec_release,
-	.poll		= v4l2_m2m_fop_poll,
-	.unlocked_ioctl	= video_ioctl2,
-	.mmap		= v4l2_m2m_fop_mmap,
-};
-
-static const struct video_device vicodec_videodev = {
-	.name		= VICODEC_NAME,
-	.vfl_dir	= VFL_DIR_M2M,
-	.fops		= &vicodec_fops,
-	.ioctl_ops	= &vicodec_ioctl_ops,
-	.minor		= -1,
-	.release	= video_device_release_empty,
-};
-
-static const struct media_device_ops vicodec_m2m_media_ops = {
-	.req_validate	= vicodec_request_validate,
-	.req_queue	= v4l2_m2m_request_queue,
-};
-
-static const struct v4l2_m2m_ops m2m_ops = {
-	.device_run	= device_run,
-	.job_ready	= job_ready,
-};
-
-static int register_instance(struct vicodec_dev *dev,
-			     struct vicodec_dev_instance *dev_instance,
-			     const char *name, bool is_enc)
-{
-	struct video_device *vfd;
-	int ret;
-
-	spin_lock_init(&dev_instance->lock);
-	mutex_init(&dev_instance->mutex);
-	dev_instance->m2m_dev = v4l2_m2m_init(&m2m_ops);
-	if (IS_ERR(dev_instance->m2m_dev)) {
-		v4l2_err(&dev->v4l2_dev, "Failed to init vicodec enc device\n");
-		return PTR_ERR(dev_instance->m2m_dev);
-	}
-
-	dev_instance->vfd = vicodec_videodev;
-	vfd = &dev_instance->vfd;
-	vfd->lock = &dev_instance->mutex;
-	vfd->v4l2_dev = &dev->v4l2_dev;
-	strscpy(vfd->name, name, sizeof(vfd->name));
-	vfd->device_caps = V4L2_CAP_STREAMING |
-		(multiplanar ? V4L2_CAP_VIDEO_M2M_MPLANE : V4L2_CAP_VIDEO_M2M);
-	if (is_enc) {
-		v4l2_disable_ioctl(vfd, VIDIOC_DECODER_CMD);
-		v4l2_disable_ioctl(vfd, VIDIOC_TRY_DECODER_CMD);
-	} else {
-		v4l2_disable_ioctl(vfd, VIDIOC_ENCODER_CMD);
-		v4l2_disable_ioctl(vfd, VIDIOC_TRY_ENCODER_CMD);
-	}
-	video_set_drvdata(vfd, dev);
-
-	ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0);
-	if (ret) {
-		v4l2_err(&dev->v4l2_dev, "Failed to register video device '%s'\n", name);
-		v4l2_m2m_release(dev_instance->m2m_dev);
-		return ret;
-	}
-	v4l2_info(&dev->v4l2_dev, "Device '%s' registered as /dev/video%d\n",
-		  name, vfd->num);
-	return 0;
-}
-
-static void vicodec_v4l2_dev_release(struct v4l2_device *v4l2_dev)
-{
-	struct vicodec_dev *dev = container_of(v4l2_dev, struct vicodec_dev, v4l2_dev);
-
-	v4l2_device_unregister(&dev->v4l2_dev);
-	v4l2_m2m_release(dev->stateful_enc.m2m_dev);
-	v4l2_m2m_release(dev->stateful_dec.m2m_dev);
-	v4l2_m2m_release(dev->stateless_dec.m2m_dev);
-#ifdef CONFIG_MEDIA_CONTROLLER
-	media_device_cleanup(&dev->mdev);
-#endif
-	kfree(dev);
-}
-
-static int vicodec_probe(struct platform_device *pdev)
-{
-	struct vicodec_dev *dev;
-	int ret;
-
-	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-	if (!dev)
-		return -ENOMEM;
-
-	ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
-	if (ret)
-		goto free_dev;
-
-	dev->v4l2_dev.release = vicodec_v4l2_dev_release;
-
-#ifdef CONFIG_MEDIA_CONTROLLER
-	dev->mdev.dev = &pdev->dev;
-	strscpy(dev->mdev.model, "vicodec", sizeof(dev->mdev.model));
-	strscpy(dev->mdev.bus_info, "platform:vicodec",
-		sizeof(dev->mdev.bus_info));
-	media_device_init(&dev->mdev);
-	dev->mdev.ops = &vicodec_m2m_media_ops;
-	dev->v4l2_dev.mdev = &dev->mdev;
-#endif
-
-	platform_set_drvdata(pdev, dev);
-
-	if (register_instance(dev, &dev->stateful_enc,
-			      "stateful-encoder", true))
-		goto unreg_dev;
-
-	if (register_instance(dev, &dev->stateful_dec,
-			      "stateful-decoder", false))
-		goto unreg_sf_enc;
-
-	if (register_instance(dev, &dev->stateless_dec,
-			      "stateless-decoder", false))
-		goto unreg_sf_dec;
-
-#ifdef CONFIG_MEDIA_CONTROLLER
-	ret = v4l2_m2m_register_media_controller(dev->stateful_enc.m2m_dev,
-						 &dev->stateful_enc.vfd,
-						 MEDIA_ENT_F_PROC_VIDEO_ENCODER);
-	if (ret) {
-		v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem media controller for enc\n");
-		goto unreg_m2m;
-	}
-
-	ret = v4l2_m2m_register_media_controller(dev->stateful_dec.m2m_dev,
-						 &dev->stateful_dec.vfd,
-						 MEDIA_ENT_F_PROC_VIDEO_DECODER);
-	if (ret) {
-		v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem media controller for dec\n");
-		goto unreg_m2m_sf_enc_mc;
-	}
-
-	ret = v4l2_m2m_register_media_controller(dev->stateless_dec.m2m_dev,
-						 &dev->stateless_dec.vfd,
-						 MEDIA_ENT_F_PROC_VIDEO_DECODER);
-	if (ret) {
-		v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem media controller for stateless dec\n");
-		goto unreg_m2m_sf_dec_mc;
-	}
-
-	ret = media_device_register(&dev->mdev);
-	if (ret) {
-		v4l2_err(&dev->v4l2_dev, "Failed to register mem2mem media device\n");
-		goto unreg_m2m_sl_dec_mc;
-	}
-#endif
-	return 0;
-
-#ifdef CONFIG_MEDIA_CONTROLLER
-unreg_m2m_sl_dec_mc:
-	v4l2_m2m_unregister_media_controller(dev->stateless_dec.m2m_dev);
-unreg_m2m_sf_dec_mc:
-	v4l2_m2m_unregister_media_controller(dev->stateful_dec.m2m_dev);
-unreg_m2m_sf_enc_mc:
-	v4l2_m2m_unregister_media_controller(dev->stateful_enc.m2m_dev);
-unreg_m2m:
-	video_unregister_device(&dev->stateless_dec.vfd);
-	v4l2_m2m_release(dev->stateless_dec.m2m_dev);
-#endif
-unreg_sf_dec:
-	video_unregister_device(&dev->stateful_dec.vfd);
-	v4l2_m2m_release(dev->stateful_dec.m2m_dev);
-unreg_sf_enc:
-	video_unregister_device(&dev->stateful_enc.vfd);
-	v4l2_m2m_release(dev->stateful_enc.m2m_dev);
-unreg_dev:
-	v4l2_device_unregister(&dev->v4l2_dev);
-free_dev:
-	kfree(dev);
-
-	return ret;
-}
-
-static int vicodec_remove(struct platform_device *pdev)
-{
-	struct vicodec_dev *dev = platform_get_drvdata(pdev);
-
-	v4l2_info(&dev->v4l2_dev, "Removing " VICODEC_NAME);
-
-#ifdef CONFIG_MEDIA_CONTROLLER
-	media_device_unregister(&dev->mdev);
-	v4l2_m2m_unregister_media_controller(dev->stateful_enc.m2m_dev);
-	v4l2_m2m_unregister_media_controller(dev->stateful_dec.m2m_dev);
-	v4l2_m2m_unregister_media_controller(dev->stateless_dec.m2m_dev);
-#endif
-
-	video_unregister_device(&dev->stateful_enc.vfd);
-	video_unregister_device(&dev->stateful_dec.vfd);
-	video_unregister_device(&dev->stateless_dec.vfd);
-	v4l2_device_put(&dev->v4l2_dev);
-
-	return 0;
-}
-
-static struct platform_driver vicodec_pdrv = {
-	.probe		= vicodec_probe,
-	.remove		= vicodec_remove,
-	.driver		= {
-		.name	= VICODEC_NAME,
-	},
-};
-
-static void __exit vicodec_exit(void)
-{
-	platform_driver_unregister(&vicodec_pdrv);
-	platform_device_unregister(&vicodec_pdev);
-}
-
-static int __init vicodec_init(void)
-{
-	int ret;
-
-	ret = platform_device_register(&vicodec_pdev);
-	if (ret)
-		return ret;
-
-	ret = platform_driver_register(&vicodec_pdrv);
-	if (ret)
-		platform_device_unregister(&vicodec_pdev);
-
-	return ret;
-}
-
-module_init(vicodec_init);
-module_exit(vicodec_exit);
diff --git a/drivers/media/platform/vim2m.c b/drivers/media/platform/vim2m.c
deleted file mode 100644
index ac6717fbb764..000000000000
--- a/drivers/media/platform/vim2m.c
+++ /dev/null
@@ -1,1441 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * A virtual v4l2-mem2mem example device.
- *
- * This is a virtual device driver for testing mem-to-mem videobuf framework.
- * It simulates a device that uses memory buffers for both source and
- * destination, processes the data and issues an "irq" (simulated by a delayed
- * workqueue).
- * The device is capable of multi-instance, multi-buffer-per-transaction
- * operation (via the mem2mem framework).
- *
- * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
- * Pawel Osciak, <pawel@osciak.com>
- * Marek Szyprowski, <m.szyprowski@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; either version 2 of the
- * License, or (at your option) any later version
- */
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/fs.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-
-#include <linux/platform_device.h>
-#include <media/v4l2-mem2mem.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-event.h>
-#include <media/videobuf2-vmalloc.h>
-
-MODULE_DESCRIPTION("Virtual device for mem2mem framework testing");
-MODULE_AUTHOR("Pawel Osciak, <pawel@osciak.com>");
-MODULE_LICENSE("GPL");
-MODULE_VERSION("0.2");
-MODULE_ALIAS("mem2mem_testdev");
-
-static unsigned int debug;
-module_param(debug, uint, 0644);
-MODULE_PARM_DESC(debug, "debug level");
-
-/* Default transaction time in msec */
-static unsigned int default_transtime = 40; /* Max 25 fps */
-module_param(default_transtime, uint, 0644);
-MODULE_PARM_DESC(default_transtime, "default transaction time in ms");
-
-#define MIN_W 32
-#define MIN_H 32
-#define MAX_W 640
-#define MAX_H 480
-
-/* Pixel alignment for non-bayer formats */
-#define WIDTH_ALIGN 2
-#define HEIGHT_ALIGN 1
-
-/* Pixel alignment for bayer formats */
-#define BAYER_WIDTH_ALIGN  2
-#define BAYER_HEIGHT_ALIGN 2
-
-/* Flags that indicate a format can be used for capture/output */
-#define MEM2MEM_CAPTURE	BIT(0)
-#define MEM2MEM_OUTPUT	BIT(1)
-
-#define MEM2MEM_NAME		"vim2m"
-
-/* Per queue */
-#define MEM2MEM_DEF_NUM_BUFS	VIDEO_MAX_FRAME
-/* In bytes, per queue */
-#define MEM2MEM_VID_MEM_LIMIT	(16 * 1024 * 1024)
-
-/* Flags that indicate processing mode */
-#define MEM2MEM_HFLIP	BIT(0)
-#define MEM2MEM_VFLIP	BIT(1)
-
-#define dprintk(dev, lvl, fmt, arg...) \
-	v4l2_dbg(lvl, debug, &(dev)->v4l2_dev, "%s: " fmt, __func__, ## arg)
-
-static void vim2m_dev_release(struct device *dev)
-{}
-
-static struct platform_device vim2m_pdev = {
-	.name		= MEM2MEM_NAME,
-	.dev.release	= vim2m_dev_release,
-};
-
-struct vim2m_fmt {
-	u32	fourcc;
-	int	depth;
-	/* Types the format can be used for */
-	u32     types;
-};
-
-static struct vim2m_fmt formats[] = {
-	{
-		.fourcc	= V4L2_PIX_FMT_RGB565,  /* rrrrrggg gggbbbbb */
-		.depth	= 16,
-		.types  = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
-	}, {
-		.fourcc	= V4L2_PIX_FMT_RGB565X, /* gggbbbbb rrrrrggg */
-		.depth	= 16,
-		.types  = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
-	}, {
-		.fourcc	= V4L2_PIX_FMT_RGB24,
-		.depth	= 24,
-		.types  = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
-	}, {
-		.fourcc	= V4L2_PIX_FMT_BGR24,
-		.depth	= 24,
-		.types  = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
-	}, {
-		.fourcc	= V4L2_PIX_FMT_YUYV,
-		.depth	= 16,
-		.types  = MEM2MEM_CAPTURE,
-	}, {
-		.fourcc	= V4L2_PIX_FMT_SBGGR8,
-		.depth	= 8,
-		.types  = MEM2MEM_CAPTURE,
-	}, {
-		.fourcc	= V4L2_PIX_FMT_SGBRG8,
-		.depth	= 8,
-		.types  = MEM2MEM_CAPTURE,
-	}, {
-		.fourcc	= V4L2_PIX_FMT_SGRBG8,
-		.depth	= 8,
-		.types  = MEM2MEM_CAPTURE,
-	}, {
-		.fourcc	= V4L2_PIX_FMT_SRGGB8,
-		.depth	= 8,
-		.types  = MEM2MEM_CAPTURE,
-	},
-};
-
-#define NUM_FORMATS ARRAY_SIZE(formats)
-
-/* Per-queue, driver-specific private data */
-struct vim2m_q_data {
-	unsigned int		width;
-	unsigned int		height;
-	unsigned int		sizeimage;
-	unsigned int		sequence;
-	struct vim2m_fmt	*fmt;
-};
-
-enum {
-	V4L2_M2M_SRC = 0,
-	V4L2_M2M_DST = 1,
-};
-
-#define V4L2_CID_TRANS_TIME_MSEC	(V4L2_CID_USER_BASE + 0x1000)
-#define V4L2_CID_TRANS_NUM_BUFS		(V4L2_CID_USER_BASE + 0x1001)
-
-static struct vim2m_fmt *find_format(u32 fourcc)
-{
-	struct vim2m_fmt *fmt;
-	unsigned int k;
-
-	for (k = 0; k < NUM_FORMATS; k++) {
-		fmt = &formats[k];
-		if (fmt->fourcc == fourcc)
-			break;
-	}
-
-	if (k == NUM_FORMATS)
-		return NULL;
-
-	return &formats[k];
-}
-
-static void get_alignment(u32 fourcc,
-			  unsigned int *walign, unsigned int *halign)
-{
-	switch (fourcc) {
-	case V4L2_PIX_FMT_SBGGR8:
-	case V4L2_PIX_FMT_SGBRG8:
-	case V4L2_PIX_FMT_SGRBG8:
-	case V4L2_PIX_FMT_SRGGB8:
-		*walign = BAYER_WIDTH_ALIGN;
-		*halign = BAYER_HEIGHT_ALIGN;
-		return;
-	default:
-		*walign = WIDTH_ALIGN;
-		*halign = HEIGHT_ALIGN;
-		return;
-	}
-}
-
-struct vim2m_dev {
-	struct v4l2_device	v4l2_dev;
-	struct video_device	vfd;
-#ifdef CONFIG_MEDIA_CONTROLLER
-	struct media_device	mdev;
-#endif
-
-	atomic_t		num_inst;
-	struct mutex		dev_mutex;
-
-	struct v4l2_m2m_dev	*m2m_dev;
-};
-
-struct vim2m_ctx {
-	struct v4l2_fh		fh;
-	struct vim2m_dev	*dev;
-
-	struct v4l2_ctrl_handler hdl;
-
-	/* Processed buffers in this transaction */
-	u8			num_processed;
-
-	/* Transaction length (i.e. how many buffers per transaction) */
-	u32			translen;
-	/* Transaction time (i.e. simulated processing time) in milliseconds */
-	u32			transtime;
-
-	struct mutex		vb_mutex;
-	struct delayed_work	work_run;
-	spinlock_t		irqlock;
-
-	/* Abort requested by m2m */
-	int			aborting;
-
-	/* Processing mode */
-	int			mode;
-
-	enum v4l2_colorspace	colorspace;
-	enum v4l2_ycbcr_encoding ycbcr_enc;
-	enum v4l2_xfer_func	xfer_func;
-	enum v4l2_quantization	quant;
-
-	/* Source and destination queue data */
-	struct vim2m_q_data   q_data[2];
-};
-
-static inline struct vim2m_ctx *file2ctx(struct file *file)
-{
-	return container_of(file->private_data, struct vim2m_ctx, fh);
-}
-
-static struct vim2m_q_data *get_q_data(struct vim2m_ctx *ctx,
-				       enum v4l2_buf_type type)
-{
-	switch (type) {
-	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-		return &ctx->q_data[V4L2_M2M_SRC];
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-		return &ctx->q_data[V4L2_M2M_DST];
-	default:
-		return NULL;
-	}
-}
-
-static const char *type_name(enum v4l2_buf_type type)
-{
-	switch (type) {
-	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-		return "Output";
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-		return "Capture";
-	default:
-		return "Invalid";
-	}
-}
-
-#define CLIP(__color) \
-	(u8)(((__color) > 0xff) ? 0xff : (((__color) < 0) ? 0 : (__color)))
-
-static void copy_line(struct vim2m_q_data *q_data_out,
-		      u8 *src, u8 *dst, bool reverse)
-{
-	int x, depth = q_data_out->fmt->depth >> 3;
-
-	if (!reverse) {
-		memcpy(dst, src, q_data_out->width * depth);
-	} else {
-		for (x = 0; x < q_data_out->width >> 1; x++) {
-			memcpy(dst, src, depth);
-			memcpy(dst + depth, src - depth, depth);
-			src -= depth << 1;
-			dst += depth << 1;
-		}
-		return;
-	}
-}
-
-static void copy_two_pixels(struct vim2m_q_data *q_data_in,
-			    struct vim2m_q_data *q_data_out,
-			    u8 *src[2], u8 **dst, int ypos, bool reverse)
-{
-	struct vim2m_fmt *out = q_data_out->fmt;
-	struct vim2m_fmt *in = q_data_in->fmt;
-	u8 _r[2], _g[2], _b[2], *r, *g, *b;
-	int i;
-
-	/* Step 1: read two consecutive pixels from src pointer */
-
-	r = _r;
-	g = _g;
-	b = _b;
-
-	switch (in->fourcc) {
-	case V4L2_PIX_FMT_RGB565: /* rrrrrggg gggbbbbb */
-		for (i = 0; i < 2; i++) {
-			u16 pix = le16_to_cpu(*(__le16 *)(src[i]));
-
-			*r++ = (u8)(((pix & 0xf800) >> 11) << 3) | 0x07;
-			*g++ = (u8)((((pix & 0x07e0) >> 5)) << 2) | 0x03;
-			*b++ = (u8)((pix & 0x1f) << 3) | 0x07;
-		}
-		break;
-	case V4L2_PIX_FMT_RGB565X: /* gggbbbbb rrrrrggg */
-		for (i = 0; i < 2; i++) {
-			u16 pix = be16_to_cpu(*(__be16 *)(src[i]));
-
-			*r++ = (u8)(((pix & 0xf800) >> 11) << 3) | 0x07;
-			*g++ = (u8)((((pix & 0x07e0) >> 5)) << 2) | 0x03;
-			*b++ = (u8)((pix & 0x1f) << 3) | 0x07;
-		}
-		break;
-	default:
-	case V4L2_PIX_FMT_RGB24:
-		for (i = 0; i < 2; i++) {
-			*r++ = src[i][0];
-			*g++ = src[i][1];
-			*b++ = src[i][2];
-		}
-		break;
-	case V4L2_PIX_FMT_BGR24:
-		for (i = 0; i < 2; i++) {
-			*b++ = src[i][0];
-			*g++ = src[i][1];
-			*r++ = src[i][2];
-		}
-		break;
-	}
-
-	/* Step 2: store two consecutive points, reversing them if needed */
-
-	r = _r;
-	g = _g;
-	b = _b;
-
-	switch (out->fourcc) {
-	case V4L2_PIX_FMT_RGB565: /* rrrrrggg gggbbbbb */
-		for (i = 0; i < 2; i++) {
-			u16 pix;
-			__le16 *dst_pix = (__le16 *)*dst;
-
-			pix = ((*r << 8) & 0xf800) | ((*g << 3) & 0x07e0) |
-			      (*b >> 3);
-
-			*dst_pix = cpu_to_le16(pix);
-
-			*dst += 2;
-		}
-		return;
-	case V4L2_PIX_FMT_RGB565X: /* gggbbbbb rrrrrggg */
-		for (i = 0; i < 2; i++) {
-			u16 pix;
-			__be16 *dst_pix = (__be16 *)*dst;
-
-			pix = ((*r << 8) & 0xf800) | ((*g << 3) & 0x07e0) |
-			      (*b >> 3);
-
-			*dst_pix = cpu_to_be16(pix);
-
-			*dst += 2;
-		}
-		return;
-	case V4L2_PIX_FMT_RGB24:
-		for (i = 0; i < 2; i++) {
-			*(*dst)++ = *r++;
-			*(*dst)++ = *g++;
-			*(*dst)++ = *b++;
-		}
-		return;
-	case V4L2_PIX_FMT_BGR24:
-		for (i = 0; i < 2; i++) {
-			*(*dst)++ = *b++;
-			*(*dst)++ = *g++;
-			*(*dst)++ = *r++;
-		}
-		return;
-	case V4L2_PIX_FMT_YUYV:
-	default:
-	{
-		u8 y, y1, u, v;
-
-		y = ((8453  * (*r) + 16594 * (*g) +  3223 * (*b)
-		     + 524288) >> 15);
-		u = ((-4878 * (*r) - 9578  * (*g) + 14456 * (*b)
-		     + 4210688) >> 15);
-		v = ((14456 * (*r++) - 12105 * (*g++) - 2351 * (*b++)
-		     + 4210688) >> 15);
-		y1 = ((8453 * (*r) + 16594 * (*g) +  3223 * (*b)
-		     + 524288) >> 15);
-
-		*(*dst)++ = y;
-		*(*dst)++ = u;
-
-		*(*dst)++ = y1;
-		*(*dst)++ = v;
-		return;
-	}
-	case V4L2_PIX_FMT_SBGGR8:
-		if (!(ypos & 1)) {
-			*(*dst)++ = *b;
-			*(*dst)++ = *++g;
-		} else {
-			*(*dst)++ = *g;
-			*(*dst)++ = *++r;
-		}
-		return;
-	case V4L2_PIX_FMT_SGBRG8:
-		if (!(ypos & 1)) {
-			*(*dst)++ = *g;
-			*(*dst)++ = *++b;
-		} else {
-			*(*dst)++ = *r;
-			*(*dst)++ = *++g;
-		}
-		return;
-	case V4L2_PIX_FMT_SGRBG8:
-		if (!(ypos & 1)) {
-			*(*dst)++ = *g;
-			*(*dst)++ = *++r;
-		} else {
-			*(*dst)++ = *b;
-			*(*dst)++ = *++g;
-		}
-		return;
-	case V4L2_PIX_FMT_SRGGB8:
-		if (!(ypos & 1)) {
-			*(*dst)++ = *r;
-			*(*dst)++ = *++g;
-		} else {
-			*(*dst)++ = *g;
-			*(*dst)++ = *++b;
-		}
-		return;
-	}
-}
-
-static int device_process(struct vim2m_ctx *ctx,
-			  struct vb2_v4l2_buffer *in_vb,
-			  struct vb2_v4l2_buffer *out_vb)
-{
-	struct vim2m_dev *dev = ctx->dev;
-	struct vim2m_q_data *q_data_in, *q_data_out;
-	u8 *p_in, *p_line, *p_in_x[2], *p, *p_out;
-	unsigned int width, height, bytesperline, bytes_per_pixel;
-	unsigned int x, y, y_in, y_out, x_int, x_fract, x_err, x_offset;
-	int start, end, step;
-
-	q_data_in = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
-	if (!q_data_in)
-		return 0;
-	bytesperline = (q_data_in->width * q_data_in->fmt->depth) >> 3;
-	bytes_per_pixel = q_data_in->fmt->depth >> 3;
-
-	q_data_out = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
-	if (!q_data_out)
-		return 0;
-
-	/* As we're doing scaling, use the output dimensions here */
-	height = q_data_out->height;
-	width = q_data_out->width;
-
-	p_in = vb2_plane_vaddr(&in_vb->vb2_buf, 0);
-	p_out = vb2_plane_vaddr(&out_vb->vb2_buf, 0);
-	if (!p_in || !p_out) {
-		v4l2_err(&dev->v4l2_dev,
-			 "Acquiring kernel pointers to buffers failed\n");
-		return -EFAULT;
-	}
-
-	out_vb->sequence = q_data_out->sequence++;
-	in_vb->sequence = q_data_in->sequence++;
-	v4l2_m2m_buf_copy_metadata(in_vb, out_vb, true);
-
-	if (ctx->mode & MEM2MEM_VFLIP) {
-		start = height - 1;
-		end = -1;
-		step = -1;
-	} else {
-		start = 0;
-		end = height;
-		step = 1;
-	}
-	y_out = 0;
-
-	/*
-	 * When format and resolution are identical,
-	 * we can use a faster copy logic
-	 */
-	if (q_data_in->fmt->fourcc == q_data_out->fmt->fourcc &&
-	    q_data_in->width == q_data_out->width &&
-	    q_data_in->height == q_data_out->height) {
-		for (y = start; y != end; y += step, y_out++) {
-			p = p_in + (y * bytesperline);
-			if (ctx->mode & MEM2MEM_HFLIP)
-				p += bytesperline - (q_data_in->fmt->depth >> 3);
-
-			copy_line(q_data_out, p, p_out,
-				  ctx->mode & MEM2MEM_HFLIP);
-
-			p_out += bytesperline;
-		}
-		return 0;
-	}
-
-	/* Slower algorithm with format conversion, hflip, vflip and scaler */
-
-	/* To speed scaler up, use Bresenham for X dimension */
-	x_int = q_data_in->width / q_data_out->width;
-	x_fract = q_data_in->width % q_data_out->width;
-
-	for (y = start; y != end; y += step, y_out++) {
-		y_in = (y * q_data_in->height) / q_data_out->height;
-		x_offset = 0;
-		x_err = 0;
-
-		p_line = p_in + (y_in * bytesperline);
-		if (ctx->mode & MEM2MEM_HFLIP)
-			p_line += bytesperline - (q_data_in->fmt->depth >> 3);
-		p_in_x[0] = p_line;
-
-		for (x = 0; x < width >> 1; x++) {
-			x_offset += x_int;
-			x_err += x_fract;
-			if (x_err > width) {
-				x_offset++;
-				x_err -= width;
-			}
-
-			if (ctx->mode & MEM2MEM_HFLIP)
-				p_in_x[1] = p_line - x_offset * bytes_per_pixel;
-			else
-				p_in_x[1] = p_line + x_offset * bytes_per_pixel;
-
-			copy_two_pixels(q_data_in, q_data_out,
-					p_in_x, &p_out, y_out,
-					ctx->mode & MEM2MEM_HFLIP);
-
-			/* Calculate the next p_in_x0 */
-			x_offset += x_int;
-			x_err += x_fract;
-			if (x_err > width) {
-				x_offset++;
-				x_err -= width;
-			}
-
-			if (ctx->mode & MEM2MEM_HFLIP)
-				p_in_x[0] = p_line - x_offset * bytes_per_pixel;
-			else
-				p_in_x[0] = p_line + x_offset * bytes_per_pixel;
-		}
-	}
-
-	return 0;
-}
-
-/*
- * mem2mem callbacks
- */
-
-/*
- * job_ready() - check whether an instance is ready to be scheduled to run
- */
-static int job_ready(void *priv)
-{
-	struct vim2m_ctx *ctx = priv;
-
-	if (v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) < ctx->translen
-	    || v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx) < ctx->translen) {
-		dprintk(ctx->dev, 1, "Not enough buffers available\n");
-		return 0;
-	}
-
-	return 1;
-}
-
-static void job_abort(void *priv)
-{
-	struct vim2m_ctx *ctx = priv;
-
-	/* Will cancel the transaction in the next interrupt handler */
-	ctx->aborting = 1;
-}
-
-/* device_run() - prepares and starts the device
- *
- * This simulates all the immediate preparations required before starting
- * a device. This will be called by the framework when it decides to schedule
- * a particular instance.
- */
-static void device_run(void *priv)
-{
-	struct vim2m_ctx *ctx = priv;
-	struct vb2_v4l2_buffer *src_buf, *dst_buf;
-
-	src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
-	dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
-
-	/* Apply request controls if any */
-	v4l2_ctrl_request_setup(src_buf->vb2_buf.req_obj.req,
-				&ctx->hdl);
-
-	device_process(ctx, src_buf, dst_buf);
-
-	/* Complete request controls if any */
-	v4l2_ctrl_request_complete(src_buf->vb2_buf.req_obj.req,
-				   &ctx->hdl);
-
-	/* Run delayed work, which simulates a hardware irq  */
-	schedule_delayed_work(&ctx->work_run, msecs_to_jiffies(ctx->transtime));
-}
-
-static void device_work(struct work_struct *w)
-{
-	struct vim2m_ctx *curr_ctx;
-	struct vim2m_dev *vim2m_dev;
-	struct vb2_v4l2_buffer *src_vb, *dst_vb;
-	unsigned long flags;
-
-	curr_ctx = container_of(w, struct vim2m_ctx, work_run.work);
-
-	if (!curr_ctx) {
-		pr_err("Instance released before the end of transaction\n");
-		return;
-	}
-
-	vim2m_dev = curr_ctx->dev;
-
-	src_vb = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
-	dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
-
-	curr_ctx->num_processed++;
-
-	spin_lock_irqsave(&curr_ctx->irqlock, flags);
-	v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE);
-	v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE);
-	spin_unlock_irqrestore(&curr_ctx->irqlock, flags);
-
-	if (curr_ctx->num_processed == curr_ctx->translen
-	    || curr_ctx->aborting) {
-		dprintk(curr_ctx->dev, 2, "Finishing capture buffer fill\n");
-		curr_ctx->num_processed = 0;
-		v4l2_m2m_job_finish(vim2m_dev->m2m_dev, curr_ctx->fh.m2m_ctx);
-	} else {
-		device_run(curr_ctx);
-	}
-}
-
-/*
- * video ioctls
- */
-static int vidioc_querycap(struct file *file, void *priv,
-			   struct v4l2_capability *cap)
-{
-	strscpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver));
-	strscpy(cap->card, MEM2MEM_NAME, sizeof(cap->card));
-	snprintf(cap->bus_info, sizeof(cap->bus_info),
-		 "platform:%s", MEM2MEM_NAME);
-	return 0;
-}
-
-static int enum_fmt(struct v4l2_fmtdesc *f, u32 type)
-{
-	int i, num;
-	struct vim2m_fmt *fmt;
-
-	num = 0;
-
-	for (i = 0; i < NUM_FORMATS; ++i) {
-		if (formats[i].types & type) {
-			/* index-th format of type type found ? */
-			if (num == f->index)
-				break;
-			/*
-			 * Correct type but haven't reached our index yet,
-			 * just increment per-type index
-			 */
-			++num;
-		}
-	}
-
-	if (i < NUM_FORMATS) {
-		/* Format found */
-		fmt = &formats[i];
-		f->pixelformat = fmt->fourcc;
-		return 0;
-	}
-
-	/* Format not found */
-	return -EINVAL;
-}
-
-static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
-				   struct v4l2_fmtdesc *f)
-{
-	return enum_fmt(f, MEM2MEM_CAPTURE);
-}
-
-static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
-				   struct v4l2_fmtdesc *f)
-{
-	return enum_fmt(f, MEM2MEM_OUTPUT);
-}
-
-static int vidioc_enum_framesizes(struct file *file, void *priv,
-				  struct v4l2_frmsizeenum *fsize)
-{
-	if (fsize->index != 0)
-		return -EINVAL;
-
-	if (!find_format(fsize->pixel_format))
-		return -EINVAL;
-
-	fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
-	fsize->stepwise.min_width = MIN_W;
-	fsize->stepwise.min_height = MIN_H;
-	fsize->stepwise.max_width = MAX_W;
-	fsize->stepwise.max_height = MAX_H;
-
-	get_alignment(fsize->pixel_format,
-		      &fsize->stepwise.step_width,
-		      &fsize->stepwise.step_height);
-	return 0;
-}
-
-static int vidioc_g_fmt(struct vim2m_ctx *ctx, struct v4l2_format *f)
-{
-	struct vb2_queue *vq;
-	struct vim2m_q_data *q_data;
-
-	vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
-	if (!vq)
-		return -EINVAL;
-
-	q_data = get_q_data(ctx, f->type);
-	if (!q_data)
-		return -EINVAL;
-
-	f->fmt.pix.width	= q_data->width;
-	f->fmt.pix.height	= q_data->height;
-	f->fmt.pix.field	= V4L2_FIELD_NONE;
-	f->fmt.pix.pixelformat	= q_data->fmt->fourcc;
-	f->fmt.pix.bytesperline	= (q_data->width * q_data->fmt->depth) >> 3;
-	f->fmt.pix.sizeimage	= q_data->sizeimage;
-	f->fmt.pix.colorspace	= ctx->colorspace;
-	f->fmt.pix.xfer_func	= ctx->xfer_func;
-	f->fmt.pix.ycbcr_enc	= ctx->ycbcr_enc;
-	f->fmt.pix.quantization	= ctx->quant;
-
-	return 0;
-}
-
-static int vidioc_g_fmt_vid_out(struct file *file, void *priv,
-				struct v4l2_format *f)
-{
-	return vidioc_g_fmt(file2ctx(file), f);
-}
-
-static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
-				struct v4l2_format *f)
-{
-	return vidioc_g_fmt(file2ctx(file), f);
-}
-
-static int vidioc_try_fmt(struct v4l2_format *f, struct vim2m_fmt *fmt)
-{
-	int walign, halign;
-	/*
-	 * V4L2 specification specifies the driver corrects the
-	 * format struct if any of the dimensions is unsupported
-	 */
-	if (f->fmt.pix.height < MIN_H)
-		f->fmt.pix.height = MIN_H;
-	else if (f->fmt.pix.height > MAX_H)
-		f->fmt.pix.height = MAX_H;
-
-	if (f->fmt.pix.width < MIN_W)
-		f->fmt.pix.width = MIN_W;
-	else if (f->fmt.pix.width > MAX_W)
-		f->fmt.pix.width = MAX_W;
-
-	get_alignment(f->fmt.pix.pixelformat, &walign, &halign);
-	f->fmt.pix.width &= ~(walign - 1);
-	f->fmt.pix.height &= ~(halign - 1);
-	f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
-	f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
-	f->fmt.pix.field = V4L2_FIELD_NONE;
-
-	return 0;
-}
-
-static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
-				  struct v4l2_format *f)
-{
-	struct vim2m_fmt *fmt;
-	struct vim2m_ctx *ctx = file2ctx(file);
-
-	fmt = find_format(f->fmt.pix.pixelformat);
-	if (!fmt) {
-		f->fmt.pix.pixelformat = formats[0].fourcc;
-		fmt = find_format(f->fmt.pix.pixelformat);
-	}
-	if (!(fmt->types & MEM2MEM_CAPTURE)) {
-		v4l2_err(&ctx->dev->v4l2_dev,
-			 "Fourcc format (0x%08x) invalid.\n",
-			 f->fmt.pix.pixelformat);
-		return -EINVAL;
-	}
-	f->fmt.pix.colorspace = ctx->colorspace;
-	f->fmt.pix.xfer_func = ctx->xfer_func;
-	f->fmt.pix.ycbcr_enc = ctx->ycbcr_enc;
-	f->fmt.pix.quantization = ctx->quant;
-
-	return vidioc_try_fmt(f, fmt);
-}
-
-static int vidioc_try_fmt_vid_out(struct file *file, void *priv,
-				  struct v4l2_format *f)
-{
-	struct vim2m_fmt *fmt;
-	struct vim2m_ctx *ctx = file2ctx(file);
-
-	fmt = find_format(f->fmt.pix.pixelformat);
-	if (!fmt) {
-		f->fmt.pix.pixelformat = formats[0].fourcc;
-		fmt = find_format(f->fmt.pix.pixelformat);
-	}
-	if (!(fmt->types & MEM2MEM_OUTPUT)) {
-		v4l2_err(&ctx->dev->v4l2_dev,
-			 "Fourcc format (0x%08x) invalid.\n",
-			 f->fmt.pix.pixelformat);
-		return -EINVAL;
-	}
-	if (!f->fmt.pix.colorspace)
-		f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
-
-	return vidioc_try_fmt(f, fmt);
-}
-
-static int vidioc_s_fmt(struct vim2m_ctx *ctx, struct v4l2_format *f)
-{
-	struct vim2m_q_data *q_data;
-	struct vb2_queue *vq;
-
-	vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
-	if (!vq)
-		return -EINVAL;
-
-	q_data = get_q_data(ctx, f->type);
-	if (!q_data)
-		return -EINVAL;
-
-	if (vb2_is_busy(vq)) {
-		v4l2_err(&ctx->dev->v4l2_dev, "%s queue busy\n", __func__);
-		return -EBUSY;
-	}
-
-	q_data->fmt		= find_format(f->fmt.pix.pixelformat);
-	q_data->width		= f->fmt.pix.width;
-	q_data->height		= f->fmt.pix.height;
-	q_data->sizeimage	= q_data->width * q_data->height
-				* q_data->fmt->depth >> 3;
-
-	dprintk(ctx->dev, 1,
-		"Format for type %s: %dx%d (%d bpp), fmt: %c%c%c%c\n",
-		type_name(f->type), q_data->width, q_data->height,
-		q_data->fmt->depth,
-		(q_data->fmt->fourcc & 0xff),
-		(q_data->fmt->fourcc >>  8) & 0xff,
-		(q_data->fmt->fourcc >> 16) & 0xff,
-		(q_data->fmt->fourcc >> 24) & 0xff);
-
-	return 0;
-}
-
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
-				struct v4l2_format *f)
-{
-	int ret;
-
-	ret = vidioc_try_fmt_vid_cap(file, priv, f);
-	if (ret)
-		return ret;
-
-	return vidioc_s_fmt(file2ctx(file), f);
-}
-
-static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
-				struct v4l2_format *f)
-{
-	struct vim2m_ctx *ctx = file2ctx(file);
-	int ret;
-
-	ret = vidioc_try_fmt_vid_out(file, priv, f);
-	if (ret)
-		return ret;
-
-	ret = vidioc_s_fmt(file2ctx(file), f);
-	if (!ret) {
-		ctx->colorspace = f->fmt.pix.colorspace;
-		ctx->xfer_func = f->fmt.pix.xfer_func;
-		ctx->ycbcr_enc = f->fmt.pix.ycbcr_enc;
-		ctx->quant = f->fmt.pix.quantization;
-	}
-	return ret;
-}
-
-static int vim2m_s_ctrl(struct v4l2_ctrl *ctrl)
-{
-	struct vim2m_ctx *ctx =
-		container_of(ctrl->handler, struct vim2m_ctx, hdl);
-
-	switch (ctrl->id) {
-	case V4L2_CID_HFLIP:
-		if (ctrl->val)
-			ctx->mode |= MEM2MEM_HFLIP;
-		else
-			ctx->mode &= ~MEM2MEM_HFLIP;
-		break;
-
-	case V4L2_CID_VFLIP:
-		if (ctrl->val)
-			ctx->mode |= MEM2MEM_VFLIP;
-		else
-			ctx->mode &= ~MEM2MEM_VFLIP;
-		break;
-
-	case V4L2_CID_TRANS_TIME_MSEC:
-		ctx->transtime = ctrl->val;
-		if (ctx->transtime < 1)
-			ctx->transtime = 1;
-		break;
-
-	case V4L2_CID_TRANS_NUM_BUFS:
-		ctx->translen = ctrl->val;
-		break;
-
-	default:
-		v4l2_err(&ctx->dev->v4l2_dev, "Invalid control\n");
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static const struct v4l2_ctrl_ops vim2m_ctrl_ops = {
-	.s_ctrl = vim2m_s_ctrl,
-};
-
-static const struct v4l2_ioctl_ops vim2m_ioctl_ops = {
-	.vidioc_querycap	= vidioc_querycap,
-
-	.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
-	.vidioc_enum_framesizes = vidioc_enum_framesizes,
-	.vidioc_g_fmt_vid_cap	= vidioc_g_fmt_vid_cap,
-	.vidioc_try_fmt_vid_cap	= vidioc_try_fmt_vid_cap,
-	.vidioc_s_fmt_vid_cap	= vidioc_s_fmt_vid_cap,
-
-	.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,
-
-	.vidioc_reqbufs		= v4l2_m2m_ioctl_reqbufs,
-	.vidioc_querybuf	= v4l2_m2m_ioctl_querybuf,
-	.vidioc_qbuf		= v4l2_m2m_ioctl_qbuf,
-	.vidioc_dqbuf		= v4l2_m2m_ioctl_dqbuf,
-	.vidioc_prepare_buf	= v4l2_m2m_ioctl_prepare_buf,
-	.vidioc_create_bufs	= v4l2_m2m_ioctl_create_bufs,
-	.vidioc_expbuf		= v4l2_m2m_ioctl_expbuf,
-
-	.vidioc_streamon	= v4l2_m2m_ioctl_streamon,
-	.vidioc_streamoff	= v4l2_m2m_ioctl_streamoff,
-
-	.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
-	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
-};
-
-/*
- * Queue operations
- */
-
-static int vim2m_queue_setup(struct vb2_queue *vq,
-			     unsigned int *nbuffers,
-			     unsigned int *nplanes,
-			     unsigned int sizes[],
-			     struct device *alloc_devs[])
-{
-	struct vim2m_ctx *ctx = vb2_get_drv_priv(vq);
-	struct vim2m_q_data *q_data;
-	unsigned int size, count = *nbuffers;
-
-	q_data = get_q_data(ctx, vq->type);
-	if (!q_data)
-		return -EINVAL;
-
-	size = q_data->width * q_data->height * q_data->fmt->depth >> 3;
-
-	while (size * count > MEM2MEM_VID_MEM_LIMIT)
-		(count)--;
-	*nbuffers = count;
-
-	if (*nplanes)
-		return sizes[0] < size ? -EINVAL : 0;
-
-	*nplanes = 1;
-	sizes[0] = size;
-
-	dprintk(ctx->dev, 1, "%s: get %d buffer(s) of size %d each.\n",
-		type_name(vq->type), count, size);
-
-	return 0;
-}
-
-static int vim2m_buf_out_validate(struct vb2_buffer *vb)
-{
-	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-	struct vim2m_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
-
-	if (vbuf->field == V4L2_FIELD_ANY)
-		vbuf->field = V4L2_FIELD_NONE;
-	if (vbuf->field != V4L2_FIELD_NONE) {
-		dprintk(ctx->dev, 1, "%s field isn't supported\n", __func__);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static int vim2m_buf_prepare(struct vb2_buffer *vb)
-{
-	struct vim2m_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
-	struct vim2m_q_data *q_data;
-
-	dprintk(ctx->dev, 2, "type: %s\n", type_name(vb->vb2_queue->type));
-
-	q_data = get_q_data(ctx, vb->vb2_queue->type);
-	if (!q_data)
-		return -EINVAL;
-	if (vb2_plane_size(vb, 0) < q_data->sizeimage) {
-		dprintk(ctx->dev, 1,
-			"%s data will not fit into plane (%lu < %lu)\n",
-			__func__, vb2_plane_size(vb, 0),
-			(long)q_data->sizeimage);
-		return -EINVAL;
-	}
-
-	vb2_set_plane_payload(vb, 0, q_data->sizeimage);
-
-	return 0;
-}
-
-static void vim2m_buf_queue(struct vb2_buffer *vb)
-{
-	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-	struct vim2m_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
-
-	v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
-}
-
-static int vim2m_start_streaming(struct vb2_queue *q, unsigned int count)
-{
-	struct vim2m_ctx *ctx = vb2_get_drv_priv(q);
-	struct vim2m_q_data *q_data = get_q_data(ctx, q->type);
-
-	if (!q_data)
-		return -EINVAL;
-
-	if (V4L2_TYPE_IS_OUTPUT(q->type))
-		ctx->aborting = 0;
-
-	q_data->sequence = 0;
-	return 0;
-}
-
-static void vim2m_stop_streaming(struct vb2_queue *q)
-{
-	struct vim2m_ctx *ctx = vb2_get_drv_priv(q);
-	struct vb2_v4l2_buffer *vbuf;
-	unsigned long flags;
-
-	cancel_delayed_work_sync(&ctx->work_run);
-
-	for (;;) {
-		if (V4L2_TYPE_IS_OUTPUT(q->type))
-			vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
-		else
-			vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
-		if (!vbuf)
-			return;
-		v4l2_ctrl_request_complete(vbuf->vb2_buf.req_obj.req,
-					   &ctx->hdl);
-		spin_lock_irqsave(&ctx->irqlock, flags);
-		v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
-		spin_unlock_irqrestore(&ctx->irqlock, flags);
-	}
-}
-
-static void vim2m_buf_request_complete(struct vb2_buffer *vb)
-{
-	struct vim2m_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
-
-	v4l2_ctrl_request_complete(vb->req_obj.req, &ctx->hdl);
-}
-
-static const struct vb2_ops vim2m_qops = {
-	.queue_setup	 = vim2m_queue_setup,
-	.buf_out_validate	 = vim2m_buf_out_validate,
-	.buf_prepare	 = vim2m_buf_prepare,
-	.buf_queue	 = vim2m_buf_queue,
-	.start_streaming = vim2m_start_streaming,
-	.stop_streaming  = vim2m_stop_streaming,
-	.wait_prepare	 = vb2_ops_wait_prepare,
-	.wait_finish	 = vb2_ops_wait_finish,
-	.buf_request_complete = vim2m_buf_request_complete,
-};
-
-static int queue_init(void *priv, struct vb2_queue *src_vq,
-		      struct vb2_queue *dst_vq)
-{
-	struct vim2m_ctx *ctx = priv;
-	int ret;
-
-	src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
-	src_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
-	src_vq->drv_priv = ctx;
-	src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
-	src_vq->ops = &vim2m_qops;
-	src_vq->mem_ops = &vb2_vmalloc_memops;
-	src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
-	src_vq->lock = &ctx->vb_mutex;
-	src_vq->supports_requests = true;
-
-	ret = vb2_queue_init(src_vq);
-	if (ret)
-		return ret;
-
-	dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	dst_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
-	dst_vq->drv_priv = ctx;
-	dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
-	dst_vq->ops = &vim2m_qops;
-	dst_vq->mem_ops = &vb2_vmalloc_memops;
-	dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
-	dst_vq->lock = &ctx->vb_mutex;
-
-	return vb2_queue_init(dst_vq);
-}
-
-static struct v4l2_ctrl_config vim2m_ctrl_trans_time_msec = {
-	.ops = &vim2m_ctrl_ops,
-	.id = V4L2_CID_TRANS_TIME_MSEC,
-	.name = "Transaction Time (msec)",
-	.type = V4L2_CTRL_TYPE_INTEGER,
-	.min = 1,
-	.max = 10001,
-	.step = 1,
-};
-
-static const struct v4l2_ctrl_config vim2m_ctrl_trans_num_bufs = {
-	.ops = &vim2m_ctrl_ops,
-	.id = V4L2_CID_TRANS_NUM_BUFS,
-	.name = "Buffers Per Transaction",
-	.type = V4L2_CTRL_TYPE_INTEGER,
-	.def = 1,
-	.min = 1,
-	.max = MEM2MEM_DEF_NUM_BUFS,
-	.step = 1,
-};
-
-/*
- * File operations
- */
-static int vim2m_open(struct file *file)
-{
-	struct vim2m_dev *dev = video_drvdata(file);
-	struct vim2m_ctx *ctx = NULL;
-	struct v4l2_ctrl_handler *hdl;
-	int rc = 0;
-
-	if (mutex_lock_interruptible(&dev->dev_mutex))
-		return -ERESTARTSYS;
-	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
-	if (!ctx) {
-		rc = -ENOMEM;
-		goto open_unlock;
-	}
-
-	v4l2_fh_init(&ctx->fh, video_devdata(file));
-	file->private_data = &ctx->fh;
-	ctx->dev = dev;
-	hdl = &ctx->hdl;
-	v4l2_ctrl_handler_init(hdl, 4);
-	v4l2_ctrl_new_std(hdl, &vim2m_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0);
-	v4l2_ctrl_new_std(hdl, &vim2m_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0);
-
-	vim2m_ctrl_trans_time_msec.def = default_transtime;
-	v4l2_ctrl_new_custom(hdl, &vim2m_ctrl_trans_time_msec, NULL);
-	v4l2_ctrl_new_custom(hdl, &vim2m_ctrl_trans_num_bufs, NULL);
-	if (hdl->error) {
-		rc = hdl->error;
-		v4l2_ctrl_handler_free(hdl);
-		kfree(ctx);
-		goto open_unlock;
-	}
-	ctx->fh.ctrl_handler = hdl;
-	v4l2_ctrl_handler_setup(hdl);
-
-	ctx->q_data[V4L2_M2M_SRC].fmt = &formats[0];
-	ctx->q_data[V4L2_M2M_SRC].width = 640;
-	ctx->q_data[V4L2_M2M_SRC].height = 480;
-	ctx->q_data[V4L2_M2M_SRC].sizeimage =
-		ctx->q_data[V4L2_M2M_SRC].width *
-		ctx->q_data[V4L2_M2M_SRC].height *
-		(ctx->q_data[V4L2_M2M_SRC].fmt->depth >> 3);
-	ctx->q_data[V4L2_M2M_DST] = ctx->q_data[V4L2_M2M_SRC];
-	ctx->colorspace = V4L2_COLORSPACE_REC709;
-
-	ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init);
-
-	mutex_init(&ctx->vb_mutex);
-	spin_lock_init(&ctx->irqlock);
-	INIT_DELAYED_WORK(&ctx->work_run, device_work);
-
-	if (IS_ERR(ctx->fh.m2m_ctx)) {
-		rc = PTR_ERR(ctx->fh.m2m_ctx);
-
-		v4l2_ctrl_handler_free(hdl);
-		v4l2_fh_exit(&ctx->fh);
-		kfree(ctx);
-		goto open_unlock;
-	}
-
-	v4l2_fh_add(&ctx->fh);
-	atomic_inc(&dev->num_inst);
-
-	dprintk(dev, 1, "Created instance: %p, m2m_ctx: %p\n",
-		ctx, ctx->fh.m2m_ctx);
-
-open_unlock:
-	mutex_unlock(&dev->dev_mutex);
-	return rc;
-}
-
-static int vim2m_release(struct file *file)
-{
-	struct vim2m_dev *dev = video_drvdata(file);
-	struct vim2m_ctx *ctx = file2ctx(file);
-
-	dprintk(dev, 1, "Releasing instance %p\n", ctx);
-
-	v4l2_fh_del(&ctx->fh);
-	v4l2_fh_exit(&ctx->fh);
-	v4l2_ctrl_handler_free(&ctx->hdl);
-	mutex_lock(&dev->dev_mutex);
-	v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
-	mutex_unlock(&dev->dev_mutex);
-	kfree(ctx);
-
-	atomic_dec(&dev->num_inst);
-
-	return 0;
-}
-
-static void vim2m_device_release(struct video_device *vdev)
-{
-	struct vim2m_dev *dev = container_of(vdev, struct vim2m_dev, vfd);
-
-	v4l2_device_unregister(&dev->v4l2_dev);
-	v4l2_m2m_release(dev->m2m_dev);
-#ifdef CONFIG_MEDIA_CONTROLLER
-	media_device_cleanup(&dev->mdev);
-#endif
-	kfree(dev);
-}
-
-static const struct v4l2_file_operations vim2m_fops = {
-	.owner		= THIS_MODULE,
-	.open		= vim2m_open,
-	.release	= vim2m_release,
-	.poll		= v4l2_m2m_fop_poll,
-	.unlocked_ioctl	= video_ioctl2,
-	.mmap		= v4l2_m2m_fop_mmap,
-};
-
-static const struct video_device vim2m_videodev = {
-	.name		= MEM2MEM_NAME,
-	.vfl_dir	= VFL_DIR_M2M,
-	.fops		= &vim2m_fops,
-	.ioctl_ops	= &vim2m_ioctl_ops,
-	.minor		= -1,
-	.release	= vim2m_device_release,
-	.device_caps	= V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING,
-};
-
-static const struct v4l2_m2m_ops m2m_ops = {
-	.device_run	= device_run,
-	.job_ready	= job_ready,
-	.job_abort	= job_abort,
-};
-
-static const struct media_device_ops m2m_media_ops = {
-	.req_validate = vb2_request_validate,
-	.req_queue = v4l2_m2m_request_queue,
-};
-
-static int vim2m_probe(struct platform_device *pdev)
-{
-	struct vim2m_dev *dev;
-	struct video_device *vfd;
-	int ret;
-
-	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-	if (!dev)
-		return -ENOMEM;
-
-	ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
-	if (ret)
-		goto error_free;
-
-	atomic_set(&dev->num_inst, 0);
-	mutex_init(&dev->dev_mutex);
-
-	dev->vfd = vim2m_videodev;
-	vfd = &dev->vfd;
-	vfd->lock = &dev->dev_mutex;
-	vfd->v4l2_dev = &dev->v4l2_dev;
-
-	ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0);
-	if (ret) {
-		v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
-		goto error_v4l2;
-	}
-
-	video_set_drvdata(vfd, dev);
-	v4l2_info(&dev->v4l2_dev,
-		  "Device registered as /dev/video%d\n", vfd->num);
-
-	platform_set_drvdata(pdev, dev);
-
-	dev->m2m_dev = v4l2_m2m_init(&m2m_ops);
-	if (IS_ERR(dev->m2m_dev)) {
-		v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n");
-		ret = PTR_ERR(dev->m2m_dev);
-		dev->m2m_dev = NULL;
-		goto error_dev;
-	}
-
-#ifdef CONFIG_MEDIA_CONTROLLER
-	dev->mdev.dev = &pdev->dev;
-	strscpy(dev->mdev.model, "vim2m", sizeof(dev->mdev.model));
-	strscpy(dev->mdev.bus_info, "platform:vim2m",
-		sizeof(dev->mdev.bus_info));
-	media_device_init(&dev->mdev);
-	dev->mdev.ops = &m2m_media_ops;
-	dev->v4l2_dev.mdev = &dev->mdev;
-
-	ret = v4l2_m2m_register_media_controller(dev->m2m_dev, vfd,
-						 MEDIA_ENT_F_PROC_VIDEO_SCALER);
-	if (ret) {
-		v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem media controller\n");
-		goto error_dev;
-	}
-
-	ret = media_device_register(&dev->mdev);
-	if (ret) {
-		v4l2_err(&dev->v4l2_dev, "Failed to register mem2mem media device\n");
-		goto error_m2m_mc;
-	}
-#endif
-	return 0;
-
-#ifdef CONFIG_MEDIA_CONTROLLER
-error_m2m_mc:
-	v4l2_m2m_unregister_media_controller(dev->m2m_dev);
-#endif
-error_dev:
-	video_unregister_device(&dev->vfd);
-	/* vim2m_device_release called by video_unregister_device to release various objects */
-	return ret;
-error_v4l2:
-	v4l2_device_unregister(&dev->v4l2_dev);
-error_free:
-	kfree(dev);
-
-	return ret;
-}
-
-static int vim2m_remove(struct platform_device *pdev)
-{
-	struct vim2m_dev *dev = platform_get_drvdata(pdev);
-
-	v4l2_info(&dev->v4l2_dev, "Removing " MEM2MEM_NAME);
-
-#ifdef CONFIG_MEDIA_CONTROLLER
-	media_device_unregister(&dev->mdev);
-	v4l2_m2m_unregister_media_controller(dev->m2m_dev);
-#endif
-	video_unregister_device(&dev->vfd);
-
-	return 0;
-}
-
-static struct platform_driver vim2m_pdrv = {
-	.probe		= vim2m_probe,
-	.remove		= vim2m_remove,
-	.driver		= {
-		.name	= MEM2MEM_NAME,
-	},
-};
-
-static void __exit vim2m_exit(void)
-{
-	platform_driver_unregister(&vim2m_pdrv);
-	platform_device_unregister(&vim2m_pdev);
-}
-
-static int __init vim2m_init(void)
-{
-	int ret;
-
-	ret = platform_device_register(&vim2m_pdev);
-	if (ret)
-		return ret;
-
-	ret = platform_driver_register(&vim2m_pdrv);
-	if (ret)
-		platform_device_unregister(&vim2m_pdev);
-
-	return ret;
-}
-
-module_init(vim2m_init);
-module_exit(vim2m_exit);
diff --git a/drivers/media/platform/vimc/Kconfig b/drivers/media/platform/vimc/Kconfig
deleted file mode 100644
index bd221d3e1a4a..000000000000
--- a/drivers/media/platform/vimc/Kconfig
+++ /dev/null
@@ -1,15 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-config VIDEO_VIMC
-	tristate "Virtual Media Controller Driver (VIMC)"
-	depends on VIDEO_DEV && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
-	select VIDEOBUF2_VMALLOC
-	select VIDEO_V4L2_TPG
-	help
-	  Skeleton driver for Virtual Media Controller
-
-	  This driver can be compared to the vivid driver for emulating
-	  a media node that exposes a complex media topology. The topology
-	  is hard coded for now but is meant to be highly configurable in
-	  the future.
-
-	  When in doubt, say N.
diff --git a/drivers/media/platform/vimc/Makefile b/drivers/media/platform/vimc/Makefile
deleted file mode 100644
index a53b2b532e9f..000000000000
--- a/drivers/media/platform/vimc/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-vimc-y := vimc-core.o vimc-common.o vimc-streamer.o vimc-capture.o \
-		vimc-debayer.o vimc-scaler.o vimc-sensor.o
-
-obj-$(CONFIG_VIDEO_VIMC) += vimc.o
-
diff --git a/drivers/media/platform/vimc/vimc-capture.c b/drivers/media/platform/vimc/vimc-capture.c
deleted file mode 100644
index 23e740c1c5c0..000000000000
--- a/drivers/media/platform/vimc/vimc-capture.c
+++ /dev/null
@@ -1,480 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * vimc-capture.c Virtual Media Controller Driver
- *
- * Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>
- */
-
-#include <media/v4l2-ioctl.h>
-#include <media/videobuf2-core.h>
-#include <media/videobuf2-vmalloc.h>
-
-#include "vimc-common.h"
-#include "vimc-streamer.h"
-
-struct vimc_cap_device {
-	struct vimc_ent_device ved;
-	struct video_device vdev;
-	struct v4l2_pix_format format;
-	struct vb2_queue queue;
-	struct list_head buf_list;
-	/*
-	 * NOTE: in a real driver, a spin lock must be used to access the
-	 * queue because the frames are generated from a hardware interruption
-	 * and the isr is not allowed to sleep.
-	 * Even if it is not necessary a spinlock in the vimc driver, we
-	 * use it here as a code reference
-	 */
-	spinlock_t qlock;
-	struct mutex lock;
-	u32 sequence;
-	struct vimc_stream stream;
-	struct media_pad pad;
-};
-
-static const struct v4l2_pix_format fmt_default = {
-	.width = 640,
-	.height = 480,
-	.pixelformat = V4L2_PIX_FMT_RGB24,
-	.field = V4L2_FIELD_NONE,
-	.colorspace = V4L2_COLORSPACE_DEFAULT,
-};
-
-struct vimc_cap_buffer {
-	/*
-	 * struct vb2_v4l2_buffer must be the first element
-	 * the videobuf2 framework will allocate this struct based on
-	 * buf_struct_size and use the first sizeof(struct vb2_buffer) bytes of
-	 * memory as a vb2_buffer
-	 */
-	struct vb2_v4l2_buffer vb2;
-	struct list_head list;
-};
-
-static int vimc_cap_querycap(struct file *file, void *priv,
-			     struct v4l2_capability *cap)
-{
-	strscpy(cap->driver, VIMC_PDEV_NAME, sizeof(cap->driver));
-	strscpy(cap->card, KBUILD_MODNAME, sizeof(cap->card));
-	snprintf(cap->bus_info, sizeof(cap->bus_info),
-		 "platform:%s", VIMC_PDEV_NAME);
-
-	return 0;
-}
-
-static void vimc_cap_get_format(struct vimc_ent_device *ved,
-				struct v4l2_pix_format *fmt)
-{
-	struct vimc_cap_device *vcap = container_of(ved, struct vimc_cap_device,
-						    ved);
-
-	*fmt = vcap->format;
-}
-
-static int vimc_cap_g_fmt_vid_cap(struct file *file, void *priv,
-				  struct v4l2_format *f)
-{
-	struct vimc_cap_device *vcap = video_drvdata(file);
-
-	f->fmt.pix = vcap->format;
-
-	return 0;
-}
-
-static int vimc_cap_try_fmt_vid_cap(struct file *file, void *priv,
-				    struct v4l2_format *f)
-{
-	struct v4l2_pix_format *format = &f->fmt.pix;
-	const struct vimc_pix_map *vpix;
-
-	format->width = clamp_t(u32, format->width, VIMC_FRAME_MIN_WIDTH,
-				VIMC_FRAME_MAX_WIDTH) & ~1;
-	format->height = clamp_t(u32, format->height, VIMC_FRAME_MIN_HEIGHT,
-				 VIMC_FRAME_MAX_HEIGHT) & ~1;
-
-	/* Don't accept a pixelformat that is not on the table */
-	vpix = vimc_pix_map_by_pixelformat(format->pixelformat);
-	if (!vpix) {
-		format->pixelformat = fmt_default.pixelformat;
-		vpix = vimc_pix_map_by_pixelformat(format->pixelformat);
-	}
-	/* TODO: Add support for custom bytesperline values */
-	format->bytesperline = format->width * vpix->bpp;
-	format->sizeimage = format->bytesperline * format->height;
-
-	if (format->field == V4L2_FIELD_ANY)
-		format->field = fmt_default.field;
-
-	vimc_colorimetry_clamp(format);
-
-	return 0;
-}
-
-static int vimc_cap_s_fmt_vid_cap(struct file *file, void *priv,
-				  struct v4l2_format *f)
-{
-	struct vimc_cap_device *vcap = video_drvdata(file);
-	int ret;
-
-	/* Do not change the format while stream is on */
-	if (vb2_is_busy(&vcap->queue))
-		return -EBUSY;
-
-	ret = vimc_cap_try_fmt_vid_cap(file, priv, f);
-	if (ret)
-		return ret;
-
-	dev_dbg(vcap->ved.dev, "%s: format update: "
-		"old:%dx%d (0x%x, %d, %d, %d, %d) "
-		"new:%dx%d (0x%x, %d, %d, %d, %d)\n", vcap->vdev.name,
-		/* old */
-		vcap->format.width, vcap->format.height,
-		vcap->format.pixelformat, vcap->format.colorspace,
-		vcap->format.quantization, vcap->format.xfer_func,
-		vcap->format.ycbcr_enc,
-		/* new */
-		f->fmt.pix.width, f->fmt.pix.height,
-		f->fmt.pix.pixelformat,	f->fmt.pix.colorspace,
-		f->fmt.pix.quantization, f->fmt.pix.xfer_func,
-		f->fmt.pix.ycbcr_enc);
-
-	vcap->format = f->fmt.pix;
-
-	return 0;
-}
-
-static int vimc_cap_enum_fmt_vid_cap(struct file *file, void *priv,
-				     struct v4l2_fmtdesc *f)
-{
-	const struct vimc_pix_map *vpix = vimc_pix_map_by_index(f->index);
-
-	if (!vpix)
-		return -EINVAL;
-
-	f->pixelformat = vpix->pixelformat;
-
-	return 0;
-}
-
-static int vimc_cap_enum_framesizes(struct file *file, void *fh,
-				    struct v4l2_frmsizeenum *fsize)
-{
-	const struct vimc_pix_map *vpix;
-
-	if (fsize->index)
-		return -EINVAL;
-
-	/* Only accept code in the pix map table */
-	vpix = vimc_pix_map_by_code(fsize->pixel_format);
-	if (!vpix)
-		return -EINVAL;
-
-	fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS;
-	fsize->stepwise.min_width = VIMC_FRAME_MIN_WIDTH;
-	fsize->stepwise.max_width = VIMC_FRAME_MAX_WIDTH;
-	fsize->stepwise.min_height = VIMC_FRAME_MIN_HEIGHT;
-	fsize->stepwise.max_height = VIMC_FRAME_MAX_HEIGHT;
-	fsize->stepwise.step_width = 1;
-	fsize->stepwise.step_height = 1;
-
-	return 0;
-}
-
-static const struct v4l2_file_operations vimc_cap_fops = {
-	.owner		= THIS_MODULE,
-	.open		= v4l2_fh_open,
-	.release	= vb2_fop_release,
-	.read           = vb2_fop_read,
-	.poll		= vb2_fop_poll,
-	.unlocked_ioctl = video_ioctl2,
-	.mmap           = vb2_fop_mmap,
-};
-
-static const struct v4l2_ioctl_ops vimc_cap_ioctl_ops = {
-	.vidioc_querycap = vimc_cap_querycap,
-
-	.vidioc_g_fmt_vid_cap = vimc_cap_g_fmt_vid_cap,
-	.vidioc_s_fmt_vid_cap = vimc_cap_s_fmt_vid_cap,
-	.vidioc_try_fmt_vid_cap = vimc_cap_try_fmt_vid_cap,
-	.vidioc_enum_fmt_vid_cap = vimc_cap_enum_fmt_vid_cap,
-	.vidioc_enum_framesizes = vimc_cap_enum_framesizes,
-
-	.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_expbuf = vb2_ioctl_expbuf,
-	.vidioc_streamon = vb2_ioctl_streamon,
-	.vidioc_streamoff = vb2_ioctl_streamoff,
-};
-
-static void vimc_cap_return_all_buffers(struct vimc_cap_device *vcap,
-					enum vb2_buffer_state state)
-{
-	struct vimc_cap_buffer *vbuf, *node;
-
-	spin_lock(&vcap->qlock);
-
-	list_for_each_entry_safe(vbuf, node, &vcap->buf_list, list) {
-		list_del(&vbuf->list);
-		vb2_buffer_done(&vbuf->vb2.vb2_buf, state);
-	}
-
-	spin_unlock(&vcap->qlock);
-}
-
-static int vimc_cap_start_streaming(struct vb2_queue *vq, unsigned int count)
-{
-	struct vimc_cap_device *vcap = vb2_get_drv_priv(vq);
-	struct media_entity *entity = &vcap->vdev.entity;
-	int ret;
-
-	vcap->sequence = 0;
-
-	/* Start the media pipeline */
-	ret = media_pipeline_start(entity, &vcap->stream.pipe);
-	if (ret) {
-		vimc_cap_return_all_buffers(vcap, VB2_BUF_STATE_QUEUED);
-		return ret;
-	}
-
-	ret = vimc_streamer_s_stream(&vcap->stream, &vcap->ved, 1);
-	if (ret) {
-		media_pipeline_stop(entity);
-		vimc_cap_return_all_buffers(vcap, VB2_BUF_STATE_QUEUED);
-		return ret;
-	}
-
-	return 0;
-}
-
-/*
- * Stop the stream engine. Any remaining buffers in the stream queue are
- * dequeued and passed on to the vb2 framework marked as STATE_ERROR.
- */
-static void vimc_cap_stop_streaming(struct vb2_queue *vq)
-{
-	struct vimc_cap_device *vcap = vb2_get_drv_priv(vq);
-
-	vimc_streamer_s_stream(&vcap->stream, &vcap->ved, 0);
-
-	/* Stop the media pipeline */
-	media_pipeline_stop(&vcap->vdev.entity);
-
-	/* Release all active buffers */
-	vimc_cap_return_all_buffers(vcap, VB2_BUF_STATE_ERROR);
-}
-
-static void vimc_cap_buf_queue(struct vb2_buffer *vb2_buf)
-{
-	struct vimc_cap_device *vcap = vb2_get_drv_priv(vb2_buf->vb2_queue);
-	struct vimc_cap_buffer *buf = container_of(vb2_buf,
-						   struct vimc_cap_buffer,
-						   vb2.vb2_buf);
-
-	spin_lock(&vcap->qlock);
-	list_add_tail(&buf->list, &vcap->buf_list);
-	spin_unlock(&vcap->qlock);
-}
-
-static int vimc_cap_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
-				unsigned int *nplanes, unsigned int sizes[],
-				struct device *alloc_devs[])
-{
-	struct vimc_cap_device *vcap = vb2_get_drv_priv(vq);
-
-	if (*nplanes)
-		return sizes[0] < vcap->format.sizeimage ? -EINVAL : 0;
-	/* We don't support multiplanes for now */
-	*nplanes = 1;
-	sizes[0] = vcap->format.sizeimage;
-
-	return 0;
-}
-
-static int vimc_cap_buffer_prepare(struct vb2_buffer *vb)
-{
-	struct vimc_cap_device *vcap = vb2_get_drv_priv(vb->vb2_queue);
-	unsigned long size = vcap->format.sizeimage;
-
-	if (vb2_plane_size(vb, 0) < size) {
-		dev_err(vcap->ved.dev, "%s: buffer too small (%lu < %lu)\n",
-			vcap->vdev.name, vb2_plane_size(vb, 0), size);
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static const struct vb2_ops vimc_cap_qops = {
-	.start_streaming	= vimc_cap_start_streaming,
-	.stop_streaming		= vimc_cap_stop_streaming,
-	.buf_queue		= vimc_cap_buf_queue,
-	.queue_setup		= vimc_cap_queue_setup,
-	.buf_prepare		= vimc_cap_buffer_prepare,
-	/*
-	 * Since q->lock is set we can use the standard
-	 * vb2_ops_wait_prepare/finish helper functions.
-	 */
-	.wait_prepare		= vb2_ops_wait_prepare,
-	.wait_finish		= vb2_ops_wait_finish,
-};
-
-static const struct media_entity_operations vimc_cap_mops = {
-	.link_validate		= vimc_vdev_link_validate,
-};
-
-void vimc_cap_release(struct vimc_ent_device *ved)
-{
-	struct vimc_cap_device *vcap =
-		container_of(ved, struct vimc_cap_device, ved);
-
-	media_entity_cleanup(vcap->ved.ent);
-	kfree(vcap);
-}
-
-void vimc_cap_unregister(struct vimc_ent_device *ved)
-{
-	struct vimc_cap_device *vcap =
-		container_of(ved, struct vimc_cap_device, ved);
-
-	vb2_queue_release(&vcap->queue);
-	video_unregister_device(&vcap->vdev);
-}
-
-static void *vimc_cap_process_frame(struct vimc_ent_device *ved,
-				    const void *frame)
-{
-	struct vimc_cap_device *vcap = container_of(ved, struct vimc_cap_device,
-						    ved);
-	struct vimc_cap_buffer *vimc_buf;
-	void *vbuf;
-
-	spin_lock(&vcap->qlock);
-
-	/* Get the first entry of the list */
-	vimc_buf = list_first_entry_or_null(&vcap->buf_list,
-					    typeof(*vimc_buf), list);
-	if (!vimc_buf) {
-		spin_unlock(&vcap->qlock);
-		return ERR_PTR(-EAGAIN);
-	}
-
-	/* Remove this entry from the list */
-	list_del(&vimc_buf->list);
-
-	spin_unlock(&vcap->qlock);
-
-	/* Fill the buffer */
-	vimc_buf->vb2.vb2_buf.timestamp = ktime_get_ns();
-	vimc_buf->vb2.sequence = vcap->sequence++;
-	vimc_buf->vb2.field = vcap->format.field;
-
-	vbuf = vb2_plane_vaddr(&vimc_buf->vb2.vb2_buf, 0);
-
-	memcpy(vbuf, frame, vcap->format.sizeimage);
-
-	/* Set it as ready */
-	vb2_set_plane_payload(&vimc_buf->vb2.vb2_buf, 0,
-			      vcap->format.sizeimage);
-	vb2_buffer_done(&vimc_buf->vb2.vb2_buf, VB2_BUF_STATE_DONE);
-	return NULL;
-}
-
-struct vimc_ent_device *vimc_cap_add(struct vimc_device *vimc,
-				     const char *vcfg_name)
-{
-	struct v4l2_device *v4l2_dev = &vimc->v4l2_dev;
-	const struct vimc_pix_map *vpix;
-	struct vimc_cap_device *vcap;
-	struct video_device *vdev;
-	struct vb2_queue *q;
-	int ret;
-
-	/* Allocate the vimc_cap_device struct */
-	vcap = kzalloc(sizeof(*vcap), GFP_KERNEL);
-	if (!vcap)
-		return NULL;
-
-	/* Initialize the media entity */
-	vcap->vdev.entity.name = vcfg_name;
-	vcap->vdev.entity.function = MEDIA_ENT_F_IO_V4L;
-	vcap->pad.flags = MEDIA_PAD_FL_SINK;
-	ret = media_entity_pads_init(&vcap->vdev.entity,
-				     1, &vcap->pad);
-	if (ret)
-		goto err_free_vcap;
-
-	/* Initialize the lock */
-	mutex_init(&vcap->lock);
-
-	/* Initialize the vb2 queue */
-	q = &vcap->queue;
-	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_USERPTR;
-	q->drv_priv = vcap;
-	q->buf_struct_size = sizeof(struct vimc_cap_buffer);
-	q->ops = &vimc_cap_qops;
-	q->mem_ops = &vb2_vmalloc_memops;
-	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
-	q->min_buffers_needed = 2;
-	q->lock = &vcap->lock;
-
-	ret = vb2_queue_init(q);
-	if (ret) {
-		dev_err(vimc->mdev.dev, "%s: vb2 queue init failed (err=%d)\n",
-			vcfg_name, ret);
-		goto err_clean_m_ent;
-	}
-
-	/* Initialize buffer list and its lock */
-	INIT_LIST_HEAD(&vcap->buf_list);
-	spin_lock_init(&vcap->qlock);
-
-	/* Set default frame format */
-	vcap->format = fmt_default;
-	vpix = vimc_pix_map_by_pixelformat(vcap->format.pixelformat);
-	vcap->format.bytesperline = vcap->format.width * vpix->bpp;
-	vcap->format.sizeimage = vcap->format.bytesperline *
-				 vcap->format.height;
-
-	/* Fill the vimc_ent_device struct */
-	vcap->ved.ent = &vcap->vdev.entity;
-	vcap->ved.process_frame = vimc_cap_process_frame;
-	vcap->ved.vdev_get_format = vimc_cap_get_format;
-	vcap->ved.dev = vimc->mdev.dev;
-
-	/* Initialize the video_device struct */
-	vdev = &vcap->vdev;
-	vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
-	vdev->entity.ops = &vimc_cap_mops;
-	vdev->release = video_device_release_empty;
-	vdev->fops = &vimc_cap_fops;
-	vdev->ioctl_ops = &vimc_cap_ioctl_ops;
-	vdev->lock = &vcap->lock;
-	vdev->queue = q;
-	vdev->v4l2_dev = v4l2_dev;
-	vdev->vfl_dir = VFL_DIR_RX;
-	strscpy(vdev->name, vcfg_name, sizeof(vdev->name));
-	video_set_drvdata(vdev, &vcap->ved);
-
-	/* Register the video_device with the v4l2 and the media framework */
-	ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
-	if (ret) {
-		dev_err(vimc->mdev.dev, "%s: video register failed (err=%d)\n",
-			vcap->vdev.name, ret);
-		goto err_release_queue;
-	}
-
-	return &vcap->ved;
-
-err_release_queue:
-	vb2_queue_release(q);
-err_clean_m_ent:
-	media_entity_cleanup(&vcap->vdev.entity);
-err_free_vcap:
-	kfree(vcap);
-
-	return NULL;
-}
diff --git a/drivers/media/platform/vimc/vimc-common.c b/drivers/media/platform/vimc/vimc-common.c
deleted file mode 100644
index c95c17c048f2..000000000000
--- a/drivers/media/platform/vimc/vimc-common.c
+++ /dev/null
@@ -1,369 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * vimc-common.c Virtual Media Controller Driver
- *
- * Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-
-#include "vimc-common.h"
-
-/*
- * NOTE: non-bayer formats need to come first (necessary for enum_mbus_code
- * in the scaler)
- */
-static const struct vimc_pix_map vimc_pix_map_list[] = {
-	/* TODO: add all missing formats */
-
-	/* RGB formats */
-	{
-		.code = MEDIA_BUS_FMT_BGR888_1X24,
-		.pixelformat = V4L2_PIX_FMT_BGR24,
-		.bpp = 3,
-		.bayer = false,
-	},
-	{
-		.code = MEDIA_BUS_FMT_RGB888_1X24,
-		.pixelformat = V4L2_PIX_FMT_RGB24,
-		.bpp = 3,
-		.bayer = false,
-	},
-	{
-		.code = MEDIA_BUS_FMT_ARGB8888_1X32,
-		.pixelformat = V4L2_PIX_FMT_ARGB32,
-		.bpp = 4,
-		.bayer = false,
-	},
-
-	/* Bayer formats */
-	{
-		.code = MEDIA_BUS_FMT_SBGGR8_1X8,
-		.pixelformat = V4L2_PIX_FMT_SBGGR8,
-		.bpp = 1,
-		.bayer = true,
-	},
-	{
-		.code = MEDIA_BUS_FMT_SGBRG8_1X8,
-		.pixelformat = V4L2_PIX_FMT_SGBRG8,
-		.bpp = 1,
-		.bayer = true,
-	},
-	{
-		.code = MEDIA_BUS_FMT_SGRBG8_1X8,
-		.pixelformat = V4L2_PIX_FMT_SGRBG8,
-		.bpp = 1,
-		.bayer = true,
-	},
-	{
-		.code = MEDIA_BUS_FMT_SRGGB8_1X8,
-		.pixelformat = V4L2_PIX_FMT_SRGGB8,
-		.bpp = 1,
-		.bayer = true,
-	},
-	{
-		.code = MEDIA_BUS_FMT_SBGGR10_1X10,
-		.pixelformat = V4L2_PIX_FMT_SBGGR10,
-		.bpp = 2,
-		.bayer = true,
-	},
-	{
-		.code = MEDIA_BUS_FMT_SGBRG10_1X10,
-		.pixelformat = V4L2_PIX_FMT_SGBRG10,
-		.bpp = 2,
-		.bayer = true,
-	},
-	{
-		.code = MEDIA_BUS_FMT_SGRBG10_1X10,
-		.pixelformat = V4L2_PIX_FMT_SGRBG10,
-		.bpp = 2,
-		.bayer = true,
-	},
-	{
-		.code = MEDIA_BUS_FMT_SRGGB10_1X10,
-		.pixelformat = V4L2_PIX_FMT_SRGGB10,
-		.bpp = 2,
-		.bayer = true,
-	},
-
-	/* 10bit raw bayer a-law compressed to 8 bits */
-	{
-		.code = MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8,
-		.pixelformat = V4L2_PIX_FMT_SBGGR10ALAW8,
-		.bpp = 1,
-		.bayer = true,
-	},
-	{
-		.code = MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8,
-		.pixelformat = V4L2_PIX_FMT_SGBRG10ALAW8,
-		.bpp = 1,
-		.bayer = true,
-	},
-	{
-		.code = MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8,
-		.pixelformat = V4L2_PIX_FMT_SGRBG10ALAW8,
-		.bpp = 1,
-		.bayer = true,
-	},
-	{
-		.code = MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8,
-		.pixelformat = V4L2_PIX_FMT_SRGGB10ALAW8,
-		.bpp = 1,
-		.bayer = true,
-	},
-
-	/* 10bit raw bayer DPCM compressed to 8 bits */
-	{
-		.code = MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8,
-		.pixelformat = V4L2_PIX_FMT_SBGGR10DPCM8,
-		.bpp = 1,
-		.bayer = true,
-	},
-	{
-		.code = MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8,
-		.pixelformat = V4L2_PIX_FMT_SGBRG10DPCM8,
-		.bpp = 1,
-		.bayer = true,
-	},
-	{
-		.code = MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8,
-		.pixelformat = V4L2_PIX_FMT_SGRBG10DPCM8,
-		.bpp = 1,
-		.bayer = true,
-	},
-	{
-		.code = MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8,
-		.pixelformat = V4L2_PIX_FMT_SRGGB10DPCM8,
-		.bpp = 1,
-		.bayer = true,
-	},
-	{
-		.code = MEDIA_BUS_FMT_SBGGR12_1X12,
-		.pixelformat = V4L2_PIX_FMT_SBGGR12,
-		.bpp = 2,
-		.bayer = true,
-	},
-	{
-		.code = MEDIA_BUS_FMT_SGBRG12_1X12,
-		.pixelformat = V4L2_PIX_FMT_SGBRG12,
-		.bpp = 2,
-		.bayer = true,
-	},
-	{
-		.code = MEDIA_BUS_FMT_SGRBG12_1X12,
-		.pixelformat = V4L2_PIX_FMT_SGRBG12,
-		.bpp = 2,
-		.bayer = true,
-	},
-	{
-		.code = MEDIA_BUS_FMT_SRGGB12_1X12,
-		.pixelformat = V4L2_PIX_FMT_SRGGB12,
-		.bpp = 2,
-		.bayer = true,
-	},
-};
-
-bool vimc_is_source(struct media_entity *ent)
-{
-	unsigned int i;
-
-	for (i = 0; i < ent->num_pads; i++)
-		if (ent->pads[i].flags & MEDIA_PAD_FL_SINK)
-			return false;
-	return true;
-}
-
-const struct vimc_pix_map *vimc_pix_map_by_index(unsigned int i)
-{
-	if (i >= ARRAY_SIZE(vimc_pix_map_list))
-		return NULL;
-
-	return &vimc_pix_map_list[i];
-}
-
-const struct vimc_pix_map *vimc_pix_map_by_code(u32 code)
-{
-	unsigned int i;
-
-	for (i = 0; i < ARRAY_SIZE(vimc_pix_map_list); i++) {
-		if (vimc_pix_map_list[i].code == code)
-			return &vimc_pix_map_list[i];
-	}
-	return NULL;
-}
-
-const struct vimc_pix_map *vimc_pix_map_by_pixelformat(u32 pixelformat)
-{
-	unsigned int i;
-
-	for (i = 0; i < ARRAY_SIZE(vimc_pix_map_list); i++) {
-		if (vimc_pix_map_list[i].pixelformat == pixelformat)
-			return &vimc_pix_map_list[i];
-	}
-	return NULL;
-}
-
-static int vimc_get_pix_format(struct media_pad *pad,
-			       struct v4l2_pix_format *fmt)
-{
-	if (is_media_entity_v4l2_subdev(pad->entity)) {
-		struct v4l2_subdev *sd =
-			media_entity_to_v4l2_subdev(pad->entity);
-		struct v4l2_subdev_format sd_fmt;
-		const struct vimc_pix_map *pix_map;
-		int ret;
-
-		sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
-		sd_fmt.pad = pad->index;
-
-		ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &sd_fmt);
-		if (ret)
-			return ret;
-
-		v4l2_fill_pix_format(fmt, &sd_fmt.format);
-		pix_map = vimc_pix_map_by_code(sd_fmt.format.code);
-		fmt->pixelformat = pix_map->pixelformat;
-	} else if (is_media_entity_v4l2_video_device(pad->entity)) {
-		struct video_device *vdev = container_of(pad->entity,
-							 struct video_device,
-							 entity);
-		struct vimc_ent_device *ved = video_get_drvdata(vdev);
-
-		if (!ved->vdev_get_format)
-			return -ENOIOCTLCMD;
-
-		ved->vdev_get_format(ved, fmt);
-	} else {
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-int vimc_vdev_link_validate(struct media_link *link)
-{
-	struct v4l2_pix_format source_fmt, sink_fmt;
-	int ret;
-
-	ret = vimc_get_pix_format(link->source, &source_fmt);
-	if (ret)
-		return ret;
-
-	ret = vimc_get_pix_format(link->sink, &sink_fmt);
-	if (ret)
-		return ret;
-
-	pr_info("vimc link validate: "
-		"%s:src:%dx%d (0x%x, %d, %d, %d, %d) "
-		"%s:snk:%dx%d (0x%x, %d, %d, %d, %d)\n",
-		/* src */
-		link->source->entity->name,
-		source_fmt.width, source_fmt.height,
-		source_fmt.pixelformat, source_fmt.colorspace,
-		source_fmt.quantization, source_fmt.xfer_func,
-		source_fmt.ycbcr_enc,
-		/* sink */
-		link->sink->entity->name,
-		sink_fmt.width, sink_fmt.height,
-		sink_fmt.pixelformat, sink_fmt.colorspace,
-		sink_fmt.quantization, sink_fmt.xfer_func,
-		sink_fmt.ycbcr_enc);
-
-	/* The width, height and pixelformat must match. */
-	if (source_fmt.width != sink_fmt.width ||
-	    source_fmt.height != sink_fmt.height ||
-	    source_fmt.pixelformat != sink_fmt.pixelformat)
-		return -EPIPE;
-
-	/*
-	 * The field order must match, or the sink field order must be NONE
-	 * to support interlaced hardware connected to bridges that support
-	 * progressive formats only.
-	 */
-	if (source_fmt.field != sink_fmt.field &&
-	    sink_fmt.field != V4L2_FIELD_NONE)
-		return -EPIPE;
-
-	/*
-	 * If colorspace is DEFAULT, then assume all the colorimetry is also
-	 * DEFAULT, return 0 to skip comparing the other colorimetry parameters
-	 */
-	if (source_fmt.colorspace == V4L2_COLORSPACE_DEFAULT ||
-	    sink_fmt.colorspace == V4L2_COLORSPACE_DEFAULT)
-		return 0;
-
-	/* Colorspace must match. */
-	if (source_fmt.colorspace != sink_fmt.colorspace)
-		return -EPIPE;
-
-	/* Colorimetry must match if they are not set to DEFAULT */
-	if (source_fmt.ycbcr_enc != V4L2_YCBCR_ENC_DEFAULT &&
-	    sink_fmt.ycbcr_enc != V4L2_YCBCR_ENC_DEFAULT &&
-	    source_fmt.ycbcr_enc != sink_fmt.ycbcr_enc)
-		return -EPIPE;
-
-	if (source_fmt.quantization != V4L2_QUANTIZATION_DEFAULT &&
-	    sink_fmt.quantization != V4L2_QUANTIZATION_DEFAULT &&
-	    source_fmt.quantization != sink_fmt.quantization)
-		return -EPIPE;
-
-	if (source_fmt.xfer_func != V4L2_XFER_FUNC_DEFAULT &&
-	    sink_fmt.xfer_func != V4L2_XFER_FUNC_DEFAULT &&
-	    source_fmt.xfer_func != sink_fmt.xfer_func)
-		return -EPIPE;
-
-	return 0;
-}
-
-static const struct media_entity_operations vimc_ent_sd_mops = {
-	.link_validate = v4l2_subdev_link_validate,
-};
-
-int vimc_ent_sd_register(struct vimc_ent_device *ved,
-			 struct v4l2_subdev *sd,
-			 struct v4l2_device *v4l2_dev,
-			 const char *const name,
-			 u32 function,
-			 u16 num_pads,
-			 struct media_pad *pads,
-			 const struct v4l2_subdev_ops *sd_ops)
-{
-	int ret;
-
-	/* Fill the vimc_ent_device struct */
-	ved->ent = &sd->entity;
-
-	/* Initialize the subdev */
-	v4l2_subdev_init(sd, sd_ops);
-	sd->entity.function = function;
-	sd->entity.ops = &vimc_ent_sd_mops;
-	sd->owner = THIS_MODULE;
-	strscpy(sd->name, name, sizeof(sd->name));
-	v4l2_set_subdevdata(sd, ved);
-
-	/* Expose this subdev to user space */
-	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-	if (sd->ctrl_handler)
-		sd->flags |= V4L2_SUBDEV_FL_HAS_EVENTS;
-
-	/* Initialize the media entity */
-	ret = media_entity_pads_init(&sd->entity, num_pads, pads);
-	if (ret)
-		return ret;
-
-	/* Register the subdev with the v4l2 and the media framework */
-	ret = v4l2_device_register_subdev(v4l2_dev, sd);
-	if (ret) {
-		dev_err(v4l2_dev->dev,
-			"%s: subdev register failed (err=%d)\n",
-			name, ret);
-		goto err_clean_m_ent;
-	}
-
-	return 0;
-
-err_clean_m_ent:
-	media_entity_cleanup(&sd->entity);
-	return ret;
-}
diff --git a/drivers/media/platform/vimc/vimc-common.h b/drivers/media/platform/vimc/vimc-common.h
deleted file mode 100644
index 616d5a6b0754..000000000000
--- a/drivers/media/platform/vimc/vimc-common.h
+++ /dev/null
@@ -1,224 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * vimc-common.h Virtual Media Controller Driver
- *
- * Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>
- */
-
-#ifndef _VIMC_COMMON_H_
-#define _VIMC_COMMON_H_
-
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <media/media-device.h>
-#include <media/v4l2-device.h>
-
-#define VIMC_PDEV_NAME "vimc"
-
-/* 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_CID_MEAN_WIN_SIZE		(VIMC_CID_VIMC_BASE + 1)
-
-#define VIMC_FRAME_MAX_WIDTH 4096
-#define VIMC_FRAME_MAX_HEIGHT 2160
-#define VIMC_FRAME_MIN_WIDTH 16
-#define VIMC_FRAME_MIN_HEIGHT 16
-
-#define VIMC_FRAME_INDEX(lin, col, width, bpp) ((lin * width + col) * bpp)
-
-/* Source and sink pad checks */
-#define VIMC_IS_SRC(pad)	(pad)
-#define VIMC_IS_SINK(pad)	(!(pad))
-
-/**
- * struct vimc_colorimetry_clamp - Adjust colorimetry parameters
- *
- * @fmt:		the pointer to struct v4l2_pix_format or
- *			struct v4l2_mbus_framefmt
- *
- * Entities must check if colorimetry given by the userspace is valid, if not
- * then set them as DEFAULT
- */
-#define vimc_colorimetry_clamp(fmt)					\
-do {									\
-	if ((fmt)->colorspace == V4L2_COLORSPACE_DEFAULT		\
-	    || (fmt)->colorspace > V4L2_COLORSPACE_DCI_P3) {		\
-		(fmt)->colorspace = V4L2_COLORSPACE_DEFAULT;		\
-		(fmt)->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;		\
-		(fmt)->quantization = V4L2_QUANTIZATION_DEFAULT;	\
-		(fmt)->xfer_func = V4L2_XFER_FUNC_DEFAULT;		\
-	}								\
-	if ((fmt)->ycbcr_enc > V4L2_YCBCR_ENC_SMPTE240M)		\
-		(fmt)->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;		\
-	if ((fmt)->quantization > V4L2_QUANTIZATION_LIM_RANGE)		\
-		(fmt)->quantization = V4L2_QUANTIZATION_DEFAULT;	\
-	if ((fmt)->xfer_func > V4L2_XFER_FUNC_SMPTE2084)		\
-		(fmt)->xfer_func = V4L2_XFER_FUNC_DEFAULT;		\
-} while (0)
-
-/**
- * struct vimc_pix_map - maps media bus code with v4l2 pixel format
- *
- * @code:		media bus format code defined by MEDIA_BUS_FMT_* macros
- * @bbp:		number of bytes each pixel occupies
- * @pixelformat:	pixel format devined by V4L2_PIX_FMT_* macros
- *
- * Struct which matches the MEDIA_BUS_FMT_* codes with the corresponding
- * V4L2_PIX_FMT_* fourcc pixelformat and its bytes per pixel (bpp)
- */
-struct vimc_pix_map {
-	unsigned int code;
-	unsigned int bpp;
-	u32 pixelformat;
-	bool bayer;
-};
-
-/**
- * struct vimc_ent_device - core struct that represents an entity in the
- * topology
- *
- * @dev:		a pointer of the device struct of the driver
- * @ent:		the pointer to struct media_entity for the node
- * @process_frame:	callback send a frame to that node
- * @vdev_get_format:	callback that returns the current format a pad, used
- *			only when is_media_entity_v4l2_video_device(ent) returns
- *			true
- *
- * Each node of the topology must create a vimc_ent_device struct. Depending on
- * the node it will be of an instance of v4l2_subdev or video_device struct
- * where both contains a struct media_entity.
- * Those structures should embedded the vimc_ent_device struct through
- * v4l2_set_subdevdata() and video_set_drvdata() respectivaly, allowing the
- * vimc_ent_device struct to be retrieved from the corresponding struct
- * media_entity
- */
-struct vimc_ent_device {
-	struct device *dev;
-	struct media_entity *ent;
-	void * (*process_frame)(struct vimc_ent_device *ved,
-				const void *frame);
-	void (*vdev_get_format)(struct vimc_ent_device *ved,
-			      struct v4l2_pix_format *fmt);
-};
-
-/**
- * struct vimc_device - main device for vimc driver
- *
- * @pipe_cfg	pointer to the vimc pipeline configuration structure
- * @ent_devs	array of vimc_ent_device pointers
- * @mdev	the associated media_device parent
- * @v4l2_dev	Internal v4l2 parent device
- */
-struct vimc_device {
-	const struct vimc_pipeline_config *pipe_cfg;
-	struct vimc_ent_device **ent_devs;
-	struct media_device mdev;
-	struct v4l2_device v4l2_dev;
-};
-
-/**
- * struct vimc_ent_config	Structure which describes individual
- *				configuration for each entity
- *
- * @name			entity name
- * @ved				pointer to vimc_ent_device (a node in the
- *					topology)
- * @add				initializes and registers
- *					vim entity - called from vimc-core
- * @unregister			unregisters vimc entity - called from vimc-core
- * @release			releases vimc entity - called from the v4l2_dev
- *					release callback
- */
-struct vimc_ent_config {
-	const char *name;
-	struct vimc_ent_device *(*add)(struct vimc_device *vimc,
-				       const char *vcfg_name);
-	void (*unregister)(struct vimc_ent_device *ved);
-	void (*release)(struct vimc_ent_device *ved);
-};
-
-/**
- * vimc_is_source - returns true if the entity has only source pads
- *
- * @ent: pointer to &struct media_entity
- *
- */
-bool vimc_is_source(struct media_entity *ent);
-
-/* prototypes for vimc_ent_config hooks */
-struct vimc_ent_device *vimc_cap_add(struct vimc_device *vimc,
-				     const char *vcfg_name);
-void vimc_cap_unregister(struct vimc_ent_device *ved);
-void vimc_cap_release(struct vimc_ent_device *ved);
-
-struct vimc_ent_device *vimc_deb_add(struct vimc_device *vimc,
-				     const char *vcfg_name);
-void vimc_deb_release(struct vimc_ent_device *ved);
-
-struct vimc_ent_device *vimc_sca_add(struct vimc_device *vimc,
-				     const char *vcfg_name);
-void vimc_sca_release(struct vimc_ent_device *ved);
-
-struct vimc_ent_device *vimc_sen_add(struct vimc_device *vimc,
-				     const char *vcfg_name);
-void vimc_sen_release(struct vimc_ent_device *ved);
-
-/**
- * vimc_pix_map_by_index - get vimc_pix_map struct by its index
- *
- * @i:			index of the vimc_pix_map struct in vimc_pix_map_list
- */
-const struct vimc_pix_map *vimc_pix_map_by_index(unsigned int i);
-
-/**
- * vimc_pix_map_by_code - get vimc_pix_map struct by media bus code
- *
- * @code:		media bus format code defined by MEDIA_BUS_FMT_* macros
- */
-const struct vimc_pix_map *vimc_pix_map_by_code(u32 code);
-
-/**
- * vimc_pix_map_by_pixelformat - get vimc_pix_map struct by v4l2 pixel format
- *
- * @pixelformat:	pixel format devined by V4L2_PIX_FMT_* macros
- */
-const struct vimc_pix_map *vimc_pix_map_by_pixelformat(u32 pixelformat);
-
-/**
- * vimc_ent_sd_register - initialize and register a subdev node
- *
- * @ved:	the vimc_ent_device struct to be initialize
- * @sd:		the v4l2_subdev struct to be initialize and registered
- * @v4l2_dev:	the v4l2 device to register the v4l2_subdev
- * @name:	name of the sub-device. Please notice that the name must be
- *		unique.
- * @function:	media entity function defined by MEDIA_ENT_F_* macros
- * @num_pads:	number of pads to initialize
- * @pads:	the array of pads of the entity, the caller should set the
-		flags of the pads
- * @sd_ops:	pointer to &struct v4l2_subdev_ops.
- *
- * Helper function initialize and register the struct vimc_ent_device and struct
- * v4l2_subdev which represents a subdev node in the topology
- */
-int vimc_ent_sd_register(struct vimc_ent_device *ved,
-			 struct v4l2_subdev *sd,
-			 struct v4l2_device *v4l2_dev,
-			 const char *const name,
-			 u32 function,
-			 u16 num_pads,
-			 struct media_pad *pads,
-			 const struct v4l2_subdev_ops *sd_ops);
-
-/**
- * vimc_vdev_link_validate - validates a media link
- *
- * @link: pointer to &struct media_link
- *
- * This function calls validates if a media link is valid for streaming.
- */
-int vimc_vdev_link_validate(struct media_link *link);
-
-#endif
diff --git a/drivers/media/platform/vimc/vimc-core.c b/drivers/media/platform/vimc/vimc-core.c
deleted file mode 100644
index 339126e565dc..000000000000
--- a/drivers/media/platform/vimc/vimc-core.c
+++ /dev/null
@@ -1,381 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * vimc-core.c Virtual Media Controller Driver
- *
- * Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <media/media-device.h>
-#include <media/v4l2-device.h>
-
-#include "vimc-common.h"
-
-#define VIMC_MDEV_MODEL_NAME "VIMC MDEV"
-
-#define VIMC_ENT_LINK(src, srcpad, sink, sinkpad, link_flags) {	\
-	.src_ent = src,						\
-	.src_pad = srcpad,					\
-	.sink_ent = sink,					\
-	.sink_pad = sinkpad,					\
-	.flags = link_flags,					\
-}
-
-/* Structure which describes links between entities */
-struct vimc_ent_link {
-	unsigned int src_ent;
-	u16 src_pad;
-	unsigned int sink_ent;
-	u16 sink_pad;
-	u32 flags;
-};
-
-/* Structure which describes the whole topology */
-struct vimc_pipeline_config {
-	const struct vimc_ent_config *ents;
-	size_t num_ents;
-	const struct vimc_ent_link *links;
-	size_t num_links;
-};
-
-/* --------------------------------------------------------------------------
- * Topology Configuration
- */
-
-static struct vimc_ent_config ent_config[] = {
-	{
-		.name = "Sensor A",
-		.add = vimc_sen_add,
-		.release = vimc_sen_release,
-	},
-	{
-		.name = "Sensor B",
-		.add = vimc_sen_add,
-		.release = vimc_sen_release,
-	},
-	{
-		.name = "Debayer A",
-		.add = vimc_deb_add,
-		.release = vimc_deb_release,
-	},
-	{
-		.name = "Debayer B",
-		.add = vimc_deb_add,
-		.release = vimc_deb_release,
-	},
-	{
-		.name = "Raw Capture 0",
-		.add = vimc_cap_add,
-		.unregister = vimc_cap_unregister,
-		.release = vimc_cap_release,
-	},
-	{
-		.name = "Raw Capture 1",
-		.add = vimc_cap_add,
-		.unregister = vimc_cap_unregister,
-		.release = vimc_cap_release,
-	},
-	{
-		/* TODO: change this to vimc-input when it is implemented */
-		.name = "RGB/YUV Input",
-		.add = vimc_sen_add,
-		.release = vimc_sen_release,
-	},
-	{
-		.name = "Scaler",
-		.add = vimc_sca_add,
-		.release = vimc_sca_release,
-	},
-	{
-		.name = "RGB/YUV Capture",
-		.add = vimc_cap_add,
-		.unregister = vimc_cap_unregister,
-		.release = vimc_cap_release,
-	},
-};
-
-static const struct vimc_ent_link ent_links[] = {
-	/* Link: Sensor A (Pad 0)->(Pad 0) Debayer A */
-	VIMC_ENT_LINK(0, 0, 2, 0, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE),
-	/* Link: Sensor A (Pad 0)->(Pad 0) Raw Capture 0 */
-	VIMC_ENT_LINK(0, 0, 4, 0, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE),
-	/* Link: Sensor B (Pad 0)->(Pad 0) Debayer B */
-	VIMC_ENT_LINK(1, 0, 3, 0, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE),
-	/* Link: Sensor B (Pad 0)->(Pad 0) Raw Capture 1 */
-	VIMC_ENT_LINK(1, 0, 5, 0, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE),
-	/* Link: Debayer A (Pad 1)->(Pad 0) Scaler */
-	VIMC_ENT_LINK(2, 1, 7, 0, MEDIA_LNK_FL_ENABLED),
-	/* Link: Debayer B (Pad 1)->(Pad 0) Scaler */
-	VIMC_ENT_LINK(3, 1, 7, 0, 0),
-	/* Link: RGB/YUV Input (Pad 0)->(Pad 0) Scaler */
-	VIMC_ENT_LINK(6, 0, 7, 0, 0),
-	/* Link: Scaler (Pad 1)->(Pad 0) RGB/YUV Capture */
-	VIMC_ENT_LINK(7, 1, 8, 0, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE),
-};
-
-static struct vimc_pipeline_config pipe_cfg = {
-	.ents		= ent_config,
-	.num_ents	= ARRAY_SIZE(ent_config),
-	.links		= ent_links,
-	.num_links	= ARRAY_SIZE(ent_links)
-};
-
-/* -------------------------------------------------------------------------- */
-
-static void vimc_rm_links(struct vimc_device *vimc)
-{
-	unsigned int i;
-
-	for (i = 0; i < vimc->pipe_cfg->num_ents; i++)
-		media_entity_remove_links(vimc->ent_devs[i]->ent);
-}
-
-static int vimc_create_links(struct vimc_device *vimc)
-{
-	unsigned int i;
-	int ret;
-
-	/* Initialize the links between entities */
-	for (i = 0; i < vimc->pipe_cfg->num_links; i++) {
-		const struct vimc_ent_link *link = &vimc->pipe_cfg->links[i];
-
-		struct vimc_ent_device *ved_src =
-			vimc->ent_devs[link->src_ent];
-		struct vimc_ent_device *ved_sink =
-			vimc->ent_devs[link->sink_ent];
-
-		ret = media_create_pad_link(ved_src->ent, link->src_pad,
-					    ved_sink->ent, link->sink_pad,
-					    link->flags);
-		if (ret)
-			goto err_rm_links;
-	}
-
-	return 0;
-
-err_rm_links:
-	vimc_rm_links(vimc);
-	return ret;
-}
-
-static int vimc_add_subdevs(struct vimc_device *vimc)
-{
-	unsigned int i;
-
-	for (i = 0; i < vimc->pipe_cfg->num_ents; i++) {
-		dev_dbg(vimc->mdev.dev, "new entity for %s\n",
-			vimc->pipe_cfg->ents[i].name);
-		vimc->ent_devs[i] = vimc->pipe_cfg->ents[i].add(vimc,
-					vimc->pipe_cfg->ents[i].name);
-		if (!vimc->ent_devs[i]) {
-			dev_err(vimc->mdev.dev, "add new entity for %s\n",
-				vimc->pipe_cfg->ents[i].name);
-			return -EINVAL;
-		}
-	}
-	return 0;
-}
-
-static void vimc_release_subdevs(struct vimc_device *vimc)
-{
-	unsigned int i;
-
-	for (i = 0; i < vimc->pipe_cfg->num_ents; i++)
-		if (vimc->ent_devs[i])
-			vimc->pipe_cfg->ents[i].release(vimc->ent_devs[i]);
-}
-
-static void vimc_unregister_subdevs(struct vimc_device *vimc)
-{
-	unsigned int i;
-
-	for (i = 0; i < vimc->pipe_cfg->num_ents; i++)
-		if (vimc->ent_devs[i] && vimc->pipe_cfg->ents[i].unregister)
-			vimc->pipe_cfg->ents[i].unregister(vimc->ent_devs[i]);
-}
-
-static void vimc_v4l2_dev_release(struct v4l2_device *v4l2_dev)
-{
-	struct vimc_device *vimc =
-		container_of(v4l2_dev, struct vimc_device, v4l2_dev);
-
-	vimc_release_subdevs(vimc);
-	media_device_cleanup(&vimc->mdev);
-	kfree(vimc->ent_devs);
-	kfree(vimc);
-}
-
-static int vimc_register_devices(struct vimc_device *vimc)
-{
-	int ret;
-
-	/* Register the v4l2 struct */
-	ret = v4l2_device_register(vimc->mdev.dev, &vimc->v4l2_dev);
-	if (ret) {
-		dev_err(vimc->mdev.dev,
-			"v4l2 device register failed (err=%d)\n", ret);
-		return ret;
-	}
-	/* allocate ent_devs */
-	vimc->ent_devs = kcalloc(vimc->pipe_cfg->num_ents,
-				 sizeof(*vimc->ent_devs), GFP_KERNEL);
-	if (!vimc->ent_devs) {
-		ret = -ENOMEM;
-		goto err_v4l2_unregister;
-	}
-
-	/* Invoke entity config hooks to initialize and register subdevs */
-	ret = vimc_add_subdevs(vimc);
-	if (ret)
-		/* remove sundevs that got added */
-		goto err_rm_subdevs;
-
-	/* Initialize links */
-	ret = vimc_create_links(vimc);
-	if (ret)
-		goto err_rm_subdevs;
-
-	/* Register the media device */
-	ret = media_device_register(&vimc->mdev);
-	if (ret) {
-		dev_err(vimc->mdev.dev,
-			"media device register failed (err=%d)\n", ret);
-		goto err_rm_subdevs;
-	}
-
-	/* Expose all subdev's nodes*/
-	ret = v4l2_device_register_subdev_nodes(&vimc->v4l2_dev);
-	if (ret) {
-		dev_err(vimc->mdev.dev,
-			"vimc subdev nodes registration failed (err=%d)\n",
-			ret);
-		goto err_mdev_unregister;
-	}
-
-	return 0;
-
-err_mdev_unregister:
-	media_device_unregister(&vimc->mdev);
-err_rm_subdevs:
-	vimc_unregister_subdevs(vimc);
-	vimc_release_subdevs(vimc);
-	kfree(vimc->ent_devs);
-err_v4l2_unregister:
-	v4l2_device_unregister(&vimc->v4l2_dev);
-
-	return ret;
-}
-
-static void vimc_unregister(struct vimc_device *vimc)
-{
-	vimc_unregister_subdevs(vimc);
-	media_device_unregister(&vimc->mdev);
-	v4l2_device_unregister(&vimc->v4l2_dev);
-}
-
-static int vimc_probe(struct platform_device *pdev)
-{
-	struct vimc_device *vimc;
-	int ret;
-
-	dev_dbg(&pdev->dev, "probe");
-
-	vimc = kzalloc(sizeof(*vimc), GFP_KERNEL);
-	if (!vimc)
-		return -ENOMEM;
-
-	vimc->pipe_cfg = &pipe_cfg;
-
-	/* Link the media device within the v4l2_device */
-	vimc->v4l2_dev.mdev = &vimc->mdev;
-
-	/* Initialize media device */
-	strscpy(vimc->mdev.model, VIMC_MDEV_MODEL_NAME,
-		sizeof(vimc->mdev.model));
-	snprintf(vimc->mdev.bus_info, sizeof(vimc->mdev.bus_info),
-		 "platform:%s", VIMC_PDEV_NAME);
-	vimc->mdev.dev = &pdev->dev;
-	media_device_init(&vimc->mdev);
-
-	ret = vimc_register_devices(vimc);
-	if (ret) {
-		media_device_cleanup(&vimc->mdev);
-		kfree(vimc);
-		return ret;
-	}
-	/*
-	 * the release cb is set only after successful registration.
-	 * if the registration fails, we release directly from probe
-	 */
-
-	vimc->v4l2_dev.release = vimc_v4l2_dev_release;
-	platform_set_drvdata(pdev, vimc);
-	return 0;
-}
-
-static int vimc_remove(struct platform_device *pdev)
-{
-	struct vimc_device *vimc = platform_get_drvdata(pdev);
-
-	dev_dbg(&pdev->dev, "remove");
-
-	vimc_unregister(vimc);
-	v4l2_device_put(&vimc->v4l2_dev);
-
-	return 0;
-}
-
-static void vimc_dev_release(struct device *dev)
-{
-}
-
-static struct platform_device vimc_pdev = {
-	.name = VIMC_PDEV_NAME,
-	.dev.release = vimc_dev_release,
-};
-
-static struct platform_driver vimc_pdrv = {
-	.probe		= vimc_probe,
-	.remove		= vimc_remove,
-	.driver		= {
-		.name	= VIMC_PDEV_NAME,
-	},
-};
-
-static int __init vimc_init(void)
-{
-	int ret;
-
-	ret = platform_device_register(&vimc_pdev);
-	if (ret) {
-		dev_err(&vimc_pdev.dev,
-			"platform device registration failed (err=%d)\n", ret);
-		return ret;
-	}
-
-	ret = platform_driver_register(&vimc_pdrv);
-	if (ret) {
-		dev_err(&vimc_pdev.dev,
-			"platform driver registration failed (err=%d)\n", ret);
-		platform_driver_unregister(&vimc_pdrv);
-		return ret;
-	}
-
-	return 0;
-}
-
-static void __exit vimc_exit(void)
-{
-	platform_driver_unregister(&vimc_pdrv);
-
-	platform_device_unregister(&vimc_pdev);
-}
-
-module_init(vimc_init);
-module_exit(vimc_exit);
-
-MODULE_DESCRIPTION("Virtual Media Controller Driver (VIMC)");
-MODULE_AUTHOR("Helen Fornazier <helen.fornazier@gmail.com>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/vimc/vimc-debayer.c b/drivers/media/platform/vimc/vimc-debayer.c
deleted file mode 100644
index baf6bf9f65b5..000000000000
--- a/drivers/media/platform/vimc/vimc-debayer.c
+++ /dev/null
@@ -1,581 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * vimc-debayer.c Virtual Media Controller Driver
- *
- * Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>
- */
-
-#include <linux/moduleparam.h>
-#include <linux/platform_device.h>
-#include <linux/vmalloc.h>
-#include <linux/v4l2-mediabus.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-event.h>
-#include <media/v4l2-subdev.h>
-
-#include "vimc-common.h"
-
-enum vimc_deb_rgb_colors {
-	VIMC_DEB_RED = 0,
-	VIMC_DEB_GREEN = 1,
-	VIMC_DEB_BLUE = 2,
-};
-
-struct vimc_deb_pix_map {
-	u32 code;
-	enum vimc_deb_rgb_colors order[2][2];
-};
-
-struct vimc_deb_device {
-	struct vimc_ent_device ved;
-	struct v4l2_subdev sd;
-	/* The active format */
-	struct v4l2_mbus_framefmt sink_fmt;
-	u32 src_code;
-	void (*set_rgb_src)(struct vimc_deb_device *vdeb, unsigned int lin,
-			    unsigned int col, unsigned int rgb[3]);
-	/* Values calculated when the stream starts */
-	u8 *src_frame;
-	const struct vimc_deb_pix_map *sink_pix_map;
-	unsigned int sink_bpp;
-	unsigned int mean_win_size;
-	struct v4l2_ctrl_handler hdl;
-	struct media_pad pads[2];
-};
-
-static const struct v4l2_mbus_framefmt sink_fmt_default = {
-	.width = 640,
-	.height = 480,
-	.code = MEDIA_BUS_FMT_SRGGB8_1X8,
-	.field = V4L2_FIELD_NONE,
-	.colorspace = V4L2_COLORSPACE_DEFAULT,
-};
-
-static const struct vimc_deb_pix_map vimc_deb_pix_map_list[] = {
-	{
-		.code = MEDIA_BUS_FMT_SBGGR8_1X8,
-		.order = { { VIMC_DEB_BLUE, VIMC_DEB_GREEN },
-			   { VIMC_DEB_GREEN, VIMC_DEB_RED } }
-	},
-	{
-		.code = MEDIA_BUS_FMT_SGBRG8_1X8,
-		.order = { { VIMC_DEB_GREEN, VIMC_DEB_BLUE },
-			   { VIMC_DEB_RED, VIMC_DEB_GREEN } }
-	},
-	{
-		.code = MEDIA_BUS_FMT_SGRBG8_1X8,
-		.order = { { VIMC_DEB_GREEN, VIMC_DEB_RED },
-			   { VIMC_DEB_BLUE, VIMC_DEB_GREEN } }
-	},
-	{
-		.code = MEDIA_BUS_FMT_SRGGB8_1X8,
-		.order = { { VIMC_DEB_RED, VIMC_DEB_GREEN },
-			   { VIMC_DEB_GREEN, VIMC_DEB_BLUE } }
-	},
-	{
-		.code = MEDIA_BUS_FMT_SBGGR10_1X10,
-		.order = { { VIMC_DEB_BLUE, VIMC_DEB_GREEN },
-			   { VIMC_DEB_GREEN, VIMC_DEB_RED } }
-	},
-	{
-		.code = MEDIA_BUS_FMT_SGBRG10_1X10,
-		.order = { { VIMC_DEB_GREEN, VIMC_DEB_BLUE },
-			   { VIMC_DEB_RED, VIMC_DEB_GREEN } }
-	},
-	{
-		.code = MEDIA_BUS_FMT_SGRBG10_1X10,
-		.order = { { VIMC_DEB_GREEN, VIMC_DEB_RED },
-			   { VIMC_DEB_BLUE, VIMC_DEB_GREEN } }
-	},
-	{
-		.code = MEDIA_BUS_FMT_SRGGB10_1X10,
-		.order = { { VIMC_DEB_RED, VIMC_DEB_GREEN },
-			   { VIMC_DEB_GREEN, VIMC_DEB_BLUE } }
-	},
-	{
-		.code = MEDIA_BUS_FMT_SBGGR12_1X12,
-		.order = { { VIMC_DEB_BLUE, VIMC_DEB_GREEN },
-			   { VIMC_DEB_GREEN, VIMC_DEB_RED } }
-	},
-	{
-		.code = MEDIA_BUS_FMT_SGBRG12_1X12,
-		.order = { { VIMC_DEB_GREEN, VIMC_DEB_BLUE },
-			   { VIMC_DEB_RED, VIMC_DEB_GREEN } }
-	},
-	{
-		.code = MEDIA_BUS_FMT_SGRBG12_1X12,
-		.order = { { VIMC_DEB_GREEN, VIMC_DEB_RED },
-			   { VIMC_DEB_BLUE, VIMC_DEB_GREEN } }
-	},
-	{
-		.code = MEDIA_BUS_FMT_SRGGB12_1X12,
-		.order = { { VIMC_DEB_RED, VIMC_DEB_GREEN },
-			   { VIMC_DEB_GREEN, VIMC_DEB_BLUE } }
-	},
-};
-
-static const struct vimc_deb_pix_map *vimc_deb_pix_map_by_code(u32 code)
-{
-	unsigned int i;
-
-	for (i = 0; i < ARRAY_SIZE(vimc_deb_pix_map_list); i++)
-		if (vimc_deb_pix_map_list[i].code == code)
-			return &vimc_deb_pix_map_list[i];
-
-	return NULL;
-}
-
-static int vimc_deb_init_cfg(struct v4l2_subdev *sd,
-			     struct v4l2_subdev_pad_config *cfg)
-{
-	struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd);
-	struct v4l2_mbus_framefmt *mf;
-	unsigned int i;
-
-	mf = v4l2_subdev_get_try_format(sd, cfg, 0);
-	*mf = sink_fmt_default;
-
-	for (i = 1; i < sd->entity.num_pads; i++) {
-		mf = v4l2_subdev_get_try_format(sd, cfg, i);
-		*mf = sink_fmt_default;
-		mf->code = vdeb->src_code;
-	}
-
-	return 0;
-}
-
-static int vimc_deb_enum_mbus_code(struct v4l2_subdev *sd,
-				   struct v4l2_subdev_pad_config *cfg,
-				   struct v4l2_subdev_mbus_code_enum *code)
-{
-	/* We only support one format for source pads */
-	if (VIMC_IS_SRC(code->pad)) {
-		struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd);
-
-		if (code->index)
-			return -EINVAL;
-
-		code->code = vdeb->src_code;
-	} else {
-		if (code->index >= ARRAY_SIZE(vimc_deb_pix_map_list))
-			return -EINVAL;
-
-		code->code = vimc_deb_pix_map_list[code->index].code;
-	}
-
-	return 0;
-}
-
-static int vimc_deb_enum_frame_size(struct v4l2_subdev *sd,
-				    struct v4l2_subdev_pad_config *cfg,
-				    struct v4l2_subdev_frame_size_enum *fse)
-{
-	struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd);
-
-	if (fse->index)
-		return -EINVAL;
-
-	if (VIMC_IS_SINK(fse->pad)) {
-		const struct vimc_deb_pix_map *vpix =
-			vimc_deb_pix_map_by_code(fse->code);
-
-		if (!vpix)
-			return -EINVAL;
-	} else if (fse->code != vdeb->src_code) {
-		return -EINVAL;
-	}
-
-	fse->min_width = VIMC_FRAME_MIN_WIDTH;
-	fse->max_width = VIMC_FRAME_MAX_WIDTH;
-	fse->min_height = VIMC_FRAME_MIN_HEIGHT;
-	fse->max_height = VIMC_FRAME_MAX_HEIGHT;
-
-	return 0;
-}
-
-static int vimc_deb_get_fmt(struct v4l2_subdev *sd,
-			    struct v4l2_subdev_pad_config *cfg,
-			    struct v4l2_subdev_format *fmt)
-{
-	struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd);
-
-	/* Get the current sink format */
-	fmt->format = fmt->which == V4L2_SUBDEV_FORMAT_TRY ?
-		      *v4l2_subdev_get_try_format(sd, cfg, 0) :
-		      vdeb->sink_fmt;
-
-	/* Set the right code for the source pad */
-	if (VIMC_IS_SRC(fmt->pad))
-		fmt->format.code = vdeb->src_code;
-
-	return 0;
-}
-
-static void vimc_deb_adjust_sink_fmt(struct v4l2_mbus_framefmt *fmt)
-{
-	const struct vimc_deb_pix_map *vpix;
-
-	/* Don't accept a code that is not on the debayer table */
-	vpix = vimc_deb_pix_map_by_code(fmt->code);
-	if (!vpix)
-		fmt->code = sink_fmt_default.code;
-
-	fmt->width = clamp_t(u32, fmt->width, VIMC_FRAME_MIN_WIDTH,
-			     VIMC_FRAME_MAX_WIDTH) & ~1;
-	fmt->height = clamp_t(u32, fmt->height, VIMC_FRAME_MIN_HEIGHT,
-			      VIMC_FRAME_MAX_HEIGHT) & ~1;
-
-	if (fmt->field == V4L2_FIELD_ANY)
-		fmt->field = sink_fmt_default.field;
-
-	vimc_colorimetry_clamp(fmt);
-}
-
-static int vimc_deb_set_fmt(struct v4l2_subdev *sd,
-			    struct v4l2_subdev_pad_config *cfg,
-			    struct v4l2_subdev_format *fmt)
-{
-	struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd);
-	struct v4l2_mbus_framefmt *sink_fmt;
-
-	if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
-		/* Do not change the format while stream is on */
-		if (vdeb->src_frame)
-			return -EBUSY;
-
-		sink_fmt = &vdeb->sink_fmt;
-	} else {
-		sink_fmt = v4l2_subdev_get_try_format(sd, cfg, 0);
-	}
-
-	/*
-	 * Do not change the format of the source pad,
-	 * it is propagated from the sink
-	 */
-	if (VIMC_IS_SRC(fmt->pad)) {
-		fmt->format = *sink_fmt;
-		/* TODO: Add support for other formats */
-		fmt->format.code = vdeb->src_code;
-	} else {
-		/* Set the new format in the sink pad */
-		vimc_deb_adjust_sink_fmt(&fmt->format);
-
-		dev_dbg(vdeb->ved.dev, "%s: sink format update: "
-			"old:%dx%d (0x%x, %d, %d, %d, %d) "
-			"new:%dx%d (0x%x, %d, %d, %d, %d)\n", vdeb->sd.name,
-			/* old */
-			sink_fmt->width, sink_fmt->height, sink_fmt->code,
-			sink_fmt->colorspace, sink_fmt->quantization,
-			sink_fmt->xfer_func, sink_fmt->ycbcr_enc,
-			/* new */
-			fmt->format.width, fmt->format.height, fmt->format.code,
-			fmt->format.colorspace,	fmt->format.quantization,
-			fmt->format.xfer_func, fmt->format.ycbcr_enc);
-
-		*sink_fmt = fmt->format;
-	}
-
-	return 0;
-}
-
-static const struct v4l2_subdev_pad_ops vimc_deb_pad_ops = {
-	.init_cfg		= vimc_deb_init_cfg,
-	.enum_mbus_code		= vimc_deb_enum_mbus_code,
-	.enum_frame_size	= vimc_deb_enum_frame_size,
-	.get_fmt		= vimc_deb_get_fmt,
-	.set_fmt		= vimc_deb_set_fmt,
-};
-
-static void vimc_deb_set_rgb_mbus_fmt_rgb888_1x24(struct vimc_deb_device *vdeb,
-						  unsigned int lin,
-						  unsigned int col,
-						  unsigned int rgb[3])
-{
-	unsigned int i, index;
-
-	index = VIMC_FRAME_INDEX(lin, col, vdeb->sink_fmt.width, 3);
-	for (i = 0; i < 3; i++)
-		vdeb->src_frame[index + i] = rgb[i];
-}
-
-static int vimc_deb_s_stream(struct v4l2_subdev *sd, int enable)
-{
-	struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd);
-
-	if (enable) {
-		const struct vimc_pix_map *vpix;
-		unsigned int frame_size;
-
-		if (vdeb->src_frame)
-			return 0;
-
-		/* Calculate the frame size of the source pad */
-		vpix = vimc_pix_map_by_code(vdeb->src_code);
-		frame_size = vdeb->sink_fmt.width * vdeb->sink_fmt.height *
-				vpix->bpp;
-
-		/* Save the bytes per pixel of the sink */
-		vpix = vimc_pix_map_by_code(vdeb->sink_fmt.code);
-		vdeb->sink_bpp = vpix->bpp;
-
-		/* Get the corresponding pixel map from the table */
-		vdeb->sink_pix_map =
-			vimc_deb_pix_map_by_code(vdeb->sink_fmt.code);
-
-		/*
-		 * Allocate the frame buffer. Use vmalloc to be able to
-		 * allocate a large amount of memory
-		 */
-		vdeb->src_frame = vmalloc(frame_size);
-		if (!vdeb->src_frame)
-			return -ENOMEM;
-
-	} else {
-		if (!vdeb->src_frame)
-			return 0;
-
-		vfree(vdeb->src_frame);
-		vdeb->src_frame = NULL;
-	}
-
-	return 0;
-}
-
-static const struct v4l2_subdev_core_ops vimc_deb_core_ops = {
-	.log_status = v4l2_ctrl_subdev_log_status,
-	.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
-	.unsubscribe_event = v4l2_event_subdev_unsubscribe,
-};
-
-static const struct v4l2_subdev_video_ops vimc_deb_video_ops = {
-	.s_stream = vimc_deb_s_stream,
-};
-
-static const struct v4l2_subdev_ops vimc_deb_ops = {
-	.core = &vimc_deb_core_ops,
-	.pad = &vimc_deb_pad_ops,
-	.video = &vimc_deb_video_ops,
-};
-
-static unsigned int vimc_deb_get_val(const u8 *bytes,
-				     const unsigned int n_bytes)
-{
-	unsigned int i;
-	unsigned int acc = 0;
-
-	for (i = 0; i < n_bytes; i++)
-		acc = acc + (bytes[i] << (8 * i));
-
-	return acc;
-}
-
-static void vimc_deb_calc_rgb_sink(struct vimc_deb_device *vdeb,
-				   const u8 *frame,
-				   const unsigned int lin,
-				   const unsigned int col,
-				   unsigned int rgb[3])
-{
-	unsigned int i, seek, wlin, wcol;
-	unsigned int n_rgb[3] = {0, 0, 0};
-
-	for (i = 0; i < 3; i++)
-		rgb[i] = 0;
-
-	/*
-	 * Calculate how many we need to subtract to get to the pixel in
-	 * the top left corner of the mean window (considering the current
-	 * pixel as the center)
-	 */
-	seek = vdeb->mean_win_size / 2;
-
-	/* Sum the values of the colors in the mean window */
-
-	dev_dbg(vdeb->ved.dev,
-		"deb: %s: --- Calc pixel %dx%d, window mean %d, seek %d ---\n",
-		vdeb->sd.name, lin, col, vdeb->sink_fmt.height, seek);
-
-	/*
-	 * Iterate through all the lines in the mean window, start
-	 * with zero if the pixel is outside the frame and don't pass
-	 * the height when the pixel is in the bottom border of the
-	 * frame
-	 */
-	for (wlin = seek > lin ? 0 : lin - seek;
-	     wlin < lin + seek + 1 && wlin < vdeb->sink_fmt.height;
-	     wlin++) {
-
-		/*
-		 * Iterate through all the columns in the mean window, start
-		 * with zero if the pixel is outside the frame and don't pass
-		 * the width when the pixel is in the right border of the
-		 * frame
-		 */
-		for (wcol = seek > col ? 0 : col - seek;
-		     wcol < col + seek + 1 && wcol < vdeb->sink_fmt.width;
-		     wcol++) {
-			enum vimc_deb_rgb_colors color;
-			unsigned int index;
-
-			/* Check which color this pixel is */
-			color = vdeb->sink_pix_map->order[wlin % 2][wcol % 2];
-
-			index = VIMC_FRAME_INDEX(wlin, wcol,
-						 vdeb->sink_fmt.width,
-						 vdeb->sink_bpp);
-
-			dev_dbg(vdeb->ved.dev,
-				"deb: %s: RGB CALC: frame index %d, win pos %dx%d, color %d\n",
-				vdeb->sd.name, index, wlin, wcol, color);
-
-			/* Get its value */
-			rgb[color] = rgb[color] +
-				vimc_deb_get_val(&frame[index], vdeb->sink_bpp);
-
-			/* Save how many values we already added */
-			n_rgb[color]++;
-
-			dev_dbg(vdeb->ved.dev, "deb: %s: RGB CALC: val %d, n %d\n",
-				vdeb->sd.name, rgb[color], n_rgb[color]);
-		}
-	}
-
-	/* Calculate the mean */
-	for (i = 0; i < 3; i++) {
-		dev_dbg(vdeb->ved.dev,
-			"deb: %s: PRE CALC: %dx%d Color %d, val %d, n %d\n",
-			vdeb->sd.name, lin, col, i, rgb[i], n_rgb[i]);
-
-		if (n_rgb[i])
-			rgb[i] = rgb[i] / n_rgb[i];
-
-		dev_dbg(vdeb->ved.dev,
-			"deb: %s: FINAL CALC: %dx%d Color %d, val %d\n",
-			vdeb->sd.name, lin, col, i, rgb[i]);
-	}
-}
-
-static void *vimc_deb_process_frame(struct vimc_ent_device *ved,
-				    const void *sink_frame)
-{
-	struct vimc_deb_device *vdeb = container_of(ved, struct vimc_deb_device,
-						    ved);
-	unsigned int rgb[3];
-	unsigned int i, j;
-
-	/* If the stream in this node is not active, just return */
-	if (!vdeb->src_frame)
-		return ERR_PTR(-EINVAL);
-
-	for (i = 0; i < vdeb->sink_fmt.height; i++)
-		for (j = 0; j < vdeb->sink_fmt.width; j++) {
-			vimc_deb_calc_rgb_sink(vdeb, sink_frame, i, j, rgb);
-			vdeb->set_rgb_src(vdeb, i, j, rgb);
-		}
-
-	return vdeb->src_frame;
-}
-
-static int vimc_deb_s_ctrl(struct v4l2_ctrl *ctrl)
-{
-	struct vimc_deb_device *vdeb =
-		container_of(ctrl->handler, struct vimc_deb_device, hdl);
-
-	switch (ctrl->id) {
-	case VIMC_CID_MEAN_WIN_SIZE:
-		vdeb->mean_win_size = ctrl->val;
-		break;
-	default:
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static const struct v4l2_ctrl_ops vimc_deb_ctrl_ops = {
-	.s_ctrl = vimc_deb_s_ctrl,
-};
-
-void vimc_deb_release(struct vimc_ent_device *ved)
-{
-	struct vimc_deb_device *vdeb =
-		container_of(ved, struct vimc_deb_device, ved);
-
-	v4l2_ctrl_handler_free(&vdeb->hdl);
-	media_entity_cleanup(vdeb->ved.ent);
-	kfree(vdeb);
-}
-
-static const struct v4l2_ctrl_config vimc_deb_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_deb_ctrl_mean_win_size = {
-	.ops = &vimc_deb_ctrl_ops,
-	.id = VIMC_CID_MEAN_WIN_SIZE,
-	.name = "Debayer Mean Window Size",
-	.type = V4L2_CTRL_TYPE_INTEGER,
-	.min = 1,
-	.max = 25,
-	.step = 2,
-	.def = 3,
-};
-
-struct vimc_ent_device *vimc_deb_add(struct vimc_device *vimc,
-				     const char *vcfg_name)
-{
-	struct v4l2_device *v4l2_dev = &vimc->v4l2_dev;
-	struct vimc_deb_device *vdeb;
-	int ret;
-
-	/* Allocate the vdeb struct */
-	vdeb = kzalloc(sizeof(*vdeb), GFP_KERNEL);
-	if (!vdeb)
-		return NULL;
-
-	/* Create controls: */
-	v4l2_ctrl_handler_init(&vdeb->hdl, 2);
-	v4l2_ctrl_new_custom(&vdeb->hdl, &vimc_deb_ctrl_class, NULL);
-	v4l2_ctrl_new_custom(&vdeb->hdl, &vimc_deb_ctrl_mean_win_size, NULL);
-	vdeb->sd.ctrl_handler = &vdeb->hdl;
-	if (vdeb->hdl.error) {
-		ret = vdeb->hdl.error;
-		goto err_free_vdeb;
-	}
-
-	/* Initialize ved and sd */
-	vdeb->pads[0].flags = MEDIA_PAD_FL_SINK;
-	vdeb->pads[1].flags = MEDIA_PAD_FL_SOURCE;
-
-	ret = vimc_ent_sd_register(&vdeb->ved, &vdeb->sd, v4l2_dev,
-				   vcfg_name,
-				   MEDIA_ENT_F_PROC_VIDEO_PIXEL_ENC_CONV, 2,
-				   vdeb->pads, &vimc_deb_ops);
-	if (ret)
-		goto err_free_hdl;
-
-	vdeb->ved.process_frame = vimc_deb_process_frame;
-	vdeb->ved.dev = vimc->mdev.dev;
-	vdeb->mean_win_size = vimc_deb_ctrl_mean_win_size.def;
-
-	/* Initialize the frame format */
-	vdeb->sink_fmt = sink_fmt_default;
-	/*
-	 * TODO: Add support for more output formats, we only support
-	 * RGB888 for now
-	 * NOTE: the src format is always the same as the sink, except
-	 * for the code
-	 */
-	vdeb->src_code = MEDIA_BUS_FMT_RGB888_1X24;
-	vdeb->set_rgb_src = vimc_deb_set_rgb_mbus_fmt_rgb888_1x24;
-
-	return &vdeb->ved;
-
-err_free_hdl:
-	v4l2_ctrl_handler_free(&vdeb->hdl);
-err_free_vdeb:
-	kfree(vdeb);
-
-	return NULL;
-}
diff --git a/drivers/media/platform/vimc/vimc-scaler.c b/drivers/media/platform/vimc/vimc-scaler.c
deleted file mode 100644
index 7521439747c5..000000000000
--- a/drivers/media/platform/vimc/vimc-scaler.c
+++ /dev/null
@@ -1,511 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * vimc-scaler.c Virtual Media Controller Driver
- *
- * Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>
- */
-
-#include <linux/moduleparam.h>
-#include <linux/vmalloc.h>
-#include <linux/v4l2-mediabus.h>
-#include <media/v4l2-rect.h>
-#include <media/v4l2-subdev.h>
-
-#include "vimc-common.h"
-
-static unsigned int sca_mult = 3;
-module_param(sca_mult, uint, 0000);
-MODULE_PARM_DESC(sca_mult, " the image size multiplier");
-
-#define MAX_ZOOM	8
-
-#define VIMC_SCA_FMT_WIDTH_DEFAULT  640
-#define VIMC_SCA_FMT_HEIGHT_DEFAULT 480
-
-struct vimc_sca_device {
-	struct vimc_ent_device ved;
-	struct v4l2_subdev sd;
-	/* NOTE: the source fmt is the same as the sink
-	 * with the width and hight multiplied by mult
-	 */
-	struct v4l2_mbus_framefmt sink_fmt;
-	struct v4l2_rect crop_rect;
-	/* Values calculated when the stream starts */
-	u8 *src_frame;
-	unsigned int src_line_size;
-	unsigned int bpp;
-	struct media_pad pads[2];
-};
-
-static const struct v4l2_mbus_framefmt sink_fmt_default = {
-	.width = VIMC_SCA_FMT_WIDTH_DEFAULT,
-	.height = VIMC_SCA_FMT_HEIGHT_DEFAULT,
-	.code = MEDIA_BUS_FMT_RGB888_1X24,
-	.field = V4L2_FIELD_NONE,
-	.colorspace = V4L2_COLORSPACE_DEFAULT,
-};
-
-static const struct v4l2_rect crop_rect_default = {
-	.width = VIMC_SCA_FMT_WIDTH_DEFAULT,
-	.height = VIMC_SCA_FMT_HEIGHT_DEFAULT,
-	.top = 0,
-	.left = 0,
-};
-
-static const struct v4l2_rect crop_rect_min = {
-	.width = VIMC_FRAME_MIN_WIDTH,
-	.height = VIMC_FRAME_MIN_HEIGHT,
-	.top = 0,
-	.left = 0,
-};
-
-static struct v4l2_rect
-vimc_sca_get_crop_bound_sink(const struct v4l2_mbus_framefmt *sink_fmt)
-{
-	/* Get the crop bounds to clamp the crop rectangle correctly */
-	struct v4l2_rect r = {
-		.left = 0,
-		.top = 0,
-		.width = sink_fmt->width,
-		.height = sink_fmt->height,
-	};
-	return r;
-}
-
-static void vimc_sca_adjust_sink_crop(struct v4l2_rect *r,
-				      const struct v4l2_mbus_framefmt *sink_fmt)
-{
-	const struct v4l2_rect sink_rect =
-		vimc_sca_get_crop_bound_sink(sink_fmt);
-
-	/* Disallow rectangles smaller than the minimal one. */
-	v4l2_rect_set_min_size(r, &crop_rect_min);
-	v4l2_rect_map_inside(r, &sink_rect);
-}
-
-static int vimc_sca_init_cfg(struct v4l2_subdev *sd,
-			     struct v4l2_subdev_pad_config *cfg)
-{
-	struct v4l2_mbus_framefmt *mf;
-	struct v4l2_rect *r;
-	unsigned int i;
-
-	mf = v4l2_subdev_get_try_format(sd, cfg, 0);
-	*mf = sink_fmt_default;
-
-	r = v4l2_subdev_get_try_crop(sd, cfg, 0);
-	*r = crop_rect_default;
-
-	for (i = 1; i < sd->entity.num_pads; i++) {
-		mf = v4l2_subdev_get_try_format(sd, cfg, i);
-		*mf = sink_fmt_default;
-		mf->width = mf->width * sca_mult;
-		mf->height = mf->height * sca_mult;
-	}
-
-	return 0;
-}
-
-static int vimc_sca_enum_mbus_code(struct v4l2_subdev *sd,
-				   struct v4l2_subdev_pad_config *cfg,
-				   struct v4l2_subdev_mbus_code_enum *code)
-{
-	const struct vimc_pix_map *vpix = vimc_pix_map_by_index(code->index);
-
-	/* We don't support bayer format */
-	if (!vpix || vpix->bayer)
-		return -EINVAL;
-
-	code->code = vpix->code;
-
-	return 0;
-}
-
-static int vimc_sca_enum_frame_size(struct v4l2_subdev *sd,
-				    struct v4l2_subdev_pad_config *cfg,
-				    struct v4l2_subdev_frame_size_enum *fse)
-{
-	const struct vimc_pix_map *vpix;
-
-	if (fse->index)
-		return -EINVAL;
-
-	/* Only accept code in the pix map table in non bayer format */
-	vpix = vimc_pix_map_by_code(fse->code);
-	if (!vpix || vpix->bayer)
-		return -EINVAL;
-
-	fse->min_width = VIMC_FRAME_MIN_WIDTH;
-	fse->min_height = VIMC_FRAME_MIN_HEIGHT;
-
-	if (VIMC_IS_SINK(fse->pad)) {
-		fse->max_width = VIMC_FRAME_MAX_WIDTH;
-		fse->max_height = VIMC_FRAME_MAX_HEIGHT;
-	} else {
-		fse->max_width = VIMC_FRAME_MAX_WIDTH * MAX_ZOOM;
-		fse->max_height = VIMC_FRAME_MAX_HEIGHT * MAX_ZOOM;
-	}
-
-	return 0;
-}
-
-static int vimc_sca_get_fmt(struct v4l2_subdev *sd,
-			    struct v4l2_subdev_pad_config *cfg,
-			    struct v4l2_subdev_format *format)
-{
-	struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd);
-	struct v4l2_rect *crop_rect;
-
-	/* Get the current sink format */
-	if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
-		format->format = *v4l2_subdev_get_try_format(sd, cfg, 0);
-		crop_rect = v4l2_subdev_get_try_crop(sd, cfg, 0);
-	} else {
-		format->format = vsca->sink_fmt;
-		crop_rect = &vsca->crop_rect;
-	}
-
-	/* Scale the frame size for the source pad */
-	if (VIMC_IS_SRC(format->pad)) {
-		format->format.width = crop_rect->width * sca_mult;
-		format->format.height = crop_rect->height * sca_mult;
-	}
-
-	return 0;
-}
-
-static void vimc_sca_adjust_sink_fmt(struct v4l2_mbus_framefmt *fmt)
-{
-	const struct vimc_pix_map *vpix;
-
-	/* Only accept code in the pix map table in non bayer format */
-	vpix = vimc_pix_map_by_code(fmt->code);
-	if (!vpix || vpix->bayer)
-		fmt->code = sink_fmt_default.code;
-
-	fmt->width = clamp_t(u32, fmt->width, VIMC_FRAME_MIN_WIDTH,
-			     VIMC_FRAME_MAX_WIDTH) & ~1;
-	fmt->height = clamp_t(u32, fmt->height, VIMC_FRAME_MIN_HEIGHT,
-			      VIMC_FRAME_MAX_HEIGHT) & ~1;
-
-	if (fmt->field == V4L2_FIELD_ANY)
-		fmt->field = sink_fmt_default.field;
-
-	vimc_colorimetry_clamp(fmt);
-}
-
-static int vimc_sca_set_fmt(struct v4l2_subdev *sd,
-			    struct v4l2_subdev_pad_config *cfg,
-			    struct v4l2_subdev_format *fmt)
-{
-	struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd);
-	struct v4l2_mbus_framefmt *sink_fmt;
-	struct v4l2_rect *crop_rect;
-
-	if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
-		/* Do not change the format while stream is on */
-		if (vsca->src_frame)
-			return -EBUSY;
-
-		sink_fmt = &vsca->sink_fmt;
-		crop_rect = &vsca->crop_rect;
-	} else {
-		sink_fmt = v4l2_subdev_get_try_format(sd, cfg, 0);
-		crop_rect = v4l2_subdev_get_try_crop(sd, cfg, 0);
-	}
-
-	/*
-	 * Do not change the format of the source pad,
-	 * it is propagated from the sink
-	 */
-	if (VIMC_IS_SRC(fmt->pad)) {
-		fmt->format = *sink_fmt;
-		fmt->format.width = crop_rect->width * sca_mult;
-		fmt->format.height = crop_rect->height * sca_mult;
-	} else {
-		/* Set the new format in the sink pad */
-		vimc_sca_adjust_sink_fmt(&fmt->format);
-
-		dev_dbg(vsca->ved.dev, "%s: sink format update: "
-			"old:%dx%d (0x%x, %d, %d, %d, %d) "
-			"new:%dx%d (0x%x, %d, %d, %d, %d)\n", vsca->sd.name,
-			/* old */
-			sink_fmt->width, sink_fmt->height, sink_fmt->code,
-			sink_fmt->colorspace, sink_fmt->quantization,
-			sink_fmt->xfer_func, sink_fmt->ycbcr_enc,
-			/* new */
-			fmt->format.width, fmt->format.height, fmt->format.code,
-			fmt->format.colorspace,	fmt->format.quantization,
-			fmt->format.xfer_func, fmt->format.ycbcr_enc);
-
-		*sink_fmt = fmt->format;
-
-		/* Do the crop, but respect the current bounds */
-		vimc_sca_adjust_sink_crop(crop_rect, sink_fmt);
-	}
-
-	return 0;
-}
-
-static int vimc_sca_get_selection(struct v4l2_subdev *sd,
-				  struct v4l2_subdev_pad_config *cfg,
-				  struct v4l2_subdev_selection *sel)
-{
-	struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd);
-	struct v4l2_mbus_framefmt *sink_fmt;
-	struct v4l2_rect *crop_rect;
-
-	if (VIMC_IS_SRC(sel->pad))
-		return -EINVAL;
-
-	if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
-		sink_fmt = &vsca->sink_fmt;
-		crop_rect = &vsca->crop_rect;
-	} else {
-		sink_fmt = v4l2_subdev_get_try_format(sd, cfg, 0);
-		crop_rect = v4l2_subdev_get_try_crop(sd, cfg, 0);
-	}
-
-	switch (sel->target) {
-	case V4L2_SEL_TGT_CROP:
-		sel->r = *crop_rect;
-		break;
-	case V4L2_SEL_TGT_CROP_BOUNDS:
-		sel->r = vimc_sca_get_crop_bound_sink(sink_fmt);
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static int vimc_sca_set_selection(struct v4l2_subdev *sd,
-				  struct v4l2_subdev_pad_config *cfg,
-				  struct v4l2_subdev_selection *sel)
-{
-	struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd);
-	struct v4l2_mbus_framefmt *sink_fmt;
-	struct v4l2_rect *crop_rect;
-
-	if (VIMC_IS_SRC(sel->pad))
-		return -EINVAL;
-
-	if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
-		/* Do not change the format while stream is on */
-		if (vsca->src_frame)
-			return -EBUSY;
-
-		crop_rect = &vsca->crop_rect;
-		sink_fmt = &vsca->sink_fmt;
-	} else {
-		crop_rect = v4l2_subdev_get_try_crop(sd, cfg, 0);
-		sink_fmt = v4l2_subdev_get_try_format(sd, cfg, 0);
-	}
-
-	switch (sel->target) {
-	case V4L2_SEL_TGT_CROP:
-		/* Do the crop, but respect the current bounds */
-		vimc_sca_adjust_sink_crop(&sel->r, sink_fmt);
-		*crop_rect = sel->r;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static const struct v4l2_subdev_pad_ops vimc_sca_pad_ops = {
-	.init_cfg		= vimc_sca_init_cfg,
-	.enum_mbus_code		= vimc_sca_enum_mbus_code,
-	.enum_frame_size	= vimc_sca_enum_frame_size,
-	.get_fmt		= vimc_sca_get_fmt,
-	.set_fmt		= vimc_sca_set_fmt,
-	.get_selection		= vimc_sca_get_selection,
-	.set_selection		= vimc_sca_set_selection,
-};
-
-static int vimc_sca_s_stream(struct v4l2_subdev *sd, int enable)
-{
-	struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd);
-
-	if (enable) {
-		const struct vimc_pix_map *vpix;
-		unsigned int frame_size;
-
-		if (vsca->src_frame)
-			return 0;
-
-		/* Save the bytes per pixel of the sink */
-		vpix = vimc_pix_map_by_code(vsca->sink_fmt.code);
-		vsca->bpp = vpix->bpp;
-
-		/* Calculate the width in bytes of the src frame */
-		vsca->src_line_size = vsca->crop_rect.width *
-				      sca_mult * vsca->bpp;
-
-		/* Calculate the frame size of the source pad */
-		frame_size = vsca->src_line_size * vsca->crop_rect.height *
-			     sca_mult;
-
-		/* Allocate the frame buffer. Use vmalloc to be able to
-		 * allocate a large amount of memory
-		 */
-		vsca->src_frame = vmalloc(frame_size);
-		if (!vsca->src_frame)
-			return -ENOMEM;
-
-	} else {
-		if (!vsca->src_frame)
-			return 0;
-
-		vfree(vsca->src_frame);
-		vsca->src_frame = NULL;
-	}
-
-	return 0;
-}
-
-static const struct v4l2_subdev_video_ops vimc_sca_video_ops = {
-	.s_stream = vimc_sca_s_stream,
-};
-
-static const struct v4l2_subdev_ops vimc_sca_ops = {
-	.pad = &vimc_sca_pad_ops,
-	.video = &vimc_sca_video_ops,
-};
-
-static void vimc_sca_fill_pix(u8 *const ptr,
-			      const u8 *const pixel,
-			      const unsigned int bpp)
-{
-	unsigned int i;
-
-	/* copy the pixel to the pointer */
-	for (i = 0; i < bpp; i++)
-		ptr[i] = pixel[i];
-}
-
-static void vimc_sca_scale_pix(const struct vimc_sca_device *const vsca,
-			       unsigned int lin, unsigned int col,
-			       const u8 *const sink_frame)
-{
-	const struct v4l2_rect crop_rect = vsca->crop_rect;
-	unsigned int i, j, index;
-	const u8 *pixel;
-
-	/* Point to the pixel value in position (lin, col) in the sink frame */
-	index = VIMC_FRAME_INDEX(lin, col,
-				 vsca->sink_fmt.width,
-				 vsca->bpp);
-	pixel = &sink_frame[index];
-
-	dev_dbg(vsca->ved.dev,
-		"sca: %s: --- scale_pix sink pos %dx%d, index %d ---\n",
-		vsca->sd.name, lin, col, index);
-
-	/* point to the place we are going to put the first pixel
-	 * in the scaled src frame
-	 */
-	lin -= crop_rect.top;
-	col -= crop_rect.left;
-	index = VIMC_FRAME_INDEX(lin * sca_mult, col * sca_mult,
-				 crop_rect.width * sca_mult, vsca->bpp);
-
-	dev_dbg(vsca->ved.dev, "sca: %s: scale_pix src pos %dx%d, index %d\n",
-		vsca->sd.name, lin * sca_mult, col * sca_mult, index);
-
-	/* Repeat this pixel mult times */
-	for (i = 0; i < sca_mult; i++) {
-		/* Iterate through each beginning of a
-		 * pixel repetition in a line
-		 */
-		for (j = 0; j < sca_mult * vsca->bpp; j += vsca->bpp) {
-			dev_dbg(vsca->ved.dev,
-				"sca: %s: sca: scale_pix src pos %d\n",
-				vsca->sd.name, index + j);
-
-			/* copy the pixel to the position index + j */
-			vimc_sca_fill_pix(&vsca->src_frame[index + j],
-					  pixel, vsca->bpp);
-		}
-
-		/* move the index to the next line */
-		index += vsca->src_line_size;
-	}
-}
-
-static void vimc_sca_fill_src_frame(const struct vimc_sca_device *const vsca,
-				    const u8 *const sink_frame)
-{
-	const struct v4l2_rect r = vsca->crop_rect;
-	unsigned int i, j;
-
-	/* Scale each pixel from the original sink frame */
-	/* TODO: implement scale down, only scale up is supported for now */
-	for (i = r.top; i < r.top + r.height; i++)
-		for (j = r.left; j < r.left + r.width; j++)
-			vimc_sca_scale_pix(vsca, i, j, sink_frame);
-}
-
-static void *vimc_sca_process_frame(struct vimc_ent_device *ved,
-				    const void *sink_frame)
-{
-	struct vimc_sca_device *vsca = container_of(ved, struct vimc_sca_device,
-						    ved);
-
-	/* If the stream in this node is not active, just return */
-	if (!vsca->src_frame)
-		return ERR_PTR(-EINVAL);
-
-	vimc_sca_fill_src_frame(vsca, sink_frame);
-
-	return vsca->src_frame;
-};
-
-void vimc_sca_release(struct vimc_ent_device *ved)
-{
-	struct vimc_sca_device *vsca =
-		container_of(ved, struct vimc_sca_device, ved);
-
-	media_entity_cleanup(vsca->ved.ent);
-	kfree(vsca);
-}
-
-struct vimc_ent_device *vimc_sca_add(struct vimc_device *vimc,
-				     const char *vcfg_name)
-{
-	struct v4l2_device *v4l2_dev = &vimc->v4l2_dev;
-	struct vimc_sca_device *vsca;
-	int ret;
-
-	/* Allocate the vsca struct */
-	vsca = kzalloc(sizeof(*vsca), GFP_KERNEL);
-	if (!vsca)
-		return NULL;
-
-	/* Initialize ved and sd */
-	vsca->pads[0].flags = MEDIA_PAD_FL_SINK;
-	vsca->pads[1].flags = MEDIA_PAD_FL_SOURCE;
-
-	ret = vimc_ent_sd_register(&vsca->ved, &vsca->sd, v4l2_dev,
-				   vcfg_name,
-				   MEDIA_ENT_F_PROC_VIDEO_SCALER, 2,
-				   vsca->pads, &vimc_sca_ops);
-	if (ret) {
-		kfree(vsca);
-		return NULL;
-	}
-
-	vsca->ved.process_frame = vimc_sca_process_frame;
-	vsca->ved.dev = vimc->mdev.dev;
-
-	/* Initialize the frame format */
-	vsca->sink_fmt = sink_fmt_default;
-
-	/* Initialize the crop selection */
-	vsca->crop_rect = crop_rect_default;
-
-	return &vsca->ved;
-}
diff --git a/drivers/media/platform/vimc/vimc-sensor.c b/drivers/media/platform/vimc/vimc-sensor.c
deleted file mode 100644
index 92daee58209e..000000000000
--- a/drivers/media/platform/vimc/vimc-sensor.c
+++ /dev/null
@@ -1,376 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * vimc-sensor.c Virtual Media Controller Driver
- *
- * Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>
- */
-
-#include <linux/v4l2-mediabus.h>
-#include <linux/vmalloc.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-event.h>
-#include <media/v4l2-subdev.h>
-#include <media/tpg/v4l2-tpg.h>
-
-#include "vimc-common.h"
-
-struct vimc_sen_device {
-	struct vimc_ent_device ved;
-	struct v4l2_subdev sd;
-	struct tpg_data tpg;
-	u8 *frame;
-	/* The active format */
-	struct v4l2_mbus_framefmt mbus_format;
-	struct v4l2_ctrl_handler hdl;
-	struct media_pad pad;
-};
-
-static const struct v4l2_mbus_framefmt fmt_default = {
-	.width = 640,
-	.height = 480,
-	.code = MEDIA_BUS_FMT_RGB888_1X24,
-	.field = V4L2_FIELD_NONE,
-	.colorspace = V4L2_COLORSPACE_DEFAULT,
-};
-
-static int vimc_sen_init_cfg(struct v4l2_subdev *sd,
-			     struct v4l2_subdev_pad_config *cfg)
-{
-	unsigned int i;
-
-	for (i = 0; i < sd->entity.num_pads; i++) {
-		struct v4l2_mbus_framefmt *mf;
-
-		mf = v4l2_subdev_get_try_format(sd, cfg, i);
-		*mf = fmt_default;
-	}
-
-	return 0;
-}
-
-static int vimc_sen_enum_mbus_code(struct v4l2_subdev *sd,
-				   struct v4l2_subdev_pad_config *cfg,
-				   struct v4l2_subdev_mbus_code_enum *code)
-{
-	const struct vimc_pix_map *vpix = vimc_pix_map_by_index(code->index);
-
-	if (!vpix)
-		return -EINVAL;
-
-	code->code = vpix->code;
-
-	return 0;
-}
-
-static int vimc_sen_enum_frame_size(struct v4l2_subdev *sd,
-				    struct v4l2_subdev_pad_config *cfg,
-				    struct v4l2_subdev_frame_size_enum *fse)
-{
-	const struct vimc_pix_map *vpix;
-
-	if (fse->index)
-		return -EINVAL;
-
-	/* Only accept code in the pix map table */
-	vpix = vimc_pix_map_by_code(fse->code);
-	if (!vpix)
-		return -EINVAL;
-
-	fse->min_width = VIMC_FRAME_MIN_WIDTH;
-	fse->max_width = VIMC_FRAME_MAX_WIDTH;
-	fse->min_height = VIMC_FRAME_MIN_HEIGHT;
-	fse->max_height = VIMC_FRAME_MAX_HEIGHT;
-
-	return 0;
-}
-
-static int vimc_sen_get_fmt(struct v4l2_subdev *sd,
-			    struct v4l2_subdev_pad_config *cfg,
-			    struct v4l2_subdev_format *fmt)
-{
-	struct vimc_sen_device *vsen =
-				container_of(sd, struct vimc_sen_device, sd);
-
-	fmt->format = fmt->which == V4L2_SUBDEV_FORMAT_TRY ?
-		      *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) :
-		      vsen->mbus_format;
-
-	return 0;
-}
-
-static void vimc_sen_tpg_s_format(struct vimc_sen_device *vsen)
-{
-	const struct vimc_pix_map *vpix =
-				vimc_pix_map_by_code(vsen->mbus_format.code);
-
-	tpg_reset_source(&vsen->tpg, vsen->mbus_format.width,
-			 vsen->mbus_format.height, vsen->mbus_format.field);
-	tpg_s_bytesperline(&vsen->tpg, 0, vsen->mbus_format.width * vpix->bpp);
-	tpg_s_buf_height(&vsen->tpg, vsen->mbus_format.height);
-	tpg_s_fourcc(&vsen->tpg, vpix->pixelformat);
-	/* TODO: add support for V4L2_FIELD_ALTERNATE */
-	tpg_s_field(&vsen->tpg, vsen->mbus_format.field, false);
-	tpg_s_colorspace(&vsen->tpg, vsen->mbus_format.colorspace);
-	tpg_s_ycbcr_enc(&vsen->tpg, vsen->mbus_format.ycbcr_enc);
-	tpg_s_quantization(&vsen->tpg, vsen->mbus_format.quantization);
-	tpg_s_xfer_func(&vsen->tpg, vsen->mbus_format.xfer_func);
-}
-
-static void vimc_sen_adjust_fmt(struct v4l2_mbus_framefmt *fmt)
-{
-	const struct vimc_pix_map *vpix;
-
-	/* Only accept code in the pix map table */
-	vpix = vimc_pix_map_by_code(fmt->code);
-	if (!vpix)
-		fmt->code = fmt_default.code;
-
-	fmt->width = clamp_t(u32, fmt->width, VIMC_FRAME_MIN_WIDTH,
-			     VIMC_FRAME_MAX_WIDTH) & ~1;
-	fmt->height = clamp_t(u32, fmt->height, VIMC_FRAME_MIN_HEIGHT,
-			      VIMC_FRAME_MAX_HEIGHT) & ~1;
-
-	/* TODO: add support for V4L2_FIELD_ALTERNATE */
-	if (fmt->field == V4L2_FIELD_ANY || fmt->field == V4L2_FIELD_ALTERNATE)
-		fmt->field = fmt_default.field;
-
-	vimc_colorimetry_clamp(fmt);
-}
-
-static int vimc_sen_set_fmt(struct v4l2_subdev *sd,
-			    struct v4l2_subdev_pad_config *cfg,
-			    struct v4l2_subdev_format *fmt)
-{
-	struct vimc_sen_device *vsen = v4l2_get_subdevdata(sd);
-	struct v4l2_mbus_framefmt *mf;
-
-	if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
-		/* Do not change the format while stream is on */
-		if (vsen->frame)
-			return -EBUSY;
-
-		mf = &vsen->mbus_format;
-	} else {
-		mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
-	}
-
-	/* Set the new format */
-	vimc_sen_adjust_fmt(&fmt->format);
-
-	dev_dbg(vsen->ved.dev, "%s: format update: "
-		"old:%dx%d (0x%x, %d, %d, %d, %d) "
-		"new:%dx%d (0x%x, %d, %d, %d, %d)\n", vsen->sd.name,
-		/* old */
-		mf->width, mf->height, mf->code,
-		mf->colorspace,	mf->quantization,
-		mf->xfer_func, mf->ycbcr_enc,
-		/* new */
-		fmt->format.width, fmt->format.height, fmt->format.code,
-		fmt->format.colorspace, fmt->format.quantization,
-		fmt->format.xfer_func, fmt->format.ycbcr_enc);
-
-	*mf = fmt->format;
-
-	return 0;
-}
-
-static const struct v4l2_subdev_pad_ops vimc_sen_pad_ops = {
-	.init_cfg		= vimc_sen_init_cfg,
-	.enum_mbus_code		= vimc_sen_enum_mbus_code,
-	.enum_frame_size	= vimc_sen_enum_frame_size,
-	.get_fmt		= vimc_sen_get_fmt,
-	.set_fmt		= vimc_sen_set_fmt,
-};
-
-static void *vimc_sen_process_frame(struct vimc_ent_device *ved,
-				    const void *sink_frame)
-{
-	struct vimc_sen_device *vsen = container_of(ved, struct vimc_sen_device,
-						    ved);
-
-	tpg_fill_plane_buffer(&vsen->tpg, 0, 0, vsen->frame);
-	return vsen->frame;
-}
-
-static int vimc_sen_s_stream(struct v4l2_subdev *sd, int enable)
-{
-	struct vimc_sen_device *vsen =
-				container_of(sd, struct vimc_sen_device, sd);
-
-	if (enable) {
-		const struct vimc_pix_map *vpix;
-		unsigned int frame_size;
-
-		/* Calculate the frame size */
-		vpix = vimc_pix_map_by_code(vsen->mbus_format.code);
-		frame_size = vsen->mbus_format.width * vpix->bpp *
-			     vsen->mbus_format.height;
-
-		/*
-		 * Allocate the frame buffer. Use vmalloc to be able to
-		 * allocate a large amount of memory
-		 */
-		vsen->frame = vmalloc(frame_size);
-		if (!vsen->frame)
-			return -ENOMEM;
-
-		/* configure the test pattern generator */
-		vimc_sen_tpg_s_format(vsen);
-
-	} else {
-
-		vfree(vsen->frame);
-		vsen->frame = NULL;
-	}
-
-	return 0;
-}
-
-static const struct v4l2_subdev_core_ops vimc_sen_core_ops = {
-	.log_status = v4l2_ctrl_subdev_log_status,
-	.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
-	.unsubscribe_event = v4l2_event_subdev_unsubscribe,
-};
-
-static const struct v4l2_subdev_video_ops vimc_sen_video_ops = {
-	.s_stream = vimc_sen_s_stream,
-};
-
-static const struct v4l2_subdev_ops vimc_sen_ops = {
-	.core = &vimc_sen_core_ops,
-	.pad = &vimc_sen_pad_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;
-	case V4L2_CID_BRIGHTNESS:
-		tpg_s_brightness(&vsen->tpg, ctrl->val);
-		break;
-	case V4L2_CID_CONTRAST:
-		tpg_s_contrast(&vsen->tpg, ctrl->val);
-		break;
-	case V4L2_CID_HUE:
-		tpg_s_hue(&vsen->tpg, ctrl->val);
-		break;
-	case V4L2_CID_SATURATION:
-		tpg_s_saturation(&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,
-};
-
-void vimc_sen_release(struct vimc_ent_device *ved)
-{
-	struct vimc_sen_device *vsen =
-		container_of(ved, struct vimc_sen_device, ved);
-
-	v4l2_ctrl_handler_free(&vsen->hdl);
-	tpg_free(&vsen->tpg);
-	media_entity_cleanup(vsen->ved.ent);
-	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,
-};
-
-struct vimc_ent_device *vimc_sen_add(struct vimc_device *vimc,
-				     const char *vcfg_name)
-{
-	struct v4l2_device *v4l2_dev = &vimc->v4l2_dev;
-	struct vimc_sen_device *vsen;
-	int ret;
-
-	/* Allocate the vsen struct */
-	vsen = kzalloc(sizeof(*vsen), GFP_KERNEL);
-	if (!vsen)
-		return NULL;
-
-	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);
-	v4l2_ctrl_new_std(&vsen->hdl, &vimc_sen_ctrl_ops,
-			  V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
-	v4l2_ctrl_new_std(&vsen->hdl, &vimc_sen_ctrl_ops,
-			  V4L2_CID_CONTRAST, 0, 255, 1, 128);
-	v4l2_ctrl_new_std(&vsen->hdl, &vimc_sen_ctrl_ops,
-			  V4L2_CID_HUE, -128, 127, 1, 0);
-	v4l2_ctrl_new_std(&vsen->hdl, &vimc_sen_ctrl_ops,
-			  V4L2_CID_SATURATION, 0, 255, 1, 128);
-	vsen->sd.ctrl_handler = &vsen->hdl;
-	if (vsen->hdl.error) {
-		ret = vsen->hdl.error;
-		goto err_free_vsen;
-	}
-
-	/* Initialize the test pattern generator */
-	tpg_init(&vsen->tpg, vsen->mbus_format.width,
-		 vsen->mbus_format.height);
-	ret = tpg_alloc(&vsen->tpg, VIMC_FRAME_MAX_WIDTH);
-	if (ret)
-		goto err_free_hdl;
-
-	/* Initialize ved and sd */
-	vsen->pad.flags = MEDIA_PAD_FL_SOURCE;
-	ret = vimc_ent_sd_register(&vsen->ved, &vsen->sd, v4l2_dev,
-				   vcfg_name,
-				   MEDIA_ENT_F_CAM_SENSOR, 1, &vsen->pad,
-				   &vimc_sen_ops);
-	if (ret)
-		goto err_free_tpg;
-
-	vsen->ved.process_frame = vimc_sen_process_frame;
-	vsen->ved.dev = vimc->mdev.dev;
-
-	/* Initialize the frame format */
-	vsen->mbus_format = fmt_default;
-
-	return &vsen->ved;
-
-err_free_tpg:
-	tpg_free(&vsen->tpg);
-err_free_hdl:
-	v4l2_ctrl_handler_free(&vsen->hdl);
-err_free_vsen:
-	kfree(vsen);
-
-	return NULL;
-}
diff --git a/drivers/media/platform/vimc/vimc-streamer.c b/drivers/media/platform/vimc/vimc-streamer.c
deleted file mode 100644
index 65feb3c596db..000000000000
--- a/drivers/media/platform/vimc/vimc-streamer.c
+++ /dev/null
@@ -1,238 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * vimc-streamer.c Virtual Media Controller Driver
- *
- * Copyright (C) 2018 Lucas A. M. Magalhães <lucmaga@gmail.com>
- *
- */
-
-#include <linux/init.h>
-#include <linux/freezer.h>
-#include <linux/kthread.h>
-
-#include "vimc-streamer.h"
-
-/**
- * vimc_get_source_entity - get the entity connected with the first sink pad
- *
- * @ent:	reference media_entity
- *
- * Helper function that returns the media entity containing the source pad
- * linked with the first sink pad from the given media entity pad list.
- *
- * Return: The source pad or NULL, if it wasn't found.
- */
-static struct media_entity *vimc_get_source_entity(struct media_entity *ent)
-{
-	struct media_pad *pad;
-	int i;
-
-	for (i = 0; i < ent->num_pads; i++) {
-		if (ent->pads[i].flags & MEDIA_PAD_FL_SOURCE)
-			continue;
-		pad = media_entity_remote_pad(&ent->pads[i]);
-		return pad ? pad->entity : NULL;
-	}
-	return NULL;
-}
-
-/**
- * vimc_streamer_pipeline_terminate - Disable stream in all ved in stream
- *
- * @stream: the pointer to the stream structure with the pipeline to be
- *	    disabled.
- *
- * Calls s_stream to disable the stream in each entity of the pipeline
- *
- */
-static void vimc_streamer_pipeline_terminate(struct vimc_stream *stream)
-{
-	struct vimc_ent_device *ved;
-	struct v4l2_subdev *sd;
-
-	while (stream->pipe_size) {
-		stream->pipe_size--;
-		ved = stream->ved_pipeline[stream->pipe_size];
-		stream->ved_pipeline[stream->pipe_size] = NULL;
-
-		if (!is_media_entity_v4l2_subdev(ved->ent))
-			continue;
-
-		sd = media_entity_to_v4l2_subdev(ved->ent);
-		v4l2_subdev_call(sd, video, s_stream, 0);
-	}
-}
-
-/**
- * vimc_streamer_pipeline_init - Initializes the stream structure
- *
- * @stream: the pointer to the stream structure to be initialized
- * @ved:    the pointer to the vimc entity initializing the stream
- *
- * Initializes the stream structure. Walks through the entity graph to
- * construct the pipeline used later on the streamer thread.
- * Calls vimc_streamer_s_stream() to enable stream in all entities of
- * the pipeline.
- *
- * Return: 0 if success, error code otherwise.
- */
-static int vimc_streamer_pipeline_init(struct vimc_stream *stream,
-				       struct vimc_ent_device *ved)
-{
-	struct media_entity *entity;
-	struct video_device *vdev;
-	struct v4l2_subdev *sd;
-	int ret = 0;
-
-	stream->pipe_size = 0;
-	while (stream->pipe_size < VIMC_STREAMER_PIPELINE_MAX_SIZE) {
-		if (!ved) {
-			vimc_streamer_pipeline_terminate(stream);
-			return -EINVAL;
-		}
-		stream->ved_pipeline[stream->pipe_size++] = ved;
-
-		if (is_media_entity_v4l2_subdev(ved->ent)) {
-			sd = media_entity_to_v4l2_subdev(ved->ent);
-			ret = v4l2_subdev_call(sd, video, s_stream, 1);
-			if (ret && ret != -ENOIOCTLCMD) {
-				dev_err(ved->dev, "subdev_call error %s\n",
-					ved->ent->name);
-				vimc_streamer_pipeline_terminate(stream);
-				return ret;
-			}
-		}
-
-		entity = vimc_get_source_entity(ved->ent);
-		/* Check if the end of the pipeline was reached */
-		if (!entity) {
-			/* the first entity of the pipe should be source only */
-			if (!vimc_is_source(ved->ent)) {
-				dev_err(ved->dev,
-					"first entity in the pipe '%s' is not a source\n",
-					ved->ent->name);
-				vimc_streamer_pipeline_terminate(stream);
-				return -EPIPE;
-			}
-			return 0;
-		}
-
-		/* Get the next device in the pipeline */
-		if (is_media_entity_v4l2_subdev(entity)) {
-			sd = media_entity_to_v4l2_subdev(entity);
-			ved = v4l2_get_subdevdata(sd);
-		} else {
-			vdev = container_of(entity,
-					    struct video_device,
-					    entity);
-			ved = video_get_drvdata(vdev);
-		}
-	}
-
-	vimc_streamer_pipeline_terminate(stream);
-	return -EINVAL;
-}
-
-/**
- * vimc_streamer_thread - Process frames through the pipeline
- *
- * @data:	vimc_stream struct of the current stream
- *
- * From the source to the sink, gets a frame from each subdevice and send to
- * the next one of the pipeline at a fixed framerate.
- *
- * Return:
- * Always zero (created as ``int`` instead of ``void`` to comply with
- * kthread API).
- */
-static int vimc_streamer_thread(void *data)
-{
-	struct vimc_stream *stream = data;
-	u8 *frame = NULL;
-	int i;
-
-	set_freezable();
-
-	for (;;) {
-		try_to_freeze();
-		if (kthread_should_stop())
-			break;
-
-		for (i = stream->pipe_size - 1; i >= 0; i--) {
-			frame = stream->ved_pipeline[i]->process_frame(
-					stream->ved_pipeline[i], frame);
-			if (!frame || IS_ERR(frame))
-				break;
-		}
-		//wait for 60hz
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(HZ / 60);
-	}
-
-	return 0;
-}
-
-/**
- * vimc_streamer_s_stream - Start/stop the streaming on the media pipeline
- *
- * @stream:	the pointer to the stream structure of the current stream
- * @ved:	pointer to the vimc entity of the entity of the stream
- * @enable:	flag to determine if stream should start/stop
- *
- * When starting, check if there is no ``stream->kthread`` allocated. This
- * should indicate that a stream is already running. Then, it initializes the
- * pipeline, creates and runs a kthread to consume buffers through the pipeline.
- * When stopping, analogously check if there is a stream running, stop the
- * thread and terminates the pipeline.
- *
- * Return: 0 if success, error code otherwise.
- */
-int vimc_streamer_s_stream(struct vimc_stream *stream,
-			   struct vimc_ent_device *ved,
-			   int enable)
-{
-	int ret;
-
-	if (!stream || !ved)
-		return -EINVAL;
-
-	if (enable) {
-		if (stream->kthread)
-			return 0;
-
-		ret = vimc_streamer_pipeline_init(stream, ved);
-		if (ret)
-			return ret;
-
-		stream->kthread = kthread_run(vimc_streamer_thread, stream,
-					      "vimc-streamer thread");
-
-		if (IS_ERR(stream->kthread)) {
-			ret = PTR_ERR(stream->kthread);
-			dev_err(ved->dev, "kthread_run failed with %d\n", ret);
-			vimc_streamer_pipeline_terminate(stream);
-			stream->kthread = NULL;
-			return ret;
-		}
-
-	} else {
-		if (!stream->kthread)
-			return 0;
-
-		ret = kthread_stop(stream->kthread);
-		/*
-		 * kthread_stop returns -EINTR in cases when streamon was
-		 * immediately followed by streamoff, and the thread didn't had
-		 * a chance to run. Ignore errors to stop the stream in the
-		 * pipeline.
-		 */
-		if (ret)
-			dev_dbg(ved->dev, "kthread_stop returned '%d'\n", ret);
-
-		stream->kthread = NULL;
-
-		vimc_streamer_pipeline_terminate(stream);
-	}
-
-	return 0;
-}
diff --git a/drivers/media/platform/vimc/vimc-streamer.h b/drivers/media/platform/vimc/vimc-streamer.h
deleted file mode 100644
index fe3c51f15fad..000000000000
--- a/drivers/media/platform/vimc/vimc-streamer.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * vimc-streamer.h Virtual Media Controller Driver
- *
- * Copyright (C) 2018 Lucas A. M. Magalhães <lucmaga@gmail.com>
- *
- */
-
-#ifndef _VIMC_STREAMER_H_
-#define _VIMC_STREAMER_H_
-
-#include <media/media-device.h>
-
-#include "vimc-common.h"
-
-#define VIMC_STREAMER_PIPELINE_MAX_SIZE 16
-
-/**
- * struct vimc_stream - struct that represents a stream in the pipeline
- *
- * @pipe:		the media pipeline object associated with this stream
- * @ved_pipeline:	array containing all the entities participating in the
- * stream. The order is from a video device (usually a capture device) where
- * stream_on was called, to the entity generating the first base image to be
- * processed in the pipeline.
- * @pipe_size:		size of @ved_pipeline
- * @kthread:		thread that generates the frames of the stream.
- *
- * When the user call stream_on in a video device, struct vimc_stream is
- * used to keep track of all entities and subdevices that generates and
- * process frames for the stream.
- */
-struct vimc_stream {
-	struct media_pipeline pipe;
-	struct vimc_ent_device *ved_pipeline[VIMC_STREAMER_PIPELINE_MAX_SIZE];
-	unsigned int pipe_size;
-	struct task_struct *kthread;
-};
-
-int vimc_streamer_s_stream(struct vimc_stream *stream,
-			   struct vimc_ent_device *ved,
-			   int enable);
-
-#endif  //_VIMC_STREAMER_H_
diff --git a/drivers/media/platform/vivid/Kconfig b/drivers/media/platform/vivid/Kconfig
deleted file mode 100644
index e2ff06edfa93..000000000000
--- a/drivers/media/platform/vivid/Kconfig
+++ /dev/null
@@ -1,41 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-config VIDEO_VIVID
-	tristate "Virtual Video Test Driver"
-	depends on VIDEO_DEV && VIDEO_V4L2 && !SPARC32 && !SPARC64 && FB
-	depends on HAS_DMA
-	select FONT_SUPPORT
-	select FONT_8x16
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	select VIDEOBUF2_VMALLOC
-	select VIDEOBUF2_DMA_CONTIG
-	select VIDEO_V4L2_TPG
-	help
-	  Enables a virtual video driver. This driver emulates a webcam,
-	  TV, S-Video and HDMI capture hardware, including VBI support for
-	  the SDTV inputs. Also video output, VBI output, radio receivers,
-	  transmitters and software defined radio capture is emulated.
-
-	  It is highly configurable and is ideal for testing applications.
-	  Error injection is supported to test rare errors that are hard
-	  to reproduce in real hardware.
-
-	  Say Y here if you want to test video apps or debug V4L devices.
-	  When in doubt, say N.
-
-config VIDEO_VIVID_CEC
-	bool "Enable CEC emulation support"
-	depends on VIDEO_VIVID
-	select CEC_CORE
-	help
-	  When selected the vivid module will emulate the optional
-	  HDMI CEC feature.
-
-config VIDEO_VIVID_MAX_DEVS
-	int "Maximum number of devices"
-	depends on VIDEO_VIVID
-	default "64"
-	help
-	  This allows you to specify the maximum number of devices supported
-	  by the vivid driver.
diff --git a/drivers/media/platform/vivid/Makefile b/drivers/media/platform/vivid/Makefile
deleted file mode 100644
index b12ad0152a3e..000000000000
--- a/drivers/media/platform/vivid/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-vivid-objs := vivid-core.o vivid-ctrls.o vivid-vid-common.o vivid-vbi-gen.o \
-		vivid-vid-cap.o vivid-vid-out.o vivid-kthread-cap.o vivid-kthread-out.o \
-		vivid-radio-rx.o vivid-radio-tx.o vivid-radio-common.o \
-		vivid-rds-gen.o vivid-sdr-cap.o vivid-vbi-cap.o vivid-vbi-out.o \
-		vivid-osd.o vivid-meta-cap.o vivid-meta-out.o \
-		vivid-kthread-touch.o vivid-touch-cap.o
-ifeq ($(CONFIG_VIDEO_VIVID_CEC),y)
-  vivid-objs += vivid-cec.o
-endif
-
-obj-$(CONFIG_VIDEO_VIVID) += vivid.o
diff --git a/drivers/media/platform/vivid/vivid-cec.c b/drivers/media/platform/vivid/vivid-cec.c
deleted file mode 100644
index 4d2413e87730..000000000000
--- a/drivers/media/platform/vivid/vivid-cec.c
+++ /dev/null
@@ -1,286 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * vivid-cec.c - A Virtual Video Test Driver, cec emulation
- *
- * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#include <media/cec.h>
-
-#include "vivid-core.h"
-#include "vivid-cec.h"
-
-#define CEC_TIM_START_BIT_TOTAL		4500
-#define CEC_TIM_START_BIT_LOW		3700
-#define CEC_TIM_START_BIT_HIGH		800
-#define CEC_TIM_DATA_BIT_TOTAL		2400
-#define CEC_TIM_DATA_BIT_0_LOW		1500
-#define CEC_TIM_DATA_BIT_0_HIGH		900
-#define CEC_TIM_DATA_BIT_1_LOW		600
-#define CEC_TIM_DATA_BIT_1_HIGH		1800
-
-void vivid_cec_bus_free_work(struct vivid_dev *dev)
-{
-	spin_lock(&dev->cec_slock);
-	while (!list_empty(&dev->cec_work_list)) {
-		struct vivid_cec_work *cw =
-			list_first_entry(&dev->cec_work_list,
-					 struct vivid_cec_work, list);
-
-		spin_unlock(&dev->cec_slock);
-		cancel_delayed_work_sync(&cw->work);
-		spin_lock(&dev->cec_slock);
-		list_del(&cw->list);
-		cec_transmit_attempt_done(cw->adap, CEC_TX_STATUS_LOW_DRIVE);
-		kfree(cw);
-	}
-	spin_unlock(&dev->cec_slock);
-}
-
-static bool vivid_cec_find_dest_adap(struct vivid_dev *dev,
-				     struct cec_adapter *adap, u8 dest)
-{
-	unsigned int i;
-
-	if (dest >= 0xf)
-		return false;
-
-	if (adap != dev->cec_rx_adap && dev->cec_rx_adap &&
-	    dev->cec_rx_adap->is_configured &&
-	    cec_has_log_addr(dev->cec_rx_adap, dest))
-		return true;
-
-	for (i = 0; i < MAX_OUTPUTS && dev->cec_tx_adap[i]; i++) {
-		if (adap == dev->cec_tx_adap[i])
-			continue;
-		if (!dev->cec_tx_adap[i]->is_configured)
-			continue;
-		if (cec_has_log_addr(dev->cec_tx_adap[i], dest))
-			return true;
-	}
-	return false;
-}
-
-static void vivid_cec_pin_adap_events(struct cec_adapter *adap, ktime_t ts,
-				      const struct cec_msg *msg, bool nacked)
-{
-	unsigned int len = nacked ? 1 : msg->len;
-	unsigned int i;
-	bool bit;
-
-	if (adap == NULL)
-		return;
-
-	/*
-	 * Suffix ULL on constant 10 makes the expression
-	 * CEC_TIM_START_BIT_TOTAL + 10ULL * len * CEC_TIM_DATA_BIT_TOTAL
-	 * to be evaluated using 64-bit unsigned arithmetic (u64), which
-	 * is what ktime_sub_us expects as second argument.
-	 */
-	ts = ktime_sub_us(ts, CEC_TIM_START_BIT_TOTAL +
-			       10ULL * len * CEC_TIM_DATA_BIT_TOTAL);
-	cec_queue_pin_cec_event(adap, false, false, ts);
-	ts = ktime_add_us(ts, CEC_TIM_START_BIT_LOW);
-	cec_queue_pin_cec_event(adap, true, false, ts);
-	ts = ktime_add_us(ts, CEC_TIM_START_BIT_HIGH);
-
-	for (i = 0; i < 10 * len; i++) {
-		switch (i % 10) {
-		case 0 ... 7:
-			bit = msg->msg[i / 10] & (0x80 >> (i % 10));
-			break;
-		case 8: /* EOM */
-			bit = i / 10 == msg->len - 1;
-			break;
-		case 9: /* ACK */
-			bit = cec_msg_is_broadcast(msg) ^ nacked;
-			break;
-		}
-		cec_queue_pin_cec_event(adap, false, false, ts);
-		if (bit)
-			ts = ktime_add_us(ts, CEC_TIM_DATA_BIT_1_LOW);
-		else
-			ts = ktime_add_us(ts, CEC_TIM_DATA_BIT_0_LOW);
-		cec_queue_pin_cec_event(adap, true, false, ts);
-		if (bit)
-			ts = ktime_add_us(ts, CEC_TIM_DATA_BIT_1_HIGH);
-		else
-			ts = ktime_add_us(ts, CEC_TIM_DATA_BIT_0_HIGH);
-	}
-}
-
-static void vivid_cec_pin_events(struct vivid_dev *dev,
-				 const struct cec_msg *msg, bool nacked)
-{
-	ktime_t ts = ktime_get();
-	unsigned int i;
-
-	vivid_cec_pin_adap_events(dev->cec_rx_adap, ts, msg, nacked);
-	for (i = 0; i < MAX_OUTPUTS; i++)
-		vivid_cec_pin_adap_events(dev->cec_tx_adap[i], ts, msg, nacked);
-}
-
-static void vivid_cec_xfer_done_worker(struct work_struct *work)
-{
-	struct vivid_cec_work *cw =
-		container_of(work, struct vivid_cec_work, work.work);
-	struct vivid_dev *dev = cw->dev;
-	struct cec_adapter *adap = cw->adap;
-	u8 dest = cec_msg_destination(&cw->msg);
-	bool valid_dest;
-	unsigned int i;
-
-	valid_dest = cec_msg_is_broadcast(&cw->msg);
-	if (!valid_dest)
-		valid_dest = vivid_cec_find_dest_adap(dev, adap, dest);
-
-	cw->tx_status = valid_dest ? CEC_TX_STATUS_OK : CEC_TX_STATUS_NACK;
-	spin_lock(&dev->cec_slock);
-	dev->cec_xfer_time_jiffies = 0;
-	dev->cec_xfer_start_jiffies = 0;
-	list_del(&cw->list);
-	spin_unlock(&dev->cec_slock);
-	vivid_cec_pin_events(dev, &cw->msg, !valid_dest);
-	cec_transmit_attempt_done(cw->adap, cw->tx_status);
-
-	/* Broadcast message */
-	if (adap != dev->cec_rx_adap)
-		cec_received_msg(dev->cec_rx_adap, &cw->msg);
-	for (i = 0; i < MAX_OUTPUTS && dev->cec_tx_adap[i]; i++)
-		if (adap != dev->cec_tx_adap[i])
-			cec_received_msg(dev->cec_tx_adap[i], &cw->msg);
-	kfree(cw);
-}
-
-static void vivid_cec_xfer_try_worker(struct work_struct *work)
-{
-	struct vivid_cec_work *cw =
-		container_of(work, struct vivid_cec_work, work.work);
-	struct vivid_dev *dev = cw->dev;
-
-	spin_lock(&dev->cec_slock);
-	if (dev->cec_xfer_time_jiffies) {
-		list_del(&cw->list);
-		spin_unlock(&dev->cec_slock);
-		cec_transmit_attempt_done(cw->adap, CEC_TX_STATUS_ARB_LOST);
-		kfree(cw);
-	} else {
-		INIT_DELAYED_WORK(&cw->work, vivid_cec_xfer_done_worker);
-		dev->cec_xfer_start_jiffies = jiffies;
-		dev->cec_xfer_time_jiffies = usecs_to_jiffies(cw->usecs);
-		spin_unlock(&dev->cec_slock);
-		schedule_delayed_work(&cw->work, dev->cec_xfer_time_jiffies);
-	}
-}
-
-static int vivid_cec_adap_enable(struct cec_adapter *adap, bool enable)
-{
-	adap->cec_pin_is_high = true;
-	return 0;
-}
-
-static int vivid_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr)
-{
-	return 0;
-}
-
-/*
- * One data bit takes 2400 us, each byte needs 10 bits so that's 24000 us
- * per byte.
- */
-#define USECS_PER_BYTE 24000
-
-static int vivid_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
-				   u32 signal_free_time, struct cec_msg *msg)
-{
-	struct vivid_dev *dev = cec_get_drvdata(adap);
-	struct vivid_cec_work *cw = kzalloc(sizeof(*cw), GFP_KERNEL);
-	long delta_jiffies = 0;
-
-	if (cw == NULL)
-		return -ENOMEM;
-	cw->dev = dev;
-	cw->adap = adap;
-	cw->usecs = CEC_FREE_TIME_TO_USEC(signal_free_time) +
-		    msg->len * USECS_PER_BYTE;
-	cw->msg = *msg;
-
-	spin_lock(&dev->cec_slock);
-	list_add(&cw->list, &dev->cec_work_list);
-	if (dev->cec_xfer_time_jiffies == 0) {
-		INIT_DELAYED_WORK(&cw->work, vivid_cec_xfer_done_worker);
-		dev->cec_xfer_start_jiffies = jiffies;
-		dev->cec_xfer_time_jiffies = usecs_to_jiffies(cw->usecs);
-		delta_jiffies = dev->cec_xfer_time_jiffies;
-	} else {
-		INIT_DELAYED_WORK(&cw->work, vivid_cec_xfer_try_worker);
-		delta_jiffies = dev->cec_xfer_start_jiffies +
-			dev->cec_xfer_time_jiffies - jiffies;
-	}
-	spin_unlock(&dev->cec_slock);
-	schedule_delayed_work(&cw->work, delta_jiffies < 0 ? 0 : delta_jiffies);
-	return 0;
-}
-
-static int vivid_received(struct cec_adapter *adap, struct cec_msg *msg)
-{
-	struct vivid_dev *dev = cec_get_drvdata(adap);
-	struct cec_msg reply;
-	u8 dest = cec_msg_destination(msg);
-	u8 disp_ctl;
-	char osd[14];
-
-	if (cec_msg_is_broadcast(msg))
-		dest = adap->log_addrs.log_addr[0];
-	cec_msg_init(&reply, dest, cec_msg_initiator(msg));
-
-	switch (cec_msg_opcode(msg)) {
-	case CEC_MSG_SET_OSD_STRING:
-		if (!cec_is_sink(adap))
-			return -ENOMSG;
-		cec_ops_set_osd_string(msg, &disp_ctl, osd);
-		switch (disp_ctl) {
-		case CEC_OP_DISP_CTL_DEFAULT:
-			strscpy(dev->osd, osd, sizeof(dev->osd));
-			dev->osd_jiffies = jiffies;
-			break;
-		case CEC_OP_DISP_CTL_UNTIL_CLEARED:
-			strscpy(dev->osd, osd, sizeof(dev->osd));
-			dev->osd_jiffies = 0;
-			break;
-		case CEC_OP_DISP_CTL_CLEAR:
-			dev->osd[0] = 0;
-			dev->osd_jiffies = 0;
-			break;
-		default:
-			cec_msg_feature_abort(&reply, cec_msg_opcode(msg),
-					      CEC_OP_ABORT_INVALID_OP);
-			cec_transmit_msg(adap, &reply, false);
-			break;
-		}
-		break;
-	default:
-		return -ENOMSG;
-	}
-	return 0;
-}
-
-static const struct cec_adap_ops vivid_cec_adap_ops = {
-	.adap_enable = vivid_cec_adap_enable,
-	.adap_log_addr = vivid_cec_adap_log_addr,
-	.adap_transmit = vivid_cec_adap_transmit,
-	.received = vivid_received,
-};
-
-struct cec_adapter *vivid_cec_alloc_adap(struct vivid_dev *dev,
-					 unsigned int idx,
-					 bool is_source)
-{
-	u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_MONITOR_ALL | CEC_CAP_MONITOR_PIN;
-	char name[32];
-
-	snprintf(name, sizeof(name), "vivid-%03d-vid-%s%d",
-		 dev->inst, is_source ? "out" : "cap", idx);
-	return cec_allocate_adapter(&vivid_cec_adap_ops, dev,
-		name, caps, 1);
-}
diff --git a/drivers/media/platform/vivid/vivid-cec.h b/drivers/media/platform/vivid/vivid-cec.h
deleted file mode 100644
index 7524ed48a914..000000000000
--- a/drivers/media/platform/vivid/vivid-cec.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * vivid-cec.h - A Virtual Video Test Driver, cec emulation
- *
- * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#ifdef CONFIG_VIDEO_VIVID_CEC
-struct cec_adapter *vivid_cec_alloc_adap(struct vivid_dev *dev,
-					 unsigned int idx,
-					 bool is_source);
-void vivid_cec_bus_free_work(struct vivid_dev *dev);
-
-#else
-
-static inline void vivid_cec_bus_free_work(struct vivid_dev *dev)
-{
-}
-
-#endif
diff --git a/drivers/media/platform/vivid/vivid-core.c b/drivers/media/platform/vivid/vivid-core.c
deleted file mode 100644
index 6c740e3e6999..000000000000
--- a/drivers/media/platform/vivid/vivid-core.c
+++ /dev/null
@@ -1,2006 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * vivid-core.c - A Virtual Video Test Driver, core initialization
- *
- * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/font.h>
-#include <linux/mutex.h>
-#include <linux/platform_device.h>
-#include <linux/videodev2.h>
-#include <linux/v4l2-dv-timings.h>
-#include <media/videobuf2-vmalloc.h>
-#include <media/videobuf2-dma-contig.h>
-#include <media/v4l2-dv-timings.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-fh.h>
-#include <media/v4l2-event.h>
-
-#include "vivid-core.h"
-#include "vivid-vid-common.h"
-#include "vivid-vid-cap.h"
-#include "vivid-vid-out.h"
-#include "vivid-radio-common.h"
-#include "vivid-radio-rx.h"
-#include "vivid-radio-tx.h"
-#include "vivid-sdr-cap.h"
-#include "vivid-vbi-cap.h"
-#include "vivid-vbi-out.h"
-#include "vivid-osd.h"
-#include "vivid-cec.h"
-#include "vivid-ctrls.h"
-#include "vivid-meta-cap.h"
-#include "vivid-meta-out.h"
-#include "vivid-touch-cap.h"
-
-#define VIVID_MODULE_NAME "vivid"
-
-/* The maximum number of vivid devices */
-#define VIVID_MAX_DEVS CONFIG_VIDEO_VIVID_MAX_DEVS
-
-MODULE_DESCRIPTION("Virtual Video Test Driver");
-MODULE_AUTHOR("Hans Verkuil");
-MODULE_LICENSE("GPL");
-
-static unsigned n_devs = 1;
-module_param(n_devs, uint, 0444);
-MODULE_PARM_DESC(n_devs, " number of driver instances to create");
-
-static int vid_cap_nr[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = -1 };
-module_param_array(vid_cap_nr, int, NULL, 0444);
-MODULE_PARM_DESC(vid_cap_nr, " videoX start number, -1 is autodetect");
-
-static int vid_out_nr[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = -1 };
-module_param_array(vid_out_nr, int, NULL, 0444);
-MODULE_PARM_DESC(vid_out_nr, " videoX start number, -1 is autodetect");
-
-static int vbi_cap_nr[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = -1 };
-module_param_array(vbi_cap_nr, int, NULL, 0444);
-MODULE_PARM_DESC(vbi_cap_nr, " vbiX start number, -1 is autodetect");
-
-static int vbi_out_nr[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = -1 };
-module_param_array(vbi_out_nr, int, NULL, 0444);
-MODULE_PARM_DESC(vbi_out_nr, " vbiX start number, -1 is autodetect");
-
-static int sdr_cap_nr[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = -1 };
-module_param_array(sdr_cap_nr, int, NULL, 0444);
-MODULE_PARM_DESC(sdr_cap_nr, " swradioX start number, -1 is autodetect");
-
-static int radio_rx_nr[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = -1 };
-module_param_array(radio_rx_nr, int, NULL, 0444);
-MODULE_PARM_DESC(radio_rx_nr, " radioX start number, -1 is autodetect");
-
-static int radio_tx_nr[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = -1 };
-module_param_array(radio_tx_nr, int, NULL, 0444);
-MODULE_PARM_DESC(radio_tx_nr, " radioX start number, -1 is autodetect");
-
-static int meta_cap_nr[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = -1 };
-module_param_array(meta_cap_nr, int, NULL, 0444);
-MODULE_PARM_DESC(meta_cap_nr, " videoX start number, -1 is autodetect");
-
-static int meta_out_nr[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = -1 };
-module_param_array(meta_out_nr, int, NULL, 0444);
-MODULE_PARM_DESC(meta_out_nr, " videoX start number, -1 is autodetect");
-
-static int touch_cap_nr[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = -1 };
-module_param_array(touch_cap_nr, int, NULL, 0444);
-MODULE_PARM_DESC(touch_cap_nr, " v4l-touchX start number, -1 is autodetect");
-
-static int ccs_cap_mode[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = -1 };
-module_param_array(ccs_cap_mode, int, NULL, 0444);
-MODULE_PARM_DESC(ccs_cap_mode, " capture crop/compose/scale mode:\n"
-			   "\t\t    bit 0=crop, 1=compose, 2=scale,\n"
-			   "\t\t    -1=user-controlled (default)");
-
-static int ccs_out_mode[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = -1 };
-module_param_array(ccs_out_mode, int, NULL, 0444);
-MODULE_PARM_DESC(ccs_out_mode, " output crop/compose/scale mode:\n"
-			   "\t\t    bit 0=crop, 1=compose, 2=scale,\n"
-			   "\t\t    -1=user-controlled (default)");
-
-static unsigned multiplanar[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = 1 };
-module_param_array(multiplanar, uint, NULL, 0444);
-MODULE_PARM_DESC(multiplanar, " 1 (default) creates a single planar device, 2 creates a multiplanar device.");
-
-/*
- * Default: video + vbi-cap (raw and sliced) + radio rx + radio tx + sdr +
- * vbi-out + vid-out + meta-cap
- */
-static unsigned int node_types[VIVID_MAX_DEVS] = {
-	[0 ... (VIVID_MAX_DEVS - 1)] = 0xe1d3d
-};
-module_param_array(node_types, uint, NULL, 0444);
-MODULE_PARM_DESC(node_types, " node types, default is 0xe1d3d. Bitmask with the following meaning:\n"
-			     "\t\t    bit 0: Video Capture node\n"
-			     "\t\t    bit 2-3: VBI Capture node: 0 = none, 1 = raw vbi, 2 = sliced vbi, 3 = both\n"
-			     "\t\t    bit 4: Radio Receiver node\n"
-			     "\t\t    bit 5: Software Defined Radio Receiver node\n"
-			     "\t\t    bit 8: Video Output node\n"
-			     "\t\t    bit 10-11: VBI Output node: 0 = none, 1 = raw vbi, 2 = sliced vbi, 3 = both\n"
-			     "\t\t    bit 12: Radio Transmitter node\n"
-			     "\t\t    bit 16: Framebuffer for testing overlays\n"
-			     "\t\t    bit 17: Metadata Capture node\n"
-			     "\t\t    bit 18: Metadata Output node\n"
-			     "\t\t    bit 19: Touch Capture node\n");
-
-/* Default: 4 inputs */
-static unsigned num_inputs[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = 4 };
-module_param_array(num_inputs, uint, NULL, 0444);
-MODULE_PARM_DESC(num_inputs, " number of inputs, default is 4");
-
-/* Default: input 0 = WEBCAM, 1 = TV, 2 = SVID, 3 = HDMI */
-static unsigned input_types[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = 0xe4 };
-module_param_array(input_types, uint, NULL, 0444);
-MODULE_PARM_DESC(input_types, " input types, default is 0xe4. Two bits per input,\n"
-			      "\t\t    bits 0-1 == input 0, bits 31-30 == input 15.\n"
-			      "\t\t    Type 0 == webcam, 1 == TV, 2 == S-Video, 3 == HDMI");
-
-/* Default: 2 outputs */
-static unsigned num_outputs[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = 2 };
-module_param_array(num_outputs, uint, NULL, 0444);
-MODULE_PARM_DESC(num_outputs, " number of outputs, default is 2");
-
-/* Default: output 0 = SVID, 1 = HDMI */
-static unsigned output_types[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = 2 };
-module_param_array(output_types, uint, NULL, 0444);
-MODULE_PARM_DESC(output_types, " output types, default is 0x02. One bit per output,\n"
-			      "\t\t    bit 0 == output 0, bit 15 == output 15.\n"
-			      "\t\t    Type 0 == S-Video, 1 == HDMI");
-
-unsigned vivid_debug;
-module_param(vivid_debug, uint, 0644);
-MODULE_PARM_DESC(vivid_debug, " activates debug info");
-
-static bool no_error_inj;
-module_param(no_error_inj, bool, 0444);
-MODULE_PARM_DESC(no_error_inj, " if set disable the error injecting controls");
-
-static unsigned int allocators[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = 0 };
-module_param_array(allocators, uint, NULL, 0444);
-MODULE_PARM_DESC(allocators, " memory allocator selection, default is 0.\n"
-			     "\t\t    0 == vmalloc\n"
-			     "\t\t    1 == dma-contig");
-
-static struct vivid_dev *vivid_devs[VIVID_MAX_DEVS];
-
-const struct v4l2_rect vivid_min_rect = {
-	0, 0, MIN_WIDTH, MIN_HEIGHT
-};
-
-const struct v4l2_rect vivid_max_rect = {
-	0, 0, MAX_WIDTH * MAX_ZOOM, MAX_HEIGHT * MAX_ZOOM
-};
-
-static const u8 vivid_hdmi_edid[256] = {
-	0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
-	0x31, 0xd8, 0x34, 0x12, 0x00, 0x00, 0x00, 0x00,
-	0x22, 0x1a, 0x01, 0x03, 0x80, 0x60, 0x36, 0x78,
-	0x0f, 0xee, 0x91, 0xa3, 0x54, 0x4c, 0x99, 0x26,
-	0x0f, 0x50, 0x54, 0x2f, 0xcf, 0x00, 0x31, 0x59,
-	0x45, 0x59, 0x81, 0x80, 0x81, 0x40, 0x90, 0x40,
-	0x95, 0x00, 0xa9, 0x40, 0xb3, 0x00, 0x08, 0xe8,
-	0x00, 0x30, 0xf2, 0x70, 0x5a, 0x80, 0xb0, 0x58,
-	0x8a, 0x00, 0xc0, 0x1c, 0x32, 0x00, 0x00, 0x1e,
-	0x00, 0x00, 0x00, 0xfd, 0x00, 0x18, 0x55, 0x18,
-	0x87, 0x3c, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20,
-	0x20, 0x20, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x76,
-	0x69, 0x76, 0x69, 0x64, 0x0a, 0x20, 0x20, 0x20,
-	0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x10,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x7b,
-
-	0x02, 0x03, 0x3f, 0xf0, 0x51, 0x61, 0x60, 0x5f,
-	0x5e, 0x5d, 0x10, 0x1f, 0x04, 0x13, 0x22, 0x21,
-	0x20, 0x05, 0x14, 0x02, 0x11, 0x01, 0x23, 0x09,
-	0x07, 0x07, 0x83, 0x01, 0x00, 0x00, 0x6d, 0x03,
-	0x0c, 0x00, 0x10, 0x00, 0x00, 0x3c, 0x21, 0x00,
-	0x60, 0x01, 0x02, 0x03, 0x67, 0xd8, 0x5d, 0xc4,
-	0x01, 0x78, 0x00, 0x00, 0xe2, 0x00, 0xea, 0xe3,
-	0x05, 0x00, 0x00, 0xe3, 0x06, 0x01, 0x00, 0x4d,
-	0xd0, 0x00, 0xa0, 0xf0, 0x70, 0x3e, 0x80, 0x30,
-	0x20, 0x35, 0x00, 0xc0, 0x1c, 0x32, 0x00, 0x00,
-	0x1e, 0x1a, 0x36, 0x80, 0xa0, 0x70, 0x38, 0x1f,
-	0x40, 0x30, 0x20, 0x35, 0x00, 0xc0, 0x1c, 0x32,
-	0x00, 0x00, 0x1a, 0x1a, 0x1d, 0x00, 0x80, 0x51,
-	0xd0, 0x1c, 0x20, 0x40, 0x80, 0x35, 0x00, 0xc0,
-	0x1c, 0x32, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63,
-};
-
-static int vidioc_querycap(struct file *file, void  *priv,
-					struct v4l2_capability *cap)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	strscpy(cap->driver, "vivid", sizeof(cap->driver));
-	strscpy(cap->card, "vivid", sizeof(cap->card));
-	snprintf(cap->bus_info, sizeof(cap->bus_info),
-			"platform:%s", dev->v4l2_dev.name);
-
-	cap->capabilities = dev->vid_cap_caps | dev->vid_out_caps |
-		dev->vbi_cap_caps | dev->vbi_out_caps |
-		dev->radio_rx_caps | dev->radio_tx_caps |
-		dev->sdr_cap_caps | dev->meta_cap_caps |
-		dev->meta_out_caps | dev->touch_cap_caps |
-		V4L2_CAP_DEVICE_CAPS;
-	return 0;
-}
-
-static int vidioc_s_hw_freq_seek(struct file *file, void *fh, const struct v4l2_hw_freq_seek *a)
-{
-	struct video_device *vdev = video_devdata(file);
-
-	if (vdev->vfl_type == VFL_TYPE_RADIO)
-		return vivid_radio_rx_s_hw_freq_seek(file, fh, a);
-	return -ENOTTY;
-}
-
-static int vidioc_enum_freq_bands(struct file *file, void *fh, struct v4l2_frequency_band *band)
-{
-	struct video_device *vdev = video_devdata(file);
-
-	if (vdev->vfl_type == VFL_TYPE_RADIO)
-		return vivid_radio_rx_enum_freq_bands(file, fh, band);
-	if (vdev->vfl_type == VFL_TYPE_SDR)
-		return vivid_sdr_enum_freq_bands(file, fh, band);
-	return -ENOTTY;
-}
-
-static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
-{
-	struct video_device *vdev = video_devdata(file);
-
-	if (vdev->vfl_type == VFL_TYPE_RADIO)
-		return vivid_radio_rx_g_tuner(file, fh, vt);
-	if (vdev->vfl_type == VFL_TYPE_SDR)
-		return vivid_sdr_g_tuner(file, fh, vt);
-	return vivid_video_g_tuner(file, fh, vt);
-}
-
-static int vidioc_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt)
-{
-	struct video_device *vdev = video_devdata(file);
-
-	if (vdev->vfl_type == VFL_TYPE_RADIO)
-		return vivid_radio_rx_s_tuner(file, fh, vt);
-	if (vdev->vfl_type == VFL_TYPE_SDR)
-		return vivid_sdr_s_tuner(file, fh, vt);
-	return vivid_video_s_tuner(file, fh, vt);
-}
-
-static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	struct video_device *vdev = video_devdata(file);
-
-	if (vdev->vfl_type == VFL_TYPE_RADIO)
-		return vivid_radio_g_frequency(file,
-			vdev->vfl_dir == VFL_DIR_RX ?
-			&dev->radio_rx_freq : &dev->radio_tx_freq, vf);
-	if (vdev->vfl_type == VFL_TYPE_SDR)
-		return vivid_sdr_g_frequency(file, fh, vf);
-	return vivid_video_g_frequency(file, fh, vf);
-}
-
-static int vidioc_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *vf)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	struct video_device *vdev = video_devdata(file);
-
-	if (vdev->vfl_type == VFL_TYPE_RADIO)
-		return vivid_radio_s_frequency(file,
-			vdev->vfl_dir == VFL_DIR_RX ?
-			&dev->radio_rx_freq : &dev->radio_tx_freq, vf);
-	if (vdev->vfl_type == VFL_TYPE_SDR)
-		return vivid_sdr_s_frequency(file, fh, vf);
-	return vivid_video_s_frequency(file, fh, vf);
-}
-
-static int vidioc_overlay(struct file *file, void *fh, unsigned i)
-{
-	struct video_device *vdev = video_devdata(file);
-
-	if (vdev->vfl_dir == VFL_DIR_RX)
-		return vivid_vid_cap_overlay(file, fh, i);
-	return vivid_vid_out_overlay(file, fh, i);
-}
-
-static int vidioc_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *a)
-{
-	struct video_device *vdev = video_devdata(file);
-
-	if (vdev->vfl_dir == VFL_DIR_RX)
-		return vivid_vid_cap_g_fbuf(file, fh, a);
-	return vivid_vid_out_g_fbuf(file, fh, a);
-}
-
-static int vidioc_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffer *a)
-{
-	struct video_device *vdev = video_devdata(file);
-
-	if (vdev->vfl_dir == VFL_DIR_RX)
-		return vivid_vid_cap_s_fbuf(file, fh, a);
-	return vivid_vid_out_s_fbuf(file, fh, a);
-}
-
-static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id id)
-{
-	struct video_device *vdev = video_devdata(file);
-
-	if (vdev->vfl_dir == VFL_DIR_RX)
-		return vivid_vid_cap_s_std(file, fh, id);
-	return vivid_vid_out_s_std(file, fh, id);
-}
-
-static int vidioc_s_dv_timings(struct file *file, void *fh, struct v4l2_dv_timings *timings)
-{
-	struct video_device *vdev = video_devdata(file);
-
-	if (vdev->vfl_dir == VFL_DIR_RX)
-		return vivid_vid_cap_s_dv_timings(file, fh, timings);
-	return vivid_vid_out_s_dv_timings(file, fh, timings);
-}
-
-static int vidioc_g_pixelaspect(struct file *file, void *fh,
-				int type, struct v4l2_fract *f)
-{
-	struct video_device *vdev = video_devdata(file);
-
-	if (vdev->vfl_dir == VFL_DIR_RX)
-		return vivid_vid_cap_g_pixelaspect(file, fh, type, f);
-	return vivid_vid_out_g_pixelaspect(file, fh, type, f);
-}
-
-static int vidioc_g_selection(struct file *file, void *fh,
-			      struct v4l2_selection *sel)
-{
-	struct video_device *vdev = video_devdata(file);
-
-	if (vdev->vfl_dir == VFL_DIR_RX)
-		return vivid_vid_cap_g_selection(file, fh, sel);
-	return vivid_vid_out_g_selection(file, fh, sel);
-}
-
-static int vidioc_s_selection(struct file *file, void *fh,
-			      struct v4l2_selection *sel)
-{
-	struct video_device *vdev = video_devdata(file);
-
-	if (vdev->vfl_dir == VFL_DIR_RX)
-		return vivid_vid_cap_s_selection(file, fh, sel);
-	return vivid_vid_out_s_selection(file, fh, sel);
-}
-
-static int vidioc_g_parm(struct file *file, void *fh,
-			  struct v4l2_streamparm *parm)
-{
-	struct video_device *vdev = video_devdata(file);
-
-	if (vdev->vfl_type == VFL_TYPE_TOUCH)
-		return vivid_g_parm_tch(file, fh, parm);
-	if (vdev->vfl_dir == VFL_DIR_RX)
-		return vivid_vid_cap_g_parm(file, fh, parm);
-	return vivid_vid_out_g_parm(file, fh, parm);
-}
-
-static int vidioc_s_parm(struct file *file, void *fh,
-			  struct v4l2_streamparm *parm)
-{
-	struct video_device *vdev = video_devdata(file);
-
-	if (vdev->vfl_dir == VFL_DIR_RX)
-		return vivid_vid_cap_s_parm(file, fh, parm);
-	return -ENOTTY;
-}
-
-static int vidioc_log_status(struct file *file, void *fh)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	struct video_device *vdev = video_devdata(file);
-
-	v4l2_ctrl_log_status(file, fh);
-	if (vdev->vfl_dir == VFL_DIR_RX && vdev->vfl_type == VFL_TYPE_VIDEO)
-		tpg_log_status(&dev->tpg);
-	return 0;
-}
-
-static ssize_t vivid_radio_read(struct file *file, char __user *buf,
-			 size_t size, loff_t *offset)
-{
-	struct video_device *vdev = video_devdata(file);
-
-	if (vdev->vfl_dir == VFL_DIR_TX)
-		return -EINVAL;
-	return vivid_radio_rx_read(file, buf, size, offset);
-}
-
-static ssize_t vivid_radio_write(struct file *file, const char __user *buf,
-			  size_t size, loff_t *offset)
-{
-	struct video_device *vdev = video_devdata(file);
-
-	if (vdev->vfl_dir == VFL_DIR_RX)
-		return -EINVAL;
-	return vivid_radio_tx_write(file, buf, size, offset);
-}
-
-static __poll_t vivid_radio_poll(struct file *file, struct poll_table_struct *wait)
-{
-	struct video_device *vdev = video_devdata(file);
-
-	if (vdev->vfl_dir == VFL_DIR_RX)
-		return vivid_radio_rx_poll(file, wait);
-	return vivid_radio_tx_poll(file, wait);
-}
-
-static int vivid_enum_input(struct file *file, void *priv,
-			    struct v4l2_input *inp)
-{
-	struct video_device *vdev = video_devdata(file);
-
-	if (vdev->vfl_type == VFL_TYPE_TOUCH)
-		return vivid_enum_input_tch(file, priv, inp);
-	return vidioc_enum_input(file, priv, inp);
-}
-
-static int vivid_g_input(struct file *file, void *priv, unsigned int *i)
-{
-	struct video_device *vdev = video_devdata(file);
-
-	if (vdev->vfl_type == VFL_TYPE_TOUCH)
-		return vivid_g_input_tch(file, priv, i);
-	return vidioc_g_input(file, priv, i);
-}
-
-static int vivid_s_input(struct file *file, void *priv, unsigned int i)
-{
-	struct video_device *vdev = video_devdata(file);
-
-	if (vdev->vfl_type == VFL_TYPE_TOUCH)
-		return vivid_s_input_tch(file, priv, i);
-	return vidioc_s_input(file, priv, i);
-}
-
-static int vivid_enum_fmt_cap(struct file *file, void  *priv,
-			      struct v4l2_fmtdesc *f)
-{
-	struct video_device *vdev = video_devdata(file);
-
-	if (vdev->vfl_type == VFL_TYPE_TOUCH)
-		return vivid_enum_fmt_tch(file, priv, f);
-	return vivid_enum_fmt_vid(file, priv, f);
-}
-
-static int vivid_g_fmt_cap(struct file *file, void *priv,
-			   struct v4l2_format *f)
-{
-	struct video_device *vdev = video_devdata(file);
-
-	if (vdev->vfl_type == VFL_TYPE_TOUCH)
-		return vivid_g_fmt_tch(file, priv, f);
-	return vidioc_g_fmt_vid_cap(file, priv, f);
-}
-
-static int vivid_try_fmt_cap(struct file *file, void *priv,
-			     struct v4l2_format *f)
-{
-	struct video_device *vdev = video_devdata(file);
-
-	if (vdev->vfl_type == VFL_TYPE_TOUCH)
-		return vivid_g_fmt_tch(file, priv, f);
-	return vidioc_try_fmt_vid_cap(file, priv, f);
-}
-
-static int vivid_s_fmt_cap(struct file *file, void *priv,
-			   struct v4l2_format *f)
-{
-	struct video_device *vdev = video_devdata(file);
-
-	if (vdev->vfl_type == VFL_TYPE_TOUCH)
-		return vivid_g_fmt_tch(file, priv, f);
-	return vidioc_s_fmt_vid_cap(file, priv, f);
-}
-
-static int vivid_g_fmt_cap_mplane(struct file *file, void *priv,
-				  struct v4l2_format *f)
-{
-	struct video_device *vdev = video_devdata(file);
-
-	if (vdev->vfl_type == VFL_TYPE_TOUCH)
-		return vivid_g_fmt_tch_mplane(file, priv, f);
-	return vidioc_g_fmt_vid_cap_mplane(file, priv, f);
-}
-
-static int vivid_try_fmt_cap_mplane(struct file *file, void *priv,
-				    struct v4l2_format *f)
-{
-	struct video_device *vdev = video_devdata(file);
-
-	if (vdev->vfl_type == VFL_TYPE_TOUCH)
-		return vivid_g_fmt_tch_mplane(file, priv, f);
-	return vidioc_try_fmt_vid_cap_mplane(file, priv, f);
-}
-
-static int vivid_s_fmt_cap_mplane(struct file *file, void *priv,
-				  struct v4l2_format *f)
-{
-	struct video_device *vdev = video_devdata(file);
-
-	if (vdev->vfl_type == VFL_TYPE_TOUCH)
-		return vivid_g_fmt_tch_mplane(file, priv, f);
-	return vidioc_s_fmt_vid_cap_mplane(file, priv, f);
-}
-
-static bool vivid_is_in_use(struct video_device *vdev)
-{
-	unsigned long flags;
-	bool res;
-
-	spin_lock_irqsave(&vdev->fh_lock, flags);
-	res = !list_empty(&vdev->fh_list);
-	spin_unlock_irqrestore(&vdev->fh_lock, flags);
-	return res;
-}
-
-static bool vivid_is_last_user(struct vivid_dev *dev)
-{
-	unsigned uses = vivid_is_in_use(&dev->vid_cap_dev) +
-			vivid_is_in_use(&dev->vid_out_dev) +
-			vivid_is_in_use(&dev->vbi_cap_dev) +
-			vivid_is_in_use(&dev->vbi_out_dev) +
-			vivid_is_in_use(&dev->sdr_cap_dev) +
-			vivid_is_in_use(&dev->radio_rx_dev) +
-			vivid_is_in_use(&dev->radio_tx_dev) +
-			vivid_is_in_use(&dev->meta_cap_dev) +
-			vivid_is_in_use(&dev->meta_out_dev) +
-			vivid_is_in_use(&dev->touch_cap_dev);
-
-	return uses == 1;
-}
-
-static int vivid_fop_release(struct file *file)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	struct video_device *vdev = video_devdata(file);
-
-	mutex_lock(&dev->mutex);
-	if (!no_error_inj && v4l2_fh_is_singular_file(file) &&
-	    !video_is_registered(vdev) && vivid_is_last_user(dev)) {
-		/*
-		 * I am the last user of this driver, and a disconnect
-		 * was forced (since this video_device is unregistered),
-		 * so re-register all video_device's again.
-		 */
-		v4l2_info(&dev->v4l2_dev, "reconnect\n");
-		set_bit(V4L2_FL_REGISTERED, &dev->vid_cap_dev.flags);
-		set_bit(V4L2_FL_REGISTERED, &dev->vid_out_dev.flags);
-		set_bit(V4L2_FL_REGISTERED, &dev->vbi_cap_dev.flags);
-		set_bit(V4L2_FL_REGISTERED, &dev->vbi_out_dev.flags);
-		set_bit(V4L2_FL_REGISTERED, &dev->sdr_cap_dev.flags);
-		set_bit(V4L2_FL_REGISTERED, &dev->radio_rx_dev.flags);
-		set_bit(V4L2_FL_REGISTERED, &dev->radio_tx_dev.flags);
-		set_bit(V4L2_FL_REGISTERED, &dev->meta_cap_dev.flags);
-		set_bit(V4L2_FL_REGISTERED, &dev->meta_out_dev.flags);
-		set_bit(V4L2_FL_REGISTERED, &dev->touch_cap_dev.flags);
-	}
-	mutex_unlock(&dev->mutex);
-	if (file->private_data == dev->overlay_cap_owner)
-		dev->overlay_cap_owner = NULL;
-	if (file->private_data == dev->radio_rx_rds_owner) {
-		dev->radio_rx_rds_last_block = 0;
-		dev->radio_rx_rds_owner = NULL;
-	}
-	if (file->private_data == dev->radio_tx_rds_owner) {
-		dev->radio_tx_rds_last_block = 0;
-		dev->radio_tx_rds_owner = NULL;
-	}
-	if (vdev->queue)
-		return vb2_fop_release(file);
-	return v4l2_fh_release(file);
-}
-
-static const struct v4l2_file_operations vivid_fops = {
-	.owner		= THIS_MODULE,
-	.open           = v4l2_fh_open,
-	.release        = vivid_fop_release,
-	.read           = vb2_fop_read,
-	.write          = vb2_fop_write,
-	.poll		= vb2_fop_poll,
-	.unlocked_ioctl = video_ioctl2,
-	.mmap           = vb2_fop_mmap,
-};
-
-static const struct v4l2_file_operations vivid_radio_fops = {
-	.owner		= THIS_MODULE,
-	.open           = v4l2_fh_open,
-	.release        = vivid_fop_release,
-	.read           = vivid_radio_read,
-	.write          = vivid_radio_write,
-	.poll		= vivid_radio_poll,
-	.unlocked_ioctl = video_ioctl2,
-};
-
-static const struct v4l2_ioctl_ops vivid_ioctl_ops = {
-	.vidioc_querycap		= vidioc_querycap,
-
-	.vidioc_enum_fmt_vid_cap	= vivid_enum_fmt_cap,
-	.vidioc_g_fmt_vid_cap		= vivid_g_fmt_cap,
-	.vidioc_try_fmt_vid_cap		= vivid_try_fmt_cap,
-	.vidioc_s_fmt_vid_cap		= vivid_s_fmt_cap,
-	.vidioc_g_fmt_vid_cap_mplane	= vivid_g_fmt_cap_mplane,
-	.vidioc_try_fmt_vid_cap_mplane	= vivid_try_fmt_cap_mplane,
-	.vidioc_s_fmt_vid_cap_mplane	= vivid_s_fmt_cap_mplane,
-
-	.vidioc_enum_fmt_vid_out	= vivid_enum_fmt_vid,
-	.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,
-	.vidioc_g_fmt_vid_out_mplane	= vidioc_g_fmt_vid_out_mplane,
-	.vidioc_try_fmt_vid_out_mplane	= vidioc_try_fmt_vid_out_mplane,
-	.vidioc_s_fmt_vid_out_mplane	= vidioc_s_fmt_vid_out_mplane,
-
-	.vidioc_g_selection		= vidioc_g_selection,
-	.vidioc_s_selection		= vidioc_s_selection,
-	.vidioc_g_pixelaspect		= vidioc_g_pixelaspect,
-
-	.vidioc_g_fmt_vbi_cap		= vidioc_g_fmt_vbi_cap,
-	.vidioc_try_fmt_vbi_cap		= vidioc_g_fmt_vbi_cap,
-	.vidioc_s_fmt_vbi_cap		= vidioc_s_fmt_vbi_cap,
-
-	.vidioc_g_fmt_sliced_vbi_cap    = vidioc_g_fmt_sliced_vbi_cap,
-	.vidioc_try_fmt_sliced_vbi_cap  = vidioc_try_fmt_sliced_vbi_cap,
-	.vidioc_s_fmt_sliced_vbi_cap    = vidioc_s_fmt_sliced_vbi_cap,
-	.vidioc_g_sliced_vbi_cap	= vidioc_g_sliced_vbi_cap,
-
-	.vidioc_g_fmt_vbi_out		= vidioc_g_fmt_vbi_out,
-	.vidioc_try_fmt_vbi_out		= vidioc_g_fmt_vbi_out,
-	.vidioc_s_fmt_vbi_out		= vidioc_s_fmt_vbi_out,
-
-	.vidioc_g_fmt_sliced_vbi_out    = vidioc_g_fmt_sliced_vbi_out,
-	.vidioc_try_fmt_sliced_vbi_out  = vidioc_try_fmt_sliced_vbi_out,
-	.vidioc_s_fmt_sliced_vbi_out    = vidioc_s_fmt_sliced_vbi_out,
-
-	.vidioc_enum_fmt_sdr_cap	= vidioc_enum_fmt_sdr_cap,
-	.vidioc_g_fmt_sdr_cap		= vidioc_g_fmt_sdr_cap,
-	.vidioc_try_fmt_sdr_cap		= vidioc_try_fmt_sdr_cap,
-	.vidioc_s_fmt_sdr_cap		= vidioc_s_fmt_sdr_cap,
-
-	.vidioc_overlay			= vidioc_overlay,
-	.vidioc_enum_framesizes		= vidioc_enum_framesizes,
-	.vidioc_enum_frameintervals	= vidioc_enum_frameintervals,
-	.vidioc_g_parm			= vidioc_g_parm,
-	.vidioc_s_parm			= vidioc_s_parm,
-
-	.vidioc_enum_fmt_vid_overlay	= vidioc_enum_fmt_vid_overlay,
-	.vidioc_g_fmt_vid_overlay	= vidioc_g_fmt_vid_overlay,
-	.vidioc_try_fmt_vid_overlay	= vidioc_try_fmt_vid_overlay,
-	.vidioc_s_fmt_vid_overlay	= vidioc_s_fmt_vid_overlay,
-	.vidioc_g_fmt_vid_out_overlay	= vidioc_g_fmt_vid_out_overlay,
-	.vidioc_try_fmt_vid_out_overlay	= vidioc_try_fmt_vid_out_overlay,
-	.vidioc_s_fmt_vid_out_overlay	= vidioc_s_fmt_vid_out_overlay,
-	.vidioc_g_fbuf			= vidioc_g_fbuf,
-	.vidioc_s_fbuf			= vidioc_s_fbuf,
-
-	.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_expbuf			= vb2_ioctl_expbuf,
-	.vidioc_streamon		= vb2_ioctl_streamon,
-	.vidioc_streamoff		= vb2_ioctl_streamoff,
-
-	.vidioc_enum_input		= vivid_enum_input,
-	.vidioc_g_input			= vivid_g_input,
-	.vidioc_s_input			= vivid_s_input,
-	.vidioc_s_audio			= vidioc_s_audio,
-	.vidioc_g_audio			= vidioc_g_audio,
-	.vidioc_enumaudio		= vidioc_enumaudio,
-	.vidioc_s_frequency		= vidioc_s_frequency,
-	.vidioc_g_frequency		= vidioc_g_frequency,
-	.vidioc_s_tuner			= vidioc_s_tuner,
-	.vidioc_g_tuner			= vidioc_g_tuner,
-	.vidioc_s_modulator		= vidioc_s_modulator,
-	.vidioc_g_modulator		= vidioc_g_modulator,
-	.vidioc_s_hw_freq_seek		= vidioc_s_hw_freq_seek,
-	.vidioc_enum_freq_bands		= vidioc_enum_freq_bands,
-
-	.vidioc_enum_output		= vidioc_enum_output,
-	.vidioc_g_output		= vidioc_g_output,
-	.vidioc_s_output		= vidioc_s_output,
-	.vidioc_s_audout		= vidioc_s_audout,
-	.vidioc_g_audout		= vidioc_g_audout,
-	.vidioc_enumaudout		= vidioc_enumaudout,
-
-	.vidioc_querystd		= vidioc_querystd,
-	.vidioc_g_std			= vidioc_g_std,
-	.vidioc_s_std			= vidioc_s_std,
-	.vidioc_s_dv_timings		= vidioc_s_dv_timings,
-	.vidioc_g_dv_timings		= vidioc_g_dv_timings,
-	.vidioc_query_dv_timings	= vidioc_query_dv_timings,
-	.vidioc_enum_dv_timings		= vidioc_enum_dv_timings,
-	.vidioc_dv_timings_cap		= vidioc_dv_timings_cap,
-	.vidioc_g_edid			= vidioc_g_edid,
-	.vidioc_s_edid			= vidioc_s_edid,
-
-	.vidioc_log_status		= vidioc_log_status,
-	.vidioc_subscribe_event		= vidioc_subscribe_event,
-	.vidioc_unsubscribe_event	= v4l2_event_unsubscribe,
-
-	.vidioc_enum_fmt_meta_cap	= vidioc_enum_fmt_meta_cap,
-	.vidioc_g_fmt_meta_cap		= vidioc_g_fmt_meta_cap,
-	.vidioc_s_fmt_meta_cap		= vidioc_g_fmt_meta_cap,
-	.vidioc_try_fmt_meta_cap	= vidioc_g_fmt_meta_cap,
-
-	.vidioc_enum_fmt_meta_out       = vidioc_enum_fmt_meta_out,
-	.vidioc_g_fmt_meta_out          = vidioc_g_fmt_meta_out,
-	.vidioc_s_fmt_meta_out          = vidioc_g_fmt_meta_out,
-	.vidioc_try_fmt_meta_out        = vidioc_g_fmt_meta_out,
-};
-
-/* -----------------------------------------------------------------
-	Initialization and module stuff
-   ------------------------------------------------------------------*/
-
-static void vivid_dev_release(struct v4l2_device *v4l2_dev)
-{
-	struct vivid_dev *dev = container_of(v4l2_dev, struct vivid_dev, v4l2_dev);
-
-	vivid_free_controls(dev);
-	v4l2_device_unregister(&dev->v4l2_dev);
-#ifdef CONFIG_MEDIA_CONTROLLER
-	media_device_cleanup(&dev->mdev);
-#endif
-	vfree(dev->scaled_line);
-	vfree(dev->blended_line);
-	vfree(dev->edid);
-	vfree(dev->bitmap_cap);
-	vfree(dev->bitmap_out);
-	tpg_free(&dev->tpg);
-	kfree(dev->query_dv_timings_qmenu);
-	kfree(dev->query_dv_timings_qmenu_strings);
-	kfree(dev);
-}
-
-#ifdef CONFIG_MEDIA_CONTROLLER
-static int vivid_req_validate(struct media_request *req)
-{
-	struct vivid_dev *dev = container_of(req->mdev, struct vivid_dev, mdev);
-
-	if (dev->req_validate_error) {
-		dev->req_validate_error = false;
-		return -EINVAL;
-	}
-	return vb2_request_validate(req);
-}
-
-static const struct media_device_ops vivid_media_ops = {
-	.req_validate = vivid_req_validate,
-	.req_queue = vb2_request_queue,
-};
-#endif
-
-static int vivid_create_queue(struct vivid_dev *dev,
-			      struct vb2_queue *q,
-			      u32 buf_type,
-			      unsigned int min_buffers_needed,
-			      const struct vb2_ops *ops)
-{
-	if (buf_type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->multiplanar)
-		buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-	else if (buf_type == V4L2_BUF_TYPE_VIDEO_OUTPUT && dev->multiplanar)
-		buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
-	else if (buf_type == V4L2_BUF_TYPE_VBI_CAPTURE && !dev->has_raw_vbi_cap)
-		buf_type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
-	else if (buf_type == V4L2_BUF_TYPE_VBI_OUTPUT && !dev->has_raw_vbi_out)
-		buf_type = V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
-
-	q->type = buf_type;
-	q->io_modes = VB2_MMAP | VB2_DMABUF;
-	q->io_modes |= V4L2_TYPE_IS_OUTPUT(buf_type) ?  VB2_WRITE : VB2_READ;
-	if (allocators[dev->inst] != 1)
-		q->io_modes |= VB2_USERPTR;
-	q->drv_priv = dev;
-	q->buf_struct_size = sizeof(struct vivid_buffer);
-	q->ops = ops;
-	q->mem_ops = allocators[dev->inst] == 1 ? &vb2_dma_contig_memops :
-						  &vb2_vmalloc_memops;
-	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
-	q->min_buffers_needed = min_buffers_needed;
-	q->lock = &dev->mutex;
-	q->dev = dev->v4l2_dev.dev;
-	q->supports_requests = true;
-
-	return vb2_queue_init(q);
-}
-
-static int vivid_create_instance(struct platform_device *pdev, int inst)
-{
-	static const struct v4l2_dv_timings def_dv_timings =
-					V4L2_DV_BT_CEA_1280X720P60;
-	unsigned in_type_counter[4] = { 0, 0, 0, 0 };
-	unsigned out_type_counter[4] = { 0, 0, 0, 0 };
-	int ccs_cap = ccs_cap_mode[inst];
-	int ccs_out = ccs_out_mode[inst];
-	bool has_tuner;
-	bool has_modulator;
-	struct vivid_dev *dev;
-	struct video_device *vfd;
-	unsigned node_type = node_types[inst];
-	v4l2_std_id tvnorms_cap = 0, tvnorms_out = 0;
-	int ret;
-	int i;
-#ifdef CONFIG_VIDEO_VIVID_CEC
-	unsigned int cec_tx_bus_cnt = 0;
-#endif
-
-	/* allocate main vivid state structure */
-	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-	if (!dev)
-		return -ENOMEM;
-
-	dev->inst = inst;
-
-#ifdef CONFIG_MEDIA_CONTROLLER
-	dev->v4l2_dev.mdev = &dev->mdev;
-
-	/* Initialize media device */
-	strscpy(dev->mdev.model, VIVID_MODULE_NAME, sizeof(dev->mdev.model));
-	snprintf(dev->mdev.bus_info, sizeof(dev->mdev.bus_info),
-		 "platform:%s-%03d", VIVID_MODULE_NAME, inst);
-	dev->mdev.dev = &pdev->dev;
-	media_device_init(&dev->mdev);
-	dev->mdev.ops = &vivid_media_ops;
-#endif
-
-	/* register v4l2_device */
-	snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name),
-			"%s-%03d", VIVID_MODULE_NAME, inst);
-	ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
-	if (ret) {
-		kfree(dev);
-		return ret;
-	}
-	dev->v4l2_dev.release = vivid_dev_release;
-
-	/* start detecting feature set */
-
-	/* do we use single- or multi-planar? */
-	dev->multiplanar = multiplanar[inst] > 1;
-	v4l2_info(&dev->v4l2_dev, "using %splanar format API\n",
-			dev->multiplanar ? "multi" : "single ");
-
-	/* how many inputs do we have and of what type? */
-	dev->num_inputs = num_inputs[inst];
-	if (dev->num_inputs < 1)
-		dev->num_inputs = 1;
-	if (dev->num_inputs >= MAX_INPUTS)
-		dev->num_inputs = MAX_INPUTS;
-	for (i = 0; i < dev->num_inputs; i++) {
-		dev->input_type[i] = (input_types[inst] >> (i * 2)) & 0x3;
-		dev->input_name_counter[i] = in_type_counter[dev->input_type[i]]++;
-	}
-	dev->has_audio_inputs = in_type_counter[TV] && in_type_counter[SVID];
-	if (in_type_counter[HDMI] == 16) {
-		/* The CEC physical address only allows for max 15 inputs */
-		in_type_counter[HDMI]--;
-		dev->num_inputs--;
-	}
-	dev->num_hdmi_inputs = in_type_counter[HDMI];
-
-	/* how many outputs do we have and of what type? */
-	dev->num_outputs = num_outputs[inst];
-	if (dev->num_outputs < 1)
-		dev->num_outputs = 1;
-	if (dev->num_outputs >= MAX_OUTPUTS)
-		dev->num_outputs = MAX_OUTPUTS;
-	for (i = 0; i < dev->num_outputs; i++) {
-		dev->output_type[i] = ((output_types[inst] >> i) & 1) ? HDMI : SVID;
-		dev->output_name_counter[i] = out_type_counter[dev->output_type[i]]++;
-		dev->display_present[i] = true;
-	}
-	dev->has_audio_outputs = out_type_counter[SVID];
-	if (out_type_counter[HDMI] == 16) {
-		/*
-		 * The CEC physical address only allows for max 15 inputs,
-		 * so outputs are also limited to 15 to allow for easy
-		 * CEC output to input mapping.
-		 */
-		out_type_counter[HDMI]--;
-		dev->num_outputs--;
-	}
-	dev->num_hdmi_outputs = out_type_counter[HDMI];
-
-	/* do we create a video capture device? */
-	dev->has_vid_cap = node_type & 0x0001;
-
-	/* do we create a vbi capture device? */
-	if (in_type_counter[TV] || in_type_counter[SVID]) {
-		dev->has_raw_vbi_cap = node_type & 0x0004;
-		dev->has_sliced_vbi_cap = node_type & 0x0008;
-		dev->has_vbi_cap = dev->has_raw_vbi_cap | dev->has_sliced_vbi_cap;
-	}
-
-	/* do we create a meta capture device */
-	dev->has_meta_cap = node_type & 0x20000;
-
-	/* sanity checks */
-	if ((in_type_counter[WEBCAM] || in_type_counter[HDMI]) &&
-	    !dev->has_vid_cap && !dev->has_meta_cap) {
-		v4l2_warn(&dev->v4l2_dev,
-			  "Webcam or HDMI input without video or metadata nodes\n");
-		kfree(dev);
-		return -EINVAL;
-	}
-	if ((in_type_counter[TV] || in_type_counter[SVID]) &&
-	    !dev->has_vid_cap && !dev->has_vbi_cap && !dev->has_meta_cap) {
-		v4l2_warn(&dev->v4l2_dev,
-			  "TV or S-Video input without video, VBI or metadata nodes\n");
-		kfree(dev);
-		return -EINVAL;
-	}
-
-	/* do we create a video output device? */
-	dev->has_vid_out = node_type & 0x0100;
-
-	/* do we create a vbi output device? */
-	if (out_type_counter[SVID]) {
-		dev->has_raw_vbi_out = node_type & 0x0400;
-		dev->has_sliced_vbi_out = node_type & 0x0800;
-		dev->has_vbi_out = dev->has_raw_vbi_out | dev->has_sliced_vbi_out;
-	}
-
-	/* do we create a metadata output device */
-	dev->has_meta_out = node_type & 0x40000;
-
-	/* sanity checks */
-	if (out_type_counter[SVID] &&
-	    !dev->has_vid_out && !dev->has_vbi_out && !dev->has_meta_out) {
-		v4l2_warn(&dev->v4l2_dev,
-			  "S-Video output without video, VBI or metadata nodes\n");
-		kfree(dev);
-		return -EINVAL;
-	}
-	if (out_type_counter[HDMI] && !dev->has_vid_out && !dev->has_meta_out) {
-		v4l2_warn(&dev->v4l2_dev,
-			  "HDMI output without video or metadata nodes\n");
-		kfree(dev);
-		return -EINVAL;
-	}
-
-	/* do we create a radio receiver device? */
-	dev->has_radio_rx = node_type & 0x0010;
-
-	/* do we create a radio transmitter device? */
-	dev->has_radio_tx = node_type & 0x1000;
-
-	/* do we create a software defined radio capture device? */
-	dev->has_sdr_cap = node_type & 0x0020;
-
-	/* do we have a TV tuner? */
-	dev->has_tv_tuner = in_type_counter[TV];
-
-	/* do we have a tuner? */
-	has_tuner = ((dev->has_vid_cap || dev->has_vbi_cap) && in_type_counter[TV]) ||
-		    dev->has_radio_rx || dev->has_sdr_cap;
-
-	/* do we have a modulator? */
-	has_modulator = dev->has_radio_tx;
-
-	if (dev->has_vid_cap)
-		/* do we have a framebuffer for overlay testing? */
-		dev->has_fb = node_type & 0x10000;
-
-	/* can we do crop/compose/scaling while capturing? */
-	if (no_error_inj && ccs_cap == -1)
-		ccs_cap = 7;
-
-	/* if ccs_cap == -1, then the user can select it using controls */
-	if (ccs_cap != -1) {
-		dev->has_crop_cap = ccs_cap & 1;
-		dev->has_compose_cap = ccs_cap & 2;
-		dev->has_scaler_cap = ccs_cap & 4;
-		v4l2_info(&dev->v4l2_dev, "Capture Crop: %c Compose: %c Scaler: %c\n",
-			dev->has_crop_cap ? 'Y' : 'N',
-			dev->has_compose_cap ? 'Y' : 'N',
-			dev->has_scaler_cap ? 'Y' : 'N');
-	}
-
-	/* can we do crop/compose/scaling with video output? */
-	if (no_error_inj && ccs_out == -1)
-		ccs_out = 7;
-
-	/* if ccs_out == -1, then the user can select it using controls */
-	if (ccs_out != -1) {
-		dev->has_crop_out = ccs_out & 1;
-		dev->has_compose_out = ccs_out & 2;
-		dev->has_scaler_out = ccs_out & 4;
-		v4l2_info(&dev->v4l2_dev, "Output Crop: %c Compose: %c Scaler: %c\n",
-			dev->has_crop_out ? 'Y' : 'N',
-			dev->has_compose_out ? 'Y' : 'N',
-			dev->has_scaler_out ? 'Y' : 'N');
-	}
-
-	/* do we create a touch capture device */
-	dev->has_touch_cap = node_type & 0x80000;
-
-	/* end detecting feature set */
-
-	if (dev->has_vid_cap) {
-		/* set up the capabilities of the video capture device */
-		dev->vid_cap_caps = dev->multiplanar ?
-			V4L2_CAP_VIDEO_CAPTURE_MPLANE :
-			V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OVERLAY;
-		dev->vid_cap_caps |= V4L2_CAP_STREAMING | V4L2_CAP_READWRITE;
-		if (dev->has_audio_inputs)
-			dev->vid_cap_caps |= V4L2_CAP_AUDIO;
-		if (dev->has_tv_tuner)
-			dev->vid_cap_caps |= V4L2_CAP_TUNER;
-	}
-	if (dev->has_vid_out) {
-		/* set up the capabilities of the video output device */
-		dev->vid_out_caps = dev->multiplanar ?
-			V4L2_CAP_VIDEO_OUTPUT_MPLANE :
-			V4L2_CAP_VIDEO_OUTPUT;
-		if (dev->has_fb)
-			dev->vid_out_caps |= V4L2_CAP_VIDEO_OUTPUT_OVERLAY;
-		dev->vid_out_caps |= V4L2_CAP_STREAMING | V4L2_CAP_READWRITE;
-		if (dev->has_audio_outputs)
-			dev->vid_out_caps |= V4L2_CAP_AUDIO;
-	}
-	if (dev->has_vbi_cap) {
-		/* set up the capabilities of the vbi capture device */
-		dev->vbi_cap_caps = (dev->has_raw_vbi_cap ? V4L2_CAP_VBI_CAPTURE : 0) |
-				    (dev->has_sliced_vbi_cap ? V4L2_CAP_SLICED_VBI_CAPTURE : 0);
-		dev->vbi_cap_caps |= V4L2_CAP_STREAMING | V4L2_CAP_READWRITE;
-		if (dev->has_audio_inputs)
-			dev->vbi_cap_caps |= V4L2_CAP_AUDIO;
-		if (dev->has_tv_tuner)
-			dev->vbi_cap_caps |= V4L2_CAP_TUNER;
-	}
-	if (dev->has_vbi_out) {
-		/* set up the capabilities of the vbi output device */
-		dev->vbi_out_caps = (dev->has_raw_vbi_out ? V4L2_CAP_VBI_OUTPUT : 0) |
-				    (dev->has_sliced_vbi_out ? V4L2_CAP_SLICED_VBI_OUTPUT : 0);
-		dev->vbi_out_caps |= V4L2_CAP_STREAMING | V4L2_CAP_READWRITE;
-		if (dev->has_audio_outputs)
-			dev->vbi_out_caps |= V4L2_CAP_AUDIO;
-	}
-	if (dev->has_sdr_cap) {
-		/* set up the capabilities of the sdr capture device */
-		dev->sdr_cap_caps = V4L2_CAP_SDR_CAPTURE | V4L2_CAP_TUNER;
-		dev->sdr_cap_caps |= V4L2_CAP_STREAMING | V4L2_CAP_READWRITE;
-	}
-	/* set up the capabilities of the radio receiver device */
-	if (dev->has_radio_rx)
-		dev->radio_rx_caps = V4L2_CAP_RADIO | V4L2_CAP_RDS_CAPTURE |
-				     V4L2_CAP_HW_FREQ_SEEK | V4L2_CAP_TUNER |
-				     V4L2_CAP_READWRITE;
-	/* set up the capabilities of the radio transmitter device */
-	if (dev->has_radio_tx)
-		dev->radio_tx_caps = V4L2_CAP_RDS_OUTPUT | V4L2_CAP_MODULATOR |
-				     V4L2_CAP_READWRITE;
-
-	/* set up the capabilities of meta capture device */
-	if (dev->has_meta_cap) {
-		dev->meta_cap_caps = V4L2_CAP_META_CAPTURE |
-				     V4L2_CAP_STREAMING | V4L2_CAP_READWRITE;
-		if (dev->has_audio_inputs)
-			dev->meta_cap_caps |= V4L2_CAP_AUDIO;
-		if (dev->has_tv_tuner)
-			dev->meta_cap_caps |= V4L2_CAP_TUNER;
-	}
-	/* set up the capabilities of meta output device */
-	if (dev->has_meta_out) {
-		dev->meta_out_caps = V4L2_CAP_META_OUTPUT |
-				     V4L2_CAP_STREAMING | V4L2_CAP_READWRITE;
-		if (dev->has_audio_outputs)
-			dev->meta_out_caps |= V4L2_CAP_AUDIO;
-	}
-	/* set up the capabilities of the touch capture device */
-	if (dev->has_touch_cap) {
-		dev->touch_cap_caps = V4L2_CAP_TOUCH | V4L2_CAP_STREAMING |
-				      V4L2_CAP_READWRITE;
-		dev->touch_cap_caps |= dev->multiplanar ?
-			V4L2_CAP_VIDEO_CAPTURE_MPLANE : V4L2_CAP_VIDEO_CAPTURE;
-	}
-
-	ret = -ENOMEM;
-	/* initialize the test pattern generator */
-	tpg_init(&dev->tpg, 640, 360);
-	if (tpg_alloc(&dev->tpg, MAX_ZOOM * MAX_WIDTH))
-		goto free_dev;
-	dev->scaled_line = vzalloc(array_size(MAX_WIDTH, MAX_ZOOM));
-	if (!dev->scaled_line)
-		goto free_dev;
-	dev->blended_line = vzalloc(array_size(MAX_WIDTH, MAX_ZOOM));
-	if (!dev->blended_line)
-		goto free_dev;
-
-	/* load the edid */
-	dev->edid = vmalloc(256 * 128);
-	if (!dev->edid)
-		goto free_dev;
-
-	while (v4l2_dv_timings_presets[dev->query_dv_timings_size].bt.width)
-		dev->query_dv_timings_size++;
-
-	/*
-	 * Create a char pointer array that points to the names of all the
-	 * preset timings
-	 */
-	dev->query_dv_timings_qmenu = kmalloc_array(dev->query_dv_timings_size,
-						    sizeof(char *), GFP_KERNEL);
-	/*
-	 * Create a string array containing the names of all the preset
-	 * timings. Each name is max 31 chars long (+ terminating 0).
-	 */
-	dev->query_dv_timings_qmenu_strings =
-		kmalloc_array(dev->query_dv_timings_size, 32, GFP_KERNEL);
-
-	if (!dev->query_dv_timings_qmenu ||
-	    !dev->query_dv_timings_qmenu_strings)
-		goto free_dev;
-
-	for (i = 0; i < dev->query_dv_timings_size; i++) {
-		const struct v4l2_bt_timings *bt = &v4l2_dv_timings_presets[i].bt;
-		char *p = dev->query_dv_timings_qmenu_strings + i * 32;
-		u32 htot, vtot;
-
-		dev->query_dv_timings_qmenu[i] = p;
-
-		htot = V4L2_DV_BT_FRAME_WIDTH(bt);
-		vtot = V4L2_DV_BT_FRAME_HEIGHT(bt);
-		snprintf(p, 32, "%ux%u%s%u",
-			bt->width, bt->height, bt->interlaced ? "i" : "p",
-			(u32)bt->pixelclock / (htot * vtot));
-	}
-
-	/* disable invalid ioctls based on the feature set */
-	if (!dev->has_audio_inputs) {
-		v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_S_AUDIO);
-		v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_G_AUDIO);
-		v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_ENUMAUDIO);
-		v4l2_disable_ioctl(&dev->vbi_cap_dev, VIDIOC_S_AUDIO);
-		v4l2_disable_ioctl(&dev->vbi_cap_dev, VIDIOC_G_AUDIO);
-		v4l2_disable_ioctl(&dev->vbi_cap_dev, VIDIOC_ENUMAUDIO);
-		v4l2_disable_ioctl(&dev->meta_cap_dev, VIDIOC_S_AUDIO);
-		v4l2_disable_ioctl(&dev->meta_cap_dev, VIDIOC_G_AUDIO);
-		v4l2_disable_ioctl(&dev->meta_cap_dev, VIDIOC_ENUMAUDIO);
-	}
-	if (!dev->has_audio_outputs) {
-		v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_S_AUDOUT);
-		v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_G_AUDOUT);
-		v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_ENUMAUDOUT);
-		v4l2_disable_ioctl(&dev->vbi_out_dev, VIDIOC_S_AUDOUT);
-		v4l2_disable_ioctl(&dev->vbi_out_dev, VIDIOC_G_AUDOUT);
-		v4l2_disable_ioctl(&dev->vbi_out_dev, VIDIOC_ENUMAUDOUT);
-		v4l2_disable_ioctl(&dev->meta_out_dev, VIDIOC_S_AUDOUT);
-		v4l2_disable_ioctl(&dev->meta_out_dev, VIDIOC_G_AUDOUT);
-		v4l2_disable_ioctl(&dev->meta_out_dev, VIDIOC_ENUMAUDOUT);
-	}
-	if (!in_type_counter[TV] && !in_type_counter[SVID]) {
-		v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_S_STD);
-		v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_G_STD);
-		v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_ENUMSTD);
-		v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_QUERYSTD);
-	}
-	if (!out_type_counter[SVID]) {
-		v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_S_STD);
-		v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_G_STD);
-		v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_ENUMSTD);
-	}
-	if (!has_tuner && !has_modulator) {
-		v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_S_FREQUENCY);
-		v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_G_FREQUENCY);
-		v4l2_disable_ioctl(&dev->vbi_cap_dev, VIDIOC_S_FREQUENCY);
-		v4l2_disable_ioctl(&dev->vbi_cap_dev, VIDIOC_G_FREQUENCY);
-		v4l2_disable_ioctl(&dev->meta_cap_dev, VIDIOC_S_FREQUENCY);
-		v4l2_disable_ioctl(&dev->meta_cap_dev, VIDIOC_G_FREQUENCY);
-	}
-	if (!has_tuner) {
-		v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_S_TUNER);
-		v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_G_TUNER);
-		v4l2_disable_ioctl(&dev->vbi_cap_dev, VIDIOC_S_TUNER);
-		v4l2_disable_ioctl(&dev->vbi_cap_dev, VIDIOC_G_TUNER);
-		v4l2_disable_ioctl(&dev->meta_cap_dev, VIDIOC_S_TUNER);
-		v4l2_disable_ioctl(&dev->meta_cap_dev, VIDIOC_G_TUNER);
-	}
-	if (in_type_counter[HDMI] == 0) {
-		v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_S_EDID);
-		v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_G_EDID);
-		v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_DV_TIMINGS_CAP);
-		v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_G_DV_TIMINGS);
-		v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_S_DV_TIMINGS);
-		v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_ENUM_DV_TIMINGS);
-		v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_QUERY_DV_TIMINGS);
-	}
-	if (out_type_counter[HDMI] == 0) {
-		v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_G_EDID);
-		v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_DV_TIMINGS_CAP);
-		v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_G_DV_TIMINGS);
-		v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_S_DV_TIMINGS);
-		v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_ENUM_DV_TIMINGS);
-	}
-	if (!dev->has_fb) {
-		v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_G_FBUF);
-		v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_S_FBUF);
-		v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_OVERLAY);
-	}
-	v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_S_HW_FREQ_SEEK);
-	v4l2_disable_ioctl(&dev->vbi_cap_dev, VIDIOC_S_HW_FREQ_SEEK);
-	v4l2_disable_ioctl(&dev->sdr_cap_dev, VIDIOC_S_HW_FREQ_SEEK);
-	v4l2_disable_ioctl(&dev->meta_cap_dev, VIDIOC_S_HW_FREQ_SEEK);
-	v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_S_FREQUENCY);
-	v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_G_FREQUENCY);
-	v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_ENUM_FRAMESIZES);
-	v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_ENUM_FRAMEINTERVALS);
-	v4l2_disable_ioctl(&dev->vbi_out_dev, VIDIOC_S_FREQUENCY);
-	v4l2_disable_ioctl(&dev->vbi_out_dev, VIDIOC_G_FREQUENCY);
-	v4l2_disable_ioctl(&dev->meta_out_dev, VIDIOC_S_FREQUENCY);
-	v4l2_disable_ioctl(&dev->meta_out_dev, VIDIOC_G_FREQUENCY);
-	v4l2_disable_ioctl(&dev->touch_cap_dev, VIDIOC_S_PARM);
-	v4l2_disable_ioctl(&dev->touch_cap_dev, VIDIOC_ENUM_FRAMESIZES);
-	v4l2_disable_ioctl(&dev->touch_cap_dev, VIDIOC_ENUM_FRAMEINTERVALS);
-
-	/* configure internal data */
-	dev->fmt_cap = &vivid_formats[0];
-	dev->fmt_out = &vivid_formats[0];
-	if (!dev->multiplanar)
-		vivid_formats[0].data_offset[0] = 0;
-	dev->webcam_size_idx = 1;
-	dev->webcam_ival_idx = 3;
-	tpg_s_fourcc(&dev->tpg, dev->fmt_cap->fourcc);
-	dev->std_out = V4L2_STD_PAL;
-	if (dev->input_type[0] == TV || dev->input_type[0] == SVID)
-		tvnorms_cap = V4L2_STD_ALL;
-	if (dev->output_type[0] == SVID)
-		tvnorms_out = V4L2_STD_ALL;
-	for (i = 0; i < MAX_INPUTS; i++) {
-		dev->dv_timings_cap[i] = def_dv_timings;
-		dev->std_cap[i] = V4L2_STD_PAL;
-	}
-	dev->dv_timings_out = def_dv_timings;
-	dev->tv_freq = 2804 /* 175.25 * 16 */;
-	dev->tv_audmode = V4L2_TUNER_MODE_STEREO;
-	dev->tv_field_cap = V4L2_FIELD_INTERLACED;
-	dev->tv_field_out = V4L2_FIELD_INTERLACED;
-	dev->radio_rx_freq = 95000 * 16;
-	dev->radio_rx_audmode = V4L2_TUNER_MODE_STEREO;
-	if (dev->has_radio_tx) {
-		dev->radio_tx_freq = 95500 * 16;
-		dev->radio_rds_loop = false;
-	}
-	dev->radio_tx_subchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_RDS;
-	dev->sdr_adc_freq = 300000;
-	dev->sdr_fm_freq = 50000000;
-	dev->sdr_pixelformat = V4L2_SDR_FMT_CU8;
-	dev->sdr_buffersize = SDR_CAP_SAMPLES_PER_BUF * 2;
-
-	dev->edid_max_blocks = dev->edid_blocks = 2;
-	memcpy(dev->edid, vivid_hdmi_edid, sizeof(vivid_hdmi_edid));
-	dev->radio_rds_init_time = ktime_get();
-
-	/* create all controls */
-	ret = vivid_create_controls(dev, ccs_cap == -1, ccs_out == -1, no_error_inj,
-			in_type_counter[TV] || in_type_counter[SVID] ||
-			out_type_counter[SVID],
-			in_type_counter[HDMI] || out_type_counter[HDMI]);
-	if (ret)
-		goto unreg_dev;
-
-	/* enable/disable interface specific controls */
-	if (dev->num_outputs && dev->output_type[0] != HDMI)
-		v4l2_ctrl_activate(dev->ctrl_display_present, false);
-	if (dev->num_inputs && dev->input_type[0] != HDMI) {
-		v4l2_ctrl_activate(dev->ctrl_dv_timings_signal_mode, false);
-		v4l2_ctrl_activate(dev->ctrl_dv_timings, false);
-	} else if (dev->num_inputs && dev->input_type[0] == HDMI) {
-		v4l2_ctrl_activate(dev->ctrl_std_signal_mode, false);
-		v4l2_ctrl_activate(dev->ctrl_standard, false);
-	}
-
-	/*
-	 * update the capture and output formats to do a proper initial
-	 * configuration.
-	 */
-	vivid_update_format_cap(dev, false);
-	vivid_update_format_out(dev);
-
-	/* initialize overlay */
-	dev->fb_cap.fmt.width = dev->src_rect.width;
-	dev->fb_cap.fmt.height = dev->src_rect.height;
-	dev->fb_cap.fmt.pixelformat = dev->fmt_cap->fourcc;
-	dev->fb_cap.fmt.bytesperline = dev->src_rect.width * tpg_g_twopixelsize(&dev->tpg, 0) / 2;
-	dev->fb_cap.fmt.sizeimage = dev->src_rect.height * dev->fb_cap.fmt.bytesperline;
-
-	/* update touch configuration */
-	dev->timeperframe_tch_cap.numerator = 1;
-	dev->timeperframe_tch_cap.denominator = 10;
-	vivid_set_touch(dev, 0);
-
-	/* initialize locks */
-	spin_lock_init(&dev->slock);
-	mutex_init(&dev->mutex);
-
-	/* init dma queues */
-	INIT_LIST_HEAD(&dev->vid_cap_active);
-	INIT_LIST_HEAD(&dev->vid_out_active);
-	INIT_LIST_HEAD(&dev->vbi_cap_active);
-	INIT_LIST_HEAD(&dev->vbi_out_active);
-	INIT_LIST_HEAD(&dev->sdr_cap_active);
-	INIT_LIST_HEAD(&dev->meta_cap_active);
-	INIT_LIST_HEAD(&dev->meta_out_active);
-	INIT_LIST_HEAD(&dev->touch_cap_active);
-
-	INIT_LIST_HEAD(&dev->cec_work_list);
-	spin_lock_init(&dev->cec_slock);
-	/*
-	 * Same as create_singlethread_workqueue, but now I can use the
-	 * string formatting of alloc_ordered_workqueue.
-	 */
-	dev->cec_workqueue =
-		alloc_ordered_workqueue("vivid-%03d-cec", WQ_MEM_RECLAIM, inst);
-	if (!dev->cec_workqueue) {
-		ret = -ENOMEM;
-		goto unreg_dev;
-	}
-
-	if (allocators[inst] == 1)
-		dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
-
-	/* start creating the vb2 queues */
-	if (dev->has_vid_cap) {
-		/* initialize vid_cap queue */
-		ret = vivid_create_queue(dev, &dev->vb_vid_cap_q,
-					 V4L2_BUF_TYPE_VIDEO_CAPTURE, 2,
-					 &vivid_vid_cap_qops);
-		if (ret)
-			goto unreg_dev;
-	}
-
-	if (dev->has_vid_out) {
-		/* initialize vid_out queue */
-		ret = vivid_create_queue(dev, &dev->vb_vid_out_q,
-					 V4L2_BUF_TYPE_VIDEO_OUTPUT, 2,
-					 &vivid_vid_out_qops);
-		if (ret)
-			goto unreg_dev;
-	}
-
-	if (dev->has_vbi_cap) {
-		/* initialize vbi_cap queue */
-		ret = vivid_create_queue(dev, &dev->vb_vbi_cap_q,
-					 V4L2_BUF_TYPE_VBI_CAPTURE, 2,
-					 &vivid_vbi_cap_qops);
-		if (ret)
-			goto unreg_dev;
-	}
-
-	if (dev->has_vbi_out) {
-		/* initialize vbi_out queue */
-		ret = vivid_create_queue(dev, &dev->vb_vbi_out_q,
-					 V4L2_BUF_TYPE_VBI_OUTPUT, 2,
-					 &vivid_vbi_out_qops);
-		if (ret)
-			goto unreg_dev;
-	}
-
-	if (dev->has_sdr_cap) {
-		/* initialize sdr_cap queue */
-		ret = vivid_create_queue(dev, &dev->vb_sdr_cap_q,
-					 V4L2_BUF_TYPE_SDR_CAPTURE, 8,
-					 &vivid_sdr_cap_qops);
-		if (ret)
-			goto unreg_dev;
-	}
-
-	if (dev->has_meta_cap) {
-		/* initialize meta_cap queue */
-		ret = vivid_create_queue(dev, &dev->vb_meta_cap_q,
-					 V4L2_BUF_TYPE_META_CAPTURE, 2,
-					 &vivid_meta_cap_qops);
-		if (ret)
-			goto unreg_dev;
-	}
-
-	if (dev->has_meta_out) {
-		/* initialize meta_out queue */
-		ret = vivid_create_queue(dev, &dev->vb_meta_out_q,
-					 V4L2_BUF_TYPE_META_OUTPUT, 1,
-					 &vivid_meta_out_qops);
-		if (ret)
-			goto unreg_dev;
-	}
-
-	if (dev->has_touch_cap) {
-		/* initialize touch_cap queue */
-		ret = vivid_create_queue(dev, &dev->vb_touch_cap_q,
-					 V4L2_BUF_TYPE_VIDEO_CAPTURE, 1,
-					 &vivid_touch_cap_qops);
-		if (ret)
-			goto unreg_dev;
-	}
-
-	if (dev->has_fb) {
-		/* Create framebuffer for testing capture/output overlay */
-		ret = vivid_fb_init(dev);
-		if (ret)
-			goto unreg_dev;
-		v4l2_info(&dev->v4l2_dev, "Framebuffer device registered as fb%d\n",
-			  dev->fb_info.node);
-	}
-
-#ifdef CONFIG_VIDEO_VIVID_CEC
-	if (dev->has_vid_cap && in_type_counter[HDMI]) {
-		struct cec_adapter *adap;
-
-		adap = vivid_cec_alloc_adap(dev, 0, false);
-		ret = PTR_ERR_OR_ZERO(adap);
-		if (ret < 0)
-			goto unreg_dev;
-		dev->cec_rx_adap = adap;
-	}
-
-	if (dev->has_vid_out) {
-		for (i = 0; i < dev->num_outputs; i++) {
-			struct cec_adapter *adap;
-
-			if (dev->output_type[i] != HDMI)
-				continue;
-
-			dev->cec_output2bus_map[i] = cec_tx_bus_cnt;
-			adap = vivid_cec_alloc_adap(dev, cec_tx_bus_cnt, true);
-			ret = PTR_ERR_OR_ZERO(adap);
-			if (ret < 0) {
-				for (i = 0; i < dev->num_outputs; i++)
-					cec_delete_adapter(dev->cec_tx_adap[i]);
-				goto unreg_dev;
-			}
-
-			dev->cec_tx_adap[cec_tx_bus_cnt] = adap;
-			cec_tx_bus_cnt++;
-		}
-	}
-#endif
-
-	v4l2_ctrl_handler_setup(&dev->ctrl_hdl_vid_cap);
-	v4l2_ctrl_handler_setup(&dev->ctrl_hdl_vid_out);
-	v4l2_ctrl_handler_setup(&dev->ctrl_hdl_vbi_cap);
-	v4l2_ctrl_handler_setup(&dev->ctrl_hdl_vbi_out);
-	v4l2_ctrl_handler_setup(&dev->ctrl_hdl_radio_rx);
-	v4l2_ctrl_handler_setup(&dev->ctrl_hdl_radio_tx);
-	v4l2_ctrl_handler_setup(&dev->ctrl_hdl_sdr_cap);
-	v4l2_ctrl_handler_setup(&dev->ctrl_hdl_meta_cap);
-	v4l2_ctrl_handler_setup(&dev->ctrl_hdl_meta_out);
-	v4l2_ctrl_handler_setup(&dev->ctrl_hdl_touch_cap);
-
-	/* finally start creating the device nodes */
-	if (dev->has_vid_cap) {
-		vfd = &dev->vid_cap_dev;
-		snprintf(vfd->name, sizeof(vfd->name),
-			 "vivid-%03d-vid-cap", inst);
-		vfd->fops = &vivid_fops;
-		vfd->ioctl_ops = &vivid_ioctl_ops;
-		vfd->device_caps = dev->vid_cap_caps;
-		vfd->release = video_device_release_empty;
-		vfd->v4l2_dev = &dev->v4l2_dev;
-		vfd->queue = &dev->vb_vid_cap_q;
-		vfd->tvnorms = tvnorms_cap;
-
-		/*
-		 * Provide a mutex to v4l2 core. It will be used to protect
-		 * all fops and v4l2 ioctls.
-		 */
-		vfd->lock = &dev->mutex;
-		video_set_drvdata(vfd, dev);
-
-#ifdef CONFIG_MEDIA_CONTROLLER
-		dev->vid_cap_pad.flags = MEDIA_PAD_FL_SINK;
-		ret = media_entity_pads_init(&vfd->entity, 1, &dev->vid_cap_pad);
-		if (ret)
-			goto unreg_dev;
-#endif
-
-#ifdef CONFIG_VIDEO_VIVID_CEC
-		if (in_type_counter[HDMI]) {
-			ret = cec_register_adapter(dev->cec_rx_adap, &pdev->dev);
-			if (ret < 0) {
-				cec_delete_adapter(dev->cec_rx_adap);
-				dev->cec_rx_adap = NULL;
-				goto unreg_dev;
-			}
-			cec_s_phys_addr(dev->cec_rx_adap, 0, false);
-			v4l2_info(&dev->v4l2_dev, "CEC adapter %s registered for HDMI input 0\n",
-				  dev_name(&dev->cec_rx_adap->devnode.dev));
-		}
-#endif
-
-		ret = video_register_device(vfd, VFL_TYPE_VIDEO, vid_cap_nr[inst]);
-		if (ret < 0)
-			goto unreg_dev;
-		v4l2_info(&dev->v4l2_dev, "V4L2 capture device registered as %s\n",
-					  video_device_node_name(vfd));
-	}
-
-	if (dev->has_vid_out) {
-		vfd = &dev->vid_out_dev;
-		snprintf(vfd->name, sizeof(vfd->name),
-			 "vivid-%03d-vid-out", inst);
-		vfd->vfl_dir = VFL_DIR_TX;
-		vfd->fops = &vivid_fops;
-		vfd->ioctl_ops = &vivid_ioctl_ops;
-		vfd->device_caps = dev->vid_out_caps;
-		vfd->release = video_device_release_empty;
-		vfd->v4l2_dev = &dev->v4l2_dev;
-		vfd->queue = &dev->vb_vid_out_q;
-		vfd->tvnorms = tvnorms_out;
-
-		/*
-		 * Provide a mutex to v4l2 core. It will be used to protect
-		 * all fops and v4l2 ioctls.
-		 */
-		vfd->lock = &dev->mutex;
-		video_set_drvdata(vfd, dev);
-
-#ifdef CONFIG_MEDIA_CONTROLLER
-		dev->vid_out_pad.flags = MEDIA_PAD_FL_SOURCE;
-		ret = media_entity_pads_init(&vfd->entity, 1, &dev->vid_out_pad);
-		if (ret)
-			goto unreg_dev;
-#endif
-
-#ifdef CONFIG_VIDEO_VIVID_CEC
-		for (i = 0; i < cec_tx_bus_cnt; i++) {
-			ret = cec_register_adapter(dev->cec_tx_adap[i], &pdev->dev);
-			if (ret < 0) {
-				for (; i < cec_tx_bus_cnt; i++) {
-					cec_delete_adapter(dev->cec_tx_adap[i]);
-					dev->cec_tx_adap[i] = NULL;
-				}
-				goto unreg_dev;
-			}
-			v4l2_info(&dev->v4l2_dev, "CEC adapter %s registered for HDMI output %d\n",
-				  dev_name(&dev->cec_tx_adap[i]->devnode.dev), i);
-			if (i < out_type_counter[HDMI])
-				cec_s_phys_addr(dev->cec_tx_adap[i], (i + 1) << 12, false);
-			else
-				cec_s_phys_addr(dev->cec_tx_adap[i], 0x1000, false);
-		}
-#endif
-
-		ret = video_register_device(vfd, VFL_TYPE_VIDEO, vid_out_nr[inst]);
-		if (ret < 0)
-			goto unreg_dev;
-		v4l2_info(&dev->v4l2_dev, "V4L2 output device registered as %s\n",
-					  video_device_node_name(vfd));
-	}
-
-	if (dev->has_vbi_cap) {
-		vfd = &dev->vbi_cap_dev;
-		snprintf(vfd->name, sizeof(vfd->name),
-			 "vivid-%03d-vbi-cap", inst);
-		vfd->fops = &vivid_fops;
-		vfd->ioctl_ops = &vivid_ioctl_ops;
-		vfd->device_caps = dev->vbi_cap_caps;
-		vfd->release = video_device_release_empty;
-		vfd->v4l2_dev = &dev->v4l2_dev;
-		vfd->queue = &dev->vb_vbi_cap_q;
-		vfd->lock = &dev->mutex;
-		vfd->tvnorms = tvnorms_cap;
-		video_set_drvdata(vfd, dev);
-
-#ifdef CONFIG_MEDIA_CONTROLLER
-		dev->vbi_cap_pad.flags = MEDIA_PAD_FL_SINK;
-		ret = media_entity_pads_init(&vfd->entity, 1, &dev->vbi_cap_pad);
-		if (ret)
-			goto unreg_dev;
-#endif
-
-		ret = video_register_device(vfd, VFL_TYPE_VBI, vbi_cap_nr[inst]);
-		if (ret < 0)
-			goto unreg_dev;
-		v4l2_info(&dev->v4l2_dev, "V4L2 capture device registered as %s, supports %s VBI\n",
-					  video_device_node_name(vfd),
-					  (dev->has_raw_vbi_cap && dev->has_sliced_vbi_cap) ?
-					  "raw and sliced" :
-					  (dev->has_raw_vbi_cap ? "raw" : "sliced"));
-	}
-
-	if (dev->has_vbi_out) {
-		vfd = &dev->vbi_out_dev;
-		snprintf(vfd->name, sizeof(vfd->name),
-			 "vivid-%03d-vbi-out", inst);
-		vfd->vfl_dir = VFL_DIR_TX;
-		vfd->fops = &vivid_fops;
-		vfd->ioctl_ops = &vivid_ioctl_ops;
-		vfd->device_caps = dev->vbi_out_caps;
-		vfd->release = video_device_release_empty;
-		vfd->v4l2_dev = &dev->v4l2_dev;
-		vfd->queue = &dev->vb_vbi_out_q;
-		vfd->lock = &dev->mutex;
-		vfd->tvnorms = tvnorms_out;
-		video_set_drvdata(vfd, dev);
-
-#ifdef CONFIG_MEDIA_CONTROLLER
-		dev->vbi_out_pad.flags = MEDIA_PAD_FL_SOURCE;
-		ret = media_entity_pads_init(&vfd->entity, 1, &dev->vbi_out_pad);
-		if (ret)
-			goto unreg_dev;
-#endif
-
-		ret = video_register_device(vfd, VFL_TYPE_VBI, vbi_out_nr[inst]);
-		if (ret < 0)
-			goto unreg_dev;
-		v4l2_info(&dev->v4l2_dev, "V4L2 output device registered as %s, supports %s VBI\n",
-					  video_device_node_name(vfd),
-					  (dev->has_raw_vbi_out && dev->has_sliced_vbi_out) ?
-					  "raw and sliced" :
-					  (dev->has_raw_vbi_out ? "raw" : "sliced"));
-	}
-
-	if (dev->has_sdr_cap) {
-		vfd = &dev->sdr_cap_dev;
-		snprintf(vfd->name, sizeof(vfd->name),
-			 "vivid-%03d-sdr-cap", inst);
-		vfd->fops = &vivid_fops;
-		vfd->ioctl_ops = &vivid_ioctl_ops;
-		vfd->device_caps = dev->sdr_cap_caps;
-		vfd->release = video_device_release_empty;
-		vfd->v4l2_dev = &dev->v4l2_dev;
-		vfd->queue = &dev->vb_sdr_cap_q;
-		vfd->lock = &dev->mutex;
-		video_set_drvdata(vfd, dev);
-
-#ifdef CONFIG_MEDIA_CONTROLLER
-		dev->sdr_cap_pad.flags = MEDIA_PAD_FL_SINK;
-		ret = media_entity_pads_init(&vfd->entity, 1, &dev->sdr_cap_pad);
-		if (ret)
-			goto unreg_dev;
-#endif
-
-		ret = video_register_device(vfd, VFL_TYPE_SDR, sdr_cap_nr[inst]);
-		if (ret < 0)
-			goto unreg_dev;
-		v4l2_info(&dev->v4l2_dev, "V4L2 capture device registered as %s\n",
-					  video_device_node_name(vfd));
-	}
-
-	if (dev->has_radio_rx) {
-		vfd = &dev->radio_rx_dev;
-		snprintf(vfd->name, sizeof(vfd->name),
-			 "vivid-%03d-rad-rx", inst);
-		vfd->fops = &vivid_radio_fops;
-		vfd->ioctl_ops = &vivid_ioctl_ops;
-		vfd->device_caps = dev->radio_rx_caps;
-		vfd->release = video_device_release_empty;
-		vfd->v4l2_dev = &dev->v4l2_dev;
-		vfd->lock = &dev->mutex;
-		video_set_drvdata(vfd, dev);
-
-		ret = video_register_device(vfd, VFL_TYPE_RADIO, radio_rx_nr[inst]);
-		if (ret < 0)
-			goto unreg_dev;
-		v4l2_info(&dev->v4l2_dev, "V4L2 receiver device registered as %s\n",
-					  video_device_node_name(vfd));
-	}
-
-	if (dev->has_radio_tx) {
-		vfd = &dev->radio_tx_dev;
-		snprintf(vfd->name, sizeof(vfd->name),
-			 "vivid-%03d-rad-tx", inst);
-		vfd->vfl_dir = VFL_DIR_TX;
-		vfd->fops = &vivid_radio_fops;
-		vfd->ioctl_ops = &vivid_ioctl_ops;
-		vfd->device_caps = dev->radio_tx_caps;
-		vfd->release = video_device_release_empty;
-		vfd->v4l2_dev = &dev->v4l2_dev;
-		vfd->lock = &dev->mutex;
-		video_set_drvdata(vfd, dev);
-
-		ret = video_register_device(vfd, VFL_TYPE_RADIO, radio_tx_nr[inst]);
-		if (ret < 0)
-			goto unreg_dev;
-		v4l2_info(&dev->v4l2_dev, "V4L2 transmitter device registered as %s\n",
-					  video_device_node_name(vfd));
-	}
-
-	if (dev->has_meta_cap) {
-		vfd = &dev->meta_cap_dev;
-		snprintf(vfd->name, sizeof(vfd->name),
-			 "vivid-%03d-meta-cap", inst);
-		vfd->fops = &vivid_fops;
-		vfd->ioctl_ops = &vivid_ioctl_ops;
-		vfd->device_caps = dev->meta_cap_caps;
-		vfd->release = video_device_release_empty;
-		vfd->v4l2_dev = &dev->v4l2_dev;
-		vfd->queue = &dev->vb_meta_cap_q;
-		vfd->lock = &dev->mutex;
-		vfd->tvnorms = tvnorms_cap;
-		video_set_drvdata(vfd, dev);
-#ifdef CONFIG_MEDIA_CONTROLLER
-		dev->meta_cap_pad.flags = MEDIA_PAD_FL_SINK;
-		ret = media_entity_pads_init(&vfd->entity, 1,
-					     &dev->meta_cap_pad);
-		if (ret)
-			goto unreg_dev;
-#endif
-		ret = video_register_device(vfd, VFL_TYPE_VIDEO,
-					    meta_cap_nr[inst]);
-		if (ret < 0)
-			goto unreg_dev;
-		v4l2_info(&dev->v4l2_dev,
-			  "V4L2 metadata capture device registered as %s\n",
-			  video_device_node_name(vfd));
-	}
-
-	if (dev->has_meta_out) {
-		vfd = &dev->meta_out_dev;
-		snprintf(vfd->name, sizeof(vfd->name),
-			 "vivid-%03d-meta-out", inst);
-		vfd->vfl_dir = VFL_DIR_TX;
-		vfd->fops = &vivid_fops;
-		vfd->ioctl_ops = &vivid_ioctl_ops;
-		vfd->device_caps = dev->meta_out_caps;
-		vfd->release = video_device_release_empty;
-		vfd->v4l2_dev = &dev->v4l2_dev;
-		vfd->queue = &dev->vb_meta_out_q;
-		vfd->lock = &dev->mutex;
-		vfd->tvnorms = tvnorms_out;
-		video_set_drvdata(vfd, dev);
-#ifdef CONFIG_MEDIA_CONTROLLER
-		dev->meta_out_pad.flags = MEDIA_PAD_FL_SOURCE;
-		ret = media_entity_pads_init(&vfd->entity, 1,
-					     &dev->meta_out_pad);
-		if (ret)
-			goto unreg_dev;
-#endif
-		ret = video_register_device(vfd, VFL_TYPE_VIDEO,
-					    meta_out_nr[inst]);
-		if (ret < 0)
-			goto unreg_dev;
-		v4l2_info(&dev->v4l2_dev,
-			  "V4L2 metadata output device registered as %s\n",
-			  video_device_node_name(vfd));
-	}
-
-	if (dev->has_touch_cap) {
-		vfd = &dev->touch_cap_dev;
-		snprintf(vfd->name, sizeof(vfd->name),
-			 "vivid-%03d-touch-cap", inst);
-		vfd->fops = &vivid_fops;
-		vfd->ioctl_ops = &vivid_ioctl_ops;
-		vfd->device_caps = dev->touch_cap_caps;
-		vfd->release = video_device_release_empty;
-		vfd->v4l2_dev = &dev->v4l2_dev;
-		vfd->queue = &dev->vb_touch_cap_q;
-		vfd->tvnorms = tvnorms_cap;
-		vfd->lock = &dev->mutex;
-		video_set_drvdata(vfd, dev);
-#ifdef CONFIG_MEDIA_CONTROLLER
-		dev->touch_cap_pad.flags = MEDIA_PAD_FL_SINK;
-		ret = media_entity_pads_init(&vfd->entity, 1,
-					     &dev->touch_cap_pad);
-		if (ret)
-			goto unreg_dev;
-#endif
-		ret = video_register_device(vfd, VFL_TYPE_TOUCH,
-					    touch_cap_nr[inst]);
-		if (ret < 0)
-			goto unreg_dev;
-		v4l2_info(&dev->v4l2_dev,
-			  "V4L2 touch capture device registered as %s\n",
-			  video_device_node_name(vfd));
-	}
-
-#ifdef CONFIG_MEDIA_CONTROLLER
-	/* Register the media device */
-	ret = media_device_register(&dev->mdev);
-	if (ret) {
-		dev_err(dev->mdev.dev,
-			"media device register failed (err=%d)\n", ret);
-		goto unreg_dev;
-	}
-#endif
-
-	/* Now that everything is fine, let's add it to device list */
-	vivid_devs[inst] = dev;
-
-	return 0;
-
-unreg_dev:
-	video_unregister_device(&dev->touch_cap_dev);
-	video_unregister_device(&dev->meta_out_dev);
-	video_unregister_device(&dev->meta_cap_dev);
-	video_unregister_device(&dev->radio_tx_dev);
-	video_unregister_device(&dev->radio_rx_dev);
-	video_unregister_device(&dev->sdr_cap_dev);
-	video_unregister_device(&dev->vbi_out_dev);
-	video_unregister_device(&dev->vbi_cap_dev);
-	video_unregister_device(&dev->vid_out_dev);
-	video_unregister_device(&dev->vid_cap_dev);
-	cec_unregister_adapter(dev->cec_rx_adap);
-	for (i = 0; i < MAX_OUTPUTS; i++)
-		cec_unregister_adapter(dev->cec_tx_adap[i]);
-	if (dev->cec_workqueue) {
-		vivid_cec_bus_free_work(dev);
-		destroy_workqueue(dev->cec_workqueue);
-	}
-free_dev:
-	v4l2_device_put(&dev->v4l2_dev);
-	return ret;
-}
-
-/* This routine allocates from 1 to n_devs virtual drivers.
-
-   The real maximum number of virtual drivers will depend on how many drivers
-   will succeed. This is limited to the maximum number of devices that
-   videodev supports, which is equal to VIDEO_NUM_DEVICES.
- */
-static int vivid_probe(struct platform_device *pdev)
-{
-	const struct font_desc *font = find_font("VGA8x16");
-	int ret = 0, i;
-
-	if (font == NULL) {
-		pr_err("vivid: could not find font\n");
-		return -ENODEV;
-	}
-
-	tpg_set_font(font->data);
-
-	n_devs = clamp_t(unsigned, n_devs, 1, VIVID_MAX_DEVS);
-
-	for (i = 0; i < n_devs; i++) {
-		ret = vivid_create_instance(pdev, i);
-		if (ret) {
-			/* If some instantiations succeeded, keep driver */
-			if (i)
-				ret = 0;
-			break;
-		}
-	}
-
-	if (ret < 0) {
-		pr_err("vivid: error %d while loading driver\n", ret);
-		return ret;
-	}
-
-	/* n_devs will reflect the actual number of allocated devices */
-	n_devs = i;
-
-	return ret;
-}
-
-static int vivid_remove(struct platform_device *pdev)
-{
-	struct vivid_dev *dev;
-	unsigned int i, j;
-
-	for (i = 0; i < n_devs; i++) {
-		dev = vivid_devs[i];
-		if (!dev)
-			continue;
-
-#ifdef CONFIG_MEDIA_CONTROLLER
-		media_device_unregister(&dev->mdev);
-#endif
-
-		if (dev->has_vid_cap) {
-			v4l2_info(&dev->v4l2_dev, "unregistering %s\n",
-				video_device_node_name(&dev->vid_cap_dev));
-			video_unregister_device(&dev->vid_cap_dev);
-		}
-		if (dev->has_vid_out) {
-			v4l2_info(&dev->v4l2_dev, "unregistering %s\n",
-				video_device_node_name(&dev->vid_out_dev));
-			video_unregister_device(&dev->vid_out_dev);
-		}
-		if (dev->has_vbi_cap) {
-			v4l2_info(&dev->v4l2_dev, "unregistering %s\n",
-				video_device_node_name(&dev->vbi_cap_dev));
-			video_unregister_device(&dev->vbi_cap_dev);
-		}
-		if (dev->has_vbi_out) {
-			v4l2_info(&dev->v4l2_dev, "unregistering %s\n",
-				video_device_node_name(&dev->vbi_out_dev));
-			video_unregister_device(&dev->vbi_out_dev);
-		}
-		if (dev->has_sdr_cap) {
-			v4l2_info(&dev->v4l2_dev, "unregistering %s\n",
-				video_device_node_name(&dev->sdr_cap_dev));
-			video_unregister_device(&dev->sdr_cap_dev);
-		}
-		if (dev->has_radio_rx) {
-			v4l2_info(&dev->v4l2_dev, "unregistering %s\n",
-				video_device_node_name(&dev->radio_rx_dev));
-			video_unregister_device(&dev->radio_rx_dev);
-		}
-		if (dev->has_radio_tx) {
-			v4l2_info(&dev->v4l2_dev, "unregistering %s\n",
-				video_device_node_name(&dev->radio_tx_dev));
-			video_unregister_device(&dev->radio_tx_dev);
-		}
-		if (dev->has_fb) {
-			v4l2_info(&dev->v4l2_dev, "unregistering fb%d\n",
-				dev->fb_info.node);
-			unregister_framebuffer(&dev->fb_info);
-			vivid_fb_release_buffers(dev);
-		}
-		if (dev->has_meta_cap) {
-			v4l2_info(&dev->v4l2_dev, "unregistering %s\n",
-				  video_device_node_name(&dev->meta_cap_dev));
-			video_unregister_device(&dev->meta_cap_dev);
-		}
-		if (dev->has_meta_out) {
-			v4l2_info(&dev->v4l2_dev, "unregistering %s\n",
-				  video_device_node_name(&dev->meta_out_dev));
-			video_unregister_device(&dev->meta_out_dev);
-		}
-		if (dev->has_touch_cap) {
-			v4l2_info(&dev->v4l2_dev, "unregistering %s\n",
-				  video_device_node_name(&dev->touch_cap_dev));
-			video_unregister_device(&dev->touch_cap_dev);
-		}
-		cec_unregister_adapter(dev->cec_rx_adap);
-		for (j = 0; j < MAX_OUTPUTS; j++)
-			cec_unregister_adapter(dev->cec_tx_adap[j]);
-		if (dev->cec_workqueue) {
-			vivid_cec_bus_free_work(dev);
-			destroy_workqueue(dev->cec_workqueue);
-		}
-		v4l2_device_put(&dev->v4l2_dev);
-		vivid_devs[i] = NULL;
-	}
-	return 0;
-}
-
-static void vivid_pdev_release(struct device *dev)
-{
-}
-
-static struct platform_device vivid_pdev = {
-	.name		= "vivid",
-	.dev.release	= vivid_pdev_release,
-};
-
-static struct platform_driver vivid_pdrv = {
-	.probe		= vivid_probe,
-	.remove		= vivid_remove,
-	.driver		= {
-		.name	= "vivid",
-	},
-};
-
-static int __init vivid_init(void)
-{
-	int ret;
-
-	ret = platform_device_register(&vivid_pdev);
-	if (ret)
-		return ret;
-
-	ret = platform_driver_register(&vivid_pdrv);
-	if (ret)
-		platform_device_unregister(&vivid_pdev);
-
-	return ret;
-}
-
-static void __exit vivid_exit(void)
-{
-	platform_driver_unregister(&vivid_pdrv);
-	platform_device_unregister(&vivid_pdev);
-}
-
-module_init(vivid_init);
-module_exit(vivid_exit);
diff --git a/drivers/media/platform/vivid/vivid-core.h b/drivers/media/platform/vivid/vivid-core.h
deleted file mode 100644
index 99e69b8f770f..000000000000
--- a/drivers/media/platform/vivid/vivid-core.h
+++ /dev/null
@@ -1,612 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * vivid-core.h - core datastructures
- *
- * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#ifndef _VIVID_CORE_H_
-#define _VIVID_CORE_H_
-
-#include <linux/fb.h>
-#include <linux/workqueue.h>
-#include <media/cec.h>
-#include <media/videobuf2-v4l2.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-dev.h>
-#include <media/v4l2-ctrls.h>
-#include <media/tpg/v4l2-tpg.h>
-#include "vivid-rds-gen.h"
-#include "vivid-vbi-gen.h"
-
-#define dprintk(dev, level, fmt, arg...) \
-	v4l2_dbg(level, vivid_debug, &dev->v4l2_dev, fmt, ## arg)
-
-/* The maximum number of clip rectangles */
-#define MAX_CLIPS  16
-/* The maximum number of inputs */
-#define MAX_INPUTS 16
-/* The maximum number of outputs */
-#define MAX_OUTPUTS 16
-/* The maximum up or down scaling factor is 4 */
-#define MAX_ZOOM  4
-/* The maximum image width/height are set to 4K DMT */
-#define MAX_WIDTH  4096
-#define MAX_HEIGHT 2160
-/* The minimum image width/height */
-#define MIN_WIDTH  16
-#define MIN_HEIGHT 16
-/* The data_offset of plane 0 for the multiplanar formats */
-#define PLANE0_DATA_OFFSET 128
-
-/* The supported TV frequency range in MHz */
-#define MIN_TV_FREQ (44U * 16U)
-#define MAX_TV_FREQ (958U * 16U)
-
-/* The number of samples returned in every SDR buffer */
-#define SDR_CAP_SAMPLES_PER_BUF 0x4000
-
-/* used by the threads to know when to resync internal counters */
-#define JIFFIES_PER_DAY (3600U * 24U * HZ)
-#define JIFFIES_RESYNC (JIFFIES_PER_DAY * (0xf0000000U / JIFFIES_PER_DAY))
-
-extern const struct v4l2_rect vivid_min_rect;
-extern const struct v4l2_rect vivid_max_rect;
-extern unsigned vivid_debug;
-
-struct vivid_fmt {
-	u32	fourcc;          /* v4l2 format id */
-	enum	tgp_color_enc color_enc;
-	bool	can_do_overlay;
-	u8	vdownsampling[TPG_MAX_PLANES];
-	u32	alpha_mask;
-	u8	planes;
-	u8	buffers;
-	u32	data_offset[TPG_MAX_PLANES];
-	u32	bit_depth[TPG_MAX_PLANES];
-};
-
-extern struct vivid_fmt vivid_formats[];
-
-/* buffer for one video frame */
-struct vivid_buffer {
-	/* common v4l buffer stuff -- must be first */
-	struct vb2_v4l2_buffer vb;
-	struct list_head	list;
-};
-
-enum vivid_input {
-	WEBCAM,
-	TV,
-	SVID,
-	HDMI,
-};
-
-enum vivid_signal_mode {
-	CURRENT_DV_TIMINGS,
-	CURRENT_STD = CURRENT_DV_TIMINGS,
-	NO_SIGNAL,
-	NO_LOCK,
-	OUT_OF_RANGE,
-	SELECTED_DV_TIMINGS,
-	SELECTED_STD = SELECTED_DV_TIMINGS,
-	CYCLE_DV_TIMINGS,
-	CYCLE_STD = CYCLE_DV_TIMINGS,
-	CUSTOM_DV_TIMINGS,
-};
-
-enum vivid_colorspace {
-	VIVID_CS_170M,
-	VIVID_CS_709,
-	VIVID_CS_SRGB,
-	VIVID_CS_OPRGB,
-	VIVID_CS_2020,
-	VIVID_CS_DCI_P3,
-	VIVID_CS_240M,
-	VIVID_CS_SYS_M,
-	VIVID_CS_SYS_BG,
-};
-
-#define VIVID_INVALID_SIGNAL(mode) \
-	((mode) == NO_SIGNAL || (mode) == NO_LOCK || (mode) == OUT_OF_RANGE)
-
-struct vivid_cec_work {
-	struct list_head	list;
-	struct delayed_work	work;
-	struct cec_adapter	*adap;
-	struct vivid_dev	*dev;
-	unsigned int		usecs;
-	unsigned int		timeout_ms;
-	u8			tx_status;
-	struct cec_msg		msg;
-};
-
-struct vivid_dev {
-	unsigned			inst;
-	struct v4l2_device		v4l2_dev;
-#ifdef CONFIG_MEDIA_CONTROLLER
-	struct media_device		mdev;
-	struct media_pad		vid_cap_pad;
-	struct media_pad		vid_out_pad;
-	struct media_pad		vbi_cap_pad;
-	struct media_pad		vbi_out_pad;
-	struct media_pad		sdr_cap_pad;
-	struct media_pad		meta_cap_pad;
-	struct media_pad		meta_out_pad;
-	struct media_pad		touch_cap_pad;
-#endif
-	struct v4l2_ctrl_handler	ctrl_hdl_user_gen;
-	struct v4l2_ctrl_handler	ctrl_hdl_user_vid;
-	struct v4l2_ctrl_handler	ctrl_hdl_user_aud;
-	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;
-	struct v4l2_ctrl_handler	ctrl_hdl_vid_out;
-	struct video_device		vbi_cap_dev;
-	struct v4l2_ctrl_handler	ctrl_hdl_vbi_cap;
-	struct video_device		vbi_out_dev;
-	struct v4l2_ctrl_handler	ctrl_hdl_vbi_out;
-	struct video_device		radio_rx_dev;
-	struct v4l2_ctrl_handler	ctrl_hdl_radio_rx;
-	struct video_device		radio_tx_dev;
-	struct v4l2_ctrl_handler	ctrl_hdl_radio_tx;
-	struct video_device		sdr_cap_dev;
-	struct v4l2_ctrl_handler	ctrl_hdl_sdr_cap;
-	struct video_device		meta_cap_dev;
-	struct v4l2_ctrl_handler	ctrl_hdl_meta_cap;
-	struct video_device		meta_out_dev;
-	struct v4l2_ctrl_handler	ctrl_hdl_meta_out;
-	struct video_device		touch_cap_dev;
-	struct v4l2_ctrl_handler	ctrl_hdl_touch_cap;
-
-	spinlock_t			slock;
-	struct mutex			mutex;
-
-	/* capabilities */
-	u32				vid_cap_caps;
-	u32				vid_out_caps;
-	u32				vbi_cap_caps;
-	u32				vbi_out_caps;
-	u32				sdr_cap_caps;
-	u32				radio_rx_caps;
-	u32				radio_tx_caps;
-	u32				meta_cap_caps;
-	u32				meta_out_caps;
-	u32				touch_cap_caps;
-
-	/* supported features */
-	bool				multiplanar;
-	unsigned			num_inputs;
-	unsigned int			num_hdmi_inputs;
-	u8				input_type[MAX_INPUTS];
-	u8				input_name_counter[MAX_INPUTS];
-	unsigned			num_outputs;
-	unsigned int			num_hdmi_outputs;
-	u8				output_type[MAX_OUTPUTS];
-	u8				output_name_counter[MAX_OUTPUTS];
-	bool				has_audio_inputs;
-	bool				has_audio_outputs;
-	bool				has_vid_cap;
-	bool				has_vid_out;
-	bool				has_vbi_cap;
-	bool				has_raw_vbi_cap;
-	bool				has_sliced_vbi_cap;
-	bool				has_vbi_out;
-	bool				has_raw_vbi_out;
-	bool				has_sliced_vbi_out;
-	bool				has_radio_rx;
-	bool				has_radio_tx;
-	bool				has_sdr_cap;
-	bool				has_fb;
-	bool				has_meta_cap;
-	bool				has_meta_out;
-	bool				has_tv_tuner;
-	bool				has_touch_cap;
-
-	bool				can_loop_video;
-
-	/* controls */
-	struct v4l2_ctrl		*brightness;
-	struct v4l2_ctrl		*contrast;
-	struct v4l2_ctrl		*saturation;
-	struct v4l2_ctrl		*hue;
-	struct {
-		/* autogain/gain cluster */
-		struct v4l2_ctrl	*autogain;
-		struct v4l2_ctrl	*gain;
-	};
-	struct v4l2_ctrl		*volume;
-	struct v4l2_ctrl		*mute;
-	struct v4l2_ctrl		*alpha;
-	struct v4l2_ctrl		*button;
-	struct v4l2_ctrl		*boolean;
-	struct v4l2_ctrl		*int32;
-	struct v4l2_ctrl		*int64;
-	struct v4l2_ctrl		*menu;
-	struct v4l2_ctrl		*string;
-	struct v4l2_ctrl		*bitmask;
-	struct v4l2_ctrl		*int_menu;
-	struct v4l2_ctrl		*test_pattern;
-	struct v4l2_ctrl		*colorspace;
-	struct v4l2_ctrl		*rgb_range_cap;
-	struct v4l2_ctrl		*real_rgb_range_cap;
-	struct {
-		/* std_signal_mode/standard cluster */
-		struct v4l2_ctrl	*ctrl_std_signal_mode;
-		struct v4l2_ctrl	*ctrl_standard;
-	};
-	struct {
-		/* dv_timings_signal_mode/timings cluster */
-		struct v4l2_ctrl	*ctrl_dv_timings_signal_mode;
-		struct v4l2_ctrl	*ctrl_dv_timings;
-	};
-	struct v4l2_ctrl		*ctrl_display_present;
-	struct v4l2_ctrl		*ctrl_has_crop_cap;
-	struct v4l2_ctrl		*ctrl_has_compose_cap;
-	struct v4l2_ctrl		*ctrl_has_scaler_cap;
-	struct v4l2_ctrl		*ctrl_has_crop_out;
-	struct v4l2_ctrl		*ctrl_has_compose_out;
-	struct v4l2_ctrl		*ctrl_has_scaler_out;
-	struct v4l2_ctrl		*ctrl_tx_mode;
-	struct v4l2_ctrl		*ctrl_tx_rgb_range;
-	struct v4l2_ctrl		*ctrl_tx_edid_present;
-	struct v4l2_ctrl		*ctrl_tx_hotplug;
-	struct v4l2_ctrl		*ctrl_tx_rxsense;
-
-	struct v4l2_ctrl		*ctrl_rx_power_present;
-
-	struct v4l2_ctrl		*radio_tx_rds_pi;
-	struct v4l2_ctrl		*radio_tx_rds_pty;
-	struct v4l2_ctrl		*radio_tx_rds_mono_stereo;
-	struct v4l2_ctrl		*radio_tx_rds_art_head;
-	struct v4l2_ctrl		*radio_tx_rds_compressed;
-	struct v4l2_ctrl		*radio_tx_rds_dyn_pty;
-	struct v4l2_ctrl		*radio_tx_rds_ta;
-	struct v4l2_ctrl		*radio_tx_rds_tp;
-	struct v4l2_ctrl		*radio_tx_rds_ms;
-	struct v4l2_ctrl		*radio_tx_rds_psname;
-	struct v4l2_ctrl		*radio_tx_rds_radiotext;
-
-	struct v4l2_ctrl		*radio_rx_rds_pty;
-	struct v4l2_ctrl		*radio_rx_rds_ta;
-	struct v4l2_ctrl		*radio_rx_rds_tp;
-	struct v4l2_ctrl		*radio_rx_rds_ms;
-	struct v4l2_ctrl		*radio_rx_rds_psname;
-	struct v4l2_ctrl		*radio_rx_rds_radiotext;
-
-	unsigned			input_brightness[MAX_INPUTS];
-	unsigned			osd_mode;
-	unsigned			button_pressed;
-	bool				sensor_hflip;
-	bool				sensor_vflip;
-	bool				hflip;
-	bool				vflip;
-	bool				vbi_cap_interlaced;
-	bool				loop_video;
-	bool				reduced_fps;
-
-	/* Framebuffer */
-	unsigned long			video_pbase;
-	void				*video_vbase;
-	u32				video_buffer_size;
-	int				display_width;
-	int				display_height;
-	int				display_byte_stride;
-	int				bits_per_pixel;
-	int				bytes_per_pixel;
-	struct fb_info			fb_info;
-	struct fb_var_screeninfo	fb_defined;
-	struct fb_fix_screeninfo	fb_fix;
-
-	/* Error injection */
-	bool				queue_setup_error;
-	bool				buf_prepare_error;
-	bool				start_streaming_error;
-	bool				dqbuf_error;
-	bool				req_validate_error;
-	bool				seq_wrap;
-	bool				time_wrap;
-	u64				time_wrap_offset;
-	unsigned			perc_dropped_buffers;
-	enum vivid_signal_mode		std_signal_mode[MAX_INPUTS];
-	unsigned int			query_std_last[MAX_INPUTS];
-	v4l2_std_id			query_std[MAX_INPUTS];
-	enum tpg_video_aspect		std_aspect_ratio[MAX_INPUTS];
-
-	enum vivid_signal_mode		dv_timings_signal_mode[MAX_INPUTS];
-	char				**query_dv_timings_qmenu;
-	char				*query_dv_timings_qmenu_strings;
-	unsigned			query_dv_timings_size;
-	unsigned int			query_dv_timings_last[MAX_INPUTS];
-	unsigned int			query_dv_timings[MAX_INPUTS];
-	enum tpg_video_aspect		dv_timings_aspect_ratio[MAX_INPUTS];
-
-	/* Input */
-	unsigned			input;
-	v4l2_std_id			std_cap[MAX_INPUTS];
-	struct v4l2_dv_timings		dv_timings_cap[MAX_INPUTS];
-	int				dv_timings_cap_sel[MAX_INPUTS];
-	u32				service_set_cap;
-	struct vivid_vbi_gen_data	vbi_gen;
-	u8				*edid;
-	unsigned			edid_blocks;
-	unsigned			edid_max_blocks;
-	unsigned			webcam_size_idx;
-	unsigned			webcam_ival_idx;
-	unsigned			tv_freq;
-	unsigned			tv_audmode;
-	unsigned			tv_field_cap;
-	unsigned			tv_audio_input;
-
-	u32				power_present;
-
-	/* Capture Overlay */
-	struct v4l2_framebuffer		fb_cap;
-	struct v4l2_fh			*overlay_cap_owner;
-	void				*fb_vbase_cap;
-	int				overlay_cap_top, overlay_cap_left;
-	enum v4l2_field			overlay_cap_field;
-	void				*bitmap_cap;
-	struct v4l2_clip		clips_cap[MAX_CLIPS];
-	struct v4l2_clip		try_clips_cap[MAX_CLIPS];
-	unsigned			clipcount_cap;
-
-	/* Output */
-	unsigned			output;
-	v4l2_std_id			std_out;
-	struct v4l2_dv_timings		dv_timings_out;
-	u32				colorspace_out;
-	u32				ycbcr_enc_out;
-	u32				hsv_enc_out;
-	u32				quantization_out;
-	u32				xfer_func_out;
-	u32				service_set_out;
-	unsigned			bytesperline_out[TPG_MAX_PLANES];
-	unsigned			tv_field_out;
-	unsigned			tv_audio_output;
-	bool				vbi_out_have_wss;
-	u8				vbi_out_wss[2];
-	bool				vbi_out_have_cc[2];
-	u8				vbi_out_cc[2][2];
-	bool				dvi_d_out;
-	u8				*scaled_line;
-	u8				*blended_line;
-	unsigned			cur_scaled_line;
-	bool				display_present[MAX_OUTPUTS];
-
-	/* Output Overlay */
-	void				*fb_vbase_out;
-	bool				overlay_out_enabled;
-	int				overlay_out_top, overlay_out_left;
-	void				*bitmap_out;
-	struct v4l2_clip		clips_out[MAX_CLIPS];
-	struct v4l2_clip		try_clips_out[MAX_CLIPS];
-	unsigned			clipcount_out;
-	unsigned			fbuf_out_flags;
-	u32				chromakey_out;
-	u8				global_alpha_out;
-
-	/* video capture */
-	struct tpg_data			tpg;
-	unsigned			ms_vid_cap;
-	bool				must_blank[VIDEO_MAX_FRAME];
-
-	const struct vivid_fmt		*fmt_cap;
-	struct v4l2_fract		timeperframe_vid_cap;
-	enum v4l2_field			field_cap;
-	struct v4l2_rect		src_rect;
-	struct v4l2_rect		fmt_cap_rect;
-	struct v4l2_rect		crop_cap;
-	struct v4l2_rect		compose_cap;
-	struct v4l2_rect		crop_bounds_cap;
-	struct vb2_queue		vb_vid_cap_q;
-	struct list_head		vid_cap_active;
-	struct vb2_queue		vb_vbi_cap_q;
-	struct list_head		vbi_cap_active;
-	struct vb2_queue		vb_meta_cap_q;
-	struct list_head		meta_cap_active;
-	struct vb2_queue		vb_touch_cap_q;
-	struct list_head		touch_cap_active;
-
-	/* thread for generating video capture stream */
-	struct task_struct		*kthread_vid_cap;
-	unsigned long			jiffies_vid_cap;
-	u64				cap_stream_start;
-	u64				cap_frame_period;
-	u64				cap_frame_eof_offset;
-	u32				cap_seq_offset;
-	u32				cap_seq_count;
-	bool				cap_seq_resync;
-	u32				vid_cap_seq_start;
-	u32				vid_cap_seq_count;
-	bool				vid_cap_streaming;
-	u32				vbi_cap_seq_start;
-	u32				vbi_cap_seq_count;
-	bool				vbi_cap_streaming;
-	bool				stream_sliced_vbi_cap;
-	u32				meta_cap_seq_start;
-	u32				meta_cap_seq_count;
-	bool				meta_cap_streaming;
-
-	/* Touch capture */
-	struct task_struct		*kthread_touch_cap;
-	unsigned long			jiffies_touch_cap;
-	u64				touch_cap_stream_start;
-	u32				touch_cap_seq_offset;
-	bool				touch_cap_seq_resync;
-	u32				touch_cap_seq_start;
-	u32				touch_cap_seq_count;
-	bool				touch_cap_streaming;
-	struct v4l2_fract		timeperframe_tch_cap;
-	struct v4l2_pix_format		tch_format;
-	int				tch_pat_random;
-
-	/* video output */
-	const struct vivid_fmt		*fmt_out;
-	struct v4l2_fract		timeperframe_vid_out;
-	enum v4l2_field			field_out;
-	struct v4l2_rect		sink_rect;
-	struct v4l2_rect		fmt_out_rect;
-	struct v4l2_rect		crop_out;
-	struct v4l2_rect		compose_out;
-	struct v4l2_rect		compose_bounds_out;
-	struct vb2_queue		vb_vid_out_q;
-	struct list_head		vid_out_active;
-	struct vb2_queue		vb_vbi_out_q;
-	struct list_head		vbi_out_active;
-	struct vb2_queue		vb_meta_out_q;
-	struct list_head		meta_out_active;
-
-	/* video loop precalculated rectangles */
-
-	/*
-	 * Intersection between what the output side composes and the capture side
-	 * crops. I.e., what actually needs to be copied from the output buffer to
-	 * the capture buffer.
-	 */
-	struct v4l2_rect		loop_vid_copy;
-	/* The part of the output buffer that (after scaling) corresponds to loop_vid_copy. */
-	struct v4l2_rect		loop_vid_out;
-	/* The part of the capture buffer that (after scaling) corresponds to loop_vid_copy. */
-	struct v4l2_rect		loop_vid_cap;
-	/*
-	 * The intersection of the framebuffer, the overlay output window and
-	 * loop_vid_copy. I.e., the part of the framebuffer that actually should be
-	 * blended with the compose_out rectangle. This uses the framebuffer origin.
-	 */
-	struct v4l2_rect		loop_fb_copy;
-	/* The same as loop_fb_copy but with compose_out origin. */
-	struct v4l2_rect		loop_vid_overlay;
-	/*
-	 * The part of the capture buffer that (after scaling) corresponds
-	 * to loop_vid_overlay.
-	 */
-	struct v4l2_rect		loop_vid_overlay_cap;
-
-	/* thread for generating video output stream */
-	struct task_struct		*kthread_vid_out;
-	unsigned long			jiffies_vid_out;
-	u32				out_seq_offset;
-	u32				out_seq_count;
-	bool				out_seq_resync;
-	u32				vid_out_seq_start;
-	u32				vid_out_seq_count;
-	bool				vid_out_streaming;
-	u32				vbi_out_seq_start;
-	u32				vbi_out_seq_count;
-	bool				vbi_out_streaming;
-	bool				stream_sliced_vbi_out;
-	u32				meta_out_seq_start;
-	u32				meta_out_seq_count;
-	bool				meta_out_streaming;
-
-	/* SDR capture */
-	struct vb2_queue		vb_sdr_cap_q;
-	struct list_head		sdr_cap_active;
-	u32				sdr_pixelformat; /* v4l2 format id */
-	unsigned			sdr_buffersize;
-	unsigned			sdr_adc_freq;
-	unsigned			sdr_fm_freq;
-	unsigned			sdr_fm_deviation;
-	int				sdr_fixp_src_phase;
-	int				sdr_fixp_mod_phase;
-
-	bool				tstamp_src_is_soe;
-	bool				has_crop_cap;
-	bool				has_compose_cap;
-	bool				has_scaler_cap;
-	bool				has_crop_out;
-	bool				has_compose_out;
-	bool				has_scaler_out;
-
-	/* thread for generating SDR stream */
-	struct task_struct		*kthread_sdr_cap;
-	unsigned long			jiffies_sdr_cap;
-	u32				sdr_cap_seq_offset;
-	u32				sdr_cap_seq_count;
-	bool				sdr_cap_seq_resync;
-
-	/* RDS generator */
-	struct vivid_rds_gen		rds_gen;
-
-	/* Radio receiver */
-	unsigned			radio_rx_freq;
-	unsigned			radio_rx_audmode;
-	int				radio_rx_sig_qual;
-	unsigned			radio_rx_hw_seek_mode;
-	bool				radio_rx_hw_seek_prog_lim;
-	bool				radio_rx_rds_controls;
-	bool				radio_rx_rds_enabled;
-	unsigned			radio_rx_rds_use_alternates;
-	unsigned			radio_rx_rds_last_block;
-	struct v4l2_fh			*radio_rx_rds_owner;
-
-	/* Radio transmitter */
-	unsigned			radio_tx_freq;
-	unsigned			radio_tx_subchans;
-	bool				radio_tx_rds_controls;
-	unsigned			radio_tx_rds_last_block;
-	struct v4l2_fh			*radio_tx_rds_owner;
-
-	/* Shared between radio receiver and transmitter */
-	bool				radio_rds_loop;
-	ktime_t				radio_rds_init_time;
-
-	/* CEC */
-	struct cec_adapter		*cec_rx_adap;
-	struct cec_adapter		*cec_tx_adap[MAX_OUTPUTS];
-	struct workqueue_struct		*cec_workqueue;
-	spinlock_t			cec_slock;
-	struct list_head		cec_work_list;
-	unsigned int			cec_xfer_time_jiffies;
-	unsigned long			cec_xfer_start_jiffies;
-	u8				cec_output2bus_map[MAX_OUTPUTS];
-
-	/* CEC OSD String */
-	char				osd[14];
-	unsigned long			osd_jiffies;
-
-	bool				meta_pts;
-	bool				meta_scr;
-};
-
-static inline bool vivid_is_webcam(const struct vivid_dev *dev)
-{
-	return dev->input_type[dev->input] == WEBCAM;
-}
-
-static inline bool vivid_is_tv_cap(const struct vivid_dev *dev)
-{
-	return dev->input_type[dev->input] == TV;
-}
-
-static inline bool vivid_is_svid_cap(const struct vivid_dev *dev)
-{
-	return dev->input_type[dev->input] == SVID;
-}
-
-static inline bool vivid_is_hdmi_cap(const struct vivid_dev *dev)
-{
-	return dev->input_type[dev->input] == HDMI;
-}
-
-static inline bool vivid_is_sdtv_cap(const struct vivid_dev *dev)
-{
-	return vivid_is_tv_cap(dev) || vivid_is_svid_cap(dev);
-}
-
-static inline bool vivid_is_svid_out(const struct vivid_dev *dev)
-{
-	return dev->output_type[dev->output] == SVID;
-}
-
-static inline bool vivid_is_hdmi_out(const struct vivid_dev *dev)
-{
-	return dev->output_type[dev->output] == HDMI;
-}
-
-#endif
diff --git a/drivers/media/platform/vivid/vivid-ctrls.c b/drivers/media/platform/vivid/vivid-ctrls.c
deleted file mode 100644
index 334130568dcb..000000000000
--- a/drivers/media/platform/vivid/vivid-ctrls.c
+++ /dev/null
@@ -1,1939 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * vivid-ctrls.c - control support functions.
- *
- * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-event.h>
-#include <media/v4l2-common.h>
-
-#include "vivid-core.h"
-#include "vivid-vid-cap.h"
-#include "vivid-vid-out.h"
-#include "vivid-vid-common.h"
-#include "vivid-radio-common.h"
-#include "vivid-osd.h"
-#include "vivid-ctrls.h"
-#include "vivid-cec.h"
-
-#define VIVID_CID_CUSTOM_BASE		(V4L2_CID_USER_BASE | 0xf000)
-#define VIVID_CID_BUTTON		(VIVID_CID_CUSTOM_BASE + 0)
-#define VIVID_CID_BOOLEAN		(VIVID_CID_CUSTOM_BASE + 1)
-#define VIVID_CID_INTEGER		(VIVID_CID_CUSTOM_BASE + 2)
-#define VIVID_CID_INTEGER64		(VIVID_CID_CUSTOM_BASE + 3)
-#define VIVID_CID_MENU			(VIVID_CID_CUSTOM_BASE + 4)
-#define VIVID_CID_STRING		(VIVID_CID_CUSTOM_BASE + 5)
-#define VIVID_CID_BITMASK		(VIVID_CID_CUSTOM_BASE + 6)
-#define VIVID_CID_INTMENU		(VIVID_CID_CUSTOM_BASE + 7)
-#define VIVID_CID_U32_ARRAY		(VIVID_CID_CUSTOM_BASE + 8)
-#define VIVID_CID_U16_MATRIX		(VIVID_CID_CUSTOM_BASE + 9)
-#define VIVID_CID_U8_4D_ARRAY		(VIVID_CID_CUSTOM_BASE + 10)
-#define VIVID_CID_AREA			(VIVID_CID_CUSTOM_BASE + 11)
-
-#define VIVID_CID_VIVID_BASE		(0x00f00000 | 0xf000)
-#define VIVID_CID_VIVID_CLASS		(0x00f00000 | 1)
-#define VIVID_CID_TEST_PATTERN		(VIVID_CID_VIVID_BASE + 0)
-#define VIVID_CID_OSD_TEXT_MODE		(VIVID_CID_VIVID_BASE + 1)
-#define VIVID_CID_HOR_MOVEMENT		(VIVID_CID_VIVID_BASE + 2)
-#define VIVID_CID_VERT_MOVEMENT		(VIVID_CID_VIVID_BASE + 3)
-#define VIVID_CID_SHOW_BORDER		(VIVID_CID_VIVID_BASE + 4)
-#define VIVID_CID_SHOW_SQUARE		(VIVID_CID_VIVID_BASE + 5)
-#define VIVID_CID_INSERT_SAV		(VIVID_CID_VIVID_BASE + 6)
-#define VIVID_CID_INSERT_EAV		(VIVID_CID_VIVID_BASE + 7)
-#define VIVID_CID_VBI_CAP_INTERLACED	(VIVID_CID_VIVID_BASE + 8)
-
-#define VIVID_CID_HFLIP			(VIVID_CID_VIVID_BASE + 20)
-#define VIVID_CID_VFLIP			(VIVID_CID_VIVID_BASE + 21)
-#define VIVID_CID_STD_ASPECT_RATIO	(VIVID_CID_VIVID_BASE + 22)
-#define VIVID_CID_DV_TIMINGS_ASPECT_RATIO	(VIVID_CID_VIVID_BASE + 23)
-#define VIVID_CID_TSTAMP_SRC		(VIVID_CID_VIVID_BASE + 24)
-#define VIVID_CID_COLORSPACE		(VIVID_CID_VIVID_BASE + 25)
-#define VIVID_CID_XFER_FUNC		(VIVID_CID_VIVID_BASE + 26)
-#define VIVID_CID_YCBCR_ENC		(VIVID_CID_VIVID_BASE + 27)
-#define VIVID_CID_QUANTIZATION		(VIVID_CID_VIVID_BASE + 28)
-#define VIVID_CID_LIMITED_RGB_RANGE	(VIVID_CID_VIVID_BASE + 29)
-#define VIVID_CID_ALPHA_MODE		(VIVID_CID_VIVID_BASE + 30)
-#define VIVID_CID_HAS_CROP_CAP		(VIVID_CID_VIVID_BASE + 31)
-#define VIVID_CID_HAS_COMPOSE_CAP	(VIVID_CID_VIVID_BASE + 32)
-#define VIVID_CID_HAS_SCALER_CAP	(VIVID_CID_VIVID_BASE + 33)
-#define VIVID_CID_HAS_CROP_OUT		(VIVID_CID_VIVID_BASE + 34)
-#define VIVID_CID_HAS_COMPOSE_OUT	(VIVID_CID_VIVID_BASE + 35)
-#define VIVID_CID_HAS_SCALER_OUT	(VIVID_CID_VIVID_BASE + 36)
-#define VIVID_CID_LOOP_VIDEO		(VIVID_CID_VIVID_BASE + 37)
-#define VIVID_CID_SEQ_WRAP		(VIVID_CID_VIVID_BASE + 38)
-#define VIVID_CID_TIME_WRAP		(VIVID_CID_VIVID_BASE + 39)
-#define VIVID_CID_MAX_EDID_BLOCKS	(VIVID_CID_VIVID_BASE + 40)
-#define VIVID_CID_PERCENTAGE_FILL	(VIVID_CID_VIVID_BASE + 41)
-#define VIVID_CID_REDUCED_FPS		(VIVID_CID_VIVID_BASE + 42)
-#define VIVID_CID_HSV_ENC		(VIVID_CID_VIVID_BASE + 43)
-#define VIVID_CID_DISPLAY_PRESENT	(VIVID_CID_VIVID_BASE + 44)
-
-#define VIVID_CID_STD_SIGNAL_MODE	(VIVID_CID_VIVID_BASE + 60)
-#define VIVID_CID_STANDARD		(VIVID_CID_VIVID_BASE + 61)
-#define VIVID_CID_DV_TIMINGS_SIGNAL_MODE	(VIVID_CID_VIVID_BASE + 62)
-#define VIVID_CID_DV_TIMINGS		(VIVID_CID_VIVID_BASE + 63)
-#define VIVID_CID_PERC_DROPPED		(VIVID_CID_VIVID_BASE + 64)
-#define VIVID_CID_DISCONNECT		(VIVID_CID_VIVID_BASE + 65)
-#define VIVID_CID_DQBUF_ERROR		(VIVID_CID_VIVID_BASE + 66)
-#define VIVID_CID_QUEUE_SETUP_ERROR	(VIVID_CID_VIVID_BASE + 67)
-#define VIVID_CID_BUF_PREPARE_ERROR	(VIVID_CID_VIVID_BASE + 68)
-#define VIVID_CID_START_STR_ERROR	(VIVID_CID_VIVID_BASE + 69)
-#define VIVID_CID_QUEUE_ERROR		(VIVID_CID_VIVID_BASE + 70)
-#define VIVID_CID_CLEAR_FB		(VIVID_CID_VIVID_BASE + 71)
-#define VIVID_CID_REQ_VALIDATE_ERROR	(VIVID_CID_VIVID_BASE + 72)
-
-#define VIVID_CID_RADIO_SEEK_MODE	(VIVID_CID_VIVID_BASE + 90)
-#define VIVID_CID_RADIO_SEEK_PROG_LIM	(VIVID_CID_VIVID_BASE + 91)
-#define VIVID_CID_RADIO_RX_RDS_RBDS	(VIVID_CID_VIVID_BASE + 92)
-#define VIVID_CID_RADIO_RX_RDS_BLOCKIO	(VIVID_CID_VIVID_BASE + 93)
-
-#define VIVID_CID_RADIO_TX_RDS_BLOCKIO	(VIVID_CID_VIVID_BASE + 94)
-
-#define VIVID_CID_SDR_CAP_FM_DEVIATION	(VIVID_CID_VIVID_BASE + 110)
-
-#define VIVID_CID_META_CAP_GENERATE_PTS	(VIVID_CID_VIVID_BASE + 111)
-#define VIVID_CID_META_CAP_GENERATE_SCR	(VIVID_CID_VIVID_BASE + 112)
-
-/* General User Controls */
-
-static int vivid_user_gen_s_ctrl(struct v4l2_ctrl *ctrl)
-{
-	struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_user_gen);
-
-	switch (ctrl->id) {
-	case VIVID_CID_DISCONNECT:
-		v4l2_info(&dev->v4l2_dev, "disconnect\n");
-		clear_bit(V4L2_FL_REGISTERED, &dev->vid_cap_dev.flags);
-		clear_bit(V4L2_FL_REGISTERED, &dev->vid_out_dev.flags);
-		clear_bit(V4L2_FL_REGISTERED, &dev->vbi_cap_dev.flags);
-		clear_bit(V4L2_FL_REGISTERED, &dev->vbi_out_dev.flags);
-		clear_bit(V4L2_FL_REGISTERED, &dev->sdr_cap_dev.flags);
-		clear_bit(V4L2_FL_REGISTERED, &dev->radio_rx_dev.flags);
-		clear_bit(V4L2_FL_REGISTERED, &dev->radio_tx_dev.flags);
-		clear_bit(V4L2_FL_REGISTERED, &dev->meta_cap_dev.flags);
-		break;
-	case VIVID_CID_BUTTON:
-		dev->button_pressed = 30;
-		break;
-	}
-	return 0;
-}
-
-static const struct v4l2_ctrl_ops vivid_user_gen_ctrl_ops = {
-	.s_ctrl = vivid_user_gen_s_ctrl,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_button = {
-	.ops = &vivid_user_gen_ctrl_ops,
-	.id = VIVID_CID_BUTTON,
-	.name = "Button",
-	.type = V4L2_CTRL_TYPE_BUTTON,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_boolean = {
-	.ops = &vivid_user_gen_ctrl_ops,
-	.id = VIVID_CID_BOOLEAN,
-	.name = "Boolean",
-	.type = V4L2_CTRL_TYPE_BOOLEAN,
-	.min = 0,
-	.max = 1,
-	.step = 1,
-	.def = 1,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_int32 = {
-	.ops = &vivid_user_gen_ctrl_ops,
-	.id = VIVID_CID_INTEGER,
-	.name = "Integer 32 Bits",
-	.type = V4L2_CTRL_TYPE_INTEGER,
-	.min = 0xffffffff80000000ULL,
-	.max = 0x7fffffff,
-	.step = 1,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_int64 = {
-	.ops = &vivid_user_gen_ctrl_ops,
-	.id = VIVID_CID_INTEGER64,
-	.name = "Integer 64 Bits",
-	.type = V4L2_CTRL_TYPE_INTEGER64,
-	.min = 0x8000000000000000ULL,
-	.max = 0x7fffffffffffffffLL,
-	.step = 1,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_u32_array = {
-	.ops = &vivid_user_gen_ctrl_ops,
-	.id = VIVID_CID_U32_ARRAY,
-	.name = "U32 1 Element Array",
-	.type = V4L2_CTRL_TYPE_U32,
-	.def = 0x18,
-	.min = 0x10,
-	.max = 0x20000,
-	.step = 1,
-	.dims = { 1 },
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_u16_matrix = {
-	.ops = &vivid_user_gen_ctrl_ops,
-	.id = VIVID_CID_U16_MATRIX,
-	.name = "U16 8x16 Matrix",
-	.type = V4L2_CTRL_TYPE_U16,
-	.def = 0x18,
-	.min = 0x10,
-	.max = 0x2000,
-	.step = 1,
-	.dims = { 8, 16 },
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_u8_4d_array = {
-	.ops = &vivid_user_gen_ctrl_ops,
-	.id = VIVID_CID_U8_4D_ARRAY,
-	.name = "U8 2x3x4x5 Array",
-	.type = V4L2_CTRL_TYPE_U8,
-	.def = 0x18,
-	.min = 0x10,
-	.max = 0x20,
-	.step = 1,
-	.dims = { 2, 3, 4, 5 },
-};
-
-static const char * const vivid_ctrl_menu_strings[] = {
-	"Menu Item 0 (Skipped)",
-	"Menu Item 1",
-	"Menu Item 2 (Skipped)",
-	"Menu Item 3",
-	"Menu Item 4",
-	"Menu Item 5 (Skipped)",
-	NULL,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_menu = {
-	.ops = &vivid_user_gen_ctrl_ops,
-	.id = VIVID_CID_MENU,
-	.name = "Menu",
-	.type = V4L2_CTRL_TYPE_MENU,
-	.min = 1,
-	.max = 4,
-	.def = 3,
-	.menu_skip_mask = 0x04,
-	.qmenu = vivid_ctrl_menu_strings,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_string = {
-	.ops = &vivid_user_gen_ctrl_ops,
-	.id = VIVID_CID_STRING,
-	.name = "String",
-	.type = V4L2_CTRL_TYPE_STRING,
-	.min = 2,
-	.max = 4,
-	.step = 1,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_bitmask = {
-	.ops = &vivid_user_gen_ctrl_ops,
-	.id = VIVID_CID_BITMASK,
-	.name = "Bitmask",
-	.type = V4L2_CTRL_TYPE_BITMASK,
-	.def = 0x80002000,
-	.min = 0,
-	.max = 0x80402010,
-	.step = 0,
-};
-
-static const s64 vivid_ctrl_int_menu_values[] = {
-	1, 1, 2, 3, 5, 8, 13, 21, 42,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_int_menu = {
-	.ops = &vivid_user_gen_ctrl_ops,
-	.id = VIVID_CID_INTMENU,
-	.name = "Integer Menu",
-	.type = V4L2_CTRL_TYPE_INTEGER_MENU,
-	.min = 1,
-	.max = 8,
-	.def = 4,
-	.menu_skip_mask = 0x02,
-	.qmenu_int = vivid_ctrl_int_menu_values,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_disconnect = {
-	.ops = &vivid_user_gen_ctrl_ops,
-	.id = VIVID_CID_DISCONNECT,
-	.name = "Disconnect",
-	.type = V4L2_CTRL_TYPE_BUTTON,
-};
-
-static const struct v4l2_area area = {
-	.width = 1000,
-	.height = 2000,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_area = {
-	.ops = &vivid_user_gen_ctrl_ops,
-	.id = VIVID_CID_AREA,
-	.name = "Area",
-	.type = V4L2_CTRL_TYPE_AREA,
-	.p_def.p_const = &area,
-};
-
-/* 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_fb_ctrl_ops,
-	.id = VIVID_CID_CLEAR_FB,
-	.name = "Clear Framebuffer",
-	.type = V4L2_CTRL_TYPE_BUTTON,
-};
-
-
-/* Video User Controls */
-
-static int vivid_user_vid_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
-{
-	struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_user_vid);
-
-	switch (ctrl->id) {
-	case V4L2_CID_AUTOGAIN:
-		dev->gain->val = (jiffies_to_msecs(jiffies) / 1000) & 0xff;
-		break;
-	}
-	return 0;
-}
-
-static int vivid_user_vid_s_ctrl(struct v4l2_ctrl *ctrl)
-{
-	struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_user_vid);
-
-	switch (ctrl->id) {
-	case V4L2_CID_BRIGHTNESS:
-		dev->input_brightness[dev->input] = ctrl->val - dev->input * 128;
-		tpg_s_brightness(&dev->tpg, dev->input_brightness[dev->input]);
-		break;
-	case V4L2_CID_CONTRAST:
-		tpg_s_contrast(&dev->tpg, ctrl->val);
-		break;
-	case V4L2_CID_SATURATION:
-		tpg_s_saturation(&dev->tpg, ctrl->val);
-		break;
-	case V4L2_CID_HUE:
-		tpg_s_hue(&dev->tpg, ctrl->val);
-		break;
-	case V4L2_CID_HFLIP:
-		dev->hflip = ctrl->val;
-		tpg_s_hflip(&dev->tpg, dev->sensor_hflip ^ dev->hflip);
-		break;
-	case V4L2_CID_VFLIP:
-		dev->vflip = ctrl->val;
-		tpg_s_vflip(&dev->tpg, dev->sensor_vflip ^ dev->vflip);
-		break;
-	case V4L2_CID_ALPHA_COMPONENT:
-		tpg_s_alpha_component(&dev->tpg, ctrl->val);
-		break;
-	}
-	return 0;
-}
-
-static const struct v4l2_ctrl_ops vivid_user_vid_ctrl_ops = {
-	.g_volatile_ctrl = vivid_user_vid_g_volatile_ctrl,
-	.s_ctrl = vivid_user_vid_s_ctrl,
-};
-
-
-/* Video Capture Controls */
-
-static int vivid_vid_cap_s_ctrl(struct v4l2_ctrl *ctrl)
-{
-	static const u32 colorspaces[] = {
-		V4L2_COLORSPACE_SMPTE170M,
-		V4L2_COLORSPACE_REC709,
-		V4L2_COLORSPACE_SRGB,
-		V4L2_COLORSPACE_OPRGB,
-		V4L2_COLORSPACE_BT2020,
-		V4L2_COLORSPACE_DCI_P3,
-		V4L2_COLORSPACE_SMPTE240M,
-		V4L2_COLORSPACE_470_SYSTEM_M,
-		V4L2_COLORSPACE_470_SYSTEM_BG,
-	};
-	struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_vid_cap);
-	unsigned int i, j;
-
-	switch (ctrl->id) {
-	case VIVID_CID_TEST_PATTERN:
-		vivid_update_quality(dev);
-		tpg_s_pattern(&dev->tpg, ctrl->val);
-		break;
-	case VIVID_CID_COLORSPACE:
-		tpg_s_colorspace(&dev->tpg, colorspaces[ctrl->val]);
-		vivid_send_source_change(dev, TV);
-		vivid_send_source_change(dev, SVID);
-		vivid_send_source_change(dev, HDMI);
-		vivid_send_source_change(dev, WEBCAM);
-		break;
-	case VIVID_CID_XFER_FUNC:
-		tpg_s_xfer_func(&dev->tpg, ctrl->val);
-		vivid_send_source_change(dev, TV);
-		vivid_send_source_change(dev, SVID);
-		vivid_send_source_change(dev, HDMI);
-		vivid_send_source_change(dev, WEBCAM);
-		break;
-	case VIVID_CID_YCBCR_ENC:
-		tpg_s_ycbcr_enc(&dev->tpg, ctrl->val);
-		vivid_send_source_change(dev, TV);
-		vivid_send_source_change(dev, SVID);
-		vivid_send_source_change(dev, HDMI);
-		vivid_send_source_change(dev, WEBCAM);
-		break;
-	case VIVID_CID_HSV_ENC:
-		tpg_s_hsv_enc(&dev->tpg, ctrl->val ? V4L2_HSV_ENC_256 :
-						     V4L2_HSV_ENC_180);
-		vivid_send_source_change(dev, TV);
-		vivid_send_source_change(dev, SVID);
-		vivid_send_source_change(dev, HDMI);
-		vivid_send_source_change(dev, WEBCAM);
-		break;
-	case VIVID_CID_QUANTIZATION:
-		tpg_s_quantization(&dev->tpg, ctrl->val);
-		vivid_send_source_change(dev, TV);
-		vivid_send_source_change(dev, SVID);
-		vivid_send_source_change(dev, HDMI);
-		vivid_send_source_change(dev, WEBCAM);
-		break;
-	case V4L2_CID_DV_RX_RGB_RANGE:
-		if (!vivid_is_hdmi_cap(dev))
-			break;
-		tpg_s_rgb_range(&dev->tpg, ctrl->val);
-		break;
-	case VIVID_CID_LIMITED_RGB_RANGE:
-		tpg_s_real_rgb_range(&dev->tpg, ctrl->val ?
-				V4L2_DV_RGB_RANGE_LIMITED : V4L2_DV_RGB_RANGE_FULL);
-		break;
-	case VIVID_CID_ALPHA_MODE:
-		tpg_s_alpha_mode(&dev->tpg, ctrl->val);
-		break;
-	case VIVID_CID_HOR_MOVEMENT:
-		tpg_s_mv_hor_mode(&dev->tpg, ctrl->val);
-		break;
-	case VIVID_CID_VERT_MOVEMENT:
-		tpg_s_mv_vert_mode(&dev->tpg, ctrl->val);
-		break;
-	case VIVID_CID_OSD_TEXT_MODE:
-		dev->osd_mode = ctrl->val;
-		break;
-	case VIVID_CID_PERCENTAGE_FILL:
-		tpg_s_perc_fill(&dev->tpg, ctrl->val);
-		for (i = 0; i < VIDEO_MAX_FRAME; i++)
-			dev->must_blank[i] = ctrl->val < 100;
-		break;
-	case VIVID_CID_INSERT_SAV:
-		tpg_s_insert_sav(&dev->tpg, ctrl->val);
-		break;
-	case VIVID_CID_INSERT_EAV:
-		tpg_s_insert_eav(&dev->tpg, ctrl->val);
-		break;
-	case VIVID_CID_HFLIP:
-		dev->sensor_hflip = ctrl->val;
-		tpg_s_hflip(&dev->tpg, dev->sensor_hflip ^ dev->hflip);
-		break;
-	case VIVID_CID_VFLIP:
-		dev->sensor_vflip = ctrl->val;
-		tpg_s_vflip(&dev->tpg, dev->sensor_vflip ^ dev->vflip);
-		break;
-	case VIVID_CID_REDUCED_FPS:
-		dev->reduced_fps = ctrl->val;
-		vivid_update_format_cap(dev, true);
-		break;
-	case VIVID_CID_HAS_CROP_CAP:
-		dev->has_crop_cap = ctrl->val;
-		vivid_update_format_cap(dev, true);
-		break;
-	case VIVID_CID_HAS_COMPOSE_CAP:
-		dev->has_compose_cap = ctrl->val;
-		vivid_update_format_cap(dev, true);
-		break;
-	case VIVID_CID_HAS_SCALER_CAP:
-		dev->has_scaler_cap = ctrl->val;
-		vivid_update_format_cap(dev, true);
-		break;
-	case VIVID_CID_SHOW_BORDER:
-		tpg_s_show_border(&dev->tpg, ctrl->val);
-		break;
-	case VIVID_CID_SHOW_SQUARE:
-		tpg_s_show_square(&dev->tpg, ctrl->val);
-		break;
-	case VIVID_CID_STD_ASPECT_RATIO:
-		dev->std_aspect_ratio[dev->input] = ctrl->val;
-		tpg_s_video_aspect(&dev->tpg, vivid_get_video_aspect(dev));
-		break;
-	case VIVID_CID_DV_TIMINGS_SIGNAL_MODE:
-		dev->dv_timings_signal_mode[dev->input] =
-			dev->ctrl_dv_timings_signal_mode->val;
-		dev->query_dv_timings[dev->input] = dev->ctrl_dv_timings->val;
-
-		dev->power_present = 0;
-		for (i = 0, j = 0;
-		     i < ARRAY_SIZE(dev->dv_timings_signal_mode);
-		     i++)
-			if (dev->input_type[i] == HDMI) {
-				if (dev->dv_timings_signal_mode[i] != NO_SIGNAL)
-					dev->power_present |= (1 << j);
-				j++;
-			}
-		__v4l2_ctrl_s_ctrl(dev->ctrl_rx_power_present,
-				   dev->power_present);
-
-		v4l2_ctrl_activate(dev->ctrl_dv_timings,
-			dev->dv_timings_signal_mode[dev->input] ==
-				SELECTED_DV_TIMINGS);
-
-		vivid_update_quality(dev);
-		vivid_send_source_change(dev, HDMI);
-		break;
-	case VIVID_CID_DV_TIMINGS_ASPECT_RATIO:
-		dev->dv_timings_aspect_ratio[dev->input] = ctrl->val;
-		tpg_s_video_aspect(&dev->tpg, vivid_get_video_aspect(dev));
-		break;
-	case VIVID_CID_TSTAMP_SRC:
-		dev->tstamp_src_is_soe = ctrl->val;
-		dev->vb_vid_cap_q.timestamp_flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
-		if (dev->tstamp_src_is_soe)
-			dev->vb_vid_cap_q.timestamp_flags |= V4L2_BUF_FLAG_TSTAMP_SRC_SOE;
-		break;
-	case VIVID_CID_MAX_EDID_BLOCKS:
-		dev->edid_max_blocks = ctrl->val;
-		if (dev->edid_blocks > dev->edid_max_blocks)
-			dev->edid_blocks = dev->edid_max_blocks;
-		break;
-	}
-	return 0;
-}
-
-static const struct v4l2_ctrl_ops vivid_vid_cap_ctrl_ops = {
-	.s_ctrl = vivid_vid_cap_s_ctrl,
-};
-
-static const char * const vivid_ctrl_hor_movement_strings[] = {
-	"Move Left Fast",
-	"Move Left",
-	"Move Left Slow",
-	"No Movement",
-	"Move Right Slow",
-	"Move Right",
-	"Move Right Fast",
-	NULL,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_hor_movement = {
-	.ops = &vivid_vid_cap_ctrl_ops,
-	.id = VIVID_CID_HOR_MOVEMENT,
-	.name = "Horizontal Movement",
-	.type = V4L2_CTRL_TYPE_MENU,
-	.max = TPG_MOVE_POS_FAST,
-	.def = TPG_MOVE_NONE,
-	.qmenu = vivid_ctrl_hor_movement_strings,
-};
-
-static const char * const vivid_ctrl_vert_movement_strings[] = {
-	"Move Up Fast",
-	"Move Up",
-	"Move Up Slow",
-	"No Movement",
-	"Move Down Slow",
-	"Move Down",
-	"Move Down Fast",
-	NULL,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_vert_movement = {
-	.ops = &vivid_vid_cap_ctrl_ops,
-	.id = VIVID_CID_VERT_MOVEMENT,
-	.name = "Vertical Movement",
-	.type = V4L2_CTRL_TYPE_MENU,
-	.max = TPG_MOVE_POS_FAST,
-	.def = TPG_MOVE_NONE,
-	.qmenu = vivid_ctrl_vert_movement_strings,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_show_border = {
-	.ops = &vivid_vid_cap_ctrl_ops,
-	.id = VIVID_CID_SHOW_BORDER,
-	.name = "Show Border",
-	.type = V4L2_CTRL_TYPE_BOOLEAN,
-	.max = 1,
-	.step = 1,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_show_square = {
-	.ops = &vivid_vid_cap_ctrl_ops,
-	.id = VIVID_CID_SHOW_SQUARE,
-	.name = "Show Square",
-	.type = V4L2_CTRL_TYPE_BOOLEAN,
-	.max = 1,
-	.step = 1,
-};
-
-static const char * const vivid_ctrl_osd_mode_strings[] = {
-	"All",
-	"Counters Only",
-	"None",
-	NULL,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_osd_mode = {
-	.ops = &vivid_vid_cap_ctrl_ops,
-	.id = VIVID_CID_OSD_TEXT_MODE,
-	.name = "OSD Text Mode",
-	.type = V4L2_CTRL_TYPE_MENU,
-	.max = ARRAY_SIZE(vivid_ctrl_osd_mode_strings) - 2,
-	.qmenu = vivid_ctrl_osd_mode_strings,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_perc_fill = {
-	.ops = &vivid_vid_cap_ctrl_ops,
-	.id = VIVID_CID_PERCENTAGE_FILL,
-	.name = "Fill Percentage of Frame",
-	.type = V4L2_CTRL_TYPE_INTEGER,
-	.min = 0,
-	.max = 100,
-	.def = 100,
-	.step = 1,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_insert_sav = {
-	.ops = &vivid_vid_cap_ctrl_ops,
-	.id = VIVID_CID_INSERT_SAV,
-	.name = "Insert SAV Code in Image",
-	.type = V4L2_CTRL_TYPE_BOOLEAN,
-	.max = 1,
-	.step = 1,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_insert_eav = {
-	.ops = &vivid_vid_cap_ctrl_ops,
-	.id = VIVID_CID_INSERT_EAV,
-	.name = "Insert EAV Code in Image",
-	.type = V4L2_CTRL_TYPE_BOOLEAN,
-	.max = 1,
-	.step = 1,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_hflip = {
-	.ops = &vivid_vid_cap_ctrl_ops,
-	.id = VIVID_CID_HFLIP,
-	.name = "Sensor Flipped Horizontally",
-	.type = V4L2_CTRL_TYPE_BOOLEAN,
-	.max = 1,
-	.step = 1,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_vflip = {
-	.ops = &vivid_vid_cap_ctrl_ops,
-	.id = VIVID_CID_VFLIP,
-	.name = "Sensor Flipped Vertically",
-	.type = V4L2_CTRL_TYPE_BOOLEAN,
-	.max = 1,
-	.step = 1,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_reduced_fps = {
-	.ops = &vivid_vid_cap_ctrl_ops,
-	.id = VIVID_CID_REDUCED_FPS,
-	.name = "Reduced Framerate",
-	.type = V4L2_CTRL_TYPE_BOOLEAN,
-	.max = 1,
-	.step = 1,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_has_crop_cap = {
-	.ops = &vivid_vid_cap_ctrl_ops,
-	.id = VIVID_CID_HAS_CROP_CAP,
-	.name = "Enable Capture Cropping",
-	.type = V4L2_CTRL_TYPE_BOOLEAN,
-	.max = 1,
-	.def = 1,
-	.step = 1,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_has_compose_cap = {
-	.ops = &vivid_vid_cap_ctrl_ops,
-	.id = VIVID_CID_HAS_COMPOSE_CAP,
-	.name = "Enable Capture Composing",
-	.type = V4L2_CTRL_TYPE_BOOLEAN,
-	.max = 1,
-	.def = 1,
-	.step = 1,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_has_scaler_cap = {
-	.ops = &vivid_vid_cap_ctrl_ops,
-	.id = VIVID_CID_HAS_SCALER_CAP,
-	.name = "Enable Capture Scaler",
-	.type = V4L2_CTRL_TYPE_BOOLEAN,
-	.max = 1,
-	.def = 1,
-	.step = 1,
-};
-
-static const char * const vivid_ctrl_tstamp_src_strings[] = {
-	"End of Frame",
-	"Start of Exposure",
-	NULL,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_tstamp_src = {
-	.ops = &vivid_vid_cap_ctrl_ops,
-	.id = VIVID_CID_TSTAMP_SRC,
-	.name = "Timestamp Source",
-	.type = V4L2_CTRL_TYPE_MENU,
-	.max = ARRAY_SIZE(vivid_ctrl_tstamp_src_strings) - 2,
-	.qmenu = vivid_ctrl_tstamp_src_strings,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_std_aspect_ratio = {
-	.ops = &vivid_vid_cap_ctrl_ops,
-	.id = VIVID_CID_STD_ASPECT_RATIO,
-	.name = "Standard Aspect Ratio",
-	.type = V4L2_CTRL_TYPE_MENU,
-	.min = 1,
-	.max = 4,
-	.def = 1,
-	.qmenu = tpg_aspect_strings,
-};
-
-static const char * const vivid_ctrl_dv_timings_signal_mode_strings[] = {
-	"Current DV Timings",
-	"No Signal",
-	"No Lock",
-	"Out of Range",
-	"Selected DV Timings",
-	"Cycle Through All DV Timings",
-	"Custom DV Timings",
-	NULL,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_dv_timings_signal_mode = {
-	.ops = &vivid_vid_cap_ctrl_ops,
-	.id = VIVID_CID_DV_TIMINGS_SIGNAL_MODE,
-	.name = "DV Timings Signal Mode",
-	.type = V4L2_CTRL_TYPE_MENU,
-	.max = 5,
-	.qmenu = vivid_ctrl_dv_timings_signal_mode_strings,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_dv_timings_aspect_ratio = {
-	.ops = &vivid_vid_cap_ctrl_ops,
-	.id = VIVID_CID_DV_TIMINGS_ASPECT_RATIO,
-	.name = "DV Timings Aspect Ratio",
-	.type = V4L2_CTRL_TYPE_MENU,
-	.max = 3,
-	.qmenu = tpg_aspect_strings,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_max_edid_blocks = {
-	.ops = &vivid_vid_cap_ctrl_ops,
-	.id = VIVID_CID_MAX_EDID_BLOCKS,
-	.name = "Maximum EDID Blocks",
-	.type = V4L2_CTRL_TYPE_INTEGER,
-	.min = 1,
-	.max = 256,
-	.def = 2,
-	.step = 1,
-};
-
-static const char * const vivid_ctrl_colorspace_strings[] = {
-	"SMPTE 170M",
-	"Rec. 709",
-	"sRGB",
-	"opRGB",
-	"BT.2020",
-	"DCI-P3",
-	"SMPTE 240M",
-	"470 System M",
-	"470 System BG",
-	NULL,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_colorspace = {
-	.ops = &vivid_vid_cap_ctrl_ops,
-	.id = VIVID_CID_COLORSPACE,
-	.name = "Colorspace",
-	.type = V4L2_CTRL_TYPE_MENU,
-	.max = ARRAY_SIZE(vivid_ctrl_colorspace_strings) - 2,
-	.def = 2,
-	.qmenu = vivid_ctrl_colorspace_strings,
-};
-
-static const char * const vivid_ctrl_xfer_func_strings[] = {
-	"Default",
-	"Rec. 709",
-	"sRGB",
-	"opRGB",
-	"SMPTE 240M",
-	"None",
-	"DCI-P3",
-	"SMPTE 2084",
-	NULL,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_xfer_func = {
-	.ops = &vivid_vid_cap_ctrl_ops,
-	.id = VIVID_CID_XFER_FUNC,
-	.name = "Transfer Function",
-	.type = V4L2_CTRL_TYPE_MENU,
-	.max = ARRAY_SIZE(vivid_ctrl_xfer_func_strings) - 2,
-	.qmenu = vivid_ctrl_xfer_func_strings,
-};
-
-static const char * const vivid_ctrl_ycbcr_enc_strings[] = {
-	"Default",
-	"ITU-R 601",
-	"Rec. 709",
-	"xvYCC 601",
-	"xvYCC 709",
-	"",
-	"BT.2020",
-	"BT.2020 Constant Luminance",
-	"SMPTE 240M",
-	NULL,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_ycbcr_enc = {
-	.ops = &vivid_vid_cap_ctrl_ops,
-	.id = VIVID_CID_YCBCR_ENC,
-	.name = "Y'CbCr Encoding",
-	.type = V4L2_CTRL_TYPE_MENU,
-	.menu_skip_mask = 1 << 5,
-	.max = ARRAY_SIZE(vivid_ctrl_ycbcr_enc_strings) - 2,
-	.qmenu = vivid_ctrl_ycbcr_enc_strings,
-};
-
-static const char * const vivid_ctrl_hsv_enc_strings[] = {
-	"Hue 0-179",
-	"Hue 0-256",
-	NULL,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_hsv_enc = {
-	.ops = &vivid_vid_cap_ctrl_ops,
-	.id = VIVID_CID_HSV_ENC,
-	.name = "HSV Encoding",
-	.type = V4L2_CTRL_TYPE_MENU,
-	.max = ARRAY_SIZE(vivid_ctrl_hsv_enc_strings) - 2,
-	.qmenu = vivid_ctrl_hsv_enc_strings,
-};
-
-static const char * const vivid_ctrl_quantization_strings[] = {
-	"Default",
-	"Full Range",
-	"Limited Range",
-	NULL,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_quantization = {
-	.ops = &vivid_vid_cap_ctrl_ops,
-	.id = VIVID_CID_QUANTIZATION,
-	.name = "Quantization",
-	.type = V4L2_CTRL_TYPE_MENU,
-	.max = ARRAY_SIZE(vivid_ctrl_quantization_strings) - 2,
-	.qmenu = vivid_ctrl_quantization_strings,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_alpha_mode = {
-	.ops = &vivid_vid_cap_ctrl_ops,
-	.id = VIVID_CID_ALPHA_MODE,
-	.name = "Apply Alpha To Red Only",
-	.type = V4L2_CTRL_TYPE_BOOLEAN,
-	.max = 1,
-	.step = 1,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_limited_rgb_range = {
-	.ops = &vivid_vid_cap_ctrl_ops,
-	.id = VIVID_CID_LIMITED_RGB_RANGE,
-	.name = "Limited RGB Range (16-235)",
-	.type = V4L2_CTRL_TYPE_BOOLEAN,
-	.max = 1,
-	.step = 1,
-};
-
-
-/* Video Loop Control */
-
-static int vivid_loop_cap_s_ctrl(struct v4l2_ctrl *ctrl)
-{
-	struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_loop_cap);
-
-	switch (ctrl->id) {
-	case VIVID_CID_LOOP_VIDEO:
-		dev->loop_video = ctrl->val;
-		vivid_update_quality(dev);
-		vivid_send_source_change(dev, SVID);
-		vivid_send_source_change(dev, HDMI);
-		break;
-	}
-	return 0;
-}
-
-static const struct v4l2_ctrl_ops vivid_loop_cap_ctrl_ops = {
-	.s_ctrl = vivid_loop_cap_s_ctrl,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_loop_video = {
-	.ops = &vivid_loop_cap_ctrl_ops,
-	.id = VIVID_CID_LOOP_VIDEO,
-	.name = "Loop Video",
-	.type = V4L2_CTRL_TYPE_BOOLEAN,
-	.max = 1,
-	.step = 1,
-};
-
-
-/* VBI Capture Control */
-
-static int vivid_vbi_cap_s_ctrl(struct v4l2_ctrl *ctrl)
-{
-	struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_vbi_cap);
-
-	switch (ctrl->id) {
-	case VIVID_CID_VBI_CAP_INTERLACED:
-		dev->vbi_cap_interlaced = ctrl->val;
-		break;
-	}
-	return 0;
-}
-
-static const struct v4l2_ctrl_ops vivid_vbi_cap_ctrl_ops = {
-	.s_ctrl = vivid_vbi_cap_s_ctrl,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_vbi_cap_interlaced = {
-	.ops = &vivid_vbi_cap_ctrl_ops,
-	.id = VIVID_CID_VBI_CAP_INTERLACED,
-	.name = "Interlaced VBI Format",
-	.type = V4L2_CTRL_TYPE_BOOLEAN,
-	.max = 1,
-	.step = 1,
-};
-
-
-/* Video Output Controls */
-
-static int vivid_vid_out_s_ctrl(struct v4l2_ctrl *ctrl)
-{
-	struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_vid_out);
-	struct v4l2_bt_timings *bt = &dev->dv_timings_out.bt;
-	u32 display_present = 0;
-	unsigned int i, j, bus_idx;
-
-	switch (ctrl->id) {
-	case VIVID_CID_HAS_CROP_OUT:
-		dev->has_crop_out = ctrl->val;
-		vivid_update_format_out(dev);
-		break;
-	case VIVID_CID_HAS_COMPOSE_OUT:
-		dev->has_compose_out = ctrl->val;
-		vivid_update_format_out(dev);
-		break;
-	case VIVID_CID_HAS_SCALER_OUT:
-		dev->has_scaler_out = ctrl->val;
-		vivid_update_format_out(dev);
-		break;
-	case V4L2_CID_DV_TX_MODE:
-		dev->dvi_d_out = ctrl->val == V4L2_DV_TX_MODE_DVI_D;
-		if (!vivid_is_hdmi_out(dev))
-			break;
-		if (!dev->dvi_d_out && (bt->flags & V4L2_DV_FL_IS_CE_VIDEO)) {
-			if (bt->width == 720 && bt->height <= 576)
-				dev->colorspace_out = V4L2_COLORSPACE_SMPTE170M;
-			else
-				dev->colorspace_out = V4L2_COLORSPACE_REC709;
-			dev->quantization_out = V4L2_QUANTIZATION_DEFAULT;
-		} else {
-			dev->colorspace_out = V4L2_COLORSPACE_SRGB;
-			dev->quantization_out = dev->dvi_d_out ?
-					V4L2_QUANTIZATION_LIM_RANGE :
-					V4L2_QUANTIZATION_DEFAULT;
-		}
-		if (dev->loop_video)
-			vivid_send_source_change(dev, HDMI);
-		break;
-	case VIVID_CID_DISPLAY_PRESENT:
-		if (dev->output_type[dev->output] != HDMI)
-			break;
-
-		dev->display_present[dev->output] = ctrl->val;
-		for (i = 0, j = 0; i < dev->num_outputs; i++)
-			if (dev->output_type[i] == HDMI)
-				display_present |=
-					dev->display_present[i] << j++;
-
-		__v4l2_ctrl_s_ctrl(dev->ctrl_tx_rxsense, display_present);
-
-		if (dev->edid_blocks) {
-			__v4l2_ctrl_s_ctrl(dev->ctrl_tx_edid_present,
-					   display_present);
-			__v4l2_ctrl_s_ctrl(dev->ctrl_tx_hotplug,
-					   display_present);
-		}
-
-		bus_idx = dev->cec_output2bus_map[dev->output];
-		if (!dev->cec_tx_adap[bus_idx])
-			break;
-
-		if (ctrl->val && dev->edid_blocks)
-			cec_s_phys_addr(dev->cec_tx_adap[bus_idx],
-					dev->cec_tx_adap[bus_idx]->phys_addr,
-					false);
-		else
-			cec_phys_addr_invalidate(dev->cec_tx_adap[bus_idx]);
-
-		break;
-	}
-	return 0;
-}
-
-static const struct v4l2_ctrl_ops vivid_vid_out_ctrl_ops = {
-	.s_ctrl = vivid_vid_out_s_ctrl,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_has_crop_out = {
-	.ops = &vivid_vid_out_ctrl_ops,
-	.id = VIVID_CID_HAS_CROP_OUT,
-	.name = "Enable Output Cropping",
-	.type = V4L2_CTRL_TYPE_BOOLEAN,
-	.max = 1,
-	.def = 1,
-	.step = 1,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_has_compose_out = {
-	.ops = &vivid_vid_out_ctrl_ops,
-	.id = VIVID_CID_HAS_COMPOSE_OUT,
-	.name = "Enable Output Composing",
-	.type = V4L2_CTRL_TYPE_BOOLEAN,
-	.max = 1,
-	.def = 1,
-	.step = 1,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_has_scaler_out = {
-	.ops = &vivid_vid_out_ctrl_ops,
-	.id = VIVID_CID_HAS_SCALER_OUT,
-	.name = "Enable Output Scaler",
-	.type = V4L2_CTRL_TYPE_BOOLEAN,
-	.max = 1,
-	.def = 1,
-	.step = 1,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_display_present = {
-	.ops = &vivid_vid_out_ctrl_ops,
-	.id = VIVID_CID_DISPLAY_PRESENT,
-	.name = "Display Present",
-	.type = V4L2_CTRL_TYPE_BOOLEAN,
-	.max = 1,
-	.def = 1,
-	.step = 1,
-};
-
-/* Streaming Controls */
-
-static int vivid_streaming_s_ctrl(struct v4l2_ctrl *ctrl)
-{
-	struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_streaming);
-	u64 rem;
-
-	switch (ctrl->id) {
-	case VIVID_CID_DQBUF_ERROR:
-		dev->dqbuf_error = true;
-		break;
-	case VIVID_CID_PERC_DROPPED:
-		dev->perc_dropped_buffers = ctrl->val;
-		break;
-	case VIVID_CID_QUEUE_SETUP_ERROR:
-		dev->queue_setup_error = true;
-		break;
-	case VIVID_CID_BUF_PREPARE_ERROR:
-		dev->buf_prepare_error = true;
-		break;
-	case VIVID_CID_START_STR_ERROR:
-		dev->start_streaming_error = true;
-		break;
-	case VIVID_CID_REQ_VALIDATE_ERROR:
-		dev->req_validate_error = true;
-		break;
-	case VIVID_CID_QUEUE_ERROR:
-		if (vb2_start_streaming_called(&dev->vb_vid_cap_q))
-			vb2_queue_error(&dev->vb_vid_cap_q);
-		if (vb2_start_streaming_called(&dev->vb_vbi_cap_q))
-			vb2_queue_error(&dev->vb_vbi_cap_q);
-		if (vb2_start_streaming_called(&dev->vb_vid_out_q))
-			vb2_queue_error(&dev->vb_vid_out_q);
-		if (vb2_start_streaming_called(&dev->vb_vbi_out_q))
-			vb2_queue_error(&dev->vb_vbi_out_q);
-		if (vb2_start_streaming_called(&dev->vb_sdr_cap_q))
-			vb2_queue_error(&dev->vb_sdr_cap_q);
-		break;
-	case VIVID_CID_SEQ_WRAP:
-		dev->seq_wrap = ctrl->val;
-		break;
-	case VIVID_CID_TIME_WRAP:
-		dev->time_wrap = ctrl->val;
-		if (ctrl->val == 0) {
-			dev->time_wrap_offset = 0;
-			break;
-		}
-		/*
-		 * We want to set the time 16 seconds before the 32 bit tv_sec
-		 * value of struct timeval would wrap around. So first we
-		 * calculate ktime_get_ns() % ((1 << 32) * NSEC_PER_SEC), and
-		 * then we set the offset to ((1 << 32) - 16) * NSEC_PER_SEC).
-		 */
-		div64_u64_rem(ktime_get_ns(),
-			0x100000000ULL * NSEC_PER_SEC, &rem);
-		dev->time_wrap_offset =
-			(0x100000000ULL - 16) * NSEC_PER_SEC - rem;
-		break;
-	}
-	return 0;
-}
-
-static const struct v4l2_ctrl_ops vivid_streaming_ctrl_ops = {
-	.s_ctrl = vivid_streaming_s_ctrl,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_dqbuf_error = {
-	.ops = &vivid_streaming_ctrl_ops,
-	.id = VIVID_CID_DQBUF_ERROR,
-	.name = "Inject V4L2_BUF_FLAG_ERROR",
-	.type = V4L2_CTRL_TYPE_BUTTON,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_perc_dropped = {
-	.ops = &vivid_streaming_ctrl_ops,
-	.id = VIVID_CID_PERC_DROPPED,
-	.name = "Percentage of Dropped Buffers",
-	.type = V4L2_CTRL_TYPE_INTEGER,
-	.min = 0,
-	.max = 100,
-	.step = 1,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_queue_setup_error = {
-	.ops = &vivid_streaming_ctrl_ops,
-	.id = VIVID_CID_QUEUE_SETUP_ERROR,
-	.name = "Inject VIDIOC_REQBUFS Error",
-	.type = V4L2_CTRL_TYPE_BUTTON,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_buf_prepare_error = {
-	.ops = &vivid_streaming_ctrl_ops,
-	.id = VIVID_CID_BUF_PREPARE_ERROR,
-	.name = "Inject VIDIOC_QBUF Error",
-	.type = V4L2_CTRL_TYPE_BUTTON,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_start_streaming_error = {
-	.ops = &vivid_streaming_ctrl_ops,
-	.id = VIVID_CID_START_STR_ERROR,
-	.name = "Inject VIDIOC_STREAMON Error",
-	.type = V4L2_CTRL_TYPE_BUTTON,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_queue_error = {
-	.ops = &vivid_streaming_ctrl_ops,
-	.id = VIVID_CID_QUEUE_ERROR,
-	.name = "Inject Fatal Streaming Error",
-	.type = V4L2_CTRL_TYPE_BUTTON,
-};
-
-#ifdef CONFIG_MEDIA_CONTROLLER
-static const struct v4l2_ctrl_config vivid_ctrl_req_validate_error = {
-	.ops = &vivid_streaming_ctrl_ops,
-	.id = VIVID_CID_REQ_VALIDATE_ERROR,
-	.name = "Inject req_validate() Error",
-	.type = V4L2_CTRL_TYPE_BUTTON,
-};
-#endif
-
-static const struct v4l2_ctrl_config vivid_ctrl_seq_wrap = {
-	.ops = &vivid_streaming_ctrl_ops,
-	.id = VIVID_CID_SEQ_WRAP,
-	.name = "Wrap Sequence Number",
-	.type = V4L2_CTRL_TYPE_BOOLEAN,
-	.max = 1,
-	.step = 1,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_time_wrap = {
-	.ops = &vivid_streaming_ctrl_ops,
-	.id = VIVID_CID_TIME_WRAP,
-	.name = "Wrap Timestamp",
-	.type = V4L2_CTRL_TYPE_BOOLEAN,
-	.max = 1,
-	.step = 1,
-};
-
-
-/* SDTV Capture Controls */
-
-static int vivid_sdtv_cap_s_ctrl(struct v4l2_ctrl *ctrl)
-{
-	struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_sdtv_cap);
-
-	switch (ctrl->id) {
-	case VIVID_CID_STD_SIGNAL_MODE:
-		dev->std_signal_mode[dev->input] =
-			dev->ctrl_std_signal_mode->val;
-		if (dev->std_signal_mode[dev->input] == SELECTED_STD)
-			dev->query_std[dev->input] =
-				vivid_standard[dev->ctrl_standard->val];
-		v4l2_ctrl_activate(dev->ctrl_standard,
-				   dev->std_signal_mode[dev->input] ==
-					SELECTED_STD);
-		vivid_update_quality(dev);
-		vivid_send_source_change(dev, TV);
-		vivid_send_source_change(dev, SVID);
-		break;
-	}
-	return 0;
-}
-
-static const struct v4l2_ctrl_ops vivid_sdtv_cap_ctrl_ops = {
-	.s_ctrl = vivid_sdtv_cap_s_ctrl,
-};
-
-static const char * const vivid_ctrl_std_signal_mode_strings[] = {
-	"Current Standard",
-	"No Signal",
-	"No Lock",
-	"",
-	"Selected Standard",
-	"Cycle Through All Standards",
-	NULL,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_std_signal_mode = {
-	.ops = &vivid_sdtv_cap_ctrl_ops,
-	.id = VIVID_CID_STD_SIGNAL_MODE,
-	.name = "Standard Signal Mode",
-	.type = V4L2_CTRL_TYPE_MENU,
-	.max = ARRAY_SIZE(vivid_ctrl_std_signal_mode_strings) - 2,
-	.menu_skip_mask = 1 << 3,
-	.qmenu = vivid_ctrl_std_signal_mode_strings,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_standard = {
-	.ops = &vivid_sdtv_cap_ctrl_ops,
-	.id = VIVID_CID_STANDARD,
-	.name = "Standard",
-	.type = V4L2_CTRL_TYPE_MENU,
-	.max = 14,
-	.qmenu = vivid_ctrl_standard_strings,
-};
-
-
-
-/* Radio Receiver Controls */
-
-static int vivid_radio_rx_s_ctrl(struct v4l2_ctrl *ctrl)
-{
-	struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_radio_rx);
-
-	switch (ctrl->id) {
-	case VIVID_CID_RADIO_SEEK_MODE:
-		dev->radio_rx_hw_seek_mode = ctrl->val;
-		break;
-	case VIVID_CID_RADIO_SEEK_PROG_LIM:
-		dev->radio_rx_hw_seek_prog_lim = ctrl->val;
-		break;
-	case VIVID_CID_RADIO_RX_RDS_RBDS:
-		dev->rds_gen.use_rbds = ctrl->val;
-		break;
-	case VIVID_CID_RADIO_RX_RDS_BLOCKIO:
-		dev->radio_rx_rds_controls = ctrl->val;
-		dev->radio_rx_caps &= ~V4L2_CAP_READWRITE;
-		dev->radio_rx_rds_use_alternates = false;
-		if (!dev->radio_rx_rds_controls) {
-			dev->radio_rx_caps |= V4L2_CAP_READWRITE;
-			__v4l2_ctrl_s_ctrl(dev->radio_rx_rds_pty, 0);
-			__v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ta, 0);
-			__v4l2_ctrl_s_ctrl(dev->radio_rx_rds_tp, 0);
-			__v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ms, 0);
-			__v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_psname, "");
-			__v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_radiotext, "");
-		}
-		v4l2_ctrl_activate(dev->radio_rx_rds_pty, dev->radio_rx_rds_controls);
-		v4l2_ctrl_activate(dev->radio_rx_rds_psname, dev->radio_rx_rds_controls);
-		v4l2_ctrl_activate(dev->radio_rx_rds_radiotext, dev->radio_rx_rds_controls);
-		v4l2_ctrl_activate(dev->radio_rx_rds_ta, dev->radio_rx_rds_controls);
-		v4l2_ctrl_activate(dev->radio_rx_rds_tp, dev->radio_rx_rds_controls);
-		v4l2_ctrl_activate(dev->radio_rx_rds_ms, dev->radio_rx_rds_controls);
-		dev->radio_rx_dev.device_caps = dev->radio_rx_caps;
-		break;
-	case V4L2_CID_RDS_RECEPTION:
-		dev->radio_rx_rds_enabled = ctrl->val;
-		break;
-	}
-	return 0;
-}
-
-static const struct v4l2_ctrl_ops vivid_radio_rx_ctrl_ops = {
-	.s_ctrl = vivid_radio_rx_s_ctrl,
-};
-
-static const char * const vivid_ctrl_radio_rds_mode_strings[] = {
-	"Block I/O",
-	"Controls",
-	NULL,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_radio_rx_rds_blockio = {
-	.ops = &vivid_radio_rx_ctrl_ops,
-	.id = VIVID_CID_RADIO_RX_RDS_BLOCKIO,
-	.name = "RDS Rx I/O Mode",
-	.type = V4L2_CTRL_TYPE_MENU,
-	.qmenu = vivid_ctrl_radio_rds_mode_strings,
-	.max = 1,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_radio_rx_rds_rbds = {
-	.ops = &vivid_radio_rx_ctrl_ops,
-	.id = VIVID_CID_RADIO_RX_RDS_RBDS,
-	.name = "Generate RBDS Instead of RDS",
-	.type = V4L2_CTRL_TYPE_BOOLEAN,
-	.max = 1,
-	.step = 1,
-};
-
-static const char * const vivid_ctrl_radio_hw_seek_mode_strings[] = {
-	"Bounded",
-	"Wrap Around",
-	"Both",
-	NULL,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_radio_hw_seek_mode = {
-	.ops = &vivid_radio_rx_ctrl_ops,
-	.id = VIVID_CID_RADIO_SEEK_MODE,
-	.name = "Radio HW Seek Mode",
-	.type = V4L2_CTRL_TYPE_MENU,
-	.max = 2,
-	.qmenu = vivid_ctrl_radio_hw_seek_mode_strings,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_radio_hw_seek_prog_lim = {
-	.ops = &vivid_radio_rx_ctrl_ops,
-	.id = VIVID_CID_RADIO_SEEK_PROG_LIM,
-	.name = "Radio Programmable HW Seek",
-	.type = V4L2_CTRL_TYPE_BOOLEAN,
-	.max = 1,
-	.step = 1,
-};
-
-
-/* Radio Transmitter Controls */
-
-static int vivid_radio_tx_s_ctrl(struct v4l2_ctrl *ctrl)
-{
-	struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_radio_tx);
-
-	switch (ctrl->id) {
-	case VIVID_CID_RADIO_TX_RDS_BLOCKIO:
-		dev->radio_tx_rds_controls = ctrl->val;
-		dev->radio_tx_caps &= ~V4L2_CAP_READWRITE;
-		if (!dev->radio_tx_rds_controls)
-			dev->radio_tx_caps |= V4L2_CAP_READWRITE;
-		dev->radio_tx_dev.device_caps = dev->radio_tx_caps;
-		break;
-	case V4L2_CID_RDS_TX_PTY:
-		if (dev->radio_rx_rds_controls)
-			v4l2_ctrl_s_ctrl(dev->radio_rx_rds_pty, ctrl->val);
-		break;
-	case V4L2_CID_RDS_TX_PS_NAME:
-		if (dev->radio_rx_rds_controls)
-			v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_psname, ctrl->p_new.p_char);
-		break;
-	case V4L2_CID_RDS_TX_RADIO_TEXT:
-		if (dev->radio_rx_rds_controls)
-			v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_radiotext, ctrl->p_new.p_char);
-		break;
-	case V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT:
-		if (dev->radio_rx_rds_controls)
-			v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ta, ctrl->val);
-		break;
-	case V4L2_CID_RDS_TX_TRAFFIC_PROGRAM:
-		if (dev->radio_rx_rds_controls)
-			v4l2_ctrl_s_ctrl(dev->radio_rx_rds_tp, ctrl->val);
-		break;
-	case V4L2_CID_RDS_TX_MUSIC_SPEECH:
-		if (dev->radio_rx_rds_controls)
-			v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ms, ctrl->val);
-		break;
-	}
-	return 0;
-}
-
-static const struct v4l2_ctrl_ops vivid_radio_tx_ctrl_ops = {
-	.s_ctrl = vivid_radio_tx_s_ctrl,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_radio_tx_rds_blockio = {
-	.ops = &vivid_radio_tx_ctrl_ops,
-	.id = VIVID_CID_RADIO_TX_RDS_BLOCKIO,
-	.name = "RDS Tx I/O Mode",
-	.type = V4L2_CTRL_TYPE_MENU,
-	.qmenu = vivid_ctrl_radio_rds_mode_strings,
-	.max = 1,
-	.def = 1,
-};
-
-
-/* SDR Capture Controls */
-
-static int vivid_sdr_cap_s_ctrl(struct v4l2_ctrl *ctrl)
-{
-	struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_sdr_cap);
-
-	switch (ctrl->id) {
-	case VIVID_CID_SDR_CAP_FM_DEVIATION:
-		dev->sdr_fm_deviation = ctrl->val;
-		break;
-	}
-	return 0;
-}
-
-static const struct v4l2_ctrl_ops vivid_sdr_cap_ctrl_ops = {
-	.s_ctrl = vivid_sdr_cap_s_ctrl,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_sdr_cap_fm_deviation = {
-	.ops = &vivid_sdr_cap_ctrl_ops,
-	.id = VIVID_CID_SDR_CAP_FM_DEVIATION,
-	.name = "FM Deviation",
-	.type = V4L2_CTRL_TYPE_INTEGER,
-	.min =    100,
-	.max = 200000,
-	.def =  75000,
-	.step =     1,
-};
-
-/* Metadata Capture Control */
-
-static int vivid_meta_cap_s_ctrl(struct v4l2_ctrl *ctrl)
-{
-	struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev,
-					     ctrl_hdl_meta_cap);
-
-	switch (ctrl->id) {
-	case VIVID_CID_META_CAP_GENERATE_PTS:
-		dev->meta_pts = ctrl->val;
-		break;
-	case VIVID_CID_META_CAP_GENERATE_SCR:
-		dev->meta_scr = ctrl->val;
-		break;
-	}
-	return 0;
-}
-
-static const struct v4l2_ctrl_ops vivid_meta_cap_ctrl_ops = {
-	.s_ctrl = vivid_meta_cap_s_ctrl,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_meta_has_pts = {
-	.ops = &vivid_meta_cap_ctrl_ops,
-	.id = VIVID_CID_META_CAP_GENERATE_PTS,
-	.name = "Generate PTS",
-	.type = V4L2_CTRL_TYPE_BOOLEAN,
-	.max = 1,
-	.def = 1,
-	.step = 1,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_meta_has_src_clk = {
-	.ops = &vivid_meta_cap_ctrl_ops,
-	.id = VIVID_CID_META_CAP_GENERATE_SCR,
-	.name = "Generate SCR",
-	.type = V4L2_CTRL_TYPE_BOOLEAN,
-	.max = 1,
-	.def = 1,
-	.step = 1,
-};
-
-static const struct v4l2_ctrl_config vivid_ctrl_class = {
-	.ops = &vivid_user_gen_ctrl_ops,
-	.flags = V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY,
-	.id = VIVID_CID_VIVID_CLASS,
-	.name = "Vivid Controls",
-	.type = V4L2_CTRL_TYPE_CTRL_CLASS,
-};
-
-int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
-		bool show_ccs_out, bool no_error_inj,
-		bool has_sdtv, bool has_hdmi)
-{
-	struct v4l2_ctrl_handler *hdl_user_gen = &dev->ctrl_hdl_user_gen;
-	struct v4l2_ctrl_handler *hdl_user_vid = &dev->ctrl_hdl_user_vid;
-	struct v4l2_ctrl_handler *hdl_user_aud = &dev->ctrl_hdl_user_aud;
-	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;
-	struct v4l2_ctrl_handler *hdl_vbi_out = &dev->ctrl_hdl_vbi_out;
-	struct v4l2_ctrl_handler *hdl_radio_rx = &dev->ctrl_hdl_radio_rx;
-	struct v4l2_ctrl_handler *hdl_radio_tx = &dev->ctrl_hdl_radio_tx;
-	struct v4l2_ctrl_handler *hdl_sdr_cap = &dev->ctrl_hdl_sdr_cap;
-	struct v4l2_ctrl_handler *hdl_meta_cap = &dev->ctrl_hdl_meta_cap;
-	struct v4l2_ctrl_handler *hdl_meta_out = &dev->ctrl_hdl_meta_out;
-	struct v4l2_ctrl_handler *hdl_tch_cap = &dev->ctrl_hdl_touch_cap;
-
-	struct v4l2_ctrl_config vivid_ctrl_dv_timings = {
-		.ops = &vivid_vid_cap_ctrl_ops,
-		.id = VIVID_CID_DV_TIMINGS,
-		.name = "DV Timings",
-		.type = V4L2_CTRL_TYPE_MENU,
-	};
-	int i;
-
-	v4l2_ctrl_handler_init(hdl_user_gen, 10);
-	v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_class, NULL);
-	v4l2_ctrl_handler_init(hdl_user_vid, 9);
-	v4l2_ctrl_new_custom(hdl_user_vid, &vivid_ctrl_class, NULL);
-	v4l2_ctrl_handler_init(hdl_user_aud, 2);
-	v4l2_ctrl_new_custom(hdl_user_aud, &vivid_ctrl_class, NULL);
-	v4l2_ctrl_handler_init(hdl_streaming, 8);
-	v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_class, NULL);
-	v4l2_ctrl_handler_init(hdl_sdtv_cap, 2);
-	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 || dev->has_fb || dev->num_hdmi_outputs)
-		v4l2_ctrl_new_custom(hdl_vid_out, &vivid_ctrl_class, NULL);
-	v4l2_ctrl_handler_init(hdl_vbi_cap, 21);
-	v4l2_ctrl_new_custom(hdl_vbi_cap, &vivid_ctrl_class, NULL);
-	v4l2_ctrl_handler_init(hdl_vbi_out, 19);
-	if (!no_error_inj)
-		v4l2_ctrl_new_custom(hdl_vbi_out, &vivid_ctrl_class, NULL);
-	v4l2_ctrl_handler_init(hdl_radio_rx, 17);
-	v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_class, NULL);
-	v4l2_ctrl_handler_init(hdl_radio_tx, 17);
-	v4l2_ctrl_new_custom(hdl_radio_tx, &vivid_ctrl_class, NULL);
-	v4l2_ctrl_handler_init(hdl_sdr_cap, 19);
-	v4l2_ctrl_new_custom(hdl_sdr_cap, &vivid_ctrl_class, NULL);
-	v4l2_ctrl_handler_init(hdl_meta_cap, 2);
-	v4l2_ctrl_new_custom(hdl_meta_cap, &vivid_ctrl_class, NULL);
-	v4l2_ctrl_handler_init(hdl_meta_out, 2);
-	v4l2_ctrl_new_custom(hdl_meta_out, &vivid_ctrl_class, NULL);
-	v4l2_ctrl_handler_init(hdl_tch_cap, 2);
-	v4l2_ctrl_new_custom(hdl_tch_cap, &vivid_ctrl_class, NULL);
-
-	/* User Controls */
-	dev->volume = v4l2_ctrl_new_std(hdl_user_aud, NULL,
-		V4L2_CID_AUDIO_VOLUME, 0, 255, 1, 200);
-	dev->mute = v4l2_ctrl_new_std(hdl_user_aud, NULL,
-		V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
-	if (dev->has_vid_cap) {
-		dev->brightness = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
-			V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
-		for (i = 0; i < MAX_INPUTS; i++)
-			dev->input_brightness[i] = 128;
-		dev->contrast = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
-			V4L2_CID_CONTRAST, 0, 255, 1, 128);
-		dev->saturation = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
-			V4L2_CID_SATURATION, 0, 255, 1, 128);
-		dev->hue = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
-			V4L2_CID_HUE, -128, 128, 1, 0);
-		v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
-			V4L2_CID_HFLIP, 0, 1, 1, 0);
-		v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
-			V4L2_CID_VFLIP, 0, 1, 1, 0);
-		dev->autogain = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
-			V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
-		dev->gain = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
-			V4L2_CID_GAIN, 0, 255, 1, 100);
-		dev->alpha = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
-			V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 0);
-	}
-	dev->button = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_button, NULL);
-	dev->int32 = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_int32, NULL);
-	dev->int64 = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_int64, NULL);
-	dev->boolean = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_boolean, NULL);
-	dev->menu = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_menu, NULL);
-	dev->string = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_string, NULL);
-	dev->bitmask = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_bitmask, NULL);
-	dev->int_menu = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_int_menu, NULL);
-	v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_area, NULL);
-	v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u32_array, NULL);
-	v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u16_matrix, NULL);
-	v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u8_4d_array, NULL);
-
-	if (dev->has_vid_cap) {
-		/* Image Processing Controls */
-		struct v4l2_ctrl_config vivid_ctrl_test_pattern = {
-			.ops = &vivid_vid_cap_ctrl_ops,
-			.id = VIVID_CID_TEST_PATTERN,
-			.name = "Test Pattern",
-			.type = V4L2_CTRL_TYPE_MENU,
-			.max = TPG_PAT_NOISE,
-			.qmenu = tpg_pattern_strings,
-		};
-
-		dev->test_pattern = v4l2_ctrl_new_custom(hdl_vid_cap,
-				&vivid_ctrl_test_pattern, NULL);
-		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_perc_fill, NULL);
-		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_hor_movement, NULL);
-		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_vert_movement, NULL);
-		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_osd_mode, NULL);
-		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_show_border, NULL);
-		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_show_square, NULL);
-		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_hflip, NULL);
-		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_vflip, NULL);
-		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_insert_sav, NULL);
-		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_insert_eav, NULL);
-		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_reduced_fps, NULL);
-		if (show_ccs_cap) {
-			dev->ctrl_has_crop_cap = v4l2_ctrl_new_custom(hdl_vid_cap,
-				&vivid_ctrl_has_crop_cap, NULL);
-			dev->ctrl_has_compose_cap = v4l2_ctrl_new_custom(hdl_vid_cap,
-				&vivid_ctrl_has_compose_cap, NULL);
-			dev->ctrl_has_scaler_cap = v4l2_ctrl_new_custom(hdl_vid_cap,
-				&vivid_ctrl_has_scaler_cap, NULL);
-		}
-
-		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_tstamp_src, NULL);
-		dev->colorspace = v4l2_ctrl_new_custom(hdl_vid_cap,
-			&vivid_ctrl_colorspace, NULL);
-		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_xfer_func, NULL);
-		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_ycbcr_enc, NULL);
-		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_hsv_enc, NULL);
-		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_quantization, NULL);
-		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_alpha_mode, NULL);
-	}
-
-	if (dev->has_vid_out && show_ccs_out) {
-		dev->ctrl_has_crop_out = v4l2_ctrl_new_custom(hdl_vid_out,
-			&vivid_ctrl_has_crop_out, NULL);
-		dev->ctrl_has_compose_out = v4l2_ctrl_new_custom(hdl_vid_out,
-			&vivid_ctrl_has_compose_out, NULL);
-		dev->ctrl_has_scaler_out = v4l2_ctrl_new_custom(hdl_vid_out,
-			&vivid_ctrl_has_scaler_out, NULL);
-	}
-
-	/*
-	 * Testing this driver with v4l2-compliance will trigger the error
-	 * injection controls, and after that nothing will work as expected.
-	 * So we have a module option to drop these error injecting controls
-	 * allowing us to run v4l2_compliance again.
-	 */
-	if (!no_error_inj) {
-		v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_disconnect, NULL);
-		v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_dqbuf_error, NULL);
-		v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_perc_dropped, NULL);
-		v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_queue_setup_error, NULL);
-		v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_buf_prepare_error, NULL);
-		v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_start_streaming_error, NULL);
-		v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_queue_error, NULL);
-#ifdef CONFIG_MEDIA_CONTROLLER
-		v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_req_validate_error, NULL);
-#endif
-		v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_seq_wrap, NULL);
-		v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_time_wrap, NULL);
-	}
-
-	if (has_sdtv && (dev->has_vid_cap || dev->has_vbi_cap)) {
-		if (dev->has_vid_cap)
-			v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_std_aspect_ratio, NULL);
-		dev->ctrl_std_signal_mode = v4l2_ctrl_new_custom(hdl_sdtv_cap,
-			&vivid_ctrl_std_signal_mode, NULL);
-		dev->ctrl_standard = v4l2_ctrl_new_custom(hdl_sdtv_cap,
-			&vivid_ctrl_standard, NULL);
-		if (dev->ctrl_std_signal_mode)
-			v4l2_ctrl_cluster(2, &dev->ctrl_std_signal_mode);
-		if (dev->has_raw_vbi_cap)
-			v4l2_ctrl_new_custom(hdl_vbi_cap, &vivid_ctrl_vbi_cap_interlaced, NULL);
-	}
-
-	if (dev->num_hdmi_inputs) {
-		s64 hdmi_input_mask = GENMASK(dev->num_hdmi_inputs - 1, 0);
-
-		dev->ctrl_dv_timings_signal_mode = v4l2_ctrl_new_custom(hdl_vid_cap,
-					&vivid_ctrl_dv_timings_signal_mode, NULL);
-
-		vivid_ctrl_dv_timings.max = dev->query_dv_timings_size - 1;
-		vivid_ctrl_dv_timings.qmenu =
-			(const char * const *)dev->query_dv_timings_qmenu;
-		dev->ctrl_dv_timings = v4l2_ctrl_new_custom(hdl_vid_cap,
-			&vivid_ctrl_dv_timings, NULL);
-		if (dev->ctrl_dv_timings_signal_mode)
-			v4l2_ctrl_cluster(2, &dev->ctrl_dv_timings_signal_mode);
-
-		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_dv_timings_aspect_ratio, NULL);
-		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_max_edid_blocks, NULL);
-		dev->real_rgb_range_cap = v4l2_ctrl_new_custom(hdl_vid_cap,
-			&vivid_ctrl_limited_rgb_range, NULL);
-		dev->rgb_range_cap = v4l2_ctrl_new_std_menu(hdl_vid_cap,
-			&vivid_vid_cap_ctrl_ops,
-			V4L2_CID_DV_RX_RGB_RANGE, V4L2_DV_RGB_RANGE_FULL,
-			0, V4L2_DV_RGB_RANGE_AUTO);
-		dev->ctrl_rx_power_present = v4l2_ctrl_new_std(hdl_vid_cap,
-			NULL, V4L2_CID_DV_RX_POWER_PRESENT, 0, hdmi_input_mask,
-			0, hdmi_input_mask);
-
-	}
-	if (dev->num_hdmi_outputs) {
-		s64 hdmi_output_mask = GENMASK(dev->num_hdmi_outputs - 1, 0);
-
-		/*
-		 * We aren't doing anything with this at the moment, but
-		 * HDMI outputs typically have this controls.
-		 */
-		dev->ctrl_tx_rgb_range = v4l2_ctrl_new_std_menu(hdl_vid_out, NULL,
-			V4L2_CID_DV_TX_RGB_RANGE, V4L2_DV_RGB_RANGE_FULL,
-			0, V4L2_DV_RGB_RANGE_AUTO);
-		dev->ctrl_tx_mode = v4l2_ctrl_new_std_menu(hdl_vid_out, NULL,
-			V4L2_CID_DV_TX_MODE, V4L2_DV_TX_MODE_HDMI,
-			0, V4L2_DV_TX_MODE_HDMI);
-		dev->ctrl_display_present = v4l2_ctrl_new_custom(hdl_vid_out,
-			&vivid_ctrl_display_present, NULL);
-		dev->ctrl_tx_hotplug = v4l2_ctrl_new_std(hdl_vid_out,
-			NULL, V4L2_CID_DV_TX_HOTPLUG, 0, hdmi_output_mask,
-			0, hdmi_output_mask);
-		dev->ctrl_tx_rxsense = v4l2_ctrl_new_std(hdl_vid_out,
-			NULL, V4L2_CID_DV_TX_RXSENSE, 0, hdmi_output_mask,
-			0, hdmi_output_mask);
-		dev->ctrl_tx_edid_present = v4l2_ctrl_new_std(hdl_vid_out,
-			NULL, V4L2_CID_DV_TX_EDID_PRESENT, 0, hdmi_output_mask,
-			0, hdmi_output_mask);
-	}
-	if ((dev->has_vid_cap && dev->has_vid_out) ||
-	    (dev->has_vbi_cap && dev->has_vbi_out))
-		v4l2_ctrl_new_custom(hdl_loop_cap, &vivid_ctrl_loop_video, NULL);
-
-	if (dev->has_fb)
-		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);
-		v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_hw_seek_prog_lim, NULL);
-		v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_rx_rds_blockio, NULL);
-		v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_rx_rds_rbds, NULL);
-		v4l2_ctrl_new_std(hdl_radio_rx, &vivid_radio_rx_ctrl_ops,
-			V4L2_CID_RDS_RECEPTION, 0, 1, 1, 1);
-		dev->radio_rx_rds_pty = v4l2_ctrl_new_std(hdl_radio_rx,
-			&vivid_radio_rx_ctrl_ops,
-			V4L2_CID_RDS_RX_PTY, 0, 31, 1, 0);
-		dev->radio_rx_rds_psname = v4l2_ctrl_new_std(hdl_radio_rx,
-			&vivid_radio_rx_ctrl_ops,
-			V4L2_CID_RDS_RX_PS_NAME, 0, 8, 8, 0);
-		dev->radio_rx_rds_radiotext = v4l2_ctrl_new_std(hdl_radio_rx,
-			&vivid_radio_rx_ctrl_ops,
-			V4L2_CID_RDS_RX_RADIO_TEXT, 0, 64, 64, 0);
-		dev->radio_rx_rds_ta = v4l2_ctrl_new_std(hdl_radio_rx,
-			&vivid_radio_rx_ctrl_ops,
-			V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT, 0, 1, 1, 0);
-		dev->radio_rx_rds_tp = v4l2_ctrl_new_std(hdl_radio_rx,
-			&vivid_radio_rx_ctrl_ops,
-			V4L2_CID_RDS_RX_TRAFFIC_PROGRAM, 0, 1, 1, 0);
-		dev->radio_rx_rds_ms = v4l2_ctrl_new_std(hdl_radio_rx,
-			&vivid_radio_rx_ctrl_ops,
-			V4L2_CID_RDS_RX_MUSIC_SPEECH, 0, 1, 1, 1);
-	}
-	if (dev->has_radio_tx) {
-		v4l2_ctrl_new_custom(hdl_radio_tx,
-			&vivid_ctrl_radio_tx_rds_blockio, NULL);
-		dev->radio_tx_rds_pi = v4l2_ctrl_new_std(hdl_radio_tx,
-			&vivid_radio_tx_ctrl_ops,
-			V4L2_CID_RDS_TX_PI, 0, 0xffff, 1, 0x8088);
-		dev->radio_tx_rds_pty = v4l2_ctrl_new_std(hdl_radio_tx,
-			&vivid_radio_tx_ctrl_ops,
-			V4L2_CID_RDS_TX_PTY, 0, 31, 1, 3);
-		dev->radio_tx_rds_psname = v4l2_ctrl_new_std(hdl_radio_tx,
-			&vivid_radio_tx_ctrl_ops,
-			V4L2_CID_RDS_TX_PS_NAME, 0, 8, 8, 0);
-		if (dev->radio_tx_rds_psname)
-			v4l2_ctrl_s_ctrl_string(dev->radio_tx_rds_psname, "VIVID-TX");
-		dev->radio_tx_rds_radiotext = v4l2_ctrl_new_std(hdl_radio_tx,
-			&vivid_radio_tx_ctrl_ops,
-			V4L2_CID_RDS_TX_RADIO_TEXT, 0, 64 * 2, 64, 0);
-		if (dev->radio_tx_rds_radiotext)
-			v4l2_ctrl_s_ctrl_string(dev->radio_tx_rds_radiotext,
-			       "This is a VIVID default Radio Text template text, change at will");
-		dev->radio_tx_rds_mono_stereo = v4l2_ctrl_new_std(hdl_radio_tx,
-			&vivid_radio_tx_ctrl_ops,
-			V4L2_CID_RDS_TX_MONO_STEREO, 0, 1, 1, 1);
-		dev->radio_tx_rds_art_head = v4l2_ctrl_new_std(hdl_radio_tx,
-			&vivid_radio_tx_ctrl_ops,
-			V4L2_CID_RDS_TX_ARTIFICIAL_HEAD, 0, 1, 1, 0);
-		dev->radio_tx_rds_compressed = v4l2_ctrl_new_std(hdl_radio_tx,
-			&vivid_radio_tx_ctrl_ops,
-			V4L2_CID_RDS_TX_COMPRESSED, 0, 1, 1, 0);
-		dev->radio_tx_rds_dyn_pty = v4l2_ctrl_new_std(hdl_radio_tx,
-			&vivid_radio_tx_ctrl_ops,
-			V4L2_CID_RDS_TX_DYNAMIC_PTY, 0, 1, 1, 0);
-		dev->radio_tx_rds_ta = v4l2_ctrl_new_std(hdl_radio_tx,
-			&vivid_radio_tx_ctrl_ops,
-			V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT, 0, 1, 1, 0);
-		dev->radio_tx_rds_tp = v4l2_ctrl_new_std(hdl_radio_tx,
-			&vivid_radio_tx_ctrl_ops,
-			V4L2_CID_RDS_TX_TRAFFIC_PROGRAM, 0, 1, 1, 1);
-		dev->radio_tx_rds_ms = v4l2_ctrl_new_std(hdl_radio_tx,
-			&vivid_radio_tx_ctrl_ops,
-			V4L2_CID_RDS_TX_MUSIC_SPEECH, 0, 1, 1, 1);
-	}
-	if (dev->has_sdr_cap) {
-		v4l2_ctrl_new_custom(hdl_sdr_cap,
-			&vivid_ctrl_sdr_cap_fm_deviation, NULL);
-	}
-	if (dev->has_meta_cap) {
-		v4l2_ctrl_new_custom(hdl_meta_cap,
-				     &vivid_ctrl_meta_has_pts, NULL);
-		v4l2_ctrl_new_custom(hdl_meta_cap,
-				     &vivid_ctrl_meta_has_src_clk, NULL);
-	}
-
-	if (hdl_user_gen->error)
-		return hdl_user_gen->error;
-	if (hdl_user_vid->error)
-		return hdl_user_vid->error;
-	if (hdl_user_aud->error)
-		return hdl_user_aud->error;
-	if (hdl_streaming->error)
-		return hdl_streaming->error;
-	if (hdl_sdr_cap->error)
-		return hdl_sdr_cap->error;
-	if (hdl_loop_cap->error)
-		return hdl_loop_cap->error;
-
-	if (dev->autogain)
-		v4l2_ctrl_auto_cluster(2, &dev->autogain, 0, true);
-
-	if (dev->has_vid_cap) {
-		v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_gen, NULL, false);
-		v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_vid, NULL, false);
-		v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_aud, NULL, false);
-		v4l2_ctrl_add_handler(hdl_vid_cap, hdl_streaming, NULL, false);
-		v4l2_ctrl_add_handler(hdl_vid_cap, hdl_sdtv_cap, NULL, false);
-		v4l2_ctrl_add_handler(hdl_vid_cap, hdl_loop_cap, NULL, false);
-		v4l2_ctrl_add_handler(hdl_vid_cap, hdl_fb, NULL, false);
-		if (hdl_vid_cap->error)
-			return hdl_vid_cap->error;
-		dev->vid_cap_dev.ctrl_handler = hdl_vid_cap;
-	}
-	if (dev->has_vid_out) {
-		v4l2_ctrl_add_handler(hdl_vid_out, hdl_user_gen, NULL, false);
-		v4l2_ctrl_add_handler(hdl_vid_out, hdl_user_aud, NULL, false);
-		v4l2_ctrl_add_handler(hdl_vid_out, hdl_streaming, NULL, false);
-		v4l2_ctrl_add_handler(hdl_vid_out, hdl_fb, NULL, false);
-		if (hdl_vid_out->error)
-			return hdl_vid_out->error;
-		dev->vid_out_dev.ctrl_handler = hdl_vid_out;
-	}
-	if (dev->has_vbi_cap) {
-		v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_user_gen, NULL, false);
-		v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_streaming, NULL, false);
-		v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_sdtv_cap, NULL, false);
-		v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_loop_cap, NULL, false);
-		if (hdl_vbi_cap->error)
-			return hdl_vbi_cap->error;
-		dev->vbi_cap_dev.ctrl_handler = hdl_vbi_cap;
-	}
-	if (dev->has_vbi_out) {
-		v4l2_ctrl_add_handler(hdl_vbi_out, hdl_user_gen, NULL, false);
-		v4l2_ctrl_add_handler(hdl_vbi_out, hdl_streaming, NULL, false);
-		if (hdl_vbi_out->error)
-			return hdl_vbi_out->error;
-		dev->vbi_out_dev.ctrl_handler = hdl_vbi_out;
-	}
-	if (dev->has_radio_rx) {
-		v4l2_ctrl_add_handler(hdl_radio_rx, hdl_user_gen, NULL, false);
-		v4l2_ctrl_add_handler(hdl_radio_rx, hdl_user_aud, NULL, false);
-		if (hdl_radio_rx->error)
-			return hdl_radio_rx->error;
-		dev->radio_rx_dev.ctrl_handler = hdl_radio_rx;
-	}
-	if (dev->has_radio_tx) {
-		v4l2_ctrl_add_handler(hdl_radio_tx, hdl_user_gen, NULL, false);
-		v4l2_ctrl_add_handler(hdl_radio_tx, hdl_user_aud, NULL, false);
-		if (hdl_radio_tx->error)
-			return hdl_radio_tx->error;
-		dev->radio_tx_dev.ctrl_handler = hdl_radio_tx;
-	}
-	if (dev->has_sdr_cap) {
-		v4l2_ctrl_add_handler(hdl_sdr_cap, hdl_user_gen, NULL, false);
-		v4l2_ctrl_add_handler(hdl_sdr_cap, hdl_streaming, NULL, false);
-		if (hdl_sdr_cap->error)
-			return hdl_sdr_cap->error;
-		dev->sdr_cap_dev.ctrl_handler = hdl_sdr_cap;
-	}
-	if (dev->has_meta_cap) {
-		v4l2_ctrl_add_handler(hdl_meta_cap, hdl_user_gen, NULL, false);
-		v4l2_ctrl_add_handler(hdl_meta_cap, hdl_streaming, NULL, false);
-		if (hdl_meta_cap->error)
-			return hdl_meta_cap->error;
-		dev->meta_cap_dev.ctrl_handler = hdl_meta_cap;
-	}
-	if (dev->has_meta_out) {
-		v4l2_ctrl_add_handler(hdl_meta_out, hdl_user_gen, NULL, false);
-		v4l2_ctrl_add_handler(hdl_meta_out, hdl_streaming, NULL, false);
-		if (hdl_meta_out->error)
-			return hdl_meta_out->error;
-		dev->meta_out_dev.ctrl_handler = hdl_meta_out;
-	}
-	if (dev->has_touch_cap) {
-		v4l2_ctrl_add_handler(hdl_tch_cap, hdl_user_gen, NULL, false);
-		v4l2_ctrl_add_handler(hdl_tch_cap, hdl_streaming, NULL, false);
-		if (hdl_tch_cap->error)
-			return hdl_tch_cap->error;
-		dev->touch_cap_dev.ctrl_handler = hdl_tch_cap;
-	}
-	return 0;
-}
-
-void vivid_free_controls(struct vivid_dev *dev)
-{
-	v4l2_ctrl_handler_free(&dev->ctrl_hdl_vid_cap);
-	v4l2_ctrl_handler_free(&dev->ctrl_hdl_vid_out);
-	v4l2_ctrl_handler_free(&dev->ctrl_hdl_vbi_cap);
-	v4l2_ctrl_handler_free(&dev->ctrl_hdl_vbi_out);
-	v4l2_ctrl_handler_free(&dev->ctrl_hdl_radio_rx);
-	v4l2_ctrl_handler_free(&dev->ctrl_hdl_radio_tx);
-	v4l2_ctrl_handler_free(&dev->ctrl_hdl_sdr_cap);
-	v4l2_ctrl_handler_free(&dev->ctrl_hdl_user_gen);
-	v4l2_ctrl_handler_free(&dev->ctrl_hdl_user_vid);
-	v4l2_ctrl_handler_free(&dev->ctrl_hdl_user_aud);
-	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);
-	v4l2_ctrl_handler_free(&dev->ctrl_hdl_meta_cap);
-	v4l2_ctrl_handler_free(&dev->ctrl_hdl_meta_out);
-	v4l2_ctrl_handler_free(&dev->ctrl_hdl_touch_cap);
-}
diff --git a/drivers/media/platform/vivid/vivid-ctrls.h b/drivers/media/platform/vivid/vivid-ctrls.h
deleted file mode 100644
index 6fad5f5d0054..000000000000
--- a/drivers/media/platform/vivid/vivid-ctrls.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * vivid-ctrls.h - control support functions.
- *
- * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#ifndef _VIVID_CTRLS_H_
-#define _VIVID_CTRLS_H_
-
-enum vivid_hw_seek_modes {
-	VIVID_HW_SEEK_BOUNDED,
-	VIVID_HW_SEEK_WRAP,
-	VIVID_HW_SEEK_BOTH,
-};
-
-int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
-		bool show_ccs_out, bool no_error_inj,
-		bool has_sdtv, bool has_hdmi);
-void vivid_free_controls(struct vivid_dev *dev);
-
-#endif
diff --git a/drivers/media/platform/vivid/vivid-kthread-cap.c b/drivers/media/platform/vivid/vivid-kthread-cap.c
deleted file mode 100644
index 01a9d671b947..000000000000
--- a/drivers/media/platform/vivid/vivid-kthread-cap.c
+++ /dev/null
@@ -1,1007 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * vivid-kthread-cap.h - video/vbi capture thread support functions.
- *
- * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/font.h>
-#include <linux/mutex.h>
-#include <linux/videodev2.h>
-#include <linux/kthread.h>
-#include <linux/freezer.h>
-#include <linux/random.h>
-#include <linux/v4l2-dv-timings.h>
-#include <asm/div64.h>
-#include <media/videobuf2-vmalloc.h>
-#include <media/v4l2-dv-timings.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-fh.h>
-#include <media/v4l2-event.h>
-#include <media/v4l2-rect.h>
-
-#include "vivid-core.h"
-#include "vivid-vid-common.h"
-#include "vivid-vid-cap.h"
-#include "vivid-vid-out.h"
-#include "vivid-radio-common.h"
-#include "vivid-radio-rx.h"
-#include "vivid-radio-tx.h"
-#include "vivid-sdr-cap.h"
-#include "vivid-vbi-cap.h"
-#include "vivid-vbi-out.h"
-#include "vivid-osd.h"
-#include "vivid-ctrls.h"
-#include "vivid-kthread-cap.h"
-#include "vivid-meta-cap.h"
-
-static inline v4l2_std_id vivid_get_std_cap(const struct vivid_dev *dev)
-{
-	if (vivid_is_sdtv_cap(dev))
-		return dev->std_cap[dev->input];
-	return 0;
-}
-
-static void copy_pix(struct vivid_dev *dev, int win_y, int win_x,
-			u16 *cap, const u16 *osd)
-{
-	u16 out;
-	int left = dev->overlay_out_left;
-	int top = dev->overlay_out_top;
-	int fb_x = win_x + left;
-	int fb_y = win_y + top;
-	int i;
-
-	out = *cap;
-	*cap = *osd;
-	if (dev->bitmap_out) {
-		const u8 *p = dev->bitmap_out;
-		unsigned stride = (dev->compose_out.width + 7) / 8;
-
-		win_x -= dev->compose_out.left;
-		win_y -= dev->compose_out.top;
-		if (!(p[stride * win_y + win_x / 8] & (1 << (win_x & 7))))
-			return;
-	}
-
-	for (i = 0; i < dev->clipcount_out; i++) {
-		struct v4l2_rect *r = &dev->clips_out[i].c;
-
-		if (fb_y >= r->top && fb_y < r->top + r->height &&
-		    fb_x >= r->left && fb_x < r->left + r->width)
-			return;
-	}
-	if ((dev->fbuf_out_flags & V4L2_FBUF_FLAG_CHROMAKEY) &&
-	    *osd != dev->chromakey_out)
-		return;
-	if ((dev->fbuf_out_flags & V4L2_FBUF_FLAG_SRC_CHROMAKEY) &&
-	    out == dev->chromakey_out)
-		return;
-	if (dev->fmt_cap->alpha_mask) {
-		if ((dev->fbuf_out_flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) &&
-		    dev->global_alpha_out)
-			return;
-		if ((dev->fbuf_out_flags & V4L2_FBUF_FLAG_LOCAL_ALPHA) &&
-		    *cap & dev->fmt_cap->alpha_mask)
-			return;
-		if ((dev->fbuf_out_flags & V4L2_FBUF_FLAG_LOCAL_INV_ALPHA) &&
-		    !(*cap & dev->fmt_cap->alpha_mask))
-			return;
-	}
-	*cap = out;
-}
-
-static void blend_line(struct vivid_dev *dev, unsigned y_offset, unsigned x_offset,
-		u8 *vcapbuf, const u8 *vosdbuf,
-		unsigned width, unsigned pixsize)
-{
-	unsigned x;
-
-	for (x = 0; x < width; x++, vcapbuf += pixsize, vosdbuf += pixsize) {
-		copy_pix(dev, y_offset, x_offset + x,
-			 (u16 *)vcapbuf, (const u16 *)vosdbuf);
-	}
-}
-
-static void scale_line(const u8 *src, u8 *dst, unsigned srcw, unsigned dstw, unsigned twopixsize)
-{
-	/* Coarse scaling with Bresenham */
-	unsigned int_part;
-	unsigned fract_part;
-	unsigned src_x = 0;
-	unsigned error = 0;
-	unsigned x;
-
-	/*
-	 * We always combine two pixels to prevent color bleed in the packed
-	 * yuv case.
-	 */
-	srcw /= 2;
-	dstw /= 2;
-	int_part = srcw / dstw;
-	fract_part = srcw % dstw;
-	for (x = 0; x < dstw; x++, dst += twopixsize) {
-		memcpy(dst, src + src_x * twopixsize, twopixsize);
-		src_x += int_part;
-		error += fract_part;
-		if (error >= dstw) {
-			error -= dstw;
-			src_x++;
-		}
-	}
-}
-
-/*
- * Precalculate the rectangles needed to perform video looping:
- *
- * The nominal pipeline is that the video output buffer is cropped by
- * crop_out, scaled to compose_out, overlaid with the output overlay,
- * cropped on the capture side by crop_cap and scaled again to the video
- * capture buffer using compose_cap.
- *
- * To keep things efficient we calculate the intersection of compose_out
- * and crop_cap (since that's the only part of the video that will
- * actually end up in the capture buffer), determine which part of the
- * video output buffer that is and which part of the video capture buffer
- * so we can scale the video straight from the output buffer to the capture
- * buffer without any intermediate steps.
- *
- * If we need to deal with an output overlay, then there is no choice and
- * that intermediate step still has to be taken. For the output overlay
- * support we calculate the intersection of the framebuffer and the overlay
- * window (which may be partially or wholly outside of the framebuffer
- * itself) and the intersection of that with loop_vid_copy (i.e. the part of
- * the actual looped video that will be overlaid). The result is calculated
- * both in framebuffer coordinates (loop_fb_copy) and compose_out coordinates
- * (loop_vid_overlay). Finally calculate the part of the capture buffer that
- * will receive that overlaid video.
- */
-static void vivid_precalc_copy_rects(struct vivid_dev *dev)
-{
-	/* Framebuffer rectangle */
-	struct v4l2_rect r_fb = {
-		0, 0, dev->display_width, dev->display_height
-	};
-	/* Overlay window rectangle in framebuffer coordinates */
-	struct v4l2_rect r_overlay = {
-		dev->overlay_out_left, dev->overlay_out_top,
-		dev->compose_out.width, dev->compose_out.height
-	};
-
-	v4l2_rect_intersect(&dev->loop_vid_copy, &dev->crop_cap, &dev->compose_out);
-
-	dev->loop_vid_out = dev->loop_vid_copy;
-	v4l2_rect_scale(&dev->loop_vid_out, &dev->compose_out, &dev->crop_out);
-	dev->loop_vid_out.left += dev->crop_out.left;
-	dev->loop_vid_out.top += dev->crop_out.top;
-
-	dev->loop_vid_cap = dev->loop_vid_copy;
-	v4l2_rect_scale(&dev->loop_vid_cap, &dev->crop_cap, &dev->compose_cap);
-
-	dprintk(dev, 1,
-		"loop_vid_copy: %dx%d@%dx%d loop_vid_out: %dx%d@%dx%d loop_vid_cap: %dx%d@%dx%d\n",
-		dev->loop_vid_copy.width, dev->loop_vid_copy.height,
-		dev->loop_vid_copy.left, dev->loop_vid_copy.top,
-		dev->loop_vid_out.width, dev->loop_vid_out.height,
-		dev->loop_vid_out.left, dev->loop_vid_out.top,
-		dev->loop_vid_cap.width, dev->loop_vid_cap.height,
-		dev->loop_vid_cap.left, dev->loop_vid_cap.top);
-
-	v4l2_rect_intersect(&r_overlay, &r_fb, &r_overlay);
-
-	/* shift r_overlay to the same origin as compose_out */
-	r_overlay.left += dev->compose_out.left - dev->overlay_out_left;
-	r_overlay.top += dev->compose_out.top - dev->overlay_out_top;
-
-	v4l2_rect_intersect(&dev->loop_vid_overlay, &r_overlay, &dev->loop_vid_copy);
-	dev->loop_fb_copy = dev->loop_vid_overlay;
-
-	/* shift dev->loop_fb_copy back again to the fb origin */
-	dev->loop_fb_copy.left -= dev->compose_out.left - dev->overlay_out_left;
-	dev->loop_fb_copy.top -= dev->compose_out.top - dev->overlay_out_top;
-
-	dev->loop_vid_overlay_cap = dev->loop_vid_overlay;
-	v4l2_rect_scale(&dev->loop_vid_overlay_cap, &dev->crop_cap, &dev->compose_cap);
-
-	dprintk(dev, 1,
-		"loop_fb_copy: %dx%d@%dx%d loop_vid_overlay: %dx%d@%dx%d loop_vid_overlay_cap: %dx%d@%dx%d\n",
-		dev->loop_fb_copy.width, dev->loop_fb_copy.height,
-		dev->loop_fb_copy.left, dev->loop_fb_copy.top,
-		dev->loop_vid_overlay.width, dev->loop_vid_overlay.height,
-		dev->loop_vid_overlay.left, dev->loop_vid_overlay.top,
-		dev->loop_vid_overlay_cap.width, dev->loop_vid_overlay_cap.height,
-		dev->loop_vid_overlay_cap.left, dev->loop_vid_overlay_cap.top);
-}
-
-static void *plane_vaddr(struct tpg_data *tpg, struct vivid_buffer *buf,
-			 unsigned p, unsigned bpl[TPG_MAX_PLANES], unsigned h)
-{
-	unsigned i;
-	void *vbuf;
-
-	if (p == 0 || tpg_g_buffers(tpg) > 1)
-		return vb2_plane_vaddr(&buf->vb.vb2_buf, p);
-	vbuf = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
-	for (i = 0; i < p; i++)
-		vbuf += bpl[i] * h / tpg->vdownsampling[i];
-	return vbuf;
-}
-
-static noinline_for_stack int vivid_copy_buffer(struct vivid_dev *dev, unsigned p,
-		u8 *vcapbuf, struct vivid_buffer *vid_cap_buf)
-{
-	bool blank = dev->must_blank[vid_cap_buf->vb.vb2_buf.index];
-	struct tpg_data *tpg = &dev->tpg;
-	struct vivid_buffer *vid_out_buf = NULL;
-	unsigned vdiv = dev->fmt_out->vdownsampling[p];
-	unsigned twopixsize = tpg_g_twopixelsize(tpg, p);
-	unsigned img_width = tpg_hdiv(tpg, p, dev->compose_cap.width);
-	unsigned img_height = dev->compose_cap.height;
-	unsigned stride_cap = tpg->bytesperline[p];
-	unsigned stride_out = dev->bytesperline_out[p];
-	unsigned stride_osd = dev->display_byte_stride;
-	unsigned hmax = (img_height * tpg->perc_fill) / 100;
-	u8 *voutbuf;
-	u8 *vosdbuf = NULL;
-	unsigned y;
-	bool blend = dev->bitmap_out || dev->clipcount_out || dev->fbuf_out_flags;
-	/* Coarse scaling with Bresenham */
-	unsigned vid_out_int_part;
-	unsigned vid_out_fract_part;
-	unsigned vid_out_y = 0;
-	unsigned vid_out_error = 0;
-	unsigned vid_overlay_int_part = 0;
-	unsigned vid_overlay_fract_part = 0;
-	unsigned vid_overlay_y = 0;
-	unsigned vid_overlay_error = 0;
-	unsigned vid_cap_left = tpg_hdiv(tpg, p, dev->loop_vid_cap.left);
-	unsigned vid_cap_right;
-	bool quick;
-
-	vid_out_int_part = dev->loop_vid_out.height / dev->loop_vid_cap.height;
-	vid_out_fract_part = dev->loop_vid_out.height % dev->loop_vid_cap.height;
-
-	if (!list_empty(&dev->vid_out_active))
-		vid_out_buf = list_entry(dev->vid_out_active.next,
-					 struct vivid_buffer, list);
-	if (vid_out_buf == NULL)
-		return -ENODATA;
-
-	vid_cap_buf->vb.field = vid_out_buf->vb.field;
-
-	voutbuf = plane_vaddr(tpg, vid_out_buf, p,
-			      dev->bytesperline_out, dev->fmt_out_rect.height);
-	if (p < dev->fmt_out->buffers)
-		voutbuf += vid_out_buf->vb.vb2_buf.planes[p].data_offset;
-	voutbuf += tpg_hdiv(tpg, p, dev->loop_vid_out.left) +
-		(dev->loop_vid_out.top / vdiv) * stride_out;
-	vcapbuf += tpg_hdiv(tpg, p, dev->compose_cap.left) +
-		(dev->compose_cap.top / vdiv) * stride_cap;
-
-	if (dev->loop_vid_copy.width == 0 || dev->loop_vid_copy.height == 0) {
-		/*
-		 * If there is nothing to copy, then just fill the capture window
-		 * with black.
-		 */
-		for (y = 0; y < hmax / vdiv; y++, vcapbuf += stride_cap)
-			memcpy(vcapbuf, tpg->black_line[p], img_width);
-		return 0;
-	}
-
-	if (dev->overlay_out_enabled &&
-	    dev->loop_vid_overlay.width && dev->loop_vid_overlay.height) {
-		vosdbuf = dev->video_vbase;
-		vosdbuf += (dev->loop_fb_copy.left * twopixsize) / 2 +
-			   dev->loop_fb_copy.top * stride_osd;
-		vid_overlay_int_part = dev->loop_vid_overlay.height /
-				       dev->loop_vid_overlay_cap.height;
-		vid_overlay_fract_part = dev->loop_vid_overlay.height %
-					 dev->loop_vid_overlay_cap.height;
-	}
-
-	vid_cap_right = tpg_hdiv(tpg, p, dev->loop_vid_cap.left + dev->loop_vid_cap.width);
-	/* quick is true if no video scaling is needed */
-	quick = dev->loop_vid_out.width == dev->loop_vid_cap.width;
-
-	dev->cur_scaled_line = dev->loop_vid_out.height;
-	for (y = 0; y < hmax; y += vdiv, vcapbuf += stride_cap) {
-		/* osdline is true if this line requires overlay blending */
-		bool osdline = vosdbuf && y >= dev->loop_vid_overlay_cap.top &&
-			  y < dev->loop_vid_overlay_cap.top + dev->loop_vid_overlay_cap.height;
-
-		/*
-		 * If this line of the capture buffer doesn't get any video, then
-		 * just fill with black.
-		 */
-		if (y < dev->loop_vid_cap.top ||
-		    y >= dev->loop_vid_cap.top + dev->loop_vid_cap.height) {
-			memcpy(vcapbuf, tpg->black_line[p], img_width);
-			continue;
-		}
-
-		/* fill the left border with black */
-		if (dev->loop_vid_cap.left)
-			memcpy(vcapbuf, tpg->black_line[p], vid_cap_left);
-
-		/* fill the right border with black */
-		if (vid_cap_right < img_width)
-			memcpy(vcapbuf + vid_cap_right, tpg->black_line[p],
-				img_width - vid_cap_right);
-
-		if (quick && !osdline) {
-			memcpy(vcapbuf + vid_cap_left,
-			       voutbuf + vid_out_y * stride_out,
-			       tpg_hdiv(tpg, p, dev->loop_vid_cap.width));
-			goto update_vid_out_y;
-		}
-		if (dev->cur_scaled_line == vid_out_y) {
-			memcpy(vcapbuf + vid_cap_left, dev->scaled_line,
-			       tpg_hdiv(tpg, p, dev->loop_vid_cap.width));
-			goto update_vid_out_y;
-		}
-		if (!osdline) {
-			scale_line(voutbuf + vid_out_y * stride_out, dev->scaled_line,
-				tpg_hdiv(tpg, p, dev->loop_vid_out.width),
-				tpg_hdiv(tpg, p, dev->loop_vid_cap.width),
-				tpg_g_twopixelsize(tpg, p));
-		} else {
-			/*
-			 * Offset in bytes within loop_vid_copy to the start of the
-			 * loop_vid_overlay rectangle.
-			 */
-			unsigned offset =
-				((dev->loop_vid_overlay.left - dev->loop_vid_copy.left) *
-				 twopixsize) / 2;
-			u8 *osd = vosdbuf + vid_overlay_y * stride_osd;
-
-			scale_line(voutbuf + vid_out_y * stride_out, dev->blended_line,
-				dev->loop_vid_out.width, dev->loop_vid_copy.width,
-				tpg_g_twopixelsize(tpg, p));
-			if (blend)
-				blend_line(dev, vid_overlay_y + dev->loop_vid_overlay.top,
-					   dev->loop_vid_overlay.left,
-					   dev->blended_line + offset, osd,
-					   dev->loop_vid_overlay.width, twopixsize / 2);
-			else
-				memcpy(dev->blended_line + offset,
-				       osd, (dev->loop_vid_overlay.width * twopixsize) / 2);
-			scale_line(dev->blended_line, dev->scaled_line,
-					dev->loop_vid_copy.width, dev->loop_vid_cap.width,
-					tpg_g_twopixelsize(tpg, p));
-		}
-		dev->cur_scaled_line = vid_out_y;
-		memcpy(vcapbuf + vid_cap_left, dev->scaled_line,
-		       tpg_hdiv(tpg, p, dev->loop_vid_cap.width));
-
-update_vid_out_y:
-		if (osdline) {
-			vid_overlay_y += vid_overlay_int_part;
-			vid_overlay_error += vid_overlay_fract_part;
-			if (vid_overlay_error >= dev->loop_vid_overlay_cap.height) {
-				vid_overlay_error -= dev->loop_vid_overlay_cap.height;
-				vid_overlay_y++;
-			}
-		}
-		vid_out_y += vid_out_int_part;
-		vid_out_error += vid_out_fract_part;
-		if (vid_out_error >= dev->loop_vid_cap.height / vdiv) {
-			vid_out_error -= dev->loop_vid_cap.height / vdiv;
-			vid_out_y++;
-		}
-	}
-
-	if (!blank)
-		return 0;
-	for (; y < img_height; y += vdiv, vcapbuf += stride_cap)
-		memcpy(vcapbuf, tpg->contrast_line[p], img_width);
-	return 0;
-}
-
-static void vivid_fillbuff(struct vivid_dev *dev, struct vivid_buffer *buf)
-{
-	struct tpg_data *tpg = &dev->tpg;
-	unsigned factor = V4L2_FIELD_HAS_T_OR_B(dev->field_cap) ? 2 : 1;
-	unsigned line_height = 16 / factor;
-	bool is_tv = vivid_is_sdtv_cap(dev);
-	bool is_60hz = is_tv && (dev->std_cap[dev->input] & V4L2_STD_525_60);
-	unsigned p;
-	int line = 1;
-	u8 *basep[TPG_MAX_PLANES][2];
-	unsigned ms;
-	char str[100];
-	s32 gain;
-	bool is_loop = false;
-
-	if (dev->loop_video && dev->can_loop_video &&
-		((vivid_is_svid_cap(dev) &&
-		!VIVID_INVALID_SIGNAL(dev->std_signal_mode[dev->input])) ||
-		(vivid_is_hdmi_cap(dev) &&
-		!VIVID_INVALID_SIGNAL(dev->dv_timings_signal_mode[dev->input]))))
-		is_loop = true;
-
-	buf->vb.sequence = dev->vid_cap_seq_count;
-	if (dev->field_cap == V4L2_FIELD_ALTERNATE) {
-		/*
-		 * 60 Hz standards start with the bottom field, 50 Hz standards
-		 * with the top field. So if the 0-based seq_count is even,
-		 * then the field is TOP for 50 Hz and BOTTOM for 60 Hz
-		 * standards.
-		 */
-		buf->vb.field = ((dev->vid_cap_seq_count & 1) ^ is_60hz) ?
-			V4L2_FIELD_BOTTOM : V4L2_FIELD_TOP;
-		/*
-		 * The sequence counter counts frames, not fields. So divide
-		 * by two.
-		 */
-		buf->vb.sequence /= 2;
-	} else {
-		buf->vb.field = dev->field_cap;
-	}
-	tpg_s_field(tpg, buf->vb.field,
-		    dev->field_cap == V4L2_FIELD_ALTERNATE);
-	tpg_s_perc_fill_blank(tpg, dev->must_blank[buf->vb.vb2_buf.index]);
-
-	vivid_precalc_copy_rects(dev);
-
-	for (p = 0; p < tpg_g_planes(tpg); p++) {
-		void *vbuf = plane_vaddr(tpg, buf, p,
-					 tpg->bytesperline, tpg->buf_height);
-
-		/*
-		 * The first plane of a multiplanar format has a non-zero
-		 * data_offset. This helps testing whether the application
-		 * correctly supports non-zero data offsets.
-		 */
-		if (p < tpg_g_buffers(tpg) && dev->fmt_cap->data_offset[p]) {
-			memset(vbuf, dev->fmt_cap->data_offset[p] & 0xff,
-			       dev->fmt_cap->data_offset[p]);
-			vbuf += dev->fmt_cap->data_offset[p];
-		}
-		tpg_calc_text_basep(tpg, basep, p, vbuf);
-		if (!is_loop || vivid_copy_buffer(dev, p, vbuf, buf))
-			tpg_fill_plane_buffer(tpg, vivid_get_std_cap(dev),
-					p, vbuf);
-	}
-	dev->must_blank[buf->vb.vb2_buf.index] = false;
-
-	/* Updates stream time, only update at the start of a new frame. */
-	if (dev->field_cap != V4L2_FIELD_ALTERNATE ||
-			(dev->vid_cap_seq_count & 1) == 0)
-		dev->ms_vid_cap =
-			jiffies_to_msecs(jiffies - dev->jiffies_vid_cap);
-
-	ms = dev->ms_vid_cap;
-	if (dev->osd_mode <= 1) {
-		snprintf(str, sizeof(str), " %02d:%02d:%02d:%03d %u%s",
-				(ms / (60 * 60 * 1000)) % 24,
-				(ms / (60 * 1000)) % 60,
-				(ms / 1000) % 60,
-				ms % 1000,
-				buf->vb.sequence,
-				(dev->field_cap == V4L2_FIELD_ALTERNATE) ?
-					(buf->vb.field == V4L2_FIELD_TOP ?
-					 " top" : " bottom") : "");
-		tpg_gen_text(tpg, basep, line++ * line_height, 16, str);
-	}
-	if (dev->osd_mode == 0) {
-		snprintf(str, sizeof(str), " %dx%d, input %d ",
-				dev->src_rect.width, dev->src_rect.height, dev->input);
-		tpg_gen_text(tpg, basep, line++ * line_height, 16, str);
-
-		gain = v4l2_ctrl_g_ctrl(dev->gain);
-		mutex_lock(dev->ctrl_hdl_user_vid.lock);
-		snprintf(str, sizeof(str),
-			" brightness %3d, contrast %3d, saturation %3d, hue %d ",
-			dev->brightness->cur.val,
-			dev->contrast->cur.val,
-			dev->saturation->cur.val,
-			dev->hue->cur.val);
-		tpg_gen_text(tpg, basep, line++ * line_height, 16, str);
-		snprintf(str, sizeof(str),
-			" autogain %d, gain %3d, alpha 0x%02x ",
-			dev->autogain->cur.val, gain, dev->alpha->cur.val);
-		mutex_unlock(dev->ctrl_hdl_user_vid.lock);
-		tpg_gen_text(tpg, basep, line++ * line_height, 16, str);
-		mutex_lock(dev->ctrl_hdl_user_aud.lock);
-		snprintf(str, sizeof(str),
-			" volume %3d, mute %d ",
-			dev->volume->cur.val, dev->mute->cur.val);
-		mutex_unlock(dev->ctrl_hdl_user_aud.lock);
-		tpg_gen_text(tpg, basep, line++ * line_height, 16, str);
-		mutex_lock(dev->ctrl_hdl_user_gen.lock);
-		snprintf(str, sizeof(str), " int32 %d, int64 %lld, bitmask %08x ",
-			dev->int32->cur.val,
-			*dev->int64->p_cur.p_s64,
-			dev->bitmask->cur.val);
-		tpg_gen_text(tpg, basep, line++ * line_height, 16, str);
-		snprintf(str, sizeof(str), " boolean %d, menu %s, string \"%s\" ",
-			dev->boolean->cur.val,
-			dev->menu->qmenu[dev->menu->cur.val],
-			dev->string->p_cur.p_char);
-		tpg_gen_text(tpg, basep, line++ * line_height, 16, str);
-		snprintf(str, sizeof(str), " integer_menu %lld, value %d ",
-			dev->int_menu->qmenu_int[dev->int_menu->cur.val],
-			dev->int_menu->cur.val);
-		mutex_unlock(dev->ctrl_hdl_user_gen.lock);
-		tpg_gen_text(tpg, basep, line++ * line_height, 16, str);
-		if (dev->button_pressed) {
-			dev->button_pressed--;
-			snprintf(str, sizeof(str), " button pressed!");
-			tpg_gen_text(tpg, basep, line++ * line_height, 16, str);
-		}
-		if (dev->osd[0]) {
-			if (vivid_is_hdmi_cap(dev)) {
-				snprintf(str, sizeof(str),
-					 " OSD \"%s\"", dev->osd);
-				tpg_gen_text(tpg, basep, line++ * line_height,
-					     16, str);
-			}
-			if (dev->osd_jiffies &&
-			    time_is_before_jiffies(dev->osd_jiffies + 5 * HZ)) {
-				dev->osd[0] = 0;
-				dev->osd_jiffies = 0;
-			}
-		}
-	}
-}
-
-/*
- * Return true if this pixel coordinate is a valid video pixel.
- */
-static bool valid_pix(struct vivid_dev *dev, int win_y, int win_x, int fb_y, int fb_x)
-{
-	int i;
-
-	if (dev->bitmap_cap) {
-		/*
-		 * Only if the corresponding bit in the bitmap is set can
-		 * the video pixel be shown. Coordinates are relative to
-		 * the overlay window set by VIDIOC_S_FMT.
-		 */
-		const u8 *p = dev->bitmap_cap;
-		unsigned stride = (dev->compose_cap.width + 7) / 8;
-
-		if (!(p[stride * win_y + win_x / 8] & (1 << (win_x & 7))))
-			return false;
-	}
-
-	for (i = 0; i < dev->clipcount_cap; i++) {
-		/*
-		 * Only if the framebuffer coordinate is not in any of the
-		 * clip rectangles will be video pixel be shown.
-		 */
-		struct v4l2_rect *r = &dev->clips_cap[i].c;
-
-		if (fb_y >= r->top && fb_y < r->top + r->height &&
-		    fb_x >= r->left && fb_x < r->left + r->width)
-			return false;
-	}
-	return true;
-}
-
-/*
- * Draw the image into the overlay buffer.
- * Note that the combination of overlay and multiplanar is not supported.
- */
-static void vivid_overlay(struct vivid_dev *dev, struct vivid_buffer *buf)
-{
-	struct tpg_data *tpg = &dev->tpg;
-	unsigned pixsize = tpg_g_twopixelsize(tpg, 0) / 2;
-	void *vbase = dev->fb_vbase_cap;
-	void *vbuf = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
-	unsigned img_width = dev->compose_cap.width;
-	unsigned img_height = dev->compose_cap.height;
-	unsigned stride = tpg->bytesperline[0];
-	/* if quick is true, then valid_pix() doesn't have to be called */
-	bool quick = dev->bitmap_cap == NULL && dev->clipcount_cap == 0;
-	int x, y, w, out_x = 0;
-
-	/*
-	 * Overlay support is only supported for formats that have a twopixelsize
-	 * that's >= 2. Warn and bail out if that's not the case.
-	 */
-	if (WARN_ON(pixsize == 0))
-		return;
-	if ((dev->overlay_cap_field == V4L2_FIELD_TOP ||
-	     dev->overlay_cap_field == V4L2_FIELD_BOTTOM) &&
-	    dev->overlay_cap_field != buf->vb.field)
-		return;
-
-	vbuf += dev->compose_cap.left * pixsize + dev->compose_cap.top * stride;
-	x = dev->overlay_cap_left;
-	w = img_width;
-	if (x < 0) {
-		out_x = -x;
-		w = w - out_x;
-		x = 0;
-	} else {
-		w = dev->fb_cap.fmt.width - x;
-		if (w > img_width)
-			w = img_width;
-	}
-	if (w <= 0)
-		return;
-	if (dev->overlay_cap_top >= 0)
-		vbase += dev->overlay_cap_top * dev->fb_cap.fmt.bytesperline;
-	for (y = dev->overlay_cap_top;
-	     y < dev->overlay_cap_top + (int)img_height;
-	     y++, vbuf += stride) {
-		int px;
-
-		if (y < 0 || y > dev->fb_cap.fmt.height)
-			continue;
-		if (quick) {
-			memcpy(vbase + x * pixsize,
-			       vbuf + out_x * pixsize, w * pixsize);
-			vbase += dev->fb_cap.fmt.bytesperline;
-			continue;
-		}
-		for (px = 0; px < w; px++) {
-			if (!valid_pix(dev, y - dev->overlay_cap_top,
-				       px + out_x, y, px + x))
-				continue;
-			memcpy(vbase + (px + x) * pixsize,
-			       vbuf + (px + out_x) * pixsize,
-			       pixsize);
-		}
-		vbase += dev->fb_cap.fmt.bytesperline;
-	}
-}
-
-static void vivid_cap_update_frame_period(struct vivid_dev *dev)
-{
-	u64 f_period;
-
-	f_period = (u64)dev->timeperframe_vid_cap.numerator * 1000000000;
-	if (WARN_ON(dev->timeperframe_vid_cap.denominator == 0))
-		dev->timeperframe_vid_cap.denominator = 1;
-	do_div(f_period, dev->timeperframe_vid_cap.denominator);
-	if (dev->field_cap == V4L2_FIELD_ALTERNATE)
-		f_period >>= 1;
-	/*
-	 * If "End of Frame", then offset the exposure time by 0.9
-	 * of the frame period.
-	 */
-	dev->cap_frame_eof_offset = f_period * 9;
-	do_div(dev->cap_frame_eof_offset, 10);
-	dev->cap_frame_period = f_period;
-}
-
-static noinline_for_stack void vivid_thread_vid_cap_tick(struct vivid_dev *dev,
-							 int dropped_bufs)
-{
-	struct vivid_buffer *vid_cap_buf = NULL;
-	struct vivid_buffer *vbi_cap_buf = NULL;
-	struct vivid_buffer *meta_cap_buf = NULL;
-	u64 f_time = 0;
-
-	dprintk(dev, 1, "Video Capture Thread Tick\n");
-
-	while (dropped_bufs-- > 1)
-		tpg_update_mv_count(&dev->tpg,
-				dev->field_cap == V4L2_FIELD_NONE ||
-				dev->field_cap == V4L2_FIELD_ALTERNATE);
-
-	/* Drop a certain percentage of buffers. */
-	if (dev->perc_dropped_buffers &&
-	    prandom_u32_max(100) < dev->perc_dropped_buffers)
-		goto update_mv;
-
-	spin_lock(&dev->slock);
-	if (!list_empty(&dev->vid_cap_active)) {
-		vid_cap_buf = list_entry(dev->vid_cap_active.next, struct vivid_buffer, list);
-		list_del(&vid_cap_buf->list);
-	}
-	if (!list_empty(&dev->vbi_cap_active)) {
-		if (dev->field_cap != V4L2_FIELD_ALTERNATE ||
-		    (dev->vbi_cap_seq_count & 1)) {
-			vbi_cap_buf = list_entry(dev->vbi_cap_active.next,
-						 struct vivid_buffer, list);
-			list_del(&vbi_cap_buf->list);
-		}
-	}
-	if (!list_empty(&dev->meta_cap_active)) {
-		meta_cap_buf = list_entry(dev->meta_cap_active.next,
-					  struct vivid_buffer, list);
-		list_del(&meta_cap_buf->list);
-	}
-
-	spin_unlock(&dev->slock);
-
-	if (!vid_cap_buf && !vbi_cap_buf && !meta_cap_buf)
-		goto update_mv;
-
-	f_time = dev->cap_frame_period * dev->vid_cap_seq_count +
-		 dev->cap_stream_start + dev->time_wrap_offset;
-
-	if (vid_cap_buf) {
-		v4l2_ctrl_request_setup(vid_cap_buf->vb.vb2_buf.req_obj.req,
-					&dev->ctrl_hdl_vid_cap);
-		/* Fill buffer */
-		vivid_fillbuff(dev, vid_cap_buf);
-		dprintk(dev, 1, "filled buffer %d\n",
-			vid_cap_buf->vb.vb2_buf.index);
-
-		/* Handle overlay */
-		if (dev->overlay_cap_owner && dev->fb_cap.base &&
-			dev->fb_cap.fmt.pixelformat == dev->fmt_cap->fourcc)
-			vivid_overlay(dev, vid_cap_buf);
-
-		v4l2_ctrl_request_complete(vid_cap_buf->vb.vb2_buf.req_obj.req,
-					   &dev->ctrl_hdl_vid_cap);
-		vb2_buffer_done(&vid_cap_buf->vb.vb2_buf, dev->dqbuf_error ?
-				VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
-		dprintk(dev, 2, "vid_cap buffer %d done\n",
-				vid_cap_buf->vb.vb2_buf.index);
-
-		vid_cap_buf->vb.vb2_buf.timestamp = f_time;
-		if (!dev->tstamp_src_is_soe)
-			vid_cap_buf->vb.vb2_buf.timestamp += dev->cap_frame_eof_offset;
-	}
-
-	if (vbi_cap_buf) {
-		u64 vbi_period;
-
-		v4l2_ctrl_request_setup(vbi_cap_buf->vb.vb2_buf.req_obj.req,
-					&dev->ctrl_hdl_vbi_cap);
-		if (dev->stream_sliced_vbi_cap)
-			vivid_sliced_vbi_cap_process(dev, vbi_cap_buf);
-		else
-			vivid_raw_vbi_cap_process(dev, vbi_cap_buf);
-		v4l2_ctrl_request_complete(vbi_cap_buf->vb.vb2_buf.req_obj.req,
-					   &dev->ctrl_hdl_vbi_cap);
-		vb2_buffer_done(&vbi_cap_buf->vb.vb2_buf, dev->dqbuf_error ?
-				VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
-		dprintk(dev, 2, "vbi_cap %d done\n",
-				vbi_cap_buf->vb.vb2_buf.index);
-
-		/* If capturing a VBI, offset by 0.05 */
-		vbi_period = dev->cap_frame_period * 5;
-		do_div(vbi_period, 100);
-		vbi_cap_buf->vb.vb2_buf.timestamp = f_time + dev->cap_frame_eof_offset + vbi_period;
-	}
-
-	if (meta_cap_buf) {
-		v4l2_ctrl_request_setup(meta_cap_buf->vb.vb2_buf.req_obj.req,
-					&dev->ctrl_hdl_meta_cap);
-		vivid_meta_cap_fillbuff(dev, meta_cap_buf, f_time);
-		v4l2_ctrl_request_complete(meta_cap_buf->vb.vb2_buf.req_obj.req,
-					   &dev->ctrl_hdl_meta_cap);
-		vb2_buffer_done(&meta_cap_buf->vb.vb2_buf, dev->dqbuf_error ?
-				VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
-		dprintk(dev, 2, "meta_cap %d done\n",
-			meta_cap_buf->vb.vb2_buf.index);
-		meta_cap_buf->vb.vb2_buf.timestamp = f_time + dev->cap_frame_eof_offset;
-	}
-
-	dev->dqbuf_error = false;
-
-update_mv:
-	/* Update the test pattern movement counters */
-	tpg_update_mv_count(&dev->tpg, dev->field_cap == V4L2_FIELD_NONE ||
-				       dev->field_cap == V4L2_FIELD_ALTERNATE);
-}
-
-static int vivid_thread_vid_cap(void *data)
-{
-	struct vivid_dev *dev = data;
-	u64 numerators_since_start;
-	u64 buffers_since_start;
-	u64 next_jiffies_since_start;
-	unsigned long jiffies_since_start;
-	unsigned long cur_jiffies;
-	unsigned wait_jiffies;
-	unsigned numerator;
-	unsigned denominator;
-	int dropped_bufs;
-
-	dprintk(dev, 1, "Video Capture Thread Start\n");
-
-	set_freezable();
-
-	/* Resets frame counters */
-	dev->cap_seq_offset = 0;
-	dev->cap_seq_count = 0;
-	dev->cap_seq_resync = false;
-	dev->jiffies_vid_cap = jiffies;
-	dev->cap_stream_start = ktime_get_ns();
-	vivid_cap_update_frame_period(dev);
-
-	for (;;) {
-		try_to_freeze();
-		if (kthread_should_stop())
-			break;
-
-		if (!mutex_trylock(&dev->mutex)) {
-			schedule_timeout_uninterruptible(1);
-			continue;
-		}
-
-		cur_jiffies = jiffies;
-		if (dev->cap_seq_resync) {
-			dev->jiffies_vid_cap = cur_jiffies;
-			dev->cap_seq_offset = dev->cap_seq_count + 1;
-			dev->cap_seq_count = 0;
-			dev->cap_stream_start += dev->cap_frame_period *
-						 dev->cap_seq_offset;
-			vivid_cap_update_frame_period(dev);
-			dev->cap_seq_resync = false;
-		}
-		numerator = dev->timeperframe_vid_cap.numerator;
-		denominator = dev->timeperframe_vid_cap.denominator;
-
-		if (dev->field_cap == V4L2_FIELD_ALTERNATE)
-			denominator *= 2;
-
-		/* Calculate the number of jiffies since we started streaming */
-		jiffies_since_start = cur_jiffies - dev->jiffies_vid_cap;
-		/* Get the number of buffers streamed since the start */
-		buffers_since_start = (u64)jiffies_since_start * denominator +
-				      (HZ * numerator) / 2;
-		do_div(buffers_since_start, HZ * numerator);
-
-		/*
-		 * After more than 0xf0000000 (rounded down to a multiple of
-		 * 'jiffies-per-day' to ease jiffies_to_msecs calculation)
-		 * jiffies have passed since we started streaming reset the
-		 * counters and keep track of the sequence offset.
-		 */
-		if (jiffies_since_start > JIFFIES_RESYNC) {
-			dev->jiffies_vid_cap = cur_jiffies;
-			dev->cap_seq_offset = buffers_since_start;
-			buffers_since_start = 0;
-		}
-		dropped_bufs = buffers_since_start + dev->cap_seq_offset - dev->cap_seq_count;
-		dev->cap_seq_count = buffers_since_start + dev->cap_seq_offset;
-		dev->vid_cap_seq_count = dev->cap_seq_count - dev->vid_cap_seq_start;
-		dev->vbi_cap_seq_count = dev->cap_seq_count - dev->vbi_cap_seq_start;
-		dev->meta_cap_seq_count = dev->cap_seq_count - dev->meta_cap_seq_start;
-
-		vivid_thread_vid_cap_tick(dev, dropped_bufs);
-
-		/*
-		 * Calculate the number of 'numerators' streamed since we started,
-		 * including the current buffer.
-		 */
-		numerators_since_start = ++buffers_since_start * numerator;
-
-		/* And the number of jiffies since we started */
-		jiffies_since_start = jiffies - dev->jiffies_vid_cap;
-
-		mutex_unlock(&dev->mutex);
-
-		/*
-		 * Calculate when that next buffer is supposed to start
-		 * in jiffies since we started streaming.
-		 */
-		next_jiffies_since_start = numerators_since_start * HZ +
-					   denominator / 2;
-		do_div(next_jiffies_since_start, denominator);
-		/* If it is in the past, then just schedule asap */
-		if (next_jiffies_since_start < jiffies_since_start)
-			next_jiffies_since_start = jiffies_since_start;
-
-		wait_jiffies = next_jiffies_since_start - jiffies_since_start;
-		schedule_timeout_interruptible(wait_jiffies ? wait_jiffies : 1);
-	}
-	dprintk(dev, 1, "Video Capture Thread End\n");
-	return 0;
-}
-
-static void vivid_grab_controls(struct vivid_dev *dev, bool grab)
-{
-	v4l2_ctrl_grab(dev->ctrl_has_crop_cap, grab);
-	v4l2_ctrl_grab(dev->ctrl_has_compose_cap, grab);
-	v4l2_ctrl_grab(dev->ctrl_has_scaler_cap, grab);
-}
-
-int vivid_start_generating_vid_cap(struct vivid_dev *dev, bool *pstreaming)
-{
-	dprintk(dev, 1, "%s\n", __func__);
-
-	if (dev->kthread_vid_cap) {
-		u32 seq_count = dev->cap_seq_count + dev->seq_wrap * 128;
-
-		if (pstreaming == &dev->vid_cap_streaming)
-			dev->vid_cap_seq_start = seq_count;
-		else if (pstreaming == &dev->vbi_cap_streaming)
-			dev->vbi_cap_seq_start = seq_count;
-		else
-			dev->meta_cap_seq_start = seq_count;
-		*pstreaming = true;
-		return 0;
-	}
-
-	/* Resets frame counters */
-	tpg_init_mv_count(&dev->tpg);
-
-	dev->vid_cap_seq_start = dev->seq_wrap * 128;
-	dev->vbi_cap_seq_start = dev->seq_wrap * 128;
-	dev->meta_cap_seq_start = dev->seq_wrap * 128;
-
-	dev->kthread_vid_cap = kthread_run(vivid_thread_vid_cap, dev,
-			"%s-vid-cap", dev->v4l2_dev.name);
-
-	if (IS_ERR(dev->kthread_vid_cap)) {
-		int err = PTR_ERR(dev->kthread_vid_cap);
-
-		dev->kthread_vid_cap = NULL;
-		v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n");
-		return err;
-	}
-	*pstreaming = true;
-	vivid_grab_controls(dev, true);
-
-	dprintk(dev, 1, "returning from %s\n", __func__);
-	return 0;
-}
-
-void vivid_stop_generating_vid_cap(struct vivid_dev *dev, bool *pstreaming)
-{
-	dprintk(dev, 1, "%s\n", __func__);
-
-	if (dev->kthread_vid_cap == NULL)
-		return;
-
-	*pstreaming = false;
-	if (pstreaming == &dev->vid_cap_streaming) {
-		/* Release all active buffers */
-		while (!list_empty(&dev->vid_cap_active)) {
-			struct vivid_buffer *buf;
-
-			buf = list_entry(dev->vid_cap_active.next,
-					 struct vivid_buffer, list);
-			list_del(&buf->list);
-			v4l2_ctrl_request_complete(buf->vb.vb2_buf.req_obj.req,
-						   &dev->ctrl_hdl_vid_cap);
-			vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
-			dprintk(dev, 2, "vid_cap buffer %d done\n",
-				buf->vb.vb2_buf.index);
-		}
-	}
-
-	if (pstreaming == &dev->vbi_cap_streaming) {
-		while (!list_empty(&dev->vbi_cap_active)) {
-			struct vivid_buffer *buf;
-
-			buf = list_entry(dev->vbi_cap_active.next,
-					 struct vivid_buffer, list);
-			list_del(&buf->list);
-			v4l2_ctrl_request_complete(buf->vb.vb2_buf.req_obj.req,
-						   &dev->ctrl_hdl_vbi_cap);
-			vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
-			dprintk(dev, 2, "vbi_cap buffer %d done\n",
-				buf->vb.vb2_buf.index);
-		}
-	}
-
-	if (pstreaming == &dev->meta_cap_streaming) {
-		while (!list_empty(&dev->meta_cap_active)) {
-			struct vivid_buffer *buf;
-
-			buf = list_entry(dev->meta_cap_active.next,
-					 struct vivid_buffer, list);
-			list_del(&buf->list);
-			v4l2_ctrl_request_complete(buf->vb.vb2_buf.req_obj.req,
-						   &dev->ctrl_hdl_meta_cap);
-			vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
-			dprintk(dev, 2, "meta_cap buffer %d done\n",
-				buf->vb.vb2_buf.index);
-		}
-	}
-
-	if (dev->vid_cap_streaming || dev->vbi_cap_streaming ||
-	    dev->meta_cap_streaming)
-		return;
-
-	/* shutdown control thread */
-	vivid_grab_controls(dev, false);
-	kthread_stop(dev->kthread_vid_cap);
-	dev->kthread_vid_cap = NULL;
-}
diff --git a/drivers/media/platform/vivid/vivid-kthread-cap.h b/drivers/media/platform/vivid/vivid-kthread-cap.h
deleted file mode 100644
index 0f43015306d6..000000000000
--- a/drivers/media/platform/vivid/vivid-kthread-cap.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * vivid-kthread-cap.h - video/vbi capture thread support functions.
- *
- * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#ifndef _VIVID_KTHREAD_CAP_H_
-#define _VIVID_KTHREAD_CAP_H_
-
-int vivid_start_generating_vid_cap(struct vivid_dev *dev, bool *pstreaming);
-void vivid_stop_generating_vid_cap(struct vivid_dev *dev, bool *pstreaming);
-
-#endif
diff --git a/drivers/media/platform/vivid/vivid-kthread-out.c b/drivers/media/platform/vivid/vivid-kthread-out.c
deleted file mode 100644
index 6780687978f9..000000000000
--- a/drivers/media/platform/vivid/vivid-kthread-out.c
+++ /dev/null
@@ -1,353 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * vivid-kthread-out.h - video/vbi output thread support functions.
- *
- * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/font.h>
-#include <linux/mutex.h>
-#include <linux/videodev2.h>
-#include <linux/kthread.h>
-#include <linux/freezer.h>
-#include <linux/random.h>
-#include <linux/v4l2-dv-timings.h>
-#include <asm/div64.h>
-#include <media/videobuf2-vmalloc.h>
-#include <media/v4l2-dv-timings.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-fh.h>
-#include <media/v4l2-event.h>
-
-#include "vivid-core.h"
-#include "vivid-vid-common.h"
-#include "vivid-vid-cap.h"
-#include "vivid-vid-out.h"
-#include "vivid-radio-common.h"
-#include "vivid-radio-rx.h"
-#include "vivid-radio-tx.h"
-#include "vivid-sdr-cap.h"
-#include "vivid-vbi-cap.h"
-#include "vivid-vbi-out.h"
-#include "vivid-osd.h"
-#include "vivid-ctrls.h"
-#include "vivid-kthread-out.h"
-#include "vivid-meta-out.h"
-
-static void vivid_thread_vid_out_tick(struct vivid_dev *dev)
-{
-	struct vivid_buffer *vid_out_buf = NULL;
-	struct vivid_buffer *vbi_out_buf = NULL;
-	struct vivid_buffer *meta_out_buf = NULL;
-
-	dprintk(dev, 1, "Video Output Thread Tick\n");
-
-	/* Drop a certain percentage of buffers. */
-	if (dev->perc_dropped_buffers &&
-	    prandom_u32_max(100) < dev->perc_dropped_buffers)
-		return;
-
-	spin_lock(&dev->slock);
-	/*
-	 * Only dequeue buffer if there is at least one more pending.
-	 * This makes video loopback possible.
-	 */
-	if (!list_empty(&dev->vid_out_active) &&
-	    !list_is_singular(&dev->vid_out_active)) {
-		vid_out_buf = list_entry(dev->vid_out_active.next,
-					 struct vivid_buffer, list);
-		list_del(&vid_out_buf->list);
-	}
-	if (!list_empty(&dev->vbi_out_active) &&
-	    (dev->field_out != V4L2_FIELD_ALTERNATE ||
-	     (dev->vbi_out_seq_count & 1))) {
-		vbi_out_buf = list_entry(dev->vbi_out_active.next,
-					 struct vivid_buffer, list);
-		list_del(&vbi_out_buf->list);
-	}
-	if (!list_empty(&dev->meta_out_active)) {
-		meta_out_buf = list_entry(dev->meta_out_active.next,
-					  struct vivid_buffer, list);
-		list_del(&meta_out_buf->list);
-	}
-	spin_unlock(&dev->slock);
-
-	if (!vid_out_buf && !vbi_out_buf && !meta_out_buf)
-		return;
-
-	if (vid_out_buf) {
-		v4l2_ctrl_request_setup(vid_out_buf->vb.vb2_buf.req_obj.req,
-					&dev->ctrl_hdl_vid_out);
-		v4l2_ctrl_request_complete(vid_out_buf->vb.vb2_buf.req_obj.req,
-					   &dev->ctrl_hdl_vid_out);
-		vid_out_buf->vb.sequence = dev->vid_out_seq_count;
-		if (dev->field_out == V4L2_FIELD_ALTERNATE) {
-			/*
-			 * The sequence counter counts frames, not fields.
-			 * So divide by two.
-			 */
-			vid_out_buf->vb.sequence /= 2;
-		}
-		vid_out_buf->vb.vb2_buf.timestamp =
-			ktime_get_ns() + dev->time_wrap_offset;
-		vb2_buffer_done(&vid_out_buf->vb.vb2_buf, dev->dqbuf_error ?
-				VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
-		dprintk(dev, 2, "vid_out buffer %d done\n",
-			vid_out_buf->vb.vb2_buf.index);
-	}
-
-	if (vbi_out_buf) {
-		v4l2_ctrl_request_setup(vbi_out_buf->vb.vb2_buf.req_obj.req,
-					&dev->ctrl_hdl_vbi_out);
-		v4l2_ctrl_request_complete(vbi_out_buf->vb.vb2_buf.req_obj.req,
-					   &dev->ctrl_hdl_vbi_out);
-		if (dev->stream_sliced_vbi_out)
-			vivid_sliced_vbi_out_process(dev, vbi_out_buf);
-
-		vbi_out_buf->vb.sequence = dev->vbi_out_seq_count;
-		vbi_out_buf->vb.vb2_buf.timestamp =
-			ktime_get_ns() + dev->time_wrap_offset;
-		vb2_buffer_done(&vbi_out_buf->vb.vb2_buf, dev->dqbuf_error ?
-				VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
-		dprintk(dev, 2, "vbi_out buffer %d done\n",
-			vbi_out_buf->vb.vb2_buf.index);
-	}
-	if (meta_out_buf) {
-		v4l2_ctrl_request_setup(meta_out_buf->vb.vb2_buf.req_obj.req,
-					&dev->ctrl_hdl_meta_out);
-		v4l2_ctrl_request_complete(meta_out_buf->vb.vb2_buf.req_obj.req,
-					   &dev->ctrl_hdl_meta_out);
-		vivid_meta_out_process(dev, meta_out_buf);
-		meta_out_buf->vb.sequence = dev->meta_out_seq_count;
-		meta_out_buf->vb.vb2_buf.timestamp =
-			ktime_get_ns() + dev->time_wrap_offset;
-		vb2_buffer_done(&meta_out_buf->vb.vb2_buf, dev->dqbuf_error ?
-				VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
-		dprintk(dev, 2, "meta_out buffer %d done\n",
-			meta_out_buf->vb.vb2_buf.index);
-	}
-
-	dev->dqbuf_error = false;
-}
-
-static int vivid_thread_vid_out(void *data)
-{
-	struct vivid_dev *dev = data;
-	u64 numerators_since_start;
-	u64 buffers_since_start;
-	u64 next_jiffies_since_start;
-	unsigned long jiffies_since_start;
-	unsigned long cur_jiffies;
-	unsigned wait_jiffies;
-	unsigned numerator;
-	unsigned denominator;
-
-	dprintk(dev, 1, "Video Output Thread Start\n");
-
-	set_freezable();
-
-	/* Resets frame counters */
-	dev->out_seq_offset = 0;
-	if (dev->seq_wrap)
-		dev->out_seq_count = 0xffffff80U;
-	dev->jiffies_vid_out = jiffies;
-	dev->vid_out_seq_start = dev->vbi_out_seq_start = 0;
-	dev->meta_out_seq_start = 0;
-	dev->out_seq_resync = false;
-
-	for (;;) {
-		try_to_freeze();
-		if (kthread_should_stop())
-			break;
-
-		if (!mutex_trylock(&dev->mutex)) {
-			schedule_timeout_uninterruptible(1);
-			continue;
-		}
-
-		cur_jiffies = jiffies;
-		if (dev->out_seq_resync) {
-			dev->jiffies_vid_out = cur_jiffies;
-			dev->out_seq_offset = dev->out_seq_count + 1;
-			dev->out_seq_count = 0;
-			dev->out_seq_resync = false;
-		}
-		numerator = dev->timeperframe_vid_out.numerator;
-		denominator = dev->timeperframe_vid_out.denominator;
-
-		if (dev->field_out == V4L2_FIELD_ALTERNATE)
-			denominator *= 2;
-
-		/* Calculate the number of jiffies since we started streaming */
-		jiffies_since_start = cur_jiffies - dev->jiffies_vid_out;
-		/* Get the number of buffers streamed since the start */
-		buffers_since_start = (u64)jiffies_since_start * denominator +
-				      (HZ * numerator) / 2;
-		do_div(buffers_since_start, HZ * numerator);
-
-		/*
-		 * After more than 0xf0000000 (rounded down to a multiple of
-		 * 'jiffies-per-day' to ease jiffies_to_msecs calculation)
-		 * jiffies have passed since we started streaming reset the
-		 * counters and keep track of the sequence offset.
-		 */
-		if (jiffies_since_start > JIFFIES_RESYNC) {
-			dev->jiffies_vid_out = cur_jiffies;
-			dev->out_seq_offset = buffers_since_start;
-			buffers_since_start = 0;
-		}
-		dev->out_seq_count = buffers_since_start + dev->out_seq_offset;
-		dev->vid_out_seq_count = dev->out_seq_count - dev->vid_out_seq_start;
-		dev->vbi_out_seq_count = dev->out_seq_count - dev->vbi_out_seq_start;
-		dev->meta_out_seq_count = dev->out_seq_count - dev->meta_out_seq_start;
-
-		vivid_thread_vid_out_tick(dev);
-		mutex_unlock(&dev->mutex);
-
-		/*
-		 * Calculate the number of 'numerators' streamed since we started,
-		 * not including the current buffer.
-		 */
-		numerators_since_start = buffers_since_start * numerator;
-
-		/* And the number of jiffies since we started */
-		jiffies_since_start = jiffies - dev->jiffies_vid_out;
-
-		/* Increase by the 'numerator' of one buffer */
-		numerators_since_start += numerator;
-		/*
-		 * Calculate when that next buffer is supposed to start
-		 * in jiffies since we started streaming.
-		 */
-		next_jiffies_since_start = numerators_since_start * HZ +
-					   denominator / 2;
-		do_div(next_jiffies_since_start, denominator);
-		/* If it is in the past, then just schedule asap */
-		if (next_jiffies_since_start < jiffies_since_start)
-			next_jiffies_since_start = jiffies_since_start;
-
-		wait_jiffies = next_jiffies_since_start - jiffies_since_start;
-		schedule_timeout_interruptible(wait_jiffies ? wait_jiffies : 1);
-	}
-	dprintk(dev, 1, "Video Output Thread End\n");
-	return 0;
-}
-
-static void vivid_grab_controls(struct vivid_dev *dev, bool grab)
-{
-	v4l2_ctrl_grab(dev->ctrl_has_crop_out, grab);
-	v4l2_ctrl_grab(dev->ctrl_has_compose_out, grab);
-	v4l2_ctrl_grab(dev->ctrl_has_scaler_out, grab);
-	v4l2_ctrl_grab(dev->ctrl_tx_mode, grab);
-	v4l2_ctrl_grab(dev->ctrl_tx_rgb_range, grab);
-}
-
-int vivid_start_generating_vid_out(struct vivid_dev *dev, bool *pstreaming)
-{
-	dprintk(dev, 1, "%s\n", __func__);
-
-	if (dev->kthread_vid_out) {
-		u32 seq_count = dev->out_seq_count + dev->seq_wrap * 128;
-
-		if (pstreaming == &dev->vid_out_streaming)
-			dev->vid_out_seq_start = seq_count;
-		else if (pstreaming == &dev->vbi_out_streaming)
-			dev->vbi_out_seq_start = seq_count;
-		else
-			dev->meta_out_seq_start = seq_count;
-		*pstreaming = true;
-		return 0;
-	}
-
-	/* Resets frame counters */
-	dev->jiffies_vid_out = jiffies;
-	dev->vid_out_seq_start = dev->seq_wrap * 128;
-	dev->vbi_out_seq_start = dev->seq_wrap * 128;
-	dev->meta_out_seq_start = dev->seq_wrap * 128;
-
-	dev->kthread_vid_out = kthread_run(vivid_thread_vid_out, dev,
-			"%s-vid-out", dev->v4l2_dev.name);
-
-	if (IS_ERR(dev->kthread_vid_out)) {
-		int err = PTR_ERR(dev->kthread_vid_out);
-
-		dev->kthread_vid_out = NULL;
-		v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n");
-		return err;
-	}
-	*pstreaming = true;
-	vivid_grab_controls(dev, true);
-
-	dprintk(dev, 1, "returning from %s\n", __func__);
-	return 0;
-}
-
-void vivid_stop_generating_vid_out(struct vivid_dev *dev, bool *pstreaming)
-{
-	dprintk(dev, 1, "%s\n", __func__);
-
-	if (dev->kthread_vid_out == NULL)
-		return;
-
-	*pstreaming = false;
-	if (pstreaming == &dev->vid_out_streaming) {
-		/* Release all active buffers */
-		while (!list_empty(&dev->vid_out_active)) {
-			struct vivid_buffer *buf;
-
-			buf = list_entry(dev->vid_out_active.next,
-					 struct vivid_buffer, list);
-			list_del(&buf->list);
-			v4l2_ctrl_request_complete(buf->vb.vb2_buf.req_obj.req,
-						   &dev->ctrl_hdl_vid_out);
-			vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
-			dprintk(dev, 2, "vid_out buffer %d done\n",
-				buf->vb.vb2_buf.index);
-		}
-	}
-
-	if (pstreaming == &dev->vbi_out_streaming) {
-		while (!list_empty(&dev->vbi_out_active)) {
-			struct vivid_buffer *buf;
-
-			buf = list_entry(dev->vbi_out_active.next,
-					 struct vivid_buffer, list);
-			list_del(&buf->list);
-			v4l2_ctrl_request_complete(buf->vb.vb2_buf.req_obj.req,
-						   &dev->ctrl_hdl_vbi_out);
-			vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
-			dprintk(dev, 2, "vbi_out buffer %d done\n",
-				buf->vb.vb2_buf.index);
-		}
-	}
-
-	if (pstreaming == &dev->meta_out_streaming) {
-		while (!list_empty(&dev->meta_out_active)) {
-			struct vivid_buffer *buf;
-
-			buf = list_entry(dev->meta_out_active.next,
-					 struct vivid_buffer, list);
-			list_del(&buf->list);
-			v4l2_ctrl_request_complete(buf->vb.vb2_buf.req_obj.req,
-						   &dev->ctrl_hdl_meta_out);
-			vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
-			dprintk(dev, 2, "meta_out buffer %d done\n",
-				buf->vb.vb2_buf.index);
-		}
-	}
-
-	if (dev->vid_out_streaming || dev->vbi_out_streaming ||
-	    dev->meta_out_streaming)
-		return;
-
-	/* shutdown control thread */
-	vivid_grab_controls(dev, false);
-	kthread_stop(dev->kthread_vid_out);
-	dev->kthread_vid_out = NULL;
-}
diff --git a/drivers/media/platform/vivid/vivid-kthread-out.h b/drivers/media/platform/vivid/vivid-kthread-out.h
deleted file mode 100644
index d5bcf44bbaca..000000000000
--- a/drivers/media/platform/vivid/vivid-kthread-out.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * vivid-kthread-out.h - video/vbi output thread support functions.
- *
- * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#ifndef _VIVID_KTHREAD_OUT_H_
-#define _VIVID_KTHREAD_OUT_H_
-
-int vivid_start_generating_vid_out(struct vivid_dev *dev, bool *pstreaming);
-void vivid_stop_generating_vid_out(struct vivid_dev *dev, bool *pstreaming);
-
-#endif
diff --git a/drivers/media/platform/vivid/vivid-kthread-touch.c b/drivers/media/platform/vivid/vivid-kthread-touch.c
deleted file mode 100644
index 674507b5ccb5..000000000000
--- a/drivers/media/platform/vivid/vivid-kthread-touch.c
+++ /dev/null
@@ -1,181 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * vivid-kthread-touch.c - touch capture thread support functions.
- *
- */
-
-#include <linux/freezer.h>
-#include "vivid-core.h"
-#include "vivid-kthread-touch.h"
-#include "vivid-touch-cap.h"
-
-static noinline_for_stack void vivid_thread_tch_cap_tick(struct vivid_dev *dev,
-							 int dropped_bufs)
-{
-	struct vivid_buffer *tch_cap_buf = NULL;
-
-	spin_lock(&dev->slock);
-	if (!list_empty(&dev->touch_cap_active)) {
-		tch_cap_buf = list_entry(dev->touch_cap_active.next,
-					 struct vivid_buffer, list);
-		list_del(&tch_cap_buf->list);
-	}
-
-	spin_unlock(&dev->slock);
-
-	if (tch_cap_buf) {
-		v4l2_ctrl_request_setup(tch_cap_buf->vb.vb2_buf.req_obj.req,
-					&dev->ctrl_hdl_touch_cap);
-
-		vivid_fillbuff_tch(dev, tch_cap_buf);
-		v4l2_ctrl_request_complete(tch_cap_buf->vb.vb2_buf.req_obj.req,
-					   &dev->ctrl_hdl_touch_cap);
-		vb2_buffer_done(&tch_cap_buf->vb.vb2_buf, dev->dqbuf_error ?
-				VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
-		dprintk(dev, 2, "touch_cap buffer %d done\n",
-			tch_cap_buf->vb.vb2_buf.index);
-
-		tch_cap_buf->vb.vb2_buf.timestamp = ktime_get_ns() + dev->time_wrap_offset;
-	}
-	dev->dqbuf_error = false;
-}
-
-static int vivid_thread_touch_cap(void *data)
-{
-	struct vivid_dev *dev = data;
-	u64 numerators_since_start;
-	u64 buffers_since_start;
-	u64 next_jiffies_since_start;
-	unsigned long jiffies_since_start;
-	unsigned long cur_jiffies;
-	unsigned int wait_jiffies;
-	unsigned int numerator;
-	unsigned int denominator;
-	int dropped_bufs;
-
-	dprintk(dev, 1, "Touch Capture Thread Start\n");
-
-	set_freezable();
-
-	/* Resets frame counters */
-	dev->touch_cap_seq_offset = 0;
-	dev->touch_cap_seq_count = 0;
-	dev->touch_cap_seq_resync = false;
-	dev->jiffies_touch_cap = jiffies;
-
-	for (;;) {
-		try_to_freeze();
-		if (kthread_should_stop())
-			break;
-
-		if (!mutex_trylock(&dev->mutex)) {
-			schedule_timeout_uninterruptible(1);
-			continue;
-		}
-		cur_jiffies = jiffies;
-		if (dev->touch_cap_seq_resync) {
-			dev->jiffies_touch_cap = cur_jiffies;
-			dev->touch_cap_seq_offset = dev->touch_cap_seq_count + 1;
-			dev->touch_cap_seq_count = 0;
-			dev->cap_seq_resync = false;
-		}
-		denominator = dev->timeperframe_tch_cap.denominator;
-		numerator = dev->timeperframe_tch_cap.numerator;
-
-		/* Calculate the number of jiffies since we started streaming */
-		jiffies_since_start = cur_jiffies - dev->jiffies_touch_cap;
-		/* Get the number of buffers streamed since the start */
-		buffers_since_start = (u64)jiffies_since_start * denominator +
-				      (HZ * numerator) / 2;
-		do_div(buffers_since_start, HZ * numerator);
-
-		/*
-		 * After more than 0xf0000000 (rounded down to a multiple of
-		 * 'jiffies-per-day' to ease jiffies_to_msecs calculation)
-		 * jiffies have passed since we started streaming reset the
-		 * counters and keep track of the sequence offset.
-		 */
-		if (jiffies_since_start > JIFFIES_RESYNC) {
-			dev->jiffies_touch_cap = cur_jiffies;
-			dev->cap_seq_offset = buffers_since_start;
-			buffers_since_start = 0;
-		}
-		dropped_bufs = buffers_since_start + dev->touch_cap_seq_offset - dev->touch_cap_seq_count;
-		dev->touch_cap_seq_count = buffers_since_start + dev->touch_cap_seq_offset;
-
-		vivid_thread_tch_cap_tick(dev, dropped_bufs);
-
-		/*
-		 * Calculate the number of 'numerators' streamed
-		 * since we started, including the current buffer.
-		 */
-		numerators_since_start = ++buffers_since_start * numerator;
-
-		/* And the number of jiffies since we started */
-		jiffies_since_start = jiffies - dev->jiffies_touch_cap;
-
-		mutex_unlock(&dev->mutex);
-
-		/*
-		 * Calculate when that next buffer is supposed to start
-		 * in jiffies since we started streaming.
-		 */
-		next_jiffies_since_start = numerators_since_start * HZ +
-					   denominator / 2;
-		do_div(next_jiffies_since_start, denominator);
-		/* If it is in the past, then just schedule asap */
-		if (next_jiffies_since_start < jiffies_since_start)
-			next_jiffies_since_start = jiffies_since_start;
-
-		wait_jiffies = next_jiffies_since_start - jiffies_since_start;
-		schedule_timeout_interruptible(wait_jiffies ? wait_jiffies : 1);
-	}
-	dprintk(dev, 1, "Touch Capture Thread End\n");
-	return 0;
-}
-
-int vivid_start_generating_touch_cap(struct vivid_dev *dev)
-{
-	if (dev->kthread_touch_cap) {
-		dev->touch_cap_streaming = true;
-		return 0;
-	}
-
-	dev->kthread_touch_cap = kthread_run(vivid_thread_touch_cap, dev,
-					     "%s-tch-cap", dev->v4l2_dev.name);
-
-	if (IS_ERR(dev->kthread_touch_cap)) {
-		int err = PTR_ERR(dev->kthread_touch_cap);
-
-		dev->kthread_touch_cap = NULL;
-		v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n");
-		return err;
-	}
-	dev->touch_cap_streaming = true;
-	dprintk(dev, 1, "returning from %s\n", __func__);
-	return 0;
-}
-
-void vivid_stop_generating_touch_cap(struct vivid_dev *dev)
-{
-	if (!dev->kthread_touch_cap)
-		return;
-
-	dev->touch_cap_streaming = false;
-
-	while (!list_empty(&dev->touch_cap_active)) {
-		struct vivid_buffer *buf;
-
-		buf = list_entry(dev->touch_cap_active.next,
-				 struct vivid_buffer, list);
-		list_del(&buf->list);
-		v4l2_ctrl_request_complete(buf->vb.vb2_buf.req_obj.req,
-					   &dev->ctrl_hdl_touch_cap);
-		vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
-		dprintk(dev, 2, "touch_cap buffer %d done\n",
-			buf->vb.vb2_buf.index);
-	}
-
-	kthread_stop(dev->kthread_touch_cap);
-	dev->kthread_touch_cap = NULL;
-}
diff --git a/drivers/media/platform/vivid/vivid-kthread-touch.h b/drivers/media/platform/vivid/vivid-kthread-touch.h
deleted file mode 100644
index ecf79b46209e..000000000000
--- a/drivers/media/platform/vivid/vivid-kthread-touch.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * vivid-kthread-cap.h - video/vbi capture thread support functions.
- *
- */
-
-#ifndef _VIVID_KTHREAD_CAP_H_
-#define _VIVID_KTHREAD_CAP_H_
-
-int vivid_start_generating_touch_cap(struct vivid_dev *dev);
-void vivid_stop_generating_touch_cap(struct vivid_dev *dev);
-
-#endif
diff --git a/drivers/media/platform/vivid/vivid-meta-cap.c b/drivers/media/platform/vivid/vivid-meta-cap.c
deleted file mode 100644
index 780f96860a6d..000000000000
--- a/drivers/media/platform/vivid/vivid-meta-cap.c
+++ /dev/null
@@ -1,201 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * vivid-meta-cap.c - meta capture support functions.
- */
-
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-#include <linux/usb/video.h>
-
-#include "vivid-core.h"
-#include "vivid-kthread-cap.h"
-#include "vivid-meta-cap.h"
-
-static int meta_cap_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
-				unsigned int *nplanes, unsigned int sizes[],
-				struct device *alloc_devs[])
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vq);
-	unsigned int size =  sizeof(struct vivid_uvc_meta_buf);
-
-	if (!vivid_is_webcam(dev))
-		return -EINVAL;
-
-	if (*nplanes) {
-		if (sizes[0] < size)
-			return -EINVAL;
-	} else {
-		sizes[0] = size;
-	}
-
-	if (vq->num_buffers + *nbuffers < 2)
-		*nbuffers = 2 - vq->num_buffers;
-
-	*nplanes = 1;
-	return 0;
-}
-
-static int meta_cap_buf_prepare(struct vb2_buffer *vb)
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
-	unsigned int size = sizeof(struct vivid_uvc_meta_buf);
-
-	dprintk(dev, 1, "%s\n", __func__);
-
-	if (dev->buf_prepare_error) {
-		/*
-		 * Error injection: test what happens if buf_prepare() returns
-		 * an error.
-		 */
-		dev->buf_prepare_error = false;
-		return -EINVAL;
-	}
-	if (vb2_plane_size(vb, 0) < size) {
-		dprintk(dev, 1, "%s data will not fit into plane (%lu < %u)\n",
-			__func__, vb2_plane_size(vb, 0), size);
-		return -EINVAL;
-	}
-	vb2_set_plane_payload(vb, 0, size);
-
-	return 0;
-}
-
-static void meta_cap_buf_queue(struct vb2_buffer *vb)
-{
-	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
-	struct vivid_buffer *buf = container_of(vbuf, struct vivid_buffer, vb);
-
-	dprintk(dev, 1, "%s\n", __func__);
-
-	spin_lock(&dev->slock);
-	list_add_tail(&buf->list, &dev->meta_cap_active);
-	spin_unlock(&dev->slock);
-}
-
-static int meta_cap_start_streaming(struct vb2_queue *vq, unsigned int count)
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vq);
-	int err;
-
-	dprintk(dev, 1, "%s\n", __func__);
-	dev->meta_cap_seq_count = 0;
-	if (dev->start_streaming_error) {
-		dev->start_streaming_error = false;
-		err = -EINVAL;
-	} else {
-		err = vivid_start_generating_vid_cap(dev,
-						     &dev->meta_cap_streaming);
-	}
-	if (err) {
-		struct vivid_buffer *buf, *tmp;
-
-		list_for_each_entry_safe(buf, tmp,
-					 &dev->meta_cap_active, list) {
-			list_del(&buf->list);
-			vb2_buffer_done(&buf->vb.vb2_buf,
-					VB2_BUF_STATE_QUEUED);
-		}
-	}
-	return err;
-}
-
-/* abort streaming and wait for last buffer */
-static void meta_cap_stop_streaming(struct vb2_queue *vq)
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vq);
-
-	dprintk(dev, 1, "%s\n", __func__);
-	vivid_stop_generating_vid_cap(dev, &dev->meta_cap_streaming);
-}
-
-static void meta_cap_buf_request_complete(struct vb2_buffer *vb)
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
-
-	v4l2_ctrl_request_complete(vb->req_obj.req, &dev->ctrl_hdl_meta_cap);
-}
-
-const struct vb2_ops vivid_meta_cap_qops = {
-	.queue_setup		= meta_cap_queue_setup,
-	.buf_prepare		= meta_cap_buf_prepare,
-	.buf_queue		= meta_cap_buf_queue,
-	.start_streaming	= meta_cap_start_streaming,
-	.stop_streaming		= meta_cap_stop_streaming,
-	.buf_request_complete	= meta_cap_buf_request_complete,
-	.wait_prepare		= vb2_ops_wait_prepare,
-	.wait_finish		= vb2_ops_wait_finish,
-};
-
-int vidioc_enum_fmt_meta_cap(struct file *file, void  *priv,
-			     struct v4l2_fmtdesc *f)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (!vivid_is_webcam(dev))
-		return -EINVAL;
-
-	if (f->index > 0)
-		return -EINVAL;
-
-	f->type = V4L2_BUF_TYPE_META_CAPTURE;
-	f->pixelformat = V4L2_META_FMT_UVC;
-	return 0;
-}
-
-int vidioc_g_fmt_meta_cap(struct file *file, void *priv,
-			  struct v4l2_format *f)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	struct v4l2_meta_format *meta = &f->fmt.meta;
-
-	if (!vivid_is_webcam(dev) || !dev->has_meta_cap)
-		return -EINVAL;
-
-	meta->dataformat = V4L2_META_FMT_UVC;
-	meta->buffersize = sizeof(struct vivid_uvc_meta_buf);
-	return 0;
-}
-
-void vivid_meta_cap_fillbuff(struct vivid_dev *dev,
-			     struct vivid_buffer *buf, u64 soe)
-{
-	struct vivid_uvc_meta_buf *meta = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
-	int buf_off = 0;
-
-	buf->vb.sequence = dev->meta_cap_seq_count;
-	if (dev->field_cap == V4L2_FIELD_ALTERNATE)
-		buf->vb.sequence /= 2;
-	memset(meta, 1, vb2_plane_size(&buf->vb.vb2_buf, 0));
-
-	meta->ns = ktime_get_ns();
-	meta->sof = buf->vb.sequence * 30;
-	meta->length = sizeof(*meta) - offsetof(struct vivid_uvc_meta_buf, length);
-	meta->flags = UVC_STREAM_EOH | UVC_STREAM_EOF;
-
-	if ((buf->vb.sequence % 2) == 0)
-		meta->flags |= UVC_STREAM_FID;
-
-	dprintk(dev, 2, "%s ns:%llu sof:%4d len:%u flags: 0x%02x",
-		__func__, meta->ns, meta->sof, meta->length, meta->flags);
-	if (dev->meta_pts) {
-		meta->flags |= UVC_STREAM_PTS;
-		meta->buf[0] = div_u64(soe, VIVID_META_CLOCK_UNIT);
-		buf_off = 4;
-		dprintk(dev, 2, " pts: %u\n", *(__u32 *)(meta->buf));
-	}
-
-	if (dev->meta_scr) {
-		meta->flags |= UVC_STREAM_SCR;
-		meta->buf[buf_off] = div_u64((soe + dev->cap_frame_eof_offset),
-					     VIVID_META_CLOCK_UNIT);
-
-		meta->buf[buf_off + 4] = (buf->vb.sequence * 30) % 1000;
-		dprintk(dev, 2, " stc: %u, sof counter: %u\n",
-			*(__u32 *)(meta->buf + buf_off),
-			*(__u16 *)(meta->buf + buf_off + 4));
-	}
-	dprintk(dev, 2, "\n");
-}
diff --git a/drivers/media/platform/vivid/vivid-meta-cap.h b/drivers/media/platform/vivid/vivid-meta-cap.h
deleted file mode 100644
index 4670d00d1576..000000000000
--- a/drivers/media/platform/vivid/vivid-meta-cap.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * vivid-meta-cap.h - meta capture support functions.
- */
-#ifndef _VIVID_META_CAP_H_
-#define _VIVID_META_CAP_H_
-
-#define VIVID_META_CLOCK_UNIT	10 /* 100 MHz */
-
-struct vivid_uvc_meta_buf {
-	__u64 ns;
-	__u16 sof;
-	__u8 length;
-	__u8 flags;
-	__u8 buf[10]; /* PTS(4)+STC(4)+SOF(2) */
-} __packed;
-
-void vivid_meta_cap_fillbuff(struct vivid_dev *dev,
-			     struct vivid_buffer *buf, u64 soe);
-
-int vidioc_enum_fmt_meta_cap(struct file *file, void  *priv,
-			     struct v4l2_fmtdesc *f);
-
-int vidioc_g_fmt_meta_cap(struct file *file, void *priv,
-			  struct v4l2_format *f);
-
-extern const struct vb2_ops vivid_meta_cap_qops;
-
-#endif
diff --git a/drivers/media/platform/vivid/vivid-meta-out.c b/drivers/media/platform/vivid/vivid-meta-out.c
deleted file mode 100644
index ff8a039aba72..000000000000
--- a/drivers/media/platform/vivid/vivid-meta-out.c
+++ /dev/null
@@ -1,174 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * vivid-meta-out.c - meta output support functions.
- */
-
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-#include <linux/usb/video.h>
-
-#include "vivid-core.h"
-#include "vivid-kthread-out.h"
-#include "vivid-meta-out.h"
-
-static int meta_out_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
-				unsigned int *nplanes, unsigned int sizes[],
-				struct device *alloc_devs[])
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vq);
-	unsigned int size =  sizeof(struct vivid_meta_out_buf);
-
-	if (!vivid_is_webcam(dev))
-		return -EINVAL;
-
-	if (*nplanes) {
-		if (sizes[0] < size)
-			return -EINVAL;
-	} else {
-		sizes[0] = size;
-	}
-
-	if (vq->num_buffers + *nbuffers < 2)
-		*nbuffers = 2 - vq->num_buffers;
-
-	*nplanes = 1;
-	return 0;
-}
-
-static int meta_out_buf_prepare(struct vb2_buffer *vb)
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
-	unsigned int size = sizeof(struct vivid_meta_out_buf);
-
-	dprintk(dev, 1, "%s\n", __func__);
-
-	if (dev->buf_prepare_error) {
-		/*
-		 * Error injection: test what happens if buf_prepare() returns
-		 * an error.
-		 */
-		dev->buf_prepare_error = false;
-		return -EINVAL;
-	}
-	if (vb2_plane_size(vb, 0) < size) {
-		dprintk(dev, 1, "%s data will not fit into plane (%lu < %u)\n",
-			__func__, vb2_plane_size(vb, 0), size);
-		return -EINVAL;
-	}
-	vb2_set_plane_payload(vb, 0, size);
-
-	return 0;
-}
-
-static void meta_out_buf_queue(struct vb2_buffer *vb)
-{
-	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
-	struct vivid_buffer *buf = container_of(vbuf, struct vivid_buffer, vb);
-
-	dprintk(dev, 1, "%s\n", __func__);
-
-	spin_lock(&dev->slock);
-	list_add_tail(&buf->list, &dev->meta_out_active);
-	spin_unlock(&dev->slock);
-}
-
-static int meta_out_start_streaming(struct vb2_queue *vq, unsigned int count)
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vq);
-	int err;
-
-	dprintk(dev, 1, "%s\n", __func__);
-	dev->meta_out_seq_count = 0;
-	if (dev->start_streaming_error) {
-		dev->start_streaming_error = false;
-		err = -EINVAL;
-	} else {
-		err = vivid_start_generating_vid_out(dev,
-						     &dev->meta_out_streaming);
-	}
-	if (err) {
-		struct vivid_buffer *buf, *tmp;
-
-		list_for_each_entry_safe(buf, tmp,
-					 &dev->meta_out_active, list) {
-			list_del(&buf->list);
-			vb2_buffer_done(&buf->vb.vb2_buf,
-					VB2_BUF_STATE_QUEUED);
-		}
-	}
-	return err;
-}
-
-/* abort streaming and wait for last buffer */
-static void meta_out_stop_streaming(struct vb2_queue *vq)
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vq);
-
-	dprintk(dev, 1, "%s\n", __func__);
-	vivid_stop_generating_vid_out(dev, &dev->meta_out_streaming);
-}
-
-static void meta_out_buf_request_complete(struct vb2_buffer *vb)
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
-
-	v4l2_ctrl_request_complete(vb->req_obj.req, &dev->ctrl_hdl_meta_out);
-}
-
-const struct vb2_ops vivid_meta_out_qops = {
-	.queue_setup            = meta_out_queue_setup,
-	.buf_prepare            = meta_out_buf_prepare,
-	.buf_queue              = meta_out_buf_queue,
-	.start_streaming        = meta_out_start_streaming,
-	.stop_streaming         = meta_out_stop_streaming,
-	.buf_request_complete   = meta_out_buf_request_complete,
-	.wait_prepare           = vb2_ops_wait_prepare,
-	.wait_finish            = vb2_ops_wait_finish,
-};
-
-int vidioc_enum_fmt_meta_out(struct file *file, void  *priv,
-			     struct v4l2_fmtdesc *f)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (!vivid_is_webcam(dev))
-		return -EINVAL;
-
-	if (f->index > 0)
-		return -EINVAL;
-
-	f->type = V4L2_BUF_TYPE_META_OUTPUT;
-	f->pixelformat = V4L2_META_FMT_VIVID;
-	return 0;
-}
-
-int vidioc_g_fmt_meta_out(struct file *file, void *priv,
-			  struct v4l2_format *f)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	struct v4l2_meta_format *meta = &f->fmt.meta;
-
-	if (!vivid_is_webcam(dev) || !dev->has_meta_out)
-		return -EINVAL;
-
-	meta->dataformat = V4L2_META_FMT_VIVID;
-	meta->buffersize = sizeof(struct vivid_meta_out_buf);
-	return 0;
-}
-
-void vivid_meta_out_process(struct vivid_dev *dev,
-			    struct vivid_buffer *buf)
-{
-	struct vivid_meta_out_buf *meta = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
-
-	tpg_s_brightness(&dev->tpg, meta->brightness);
-	tpg_s_contrast(&dev->tpg, meta->contrast);
-	tpg_s_saturation(&dev->tpg, meta->saturation);
-	tpg_s_hue(&dev->tpg, meta->hue);
-	dprintk(dev, 2, " %s brightness %u contrast %u saturation %u hue %d\n",
-		__func__, meta->brightness, meta->contrast,
-		meta->saturation, meta->hue);
-}
diff --git a/drivers/media/platform/vivid/vivid-meta-out.h b/drivers/media/platform/vivid/vivid-meta-out.h
deleted file mode 100644
index 0c639b7c2842..000000000000
--- a/drivers/media/platform/vivid/vivid-meta-out.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * vivid-meta-out.h - meta output support functions.
- */
-#ifndef _VIVID_META_OUT_H_
-#define _VIVID_META_OUT_H_
-
-struct vivid_meta_out_buf {
-	u16	brightness;
-	u16	contrast;
-	u16	saturation;
-	s16	hue;
-};
-
-void vivid_meta_out_process(struct vivid_dev *dev, struct vivid_buffer *buf);
-int vidioc_enum_fmt_meta_out(struct file *file, void  *priv,
-			     struct v4l2_fmtdesc *f);
-int vidioc_g_fmt_meta_out(struct file *file, void *priv,
-			  struct v4l2_format *f);
-int vidioc_s_fmt_meta_out(struct file *file, void *priv,
-			  struct v4l2_format *f);
-
-extern const struct vb2_ops vivid_meta_out_qops;
-
-#endif
diff --git a/drivers/media/platform/vivid/vivid-osd.c b/drivers/media/platform/vivid/vivid-osd.c
deleted file mode 100644
index fbaec8acc161..000000000000
--- a/drivers/media/platform/vivid/vivid-osd.c
+++ /dev/null
@@ -1,388 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * vivid-osd.c - osd support for testing overlays.
- *
- * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/font.h>
-#include <linux/mutex.h>
-#include <linux/videodev2.h>
-#include <linux/kthread.h>
-#include <linux/freezer.h>
-#include <linux/fb.h>
-#include <media/videobuf2-vmalloc.h>
-#include <media/v4l2-device.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 "vivid-core.h"
-#include "vivid-osd.h"
-
-#define MAX_OSD_WIDTH  720
-#define MAX_OSD_HEIGHT 576
-
-/*
- * Order: white, yellow, cyan, green, magenta, red, blue, black,
- * and same again with the alpha bit set (if any)
- */
-static const u16 rgb555[16] = {
-	0x7fff, 0x7fe0, 0x03ff, 0x03e0, 0x7c1f, 0x7c00, 0x001f, 0x0000,
-	0xffff, 0xffe0, 0x83ff, 0x83e0, 0xfc1f, 0xfc00, 0x801f, 0x8000
-};
-
-static const u16 rgb565[16] = {
-	0xffff, 0xffe0, 0x07ff, 0x07e0, 0xf81f, 0xf800, 0x001f, 0x0000,
-	0xffff, 0xffe0, 0x07ff, 0x07e0, 0xf81f, 0xf800, 0x001f, 0x0000
-};
-
-void vivid_clear_fb(struct vivid_dev *dev)
-{
-	void *p = dev->video_vbase;
-	const u16 *rgb = rgb555;
-	unsigned x, y;
-
-	if (dev->fb_defined.green.length == 6)
-		rgb = rgb565;
-
-	for (y = 0; y < dev->display_height; y++) {
-		u16 *d = p;
-
-		for (x = 0; x < dev->display_width; x++)
-			d[x] = rgb[(y / 16 + x / 16) % 16];
-		p += dev->display_byte_stride;
-	}
-}
-
-/* --------------------------------------------------------------------- */
-
-static int vivid_fb_ioctl(struct fb_info *info, unsigned cmd, unsigned long arg)
-{
-	struct vivid_dev *dev = (struct vivid_dev *)info->par;
-
-	switch (cmd) {
-	case FBIOGET_VBLANK: {
-		struct fb_vblank vblank;
-
-		memset(&vblank, 0, sizeof(vblank));
-		vblank.flags = FB_VBLANK_HAVE_COUNT | FB_VBLANK_HAVE_VCOUNT |
-			FB_VBLANK_HAVE_VSYNC;
-		vblank.count = 0;
-		vblank.vcount = 0;
-		vblank.hcount = 0;
-		if (copy_to_user((void __user *)arg, &vblank, sizeof(vblank)))
-			return -EFAULT;
-		return 0;
-	}
-
-	default:
-		dprintk(dev, 1, "Unknown ioctl %08x\n", cmd);
-		return -EINVAL;
-	}
-	return 0;
-}
-
-/* Framebuffer device handling */
-
-static int vivid_fb_set_var(struct vivid_dev *dev, struct fb_var_screeninfo *var)
-{
-	dprintk(dev, 1, "vivid_fb_set_var\n");
-
-	if (var->bits_per_pixel != 16) {
-		dprintk(dev, 1, "vivid_fb_set_var - Invalid bpp\n");
-		return -EINVAL;
-	}
-	dev->display_byte_stride = var->xres * dev->bytes_per_pixel;
-
-	return 0;
-}
-
-static int vivid_fb_get_fix(struct vivid_dev *dev, struct fb_fix_screeninfo *fix)
-{
-	dprintk(dev, 1, "vivid_fb_get_fix\n");
-	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
-	strscpy(fix->id, "vioverlay fb", sizeof(fix->id));
-	fix->smem_start = dev->video_pbase;
-	fix->smem_len = dev->video_buffer_size;
-	fix->type = FB_TYPE_PACKED_PIXELS;
-	fix->visual = FB_VISUAL_TRUECOLOR;
-	fix->xpanstep = 1;
-	fix->ypanstep = 1;
-	fix->ywrapstep = 0;
-	fix->line_length = dev->display_byte_stride;
-	fix->accel = FB_ACCEL_NONE;
-	return 0;
-}
-
-/* Check the requested display mode, returning -EINVAL if we can't
-   handle it. */
-
-static int _vivid_fb_check_var(struct fb_var_screeninfo *var, struct vivid_dev *dev)
-{
-	dprintk(dev, 1, "vivid_fb_check_var\n");
-
-	var->bits_per_pixel = 16;
-	if (var->green.length == 5) {
-		var->red.offset = 10;
-		var->red.length = 5;
-		var->green.offset = 5;
-		var->green.length = 5;
-		var->blue.offset = 0;
-		var->blue.length = 5;
-		var->transp.offset = 15;
-		var->transp.length = 1;
-	} else {
-		var->red.offset = 11;
-		var->red.length = 5;
-		var->green.offset = 5;
-		var->green.length = 6;
-		var->blue.offset = 0;
-		var->blue.length = 5;
-		var->transp.offset = 0;
-		var->transp.length = 0;
-	}
-	var->xoffset = var->yoffset = 0;
-	var->left_margin = var->upper_margin = 0;
-	var->nonstd = 0;
-
-	var->vmode &= ~FB_VMODE_MASK;
-	var->vmode |= FB_VMODE_NONINTERLACED;
-
-	/* Dummy values */
-	var->hsync_len = 24;
-	var->vsync_len = 2;
-	var->pixclock = 84316;
-	var->right_margin = 776;
-	var->lower_margin = 591;
-	return 0;
-}
-
-static int vivid_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
-{
-	struct vivid_dev *dev = (struct vivid_dev *) info->par;
-
-	dprintk(dev, 1, "vivid_fb_check_var\n");
-	return _vivid_fb_check_var(var, dev);
-}
-
-static int vivid_fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
-{
-	return 0;
-}
-
-static int vivid_fb_set_par(struct fb_info *info)
-{
-	int rc = 0;
-	struct vivid_dev *dev = (struct vivid_dev *) info->par;
-
-	dprintk(dev, 1, "vivid_fb_set_par\n");
-
-	rc = vivid_fb_set_var(dev, &info->var);
-	vivid_fb_get_fix(dev, &info->fix);
-	return rc;
-}
-
-static int vivid_fb_setcolreg(unsigned regno, unsigned red, unsigned green,
-				unsigned blue, unsigned transp,
-				struct fb_info *info)
-{
-	u32 color, *palette;
-
-	if (regno >= info->cmap.len)
-		return -EINVAL;
-
-	color = ((transp & 0xFF00) << 16) | ((red & 0xFF00) << 8) |
-		 (green & 0xFF00) | ((blue & 0xFF00) >> 8);
-	if (regno >= 16)
-		return -EINVAL;
-
-	palette = info->pseudo_palette;
-	if (info->var.bits_per_pixel == 16) {
-		switch (info->var.green.length) {
-		case 6:
-			color = (red & 0xf800) |
-				((green & 0xfc00) >> 5) |
-				((blue & 0xf800) >> 11);
-			break;
-		case 5:
-			color = ((red & 0xf800) >> 1) |
-				((green & 0xf800) >> 6) |
-				((blue & 0xf800) >> 11) |
-				(transp ? 0x8000 : 0);
-			break;
-		}
-	}
-	palette[regno] = color;
-	return 0;
-}
-
-/* We don't really support blanking. All this does is enable or
-   disable the OSD. */
-static int vivid_fb_blank(int blank_mode, struct fb_info *info)
-{
-	struct vivid_dev *dev = (struct vivid_dev *)info->par;
-
-	dprintk(dev, 1, "Set blanking mode : %d\n", blank_mode);
-	switch (blank_mode) {
-	case FB_BLANK_UNBLANK:
-		break;
-	case FB_BLANK_NORMAL:
-	case FB_BLANK_HSYNC_SUSPEND:
-	case FB_BLANK_VSYNC_SUSPEND:
-	case FB_BLANK_POWERDOWN:
-		break;
-	}
-	return 0;
-}
-
-static const struct fb_ops vivid_fb_ops = {
-	.owner = THIS_MODULE,
-	.fb_check_var   = vivid_fb_check_var,
-	.fb_set_par     = vivid_fb_set_par,
-	.fb_setcolreg   = vivid_fb_setcolreg,
-	.fb_fillrect    = cfb_fillrect,
-	.fb_copyarea    = cfb_copyarea,
-	.fb_imageblit   = cfb_imageblit,
-	.fb_cursor      = NULL,
-	.fb_ioctl       = vivid_fb_ioctl,
-	.fb_pan_display = vivid_fb_pan_display,
-	.fb_blank       = vivid_fb_blank,
-};
-
-/* Initialization */
-
-
-/* Setup our initial video mode */
-static int vivid_fb_init_vidmode(struct vivid_dev *dev)
-{
-	struct v4l2_rect start_window;
-
-	/* Color mode */
-
-	dev->bits_per_pixel = 16;
-	dev->bytes_per_pixel = dev->bits_per_pixel / 8;
-
-	start_window.width = MAX_OSD_WIDTH;
-	start_window.left = 0;
-
-	dev->display_byte_stride = start_window.width * dev->bytes_per_pixel;
-
-	/* Vertical size & position */
-
-	start_window.height = MAX_OSD_HEIGHT;
-	start_window.top = 0;
-
-	dev->display_width = start_window.width;
-	dev->display_height = start_window.height;
-
-	/* Generate a valid fb_var_screeninfo */
-
-	dev->fb_defined.xres = dev->display_width;
-	dev->fb_defined.yres = dev->display_height;
-	dev->fb_defined.xres_virtual = dev->display_width;
-	dev->fb_defined.yres_virtual = dev->display_height;
-	dev->fb_defined.bits_per_pixel = dev->bits_per_pixel;
-	dev->fb_defined.vmode = FB_VMODE_NONINTERLACED;
-	dev->fb_defined.left_margin = start_window.left + 1;
-	dev->fb_defined.upper_margin = start_window.top + 1;
-	dev->fb_defined.accel_flags = FB_ACCEL_NONE;
-	dev->fb_defined.nonstd = 0;
-	/* set default to 1:5:5:5 */
-	dev->fb_defined.green.length = 5;
-
-	/* We've filled in the most data, let the usual mode check
-	   routine fill in the rest. */
-	_vivid_fb_check_var(&dev->fb_defined, dev);
-
-	/* Generate valid fb_fix_screeninfo */
-
-	vivid_fb_get_fix(dev, &dev->fb_fix);
-
-	/* Generate valid fb_info */
-
-	dev->fb_info.node = -1;
-	dev->fb_info.flags = FBINFO_FLAG_DEFAULT;
-	dev->fb_info.par = dev;
-	dev->fb_info.var = dev->fb_defined;
-	dev->fb_info.fix = dev->fb_fix;
-	dev->fb_info.screen_base = (u8 __iomem *)dev->video_vbase;
-	dev->fb_info.fbops = &vivid_fb_ops;
-
-	/* Supply some monitor specs. Bogus values will do for now */
-	dev->fb_info.monspecs.hfmin = 8000;
-	dev->fb_info.monspecs.hfmax = 70000;
-	dev->fb_info.monspecs.vfmin = 10;
-	dev->fb_info.monspecs.vfmax = 100;
-
-	/* Allocate color map */
-	if (fb_alloc_cmap(&dev->fb_info.cmap, 256, 1)) {
-		pr_err("abort, unable to alloc cmap\n");
-		return -ENOMEM;
-	}
-
-	/* Allocate the pseudo palette */
-	dev->fb_info.pseudo_palette = kmalloc_array(16, sizeof(u32), GFP_KERNEL);
-
-	return dev->fb_info.pseudo_palette ? 0 : -ENOMEM;
-}
-
-/* Release any memory we've grabbed */
-void vivid_fb_release_buffers(struct vivid_dev *dev)
-{
-	if (dev->video_vbase == NULL)
-		return;
-
-	/* Release cmap */
-	if (dev->fb_info.cmap.len)
-		fb_dealloc_cmap(&dev->fb_info.cmap);
-
-	/* Release pseudo palette */
-	kfree(dev->fb_info.pseudo_palette);
-	kfree(dev->video_vbase);
-}
-
-/* Initialize the specified card */
-
-int vivid_fb_init(struct vivid_dev *dev)
-{
-	int ret;
-
-	dev->video_buffer_size = MAX_OSD_HEIGHT * MAX_OSD_WIDTH * 2;
-	dev->video_vbase = kzalloc(dev->video_buffer_size, GFP_KERNEL | GFP_DMA32);
-	if (dev->video_vbase == NULL)
-		return -ENOMEM;
-	dev->video_pbase = virt_to_phys(dev->video_vbase);
-
-	pr_info("Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
-			dev->video_pbase, dev->video_vbase,
-			dev->video_buffer_size / 1024);
-
-	/* Set the startup video mode information */
-	ret = vivid_fb_init_vidmode(dev);
-	if (ret) {
-		vivid_fb_release_buffers(dev);
-		return ret;
-	}
-
-	vivid_clear_fb(dev);
-
-	/* Register the framebuffer */
-	if (register_framebuffer(&dev->fb_info) < 0) {
-		vivid_fb_release_buffers(dev);
-		return -EINVAL;
-	}
-
-	/* Set the card to the requested mode */
-	vivid_fb_set_par(&dev->fb_info);
-	return 0;
-
-}
diff --git a/drivers/media/platform/vivid/vivid-osd.h b/drivers/media/platform/vivid/vivid-osd.h
deleted file mode 100644
index f9ac1af25dd3..000000000000
--- a/drivers/media/platform/vivid/vivid-osd.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * vivid-osd.h - output overlay support functions.
- *
- * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#ifndef _VIVID_OSD_H_
-#define _VIVID_OSD_H_
-
-int vivid_fb_init(struct vivid_dev *dev);
-void vivid_fb_release_buffers(struct vivid_dev *dev);
-void vivid_clear_fb(struct vivid_dev *dev);
-
-#endif
diff --git a/drivers/media/platform/vivid/vivid-radio-common.c b/drivers/media/platform/vivid/vivid-radio-common.c
deleted file mode 100644
index 138c7bce68b1..000000000000
--- a/drivers/media/platform/vivid/vivid-radio-common.c
+++ /dev/null
@@ -1,177 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * vivid-radio-common.c - common radio rx/tx support functions.
- *
- * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/videodev2.h>
-
-#include "vivid-core.h"
-#include "vivid-ctrls.h"
-#include "vivid-radio-common.h"
-#include "vivid-rds-gen.h"
-
-/*
- * These functions are shared between the vivid receiver and transmitter
- * since both use the same frequency bands.
- */
-
-const struct v4l2_frequency_band vivid_radio_bands[TOT_BANDS] = {
-	/* Band FM */
-	{
-		.type = V4L2_TUNER_RADIO,
-		.index = 0,
-		.capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
-			      V4L2_TUNER_CAP_FREQ_BANDS,
-		.rangelow   = FM_FREQ_RANGE_LOW,
-		.rangehigh  = FM_FREQ_RANGE_HIGH,
-		.modulation = V4L2_BAND_MODULATION_FM,
-	},
-	/* Band AM */
-	{
-		.type = V4L2_TUNER_RADIO,
-		.index = 1,
-		.capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_FREQ_BANDS,
-		.rangelow   = AM_FREQ_RANGE_LOW,
-		.rangehigh  = AM_FREQ_RANGE_HIGH,
-		.modulation = V4L2_BAND_MODULATION_AM,
-	},
-	/* Band SW */
-	{
-		.type = V4L2_TUNER_RADIO,
-		.index = 2,
-		.capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_FREQ_BANDS,
-		.rangelow   = SW_FREQ_RANGE_LOW,
-		.rangehigh  = SW_FREQ_RANGE_HIGH,
-		.modulation = V4L2_BAND_MODULATION_AM,
-	},
-};
-
-/*
- * Initialize the RDS generator. If we can loop, then the RDS generator
- * is set up with the values from the RDS TX controls, otherwise it
- * will fill in standard values using one of two alternates.
- */
-void vivid_radio_rds_init(struct vivid_dev *dev)
-{
-	struct vivid_rds_gen *rds = &dev->rds_gen;
-	bool alt = dev->radio_rx_rds_use_alternates;
-
-	/* Do nothing, blocks will be filled by the transmitter */
-	if (dev->radio_rds_loop && !dev->radio_tx_rds_controls)
-		return;
-
-	if (dev->radio_rds_loop) {
-		v4l2_ctrl_lock(dev->radio_tx_rds_pi);
-		rds->picode = dev->radio_tx_rds_pi->cur.val;
-		rds->pty = dev->radio_tx_rds_pty->cur.val;
-		rds->mono_stereo = dev->radio_tx_rds_mono_stereo->cur.val;
-		rds->art_head = dev->radio_tx_rds_art_head->cur.val;
-		rds->compressed = dev->radio_tx_rds_compressed->cur.val;
-		rds->dyn_pty = dev->radio_tx_rds_dyn_pty->cur.val;
-		rds->ta = dev->radio_tx_rds_ta->cur.val;
-		rds->tp = dev->radio_tx_rds_tp->cur.val;
-		rds->ms = dev->radio_tx_rds_ms->cur.val;
-		strscpy(rds->psname,
-			dev->radio_tx_rds_psname->p_cur.p_char,
-			sizeof(rds->psname));
-		strscpy(rds->radiotext,
-			dev->radio_tx_rds_radiotext->p_cur.p_char + alt * 64,
-			sizeof(rds->radiotext));
-		v4l2_ctrl_unlock(dev->radio_tx_rds_pi);
-	} else {
-		vivid_rds_gen_fill(rds, dev->radio_rx_freq, alt);
-	}
-	if (dev->radio_rx_rds_controls) {
-		v4l2_ctrl_s_ctrl(dev->radio_rx_rds_pty, rds->pty);
-		v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ta, rds->ta);
-		v4l2_ctrl_s_ctrl(dev->radio_rx_rds_tp, rds->tp);
-		v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ms, rds->ms);
-		v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_psname, rds->psname);
-		v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_radiotext, rds->radiotext);
-		if (!dev->radio_rds_loop)
-			dev->radio_rx_rds_use_alternates = !dev->radio_rx_rds_use_alternates;
-	}
-	vivid_rds_generate(rds);
-}
-
-/*
- * Calculate the emulated signal quality taking into account the frequency
- * the transmitter is using.
- */
-static void vivid_radio_calc_sig_qual(struct vivid_dev *dev)
-{
-	int mod = 16000;
-	int delta = 800;
-	int sig_qual, sig_qual_tx = mod;
-
-	/*
-	 * For SW and FM there is a channel every 1000 kHz, for AM there is one
-	 * every 100 kHz.
-	 */
-	if (dev->radio_rx_freq <= AM_FREQ_RANGE_HIGH) {
-		mod /= 10;
-		delta /= 10;
-	}
-	sig_qual = (dev->radio_rx_freq + delta) % mod - delta;
-	if (dev->has_radio_tx)
-		sig_qual_tx = dev->radio_rx_freq - dev->radio_tx_freq;
-	if (abs(sig_qual_tx) <= abs(sig_qual)) {
-		sig_qual = sig_qual_tx;
-		/*
-		 * Zero the internal rds buffer if we are going to loop
-		 * rds blocks.
-		 */
-		if (!dev->radio_rds_loop && !dev->radio_tx_rds_controls)
-			memset(dev->rds_gen.data, 0,
-			       sizeof(dev->rds_gen.data));
-		dev->radio_rds_loop = dev->radio_rx_freq >= FM_FREQ_RANGE_LOW;
-	} else {
-		dev->radio_rds_loop = false;
-	}
-	if (dev->radio_rx_freq <= AM_FREQ_RANGE_HIGH)
-		sig_qual *= 10;
-	dev->radio_rx_sig_qual = sig_qual;
-}
-
-int vivid_radio_g_frequency(struct file *file, const unsigned *pfreq, struct v4l2_frequency *vf)
-{
-	if (vf->tuner != 0)
-		return -EINVAL;
-	vf->frequency = *pfreq;
-	return 0;
-}
-
-int vivid_radio_s_frequency(struct file *file, unsigned *pfreq, const struct v4l2_frequency *vf)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	unsigned freq;
-	unsigned band;
-
-	if (vf->tuner != 0)
-		return -EINVAL;
-
-	if (vf->frequency >= (FM_FREQ_RANGE_LOW + SW_FREQ_RANGE_HIGH) / 2)
-		band = BAND_FM;
-	else if (vf->frequency <= (AM_FREQ_RANGE_HIGH + SW_FREQ_RANGE_LOW) / 2)
-		band = BAND_AM;
-	else
-		band = BAND_SW;
-
-	freq = clamp_t(u32, vf->frequency, vivid_radio_bands[band].rangelow,
-					   vivid_radio_bands[band].rangehigh);
-	*pfreq = freq;
-
-	/*
-	 * For both receiver and transmitter recalculate the signal quality
-	 * (since that depends on both frequencies) and re-init the rds
-	 * generator.
-	 */
-	vivid_radio_calc_sig_qual(dev);
-	vivid_radio_rds_init(dev);
-	return 0;
-}
diff --git a/drivers/media/platform/vivid/vivid-radio-common.h b/drivers/media/platform/vivid/vivid-radio-common.h
deleted file mode 100644
index 30a9900e5b2b..000000000000
--- a/drivers/media/platform/vivid/vivid-radio-common.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * vivid-radio-common.h - common radio rx/tx support functions.
- *
- * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#ifndef _VIVID_RADIO_COMMON_H_
-#define _VIVID_RADIO_COMMON_H_
-
-/* The supported radio frequency ranges in kHz */
-#define FM_FREQ_RANGE_LOW       (64000U * 16U)
-#define FM_FREQ_RANGE_HIGH      (108000U * 16U)
-#define AM_FREQ_RANGE_LOW       (520U * 16U)
-#define AM_FREQ_RANGE_HIGH      (1710U * 16U)
-#define SW_FREQ_RANGE_LOW       (2300U * 16U)
-#define SW_FREQ_RANGE_HIGH      (26100U * 16U)
-
-enum { BAND_FM, BAND_AM, BAND_SW, TOT_BANDS };
-
-extern const struct v4l2_frequency_band vivid_radio_bands[TOT_BANDS];
-
-int vivid_radio_g_frequency(struct file *file, const unsigned *freq, struct v4l2_frequency *vf);
-int vivid_radio_s_frequency(struct file *file, unsigned *freq, const struct v4l2_frequency *vf);
-
-void vivid_radio_rds_init(struct vivid_dev *dev);
-
-#endif
diff --git a/drivers/media/platform/vivid/vivid-radio-rx.c b/drivers/media/platform/vivid/vivid-radio-rx.c
deleted file mode 100644
index 232cab508f48..000000000000
--- a/drivers/media/platform/vivid/vivid-radio-rx.c
+++ /dev/null
@@ -1,278 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * vivid-radio-rx.c - radio receiver support functions.
- *
- * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/videodev2.h>
-#include <linux/v4l2-dv-timings.h>
-#include <linux/sched/signal.h>
-
-#include <media/v4l2-common.h>
-#include <media/v4l2-event.h>
-#include <media/v4l2-dv-timings.h>
-
-#include "vivid-core.h"
-#include "vivid-ctrls.h"
-#include "vivid-radio-common.h"
-#include "vivid-rds-gen.h"
-#include "vivid-radio-rx.h"
-
-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 v4l2_rds_data *data = dev->rds_gen.data;
-	bool use_alternates;
-	ktime_t timestamp;
-	unsigned blk;
-	int perc;
-	int i;
-
-	if (dev->radio_rx_rds_controls)
-		return -EINVAL;
-	if (size < sizeof(*data))
-		return 0;
-	size = sizeof(*data) * (size / sizeof(*data));
-
-	if (mutex_lock_interruptible(&dev->mutex))
-		return -ERESTARTSYS;
-	if (dev->radio_rx_rds_owner &&
-	    file->private_data != dev->radio_rx_rds_owner) {
-		mutex_unlock(&dev->mutex);
-		return -EBUSY;
-	}
-	if (dev->radio_rx_rds_owner == NULL) {
-		vivid_radio_rds_init(dev);
-		dev->radio_rx_rds_owner = file->private_data;
-	}
-
-retry:
-	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);
-	}
-	if (blk >= dev->radio_rx_rds_last_block + VIVID_RDS_GEN_BLOCKS)
-		dev->radio_rx_rds_last_block = blk - VIVID_RDS_GEN_BLOCKS + 1;
-
-	/*
-	 * No data is available if there hasn't been time to get new data,
-	 * or if the RDS receiver has been disabled, or if we use the data
-	 * from the RDS transmitter and that RDS transmitter has been disabled,
-	 * or if the signal quality is too weak.
-	 */
-	if (blk == dev->radio_rx_rds_last_block || !dev->radio_rx_rds_enabled ||
-	    (dev->radio_rds_loop && !(dev->radio_tx_subchans & V4L2_TUNER_SUB_RDS)) ||
-	    abs(dev->radio_rx_sig_qual) > 200) {
-		mutex_unlock(&dev->mutex);
-		if (file->f_flags & O_NONBLOCK)
-			return -EWOULDBLOCK;
-		if (msleep_interruptible(20) && signal_pending(current))
-			return -EINTR;
-		if (mutex_lock_interruptible(&dev->mutex))
-			return -ERESTARTSYS;
-		goto retry;
-	}
-
-	/* abs(dev->radio_rx_sig_qual) <= 200, map that to a 0-50% range */
-	perc = abs(dev->radio_rx_sig_qual) / 4;
-
-	for (i = 0; i < size && blk > dev->radio_rx_rds_last_block;
-			dev->radio_rx_rds_last_block++) {
-		unsigned data_blk = dev->radio_rx_rds_last_block % VIVID_RDS_GEN_BLOCKS;
-		struct v4l2_rds_data rds = data[data_blk];
-
-		if (data_blk == 0 && dev->radio_rds_loop)
-			vivid_radio_rds_init(dev);
-		if (perc && prandom_u32_max(100) < perc) {
-			switch (prandom_u32_max(4)) {
-			case 0:
-				rds.block |= V4L2_RDS_BLOCK_CORRECTED;
-				break;
-			case 1:
-				rds.block |= V4L2_RDS_BLOCK_INVALID;
-				break;
-			case 2:
-				rds.block |= V4L2_RDS_BLOCK_ERROR;
-				rds.lsb = prandom_u32_max(256);
-				rds.msb = prandom_u32_max(256);
-				break;
-			case 3: /* Skip block altogether */
-				if (i)
-					continue;
-				/*
-				 * Must make sure at least one block is
-				 * returned, otherwise the application
-				 * might think that end-of-file occurred.
-				 */
-				break;
-			}
-		}
-		if (copy_to_user(buf + i, &rds, sizeof(rds))) {
-			i = -EFAULT;
-			break;
-		}
-		i += sizeof(rds);
-	}
-	mutex_unlock(&dev->mutex);
-	return i;
-}
-
-__poll_t vivid_radio_rx_poll(struct file *file, struct poll_table_struct *wait)
-{
-	return EPOLLIN | EPOLLRDNORM | v4l2_ctrl_poll(file, wait);
-}
-
-int vivid_radio_rx_enum_freq_bands(struct file *file, void *fh, struct v4l2_frequency_band *band)
-{
-	if (band->tuner != 0)
-		return -EINVAL;
-
-	if (band->index >= TOT_BANDS)
-		return -EINVAL;
-
-	*band = vivid_radio_bands[band->index];
-	return 0;
-}
-
-int vivid_radio_rx_s_hw_freq_seek(struct file *file, void *fh, const struct v4l2_hw_freq_seek *a)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	unsigned low, high;
-	unsigned freq;
-	unsigned spacing;
-	unsigned band;
-
-	if (a->tuner)
-		return -EINVAL;
-	if (a->wrap_around && dev->radio_rx_hw_seek_mode == VIVID_HW_SEEK_BOUNDED)
-		return -EINVAL;
-
-	if (!a->wrap_around && dev->radio_rx_hw_seek_mode == VIVID_HW_SEEK_WRAP)
-		return -EINVAL;
-	if (!a->rangelow ^ !a->rangehigh)
-		return -EINVAL;
-
-	if (file->f_flags & O_NONBLOCK)
-		return -EWOULDBLOCK;
-
-	if (a->rangelow) {
-		for (band = 0; band < TOT_BANDS; band++)
-			if (a->rangelow >= vivid_radio_bands[band].rangelow &&
-			    a->rangehigh <= vivid_radio_bands[band].rangehigh)
-				break;
-		if (band == TOT_BANDS)
-			return -EINVAL;
-		if (!dev->radio_rx_hw_seek_prog_lim &&
-		    (a->rangelow != vivid_radio_bands[band].rangelow ||
-		     a->rangehigh != vivid_radio_bands[band].rangehigh))
-			return -EINVAL;
-		low = a->rangelow;
-		high = a->rangehigh;
-	} else {
-		for (band = 0; band < TOT_BANDS; band++)
-			if (dev->radio_rx_freq >= vivid_radio_bands[band].rangelow &&
-			    dev->radio_rx_freq <= vivid_radio_bands[band].rangehigh)
-				break;
-		if (band == TOT_BANDS)
-			return -EINVAL;
-		low = vivid_radio_bands[band].rangelow;
-		high = vivid_radio_bands[band].rangehigh;
-	}
-	spacing = band == BAND_AM ? 1600 : 16000;
-	freq = clamp(dev->radio_rx_freq, low, high);
-
-	if (a->seek_upward) {
-		freq = spacing * (freq / spacing) + spacing;
-		if (freq > high) {
-			if (!a->wrap_around)
-				return -ENODATA;
-			freq = spacing * (low / spacing) + spacing;
-			if (freq >= dev->radio_rx_freq)
-				return -ENODATA;
-		}
-	} else {
-		freq = spacing * ((freq + spacing - 1) / spacing) - spacing;
-		if (freq < low) {
-			if (!a->wrap_around)
-				return -ENODATA;
-			freq = spacing * ((high + spacing - 1) / spacing) - spacing;
-			if (freq <= dev->radio_rx_freq)
-				return -ENODATA;
-		}
-	}
-	return 0;
-}
-
-int vivid_radio_rx_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	int delta = 800;
-	int sig_qual;
-
-	if (vt->index > 0)
-		return -EINVAL;
-
-	strscpy(vt->name, "AM/FM/SW Receiver", sizeof(vt->name));
-	vt->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
-			 V4L2_TUNER_CAP_FREQ_BANDS | V4L2_TUNER_CAP_RDS |
-			 (dev->radio_rx_rds_controls ?
-				V4L2_TUNER_CAP_RDS_CONTROLS :
-				V4L2_TUNER_CAP_RDS_BLOCK_IO) |
-			 (dev->radio_rx_hw_seek_prog_lim ?
-				V4L2_TUNER_CAP_HWSEEK_PROG_LIM : 0);
-	switch (dev->radio_rx_hw_seek_mode) {
-	case VIVID_HW_SEEK_BOUNDED:
-		vt->capability |= V4L2_TUNER_CAP_HWSEEK_BOUNDED;
-		break;
-	case VIVID_HW_SEEK_WRAP:
-		vt->capability |= V4L2_TUNER_CAP_HWSEEK_WRAP;
-		break;
-	case VIVID_HW_SEEK_BOTH:
-		vt->capability |= V4L2_TUNER_CAP_HWSEEK_WRAP |
-				  V4L2_TUNER_CAP_HWSEEK_BOUNDED;
-		break;
-	}
-	vt->rangelow = AM_FREQ_RANGE_LOW;
-	vt->rangehigh = FM_FREQ_RANGE_HIGH;
-	sig_qual = dev->radio_rx_sig_qual;
-	vt->signal = abs(sig_qual) > delta ? 0 :
-		     0xffff - ((unsigned)abs(sig_qual) * 0xffff) / delta;
-	vt->afc = sig_qual > delta ? 0 : sig_qual;
-	if (abs(sig_qual) > delta)
-		vt->rxsubchans = 0;
-	else if (dev->radio_rx_freq < FM_FREQ_RANGE_LOW || vt->signal < 0x8000)
-		vt->rxsubchans = V4L2_TUNER_SUB_MONO;
-	else if (dev->radio_rds_loop && !(dev->radio_tx_subchans & V4L2_TUNER_SUB_STEREO))
-		vt->rxsubchans = V4L2_TUNER_SUB_MONO;
-	else
-		vt->rxsubchans = V4L2_TUNER_SUB_STEREO;
-	if (dev->radio_rx_rds_enabled &&
-	    (!dev->radio_rds_loop || (dev->radio_tx_subchans & V4L2_TUNER_SUB_RDS)) &&
-	    dev->radio_rx_freq >= FM_FREQ_RANGE_LOW && vt->signal >= 0xc000)
-		vt->rxsubchans |= V4L2_TUNER_SUB_RDS;
-	if (dev->radio_rx_rds_controls)
-		vivid_radio_rds_init(dev);
-	vt->audmode = dev->radio_rx_audmode;
-	return 0;
-}
-
-int vivid_radio_rx_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (vt->index)
-		return -EINVAL;
-	dev->radio_rx_audmode = vt->audmode >= V4L2_TUNER_MODE_STEREO;
-	return 0;
-}
diff --git a/drivers/media/platform/vivid/vivid-radio-rx.h b/drivers/media/platform/vivid/vivid-radio-rx.h
deleted file mode 100644
index c9c7849f6f99..000000000000
--- a/drivers/media/platform/vivid/vivid-radio-rx.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * vivid-radio-rx.h - radio receiver support functions.
- *
- * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#ifndef _VIVID_RADIO_RX_H_
-#define _VIVID_RADIO_RX_H_
-
-ssize_t vivid_radio_rx_read(struct file *, char __user *, size_t, loff_t *);
-__poll_t vivid_radio_rx_poll(struct file *file, struct poll_table_struct *wait);
-
-int vivid_radio_rx_enum_freq_bands(struct file *file, void *fh, struct v4l2_frequency_band *band);
-int vivid_radio_rx_s_hw_freq_seek(struct file *file, void *fh, const struct v4l2_hw_freq_seek *a);
-int vivid_radio_rx_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt);
-int vivid_radio_rx_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt);
-
-#endif
diff --git a/drivers/media/platform/vivid/vivid-radio-tx.c b/drivers/media/platform/vivid/vivid-radio-tx.c
deleted file mode 100644
index 049d40b948bb..000000000000
--- a/drivers/media/platform/vivid/vivid-radio-tx.c
+++ /dev/null
@@ -1,128 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * vivid-radio-tx.c - radio transmitter support functions.
- *
- * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/sched/signal.h>
-#include <linux/delay.h>
-#include <linux/videodev2.h>
-#include <linux/v4l2-dv-timings.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-event.h>
-#include <media/v4l2-dv-timings.h>
-
-#include "vivid-core.h"
-#include "vivid-ctrls.h"
-#include "vivid-radio-common.h"
-#include "vivid-radio-tx.h"
-
-ssize_t vivid_radio_tx_write(struct file *file, const char __user *buf,
-			  size_t size, loff_t *offset)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	struct v4l2_rds_data *data = dev->rds_gen.data;
-	ktime_t timestamp;
-	unsigned blk;
-	int i;
-
-	if (dev->radio_tx_rds_controls)
-		return -EINVAL;
-
-	if (size < sizeof(*data))
-		return -EINVAL;
-	size = sizeof(*data) * (size / sizeof(*data));
-
-	if (mutex_lock_interruptible(&dev->mutex))
-		return -ERESTARTSYS;
-	if (dev->radio_tx_rds_owner &&
-	    file->private_data != dev->radio_tx_rds_owner) {
-		mutex_unlock(&dev->mutex);
-		return -EBUSY;
-	}
-	dev->radio_tx_rds_owner = file->private_data;
-
-retry:
-	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;
-
-	/*
-	 * No data is available if there hasn't been time to get new data,
-	 * or if the RDS receiver has been disabled, or if we use the data
-	 * from the RDS transmitter and that RDS transmitter has been disabled,
-	 * or if the signal quality is too weak.
-	 */
-	if (blk == dev->radio_tx_rds_last_block ||
-	    !(dev->radio_tx_subchans & V4L2_TUNER_SUB_RDS)) {
-		mutex_unlock(&dev->mutex);
-		if (file->f_flags & O_NONBLOCK)
-			return -EWOULDBLOCK;
-		if (msleep_interruptible(20) && signal_pending(current))
-			return -EINTR;
-		if (mutex_lock_interruptible(&dev->mutex))
-			return -ERESTARTSYS;
-		goto retry;
-	}
-
-	for (i = 0; i < size && blk > dev->radio_tx_rds_last_block;
-			dev->radio_tx_rds_last_block++) {
-		unsigned data_blk = dev->radio_tx_rds_last_block % VIVID_RDS_GEN_BLOCKS;
-		struct v4l2_rds_data rds;
-
-		if (copy_from_user(&rds, buf + i, sizeof(rds))) {
-			i = -EFAULT;
-			break;
-		}
-		i += sizeof(rds);
-		if (!dev->radio_rds_loop)
-			continue;
-		if ((rds.block & V4L2_RDS_BLOCK_MSK) == V4L2_RDS_BLOCK_INVALID ||
-		    (rds.block & V4L2_RDS_BLOCK_ERROR))
-			continue;
-		rds.block &= V4L2_RDS_BLOCK_MSK;
-		data[data_blk] = rds;
-	}
-	mutex_unlock(&dev->mutex);
-	return i;
-}
-
-__poll_t vivid_radio_tx_poll(struct file *file, struct poll_table_struct *wait)
-{
-	return EPOLLOUT | EPOLLWRNORM | v4l2_ctrl_poll(file, wait);
-}
-
-int vidioc_g_modulator(struct file *file, void *fh, struct v4l2_modulator *a)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (a->index > 0)
-		return -EINVAL;
-
-	strscpy(a->name, "AM/FM/SW Transmitter", sizeof(a->name));
-	a->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
-			V4L2_TUNER_CAP_FREQ_BANDS | V4L2_TUNER_CAP_RDS |
-			(dev->radio_tx_rds_controls ?
-				V4L2_TUNER_CAP_RDS_CONTROLS :
-				V4L2_TUNER_CAP_RDS_BLOCK_IO);
-	a->rangelow = AM_FREQ_RANGE_LOW;
-	a->rangehigh = FM_FREQ_RANGE_HIGH;
-	a->txsubchans = dev->radio_tx_subchans;
-	return 0;
-}
-
-int vidioc_s_modulator(struct file *file, void *fh, const struct v4l2_modulator *a)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (a->index)
-		return -EINVAL;
-	if (a->txsubchans & ~0x13)
-		return -EINVAL;
-	dev->radio_tx_subchans = a->txsubchans;
-	return 0;
-}
diff --git a/drivers/media/platform/vivid/vivid-radio-tx.h b/drivers/media/platform/vivid/vivid-radio-tx.h
deleted file mode 100644
index c2bf1e7e634a..000000000000
--- a/drivers/media/platform/vivid/vivid-radio-tx.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * vivid-radio-tx.h - radio transmitter support functions.
- *
- * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#ifndef _VIVID_RADIO_TX_H_
-#define _VIVID_RADIO_TX_H_
-
-ssize_t vivid_radio_tx_write(struct file *, const char __user *, size_t, loff_t *);
-__poll_t vivid_radio_tx_poll(struct file *file, struct poll_table_struct *wait);
-
-int vidioc_g_modulator(struct file *file, void *fh, struct v4l2_modulator *a);
-int vidioc_s_modulator(struct file *file, void *fh, const struct v4l2_modulator *a);
-
-#endif
diff --git a/drivers/media/platform/vivid/vivid-rds-gen.c b/drivers/media/platform/vivid/vivid-rds-gen.c
deleted file mode 100644
index b5b104ee64c9..000000000000
--- a/drivers/media/platform/vivid/vivid-rds-gen.c
+++ /dev/null
@@ -1,157 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * vivid-rds-gen.c - rds (radio data system) generator support functions.
- *
- * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#include <linux/kernel.h>
-#include <linux/ktime.h>
-#include <linux/string.h>
-#include <linux/videodev2.h>
-
-#include "vivid-rds-gen.h"
-
-static u8 vivid_get_di(const struct vivid_rds_gen *rds, unsigned grp)
-{
-	switch (grp) {
-	case 0:
-		return (rds->dyn_pty << 2) | (grp & 3);
-	case 1:
-		return (rds->compressed << 2) | (grp & 3);
-	case 2:
-		return (rds->art_head << 2) | (grp & 3);
-	case 3:
-		return (rds->mono_stereo << 2) | (grp & 3);
-	}
-	return 0;
-}
-
-/*
- * This RDS generator creates 57 RDS groups (one group == four RDS blocks).
- * Groups 0-3, 22-25 and 44-47 (spaced 22 groups apart) are filled with a
- * standard 0B group containing the PI code and PS name.
- *
- * Groups 4-19 and 26-41 use group 2A for the radio text.
- *
- * Group 56 contains the time (group 4A).
- *
- * All remaining groups use a filler group 15B block that just repeats
- * the PI and PTY codes.
- */
-void vivid_rds_generate(struct vivid_rds_gen *rds)
-{
-	struct v4l2_rds_data *data = rds->data;
-	unsigned grp;
-	unsigned idx;
-	struct tm tm;
-	unsigned date;
-	unsigned time;
-	int l;
-
-	for (grp = 0; grp < VIVID_RDS_GEN_GROUPS; grp++, data += VIVID_RDS_GEN_BLKS_PER_GRP) {
-		data[0].lsb = rds->picode & 0xff;
-		data[0].msb = rds->picode >> 8;
-		data[0].block = V4L2_RDS_BLOCK_A | (V4L2_RDS_BLOCK_A << 3);
-		data[1].lsb = rds->pty << 5;
-		data[1].msb = (rds->pty >> 3) | (rds->tp << 2);
-		data[1].block = V4L2_RDS_BLOCK_B | (V4L2_RDS_BLOCK_B << 3);
-		data[3].block = V4L2_RDS_BLOCK_D | (V4L2_RDS_BLOCK_D << 3);
-
-		switch (grp) {
-		case 0 ... 3:
-		case 22 ... 25:
-		case 44 ... 47: /* Group 0B */
-			idx = (grp % 22) % 4;
-			data[1].lsb |= (rds->ta << 4) | (rds->ms << 3);
-			data[1].lsb |= vivid_get_di(rds, idx);
-			data[1].msb |= 1 << 3;
-			data[2].lsb = rds->picode & 0xff;
-			data[2].msb = rds->picode >> 8;
-			data[2].block = V4L2_RDS_BLOCK_C_ALT | (V4L2_RDS_BLOCK_C_ALT << 3);
-			data[3].lsb = rds->psname[2 * idx + 1];
-			data[3].msb = rds->psname[2 * idx];
-			break;
-		case 4 ... 19:
-		case 26 ... 41: /* Group 2A */
-			idx = ((grp - 4) % 22) % 16;
-			data[1].lsb |= idx;
-			data[1].msb |= 4 << 3;
-			data[2].msb = rds->radiotext[4 * idx];
-			data[2].lsb = rds->radiotext[4 * idx + 1];
-			data[2].block = V4L2_RDS_BLOCK_C | (V4L2_RDS_BLOCK_C << 3);
-			data[3].msb = rds->radiotext[4 * idx + 2];
-			data[3].lsb = rds->radiotext[4 * idx + 3];
-			break;
-		case 56:
-			/*
-			 * Group 4A
-			 *
-			 * Uses the algorithm from Annex G of the RDS standard
-			 * EN 50067:1998 to convert a UTC date to an RDS Modified
-			 * Julian Day.
-			 */
-			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;
-			time = (tm.tm_hour << 12) |
-			       (tm.tm_min << 6) |
-			       (sys_tz.tz_minuteswest >= 0 ? 0x20 : 0) |
-			       (abs(sys_tz.tz_minuteswest) / 30);
-			data[1].lsb &= ~3;
-			data[1].lsb |= date >> 15;
-			data[1].msb |= 8 << 3;
-			data[2].lsb = (date << 1) & 0xfe;
-			data[2].lsb |= (time >> 16) & 1;
-			data[2].msb = (date >> 7) & 0xff;
-			data[2].block = V4L2_RDS_BLOCK_C | (V4L2_RDS_BLOCK_C << 3);
-			data[3].lsb = time & 0xff;
-			data[3].msb = (time >> 8) & 0xff;
-			break;
-		default: /* Group 15B */
-			data[1].lsb |= (rds->ta << 4) | (rds->ms << 3);
-			data[1].lsb |= vivid_get_di(rds, grp % 22);
-			data[1].msb |= 0x1f << 3;
-			data[2].lsb = rds->picode & 0xff;
-			data[2].msb = rds->picode >> 8;
-			data[2].block = V4L2_RDS_BLOCK_C_ALT | (V4L2_RDS_BLOCK_C_ALT << 3);
-			data[3].lsb = rds->pty << 5;
-			data[3].lsb |= (rds->ta << 4) | (rds->ms << 3);
-			data[3].lsb |= vivid_get_di(rds, grp % 22);
-			data[3].msb |= rds->pty >> 3;
-			data[3].msb |= 0x1f << 3;
-			break;
-		}
-	}
-}
-
-void vivid_rds_gen_fill(struct vivid_rds_gen *rds, unsigned freq,
-			  bool alt)
-{
-	/* Alternate PTY between Info and Weather */
-	if (rds->use_rbds) {
-		rds->picode = 0x2e75; /* 'KLNX' call sign */
-		rds->pty = alt ? 29 : 2;
-	} else {
-		rds->picode = 0x8088;
-		rds->pty = alt ? 16 : 3;
-	}
-	rds->mono_stereo = true;
-	rds->art_head = false;
-	rds->compressed = false;
-	rds->dyn_pty = false;
-	rds->tp = true;
-	rds->ta = alt;
-	rds->ms = true;
-	snprintf(rds->psname, sizeof(rds->psname), "%6d.%1d",
-		 freq / 16, ((freq & 0xf) * 10) / 16);
-	if (alt)
-		strscpy(rds->radiotext,
-			" The Radio Data System can switch between different Radio Texts ",
-			sizeof(rds->radiotext));
-	else
-		strscpy(rds->radiotext,
-			"An example of Radio Text as transmitted by the Radio Data System",
-			sizeof(rds->radiotext));
-}
diff --git a/drivers/media/platform/vivid/vivid-rds-gen.h b/drivers/media/platform/vivid/vivid-rds-gen.h
deleted file mode 100644
index 35ac5742302b..000000000000
--- a/drivers/media/platform/vivid/vivid-rds-gen.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * vivid-rds-gen.h - rds (radio data system) generator support functions.
- *
- * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#ifndef _VIVID_RDS_GEN_H_
-#define _VIVID_RDS_GEN_H_
-
-/*
- * It takes almost exactly 5 seconds to transmit 57 RDS groups.
- * Each group has 4 blocks and each block has a payload of 16 bits + a
- * block identification. The driver will generate the contents of these
- * 57 groups only when necessary and it will just be played continuously.
- */
-#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];
-	bool			use_rbds;
-	u16			picode;
-	u8			pty;
-	bool			mono_stereo;
-	bool			art_head;
-	bool			compressed;
-	bool			dyn_pty;
-	bool			ta;
-	bool			tp;
-	bool			ms;
-	char			psname[8 + 1];
-	char			radiotext[64 + 1];
-};
-
-void vivid_rds_gen_fill(struct vivid_rds_gen *rds, unsigned freq,
-		    bool use_alternate);
-void vivid_rds_generate(struct vivid_rds_gen *rds);
-
-#endif
diff --git a/drivers/media/platform/vivid/vivid-sdr-cap.c b/drivers/media/platform/vivid/vivid-sdr-cap.c
deleted file mode 100644
index 2b7522e16efc..000000000000
--- a/drivers/media/platform/vivid/vivid-sdr-cap.c
+++ /dev/null
@@ -1,570 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * vivid-sdr-cap.c - software defined radio support functions.
- *
- * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/kthread.h>
-#include <linux/freezer.h>
-#include <linux/math64.h>
-#include <linux/videodev2.h>
-#include <linux/v4l2-dv-timings.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-event.h>
-#include <media/v4l2-dv-timings.h>
-#include <linux/fixp-arith.h>
-
-#include "vivid-core.h"
-#include "vivid-ctrls.h"
-#include "vivid-sdr-cap.h"
-
-/* stream formats */
-struct vivid_format {
-	u32	pixelformat;
-	u32	buffersize;
-};
-
-/* format descriptions for capture and preview */
-static const struct vivid_format formats[] = {
-	{
-		.pixelformat	= V4L2_SDR_FMT_CU8,
-		.buffersize	= SDR_CAP_SAMPLES_PER_BUF * 2,
-	}, {
-		.pixelformat	= V4L2_SDR_FMT_CS8,
-		.buffersize	= SDR_CAP_SAMPLES_PER_BUF * 2,
-	},
-};
-
-static const struct v4l2_frequency_band bands_adc[] = {
-	{
-		.tuner = 0,
-		.type = V4L2_TUNER_ADC,
-		.index = 0,
-		.capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
-		.rangelow   =  300000,
-		.rangehigh  =  300000,
-	},
-	{
-		.tuner = 0,
-		.type = V4L2_TUNER_ADC,
-		.index = 1,
-		.capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
-		.rangelow   =  900001,
-		.rangehigh  = 2800000,
-	},
-	{
-		.tuner = 0,
-		.type = V4L2_TUNER_ADC,
-		.index = 2,
-		.capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
-		.rangelow   = 3200000,
-		.rangehigh  = 3200000,
-	},
-};
-
-/* ADC band midpoints */
-#define BAND_ADC_0 ((bands_adc[0].rangehigh + bands_adc[1].rangelow) / 2)
-#define BAND_ADC_1 ((bands_adc[1].rangehigh + bands_adc[2].rangelow) / 2)
-
-static const struct v4l2_frequency_band bands_fm[] = {
-	{
-		.tuner = 1,
-		.type = V4L2_TUNER_RF,
-		.index = 0,
-		.capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
-		.rangelow   =    50000000,
-		.rangehigh  =  2000000000,
-	},
-};
-
-static void vivid_thread_sdr_cap_tick(struct vivid_dev *dev)
-{
-	struct vivid_buffer *sdr_cap_buf = NULL;
-
-	dprintk(dev, 1, "SDR Capture Thread Tick\n");
-
-	/* Drop a certain percentage of buffers. */
-	if (dev->perc_dropped_buffers &&
-	    prandom_u32_max(100) < dev->perc_dropped_buffers)
-		return;
-
-	spin_lock(&dev->slock);
-	if (!list_empty(&dev->sdr_cap_active)) {
-		sdr_cap_buf = list_entry(dev->sdr_cap_active.next,
-					 struct vivid_buffer, list);
-		list_del(&sdr_cap_buf->list);
-	}
-	spin_unlock(&dev->slock);
-
-	if (sdr_cap_buf) {
-		sdr_cap_buf->vb.sequence = dev->sdr_cap_seq_count;
-		v4l2_ctrl_request_setup(sdr_cap_buf->vb.vb2_buf.req_obj.req,
-					&dev->ctrl_hdl_sdr_cap);
-		v4l2_ctrl_request_complete(sdr_cap_buf->vb.vb2_buf.req_obj.req,
-					   &dev->ctrl_hdl_sdr_cap);
-		vivid_sdr_cap_process(dev, sdr_cap_buf);
-		sdr_cap_buf->vb.vb2_buf.timestamp =
-			ktime_get_ns() + dev->time_wrap_offset;
-		vb2_buffer_done(&sdr_cap_buf->vb.vb2_buf, dev->dqbuf_error ?
-				VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
-		dev->dqbuf_error = false;
-	}
-}
-
-static int vivid_thread_sdr_cap(void *data)
-{
-	struct vivid_dev *dev = data;
-	u64 samples_since_start;
-	u64 buffers_since_start;
-	u64 next_jiffies_since_start;
-	unsigned long jiffies_since_start;
-	unsigned long cur_jiffies;
-	unsigned wait_jiffies;
-
-	dprintk(dev, 1, "SDR Capture Thread Start\n");
-
-	set_freezable();
-
-	/* Resets frame counters */
-	dev->sdr_cap_seq_offset = 0;
-	if (dev->seq_wrap)
-		dev->sdr_cap_seq_offset = 0xffffff80U;
-	dev->jiffies_sdr_cap = jiffies;
-	dev->sdr_cap_seq_resync = false;
-
-	for (;;) {
-		try_to_freeze();
-		if (kthread_should_stop())
-			break;
-
-		if (!mutex_trylock(&dev->mutex)) {
-			schedule_timeout_uninterruptible(1);
-			continue;
-		}
-
-		cur_jiffies = jiffies;
-		if (dev->sdr_cap_seq_resync) {
-			dev->jiffies_sdr_cap = cur_jiffies;
-			dev->sdr_cap_seq_offset = dev->sdr_cap_seq_count + 1;
-			dev->sdr_cap_seq_count = 0;
-			dev->sdr_cap_seq_resync = false;
-		}
-		/* Calculate the number of jiffies since we started streaming */
-		jiffies_since_start = cur_jiffies - dev->jiffies_sdr_cap;
-		/* Get the number of buffers streamed since the start */
-		buffers_since_start =
-			(u64)jiffies_since_start * dev->sdr_adc_freq +
-				      (HZ * SDR_CAP_SAMPLES_PER_BUF) / 2;
-		do_div(buffers_since_start, HZ * SDR_CAP_SAMPLES_PER_BUF);
-
-		/*
-		 * After more than 0xf0000000 (rounded down to a multiple of
-		 * 'jiffies-per-day' to ease jiffies_to_msecs calculation)
-		 * jiffies have passed since we started streaming reset the
-		 * counters and keep track of the sequence offset.
-		 */
-		if (jiffies_since_start > JIFFIES_RESYNC) {
-			dev->jiffies_sdr_cap = cur_jiffies;
-			dev->sdr_cap_seq_offset = buffers_since_start;
-			buffers_since_start = 0;
-		}
-		dev->sdr_cap_seq_count =
-			buffers_since_start + dev->sdr_cap_seq_offset;
-
-		vivid_thread_sdr_cap_tick(dev);
-		mutex_unlock(&dev->mutex);
-
-		/*
-		 * Calculate the number of samples streamed since we started,
-		 * not including the current buffer.
-		 */
-		samples_since_start = buffers_since_start * SDR_CAP_SAMPLES_PER_BUF;
-
-		/* And the number of jiffies since we started */
-		jiffies_since_start = jiffies - dev->jiffies_sdr_cap;
-
-		/* Increase by the number of samples in one buffer */
-		samples_since_start += SDR_CAP_SAMPLES_PER_BUF;
-		/*
-		 * Calculate when that next buffer is supposed to start
-		 * in jiffies since we started streaming.
-		 */
-		next_jiffies_since_start = samples_since_start * HZ +
-					   dev->sdr_adc_freq / 2;
-		do_div(next_jiffies_since_start, dev->sdr_adc_freq);
-		/* If it is in the past, then just schedule asap */
-		if (next_jiffies_since_start < jiffies_since_start)
-			next_jiffies_since_start = jiffies_since_start;
-
-		wait_jiffies = next_jiffies_since_start - jiffies_since_start;
-		schedule_timeout_interruptible(wait_jiffies ? wait_jiffies : 1);
-	}
-	dprintk(dev, 1, "SDR Capture Thread End\n");
-	return 0;
-}
-
-static int sdr_cap_queue_setup(struct vb2_queue *vq,
-		       unsigned *nbuffers, unsigned *nplanes,
-		       unsigned sizes[], struct device *alloc_devs[])
-{
-	/* 2 = max 16-bit sample returned */
-	sizes[0] = SDR_CAP_SAMPLES_PER_BUF * 2;
-	*nplanes = 1;
-	return 0;
-}
-
-static int sdr_cap_buf_prepare(struct vb2_buffer *vb)
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
-	unsigned size = SDR_CAP_SAMPLES_PER_BUF * 2;
-
-	dprintk(dev, 1, "%s\n", __func__);
-
-	if (dev->buf_prepare_error) {
-		/*
-		 * Error injection: test what happens if buf_prepare() returns
-		 * an error.
-		 */
-		dev->buf_prepare_error = false;
-		return -EINVAL;
-	}
-	if (vb2_plane_size(vb, 0) < size) {
-		dprintk(dev, 1, "%s data will not fit into plane (%lu < %u)\n",
-				__func__, vb2_plane_size(vb, 0), size);
-		return -EINVAL;
-	}
-	vb2_set_plane_payload(vb, 0, size);
-
-	return 0;
-}
-
-static void sdr_cap_buf_queue(struct vb2_buffer *vb)
-{
-	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
-	struct vivid_buffer *buf = container_of(vbuf, struct vivid_buffer, vb);
-
-	dprintk(dev, 1, "%s\n", __func__);
-
-	spin_lock(&dev->slock);
-	list_add_tail(&buf->list, &dev->sdr_cap_active);
-	spin_unlock(&dev->slock);
-}
-
-static int sdr_cap_start_streaming(struct vb2_queue *vq, unsigned count)
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vq);
-	int err = 0;
-
-	dprintk(dev, 1, "%s\n", __func__);
-	dev->sdr_cap_seq_count = 0;
-	if (dev->start_streaming_error) {
-		dev->start_streaming_error = false;
-		err = -EINVAL;
-	} else if (dev->kthread_sdr_cap == NULL) {
-		dev->kthread_sdr_cap = kthread_run(vivid_thread_sdr_cap, dev,
-				"%s-sdr-cap", dev->v4l2_dev.name);
-
-		if (IS_ERR(dev->kthread_sdr_cap)) {
-			v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n");
-			err = PTR_ERR(dev->kthread_sdr_cap);
-			dev->kthread_sdr_cap = NULL;
-		}
-	}
-	if (err) {
-		struct vivid_buffer *buf, *tmp;
-
-		list_for_each_entry_safe(buf, tmp, &dev->sdr_cap_active, list) {
-			list_del(&buf->list);
-			vb2_buffer_done(&buf->vb.vb2_buf,
-					VB2_BUF_STATE_QUEUED);
-		}
-	}
-	return err;
-}
-
-/* abort streaming and wait for last buffer */
-static void sdr_cap_stop_streaming(struct vb2_queue *vq)
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vq);
-
-	if (dev->kthread_sdr_cap == NULL)
-		return;
-
-	while (!list_empty(&dev->sdr_cap_active)) {
-		struct vivid_buffer *buf;
-
-		buf = list_entry(dev->sdr_cap_active.next,
-				struct vivid_buffer, list);
-		list_del(&buf->list);
-		v4l2_ctrl_request_complete(buf->vb.vb2_buf.req_obj.req,
-					   &dev->ctrl_hdl_sdr_cap);
-		vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
-	}
-
-	/* shutdown control thread */
-	kthread_stop(dev->kthread_sdr_cap);
-	dev->kthread_sdr_cap = NULL;
-}
-
-static void sdr_cap_buf_request_complete(struct vb2_buffer *vb)
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
-
-	v4l2_ctrl_request_complete(vb->req_obj.req, &dev->ctrl_hdl_sdr_cap);
-}
-
-const struct vb2_ops vivid_sdr_cap_qops = {
-	.queue_setup		= sdr_cap_queue_setup,
-	.buf_prepare		= sdr_cap_buf_prepare,
-	.buf_queue		= sdr_cap_buf_queue,
-	.start_streaming	= sdr_cap_start_streaming,
-	.stop_streaming		= sdr_cap_stop_streaming,
-	.buf_request_complete	= sdr_cap_buf_request_complete,
-	.wait_prepare		= vb2_ops_wait_prepare,
-	.wait_finish		= vb2_ops_wait_finish,
-};
-
-int vivid_sdr_enum_freq_bands(struct file *file, void *fh,
-		struct v4l2_frequency_band *band)
-{
-	switch (band->tuner) {
-	case 0:
-		if (band->index >= ARRAY_SIZE(bands_adc))
-			return -EINVAL;
-		*band = bands_adc[band->index];
-		return 0;
-	case 1:
-		if (band->index >= ARRAY_SIZE(bands_fm))
-			return -EINVAL;
-		*band = bands_fm[band->index];
-		return 0;
-	default:
-		return -EINVAL;
-	}
-}
-
-int vivid_sdr_g_frequency(struct file *file, void *fh,
-		struct v4l2_frequency *vf)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	switch (vf->tuner) {
-	case 0:
-		vf->frequency = dev->sdr_adc_freq;
-		vf->type = V4L2_TUNER_ADC;
-		return 0;
-	case 1:
-		vf->frequency = dev->sdr_fm_freq;
-		vf->type = V4L2_TUNER_RF;
-		return 0;
-	default:
-		return -EINVAL;
-	}
-}
-
-int vivid_sdr_s_frequency(struct file *file, void *fh,
-		const struct v4l2_frequency *vf)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	unsigned freq = vf->frequency;
-	unsigned band;
-
-	switch (vf->tuner) {
-	case 0:
-		if (vf->type != V4L2_TUNER_ADC)
-			return -EINVAL;
-		if (freq < BAND_ADC_0)
-			band = 0;
-		else if (freq < BAND_ADC_1)
-			band = 1;
-		else
-			band = 2;
-
-		freq = clamp_t(unsigned, freq,
-				bands_adc[band].rangelow,
-				bands_adc[band].rangehigh);
-
-		if (vb2_is_streaming(&dev->vb_sdr_cap_q) &&
-		    freq != dev->sdr_adc_freq) {
-			/* resync the thread's timings */
-			dev->sdr_cap_seq_resync = true;
-		}
-		dev->sdr_adc_freq = freq;
-		return 0;
-	case 1:
-		if (vf->type != V4L2_TUNER_RF)
-			return -EINVAL;
-		dev->sdr_fm_freq = clamp_t(unsigned, freq,
-				bands_fm[0].rangelow,
-				bands_fm[0].rangehigh);
-		return 0;
-	default:
-		return -EINVAL;
-	}
-}
-
-int vivid_sdr_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
-{
-	switch (vt->index) {
-	case 0:
-		strscpy(vt->name, "ADC", sizeof(vt->name));
-		vt->type = V4L2_TUNER_ADC;
-		vt->capability =
-			V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
-		vt->rangelow = bands_adc[0].rangelow;
-		vt->rangehigh = bands_adc[2].rangehigh;
-		return 0;
-	case 1:
-		strscpy(vt->name, "RF", sizeof(vt->name));
-		vt->type = V4L2_TUNER_RF;
-		vt->capability =
-			V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
-		vt->rangelow = bands_fm[0].rangelow;
-		vt->rangehigh = bands_fm[0].rangehigh;
-		return 0;
-	default:
-		return -EINVAL;
-	}
-}
-
-int vivid_sdr_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt)
-{
-	if (vt->index > 1)
-		return -EINVAL;
-	return 0;
-}
-
-int vidioc_enum_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f)
-{
-	if (f->index >= ARRAY_SIZE(formats))
-		return -EINVAL;
-	f->pixelformat = formats[f->index].pixelformat;
-	return 0;
-}
-
-int vidioc_g_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_format *f)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	f->fmt.sdr.pixelformat = dev->sdr_pixelformat;
-	f->fmt.sdr.buffersize = dev->sdr_buffersize;
-	memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
-	return 0;
-}
-
-int vidioc_s_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_format *f)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	struct vb2_queue *q = &dev->vb_sdr_cap_q;
-	int i;
-
-	if (vb2_is_busy(q))
-		return -EBUSY;
-
-	memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
-	for (i = 0; i < ARRAY_SIZE(formats); i++) {
-		if (formats[i].pixelformat == f->fmt.sdr.pixelformat) {
-			dev->sdr_pixelformat = formats[i].pixelformat;
-			dev->sdr_buffersize = formats[i].buffersize;
-			f->fmt.sdr.buffersize = formats[i].buffersize;
-			return 0;
-		}
-	}
-	dev->sdr_pixelformat = formats[0].pixelformat;
-	dev->sdr_buffersize = formats[0].buffersize;
-	f->fmt.sdr.pixelformat = formats[0].pixelformat;
-	f->fmt.sdr.buffersize = formats[0].buffersize;
-	return 0;
-}
-
-int vidioc_try_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_format *f)
-{
-	int i;
-
-	memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
-	for (i = 0; i < ARRAY_SIZE(formats); i++) {
-		if (formats[i].pixelformat == f->fmt.sdr.pixelformat) {
-			f->fmt.sdr.buffersize = formats[i].buffersize;
-			return 0;
-		}
-	}
-	f->fmt.sdr.pixelformat = formats[0].pixelformat;
-	f->fmt.sdr.buffersize = formats[0].buffersize;
-	return 0;
-}
-
-#define FIXP_N    (15)
-#define FIXP_FRAC (1 << FIXP_N)
-#define FIXP_2PI  ((int)(2 * 3.141592653589 * FIXP_FRAC))
-#define M_100000PI (3.14159 * 100000)
-
-void vivid_sdr_cap_process(struct vivid_dev *dev, struct vivid_buffer *buf)
-{
-	u8 *vbuf = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
-	unsigned long i;
-	unsigned long plane_size = vb2_plane_size(&buf->vb.vb2_buf, 0);
-	s64 s64tmp;
-	s32 src_phase_step;
-	s32 mod_phase_step;
-	s32 fixp_i;
-	s32 fixp_q;
-
-	/* calculate phase step */
-	#define BEEP_FREQ 1000 /* 1kHz beep */
-	src_phase_step = DIV_ROUND_CLOSEST(FIXP_2PI * BEEP_FREQ,
-					   dev->sdr_adc_freq);
-
-	for (i = 0; i < plane_size; i += 2) {
-		mod_phase_step = fixp_cos32_rad(dev->sdr_fixp_src_phase,
-						FIXP_2PI) >> (31 - FIXP_N);
-
-		dev->sdr_fixp_src_phase += src_phase_step;
-		s64tmp = (s64) mod_phase_step * dev->sdr_fm_deviation;
-		dev->sdr_fixp_mod_phase += div_s64(s64tmp, M_100000PI);
-
-		/*
-		 * Transfer phase angle to [0, 2xPI] in order to avoid variable
-		 * overflow and make it suitable for cosine implementation
-		 * used, which does not support negative angles.
-		 */
-		dev->sdr_fixp_src_phase %= FIXP_2PI;
-		dev->sdr_fixp_mod_phase %= FIXP_2PI;
-
-		if (dev->sdr_fixp_mod_phase < 0)
-			dev->sdr_fixp_mod_phase += FIXP_2PI;
-
-		fixp_i = fixp_cos32_rad(dev->sdr_fixp_mod_phase, FIXP_2PI);
-		fixp_q = fixp_sin32_rad(dev->sdr_fixp_mod_phase, FIXP_2PI);
-
-		/* Normalize fraction values represented with 32 bit precision
-		 * to fixed point representation with FIXP_N bits */
-		fixp_i >>= (31 - FIXP_N);
-		fixp_q >>= (31 - FIXP_N);
-
-		switch (dev->sdr_pixelformat) {
-		case V4L2_SDR_FMT_CU8:
-			/* convert 'fixp float' to u8 [0, +255] */
-			/* u8 = X * 127.5 + 127.5; X is float [-1.0, +1.0] */
-			fixp_i = fixp_i * 1275 + FIXP_FRAC * 1275;
-			fixp_q = fixp_q * 1275 + FIXP_FRAC * 1275;
-			*vbuf++ = DIV_ROUND_CLOSEST(fixp_i, FIXP_FRAC * 10);
-			*vbuf++ = DIV_ROUND_CLOSEST(fixp_q, FIXP_FRAC * 10);
-			break;
-		case V4L2_SDR_FMT_CS8:
-			/* convert 'fixp float' to s8 [-128, +127] */
-			/* s8 = X * 127.5 - 0.5; X is float [-1.0, +1.0] */
-			fixp_i = fixp_i * 1275 - FIXP_FRAC * 5;
-			fixp_q = fixp_q * 1275 - FIXP_FRAC * 5;
-			*vbuf++ = DIV_ROUND_CLOSEST(fixp_i, FIXP_FRAC * 10);
-			*vbuf++ = DIV_ROUND_CLOSEST(fixp_q, FIXP_FRAC * 10);
-			break;
-		default:
-			break;
-		}
-	}
-}
diff --git a/drivers/media/platform/vivid/vivid-sdr-cap.h b/drivers/media/platform/vivid/vivid-sdr-cap.h
deleted file mode 100644
index 813c9248e5a7..000000000000
--- a/drivers/media/platform/vivid/vivid-sdr-cap.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * vivid-sdr-cap.h - software defined radio support functions.
- *
- * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#ifndef _VIVID_SDR_CAP_H_
-#define _VIVID_SDR_CAP_H_
-
-int vivid_sdr_enum_freq_bands(struct file *file, void *fh, struct v4l2_frequency_band *band);
-int vivid_sdr_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf);
-int vivid_sdr_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *vf);
-int vivid_sdr_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt);
-int vivid_sdr_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt);
-int vidioc_enum_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f);
-int vidioc_g_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_format *f);
-int vidioc_s_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_format *f);
-int vidioc_try_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_format *f);
-void vivid_sdr_cap_process(struct vivid_dev *dev, struct vivid_buffer *buf);
-
-extern const struct vb2_ops vivid_sdr_cap_qops;
-
-#endif
diff --git a/drivers/media/platform/vivid/vivid-touch-cap.c b/drivers/media/platform/vivid/vivid-touch-cap.c
deleted file mode 100644
index ebb00b128030..000000000000
--- a/drivers/media/platform/vivid/vivid-touch-cap.c
+++ /dev/null
@@ -1,341 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * vivid-touch-cap.c - touch support functions.
- */
-
-#include "vivid-core.h"
-#include "vivid-kthread-touch.h"
-#include "vivid-vid-common.h"
-#include "vivid-touch-cap.h"
-
-static int touch_cap_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
-				 unsigned int *nplanes, unsigned int sizes[],
-				 struct device *alloc_devs[])
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vq);
-	struct v4l2_pix_format *f = &dev->tch_format;
-	unsigned int size = f->sizeimage;
-
-	if (*nplanes) {
-		if (sizes[0] < size)
-			return -EINVAL;
-	} else {
-		sizes[0] = size;
-	}
-
-	if (vq->num_buffers + *nbuffers < 2)
-		*nbuffers = 2 - vq->num_buffers;
-
-	*nplanes = 1;
-	return 0;
-}
-
-static int touch_cap_buf_prepare(struct vb2_buffer *vb)
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
-	struct v4l2_pix_format *f = &dev->tch_format;
-	unsigned int size = f->sizeimage;
-
-	if (dev->buf_prepare_error) {
-		/*
-		 * Error injection: test what happens if buf_prepare() returns
-		 * an error.
-		 */
-		dev->buf_prepare_error = false;
-		return -EINVAL;
-	}
-	if (vb2_plane_size(vb, 0) < size) {
-		dprintk(dev, 1, "%s data will not fit into plane (%lu < %u)\n",
-			__func__, vb2_plane_size(vb, 0), size);
-		return -EINVAL;
-	}
-	vb2_set_plane_payload(vb, 0, size);
-
-	return 0;
-}
-
-static void touch_cap_buf_queue(struct vb2_buffer *vb)
-{
-	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
-	struct vivid_buffer *buf = container_of(vbuf, struct vivid_buffer, vb);
-
-	vbuf->field = V4L2_FIELD_NONE;
-	spin_lock(&dev->slock);
-	list_add_tail(&buf->list, &dev->touch_cap_active);
-	spin_unlock(&dev->slock);
-}
-
-static int touch_cap_start_streaming(struct vb2_queue *vq, unsigned int count)
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vq);
-	int err;
-
-	dev->touch_cap_seq_count = 0;
-	if (dev->start_streaming_error) {
-		dev->start_streaming_error = false;
-		err = -EINVAL;
-	} else {
-		err = vivid_start_generating_touch_cap(dev);
-	}
-	if (err) {
-		struct vivid_buffer *buf, *tmp;
-
-		list_for_each_entry_safe(buf, tmp,
-					 &dev->touch_cap_active, list) {
-			list_del(&buf->list);
-			vb2_buffer_done(&buf->vb.vb2_buf,
-					VB2_BUF_STATE_QUEUED);
-		}
-	}
-	return err;
-}
-
-/* abort streaming and wait for last buffer */
-static void touch_cap_stop_streaming(struct vb2_queue *vq)
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vq);
-
-	vivid_stop_generating_touch_cap(dev);
-}
-
-static void touch_cap_buf_request_complete(struct vb2_buffer *vb)
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
-
-	v4l2_ctrl_request_complete(vb->req_obj.req, &dev->ctrl_hdl_touch_cap);
-}
-
-const struct vb2_ops vivid_touch_cap_qops = {
-	.queue_setup		= touch_cap_queue_setup,
-	.buf_prepare		= touch_cap_buf_prepare,
-	.buf_queue		= touch_cap_buf_queue,
-	.start_streaming	= touch_cap_start_streaming,
-	.stop_streaming		= touch_cap_stop_streaming,
-	.buf_request_complete	= touch_cap_buf_request_complete,
-	.wait_prepare		= vb2_ops_wait_prepare,
-	.wait_finish		= vb2_ops_wait_finish,
-};
-
-int vivid_enum_fmt_tch(struct file *file, void  *priv, struct v4l2_fmtdesc *f)
-{
-	if (f->index)
-		return -EINVAL;
-
-	f->pixelformat = V4L2_TCH_FMT_DELTA_TD16;
-	return 0;
-}
-
-int vivid_g_fmt_tch(struct file *file, void *priv, struct v4l2_format *f)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (dev->multiplanar)
-		return -ENOTTY;
-	f->fmt.pix = dev->tch_format;
-	return 0;
-}
-
-int vivid_g_fmt_tch_mplane(struct file *file, void *priv, struct v4l2_format *f)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	struct v4l2_format sp_fmt;
-
-	if (!dev->multiplanar)
-		return -ENOTTY;
-	sp_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	sp_fmt.fmt.pix = dev->tch_format;
-	fmt_sp2mp(&sp_fmt, f);
-	return 0;
-}
-
-int vivid_g_parm_tch(struct file *file, void *priv,
-		     struct v4l2_streamparm *parm)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (parm->type != (dev->multiplanar ?
-			   V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
-			   V4L2_BUF_TYPE_VIDEO_CAPTURE))
-		return -EINVAL;
-
-	parm->parm.capture.capability   = V4L2_CAP_TIMEPERFRAME;
-	parm->parm.capture.timeperframe = dev->timeperframe_tch_cap;
-	parm->parm.capture.readbuffers  = 1;
-	return 0;
-}
-
-int vivid_enum_input_tch(struct file *file, void *priv, struct v4l2_input *inp)
-{
-	if (inp->index)
-		return -EINVAL;
-
-	inp->type = V4L2_INPUT_TYPE_TOUCH;
-	strscpy(inp->name, "Vivid Touch", sizeof(inp->name));
-	inp->capabilities = 0;
-	return 0;
-}
-
-int vivid_g_input_tch(struct file *file, void *priv, unsigned int *i)
-{
-	*i = 0;
-	return 0;
-}
-
-int vivid_set_touch(struct vivid_dev *dev, unsigned int i)
-{
-	struct v4l2_pix_format *f = &dev->tch_format;
-
-	if (i)
-		return -EINVAL;
-
-	f->pixelformat = V4L2_TCH_FMT_DELTA_TD16;
-	f->width =  VIVID_TCH_WIDTH;
-	f->height = VIVID_TCH_HEIGHT;
-	f->field = V4L2_FIELD_NONE;
-	f->colorspace = V4L2_COLORSPACE_RAW;
-	f->bytesperline = f->width * sizeof(s16);
-	f->sizeimage = f->width * f->height * sizeof(s16);
-	return 0;
-}
-
-int vivid_s_input_tch(struct file *file, void *priv, unsigned int i)
-{
-	return vivid_set_touch(video_drvdata(file), i);
-}
-
-static void vivid_fill_buff_noise(__s16 *tch_buf, int size)
-{
-	int i;
-
-	/* Fill 10% of the values within range -3 and 3, zero the others */
-	for (i = 0; i < size; i++) {
-		unsigned int rand = get_random_int();
-
-		if (rand % 10)
-			tch_buf[i] = 0;
-		else
-			tch_buf[i] = (rand / 10) % 7 - 3;
-	}
-}
-
-static inline int get_random_pressure(void)
-{
-	return get_random_int() % VIVID_PRESSURE_LIMIT;
-}
-
-static void vivid_tch_buf_set(struct v4l2_pix_format *f,
-			      __s16 *tch_buf,
-			      int index)
-{
-	unsigned int x = index % f->width;
-	unsigned int y = index / f->width;
-	unsigned int offset = VIVID_MIN_PRESSURE;
-
-	tch_buf[index] = offset + get_random_pressure();
-	offset /= 2;
-	if (x)
-		tch_buf[index - 1] = offset + get_random_pressure();
-	if (x < f->width - 1)
-		tch_buf[index + 1] = offset + get_random_pressure();
-	if (y)
-		tch_buf[index - f->width] = offset + get_random_pressure();
-	if (y < f->height - 1)
-		tch_buf[index + f->width] = offset + get_random_pressure();
-	offset /= 2;
-	if (x && y)
-		tch_buf[index - 1 - f->width] = offset + get_random_pressure();
-	if (x < f->width - 1 && y)
-		tch_buf[index + 1 - f->width] = offset + get_random_pressure();
-	if (x && y < f->height - 1)
-		tch_buf[index - 1 + f->width] = offset + get_random_pressure();
-	if (x < f->width - 1 && y < f->height - 1)
-		tch_buf[index + 1 + f->width] = offset + get_random_pressure();
-}
-
-void vivid_fillbuff_tch(struct vivid_dev *dev, struct vivid_buffer *buf)
-{
-	struct v4l2_pix_format *f = &dev->tch_format;
-	int size = f->width * f->height;
-	int x, y, xstart, ystart, offset_x, offset_y;
-	unsigned int test_pattern, test_pat_idx, rand;
-
-	__s16 *tch_buf = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
-
-	buf->vb.sequence = dev->touch_cap_seq_count;
-	test_pattern = (buf->vb.sequence / TCH_SEQ_COUNT) % TEST_CASE_MAX;
-	test_pat_idx = buf->vb.sequence % TCH_SEQ_COUNT;
-
-	vivid_fill_buff_noise(tch_buf, size);
-
-	if (test_pat_idx >= TCH_PATTERN_COUNT)
-		return;
-
-	if (test_pat_idx == 0)
-		dev->tch_pat_random = get_random_int();
-	rand = dev->tch_pat_random;
-
-	switch (test_pattern) {
-	case SINGLE_TAP:
-		if (test_pat_idx == 2)
-			vivid_tch_buf_set(f, tch_buf, rand % size);
-		break;
-	case DOUBLE_TAP:
-		if (test_pat_idx == 2 || test_pat_idx == 4)
-			vivid_tch_buf_set(f, tch_buf, rand % size);
-		break;
-	case TRIPLE_TAP:
-		if (test_pat_idx == 2 || test_pat_idx == 4 || test_pat_idx == 6)
-			vivid_tch_buf_set(f, tch_buf, rand % size);
-		break;
-	case MOVE_LEFT_TO_RIGHT:
-		vivid_tch_buf_set(f, tch_buf,
-				  (rand % f->height) * f->width +
-				  test_pat_idx *
-				  (f->width / TCH_PATTERN_COUNT));
-		break;
-	case ZOOM_IN:
-		x = f->width / 2;
-		y = f->height / 2;
-		offset_x = ((TCH_PATTERN_COUNT - 1 - test_pat_idx) * x) /
-				TCH_PATTERN_COUNT;
-		offset_y = ((TCH_PATTERN_COUNT - 1 - test_pat_idx) * y) /
-				TCH_PATTERN_COUNT;
-		vivid_tch_buf_set(f, tch_buf,
-				  (x - offset_x) + f->width * (y - offset_y));
-		vivid_tch_buf_set(f, tch_buf,
-				  (x + offset_x) + f->width * (y + offset_y));
-		break;
-	case ZOOM_OUT:
-		x = f->width / 2;
-		y = f->height / 2;
-		offset_x = (test_pat_idx * x) / TCH_PATTERN_COUNT;
-		offset_y = (test_pat_idx * y) / TCH_PATTERN_COUNT;
-		vivid_tch_buf_set(f, tch_buf,
-				  (x - offset_x) + f->width * (y - offset_y));
-		vivid_tch_buf_set(f, tch_buf,
-				  (x + offset_x) + f->width * (y + offset_y));
-		break;
-	case PALM_PRESS:
-		for (x = 0; x < f->width; x++)
-			for (y = f->height / 2; y < f->height; y++)
-				tch_buf[x + f->width * y] = VIVID_MIN_PRESSURE +
-							get_random_pressure();
-		break;
-	case MULTIPLE_PRESS:
-		/* 16 pressure points */
-		for (y = 0; y < 4; y++) {
-			for (x = 0; x < 4; x++) {
-				ystart = (y * f->height) / 4 + f->height / 8;
-				xstart = (x * f->width) / 4 + f->width / 8;
-				vivid_tch_buf_set(f, tch_buf,
-						  ystart * f->width + xstart);
-			}
-		}
-		break;
-	}
-#ifdef __BIG_ENDIAN__
-	for (x = 0; x < size; x++)
-		tch_buf[x] = (__force s16)__cpu_to_le16((u16)tch_buf[x]);
-#endif
-}
diff --git a/drivers/media/platform/vivid/vivid-touch-cap.h b/drivers/media/platform/vivid/vivid-touch-cap.h
deleted file mode 100644
index 07e514046ae8..000000000000
--- a/drivers/media/platform/vivid/vivid-touch-cap.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * vivid-touch-cap.h - touch support functions.
- */
-#ifndef _VIVID_TOUCH_CAP_H_
-#define _VIVID_TOUCH_CAP_H_
-
-#define VIVID_TCH_HEIGHT	12
-#define VIVID_TCH_WIDTH		21
-#define VIVID_MIN_PRESSURE	180
-#define VIVID_PRESSURE_LIMIT	40
-#define TCH_SEQ_COUNT		16
-#define TCH_PATTERN_COUNT	12
-
-enum vivid_tch_test {
-	SINGLE_TAP,
-	DOUBLE_TAP,
-	TRIPLE_TAP,
-	MOVE_LEFT_TO_RIGHT,
-	ZOOM_IN,
-	ZOOM_OUT,
-	PALM_PRESS,
-	MULTIPLE_PRESS,
-	TEST_CASE_MAX
-};
-
-extern const struct vb2_ops vivid_touch_cap_qops;
-
-int vivid_enum_fmt_tch(struct file *file, void  *priv, struct v4l2_fmtdesc *f);
-int vivid_g_fmt_tch(struct file *file, void *priv, struct v4l2_format *f);
-int vivid_g_fmt_tch_mplane(struct file *file, void *priv, struct v4l2_format *f);
-int vivid_enum_input_tch(struct file *file, void *priv, struct v4l2_input *inp);
-int vivid_g_input_tch(struct file *file, void *priv, unsigned int *i);
-int vivid_s_input_tch(struct file *file, void *priv, unsigned int i);
-void vivid_fillbuff_tch(struct vivid_dev *dev, struct vivid_buffer *buf);
-int vivid_set_touch(struct vivid_dev *dev, unsigned int i);
-int vivid_g_parm_tch(struct file *file, void *priv,
-		     struct v4l2_streamparm *parm);
-#endif
diff --git a/drivers/media/platform/vivid/vivid-vbi-cap.c b/drivers/media/platform/vivid/vivid-vbi-cap.c
deleted file mode 100644
index 1a9348eea781..000000000000
--- a/drivers/media/platform/vivid/vivid-vbi-cap.c
+++ /dev/null
@@ -1,365 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * vivid-vbi-cap.c - vbi capture support functions.
- *
- * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-
-#include "vivid-core.h"
-#include "vivid-kthread-cap.h"
-#include "vivid-vbi-cap.h"
-#include "vivid-vbi-gen.h"
-
-static void vivid_sliced_vbi_cap_fill(struct vivid_dev *dev, unsigned seqnr)
-{
-	struct vivid_vbi_gen_data *vbi_gen = &dev->vbi_gen;
-	bool is_60hz = dev->std_cap[dev->input] & V4L2_STD_525_60;
-
-	vivid_vbi_gen_sliced(vbi_gen, is_60hz, seqnr);
-
-	if (!is_60hz) {
-		if (dev->loop_video) {
-			if (dev->vbi_out_have_wss) {
-				vbi_gen->data[12].data[0] = dev->vbi_out_wss[0];
-				vbi_gen->data[12].data[1] = dev->vbi_out_wss[1];
-			} else {
-				vbi_gen->data[12].id = 0;
-			}
-		} else {
-			switch (tpg_g_video_aspect(&dev->tpg)) {
-			case TPG_VIDEO_ASPECT_14X9_CENTRE:
-				vbi_gen->data[12].data[0] = 0x01;
-				break;
-			case TPG_VIDEO_ASPECT_16X9_CENTRE:
-				vbi_gen->data[12].data[0] = 0x0b;
-				break;
-			case TPG_VIDEO_ASPECT_16X9_ANAMORPHIC:
-				vbi_gen->data[12].data[0] = 0x07;
-				break;
-			case TPG_VIDEO_ASPECT_4X3:
-			default:
-				vbi_gen->data[12].data[0] = 0x08;
-				break;
-			}
-		}
-	} else if (dev->loop_video && is_60hz) {
-		if (dev->vbi_out_have_cc[0]) {
-			vbi_gen->data[0].data[0] = dev->vbi_out_cc[0][0];
-			vbi_gen->data[0].data[1] = dev->vbi_out_cc[0][1];
-		} else {
-			vbi_gen->data[0].id = 0;
-		}
-		if (dev->vbi_out_have_cc[1]) {
-			vbi_gen->data[1].data[0] = dev->vbi_out_cc[1][0];
-			vbi_gen->data[1].data[1] = dev->vbi_out_cc[1][1];
-		} else {
-			vbi_gen->data[1].id = 0;
-		}
-	}
-}
-
-static void vivid_g_fmt_vbi_cap(struct vivid_dev *dev, struct v4l2_vbi_format *vbi)
-{
-	bool is_60hz = dev->std_cap[dev->input] & V4L2_STD_525_60;
-
-	vbi->sampling_rate = 27000000;
-	vbi->offset = 24;
-	vbi->samples_per_line = 1440;
-	vbi->sample_format = V4L2_PIX_FMT_GREY;
-	vbi->start[0] = is_60hz ? V4L2_VBI_ITU_525_F1_START + 9 : V4L2_VBI_ITU_625_F1_START + 5;
-	vbi->start[1] = is_60hz ? V4L2_VBI_ITU_525_F2_START + 9 : V4L2_VBI_ITU_625_F2_START + 5;
-	vbi->count[0] = vbi->count[1] = is_60hz ? 12 : 18;
-	vbi->flags = dev->vbi_cap_interlaced ? V4L2_VBI_INTERLACED : 0;
-	vbi->reserved[0] = 0;
-	vbi->reserved[1] = 0;
-}
-
-void vivid_raw_vbi_cap_process(struct vivid_dev *dev, struct vivid_buffer *buf)
-{
-	struct v4l2_vbi_format vbi;
-	u8 *vbuf = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
-
-	vivid_g_fmt_vbi_cap(dev, &vbi);
-	buf->vb.sequence = dev->vbi_cap_seq_count;
-	if (dev->field_cap == V4L2_FIELD_ALTERNATE)
-		buf->vb.sequence /= 2;
-
-	vivid_sliced_vbi_cap_fill(dev, buf->vb.sequence);
-
-	memset(vbuf, 0x10, vb2_plane_size(&buf->vb.vb2_buf, 0));
-
-	if (!VIVID_INVALID_SIGNAL(dev->std_signal_mode[dev->input]))
-		vivid_vbi_gen_raw(&dev->vbi_gen, &vbi, vbuf);
-}
-
-
-void vivid_sliced_vbi_cap_process(struct vivid_dev *dev,
-			struct vivid_buffer *buf)
-{
-	struct v4l2_sliced_vbi_data *vbuf =
-			vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
-
-	buf->vb.sequence = dev->vbi_cap_seq_count;
-	if (dev->field_cap == V4L2_FIELD_ALTERNATE)
-		buf->vb.sequence /= 2;
-
-	vivid_sliced_vbi_cap_fill(dev, buf->vb.sequence);
-
-	memset(vbuf, 0, vb2_plane_size(&buf->vb.vb2_buf, 0));
-	if (!VIVID_INVALID_SIGNAL(dev->std_signal_mode[dev->input])) {
-		unsigned i;
-
-		for (i = 0; i < 25; i++)
-			vbuf[i] = dev->vbi_gen.data[i];
-	}
-}
-
-static int vbi_cap_queue_setup(struct vb2_queue *vq,
-		       unsigned *nbuffers, unsigned *nplanes,
-		       unsigned sizes[], struct device *alloc_devs[])
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vq);
-	bool is_60hz = dev->std_cap[dev->input] & V4L2_STD_525_60;
-	unsigned size = vq->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE ?
-		36 * sizeof(struct v4l2_sliced_vbi_data) :
-		1440 * 2 * (is_60hz ? 12 : 18);
-
-	if (!vivid_is_sdtv_cap(dev))
-		return -EINVAL;
-
-	sizes[0] = size;
-
-	if (vq->num_buffers + *nbuffers < 2)
-		*nbuffers = 2 - vq->num_buffers;
-
-	*nplanes = 1;
-	return 0;
-}
-
-static int vbi_cap_buf_prepare(struct vb2_buffer *vb)
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
-	bool is_60hz = dev->std_cap[dev->input] & V4L2_STD_525_60;
-	unsigned size = vb->vb2_queue->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE ?
-		36 * sizeof(struct v4l2_sliced_vbi_data) :
-		1440 * 2 * (is_60hz ? 12 : 18);
-
-	dprintk(dev, 1, "%s\n", __func__);
-
-	if (dev->buf_prepare_error) {
-		/*
-		 * Error injection: test what happens if buf_prepare() returns
-		 * an error.
-		 */
-		dev->buf_prepare_error = false;
-		return -EINVAL;
-	}
-	if (vb2_plane_size(vb, 0) < size) {
-		dprintk(dev, 1, "%s data will not fit into plane (%lu < %u)\n",
-				__func__, vb2_plane_size(vb, 0), size);
-		return -EINVAL;
-	}
-	vb2_set_plane_payload(vb, 0, size);
-
-	return 0;
-}
-
-static void vbi_cap_buf_queue(struct vb2_buffer *vb)
-{
-	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
-	struct vivid_buffer *buf = container_of(vbuf, struct vivid_buffer, vb);
-
-	dprintk(dev, 1, "%s\n", __func__);
-
-	spin_lock(&dev->slock);
-	list_add_tail(&buf->list, &dev->vbi_cap_active);
-	spin_unlock(&dev->slock);
-}
-
-static int vbi_cap_start_streaming(struct vb2_queue *vq, unsigned count)
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vq);
-	int err;
-
-	dprintk(dev, 1, "%s\n", __func__);
-	dev->vbi_cap_seq_count = 0;
-	if (dev->start_streaming_error) {
-		dev->start_streaming_error = false;
-		err = -EINVAL;
-	} else {
-		err = vivid_start_generating_vid_cap(dev, &dev->vbi_cap_streaming);
-	}
-	if (err) {
-		struct vivid_buffer *buf, *tmp;
-
-		list_for_each_entry_safe(buf, tmp, &dev->vbi_cap_active, list) {
-			list_del(&buf->list);
-			vb2_buffer_done(&buf->vb.vb2_buf,
-					VB2_BUF_STATE_QUEUED);
-		}
-	}
-	return err;
-}
-
-/* abort streaming and wait for last buffer */
-static void vbi_cap_stop_streaming(struct vb2_queue *vq)
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vq);
-
-	dprintk(dev, 1, "%s\n", __func__);
-	vivid_stop_generating_vid_cap(dev, &dev->vbi_cap_streaming);
-}
-
-static void vbi_cap_buf_request_complete(struct vb2_buffer *vb)
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
-
-	v4l2_ctrl_request_complete(vb->req_obj.req, &dev->ctrl_hdl_vbi_cap);
-}
-
-const struct vb2_ops vivid_vbi_cap_qops = {
-	.queue_setup		= vbi_cap_queue_setup,
-	.buf_prepare		= vbi_cap_buf_prepare,
-	.buf_queue		= vbi_cap_buf_queue,
-	.start_streaming	= vbi_cap_start_streaming,
-	.stop_streaming		= vbi_cap_stop_streaming,
-	.buf_request_complete	= vbi_cap_buf_request_complete,
-	.wait_prepare		= vb2_ops_wait_prepare,
-	.wait_finish		= vb2_ops_wait_finish,
-};
-
-int vidioc_g_fmt_vbi_cap(struct file *file, void *priv,
-					struct v4l2_format *f)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	struct v4l2_vbi_format *vbi = &f->fmt.vbi;
-
-	if (!vivid_is_sdtv_cap(dev) || !dev->has_raw_vbi_cap)
-		return -EINVAL;
-
-	vivid_g_fmt_vbi_cap(dev, vbi);
-	return 0;
-}
-
-int vidioc_s_fmt_vbi_cap(struct file *file, void *priv,
-					struct v4l2_format *f)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	int ret = vidioc_g_fmt_vbi_cap(file, priv, f);
-
-	if (ret)
-		return ret;
-	if (dev->stream_sliced_vbi_cap && vb2_is_busy(&dev->vb_vbi_cap_q))
-		return -EBUSY;
-	dev->stream_sliced_vbi_cap = false;
-	dev->vbi_cap_dev.queue->type = V4L2_BUF_TYPE_VBI_CAPTURE;
-	return 0;
-}
-
-void vivid_fill_service_lines(struct v4l2_sliced_vbi_format *vbi, u32 service_set)
-{
-	vbi->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
-	vbi->service_set = service_set;
-	memset(vbi->service_lines, 0, sizeof(vbi->service_lines));
-	memset(vbi->reserved, 0, sizeof(vbi->reserved));
-
-	if (vbi->service_set == 0)
-		return;
-
-	if (vbi->service_set & V4L2_SLICED_CAPTION_525) {
-		vbi->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
-		vbi->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
-	}
-	if (vbi->service_set & V4L2_SLICED_WSS_625) {
-		unsigned i;
-
-		for (i = 7; i <= 18; i++)
-			vbi->service_lines[0][i] =
-			vbi->service_lines[1][i] = V4L2_SLICED_TELETEXT_B;
-		vbi->service_lines[0][23] = V4L2_SLICED_WSS_625;
-	}
-}
-
-int vidioc_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	struct v4l2_sliced_vbi_format *vbi = &fmt->fmt.sliced;
-
-	if (!vivid_is_sdtv_cap(dev) || !dev->has_sliced_vbi_cap)
-		return -EINVAL;
-
-	vivid_fill_service_lines(vbi, dev->service_set_cap);
-	return 0;
-}
-
-int vidioc_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	struct v4l2_sliced_vbi_format *vbi = &fmt->fmt.sliced;
-	bool is_60hz = dev->std_cap[dev->input] & V4L2_STD_525_60;
-	u32 service_set = vbi->service_set;
-
-	if (!vivid_is_sdtv_cap(dev) || !dev->has_sliced_vbi_cap)
-		return -EINVAL;
-
-	service_set &= is_60hz ? V4L2_SLICED_CAPTION_525 :
-				 V4L2_SLICED_WSS_625 | V4L2_SLICED_TELETEXT_B;
-	vivid_fill_service_lines(vbi, service_set);
-	return 0;
-}
-
-int vidioc_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	struct v4l2_sliced_vbi_format *vbi = &fmt->fmt.sliced;
-	int ret = vidioc_try_fmt_sliced_vbi_cap(file, fh, fmt);
-
-	if (ret)
-		return ret;
-	if (!dev->stream_sliced_vbi_cap && vb2_is_busy(&dev->vb_vbi_cap_q))
-		return -EBUSY;
-	dev->service_set_cap = vbi->service_set;
-	dev->stream_sliced_vbi_cap = true;
-	dev->vbi_cap_dev.queue->type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
-	return 0;
-}
-
-int vidioc_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced_vbi_cap *cap)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	struct video_device *vdev = video_devdata(file);
-	bool is_60hz;
-
-	if (vdev->vfl_dir == VFL_DIR_RX) {
-		is_60hz = dev->std_cap[dev->input] & V4L2_STD_525_60;
-		if (!vivid_is_sdtv_cap(dev) || !dev->has_sliced_vbi_cap ||
-		    cap->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
-			return -EINVAL;
-	} else {
-		is_60hz = dev->std_out & V4L2_STD_525_60;
-		if (!vivid_is_svid_out(dev) || !dev->has_sliced_vbi_out ||
-		    cap->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT)
-			return -EINVAL;
-	}
-
-	cap->service_set = is_60hz ? V4L2_SLICED_CAPTION_525 :
-				     V4L2_SLICED_WSS_625 | V4L2_SLICED_TELETEXT_B;
-	if (is_60hz) {
-		cap->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
-		cap->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
-	} else {
-		unsigned i;
-
-		for (i = 7; i <= 18; i++)
-			cap->service_lines[0][i] =
-			cap->service_lines[1][i] = V4L2_SLICED_TELETEXT_B;
-		cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
-	}
-	return 0;
-}
diff --git a/drivers/media/platform/vivid/vivid-vbi-cap.h b/drivers/media/platform/vivid/vivid-vbi-cap.h
deleted file mode 100644
index 91d2de01381c..000000000000
--- a/drivers/media/platform/vivid/vivid-vbi-cap.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * vivid-vbi-cap.h - vbi capture support functions.
- *
- * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#ifndef _VIVID_VBI_CAP_H_
-#define _VIVID_VBI_CAP_H_
-
-void vivid_fill_time_of_day_packet(u8 *packet);
-void vivid_raw_vbi_cap_process(struct vivid_dev *dev, struct vivid_buffer *buf);
-void vivid_sliced_vbi_cap_process(struct vivid_dev *dev, struct vivid_buffer *buf);
-void vivid_sliced_vbi_out_process(struct vivid_dev *dev, struct vivid_buffer *buf);
-int vidioc_g_fmt_vbi_cap(struct file *file, void *priv,
-					struct v4l2_format *f);
-int vidioc_s_fmt_vbi_cap(struct file *file, void *priv,
-					struct v4l2_format *f);
-int vidioc_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt);
-int vidioc_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt);
-int vidioc_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt);
-int vidioc_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced_vbi_cap *cap);
-
-void vivid_fill_service_lines(struct v4l2_sliced_vbi_format *vbi, u32 service_set);
-
-extern const struct vb2_ops vivid_vbi_cap_qops;
-
-#endif
diff --git a/drivers/media/platform/vivid/vivid-vbi-gen.c b/drivers/media/platform/vivid/vivid-vbi-gen.c
deleted file mode 100644
index acc98445a1fa..000000000000
--- a/drivers/media/platform/vivid/vivid-vbi-gen.c
+++ /dev/null
@@ -1,311 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * vivid-vbi-gen.c - vbi generator support functions.
- *
- * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/ktime.h>
-#include <linux/string.h>
-#include <linux/videodev2.h>
-
-#include "vivid-vbi-gen.h"
-
-static void wss_insert(u8 *wss, u32 val, unsigned size)
-{
-	while (size--)
-		*wss++ = (val & (1 << size)) ? 0xc0 : 0x10;
-}
-
-static void vivid_vbi_gen_wss_raw(const struct v4l2_sliced_vbi_data *data,
-		u8 *buf, unsigned sampling_rate)
-{
-	const unsigned rate = 5000000;	/* WSS has a 5 MHz transmission rate */
-	u8 wss[29 + 24 + 24 + 24 + 18 + 18] = { 0 };
-	const unsigned zero = 0x07;
-	const unsigned one = 0x38;
-	unsigned bit = 0;
-	u16 wss_data;
-	int i;
-
-	wss_insert(wss + bit, 0x1f1c71c7, 29); bit += 29;
-	wss_insert(wss + bit, 0x1e3c1f, 24); bit += 24;
-
-	wss_data = (data->data[1] << 8) | data->data[0];
-	for (i = 0; i <= 13; i++, bit += 6)
-		wss_insert(wss + bit, (wss_data & (1 << i)) ? one : zero, 6);
-
-	for (i = 0, bit = 0; bit < sizeof(wss); bit++) {
-		unsigned n = ((bit + 1) * sampling_rate) / rate;
-
-		while (i < n)
-			buf[i++] = wss[bit];
-	}
-}
-
-static void vivid_vbi_gen_teletext_raw(const struct v4l2_sliced_vbi_data *data,
-		u8 *buf, unsigned sampling_rate)
-{
-	const unsigned rate = 6937500 / 10;	/* Teletext has a 6.9375 MHz transmission rate */
-	u8 teletext[45] = { 0x55, 0x55, 0x27 };
-	unsigned bit = 0;
-	int i;
-
-	memcpy(teletext + 3, data->data, sizeof(teletext) - 3);
-	/* prevents 32 bit overflow */
-	sampling_rate /= 10;
-
-	for (i = 0, bit = 0; bit < sizeof(teletext) * 8; bit++) {
-		unsigned n = ((bit + 1) * sampling_rate) / rate;
-		u8 val = (teletext[bit / 8] & (1 << (bit & 7))) ? 0xc0 : 0x10;
-
-		while (i < n)
-			buf[i++] = val;
-	}
-}
-
-static void cc_insert(u8 *cc, u8 ch)
-{
-	unsigned tot = 0;
-	unsigned i;
-
-	for (i = 0; i < 7; i++) {
-		cc[2 * i] = cc[2 * i + 1] = (ch & (1 << i)) ? 1 : 0;
-		tot += cc[2 * i];
-	}
-	cc[14] = cc[15] = !(tot & 1);
-}
-
-#define CC_PREAMBLE_BITS (14 + 4 + 2)
-
-static void vivid_vbi_gen_cc_raw(const struct v4l2_sliced_vbi_data *data,
-		u8 *buf, unsigned sampling_rate)
-{
-	const unsigned rate = 1000000;	/* CC has a 1 MHz transmission rate */
-
-	u8 cc[CC_PREAMBLE_BITS + 2 * 16] = {
-		/* Clock run-in: 7 cycles */
-		0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
-		/* 2 cycles of 0 */
-		0, 0, 0, 0,
-		/* Start bit of 1 (each bit is two cycles) */
-		1, 1
-	};
-	unsigned bit, i;
-
-	cc_insert(cc + CC_PREAMBLE_BITS, data->data[0]);
-	cc_insert(cc + CC_PREAMBLE_BITS + 16, data->data[1]);
-
-	for (i = 0, bit = 0; bit < sizeof(cc); bit++) {
-		unsigned n = ((bit + 1) * sampling_rate) / rate;
-
-		while (i < n)
-			buf[i++] = cc[bit] ? 0xc0 : 0x10;
-	}
-}
-
-void vivid_vbi_gen_raw(const struct vivid_vbi_gen_data *vbi,
-		const struct v4l2_vbi_format *vbi_fmt, u8 *buf)
-{
-	unsigned idx;
-
-	for (idx = 0; idx < 25; idx++) {
-		const struct v4l2_sliced_vbi_data *data = vbi->data + idx;
-		unsigned start_2nd_field;
-		unsigned line = data->line;
-		u8 *linebuf = buf;
-
-		start_2nd_field = (data->id & V4L2_SLICED_VBI_525) ? 263 : 313;
-		if (data->field)
-			line += start_2nd_field;
-		line -= vbi_fmt->start[data->field];
-
-		if (vbi_fmt->flags & V4L2_VBI_INTERLACED)
-			linebuf += (line * 2 + data->field) *
-				vbi_fmt->samples_per_line;
-		else
-			linebuf += (line + data->field * vbi_fmt->count[0]) *
-				vbi_fmt->samples_per_line;
-		if (data->id == V4L2_SLICED_CAPTION_525)
-			vivid_vbi_gen_cc_raw(data, linebuf, vbi_fmt->sampling_rate);
-		else if (data->id == V4L2_SLICED_WSS_625)
-			vivid_vbi_gen_wss_raw(data, linebuf, vbi_fmt->sampling_rate);
-		else if (data->id == V4L2_SLICED_TELETEXT_B)
-			vivid_vbi_gen_teletext_raw(data, linebuf, vbi_fmt->sampling_rate);
-	}
-}
-
-static const u8 vivid_cc_sequence1[30] = {
-	0x14, 0x20,	/* Resume Caption Loading */
-	'H',  'e',
-	'l',  'l',
-	'o',  ' ',
-	'w',  'o',
-	'r',  'l',
-	'd',  '!',
-	0x14, 0x2f,	/* End of Caption */
-};
-
-static const u8 vivid_cc_sequence2[30] = {
-	0x14, 0x20,	/* Resume Caption Loading */
-	'C',  'l',
-	'o',  's',
-	'e',  'd',
-	' ',  'c',
-	'a',  'p',
-	't',  'i',
-	'o',  'n',
-	's',  ' ',
-	't',  'e',
-	's',  't',
-	0x14, 0x2f,	/* End of Caption */
-};
-
-static u8 calc_parity(u8 val)
-{
-	unsigned i;
-	unsigned tot = 0;
-
-	for (i = 0; i < 7; i++)
-		tot += (val & (1 << i)) ? 1 : 0;
-	return val | ((tot & 1) ? 0 : 0x80);
-}
-
-static void vivid_vbi_gen_set_time_of_day(u8 *packet)
-{
-	struct tm tm;
-	u8 checksum, i;
-
-	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);
-	packet[3] = calc_parity(0x40 | tm.tm_hour);
-	packet[4] = calc_parity(0x40 | tm.tm_mday);
-	if (tm.tm_mday == 1 && tm.tm_mon == 2 &&
-	    sys_tz.tz_minuteswest > tm.tm_min + tm.tm_hour * 60)
-		packet[4] = calc_parity(0x60 | tm.tm_mday);
-	packet[5] = calc_parity(0x40 | (1 + tm.tm_mon));
-	packet[6] = calc_parity(0x40 | (1 + tm.tm_wday));
-	packet[7] = calc_parity(0x40 | ((tm.tm_year - 90) & 0x3f));
-	packet[8] = calc_parity(0x0f);
-	for (checksum = i = 0; i <= 8; i++)
-		checksum += packet[i] & 0x7f;
-	packet[9] = calc_parity(0x100 - checksum);
-	checksum = 0;
-	packet[10] = calc_parity(0x07);
-	packet[11] = calc_parity(0x04);
-	if (sys_tz.tz_minuteswest >= 0)
-		packet[12] = calc_parity(0x40 | ((sys_tz.tz_minuteswest / 60) & 0x1f));
-	else
-		packet[12] = calc_parity(0x40 | ((24 + sys_tz.tz_minuteswest / 60) & 0x1f));
-	packet[13] = calc_parity(0);
-	packet[14] = calc_parity(0x0f);
-	for (checksum = 0, i = 10; i <= 14; i++)
-		checksum += packet[i] & 0x7f;
-	packet[15] = calc_parity(0x100 - checksum);
-}
-
-static const u8 hamming[16] = {
-	0x15, 0x02, 0x49, 0x5e, 0x64, 0x73, 0x38, 0x2f,
-	0xd0, 0xc7, 0x8c, 0x9b, 0xa1, 0xb6, 0xfd, 0xea
-};
-
-static void vivid_vbi_gen_teletext(u8 *packet, unsigned line, unsigned frame)
-{
-	unsigned offset = 2;
-	unsigned i;
-
-	packet[0] = hamming[1 + ((line & 1) << 3)];
-	packet[1] = hamming[line >> 1];
-	memset(packet + 2, 0x20, 40);
-	if (line == 0) {
-		/* subcode */
-		packet[2] = hamming[frame % 10];
-		packet[3] = hamming[frame / 10];
-		packet[4] = hamming[0];
-		packet[5] = hamming[0];
-		packet[6] = hamming[0];
-		packet[7] = hamming[0];
-		packet[8] = hamming[0];
-		packet[9] = hamming[1];
-		offset = 10;
-	}
-	packet += offset;
-	memcpy(packet, "Page: 100 Row: 10", 17);
-	packet[7] = '0' + frame / 10;
-	packet[8] = '0' + frame % 10;
-	packet[15] = '0' + line / 10;
-	packet[16] = '0' + line % 10;
-	for (i = 0; i < 42 - offset; i++)
-		packet[i] = calc_parity(packet[i]);
-}
-
-void vivid_vbi_gen_sliced(struct vivid_vbi_gen_data *vbi,
-		bool is_60hz, unsigned seqnr)
-{
-	struct v4l2_sliced_vbi_data *data0 = vbi->data;
-	struct v4l2_sliced_vbi_data *data1 = vbi->data + 1;
-	unsigned frame = seqnr % 60;
-
-	memset(vbi->data, 0, sizeof(vbi->data));
-
-	if (!is_60hz) {
-		unsigned i;
-
-		for (i = 0; i <= 11; i++) {
-			data0->id = V4L2_SLICED_TELETEXT_B;
-			data0->line = 7 + i;
-			vivid_vbi_gen_teletext(data0->data, i, frame);
-			data0++;
-		}
-		data0->id = V4L2_SLICED_WSS_625;
-		data0->line = 23;
-		/* 4x3 video aspect ratio */
-		data0->data[0] = 0x08;
-		data0++;
-		for (i = 0; i <= 11; i++) {
-			data0->id = V4L2_SLICED_TELETEXT_B;
-			data0->field = 1;
-			data0->line = 7 + i;
-			vivid_vbi_gen_teletext(data0->data, 12 + i, frame);
-			data0++;
-		}
-		return;
-	}
-
-	data0->id = V4L2_SLICED_CAPTION_525;
-	data0->line = 21;
-	data1->id = V4L2_SLICED_CAPTION_525;
-	data1->field = 1;
-	data1->line = 21;
-
-	if (frame < 15) {
-		data0->data[0] = calc_parity(vivid_cc_sequence1[2 * frame]);
-		data0->data[1] = calc_parity(vivid_cc_sequence1[2 * frame + 1]);
-	} else if (frame >= 30 && frame < 45) {
-		frame -= 30;
-		data0->data[0] = calc_parity(vivid_cc_sequence2[2 * frame]);
-		data0->data[1] = calc_parity(vivid_cc_sequence2[2 * frame + 1]);
-	} else {
-		data0->data[0] = calc_parity(0);
-		data0->data[1] = calc_parity(0);
-	}
-
-	frame = seqnr % (30 * 60);
-	switch (frame) {
-	case 0:
-		vivid_vbi_gen_set_time_of_day(vbi->time_of_day_packet);
-		/* fall through */
-	case 1 ... 7:
-		data1->data[0] = vbi->time_of_day_packet[frame * 2];
-		data1->data[1] = vbi->time_of_day_packet[frame * 2 + 1];
-		break;
-	default:
-		data1->data[0] = calc_parity(0);
-		data1->data[1] = calc_parity(0);
-		break;
-	}
-}
diff --git a/drivers/media/platform/vivid/vivid-vbi-gen.h b/drivers/media/platform/vivid/vivid-vbi-gen.h
deleted file mode 100644
index 2657a7f5571c..000000000000
--- a/drivers/media/platform/vivid/vivid-vbi-gen.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * vivid-vbi-gen.h - vbi generator support functions.
- *
- * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#ifndef _VIVID_VBI_GEN_H_
-#define _VIVID_VBI_GEN_H_
-
-struct vivid_vbi_gen_data {
-	struct v4l2_sliced_vbi_data data[25];
-	u8 time_of_day_packet[16];
-};
-
-void vivid_vbi_gen_sliced(struct vivid_vbi_gen_data *vbi,
-		bool is_60hz, unsigned seqnr);
-void vivid_vbi_gen_raw(const struct vivid_vbi_gen_data *vbi,
-		const struct v4l2_vbi_format *vbi_fmt, u8 *buf);
-
-#endif
diff --git a/drivers/media/platform/vivid/vivid-vbi-out.c b/drivers/media/platform/vivid/vivid-vbi-out.c
deleted file mode 100644
index cd56476902a2..000000000000
--- a/drivers/media/platform/vivid/vivid-vbi-out.c
+++ /dev/null
@@ -1,250 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * vivid-vbi-out.c - vbi output support functions.
- *
- * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-
-#include "vivid-core.h"
-#include "vivid-kthread-out.h"
-#include "vivid-vbi-out.h"
-#include "vivid-vbi-cap.h"
-
-static int vbi_out_queue_setup(struct vb2_queue *vq,
-		       unsigned *nbuffers, unsigned *nplanes,
-		       unsigned sizes[], struct device *alloc_devs[])
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vq);
-	bool is_60hz = dev->std_out & V4L2_STD_525_60;
-	unsigned size = vq->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT ?
-		36 * sizeof(struct v4l2_sliced_vbi_data) :
-		1440 * 2 * (is_60hz ? 12 : 18);
-
-	if (!vivid_is_svid_out(dev))
-		return -EINVAL;
-
-	sizes[0] = size;
-
-	if (vq->num_buffers + *nbuffers < 2)
-		*nbuffers = 2 - vq->num_buffers;
-
-	*nplanes = 1;
-	return 0;
-}
-
-static int vbi_out_buf_prepare(struct vb2_buffer *vb)
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
-	bool is_60hz = dev->std_out & V4L2_STD_525_60;
-	unsigned size = vb->vb2_queue->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT ?
-		36 * sizeof(struct v4l2_sliced_vbi_data) :
-		1440 * 2 * (is_60hz ? 12 : 18);
-
-	dprintk(dev, 1, "%s\n", __func__);
-
-	if (dev->buf_prepare_error) {
-		/*
-		 * Error injection: test what happens if buf_prepare() returns
-		 * an error.
-		 */
-		dev->buf_prepare_error = false;
-		return -EINVAL;
-	}
-	if (vb2_plane_size(vb, 0) < size) {
-		dprintk(dev, 1, "%s data will not fit into plane (%lu < %u)\n",
-				__func__, vb2_plane_size(vb, 0), size);
-		return -EINVAL;
-	}
-	vb2_set_plane_payload(vb, 0, size);
-
-	return 0;
-}
-
-static void vbi_out_buf_queue(struct vb2_buffer *vb)
-{
-	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
-	struct vivid_buffer *buf = container_of(vbuf, struct vivid_buffer, vb);
-
-	dprintk(dev, 1, "%s\n", __func__);
-
-	spin_lock(&dev->slock);
-	list_add_tail(&buf->list, &dev->vbi_out_active);
-	spin_unlock(&dev->slock);
-}
-
-static int vbi_out_start_streaming(struct vb2_queue *vq, unsigned count)
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vq);
-	int err;
-
-	dprintk(dev, 1, "%s\n", __func__);
-	dev->vbi_out_seq_count = 0;
-	if (dev->start_streaming_error) {
-		dev->start_streaming_error = false;
-		err = -EINVAL;
-	} else {
-		err = vivid_start_generating_vid_out(dev, &dev->vbi_out_streaming);
-	}
-	if (err) {
-		struct vivid_buffer *buf, *tmp;
-
-		list_for_each_entry_safe(buf, tmp, &dev->vbi_out_active, list) {
-			list_del(&buf->list);
-			vb2_buffer_done(&buf->vb.vb2_buf,
-					VB2_BUF_STATE_QUEUED);
-		}
-	}
-	return err;
-}
-
-/* abort streaming and wait for last buffer */
-static void vbi_out_stop_streaming(struct vb2_queue *vq)
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vq);
-
-	dprintk(dev, 1, "%s\n", __func__);
-	vivid_stop_generating_vid_out(dev, &dev->vbi_out_streaming);
-	dev->vbi_out_have_wss = false;
-	dev->vbi_out_have_cc[0] = false;
-	dev->vbi_out_have_cc[1] = false;
-}
-
-static void vbi_out_buf_request_complete(struct vb2_buffer *vb)
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
-
-	v4l2_ctrl_request_complete(vb->req_obj.req, &dev->ctrl_hdl_vbi_out);
-}
-
-const struct vb2_ops vivid_vbi_out_qops = {
-	.queue_setup		= vbi_out_queue_setup,
-	.buf_prepare		= vbi_out_buf_prepare,
-	.buf_queue		= vbi_out_buf_queue,
-	.start_streaming	= vbi_out_start_streaming,
-	.stop_streaming		= vbi_out_stop_streaming,
-	.buf_request_complete	= vbi_out_buf_request_complete,
-	.wait_prepare		= vb2_ops_wait_prepare,
-	.wait_finish		= vb2_ops_wait_finish,
-};
-
-int vidioc_g_fmt_vbi_out(struct file *file, void *priv,
-					struct v4l2_format *f)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	struct v4l2_vbi_format *vbi = &f->fmt.vbi;
-	bool is_60hz = dev->std_out & V4L2_STD_525_60;
-
-	if (!vivid_is_svid_out(dev) || !dev->has_raw_vbi_out)
-		return -EINVAL;
-
-	vbi->sampling_rate = 25000000;
-	vbi->offset = 24;
-	vbi->samples_per_line = 1440;
-	vbi->sample_format = V4L2_PIX_FMT_GREY;
-	vbi->start[0] = is_60hz ? V4L2_VBI_ITU_525_F1_START + 9 : V4L2_VBI_ITU_625_F1_START + 5;
-	vbi->start[1] = is_60hz ? V4L2_VBI_ITU_525_F2_START + 9 : V4L2_VBI_ITU_625_F2_START + 5;
-	vbi->count[0] = vbi->count[1] = is_60hz ? 12 : 18;
-	vbi->flags = dev->vbi_cap_interlaced ? V4L2_VBI_INTERLACED : 0;
-	vbi->reserved[0] = 0;
-	vbi->reserved[1] = 0;
-	return 0;
-}
-
-int vidioc_s_fmt_vbi_out(struct file *file, void *priv,
-					struct v4l2_format *f)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	int ret = vidioc_g_fmt_vbi_out(file, priv, f);
-
-	if (ret)
-		return ret;
-	if (vb2_is_busy(&dev->vb_vbi_out_q))
-		return -EBUSY;
-	dev->stream_sliced_vbi_out = false;
-	dev->vbi_out_dev.queue->type = V4L2_BUF_TYPE_VBI_OUTPUT;
-	return 0;
-}
-
-int vidioc_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	struct v4l2_sliced_vbi_format *vbi = &fmt->fmt.sliced;
-
-	if (!vivid_is_svid_out(dev) || !dev->has_sliced_vbi_out)
-		return -EINVAL;
-
-	vivid_fill_service_lines(vbi, dev->service_set_out);
-	return 0;
-}
-
-int vidioc_try_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	struct v4l2_sliced_vbi_format *vbi = &fmt->fmt.sliced;
-	bool is_60hz = dev->std_out & V4L2_STD_525_60;
-	u32 service_set = vbi->service_set;
-
-	if (!vivid_is_svid_out(dev) || !dev->has_sliced_vbi_out)
-		return -EINVAL;
-
-	service_set &= is_60hz ? V4L2_SLICED_CAPTION_525 :
-				 V4L2_SLICED_WSS_625 | V4L2_SLICED_TELETEXT_B;
-	vivid_fill_service_lines(vbi, service_set);
-	return 0;
-}
-
-int vidioc_s_fmt_sliced_vbi_out(struct file *file, void *fh,
-		struct v4l2_format *fmt)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	struct v4l2_sliced_vbi_format *vbi = &fmt->fmt.sliced;
-	int ret = vidioc_try_fmt_sliced_vbi_out(file, fh, fmt);
-
-	if (ret)
-		return ret;
-	if (vb2_is_busy(&dev->vb_vbi_out_q))
-		return -EBUSY;
-	dev->service_set_out = vbi->service_set;
-	dev->stream_sliced_vbi_out = true;
-	dev->vbi_out_dev.queue->type = V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
-	return 0;
-}
-
-void vivid_sliced_vbi_out_process(struct vivid_dev *dev,
-		struct vivid_buffer *buf)
-{
-	struct v4l2_sliced_vbi_data *vbi =
-		vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
-	unsigned elems =
-		vb2_get_plane_payload(&buf->vb.vb2_buf, 0) / sizeof(*vbi);
-
-	dev->vbi_out_have_cc[0] = false;
-	dev->vbi_out_have_cc[1] = false;
-	dev->vbi_out_have_wss = false;
-	while (elems--) {
-		switch (vbi->id) {
-		case V4L2_SLICED_CAPTION_525:
-			if ((dev->std_out & V4L2_STD_525_60) && vbi->line == 21) {
-				dev->vbi_out_have_cc[!!vbi->field] = true;
-				dev->vbi_out_cc[!!vbi->field][0] = vbi->data[0];
-				dev->vbi_out_cc[!!vbi->field][1] = vbi->data[1];
-			}
-			break;
-		case V4L2_SLICED_WSS_625:
-			if ((dev->std_out & V4L2_STD_625_50) &&
-			    vbi->field == 0 && vbi->line == 23) {
-				dev->vbi_out_have_wss = true;
-				dev->vbi_out_wss[0] = vbi->data[0];
-				dev->vbi_out_wss[1] = vbi->data[1];
-			}
-			break;
-		}
-		vbi++;
-	}
-}
diff --git a/drivers/media/platform/vivid/vivid-vbi-out.h b/drivers/media/platform/vivid/vivid-vbi-out.h
deleted file mode 100644
index 76584940cdaf..000000000000
--- a/drivers/media/platform/vivid/vivid-vbi-out.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * vivid-vbi-out.h - vbi output support functions.
- *
- * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#ifndef _VIVID_VBI_OUT_H_
-#define _VIVID_VBI_OUT_H_
-
-void vivid_sliced_vbi_out_process(struct vivid_dev *dev, struct vivid_buffer *buf);
-int vidioc_g_fmt_vbi_out(struct file *file, void *priv,
-					struct v4l2_format *f);
-int vidioc_s_fmt_vbi_out(struct file *file, void *priv,
-					struct v4l2_format *f);
-int vidioc_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt);
-int vidioc_try_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt);
-int vidioc_s_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt);
-
-extern const struct vb2_ops vivid_vbi_out_qops;
-
-#endif
diff --git a/drivers/media/platform/vivid/vivid-vid-cap.c b/drivers/media/platform/vivid/vivid-vid-cap.c
deleted file mode 100644
index e94beef008c8..000000000000
--- a/drivers/media/platform/vivid/vivid-vid-cap.c
+++ /dev/null
@@ -1,1918 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * vivid-vid-cap.c - video capture support functions.
- *
- * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/vmalloc.h>
-#include <linux/videodev2.h>
-#include <linux/v4l2-dv-timings.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-event.h>
-#include <media/v4l2-dv-timings.h>
-#include <media/v4l2-rect.h>
-
-#include "vivid-core.h"
-#include "vivid-vid-common.h"
-#include "vivid-kthread-cap.h"
-#include "vivid-vid-cap.h"
-
-static const struct vivid_fmt formats_ovl[] = {
-	{
-		.fourcc   = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_XRGB555, /* gggbbbbb arrrrrgg */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_ARGB555, /* gggbbbbb arrrrrgg */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-};
-
-/* The number of discrete webcam framesizes */
-#define VIVID_WEBCAM_SIZES 6
-/* The number of discrete webcam frameintervals */
-#define VIVID_WEBCAM_IVALS (VIVID_WEBCAM_SIZES * 2)
-
-/* Sizes must be in increasing order */
-static const struct v4l2_frmsize_discrete webcam_sizes[VIVID_WEBCAM_SIZES] = {
-	{  320, 180 },
-	{  640, 360 },
-	{  640, 480 },
-	{ 1280, 720 },
-	{ 1920, 1080 },
-	{ 3840, 2160 },
-};
-
-/*
- * Intervals must be in increasing order and there must be twice as many
- * elements in this array as there are in webcam_sizes.
- */
-static const struct v4l2_fract webcam_intervals[VIVID_WEBCAM_IVALS] = {
-	{  1, 1 },
-	{  1, 2 },
-	{  1, 4 },
-	{  1, 5 },
-	{  1, 10 },
-	{  2, 25 },
-	{  1, 15 },
-	{  1, 25 },
-	{  1, 30 },
-	{  1, 40 },
-	{  1, 50 },
-	{  1, 60 },
-};
-
-static int vid_cap_queue_setup(struct vb2_queue *vq,
-		       unsigned *nbuffers, unsigned *nplanes,
-		       unsigned sizes[], struct device *alloc_devs[])
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vq);
-	unsigned buffers = tpg_g_buffers(&dev->tpg);
-	unsigned h = dev->fmt_cap_rect.height;
-	unsigned p;
-
-	if (dev->field_cap == V4L2_FIELD_ALTERNATE) {
-		/*
-		 * You cannot use read() with FIELD_ALTERNATE since the field
-		 * information (TOP/BOTTOM) cannot be passed back to the user.
-		 */
-		if (vb2_fileio_is_active(vq))
-			return -EINVAL;
-	}
-
-	if (dev->queue_setup_error) {
-		/*
-		 * Error injection: test what happens if queue_setup() returns
-		 * an error.
-		 */
-		dev->queue_setup_error = false;
-		return -EINVAL;
-	}
-	if (*nplanes) {
-		/*
-		 * Check if the number of requested planes match
-		 * the number of buffers in the current format. You can't mix that.
-		 */
-		if (*nplanes != buffers)
-			return -EINVAL;
-		for (p = 0; p < buffers; p++) {
-			if (sizes[p] < tpg_g_line_width(&dev->tpg, p) * h +
-						dev->fmt_cap->data_offset[p])
-				return -EINVAL;
-		}
-	} else {
-		for (p = 0; p < buffers; p++)
-			sizes[p] = (tpg_g_line_width(&dev->tpg, p) * h) /
-					dev->fmt_cap->vdownsampling[p] +
-					dev->fmt_cap->data_offset[p];
-	}
-
-	if (vq->num_buffers + *nbuffers < 2)
-		*nbuffers = 2 - vq->num_buffers;
-
-	*nplanes = buffers;
-
-	dprintk(dev, 1, "%s: count=%d\n", __func__, *nbuffers);
-	for (p = 0; p < buffers; p++)
-		dprintk(dev, 1, "%s: size[%u]=%u\n", __func__, p, sizes[p]);
-
-	return 0;
-}
-
-static int vid_cap_buf_prepare(struct vb2_buffer *vb)
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
-	unsigned long size;
-	unsigned buffers = tpg_g_buffers(&dev->tpg);
-	unsigned p;
-
-	dprintk(dev, 1, "%s\n", __func__);
-
-	if (WARN_ON(NULL == dev->fmt_cap))
-		return -EINVAL;
-
-	if (dev->buf_prepare_error) {
-		/*
-		 * Error injection: test what happens if buf_prepare() returns
-		 * an error.
-		 */
-		dev->buf_prepare_error = false;
-		return -EINVAL;
-	}
-	for (p = 0; p < buffers; p++) {
-		size = (tpg_g_line_width(&dev->tpg, p) *
-			dev->fmt_cap_rect.height) /
-			dev->fmt_cap->vdownsampling[p] +
-			dev->fmt_cap->data_offset[p];
-
-		if (vb2_plane_size(vb, p) < size) {
-			dprintk(dev, 1, "%s data will not fit into plane %u (%lu < %lu)\n",
-					__func__, p, vb2_plane_size(vb, p), size);
-			return -EINVAL;
-		}
-
-		vb2_set_plane_payload(vb, p, size);
-		vb->planes[p].data_offset = dev->fmt_cap->data_offset[p];
-	}
-
-	return 0;
-}
-
-static void vid_cap_buf_finish(struct vb2_buffer *vb)
-{
-	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
-	struct v4l2_timecode *tc = &vbuf->timecode;
-	unsigned fps = 25;
-	unsigned seq = vbuf->sequence;
-
-	if (!vivid_is_sdtv_cap(dev))
-		return;
-
-	/*
-	 * Set the timecode. Rarely used, so it is interesting to
-	 * test this.
-	 */
-	vbuf->flags |= V4L2_BUF_FLAG_TIMECODE;
-	if (dev->std_cap[dev->input] & V4L2_STD_525_60)
-		fps = 30;
-	tc->type = (fps == 30) ? V4L2_TC_TYPE_30FPS : V4L2_TC_TYPE_25FPS;
-	tc->flags = 0;
-	tc->frames = seq % fps;
-	tc->seconds = (seq / fps) % 60;
-	tc->minutes = (seq / (60 * fps)) % 60;
-	tc->hours = (seq / (60 * 60 * fps)) % 24;
-}
-
-static void vid_cap_buf_queue(struct vb2_buffer *vb)
-{
-	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
-	struct vivid_buffer *buf = container_of(vbuf, struct vivid_buffer, vb);
-
-	dprintk(dev, 1, "%s\n", __func__);
-
-	spin_lock(&dev->slock);
-	list_add_tail(&buf->list, &dev->vid_cap_active);
-	spin_unlock(&dev->slock);
-}
-
-static int vid_cap_start_streaming(struct vb2_queue *vq, unsigned count)
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vq);
-	unsigned i;
-	int err;
-
-	if (vb2_is_streaming(&dev->vb_vid_out_q))
-		dev->can_loop_video = vivid_vid_can_loop(dev);
-
-	dev->vid_cap_seq_count = 0;
-	dprintk(dev, 1, "%s\n", __func__);
-	for (i = 0; i < VIDEO_MAX_FRAME; i++)
-		dev->must_blank[i] = tpg_g_perc_fill(&dev->tpg) < 100;
-	if (dev->start_streaming_error) {
-		dev->start_streaming_error = false;
-		err = -EINVAL;
-	} else {
-		err = vivid_start_generating_vid_cap(dev, &dev->vid_cap_streaming);
-	}
-	if (err) {
-		struct vivid_buffer *buf, *tmp;
-
-		list_for_each_entry_safe(buf, tmp, &dev->vid_cap_active, list) {
-			list_del(&buf->list);
-			vb2_buffer_done(&buf->vb.vb2_buf,
-					VB2_BUF_STATE_QUEUED);
-		}
-	}
-	return err;
-}
-
-/* abort streaming and wait for last buffer */
-static void vid_cap_stop_streaming(struct vb2_queue *vq)
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vq);
-
-	dprintk(dev, 1, "%s\n", __func__);
-	vivid_stop_generating_vid_cap(dev, &dev->vid_cap_streaming);
-	dev->can_loop_video = false;
-}
-
-static void vid_cap_buf_request_complete(struct vb2_buffer *vb)
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
-
-	v4l2_ctrl_request_complete(vb->req_obj.req, &dev->ctrl_hdl_vid_cap);
-}
-
-const struct vb2_ops vivid_vid_cap_qops = {
-	.queue_setup		= vid_cap_queue_setup,
-	.buf_prepare		= vid_cap_buf_prepare,
-	.buf_finish		= vid_cap_buf_finish,
-	.buf_queue		= vid_cap_buf_queue,
-	.start_streaming	= vid_cap_start_streaming,
-	.stop_streaming		= vid_cap_stop_streaming,
-	.buf_request_complete	= vid_cap_buf_request_complete,
-	.wait_prepare		= vb2_ops_wait_prepare,
-	.wait_finish		= vb2_ops_wait_finish,
-};
-
-/*
- * Determine the 'picture' quality based on the current TV frequency: either
- * COLOR for a good 'signal', GRAY (grayscale picture) for a slightly off
- * signal or NOISE for no signal.
- */
-void vivid_update_quality(struct vivid_dev *dev)
-{
-	unsigned freq_modulus;
-
-	if (dev->loop_video && (vivid_is_svid_cap(dev) || vivid_is_hdmi_cap(dev))) {
-		/*
-		 * The 'noise' will only be replaced by the actual video
-		 * if the output video matches the input video settings.
-		 */
-		tpg_s_quality(&dev->tpg, TPG_QUAL_NOISE, 0);
-		return;
-	}
-	if (vivid_is_hdmi_cap(dev) &&
-	    VIVID_INVALID_SIGNAL(dev->dv_timings_signal_mode[dev->input])) {
-		tpg_s_quality(&dev->tpg, TPG_QUAL_NOISE, 0);
-		return;
-	}
-	if (vivid_is_sdtv_cap(dev) &&
-	    VIVID_INVALID_SIGNAL(dev->std_signal_mode[dev->input])) {
-		tpg_s_quality(&dev->tpg, TPG_QUAL_NOISE, 0);
-		return;
-	}
-	if (!vivid_is_tv_cap(dev)) {
-		tpg_s_quality(&dev->tpg, TPG_QUAL_COLOR, 0);
-		return;
-	}
-
-	/*
-	 * There is a fake channel every 6 MHz at 49.25, 55.25, etc.
-	 * From +/- 0.25 MHz around the channel there is color, and from
-	 * +/- 1 MHz there is grayscale (chroma is lost).
-	 * Everywhere else it is just noise.
-	 */
-	freq_modulus = (dev->tv_freq - 676 /* (43.25-1) * 16 */) % (6 * 16);
-	if (freq_modulus > 2 * 16) {
-		tpg_s_quality(&dev->tpg, TPG_QUAL_NOISE,
-			next_pseudo_random32(dev->tv_freq ^ 0x55) & 0x3f);
-		return;
-	}
-	if (freq_modulus < 12 /*0.75 * 16*/ || freq_modulus > 20 /*1.25 * 16*/)
-		tpg_s_quality(&dev->tpg, TPG_QUAL_GRAY, 0);
-	else
-		tpg_s_quality(&dev->tpg, TPG_QUAL_COLOR, 0);
-}
-
-/*
- * Get the current picture quality and the associated afc value.
- */
-static enum tpg_quality vivid_get_quality(struct vivid_dev *dev, s32 *afc)
-{
-	unsigned freq_modulus;
-
-	if (afc)
-		*afc = 0;
-	if (tpg_g_quality(&dev->tpg) == TPG_QUAL_COLOR ||
-	    tpg_g_quality(&dev->tpg) == TPG_QUAL_NOISE)
-		return tpg_g_quality(&dev->tpg);
-
-	/*
-	 * There is a fake channel every 6 MHz at 49.25, 55.25, etc.
-	 * From +/- 0.25 MHz around the channel there is color, and from
-	 * +/- 1 MHz there is grayscale (chroma is lost).
-	 * Everywhere else it is just gray.
-	 */
-	freq_modulus = (dev->tv_freq - 676 /* (43.25-1) * 16 */) % (6 * 16);
-	if (afc)
-		*afc = freq_modulus - 1 * 16;
-	return TPG_QUAL_GRAY;
-}
-
-enum tpg_video_aspect vivid_get_video_aspect(const struct vivid_dev *dev)
-{
-	if (vivid_is_sdtv_cap(dev))
-		return dev->std_aspect_ratio[dev->input];
-
-	if (vivid_is_hdmi_cap(dev))
-		return dev->dv_timings_aspect_ratio[dev->input];
-
-	return TPG_VIDEO_ASPECT_IMAGE;
-}
-
-static enum tpg_pixel_aspect vivid_get_pixel_aspect(const struct vivid_dev *dev)
-{
-	if (vivid_is_sdtv_cap(dev))
-		return (dev->std_cap[dev->input] & V4L2_STD_525_60) ?
-			TPG_PIXEL_ASPECT_NTSC : TPG_PIXEL_ASPECT_PAL;
-
-	if (vivid_is_hdmi_cap(dev) &&
-	    dev->src_rect.width == 720 && dev->src_rect.height <= 576)
-		return dev->src_rect.height == 480 ?
-			TPG_PIXEL_ASPECT_NTSC : TPG_PIXEL_ASPECT_PAL;
-
-	return TPG_PIXEL_ASPECT_SQUARE;
-}
-
-/*
- * Called whenever the format has to be reset which can occur when
- * changing inputs, standard, timings, etc.
- */
-void vivid_update_format_cap(struct vivid_dev *dev, bool keep_controls)
-{
-	struct v4l2_bt_timings *bt = &dev->dv_timings_cap[dev->input].bt;
-	unsigned size;
-	u64 pixelclock;
-
-	switch (dev->input_type[dev->input]) {
-	case WEBCAM:
-	default:
-		dev->src_rect.width = webcam_sizes[dev->webcam_size_idx].width;
-		dev->src_rect.height = webcam_sizes[dev->webcam_size_idx].height;
-		dev->timeperframe_vid_cap = webcam_intervals[dev->webcam_ival_idx];
-		dev->field_cap = V4L2_FIELD_NONE;
-		tpg_s_rgb_range(&dev->tpg, V4L2_DV_RGB_RANGE_AUTO);
-		break;
-	case TV:
-	case SVID:
-		dev->field_cap = dev->tv_field_cap;
-		dev->src_rect.width = 720;
-		if (dev->std_cap[dev->input] & V4L2_STD_525_60) {
-			dev->src_rect.height = 480;
-			dev->timeperframe_vid_cap = (struct v4l2_fract) { 1001, 30000 };
-			dev->service_set_cap = V4L2_SLICED_CAPTION_525;
-		} else {
-			dev->src_rect.height = 576;
-			dev->timeperframe_vid_cap = (struct v4l2_fract) { 1000, 25000 };
-			dev->service_set_cap = V4L2_SLICED_WSS_625 | V4L2_SLICED_TELETEXT_B;
-		}
-		tpg_s_rgb_range(&dev->tpg, V4L2_DV_RGB_RANGE_AUTO);
-		break;
-	case HDMI:
-		dev->src_rect.width = bt->width;
-		dev->src_rect.height = bt->height;
-		size = V4L2_DV_BT_FRAME_WIDTH(bt) * V4L2_DV_BT_FRAME_HEIGHT(bt);
-		if (dev->reduced_fps && can_reduce_fps(bt)) {
-			pixelclock = div_u64(bt->pixelclock * 1000, 1001);
-			bt->flags |= V4L2_DV_FL_REDUCED_FPS;
-		} else {
-			pixelclock = bt->pixelclock;
-			bt->flags &= ~V4L2_DV_FL_REDUCED_FPS;
-		}
-		dev->timeperframe_vid_cap = (struct v4l2_fract) {
-			size / 100, (u32)pixelclock / 100
-		};
-		if (bt->interlaced)
-			dev->field_cap = V4L2_FIELD_ALTERNATE;
-		else
-			dev->field_cap = V4L2_FIELD_NONE;
-
-		/*
-		 * We can be called from within s_ctrl, in that case we can't
-		 * set/get controls. Luckily we don't need to in that case.
-		 */
-		if (keep_controls || !dev->colorspace)
-			break;
-		if (bt->flags & V4L2_DV_FL_IS_CE_VIDEO) {
-			if (bt->width == 720 && bt->height <= 576)
-				v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_170M);
-			else
-				v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_709);
-			v4l2_ctrl_s_ctrl(dev->real_rgb_range_cap, 1);
-		} else {
-			v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_SRGB);
-			v4l2_ctrl_s_ctrl(dev->real_rgb_range_cap, 0);
-		}
-		tpg_s_rgb_range(&dev->tpg, v4l2_ctrl_g_ctrl(dev->rgb_range_cap));
-		break;
-	}
-	vfree(dev->bitmap_cap);
-	dev->bitmap_cap = NULL;
-	vivid_update_quality(dev);
-	tpg_reset_source(&dev->tpg, dev->src_rect.width, dev->src_rect.height, dev->field_cap);
-	dev->crop_cap = dev->src_rect;
-	dev->crop_bounds_cap = dev->src_rect;
-	dev->compose_cap = dev->crop_cap;
-	if (V4L2_FIELD_HAS_T_OR_B(dev->field_cap))
-		dev->compose_cap.height /= 2;
-	dev->fmt_cap_rect = dev->compose_cap;
-	tpg_s_video_aspect(&dev->tpg, vivid_get_video_aspect(dev));
-	tpg_s_pixel_aspect(&dev->tpg, vivid_get_pixel_aspect(dev));
-	tpg_update_mv_step(&dev->tpg);
-}
-
-/* Map the field to something that is valid for the current input */
-static enum v4l2_field vivid_field_cap(struct vivid_dev *dev, enum v4l2_field field)
-{
-	if (vivid_is_sdtv_cap(dev)) {
-		switch (field) {
-		case V4L2_FIELD_INTERLACED_TB:
-		case V4L2_FIELD_INTERLACED_BT:
-		case V4L2_FIELD_SEQ_TB:
-		case V4L2_FIELD_SEQ_BT:
-		case V4L2_FIELD_TOP:
-		case V4L2_FIELD_BOTTOM:
-		case V4L2_FIELD_ALTERNATE:
-			return field;
-		case V4L2_FIELD_INTERLACED:
-		default:
-			return V4L2_FIELD_INTERLACED;
-		}
-	}
-	if (vivid_is_hdmi_cap(dev))
-		return dev->dv_timings_cap[dev->input].bt.interlaced ?
-			V4L2_FIELD_ALTERNATE : V4L2_FIELD_NONE;
-	return V4L2_FIELD_NONE;
-}
-
-static unsigned vivid_colorspace_cap(struct vivid_dev *dev)
-{
-	if (!dev->loop_video || vivid_is_webcam(dev) || vivid_is_tv_cap(dev))
-		return tpg_g_colorspace(&dev->tpg);
-	return dev->colorspace_out;
-}
-
-static unsigned vivid_xfer_func_cap(struct vivid_dev *dev)
-{
-	if (!dev->loop_video || vivid_is_webcam(dev) || vivid_is_tv_cap(dev))
-		return tpg_g_xfer_func(&dev->tpg);
-	return dev->xfer_func_out;
-}
-
-static unsigned vivid_ycbcr_enc_cap(struct vivid_dev *dev)
-{
-	if (!dev->loop_video || vivid_is_webcam(dev) || vivid_is_tv_cap(dev))
-		return tpg_g_ycbcr_enc(&dev->tpg);
-	return dev->ycbcr_enc_out;
-}
-
-static unsigned int vivid_hsv_enc_cap(struct vivid_dev *dev)
-{
-	if (!dev->loop_video || vivid_is_webcam(dev) || vivid_is_tv_cap(dev))
-		return tpg_g_hsv_enc(&dev->tpg);
-	return dev->hsv_enc_out;
-}
-
-static unsigned vivid_quantization_cap(struct vivid_dev *dev)
-{
-	if (!dev->loop_video || vivid_is_webcam(dev) || vivid_is_tv_cap(dev))
-		return tpg_g_quantization(&dev->tpg);
-	return dev->quantization_out;
-}
-
-int vivid_g_fmt_vid_cap(struct file *file, void *priv,
-					struct v4l2_format *f)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	struct v4l2_pix_format_mplane *mp = &f->fmt.pix_mp;
-	unsigned p;
-
-	mp->width        = dev->fmt_cap_rect.width;
-	mp->height       = dev->fmt_cap_rect.height;
-	mp->field        = dev->field_cap;
-	mp->pixelformat  = dev->fmt_cap->fourcc;
-	mp->colorspace   = vivid_colorspace_cap(dev);
-	mp->xfer_func    = vivid_xfer_func_cap(dev);
-	if (dev->fmt_cap->color_enc == TGP_COLOR_ENC_HSV)
-		mp->hsv_enc    = vivid_hsv_enc_cap(dev);
-	else
-		mp->ycbcr_enc    = vivid_ycbcr_enc_cap(dev);
-	mp->quantization = vivid_quantization_cap(dev);
-	mp->num_planes = dev->fmt_cap->buffers;
-	for (p = 0; p < mp->num_planes; p++) {
-		mp->plane_fmt[p].bytesperline = tpg_g_bytesperline(&dev->tpg, p);
-		mp->plane_fmt[p].sizeimage =
-			(tpg_g_line_width(&dev->tpg, p) * mp->height) /
-			dev->fmt_cap->vdownsampling[p] +
-			dev->fmt_cap->data_offset[p];
-	}
-	return 0;
-}
-
-int vivid_try_fmt_vid_cap(struct file *file, void *priv,
-			struct v4l2_format *f)
-{
-	struct v4l2_pix_format_mplane *mp = &f->fmt.pix_mp;
-	struct v4l2_plane_pix_format *pfmt = mp->plane_fmt;
-	struct vivid_dev *dev = video_drvdata(file);
-	const struct vivid_fmt *fmt;
-	unsigned bytesperline, max_bpl;
-	unsigned factor = 1;
-	unsigned w, h;
-	unsigned p;
-
-	fmt = vivid_get_format(dev, mp->pixelformat);
-	if (!fmt) {
-		dprintk(dev, 1, "Fourcc format (0x%08x) unknown.\n",
-			mp->pixelformat);
-		mp->pixelformat = V4L2_PIX_FMT_YUYV;
-		fmt = vivid_get_format(dev, mp->pixelformat);
-	}
-
-	mp->field = vivid_field_cap(dev, mp->field);
-	if (vivid_is_webcam(dev)) {
-		const struct v4l2_frmsize_discrete *sz =
-			v4l2_find_nearest_size(webcam_sizes,
-					       VIVID_WEBCAM_SIZES, width,
-					       height, mp->width, mp->height);
-
-		w = sz->width;
-		h = sz->height;
-	} else if (vivid_is_sdtv_cap(dev)) {
-		w = 720;
-		h = (dev->std_cap[dev->input] & V4L2_STD_525_60) ? 480 : 576;
-	} else {
-		w = dev->src_rect.width;
-		h = dev->src_rect.height;
-	}
-	if (V4L2_FIELD_HAS_T_OR_B(mp->field))
-		factor = 2;
-	if (vivid_is_webcam(dev) ||
-	    (!dev->has_scaler_cap && !dev->has_crop_cap && !dev->has_compose_cap)) {
-		mp->width = w;
-		mp->height = h / factor;
-	} else {
-		struct v4l2_rect r = { 0, 0, mp->width, mp->height * factor };
-
-		v4l2_rect_set_min_size(&r, &vivid_min_rect);
-		v4l2_rect_set_max_size(&r, &vivid_max_rect);
-		if (dev->has_scaler_cap && !dev->has_compose_cap) {
-			struct v4l2_rect max_r = { 0, 0, MAX_ZOOM * w, MAX_ZOOM * h };
-
-			v4l2_rect_set_max_size(&r, &max_r);
-		} else if (!dev->has_scaler_cap && dev->has_crop_cap && !dev->has_compose_cap) {
-			v4l2_rect_set_max_size(&r, &dev->src_rect);
-		} else if (!dev->has_scaler_cap && !dev->has_crop_cap) {
-			v4l2_rect_set_min_size(&r, &dev->src_rect);
-		}
-		mp->width = r.width;
-		mp->height = r.height / factor;
-	}
-
-	/* This driver supports custom bytesperline values */
-
-	mp->num_planes = fmt->buffers;
-	for (p = 0; p < fmt->buffers; p++) {
-		/* Calculate the minimum supported bytesperline value */
-		bytesperline = (mp->width * fmt->bit_depth[p]) >> 3;
-		/* Calculate the maximum supported bytesperline value */
-		max_bpl = (MAX_ZOOM * MAX_WIDTH * fmt->bit_depth[p]) >> 3;
-
-		if (pfmt[p].bytesperline > max_bpl)
-			pfmt[p].bytesperline = max_bpl;
-		if (pfmt[p].bytesperline < bytesperline)
-			pfmt[p].bytesperline = bytesperline;
-
-		pfmt[p].sizeimage = (pfmt[p].bytesperline * mp->height) /
-				fmt->vdownsampling[p] + fmt->data_offset[p];
-
-		memset(pfmt[p].reserved, 0, sizeof(pfmt[p].reserved));
-	}
-	for (p = fmt->buffers; p < fmt->planes; p++)
-		pfmt[0].sizeimage += (pfmt[0].bytesperline * mp->height *
-			(fmt->bit_depth[p] / fmt->vdownsampling[p])) /
-			(fmt->bit_depth[0] / fmt->vdownsampling[0]);
-
-	mp->colorspace = vivid_colorspace_cap(dev);
-	if (fmt->color_enc == TGP_COLOR_ENC_HSV)
-		mp->hsv_enc = vivid_hsv_enc_cap(dev);
-	else
-		mp->ycbcr_enc = vivid_ycbcr_enc_cap(dev);
-	mp->xfer_func = vivid_xfer_func_cap(dev);
-	mp->quantization = vivid_quantization_cap(dev);
-	memset(mp->reserved, 0, sizeof(mp->reserved));
-	return 0;
-}
-
-int vivid_s_fmt_vid_cap(struct file *file, void *priv,
-					struct v4l2_format *f)
-{
-	struct v4l2_pix_format_mplane *mp = &f->fmt.pix_mp;
-	struct vivid_dev *dev = video_drvdata(file);
-	struct v4l2_rect *crop = &dev->crop_cap;
-	struct v4l2_rect *compose = &dev->compose_cap;
-	struct vb2_queue *q = &dev->vb_vid_cap_q;
-	int ret = vivid_try_fmt_vid_cap(file, priv, f);
-	unsigned factor = 1;
-	unsigned p;
-	unsigned i;
-
-	if (ret < 0)
-		return ret;
-
-	if (vb2_is_busy(q)) {
-		dprintk(dev, 1, "%s device busy\n", __func__);
-		return -EBUSY;
-	}
-
-	if (dev->overlay_cap_owner && dev->fb_cap.fmt.pixelformat != mp->pixelformat) {
-		dprintk(dev, 1, "overlay is active, can't change pixelformat\n");
-		return -EBUSY;
-	}
-
-	dev->fmt_cap = vivid_get_format(dev, mp->pixelformat);
-	if (V4L2_FIELD_HAS_T_OR_B(mp->field))
-		factor = 2;
-
-	/* Note: the webcam input doesn't support scaling, cropping or composing */
-
-	if (!vivid_is_webcam(dev) &&
-	    (dev->has_scaler_cap || dev->has_crop_cap || dev->has_compose_cap)) {
-		struct v4l2_rect r = { 0, 0, mp->width, mp->height };
-
-		if (dev->has_scaler_cap) {
-			if (dev->has_compose_cap)
-				v4l2_rect_map_inside(compose, &r);
-			else
-				*compose = r;
-			if (dev->has_crop_cap && !dev->has_compose_cap) {
-				struct v4l2_rect min_r = {
-					0, 0,
-					r.width / MAX_ZOOM,
-					factor * r.height / MAX_ZOOM
-				};
-				struct v4l2_rect max_r = {
-					0, 0,
-					r.width * MAX_ZOOM,
-					factor * r.height * MAX_ZOOM
-				};
-
-				v4l2_rect_set_min_size(crop, &min_r);
-				v4l2_rect_set_max_size(crop, &max_r);
-				v4l2_rect_map_inside(crop, &dev->crop_bounds_cap);
-			} else if (dev->has_crop_cap) {
-				struct v4l2_rect min_r = {
-					0, 0,
-					compose->width / MAX_ZOOM,
-					factor * compose->height / MAX_ZOOM
-				};
-				struct v4l2_rect max_r = {
-					0, 0,
-					compose->width * MAX_ZOOM,
-					factor * compose->height * MAX_ZOOM
-				};
-
-				v4l2_rect_set_min_size(crop, &min_r);
-				v4l2_rect_set_max_size(crop, &max_r);
-				v4l2_rect_map_inside(crop, &dev->crop_bounds_cap);
-			}
-		} else if (dev->has_crop_cap && !dev->has_compose_cap) {
-			r.height *= factor;
-			v4l2_rect_set_size_to(crop, &r);
-			v4l2_rect_map_inside(crop, &dev->crop_bounds_cap);
-			r = *crop;
-			r.height /= factor;
-			v4l2_rect_set_size_to(compose, &r);
-		} else if (!dev->has_crop_cap) {
-			v4l2_rect_map_inside(compose, &r);
-		} else {
-			r.height *= factor;
-			v4l2_rect_set_max_size(crop, &r);
-			v4l2_rect_map_inside(crop, &dev->crop_bounds_cap);
-			compose->top *= factor;
-			compose->height *= factor;
-			v4l2_rect_set_size_to(compose, crop);
-			v4l2_rect_map_inside(compose, &r);
-			compose->top /= factor;
-			compose->height /= factor;
-		}
-	} else if (vivid_is_webcam(dev)) {
-		/* Guaranteed to be a match */
-		for (i = 0; i < ARRAY_SIZE(webcam_sizes); i++)
-			if (webcam_sizes[i].width == mp->width &&
-					webcam_sizes[i].height == mp->height)
-				break;
-		dev->webcam_size_idx = i;
-		if (dev->webcam_ival_idx >= 2 * (VIVID_WEBCAM_SIZES - i))
-			dev->webcam_ival_idx = 2 * (VIVID_WEBCAM_SIZES - i) - 1;
-		vivid_update_format_cap(dev, false);
-	} else {
-		struct v4l2_rect r = { 0, 0, mp->width, mp->height };
-
-		v4l2_rect_set_size_to(compose, &r);
-		r.height *= factor;
-		v4l2_rect_set_size_to(crop, &r);
-	}
-
-	dev->fmt_cap_rect.width = mp->width;
-	dev->fmt_cap_rect.height = mp->height;
-	tpg_s_buf_height(&dev->tpg, mp->height);
-	tpg_s_fourcc(&dev->tpg, dev->fmt_cap->fourcc);
-	for (p = 0; p < tpg_g_buffers(&dev->tpg); p++)
-		tpg_s_bytesperline(&dev->tpg, p, mp->plane_fmt[p].bytesperline);
-	dev->field_cap = mp->field;
-	if (dev->field_cap == V4L2_FIELD_ALTERNATE)
-		tpg_s_field(&dev->tpg, V4L2_FIELD_TOP, true);
-	else
-		tpg_s_field(&dev->tpg, dev->field_cap, false);
-	tpg_s_crop_compose(&dev->tpg, &dev->crop_cap, &dev->compose_cap);
-	if (vivid_is_sdtv_cap(dev))
-		dev->tv_field_cap = mp->field;
-	tpg_update_mv_step(&dev->tpg);
-	return 0;
-}
-
-int vidioc_g_fmt_vid_cap_mplane(struct file *file, void *priv,
-					struct v4l2_format *f)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (!dev->multiplanar)
-		return -ENOTTY;
-	return vivid_g_fmt_vid_cap(file, priv, f);
-}
-
-int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv,
-			struct v4l2_format *f)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (!dev->multiplanar)
-		return -ENOTTY;
-	return vivid_try_fmt_vid_cap(file, priv, f);
-}
-
-int vidioc_s_fmt_vid_cap_mplane(struct file *file, void *priv,
-			struct v4l2_format *f)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (!dev->multiplanar)
-		return -ENOTTY;
-	return vivid_s_fmt_vid_cap(file, priv, f);
-}
-
-int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
-					struct v4l2_format *f)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (dev->multiplanar)
-		return -ENOTTY;
-	return fmt_sp2mp_func(file, priv, f, vivid_g_fmt_vid_cap);
-}
-
-int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
-			struct v4l2_format *f)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (dev->multiplanar)
-		return -ENOTTY;
-	return fmt_sp2mp_func(file, priv, f, vivid_try_fmt_vid_cap);
-}
-
-int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
-			struct v4l2_format *f)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (dev->multiplanar)
-		return -ENOTTY;
-	return fmt_sp2mp_func(file, priv, f, vivid_s_fmt_vid_cap);
-}
-
-int vivid_vid_cap_g_selection(struct file *file, void *priv,
-			      struct v4l2_selection *sel)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (!dev->has_crop_cap && !dev->has_compose_cap)
-		return -ENOTTY;
-	if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return -EINVAL;
-	if (vivid_is_webcam(dev))
-		return -ENODATA;
-
-	sel->r.left = sel->r.top = 0;
-	switch (sel->target) {
-	case V4L2_SEL_TGT_CROP:
-		if (!dev->has_crop_cap)
-			return -EINVAL;
-		sel->r = dev->crop_cap;
-		break;
-	case V4L2_SEL_TGT_CROP_DEFAULT:
-	case V4L2_SEL_TGT_CROP_BOUNDS:
-		if (!dev->has_crop_cap)
-			return -EINVAL;
-		sel->r = dev->src_rect;
-		break;
-	case V4L2_SEL_TGT_COMPOSE_BOUNDS:
-		if (!dev->has_compose_cap)
-			return -EINVAL;
-		sel->r = vivid_max_rect;
-		break;
-	case V4L2_SEL_TGT_COMPOSE:
-		if (!dev->has_compose_cap)
-			return -EINVAL;
-		sel->r = dev->compose_cap;
-		break;
-	case V4L2_SEL_TGT_COMPOSE_DEFAULT:
-		if (!dev->has_compose_cap)
-			return -EINVAL;
-		sel->r = dev->fmt_cap_rect;
-		break;
-	default:
-		return -EINVAL;
-	}
-	return 0;
-}
-
-int vivid_vid_cap_s_selection(struct file *file, void *fh, struct v4l2_selection *s)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	struct v4l2_rect *crop = &dev->crop_cap;
-	struct v4l2_rect *compose = &dev->compose_cap;
-	unsigned factor = V4L2_FIELD_HAS_T_OR_B(dev->field_cap) ? 2 : 1;
-	int ret;
-
-	if (!dev->has_crop_cap && !dev->has_compose_cap)
-		return -ENOTTY;
-	if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return -EINVAL;
-	if (vivid_is_webcam(dev))
-		return -ENODATA;
-
-	switch (s->target) {
-	case V4L2_SEL_TGT_CROP:
-		if (!dev->has_crop_cap)
-			return -EINVAL;
-		ret = vivid_vid_adjust_sel(s->flags, &s->r);
-		if (ret)
-			return ret;
-		v4l2_rect_set_min_size(&s->r, &vivid_min_rect);
-		v4l2_rect_set_max_size(&s->r, &dev->src_rect);
-		v4l2_rect_map_inside(&s->r, &dev->crop_bounds_cap);
-		s->r.top /= factor;
-		s->r.height /= factor;
-		if (dev->has_scaler_cap) {
-			struct v4l2_rect fmt = dev->fmt_cap_rect;
-			struct v4l2_rect max_rect = {
-				0, 0,
-				s->r.width * MAX_ZOOM,
-				s->r.height * MAX_ZOOM
-			};
-			struct v4l2_rect min_rect = {
-				0, 0,
-				s->r.width / MAX_ZOOM,
-				s->r.height / MAX_ZOOM
-			};
-
-			v4l2_rect_set_min_size(&fmt, &min_rect);
-			if (!dev->has_compose_cap)
-				v4l2_rect_set_max_size(&fmt, &max_rect);
-			if (!v4l2_rect_same_size(&dev->fmt_cap_rect, &fmt) &&
-			    vb2_is_busy(&dev->vb_vid_cap_q))
-				return -EBUSY;
-			if (dev->has_compose_cap) {
-				v4l2_rect_set_min_size(compose, &min_rect);
-				v4l2_rect_set_max_size(compose, &max_rect);
-			}
-			dev->fmt_cap_rect = fmt;
-			tpg_s_buf_height(&dev->tpg, fmt.height);
-		} else if (dev->has_compose_cap) {
-			struct v4l2_rect fmt = dev->fmt_cap_rect;
-
-			v4l2_rect_set_min_size(&fmt, &s->r);
-			if (!v4l2_rect_same_size(&dev->fmt_cap_rect, &fmt) &&
-			    vb2_is_busy(&dev->vb_vid_cap_q))
-				return -EBUSY;
-			dev->fmt_cap_rect = fmt;
-			tpg_s_buf_height(&dev->tpg, fmt.height);
-			v4l2_rect_set_size_to(compose, &s->r);
-			v4l2_rect_map_inside(compose, &dev->fmt_cap_rect);
-		} else {
-			if (!v4l2_rect_same_size(&s->r, &dev->fmt_cap_rect) &&
-			    vb2_is_busy(&dev->vb_vid_cap_q))
-				return -EBUSY;
-			v4l2_rect_set_size_to(&dev->fmt_cap_rect, &s->r);
-			v4l2_rect_set_size_to(compose, &s->r);
-			v4l2_rect_map_inside(compose, &dev->fmt_cap_rect);
-			tpg_s_buf_height(&dev->tpg, dev->fmt_cap_rect.height);
-		}
-		s->r.top *= factor;
-		s->r.height *= factor;
-		*crop = s->r;
-		break;
-	case V4L2_SEL_TGT_COMPOSE:
-		if (!dev->has_compose_cap)
-			return -EINVAL;
-		ret = vivid_vid_adjust_sel(s->flags, &s->r);
-		if (ret)
-			return ret;
-		v4l2_rect_set_min_size(&s->r, &vivid_min_rect);
-		v4l2_rect_set_max_size(&s->r, &dev->fmt_cap_rect);
-		if (dev->has_scaler_cap) {
-			struct v4l2_rect max_rect = {
-				0, 0,
-				dev->src_rect.width * MAX_ZOOM,
-				(dev->src_rect.height / factor) * MAX_ZOOM
-			};
-
-			v4l2_rect_set_max_size(&s->r, &max_rect);
-			if (dev->has_crop_cap) {
-				struct v4l2_rect min_rect = {
-					0, 0,
-					s->r.width / MAX_ZOOM,
-					(s->r.height * factor) / MAX_ZOOM
-				};
-				struct v4l2_rect max_rect = {
-					0, 0,
-					s->r.width * MAX_ZOOM,
-					(s->r.height * factor) * MAX_ZOOM
-				};
-
-				v4l2_rect_set_min_size(crop, &min_rect);
-				v4l2_rect_set_max_size(crop, &max_rect);
-				v4l2_rect_map_inside(crop, &dev->crop_bounds_cap);
-			}
-		} else if (dev->has_crop_cap) {
-			s->r.top *= factor;
-			s->r.height *= factor;
-			v4l2_rect_set_max_size(&s->r, &dev->src_rect);
-			v4l2_rect_set_size_to(crop, &s->r);
-			v4l2_rect_map_inside(crop, &dev->crop_bounds_cap);
-			s->r.top /= factor;
-			s->r.height /= factor;
-		} else {
-			v4l2_rect_set_size_to(&s->r, &dev->src_rect);
-			s->r.height /= factor;
-		}
-		v4l2_rect_map_inside(&s->r, &dev->fmt_cap_rect);
-		if (dev->bitmap_cap && (compose->width != s->r.width ||
-					compose->height != s->r.height)) {
-			vfree(dev->bitmap_cap);
-			dev->bitmap_cap = NULL;
-		}
-		*compose = s->r;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	tpg_s_crop_compose(&dev->tpg, crop, compose);
-	return 0;
-}
-
-int vivid_vid_cap_g_pixelaspect(struct file *file, void *priv,
-				int type, struct v4l2_fract *f)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return -EINVAL;
-
-	switch (vivid_get_pixel_aspect(dev)) {
-	case TPG_PIXEL_ASPECT_NTSC:
-		f->numerator = 11;
-		f->denominator = 10;
-		break;
-	case TPG_PIXEL_ASPECT_PAL:
-		f->numerator = 54;
-		f->denominator = 59;
-		break;
-	default:
-		break;
-	}
-	return 0;
-}
-
-int vidioc_enum_fmt_vid_overlay(struct file *file, void  *priv,
-					struct v4l2_fmtdesc *f)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	const struct vivid_fmt *fmt;
-
-	if (dev->multiplanar)
-		return -ENOTTY;
-
-	if (f->index >= ARRAY_SIZE(formats_ovl))
-		return -EINVAL;
-
-	fmt = &formats_ovl[f->index];
-
-	f->pixelformat = fmt->fourcc;
-	return 0;
-}
-
-int vidioc_g_fmt_vid_overlay(struct file *file, void *priv,
-					struct v4l2_format *f)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	const struct v4l2_rect *compose = &dev->compose_cap;
-	struct v4l2_window *win = &f->fmt.win;
-	unsigned clipcount = win->clipcount;
-
-	if (dev->multiplanar)
-		return -ENOTTY;
-
-	win->w.top = dev->overlay_cap_top;
-	win->w.left = dev->overlay_cap_left;
-	win->w.width = compose->width;
-	win->w.height = compose->height;
-	win->field = dev->overlay_cap_field;
-	win->clipcount = dev->clipcount_cap;
-	if (clipcount > dev->clipcount_cap)
-		clipcount = dev->clipcount_cap;
-	if (dev->bitmap_cap == NULL)
-		win->bitmap = NULL;
-	else if (win->bitmap) {
-		if (copy_to_user(win->bitmap, dev->bitmap_cap,
-		    ((compose->width + 7) / 8) * compose->height))
-			return -EFAULT;
-	}
-	if (clipcount && win->clips) {
-		if (copy_to_user(win->clips, dev->clips_cap,
-				 clipcount * sizeof(dev->clips_cap[0])))
-			return -EFAULT;
-	}
-	return 0;
-}
-
-int vidioc_try_fmt_vid_overlay(struct file *file, void *priv,
-					struct v4l2_format *f)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	const struct v4l2_rect *compose = &dev->compose_cap;
-	struct v4l2_window *win = &f->fmt.win;
-	int i, j;
-
-	if (dev->multiplanar)
-		return -ENOTTY;
-
-	win->w.left = clamp_t(int, win->w.left,
-			      -dev->fb_cap.fmt.width, dev->fb_cap.fmt.width);
-	win->w.top = clamp_t(int, win->w.top,
-			     -dev->fb_cap.fmt.height, dev->fb_cap.fmt.height);
-	win->w.width = compose->width;
-	win->w.height = compose->height;
-	if (win->field != V4L2_FIELD_BOTTOM && win->field != V4L2_FIELD_TOP)
-		win->field = V4L2_FIELD_ANY;
-	win->chromakey = 0;
-	win->global_alpha = 0;
-	if (win->clipcount && !win->clips)
-		win->clipcount = 0;
-	if (win->clipcount > MAX_CLIPS)
-		win->clipcount = MAX_CLIPS;
-	if (win->clipcount) {
-		if (copy_from_user(dev->try_clips_cap, win->clips,
-				   win->clipcount * sizeof(dev->clips_cap[0])))
-			return -EFAULT;
-		for (i = 0; i < win->clipcount; i++) {
-			struct v4l2_rect *r = &dev->try_clips_cap[i].c;
-
-			r->top = clamp_t(s32, r->top, 0, dev->fb_cap.fmt.height - 1);
-			r->height = clamp_t(s32, r->height, 1, dev->fb_cap.fmt.height - r->top);
-			r->left = clamp_t(u32, r->left, 0, dev->fb_cap.fmt.width - 1);
-			r->width = clamp_t(u32, r->width, 1, dev->fb_cap.fmt.width - r->left);
-		}
-		/*
-		 * Yeah, so sue me, it's an O(n^2) algorithm. But n is a small
-		 * number and it's typically a one-time deal.
-		 */
-		for (i = 0; i < win->clipcount - 1; i++) {
-			struct v4l2_rect *r1 = &dev->try_clips_cap[i].c;
-
-			for (j = i + 1; j < win->clipcount; j++) {
-				struct v4l2_rect *r2 = &dev->try_clips_cap[j].c;
-
-				if (v4l2_rect_overlap(r1, r2))
-					return -EINVAL;
-			}
-		}
-		if (copy_to_user(win->clips, dev->try_clips_cap,
-				 win->clipcount * sizeof(dev->clips_cap[0])))
-			return -EFAULT;
-	}
-	return 0;
-}
-
-int vidioc_s_fmt_vid_overlay(struct file *file, void *priv,
-					struct v4l2_format *f)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	const struct v4l2_rect *compose = &dev->compose_cap;
-	struct v4l2_window *win = &f->fmt.win;
-	int ret = vidioc_try_fmt_vid_overlay(file, priv, f);
-	unsigned bitmap_size = ((compose->width + 7) / 8) * compose->height;
-	unsigned clips_size = win->clipcount * sizeof(dev->clips_cap[0]);
-	void *new_bitmap = NULL;
-
-	if (ret)
-		return ret;
-
-	if (win->bitmap) {
-		new_bitmap = vzalloc(bitmap_size);
-
-		if (new_bitmap == NULL)
-			return -ENOMEM;
-		if (copy_from_user(new_bitmap, win->bitmap, bitmap_size)) {
-			vfree(new_bitmap);
-			return -EFAULT;
-		}
-	}
-
-	dev->overlay_cap_top = win->w.top;
-	dev->overlay_cap_left = win->w.left;
-	dev->overlay_cap_field = win->field;
-	vfree(dev->bitmap_cap);
-	dev->bitmap_cap = new_bitmap;
-	dev->clipcount_cap = win->clipcount;
-	if (dev->clipcount_cap)
-		memcpy(dev->clips_cap, dev->try_clips_cap, clips_size);
-	return 0;
-}
-
-int vivid_vid_cap_overlay(struct file *file, void *fh, unsigned i)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (dev->multiplanar)
-		return -ENOTTY;
-
-	if (i && dev->fb_vbase_cap == NULL)
-		return -EINVAL;
-
-	if (i && dev->fb_cap.fmt.pixelformat != dev->fmt_cap->fourcc) {
-		dprintk(dev, 1, "mismatch between overlay and video capture pixelformats\n");
-		return -EINVAL;
-	}
-
-	if (dev->overlay_cap_owner && dev->overlay_cap_owner != fh)
-		return -EBUSY;
-	dev->overlay_cap_owner = i ? fh : NULL;
-	return 0;
-}
-
-int vivid_vid_cap_g_fbuf(struct file *file, void *fh,
-				struct v4l2_framebuffer *a)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (dev->multiplanar)
-		return -ENOTTY;
-
-	*a = dev->fb_cap;
-	a->capability = V4L2_FBUF_CAP_BITMAP_CLIPPING |
-			V4L2_FBUF_CAP_LIST_CLIPPING;
-	a->flags = V4L2_FBUF_FLAG_PRIMARY;
-	a->fmt.field = V4L2_FIELD_NONE;
-	a->fmt.colorspace = V4L2_COLORSPACE_SRGB;
-	a->fmt.priv = 0;
-	return 0;
-}
-
-int vivid_vid_cap_s_fbuf(struct file *file, void *fh,
-				const struct v4l2_framebuffer *a)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	const struct vivid_fmt *fmt;
-
-	if (dev->multiplanar)
-		return -ENOTTY;
-
-	if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO))
-		return -EPERM;
-
-	if (dev->overlay_cap_owner)
-		return -EBUSY;
-
-	if (a->base == NULL) {
-		dev->fb_cap.base = NULL;
-		dev->fb_vbase_cap = NULL;
-		return 0;
-	}
-
-	if (a->fmt.width < 48 || a->fmt.height < 32)
-		return -EINVAL;
-	fmt = vivid_get_format(dev, a->fmt.pixelformat);
-	if (!fmt || !fmt->can_do_overlay)
-		return -EINVAL;
-	if (a->fmt.bytesperline < (a->fmt.width * fmt->bit_depth[0]) / 8)
-		return -EINVAL;
-	if (a->fmt.height * a->fmt.bytesperline < a->fmt.sizeimage)
-		return -EINVAL;
-
-	dev->fb_vbase_cap = phys_to_virt((unsigned long)a->base);
-	dev->fb_cap = *a;
-	dev->overlay_cap_left = clamp_t(int, dev->overlay_cap_left,
-				    -dev->fb_cap.fmt.width, dev->fb_cap.fmt.width);
-	dev->overlay_cap_top = clamp_t(int, dev->overlay_cap_top,
-				   -dev->fb_cap.fmt.height, dev->fb_cap.fmt.height);
-	return 0;
-}
-
-static const struct v4l2_audio vivid_audio_inputs[] = {
-	{ 0, "TV", V4L2_AUDCAP_STEREO },
-	{ 1, "Line-In", V4L2_AUDCAP_STEREO },
-};
-
-int vidioc_enum_input(struct file *file, void *priv,
-				struct v4l2_input *inp)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (inp->index >= dev->num_inputs)
-		return -EINVAL;
-
-	inp->type = V4L2_INPUT_TYPE_CAMERA;
-	switch (dev->input_type[inp->index]) {
-	case WEBCAM:
-		snprintf(inp->name, sizeof(inp->name), "Webcam %u",
-				dev->input_name_counter[inp->index]);
-		inp->capabilities = 0;
-		break;
-	case TV:
-		snprintf(inp->name, sizeof(inp->name), "TV %u",
-				dev->input_name_counter[inp->index]);
-		inp->type = V4L2_INPUT_TYPE_TUNER;
-		inp->std = V4L2_STD_ALL;
-		if (dev->has_audio_inputs)
-			inp->audioset = (1 << ARRAY_SIZE(vivid_audio_inputs)) - 1;
-		inp->capabilities = V4L2_IN_CAP_STD;
-		break;
-	case SVID:
-		snprintf(inp->name, sizeof(inp->name), "S-Video %u",
-				dev->input_name_counter[inp->index]);
-		inp->std = V4L2_STD_ALL;
-		if (dev->has_audio_inputs)
-			inp->audioset = (1 << ARRAY_SIZE(vivid_audio_inputs)) - 1;
-		inp->capabilities = V4L2_IN_CAP_STD;
-		break;
-	case HDMI:
-		snprintf(inp->name, sizeof(inp->name), "HDMI %u",
-				dev->input_name_counter[inp->index]);
-		inp->capabilities = V4L2_IN_CAP_DV_TIMINGS;
-		if (dev->edid_blocks == 0 ||
-		    dev->dv_timings_signal_mode[dev->input] == NO_SIGNAL)
-			inp->status |= V4L2_IN_ST_NO_SIGNAL;
-		else if (dev->dv_timings_signal_mode[dev->input] == NO_LOCK ||
-			 dev->dv_timings_signal_mode[dev->input] == OUT_OF_RANGE)
-			inp->status |= V4L2_IN_ST_NO_H_LOCK;
-		break;
-	}
-	if (dev->sensor_hflip)
-		inp->status |= V4L2_IN_ST_HFLIP;
-	if (dev->sensor_vflip)
-		inp->status |= V4L2_IN_ST_VFLIP;
-	if (dev->input == inp->index && vivid_is_sdtv_cap(dev)) {
-		if (dev->std_signal_mode[dev->input] == NO_SIGNAL) {
-			inp->status |= V4L2_IN_ST_NO_SIGNAL;
-		} else if (dev->std_signal_mode[dev->input] == NO_LOCK) {
-			inp->status |= V4L2_IN_ST_NO_H_LOCK;
-		} else if (vivid_is_tv_cap(dev)) {
-			switch (tpg_g_quality(&dev->tpg)) {
-			case TPG_QUAL_GRAY:
-				inp->status |= V4L2_IN_ST_COLOR_KILL;
-				break;
-			case TPG_QUAL_NOISE:
-				inp->status |= V4L2_IN_ST_NO_H_LOCK;
-				break;
-			default:
-				break;
-			}
-		}
-	}
-	return 0;
-}
-
-int vidioc_g_input(struct file *file, void *priv, unsigned *i)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	*i = dev->input;
-	return 0;
-}
-
-int vidioc_s_input(struct file *file, void *priv, unsigned i)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	struct v4l2_bt_timings *bt = &dev->dv_timings_cap[dev->input].bt;
-	unsigned brightness;
-
-	if (i >= dev->num_inputs)
-		return -EINVAL;
-
-	if (i == dev->input)
-		return 0;
-
-	if (vb2_is_busy(&dev->vb_vid_cap_q) ||
-	    vb2_is_busy(&dev->vb_vbi_cap_q) ||
-	    vb2_is_busy(&dev->vb_meta_cap_q))
-		return -EBUSY;
-
-	dev->input = i;
-	dev->vid_cap_dev.tvnorms = 0;
-	if (dev->input_type[i] == TV || dev->input_type[i] == SVID) {
-		dev->tv_audio_input = (dev->input_type[i] == TV) ? 0 : 1;
-		dev->vid_cap_dev.tvnorms = V4L2_STD_ALL;
-	}
-	dev->vbi_cap_dev.tvnorms = dev->vid_cap_dev.tvnorms;
-	dev->meta_cap_dev.tvnorms = dev->vid_cap_dev.tvnorms;
-	vivid_update_format_cap(dev, false);
-
-	if (dev->colorspace) {
-		switch (dev->input_type[i]) {
-		case WEBCAM:
-			v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_SRGB);
-			break;
-		case TV:
-		case SVID:
-			v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_170M);
-			break;
-		case HDMI:
-			if (bt->flags & V4L2_DV_FL_IS_CE_VIDEO) {
-				if (dev->src_rect.width == 720 && dev->src_rect.height <= 576)
-					v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_170M);
-				else
-					v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_709);
-			} else {
-				v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_SRGB);
-			}
-			break;
-		}
-	}
-
-	/*
-	 * Modify the brightness range depending on the input.
-	 * This makes it easy to use vivid to test if applications can
-	 * handle control range modifications and is also how this is
-	 * typically used in practice as different inputs may be hooked
-	 * up to different receivers with different control ranges.
-	 */
-	brightness = 128 * i + dev->input_brightness[i];
-	v4l2_ctrl_modify_range(dev->brightness,
-			128 * i, 255 + 128 * i, 1, 128 + 128 * i);
-	v4l2_ctrl_s_ctrl(dev->brightness, brightness);
-
-	/* Restore per-input states. */
-	v4l2_ctrl_activate(dev->ctrl_dv_timings_signal_mode,
-			   vivid_is_hdmi_cap(dev));
-	v4l2_ctrl_activate(dev->ctrl_dv_timings, vivid_is_hdmi_cap(dev) &&
-			   dev->dv_timings_signal_mode[dev->input] ==
-			   SELECTED_DV_TIMINGS);
-	v4l2_ctrl_activate(dev->ctrl_std_signal_mode, vivid_is_sdtv_cap(dev));
-	v4l2_ctrl_activate(dev->ctrl_standard, vivid_is_sdtv_cap(dev) &&
-			   dev->std_signal_mode[dev->input]);
-
-	if (vivid_is_hdmi_cap(dev)) {
-		v4l2_ctrl_s_ctrl(dev->ctrl_dv_timings_signal_mode,
-				 dev->dv_timings_signal_mode[dev->input]);
-		v4l2_ctrl_s_ctrl(dev->ctrl_dv_timings,
-				 dev->query_dv_timings[dev->input]);
-	} else if (vivid_is_sdtv_cap(dev)) {
-		v4l2_ctrl_s_ctrl(dev->ctrl_std_signal_mode,
-				 dev->std_signal_mode[dev->input]);
-		v4l2_ctrl_s_ctrl(dev->ctrl_standard,
-				 dev->std_signal_mode[dev->input]);
-	}
-
-	return 0;
-}
-
-int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)
-{
-	if (vin->index >= ARRAY_SIZE(vivid_audio_inputs))
-		return -EINVAL;
-	*vin = vivid_audio_inputs[vin->index];
-	return 0;
-}
-
-int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (!vivid_is_sdtv_cap(dev))
-		return -EINVAL;
-	*vin = vivid_audio_inputs[dev->tv_audio_input];
-	return 0;
-}
-
-int vidioc_s_audio(struct file *file, void *fh, const struct v4l2_audio *vin)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (!vivid_is_sdtv_cap(dev))
-		return -EINVAL;
-	if (vin->index >= ARRAY_SIZE(vivid_audio_inputs))
-		return -EINVAL;
-	dev->tv_audio_input = vin->index;
-	return 0;
-}
-
-int vivid_video_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (vf->tuner != 0)
-		return -EINVAL;
-	vf->frequency = dev->tv_freq;
-	return 0;
-}
-
-int vivid_video_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *vf)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (vf->tuner != 0)
-		return -EINVAL;
-	dev->tv_freq = clamp_t(unsigned, vf->frequency, MIN_TV_FREQ, MAX_TV_FREQ);
-	if (vivid_is_tv_cap(dev))
-		vivid_update_quality(dev);
-	return 0;
-}
-
-int vivid_video_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (vt->index != 0)
-		return -EINVAL;
-	if (vt->audmode > V4L2_TUNER_MODE_LANG1_LANG2)
-		return -EINVAL;
-	dev->tv_audmode = vt->audmode;
-	return 0;
-}
-
-int vivid_video_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	enum tpg_quality qual;
-
-	if (vt->index != 0)
-		return -EINVAL;
-
-	vt->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
-			 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
-	vt->audmode = dev->tv_audmode;
-	vt->rangelow = MIN_TV_FREQ;
-	vt->rangehigh = MAX_TV_FREQ;
-	qual = vivid_get_quality(dev, &vt->afc);
-	if (qual == TPG_QUAL_COLOR)
-		vt->signal = 0xffff;
-	else if (qual == TPG_QUAL_GRAY)
-		vt->signal = 0x8000;
-	else
-		vt->signal = 0;
-	if (qual == TPG_QUAL_NOISE) {
-		vt->rxsubchans = 0;
-	} else if (qual == TPG_QUAL_GRAY) {
-		vt->rxsubchans = V4L2_TUNER_SUB_MONO;
-	} else {
-		unsigned int channel_nr = dev->tv_freq / (6 * 16);
-		unsigned int options =
-			(dev->std_cap[dev->input] & V4L2_STD_NTSC_M) ? 4 : 3;
-
-		switch (channel_nr % options) {
-		case 0:
-			vt->rxsubchans = V4L2_TUNER_SUB_MONO;
-			break;
-		case 1:
-			vt->rxsubchans = V4L2_TUNER_SUB_STEREO;
-			break;
-		case 2:
-			if (dev->std_cap[dev->input] & V4L2_STD_NTSC_M)
-				vt->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_SAP;
-			else
-				vt->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
-			break;
-		case 3:
-			vt->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_SAP;
-			break;
-		}
-	}
-	strscpy(vt->name, "TV Tuner", sizeof(vt->name));
-	return 0;
-}
-
-/* Must remain in sync with the vivid_ctrl_standard_strings array */
-const v4l2_std_id vivid_standard[] = {
-	V4L2_STD_NTSC_M,
-	V4L2_STD_NTSC_M_JP,
-	V4L2_STD_NTSC_M_KR,
-	V4L2_STD_NTSC_443,
-	V4L2_STD_PAL_BG | V4L2_STD_PAL_H,
-	V4L2_STD_PAL_I,
-	V4L2_STD_PAL_DK,
-	V4L2_STD_PAL_M,
-	V4L2_STD_PAL_N,
-	V4L2_STD_PAL_Nc,
-	V4L2_STD_PAL_60,
-	V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H,
-	V4L2_STD_SECAM_DK,
-	V4L2_STD_SECAM_L,
-	V4L2_STD_SECAM_LC,
-	V4L2_STD_UNKNOWN
-};
-
-/* Must remain in sync with the vivid_standard array */
-const char * const vivid_ctrl_standard_strings[] = {
-	"NTSC-M",
-	"NTSC-M-JP",
-	"NTSC-M-KR",
-	"NTSC-443",
-	"PAL-BGH",
-	"PAL-I",
-	"PAL-DK",
-	"PAL-M",
-	"PAL-N",
-	"PAL-Nc",
-	"PAL-60",
-	"SECAM-BGH",
-	"SECAM-DK",
-	"SECAM-L",
-	"SECAM-Lc",
-	NULL,
-};
-
-int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *id)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	unsigned int last = dev->query_std_last[dev->input];
-
-	if (!vivid_is_sdtv_cap(dev))
-		return -ENODATA;
-	if (dev->std_signal_mode[dev->input] == NO_SIGNAL ||
-	    dev->std_signal_mode[dev->input] == NO_LOCK) {
-		*id = V4L2_STD_UNKNOWN;
-		return 0;
-	}
-	if (vivid_is_tv_cap(dev) && tpg_g_quality(&dev->tpg) == TPG_QUAL_NOISE) {
-		*id = V4L2_STD_UNKNOWN;
-	} else if (dev->std_signal_mode[dev->input] == CURRENT_STD) {
-		*id = dev->std_cap[dev->input];
-	} else if (dev->std_signal_mode[dev->input] == SELECTED_STD) {
-		*id = dev->query_std[dev->input];
-	} else {
-		*id = vivid_standard[last];
-		dev->query_std_last[dev->input] =
-			(last + 1) % ARRAY_SIZE(vivid_standard);
-	}
-
-	return 0;
-}
-
-int vivid_vid_cap_s_std(struct file *file, void *priv, v4l2_std_id id)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (!vivid_is_sdtv_cap(dev))
-		return -ENODATA;
-	if (dev->std_cap[dev->input] == id)
-		return 0;
-	if (vb2_is_busy(&dev->vb_vid_cap_q) || vb2_is_busy(&dev->vb_vbi_cap_q))
-		return -EBUSY;
-	dev->std_cap[dev->input] = id;
-	vivid_update_format_cap(dev, false);
-	return 0;
-}
-
-static void find_aspect_ratio(u32 width, u32 height,
-			       u32 *num, u32 *denom)
-{
-	if (!(height % 3) && ((height * 4 / 3) == width)) {
-		*num = 4;
-		*denom = 3;
-	} else if (!(height % 9) && ((height * 16 / 9) == width)) {
-		*num = 16;
-		*denom = 9;
-	} else if (!(height % 10) && ((height * 16 / 10) == width)) {
-		*num = 16;
-		*denom = 10;
-	} else if (!(height % 4) && ((height * 5 / 4) == width)) {
-		*num = 5;
-		*denom = 4;
-	} else if (!(height % 9) && ((height * 15 / 9) == width)) {
-		*num = 15;
-		*denom = 9;
-	} else { /* default to 16:9 */
-		*num = 16;
-		*denom = 9;
-	}
-}
-
-static bool valid_cvt_gtf_timings(struct v4l2_dv_timings *timings)
-{
-	struct v4l2_bt_timings *bt = &timings->bt;
-	u32 total_h_pixel;
-	u32 total_v_lines;
-	u32 h_freq;
-
-	if (!v4l2_valid_dv_timings(timings, &vivid_dv_timings_cap,
-				NULL, NULL))
-		return false;
-
-	total_h_pixel = V4L2_DV_BT_FRAME_WIDTH(bt);
-	total_v_lines = V4L2_DV_BT_FRAME_HEIGHT(bt);
-
-	h_freq = (u32)bt->pixelclock / total_h_pixel;
-
-	if (bt->standards == 0 || (bt->standards & V4L2_DV_BT_STD_CVT)) {
-		if (v4l2_detect_cvt(total_v_lines, h_freq, bt->vsync, bt->width,
-				    bt->polarities, bt->interlaced, timings))
-			return true;
-	}
-
-	if (bt->standards == 0 || (bt->standards & V4L2_DV_BT_STD_GTF)) {
-		struct v4l2_fract aspect_ratio;
-
-		find_aspect_ratio(bt->width, bt->height,
-				  &aspect_ratio.numerator,
-				  &aspect_ratio.denominator);
-		if (v4l2_detect_gtf(total_v_lines, h_freq, bt->vsync,
-				    bt->polarities, bt->interlaced,
-				    aspect_ratio, timings))
-			return true;
-	}
-	return false;
-}
-
-int vivid_vid_cap_s_dv_timings(struct file *file, void *_fh,
-				    struct v4l2_dv_timings *timings)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (!vivid_is_hdmi_cap(dev))
-		return -ENODATA;
-	if (!v4l2_find_dv_timings_cap(timings, &vivid_dv_timings_cap,
-				      0, NULL, NULL) &&
-	    !valid_cvt_gtf_timings(timings))
-		return -EINVAL;
-
-	if (v4l2_match_dv_timings(timings, &dev->dv_timings_cap[dev->input],
-				  0, false))
-		return 0;
-	if (vb2_is_busy(&dev->vb_vid_cap_q))
-		return -EBUSY;
-
-	dev->dv_timings_cap[dev->input] = *timings;
-	vivid_update_format_cap(dev, false);
-	return 0;
-}
-
-int vidioc_query_dv_timings(struct file *file, void *_fh,
-				    struct v4l2_dv_timings *timings)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	unsigned int input = dev->input;
-	unsigned int last = dev->query_dv_timings_last[input];
-
-	if (!vivid_is_hdmi_cap(dev))
-		return -ENODATA;
-	if (dev->dv_timings_signal_mode[input] == NO_SIGNAL ||
-	    dev->edid_blocks == 0)
-		return -ENOLINK;
-	if (dev->dv_timings_signal_mode[input] == NO_LOCK)
-		return -ENOLCK;
-	if (dev->dv_timings_signal_mode[input] == OUT_OF_RANGE) {
-		timings->bt.pixelclock = vivid_dv_timings_cap.bt.max_pixelclock * 2;
-		return -ERANGE;
-	}
-	if (dev->dv_timings_signal_mode[input] == CURRENT_DV_TIMINGS) {
-		*timings = dev->dv_timings_cap[input];
-	} else if (dev->dv_timings_signal_mode[input] ==
-		   SELECTED_DV_TIMINGS) {
-		*timings =
-			v4l2_dv_timings_presets[dev->query_dv_timings[input]];
-	} else {
-		*timings =
-			v4l2_dv_timings_presets[last];
-		dev->query_dv_timings_last[input] =
-			(last + 1) % dev->query_dv_timings_size;
-	}
-	return 0;
-}
-
-int vidioc_s_edid(struct file *file, void *_fh,
-			 struct v4l2_edid *edid)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	u16 phys_addr;
-	u32 display_present = 0;
-	unsigned int i, j;
-	int ret;
-
-	memset(edid->reserved, 0, sizeof(edid->reserved));
-	if (edid->pad >= dev->num_inputs)
-		return -EINVAL;
-	if (dev->input_type[edid->pad] != HDMI || edid->start_block)
-		return -EINVAL;
-	if (edid->blocks == 0) {
-		dev->edid_blocks = 0;
-		v4l2_ctrl_s_ctrl(dev->ctrl_tx_edid_present, 0);
-		v4l2_ctrl_s_ctrl(dev->ctrl_tx_hotplug, 0);
-		phys_addr = CEC_PHYS_ADDR_INVALID;
-		goto set_phys_addr;
-	}
-	if (edid->blocks > dev->edid_max_blocks) {
-		edid->blocks = dev->edid_max_blocks;
-		return -E2BIG;
-	}
-	phys_addr = cec_get_edid_phys_addr(edid->edid, edid->blocks * 128, NULL);
-	ret = v4l2_phys_addr_validate(phys_addr, &phys_addr, NULL);
-	if (ret)
-		return ret;
-
-	if (vb2_is_busy(&dev->vb_vid_cap_q))
-		return -EBUSY;
-
-	dev->edid_blocks = edid->blocks;
-	memcpy(dev->edid, edid->edid, edid->blocks * 128);
-
-	for (i = 0, j = 0; i < dev->num_outputs; i++)
-		if (dev->output_type[i] == HDMI)
-			display_present |=
-				dev->display_present[i] << j++;
-
-	v4l2_ctrl_s_ctrl(dev->ctrl_tx_edid_present, display_present);
-	v4l2_ctrl_s_ctrl(dev->ctrl_tx_hotplug, display_present);
-
-set_phys_addr:
-	/* TODO: a proper hotplug detect cycle should be emulated here */
-	cec_s_phys_addr(dev->cec_rx_adap, phys_addr, false);
-
-	for (i = 0; i < MAX_OUTPUTS && dev->cec_tx_adap[i]; i++)
-		cec_s_phys_addr(dev->cec_tx_adap[i],
-				dev->display_present[i] ?
-				v4l2_phys_addr_for_input(phys_addr, i + 1) :
-				CEC_PHYS_ADDR_INVALID,
-				false);
-	return 0;
-}
-
-int vidioc_enum_framesizes(struct file *file, void *fh,
-					 struct v4l2_frmsizeenum *fsize)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (!vivid_is_webcam(dev) && !dev->has_scaler_cap)
-		return -EINVAL;
-	if (vivid_get_format(dev, fsize->pixel_format) == NULL)
-		return -EINVAL;
-	if (vivid_is_webcam(dev)) {
-		if (fsize->index >= ARRAY_SIZE(webcam_sizes))
-			return -EINVAL;
-		fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
-		fsize->discrete = webcam_sizes[fsize->index];
-		return 0;
-	}
-	if (fsize->index)
-		return -EINVAL;
-	fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
-	fsize->stepwise.min_width = MIN_WIDTH;
-	fsize->stepwise.max_width = MAX_WIDTH * MAX_ZOOM;
-	fsize->stepwise.step_width = 2;
-	fsize->stepwise.min_height = MIN_HEIGHT;
-	fsize->stepwise.max_height = MAX_HEIGHT * MAX_ZOOM;
-	fsize->stepwise.step_height = 2;
-	return 0;
-}
-
-/* timeperframe is arbitrary and continuous */
-int vidioc_enum_frameintervals(struct file *file, void *priv,
-					     struct v4l2_frmivalenum *fival)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	const struct vivid_fmt *fmt;
-	int i;
-
-	fmt = vivid_get_format(dev, fival->pixel_format);
-	if (!fmt)
-		return -EINVAL;
-
-	if (!vivid_is_webcam(dev)) {
-		if (fival->index)
-			return -EINVAL;
-		if (fival->width < MIN_WIDTH || fival->width > MAX_WIDTH * MAX_ZOOM)
-			return -EINVAL;
-		if (fival->height < MIN_HEIGHT || fival->height > MAX_HEIGHT * MAX_ZOOM)
-			return -EINVAL;
-		fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
-		fival->discrete = dev->timeperframe_vid_cap;
-		return 0;
-	}
-
-	for (i = 0; i < ARRAY_SIZE(webcam_sizes); i++)
-		if (fival->width == webcam_sizes[i].width &&
-		    fival->height == webcam_sizes[i].height)
-			break;
-	if (i == ARRAY_SIZE(webcam_sizes))
-		return -EINVAL;
-	if (fival->index >= 2 * (VIVID_WEBCAM_SIZES - i))
-		return -EINVAL;
-	fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
-	fival->discrete = webcam_intervals[fival->index];
-	return 0;
-}
-
-int vivid_vid_cap_g_parm(struct file *file, void *priv,
-			  struct v4l2_streamparm *parm)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (parm->type != (dev->multiplanar ?
-			   V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
-			   V4L2_BUF_TYPE_VIDEO_CAPTURE))
-		return -EINVAL;
-
-	parm->parm.capture.capability   = V4L2_CAP_TIMEPERFRAME;
-	parm->parm.capture.timeperframe = dev->timeperframe_vid_cap;
-	parm->parm.capture.readbuffers  = 1;
-	return 0;
-}
-
-int vivid_vid_cap_s_parm(struct file *file, void *priv,
-			  struct v4l2_streamparm *parm)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	unsigned ival_sz = 2 * (VIVID_WEBCAM_SIZES - dev->webcam_size_idx);
-	struct v4l2_fract tpf;
-	unsigned i;
-
-	if (parm->type != (dev->multiplanar ?
-			   V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
-			   V4L2_BUF_TYPE_VIDEO_CAPTURE))
-		return -EINVAL;
-	if (!vivid_is_webcam(dev))
-		return vivid_vid_cap_g_parm(file, priv, parm);
-
-	tpf = parm->parm.capture.timeperframe;
-
-	if (tpf.denominator == 0)
-		tpf = webcam_intervals[ival_sz - 1];
-	for (i = 0; i < ival_sz; i++)
-		if (V4L2_FRACT_COMPARE(tpf, >=, webcam_intervals[i]))
-			break;
-	if (i == ival_sz)
-		i = ival_sz - 1;
-	dev->webcam_ival_idx = i;
-	tpf = webcam_intervals[dev->webcam_ival_idx];
-
-	/* resync the thread's timings */
-	dev->cap_seq_resync = true;
-	dev->timeperframe_vid_cap = tpf;
-	parm->parm.capture.capability   = V4L2_CAP_TIMEPERFRAME;
-	parm->parm.capture.timeperframe = tpf;
-	parm->parm.capture.readbuffers  = 1;
-	return 0;
-}
diff --git a/drivers/media/platform/vivid/vivid-vid-cap.h b/drivers/media/platform/vivid/vivid-vid-cap.h
deleted file mode 100644
index 1e422a59eeab..000000000000
--- a/drivers/media/platform/vivid/vivid-vid-cap.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * vivid-vid-cap.h - video capture support functions.
- *
- * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#ifndef _VIVID_VID_CAP_H_
-#define _VIVID_VID_CAP_H_
-
-void vivid_update_quality(struct vivid_dev *dev);
-void vivid_update_format_cap(struct vivid_dev *dev, bool keep_controls);
-enum tpg_video_aspect vivid_get_video_aspect(const struct vivid_dev *dev);
-
-extern const v4l2_std_id vivid_standard[];
-extern const char * const vivid_ctrl_standard_strings[];
-
-extern const struct vb2_ops vivid_vid_cap_qops;
-
-int vivid_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f);
-int vivid_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f);
-int vivid_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f);
-int vidioc_g_fmt_vid_cap_mplane(struct file *file, void *priv, struct v4l2_format *f);
-int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv, struct v4l2_format *f);
-int vidioc_s_fmt_vid_cap_mplane(struct file *file, void *priv, struct v4l2_format *f);
-int vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f);
-int vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f);
-int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f);
-int vivid_vid_cap_g_selection(struct file *file, void *priv, struct v4l2_selection *sel);
-int vivid_vid_cap_s_selection(struct file *file, void *fh, struct v4l2_selection *s);
-int vivid_vid_cap_g_pixelaspect(struct file *file, void *priv, int type, struct v4l2_fract *f);
-int vidioc_enum_fmt_vid_overlay(struct file *file, void  *priv, struct v4l2_fmtdesc *f);
-int vidioc_g_fmt_vid_overlay(struct file *file, void *priv, struct v4l2_format *f);
-int vidioc_try_fmt_vid_overlay(struct file *file, void *priv, struct v4l2_format *f);
-int vidioc_s_fmt_vid_overlay(struct file *file, void *priv, struct v4l2_format *f);
-int vivid_vid_cap_overlay(struct file *file, void *fh, unsigned i);
-int vivid_vid_cap_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *a);
-int vivid_vid_cap_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffer *a);
-int vidioc_enum_input(struct file *file, void *priv, struct v4l2_input *inp);
-int vidioc_g_input(struct file *file, void *priv, unsigned *i);
-int vidioc_s_input(struct file *file, void *priv, unsigned i);
-int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin);
-int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *vin);
-int vidioc_s_audio(struct file *file, void *fh, const struct v4l2_audio *vin);
-int vivid_video_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf);
-int vivid_video_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *vf);
-int vivid_video_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt);
-int vivid_video_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt);
-int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *id);
-int vivid_vid_cap_s_std(struct file *file, void *priv, v4l2_std_id id);
-int vivid_vid_cap_s_dv_timings(struct file *file, void *_fh, struct v4l2_dv_timings *timings);
-int vidioc_query_dv_timings(struct file *file, void *_fh, struct v4l2_dv_timings *timings);
-int vidioc_s_edid(struct file *file, void *_fh, struct v4l2_edid *edid);
-int vidioc_enum_framesizes(struct file *file, void *fh, struct v4l2_frmsizeenum *fsize);
-int vidioc_enum_frameintervals(struct file *file, void *priv, struct v4l2_frmivalenum *fival);
-int vivid_vid_cap_g_parm(struct file *file, void *priv, struct v4l2_streamparm *parm);
-int vivid_vid_cap_s_parm(struct file *file, void *priv, struct v4l2_streamparm *parm);
-
-#endif
diff --git a/drivers/media/platform/vivid/vivid-vid-common.c b/drivers/media/platform/vivid/vivid-vid-common.c
deleted file mode 100644
index 76b0be670ebb..000000000000
--- a/drivers/media/platform/vivid/vivid-vid-common.c
+++ /dev/null
@@ -1,1035 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * vivid-vid-common.c - common video support functions.
- *
- * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/videodev2.h>
-#include <linux/v4l2-dv-timings.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-event.h>
-#include <media/v4l2-dv-timings.h>
-
-#include "vivid-core.h"
-#include "vivid-vid-common.h"
-
-const struct v4l2_dv_timings_cap vivid_dv_timings_cap = {
-	.type = V4L2_DV_BT_656_1120,
-	/* keep this initialization for compatibility with GCC < 4.4.6 */
-	.reserved = { 0 },
-	V4L2_INIT_BT_TIMINGS(16, MAX_WIDTH, 16, MAX_HEIGHT, 14000000, 775000000,
-		V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT |
-		V4L2_DV_BT_STD_CVT | V4L2_DV_BT_STD_GTF,
-		V4L2_DV_BT_CAP_PROGRESSIVE | V4L2_DV_BT_CAP_INTERLACED)
-};
-
-/* ------------------------------------------------------------------
-	Basic structures
-   ------------------------------------------------------------------*/
-
-struct vivid_fmt vivid_formats[] = {
-	{
-		.fourcc   = V4L2_PIX_FMT_YUYV,
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.color_enc = TGP_COLOR_ENC_YCBCR,
-		.planes   = 1,
-		.buffers = 1,
-		.data_offset = { PLANE0_DATA_OFFSET },
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_UYVY,
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.color_enc = TGP_COLOR_ENC_YCBCR,
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_YVYU,
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.color_enc = TGP_COLOR_ENC_YCBCR,
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_VYUY,
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.color_enc = TGP_COLOR_ENC_YCBCR,
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_YUV422P,
-		.vdownsampling = { 1, 1, 1 },
-		.bit_depth = { 8, 4, 4 },
-		.color_enc = TGP_COLOR_ENC_YCBCR,
-		.planes   = 3,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_YUV420,
-		.vdownsampling = { 1, 2, 2 },
-		.bit_depth = { 8, 4, 4 },
-		.color_enc = TGP_COLOR_ENC_YCBCR,
-		.planes   = 3,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_YVU420,
-		.vdownsampling = { 1, 2, 2 },
-		.bit_depth = { 8, 4, 4 },
-		.color_enc = TGP_COLOR_ENC_YCBCR,
-		.planes   = 3,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_NV12,
-		.vdownsampling = { 1, 2 },
-		.bit_depth = { 8, 8 },
-		.color_enc = TGP_COLOR_ENC_YCBCR,
-		.planes   = 2,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_NV21,
-		.vdownsampling = { 1, 2 },
-		.bit_depth = { 8, 8 },
-		.color_enc = TGP_COLOR_ENC_YCBCR,
-		.planes   = 2,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_NV16,
-		.vdownsampling = { 1, 1 },
-		.bit_depth = { 8, 8 },
-		.color_enc = TGP_COLOR_ENC_YCBCR,
-		.planes   = 2,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_NV61,
-		.vdownsampling = { 1, 1 },
-		.bit_depth = { 8, 8 },
-		.color_enc = TGP_COLOR_ENC_YCBCR,
-		.planes   = 2,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_NV24,
-		.vdownsampling = { 1, 1 },
-		.bit_depth = { 8, 16 },
-		.color_enc = TGP_COLOR_ENC_YCBCR,
-		.planes   = 2,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_NV42,
-		.vdownsampling = { 1, 1 },
-		.bit_depth = { 8, 16 },
-		.color_enc = TGP_COLOR_ENC_YCBCR,
-		.planes   = 2,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_YUV555, /* uuuvvvvv ayyyyyuu */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-		.alpha_mask = 0x8000,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_YUV565, /* uuuvvvvv yyyyyuuu */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_YUV444, /* uuuuvvvv aaaayyyy */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-		.alpha_mask = 0xf000,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_YUV32, /* ayuv */
-		.vdownsampling = { 1 },
-		.bit_depth = { 32 },
-		.planes   = 1,
-		.buffers = 1,
-		.alpha_mask = 0x000000ff,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_AYUV32,
-		.vdownsampling = { 1 },
-		.bit_depth = { 32 },
-		.planes   = 1,
-		.buffers = 1,
-		.alpha_mask = 0x000000ff,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_XYUV32,
-		.vdownsampling = { 1 },
-		.bit_depth = { 32 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_VUYA32,
-		.vdownsampling = { 1 },
-		.bit_depth = { 32 },
-		.planes   = 1,
-		.buffers = 1,
-		.alpha_mask = 0xff000000,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_VUYX32,
-		.vdownsampling = { 1 },
-		.bit_depth = { 32 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_GREY,
-		.vdownsampling = { 1 },
-		.bit_depth = { 8 },
-		.color_enc = TGP_COLOR_ENC_LUMA,
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_Y10,
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.color_enc = TGP_COLOR_ENC_LUMA,
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_Y12,
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.color_enc = TGP_COLOR_ENC_LUMA,
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_Y16,
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.color_enc = TGP_COLOR_ENC_LUMA,
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_Y16_BE,
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.color_enc = TGP_COLOR_ENC_LUMA,
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_RGB332, /* rrrgggbb */
-		.vdownsampling = { 1 },
-		.bit_depth = { 8 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-		.can_do_overlay = true,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-		.can_do_overlay = true,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_RGB444, /* ggggbbbb xxxxrrrr */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_XRGB444, /* ggggbbbb xxxxrrrr */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_ARGB444, /* ggggbbbb aaaarrrr */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-		.alpha_mask = 0x00f0,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_RGBX444, /* bbbbxxxx rrrrgggg */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_RGBA444, /* bbbbaaaa rrrrgggg */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-		.alpha_mask = 0x00f0,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_XBGR444, /* ggggrrrr xxxxbbbb */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_ABGR444, /* ggggrrrr aaaabbbb */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-		.alpha_mask = 0x00f0,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_BGRX444, /* rrrrxxxx bbbbgggg */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_BGRA444, /* rrrraaaa bbbbgggg  */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-		.alpha_mask = 0x00f0,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_RGB555, /* gggbbbbb xrrrrrgg */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-		.can_do_overlay = true,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_XRGB555, /* gggbbbbb xrrrrrgg */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-		.can_do_overlay = true,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_ARGB555, /* gggbbbbb arrrrrgg */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-		.can_do_overlay = true,
-		.alpha_mask = 0x8000,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_RGBX555, /* ggbbbbbx rrrrrggg */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-		.can_do_overlay = true,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_RGBA555, /* ggbbbbba rrrrrggg */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-		.can_do_overlay = true,
-		.alpha_mask = 0x8000,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_XBGR555, /* gggrrrrr xbbbbbgg */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-		.can_do_overlay = true,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_ABGR555, /* gggrrrrr abbbbbgg */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-		.can_do_overlay = true,
-		.alpha_mask = 0x8000,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_BGRX555, /* ggrrrrrx bbbbbggg */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-		.can_do_overlay = true,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_BGRA555, /* ggrrrrra bbbbbggg */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-		.can_do_overlay = true,
-		.alpha_mask = 0x8000,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_RGB555X, /* xrrrrrgg gggbbbbb */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_XRGB555X, /* xrrrrrgg gggbbbbb */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_ARGB555X, /* arrrrrgg gggbbbbb */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-		.alpha_mask = 0x0080,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_RGB24, /* rgb */
-		.vdownsampling = { 1 },
-		.bit_depth = { 24 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_BGR24, /* bgr */
-		.vdownsampling = { 1 },
-		.bit_depth = { 24 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_BGR666, /* bbbbbbgg ggggrrrr rrxxxxxx */
-		.vdownsampling = { 1 },
-		.bit_depth = { 32 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_RGB32, /* xrgb */
-		.vdownsampling = { 1 },
-		.bit_depth = { 32 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_BGR32, /* bgrx */
-		.vdownsampling = { 1 },
-		.bit_depth = { 32 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_XRGB32, /* xrgb */
-		.vdownsampling = { 1 },
-		.bit_depth = { 32 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_XBGR32, /* bgrx */
-		.vdownsampling = { 1 },
-		.bit_depth = { 32 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_ARGB32, /* argb */
-		.vdownsampling = { 1 },
-		.bit_depth = { 32 },
-		.planes   = 1,
-		.buffers = 1,
-		.alpha_mask = 0x000000ff,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_ABGR32, /* bgra */
-		.vdownsampling = { 1 },
-		.bit_depth = { 32 },
-		.planes   = 1,
-		.buffers = 1,
-		.alpha_mask = 0xff000000,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_RGBX32, /* rgbx */
-		.vdownsampling = { 1 },
-		.bit_depth = { 32 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_BGRX32, /* xbgr */
-		.vdownsampling = { 1 },
-		.bit_depth = { 32 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_RGBA32, /* rgba */
-		.vdownsampling = { 1 },
-		.bit_depth = { 32 },
-		.planes   = 1,
-		.buffers = 1,
-		.alpha_mask = 0x000000ff,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_BGRA32, /* abgr */
-		.vdownsampling = { 1 },
-		.bit_depth = { 32 },
-		.planes   = 1,
-		.buffers = 1,
-		.alpha_mask = 0xff000000,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_SBGGR8, /* Bayer BG/GR */
-		.vdownsampling = { 1 },
-		.bit_depth = { 8 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_SGBRG8, /* Bayer GB/RG */
-		.vdownsampling = { 1 },
-		.bit_depth = { 8 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_SGRBG8, /* Bayer GR/BG */
-		.vdownsampling = { 1 },
-		.bit_depth = { 8 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_SRGGB8, /* Bayer RG/GB */
-		.vdownsampling = { 1 },
-		.bit_depth = { 8 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_SBGGR10, /* Bayer BG/GR */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_SGBRG10, /* Bayer GB/RG */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_SGRBG10, /* Bayer GR/BG */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_SRGGB10, /* Bayer RG/GB */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_SBGGR12, /* Bayer BG/GR */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_SGBRG12, /* Bayer GB/RG */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_SGRBG12, /* Bayer GR/BG */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_SRGGB12, /* Bayer RG/GB */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_SBGGR16, /* Bayer BG/GR */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_SGBRG16, /* Bayer GB/RG */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_SGRBG16, /* Bayer GR/BG */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_SRGGB16, /* Bayer RG/GB */
-		.vdownsampling = { 1 },
-		.bit_depth = { 16 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_HSV24, /* HSV 24bits */
-		.color_enc = TGP_COLOR_ENC_HSV,
-		.vdownsampling = { 1 },
-		.bit_depth = { 24 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_HSV32, /* HSV 32bits */
-		.color_enc = TGP_COLOR_ENC_HSV,
-		.vdownsampling = { 1 },
-		.bit_depth = { 32 },
-		.planes   = 1,
-		.buffers = 1,
-	},
-
-	/* Multiplanar formats */
-
-	{
-		.fourcc   = V4L2_PIX_FMT_NV16M,
-		.vdownsampling = { 1, 1 },
-		.bit_depth = { 8, 8 },
-		.color_enc = TGP_COLOR_ENC_YCBCR,
-		.planes   = 2,
-		.buffers = 2,
-		.data_offset = { PLANE0_DATA_OFFSET, 0 },
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_NV61M,
-		.vdownsampling = { 1, 1 },
-		.bit_depth = { 8, 8 },
-		.color_enc = TGP_COLOR_ENC_YCBCR,
-		.planes   = 2,
-		.buffers = 2,
-		.data_offset = { 0, PLANE0_DATA_OFFSET },
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_YUV420M,
-		.vdownsampling = { 1, 2, 2 },
-		.bit_depth = { 8, 4, 4 },
-		.color_enc = TGP_COLOR_ENC_YCBCR,
-		.planes   = 3,
-		.buffers = 3,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_YVU420M,
-		.vdownsampling = { 1, 2, 2 },
-		.bit_depth = { 8, 4, 4 },
-		.color_enc = TGP_COLOR_ENC_YCBCR,
-		.planes   = 3,
-		.buffers = 3,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_NV12M,
-		.vdownsampling = { 1, 2 },
-		.bit_depth = { 8, 8 },
-		.color_enc = TGP_COLOR_ENC_YCBCR,
-		.planes   = 2,
-		.buffers = 2,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_NV21M,
-		.vdownsampling = { 1, 2 },
-		.bit_depth = { 8, 8 },
-		.color_enc = TGP_COLOR_ENC_YCBCR,
-		.planes   = 2,
-		.buffers = 2,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_YUV422M,
-		.vdownsampling = { 1, 1, 1 },
-		.bit_depth = { 8, 4, 4 },
-		.color_enc = TGP_COLOR_ENC_YCBCR,
-		.planes   = 3,
-		.buffers = 3,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_YVU422M,
-		.vdownsampling = { 1, 1, 1 },
-		.bit_depth = { 8, 4, 4 },
-		.color_enc = TGP_COLOR_ENC_YCBCR,
-		.planes   = 3,
-		.buffers = 3,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_YUV444M,
-		.vdownsampling = { 1, 1, 1 },
-		.bit_depth = { 8, 8, 8 },
-		.color_enc = TGP_COLOR_ENC_YCBCR,
-		.planes   = 3,
-		.buffers = 3,
-	},
-	{
-		.fourcc   = V4L2_PIX_FMT_YVU444M,
-		.vdownsampling = { 1, 1, 1 },
-		.bit_depth = { 8, 8, 8 },
-		.color_enc = TGP_COLOR_ENC_YCBCR,
-		.planes   = 3,
-		.buffers = 3,
-	},
-};
-
-/* There are this many multiplanar formats in the list */
-#define VIVID_MPLANAR_FORMATS 10
-
-const struct vivid_fmt *vivid_get_format(struct vivid_dev *dev, u32 pixelformat)
-{
-	const struct vivid_fmt *fmt;
-	unsigned k;
-
-	for (k = 0; k < ARRAY_SIZE(vivid_formats); k++) {
-		fmt = &vivid_formats[k];
-		if (fmt->fourcc == pixelformat)
-			if (fmt->buffers == 1 || dev->multiplanar)
-				return fmt;
-	}
-
-	return NULL;
-}
-
-bool vivid_vid_can_loop(struct vivid_dev *dev)
-{
-	if (dev->src_rect.width != dev->sink_rect.width ||
-	    dev->src_rect.height != dev->sink_rect.height)
-		return false;
-	if (dev->fmt_cap->fourcc != dev->fmt_out->fourcc)
-		return false;
-	if (dev->field_cap != dev->field_out)
-		return false;
-	/*
-	 * While this can be supported, it is just too much work
-	 * to actually implement.
-	 */
-	if (dev->field_cap == V4L2_FIELD_SEQ_TB ||
-	    dev->field_cap == V4L2_FIELD_SEQ_BT)
-		return false;
-	if (vivid_is_svid_cap(dev) && vivid_is_svid_out(dev)) {
-		if (!(dev->std_cap[dev->input] & V4L2_STD_525_60) !=
-		    !(dev->std_out & V4L2_STD_525_60))
-			return false;
-		return true;
-	}
-	if (vivid_is_hdmi_cap(dev) && vivid_is_hdmi_out(dev))
-		return true;
-	return false;
-}
-
-void vivid_send_source_change(struct vivid_dev *dev, unsigned type)
-{
-	struct v4l2_event ev = {
-		.type = V4L2_EVENT_SOURCE_CHANGE,
-		.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION,
-	};
-	unsigned i;
-
-	for (i = 0; i < dev->num_inputs; i++) {
-		ev.id = i;
-		if (dev->input_type[i] == type) {
-			if (video_is_registered(&dev->vid_cap_dev) && dev->has_vid_cap)
-				v4l2_event_queue(&dev->vid_cap_dev, &ev);
-			if (video_is_registered(&dev->vbi_cap_dev) && dev->has_vbi_cap)
-				v4l2_event_queue(&dev->vbi_cap_dev, &ev);
-		}
-	}
-}
-
-/*
- * Conversion function that converts a single-planar format to a
- * single-plane multiplanar format.
- */
-void fmt_sp2mp(const struct v4l2_format *sp_fmt, struct v4l2_format *mp_fmt)
-{
-	struct v4l2_pix_format_mplane *mp = &mp_fmt->fmt.pix_mp;
-	struct v4l2_plane_pix_format *ppix = &mp->plane_fmt[0];
-	const struct v4l2_pix_format *pix = &sp_fmt->fmt.pix;
-	bool is_out = sp_fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT;
-
-	memset(mp->reserved, 0, sizeof(mp->reserved));
-	mp_fmt->type = is_out ? V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE :
-			   V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-	mp->width = pix->width;
-	mp->height = pix->height;
-	mp->pixelformat = pix->pixelformat;
-	mp->field = pix->field;
-	mp->colorspace = pix->colorspace;
-	mp->xfer_func = pix->xfer_func;
-	/* Also copies hsv_enc */
-	mp->ycbcr_enc = pix->ycbcr_enc;
-	mp->quantization = pix->quantization;
-	mp->num_planes = 1;
-	mp->flags = pix->flags;
-	ppix->sizeimage = pix->sizeimage;
-	ppix->bytesperline = pix->bytesperline;
-	memset(ppix->reserved, 0, sizeof(ppix->reserved));
-}
-
-int fmt_sp2mp_func(struct file *file, void *priv,
-		struct v4l2_format *f, fmtfunc func)
-{
-	struct v4l2_format fmt;
-	struct v4l2_pix_format_mplane *mp = &fmt.fmt.pix_mp;
-	struct v4l2_plane_pix_format *ppix = &mp->plane_fmt[0];
-	struct v4l2_pix_format *pix = &f->fmt.pix;
-	int ret;
-
-	/* Converts to a mplane format */
-	fmt_sp2mp(f, &fmt);
-	/* Passes it to the generic mplane format function */
-	ret = func(file, priv, &fmt);
-	/* Copies back the mplane data to the single plane format */
-	pix->width = mp->width;
-	pix->height = mp->height;
-	pix->pixelformat = mp->pixelformat;
-	pix->field = mp->field;
-	pix->colorspace = mp->colorspace;
-	pix->xfer_func = mp->xfer_func;
-	/* Also copies hsv_enc */
-	pix->ycbcr_enc = mp->ycbcr_enc;
-	pix->quantization = mp->quantization;
-	pix->sizeimage = ppix->sizeimage;
-	pix->bytesperline = ppix->bytesperline;
-	pix->flags = mp->flags;
-	return ret;
-}
-
-int vivid_vid_adjust_sel(unsigned flags, struct v4l2_rect *r)
-{
-	unsigned w = r->width;
-	unsigned h = r->height;
-
-	/* sanitize w and h in case someone passes ~0 as the value */
-	w &= 0xffff;
-	h &= 0xffff;
-	if (!(flags & V4L2_SEL_FLAG_LE)) {
-		w++;
-		h++;
-		if (w < 2)
-			w = 2;
-		if (h < 2)
-			h = 2;
-	}
-	if (!(flags & V4L2_SEL_FLAG_GE)) {
-		if (w > MAX_WIDTH)
-			w = MAX_WIDTH;
-		if (h > MAX_HEIGHT)
-			h = MAX_HEIGHT;
-	}
-	w = w & ~1;
-	h = h & ~1;
-	if (w < 2 || h < 2)
-		return -ERANGE;
-	if (w > MAX_WIDTH || h > MAX_HEIGHT)
-		return -ERANGE;
-	if (r->top < 0)
-		r->top = 0;
-	if (r->left < 0)
-		r->left = 0;
-	/* sanitize left and top in case someone passes ~0 as the value */
-	r->left &= 0xfffe;
-	r->top &= 0xfffe;
-	if (r->left + w > MAX_WIDTH)
-		r->left = MAX_WIDTH - w;
-	if (r->top + h > MAX_HEIGHT)
-		r->top = MAX_HEIGHT - h;
-	if ((flags & (V4L2_SEL_FLAG_GE | V4L2_SEL_FLAG_LE)) ==
-			(V4L2_SEL_FLAG_GE | V4L2_SEL_FLAG_LE) &&
-	    (r->width != w || r->height != h))
-		return -ERANGE;
-	r->width = w;
-	r->height = h;
-	return 0;
-}
-
-int vivid_enum_fmt_vid(struct file *file, void  *priv,
-					struct v4l2_fmtdesc *f)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	const struct vivid_fmt *fmt;
-
-	if (f->index >= ARRAY_SIZE(vivid_formats) -
-	    (dev->multiplanar ? 0 : VIVID_MPLANAR_FORMATS))
-		return -EINVAL;
-
-	fmt = &vivid_formats[f->index];
-
-	f->pixelformat = fmt->fourcc;
-	return 0;
-}
-
-int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	struct video_device *vdev = video_devdata(file);
-
-	if (vdev->vfl_dir == VFL_DIR_RX) {
-		if (!vivid_is_sdtv_cap(dev))
-			return -ENODATA;
-		*id = dev->std_cap[dev->input];
-	} else {
-		if (!vivid_is_svid_out(dev))
-			return -ENODATA;
-		*id = dev->std_out;
-	}
-	return 0;
-}
-
-int vidioc_g_dv_timings(struct file *file, void *_fh,
-				    struct v4l2_dv_timings *timings)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	struct video_device *vdev = video_devdata(file);
-
-	if (vdev->vfl_dir == VFL_DIR_RX) {
-		if (!vivid_is_hdmi_cap(dev))
-			return -ENODATA;
-		*timings = dev->dv_timings_cap[dev->input];
-	} else {
-		if (!vivid_is_hdmi_out(dev))
-			return -ENODATA;
-		*timings = dev->dv_timings_out;
-	}
-	return 0;
-}
-
-int vidioc_enum_dv_timings(struct file *file, void *_fh,
-				    struct v4l2_enum_dv_timings *timings)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	struct video_device *vdev = video_devdata(file);
-
-	if (vdev->vfl_dir == VFL_DIR_RX) {
-		if (!vivid_is_hdmi_cap(dev))
-			return -ENODATA;
-	} else {
-		if (!vivid_is_hdmi_out(dev))
-			return -ENODATA;
-	}
-	return v4l2_enum_dv_timings_cap(timings, &vivid_dv_timings_cap,
-			NULL, NULL);
-}
-
-int vidioc_dv_timings_cap(struct file *file, void *_fh,
-				    struct v4l2_dv_timings_cap *cap)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	struct video_device *vdev = video_devdata(file);
-
-	if (vdev->vfl_dir == VFL_DIR_RX) {
-		if (!vivid_is_hdmi_cap(dev))
-			return -ENODATA;
-	} else {
-		if (!vivid_is_hdmi_out(dev))
-			return -ENODATA;
-	}
-	*cap = vivid_dv_timings_cap;
-	return 0;
-}
-
-int vidioc_g_edid(struct file *file, void *_fh,
-			 struct v4l2_edid *edid)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	struct video_device *vdev = video_devdata(file);
-	struct cec_adapter *adap;
-
-	memset(edid->reserved, 0, sizeof(edid->reserved));
-	if (vdev->vfl_dir == VFL_DIR_RX) {
-		if (edid->pad >= dev->num_inputs)
-			return -EINVAL;
-		if (dev->input_type[edid->pad] != HDMI)
-			return -EINVAL;
-		adap = dev->cec_rx_adap;
-	} else {
-		unsigned int bus_idx;
-
-		if (edid->pad >= dev->num_outputs)
-			return -EINVAL;
-		if (dev->output_type[edid->pad] != HDMI)
-			return -EINVAL;
-		if (!dev->display_present[edid->pad])
-			return -ENODATA;
-		bus_idx = dev->cec_output2bus_map[edid->pad];
-		adap = dev->cec_tx_adap[bus_idx];
-	}
-	if (edid->start_block == 0 && edid->blocks == 0) {
-		edid->blocks = dev->edid_blocks;
-		return 0;
-	}
-	if (dev->edid_blocks == 0)
-		return -ENODATA;
-	if (edid->start_block >= dev->edid_blocks)
-		return -EINVAL;
-	if (edid->blocks > dev->edid_blocks - edid->start_block)
-		edid->blocks = dev->edid_blocks - edid->start_block;
-	if (adap)
-		v4l2_set_edid_phys_addr(dev->edid, dev->edid_blocks * 128, adap->phys_addr);
-	memcpy(edid->edid, dev->edid + edid->start_block * 128, edid->blocks * 128);
-	return 0;
-}
diff --git a/drivers/media/platform/vivid/vivid-vid-common.h b/drivers/media/platform/vivid/vivid-vid-common.h
deleted file mode 100644
index d908d9725283..000000000000
--- a/drivers/media/platform/vivid/vivid-vid-common.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * vivid-vid-common.h - common video support functions.
- *
- * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#ifndef _VIVID_VID_COMMON_H_
-#define _VIVID_VID_COMMON_H_
-
-typedef int (*fmtfunc)(struct file *file, void *priv, struct v4l2_format *f);
-
-/*
- * Conversion function that converts a single-planar format to a
- * single-plane multiplanar format.
- */
-void fmt_sp2mp(const struct v4l2_format *sp_fmt, struct v4l2_format *mp_fmt);
-int fmt_sp2mp_func(struct file *file, void *priv,
-		struct v4l2_format *f, fmtfunc func);
-
-extern const struct v4l2_dv_timings_cap vivid_dv_timings_cap;
-
-const struct vivid_fmt *vivid_get_format(struct vivid_dev *dev, u32 pixelformat);
-
-bool vivid_vid_can_loop(struct vivid_dev *dev);
-void vivid_send_source_change(struct vivid_dev *dev, unsigned type);
-
-int vivid_vid_adjust_sel(unsigned flags, struct v4l2_rect *r);
-
-int vivid_enum_fmt_vid(struct file *file, void  *priv, struct v4l2_fmtdesc *f);
-int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id);
-int vidioc_g_dv_timings(struct file *file, void *_fh, struct v4l2_dv_timings *timings);
-int vidioc_enum_dv_timings(struct file *file, void *_fh, struct v4l2_enum_dv_timings *timings);
-int vidioc_dv_timings_cap(struct file *file, void *_fh, struct v4l2_dv_timings_cap *cap);
-int vidioc_g_edid(struct file *file, void *_fh, struct v4l2_edid *edid);
-int vidioc_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub);
-
-#endif
diff --git a/drivers/media/platform/vivid/vivid-vid-out.c b/drivers/media/platform/vivid/vivid-vid-out.c
deleted file mode 100644
index ee3446e3217c..000000000000
--- a/drivers/media/platform/vivid/vivid-vid-out.c
+++ /dev/null
@@ -1,1210 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * vivid-vid-out.c - video output support functions.
- *
- * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/videodev2.h>
-#include <linux/v4l2-dv-timings.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-event.h>
-#include <media/v4l2-dv-timings.h>
-#include <media/v4l2-rect.h>
-
-#include "vivid-core.h"
-#include "vivid-vid-common.h"
-#include "vivid-kthread-out.h"
-#include "vivid-vid-out.h"
-
-static int vid_out_queue_setup(struct vb2_queue *vq,
-		       unsigned *nbuffers, unsigned *nplanes,
-		       unsigned sizes[], struct device *alloc_devs[])
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vq);
-	const struct vivid_fmt *vfmt = dev->fmt_out;
-	unsigned planes = vfmt->buffers;
-	unsigned h = dev->fmt_out_rect.height;
-	unsigned int size = dev->bytesperline_out[0] * h + vfmt->data_offset[0];
-	unsigned p;
-
-	for (p = vfmt->buffers; p < vfmt->planes; p++)
-		size += dev->bytesperline_out[p] * h / vfmt->vdownsampling[p] +
-			vfmt->data_offset[p];
-
-	if (dev->field_out == V4L2_FIELD_ALTERNATE) {
-		/*
-		 * You cannot use write() with FIELD_ALTERNATE since the field
-		 * information (TOP/BOTTOM) cannot be passed to the kernel.
-		 */
-		if (vb2_fileio_is_active(vq))
-			return -EINVAL;
-	}
-
-	if (dev->queue_setup_error) {
-		/*
-		 * Error injection: test what happens if queue_setup() returns
-		 * an error.
-		 */
-		dev->queue_setup_error = false;
-		return -EINVAL;
-	}
-
-	if (*nplanes) {
-		/*
-		 * Check if the number of requested planes match
-		 * the number of planes in the current format. You can't mix that.
-		 */
-		if (*nplanes != planes)
-			return -EINVAL;
-		if (sizes[0] < size)
-			return -EINVAL;
-		for (p = 1; p < planes; p++) {
-			if (sizes[p] < dev->bytesperline_out[p] * h +
-				       vfmt->data_offset[p])
-				return -EINVAL;
-		}
-	} else {
-		for (p = 0; p < planes; p++)
-			sizes[p] = p ? dev->bytesperline_out[p] * h +
-				       vfmt->data_offset[p] : size;
-	}
-
-	if (vq->num_buffers + *nbuffers < 2)
-		*nbuffers = 2 - vq->num_buffers;
-
-	*nplanes = planes;
-
-	dprintk(dev, 1, "%s: count=%d\n", __func__, *nbuffers);
-	for (p = 0; p < planes; p++)
-		dprintk(dev, 1, "%s: size[%u]=%u\n", __func__, p, sizes[p]);
-	return 0;
-}
-
-static int vid_out_buf_out_validate(struct vb2_buffer *vb)
-{
-	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
-
-	dprintk(dev, 1, "%s\n", __func__);
-
-	if (dev->field_out != V4L2_FIELD_ALTERNATE)
-		vbuf->field = dev->field_out;
-	else if (vbuf->field != V4L2_FIELD_TOP &&
-		 vbuf->field != V4L2_FIELD_BOTTOM)
-		return -EINVAL;
-	return 0;
-}
-
-static int vid_out_buf_prepare(struct vb2_buffer *vb)
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
-	const struct vivid_fmt *vfmt = dev->fmt_out;
-	unsigned int planes = vfmt->buffers;
-	unsigned int h = dev->fmt_out_rect.height;
-	unsigned int size = dev->bytesperline_out[0] * h;
-	unsigned p;
-
-	for (p = vfmt->buffers; p < vfmt->planes; p++)
-		size += dev->bytesperline_out[p] * h / vfmt->vdownsampling[p];
-
-	dprintk(dev, 1, "%s\n", __func__);
-
-	if (WARN_ON(NULL == dev->fmt_out))
-		return -EINVAL;
-
-	if (dev->buf_prepare_error) {
-		/*
-		 * Error injection: test what happens if buf_prepare() returns
-		 * an error.
-		 */
-		dev->buf_prepare_error = false;
-		return -EINVAL;
-	}
-
-	for (p = 0; p < planes; p++) {
-		if (p)
-			size = dev->bytesperline_out[p] * h;
-		size += vb->planes[p].data_offset;
-
-		if (vb2_get_plane_payload(vb, p) < size) {
-			dprintk(dev, 1, "%s the payload is too small for plane %u (%lu < %u)\n",
-					__func__, p, vb2_get_plane_payload(vb, p), size);
-			return -EINVAL;
-		}
-	}
-
-	return 0;
-}
-
-static void vid_out_buf_queue(struct vb2_buffer *vb)
-{
-	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
-	struct vivid_buffer *buf = container_of(vbuf, struct vivid_buffer, vb);
-
-	dprintk(dev, 1, "%s\n", __func__);
-
-	spin_lock(&dev->slock);
-	list_add_tail(&buf->list, &dev->vid_out_active);
-	spin_unlock(&dev->slock);
-}
-
-static int vid_out_start_streaming(struct vb2_queue *vq, unsigned count)
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vq);
-	int err;
-
-	if (vb2_is_streaming(&dev->vb_vid_cap_q))
-		dev->can_loop_video = vivid_vid_can_loop(dev);
-
-	dev->vid_out_seq_count = 0;
-	dprintk(dev, 1, "%s\n", __func__);
-	if (dev->start_streaming_error) {
-		dev->start_streaming_error = false;
-		err = -EINVAL;
-	} else {
-		err = vivid_start_generating_vid_out(dev, &dev->vid_out_streaming);
-	}
-	if (err) {
-		struct vivid_buffer *buf, *tmp;
-
-		list_for_each_entry_safe(buf, tmp, &dev->vid_out_active, list) {
-			list_del(&buf->list);
-			vb2_buffer_done(&buf->vb.vb2_buf,
-					VB2_BUF_STATE_QUEUED);
-		}
-	}
-	return err;
-}
-
-/* abort streaming and wait for last buffer */
-static void vid_out_stop_streaming(struct vb2_queue *vq)
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vq);
-
-	dprintk(dev, 1, "%s\n", __func__);
-	vivid_stop_generating_vid_out(dev, &dev->vid_out_streaming);
-	dev->can_loop_video = false;
-}
-
-static void vid_out_buf_request_complete(struct vb2_buffer *vb)
-{
-	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
-
-	v4l2_ctrl_request_complete(vb->req_obj.req, &dev->ctrl_hdl_vid_out);
-}
-
-const struct vb2_ops vivid_vid_out_qops = {
-	.queue_setup		= vid_out_queue_setup,
-	.buf_out_validate		= vid_out_buf_out_validate,
-	.buf_prepare		= vid_out_buf_prepare,
-	.buf_queue		= vid_out_buf_queue,
-	.start_streaming	= vid_out_start_streaming,
-	.stop_streaming		= vid_out_stop_streaming,
-	.buf_request_complete	= vid_out_buf_request_complete,
-	.wait_prepare		= vb2_ops_wait_prepare,
-	.wait_finish		= vb2_ops_wait_finish,
-};
-
-/*
- * Called whenever the format has to be reset which can occur when
- * changing outputs, standard, timings, etc.
- */
-void vivid_update_format_out(struct vivid_dev *dev)
-{
-	struct v4l2_bt_timings *bt = &dev->dv_timings_out.bt;
-	unsigned size, p;
-	u64 pixelclock;
-
-	switch (dev->output_type[dev->output]) {
-	case SVID:
-	default:
-		dev->field_out = dev->tv_field_out;
-		dev->sink_rect.width = 720;
-		if (dev->std_out & V4L2_STD_525_60) {
-			dev->sink_rect.height = 480;
-			dev->timeperframe_vid_out = (struct v4l2_fract) { 1001, 30000 };
-			dev->service_set_out = V4L2_SLICED_CAPTION_525;
-		} else {
-			dev->sink_rect.height = 576;
-			dev->timeperframe_vid_out = (struct v4l2_fract) { 1000, 25000 };
-			dev->service_set_out = V4L2_SLICED_WSS_625 | V4L2_SLICED_TELETEXT_B;
-		}
-		dev->colorspace_out = V4L2_COLORSPACE_SMPTE170M;
-		break;
-	case HDMI:
-		dev->sink_rect.width = bt->width;
-		dev->sink_rect.height = bt->height;
-		size = V4L2_DV_BT_FRAME_WIDTH(bt) * V4L2_DV_BT_FRAME_HEIGHT(bt);
-
-		if (can_reduce_fps(bt) && (bt->flags & V4L2_DV_FL_REDUCED_FPS))
-			pixelclock = div_u64(bt->pixelclock * 1000, 1001);
-		else
-			pixelclock = bt->pixelclock;
-
-		dev->timeperframe_vid_out = (struct v4l2_fract) {
-			size / 100, (u32)pixelclock / 100
-		};
-		if (bt->interlaced)
-			dev->field_out = V4L2_FIELD_ALTERNATE;
-		else
-			dev->field_out = V4L2_FIELD_NONE;
-		if (!dev->dvi_d_out && (bt->flags & V4L2_DV_FL_IS_CE_VIDEO)) {
-			if (bt->width == 720 && bt->height <= 576)
-				dev->colorspace_out = V4L2_COLORSPACE_SMPTE170M;
-			else
-				dev->colorspace_out = V4L2_COLORSPACE_REC709;
-		} else {
-			dev->colorspace_out = V4L2_COLORSPACE_SRGB;
-		}
-		break;
-	}
-	dev->xfer_func_out = V4L2_XFER_FUNC_DEFAULT;
-	dev->ycbcr_enc_out = V4L2_YCBCR_ENC_DEFAULT;
-	dev->hsv_enc_out = V4L2_HSV_ENC_180;
-	dev->quantization_out = V4L2_QUANTIZATION_DEFAULT;
-	dev->compose_out = dev->sink_rect;
-	dev->compose_bounds_out = dev->sink_rect;
-	dev->crop_out = dev->compose_out;
-	if (V4L2_FIELD_HAS_T_OR_B(dev->field_out))
-		dev->crop_out.height /= 2;
-	dev->fmt_out_rect = dev->crop_out;
-	for (p = 0; p < dev->fmt_out->planes; p++)
-		dev->bytesperline_out[p] =
-			(dev->sink_rect.width * dev->fmt_out->bit_depth[p]) / 8;
-}
-
-/* Map the field to something that is valid for the current output */
-static enum v4l2_field vivid_field_out(struct vivid_dev *dev, enum v4l2_field field)
-{
-	if (vivid_is_svid_out(dev)) {
-		switch (field) {
-		case V4L2_FIELD_INTERLACED_TB:
-		case V4L2_FIELD_INTERLACED_BT:
-		case V4L2_FIELD_SEQ_TB:
-		case V4L2_FIELD_SEQ_BT:
-		case V4L2_FIELD_ALTERNATE:
-			return field;
-		case V4L2_FIELD_INTERLACED:
-		default:
-			return V4L2_FIELD_INTERLACED;
-		}
-	}
-	if (vivid_is_hdmi_out(dev))
-		return dev->dv_timings_out.bt.interlaced ? V4L2_FIELD_ALTERNATE :
-						       V4L2_FIELD_NONE;
-	return V4L2_FIELD_NONE;
-}
-
-static enum tpg_pixel_aspect vivid_get_pixel_aspect(const struct vivid_dev *dev)
-{
-	if (vivid_is_svid_out(dev))
-		return (dev->std_out & V4L2_STD_525_60) ?
-			TPG_PIXEL_ASPECT_NTSC : TPG_PIXEL_ASPECT_PAL;
-
-	if (vivid_is_hdmi_out(dev) &&
-	    dev->sink_rect.width == 720 && dev->sink_rect.height <= 576)
-		return dev->sink_rect.height == 480 ?
-			TPG_PIXEL_ASPECT_NTSC : TPG_PIXEL_ASPECT_PAL;
-
-	return TPG_PIXEL_ASPECT_SQUARE;
-}
-
-int vivid_g_fmt_vid_out(struct file *file, void *priv,
-					struct v4l2_format *f)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	struct v4l2_pix_format_mplane *mp = &f->fmt.pix_mp;
-	const struct vivid_fmt *fmt = dev->fmt_out;
-	unsigned p;
-
-	mp->width        = dev->fmt_out_rect.width;
-	mp->height       = dev->fmt_out_rect.height;
-	mp->field        = dev->field_out;
-	mp->pixelformat  = fmt->fourcc;
-	mp->colorspace   = dev->colorspace_out;
-	mp->xfer_func    = dev->xfer_func_out;
-	mp->ycbcr_enc    = dev->ycbcr_enc_out;
-	mp->quantization = dev->quantization_out;
-	mp->num_planes = fmt->buffers;
-	for (p = 0; p < mp->num_planes; p++) {
-		mp->plane_fmt[p].bytesperline = dev->bytesperline_out[p];
-		mp->plane_fmt[p].sizeimage =
-			mp->plane_fmt[p].bytesperline * mp->height +
-			fmt->data_offset[p];
-	}
-	for (p = fmt->buffers; p < fmt->planes; p++) {
-		unsigned stride = dev->bytesperline_out[p];
-
-		mp->plane_fmt[0].sizeimage +=
-			(stride * mp->height) / fmt->vdownsampling[p];
-	}
-	return 0;
-}
-
-int vivid_try_fmt_vid_out(struct file *file, void *priv,
-			struct v4l2_format *f)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	struct v4l2_bt_timings *bt = &dev->dv_timings_out.bt;
-	struct v4l2_pix_format_mplane *mp = &f->fmt.pix_mp;
-	struct v4l2_plane_pix_format *pfmt = mp->plane_fmt;
-	const struct vivid_fmt *fmt;
-	unsigned bytesperline, max_bpl;
-	unsigned factor = 1;
-	unsigned w, h;
-	unsigned p;
-
-	fmt = vivid_get_format(dev, mp->pixelformat);
-	if (!fmt) {
-		dprintk(dev, 1, "Fourcc format (0x%08x) unknown.\n",
-			mp->pixelformat);
-		mp->pixelformat = V4L2_PIX_FMT_YUYV;
-		fmt = vivid_get_format(dev, mp->pixelformat);
-	}
-
-	mp->field = vivid_field_out(dev, mp->field);
-	if (vivid_is_svid_out(dev)) {
-		w = 720;
-		h = (dev->std_out & V4L2_STD_525_60) ? 480 : 576;
-	} else {
-		w = dev->sink_rect.width;
-		h = dev->sink_rect.height;
-	}
-	if (V4L2_FIELD_HAS_T_OR_B(mp->field))
-		factor = 2;
-	if (!dev->has_scaler_out && !dev->has_crop_out && !dev->has_compose_out) {
-		mp->width = w;
-		mp->height = h / factor;
-	} else {
-		struct v4l2_rect r = { 0, 0, mp->width, mp->height * factor };
-
-		v4l2_rect_set_min_size(&r, &vivid_min_rect);
-		v4l2_rect_set_max_size(&r, &vivid_max_rect);
-		if (dev->has_scaler_out && !dev->has_crop_out) {
-			struct v4l2_rect max_r = { 0, 0, MAX_ZOOM * w, MAX_ZOOM * h };
-
-			v4l2_rect_set_max_size(&r, &max_r);
-		} else if (!dev->has_scaler_out && dev->has_compose_out && !dev->has_crop_out) {
-			v4l2_rect_set_max_size(&r, &dev->sink_rect);
-		} else if (!dev->has_scaler_out && !dev->has_compose_out) {
-			v4l2_rect_set_min_size(&r, &dev->sink_rect);
-		}
-		mp->width = r.width;
-		mp->height = r.height / factor;
-	}
-
-	/* This driver supports custom bytesperline values */
-
-	mp->num_planes = fmt->buffers;
-	for (p = 0; p < fmt->buffers; p++) {
-		/* Calculate the minimum supported bytesperline value */
-		bytesperline = (mp->width * fmt->bit_depth[p]) >> 3;
-		/* Calculate the maximum supported bytesperline value */
-		max_bpl = (MAX_ZOOM * MAX_WIDTH * fmt->bit_depth[p]) >> 3;
-
-		if (pfmt[p].bytesperline > max_bpl)
-			pfmt[p].bytesperline = max_bpl;
-		if (pfmt[p].bytesperline < bytesperline)
-			pfmt[p].bytesperline = bytesperline;
-
-		pfmt[p].sizeimage = (pfmt[p].bytesperline * mp->height) /
-				fmt->vdownsampling[p] + fmt->data_offset[p];
-
-		memset(pfmt[p].reserved, 0, sizeof(pfmt[p].reserved));
-	}
-	for (p = fmt->buffers; p < fmt->planes; p++)
-		pfmt[0].sizeimage += (pfmt[0].bytesperline * mp->height *
-			(fmt->bit_depth[p] / fmt->vdownsampling[p])) /
-			(fmt->bit_depth[0] / fmt->vdownsampling[0]);
-
-	mp->xfer_func = V4L2_XFER_FUNC_DEFAULT;
-	mp->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
-	mp->quantization = V4L2_QUANTIZATION_DEFAULT;
-	if (vivid_is_svid_out(dev)) {
-		mp->colorspace = V4L2_COLORSPACE_SMPTE170M;
-	} else if (dev->dvi_d_out || !(bt->flags & V4L2_DV_FL_IS_CE_VIDEO)) {
-		mp->colorspace = V4L2_COLORSPACE_SRGB;
-		if (dev->dvi_d_out)
-			mp->quantization = V4L2_QUANTIZATION_LIM_RANGE;
-	} else if (bt->width == 720 && bt->height <= 576) {
-		mp->colorspace = V4L2_COLORSPACE_SMPTE170M;
-	} else if (mp->colorspace != V4L2_COLORSPACE_SMPTE170M &&
-		   mp->colorspace != V4L2_COLORSPACE_REC709 &&
-		   mp->colorspace != V4L2_COLORSPACE_OPRGB &&
-		   mp->colorspace != V4L2_COLORSPACE_BT2020 &&
-		   mp->colorspace != V4L2_COLORSPACE_SRGB) {
-		mp->colorspace = V4L2_COLORSPACE_REC709;
-	}
-	memset(mp->reserved, 0, sizeof(mp->reserved));
-	return 0;
-}
-
-int vivid_s_fmt_vid_out(struct file *file, void *priv,
-					struct v4l2_format *f)
-{
-	struct v4l2_pix_format_mplane *mp = &f->fmt.pix_mp;
-	struct vivid_dev *dev = video_drvdata(file);
-	struct v4l2_rect *crop = &dev->crop_out;
-	struct v4l2_rect *compose = &dev->compose_out;
-	struct vb2_queue *q = &dev->vb_vid_out_q;
-	int ret = vivid_try_fmt_vid_out(file, priv, f);
-	unsigned factor = 1;
-	unsigned p;
-
-	if (ret < 0)
-		return ret;
-
-	if (vb2_is_busy(q) &&
-	    (vivid_is_svid_out(dev) ||
-	     mp->width != dev->fmt_out_rect.width ||
-	     mp->height != dev->fmt_out_rect.height ||
-	     mp->pixelformat != dev->fmt_out->fourcc ||
-	     mp->field != dev->field_out)) {
-		dprintk(dev, 1, "%s device busy\n", __func__);
-		return -EBUSY;
-	}
-
-	/*
-	 * Allow for changing the colorspace on the fly. Useful for testing
-	 * purposes, and it is something that HDMI transmitters are able
-	 * to do.
-	 */
-	if (vb2_is_busy(q))
-		goto set_colorspace;
-
-	dev->fmt_out = vivid_get_format(dev, mp->pixelformat);
-	if (V4L2_FIELD_HAS_T_OR_B(mp->field))
-		factor = 2;
-
-	if (dev->has_scaler_out || dev->has_crop_out || dev->has_compose_out) {
-		struct v4l2_rect r = { 0, 0, mp->width, mp->height };
-
-		if (dev->has_scaler_out) {
-			if (dev->has_crop_out)
-				v4l2_rect_map_inside(crop, &r);
-			else
-				*crop = r;
-			if (dev->has_compose_out && !dev->has_crop_out) {
-				struct v4l2_rect min_r = {
-					0, 0,
-					r.width / MAX_ZOOM,
-					factor * r.height / MAX_ZOOM
-				};
-				struct v4l2_rect max_r = {
-					0, 0,
-					r.width * MAX_ZOOM,
-					factor * r.height * MAX_ZOOM
-				};
-
-				v4l2_rect_set_min_size(compose, &min_r);
-				v4l2_rect_set_max_size(compose, &max_r);
-				v4l2_rect_map_inside(compose, &dev->compose_bounds_out);
-			} else if (dev->has_compose_out) {
-				struct v4l2_rect min_r = {
-					0, 0,
-					crop->width / MAX_ZOOM,
-					factor * crop->height / MAX_ZOOM
-				};
-				struct v4l2_rect max_r = {
-					0, 0,
-					crop->width * MAX_ZOOM,
-					factor * crop->height * MAX_ZOOM
-				};
-
-				v4l2_rect_set_min_size(compose, &min_r);
-				v4l2_rect_set_max_size(compose, &max_r);
-				v4l2_rect_map_inside(compose, &dev->compose_bounds_out);
-			}
-		} else if (dev->has_compose_out && !dev->has_crop_out) {
-			v4l2_rect_set_size_to(crop, &r);
-			r.height *= factor;
-			v4l2_rect_set_size_to(compose, &r);
-			v4l2_rect_map_inside(compose, &dev->compose_bounds_out);
-		} else if (!dev->has_compose_out) {
-			v4l2_rect_map_inside(crop, &r);
-			r.height /= factor;
-			v4l2_rect_set_size_to(compose, &r);
-		} else {
-			r.height *= factor;
-			v4l2_rect_set_max_size(compose, &r);
-			v4l2_rect_map_inside(compose, &dev->compose_bounds_out);
-			crop->top *= factor;
-			crop->height *= factor;
-			v4l2_rect_set_size_to(crop, compose);
-			v4l2_rect_map_inside(crop, &r);
-			crop->top /= factor;
-			crop->height /= factor;
-		}
-	} else {
-		struct v4l2_rect r = { 0, 0, mp->width, mp->height };
-
-		v4l2_rect_set_size_to(crop, &r);
-		r.height /= factor;
-		v4l2_rect_set_size_to(compose, &r);
-	}
-
-	dev->fmt_out_rect.width = mp->width;
-	dev->fmt_out_rect.height = mp->height;
-	for (p = 0; p < mp->num_planes; p++)
-		dev->bytesperline_out[p] = mp->plane_fmt[p].bytesperline;
-	for (p = dev->fmt_out->buffers; p < dev->fmt_out->planes; p++)
-		dev->bytesperline_out[p] =
-			(dev->bytesperline_out[0] * dev->fmt_out->bit_depth[p]) /
-			dev->fmt_out->bit_depth[0];
-	dev->field_out = mp->field;
-	if (vivid_is_svid_out(dev))
-		dev->tv_field_out = mp->field;
-
-set_colorspace:
-	dev->colorspace_out = mp->colorspace;
-	dev->xfer_func_out = mp->xfer_func;
-	dev->ycbcr_enc_out = mp->ycbcr_enc;
-	dev->quantization_out = mp->quantization;
-	if (dev->loop_video) {
-		vivid_send_source_change(dev, SVID);
-		vivid_send_source_change(dev, HDMI);
-	}
-	return 0;
-}
-
-int vidioc_g_fmt_vid_out_mplane(struct file *file, void *priv,
-					struct v4l2_format *f)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (!dev->multiplanar)
-		return -ENOTTY;
-	return vivid_g_fmt_vid_out(file, priv, f);
-}
-
-int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv,
-			struct v4l2_format *f)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (!dev->multiplanar)
-		return -ENOTTY;
-	return vivid_try_fmt_vid_out(file, priv, f);
-}
-
-int vidioc_s_fmt_vid_out_mplane(struct file *file, void *priv,
-			struct v4l2_format *f)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (!dev->multiplanar)
-		return -ENOTTY;
-	return vivid_s_fmt_vid_out(file, priv, f);
-}
-
-int vidioc_g_fmt_vid_out(struct file *file, void *priv,
-					struct v4l2_format *f)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (dev->multiplanar)
-		return -ENOTTY;
-	return fmt_sp2mp_func(file, priv, f, vivid_g_fmt_vid_out);
-}
-
-int vidioc_try_fmt_vid_out(struct file *file, void *priv,
-			struct v4l2_format *f)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (dev->multiplanar)
-		return -ENOTTY;
-	return fmt_sp2mp_func(file, priv, f, vivid_try_fmt_vid_out);
-}
-
-int vidioc_s_fmt_vid_out(struct file *file, void *priv,
-			struct v4l2_format *f)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (dev->multiplanar)
-		return -ENOTTY;
-	return fmt_sp2mp_func(file, priv, f, vivid_s_fmt_vid_out);
-}
-
-int vivid_vid_out_g_selection(struct file *file, void *priv,
-			      struct v4l2_selection *sel)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (!dev->has_crop_out && !dev->has_compose_out)
-		return -ENOTTY;
-	if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
-		return -EINVAL;
-
-	sel->r.left = sel->r.top = 0;
-	switch (sel->target) {
-	case V4L2_SEL_TGT_CROP:
-		if (!dev->has_crop_out)
-			return -EINVAL;
-		sel->r = dev->crop_out;
-		break;
-	case V4L2_SEL_TGT_CROP_DEFAULT:
-		if (!dev->has_crop_out)
-			return -EINVAL;
-		sel->r = dev->fmt_out_rect;
-		break;
-	case V4L2_SEL_TGT_CROP_BOUNDS:
-		if (!dev->has_crop_out)
-			return -EINVAL;
-		sel->r = vivid_max_rect;
-		break;
-	case V4L2_SEL_TGT_COMPOSE:
-		if (!dev->has_compose_out)
-			return -EINVAL;
-		sel->r = dev->compose_out;
-		break;
-	case V4L2_SEL_TGT_COMPOSE_DEFAULT:
-	case V4L2_SEL_TGT_COMPOSE_BOUNDS:
-		if (!dev->has_compose_out)
-			return -EINVAL;
-		sel->r = dev->sink_rect;
-		break;
-	default:
-		return -EINVAL;
-	}
-	return 0;
-}
-
-int vivid_vid_out_s_selection(struct file *file, void *fh, struct v4l2_selection *s)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	struct v4l2_rect *crop = &dev->crop_out;
-	struct v4l2_rect *compose = &dev->compose_out;
-	unsigned factor = V4L2_FIELD_HAS_T_OR_B(dev->field_out) ? 2 : 1;
-	int ret;
-
-	if (!dev->has_crop_out && !dev->has_compose_out)
-		return -ENOTTY;
-	if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
-		return -EINVAL;
-
-	switch (s->target) {
-	case V4L2_SEL_TGT_CROP:
-		if (!dev->has_crop_out)
-			return -EINVAL;
-		ret = vivid_vid_adjust_sel(s->flags, &s->r);
-		if (ret)
-			return ret;
-		v4l2_rect_set_min_size(&s->r, &vivid_min_rect);
-		v4l2_rect_set_max_size(&s->r, &dev->fmt_out_rect);
-		if (dev->has_scaler_out) {
-			struct v4l2_rect max_rect = {
-				0, 0,
-				dev->sink_rect.width * MAX_ZOOM,
-				(dev->sink_rect.height / factor) * MAX_ZOOM
-			};
-
-			v4l2_rect_set_max_size(&s->r, &max_rect);
-			if (dev->has_compose_out) {
-				struct v4l2_rect min_rect = {
-					0, 0,
-					s->r.width / MAX_ZOOM,
-					(s->r.height * factor) / MAX_ZOOM
-				};
-				struct v4l2_rect max_rect = {
-					0, 0,
-					s->r.width * MAX_ZOOM,
-					(s->r.height * factor) * MAX_ZOOM
-				};
-
-				v4l2_rect_set_min_size(compose, &min_rect);
-				v4l2_rect_set_max_size(compose, &max_rect);
-				v4l2_rect_map_inside(compose, &dev->compose_bounds_out);
-			}
-		} else if (dev->has_compose_out) {
-			s->r.top *= factor;
-			s->r.height *= factor;
-			v4l2_rect_set_max_size(&s->r, &dev->sink_rect);
-			v4l2_rect_set_size_to(compose, &s->r);
-			v4l2_rect_map_inside(compose, &dev->compose_bounds_out);
-			s->r.top /= factor;
-			s->r.height /= factor;
-		} else {
-			v4l2_rect_set_size_to(&s->r, &dev->sink_rect);
-			s->r.height /= factor;
-		}
-		v4l2_rect_map_inside(&s->r, &dev->fmt_out_rect);
-		*crop = s->r;
-		break;
-	case V4L2_SEL_TGT_COMPOSE:
-		if (!dev->has_compose_out)
-			return -EINVAL;
-		ret = vivid_vid_adjust_sel(s->flags, &s->r);
-		if (ret)
-			return ret;
-		v4l2_rect_set_min_size(&s->r, &vivid_min_rect);
-		v4l2_rect_set_max_size(&s->r, &dev->sink_rect);
-		v4l2_rect_map_inside(&s->r, &dev->compose_bounds_out);
-		s->r.top /= factor;
-		s->r.height /= factor;
-		if (dev->has_scaler_out) {
-			struct v4l2_rect fmt = dev->fmt_out_rect;
-			struct v4l2_rect max_rect = {
-				0, 0,
-				s->r.width * MAX_ZOOM,
-				s->r.height * MAX_ZOOM
-			};
-			struct v4l2_rect min_rect = {
-				0, 0,
-				s->r.width / MAX_ZOOM,
-				s->r.height / MAX_ZOOM
-			};
-
-			v4l2_rect_set_min_size(&fmt, &min_rect);
-			if (!dev->has_crop_out)
-				v4l2_rect_set_max_size(&fmt, &max_rect);
-			if (!v4l2_rect_same_size(&dev->fmt_out_rect, &fmt) &&
-			    vb2_is_busy(&dev->vb_vid_out_q))
-				return -EBUSY;
-			if (dev->has_crop_out) {
-				v4l2_rect_set_min_size(crop, &min_rect);
-				v4l2_rect_set_max_size(crop, &max_rect);
-			}
-			dev->fmt_out_rect = fmt;
-		} else if (dev->has_crop_out) {
-			struct v4l2_rect fmt = dev->fmt_out_rect;
-
-			v4l2_rect_set_min_size(&fmt, &s->r);
-			if (!v4l2_rect_same_size(&dev->fmt_out_rect, &fmt) &&
-			    vb2_is_busy(&dev->vb_vid_out_q))
-				return -EBUSY;
-			dev->fmt_out_rect = fmt;
-			v4l2_rect_set_size_to(crop, &s->r);
-			v4l2_rect_map_inside(crop, &dev->fmt_out_rect);
-		} else {
-			if (!v4l2_rect_same_size(&s->r, &dev->fmt_out_rect) &&
-			    vb2_is_busy(&dev->vb_vid_out_q))
-				return -EBUSY;
-			v4l2_rect_set_size_to(&dev->fmt_out_rect, &s->r);
-			v4l2_rect_set_size_to(crop, &s->r);
-			crop->height /= factor;
-			v4l2_rect_map_inside(crop, &dev->fmt_out_rect);
-		}
-		s->r.top *= factor;
-		s->r.height *= factor;
-		if (dev->bitmap_out && (compose->width != s->r.width ||
-					compose->height != s->r.height)) {
-			vfree(dev->bitmap_out);
-			dev->bitmap_out = NULL;
-		}
-		*compose = s->r;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-int vivid_vid_out_g_pixelaspect(struct file *file, void *priv,
-				int type, struct v4l2_fract *f)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
-		return -EINVAL;
-
-	switch (vivid_get_pixel_aspect(dev)) {
-	case TPG_PIXEL_ASPECT_NTSC:
-		f->numerator = 11;
-		f->denominator = 10;
-		break;
-	case TPG_PIXEL_ASPECT_PAL:
-		f->numerator = 54;
-		f->denominator = 59;
-		break;
-	default:
-		break;
-	}
-	return 0;
-}
-
-int vidioc_g_fmt_vid_out_overlay(struct file *file, void *priv,
-					struct v4l2_format *f)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	const struct v4l2_rect *compose = &dev->compose_out;
-	struct v4l2_window *win = &f->fmt.win;
-	unsigned clipcount = win->clipcount;
-
-	if (!dev->has_fb)
-		return -EINVAL;
-	win->w.top = dev->overlay_out_top;
-	win->w.left = dev->overlay_out_left;
-	win->w.width = compose->width;
-	win->w.height = compose->height;
-	win->clipcount = dev->clipcount_out;
-	win->field = V4L2_FIELD_ANY;
-	win->chromakey = dev->chromakey_out;
-	win->global_alpha = dev->global_alpha_out;
-	if (clipcount > dev->clipcount_out)
-		clipcount = dev->clipcount_out;
-	if (dev->bitmap_out == NULL)
-		win->bitmap = NULL;
-	else if (win->bitmap) {
-		if (copy_to_user(win->bitmap, dev->bitmap_out,
-		    ((dev->compose_out.width + 7) / 8) * dev->compose_out.height))
-			return -EFAULT;
-	}
-	if (clipcount && win->clips) {
-		if (copy_to_user(win->clips, dev->clips_out,
-				 clipcount * sizeof(dev->clips_out[0])))
-			return -EFAULT;
-	}
-	return 0;
-}
-
-int vidioc_try_fmt_vid_out_overlay(struct file *file, void *priv,
-					struct v4l2_format *f)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	const struct v4l2_rect *compose = &dev->compose_out;
-	struct v4l2_window *win = &f->fmt.win;
-	int i, j;
-
-	if (!dev->has_fb)
-		return -EINVAL;
-	win->w.left = clamp_t(int, win->w.left,
-			      -dev->display_width, dev->display_width);
-	win->w.top = clamp_t(int, win->w.top,
-			     -dev->display_height, dev->display_height);
-	win->w.width = compose->width;
-	win->w.height = compose->height;
-	/*
-	 * It makes no sense for an OSD to overlay only top or bottom fields,
-	 * so always set this to ANY.
-	 */
-	win->field = V4L2_FIELD_ANY;
-	if (win->clipcount && !win->clips)
-		win->clipcount = 0;
-	if (win->clipcount > MAX_CLIPS)
-		win->clipcount = MAX_CLIPS;
-	if (win->clipcount) {
-		if (copy_from_user(dev->try_clips_out, win->clips,
-				   win->clipcount * sizeof(dev->clips_out[0])))
-			return -EFAULT;
-		for (i = 0; i < win->clipcount; i++) {
-			struct v4l2_rect *r = &dev->try_clips_out[i].c;
-
-			r->top = clamp_t(s32, r->top, 0, dev->display_height - 1);
-			r->height = clamp_t(s32, r->height, 1, dev->display_height - r->top);
-			r->left = clamp_t(u32, r->left, 0, dev->display_width - 1);
-			r->width = clamp_t(u32, r->width, 1, dev->display_width - r->left);
-		}
-		/*
-		 * Yeah, so sue me, it's an O(n^2) algorithm. But n is a small
-		 * number and it's typically a one-time deal.
-		 */
-		for (i = 0; i < win->clipcount - 1; i++) {
-			struct v4l2_rect *r1 = &dev->try_clips_out[i].c;
-
-			for (j = i + 1; j < win->clipcount; j++) {
-				struct v4l2_rect *r2 = &dev->try_clips_out[j].c;
-
-				if (v4l2_rect_overlap(r1, r2))
-					return -EINVAL;
-			}
-		}
-		if (copy_to_user(win->clips, dev->try_clips_out,
-				 win->clipcount * sizeof(dev->clips_out[0])))
-			return -EFAULT;
-	}
-	return 0;
-}
-
-int vidioc_s_fmt_vid_out_overlay(struct file *file, void *priv,
-					struct v4l2_format *f)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	const struct v4l2_rect *compose = &dev->compose_out;
-	struct v4l2_window *win = &f->fmt.win;
-	int ret = vidioc_try_fmt_vid_out_overlay(file, priv, f);
-	unsigned bitmap_size = ((compose->width + 7) / 8) * compose->height;
-	unsigned clips_size = win->clipcount * sizeof(dev->clips_out[0]);
-	void *new_bitmap = NULL;
-
-	if (ret)
-		return ret;
-
-	if (win->bitmap) {
-		new_bitmap = vzalloc(bitmap_size);
-
-		if (!new_bitmap)
-			return -ENOMEM;
-		if (copy_from_user(new_bitmap, win->bitmap, bitmap_size)) {
-			vfree(new_bitmap);
-			return -EFAULT;
-		}
-	}
-
-	dev->overlay_out_top = win->w.top;
-	dev->overlay_out_left = win->w.left;
-	vfree(dev->bitmap_out);
-	dev->bitmap_out = new_bitmap;
-	dev->clipcount_out = win->clipcount;
-	if (dev->clipcount_out)
-		memcpy(dev->clips_out, dev->try_clips_out, clips_size);
-	dev->chromakey_out = win->chromakey;
-	dev->global_alpha_out = win->global_alpha;
-	return ret;
-}
-
-int vivid_vid_out_overlay(struct file *file, void *fh, unsigned i)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (i && !dev->fmt_out->can_do_overlay) {
-		dprintk(dev, 1, "unsupported output format for output overlay\n");
-		return -EINVAL;
-	}
-
-	dev->overlay_out_enabled = i;
-	return 0;
-}
-
-int vivid_vid_out_g_fbuf(struct file *file, void *fh,
-				struct v4l2_framebuffer *a)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	a->capability = V4L2_FBUF_CAP_EXTERNOVERLAY |
-			V4L2_FBUF_CAP_BITMAP_CLIPPING |
-			V4L2_FBUF_CAP_LIST_CLIPPING |
-			V4L2_FBUF_CAP_CHROMAKEY |
-			V4L2_FBUF_CAP_SRC_CHROMAKEY |
-			V4L2_FBUF_CAP_GLOBAL_ALPHA |
-			V4L2_FBUF_CAP_LOCAL_ALPHA |
-			V4L2_FBUF_CAP_LOCAL_INV_ALPHA;
-	a->flags = V4L2_FBUF_FLAG_OVERLAY | dev->fbuf_out_flags;
-	a->base = (void *)dev->video_pbase;
-	a->fmt.width = dev->display_width;
-	a->fmt.height = dev->display_height;
-	if (dev->fb_defined.green.length == 5)
-		a->fmt.pixelformat = V4L2_PIX_FMT_ARGB555;
-	else
-		a->fmt.pixelformat = V4L2_PIX_FMT_RGB565;
-	a->fmt.bytesperline = dev->display_byte_stride;
-	a->fmt.sizeimage = a->fmt.height * a->fmt.bytesperline;
-	a->fmt.field = V4L2_FIELD_NONE;
-	a->fmt.colorspace = V4L2_COLORSPACE_SRGB;
-	a->fmt.priv = 0;
-	return 0;
-}
-
-int vivid_vid_out_s_fbuf(struct file *file, void *fh,
-				const struct v4l2_framebuffer *a)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	const unsigned chroma_flags = V4L2_FBUF_FLAG_CHROMAKEY |
-				      V4L2_FBUF_FLAG_SRC_CHROMAKEY;
-	const unsigned alpha_flags = V4L2_FBUF_FLAG_GLOBAL_ALPHA |
-				     V4L2_FBUF_FLAG_LOCAL_ALPHA |
-				     V4L2_FBUF_FLAG_LOCAL_INV_ALPHA;
-
-
-	if ((a->flags & chroma_flags) == chroma_flags)
-		return -EINVAL;
-	switch (a->flags & alpha_flags) {
-	case 0:
-	case V4L2_FBUF_FLAG_GLOBAL_ALPHA:
-	case V4L2_FBUF_FLAG_LOCAL_ALPHA:
-	case V4L2_FBUF_FLAG_LOCAL_INV_ALPHA:
-		break;
-	default:
-		return -EINVAL;
-	}
-	dev->fbuf_out_flags &= ~(chroma_flags | alpha_flags);
-	dev->fbuf_out_flags = a->flags & (chroma_flags | alpha_flags);
-	return 0;
-}
-
-static const struct v4l2_audioout vivid_audio_outputs[] = {
-	{ 0, "Line-Out 1" },
-	{ 1, "Line-Out 2" },
-};
-
-int vidioc_enum_output(struct file *file, void *priv,
-				struct v4l2_output *out)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (out->index >= dev->num_outputs)
-		return -EINVAL;
-
-	out->type = V4L2_OUTPUT_TYPE_ANALOG;
-	switch (dev->output_type[out->index]) {
-	case SVID:
-		snprintf(out->name, sizeof(out->name), "S-Video %u",
-				dev->output_name_counter[out->index]);
-		out->std = V4L2_STD_ALL;
-		if (dev->has_audio_outputs)
-			out->audioset = (1 << ARRAY_SIZE(vivid_audio_outputs)) - 1;
-		out->capabilities = V4L2_OUT_CAP_STD;
-		break;
-	case HDMI:
-		snprintf(out->name, sizeof(out->name), "HDMI %u",
-				dev->output_name_counter[out->index]);
-		out->capabilities = V4L2_OUT_CAP_DV_TIMINGS;
-		break;
-	}
-	return 0;
-}
-
-int vidioc_g_output(struct file *file, void *priv, unsigned *o)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	*o = dev->output;
-	return 0;
-}
-
-int vidioc_s_output(struct file *file, void *priv, unsigned o)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (o >= dev->num_outputs)
-		return -EINVAL;
-
-	if (o == dev->output)
-		return 0;
-
-	if (vb2_is_busy(&dev->vb_vid_out_q) ||
-	    vb2_is_busy(&dev->vb_vbi_out_q) ||
-	    vb2_is_busy(&dev->vb_meta_out_q))
-		return -EBUSY;
-
-	dev->output = o;
-	dev->tv_audio_output = 0;
-	if (dev->output_type[o] == SVID)
-		dev->vid_out_dev.tvnorms = V4L2_STD_ALL;
-	else
-		dev->vid_out_dev.tvnorms = 0;
-
-	dev->vbi_out_dev.tvnorms = dev->vid_out_dev.tvnorms;
-	dev->meta_out_dev.tvnorms = dev->vid_out_dev.tvnorms;
-	vivid_update_format_out(dev);
-
-	v4l2_ctrl_activate(dev->ctrl_display_present, vivid_is_hdmi_out(dev));
-	if (vivid_is_hdmi_out(dev))
-		v4l2_ctrl_s_ctrl(dev->ctrl_display_present,
-				 dev->display_present[dev->output]);
-
-	return 0;
-}
-
-int vidioc_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vout)
-{
-	if (vout->index >= ARRAY_SIZE(vivid_audio_outputs))
-		return -EINVAL;
-	*vout = vivid_audio_outputs[vout->index];
-	return 0;
-}
-
-int vidioc_g_audout(struct file *file, void *fh, struct v4l2_audioout *vout)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (!vivid_is_svid_out(dev))
-		return -EINVAL;
-	*vout = vivid_audio_outputs[dev->tv_audio_output];
-	return 0;
-}
-
-int vidioc_s_audout(struct file *file, void *fh, const struct v4l2_audioout *vout)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (!vivid_is_svid_out(dev))
-		return -EINVAL;
-	if (vout->index >= ARRAY_SIZE(vivid_audio_outputs))
-		return -EINVAL;
-	dev->tv_audio_output = vout->index;
-	return 0;
-}
-
-int vivid_vid_out_s_std(struct file *file, void *priv, v4l2_std_id id)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (!vivid_is_svid_out(dev))
-		return -ENODATA;
-	if (dev->std_out == id)
-		return 0;
-	if (vb2_is_busy(&dev->vb_vid_out_q) || vb2_is_busy(&dev->vb_vbi_out_q))
-		return -EBUSY;
-	dev->std_out = id;
-	vivid_update_format_out(dev);
-	return 0;
-}
-
-static bool valid_cvt_gtf_timings(struct v4l2_dv_timings *timings)
-{
-	struct v4l2_bt_timings *bt = &timings->bt;
-
-	if ((bt->standards & (V4L2_DV_BT_STD_CVT | V4L2_DV_BT_STD_GTF)) &&
-	    v4l2_valid_dv_timings(timings, &vivid_dv_timings_cap, NULL, NULL))
-		return true;
-
-	return false;
-}
-
-int vivid_vid_out_s_dv_timings(struct file *file, void *_fh,
-				    struct v4l2_dv_timings *timings)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-	if (!vivid_is_hdmi_out(dev))
-		return -ENODATA;
-	if (!v4l2_find_dv_timings_cap(timings, &vivid_dv_timings_cap,
-				0, NULL, NULL) &&
-	    !valid_cvt_gtf_timings(timings))
-		return -EINVAL;
-	if (v4l2_match_dv_timings(timings, &dev->dv_timings_out, 0, true))
-		return 0;
-	if (vb2_is_busy(&dev->vb_vid_out_q))
-		return -EBUSY;
-	dev->dv_timings_out = *timings;
-	vivid_update_format_out(dev);
-	return 0;
-}
-
-int vivid_vid_out_g_parm(struct file *file, void *priv,
-			  struct v4l2_streamparm *parm)
-{
-	struct vivid_dev *dev = video_drvdata(file);
-
-	if (parm->type != (dev->multiplanar ?
-			   V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE :
-			   V4L2_BUF_TYPE_VIDEO_OUTPUT))
-		return -EINVAL;
-
-	parm->parm.output.capability   = V4L2_CAP_TIMEPERFRAME;
-	parm->parm.output.timeperframe = dev->timeperframe_vid_out;
-	parm->parm.output.writebuffers  = 1;
-
-	return 0;
-}
-
-int vidioc_subscribe_event(struct v4l2_fh *fh,
-			const struct v4l2_event_subscription *sub)
-{
-	switch (sub->type) {
-	case V4L2_EVENT_SOURCE_CHANGE:
-		if (fh->vdev->vfl_dir == VFL_DIR_RX)
-			return v4l2_src_change_event_subscribe(fh, sub);
-		break;
-	default:
-		return v4l2_ctrl_subscribe_event(fh, sub);
-	}
-	return -EINVAL;
-}
diff --git a/drivers/media/platform/vivid/vivid-vid-out.h b/drivers/media/platform/vivid/vivid-vid-out.h
deleted file mode 100644
index 8d56314f4ea1..000000000000
--- a/drivers/media/platform/vivid/vivid-vid-out.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * vivid-vid-out.h - video output support functions.
- *
- * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#ifndef _VIVID_VID_OUT_H_
-#define _VIVID_VID_OUT_H_
-
-extern const struct vb2_ops vivid_vid_out_qops;
-
-void vivid_update_format_out(struct vivid_dev *dev);
-
-int vivid_g_fmt_vid_out(struct file *file, void *priv, struct v4l2_format *f);
-int vivid_try_fmt_vid_out(struct file *file, void *priv, struct v4l2_format *f);
-int vivid_s_fmt_vid_out(struct file *file, void *priv, struct v4l2_format *f);
-int vidioc_g_fmt_vid_out_mplane(struct file *file, void *priv, struct v4l2_format *f);
-int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv, struct v4l2_format *f);
-int vidioc_s_fmt_vid_out_mplane(struct file *file, void *priv, struct v4l2_format *f);
-int vidioc_g_fmt_vid_out(struct file *file, void *priv, struct v4l2_format *f);
-int vidioc_try_fmt_vid_out(struct file *file, void *priv, struct v4l2_format *f);
-int vidioc_s_fmt_vid_out(struct file *file, void *priv, struct v4l2_format *f);
-int vivid_vid_out_g_selection(struct file *file, void *priv, struct v4l2_selection *sel);
-int vivid_vid_out_s_selection(struct file *file, void *fh, struct v4l2_selection *s);
-int vivid_vid_out_g_pixelaspect(struct file *file, void *priv, int type, struct v4l2_fract *f);
-int vidioc_enum_fmt_vid_out_overlay(struct file *file, void  *priv, struct v4l2_fmtdesc *f);
-int vidioc_g_fmt_vid_out_overlay(struct file *file, void *priv, struct v4l2_format *f);
-int vidioc_try_fmt_vid_out_overlay(struct file *file, void *priv, struct v4l2_format *f);
-int vidioc_s_fmt_vid_out_overlay(struct file *file, void *priv, struct v4l2_format *f);
-int vivid_vid_out_overlay(struct file *file, void *fh, unsigned i);
-int vivid_vid_out_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *a);
-int vivid_vid_out_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffer *a);
-int vidioc_enum_output(struct file *file, void *priv, struct v4l2_output *out);
-int vidioc_g_output(struct file *file, void *priv, unsigned *i);
-int vidioc_s_output(struct file *file, void *priv, unsigned i);
-int vidioc_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vout);
-int vidioc_g_audout(struct file *file, void *fh, struct v4l2_audioout *vout);
-int vidioc_s_audout(struct file *file, void *fh, const struct v4l2_audioout *vout);
-int vivid_vid_out_s_std(struct file *file, void *priv, v4l2_std_id id);
-int vivid_vid_out_s_dv_timings(struct file *file, void *_fh, struct v4l2_dv_timings *timings);
-int vivid_vid_out_g_parm(struct file *file, void *priv, struct v4l2_streamparm *parm);
-
-#endif
diff --git a/drivers/media/platform/xilinx/Kconfig b/drivers/media/platform/xilinx/Kconfig
index a2773ad7c185..01c96fb66414 100644
--- a/drivers/media/platform/xilinx/Kconfig
+++ b/drivers/media/platform/xilinx/Kconfig
@@ -2,7 +2,9 @@
 
 config VIDEO_XILINX
 	tristate "Xilinx Video IP (EXPERIMENTAL)"
-	depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF && HAS_DMA
+	depends on VIDEO_V4L2  && OF && HAS_DMA
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select VIDEOBUF2_DMA_CONTIG
 	select V4L2_FWNODE
 	help
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index eb79d99787bd..d29e29645e04 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -36,7 +36,7 @@ config RADIO_SI476X
 	  In order to control your radio card, you will need to use programs
 	  that are compatible with the Video For Linux 2 API.  Information on
 	  this API and pointers to "v4l2" programs may be found at
-	  <file:Documentation/media/media_uapi.rst>.
+	  <file:Documentation/userspace-api/media/index.rst>.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called radio-si476x.
@@ -76,7 +76,7 @@ config RADIO_MAXIRADIO
 	  In order to control your radio card, you will need to use programs
 	  that are compatible with the Video For Linux API.  Information on
 	  this API and pointers to "v4l" programs may be found at
-	  <file:Documentation/media/media_uapi.rst>.
+	  <file:Documentation/userspace-api/media/index.rst>.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called radio-maxiradio.
@@ -94,7 +94,7 @@ config RADIO_SHARK
 	  In order to control your radio card, you will need to use programs
 	  that are compatible with the Video For Linux API.  Information on
 	  this API and pointers to "v4l" programs may be found at
-	  <file:Documentation/media/media_uapi.rst>.
+	  <file:Documentation/userspace-api/media/index.rst>.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called radio-shark.
@@ -111,7 +111,7 @@ config RADIO_SHARK2
 	  In order to control your radio card, you will need to use programs
 	  that are compatible with the Video For Linux API.  Information on
 	  this API and pointers to "v4l" programs may be found at
-	  <file:Documentation/media/media_uapi.rst>.
+	  <file:Documentation/userspace-api/media/index.rst>.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called radio-shark2.
@@ -218,7 +218,7 @@ config RADIO_WL1273
 	  In order to control your radio card, you will need to use programs
 	  that are compatible with the Video For Linux 2 API.  Information on
 	  this API and pointers to "v4l2" programs may be found at
-	  <file:Documentation/media/media_uapi.rst>.
+	  <file:Documentation/userspace-api/media/index.rst>.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called radio-wl1273.
@@ -272,7 +272,7 @@ config RADIO_RTRACK
 	  been reported to be used by these cards.
 
 	  More information is contained in the file
-	  <file:Documentation/media/v4l-drivers/radiotrack.rst>.
+	  <file:Documentation/driver-api/media/drivers/radiotrack.rst>.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called radio-aimslab.
diff --git a/drivers/media/radio/si470x/Kconfig b/drivers/media/radio/si470x/Kconfig
index a1ba8bc54b62..7161bd6cd13c 100644
--- a/drivers/media/radio/si470x/Kconfig
+++ b/drivers/media/radio/si470x/Kconfig
@@ -30,7 +30,7 @@ config USB_SI470X
 
 	  Please have a look at the documentation, especially on how
 	  to redirect the audio stream from the radio to your sound device:
-	  Documentation/media/v4l-drivers/si470x.rst
+	  Documentation/admin-guide/media/si470x.rst
 
 	  Say Y here if you want to connect this type of radio to your
 	  computer's USB port.
diff --git a/drivers/media/radio/wl128x/Kconfig b/drivers/media/radio/wl128x/Kconfig
index 1dee7277004b..d5ae3388d3db 100644
--- a/drivers/media/radio/wl128x/Kconfig
+++ b/drivers/media/radio/wl128x/Kconfig
@@ -2,7 +2,6 @@
 #
 # TI's wl128x FM driver based on TI's ST driver.
 #
-menu "Texas Instruments WL128x FM driver (ST based)"
 config RADIO_WL128X
 	tristate "Texas Instruments WL128x FM Radio"
 	depends on VIDEO_V4L2 && RFKILL && TTY && TI_ST
@@ -13,6 +12,4 @@ config RADIO_WL128X
 	  In order to control your radio card, you will need to use programs
 	  that are compatible with the Video For Linux 2 API.  Information on
 	  this API and pointers to "v4l2" programs may be found at
-	  <file:Documentation/media/media_uapi.rst>.
-
-endmenu
+	  <file:Documentation/userspace-api/media/index.rst>.
diff --git a/drivers/media/spi/Kconfig b/drivers/media/spi/Kconfig
index bcc49cb47de6..857ef4ace6e9 100644
--- a/drivers/media/spi/Kconfig
+++ b/drivers/media/spi/Kconfig
@@ -1,15 +1,17 @@
 # SPDX-License-Identifier: GPL-2.0-only
 if VIDEO_V4L2
 
-comment "SPI drivers hidden by 'Autoselect ancillary drivers'"
-	depends on MEDIA_HIDE_ANCILLARY_SUBDRV
+comment "SPI I2C drivers auto-selected by 'Autoselect ancillary drivers'"
+	depends on MEDIA_HIDE_ANCILLARY_SUBDRV && SPI
 
 menu "SPI helper chips"
 	visible if !MEDIA_HIDE_ANCILLARY_SUBDRV
 
 config VIDEO_GS1662
 	tristate "Gennum Serializers video"
-	depends on SPI && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on SPI && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	help
 	  Enable the GS1662 driver which serializes video streams.
 
diff --git a/drivers/media/test-drivers/Kconfig b/drivers/media/test-drivers/Kconfig
new file mode 100644
index 000000000000..188381c85593
--- /dev/null
+++ b/drivers/media/test-drivers/Kconfig
@@ -0,0 +1,26 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+menuconfig V4L_TEST_DRIVERS
+	bool "V4L test drivers"
+	depends on VIDEO_DEV
+
+if V4L_TEST_DRIVERS
+
+source "drivers/media/test-drivers/vimc/Kconfig"
+
+source "drivers/media/test-drivers/vivid/Kconfig"
+
+config VIDEO_VIM2M
+	tristate "Virtual Memory-to-Memory Driver"
+	depends on VIDEO_DEV && VIDEO_V4L2
+	select VIDEOBUF2_VMALLOC
+	select V4L2_MEM2MEM_DEV
+	select MEDIA_CONTROLLER
+	select MEDIA_CONTROLLER_REQUEST_API
+	help
+	  This is a virtual test device for the memory-to-memory driver
+	  framework.
+
+source "drivers/media/test-drivers/vicodec/Kconfig"
+
+endif #V4L_TEST_DRIVERS
diff --git a/drivers/media/test-drivers/Makefile b/drivers/media/test-drivers/Makefile
new file mode 100644
index 000000000000..74410d3a9f2d
--- /dev/null
+++ b/drivers/media/test-drivers/Makefile
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the test drivers.
+#
+
+obj-$(CONFIG_VIDEO_VIMC)		+= vimc/
+obj-$(CONFIG_VIDEO_VIVID)		+= vivid/
+obj-$(CONFIG_VIDEO_VIM2M)		+= vim2m.o
+obj-$(CONFIG_VIDEO_VICODEC)		+= vicodec/
diff --git a/drivers/media/test-drivers/vicodec/Kconfig b/drivers/media/test-drivers/vicodec/Kconfig
new file mode 100644
index 000000000000..d77c67810c73
--- /dev/null
+++ b/drivers/media/test-drivers/vicodec/Kconfig
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config VIDEO_VICODEC
+	tristate "Virtual Codec Driver"
+	depends on VIDEO_DEV && VIDEO_V4L2
+	select VIDEOBUF2_VMALLOC
+	select V4L2_MEM2MEM_DEV
+	select MEDIA_CONTROLLER
+	select MEDIA_CONTROLLER_REQUEST_API
+	help
+	  Driver for a Virtual Codec
+
+	  This driver can be compared to the vim2m driver for emulating
+	  a video device node that exposes an emulated hardware codec.
+
+	  When in doubt, say N.
diff --git a/drivers/media/test-drivers/vicodec/Makefile b/drivers/media/test-drivers/vicodec/Makefile
new file mode 100644
index 000000000000..01bf7e9308a6
--- /dev/null
+++ b/drivers/media/test-drivers/vicodec/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+vicodec-objs := vicodec-core.o codec-fwht.o codec-v4l2-fwht.o
+
+obj-$(CONFIG_VIDEO_VICODEC) += vicodec.o
diff --git a/drivers/media/test-drivers/vicodec/codec-fwht.c b/drivers/media/test-drivers/vicodec/codec-fwht.c
new file mode 100644
index 000000000000..31faf319e508
--- /dev/null
+++ b/drivers/media/test-drivers/vicodec/codec-fwht.c
@@ -0,0 +1,958 @@
+// SPDX-License-Identifier: LGPL-2.1+
+/*
+ * Copyright 2016 Tom aan de Wiel
+ * Copyright 2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ *
+ * 8x8 Fast Walsh Hadamard Transform in sequency order based on the paper:
+ *
+ * A Recursive Algorithm for Sequency-Ordered Fast Walsh Transforms,
+ * R.D. Brown, 1977
+ */
+
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include "codec-fwht.h"
+
+#define OVERFLOW_BIT BIT(14)
+
+/*
+ * Note: bit 0 of the header must always be 0. Otherwise it cannot
+ * be guaranteed that the magic 8 byte sequence (see below) can
+ * never occur in the rlc output.
+ */
+#define PFRAME_BIT BIT(15)
+#define DUPS_MASK 0x1ffe
+
+#define PBLOCK 0
+#define IBLOCK 1
+
+#define ALL_ZEROS 15
+
+static const uint8_t zigzag[64] = {
+	0,
+	1,  8,
+	2,  9, 16,
+	3, 10, 17, 24,
+	4, 11, 18, 25, 32,
+	5, 12, 19, 26, 33, 40,
+	6, 13, 20, 27, 34, 41, 48,
+	7, 14, 21, 28, 35, 42, 49, 56,
+	15, 22, 29, 36, 43, 50, 57,
+	23, 30, 37, 44, 51, 58,
+	31, 38, 45, 52, 59,
+	39, 46, 53, 60,
+	47, 54, 61,
+	55, 62,
+	63,
+};
+
+/*
+ * noinline_for_stack to work around
+ * https://bugs.llvm.org/show_bug.cgi?id=38809
+ */
+static int noinline_for_stack
+rlc(const s16 *in, __be16 *output, int blocktype)
+{
+	s16 block[8 * 8];
+	s16 *wp = block;
+	int i = 0;
+	int x, y;
+	int ret = 0;
+
+	/* read in block from framebuffer */
+	int lastzero_run = 0;
+	int to_encode;
+
+	for (y = 0; y < 8; y++) {
+		for (x = 0; x < 8; x++) {
+			*wp = in[x + y * 8];
+			wp++;
+		}
+	}
+
+	/* keep track of amount of trailing zeros */
+	for (i = 63; i >= 0 && !block[zigzag[i]]; i--)
+		lastzero_run++;
+
+	*output++ = (blocktype == PBLOCK ? htons(PFRAME_BIT) : 0);
+	ret++;
+
+	to_encode = 8 * 8 - (lastzero_run > 14 ? lastzero_run : 0);
+
+	i = 0;
+	while (i < to_encode) {
+		int cnt = 0;
+		int tmp;
+
+		/* count leading zeros */
+		while ((tmp = block[zigzag[i]]) == 0 && cnt < 14) {
+			cnt++;
+			i++;
+			if (i == to_encode) {
+				cnt--;
+				break;
+			}
+		}
+		/* 4 bits for run, 12 for coefficient (quantization by 4) */
+		*output++ = htons((cnt | tmp << 4));
+		i++;
+		ret++;
+	}
+	if (lastzero_run > 14) {
+		*output = htons(ALL_ZEROS | 0);
+		ret++;
+	}
+
+	return ret;
+}
+
+/*
+ * This function will worst-case increase rlc_in by 65*2 bytes:
+ * one s16 value for the header and 8 * 8 coefficients of type s16.
+ */
+static noinline_for_stack u16
+derlc(const __be16 **rlc_in, s16 *dwht_out, const __be16 *end_of_input)
+{
+	/* header */
+	const __be16 *input = *rlc_in;
+	u16 stat;
+	int dec_count = 0;
+	s16 block[8 * 8 + 16];
+	s16 *wp = block;
+	int i;
+
+	if (input > end_of_input)
+		return OVERFLOW_BIT;
+	stat = ntohs(*input++);
+
+	/*
+	 * Now de-compress, it expands one byte to up to 15 bytes
+	 * (or fills the remainder of the 64 bytes with zeroes if it
+	 * is the last byte to expand).
+	 *
+	 * So block has to be 8 * 8 + 16 bytes, the '+ 16' is to
+	 * allow for overflow if the incoming data was malformed.
+	 */
+	while (dec_count < 8 * 8) {
+		s16 in;
+		int length;
+		int coeff;
+
+		if (input > end_of_input)
+			return OVERFLOW_BIT;
+		in = ntohs(*input++);
+		length = in & 0xf;
+		coeff = in >> 4;
+
+		/* fill remainder with zeros */
+		if (length == 15) {
+			for (i = 0; i < 64 - dec_count; i++)
+				*wp++ = 0;
+			break;
+		}
+
+		for (i = 0; i < length; i++)
+			*wp++ = 0;
+		*wp++ = coeff;
+		dec_count += length + 1;
+	}
+
+	wp = block;
+
+	for (i = 0; i < 64; i++) {
+		int pos = zigzag[i];
+		int y = pos / 8;
+		int x = pos % 8;
+
+		dwht_out[x + y * 8] = *wp++;
+	}
+	*rlc_in = input;
+	return stat;
+}
+
+static const int quant_table[] = {
+	2, 2, 2, 2, 2, 2,  2,  2,
+	2, 2, 2, 2, 2, 2,  2,  2,
+	2, 2, 2, 2, 2, 2,  2,  3,
+	2, 2, 2, 2, 2, 2,  3,  6,
+	2, 2, 2, 2, 2, 3,  6,  6,
+	2, 2, 2, 2, 3, 6,  6,  6,
+	2, 2, 2, 3, 6, 6,  6,  6,
+	2, 2, 3, 6, 6, 6,  6,  8,
+};
+
+static const int quant_table_p[] = {
+	3, 3, 3, 3, 3, 3,  3,  3,
+	3, 3, 3, 3, 3, 3,  3,  3,
+	3, 3, 3, 3, 3, 3,  3,  3,
+	3, 3, 3, 3, 3, 3,  3,  6,
+	3, 3, 3, 3, 3, 3,  6,  6,
+	3, 3, 3, 3, 3, 6,  6,  9,
+	3, 3, 3, 3, 6, 6,  9,  9,
+	3, 3, 3, 6, 6, 9,  9,  10,
+};
+
+static void quantize_intra(s16 *coeff, s16 *de_coeff, u16 qp)
+{
+	const int *quant = quant_table;
+	int i, j;
+
+	for (j = 0; j < 8; j++) {
+		for (i = 0; i < 8; i++, quant++, coeff++, de_coeff++) {
+			*coeff >>= *quant;
+			if (*coeff >= -qp && *coeff <= qp)
+				*coeff = *de_coeff = 0;
+			else
+				*de_coeff = *coeff << *quant;
+		}
+	}
+}
+
+static void dequantize_intra(s16 *coeff)
+{
+	const int *quant = quant_table;
+	int i, j;
+
+	for (j = 0; j < 8; j++)
+		for (i = 0; i < 8; i++, quant++, coeff++)
+			*coeff <<= *quant;
+}
+
+static void quantize_inter(s16 *coeff, s16 *de_coeff, u16 qp)
+{
+	const int *quant = quant_table_p;
+	int i, j;
+
+	for (j = 0; j < 8; j++) {
+		for (i = 0; i < 8; i++, quant++, coeff++, de_coeff++) {
+			*coeff >>= *quant;
+			if (*coeff >= -qp && *coeff <= qp)
+				*coeff = *de_coeff = 0;
+			else
+				*de_coeff = *coeff << *quant;
+		}
+	}
+}
+
+static void dequantize_inter(s16 *coeff)
+{
+	const int *quant = quant_table_p;
+	int i, j;
+
+	for (j = 0; j < 8; j++)
+		for (i = 0; i < 8; i++, quant++, coeff++)
+			*coeff <<= *quant;
+}
+
+static void noinline_for_stack fwht(const u8 *block, s16 *output_block,
+				    unsigned int stride,
+				    unsigned int input_step, bool intra)
+{
+	/* we'll need more than 8 bits for the transformed coefficients */
+	s32 workspace1[8], workspace2[8];
+	const u8 *tmp = block;
+	s16 *out = output_block;
+	int add = intra ? 256 : 0;
+	unsigned int i;
+
+	/* stage 1 */
+	for (i = 0; i < 8; i++, tmp += stride, out += 8) {
+		switch (input_step) {
+		case 1:
+			workspace1[0]  = tmp[0] + tmp[1] - add;
+			workspace1[1]  = tmp[0] - tmp[1];
+
+			workspace1[2]  = tmp[2] + tmp[3] - add;
+			workspace1[3]  = tmp[2] - tmp[3];
+
+			workspace1[4]  = tmp[4] + tmp[5] - add;
+			workspace1[5]  = tmp[4] - tmp[5];
+
+			workspace1[6]  = tmp[6] + tmp[7] - add;
+			workspace1[7]  = tmp[6] - tmp[7];
+			break;
+		case 2:
+			workspace1[0]  = tmp[0] + tmp[2] - add;
+			workspace1[1]  = tmp[0] - tmp[2];
+
+			workspace1[2]  = tmp[4] + tmp[6] - add;
+			workspace1[3]  = tmp[4] - tmp[6];
+
+			workspace1[4]  = tmp[8] + tmp[10] - add;
+			workspace1[5]  = tmp[8] - tmp[10];
+
+			workspace1[6]  = tmp[12] + tmp[14] - add;
+			workspace1[7]  = tmp[12] - tmp[14];
+			break;
+		case 3:
+			workspace1[0]  = tmp[0] + tmp[3] - add;
+			workspace1[1]  = tmp[0] - tmp[3];
+
+			workspace1[2]  = tmp[6] + tmp[9] - add;
+			workspace1[3]  = tmp[6] - tmp[9];
+
+			workspace1[4]  = tmp[12] + tmp[15] - add;
+			workspace1[5]  = tmp[12] - tmp[15];
+
+			workspace1[6]  = tmp[18] + tmp[21] - add;
+			workspace1[7]  = tmp[18] - tmp[21];
+			break;
+		default:
+			workspace1[0]  = tmp[0] + tmp[4] - add;
+			workspace1[1]  = tmp[0] - tmp[4];
+
+			workspace1[2]  = tmp[8] + tmp[12] - add;
+			workspace1[3]  = tmp[8] - tmp[12];
+
+			workspace1[4]  = tmp[16] + tmp[20] - add;
+			workspace1[5]  = tmp[16] - tmp[20];
+
+			workspace1[6]  = tmp[24] + tmp[28] - add;
+			workspace1[7]  = tmp[24] - tmp[28];
+			break;
+		}
+
+		/* stage 2 */
+		workspace2[0] = workspace1[0] + workspace1[2];
+		workspace2[1] = workspace1[0] - workspace1[2];
+		workspace2[2] = workspace1[1] - workspace1[3];
+		workspace2[3] = workspace1[1] + workspace1[3];
+
+		workspace2[4] = workspace1[4] + workspace1[6];
+		workspace2[5] = workspace1[4] - workspace1[6];
+		workspace2[6] = workspace1[5] - workspace1[7];
+		workspace2[7] = workspace1[5] + workspace1[7];
+
+		/* stage 3 */
+		out[0] = workspace2[0] + workspace2[4];
+		out[1] = workspace2[0] - workspace2[4];
+		out[2] = workspace2[1] - workspace2[5];
+		out[3] = workspace2[1] + workspace2[5];
+		out[4] = workspace2[2] + workspace2[6];
+		out[5] = workspace2[2] - workspace2[6];
+		out[6] = workspace2[3] - workspace2[7];
+		out[7] = workspace2[3] + workspace2[7];
+	}
+
+	out = output_block;
+
+	for (i = 0; i < 8; i++, out++) {
+		/* stage 1 */
+		workspace1[0]  = out[0] + out[1 * 8];
+		workspace1[1]  = out[0] - out[1 * 8];
+
+		workspace1[2]  = out[2 * 8] + out[3 * 8];
+		workspace1[3]  = out[2 * 8] - out[3 * 8];
+
+		workspace1[4]  = out[4 * 8] + out[5 * 8];
+		workspace1[5]  = out[4 * 8] - out[5 * 8];
+
+		workspace1[6]  = out[6 * 8] + out[7 * 8];
+		workspace1[7]  = out[6 * 8] - out[7 * 8];
+
+		/* stage 2 */
+		workspace2[0] = workspace1[0] + workspace1[2];
+		workspace2[1] = workspace1[0] - workspace1[2];
+		workspace2[2] = workspace1[1] - workspace1[3];
+		workspace2[3] = workspace1[1] + workspace1[3];
+
+		workspace2[4] = workspace1[4] + workspace1[6];
+		workspace2[5] = workspace1[4] - workspace1[6];
+		workspace2[6] = workspace1[5] - workspace1[7];
+		workspace2[7] = workspace1[5] + workspace1[7];
+		/* stage 3 */
+		out[0 * 8] = workspace2[0] + workspace2[4];
+		out[1 * 8] = workspace2[0] - workspace2[4];
+		out[2 * 8] = workspace2[1] - workspace2[5];
+		out[3 * 8] = workspace2[1] + workspace2[5];
+		out[4 * 8] = workspace2[2] + workspace2[6];
+		out[5 * 8] = workspace2[2] - workspace2[6];
+		out[6 * 8] = workspace2[3] - workspace2[7];
+		out[7 * 8] = workspace2[3] + workspace2[7];
+	}
+}
+
+/*
+ * Not the nicest way of doing it, but P-blocks get twice the range of
+ * that of the I-blocks. Therefore we need a type bigger than 8 bits.
+ * Furthermore values can be negative... This is just a version that
+ * works with 16 signed data
+ */
+static void noinline_for_stack
+fwht16(const s16 *block, s16 *output_block, int stride, int intra)
+{
+	/* we'll need more than 8 bits for the transformed coefficients */
+	s32 workspace1[8], workspace2[8];
+	const s16 *tmp = block;
+	s16 *out = output_block;
+	int i;
+
+	for (i = 0; i < 8; i++, tmp += stride, out += 8) {
+		/* stage 1 */
+		workspace1[0]  = tmp[0] + tmp[1];
+		workspace1[1]  = tmp[0] - tmp[1];
+
+		workspace1[2]  = tmp[2] + tmp[3];
+		workspace1[3]  = tmp[2] - tmp[3];
+
+		workspace1[4]  = tmp[4] + tmp[5];
+		workspace1[5]  = tmp[4] - tmp[5];
+
+		workspace1[6]  = tmp[6] + tmp[7];
+		workspace1[7]  = tmp[6] - tmp[7];
+
+		/* stage 2 */
+		workspace2[0] = workspace1[0] + workspace1[2];
+		workspace2[1] = workspace1[0] - workspace1[2];
+		workspace2[2] = workspace1[1] - workspace1[3];
+		workspace2[3] = workspace1[1] + workspace1[3];
+
+		workspace2[4] = workspace1[4] + workspace1[6];
+		workspace2[5] = workspace1[4] - workspace1[6];
+		workspace2[6] = workspace1[5] - workspace1[7];
+		workspace2[7] = workspace1[5] + workspace1[7];
+
+		/* stage 3 */
+		out[0] = workspace2[0] + workspace2[4];
+		out[1] = workspace2[0] - workspace2[4];
+		out[2] = workspace2[1] - workspace2[5];
+		out[3] = workspace2[1] + workspace2[5];
+		out[4] = workspace2[2] + workspace2[6];
+		out[5] = workspace2[2] - workspace2[6];
+		out[6] = workspace2[3] - workspace2[7];
+		out[7] = workspace2[3] + workspace2[7];
+	}
+
+	out = output_block;
+
+	for (i = 0; i < 8; i++, out++) {
+		/* stage 1 */
+		workspace1[0]  = out[0] + out[1*8];
+		workspace1[1]  = out[0] - out[1*8];
+
+		workspace1[2]  = out[2*8] + out[3*8];
+		workspace1[3]  = out[2*8] - out[3*8];
+
+		workspace1[4]  = out[4*8] + out[5*8];
+		workspace1[5]  = out[4*8] - out[5*8];
+
+		workspace1[6]  = out[6*8] + out[7*8];
+		workspace1[7]  = out[6*8] - out[7*8];
+
+		/* stage 2 */
+		workspace2[0] = workspace1[0] + workspace1[2];
+		workspace2[1] = workspace1[0] - workspace1[2];
+		workspace2[2] = workspace1[1] - workspace1[3];
+		workspace2[3] = workspace1[1] + workspace1[3];
+
+		workspace2[4] = workspace1[4] + workspace1[6];
+		workspace2[5] = workspace1[4] - workspace1[6];
+		workspace2[6] = workspace1[5] - workspace1[7];
+		workspace2[7] = workspace1[5] + workspace1[7];
+
+		/* stage 3 */
+		out[0*8] = workspace2[0] + workspace2[4];
+		out[1*8] = workspace2[0] - workspace2[4];
+		out[2*8] = workspace2[1] - workspace2[5];
+		out[3*8] = workspace2[1] + workspace2[5];
+		out[4*8] = workspace2[2] + workspace2[6];
+		out[5*8] = workspace2[2] - workspace2[6];
+		out[6*8] = workspace2[3] - workspace2[7];
+		out[7*8] = workspace2[3] + workspace2[7];
+	}
+}
+
+static noinline_for_stack void
+ifwht(const s16 *block, s16 *output_block, int intra)
+{
+	/*
+	 * we'll need more than 8 bits for the transformed coefficients
+	 * use native unit of cpu
+	 */
+	int workspace1[8], workspace2[8];
+	int inter = intra ? 0 : 1;
+	const s16 *tmp = block;
+	s16 *out = output_block;
+	int i;
+
+	for (i = 0; i < 8; i++, tmp += 8, out += 8) {
+		/* stage 1 */
+		workspace1[0]  = tmp[0] + tmp[1];
+		workspace1[1]  = tmp[0] - tmp[1];
+
+		workspace1[2]  = tmp[2] + tmp[3];
+		workspace1[3]  = tmp[2] - tmp[3];
+
+		workspace1[4]  = tmp[4] + tmp[5];
+		workspace1[5]  = tmp[4] - tmp[5];
+
+		workspace1[6]  = tmp[6] + tmp[7];
+		workspace1[7]  = tmp[6] - tmp[7];
+
+		/* stage 2 */
+		workspace2[0] = workspace1[0] + workspace1[2];
+		workspace2[1] = workspace1[0] - workspace1[2];
+		workspace2[2] = workspace1[1] - workspace1[3];
+		workspace2[3] = workspace1[1] + workspace1[3];
+
+		workspace2[4] = workspace1[4] + workspace1[6];
+		workspace2[5] = workspace1[4] - workspace1[6];
+		workspace2[6] = workspace1[5] - workspace1[7];
+		workspace2[7] = workspace1[5] + workspace1[7];
+
+		/* stage 3 */
+		out[0] = workspace2[0] + workspace2[4];
+		out[1] = workspace2[0] - workspace2[4];
+		out[2] = workspace2[1] - workspace2[5];
+		out[3] = workspace2[1] + workspace2[5];
+		out[4] = workspace2[2] + workspace2[6];
+		out[5] = workspace2[2] - workspace2[6];
+		out[6] = workspace2[3] - workspace2[7];
+		out[7] = workspace2[3] + workspace2[7];
+	}
+
+	out = output_block;
+
+	for (i = 0; i < 8; i++, out++) {
+		/* stage 1 */
+		workspace1[0]  = out[0] + out[1 * 8];
+		workspace1[1]  = out[0] - out[1 * 8];
+
+		workspace1[2]  = out[2 * 8] + out[3 * 8];
+		workspace1[3]  = out[2 * 8] - out[3 * 8];
+
+		workspace1[4]  = out[4 * 8] + out[5 * 8];
+		workspace1[5]  = out[4 * 8] - out[5 * 8];
+
+		workspace1[6]  = out[6 * 8] + out[7 * 8];
+		workspace1[7]  = out[6 * 8] - out[7 * 8];
+
+		/* stage 2 */
+		workspace2[0] = workspace1[0] + workspace1[2];
+		workspace2[1] = workspace1[0] - workspace1[2];
+		workspace2[2] = workspace1[1] - workspace1[3];
+		workspace2[3] = workspace1[1] + workspace1[3];
+
+		workspace2[4] = workspace1[4] + workspace1[6];
+		workspace2[5] = workspace1[4] - workspace1[6];
+		workspace2[6] = workspace1[5] - workspace1[7];
+		workspace2[7] = workspace1[5] + workspace1[7];
+
+		/* stage 3 */
+		if (inter) {
+			int d;
+
+			out[0 * 8] = workspace2[0] + workspace2[4];
+			out[1 * 8] = workspace2[0] - workspace2[4];
+			out[2 * 8] = workspace2[1] - workspace2[5];
+			out[3 * 8] = workspace2[1] + workspace2[5];
+			out[4 * 8] = workspace2[2] + workspace2[6];
+			out[5 * 8] = workspace2[2] - workspace2[6];
+			out[6 * 8] = workspace2[3] - workspace2[7];
+			out[7 * 8] = workspace2[3] + workspace2[7];
+
+			for (d = 0; d < 8; d++)
+				out[8 * d] >>= 6;
+		} else {
+			int d;
+
+			out[0 * 8] = workspace2[0] + workspace2[4];
+			out[1 * 8] = workspace2[0] - workspace2[4];
+			out[2 * 8] = workspace2[1] - workspace2[5];
+			out[3 * 8] = workspace2[1] + workspace2[5];
+			out[4 * 8] = workspace2[2] + workspace2[6];
+			out[5 * 8] = workspace2[2] - workspace2[6];
+			out[6 * 8] = workspace2[3] - workspace2[7];
+			out[7 * 8] = workspace2[3] + workspace2[7];
+
+			for (d = 0; d < 8; d++) {
+				out[8 * d] >>= 6;
+				out[8 * d] += 128;
+			}
+		}
+	}
+}
+
+static void fill_encoder_block(const u8 *input, s16 *dst,
+			       unsigned int stride, unsigned int input_step)
+{
+	int i, j;
+
+	for (i = 0; i < 8; i++) {
+		for (j = 0; j < 8; j++, input += input_step)
+			*dst++ = *input;
+		input += stride - 8 * input_step;
+	}
+}
+
+static int var_intra(const s16 *input)
+{
+	int32_t mean = 0;
+	int32_t ret = 0;
+	const s16 *tmp = input;
+	int i;
+
+	for (i = 0; i < 8 * 8; i++, tmp++)
+		mean += *tmp;
+	mean /= 64;
+	tmp = input;
+	for (i = 0; i < 8 * 8; i++, tmp++)
+		ret += (*tmp - mean) < 0 ? -(*tmp - mean) : (*tmp - mean);
+	return ret;
+}
+
+static int var_inter(const s16 *old, const s16 *new)
+{
+	int32_t ret = 0;
+	int i;
+
+	for (i = 0; i < 8 * 8; i++, old++, new++)
+		ret += (*old - *new) < 0 ? -(*old - *new) : (*old - *new);
+	return ret;
+}
+
+static noinline_for_stack int
+decide_blocktype(const u8 *cur, const u8 *reference, s16 *deltablock,
+		 unsigned int stride, unsigned int input_step)
+{
+	s16 tmp[64];
+	s16 old[64];
+	s16 *work = tmp;
+	unsigned int k, l;
+	int vari;
+	int vard;
+
+	fill_encoder_block(cur, tmp, stride, input_step);
+	fill_encoder_block(reference, old, 8, 1);
+	vari = var_intra(tmp);
+
+	for (k = 0; k < 8; k++) {
+		for (l = 0; l < 8; l++) {
+			*deltablock = *work - *reference;
+			deltablock++;
+			work++;
+			reference++;
+		}
+	}
+	deltablock -= 64;
+	vard = var_inter(old, tmp);
+	return vari <= vard ? IBLOCK : PBLOCK;
+}
+
+static void fill_decoder_block(u8 *dst, const s16 *input, int stride,
+			       unsigned int dst_step)
+{
+	int i, j;
+
+	for (i = 0; i < 8; i++) {
+		for (j = 0; j < 8; j++, input++, dst += dst_step) {
+			if (*input < 0)
+				*dst = 0;
+			else if (*input > 255)
+				*dst = 255;
+			else
+				*dst = *input;
+		}
+		dst += stride - (8 * dst_step);
+	}
+}
+
+static void add_deltas(s16 *deltas, const u8 *ref, int stride,
+		       unsigned int ref_step)
+{
+	int k, l;
+
+	for (k = 0; k < 8; k++) {
+		for (l = 0; l < 8; l++) {
+			*deltas += *ref;
+			ref += ref_step;
+			/*
+			 * Due to quantizing, it might possible that the
+			 * decoded coefficients are slightly out of range
+			 */
+			if (*deltas < 0)
+				*deltas = 0;
+			else if (*deltas > 255)
+				*deltas = 255;
+			deltas++;
+		}
+		ref += stride - (8 * ref_step);
+	}
+}
+
+static u32 encode_plane(u8 *input, u8 *refp, __be16 **rlco, __be16 *rlco_max,
+			struct fwht_cframe *cf, u32 height, u32 width,
+			u32 stride, unsigned int input_step,
+			bool is_intra, bool next_is_intra)
+{
+	u8 *input_start = input;
+	__be16 *rlco_start = *rlco;
+	s16 deltablock[64];
+	__be16 pframe_bit = htons(PFRAME_BIT);
+	u32 encoding = 0;
+	unsigned int last_size = 0;
+	unsigned int i, j;
+
+	width = round_up(width, 8);
+	height = round_up(height, 8);
+
+	for (j = 0; j < height / 8; j++) {
+		input = input_start + j * 8 * stride;
+		for (i = 0; i < width / 8; i++) {
+			/* intra code, first frame is always intra coded. */
+			int blocktype = IBLOCK;
+			unsigned int size;
+
+			if (!is_intra)
+				blocktype = decide_blocktype(input, refp,
+					deltablock, stride, input_step);
+			if (blocktype == IBLOCK) {
+				fwht(input, cf->coeffs, stride, input_step, 1);
+				quantize_intra(cf->coeffs, cf->de_coeffs,
+					       cf->i_frame_qp);
+			} else {
+				/* inter code */
+				encoding |= FWHT_FRAME_PCODED;
+				fwht16(deltablock, cf->coeffs, 8, 0);
+				quantize_inter(cf->coeffs, cf->de_coeffs,
+					       cf->p_frame_qp);
+			}
+			if (!next_is_intra) {
+				ifwht(cf->de_coeffs, cf->de_fwht, blocktype);
+
+				if (blocktype == PBLOCK)
+					add_deltas(cf->de_fwht, refp, 8, 1);
+				fill_decoder_block(refp, cf->de_fwht, 8, 1);
+			}
+
+			input += 8 * input_step;
+			refp += 8 * 8;
+
+			size = rlc(cf->coeffs, *rlco, blocktype);
+			if (last_size == size &&
+			    !memcmp(*rlco + 1, *rlco - size + 1, 2 * size - 2)) {
+				__be16 *last_rlco = *rlco - size;
+				s16 hdr = ntohs(*last_rlco);
+
+				if (!((*last_rlco ^ **rlco) & pframe_bit) &&
+				    (hdr & DUPS_MASK) < DUPS_MASK)
+					*last_rlco = htons(hdr + 2);
+				else
+					*rlco += size;
+			} else {
+				*rlco += size;
+			}
+			if (*rlco >= rlco_max) {
+				encoding |= FWHT_FRAME_UNENCODED;
+				goto exit_loop;
+			}
+			last_size = size;
+		}
+	}
+
+exit_loop:
+	if (encoding & FWHT_FRAME_UNENCODED) {
+		u8 *out = (u8 *)rlco_start;
+		u8 *p;
+
+		input = input_start;
+		/*
+		 * The compressed stream should never contain the magic
+		 * header, so when we copy the YUV data we replace 0xff
+		 * by 0xfe. Since YUV is limited range such values
+		 * shouldn't appear anyway.
+		 */
+		for (j = 0; j < height; j++) {
+			for (i = 0, p = input; i < width; i++, p += input_step)
+				*out++ = (*p == 0xff) ? 0xfe : *p;
+			input += stride;
+		}
+		*rlco = (__be16 *)out;
+		encoding &= ~FWHT_FRAME_PCODED;
+	}
+	return encoding;
+}
+
+u32 fwht_encode_frame(struct fwht_raw_frame *frm,
+		      struct fwht_raw_frame *ref_frm,
+		      struct fwht_cframe *cf,
+		      bool is_intra, bool next_is_intra,
+		      unsigned int width, unsigned int height,
+		      unsigned int stride, unsigned int chroma_stride)
+{
+	unsigned int size = height * width;
+	__be16 *rlco = cf->rlc_data;
+	__be16 *rlco_max;
+	u32 encoding;
+
+	rlco_max = rlco + size / 2 - 256;
+	encoding = encode_plane(frm->luma, ref_frm->luma, &rlco, rlco_max, cf,
+				height, width, stride,
+				frm->luma_alpha_step, is_intra, next_is_intra);
+	if (encoding & FWHT_FRAME_UNENCODED)
+		encoding |= FWHT_LUMA_UNENCODED;
+	encoding &= ~FWHT_FRAME_UNENCODED;
+
+	if (frm->components_num >= 3) {
+		u32 chroma_h = height / frm->height_div;
+		u32 chroma_w = width / frm->width_div;
+		unsigned int chroma_size = chroma_h * chroma_w;
+
+		rlco_max = rlco + chroma_size / 2 - 256;
+		encoding |= encode_plane(frm->cb, ref_frm->cb, &rlco, rlco_max,
+					 cf, chroma_h, chroma_w,
+					 chroma_stride, frm->chroma_step,
+					 is_intra, next_is_intra);
+		if (encoding & FWHT_FRAME_UNENCODED)
+			encoding |= FWHT_CB_UNENCODED;
+		encoding &= ~FWHT_FRAME_UNENCODED;
+		rlco_max = rlco + chroma_size / 2 - 256;
+		encoding |= encode_plane(frm->cr, ref_frm->cr, &rlco, rlco_max,
+					 cf, chroma_h, chroma_w,
+					 chroma_stride, frm->chroma_step,
+					 is_intra, next_is_intra);
+		if (encoding & FWHT_FRAME_UNENCODED)
+			encoding |= FWHT_CR_UNENCODED;
+		encoding &= ~FWHT_FRAME_UNENCODED;
+	}
+
+	if (frm->components_num == 4) {
+		rlco_max = rlco + size / 2 - 256;
+		encoding |= encode_plane(frm->alpha, ref_frm->alpha, &rlco,
+					 rlco_max, cf, height, width,
+					 stride, frm->luma_alpha_step,
+					 is_intra, next_is_intra);
+		if (encoding & FWHT_FRAME_UNENCODED)
+			encoding |= FWHT_ALPHA_UNENCODED;
+		encoding &= ~FWHT_FRAME_UNENCODED;
+	}
+
+	cf->size = (rlco - cf->rlc_data) * sizeof(*rlco);
+	return encoding;
+}
+
+static bool decode_plane(struct fwht_cframe *cf, const __be16 **rlco,
+			 u32 height, u32 width, const u8 *ref, u32 ref_stride,
+			 unsigned int ref_step, u8 *dst,
+			 unsigned int dst_stride, unsigned int dst_step,
+			 bool uncompressed, const __be16 *end_of_rlco_buf)
+{
+	unsigned int copies = 0;
+	s16 copy[8 * 8];
+	u16 stat;
+	unsigned int i, j;
+	bool is_intra = !ref;
+
+	width = round_up(width, 8);
+	height = round_up(height, 8);
+
+	if (uncompressed) {
+		int i;
+
+		if (end_of_rlco_buf + 1 < *rlco + width * height / 2)
+			return false;
+		for (i = 0; i < height; i++) {
+			memcpy(dst, *rlco, width);
+			dst += dst_stride;
+			*rlco += width / 2;
+		}
+		return true;
+	}
+
+	/*
+	 * When decoding each macroblock the rlco pointer will be increased
+	 * by 65 * 2 bytes worst-case.
+	 * To avoid overflow the buffer has to be 65/64th of the actual raw
+	 * image size, just in case someone feeds it malicious data.
+	 */
+	for (j = 0; j < height / 8; j++) {
+		for (i = 0; i < width / 8; i++) {
+			const u8 *refp = ref + j * 8 * ref_stride +
+				i * 8 * ref_step;
+			u8 *dstp = dst + j * 8 * dst_stride + i * 8 * dst_step;
+
+			if (copies) {
+				memcpy(cf->de_fwht, copy, sizeof(copy));
+				if ((stat & PFRAME_BIT) && !is_intra)
+					add_deltas(cf->de_fwht, refp,
+						   ref_stride, ref_step);
+				fill_decoder_block(dstp, cf->de_fwht,
+						   dst_stride, dst_step);
+				copies--;
+				continue;
+			}
+
+			stat = derlc(rlco, cf->coeffs, end_of_rlco_buf);
+			if (stat & OVERFLOW_BIT)
+				return false;
+			if ((stat & PFRAME_BIT) && !is_intra)
+				dequantize_inter(cf->coeffs);
+			else
+				dequantize_intra(cf->coeffs);
+
+			ifwht(cf->coeffs, cf->de_fwht,
+			      ((stat & PFRAME_BIT) && !is_intra) ? 0 : 1);
+
+			copies = (stat & DUPS_MASK) >> 1;
+			if (copies)
+				memcpy(copy, cf->de_fwht, sizeof(copy));
+			if ((stat & PFRAME_BIT) && !is_intra)
+				add_deltas(cf->de_fwht, refp,
+					   ref_stride, ref_step);
+			fill_decoder_block(dstp, cf->de_fwht, dst_stride,
+					   dst_step);
+		}
+	}
+	return true;
+}
+
+bool fwht_decode_frame(struct fwht_cframe *cf, u32 hdr_flags,
+		       unsigned int components_num, unsigned int width,
+		       unsigned int height, const struct fwht_raw_frame *ref,
+		       unsigned int ref_stride, unsigned int ref_chroma_stride,
+		       struct fwht_raw_frame *dst, unsigned int dst_stride,
+		       unsigned int dst_chroma_stride)
+{
+	const __be16 *rlco = cf->rlc_data;
+	const __be16 *end_of_rlco_buf = cf->rlc_data +
+			(cf->size / sizeof(*rlco)) - 1;
+
+	if (!decode_plane(cf, &rlco, height, width, ref->luma, ref_stride,
+			  ref->luma_alpha_step, dst->luma, dst_stride,
+			  dst->luma_alpha_step,
+			  hdr_flags & FWHT_FL_LUMA_IS_UNCOMPRESSED,
+			  end_of_rlco_buf))
+		return false;
+
+	if (components_num >= 3) {
+		u32 h = height;
+		u32 w = width;
+
+		if (!(hdr_flags & FWHT_FL_CHROMA_FULL_HEIGHT))
+			h /= 2;
+		if (!(hdr_flags & FWHT_FL_CHROMA_FULL_WIDTH))
+			w /= 2;
+
+		if (!decode_plane(cf, &rlco, h, w, ref->cb, ref_chroma_stride,
+				  ref->chroma_step, dst->cb, dst_chroma_stride,
+				  dst->chroma_step,
+				  hdr_flags & FWHT_FL_CB_IS_UNCOMPRESSED,
+				  end_of_rlco_buf))
+			return false;
+		if (!decode_plane(cf, &rlco, h, w, ref->cr, ref_chroma_stride,
+				  ref->chroma_step, dst->cr, dst_chroma_stride,
+				  dst->chroma_step,
+				  hdr_flags & FWHT_FL_CR_IS_UNCOMPRESSED,
+				  end_of_rlco_buf))
+			return false;
+	}
+
+	if (components_num == 4)
+		if (!decode_plane(cf, &rlco, height, width, ref->alpha, ref_stride,
+				  ref->luma_alpha_step, dst->alpha, dst_stride,
+				  dst->luma_alpha_step,
+				  hdr_flags & FWHT_FL_ALPHA_IS_UNCOMPRESSED,
+				  end_of_rlco_buf))
+			return false;
+	return true;
+}
diff --git a/drivers/media/test-drivers/vicodec/codec-fwht.h b/drivers/media/test-drivers/vicodec/codec-fwht.h
new file mode 100644
index 000000000000..b6fec2b1cbca
--- /dev/null
+++ b/drivers/media/test-drivers/vicodec/codec-fwht.h
@@ -0,0 +1,150 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+/*
+ * Copyright 2016 Tom aan de Wiel
+ * Copyright 2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#ifndef CODEC_FWHT_H
+#define CODEC_FWHT_H
+
+#include <linux/types.h>
+#include <linux/bitops.h>
+#include <asm/byteorder.h>
+
+/*
+ * The compressed format consists of a fwht_cframe_hdr struct followed by the
+ * compressed frame data. The header contains the size of that data.
+ * Each Y, Cb and Cr plane is compressed separately. If the compressed
+ * size of each plane becomes larger than the uncompressed size, then
+ * that plane is stored uncompressed and the corresponding bit is set
+ * in the flags field of the header.
+ *
+ * Each compressed plane consists of macroblocks and each macroblock
+ * is run-length-encoded. Each macroblock starts with a 16 bit value.
+ * Bit 15 indicates if this is a P-coded macroblock (1) or not (0).
+ * P-coded macroblocks contain a delta against the previous frame.
+ *
+ * Bits 1-12 contain a number. If non-zero, then this same macroblock
+ * repeats that number of times. This results in a high degree of
+ * compression for generated images like colorbars.
+ *
+ * Following this macroblock header the MB coefficients are run-length
+ * encoded: the top 12 bits contain the coefficient, the bottom 4 bits
+ * tell how many times this coefficient occurs. The value 0xf indicates
+ * that the remainder of the macroblock should be filled with zeroes.
+ *
+ * All 16 and 32 bit values are stored in big-endian (network) order.
+ *
+ * Each fwht_cframe_hdr starts with an 8 byte magic header that is
+ * guaranteed not to occur in the compressed frame data. This header
+ * can be used to sync to the next frame.
+ *
+ * This codec uses the Fast Walsh Hadamard Transform. Tom aan de Wiel
+ * developed this as part of a university project, specifically for use
+ * with this driver. His project report can be found here:
+ *
+ * https://hverkuil.home.xs4all.nl/fwht.pdf
+ */
+
+/*
+ * This is a sequence of 8 bytes with the low 4 bits set to 0xf.
+ *
+ * This sequence cannot occur in the encoded data
+ *
+ * Note that these two magic values are symmetrical so endian issues here.
+ */
+#define FWHT_MAGIC1 0x4f4f4f4f
+#define FWHT_MAGIC2 0xffffffff
+
+#define FWHT_VERSION 3
+
+/* Set if this is an interlaced format */
+#define FWHT_FL_IS_INTERLACED		BIT(0)
+/* Set if this is a bottom-first (NTSC) interlaced format */
+#define FWHT_FL_IS_BOTTOM_FIRST		BIT(1)
+/* Set if each 'frame' contains just one field */
+#define FWHT_FL_IS_ALTERNATE		BIT(2)
+/*
+ * If FWHT_FL_IS_ALTERNATE was set, then this is set if this
+ * 'frame' is the bottom field, else it is the top field.
+ */
+#define FWHT_FL_IS_BOTTOM_FIELD		BIT(3)
+/* Set if this frame is uncompressed */
+#define FWHT_FL_LUMA_IS_UNCOMPRESSED	BIT(4)
+#define FWHT_FL_CB_IS_UNCOMPRESSED	BIT(5)
+#define FWHT_FL_CR_IS_UNCOMPRESSED	BIT(6)
+#define FWHT_FL_CHROMA_FULL_HEIGHT	BIT(7)
+#define FWHT_FL_CHROMA_FULL_WIDTH	BIT(8)
+#define FWHT_FL_ALPHA_IS_UNCOMPRESSED	BIT(9)
+#define FWHT_FL_I_FRAME			BIT(10)
+
+/* A 4-values flag - the number of components - 1 */
+#define FWHT_FL_COMPONENTS_NUM_MSK	GENMASK(18, 16)
+#define FWHT_FL_COMPONENTS_NUM_OFFSET	16
+
+#define FWHT_FL_PIXENC_MSK	GENMASK(20, 19)
+#define FWHT_FL_PIXENC_OFFSET	19
+#define FWHT_FL_PIXENC_YUV	(1 << FWHT_FL_PIXENC_OFFSET)
+#define FWHT_FL_PIXENC_RGB	(2 << FWHT_FL_PIXENC_OFFSET)
+#define FWHT_FL_PIXENC_HSV	(3 << FWHT_FL_PIXENC_OFFSET)
+
+/*
+ * A macro to calculate the needed padding in order to make sure
+ * both luma and chroma components resolutions are rounded up to
+ * a multiple of 8
+ */
+#define vic_round_dim(dim, div) (round_up((dim) / (div), 8) * (div))
+
+struct fwht_cframe_hdr {
+	u32 magic1;
+	u32 magic2;
+	__be32 version;
+	__be32 width, height;
+	__be32 flags;
+	__be32 colorspace;
+	__be32 xfer_func;
+	__be32 ycbcr_enc;
+	__be32 quantization;
+	__be32 size;
+};
+
+struct fwht_cframe {
+	u16 i_frame_qp;
+	u16 p_frame_qp;
+	__be16 *rlc_data;
+	s16 coeffs[8 * 8];
+	s16 de_coeffs[8 * 8];
+	s16 de_fwht[8 * 8];
+	u32 size;
+};
+
+struct fwht_raw_frame {
+	unsigned int width_div;
+	unsigned int height_div;
+	unsigned int luma_alpha_step;
+	unsigned int chroma_step;
+	unsigned int components_num;
+	u8 *buf;
+	u8 *luma, *cb, *cr, *alpha;
+};
+
+#define FWHT_FRAME_PCODED	BIT(0)
+#define FWHT_FRAME_UNENCODED	BIT(1)
+#define FWHT_LUMA_UNENCODED	BIT(2)
+#define FWHT_CB_UNENCODED	BIT(3)
+#define FWHT_CR_UNENCODED	BIT(4)
+#define FWHT_ALPHA_UNENCODED	BIT(5)
+
+u32 fwht_encode_frame(struct fwht_raw_frame *frm,
+		      struct fwht_raw_frame *ref_frm,
+		      struct fwht_cframe *cf,
+		      bool is_intra, bool next_is_intra,
+		      unsigned int width, unsigned int height,
+		      unsigned int stride, unsigned int chroma_stride);
+bool fwht_decode_frame(struct fwht_cframe *cf, u32 hdr_flags,
+		unsigned int components_num, unsigned int width,
+		unsigned int height, const struct fwht_raw_frame *ref,
+		unsigned int ref_stride, unsigned int ref_chroma_stride,
+		struct fwht_raw_frame *dst, unsigned int dst_stride,
+		unsigned int dst_chroma_stride);
+#endif
diff --git a/drivers/media/test-drivers/vicodec/codec-v4l2-fwht.c b/drivers/media/test-drivers/vicodec/codec-v4l2-fwht.c
new file mode 100644
index 000000000000..b6e39fbd8ad5
--- /dev/null
+++ b/drivers/media/test-drivers/vicodec/codec-v4l2-fwht.c
@@ -0,0 +1,367 @@
+// SPDX-License-Identifier: LGPL-2.1
+/*
+ * A V4L2 frontend for the FWHT codec
+ *
+ * Copyright 2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/videodev2.h>
+#include "codec-v4l2-fwht.h"
+
+static const struct v4l2_fwht_pixfmt_info v4l2_fwht_pixfmts[] = {
+	{ V4L2_PIX_FMT_YUV420,  1, 3, 2, 1, 1, 2, 2, 3, 3, FWHT_FL_PIXENC_YUV},
+	{ V4L2_PIX_FMT_YVU420,  1, 3, 2, 1, 1, 2, 2, 3, 3, FWHT_FL_PIXENC_YUV},
+	{ V4L2_PIX_FMT_YUV422P, 1, 2, 1, 1, 1, 2, 1, 3, 3, FWHT_FL_PIXENC_YUV},
+	{ V4L2_PIX_FMT_NV12,    1, 3, 2, 1, 2, 2, 2, 3, 2, FWHT_FL_PIXENC_YUV},
+	{ V4L2_PIX_FMT_NV21,    1, 3, 2, 1, 2, 2, 2, 3, 2, FWHT_FL_PIXENC_YUV},
+	{ V4L2_PIX_FMT_NV16,    1, 2, 1, 1, 2, 2, 1, 3, 2, FWHT_FL_PIXENC_YUV},
+	{ V4L2_PIX_FMT_NV61,    1, 2, 1, 1, 2, 2, 1, 3, 2, FWHT_FL_PIXENC_YUV},
+	{ V4L2_PIX_FMT_NV24,    1, 3, 1, 1, 2, 1, 1, 3, 2, FWHT_FL_PIXENC_YUV},
+	{ V4L2_PIX_FMT_NV42,    1, 3, 1, 1, 2, 1, 1, 3, 2, FWHT_FL_PIXENC_YUV},
+	{ V4L2_PIX_FMT_YUYV,    2, 2, 1, 2, 4, 2, 1, 3, 1, FWHT_FL_PIXENC_YUV},
+	{ V4L2_PIX_FMT_YVYU,    2, 2, 1, 2, 4, 2, 1, 3, 1, FWHT_FL_PIXENC_YUV},
+	{ V4L2_PIX_FMT_UYVY,    2, 2, 1, 2, 4, 2, 1, 3, 1, FWHT_FL_PIXENC_YUV},
+	{ V4L2_PIX_FMT_VYUY,    2, 2, 1, 2, 4, 2, 1, 3, 1, FWHT_FL_PIXENC_YUV},
+	{ V4L2_PIX_FMT_BGR24,   3, 3, 1, 3, 3, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB},
+	{ V4L2_PIX_FMT_RGB24,   3, 3, 1, 3, 3, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB},
+	{ V4L2_PIX_FMT_HSV24,   3, 3, 1, 3, 3, 1, 1, 3, 1, FWHT_FL_PIXENC_HSV},
+	{ V4L2_PIX_FMT_BGR32,   4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB},
+	{ V4L2_PIX_FMT_XBGR32,  4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB},
+	{ V4L2_PIX_FMT_ABGR32,  4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB},
+	{ V4L2_PIX_FMT_RGB32,   4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB},
+	{ V4L2_PIX_FMT_XRGB32,  4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB},
+	{ V4L2_PIX_FMT_ARGB32,  4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB},
+	{ V4L2_PIX_FMT_BGRX32,  4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB},
+	{ V4L2_PIX_FMT_BGRA32,  4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB},
+	{ V4L2_PIX_FMT_RGBX32,  4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB},
+	{ V4L2_PIX_FMT_RGBA32,  4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB},
+	{ V4L2_PIX_FMT_HSV32,   4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_HSV},
+	{ V4L2_PIX_FMT_GREY,    1, 1, 1, 1, 0, 1, 1, 1, 1, FWHT_FL_PIXENC_RGB},
+};
+
+bool v4l2_fwht_validate_fmt(const struct v4l2_fwht_pixfmt_info *info,
+			    u32 width_div, u32 height_div, u32 components_num,
+			    u32 pixenc)
+{
+	if (info->width_div == width_div &&
+	    info->height_div == height_div &&
+	    (!pixenc || info->pixenc == pixenc) &&
+	    info->components_num == components_num)
+		return true;
+	return false;
+}
+
+const struct v4l2_fwht_pixfmt_info *v4l2_fwht_find_nth_fmt(u32 width_div,
+							  u32 height_div,
+							  u32 components_num,
+							  u32 pixenc,
+							  unsigned int start_idx)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(v4l2_fwht_pixfmts); i++) {
+		bool is_valid = v4l2_fwht_validate_fmt(&v4l2_fwht_pixfmts[i],
+						       width_div, height_div,
+						       components_num, pixenc);
+		if (is_valid) {
+			if (start_idx == 0)
+				return v4l2_fwht_pixfmts + i;
+			start_idx--;
+		}
+	}
+	return NULL;
+}
+
+const struct v4l2_fwht_pixfmt_info *v4l2_fwht_find_pixfmt(u32 pixelformat)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(v4l2_fwht_pixfmts); i++)
+		if (v4l2_fwht_pixfmts[i].id == pixelformat)
+			return v4l2_fwht_pixfmts + i;
+	return NULL;
+}
+
+const struct v4l2_fwht_pixfmt_info *v4l2_fwht_get_pixfmt(u32 idx)
+{
+	if (idx >= ARRAY_SIZE(v4l2_fwht_pixfmts))
+		return NULL;
+	return v4l2_fwht_pixfmts + idx;
+}
+
+static int prepare_raw_frame(struct fwht_raw_frame *rf,
+			 const struct v4l2_fwht_pixfmt_info *info, u8 *buf,
+			 unsigned int size)
+{
+	rf->luma = buf;
+	rf->width_div = info->width_div;
+	rf->height_div = info->height_div;
+	rf->luma_alpha_step = info->luma_alpha_step;
+	rf->chroma_step = info->chroma_step;
+	rf->alpha = NULL;
+	rf->components_num = info->components_num;
+
+	/*
+	 * The buffer is NULL if it is the reference
+	 * frame of an I-frame in the stateless decoder
+	 */
+	if (!buf) {
+		rf->luma = NULL;
+		rf->cb = NULL;
+		rf->cr = NULL;
+		rf->alpha = NULL;
+		return 0;
+	}
+	switch (info->id) {
+	case V4L2_PIX_FMT_GREY:
+		rf->cb = NULL;
+		rf->cr = NULL;
+		break;
+	case V4L2_PIX_FMT_YUV420:
+		rf->cb = rf->luma + size;
+		rf->cr = rf->cb + size / 4;
+		break;
+	case V4L2_PIX_FMT_YVU420:
+		rf->cr = rf->luma + size;
+		rf->cb = rf->cr + size / 4;
+		break;
+	case V4L2_PIX_FMT_YUV422P:
+		rf->cb = rf->luma + size;
+		rf->cr = rf->cb + size / 2;
+		break;
+	case V4L2_PIX_FMT_NV12:
+	case V4L2_PIX_FMT_NV16:
+	case V4L2_PIX_FMT_NV24:
+		rf->cb = rf->luma + size;
+		rf->cr = rf->cb + 1;
+		break;
+	case V4L2_PIX_FMT_NV21:
+	case V4L2_PIX_FMT_NV61:
+	case V4L2_PIX_FMT_NV42:
+		rf->cr = rf->luma + size;
+		rf->cb = rf->cr + 1;
+		break;
+	case V4L2_PIX_FMT_YUYV:
+		rf->cb = rf->luma + 1;
+		rf->cr = rf->cb + 2;
+		break;
+	case V4L2_PIX_FMT_YVYU:
+		rf->cr = rf->luma + 1;
+		rf->cb = rf->cr + 2;
+		break;
+	case V4L2_PIX_FMT_UYVY:
+		rf->cb = rf->luma;
+		rf->cr = rf->cb + 2;
+		rf->luma++;
+		break;
+	case V4L2_PIX_FMT_VYUY:
+		rf->cr = rf->luma;
+		rf->cb = rf->cr + 2;
+		rf->luma++;
+		break;
+	case V4L2_PIX_FMT_RGB24:
+	case V4L2_PIX_FMT_HSV24:
+		rf->cr = rf->luma;
+		rf->cb = rf->cr + 2;
+		rf->luma++;
+		break;
+	case V4L2_PIX_FMT_BGR24:
+		rf->cb = rf->luma;
+		rf->cr = rf->cb + 2;
+		rf->luma++;
+		break;
+	case V4L2_PIX_FMT_RGB32:
+	case V4L2_PIX_FMT_XRGB32:
+	case V4L2_PIX_FMT_HSV32:
+	case V4L2_PIX_FMT_ARGB32:
+		rf->alpha = rf->luma;
+		rf->cr = rf->luma + 1;
+		rf->cb = rf->cr + 2;
+		rf->luma += 2;
+		break;
+	case V4L2_PIX_FMT_BGR32:
+	case V4L2_PIX_FMT_XBGR32:
+	case V4L2_PIX_FMT_ABGR32:
+		rf->cb = rf->luma;
+		rf->cr = rf->cb + 2;
+		rf->luma++;
+		rf->alpha = rf->cr + 1;
+		break;
+	case V4L2_PIX_FMT_BGRX32:
+	case V4L2_PIX_FMT_BGRA32:
+		rf->alpha = rf->luma;
+		rf->cb = rf->luma + 1;
+		rf->cr = rf->cb + 2;
+		rf->luma += 2;
+		break;
+	case V4L2_PIX_FMT_RGBX32:
+	case V4L2_PIX_FMT_RGBA32:
+		rf->alpha = rf->luma + 3;
+		rf->cr = rf->luma;
+		rf->cb = rf->cr + 2;
+		rf->luma++;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+int v4l2_fwht_encode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out)
+{
+	unsigned int size = state->stride * state->coded_height;
+	unsigned int chroma_stride = state->stride;
+	const struct v4l2_fwht_pixfmt_info *info = state->info;
+	struct fwht_cframe_hdr *p_hdr;
+	struct fwht_cframe cf;
+	struct fwht_raw_frame rf;
+	u32 encoding;
+	u32 flags = 0;
+
+	if (!info)
+		return -EINVAL;
+
+	if (prepare_raw_frame(&rf, info, p_in, size))
+		return -EINVAL;
+
+	if (info->planes_num == 3)
+		chroma_stride /= 2;
+
+	if (info->id == V4L2_PIX_FMT_NV24 ||
+	    info->id == V4L2_PIX_FMT_NV42)
+		chroma_stride *= 2;
+
+	cf.i_frame_qp = state->i_frame_qp;
+	cf.p_frame_qp = state->p_frame_qp;
+	cf.rlc_data = (__be16 *)(p_out + sizeof(*p_hdr));
+
+	encoding = fwht_encode_frame(&rf, &state->ref_frame, &cf,
+				     !state->gop_cnt,
+				     state->gop_cnt == state->gop_size - 1,
+				     state->visible_width,
+				     state->visible_height,
+				     state->stride, chroma_stride);
+	if (!(encoding & FWHT_FRAME_PCODED))
+		state->gop_cnt = 0;
+	if (++state->gop_cnt >= state->gop_size)
+		state->gop_cnt = 0;
+
+	p_hdr = (struct fwht_cframe_hdr *)p_out;
+	p_hdr->magic1 = FWHT_MAGIC1;
+	p_hdr->magic2 = FWHT_MAGIC2;
+	p_hdr->version = htonl(FWHT_VERSION);
+	p_hdr->width = htonl(state->visible_width);
+	p_hdr->height = htonl(state->visible_height);
+	flags |= (info->components_num - 1) << FWHT_FL_COMPONENTS_NUM_OFFSET;
+	flags |= info->pixenc;
+	if (encoding & FWHT_LUMA_UNENCODED)
+		flags |= FWHT_FL_LUMA_IS_UNCOMPRESSED;
+	if (encoding & FWHT_CB_UNENCODED)
+		flags |= FWHT_FL_CB_IS_UNCOMPRESSED;
+	if (encoding & FWHT_CR_UNENCODED)
+		flags |= FWHT_FL_CR_IS_UNCOMPRESSED;
+	if (encoding & FWHT_ALPHA_UNENCODED)
+		flags |= FWHT_FL_ALPHA_IS_UNCOMPRESSED;
+	if (!(encoding & FWHT_FRAME_PCODED))
+		flags |= FWHT_FL_I_FRAME;
+	if (rf.height_div == 1)
+		flags |= FWHT_FL_CHROMA_FULL_HEIGHT;
+	if (rf.width_div == 1)
+		flags |= FWHT_FL_CHROMA_FULL_WIDTH;
+	p_hdr->flags = htonl(flags);
+	p_hdr->colorspace = htonl(state->colorspace);
+	p_hdr->xfer_func = htonl(state->xfer_func);
+	p_hdr->ycbcr_enc = htonl(state->ycbcr_enc);
+	p_hdr->quantization = htonl(state->quantization);
+	p_hdr->size = htonl(cf.size);
+	return cf.size + sizeof(*p_hdr);
+}
+
+int v4l2_fwht_decode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out)
+{
+	u32 flags;
+	struct fwht_cframe cf;
+	unsigned int components_num = 3;
+	unsigned int version;
+	const struct v4l2_fwht_pixfmt_info *info;
+	unsigned int hdr_width_div, hdr_height_div;
+	struct fwht_raw_frame dst_rf;
+	unsigned int dst_chroma_stride = state->stride;
+	unsigned int ref_chroma_stride = state->ref_stride;
+	unsigned int dst_size = state->stride * state->coded_height;
+	unsigned int ref_size;
+
+	if (!state->info)
+		return -EINVAL;
+
+	info = state->info;
+
+	version = ntohl(state->header.version);
+	if (!version || version > FWHT_VERSION) {
+		pr_err("version %d is not supported, current version is %d\n",
+		       version, FWHT_VERSION);
+		return -EINVAL;
+	}
+
+	if (state->header.magic1 != FWHT_MAGIC1 ||
+	    state->header.magic2 != FWHT_MAGIC2)
+		return -EINVAL;
+
+	/* TODO: support resolution changes */
+	if (ntohl(state->header.width)  != state->visible_width ||
+	    ntohl(state->header.height) != state->visible_height)
+		return -EINVAL;
+
+	flags = ntohl(state->header.flags);
+
+	if (version >= 2) {
+		if ((flags & FWHT_FL_PIXENC_MSK) != info->pixenc)
+			return -EINVAL;
+		components_num = 1 + ((flags & FWHT_FL_COMPONENTS_NUM_MSK) >>
+				FWHT_FL_COMPONENTS_NUM_OFFSET);
+	}
+
+	if (components_num != info->components_num)
+		return -EINVAL;
+
+	state->colorspace = ntohl(state->header.colorspace);
+	state->xfer_func = ntohl(state->header.xfer_func);
+	state->ycbcr_enc = ntohl(state->header.ycbcr_enc);
+	state->quantization = ntohl(state->header.quantization);
+	cf.rlc_data = (__be16 *)p_in;
+	cf.size = ntohl(state->header.size);
+
+	hdr_width_div = (flags & FWHT_FL_CHROMA_FULL_WIDTH) ? 1 : 2;
+	hdr_height_div = (flags & FWHT_FL_CHROMA_FULL_HEIGHT) ? 1 : 2;
+	if (hdr_width_div != info->width_div ||
+	    hdr_height_div != info->height_div)
+		return -EINVAL;
+
+	if (prepare_raw_frame(&dst_rf, info, p_out, dst_size))
+		return -EINVAL;
+	if (info->planes_num == 3) {
+		dst_chroma_stride /= 2;
+		ref_chroma_stride /= 2;
+	}
+	if (info->id == V4L2_PIX_FMT_NV24 ||
+	    info->id == V4L2_PIX_FMT_NV42) {
+		dst_chroma_stride *= 2;
+		ref_chroma_stride *= 2;
+	}
+
+
+	ref_size = state->ref_stride * state->coded_height;
+
+	if (prepare_raw_frame(&state->ref_frame, info, state->ref_frame.buf,
+			      ref_size))
+		return -EINVAL;
+
+	if (!fwht_decode_frame(&cf, flags, components_num,
+			state->visible_width, state->visible_height,
+			&state->ref_frame, state->ref_stride, ref_chroma_stride,
+			&dst_rf, state->stride, dst_chroma_stride))
+		return -EINVAL;
+	return 0;
+}
diff --git a/drivers/media/test-drivers/vicodec/codec-v4l2-fwht.h b/drivers/media/test-drivers/vicodec/codec-v4l2-fwht.h
new file mode 100644
index 000000000000..1a0d2a9f931a
--- /dev/null
+++ b/drivers/media/test-drivers/vicodec/codec-v4l2-fwht.h
@@ -0,0 +1,64 @@
+/* SPDX-License-Identifier: LGPL-2.1 */
+/*
+ * Copyright 2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#ifndef CODEC_V4L2_FWHT_H
+#define CODEC_V4L2_FWHT_H
+
+#include "codec-fwht.h"
+
+struct v4l2_fwht_pixfmt_info {
+	u32 id;
+	unsigned int bytesperline_mult;
+	unsigned int sizeimage_mult;
+	unsigned int sizeimage_div;
+	unsigned int luma_alpha_step;
+	unsigned int chroma_step;
+	/* Chroma plane subsampling */
+	unsigned int width_div;
+	unsigned int height_div;
+	unsigned int components_num;
+	unsigned int planes_num;
+	unsigned int pixenc;
+};
+
+struct v4l2_fwht_state {
+	const struct v4l2_fwht_pixfmt_info *info;
+	unsigned int visible_width;
+	unsigned int visible_height;
+	unsigned int coded_width;
+	unsigned int coded_height;
+	unsigned int stride;
+	unsigned int ref_stride;
+	unsigned int gop_size;
+	unsigned int gop_cnt;
+	u16 i_frame_qp;
+	u16 p_frame_qp;
+
+	enum v4l2_colorspace colorspace;
+	enum v4l2_ycbcr_encoding ycbcr_enc;
+	enum v4l2_xfer_func xfer_func;
+	enum v4l2_quantization quantization;
+
+	struct fwht_raw_frame ref_frame;
+	struct fwht_cframe_hdr header;
+	u8 *compressed_frame;
+	u64 ref_frame_ts;
+};
+
+const struct v4l2_fwht_pixfmt_info *v4l2_fwht_find_pixfmt(u32 pixelformat);
+const struct v4l2_fwht_pixfmt_info *v4l2_fwht_get_pixfmt(u32 idx);
+bool v4l2_fwht_validate_fmt(const struct v4l2_fwht_pixfmt_info *info,
+			    u32 width_div, u32 height_div, u32 components_num,
+			    u32 pixenc);
+const struct v4l2_fwht_pixfmt_info *v4l2_fwht_find_nth_fmt(u32 width_div,
+							  u32 height_div,
+							  u32 components_num,
+							  u32 pixenc,
+							  unsigned int start_idx);
+
+int v4l2_fwht_encode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out);
+int v4l2_fwht_decode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out);
+
+#endif
diff --git a/drivers/media/test-drivers/vicodec/vicodec-core.c b/drivers/media/test-drivers/vicodec/vicodec-core.c
new file mode 100644
index 000000000000..30ced1c21387
--- /dev/null
+++ b/drivers/media/test-drivers/vicodec/vicodec-core.c
@@ -0,0 +1,2238 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * A virtual codec example device.
+ *
+ * Copyright 2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ *
+ * This is a virtual codec device driver for testing the codec framework.
+ * It simulates a device that uses memory buffers for both source and
+ * destination and encodes or decodes the data.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+
+#include <linux/platform_device.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-event.h>
+#include <media/videobuf2-vmalloc.h>
+
+#include "codec-v4l2-fwht.h"
+
+MODULE_DESCRIPTION("Virtual codec device");
+MODULE_AUTHOR("Hans Verkuil <hans.verkuil@cisco.com>");
+MODULE_LICENSE("GPL v2");
+
+static bool multiplanar;
+module_param(multiplanar, bool, 0444);
+MODULE_PARM_DESC(multiplanar,
+		 " use multi-planar API instead of single-planar API");
+
+static unsigned int debug;
+module_param(debug, uint, 0644);
+MODULE_PARM_DESC(debug, " activates debug info");
+
+#define VICODEC_NAME		"vicodec"
+#define MAX_WIDTH		4096U
+#define MIN_WIDTH		640U
+#define MAX_HEIGHT		2160U
+#define MIN_HEIGHT		360U
+
+#define dprintk(dev, fmt, arg...) \
+	v4l2_dbg(1, debug, &dev->v4l2_dev, "%s: " fmt, __func__, ## arg)
+
+
+struct pixfmt_info {
+	u32 id;
+	unsigned int bytesperline_mult;
+	unsigned int sizeimage_mult;
+	unsigned int sizeimage_div;
+	unsigned int luma_step;
+	unsigned int chroma_step;
+	/* Chroma plane subsampling */
+	unsigned int width_div;
+	unsigned int height_div;
+};
+
+static const struct v4l2_fwht_pixfmt_info pixfmt_fwht = {
+	V4L2_PIX_FMT_FWHT, 0, 3, 1, 1, 1, 1, 1, 0, 1
+};
+
+static const struct v4l2_fwht_pixfmt_info pixfmt_stateless_fwht = {
+	V4L2_PIX_FMT_FWHT_STATELESS, 0, 3, 1, 1, 1, 1, 1, 0, 1
+};
+
+static void vicodec_dev_release(struct device *dev)
+{
+}
+
+static struct platform_device vicodec_pdev = {
+	.name		= VICODEC_NAME,
+	.dev.release	= vicodec_dev_release,
+};
+
+/* Per-queue, driver-specific private data */
+struct vicodec_q_data {
+	unsigned int		coded_width;
+	unsigned int		coded_height;
+	unsigned int		visible_width;
+	unsigned int		visible_height;
+	unsigned int		sizeimage;
+	unsigned int		vb2_sizeimage;
+	unsigned int		sequence;
+	const struct v4l2_fwht_pixfmt_info *info;
+};
+
+enum {
+	V4L2_M2M_SRC = 0,
+	V4L2_M2M_DST = 1,
+};
+
+struct vicodec_dev_instance {
+	struct video_device     vfd;
+	struct mutex            mutex;
+	spinlock_t              lock;
+	struct v4l2_m2m_dev     *m2m_dev;
+};
+
+struct vicodec_dev {
+	struct v4l2_device	v4l2_dev;
+	struct vicodec_dev_instance stateful_enc;
+	struct vicodec_dev_instance stateful_dec;
+	struct vicodec_dev_instance stateless_dec;
+#ifdef CONFIG_MEDIA_CONTROLLER
+	struct media_device	mdev;
+#endif
+
+};
+
+struct vicodec_ctx {
+	struct v4l2_fh		fh;
+	struct vicodec_dev	*dev;
+	bool			is_enc;
+	bool			is_stateless;
+	spinlock_t		*lock;
+
+	struct v4l2_ctrl_handler hdl;
+
+	/* Source and destination queue data */
+	struct vicodec_q_data   q_data[2];
+	struct v4l2_fwht_state	state;
+
+	u32			cur_buf_offset;
+	u32			comp_max_size;
+	u32			comp_size;
+	u32			header_size;
+	u32			comp_magic_cnt;
+	bool			comp_has_frame;
+	bool			comp_has_next_frame;
+	bool			first_source_change_sent;
+	bool			source_changed;
+};
+
+static const struct v4l2_event vicodec_eos_event = {
+	.type = V4L2_EVENT_EOS
+};
+
+static inline struct vicodec_ctx *file2ctx(struct file *file)
+{
+	return container_of(file->private_data, struct vicodec_ctx, fh);
+}
+
+static struct vicodec_q_data *get_q_data(struct vicodec_ctx *ctx,
+					 enum v4l2_buf_type type)
+{
+	switch (type) {
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+		return &ctx->q_data[V4L2_M2M_SRC];
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+		return &ctx->q_data[V4L2_M2M_DST];
+	default:
+		break;
+	}
+	return NULL;
+}
+
+static void copy_cap_to_ref(const u8 *cap, const struct v4l2_fwht_pixfmt_info *info,
+		struct v4l2_fwht_state *state)
+{
+	int plane_idx;
+	u8 *p_ref = state->ref_frame.buf;
+	unsigned int cap_stride = state->stride;
+	unsigned int ref_stride = state->ref_stride;
+
+	for (plane_idx = 0; plane_idx < info->planes_num; plane_idx++) {
+		int i;
+		unsigned int h_div = (plane_idx == 1 || plane_idx == 2) ?
+			info->height_div : 1;
+		const u8 *row_cap = cap;
+		u8 *row_ref = p_ref;
+
+		if (info->planes_num == 3 && plane_idx == 1) {
+			cap_stride /= 2;
+			ref_stride /= 2;
+		}
+
+		if (plane_idx == 1 &&
+		    (info->id == V4L2_PIX_FMT_NV24 ||
+		     info->id == V4L2_PIX_FMT_NV42)) {
+			cap_stride *= 2;
+			ref_stride *= 2;
+		}
+
+		for (i = 0; i < state->visible_height / h_div; i++) {
+			memcpy(row_ref, row_cap, ref_stride);
+			row_ref += ref_stride;
+			row_cap += cap_stride;
+		}
+		cap += cap_stride * (state->coded_height / h_div);
+		p_ref += ref_stride * (state->coded_height / h_div);
+	}
+}
+
+static bool validate_by_version(unsigned int flags, unsigned int version)
+{
+	if (!version || version > FWHT_VERSION)
+		return false;
+
+	if (version >= 2) {
+		unsigned int components_num = 1 +
+			((flags & FWHT_FL_COMPONENTS_NUM_MSK) >>
+			 FWHT_FL_COMPONENTS_NUM_OFFSET);
+		unsigned int pixenc = flags & FWHT_FL_PIXENC_MSK;
+
+		if (components_num == 0 || components_num > 4 || !pixenc)
+			return false;
+	}
+	return true;
+}
+
+static bool validate_stateless_params_flags(const struct v4l2_ctrl_fwht_params *params,
+					    const struct v4l2_fwht_pixfmt_info *cur_info)
+{
+	unsigned int width_div =
+		(params->flags & FWHT_FL_CHROMA_FULL_WIDTH) ? 1 : 2;
+	unsigned int height_div =
+		(params->flags & FWHT_FL_CHROMA_FULL_HEIGHT) ? 1 : 2;
+	unsigned int components_num = 3;
+	unsigned int pixenc = 0;
+
+	if (params->version < 3)
+		return false;
+
+	components_num = 1 + ((params->flags & FWHT_FL_COMPONENTS_NUM_MSK) >>
+			      FWHT_FL_COMPONENTS_NUM_OFFSET);
+	pixenc = (params->flags & FWHT_FL_PIXENC_MSK);
+	if (v4l2_fwht_validate_fmt(cur_info, width_div, height_div,
+				    components_num, pixenc))
+		return true;
+	return false;
+}
+
+
+static void update_state_from_header(struct vicodec_ctx *ctx)
+{
+	const struct fwht_cframe_hdr *p_hdr = &ctx->state.header;
+
+	ctx->state.visible_width = ntohl(p_hdr->width);
+	ctx->state.visible_height = ntohl(p_hdr->height);
+	ctx->state.colorspace = ntohl(p_hdr->colorspace);
+	ctx->state.xfer_func = ntohl(p_hdr->xfer_func);
+	ctx->state.ycbcr_enc = ntohl(p_hdr->ycbcr_enc);
+	ctx->state.quantization = ntohl(p_hdr->quantization);
+}
+
+static int device_process(struct vicodec_ctx *ctx,
+			  struct vb2_v4l2_buffer *src_vb,
+			  struct vb2_v4l2_buffer *dst_vb)
+{
+	struct vicodec_dev *dev = ctx->dev;
+	struct v4l2_fwht_state *state = &ctx->state;
+	u8 *p_src, *p_dst;
+	int ret = 0;
+
+	if (ctx->is_enc || ctx->is_stateless)
+		p_src = vb2_plane_vaddr(&src_vb->vb2_buf, 0);
+	else
+		p_src = state->compressed_frame;
+
+	if (ctx->is_stateless) {
+		struct media_request *src_req = src_vb->vb2_buf.req_obj.req;
+
+		ret = v4l2_ctrl_request_setup(src_req, &ctx->hdl);
+		if (ret)
+			return ret;
+		update_state_from_header(ctx);
+
+		ctx->state.header.size =
+			htonl(vb2_get_plane_payload(&src_vb->vb2_buf, 0));
+		/*
+		 * set the reference buffer from the reference timestamp
+		 * only if this is a P-frame
+		 */
+		if (!(ntohl(ctx->state.header.flags) & FWHT_FL_I_FRAME)) {
+			struct vb2_buffer *ref_vb2_buf;
+			int ref_buf_idx;
+			struct vb2_queue *vq_cap =
+				v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
+						V4L2_BUF_TYPE_VIDEO_CAPTURE);
+
+			ref_buf_idx = vb2_find_timestamp(vq_cap,
+							 ctx->state.ref_frame_ts, 0);
+			if (ref_buf_idx < 0)
+				return -EINVAL;
+
+			ref_vb2_buf = vq_cap->bufs[ref_buf_idx];
+			if (ref_vb2_buf->state == VB2_BUF_STATE_ERROR)
+				ret = -EINVAL;
+			ctx->state.ref_frame.buf =
+				vb2_plane_vaddr(ref_vb2_buf, 0);
+		} else {
+			ctx->state.ref_frame.buf = NULL;
+		}
+	}
+	p_dst = vb2_plane_vaddr(&dst_vb->vb2_buf, 0);
+	if (!p_src || !p_dst) {
+		v4l2_err(&dev->v4l2_dev,
+			 "Acquiring kernel pointers to buffers failed\n");
+		return -EFAULT;
+	}
+
+	if (ctx->is_enc) {
+		struct vicodec_q_data *q_src;
+		int comp_sz_or_errcode;
+
+		q_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+		state->info = q_src->info;
+		comp_sz_or_errcode = v4l2_fwht_encode(state, p_src, p_dst);
+		if (comp_sz_or_errcode < 0)
+			return comp_sz_or_errcode;
+		vb2_set_plane_payload(&dst_vb->vb2_buf, 0, comp_sz_or_errcode);
+	} else {
+		struct vicodec_q_data *q_dst;
+		unsigned int comp_frame_size = ntohl(ctx->state.header.size);
+
+		q_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+		if (comp_frame_size > ctx->comp_max_size)
+			return -EINVAL;
+		state->info = q_dst->info;
+		ret = v4l2_fwht_decode(state, p_src, p_dst);
+		if (ret < 0)
+			return ret;
+		if (!ctx->is_stateless)
+			copy_cap_to_ref(p_dst, ctx->state.info, &ctx->state);
+
+		vb2_set_plane_payload(&dst_vb->vb2_buf, 0, q_dst->sizeimage);
+		if (ntohl(ctx->state.header.flags) & FWHT_FL_I_FRAME)
+			dst_vb->flags |= V4L2_BUF_FLAG_KEYFRAME;
+		else
+			dst_vb->flags |= V4L2_BUF_FLAG_PFRAME;
+	}
+	return ret;
+}
+
+/*
+ * mem2mem callbacks
+ */
+static enum vb2_buffer_state get_next_header(struct vicodec_ctx *ctx,
+					     u8 **pp, u32 sz)
+{
+	static const u8 magic[] = {
+		0x4f, 0x4f, 0x4f, 0x4f, 0xff, 0xff, 0xff, 0xff
+	};
+	u8 *p = *pp;
+	u32 state;
+	u8 *header = (u8 *)&ctx->state.header;
+
+	state = VB2_BUF_STATE_DONE;
+
+	if (!ctx->header_size) {
+		state = VB2_BUF_STATE_ERROR;
+		for (; p < *pp + sz; p++) {
+			u32 copy;
+
+			p = memchr(p, magic[ctx->comp_magic_cnt],
+				   *pp + sz - p);
+			if (!p) {
+				ctx->comp_magic_cnt = 0;
+				p = *pp + sz;
+				break;
+			}
+			copy = sizeof(magic) - ctx->comp_magic_cnt;
+			if (*pp + sz - p < copy)
+				copy = *pp + sz - p;
+
+			memcpy(header + ctx->comp_magic_cnt, p, copy);
+			ctx->comp_magic_cnt += copy;
+			if (!memcmp(header, magic, ctx->comp_magic_cnt)) {
+				p += copy;
+				state = VB2_BUF_STATE_DONE;
+				break;
+			}
+			ctx->comp_magic_cnt = 0;
+		}
+		if (ctx->comp_magic_cnt < sizeof(magic)) {
+			*pp = p;
+			return state;
+		}
+		ctx->header_size = sizeof(magic);
+	}
+
+	if (ctx->header_size < sizeof(struct fwht_cframe_hdr)) {
+		u32 copy = sizeof(struct fwht_cframe_hdr) - ctx->header_size;
+
+		if (*pp + sz - p < copy)
+			copy = *pp + sz - p;
+
+		memcpy(header + ctx->header_size, p, copy);
+		p += copy;
+		ctx->header_size += copy;
+	}
+	*pp = p;
+	return state;
+}
+
+/* device_run() - prepares and starts the device */
+static void device_run(void *priv)
+{
+	struct vicodec_ctx *ctx = priv;
+	struct vicodec_dev *dev = ctx->dev;
+	struct vb2_v4l2_buffer *src_buf, *dst_buf;
+	struct vicodec_q_data *q_src, *q_dst;
+	u32 state;
+	struct media_request *src_req;
+
+	src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
+	dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
+	src_req = src_buf->vb2_buf.req_obj.req;
+
+	q_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+	q_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+
+	state = VB2_BUF_STATE_DONE;
+	if (device_process(ctx, src_buf, dst_buf))
+		state = VB2_BUF_STATE_ERROR;
+	else
+		dst_buf->sequence = q_dst->sequence++;
+	dst_buf->flags &= ~V4L2_BUF_FLAG_LAST;
+	v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, false);
+
+	spin_lock(ctx->lock);
+	if (!ctx->comp_has_next_frame &&
+	    v4l2_m2m_is_last_draining_src_buf(ctx->fh.m2m_ctx, src_buf)) {
+		dst_buf->flags |= V4L2_BUF_FLAG_LAST;
+		v4l2_event_queue_fh(&ctx->fh, &vicodec_eos_event);
+		v4l2_m2m_mark_stopped(ctx->fh.m2m_ctx);
+	}
+	if (ctx->is_enc || ctx->is_stateless) {
+		src_buf->sequence = q_src->sequence++;
+		src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+		v4l2_m2m_buf_done(src_buf, state);
+	} else if (vb2_get_plane_payload(&src_buf->vb2_buf, 0) == ctx->cur_buf_offset) {
+		src_buf->sequence = q_src->sequence++;
+		src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+		v4l2_m2m_buf_done(src_buf, state);
+		ctx->cur_buf_offset = 0;
+		ctx->comp_has_next_frame = false;
+	}
+	v4l2_m2m_buf_done(dst_buf, state);
+
+	ctx->comp_size = 0;
+	ctx->header_size = 0;
+	ctx->comp_magic_cnt = 0;
+	ctx->comp_has_frame = false;
+	spin_unlock(ctx->lock);
+	if (ctx->is_stateless && src_req)
+		v4l2_ctrl_request_complete(src_req, &ctx->hdl);
+
+	if (ctx->is_enc)
+		v4l2_m2m_job_finish(dev->stateful_enc.m2m_dev, ctx->fh.m2m_ctx);
+	else if (ctx->is_stateless)
+		v4l2_m2m_job_finish(dev->stateless_dec.m2m_dev,
+				    ctx->fh.m2m_ctx);
+	else
+		v4l2_m2m_job_finish(dev->stateful_dec.m2m_dev, ctx->fh.m2m_ctx);
+}
+
+static void job_remove_src_buf(struct vicodec_ctx *ctx, u32 state)
+{
+	struct vb2_v4l2_buffer *src_buf;
+	struct vicodec_q_data *q_src;
+
+	q_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+	spin_lock(ctx->lock);
+	src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+	src_buf->sequence = q_src->sequence++;
+	v4l2_m2m_buf_done(src_buf, state);
+	ctx->cur_buf_offset = 0;
+	spin_unlock(ctx->lock);
+}
+
+static const struct v4l2_fwht_pixfmt_info *
+info_from_header(const struct fwht_cframe_hdr *p_hdr)
+{
+	unsigned int flags = ntohl(p_hdr->flags);
+	unsigned int width_div = (flags & FWHT_FL_CHROMA_FULL_WIDTH) ? 1 : 2;
+	unsigned int height_div = (flags & FWHT_FL_CHROMA_FULL_HEIGHT) ? 1 : 2;
+	unsigned int components_num = 3;
+	unsigned int pixenc = 0;
+	unsigned int version = ntohl(p_hdr->version);
+
+	if (version >= 2) {
+		components_num = 1 + ((flags & FWHT_FL_COMPONENTS_NUM_MSK) >>
+				FWHT_FL_COMPONENTS_NUM_OFFSET);
+		pixenc = (flags & FWHT_FL_PIXENC_MSK);
+	}
+	return v4l2_fwht_find_nth_fmt(width_div, height_div,
+				     components_num, pixenc, 0);
+}
+
+static bool is_header_valid(const struct fwht_cframe_hdr *p_hdr)
+{
+	const struct v4l2_fwht_pixfmt_info *info;
+	unsigned int w = ntohl(p_hdr->width);
+	unsigned int h = ntohl(p_hdr->height);
+	unsigned int version = ntohl(p_hdr->version);
+	unsigned int flags = ntohl(p_hdr->flags);
+
+	if (w < MIN_WIDTH || w > MAX_WIDTH || h < MIN_HEIGHT || h > MAX_HEIGHT)
+		return false;
+
+	if (!validate_by_version(flags, version))
+		return false;
+
+	info = info_from_header(p_hdr);
+	if (!info)
+		return false;
+	return true;
+}
+
+static void update_capture_data_from_header(struct vicodec_ctx *ctx)
+{
+	struct vicodec_q_data *q_dst = get_q_data(ctx,
+						  V4L2_BUF_TYPE_VIDEO_CAPTURE);
+	const struct fwht_cframe_hdr *p_hdr = &ctx->state.header;
+	const struct v4l2_fwht_pixfmt_info *info = info_from_header(p_hdr);
+	unsigned int flags = ntohl(p_hdr->flags);
+	unsigned int hdr_width_div = (flags & FWHT_FL_CHROMA_FULL_WIDTH) ? 1 : 2;
+	unsigned int hdr_height_div = (flags & FWHT_FL_CHROMA_FULL_HEIGHT) ? 1 : 2;
+
+	/*
+	 * This function should not be used by a stateless codec since
+	 * it changes values in q_data that are not request specific
+	 */
+	WARN_ON(ctx->is_stateless);
+
+	q_dst->info = info;
+	q_dst->visible_width = ntohl(p_hdr->width);
+	q_dst->visible_height = ntohl(p_hdr->height);
+	q_dst->coded_width = vic_round_dim(q_dst->visible_width, hdr_width_div);
+	q_dst->coded_height = vic_round_dim(q_dst->visible_height,
+					    hdr_height_div);
+
+	q_dst->sizeimage = q_dst->coded_width * q_dst->coded_height *
+		q_dst->info->sizeimage_mult / q_dst->info->sizeimage_div;
+	ctx->state.colorspace = ntohl(p_hdr->colorspace);
+
+	ctx->state.xfer_func = ntohl(p_hdr->xfer_func);
+	ctx->state.ycbcr_enc = ntohl(p_hdr->ycbcr_enc);
+	ctx->state.quantization = ntohl(p_hdr->quantization);
+}
+
+static void set_last_buffer(struct vb2_v4l2_buffer *dst_buf,
+			    const struct vb2_v4l2_buffer *src_buf,
+			    struct vicodec_ctx *ctx)
+{
+	struct vicodec_q_data *q_dst = get_q_data(ctx,
+						  V4L2_BUF_TYPE_VIDEO_CAPTURE);
+
+	vb2_set_plane_payload(&dst_buf->vb2_buf, 0, 0);
+	dst_buf->sequence = q_dst->sequence++;
+
+	v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, !ctx->is_enc);
+	dst_buf->flags |= V4L2_BUF_FLAG_LAST;
+	v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
+}
+
+static int job_ready(void *priv)
+{
+	static const u8 magic[] = {
+		0x4f, 0x4f, 0x4f, 0x4f, 0xff, 0xff, 0xff, 0xff
+	};
+	struct vicodec_ctx *ctx = priv;
+	struct vb2_v4l2_buffer *src_buf;
+	u8 *p_src;
+	u8 *p;
+	u32 sz;
+	u32 state;
+	struct vicodec_q_data *q_dst = get_q_data(ctx,
+						  V4L2_BUF_TYPE_VIDEO_CAPTURE);
+	unsigned int flags;
+	unsigned int hdr_width_div;
+	unsigned int hdr_height_div;
+	unsigned int max_to_copy;
+	unsigned int comp_frame_size;
+
+	if (ctx->source_changed)
+		return 0;
+	if (ctx->is_stateless || ctx->is_enc || ctx->comp_has_frame)
+		return 1;
+
+restart:
+	ctx->comp_has_next_frame = false;
+	src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
+	if (!src_buf)
+		return 0;
+	p_src = vb2_plane_vaddr(&src_buf->vb2_buf, 0);
+	sz = vb2_get_plane_payload(&src_buf->vb2_buf, 0);
+	p = p_src + ctx->cur_buf_offset;
+
+	state = VB2_BUF_STATE_DONE;
+
+	if (ctx->header_size < sizeof(struct fwht_cframe_hdr)) {
+		state = get_next_header(ctx, &p, p_src + sz - p);
+		if (ctx->header_size < sizeof(struct fwht_cframe_hdr)) {
+			if (v4l2_m2m_is_last_draining_src_buf(ctx->fh.m2m_ctx,
+							      src_buf))
+				return 1;
+			job_remove_src_buf(ctx, state);
+			goto restart;
+		}
+	}
+
+	comp_frame_size = ntohl(ctx->state.header.size);
+
+	/*
+	 * The current scanned frame might be the first frame of a new
+	 * resolution so its size might be larger than ctx->comp_max_size.
+	 * In that case it is copied up to the current buffer capacity and
+	 * the copy will continue after allocating new large enough buffer
+	 * when restreaming
+	 */
+	max_to_copy = min(comp_frame_size, ctx->comp_max_size);
+
+	if (ctx->comp_size < max_to_copy) {
+		u32 copy = max_to_copy - ctx->comp_size;
+
+		if (copy > p_src + sz - p)
+			copy = p_src + sz - p;
+
+		memcpy(ctx->state.compressed_frame + ctx->comp_size,
+		       p, copy);
+		p += copy;
+		ctx->comp_size += copy;
+		if (ctx->comp_size < max_to_copy) {
+			if (v4l2_m2m_is_last_draining_src_buf(ctx->fh.m2m_ctx,
+							      src_buf))
+				return 1;
+			job_remove_src_buf(ctx, state);
+			goto restart;
+		}
+	}
+	ctx->cur_buf_offset = p - p_src;
+	if (ctx->comp_size == comp_frame_size)
+		ctx->comp_has_frame = true;
+	ctx->comp_has_next_frame = false;
+	if (ctx->comp_has_frame && sz - ctx->cur_buf_offset >=
+			sizeof(struct fwht_cframe_hdr)) {
+		struct fwht_cframe_hdr *p_hdr = (struct fwht_cframe_hdr *)p;
+		u32 frame_size = ntohl(p_hdr->size);
+		u32 remaining = sz - ctx->cur_buf_offset - sizeof(*p_hdr);
+
+		if (!memcmp(p, magic, sizeof(magic)))
+			ctx->comp_has_next_frame = remaining >= frame_size;
+	}
+	/*
+	 * if the header is invalid the device_run will just drop the frame
+	 * with an error
+	 */
+	if (!is_header_valid(&ctx->state.header) && ctx->comp_has_frame)
+		return 1;
+	flags = ntohl(ctx->state.header.flags);
+	hdr_width_div = (flags & FWHT_FL_CHROMA_FULL_WIDTH) ? 1 : 2;
+	hdr_height_div = (flags & FWHT_FL_CHROMA_FULL_HEIGHT) ? 1 : 2;
+
+	if (ntohl(ctx->state.header.width) != q_dst->visible_width ||
+	    ntohl(ctx->state.header.height) != q_dst->visible_height ||
+	    !q_dst->info ||
+	    hdr_width_div != q_dst->info->width_div ||
+	    hdr_height_div != q_dst->info->height_div) {
+		static const struct v4l2_event rs_event = {
+			.type = V4L2_EVENT_SOURCE_CHANGE,
+			.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION,
+		};
+
+		struct vb2_v4l2_buffer *dst_buf =
+			v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
+
+		update_capture_data_from_header(ctx);
+		v4l2_event_queue_fh(&ctx->fh, &rs_event);
+		set_last_buffer(dst_buf, src_buf, ctx);
+		ctx->source_changed = true;
+		return 0;
+	}
+	return 1;
+}
+
+/*
+ * video ioctls
+ */
+
+static const struct v4l2_fwht_pixfmt_info *find_fmt(u32 fmt)
+{
+	const struct v4l2_fwht_pixfmt_info *info =
+		v4l2_fwht_find_pixfmt(fmt);
+
+	if (!info)
+		info = v4l2_fwht_get_pixfmt(0);
+	return info;
+}
+
+static int vidioc_querycap(struct file *file, void *priv,
+			   struct v4l2_capability *cap)
+{
+	strscpy(cap->driver, VICODEC_NAME, sizeof(cap->driver));
+	strscpy(cap->card, VICODEC_NAME, sizeof(cap->card));
+	snprintf(cap->bus_info, sizeof(cap->bus_info),
+			"platform:%s", VICODEC_NAME);
+	return 0;
+}
+
+static int enum_fmt(struct v4l2_fmtdesc *f, struct vicodec_ctx *ctx,
+		    bool is_out)
+{
+	bool is_uncomp = (ctx->is_enc && is_out) || (!ctx->is_enc && !is_out);
+
+	if (V4L2_TYPE_IS_MULTIPLANAR(f->type) && !multiplanar)
+		return -EINVAL;
+	if (!V4L2_TYPE_IS_MULTIPLANAR(f->type) && multiplanar)
+		return -EINVAL;
+
+	if (is_uncomp) {
+		const struct v4l2_fwht_pixfmt_info *info =
+					get_q_data(ctx, f->type)->info;
+
+		if (ctx->is_enc ||
+		    !vb2_is_streaming(&ctx->fh.m2m_ctx->cap_q_ctx.q))
+			info = v4l2_fwht_get_pixfmt(f->index);
+		else
+			info = v4l2_fwht_find_nth_fmt(info->width_div,
+						     info->height_div,
+						     info->components_num,
+						     info->pixenc,
+						     f->index);
+		if (!info)
+			return -EINVAL;
+		f->pixelformat = info->id;
+	} else {
+		if (f->index)
+			return -EINVAL;
+		f->pixelformat = ctx->is_stateless ?
+			V4L2_PIX_FMT_FWHT_STATELESS : V4L2_PIX_FMT_FWHT;
+		if (!ctx->is_enc && !ctx->is_stateless)
+			f->flags = V4L2_FMT_FLAG_DYN_RESOLUTION |
+				   V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM;
+	}
+	return 0;
+}
+
+static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
+				   struct v4l2_fmtdesc *f)
+{
+	struct vicodec_ctx *ctx = file2ctx(file);
+
+	return enum_fmt(f, ctx, false);
+}
+
+static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
+				   struct v4l2_fmtdesc *f)
+{
+	struct vicodec_ctx *ctx = file2ctx(file);
+
+	return enum_fmt(f, ctx, true);
+}
+
+static int vidioc_g_fmt(struct vicodec_ctx *ctx, struct v4l2_format *f)
+{
+	struct vb2_queue *vq;
+	struct vicodec_q_data *q_data;
+	struct v4l2_pix_format_mplane *pix_mp;
+	struct v4l2_pix_format *pix;
+	const struct v4l2_fwht_pixfmt_info *info;
+
+	vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
+	if (!vq)
+		return -EINVAL;
+
+	q_data = get_q_data(ctx, f->type);
+	info = q_data->info;
+
+	switch (f->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+		if (multiplanar)
+			return -EINVAL;
+		pix = &f->fmt.pix;
+		pix->width = q_data->coded_width;
+		pix->height = q_data->coded_height;
+		pix->field = V4L2_FIELD_NONE;
+		pix->pixelformat = info->id;
+		pix->bytesperline = q_data->coded_width *
+					info->bytesperline_mult;
+		pix->sizeimage = q_data->sizeimage;
+		pix->colorspace = ctx->state.colorspace;
+		pix->xfer_func = ctx->state.xfer_func;
+		pix->ycbcr_enc = ctx->state.ycbcr_enc;
+		pix->quantization = ctx->state.quantization;
+		break;
+
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+		if (!multiplanar)
+			return -EINVAL;
+		pix_mp = &f->fmt.pix_mp;
+		pix_mp->width = q_data->coded_width;
+		pix_mp->height = q_data->coded_height;
+		pix_mp->field = V4L2_FIELD_NONE;
+		pix_mp->pixelformat = info->id;
+		pix_mp->num_planes = 1;
+		pix_mp->plane_fmt[0].bytesperline =
+				q_data->coded_width * info->bytesperline_mult;
+		pix_mp->plane_fmt[0].sizeimage = q_data->sizeimage;
+		pix_mp->colorspace = ctx->state.colorspace;
+		pix_mp->xfer_func = ctx->state.xfer_func;
+		pix_mp->ycbcr_enc = ctx->state.ycbcr_enc;
+		pix_mp->quantization = ctx->state.quantization;
+		memset(pix_mp->reserved, 0, sizeof(pix_mp->reserved));
+		memset(pix_mp->plane_fmt[0].reserved, 0,
+		       sizeof(pix_mp->plane_fmt[0].reserved));
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int vidioc_g_fmt_vid_out(struct file *file, void *priv,
+				struct v4l2_format *f)
+{
+	return vidioc_g_fmt(file2ctx(file), f);
+}
+
+static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
+				struct v4l2_format *f)
+{
+	return vidioc_g_fmt(file2ctx(file), f);
+}
+
+static int vidioc_try_fmt(struct vicodec_ctx *ctx, struct v4l2_format *f)
+{
+	struct v4l2_pix_format_mplane *pix_mp;
+	struct v4l2_pix_format *pix;
+	struct v4l2_plane_pix_format *plane;
+	const struct v4l2_fwht_pixfmt_info *info = ctx->is_stateless ?
+		&pixfmt_stateless_fwht : &pixfmt_fwht;
+
+	switch (f->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+		pix = &f->fmt.pix;
+		if (pix->pixelformat != V4L2_PIX_FMT_FWHT &&
+		    pix->pixelformat != V4L2_PIX_FMT_FWHT_STATELESS)
+			info = find_fmt(pix->pixelformat);
+
+		pix->width = clamp(pix->width, MIN_WIDTH, MAX_WIDTH);
+		pix->width = vic_round_dim(pix->width, info->width_div);
+
+		pix->height = clamp(pix->height, MIN_HEIGHT, MAX_HEIGHT);
+		pix->height = vic_round_dim(pix->height, info->height_div);
+
+		pix->field = V4L2_FIELD_NONE;
+		pix->bytesperline =
+			pix->width * info->bytesperline_mult;
+		pix->sizeimage = pix->width * pix->height *
+			info->sizeimage_mult / info->sizeimage_div;
+		if (pix->pixelformat == V4L2_PIX_FMT_FWHT)
+			pix->sizeimage += sizeof(struct fwht_cframe_hdr);
+		break;
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+		pix_mp = &f->fmt.pix_mp;
+		plane = pix_mp->plane_fmt;
+		if (pix_mp->pixelformat != V4L2_PIX_FMT_FWHT &&
+		    pix_mp->pixelformat != V4L2_PIX_FMT_FWHT_STATELESS)
+			info = find_fmt(pix_mp->pixelformat);
+		pix_mp->num_planes = 1;
+
+		pix_mp->width = clamp(pix_mp->width, MIN_WIDTH, MAX_WIDTH);
+		pix_mp->width = vic_round_dim(pix_mp->width, info->width_div);
+
+		pix_mp->height = clamp(pix_mp->height, MIN_HEIGHT, MAX_HEIGHT);
+		pix_mp->height = vic_round_dim(pix_mp->height,
+					       info->height_div);
+
+		pix_mp->field = V4L2_FIELD_NONE;
+		plane->bytesperline =
+			pix_mp->width * info->bytesperline_mult;
+		plane->sizeimage = pix_mp->width * pix_mp->height *
+			info->sizeimage_mult / info->sizeimage_div;
+		if (pix_mp->pixelformat == V4L2_PIX_FMT_FWHT)
+			plane->sizeimage += sizeof(struct fwht_cframe_hdr);
+		memset(pix_mp->reserved, 0, sizeof(pix_mp->reserved));
+		memset(plane->reserved, 0, sizeof(plane->reserved));
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
+				  struct v4l2_format *f)
+{
+	struct vicodec_ctx *ctx = file2ctx(file);
+	struct v4l2_pix_format_mplane *pix_mp;
+	struct v4l2_pix_format *pix;
+
+	switch (f->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		if (multiplanar)
+			return -EINVAL;
+		pix = &f->fmt.pix;
+		pix->pixelformat = ctx->is_enc ? V4L2_PIX_FMT_FWHT :
+				   find_fmt(f->fmt.pix.pixelformat)->id;
+		pix->colorspace = ctx->state.colorspace;
+		pix->xfer_func = ctx->state.xfer_func;
+		pix->ycbcr_enc = ctx->state.ycbcr_enc;
+		pix->quantization = ctx->state.quantization;
+		break;
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+		if (!multiplanar)
+			return -EINVAL;
+		pix_mp = &f->fmt.pix_mp;
+		pix_mp->pixelformat = ctx->is_enc ? V4L2_PIX_FMT_FWHT :
+				      find_fmt(pix_mp->pixelformat)->id;
+		pix_mp->colorspace = ctx->state.colorspace;
+		pix_mp->xfer_func = ctx->state.xfer_func;
+		pix_mp->ycbcr_enc = ctx->state.ycbcr_enc;
+		pix_mp->quantization = ctx->state.quantization;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return vidioc_try_fmt(ctx, f);
+}
+
+static int vidioc_try_fmt_vid_out(struct file *file, void *priv,
+				  struct v4l2_format *f)
+{
+	struct vicodec_ctx *ctx = file2ctx(file);
+	struct v4l2_pix_format_mplane *pix_mp;
+	struct v4l2_pix_format *pix;
+
+	switch (f->type) {
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+		if (multiplanar)
+			return -EINVAL;
+		pix = &f->fmt.pix;
+		if (ctx->is_enc)
+			pix->pixelformat = find_fmt(pix->pixelformat)->id;
+		else if (ctx->is_stateless)
+			pix->pixelformat = V4L2_PIX_FMT_FWHT_STATELESS;
+		else
+			pix->pixelformat = V4L2_PIX_FMT_FWHT;
+		if (!pix->colorspace)
+			pix->colorspace = V4L2_COLORSPACE_REC709;
+		break;
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+		if (!multiplanar)
+			return -EINVAL;
+		pix_mp = &f->fmt.pix_mp;
+		if (ctx->is_enc)
+			pix_mp->pixelformat = find_fmt(pix_mp->pixelformat)->id;
+		else if (ctx->is_stateless)
+			pix_mp->pixelformat = V4L2_PIX_FMT_FWHT_STATELESS;
+		else
+			pix_mp->pixelformat = V4L2_PIX_FMT_FWHT;
+		if (!pix_mp->colorspace)
+			pix_mp->colorspace = V4L2_COLORSPACE_REC709;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return vidioc_try_fmt(ctx, f);
+}
+
+static int vidioc_s_fmt(struct vicodec_ctx *ctx, struct v4l2_format *f)
+{
+	struct vicodec_q_data *q_data;
+	struct vb2_queue *vq;
+	bool fmt_changed = true;
+	struct v4l2_pix_format_mplane *pix_mp;
+	struct v4l2_pix_format *pix;
+
+	vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
+	if (!vq)
+		return -EINVAL;
+
+	q_data = get_q_data(ctx, f->type);
+	if (!q_data)
+		return -EINVAL;
+
+	switch (f->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+		pix = &f->fmt.pix;
+		if (ctx->is_enc && V4L2_TYPE_IS_OUTPUT(f->type))
+			fmt_changed =
+				!q_data->info ||
+				q_data->info->id != pix->pixelformat ||
+				q_data->coded_width != pix->width ||
+				q_data->coded_height != pix->height;
+
+		if (vb2_is_busy(vq) && fmt_changed)
+			return -EBUSY;
+
+		if (pix->pixelformat == V4L2_PIX_FMT_FWHT)
+			q_data->info = &pixfmt_fwht;
+		else if (pix->pixelformat == V4L2_PIX_FMT_FWHT_STATELESS)
+			q_data->info = &pixfmt_stateless_fwht;
+		else
+			q_data->info = find_fmt(pix->pixelformat);
+		q_data->coded_width = pix->width;
+		q_data->coded_height = pix->height;
+		q_data->sizeimage = pix->sizeimage;
+		break;
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+		pix_mp = &f->fmt.pix_mp;
+		if (ctx->is_enc && V4L2_TYPE_IS_OUTPUT(f->type))
+			fmt_changed =
+				!q_data->info ||
+				q_data->info->id != pix_mp->pixelformat ||
+				q_data->coded_width != pix_mp->width ||
+				q_data->coded_height != pix_mp->height;
+
+		if (vb2_is_busy(vq) && fmt_changed)
+			return -EBUSY;
+
+		if (pix_mp->pixelformat == V4L2_PIX_FMT_FWHT)
+			q_data->info = &pixfmt_fwht;
+		else if (pix_mp->pixelformat == V4L2_PIX_FMT_FWHT_STATELESS)
+			q_data->info = &pixfmt_stateless_fwht;
+		else
+			q_data->info = find_fmt(pix_mp->pixelformat);
+		q_data->coded_width = pix_mp->width;
+		q_data->coded_height = pix_mp->height;
+		q_data->sizeimage = pix_mp->plane_fmt[0].sizeimage;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	dprintk(ctx->dev,
+		"Setting format for type %d, coded wxh: %dx%d, fourcc: 0x%08x\n",
+		f->type, q_data->coded_width, q_data->coded_height,
+		q_data->info->id);
+
+	return 0;
+}
+
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+				struct v4l2_format *f)
+{
+	int ret;
+
+	ret = vidioc_try_fmt_vid_cap(file, priv, f);
+	if (ret)
+		return ret;
+
+	return vidioc_s_fmt(file2ctx(file), f);
+}
+
+static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
+				struct v4l2_format *f)
+{
+	struct vicodec_ctx *ctx = file2ctx(file);
+	struct vicodec_q_data *q_data;
+	struct vicodec_q_data *q_data_cap;
+	struct v4l2_pix_format *pix;
+	struct v4l2_pix_format_mplane *pix_mp;
+	u32 coded_w = 0, coded_h = 0;
+	unsigned int size = 0;
+	int ret;
+
+	q_data = get_q_data(ctx, f->type);
+	q_data_cap = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+
+	ret = vidioc_try_fmt_vid_out(file, priv, f);
+	if (ret)
+		return ret;
+
+	if (ctx->is_enc) {
+		struct vb2_queue *vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
+		struct vb2_queue *vq_cap = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
+							   V4L2_BUF_TYPE_VIDEO_CAPTURE);
+		const struct v4l2_fwht_pixfmt_info *info = ctx->is_stateless ?
+			&pixfmt_stateless_fwht : &pixfmt_fwht;
+
+		if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
+			coded_w = f->fmt.pix.width;
+			coded_h = f->fmt.pix.height;
+		} else {
+			coded_w = f->fmt.pix_mp.width;
+			coded_h = f->fmt.pix_mp.height;
+		}
+		if (vb2_is_busy(vq) && (coded_w != q_data->coded_width ||
+					coded_h != q_data->coded_height))
+			return -EBUSY;
+		size = coded_w * coded_h *
+			info->sizeimage_mult / info->sizeimage_div;
+		if (!ctx->is_stateless)
+			size += sizeof(struct fwht_cframe_hdr);
+
+		if (vb2_is_busy(vq_cap) && size > q_data_cap->sizeimage)
+			return -EBUSY;
+	}
+
+	ret = vidioc_s_fmt(file2ctx(file), f);
+	if (!ret) {
+		if (ctx->is_enc) {
+			q_data->visible_width = coded_w;
+			q_data->visible_height = coded_h;
+			q_data_cap->coded_width = coded_w;
+			q_data_cap->coded_height = coded_h;
+			q_data_cap->sizeimage = size;
+		}
+
+		switch (f->type) {
+		case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+			pix = &f->fmt.pix;
+			ctx->state.colorspace = pix->colorspace;
+			ctx->state.xfer_func = pix->xfer_func;
+			ctx->state.ycbcr_enc = pix->ycbcr_enc;
+			ctx->state.quantization = pix->quantization;
+			break;
+		case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+			pix_mp = &f->fmt.pix_mp;
+			ctx->state.colorspace = pix_mp->colorspace;
+			ctx->state.xfer_func = pix_mp->xfer_func;
+			ctx->state.ycbcr_enc = pix_mp->ycbcr_enc;
+			ctx->state.quantization = pix_mp->quantization;
+			break;
+		default:
+			break;
+		}
+	}
+	return ret;
+}
+
+static int vidioc_g_selection(struct file *file, void *priv,
+			      struct v4l2_selection *s)
+{
+	struct vicodec_ctx *ctx = file2ctx(file);
+	struct vicodec_q_data *q_data;
+
+	q_data = get_q_data(ctx, s->type);
+	if (!q_data)
+		return -EINVAL;
+	/*
+	 * encoder supports only cropping on the OUTPUT buffer
+	 * decoder supports only composing on the CAPTURE buffer
+	 */
+	if (ctx->is_enc && s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
+		switch (s->target) {
+		case V4L2_SEL_TGT_CROP:
+			s->r.left = 0;
+			s->r.top = 0;
+			s->r.width = q_data->visible_width;
+			s->r.height = q_data->visible_height;
+			return 0;
+		case V4L2_SEL_TGT_CROP_DEFAULT:
+		case V4L2_SEL_TGT_CROP_BOUNDS:
+			s->r.left = 0;
+			s->r.top = 0;
+			s->r.width = q_data->coded_width;
+			s->r.height = q_data->coded_height;
+			return 0;
+		}
+	} else if (!ctx->is_enc && s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		switch (s->target) {
+		case V4L2_SEL_TGT_COMPOSE:
+			s->r.left = 0;
+			s->r.top = 0;
+			s->r.width = q_data->visible_width;
+			s->r.height = q_data->visible_height;
+			return 0;
+		case V4L2_SEL_TGT_COMPOSE_DEFAULT:
+		case V4L2_SEL_TGT_COMPOSE_BOUNDS:
+			s->r.left = 0;
+			s->r.top = 0;
+			s->r.width = q_data->coded_width;
+			s->r.height = q_data->coded_height;
+			return 0;
+		}
+	}
+	return -EINVAL;
+}
+
+static int vidioc_s_selection(struct file *file, void *priv,
+			      struct v4l2_selection *s)
+{
+	struct vicodec_ctx *ctx = file2ctx(file);
+	struct vicodec_q_data *q_data;
+
+	if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+		return -EINVAL;
+
+	q_data = get_q_data(ctx, s->type);
+	if (!q_data)
+		return -EINVAL;
+
+	if (!ctx->is_enc || s->target != V4L2_SEL_TGT_CROP)
+		return -EINVAL;
+
+	s->r.left = 0;
+	s->r.top = 0;
+	q_data->visible_width = clamp(s->r.width, MIN_WIDTH,
+				      q_data->coded_width);
+	s->r.width = q_data->visible_width;
+	q_data->visible_height = clamp(s->r.height, MIN_HEIGHT,
+				       q_data->coded_height);
+	s->r.height = q_data->visible_height;
+	return 0;
+}
+
+static int vicodec_encoder_cmd(struct file *file, void *fh,
+			    struct v4l2_encoder_cmd *ec)
+{
+	struct vicodec_ctx *ctx = file2ctx(file);
+	int ret;
+
+	ret = v4l2_m2m_ioctl_try_encoder_cmd(file, fh, ec);
+	if (ret < 0)
+		return ret;
+
+	if (!vb2_is_streaming(&ctx->fh.m2m_ctx->cap_q_ctx.q) ||
+	    !vb2_is_streaming(&ctx->fh.m2m_ctx->out_q_ctx.q))
+		return 0;
+
+	ret = v4l2_m2m_ioctl_encoder_cmd(file, fh, ec);
+	if (ret < 0)
+		return ret;
+
+	if (ec->cmd == V4L2_ENC_CMD_STOP &&
+	    v4l2_m2m_has_stopped(ctx->fh.m2m_ctx))
+		v4l2_event_queue_fh(&ctx->fh, &vicodec_eos_event);
+
+	if (ec->cmd == V4L2_ENC_CMD_START &&
+	    v4l2_m2m_has_stopped(ctx->fh.m2m_ctx))
+		vb2_clear_last_buffer_dequeued(&ctx->fh.m2m_ctx->cap_q_ctx.q);
+
+	return 0;
+}
+
+static int vicodec_decoder_cmd(struct file *file, void *fh,
+			    struct v4l2_decoder_cmd *dc)
+{
+	struct vicodec_ctx *ctx = file2ctx(file);
+	int ret;
+
+	ret = v4l2_m2m_ioctl_try_decoder_cmd(file, fh, dc);
+	if (ret < 0)
+		return ret;
+
+	if (!vb2_is_streaming(&ctx->fh.m2m_ctx->cap_q_ctx.q) ||
+	    !vb2_is_streaming(&ctx->fh.m2m_ctx->out_q_ctx.q))
+		return 0;
+
+	ret = v4l2_m2m_ioctl_decoder_cmd(file, fh, dc);
+	if (ret < 0)
+		return ret;
+
+	if (dc->cmd == V4L2_DEC_CMD_STOP &&
+	    v4l2_m2m_has_stopped(ctx->fh.m2m_ctx))
+		v4l2_event_queue_fh(&ctx->fh, &vicodec_eos_event);
+
+	if (dc->cmd == V4L2_DEC_CMD_START &&
+	    v4l2_m2m_has_stopped(ctx->fh.m2m_ctx))
+		vb2_clear_last_buffer_dequeued(&ctx->fh.m2m_ctx->cap_q_ctx.q);
+
+	return 0;
+}
+
+static int vicodec_enum_framesizes(struct file *file, void *fh,
+				   struct v4l2_frmsizeenum *fsize)
+{
+	switch (fsize->pixel_format) {
+	case V4L2_PIX_FMT_FWHT_STATELESS:
+		break;
+	case V4L2_PIX_FMT_FWHT:
+		break;
+	default:
+		if (find_fmt(fsize->pixel_format)->id == fsize->pixel_format)
+			break;
+		return -EINVAL;
+	}
+
+	if (fsize->index)
+		return -EINVAL;
+
+	fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
+
+	fsize->stepwise.min_width = MIN_WIDTH;
+	fsize->stepwise.max_width = MAX_WIDTH;
+	fsize->stepwise.step_width = 8;
+	fsize->stepwise.min_height = MIN_HEIGHT;
+	fsize->stepwise.max_height = MAX_HEIGHT;
+	fsize->stepwise.step_height = 8;
+
+	return 0;
+}
+
+static int vicodec_subscribe_event(struct v4l2_fh *fh,
+				const struct v4l2_event_subscription *sub)
+{
+	struct vicodec_ctx *ctx = container_of(fh, struct vicodec_ctx, fh);
+
+	switch (sub->type) {
+	case V4L2_EVENT_SOURCE_CHANGE:
+		if (ctx->is_enc)
+			return -EINVAL;
+		/* fall through */
+	case V4L2_EVENT_EOS:
+		if (ctx->is_stateless)
+			return -EINVAL;
+		return v4l2_event_subscribe(fh, sub, 0, NULL);
+	default:
+		return v4l2_ctrl_subscribe_event(fh, sub);
+	}
+}
+
+static const struct v4l2_ioctl_ops vicodec_ioctl_ops = {
+	.vidioc_querycap	= vidioc_querycap,
+
+	.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
+	.vidioc_g_fmt_vid_cap	= vidioc_g_fmt_vid_cap,
+	.vidioc_try_fmt_vid_cap	= vidioc_try_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap	= vidioc_s_fmt_vid_cap,
+
+	.vidioc_g_fmt_vid_cap_mplane	= vidioc_g_fmt_vid_cap,
+	.vidioc_try_fmt_vid_cap_mplane	= vidioc_try_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap_mplane	= vidioc_s_fmt_vid_cap,
+
+	.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,
+
+	.vidioc_g_fmt_vid_out_mplane	= vidioc_g_fmt_vid_out,
+	.vidioc_try_fmt_vid_out_mplane	= vidioc_try_fmt_vid_out,
+	.vidioc_s_fmt_vid_out_mplane	= vidioc_s_fmt_vid_out,
+
+	.vidioc_reqbufs		= v4l2_m2m_ioctl_reqbufs,
+	.vidioc_querybuf	= v4l2_m2m_ioctl_querybuf,
+	.vidioc_qbuf		= v4l2_m2m_ioctl_qbuf,
+	.vidioc_dqbuf		= v4l2_m2m_ioctl_dqbuf,
+	.vidioc_prepare_buf	= v4l2_m2m_ioctl_prepare_buf,
+	.vidioc_create_bufs	= v4l2_m2m_ioctl_create_bufs,
+	.vidioc_expbuf		= v4l2_m2m_ioctl_expbuf,
+
+	.vidioc_streamon	= v4l2_m2m_ioctl_streamon,
+	.vidioc_streamoff	= v4l2_m2m_ioctl_streamoff,
+
+	.vidioc_g_selection	= vidioc_g_selection,
+	.vidioc_s_selection	= vidioc_s_selection,
+
+	.vidioc_try_encoder_cmd	= v4l2_m2m_ioctl_try_encoder_cmd,
+	.vidioc_encoder_cmd	= vicodec_encoder_cmd,
+	.vidioc_try_decoder_cmd	= v4l2_m2m_ioctl_try_decoder_cmd,
+	.vidioc_decoder_cmd	= vicodec_decoder_cmd,
+	.vidioc_enum_framesizes = vicodec_enum_framesizes,
+
+	.vidioc_subscribe_event = vicodec_subscribe_event,
+	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+};
+
+
+/*
+ * Queue operations
+ */
+
+static int vicodec_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
+			       unsigned int *nplanes, unsigned int sizes[],
+			       struct device *alloc_devs[])
+{
+	struct vicodec_ctx *ctx = vb2_get_drv_priv(vq);
+	struct vicodec_q_data *q_data = get_q_data(ctx, vq->type);
+	unsigned int size = q_data->sizeimage;
+
+	if (*nplanes)
+		return sizes[0] < size ? -EINVAL : 0;
+
+	*nplanes = 1;
+	sizes[0] = size;
+	q_data->vb2_sizeimage = size;
+	return 0;
+}
+
+static int vicodec_buf_out_validate(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+
+	vbuf->field = V4L2_FIELD_NONE;
+	return 0;
+}
+
+static int vicodec_buf_prepare(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct vicodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+	struct vicodec_q_data *q_data;
+
+	dprintk(ctx->dev, "type: %d\n", vb->vb2_queue->type);
+
+	q_data = get_q_data(ctx, vb->vb2_queue->type);
+	if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
+		if (vbuf->field == V4L2_FIELD_ANY)
+			vbuf->field = V4L2_FIELD_NONE;
+		if (vbuf->field != V4L2_FIELD_NONE) {
+			dprintk(ctx->dev, "%s field isn't supported\n",
+					__func__);
+			return -EINVAL;
+		}
+	}
+
+	if (vb2_plane_size(vb, 0) < q_data->vb2_sizeimage) {
+		dprintk(ctx->dev,
+			"%s data will not fit into plane (%lu < %lu)\n",
+			__func__, vb2_plane_size(vb, 0),
+			(long)q_data->vb2_sizeimage);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void vicodec_buf_queue(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct vicodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+	unsigned int sz = vb2_get_plane_payload(&vbuf->vb2_buf, 0);
+	u8 *p_src = vb2_plane_vaddr(&vbuf->vb2_buf, 0);
+	u8 *p = p_src;
+	struct vb2_queue *vq_out = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
+						   V4L2_BUF_TYPE_VIDEO_OUTPUT);
+	struct vb2_queue *vq_cap = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
+						   V4L2_BUF_TYPE_VIDEO_CAPTURE);
+	bool header_valid = false;
+	static const struct v4l2_event rs_event = {
+		.type = V4L2_EVENT_SOURCE_CHANGE,
+		.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION,
+	};
+
+	if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type) &&
+	    vb2_is_streaming(vb->vb2_queue) &&
+	    v4l2_m2m_dst_buf_is_last(ctx->fh.m2m_ctx)) {
+		unsigned int i;
+
+		for (i = 0; i < vb->num_planes; i++)
+			vb->planes[i].bytesused = 0;
+
+		vbuf->field = V4L2_FIELD_NONE;
+		vbuf->sequence =
+			get_q_data(ctx, vb->vb2_queue->type)->sequence++;
+
+		v4l2_m2m_last_buffer_done(ctx->fh.m2m_ctx, vbuf);
+		v4l2_event_queue_fh(&ctx->fh, &vicodec_eos_event);
+		return;
+	}
+
+	/* buf_queue handles only the first source change event */
+	if (ctx->first_source_change_sent) {
+		v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
+		return;
+	}
+
+	/*
+	 * if both queues are streaming, the source change event is
+	 * handled in job_ready
+	 */
+	if (vb2_is_streaming(vq_cap) && vb2_is_streaming(vq_out)) {
+		v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
+		return;
+	}
+
+	/*
+	 * source change event is relevant only for the stateful decoder
+	 * in the compressed stream
+	 */
+	if (ctx->is_stateless || ctx->is_enc ||
+	    !V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
+		v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
+		return;
+	}
+
+	do {
+		enum vb2_buffer_state state =
+			get_next_header(ctx, &p, p_src + sz - p);
+
+		if (ctx->header_size < sizeof(struct fwht_cframe_hdr)) {
+			v4l2_m2m_buf_done(vbuf, state);
+			return;
+		}
+		header_valid = is_header_valid(&ctx->state.header);
+		/*
+		 * p points right after the end of the header in the
+		 * buffer. If the header is invalid we set p to point
+		 * to the next byte after the start of the header
+		 */
+		if (!header_valid) {
+			p = p - sizeof(struct fwht_cframe_hdr) + 1;
+			if (p < p_src)
+				p = p_src;
+			ctx->header_size = 0;
+			ctx->comp_magic_cnt = 0;
+		}
+
+	} while (!header_valid);
+
+	ctx->cur_buf_offset = p - p_src;
+	update_capture_data_from_header(ctx);
+	ctx->first_source_change_sent = true;
+	v4l2_event_queue_fh(&ctx->fh, &rs_event);
+	v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
+}
+
+static void vicodec_return_bufs(struct vb2_queue *q, u32 state)
+{
+	struct vicodec_ctx *ctx = vb2_get_drv_priv(q);
+	struct vb2_v4l2_buffer *vbuf;
+
+	for (;;) {
+		if (V4L2_TYPE_IS_OUTPUT(q->type))
+			vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+		else
+			vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
+		if (vbuf == NULL)
+			return;
+		v4l2_ctrl_request_complete(vbuf->vb2_buf.req_obj.req,
+					   &ctx->hdl);
+		spin_lock(ctx->lock);
+		v4l2_m2m_buf_done(vbuf, state);
+		spin_unlock(ctx->lock);
+	}
+}
+
+static unsigned int total_frame_size(struct vicodec_q_data *q_data)
+{
+	unsigned int size;
+	unsigned int chroma_div;
+
+	if (!q_data->info) {
+		WARN_ON(1);
+		return 0;
+	}
+	size = q_data->coded_width * q_data->coded_height;
+	chroma_div = q_data->info->width_div * q_data->info->height_div;
+
+	if (q_data->info->components_num == 4)
+		return 2 * size + 2 * (size / chroma_div);
+	else if (q_data->info->components_num == 3)
+		return size + 2 * (size / chroma_div);
+	return size;
+}
+
+static int vicodec_start_streaming(struct vb2_queue *q,
+				   unsigned int count)
+{
+	struct vicodec_ctx *ctx = vb2_get_drv_priv(q);
+	struct vicodec_q_data *q_data = get_q_data(ctx, q->type);
+	struct v4l2_fwht_state *state = &ctx->state;
+	const struct v4l2_fwht_pixfmt_info *info = q_data->info;
+	unsigned int size = q_data->coded_width * q_data->coded_height;
+	unsigned int chroma_div;
+	unsigned int total_planes_size;
+	u8 *new_comp_frame = NULL;
+
+	chroma_div = info->width_div * info->height_div;
+	q_data->sequence = 0;
+
+	v4l2_m2m_update_start_streaming_state(ctx->fh.m2m_ctx, q);
+
+	state->gop_cnt = 0;
+
+	if ((V4L2_TYPE_IS_OUTPUT(q->type) && !ctx->is_enc) ||
+	    (!V4L2_TYPE_IS_OUTPUT(q->type) && ctx->is_enc))
+		return 0;
+
+	if (info->id == V4L2_PIX_FMT_FWHT ||
+	    info->id == V4L2_PIX_FMT_FWHT_STATELESS) {
+		vicodec_return_bufs(q, VB2_BUF_STATE_QUEUED);
+		return -EINVAL;
+	}
+	total_planes_size = total_frame_size(q_data);
+	ctx->comp_max_size = total_planes_size;
+
+	state->visible_width = q_data->visible_width;
+	state->visible_height = q_data->visible_height;
+	state->coded_width = q_data->coded_width;
+	state->coded_height = q_data->coded_height;
+	state->stride = q_data->coded_width *
+				info->bytesperline_mult;
+
+	if (ctx->is_stateless) {
+		state->ref_stride = state->stride;
+		return 0;
+	}
+	state->ref_stride = q_data->coded_width * info->luma_alpha_step;
+
+	state->ref_frame.buf = kvmalloc(total_planes_size, GFP_KERNEL);
+	state->ref_frame.luma = state->ref_frame.buf;
+	new_comp_frame = kvmalloc(ctx->comp_max_size, GFP_KERNEL);
+
+	if (!state->ref_frame.luma || !new_comp_frame) {
+		kvfree(state->ref_frame.luma);
+		kvfree(new_comp_frame);
+		vicodec_return_bufs(q, VB2_BUF_STATE_QUEUED);
+		return -ENOMEM;
+	}
+	/*
+	 * if state->compressed_frame was already allocated then
+	 * it contain data of the first frame of the new resolution
+	 */
+	if (state->compressed_frame) {
+		if (ctx->comp_size > ctx->comp_max_size)
+			ctx->comp_size = ctx->comp_max_size;
+
+		memcpy(new_comp_frame,
+		       state->compressed_frame, ctx->comp_size);
+	}
+
+	kvfree(state->compressed_frame);
+	state->compressed_frame = new_comp_frame;
+
+	if (info->components_num < 3) {
+		state->ref_frame.cb = NULL;
+		state->ref_frame.cr = NULL;
+		state->ref_frame.alpha = NULL;
+		return 0;
+	}
+
+	state->ref_frame.cb = state->ref_frame.luma + size;
+	state->ref_frame.cr = state->ref_frame.cb + size / chroma_div;
+
+	if (info->components_num == 4)
+		state->ref_frame.alpha =
+			state->ref_frame.cr + size / chroma_div;
+	else
+		state->ref_frame.alpha = NULL;
+
+	return 0;
+}
+
+static void vicodec_stop_streaming(struct vb2_queue *q)
+{
+	struct vicodec_ctx *ctx = vb2_get_drv_priv(q);
+
+	vicodec_return_bufs(q, VB2_BUF_STATE_ERROR);
+
+	v4l2_m2m_update_stop_streaming_state(ctx->fh.m2m_ctx, q);
+
+	if (V4L2_TYPE_IS_OUTPUT(q->type) &&
+	    v4l2_m2m_has_stopped(ctx->fh.m2m_ctx))
+		v4l2_event_queue_fh(&ctx->fh, &vicodec_eos_event);
+
+	if (!ctx->is_enc && V4L2_TYPE_IS_OUTPUT(q->type))
+		ctx->first_source_change_sent = false;
+
+	if ((!V4L2_TYPE_IS_OUTPUT(q->type) && !ctx->is_enc) ||
+	    (V4L2_TYPE_IS_OUTPUT(q->type) && ctx->is_enc)) {
+		if (!ctx->is_stateless)
+			kvfree(ctx->state.ref_frame.buf);
+		ctx->state.ref_frame.buf = NULL;
+		ctx->state.ref_frame.luma = NULL;
+		ctx->comp_max_size = 0;
+		ctx->source_changed = false;
+	}
+	if (V4L2_TYPE_IS_OUTPUT(q->type) && !ctx->is_enc) {
+		ctx->cur_buf_offset = 0;
+		ctx->comp_size = 0;
+		ctx->header_size = 0;
+		ctx->comp_magic_cnt = 0;
+		ctx->comp_has_frame = 0;
+		ctx->comp_has_next_frame = 0;
+	}
+}
+
+static void vicodec_buf_request_complete(struct vb2_buffer *vb)
+{
+	struct vicodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+
+	v4l2_ctrl_request_complete(vb->req_obj.req, &ctx->hdl);
+}
+
+
+static const struct vb2_ops vicodec_qops = {
+	.queue_setup		= vicodec_queue_setup,
+	.buf_out_validate	= vicodec_buf_out_validate,
+	.buf_prepare		= vicodec_buf_prepare,
+	.buf_queue		= vicodec_buf_queue,
+	.buf_request_complete	= vicodec_buf_request_complete,
+	.start_streaming	= vicodec_start_streaming,
+	.stop_streaming		= vicodec_stop_streaming,
+	.wait_prepare		= vb2_ops_wait_prepare,
+	.wait_finish		= vb2_ops_wait_finish,
+};
+
+static int queue_init(void *priv, struct vb2_queue *src_vq,
+		      struct vb2_queue *dst_vq)
+{
+	struct vicodec_ctx *ctx = priv;
+	int ret;
+
+	src_vq->type = (multiplanar ?
+			V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE :
+			V4L2_BUF_TYPE_VIDEO_OUTPUT);
+	src_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
+	src_vq->drv_priv = ctx;
+	src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
+	src_vq->ops = &vicodec_qops;
+	src_vq->mem_ops = &vb2_vmalloc_memops;
+	src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+	if (ctx->is_enc)
+		src_vq->lock = &ctx->dev->stateful_enc.mutex;
+	else if (ctx->is_stateless)
+		src_vq->lock = &ctx->dev->stateless_dec.mutex;
+	else
+		src_vq->lock = &ctx->dev->stateful_dec.mutex;
+	src_vq->supports_requests = ctx->is_stateless;
+	src_vq->requires_requests = ctx->is_stateless;
+	ret = vb2_queue_init(src_vq);
+	if (ret)
+		return ret;
+
+	dst_vq->type = (multiplanar ?
+			V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
+			V4L2_BUF_TYPE_VIDEO_CAPTURE);
+	dst_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
+	dst_vq->drv_priv = ctx;
+	dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
+	dst_vq->ops = &vicodec_qops;
+	dst_vq->mem_ops = &vb2_vmalloc_memops;
+	dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+	dst_vq->lock = src_vq->lock;
+
+	return vb2_queue_init(dst_vq);
+}
+
+static int vicodec_try_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct vicodec_ctx *ctx = container_of(ctrl->handler,
+			struct vicodec_ctx, hdl);
+	const struct v4l2_ctrl_fwht_params *params;
+	struct vicodec_q_data *q_dst = get_q_data(ctx,
+			V4L2_BUF_TYPE_VIDEO_CAPTURE);
+
+	switch (ctrl->id) {
+	case V4L2_CID_MPEG_VIDEO_FWHT_PARAMS:
+		if (!q_dst->info)
+			return -EINVAL;
+		params = ctrl->p_new.p_fwht_params;
+		if (params->width > q_dst->coded_width ||
+		    params->width < MIN_WIDTH ||
+		    params->height > q_dst->coded_height ||
+		    params->height < MIN_HEIGHT)
+			return -EINVAL;
+		if (!validate_by_version(params->flags, params->version))
+			return -EINVAL;
+		if (!validate_stateless_params_flags(params, q_dst->info))
+			return -EINVAL;
+		return 0;
+	default:
+		return 0;
+	}
+	return 0;
+}
+
+static void update_header_from_stateless_params(struct vicodec_ctx *ctx,
+						const struct v4l2_ctrl_fwht_params *params)
+{
+	struct fwht_cframe_hdr *p_hdr = &ctx->state.header;
+
+	p_hdr->magic1 = FWHT_MAGIC1;
+	p_hdr->magic2 = FWHT_MAGIC2;
+	p_hdr->version = htonl(params->version);
+	p_hdr->width = htonl(params->width);
+	p_hdr->height = htonl(params->height);
+	p_hdr->flags = htonl(params->flags);
+	p_hdr->colorspace = htonl(params->colorspace);
+	p_hdr->xfer_func = htonl(params->xfer_func);
+	p_hdr->ycbcr_enc = htonl(params->ycbcr_enc);
+	p_hdr->quantization = htonl(params->quantization);
+}
+
+static int vicodec_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct vicodec_ctx *ctx = container_of(ctrl->handler,
+					       struct vicodec_ctx, hdl);
+	const struct v4l2_ctrl_fwht_params *params;
+
+	switch (ctrl->id) {
+	case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
+		ctx->state.gop_size = ctrl->val;
+		return 0;
+	case V4L2_CID_FWHT_I_FRAME_QP:
+		ctx->state.i_frame_qp = ctrl->val;
+		return 0;
+	case V4L2_CID_FWHT_P_FRAME_QP:
+		ctx->state.p_frame_qp = ctrl->val;
+		return 0;
+	case V4L2_CID_MPEG_VIDEO_FWHT_PARAMS:
+		params = ctrl->p_new.p_fwht_params;
+		update_header_from_stateless_params(ctx, params);
+		ctx->state.ref_frame_ts = params->backward_ref_ts;
+		return 0;
+	}
+	return -EINVAL;
+}
+
+static const struct v4l2_ctrl_ops vicodec_ctrl_ops = {
+	.s_ctrl = vicodec_s_ctrl,
+	.try_ctrl = vicodec_try_ctrl,
+};
+
+static const struct v4l2_ctrl_config vicodec_ctrl_stateless_state = {
+	.ops		= &vicodec_ctrl_ops,
+	.id		= V4L2_CID_MPEG_VIDEO_FWHT_PARAMS,
+	.elem_size      = sizeof(struct v4l2_ctrl_fwht_params),
+};
+
+/*
+ * File operations
+ */
+static int vicodec_open(struct file *file)
+{
+	const struct v4l2_fwht_pixfmt_info *info = v4l2_fwht_get_pixfmt(0);
+	struct video_device *vfd = video_devdata(file);
+	struct vicodec_dev *dev = video_drvdata(file);
+	struct vicodec_ctx *ctx = NULL;
+	struct v4l2_ctrl_handler *hdl;
+	unsigned int raw_size;
+	unsigned int comp_size;
+	int rc = 0;
+
+	if (mutex_lock_interruptible(vfd->lock))
+		return -ERESTARTSYS;
+	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+	if (!ctx) {
+		rc = -ENOMEM;
+		goto open_unlock;
+	}
+
+	if (vfd == &dev->stateful_enc.vfd)
+		ctx->is_enc = true;
+	else if (vfd == &dev->stateless_dec.vfd)
+		ctx->is_stateless = true;
+
+	v4l2_fh_init(&ctx->fh, video_devdata(file));
+	file->private_data = &ctx->fh;
+	ctx->dev = dev;
+	hdl = &ctx->hdl;
+	v4l2_ctrl_handler_init(hdl, 5);
+	v4l2_ctrl_new_std(hdl, &vicodec_ctrl_ops, V4L2_CID_MPEG_VIDEO_GOP_SIZE,
+			  1, 16, 1, 10);
+	v4l2_ctrl_new_std(hdl, &vicodec_ctrl_ops, V4L2_CID_FWHT_I_FRAME_QP,
+			  1, 31, 1, 20);
+	v4l2_ctrl_new_std(hdl, &vicodec_ctrl_ops, V4L2_CID_FWHT_P_FRAME_QP,
+			  1, 31, 1, 20);
+	if (ctx->is_enc)
+		v4l2_ctrl_new_std(hdl, &vicodec_ctrl_ops,
+				  V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, 1, 1, 1, 1);
+	if (ctx->is_stateless)
+		v4l2_ctrl_new_custom(hdl, &vicodec_ctrl_stateless_state, NULL);
+	if (hdl->error) {
+		rc = hdl->error;
+		v4l2_ctrl_handler_free(hdl);
+		kfree(ctx);
+		goto open_unlock;
+	}
+	ctx->fh.ctrl_handler = hdl;
+	v4l2_ctrl_handler_setup(hdl);
+
+	if (ctx->is_enc)
+		ctx->q_data[V4L2_M2M_SRC].info = info;
+	else if (ctx->is_stateless)
+		ctx->q_data[V4L2_M2M_SRC].info = &pixfmt_stateless_fwht;
+	else
+		ctx->q_data[V4L2_M2M_SRC].info = &pixfmt_fwht;
+	ctx->q_data[V4L2_M2M_SRC].coded_width = 1280;
+	ctx->q_data[V4L2_M2M_SRC].coded_height = 720;
+	ctx->q_data[V4L2_M2M_SRC].visible_width = 1280;
+	ctx->q_data[V4L2_M2M_SRC].visible_height = 720;
+	raw_size = 1280 * 720 * info->sizeimage_mult / info->sizeimage_div;
+	comp_size = 1280 * 720 * pixfmt_fwht.sizeimage_mult /
+				 pixfmt_fwht.sizeimage_div;
+	if (ctx->is_enc)
+		ctx->q_data[V4L2_M2M_SRC].sizeimage = raw_size;
+	else if (ctx->is_stateless)
+		ctx->q_data[V4L2_M2M_SRC].sizeimage = comp_size;
+	else
+		ctx->q_data[V4L2_M2M_SRC].sizeimage =
+			comp_size + sizeof(struct fwht_cframe_hdr);
+	ctx->q_data[V4L2_M2M_DST] = ctx->q_data[V4L2_M2M_SRC];
+	if (ctx->is_enc) {
+		ctx->q_data[V4L2_M2M_DST].info = &pixfmt_fwht;
+		ctx->q_data[V4L2_M2M_DST].sizeimage =
+			comp_size + sizeof(struct fwht_cframe_hdr);
+	} else {
+		ctx->q_data[V4L2_M2M_DST].info = info;
+		ctx->q_data[V4L2_M2M_DST].sizeimage = raw_size;
+	}
+
+	ctx->state.colorspace = V4L2_COLORSPACE_REC709;
+
+	if (ctx->is_enc) {
+		ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->stateful_enc.m2m_dev,
+						    ctx, &queue_init);
+		ctx->lock = &dev->stateful_enc.lock;
+	} else if (ctx->is_stateless) {
+		ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->stateless_dec.m2m_dev,
+						    ctx, &queue_init);
+		ctx->lock = &dev->stateless_dec.lock;
+	} else {
+		ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->stateful_dec.m2m_dev,
+						    ctx, &queue_init);
+		ctx->lock = &dev->stateful_dec.lock;
+	}
+
+	if (IS_ERR(ctx->fh.m2m_ctx)) {
+		rc = PTR_ERR(ctx->fh.m2m_ctx);
+
+		v4l2_ctrl_handler_free(hdl);
+		v4l2_fh_exit(&ctx->fh);
+		kfree(ctx);
+		goto open_unlock;
+	}
+
+	v4l2_fh_add(&ctx->fh);
+
+open_unlock:
+	mutex_unlock(vfd->lock);
+	return rc;
+}
+
+static int vicodec_release(struct file *file)
+{
+	struct video_device *vfd = video_devdata(file);
+	struct vicodec_ctx *ctx = file2ctx(file);
+
+	mutex_lock(vfd->lock);
+	v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
+	mutex_unlock(vfd->lock);
+	v4l2_fh_del(&ctx->fh);
+	v4l2_fh_exit(&ctx->fh);
+	v4l2_ctrl_handler_free(&ctx->hdl);
+	kvfree(ctx->state.compressed_frame);
+	kfree(ctx);
+
+	return 0;
+}
+
+static int vicodec_request_validate(struct media_request *req)
+{
+	struct media_request_object *obj;
+	struct v4l2_ctrl_handler *parent_hdl, *hdl;
+	struct vicodec_ctx *ctx = NULL;
+	struct v4l2_ctrl *ctrl;
+	unsigned int count;
+
+	list_for_each_entry(obj, &req->objects, list) {
+		struct vb2_buffer *vb;
+
+		if (vb2_request_object_is_buffer(obj)) {
+			vb = container_of(obj, struct vb2_buffer, req_obj);
+			ctx = vb2_get_drv_priv(vb->vb2_queue);
+
+			break;
+		}
+	}
+
+	if (!ctx) {
+		pr_err("No buffer was provided with the request\n");
+		return -ENOENT;
+	}
+
+	count = vb2_request_buffer_cnt(req);
+	if (!count) {
+		v4l2_info(&ctx->dev->v4l2_dev,
+			  "No buffer was provided with the request\n");
+		return -ENOENT;
+	} else if (count > 1) {
+		v4l2_info(&ctx->dev->v4l2_dev,
+			  "More than one buffer was provided with the request\n");
+		return -EINVAL;
+	}
+
+	parent_hdl = &ctx->hdl;
+
+	hdl = v4l2_ctrl_request_hdl_find(req, parent_hdl);
+	if (!hdl) {
+		v4l2_info(&ctx->dev->v4l2_dev, "Missing codec control\n");
+		return -ENOENT;
+	}
+	ctrl = v4l2_ctrl_request_hdl_ctrl_find(hdl,
+					       vicodec_ctrl_stateless_state.id);
+	if (!ctrl) {
+		v4l2_info(&ctx->dev->v4l2_dev,
+			  "Missing required codec control\n");
+		return -ENOENT;
+	}
+
+	return vb2_request_validate(req);
+}
+
+static const struct v4l2_file_operations vicodec_fops = {
+	.owner		= THIS_MODULE,
+	.open		= vicodec_open,
+	.release	= vicodec_release,
+	.poll		= v4l2_m2m_fop_poll,
+	.unlocked_ioctl	= video_ioctl2,
+	.mmap		= v4l2_m2m_fop_mmap,
+};
+
+static const struct video_device vicodec_videodev = {
+	.name		= VICODEC_NAME,
+	.vfl_dir	= VFL_DIR_M2M,
+	.fops		= &vicodec_fops,
+	.ioctl_ops	= &vicodec_ioctl_ops,
+	.minor		= -1,
+	.release	= video_device_release_empty,
+};
+
+static const struct media_device_ops vicodec_m2m_media_ops = {
+	.req_validate	= vicodec_request_validate,
+	.req_queue	= v4l2_m2m_request_queue,
+};
+
+static const struct v4l2_m2m_ops m2m_ops = {
+	.device_run	= device_run,
+	.job_ready	= job_ready,
+};
+
+static int register_instance(struct vicodec_dev *dev,
+			     struct vicodec_dev_instance *dev_instance,
+			     const char *name, bool is_enc)
+{
+	struct video_device *vfd;
+	int ret;
+
+	spin_lock_init(&dev_instance->lock);
+	mutex_init(&dev_instance->mutex);
+	dev_instance->m2m_dev = v4l2_m2m_init(&m2m_ops);
+	if (IS_ERR(dev_instance->m2m_dev)) {
+		v4l2_err(&dev->v4l2_dev, "Failed to init vicodec enc device\n");
+		return PTR_ERR(dev_instance->m2m_dev);
+	}
+
+	dev_instance->vfd = vicodec_videodev;
+	vfd = &dev_instance->vfd;
+	vfd->lock = &dev_instance->mutex;
+	vfd->v4l2_dev = &dev->v4l2_dev;
+	strscpy(vfd->name, name, sizeof(vfd->name));
+	vfd->device_caps = V4L2_CAP_STREAMING |
+		(multiplanar ? V4L2_CAP_VIDEO_M2M_MPLANE : V4L2_CAP_VIDEO_M2M);
+	if (is_enc) {
+		v4l2_disable_ioctl(vfd, VIDIOC_DECODER_CMD);
+		v4l2_disable_ioctl(vfd, VIDIOC_TRY_DECODER_CMD);
+	} else {
+		v4l2_disable_ioctl(vfd, VIDIOC_ENCODER_CMD);
+		v4l2_disable_ioctl(vfd, VIDIOC_TRY_ENCODER_CMD);
+	}
+	video_set_drvdata(vfd, dev);
+
+	ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0);
+	if (ret) {
+		v4l2_err(&dev->v4l2_dev, "Failed to register video device '%s'\n", name);
+		v4l2_m2m_release(dev_instance->m2m_dev);
+		return ret;
+	}
+	v4l2_info(&dev->v4l2_dev, "Device '%s' registered as /dev/video%d\n",
+		  name, vfd->num);
+	return 0;
+}
+
+static void vicodec_v4l2_dev_release(struct v4l2_device *v4l2_dev)
+{
+	struct vicodec_dev *dev = container_of(v4l2_dev, struct vicodec_dev, v4l2_dev);
+
+	v4l2_device_unregister(&dev->v4l2_dev);
+	v4l2_m2m_release(dev->stateful_enc.m2m_dev);
+	v4l2_m2m_release(dev->stateful_dec.m2m_dev);
+	v4l2_m2m_release(dev->stateless_dec.m2m_dev);
+#ifdef CONFIG_MEDIA_CONTROLLER
+	media_device_cleanup(&dev->mdev);
+#endif
+	kfree(dev);
+}
+
+static int vicodec_probe(struct platform_device *pdev)
+{
+	struct vicodec_dev *dev;
+	int ret;
+
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	if (!dev)
+		return -ENOMEM;
+
+	ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
+	if (ret)
+		goto free_dev;
+
+	dev->v4l2_dev.release = vicodec_v4l2_dev_release;
+
+#ifdef CONFIG_MEDIA_CONTROLLER
+	dev->mdev.dev = &pdev->dev;
+	strscpy(dev->mdev.model, "vicodec", sizeof(dev->mdev.model));
+	strscpy(dev->mdev.bus_info, "platform:vicodec",
+		sizeof(dev->mdev.bus_info));
+	media_device_init(&dev->mdev);
+	dev->mdev.ops = &vicodec_m2m_media_ops;
+	dev->v4l2_dev.mdev = &dev->mdev;
+#endif
+
+	platform_set_drvdata(pdev, dev);
+
+	if (register_instance(dev, &dev->stateful_enc,
+			      "stateful-encoder", true))
+		goto unreg_dev;
+
+	if (register_instance(dev, &dev->stateful_dec,
+			      "stateful-decoder", false))
+		goto unreg_sf_enc;
+
+	if (register_instance(dev, &dev->stateless_dec,
+			      "stateless-decoder", false))
+		goto unreg_sf_dec;
+
+#ifdef CONFIG_MEDIA_CONTROLLER
+	ret = v4l2_m2m_register_media_controller(dev->stateful_enc.m2m_dev,
+						 &dev->stateful_enc.vfd,
+						 MEDIA_ENT_F_PROC_VIDEO_ENCODER);
+	if (ret) {
+		v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem media controller for enc\n");
+		goto unreg_m2m;
+	}
+
+	ret = v4l2_m2m_register_media_controller(dev->stateful_dec.m2m_dev,
+						 &dev->stateful_dec.vfd,
+						 MEDIA_ENT_F_PROC_VIDEO_DECODER);
+	if (ret) {
+		v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem media controller for dec\n");
+		goto unreg_m2m_sf_enc_mc;
+	}
+
+	ret = v4l2_m2m_register_media_controller(dev->stateless_dec.m2m_dev,
+						 &dev->stateless_dec.vfd,
+						 MEDIA_ENT_F_PROC_VIDEO_DECODER);
+	if (ret) {
+		v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem media controller for stateless dec\n");
+		goto unreg_m2m_sf_dec_mc;
+	}
+
+	ret = media_device_register(&dev->mdev);
+	if (ret) {
+		v4l2_err(&dev->v4l2_dev, "Failed to register mem2mem media device\n");
+		goto unreg_m2m_sl_dec_mc;
+	}
+#endif
+	return 0;
+
+#ifdef CONFIG_MEDIA_CONTROLLER
+unreg_m2m_sl_dec_mc:
+	v4l2_m2m_unregister_media_controller(dev->stateless_dec.m2m_dev);
+unreg_m2m_sf_dec_mc:
+	v4l2_m2m_unregister_media_controller(dev->stateful_dec.m2m_dev);
+unreg_m2m_sf_enc_mc:
+	v4l2_m2m_unregister_media_controller(dev->stateful_enc.m2m_dev);
+unreg_m2m:
+	video_unregister_device(&dev->stateless_dec.vfd);
+	v4l2_m2m_release(dev->stateless_dec.m2m_dev);
+#endif
+unreg_sf_dec:
+	video_unregister_device(&dev->stateful_dec.vfd);
+	v4l2_m2m_release(dev->stateful_dec.m2m_dev);
+unreg_sf_enc:
+	video_unregister_device(&dev->stateful_enc.vfd);
+	v4l2_m2m_release(dev->stateful_enc.m2m_dev);
+unreg_dev:
+	v4l2_device_unregister(&dev->v4l2_dev);
+free_dev:
+	kfree(dev);
+
+	return ret;
+}
+
+static int vicodec_remove(struct platform_device *pdev)
+{
+	struct vicodec_dev *dev = platform_get_drvdata(pdev);
+
+	v4l2_info(&dev->v4l2_dev, "Removing " VICODEC_NAME);
+
+#ifdef CONFIG_MEDIA_CONTROLLER
+	media_device_unregister(&dev->mdev);
+	v4l2_m2m_unregister_media_controller(dev->stateful_enc.m2m_dev);
+	v4l2_m2m_unregister_media_controller(dev->stateful_dec.m2m_dev);
+	v4l2_m2m_unregister_media_controller(dev->stateless_dec.m2m_dev);
+#endif
+
+	video_unregister_device(&dev->stateful_enc.vfd);
+	video_unregister_device(&dev->stateful_dec.vfd);
+	video_unregister_device(&dev->stateless_dec.vfd);
+	v4l2_device_put(&dev->v4l2_dev);
+
+	return 0;
+}
+
+static struct platform_driver vicodec_pdrv = {
+	.probe		= vicodec_probe,
+	.remove		= vicodec_remove,
+	.driver		= {
+		.name	= VICODEC_NAME,
+	},
+};
+
+static void __exit vicodec_exit(void)
+{
+	platform_driver_unregister(&vicodec_pdrv);
+	platform_device_unregister(&vicodec_pdev);
+}
+
+static int __init vicodec_init(void)
+{
+	int ret;
+
+	ret = platform_device_register(&vicodec_pdev);
+	if (ret)
+		return ret;
+
+	ret = platform_driver_register(&vicodec_pdrv);
+	if (ret)
+		platform_device_unregister(&vicodec_pdev);
+
+	return ret;
+}
+
+module_init(vicodec_init);
+module_exit(vicodec_exit);
diff --git a/drivers/media/test-drivers/vim2m.c b/drivers/media/test-drivers/vim2m.c
new file mode 100644
index 000000000000..a776bb8e0e09
--- /dev/null
+++ b/drivers/media/test-drivers/vim2m.c
@@ -0,0 +1,1433 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * A virtual v4l2-mem2mem example device.
+ *
+ * This is a virtual device driver for testing mem-to-mem videobuf framework.
+ * It simulates a device that uses memory buffers for both source and
+ * destination, processes the data and issues an "irq" (simulated by a delayed
+ * workqueue).
+ * The device is capable of multi-instance, multi-buffer-per-transaction
+ * operation (via the mem2mem framework).
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * Pawel Osciak, <pawel@osciak.com>
+ * Marek Szyprowski, <m.szyprowski@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; either version 2 of the
+ * License, or (at your option) any later version
+ */
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+
+#include <linux/platform_device.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-event.h>
+#include <media/videobuf2-vmalloc.h>
+
+MODULE_DESCRIPTION("Virtual device for mem2mem framework testing");
+MODULE_AUTHOR("Pawel Osciak, <pawel@osciak.com>");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("0.2");
+MODULE_ALIAS("mem2mem_testdev");
+
+static unsigned int debug;
+module_param(debug, uint, 0644);
+MODULE_PARM_DESC(debug, "debug level");
+
+/* Default transaction time in msec */
+static unsigned int default_transtime = 40; /* Max 25 fps */
+module_param(default_transtime, uint, 0644);
+MODULE_PARM_DESC(default_transtime, "default transaction time in ms");
+
+#define MIN_W 32
+#define MIN_H 32
+#define MAX_W 640
+#define MAX_H 480
+
+/* Pixel alignment for non-bayer formats */
+#define WIDTH_ALIGN 2
+#define HEIGHT_ALIGN 1
+
+/* Pixel alignment for bayer formats */
+#define BAYER_WIDTH_ALIGN  2
+#define BAYER_HEIGHT_ALIGN 2
+
+/* Flags that indicate a format can be used for capture/output */
+#define MEM2MEM_CAPTURE	BIT(0)
+#define MEM2MEM_OUTPUT	BIT(1)
+
+#define MEM2MEM_NAME		"vim2m"
+
+/* Per queue */
+#define MEM2MEM_DEF_NUM_BUFS	VIDEO_MAX_FRAME
+/* In bytes, per queue */
+#define MEM2MEM_VID_MEM_LIMIT	(16 * 1024 * 1024)
+
+/* Flags that indicate processing mode */
+#define MEM2MEM_HFLIP	BIT(0)
+#define MEM2MEM_VFLIP	BIT(1)
+
+#define dprintk(dev, lvl, fmt, arg...) \
+	v4l2_dbg(lvl, debug, &(dev)->v4l2_dev, "%s: " fmt, __func__, ## arg)
+
+static void vim2m_dev_release(struct device *dev)
+{}
+
+static struct platform_device vim2m_pdev = {
+	.name		= MEM2MEM_NAME,
+	.dev.release	= vim2m_dev_release,
+};
+
+struct vim2m_fmt {
+	u32	fourcc;
+	int	depth;
+	/* Types the format can be used for */
+	u32     types;
+};
+
+static struct vim2m_fmt formats[] = {
+	{
+		.fourcc	= V4L2_PIX_FMT_RGB565,  /* rrrrrggg gggbbbbb */
+		.depth	= 16,
+		.types  = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
+	}, {
+		.fourcc	= V4L2_PIX_FMT_RGB565X, /* gggbbbbb rrrrrggg */
+		.depth	= 16,
+		.types  = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
+	}, {
+		.fourcc	= V4L2_PIX_FMT_RGB24,
+		.depth	= 24,
+		.types  = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
+	}, {
+		.fourcc	= V4L2_PIX_FMT_BGR24,
+		.depth	= 24,
+		.types  = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
+	}, {
+		.fourcc	= V4L2_PIX_FMT_YUYV,
+		.depth	= 16,
+		.types  = MEM2MEM_CAPTURE,
+	}, {
+		.fourcc	= V4L2_PIX_FMT_SBGGR8,
+		.depth	= 8,
+		.types  = MEM2MEM_CAPTURE,
+	}, {
+		.fourcc	= V4L2_PIX_FMT_SGBRG8,
+		.depth	= 8,
+		.types  = MEM2MEM_CAPTURE,
+	}, {
+		.fourcc	= V4L2_PIX_FMT_SGRBG8,
+		.depth	= 8,
+		.types  = MEM2MEM_CAPTURE,
+	}, {
+		.fourcc	= V4L2_PIX_FMT_SRGGB8,
+		.depth	= 8,
+		.types  = MEM2MEM_CAPTURE,
+	},
+};
+
+#define NUM_FORMATS ARRAY_SIZE(formats)
+
+/* Per-queue, driver-specific private data */
+struct vim2m_q_data {
+	unsigned int		width;
+	unsigned int		height;
+	unsigned int		sizeimage;
+	unsigned int		sequence;
+	struct vim2m_fmt	*fmt;
+};
+
+enum {
+	V4L2_M2M_SRC = 0,
+	V4L2_M2M_DST = 1,
+};
+
+#define V4L2_CID_TRANS_TIME_MSEC	(V4L2_CID_USER_BASE + 0x1000)
+#define V4L2_CID_TRANS_NUM_BUFS		(V4L2_CID_USER_BASE + 0x1001)
+
+static struct vim2m_fmt *find_format(u32 fourcc)
+{
+	struct vim2m_fmt *fmt;
+	unsigned int k;
+
+	for (k = 0; k < NUM_FORMATS; k++) {
+		fmt = &formats[k];
+		if (fmt->fourcc == fourcc)
+			break;
+	}
+
+	if (k == NUM_FORMATS)
+		return NULL;
+
+	return &formats[k];
+}
+
+static void get_alignment(u32 fourcc,
+			  unsigned int *walign, unsigned int *halign)
+{
+	switch (fourcc) {
+	case V4L2_PIX_FMT_SBGGR8:
+	case V4L2_PIX_FMT_SGBRG8:
+	case V4L2_PIX_FMT_SGRBG8:
+	case V4L2_PIX_FMT_SRGGB8:
+		*walign = BAYER_WIDTH_ALIGN;
+		*halign = BAYER_HEIGHT_ALIGN;
+		return;
+	default:
+		*walign = WIDTH_ALIGN;
+		*halign = HEIGHT_ALIGN;
+		return;
+	}
+}
+
+struct vim2m_dev {
+	struct v4l2_device	v4l2_dev;
+	struct video_device	vfd;
+#ifdef CONFIG_MEDIA_CONTROLLER
+	struct media_device	mdev;
+#endif
+
+	atomic_t		num_inst;
+	struct mutex		dev_mutex;
+
+	struct v4l2_m2m_dev	*m2m_dev;
+};
+
+struct vim2m_ctx {
+	struct v4l2_fh		fh;
+	struct vim2m_dev	*dev;
+
+	struct v4l2_ctrl_handler hdl;
+
+	/* Processed buffers in this transaction */
+	u8			num_processed;
+
+	/* Transaction length (i.e. how many buffers per transaction) */
+	u32			translen;
+	/* Transaction time (i.e. simulated processing time) in milliseconds */
+	u32			transtime;
+
+	struct mutex		vb_mutex;
+	struct delayed_work	work_run;
+
+	/* Abort requested by m2m */
+	int			aborting;
+
+	/* Processing mode */
+	int			mode;
+
+	enum v4l2_colorspace	colorspace;
+	enum v4l2_ycbcr_encoding ycbcr_enc;
+	enum v4l2_xfer_func	xfer_func;
+	enum v4l2_quantization	quant;
+
+	/* Source and destination queue data */
+	struct vim2m_q_data   q_data[2];
+};
+
+static inline struct vim2m_ctx *file2ctx(struct file *file)
+{
+	return container_of(file->private_data, struct vim2m_ctx, fh);
+}
+
+static struct vim2m_q_data *get_q_data(struct vim2m_ctx *ctx,
+				       enum v4l2_buf_type type)
+{
+	switch (type) {
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+		return &ctx->q_data[V4L2_M2M_SRC];
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		return &ctx->q_data[V4L2_M2M_DST];
+	default:
+		return NULL;
+	}
+}
+
+static const char *type_name(enum v4l2_buf_type type)
+{
+	switch (type) {
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+		return "Output";
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		return "Capture";
+	default:
+		return "Invalid";
+	}
+}
+
+#define CLIP(__color) \
+	(u8)(((__color) > 0xff) ? 0xff : (((__color) < 0) ? 0 : (__color)))
+
+static void copy_line(struct vim2m_q_data *q_data_out,
+		      u8 *src, u8 *dst, bool reverse)
+{
+	int x, depth = q_data_out->fmt->depth >> 3;
+
+	if (!reverse) {
+		memcpy(dst, src, q_data_out->width * depth);
+	} else {
+		for (x = 0; x < q_data_out->width >> 1; x++) {
+			memcpy(dst, src, depth);
+			memcpy(dst + depth, src - depth, depth);
+			src -= depth << 1;
+			dst += depth << 1;
+		}
+		return;
+	}
+}
+
+static void copy_two_pixels(struct vim2m_q_data *q_data_in,
+			    struct vim2m_q_data *q_data_out,
+			    u8 *src[2], u8 **dst, int ypos, bool reverse)
+{
+	struct vim2m_fmt *out = q_data_out->fmt;
+	struct vim2m_fmt *in = q_data_in->fmt;
+	u8 _r[2], _g[2], _b[2], *r, *g, *b;
+	int i;
+
+	/* Step 1: read two consecutive pixels from src pointer */
+
+	r = _r;
+	g = _g;
+	b = _b;
+
+	switch (in->fourcc) {
+	case V4L2_PIX_FMT_RGB565: /* rrrrrggg gggbbbbb */
+		for (i = 0; i < 2; i++) {
+			u16 pix = le16_to_cpu(*(__le16 *)(src[i]));
+
+			*r++ = (u8)(((pix & 0xf800) >> 11) << 3) | 0x07;
+			*g++ = (u8)((((pix & 0x07e0) >> 5)) << 2) | 0x03;
+			*b++ = (u8)((pix & 0x1f) << 3) | 0x07;
+		}
+		break;
+	case V4L2_PIX_FMT_RGB565X: /* gggbbbbb rrrrrggg */
+		for (i = 0; i < 2; i++) {
+			u16 pix = be16_to_cpu(*(__be16 *)(src[i]));
+
+			*r++ = (u8)(((pix & 0xf800) >> 11) << 3) | 0x07;
+			*g++ = (u8)((((pix & 0x07e0) >> 5)) << 2) | 0x03;
+			*b++ = (u8)((pix & 0x1f) << 3) | 0x07;
+		}
+		break;
+	default:
+	case V4L2_PIX_FMT_RGB24:
+		for (i = 0; i < 2; i++) {
+			*r++ = src[i][0];
+			*g++ = src[i][1];
+			*b++ = src[i][2];
+		}
+		break;
+	case V4L2_PIX_FMT_BGR24:
+		for (i = 0; i < 2; i++) {
+			*b++ = src[i][0];
+			*g++ = src[i][1];
+			*r++ = src[i][2];
+		}
+		break;
+	}
+
+	/* Step 2: store two consecutive points, reversing them if needed */
+
+	r = _r;
+	g = _g;
+	b = _b;
+
+	switch (out->fourcc) {
+	case V4L2_PIX_FMT_RGB565: /* rrrrrggg gggbbbbb */
+		for (i = 0; i < 2; i++) {
+			u16 pix;
+			__le16 *dst_pix = (__le16 *)*dst;
+
+			pix = ((*r << 8) & 0xf800) | ((*g << 3) & 0x07e0) |
+			      (*b >> 3);
+
+			*dst_pix = cpu_to_le16(pix);
+
+			*dst += 2;
+		}
+		return;
+	case V4L2_PIX_FMT_RGB565X: /* gggbbbbb rrrrrggg */
+		for (i = 0; i < 2; i++) {
+			u16 pix;
+			__be16 *dst_pix = (__be16 *)*dst;
+
+			pix = ((*r << 8) & 0xf800) | ((*g << 3) & 0x07e0) |
+			      (*b >> 3);
+
+			*dst_pix = cpu_to_be16(pix);
+
+			*dst += 2;
+		}
+		return;
+	case V4L2_PIX_FMT_RGB24:
+		for (i = 0; i < 2; i++) {
+			*(*dst)++ = *r++;
+			*(*dst)++ = *g++;
+			*(*dst)++ = *b++;
+		}
+		return;
+	case V4L2_PIX_FMT_BGR24:
+		for (i = 0; i < 2; i++) {
+			*(*dst)++ = *b++;
+			*(*dst)++ = *g++;
+			*(*dst)++ = *r++;
+		}
+		return;
+	case V4L2_PIX_FMT_YUYV:
+	default:
+	{
+		u8 y, y1, u, v;
+
+		y = ((8453  * (*r) + 16594 * (*g) +  3223 * (*b)
+		     + 524288) >> 15);
+		u = ((-4878 * (*r) - 9578  * (*g) + 14456 * (*b)
+		     + 4210688) >> 15);
+		v = ((14456 * (*r++) - 12105 * (*g++) - 2351 * (*b++)
+		     + 4210688) >> 15);
+		y1 = ((8453 * (*r) + 16594 * (*g) +  3223 * (*b)
+		     + 524288) >> 15);
+
+		*(*dst)++ = y;
+		*(*dst)++ = u;
+
+		*(*dst)++ = y1;
+		*(*dst)++ = v;
+		return;
+	}
+	case V4L2_PIX_FMT_SBGGR8:
+		if (!(ypos & 1)) {
+			*(*dst)++ = *b;
+			*(*dst)++ = *++g;
+		} else {
+			*(*dst)++ = *g;
+			*(*dst)++ = *++r;
+		}
+		return;
+	case V4L2_PIX_FMT_SGBRG8:
+		if (!(ypos & 1)) {
+			*(*dst)++ = *g;
+			*(*dst)++ = *++b;
+		} else {
+			*(*dst)++ = *r;
+			*(*dst)++ = *++g;
+		}
+		return;
+	case V4L2_PIX_FMT_SGRBG8:
+		if (!(ypos & 1)) {
+			*(*dst)++ = *g;
+			*(*dst)++ = *++r;
+		} else {
+			*(*dst)++ = *b;
+			*(*dst)++ = *++g;
+		}
+		return;
+	case V4L2_PIX_FMT_SRGGB8:
+		if (!(ypos & 1)) {
+			*(*dst)++ = *r;
+			*(*dst)++ = *++g;
+		} else {
+			*(*dst)++ = *g;
+			*(*dst)++ = *++b;
+		}
+		return;
+	}
+}
+
+static int device_process(struct vim2m_ctx *ctx,
+			  struct vb2_v4l2_buffer *in_vb,
+			  struct vb2_v4l2_buffer *out_vb)
+{
+	struct vim2m_dev *dev = ctx->dev;
+	struct vim2m_q_data *q_data_in, *q_data_out;
+	u8 *p_in, *p_line, *p_in_x[2], *p, *p_out;
+	unsigned int width, height, bytesperline, bytes_per_pixel;
+	unsigned int x, y, y_in, y_out, x_int, x_fract, x_err, x_offset;
+	int start, end, step;
+
+	q_data_in = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+	if (!q_data_in)
+		return 0;
+	bytesperline = (q_data_in->width * q_data_in->fmt->depth) >> 3;
+	bytes_per_pixel = q_data_in->fmt->depth >> 3;
+
+	q_data_out = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+	if (!q_data_out)
+		return 0;
+
+	/* As we're doing scaling, use the output dimensions here */
+	height = q_data_out->height;
+	width = q_data_out->width;
+
+	p_in = vb2_plane_vaddr(&in_vb->vb2_buf, 0);
+	p_out = vb2_plane_vaddr(&out_vb->vb2_buf, 0);
+	if (!p_in || !p_out) {
+		v4l2_err(&dev->v4l2_dev,
+			 "Acquiring kernel pointers to buffers failed\n");
+		return -EFAULT;
+	}
+
+	out_vb->sequence = q_data_out->sequence++;
+	in_vb->sequence = q_data_in->sequence++;
+	v4l2_m2m_buf_copy_metadata(in_vb, out_vb, true);
+
+	if (ctx->mode & MEM2MEM_VFLIP) {
+		start = height - 1;
+		end = -1;
+		step = -1;
+	} else {
+		start = 0;
+		end = height;
+		step = 1;
+	}
+	y_out = 0;
+
+	/*
+	 * When format and resolution are identical,
+	 * we can use a faster copy logic
+	 */
+	if (q_data_in->fmt->fourcc == q_data_out->fmt->fourcc &&
+	    q_data_in->width == q_data_out->width &&
+	    q_data_in->height == q_data_out->height) {
+		for (y = start; y != end; y += step, y_out++) {
+			p = p_in + (y * bytesperline);
+			if (ctx->mode & MEM2MEM_HFLIP)
+				p += bytesperline - (q_data_in->fmt->depth >> 3);
+
+			copy_line(q_data_out, p, p_out,
+				  ctx->mode & MEM2MEM_HFLIP);
+
+			p_out += bytesperline;
+		}
+		return 0;
+	}
+
+	/* Slower algorithm with format conversion, hflip, vflip and scaler */
+
+	/* To speed scaler up, use Bresenham for X dimension */
+	x_int = q_data_in->width / q_data_out->width;
+	x_fract = q_data_in->width % q_data_out->width;
+
+	for (y = start; y != end; y += step, y_out++) {
+		y_in = (y * q_data_in->height) / q_data_out->height;
+		x_offset = 0;
+		x_err = 0;
+
+		p_line = p_in + (y_in * bytesperline);
+		if (ctx->mode & MEM2MEM_HFLIP)
+			p_line += bytesperline - (q_data_in->fmt->depth >> 3);
+		p_in_x[0] = p_line;
+
+		for (x = 0; x < width >> 1; x++) {
+			x_offset += x_int;
+			x_err += x_fract;
+			if (x_err > width) {
+				x_offset++;
+				x_err -= width;
+			}
+
+			if (ctx->mode & MEM2MEM_HFLIP)
+				p_in_x[1] = p_line - x_offset * bytes_per_pixel;
+			else
+				p_in_x[1] = p_line + x_offset * bytes_per_pixel;
+
+			copy_two_pixels(q_data_in, q_data_out,
+					p_in_x, &p_out, y_out,
+					ctx->mode & MEM2MEM_HFLIP);
+
+			/* Calculate the next p_in_x0 */
+			x_offset += x_int;
+			x_err += x_fract;
+			if (x_err > width) {
+				x_offset++;
+				x_err -= width;
+			}
+
+			if (ctx->mode & MEM2MEM_HFLIP)
+				p_in_x[0] = p_line - x_offset * bytes_per_pixel;
+			else
+				p_in_x[0] = p_line + x_offset * bytes_per_pixel;
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * mem2mem callbacks
+ */
+
+/*
+ * job_ready() - check whether an instance is ready to be scheduled to run
+ */
+static int job_ready(void *priv)
+{
+	struct vim2m_ctx *ctx = priv;
+
+	if (v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) < ctx->translen
+	    || v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx) < ctx->translen) {
+		dprintk(ctx->dev, 1, "Not enough buffers available\n");
+		return 0;
+	}
+
+	return 1;
+}
+
+static void job_abort(void *priv)
+{
+	struct vim2m_ctx *ctx = priv;
+
+	/* Will cancel the transaction in the next interrupt handler */
+	ctx->aborting = 1;
+}
+
+/* device_run() - prepares and starts the device
+ *
+ * This simulates all the immediate preparations required before starting
+ * a device. This will be called by the framework when it decides to schedule
+ * a particular instance.
+ */
+static void device_run(void *priv)
+{
+	struct vim2m_ctx *ctx = priv;
+	struct vb2_v4l2_buffer *src_buf, *dst_buf;
+
+	src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
+	dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
+
+	/* Apply request controls if any */
+	v4l2_ctrl_request_setup(src_buf->vb2_buf.req_obj.req,
+				&ctx->hdl);
+
+	device_process(ctx, src_buf, dst_buf);
+
+	/* Complete request controls if any */
+	v4l2_ctrl_request_complete(src_buf->vb2_buf.req_obj.req,
+				   &ctx->hdl);
+
+	/* Run delayed work, which simulates a hardware irq  */
+	schedule_delayed_work(&ctx->work_run, msecs_to_jiffies(ctx->transtime));
+}
+
+static void device_work(struct work_struct *w)
+{
+	struct vim2m_ctx *curr_ctx;
+	struct vim2m_dev *vim2m_dev;
+	struct vb2_v4l2_buffer *src_vb, *dst_vb;
+
+	curr_ctx = container_of(w, struct vim2m_ctx, work_run.work);
+
+	if (!curr_ctx) {
+		pr_err("Instance released before the end of transaction\n");
+		return;
+	}
+
+	vim2m_dev = curr_ctx->dev;
+
+	src_vb = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
+	dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
+
+	curr_ctx->num_processed++;
+
+	v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE);
+	v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE);
+
+	if (curr_ctx->num_processed == curr_ctx->translen
+	    || curr_ctx->aborting) {
+		dprintk(curr_ctx->dev, 2, "Finishing capture buffer fill\n");
+		curr_ctx->num_processed = 0;
+		v4l2_m2m_job_finish(vim2m_dev->m2m_dev, curr_ctx->fh.m2m_ctx);
+	} else {
+		device_run(curr_ctx);
+	}
+}
+
+/*
+ * video ioctls
+ */
+static int vidioc_querycap(struct file *file, void *priv,
+			   struct v4l2_capability *cap)
+{
+	strscpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver));
+	strscpy(cap->card, MEM2MEM_NAME, sizeof(cap->card));
+	snprintf(cap->bus_info, sizeof(cap->bus_info),
+		 "platform:%s", MEM2MEM_NAME);
+	return 0;
+}
+
+static int enum_fmt(struct v4l2_fmtdesc *f, u32 type)
+{
+	int i, num;
+	struct vim2m_fmt *fmt;
+
+	num = 0;
+
+	for (i = 0; i < NUM_FORMATS; ++i) {
+		if (formats[i].types & type) {
+			/* index-th format of type type found ? */
+			if (num == f->index)
+				break;
+			/*
+			 * Correct type but haven't reached our index yet,
+			 * just increment per-type index
+			 */
+			++num;
+		}
+	}
+
+	if (i < NUM_FORMATS) {
+		/* Format found */
+		fmt = &formats[i];
+		f->pixelformat = fmt->fourcc;
+		return 0;
+	}
+
+	/* Format not found */
+	return -EINVAL;
+}
+
+static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
+				   struct v4l2_fmtdesc *f)
+{
+	return enum_fmt(f, MEM2MEM_CAPTURE);
+}
+
+static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
+				   struct v4l2_fmtdesc *f)
+{
+	return enum_fmt(f, MEM2MEM_OUTPUT);
+}
+
+static int vidioc_enum_framesizes(struct file *file, void *priv,
+				  struct v4l2_frmsizeenum *fsize)
+{
+	if (fsize->index != 0)
+		return -EINVAL;
+
+	if (!find_format(fsize->pixel_format))
+		return -EINVAL;
+
+	fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
+	fsize->stepwise.min_width = MIN_W;
+	fsize->stepwise.min_height = MIN_H;
+	fsize->stepwise.max_width = MAX_W;
+	fsize->stepwise.max_height = MAX_H;
+
+	get_alignment(fsize->pixel_format,
+		      &fsize->stepwise.step_width,
+		      &fsize->stepwise.step_height);
+	return 0;
+}
+
+static int vidioc_g_fmt(struct vim2m_ctx *ctx, struct v4l2_format *f)
+{
+	struct vb2_queue *vq;
+	struct vim2m_q_data *q_data;
+
+	vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
+	if (!vq)
+		return -EINVAL;
+
+	q_data = get_q_data(ctx, f->type);
+	if (!q_data)
+		return -EINVAL;
+
+	f->fmt.pix.width	= q_data->width;
+	f->fmt.pix.height	= q_data->height;
+	f->fmt.pix.field	= V4L2_FIELD_NONE;
+	f->fmt.pix.pixelformat	= q_data->fmt->fourcc;
+	f->fmt.pix.bytesperline	= (q_data->width * q_data->fmt->depth) >> 3;
+	f->fmt.pix.sizeimage	= q_data->sizeimage;
+	f->fmt.pix.colorspace	= ctx->colorspace;
+	f->fmt.pix.xfer_func	= ctx->xfer_func;
+	f->fmt.pix.ycbcr_enc	= ctx->ycbcr_enc;
+	f->fmt.pix.quantization	= ctx->quant;
+
+	return 0;
+}
+
+static int vidioc_g_fmt_vid_out(struct file *file, void *priv,
+				struct v4l2_format *f)
+{
+	return vidioc_g_fmt(file2ctx(file), f);
+}
+
+static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
+				struct v4l2_format *f)
+{
+	return vidioc_g_fmt(file2ctx(file), f);
+}
+
+static int vidioc_try_fmt(struct v4l2_format *f, struct vim2m_fmt *fmt)
+{
+	int walign, halign;
+	/*
+	 * V4L2 specification specifies the driver corrects the
+	 * format struct if any of the dimensions is unsupported
+	 */
+	if (f->fmt.pix.height < MIN_H)
+		f->fmt.pix.height = MIN_H;
+	else if (f->fmt.pix.height > MAX_H)
+		f->fmt.pix.height = MAX_H;
+
+	if (f->fmt.pix.width < MIN_W)
+		f->fmt.pix.width = MIN_W;
+	else if (f->fmt.pix.width > MAX_W)
+		f->fmt.pix.width = MAX_W;
+
+	get_alignment(f->fmt.pix.pixelformat, &walign, &halign);
+	f->fmt.pix.width &= ~(walign - 1);
+	f->fmt.pix.height &= ~(halign - 1);
+	f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
+	f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
+	f->fmt.pix.field = V4L2_FIELD_NONE;
+
+	return 0;
+}
+
+static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
+				  struct v4l2_format *f)
+{
+	struct vim2m_fmt *fmt;
+	struct vim2m_ctx *ctx = file2ctx(file);
+
+	fmt = find_format(f->fmt.pix.pixelformat);
+	if (!fmt) {
+		f->fmt.pix.pixelformat = formats[0].fourcc;
+		fmt = find_format(f->fmt.pix.pixelformat);
+	}
+	if (!(fmt->types & MEM2MEM_CAPTURE)) {
+		v4l2_err(&ctx->dev->v4l2_dev,
+			 "Fourcc format (0x%08x) invalid.\n",
+			 f->fmt.pix.pixelformat);
+		return -EINVAL;
+	}
+	f->fmt.pix.colorspace = ctx->colorspace;
+	f->fmt.pix.xfer_func = ctx->xfer_func;
+	f->fmt.pix.ycbcr_enc = ctx->ycbcr_enc;
+	f->fmt.pix.quantization = ctx->quant;
+
+	return vidioc_try_fmt(f, fmt);
+}
+
+static int vidioc_try_fmt_vid_out(struct file *file, void *priv,
+				  struct v4l2_format *f)
+{
+	struct vim2m_fmt *fmt;
+	struct vim2m_ctx *ctx = file2ctx(file);
+
+	fmt = find_format(f->fmt.pix.pixelformat);
+	if (!fmt) {
+		f->fmt.pix.pixelformat = formats[0].fourcc;
+		fmt = find_format(f->fmt.pix.pixelformat);
+	}
+	if (!(fmt->types & MEM2MEM_OUTPUT)) {
+		v4l2_err(&ctx->dev->v4l2_dev,
+			 "Fourcc format (0x%08x) invalid.\n",
+			 f->fmt.pix.pixelformat);
+		return -EINVAL;
+	}
+	if (!f->fmt.pix.colorspace)
+		f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
+
+	return vidioc_try_fmt(f, fmt);
+}
+
+static int vidioc_s_fmt(struct vim2m_ctx *ctx, struct v4l2_format *f)
+{
+	struct vim2m_q_data *q_data;
+	struct vb2_queue *vq;
+
+	vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
+	if (!vq)
+		return -EINVAL;
+
+	q_data = get_q_data(ctx, f->type);
+	if (!q_data)
+		return -EINVAL;
+
+	if (vb2_is_busy(vq)) {
+		v4l2_err(&ctx->dev->v4l2_dev, "%s queue busy\n", __func__);
+		return -EBUSY;
+	}
+
+	q_data->fmt		= find_format(f->fmt.pix.pixelformat);
+	q_data->width		= f->fmt.pix.width;
+	q_data->height		= f->fmt.pix.height;
+	q_data->sizeimage	= q_data->width * q_data->height
+				* q_data->fmt->depth >> 3;
+
+	dprintk(ctx->dev, 1,
+		"Format for type %s: %dx%d (%d bpp), fmt: %c%c%c%c\n",
+		type_name(f->type), q_data->width, q_data->height,
+		q_data->fmt->depth,
+		(q_data->fmt->fourcc & 0xff),
+		(q_data->fmt->fourcc >>  8) & 0xff,
+		(q_data->fmt->fourcc >> 16) & 0xff,
+		(q_data->fmt->fourcc >> 24) & 0xff);
+
+	return 0;
+}
+
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+				struct v4l2_format *f)
+{
+	int ret;
+
+	ret = vidioc_try_fmt_vid_cap(file, priv, f);
+	if (ret)
+		return ret;
+
+	return vidioc_s_fmt(file2ctx(file), f);
+}
+
+static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
+				struct v4l2_format *f)
+{
+	struct vim2m_ctx *ctx = file2ctx(file);
+	int ret;
+
+	ret = vidioc_try_fmt_vid_out(file, priv, f);
+	if (ret)
+		return ret;
+
+	ret = vidioc_s_fmt(file2ctx(file), f);
+	if (!ret) {
+		ctx->colorspace = f->fmt.pix.colorspace;
+		ctx->xfer_func = f->fmt.pix.xfer_func;
+		ctx->ycbcr_enc = f->fmt.pix.ycbcr_enc;
+		ctx->quant = f->fmt.pix.quantization;
+	}
+	return ret;
+}
+
+static int vim2m_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct vim2m_ctx *ctx =
+		container_of(ctrl->handler, struct vim2m_ctx, hdl);
+
+	switch (ctrl->id) {
+	case V4L2_CID_HFLIP:
+		if (ctrl->val)
+			ctx->mode |= MEM2MEM_HFLIP;
+		else
+			ctx->mode &= ~MEM2MEM_HFLIP;
+		break;
+
+	case V4L2_CID_VFLIP:
+		if (ctrl->val)
+			ctx->mode |= MEM2MEM_VFLIP;
+		else
+			ctx->mode &= ~MEM2MEM_VFLIP;
+		break;
+
+	case V4L2_CID_TRANS_TIME_MSEC:
+		ctx->transtime = ctrl->val;
+		if (ctx->transtime < 1)
+			ctx->transtime = 1;
+		break;
+
+	case V4L2_CID_TRANS_NUM_BUFS:
+		ctx->translen = ctrl->val;
+		break;
+
+	default:
+		v4l2_err(&ctx->dev->v4l2_dev, "Invalid control\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct v4l2_ctrl_ops vim2m_ctrl_ops = {
+	.s_ctrl = vim2m_s_ctrl,
+};
+
+static const struct v4l2_ioctl_ops vim2m_ioctl_ops = {
+	.vidioc_querycap	= vidioc_querycap,
+
+	.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
+	.vidioc_enum_framesizes = vidioc_enum_framesizes,
+	.vidioc_g_fmt_vid_cap	= vidioc_g_fmt_vid_cap,
+	.vidioc_try_fmt_vid_cap	= vidioc_try_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap	= vidioc_s_fmt_vid_cap,
+
+	.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,
+
+	.vidioc_reqbufs		= v4l2_m2m_ioctl_reqbufs,
+	.vidioc_querybuf	= v4l2_m2m_ioctl_querybuf,
+	.vidioc_qbuf		= v4l2_m2m_ioctl_qbuf,
+	.vidioc_dqbuf		= v4l2_m2m_ioctl_dqbuf,
+	.vidioc_prepare_buf	= v4l2_m2m_ioctl_prepare_buf,
+	.vidioc_create_bufs	= v4l2_m2m_ioctl_create_bufs,
+	.vidioc_expbuf		= v4l2_m2m_ioctl_expbuf,
+
+	.vidioc_streamon	= v4l2_m2m_ioctl_streamon,
+	.vidioc_streamoff	= v4l2_m2m_ioctl_streamoff,
+
+	.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+};
+
+/*
+ * Queue operations
+ */
+
+static int vim2m_queue_setup(struct vb2_queue *vq,
+			     unsigned int *nbuffers,
+			     unsigned int *nplanes,
+			     unsigned int sizes[],
+			     struct device *alloc_devs[])
+{
+	struct vim2m_ctx *ctx = vb2_get_drv_priv(vq);
+	struct vim2m_q_data *q_data;
+	unsigned int size, count = *nbuffers;
+
+	q_data = get_q_data(ctx, vq->type);
+	if (!q_data)
+		return -EINVAL;
+
+	size = q_data->width * q_data->height * q_data->fmt->depth >> 3;
+
+	while (size * count > MEM2MEM_VID_MEM_LIMIT)
+		(count)--;
+	*nbuffers = count;
+
+	if (*nplanes)
+		return sizes[0] < size ? -EINVAL : 0;
+
+	*nplanes = 1;
+	sizes[0] = size;
+
+	dprintk(ctx->dev, 1, "%s: get %d buffer(s) of size %d each.\n",
+		type_name(vq->type), count, size);
+
+	return 0;
+}
+
+static int vim2m_buf_out_validate(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct vim2m_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+
+	if (vbuf->field == V4L2_FIELD_ANY)
+		vbuf->field = V4L2_FIELD_NONE;
+	if (vbuf->field != V4L2_FIELD_NONE) {
+		dprintk(ctx->dev, 1, "%s field isn't supported\n", __func__);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int vim2m_buf_prepare(struct vb2_buffer *vb)
+{
+	struct vim2m_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+	struct vim2m_q_data *q_data;
+
+	dprintk(ctx->dev, 2, "type: %s\n", type_name(vb->vb2_queue->type));
+
+	q_data = get_q_data(ctx, vb->vb2_queue->type);
+	if (!q_data)
+		return -EINVAL;
+	if (vb2_plane_size(vb, 0) < q_data->sizeimage) {
+		dprintk(ctx->dev, 1,
+			"%s data will not fit into plane (%lu < %lu)\n",
+			__func__, vb2_plane_size(vb, 0),
+			(long)q_data->sizeimage);
+		return -EINVAL;
+	}
+
+	vb2_set_plane_payload(vb, 0, q_data->sizeimage);
+
+	return 0;
+}
+
+static void vim2m_buf_queue(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct vim2m_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+
+	v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
+}
+
+static int vim2m_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+	struct vim2m_ctx *ctx = vb2_get_drv_priv(q);
+	struct vim2m_q_data *q_data = get_q_data(ctx, q->type);
+
+	if (!q_data)
+		return -EINVAL;
+
+	if (V4L2_TYPE_IS_OUTPUT(q->type))
+		ctx->aborting = 0;
+
+	q_data->sequence = 0;
+	return 0;
+}
+
+static void vim2m_stop_streaming(struct vb2_queue *q)
+{
+	struct vim2m_ctx *ctx = vb2_get_drv_priv(q);
+	struct vb2_v4l2_buffer *vbuf;
+
+	cancel_delayed_work_sync(&ctx->work_run);
+
+	for (;;) {
+		if (V4L2_TYPE_IS_OUTPUT(q->type))
+			vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+		else
+			vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
+		if (!vbuf)
+			return;
+		v4l2_ctrl_request_complete(vbuf->vb2_buf.req_obj.req,
+					   &ctx->hdl);
+		v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
+	}
+}
+
+static void vim2m_buf_request_complete(struct vb2_buffer *vb)
+{
+	struct vim2m_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+
+	v4l2_ctrl_request_complete(vb->req_obj.req, &ctx->hdl);
+}
+
+static const struct vb2_ops vim2m_qops = {
+	.queue_setup	 = vim2m_queue_setup,
+	.buf_out_validate	 = vim2m_buf_out_validate,
+	.buf_prepare	 = vim2m_buf_prepare,
+	.buf_queue	 = vim2m_buf_queue,
+	.start_streaming = vim2m_start_streaming,
+	.stop_streaming  = vim2m_stop_streaming,
+	.wait_prepare	 = vb2_ops_wait_prepare,
+	.wait_finish	 = vb2_ops_wait_finish,
+	.buf_request_complete = vim2m_buf_request_complete,
+};
+
+static int queue_init(void *priv, struct vb2_queue *src_vq,
+		      struct vb2_queue *dst_vq)
+{
+	struct vim2m_ctx *ctx = priv;
+	int ret;
+
+	src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+	src_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
+	src_vq->drv_priv = ctx;
+	src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
+	src_vq->ops = &vim2m_qops;
+	src_vq->mem_ops = &vb2_vmalloc_memops;
+	src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+	src_vq->lock = &ctx->vb_mutex;
+	src_vq->supports_requests = true;
+
+	ret = vb2_queue_init(src_vq);
+	if (ret)
+		return ret;
+
+	dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	dst_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
+	dst_vq->drv_priv = ctx;
+	dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
+	dst_vq->ops = &vim2m_qops;
+	dst_vq->mem_ops = &vb2_vmalloc_memops;
+	dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+	dst_vq->lock = &ctx->vb_mutex;
+
+	return vb2_queue_init(dst_vq);
+}
+
+static struct v4l2_ctrl_config vim2m_ctrl_trans_time_msec = {
+	.ops = &vim2m_ctrl_ops,
+	.id = V4L2_CID_TRANS_TIME_MSEC,
+	.name = "Transaction Time (msec)",
+	.type = V4L2_CTRL_TYPE_INTEGER,
+	.min = 1,
+	.max = 10001,
+	.step = 1,
+};
+
+static const struct v4l2_ctrl_config vim2m_ctrl_trans_num_bufs = {
+	.ops = &vim2m_ctrl_ops,
+	.id = V4L2_CID_TRANS_NUM_BUFS,
+	.name = "Buffers Per Transaction",
+	.type = V4L2_CTRL_TYPE_INTEGER,
+	.def = 1,
+	.min = 1,
+	.max = MEM2MEM_DEF_NUM_BUFS,
+	.step = 1,
+};
+
+/*
+ * File operations
+ */
+static int vim2m_open(struct file *file)
+{
+	struct vim2m_dev *dev = video_drvdata(file);
+	struct vim2m_ctx *ctx = NULL;
+	struct v4l2_ctrl_handler *hdl;
+	int rc = 0;
+
+	if (mutex_lock_interruptible(&dev->dev_mutex))
+		return -ERESTARTSYS;
+	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+	if (!ctx) {
+		rc = -ENOMEM;
+		goto open_unlock;
+	}
+
+	v4l2_fh_init(&ctx->fh, video_devdata(file));
+	file->private_data = &ctx->fh;
+	ctx->dev = dev;
+	hdl = &ctx->hdl;
+	v4l2_ctrl_handler_init(hdl, 4);
+	v4l2_ctrl_new_std(hdl, &vim2m_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0);
+	v4l2_ctrl_new_std(hdl, &vim2m_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0);
+
+	vim2m_ctrl_trans_time_msec.def = default_transtime;
+	v4l2_ctrl_new_custom(hdl, &vim2m_ctrl_trans_time_msec, NULL);
+	v4l2_ctrl_new_custom(hdl, &vim2m_ctrl_trans_num_bufs, NULL);
+	if (hdl->error) {
+		rc = hdl->error;
+		v4l2_ctrl_handler_free(hdl);
+		kfree(ctx);
+		goto open_unlock;
+	}
+	ctx->fh.ctrl_handler = hdl;
+	v4l2_ctrl_handler_setup(hdl);
+
+	ctx->q_data[V4L2_M2M_SRC].fmt = &formats[0];
+	ctx->q_data[V4L2_M2M_SRC].width = 640;
+	ctx->q_data[V4L2_M2M_SRC].height = 480;
+	ctx->q_data[V4L2_M2M_SRC].sizeimage =
+		ctx->q_data[V4L2_M2M_SRC].width *
+		ctx->q_data[V4L2_M2M_SRC].height *
+		(ctx->q_data[V4L2_M2M_SRC].fmt->depth >> 3);
+	ctx->q_data[V4L2_M2M_DST] = ctx->q_data[V4L2_M2M_SRC];
+	ctx->colorspace = V4L2_COLORSPACE_REC709;
+
+	ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init);
+
+	mutex_init(&ctx->vb_mutex);
+	INIT_DELAYED_WORK(&ctx->work_run, device_work);
+
+	if (IS_ERR(ctx->fh.m2m_ctx)) {
+		rc = PTR_ERR(ctx->fh.m2m_ctx);
+
+		v4l2_ctrl_handler_free(hdl);
+		v4l2_fh_exit(&ctx->fh);
+		kfree(ctx);
+		goto open_unlock;
+	}
+
+	v4l2_fh_add(&ctx->fh);
+	atomic_inc(&dev->num_inst);
+
+	dprintk(dev, 1, "Created instance: %p, m2m_ctx: %p\n",
+		ctx, ctx->fh.m2m_ctx);
+
+open_unlock:
+	mutex_unlock(&dev->dev_mutex);
+	return rc;
+}
+
+static int vim2m_release(struct file *file)
+{
+	struct vim2m_dev *dev = video_drvdata(file);
+	struct vim2m_ctx *ctx = file2ctx(file);
+
+	dprintk(dev, 1, "Releasing instance %p\n", ctx);
+
+	v4l2_fh_del(&ctx->fh);
+	v4l2_fh_exit(&ctx->fh);
+	v4l2_ctrl_handler_free(&ctx->hdl);
+	mutex_lock(&dev->dev_mutex);
+	v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
+	mutex_unlock(&dev->dev_mutex);
+	kfree(ctx);
+
+	atomic_dec(&dev->num_inst);
+
+	return 0;
+}
+
+static void vim2m_device_release(struct video_device *vdev)
+{
+	struct vim2m_dev *dev = container_of(vdev, struct vim2m_dev, vfd);
+
+	v4l2_device_unregister(&dev->v4l2_dev);
+	v4l2_m2m_release(dev->m2m_dev);
+#ifdef CONFIG_MEDIA_CONTROLLER
+	media_device_cleanup(&dev->mdev);
+#endif
+	kfree(dev);
+}
+
+static const struct v4l2_file_operations vim2m_fops = {
+	.owner		= THIS_MODULE,
+	.open		= vim2m_open,
+	.release	= vim2m_release,
+	.poll		= v4l2_m2m_fop_poll,
+	.unlocked_ioctl	= video_ioctl2,
+	.mmap		= v4l2_m2m_fop_mmap,
+};
+
+static const struct video_device vim2m_videodev = {
+	.name		= MEM2MEM_NAME,
+	.vfl_dir	= VFL_DIR_M2M,
+	.fops		= &vim2m_fops,
+	.ioctl_ops	= &vim2m_ioctl_ops,
+	.minor		= -1,
+	.release	= vim2m_device_release,
+	.device_caps	= V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING,
+};
+
+static const struct v4l2_m2m_ops m2m_ops = {
+	.device_run	= device_run,
+	.job_ready	= job_ready,
+	.job_abort	= job_abort,
+};
+
+static const struct media_device_ops m2m_media_ops = {
+	.req_validate = vb2_request_validate,
+	.req_queue = v4l2_m2m_request_queue,
+};
+
+static int vim2m_probe(struct platform_device *pdev)
+{
+	struct vim2m_dev *dev;
+	struct video_device *vfd;
+	int ret;
+
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	if (!dev)
+		return -ENOMEM;
+
+	ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
+	if (ret)
+		goto error_free;
+
+	atomic_set(&dev->num_inst, 0);
+	mutex_init(&dev->dev_mutex);
+
+	dev->vfd = vim2m_videodev;
+	vfd = &dev->vfd;
+	vfd->lock = &dev->dev_mutex;
+	vfd->v4l2_dev = &dev->v4l2_dev;
+
+	ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0);
+	if (ret) {
+		v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
+		goto error_v4l2;
+	}
+
+	video_set_drvdata(vfd, dev);
+	v4l2_info(&dev->v4l2_dev,
+		  "Device registered as /dev/video%d\n", vfd->num);
+
+	platform_set_drvdata(pdev, dev);
+
+	dev->m2m_dev = v4l2_m2m_init(&m2m_ops);
+	if (IS_ERR(dev->m2m_dev)) {
+		v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n");
+		ret = PTR_ERR(dev->m2m_dev);
+		dev->m2m_dev = NULL;
+		goto error_dev;
+	}
+
+#ifdef CONFIG_MEDIA_CONTROLLER
+	dev->mdev.dev = &pdev->dev;
+	strscpy(dev->mdev.model, "vim2m", sizeof(dev->mdev.model));
+	strscpy(dev->mdev.bus_info, "platform:vim2m",
+		sizeof(dev->mdev.bus_info));
+	media_device_init(&dev->mdev);
+	dev->mdev.ops = &m2m_media_ops;
+	dev->v4l2_dev.mdev = &dev->mdev;
+
+	ret = v4l2_m2m_register_media_controller(dev->m2m_dev, vfd,
+						 MEDIA_ENT_F_PROC_VIDEO_SCALER);
+	if (ret) {
+		v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem media controller\n");
+		goto error_dev;
+	}
+
+	ret = media_device_register(&dev->mdev);
+	if (ret) {
+		v4l2_err(&dev->v4l2_dev, "Failed to register mem2mem media device\n");
+		goto error_m2m_mc;
+	}
+#endif
+	return 0;
+
+#ifdef CONFIG_MEDIA_CONTROLLER
+error_m2m_mc:
+	v4l2_m2m_unregister_media_controller(dev->m2m_dev);
+#endif
+error_dev:
+	video_unregister_device(&dev->vfd);
+	/* vim2m_device_release called by video_unregister_device to release various objects */
+	return ret;
+error_v4l2:
+	v4l2_device_unregister(&dev->v4l2_dev);
+error_free:
+	kfree(dev);
+
+	return ret;
+}
+
+static int vim2m_remove(struct platform_device *pdev)
+{
+	struct vim2m_dev *dev = platform_get_drvdata(pdev);
+
+	v4l2_info(&dev->v4l2_dev, "Removing " MEM2MEM_NAME);
+
+#ifdef CONFIG_MEDIA_CONTROLLER
+	media_device_unregister(&dev->mdev);
+	v4l2_m2m_unregister_media_controller(dev->m2m_dev);
+#endif
+	video_unregister_device(&dev->vfd);
+
+	return 0;
+}
+
+static struct platform_driver vim2m_pdrv = {
+	.probe		= vim2m_probe,
+	.remove		= vim2m_remove,
+	.driver		= {
+		.name	= MEM2MEM_NAME,
+	},
+};
+
+static void __exit vim2m_exit(void)
+{
+	platform_driver_unregister(&vim2m_pdrv);
+	platform_device_unregister(&vim2m_pdev);
+}
+
+static int __init vim2m_init(void)
+{
+	int ret;
+
+	ret = platform_device_register(&vim2m_pdev);
+	if (ret)
+		return ret;
+
+	ret = platform_driver_register(&vim2m_pdrv);
+	if (ret)
+		platform_device_unregister(&vim2m_pdev);
+
+	return ret;
+}
+
+module_init(vim2m_init);
+module_exit(vim2m_exit);
diff --git a/drivers/media/test-drivers/vimc/Kconfig b/drivers/media/test-drivers/vimc/Kconfig
new file mode 100644
index 000000000000..4068a67585f9
--- /dev/null
+++ b/drivers/media/test-drivers/vimc/Kconfig
@@ -0,0 +1,17 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config VIDEO_VIMC
+	tristate "Virtual Media Controller Driver (VIMC)"
+	depends on VIDEO_DEV && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
+	select VIDEOBUF2_VMALLOC
+	select VIDEO_V4L2_TPG
+	help
+	  Skeleton driver for Virtual Media Controller
+
+	  This driver can be compared to the vivid driver for emulating
+	  a media node that exposes a complex media topology. The topology
+	  is hard coded for now but is meant to be highly configurable in
+	  the future.
+
+	  When in doubt, say N.
diff --git a/drivers/media/test-drivers/vimc/Makefile b/drivers/media/test-drivers/vimc/Makefile
new file mode 100644
index 000000000000..a53b2b532e9f
--- /dev/null
+++ b/drivers/media/test-drivers/vimc/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+vimc-y := vimc-core.o vimc-common.o vimc-streamer.o vimc-capture.o \
+		vimc-debayer.o vimc-scaler.o vimc-sensor.o
+
+obj-$(CONFIG_VIDEO_VIMC) += vimc.o
+
diff --git a/drivers/media/test-drivers/vimc/vimc-capture.c b/drivers/media/test-drivers/vimc/vimc-capture.c
new file mode 100644
index 000000000000..5315c201314c
--- /dev/null
+++ b/drivers/media/test-drivers/vimc/vimc-capture.c
@@ -0,0 +1,486 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * vimc-capture.c Virtual Media Controller Driver
+ *
+ * Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>
+ */
+
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-vmalloc.h>
+
+#include "vimc-common.h"
+#include "vimc-streamer.h"
+
+struct vimc_cap_device {
+	struct vimc_ent_device ved;
+	struct video_device vdev;
+	struct v4l2_pix_format format;
+	struct vb2_queue queue;
+	struct list_head buf_list;
+	/*
+	 * NOTE: in a real driver, a spin lock must be used to access the
+	 * queue because the frames are generated from a hardware interruption
+	 * and the isr is not allowed to sleep.
+	 * Even if it is not necessary a spinlock in the vimc driver, we
+	 * use it here as a code reference
+	 */
+	spinlock_t qlock;
+	struct mutex lock;
+	u32 sequence;
+	struct vimc_stream stream;
+	struct media_pad pad;
+};
+
+static const struct v4l2_pix_format fmt_default = {
+	.width = 640,
+	.height = 480,
+	.pixelformat = V4L2_PIX_FMT_RGB24,
+	.field = V4L2_FIELD_NONE,
+	.colorspace = V4L2_COLORSPACE_DEFAULT,
+};
+
+struct vimc_cap_buffer {
+	/*
+	 * struct vb2_v4l2_buffer must be the first element
+	 * the videobuf2 framework will allocate this struct based on
+	 * buf_struct_size and use the first sizeof(struct vb2_buffer) bytes of
+	 * memory as a vb2_buffer
+	 */
+	struct vb2_v4l2_buffer vb2;
+	struct list_head list;
+};
+
+static int vimc_cap_querycap(struct file *file, void *priv,
+			     struct v4l2_capability *cap)
+{
+	strscpy(cap->driver, VIMC_PDEV_NAME, sizeof(cap->driver));
+	strscpy(cap->card, KBUILD_MODNAME, sizeof(cap->card));
+	snprintf(cap->bus_info, sizeof(cap->bus_info),
+		 "platform:%s", VIMC_PDEV_NAME);
+
+	return 0;
+}
+
+static void vimc_cap_get_format(struct vimc_ent_device *ved,
+				struct v4l2_pix_format *fmt)
+{
+	struct vimc_cap_device *vcap = container_of(ved, struct vimc_cap_device,
+						    ved);
+
+	*fmt = vcap->format;
+}
+
+static int vimc_cap_g_fmt_vid_cap(struct file *file, void *priv,
+				  struct v4l2_format *f)
+{
+	struct vimc_cap_device *vcap = video_drvdata(file);
+
+	f->fmt.pix = vcap->format;
+
+	return 0;
+}
+
+static int vimc_cap_try_fmt_vid_cap(struct file *file, void *priv,
+				    struct v4l2_format *f)
+{
+	struct v4l2_pix_format *format = &f->fmt.pix;
+	const struct vimc_pix_map *vpix;
+
+	format->width = clamp_t(u32, format->width, VIMC_FRAME_MIN_WIDTH,
+				VIMC_FRAME_MAX_WIDTH) & ~1;
+	format->height = clamp_t(u32, format->height, VIMC_FRAME_MIN_HEIGHT,
+				 VIMC_FRAME_MAX_HEIGHT) & ~1;
+
+	/* Don't accept a pixelformat that is not on the table */
+	vpix = vimc_pix_map_by_pixelformat(format->pixelformat);
+	if (!vpix) {
+		format->pixelformat = fmt_default.pixelformat;
+		vpix = vimc_pix_map_by_pixelformat(format->pixelformat);
+	}
+	/* TODO: Add support for custom bytesperline values */
+	format->bytesperline = format->width * vpix->bpp;
+	format->sizeimage = format->bytesperline * format->height;
+
+	if (format->field == V4L2_FIELD_ANY)
+		format->field = fmt_default.field;
+
+	vimc_colorimetry_clamp(format);
+
+	return 0;
+}
+
+static int vimc_cap_s_fmt_vid_cap(struct file *file, void *priv,
+				  struct v4l2_format *f)
+{
+	struct vimc_cap_device *vcap = video_drvdata(file);
+	int ret;
+
+	/* Do not change the format while stream is on */
+	if (vb2_is_busy(&vcap->queue))
+		return -EBUSY;
+
+	ret = vimc_cap_try_fmt_vid_cap(file, priv, f);
+	if (ret)
+		return ret;
+
+	dev_dbg(vcap->ved.dev, "%s: format update: "
+		"old:%dx%d (0x%x, %d, %d, %d, %d) "
+		"new:%dx%d (0x%x, %d, %d, %d, %d)\n", vcap->vdev.name,
+		/* old */
+		vcap->format.width, vcap->format.height,
+		vcap->format.pixelformat, vcap->format.colorspace,
+		vcap->format.quantization, vcap->format.xfer_func,
+		vcap->format.ycbcr_enc,
+		/* new */
+		f->fmt.pix.width, f->fmt.pix.height,
+		f->fmt.pix.pixelformat,	f->fmt.pix.colorspace,
+		f->fmt.pix.quantization, f->fmt.pix.xfer_func,
+		f->fmt.pix.ycbcr_enc);
+
+	vcap->format = f->fmt.pix;
+
+	return 0;
+}
+
+static int vimc_cap_enum_fmt_vid_cap(struct file *file, void *priv,
+				     struct v4l2_fmtdesc *f)
+{
+	const struct vimc_pix_map *vpix = vimc_pix_map_by_index(f->index);
+
+	if (!vpix)
+		return -EINVAL;
+
+	f->pixelformat = vpix->pixelformat;
+
+	return 0;
+}
+
+static int vimc_cap_enum_framesizes(struct file *file, void *fh,
+				    struct v4l2_frmsizeenum *fsize)
+{
+	const struct vimc_pix_map *vpix;
+
+	if (fsize->index)
+		return -EINVAL;
+
+	/* Only accept code in the pix map table */
+	vpix = vimc_pix_map_by_code(fsize->pixel_format);
+	if (!vpix)
+		return -EINVAL;
+
+	fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS;
+	fsize->stepwise.min_width = VIMC_FRAME_MIN_WIDTH;
+	fsize->stepwise.max_width = VIMC_FRAME_MAX_WIDTH;
+	fsize->stepwise.min_height = VIMC_FRAME_MIN_HEIGHT;
+	fsize->stepwise.max_height = VIMC_FRAME_MAX_HEIGHT;
+	fsize->stepwise.step_width = 1;
+	fsize->stepwise.step_height = 1;
+
+	return 0;
+}
+
+static const struct v4l2_file_operations vimc_cap_fops = {
+	.owner		= THIS_MODULE,
+	.open		= v4l2_fh_open,
+	.release	= vb2_fop_release,
+	.read           = vb2_fop_read,
+	.poll		= vb2_fop_poll,
+	.unlocked_ioctl = video_ioctl2,
+	.mmap           = vb2_fop_mmap,
+};
+
+static const struct v4l2_ioctl_ops vimc_cap_ioctl_ops = {
+	.vidioc_querycap = vimc_cap_querycap,
+
+	.vidioc_g_fmt_vid_cap = vimc_cap_g_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap = vimc_cap_s_fmt_vid_cap,
+	.vidioc_try_fmt_vid_cap = vimc_cap_try_fmt_vid_cap,
+	.vidioc_enum_fmt_vid_cap = vimc_cap_enum_fmt_vid_cap,
+	.vidioc_enum_framesizes = vimc_cap_enum_framesizes,
+
+	.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_expbuf = vb2_ioctl_expbuf,
+	.vidioc_streamon = vb2_ioctl_streamon,
+	.vidioc_streamoff = vb2_ioctl_streamoff,
+};
+
+static void vimc_cap_return_all_buffers(struct vimc_cap_device *vcap,
+					enum vb2_buffer_state state)
+{
+	struct vimc_cap_buffer *vbuf, *node;
+
+	spin_lock(&vcap->qlock);
+
+	list_for_each_entry_safe(vbuf, node, &vcap->buf_list, list) {
+		list_del(&vbuf->list);
+		vb2_buffer_done(&vbuf->vb2.vb2_buf, state);
+	}
+
+	spin_unlock(&vcap->qlock);
+}
+
+static int vimc_cap_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+	struct vimc_cap_device *vcap = vb2_get_drv_priv(vq);
+	struct media_entity *entity = &vcap->vdev.entity;
+	int ret;
+
+	vcap->sequence = 0;
+
+	/* Start the media pipeline */
+	ret = media_pipeline_start(entity, &vcap->stream.pipe);
+	if (ret) {
+		vimc_cap_return_all_buffers(vcap, VB2_BUF_STATE_QUEUED);
+		return ret;
+	}
+
+	ret = vimc_streamer_s_stream(&vcap->stream, &vcap->ved, 1);
+	if (ret) {
+		media_pipeline_stop(entity);
+		vimc_cap_return_all_buffers(vcap, VB2_BUF_STATE_QUEUED);
+		return ret;
+	}
+
+	return 0;
+}
+
+/*
+ * Stop the stream engine. Any remaining buffers in the stream queue are
+ * dequeued and passed on to the vb2 framework marked as STATE_ERROR.
+ */
+static void vimc_cap_stop_streaming(struct vb2_queue *vq)
+{
+	struct vimc_cap_device *vcap = vb2_get_drv_priv(vq);
+
+	vimc_streamer_s_stream(&vcap->stream, &vcap->ved, 0);
+
+	/* Stop the media pipeline */
+	media_pipeline_stop(&vcap->vdev.entity);
+
+	/* Release all active buffers */
+	vimc_cap_return_all_buffers(vcap, VB2_BUF_STATE_ERROR);
+}
+
+static void vimc_cap_buf_queue(struct vb2_buffer *vb2_buf)
+{
+	struct vimc_cap_device *vcap = vb2_get_drv_priv(vb2_buf->vb2_queue);
+	struct vimc_cap_buffer *buf = container_of(vb2_buf,
+						   struct vimc_cap_buffer,
+						   vb2.vb2_buf);
+
+	spin_lock(&vcap->qlock);
+	list_add_tail(&buf->list, &vcap->buf_list);
+	spin_unlock(&vcap->qlock);
+}
+
+static int vimc_cap_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
+				unsigned int *nplanes, unsigned int sizes[],
+				struct device *alloc_devs[])
+{
+	struct vimc_cap_device *vcap = vb2_get_drv_priv(vq);
+
+	if (*nplanes)
+		return sizes[0] < vcap->format.sizeimage ? -EINVAL : 0;
+	/* We don't support multiplanes for now */
+	*nplanes = 1;
+	sizes[0] = vcap->format.sizeimage;
+
+	return 0;
+}
+
+static int vimc_cap_buffer_prepare(struct vb2_buffer *vb)
+{
+	struct vimc_cap_device *vcap = vb2_get_drv_priv(vb->vb2_queue);
+	unsigned long size = vcap->format.sizeimage;
+
+	if (vb2_plane_size(vb, 0) < size) {
+		dev_err(vcap->ved.dev, "%s: buffer too small (%lu < %lu)\n",
+			vcap->vdev.name, vb2_plane_size(vb, 0), size);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static const struct vb2_ops vimc_cap_qops = {
+	.start_streaming	= vimc_cap_start_streaming,
+	.stop_streaming		= vimc_cap_stop_streaming,
+	.buf_queue		= vimc_cap_buf_queue,
+	.queue_setup		= vimc_cap_queue_setup,
+	.buf_prepare		= vimc_cap_buffer_prepare,
+	/*
+	 * Since q->lock is set we can use the standard
+	 * vb2_ops_wait_prepare/finish helper functions.
+	 */
+	.wait_prepare		= vb2_ops_wait_prepare,
+	.wait_finish		= vb2_ops_wait_finish,
+};
+
+static const struct media_entity_operations vimc_cap_mops = {
+	.link_validate		= vimc_vdev_link_validate,
+};
+
+static void vimc_cap_release(struct vimc_ent_device *ved)
+{
+	struct vimc_cap_device *vcap =
+		container_of(ved, struct vimc_cap_device, ved);
+
+	media_entity_cleanup(vcap->ved.ent);
+	kfree(vcap);
+}
+
+static void vimc_cap_unregister(struct vimc_ent_device *ved)
+{
+	struct vimc_cap_device *vcap =
+		container_of(ved, struct vimc_cap_device, ved);
+
+	vb2_queue_release(&vcap->queue);
+	video_unregister_device(&vcap->vdev);
+}
+
+static void *vimc_cap_process_frame(struct vimc_ent_device *ved,
+				    const void *frame)
+{
+	struct vimc_cap_device *vcap = container_of(ved, struct vimc_cap_device,
+						    ved);
+	struct vimc_cap_buffer *vimc_buf;
+	void *vbuf;
+
+	spin_lock(&vcap->qlock);
+
+	/* Get the first entry of the list */
+	vimc_buf = list_first_entry_or_null(&vcap->buf_list,
+					    typeof(*vimc_buf), list);
+	if (!vimc_buf) {
+		spin_unlock(&vcap->qlock);
+		return ERR_PTR(-EAGAIN);
+	}
+
+	/* Remove this entry from the list */
+	list_del(&vimc_buf->list);
+
+	spin_unlock(&vcap->qlock);
+
+	/* Fill the buffer */
+	vimc_buf->vb2.vb2_buf.timestamp = ktime_get_ns();
+	vimc_buf->vb2.sequence = vcap->sequence++;
+	vimc_buf->vb2.field = vcap->format.field;
+
+	vbuf = vb2_plane_vaddr(&vimc_buf->vb2.vb2_buf, 0);
+
+	memcpy(vbuf, frame, vcap->format.sizeimage);
+
+	/* Set it as ready */
+	vb2_set_plane_payload(&vimc_buf->vb2.vb2_buf, 0,
+			      vcap->format.sizeimage);
+	vb2_buffer_done(&vimc_buf->vb2.vb2_buf, VB2_BUF_STATE_DONE);
+	return NULL;
+}
+
+static struct vimc_ent_device *vimc_cap_add(struct vimc_device *vimc,
+					    const char *vcfg_name)
+{
+	struct v4l2_device *v4l2_dev = &vimc->v4l2_dev;
+	const struct vimc_pix_map *vpix;
+	struct vimc_cap_device *vcap;
+	struct video_device *vdev;
+	struct vb2_queue *q;
+	int ret;
+
+	/* Allocate the vimc_cap_device struct */
+	vcap = kzalloc(sizeof(*vcap), GFP_KERNEL);
+	if (!vcap)
+		return ERR_PTR(-ENOMEM);
+
+	/* Initialize the media entity */
+	vcap->vdev.entity.name = vcfg_name;
+	vcap->vdev.entity.function = MEDIA_ENT_F_IO_V4L;
+	vcap->pad.flags = MEDIA_PAD_FL_SINK;
+	ret = media_entity_pads_init(&vcap->vdev.entity,
+				     1, &vcap->pad);
+	if (ret)
+		goto err_free_vcap;
+
+	/* Initialize the lock */
+	mutex_init(&vcap->lock);
+
+	/* Initialize the vb2 queue */
+	q = &vcap->queue;
+	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_USERPTR;
+	q->drv_priv = vcap;
+	q->buf_struct_size = sizeof(struct vimc_cap_buffer);
+	q->ops = &vimc_cap_qops;
+	q->mem_ops = &vb2_vmalloc_memops;
+	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+	q->min_buffers_needed = 2;
+	q->lock = &vcap->lock;
+
+	ret = vb2_queue_init(q);
+	if (ret) {
+		dev_err(vimc->mdev.dev, "%s: vb2 queue init failed (err=%d)\n",
+			vcfg_name, ret);
+		goto err_clean_m_ent;
+	}
+
+	/* Initialize buffer list and its lock */
+	INIT_LIST_HEAD(&vcap->buf_list);
+	spin_lock_init(&vcap->qlock);
+
+	/* Set default frame format */
+	vcap->format = fmt_default;
+	vpix = vimc_pix_map_by_pixelformat(vcap->format.pixelformat);
+	vcap->format.bytesperline = vcap->format.width * vpix->bpp;
+	vcap->format.sizeimage = vcap->format.bytesperline *
+				 vcap->format.height;
+
+	/* Fill the vimc_ent_device struct */
+	vcap->ved.ent = &vcap->vdev.entity;
+	vcap->ved.process_frame = vimc_cap_process_frame;
+	vcap->ved.vdev_get_format = vimc_cap_get_format;
+	vcap->ved.dev = vimc->mdev.dev;
+
+	/* Initialize the video_device struct */
+	vdev = &vcap->vdev;
+	vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
+	vdev->entity.ops = &vimc_cap_mops;
+	vdev->release = video_device_release_empty;
+	vdev->fops = &vimc_cap_fops;
+	vdev->ioctl_ops = &vimc_cap_ioctl_ops;
+	vdev->lock = &vcap->lock;
+	vdev->queue = q;
+	vdev->v4l2_dev = v4l2_dev;
+	vdev->vfl_dir = VFL_DIR_RX;
+	strscpy(vdev->name, vcfg_name, sizeof(vdev->name));
+	video_set_drvdata(vdev, &vcap->ved);
+
+	/* Register the video_device with the v4l2 and the media framework */
+	ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
+	if (ret) {
+		dev_err(vimc->mdev.dev, "%s: video register failed (err=%d)\n",
+			vcap->vdev.name, ret);
+		goto err_release_queue;
+	}
+
+	return &vcap->ved;
+
+err_release_queue:
+	vb2_queue_release(q);
+err_clean_m_ent:
+	media_entity_cleanup(&vcap->vdev.entity);
+err_free_vcap:
+	kfree(vcap);
+
+	return ERR_PTR(ret);
+}
+
+struct vimc_ent_type vimc_cap_type = {
+	.add = vimc_cap_add,
+	.unregister = vimc_cap_unregister,
+	.release = vimc_cap_release
+};
diff --git a/drivers/media/test-drivers/vimc/vimc-common.c b/drivers/media/test-drivers/vimc/vimc-common.c
new file mode 100644
index 000000000000..c95c17c048f2
--- /dev/null
+++ b/drivers/media/test-drivers/vimc/vimc-common.c
@@ -0,0 +1,369 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * vimc-common.c Virtual Media Controller Driver
+ *
+ * Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+
+#include "vimc-common.h"
+
+/*
+ * NOTE: non-bayer formats need to come first (necessary for enum_mbus_code
+ * in the scaler)
+ */
+static const struct vimc_pix_map vimc_pix_map_list[] = {
+	/* TODO: add all missing formats */
+
+	/* RGB formats */
+	{
+		.code = MEDIA_BUS_FMT_BGR888_1X24,
+		.pixelformat = V4L2_PIX_FMT_BGR24,
+		.bpp = 3,
+		.bayer = false,
+	},
+	{
+		.code = MEDIA_BUS_FMT_RGB888_1X24,
+		.pixelformat = V4L2_PIX_FMT_RGB24,
+		.bpp = 3,
+		.bayer = false,
+	},
+	{
+		.code = MEDIA_BUS_FMT_ARGB8888_1X32,
+		.pixelformat = V4L2_PIX_FMT_ARGB32,
+		.bpp = 4,
+		.bayer = false,
+	},
+
+	/* Bayer formats */
+	{
+		.code = MEDIA_BUS_FMT_SBGGR8_1X8,
+		.pixelformat = V4L2_PIX_FMT_SBGGR8,
+		.bpp = 1,
+		.bayer = true,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGBRG8_1X8,
+		.pixelformat = V4L2_PIX_FMT_SGBRG8,
+		.bpp = 1,
+		.bayer = true,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGRBG8_1X8,
+		.pixelformat = V4L2_PIX_FMT_SGRBG8,
+		.bpp = 1,
+		.bayer = true,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SRGGB8_1X8,
+		.pixelformat = V4L2_PIX_FMT_SRGGB8,
+		.bpp = 1,
+		.bayer = true,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SBGGR10_1X10,
+		.pixelformat = V4L2_PIX_FMT_SBGGR10,
+		.bpp = 2,
+		.bayer = true,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGBRG10_1X10,
+		.pixelformat = V4L2_PIX_FMT_SGBRG10,
+		.bpp = 2,
+		.bayer = true,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGRBG10_1X10,
+		.pixelformat = V4L2_PIX_FMT_SGRBG10,
+		.bpp = 2,
+		.bayer = true,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SRGGB10_1X10,
+		.pixelformat = V4L2_PIX_FMT_SRGGB10,
+		.bpp = 2,
+		.bayer = true,
+	},
+
+	/* 10bit raw bayer a-law compressed to 8 bits */
+	{
+		.code = MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8,
+		.pixelformat = V4L2_PIX_FMT_SBGGR10ALAW8,
+		.bpp = 1,
+		.bayer = true,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8,
+		.pixelformat = V4L2_PIX_FMT_SGBRG10ALAW8,
+		.bpp = 1,
+		.bayer = true,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8,
+		.pixelformat = V4L2_PIX_FMT_SGRBG10ALAW8,
+		.bpp = 1,
+		.bayer = true,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8,
+		.pixelformat = V4L2_PIX_FMT_SRGGB10ALAW8,
+		.bpp = 1,
+		.bayer = true,
+	},
+
+	/* 10bit raw bayer DPCM compressed to 8 bits */
+	{
+		.code = MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8,
+		.pixelformat = V4L2_PIX_FMT_SBGGR10DPCM8,
+		.bpp = 1,
+		.bayer = true,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8,
+		.pixelformat = V4L2_PIX_FMT_SGBRG10DPCM8,
+		.bpp = 1,
+		.bayer = true,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8,
+		.pixelformat = V4L2_PIX_FMT_SGRBG10DPCM8,
+		.bpp = 1,
+		.bayer = true,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8,
+		.pixelformat = V4L2_PIX_FMT_SRGGB10DPCM8,
+		.bpp = 1,
+		.bayer = true,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SBGGR12_1X12,
+		.pixelformat = V4L2_PIX_FMT_SBGGR12,
+		.bpp = 2,
+		.bayer = true,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGBRG12_1X12,
+		.pixelformat = V4L2_PIX_FMT_SGBRG12,
+		.bpp = 2,
+		.bayer = true,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGRBG12_1X12,
+		.pixelformat = V4L2_PIX_FMT_SGRBG12,
+		.bpp = 2,
+		.bayer = true,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SRGGB12_1X12,
+		.pixelformat = V4L2_PIX_FMT_SRGGB12,
+		.bpp = 2,
+		.bayer = true,
+	},
+};
+
+bool vimc_is_source(struct media_entity *ent)
+{
+	unsigned int i;
+
+	for (i = 0; i < ent->num_pads; i++)
+		if (ent->pads[i].flags & MEDIA_PAD_FL_SINK)
+			return false;
+	return true;
+}
+
+const struct vimc_pix_map *vimc_pix_map_by_index(unsigned int i)
+{
+	if (i >= ARRAY_SIZE(vimc_pix_map_list))
+		return NULL;
+
+	return &vimc_pix_map_list[i];
+}
+
+const struct vimc_pix_map *vimc_pix_map_by_code(u32 code)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(vimc_pix_map_list); i++) {
+		if (vimc_pix_map_list[i].code == code)
+			return &vimc_pix_map_list[i];
+	}
+	return NULL;
+}
+
+const struct vimc_pix_map *vimc_pix_map_by_pixelformat(u32 pixelformat)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(vimc_pix_map_list); i++) {
+		if (vimc_pix_map_list[i].pixelformat == pixelformat)
+			return &vimc_pix_map_list[i];
+	}
+	return NULL;
+}
+
+static int vimc_get_pix_format(struct media_pad *pad,
+			       struct v4l2_pix_format *fmt)
+{
+	if (is_media_entity_v4l2_subdev(pad->entity)) {
+		struct v4l2_subdev *sd =
+			media_entity_to_v4l2_subdev(pad->entity);
+		struct v4l2_subdev_format sd_fmt;
+		const struct vimc_pix_map *pix_map;
+		int ret;
+
+		sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+		sd_fmt.pad = pad->index;
+
+		ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &sd_fmt);
+		if (ret)
+			return ret;
+
+		v4l2_fill_pix_format(fmt, &sd_fmt.format);
+		pix_map = vimc_pix_map_by_code(sd_fmt.format.code);
+		fmt->pixelformat = pix_map->pixelformat;
+	} else if (is_media_entity_v4l2_video_device(pad->entity)) {
+		struct video_device *vdev = container_of(pad->entity,
+							 struct video_device,
+							 entity);
+		struct vimc_ent_device *ved = video_get_drvdata(vdev);
+
+		if (!ved->vdev_get_format)
+			return -ENOIOCTLCMD;
+
+		ved->vdev_get_format(ved, fmt);
+	} else {
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int vimc_vdev_link_validate(struct media_link *link)
+{
+	struct v4l2_pix_format source_fmt, sink_fmt;
+	int ret;
+
+	ret = vimc_get_pix_format(link->source, &source_fmt);
+	if (ret)
+		return ret;
+
+	ret = vimc_get_pix_format(link->sink, &sink_fmt);
+	if (ret)
+		return ret;
+
+	pr_info("vimc link validate: "
+		"%s:src:%dx%d (0x%x, %d, %d, %d, %d) "
+		"%s:snk:%dx%d (0x%x, %d, %d, %d, %d)\n",
+		/* src */
+		link->source->entity->name,
+		source_fmt.width, source_fmt.height,
+		source_fmt.pixelformat, source_fmt.colorspace,
+		source_fmt.quantization, source_fmt.xfer_func,
+		source_fmt.ycbcr_enc,
+		/* sink */
+		link->sink->entity->name,
+		sink_fmt.width, sink_fmt.height,
+		sink_fmt.pixelformat, sink_fmt.colorspace,
+		sink_fmt.quantization, sink_fmt.xfer_func,
+		sink_fmt.ycbcr_enc);
+
+	/* The width, height and pixelformat must match. */
+	if (source_fmt.width != sink_fmt.width ||
+	    source_fmt.height != sink_fmt.height ||
+	    source_fmt.pixelformat != sink_fmt.pixelformat)
+		return -EPIPE;
+
+	/*
+	 * The field order must match, or the sink field order must be NONE
+	 * to support interlaced hardware connected to bridges that support
+	 * progressive formats only.
+	 */
+	if (source_fmt.field != sink_fmt.field &&
+	    sink_fmt.field != V4L2_FIELD_NONE)
+		return -EPIPE;
+
+	/*
+	 * If colorspace is DEFAULT, then assume all the colorimetry is also
+	 * DEFAULT, return 0 to skip comparing the other colorimetry parameters
+	 */
+	if (source_fmt.colorspace == V4L2_COLORSPACE_DEFAULT ||
+	    sink_fmt.colorspace == V4L2_COLORSPACE_DEFAULT)
+		return 0;
+
+	/* Colorspace must match. */
+	if (source_fmt.colorspace != sink_fmt.colorspace)
+		return -EPIPE;
+
+	/* Colorimetry must match if they are not set to DEFAULT */
+	if (source_fmt.ycbcr_enc != V4L2_YCBCR_ENC_DEFAULT &&
+	    sink_fmt.ycbcr_enc != V4L2_YCBCR_ENC_DEFAULT &&
+	    source_fmt.ycbcr_enc != sink_fmt.ycbcr_enc)
+		return -EPIPE;
+
+	if (source_fmt.quantization != V4L2_QUANTIZATION_DEFAULT &&
+	    sink_fmt.quantization != V4L2_QUANTIZATION_DEFAULT &&
+	    source_fmt.quantization != sink_fmt.quantization)
+		return -EPIPE;
+
+	if (source_fmt.xfer_func != V4L2_XFER_FUNC_DEFAULT &&
+	    sink_fmt.xfer_func != V4L2_XFER_FUNC_DEFAULT &&
+	    source_fmt.xfer_func != sink_fmt.xfer_func)
+		return -EPIPE;
+
+	return 0;
+}
+
+static const struct media_entity_operations vimc_ent_sd_mops = {
+	.link_validate = v4l2_subdev_link_validate,
+};
+
+int vimc_ent_sd_register(struct vimc_ent_device *ved,
+			 struct v4l2_subdev *sd,
+			 struct v4l2_device *v4l2_dev,
+			 const char *const name,
+			 u32 function,
+			 u16 num_pads,
+			 struct media_pad *pads,
+			 const struct v4l2_subdev_ops *sd_ops)
+{
+	int ret;
+
+	/* Fill the vimc_ent_device struct */
+	ved->ent = &sd->entity;
+
+	/* Initialize the subdev */
+	v4l2_subdev_init(sd, sd_ops);
+	sd->entity.function = function;
+	sd->entity.ops = &vimc_ent_sd_mops;
+	sd->owner = THIS_MODULE;
+	strscpy(sd->name, name, sizeof(sd->name));
+	v4l2_set_subdevdata(sd, ved);
+
+	/* Expose this subdev to user space */
+	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	if (sd->ctrl_handler)
+		sd->flags |= V4L2_SUBDEV_FL_HAS_EVENTS;
+
+	/* Initialize the media entity */
+	ret = media_entity_pads_init(&sd->entity, num_pads, pads);
+	if (ret)
+		return ret;
+
+	/* Register the subdev with the v4l2 and the media framework */
+	ret = v4l2_device_register_subdev(v4l2_dev, sd);
+	if (ret) {
+		dev_err(v4l2_dev->dev,
+			"%s: subdev register failed (err=%d)\n",
+			name, ret);
+		goto err_clean_m_ent;
+	}
+
+	return 0;
+
+err_clean_m_ent:
+	media_entity_cleanup(&sd->entity);
+	return ret;
+}
diff --git a/drivers/media/test-drivers/vimc/vimc-common.h b/drivers/media/test-drivers/vimc/vimc-common.h
new file mode 100644
index 000000000000..487bd020f85c
--- /dev/null
+++ b/drivers/media/test-drivers/vimc/vimc-common.h
@@ -0,0 +1,221 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * vimc-common.h Virtual Media Controller Driver
+ *
+ * Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>
+ */
+
+#ifndef _VIMC_COMMON_H_
+#define _VIMC_COMMON_H_
+
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <media/media-device.h>
+#include <media/v4l2-device.h>
+
+#define VIMC_PDEV_NAME "vimc"
+
+/* 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_CID_MEAN_WIN_SIZE		(VIMC_CID_VIMC_BASE + 1)
+
+#define VIMC_FRAME_MAX_WIDTH 4096
+#define VIMC_FRAME_MAX_HEIGHT 2160
+#define VIMC_FRAME_MIN_WIDTH 16
+#define VIMC_FRAME_MIN_HEIGHT 16
+
+#define VIMC_FRAME_INDEX(lin, col, width, bpp) ((lin * width + col) * bpp)
+
+/* Source and sink pad checks */
+#define VIMC_IS_SRC(pad)	(pad)
+#define VIMC_IS_SINK(pad)	(!(pad))
+
+/**
+ * vimc_colorimetry_clamp - Adjust colorimetry parameters
+ *
+ * @fmt:		the pointer to struct v4l2_pix_format or
+ *			struct v4l2_mbus_framefmt
+ *
+ * Entities must check if colorimetry given by the userspace is valid, if not
+ * then set them as DEFAULT
+ */
+#define vimc_colorimetry_clamp(fmt)					\
+do {									\
+	if ((fmt)->colorspace == V4L2_COLORSPACE_DEFAULT		\
+	    || (fmt)->colorspace > V4L2_COLORSPACE_DCI_P3) {		\
+		(fmt)->colorspace = V4L2_COLORSPACE_DEFAULT;		\
+		(fmt)->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;		\
+		(fmt)->quantization = V4L2_QUANTIZATION_DEFAULT;	\
+		(fmt)->xfer_func = V4L2_XFER_FUNC_DEFAULT;		\
+	}								\
+	if ((fmt)->ycbcr_enc > V4L2_YCBCR_ENC_SMPTE240M)		\
+		(fmt)->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;		\
+	if ((fmt)->quantization > V4L2_QUANTIZATION_LIM_RANGE)		\
+		(fmt)->quantization = V4L2_QUANTIZATION_DEFAULT;	\
+	if ((fmt)->xfer_func > V4L2_XFER_FUNC_SMPTE2084)		\
+		(fmt)->xfer_func = V4L2_XFER_FUNC_DEFAULT;		\
+} while (0)
+
+/**
+ * struct vimc_pix_map - maps media bus code with v4l2 pixel format
+ *
+ * @code:		media bus format code defined by MEDIA_BUS_FMT_* macros
+ * @bpp:		number of bytes each pixel occupies
+ * @pixelformat:	pixel format defined by V4L2_PIX_FMT_* macros
+ * @bayer:		true if this is a bayer format
+ *
+ * Struct which matches the MEDIA_BUS_FMT_* codes with the corresponding
+ * V4L2_PIX_FMT_* fourcc pixelformat and its bytes per pixel (bpp)
+ */
+struct vimc_pix_map {
+	unsigned int code;
+	unsigned int bpp;
+	u32 pixelformat;
+	bool bayer;
+};
+
+/**
+ * struct vimc_ent_device - core struct that represents an entity in the
+ * topology
+ *
+ * @dev:		a pointer of the device struct of the driver
+ * @ent:		the pointer to struct media_entity for the node
+ * @process_frame:	callback send a frame to that node
+ * @vdev_get_format:	callback that returns the current format a pad, used
+ *			only when is_media_entity_v4l2_video_device(ent) returns
+ *			true
+ *
+ * Each node of the topology must create a vimc_ent_device struct. Depending on
+ * the node it will be of an instance of v4l2_subdev or video_device struct
+ * where both contains a struct media_entity.
+ * Those structures should embedded the vimc_ent_device struct through
+ * v4l2_set_subdevdata() and video_set_drvdata() respectively, allowing the
+ * vimc_ent_device struct to be retrieved from the corresponding struct
+ * media_entity
+ */
+struct vimc_ent_device {
+	struct device *dev;
+	struct media_entity *ent;
+	void * (*process_frame)(struct vimc_ent_device *ved,
+				const void *frame);
+	void (*vdev_get_format)(struct vimc_ent_device *ved,
+			      struct v4l2_pix_format *fmt);
+};
+
+/**
+ * struct vimc_device - main device for vimc driver
+ *
+ * @pipe_cfg:	pointer to the vimc pipeline configuration structure
+ * @ent_devs:	array of vimc_ent_device pointers
+ * @mdev:	the associated media_device parent
+ * @v4l2_dev:	Internal v4l2 parent device
+ */
+struct vimc_device {
+	const struct vimc_pipeline_config *pipe_cfg;
+	struct vimc_ent_device **ent_devs;
+	struct media_device mdev;
+	struct v4l2_device v4l2_dev;
+};
+
+/**
+ * struct vimc_ent_type		Structure for the callbacks of the entity types
+ *
+ *
+ * @add:			initializes and registers
+ *				vimc entity - called from vimc-core
+ * @unregister:			unregisters vimc entity - called from vimc-core
+ * @release:			releases vimc entity - called from the v4l2_dev
+ *				release callback
+ */
+struct vimc_ent_type {
+	struct vimc_ent_device *(*add)(struct vimc_device *vimc,
+				       const char *vcfg_name);
+	void (*unregister)(struct vimc_ent_device *ved);
+	void (*release)(struct vimc_ent_device *ved);
+};
+
+/**
+ * struct vimc_ent_config	Structure which describes individual
+ *				configuration for each entity
+ *
+ * @name:			entity name
+ * @type:			contain the callbacks of this entity type
+ *
+ */
+struct vimc_ent_config {
+	const char *name;
+	struct vimc_ent_type *type;
+};
+
+/**
+ * vimc_is_source - returns true if the entity has only source pads
+ *
+ * @ent: pointer to &struct media_entity
+ *
+ */
+bool vimc_is_source(struct media_entity *ent);
+
+extern struct vimc_ent_type vimc_sen_type;
+extern struct vimc_ent_type vimc_deb_type;
+extern struct vimc_ent_type vimc_sca_type;
+extern struct vimc_ent_type vimc_cap_type;
+
+/**
+ * vimc_pix_map_by_index - get vimc_pix_map struct by its index
+ *
+ * @i:			index of the vimc_pix_map struct in vimc_pix_map_list
+ */
+const struct vimc_pix_map *vimc_pix_map_by_index(unsigned int i);
+
+/**
+ * vimc_pix_map_by_code - get vimc_pix_map struct by media bus code
+ *
+ * @code:		media bus format code defined by MEDIA_BUS_FMT_* macros
+ */
+const struct vimc_pix_map *vimc_pix_map_by_code(u32 code);
+
+/**
+ * vimc_pix_map_by_pixelformat - get vimc_pix_map struct by v4l2 pixel format
+ *
+ * @pixelformat:	pixel format defined by V4L2_PIX_FMT_* macros
+ */
+const struct vimc_pix_map *vimc_pix_map_by_pixelformat(u32 pixelformat);
+
+/**
+ * vimc_ent_sd_register - initialize and register a subdev node
+ *
+ * @ved:	the vimc_ent_device struct to be initialize
+ * @sd:		the v4l2_subdev struct to be initialize and registered
+ * @v4l2_dev:	the v4l2 device to register the v4l2_subdev
+ * @name:	name of the sub-device. Please notice that the name must be
+ *		unique.
+ * @function:	media entity function defined by MEDIA_ENT_F_* macros
+ * @num_pads:	number of pads to initialize
+ * @pads:	the array of pads of the entity, the caller should set the
+ *		flags of the pads
+ * @sd_ops:	pointer to &struct v4l2_subdev_ops.
+ *
+ * Helper function initialize and register the struct vimc_ent_device and struct
+ * v4l2_subdev which represents a subdev node in the topology
+ */
+int vimc_ent_sd_register(struct vimc_ent_device *ved,
+			 struct v4l2_subdev *sd,
+			 struct v4l2_device *v4l2_dev,
+			 const char *const name,
+			 u32 function,
+			 u16 num_pads,
+			 struct media_pad *pads,
+			 const struct v4l2_subdev_ops *sd_ops);
+
+/**
+ * vimc_vdev_link_validate - validates a media link
+ *
+ * @link: pointer to &struct media_link
+ *
+ * This function calls validates if a media link is valid for streaming.
+ */
+int vimc_vdev_link_validate(struct media_link *link);
+
+#endif
diff --git a/drivers/media/test-drivers/vimc/vimc-core.c b/drivers/media/test-drivers/vimc/vimc-core.c
new file mode 100644
index 000000000000..11210aaa2551
--- /dev/null
+++ b/drivers/media/test-drivers/vimc/vimc-core.c
@@ -0,0 +1,369 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * vimc-core.c Virtual Media Controller Driver
+ *
+ * Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <media/media-device.h>
+#include <media/v4l2-device.h>
+
+#include "vimc-common.h"
+
+#define VIMC_MDEV_MODEL_NAME "VIMC MDEV"
+
+#define VIMC_ENT_LINK(src, srcpad, sink, sinkpad, link_flags) {	\
+	.src_ent = src,						\
+	.src_pad = srcpad,					\
+	.sink_ent = sink,					\
+	.sink_pad = sinkpad,					\
+	.flags = link_flags,					\
+}
+
+/* Structure which describes links between entities */
+struct vimc_ent_link {
+	unsigned int src_ent;
+	u16 src_pad;
+	unsigned int sink_ent;
+	u16 sink_pad;
+	u32 flags;
+};
+
+/* Structure which describes the whole topology */
+struct vimc_pipeline_config {
+	const struct vimc_ent_config *ents;
+	size_t num_ents;
+	const struct vimc_ent_link *links;
+	size_t num_links;
+};
+
+/* --------------------------------------------------------------------------
+ * Topology Configuration
+ */
+
+static struct vimc_ent_config ent_config[] = {
+	{
+		.name = "Sensor A",
+		.type = &vimc_sen_type
+	},
+	{
+		.name = "Sensor B",
+		.type = &vimc_sen_type
+	},
+	{
+		.name = "Debayer A",
+		.type = &vimc_deb_type
+	},
+	{
+		.name = "Debayer B",
+		.type = &vimc_deb_type
+	},
+	{
+		.name = "Raw Capture 0",
+		.type = &vimc_cap_type
+	},
+	{
+		.name = "Raw Capture 1",
+		.type = &vimc_cap_type
+	},
+	{
+		/* TODO: change this to vimc-input when it is implemented */
+		.name = "RGB/YUV Input",
+		.type = &vimc_sen_type
+	},
+	{
+		.name = "Scaler",
+		.type = &vimc_sca_type
+	},
+	{
+		.name = "RGB/YUV Capture",
+		.type = &vimc_cap_type
+	},
+};
+
+static const struct vimc_ent_link ent_links[] = {
+	/* Link: Sensor A (Pad 0)->(Pad 0) Debayer A */
+	VIMC_ENT_LINK(0, 0, 2, 0, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE),
+	/* Link: Sensor A (Pad 0)->(Pad 0) Raw Capture 0 */
+	VIMC_ENT_LINK(0, 0, 4, 0, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE),
+	/* Link: Sensor B (Pad 0)->(Pad 0) Debayer B */
+	VIMC_ENT_LINK(1, 0, 3, 0, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE),
+	/* Link: Sensor B (Pad 0)->(Pad 0) Raw Capture 1 */
+	VIMC_ENT_LINK(1, 0, 5, 0, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE),
+	/* Link: Debayer A (Pad 1)->(Pad 0) Scaler */
+	VIMC_ENT_LINK(2, 1, 7, 0, MEDIA_LNK_FL_ENABLED),
+	/* Link: Debayer B (Pad 1)->(Pad 0) Scaler */
+	VIMC_ENT_LINK(3, 1, 7, 0, 0),
+	/* Link: RGB/YUV Input (Pad 0)->(Pad 0) Scaler */
+	VIMC_ENT_LINK(6, 0, 7, 0, 0),
+	/* Link: Scaler (Pad 1)->(Pad 0) RGB/YUV Capture */
+	VIMC_ENT_LINK(7, 1, 8, 0, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE),
+};
+
+static struct vimc_pipeline_config pipe_cfg = {
+	.ents		= ent_config,
+	.num_ents	= ARRAY_SIZE(ent_config),
+	.links		= ent_links,
+	.num_links	= ARRAY_SIZE(ent_links)
+};
+
+/* -------------------------------------------------------------------------- */
+
+static void vimc_rm_links(struct vimc_device *vimc)
+{
+	unsigned int i;
+
+	for (i = 0; i < vimc->pipe_cfg->num_ents; i++)
+		media_entity_remove_links(vimc->ent_devs[i]->ent);
+}
+
+static int vimc_create_links(struct vimc_device *vimc)
+{
+	unsigned int i;
+	int ret;
+
+	/* Initialize the links between entities */
+	for (i = 0; i < vimc->pipe_cfg->num_links; i++) {
+		const struct vimc_ent_link *link = &vimc->pipe_cfg->links[i];
+
+		struct vimc_ent_device *ved_src =
+			vimc->ent_devs[link->src_ent];
+		struct vimc_ent_device *ved_sink =
+			vimc->ent_devs[link->sink_ent];
+
+		ret = media_create_pad_link(ved_src->ent, link->src_pad,
+					    ved_sink->ent, link->sink_pad,
+					    link->flags);
+		if (ret)
+			goto err_rm_links;
+	}
+
+	return 0;
+
+err_rm_links:
+	vimc_rm_links(vimc);
+	return ret;
+}
+
+static void vimc_release_subdevs(struct vimc_device *vimc)
+{
+	unsigned int i;
+
+	for (i = 0; i < vimc->pipe_cfg->num_ents; i++)
+		if (vimc->ent_devs[i])
+			vimc->pipe_cfg->ents[i].type->release(vimc->ent_devs[i]);
+}
+
+static void vimc_unregister_subdevs(struct vimc_device *vimc)
+{
+	unsigned int i;
+
+	for (i = 0; i < vimc->pipe_cfg->num_ents; i++)
+		if (vimc->ent_devs[i] && vimc->pipe_cfg->ents[i].type->unregister)
+			vimc->pipe_cfg->ents[i].type->unregister(vimc->ent_devs[i]);
+}
+
+static int vimc_add_subdevs(struct vimc_device *vimc)
+{
+	unsigned int i;
+
+	for (i = 0; i < vimc->pipe_cfg->num_ents; i++) {
+		dev_dbg(vimc->mdev.dev, "new entity for %s\n",
+			vimc->pipe_cfg->ents[i].name);
+		vimc->ent_devs[i] = vimc->pipe_cfg->ents[i].type->add(vimc,
+					vimc->pipe_cfg->ents[i].name);
+		if (IS_ERR(vimc->ent_devs[i])) {
+			int err = PTR_ERR(vimc->ent_devs[i]);
+
+			dev_err(vimc->mdev.dev, "adding entity %s failed (%d)\n",
+				vimc->pipe_cfg->ents[i].name, err);
+			vimc->ent_devs[i] = NULL;
+			vimc_unregister_subdevs(vimc);
+			vimc_release_subdevs(vimc);
+			return err;
+		}
+	}
+	return 0;
+}
+
+static void vimc_v4l2_dev_release(struct v4l2_device *v4l2_dev)
+{
+	struct vimc_device *vimc =
+		container_of(v4l2_dev, struct vimc_device, v4l2_dev);
+
+	vimc_release_subdevs(vimc);
+	media_device_cleanup(&vimc->mdev);
+	kfree(vimc->ent_devs);
+	kfree(vimc);
+}
+
+static int vimc_register_devices(struct vimc_device *vimc)
+{
+	int ret;
+
+	/* Register the v4l2 struct */
+	ret = v4l2_device_register(vimc->mdev.dev, &vimc->v4l2_dev);
+	if (ret) {
+		dev_err(vimc->mdev.dev,
+			"v4l2 device register failed (err=%d)\n", ret);
+		return ret;
+	}
+	/* allocate ent_devs */
+	vimc->ent_devs = kcalloc(vimc->pipe_cfg->num_ents,
+				 sizeof(*vimc->ent_devs), GFP_KERNEL);
+	if (!vimc->ent_devs) {
+		ret = -ENOMEM;
+		goto err_v4l2_unregister;
+	}
+
+	/* Invoke entity config hooks to initialize and register subdevs */
+	ret = vimc_add_subdevs(vimc);
+	if (ret)
+		goto err_free_ent_devs;
+
+	/* Initialize links */
+	ret = vimc_create_links(vimc);
+	if (ret)
+		goto err_rm_subdevs;
+
+	/* Register the media device */
+	ret = media_device_register(&vimc->mdev);
+	if (ret) {
+		dev_err(vimc->mdev.dev,
+			"media device register failed (err=%d)\n", ret);
+		goto err_rm_subdevs;
+	}
+
+	/* Expose all subdev's nodes*/
+	ret = v4l2_device_register_subdev_nodes(&vimc->v4l2_dev);
+	if (ret) {
+		dev_err(vimc->mdev.dev,
+			"vimc subdev nodes registration failed (err=%d)\n",
+			ret);
+		goto err_mdev_unregister;
+	}
+
+	return 0;
+
+err_mdev_unregister:
+	media_device_unregister(&vimc->mdev);
+err_rm_subdevs:
+	vimc_unregister_subdevs(vimc);
+	vimc_release_subdevs(vimc);
+err_free_ent_devs:
+	kfree(vimc->ent_devs);
+err_v4l2_unregister:
+	v4l2_device_unregister(&vimc->v4l2_dev);
+
+	return ret;
+}
+
+static int vimc_probe(struct platform_device *pdev)
+{
+	struct vimc_device *vimc;
+	int ret;
+
+	dev_dbg(&pdev->dev, "probe");
+
+	vimc = kzalloc(sizeof(*vimc), GFP_KERNEL);
+	if (!vimc)
+		return -ENOMEM;
+
+	vimc->pipe_cfg = &pipe_cfg;
+
+	/* Link the media device within the v4l2_device */
+	vimc->v4l2_dev.mdev = &vimc->mdev;
+
+	/* Initialize media device */
+	strscpy(vimc->mdev.model, VIMC_MDEV_MODEL_NAME,
+		sizeof(vimc->mdev.model));
+	snprintf(vimc->mdev.bus_info, sizeof(vimc->mdev.bus_info),
+		 "platform:%s", VIMC_PDEV_NAME);
+	vimc->mdev.dev = &pdev->dev;
+	media_device_init(&vimc->mdev);
+
+	ret = vimc_register_devices(vimc);
+	if (ret) {
+		media_device_cleanup(&vimc->mdev);
+		kfree(vimc);
+		return ret;
+	}
+	/*
+	 * the release cb is set only after successful registration.
+	 * if the registration fails, we release directly from probe
+	 */
+
+	vimc->v4l2_dev.release = vimc_v4l2_dev_release;
+	platform_set_drvdata(pdev, vimc);
+	return 0;
+}
+
+static int vimc_remove(struct platform_device *pdev)
+{
+	struct vimc_device *vimc = platform_get_drvdata(pdev);
+
+	dev_dbg(&pdev->dev, "remove");
+
+	vimc_unregister_subdevs(vimc);
+	media_device_unregister(&vimc->mdev);
+	v4l2_device_unregister(&vimc->v4l2_dev);
+	v4l2_device_put(&vimc->v4l2_dev);
+
+	return 0;
+}
+
+static void vimc_dev_release(struct device *dev)
+{
+}
+
+static struct platform_device vimc_pdev = {
+	.name = VIMC_PDEV_NAME,
+	.dev.release = vimc_dev_release,
+};
+
+static struct platform_driver vimc_pdrv = {
+	.probe		= vimc_probe,
+	.remove		= vimc_remove,
+	.driver		= {
+		.name	= VIMC_PDEV_NAME,
+	},
+};
+
+static int __init vimc_init(void)
+{
+	int ret;
+
+	ret = platform_device_register(&vimc_pdev);
+	if (ret) {
+		dev_err(&vimc_pdev.dev,
+			"platform device registration failed (err=%d)\n", ret);
+		return ret;
+	}
+
+	ret = platform_driver_register(&vimc_pdrv);
+	if (ret) {
+		dev_err(&vimc_pdev.dev,
+			"platform driver registration failed (err=%d)\n", ret);
+		platform_driver_unregister(&vimc_pdrv);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void __exit vimc_exit(void)
+{
+	platform_driver_unregister(&vimc_pdrv);
+
+	platform_device_unregister(&vimc_pdev);
+}
+
+module_init(vimc_init);
+module_exit(vimc_exit);
+
+MODULE_DESCRIPTION("Virtual Media Controller Driver (VIMC)");
+MODULE_AUTHOR("Helen Fornazier <helen.fornazier@gmail.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/test-drivers/vimc/vimc-debayer.c b/drivers/media/test-drivers/vimc/vimc-debayer.c
new file mode 100644
index 000000000000..d10aee9f84c4
--- /dev/null
+++ b/drivers/media/test-drivers/vimc/vimc-debayer.c
@@ -0,0 +1,586 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * vimc-debayer.c Virtual Media Controller Driver
+ *
+ * Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>
+ */
+
+#include <linux/moduleparam.h>
+#include <linux/platform_device.h>
+#include <linux/vmalloc.h>
+#include <linux/v4l2-mediabus.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-subdev.h>
+
+#include "vimc-common.h"
+
+enum vimc_deb_rgb_colors {
+	VIMC_DEB_RED = 0,
+	VIMC_DEB_GREEN = 1,
+	VIMC_DEB_BLUE = 2,
+};
+
+struct vimc_deb_pix_map {
+	u32 code;
+	enum vimc_deb_rgb_colors order[2][2];
+};
+
+struct vimc_deb_device {
+	struct vimc_ent_device ved;
+	struct v4l2_subdev sd;
+	/* The active format */
+	struct v4l2_mbus_framefmt sink_fmt;
+	u32 src_code;
+	void (*set_rgb_src)(struct vimc_deb_device *vdeb, unsigned int lin,
+			    unsigned int col, unsigned int rgb[3]);
+	/* Values calculated when the stream starts */
+	u8 *src_frame;
+	const struct vimc_deb_pix_map *sink_pix_map;
+	unsigned int sink_bpp;
+	unsigned int mean_win_size;
+	struct v4l2_ctrl_handler hdl;
+	struct media_pad pads[2];
+};
+
+static const struct v4l2_mbus_framefmt sink_fmt_default = {
+	.width = 640,
+	.height = 480,
+	.code = MEDIA_BUS_FMT_SRGGB8_1X8,
+	.field = V4L2_FIELD_NONE,
+	.colorspace = V4L2_COLORSPACE_DEFAULT,
+};
+
+static const struct vimc_deb_pix_map vimc_deb_pix_map_list[] = {
+	{
+		.code = MEDIA_BUS_FMT_SBGGR8_1X8,
+		.order = { { VIMC_DEB_BLUE, VIMC_DEB_GREEN },
+			   { VIMC_DEB_GREEN, VIMC_DEB_RED } }
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGBRG8_1X8,
+		.order = { { VIMC_DEB_GREEN, VIMC_DEB_BLUE },
+			   { VIMC_DEB_RED, VIMC_DEB_GREEN } }
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGRBG8_1X8,
+		.order = { { VIMC_DEB_GREEN, VIMC_DEB_RED },
+			   { VIMC_DEB_BLUE, VIMC_DEB_GREEN } }
+	},
+	{
+		.code = MEDIA_BUS_FMT_SRGGB8_1X8,
+		.order = { { VIMC_DEB_RED, VIMC_DEB_GREEN },
+			   { VIMC_DEB_GREEN, VIMC_DEB_BLUE } }
+	},
+	{
+		.code = MEDIA_BUS_FMT_SBGGR10_1X10,
+		.order = { { VIMC_DEB_BLUE, VIMC_DEB_GREEN },
+			   { VIMC_DEB_GREEN, VIMC_DEB_RED } }
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGBRG10_1X10,
+		.order = { { VIMC_DEB_GREEN, VIMC_DEB_BLUE },
+			   { VIMC_DEB_RED, VIMC_DEB_GREEN } }
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGRBG10_1X10,
+		.order = { { VIMC_DEB_GREEN, VIMC_DEB_RED },
+			   { VIMC_DEB_BLUE, VIMC_DEB_GREEN } }
+	},
+	{
+		.code = MEDIA_BUS_FMT_SRGGB10_1X10,
+		.order = { { VIMC_DEB_RED, VIMC_DEB_GREEN },
+			   { VIMC_DEB_GREEN, VIMC_DEB_BLUE } }
+	},
+	{
+		.code = MEDIA_BUS_FMT_SBGGR12_1X12,
+		.order = { { VIMC_DEB_BLUE, VIMC_DEB_GREEN },
+			   { VIMC_DEB_GREEN, VIMC_DEB_RED } }
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGBRG12_1X12,
+		.order = { { VIMC_DEB_GREEN, VIMC_DEB_BLUE },
+			   { VIMC_DEB_RED, VIMC_DEB_GREEN } }
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGRBG12_1X12,
+		.order = { { VIMC_DEB_GREEN, VIMC_DEB_RED },
+			   { VIMC_DEB_BLUE, VIMC_DEB_GREEN } }
+	},
+	{
+		.code = MEDIA_BUS_FMT_SRGGB12_1X12,
+		.order = { { VIMC_DEB_RED, VIMC_DEB_GREEN },
+			   { VIMC_DEB_GREEN, VIMC_DEB_BLUE } }
+	},
+};
+
+static const struct vimc_deb_pix_map *vimc_deb_pix_map_by_code(u32 code)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(vimc_deb_pix_map_list); i++)
+		if (vimc_deb_pix_map_list[i].code == code)
+			return &vimc_deb_pix_map_list[i];
+
+	return NULL;
+}
+
+static int vimc_deb_init_cfg(struct v4l2_subdev *sd,
+			     struct v4l2_subdev_pad_config *cfg)
+{
+	struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd);
+	struct v4l2_mbus_framefmt *mf;
+	unsigned int i;
+
+	mf = v4l2_subdev_get_try_format(sd, cfg, 0);
+	*mf = sink_fmt_default;
+
+	for (i = 1; i < sd->entity.num_pads; i++) {
+		mf = v4l2_subdev_get_try_format(sd, cfg, i);
+		*mf = sink_fmt_default;
+		mf->code = vdeb->src_code;
+	}
+
+	return 0;
+}
+
+static int vimc_deb_enum_mbus_code(struct v4l2_subdev *sd,
+				   struct v4l2_subdev_pad_config *cfg,
+				   struct v4l2_subdev_mbus_code_enum *code)
+{
+	/* We only support one format for source pads */
+	if (VIMC_IS_SRC(code->pad)) {
+		struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd);
+
+		if (code->index)
+			return -EINVAL;
+
+		code->code = vdeb->src_code;
+	} else {
+		if (code->index >= ARRAY_SIZE(vimc_deb_pix_map_list))
+			return -EINVAL;
+
+		code->code = vimc_deb_pix_map_list[code->index].code;
+	}
+
+	return 0;
+}
+
+static int vimc_deb_enum_frame_size(struct v4l2_subdev *sd,
+				    struct v4l2_subdev_pad_config *cfg,
+				    struct v4l2_subdev_frame_size_enum *fse)
+{
+	struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd);
+
+	if (fse->index)
+		return -EINVAL;
+
+	if (VIMC_IS_SINK(fse->pad)) {
+		const struct vimc_deb_pix_map *vpix =
+			vimc_deb_pix_map_by_code(fse->code);
+
+		if (!vpix)
+			return -EINVAL;
+	} else if (fse->code != vdeb->src_code) {
+		return -EINVAL;
+	}
+
+	fse->min_width = VIMC_FRAME_MIN_WIDTH;
+	fse->max_width = VIMC_FRAME_MAX_WIDTH;
+	fse->min_height = VIMC_FRAME_MIN_HEIGHT;
+	fse->max_height = VIMC_FRAME_MAX_HEIGHT;
+
+	return 0;
+}
+
+static int vimc_deb_get_fmt(struct v4l2_subdev *sd,
+			    struct v4l2_subdev_pad_config *cfg,
+			    struct v4l2_subdev_format *fmt)
+{
+	struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd);
+
+	/* Get the current sink format */
+	fmt->format = fmt->which == V4L2_SUBDEV_FORMAT_TRY ?
+		      *v4l2_subdev_get_try_format(sd, cfg, 0) :
+		      vdeb->sink_fmt;
+
+	/* Set the right code for the source pad */
+	if (VIMC_IS_SRC(fmt->pad))
+		fmt->format.code = vdeb->src_code;
+
+	return 0;
+}
+
+static void vimc_deb_adjust_sink_fmt(struct v4l2_mbus_framefmt *fmt)
+{
+	const struct vimc_deb_pix_map *vpix;
+
+	/* Don't accept a code that is not on the debayer table */
+	vpix = vimc_deb_pix_map_by_code(fmt->code);
+	if (!vpix)
+		fmt->code = sink_fmt_default.code;
+
+	fmt->width = clamp_t(u32, fmt->width, VIMC_FRAME_MIN_WIDTH,
+			     VIMC_FRAME_MAX_WIDTH) & ~1;
+	fmt->height = clamp_t(u32, fmt->height, VIMC_FRAME_MIN_HEIGHT,
+			      VIMC_FRAME_MAX_HEIGHT) & ~1;
+
+	if (fmt->field == V4L2_FIELD_ANY)
+		fmt->field = sink_fmt_default.field;
+
+	vimc_colorimetry_clamp(fmt);
+}
+
+static int vimc_deb_set_fmt(struct v4l2_subdev *sd,
+			    struct v4l2_subdev_pad_config *cfg,
+			    struct v4l2_subdev_format *fmt)
+{
+	struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd);
+	struct v4l2_mbus_framefmt *sink_fmt;
+
+	if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
+		/* Do not change the format while stream is on */
+		if (vdeb->src_frame)
+			return -EBUSY;
+
+		sink_fmt = &vdeb->sink_fmt;
+	} else {
+		sink_fmt = v4l2_subdev_get_try_format(sd, cfg, 0);
+	}
+
+	/*
+	 * Do not change the format of the source pad,
+	 * it is propagated from the sink
+	 */
+	if (VIMC_IS_SRC(fmt->pad)) {
+		fmt->format = *sink_fmt;
+		/* TODO: Add support for other formats */
+		fmt->format.code = vdeb->src_code;
+	} else {
+		/* Set the new format in the sink pad */
+		vimc_deb_adjust_sink_fmt(&fmt->format);
+
+		dev_dbg(vdeb->ved.dev, "%s: sink format update: "
+			"old:%dx%d (0x%x, %d, %d, %d, %d) "
+			"new:%dx%d (0x%x, %d, %d, %d, %d)\n", vdeb->sd.name,
+			/* old */
+			sink_fmt->width, sink_fmt->height, sink_fmt->code,
+			sink_fmt->colorspace, sink_fmt->quantization,
+			sink_fmt->xfer_func, sink_fmt->ycbcr_enc,
+			/* new */
+			fmt->format.width, fmt->format.height, fmt->format.code,
+			fmt->format.colorspace,	fmt->format.quantization,
+			fmt->format.xfer_func, fmt->format.ycbcr_enc);
+
+		*sink_fmt = fmt->format;
+	}
+
+	return 0;
+}
+
+static const struct v4l2_subdev_pad_ops vimc_deb_pad_ops = {
+	.init_cfg		= vimc_deb_init_cfg,
+	.enum_mbus_code		= vimc_deb_enum_mbus_code,
+	.enum_frame_size	= vimc_deb_enum_frame_size,
+	.get_fmt		= vimc_deb_get_fmt,
+	.set_fmt		= vimc_deb_set_fmt,
+};
+
+static void vimc_deb_set_rgb_mbus_fmt_rgb888_1x24(struct vimc_deb_device *vdeb,
+						  unsigned int lin,
+						  unsigned int col,
+						  unsigned int rgb[3])
+{
+	unsigned int i, index;
+
+	index = VIMC_FRAME_INDEX(lin, col, vdeb->sink_fmt.width, 3);
+	for (i = 0; i < 3; i++)
+		vdeb->src_frame[index + i] = rgb[i];
+}
+
+static int vimc_deb_s_stream(struct v4l2_subdev *sd, int enable)
+{
+	struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd);
+
+	if (enable) {
+		const struct vimc_pix_map *vpix;
+		unsigned int frame_size;
+
+		if (vdeb->src_frame)
+			return 0;
+
+		/* Calculate the frame size of the source pad */
+		vpix = vimc_pix_map_by_code(vdeb->src_code);
+		frame_size = vdeb->sink_fmt.width * vdeb->sink_fmt.height *
+				vpix->bpp;
+
+		/* Save the bytes per pixel of the sink */
+		vpix = vimc_pix_map_by_code(vdeb->sink_fmt.code);
+		vdeb->sink_bpp = vpix->bpp;
+
+		/* Get the corresponding pixel map from the table */
+		vdeb->sink_pix_map =
+			vimc_deb_pix_map_by_code(vdeb->sink_fmt.code);
+
+		/*
+		 * Allocate the frame buffer. Use vmalloc to be able to
+		 * allocate a large amount of memory
+		 */
+		vdeb->src_frame = vmalloc(frame_size);
+		if (!vdeb->src_frame)
+			return -ENOMEM;
+
+	} else {
+		if (!vdeb->src_frame)
+			return 0;
+
+		vfree(vdeb->src_frame);
+		vdeb->src_frame = NULL;
+	}
+
+	return 0;
+}
+
+static const struct v4l2_subdev_core_ops vimc_deb_core_ops = {
+	.log_status = v4l2_ctrl_subdev_log_status,
+	.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
+	.unsubscribe_event = v4l2_event_subdev_unsubscribe,
+};
+
+static const struct v4l2_subdev_video_ops vimc_deb_video_ops = {
+	.s_stream = vimc_deb_s_stream,
+};
+
+static const struct v4l2_subdev_ops vimc_deb_ops = {
+	.core = &vimc_deb_core_ops,
+	.pad = &vimc_deb_pad_ops,
+	.video = &vimc_deb_video_ops,
+};
+
+static unsigned int vimc_deb_get_val(const u8 *bytes,
+				     const unsigned int n_bytes)
+{
+	unsigned int i;
+	unsigned int acc = 0;
+
+	for (i = 0; i < n_bytes; i++)
+		acc = acc + (bytes[i] << (8 * i));
+
+	return acc;
+}
+
+static void vimc_deb_calc_rgb_sink(struct vimc_deb_device *vdeb,
+				   const u8 *frame,
+				   const unsigned int lin,
+				   const unsigned int col,
+				   unsigned int rgb[3])
+{
+	unsigned int i, seek, wlin, wcol;
+	unsigned int n_rgb[3] = {0, 0, 0};
+
+	for (i = 0; i < 3; i++)
+		rgb[i] = 0;
+
+	/*
+	 * Calculate how many we need to subtract to get to the pixel in
+	 * the top left corner of the mean window (considering the current
+	 * pixel as the center)
+	 */
+	seek = vdeb->mean_win_size / 2;
+
+	/* Sum the values of the colors in the mean window */
+
+	dev_dbg(vdeb->ved.dev,
+		"deb: %s: --- Calc pixel %dx%d, window mean %d, seek %d ---\n",
+		vdeb->sd.name, lin, col, vdeb->sink_fmt.height, seek);
+
+	/*
+	 * Iterate through all the lines in the mean window, start
+	 * with zero if the pixel is outside the frame and don't pass
+	 * the height when the pixel is in the bottom border of the
+	 * frame
+	 */
+	for (wlin = seek > lin ? 0 : lin - seek;
+	     wlin < lin + seek + 1 && wlin < vdeb->sink_fmt.height;
+	     wlin++) {
+
+		/*
+		 * Iterate through all the columns in the mean window, start
+		 * with zero if the pixel is outside the frame and don't pass
+		 * the width when the pixel is in the right border of the
+		 * frame
+		 */
+		for (wcol = seek > col ? 0 : col - seek;
+		     wcol < col + seek + 1 && wcol < vdeb->sink_fmt.width;
+		     wcol++) {
+			enum vimc_deb_rgb_colors color;
+			unsigned int index;
+
+			/* Check which color this pixel is */
+			color = vdeb->sink_pix_map->order[wlin % 2][wcol % 2];
+
+			index = VIMC_FRAME_INDEX(wlin, wcol,
+						 vdeb->sink_fmt.width,
+						 vdeb->sink_bpp);
+
+			dev_dbg(vdeb->ved.dev,
+				"deb: %s: RGB CALC: frame index %d, win pos %dx%d, color %d\n",
+				vdeb->sd.name, index, wlin, wcol, color);
+
+			/* Get its value */
+			rgb[color] = rgb[color] +
+				vimc_deb_get_val(&frame[index], vdeb->sink_bpp);
+
+			/* Save how many values we already added */
+			n_rgb[color]++;
+
+			dev_dbg(vdeb->ved.dev, "deb: %s: RGB CALC: val %d, n %d\n",
+				vdeb->sd.name, rgb[color], n_rgb[color]);
+		}
+	}
+
+	/* Calculate the mean */
+	for (i = 0; i < 3; i++) {
+		dev_dbg(vdeb->ved.dev,
+			"deb: %s: PRE CALC: %dx%d Color %d, val %d, n %d\n",
+			vdeb->sd.name, lin, col, i, rgb[i], n_rgb[i]);
+
+		if (n_rgb[i])
+			rgb[i] = rgb[i] / n_rgb[i];
+
+		dev_dbg(vdeb->ved.dev,
+			"deb: %s: FINAL CALC: %dx%d Color %d, val %d\n",
+			vdeb->sd.name, lin, col, i, rgb[i]);
+	}
+}
+
+static void *vimc_deb_process_frame(struct vimc_ent_device *ved,
+				    const void *sink_frame)
+{
+	struct vimc_deb_device *vdeb = container_of(ved, struct vimc_deb_device,
+						    ved);
+	unsigned int rgb[3];
+	unsigned int i, j;
+
+	/* If the stream in this node is not active, just return */
+	if (!vdeb->src_frame)
+		return ERR_PTR(-EINVAL);
+
+	for (i = 0; i < vdeb->sink_fmt.height; i++)
+		for (j = 0; j < vdeb->sink_fmt.width; j++) {
+			vimc_deb_calc_rgb_sink(vdeb, sink_frame, i, j, rgb);
+			vdeb->set_rgb_src(vdeb, i, j, rgb);
+		}
+
+	return vdeb->src_frame;
+}
+
+static int vimc_deb_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct vimc_deb_device *vdeb =
+		container_of(ctrl->handler, struct vimc_deb_device, hdl);
+
+	switch (ctrl->id) {
+	case VIMC_CID_MEAN_WIN_SIZE:
+		vdeb->mean_win_size = ctrl->val;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static const struct v4l2_ctrl_ops vimc_deb_ctrl_ops = {
+	.s_ctrl = vimc_deb_s_ctrl,
+};
+
+static void vimc_deb_release(struct vimc_ent_device *ved)
+{
+	struct vimc_deb_device *vdeb =
+		container_of(ved, struct vimc_deb_device, ved);
+
+	v4l2_ctrl_handler_free(&vdeb->hdl);
+	media_entity_cleanup(vdeb->ved.ent);
+	kfree(vdeb);
+}
+
+static const struct v4l2_ctrl_config vimc_deb_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_deb_ctrl_mean_win_size = {
+	.ops = &vimc_deb_ctrl_ops,
+	.id = VIMC_CID_MEAN_WIN_SIZE,
+	.name = "Debayer Mean Window Size",
+	.type = V4L2_CTRL_TYPE_INTEGER,
+	.min = 1,
+	.max = 25,
+	.step = 2,
+	.def = 3,
+};
+
+static struct vimc_ent_device *vimc_deb_add(struct vimc_device *vimc,
+					    const char *vcfg_name)
+{
+	struct v4l2_device *v4l2_dev = &vimc->v4l2_dev;
+	struct vimc_deb_device *vdeb;
+	int ret;
+
+	/* Allocate the vdeb struct */
+	vdeb = kzalloc(sizeof(*vdeb), GFP_KERNEL);
+	if (!vdeb)
+		return ERR_PTR(-ENOMEM);
+
+	/* Create controls: */
+	v4l2_ctrl_handler_init(&vdeb->hdl, 2);
+	v4l2_ctrl_new_custom(&vdeb->hdl, &vimc_deb_ctrl_class, NULL);
+	v4l2_ctrl_new_custom(&vdeb->hdl, &vimc_deb_ctrl_mean_win_size, NULL);
+	vdeb->sd.ctrl_handler = &vdeb->hdl;
+	if (vdeb->hdl.error) {
+		ret = vdeb->hdl.error;
+		goto err_free_vdeb;
+	}
+
+	/* Initialize ved and sd */
+	vdeb->pads[0].flags = MEDIA_PAD_FL_SINK;
+	vdeb->pads[1].flags = MEDIA_PAD_FL_SOURCE;
+
+	ret = vimc_ent_sd_register(&vdeb->ved, &vdeb->sd, v4l2_dev,
+				   vcfg_name,
+				   MEDIA_ENT_F_PROC_VIDEO_PIXEL_ENC_CONV, 2,
+				   vdeb->pads, &vimc_deb_ops);
+	if (ret)
+		goto err_free_hdl;
+
+	vdeb->ved.process_frame = vimc_deb_process_frame;
+	vdeb->ved.dev = vimc->mdev.dev;
+	vdeb->mean_win_size = vimc_deb_ctrl_mean_win_size.def;
+
+	/* Initialize the frame format */
+	vdeb->sink_fmt = sink_fmt_default;
+	/*
+	 * TODO: Add support for more output formats, we only support
+	 * RGB888 for now
+	 * NOTE: the src format is always the same as the sink, except
+	 * for the code
+	 */
+	vdeb->src_code = MEDIA_BUS_FMT_RGB888_1X24;
+	vdeb->set_rgb_src = vimc_deb_set_rgb_mbus_fmt_rgb888_1x24;
+
+	return &vdeb->ved;
+
+err_free_hdl:
+	v4l2_ctrl_handler_free(&vdeb->hdl);
+err_free_vdeb:
+	kfree(vdeb);
+
+	return ERR_PTR(ret);
+}
+
+struct vimc_ent_type vimc_deb_type = {
+	.add = vimc_deb_add,
+	.release = vimc_deb_release
+};
diff --git a/drivers/media/test-drivers/vimc/vimc-scaler.c b/drivers/media/test-drivers/vimc/vimc-scaler.c
new file mode 100644
index 000000000000..465b906b7497
--- /dev/null
+++ b/drivers/media/test-drivers/vimc/vimc-scaler.c
@@ -0,0 +1,516 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * vimc-scaler.c Virtual Media Controller Driver
+ *
+ * Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>
+ */
+
+#include <linux/moduleparam.h>
+#include <linux/vmalloc.h>
+#include <linux/v4l2-mediabus.h>
+#include <media/v4l2-rect.h>
+#include <media/v4l2-subdev.h>
+
+#include "vimc-common.h"
+
+static unsigned int sca_mult = 3;
+module_param(sca_mult, uint, 0000);
+MODULE_PARM_DESC(sca_mult, " the image size multiplier");
+
+#define MAX_ZOOM	8
+
+#define VIMC_SCA_FMT_WIDTH_DEFAULT  640
+#define VIMC_SCA_FMT_HEIGHT_DEFAULT 480
+
+struct vimc_sca_device {
+	struct vimc_ent_device ved;
+	struct v4l2_subdev sd;
+	/* NOTE: the source fmt is the same as the sink
+	 * with the width and hight multiplied by mult
+	 */
+	struct v4l2_mbus_framefmt sink_fmt;
+	struct v4l2_rect crop_rect;
+	/* Values calculated when the stream starts */
+	u8 *src_frame;
+	unsigned int src_line_size;
+	unsigned int bpp;
+	struct media_pad pads[2];
+};
+
+static const struct v4l2_mbus_framefmt sink_fmt_default = {
+	.width = VIMC_SCA_FMT_WIDTH_DEFAULT,
+	.height = VIMC_SCA_FMT_HEIGHT_DEFAULT,
+	.code = MEDIA_BUS_FMT_RGB888_1X24,
+	.field = V4L2_FIELD_NONE,
+	.colorspace = V4L2_COLORSPACE_DEFAULT,
+};
+
+static const struct v4l2_rect crop_rect_default = {
+	.width = VIMC_SCA_FMT_WIDTH_DEFAULT,
+	.height = VIMC_SCA_FMT_HEIGHT_DEFAULT,
+	.top = 0,
+	.left = 0,
+};
+
+static const struct v4l2_rect crop_rect_min = {
+	.width = VIMC_FRAME_MIN_WIDTH,
+	.height = VIMC_FRAME_MIN_HEIGHT,
+	.top = 0,
+	.left = 0,
+};
+
+static struct v4l2_rect
+vimc_sca_get_crop_bound_sink(const struct v4l2_mbus_framefmt *sink_fmt)
+{
+	/* Get the crop bounds to clamp the crop rectangle correctly */
+	struct v4l2_rect r = {
+		.left = 0,
+		.top = 0,
+		.width = sink_fmt->width,
+		.height = sink_fmt->height,
+	};
+	return r;
+}
+
+static void vimc_sca_adjust_sink_crop(struct v4l2_rect *r,
+				      const struct v4l2_mbus_framefmt *sink_fmt)
+{
+	const struct v4l2_rect sink_rect =
+		vimc_sca_get_crop_bound_sink(sink_fmt);
+
+	/* Disallow rectangles smaller than the minimal one. */
+	v4l2_rect_set_min_size(r, &crop_rect_min);
+	v4l2_rect_map_inside(r, &sink_rect);
+}
+
+static int vimc_sca_init_cfg(struct v4l2_subdev *sd,
+			     struct v4l2_subdev_pad_config *cfg)
+{
+	struct v4l2_mbus_framefmt *mf;
+	struct v4l2_rect *r;
+	unsigned int i;
+
+	mf = v4l2_subdev_get_try_format(sd, cfg, 0);
+	*mf = sink_fmt_default;
+
+	r = v4l2_subdev_get_try_crop(sd, cfg, 0);
+	*r = crop_rect_default;
+
+	for (i = 1; i < sd->entity.num_pads; i++) {
+		mf = v4l2_subdev_get_try_format(sd, cfg, i);
+		*mf = sink_fmt_default;
+		mf->width = mf->width * sca_mult;
+		mf->height = mf->height * sca_mult;
+	}
+
+	return 0;
+}
+
+static int vimc_sca_enum_mbus_code(struct v4l2_subdev *sd,
+				   struct v4l2_subdev_pad_config *cfg,
+				   struct v4l2_subdev_mbus_code_enum *code)
+{
+	const struct vimc_pix_map *vpix = vimc_pix_map_by_index(code->index);
+
+	/* We don't support bayer format */
+	if (!vpix || vpix->bayer)
+		return -EINVAL;
+
+	code->code = vpix->code;
+
+	return 0;
+}
+
+static int vimc_sca_enum_frame_size(struct v4l2_subdev *sd,
+				    struct v4l2_subdev_pad_config *cfg,
+				    struct v4l2_subdev_frame_size_enum *fse)
+{
+	const struct vimc_pix_map *vpix;
+
+	if (fse->index)
+		return -EINVAL;
+
+	/* Only accept code in the pix map table in non bayer format */
+	vpix = vimc_pix_map_by_code(fse->code);
+	if (!vpix || vpix->bayer)
+		return -EINVAL;
+
+	fse->min_width = VIMC_FRAME_MIN_WIDTH;
+	fse->min_height = VIMC_FRAME_MIN_HEIGHT;
+
+	if (VIMC_IS_SINK(fse->pad)) {
+		fse->max_width = VIMC_FRAME_MAX_WIDTH;
+		fse->max_height = VIMC_FRAME_MAX_HEIGHT;
+	} else {
+		fse->max_width = VIMC_FRAME_MAX_WIDTH * MAX_ZOOM;
+		fse->max_height = VIMC_FRAME_MAX_HEIGHT * MAX_ZOOM;
+	}
+
+	return 0;
+}
+
+static int vimc_sca_get_fmt(struct v4l2_subdev *sd,
+			    struct v4l2_subdev_pad_config *cfg,
+			    struct v4l2_subdev_format *format)
+{
+	struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd);
+	struct v4l2_rect *crop_rect;
+
+	/* Get the current sink format */
+	if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
+		format->format = *v4l2_subdev_get_try_format(sd, cfg, 0);
+		crop_rect = v4l2_subdev_get_try_crop(sd, cfg, 0);
+	} else {
+		format->format = vsca->sink_fmt;
+		crop_rect = &vsca->crop_rect;
+	}
+
+	/* Scale the frame size for the source pad */
+	if (VIMC_IS_SRC(format->pad)) {
+		format->format.width = crop_rect->width * sca_mult;
+		format->format.height = crop_rect->height * sca_mult;
+	}
+
+	return 0;
+}
+
+static void vimc_sca_adjust_sink_fmt(struct v4l2_mbus_framefmt *fmt)
+{
+	const struct vimc_pix_map *vpix;
+
+	/* Only accept code in the pix map table in non bayer format */
+	vpix = vimc_pix_map_by_code(fmt->code);
+	if (!vpix || vpix->bayer)
+		fmt->code = sink_fmt_default.code;
+
+	fmt->width = clamp_t(u32, fmt->width, VIMC_FRAME_MIN_WIDTH,
+			     VIMC_FRAME_MAX_WIDTH) & ~1;
+	fmt->height = clamp_t(u32, fmt->height, VIMC_FRAME_MIN_HEIGHT,
+			      VIMC_FRAME_MAX_HEIGHT) & ~1;
+
+	if (fmt->field == V4L2_FIELD_ANY)
+		fmt->field = sink_fmt_default.field;
+
+	vimc_colorimetry_clamp(fmt);
+}
+
+static int vimc_sca_set_fmt(struct v4l2_subdev *sd,
+			    struct v4l2_subdev_pad_config *cfg,
+			    struct v4l2_subdev_format *fmt)
+{
+	struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd);
+	struct v4l2_mbus_framefmt *sink_fmt;
+	struct v4l2_rect *crop_rect;
+
+	if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
+		/* Do not change the format while stream is on */
+		if (vsca->src_frame)
+			return -EBUSY;
+
+		sink_fmt = &vsca->sink_fmt;
+		crop_rect = &vsca->crop_rect;
+	} else {
+		sink_fmt = v4l2_subdev_get_try_format(sd, cfg, 0);
+		crop_rect = v4l2_subdev_get_try_crop(sd, cfg, 0);
+	}
+
+	/*
+	 * Do not change the format of the source pad,
+	 * it is propagated from the sink
+	 */
+	if (VIMC_IS_SRC(fmt->pad)) {
+		fmt->format = *sink_fmt;
+		fmt->format.width = crop_rect->width * sca_mult;
+		fmt->format.height = crop_rect->height * sca_mult;
+	} else {
+		/* Set the new format in the sink pad */
+		vimc_sca_adjust_sink_fmt(&fmt->format);
+
+		dev_dbg(vsca->ved.dev, "%s: sink format update: "
+			"old:%dx%d (0x%x, %d, %d, %d, %d) "
+			"new:%dx%d (0x%x, %d, %d, %d, %d)\n", vsca->sd.name,
+			/* old */
+			sink_fmt->width, sink_fmt->height, sink_fmt->code,
+			sink_fmt->colorspace, sink_fmt->quantization,
+			sink_fmt->xfer_func, sink_fmt->ycbcr_enc,
+			/* new */
+			fmt->format.width, fmt->format.height, fmt->format.code,
+			fmt->format.colorspace,	fmt->format.quantization,
+			fmt->format.xfer_func, fmt->format.ycbcr_enc);
+
+		*sink_fmt = fmt->format;
+
+		/* Do the crop, but respect the current bounds */
+		vimc_sca_adjust_sink_crop(crop_rect, sink_fmt);
+	}
+
+	return 0;
+}
+
+static int vimc_sca_get_selection(struct v4l2_subdev *sd,
+				  struct v4l2_subdev_pad_config *cfg,
+				  struct v4l2_subdev_selection *sel)
+{
+	struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd);
+	struct v4l2_mbus_framefmt *sink_fmt;
+	struct v4l2_rect *crop_rect;
+
+	if (VIMC_IS_SRC(sel->pad))
+		return -EINVAL;
+
+	if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
+		sink_fmt = &vsca->sink_fmt;
+		crop_rect = &vsca->crop_rect;
+	} else {
+		sink_fmt = v4l2_subdev_get_try_format(sd, cfg, 0);
+		crop_rect = v4l2_subdev_get_try_crop(sd, cfg, 0);
+	}
+
+	switch (sel->target) {
+	case V4L2_SEL_TGT_CROP:
+		sel->r = *crop_rect;
+		break;
+	case V4L2_SEL_TGT_CROP_BOUNDS:
+		sel->r = vimc_sca_get_crop_bound_sink(sink_fmt);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int vimc_sca_set_selection(struct v4l2_subdev *sd,
+				  struct v4l2_subdev_pad_config *cfg,
+				  struct v4l2_subdev_selection *sel)
+{
+	struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd);
+	struct v4l2_mbus_framefmt *sink_fmt;
+	struct v4l2_rect *crop_rect;
+
+	if (VIMC_IS_SRC(sel->pad))
+		return -EINVAL;
+
+	if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
+		/* Do not change the format while stream is on */
+		if (vsca->src_frame)
+			return -EBUSY;
+
+		crop_rect = &vsca->crop_rect;
+		sink_fmt = &vsca->sink_fmt;
+	} else {
+		crop_rect = v4l2_subdev_get_try_crop(sd, cfg, 0);
+		sink_fmt = v4l2_subdev_get_try_format(sd, cfg, 0);
+	}
+
+	switch (sel->target) {
+	case V4L2_SEL_TGT_CROP:
+		/* Do the crop, but respect the current bounds */
+		vimc_sca_adjust_sink_crop(&sel->r, sink_fmt);
+		*crop_rect = sel->r;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct v4l2_subdev_pad_ops vimc_sca_pad_ops = {
+	.init_cfg		= vimc_sca_init_cfg,
+	.enum_mbus_code		= vimc_sca_enum_mbus_code,
+	.enum_frame_size	= vimc_sca_enum_frame_size,
+	.get_fmt		= vimc_sca_get_fmt,
+	.set_fmt		= vimc_sca_set_fmt,
+	.get_selection		= vimc_sca_get_selection,
+	.set_selection		= vimc_sca_set_selection,
+};
+
+static int vimc_sca_s_stream(struct v4l2_subdev *sd, int enable)
+{
+	struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd);
+
+	if (enable) {
+		const struct vimc_pix_map *vpix;
+		unsigned int frame_size;
+
+		if (vsca->src_frame)
+			return 0;
+
+		/* Save the bytes per pixel of the sink */
+		vpix = vimc_pix_map_by_code(vsca->sink_fmt.code);
+		vsca->bpp = vpix->bpp;
+
+		/* Calculate the width in bytes of the src frame */
+		vsca->src_line_size = vsca->crop_rect.width *
+				      sca_mult * vsca->bpp;
+
+		/* Calculate the frame size of the source pad */
+		frame_size = vsca->src_line_size * vsca->crop_rect.height *
+			     sca_mult;
+
+		/* Allocate the frame buffer. Use vmalloc to be able to
+		 * allocate a large amount of memory
+		 */
+		vsca->src_frame = vmalloc(frame_size);
+		if (!vsca->src_frame)
+			return -ENOMEM;
+
+	} else {
+		if (!vsca->src_frame)
+			return 0;
+
+		vfree(vsca->src_frame);
+		vsca->src_frame = NULL;
+	}
+
+	return 0;
+}
+
+static const struct v4l2_subdev_video_ops vimc_sca_video_ops = {
+	.s_stream = vimc_sca_s_stream,
+};
+
+static const struct v4l2_subdev_ops vimc_sca_ops = {
+	.pad = &vimc_sca_pad_ops,
+	.video = &vimc_sca_video_ops,
+};
+
+static void vimc_sca_fill_pix(u8 *const ptr,
+			      const u8 *const pixel,
+			      const unsigned int bpp)
+{
+	unsigned int i;
+
+	/* copy the pixel to the pointer */
+	for (i = 0; i < bpp; i++)
+		ptr[i] = pixel[i];
+}
+
+static void vimc_sca_scale_pix(const struct vimc_sca_device *const vsca,
+			       unsigned int lin, unsigned int col,
+			       const u8 *const sink_frame)
+{
+	const struct v4l2_rect crop_rect = vsca->crop_rect;
+	unsigned int i, j, index;
+	const u8 *pixel;
+
+	/* Point to the pixel value in position (lin, col) in the sink frame */
+	index = VIMC_FRAME_INDEX(lin, col,
+				 vsca->sink_fmt.width,
+				 vsca->bpp);
+	pixel = &sink_frame[index];
+
+	dev_dbg(vsca->ved.dev,
+		"sca: %s: --- scale_pix sink pos %dx%d, index %d ---\n",
+		vsca->sd.name, lin, col, index);
+
+	/* point to the place we are going to put the first pixel
+	 * in the scaled src frame
+	 */
+	lin -= crop_rect.top;
+	col -= crop_rect.left;
+	index = VIMC_FRAME_INDEX(lin * sca_mult, col * sca_mult,
+				 crop_rect.width * sca_mult, vsca->bpp);
+
+	dev_dbg(vsca->ved.dev, "sca: %s: scale_pix src pos %dx%d, index %d\n",
+		vsca->sd.name, lin * sca_mult, col * sca_mult, index);
+
+	/* Repeat this pixel mult times */
+	for (i = 0; i < sca_mult; i++) {
+		/* Iterate through each beginning of a
+		 * pixel repetition in a line
+		 */
+		for (j = 0; j < sca_mult * vsca->bpp; j += vsca->bpp) {
+			dev_dbg(vsca->ved.dev,
+				"sca: %s: sca: scale_pix src pos %d\n",
+				vsca->sd.name, index + j);
+
+			/* copy the pixel to the position index + j */
+			vimc_sca_fill_pix(&vsca->src_frame[index + j],
+					  pixel, vsca->bpp);
+		}
+
+		/* move the index to the next line */
+		index += vsca->src_line_size;
+	}
+}
+
+static void vimc_sca_fill_src_frame(const struct vimc_sca_device *const vsca,
+				    const u8 *const sink_frame)
+{
+	const struct v4l2_rect r = vsca->crop_rect;
+	unsigned int i, j;
+
+	/* Scale each pixel from the original sink frame */
+	/* TODO: implement scale down, only scale up is supported for now */
+	for (i = r.top; i < r.top + r.height; i++)
+		for (j = r.left; j < r.left + r.width; j++)
+			vimc_sca_scale_pix(vsca, i, j, sink_frame);
+}
+
+static void *vimc_sca_process_frame(struct vimc_ent_device *ved,
+				    const void *sink_frame)
+{
+	struct vimc_sca_device *vsca = container_of(ved, struct vimc_sca_device,
+						    ved);
+
+	/* If the stream in this node is not active, just return */
+	if (!vsca->src_frame)
+		return ERR_PTR(-EINVAL);
+
+	vimc_sca_fill_src_frame(vsca, sink_frame);
+
+	return vsca->src_frame;
+};
+
+static void vimc_sca_release(struct vimc_ent_device *ved)
+{
+	struct vimc_sca_device *vsca =
+		container_of(ved, struct vimc_sca_device, ved);
+
+	media_entity_cleanup(vsca->ved.ent);
+	kfree(vsca);
+}
+
+static struct vimc_ent_device *vimc_sca_add(struct vimc_device *vimc,
+					    const char *vcfg_name)
+{
+	struct v4l2_device *v4l2_dev = &vimc->v4l2_dev;
+	struct vimc_sca_device *vsca;
+	int ret;
+
+	/* Allocate the vsca struct */
+	vsca = kzalloc(sizeof(*vsca), GFP_KERNEL);
+	if (!vsca)
+		return ERR_PTR(-ENOMEM);
+
+	/* Initialize ved and sd */
+	vsca->pads[0].flags = MEDIA_PAD_FL_SINK;
+	vsca->pads[1].flags = MEDIA_PAD_FL_SOURCE;
+
+	ret = vimc_ent_sd_register(&vsca->ved, &vsca->sd, v4l2_dev,
+				   vcfg_name,
+				   MEDIA_ENT_F_PROC_VIDEO_SCALER, 2,
+				   vsca->pads, &vimc_sca_ops);
+	if (ret) {
+		kfree(vsca);
+		return ERR_PTR(ret);
+	}
+
+	vsca->ved.process_frame = vimc_sca_process_frame;
+	vsca->ved.dev = vimc->mdev.dev;
+
+	/* Initialize the frame format */
+	vsca->sink_fmt = sink_fmt_default;
+
+	/* Initialize the crop selection */
+	vsca->crop_rect = crop_rect_default;
+
+	return &vsca->ved;
+}
+
+struct vimc_ent_type vimc_sca_type = {
+	.add = vimc_sca_add,
+	.release = vimc_sca_release
+};
diff --git a/drivers/media/test-drivers/vimc/vimc-sensor.c b/drivers/media/test-drivers/vimc/vimc-sensor.c
new file mode 100644
index 000000000000..228120b3a6dd
--- /dev/null
+++ b/drivers/media/test-drivers/vimc/vimc-sensor.c
@@ -0,0 +1,381 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * vimc-sensor.c Virtual Media Controller Driver
+ *
+ * Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>
+ */
+
+#include <linux/v4l2-mediabus.h>
+#include <linux/vmalloc.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-subdev.h>
+#include <media/tpg/v4l2-tpg.h>
+
+#include "vimc-common.h"
+
+struct vimc_sen_device {
+	struct vimc_ent_device ved;
+	struct v4l2_subdev sd;
+	struct tpg_data tpg;
+	u8 *frame;
+	/* The active format */
+	struct v4l2_mbus_framefmt mbus_format;
+	struct v4l2_ctrl_handler hdl;
+	struct media_pad pad;
+};
+
+static const struct v4l2_mbus_framefmt fmt_default = {
+	.width = 640,
+	.height = 480,
+	.code = MEDIA_BUS_FMT_RGB888_1X24,
+	.field = V4L2_FIELD_NONE,
+	.colorspace = V4L2_COLORSPACE_DEFAULT,
+};
+
+static int vimc_sen_init_cfg(struct v4l2_subdev *sd,
+			     struct v4l2_subdev_pad_config *cfg)
+{
+	unsigned int i;
+
+	for (i = 0; i < sd->entity.num_pads; i++) {
+		struct v4l2_mbus_framefmt *mf;
+
+		mf = v4l2_subdev_get_try_format(sd, cfg, i);
+		*mf = fmt_default;
+	}
+
+	return 0;
+}
+
+static int vimc_sen_enum_mbus_code(struct v4l2_subdev *sd,
+				   struct v4l2_subdev_pad_config *cfg,
+				   struct v4l2_subdev_mbus_code_enum *code)
+{
+	const struct vimc_pix_map *vpix = vimc_pix_map_by_index(code->index);
+
+	if (!vpix)
+		return -EINVAL;
+
+	code->code = vpix->code;
+
+	return 0;
+}
+
+static int vimc_sen_enum_frame_size(struct v4l2_subdev *sd,
+				    struct v4l2_subdev_pad_config *cfg,
+				    struct v4l2_subdev_frame_size_enum *fse)
+{
+	const struct vimc_pix_map *vpix;
+
+	if (fse->index)
+		return -EINVAL;
+
+	/* Only accept code in the pix map table */
+	vpix = vimc_pix_map_by_code(fse->code);
+	if (!vpix)
+		return -EINVAL;
+
+	fse->min_width = VIMC_FRAME_MIN_WIDTH;
+	fse->max_width = VIMC_FRAME_MAX_WIDTH;
+	fse->min_height = VIMC_FRAME_MIN_HEIGHT;
+	fse->max_height = VIMC_FRAME_MAX_HEIGHT;
+
+	return 0;
+}
+
+static int vimc_sen_get_fmt(struct v4l2_subdev *sd,
+			    struct v4l2_subdev_pad_config *cfg,
+			    struct v4l2_subdev_format *fmt)
+{
+	struct vimc_sen_device *vsen =
+				container_of(sd, struct vimc_sen_device, sd);
+
+	fmt->format = fmt->which == V4L2_SUBDEV_FORMAT_TRY ?
+		      *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) :
+		      vsen->mbus_format;
+
+	return 0;
+}
+
+static void vimc_sen_tpg_s_format(struct vimc_sen_device *vsen)
+{
+	const struct vimc_pix_map *vpix =
+				vimc_pix_map_by_code(vsen->mbus_format.code);
+
+	tpg_reset_source(&vsen->tpg, vsen->mbus_format.width,
+			 vsen->mbus_format.height, vsen->mbus_format.field);
+	tpg_s_bytesperline(&vsen->tpg, 0, vsen->mbus_format.width * vpix->bpp);
+	tpg_s_buf_height(&vsen->tpg, vsen->mbus_format.height);
+	tpg_s_fourcc(&vsen->tpg, vpix->pixelformat);
+	/* TODO: add support for V4L2_FIELD_ALTERNATE */
+	tpg_s_field(&vsen->tpg, vsen->mbus_format.field, false);
+	tpg_s_colorspace(&vsen->tpg, vsen->mbus_format.colorspace);
+	tpg_s_ycbcr_enc(&vsen->tpg, vsen->mbus_format.ycbcr_enc);
+	tpg_s_quantization(&vsen->tpg, vsen->mbus_format.quantization);
+	tpg_s_xfer_func(&vsen->tpg, vsen->mbus_format.xfer_func);
+}
+
+static void vimc_sen_adjust_fmt(struct v4l2_mbus_framefmt *fmt)
+{
+	const struct vimc_pix_map *vpix;
+
+	/* Only accept code in the pix map table */
+	vpix = vimc_pix_map_by_code(fmt->code);
+	if (!vpix)
+		fmt->code = fmt_default.code;
+
+	fmt->width = clamp_t(u32, fmt->width, VIMC_FRAME_MIN_WIDTH,
+			     VIMC_FRAME_MAX_WIDTH) & ~1;
+	fmt->height = clamp_t(u32, fmt->height, VIMC_FRAME_MIN_HEIGHT,
+			      VIMC_FRAME_MAX_HEIGHT) & ~1;
+
+	/* TODO: add support for V4L2_FIELD_ALTERNATE */
+	if (fmt->field == V4L2_FIELD_ANY || fmt->field == V4L2_FIELD_ALTERNATE)
+		fmt->field = fmt_default.field;
+
+	vimc_colorimetry_clamp(fmt);
+}
+
+static int vimc_sen_set_fmt(struct v4l2_subdev *sd,
+			    struct v4l2_subdev_pad_config *cfg,
+			    struct v4l2_subdev_format *fmt)
+{
+	struct vimc_sen_device *vsen = v4l2_get_subdevdata(sd);
+	struct v4l2_mbus_framefmt *mf;
+
+	if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
+		/* Do not change the format while stream is on */
+		if (vsen->frame)
+			return -EBUSY;
+
+		mf = &vsen->mbus_format;
+	} else {
+		mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
+	}
+
+	/* Set the new format */
+	vimc_sen_adjust_fmt(&fmt->format);
+
+	dev_dbg(vsen->ved.dev, "%s: format update: "
+		"old:%dx%d (0x%x, %d, %d, %d, %d) "
+		"new:%dx%d (0x%x, %d, %d, %d, %d)\n", vsen->sd.name,
+		/* old */
+		mf->width, mf->height, mf->code,
+		mf->colorspace,	mf->quantization,
+		mf->xfer_func, mf->ycbcr_enc,
+		/* new */
+		fmt->format.width, fmt->format.height, fmt->format.code,
+		fmt->format.colorspace, fmt->format.quantization,
+		fmt->format.xfer_func, fmt->format.ycbcr_enc);
+
+	*mf = fmt->format;
+
+	return 0;
+}
+
+static const struct v4l2_subdev_pad_ops vimc_sen_pad_ops = {
+	.init_cfg		= vimc_sen_init_cfg,
+	.enum_mbus_code		= vimc_sen_enum_mbus_code,
+	.enum_frame_size	= vimc_sen_enum_frame_size,
+	.get_fmt		= vimc_sen_get_fmt,
+	.set_fmt		= vimc_sen_set_fmt,
+};
+
+static void *vimc_sen_process_frame(struct vimc_ent_device *ved,
+				    const void *sink_frame)
+{
+	struct vimc_sen_device *vsen = container_of(ved, struct vimc_sen_device,
+						    ved);
+
+	tpg_fill_plane_buffer(&vsen->tpg, 0, 0, vsen->frame);
+	return vsen->frame;
+}
+
+static int vimc_sen_s_stream(struct v4l2_subdev *sd, int enable)
+{
+	struct vimc_sen_device *vsen =
+				container_of(sd, struct vimc_sen_device, sd);
+
+	if (enable) {
+		const struct vimc_pix_map *vpix;
+		unsigned int frame_size;
+
+		/* Calculate the frame size */
+		vpix = vimc_pix_map_by_code(vsen->mbus_format.code);
+		frame_size = vsen->mbus_format.width * vpix->bpp *
+			     vsen->mbus_format.height;
+
+		/*
+		 * Allocate the frame buffer. Use vmalloc to be able to
+		 * allocate a large amount of memory
+		 */
+		vsen->frame = vmalloc(frame_size);
+		if (!vsen->frame)
+			return -ENOMEM;
+
+		/* configure the test pattern generator */
+		vimc_sen_tpg_s_format(vsen);
+
+	} else {
+
+		vfree(vsen->frame);
+		vsen->frame = NULL;
+	}
+
+	return 0;
+}
+
+static const struct v4l2_subdev_core_ops vimc_sen_core_ops = {
+	.log_status = v4l2_ctrl_subdev_log_status,
+	.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
+	.unsubscribe_event = v4l2_event_subdev_unsubscribe,
+};
+
+static const struct v4l2_subdev_video_ops vimc_sen_video_ops = {
+	.s_stream = vimc_sen_s_stream,
+};
+
+static const struct v4l2_subdev_ops vimc_sen_ops = {
+	.core = &vimc_sen_core_ops,
+	.pad = &vimc_sen_pad_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;
+	case V4L2_CID_BRIGHTNESS:
+		tpg_s_brightness(&vsen->tpg, ctrl->val);
+		break;
+	case V4L2_CID_CONTRAST:
+		tpg_s_contrast(&vsen->tpg, ctrl->val);
+		break;
+	case V4L2_CID_HUE:
+		tpg_s_hue(&vsen->tpg, ctrl->val);
+		break;
+	case V4L2_CID_SATURATION:
+		tpg_s_saturation(&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_release(struct vimc_ent_device *ved)
+{
+	struct vimc_sen_device *vsen =
+		container_of(ved, struct vimc_sen_device, ved);
+
+	v4l2_ctrl_handler_free(&vsen->hdl);
+	tpg_free(&vsen->tpg);
+	media_entity_cleanup(vsen->ved.ent);
+	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 struct vimc_ent_device *vimc_sen_add(struct vimc_device *vimc,
+					    const char *vcfg_name)
+{
+	struct v4l2_device *v4l2_dev = &vimc->v4l2_dev;
+	struct vimc_sen_device *vsen;
+	int ret;
+
+	/* Allocate the vsen struct */
+	vsen = kzalloc(sizeof(*vsen), GFP_KERNEL);
+	if (!vsen)
+		return ERR_PTR(-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);
+	v4l2_ctrl_new_std(&vsen->hdl, &vimc_sen_ctrl_ops,
+			  V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
+	v4l2_ctrl_new_std(&vsen->hdl, &vimc_sen_ctrl_ops,
+			  V4L2_CID_CONTRAST, 0, 255, 1, 128);
+	v4l2_ctrl_new_std(&vsen->hdl, &vimc_sen_ctrl_ops,
+			  V4L2_CID_HUE, -128, 127, 1, 0);
+	v4l2_ctrl_new_std(&vsen->hdl, &vimc_sen_ctrl_ops,
+			  V4L2_CID_SATURATION, 0, 255, 1, 128);
+	vsen->sd.ctrl_handler = &vsen->hdl;
+	if (vsen->hdl.error) {
+		ret = vsen->hdl.error;
+		goto err_free_vsen;
+	}
+
+	/* Initialize the test pattern generator */
+	tpg_init(&vsen->tpg, vsen->mbus_format.width,
+		 vsen->mbus_format.height);
+	ret = tpg_alloc(&vsen->tpg, VIMC_FRAME_MAX_WIDTH);
+	if (ret)
+		goto err_free_hdl;
+
+	/* Initialize ved and sd */
+	vsen->pad.flags = MEDIA_PAD_FL_SOURCE;
+	ret = vimc_ent_sd_register(&vsen->ved, &vsen->sd, v4l2_dev,
+				   vcfg_name,
+				   MEDIA_ENT_F_CAM_SENSOR, 1, &vsen->pad,
+				   &vimc_sen_ops);
+	if (ret)
+		goto err_free_tpg;
+
+	vsen->ved.process_frame = vimc_sen_process_frame;
+	vsen->ved.dev = vimc->mdev.dev;
+
+	/* Initialize the frame format */
+	vsen->mbus_format = fmt_default;
+
+	return &vsen->ved;
+
+err_free_tpg:
+	tpg_free(&vsen->tpg);
+err_free_hdl:
+	v4l2_ctrl_handler_free(&vsen->hdl);
+err_free_vsen:
+	kfree(vsen);
+
+	return ERR_PTR(ret);
+}
+
+struct vimc_ent_type vimc_sen_type = {
+	.add = vimc_sen_add,
+	.release = vimc_sen_release
+};
diff --git a/drivers/media/test-drivers/vimc/vimc-streamer.c b/drivers/media/test-drivers/vimc/vimc-streamer.c
new file mode 100644
index 000000000000..65feb3c596db
--- /dev/null
+++ b/drivers/media/test-drivers/vimc/vimc-streamer.c
@@ -0,0 +1,238 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * vimc-streamer.c Virtual Media Controller Driver
+ *
+ * Copyright (C) 2018 Lucas A. M. Magalhães <lucmaga@gmail.com>
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/freezer.h>
+#include <linux/kthread.h>
+
+#include "vimc-streamer.h"
+
+/**
+ * vimc_get_source_entity - get the entity connected with the first sink pad
+ *
+ * @ent:	reference media_entity
+ *
+ * Helper function that returns the media entity containing the source pad
+ * linked with the first sink pad from the given media entity pad list.
+ *
+ * Return: The source pad or NULL, if it wasn't found.
+ */
+static struct media_entity *vimc_get_source_entity(struct media_entity *ent)
+{
+	struct media_pad *pad;
+	int i;
+
+	for (i = 0; i < ent->num_pads; i++) {
+		if (ent->pads[i].flags & MEDIA_PAD_FL_SOURCE)
+			continue;
+		pad = media_entity_remote_pad(&ent->pads[i]);
+		return pad ? pad->entity : NULL;
+	}
+	return NULL;
+}
+
+/**
+ * vimc_streamer_pipeline_terminate - Disable stream in all ved in stream
+ *
+ * @stream: the pointer to the stream structure with the pipeline to be
+ *	    disabled.
+ *
+ * Calls s_stream to disable the stream in each entity of the pipeline
+ *
+ */
+static void vimc_streamer_pipeline_terminate(struct vimc_stream *stream)
+{
+	struct vimc_ent_device *ved;
+	struct v4l2_subdev *sd;
+
+	while (stream->pipe_size) {
+		stream->pipe_size--;
+		ved = stream->ved_pipeline[stream->pipe_size];
+		stream->ved_pipeline[stream->pipe_size] = NULL;
+
+		if (!is_media_entity_v4l2_subdev(ved->ent))
+			continue;
+
+		sd = media_entity_to_v4l2_subdev(ved->ent);
+		v4l2_subdev_call(sd, video, s_stream, 0);
+	}
+}
+
+/**
+ * vimc_streamer_pipeline_init - Initializes the stream structure
+ *
+ * @stream: the pointer to the stream structure to be initialized
+ * @ved:    the pointer to the vimc entity initializing the stream
+ *
+ * Initializes the stream structure. Walks through the entity graph to
+ * construct the pipeline used later on the streamer thread.
+ * Calls vimc_streamer_s_stream() to enable stream in all entities of
+ * the pipeline.
+ *
+ * Return: 0 if success, error code otherwise.
+ */
+static int vimc_streamer_pipeline_init(struct vimc_stream *stream,
+				       struct vimc_ent_device *ved)
+{
+	struct media_entity *entity;
+	struct video_device *vdev;
+	struct v4l2_subdev *sd;
+	int ret = 0;
+
+	stream->pipe_size = 0;
+	while (stream->pipe_size < VIMC_STREAMER_PIPELINE_MAX_SIZE) {
+		if (!ved) {
+			vimc_streamer_pipeline_terminate(stream);
+			return -EINVAL;
+		}
+		stream->ved_pipeline[stream->pipe_size++] = ved;
+
+		if (is_media_entity_v4l2_subdev(ved->ent)) {
+			sd = media_entity_to_v4l2_subdev(ved->ent);
+			ret = v4l2_subdev_call(sd, video, s_stream, 1);
+			if (ret && ret != -ENOIOCTLCMD) {
+				dev_err(ved->dev, "subdev_call error %s\n",
+					ved->ent->name);
+				vimc_streamer_pipeline_terminate(stream);
+				return ret;
+			}
+		}
+
+		entity = vimc_get_source_entity(ved->ent);
+		/* Check if the end of the pipeline was reached */
+		if (!entity) {
+			/* the first entity of the pipe should be source only */
+			if (!vimc_is_source(ved->ent)) {
+				dev_err(ved->dev,
+					"first entity in the pipe '%s' is not a source\n",
+					ved->ent->name);
+				vimc_streamer_pipeline_terminate(stream);
+				return -EPIPE;
+			}
+			return 0;
+		}
+
+		/* Get the next device in the pipeline */
+		if (is_media_entity_v4l2_subdev(entity)) {
+			sd = media_entity_to_v4l2_subdev(entity);
+			ved = v4l2_get_subdevdata(sd);
+		} else {
+			vdev = container_of(entity,
+					    struct video_device,
+					    entity);
+			ved = video_get_drvdata(vdev);
+		}
+	}
+
+	vimc_streamer_pipeline_terminate(stream);
+	return -EINVAL;
+}
+
+/**
+ * vimc_streamer_thread - Process frames through the pipeline
+ *
+ * @data:	vimc_stream struct of the current stream
+ *
+ * From the source to the sink, gets a frame from each subdevice and send to
+ * the next one of the pipeline at a fixed framerate.
+ *
+ * Return:
+ * Always zero (created as ``int`` instead of ``void`` to comply with
+ * kthread API).
+ */
+static int vimc_streamer_thread(void *data)
+{
+	struct vimc_stream *stream = data;
+	u8 *frame = NULL;
+	int i;
+
+	set_freezable();
+
+	for (;;) {
+		try_to_freeze();
+		if (kthread_should_stop())
+			break;
+
+		for (i = stream->pipe_size - 1; i >= 0; i--) {
+			frame = stream->ved_pipeline[i]->process_frame(
+					stream->ved_pipeline[i], frame);
+			if (!frame || IS_ERR(frame))
+				break;
+		}
+		//wait for 60hz
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		schedule_timeout(HZ / 60);
+	}
+
+	return 0;
+}
+
+/**
+ * vimc_streamer_s_stream - Start/stop the streaming on the media pipeline
+ *
+ * @stream:	the pointer to the stream structure of the current stream
+ * @ved:	pointer to the vimc entity of the entity of the stream
+ * @enable:	flag to determine if stream should start/stop
+ *
+ * When starting, check if there is no ``stream->kthread`` allocated. This
+ * should indicate that a stream is already running. Then, it initializes the
+ * pipeline, creates and runs a kthread to consume buffers through the pipeline.
+ * When stopping, analogously check if there is a stream running, stop the
+ * thread and terminates the pipeline.
+ *
+ * Return: 0 if success, error code otherwise.
+ */
+int vimc_streamer_s_stream(struct vimc_stream *stream,
+			   struct vimc_ent_device *ved,
+			   int enable)
+{
+	int ret;
+
+	if (!stream || !ved)
+		return -EINVAL;
+
+	if (enable) {
+		if (stream->kthread)
+			return 0;
+
+		ret = vimc_streamer_pipeline_init(stream, ved);
+		if (ret)
+			return ret;
+
+		stream->kthread = kthread_run(vimc_streamer_thread, stream,
+					      "vimc-streamer thread");
+
+		if (IS_ERR(stream->kthread)) {
+			ret = PTR_ERR(stream->kthread);
+			dev_err(ved->dev, "kthread_run failed with %d\n", ret);
+			vimc_streamer_pipeline_terminate(stream);
+			stream->kthread = NULL;
+			return ret;
+		}
+
+	} else {
+		if (!stream->kthread)
+			return 0;
+
+		ret = kthread_stop(stream->kthread);
+		/*
+		 * kthread_stop returns -EINTR in cases when streamon was
+		 * immediately followed by streamoff, and the thread didn't had
+		 * a chance to run. Ignore errors to stop the stream in the
+		 * pipeline.
+		 */
+		if (ret)
+			dev_dbg(ved->dev, "kthread_stop returned '%d'\n", ret);
+
+		stream->kthread = NULL;
+
+		vimc_streamer_pipeline_terminate(stream);
+	}
+
+	return 0;
+}
diff --git a/drivers/media/test-drivers/vimc/vimc-streamer.h b/drivers/media/test-drivers/vimc/vimc-streamer.h
new file mode 100644
index 000000000000..3bb6731b8d4d
--- /dev/null
+++ b/drivers/media/test-drivers/vimc/vimc-streamer.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * vimc-streamer.h Virtual Media Controller Driver
+ *
+ * Copyright (C) 2018 Lucas A. M. Magalhães <lucmaga@gmail.com>
+ *
+ */
+
+#ifndef _VIMC_STREAMER_H_
+#define _VIMC_STREAMER_H_
+
+#include <media/media-device.h>
+
+#include "vimc-common.h"
+
+#define VIMC_STREAMER_PIPELINE_MAX_SIZE 16
+
+/**
+ * struct vimc_stream - struct that represents a stream in the pipeline
+ *
+ * @pipe:		the media pipeline object associated with this stream
+ * @ved_pipeline:	array containing all the entities participating in the
+ * 			stream. The order is from a video device (usually a
+ *			capture device) where stream_on was called, to the
+ *			entity generating the first base image to be
+ *			processed in the pipeline.
+ * @pipe_size:		size of @ved_pipeline
+ * @kthread:		thread that generates the frames of the stream.
+ *
+ * When the user call stream_on in a video device, struct vimc_stream is
+ * used to keep track of all entities and subdevices that generates and
+ * process frames for the stream.
+ */
+struct vimc_stream {
+	struct media_pipeline pipe;
+	struct vimc_ent_device *ved_pipeline[VIMC_STREAMER_PIPELINE_MAX_SIZE];
+	unsigned int pipe_size;
+	struct task_struct *kthread;
+};
+
+int vimc_streamer_s_stream(struct vimc_stream *stream,
+			   struct vimc_ent_device *ved,
+			   int enable);
+
+#endif  //_VIMC_STREAMER_H_
diff --git a/drivers/media/test-drivers/vivid/Kconfig b/drivers/media/test-drivers/vivid/Kconfig
new file mode 100644
index 000000000000..c3abde2986b2
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/Kconfig
@@ -0,0 +1,43 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config VIDEO_VIVID
+	tristate "Virtual Video Test Driver"
+	depends on VIDEO_DEV && VIDEO_V4L2 && !SPARC32 && !SPARC64 && FB
+	depends on HAS_DMA
+	select FONT_SUPPORT
+	select FONT_8x16
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select VIDEOBUF2_VMALLOC
+	select VIDEOBUF2_DMA_CONTIG
+	select VIDEO_V4L2_TPG
+	select MEDIA_CONTROLLER
+	select MEDIA_CONTROLLER_REQUEST_API
+	help
+	  Enables a virtual video driver. This driver emulates a webcam,
+	  TV, S-Video and HDMI capture hardware, including VBI support for
+	  the SDTV inputs. Also video output, VBI output, radio receivers,
+	  transmitters and software defined radio capture is emulated.
+
+	  It is highly configurable and is ideal for testing applications.
+	  Error injection is supported to test rare errors that are hard
+	  to reproduce in real hardware.
+
+	  Say Y here if you want to test video apps or debug V4L devices.
+	  When in doubt, say N.
+
+config VIDEO_VIVID_CEC
+	bool "Enable CEC emulation support"
+	depends on VIDEO_VIVID
+	select CEC_CORE
+	help
+	  When selected the vivid module will emulate the optional
+	  HDMI CEC feature.
+
+config VIDEO_VIVID_MAX_DEVS
+	int "Maximum number of devices"
+	depends on VIDEO_VIVID
+	default "64"
+	help
+	  This allows you to specify the maximum number of devices supported
+	  by the vivid driver.
diff --git a/drivers/media/test-drivers/vivid/Makefile b/drivers/media/test-drivers/vivid/Makefile
new file mode 100644
index 000000000000..b12ad0152a3e
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/Makefile
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0
+vivid-objs := vivid-core.o vivid-ctrls.o vivid-vid-common.o vivid-vbi-gen.o \
+		vivid-vid-cap.o vivid-vid-out.o vivid-kthread-cap.o vivid-kthread-out.o \
+		vivid-radio-rx.o vivid-radio-tx.o vivid-radio-common.o \
+		vivid-rds-gen.o vivid-sdr-cap.o vivid-vbi-cap.o vivid-vbi-out.o \
+		vivid-osd.o vivid-meta-cap.o vivid-meta-out.o \
+		vivid-kthread-touch.o vivid-touch-cap.o
+ifeq ($(CONFIG_VIDEO_VIVID_CEC),y)
+  vivid-objs += vivid-cec.o
+endif
+
+obj-$(CONFIG_VIDEO_VIVID) += vivid.o
diff --git a/drivers/media/test-drivers/vivid/vivid-cec.c b/drivers/media/test-drivers/vivid/vivid-cec.c
new file mode 100644
index 000000000000..4d2413e87730
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-cec.c
@@ -0,0 +1,286 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * vivid-cec.c - A Virtual Video Test Driver, cec emulation
+ *
+ * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#include <media/cec.h>
+
+#include "vivid-core.h"
+#include "vivid-cec.h"
+
+#define CEC_TIM_START_BIT_TOTAL		4500
+#define CEC_TIM_START_BIT_LOW		3700
+#define CEC_TIM_START_BIT_HIGH		800
+#define CEC_TIM_DATA_BIT_TOTAL		2400
+#define CEC_TIM_DATA_BIT_0_LOW		1500
+#define CEC_TIM_DATA_BIT_0_HIGH		900
+#define CEC_TIM_DATA_BIT_1_LOW		600
+#define CEC_TIM_DATA_BIT_1_HIGH		1800
+
+void vivid_cec_bus_free_work(struct vivid_dev *dev)
+{
+	spin_lock(&dev->cec_slock);
+	while (!list_empty(&dev->cec_work_list)) {
+		struct vivid_cec_work *cw =
+			list_first_entry(&dev->cec_work_list,
+					 struct vivid_cec_work, list);
+
+		spin_unlock(&dev->cec_slock);
+		cancel_delayed_work_sync(&cw->work);
+		spin_lock(&dev->cec_slock);
+		list_del(&cw->list);
+		cec_transmit_attempt_done(cw->adap, CEC_TX_STATUS_LOW_DRIVE);
+		kfree(cw);
+	}
+	spin_unlock(&dev->cec_slock);
+}
+
+static bool vivid_cec_find_dest_adap(struct vivid_dev *dev,
+				     struct cec_adapter *adap, u8 dest)
+{
+	unsigned int i;
+
+	if (dest >= 0xf)
+		return false;
+
+	if (adap != dev->cec_rx_adap && dev->cec_rx_adap &&
+	    dev->cec_rx_adap->is_configured &&
+	    cec_has_log_addr(dev->cec_rx_adap, dest))
+		return true;
+
+	for (i = 0; i < MAX_OUTPUTS && dev->cec_tx_adap[i]; i++) {
+		if (adap == dev->cec_tx_adap[i])
+			continue;
+		if (!dev->cec_tx_adap[i]->is_configured)
+			continue;
+		if (cec_has_log_addr(dev->cec_tx_adap[i], dest))
+			return true;
+	}
+	return false;
+}
+
+static void vivid_cec_pin_adap_events(struct cec_adapter *adap, ktime_t ts,
+				      const struct cec_msg *msg, bool nacked)
+{
+	unsigned int len = nacked ? 1 : msg->len;
+	unsigned int i;
+	bool bit;
+
+	if (adap == NULL)
+		return;
+
+	/*
+	 * Suffix ULL on constant 10 makes the expression
+	 * CEC_TIM_START_BIT_TOTAL + 10ULL * len * CEC_TIM_DATA_BIT_TOTAL
+	 * to be evaluated using 64-bit unsigned arithmetic (u64), which
+	 * is what ktime_sub_us expects as second argument.
+	 */
+	ts = ktime_sub_us(ts, CEC_TIM_START_BIT_TOTAL +
+			       10ULL * len * CEC_TIM_DATA_BIT_TOTAL);
+	cec_queue_pin_cec_event(adap, false, false, ts);
+	ts = ktime_add_us(ts, CEC_TIM_START_BIT_LOW);
+	cec_queue_pin_cec_event(adap, true, false, ts);
+	ts = ktime_add_us(ts, CEC_TIM_START_BIT_HIGH);
+
+	for (i = 0; i < 10 * len; i++) {
+		switch (i % 10) {
+		case 0 ... 7:
+			bit = msg->msg[i / 10] & (0x80 >> (i % 10));
+			break;
+		case 8: /* EOM */
+			bit = i / 10 == msg->len - 1;
+			break;
+		case 9: /* ACK */
+			bit = cec_msg_is_broadcast(msg) ^ nacked;
+			break;
+		}
+		cec_queue_pin_cec_event(adap, false, false, ts);
+		if (bit)
+			ts = ktime_add_us(ts, CEC_TIM_DATA_BIT_1_LOW);
+		else
+			ts = ktime_add_us(ts, CEC_TIM_DATA_BIT_0_LOW);
+		cec_queue_pin_cec_event(adap, true, false, ts);
+		if (bit)
+			ts = ktime_add_us(ts, CEC_TIM_DATA_BIT_1_HIGH);
+		else
+			ts = ktime_add_us(ts, CEC_TIM_DATA_BIT_0_HIGH);
+	}
+}
+
+static void vivid_cec_pin_events(struct vivid_dev *dev,
+				 const struct cec_msg *msg, bool nacked)
+{
+	ktime_t ts = ktime_get();
+	unsigned int i;
+
+	vivid_cec_pin_adap_events(dev->cec_rx_adap, ts, msg, nacked);
+	for (i = 0; i < MAX_OUTPUTS; i++)
+		vivid_cec_pin_adap_events(dev->cec_tx_adap[i], ts, msg, nacked);
+}
+
+static void vivid_cec_xfer_done_worker(struct work_struct *work)
+{
+	struct vivid_cec_work *cw =
+		container_of(work, struct vivid_cec_work, work.work);
+	struct vivid_dev *dev = cw->dev;
+	struct cec_adapter *adap = cw->adap;
+	u8 dest = cec_msg_destination(&cw->msg);
+	bool valid_dest;
+	unsigned int i;
+
+	valid_dest = cec_msg_is_broadcast(&cw->msg);
+	if (!valid_dest)
+		valid_dest = vivid_cec_find_dest_adap(dev, adap, dest);
+
+	cw->tx_status = valid_dest ? CEC_TX_STATUS_OK : CEC_TX_STATUS_NACK;
+	spin_lock(&dev->cec_slock);
+	dev->cec_xfer_time_jiffies = 0;
+	dev->cec_xfer_start_jiffies = 0;
+	list_del(&cw->list);
+	spin_unlock(&dev->cec_slock);
+	vivid_cec_pin_events(dev, &cw->msg, !valid_dest);
+	cec_transmit_attempt_done(cw->adap, cw->tx_status);
+
+	/* Broadcast message */
+	if (adap != dev->cec_rx_adap)
+		cec_received_msg(dev->cec_rx_adap, &cw->msg);
+	for (i = 0; i < MAX_OUTPUTS && dev->cec_tx_adap[i]; i++)
+		if (adap != dev->cec_tx_adap[i])
+			cec_received_msg(dev->cec_tx_adap[i], &cw->msg);
+	kfree(cw);
+}
+
+static void vivid_cec_xfer_try_worker(struct work_struct *work)
+{
+	struct vivid_cec_work *cw =
+		container_of(work, struct vivid_cec_work, work.work);
+	struct vivid_dev *dev = cw->dev;
+
+	spin_lock(&dev->cec_slock);
+	if (dev->cec_xfer_time_jiffies) {
+		list_del(&cw->list);
+		spin_unlock(&dev->cec_slock);
+		cec_transmit_attempt_done(cw->adap, CEC_TX_STATUS_ARB_LOST);
+		kfree(cw);
+	} else {
+		INIT_DELAYED_WORK(&cw->work, vivid_cec_xfer_done_worker);
+		dev->cec_xfer_start_jiffies = jiffies;
+		dev->cec_xfer_time_jiffies = usecs_to_jiffies(cw->usecs);
+		spin_unlock(&dev->cec_slock);
+		schedule_delayed_work(&cw->work, dev->cec_xfer_time_jiffies);
+	}
+}
+
+static int vivid_cec_adap_enable(struct cec_adapter *adap, bool enable)
+{
+	adap->cec_pin_is_high = true;
+	return 0;
+}
+
+static int vivid_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr)
+{
+	return 0;
+}
+
+/*
+ * One data bit takes 2400 us, each byte needs 10 bits so that's 24000 us
+ * per byte.
+ */
+#define USECS_PER_BYTE 24000
+
+static int vivid_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
+				   u32 signal_free_time, struct cec_msg *msg)
+{
+	struct vivid_dev *dev = cec_get_drvdata(adap);
+	struct vivid_cec_work *cw = kzalloc(sizeof(*cw), GFP_KERNEL);
+	long delta_jiffies = 0;
+
+	if (cw == NULL)
+		return -ENOMEM;
+	cw->dev = dev;
+	cw->adap = adap;
+	cw->usecs = CEC_FREE_TIME_TO_USEC(signal_free_time) +
+		    msg->len * USECS_PER_BYTE;
+	cw->msg = *msg;
+
+	spin_lock(&dev->cec_slock);
+	list_add(&cw->list, &dev->cec_work_list);
+	if (dev->cec_xfer_time_jiffies == 0) {
+		INIT_DELAYED_WORK(&cw->work, vivid_cec_xfer_done_worker);
+		dev->cec_xfer_start_jiffies = jiffies;
+		dev->cec_xfer_time_jiffies = usecs_to_jiffies(cw->usecs);
+		delta_jiffies = dev->cec_xfer_time_jiffies;
+	} else {
+		INIT_DELAYED_WORK(&cw->work, vivid_cec_xfer_try_worker);
+		delta_jiffies = dev->cec_xfer_start_jiffies +
+			dev->cec_xfer_time_jiffies - jiffies;
+	}
+	spin_unlock(&dev->cec_slock);
+	schedule_delayed_work(&cw->work, delta_jiffies < 0 ? 0 : delta_jiffies);
+	return 0;
+}
+
+static int vivid_received(struct cec_adapter *adap, struct cec_msg *msg)
+{
+	struct vivid_dev *dev = cec_get_drvdata(adap);
+	struct cec_msg reply;
+	u8 dest = cec_msg_destination(msg);
+	u8 disp_ctl;
+	char osd[14];
+
+	if (cec_msg_is_broadcast(msg))
+		dest = adap->log_addrs.log_addr[0];
+	cec_msg_init(&reply, dest, cec_msg_initiator(msg));
+
+	switch (cec_msg_opcode(msg)) {
+	case CEC_MSG_SET_OSD_STRING:
+		if (!cec_is_sink(adap))
+			return -ENOMSG;
+		cec_ops_set_osd_string(msg, &disp_ctl, osd);
+		switch (disp_ctl) {
+		case CEC_OP_DISP_CTL_DEFAULT:
+			strscpy(dev->osd, osd, sizeof(dev->osd));
+			dev->osd_jiffies = jiffies;
+			break;
+		case CEC_OP_DISP_CTL_UNTIL_CLEARED:
+			strscpy(dev->osd, osd, sizeof(dev->osd));
+			dev->osd_jiffies = 0;
+			break;
+		case CEC_OP_DISP_CTL_CLEAR:
+			dev->osd[0] = 0;
+			dev->osd_jiffies = 0;
+			break;
+		default:
+			cec_msg_feature_abort(&reply, cec_msg_opcode(msg),
+					      CEC_OP_ABORT_INVALID_OP);
+			cec_transmit_msg(adap, &reply, false);
+			break;
+		}
+		break;
+	default:
+		return -ENOMSG;
+	}
+	return 0;
+}
+
+static const struct cec_adap_ops vivid_cec_adap_ops = {
+	.adap_enable = vivid_cec_adap_enable,
+	.adap_log_addr = vivid_cec_adap_log_addr,
+	.adap_transmit = vivid_cec_adap_transmit,
+	.received = vivid_received,
+};
+
+struct cec_adapter *vivid_cec_alloc_adap(struct vivid_dev *dev,
+					 unsigned int idx,
+					 bool is_source)
+{
+	u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_MONITOR_ALL | CEC_CAP_MONITOR_PIN;
+	char name[32];
+
+	snprintf(name, sizeof(name), "vivid-%03d-vid-%s%d",
+		 dev->inst, is_source ? "out" : "cap", idx);
+	return cec_allocate_adapter(&vivid_cec_adap_ops, dev,
+		name, caps, 1);
+}
diff --git a/drivers/media/test-drivers/vivid/vivid-cec.h b/drivers/media/test-drivers/vivid/vivid-cec.h
new file mode 100644
index 000000000000..7524ed48a914
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-cec.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * vivid-cec.h - A Virtual Video Test Driver, cec emulation
+ *
+ * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#ifdef CONFIG_VIDEO_VIVID_CEC
+struct cec_adapter *vivid_cec_alloc_adap(struct vivid_dev *dev,
+					 unsigned int idx,
+					 bool is_source);
+void vivid_cec_bus_free_work(struct vivid_dev *dev);
+
+#else
+
+static inline void vivid_cec_bus_free_work(struct vivid_dev *dev)
+{
+}
+
+#endif
diff --git a/drivers/media/test-drivers/vivid/vivid-core.c b/drivers/media/test-drivers/vivid/vivid-core.c
new file mode 100644
index 000000000000..6c740e3e6999
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-core.c
@@ -0,0 +1,2006 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * vivid-core.c - A Virtual Video Test Driver, core initialization
+ *
+ * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/font.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/videodev2.h>
+#include <linux/v4l2-dv-timings.h>
+#include <media/videobuf2-vmalloc.h>
+#include <media/videobuf2-dma-contig.h>
+#include <media/v4l2-dv-timings.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-fh.h>
+#include <media/v4l2-event.h>
+
+#include "vivid-core.h"
+#include "vivid-vid-common.h"
+#include "vivid-vid-cap.h"
+#include "vivid-vid-out.h"
+#include "vivid-radio-common.h"
+#include "vivid-radio-rx.h"
+#include "vivid-radio-tx.h"
+#include "vivid-sdr-cap.h"
+#include "vivid-vbi-cap.h"
+#include "vivid-vbi-out.h"
+#include "vivid-osd.h"
+#include "vivid-cec.h"
+#include "vivid-ctrls.h"
+#include "vivid-meta-cap.h"
+#include "vivid-meta-out.h"
+#include "vivid-touch-cap.h"
+
+#define VIVID_MODULE_NAME "vivid"
+
+/* The maximum number of vivid devices */
+#define VIVID_MAX_DEVS CONFIG_VIDEO_VIVID_MAX_DEVS
+
+MODULE_DESCRIPTION("Virtual Video Test Driver");
+MODULE_AUTHOR("Hans Verkuil");
+MODULE_LICENSE("GPL");
+
+static unsigned n_devs = 1;
+module_param(n_devs, uint, 0444);
+MODULE_PARM_DESC(n_devs, " number of driver instances to create");
+
+static int vid_cap_nr[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = -1 };
+module_param_array(vid_cap_nr, int, NULL, 0444);
+MODULE_PARM_DESC(vid_cap_nr, " videoX start number, -1 is autodetect");
+
+static int vid_out_nr[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = -1 };
+module_param_array(vid_out_nr, int, NULL, 0444);
+MODULE_PARM_DESC(vid_out_nr, " videoX start number, -1 is autodetect");
+
+static int vbi_cap_nr[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = -1 };
+module_param_array(vbi_cap_nr, int, NULL, 0444);
+MODULE_PARM_DESC(vbi_cap_nr, " vbiX start number, -1 is autodetect");
+
+static int vbi_out_nr[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = -1 };
+module_param_array(vbi_out_nr, int, NULL, 0444);
+MODULE_PARM_DESC(vbi_out_nr, " vbiX start number, -1 is autodetect");
+
+static int sdr_cap_nr[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = -1 };
+module_param_array(sdr_cap_nr, int, NULL, 0444);
+MODULE_PARM_DESC(sdr_cap_nr, " swradioX start number, -1 is autodetect");
+
+static int radio_rx_nr[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = -1 };
+module_param_array(radio_rx_nr, int, NULL, 0444);
+MODULE_PARM_DESC(radio_rx_nr, " radioX start number, -1 is autodetect");
+
+static int radio_tx_nr[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = -1 };
+module_param_array(radio_tx_nr, int, NULL, 0444);
+MODULE_PARM_DESC(radio_tx_nr, " radioX start number, -1 is autodetect");
+
+static int meta_cap_nr[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = -1 };
+module_param_array(meta_cap_nr, int, NULL, 0444);
+MODULE_PARM_DESC(meta_cap_nr, " videoX start number, -1 is autodetect");
+
+static int meta_out_nr[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = -1 };
+module_param_array(meta_out_nr, int, NULL, 0444);
+MODULE_PARM_DESC(meta_out_nr, " videoX start number, -1 is autodetect");
+
+static int touch_cap_nr[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = -1 };
+module_param_array(touch_cap_nr, int, NULL, 0444);
+MODULE_PARM_DESC(touch_cap_nr, " v4l-touchX start number, -1 is autodetect");
+
+static int ccs_cap_mode[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = -1 };
+module_param_array(ccs_cap_mode, int, NULL, 0444);
+MODULE_PARM_DESC(ccs_cap_mode, " capture crop/compose/scale mode:\n"
+			   "\t\t    bit 0=crop, 1=compose, 2=scale,\n"
+			   "\t\t    -1=user-controlled (default)");
+
+static int ccs_out_mode[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = -1 };
+module_param_array(ccs_out_mode, int, NULL, 0444);
+MODULE_PARM_DESC(ccs_out_mode, " output crop/compose/scale mode:\n"
+			   "\t\t    bit 0=crop, 1=compose, 2=scale,\n"
+			   "\t\t    -1=user-controlled (default)");
+
+static unsigned multiplanar[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = 1 };
+module_param_array(multiplanar, uint, NULL, 0444);
+MODULE_PARM_DESC(multiplanar, " 1 (default) creates a single planar device, 2 creates a multiplanar device.");
+
+/*
+ * Default: video + vbi-cap (raw and sliced) + radio rx + radio tx + sdr +
+ * vbi-out + vid-out + meta-cap
+ */
+static unsigned int node_types[VIVID_MAX_DEVS] = {
+	[0 ... (VIVID_MAX_DEVS - 1)] = 0xe1d3d
+};
+module_param_array(node_types, uint, NULL, 0444);
+MODULE_PARM_DESC(node_types, " node types, default is 0xe1d3d. Bitmask with the following meaning:\n"
+			     "\t\t    bit 0: Video Capture node\n"
+			     "\t\t    bit 2-3: VBI Capture node: 0 = none, 1 = raw vbi, 2 = sliced vbi, 3 = both\n"
+			     "\t\t    bit 4: Radio Receiver node\n"
+			     "\t\t    bit 5: Software Defined Radio Receiver node\n"
+			     "\t\t    bit 8: Video Output node\n"
+			     "\t\t    bit 10-11: VBI Output node: 0 = none, 1 = raw vbi, 2 = sliced vbi, 3 = both\n"
+			     "\t\t    bit 12: Radio Transmitter node\n"
+			     "\t\t    bit 16: Framebuffer for testing overlays\n"
+			     "\t\t    bit 17: Metadata Capture node\n"
+			     "\t\t    bit 18: Metadata Output node\n"
+			     "\t\t    bit 19: Touch Capture node\n");
+
+/* Default: 4 inputs */
+static unsigned num_inputs[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = 4 };
+module_param_array(num_inputs, uint, NULL, 0444);
+MODULE_PARM_DESC(num_inputs, " number of inputs, default is 4");
+
+/* Default: input 0 = WEBCAM, 1 = TV, 2 = SVID, 3 = HDMI */
+static unsigned input_types[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = 0xe4 };
+module_param_array(input_types, uint, NULL, 0444);
+MODULE_PARM_DESC(input_types, " input types, default is 0xe4. Two bits per input,\n"
+			      "\t\t    bits 0-1 == input 0, bits 31-30 == input 15.\n"
+			      "\t\t    Type 0 == webcam, 1 == TV, 2 == S-Video, 3 == HDMI");
+
+/* Default: 2 outputs */
+static unsigned num_outputs[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = 2 };
+module_param_array(num_outputs, uint, NULL, 0444);
+MODULE_PARM_DESC(num_outputs, " number of outputs, default is 2");
+
+/* Default: output 0 = SVID, 1 = HDMI */
+static unsigned output_types[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = 2 };
+module_param_array(output_types, uint, NULL, 0444);
+MODULE_PARM_DESC(output_types, " output types, default is 0x02. One bit per output,\n"
+			      "\t\t    bit 0 == output 0, bit 15 == output 15.\n"
+			      "\t\t    Type 0 == S-Video, 1 == HDMI");
+
+unsigned vivid_debug;
+module_param(vivid_debug, uint, 0644);
+MODULE_PARM_DESC(vivid_debug, " activates debug info");
+
+static bool no_error_inj;
+module_param(no_error_inj, bool, 0444);
+MODULE_PARM_DESC(no_error_inj, " if set disable the error injecting controls");
+
+static unsigned int allocators[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = 0 };
+module_param_array(allocators, uint, NULL, 0444);
+MODULE_PARM_DESC(allocators, " memory allocator selection, default is 0.\n"
+			     "\t\t    0 == vmalloc\n"
+			     "\t\t    1 == dma-contig");
+
+static struct vivid_dev *vivid_devs[VIVID_MAX_DEVS];
+
+const struct v4l2_rect vivid_min_rect = {
+	0, 0, MIN_WIDTH, MIN_HEIGHT
+};
+
+const struct v4l2_rect vivid_max_rect = {
+	0, 0, MAX_WIDTH * MAX_ZOOM, MAX_HEIGHT * MAX_ZOOM
+};
+
+static const u8 vivid_hdmi_edid[256] = {
+	0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
+	0x31, 0xd8, 0x34, 0x12, 0x00, 0x00, 0x00, 0x00,
+	0x22, 0x1a, 0x01, 0x03, 0x80, 0x60, 0x36, 0x78,
+	0x0f, 0xee, 0x91, 0xa3, 0x54, 0x4c, 0x99, 0x26,
+	0x0f, 0x50, 0x54, 0x2f, 0xcf, 0x00, 0x31, 0x59,
+	0x45, 0x59, 0x81, 0x80, 0x81, 0x40, 0x90, 0x40,
+	0x95, 0x00, 0xa9, 0x40, 0xb3, 0x00, 0x08, 0xe8,
+	0x00, 0x30, 0xf2, 0x70, 0x5a, 0x80, 0xb0, 0x58,
+	0x8a, 0x00, 0xc0, 0x1c, 0x32, 0x00, 0x00, 0x1e,
+	0x00, 0x00, 0x00, 0xfd, 0x00, 0x18, 0x55, 0x18,
+	0x87, 0x3c, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x76,
+	0x69, 0x76, 0x69, 0x64, 0x0a, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x10,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x7b,
+
+	0x02, 0x03, 0x3f, 0xf0, 0x51, 0x61, 0x60, 0x5f,
+	0x5e, 0x5d, 0x10, 0x1f, 0x04, 0x13, 0x22, 0x21,
+	0x20, 0x05, 0x14, 0x02, 0x11, 0x01, 0x23, 0x09,
+	0x07, 0x07, 0x83, 0x01, 0x00, 0x00, 0x6d, 0x03,
+	0x0c, 0x00, 0x10, 0x00, 0x00, 0x3c, 0x21, 0x00,
+	0x60, 0x01, 0x02, 0x03, 0x67, 0xd8, 0x5d, 0xc4,
+	0x01, 0x78, 0x00, 0x00, 0xe2, 0x00, 0xea, 0xe3,
+	0x05, 0x00, 0x00, 0xe3, 0x06, 0x01, 0x00, 0x4d,
+	0xd0, 0x00, 0xa0, 0xf0, 0x70, 0x3e, 0x80, 0x30,
+	0x20, 0x35, 0x00, 0xc0, 0x1c, 0x32, 0x00, 0x00,
+	0x1e, 0x1a, 0x36, 0x80, 0xa0, 0x70, 0x38, 0x1f,
+	0x40, 0x30, 0x20, 0x35, 0x00, 0xc0, 0x1c, 0x32,
+	0x00, 0x00, 0x1a, 0x1a, 0x1d, 0x00, 0x80, 0x51,
+	0xd0, 0x1c, 0x20, 0x40, 0x80, 0x35, 0x00, 0xc0,
+	0x1c, 0x32, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63,
+};
+
+static int vidioc_querycap(struct file *file, void  *priv,
+					struct v4l2_capability *cap)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	strscpy(cap->driver, "vivid", sizeof(cap->driver));
+	strscpy(cap->card, "vivid", sizeof(cap->card));
+	snprintf(cap->bus_info, sizeof(cap->bus_info),
+			"platform:%s", dev->v4l2_dev.name);
+
+	cap->capabilities = dev->vid_cap_caps | dev->vid_out_caps |
+		dev->vbi_cap_caps | dev->vbi_out_caps |
+		dev->radio_rx_caps | dev->radio_tx_caps |
+		dev->sdr_cap_caps | dev->meta_cap_caps |
+		dev->meta_out_caps | dev->touch_cap_caps |
+		V4L2_CAP_DEVICE_CAPS;
+	return 0;
+}
+
+static int vidioc_s_hw_freq_seek(struct file *file, void *fh, const struct v4l2_hw_freq_seek *a)
+{
+	struct video_device *vdev = video_devdata(file);
+
+	if (vdev->vfl_type == VFL_TYPE_RADIO)
+		return vivid_radio_rx_s_hw_freq_seek(file, fh, a);
+	return -ENOTTY;
+}
+
+static int vidioc_enum_freq_bands(struct file *file, void *fh, struct v4l2_frequency_band *band)
+{
+	struct video_device *vdev = video_devdata(file);
+
+	if (vdev->vfl_type == VFL_TYPE_RADIO)
+		return vivid_radio_rx_enum_freq_bands(file, fh, band);
+	if (vdev->vfl_type == VFL_TYPE_SDR)
+		return vivid_sdr_enum_freq_bands(file, fh, band);
+	return -ENOTTY;
+}
+
+static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
+{
+	struct video_device *vdev = video_devdata(file);
+
+	if (vdev->vfl_type == VFL_TYPE_RADIO)
+		return vivid_radio_rx_g_tuner(file, fh, vt);
+	if (vdev->vfl_type == VFL_TYPE_SDR)
+		return vivid_sdr_g_tuner(file, fh, vt);
+	return vivid_video_g_tuner(file, fh, vt);
+}
+
+static int vidioc_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt)
+{
+	struct video_device *vdev = video_devdata(file);
+
+	if (vdev->vfl_type == VFL_TYPE_RADIO)
+		return vivid_radio_rx_s_tuner(file, fh, vt);
+	if (vdev->vfl_type == VFL_TYPE_SDR)
+		return vivid_sdr_s_tuner(file, fh, vt);
+	return vivid_video_s_tuner(file, fh, vt);
+}
+
+static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	struct video_device *vdev = video_devdata(file);
+
+	if (vdev->vfl_type == VFL_TYPE_RADIO)
+		return vivid_radio_g_frequency(file,
+			vdev->vfl_dir == VFL_DIR_RX ?
+			&dev->radio_rx_freq : &dev->radio_tx_freq, vf);
+	if (vdev->vfl_type == VFL_TYPE_SDR)
+		return vivid_sdr_g_frequency(file, fh, vf);
+	return vivid_video_g_frequency(file, fh, vf);
+}
+
+static int vidioc_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *vf)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	struct video_device *vdev = video_devdata(file);
+
+	if (vdev->vfl_type == VFL_TYPE_RADIO)
+		return vivid_radio_s_frequency(file,
+			vdev->vfl_dir == VFL_DIR_RX ?
+			&dev->radio_rx_freq : &dev->radio_tx_freq, vf);
+	if (vdev->vfl_type == VFL_TYPE_SDR)
+		return vivid_sdr_s_frequency(file, fh, vf);
+	return vivid_video_s_frequency(file, fh, vf);
+}
+
+static int vidioc_overlay(struct file *file, void *fh, unsigned i)
+{
+	struct video_device *vdev = video_devdata(file);
+
+	if (vdev->vfl_dir == VFL_DIR_RX)
+		return vivid_vid_cap_overlay(file, fh, i);
+	return vivid_vid_out_overlay(file, fh, i);
+}
+
+static int vidioc_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *a)
+{
+	struct video_device *vdev = video_devdata(file);
+
+	if (vdev->vfl_dir == VFL_DIR_RX)
+		return vivid_vid_cap_g_fbuf(file, fh, a);
+	return vivid_vid_out_g_fbuf(file, fh, a);
+}
+
+static int vidioc_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffer *a)
+{
+	struct video_device *vdev = video_devdata(file);
+
+	if (vdev->vfl_dir == VFL_DIR_RX)
+		return vivid_vid_cap_s_fbuf(file, fh, a);
+	return vivid_vid_out_s_fbuf(file, fh, a);
+}
+
+static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id id)
+{
+	struct video_device *vdev = video_devdata(file);
+
+	if (vdev->vfl_dir == VFL_DIR_RX)
+		return vivid_vid_cap_s_std(file, fh, id);
+	return vivid_vid_out_s_std(file, fh, id);
+}
+
+static int vidioc_s_dv_timings(struct file *file, void *fh, struct v4l2_dv_timings *timings)
+{
+	struct video_device *vdev = video_devdata(file);
+
+	if (vdev->vfl_dir == VFL_DIR_RX)
+		return vivid_vid_cap_s_dv_timings(file, fh, timings);
+	return vivid_vid_out_s_dv_timings(file, fh, timings);
+}
+
+static int vidioc_g_pixelaspect(struct file *file, void *fh,
+				int type, struct v4l2_fract *f)
+{
+	struct video_device *vdev = video_devdata(file);
+
+	if (vdev->vfl_dir == VFL_DIR_RX)
+		return vivid_vid_cap_g_pixelaspect(file, fh, type, f);
+	return vivid_vid_out_g_pixelaspect(file, fh, type, f);
+}
+
+static int vidioc_g_selection(struct file *file, void *fh,
+			      struct v4l2_selection *sel)
+{
+	struct video_device *vdev = video_devdata(file);
+
+	if (vdev->vfl_dir == VFL_DIR_RX)
+		return vivid_vid_cap_g_selection(file, fh, sel);
+	return vivid_vid_out_g_selection(file, fh, sel);
+}
+
+static int vidioc_s_selection(struct file *file, void *fh,
+			      struct v4l2_selection *sel)
+{
+	struct video_device *vdev = video_devdata(file);
+
+	if (vdev->vfl_dir == VFL_DIR_RX)
+		return vivid_vid_cap_s_selection(file, fh, sel);
+	return vivid_vid_out_s_selection(file, fh, sel);
+}
+
+static int vidioc_g_parm(struct file *file, void *fh,
+			  struct v4l2_streamparm *parm)
+{
+	struct video_device *vdev = video_devdata(file);
+
+	if (vdev->vfl_type == VFL_TYPE_TOUCH)
+		return vivid_g_parm_tch(file, fh, parm);
+	if (vdev->vfl_dir == VFL_DIR_RX)
+		return vivid_vid_cap_g_parm(file, fh, parm);
+	return vivid_vid_out_g_parm(file, fh, parm);
+}
+
+static int vidioc_s_parm(struct file *file, void *fh,
+			  struct v4l2_streamparm *parm)
+{
+	struct video_device *vdev = video_devdata(file);
+
+	if (vdev->vfl_dir == VFL_DIR_RX)
+		return vivid_vid_cap_s_parm(file, fh, parm);
+	return -ENOTTY;
+}
+
+static int vidioc_log_status(struct file *file, void *fh)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	struct video_device *vdev = video_devdata(file);
+
+	v4l2_ctrl_log_status(file, fh);
+	if (vdev->vfl_dir == VFL_DIR_RX && vdev->vfl_type == VFL_TYPE_VIDEO)
+		tpg_log_status(&dev->tpg);
+	return 0;
+}
+
+static ssize_t vivid_radio_read(struct file *file, char __user *buf,
+			 size_t size, loff_t *offset)
+{
+	struct video_device *vdev = video_devdata(file);
+
+	if (vdev->vfl_dir == VFL_DIR_TX)
+		return -EINVAL;
+	return vivid_radio_rx_read(file, buf, size, offset);
+}
+
+static ssize_t vivid_radio_write(struct file *file, const char __user *buf,
+			  size_t size, loff_t *offset)
+{
+	struct video_device *vdev = video_devdata(file);
+
+	if (vdev->vfl_dir == VFL_DIR_RX)
+		return -EINVAL;
+	return vivid_radio_tx_write(file, buf, size, offset);
+}
+
+static __poll_t vivid_radio_poll(struct file *file, struct poll_table_struct *wait)
+{
+	struct video_device *vdev = video_devdata(file);
+
+	if (vdev->vfl_dir == VFL_DIR_RX)
+		return vivid_radio_rx_poll(file, wait);
+	return vivid_radio_tx_poll(file, wait);
+}
+
+static int vivid_enum_input(struct file *file, void *priv,
+			    struct v4l2_input *inp)
+{
+	struct video_device *vdev = video_devdata(file);
+
+	if (vdev->vfl_type == VFL_TYPE_TOUCH)
+		return vivid_enum_input_tch(file, priv, inp);
+	return vidioc_enum_input(file, priv, inp);
+}
+
+static int vivid_g_input(struct file *file, void *priv, unsigned int *i)
+{
+	struct video_device *vdev = video_devdata(file);
+
+	if (vdev->vfl_type == VFL_TYPE_TOUCH)
+		return vivid_g_input_tch(file, priv, i);
+	return vidioc_g_input(file, priv, i);
+}
+
+static int vivid_s_input(struct file *file, void *priv, unsigned int i)
+{
+	struct video_device *vdev = video_devdata(file);
+
+	if (vdev->vfl_type == VFL_TYPE_TOUCH)
+		return vivid_s_input_tch(file, priv, i);
+	return vidioc_s_input(file, priv, i);
+}
+
+static int vivid_enum_fmt_cap(struct file *file, void  *priv,
+			      struct v4l2_fmtdesc *f)
+{
+	struct video_device *vdev = video_devdata(file);
+
+	if (vdev->vfl_type == VFL_TYPE_TOUCH)
+		return vivid_enum_fmt_tch(file, priv, f);
+	return vivid_enum_fmt_vid(file, priv, f);
+}
+
+static int vivid_g_fmt_cap(struct file *file, void *priv,
+			   struct v4l2_format *f)
+{
+	struct video_device *vdev = video_devdata(file);
+
+	if (vdev->vfl_type == VFL_TYPE_TOUCH)
+		return vivid_g_fmt_tch(file, priv, f);
+	return vidioc_g_fmt_vid_cap(file, priv, f);
+}
+
+static int vivid_try_fmt_cap(struct file *file, void *priv,
+			     struct v4l2_format *f)
+{
+	struct video_device *vdev = video_devdata(file);
+
+	if (vdev->vfl_type == VFL_TYPE_TOUCH)
+		return vivid_g_fmt_tch(file, priv, f);
+	return vidioc_try_fmt_vid_cap(file, priv, f);
+}
+
+static int vivid_s_fmt_cap(struct file *file, void *priv,
+			   struct v4l2_format *f)
+{
+	struct video_device *vdev = video_devdata(file);
+
+	if (vdev->vfl_type == VFL_TYPE_TOUCH)
+		return vivid_g_fmt_tch(file, priv, f);
+	return vidioc_s_fmt_vid_cap(file, priv, f);
+}
+
+static int vivid_g_fmt_cap_mplane(struct file *file, void *priv,
+				  struct v4l2_format *f)
+{
+	struct video_device *vdev = video_devdata(file);
+
+	if (vdev->vfl_type == VFL_TYPE_TOUCH)
+		return vivid_g_fmt_tch_mplane(file, priv, f);
+	return vidioc_g_fmt_vid_cap_mplane(file, priv, f);
+}
+
+static int vivid_try_fmt_cap_mplane(struct file *file, void *priv,
+				    struct v4l2_format *f)
+{
+	struct video_device *vdev = video_devdata(file);
+
+	if (vdev->vfl_type == VFL_TYPE_TOUCH)
+		return vivid_g_fmt_tch_mplane(file, priv, f);
+	return vidioc_try_fmt_vid_cap_mplane(file, priv, f);
+}
+
+static int vivid_s_fmt_cap_mplane(struct file *file, void *priv,
+				  struct v4l2_format *f)
+{
+	struct video_device *vdev = video_devdata(file);
+
+	if (vdev->vfl_type == VFL_TYPE_TOUCH)
+		return vivid_g_fmt_tch_mplane(file, priv, f);
+	return vidioc_s_fmt_vid_cap_mplane(file, priv, f);
+}
+
+static bool vivid_is_in_use(struct video_device *vdev)
+{
+	unsigned long flags;
+	bool res;
+
+	spin_lock_irqsave(&vdev->fh_lock, flags);
+	res = !list_empty(&vdev->fh_list);
+	spin_unlock_irqrestore(&vdev->fh_lock, flags);
+	return res;
+}
+
+static bool vivid_is_last_user(struct vivid_dev *dev)
+{
+	unsigned uses = vivid_is_in_use(&dev->vid_cap_dev) +
+			vivid_is_in_use(&dev->vid_out_dev) +
+			vivid_is_in_use(&dev->vbi_cap_dev) +
+			vivid_is_in_use(&dev->vbi_out_dev) +
+			vivid_is_in_use(&dev->sdr_cap_dev) +
+			vivid_is_in_use(&dev->radio_rx_dev) +
+			vivid_is_in_use(&dev->radio_tx_dev) +
+			vivid_is_in_use(&dev->meta_cap_dev) +
+			vivid_is_in_use(&dev->meta_out_dev) +
+			vivid_is_in_use(&dev->touch_cap_dev);
+
+	return uses == 1;
+}
+
+static int vivid_fop_release(struct file *file)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	struct video_device *vdev = video_devdata(file);
+
+	mutex_lock(&dev->mutex);
+	if (!no_error_inj && v4l2_fh_is_singular_file(file) &&
+	    !video_is_registered(vdev) && vivid_is_last_user(dev)) {
+		/*
+		 * I am the last user of this driver, and a disconnect
+		 * was forced (since this video_device is unregistered),
+		 * so re-register all video_device's again.
+		 */
+		v4l2_info(&dev->v4l2_dev, "reconnect\n");
+		set_bit(V4L2_FL_REGISTERED, &dev->vid_cap_dev.flags);
+		set_bit(V4L2_FL_REGISTERED, &dev->vid_out_dev.flags);
+		set_bit(V4L2_FL_REGISTERED, &dev->vbi_cap_dev.flags);
+		set_bit(V4L2_FL_REGISTERED, &dev->vbi_out_dev.flags);
+		set_bit(V4L2_FL_REGISTERED, &dev->sdr_cap_dev.flags);
+		set_bit(V4L2_FL_REGISTERED, &dev->radio_rx_dev.flags);
+		set_bit(V4L2_FL_REGISTERED, &dev->radio_tx_dev.flags);
+		set_bit(V4L2_FL_REGISTERED, &dev->meta_cap_dev.flags);
+		set_bit(V4L2_FL_REGISTERED, &dev->meta_out_dev.flags);
+		set_bit(V4L2_FL_REGISTERED, &dev->touch_cap_dev.flags);
+	}
+	mutex_unlock(&dev->mutex);
+	if (file->private_data == dev->overlay_cap_owner)
+		dev->overlay_cap_owner = NULL;
+	if (file->private_data == dev->radio_rx_rds_owner) {
+		dev->radio_rx_rds_last_block = 0;
+		dev->radio_rx_rds_owner = NULL;
+	}
+	if (file->private_data == dev->radio_tx_rds_owner) {
+		dev->radio_tx_rds_last_block = 0;
+		dev->radio_tx_rds_owner = NULL;
+	}
+	if (vdev->queue)
+		return vb2_fop_release(file);
+	return v4l2_fh_release(file);
+}
+
+static const struct v4l2_file_operations vivid_fops = {
+	.owner		= THIS_MODULE,
+	.open           = v4l2_fh_open,
+	.release        = vivid_fop_release,
+	.read           = vb2_fop_read,
+	.write          = vb2_fop_write,
+	.poll		= vb2_fop_poll,
+	.unlocked_ioctl = video_ioctl2,
+	.mmap           = vb2_fop_mmap,
+};
+
+static const struct v4l2_file_operations vivid_radio_fops = {
+	.owner		= THIS_MODULE,
+	.open           = v4l2_fh_open,
+	.release        = vivid_fop_release,
+	.read           = vivid_radio_read,
+	.write          = vivid_radio_write,
+	.poll		= vivid_radio_poll,
+	.unlocked_ioctl = video_ioctl2,
+};
+
+static const struct v4l2_ioctl_ops vivid_ioctl_ops = {
+	.vidioc_querycap		= vidioc_querycap,
+
+	.vidioc_enum_fmt_vid_cap	= vivid_enum_fmt_cap,
+	.vidioc_g_fmt_vid_cap		= vivid_g_fmt_cap,
+	.vidioc_try_fmt_vid_cap		= vivid_try_fmt_cap,
+	.vidioc_s_fmt_vid_cap		= vivid_s_fmt_cap,
+	.vidioc_g_fmt_vid_cap_mplane	= vivid_g_fmt_cap_mplane,
+	.vidioc_try_fmt_vid_cap_mplane	= vivid_try_fmt_cap_mplane,
+	.vidioc_s_fmt_vid_cap_mplane	= vivid_s_fmt_cap_mplane,
+
+	.vidioc_enum_fmt_vid_out	= vivid_enum_fmt_vid,
+	.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,
+	.vidioc_g_fmt_vid_out_mplane	= vidioc_g_fmt_vid_out_mplane,
+	.vidioc_try_fmt_vid_out_mplane	= vidioc_try_fmt_vid_out_mplane,
+	.vidioc_s_fmt_vid_out_mplane	= vidioc_s_fmt_vid_out_mplane,
+
+	.vidioc_g_selection		= vidioc_g_selection,
+	.vidioc_s_selection		= vidioc_s_selection,
+	.vidioc_g_pixelaspect		= vidioc_g_pixelaspect,
+
+	.vidioc_g_fmt_vbi_cap		= vidioc_g_fmt_vbi_cap,
+	.vidioc_try_fmt_vbi_cap		= vidioc_g_fmt_vbi_cap,
+	.vidioc_s_fmt_vbi_cap		= vidioc_s_fmt_vbi_cap,
+
+	.vidioc_g_fmt_sliced_vbi_cap    = vidioc_g_fmt_sliced_vbi_cap,
+	.vidioc_try_fmt_sliced_vbi_cap  = vidioc_try_fmt_sliced_vbi_cap,
+	.vidioc_s_fmt_sliced_vbi_cap    = vidioc_s_fmt_sliced_vbi_cap,
+	.vidioc_g_sliced_vbi_cap	= vidioc_g_sliced_vbi_cap,
+
+	.vidioc_g_fmt_vbi_out		= vidioc_g_fmt_vbi_out,
+	.vidioc_try_fmt_vbi_out		= vidioc_g_fmt_vbi_out,
+	.vidioc_s_fmt_vbi_out		= vidioc_s_fmt_vbi_out,
+
+	.vidioc_g_fmt_sliced_vbi_out    = vidioc_g_fmt_sliced_vbi_out,
+	.vidioc_try_fmt_sliced_vbi_out  = vidioc_try_fmt_sliced_vbi_out,
+	.vidioc_s_fmt_sliced_vbi_out    = vidioc_s_fmt_sliced_vbi_out,
+
+	.vidioc_enum_fmt_sdr_cap	= vidioc_enum_fmt_sdr_cap,
+	.vidioc_g_fmt_sdr_cap		= vidioc_g_fmt_sdr_cap,
+	.vidioc_try_fmt_sdr_cap		= vidioc_try_fmt_sdr_cap,
+	.vidioc_s_fmt_sdr_cap		= vidioc_s_fmt_sdr_cap,
+
+	.vidioc_overlay			= vidioc_overlay,
+	.vidioc_enum_framesizes		= vidioc_enum_framesizes,
+	.vidioc_enum_frameintervals	= vidioc_enum_frameintervals,
+	.vidioc_g_parm			= vidioc_g_parm,
+	.vidioc_s_parm			= vidioc_s_parm,
+
+	.vidioc_enum_fmt_vid_overlay	= vidioc_enum_fmt_vid_overlay,
+	.vidioc_g_fmt_vid_overlay	= vidioc_g_fmt_vid_overlay,
+	.vidioc_try_fmt_vid_overlay	= vidioc_try_fmt_vid_overlay,
+	.vidioc_s_fmt_vid_overlay	= vidioc_s_fmt_vid_overlay,
+	.vidioc_g_fmt_vid_out_overlay	= vidioc_g_fmt_vid_out_overlay,
+	.vidioc_try_fmt_vid_out_overlay	= vidioc_try_fmt_vid_out_overlay,
+	.vidioc_s_fmt_vid_out_overlay	= vidioc_s_fmt_vid_out_overlay,
+	.vidioc_g_fbuf			= vidioc_g_fbuf,
+	.vidioc_s_fbuf			= vidioc_s_fbuf,
+
+	.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_expbuf			= vb2_ioctl_expbuf,
+	.vidioc_streamon		= vb2_ioctl_streamon,
+	.vidioc_streamoff		= vb2_ioctl_streamoff,
+
+	.vidioc_enum_input		= vivid_enum_input,
+	.vidioc_g_input			= vivid_g_input,
+	.vidioc_s_input			= vivid_s_input,
+	.vidioc_s_audio			= vidioc_s_audio,
+	.vidioc_g_audio			= vidioc_g_audio,
+	.vidioc_enumaudio		= vidioc_enumaudio,
+	.vidioc_s_frequency		= vidioc_s_frequency,
+	.vidioc_g_frequency		= vidioc_g_frequency,
+	.vidioc_s_tuner			= vidioc_s_tuner,
+	.vidioc_g_tuner			= vidioc_g_tuner,
+	.vidioc_s_modulator		= vidioc_s_modulator,
+	.vidioc_g_modulator		= vidioc_g_modulator,
+	.vidioc_s_hw_freq_seek		= vidioc_s_hw_freq_seek,
+	.vidioc_enum_freq_bands		= vidioc_enum_freq_bands,
+
+	.vidioc_enum_output		= vidioc_enum_output,
+	.vidioc_g_output		= vidioc_g_output,
+	.vidioc_s_output		= vidioc_s_output,
+	.vidioc_s_audout		= vidioc_s_audout,
+	.vidioc_g_audout		= vidioc_g_audout,
+	.vidioc_enumaudout		= vidioc_enumaudout,
+
+	.vidioc_querystd		= vidioc_querystd,
+	.vidioc_g_std			= vidioc_g_std,
+	.vidioc_s_std			= vidioc_s_std,
+	.vidioc_s_dv_timings		= vidioc_s_dv_timings,
+	.vidioc_g_dv_timings		= vidioc_g_dv_timings,
+	.vidioc_query_dv_timings	= vidioc_query_dv_timings,
+	.vidioc_enum_dv_timings		= vidioc_enum_dv_timings,
+	.vidioc_dv_timings_cap		= vidioc_dv_timings_cap,
+	.vidioc_g_edid			= vidioc_g_edid,
+	.vidioc_s_edid			= vidioc_s_edid,
+
+	.vidioc_log_status		= vidioc_log_status,
+	.vidioc_subscribe_event		= vidioc_subscribe_event,
+	.vidioc_unsubscribe_event	= v4l2_event_unsubscribe,
+
+	.vidioc_enum_fmt_meta_cap	= vidioc_enum_fmt_meta_cap,
+	.vidioc_g_fmt_meta_cap		= vidioc_g_fmt_meta_cap,
+	.vidioc_s_fmt_meta_cap		= vidioc_g_fmt_meta_cap,
+	.vidioc_try_fmt_meta_cap	= vidioc_g_fmt_meta_cap,
+
+	.vidioc_enum_fmt_meta_out       = vidioc_enum_fmt_meta_out,
+	.vidioc_g_fmt_meta_out          = vidioc_g_fmt_meta_out,
+	.vidioc_s_fmt_meta_out          = vidioc_g_fmt_meta_out,
+	.vidioc_try_fmt_meta_out        = vidioc_g_fmt_meta_out,
+};
+
+/* -----------------------------------------------------------------
+	Initialization and module stuff
+   ------------------------------------------------------------------*/
+
+static void vivid_dev_release(struct v4l2_device *v4l2_dev)
+{
+	struct vivid_dev *dev = container_of(v4l2_dev, struct vivid_dev, v4l2_dev);
+
+	vivid_free_controls(dev);
+	v4l2_device_unregister(&dev->v4l2_dev);
+#ifdef CONFIG_MEDIA_CONTROLLER
+	media_device_cleanup(&dev->mdev);
+#endif
+	vfree(dev->scaled_line);
+	vfree(dev->blended_line);
+	vfree(dev->edid);
+	vfree(dev->bitmap_cap);
+	vfree(dev->bitmap_out);
+	tpg_free(&dev->tpg);
+	kfree(dev->query_dv_timings_qmenu);
+	kfree(dev->query_dv_timings_qmenu_strings);
+	kfree(dev);
+}
+
+#ifdef CONFIG_MEDIA_CONTROLLER
+static int vivid_req_validate(struct media_request *req)
+{
+	struct vivid_dev *dev = container_of(req->mdev, struct vivid_dev, mdev);
+
+	if (dev->req_validate_error) {
+		dev->req_validate_error = false;
+		return -EINVAL;
+	}
+	return vb2_request_validate(req);
+}
+
+static const struct media_device_ops vivid_media_ops = {
+	.req_validate = vivid_req_validate,
+	.req_queue = vb2_request_queue,
+};
+#endif
+
+static int vivid_create_queue(struct vivid_dev *dev,
+			      struct vb2_queue *q,
+			      u32 buf_type,
+			      unsigned int min_buffers_needed,
+			      const struct vb2_ops *ops)
+{
+	if (buf_type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->multiplanar)
+		buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+	else if (buf_type == V4L2_BUF_TYPE_VIDEO_OUTPUT && dev->multiplanar)
+		buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+	else if (buf_type == V4L2_BUF_TYPE_VBI_CAPTURE && !dev->has_raw_vbi_cap)
+		buf_type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
+	else if (buf_type == V4L2_BUF_TYPE_VBI_OUTPUT && !dev->has_raw_vbi_out)
+		buf_type = V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
+
+	q->type = buf_type;
+	q->io_modes = VB2_MMAP | VB2_DMABUF;
+	q->io_modes |= V4L2_TYPE_IS_OUTPUT(buf_type) ?  VB2_WRITE : VB2_READ;
+	if (allocators[dev->inst] != 1)
+		q->io_modes |= VB2_USERPTR;
+	q->drv_priv = dev;
+	q->buf_struct_size = sizeof(struct vivid_buffer);
+	q->ops = ops;
+	q->mem_ops = allocators[dev->inst] == 1 ? &vb2_dma_contig_memops :
+						  &vb2_vmalloc_memops;
+	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+	q->min_buffers_needed = min_buffers_needed;
+	q->lock = &dev->mutex;
+	q->dev = dev->v4l2_dev.dev;
+	q->supports_requests = true;
+
+	return vb2_queue_init(q);
+}
+
+static int vivid_create_instance(struct platform_device *pdev, int inst)
+{
+	static const struct v4l2_dv_timings def_dv_timings =
+					V4L2_DV_BT_CEA_1280X720P60;
+	unsigned in_type_counter[4] = { 0, 0, 0, 0 };
+	unsigned out_type_counter[4] = { 0, 0, 0, 0 };
+	int ccs_cap = ccs_cap_mode[inst];
+	int ccs_out = ccs_out_mode[inst];
+	bool has_tuner;
+	bool has_modulator;
+	struct vivid_dev *dev;
+	struct video_device *vfd;
+	unsigned node_type = node_types[inst];
+	v4l2_std_id tvnorms_cap = 0, tvnorms_out = 0;
+	int ret;
+	int i;
+#ifdef CONFIG_VIDEO_VIVID_CEC
+	unsigned int cec_tx_bus_cnt = 0;
+#endif
+
+	/* allocate main vivid state structure */
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	if (!dev)
+		return -ENOMEM;
+
+	dev->inst = inst;
+
+#ifdef CONFIG_MEDIA_CONTROLLER
+	dev->v4l2_dev.mdev = &dev->mdev;
+
+	/* Initialize media device */
+	strscpy(dev->mdev.model, VIVID_MODULE_NAME, sizeof(dev->mdev.model));
+	snprintf(dev->mdev.bus_info, sizeof(dev->mdev.bus_info),
+		 "platform:%s-%03d", VIVID_MODULE_NAME, inst);
+	dev->mdev.dev = &pdev->dev;
+	media_device_init(&dev->mdev);
+	dev->mdev.ops = &vivid_media_ops;
+#endif
+
+	/* register v4l2_device */
+	snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name),
+			"%s-%03d", VIVID_MODULE_NAME, inst);
+	ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
+	if (ret) {
+		kfree(dev);
+		return ret;
+	}
+	dev->v4l2_dev.release = vivid_dev_release;
+
+	/* start detecting feature set */
+
+	/* do we use single- or multi-planar? */
+	dev->multiplanar = multiplanar[inst] > 1;
+	v4l2_info(&dev->v4l2_dev, "using %splanar format API\n",
+			dev->multiplanar ? "multi" : "single ");
+
+	/* how many inputs do we have and of what type? */
+	dev->num_inputs = num_inputs[inst];
+	if (dev->num_inputs < 1)
+		dev->num_inputs = 1;
+	if (dev->num_inputs >= MAX_INPUTS)
+		dev->num_inputs = MAX_INPUTS;
+	for (i = 0; i < dev->num_inputs; i++) {
+		dev->input_type[i] = (input_types[inst] >> (i * 2)) & 0x3;
+		dev->input_name_counter[i] = in_type_counter[dev->input_type[i]]++;
+	}
+	dev->has_audio_inputs = in_type_counter[TV] && in_type_counter[SVID];
+	if (in_type_counter[HDMI] == 16) {
+		/* The CEC physical address only allows for max 15 inputs */
+		in_type_counter[HDMI]--;
+		dev->num_inputs--;
+	}
+	dev->num_hdmi_inputs = in_type_counter[HDMI];
+
+	/* how many outputs do we have and of what type? */
+	dev->num_outputs = num_outputs[inst];
+	if (dev->num_outputs < 1)
+		dev->num_outputs = 1;
+	if (dev->num_outputs >= MAX_OUTPUTS)
+		dev->num_outputs = MAX_OUTPUTS;
+	for (i = 0; i < dev->num_outputs; i++) {
+		dev->output_type[i] = ((output_types[inst] >> i) & 1) ? HDMI : SVID;
+		dev->output_name_counter[i] = out_type_counter[dev->output_type[i]]++;
+		dev->display_present[i] = true;
+	}
+	dev->has_audio_outputs = out_type_counter[SVID];
+	if (out_type_counter[HDMI] == 16) {
+		/*
+		 * The CEC physical address only allows for max 15 inputs,
+		 * so outputs are also limited to 15 to allow for easy
+		 * CEC output to input mapping.
+		 */
+		out_type_counter[HDMI]--;
+		dev->num_outputs--;
+	}
+	dev->num_hdmi_outputs = out_type_counter[HDMI];
+
+	/* do we create a video capture device? */
+	dev->has_vid_cap = node_type & 0x0001;
+
+	/* do we create a vbi capture device? */
+	if (in_type_counter[TV] || in_type_counter[SVID]) {
+		dev->has_raw_vbi_cap = node_type & 0x0004;
+		dev->has_sliced_vbi_cap = node_type & 0x0008;
+		dev->has_vbi_cap = dev->has_raw_vbi_cap | dev->has_sliced_vbi_cap;
+	}
+
+	/* do we create a meta capture device */
+	dev->has_meta_cap = node_type & 0x20000;
+
+	/* sanity checks */
+	if ((in_type_counter[WEBCAM] || in_type_counter[HDMI]) &&
+	    !dev->has_vid_cap && !dev->has_meta_cap) {
+		v4l2_warn(&dev->v4l2_dev,
+			  "Webcam or HDMI input without video or metadata nodes\n");
+		kfree(dev);
+		return -EINVAL;
+	}
+	if ((in_type_counter[TV] || in_type_counter[SVID]) &&
+	    !dev->has_vid_cap && !dev->has_vbi_cap && !dev->has_meta_cap) {
+		v4l2_warn(&dev->v4l2_dev,
+			  "TV or S-Video input without video, VBI or metadata nodes\n");
+		kfree(dev);
+		return -EINVAL;
+	}
+
+	/* do we create a video output device? */
+	dev->has_vid_out = node_type & 0x0100;
+
+	/* do we create a vbi output device? */
+	if (out_type_counter[SVID]) {
+		dev->has_raw_vbi_out = node_type & 0x0400;
+		dev->has_sliced_vbi_out = node_type & 0x0800;
+		dev->has_vbi_out = dev->has_raw_vbi_out | dev->has_sliced_vbi_out;
+	}
+
+	/* do we create a metadata output device */
+	dev->has_meta_out = node_type & 0x40000;
+
+	/* sanity checks */
+	if (out_type_counter[SVID] &&
+	    !dev->has_vid_out && !dev->has_vbi_out && !dev->has_meta_out) {
+		v4l2_warn(&dev->v4l2_dev,
+			  "S-Video output without video, VBI or metadata nodes\n");
+		kfree(dev);
+		return -EINVAL;
+	}
+	if (out_type_counter[HDMI] && !dev->has_vid_out && !dev->has_meta_out) {
+		v4l2_warn(&dev->v4l2_dev,
+			  "HDMI output without video or metadata nodes\n");
+		kfree(dev);
+		return -EINVAL;
+	}
+
+	/* do we create a radio receiver device? */
+	dev->has_radio_rx = node_type & 0x0010;
+
+	/* do we create a radio transmitter device? */
+	dev->has_radio_tx = node_type & 0x1000;
+
+	/* do we create a software defined radio capture device? */
+	dev->has_sdr_cap = node_type & 0x0020;
+
+	/* do we have a TV tuner? */
+	dev->has_tv_tuner = in_type_counter[TV];
+
+	/* do we have a tuner? */
+	has_tuner = ((dev->has_vid_cap || dev->has_vbi_cap) && in_type_counter[TV]) ||
+		    dev->has_radio_rx || dev->has_sdr_cap;
+
+	/* do we have a modulator? */
+	has_modulator = dev->has_radio_tx;
+
+	if (dev->has_vid_cap)
+		/* do we have a framebuffer for overlay testing? */
+		dev->has_fb = node_type & 0x10000;
+
+	/* can we do crop/compose/scaling while capturing? */
+	if (no_error_inj && ccs_cap == -1)
+		ccs_cap = 7;
+
+	/* if ccs_cap == -1, then the user can select it using controls */
+	if (ccs_cap != -1) {
+		dev->has_crop_cap = ccs_cap & 1;
+		dev->has_compose_cap = ccs_cap & 2;
+		dev->has_scaler_cap = ccs_cap & 4;
+		v4l2_info(&dev->v4l2_dev, "Capture Crop: %c Compose: %c Scaler: %c\n",
+			dev->has_crop_cap ? 'Y' : 'N',
+			dev->has_compose_cap ? 'Y' : 'N',
+			dev->has_scaler_cap ? 'Y' : 'N');
+	}
+
+	/* can we do crop/compose/scaling with video output? */
+	if (no_error_inj && ccs_out == -1)
+		ccs_out = 7;
+
+	/* if ccs_out == -1, then the user can select it using controls */
+	if (ccs_out != -1) {
+		dev->has_crop_out = ccs_out & 1;
+		dev->has_compose_out = ccs_out & 2;
+		dev->has_scaler_out = ccs_out & 4;
+		v4l2_info(&dev->v4l2_dev, "Output Crop: %c Compose: %c Scaler: %c\n",
+			dev->has_crop_out ? 'Y' : 'N',
+			dev->has_compose_out ? 'Y' : 'N',
+			dev->has_scaler_out ? 'Y' : 'N');
+	}
+
+	/* do we create a touch capture device */
+	dev->has_touch_cap = node_type & 0x80000;
+
+	/* end detecting feature set */
+
+	if (dev->has_vid_cap) {
+		/* set up the capabilities of the video capture device */
+		dev->vid_cap_caps = dev->multiplanar ?
+			V4L2_CAP_VIDEO_CAPTURE_MPLANE :
+			V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OVERLAY;
+		dev->vid_cap_caps |= V4L2_CAP_STREAMING | V4L2_CAP_READWRITE;
+		if (dev->has_audio_inputs)
+			dev->vid_cap_caps |= V4L2_CAP_AUDIO;
+		if (dev->has_tv_tuner)
+			dev->vid_cap_caps |= V4L2_CAP_TUNER;
+	}
+	if (dev->has_vid_out) {
+		/* set up the capabilities of the video output device */
+		dev->vid_out_caps = dev->multiplanar ?
+			V4L2_CAP_VIDEO_OUTPUT_MPLANE :
+			V4L2_CAP_VIDEO_OUTPUT;
+		if (dev->has_fb)
+			dev->vid_out_caps |= V4L2_CAP_VIDEO_OUTPUT_OVERLAY;
+		dev->vid_out_caps |= V4L2_CAP_STREAMING | V4L2_CAP_READWRITE;
+		if (dev->has_audio_outputs)
+			dev->vid_out_caps |= V4L2_CAP_AUDIO;
+	}
+	if (dev->has_vbi_cap) {
+		/* set up the capabilities of the vbi capture device */
+		dev->vbi_cap_caps = (dev->has_raw_vbi_cap ? V4L2_CAP_VBI_CAPTURE : 0) |
+				    (dev->has_sliced_vbi_cap ? V4L2_CAP_SLICED_VBI_CAPTURE : 0);
+		dev->vbi_cap_caps |= V4L2_CAP_STREAMING | V4L2_CAP_READWRITE;
+		if (dev->has_audio_inputs)
+			dev->vbi_cap_caps |= V4L2_CAP_AUDIO;
+		if (dev->has_tv_tuner)
+			dev->vbi_cap_caps |= V4L2_CAP_TUNER;
+	}
+	if (dev->has_vbi_out) {
+		/* set up the capabilities of the vbi output device */
+		dev->vbi_out_caps = (dev->has_raw_vbi_out ? V4L2_CAP_VBI_OUTPUT : 0) |
+				    (dev->has_sliced_vbi_out ? V4L2_CAP_SLICED_VBI_OUTPUT : 0);
+		dev->vbi_out_caps |= V4L2_CAP_STREAMING | V4L2_CAP_READWRITE;
+		if (dev->has_audio_outputs)
+			dev->vbi_out_caps |= V4L2_CAP_AUDIO;
+	}
+	if (dev->has_sdr_cap) {
+		/* set up the capabilities of the sdr capture device */
+		dev->sdr_cap_caps = V4L2_CAP_SDR_CAPTURE | V4L2_CAP_TUNER;
+		dev->sdr_cap_caps |= V4L2_CAP_STREAMING | V4L2_CAP_READWRITE;
+	}
+	/* set up the capabilities of the radio receiver device */
+	if (dev->has_radio_rx)
+		dev->radio_rx_caps = V4L2_CAP_RADIO | V4L2_CAP_RDS_CAPTURE |
+				     V4L2_CAP_HW_FREQ_SEEK | V4L2_CAP_TUNER |
+				     V4L2_CAP_READWRITE;
+	/* set up the capabilities of the radio transmitter device */
+	if (dev->has_radio_tx)
+		dev->radio_tx_caps = V4L2_CAP_RDS_OUTPUT | V4L2_CAP_MODULATOR |
+				     V4L2_CAP_READWRITE;
+
+	/* set up the capabilities of meta capture device */
+	if (dev->has_meta_cap) {
+		dev->meta_cap_caps = V4L2_CAP_META_CAPTURE |
+				     V4L2_CAP_STREAMING | V4L2_CAP_READWRITE;
+		if (dev->has_audio_inputs)
+			dev->meta_cap_caps |= V4L2_CAP_AUDIO;
+		if (dev->has_tv_tuner)
+			dev->meta_cap_caps |= V4L2_CAP_TUNER;
+	}
+	/* set up the capabilities of meta output device */
+	if (dev->has_meta_out) {
+		dev->meta_out_caps = V4L2_CAP_META_OUTPUT |
+				     V4L2_CAP_STREAMING | V4L2_CAP_READWRITE;
+		if (dev->has_audio_outputs)
+			dev->meta_out_caps |= V4L2_CAP_AUDIO;
+	}
+	/* set up the capabilities of the touch capture device */
+	if (dev->has_touch_cap) {
+		dev->touch_cap_caps = V4L2_CAP_TOUCH | V4L2_CAP_STREAMING |
+				      V4L2_CAP_READWRITE;
+		dev->touch_cap_caps |= dev->multiplanar ?
+			V4L2_CAP_VIDEO_CAPTURE_MPLANE : V4L2_CAP_VIDEO_CAPTURE;
+	}
+
+	ret = -ENOMEM;
+	/* initialize the test pattern generator */
+	tpg_init(&dev->tpg, 640, 360);
+	if (tpg_alloc(&dev->tpg, MAX_ZOOM * MAX_WIDTH))
+		goto free_dev;
+	dev->scaled_line = vzalloc(array_size(MAX_WIDTH, MAX_ZOOM));
+	if (!dev->scaled_line)
+		goto free_dev;
+	dev->blended_line = vzalloc(array_size(MAX_WIDTH, MAX_ZOOM));
+	if (!dev->blended_line)
+		goto free_dev;
+
+	/* load the edid */
+	dev->edid = vmalloc(256 * 128);
+	if (!dev->edid)
+		goto free_dev;
+
+	while (v4l2_dv_timings_presets[dev->query_dv_timings_size].bt.width)
+		dev->query_dv_timings_size++;
+
+	/*
+	 * Create a char pointer array that points to the names of all the
+	 * preset timings
+	 */
+	dev->query_dv_timings_qmenu = kmalloc_array(dev->query_dv_timings_size,
+						    sizeof(char *), GFP_KERNEL);
+	/*
+	 * Create a string array containing the names of all the preset
+	 * timings. Each name is max 31 chars long (+ terminating 0).
+	 */
+	dev->query_dv_timings_qmenu_strings =
+		kmalloc_array(dev->query_dv_timings_size, 32, GFP_KERNEL);
+
+	if (!dev->query_dv_timings_qmenu ||
+	    !dev->query_dv_timings_qmenu_strings)
+		goto free_dev;
+
+	for (i = 0; i < dev->query_dv_timings_size; i++) {
+		const struct v4l2_bt_timings *bt = &v4l2_dv_timings_presets[i].bt;
+		char *p = dev->query_dv_timings_qmenu_strings + i * 32;
+		u32 htot, vtot;
+
+		dev->query_dv_timings_qmenu[i] = p;
+
+		htot = V4L2_DV_BT_FRAME_WIDTH(bt);
+		vtot = V4L2_DV_BT_FRAME_HEIGHT(bt);
+		snprintf(p, 32, "%ux%u%s%u",
+			bt->width, bt->height, bt->interlaced ? "i" : "p",
+			(u32)bt->pixelclock / (htot * vtot));
+	}
+
+	/* disable invalid ioctls based on the feature set */
+	if (!dev->has_audio_inputs) {
+		v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_S_AUDIO);
+		v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_G_AUDIO);
+		v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_ENUMAUDIO);
+		v4l2_disable_ioctl(&dev->vbi_cap_dev, VIDIOC_S_AUDIO);
+		v4l2_disable_ioctl(&dev->vbi_cap_dev, VIDIOC_G_AUDIO);
+		v4l2_disable_ioctl(&dev->vbi_cap_dev, VIDIOC_ENUMAUDIO);
+		v4l2_disable_ioctl(&dev->meta_cap_dev, VIDIOC_S_AUDIO);
+		v4l2_disable_ioctl(&dev->meta_cap_dev, VIDIOC_G_AUDIO);
+		v4l2_disable_ioctl(&dev->meta_cap_dev, VIDIOC_ENUMAUDIO);
+	}
+	if (!dev->has_audio_outputs) {
+		v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_S_AUDOUT);
+		v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_G_AUDOUT);
+		v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_ENUMAUDOUT);
+		v4l2_disable_ioctl(&dev->vbi_out_dev, VIDIOC_S_AUDOUT);
+		v4l2_disable_ioctl(&dev->vbi_out_dev, VIDIOC_G_AUDOUT);
+		v4l2_disable_ioctl(&dev->vbi_out_dev, VIDIOC_ENUMAUDOUT);
+		v4l2_disable_ioctl(&dev->meta_out_dev, VIDIOC_S_AUDOUT);
+		v4l2_disable_ioctl(&dev->meta_out_dev, VIDIOC_G_AUDOUT);
+		v4l2_disable_ioctl(&dev->meta_out_dev, VIDIOC_ENUMAUDOUT);
+	}
+	if (!in_type_counter[TV] && !in_type_counter[SVID]) {
+		v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_S_STD);
+		v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_G_STD);
+		v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_ENUMSTD);
+		v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_QUERYSTD);
+	}
+	if (!out_type_counter[SVID]) {
+		v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_S_STD);
+		v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_G_STD);
+		v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_ENUMSTD);
+	}
+	if (!has_tuner && !has_modulator) {
+		v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_S_FREQUENCY);
+		v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_G_FREQUENCY);
+		v4l2_disable_ioctl(&dev->vbi_cap_dev, VIDIOC_S_FREQUENCY);
+		v4l2_disable_ioctl(&dev->vbi_cap_dev, VIDIOC_G_FREQUENCY);
+		v4l2_disable_ioctl(&dev->meta_cap_dev, VIDIOC_S_FREQUENCY);
+		v4l2_disable_ioctl(&dev->meta_cap_dev, VIDIOC_G_FREQUENCY);
+	}
+	if (!has_tuner) {
+		v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_S_TUNER);
+		v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_G_TUNER);
+		v4l2_disable_ioctl(&dev->vbi_cap_dev, VIDIOC_S_TUNER);
+		v4l2_disable_ioctl(&dev->vbi_cap_dev, VIDIOC_G_TUNER);
+		v4l2_disable_ioctl(&dev->meta_cap_dev, VIDIOC_S_TUNER);
+		v4l2_disable_ioctl(&dev->meta_cap_dev, VIDIOC_G_TUNER);
+	}
+	if (in_type_counter[HDMI] == 0) {
+		v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_S_EDID);
+		v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_G_EDID);
+		v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_DV_TIMINGS_CAP);
+		v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_G_DV_TIMINGS);
+		v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_S_DV_TIMINGS);
+		v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_ENUM_DV_TIMINGS);
+		v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_QUERY_DV_TIMINGS);
+	}
+	if (out_type_counter[HDMI] == 0) {
+		v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_G_EDID);
+		v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_DV_TIMINGS_CAP);
+		v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_G_DV_TIMINGS);
+		v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_S_DV_TIMINGS);
+		v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_ENUM_DV_TIMINGS);
+	}
+	if (!dev->has_fb) {
+		v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_G_FBUF);
+		v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_S_FBUF);
+		v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_OVERLAY);
+	}
+	v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_S_HW_FREQ_SEEK);
+	v4l2_disable_ioctl(&dev->vbi_cap_dev, VIDIOC_S_HW_FREQ_SEEK);
+	v4l2_disable_ioctl(&dev->sdr_cap_dev, VIDIOC_S_HW_FREQ_SEEK);
+	v4l2_disable_ioctl(&dev->meta_cap_dev, VIDIOC_S_HW_FREQ_SEEK);
+	v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_S_FREQUENCY);
+	v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_G_FREQUENCY);
+	v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_ENUM_FRAMESIZES);
+	v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_ENUM_FRAMEINTERVALS);
+	v4l2_disable_ioctl(&dev->vbi_out_dev, VIDIOC_S_FREQUENCY);
+	v4l2_disable_ioctl(&dev->vbi_out_dev, VIDIOC_G_FREQUENCY);
+	v4l2_disable_ioctl(&dev->meta_out_dev, VIDIOC_S_FREQUENCY);
+	v4l2_disable_ioctl(&dev->meta_out_dev, VIDIOC_G_FREQUENCY);
+	v4l2_disable_ioctl(&dev->touch_cap_dev, VIDIOC_S_PARM);
+	v4l2_disable_ioctl(&dev->touch_cap_dev, VIDIOC_ENUM_FRAMESIZES);
+	v4l2_disable_ioctl(&dev->touch_cap_dev, VIDIOC_ENUM_FRAMEINTERVALS);
+
+	/* configure internal data */
+	dev->fmt_cap = &vivid_formats[0];
+	dev->fmt_out = &vivid_formats[0];
+	if (!dev->multiplanar)
+		vivid_formats[0].data_offset[0] = 0;
+	dev->webcam_size_idx = 1;
+	dev->webcam_ival_idx = 3;
+	tpg_s_fourcc(&dev->tpg, dev->fmt_cap->fourcc);
+	dev->std_out = V4L2_STD_PAL;
+	if (dev->input_type[0] == TV || dev->input_type[0] == SVID)
+		tvnorms_cap = V4L2_STD_ALL;
+	if (dev->output_type[0] == SVID)
+		tvnorms_out = V4L2_STD_ALL;
+	for (i = 0; i < MAX_INPUTS; i++) {
+		dev->dv_timings_cap[i] = def_dv_timings;
+		dev->std_cap[i] = V4L2_STD_PAL;
+	}
+	dev->dv_timings_out = def_dv_timings;
+	dev->tv_freq = 2804 /* 175.25 * 16 */;
+	dev->tv_audmode = V4L2_TUNER_MODE_STEREO;
+	dev->tv_field_cap = V4L2_FIELD_INTERLACED;
+	dev->tv_field_out = V4L2_FIELD_INTERLACED;
+	dev->radio_rx_freq = 95000 * 16;
+	dev->radio_rx_audmode = V4L2_TUNER_MODE_STEREO;
+	if (dev->has_radio_tx) {
+		dev->radio_tx_freq = 95500 * 16;
+		dev->radio_rds_loop = false;
+	}
+	dev->radio_tx_subchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_RDS;
+	dev->sdr_adc_freq = 300000;
+	dev->sdr_fm_freq = 50000000;
+	dev->sdr_pixelformat = V4L2_SDR_FMT_CU8;
+	dev->sdr_buffersize = SDR_CAP_SAMPLES_PER_BUF * 2;
+
+	dev->edid_max_blocks = dev->edid_blocks = 2;
+	memcpy(dev->edid, vivid_hdmi_edid, sizeof(vivid_hdmi_edid));
+	dev->radio_rds_init_time = ktime_get();
+
+	/* create all controls */
+	ret = vivid_create_controls(dev, ccs_cap == -1, ccs_out == -1, no_error_inj,
+			in_type_counter[TV] || in_type_counter[SVID] ||
+			out_type_counter[SVID],
+			in_type_counter[HDMI] || out_type_counter[HDMI]);
+	if (ret)
+		goto unreg_dev;
+
+	/* enable/disable interface specific controls */
+	if (dev->num_outputs && dev->output_type[0] != HDMI)
+		v4l2_ctrl_activate(dev->ctrl_display_present, false);
+	if (dev->num_inputs && dev->input_type[0] != HDMI) {
+		v4l2_ctrl_activate(dev->ctrl_dv_timings_signal_mode, false);
+		v4l2_ctrl_activate(dev->ctrl_dv_timings, false);
+	} else if (dev->num_inputs && dev->input_type[0] == HDMI) {
+		v4l2_ctrl_activate(dev->ctrl_std_signal_mode, false);
+		v4l2_ctrl_activate(dev->ctrl_standard, false);
+	}
+
+	/*
+	 * update the capture and output formats to do a proper initial
+	 * configuration.
+	 */
+	vivid_update_format_cap(dev, false);
+	vivid_update_format_out(dev);
+
+	/* initialize overlay */
+	dev->fb_cap.fmt.width = dev->src_rect.width;
+	dev->fb_cap.fmt.height = dev->src_rect.height;
+	dev->fb_cap.fmt.pixelformat = dev->fmt_cap->fourcc;
+	dev->fb_cap.fmt.bytesperline = dev->src_rect.width * tpg_g_twopixelsize(&dev->tpg, 0) / 2;
+	dev->fb_cap.fmt.sizeimage = dev->src_rect.height * dev->fb_cap.fmt.bytesperline;
+
+	/* update touch configuration */
+	dev->timeperframe_tch_cap.numerator = 1;
+	dev->timeperframe_tch_cap.denominator = 10;
+	vivid_set_touch(dev, 0);
+
+	/* initialize locks */
+	spin_lock_init(&dev->slock);
+	mutex_init(&dev->mutex);
+
+	/* init dma queues */
+	INIT_LIST_HEAD(&dev->vid_cap_active);
+	INIT_LIST_HEAD(&dev->vid_out_active);
+	INIT_LIST_HEAD(&dev->vbi_cap_active);
+	INIT_LIST_HEAD(&dev->vbi_out_active);
+	INIT_LIST_HEAD(&dev->sdr_cap_active);
+	INIT_LIST_HEAD(&dev->meta_cap_active);
+	INIT_LIST_HEAD(&dev->meta_out_active);
+	INIT_LIST_HEAD(&dev->touch_cap_active);
+
+	INIT_LIST_HEAD(&dev->cec_work_list);
+	spin_lock_init(&dev->cec_slock);
+	/*
+	 * Same as create_singlethread_workqueue, but now I can use the
+	 * string formatting of alloc_ordered_workqueue.
+	 */
+	dev->cec_workqueue =
+		alloc_ordered_workqueue("vivid-%03d-cec", WQ_MEM_RECLAIM, inst);
+	if (!dev->cec_workqueue) {
+		ret = -ENOMEM;
+		goto unreg_dev;
+	}
+
+	if (allocators[inst] == 1)
+		dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+
+	/* start creating the vb2 queues */
+	if (dev->has_vid_cap) {
+		/* initialize vid_cap queue */
+		ret = vivid_create_queue(dev, &dev->vb_vid_cap_q,
+					 V4L2_BUF_TYPE_VIDEO_CAPTURE, 2,
+					 &vivid_vid_cap_qops);
+		if (ret)
+			goto unreg_dev;
+	}
+
+	if (dev->has_vid_out) {
+		/* initialize vid_out queue */
+		ret = vivid_create_queue(dev, &dev->vb_vid_out_q,
+					 V4L2_BUF_TYPE_VIDEO_OUTPUT, 2,
+					 &vivid_vid_out_qops);
+		if (ret)
+			goto unreg_dev;
+	}
+
+	if (dev->has_vbi_cap) {
+		/* initialize vbi_cap queue */
+		ret = vivid_create_queue(dev, &dev->vb_vbi_cap_q,
+					 V4L2_BUF_TYPE_VBI_CAPTURE, 2,
+					 &vivid_vbi_cap_qops);
+		if (ret)
+			goto unreg_dev;
+	}
+
+	if (dev->has_vbi_out) {
+		/* initialize vbi_out queue */
+		ret = vivid_create_queue(dev, &dev->vb_vbi_out_q,
+					 V4L2_BUF_TYPE_VBI_OUTPUT, 2,
+					 &vivid_vbi_out_qops);
+		if (ret)
+			goto unreg_dev;
+	}
+
+	if (dev->has_sdr_cap) {
+		/* initialize sdr_cap queue */
+		ret = vivid_create_queue(dev, &dev->vb_sdr_cap_q,
+					 V4L2_BUF_TYPE_SDR_CAPTURE, 8,
+					 &vivid_sdr_cap_qops);
+		if (ret)
+			goto unreg_dev;
+	}
+
+	if (dev->has_meta_cap) {
+		/* initialize meta_cap queue */
+		ret = vivid_create_queue(dev, &dev->vb_meta_cap_q,
+					 V4L2_BUF_TYPE_META_CAPTURE, 2,
+					 &vivid_meta_cap_qops);
+		if (ret)
+			goto unreg_dev;
+	}
+
+	if (dev->has_meta_out) {
+		/* initialize meta_out queue */
+		ret = vivid_create_queue(dev, &dev->vb_meta_out_q,
+					 V4L2_BUF_TYPE_META_OUTPUT, 1,
+					 &vivid_meta_out_qops);
+		if (ret)
+			goto unreg_dev;
+	}
+
+	if (dev->has_touch_cap) {
+		/* initialize touch_cap queue */
+		ret = vivid_create_queue(dev, &dev->vb_touch_cap_q,
+					 V4L2_BUF_TYPE_VIDEO_CAPTURE, 1,
+					 &vivid_touch_cap_qops);
+		if (ret)
+			goto unreg_dev;
+	}
+
+	if (dev->has_fb) {
+		/* Create framebuffer for testing capture/output overlay */
+		ret = vivid_fb_init(dev);
+		if (ret)
+			goto unreg_dev;
+		v4l2_info(&dev->v4l2_dev, "Framebuffer device registered as fb%d\n",
+			  dev->fb_info.node);
+	}
+
+#ifdef CONFIG_VIDEO_VIVID_CEC
+	if (dev->has_vid_cap && in_type_counter[HDMI]) {
+		struct cec_adapter *adap;
+
+		adap = vivid_cec_alloc_adap(dev, 0, false);
+		ret = PTR_ERR_OR_ZERO(adap);
+		if (ret < 0)
+			goto unreg_dev;
+		dev->cec_rx_adap = adap;
+	}
+
+	if (dev->has_vid_out) {
+		for (i = 0; i < dev->num_outputs; i++) {
+			struct cec_adapter *adap;
+
+			if (dev->output_type[i] != HDMI)
+				continue;
+
+			dev->cec_output2bus_map[i] = cec_tx_bus_cnt;
+			adap = vivid_cec_alloc_adap(dev, cec_tx_bus_cnt, true);
+			ret = PTR_ERR_OR_ZERO(adap);
+			if (ret < 0) {
+				for (i = 0; i < dev->num_outputs; i++)
+					cec_delete_adapter(dev->cec_tx_adap[i]);
+				goto unreg_dev;
+			}
+
+			dev->cec_tx_adap[cec_tx_bus_cnt] = adap;
+			cec_tx_bus_cnt++;
+		}
+	}
+#endif
+
+	v4l2_ctrl_handler_setup(&dev->ctrl_hdl_vid_cap);
+	v4l2_ctrl_handler_setup(&dev->ctrl_hdl_vid_out);
+	v4l2_ctrl_handler_setup(&dev->ctrl_hdl_vbi_cap);
+	v4l2_ctrl_handler_setup(&dev->ctrl_hdl_vbi_out);
+	v4l2_ctrl_handler_setup(&dev->ctrl_hdl_radio_rx);
+	v4l2_ctrl_handler_setup(&dev->ctrl_hdl_radio_tx);
+	v4l2_ctrl_handler_setup(&dev->ctrl_hdl_sdr_cap);
+	v4l2_ctrl_handler_setup(&dev->ctrl_hdl_meta_cap);
+	v4l2_ctrl_handler_setup(&dev->ctrl_hdl_meta_out);
+	v4l2_ctrl_handler_setup(&dev->ctrl_hdl_touch_cap);
+
+	/* finally start creating the device nodes */
+	if (dev->has_vid_cap) {
+		vfd = &dev->vid_cap_dev;
+		snprintf(vfd->name, sizeof(vfd->name),
+			 "vivid-%03d-vid-cap", inst);
+		vfd->fops = &vivid_fops;
+		vfd->ioctl_ops = &vivid_ioctl_ops;
+		vfd->device_caps = dev->vid_cap_caps;
+		vfd->release = video_device_release_empty;
+		vfd->v4l2_dev = &dev->v4l2_dev;
+		vfd->queue = &dev->vb_vid_cap_q;
+		vfd->tvnorms = tvnorms_cap;
+
+		/*
+		 * Provide a mutex to v4l2 core. It will be used to protect
+		 * all fops and v4l2 ioctls.
+		 */
+		vfd->lock = &dev->mutex;
+		video_set_drvdata(vfd, dev);
+
+#ifdef CONFIG_MEDIA_CONTROLLER
+		dev->vid_cap_pad.flags = MEDIA_PAD_FL_SINK;
+		ret = media_entity_pads_init(&vfd->entity, 1, &dev->vid_cap_pad);
+		if (ret)
+			goto unreg_dev;
+#endif
+
+#ifdef CONFIG_VIDEO_VIVID_CEC
+		if (in_type_counter[HDMI]) {
+			ret = cec_register_adapter(dev->cec_rx_adap, &pdev->dev);
+			if (ret < 0) {
+				cec_delete_adapter(dev->cec_rx_adap);
+				dev->cec_rx_adap = NULL;
+				goto unreg_dev;
+			}
+			cec_s_phys_addr(dev->cec_rx_adap, 0, false);
+			v4l2_info(&dev->v4l2_dev, "CEC adapter %s registered for HDMI input 0\n",
+				  dev_name(&dev->cec_rx_adap->devnode.dev));
+		}
+#endif
+
+		ret = video_register_device(vfd, VFL_TYPE_VIDEO, vid_cap_nr[inst]);
+		if (ret < 0)
+			goto unreg_dev;
+		v4l2_info(&dev->v4l2_dev, "V4L2 capture device registered as %s\n",
+					  video_device_node_name(vfd));
+	}
+
+	if (dev->has_vid_out) {
+		vfd = &dev->vid_out_dev;
+		snprintf(vfd->name, sizeof(vfd->name),
+			 "vivid-%03d-vid-out", inst);
+		vfd->vfl_dir = VFL_DIR_TX;
+		vfd->fops = &vivid_fops;
+		vfd->ioctl_ops = &vivid_ioctl_ops;
+		vfd->device_caps = dev->vid_out_caps;
+		vfd->release = video_device_release_empty;
+		vfd->v4l2_dev = &dev->v4l2_dev;
+		vfd->queue = &dev->vb_vid_out_q;
+		vfd->tvnorms = tvnorms_out;
+
+		/*
+		 * Provide a mutex to v4l2 core. It will be used to protect
+		 * all fops and v4l2 ioctls.
+		 */
+		vfd->lock = &dev->mutex;
+		video_set_drvdata(vfd, dev);
+
+#ifdef CONFIG_MEDIA_CONTROLLER
+		dev->vid_out_pad.flags = MEDIA_PAD_FL_SOURCE;
+		ret = media_entity_pads_init(&vfd->entity, 1, &dev->vid_out_pad);
+		if (ret)
+			goto unreg_dev;
+#endif
+
+#ifdef CONFIG_VIDEO_VIVID_CEC
+		for (i = 0; i < cec_tx_bus_cnt; i++) {
+			ret = cec_register_adapter(dev->cec_tx_adap[i], &pdev->dev);
+			if (ret < 0) {
+				for (; i < cec_tx_bus_cnt; i++) {
+					cec_delete_adapter(dev->cec_tx_adap[i]);
+					dev->cec_tx_adap[i] = NULL;
+				}
+				goto unreg_dev;
+			}
+			v4l2_info(&dev->v4l2_dev, "CEC adapter %s registered for HDMI output %d\n",
+				  dev_name(&dev->cec_tx_adap[i]->devnode.dev), i);
+			if (i < out_type_counter[HDMI])
+				cec_s_phys_addr(dev->cec_tx_adap[i], (i + 1) << 12, false);
+			else
+				cec_s_phys_addr(dev->cec_tx_adap[i], 0x1000, false);
+		}
+#endif
+
+		ret = video_register_device(vfd, VFL_TYPE_VIDEO, vid_out_nr[inst]);
+		if (ret < 0)
+			goto unreg_dev;
+		v4l2_info(&dev->v4l2_dev, "V4L2 output device registered as %s\n",
+					  video_device_node_name(vfd));
+	}
+
+	if (dev->has_vbi_cap) {
+		vfd = &dev->vbi_cap_dev;
+		snprintf(vfd->name, sizeof(vfd->name),
+			 "vivid-%03d-vbi-cap", inst);
+		vfd->fops = &vivid_fops;
+		vfd->ioctl_ops = &vivid_ioctl_ops;
+		vfd->device_caps = dev->vbi_cap_caps;
+		vfd->release = video_device_release_empty;
+		vfd->v4l2_dev = &dev->v4l2_dev;
+		vfd->queue = &dev->vb_vbi_cap_q;
+		vfd->lock = &dev->mutex;
+		vfd->tvnorms = tvnorms_cap;
+		video_set_drvdata(vfd, dev);
+
+#ifdef CONFIG_MEDIA_CONTROLLER
+		dev->vbi_cap_pad.flags = MEDIA_PAD_FL_SINK;
+		ret = media_entity_pads_init(&vfd->entity, 1, &dev->vbi_cap_pad);
+		if (ret)
+			goto unreg_dev;
+#endif
+
+		ret = video_register_device(vfd, VFL_TYPE_VBI, vbi_cap_nr[inst]);
+		if (ret < 0)
+			goto unreg_dev;
+		v4l2_info(&dev->v4l2_dev, "V4L2 capture device registered as %s, supports %s VBI\n",
+					  video_device_node_name(vfd),
+					  (dev->has_raw_vbi_cap && dev->has_sliced_vbi_cap) ?
+					  "raw and sliced" :
+					  (dev->has_raw_vbi_cap ? "raw" : "sliced"));
+	}
+
+	if (dev->has_vbi_out) {
+		vfd = &dev->vbi_out_dev;
+		snprintf(vfd->name, sizeof(vfd->name),
+			 "vivid-%03d-vbi-out", inst);
+		vfd->vfl_dir = VFL_DIR_TX;
+		vfd->fops = &vivid_fops;
+		vfd->ioctl_ops = &vivid_ioctl_ops;
+		vfd->device_caps = dev->vbi_out_caps;
+		vfd->release = video_device_release_empty;
+		vfd->v4l2_dev = &dev->v4l2_dev;
+		vfd->queue = &dev->vb_vbi_out_q;
+		vfd->lock = &dev->mutex;
+		vfd->tvnorms = tvnorms_out;
+		video_set_drvdata(vfd, dev);
+
+#ifdef CONFIG_MEDIA_CONTROLLER
+		dev->vbi_out_pad.flags = MEDIA_PAD_FL_SOURCE;
+		ret = media_entity_pads_init(&vfd->entity, 1, &dev->vbi_out_pad);
+		if (ret)
+			goto unreg_dev;
+#endif
+
+		ret = video_register_device(vfd, VFL_TYPE_VBI, vbi_out_nr[inst]);
+		if (ret < 0)
+			goto unreg_dev;
+		v4l2_info(&dev->v4l2_dev, "V4L2 output device registered as %s, supports %s VBI\n",
+					  video_device_node_name(vfd),
+					  (dev->has_raw_vbi_out && dev->has_sliced_vbi_out) ?
+					  "raw and sliced" :
+					  (dev->has_raw_vbi_out ? "raw" : "sliced"));
+	}
+
+	if (dev->has_sdr_cap) {
+		vfd = &dev->sdr_cap_dev;
+		snprintf(vfd->name, sizeof(vfd->name),
+			 "vivid-%03d-sdr-cap", inst);
+		vfd->fops = &vivid_fops;
+		vfd->ioctl_ops = &vivid_ioctl_ops;
+		vfd->device_caps = dev->sdr_cap_caps;
+		vfd->release = video_device_release_empty;
+		vfd->v4l2_dev = &dev->v4l2_dev;
+		vfd->queue = &dev->vb_sdr_cap_q;
+		vfd->lock = &dev->mutex;
+		video_set_drvdata(vfd, dev);
+
+#ifdef CONFIG_MEDIA_CONTROLLER
+		dev->sdr_cap_pad.flags = MEDIA_PAD_FL_SINK;
+		ret = media_entity_pads_init(&vfd->entity, 1, &dev->sdr_cap_pad);
+		if (ret)
+			goto unreg_dev;
+#endif
+
+		ret = video_register_device(vfd, VFL_TYPE_SDR, sdr_cap_nr[inst]);
+		if (ret < 0)
+			goto unreg_dev;
+		v4l2_info(&dev->v4l2_dev, "V4L2 capture device registered as %s\n",
+					  video_device_node_name(vfd));
+	}
+
+	if (dev->has_radio_rx) {
+		vfd = &dev->radio_rx_dev;
+		snprintf(vfd->name, sizeof(vfd->name),
+			 "vivid-%03d-rad-rx", inst);
+		vfd->fops = &vivid_radio_fops;
+		vfd->ioctl_ops = &vivid_ioctl_ops;
+		vfd->device_caps = dev->radio_rx_caps;
+		vfd->release = video_device_release_empty;
+		vfd->v4l2_dev = &dev->v4l2_dev;
+		vfd->lock = &dev->mutex;
+		video_set_drvdata(vfd, dev);
+
+		ret = video_register_device(vfd, VFL_TYPE_RADIO, radio_rx_nr[inst]);
+		if (ret < 0)
+			goto unreg_dev;
+		v4l2_info(&dev->v4l2_dev, "V4L2 receiver device registered as %s\n",
+					  video_device_node_name(vfd));
+	}
+
+	if (dev->has_radio_tx) {
+		vfd = &dev->radio_tx_dev;
+		snprintf(vfd->name, sizeof(vfd->name),
+			 "vivid-%03d-rad-tx", inst);
+		vfd->vfl_dir = VFL_DIR_TX;
+		vfd->fops = &vivid_radio_fops;
+		vfd->ioctl_ops = &vivid_ioctl_ops;
+		vfd->device_caps = dev->radio_tx_caps;
+		vfd->release = video_device_release_empty;
+		vfd->v4l2_dev = &dev->v4l2_dev;
+		vfd->lock = &dev->mutex;
+		video_set_drvdata(vfd, dev);
+
+		ret = video_register_device(vfd, VFL_TYPE_RADIO, radio_tx_nr[inst]);
+		if (ret < 0)
+			goto unreg_dev;
+		v4l2_info(&dev->v4l2_dev, "V4L2 transmitter device registered as %s\n",
+					  video_device_node_name(vfd));
+	}
+
+	if (dev->has_meta_cap) {
+		vfd = &dev->meta_cap_dev;
+		snprintf(vfd->name, sizeof(vfd->name),
+			 "vivid-%03d-meta-cap", inst);
+		vfd->fops = &vivid_fops;
+		vfd->ioctl_ops = &vivid_ioctl_ops;
+		vfd->device_caps = dev->meta_cap_caps;
+		vfd->release = video_device_release_empty;
+		vfd->v4l2_dev = &dev->v4l2_dev;
+		vfd->queue = &dev->vb_meta_cap_q;
+		vfd->lock = &dev->mutex;
+		vfd->tvnorms = tvnorms_cap;
+		video_set_drvdata(vfd, dev);
+#ifdef CONFIG_MEDIA_CONTROLLER
+		dev->meta_cap_pad.flags = MEDIA_PAD_FL_SINK;
+		ret = media_entity_pads_init(&vfd->entity, 1,
+					     &dev->meta_cap_pad);
+		if (ret)
+			goto unreg_dev;
+#endif
+		ret = video_register_device(vfd, VFL_TYPE_VIDEO,
+					    meta_cap_nr[inst]);
+		if (ret < 0)
+			goto unreg_dev;
+		v4l2_info(&dev->v4l2_dev,
+			  "V4L2 metadata capture device registered as %s\n",
+			  video_device_node_name(vfd));
+	}
+
+	if (dev->has_meta_out) {
+		vfd = &dev->meta_out_dev;
+		snprintf(vfd->name, sizeof(vfd->name),
+			 "vivid-%03d-meta-out", inst);
+		vfd->vfl_dir = VFL_DIR_TX;
+		vfd->fops = &vivid_fops;
+		vfd->ioctl_ops = &vivid_ioctl_ops;
+		vfd->device_caps = dev->meta_out_caps;
+		vfd->release = video_device_release_empty;
+		vfd->v4l2_dev = &dev->v4l2_dev;
+		vfd->queue = &dev->vb_meta_out_q;
+		vfd->lock = &dev->mutex;
+		vfd->tvnorms = tvnorms_out;
+		video_set_drvdata(vfd, dev);
+#ifdef CONFIG_MEDIA_CONTROLLER
+		dev->meta_out_pad.flags = MEDIA_PAD_FL_SOURCE;
+		ret = media_entity_pads_init(&vfd->entity, 1,
+					     &dev->meta_out_pad);
+		if (ret)
+			goto unreg_dev;
+#endif
+		ret = video_register_device(vfd, VFL_TYPE_VIDEO,
+					    meta_out_nr[inst]);
+		if (ret < 0)
+			goto unreg_dev;
+		v4l2_info(&dev->v4l2_dev,
+			  "V4L2 metadata output device registered as %s\n",
+			  video_device_node_name(vfd));
+	}
+
+	if (dev->has_touch_cap) {
+		vfd = &dev->touch_cap_dev;
+		snprintf(vfd->name, sizeof(vfd->name),
+			 "vivid-%03d-touch-cap", inst);
+		vfd->fops = &vivid_fops;
+		vfd->ioctl_ops = &vivid_ioctl_ops;
+		vfd->device_caps = dev->touch_cap_caps;
+		vfd->release = video_device_release_empty;
+		vfd->v4l2_dev = &dev->v4l2_dev;
+		vfd->queue = &dev->vb_touch_cap_q;
+		vfd->tvnorms = tvnorms_cap;
+		vfd->lock = &dev->mutex;
+		video_set_drvdata(vfd, dev);
+#ifdef CONFIG_MEDIA_CONTROLLER
+		dev->touch_cap_pad.flags = MEDIA_PAD_FL_SINK;
+		ret = media_entity_pads_init(&vfd->entity, 1,
+					     &dev->touch_cap_pad);
+		if (ret)
+			goto unreg_dev;
+#endif
+		ret = video_register_device(vfd, VFL_TYPE_TOUCH,
+					    touch_cap_nr[inst]);
+		if (ret < 0)
+			goto unreg_dev;
+		v4l2_info(&dev->v4l2_dev,
+			  "V4L2 touch capture device registered as %s\n",
+			  video_device_node_name(vfd));
+	}
+
+#ifdef CONFIG_MEDIA_CONTROLLER
+	/* Register the media device */
+	ret = media_device_register(&dev->mdev);
+	if (ret) {
+		dev_err(dev->mdev.dev,
+			"media device register failed (err=%d)\n", ret);
+		goto unreg_dev;
+	}
+#endif
+
+	/* Now that everything is fine, let's add it to device list */
+	vivid_devs[inst] = dev;
+
+	return 0;
+
+unreg_dev:
+	video_unregister_device(&dev->touch_cap_dev);
+	video_unregister_device(&dev->meta_out_dev);
+	video_unregister_device(&dev->meta_cap_dev);
+	video_unregister_device(&dev->radio_tx_dev);
+	video_unregister_device(&dev->radio_rx_dev);
+	video_unregister_device(&dev->sdr_cap_dev);
+	video_unregister_device(&dev->vbi_out_dev);
+	video_unregister_device(&dev->vbi_cap_dev);
+	video_unregister_device(&dev->vid_out_dev);
+	video_unregister_device(&dev->vid_cap_dev);
+	cec_unregister_adapter(dev->cec_rx_adap);
+	for (i = 0; i < MAX_OUTPUTS; i++)
+		cec_unregister_adapter(dev->cec_tx_adap[i]);
+	if (dev->cec_workqueue) {
+		vivid_cec_bus_free_work(dev);
+		destroy_workqueue(dev->cec_workqueue);
+	}
+free_dev:
+	v4l2_device_put(&dev->v4l2_dev);
+	return ret;
+}
+
+/* This routine allocates from 1 to n_devs virtual drivers.
+
+   The real maximum number of virtual drivers will depend on how many drivers
+   will succeed. This is limited to the maximum number of devices that
+   videodev supports, which is equal to VIDEO_NUM_DEVICES.
+ */
+static int vivid_probe(struct platform_device *pdev)
+{
+	const struct font_desc *font = find_font("VGA8x16");
+	int ret = 0, i;
+
+	if (font == NULL) {
+		pr_err("vivid: could not find font\n");
+		return -ENODEV;
+	}
+
+	tpg_set_font(font->data);
+
+	n_devs = clamp_t(unsigned, n_devs, 1, VIVID_MAX_DEVS);
+
+	for (i = 0; i < n_devs; i++) {
+		ret = vivid_create_instance(pdev, i);
+		if (ret) {
+			/* If some instantiations succeeded, keep driver */
+			if (i)
+				ret = 0;
+			break;
+		}
+	}
+
+	if (ret < 0) {
+		pr_err("vivid: error %d while loading driver\n", ret);
+		return ret;
+	}
+
+	/* n_devs will reflect the actual number of allocated devices */
+	n_devs = i;
+
+	return ret;
+}
+
+static int vivid_remove(struct platform_device *pdev)
+{
+	struct vivid_dev *dev;
+	unsigned int i, j;
+
+	for (i = 0; i < n_devs; i++) {
+		dev = vivid_devs[i];
+		if (!dev)
+			continue;
+
+#ifdef CONFIG_MEDIA_CONTROLLER
+		media_device_unregister(&dev->mdev);
+#endif
+
+		if (dev->has_vid_cap) {
+			v4l2_info(&dev->v4l2_dev, "unregistering %s\n",
+				video_device_node_name(&dev->vid_cap_dev));
+			video_unregister_device(&dev->vid_cap_dev);
+		}
+		if (dev->has_vid_out) {
+			v4l2_info(&dev->v4l2_dev, "unregistering %s\n",
+				video_device_node_name(&dev->vid_out_dev));
+			video_unregister_device(&dev->vid_out_dev);
+		}
+		if (dev->has_vbi_cap) {
+			v4l2_info(&dev->v4l2_dev, "unregistering %s\n",
+				video_device_node_name(&dev->vbi_cap_dev));
+			video_unregister_device(&dev->vbi_cap_dev);
+		}
+		if (dev->has_vbi_out) {
+			v4l2_info(&dev->v4l2_dev, "unregistering %s\n",
+				video_device_node_name(&dev->vbi_out_dev));
+			video_unregister_device(&dev->vbi_out_dev);
+		}
+		if (dev->has_sdr_cap) {
+			v4l2_info(&dev->v4l2_dev, "unregistering %s\n",
+				video_device_node_name(&dev->sdr_cap_dev));
+			video_unregister_device(&dev->sdr_cap_dev);
+		}
+		if (dev->has_radio_rx) {
+			v4l2_info(&dev->v4l2_dev, "unregistering %s\n",
+				video_device_node_name(&dev->radio_rx_dev));
+			video_unregister_device(&dev->radio_rx_dev);
+		}
+		if (dev->has_radio_tx) {
+			v4l2_info(&dev->v4l2_dev, "unregistering %s\n",
+				video_device_node_name(&dev->radio_tx_dev));
+			video_unregister_device(&dev->radio_tx_dev);
+		}
+		if (dev->has_fb) {
+			v4l2_info(&dev->v4l2_dev, "unregistering fb%d\n",
+				dev->fb_info.node);
+			unregister_framebuffer(&dev->fb_info);
+			vivid_fb_release_buffers(dev);
+		}
+		if (dev->has_meta_cap) {
+			v4l2_info(&dev->v4l2_dev, "unregistering %s\n",
+				  video_device_node_name(&dev->meta_cap_dev));
+			video_unregister_device(&dev->meta_cap_dev);
+		}
+		if (dev->has_meta_out) {
+			v4l2_info(&dev->v4l2_dev, "unregistering %s\n",
+				  video_device_node_name(&dev->meta_out_dev));
+			video_unregister_device(&dev->meta_out_dev);
+		}
+		if (dev->has_touch_cap) {
+			v4l2_info(&dev->v4l2_dev, "unregistering %s\n",
+				  video_device_node_name(&dev->touch_cap_dev));
+			video_unregister_device(&dev->touch_cap_dev);
+		}
+		cec_unregister_adapter(dev->cec_rx_adap);
+		for (j = 0; j < MAX_OUTPUTS; j++)
+			cec_unregister_adapter(dev->cec_tx_adap[j]);
+		if (dev->cec_workqueue) {
+			vivid_cec_bus_free_work(dev);
+			destroy_workqueue(dev->cec_workqueue);
+		}
+		v4l2_device_put(&dev->v4l2_dev);
+		vivid_devs[i] = NULL;
+	}
+	return 0;
+}
+
+static void vivid_pdev_release(struct device *dev)
+{
+}
+
+static struct platform_device vivid_pdev = {
+	.name		= "vivid",
+	.dev.release	= vivid_pdev_release,
+};
+
+static struct platform_driver vivid_pdrv = {
+	.probe		= vivid_probe,
+	.remove		= vivid_remove,
+	.driver		= {
+		.name	= "vivid",
+	},
+};
+
+static int __init vivid_init(void)
+{
+	int ret;
+
+	ret = platform_device_register(&vivid_pdev);
+	if (ret)
+		return ret;
+
+	ret = platform_driver_register(&vivid_pdrv);
+	if (ret)
+		platform_device_unregister(&vivid_pdev);
+
+	return ret;
+}
+
+static void __exit vivid_exit(void)
+{
+	platform_driver_unregister(&vivid_pdrv);
+	platform_device_unregister(&vivid_pdev);
+}
+
+module_init(vivid_init);
+module_exit(vivid_exit);
diff --git a/drivers/media/test-drivers/vivid/vivid-core.h b/drivers/media/test-drivers/vivid/vivid-core.h
new file mode 100644
index 000000000000..99e69b8f770f
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-core.h
@@ -0,0 +1,612 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * vivid-core.h - core datastructures
+ *
+ * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _VIVID_CORE_H_
+#define _VIVID_CORE_H_
+
+#include <linux/fb.h>
+#include <linux/workqueue.h>
+#include <media/cec.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-dev.h>
+#include <media/v4l2-ctrls.h>
+#include <media/tpg/v4l2-tpg.h>
+#include "vivid-rds-gen.h"
+#include "vivid-vbi-gen.h"
+
+#define dprintk(dev, level, fmt, arg...) \
+	v4l2_dbg(level, vivid_debug, &dev->v4l2_dev, fmt, ## arg)
+
+/* The maximum number of clip rectangles */
+#define MAX_CLIPS  16
+/* The maximum number of inputs */
+#define MAX_INPUTS 16
+/* The maximum number of outputs */
+#define MAX_OUTPUTS 16
+/* The maximum up or down scaling factor is 4 */
+#define MAX_ZOOM  4
+/* The maximum image width/height are set to 4K DMT */
+#define MAX_WIDTH  4096
+#define MAX_HEIGHT 2160
+/* The minimum image width/height */
+#define MIN_WIDTH  16
+#define MIN_HEIGHT 16
+/* The data_offset of plane 0 for the multiplanar formats */
+#define PLANE0_DATA_OFFSET 128
+
+/* The supported TV frequency range in MHz */
+#define MIN_TV_FREQ (44U * 16U)
+#define MAX_TV_FREQ (958U * 16U)
+
+/* The number of samples returned in every SDR buffer */
+#define SDR_CAP_SAMPLES_PER_BUF 0x4000
+
+/* used by the threads to know when to resync internal counters */
+#define JIFFIES_PER_DAY (3600U * 24U * HZ)
+#define JIFFIES_RESYNC (JIFFIES_PER_DAY * (0xf0000000U / JIFFIES_PER_DAY))
+
+extern const struct v4l2_rect vivid_min_rect;
+extern const struct v4l2_rect vivid_max_rect;
+extern unsigned vivid_debug;
+
+struct vivid_fmt {
+	u32	fourcc;          /* v4l2 format id */
+	enum	tgp_color_enc color_enc;
+	bool	can_do_overlay;
+	u8	vdownsampling[TPG_MAX_PLANES];
+	u32	alpha_mask;
+	u8	planes;
+	u8	buffers;
+	u32	data_offset[TPG_MAX_PLANES];
+	u32	bit_depth[TPG_MAX_PLANES];
+};
+
+extern struct vivid_fmt vivid_formats[];
+
+/* buffer for one video frame */
+struct vivid_buffer {
+	/* common v4l buffer stuff -- must be first */
+	struct vb2_v4l2_buffer vb;
+	struct list_head	list;
+};
+
+enum vivid_input {
+	WEBCAM,
+	TV,
+	SVID,
+	HDMI,
+};
+
+enum vivid_signal_mode {
+	CURRENT_DV_TIMINGS,
+	CURRENT_STD = CURRENT_DV_TIMINGS,
+	NO_SIGNAL,
+	NO_LOCK,
+	OUT_OF_RANGE,
+	SELECTED_DV_TIMINGS,
+	SELECTED_STD = SELECTED_DV_TIMINGS,
+	CYCLE_DV_TIMINGS,
+	CYCLE_STD = CYCLE_DV_TIMINGS,
+	CUSTOM_DV_TIMINGS,
+};
+
+enum vivid_colorspace {
+	VIVID_CS_170M,
+	VIVID_CS_709,
+	VIVID_CS_SRGB,
+	VIVID_CS_OPRGB,
+	VIVID_CS_2020,
+	VIVID_CS_DCI_P3,
+	VIVID_CS_240M,
+	VIVID_CS_SYS_M,
+	VIVID_CS_SYS_BG,
+};
+
+#define VIVID_INVALID_SIGNAL(mode) \
+	((mode) == NO_SIGNAL || (mode) == NO_LOCK || (mode) == OUT_OF_RANGE)
+
+struct vivid_cec_work {
+	struct list_head	list;
+	struct delayed_work	work;
+	struct cec_adapter	*adap;
+	struct vivid_dev	*dev;
+	unsigned int		usecs;
+	unsigned int		timeout_ms;
+	u8			tx_status;
+	struct cec_msg		msg;
+};
+
+struct vivid_dev {
+	unsigned			inst;
+	struct v4l2_device		v4l2_dev;
+#ifdef CONFIG_MEDIA_CONTROLLER
+	struct media_device		mdev;
+	struct media_pad		vid_cap_pad;
+	struct media_pad		vid_out_pad;
+	struct media_pad		vbi_cap_pad;
+	struct media_pad		vbi_out_pad;
+	struct media_pad		sdr_cap_pad;
+	struct media_pad		meta_cap_pad;
+	struct media_pad		meta_out_pad;
+	struct media_pad		touch_cap_pad;
+#endif
+	struct v4l2_ctrl_handler	ctrl_hdl_user_gen;
+	struct v4l2_ctrl_handler	ctrl_hdl_user_vid;
+	struct v4l2_ctrl_handler	ctrl_hdl_user_aud;
+	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;
+	struct v4l2_ctrl_handler	ctrl_hdl_vid_out;
+	struct video_device		vbi_cap_dev;
+	struct v4l2_ctrl_handler	ctrl_hdl_vbi_cap;
+	struct video_device		vbi_out_dev;
+	struct v4l2_ctrl_handler	ctrl_hdl_vbi_out;
+	struct video_device		radio_rx_dev;
+	struct v4l2_ctrl_handler	ctrl_hdl_radio_rx;
+	struct video_device		radio_tx_dev;
+	struct v4l2_ctrl_handler	ctrl_hdl_radio_tx;
+	struct video_device		sdr_cap_dev;
+	struct v4l2_ctrl_handler	ctrl_hdl_sdr_cap;
+	struct video_device		meta_cap_dev;
+	struct v4l2_ctrl_handler	ctrl_hdl_meta_cap;
+	struct video_device		meta_out_dev;
+	struct v4l2_ctrl_handler	ctrl_hdl_meta_out;
+	struct video_device		touch_cap_dev;
+	struct v4l2_ctrl_handler	ctrl_hdl_touch_cap;
+
+	spinlock_t			slock;
+	struct mutex			mutex;
+
+	/* capabilities */
+	u32				vid_cap_caps;
+	u32				vid_out_caps;
+	u32				vbi_cap_caps;
+	u32				vbi_out_caps;
+	u32				sdr_cap_caps;
+	u32				radio_rx_caps;
+	u32				radio_tx_caps;
+	u32				meta_cap_caps;
+	u32				meta_out_caps;
+	u32				touch_cap_caps;
+
+	/* supported features */
+	bool				multiplanar;
+	unsigned			num_inputs;
+	unsigned int			num_hdmi_inputs;
+	u8				input_type[MAX_INPUTS];
+	u8				input_name_counter[MAX_INPUTS];
+	unsigned			num_outputs;
+	unsigned int			num_hdmi_outputs;
+	u8				output_type[MAX_OUTPUTS];
+	u8				output_name_counter[MAX_OUTPUTS];
+	bool				has_audio_inputs;
+	bool				has_audio_outputs;
+	bool				has_vid_cap;
+	bool				has_vid_out;
+	bool				has_vbi_cap;
+	bool				has_raw_vbi_cap;
+	bool				has_sliced_vbi_cap;
+	bool				has_vbi_out;
+	bool				has_raw_vbi_out;
+	bool				has_sliced_vbi_out;
+	bool				has_radio_rx;
+	bool				has_radio_tx;
+	bool				has_sdr_cap;
+	bool				has_fb;
+	bool				has_meta_cap;
+	bool				has_meta_out;
+	bool				has_tv_tuner;
+	bool				has_touch_cap;
+
+	bool				can_loop_video;
+
+	/* controls */
+	struct v4l2_ctrl		*brightness;
+	struct v4l2_ctrl		*contrast;
+	struct v4l2_ctrl		*saturation;
+	struct v4l2_ctrl		*hue;
+	struct {
+		/* autogain/gain cluster */
+		struct v4l2_ctrl	*autogain;
+		struct v4l2_ctrl	*gain;
+	};
+	struct v4l2_ctrl		*volume;
+	struct v4l2_ctrl		*mute;
+	struct v4l2_ctrl		*alpha;
+	struct v4l2_ctrl		*button;
+	struct v4l2_ctrl		*boolean;
+	struct v4l2_ctrl		*int32;
+	struct v4l2_ctrl		*int64;
+	struct v4l2_ctrl		*menu;
+	struct v4l2_ctrl		*string;
+	struct v4l2_ctrl		*bitmask;
+	struct v4l2_ctrl		*int_menu;
+	struct v4l2_ctrl		*test_pattern;
+	struct v4l2_ctrl		*colorspace;
+	struct v4l2_ctrl		*rgb_range_cap;
+	struct v4l2_ctrl		*real_rgb_range_cap;
+	struct {
+		/* std_signal_mode/standard cluster */
+		struct v4l2_ctrl	*ctrl_std_signal_mode;
+		struct v4l2_ctrl	*ctrl_standard;
+	};
+	struct {
+		/* dv_timings_signal_mode/timings cluster */
+		struct v4l2_ctrl	*ctrl_dv_timings_signal_mode;
+		struct v4l2_ctrl	*ctrl_dv_timings;
+	};
+	struct v4l2_ctrl		*ctrl_display_present;
+	struct v4l2_ctrl		*ctrl_has_crop_cap;
+	struct v4l2_ctrl		*ctrl_has_compose_cap;
+	struct v4l2_ctrl		*ctrl_has_scaler_cap;
+	struct v4l2_ctrl		*ctrl_has_crop_out;
+	struct v4l2_ctrl		*ctrl_has_compose_out;
+	struct v4l2_ctrl		*ctrl_has_scaler_out;
+	struct v4l2_ctrl		*ctrl_tx_mode;
+	struct v4l2_ctrl		*ctrl_tx_rgb_range;
+	struct v4l2_ctrl		*ctrl_tx_edid_present;
+	struct v4l2_ctrl		*ctrl_tx_hotplug;
+	struct v4l2_ctrl		*ctrl_tx_rxsense;
+
+	struct v4l2_ctrl		*ctrl_rx_power_present;
+
+	struct v4l2_ctrl		*radio_tx_rds_pi;
+	struct v4l2_ctrl		*radio_tx_rds_pty;
+	struct v4l2_ctrl		*radio_tx_rds_mono_stereo;
+	struct v4l2_ctrl		*radio_tx_rds_art_head;
+	struct v4l2_ctrl		*radio_tx_rds_compressed;
+	struct v4l2_ctrl		*radio_tx_rds_dyn_pty;
+	struct v4l2_ctrl		*radio_tx_rds_ta;
+	struct v4l2_ctrl		*radio_tx_rds_tp;
+	struct v4l2_ctrl		*radio_tx_rds_ms;
+	struct v4l2_ctrl		*radio_tx_rds_psname;
+	struct v4l2_ctrl		*radio_tx_rds_radiotext;
+
+	struct v4l2_ctrl		*radio_rx_rds_pty;
+	struct v4l2_ctrl		*radio_rx_rds_ta;
+	struct v4l2_ctrl		*radio_rx_rds_tp;
+	struct v4l2_ctrl		*radio_rx_rds_ms;
+	struct v4l2_ctrl		*radio_rx_rds_psname;
+	struct v4l2_ctrl		*radio_rx_rds_radiotext;
+
+	unsigned			input_brightness[MAX_INPUTS];
+	unsigned			osd_mode;
+	unsigned			button_pressed;
+	bool				sensor_hflip;
+	bool				sensor_vflip;
+	bool				hflip;
+	bool				vflip;
+	bool				vbi_cap_interlaced;
+	bool				loop_video;
+	bool				reduced_fps;
+
+	/* Framebuffer */
+	unsigned long			video_pbase;
+	void				*video_vbase;
+	u32				video_buffer_size;
+	int				display_width;
+	int				display_height;
+	int				display_byte_stride;
+	int				bits_per_pixel;
+	int				bytes_per_pixel;
+	struct fb_info			fb_info;
+	struct fb_var_screeninfo	fb_defined;
+	struct fb_fix_screeninfo	fb_fix;
+
+	/* Error injection */
+	bool				queue_setup_error;
+	bool				buf_prepare_error;
+	bool				start_streaming_error;
+	bool				dqbuf_error;
+	bool				req_validate_error;
+	bool				seq_wrap;
+	bool				time_wrap;
+	u64				time_wrap_offset;
+	unsigned			perc_dropped_buffers;
+	enum vivid_signal_mode		std_signal_mode[MAX_INPUTS];
+	unsigned int			query_std_last[MAX_INPUTS];
+	v4l2_std_id			query_std[MAX_INPUTS];
+	enum tpg_video_aspect		std_aspect_ratio[MAX_INPUTS];
+
+	enum vivid_signal_mode		dv_timings_signal_mode[MAX_INPUTS];
+	char				**query_dv_timings_qmenu;
+	char				*query_dv_timings_qmenu_strings;
+	unsigned			query_dv_timings_size;
+	unsigned int			query_dv_timings_last[MAX_INPUTS];
+	unsigned int			query_dv_timings[MAX_INPUTS];
+	enum tpg_video_aspect		dv_timings_aspect_ratio[MAX_INPUTS];
+
+	/* Input */
+	unsigned			input;
+	v4l2_std_id			std_cap[MAX_INPUTS];
+	struct v4l2_dv_timings		dv_timings_cap[MAX_INPUTS];
+	int				dv_timings_cap_sel[MAX_INPUTS];
+	u32				service_set_cap;
+	struct vivid_vbi_gen_data	vbi_gen;
+	u8				*edid;
+	unsigned			edid_blocks;
+	unsigned			edid_max_blocks;
+	unsigned			webcam_size_idx;
+	unsigned			webcam_ival_idx;
+	unsigned			tv_freq;
+	unsigned			tv_audmode;
+	unsigned			tv_field_cap;
+	unsigned			tv_audio_input;
+
+	u32				power_present;
+
+	/* Capture Overlay */
+	struct v4l2_framebuffer		fb_cap;
+	struct v4l2_fh			*overlay_cap_owner;
+	void				*fb_vbase_cap;
+	int				overlay_cap_top, overlay_cap_left;
+	enum v4l2_field			overlay_cap_field;
+	void				*bitmap_cap;
+	struct v4l2_clip		clips_cap[MAX_CLIPS];
+	struct v4l2_clip		try_clips_cap[MAX_CLIPS];
+	unsigned			clipcount_cap;
+
+	/* Output */
+	unsigned			output;
+	v4l2_std_id			std_out;
+	struct v4l2_dv_timings		dv_timings_out;
+	u32				colorspace_out;
+	u32				ycbcr_enc_out;
+	u32				hsv_enc_out;
+	u32				quantization_out;
+	u32				xfer_func_out;
+	u32				service_set_out;
+	unsigned			bytesperline_out[TPG_MAX_PLANES];
+	unsigned			tv_field_out;
+	unsigned			tv_audio_output;
+	bool				vbi_out_have_wss;
+	u8				vbi_out_wss[2];
+	bool				vbi_out_have_cc[2];
+	u8				vbi_out_cc[2][2];
+	bool				dvi_d_out;
+	u8				*scaled_line;
+	u8				*blended_line;
+	unsigned			cur_scaled_line;
+	bool				display_present[MAX_OUTPUTS];
+
+	/* Output Overlay */
+	void				*fb_vbase_out;
+	bool				overlay_out_enabled;
+	int				overlay_out_top, overlay_out_left;
+	void				*bitmap_out;
+	struct v4l2_clip		clips_out[MAX_CLIPS];
+	struct v4l2_clip		try_clips_out[MAX_CLIPS];
+	unsigned			clipcount_out;
+	unsigned			fbuf_out_flags;
+	u32				chromakey_out;
+	u8				global_alpha_out;
+
+	/* video capture */
+	struct tpg_data			tpg;
+	unsigned			ms_vid_cap;
+	bool				must_blank[VIDEO_MAX_FRAME];
+
+	const struct vivid_fmt		*fmt_cap;
+	struct v4l2_fract		timeperframe_vid_cap;
+	enum v4l2_field			field_cap;
+	struct v4l2_rect		src_rect;
+	struct v4l2_rect		fmt_cap_rect;
+	struct v4l2_rect		crop_cap;
+	struct v4l2_rect		compose_cap;
+	struct v4l2_rect		crop_bounds_cap;
+	struct vb2_queue		vb_vid_cap_q;
+	struct list_head		vid_cap_active;
+	struct vb2_queue		vb_vbi_cap_q;
+	struct list_head		vbi_cap_active;
+	struct vb2_queue		vb_meta_cap_q;
+	struct list_head		meta_cap_active;
+	struct vb2_queue		vb_touch_cap_q;
+	struct list_head		touch_cap_active;
+
+	/* thread for generating video capture stream */
+	struct task_struct		*kthread_vid_cap;
+	unsigned long			jiffies_vid_cap;
+	u64				cap_stream_start;
+	u64				cap_frame_period;
+	u64				cap_frame_eof_offset;
+	u32				cap_seq_offset;
+	u32				cap_seq_count;
+	bool				cap_seq_resync;
+	u32				vid_cap_seq_start;
+	u32				vid_cap_seq_count;
+	bool				vid_cap_streaming;
+	u32				vbi_cap_seq_start;
+	u32				vbi_cap_seq_count;
+	bool				vbi_cap_streaming;
+	bool				stream_sliced_vbi_cap;
+	u32				meta_cap_seq_start;
+	u32				meta_cap_seq_count;
+	bool				meta_cap_streaming;
+
+	/* Touch capture */
+	struct task_struct		*kthread_touch_cap;
+	unsigned long			jiffies_touch_cap;
+	u64				touch_cap_stream_start;
+	u32				touch_cap_seq_offset;
+	bool				touch_cap_seq_resync;
+	u32				touch_cap_seq_start;
+	u32				touch_cap_seq_count;
+	bool				touch_cap_streaming;
+	struct v4l2_fract		timeperframe_tch_cap;
+	struct v4l2_pix_format		tch_format;
+	int				tch_pat_random;
+
+	/* video output */
+	const struct vivid_fmt		*fmt_out;
+	struct v4l2_fract		timeperframe_vid_out;
+	enum v4l2_field			field_out;
+	struct v4l2_rect		sink_rect;
+	struct v4l2_rect		fmt_out_rect;
+	struct v4l2_rect		crop_out;
+	struct v4l2_rect		compose_out;
+	struct v4l2_rect		compose_bounds_out;
+	struct vb2_queue		vb_vid_out_q;
+	struct list_head		vid_out_active;
+	struct vb2_queue		vb_vbi_out_q;
+	struct list_head		vbi_out_active;
+	struct vb2_queue		vb_meta_out_q;
+	struct list_head		meta_out_active;
+
+	/* video loop precalculated rectangles */
+
+	/*
+	 * Intersection between what the output side composes and the capture side
+	 * crops. I.e., what actually needs to be copied from the output buffer to
+	 * the capture buffer.
+	 */
+	struct v4l2_rect		loop_vid_copy;
+	/* The part of the output buffer that (after scaling) corresponds to loop_vid_copy. */
+	struct v4l2_rect		loop_vid_out;
+	/* The part of the capture buffer that (after scaling) corresponds to loop_vid_copy. */
+	struct v4l2_rect		loop_vid_cap;
+	/*
+	 * The intersection of the framebuffer, the overlay output window and
+	 * loop_vid_copy. I.e., the part of the framebuffer that actually should be
+	 * blended with the compose_out rectangle. This uses the framebuffer origin.
+	 */
+	struct v4l2_rect		loop_fb_copy;
+	/* The same as loop_fb_copy but with compose_out origin. */
+	struct v4l2_rect		loop_vid_overlay;
+	/*
+	 * The part of the capture buffer that (after scaling) corresponds
+	 * to loop_vid_overlay.
+	 */
+	struct v4l2_rect		loop_vid_overlay_cap;
+
+	/* thread for generating video output stream */
+	struct task_struct		*kthread_vid_out;
+	unsigned long			jiffies_vid_out;
+	u32				out_seq_offset;
+	u32				out_seq_count;
+	bool				out_seq_resync;
+	u32				vid_out_seq_start;
+	u32				vid_out_seq_count;
+	bool				vid_out_streaming;
+	u32				vbi_out_seq_start;
+	u32				vbi_out_seq_count;
+	bool				vbi_out_streaming;
+	bool				stream_sliced_vbi_out;
+	u32				meta_out_seq_start;
+	u32				meta_out_seq_count;
+	bool				meta_out_streaming;
+
+	/* SDR capture */
+	struct vb2_queue		vb_sdr_cap_q;
+	struct list_head		sdr_cap_active;
+	u32				sdr_pixelformat; /* v4l2 format id */
+	unsigned			sdr_buffersize;
+	unsigned			sdr_adc_freq;
+	unsigned			sdr_fm_freq;
+	unsigned			sdr_fm_deviation;
+	int				sdr_fixp_src_phase;
+	int				sdr_fixp_mod_phase;
+
+	bool				tstamp_src_is_soe;
+	bool				has_crop_cap;
+	bool				has_compose_cap;
+	bool				has_scaler_cap;
+	bool				has_crop_out;
+	bool				has_compose_out;
+	bool				has_scaler_out;
+
+	/* thread for generating SDR stream */
+	struct task_struct		*kthread_sdr_cap;
+	unsigned long			jiffies_sdr_cap;
+	u32				sdr_cap_seq_offset;
+	u32				sdr_cap_seq_count;
+	bool				sdr_cap_seq_resync;
+
+	/* RDS generator */
+	struct vivid_rds_gen		rds_gen;
+
+	/* Radio receiver */
+	unsigned			radio_rx_freq;
+	unsigned			radio_rx_audmode;
+	int				radio_rx_sig_qual;
+	unsigned			radio_rx_hw_seek_mode;
+	bool				radio_rx_hw_seek_prog_lim;
+	bool				radio_rx_rds_controls;
+	bool				radio_rx_rds_enabled;
+	unsigned			radio_rx_rds_use_alternates;
+	unsigned			radio_rx_rds_last_block;
+	struct v4l2_fh			*radio_rx_rds_owner;
+
+	/* Radio transmitter */
+	unsigned			radio_tx_freq;
+	unsigned			radio_tx_subchans;
+	bool				radio_tx_rds_controls;
+	unsigned			radio_tx_rds_last_block;
+	struct v4l2_fh			*radio_tx_rds_owner;
+
+	/* Shared between radio receiver and transmitter */
+	bool				radio_rds_loop;
+	ktime_t				radio_rds_init_time;
+
+	/* CEC */
+	struct cec_adapter		*cec_rx_adap;
+	struct cec_adapter		*cec_tx_adap[MAX_OUTPUTS];
+	struct workqueue_struct		*cec_workqueue;
+	spinlock_t			cec_slock;
+	struct list_head		cec_work_list;
+	unsigned int			cec_xfer_time_jiffies;
+	unsigned long			cec_xfer_start_jiffies;
+	u8				cec_output2bus_map[MAX_OUTPUTS];
+
+	/* CEC OSD String */
+	char				osd[14];
+	unsigned long			osd_jiffies;
+
+	bool				meta_pts;
+	bool				meta_scr;
+};
+
+static inline bool vivid_is_webcam(const struct vivid_dev *dev)
+{
+	return dev->input_type[dev->input] == WEBCAM;
+}
+
+static inline bool vivid_is_tv_cap(const struct vivid_dev *dev)
+{
+	return dev->input_type[dev->input] == TV;
+}
+
+static inline bool vivid_is_svid_cap(const struct vivid_dev *dev)
+{
+	return dev->input_type[dev->input] == SVID;
+}
+
+static inline bool vivid_is_hdmi_cap(const struct vivid_dev *dev)
+{
+	return dev->input_type[dev->input] == HDMI;
+}
+
+static inline bool vivid_is_sdtv_cap(const struct vivid_dev *dev)
+{
+	return vivid_is_tv_cap(dev) || vivid_is_svid_cap(dev);
+}
+
+static inline bool vivid_is_svid_out(const struct vivid_dev *dev)
+{
+	return dev->output_type[dev->output] == SVID;
+}
+
+static inline bool vivid_is_hdmi_out(const struct vivid_dev *dev)
+{
+	return dev->output_type[dev->output] == HDMI;
+}
+
+#endif
diff --git a/drivers/media/test-drivers/vivid/vivid-ctrls.c b/drivers/media/test-drivers/vivid/vivid-ctrls.c
new file mode 100644
index 000000000000..334130568dcb
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-ctrls.c
@@ -0,0 +1,1939 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * vivid-ctrls.c - control support functions.
+ *
+ * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-common.h>
+
+#include "vivid-core.h"
+#include "vivid-vid-cap.h"
+#include "vivid-vid-out.h"
+#include "vivid-vid-common.h"
+#include "vivid-radio-common.h"
+#include "vivid-osd.h"
+#include "vivid-ctrls.h"
+#include "vivid-cec.h"
+
+#define VIVID_CID_CUSTOM_BASE		(V4L2_CID_USER_BASE | 0xf000)
+#define VIVID_CID_BUTTON		(VIVID_CID_CUSTOM_BASE + 0)
+#define VIVID_CID_BOOLEAN		(VIVID_CID_CUSTOM_BASE + 1)
+#define VIVID_CID_INTEGER		(VIVID_CID_CUSTOM_BASE + 2)
+#define VIVID_CID_INTEGER64		(VIVID_CID_CUSTOM_BASE + 3)
+#define VIVID_CID_MENU			(VIVID_CID_CUSTOM_BASE + 4)
+#define VIVID_CID_STRING		(VIVID_CID_CUSTOM_BASE + 5)
+#define VIVID_CID_BITMASK		(VIVID_CID_CUSTOM_BASE + 6)
+#define VIVID_CID_INTMENU		(VIVID_CID_CUSTOM_BASE + 7)
+#define VIVID_CID_U32_ARRAY		(VIVID_CID_CUSTOM_BASE + 8)
+#define VIVID_CID_U16_MATRIX		(VIVID_CID_CUSTOM_BASE + 9)
+#define VIVID_CID_U8_4D_ARRAY		(VIVID_CID_CUSTOM_BASE + 10)
+#define VIVID_CID_AREA			(VIVID_CID_CUSTOM_BASE + 11)
+
+#define VIVID_CID_VIVID_BASE		(0x00f00000 | 0xf000)
+#define VIVID_CID_VIVID_CLASS		(0x00f00000 | 1)
+#define VIVID_CID_TEST_PATTERN		(VIVID_CID_VIVID_BASE + 0)
+#define VIVID_CID_OSD_TEXT_MODE		(VIVID_CID_VIVID_BASE + 1)
+#define VIVID_CID_HOR_MOVEMENT		(VIVID_CID_VIVID_BASE + 2)
+#define VIVID_CID_VERT_MOVEMENT		(VIVID_CID_VIVID_BASE + 3)
+#define VIVID_CID_SHOW_BORDER		(VIVID_CID_VIVID_BASE + 4)
+#define VIVID_CID_SHOW_SQUARE		(VIVID_CID_VIVID_BASE + 5)
+#define VIVID_CID_INSERT_SAV		(VIVID_CID_VIVID_BASE + 6)
+#define VIVID_CID_INSERT_EAV		(VIVID_CID_VIVID_BASE + 7)
+#define VIVID_CID_VBI_CAP_INTERLACED	(VIVID_CID_VIVID_BASE + 8)
+
+#define VIVID_CID_HFLIP			(VIVID_CID_VIVID_BASE + 20)
+#define VIVID_CID_VFLIP			(VIVID_CID_VIVID_BASE + 21)
+#define VIVID_CID_STD_ASPECT_RATIO	(VIVID_CID_VIVID_BASE + 22)
+#define VIVID_CID_DV_TIMINGS_ASPECT_RATIO	(VIVID_CID_VIVID_BASE + 23)
+#define VIVID_CID_TSTAMP_SRC		(VIVID_CID_VIVID_BASE + 24)
+#define VIVID_CID_COLORSPACE		(VIVID_CID_VIVID_BASE + 25)
+#define VIVID_CID_XFER_FUNC		(VIVID_CID_VIVID_BASE + 26)
+#define VIVID_CID_YCBCR_ENC		(VIVID_CID_VIVID_BASE + 27)
+#define VIVID_CID_QUANTIZATION		(VIVID_CID_VIVID_BASE + 28)
+#define VIVID_CID_LIMITED_RGB_RANGE	(VIVID_CID_VIVID_BASE + 29)
+#define VIVID_CID_ALPHA_MODE		(VIVID_CID_VIVID_BASE + 30)
+#define VIVID_CID_HAS_CROP_CAP		(VIVID_CID_VIVID_BASE + 31)
+#define VIVID_CID_HAS_COMPOSE_CAP	(VIVID_CID_VIVID_BASE + 32)
+#define VIVID_CID_HAS_SCALER_CAP	(VIVID_CID_VIVID_BASE + 33)
+#define VIVID_CID_HAS_CROP_OUT		(VIVID_CID_VIVID_BASE + 34)
+#define VIVID_CID_HAS_COMPOSE_OUT	(VIVID_CID_VIVID_BASE + 35)
+#define VIVID_CID_HAS_SCALER_OUT	(VIVID_CID_VIVID_BASE + 36)
+#define VIVID_CID_LOOP_VIDEO		(VIVID_CID_VIVID_BASE + 37)
+#define VIVID_CID_SEQ_WRAP		(VIVID_CID_VIVID_BASE + 38)
+#define VIVID_CID_TIME_WRAP		(VIVID_CID_VIVID_BASE + 39)
+#define VIVID_CID_MAX_EDID_BLOCKS	(VIVID_CID_VIVID_BASE + 40)
+#define VIVID_CID_PERCENTAGE_FILL	(VIVID_CID_VIVID_BASE + 41)
+#define VIVID_CID_REDUCED_FPS		(VIVID_CID_VIVID_BASE + 42)
+#define VIVID_CID_HSV_ENC		(VIVID_CID_VIVID_BASE + 43)
+#define VIVID_CID_DISPLAY_PRESENT	(VIVID_CID_VIVID_BASE + 44)
+
+#define VIVID_CID_STD_SIGNAL_MODE	(VIVID_CID_VIVID_BASE + 60)
+#define VIVID_CID_STANDARD		(VIVID_CID_VIVID_BASE + 61)
+#define VIVID_CID_DV_TIMINGS_SIGNAL_MODE	(VIVID_CID_VIVID_BASE + 62)
+#define VIVID_CID_DV_TIMINGS		(VIVID_CID_VIVID_BASE + 63)
+#define VIVID_CID_PERC_DROPPED		(VIVID_CID_VIVID_BASE + 64)
+#define VIVID_CID_DISCONNECT		(VIVID_CID_VIVID_BASE + 65)
+#define VIVID_CID_DQBUF_ERROR		(VIVID_CID_VIVID_BASE + 66)
+#define VIVID_CID_QUEUE_SETUP_ERROR	(VIVID_CID_VIVID_BASE + 67)
+#define VIVID_CID_BUF_PREPARE_ERROR	(VIVID_CID_VIVID_BASE + 68)
+#define VIVID_CID_START_STR_ERROR	(VIVID_CID_VIVID_BASE + 69)
+#define VIVID_CID_QUEUE_ERROR		(VIVID_CID_VIVID_BASE + 70)
+#define VIVID_CID_CLEAR_FB		(VIVID_CID_VIVID_BASE + 71)
+#define VIVID_CID_REQ_VALIDATE_ERROR	(VIVID_CID_VIVID_BASE + 72)
+
+#define VIVID_CID_RADIO_SEEK_MODE	(VIVID_CID_VIVID_BASE + 90)
+#define VIVID_CID_RADIO_SEEK_PROG_LIM	(VIVID_CID_VIVID_BASE + 91)
+#define VIVID_CID_RADIO_RX_RDS_RBDS	(VIVID_CID_VIVID_BASE + 92)
+#define VIVID_CID_RADIO_RX_RDS_BLOCKIO	(VIVID_CID_VIVID_BASE + 93)
+
+#define VIVID_CID_RADIO_TX_RDS_BLOCKIO	(VIVID_CID_VIVID_BASE + 94)
+
+#define VIVID_CID_SDR_CAP_FM_DEVIATION	(VIVID_CID_VIVID_BASE + 110)
+
+#define VIVID_CID_META_CAP_GENERATE_PTS	(VIVID_CID_VIVID_BASE + 111)
+#define VIVID_CID_META_CAP_GENERATE_SCR	(VIVID_CID_VIVID_BASE + 112)
+
+/* General User Controls */
+
+static int vivid_user_gen_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_user_gen);
+
+	switch (ctrl->id) {
+	case VIVID_CID_DISCONNECT:
+		v4l2_info(&dev->v4l2_dev, "disconnect\n");
+		clear_bit(V4L2_FL_REGISTERED, &dev->vid_cap_dev.flags);
+		clear_bit(V4L2_FL_REGISTERED, &dev->vid_out_dev.flags);
+		clear_bit(V4L2_FL_REGISTERED, &dev->vbi_cap_dev.flags);
+		clear_bit(V4L2_FL_REGISTERED, &dev->vbi_out_dev.flags);
+		clear_bit(V4L2_FL_REGISTERED, &dev->sdr_cap_dev.flags);
+		clear_bit(V4L2_FL_REGISTERED, &dev->radio_rx_dev.flags);
+		clear_bit(V4L2_FL_REGISTERED, &dev->radio_tx_dev.flags);
+		clear_bit(V4L2_FL_REGISTERED, &dev->meta_cap_dev.flags);
+		break;
+	case VIVID_CID_BUTTON:
+		dev->button_pressed = 30;
+		break;
+	}
+	return 0;
+}
+
+static const struct v4l2_ctrl_ops vivid_user_gen_ctrl_ops = {
+	.s_ctrl = vivid_user_gen_s_ctrl,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_button = {
+	.ops = &vivid_user_gen_ctrl_ops,
+	.id = VIVID_CID_BUTTON,
+	.name = "Button",
+	.type = V4L2_CTRL_TYPE_BUTTON,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_boolean = {
+	.ops = &vivid_user_gen_ctrl_ops,
+	.id = VIVID_CID_BOOLEAN,
+	.name = "Boolean",
+	.type = V4L2_CTRL_TYPE_BOOLEAN,
+	.min = 0,
+	.max = 1,
+	.step = 1,
+	.def = 1,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_int32 = {
+	.ops = &vivid_user_gen_ctrl_ops,
+	.id = VIVID_CID_INTEGER,
+	.name = "Integer 32 Bits",
+	.type = V4L2_CTRL_TYPE_INTEGER,
+	.min = 0xffffffff80000000ULL,
+	.max = 0x7fffffff,
+	.step = 1,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_int64 = {
+	.ops = &vivid_user_gen_ctrl_ops,
+	.id = VIVID_CID_INTEGER64,
+	.name = "Integer 64 Bits",
+	.type = V4L2_CTRL_TYPE_INTEGER64,
+	.min = 0x8000000000000000ULL,
+	.max = 0x7fffffffffffffffLL,
+	.step = 1,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_u32_array = {
+	.ops = &vivid_user_gen_ctrl_ops,
+	.id = VIVID_CID_U32_ARRAY,
+	.name = "U32 1 Element Array",
+	.type = V4L2_CTRL_TYPE_U32,
+	.def = 0x18,
+	.min = 0x10,
+	.max = 0x20000,
+	.step = 1,
+	.dims = { 1 },
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_u16_matrix = {
+	.ops = &vivid_user_gen_ctrl_ops,
+	.id = VIVID_CID_U16_MATRIX,
+	.name = "U16 8x16 Matrix",
+	.type = V4L2_CTRL_TYPE_U16,
+	.def = 0x18,
+	.min = 0x10,
+	.max = 0x2000,
+	.step = 1,
+	.dims = { 8, 16 },
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_u8_4d_array = {
+	.ops = &vivid_user_gen_ctrl_ops,
+	.id = VIVID_CID_U8_4D_ARRAY,
+	.name = "U8 2x3x4x5 Array",
+	.type = V4L2_CTRL_TYPE_U8,
+	.def = 0x18,
+	.min = 0x10,
+	.max = 0x20,
+	.step = 1,
+	.dims = { 2, 3, 4, 5 },
+};
+
+static const char * const vivid_ctrl_menu_strings[] = {
+	"Menu Item 0 (Skipped)",
+	"Menu Item 1",
+	"Menu Item 2 (Skipped)",
+	"Menu Item 3",
+	"Menu Item 4",
+	"Menu Item 5 (Skipped)",
+	NULL,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_menu = {
+	.ops = &vivid_user_gen_ctrl_ops,
+	.id = VIVID_CID_MENU,
+	.name = "Menu",
+	.type = V4L2_CTRL_TYPE_MENU,
+	.min = 1,
+	.max = 4,
+	.def = 3,
+	.menu_skip_mask = 0x04,
+	.qmenu = vivid_ctrl_menu_strings,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_string = {
+	.ops = &vivid_user_gen_ctrl_ops,
+	.id = VIVID_CID_STRING,
+	.name = "String",
+	.type = V4L2_CTRL_TYPE_STRING,
+	.min = 2,
+	.max = 4,
+	.step = 1,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_bitmask = {
+	.ops = &vivid_user_gen_ctrl_ops,
+	.id = VIVID_CID_BITMASK,
+	.name = "Bitmask",
+	.type = V4L2_CTRL_TYPE_BITMASK,
+	.def = 0x80002000,
+	.min = 0,
+	.max = 0x80402010,
+	.step = 0,
+};
+
+static const s64 vivid_ctrl_int_menu_values[] = {
+	1, 1, 2, 3, 5, 8, 13, 21, 42,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_int_menu = {
+	.ops = &vivid_user_gen_ctrl_ops,
+	.id = VIVID_CID_INTMENU,
+	.name = "Integer Menu",
+	.type = V4L2_CTRL_TYPE_INTEGER_MENU,
+	.min = 1,
+	.max = 8,
+	.def = 4,
+	.menu_skip_mask = 0x02,
+	.qmenu_int = vivid_ctrl_int_menu_values,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_disconnect = {
+	.ops = &vivid_user_gen_ctrl_ops,
+	.id = VIVID_CID_DISCONNECT,
+	.name = "Disconnect",
+	.type = V4L2_CTRL_TYPE_BUTTON,
+};
+
+static const struct v4l2_area area = {
+	.width = 1000,
+	.height = 2000,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_area = {
+	.ops = &vivid_user_gen_ctrl_ops,
+	.id = VIVID_CID_AREA,
+	.name = "Area",
+	.type = V4L2_CTRL_TYPE_AREA,
+	.p_def.p_const = &area,
+};
+
+/* 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_fb_ctrl_ops,
+	.id = VIVID_CID_CLEAR_FB,
+	.name = "Clear Framebuffer",
+	.type = V4L2_CTRL_TYPE_BUTTON,
+};
+
+
+/* Video User Controls */
+
+static int vivid_user_vid_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_user_vid);
+
+	switch (ctrl->id) {
+	case V4L2_CID_AUTOGAIN:
+		dev->gain->val = (jiffies_to_msecs(jiffies) / 1000) & 0xff;
+		break;
+	}
+	return 0;
+}
+
+static int vivid_user_vid_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_user_vid);
+
+	switch (ctrl->id) {
+	case V4L2_CID_BRIGHTNESS:
+		dev->input_brightness[dev->input] = ctrl->val - dev->input * 128;
+		tpg_s_brightness(&dev->tpg, dev->input_brightness[dev->input]);
+		break;
+	case V4L2_CID_CONTRAST:
+		tpg_s_contrast(&dev->tpg, ctrl->val);
+		break;
+	case V4L2_CID_SATURATION:
+		tpg_s_saturation(&dev->tpg, ctrl->val);
+		break;
+	case V4L2_CID_HUE:
+		tpg_s_hue(&dev->tpg, ctrl->val);
+		break;
+	case V4L2_CID_HFLIP:
+		dev->hflip = ctrl->val;
+		tpg_s_hflip(&dev->tpg, dev->sensor_hflip ^ dev->hflip);
+		break;
+	case V4L2_CID_VFLIP:
+		dev->vflip = ctrl->val;
+		tpg_s_vflip(&dev->tpg, dev->sensor_vflip ^ dev->vflip);
+		break;
+	case V4L2_CID_ALPHA_COMPONENT:
+		tpg_s_alpha_component(&dev->tpg, ctrl->val);
+		break;
+	}
+	return 0;
+}
+
+static const struct v4l2_ctrl_ops vivid_user_vid_ctrl_ops = {
+	.g_volatile_ctrl = vivid_user_vid_g_volatile_ctrl,
+	.s_ctrl = vivid_user_vid_s_ctrl,
+};
+
+
+/* Video Capture Controls */
+
+static int vivid_vid_cap_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	static const u32 colorspaces[] = {
+		V4L2_COLORSPACE_SMPTE170M,
+		V4L2_COLORSPACE_REC709,
+		V4L2_COLORSPACE_SRGB,
+		V4L2_COLORSPACE_OPRGB,
+		V4L2_COLORSPACE_BT2020,
+		V4L2_COLORSPACE_DCI_P3,
+		V4L2_COLORSPACE_SMPTE240M,
+		V4L2_COLORSPACE_470_SYSTEM_M,
+		V4L2_COLORSPACE_470_SYSTEM_BG,
+	};
+	struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_vid_cap);
+	unsigned int i, j;
+
+	switch (ctrl->id) {
+	case VIVID_CID_TEST_PATTERN:
+		vivid_update_quality(dev);
+		tpg_s_pattern(&dev->tpg, ctrl->val);
+		break;
+	case VIVID_CID_COLORSPACE:
+		tpg_s_colorspace(&dev->tpg, colorspaces[ctrl->val]);
+		vivid_send_source_change(dev, TV);
+		vivid_send_source_change(dev, SVID);
+		vivid_send_source_change(dev, HDMI);
+		vivid_send_source_change(dev, WEBCAM);
+		break;
+	case VIVID_CID_XFER_FUNC:
+		tpg_s_xfer_func(&dev->tpg, ctrl->val);
+		vivid_send_source_change(dev, TV);
+		vivid_send_source_change(dev, SVID);
+		vivid_send_source_change(dev, HDMI);
+		vivid_send_source_change(dev, WEBCAM);
+		break;
+	case VIVID_CID_YCBCR_ENC:
+		tpg_s_ycbcr_enc(&dev->tpg, ctrl->val);
+		vivid_send_source_change(dev, TV);
+		vivid_send_source_change(dev, SVID);
+		vivid_send_source_change(dev, HDMI);
+		vivid_send_source_change(dev, WEBCAM);
+		break;
+	case VIVID_CID_HSV_ENC:
+		tpg_s_hsv_enc(&dev->tpg, ctrl->val ? V4L2_HSV_ENC_256 :
+						     V4L2_HSV_ENC_180);
+		vivid_send_source_change(dev, TV);
+		vivid_send_source_change(dev, SVID);
+		vivid_send_source_change(dev, HDMI);
+		vivid_send_source_change(dev, WEBCAM);
+		break;
+	case VIVID_CID_QUANTIZATION:
+		tpg_s_quantization(&dev->tpg, ctrl->val);
+		vivid_send_source_change(dev, TV);
+		vivid_send_source_change(dev, SVID);
+		vivid_send_source_change(dev, HDMI);
+		vivid_send_source_change(dev, WEBCAM);
+		break;
+	case V4L2_CID_DV_RX_RGB_RANGE:
+		if (!vivid_is_hdmi_cap(dev))
+			break;
+		tpg_s_rgb_range(&dev->tpg, ctrl->val);
+		break;
+	case VIVID_CID_LIMITED_RGB_RANGE:
+		tpg_s_real_rgb_range(&dev->tpg, ctrl->val ?
+				V4L2_DV_RGB_RANGE_LIMITED : V4L2_DV_RGB_RANGE_FULL);
+		break;
+	case VIVID_CID_ALPHA_MODE:
+		tpg_s_alpha_mode(&dev->tpg, ctrl->val);
+		break;
+	case VIVID_CID_HOR_MOVEMENT:
+		tpg_s_mv_hor_mode(&dev->tpg, ctrl->val);
+		break;
+	case VIVID_CID_VERT_MOVEMENT:
+		tpg_s_mv_vert_mode(&dev->tpg, ctrl->val);
+		break;
+	case VIVID_CID_OSD_TEXT_MODE:
+		dev->osd_mode = ctrl->val;
+		break;
+	case VIVID_CID_PERCENTAGE_FILL:
+		tpg_s_perc_fill(&dev->tpg, ctrl->val);
+		for (i = 0; i < VIDEO_MAX_FRAME; i++)
+			dev->must_blank[i] = ctrl->val < 100;
+		break;
+	case VIVID_CID_INSERT_SAV:
+		tpg_s_insert_sav(&dev->tpg, ctrl->val);
+		break;
+	case VIVID_CID_INSERT_EAV:
+		tpg_s_insert_eav(&dev->tpg, ctrl->val);
+		break;
+	case VIVID_CID_HFLIP:
+		dev->sensor_hflip = ctrl->val;
+		tpg_s_hflip(&dev->tpg, dev->sensor_hflip ^ dev->hflip);
+		break;
+	case VIVID_CID_VFLIP:
+		dev->sensor_vflip = ctrl->val;
+		tpg_s_vflip(&dev->tpg, dev->sensor_vflip ^ dev->vflip);
+		break;
+	case VIVID_CID_REDUCED_FPS:
+		dev->reduced_fps = ctrl->val;
+		vivid_update_format_cap(dev, true);
+		break;
+	case VIVID_CID_HAS_CROP_CAP:
+		dev->has_crop_cap = ctrl->val;
+		vivid_update_format_cap(dev, true);
+		break;
+	case VIVID_CID_HAS_COMPOSE_CAP:
+		dev->has_compose_cap = ctrl->val;
+		vivid_update_format_cap(dev, true);
+		break;
+	case VIVID_CID_HAS_SCALER_CAP:
+		dev->has_scaler_cap = ctrl->val;
+		vivid_update_format_cap(dev, true);
+		break;
+	case VIVID_CID_SHOW_BORDER:
+		tpg_s_show_border(&dev->tpg, ctrl->val);
+		break;
+	case VIVID_CID_SHOW_SQUARE:
+		tpg_s_show_square(&dev->tpg, ctrl->val);
+		break;
+	case VIVID_CID_STD_ASPECT_RATIO:
+		dev->std_aspect_ratio[dev->input] = ctrl->val;
+		tpg_s_video_aspect(&dev->tpg, vivid_get_video_aspect(dev));
+		break;
+	case VIVID_CID_DV_TIMINGS_SIGNAL_MODE:
+		dev->dv_timings_signal_mode[dev->input] =
+			dev->ctrl_dv_timings_signal_mode->val;
+		dev->query_dv_timings[dev->input] = dev->ctrl_dv_timings->val;
+
+		dev->power_present = 0;
+		for (i = 0, j = 0;
+		     i < ARRAY_SIZE(dev->dv_timings_signal_mode);
+		     i++)
+			if (dev->input_type[i] == HDMI) {
+				if (dev->dv_timings_signal_mode[i] != NO_SIGNAL)
+					dev->power_present |= (1 << j);
+				j++;
+			}
+		__v4l2_ctrl_s_ctrl(dev->ctrl_rx_power_present,
+				   dev->power_present);
+
+		v4l2_ctrl_activate(dev->ctrl_dv_timings,
+			dev->dv_timings_signal_mode[dev->input] ==
+				SELECTED_DV_TIMINGS);
+
+		vivid_update_quality(dev);
+		vivid_send_source_change(dev, HDMI);
+		break;
+	case VIVID_CID_DV_TIMINGS_ASPECT_RATIO:
+		dev->dv_timings_aspect_ratio[dev->input] = ctrl->val;
+		tpg_s_video_aspect(&dev->tpg, vivid_get_video_aspect(dev));
+		break;
+	case VIVID_CID_TSTAMP_SRC:
+		dev->tstamp_src_is_soe = ctrl->val;
+		dev->vb_vid_cap_q.timestamp_flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+		if (dev->tstamp_src_is_soe)
+			dev->vb_vid_cap_q.timestamp_flags |= V4L2_BUF_FLAG_TSTAMP_SRC_SOE;
+		break;
+	case VIVID_CID_MAX_EDID_BLOCKS:
+		dev->edid_max_blocks = ctrl->val;
+		if (dev->edid_blocks > dev->edid_max_blocks)
+			dev->edid_blocks = dev->edid_max_blocks;
+		break;
+	}
+	return 0;
+}
+
+static const struct v4l2_ctrl_ops vivid_vid_cap_ctrl_ops = {
+	.s_ctrl = vivid_vid_cap_s_ctrl,
+};
+
+static const char * const vivid_ctrl_hor_movement_strings[] = {
+	"Move Left Fast",
+	"Move Left",
+	"Move Left Slow",
+	"No Movement",
+	"Move Right Slow",
+	"Move Right",
+	"Move Right Fast",
+	NULL,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_hor_movement = {
+	.ops = &vivid_vid_cap_ctrl_ops,
+	.id = VIVID_CID_HOR_MOVEMENT,
+	.name = "Horizontal Movement",
+	.type = V4L2_CTRL_TYPE_MENU,
+	.max = TPG_MOVE_POS_FAST,
+	.def = TPG_MOVE_NONE,
+	.qmenu = vivid_ctrl_hor_movement_strings,
+};
+
+static const char * const vivid_ctrl_vert_movement_strings[] = {
+	"Move Up Fast",
+	"Move Up",
+	"Move Up Slow",
+	"No Movement",
+	"Move Down Slow",
+	"Move Down",
+	"Move Down Fast",
+	NULL,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_vert_movement = {
+	.ops = &vivid_vid_cap_ctrl_ops,
+	.id = VIVID_CID_VERT_MOVEMENT,
+	.name = "Vertical Movement",
+	.type = V4L2_CTRL_TYPE_MENU,
+	.max = TPG_MOVE_POS_FAST,
+	.def = TPG_MOVE_NONE,
+	.qmenu = vivid_ctrl_vert_movement_strings,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_show_border = {
+	.ops = &vivid_vid_cap_ctrl_ops,
+	.id = VIVID_CID_SHOW_BORDER,
+	.name = "Show Border",
+	.type = V4L2_CTRL_TYPE_BOOLEAN,
+	.max = 1,
+	.step = 1,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_show_square = {
+	.ops = &vivid_vid_cap_ctrl_ops,
+	.id = VIVID_CID_SHOW_SQUARE,
+	.name = "Show Square",
+	.type = V4L2_CTRL_TYPE_BOOLEAN,
+	.max = 1,
+	.step = 1,
+};
+
+static const char * const vivid_ctrl_osd_mode_strings[] = {
+	"All",
+	"Counters Only",
+	"None",
+	NULL,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_osd_mode = {
+	.ops = &vivid_vid_cap_ctrl_ops,
+	.id = VIVID_CID_OSD_TEXT_MODE,
+	.name = "OSD Text Mode",
+	.type = V4L2_CTRL_TYPE_MENU,
+	.max = ARRAY_SIZE(vivid_ctrl_osd_mode_strings) - 2,
+	.qmenu = vivid_ctrl_osd_mode_strings,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_perc_fill = {
+	.ops = &vivid_vid_cap_ctrl_ops,
+	.id = VIVID_CID_PERCENTAGE_FILL,
+	.name = "Fill Percentage of Frame",
+	.type = V4L2_CTRL_TYPE_INTEGER,
+	.min = 0,
+	.max = 100,
+	.def = 100,
+	.step = 1,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_insert_sav = {
+	.ops = &vivid_vid_cap_ctrl_ops,
+	.id = VIVID_CID_INSERT_SAV,
+	.name = "Insert SAV Code in Image",
+	.type = V4L2_CTRL_TYPE_BOOLEAN,
+	.max = 1,
+	.step = 1,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_insert_eav = {
+	.ops = &vivid_vid_cap_ctrl_ops,
+	.id = VIVID_CID_INSERT_EAV,
+	.name = "Insert EAV Code in Image",
+	.type = V4L2_CTRL_TYPE_BOOLEAN,
+	.max = 1,
+	.step = 1,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_hflip = {
+	.ops = &vivid_vid_cap_ctrl_ops,
+	.id = VIVID_CID_HFLIP,
+	.name = "Sensor Flipped Horizontally",
+	.type = V4L2_CTRL_TYPE_BOOLEAN,
+	.max = 1,
+	.step = 1,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_vflip = {
+	.ops = &vivid_vid_cap_ctrl_ops,
+	.id = VIVID_CID_VFLIP,
+	.name = "Sensor Flipped Vertically",
+	.type = V4L2_CTRL_TYPE_BOOLEAN,
+	.max = 1,
+	.step = 1,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_reduced_fps = {
+	.ops = &vivid_vid_cap_ctrl_ops,
+	.id = VIVID_CID_REDUCED_FPS,
+	.name = "Reduced Framerate",
+	.type = V4L2_CTRL_TYPE_BOOLEAN,
+	.max = 1,
+	.step = 1,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_has_crop_cap = {
+	.ops = &vivid_vid_cap_ctrl_ops,
+	.id = VIVID_CID_HAS_CROP_CAP,
+	.name = "Enable Capture Cropping",
+	.type = V4L2_CTRL_TYPE_BOOLEAN,
+	.max = 1,
+	.def = 1,
+	.step = 1,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_has_compose_cap = {
+	.ops = &vivid_vid_cap_ctrl_ops,
+	.id = VIVID_CID_HAS_COMPOSE_CAP,
+	.name = "Enable Capture Composing",
+	.type = V4L2_CTRL_TYPE_BOOLEAN,
+	.max = 1,
+	.def = 1,
+	.step = 1,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_has_scaler_cap = {
+	.ops = &vivid_vid_cap_ctrl_ops,
+	.id = VIVID_CID_HAS_SCALER_CAP,
+	.name = "Enable Capture Scaler",
+	.type = V4L2_CTRL_TYPE_BOOLEAN,
+	.max = 1,
+	.def = 1,
+	.step = 1,
+};
+
+static const char * const vivid_ctrl_tstamp_src_strings[] = {
+	"End of Frame",
+	"Start of Exposure",
+	NULL,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_tstamp_src = {
+	.ops = &vivid_vid_cap_ctrl_ops,
+	.id = VIVID_CID_TSTAMP_SRC,
+	.name = "Timestamp Source",
+	.type = V4L2_CTRL_TYPE_MENU,
+	.max = ARRAY_SIZE(vivid_ctrl_tstamp_src_strings) - 2,
+	.qmenu = vivid_ctrl_tstamp_src_strings,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_std_aspect_ratio = {
+	.ops = &vivid_vid_cap_ctrl_ops,
+	.id = VIVID_CID_STD_ASPECT_RATIO,
+	.name = "Standard Aspect Ratio",
+	.type = V4L2_CTRL_TYPE_MENU,
+	.min = 1,
+	.max = 4,
+	.def = 1,
+	.qmenu = tpg_aspect_strings,
+};
+
+static const char * const vivid_ctrl_dv_timings_signal_mode_strings[] = {
+	"Current DV Timings",
+	"No Signal",
+	"No Lock",
+	"Out of Range",
+	"Selected DV Timings",
+	"Cycle Through All DV Timings",
+	"Custom DV Timings",
+	NULL,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_dv_timings_signal_mode = {
+	.ops = &vivid_vid_cap_ctrl_ops,
+	.id = VIVID_CID_DV_TIMINGS_SIGNAL_MODE,
+	.name = "DV Timings Signal Mode",
+	.type = V4L2_CTRL_TYPE_MENU,
+	.max = 5,
+	.qmenu = vivid_ctrl_dv_timings_signal_mode_strings,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_dv_timings_aspect_ratio = {
+	.ops = &vivid_vid_cap_ctrl_ops,
+	.id = VIVID_CID_DV_TIMINGS_ASPECT_RATIO,
+	.name = "DV Timings Aspect Ratio",
+	.type = V4L2_CTRL_TYPE_MENU,
+	.max = 3,
+	.qmenu = tpg_aspect_strings,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_max_edid_blocks = {
+	.ops = &vivid_vid_cap_ctrl_ops,
+	.id = VIVID_CID_MAX_EDID_BLOCKS,
+	.name = "Maximum EDID Blocks",
+	.type = V4L2_CTRL_TYPE_INTEGER,
+	.min = 1,
+	.max = 256,
+	.def = 2,
+	.step = 1,
+};
+
+static const char * const vivid_ctrl_colorspace_strings[] = {
+	"SMPTE 170M",
+	"Rec. 709",
+	"sRGB",
+	"opRGB",
+	"BT.2020",
+	"DCI-P3",
+	"SMPTE 240M",
+	"470 System M",
+	"470 System BG",
+	NULL,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_colorspace = {
+	.ops = &vivid_vid_cap_ctrl_ops,
+	.id = VIVID_CID_COLORSPACE,
+	.name = "Colorspace",
+	.type = V4L2_CTRL_TYPE_MENU,
+	.max = ARRAY_SIZE(vivid_ctrl_colorspace_strings) - 2,
+	.def = 2,
+	.qmenu = vivid_ctrl_colorspace_strings,
+};
+
+static const char * const vivid_ctrl_xfer_func_strings[] = {
+	"Default",
+	"Rec. 709",
+	"sRGB",
+	"opRGB",
+	"SMPTE 240M",
+	"None",
+	"DCI-P3",
+	"SMPTE 2084",
+	NULL,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_xfer_func = {
+	.ops = &vivid_vid_cap_ctrl_ops,
+	.id = VIVID_CID_XFER_FUNC,
+	.name = "Transfer Function",
+	.type = V4L2_CTRL_TYPE_MENU,
+	.max = ARRAY_SIZE(vivid_ctrl_xfer_func_strings) - 2,
+	.qmenu = vivid_ctrl_xfer_func_strings,
+};
+
+static const char * const vivid_ctrl_ycbcr_enc_strings[] = {
+	"Default",
+	"ITU-R 601",
+	"Rec. 709",
+	"xvYCC 601",
+	"xvYCC 709",
+	"",
+	"BT.2020",
+	"BT.2020 Constant Luminance",
+	"SMPTE 240M",
+	NULL,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_ycbcr_enc = {
+	.ops = &vivid_vid_cap_ctrl_ops,
+	.id = VIVID_CID_YCBCR_ENC,
+	.name = "Y'CbCr Encoding",
+	.type = V4L2_CTRL_TYPE_MENU,
+	.menu_skip_mask = 1 << 5,
+	.max = ARRAY_SIZE(vivid_ctrl_ycbcr_enc_strings) - 2,
+	.qmenu = vivid_ctrl_ycbcr_enc_strings,
+};
+
+static const char * const vivid_ctrl_hsv_enc_strings[] = {
+	"Hue 0-179",
+	"Hue 0-256",
+	NULL,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_hsv_enc = {
+	.ops = &vivid_vid_cap_ctrl_ops,
+	.id = VIVID_CID_HSV_ENC,
+	.name = "HSV Encoding",
+	.type = V4L2_CTRL_TYPE_MENU,
+	.max = ARRAY_SIZE(vivid_ctrl_hsv_enc_strings) - 2,
+	.qmenu = vivid_ctrl_hsv_enc_strings,
+};
+
+static const char * const vivid_ctrl_quantization_strings[] = {
+	"Default",
+	"Full Range",
+	"Limited Range",
+	NULL,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_quantization = {
+	.ops = &vivid_vid_cap_ctrl_ops,
+	.id = VIVID_CID_QUANTIZATION,
+	.name = "Quantization",
+	.type = V4L2_CTRL_TYPE_MENU,
+	.max = ARRAY_SIZE(vivid_ctrl_quantization_strings) - 2,
+	.qmenu = vivid_ctrl_quantization_strings,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_alpha_mode = {
+	.ops = &vivid_vid_cap_ctrl_ops,
+	.id = VIVID_CID_ALPHA_MODE,
+	.name = "Apply Alpha To Red Only",
+	.type = V4L2_CTRL_TYPE_BOOLEAN,
+	.max = 1,
+	.step = 1,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_limited_rgb_range = {
+	.ops = &vivid_vid_cap_ctrl_ops,
+	.id = VIVID_CID_LIMITED_RGB_RANGE,
+	.name = "Limited RGB Range (16-235)",
+	.type = V4L2_CTRL_TYPE_BOOLEAN,
+	.max = 1,
+	.step = 1,
+};
+
+
+/* Video Loop Control */
+
+static int vivid_loop_cap_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_loop_cap);
+
+	switch (ctrl->id) {
+	case VIVID_CID_LOOP_VIDEO:
+		dev->loop_video = ctrl->val;
+		vivid_update_quality(dev);
+		vivid_send_source_change(dev, SVID);
+		vivid_send_source_change(dev, HDMI);
+		break;
+	}
+	return 0;
+}
+
+static const struct v4l2_ctrl_ops vivid_loop_cap_ctrl_ops = {
+	.s_ctrl = vivid_loop_cap_s_ctrl,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_loop_video = {
+	.ops = &vivid_loop_cap_ctrl_ops,
+	.id = VIVID_CID_LOOP_VIDEO,
+	.name = "Loop Video",
+	.type = V4L2_CTRL_TYPE_BOOLEAN,
+	.max = 1,
+	.step = 1,
+};
+
+
+/* VBI Capture Control */
+
+static int vivid_vbi_cap_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_vbi_cap);
+
+	switch (ctrl->id) {
+	case VIVID_CID_VBI_CAP_INTERLACED:
+		dev->vbi_cap_interlaced = ctrl->val;
+		break;
+	}
+	return 0;
+}
+
+static const struct v4l2_ctrl_ops vivid_vbi_cap_ctrl_ops = {
+	.s_ctrl = vivid_vbi_cap_s_ctrl,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_vbi_cap_interlaced = {
+	.ops = &vivid_vbi_cap_ctrl_ops,
+	.id = VIVID_CID_VBI_CAP_INTERLACED,
+	.name = "Interlaced VBI Format",
+	.type = V4L2_CTRL_TYPE_BOOLEAN,
+	.max = 1,
+	.step = 1,
+};
+
+
+/* Video Output Controls */
+
+static int vivid_vid_out_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_vid_out);
+	struct v4l2_bt_timings *bt = &dev->dv_timings_out.bt;
+	u32 display_present = 0;
+	unsigned int i, j, bus_idx;
+
+	switch (ctrl->id) {
+	case VIVID_CID_HAS_CROP_OUT:
+		dev->has_crop_out = ctrl->val;
+		vivid_update_format_out(dev);
+		break;
+	case VIVID_CID_HAS_COMPOSE_OUT:
+		dev->has_compose_out = ctrl->val;
+		vivid_update_format_out(dev);
+		break;
+	case VIVID_CID_HAS_SCALER_OUT:
+		dev->has_scaler_out = ctrl->val;
+		vivid_update_format_out(dev);
+		break;
+	case V4L2_CID_DV_TX_MODE:
+		dev->dvi_d_out = ctrl->val == V4L2_DV_TX_MODE_DVI_D;
+		if (!vivid_is_hdmi_out(dev))
+			break;
+		if (!dev->dvi_d_out && (bt->flags & V4L2_DV_FL_IS_CE_VIDEO)) {
+			if (bt->width == 720 && bt->height <= 576)
+				dev->colorspace_out = V4L2_COLORSPACE_SMPTE170M;
+			else
+				dev->colorspace_out = V4L2_COLORSPACE_REC709;
+			dev->quantization_out = V4L2_QUANTIZATION_DEFAULT;
+		} else {
+			dev->colorspace_out = V4L2_COLORSPACE_SRGB;
+			dev->quantization_out = dev->dvi_d_out ?
+					V4L2_QUANTIZATION_LIM_RANGE :
+					V4L2_QUANTIZATION_DEFAULT;
+		}
+		if (dev->loop_video)
+			vivid_send_source_change(dev, HDMI);
+		break;
+	case VIVID_CID_DISPLAY_PRESENT:
+		if (dev->output_type[dev->output] != HDMI)
+			break;
+
+		dev->display_present[dev->output] = ctrl->val;
+		for (i = 0, j = 0; i < dev->num_outputs; i++)
+			if (dev->output_type[i] == HDMI)
+				display_present |=
+					dev->display_present[i] << j++;
+
+		__v4l2_ctrl_s_ctrl(dev->ctrl_tx_rxsense, display_present);
+
+		if (dev->edid_blocks) {
+			__v4l2_ctrl_s_ctrl(dev->ctrl_tx_edid_present,
+					   display_present);
+			__v4l2_ctrl_s_ctrl(dev->ctrl_tx_hotplug,
+					   display_present);
+		}
+
+		bus_idx = dev->cec_output2bus_map[dev->output];
+		if (!dev->cec_tx_adap[bus_idx])
+			break;
+
+		if (ctrl->val && dev->edid_blocks)
+			cec_s_phys_addr(dev->cec_tx_adap[bus_idx],
+					dev->cec_tx_adap[bus_idx]->phys_addr,
+					false);
+		else
+			cec_phys_addr_invalidate(dev->cec_tx_adap[bus_idx]);
+
+		break;
+	}
+	return 0;
+}
+
+static const struct v4l2_ctrl_ops vivid_vid_out_ctrl_ops = {
+	.s_ctrl = vivid_vid_out_s_ctrl,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_has_crop_out = {
+	.ops = &vivid_vid_out_ctrl_ops,
+	.id = VIVID_CID_HAS_CROP_OUT,
+	.name = "Enable Output Cropping",
+	.type = V4L2_CTRL_TYPE_BOOLEAN,
+	.max = 1,
+	.def = 1,
+	.step = 1,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_has_compose_out = {
+	.ops = &vivid_vid_out_ctrl_ops,
+	.id = VIVID_CID_HAS_COMPOSE_OUT,
+	.name = "Enable Output Composing",
+	.type = V4L2_CTRL_TYPE_BOOLEAN,
+	.max = 1,
+	.def = 1,
+	.step = 1,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_has_scaler_out = {
+	.ops = &vivid_vid_out_ctrl_ops,
+	.id = VIVID_CID_HAS_SCALER_OUT,
+	.name = "Enable Output Scaler",
+	.type = V4L2_CTRL_TYPE_BOOLEAN,
+	.max = 1,
+	.def = 1,
+	.step = 1,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_display_present = {
+	.ops = &vivid_vid_out_ctrl_ops,
+	.id = VIVID_CID_DISPLAY_PRESENT,
+	.name = "Display Present",
+	.type = V4L2_CTRL_TYPE_BOOLEAN,
+	.max = 1,
+	.def = 1,
+	.step = 1,
+};
+
+/* Streaming Controls */
+
+static int vivid_streaming_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_streaming);
+	u64 rem;
+
+	switch (ctrl->id) {
+	case VIVID_CID_DQBUF_ERROR:
+		dev->dqbuf_error = true;
+		break;
+	case VIVID_CID_PERC_DROPPED:
+		dev->perc_dropped_buffers = ctrl->val;
+		break;
+	case VIVID_CID_QUEUE_SETUP_ERROR:
+		dev->queue_setup_error = true;
+		break;
+	case VIVID_CID_BUF_PREPARE_ERROR:
+		dev->buf_prepare_error = true;
+		break;
+	case VIVID_CID_START_STR_ERROR:
+		dev->start_streaming_error = true;
+		break;
+	case VIVID_CID_REQ_VALIDATE_ERROR:
+		dev->req_validate_error = true;
+		break;
+	case VIVID_CID_QUEUE_ERROR:
+		if (vb2_start_streaming_called(&dev->vb_vid_cap_q))
+			vb2_queue_error(&dev->vb_vid_cap_q);
+		if (vb2_start_streaming_called(&dev->vb_vbi_cap_q))
+			vb2_queue_error(&dev->vb_vbi_cap_q);
+		if (vb2_start_streaming_called(&dev->vb_vid_out_q))
+			vb2_queue_error(&dev->vb_vid_out_q);
+		if (vb2_start_streaming_called(&dev->vb_vbi_out_q))
+			vb2_queue_error(&dev->vb_vbi_out_q);
+		if (vb2_start_streaming_called(&dev->vb_sdr_cap_q))
+			vb2_queue_error(&dev->vb_sdr_cap_q);
+		break;
+	case VIVID_CID_SEQ_WRAP:
+		dev->seq_wrap = ctrl->val;
+		break;
+	case VIVID_CID_TIME_WRAP:
+		dev->time_wrap = ctrl->val;
+		if (ctrl->val == 0) {
+			dev->time_wrap_offset = 0;
+			break;
+		}
+		/*
+		 * We want to set the time 16 seconds before the 32 bit tv_sec
+		 * value of struct timeval would wrap around. So first we
+		 * calculate ktime_get_ns() % ((1 << 32) * NSEC_PER_SEC), and
+		 * then we set the offset to ((1 << 32) - 16) * NSEC_PER_SEC).
+		 */
+		div64_u64_rem(ktime_get_ns(),
+			0x100000000ULL * NSEC_PER_SEC, &rem);
+		dev->time_wrap_offset =
+			(0x100000000ULL - 16) * NSEC_PER_SEC - rem;
+		break;
+	}
+	return 0;
+}
+
+static const struct v4l2_ctrl_ops vivid_streaming_ctrl_ops = {
+	.s_ctrl = vivid_streaming_s_ctrl,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_dqbuf_error = {
+	.ops = &vivid_streaming_ctrl_ops,
+	.id = VIVID_CID_DQBUF_ERROR,
+	.name = "Inject V4L2_BUF_FLAG_ERROR",
+	.type = V4L2_CTRL_TYPE_BUTTON,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_perc_dropped = {
+	.ops = &vivid_streaming_ctrl_ops,
+	.id = VIVID_CID_PERC_DROPPED,
+	.name = "Percentage of Dropped Buffers",
+	.type = V4L2_CTRL_TYPE_INTEGER,
+	.min = 0,
+	.max = 100,
+	.step = 1,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_queue_setup_error = {
+	.ops = &vivid_streaming_ctrl_ops,
+	.id = VIVID_CID_QUEUE_SETUP_ERROR,
+	.name = "Inject VIDIOC_REQBUFS Error",
+	.type = V4L2_CTRL_TYPE_BUTTON,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_buf_prepare_error = {
+	.ops = &vivid_streaming_ctrl_ops,
+	.id = VIVID_CID_BUF_PREPARE_ERROR,
+	.name = "Inject VIDIOC_QBUF Error",
+	.type = V4L2_CTRL_TYPE_BUTTON,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_start_streaming_error = {
+	.ops = &vivid_streaming_ctrl_ops,
+	.id = VIVID_CID_START_STR_ERROR,
+	.name = "Inject VIDIOC_STREAMON Error",
+	.type = V4L2_CTRL_TYPE_BUTTON,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_queue_error = {
+	.ops = &vivid_streaming_ctrl_ops,
+	.id = VIVID_CID_QUEUE_ERROR,
+	.name = "Inject Fatal Streaming Error",
+	.type = V4L2_CTRL_TYPE_BUTTON,
+};
+
+#ifdef CONFIG_MEDIA_CONTROLLER
+static const struct v4l2_ctrl_config vivid_ctrl_req_validate_error = {
+	.ops = &vivid_streaming_ctrl_ops,
+	.id = VIVID_CID_REQ_VALIDATE_ERROR,
+	.name = "Inject req_validate() Error",
+	.type = V4L2_CTRL_TYPE_BUTTON,
+};
+#endif
+
+static const struct v4l2_ctrl_config vivid_ctrl_seq_wrap = {
+	.ops = &vivid_streaming_ctrl_ops,
+	.id = VIVID_CID_SEQ_WRAP,
+	.name = "Wrap Sequence Number",
+	.type = V4L2_CTRL_TYPE_BOOLEAN,
+	.max = 1,
+	.step = 1,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_time_wrap = {
+	.ops = &vivid_streaming_ctrl_ops,
+	.id = VIVID_CID_TIME_WRAP,
+	.name = "Wrap Timestamp",
+	.type = V4L2_CTRL_TYPE_BOOLEAN,
+	.max = 1,
+	.step = 1,
+};
+
+
+/* SDTV Capture Controls */
+
+static int vivid_sdtv_cap_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_sdtv_cap);
+
+	switch (ctrl->id) {
+	case VIVID_CID_STD_SIGNAL_MODE:
+		dev->std_signal_mode[dev->input] =
+			dev->ctrl_std_signal_mode->val;
+		if (dev->std_signal_mode[dev->input] == SELECTED_STD)
+			dev->query_std[dev->input] =
+				vivid_standard[dev->ctrl_standard->val];
+		v4l2_ctrl_activate(dev->ctrl_standard,
+				   dev->std_signal_mode[dev->input] ==
+					SELECTED_STD);
+		vivid_update_quality(dev);
+		vivid_send_source_change(dev, TV);
+		vivid_send_source_change(dev, SVID);
+		break;
+	}
+	return 0;
+}
+
+static const struct v4l2_ctrl_ops vivid_sdtv_cap_ctrl_ops = {
+	.s_ctrl = vivid_sdtv_cap_s_ctrl,
+};
+
+static const char * const vivid_ctrl_std_signal_mode_strings[] = {
+	"Current Standard",
+	"No Signal",
+	"No Lock",
+	"",
+	"Selected Standard",
+	"Cycle Through All Standards",
+	NULL,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_std_signal_mode = {
+	.ops = &vivid_sdtv_cap_ctrl_ops,
+	.id = VIVID_CID_STD_SIGNAL_MODE,
+	.name = "Standard Signal Mode",
+	.type = V4L2_CTRL_TYPE_MENU,
+	.max = ARRAY_SIZE(vivid_ctrl_std_signal_mode_strings) - 2,
+	.menu_skip_mask = 1 << 3,
+	.qmenu = vivid_ctrl_std_signal_mode_strings,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_standard = {
+	.ops = &vivid_sdtv_cap_ctrl_ops,
+	.id = VIVID_CID_STANDARD,
+	.name = "Standard",
+	.type = V4L2_CTRL_TYPE_MENU,
+	.max = 14,
+	.qmenu = vivid_ctrl_standard_strings,
+};
+
+
+
+/* Radio Receiver Controls */
+
+static int vivid_radio_rx_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_radio_rx);
+
+	switch (ctrl->id) {
+	case VIVID_CID_RADIO_SEEK_MODE:
+		dev->radio_rx_hw_seek_mode = ctrl->val;
+		break;
+	case VIVID_CID_RADIO_SEEK_PROG_LIM:
+		dev->radio_rx_hw_seek_prog_lim = ctrl->val;
+		break;
+	case VIVID_CID_RADIO_RX_RDS_RBDS:
+		dev->rds_gen.use_rbds = ctrl->val;
+		break;
+	case VIVID_CID_RADIO_RX_RDS_BLOCKIO:
+		dev->radio_rx_rds_controls = ctrl->val;
+		dev->radio_rx_caps &= ~V4L2_CAP_READWRITE;
+		dev->radio_rx_rds_use_alternates = false;
+		if (!dev->radio_rx_rds_controls) {
+			dev->radio_rx_caps |= V4L2_CAP_READWRITE;
+			__v4l2_ctrl_s_ctrl(dev->radio_rx_rds_pty, 0);
+			__v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ta, 0);
+			__v4l2_ctrl_s_ctrl(dev->radio_rx_rds_tp, 0);
+			__v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ms, 0);
+			__v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_psname, "");
+			__v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_radiotext, "");
+		}
+		v4l2_ctrl_activate(dev->radio_rx_rds_pty, dev->radio_rx_rds_controls);
+		v4l2_ctrl_activate(dev->radio_rx_rds_psname, dev->radio_rx_rds_controls);
+		v4l2_ctrl_activate(dev->radio_rx_rds_radiotext, dev->radio_rx_rds_controls);
+		v4l2_ctrl_activate(dev->radio_rx_rds_ta, dev->radio_rx_rds_controls);
+		v4l2_ctrl_activate(dev->radio_rx_rds_tp, dev->radio_rx_rds_controls);
+		v4l2_ctrl_activate(dev->radio_rx_rds_ms, dev->radio_rx_rds_controls);
+		dev->radio_rx_dev.device_caps = dev->radio_rx_caps;
+		break;
+	case V4L2_CID_RDS_RECEPTION:
+		dev->radio_rx_rds_enabled = ctrl->val;
+		break;
+	}
+	return 0;
+}
+
+static const struct v4l2_ctrl_ops vivid_radio_rx_ctrl_ops = {
+	.s_ctrl = vivid_radio_rx_s_ctrl,
+};
+
+static const char * const vivid_ctrl_radio_rds_mode_strings[] = {
+	"Block I/O",
+	"Controls",
+	NULL,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_radio_rx_rds_blockio = {
+	.ops = &vivid_radio_rx_ctrl_ops,
+	.id = VIVID_CID_RADIO_RX_RDS_BLOCKIO,
+	.name = "RDS Rx I/O Mode",
+	.type = V4L2_CTRL_TYPE_MENU,
+	.qmenu = vivid_ctrl_radio_rds_mode_strings,
+	.max = 1,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_radio_rx_rds_rbds = {
+	.ops = &vivid_radio_rx_ctrl_ops,
+	.id = VIVID_CID_RADIO_RX_RDS_RBDS,
+	.name = "Generate RBDS Instead of RDS",
+	.type = V4L2_CTRL_TYPE_BOOLEAN,
+	.max = 1,
+	.step = 1,
+};
+
+static const char * const vivid_ctrl_radio_hw_seek_mode_strings[] = {
+	"Bounded",
+	"Wrap Around",
+	"Both",
+	NULL,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_radio_hw_seek_mode = {
+	.ops = &vivid_radio_rx_ctrl_ops,
+	.id = VIVID_CID_RADIO_SEEK_MODE,
+	.name = "Radio HW Seek Mode",
+	.type = V4L2_CTRL_TYPE_MENU,
+	.max = 2,
+	.qmenu = vivid_ctrl_radio_hw_seek_mode_strings,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_radio_hw_seek_prog_lim = {
+	.ops = &vivid_radio_rx_ctrl_ops,
+	.id = VIVID_CID_RADIO_SEEK_PROG_LIM,
+	.name = "Radio Programmable HW Seek",
+	.type = V4L2_CTRL_TYPE_BOOLEAN,
+	.max = 1,
+	.step = 1,
+};
+
+
+/* Radio Transmitter Controls */
+
+static int vivid_radio_tx_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_radio_tx);
+
+	switch (ctrl->id) {
+	case VIVID_CID_RADIO_TX_RDS_BLOCKIO:
+		dev->radio_tx_rds_controls = ctrl->val;
+		dev->radio_tx_caps &= ~V4L2_CAP_READWRITE;
+		if (!dev->radio_tx_rds_controls)
+			dev->radio_tx_caps |= V4L2_CAP_READWRITE;
+		dev->radio_tx_dev.device_caps = dev->radio_tx_caps;
+		break;
+	case V4L2_CID_RDS_TX_PTY:
+		if (dev->radio_rx_rds_controls)
+			v4l2_ctrl_s_ctrl(dev->radio_rx_rds_pty, ctrl->val);
+		break;
+	case V4L2_CID_RDS_TX_PS_NAME:
+		if (dev->radio_rx_rds_controls)
+			v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_psname, ctrl->p_new.p_char);
+		break;
+	case V4L2_CID_RDS_TX_RADIO_TEXT:
+		if (dev->radio_rx_rds_controls)
+			v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_radiotext, ctrl->p_new.p_char);
+		break;
+	case V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT:
+		if (dev->radio_rx_rds_controls)
+			v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ta, ctrl->val);
+		break;
+	case V4L2_CID_RDS_TX_TRAFFIC_PROGRAM:
+		if (dev->radio_rx_rds_controls)
+			v4l2_ctrl_s_ctrl(dev->radio_rx_rds_tp, ctrl->val);
+		break;
+	case V4L2_CID_RDS_TX_MUSIC_SPEECH:
+		if (dev->radio_rx_rds_controls)
+			v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ms, ctrl->val);
+		break;
+	}
+	return 0;
+}
+
+static const struct v4l2_ctrl_ops vivid_radio_tx_ctrl_ops = {
+	.s_ctrl = vivid_radio_tx_s_ctrl,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_radio_tx_rds_blockio = {
+	.ops = &vivid_radio_tx_ctrl_ops,
+	.id = VIVID_CID_RADIO_TX_RDS_BLOCKIO,
+	.name = "RDS Tx I/O Mode",
+	.type = V4L2_CTRL_TYPE_MENU,
+	.qmenu = vivid_ctrl_radio_rds_mode_strings,
+	.max = 1,
+	.def = 1,
+};
+
+
+/* SDR Capture Controls */
+
+static int vivid_sdr_cap_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_sdr_cap);
+
+	switch (ctrl->id) {
+	case VIVID_CID_SDR_CAP_FM_DEVIATION:
+		dev->sdr_fm_deviation = ctrl->val;
+		break;
+	}
+	return 0;
+}
+
+static const struct v4l2_ctrl_ops vivid_sdr_cap_ctrl_ops = {
+	.s_ctrl = vivid_sdr_cap_s_ctrl,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_sdr_cap_fm_deviation = {
+	.ops = &vivid_sdr_cap_ctrl_ops,
+	.id = VIVID_CID_SDR_CAP_FM_DEVIATION,
+	.name = "FM Deviation",
+	.type = V4L2_CTRL_TYPE_INTEGER,
+	.min =    100,
+	.max = 200000,
+	.def =  75000,
+	.step =     1,
+};
+
+/* Metadata Capture Control */
+
+static int vivid_meta_cap_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev,
+					     ctrl_hdl_meta_cap);
+
+	switch (ctrl->id) {
+	case VIVID_CID_META_CAP_GENERATE_PTS:
+		dev->meta_pts = ctrl->val;
+		break;
+	case VIVID_CID_META_CAP_GENERATE_SCR:
+		dev->meta_scr = ctrl->val;
+		break;
+	}
+	return 0;
+}
+
+static const struct v4l2_ctrl_ops vivid_meta_cap_ctrl_ops = {
+	.s_ctrl = vivid_meta_cap_s_ctrl,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_meta_has_pts = {
+	.ops = &vivid_meta_cap_ctrl_ops,
+	.id = VIVID_CID_META_CAP_GENERATE_PTS,
+	.name = "Generate PTS",
+	.type = V4L2_CTRL_TYPE_BOOLEAN,
+	.max = 1,
+	.def = 1,
+	.step = 1,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_meta_has_src_clk = {
+	.ops = &vivid_meta_cap_ctrl_ops,
+	.id = VIVID_CID_META_CAP_GENERATE_SCR,
+	.name = "Generate SCR",
+	.type = V4L2_CTRL_TYPE_BOOLEAN,
+	.max = 1,
+	.def = 1,
+	.step = 1,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_class = {
+	.ops = &vivid_user_gen_ctrl_ops,
+	.flags = V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY,
+	.id = VIVID_CID_VIVID_CLASS,
+	.name = "Vivid Controls",
+	.type = V4L2_CTRL_TYPE_CTRL_CLASS,
+};
+
+int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
+		bool show_ccs_out, bool no_error_inj,
+		bool has_sdtv, bool has_hdmi)
+{
+	struct v4l2_ctrl_handler *hdl_user_gen = &dev->ctrl_hdl_user_gen;
+	struct v4l2_ctrl_handler *hdl_user_vid = &dev->ctrl_hdl_user_vid;
+	struct v4l2_ctrl_handler *hdl_user_aud = &dev->ctrl_hdl_user_aud;
+	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;
+	struct v4l2_ctrl_handler *hdl_vbi_out = &dev->ctrl_hdl_vbi_out;
+	struct v4l2_ctrl_handler *hdl_radio_rx = &dev->ctrl_hdl_radio_rx;
+	struct v4l2_ctrl_handler *hdl_radio_tx = &dev->ctrl_hdl_radio_tx;
+	struct v4l2_ctrl_handler *hdl_sdr_cap = &dev->ctrl_hdl_sdr_cap;
+	struct v4l2_ctrl_handler *hdl_meta_cap = &dev->ctrl_hdl_meta_cap;
+	struct v4l2_ctrl_handler *hdl_meta_out = &dev->ctrl_hdl_meta_out;
+	struct v4l2_ctrl_handler *hdl_tch_cap = &dev->ctrl_hdl_touch_cap;
+
+	struct v4l2_ctrl_config vivid_ctrl_dv_timings = {
+		.ops = &vivid_vid_cap_ctrl_ops,
+		.id = VIVID_CID_DV_TIMINGS,
+		.name = "DV Timings",
+		.type = V4L2_CTRL_TYPE_MENU,
+	};
+	int i;
+
+	v4l2_ctrl_handler_init(hdl_user_gen, 10);
+	v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_class, NULL);
+	v4l2_ctrl_handler_init(hdl_user_vid, 9);
+	v4l2_ctrl_new_custom(hdl_user_vid, &vivid_ctrl_class, NULL);
+	v4l2_ctrl_handler_init(hdl_user_aud, 2);
+	v4l2_ctrl_new_custom(hdl_user_aud, &vivid_ctrl_class, NULL);
+	v4l2_ctrl_handler_init(hdl_streaming, 8);
+	v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_class, NULL);
+	v4l2_ctrl_handler_init(hdl_sdtv_cap, 2);
+	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 || dev->has_fb || dev->num_hdmi_outputs)
+		v4l2_ctrl_new_custom(hdl_vid_out, &vivid_ctrl_class, NULL);
+	v4l2_ctrl_handler_init(hdl_vbi_cap, 21);
+	v4l2_ctrl_new_custom(hdl_vbi_cap, &vivid_ctrl_class, NULL);
+	v4l2_ctrl_handler_init(hdl_vbi_out, 19);
+	if (!no_error_inj)
+		v4l2_ctrl_new_custom(hdl_vbi_out, &vivid_ctrl_class, NULL);
+	v4l2_ctrl_handler_init(hdl_radio_rx, 17);
+	v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_class, NULL);
+	v4l2_ctrl_handler_init(hdl_radio_tx, 17);
+	v4l2_ctrl_new_custom(hdl_radio_tx, &vivid_ctrl_class, NULL);
+	v4l2_ctrl_handler_init(hdl_sdr_cap, 19);
+	v4l2_ctrl_new_custom(hdl_sdr_cap, &vivid_ctrl_class, NULL);
+	v4l2_ctrl_handler_init(hdl_meta_cap, 2);
+	v4l2_ctrl_new_custom(hdl_meta_cap, &vivid_ctrl_class, NULL);
+	v4l2_ctrl_handler_init(hdl_meta_out, 2);
+	v4l2_ctrl_new_custom(hdl_meta_out, &vivid_ctrl_class, NULL);
+	v4l2_ctrl_handler_init(hdl_tch_cap, 2);
+	v4l2_ctrl_new_custom(hdl_tch_cap, &vivid_ctrl_class, NULL);
+
+	/* User Controls */
+	dev->volume = v4l2_ctrl_new_std(hdl_user_aud, NULL,
+		V4L2_CID_AUDIO_VOLUME, 0, 255, 1, 200);
+	dev->mute = v4l2_ctrl_new_std(hdl_user_aud, NULL,
+		V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
+	if (dev->has_vid_cap) {
+		dev->brightness = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
+			V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
+		for (i = 0; i < MAX_INPUTS; i++)
+			dev->input_brightness[i] = 128;
+		dev->contrast = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
+			V4L2_CID_CONTRAST, 0, 255, 1, 128);
+		dev->saturation = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
+			V4L2_CID_SATURATION, 0, 255, 1, 128);
+		dev->hue = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
+			V4L2_CID_HUE, -128, 128, 1, 0);
+		v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
+			V4L2_CID_HFLIP, 0, 1, 1, 0);
+		v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
+			V4L2_CID_VFLIP, 0, 1, 1, 0);
+		dev->autogain = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
+			V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
+		dev->gain = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
+			V4L2_CID_GAIN, 0, 255, 1, 100);
+		dev->alpha = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
+			V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 0);
+	}
+	dev->button = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_button, NULL);
+	dev->int32 = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_int32, NULL);
+	dev->int64 = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_int64, NULL);
+	dev->boolean = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_boolean, NULL);
+	dev->menu = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_menu, NULL);
+	dev->string = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_string, NULL);
+	dev->bitmask = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_bitmask, NULL);
+	dev->int_menu = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_int_menu, NULL);
+	v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_area, NULL);
+	v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u32_array, NULL);
+	v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u16_matrix, NULL);
+	v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u8_4d_array, NULL);
+
+	if (dev->has_vid_cap) {
+		/* Image Processing Controls */
+		struct v4l2_ctrl_config vivid_ctrl_test_pattern = {
+			.ops = &vivid_vid_cap_ctrl_ops,
+			.id = VIVID_CID_TEST_PATTERN,
+			.name = "Test Pattern",
+			.type = V4L2_CTRL_TYPE_MENU,
+			.max = TPG_PAT_NOISE,
+			.qmenu = tpg_pattern_strings,
+		};
+
+		dev->test_pattern = v4l2_ctrl_new_custom(hdl_vid_cap,
+				&vivid_ctrl_test_pattern, NULL);
+		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_perc_fill, NULL);
+		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_hor_movement, NULL);
+		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_vert_movement, NULL);
+		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_osd_mode, NULL);
+		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_show_border, NULL);
+		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_show_square, NULL);
+		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_hflip, NULL);
+		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_vflip, NULL);
+		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_insert_sav, NULL);
+		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_insert_eav, NULL);
+		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_reduced_fps, NULL);
+		if (show_ccs_cap) {
+			dev->ctrl_has_crop_cap = v4l2_ctrl_new_custom(hdl_vid_cap,
+				&vivid_ctrl_has_crop_cap, NULL);
+			dev->ctrl_has_compose_cap = v4l2_ctrl_new_custom(hdl_vid_cap,
+				&vivid_ctrl_has_compose_cap, NULL);
+			dev->ctrl_has_scaler_cap = v4l2_ctrl_new_custom(hdl_vid_cap,
+				&vivid_ctrl_has_scaler_cap, NULL);
+		}
+
+		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_tstamp_src, NULL);
+		dev->colorspace = v4l2_ctrl_new_custom(hdl_vid_cap,
+			&vivid_ctrl_colorspace, NULL);
+		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_xfer_func, NULL);
+		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_ycbcr_enc, NULL);
+		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_hsv_enc, NULL);
+		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_quantization, NULL);
+		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_alpha_mode, NULL);
+	}
+
+	if (dev->has_vid_out && show_ccs_out) {
+		dev->ctrl_has_crop_out = v4l2_ctrl_new_custom(hdl_vid_out,
+			&vivid_ctrl_has_crop_out, NULL);
+		dev->ctrl_has_compose_out = v4l2_ctrl_new_custom(hdl_vid_out,
+			&vivid_ctrl_has_compose_out, NULL);
+		dev->ctrl_has_scaler_out = v4l2_ctrl_new_custom(hdl_vid_out,
+			&vivid_ctrl_has_scaler_out, NULL);
+	}
+
+	/*
+	 * Testing this driver with v4l2-compliance will trigger the error
+	 * injection controls, and after that nothing will work as expected.
+	 * So we have a module option to drop these error injecting controls
+	 * allowing us to run v4l2_compliance again.
+	 */
+	if (!no_error_inj) {
+		v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_disconnect, NULL);
+		v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_dqbuf_error, NULL);
+		v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_perc_dropped, NULL);
+		v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_queue_setup_error, NULL);
+		v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_buf_prepare_error, NULL);
+		v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_start_streaming_error, NULL);
+		v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_queue_error, NULL);
+#ifdef CONFIG_MEDIA_CONTROLLER
+		v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_req_validate_error, NULL);
+#endif
+		v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_seq_wrap, NULL);
+		v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_time_wrap, NULL);
+	}
+
+	if (has_sdtv && (dev->has_vid_cap || dev->has_vbi_cap)) {
+		if (dev->has_vid_cap)
+			v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_std_aspect_ratio, NULL);
+		dev->ctrl_std_signal_mode = v4l2_ctrl_new_custom(hdl_sdtv_cap,
+			&vivid_ctrl_std_signal_mode, NULL);
+		dev->ctrl_standard = v4l2_ctrl_new_custom(hdl_sdtv_cap,
+			&vivid_ctrl_standard, NULL);
+		if (dev->ctrl_std_signal_mode)
+			v4l2_ctrl_cluster(2, &dev->ctrl_std_signal_mode);
+		if (dev->has_raw_vbi_cap)
+			v4l2_ctrl_new_custom(hdl_vbi_cap, &vivid_ctrl_vbi_cap_interlaced, NULL);
+	}
+
+	if (dev->num_hdmi_inputs) {
+		s64 hdmi_input_mask = GENMASK(dev->num_hdmi_inputs - 1, 0);
+
+		dev->ctrl_dv_timings_signal_mode = v4l2_ctrl_new_custom(hdl_vid_cap,
+					&vivid_ctrl_dv_timings_signal_mode, NULL);
+
+		vivid_ctrl_dv_timings.max = dev->query_dv_timings_size - 1;
+		vivid_ctrl_dv_timings.qmenu =
+			(const char * const *)dev->query_dv_timings_qmenu;
+		dev->ctrl_dv_timings = v4l2_ctrl_new_custom(hdl_vid_cap,
+			&vivid_ctrl_dv_timings, NULL);
+		if (dev->ctrl_dv_timings_signal_mode)
+			v4l2_ctrl_cluster(2, &dev->ctrl_dv_timings_signal_mode);
+
+		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_dv_timings_aspect_ratio, NULL);
+		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_max_edid_blocks, NULL);
+		dev->real_rgb_range_cap = v4l2_ctrl_new_custom(hdl_vid_cap,
+			&vivid_ctrl_limited_rgb_range, NULL);
+		dev->rgb_range_cap = v4l2_ctrl_new_std_menu(hdl_vid_cap,
+			&vivid_vid_cap_ctrl_ops,
+			V4L2_CID_DV_RX_RGB_RANGE, V4L2_DV_RGB_RANGE_FULL,
+			0, V4L2_DV_RGB_RANGE_AUTO);
+		dev->ctrl_rx_power_present = v4l2_ctrl_new_std(hdl_vid_cap,
+			NULL, V4L2_CID_DV_RX_POWER_PRESENT, 0, hdmi_input_mask,
+			0, hdmi_input_mask);
+
+	}
+	if (dev->num_hdmi_outputs) {
+		s64 hdmi_output_mask = GENMASK(dev->num_hdmi_outputs - 1, 0);
+
+		/*
+		 * We aren't doing anything with this at the moment, but
+		 * HDMI outputs typically have this controls.
+		 */
+		dev->ctrl_tx_rgb_range = v4l2_ctrl_new_std_menu(hdl_vid_out, NULL,
+			V4L2_CID_DV_TX_RGB_RANGE, V4L2_DV_RGB_RANGE_FULL,
+			0, V4L2_DV_RGB_RANGE_AUTO);
+		dev->ctrl_tx_mode = v4l2_ctrl_new_std_menu(hdl_vid_out, NULL,
+			V4L2_CID_DV_TX_MODE, V4L2_DV_TX_MODE_HDMI,
+			0, V4L2_DV_TX_MODE_HDMI);
+		dev->ctrl_display_present = v4l2_ctrl_new_custom(hdl_vid_out,
+			&vivid_ctrl_display_present, NULL);
+		dev->ctrl_tx_hotplug = v4l2_ctrl_new_std(hdl_vid_out,
+			NULL, V4L2_CID_DV_TX_HOTPLUG, 0, hdmi_output_mask,
+			0, hdmi_output_mask);
+		dev->ctrl_tx_rxsense = v4l2_ctrl_new_std(hdl_vid_out,
+			NULL, V4L2_CID_DV_TX_RXSENSE, 0, hdmi_output_mask,
+			0, hdmi_output_mask);
+		dev->ctrl_tx_edid_present = v4l2_ctrl_new_std(hdl_vid_out,
+			NULL, V4L2_CID_DV_TX_EDID_PRESENT, 0, hdmi_output_mask,
+			0, hdmi_output_mask);
+	}
+	if ((dev->has_vid_cap && dev->has_vid_out) ||
+	    (dev->has_vbi_cap && dev->has_vbi_out))
+		v4l2_ctrl_new_custom(hdl_loop_cap, &vivid_ctrl_loop_video, NULL);
+
+	if (dev->has_fb)
+		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);
+		v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_hw_seek_prog_lim, NULL);
+		v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_rx_rds_blockio, NULL);
+		v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_rx_rds_rbds, NULL);
+		v4l2_ctrl_new_std(hdl_radio_rx, &vivid_radio_rx_ctrl_ops,
+			V4L2_CID_RDS_RECEPTION, 0, 1, 1, 1);
+		dev->radio_rx_rds_pty = v4l2_ctrl_new_std(hdl_radio_rx,
+			&vivid_radio_rx_ctrl_ops,
+			V4L2_CID_RDS_RX_PTY, 0, 31, 1, 0);
+		dev->radio_rx_rds_psname = v4l2_ctrl_new_std(hdl_radio_rx,
+			&vivid_radio_rx_ctrl_ops,
+			V4L2_CID_RDS_RX_PS_NAME, 0, 8, 8, 0);
+		dev->radio_rx_rds_radiotext = v4l2_ctrl_new_std(hdl_radio_rx,
+			&vivid_radio_rx_ctrl_ops,
+			V4L2_CID_RDS_RX_RADIO_TEXT, 0, 64, 64, 0);
+		dev->radio_rx_rds_ta = v4l2_ctrl_new_std(hdl_radio_rx,
+			&vivid_radio_rx_ctrl_ops,
+			V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT, 0, 1, 1, 0);
+		dev->radio_rx_rds_tp = v4l2_ctrl_new_std(hdl_radio_rx,
+			&vivid_radio_rx_ctrl_ops,
+			V4L2_CID_RDS_RX_TRAFFIC_PROGRAM, 0, 1, 1, 0);
+		dev->radio_rx_rds_ms = v4l2_ctrl_new_std(hdl_radio_rx,
+			&vivid_radio_rx_ctrl_ops,
+			V4L2_CID_RDS_RX_MUSIC_SPEECH, 0, 1, 1, 1);
+	}
+	if (dev->has_radio_tx) {
+		v4l2_ctrl_new_custom(hdl_radio_tx,
+			&vivid_ctrl_radio_tx_rds_blockio, NULL);
+		dev->radio_tx_rds_pi = v4l2_ctrl_new_std(hdl_radio_tx,
+			&vivid_radio_tx_ctrl_ops,
+			V4L2_CID_RDS_TX_PI, 0, 0xffff, 1, 0x8088);
+		dev->radio_tx_rds_pty = v4l2_ctrl_new_std(hdl_radio_tx,
+			&vivid_radio_tx_ctrl_ops,
+			V4L2_CID_RDS_TX_PTY, 0, 31, 1, 3);
+		dev->radio_tx_rds_psname = v4l2_ctrl_new_std(hdl_radio_tx,
+			&vivid_radio_tx_ctrl_ops,
+			V4L2_CID_RDS_TX_PS_NAME, 0, 8, 8, 0);
+		if (dev->radio_tx_rds_psname)
+			v4l2_ctrl_s_ctrl_string(dev->radio_tx_rds_psname, "VIVID-TX");
+		dev->radio_tx_rds_radiotext = v4l2_ctrl_new_std(hdl_radio_tx,
+			&vivid_radio_tx_ctrl_ops,
+			V4L2_CID_RDS_TX_RADIO_TEXT, 0, 64 * 2, 64, 0);
+		if (dev->radio_tx_rds_radiotext)
+			v4l2_ctrl_s_ctrl_string(dev->radio_tx_rds_radiotext,
+			       "This is a VIVID default Radio Text template text, change at will");
+		dev->radio_tx_rds_mono_stereo = v4l2_ctrl_new_std(hdl_radio_tx,
+			&vivid_radio_tx_ctrl_ops,
+			V4L2_CID_RDS_TX_MONO_STEREO, 0, 1, 1, 1);
+		dev->radio_tx_rds_art_head = v4l2_ctrl_new_std(hdl_radio_tx,
+			&vivid_radio_tx_ctrl_ops,
+			V4L2_CID_RDS_TX_ARTIFICIAL_HEAD, 0, 1, 1, 0);
+		dev->radio_tx_rds_compressed = v4l2_ctrl_new_std(hdl_radio_tx,
+			&vivid_radio_tx_ctrl_ops,
+			V4L2_CID_RDS_TX_COMPRESSED, 0, 1, 1, 0);
+		dev->radio_tx_rds_dyn_pty = v4l2_ctrl_new_std(hdl_radio_tx,
+			&vivid_radio_tx_ctrl_ops,
+			V4L2_CID_RDS_TX_DYNAMIC_PTY, 0, 1, 1, 0);
+		dev->radio_tx_rds_ta = v4l2_ctrl_new_std(hdl_radio_tx,
+			&vivid_radio_tx_ctrl_ops,
+			V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT, 0, 1, 1, 0);
+		dev->radio_tx_rds_tp = v4l2_ctrl_new_std(hdl_radio_tx,
+			&vivid_radio_tx_ctrl_ops,
+			V4L2_CID_RDS_TX_TRAFFIC_PROGRAM, 0, 1, 1, 1);
+		dev->radio_tx_rds_ms = v4l2_ctrl_new_std(hdl_radio_tx,
+			&vivid_radio_tx_ctrl_ops,
+			V4L2_CID_RDS_TX_MUSIC_SPEECH, 0, 1, 1, 1);
+	}
+	if (dev->has_sdr_cap) {
+		v4l2_ctrl_new_custom(hdl_sdr_cap,
+			&vivid_ctrl_sdr_cap_fm_deviation, NULL);
+	}
+	if (dev->has_meta_cap) {
+		v4l2_ctrl_new_custom(hdl_meta_cap,
+				     &vivid_ctrl_meta_has_pts, NULL);
+		v4l2_ctrl_new_custom(hdl_meta_cap,
+				     &vivid_ctrl_meta_has_src_clk, NULL);
+	}
+
+	if (hdl_user_gen->error)
+		return hdl_user_gen->error;
+	if (hdl_user_vid->error)
+		return hdl_user_vid->error;
+	if (hdl_user_aud->error)
+		return hdl_user_aud->error;
+	if (hdl_streaming->error)
+		return hdl_streaming->error;
+	if (hdl_sdr_cap->error)
+		return hdl_sdr_cap->error;
+	if (hdl_loop_cap->error)
+		return hdl_loop_cap->error;
+
+	if (dev->autogain)
+		v4l2_ctrl_auto_cluster(2, &dev->autogain, 0, true);
+
+	if (dev->has_vid_cap) {
+		v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_gen, NULL, false);
+		v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_vid, NULL, false);
+		v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_aud, NULL, false);
+		v4l2_ctrl_add_handler(hdl_vid_cap, hdl_streaming, NULL, false);
+		v4l2_ctrl_add_handler(hdl_vid_cap, hdl_sdtv_cap, NULL, false);
+		v4l2_ctrl_add_handler(hdl_vid_cap, hdl_loop_cap, NULL, false);
+		v4l2_ctrl_add_handler(hdl_vid_cap, hdl_fb, NULL, false);
+		if (hdl_vid_cap->error)
+			return hdl_vid_cap->error;
+		dev->vid_cap_dev.ctrl_handler = hdl_vid_cap;
+	}
+	if (dev->has_vid_out) {
+		v4l2_ctrl_add_handler(hdl_vid_out, hdl_user_gen, NULL, false);
+		v4l2_ctrl_add_handler(hdl_vid_out, hdl_user_aud, NULL, false);
+		v4l2_ctrl_add_handler(hdl_vid_out, hdl_streaming, NULL, false);
+		v4l2_ctrl_add_handler(hdl_vid_out, hdl_fb, NULL, false);
+		if (hdl_vid_out->error)
+			return hdl_vid_out->error;
+		dev->vid_out_dev.ctrl_handler = hdl_vid_out;
+	}
+	if (dev->has_vbi_cap) {
+		v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_user_gen, NULL, false);
+		v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_streaming, NULL, false);
+		v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_sdtv_cap, NULL, false);
+		v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_loop_cap, NULL, false);
+		if (hdl_vbi_cap->error)
+			return hdl_vbi_cap->error;
+		dev->vbi_cap_dev.ctrl_handler = hdl_vbi_cap;
+	}
+	if (dev->has_vbi_out) {
+		v4l2_ctrl_add_handler(hdl_vbi_out, hdl_user_gen, NULL, false);
+		v4l2_ctrl_add_handler(hdl_vbi_out, hdl_streaming, NULL, false);
+		if (hdl_vbi_out->error)
+			return hdl_vbi_out->error;
+		dev->vbi_out_dev.ctrl_handler = hdl_vbi_out;
+	}
+	if (dev->has_radio_rx) {
+		v4l2_ctrl_add_handler(hdl_radio_rx, hdl_user_gen, NULL, false);
+		v4l2_ctrl_add_handler(hdl_radio_rx, hdl_user_aud, NULL, false);
+		if (hdl_radio_rx->error)
+			return hdl_radio_rx->error;
+		dev->radio_rx_dev.ctrl_handler = hdl_radio_rx;
+	}
+	if (dev->has_radio_tx) {
+		v4l2_ctrl_add_handler(hdl_radio_tx, hdl_user_gen, NULL, false);
+		v4l2_ctrl_add_handler(hdl_radio_tx, hdl_user_aud, NULL, false);
+		if (hdl_radio_tx->error)
+			return hdl_radio_tx->error;
+		dev->radio_tx_dev.ctrl_handler = hdl_radio_tx;
+	}
+	if (dev->has_sdr_cap) {
+		v4l2_ctrl_add_handler(hdl_sdr_cap, hdl_user_gen, NULL, false);
+		v4l2_ctrl_add_handler(hdl_sdr_cap, hdl_streaming, NULL, false);
+		if (hdl_sdr_cap->error)
+			return hdl_sdr_cap->error;
+		dev->sdr_cap_dev.ctrl_handler = hdl_sdr_cap;
+	}
+	if (dev->has_meta_cap) {
+		v4l2_ctrl_add_handler(hdl_meta_cap, hdl_user_gen, NULL, false);
+		v4l2_ctrl_add_handler(hdl_meta_cap, hdl_streaming, NULL, false);
+		if (hdl_meta_cap->error)
+			return hdl_meta_cap->error;
+		dev->meta_cap_dev.ctrl_handler = hdl_meta_cap;
+	}
+	if (dev->has_meta_out) {
+		v4l2_ctrl_add_handler(hdl_meta_out, hdl_user_gen, NULL, false);
+		v4l2_ctrl_add_handler(hdl_meta_out, hdl_streaming, NULL, false);
+		if (hdl_meta_out->error)
+			return hdl_meta_out->error;
+		dev->meta_out_dev.ctrl_handler = hdl_meta_out;
+	}
+	if (dev->has_touch_cap) {
+		v4l2_ctrl_add_handler(hdl_tch_cap, hdl_user_gen, NULL, false);
+		v4l2_ctrl_add_handler(hdl_tch_cap, hdl_streaming, NULL, false);
+		if (hdl_tch_cap->error)
+			return hdl_tch_cap->error;
+		dev->touch_cap_dev.ctrl_handler = hdl_tch_cap;
+	}
+	return 0;
+}
+
+void vivid_free_controls(struct vivid_dev *dev)
+{
+	v4l2_ctrl_handler_free(&dev->ctrl_hdl_vid_cap);
+	v4l2_ctrl_handler_free(&dev->ctrl_hdl_vid_out);
+	v4l2_ctrl_handler_free(&dev->ctrl_hdl_vbi_cap);
+	v4l2_ctrl_handler_free(&dev->ctrl_hdl_vbi_out);
+	v4l2_ctrl_handler_free(&dev->ctrl_hdl_radio_rx);
+	v4l2_ctrl_handler_free(&dev->ctrl_hdl_radio_tx);
+	v4l2_ctrl_handler_free(&dev->ctrl_hdl_sdr_cap);
+	v4l2_ctrl_handler_free(&dev->ctrl_hdl_user_gen);
+	v4l2_ctrl_handler_free(&dev->ctrl_hdl_user_vid);
+	v4l2_ctrl_handler_free(&dev->ctrl_hdl_user_aud);
+	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);
+	v4l2_ctrl_handler_free(&dev->ctrl_hdl_meta_cap);
+	v4l2_ctrl_handler_free(&dev->ctrl_hdl_meta_out);
+	v4l2_ctrl_handler_free(&dev->ctrl_hdl_touch_cap);
+}
diff --git a/drivers/media/test-drivers/vivid/vivid-ctrls.h b/drivers/media/test-drivers/vivid/vivid-ctrls.h
new file mode 100644
index 000000000000..6fad5f5d0054
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-ctrls.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * vivid-ctrls.h - control support functions.
+ *
+ * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _VIVID_CTRLS_H_
+#define _VIVID_CTRLS_H_
+
+enum vivid_hw_seek_modes {
+	VIVID_HW_SEEK_BOUNDED,
+	VIVID_HW_SEEK_WRAP,
+	VIVID_HW_SEEK_BOTH,
+};
+
+int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
+		bool show_ccs_out, bool no_error_inj,
+		bool has_sdtv, bool has_hdmi);
+void vivid_free_controls(struct vivid_dev *dev);
+
+#endif
diff --git a/drivers/media/test-drivers/vivid/vivid-kthread-cap.c b/drivers/media/test-drivers/vivid/vivid-kthread-cap.c
new file mode 100644
index 000000000000..01a9d671b947
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-kthread-cap.c
@@ -0,0 +1,1007 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * vivid-kthread-cap.h - video/vbi capture thread support functions.
+ *
+ * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/font.h>
+#include <linux/mutex.h>
+#include <linux/videodev2.h>
+#include <linux/kthread.h>
+#include <linux/freezer.h>
+#include <linux/random.h>
+#include <linux/v4l2-dv-timings.h>
+#include <asm/div64.h>
+#include <media/videobuf2-vmalloc.h>
+#include <media/v4l2-dv-timings.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-fh.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-rect.h>
+
+#include "vivid-core.h"
+#include "vivid-vid-common.h"
+#include "vivid-vid-cap.h"
+#include "vivid-vid-out.h"
+#include "vivid-radio-common.h"
+#include "vivid-radio-rx.h"
+#include "vivid-radio-tx.h"
+#include "vivid-sdr-cap.h"
+#include "vivid-vbi-cap.h"
+#include "vivid-vbi-out.h"
+#include "vivid-osd.h"
+#include "vivid-ctrls.h"
+#include "vivid-kthread-cap.h"
+#include "vivid-meta-cap.h"
+
+static inline v4l2_std_id vivid_get_std_cap(const struct vivid_dev *dev)
+{
+	if (vivid_is_sdtv_cap(dev))
+		return dev->std_cap[dev->input];
+	return 0;
+}
+
+static void copy_pix(struct vivid_dev *dev, int win_y, int win_x,
+			u16 *cap, const u16 *osd)
+{
+	u16 out;
+	int left = dev->overlay_out_left;
+	int top = dev->overlay_out_top;
+	int fb_x = win_x + left;
+	int fb_y = win_y + top;
+	int i;
+
+	out = *cap;
+	*cap = *osd;
+	if (dev->bitmap_out) {
+		const u8 *p = dev->bitmap_out;
+		unsigned stride = (dev->compose_out.width + 7) / 8;
+
+		win_x -= dev->compose_out.left;
+		win_y -= dev->compose_out.top;
+		if (!(p[stride * win_y + win_x / 8] & (1 << (win_x & 7))))
+			return;
+	}
+
+	for (i = 0; i < dev->clipcount_out; i++) {
+		struct v4l2_rect *r = &dev->clips_out[i].c;
+
+		if (fb_y >= r->top && fb_y < r->top + r->height &&
+		    fb_x >= r->left && fb_x < r->left + r->width)
+			return;
+	}
+	if ((dev->fbuf_out_flags & V4L2_FBUF_FLAG_CHROMAKEY) &&
+	    *osd != dev->chromakey_out)
+		return;
+	if ((dev->fbuf_out_flags & V4L2_FBUF_FLAG_SRC_CHROMAKEY) &&
+	    out == dev->chromakey_out)
+		return;
+	if (dev->fmt_cap->alpha_mask) {
+		if ((dev->fbuf_out_flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) &&
+		    dev->global_alpha_out)
+			return;
+		if ((dev->fbuf_out_flags & V4L2_FBUF_FLAG_LOCAL_ALPHA) &&
+		    *cap & dev->fmt_cap->alpha_mask)
+			return;
+		if ((dev->fbuf_out_flags & V4L2_FBUF_FLAG_LOCAL_INV_ALPHA) &&
+		    !(*cap & dev->fmt_cap->alpha_mask))
+			return;
+	}
+	*cap = out;
+}
+
+static void blend_line(struct vivid_dev *dev, unsigned y_offset, unsigned x_offset,
+		u8 *vcapbuf, const u8 *vosdbuf,
+		unsigned width, unsigned pixsize)
+{
+	unsigned x;
+
+	for (x = 0; x < width; x++, vcapbuf += pixsize, vosdbuf += pixsize) {
+		copy_pix(dev, y_offset, x_offset + x,
+			 (u16 *)vcapbuf, (const u16 *)vosdbuf);
+	}
+}
+
+static void scale_line(const u8 *src, u8 *dst, unsigned srcw, unsigned dstw, unsigned twopixsize)
+{
+	/* Coarse scaling with Bresenham */
+	unsigned int_part;
+	unsigned fract_part;
+	unsigned src_x = 0;
+	unsigned error = 0;
+	unsigned x;
+
+	/*
+	 * We always combine two pixels to prevent color bleed in the packed
+	 * yuv case.
+	 */
+	srcw /= 2;
+	dstw /= 2;
+	int_part = srcw / dstw;
+	fract_part = srcw % dstw;
+	for (x = 0; x < dstw; x++, dst += twopixsize) {
+		memcpy(dst, src + src_x * twopixsize, twopixsize);
+		src_x += int_part;
+		error += fract_part;
+		if (error >= dstw) {
+			error -= dstw;
+			src_x++;
+		}
+	}
+}
+
+/*
+ * Precalculate the rectangles needed to perform video looping:
+ *
+ * The nominal pipeline is that the video output buffer is cropped by
+ * crop_out, scaled to compose_out, overlaid with the output overlay,
+ * cropped on the capture side by crop_cap and scaled again to the video
+ * capture buffer using compose_cap.
+ *
+ * To keep things efficient we calculate the intersection of compose_out
+ * and crop_cap (since that's the only part of the video that will
+ * actually end up in the capture buffer), determine which part of the
+ * video output buffer that is and which part of the video capture buffer
+ * so we can scale the video straight from the output buffer to the capture
+ * buffer without any intermediate steps.
+ *
+ * If we need to deal with an output overlay, then there is no choice and
+ * that intermediate step still has to be taken. For the output overlay
+ * support we calculate the intersection of the framebuffer and the overlay
+ * window (which may be partially or wholly outside of the framebuffer
+ * itself) and the intersection of that with loop_vid_copy (i.e. the part of
+ * the actual looped video that will be overlaid). The result is calculated
+ * both in framebuffer coordinates (loop_fb_copy) and compose_out coordinates
+ * (loop_vid_overlay). Finally calculate the part of the capture buffer that
+ * will receive that overlaid video.
+ */
+static void vivid_precalc_copy_rects(struct vivid_dev *dev)
+{
+	/* Framebuffer rectangle */
+	struct v4l2_rect r_fb = {
+		0, 0, dev->display_width, dev->display_height
+	};
+	/* Overlay window rectangle in framebuffer coordinates */
+	struct v4l2_rect r_overlay = {
+		dev->overlay_out_left, dev->overlay_out_top,
+		dev->compose_out.width, dev->compose_out.height
+	};
+
+	v4l2_rect_intersect(&dev->loop_vid_copy, &dev->crop_cap, &dev->compose_out);
+
+	dev->loop_vid_out = dev->loop_vid_copy;
+	v4l2_rect_scale(&dev->loop_vid_out, &dev->compose_out, &dev->crop_out);
+	dev->loop_vid_out.left += dev->crop_out.left;
+	dev->loop_vid_out.top += dev->crop_out.top;
+
+	dev->loop_vid_cap = dev->loop_vid_copy;
+	v4l2_rect_scale(&dev->loop_vid_cap, &dev->crop_cap, &dev->compose_cap);
+
+	dprintk(dev, 1,
+		"loop_vid_copy: %dx%d@%dx%d loop_vid_out: %dx%d@%dx%d loop_vid_cap: %dx%d@%dx%d\n",
+		dev->loop_vid_copy.width, dev->loop_vid_copy.height,
+		dev->loop_vid_copy.left, dev->loop_vid_copy.top,
+		dev->loop_vid_out.width, dev->loop_vid_out.height,
+		dev->loop_vid_out.left, dev->loop_vid_out.top,
+		dev->loop_vid_cap.width, dev->loop_vid_cap.height,
+		dev->loop_vid_cap.left, dev->loop_vid_cap.top);
+
+	v4l2_rect_intersect(&r_overlay, &r_fb, &r_overlay);
+
+	/* shift r_overlay to the same origin as compose_out */
+	r_overlay.left += dev->compose_out.left - dev->overlay_out_left;
+	r_overlay.top += dev->compose_out.top - dev->overlay_out_top;
+
+	v4l2_rect_intersect(&dev->loop_vid_overlay, &r_overlay, &dev->loop_vid_copy);
+	dev->loop_fb_copy = dev->loop_vid_overlay;
+
+	/* shift dev->loop_fb_copy back again to the fb origin */
+	dev->loop_fb_copy.left -= dev->compose_out.left - dev->overlay_out_left;
+	dev->loop_fb_copy.top -= dev->compose_out.top - dev->overlay_out_top;
+
+	dev->loop_vid_overlay_cap = dev->loop_vid_overlay;
+	v4l2_rect_scale(&dev->loop_vid_overlay_cap, &dev->crop_cap, &dev->compose_cap);
+
+	dprintk(dev, 1,
+		"loop_fb_copy: %dx%d@%dx%d loop_vid_overlay: %dx%d@%dx%d loop_vid_overlay_cap: %dx%d@%dx%d\n",
+		dev->loop_fb_copy.width, dev->loop_fb_copy.height,
+		dev->loop_fb_copy.left, dev->loop_fb_copy.top,
+		dev->loop_vid_overlay.width, dev->loop_vid_overlay.height,
+		dev->loop_vid_overlay.left, dev->loop_vid_overlay.top,
+		dev->loop_vid_overlay_cap.width, dev->loop_vid_overlay_cap.height,
+		dev->loop_vid_overlay_cap.left, dev->loop_vid_overlay_cap.top);
+}
+
+static void *plane_vaddr(struct tpg_data *tpg, struct vivid_buffer *buf,
+			 unsigned p, unsigned bpl[TPG_MAX_PLANES], unsigned h)
+{
+	unsigned i;
+	void *vbuf;
+
+	if (p == 0 || tpg_g_buffers(tpg) > 1)
+		return vb2_plane_vaddr(&buf->vb.vb2_buf, p);
+	vbuf = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
+	for (i = 0; i < p; i++)
+		vbuf += bpl[i] * h / tpg->vdownsampling[i];
+	return vbuf;
+}
+
+static noinline_for_stack int vivid_copy_buffer(struct vivid_dev *dev, unsigned p,
+		u8 *vcapbuf, struct vivid_buffer *vid_cap_buf)
+{
+	bool blank = dev->must_blank[vid_cap_buf->vb.vb2_buf.index];
+	struct tpg_data *tpg = &dev->tpg;
+	struct vivid_buffer *vid_out_buf = NULL;
+	unsigned vdiv = dev->fmt_out->vdownsampling[p];
+	unsigned twopixsize = tpg_g_twopixelsize(tpg, p);
+	unsigned img_width = tpg_hdiv(tpg, p, dev->compose_cap.width);
+	unsigned img_height = dev->compose_cap.height;
+	unsigned stride_cap = tpg->bytesperline[p];
+	unsigned stride_out = dev->bytesperline_out[p];
+	unsigned stride_osd = dev->display_byte_stride;
+	unsigned hmax = (img_height * tpg->perc_fill) / 100;
+	u8 *voutbuf;
+	u8 *vosdbuf = NULL;
+	unsigned y;
+	bool blend = dev->bitmap_out || dev->clipcount_out || dev->fbuf_out_flags;
+	/* Coarse scaling with Bresenham */
+	unsigned vid_out_int_part;
+	unsigned vid_out_fract_part;
+	unsigned vid_out_y = 0;
+	unsigned vid_out_error = 0;
+	unsigned vid_overlay_int_part = 0;
+	unsigned vid_overlay_fract_part = 0;
+	unsigned vid_overlay_y = 0;
+	unsigned vid_overlay_error = 0;
+	unsigned vid_cap_left = tpg_hdiv(tpg, p, dev->loop_vid_cap.left);
+	unsigned vid_cap_right;
+	bool quick;
+
+	vid_out_int_part = dev->loop_vid_out.height / dev->loop_vid_cap.height;
+	vid_out_fract_part = dev->loop_vid_out.height % dev->loop_vid_cap.height;
+
+	if (!list_empty(&dev->vid_out_active))
+		vid_out_buf = list_entry(dev->vid_out_active.next,
+					 struct vivid_buffer, list);
+	if (vid_out_buf == NULL)
+		return -ENODATA;
+
+	vid_cap_buf->vb.field = vid_out_buf->vb.field;
+
+	voutbuf = plane_vaddr(tpg, vid_out_buf, p,
+			      dev->bytesperline_out, dev->fmt_out_rect.height);
+	if (p < dev->fmt_out->buffers)
+		voutbuf += vid_out_buf->vb.vb2_buf.planes[p].data_offset;
+	voutbuf += tpg_hdiv(tpg, p, dev->loop_vid_out.left) +
+		(dev->loop_vid_out.top / vdiv) * stride_out;
+	vcapbuf += tpg_hdiv(tpg, p, dev->compose_cap.left) +
+		(dev->compose_cap.top / vdiv) * stride_cap;
+
+	if (dev->loop_vid_copy.width == 0 || dev->loop_vid_copy.height == 0) {
+		/*
+		 * If there is nothing to copy, then just fill the capture window
+		 * with black.
+		 */
+		for (y = 0; y < hmax / vdiv; y++, vcapbuf += stride_cap)
+			memcpy(vcapbuf, tpg->black_line[p], img_width);
+		return 0;
+	}
+
+	if (dev->overlay_out_enabled &&
+	    dev->loop_vid_overlay.width && dev->loop_vid_overlay.height) {
+		vosdbuf = dev->video_vbase;
+		vosdbuf += (dev->loop_fb_copy.left * twopixsize) / 2 +
+			   dev->loop_fb_copy.top * stride_osd;
+		vid_overlay_int_part = dev->loop_vid_overlay.height /
+				       dev->loop_vid_overlay_cap.height;
+		vid_overlay_fract_part = dev->loop_vid_overlay.height %
+					 dev->loop_vid_overlay_cap.height;
+	}
+
+	vid_cap_right = tpg_hdiv(tpg, p, dev->loop_vid_cap.left + dev->loop_vid_cap.width);
+	/* quick is true if no video scaling is needed */
+	quick = dev->loop_vid_out.width == dev->loop_vid_cap.width;
+
+	dev->cur_scaled_line = dev->loop_vid_out.height;
+	for (y = 0; y < hmax; y += vdiv, vcapbuf += stride_cap) {
+		/* osdline is true if this line requires overlay blending */
+		bool osdline = vosdbuf && y >= dev->loop_vid_overlay_cap.top &&
+			  y < dev->loop_vid_overlay_cap.top + dev->loop_vid_overlay_cap.height;
+
+		/*
+		 * If this line of the capture buffer doesn't get any video, then
+		 * just fill with black.
+		 */
+		if (y < dev->loop_vid_cap.top ||
+		    y >= dev->loop_vid_cap.top + dev->loop_vid_cap.height) {
+			memcpy(vcapbuf, tpg->black_line[p], img_width);
+			continue;
+		}
+
+		/* fill the left border with black */
+		if (dev->loop_vid_cap.left)
+			memcpy(vcapbuf, tpg->black_line[p], vid_cap_left);
+
+		/* fill the right border with black */
+		if (vid_cap_right < img_width)
+			memcpy(vcapbuf + vid_cap_right, tpg->black_line[p],
+				img_width - vid_cap_right);
+
+		if (quick && !osdline) {
+			memcpy(vcapbuf + vid_cap_left,
+			       voutbuf + vid_out_y * stride_out,
+			       tpg_hdiv(tpg, p, dev->loop_vid_cap.width));
+			goto update_vid_out_y;
+		}
+		if (dev->cur_scaled_line == vid_out_y) {
+			memcpy(vcapbuf + vid_cap_left, dev->scaled_line,
+			       tpg_hdiv(tpg, p, dev->loop_vid_cap.width));
+			goto update_vid_out_y;
+		}
+		if (!osdline) {
+			scale_line(voutbuf + vid_out_y * stride_out, dev->scaled_line,
+				tpg_hdiv(tpg, p, dev->loop_vid_out.width),
+				tpg_hdiv(tpg, p, dev->loop_vid_cap.width),
+				tpg_g_twopixelsize(tpg, p));
+		} else {
+			/*
+			 * Offset in bytes within loop_vid_copy to the start of the
+			 * loop_vid_overlay rectangle.
+			 */
+			unsigned offset =
+				((dev->loop_vid_overlay.left - dev->loop_vid_copy.left) *
+				 twopixsize) / 2;
+			u8 *osd = vosdbuf + vid_overlay_y * stride_osd;
+
+			scale_line(voutbuf + vid_out_y * stride_out, dev->blended_line,
+				dev->loop_vid_out.width, dev->loop_vid_copy.width,
+				tpg_g_twopixelsize(tpg, p));
+			if (blend)
+				blend_line(dev, vid_overlay_y + dev->loop_vid_overlay.top,
+					   dev->loop_vid_overlay.left,
+					   dev->blended_line + offset, osd,
+					   dev->loop_vid_overlay.width, twopixsize / 2);
+			else
+				memcpy(dev->blended_line + offset,
+				       osd, (dev->loop_vid_overlay.width * twopixsize) / 2);
+			scale_line(dev->blended_line, dev->scaled_line,
+					dev->loop_vid_copy.width, dev->loop_vid_cap.width,
+					tpg_g_twopixelsize(tpg, p));
+		}
+		dev->cur_scaled_line = vid_out_y;
+		memcpy(vcapbuf + vid_cap_left, dev->scaled_line,
+		       tpg_hdiv(tpg, p, dev->loop_vid_cap.width));
+
+update_vid_out_y:
+		if (osdline) {
+			vid_overlay_y += vid_overlay_int_part;
+			vid_overlay_error += vid_overlay_fract_part;
+			if (vid_overlay_error >= dev->loop_vid_overlay_cap.height) {
+				vid_overlay_error -= dev->loop_vid_overlay_cap.height;
+				vid_overlay_y++;
+			}
+		}
+		vid_out_y += vid_out_int_part;
+		vid_out_error += vid_out_fract_part;
+		if (vid_out_error >= dev->loop_vid_cap.height / vdiv) {
+			vid_out_error -= dev->loop_vid_cap.height / vdiv;
+			vid_out_y++;
+		}
+	}
+
+	if (!blank)
+		return 0;
+	for (; y < img_height; y += vdiv, vcapbuf += stride_cap)
+		memcpy(vcapbuf, tpg->contrast_line[p], img_width);
+	return 0;
+}
+
+static void vivid_fillbuff(struct vivid_dev *dev, struct vivid_buffer *buf)
+{
+	struct tpg_data *tpg = &dev->tpg;
+	unsigned factor = V4L2_FIELD_HAS_T_OR_B(dev->field_cap) ? 2 : 1;
+	unsigned line_height = 16 / factor;
+	bool is_tv = vivid_is_sdtv_cap(dev);
+	bool is_60hz = is_tv && (dev->std_cap[dev->input] & V4L2_STD_525_60);
+	unsigned p;
+	int line = 1;
+	u8 *basep[TPG_MAX_PLANES][2];
+	unsigned ms;
+	char str[100];
+	s32 gain;
+	bool is_loop = false;
+
+	if (dev->loop_video && dev->can_loop_video &&
+		((vivid_is_svid_cap(dev) &&
+		!VIVID_INVALID_SIGNAL(dev->std_signal_mode[dev->input])) ||
+		(vivid_is_hdmi_cap(dev) &&
+		!VIVID_INVALID_SIGNAL(dev->dv_timings_signal_mode[dev->input]))))
+		is_loop = true;
+
+	buf->vb.sequence = dev->vid_cap_seq_count;
+	if (dev->field_cap == V4L2_FIELD_ALTERNATE) {
+		/*
+		 * 60 Hz standards start with the bottom field, 50 Hz standards
+		 * with the top field. So if the 0-based seq_count is even,
+		 * then the field is TOP for 50 Hz and BOTTOM for 60 Hz
+		 * standards.
+		 */
+		buf->vb.field = ((dev->vid_cap_seq_count & 1) ^ is_60hz) ?
+			V4L2_FIELD_BOTTOM : V4L2_FIELD_TOP;
+		/*
+		 * The sequence counter counts frames, not fields. So divide
+		 * by two.
+		 */
+		buf->vb.sequence /= 2;
+	} else {
+		buf->vb.field = dev->field_cap;
+	}
+	tpg_s_field(tpg, buf->vb.field,
+		    dev->field_cap == V4L2_FIELD_ALTERNATE);
+	tpg_s_perc_fill_blank(tpg, dev->must_blank[buf->vb.vb2_buf.index]);
+
+	vivid_precalc_copy_rects(dev);
+
+	for (p = 0; p < tpg_g_planes(tpg); p++) {
+		void *vbuf = plane_vaddr(tpg, buf, p,
+					 tpg->bytesperline, tpg->buf_height);
+
+		/*
+		 * The first plane of a multiplanar format has a non-zero
+		 * data_offset. This helps testing whether the application
+		 * correctly supports non-zero data offsets.
+		 */
+		if (p < tpg_g_buffers(tpg) && dev->fmt_cap->data_offset[p]) {
+			memset(vbuf, dev->fmt_cap->data_offset[p] & 0xff,
+			       dev->fmt_cap->data_offset[p]);
+			vbuf += dev->fmt_cap->data_offset[p];
+		}
+		tpg_calc_text_basep(tpg, basep, p, vbuf);
+		if (!is_loop || vivid_copy_buffer(dev, p, vbuf, buf))
+			tpg_fill_plane_buffer(tpg, vivid_get_std_cap(dev),
+					p, vbuf);
+	}
+	dev->must_blank[buf->vb.vb2_buf.index] = false;
+
+	/* Updates stream time, only update at the start of a new frame. */
+	if (dev->field_cap != V4L2_FIELD_ALTERNATE ||
+			(dev->vid_cap_seq_count & 1) == 0)
+		dev->ms_vid_cap =
+			jiffies_to_msecs(jiffies - dev->jiffies_vid_cap);
+
+	ms = dev->ms_vid_cap;
+	if (dev->osd_mode <= 1) {
+		snprintf(str, sizeof(str), " %02d:%02d:%02d:%03d %u%s",
+				(ms / (60 * 60 * 1000)) % 24,
+				(ms / (60 * 1000)) % 60,
+				(ms / 1000) % 60,
+				ms % 1000,
+				buf->vb.sequence,
+				(dev->field_cap == V4L2_FIELD_ALTERNATE) ?
+					(buf->vb.field == V4L2_FIELD_TOP ?
+					 " top" : " bottom") : "");
+		tpg_gen_text(tpg, basep, line++ * line_height, 16, str);
+	}
+	if (dev->osd_mode == 0) {
+		snprintf(str, sizeof(str), " %dx%d, input %d ",
+				dev->src_rect.width, dev->src_rect.height, dev->input);
+		tpg_gen_text(tpg, basep, line++ * line_height, 16, str);
+
+		gain = v4l2_ctrl_g_ctrl(dev->gain);
+		mutex_lock(dev->ctrl_hdl_user_vid.lock);
+		snprintf(str, sizeof(str),
+			" brightness %3d, contrast %3d, saturation %3d, hue %d ",
+			dev->brightness->cur.val,
+			dev->contrast->cur.val,
+			dev->saturation->cur.val,
+			dev->hue->cur.val);
+		tpg_gen_text(tpg, basep, line++ * line_height, 16, str);
+		snprintf(str, sizeof(str),
+			" autogain %d, gain %3d, alpha 0x%02x ",
+			dev->autogain->cur.val, gain, dev->alpha->cur.val);
+		mutex_unlock(dev->ctrl_hdl_user_vid.lock);
+		tpg_gen_text(tpg, basep, line++ * line_height, 16, str);
+		mutex_lock(dev->ctrl_hdl_user_aud.lock);
+		snprintf(str, sizeof(str),
+			" volume %3d, mute %d ",
+			dev->volume->cur.val, dev->mute->cur.val);
+		mutex_unlock(dev->ctrl_hdl_user_aud.lock);
+		tpg_gen_text(tpg, basep, line++ * line_height, 16, str);
+		mutex_lock(dev->ctrl_hdl_user_gen.lock);
+		snprintf(str, sizeof(str), " int32 %d, int64 %lld, bitmask %08x ",
+			dev->int32->cur.val,
+			*dev->int64->p_cur.p_s64,
+			dev->bitmask->cur.val);
+		tpg_gen_text(tpg, basep, line++ * line_height, 16, str);
+		snprintf(str, sizeof(str), " boolean %d, menu %s, string \"%s\" ",
+			dev->boolean->cur.val,
+			dev->menu->qmenu[dev->menu->cur.val],
+			dev->string->p_cur.p_char);
+		tpg_gen_text(tpg, basep, line++ * line_height, 16, str);
+		snprintf(str, sizeof(str), " integer_menu %lld, value %d ",
+			dev->int_menu->qmenu_int[dev->int_menu->cur.val],
+			dev->int_menu->cur.val);
+		mutex_unlock(dev->ctrl_hdl_user_gen.lock);
+		tpg_gen_text(tpg, basep, line++ * line_height, 16, str);
+		if (dev->button_pressed) {
+			dev->button_pressed--;
+			snprintf(str, sizeof(str), " button pressed!");
+			tpg_gen_text(tpg, basep, line++ * line_height, 16, str);
+		}
+		if (dev->osd[0]) {
+			if (vivid_is_hdmi_cap(dev)) {
+				snprintf(str, sizeof(str),
+					 " OSD \"%s\"", dev->osd);
+				tpg_gen_text(tpg, basep, line++ * line_height,
+					     16, str);
+			}
+			if (dev->osd_jiffies &&
+			    time_is_before_jiffies(dev->osd_jiffies + 5 * HZ)) {
+				dev->osd[0] = 0;
+				dev->osd_jiffies = 0;
+			}
+		}
+	}
+}
+
+/*
+ * Return true if this pixel coordinate is a valid video pixel.
+ */
+static bool valid_pix(struct vivid_dev *dev, int win_y, int win_x, int fb_y, int fb_x)
+{
+	int i;
+
+	if (dev->bitmap_cap) {
+		/*
+		 * Only if the corresponding bit in the bitmap is set can
+		 * the video pixel be shown. Coordinates are relative to
+		 * the overlay window set by VIDIOC_S_FMT.
+		 */
+		const u8 *p = dev->bitmap_cap;
+		unsigned stride = (dev->compose_cap.width + 7) / 8;
+
+		if (!(p[stride * win_y + win_x / 8] & (1 << (win_x & 7))))
+			return false;
+	}
+
+	for (i = 0; i < dev->clipcount_cap; i++) {
+		/*
+		 * Only if the framebuffer coordinate is not in any of the
+		 * clip rectangles will be video pixel be shown.
+		 */
+		struct v4l2_rect *r = &dev->clips_cap[i].c;
+
+		if (fb_y >= r->top && fb_y < r->top + r->height &&
+		    fb_x >= r->left && fb_x < r->left + r->width)
+			return false;
+	}
+	return true;
+}
+
+/*
+ * Draw the image into the overlay buffer.
+ * Note that the combination of overlay and multiplanar is not supported.
+ */
+static void vivid_overlay(struct vivid_dev *dev, struct vivid_buffer *buf)
+{
+	struct tpg_data *tpg = &dev->tpg;
+	unsigned pixsize = tpg_g_twopixelsize(tpg, 0) / 2;
+	void *vbase = dev->fb_vbase_cap;
+	void *vbuf = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
+	unsigned img_width = dev->compose_cap.width;
+	unsigned img_height = dev->compose_cap.height;
+	unsigned stride = tpg->bytesperline[0];
+	/* if quick is true, then valid_pix() doesn't have to be called */
+	bool quick = dev->bitmap_cap == NULL && dev->clipcount_cap == 0;
+	int x, y, w, out_x = 0;
+
+	/*
+	 * Overlay support is only supported for formats that have a twopixelsize
+	 * that's >= 2. Warn and bail out if that's not the case.
+	 */
+	if (WARN_ON(pixsize == 0))
+		return;
+	if ((dev->overlay_cap_field == V4L2_FIELD_TOP ||
+	     dev->overlay_cap_field == V4L2_FIELD_BOTTOM) &&
+	    dev->overlay_cap_field != buf->vb.field)
+		return;
+
+	vbuf += dev->compose_cap.left * pixsize + dev->compose_cap.top * stride;
+	x = dev->overlay_cap_left;
+	w = img_width;
+	if (x < 0) {
+		out_x = -x;
+		w = w - out_x;
+		x = 0;
+	} else {
+		w = dev->fb_cap.fmt.width - x;
+		if (w > img_width)
+			w = img_width;
+	}
+	if (w <= 0)
+		return;
+	if (dev->overlay_cap_top >= 0)
+		vbase += dev->overlay_cap_top * dev->fb_cap.fmt.bytesperline;
+	for (y = dev->overlay_cap_top;
+	     y < dev->overlay_cap_top + (int)img_height;
+	     y++, vbuf += stride) {
+		int px;
+
+		if (y < 0 || y > dev->fb_cap.fmt.height)
+			continue;
+		if (quick) {
+			memcpy(vbase + x * pixsize,
+			       vbuf + out_x * pixsize, w * pixsize);
+			vbase += dev->fb_cap.fmt.bytesperline;
+			continue;
+		}
+		for (px = 0; px < w; px++) {
+			if (!valid_pix(dev, y - dev->overlay_cap_top,
+				       px + out_x, y, px + x))
+				continue;
+			memcpy(vbase + (px + x) * pixsize,
+			       vbuf + (px + out_x) * pixsize,
+			       pixsize);
+		}
+		vbase += dev->fb_cap.fmt.bytesperline;
+	}
+}
+
+static void vivid_cap_update_frame_period(struct vivid_dev *dev)
+{
+	u64 f_period;
+
+	f_period = (u64)dev->timeperframe_vid_cap.numerator * 1000000000;
+	if (WARN_ON(dev->timeperframe_vid_cap.denominator == 0))
+		dev->timeperframe_vid_cap.denominator = 1;
+	do_div(f_period, dev->timeperframe_vid_cap.denominator);
+	if (dev->field_cap == V4L2_FIELD_ALTERNATE)
+		f_period >>= 1;
+	/*
+	 * If "End of Frame", then offset the exposure time by 0.9
+	 * of the frame period.
+	 */
+	dev->cap_frame_eof_offset = f_period * 9;
+	do_div(dev->cap_frame_eof_offset, 10);
+	dev->cap_frame_period = f_period;
+}
+
+static noinline_for_stack void vivid_thread_vid_cap_tick(struct vivid_dev *dev,
+							 int dropped_bufs)
+{
+	struct vivid_buffer *vid_cap_buf = NULL;
+	struct vivid_buffer *vbi_cap_buf = NULL;
+	struct vivid_buffer *meta_cap_buf = NULL;
+	u64 f_time = 0;
+
+	dprintk(dev, 1, "Video Capture Thread Tick\n");
+
+	while (dropped_bufs-- > 1)
+		tpg_update_mv_count(&dev->tpg,
+				dev->field_cap == V4L2_FIELD_NONE ||
+				dev->field_cap == V4L2_FIELD_ALTERNATE);
+
+	/* Drop a certain percentage of buffers. */
+	if (dev->perc_dropped_buffers &&
+	    prandom_u32_max(100) < dev->perc_dropped_buffers)
+		goto update_mv;
+
+	spin_lock(&dev->slock);
+	if (!list_empty(&dev->vid_cap_active)) {
+		vid_cap_buf = list_entry(dev->vid_cap_active.next, struct vivid_buffer, list);
+		list_del(&vid_cap_buf->list);
+	}
+	if (!list_empty(&dev->vbi_cap_active)) {
+		if (dev->field_cap != V4L2_FIELD_ALTERNATE ||
+		    (dev->vbi_cap_seq_count & 1)) {
+			vbi_cap_buf = list_entry(dev->vbi_cap_active.next,
+						 struct vivid_buffer, list);
+			list_del(&vbi_cap_buf->list);
+		}
+	}
+	if (!list_empty(&dev->meta_cap_active)) {
+		meta_cap_buf = list_entry(dev->meta_cap_active.next,
+					  struct vivid_buffer, list);
+		list_del(&meta_cap_buf->list);
+	}
+
+	spin_unlock(&dev->slock);
+
+	if (!vid_cap_buf && !vbi_cap_buf && !meta_cap_buf)
+		goto update_mv;
+
+	f_time = dev->cap_frame_period * dev->vid_cap_seq_count +
+		 dev->cap_stream_start + dev->time_wrap_offset;
+
+	if (vid_cap_buf) {
+		v4l2_ctrl_request_setup(vid_cap_buf->vb.vb2_buf.req_obj.req,
+					&dev->ctrl_hdl_vid_cap);
+		/* Fill buffer */
+		vivid_fillbuff(dev, vid_cap_buf);
+		dprintk(dev, 1, "filled buffer %d\n",
+			vid_cap_buf->vb.vb2_buf.index);
+
+		/* Handle overlay */
+		if (dev->overlay_cap_owner && dev->fb_cap.base &&
+			dev->fb_cap.fmt.pixelformat == dev->fmt_cap->fourcc)
+			vivid_overlay(dev, vid_cap_buf);
+
+		v4l2_ctrl_request_complete(vid_cap_buf->vb.vb2_buf.req_obj.req,
+					   &dev->ctrl_hdl_vid_cap);
+		vb2_buffer_done(&vid_cap_buf->vb.vb2_buf, dev->dqbuf_error ?
+				VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
+		dprintk(dev, 2, "vid_cap buffer %d done\n",
+				vid_cap_buf->vb.vb2_buf.index);
+
+		vid_cap_buf->vb.vb2_buf.timestamp = f_time;
+		if (!dev->tstamp_src_is_soe)
+			vid_cap_buf->vb.vb2_buf.timestamp += dev->cap_frame_eof_offset;
+	}
+
+	if (vbi_cap_buf) {
+		u64 vbi_period;
+
+		v4l2_ctrl_request_setup(vbi_cap_buf->vb.vb2_buf.req_obj.req,
+					&dev->ctrl_hdl_vbi_cap);
+		if (dev->stream_sliced_vbi_cap)
+			vivid_sliced_vbi_cap_process(dev, vbi_cap_buf);
+		else
+			vivid_raw_vbi_cap_process(dev, vbi_cap_buf);
+		v4l2_ctrl_request_complete(vbi_cap_buf->vb.vb2_buf.req_obj.req,
+					   &dev->ctrl_hdl_vbi_cap);
+		vb2_buffer_done(&vbi_cap_buf->vb.vb2_buf, dev->dqbuf_error ?
+				VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
+		dprintk(dev, 2, "vbi_cap %d done\n",
+				vbi_cap_buf->vb.vb2_buf.index);
+
+		/* If capturing a VBI, offset by 0.05 */
+		vbi_period = dev->cap_frame_period * 5;
+		do_div(vbi_period, 100);
+		vbi_cap_buf->vb.vb2_buf.timestamp = f_time + dev->cap_frame_eof_offset + vbi_period;
+	}
+
+	if (meta_cap_buf) {
+		v4l2_ctrl_request_setup(meta_cap_buf->vb.vb2_buf.req_obj.req,
+					&dev->ctrl_hdl_meta_cap);
+		vivid_meta_cap_fillbuff(dev, meta_cap_buf, f_time);
+		v4l2_ctrl_request_complete(meta_cap_buf->vb.vb2_buf.req_obj.req,
+					   &dev->ctrl_hdl_meta_cap);
+		vb2_buffer_done(&meta_cap_buf->vb.vb2_buf, dev->dqbuf_error ?
+				VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
+		dprintk(dev, 2, "meta_cap %d done\n",
+			meta_cap_buf->vb.vb2_buf.index);
+		meta_cap_buf->vb.vb2_buf.timestamp = f_time + dev->cap_frame_eof_offset;
+	}
+
+	dev->dqbuf_error = false;
+
+update_mv:
+	/* Update the test pattern movement counters */
+	tpg_update_mv_count(&dev->tpg, dev->field_cap == V4L2_FIELD_NONE ||
+				       dev->field_cap == V4L2_FIELD_ALTERNATE);
+}
+
+static int vivid_thread_vid_cap(void *data)
+{
+	struct vivid_dev *dev = data;
+	u64 numerators_since_start;
+	u64 buffers_since_start;
+	u64 next_jiffies_since_start;
+	unsigned long jiffies_since_start;
+	unsigned long cur_jiffies;
+	unsigned wait_jiffies;
+	unsigned numerator;
+	unsigned denominator;
+	int dropped_bufs;
+
+	dprintk(dev, 1, "Video Capture Thread Start\n");
+
+	set_freezable();
+
+	/* Resets frame counters */
+	dev->cap_seq_offset = 0;
+	dev->cap_seq_count = 0;
+	dev->cap_seq_resync = false;
+	dev->jiffies_vid_cap = jiffies;
+	dev->cap_stream_start = ktime_get_ns();
+	vivid_cap_update_frame_period(dev);
+
+	for (;;) {
+		try_to_freeze();
+		if (kthread_should_stop())
+			break;
+
+		if (!mutex_trylock(&dev->mutex)) {
+			schedule_timeout_uninterruptible(1);
+			continue;
+		}
+
+		cur_jiffies = jiffies;
+		if (dev->cap_seq_resync) {
+			dev->jiffies_vid_cap = cur_jiffies;
+			dev->cap_seq_offset = dev->cap_seq_count + 1;
+			dev->cap_seq_count = 0;
+			dev->cap_stream_start += dev->cap_frame_period *
+						 dev->cap_seq_offset;
+			vivid_cap_update_frame_period(dev);
+			dev->cap_seq_resync = false;
+		}
+		numerator = dev->timeperframe_vid_cap.numerator;
+		denominator = dev->timeperframe_vid_cap.denominator;
+
+		if (dev->field_cap == V4L2_FIELD_ALTERNATE)
+			denominator *= 2;
+
+		/* Calculate the number of jiffies since we started streaming */
+		jiffies_since_start = cur_jiffies - dev->jiffies_vid_cap;
+		/* Get the number of buffers streamed since the start */
+		buffers_since_start = (u64)jiffies_since_start * denominator +
+				      (HZ * numerator) / 2;
+		do_div(buffers_since_start, HZ * numerator);
+
+		/*
+		 * After more than 0xf0000000 (rounded down to a multiple of
+		 * 'jiffies-per-day' to ease jiffies_to_msecs calculation)
+		 * jiffies have passed since we started streaming reset the
+		 * counters and keep track of the sequence offset.
+		 */
+		if (jiffies_since_start > JIFFIES_RESYNC) {
+			dev->jiffies_vid_cap = cur_jiffies;
+			dev->cap_seq_offset = buffers_since_start;
+			buffers_since_start = 0;
+		}
+		dropped_bufs = buffers_since_start + dev->cap_seq_offset - dev->cap_seq_count;
+		dev->cap_seq_count = buffers_since_start + dev->cap_seq_offset;
+		dev->vid_cap_seq_count = dev->cap_seq_count - dev->vid_cap_seq_start;
+		dev->vbi_cap_seq_count = dev->cap_seq_count - dev->vbi_cap_seq_start;
+		dev->meta_cap_seq_count = dev->cap_seq_count - dev->meta_cap_seq_start;
+
+		vivid_thread_vid_cap_tick(dev, dropped_bufs);
+
+		/*
+		 * Calculate the number of 'numerators' streamed since we started,
+		 * including the current buffer.
+		 */
+		numerators_since_start = ++buffers_since_start * numerator;
+
+		/* And the number of jiffies since we started */
+		jiffies_since_start = jiffies - dev->jiffies_vid_cap;
+
+		mutex_unlock(&dev->mutex);
+
+		/*
+		 * Calculate when that next buffer is supposed to start
+		 * in jiffies since we started streaming.
+		 */
+		next_jiffies_since_start = numerators_since_start * HZ +
+					   denominator / 2;
+		do_div(next_jiffies_since_start, denominator);
+		/* If it is in the past, then just schedule asap */
+		if (next_jiffies_since_start < jiffies_since_start)
+			next_jiffies_since_start = jiffies_since_start;
+
+		wait_jiffies = next_jiffies_since_start - jiffies_since_start;
+		schedule_timeout_interruptible(wait_jiffies ? wait_jiffies : 1);
+	}
+	dprintk(dev, 1, "Video Capture Thread End\n");
+	return 0;
+}
+
+static void vivid_grab_controls(struct vivid_dev *dev, bool grab)
+{
+	v4l2_ctrl_grab(dev->ctrl_has_crop_cap, grab);
+	v4l2_ctrl_grab(dev->ctrl_has_compose_cap, grab);
+	v4l2_ctrl_grab(dev->ctrl_has_scaler_cap, grab);
+}
+
+int vivid_start_generating_vid_cap(struct vivid_dev *dev, bool *pstreaming)
+{
+	dprintk(dev, 1, "%s\n", __func__);
+
+	if (dev->kthread_vid_cap) {
+		u32 seq_count = dev->cap_seq_count + dev->seq_wrap * 128;
+
+		if (pstreaming == &dev->vid_cap_streaming)
+			dev->vid_cap_seq_start = seq_count;
+		else if (pstreaming == &dev->vbi_cap_streaming)
+			dev->vbi_cap_seq_start = seq_count;
+		else
+			dev->meta_cap_seq_start = seq_count;
+		*pstreaming = true;
+		return 0;
+	}
+
+	/* Resets frame counters */
+	tpg_init_mv_count(&dev->tpg);
+
+	dev->vid_cap_seq_start = dev->seq_wrap * 128;
+	dev->vbi_cap_seq_start = dev->seq_wrap * 128;
+	dev->meta_cap_seq_start = dev->seq_wrap * 128;
+
+	dev->kthread_vid_cap = kthread_run(vivid_thread_vid_cap, dev,
+			"%s-vid-cap", dev->v4l2_dev.name);
+
+	if (IS_ERR(dev->kthread_vid_cap)) {
+		int err = PTR_ERR(dev->kthread_vid_cap);
+
+		dev->kthread_vid_cap = NULL;
+		v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n");
+		return err;
+	}
+	*pstreaming = true;
+	vivid_grab_controls(dev, true);
+
+	dprintk(dev, 1, "returning from %s\n", __func__);
+	return 0;
+}
+
+void vivid_stop_generating_vid_cap(struct vivid_dev *dev, bool *pstreaming)
+{
+	dprintk(dev, 1, "%s\n", __func__);
+
+	if (dev->kthread_vid_cap == NULL)
+		return;
+
+	*pstreaming = false;
+	if (pstreaming == &dev->vid_cap_streaming) {
+		/* Release all active buffers */
+		while (!list_empty(&dev->vid_cap_active)) {
+			struct vivid_buffer *buf;
+
+			buf = list_entry(dev->vid_cap_active.next,
+					 struct vivid_buffer, list);
+			list_del(&buf->list);
+			v4l2_ctrl_request_complete(buf->vb.vb2_buf.req_obj.req,
+						   &dev->ctrl_hdl_vid_cap);
+			vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+			dprintk(dev, 2, "vid_cap buffer %d done\n",
+				buf->vb.vb2_buf.index);
+		}
+	}
+
+	if (pstreaming == &dev->vbi_cap_streaming) {
+		while (!list_empty(&dev->vbi_cap_active)) {
+			struct vivid_buffer *buf;
+
+			buf = list_entry(dev->vbi_cap_active.next,
+					 struct vivid_buffer, list);
+			list_del(&buf->list);
+			v4l2_ctrl_request_complete(buf->vb.vb2_buf.req_obj.req,
+						   &dev->ctrl_hdl_vbi_cap);
+			vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+			dprintk(dev, 2, "vbi_cap buffer %d done\n",
+				buf->vb.vb2_buf.index);
+		}
+	}
+
+	if (pstreaming == &dev->meta_cap_streaming) {
+		while (!list_empty(&dev->meta_cap_active)) {
+			struct vivid_buffer *buf;
+
+			buf = list_entry(dev->meta_cap_active.next,
+					 struct vivid_buffer, list);
+			list_del(&buf->list);
+			v4l2_ctrl_request_complete(buf->vb.vb2_buf.req_obj.req,
+						   &dev->ctrl_hdl_meta_cap);
+			vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+			dprintk(dev, 2, "meta_cap buffer %d done\n",
+				buf->vb.vb2_buf.index);
+		}
+	}
+
+	if (dev->vid_cap_streaming || dev->vbi_cap_streaming ||
+	    dev->meta_cap_streaming)
+		return;
+
+	/* shutdown control thread */
+	vivid_grab_controls(dev, false);
+	kthread_stop(dev->kthread_vid_cap);
+	dev->kthread_vid_cap = NULL;
+}
diff --git a/drivers/media/test-drivers/vivid/vivid-kthread-cap.h b/drivers/media/test-drivers/vivid/vivid-kthread-cap.h
new file mode 100644
index 000000000000..0f43015306d6
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-kthread-cap.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * vivid-kthread-cap.h - video/vbi capture thread support functions.
+ *
+ * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _VIVID_KTHREAD_CAP_H_
+#define _VIVID_KTHREAD_CAP_H_
+
+int vivid_start_generating_vid_cap(struct vivid_dev *dev, bool *pstreaming);
+void vivid_stop_generating_vid_cap(struct vivid_dev *dev, bool *pstreaming);
+
+#endif
diff --git a/drivers/media/test-drivers/vivid/vivid-kthread-out.c b/drivers/media/test-drivers/vivid/vivid-kthread-out.c
new file mode 100644
index 000000000000..6780687978f9
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-kthread-out.c
@@ -0,0 +1,353 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * vivid-kthread-out.h - video/vbi output thread support functions.
+ *
+ * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/font.h>
+#include <linux/mutex.h>
+#include <linux/videodev2.h>
+#include <linux/kthread.h>
+#include <linux/freezer.h>
+#include <linux/random.h>
+#include <linux/v4l2-dv-timings.h>
+#include <asm/div64.h>
+#include <media/videobuf2-vmalloc.h>
+#include <media/v4l2-dv-timings.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-fh.h>
+#include <media/v4l2-event.h>
+
+#include "vivid-core.h"
+#include "vivid-vid-common.h"
+#include "vivid-vid-cap.h"
+#include "vivid-vid-out.h"
+#include "vivid-radio-common.h"
+#include "vivid-radio-rx.h"
+#include "vivid-radio-tx.h"
+#include "vivid-sdr-cap.h"
+#include "vivid-vbi-cap.h"
+#include "vivid-vbi-out.h"
+#include "vivid-osd.h"
+#include "vivid-ctrls.h"
+#include "vivid-kthread-out.h"
+#include "vivid-meta-out.h"
+
+static void vivid_thread_vid_out_tick(struct vivid_dev *dev)
+{
+	struct vivid_buffer *vid_out_buf = NULL;
+	struct vivid_buffer *vbi_out_buf = NULL;
+	struct vivid_buffer *meta_out_buf = NULL;
+
+	dprintk(dev, 1, "Video Output Thread Tick\n");
+
+	/* Drop a certain percentage of buffers. */
+	if (dev->perc_dropped_buffers &&
+	    prandom_u32_max(100) < dev->perc_dropped_buffers)
+		return;
+
+	spin_lock(&dev->slock);
+	/*
+	 * Only dequeue buffer if there is at least one more pending.
+	 * This makes video loopback possible.
+	 */
+	if (!list_empty(&dev->vid_out_active) &&
+	    !list_is_singular(&dev->vid_out_active)) {
+		vid_out_buf = list_entry(dev->vid_out_active.next,
+					 struct vivid_buffer, list);
+		list_del(&vid_out_buf->list);
+	}
+	if (!list_empty(&dev->vbi_out_active) &&
+	    (dev->field_out != V4L2_FIELD_ALTERNATE ||
+	     (dev->vbi_out_seq_count & 1))) {
+		vbi_out_buf = list_entry(dev->vbi_out_active.next,
+					 struct vivid_buffer, list);
+		list_del(&vbi_out_buf->list);
+	}
+	if (!list_empty(&dev->meta_out_active)) {
+		meta_out_buf = list_entry(dev->meta_out_active.next,
+					  struct vivid_buffer, list);
+		list_del(&meta_out_buf->list);
+	}
+	spin_unlock(&dev->slock);
+
+	if (!vid_out_buf && !vbi_out_buf && !meta_out_buf)
+		return;
+
+	if (vid_out_buf) {
+		v4l2_ctrl_request_setup(vid_out_buf->vb.vb2_buf.req_obj.req,
+					&dev->ctrl_hdl_vid_out);
+		v4l2_ctrl_request_complete(vid_out_buf->vb.vb2_buf.req_obj.req,
+					   &dev->ctrl_hdl_vid_out);
+		vid_out_buf->vb.sequence = dev->vid_out_seq_count;
+		if (dev->field_out == V4L2_FIELD_ALTERNATE) {
+			/*
+			 * The sequence counter counts frames, not fields.
+			 * So divide by two.
+			 */
+			vid_out_buf->vb.sequence /= 2;
+		}
+		vid_out_buf->vb.vb2_buf.timestamp =
+			ktime_get_ns() + dev->time_wrap_offset;
+		vb2_buffer_done(&vid_out_buf->vb.vb2_buf, dev->dqbuf_error ?
+				VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
+		dprintk(dev, 2, "vid_out buffer %d done\n",
+			vid_out_buf->vb.vb2_buf.index);
+	}
+
+	if (vbi_out_buf) {
+		v4l2_ctrl_request_setup(vbi_out_buf->vb.vb2_buf.req_obj.req,
+					&dev->ctrl_hdl_vbi_out);
+		v4l2_ctrl_request_complete(vbi_out_buf->vb.vb2_buf.req_obj.req,
+					   &dev->ctrl_hdl_vbi_out);
+		if (dev->stream_sliced_vbi_out)
+			vivid_sliced_vbi_out_process(dev, vbi_out_buf);
+
+		vbi_out_buf->vb.sequence = dev->vbi_out_seq_count;
+		vbi_out_buf->vb.vb2_buf.timestamp =
+			ktime_get_ns() + dev->time_wrap_offset;
+		vb2_buffer_done(&vbi_out_buf->vb.vb2_buf, dev->dqbuf_error ?
+				VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
+		dprintk(dev, 2, "vbi_out buffer %d done\n",
+			vbi_out_buf->vb.vb2_buf.index);
+	}
+	if (meta_out_buf) {
+		v4l2_ctrl_request_setup(meta_out_buf->vb.vb2_buf.req_obj.req,
+					&dev->ctrl_hdl_meta_out);
+		v4l2_ctrl_request_complete(meta_out_buf->vb.vb2_buf.req_obj.req,
+					   &dev->ctrl_hdl_meta_out);
+		vivid_meta_out_process(dev, meta_out_buf);
+		meta_out_buf->vb.sequence = dev->meta_out_seq_count;
+		meta_out_buf->vb.vb2_buf.timestamp =
+			ktime_get_ns() + dev->time_wrap_offset;
+		vb2_buffer_done(&meta_out_buf->vb.vb2_buf, dev->dqbuf_error ?
+				VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
+		dprintk(dev, 2, "meta_out buffer %d done\n",
+			meta_out_buf->vb.vb2_buf.index);
+	}
+
+	dev->dqbuf_error = false;
+}
+
+static int vivid_thread_vid_out(void *data)
+{
+	struct vivid_dev *dev = data;
+	u64 numerators_since_start;
+	u64 buffers_since_start;
+	u64 next_jiffies_since_start;
+	unsigned long jiffies_since_start;
+	unsigned long cur_jiffies;
+	unsigned wait_jiffies;
+	unsigned numerator;
+	unsigned denominator;
+
+	dprintk(dev, 1, "Video Output Thread Start\n");
+
+	set_freezable();
+
+	/* Resets frame counters */
+	dev->out_seq_offset = 0;
+	if (dev->seq_wrap)
+		dev->out_seq_count = 0xffffff80U;
+	dev->jiffies_vid_out = jiffies;
+	dev->vid_out_seq_start = dev->vbi_out_seq_start = 0;
+	dev->meta_out_seq_start = 0;
+	dev->out_seq_resync = false;
+
+	for (;;) {
+		try_to_freeze();
+		if (kthread_should_stop())
+			break;
+
+		if (!mutex_trylock(&dev->mutex)) {
+			schedule_timeout_uninterruptible(1);
+			continue;
+		}
+
+		cur_jiffies = jiffies;
+		if (dev->out_seq_resync) {
+			dev->jiffies_vid_out = cur_jiffies;
+			dev->out_seq_offset = dev->out_seq_count + 1;
+			dev->out_seq_count = 0;
+			dev->out_seq_resync = false;
+		}
+		numerator = dev->timeperframe_vid_out.numerator;
+		denominator = dev->timeperframe_vid_out.denominator;
+
+		if (dev->field_out == V4L2_FIELD_ALTERNATE)
+			denominator *= 2;
+
+		/* Calculate the number of jiffies since we started streaming */
+		jiffies_since_start = cur_jiffies - dev->jiffies_vid_out;
+		/* Get the number of buffers streamed since the start */
+		buffers_since_start = (u64)jiffies_since_start * denominator +
+				      (HZ * numerator) / 2;
+		do_div(buffers_since_start, HZ * numerator);
+
+		/*
+		 * After more than 0xf0000000 (rounded down to a multiple of
+		 * 'jiffies-per-day' to ease jiffies_to_msecs calculation)
+		 * jiffies have passed since we started streaming reset the
+		 * counters and keep track of the sequence offset.
+		 */
+		if (jiffies_since_start > JIFFIES_RESYNC) {
+			dev->jiffies_vid_out = cur_jiffies;
+			dev->out_seq_offset = buffers_since_start;
+			buffers_since_start = 0;
+		}
+		dev->out_seq_count = buffers_since_start + dev->out_seq_offset;
+		dev->vid_out_seq_count = dev->out_seq_count - dev->vid_out_seq_start;
+		dev->vbi_out_seq_count = dev->out_seq_count - dev->vbi_out_seq_start;
+		dev->meta_out_seq_count = dev->out_seq_count - dev->meta_out_seq_start;
+
+		vivid_thread_vid_out_tick(dev);
+		mutex_unlock(&dev->mutex);
+
+		/*
+		 * Calculate the number of 'numerators' streamed since we started,
+		 * not including the current buffer.
+		 */
+		numerators_since_start = buffers_since_start * numerator;
+
+		/* And the number of jiffies since we started */
+		jiffies_since_start = jiffies - dev->jiffies_vid_out;
+
+		/* Increase by the 'numerator' of one buffer */
+		numerators_since_start += numerator;
+		/*
+		 * Calculate when that next buffer is supposed to start
+		 * in jiffies since we started streaming.
+		 */
+		next_jiffies_since_start = numerators_since_start * HZ +
+					   denominator / 2;
+		do_div(next_jiffies_since_start, denominator);
+		/* If it is in the past, then just schedule asap */
+		if (next_jiffies_since_start < jiffies_since_start)
+			next_jiffies_since_start = jiffies_since_start;
+
+		wait_jiffies = next_jiffies_since_start - jiffies_since_start;
+		schedule_timeout_interruptible(wait_jiffies ? wait_jiffies : 1);
+	}
+	dprintk(dev, 1, "Video Output Thread End\n");
+	return 0;
+}
+
+static void vivid_grab_controls(struct vivid_dev *dev, bool grab)
+{
+	v4l2_ctrl_grab(dev->ctrl_has_crop_out, grab);
+	v4l2_ctrl_grab(dev->ctrl_has_compose_out, grab);
+	v4l2_ctrl_grab(dev->ctrl_has_scaler_out, grab);
+	v4l2_ctrl_grab(dev->ctrl_tx_mode, grab);
+	v4l2_ctrl_grab(dev->ctrl_tx_rgb_range, grab);
+}
+
+int vivid_start_generating_vid_out(struct vivid_dev *dev, bool *pstreaming)
+{
+	dprintk(dev, 1, "%s\n", __func__);
+
+	if (dev->kthread_vid_out) {
+		u32 seq_count = dev->out_seq_count + dev->seq_wrap * 128;
+
+		if (pstreaming == &dev->vid_out_streaming)
+			dev->vid_out_seq_start = seq_count;
+		else if (pstreaming == &dev->vbi_out_streaming)
+			dev->vbi_out_seq_start = seq_count;
+		else
+			dev->meta_out_seq_start = seq_count;
+		*pstreaming = true;
+		return 0;
+	}
+
+	/* Resets frame counters */
+	dev->jiffies_vid_out = jiffies;
+	dev->vid_out_seq_start = dev->seq_wrap * 128;
+	dev->vbi_out_seq_start = dev->seq_wrap * 128;
+	dev->meta_out_seq_start = dev->seq_wrap * 128;
+
+	dev->kthread_vid_out = kthread_run(vivid_thread_vid_out, dev,
+			"%s-vid-out", dev->v4l2_dev.name);
+
+	if (IS_ERR(dev->kthread_vid_out)) {
+		int err = PTR_ERR(dev->kthread_vid_out);
+
+		dev->kthread_vid_out = NULL;
+		v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n");
+		return err;
+	}
+	*pstreaming = true;
+	vivid_grab_controls(dev, true);
+
+	dprintk(dev, 1, "returning from %s\n", __func__);
+	return 0;
+}
+
+void vivid_stop_generating_vid_out(struct vivid_dev *dev, bool *pstreaming)
+{
+	dprintk(dev, 1, "%s\n", __func__);
+
+	if (dev->kthread_vid_out == NULL)
+		return;
+
+	*pstreaming = false;
+	if (pstreaming == &dev->vid_out_streaming) {
+		/* Release all active buffers */
+		while (!list_empty(&dev->vid_out_active)) {
+			struct vivid_buffer *buf;
+
+			buf = list_entry(dev->vid_out_active.next,
+					 struct vivid_buffer, list);
+			list_del(&buf->list);
+			v4l2_ctrl_request_complete(buf->vb.vb2_buf.req_obj.req,
+						   &dev->ctrl_hdl_vid_out);
+			vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+			dprintk(dev, 2, "vid_out buffer %d done\n",
+				buf->vb.vb2_buf.index);
+		}
+	}
+
+	if (pstreaming == &dev->vbi_out_streaming) {
+		while (!list_empty(&dev->vbi_out_active)) {
+			struct vivid_buffer *buf;
+
+			buf = list_entry(dev->vbi_out_active.next,
+					 struct vivid_buffer, list);
+			list_del(&buf->list);
+			v4l2_ctrl_request_complete(buf->vb.vb2_buf.req_obj.req,
+						   &dev->ctrl_hdl_vbi_out);
+			vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+			dprintk(dev, 2, "vbi_out buffer %d done\n",
+				buf->vb.vb2_buf.index);
+		}
+	}
+
+	if (pstreaming == &dev->meta_out_streaming) {
+		while (!list_empty(&dev->meta_out_active)) {
+			struct vivid_buffer *buf;
+
+			buf = list_entry(dev->meta_out_active.next,
+					 struct vivid_buffer, list);
+			list_del(&buf->list);
+			v4l2_ctrl_request_complete(buf->vb.vb2_buf.req_obj.req,
+						   &dev->ctrl_hdl_meta_out);
+			vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+			dprintk(dev, 2, "meta_out buffer %d done\n",
+				buf->vb.vb2_buf.index);
+		}
+	}
+
+	if (dev->vid_out_streaming || dev->vbi_out_streaming ||
+	    dev->meta_out_streaming)
+		return;
+
+	/* shutdown control thread */
+	vivid_grab_controls(dev, false);
+	kthread_stop(dev->kthread_vid_out);
+	dev->kthread_vid_out = NULL;
+}
diff --git a/drivers/media/test-drivers/vivid/vivid-kthread-out.h b/drivers/media/test-drivers/vivid/vivid-kthread-out.h
new file mode 100644
index 000000000000..d5bcf44bbaca
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-kthread-out.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * vivid-kthread-out.h - video/vbi output thread support functions.
+ *
+ * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _VIVID_KTHREAD_OUT_H_
+#define _VIVID_KTHREAD_OUT_H_
+
+int vivid_start_generating_vid_out(struct vivid_dev *dev, bool *pstreaming);
+void vivid_stop_generating_vid_out(struct vivid_dev *dev, bool *pstreaming);
+
+#endif
diff --git a/drivers/media/test-drivers/vivid/vivid-kthread-touch.c b/drivers/media/test-drivers/vivid/vivid-kthread-touch.c
new file mode 100644
index 000000000000..674507b5ccb5
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-kthread-touch.c
@@ -0,0 +1,181 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * vivid-kthread-touch.c - touch capture thread support functions.
+ *
+ */
+
+#include <linux/freezer.h>
+#include "vivid-core.h"
+#include "vivid-kthread-touch.h"
+#include "vivid-touch-cap.h"
+
+static noinline_for_stack void vivid_thread_tch_cap_tick(struct vivid_dev *dev,
+							 int dropped_bufs)
+{
+	struct vivid_buffer *tch_cap_buf = NULL;
+
+	spin_lock(&dev->slock);
+	if (!list_empty(&dev->touch_cap_active)) {
+		tch_cap_buf = list_entry(dev->touch_cap_active.next,
+					 struct vivid_buffer, list);
+		list_del(&tch_cap_buf->list);
+	}
+
+	spin_unlock(&dev->slock);
+
+	if (tch_cap_buf) {
+		v4l2_ctrl_request_setup(tch_cap_buf->vb.vb2_buf.req_obj.req,
+					&dev->ctrl_hdl_touch_cap);
+
+		vivid_fillbuff_tch(dev, tch_cap_buf);
+		v4l2_ctrl_request_complete(tch_cap_buf->vb.vb2_buf.req_obj.req,
+					   &dev->ctrl_hdl_touch_cap);
+		vb2_buffer_done(&tch_cap_buf->vb.vb2_buf, dev->dqbuf_error ?
+				VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
+		dprintk(dev, 2, "touch_cap buffer %d done\n",
+			tch_cap_buf->vb.vb2_buf.index);
+
+		tch_cap_buf->vb.vb2_buf.timestamp = ktime_get_ns() + dev->time_wrap_offset;
+	}
+	dev->dqbuf_error = false;
+}
+
+static int vivid_thread_touch_cap(void *data)
+{
+	struct vivid_dev *dev = data;
+	u64 numerators_since_start;
+	u64 buffers_since_start;
+	u64 next_jiffies_since_start;
+	unsigned long jiffies_since_start;
+	unsigned long cur_jiffies;
+	unsigned int wait_jiffies;
+	unsigned int numerator;
+	unsigned int denominator;
+	int dropped_bufs;
+
+	dprintk(dev, 1, "Touch Capture Thread Start\n");
+
+	set_freezable();
+
+	/* Resets frame counters */
+	dev->touch_cap_seq_offset = 0;
+	dev->touch_cap_seq_count = 0;
+	dev->touch_cap_seq_resync = false;
+	dev->jiffies_touch_cap = jiffies;
+
+	for (;;) {
+		try_to_freeze();
+		if (kthread_should_stop())
+			break;
+
+		if (!mutex_trylock(&dev->mutex)) {
+			schedule_timeout_uninterruptible(1);
+			continue;
+		}
+		cur_jiffies = jiffies;
+		if (dev->touch_cap_seq_resync) {
+			dev->jiffies_touch_cap = cur_jiffies;
+			dev->touch_cap_seq_offset = dev->touch_cap_seq_count + 1;
+			dev->touch_cap_seq_count = 0;
+			dev->cap_seq_resync = false;
+		}
+		denominator = dev->timeperframe_tch_cap.denominator;
+		numerator = dev->timeperframe_tch_cap.numerator;
+
+		/* Calculate the number of jiffies since we started streaming */
+		jiffies_since_start = cur_jiffies - dev->jiffies_touch_cap;
+		/* Get the number of buffers streamed since the start */
+		buffers_since_start = (u64)jiffies_since_start * denominator +
+				      (HZ * numerator) / 2;
+		do_div(buffers_since_start, HZ * numerator);
+
+		/*
+		 * After more than 0xf0000000 (rounded down to a multiple of
+		 * 'jiffies-per-day' to ease jiffies_to_msecs calculation)
+		 * jiffies have passed since we started streaming reset the
+		 * counters and keep track of the sequence offset.
+		 */
+		if (jiffies_since_start > JIFFIES_RESYNC) {
+			dev->jiffies_touch_cap = cur_jiffies;
+			dev->cap_seq_offset = buffers_since_start;
+			buffers_since_start = 0;
+		}
+		dropped_bufs = buffers_since_start + dev->touch_cap_seq_offset - dev->touch_cap_seq_count;
+		dev->touch_cap_seq_count = buffers_since_start + dev->touch_cap_seq_offset;
+
+		vivid_thread_tch_cap_tick(dev, dropped_bufs);
+
+		/*
+		 * Calculate the number of 'numerators' streamed
+		 * since we started, including the current buffer.
+		 */
+		numerators_since_start = ++buffers_since_start * numerator;
+
+		/* And the number of jiffies since we started */
+		jiffies_since_start = jiffies - dev->jiffies_touch_cap;
+
+		mutex_unlock(&dev->mutex);
+
+		/*
+		 * Calculate when that next buffer is supposed to start
+		 * in jiffies since we started streaming.
+		 */
+		next_jiffies_since_start = numerators_since_start * HZ +
+					   denominator / 2;
+		do_div(next_jiffies_since_start, denominator);
+		/* If it is in the past, then just schedule asap */
+		if (next_jiffies_since_start < jiffies_since_start)
+			next_jiffies_since_start = jiffies_since_start;
+
+		wait_jiffies = next_jiffies_since_start - jiffies_since_start;
+		schedule_timeout_interruptible(wait_jiffies ? wait_jiffies : 1);
+	}
+	dprintk(dev, 1, "Touch Capture Thread End\n");
+	return 0;
+}
+
+int vivid_start_generating_touch_cap(struct vivid_dev *dev)
+{
+	if (dev->kthread_touch_cap) {
+		dev->touch_cap_streaming = true;
+		return 0;
+	}
+
+	dev->kthread_touch_cap = kthread_run(vivid_thread_touch_cap, dev,
+					     "%s-tch-cap", dev->v4l2_dev.name);
+
+	if (IS_ERR(dev->kthread_touch_cap)) {
+		int err = PTR_ERR(dev->kthread_touch_cap);
+
+		dev->kthread_touch_cap = NULL;
+		v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n");
+		return err;
+	}
+	dev->touch_cap_streaming = true;
+	dprintk(dev, 1, "returning from %s\n", __func__);
+	return 0;
+}
+
+void vivid_stop_generating_touch_cap(struct vivid_dev *dev)
+{
+	if (!dev->kthread_touch_cap)
+		return;
+
+	dev->touch_cap_streaming = false;
+
+	while (!list_empty(&dev->touch_cap_active)) {
+		struct vivid_buffer *buf;
+
+		buf = list_entry(dev->touch_cap_active.next,
+				 struct vivid_buffer, list);
+		list_del(&buf->list);
+		v4l2_ctrl_request_complete(buf->vb.vb2_buf.req_obj.req,
+					   &dev->ctrl_hdl_touch_cap);
+		vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+		dprintk(dev, 2, "touch_cap buffer %d done\n",
+			buf->vb.vb2_buf.index);
+	}
+
+	kthread_stop(dev->kthread_touch_cap);
+	dev->kthread_touch_cap = NULL;
+}
diff --git a/drivers/media/test-drivers/vivid/vivid-kthread-touch.h b/drivers/media/test-drivers/vivid/vivid-kthread-touch.h
new file mode 100644
index 000000000000..ecf79b46209e
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-kthread-touch.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * vivid-kthread-cap.h - video/vbi capture thread support functions.
+ *
+ */
+
+#ifndef _VIVID_KTHREAD_CAP_H_
+#define _VIVID_KTHREAD_CAP_H_
+
+int vivid_start_generating_touch_cap(struct vivid_dev *dev);
+void vivid_stop_generating_touch_cap(struct vivid_dev *dev);
+
+#endif
diff --git a/drivers/media/test-drivers/vivid/vivid-meta-cap.c b/drivers/media/test-drivers/vivid/vivid-meta-cap.c
new file mode 100644
index 000000000000..780f96860a6d
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-meta-cap.c
@@ -0,0 +1,201 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * vivid-meta-cap.c - meta capture support functions.
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-common.h>
+#include <linux/usb/video.h>
+
+#include "vivid-core.h"
+#include "vivid-kthread-cap.h"
+#include "vivid-meta-cap.h"
+
+static int meta_cap_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
+				unsigned int *nplanes, unsigned int sizes[],
+				struct device *alloc_devs[])
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vq);
+	unsigned int size =  sizeof(struct vivid_uvc_meta_buf);
+
+	if (!vivid_is_webcam(dev))
+		return -EINVAL;
+
+	if (*nplanes) {
+		if (sizes[0] < size)
+			return -EINVAL;
+	} else {
+		sizes[0] = size;
+	}
+
+	if (vq->num_buffers + *nbuffers < 2)
+		*nbuffers = 2 - vq->num_buffers;
+
+	*nplanes = 1;
+	return 0;
+}
+
+static int meta_cap_buf_prepare(struct vb2_buffer *vb)
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
+	unsigned int size = sizeof(struct vivid_uvc_meta_buf);
+
+	dprintk(dev, 1, "%s\n", __func__);
+
+	if (dev->buf_prepare_error) {
+		/*
+		 * Error injection: test what happens if buf_prepare() returns
+		 * an error.
+		 */
+		dev->buf_prepare_error = false;
+		return -EINVAL;
+	}
+	if (vb2_plane_size(vb, 0) < size) {
+		dprintk(dev, 1, "%s data will not fit into plane (%lu < %u)\n",
+			__func__, vb2_plane_size(vb, 0), size);
+		return -EINVAL;
+	}
+	vb2_set_plane_payload(vb, 0, size);
+
+	return 0;
+}
+
+static void meta_cap_buf_queue(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
+	struct vivid_buffer *buf = container_of(vbuf, struct vivid_buffer, vb);
+
+	dprintk(dev, 1, "%s\n", __func__);
+
+	spin_lock(&dev->slock);
+	list_add_tail(&buf->list, &dev->meta_cap_active);
+	spin_unlock(&dev->slock);
+}
+
+static int meta_cap_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vq);
+	int err;
+
+	dprintk(dev, 1, "%s\n", __func__);
+	dev->meta_cap_seq_count = 0;
+	if (dev->start_streaming_error) {
+		dev->start_streaming_error = false;
+		err = -EINVAL;
+	} else {
+		err = vivid_start_generating_vid_cap(dev,
+						     &dev->meta_cap_streaming);
+	}
+	if (err) {
+		struct vivid_buffer *buf, *tmp;
+
+		list_for_each_entry_safe(buf, tmp,
+					 &dev->meta_cap_active, list) {
+			list_del(&buf->list);
+			vb2_buffer_done(&buf->vb.vb2_buf,
+					VB2_BUF_STATE_QUEUED);
+		}
+	}
+	return err;
+}
+
+/* abort streaming and wait for last buffer */
+static void meta_cap_stop_streaming(struct vb2_queue *vq)
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vq);
+
+	dprintk(dev, 1, "%s\n", __func__);
+	vivid_stop_generating_vid_cap(dev, &dev->meta_cap_streaming);
+}
+
+static void meta_cap_buf_request_complete(struct vb2_buffer *vb)
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
+
+	v4l2_ctrl_request_complete(vb->req_obj.req, &dev->ctrl_hdl_meta_cap);
+}
+
+const struct vb2_ops vivid_meta_cap_qops = {
+	.queue_setup		= meta_cap_queue_setup,
+	.buf_prepare		= meta_cap_buf_prepare,
+	.buf_queue		= meta_cap_buf_queue,
+	.start_streaming	= meta_cap_start_streaming,
+	.stop_streaming		= meta_cap_stop_streaming,
+	.buf_request_complete	= meta_cap_buf_request_complete,
+	.wait_prepare		= vb2_ops_wait_prepare,
+	.wait_finish		= vb2_ops_wait_finish,
+};
+
+int vidioc_enum_fmt_meta_cap(struct file *file, void  *priv,
+			     struct v4l2_fmtdesc *f)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (!vivid_is_webcam(dev))
+		return -EINVAL;
+
+	if (f->index > 0)
+		return -EINVAL;
+
+	f->type = V4L2_BUF_TYPE_META_CAPTURE;
+	f->pixelformat = V4L2_META_FMT_UVC;
+	return 0;
+}
+
+int vidioc_g_fmt_meta_cap(struct file *file, void *priv,
+			  struct v4l2_format *f)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	struct v4l2_meta_format *meta = &f->fmt.meta;
+
+	if (!vivid_is_webcam(dev) || !dev->has_meta_cap)
+		return -EINVAL;
+
+	meta->dataformat = V4L2_META_FMT_UVC;
+	meta->buffersize = sizeof(struct vivid_uvc_meta_buf);
+	return 0;
+}
+
+void vivid_meta_cap_fillbuff(struct vivid_dev *dev,
+			     struct vivid_buffer *buf, u64 soe)
+{
+	struct vivid_uvc_meta_buf *meta = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
+	int buf_off = 0;
+
+	buf->vb.sequence = dev->meta_cap_seq_count;
+	if (dev->field_cap == V4L2_FIELD_ALTERNATE)
+		buf->vb.sequence /= 2;
+	memset(meta, 1, vb2_plane_size(&buf->vb.vb2_buf, 0));
+
+	meta->ns = ktime_get_ns();
+	meta->sof = buf->vb.sequence * 30;
+	meta->length = sizeof(*meta) - offsetof(struct vivid_uvc_meta_buf, length);
+	meta->flags = UVC_STREAM_EOH | UVC_STREAM_EOF;
+
+	if ((buf->vb.sequence % 2) == 0)
+		meta->flags |= UVC_STREAM_FID;
+
+	dprintk(dev, 2, "%s ns:%llu sof:%4d len:%u flags: 0x%02x",
+		__func__, meta->ns, meta->sof, meta->length, meta->flags);
+	if (dev->meta_pts) {
+		meta->flags |= UVC_STREAM_PTS;
+		meta->buf[0] = div_u64(soe, VIVID_META_CLOCK_UNIT);
+		buf_off = 4;
+		dprintk(dev, 2, " pts: %u\n", *(__u32 *)(meta->buf));
+	}
+
+	if (dev->meta_scr) {
+		meta->flags |= UVC_STREAM_SCR;
+		meta->buf[buf_off] = div_u64((soe + dev->cap_frame_eof_offset),
+					     VIVID_META_CLOCK_UNIT);
+
+		meta->buf[buf_off + 4] = (buf->vb.sequence * 30) % 1000;
+		dprintk(dev, 2, " stc: %u, sof counter: %u\n",
+			*(__u32 *)(meta->buf + buf_off),
+			*(__u16 *)(meta->buf + buf_off + 4));
+	}
+	dprintk(dev, 2, "\n");
+}
diff --git a/drivers/media/test-drivers/vivid/vivid-meta-cap.h b/drivers/media/test-drivers/vivid/vivid-meta-cap.h
new file mode 100644
index 000000000000..4670d00d1576
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-meta-cap.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * vivid-meta-cap.h - meta capture support functions.
+ */
+#ifndef _VIVID_META_CAP_H_
+#define _VIVID_META_CAP_H_
+
+#define VIVID_META_CLOCK_UNIT	10 /* 100 MHz */
+
+struct vivid_uvc_meta_buf {
+	__u64 ns;
+	__u16 sof;
+	__u8 length;
+	__u8 flags;
+	__u8 buf[10]; /* PTS(4)+STC(4)+SOF(2) */
+} __packed;
+
+void vivid_meta_cap_fillbuff(struct vivid_dev *dev,
+			     struct vivid_buffer *buf, u64 soe);
+
+int vidioc_enum_fmt_meta_cap(struct file *file, void  *priv,
+			     struct v4l2_fmtdesc *f);
+
+int vidioc_g_fmt_meta_cap(struct file *file, void *priv,
+			  struct v4l2_format *f);
+
+extern const struct vb2_ops vivid_meta_cap_qops;
+
+#endif
diff --git a/drivers/media/test-drivers/vivid/vivid-meta-out.c b/drivers/media/test-drivers/vivid/vivid-meta-out.c
new file mode 100644
index 000000000000..ff8a039aba72
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-meta-out.c
@@ -0,0 +1,174 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * vivid-meta-out.c - meta output support functions.
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-common.h>
+#include <linux/usb/video.h>
+
+#include "vivid-core.h"
+#include "vivid-kthread-out.h"
+#include "vivid-meta-out.h"
+
+static int meta_out_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
+				unsigned int *nplanes, unsigned int sizes[],
+				struct device *alloc_devs[])
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vq);
+	unsigned int size =  sizeof(struct vivid_meta_out_buf);
+
+	if (!vivid_is_webcam(dev))
+		return -EINVAL;
+
+	if (*nplanes) {
+		if (sizes[0] < size)
+			return -EINVAL;
+	} else {
+		sizes[0] = size;
+	}
+
+	if (vq->num_buffers + *nbuffers < 2)
+		*nbuffers = 2 - vq->num_buffers;
+
+	*nplanes = 1;
+	return 0;
+}
+
+static int meta_out_buf_prepare(struct vb2_buffer *vb)
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
+	unsigned int size = sizeof(struct vivid_meta_out_buf);
+
+	dprintk(dev, 1, "%s\n", __func__);
+
+	if (dev->buf_prepare_error) {
+		/*
+		 * Error injection: test what happens if buf_prepare() returns
+		 * an error.
+		 */
+		dev->buf_prepare_error = false;
+		return -EINVAL;
+	}
+	if (vb2_plane_size(vb, 0) < size) {
+		dprintk(dev, 1, "%s data will not fit into plane (%lu < %u)\n",
+			__func__, vb2_plane_size(vb, 0), size);
+		return -EINVAL;
+	}
+	vb2_set_plane_payload(vb, 0, size);
+
+	return 0;
+}
+
+static void meta_out_buf_queue(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
+	struct vivid_buffer *buf = container_of(vbuf, struct vivid_buffer, vb);
+
+	dprintk(dev, 1, "%s\n", __func__);
+
+	spin_lock(&dev->slock);
+	list_add_tail(&buf->list, &dev->meta_out_active);
+	spin_unlock(&dev->slock);
+}
+
+static int meta_out_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vq);
+	int err;
+
+	dprintk(dev, 1, "%s\n", __func__);
+	dev->meta_out_seq_count = 0;
+	if (dev->start_streaming_error) {
+		dev->start_streaming_error = false;
+		err = -EINVAL;
+	} else {
+		err = vivid_start_generating_vid_out(dev,
+						     &dev->meta_out_streaming);
+	}
+	if (err) {
+		struct vivid_buffer *buf, *tmp;
+
+		list_for_each_entry_safe(buf, tmp,
+					 &dev->meta_out_active, list) {
+			list_del(&buf->list);
+			vb2_buffer_done(&buf->vb.vb2_buf,
+					VB2_BUF_STATE_QUEUED);
+		}
+	}
+	return err;
+}
+
+/* abort streaming and wait for last buffer */
+static void meta_out_stop_streaming(struct vb2_queue *vq)
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vq);
+
+	dprintk(dev, 1, "%s\n", __func__);
+	vivid_stop_generating_vid_out(dev, &dev->meta_out_streaming);
+}
+
+static void meta_out_buf_request_complete(struct vb2_buffer *vb)
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
+
+	v4l2_ctrl_request_complete(vb->req_obj.req, &dev->ctrl_hdl_meta_out);
+}
+
+const struct vb2_ops vivid_meta_out_qops = {
+	.queue_setup            = meta_out_queue_setup,
+	.buf_prepare            = meta_out_buf_prepare,
+	.buf_queue              = meta_out_buf_queue,
+	.start_streaming        = meta_out_start_streaming,
+	.stop_streaming         = meta_out_stop_streaming,
+	.buf_request_complete   = meta_out_buf_request_complete,
+	.wait_prepare           = vb2_ops_wait_prepare,
+	.wait_finish            = vb2_ops_wait_finish,
+};
+
+int vidioc_enum_fmt_meta_out(struct file *file, void  *priv,
+			     struct v4l2_fmtdesc *f)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (!vivid_is_webcam(dev))
+		return -EINVAL;
+
+	if (f->index > 0)
+		return -EINVAL;
+
+	f->type = V4L2_BUF_TYPE_META_OUTPUT;
+	f->pixelformat = V4L2_META_FMT_VIVID;
+	return 0;
+}
+
+int vidioc_g_fmt_meta_out(struct file *file, void *priv,
+			  struct v4l2_format *f)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	struct v4l2_meta_format *meta = &f->fmt.meta;
+
+	if (!vivid_is_webcam(dev) || !dev->has_meta_out)
+		return -EINVAL;
+
+	meta->dataformat = V4L2_META_FMT_VIVID;
+	meta->buffersize = sizeof(struct vivid_meta_out_buf);
+	return 0;
+}
+
+void vivid_meta_out_process(struct vivid_dev *dev,
+			    struct vivid_buffer *buf)
+{
+	struct vivid_meta_out_buf *meta = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
+
+	tpg_s_brightness(&dev->tpg, meta->brightness);
+	tpg_s_contrast(&dev->tpg, meta->contrast);
+	tpg_s_saturation(&dev->tpg, meta->saturation);
+	tpg_s_hue(&dev->tpg, meta->hue);
+	dprintk(dev, 2, " %s brightness %u contrast %u saturation %u hue %d\n",
+		__func__, meta->brightness, meta->contrast,
+		meta->saturation, meta->hue);
+}
diff --git a/drivers/media/test-drivers/vivid/vivid-meta-out.h b/drivers/media/test-drivers/vivid/vivid-meta-out.h
new file mode 100644
index 000000000000..0c639b7c2842
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-meta-out.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * vivid-meta-out.h - meta output support functions.
+ */
+#ifndef _VIVID_META_OUT_H_
+#define _VIVID_META_OUT_H_
+
+struct vivid_meta_out_buf {
+	u16	brightness;
+	u16	contrast;
+	u16	saturation;
+	s16	hue;
+};
+
+void vivid_meta_out_process(struct vivid_dev *dev, struct vivid_buffer *buf);
+int vidioc_enum_fmt_meta_out(struct file *file, void  *priv,
+			     struct v4l2_fmtdesc *f);
+int vidioc_g_fmt_meta_out(struct file *file, void *priv,
+			  struct v4l2_format *f);
+int vidioc_s_fmt_meta_out(struct file *file, void *priv,
+			  struct v4l2_format *f);
+
+extern const struct vb2_ops vivid_meta_out_qops;
+
+#endif
diff --git a/drivers/media/test-drivers/vivid/vivid-osd.c b/drivers/media/test-drivers/vivid/vivid-osd.c
new file mode 100644
index 000000000000..fbaec8acc161
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-osd.c
@@ -0,0 +1,388 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * vivid-osd.c - osd support for testing overlays.
+ *
+ * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/font.h>
+#include <linux/mutex.h>
+#include <linux/videodev2.h>
+#include <linux/kthread.h>
+#include <linux/freezer.h>
+#include <linux/fb.h>
+#include <media/videobuf2-vmalloc.h>
+#include <media/v4l2-device.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 "vivid-core.h"
+#include "vivid-osd.h"
+
+#define MAX_OSD_WIDTH  720
+#define MAX_OSD_HEIGHT 576
+
+/*
+ * Order: white, yellow, cyan, green, magenta, red, blue, black,
+ * and same again with the alpha bit set (if any)
+ */
+static const u16 rgb555[16] = {
+	0x7fff, 0x7fe0, 0x03ff, 0x03e0, 0x7c1f, 0x7c00, 0x001f, 0x0000,
+	0xffff, 0xffe0, 0x83ff, 0x83e0, 0xfc1f, 0xfc00, 0x801f, 0x8000
+};
+
+static const u16 rgb565[16] = {
+	0xffff, 0xffe0, 0x07ff, 0x07e0, 0xf81f, 0xf800, 0x001f, 0x0000,
+	0xffff, 0xffe0, 0x07ff, 0x07e0, 0xf81f, 0xf800, 0x001f, 0x0000
+};
+
+void vivid_clear_fb(struct vivid_dev *dev)
+{
+	void *p = dev->video_vbase;
+	const u16 *rgb = rgb555;
+	unsigned x, y;
+
+	if (dev->fb_defined.green.length == 6)
+		rgb = rgb565;
+
+	for (y = 0; y < dev->display_height; y++) {
+		u16 *d = p;
+
+		for (x = 0; x < dev->display_width; x++)
+			d[x] = rgb[(y / 16 + x / 16) % 16];
+		p += dev->display_byte_stride;
+	}
+}
+
+/* --------------------------------------------------------------------- */
+
+static int vivid_fb_ioctl(struct fb_info *info, unsigned cmd, unsigned long arg)
+{
+	struct vivid_dev *dev = (struct vivid_dev *)info->par;
+
+	switch (cmd) {
+	case FBIOGET_VBLANK: {
+		struct fb_vblank vblank;
+
+		memset(&vblank, 0, sizeof(vblank));
+		vblank.flags = FB_VBLANK_HAVE_COUNT | FB_VBLANK_HAVE_VCOUNT |
+			FB_VBLANK_HAVE_VSYNC;
+		vblank.count = 0;
+		vblank.vcount = 0;
+		vblank.hcount = 0;
+		if (copy_to_user((void __user *)arg, &vblank, sizeof(vblank)))
+			return -EFAULT;
+		return 0;
+	}
+
+	default:
+		dprintk(dev, 1, "Unknown ioctl %08x\n", cmd);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/* Framebuffer device handling */
+
+static int vivid_fb_set_var(struct vivid_dev *dev, struct fb_var_screeninfo *var)
+{
+	dprintk(dev, 1, "vivid_fb_set_var\n");
+
+	if (var->bits_per_pixel != 16) {
+		dprintk(dev, 1, "vivid_fb_set_var - Invalid bpp\n");
+		return -EINVAL;
+	}
+	dev->display_byte_stride = var->xres * dev->bytes_per_pixel;
+
+	return 0;
+}
+
+static int vivid_fb_get_fix(struct vivid_dev *dev, struct fb_fix_screeninfo *fix)
+{
+	dprintk(dev, 1, "vivid_fb_get_fix\n");
+	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+	strscpy(fix->id, "vioverlay fb", sizeof(fix->id));
+	fix->smem_start = dev->video_pbase;
+	fix->smem_len = dev->video_buffer_size;
+	fix->type = FB_TYPE_PACKED_PIXELS;
+	fix->visual = FB_VISUAL_TRUECOLOR;
+	fix->xpanstep = 1;
+	fix->ypanstep = 1;
+	fix->ywrapstep = 0;
+	fix->line_length = dev->display_byte_stride;
+	fix->accel = FB_ACCEL_NONE;
+	return 0;
+}
+
+/* Check the requested display mode, returning -EINVAL if we can't
+   handle it. */
+
+static int _vivid_fb_check_var(struct fb_var_screeninfo *var, struct vivid_dev *dev)
+{
+	dprintk(dev, 1, "vivid_fb_check_var\n");
+
+	var->bits_per_pixel = 16;
+	if (var->green.length == 5) {
+		var->red.offset = 10;
+		var->red.length = 5;
+		var->green.offset = 5;
+		var->green.length = 5;
+		var->blue.offset = 0;
+		var->blue.length = 5;
+		var->transp.offset = 15;
+		var->transp.length = 1;
+	} else {
+		var->red.offset = 11;
+		var->red.length = 5;
+		var->green.offset = 5;
+		var->green.length = 6;
+		var->blue.offset = 0;
+		var->blue.length = 5;
+		var->transp.offset = 0;
+		var->transp.length = 0;
+	}
+	var->xoffset = var->yoffset = 0;
+	var->left_margin = var->upper_margin = 0;
+	var->nonstd = 0;
+
+	var->vmode &= ~FB_VMODE_MASK;
+	var->vmode |= FB_VMODE_NONINTERLACED;
+
+	/* Dummy values */
+	var->hsync_len = 24;
+	var->vsync_len = 2;
+	var->pixclock = 84316;
+	var->right_margin = 776;
+	var->lower_margin = 591;
+	return 0;
+}
+
+static int vivid_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+	struct vivid_dev *dev = (struct vivid_dev *) info->par;
+
+	dprintk(dev, 1, "vivid_fb_check_var\n");
+	return _vivid_fb_check_var(var, dev);
+}
+
+static int vivid_fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+	return 0;
+}
+
+static int vivid_fb_set_par(struct fb_info *info)
+{
+	int rc = 0;
+	struct vivid_dev *dev = (struct vivid_dev *) info->par;
+
+	dprintk(dev, 1, "vivid_fb_set_par\n");
+
+	rc = vivid_fb_set_var(dev, &info->var);
+	vivid_fb_get_fix(dev, &info->fix);
+	return rc;
+}
+
+static int vivid_fb_setcolreg(unsigned regno, unsigned red, unsigned green,
+				unsigned blue, unsigned transp,
+				struct fb_info *info)
+{
+	u32 color, *palette;
+
+	if (regno >= info->cmap.len)
+		return -EINVAL;
+
+	color = ((transp & 0xFF00) << 16) | ((red & 0xFF00) << 8) |
+		 (green & 0xFF00) | ((blue & 0xFF00) >> 8);
+	if (regno >= 16)
+		return -EINVAL;
+
+	palette = info->pseudo_palette;
+	if (info->var.bits_per_pixel == 16) {
+		switch (info->var.green.length) {
+		case 6:
+			color = (red & 0xf800) |
+				((green & 0xfc00) >> 5) |
+				((blue & 0xf800) >> 11);
+			break;
+		case 5:
+			color = ((red & 0xf800) >> 1) |
+				((green & 0xf800) >> 6) |
+				((blue & 0xf800) >> 11) |
+				(transp ? 0x8000 : 0);
+			break;
+		}
+	}
+	palette[regno] = color;
+	return 0;
+}
+
+/* We don't really support blanking. All this does is enable or
+   disable the OSD. */
+static int vivid_fb_blank(int blank_mode, struct fb_info *info)
+{
+	struct vivid_dev *dev = (struct vivid_dev *)info->par;
+
+	dprintk(dev, 1, "Set blanking mode : %d\n", blank_mode);
+	switch (blank_mode) {
+	case FB_BLANK_UNBLANK:
+		break;
+	case FB_BLANK_NORMAL:
+	case FB_BLANK_HSYNC_SUSPEND:
+	case FB_BLANK_VSYNC_SUSPEND:
+	case FB_BLANK_POWERDOWN:
+		break;
+	}
+	return 0;
+}
+
+static const struct fb_ops vivid_fb_ops = {
+	.owner = THIS_MODULE,
+	.fb_check_var   = vivid_fb_check_var,
+	.fb_set_par     = vivid_fb_set_par,
+	.fb_setcolreg   = vivid_fb_setcolreg,
+	.fb_fillrect    = cfb_fillrect,
+	.fb_copyarea    = cfb_copyarea,
+	.fb_imageblit   = cfb_imageblit,
+	.fb_cursor      = NULL,
+	.fb_ioctl       = vivid_fb_ioctl,
+	.fb_pan_display = vivid_fb_pan_display,
+	.fb_blank       = vivid_fb_blank,
+};
+
+/* Initialization */
+
+
+/* Setup our initial video mode */
+static int vivid_fb_init_vidmode(struct vivid_dev *dev)
+{
+	struct v4l2_rect start_window;
+
+	/* Color mode */
+
+	dev->bits_per_pixel = 16;
+	dev->bytes_per_pixel = dev->bits_per_pixel / 8;
+
+	start_window.width = MAX_OSD_WIDTH;
+	start_window.left = 0;
+
+	dev->display_byte_stride = start_window.width * dev->bytes_per_pixel;
+
+	/* Vertical size & position */
+
+	start_window.height = MAX_OSD_HEIGHT;
+	start_window.top = 0;
+
+	dev->display_width = start_window.width;
+	dev->display_height = start_window.height;
+
+	/* Generate a valid fb_var_screeninfo */
+
+	dev->fb_defined.xres = dev->display_width;
+	dev->fb_defined.yres = dev->display_height;
+	dev->fb_defined.xres_virtual = dev->display_width;
+	dev->fb_defined.yres_virtual = dev->display_height;
+	dev->fb_defined.bits_per_pixel = dev->bits_per_pixel;
+	dev->fb_defined.vmode = FB_VMODE_NONINTERLACED;
+	dev->fb_defined.left_margin = start_window.left + 1;
+	dev->fb_defined.upper_margin = start_window.top + 1;
+	dev->fb_defined.accel_flags = FB_ACCEL_NONE;
+	dev->fb_defined.nonstd = 0;
+	/* set default to 1:5:5:5 */
+	dev->fb_defined.green.length = 5;
+
+	/* We've filled in the most data, let the usual mode check
+	   routine fill in the rest. */
+	_vivid_fb_check_var(&dev->fb_defined, dev);
+
+	/* Generate valid fb_fix_screeninfo */
+
+	vivid_fb_get_fix(dev, &dev->fb_fix);
+
+	/* Generate valid fb_info */
+
+	dev->fb_info.node = -1;
+	dev->fb_info.flags = FBINFO_FLAG_DEFAULT;
+	dev->fb_info.par = dev;
+	dev->fb_info.var = dev->fb_defined;
+	dev->fb_info.fix = dev->fb_fix;
+	dev->fb_info.screen_base = (u8 __iomem *)dev->video_vbase;
+	dev->fb_info.fbops = &vivid_fb_ops;
+
+	/* Supply some monitor specs. Bogus values will do for now */
+	dev->fb_info.monspecs.hfmin = 8000;
+	dev->fb_info.monspecs.hfmax = 70000;
+	dev->fb_info.monspecs.vfmin = 10;
+	dev->fb_info.monspecs.vfmax = 100;
+
+	/* Allocate color map */
+	if (fb_alloc_cmap(&dev->fb_info.cmap, 256, 1)) {
+		pr_err("abort, unable to alloc cmap\n");
+		return -ENOMEM;
+	}
+
+	/* Allocate the pseudo palette */
+	dev->fb_info.pseudo_palette = kmalloc_array(16, sizeof(u32), GFP_KERNEL);
+
+	return dev->fb_info.pseudo_palette ? 0 : -ENOMEM;
+}
+
+/* Release any memory we've grabbed */
+void vivid_fb_release_buffers(struct vivid_dev *dev)
+{
+	if (dev->video_vbase == NULL)
+		return;
+
+	/* Release cmap */
+	if (dev->fb_info.cmap.len)
+		fb_dealloc_cmap(&dev->fb_info.cmap);
+
+	/* Release pseudo palette */
+	kfree(dev->fb_info.pseudo_palette);
+	kfree(dev->video_vbase);
+}
+
+/* Initialize the specified card */
+
+int vivid_fb_init(struct vivid_dev *dev)
+{
+	int ret;
+
+	dev->video_buffer_size = MAX_OSD_HEIGHT * MAX_OSD_WIDTH * 2;
+	dev->video_vbase = kzalloc(dev->video_buffer_size, GFP_KERNEL | GFP_DMA32);
+	if (dev->video_vbase == NULL)
+		return -ENOMEM;
+	dev->video_pbase = virt_to_phys(dev->video_vbase);
+
+	pr_info("Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
+			dev->video_pbase, dev->video_vbase,
+			dev->video_buffer_size / 1024);
+
+	/* Set the startup video mode information */
+	ret = vivid_fb_init_vidmode(dev);
+	if (ret) {
+		vivid_fb_release_buffers(dev);
+		return ret;
+	}
+
+	vivid_clear_fb(dev);
+
+	/* Register the framebuffer */
+	if (register_framebuffer(&dev->fb_info) < 0) {
+		vivid_fb_release_buffers(dev);
+		return -EINVAL;
+	}
+
+	/* Set the card to the requested mode */
+	vivid_fb_set_par(&dev->fb_info);
+	return 0;
+
+}
diff --git a/drivers/media/test-drivers/vivid/vivid-osd.h b/drivers/media/test-drivers/vivid/vivid-osd.h
new file mode 100644
index 000000000000..f9ac1af25dd3
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-osd.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * vivid-osd.h - output overlay support functions.
+ *
+ * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _VIVID_OSD_H_
+#define _VIVID_OSD_H_
+
+int vivid_fb_init(struct vivid_dev *dev);
+void vivid_fb_release_buffers(struct vivid_dev *dev);
+void vivid_clear_fb(struct vivid_dev *dev);
+
+#endif
diff --git a/drivers/media/test-drivers/vivid/vivid-radio-common.c b/drivers/media/test-drivers/vivid/vivid-radio-common.c
new file mode 100644
index 000000000000..138c7bce68b1
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-radio-common.c
@@ -0,0 +1,177 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * vivid-radio-common.c - common radio rx/tx support functions.
+ *
+ * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/videodev2.h>
+
+#include "vivid-core.h"
+#include "vivid-ctrls.h"
+#include "vivid-radio-common.h"
+#include "vivid-rds-gen.h"
+
+/*
+ * These functions are shared between the vivid receiver and transmitter
+ * since both use the same frequency bands.
+ */
+
+const struct v4l2_frequency_band vivid_radio_bands[TOT_BANDS] = {
+	/* Band FM */
+	{
+		.type = V4L2_TUNER_RADIO,
+		.index = 0,
+		.capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
+			      V4L2_TUNER_CAP_FREQ_BANDS,
+		.rangelow   = FM_FREQ_RANGE_LOW,
+		.rangehigh  = FM_FREQ_RANGE_HIGH,
+		.modulation = V4L2_BAND_MODULATION_FM,
+	},
+	/* Band AM */
+	{
+		.type = V4L2_TUNER_RADIO,
+		.index = 1,
+		.capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_FREQ_BANDS,
+		.rangelow   = AM_FREQ_RANGE_LOW,
+		.rangehigh  = AM_FREQ_RANGE_HIGH,
+		.modulation = V4L2_BAND_MODULATION_AM,
+	},
+	/* Band SW */
+	{
+		.type = V4L2_TUNER_RADIO,
+		.index = 2,
+		.capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_FREQ_BANDS,
+		.rangelow   = SW_FREQ_RANGE_LOW,
+		.rangehigh  = SW_FREQ_RANGE_HIGH,
+		.modulation = V4L2_BAND_MODULATION_AM,
+	},
+};
+
+/*
+ * Initialize the RDS generator. If we can loop, then the RDS generator
+ * is set up with the values from the RDS TX controls, otherwise it
+ * will fill in standard values using one of two alternates.
+ */
+void vivid_radio_rds_init(struct vivid_dev *dev)
+{
+	struct vivid_rds_gen *rds = &dev->rds_gen;
+	bool alt = dev->radio_rx_rds_use_alternates;
+
+	/* Do nothing, blocks will be filled by the transmitter */
+	if (dev->radio_rds_loop && !dev->radio_tx_rds_controls)
+		return;
+
+	if (dev->radio_rds_loop) {
+		v4l2_ctrl_lock(dev->radio_tx_rds_pi);
+		rds->picode = dev->radio_tx_rds_pi->cur.val;
+		rds->pty = dev->radio_tx_rds_pty->cur.val;
+		rds->mono_stereo = dev->radio_tx_rds_mono_stereo->cur.val;
+		rds->art_head = dev->radio_tx_rds_art_head->cur.val;
+		rds->compressed = dev->radio_tx_rds_compressed->cur.val;
+		rds->dyn_pty = dev->radio_tx_rds_dyn_pty->cur.val;
+		rds->ta = dev->radio_tx_rds_ta->cur.val;
+		rds->tp = dev->radio_tx_rds_tp->cur.val;
+		rds->ms = dev->radio_tx_rds_ms->cur.val;
+		strscpy(rds->psname,
+			dev->radio_tx_rds_psname->p_cur.p_char,
+			sizeof(rds->psname));
+		strscpy(rds->radiotext,
+			dev->radio_tx_rds_radiotext->p_cur.p_char + alt * 64,
+			sizeof(rds->radiotext));
+		v4l2_ctrl_unlock(dev->radio_tx_rds_pi);
+	} else {
+		vivid_rds_gen_fill(rds, dev->radio_rx_freq, alt);
+	}
+	if (dev->radio_rx_rds_controls) {
+		v4l2_ctrl_s_ctrl(dev->radio_rx_rds_pty, rds->pty);
+		v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ta, rds->ta);
+		v4l2_ctrl_s_ctrl(dev->radio_rx_rds_tp, rds->tp);
+		v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ms, rds->ms);
+		v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_psname, rds->psname);
+		v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_radiotext, rds->radiotext);
+		if (!dev->radio_rds_loop)
+			dev->radio_rx_rds_use_alternates = !dev->radio_rx_rds_use_alternates;
+	}
+	vivid_rds_generate(rds);
+}
+
+/*
+ * Calculate the emulated signal quality taking into account the frequency
+ * the transmitter is using.
+ */
+static void vivid_radio_calc_sig_qual(struct vivid_dev *dev)
+{
+	int mod = 16000;
+	int delta = 800;
+	int sig_qual, sig_qual_tx = mod;
+
+	/*
+	 * For SW and FM there is a channel every 1000 kHz, for AM there is one
+	 * every 100 kHz.
+	 */
+	if (dev->radio_rx_freq <= AM_FREQ_RANGE_HIGH) {
+		mod /= 10;
+		delta /= 10;
+	}
+	sig_qual = (dev->radio_rx_freq + delta) % mod - delta;
+	if (dev->has_radio_tx)
+		sig_qual_tx = dev->radio_rx_freq - dev->radio_tx_freq;
+	if (abs(sig_qual_tx) <= abs(sig_qual)) {
+		sig_qual = sig_qual_tx;
+		/*
+		 * Zero the internal rds buffer if we are going to loop
+		 * rds blocks.
+		 */
+		if (!dev->radio_rds_loop && !dev->radio_tx_rds_controls)
+			memset(dev->rds_gen.data, 0,
+			       sizeof(dev->rds_gen.data));
+		dev->radio_rds_loop = dev->radio_rx_freq >= FM_FREQ_RANGE_LOW;
+	} else {
+		dev->radio_rds_loop = false;
+	}
+	if (dev->radio_rx_freq <= AM_FREQ_RANGE_HIGH)
+		sig_qual *= 10;
+	dev->radio_rx_sig_qual = sig_qual;
+}
+
+int vivid_radio_g_frequency(struct file *file, const unsigned *pfreq, struct v4l2_frequency *vf)
+{
+	if (vf->tuner != 0)
+		return -EINVAL;
+	vf->frequency = *pfreq;
+	return 0;
+}
+
+int vivid_radio_s_frequency(struct file *file, unsigned *pfreq, const struct v4l2_frequency *vf)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	unsigned freq;
+	unsigned band;
+
+	if (vf->tuner != 0)
+		return -EINVAL;
+
+	if (vf->frequency >= (FM_FREQ_RANGE_LOW + SW_FREQ_RANGE_HIGH) / 2)
+		band = BAND_FM;
+	else if (vf->frequency <= (AM_FREQ_RANGE_HIGH + SW_FREQ_RANGE_LOW) / 2)
+		band = BAND_AM;
+	else
+		band = BAND_SW;
+
+	freq = clamp_t(u32, vf->frequency, vivid_radio_bands[band].rangelow,
+					   vivid_radio_bands[band].rangehigh);
+	*pfreq = freq;
+
+	/*
+	 * For both receiver and transmitter recalculate the signal quality
+	 * (since that depends on both frequencies) and re-init the rds
+	 * generator.
+	 */
+	vivid_radio_calc_sig_qual(dev);
+	vivid_radio_rds_init(dev);
+	return 0;
+}
diff --git a/drivers/media/test-drivers/vivid/vivid-radio-common.h b/drivers/media/test-drivers/vivid/vivid-radio-common.h
new file mode 100644
index 000000000000..30a9900e5b2b
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-radio-common.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * vivid-radio-common.h - common radio rx/tx support functions.
+ *
+ * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _VIVID_RADIO_COMMON_H_
+#define _VIVID_RADIO_COMMON_H_
+
+/* The supported radio frequency ranges in kHz */
+#define FM_FREQ_RANGE_LOW       (64000U * 16U)
+#define FM_FREQ_RANGE_HIGH      (108000U * 16U)
+#define AM_FREQ_RANGE_LOW       (520U * 16U)
+#define AM_FREQ_RANGE_HIGH      (1710U * 16U)
+#define SW_FREQ_RANGE_LOW       (2300U * 16U)
+#define SW_FREQ_RANGE_HIGH      (26100U * 16U)
+
+enum { BAND_FM, BAND_AM, BAND_SW, TOT_BANDS };
+
+extern const struct v4l2_frequency_band vivid_radio_bands[TOT_BANDS];
+
+int vivid_radio_g_frequency(struct file *file, const unsigned *freq, struct v4l2_frequency *vf);
+int vivid_radio_s_frequency(struct file *file, unsigned *freq, const struct v4l2_frequency *vf);
+
+void vivid_radio_rds_init(struct vivid_dev *dev);
+
+#endif
diff --git a/drivers/media/test-drivers/vivid/vivid-radio-rx.c b/drivers/media/test-drivers/vivid/vivid-radio-rx.c
new file mode 100644
index 000000000000..232cab508f48
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-radio-rx.c
@@ -0,0 +1,278 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * vivid-radio-rx.c - radio receiver support functions.
+ *
+ * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/videodev2.h>
+#include <linux/v4l2-dv-timings.h>
+#include <linux/sched/signal.h>
+
+#include <media/v4l2-common.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-dv-timings.h>
+
+#include "vivid-core.h"
+#include "vivid-ctrls.h"
+#include "vivid-radio-common.h"
+#include "vivid-rds-gen.h"
+#include "vivid-radio-rx.h"
+
+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 v4l2_rds_data *data = dev->rds_gen.data;
+	bool use_alternates;
+	ktime_t timestamp;
+	unsigned blk;
+	int perc;
+	int i;
+
+	if (dev->radio_rx_rds_controls)
+		return -EINVAL;
+	if (size < sizeof(*data))
+		return 0;
+	size = sizeof(*data) * (size / sizeof(*data));
+
+	if (mutex_lock_interruptible(&dev->mutex))
+		return -ERESTARTSYS;
+	if (dev->radio_rx_rds_owner &&
+	    file->private_data != dev->radio_rx_rds_owner) {
+		mutex_unlock(&dev->mutex);
+		return -EBUSY;
+	}
+	if (dev->radio_rx_rds_owner == NULL) {
+		vivid_radio_rds_init(dev);
+		dev->radio_rx_rds_owner = file->private_data;
+	}
+
+retry:
+	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);
+	}
+	if (blk >= dev->radio_rx_rds_last_block + VIVID_RDS_GEN_BLOCKS)
+		dev->radio_rx_rds_last_block = blk - VIVID_RDS_GEN_BLOCKS + 1;
+
+	/*
+	 * No data is available if there hasn't been time to get new data,
+	 * or if the RDS receiver has been disabled, or if we use the data
+	 * from the RDS transmitter and that RDS transmitter has been disabled,
+	 * or if the signal quality is too weak.
+	 */
+	if (blk == dev->radio_rx_rds_last_block || !dev->radio_rx_rds_enabled ||
+	    (dev->radio_rds_loop && !(dev->radio_tx_subchans & V4L2_TUNER_SUB_RDS)) ||
+	    abs(dev->radio_rx_sig_qual) > 200) {
+		mutex_unlock(&dev->mutex);
+		if (file->f_flags & O_NONBLOCK)
+			return -EWOULDBLOCK;
+		if (msleep_interruptible(20) && signal_pending(current))
+			return -EINTR;
+		if (mutex_lock_interruptible(&dev->mutex))
+			return -ERESTARTSYS;
+		goto retry;
+	}
+
+	/* abs(dev->radio_rx_sig_qual) <= 200, map that to a 0-50% range */
+	perc = abs(dev->radio_rx_sig_qual) / 4;
+
+	for (i = 0; i < size && blk > dev->radio_rx_rds_last_block;
+			dev->radio_rx_rds_last_block++) {
+		unsigned data_blk = dev->radio_rx_rds_last_block % VIVID_RDS_GEN_BLOCKS;
+		struct v4l2_rds_data rds = data[data_blk];
+
+		if (data_blk == 0 && dev->radio_rds_loop)
+			vivid_radio_rds_init(dev);
+		if (perc && prandom_u32_max(100) < perc) {
+			switch (prandom_u32_max(4)) {
+			case 0:
+				rds.block |= V4L2_RDS_BLOCK_CORRECTED;
+				break;
+			case 1:
+				rds.block |= V4L2_RDS_BLOCK_INVALID;
+				break;
+			case 2:
+				rds.block |= V4L2_RDS_BLOCK_ERROR;
+				rds.lsb = prandom_u32_max(256);
+				rds.msb = prandom_u32_max(256);
+				break;
+			case 3: /* Skip block altogether */
+				if (i)
+					continue;
+				/*
+				 * Must make sure at least one block is
+				 * returned, otherwise the application
+				 * might think that end-of-file occurred.
+				 */
+				break;
+			}
+		}
+		if (copy_to_user(buf + i, &rds, sizeof(rds))) {
+			i = -EFAULT;
+			break;
+		}
+		i += sizeof(rds);
+	}
+	mutex_unlock(&dev->mutex);
+	return i;
+}
+
+__poll_t vivid_radio_rx_poll(struct file *file, struct poll_table_struct *wait)
+{
+	return EPOLLIN | EPOLLRDNORM | v4l2_ctrl_poll(file, wait);
+}
+
+int vivid_radio_rx_enum_freq_bands(struct file *file, void *fh, struct v4l2_frequency_band *band)
+{
+	if (band->tuner != 0)
+		return -EINVAL;
+
+	if (band->index >= TOT_BANDS)
+		return -EINVAL;
+
+	*band = vivid_radio_bands[band->index];
+	return 0;
+}
+
+int vivid_radio_rx_s_hw_freq_seek(struct file *file, void *fh, const struct v4l2_hw_freq_seek *a)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	unsigned low, high;
+	unsigned freq;
+	unsigned spacing;
+	unsigned band;
+
+	if (a->tuner)
+		return -EINVAL;
+	if (a->wrap_around && dev->radio_rx_hw_seek_mode == VIVID_HW_SEEK_BOUNDED)
+		return -EINVAL;
+
+	if (!a->wrap_around && dev->radio_rx_hw_seek_mode == VIVID_HW_SEEK_WRAP)
+		return -EINVAL;
+	if (!a->rangelow ^ !a->rangehigh)
+		return -EINVAL;
+
+	if (file->f_flags & O_NONBLOCK)
+		return -EWOULDBLOCK;
+
+	if (a->rangelow) {
+		for (band = 0; band < TOT_BANDS; band++)
+			if (a->rangelow >= vivid_radio_bands[band].rangelow &&
+			    a->rangehigh <= vivid_radio_bands[band].rangehigh)
+				break;
+		if (band == TOT_BANDS)
+			return -EINVAL;
+		if (!dev->radio_rx_hw_seek_prog_lim &&
+		    (a->rangelow != vivid_radio_bands[band].rangelow ||
+		     a->rangehigh != vivid_radio_bands[band].rangehigh))
+			return -EINVAL;
+		low = a->rangelow;
+		high = a->rangehigh;
+	} else {
+		for (band = 0; band < TOT_BANDS; band++)
+			if (dev->radio_rx_freq >= vivid_radio_bands[band].rangelow &&
+			    dev->radio_rx_freq <= vivid_radio_bands[band].rangehigh)
+				break;
+		if (band == TOT_BANDS)
+			return -EINVAL;
+		low = vivid_radio_bands[band].rangelow;
+		high = vivid_radio_bands[band].rangehigh;
+	}
+	spacing = band == BAND_AM ? 1600 : 16000;
+	freq = clamp(dev->radio_rx_freq, low, high);
+
+	if (a->seek_upward) {
+		freq = spacing * (freq / spacing) + spacing;
+		if (freq > high) {
+			if (!a->wrap_around)
+				return -ENODATA;
+			freq = spacing * (low / spacing) + spacing;
+			if (freq >= dev->radio_rx_freq)
+				return -ENODATA;
+		}
+	} else {
+		freq = spacing * ((freq + spacing - 1) / spacing) - spacing;
+		if (freq < low) {
+			if (!a->wrap_around)
+				return -ENODATA;
+			freq = spacing * ((high + spacing - 1) / spacing) - spacing;
+			if (freq <= dev->radio_rx_freq)
+				return -ENODATA;
+		}
+	}
+	return 0;
+}
+
+int vivid_radio_rx_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	int delta = 800;
+	int sig_qual;
+
+	if (vt->index > 0)
+		return -EINVAL;
+
+	strscpy(vt->name, "AM/FM/SW Receiver", sizeof(vt->name));
+	vt->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
+			 V4L2_TUNER_CAP_FREQ_BANDS | V4L2_TUNER_CAP_RDS |
+			 (dev->radio_rx_rds_controls ?
+				V4L2_TUNER_CAP_RDS_CONTROLS :
+				V4L2_TUNER_CAP_RDS_BLOCK_IO) |
+			 (dev->radio_rx_hw_seek_prog_lim ?
+				V4L2_TUNER_CAP_HWSEEK_PROG_LIM : 0);
+	switch (dev->radio_rx_hw_seek_mode) {
+	case VIVID_HW_SEEK_BOUNDED:
+		vt->capability |= V4L2_TUNER_CAP_HWSEEK_BOUNDED;
+		break;
+	case VIVID_HW_SEEK_WRAP:
+		vt->capability |= V4L2_TUNER_CAP_HWSEEK_WRAP;
+		break;
+	case VIVID_HW_SEEK_BOTH:
+		vt->capability |= V4L2_TUNER_CAP_HWSEEK_WRAP |
+				  V4L2_TUNER_CAP_HWSEEK_BOUNDED;
+		break;
+	}
+	vt->rangelow = AM_FREQ_RANGE_LOW;
+	vt->rangehigh = FM_FREQ_RANGE_HIGH;
+	sig_qual = dev->radio_rx_sig_qual;
+	vt->signal = abs(sig_qual) > delta ? 0 :
+		     0xffff - ((unsigned)abs(sig_qual) * 0xffff) / delta;
+	vt->afc = sig_qual > delta ? 0 : sig_qual;
+	if (abs(sig_qual) > delta)
+		vt->rxsubchans = 0;
+	else if (dev->radio_rx_freq < FM_FREQ_RANGE_LOW || vt->signal < 0x8000)
+		vt->rxsubchans = V4L2_TUNER_SUB_MONO;
+	else if (dev->radio_rds_loop && !(dev->radio_tx_subchans & V4L2_TUNER_SUB_STEREO))
+		vt->rxsubchans = V4L2_TUNER_SUB_MONO;
+	else
+		vt->rxsubchans = V4L2_TUNER_SUB_STEREO;
+	if (dev->radio_rx_rds_enabled &&
+	    (!dev->radio_rds_loop || (dev->radio_tx_subchans & V4L2_TUNER_SUB_RDS)) &&
+	    dev->radio_rx_freq >= FM_FREQ_RANGE_LOW && vt->signal >= 0xc000)
+		vt->rxsubchans |= V4L2_TUNER_SUB_RDS;
+	if (dev->radio_rx_rds_controls)
+		vivid_radio_rds_init(dev);
+	vt->audmode = dev->radio_rx_audmode;
+	return 0;
+}
+
+int vivid_radio_rx_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (vt->index)
+		return -EINVAL;
+	dev->radio_rx_audmode = vt->audmode >= V4L2_TUNER_MODE_STEREO;
+	return 0;
+}
diff --git a/drivers/media/test-drivers/vivid/vivid-radio-rx.h b/drivers/media/test-drivers/vivid/vivid-radio-rx.h
new file mode 100644
index 000000000000..c9c7849f6f99
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-radio-rx.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * vivid-radio-rx.h - radio receiver support functions.
+ *
+ * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _VIVID_RADIO_RX_H_
+#define _VIVID_RADIO_RX_H_
+
+ssize_t vivid_radio_rx_read(struct file *, char __user *, size_t, loff_t *);
+__poll_t vivid_radio_rx_poll(struct file *file, struct poll_table_struct *wait);
+
+int vivid_radio_rx_enum_freq_bands(struct file *file, void *fh, struct v4l2_frequency_band *band);
+int vivid_radio_rx_s_hw_freq_seek(struct file *file, void *fh, const struct v4l2_hw_freq_seek *a);
+int vivid_radio_rx_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt);
+int vivid_radio_rx_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt);
+
+#endif
diff --git a/drivers/media/test-drivers/vivid/vivid-radio-tx.c b/drivers/media/test-drivers/vivid/vivid-radio-tx.c
new file mode 100644
index 000000000000..049d40b948bb
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-radio-tx.c
@@ -0,0 +1,128 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * vivid-radio-tx.c - radio transmitter support functions.
+ *
+ * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/sched/signal.h>
+#include <linux/delay.h>
+#include <linux/videodev2.h>
+#include <linux/v4l2-dv-timings.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-dv-timings.h>
+
+#include "vivid-core.h"
+#include "vivid-ctrls.h"
+#include "vivid-radio-common.h"
+#include "vivid-radio-tx.h"
+
+ssize_t vivid_radio_tx_write(struct file *file, const char __user *buf,
+			  size_t size, loff_t *offset)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	struct v4l2_rds_data *data = dev->rds_gen.data;
+	ktime_t timestamp;
+	unsigned blk;
+	int i;
+
+	if (dev->radio_tx_rds_controls)
+		return -EINVAL;
+
+	if (size < sizeof(*data))
+		return -EINVAL;
+	size = sizeof(*data) * (size / sizeof(*data));
+
+	if (mutex_lock_interruptible(&dev->mutex))
+		return -ERESTARTSYS;
+	if (dev->radio_tx_rds_owner &&
+	    file->private_data != dev->radio_tx_rds_owner) {
+		mutex_unlock(&dev->mutex);
+		return -EBUSY;
+	}
+	dev->radio_tx_rds_owner = file->private_data;
+
+retry:
+	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;
+
+	/*
+	 * No data is available if there hasn't been time to get new data,
+	 * or if the RDS receiver has been disabled, or if we use the data
+	 * from the RDS transmitter and that RDS transmitter has been disabled,
+	 * or if the signal quality is too weak.
+	 */
+	if (blk == dev->radio_tx_rds_last_block ||
+	    !(dev->radio_tx_subchans & V4L2_TUNER_SUB_RDS)) {
+		mutex_unlock(&dev->mutex);
+		if (file->f_flags & O_NONBLOCK)
+			return -EWOULDBLOCK;
+		if (msleep_interruptible(20) && signal_pending(current))
+			return -EINTR;
+		if (mutex_lock_interruptible(&dev->mutex))
+			return -ERESTARTSYS;
+		goto retry;
+	}
+
+	for (i = 0; i < size && blk > dev->radio_tx_rds_last_block;
+			dev->radio_tx_rds_last_block++) {
+		unsigned data_blk = dev->radio_tx_rds_last_block % VIVID_RDS_GEN_BLOCKS;
+		struct v4l2_rds_data rds;
+
+		if (copy_from_user(&rds, buf + i, sizeof(rds))) {
+			i = -EFAULT;
+			break;
+		}
+		i += sizeof(rds);
+		if (!dev->radio_rds_loop)
+			continue;
+		if ((rds.block & V4L2_RDS_BLOCK_MSK) == V4L2_RDS_BLOCK_INVALID ||
+		    (rds.block & V4L2_RDS_BLOCK_ERROR))
+			continue;
+		rds.block &= V4L2_RDS_BLOCK_MSK;
+		data[data_blk] = rds;
+	}
+	mutex_unlock(&dev->mutex);
+	return i;
+}
+
+__poll_t vivid_radio_tx_poll(struct file *file, struct poll_table_struct *wait)
+{
+	return EPOLLOUT | EPOLLWRNORM | v4l2_ctrl_poll(file, wait);
+}
+
+int vidioc_g_modulator(struct file *file, void *fh, struct v4l2_modulator *a)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (a->index > 0)
+		return -EINVAL;
+
+	strscpy(a->name, "AM/FM/SW Transmitter", sizeof(a->name));
+	a->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
+			V4L2_TUNER_CAP_FREQ_BANDS | V4L2_TUNER_CAP_RDS |
+			(dev->radio_tx_rds_controls ?
+				V4L2_TUNER_CAP_RDS_CONTROLS :
+				V4L2_TUNER_CAP_RDS_BLOCK_IO);
+	a->rangelow = AM_FREQ_RANGE_LOW;
+	a->rangehigh = FM_FREQ_RANGE_HIGH;
+	a->txsubchans = dev->radio_tx_subchans;
+	return 0;
+}
+
+int vidioc_s_modulator(struct file *file, void *fh, const struct v4l2_modulator *a)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (a->index)
+		return -EINVAL;
+	if (a->txsubchans & ~0x13)
+		return -EINVAL;
+	dev->radio_tx_subchans = a->txsubchans;
+	return 0;
+}
diff --git a/drivers/media/test-drivers/vivid/vivid-radio-tx.h b/drivers/media/test-drivers/vivid/vivid-radio-tx.h
new file mode 100644
index 000000000000..c2bf1e7e634a
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-radio-tx.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * vivid-radio-tx.h - radio transmitter support functions.
+ *
+ * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _VIVID_RADIO_TX_H_
+#define _VIVID_RADIO_TX_H_
+
+ssize_t vivid_radio_tx_write(struct file *, const char __user *, size_t, loff_t *);
+__poll_t vivid_radio_tx_poll(struct file *file, struct poll_table_struct *wait);
+
+int vidioc_g_modulator(struct file *file, void *fh, struct v4l2_modulator *a);
+int vidioc_s_modulator(struct file *file, void *fh, const struct v4l2_modulator *a);
+
+#endif
diff --git a/drivers/media/test-drivers/vivid/vivid-rds-gen.c b/drivers/media/test-drivers/vivid/vivid-rds-gen.c
new file mode 100644
index 000000000000..b5b104ee64c9
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-rds-gen.c
@@ -0,0 +1,157 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * vivid-rds-gen.c - rds (radio data system) generator support functions.
+ *
+ * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#include <linux/kernel.h>
+#include <linux/ktime.h>
+#include <linux/string.h>
+#include <linux/videodev2.h>
+
+#include "vivid-rds-gen.h"
+
+static u8 vivid_get_di(const struct vivid_rds_gen *rds, unsigned grp)
+{
+	switch (grp) {
+	case 0:
+		return (rds->dyn_pty << 2) | (grp & 3);
+	case 1:
+		return (rds->compressed << 2) | (grp & 3);
+	case 2:
+		return (rds->art_head << 2) | (grp & 3);
+	case 3:
+		return (rds->mono_stereo << 2) | (grp & 3);
+	}
+	return 0;
+}
+
+/*
+ * This RDS generator creates 57 RDS groups (one group == four RDS blocks).
+ * Groups 0-3, 22-25 and 44-47 (spaced 22 groups apart) are filled with a
+ * standard 0B group containing the PI code and PS name.
+ *
+ * Groups 4-19 and 26-41 use group 2A for the radio text.
+ *
+ * Group 56 contains the time (group 4A).
+ *
+ * All remaining groups use a filler group 15B block that just repeats
+ * the PI and PTY codes.
+ */
+void vivid_rds_generate(struct vivid_rds_gen *rds)
+{
+	struct v4l2_rds_data *data = rds->data;
+	unsigned grp;
+	unsigned idx;
+	struct tm tm;
+	unsigned date;
+	unsigned time;
+	int l;
+
+	for (grp = 0; grp < VIVID_RDS_GEN_GROUPS; grp++, data += VIVID_RDS_GEN_BLKS_PER_GRP) {
+		data[0].lsb = rds->picode & 0xff;
+		data[0].msb = rds->picode >> 8;
+		data[0].block = V4L2_RDS_BLOCK_A | (V4L2_RDS_BLOCK_A << 3);
+		data[1].lsb = rds->pty << 5;
+		data[1].msb = (rds->pty >> 3) | (rds->tp << 2);
+		data[1].block = V4L2_RDS_BLOCK_B | (V4L2_RDS_BLOCK_B << 3);
+		data[3].block = V4L2_RDS_BLOCK_D | (V4L2_RDS_BLOCK_D << 3);
+
+		switch (grp) {
+		case 0 ... 3:
+		case 22 ... 25:
+		case 44 ... 47: /* Group 0B */
+			idx = (grp % 22) % 4;
+			data[1].lsb |= (rds->ta << 4) | (rds->ms << 3);
+			data[1].lsb |= vivid_get_di(rds, idx);
+			data[1].msb |= 1 << 3;
+			data[2].lsb = rds->picode & 0xff;
+			data[2].msb = rds->picode >> 8;
+			data[2].block = V4L2_RDS_BLOCK_C_ALT | (V4L2_RDS_BLOCK_C_ALT << 3);
+			data[3].lsb = rds->psname[2 * idx + 1];
+			data[3].msb = rds->psname[2 * idx];
+			break;
+		case 4 ... 19:
+		case 26 ... 41: /* Group 2A */
+			idx = ((grp - 4) % 22) % 16;
+			data[1].lsb |= idx;
+			data[1].msb |= 4 << 3;
+			data[2].msb = rds->radiotext[4 * idx];
+			data[2].lsb = rds->radiotext[4 * idx + 1];
+			data[2].block = V4L2_RDS_BLOCK_C | (V4L2_RDS_BLOCK_C << 3);
+			data[3].msb = rds->radiotext[4 * idx + 2];
+			data[3].lsb = rds->radiotext[4 * idx + 3];
+			break;
+		case 56:
+			/*
+			 * Group 4A
+			 *
+			 * Uses the algorithm from Annex G of the RDS standard
+			 * EN 50067:1998 to convert a UTC date to an RDS Modified
+			 * Julian Day.
+			 */
+			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;
+			time = (tm.tm_hour << 12) |
+			       (tm.tm_min << 6) |
+			       (sys_tz.tz_minuteswest >= 0 ? 0x20 : 0) |
+			       (abs(sys_tz.tz_minuteswest) / 30);
+			data[1].lsb &= ~3;
+			data[1].lsb |= date >> 15;
+			data[1].msb |= 8 << 3;
+			data[2].lsb = (date << 1) & 0xfe;
+			data[2].lsb |= (time >> 16) & 1;
+			data[2].msb = (date >> 7) & 0xff;
+			data[2].block = V4L2_RDS_BLOCK_C | (V4L2_RDS_BLOCK_C << 3);
+			data[3].lsb = time & 0xff;
+			data[3].msb = (time >> 8) & 0xff;
+			break;
+		default: /* Group 15B */
+			data[1].lsb |= (rds->ta << 4) | (rds->ms << 3);
+			data[1].lsb |= vivid_get_di(rds, grp % 22);
+			data[1].msb |= 0x1f << 3;
+			data[2].lsb = rds->picode & 0xff;
+			data[2].msb = rds->picode >> 8;
+			data[2].block = V4L2_RDS_BLOCK_C_ALT | (V4L2_RDS_BLOCK_C_ALT << 3);
+			data[3].lsb = rds->pty << 5;
+			data[3].lsb |= (rds->ta << 4) | (rds->ms << 3);
+			data[3].lsb |= vivid_get_di(rds, grp % 22);
+			data[3].msb |= rds->pty >> 3;
+			data[3].msb |= 0x1f << 3;
+			break;
+		}
+	}
+}
+
+void vivid_rds_gen_fill(struct vivid_rds_gen *rds, unsigned freq,
+			  bool alt)
+{
+	/* Alternate PTY between Info and Weather */
+	if (rds->use_rbds) {
+		rds->picode = 0x2e75; /* 'KLNX' call sign */
+		rds->pty = alt ? 29 : 2;
+	} else {
+		rds->picode = 0x8088;
+		rds->pty = alt ? 16 : 3;
+	}
+	rds->mono_stereo = true;
+	rds->art_head = false;
+	rds->compressed = false;
+	rds->dyn_pty = false;
+	rds->tp = true;
+	rds->ta = alt;
+	rds->ms = true;
+	snprintf(rds->psname, sizeof(rds->psname), "%6d.%1d",
+		 freq / 16, ((freq & 0xf) * 10) / 16);
+	if (alt)
+		strscpy(rds->radiotext,
+			" The Radio Data System can switch between different Radio Texts ",
+			sizeof(rds->radiotext));
+	else
+		strscpy(rds->radiotext,
+			"An example of Radio Text as transmitted by the Radio Data System",
+			sizeof(rds->radiotext));
+}
diff --git a/drivers/media/test-drivers/vivid/vivid-rds-gen.h b/drivers/media/test-drivers/vivid/vivid-rds-gen.h
new file mode 100644
index 000000000000..35ac5742302b
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-rds-gen.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * vivid-rds-gen.h - rds (radio data system) generator support functions.
+ *
+ * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _VIVID_RDS_GEN_H_
+#define _VIVID_RDS_GEN_H_
+
+/*
+ * It takes almost exactly 5 seconds to transmit 57 RDS groups.
+ * Each group has 4 blocks and each block has a payload of 16 bits + a
+ * block identification. The driver will generate the contents of these
+ * 57 groups only when necessary and it will just be played continuously.
+ */
+#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];
+	bool			use_rbds;
+	u16			picode;
+	u8			pty;
+	bool			mono_stereo;
+	bool			art_head;
+	bool			compressed;
+	bool			dyn_pty;
+	bool			ta;
+	bool			tp;
+	bool			ms;
+	char			psname[8 + 1];
+	char			radiotext[64 + 1];
+};
+
+void vivid_rds_gen_fill(struct vivid_rds_gen *rds, unsigned freq,
+		    bool use_alternate);
+void vivid_rds_generate(struct vivid_rds_gen *rds);
+
+#endif
diff --git a/drivers/media/test-drivers/vivid/vivid-sdr-cap.c b/drivers/media/test-drivers/vivid/vivid-sdr-cap.c
new file mode 100644
index 000000000000..2b7522e16efc
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-sdr-cap.c
@@ -0,0 +1,570 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * vivid-sdr-cap.c - software defined radio support functions.
+ *
+ * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/kthread.h>
+#include <linux/freezer.h>
+#include <linux/math64.h>
+#include <linux/videodev2.h>
+#include <linux/v4l2-dv-timings.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-dv-timings.h>
+#include <linux/fixp-arith.h>
+
+#include "vivid-core.h"
+#include "vivid-ctrls.h"
+#include "vivid-sdr-cap.h"
+
+/* stream formats */
+struct vivid_format {
+	u32	pixelformat;
+	u32	buffersize;
+};
+
+/* format descriptions for capture and preview */
+static const struct vivid_format formats[] = {
+	{
+		.pixelformat	= V4L2_SDR_FMT_CU8,
+		.buffersize	= SDR_CAP_SAMPLES_PER_BUF * 2,
+	}, {
+		.pixelformat	= V4L2_SDR_FMT_CS8,
+		.buffersize	= SDR_CAP_SAMPLES_PER_BUF * 2,
+	},
+};
+
+static const struct v4l2_frequency_band bands_adc[] = {
+	{
+		.tuner = 0,
+		.type = V4L2_TUNER_ADC,
+		.index = 0,
+		.capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
+		.rangelow   =  300000,
+		.rangehigh  =  300000,
+	},
+	{
+		.tuner = 0,
+		.type = V4L2_TUNER_ADC,
+		.index = 1,
+		.capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
+		.rangelow   =  900001,
+		.rangehigh  = 2800000,
+	},
+	{
+		.tuner = 0,
+		.type = V4L2_TUNER_ADC,
+		.index = 2,
+		.capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
+		.rangelow   = 3200000,
+		.rangehigh  = 3200000,
+	},
+};
+
+/* ADC band midpoints */
+#define BAND_ADC_0 ((bands_adc[0].rangehigh + bands_adc[1].rangelow) / 2)
+#define BAND_ADC_1 ((bands_adc[1].rangehigh + bands_adc[2].rangelow) / 2)
+
+static const struct v4l2_frequency_band bands_fm[] = {
+	{
+		.tuner = 1,
+		.type = V4L2_TUNER_RF,
+		.index = 0,
+		.capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
+		.rangelow   =    50000000,
+		.rangehigh  =  2000000000,
+	},
+};
+
+static void vivid_thread_sdr_cap_tick(struct vivid_dev *dev)
+{
+	struct vivid_buffer *sdr_cap_buf = NULL;
+
+	dprintk(dev, 1, "SDR Capture Thread Tick\n");
+
+	/* Drop a certain percentage of buffers. */
+	if (dev->perc_dropped_buffers &&
+	    prandom_u32_max(100) < dev->perc_dropped_buffers)
+		return;
+
+	spin_lock(&dev->slock);
+	if (!list_empty(&dev->sdr_cap_active)) {
+		sdr_cap_buf = list_entry(dev->sdr_cap_active.next,
+					 struct vivid_buffer, list);
+		list_del(&sdr_cap_buf->list);
+	}
+	spin_unlock(&dev->slock);
+
+	if (sdr_cap_buf) {
+		sdr_cap_buf->vb.sequence = dev->sdr_cap_seq_count;
+		v4l2_ctrl_request_setup(sdr_cap_buf->vb.vb2_buf.req_obj.req,
+					&dev->ctrl_hdl_sdr_cap);
+		v4l2_ctrl_request_complete(sdr_cap_buf->vb.vb2_buf.req_obj.req,
+					   &dev->ctrl_hdl_sdr_cap);
+		vivid_sdr_cap_process(dev, sdr_cap_buf);
+		sdr_cap_buf->vb.vb2_buf.timestamp =
+			ktime_get_ns() + dev->time_wrap_offset;
+		vb2_buffer_done(&sdr_cap_buf->vb.vb2_buf, dev->dqbuf_error ?
+				VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
+		dev->dqbuf_error = false;
+	}
+}
+
+static int vivid_thread_sdr_cap(void *data)
+{
+	struct vivid_dev *dev = data;
+	u64 samples_since_start;
+	u64 buffers_since_start;
+	u64 next_jiffies_since_start;
+	unsigned long jiffies_since_start;
+	unsigned long cur_jiffies;
+	unsigned wait_jiffies;
+
+	dprintk(dev, 1, "SDR Capture Thread Start\n");
+
+	set_freezable();
+
+	/* Resets frame counters */
+	dev->sdr_cap_seq_offset = 0;
+	if (dev->seq_wrap)
+		dev->sdr_cap_seq_offset = 0xffffff80U;
+	dev->jiffies_sdr_cap = jiffies;
+	dev->sdr_cap_seq_resync = false;
+
+	for (;;) {
+		try_to_freeze();
+		if (kthread_should_stop())
+			break;
+
+		if (!mutex_trylock(&dev->mutex)) {
+			schedule_timeout_uninterruptible(1);
+			continue;
+		}
+
+		cur_jiffies = jiffies;
+		if (dev->sdr_cap_seq_resync) {
+			dev->jiffies_sdr_cap = cur_jiffies;
+			dev->sdr_cap_seq_offset = dev->sdr_cap_seq_count + 1;
+			dev->sdr_cap_seq_count = 0;
+			dev->sdr_cap_seq_resync = false;
+		}
+		/* Calculate the number of jiffies since we started streaming */
+		jiffies_since_start = cur_jiffies - dev->jiffies_sdr_cap;
+		/* Get the number of buffers streamed since the start */
+		buffers_since_start =
+			(u64)jiffies_since_start * dev->sdr_adc_freq +
+				      (HZ * SDR_CAP_SAMPLES_PER_BUF) / 2;
+		do_div(buffers_since_start, HZ * SDR_CAP_SAMPLES_PER_BUF);
+
+		/*
+		 * After more than 0xf0000000 (rounded down to a multiple of
+		 * 'jiffies-per-day' to ease jiffies_to_msecs calculation)
+		 * jiffies have passed since we started streaming reset the
+		 * counters and keep track of the sequence offset.
+		 */
+		if (jiffies_since_start > JIFFIES_RESYNC) {
+			dev->jiffies_sdr_cap = cur_jiffies;
+			dev->sdr_cap_seq_offset = buffers_since_start;
+			buffers_since_start = 0;
+		}
+		dev->sdr_cap_seq_count =
+			buffers_since_start + dev->sdr_cap_seq_offset;
+
+		vivid_thread_sdr_cap_tick(dev);
+		mutex_unlock(&dev->mutex);
+
+		/*
+		 * Calculate the number of samples streamed since we started,
+		 * not including the current buffer.
+		 */
+		samples_since_start = buffers_since_start * SDR_CAP_SAMPLES_PER_BUF;
+
+		/* And the number of jiffies since we started */
+		jiffies_since_start = jiffies - dev->jiffies_sdr_cap;
+
+		/* Increase by the number of samples in one buffer */
+		samples_since_start += SDR_CAP_SAMPLES_PER_BUF;
+		/*
+		 * Calculate when that next buffer is supposed to start
+		 * in jiffies since we started streaming.
+		 */
+		next_jiffies_since_start = samples_since_start * HZ +
+					   dev->sdr_adc_freq / 2;
+		do_div(next_jiffies_since_start, dev->sdr_adc_freq);
+		/* If it is in the past, then just schedule asap */
+		if (next_jiffies_since_start < jiffies_since_start)
+			next_jiffies_since_start = jiffies_since_start;
+
+		wait_jiffies = next_jiffies_since_start - jiffies_since_start;
+		schedule_timeout_interruptible(wait_jiffies ? wait_jiffies : 1);
+	}
+	dprintk(dev, 1, "SDR Capture Thread End\n");
+	return 0;
+}
+
+static int sdr_cap_queue_setup(struct vb2_queue *vq,
+		       unsigned *nbuffers, unsigned *nplanes,
+		       unsigned sizes[], struct device *alloc_devs[])
+{
+	/* 2 = max 16-bit sample returned */
+	sizes[0] = SDR_CAP_SAMPLES_PER_BUF * 2;
+	*nplanes = 1;
+	return 0;
+}
+
+static int sdr_cap_buf_prepare(struct vb2_buffer *vb)
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
+	unsigned size = SDR_CAP_SAMPLES_PER_BUF * 2;
+
+	dprintk(dev, 1, "%s\n", __func__);
+
+	if (dev->buf_prepare_error) {
+		/*
+		 * Error injection: test what happens if buf_prepare() returns
+		 * an error.
+		 */
+		dev->buf_prepare_error = false;
+		return -EINVAL;
+	}
+	if (vb2_plane_size(vb, 0) < size) {
+		dprintk(dev, 1, "%s data will not fit into plane (%lu < %u)\n",
+				__func__, vb2_plane_size(vb, 0), size);
+		return -EINVAL;
+	}
+	vb2_set_plane_payload(vb, 0, size);
+
+	return 0;
+}
+
+static void sdr_cap_buf_queue(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
+	struct vivid_buffer *buf = container_of(vbuf, struct vivid_buffer, vb);
+
+	dprintk(dev, 1, "%s\n", __func__);
+
+	spin_lock(&dev->slock);
+	list_add_tail(&buf->list, &dev->sdr_cap_active);
+	spin_unlock(&dev->slock);
+}
+
+static int sdr_cap_start_streaming(struct vb2_queue *vq, unsigned count)
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vq);
+	int err = 0;
+
+	dprintk(dev, 1, "%s\n", __func__);
+	dev->sdr_cap_seq_count = 0;
+	if (dev->start_streaming_error) {
+		dev->start_streaming_error = false;
+		err = -EINVAL;
+	} else if (dev->kthread_sdr_cap == NULL) {
+		dev->kthread_sdr_cap = kthread_run(vivid_thread_sdr_cap, dev,
+				"%s-sdr-cap", dev->v4l2_dev.name);
+
+		if (IS_ERR(dev->kthread_sdr_cap)) {
+			v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n");
+			err = PTR_ERR(dev->kthread_sdr_cap);
+			dev->kthread_sdr_cap = NULL;
+		}
+	}
+	if (err) {
+		struct vivid_buffer *buf, *tmp;
+
+		list_for_each_entry_safe(buf, tmp, &dev->sdr_cap_active, list) {
+			list_del(&buf->list);
+			vb2_buffer_done(&buf->vb.vb2_buf,
+					VB2_BUF_STATE_QUEUED);
+		}
+	}
+	return err;
+}
+
+/* abort streaming and wait for last buffer */
+static void sdr_cap_stop_streaming(struct vb2_queue *vq)
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vq);
+
+	if (dev->kthread_sdr_cap == NULL)
+		return;
+
+	while (!list_empty(&dev->sdr_cap_active)) {
+		struct vivid_buffer *buf;
+
+		buf = list_entry(dev->sdr_cap_active.next,
+				struct vivid_buffer, list);
+		list_del(&buf->list);
+		v4l2_ctrl_request_complete(buf->vb.vb2_buf.req_obj.req,
+					   &dev->ctrl_hdl_sdr_cap);
+		vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+	}
+
+	/* shutdown control thread */
+	kthread_stop(dev->kthread_sdr_cap);
+	dev->kthread_sdr_cap = NULL;
+}
+
+static void sdr_cap_buf_request_complete(struct vb2_buffer *vb)
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
+
+	v4l2_ctrl_request_complete(vb->req_obj.req, &dev->ctrl_hdl_sdr_cap);
+}
+
+const struct vb2_ops vivid_sdr_cap_qops = {
+	.queue_setup		= sdr_cap_queue_setup,
+	.buf_prepare		= sdr_cap_buf_prepare,
+	.buf_queue		= sdr_cap_buf_queue,
+	.start_streaming	= sdr_cap_start_streaming,
+	.stop_streaming		= sdr_cap_stop_streaming,
+	.buf_request_complete	= sdr_cap_buf_request_complete,
+	.wait_prepare		= vb2_ops_wait_prepare,
+	.wait_finish		= vb2_ops_wait_finish,
+};
+
+int vivid_sdr_enum_freq_bands(struct file *file, void *fh,
+		struct v4l2_frequency_band *band)
+{
+	switch (band->tuner) {
+	case 0:
+		if (band->index >= ARRAY_SIZE(bands_adc))
+			return -EINVAL;
+		*band = bands_adc[band->index];
+		return 0;
+	case 1:
+		if (band->index >= ARRAY_SIZE(bands_fm))
+			return -EINVAL;
+		*band = bands_fm[band->index];
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+int vivid_sdr_g_frequency(struct file *file, void *fh,
+		struct v4l2_frequency *vf)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	switch (vf->tuner) {
+	case 0:
+		vf->frequency = dev->sdr_adc_freq;
+		vf->type = V4L2_TUNER_ADC;
+		return 0;
+	case 1:
+		vf->frequency = dev->sdr_fm_freq;
+		vf->type = V4L2_TUNER_RF;
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+int vivid_sdr_s_frequency(struct file *file, void *fh,
+		const struct v4l2_frequency *vf)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	unsigned freq = vf->frequency;
+	unsigned band;
+
+	switch (vf->tuner) {
+	case 0:
+		if (vf->type != V4L2_TUNER_ADC)
+			return -EINVAL;
+		if (freq < BAND_ADC_0)
+			band = 0;
+		else if (freq < BAND_ADC_1)
+			band = 1;
+		else
+			band = 2;
+
+		freq = clamp_t(unsigned, freq,
+				bands_adc[band].rangelow,
+				bands_adc[band].rangehigh);
+
+		if (vb2_is_streaming(&dev->vb_sdr_cap_q) &&
+		    freq != dev->sdr_adc_freq) {
+			/* resync the thread's timings */
+			dev->sdr_cap_seq_resync = true;
+		}
+		dev->sdr_adc_freq = freq;
+		return 0;
+	case 1:
+		if (vf->type != V4L2_TUNER_RF)
+			return -EINVAL;
+		dev->sdr_fm_freq = clamp_t(unsigned, freq,
+				bands_fm[0].rangelow,
+				bands_fm[0].rangehigh);
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+int vivid_sdr_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
+{
+	switch (vt->index) {
+	case 0:
+		strscpy(vt->name, "ADC", sizeof(vt->name));
+		vt->type = V4L2_TUNER_ADC;
+		vt->capability =
+			V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
+		vt->rangelow = bands_adc[0].rangelow;
+		vt->rangehigh = bands_adc[2].rangehigh;
+		return 0;
+	case 1:
+		strscpy(vt->name, "RF", sizeof(vt->name));
+		vt->type = V4L2_TUNER_RF;
+		vt->capability =
+			V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
+		vt->rangelow = bands_fm[0].rangelow;
+		vt->rangehigh = bands_fm[0].rangehigh;
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+int vivid_sdr_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt)
+{
+	if (vt->index > 1)
+		return -EINVAL;
+	return 0;
+}
+
+int vidioc_enum_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f)
+{
+	if (f->index >= ARRAY_SIZE(formats))
+		return -EINVAL;
+	f->pixelformat = formats[f->index].pixelformat;
+	return 0;
+}
+
+int vidioc_g_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_format *f)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	f->fmt.sdr.pixelformat = dev->sdr_pixelformat;
+	f->fmt.sdr.buffersize = dev->sdr_buffersize;
+	memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
+	return 0;
+}
+
+int vidioc_s_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_format *f)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	struct vb2_queue *q = &dev->vb_sdr_cap_q;
+	int i;
+
+	if (vb2_is_busy(q))
+		return -EBUSY;
+
+	memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
+	for (i = 0; i < ARRAY_SIZE(formats); i++) {
+		if (formats[i].pixelformat == f->fmt.sdr.pixelformat) {
+			dev->sdr_pixelformat = formats[i].pixelformat;
+			dev->sdr_buffersize = formats[i].buffersize;
+			f->fmt.sdr.buffersize = formats[i].buffersize;
+			return 0;
+		}
+	}
+	dev->sdr_pixelformat = formats[0].pixelformat;
+	dev->sdr_buffersize = formats[0].buffersize;
+	f->fmt.sdr.pixelformat = formats[0].pixelformat;
+	f->fmt.sdr.buffersize = formats[0].buffersize;
+	return 0;
+}
+
+int vidioc_try_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_format *f)
+{
+	int i;
+
+	memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
+	for (i = 0; i < ARRAY_SIZE(formats); i++) {
+		if (formats[i].pixelformat == f->fmt.sdr.pixelformat) {
+			f->fmt.sdr.buffersize = formats[i].buffersize;
+			return 0;
+		}
+	}
+	f->fmt.sdr.pixelformat = formats[0].pixelformat;
+	f->fmt.sdr.buffersize = formats[0].buffersize;
+	return 0;
+}
+
+#define FIXP_N    (15)
+#define FIXP_FRAC (1 << FIXP_N)
+#define FIXP_2PI  ((int)(2 * 3.141592653589 * FIXP_FRAC))
+#define M_100000PI (3.14159 * 100000)
+
+void vivid_sdr_cap_process(struct vivid_dev *dev, struct vivid_buffer *buf)
+{
+	u8 *vbuf = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
+	unsigned long i;
+	unsigned long plane_size = vb2_plane_size(&buf->vb.vb2_buf, 0);
+	s64 s64tmp;
+	s32 src_phase_step;
+	s32 mod_phase_step;
+	s32 fixp_i;
+	s32 fixp_q;
+
+	/* calculate phase step */
+	#define BEEP_FREQ 1000 /* 1kHz beep */
+	src_phase_step = DIV_ROUND_CLOSEST(FIXP_2PI * BEEP_FREQ,
+					   dev->sdr_adc_freq);
+
+	for (i = 0; i < plane_size; i += 2) {
+		mod_phase_step = fixp_cos32_rad(dev->sdr_fixp_src_phase,
+						FIXP_2PI) >> (31 - FIXP_N);
+
+		dev->sdr_fixp_src_phase += src_phase_step;
+		s64tmp = (s64) mod_phase_step * dev->sdr_fm_deviation;
+		dev->sdr_fixp_mod_phase += div_s64(s64tmp, M_100000PI);
+
+		/*
+		 * Transfer phase angle to [0, 2xPI] in order to avoid variable
+		 * overflow and make it suitable for cosine implementation
+		 * used, which does not support negative angles.
+		 */
+		dev->sdr_fixp_src_phase %= FIXP_2PI;
+		dev->sdr_fixp_mod_phase %= FIXP_2PI;
+
+		if (dev->sdr_fixp_mod_phase < 0)
+			dev->sdr_fixp_mod_phase += FIXP_2PI;
+
+		fixp_i = fixp_cos32_rad(dev->sdr_fixp_mod_phase, FIXP_2PI);
+		fixp_q = fixp_sin32_rad(dev->sdr_fixp_mod_phase, FIXP_2PI);
+
+		/* Normalize fraction values represented with 32 bit precision
+		 * to fixed point representation with FIXP_N bits */
+		fixp_i >>= (31 - FIXP_N);
+		fixp_q >>= (31 - FIXP_N);
+
+		switch (dev->sdr_pixelformat) {
+		case V4L2_SDR_FMT_CU8:
+			/* convert 'fixp float' to u8 [0, +255] */
+			/* u8 = X * 127.5 + 127.5; X is float [-1.0, +1.0] */
+			fixp_i = fixp_i * 1275 + FIXP_FRAC * 1275;
+			fixp_q = fixp_q * 1275 + FIXP_FRAC * 1275;
+			*vbuf++ = DIV_ROUND_CLOSEST(fixp_i, FIXP_FRAC * 10);
+			*vbuf++ = DIV_ROUND_CLOSEST(fixp_q, FIXP_FRAC * 10);
+			break;
+		case V4L2_SDR_FMT_CS8:
+			/* convert 'fixp float' to s8 [-128, +127] */
+			/* s8 = X * 127.5 - 0.5; X is float [-1.0, +1.0] */
+			fixp_i = fixp_i * 1275 - FIXP_FRAC * 5;
+			fixp_q = fixp_q * 1275 - FIXP_FRAC * 5;
+			*vbuf++ = DIV_ROUND_CLOSEST(fixp_i, FIXP_FRAC * 10);
+			*vbuf++ = DIV_ROUND_CLOSEST(fixp_q, FIXP_FRAC * 10);
+			break;
+		default:
+			break;
+		}
+	}
+}
diff --git a/drivers/media/test-drivers/vivid/vivid-sdr-cap.h b/drivers/media/test-drivers/vivid/vivid-sdr-cap.h
new file mode 100644
index 000000000000..813c9248e5a7
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-sdr-cap.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * vivid-sdr-cap.h - software defined radio support functions.
+ *
+ * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _VIVID_SDR_CAP_H_
+#define _VIVID_SDR_CAP_H_
+
+int vivid_sdr_enum_freq_bands(struct file *file, void *fh, struct v4l2_frequency_band *band);
+int vivid_sdr_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf);
+int vivid_sdr_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *vf);
+int vivid_sdr_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt);
+int vivid_sdr_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt);
+int vidioc_enum_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f);
+int vidioc_g_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_format *f);
+int vidioc_s_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_format *f);
+int vidioc_try_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_format *f);
+void vivid_sdr_cap_process(struct vivid_dev *dev, struct vivid_buffer *buf);
+
+extern const struct vb2_ops vivid_sdr_cap_qops;
+
+#endif
diff --git a/drivers/media/test-drivers/vivid/vivid-touch-cap.c b/drivers/media/test-drivers/vivid/vivid-touch-cap.c
new file mode 100644
index 000000000000..ebb00b128030
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-touch-cap.c
@@ -0,0 +1,341 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * vivid-touch-cap.c - touch support functions.
+ */
+
+#include "vivid-core.h"
+#include "vivid-kthread-touch.h"
+#include "vivid-vid-common.h"
+#include "vivid-touch-cap.h"
+
+static int touch_cap_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
+				 unsigned int *nplanes, unsigned int sizes[],
+				 struct device *alloc_devs[])
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vq);
+	struct v4l2_pix_format *f = &dev->tch_format;
+	unsigned int size = f->sizeimage;
+
+	if (*nplanes) {
+		if (sizes[0] < size)
+			return -EINVAL;
+	} else {
+		sizes[0] = size;
+	}
+
+	if (vq->num_buffers + *nbuffers < 2)
+		*nbuffers = 2 - vq->num_buffers;
+
+	*nplanes = 1;
+	return 0;
+}
+
+static int touch_cap_buf_prepare(struct vb2_buffer *vb)
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
+	struct v4l2_pix_format *f = &dev->tch_format;
+	unsigned int size = f->sizeimage;
+
+	if (dev->buf_prepare_error) {
+		/*
+		 * Error injection: test what happens if buf_prepare() returns
+		 * an error.
+		 */
+		dev->buf_prepare_error = false;
+		return -EINVAL;
+	}
+	if (vb2_plane_size(vb, 0) < size) {
+		dprintk(dev, 1, "%s data will not fit into plane (%lu < %u)\n",
+			__func__, vb2_plane_size(vb, 0), size);
+		return -EINVAL;
+	}
+	vb2_set_plane_payload(vb, 0, size);
+
+	return 0;
+}
+
+static void touch_cap_buf_queue(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
+	struct vivid_buffer *buf = container_of(vbuf, struct vivid_buffer, vb);
+
+	vbuf->field = V4L2_FIELD_NONE;
+	spin_lock(&dev->slock);
+	list_add_tail(&buf->list, &dev->touch_cap_active);
+	spin_unlock(&dev->slock);
+}
+
+static int touch_cap_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vq);
+	int err;
+
+	dev->touch_cap_seq_count = 0;
+	if (dev->start_streaming_error) {
+		dev->start_streaming_error = false;
+		err = -EINVAL;
+	} else {
+		err = vivid_start_generating_touch_cap(dev);
+	}
+	if (err) {
+		struct vivid_buffer *buf, *tmp;
+
+		list_for_each_entry_safe(buf, tmp,
+					 &dev->touch_cap_active, list) {
+			list_del(&buf->list);
+			vb2_buffer_done(&buf->vb.vb2_buf,
+					VB2_BUF_STATE_QUEUED);
+		}
+	}
+	return err;
+}
+
+/* abort streaming and wait for last buffer */
+static void touch_cap_stop_streaming(struct vb2_queue *vq)
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vq);
+
+	vivid_stop_generating_touch_cap(dev);
+}
+
+static void touch_cap_buf_request_complete(struct vb2_buffer *vb)
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
+
+	v4l2_ctrl_request_complete(vb->req_obj.req, &dev->ctrl_hdl_touch_cap);
+}
+
+const struct vb2_ops vivid_touch_cap_qops = {
+	.queue_setup		= touch_cap_queue_setup,
+	.buf_prepare		= touch_cap_buf_prepare,
+	.buf_queue		= touch_cap_buf_queue,
+	.start_streaming	= touch_cap_start_streaming,
+	.stop_streaming		= touch_cap_stop_streaming,
+	.buf_request_complete	= touch_cap_buf_request_complete,
+	.wait_prepare		= vb2_ops_wait_prepare,
+	.wait_finish		= vb2_ops_wait_finish,
+};
+
+int vivid_enum_fmt_tch(struct file *file, void  *priv, struct v4l2_fmtdesc *f)
+{
+	if (f->index)
+		return -EINVAL;
+
+	f->pixelformat = V4L2_TCH_FMT_DELTA_TD16;
+	return 0;
+}
+
+int vivid_g_fmt_tch(struct file *file, void *priv, struct v4l2_format *f)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (dev->multiplanar)
+		return -ENOTTY;
+	f->fmt.pix = dev->tch_format;
+	return 0;
+}
+
+int vivid_g_fmt_tch_mplane(struct file *file, void *priv, struct v4l2_format *f)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	struct v4l2_format sp_fmt;
+
+	if (!dev->multiplanar)
+		return -ENOTTY;
+	sp_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	sp_fmt.fmt.pix = dev->tch_format;
+	fmt_sp2mp(&sp_fmt, f);
+	return 0;
+}
+
+int vivid_g_parm_tch(struct file *file, void *priv,
+		     struct v4l2_streamparm *parm)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (parm->type != (dev->multiplanar ?
+			   V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
+			   V4L2_BUF_TYPE_VIDEO_CAPTURE))
+		return -EINVAL;
+
+	parm->parm.capture.capability   = V4L2_CAP_TIMEPERFRAME;
+	parm->parm.capture.timeperframe = dev->timeperframe_tch_cap;
+	parm->parm.capture.readbuffers  = 1;
+	return 0;
+}
+
+int vivid_enum_input_tch(struct file *file, void *priv, struct v4l2_input *inp)
+{
+	if (inp->index)
+		return -EINVAL;
+
+	inp->type = V4L2_INPUT_TYPE_TOUCH;
+	strscpy(inp->name, "Vivid Touch", sizeof(inp->name));
+	inp->capabilities = 0;
+	return 0;
+}
+
+int vivid_g_input_tch(struct file *file, void *priv, unsigned int *i)
+{
+	*i = 0;
+	return 0;
+}
+
+int vivid_set_touch(struct vivid_dev *dev, unsigned int i)
+{
+	struct v4l2_pix_format *f = &dev->tch_format;
+
+	if (i)
+		return -EINVAL;
+
+	f->pixelformat = V4L2_TCH_FMT_DELTA_TD16;
+	f->width =  VIVID_TCH_WIDTH;
+	f->height = VIVID_TCH_HEIGHT;
+	f->field = V4L2_FIELD_NONE;
+	f->colorspace = V4L2_COLORSPACE_RAW;
+	f->bytesperline = f->width * sizeof(s16);
+	f->sizeimage = f->width * f->height * sizeof(s16);
+	return 0;
+}
+
+int vivid_s_input_tch(struct file *file, void *priv, unsigned int i)
+{
+	return vivid_set_touch(video_drvdata(file), i);
+}
+
+static void vivid_fill_buff_noise(__s16 *tch_buf, int size)
+{
+	int i;
+
+	/* Fill 10% of the values within range -3 and 3, zero the others */
+	for (i = 0; i < size; i++) {
+		unsigned int rand = get_random_int();
+
+		if (rand % 10)
+			tch_buf[i] = 0;
+		else
+			tch_buf[i] = (rand / 10) % 7 - 3;
+	}
+}
+
+static inline int get_random_pressure(void)
+{
+	return get_random_int() % VIVID_PRESSURE_LIMIT;
+}
+
+static void vivid_tch_buf_set(struct v4l2_pix_format *f,
+			      __s16 *tch_buf,
+			      int index)
+{
+	unsigned int x = index % f->width;
+	unsigned int y = index / f->width;
+	unsigned int offset = VIVID_MIN_PRESSURE;
+
+	tch_buf[index] = offset + get_random_pressure();
+	offset /= 2;
+	if (x)
+		tch_buf[index - 1] = offset + get_random_pressure();
+	if (x < f->width - 1)
+		tch_buf[index + 1] = offset + get_random_pressure();
+	if (y)
+		tch_buf[index - f->width] = offset + get_random_pressure();
+	if (y < f->height - 1)
+		tch_buf[index + f->width] = offset + get_random_pressure();
+	offset /= 2;
+	if (x && y)
+		tch_buf[index - 1 - f->width] = offset + get_random_pressure();
+	if (x < f->width - 1 && y)
+		tch_buf[index + 1 - f->width] = offset + get_random_pressure();
+	if (x && y < f->height - 1)
+		tch_buf[index - 1 + f->width] = offset + get_random_pressure();
+	if (x < f->width - 1 && y < f->height - 1)
+		tch_buf[index + 1 + f->width] = offset + get_random_pressure();
+}
+
+void vivid_fillbuff_tch(struct vivid_dev *dev, struct vivid_buffer *buf)
+{
+	struct v4l2_pix_format *f = &dev->tch_format;
+	int size = f->width * f->height;
+	int x, y, xstart, ystart, offset_x, offset_y;
+	unsigned int test_pattern, test_pat_idx, rand;
+
+	__s16 *tch_buf = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
+
+	buf->vb.sequence = dev->touch_cap_seq_count;
+	test_pattern = (buf->vb.sequence / TCH_SEQ_COUNT) % TEST_CASE_MAX;
+	test_pat_idx = buf->vb.sequence % TCH_SEQ_COUNT;
+
+	vivid_fill_buff_noise(tch_buf, size);
+
+	if (test_pat_idx >= TCH_PATTERN_COUNT)
+		return;
+
+	if (test_pat_idx == 0)
+		dev->tch_pat_random = get_random_int();
+	rand = dev->tch_pat_random;
+
+	switch (test_pattern) {
+	case SINGLE_TAP:
+		if (test_pat_idx == 2)
+			vivid_tch_buf_set(f, tch_buf, rand % size);
+		break;
+	case DOUBLE_TAP:
+		if (test_pat_idx == 2 || test_pat_idx == 4)
+			vivid_tch_buf_set(f, tch_buf, rand % size);
+		break;
+	case TRIPLE_TAP:
+		if (test_pat_idx == 2 || test_pat_idx == 4 || test_pat_idx == 6)
+			vivid_tch_buf_set(f, tch_buf, rand % size);
+		break;
+	case MOVE_LEFT_TO_RIGHT:
+		vivid_tch_buf_set(f, tch_buf,
+				  (rand % f->height) * f->width +
+				  test_pat_idx *
+				  (f->width / TCH_PATTERN_COUNT));
+		break;
+	case ZOOM_IN:
+		x = f->width / 2;
+		y = f->height / 2;
+		offset_x = ((TCH_PATTERN_COUNT - 1 - test_pat_idx) * x) /
+				TCH_PATTERN_COUNT;
+		offset_y = ((TCH_PATTERN_COUNT - 1 - test_pat_idx) * y) /
+				TCH_PATTERN_COUNT;
+		vivid_tch_buf_set(f, tch_buf,
+				  (x - offset_x) + f->width * (y - offset_y));
+		vivid_tch_buf_set(f, tch_buf,
+				  (x + offset_x) + f->width * (y + offset_y));
+		break;
+	case ZOOM_OUT:
+		x = f->width / 2;
+		y = f->height / 2;
+		offset_x = (test_pat_idx * x) / TCH_PATTERN_COUNT;
+		offset_y = (test_pat_idx * y) / TCH_PATTERN_COUNT;
+		vivid_tch_buf_set(f, tch_buf,
+				  (x - offset_x) + f->width * (y - offset_y));
+		vivid_tch_buf_set(f, tch_buf,
+				  (x + offset_x) + f->width * (y + offset_y));
+		break;
+	case PALM_PRESS:
+		for (x = 0; x < f->width; x++)
+			for (y = f->height / 2; y < f->height; y++)
+				tch_buf[x + f->width * y] = VIVID_MIN_PRESSURE +
+							get_random_pressure();
+		break;
+	case MULTIPLE_PRESS:
+		/* 16 pressure points */
+		for (y = 0; y < 4; y++) {
+			for (x = 0; x < 4; x++) {
+				ystart = (y * f->height) / 4 + f->height / 8;
+				xstart = (x * f->width) / 4 + f->width / 8;
+				vivid_tch_buf_set(f, tch_buf,
+						  ystart * f->width + xstart);
+			}
+		}
+		break;
+	}
+#ifdef __BIG_ENDIAN__
+	for (x = 0; x < size; x++)
+		tch_buf[x] = (__force s16)__cpu_to_le16((u16)tch_buf[x]);
+#endif
+}
diff --git a/drivers/media/test-drivers/vivid/vivid-touch-cap.h b/drivers/media/test-drivers/vivid/vivid-touch-cap.h
new file mode 100644
index 000000000000..07e514046ae8
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-touch-cap.h
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * vivid-touch-cap.h - touch support functions.
+ */
+#ifndef _VIVID_TOUCH_CAP_H_
+#define _VIVID_TOUCH_CAP_H_
+
+#define VIVID_TCH_HEIGHT	12
+#define VIVID_TCH_WIDTH		21
+#define VIVID_MIN_PRESSURE	180
+#define VIVID_PRESSURE_LIMIT	40
+#define TCH_SEQ_COUNT		16
+#define TCH_PATTERN_COUNT	12
+
+enum vivid_tch_test {
+	SINGLE_TAP,
+	DOUBLE_TAP,
+	TRIPLE_TAP,
+	MOVE_LEFT_TO_RIGHT,
+	ZOOM_IN,
+	ZOOM_OUT,
+	PALM_PRESS,
+	MULTIPLE_PRESS,
+	TEST_CASE_MAX
+};
+
+extern const struct vb2_ops vivid_touch_cap_qops;
+
+int vivid_enum_fmt_tch(struct file *file, void  *priv, struct v4l2_fmtdesc *f);
+int vivid_g_fmt_tch(struct file *file, void *priv, struct v4l2_format *f);
+int vivid_g_fmt_tch_mplane(struct file *file, void *priv, struct v4l2_format *f);
+int vivid_enum_input_tch(struct file *file, void *priv, struct v4l2_input *inp);
+int vivid_g_input_tch(struct file *file, void *priv, unsigned int *i);
+int vivid_s_input_tch(struct file *file, void *priv, unsigned int i);
+void vivid_fillbuff_tch(struct vivid_dev *dev, struct vivid_buffer *buf);
+int vivid_set_touch(struct vivid_dev *dev, unsigned int i);
+int vivid_g_parm_tch(struct file *file, void *priv,
+		     struct v4l2_streamparm *parm);
+#endif
diff --git a/drivers/media/test-drivers/vivid/vivid-vbi-cap.c b/drivers/media/test-drivers/vivid/vivid-vbi-cap.c
new file mode 100644
index 000000000000..1a9348eea781
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-vbi-cap.c
@@ -0,0 +1,365 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * vivid-vbi-cap.c - vbi capture support functions.
+ *
+ * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-common.h>
+
+#include "vivid-core.h"
+#include "vivid-kthread-cap.h"
+#include "vivid-vbi-cap.h"
+#include "vivid-vbi-gen.h"
+
+static void vivid_sliced_vbi_cap_fill(struct vivid_dev *dev, unsigned seqnr)
+{
+	struct vivid_vbi_gen_data *vbi_gen = &dev->vbi_gen;
+	bool is_60hz = dev->std_cap[dev->input] & V4L2_STD_525_60;
+
+	vivid_vbi_gen_sliced(vbi_gen, is_60hz, seqnr);
+
+	if (!is_60hz) {
+		if (dev->loop_video) {
+			if (dev->vbi_out_have_wss) {
+				vbi_gen->data[12].data[0] = dev->vbi_out_wss[0];
+				vbi_gen->data[12].data[1] = dev->vbi_out_wss[1];
+			} else {
+				vbi_gen->data[12].id = 0;
+			}
+		} else {
+			switch (tpg_g_video_aspect(&dev->tpg)) {
+			case TPG_VIDEO_ASPECT_14X9_CENTRE:
+				vbi_gen->data[12].data[0] = 0x01;
+				break;
+			case TPG_VIDEO_ASPECT_16X9_CENTRE:
+				vbi_gen->data[12].data[0] = 0x0b;
+				break;
+			case TPG_VIDEO_ASPECT_16X9_ANAMORPHIC:
+				vbi_gen->data[12].data[0] = 0x07;
+				break;
+			case TPG_VIDEO_ASPECT_4X3:
+			default:
+				vbi_gen->data[12].data[0] = 0x08;
+				break;
+			}
+		}
+	} else if (dev->loop_video && is_60hz) {
+		if (dev->vbi_out_have_cc[0]) {
+			vbi_gen->data[0].data[0] = dev->vbi_out_cc[0][0];
+			vbi_gen->data[0].data[1] = dev->vbi_out_cc[0][1];
+		} else {
+			vbi_gen->data[0].id = 0;
+		}
+		if (dev->vbi_out_have_cc[1]) {
+			vbi_gen->data[1].data[0] = dev->vbi_out_cc[1][0];
+			vbi_gen->data[1].data[1] = dev->vbi_out_cc[1][1];
+		} else {
+			vbi_gen->data[1].id = 0;
+		}
+	}
+}
+
+static void vivid_g_fmt_vbi_cap(struct vivid_dev *dev, struct v4l2_vbi_format *vbi)
+{
+	bool is_60hz = dev->std_cap[dev->input] & V4L2_STD_525_60;
+
+	vbi->sampling_rate = 27000000;
+	vbi->offset = 24;
+	vbi->samples_per_line = 1440;
+	vbi->sample_format = V4L2_PIX_FMT_GREY;
+	vbi->start[0] = is_60hz ? V4L2_VBI_ITU_525_F1_START + 9 : V4L2_VBI_ITU_625_F1_START + 5;
+	vbi->start[1] = is_60hz ? V4L2_VBI_ITU_525_F2_START + 9 : V4L2_VBI_ITU_625_F2_START + 5;
+	vbi->count[0] = vbi->count[1] = is_60hz ? 12 : 18;
+	vbi->flags = dev->vbi_cap_interlaced ? V4L2_VBI_INTERLACED : 0;
+	vbi->reserved[0] = 0;
+	vbi->reserved[1] = 0;
+}
+
+void vivid_raw_vbi_cap_process(struct vivid_dev *dev, struct vivid_buffer *buf)
+{
+	struct v4l2_vbi_format vbi;
+	u8 *vbuf = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
+
+	vivid_g_fmt_vbi_cap(dev, &vbi);
+	buf->vb.sequence = dev->vbi_cap_seq_count;
+	if (dev->field_cap == V4L2_FIELD_ALTERNATE)
+		buf->vb.sequence /= 2;
+
+	vivid_sliced_vbi_cap_fill(dev, buf->vb.sequence);
+
+	memset(vbuf, 0x10, vb2_plane_size(&buf->vb.vb2_buf, 0));
+
+	if (!VIVID_INVALID_SIGNAL(dev->std_signal_mode[dev->input]))
+		vivid_vbi_gen_raw(&dev->vbi_gen, &vbi, vbuf);
+}
+
+
+void vivid_sliced_vbi_cap_process(struct vivid_dev *dev,
+			struct vivid_buffer *buf)
+{
+	struct v4l2_sliced_vbi_data *vbuf =
+			vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
+
+	buf->vb.sequence = dev->vbi_cap_seq_count;
+	if (dev->field_cap == V4L2_FIELD_ALTERNATE)
+		buf->vb.sequence /= 2;
+
+	vivid_sliced_vbi_cap_fill(dev, buf->vb.sequence);
+
+	memset(vbuf, 0, vb2_plane_size(&buf->vb.vb2_buf, 0));
+	if (!VIVID_INVALID_SIGNAL(dev->std_signal_mode[dev->input])) {
+		unsigned i;
+
+		for (i = 0; i < 25; i++)
+			vbuf[i] = dev->vbi_gen.data[i];
+	}
+}
+
+static int vbi_cap_queue_setup(struct vb2_queue *vq,
+		       unsigned *nbuffers, unsigned *nplanes,
+		       unsigned sizes[], struct device *alloc_devs[])
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vq);
+	bool is_60hz = dev->std_cap[dev->input] & V4L2_STD_525_60;
+	unsigned size = vq->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE ?
+		36 * sizeof(struct v4l2_sliced_vbi_data) :
+		1440 * 2 * (is_60hz ? 12 : 18);
+
+	if (!vivid_is_sdtv_cap(dev))
+		return -EINVAL;
+
+	sizes[0] = size;
+
+	if (vq->num_buffers + *nbuffers < 2)
+		*nbuffers = 2 - vq->num_buffers;
+
+	*nplanes = 1;
+	return 0;
+}
+
+static int vbi_cap_buf_prepare(struct vb2_buffer *vb)
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
+	bool is_60hz = dev->std_cap[dev->input] & V4L2_STD_525_60;
+	unsigned size = vb->vb2_queue->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE ?
+		36 * sizeof(struct v4l2_sliced_vbi_data) :
+		1440 * 2 * (is_60hz ? 12 : 18);
+
+	dprintk(dev, 1, "%s\n", __func__);
+
+	if (dev->buf_prepare_error) {
+		/*
+		 * Error injection: test what happens if buf_prepare() returns
+		 * an error.
+		 */
+		dev->buf_prepare_error = false;
+		return -EINVAL;
+	}
+	if (vb2_plane_size(vb, 0) < size) {
+		dprintk(dev, 1, "%s data will not fit into plane (%lu < %u)\n",
+				__func__, vb2_plane_size(vb, 0), size);
+		return -EINVAL;
+	}
+	vb2_set_plane_payload(vb, 0, size);
+
+	return 0;
+}
+
+static void vbi_cap_buf_queue(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
+	struct vivid_buffer *buf = container_of(vbuf, struct vivid_buffer, vb);
+
+	dprintk(dev, 1, "%s\n", __func__);
+
+	spin_lock(&dev->slock);
+	list_add_tail(&buf->list, &dev->vbi_cap_active);
+	spin_unlock(&dev->slock);
+}
+
+static int vbi_cap_start_streaming(struct vb2_queue *vq, unsigned count)
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vq);
+	int err;
+
+	dprintk(dev, 1, "%s\n", __func__);
+	dev->vbi_cap_seq_count = 0;
+	if (dev->start_streaming_error) {
+		dev->start_streaming_error = false;
+		err = -EINVAL;
+	} else {
+		err = vivid_start_generating_vid_cap(dev, &dev->vbi_cap_streaming);
+	}
+	if (err) {
+		struct vivid_buffer *buf, *tmp;
+
+		list_for_each_entry_safe(buf, tmp, &dev->vbi_cap_active, list) {
+			list_del(&buf->list);
+			vb2_buffer_done(&buf->vb.vb2_buf,
+					VB2_BUF_STATE_QUEUED);
+		}
+	}
+	return err;
+}
+
+/* abort streaming and wait for last buffer */
+static void vbi_cap_stop_streaming(struct vb2_queue *vq)
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vq);
+
+	dprintk(dev, 1, "%s\n", __func__);
+	vivid_stop_generating_vid_cap(dev, &dev->vbi_cap_streaming);
+}
+
+static void vbi_cap_buf_request_complete(struct vb2_buffer *vb)
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
+
+	v4l2_ctrl_request_complete(vb->req_obj.req, &dev->ctrl_hdl_vbi_cap);
+}
+
+const struct vb2_ops vivid_vbi_cap_qops = {
+	.queue_setup		= vbi_cap_queue_setup,
+	.buf_prepare		= vbi_cap_buf_prepare,
+	.buf_queue		= vbi_cap_buf_queue,
+	.start_streaming	= vbi_cap_start_streaming,
+	.stop_streaming		= vbi_cap_stop_streaming,
+	.buf_request_complete	= vbi_cap_buf_request_complete,
+	.wait_prepare		= vb2_ops_wait_prepare,
+	.wait_finish		= vb2_ops_wait_finish,
+};
+
+int vidioc_g_fmt_vbi_cap(struct file *file, void *priv,
+					struct v4l2_format *f)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	struct v4l2_vbi_format *vbi = &f->fmt.vbi;
+
+	if (!vivid_is_sdtv_cap(dev) || !dev->has_raw_vbi_cap)
+		return -EINVAL;
+
+	vivid_g_fmt_vbi_cap(dev, vbi);
+	return 0;
+}
+
+int vidioc_s_fmt_vbi_cap(struct file *file, void *priv,
+					struct v4l2_format *f)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	int ret = vidioc_g_fmt_vbi_cap(file, priv, f);
+
+	if (ret)
+		return ret;
+	if (dev->stream_sliced_vbi_cap && vb2_is_busy(&dev->vb_vbi_cap_q))
+		return -EBUSY;
+	dev->stream_sliced_vbi_cap = false;
+	dev->vbi_cap_dev.queue->type = V4L2_BUF_TYPE_VBI_CAPTURE;
+	return 0;
+}
+
+void vivid_fill_service_lines(struct v4l2_sliced_vbi_format *vbi, u32 service_set)
+{
+	vbi->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
+	vbi->service_set = service_set;
+	memset(vbi->service_lines, 0, sizeof(vbi->service_lines));
+	memset(vbi->reserved, 0, sizeof(vbi->reserved));
+
+	if (vbi->service_set == 0)
+		return;
+
+	if (vbi->service_set & V4L2_SLICED_CAPTION_525) {
+		vbi->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
+		vbi->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
+	}
+	if (vbi->service_set & V4L2_SLICED_WSS_625) {
+		unsigned i;
+
+		for (i = 7; i <= 18; i++)
+			vbi->service_lines[0][i] =
+			vbi->service_lines[1][i] = V4L2_SLICED_TELETEXT_B;
+		vbi->service_lines[0][23] = V4L2_SLICED_WSS_625;
+	}
+}
+
+int vidioc_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	struct v4l2_sliced_vbi_format *vbi = &fmt->fmt.sliced;
+
+	if (!vivid_is_sdtv_cap(dev) || !dev->has_sliced_vbi_cap)
+		return -EINVAL;
+
+	vivid_fill_service_lines(vbi, dev->service_set_cap);
+	return 0;
+}
+
+int vidioc_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	struct v4l2_sliced_vbi_format *vbi = &fmt->fmt.sliced;
+	bool is_60hz = dev->std_cap[dev->input] & V4L2_STD_525_60;
+	u32 service_set = vbi->service_set;
+
+	if (!vivid_is_sdtv_cap(dev) || !dev->has_sliced_vbi_cap)
+		return -EINVAL;
+
+	service_set &= is_60hz ? V4L2_SLICED_CAPTION_525 :
+				 V4L2_SLICED_WSS_625 | V4L2_SLICED_TELETEXT_B;
+	vivid_fill_service_lines(vbi, service_set);
+	return 0;
+}
+
+int vidioc_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	struct v4l2_sliced_vbi_format *vbi = &fmt->fmt.sliced;
+	int ret = vidioc_try_fmt_sliced_vbi_cap(file, fh, fmt);
+
+	if (ret)
+		return ret;
+	if (!dev->stream_sliced_vbi_cap && vb2_is_busy(&dev->vb_vbi_cap_q))
+		return -EBUSY;
+	dev->service_set_cap = vbi->service_set;
+	dev->stream_sliced_vbi_cap = true;
+	dev->vbi_cap_dev.queue->type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
+	return 0;
+}
+
+int vidioc_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced_vbi_cap *cap)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	struct video_device *vdev = video_devdata(file);
+	bool is_60hz;
+
+	if (vdev->vfl_dir == VFL_DIR_RX) {
+		is_60hz = dev->std_cap[dev->input] & V4L2_STD_525_60;
+		if (!vivid_is_sdtv_cap(dev) || !dev->has_sliced_vbi_cap ||
+		    cap->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
+			return -EINVAL;
+	} else {
+		is_60hz = dev->std_out & V4L2_STD_525_60;
+		if (!vivid_is_svid_out(dev) || !dev->has_sliced_vbi_out ||
+		    cap->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT)
+			return -EINVAL;
+	}
+
+	cap->service_set = is_60hz ? V4L2_SLICED_CAPTION_525 :
+				     V4L2_SLICED_WSS_625 | V4L2_SLICED_TELETEXT_B;
+	if (is_60hz) {
+		cap->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
+		cap->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
+	} else {
+		unsigned i;
+
+		for (i = 7; i <= 18; i++)
+			cap->service_lines[0][i] =
+			cap->service_lines[1][i] = V4L2_SLICED_TELETEXT_B;
+		cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
+	}
+	return 0;
+}
diff --git a/drivers/media/test-drivers/vivid/vivid-vbi-cap.h b/drivers/media/test-drivers/vivid/vivid-vbi-cap.h
new file mode 100644
index 000000000000..91d2de01381c
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-vbi-cap.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * vivid-vbi-cap.h - vbi capture support functions.
+ *
+ * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _VIVID_VBI_CAP_H_
+#define _VIVID_VBI_CAP_H_
+
+void vivid_fill_time_of_day_packet(u8 *packet);
+void vivid_raw_vbi_cap_process(struct vivid_dev *dev, struct vivid_buffer *buf);
+void vivid_sliced_vbi_cap_process(struct vivid_dev *dev, struct vivid_buffer *buf);
+void vivid_sliced_vbi_out_process(struct vivid_dev *dev, struct vivid_buffer *buf);
+int vidioc_g_fmt_vbi_cap(struct file *file, void *priv,
+					struct v4l2_format *f);
+int vidioc_s_fmt_vbi_cap(struct file *file, void *priv,
+					struct v4l2_format *f);
+int vidioc_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt);
+int vidioc_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt);
+int vidioc_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt);
+int vidioc_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced_vbi_cap *cap);
+
+void vivid_fill_service_lines(struct v4l2_sliced_vbi_format *vbi, u32 service_set);
+
+extern const struct vb2_ops vivid_vbi_cap_qops;
+
+#endif
diff --git a/drivers/media/test-drivers/vivid/vivid-vbi-gen.c b/drivers/media/test-drivers/vivid/vivid-vbi-gen.c
new file mode 100644
index 000000000000..acc98445a1fa
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-vbi-gen.c
@@ -0,0 +1,311 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * vivid-vbi-gen.c - vbi generator support functions.
+ *
+ * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/ktime.h>
+#include <linux/string.h>
+#include <linux/videodev2.h>
+
+#include "vivid-vbi-gen.h"
+
+static void wss_insert(u8 *wss, u32 val, unsigned size)
+{
+	while (size--)
+		*wss++ = (val & (1 << size)) ? 0xc0 : 0x10;
+}
+
+static void vivid_vbi_gen_wss_raw(const struct v4l2_sliced_vbi_data *data,
+		u8 *buf, unsigned sampling_rate)
+{
+	const unsigned rate = 5000000;	/* WSS has a 5 MHz transmission rate */
+	u8 wss[29 + 24 + 24 + 24 + 18 + 18] = { 0 };
+	const unsigned zero = 0x07;
+	const unsigned one = 0x38;
+	unsigned bit = 0;
+	u16 wss_data;
+	int i;
+
+	wss_insert(wss + bit, 0x1f1c71c7, 29); bit += 29;
+	wss_insert(wss + bit, 0x1e3c1f, 24); bit += 24;
+
+	wss_data = (data->data[1] << 8) | data->data[0];
+	for (i = 0; i <= 13; i++, bit += 6)
+		wss_insert(wss + bit, (wss_data & (1 << i)) ? one : zero, 6);
+
+	for (i = 0, bit = 0; bit < sizeof(wss); bit++) {
+		unsigned n = ((bit + 1) * sampling_rate) / rate;
+
+		while (i < n)
+			buf[i++] = wss[bit];
+	}
+}
+
+static void vivid_vbi_gen_teletext_raw(const struct v4l2_sliced_vbi_data *data,
+		u8 *buf, unsigned sampling_rate)
+{
+	const unsigned rate = 6937500 / 10;	/* Teletext has a 6.9375 MHz transmission rate */
+	u8 teletext[45] = { 0x55, 0x55, 0x27 };
+	unsigned bit = 0;
+	int i;
+
+	memcpy(teletext + 3, data->data, sizeof(teletext) - 3);
+	/* prevents 32 bit overflow */
+	sampling_rate /= 10;
+
+	for (i = 0, bit = 0; bit < sizeof(teletext) * 8; bit++) {
+		unsigned n = ((bit + 1) * sampling_rate) / rate;
+		u8 val = (teletext[bit / 8] & (1 << (bit & 7))) ? 0xc0 : 0x10;
+
+		while (i < n)
+			buf[i++] = val;
+	}
+}
+
+static void cc_insert(u8 *cc, u8 ch)
+{
+	unsigned tot = 0;
+	unsigned i;
+
+	for (i = 0; i < 7; i++) {
+		cc[2 * i] = cc[2 * i + 1] = (ch & (1 << i)) ? 1 : 0;
+		tot += cc[2 * i];
+	}
+	cc[14] = cc[15] = !(tot & 1);
+}
+
+#define CC_PREAMBLE_BITS (14 + 4 + 2)
+
+static void vivid_vbi_gen_cc_raw(const struct v4l2_sliced_vbi_data *data,
+		u8 *buf, unsigned sampling_rate)
+{
+	const unsigned rate = 1000000;	/* CC has a 1 MHz transmission rate */
+
+	u8 cc[CC_PREAMBLE_BITS + 2 * 16] = {
+		/* Clock run-in: 7 cycles */
+		0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
+		/* 2 cycles of 0 */
+		0, 0, 0, 0,
+		/* Start bit of 1 (each bit is two cycles) */
+		1, 1
+	};
+	unsigned bit, i;
+
+	cc_insert(cc + CC_PREAMBLE_BITS, data->data[0]);
+	cc_insert(cc + CC_PREAMBLE_BITS + 16, data->data[1]);
+
+	for (i = 0, bit = 0; bit < sizeof(cc); bit++) {
+		unsigned n = ((bit + 1) * sampling_rate) / rate;
+
+		while (i < n)
+			buf[i++] = cc[bit] ? 0xc0 : 0x10;
+	}
+}
+
+void vivid_vbi_gen_raw(const struct vivid_vbi_gen_data *vbi,
+		const struct v4l2_vbi_format *vbi_fmt, u8 *buf)
+{
+	unsigned idx;
+
+	for (idx = 0; idx < 25; idx++) {
+		const struct v4l2_sliced_vbi_data *data = vbi->data + idx;
+		unsigned start_2nd_field;
+		unsigned line = data->line;
+		u8 *linebuf = buf;
+
+		start_2nd_field = (data->id & V4L2_SLICED_VBI_525) ? 263 : 313;
+		if (data->field)
+			line += start_2nd_field;
+		line -= vbi_fmt->start[data->field];
+
+		if (vbi_fmt->flags & V4L2_VBI_INTERLACED)
+			linebuf += (line * 2 + data->field) *
+				vbi_fmt->samples_per_line;
+		else
+			linebuf += (line + data->field * vbi_fmt->count[0]) *
+				vbi_fmt->samples_per_line;
+		if (data->id == V4L2_SLICED_CAPTION_525)
+			vivid_vbi_gen_cc_raw(data, linebuf, vbi_fmt->sampling_rate);
+		else if (data->id == V4L2_SLICED_WSS_625)
+			vivid_vbi_gen_wss_raw(data, linebuf, vbi_fmt->sampling_rate);
+		else if (data->id == V4L2_SLICED_TELETEXT_B)
+			vivid_vbi_gen_teletext_raw(data, linebuf, vbi_fmt->sampling_rate);
+	}
+}
+
+static const u8 vivid_cc_sequence1[30] = {
+	0x14, 0x20,	/* Resume Caption Loading */
+	'H',  'e',
+	'l',  'l',
+	'o',  ' ',
+	'w',  'o',
+	'r',  'l',
+	'd',  '!',
+	0x14, 0x2f,	/* End of Caption */
+};
+
+static const u8 vivid_cc_sequence2[30] = {
+	0x14, 0x20,	/* Resume Caption Loading */
+	'C',  'l',
+	'o',  's',
+	'e',  'd',
+	' ',  'c',
+	'a',  'p',
+	't',  'i',
+	'o',  'n',
+	's',  ' ',
+	't',  'e',
+	's',  't',
+	0x14, 0x2f,	/* End of Caption */
+};
+
+static u8 calc_parity(u8 val)
+{
+	unsigned i;
+	unsigned tot = 0;
+
+	for (i = 0; i < 7; i++)
+		tot += (val & (1 << i)) ? 1 : 0;
+	return val | ((tot & 1) ? 0 : 0x80);
+}
+
+static void vivid_vbi_gen_set_time_of_day(u8 *packet)
+{
+	struct tm tm;
+	u8 checksum, i;
+
+	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);
+	packet[3] = calc_parity(0x40 | tm.tm_hour);
+	packet[4] = calc_parity(0x40 | tm.tm_mday);
+	if (tm.tm_mday == 1 && tm.tm_mon == 2 &&
+	    sys_tz.tz_minuteswest > tm.tm_min + tm.tm_hour * 60)
+		packet[4] = calc_parity(0x60 | tm.tm_mday);
+	packet[5] = calc_parity(0x40 | (1 + tm.tm_mon));
+	packet[6] = calc_parity(0x40 | (1 + tm.tm_wday));
+	packet[7] = calc_parity(0x40 | ((tm.tm_year - 90) & 0x3f));
+	packet[8] = calc_parity(0x0f);
+	for (checksum = i = 0; i <= 8; i++)
+		checksum += packet[i] & 0x7f;
+	packet[9] = calc_parity(0x100 - checksum);
+	checksum = 0;
+	packet[10] = calc_parity(0x07);
+	packet[11] = calc_parity(0x04);
+	if (sys_tz.tz_minuteswest >= 0)
+		packet[12] = calc_parity(0x40 | ((sys_tz.tz_minuteswest / 60) & 0x1f));
+	else
+		packet[12] = calc_parity(0x40 | ((24 + sys_tz.tz_minuteswest / 60) & 0x1f));
+	packet[13] = calc_parity(0);
+	packet[14] = calc_parity(0x0f);
+	for (checksum = 0, i = 10; i <= 14; i++)
+		checksum += packet[i] & 0x7f;
+	packet[15] = calc_parity(0x100 - checksum);
+}
+
+static const u8 hamming[16] = {
+	0x15, 0x02, 0x49, 0x5e, 0x64, 0x73, 0x38, 0x2f,
+	0xd0, 0xc7, 0x8c, 0x9b, 0xa1, 0xb6, 0xfd, 0xea
+};
+
+static void vivid_vbi_gen_teletext(u8 *packet, unsigned line, unsigned frame)
+{
+	unsigned offset = 2;
+	unsigned i;
+
+	packet[0] = hamming[1 + ((line & 1) << 3)];
+	packet[1] = hamming[line >> 1];
+	memset(packet + 2, 0x20, 40);
+	if (line == 0) {
+		/* subcode */
+		packet[2] = hamming[frame % 10];
+		packet[3] = hamming[frame / 10];
+		packet[4] = hamming[0];
+		packet[5] = hamming[0];
+		packet[6] = hamming[0];
+		packet[7] = hamming[0];
+		packet[8] = hamming[0];
+		packet[9] = hamming[1];
+		offset = 10;
+	}
+	packet += offset;
+	memcpy(packet, "Page: 100 Row: 10", 17);
+	packet[7] = '0' + frame / 10;
+	packet[8] = '0' + frame % 10;
+	packet[15] = '0' + line / 10;
+	packet[16] = '0' + line % 10;
+	for (i = 0; i < 42 - offset; i++)
+		packet[i] = calc_parity(packet[i]);
+}
+
+void vivid_vbi_gen_sliced(struct vivid_vbi_gen_data *vbi,
+		bool is_60hz, unsigned seqnr)
+{
+	struct v4l2_sliced_vbi_data *data0 = vbi->data;
+	struct v4l2_sliced_vbi_data *data1 = vbi->data + 1;
+	unsigned frame = seqnr % 60;
+
+	memset(vbi->data, 0, sizeof(vbi->data));
+
+	if (!is_60hz) {
+		unsigned i;
+
+		for (i = 0; i <= 11; i++) {
+			data0->id = V4L2_SLICED_TELETEXT_B;
+			data0->line = 7 + i;
+			vivid_vbi_gen_teletext(data0->data, i, frame);
+			data0++;
+		}
+		data0->id = V4L2_SLICED_WSS_625;
+		data0->line = 23;
+		/* 4x3 video aspect ratio */
+		data0->data[0] = 0x08;
+		data0++;
+		for (i = 0; i <= 11; i++) {
+			data0->id = V4L2_SLICED_TELETEXT_B;
+			data0->field = 1;
+			data0->line = 7 + i;
+			vivid_vbi_gen_teletext(data0->data, 12 + i, frame);
+			data0++;
+		}
+		return;
+	}
+
+	data0->id = V4L2_SLICED_CAPTION_525;
+	data0->line = 21;
+	data1->id = V4L2_SLICED_CAPTION_525;
+	data1->field = 1;
+	data1->line = 21;
+
+	if (frame < 15) {
+		data0->data[0] = calc_parity(vivid_cc_sequence1[2 * frame]);
+		data0->data[1] = calc_parity(vivid_cc_sequence1[2 * frame + 1]);
+	} else if (frame >= 30 && frame < 45) {
+		frame -= 30;
+		data0->data[0] = calc_parity(vivid_cc_sequence2[2 * frame]);
+		data0->data[1] = calc_parity(vivid_cc_sequence2[2 * frame + 1]);
+	} else {
+		data0->data[0] = calc_parity(0);
+		data0->data[1] = calc_parity(0);
+	}
+
+	frame = seqnr % (30 * 60);
+	switch (frame) {
+	case 0:
+		vivid_vbi_gen_set_time_of_day(vbi->time_of_day_packet);
+		/* fall through */
+	case 1 ... 7:
+		data1->data[0] = vbi->time_of_day_packet[frame * 2];
+		data1->data[1] = vbi->time_of_day_packet[frame * 2 + 1];
+		break;
+	default:
+		data1->data[0] = calc_parity(0);
+		data1->data[1] = calc_parity(0);
+		break;
+	}
+}
diff --git a/drivers/media/test-drivers/vivid/vivid-vbi-gen.h b/drivers/media/test-drivers/vivid/vivid-vbi-gen.h
new file mode 100644
index 000000000000..2657a7f5571c
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-vbi-gen.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * vivid-vbi-gen.h - vbi generator support functions.
+ *
+ * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _VIVID_VBI_GEN_H_
+#define _VIVID_VBI_GEN_H_
+
+struct vivid_vbi_gen_data {
+	struct v4l2_sliced_vbi_data data[25];
+	u8 time_of_day_packet[16];
+};
+
+void vivid_vbi_gen_sliced(struct vivid_vbi_gen_data *vbi,
+		bool is_60hz, unsigned seqnr);
+void vivid_vbi_gen_raw(const struct vivid_vbi_gen_data *vbi,
+		const struct v4l2_vbi_format *vbi_fmt, u8 *buf);
+
+#endif
diff --git a/drivers/media/test-drivers/vivid/vivid-vbi-out.c b/drivers/media/test-drivers/vivid/vivid-vbi-out.c
new file mode 100644
index 000000000000..cd56476902a2
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-vbi-out.c
@@ -0,0 +1,250 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * vivid-vbi-out.c - vbi output support functions.
+ *
+ * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-common.h>
+
+#include "vivid-core.h"
+#include "vivid-kthread-out.h"
+#include "vivid-vbi-out.h"
+#include "vivid-vbi-cap.h"
+
+static int vbi_out_queue_setup(struct vb2_queue *vq,
+		       unsigned *nbuffers, unsigned *nplanes,
+		       unsigned sizes[], struct device *alloc_devs[])
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vq);
+	bool is_60hz = dev->std_out & V4L2_STD_525_60;
+	unsigned size = vq->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT ?
+		36 * sizeof(struct v4l2_sliced_vbi_data) :
+		1440 * 2 * (is_60hz ? 12 : 18);
+
+	if (!vivid_is_svid_out(dev))
+		return -EINVAL;
+
+	sizes[0] = size;
+
+	if (vq->num_buffers + *nbuffers < 2)
+		*nbuffers = 2 - vq->num_buffers;
+
+	*nplanes = 1;
+	return 0;
+}
+
+static int vbi_out_buf_prepare(struct vb2_buffer *vb)
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
+	bool is_60hz = dev->std_out & V4L2_STD_525_60;
+	unsigned size = vb->vb2_queue->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT ?
+		36 * sizeof(struct v4l2_sliced_vbi_data) :
+		1440 * 2 * (is_60hz ? 12 : 18);
+
+	dprintk(dev, 1, "%s\n", __func__);
+
+	if (dev->buf_prepare_error) {
+		/*
+		 * Error injection: test what happens if buf_prepare() returns
+		 * an error.
+		 */
+		dev->buf_prepare_error = false;
+		return -EINVAL;
+	}
+	if (vb2_plane_size(vb, 0) < size) {
+		dprintk(dev, 1, "%s data will not fit into plane (%lu < %u)\n",
+				__func__, vb2_plane_size(vb, 0), size);
+		return -EINVAL;
+	}
+	vb2_set_plane_payload(vb, 0, size);
+
+	return 0;
+}
+
+static void vbi_out_buf_queue(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
+	struct vivid_buffer *buf = container_of(vbuf, struct vivid_buffer, vb);
+
+	dprintk(dev, 1, "%s\n", __func__);
+
+	spin_lock(&dev->slock);
+	list_add_tail(&buf->list, &dev->vbi_out_active);
+	spin_unlock(&dev->slock);
+}
+
+static int vbi_out_start_streaming(struct vb2_queue *vq, unsigned count)
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vq);
+	int err;
+
+	dprintk(dev, 1, "%s\n", __func__);
+	dev->vbi_out_seq_count = 0;
+	if (dev->start_streaming_error) {
+		dev->start_streaming_error = false;
+		err = -EINVAL;
+	} else {
+		err = vivid_start_generating_vid_out(dev, &dev->vbi_out_streaming);
+	}
+	if (err) {
+		struct vivid_buffer *buf, *tmp;
+
+		list_for_each_entry_safe(buf, tmp, &dev->vbi_out_active, list) {
+			list_del(&buf->list);
+			vb2_buffer_done(&buf->vb.vb2_buf,
+					VB2_BUF_STATE_QUEUED);
+		}
+	}
+	return err;
+}
+
+/* abort streaming and wait for last buffer */
+static void vbi_out_stop_streaming(struct vb2_queue *vq)
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vq);
+
+	dprintk(dev, 1, "%s\n", __func__);
+	vivid_stop_generating_vid_out(dev, &dev->vbi_out_streaming);
+	dev->vbi_out_have_wss = false;
+	dev->vbi_out_have_cc[0] = false;
+	dev->vbi_out_have_cc[1] = false;
+}
+
+static void vbi_out_buf_request_complete(struct vb2_buffer *vb)
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
+
+	v4l2_ctrl_request_complete(vb->req_obj.req, &dev->ctrl_hdl_vbi_out);
+}
+
+const struct vb2_ops vivid_vbi_out_qops = {
+	.queue_setup		= vbi_out_queue_setup,
+	.buf_prepare		= vbi_out_buf_prepare,
+	.buf_queue		= vbi_out_buf_queue,
+	.start_streaming	= vbi_out_start_streaming,
+	.stop_streaming		= vbi_out_stop_streaming,
+	.buf_request_complete	= vbi_out_buf_request_complete,
+	.wait_prepare		= vb2_ops_wait_prepare,
+	.wait_finish		= vb2_ops_wait_finish,
+};
+
+int vidioc_g_fmt_vbi_out(struct file *file, void *priv,
+					struct v4l2_format *f)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	struct v4l2_vbi_format *vbi = &f->fmt.vbi;
+	bool is_60hz = dev->std_out & V4L2_STD_525_60;
+
+	if (!vivid_is_svid_out(dev) || !dev->has_raw_vbi_out)
+		return -EINVAL;
+
+	vbi->sampling_rate = 25000000;
+	vbi->offset = 24;
+	vbi->samples_per_line = 1440;
+	vbi->sample_format = V4L2_PIX_FMT_GREY;
+	vbi->start[0] = is_60hz ? V4L2_VBI_ITU_525_F1_START + 9 : V4L2_VBI_ITU_625_F1_START + 5;
+	vbi->start[1] = is_60hz ? V4L2_VBI_ITU_525_F2_START + 9 : V4L2_VBI_ITU_625_F2_START + 5;
+	vbi->count[0] = vbi->count[1] = is_60hz ? 12 : 18;
+	vbi->flags = dev->vbi_cap_interlaced ? V4L2_VBI_INTERLACED : 0;
+	vbi->reserved[0] = 0;
+	vbi->reserved[1] = 0;
+	return 0;
+}
+
+int vidioc_s_fmt_vbi_out(struct file *file, void *priv,
+					struct v4l2_format *f)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	int ret = vidioc_g_fmt_vbi_out(file, priv, f);
+
+	if (ret)
+		return ret;
+	if (vb2_is_busy(&dev->vb_vbi_out_q))
+		return -EBUSY;
+	dev->stream_sliced_vbi_out = false;
+	dev->vbi_out_dev.queue->type = V4L2_BUF_TYPE_VBI_OUTPUT;
+	return 0;
+}
+
+int vidioc_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	struct v4l2_sliced_vbi_format *vbi = &fmt->fmt.sliced;
+
+	if (!vivid_is_svid_out(dev) || !dev->has_sliced_vbi_out)
+		return -EINVAL;
+
+	vivid_fill_service_lines(vbi, dev->service_set_out);
+	return 0;
+}
+
+int vidioc_try_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	struct v4l2_sliced_vbi_format *vbi = &fmt->fmt.sliced;
+	bool is_60hz = dev->std_out & V4L2_STD_525_60;
+	u32 service_set = vbi->service_set;
+
+	if (!vivid_is_svid_out(dev) || !dev->has_sliced_vbi_out)
+		return -EINVAL;
+
+	service_set &= is_60hz ? V4L2_SLICED_CAPTION_525 :
+				 V4L2_SLICED_WSS_625 | V4L2_SLICED_TELETEXT_B;
+	vivid_fill_service_lines(vbi, service_set);
+	return 0;
+}
+
+int vidioc_s_fmt_sliced_vbi_out(struct file *file, void *fh,
+		struct v4l2_format *fmt)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	struct v4l2_sliced_vbi_format *vbi = &fmt->fmt.sliced;
+	int ret = vidioc_try_fmt_sliced_vbi_out(file, fh, fmt);
+
+	if (ret)
+		return ret;
+	if (vb2_is_busy(&dev->vb_vbi_out_q))
+		return -EBUSY;
+	dev->service_set_out = vbi->service_set;
+	dev->stream_sliced_vbi_out = true;
+	dev->vbi_out_dev.queue->type = V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
+	return 0;
+}
+
+void vivid_sliced_vbi_out_process(struct vivid_dev *dev,
+		struct vivid_buffer *buf)
+{
+	struct v4l2_sliced_vbi_data *vbi =
+		vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
+	unsigned elems =
+		vb2_get_plane_payload(&buf->vb.vb2_buf, 0) / sizeof(*vbi);
+
+	dev->vbi_out_have_cc[0] = false;
+	dev->vbi_out_have_cc[1] = false;
+	dev->vbi_out_have_wss = false;
+	while (elems--) {
+		switch (vbi->id) {
+		case V4L2_SLICED_CAPTION_525:
+			if ((dev->std_out & V4L2_STD_525_60) && vbi->line == 21) {
+				dev->vbi_out_have_cc[!!vbi->field] = true;
+				dev->vbi_out_cc[!!vbi->field][0] = vbi->data[0];
+				dev->vbi_out_cc[!!vbi->field][1] = vbi->data[1];
+			}
+			break;
+		case V4L2_SLICED_WSS_625:
+			if ((dev->std_out & V4L2_STD_625_50) &&
+			    vbi->field == 0 && vbi->line == 23) {
+				dev->vbi_out_have_wss = true;
+				dev->vbi_out_wss[0] = vbi->data[0];
+				dev->vbi_out_wss[1] = vbi->data[1];
+			}
+			break;
+		}
+		vbi++;
+	}
+}
diff --git a/drivers/media/test-drivers/vivid/vivid-vbi-out.h b/drivers/media/test-drivers/vivid/vivid-vbi-out.h
new file mode 100644
index 000000000000..76584940cdaf
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-vbi-out.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * vivid-vbi-out.h - vbi output support functions.
+ *
+ * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _VIVID_VBI_OUT_H_
+#define _VIVID_VBI_OUT_H_
+
+void vivid_sliced_vbi_out_process(struct vivid_dev *dev, struct vivid_buffer *buf);
+int vidioc_g_fmt_vbi_out(struct file *file, void *priv,
+					struct v4l2_format *f);
+int vidioc_s_fmt_vbi_out(struct file *file, void *priv,
+					struct v4l2_format *f);
+int vidioc_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt);
+int vidioc_try_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt);
+int vidioc_s_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt);
+
+extern const struct vb2_ops vivid_vbi_out_qops;
+
+#endif
diff --git a/drivers/media/test-drivers/vivid/vivid-vid-cap.c b/drivers/media/test-drivers/vivid/vivid-vid-cap.c
new file mode 100644
index 000000000000..e94beef008c8
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-vid-cap.c
@@ -0,0 +1,1918 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * vivid-vid-cap.c - video capture support functions.
+ *
+ * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/vmalloc.h>
+#include <linux/videodev2.h>
+#include <linux/v4l2-dv-timings.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-dv-timings.h>
+#include <media/v4l2-rect.h>
+
+#include "vivid-core.h"
+#include "vivid-vid-common.h"
+#include "vivid-kthread-cap.h"
+#include "vivid-vid-cap.h"
+
+static const struct vivid_fmt formats_ovl[] = {
+	{
+		.fourcc   = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_XRGB555, /* gggbbbbb arrrrrgg */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_ARGB555, /* gggbbbbb arrrrrgg */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+};
+
+/* The number of discrete webcam framesizes */
+#define VIVID_WEBCAM_SIZES 6
+/* The number of discrete webcam frameintervals */
+#define VIVID_WEBCAM_IVALS (VIVID_WEBCAM_SIZES * 2)
+
+/* Sizes must be in increasing order */
+static const struct v4l2_frmsize_discrete webcam_sizes[VIVID_WEBCAM_SIZES] = {
+	{  320, 180 },
+	{  640, 360 },
+	{  640, 480 },
+	{ 1280, 720 },
+	{ 1920, 1080 },
+	{ 3840, 2160 },
+};
+
+/*
+ * Intervals must be in increasing order and there must be twice as many
+ * elements in this array as there are in webcam_sizes.
+ */
+static const struct v4l2_fract webcam_intervals[VIVID_WEBCAM_IVALS] = {
+	{  1, 1 },
+	{  1, 2 },
+	{  1, 4 },
+	{  1, 5 },
+	{  1, 10 },
+	{  2, 25 },
+	{  1, 15 },
+	{  1, 25 },
+	{  1, 30 },
+	{  1, 40 },
+	{  1, 50 },
+	{  1, 60 },
+};
+
+static int vid_cap_queue_setup(struct vb2_queue *vq,
+		       unsigned *nbuffers, unsigned *nplanes,
+		       unsigned sizes[], struct device *alloc_devs[])
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vq);
+	unsigned buffers = tpg_g_buffers(&dev->tpg);
+	unsigned h = dev->fmt_cap_rect.height;
+	unsigned p;
+
+	if (dev->field_cap == V4L2_FIELD_ALTERNATE) {
+		/*
+		 * You cannot use read() with FIELD_ALTERNATE since the field
+		 * information (TOP/BOTTOM) cannot be passed back to the user.
+		 */
+		if (vb2_fileio_is_active(vq))
+			return -EINVAL;
+	}
+
+	if (dev->queue_setup_error) {
+		/*
+		 * Error injection: test what happens if queue_setup() returns
+		 * an error.
+		 */
+		dev->queue_setup_error = false;
+		return -EINVAL;
+	}
+	if (*nplanes) {
+		/*
+		 * Check if the number of requested planes match
+		 * the number of buffers in the current format. You can't mix that.
+		 */
+		if (*nplanes != buffers)
+			return -EINVAL;
+		for (p = 0; p < buffers; p++) {
+			if (sizes[p] < tpg_g_line_width(&dev->tpg, p) * h +
+						dev->fmt_cap->data_offset[p])
+				return -EINVAL;
+		}
+	} else {
+		for (p = 0; p < buffers; p++)
+			sizes[p] = (tpg_g_line_width(&dev->tpg, p) * h) /
+					dev->fmt_cap->vdownsampling[p] +
+					dev->fmt_cap->data_offset[p];
+	}
+
+	if (vq->num_buffers + *nbuffers < 2)
+		*nbuffers = 2 - vq->num_buffers;
+
+	*nplanes = buffers;
+
+	dprintk(dev, 1, "%s: count=%d\n", __func__, *nbuffers);
+	for (p = 0; p < buffers; p++)
+		dprintk(dev, 1, "%s: size[%u]=%u\n", __func__, p, sizes[p]);
+
+	return 0;
+}
+
+static int vid_cap_buf_prepare(struct vb2_buffer *vb)
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
+	unsigned long size;
+	unsigned buffers = tpg_g_buffers(&dev->tpg);
+	unsigned p;
+
+	dprintk(dev, 1, "%s\n", __func__);
+
+	if (WARN_ON(NULL == dev->fmt_cap))
+		return -EINVAL;
+
+	if (dev->buf_prepare_error) {
+		/*
+		 * Error injection: test what happens if buf_prepare() returns
+		 * an error.
+		 */
+		dev->buf_prepare_error = false;
+		return -EINVAL;
+	}
+	for (p = 0; p < buffers; p++) {
+		size = (tpg_g_line_width(&dev->tpg, p) *
+			dev->fmt_cap_rect.height) /
+			dev->fmt_cap->vdownsampling[p] +
+			dev->fmt_cap->data_offset[p];
+
+		if (vb2_plane_size(vb, p) < size) {
+			dprintk(dev, 1, "%s data will not fit into plane %u (%lu < %lu)\n",
+					__func__, p, vb2_plane_size(vb, p), size);
+			return -EINVAL;
+		}
+
+		vb2_set_plane_payload(vb, p, size);
+		vb->planes[p].data_offset = dev->fmt_cap->data_offset[p];
+	}
+
+	return 0;
+}
+
+static void vid_cap_buf_finish(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
+	struct v4l2_timecode *tc = &vbuf->timecode;
+	unsigned fps = 25;
+	unsigned seq = vbuf->sequence;
+
+	if (!vivid_is_sdtv_cap(dev))
+		return;
+
+	/*
+	 * Set the timecode. Rarely used, so it is interesting to
+	 * test this.
+	 */
+	vbuf->flags |= V4L2_BUF_FLAG_TIMECODE;
+	if (dev->std_cap[dev->input] & V4L2_STD_525_60)
+		fps = 30;
+	tc->type = (fps == 30) ? V4L2_TC_TYPE_30FPS : V4L2_TC_TYPE_25FPS;
+	tc->flags = 0;
+	tc->frames = seq % fps;
+	tc->seconds = (seq / fps) % 60;
+	tc->minutes = (seq / (60 * fps)) % 60;
+	tc->hours = (seq / (60 * 60 * fps)) % 24;
+}
+
+static void vid_cap_buf_queue(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
+	struct vivid_buffer *buf = container_of(vbuf, struct vivid_buffer, vb);
+
+	dprintk(dev, 1, "%s\n", __func__);
+
+	spin_lock(&dev->slock);
+	list_add_tail(&buf->list, &dev->vid_cap_active);
+	spin_unlock(&dev->slock);
+}
+
+static int vid_cap_start_streaming(struct vb2_queue *vq, unsigned count)
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vq);
+	unsigned i;
+	int err;
+
+	if (vb2_is_streaming(&dev->vb_vid_out_q))
+		dev->can_loop_video = vivid_vid_can_loop(dev);
+
+	dev->vid_cap_seq_count = 0;
+	dprintk(dev, 1, "%s\n", __func__);
+	for (i = 0; i < VIDEO_MAX_FRAME; i++)
+		dev->must_blank[i] = tpg_g_perc_fill(&dev->tpg) < 100;
+	if (dev->start_streaming_error) {
+		dev->start_streaming_error = false;
+		err = -EINVAL;
+	} else {
+		err = vivid_start_generating_vid_cap(dev, &dev->vid_cap_streaming);
+	}
+	if (err) {
+		struct vivid_buffer *buf, *tmp;
+
+		list_for_each_entry_safe(buf, tmp, &dev->vid_cap_active, list) {
+			list_del(&buf->list);
+			vb2_buffer_done(&buf->vb.vb2_buf,
+					VB2_BUF_STATE_QUEUED);
+		}
+	}
+	return err;
+}
+
+/* abort streaming and wait for last buffer */
+static void vid_cap_stop_streaming(struct vb2_queue *vq)
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vq);
+
+	dprintk(dev, 1, "%s\n", __func__);
+	vivid_stop_generating_vid_cap(dev, &dev->vid_cap_streaming);
+	dev->can_loop_video = false;
+}
+
+static void vid_cap_buf_request_complete(struct vb2_buffer *vb)
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
+
+	v4l2_ctrl_request_complete(vb->req_obj.req, &dev->ctrl_hdl_vid_cap);
+}
+
+const struct vb2_ops vivid_vid_cap_qops = {
+	.queue_setup		= vid_cap_queue_setup,
+	.buf_prepare		= vid_cap_buf_prepare,
+	.buf_finish		= vid_cap_buf_finish,
+	.buf_queue		= vid_cap_buf_queue,
+	.start_streaming	= vid_cap_start_streaming,
+	.stop_streaming		= vid_cap_stop_streaming,
+	.buf_request_complete	= vid_cap_buf_request_complete,
+	.wait_prepare		= vb2_ops_wait_prepare,
+	.wait_finish		= vb2_ops_wait_finish,
+};
+
+/*
+ * Determine the 'picture' quality based on the current TV frequency: either
+ * COLOR for a good 'signal', GRAY (grayscale picture) for a slightly off
+ * signal or NOISE for no signal.
+ */
+void vivid_update_quality(struct vivid_dev *dev)
+{
+	unsigned freq_modulus;
+
+	if (dev->loop_video && (vivid_is_svid_cap(dev) || vivid_is_hdmi_cap(dev))) {
+		/*
+		 * The 'noise' will only be replaced by the actual video
+		 * if the output video matches the input video settings.
+		 */
+		tpg_s_quality(&dev->tpg, TPG_QUAL_NOISE, 0);
+		return;
+	}
+	if (vivid_is_hdmi_cap(dev) &&
+	    VIVID_INVALID_SIGNAL(dev->dv_timings_signal_mode[dev->input])) {
+		tpg_s_quality(&dev->tpg, TPG_QUAL_NOISE, 0);
+		return;
+	}
+	if (vivid_is_sdtv_cap(dev) &&
+	    VIVID_INVALID_SIGNAL(dev->std_signal_mode[dev->input])) {
+		tpg_s_quality(&dev->tpg, TPG_QUAL_NOISE, 0);
+		return;
+	}
+	if (!vivid_is_tv_cap(dev)) {
+		tpg_s_quality(&dev->tpg, TPG_QUAL_COLOR, 0);
+		return;
+	}
+
+	/*
+	 * There is a fake channel every 6 MHz at 49.25, 55.25, etc.
+	 * From +/- 0.25 MHz around the channel there is color, and from
+	 * +/- 1 MHz there is grayscale (chroma is lost).
+	 * Everywhere else it is just noise.
+	 */
+	freq_modulus = (dev->tv_freq - 676 /* (43.25-1) * 16 */) % (6 * 16);
+	if (freq_modulus > 2 * 16) {
+		tpg_s_quality(&dev->tpg, TPG_QUAL_NOISE,
+			next_pseudo_random32(dev->tv_freq ^ 0x55) & 0x3f);
+		return;
+	}
+	if (freq_modulus < 12 /*0.75 * 16*/ || freq_modulus > 20 /*1.25 * 16*/)
+		tpg_s_quality(&dev->tpg, TPG_QUAL_GRAY, 0);
+	else
+		tpg_s_quality(&dev->tpg, TPG_QUAL_COLOR, 0);
+}
+
+/*
+ * Get the current picture quality and the associated afc value.
+ */
+static enum tpg_quality vivid_get_quality(struct vivid_dev *dev, s32 *afc)
+{
+	unsigned freq_modulus;
+
+	if (afc)
+		*afc = 0;
+	if (tpg_g_quality(&dev->tpg) == TPG_QUAL_COLOR ||
+	    tpg_g_quality(&dev->tpg) == TPG_QUAL_NOISE)
+		return tpg_g_quality(&dev->tpg);
+
+	/*
+	 * There is a fake channel every 6 MHz at 49.25, 55.25, etc.
+	 * From +/- 0.25 MHz around the channel there is color, and from
+	 * +/- 1 MHz there is grayscale (chroma is lost).
+	 * Everywhere else it is just gray.
+	 */
+	freq_modulus = (dev->tv_freq - 676 /* (43.25-1) * 16 */) % (6 * 16);
+	if (afc)
+		*afc = freq_modulus - 1 * 16;
+	return TPG_QUAL_GRAY;
+}
+
+enum tpg_video_aspect vivid_get_video_aspect(const struct vivid_dev *dev)
+{
+	if (vivid_is_sdtv_cap(dev))
+		return dev->std_aspect_ratio[dev->input];
+
+	if (vivid_is_hdmi_cap(dev))
+		return dev->dv_timings_aspect_ratio[dev->input];
+
+	return TPG_VIDEO_ASPECT_IMAGE;
+}
+
+static enum tpg_pixel_aspect vivid_get_pixel_aspect(const struct vivid_dev *dev)
+{
+	if (vivid_is_sdtv_cap(dev))
+		return (dev->std_cap[dev->input] & V4L2_STD_525_60) ?
+			TPG_PIXEL_ASPECT_NTSC : TPG_PIXEL_ASPECT_PAL;
+
+	if (vivid_is_hdmi_cap(dev) &&
+	    dev->src_rect.width == 720 && dev->src_rect.height <= 576)
+		return dev->src_rect.height == 480 ?
+			TPG_PIXEL_ASPECT_NTSC : TPG_PIXEL_ASPECT_PAL;
+
+	return TPG_PIXEL_ASPECT_SQUARE;
+}
+
+/*
+ * Called whenever the format has to be reset which can occur when
+ * changing inputs, standard, timings, etc.
+ */
+void vivid_update_format_cap(struct vivid_dev *dev, bool keep_controls)
+{
+	struct v4l2_bt_timings *bt = &dev->dv_timings_cap[dev->input].bt;
+	unsigned size;
+	u64 pixelclock;
+
+	switch (dev->input_type[dev->input]) {
+	case WEBCAM:
+	default:
+		dev->src_rect.width = webcam_sizes[dev->webcam_size_idx].width;
+		dev->src_rect.height = webcam_sizes[dev->webcam_size_idx].height;
+		dev->timeperframe_vid_cap = webcam_intervals[dev->webcam_ival_idx];
+		dev->field_cap = V4L2_FIELD_NONE;
+		tpg_s_rgb_range(&dev->tpg, V4L2_DV_RGB_RANGE_AUTO);
+		break;
+	case TV:
+	case SVID:
+		dev->field_cap = dev->tv_field_cap;
+		dev->src_rect.width = 720;
+		if (dev->std_cap[dev->input] & V4L2_STD_525_60) {
+			dev->src_rect.height = 480;
+			dev->timeperframe_vid_cap = (struct v4l2_fract) { 1001, 30000 };
+			dev->service_set_cap = V4L2_SLICED_CAPTION_525;
+		} else {
+			dev->src_rect.height = 576;
+			dev->timeperframe_vid_cap = (struct v4l2_fract) { 1000, 25000 };
+			dev->service_set_cap = V4L2_SLICED_WSS_625 | V4L2_SLICED_TELETEXT_B;
+		}
+		tpg_s_rgb_range(&dev->tpg, V4L2_DV_RGB_RANGE_AUTO);
+		break;
+	case HDMI:
+		dev->src_rect.width = bt->width;
+		dev->src_rect.height = bt->height;
+		size = V4L2_DV_BT_FRAME_WIDTH(bt) * V4L2_DV_BT_FRAME_HEIGHT(bt);
+		if (dev->reduced_fps && can_reduce_fps(bt)) {
+			pixelclock = div_u64(bt->pixelclock * 1000, 1001);
+			bt->flags |= V4L2_DV_FL_REDUCED_FPS;
+		} else {
+			pixelclock = bt->pixelclock;
+			bt->flags &= ~V4L2_DV_FL_REDUCED_FPS;
+		}
+		dev->timeperframe_vid_cap = (struct v4l2_fract) {
+			size / 100, (u32)pixelclock / 100
+		};
+		if (bt->interlaced)
+			dev->field_cap = V4L2_FIELD_ALTERNATE;
+		else
+			dev->field_cap = V4L2_FIELD_NONE;
+
+		/*
+		 * We can be called from within s_ctrl, in that case we can't
+		 * set/get controls. Luckily we don't need to in that case.
+		 */
+		if (keep_controls || !dev->colorspace)
+			break;
+		if (bt->flags & V4L2_DV_FL_IS_CE_VIDEO) {
+			if (bt->width == 720 && bt->height <= 576)
+				v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_170M);
+			else
+				v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_709);
+			v4l2_ctrl_s_ctrl(dev->real_rgb_range_cap, 1);
+		} else {
+			v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_SRGB);
+			v4l2_ctrl_s_ctrl(dev->real_rgb_range_cap, 0);
+		}
+		tpg_s_rgb_range(&dev->tpg, v4l2_ctrl_g_ctrl(dev->rgb_range_cap));
+		break;
+	}
+	vfree(dev->bitmap_cap);
+	dev->bitmap_cap = NULL;
+	vivid_update_quality(dev);
+	tpg_reset_source(&dev->tpg, dev->src_rect.width, dev->src_rect.height, dev->field_cap);
+	dev->crop_cap = dev->src_rect;
+	dev->crop_bounds_cap = dev->src_rect;
+	dev->compose_cap = dev->crop_cap;
+	if (V4L2_FIELD_HAS_T_OR_B(dev->field_cap))
+		dev->compose_cap.height /= 2;
+	dev->fmt_cap_rect = dev->compose_cap;
+	tpg_s_video_aspect(&dev->tpg, vivid_get_video_aspect(dev));
+	tpg_s_pixel_aspect(&dev->tpg, vivid_get_pixel_aspect(dev));
+	tpg_update_mv_step(&dev->tpg);
+}
+
+/* Map the field to something that is valid for the current input */
+static enum v4l2_field vivid_field_cap(struct vivid_dev *dev, enum v4l2_field field)
+{
+	if (vivid_is_sdtv_cap(dev)) {
+		switch (field) {
+		case V4L2_FIELD_INTERLACED_TB:
+		case V4L2_FIELD_INTERLACED_BT:
+		case V4L2_FIELD_SEQ_TB:
+		case V4L2_FIELD_SEQ_BT:
+		case V4L2_FIELD_TOP:
+		case V4L2_FIELD_BOTTOM:
+		case V4L2_FIELD_ALTERNATE:
+			return field;
+		case V4L2_FIELD_INTERLACED:
+		default:
+			return V4L2_FIELD_INTERLACED;
+		}
+	}
+	if (vivid_is_hdmi_cap(dev))
+		return dev->dv_timings_cap[dev->input].bt.interlaced ?
+			V4L2_FIELD_ALTERNATE : V4L2_FIELD_NONE;
+	return V4L2_FIELD_NONE;
+}
+
+static unsigned vivid_colorspace_cap(struct vivid_dev *dev)
+{
+	if (!dev->loop_video || vivid_is_webcam(dev) || vivid_is_tv_cap(dev))
+		return tpg_g_colorspace(&dev->tpg);
+	return dev->colorspace_out;
+}
+
+static unsigned vivid_xfer_func_cap(struct vivid_dev *dev)
+{
+	if (!dev->loop_video || vivid_is_webcam(dev) || vivid_is_tv_cap(dev))
+		return tpg_g_xfer_func(&dev->tpg);
+	return dev->xfer_func_out;
+}
+
+static unsigned vivid_ycbcr_enc_cap(struct vivid_dev *dev)
+{
+	if (!dev->loop_video || vivid_is_webcam(dev) || vivid_is_tv_cap(dev))
+		return tpg_g_ycbcr_enc(&dev->tpg);
+	return dev->ycbcr_enc_out;
+}
+
+static unsigned int vivid_hsv_enc_cap(struct vivid_dev *dev)
+{
+	if (!dev->loop_video || vivid_is_webcam(dev) || vivid_is_tv_cap(dev))
+		return tpg_g_hsv_enc(&dev->tpg);
+	return dev->hsv_enc_out;
+}
+
+static unsigned vivid_quantization_cap(struct vivid_dev *dev)
+{
+	if (!dev->loop_video || vivid_is_webcam(dev) || vivid_is_tv_cap(dev))
+		return tpg_g_quantization(&dev->tpg);
+	return dev->quantization_out;
+}
+
+int vivid_g_fmt_vid_cap(struct file *file, void *priv,
+					struct v4l2_format *f)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	struct v4l2_pix_format_mplane *mp = &f->fmt.pix_mp;
+	unsigned p;
+
+	mp->width        = dev->fmt_cap_rect.width;
+	mp->height       = dev->fmt_cap_rect.height;
+	mp->field        = dev->field_cap;
+	mp->pixelformat  = dev->fmt_cap->fourcc;
+	mp->colorspace   = vivid_colorspace_cap(dev);
+	mp->xfer_func    = vivid_xfer_func_cap(dev);
+	if (dev->fmt_cap->color_enc == TGP_COLOR_ENC_HSV)
+		mp->hsv_enc    = vivid_hsv_enc_cap(dev);
+	else
+		mp->ycbcr_enc    = vivid_ycbcr_enc_cap(dev);
+	mp->quantization = vivid_quantization_cap(dev);
+	mp->num_planes = dev->fmt_cap->buffers;
+	for (p = 0; p < mp->num_planes; p++) {
+		mp->plane_fmt[p].bytesperline = tpg_g_bytesperline(&dev->tpg, p);
+		mp->plane_fmt[p].sizeimage =
+			(tpg_g_line_width(&dev->tpg, p) * mp->height) /
+			dev->fmt_cap->vdownsampling[p] +
+			dev->fmt_cap->data_offset[p];
+	}
+	return 0;
+}
+
+int vivid_try_fmt_vid_cap(struct file *file, void *priv,
+			struct v4l2_format *f)
+{
+	struct v4l2_pix_format_mplane *mp = &f->fmt.pix_mp;
+	struct v4l2_plane_pix_format *pfmt = mp->plane_fmt;
+	struct vivid_dev *dev = video_drvdata(file);
+	const struct vivid_fmt *fmt;
+	unsigned bytesperline, max_bpl;
+	unsigned factor = 1;
+	unsigned w, h;
+	unsigned p;
+
+	fmt = vivid_get_format(dev, mp->pixelformat);
+	if (!fmt) {
+		dprintk(dev, 1, "Fourcc format (0x%08x) unknown.\n",
+			mp->pixelformat);
+		mp->pixelformat = V4L2_PIX_FMT_YUYV;
+		fmt = vivid_get_format(dev, mp->pixelformat);
+	}
+
+	mp->field = vivid_field_cap(dev, mp->field);
+	if (vivid_is_webcam(dev)) {
+		const struct v4l2_frmsize_discrete *sz =
+			v4l2_find_nearest_size(webcam_sizes,
+					       VIVID_WEBCAM_SIZES, width,
+					       height, mp->width, mp->height);
+
+		w = sz->width;
+		h = sz->height;
+	} else if (vivid_is_sdtv_cap(dev)) {
+		w = 720;
+		h = (dev->std_cap[dev->input] & V4L2_STD_525_60) ? 480 : 576;
+	} else {
+		w = dev->src_rect.width;
+		h = dev->src_rect.height;
+	}
+	if (V4L2_FIELD_HAS_T_OR_B(mp->field))
+		factor = 2;
+	if (vivid_is_webcam(dev) ||
+	    (!dev->has_scaler_cap && !dev->has_crop_cap && !dev->has_compose_cap)) {
+		mp->width = w;
+		mp->height = h / factor;
+	} else {
+		struct v4l2_rect r = { 0, 0, mp->width, mp->height * factor };
+
+		v4l2_rect_set_min_size(&r, &vivid_min_rect);
+		v4l2_rect_set_max_size(&r, &vivid_max_rect);
+		if (dev->has_scaler_cap && !dev->has_compose_cap) {
+			struct v4l2_rect max_r = { 0, 0, MAX_ZOOM * w, MAX_ZOOM * h };
+
+			v4l2_rect_set_max_size(&r, &max_r);
+		} else if (!dev->has_scaler_cap && dev->has_crop_cap && !dev->has_compose_cap) {
+			v4l2_rect_set_max_size(&r, &dev->src_rect);
+		} else if (!dev->has_scaler_cap && !dev->has_crop_cap) {
+			v4l2_rect_set_min_size(&r, &dev->src_rect);
+		}
+		mp->width = r.width;
+		mp->height = r.height / factor;
+	}
+
+	/* This driver supports custom bytesperline values */
+
+	mp->num_planes = fmt->buffers;
+	for (p = 0; p < fmt->buffers; p++) {
+		/* Calculate the minimum supported bytesperline value */
+		bytesperline = (mp->width * fmt->bit_depth[p]) >> 3;
+		/* Calculate the maximum supported bytesperline value */
+		max_bpl = (MAX_ZOOM * MAX_WIDTH * fmt->bit_depth[p]) >> 3;
+
+		if (pfmt[p].bytesperline > max_bpl)
+			pfmt[p].bytesperline = max_bpl;
+		if (pfmt[p].bytesperline < bytesperline)
+			pfmt[p].bytesperline = bytesperline;
+
+		pfmt[p].sizeimage = (pfmt[p].bytesperline * mp->height) /
+				fmt->vdownsampling[p] + fmt->data_offset[p];
+
+		memset(pfmt[p].reserved, 0, sizeof(pfmt[p].reserved));
+	}
+	for (p = fmt->buffers; p < fmt->planes; p++)
+		pfmt[0].sizeimage += (pfmt[0].bytesperline * mp->height *
+			(fmt->bit_depth[p] / fmt->vdownsampling[p])) /
+			(fmt->bit_depth[0] / fmt->vdownsampling[0]);
+
+	mp->colorspace = vivid_colorspace_cap(dev);
+	if (fmt->color_enc == TGP_COLOR_ENC_HSV)
+		mp->hsv_enc = vivid_hsv_enc_cap(dev);
+	else
+		mp->ycbcr_enc = vivid_ycbcr_enc_cap(dev);
+	mp->xfer_func = vivid_xfer_func_cap(dev);
+	mp->quantization = vivid_quantization_cap(dev);
+	memset(mp->reserved, 0, sizeof(mp->reserved));
+	return 0;
+}
+
+int vivid_s_fmt_vid_cap(struct file *file, void *priv,
+					struct v4l2_format *f)
+{
+	struct v4l2_pix_format_mplane *mp = &f->fmt.pix_mp;
+	struct vivid_dev *dev = video_drvdata(file);
+	struct v4l2_rect *crop = &dev->crop_cap;
+	struct v4l2_rect *compose = &dev->compose_cap;
+	struct vb2_queue *q = &dev->vb_vid_cap_q;
+	int ret = vivid_try_fmt_vid_cap(file, priv, f);
+	unsigned factor = 1;
+	unsigned p;
+	unsigned i;
+
+	if (ret < 0)
+		return ret;
+
+	if (vb2_is_busy(q)) {
+		dprintk(dev, 1, "%s device busy\n", __func__);
+		return -EBUSY;
+	}
+
+	if (dev->overlay_cap_owner && dev->fb_cap.fmt.pixelformat != mp->pixelformat) {
+		dprintk(dev, 1, "overlay is active, can't change pixelformat\n");
+		return -EBUSY;
+	}
+
+	dev->fmt_cap = vivid_get_format(dev, mp->pixelformat);
+	if (V4L2_FIELD_HAS_T_OR_B(mp->field))
+		factor = 2;
+
+	/* Note: the webcam input doesn't support scaling, cropping or composing */
+
+	if (!vivid_is_webcam(dev) &&
+	    (dev->has_scaler_cap || dev->has_crop_cap || dev->has_compose_cap)) {
+		struct v4l2_rect r = { 0, 0, mp->width, mp->height };
+
+		if (dev->has_scaler_cap) {
+			if (dev->has_compose_cap)
+				v4l2_rect_map_inside(compose, &r);
+			else
+				*compose = r;
+			if (dev->has_crop_cap && !dev->has_compose_cap) {
+				struct v4l2_rect min_r = {
+					0, 0,
+					r.width / MAX_ZOOM,
+					factor * r.height / MAX_ZOOM
+				};
+				struct v4l2_rect max_r = {
+					0, 0,
+					r.width * MAX_ZOOM,
+					factor * r.height * MAX_ZOOM
+				};
+
+				v4l2_rect_set_min_size(crop, &min_r);
+				v4l2_rect_set_max_size(crop, &max_r);
+				v4l2_rect_map_inside(crop, &dev->crop_bounds_cap);
+			} else if (dev->has_crop_cap) {
+				struct v4l2_rect min_r = {
+					0, 0,
+					compose->width / MAX_ZOOM,
+					factor * compose->height / MAX_ZOOM
+				};
+				struct v4l2_rect max_r = {
+					0, 0,
+					compose->width * MAX_ZOOM,
+					factor * compose->height * MAX_ZOOM
+				};
+
+				v4l2_rect_set_min_size(crop, &min_r);
+				v4l2_rect_set_max_size(crop, &max_r);
+				v4l2_rect_map_inside(crop, &dev->crop_bounds_cap);
+			}
+		} else if (dev->has_crop_cap && !dev->has_compose_cap) {
+			r.height *= factor;
+			v4l2_rect_set_size_to(crop, &r);
+			v4l2_rect_map_inside(crop, &dev->crop_bounds_cap);
+			r = *crop;
+			r.height /= factor;
+			v4l2_rect_set_size_to(compose, &r);
+		} else if (!dev->has_crop_cap) {
+			v4l2_rect_map_inside(compose, &r);
+		} else {
+			r.height *= factor;
+			v4l2_rect_set_max_size(crop, &r);
+			v4l2_rect_map_inside(crop, &dev->crop_bounds_cap);
+			compose->top *= factor;
+			compose->height *= factor;
+			v4l2_rect_set_size_to(compose, crop);
+			v4l2_rect_map_inside(compose, &r);
+			compose->top /= factor;
+			compose->height /= factor;
+		}
+	} else if (vivid_is_webcam(dev)) {
+		/* Guaranteed to be a match */
+		for (i = 0; i < ARRAY_SIZE(webcam_sizes); i++)
+			if (webcam_sizes[i].width == mp->width &&
+					webcam_sizes[i].height == mp->height)
+				break;
+		dev->webcam_size_idx = i;
+		if (dev->webcam_ival_idx >= 2 * (VIVID_WEBCAM_SIZES - i))
+			dev->webcam_ival_idx = 2 * (VIVID_WEBCAM_SIZES - i) - 1;
+		vivid_update_format_cap(dev, false);
+	} else {
+		struct v4l2_rect r = { 0, 0, mp->width, mp->height };
+
+		v4l2_rect_set_size_to(compose, &r);
+		r.height *= factor;
+		v4l2_rect_set_size_to(crop, &r);
+	}
+
+	dev->fmt_cap_rect.width = mp->width;
+	dev->fmt_cap_rect.height = mp->height;
+	tpg_s_buf_height(&dev->tpg, mp->height);
+	tpg_s_fourcc(&dev->tpg, dev->fmt_cap->fourcc);
+	for (p = 0; p < tpg_g_buffers(&dev->tpg); p++)
+		tpg_s_bytesperline(&dev->tpg, p, mp->plane_fmt[p].bytesperline);
+	dev->field_cap = mp->field;
+	if (dev->field_cap == V4L2_FIELD_ALTERNATE)
+		tpg_s_field(&dev->tpg, V4L2_FIELD_TOP, true);
+	else
+		tpg_s_field(&dev->tpg, dev->field_cap, false);
+	tpg_s_crop_compose(&dev->tpg, &dev->crop_cap, &dev->compose_cap);
+	if (vivid_is_sdtv_cap(dev))
+		dev->tv_field_cap = mp->field;
+	tpg_update_mv_step(&dev->tpg);
+	return 0;
+}
+
+int vidioc_g_fmt_vid_cap_mplane(struct file *file, void *priv,
+					struct v4l2_format *f)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (!dev->multiplanar)
+		return -ENOTTY;
+	return vivid_g_fmt_vid_cap(file, priv, f);
+}
+
+int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv,
+			struct v4l2_format *f)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (!dev->multiplanar)
+		return -ENOTTY;
+	return vivid_try_fmt_vid_cap(file, priv, f);
+}
+
+int vidioc_s_fmt_vid_cap_mplane(struct file *file, void *priv,
+			struct v4l2_format *f)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (!dev->multiplanar)
+		return -ENOTTY;
+	return vivid_s_fmt_vid_cap(file, priv, f);
+}
+
+int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
+					struct v4l2_format *f)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (dev->multiplanar)
+		return -ENOTTY;
+	return fmt_sp2mp_func(file, priv, f, vivid_g_fmt_vid_cap);
+}
+
+int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
+			struct v4l2_format *f)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (dev->multiplanar)
+		return -ENOTTY;
+	return fmt_sp2mp_func(file, priv, f, vivid_try_fmt_vid_cap);
+}
+
+int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+			struct v4l2_format *f)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (dev->multiplanar)
+		return -ENOTTY;
+	return fmt_sp2mp_func(file, priv, f, vivid_s_fmt_vid_cap);
+}
+
+int vivid_vid_cap_g_selection(struct file *file, void *priv,
+			      struct v4l2_selection *sel)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (!dev->has_crop_cap && !dev->has_compose_cap)
+		return -ENOTTY;
+	if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+	if (vivid_is_webcam(dev))
+		return -ENODATA;
+
+	sel->r.left = sel->r.top = 0;
+	switch (sel->target) {
+	case V4L2_SEL_TGT_CROP:
+		if (!dev->has_crop_cap)
+			return -EINVAL;
+		sel->r = dev->crop_cap;
+		break;
+	case V4L2_SEL_TGT_CROP_DEFAULT:
+	case V4L2_SEL_TGT_CROP_BOUNDS:
+		if (!dev->has_crop_cap)
+			return -EINVAL;
+		sel->r = dev->src_rect;
+		break;
+	case V4L2_SEL_TGT_COMPOSE_BOUNDS:
+		if (!dev->has_compose_cap)
+			return -EINVAL;
+		sel->r = vivid_max_rect;
+		break;
+	case V4L2_SEL_TGT_COMPOSE:
+		if (!dev->has_compose_cap)
+			return -EINVAL;
+		sel->r = dev->compose_cap;
+		break;
+	case V4L2_SEL_TGT_COMPOSE_DEFAULT:
+		if (!dev->has_compose_cap)
+			return -EINVAL;
+		sel->r = dev->fmt_cap_rect;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+int vivid_vid_cap_s_selection(struct file *file, void *fh, struct v4l2_selection *s)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	struct v4l2_rect *crop = &dev->crop_cap;
+	struct v4l2_rect *compose = &dev->compose_cap;
+	unsigned factor = V4L2_FIELD_HAS_T_OR_B(dev->field_cap) ? 2 : 1;
+	int ret;
+
+	if (!dev->has_crop_cap && !dev->has_compose_cap)
+		return -ENOTTY;
+	if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+	if (vivid_is_webcam(dev))
+		return -ENODATA;
+
+	switch (s->target) {
+	case V4L2_SEL_TGT_CROP:
+		if (!dev->has_crop_cap)
+			return -EINVAL;
+		ret = vivid_vid_adjust_sel(s->flags, &s->r);
+		if (ret)
+			return ret;
+		v4l2_rect_set_min_size(&s->r, &vivid_min_rect);
+		v4l2_rect_set_max_size(&s->r, &dev->src_rect);
+		v4l2_rect_map_inside(&s->r, &dev->crop_bounds_cap);
+		s->r.top /= factor;
+		s->r.height /= factor;
+		if (dev->has_scaler_cap) {
+			struct v4l2_rect fmt = dev->fmt_cap_rect;
+			struct v4l2_rect max_rect = {
+				0, 0,
+				s->r.width * MAX_ZOOM,
+				s->r.height * MAX_ZOOM
+			};
+			struct v4l2_rect min_rect = {
+				0, 0,
+				s->r.width / MAX_ZOOM,
+				s->r.height / MAX_ZOOM
+			};
+
+			v4l2_rect_set_min_size(&fmt, &min_rect);
+			if (!dev->has_compose_cap)
+				v4l2_rect_set_max_size(&fmt, &max_rect);
+			if (!v4l2_rect_same_size(&dev->fmt_cap_rect, &fmt) &&
+			    vb2_is_busy(&dev->vb_vid_cap_q))
+				return -EBUSY;
+			if (dev->has_compose_cap) {
+				v4l2_rect_set_min_size(compose, &min_rect);
+				v4l2_rect_set_max_size(compose, &max_rect);
+			}
+			dev->fmt_cap_rect = fmt;
+			tpg_s_buf_height(&dev->tpg, fmt.height);
+		} else if (dev->has_compose_cap) {
+			struct v4l2_rect fmt = dev->fmt_cap_rect;
+
+			v4l2_rect_set_min_size(&fmt, &s->r);
+			if (!v4l2_rect_same_size(&dev->fmt_cap_rect, &fmt) &&
+			    vb2_is_busy(&dev->vb_vid_cap_q))
+				return -EBUSY;
+			dev->fmt_cap_rect = fmt;
+			tpg_s_buf_height(&dev->tpg, fmt.height);
+			v4l2_rect_set_size_to(compose, &s->r);
+			v4l2_rect_map_inside(compose, &dev->fmt_cap_rect);
+		} else {
+			if (!v4l2_rect_same_size(&s->r, &dev->fmt_cap_rect) &&
+			    vb2_is_busy(&dev->vb_vid_cap_q))
+				return -EBUSY;
+			v4l2_rect_set_size_to(&dev->fmt_cap_rect, &s->r);
+			v4l2_rect_set_size_to(compose, &s->r);
+			v4l2_rect_map_inside(compose, &dev->fmt_cap_rect);
+			tpg_s_buf_height(&dev->tpg, dev->fmt_cap_rect.height);
+		}
+		s->r.top *= factor;
+		s->r.height *= factor;
+		*crop = s->r;
+		break;
+	case V4L2_SEL_TGT_COMPOSE:
+		if (!dev->has_compose_cap)
+			return -EINVAL;
+		ret = vivid_vid_adjust_sel(s->flags, &s->r);
+		if (ret)
+			return ret;
+		v4l2_rect_set_min_size(&s->r, &vivid_min_rect);
+		v4l2_rect_set_max_size(&s->r, &dev->fmt_cap_rect);
+		if (dev->has_scaler_cap) {
+			struct v4l2_rect max_rect = {
+				0, 0,
+				dev->src_rect.width * MAX_ZOOM,
+				(dev->src_rect.height / factor) * MAX_ZOOM
+			};
+
+			v4l2_rect_set_max_size(&s->r, &max_rect);
+			if (dev->has_crop_cap) {
+				struct v4l2_rect min_rect = {
+					0, 0,
+					s->r.width / MAX_ZOOM,
+					(s->r.height * factor) / MAX_ZOOM
+				};
+				struct v4l2_rect max_rect = {
+					0, 0,
+					s->r.width * MAX_ZOOM,
+					(s->r.height * factor) * MAX_ZOOM
+				};
+
+				v4l2_rect_set_min_size(crop, &min_rect);
+				v4l2_rect_set_max_size(crop, &max_rect);
+				v4l2_rect_map_inside(crop, &dev->crop_bounds_cap);
+			}
+		} else if (dev->has_crop_cap) {
+			s->r.top *= factor;
+			s->r.height *= factor;
+			v4l2_rect_set_max_size(&s->r, &dev->src_rect);
+			v4l2_rect_set_size_to(crop, &s->r);
+			v4l2_rect_map_inside(crop, &dev->crop_bounds_cap);
+			s->r.top /= factor;
+			s->r.height /= factor;
+		} else {
+			v4l2_rect_set_size_to(&s->r, &dev->src_rect);
+			s->r.height /= factor;
+		}
+		v4l2_rect_map_inside(&s->r, &dev->fmt_cap_rect);
+		if (dev->bitmap_cap && (compose->width != s->r.width ||
+					compose->height != s->r.height)) {
+			vfree(dev->bitmap_cap);
+			dev->bitmap_cap = NULL;
+		}
+		*compose = s->r;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	tpg_s_crop_compose(&dev->tpg, crop, compose);
+	return 0;
+}
+
+int vivid_vid_cap_g_pixelaspect(struct file *file, void *priv,
+				int type, struct v4l2_fract *f)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+
+	switch (vivid_get_pixel_aspect(dev)) {
+	case TPG_PIXEL_ASPECT_NTSC:
+		f->numerator = 11;
+		f->denominator = 10;
+		break;
+	case TPG_PIXEL_ASPECT_PAL:
+		f->numerator = 54;
+		f->denominator = 59;
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
+int vidioc_enum_fmt_vid_overlay(struct file *file, void  *priv,
+					struct v4l2_fmtdesc *f)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	const struct vivid_fmt *fmt;
+
+	if (dev->multiplanar)
+		return -ENOTTY;
+
+	if (f->index >= ARRAY_SIZE(formats_ovl))
+		return -EINVAL;
+
+	fmt = &formats_ovl[f->index];
+
+	f->pixelformat = fmt->fourcc;
+	return 0;
+}
+
+int vidioc_g_fmt_vid_overlay(struct file *file, void *priv,
+					struct v4l2_format *f)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	const struct v4l2_rect *compose = &dev->compose_cap;
+	struct v4l2_window *win = &f->fmt.win;
+	unsigned clipcount = win->clipcount;
+
+	if (dev->multiplanar)
+		return -ENOTTY;
+
+	win->w.top = dev->overlay_cap_top;
+	win->w.left = dev->overlay_cap_left;
+	win->w.width = compose->width;
+	win->w.height = compose->height;
+	win->field = dev->overlay_cap_field;
+	win->clipcount = dev->clipcount_cap;
+	if (clipcount > dev->clipcount_cap)
+		clipcount = dev->clipcount_cap;
+	if (dev->bitmap_cap == NULL)
+		win->bitmap = NULL;
+	else if (win->bitmap) {
+		if (copy_to_user(win->bitmap, dev->bitmap_cap,
+		    ((compose->width + 7) / 8) * compose->height))
+			return -EFAULT;
+	}
+	if (clipcount && win->clips) {
+		if (copy_to_user(win->clips, dev->clips_cap,
+				 clipcount * sizeof(dev->clips_cap[0])))
+			return -EFAULT;
+	}
+	return 0;
+}
+
+int vidioc_try_fmt_vid_overlay(struct file *file, void *priv,
+					struct v4l2_format *f)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	const struct v4l2_rect *compose = &dev->compose_cap;
+	struct v4l2_window *win = &f->fmt.win;
+	int i, j;
+
+	if (dev->multiplanar)
+		return -ENOTTY;
+
+	win->w.left = clamp_t(int, win->w.left,
+			      -dev->fb_cap.fmt.width, dev->fb_cap.fmt.width);
+	win->w.top = clamp_t(int, win->w.top,
+			     -dev->fb_cap.fmt.height, dev->fb_cap.fmt.height);
+	win->w.width = compose->width;
+	win->w.height = compose->height;
+	if (win->field != V4L2_FIELD_BOTTOM && win->field != V4L2_FIELD_TOP)
+		win->field = V4L2_FIELD_ANY;
+	win->chromakey = 0;
+	win->global_alpha = 0;
+	if (win->clipcount && !win->clips)
+		win->clipcount = 0;
+	if (win->clipcount > MAX_CLIPS)
+		win->clipcount = MAX_CLIPS;
+	if (win->clipcount) {
+		if (copy_from_user(dev->try_clips_cap, win->clips,
+				   win->clipcount * sizeof(dev->clips_cap[0])))
+			return -EFAULT;
+		for (i = 0; i < win->clipcount; i++) {
+			struct v4l2_rect *r = &dev->try_clips_cap[i].c;
+
+			r->top = clamp_t(s32, r->top, 0, dev->fb_cap.fmt.height - 1);
+			r->height = clamp_t(s32, r->height, 1, dev->fb_cap.fmt.height - r->top);
+			r->left = clamp_t(u32, r->left, 0, dev->fb_cap.fmt.width - 1);
+			r->width = clamp_t(u32, r->width, 1, dev->fb_cap.fmt.width - r->left);
+		}
+		/*
+		 * Yeah, so sue me, it's an O(n^2) algorithm. But n is a small
+		 * number and it's typically a one-time deal.
+		 */
+		for (i = 0; i < win->clipcount - 1; i++) {
+			struct v4l2_rect *r1 = &dev->try_clips_cap[i].c;
+
+			for (j = i + 1; j < win->clipcount; j++) {
+				struct v4l2_rect *r2 = &dev->try_clips_cap[j].c;
+
+				if (v4l2_rect_overlap(r1, r2))
+					return -EINVAL;
+			}
+		}
+		if (copy_to_user(win->clips, dev->try_clips_cap,
+				 win->clipcount * sizeof(dev->clips_cap[0])))
+			return -EFAULT;
+	}
+	return 0;
+}
+
+int vidioc_s_fmt_vid_overlay(struct file *file, void *priv,
+					struct v4l2_format *f)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	const struct v4l2_rect *compose = &dev->compose_cap;
+	struct v4l2_window *win = &f->fmt.win;
+	int ret = vidioc_try_fmt_vid_overlay(file, priv, f);
+	unsigned bitmap_size = ((compose->width + 7) / 8) * compose->height;
+	unsigned clips_size = win->clipcount * sizeof(dev->clips_cap[0]);
+	void *new_bitmap = NULL;
+
+	if (ret)
+		return ret;
+
+	if (win->bitmap) {
+		new_bitmap = vzalloc(bitmap_size);
+
+		if (new_bitmap == NULL)
+			return -ENOMEM;
+		if (copy_from_user(new_bitmap, win->bitmap, bitmap_size)) {
+			vfree(new_bitmap);
+			return -EFAULT;
+		}
+	}
+
+	dev->overlay_cap_top = win->w.top;
+	dev->overlay_cap_left = win->w.left;
+	dev->overlay_cap_field = win->field;
+	vfree(dev->bitmap_cap);
+	dev->bitmap_cap = new_bitmap;
+	dev->clipcount_cap = win->clipcount;
+	if (dev->clipcount_cap)
+		memcpy(dev->clips_cap, dev->try_clips_cap, clips_size);
+	return 0;
+}
+
+int vivid_vid_cap_overlay(struct file *file, void *fh, unsigned i)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (dev->multiplanar)
+		return -ENOTTY;
+
+	if (i && dev->fb_vbase_cap == NULL)
+		return -EINVAL;
+
+	if (i && dev->fb_cap.fmt.pixelformat != dev->fmt_cap->fourcc) {
+		dprintk(dev, 1, "mismatch between overlay and video capture pixelformats\n");
+		return -EINVAL;
+	}
+
+	if (dev->overlay_cap_owner && dev->overlay_cap_owner != fh)
+		return -EBUSY;
+	dev->overlay_cap_owner = i ? fh : NULL;
+	return 0;
+}
+
+int vivid_vid_cap_g_fbuf(struct file *file, void *fh,
+				struct v4l2_framebuffer *a)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (dev->multiplanar)
+		return -ENOTTY;
+
+	*a = dev->fb_cap;
+	a->capability = V4L2_FBUF_CAP_BITMAP_CLIPPING |
+			V4L2_FBUF_CAP_LIST_CLIPPING;
+	a->flags = V4L2_FBUF_FLAG_PRIMARY;
+	a->fmt.field = V4L2_FIELD_NONE;
+	a->fmt.colorspace = V4L2_COLORSPACE_SRGB;
+	a->fmt.priv = 0;
+	return 0;
+}
+
+int vivid_vid_cap_s_fbuf(struct file *file, void *fh,
+				const struct v4l2_framebuffer *a)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	const struct vivid_fmt *fmt;
+
+	if (dev->multiplanar)
+		return -ENOTTY;
+
+	if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO))
+		return -EPERM;
+
+	if (dev->overlay_cap_owner)
+		return -EBUSY;
+
+	if (a->base == NULL) {
+		dev->fb_cap.base = NULL;
+		dev->fb_vbase_cap = NULL;
+		return 0;
+	}
+
+	if (a->fmt.width < 48 || a->fmt.height < 32)
+		return -EINVAL;
+	fmt = vivid_get_format(dev, a->fmt.pixelformat);
+	if (!fmt || !fmt->can_do_overlay)
+		return -EINVAL;
+	if (a->fmt.bytesperline < (a->fmt.width * fmt->bit_depth[0]) / 8)
+		return -EINVAL;
+	if (a->fmt.height * a->fmt.bytesperline < a->fmt.sizeimage)
+		return -EINVAL;
+
+	dev->fb_vbase_cap = phys_to_virt((unsigned long)a->base);
+	dev->fb_cap = *a;
+	dev->overlay_cap_left = clamp_t(int, dev->overlay_cap_left,
+				    -dev->fb_cap.fmt.width, dev->fb_cap.fmt.width);
+	dev->overlay_cap_top = clamp_t(int, dev->overlay_cap_top,
+				   -dev->fb_cap.fmt.height, dev->fb_cap.fmt.height);
+	return 0;
+}
+
+static const struct v4l2_audio vivid_audio_inputs[] = {
+	{ 0, "TV", V4L2_AUDCAP_STEREO },
+	{ 1, "Line-In", V4L2_AUDCAP_STEREO },
+};
+
+int vidioc_enum_input(struct file *file, void *priv,
+				struct v4l2_input *inp)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (inp->index >= dev->num_inputs)
+		return -EINVAL;
+
+	inp->type = V4L2_INPUT_TYPE_CAMERA;
+	switch (dev->input_type[inp->index]) {
+	case WEBCAM:
+		snprintf(inp->name, sizeof(inp->name), "Webcam %u",
+				dev->input_name_counter[inp->index]);
+		inp->capabilities = 0;
+		break;
+	case TV:
+		snprintf(inp->name, sizeof(inp->name), "TV %u",
+				dev->input_name_counter[inp->index]);
+		inp->type = V4L2_INPUT_TYPE_TUNER;
+		inp->std = V4L2_STD_ALL;
+		if (dev->has_audio_inputs)
+			inp->audioset = (1 << ARRAY_SIZE(vivid_audio_inputs)) - 1;
+		inp->capabilities = V4L2_IN_CAP_STD;
+		break;
+	case SVID:
+		snprintf(inp->name, sizeof(inp->name), "S-Video %u",
+				dev->input_name_counter[inp->index]);
+		inp->std = V4L2_STD_ALL;
+		if (dev->has_audio_inputs)
+			inp->audioset = (1 << ARRAY_SIZE(vivid_audio_inputs)) - 1;
+		inp->capabilities = V4L2_IN_CAP_STD;
+		break;
+	case HDMI:
+		snprintf(inp->name, sizeof(inp->name), "HDMI %u",
+				dev->input_name_counter[inp->index]);
+		inp->capabilities = V4L2_IN_CAP_DV_TIMINGS;
+		if (dev->edid_blocks == 0 ||
+		    dev->dv_timings_signal_mode[dev->input] == NO_SIGNAL)
+			inp->status |= V4L2_IN_ST_NO_SIGNAL;
+		else if (dev->dv_timings_signal_mode[dev->input] == NO_LOCK ||
+			 dev->dv_timings_signal_mode[dev->input] == OUT_OF_RANGE)
+			inp->status |= V4L2_IN_ST_NO_H_LOCK;
+		break;
+	}
+	if (dev->sensor_hflip)
+		inp->status |= V4L2_IN_ST_HFLIP;
+	if (dev->sensor_vflip)
+		inp->status |= V4L2_IN_ST_VFLIP;
+	if (dev->input == inp->index && vivid_is_sdtv_cap(dev)) {
+		if (dev->std_signal_mode[dev->input] == NO_SIGNAL) {
+			inp->status |= V4L2_IN_ST_NO_SIGNAL;
+		} else if (dev->std_signal_mode[dev->input] == NO_LOCK) {
+			inp->status |= V4L2_IN_ST_NO_H_LOCK;
+		} else if (vivid_is_tv_cap(dev)) {
+			switch (tpg_g_quality(&dev->tpg)) {
+			case TPG_QUAL_GRAY:
+				inp->status |= V4L2_IN_ST_COLOR_KILL;
+				break;
+			case TPG_QUAL_NOISE:
+				inp->status |= V4L2_IN_ST_NO_H_LOCK;
+				break;
+			default:
+				break;
+			}
+		}
+	}
+	return 0;
+}
+
+int vidioc_g_input(struct file *file, void *priv, unsigned *i)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	*i = dev->input;
+	return 0;
+}
+
+int vidioc_s_input(struct file *file, void *priv, unsigned i)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	struct v4l2_bt_timings *bt = &dev->dv_timings_cap[dev->input].bt;
+	unsigned brightness;
+
+	if (i >= dev->num_inputs)
+		return -EINVAL;
+
+	if (i == dev->input)
+		return 0;
+
+	if (vb2_is_busy(&dev->vb_vid_cap_q) ||
+	    vb2_is_busy(&dev->vb_vbi_cap_q) ||
+	    vb2_is_busy(&dev->vb_meta_cap_q))
+		return -EBUSY;
+
+	dev->input = i;
+	dev->vid_cap_dev.tvnorms = 0;
+	if (dev->input_type[i] == TV || dev->input_type[i] == SVID) {
+		dev->tv_audio_input = (dev->input_type[i] == TV) ? 0 : 1;
+		dev->vid_cap_dev.tvnorms = V4L2_STD_ALL;
+	}
+	dev->vbi_cap_dev.tvnorms = dev->vid_cap_dev.tvnorms;
+	dev->meta_cap_dev.tvnorms = dev->vid_cap_dev.tvnorms;
+	vivid_update_format_cap(dev, false);
+
+	if (dev->colorspace) {
+		switch (dev->input_type[i]) {
+		case WEBCAM:
+			v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_SRGB);
+			break;
+		case TV:
+		case SVID:
+			v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_170M);
+			break;
+		case HDMI:
+			if (bt->flags & V4L2_DV_FL_IS_CE_VIDEO) {
+				if (dev->src_rect.width == 720 && dev->src_rect.height <= 576)
+					v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_170M);
+				else
+					v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_709);
+			} else {
+				v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_SRGB);
+			}
+			break;
+		}
+	}
+
+	/*
+	 * Modify the brightness range depending on the input.
+	 * This makes it easy to use vivid to test if applications can
+	 * handle control range modifications and is also how this is
+	 * typically used in practice as different inputs may be hooked
+	 * up to different receivers with different control ranges.
+	 */
+	brightness = 128 * i + dev->input_brightness[i];
+	v4l2_ctrl_modify_range(dev->brightness,
+			128 * i, 255 + 128 * i, 1, 128 + 128 * i);
+	v4l2_ctrl_s_ctrl(dev->brightness, brightness);
+
+	/* Restore per-input states. */
+	v4l2_ctrl_activate(dev->ctrl_dv_timings_signal_mode,
+			   vivid_is_hdmi_cap(dev));
+	v4l2_ctrl_activate(dev->ctrl_dv_timings, vivid_is_hdmi_cap(dev) &&
+			   dev->dv_timings_signal_mode[dev->input] ==
+			   SELECTED_DV_TIMINGS);
+	v4l2_ctrl_activate(dev->ctrl_std_signal_mode, vivid_is_sdtv_cap(dev));
+	v4l2_ctrl_activate(dev->ctrl_standard, vivid_is_sdtv_cap(dev) &&
+			   dev->std_signal_mode[dev->input]);
+
+	if (vivid_is_hdmi_cap(dev)) {
+		v4l2_ctrl_s_ctrl(dev->ctrl_dv_timings_signal_mode,
+				 dev->dv_timings_signal_mode[dev->input]);
+		v4l2_ctrl_s_ctrl(dev->ctrl_dv_timings,
+				 dev->query_dv_timings[dev->input]);
+	} else if (vivid_is_sdtv_cap(dev)) {
+		v4l2_ctrl_s_ctrl(dev->ctrl_std_signal_mode,
+				 dev->std_signal_mode[dev->input]);
+		v4l2_ctrl_s_ctrl(dev->ctrl_standard,
+				 dev->std_signal_mode[dev->input]);
+	}
+
+	return 0;
+}
+
+int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)
+{
+	if (vin->index >= ARRAY_SIZE(vivid_audio_inputs))
+		return -EINVAL;
+	*vin = vivid_audio_inputs[vin->index];
+	return 0;
+}
+
+int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (!vivid_is_sdtv_cap(dev))
+		return -EINVAL;
+	*vin = vivid_audio_inputs[dev->tv_audio_input];
+	return 0;
+}
+
+int vidioc_s_audio(struct file *file, void *fh, const struct v4l2_audio *vin)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (!vivid_is_sdtv_cap(dev))
+		return -EINVAL;
+	if (vin->index >= ARRAY_SIZE(vivid_audio_inputs))
+		return -EINVAL;
+	dev->tv_audio_input = vin->index;
+	return 0;
+}
+
+int vivid_video_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (vf->tuner != 0)
+		return -EINVAL;
+	vf->frequency = dev->tv_freq;
+	return 0;
+}
+
+int vivid_video_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *vf)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (vf->tuner != 0)
+		return -EINVAL;
+	dev->tv_freq = clamp_t(unsigned, vf->frequency, MIN_TV_FREQ, MAX_TV_FREQ);
+	if (vivid_is_tv_cap(dev))
+		vivid_update_quality(dev);
+	return 0;
+}
+
+int vivid_video_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (vt->index != 0)
+		return -EINVAL;
+	if (vt->audmode > V4L2_TUNER_MODE_LANG1_LANG2)
+		return -EINVAL;
+	dev->tv_audmode = vt->audmode;
+	return 0;
+}
+
+int vivid_video_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	enum tpg_quality qual;
+
+	if (vt->index != 0)
+		return -EINVAL;
+
+	vt->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
+			 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
+	vt->audmode = dev->tv_audmode;
+	vt->rangelow = MIN_TV_FREQ;
+	vt->rangehigh = MAX_TV_FREQ;
+	qual = vivid_get_quality(dev, &vt->afc);
+	if (qual == TPG_QUAL_COLOR)
+		vt->signal = 0xffff;
+	else if (qual == TPG_QUAL_GRAY)
+		vt->signal = 0x8000;
+	else
+		vt->signal = 0;
+	if (qual == TPG_QUAL_NOISE) {
+		vt->rxsubchans = 0;
+	} else if (qual == TPG_QUAL_GRAY) {
+		vt->rxsubchans = V4L2_TUNER_SUB_MONO;
+	} else {
+		unsigned int channel_nr = dev->tv_freq / (6 * 16);
+		unsigned int options =
+			(dev->std_cap[dev->input] & V4L2_STD_NTSC_M) ? 4 : 3;
+
+		switch (channel_nr % options) {
+		case 0:
+			vt->rxsubchans = V4L2_TUNER_SUB_MONO;
+			break;
+		case 1:
+			vt->rxsubchans = V4L2_TUNER_SUB_STEREO;
+			break;
+		case 2:
+			if (dev->std_cap[dev->input] & V4L2_STD_NTSC_M)
+				vt->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_SAP;
+			else
+				vt->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
+			break;
+		case 3:
+			vt->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_SAP;
+			break;
+		}
+	}
+	strscpy(vt->name, "TV Tuner", sizeof(vt->name));
+	return 0;
+}
+
+/* Must remain in sync with the vivid_ctrl_standard_strings array */
+const v4l2_std_id vivid_standard[] = {
+	V4L2_STD_NTSC_M,
+	V4L2_STD_NTSC_M_JP,
+	V4L2_STD_NTSC_M_KR,
+	V4L2_STD_NTSC_443,
+	V4L2_STD_PAL_BG | V4L2_STD_PAL_H,
+	V4L2_STD_PAL_I,
+	V4L2_STD_PAL_DK,
+	V4L2_STD_PAL_M,
+	V4L2_STD_PAL_N,
+	V4L2_STD_PAL_Nc,
+	V4L2_STD_PAL_60,
+	V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H,
+	V4L2_STD_SECAM_DK,
+	V4L2_STD_SECAM_L,
+	V4L2_STD_SECAM_LC,
+	V4L2_STD_UNKNOWN
+};
+
+/* Must remain in sync with the vivid_standard array */
+const char * const vivid_ctrl_standard_strings[] = {
+	"NTSC-M",
+	"NTSC-M-JP",
+	"NTSC-M-KR",
+	"NTSC-443",
+	"PAL-BGH",
+	"PAL-I",
+	"PAL-DK",
+	"PAL-M",
+	"PAL-N",
+	"PAL-Nc",
+	"PAL-60",
+	"SECAM-BGH",
+	"SECAM-DK",
+	"SECAM-L",
+	"SECAM-Lc",
+	NULL,
+};
+
+int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *id)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	unsigned int last = dev->query_std_last[dev->input];
+
+	if (!vivid_is_sdtv_cap(dev))
+		return -ENODATA;
+	if (dev->std_signal_mode[dev->input] == NO_SIGNAL ||
+	    dev->std_signal_mode[dev->input] == NO_LOCK) {
+		*id = V4L2_STD_UNKNOWN;
+		return 0;
+	}
+	if (vivid_is_tv_cap(dev) && tpg_g_quality(&dev->tpg) == TPG_QUAL_NOISE) {
+		*id = V4L2_STD_UNKNOWN;
+	} else if (dev->std_signal_mode[dev->input] == CURRENT_STD) {
+		*id = dev->std_cap[dev->input];
+	} else if (dev->std_signal_mode[dev->input] == SELECTED_STD) {
+		*id = dev->query_std[dev->input];
+	} else {
+		*id = vivid_standard[last];
+		dev->query_std_last[dev->input] =
+			(last + 1) % ARRAY_SIZE(vivid_standard);
+	}
+
+	return 0;
+}
+
+int vivid_vid_cap_s_std(struct file *file, void *priv, v4l2_std_id id)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (!vivid_is_sdtv_cap(dev))
+		return -ENODATA;
+	if (dev->std_cap[dev->input] == id)
+		return 0;
+	if (vb2_is_busy(&dev->vb_vid_cap_q) || vb2_is_busy(&dev->vb_vbi_cap_q))
+		return -EBUSY;
+	dev->std_cap[dev->input] = id;
+	vivid_update_format_cap(dev, false);
+	return 0;
+}
+
+static void find_aspect_ratio(u32 width, u32 height,
+			       u32 *num, u32 *denom)
+{
+	if (!(height % 3) && ((height * 4 / 3) == width)) {
+		*num = 4;
+		*denom = 3;
+	} else if (!(height % 9) && ((height * 16 / 9) == width)) {
+		*num = 16;
+		*denom = 9;
+	} else if (!(height % 10) && ((height * 16 / 10) == width)) {
+		*num = 16;
+		*denom = 10;
+	} else if (!(height % 4) && ((height * 5 / 4) == width)) {
+		*num = 5;
+		*denom = 4;
+	} else if (!(height % 9) && ((height * 15 / 9) == width)) {
+		*num = 15;
+		*denom = 9;
+	} else { /* default to 16:9 */
+		*num = 16;
+		*denom = 9;
+	}
+}
+
+static bool valid_cvt_gtf_timings(struct v4l2_dv_timings *timings)
+{
+	struct v4l2_bt_timings *bt = &timings->bt;
+	u32 total_h_pixel;
+	u32 total_v_lines;
+	u32 h_freq;
+
+	if (!v4l2_valid_dv_timings(timings, &vivid_dv_timings_cap,
+				NULL, NULL))
+		return false;
+
+	total_h_pixel = V4L2_DV_BT_FRAME_WIDTH(bt);
+	total_v_lines = V4L2_DV_BT_FRAME_HEIGHT(bt);
+
+	h_freq = (u32)bt->pixelclock / total_h_pixel;
+
+	if (bt->standards == 0 || (bt->standards & V4L2_DV_BT_STD_CVT)) {
+		if (v4l2_detect_cvt(total_v_lines, h_freq, bt->vsync, bt->width,
+				    bt->polarities, bt->interlaced, timings))
+			return true;
+	}
+
+	if (bt->standards == 0 || (bt->standards & V4L2_DV_BT_STD_GTF)) {
+		struct v4l2_fract aspect_ratio;
+
+		find_aspect_ratio(bt->width, bt->height,
+				  &aspect_ratio.numerator,
+				  &aspect_ratio.denominator);
+		if (v4l2_detect_gtf(total_v_lines, h_freq, bt->vsync,
+				    bt->polarities, bt->interlaced,
+				    aspect_ratio, timings))
+			return true;
+	}
+	return false;
+}
+
+int vivid_vid_cap_s_dv_timings(struct file *file, void *_fh,
+				    struct v4l2_dv_timings *timings)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (!vivid_is_hdmi_cap(dev))
+		return -ENODATA;
+	if (!v4l2_find_dv_timings_cap(timings, &vivid_dv_timings_cap,
+				      0, NULL, NULL) &&
+	    !valid_cvt_gtf_timings(timings))
+		return -EINVAL;
+
+	if (v4l2_match_dv_timings(timings, &dev->dv_timings_cap[dev->input],
+				  0, false))
+		return 0;
+	if (vb2_is_busy(&dev->vb_vid_cap_q))
+		return -EBUSY;
+
+	dev->dv_timings_cap[dev->input] = *timings;
+	vivid_update_format_cap(dev, false);
+	return 0;
+}
+
+int vidioc_query_dv_timings(struct file *file, void *_fh,
+				    struct v4l2_dv_timings *timings)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	unsigned int input = dev->input;
+	unsigned int last = dev->query_dv_timings_last[input];
+
+	if (!vivid_is_hdmi_cap(dev))
+		return -ENODATA;
+	if (dev->dv_timings_signal_mode[input] == NO_SIGNAL ||
+	    dev->edid_blocks == 0)
+		return -ENOLINK;
+	if (dev->dv_timings_signal_mode[input] == NO_LOCK)
+		return -ENOLCK;
+	if (dev->dv_timings_signal_mode[input] == OUT_OF_RANGE) {
+		timings->bt.pixelclock = vivid_dv_timings_cap.bt.max_pixelclock * 2;
+		return -ERANGE;
+	}
+	if (dev->dv_timings_signal_mode[input] == CURRENT_DV_TIMINGS) {
+		*timings = dev->dv_timings_cap[input];
+	} else if (dev->dv_timings_signal_mode[input] ==
+		   SELECTED_DV_TIMINGS) {
+		*timings =
+			v4l2_dv_timings_presets[dev->query_dv_timings[input]];
+	} else {
+		*timings =
+			v4l2_dv_timings_presets[last];
+		dev->query_dv_timings_last[input] =
+			(last + 1) % dev->query_dv_timings_size;
+	}
+	return 0;
+}
+
+int vidioc_s_edid(struct file *file, void *_fh,
+			 struct v4l2_edid *edid)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	u16 phys_addr;
+	u32 display_present = 0;
+	unsigned int i, j;
+	int ret;
+
+	memset(edid->reserved, 0, sizeof(edid->reserved));
+	if (edid->pad >= dev->num_inputs)
+		return -EINVAL;
+	if (dev->input_type[edid->pad] != HDMI || edid->start_block)
+		return -EINVAL;
+	if (edid->blocks == 0) {
+		dev->edid_blocks = 0;
+		v4l2_ctrl_s_ctrl(dev->ctrl_tx_edid_present, 0);
+		v4l2_ctrl_s_ctrl(dev->ctrl_tx_hotplug, 0);
+		phys_addr = CEC_PHYS_ADDR_INVALID;
+		goto set_phys_addr;
+	}
+	if (edid->blocks > dev->edid_max_blocks) {
+		edid->blocks = dev->edid_max_blocks;
+		return -E2BIG;
+	}
+	phys_addr = cec_get_edid_phys_addr(edid->edid, edid->blocks * 128, NULL);
+	ret = v4l2_phys_addr_validate(phys_addr, &phys_addr, NULL);
+	if (ret)
+		return ret;
+
+	if (vb2_is_busy(&dev->vb_vid_cap_q))
+		return -EBUSY;
+
+	dev->edid_blocks = edid->blocks;
+	memcpy(dev->edid, edid->edid, edid->blocks * 128);
+
+	for (i = 0, j = 0; i < dev->num_outputs; i++)
+		if (dev->output_type[i] == HDMI)
+			display_present |=
+				dev->display_present[i] << j++;
+
+	v4l2_ctrl_s_ctrl(dev->ctrl_tx_edid_present, display_present);
+	v4l2_ctrl_s_ctrl(dev->ctrl_tx_hotplug, display_present);
+
+set_phys_addr:
+	/* TODO: a proper hotplug detect cycle should be emulated here */
+	cec_s_phys_addr(dev->cec_rx_adap, phys_addr, false);
+
+	for (i = 0; i < MAX_OUTPUTS && dev->cec_tx_adap[i]; i++)
+		cec_s_phys_addr(dev->cec_tx_adap[i],
+				dev->display_present[i] ?
+				v4l2_phys_addr_for_input(phys_addr, i + 1) :
+				CEC_PHYS_ADDR_INVALID,
+				false);
+	return 0;
+}
+
+int vidioc_enum_framesizes(struct file *file, void *fh,
+					 struct v4l2_frmsizeenum *fsize)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (!vivid_is_webcam(dev) && !dev->has_scaler_cap)
+		return -EINVAL;
+	if (vivid_get_format(dev, fsize->pixel_format) == NULL)
+		return -EINVAL;
+	if (vivid_is_webcam(dev)) {
+		if (fsize->index >= ARRAY_SIZE(webcam_sizes))
+			return -EINVAL;
+		fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+		fsize->discrete = webcam_sizes[fsize->index];
+		return 0;
+	}
+	if (fsize->index)
+		return -EINVAL;
+	fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
+	fsize->stepwise.min_width = MIN_WIDTH;
+	fsize->stepwise.max_width = MAX_WIDTH * MAX_ZOOM;
+	fsize->stepwise.step_width = 2;
+	fsize->stepwise.min_height = MIN_HEIGHT;
+	fsize->stepwise.max_height = MAX_HEIGHT * MAX_ZOOM;
+	fsize->stepwise.step_height = 2;
+	return 0;
+}
+
+/* timeperframe is arbitrary and continuous */
+int vidioc_enum_frameintervals(struct file *file, void *priv,
+					     struct v4l2_frmivalenum *fival)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	const struct vivid_fmt *fmt;
+	int i;
+
+	fmt = vivid_get_format(dev, fival->pixel_format);
+	if (!fmt)
+		return -EINVAL;
+
+	if (!vivid_is_webcam(dev)) {
+		if (fival->index)
+			return -EINVAL;
+		if (fival->width < MIN_WIDTH || fival->width > MAX_WIDTH * MAX_ZOOM)
+			return -EINVAL;
+		if (fival->height < MIN_HEIGHT || fival->height > MAX_HEIGHT * MAX_ZOOM)
+			return -EINVAL;
+		fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
+		fival->discrete = dev->timeperframe_vid_cap;
+		return 0;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(webcam_sizes); i++)
+		if (fival->width == webcam_sizes[i].width &&
+		    fival->height == webcam_sizes[i].height)
+			break;
+	if (i == ARRAY_SIZE(webcam_sizes))
+		return -EINVAL;
+	if (fival->index >= 2 * (VIVID_WEBCAM_SIZES - i))
+		return -EINVAL;
+	fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
+	fival->discrete = webcam_intervals[fival->index];
+	return 0;
+}
+
+int vivid_vid_cap_g_parm(struct file *file, void *priv,
+			  struct v4l2_streamparm *parm)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (parm->type != (dev->multiplanar ?
+			   V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
+			   V4L2_BUF_TYPE_VIDEO_CAPTURE))
+		return -EINVAL;
+
+	parm->parm.capture.capability   = V4L2_CAP_TIMEPERFRAME;
+	parm->parm.capture.timeperframe = dev->timeperframe_vid_cap;
+	parm->parm.capture.readbuffers  = 1;
+	return 0;
+}
+
+int vivid_vid_cap_s_parm(struct file *file, void *priv,
+			  struct v4l2_streamparm *parm)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	unsigned ival_sz = 2 * (VIVID_WEBCAM_SIZES - dev->webcam_size_idx);
+	struct v4l2_fract tpf;
+	unsigned i;
+
+	if (parm->type != (dev->multiplanar ?
+			   V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
+			   V4L2_BUF_TYPE_VIDEO_CAPTURE))
+		return -EINVAL;
+	if (!vivid_is_webcam(dev))
+		return vivid_vid_cap_g_parm(file, priv, parm);
+
+	tpf = parm->parm.capture.timeperframe;
+
+	if (tpf.denominator == 0)
+		tpf = webcam_intervals[ival_sz - 1];
+	for (i = 0; i < ival_sz; i++)
+		if (V4L2_FRACT_COMPARE(tpf, >=, webcam_intervals[i]))
+			break;
+	if (i == ival_sz)
+		i = ival_sz - 1;
+	dev->webcam_ival_idx = i;
+	tpf = webcam_intervals[dev->webcam_ival_idx];
+
+	/* resync the thread's timings */
+	dev->cap_seq_resync = true;
+	dev->timeperframe_vid_cap = tpf;
+	parm->parm.capture.capability   = V4L2_CAP_TIMEPERFRAME;
+	parm->parm.capture.timeperframe = tpf;
+	parm->parm.capture.readbuffers  = 1;
+	return 0;
+}
diff --git a/drivers/media/test-drivers/vivid/vivid-vid-cap.h b/drivers/media/test-drivers/vivid/vivid-vid-cap.h
new file mode 100644
index 000000000000..1e422a59eeab
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-vid-cap.h
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * vivid-vid-cap.h - video capture support functions.
+ *
+ * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _VIVID_VID_CAP_H_
+#define _VIVID_VID_CAP_H_
+
+void vivid_update_quality(struct vivid_dev *dev);
+void vivid_update_format_cap(struct vivid_dev *dev, bool keep_controls);
+enum tpg_video_aspect vivid_get_video_aspect(const struct vivid_dev *dev);
+
+extern const v4l2_std_id vivid_standard[];
+extern const char * const vivid_ctrl_standard_strings[];
+
+extern const struct vb2_ops vivid_vid_cap_qops;
+
+int vivid_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f);
+int vivid_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f);
+int vivid_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f);
+int vidioc_g_fmt_vid_cap_mplane(struct file *file, void *priv, struct v4l2_format *f);
+int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv, struct v4l2_format *f);
+int vidioc_s_fmt_vid_cap_mplane(struct file *file, void *priv, struct v4l2_format *f);
+int vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f);
+int vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f);
+int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f);
+int vivid_vid_cap_g_selection(struct file *file, void *priv, struct v4l2_selection *sel);
+int vivid_vid_cap_s_selection(struct file *file, void *fh, struct v4l2_selection *s);
+int vivid_vid_cap_g_pixelaspect(struct file *file, void *priv, int type, struct v4l2_fract *f);
+int vidioc_enum_fmt_vid_overlay(struct file *file, void  *priv, struct v4l2_fmtdesc *f);
+int vidioc_g_fmt_vid_overlay(struct file *file, void *priv, struct v4l2_format *f);
+int vidioc_try_fmt_vid_overlay(struct file *file, void *priv, struct v4l2_format *f);
+int vidioc_s_fmt_vid_overlay(struct file *file, void *priv, struct v4l2_format *f);
+int vivid_vid_cap_overlay(struct file *file, void *fh, unsigned i);
+int vivid_vid_cap_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *a);
+int vivid_vid_cap_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffer *a);
+int vidioc_enum_input(struct file *file, void *priv, struct v4l2_input *inp);
+int vidioc_g_input(struct file *file, void *priv, unsigned *i);
+int vidioc_s_input(struct file *file, void *priv, unsigned i);
+int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin);
+int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *vin);
+int vidioc_s_audio(struct file *file, void *fh, const struct v4l2_audio *vin);
+int vivid_video_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf);
+int vivid_video_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *vf);
+int vivid_video_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt);
+int vivid_video_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt);
+int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *id);
+int vivid_vid_cap_s_std(struct file *file, void *priv, v4l2_std_id id);
+int vivid_vid_cap_s_dv_timings(struct file *file, void *_fh, struct v4l2_dv_timings *timings);
+int vidioc_query_dv_timings(struct file *file, void *_fh, struct v4l2_dv_timings *timings);
+int vidioc_s_edid(struct file *file, void *_fh, struct v4l2_edid *edid);
+int vidioc_enum_framesizes(struct file *file, void *fh, struct v4l2_frmsizeenum *fsize);
+int vidioc_enum_frameintervals(struct file *file, void *priv, struct v4l2_frmivalenum *fival);
+int vivid_vid_cap_g_parm(struct file *file, void *priv, struct v4l2_streamparm *parm);
+int vivid_vid_cap_s_parm(struct file *file, void *priv, struct v4l2_streamparm *parm);
+
+#endif
diff --git a/drivers/media/test-drivers/vivid/vivid-vid-common.c b/drivers/media/test-drivers/vivid/vivid-vid-common.c
new file mode 100644
index 000000000000..76b0be670ebb
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-vid-common.c
@@ -0,0 +1,1035 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * vivid-vid-common.c - common video support functions.
+ *
+ * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/videodev2.h>
+#include <linux/v4l2-dv-timings.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-dv-timings.h>
+
+#include "vivid-core.h"
+#include "vivid-vid-common.h"
+
+const struct v4l2_dv_timings_cap vivid_dv_timings_cap = {
+	.type = V4L2_DV_BT_656_1120,
+	/* keep this initialization for compatibility with GCC < 4.4.6 */
+	.reserved = { 0 },
+	V4L2_INIT_BT_TIMINGS(16, MAX_WIDTH, 16, MAX_HEIGHT, 14000000, 775000000,
+		V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT |
+		V4L2_DV_BT_STD_CVT | V4L2_DV_BT_STD_GTF,
+		V4L2_DV_BT_CAP_PROGRESSIVE | V4L2_DV_BT_CAP_INTERLACED)
+};
+
+/* ------------------------------------------------------------------
+	Basic structures
+   ------------------------------------------------------------------*/
+
+struct vivid_fmt vivid_formats[] = {
+	{
+		.fourcc   = V4L2_PIX_FMT_YUYV,
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.color_enc = TGP_COLOR_ENC_YCBCR,
+		.planes   = 1,
+		.buffers = 1,
+		.data_offset = { PLANE0_DATA_OFFSET },
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_UYVY,
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.color_enc = TGP_COLOR_ENC_YCBCR,
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_YVYU,
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.color_enc = TGP_COLOR_ENC_YCBCR,
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_VYUY,
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.color_enc = TGP_COLOR_ENC_YCBCR,
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_YUV422P,
+		.vdownsampling = { 1, 1, 1 },
+		.bit_depth = { 8, 4, 4 },
+		.color_enc = TGP_COLOR_ENC_YCBCR,
+		.planes   = 3,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_YUV420,
+		.vdownsampling = { 1, 2, 2 },
+		.bit_depth = { 8, 4, 4 },
+		.color_enc = TGP_COLOR_ENC_YCBCR,
+		.planes   = 3,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_YVU420,
+		.vdownsampling = { 1, 2, 2 },
+		.bit_depth = { 8, 4, 4 },
+		.color_enc = TGP_COLOR_ENC_YCBCR,
+		.planes   = 3,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_NV12,
+		.vdownsampling = { 1, 2 },
+		.bit_depth = { 8, 8 },
+		.color_enc = TGP_COLOR_ENC_YCBCR,
+		.planes   = 2,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_NV21,
+		.vdownsampling = { 1, 2 },
+		.bit_depth = { 8, 8 },
+		.color_enc = TGP_COLOR_ENC_YCBCR,
+		.planes   = 2,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_NV16,
+		.vdownsampling = { 1, 1 },
+		.bit_depth = { 8, 8 },
+		.color_enc = TGP_COLOR_ENC_YCBCR,
+		.planes   = 2,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_NV61,
+		.vdownsampling = { 1, 1 },
+		.bit_depth = { 8, 8 },
+		.color_enc = TGP_COLOR_ENC_YCBCR,
+		.planes   = 2,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_NV24,
+		.vdownsampling = { 1, 1 },
+		.bit_depth = { 8, 16 },
+		.color_enc = TGP_COLOR_ENC_YCBCR,
+		.planes   = 2,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_NV42,
+		.vdownsampling = { 1, 1 },
+		.bit_depth = { 8, 16 },
+		.color_enc = TGP_COLOR_ENC_YCBCR,
+		.planes   = 2,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_YUV555, /* uuuvvvvv ayyyyyuu */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+		.alpha_mask = 0x8000,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_YUV565, /* uuuvvvvv yyyyyuuu */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_YUV444, /* uuuuvvvv aaaayyyy */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+		.alpha_mask = 0xf000,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_YUV32, /* ayuv */
+		.vdownsampling = { 1 },
+		.bit_depth = { 32 },
+		.planes   = 1,
+		.buffers = 1,
+		.alpha_mask = 0x000000ff,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_AYUV32,
+		.vdownsampling = { 1 },
+		.bit_depth = { 32 },
+		.planes   = 1,
+		.buffers = 1,
+		.alpha_mask = 0x000000ff,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_XYUV32,
+		.vdownsampling = { 1 },
+		.bit_depth = { 32 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_VUYA32,
+		.vdownsampling = { 1 },
+		.bit_depth = { 32 },
+		.planes   = 1,
+		.buffers = 1,
+		.alpha_mask = 0xff000000,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_VUYX32,
+		.vdownsampling = { 1 },
+		.bit_depth = { 32 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_GREY,
+		.vdownsampling = { 1 },
+		.bit_depth = { 8 },
+		.color_enc = TGP_COLOR_ENC_LUMA,
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_Y10,
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.color_enc = TGP_COLOR_ENC_LUMA,
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_Y12,
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.color_enc = TGP_COLOR_ENC_LUMA,
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_Y16,
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.color_enc = TGP_COLOR_ENC_LUMA,
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_Y16_BE,
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.color_enc = TGP_COLOR_ENC_LUMA,
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_RGB332, /* rrrgggbb */
+		.vdownsampling = { 1 },
+		.bit_depth = { 8 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+		.can_do_overlay = true,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+		.can_do_overlay = true,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_RGB444, /* ggggbbbb xxxxrrrr */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_XRGB444, /* ggggbbbb xxxxrrrr */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_ARGB444, /* ggggbbbb aaaarrrr */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+		.alpha_mask = 0x00f0,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_RGBX444, /* bbbbxxxx rrrrgggg */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_RGBA444, /* bbbbaaaa rrrrgggg */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+		.alpha_mask = 0x00f0,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_XBGR444, /* ggggrrrr xxxxbbbb */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_ABGR444, /* ggggrrrr aaaabbbb */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+		.alpha_mask = 0x00f0,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_BGRX444, /* rrrrxxxx bbbbgggg */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_BGRA444, /* rrrraaaa bbbbgggg  */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+		.alpha_mask = 0x00f0,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_RGB555, /* gggbbbbb xrrrrrgg */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+		.can_do_overlay = true,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_XRGB555, /* gggbbbbb xrrrrrgg */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+		.can_do_overlay = true,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_ARGB555, /* gggbbbbb arrrrrgg */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+		.can_do_overlay = true,
+		.alpha_mask = 0x8000,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_RGBX555, /* ggbbbbbx rrrrrggg */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+		.can_do_overlay = true,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_RGBA555, /* ggbbbbba rrrrrggg */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+		.can_do_overlay = true,
+		.alpha_mask = 0x8000,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_XBGR555, /* gggrrrrr xbbbbbgg */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+		.can_do_overlay = true,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_ABGR555, /* gggrrrrr abbbbbgg */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+		.can_do_overlay = true,
+		.alpha_mask = 0x8000,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_BGRX555, /* ggrrrrrx bbbbbggg */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+		.can_do_overlay = true,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_BGRA555, /* ggrrrrra bbbbbggg */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+		.can_do_overlay = true,
+		.alpha_mask = 0x8000,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_RGB555X, /* xrrrrrgg gggbbbbb */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_XRGB555X, /* xrrrrrgg gggbbbbb */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_ARGB555X, /* arrrrrgg gggbbbbb */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+		.alpha_mask = 0x0080,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_RGB24, /* rgb */
+		.vdownsampling = { 1 },
+		.bit_depth = { 24 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_BGR24, /* bgr */
+		.vdownsampling = { 1 },
+		.bit_depth = { 24 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_BGR666, /* bbbbbbgg ggggrrrr rrxxxxxx */
+		.vdownsampling = { 1 },
+		.bit_depth = { 32 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_RGB32, /* xrgb */
+		.vdownsampling = { 1 },
+		.bit_depth = { 32 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_BGR32, /* bgrx */
+		.vdownsampling = { 1 },
+		.bit_depth = { 32 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_XRGB32, /* xrgb */
+		.vdownsampling = { 1 },
+		.bit_depth = { 32 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_XBGR32, /* bgrx */
+		.vdownsampling = { 1 },
+		.bit_depth = { 32 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_ARGB32, /* argb */
+		.vdownsampling = { 1 },
+		.bit_depth = { 32 },
+		.planes   = 1,
+		.buffers = 1,
+		.alpha_mask = 0x000000ff,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_ABGR32, /* bgra */
+		.vdownsampling = { 1 },
+		.bit_depth = { 32 },
+		.planes   = 1,
+		.buffers = 1,
+		.alpha_mask = 0xff000000,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_RGBX32, /* rgbx */
+		.vdownsampling = { 1 },
+		.bit_depth = { 32 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_BGRX32, /* xbgr */
+		.vdownsampling = { 1 },
+		.bit_depth = { 32 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_RGBA32, /* rgba */
+		.vdownsampling = { 1 },
+		.bit_depth = { 32 },
+		.planes   = 1,
+		.buffers = 1,
+		.alpha_mask = 0x000000ff,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_BGRA32, /* abgr */
+		.vdownsampling = { 1 },
+		.bit_depth = { 32 },
+		.planes   = 1,
+		.buffers = 1,
+		.alpha_mask = 0xff000000,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_SBGGR8, /* Bayer BG/GR */
+		.vdownsampling = { 1 },
+		.bit_depth = { 8 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_SGBRG8, /* Bayer GB/RG */
+		.vdownsampling = { 1 },
+		.bit_depth = { 8 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_SGRBG8, /* Bayer GR/BG */
+		.vdownsampling = { 1 },
+		.bit_depth = { 8 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_SRGGB8, /* Bayer RG/GB */
+		.vdownsampling = { 1 },
+		.bit_depth = { 8 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_SBGGR10, /* Bayer BG/GR */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_SGBRG10, /* Bayer GB/RG */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_SGRBG10, /* Bayer GR/BG */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_SRGGB10, /* Bayer RG/GB */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_SBGGR12, /* Bayer BG/GR */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_SGBRG12, /* Bayer GB/RG */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_SGRBG12, /* Bayer GR/BG */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_SRGGB12, /* Bayer RG/GB */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_SBGGR16, /* Bayer BG/GR */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_SGBRG16, /* Bayer GB/RG */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_SGRBG16, /* Bayer GR/BG */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_SRGGB16, /* Bayer RG/GB */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_HSV24, /* HSV 24bits */
+		.color_enc = TGP_COLOR_ENC_HSV,
+		.vdownsampling = { 1 },
+		.bit_depth = { 24 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_HSV32, /* HSV 32bits */
+		.color_enc = TGP_COLOR_ENC_HSV,
+		.vdownsampling = { 1 },
+		.bit_depth = { 32 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+
+	/* Multiplanar formats */
+
+	{
+		.fourcc   = V4L2_PIX_FMT_NV16M,
+		.vdownsampling = { 1, 1 },
+		.bit_depth = { 8, 8 },
+		.color_enc = TGP_COLOR_ENC_YCBCR,
+		.planes   = 2,
+		.buffers = 2,
+		.data_offset = { PLANE0_DATA_OFFSET, 0 },
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_NV61M,
+		.vdownsampling = { 1, 1 },
+		.bit_depth = { 8, 8 },
+		.color_enc = TGP_COLOR_ENC_YCBCR,
+		.planes   = 2,
+		.buffers = 2,
+		.data_offset = { 0, PLANE0_DATA_OFFSET },
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_YUV420M,
+		.vdownsampling = { 1, 2, 2 },
+		.bit_depth = { 8, 4, 4 },
+		.color_enc = TGP_COLOR_ENC_YCBCR,
+		.planes   = 3,
+		.buffers = 3,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_YVU420M,
+		.vdownsampling = { 1, 2, 2 },
+		.bit_depth = { 8, 4, 4 },
+		.color_enc = TGP_COLOR_ENC_YCBCR,
+		.planes   = 3,
+		.buffers = 3,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_NV12M,
+		.vdownsampling = { 1, 2 },
+		.bit_depth = { 8, 8 },
+		.color_enc = TGP_COLOR_ENC_YCBCR,
+		.planes   = 2,
+		.buffers = 2,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_NV21M,
+		.vdownsampling = { 1, 2 },
+		.bit_depth = { 8, 8 },
+		.color_enc = TGP_COLOR_ENC_YCBCR,
+		.planes   = 2,
+		.buffers = 2,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_YUV422M,
+		.vdownsampling = { 1, 1, 1 },
+		.bit_depth = { 8, 4, 4 },
+		.color_enc = TGP_COLOR_ENC_YCBCR,
+		.planes   = 3,
+		.buffers = 3,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_YVU422M,
+		.vdownsampling = { 1, 1, 1 },
+		.bit_depth = { 8, 4, 4 },
+		.color_enc = TGP_COLOR_ENC_YCBCR,
+		.planes   = 3,
+		.buffers = 3,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_YUV444M,
+		.vdownsampling = { 1, 1, 1 },
+		.bit_depth = { 8, 8, 8 },
+		.color_enc = TGP_COLOR_ENC_YCBCR,
+		.planes   = 3,
+		.buffers = 3,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_YVU444M,
+		.vdownsampling = { 1, 1, 1 },
+		.bit_depth = { 8, 8, 8 },
+		.color_enc = TGP_COLOR_ENC_YCBCR,
+		.planes   = 3,
+		.buffers = 3,
+	},
+};
+
+/* There are this many multiplanar formats in the list */
+#define VIVID_MPLANAR_FORMATS 10
+
+const struct vivid_fmt *vivid_get_format(struct vivid_dev *dev, u32 pixelformat)
+{
+	const struct vivid_fmt *fmt;
+	unsigned k;
+
+	for (k = 0; k < ARRAY_SIZE(vivid_formats); k++) {
+		fmt = &vivid_formats[k];
+		if (fmt->fourcc == pixelformat)
+			if (fmt->buffers == 1 || dev->multiplanar)
+				return fmt;
+	}
+
+	return NULL;
+}
+
+bool vivid_vid_can_loop(struct vivid_dev *dev)
+{
+	if (dev->src_rect.width != dev->sink_rect.width ||
+	    dev->src_rect.height != dev->sink_rect.height)
+		return false;
+	if (dev->fmt_cap->fourcc != dev->fmt_out->fourcc)
+		return false;
+	if (dev->field_cap != dev->field_out)
+		return false;
+	/*
+	 * While this can be supported, it is just too much work
+	 * to actually implement.
+	 */
+	if (dev->field_cap == V4L2_FIELD_SEQ_TB ||
+	    dev->field_cap == V4L2_FIELD_SEQ_BT)
+		return false;
+	if (vivid_is_svid_cap(dev) && vivid_is_svid_out(dev)) {
+		if (!(dev->std_cap[dev->input] & V4L2_STD_525_60) !=
+		    !(dev->std_out & V4L2_STD_525_60))
+			return false;
+		return true;
+	}
+	if (vivid_is_hdmi_cap(dev) && vivid_is_hdmi_out(dev))
+		return true;
+	return false;
+}
+
+void vivid_send_source_change(struct vivid_dev *dev, unsigned type)
+{
+	struct v4l2_event ev = {
+		.type = V4L2_EVENT_SOURCE_CHANGE,
+		.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION,
+	};
+	unsigned i;
+
+	for (i = 0; i < dev->num_inputs; i++) {
+		ev.id = i;
+		if (dev->input_type[i] == type) {
+			if (video_is_registered(&dev->vid_cap_dev) && dev->has_vid_cap)
+				v4l2_event_queue(&dev->vid_cap_dev, &ev);
+			if (video_is_registered(&dev->vbi_cap_dev) && dev->has_vbi_cap)
+				v4l2_event_queue(&dev->vbi_cap_dev, &ev);
+		}
+	}
+}
+
+/*
+ * Conversion function that converts a single-planar format to a
+ * single-plane multiplanar format.
+ */
+void fmt_sp2mp(const struct v4l2_format *sp_fmt, struct v4l2_format *mp_fmt)
+{
+	struct v4l2_pix_format_mplane *mp = &mp_fmt->fmt.pix_mp;
+	struct v4l2_plane_pix_format *ppix = &mp->plane_fmt[0];
+	const struct v4l2_pix_format *pix = &sp_fmt->fmt.pix;
+	bool is_out = sp_fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT;
+
+	memset(mp->reserved, 0, sizeof(mp->reserved));
+	mp_fmt->type = is_out ? V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE :
+			   V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+	mp->width = pix->width;
+	mp->height = pix->height;
+	mp->pixelformat = pix->pixelformat;
+	mp->field = pix->field;
+	mp->colorspace = pix->colorspace;
+	mp->xfer_func = pix->xfer_func;
+	/* Also copies hsv_enc */
+	mp->ycbcr_enc = pix->ycbcr_enc;
+	mp->quantization = pix->quantization;
+	mp->num_planes = 1;
+	mp->flags = pix->flags;
+	ppix->sizeimage = pix->sizeimage;
+	ppix->bytesperline = pix->bytesperline;
+	memset(ppix->reserved, 0, sizeof(ppix->reserved));
+}
+
+int fmt_sp2mp_func(struct file *file, void *priv,
+		struct v4l2_format *f, fmtfunc func)
+{
+	struct v4l2_format fmt;
+	struct v4l2_pix_format_mplane *mp = &fmt.fmt.pix_mp;
+	struct v4l2_plane_pix_format *ppix = &mp->plane_fmt[0];
+	struct v4l2_pix_format *pix = &f->fmt.pix;
+	int ret;
+
+	/* Converts to a mplane format */
+	fmt_sp2mp(f, &fmt);
+	/* Passes it to the generic mplane format function */
+	ret = func(file, priv, &fmt);
+	/* Copies back the mplane data to the single plane format */
+	pix->width = mp->width;
+	pix->height = mp->height;
+	pix->pixelformat = mp->pixelformat;
+	pix->field = mp->field;
+	pix->colorspace = mp->colorspace;
+	pix->xfer_func = mp->xfer_func;
+	/* Also copies hsv_enc */
+	pix->ycbcr_enc = mp->ycbcr_enc;
+	pix->quantization = mp->quantization;
+	pix->sizeimage = ppix->sizeimage;
+	pix->bytesperline = ppix->bytesperline;
+	pix->flags = mp->flags;
+	return ret;
+}
+
+int vivid_vid_adjust_sel(unsigned flags, struct v4l2_rect *r)
+{
+	unsigned w = r->width;
+	unsigned h = r->height;
+
+	/* sanitize w and h in case someone passes ~0 as the value */
+	w &= 0xffff;
+	h &= 0xffff;
+	if (!(flags & V4L2_SEL_FLAG_LE)) {
+		w++;
+		h++;
+		if (w < 2)
+			w = 2;
+		if (h < 2)
+			h = 2;
+	}
+	if (!(flags & V4L2_SEL_FLAG_GE)) {
+		if (w > MAX_WIDTH)
+			w = MAX_WIDTH;
+		if (h > MAX_HEIGHT)
+			h = MAX_HEIGHT;
+	}
+	w = w & ~1;
+	h = h & ~1;
+	if (w < 2 || h < 2)
+		return -ERANGE;
+	if (w > MAX_WIDTH || h > MAX_HEIGHT)
+		return -ERANGE;
+	if (r->top < 0)
+		r->top = 0;
+	if (r->left < 0)
+		r->left = 0;
+	/* sanitize left and top in case someone passes ~0 as the value */
+	r->left &= 0xfffe;
+	r->top &= 0xfffe;
+	if (r->left + w > MAX_WIDTH)
+		r->left = MAX_WIDTH - w;
+	if (r->top + h > MAX_HEIGHT)
+		r->top = MAX_HEIGHT - h;
+	if ((flags & (V4L2_SEL_FLAG_GE | V4L2_SEL_FLAG_LE)) ==
+			(V4L2_SEL_FLAG_GE | V4L2_SEL_FLAG_LE) &&
+	    (r->width != w || r->height != h))
+		return -ERANGE;
+	r->width = w;
+	r->height = h;
+	return 0;
+}
+
+int vivid_enum_fmt_vid(struct file *file, void  *priv,
+					struct v4l2_fmtdesc *f)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	const struct vivid_fmt *fmt;
+
+	if (f->index >= ARRAY_SIZE(vivid_formats) -
+	    (dev->multiplanar ? 0 : VIVID_MPLANAR_FORMATS))
+		return -EINVAL;
+
+	fmt = &vivid_formats[f->index];
+
+	f->pixelformat = fmt->fourcc;
+	return 0;
+}
+
+int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	struct video_device *vdev = video_devdata(file);
+
+	if (vdev->vfl_dir == VFL_DIR_RX) {
+		if (!vivid_is_sdtv_cap(dev))
+			return -ENODATA;
+		*id = dev->std_cap[dev->input];
+	} else {
+		if (!vivid_is_svid_out(dev))
+			return -ENODATA;
+		*id = dev->std_out;
+	}
+	return 0;
+}
+
+int vidioc_g_dv_timings(struct file *file, void *_fh,
+				    struct v4l2_dv_timings *timings)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	struct video_device *vdev = video_devdata(file);
+
+	if (vdev->vfl_dir == VFL_DIR_RX) {
+		if (!vivid_is_hdmi_cap(dev))
+			return -ENODATA;
+		*timings = dev->dv_timings_cap[dev->input];
+	} else {
+		if (!vivid_is_hdmi_out(dev))
+			return -ENODATA;
+		*timings = dev->dv_timings_out;
+	}
+	return 0;
+}
+
+int vidioc_enum_dv_timings(struct file *file, void *_fh,
+				    struct v4l2_enum_dv_timings *timings)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	struct video_device *vdev = video_devdata(file);
+
+	if (vdev->vfl_dir == VFL_DIR_RX) {
+		if (!vivid_is_hdmi_cap(dev))
+			return -ENODATA;
+	} else {
+		if (!vivid_is_hdmi_out(dev))
+			return -ENODATA;
+	}
+	return v4l2_enum_dv_timings_cap(timings, &vivid_dv_timings_cap,
+			NULL, NULL);
+}
+
+int vidioc_dv_timings_cap(struct file *file, void *_fh,
+				    struct v4l2_dv_timings_cap *cap)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	struct video_device *vdev = video_devdata(file);
+
+	if (vdev->vfl_dir == VFL_DIR_RX) {
+		if (!vivid_is_hdmi_cap(dev))
+			return -ENODATA;
+	} else {
+		if (!vivid_is_hdmi_out(dev))
+			return -ENODATA;
+	}
+	*cap = vivid_dv_timings_cap;
+	return 0;
+}
+
+int vidioc_g_edid(struct file *file, void *_fh,
+			 struct v4l2_edid *edid)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	struct video_device *vdev = video_devdata(file);
+	struct cec_adapter *adap;
+
+	memset(edid->reserved, 0, sizeof(edid->reserved));
+	if (vdev->vfl_dir == VFL_DIR_RX) {
+		if (edid->pad >= dev->num_inputs)
+			return -EINVAL;
+		if (dev->input_type[edid->pad] != HDMI)
+			return -EINVAL;
+		adap = dev->cec_rx_adap;
+	} else {
+		unsigned int bus_idx;
+
+		if (edid->pad >= dev->num_outputs)
+			return -EINVAL;
+		if (dev->output_type[edid->pad] != HDMI)
+			return -EINVAL;
+		if (!dev->display_present[edid->pad])
+			return -ENODATA;
+		bus_idx = dev->cec_output2bus_map[edid->pad];
+		adap = dev->cec_tx_adap[bus_idx];
+	}
+	if (edid->start_block == 0 && edid->blocks == 0) {
+		edid->blocks = dev->edid_blocks;
+		return 0;
+	}
+	if (dev->edid_blocks == 0)
+		return -ENODATA;
+	if (edid->start_block >= dev->edid_blocks)
+		return -EINVAL;
+	if (edid->blocks > dev->edid_blocks - edid->start_block)
+		edid->blocks = dev->edid_blocks - edid->start_block;
+	if (adap)
+		v4l2_set_edid_phys_addr(dev->edid, dev->edid_blocks * 128, adap->phys_addr);
+	memcpy(edid->edid, dev->edid + edid->start_block * 128, edid->blocks * 128);
+	return 0;
+}
diff --git a/drivers/media/test-drivers/vivid/vivid-vid-common.h b/drivers/media/test-drivers/vivid/vivid-vid-common.h
new file mode 100644
index 000000000000..d908d9725283
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-vid-common.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * vivid-vid-common.h - common video support functions.
+ *
+ * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _VIVID_VID_COMMON_H_
+#define _VIVID_VID_COMMON_H_
+
+typedef int (*fmtfunc)(struct file *file, void *priv, struct v4l2_format *f);
+
+/*
+ * Conversion function that converts a single-planar format to a
+ * single-plane multiplanar format.
+ */
+void fmt_sp2mp(const struct v4l2_format *sp_fmt, struct v4l2_format *mp_fmt);
+int fmt_sp2mp_func(struct file *file, void *priv,
+		struct v4l2_format *f, fmtfunc func);
+
+extern const struct v4l2_dv_timings_cap vivid_dv_timings_cap;
+
+const struct vivid_fmt *vivid_get_format(struct vivid_dev *dev, u32 pixelformat);
+
+bool vivid_vid_can_loop(struct vivid_dev *dev);
+void vivid_send_source_change(struct vivid_dev *dev, unsigned type);
+
+int vivid_vid_adjust_sel(unsigned flags, struct v4l2_rect *r);
+
+int vivid_enum_fmt_vid(struct file *file, void  *priv, struct v4l2_fmtdesc *f);
+int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id);
+int vidioc_g_dv_timings(struct file *file, void *_fh, struct v4l2_dv_timings *timings);
+int vidioc_enum_dv_timings(struct file *file, void *_fh, struct v4l2_enum_dv_timings *timings);
+int vidioc_dv_timings_cap(struct file *file, void *_fh, struct v4l2_dv_timings_cap *cap);
+int vidioc_g_edid(struct file *file, void *_fh, struct v4l2_edid *edid);
+int vidioc_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub);
+
+#endif
diff --git a/drivers/media/test-drivers/vivid/vivid-vid-out.c b/drivers/media/test-drivers/vivid/vivid-vid-out.c
new file mode 100644
index 000000000000..ee3446e3217c
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-vid-out.c
@@ -0,0 +1,1210 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * vivid-vid-out.c - video output support functions.
+ *
+ * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/videodev2.h>
+#include <linux/v4l2-dv-timings.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-dv-timings.h>
+#include <media/v4l2-rect.h>
+
+#include "vivid-core.h"
+#include "vivid-vid-common.h"
+#include "vivid-kthread-out.h"
+#include "vivid-vid-out.h"
+
+static int vid_out_queue_setup(struct vb2_queue *vq,
+		       unsigned *nbuffers, unsigned *nplanes,
+		       unsigned sizes[], struct device *alloc_devs[])
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vq);
+	const struct vivid_fmt *vfmt = dev->fmt_out;
+	unsigned planes = vfmt->buffers;
+	unsigned h = dev->fmt_out_rect.height;
+	unsigned int size = dev->bytesperline_out[0] * h + vfmt->data_offset[0];
+	unsigned p;
+
+	for (p = vfmt->buffers; p < vfmt->planes; p++)
+		size += dev->bytesperline_out[p] * h / vfmt->vdownsampling[p] +
+			vfmt->data_offset[p];
+
+	if (dev->field_out == V4L2_FIELD_ALTERNATE) {
+		/*
+		 * You cannot use write() with FIELD_ALTERNATE since the field
+		 * information (TOP/BOTTOM) cannot be passed to the kernel.
+		 */
+		if (vb2_fileio_is_active(vq))
+			return -EINVAL;
+	}
+
+	if (dev->queue_setup_error) {
+		/*
+		 * Error injection: test what happens if queue_setup() returns
+		 * an error.
+		 */
+		dev->queue_setup_error = false;
+		return -EINVAL;
+	}
+
+	if (*nplanes) {
+		/*
+		 * Check if the number of requested planes match
+		 * the number of planes in the current format. You can't mix that.
+		 */
+		if (*nplanes != planes)
+			return -EINVAL;
+		if (sizes[0] < size)
+			return -EINVAL;
+		for (p = 1; p < planes; p++) {
+			if (sizes[p] < dev->bytesperline_out[p] * h +
+				       vfmt->data_offset[p])
+				return -EINVAL;
+		}
+	} else {
+		for (p = 0; p < planes; p++)
+			sizes[p] = p ? dev->bytesperline_out[p] * h +
+				       vfmt->data_offset[p] : size;
+	}
+
+	if (vq->num_buffers + *nbuffers < 2)
+		*nbuffers = 2 - vq->num_buffers;
+
+	*nplanes = planes;
+
+	dprintk(dev, 1, "%s: count=%d\n", __func__, *nbuffers);
+	for (p = 0; p < planes; p++)
+		dprintk(dev, 1, "%s: size[%u]=%u\n", __func__, p, sizes[p]);
+	return 0;
+}
+
+static int vid_out_buf_out_validate(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
+
+	dprintk(dev, 1, "%s\n", __func__);
+
+	if (dev->field_out != V4L2_FIELD_ALTERNATE)
+		vbuf->field = dev->field_out;
+	else if (vbuf->field != V4L2_FIELD_TOP &&
+		 vbuf->field != V4L2_FIELD_BOTTOM)
+		return -EINVAL;
+	return 0;
+}
+
+static int vid_out_buf_prepare(struct vb2_buffer *vb)
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
+	const struct vivid_fmt *vfmt = dev->fmt_out;
+	unsigned int planes = vfmt->buffers;
+	unsigned int h = dev->fmt_out_rect.height;
+	unsigned int size = dev->bytesperline_out[0] * h;
+	unsigned p;
+
+	for (p = vfmt->buffers; p < vfmt->planes; p++)
+		size += dev->bytesperline_out[p] * h / vfmt->vdownsampling[p];
+
+	dprintk(dev, 1, "%s\n", __func__);
+
+	if (WARN_ON(NULL == dev->fmt_out))
+		return -EINVAL;
+
+	if (dev->buf_prepare_error) {
+		/*
+		 * Error injection: test what happens if buf_prepare() returns
+		 * an error.
+		 */
+		dev->buf_prepare_error = false;
+		return -EINVAL;
+	}
+
+	for (p = 0; p < planes; p++) {
+		if (p)
+			size = dev->bytesperline_out[p] * h;
+		size += vb->planes[p].data_offset;
+
+		if (vb2_get_plane_payload(vb, p) < size) {
+			dprintk(dev, 1, "%s the payload is too small for plane %u (%lu < %u)\n",
+					__func__, p, vb2_get_plane_payload(vb, p), size);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+static void vid_out_buf_queue(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
+	struct vivid_buffer *buf = container_of(vbuf, struct vivid_buffer, vb);
+
+	dprintk(dev, 1, "%s\n", __func__);
+
+	spin_lock(&dev->slock);
+	list_add_tail(&buf->list, &dev->vid_out_active);
+	spin_unlock(&dev->slock);
+}
+
+static int vid_out_start_streaming(struct vb2_queue *vq, unsigned count)
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vq);
+	int err;
+
+	if (vb2_is_streaming(&dev->vb_vid_cap_q))
+		dev->can_loop_video = vivid_vid_can_loop(dev);
+
+	dev->vid_out_seq_count = 0;
+	dprintk(dev, 1, "%s\n", __func__);
+	if (dev->start_streaming_error) {
+		dev->start_streaming_error = false;
+		err = -EINVAL;
+	} else {
+		err = vivid_start_generating_vid_out(dev, &dev->vid_out_streaming);
+	}
+	if (err) {
+		struct vivid_buffer *buf, *tmp;
+
+		list_for_each_entry_safe(buf, tmp, &dev->vid_out_active, list) {
+			list_del(&buf->list);
+			vb2_buffer_done(&buf->vb.vb2_buf,
+					VB2_BUF_STATE_QUEUED);
+		}
+	}
+	return err;
+}
+
+/* abort streaming and wait for last buffer */
+static void vid_out_stop_streaming(struct vb2_queue *vq)
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vq);
+
+	dprintk(dev, 1, "%s\n", __func__);
+	vivid_stop_generating_vid_out(dev, &dev->vid_out_streaming);
+	dev->can_loop_video = false;
+}
+
+static void vid_out_buf_request_complete(struct vb2_buffer *vb)
+{
+	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
+
+	v4l2_ctrl_request_complete(vb->req_obj.req, &dev->ctrl_hdl_vid_out);
+}
+
+const struct vb2_ops vivid_vid_out_qops = {
+	.queue_setup		= vid_out_queue_setup,
+	.buf_out_validate		= vid_out_buf_out_validate,
+	.buf_prepare		= vid_out_buf_prepare,
+	.buf_queue		= vid_out_buf_queue,
+	.start_streaming	= vid_out_start_streaming,
+	.stop_streaming		= vid_out_stop_streaming,
+	.buf_request_complete	= vid_out_buf_request_complete,
+	.wait_prepare		= vb2_ops_wait_prepare,
+	.wait_finish		= vb2_ops_wait_finish,
+};
+
+/*
+ * Called whenever the format has to be reset which can occur when
+ * changing outputs, standard, timings, etc.
+ */
+void vivid_update_format_out(struct vivid_dev *dev)
+{
+	struct v4l2_bt_timings *bt = &dev->dv_timings_out.bt;
+	unsigned size, p;
+	u64 pixelclock;
+
+	switch (dev->output_type[dev->output]) {
+	case SVID:
+	default:
+		dev->field_out = dev->tv_field_out;
+		dev->sink_rect.width = 720;
+		if (dev->std_out & V4L2_STD_525_60) {
+			dev->sink_rect.height = 480;
+			dev->timeperframe_vid_out = (struct v4l2_fract) { 1001, 30000 };
+			dev->service_set_out = V4L2_SLICED_CAPTION_525;
+		} else {
+			dev->sink_rect.height = 576;
+			dev->timeperframe_vid_out = (struct v4l2_fract) { 1000, 25000 };
+			dev->service_set_out = V4L2_SLICED_WSS_625 | V4L2_SLICED_TELETEXT_B;
+		}
+		dev->colorspace_out = V4L2_COLORSPACE_SMPTE170M;
+		break;
+	case HDMI:
+		dev->sink_rect.width = bt->width;
+		dev->sink_rect.height = bt->height;
+		size = V4L2_DV_BT_FRAME_WIDTH(bt) * V4L2_DV_BT_FRAME_HEIGHT(bt);
+
+		if (can_reduce_fps(bt) && (bt->flags & V4L2_DV_FL_REDUCED_FPS))
+			pixelclock = div_u64(bt->pixelclock * 1000, 1001);
+		else
+			pixelclock = bt->pixelclock;
+
+		dev->timeperframe_vid_out = (struct v4l2_fract) {
+			size / 100, (u32)pixelclock / 100
+		};
+		if (bt->interlaced)
+			dev->field_out = V4L2_FIELD_ALTERNATE;
+		else
+			dev->field_out = V4L2_FIELD_NONE;
+		if (!dev->dvi_d_out && (bt->flags & V4L2_DV_FL_IS_CE_VIDEO)) {
+			if (bt->width == 720 && bt->height <= 576)
+				dev->colorspace_out = V4L2_COLORSPACE_SMPTE170M;
+			else
+				dev->colorspace_out = V4L2_COLORSPACE_REC709;
+		} else {
+			dev->colorspace_out = V4L2_COLORSPACE_SRGB;
+		}
+		break;
+	}
+	dev->xfer_func_out = V4L2_XFER_FUNC_DEFAULT;
+	dev->ycbcr_enc_out = V4L2_YCBCR_ENC_DEFAULT;
+	dev->hsv_enc_out = V4L2_HSV_ENC_180;
+	dev->quantization_out = V4L2_QUANTIZATION_DEFAULT;
+	dev->compose_out = dev->sink_rect;
+	dev->compose_bounds_out = dev->sink_rect;
+	dev->crop_out = dev->compose_out;
+	if (V4L2_FIELD_HAS_T_OR_B(dev->field_out))
+		dev->crop_out.height /= 2;
+	dev->fmt_out_rect = dev->crop_out;
+	for (p = 0; p < dev->fmt_out->planes; p++)
+		dev->bytesperline_out[p] =
+			(dev->sink_rect.width * dev->fmt_out->bit_depth[p]) / 8;
+}
+
+/* Map the field to something that is valid for the current output */
+static enum v4l2_field vivid_field_out(struct vivid_dev *dev, enum v4l2_field field)
+{
+	if (vivid_is_svid_out(dev)) {
+		switch (field) {
+		case V4L2_FIELD_INTERLACED_TB:
+		case V4L2_FIELD_INTERLACED_BT:
+		case V4L2_FIELD_SEQ_TB:
+		case V4L2_FIELD_SEQ_BT:
+		case V4L2_FIELD_ALTERNATE:
+			return field;
+		case V4L2_FIELD_INTERLACED:
+		default:
+			return V4L2_FIELD_INTERLACED;
+		}
+	}
+	if (vivid_is_hdmi_out(dev))
+		return dev->dv_timings_out.bt.interlaced ? V4L2_FIELD_ALTERNATE :
+						       V4L2_FIELD_NONE;
+	return V4L2_FIELD_NONE;
+}
+
+static enum tpg_pixel_aspect vivid_get_pixel_aspect(const struct vivid_dev *dev)
+{
+	if (vivid_is_svid_out(dev))
+		return (dev->std_out & V4L2_STD_525_60) ?
+			TPG_PIXEL_ASPECT_NTSC : TPG_PIXEL_ASPECT_PAL;
+
+	if (vivid_is_hdmi_out(dev) &&
+	    dev->sink_rect.width == 720 && dev->sink_rect.height <= 576)
+		return dev->sink_rect.height == 480 ?
+			TPG_PIXEL_ASPECT_NTSC : TPG_PIXEL_ASPECT_PAL;
+
+	return TPG_PIXEL_ASPECT_SQUARE;
+}
+
+int vivid_g_fmt_vid_out(struct file *file, void *priv,
+					struct v4l2_format *f)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	struct v4l2_pix_format_mplane *mp = &f->fmt.pix_mp;
+	const struct vivid_fmt *fmt = dev->fmt_out;
+	unsigned p;
+
+	mp->width        = dev->fmt_out_rect.width;
+	mp->height       = dev->fmt_out_rect.height;
+	mp->field        = dev->field_out;
+	mp->pixelformat  = fmt->fourcc;
+	mp->colorspace   = dev->colorspace_out;
+	mp->xfer_func    = dev->xfer_func_out;
+	mp->ycbcr_enc    = dev->ycbcr_enc_out;
+	mp->quantization = dev->quantization_out;
+	mp->num_planes = fmt->buffers;
+	for (p = 0; p < mp->num_planes; p++) {
+		mp->plane_fmt[p].bytesperline = dev->bytesperline_out[p];
+		mp->plane_fmt[p].sizeimage =
+			mp->plane_fmt[p].bytesperline * mp->height +
+			fmt->data_offset[p];
+	}
+	for (p = fmt->buffers; p < fmt->planes; p++) {
+		unsigned stride = dev->bytesperline_out[p];
+
+		mp->plane_fmt[0].sizeimage +=
+			(stride * mp->height) / fmt->vdownsampling[p];
+	}
+	return 0;
+}
+
+int vivid_try_fmt_vid_out(struct file *file, void *priv,
+			struct v4l2_format *f)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	struct v4l2_bt_timings *bt = &dev->dv_timings_out.bt;
+	struct v4l2_pix_format_mplane *mp = &f->fmt.pix_mp;
+	struct v4l2_plane_pix_format *pfmt = mp->plane_fmt;
+	const struct vivid_fmt *fmt;
+	unsigned bytesperline, max_bpl;
+	unsigned factor = 1;
+	unsigned w, h;
+	unsigned p;
+
+	fmt = vivid_get_format(dev, mp->pixelformat);
+	if (!fmt) {
+		dprintk(dev, 1, "Fourcc format (0x%08x) unknown.\n",
+			mp->pixelformat);
+		mp->pixelformat = V4L2_PIX_FMT_YUYV;
+		fmt = vivid_get_format(dev, mp->pixelformat);
+	}
+
+	mp->field = vivid_field_out(dev, mp->field);
+	if (vivid_is_svid_out(dev)) {
+		w = 720;
+		h = (dev->std_out & V4L2_STD_525_60) ? 480 : 576;
+	} else {
+		w = dev->sink_rect.width;
+		h = dev->sink_rect.height;
+	}
+	if (V4L2_FIELD_HAS_T_OR_B(mp->field))
+		factor = 2;
+	if (!dev->has_scaler_out && !dev->has_crop_out && !dev->has_compose_out) {
+		mp->width = w;
+		mp->height = h / factor;
+	} else {
+		struct v4l2_rect r = { 0, 0, mp->width, mp->height * factor };
+
+		v4l2_rect_set_min_size(&r, &vivid_min_rect);
+		v4l2_rect_set_max_size(&r, &vivid_max_rect);
+		if (dev->has_scaler_out && !dev->has_crop_out) {
+			struct v4l2_rect max_r = { 0, 0, MAX_ZOOM * w, MAX_ZOOM * h };
+
+			v4l2_rect_set_max_size(&r, &max_r);
+		} else if (!dev->has_scaler_out && dev->has_compose_out && !dev->has_crop_out) {
+			v4l2_rect_set_max_size(&r, &dev->sink_rect);
+		} else if (!dev->has_scaler_out && !dev->has_compose_out) {
+			v4l2_rect_set_min_size(&r, &dev->sink_rect);
+		}
+		mp->width = r.width;
+		mp->height = r.height / factor;
+	}
+
+	/* This driver supports custom bytesperline values */
+
+	mp->num_planes = fmt->buffers;
+	for (p = 0; p < fmt->buffers; p++) {
+		/* Calculate the minimum supported bytesperline value */
+		bytesperline = (mp->width * fmt->bit_depth[p]) >> 3;
+		/* Calculate the maximum supported bytesperline value */
+		max_bpl = (MAX_ZOOM * MAX_WIDTH * fmt->bit_depth[p]) >> 3;
+
+		if (pfmt[p].bytesperline > max_bpl)
+			pfmt[p].bytesperline = max_bpl;
+		if (pfmt[p].bytesperline < bytesperline)
+			pfmt[p].bytesperline = bytesperline;
+
+		pfmt[p].sizeimage = (pfmt[p].bytesperline * mp->height) /
+				fmt->vdownsampling[p] + fmt->data_offset[p];
+
+		memset(pfmt[p].reserved, 0, sizeof(pfmt[p].reserved));
+	}
+	for (p = fmt->buffers; p < fmt->planes; p++)
+		pfmt[0].sizeimage += (pfmt[0].bytesperline * mp->height *
+			(fmt->bit_depth[p] / fmt->vdownsampling[p])) /
+			(fmt->bit_depth[0] / fmt->vdownsampling[0]);
+
+	mp->xfer_func = V4L2_XFER_FUNC_DEFAULT;
+	mp->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+	mp->quantization = V4L2_QUANTIZATION_DEFAULT;
+	if (vivid_is_svid_out(dev)) {
+		mp->colorspace = V4L2_COLORSPACE_SMPTE170M;
+	} else if (dev->dvi_d_out || !(bt->flags & V4L2_DV_FL_IS_CE_VIDEO)) {
+		mp->colorspace = V4L2_COLORSPACE_SRGB;
+		if (dev->dvi_d_out)
+			mp->quantization = V4L2_QUANTIZATION_LIM_RANGE;
+	} else if (bt->width == 720 && bt->height <= 576) {
+		mp->colorspace = V4L2_COLORSPACE_SMPTE170M;
+	} else if (mp->colorspace != V4L2_COLORSPACE_SMPTE170M &&
+		   mp->colorspace != V4L2_COLORSPACE_REC709 &&
+		   mp->colorspace != V4L2_COLORSPACE_OPRGB &&
+		   mp->colorspace != V4L2_COLORSPACE_BT2020 &&
+		   mp->colorspace != V4L2_COLORSPACE_SRGB) {
+		mp->colorspace = V4L2_COLORSPACE_REC709;
+	}
+	memset(mp->reserved, 0, sizeof(mp->reserved));
+	return 0;
+}
+
+int vivid_s_fmt_vid_out(struct file *file, void *priv,
+					struct v4l2_format *f)
+{
+	struct v4l2_pix_format_mplane *mp = &f->fmt.pix_mp;
+	struct vivid_dev *dev = video_drvdata(file);
+	struct v4l2_rect *crop = &dev->crop_out;
+	struct v4l2_rect *compose = &dev->compose_out;
+	struct vb2_queue *q = &dev->vb_vid_out_q;
+	int ret = vivid_try_fmt_vid_out(file, priv, f);
+	unsigned factor = 1;
+	unsigned p;
+
+	if (ret < 0)
+		return ret;
+
+	if (vb2_is_busy(q) &&
+	    (vivid_is_svid_out(dev) ||
+	     mp->width != dev->fmt_out_rect.width ||
+	     mp->height != dev->fmt_out_rect.height ||
+	     mp->pixelformat != dev->fmt_out->fourcc ||
+	     mp->field != dev->field_out)) {
+		dprintk(dev, 1, "%s device busy\n", __func__);
+		return -EBUSY;
+	}
+
+	/*
+	 * Allow for changing the colorspace on the fly. Useful for testing
+	 * purposes, and it is something that HDMI transmitters are able
+	 * to do.
+	 */
+	if (vb2_is_busy(q))
+		goto set_colorspace;
+
+	dev->fmt_out = vivid_get_format(dev, mp->pixelformat);
+	if (V4L2_FIELD_HAS_T_OR_B(mp->field))
+		factor = 2;
+
+	if (dev->has_scaler_out || dev->has_crop_out || dev->has_compose_out) {
+		struct v4l2_rect r = { 0, 0, mp->width, mp->height };
+
+		if (dev->has_scaler_out) {
+			if (dev->has_crop_out)
+				v4l2_rect_map_inside(crop, &r);
+			else
+				*crop = r;
+			if (dev->has_compose_out && !dev->has_crop_out) {
+				struct v4l2_rect min_r = {
+					0, 0,
+					r.width / MAX_ZOOM,
+					factor * r.height / MAX_ZOOM
+				};
+				struct v4l2_rect max_r = {
+					0, 0,
+					r.width * MAX_ZOOM,
+					factor * r.height * MAX_ZOOM
+				};
+
+				v4l2_rect_set_min_size(compose, &min_r);
+				v4l2_rect_set_max_size(compose, &max_r);
+				v4l2_rect_map_inside(compose, &dev->compose_bounds_out);
+			} else if (dev->has_compose_out) {
+				struct v4l2_rect min_r = {
+					0, 0,
+					crop->width / MAX_ZOOM,
+					factor * crop->height / MAX_ZOOM
+				};
+				struct v4l2_rect max_r = {
+					0, 0,
+					crop->width * MAX_ZOOM,
+					factor * crop->height * MAX_ZOOM
+				};
+
+				v4l2_rect_set_min_size(compose, &min_r);
+				v4l2_rect_set_max_size(compose, &max_r);
+				v4l2_rect_map_inside(compose, &dev->compose_bounds_out);
+			}
+		} else if (dev->has_compose_out && !dev->has_crop_out) {
+			v4l2_rect_set_size_to(crop, &r);
+			r.height *= factor;
+			v4l2_rect_set_size_to(compose, &r);
+			v4l2_rect_map_inside(compose, &dev->compose_bounds_out);
+		} else if (!dev->has_compose_out) {
+			v4l2_rect_map_inside(crop, &r);
+			r.height /= factor;
+			v4l2_rect_set_size_to(compose, &r);
+		} else {
+			r.height *= factor;
+			v4l2_rect_set_max_size(compose, &r);
+			v4l2_rect_map_inside(compose, &dev->compose_bounds_out);
+			crop->top *= factor;
+			crop->height *= factor;
+			v4l2_rect_set_size_to(crop, compose);
+			v4l2_rect_map_inside(crop, &r);
+			crop->top /= factor;
+			crop->height /= factor;
+		}
+	} else {
+		struct v4l2_rect r = { 0, 0, mp->width, mp->height };
+
+		v4l2_rect_set_size_to(crop, &r);
+		r.height /= factor;
+		v4l2_rect_set_size_to(compose, &r);
+	}
+
+	dev->fmt_out_rect.width = mp->width;
+	dev->fmt_out_rect.height = mp->height;
+	for (p = 0; p < mp->num_planes; p++)
+		dev->bytesperline_out[p] = mp->plane_fmt[p].bytesperline;
+	for (p = dev->fmt_out->buffers; p < dev->fmt_out->planes; p++)
+		dev->bytesperline_out[p] =
+			(dev->bytesperline_out[0] * dev->fmt_out->bit_depth[p]) /
+			dev->fmt_out->bit_depth[0];
+	dev->field_out = mp->field;
+	if (vivid_is_svid_out(dev))
+		dev->tv_field_out = mp->field;
+
+set_colorspace:
+	dev->colorspace_out = mp->colorspace;
+	dev->xfer_func_out = mp->xfer_func;
+	dev->ycbcr_enc_out = mp->ycbcr_enc;
+	dev->quantization_out = mp->quantization;
+	if (dev->loop_video) {
+		vivid_send_source_change(dev, SVID);
+		vivid_send_source_change(dev, HDMI);
+	}
+	return 0;
+}
+
+int vidioc_g_fmt_vid_out_mplane(struct file *file, void *priv,
+					struct v4l2_format *f)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (!dev->multiplanar)
+		return -ENOTTY;
+	return vivid_g_fmt_vid_out(file, priv, f);
+}
+
+int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv,
+			struct v4l2_format *f)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (!dev->multiplanar)
+		return -ENOTTY;
+	return vivid_try_fmt_vid_out(file, priv, f);
+}
+
+int vidioc_s_fmt_vid_out_mplane(struct file *file, void *priv,
+			struct v4l2_format *f)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (!dev->multiplanar)
+		return -ENOTTY;
+	return vivid_s_fmt_vid_out(file, priv, f);
+}
+
+int vidioc_g_fmt_vid_out(struct file *file, void *priv,
+					struct v4l2_format *f)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (dev->multiplanar)
+		return -ENOTTY;
+	return fmt_sp2mp_func(file, priv, f, vivid_g_fmt_vid_out);
+}
+
+int vidioc_try_fmt_vid_out(struct file *file, void *priv,
+			struct v4l2_format *f)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (dev->multiplanar)
+		return -ENOTTY;
+	return fmt_sp2mp_func(file, priv, f, vivid_try_fmt_vid_out);
+}
+
+int vidioc_s_fmt_vid_out(struct file *file, void *priv,
+			struct v4l2_format *f)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (dev->multiplanar)
+		return -ENOTTY;
+	return fmt_sp2mp_func(file, priv, f, vivid_s_fmt_vid_out);
+}
+
+int vivid_vid_out_g_selection(struct file *file, void *priv,
+			      struct v4l2_selection *sel)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (!dev->has_crop_out && !dev->has_compose_out)
+		return -ENOTTY;
+	if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+		return -EINVAL;
+
+	sel->r.left = sel->r.top = 0;
+	switch (sel->target) {
+	case V4L2_SEL_TGT_CROP:
+		if (!dev->has_crop_out)
+			return -EINVAL;
+		sel->r = dev->crop_out;
+		break;
+	case V4L2_SEL_TGT_CROP_DEFAULT:
+		if (!dev->has_crop_out)
+			return -EINVAL;
+		sel->r = dev->fmt_out_rect;
+		break;
+	case V4L2_SEL_TGT_CROP_BOUNDS:
+		if (!dev->has_crop_out)
+			return -EINVAL;
+		sel->r = vivid_max_rect;
+		break;
+	case V4L2_SEL_TGT_COMPOSE:
+		if (!dev->has_compose_out)
+			return -EINVAL;
+		sel->r = dev->compose_out;
+		break;
+	case V4L2_SEL_TGT_COMPOSE_DEFAULT:
+	case V4L2_SEL_TGT_COMPOSE_BOUNDS:
+		if (!dev->has_compose_out)
+			return -EINVAL;
+		sel->r = dev->sink_rect;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+int vivid_vid_out_s_selection(struct file *file, void *fh, struct v4l2_selection *s)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	struct v4l2_rect *crop = &dev->crop_out;
+	struct v4l2_rect *compose = &dev->compose_out;
+	unsigned factor = V4L2_FIELD_HAS_T_OR_B(dev->field_out) ? 2 : 1;
+	int ret;
+
+	if (!dev->has_crop_out && !dev->has_compose_out)
+		return -ENOTTY;
+	if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+		return -EINVAL;
+
+	switch (s->target) {
+	case V4L2_SEL_TGT_CROP:
+		if (!dev->has_crop_out)
+			return -EINVAL;
+		ret = vivid_vid_adjust_sel(s->flags, &s->r);
+		if (ret)
+			return ret;
+		v4l2_rect_set_min_size(&s->r, &vivid_min_rect);
+		v4l2_rect_set_max_size(&s->r, &dev->fmt_out_rect);
+		if (dev->has_scaler_out) {
+			struct v4l2_rect max_rect = {
+				0, 0,
+				dev->sink_rect.width * MAX_ZOOM,
+				(dev->sink_rect.height / factor) * MAX_ZOOM
+			};
+
+			v4l2_rect_set_max_size(&s->r, &max_rect);
+			if (dev->has_compose_out) {
+				struct v4l2_rect min_rect = {
+					0, 0,
+					s->r.width / MAX_ZOOM,
+					(s->r.height * factor) / MAX_ZOOM
+				};
+				struct v4l2_rect max_rect = {
+					0, 0,
+					s->r.width * MAX_ZOOM,
+					(s->r.height * factor) * MAX_ZOOM
+				};
+
+				v4l2_rect_set_min_size(compose, &min_rect);
+				v4l2_rect_set_max_size(compose, &max_rect);
+				v4l2_rect_map_inside(compose, &dev->compose_bounds_out);
+			}
+		} else if (dev->has_compose_out) {
+			s->r.top *= factor;
+			s->r.height *= factor;
+			v4l2_rect_set_max_size(&s->r, &dev->sink_rect);
+			v4l2_rect_set_size_to(compose, &s->r);
+			v4l2_rect_map_inside(compose, &dev->compose_bounds_out);
+			s->r.top /= factor;
+			s->r.height /= factor;
+		} else {
+			v4l2_rect_set_size_to(&s->r, &dev->sink_rect);
+			s->r.height /= factor;
+		}
+		v4l2_rect_map_inside(&s->r, &dev->fmt_out_rect);
+		*crop = s->r;
+		break;
+	case V4L2_SEL_TGT_COMPOSE:
+		if (!dev->has_compose_out)
+			return -EINVAL;
+		ret = vivid_vid_adjust_sel(s->flags, &s->r);
+		if (ret)
+			return ret;
+		v4l2_rect_set_min_size(&s->r, &vivid_min_rect);
+		v4l2_rect_set_max_size(&s->r, &dev->sink_rect);
+		v4l2_rect_map_inside(&s->r, &dev->compose_bounds_out);
+		s->r.top /= factor;
+		s->r.height /= factor;
+		if (dev->has_scaler_out) {
+			struct v4l2_rect fmt = dev->fmt_out_rect;
+			struct v4l2_rect max_rect = {
+				0, 0,
+				s->r.width * MAX_ZOOM,
+				s->r.height * MAX_ZOOM
+			};
+			struct v4l2_rect min_rect = {
+				0, 0,
+				s->r.width / MAX_ZOOM,
+				s->r.height / MAX_ZOOM
+			};
+
+			v4l2_rect_set_min_size(&fmt, &min_rect);
+			if (!dev->has_crop_out)
+				v4l2_rect_set_max_size(&fmt, &max_rect);
+			if (!v4l2_rect_same_size(&dev->fmt_out_rect, &fmt) &&
+			    vb2_is_busy(&dev->vb_vid_out_q))
+				return -EBUSY;
+			if (dev->has_crop_out) {
+				v4l2_rect_set_min_size(crop, &min_rect);
+				v4l2_rect_set_max_size(crop, &max_rect);
+			}
+			dev->fmt_out_rect = fmt;
+		} else if (dev->has_crop_out) {
+			struct v4l2_rect fmt = dev->fmt_out_rect;
+
+			v4l2_rect_set_min_size(&fmt, &s->r);
+			if (!v4l2_rect_same_size(&dev->fmt_out_rect, &fmt) &&
+			    vb2_is_busy(&dev->vb_vid_out_q))
+				return -EBUSY;
+			dev->fmt_out_rect = fmt;
+			v4l2_rect_set_size_to(crop, &s->r);
+			v4l2_rect_map_inside(crop, &dev->fmt_out_rect);
+		} else {
+			if (!v4l2_rect_same_size(&s->r, &dev->fmt_out_rect) &&
+			    vb2_is_busy(&dev->vb_vid_out_q))
+				return -EBUSY;
+			v4l2_rect_set_size_to(&dev->fmt_out_rect, &s->r);
+			v4l2_rect_set_size_to(crop, &s->r);
+			crop->height /= factor;
+			v4l2_rect_map_inside(crop, &dev->fmt_out_rect);
+		}
+		s->r.top *= factor;
+		s->r.height *= factor;
+		if (dev->bitmap_out && (compose->width != s->r.width ||
+					compose->height != s->r.height)) {
+			vfree(dev->bitmap_out);
+			dev->bitmap_out = NULL;
+		}
+		*compose = s->r;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int vivid_vid_out_g_pixelaspect(struct file *file, void *priv,
+				int type, struct v4l2_fract *f)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+		return -EINVAL;
+
+	switch (vivid_get_pixel_aspect(dev)) {
+	case TPG_PIXEL_ASPECT_NTSC:
+		f->numerator = 11;
+		f->denominator = 10;
+		break;
+	case TPG_PIXEL_ASPECT_PAL:
+		f->numerator = 54;
+		f->denominator = 59;
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
+int vidioc_g_fmt_vid_out_overlay(struct file *file, void *priv,
+					struct v4l2_format *f)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	const struct v4l2_rect *compose = &dev->compose_out;
+	struct v4l2_window *win = &f->fmt.win;
+	unsigned clipcount = win->clipcount;
+
+	if (!dev->has_fb)
+		return -EINVAL;
+	win->w.top = dev->overlay_out_top;
+	win->w.left = dev->overlay_out_left;
+	win->w.width = compose->width;
+	win->w.height = compose->height;
+	win->clipcount = dev->clipcount_out;
+	win->field = V4L2_FIELD_ANY;
+	win->chromakey = dev->chromakey_out;
+	win->global_alpha = dev->global_alpha_out;
+	if (clipcount > dev->clipcount_out)
+		clipcount = dev->clipcount_out;
+	if (dev->bitmap_out == NULL)
+		win->bitmap = NULL;
+	else if (win->bitmap) {
+		if (copy_to_user(win->bitmap, dev->bitmap_out,
+		    ((dev->compose_out.width + 7) / 8) * dev->compose_out.height))
+			return -EFAULT;
+	}
+	if (clipcount && win->clips) {
+		if (copy_to_user(win->clips, dev->clips_out,
+				 clipcount * sizeof(dev->clips_out[0])))
+			return -EFAULT;
+	}
+	return 0;
+}
+
+int vidioc_try_fmt_vid_out_overlay(struct file *file, void *priv,
+					struct v4l2_format *f)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	const struct v4l2_rect *compose = &dev->compose_out;
+	struct v4l2_window *win = &f->fmt.win;
+	int i, j;
+
+	if (!dev->has_fb)
+		return -EINVAL;
+	win->w.left = clamp_t(int, win->w.left,
+			      -dev->display_width, dev->display_width);
+	win->w.top = clamp_t(int, win->w.top,
+			     -dev->display_height, dev->display_height);
+	win->w.width = compose->width;
+	win->w.height = compose->height;
+	/*
+	 * It makes no sense for an OSD to overlay only top or bottom fields,
+	 * so always set this to ANY.
+	 */
+	win->field = V4L2_FIELD_ANY;
+	if (win->clipcount && !win->clips)
+		win->clipcount = 0;
+	if (win->clipcount > MAX_CLIPS)
+		win->clipcount = MAX_CLIPS;
+	if (win->clipcount) {
+		if (copy_from_user(dev->try_clips_out, win->clips,
+				   win->clipcount * sizeof(dev->clips_out[0])))
+			return -EFAULT;
+		for (i = 0; i < win->clipcount; i++) {
+			struct v4l2_rect *r = &dev->try_clips_out[i].c;
+
+			r->top = clamp_t(s32, r->top, 0, dev->display_height - 1);
+			r->height = clamp_t(s32, r->height, 1, dev->display_height - r->top);
+			r->left = clamp_t(u32, r->left, 0, dev->display_width - 1);
+			r->width = clamp_t(u32, r->width, 1, dev->display_width - r->left);
+		}
+		/*
+		 * Yeah, so sue me, it's an O(n^2) algorithm. But n is a small
+		 * number and it's typically a one-time deal.
+		 */
+		for (i = 0; i < win->clipcount - 1; i++) {
+			struct v4l2_rect *r1 = &dev->try_clips_out[i].c;
+
+			for (j = i + 1; j < win->clipcount; j++) {
+				struct v4l2_rect *r2 = &dev->try_clips_out[j].c;
+
+				if (v4l2_rect_overlap(r1, r2))
+					return -EINVAL;
+			}
+		}
+		if (copy_to_user(win->clips, dev->try_clips_out,
+				 win->clipcount * sizeof(dev->clips_out[0])))
+			return -EFAULT;
+	}
+	return 0;
+}
+
+int vidioc_s_fmt_vid_out_overlay(struct file *file, void *priv,
+					struct v4l2_format *f)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	const struct v4l2_rect *compose = &dev->compose_out;
+	struct v4l2_window *win = &f->fmt.win;
+	int ret = vidioc_try_fmt_vid_out_overlay(file, priv, f);
+	unsigned bitmap_size = ((compose->width + 7) / 8) * compose->height;
+	unsigned clips_size = win->clipcount * sizeof(dev->clips_out[0]);
+	void *new_bitmap = NULL;
+
+	if (ret)
+		return ret;
+
+	if (win->bitmap) {
+		new_bitmap = vzalloc(bitmap_size);
+
+		if (!new_bitmap)
+			return -ENOMEM;
+		if (copy_from_user(new_bitmap, win->bitmap, bitmap_size)) {
+			vfree(new_bitmap);
+			return -EFAULT;
+		}
+	}
+
+	dev->overlay_out_top = win->w.top;
+	dev->overlay_out_left = win->w.left;
+	vfree(dev->bitmap_out);
+	dev->bitmap_out = new_bitmap;
+	dev->clipcount_out = win->clipcount;
+	if (dev->clipcount_out)
+		memcpy(dev->clips_out, dev->try_clips_out, clips_size);
+	dev->chromakey_out = win->chromakey;
+	dev->global_alpha_out = win->global_alpha;
+	return ret;
+}
+
+int vivid_vid_out_overlay(struct file *file, void *fh, unsigned i)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (i && !dev->fmt_out->can_do_overlay) {
+		dprintk(dev, 1, "unsupported output format for output overlay\n");
+		return -EINVAL;
+	}
+
+	dev->overlay_out_enabled = i;
+	return 0;
+}
+
+int vivid_vid_out_g_fbuf(struct file *file, void *fh,
+				struct v4l2_framebuffer *a)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	a->capability = V4L2_FBUF_CAP_EXTERNOVERLAY |
+			V4L2_FBUF_CAP_BITMAP_CLIPPING |
+			V4L2_FBUF_CAP_LIST_CLIPPING |
+			V4L2_FBUF_CAP_CHROMAKEY |
+			V4L2_FBUF_CAP_SRC_CHROMAKEY |
+			V4L2_FBUF_CAP_GLOBAL_ALPHA |
+			V4L2_FBUF_CAP_LOCAL_ALPHA |
+			V4L2_FBUF_CAP_LOCAL_INV_ALPHA;
+	a->flags = V4L2_FBUF_FLAG_OVERLAY | dev->fbuf_out_flags;
+	a->base = (void *)dev->video_pbase;
+	a->fmt.width = dev->display_width;
+	a->fmt.height = dev->display_height;
+	if (dev->fb_defined.green.length == 5)
+		a->fmt.pixelformat = V4L2_PIX_FMT_ARGB555;
+	else
+		a->fmt.pixelformat = V4L2_PIX_FMT_RGB565;
+	a->fmt.bytesperline = dev->display_byte_stride;
+	a->fmt.sizeimage = a->fmt.height * a->fmt.bytesperline;
+	a->fmt.field = V4L2_FIELD_NONE;
+	a->fmt.colorspace = V4L2_COLORSPACE_SRGB;
+	a->fmt.priv = 0;
+	return 0;
+}
+
+int vivid_vid_out_s_fbuf(struct file *file, void *fh,
+				const struct v4l2_framebuffer *a)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	const unsigned chroma_flags = V4L2_FBUF_FLAG_CHROMAKEY |
+				      V4L2_FBUF_FLAG_SRC_CHROMAKEY;
+	const unsigned alpha_flags = V4L2_FBUF_FLAG_GLOBAL_ALPHA |
+				     V4L2_FBUF_FLAG_LOCAL_ALPHA |
+				     V4L2_FBUF_FLAG_LOCAL_INV_ALPHA;
+
+
+	if ((a->flags & chroma_flags) == chroma_flags)
+		return -EINVAL;
+	switch (a->flags & alpha_flags) {
+	case 0:
+	case V4L2_FBUF_FLAG_GLOBAL_ALPHA:
+	case V4L2_FBUF_FLAG_LOCAL_ALPHA:
+	case V4L2_FBUF_FLAG_LOCAL_INV_ALPHA:
+		break;
+	default:
+		return -EINVAL;
+	}
+	dev->fbuf_out_flags &= ~(chroma_flags | alpha_flags);
+	dev->fbuf_out_flags = a->flags & (chroma_flags | alpha_flags);
+	return 0;
+}
+
+static const struct v4l2_audioout vivid_audio_outputs[] = {
+	{ 0, "Line-Out 1" },
+	{ 1, "Line-Out 2" },
+};
+
+int vidioc_enum_output(struct file *file, void *priv,
+				struct v4l2_output *out)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (out->index >= dev->num_outputs)
+		return -EINVAL;
+
+	out->type = V4L2_OUTPUT_TYPE_ANALOG;
+	switch (dev->output_type[out->index]) {
+	case SVID:
+		snprintf(out->name, sizeof(out->name), "S-Video %u",
+				dev->output_name_counter[out->index]);
+		out->std = V4L2_STD_ALL;
+		if (dev->has_audio_outputs)
+			out->audioset = (1 << ARRAY_SIZE(vivid_audio_outputs)) - 1;
+		out->capabilities = V4L2_OUT_CAP_STD;
+		break;
+	case HDMI:
+		snprintf(out->name, sizeof(out->name), "HDMI %u",
+				dev->output_name_counter[out->index]);
+		out->capabilities = V4L2_OUT_CAP_DV_TIMINGS;
+		break;
+	}
+	return 0;
+}
+
+int vidioc_g_output(struct file *file, void *priv, unsigned *o)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	*o = dev->output;
+	return 0;
+}
+
+int vidioc_s_output(struct file *file, void *priv, unsigned o)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (o >= dev->num_outputs)
+		return -EINVAL;
+
+	if (o == dev->output)
+		return 0;
+
+	if (vb2_is_busy(&dev->vb_vid_out_q) ||
+	    vb2_is_busy(&dev->vb_vbi_out_q) ||
+	    vb2_is_busy(&dev->vb_meta_out_q))
+		return -EBUSY;
+
+	dev->output = o;
+	dev->tv_audio_output = 0;
+	if (dev->output_type[o] == SVID)
+		dev->vid_out_dev.tvnorms = V4L2_STD_ALL;
+	else
+		dev->vid_out_dev.tvnorms = 0;
+
+	dev->vbi_out_dev.tvnorms = dev->vid_out_dev.tvnorms;
+	dev->meta_out_dev.tvnorms = dev->vid_out_dev.tvnorms;
+	vivid_update_format_out(dev);
+
+	v4l2_ctrl_activate(dev->ctrl_display_present, vivid_is_hdmi_out(dev));
+	if (vivid_is_hdmi_out(dev))
+		v4l2_ctrl_s_ctrl(dev->ctrl_display_present,
+				 dev->display_present[dev->output]);
+
+	return 0;
+}
+
+int vidioc_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vout)
+{
+	if (vout->index >= ARRAY_SIZE(vivid_audio_outputs))
+		return -EINVAL;
+	*vout = vivid_audio_outputs[vout->index];
+	return 0;
+}
+
+int vidioc_g_audout(struct file *file, void *fh, struct v4l2_audioout *vout)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (!vivid_is_svid_out(dev))
+		return -EINVAL;
+	*vout = vivid_audio_outputs[dev->tv_audio_output];
+	return 0;
+}
+
+int vidioc_s_audout(struct file *file, void *fh, const struct v4l2_audioout *vout)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (!vivid_is_svid_out(dev))
+		return -EINVAL;
+	if (vout->index >= ARRAY_SIZE(vivid_audio_outputs))
+		return -EINVAL;
+	dev->tv_audio_output = vout->index;
+	return 0;
+}
+
+int vivid_vid_out_s_std(struct file *file, void *priv, v4l2_std_id id)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (!vivid_is_svid_out(dev))
+		return -ENODATA;
+	if (dev->std_out == id)
+		return 0;
+	if (vb2_is_busy(&dev->vb_vid_out_q) || vb2_is_busy(&dev->vb_vbi_out_q))
+		return -EBUSY;
+	dev->std_out = id;
+	vivid_update_format_out(dev);
+	return 0;
+}
+
+static bool valid_cvt_gtf_timings(struct v4l2_dv_timings *timings)
+{
+	struct v4l2_bt_timings *bt = &timings->bt;
+
+	if ((bt->standards & (V4L2_DV_BT_STD_CVT | V4L2_DV_BT_STD_GTF)) &&
+	    v4l2_valid_dv_timings(timings, &vivid_dv_timings_cap, NULL, NULL))
+		return true;
+
+	return false;
+}
+
+int vivid_vid_out_s_dv_timings(struct file *file, void *_fh,
+				    struct v4l2_dv_timings *timings)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+	if (!vivid_is_hdmi_out(dev))
+		return -ENODATA;
+	if (!v4l2_find_dv_timings_cap(timings, &vivid_dv_timings_cap,
+				0, NULL, NULL) &&
+	    !valid_cvt_gtf_timings(timings))
+		return -EINVAL;
+	if (v4l2_match_dv_timings(timings, &dev->dv_timings_out, 0, true))
+		return 0;
+	if (vb2_is_busy(&dev->vb_vid_out_q))
+		return -EBUSY;
+	dev->dv_timings_out = *timings;
+	vivid_update_format_out(dev);
+	return 0;
+}
+
+int vivid_vid_out_g_parm(struct file *file, void *priv,
+			  struct v4l2_streamparm *parm)
+{
+	struct vivid_dev *dev = video_drvdata(file);
+
+	if (parm->type != (dev->multiplanar ?
+			   V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE :
+			   V4L2_BUF_TYPE_VIDEO_OUTPUT))
+		return -EINVAL;
+
+	parm->parm.output.capability   = V4L2_CAP_TIMEPERFRAME;
+	parm->parm.output.timeperframe = dev->timeperframe_vid_out;
+	parm->parm.output.writebuffers  = 1;
+
+	return 0;
+}
+
+int vidioc_subscribe_event(struct v4l2_fh *fh,
+			const struct v4l2_event_subscription *sub)
+{
+	switch (sub->type) {
+	case V4L2_EVENT_SOURCE_CHANGE:
+		if (fh->vdev->vfl_dir == VFL_DIR_RX)
+			return v4l2_src_change_event_subscribe(fh, sub);
+		break;
+	default:
+		return v4l2_ctrl_subscribe_event(fh, sub);
+	}
+	return -EINVAL;
+}
diff --git a/drivers/media/test-drivers/vivid/vivid-vid-out.h b/drivers/media/test-drivers/vivid/vivid-vid-out.h
new file mode 100644
index 000000000000..8d56314f4ea1
--- /dev/null
+++ b/drivers/media/test-drivers/vivid/vivid-vid-out.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * vivid-vid-out.h - video output support functions.
+ *
+ * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _VIVID_VID_OUT_H_
+#define _VIVID_VID_OUT_H_
+
+extern const struct vb2_ops vivid_vid_out_qops;
+
+void vivid_update_format_out(struct vivid_dev *dev);
+
+int vivid_g_fmt_vid_out(struct file *file, void *priv, struct v4l2_format *f);
+int vivid_try_fmt_vid_out(struct file *file, void *priv, struct v4l2_format *f);
+int vivid_s_fmt_vid_out(struct file *file, void *priv, struct v4l2_format *f);
+int vidioc_g_fmt_vid_out_mplane(struct file *file, void *priv, struct v4l2_format *f);
+int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv, struct v4l2_format *f);
+int vidioc_s_fmt_vid_out_mplane(struct file *file, void *priv, struct v4l2_format *f);
+int vidioc_g_fmt_vid_out(struct file *file, void *priv, struct v4l2_format *f);
+int vidioc_try_fmt_vid_out(struct file *file, void *priv, struct v4l2_format *f);
+int vidioc_s_fmt_vid_out(struct file *file, void *priv, struct v4l2_format *f);
+int vivid_vid_out_g_selection(struct file *file, void *priv, struct v4l2_selection *sel);
+int vivid_vid_out_s_selection(struct file *file, void *fh, struct v4l2_selection *s);
+int vivid_vid_out_g_pixelaspect(struct file *file, void *priv, int type, struct v4l2_fract *f);
+int vidioc_enum_fmt_vid_out_overlay(struct file *file, void  *priv, struct v4l2_fmtdesc *f);
+int vidioc_g_fmt_vid_out_overlay(struct file *file, void *priv, struct v4l2_format *f);
+int vidioc_try_fmt_vid_out_overlay(struct file *file, void *priv, struct v4l2_format *f);
+int vidioc_s_fmt_vid_out_overlay(struct file *file, void *priv, struct v4l2_format *f);
+int vivid_vid_out_overlay(struct file *file, void *fh, unsigned i);
+int vivid_vid_out_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *a);
+int vivid_vid_out_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffer *a);
+int vidioc_enum_output(struct file *file, void *priv, struct v4l2_output *out);
+int vidioc_g_output(struct file *file, void *priv, unsigned *i);
+int vidioc_s_output(struct file *file, void *priv, unsigned i);
+int vidioc_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vout);
+int vidioc_g_audout(struct file *file, void *fh, struct v4l2_audioout *vout);
+int vidioc_s_audout(struct file *file, void *fh, const struct v4l2_audioout *vout);
+int vivid_vid_out_s_std(struct file *file, void *priv, v4l2_std_id id);
+int vivid_vid_out_s_dv_timings(struct file *file, void *_fh, struct v4l2_dv_timings *timings);
+int vivid_vid_out_g_parm(struct file *file, void *priv, struct v4l2_streamparm *parm);
+
+#endif
diff --git a/drivers/media/tuners/Kconfig b/drivers/media/tuners/Kconfig
index e104bb7766e1..2368b0e230e5 100644
--- a/drivers/media/tuners/Kconfig
+++ b/drivers/media/tuners/Kconfig
@@ -15,7 +15,7 @@ config MEDIA_TUNER
 	select MEDIA_TUNER_TDA9887 if MEDIA_SUBDRV_AUTOSELECT
 	select MEDIA_TUNER_MC44S803 if MEDIA_SUBDRV_AUTOSELECT
 
-comment "Tuner drivers hidden by 'Autoselect ancillary drivers'"
+comment "Tuner drivers auto-selected by 'Autoselect ancillary drivers'"
 	depends on MEDIA_HIDE_ANCILLARY_SUBDRV
 	depends on MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT || MEDIA_RADIO_SUPPORT || MEDIA_SDR_SUPPORT
 
diff --git a/drivers/media/usb/Kconfig b/drivers/media/usb/Kconfig
index e678d3d11467..00feadb217d8 100644
--- a/drivers/media/usb/Kconfig
+++ b/drivers/media/usb/Kconfig
@@ -1,4 +1,10 @@
 # SPDX-License-Identifier: GPL-2.0-only
+
+# This Kconfig option is also used by the legacy av7110 driver
+config TTPCI_EEPROM
+	tristate
+	depends on I2C
+
 if USB && MEDIA_SUPPORT
 
 menuconfig MEDIA_USB_SUPPORT
@@ -60,11 +66,5 @@ source "drivers/media/usb/hackrf/Kconfig"
 source "drivers/media/usb/msi2500/Kconfig"
 endif
 
-if MEDIA_CEC_SUPPORT
-	comment "USB HDMI CEC adapters"
-source "drivers/media/usb/pulse8-cec/Kconfig"
-source "drivers/media/usb/rainshadow-cec/Kconfig"
-endif
-
 endif #MEDIA_USB_SUPPORT
 endif #USB
diff --git a/drivers/media/usb/Makefile b/drivers/media/usb/Makefile
index 169aa07c97bd..3eaff3149ef4 100644
--- a/drivers/media/usb/Makefile
+++ b/drivers/media/usb/Makefile
@@ -24,5 +24,3 @@ obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
 obj-$(CONFIG_VIDEO_USBTV) += usbtv/
 obj-$(CONFIG_VIDEO_GO7007) += go7007/
 obj-$(CONFIG_DVB_AS102) += as102/
-obj-$(CONFIG_USB_PULSE8_CEC) += pulse8-cec/
-obj-$(CONFIG_USB_RAINSHADOW_CEC) += rainshadow-cec/
diff --git a/drivers/media/usb/cx231xx/cx231xx-input.c b/drivers/media/usb/cx231xx/cx231xx-input.c
index 9f88c640ec2b..8149702bcf89 100644
--- a/drivers/media/usb/cx231xx/cx231xx-input.c
+++ b/drivers/media/usb/cx231xx/cx231xx-input.c
@@ -88,7 +88,7 @@ int cx231xx_ir_init(struct cx231xx *dev)
 	ir_i2c_bus = cx231xx_boards[dev->model].ir_i2c_master;
 	dev_dbg(dev->dev, "Trying to bind ir at bus %d, addr 0x%02x\n",
 		ir_i2c_bus, info.addr);
-	dev->ir_i2c_client = i2c_new_device(
+	dev->ir_i2c_client = i2c_new_client_device(
 		cx231xx_get_i2c_adap(dev, ir_i2c_bus), &info);
 
 	return 0;
@@ -96,7 +96,6 @@ int cx231xx_ir_init(struct cx231xx *dev)
 
 void cx231xx_ir_exit(struct cx231xx *dev)
 {
-	if (dev->ir_i2c_client)
-		i2c_unregister_device(dev->ir_i2c_client);
+	i2c_unregister_device(dev->ir_i2c_client);
 	dev->ir_i2c_client = NULL;
 }
diff --git a/drivers/media/usb/dvb-usb-v2/Kconfig b/drivers/media/usb/dvb-usb-v2/Kconfig
index b21a4d413872..ff0ae64424c4 100644
--- a/drivers/media/usb/dvb-usb-v2/Kconfig
+++ b/drivers/media/usb/dvb-usb-v2/Kconfig
@@ -7,7 +7,7 @@ config DVB_USB_V2
 	  USB1.1 and USB2.0 DVB devices.
 
 	  Almost every USB device needs a firmware, please look into
-	  <file:Documentation/media/dvb-drivers/dvb-usb.rst>.
+	  <file:Documentation/driver-api/media/drivers/dvb-usb.rst>.
 
 	  For a complete list of supported USB devices see the LinuxTV DVB Wiki:
 	  <https://linuxtv.org/wiki/index.php/DVB_USB>
diff --git a/drivers/media/usb/dvb-usb-v2/gl861.c b/drivers/media/usb/dvb-usb-v2/gl861.c
index 19217dcf20f1..42c3b8af0774 100644
--- a/drivers/media/usb/dvb-usb-v2/gl861.c
+++ b/drivers/media/usb/dvb-usb-v2/gl861.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /* DVB USB compliant linux driver for GL861 USB2.0 devices.
  *
- * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+ * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
  */
 #include <linux/string.h>
 
diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.c b/drivers/media/usb/dvb-usb-v2/lmedm04.c
index fd8b42bb9a84..8a3c0eeed959 100644
--- a/drivers/media/usb/dvb-usb-v2/lmedm04.c
+++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c
@@ -22,7 +22,7 @@
  *
  * LME2510C + M88RS2000
  *
- * For firmware see Documentation/media/dvb-drivers/lmedm04.rst
+ * For firmware see Documentation/admin-guide/media/lmedm04.rst
  *
  * I2C addresses:
  * 0xd0 - STV0288	- Demodulator
@@ -39,7 +39,7 @@
  * Copyright (C) 2010 Malcolm Priestley (tvboxspy@gmail.com)
  * LME2510(C)(C) Leaguerme (Shenzhen) MicroElectronics Co., Ltd.
  *
- * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+ * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
  *
  * Known Issues :
  *	LME2510: Non Intel USB chipsets fail to maintain High Speed on
diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.h b/drivers/media/usb/dvb-usb-v2/lmedm04.h
index 766a8348624d..4335b6ebcc1c 100644
--- a/drivers/media/usb/dvb-usb-v2/lmedm04.h
+++ b/drivers/media/usb/dvb-usb-v2/lmedm04.h
@@ -14,7 +14,7 @@
  * MVB0001F (LME2510C+LGTDQT-P001F)
  *
  * *
- * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+ * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
  */
 #ifndef _DVB_USB_LME2510_H_
 #define _DVB_USB_LME2510_H_
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf.c b/drivers/media/usb/dvb-usb-v2/mxl111sf.c
index 55b4ae7037a4..7865fa0a8295 100644
--- a/drivers/media/usb/dvb-usb-v2/mxl111sf.c
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf.c
@@ -2,7 +2,7 @@
 /*
  * Copyright (C) 2010-2014 Michael Krufky (mkrufky@linuxtv.org)
  *
- * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+ * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
  */
 
 #include <linux/vmalloc.h>
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf.h b/drivers/media/usb/dvb-usb-v2/mxl111sf.h
index 70bd2a2a8ec1..e57e5d2353b4 100644
--- a/drivers/media/usb/dvb-usb-v2/mxl111sf.h
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf.h
@@ -2,7 +2,7 @@
 /*
  * Copyright (C) 2010-2014 Michael Krufky (mkrufky@linuxtv.org)
  *
- * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+ * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
  */
 
 #ifndef _DVB_USB_MXL111SF_H_
diff --git a/drivers/media/usb/dvb-usb/Kconfig b/drivers/media/usb/dvb-usb/Kconfig
index 1a3e5f965ae4..15d29c91662f 100644
--- a/drivers/media/usb/dvb-usb/Kconfig
+++ b/drivers/media/usb/dvb-usb/Kconfig
@@ -2,12 +2,13 @@
 config DVB_USB
 	tristate "Support for various USB DVB devices"
 	depends on DVB_CORE && USB && I2C && RC_CORE
+	select CYPRESS_FIRMWARE
 	help
 	  By enabling this you will be able to choose the various supported
 	  USB1.1 and USB2.0 DVB devices.
 
 	  Almost every USB device needs a firmware, please look into
-	  <file:Documentation/media/dvb-drivers/dvb-usb.rst>.
+	  <file:Documentation/driver-api/media/drivers/dvb-usb.rst>.
 
 	  For a complete list of supported USB devices see the LinuxTV DVB Wiki:
 	  <https://linuxtv.org/wiki/index.php/DVB_USB>
diff --git a/drivers/media/usb/dvb-usb/a800.c b/drivers/media/usb/dvb-usb/a800.c
index 666213f5d5d8..15bbefe3bc00 100644
--- a/drivers/media/usb/dvb-usb/a800.c
+++ b/drivers/media/usb/dvb-usb/a800.c
@@ -8,7 +8,7 @@
  *   - AVerMedia who kindly provided information and
  *   - Glen Harris who suffered from my mistakes during development.
  *
- * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+ * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
  */
 #include "dibusb.h"
 
diff --git a/drivers/media/usb/dvb-usb/af9005-fe.c b/drivers/media/usb/dvb-usb/af9005-fe.c
index 6c960f723457..9d6fa0556d7b 100644
--- a/drivers/media/usb/dvb-usb/af9005-fe.c
+++ b/drivers/media/usb/dvb-usb/af9005-fe.c
@@ -6,7 +6,7 @@
  *
  * Thanks to Afatech who kindly provided information.
  *
- * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+ * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
  */
 #include "af9005.h"
 #include "af9005-script.h"
diff --git a/drivers/media/usb/dvb-usb/af9005-remote.c b/drivers/media/usb/dvb-usb/af9005-remote.c
index c664353f3911..41d48b3c8d05 100644
--- a/drivers/media/usb/dvb-usb/af9005-remote.c
+++ b/drivers/media/usb/dvb-usb/af9005-remote.c
@@ -8,7 +8,7 @@
  *
  * Thanks to Afatech who kindly provided information.
  *
- * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+ * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
  */
 #include "af9005.h"
 /* debug */
diff --git a/drivers/media/usb/dvb-usb/af9005.c b/drivers/media/usb/dvb-usb/af9005.c
index 89b4b5d84cdf..3446bcac8ed1 100644
--- a/drivers/media/usb/dvb-usb/af9005.c
+++ b/drivers/media/usb/dvb-usb/af9005.c
@@ -6,7 +6,7 @@
  *
  * Thanks to Afatech who kindly provided information.
  *
- * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+ * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
  */
 #include "af9005.h"
 
diff --git a/drivers/media/usb/dvb-usb/af9005.h b/drivers/media/usb/dvb-usb/af9005.h
index 3179a7c71e8f..11d74dc26d83 100644
--- a/drivers/media/usb/dvb-usb/af9005.h
+++ b/drivers/media/usb/dvb-usb/af9005.h
@@ -6,7 +6,7 @@
  *
  * Thanks to Afatech who kindly provided information.
  *
- * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+ * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
  */
 #ifndef _DVB_USB_AF9005_H_
 #define _DVB_USB_AF9005_H_
diff --git a/drivers/media/usb/dvb-usb/az6027.c b/drivers/media/usb/dvb-usb/az6027.c
index 8de18da0c4bd..d5be540e31a7 100644
--- a/drivers/media/usb/dvb-usb/az6027.c
+++ b/drivers/media/usb/dvb-usb/az6027.c
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 2009 Adams.Xu <adams.xu@azwave.com.cn>
  *
- * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+ * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
  */
 #include "az6027.h"
 
diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c
index c421b603be44..fd058f71ce49 100644
--- a/drivers/media/usb/dvb-usb/cxusb.c
+++ b/drivers/media/usb/dvb-usb/cxusb.c
@@ -18,7 +18,7 @@
  * Copyright (C) 2006, 2007 Chris Pascoe (c.pascoe@itee.uq.edu.au)
  * Copyright (C) 2011, 2017 Maciej S. Szmigiero (mail@maciej.szmigiero.name)
  *
- * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+ * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
  */
 #include <media/tuner.h>
 #include <linux/delay.h>
diff --git a/drivers/media/usb/dvb-usb/dibusb-common.c b/drivers/media/usb/dvb-usb/dibusb-common.c
index 59ce2dec11e9..02b51d1a1b67 100644
--- a/drivers/media/usb/dvb-usb/dibusb-common.c
+++ b/drivers/media/usb/dvb-usb/dibusb-common.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@posteo.de)
  *
- * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+ * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
  */
 
 #include "dibusb.h"
diff --git a/drivers/media/usb/dvb-usb/dibusb-mb.c b/drivers/media/usb/dvb-usb/dibusb-mb.c
index d4ea72bf09c5..f462c918d5a4 100644
--- a/drivers/media/usb/dvb-usb/dibusb-mb.c
+++ b/drivers/media/usb/dvb-usb/dibusb-mb.c
@@ -7,7 +7,7 @@
  * based on GPL code from DiBcom, which has
  * Copyright (C) 2004 Amaury Demol for DiBcom
  *
- * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+ * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
  */
 #include "dibusb.h"
 
diff --git a/drivers/media/usb/dvb-usb/dibusb-mc-common.c b/drivers/media/usb/dvb-usb/dibusb-mc-common.c
index 967027e29c17..b8cde4cded33 100644
--- a/drivers/media/usb/dvb-usb/dibusb-mc-common.c
+++ b/drivers/media/usb/dvb-usb/dibusb-mc-common.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
  *
- * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+ * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
  */
 
 #include "dibusb.h"
diff --git a/drivers/media/usb/dvb-usb/dibusb-mc.c b/drivers/media/usb/dvb-usb/dibusb-mc.c
index ada3bee296c2..e2689977c8c8 100644
--- a/drivers/media/usb/dvb-usb/dibusb-mc.c
+++ b/drivers/media/usb/dvb-usb/dibusb-mc.c
@@ -7,7 +7,7 @@
  * based on GPL code from DiBcom, which has
  * Copyright (C) 2004 Amaury Demol for DiBcom
  *
- * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+ * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
  */
 #include "dibusb.h"
 
diff --git a/drivers/media/usb/dvb-usb/dibusb.h b/drivers/media/usb/dvb-usb/dibusb.h
index a83326c36ca7..f61de0744821 100644
--- a/drivers/media/usb/dvb-usb/dibusb.h
+++ b/drivers/media/usb/dvb-usb/dibusb.h
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@posteo.de)
  *
- * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+ * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
  */
 #ifndef _DVB_USB_DIBUSB_H_
 #define _DVB_USB_DIBUSB_H_
diff --git a/drivers/media/usb/dvb-usb/digitv.c b/drivers/media/usb/dvb-usb/digitv.c
index 99a39339d45d..906438c5a40f 100644
--- a/drivers/media/usb/dvb-usb/digitv.c
+++ b/drivers/media/usb/dvb-usb/digitv.c
@@ -6,7 +6,7 @@
  *
  * partly based on the SDK published by Nebula Electronics
  *
- * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+ * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
  */
 #include "digitv.h"
 
diff --git a/drivers/media/usb/dvb-usb/dtt200u-fe.c b/drivers/media/usb/dvb-usb/dtt200u-fe.c
index 00ce723c7bf0..9f83560ba63d 100644
--- a/drivers/media/usb/dvb-usb/dtt200u-fe.c
+++ b/drivers/media/usb/dvb-usb/dtt200u-fe.c
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@posteo.de>
  *
- * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+ * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
  */
 #include "dtt200u.h"
 
diff --git a/drivers/media/usb/dvb-usb/dtt200u.c b/drivers/media/usb/dvb-usb/dtt200u.c
index 1e7296b2e5b2..24efa023d827 100644
--- a/drivers/media/usb/dvb-usb/dtt200u.c
+++ b/drivers/media/usb/dvb-usb/dtt200u.c
@@ -6,7 +6,7 @@
  *
  * Thanks to Steve Chang from WideView for providing support for the WT-220U.
  *
- * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+ * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
  */
 #include "dtt200u.h"
 
diff --git a/drivers/media/usb/dvb-usb/dtt200u.h b/drivers/media/usb/dvb-usb/dtt200u.h
index 832f355114e4..696c2c1f3af3 100644
--- a/drivers/media/usb/dvb-usb/dtt200u.h
+++ b/drivers/media/usb/dvb-usb/dtt200u.h
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@posteo.de)
  *
- * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+ * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
  */
 #ifndef _DVB_USB_DTT200U_H_
 #define _DVB_USB_DTT200U_H_
diff --git a/drivers/media/usb/dvb-usb/dvb-usb-init.c b/drivers/media/usb/dvb-usb/dvb-usb-init.c
index 16a0b4a359ea..46ada09ce38a 100644
--- a/drivers/media/usb/dvb-usb/dvb-usb-init.c
+++ b/drivers/media/usb/dvb-usb/dvb-usb-init.c
@@ -6,7 +6,7 @@
  *
  * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@posteo.de)
  *
- * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+ * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
  */
 #include "dvb-usb-common.h"
 
diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c
index 1007366a295b..594a763b46cf 100644
--- a/drivers/media/usb/dvb-usb/dw2102.c
+++ b/drivers/media/usb/dvb-usb/dw2102.c
@@ -8,7 +8,7 @@
  *	Terratec Cinergy S2 cards
  * Copyright (C) 2008-2012 Igor M. Liplianin (liplianin@me.by)
  *
- * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+ * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
  */
 #include <media/dvb-usb-ids.h>
 #include "dw2102.h"
diff --git a/drivers/media/usb/dvb-usb/gp8psk.c b/drivers/media/usb/dvb-usb/gp8psk.c
index 1282f701f185..c07f46f5176e 100644
--- a/drivers/media/usb/dvb-usb/gp8psk.c
+++ b/drivers/media/usb/dvb-usb/gp8psk.c
@@ -9,7 +9,7 @@
  *
  * This module is based off the vp7045 and vp702x modules
  *
- * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+ * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
  */
 #include "gp8psk.h"
 #include "gp8psk-fe.h"
diff --git a/drivers/media/usb/dvb-usb/gp8psk.h b/drivers/media/usb/dvb-usb/gp8psk.h
index 2f4c1368eabe..5293dfdd2609 100644
--- a/drivers/media/usb/dvb-usb/gp8psk.h
+++ b/drivers/media/usb/dvb-usb/gp8psk.h
@@ -9,7 +9,7 @@
  *
  * This module is based off the vp7045 and vp702x modules
  *
- * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+ * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
  */
 #ifndef _DVB_USB_GP8PSK_H_
 #define _DVB_USB_GP8PSK_H_
diff --git a/drivers/media/usb/dvb-usb/m920x.c b/drivers/media/usb/dvb-usb/m920x.c
index d866a1990a7d..b8b99be5564b 100644
--- a/drivers/media/usb/dvb-usb/m920x.c
+++ b/drivers/media/usb/dvb-usb/m920x.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2006 Aapo Tahkola (aet@rasterburn.org)
  *
- * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+ * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
  */
 
 #include "m920x.h"
diff --git a/drivers/media/usb/dvb-usb/nova-t-usb2.c b/drivers/media/usb/dvb-usb/nova-t-usb2.c
index e368935a5089..e7b290552b66 100644
--- a/drivers/media/usb/dvb-usb/nova-t-usb2.c
+++ b/drivers/media/usb/dvb-usb/nova-t-usb2.c
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@posteo.de)
  *
- * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+ * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
  */
 #include "dibusb.h"
 
diff --git a/drivers/media/usb/dvb-usb/opera1.c b/drivers/media/usb/dvb-usb/opera1.c
index 823b33ae828d..e8d784b9d119 100644
--- a/drivers/media/usb/dvb-usb/opera1.c
+++ b/drivers/media/usb/dvb-usb/opera1.c
@@ -4,7 +4,7 @@
 * Copyright (C) 2006 Mario Hlawitschka (dh1pa@amsat.org)
 * Copyright (C) 2006 Marco Gittler (g.marco@freenet.de)
 *
-* see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+* see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
 */
 
 #define DVB_USB_LOG_PREFIX "opera"
diff --git a/drivers/media/usb/dvb-usb/ttusb2.c b/drivers/media/usb/dvb-usb/ttusb2.c
index e12a5466b677..fd3e7312daef 100644
--- a/drivers/media/usb/dvb-usb/ttusb2.c
+++ b/drivers/media/usb/dvb-usb/ttusb2.c
@@ -17,7 +17,7 @@
  * Copyright (c) 2003 Felix Domke <tmbinc@elitedvb.net>
  * Copyright (C) 2005-6 Patrick Boettcher <pb@linuxtv.org>
  *
- * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+ * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
  */
 #define DVB_USB_LOG_PREFIX "ttusb2"
 #include "dvb-usb.h"
diff --git a/drivers/media/usb/dvb-usb/ttusb2.h b/drivers/media/usb/dvb-usb/ttusb2.h
index 8a3853cd6a26..b34c469d83f9 100644
--- a/drivers/media/usb/dvb-usb/ttusb2.h
+++ b/drivers/media/usb/dvb-usb/ttusb2.h
@@ -6,7 +6,7 @@
  * Copyright (c) 2003 Felix Domke <tmbinc@elitedvb.net>
  * Copyright (C) 2005-6 Patrick Boettcher <pb@linuxtv.de>
  *
- * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+ * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
  */
 #ifndef _DVB_USB_TTUSB2_H_
 #define _DVB_USB_TTUSB2_H_
diff --git a/drivers/media/usb/dvb-usb/umt-010.c b/drivers/media/usb/dvb-usb/umt-010.c
index a2101bd43349..2181993771ae 100644
--- a/drivers/media/usb/dvb-usb/umt-010.c
+++ b/drivers/media/usb/dvb-usb/umt-010.c
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@posteo.de)
  *
- * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+ * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
  */
 #include "dibusb.h"
 
diff --git a/drivers/media/usb/dvb-usb/vp702x-fe.c b/drivers/media/usb/dvb-usb/vp702x-fe.c
index 1c75a9c9dfca..c1e7931900ee 100644
--- a/drivers/media/usb/dvb-usb/vp702x-fe.c
+++ b/drivers/media/usb/dvb-usb/vp702x-fe.c
@@ -12,7 +12,7 @@
  * This file can be removed soon, after the DST-driver is rewritten to provice
  * the frontend-controlling separately.
  *
- * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+ * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
  */
 #include "vp702x.h"
 
diff --git a/drivers/media/usb/dvb-usb/vp702x.c b/drivers/media/usb/dvb-usb/vp702x.c
index 381b5c898a07..bf54747e2e01 100644
--- a/drivers/media/usb/dvb-usb/vp702x.c
+++ b/drivers/media/usb/dvb-usb/vp702x.c
@@ -9,7 +9,7 @@
  *
  * Thanks to Twinhan who kindly provided hardware and information.
  *
- * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+ * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
  */
 #include "vp702x.h"
 #include <linux/mutex.h>
diff --git a/drivers/media/usb/dvb-usb/vp7045-fe.c b/drivers/media/usb/dvb-usb/vp7045-fe.c
index d253307a35f8..e99740ec2650 100644
--- a/drivers/media/usb/dvb-usb/vp7045-fe.c
+++ b/drivers/media/usb/dvb-usb/vp7045-fe.c
@@ -6,7 +6,7 @@
  *
  * Thanks to Twinhan who kindly provided hardware and information.
  *
- * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+ * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
  */
 #include "vp7045.h"
 
diff --git a/drivers/media/usb/dvb-usb/vp7045.c b/drivers/media/usb/dvb-usb/vp7045.c
index 2baf57216d19..23e3a90af1f4 100644
--- a/drivers/media/usb/dvb-usb/vp7045.c
+++ b/drivers/media/usb/dvb-usb/vp7045.c
@@ -7,7 +7,7 @@
  *
  * Thanks to Twinhan who kindly provided hardware and information.
  *
- * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+ * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
  */
 #include "vp7045.h"
 
diff --git a/drivers/media/usb/dvb-usb/vp7045.h b/drivers/media/usb/dvb-usb/vp7045.h
index 818366746c41..1c8438f22b97 100644
--- a/drivers/media/usb/dvb-usb/vp7045.h
+++ b/drivers/media/usb/dvb-usb/vp7045.h
@@ -6,7 +6,7 @@
  *
  * Thanks to Twinhan who kindly provided hardware and information.
  *
- * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+ * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
  */
 #ifndef _DVB_USB_VP7045_H_
 #define _DVB_USB_VP7045_H_
diff --git a/drivers/media/usb/gspca/Kconfig b/drivers/media/usb/gspca/Kconfig
index 77a360958239..0283e3b908e4 100644
--- a/drivers/media/usb/gspca/Kconfig
+++ b/drivers/media/usb/gspca/Kconfig
@@ -9,7 +9,7 @@ menuconfig USB_GSPCA
 	  Say Y here if you want to enable selecting webcams based
 	  on the GSPCA framework.
 
-	  See <file:Documentation/media/v4l-drivers/gspca-cardlist.rst> for more info.
+	  See <file:Documentation/admin-guide/media/gspca-cardlist.rst> for more info.
 
 	  This driver uses the Video For Linux API. You must say Y or M to
 	  "Video For Linux" to use this driver.
diff --git a/drivers/media/usb/hdpvr/hdpvr-core.c b/drivers/media/usb/hdpvr/hdpvr-core.c
index b75c18a012a7..52e05a69c46e 100644
--- a/drivers/media/usb/hdpvr/hdpvr-core.c
+++ b/drivers/media/usb/hdpvr/hdpvr-core.c
@@ -363,9 +363,9 @@ static int hdpvr_probe(struct usb_interface *interface,
 	}
 
 	client = hdpvr_register_ir_i2c(dev);
-	if (!client) {
+	if (IS_ERR(client)) {
 		v4l2_err(&dev->v4l2_dev, "i2c IR device register failed\n");
-		retval = -ENODEV;
+		retval = PTR_ERR(client);
 		goto reg_fail;
 	}
 #endif
diff --git a/drivers/media/usb/hdpvr/hdpvr-i2c.c b/drivers/media/usb/hdpvr/hdpvr-i2c.c
index 785c8508a46e..070559b01b01 100644
--- a/drivers/media/usb/hdpvr/hdpvr-i2c.c
+++ b/drivers/media/usb/hdpvr/hdpvr-i2c.c
@@ -44,7 +44,7 @@ struct i2c_client *hdpvr_register_ir_i2c(struct hdpvr_device *dev)
 	init_data->polling_interval = 405; /* ms, duplicated from Windows */
 	info.platform_data = init_data;
 
-	return i2c_new_device(&dev->i2c_adapter, &info);
+	return i2c_new_client_device(&dev->i2c_adapter, &info);
 }
 
 static int hdpvr_i2c_read(struct hdpvr_device *dev, int bus,
diff --git a/drivers/media/usb/pulse8-cec/Kconfig b/drivers/media/usb/pulse8-cec/Kconfig
deleted file mode 100644
index e802d30dbbee..000000000000
--- a/drivers/media/usb/pulse8-cec/Kconfig
+++ /dev/null
@@ -1,12 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-config USB_PULSE8_CEC
-	tristate "Pulse Eight HDMI CEC"
-	depends on USB_ACM
-	select CEC_CORE
-	select SERIO
-	select SERIO_SERPORT
-	help
-	  This is a cec driver for the Pulse Eight HDMI CEC device.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called pulse8-cec.
diff --git a/drivers/media/usb/pulse8-cec/Makefile b/drivers/media/usb/pulse8-cec/Makefile
deleted file mode 100644
index 7816c68bf928..000000000000
--- a/drivers/media/usb/pulse8-cec/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_USB_PULSE8_CEC) += pulse8-cec.o
diff --git a/drivers/media/usb/pulse8-cec/pulse8-cec.c b/drivers/media/usb/pulse8-cec/pulse8-cec.c
deleted file mode 100644
index 0655aa9ecf28..000000000000
--- a/drivers/media/usb/pulse8-cec/pulse8-cec.c
+++ /dev/null
@@ -1,909 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Pulse Eight HDMI CEC driver
- *
- * Copyright 2016 Hans Verkuil <hverkuil@xs4all.nl
- */
-
-/*
- * Notes:
- *
- * - Devices with firmware version < 2 do not store their configuration in
- *   EEPROM.
- *
- * - In autonomous mode, only messages from a TV will be acknowledged, even
- *   polling messages. Upon receiving a message from a TV, the dongle will
- *   respond to messages from any logical address.
- *
- * - In autonomous mode, the dongle will by default reply Feature Abort
- *   [Unrecognized Opcode] when it receives Give Device Vendor ID. It will
- *   however observe vendor ID's reported by other devices and possibly
- *   alter this behavior. When TV's (and TV's only) report that their vendor ID
- *   is LG (0x00e091), the dongle will itself reply that it has the same vendor
- *   ID, and it will respond to at least one vendor specific command.
- *
- * - In autonomous mode, the dongle is known to attempt wakeup if it receives
- *   <User Control Pressed> ["Power On"], ["Power] or ["Power Toggle"], or if it
- *   receives <Set Stream Path> with its own physical address. It also does this
- *   if it receives <Vendor Specific Command> [0x03 0x00] from an LG TV.
- */
-
-#include <linux/completion.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/workqueue.h>
-#include <linux/serio.h>
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/delay.h>
-
-#include <media/cec.h>
-
-MODULE_AUTHOR("Hans Verkuil <hverkuil@xs4all.nl>");
-MODULE_DESCRIPTION("Pulse Eight HDMI CEC driver");
-MODULE_LICENSE("GPL");
-
-static int debug;
-static int persistent_config;
-module_param(debug, int, 0644);
-module_param(persistent_config, int, 0644);
-MODULE_PARM_DESC(debug, "debug level (0-2)");
-MODULE_PARM_DESC(persistent_config, "read config from persistent memory (0-1)");
-
-enum pulse8_msgcodes {
-	MSGCODE_NOTHING = 0,
-	MSGCODE_PING,
-	MSGCODE_TIMEOUT_ERROR,
-	MSGCODE_HIGH_ERROR,
-	MSGCODE_LOW_ERROR,
-	MSGCODE_FRAME_START,
-	MSGCODE_FRAME_DATA,
-	MSGCODE_RECEIVE_FAILED,
-	MSGCODE_COMMAND_ACCEPTED,	/* 0x08 */
-	MSGCODE_COMMAND_REJECTED,
-	MSGCODE_SET_ACK_MASK,
-	MSGCODE_TRANSMIT,
-	MSGCODE_TRANSMIT_EOM,
-	MSGCODE_TRANSMIT_IDLETIME,
-	MSGCODE_TRANSMIT_ACK_POLARITY,
-	MSGCODE_TRANSMIT_LINE_TIMEOUT,
-	MSGCODE_TRANSMIT_SUCCEEDED,	/* 0x10 */
-	MSGCODE_TRANSMIT_FAILED_LINE,
-	MSGCODE_TRANSMIT_FAILED_ACK,
-	MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA,
-	MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE,
-	MSGCODE_FIRMWARE_VERSION,
-	MSGCODE_START_BOOTLOADER,
-	MSGCODE_GET_BUILDDATE,
-	MSGCODE_SET_CONTROLLED,		/* 0x18 */
-	MSGCODE_GET_AUTO_ENABLED,
-	MSGCODE_SET_AUTO_ENABLED,
-	MSGCODE_GET_DEFAULT_LOGICAL_ADDRESS,
-	MSGCODE_SET_DEFAULT_LOGICAL_ADDRESS,
-	MSGCODE_GET_LOGICAL_ADDRESS_MASK,
-	MSGCODE_SET_LOGICAL_ADDRESS_MASK,
-	MSGCODE_GET_PHYSICAL_ADDRESS,
-	MSGCODE_SET_PHYSICAL_ADDRESS,	/* 0x20 */
-	MSGCODE_GET_DEVICE_TYPE,
-	MSGCODE_SET_DEVICE_TYPE,
-	MSGCODE_GET_HDMI_VERSION,
-	MSGCODE_SET_HDMI_VERSION,
-	MSGCODE_GET_OSD_NAME,
-	MSGCODE_SET_OSD_NAME,
-	MSGCODE_WRITE_EEPROM,
-	MSGCODE_GET_ADAPTER_TYPE,	/* 0x28 */
-	MSGCODE_SET_ACTIVE_SOURCE,
-
-	MSGCODE_FRAME_EOM = 0x80,
-	MSGCODE_FRAME_ACK = 0x40,
-};
-
-static const char * const pulse8_msgnames[] = {
-	"NOTHING",
-	"PING",
-	"TIMEOUT_ERROR",
-	"HIGH_ERROR",
-	"LOW_ERROR",
-	"FRAME_START",
-	"FRAME_DATA",
-	"RECEIVE_FAILED",
-	"COMMAND_ACCEPTED",
-	"COMMAND_REJECTED",
-	"SET_ACK_MASK",
-	"TRANSMIT",
-	"TRANSMIT_EOM",
-	"TRANSMIT_IDLETIME",
-	"TRANSMIT_ACK_POLARITY",
-	"TRANSMIT_LINE_TIMEOUT",
-	"TRANSMIT_SUCCEEDED",
-	"TRANSMIT_FAILED_LINE",
-	"TRANSMIT_FAILED_ACK",
-	"TRANSMIT_FAILED_TIMEOUT_DATA",
-	"TRANSMIT_FAILED_TIMEOUT_LINE",
-	"FIRMWARE_VERSION",
-	"START_BOOTLOADER",
-	"GET_BUILDDATE",
-	"SET_CONTROLLED",
-	"GET_AUTO_ENABLED",
-	"SET_AUTO_ENABLED",
-	"GET_DEFAULT_LOGICAL_ADDRESS",
-	"SET_DEFAULT_LOGICAL_ADDRESS",
-	"GET_LOGICAL_ADDRESS_MASK",
-	"SET_LOGICAL_ADDRESS_MASK",
-	"GET_PHYSICAL_ADDRESS",
-	"SET_PHYSICAL_ADDRESS",
-	"GET_DEVICE_TYPE",
-	"SET_DEVICE_TYPE",
-	"GET_HDMI_VERSION",
-	"SET_HDMI_VERSION",
-	"GET_OSD_NAME",
-	"SET_OSD_NAME",
-	"WRITE_EEPROM",
-	"GET_ADAPTER_TYPE",
-	"SET_ACTIVE_SOURCE",
-};
-
-static const char *pulse8_msgname(u8 cmd)
-{
-	static char unknown_msg[5];
-
-	if ((cmd & 0x3f) < ARRAY_SIZE(pulse8_msgnames))
-		return pulse8_msgnames[cmd & 0x3f];
-	snprintf(unknown_msg, sizeof(unknown_msg), "0x%02x", cmd);
-	return unknown_msg;
-}
-
-#define MSGSTART	0xff
-#define MSGEND		0xfe
-#define MSGESC		0xfd
-#define MSGOFFSET	3
-
-#define DATA_SIZE 256
-
-#define PING_PERIOD	(15 * HZ)
-
-#define NUM_MSGS 8
-
-struct pulse8 {
-	struct device *dev;
-	struct serio *serio;
-	struct cec_adapter *adap;
-	unsigned int vers;
-
-	struct delayed_work ping_eeprom_work;
-
-	struct work_struct irq_work;
-	struct cec_msg rx_msg[NUM_MSGS];
-	unsigned int rx_msg_cur_idx, rx_msg_num;
-	/* protect rx_msg_cur_idx and rx_msg_num */
-	spinlock_t msg_lock;
-	u8 new_rx_msg[CEC_MAX_MSG_SIZE];
-	u8 new_rx_msg_len;
-
-	struct work_struct tx_work;
-	u32 tx_done_status;
-	u32 tx_signal_free_time;
-	struct cec_msg tx_msg;
-	bool tx_msg_is_bcast;
-
-	struct completion cmd_done;
-	u8 data[DATA_SIZE];
-	unsigned int len;
-	u8 buf[DATA_SIZE];
-	unsigned int idx;
-	bool escape;
-	bool started;
-
-	/* locks access to the adapter */
-	struct mutex lock;
-	bool config_pending;
-	bool restoring_config;
-	bool autonomous;
-};
-
-static int pulse8_send(struct serio *serio, const u8 *command, u8 cmd_len)
-{
-	int err = 0;
-
-	err = serio_write(serio, MSGSTART);
-	if (err)
-		return err;
-	for (; !err && cmd_len; command++, cmd_len--) {
-		if (*command >= MSGESC) {
-			err = serio_write(serio, MSGESC);
-			if (!err)
-				err = serio_write(serio, *command - MSGOFFSET);
-		} else {
-			err = serio_write(serio, *command);
-		}
-	}
-	if (!err)
-		err = serio_write(serio, MSGEND);
-
-	return err;
-}
-
-static int pulse8_send_and_wait_once(struct pulse8 *pulse8,
-				     const u8 *cmd, u8 cmd_len,
-				     u8 response, u8 size)
-{
-	int err;
-
-	if (debug > 1)
-		dev_info(pulse8->dev, "transmit %s: %*ph\n",
-			 pulse8_msgname(cmd[0]), cmd_len, cmd);
-	init_completion(&pulse8->cmd_done);
-
-	err = pulse8_send(pulse8->serio, cmd, cmd_len);
-	if (err)
-		return err;
-
-	if (!wait_for_completion_timeout(&pulse8->cmd_done, HZ))
-		return -ETIMEDOUT;
-	if ((pulse8->data[0] & 0x3f) == MSGCODE_COMMAND_REJECTED &&
-	    cmd[0] != MSGCODE_SET_CONTROLLED &&
-	    cmd[0] != MSGCODE_SET_AUTO_ENABLED &&
-	    cmd[0] != MSGCODE_GET_BUILDDATE)
-		return -ENOTTY;
-	if (response &&
-	    ((pulse8->data[0] & 0x3f) != response || pulse8->len < size + 1)) {
-		dev_info(pulse8->dev, "transmit %s failed with %s\n",
-			 pulse8_msgname(cmd[0]),
-			 pulse8_msgname(pulse8->data[0]));
-		return -EIO;
-	}
-	return 0;
-}
-
-static int pulse8_send_and_wait(struct pulse8 *pulse8,
-				const u8 *cmd, u8 cmd_len, u8 response, u8 size)
-{
-	u8 cmd_sc[2];
-	int err;
-
-	err = pulse8_send_and_wait_once(pulse8, cmd, cmd_len, response, size);
-	if (err != -ENOTTY)
-		return err;
-
-	cmd_sc[0] = MSGCODE_SET_CONTROLLED;
-	cmd_sc[1] = 1;
-	err = pulse8_send_and_wait_once(pulse8, cmd_sc, 2,
-					MSGCODE_COMMAND_ACCEPTED, 1);
-	if (!err)
-		err = pulse8_send_and_wait_once(pulse8, cmd, cmd_len,
-						response, size);
-	return err == -ENOTTY ? -EIO : err;
-}
-
-static void pulse8_tx_work_handler(struct work_struct *work)
-{
-	struct pulse8 *pulse8 = container_of(work, struct pulse8, tx_work);
-	struct cec_msg *msg = &pulse8->tx_msg;
-	unsigned int i;
-	u8 cmd[2];
-	int err;
-
-	if (msg->len == 0)
-		return;
-
-	mutex_lock(&pulse8->lock);
-	cmd[0] = MSGCODE_TRANSMIT_IDLETIME;
-	cmd[1] = pulse8->tx_signal_free_time;
-	err = pulse8_send_and_wait(pulse8, cmd, 2,
-				   MSGCODE_COMMAND_ACCEPTED, 1);
-	cmd[0] = MSGCODE_TRANSMIT_ACK_POLARITY;
-	cmd[1] = cec_msg_is_broadcast(msg);
-	pulse8->tx_msg_is_bcast = cec_msg_is_broadcast(msg);
-	if (!err)
-		err = pulse8_send_and_wait(pulse8, cmd, 2,
-					   MSGCODE_COMMAND_ACCEPTED, 1);
-	cmd[0] = msg->len == 1 ? MSGCODE_TRANSMIT_EOM : MSGCODE_TRANSMIT;
-	cmd[1] = msg->msg[0];
-	if (!err)
-		err = pulse8_send_and_wait(pulse8, cmd, 2,
-					   MSGCODE_COMMAND_ACCEPTED, 1);
-	if (!err && msg->len > 1) {
-		for (i = 1; !err && i < msg->len; i++) {
-			cmd[0] = ((i == msg->len - 1)) ?
-				MSGCODE_TRANSMIT_EOM : MSGCODE_TRANSMIT;
-			cmd[1] = msg->msg[i];
-			err = pulse8_send_and_wait(pulse8, cmd, 2,
-						   MSGCODE_COMMAND_ACCEPTED, 1);
-		}
-	}
-	if (err && debug)
-		dev_info(pulse8->dev, "%s(0x%02x) failed with error %d for msg %*ph\n",
-			 pulse8_msgname(cmd[0]), cmd[1],
-			 err, msg->len, msg->msg);
-	msg->len = 0;
-	mutex_unlock(&pulse8->lock);
-	if (err)
-		cec_transmit_attempt_done(pulse8->adap, CEC_TX_STATUS_ERROR);
-}
-
-static void pulse8_irq_work_handler(struct work_struct *work)
-{
-	struct pulse8 *pulse8 =
-		container_of(work, struct pulse8, irq_work);
-	unsigned long flags;
-	u32 status;
-
-	spin_lock_irqsave(&pulse8->msg_lock, flags);
-	while (pulse8->rx_msg_num) {
-		spin_unlock_irqrestore(&pulse8->msg_lock, flags);
-		if (debug)
-			dev_info(pulse8->dev, "adap received %*ph\n",
-				 pulse8->rx_msg[pulse8->rx_msg_cur_idx].len,
-				 pulse8->rx_msg[pulse8->rx_msg_cur_idx].msg);
-		cec_received_msg(pulse8->adap,
-				 &pulse8->rx_msg[pulse8->rx_msg_cur_idx]);
-		spin_lock_irqsave(&pulse8->msg_lock, flags);
-		if (pulse8->rx_msg_num)
-			pulse8->rx_msg_num--;
-		pulse8->rx_msg_cur_idx =
-			(pulse8->rx_msg_cur_idx + 1) % NUM_MSGS;
-	}
-	spin_unlock_irqrestore(&pulse8->msg_lock, flags);
-
-	mutex_lock(&pulse8->lock);
-	status = pulse8->tx_done_status;
-	pulse8->tx_done_status = 0;
-	mutex_unlock(&pulse8->lock);
-	if (status)
-		cec_transmit_attempt_done(pulse8->adap, status);
-}
-
-static irqreturn_t pulse8_interrupt(struct serio *serio, unsigned char data,
-				    unsigned int flags)
-{
-	struct pulse8 *pulse8 = serio_get_drvdata(serio);
-	unsigned long irq_flags;
-	unsigned int idx;
-
-	if (!pulse8->started && data != MSGSTART)
-		return IRQ_HANDLED;
-	if (data == MSGESC) {
-		pulse8->escape = true;
-		return IRQ_HANDLED;
-	}
-	if (pulse8->escape) {
-		data += MSGOFFSET;
-		pulse8->escape = false;
-	} else if (data == MSGEND) {
-		u8 msgcode = pulse8->buf[0];
-
-		if (debug > 1)
-			dev_info(pulse8->dev, "received %s: %*ph\n",
-				 pulse8_msgname(msgcode),
-				 pulse8->idx, pulse8->buf);
-		switch (msgcode & 0x3f) {
-		case MSGCODE_FRAME_START:
-			/*
-			 * Test if we are receiving a new msg when a previous
-			 * message is still pending.
-			 */
-			if (!(msgcode & MSGCODE_FRAME_EOM)) {
-				pulse8->new_rx_msg_len = 1;
-				pulse8->new_rx_msg[0] = pulse8->buf[1];
-				break;
-			}
-			/* fall through */
-		case MSGCODE_FRAME_DATA:
-			if (pulse8->new_rx_msg_len < CEC_MAX_MSG_SIZE)
-				pulse8->new_rx_msg[pulse8->new_rx_msg_len++] =
-					pulse8->buf[1];
-			if (!(msgcode & MSGCODE_FRAME_EOM))
-				break;
-
-			spin_lock_irqsave(&pulse8->msg_lock, irq_flags);
-			idx = (pulse8->rx_msg_cur_idx + pulse8->rx_msg_num) %
-				NUM_MSGS;
-			if (pulse8->rx_msg_num == NUM_MSGS) {
-				dev_warn(pulse8->dev,
-					 "message queue is full, dropping %*ph\n",
-					 pulse8->new_rx_msg_len,
-					 pulse8->new_rx_msg);
-				spin_unlock_irqrestore(&pulse8->msg_lock,
-						       irq_flags);
-				pulse8->new_rx_msg_len = 0;
-				break;
-			}
-			pulse8->rx_msg_num++;
-			memcpy(pulse8->rx_msg[idx].msg, pulse8->new_rx_msg,
-			       pulse8->new_rx_msg_len);
-			pulse8->rx_msg[idx].len = pulse8->new_rx_msg_len;
-			spin_unlock_irqrestore(&pulse8->msg_lock, irq_flags);
-			schedule_work(&pulse8->irq_work);
-			pulse8->new_rx_msg_len = 0;
-			break;
-		case MSGCODE_TRANSMIT_SUCCEEDED:
-			WARN_ON(pulse8->tx_done_status);
-			pulse8->tx_done_status = CEC_TX_STATUS_OK;
-			schedule_work(&pulse8->irq_work);
-			break;
-		case MSGCODE_TRANSMIT_FAILED_ACK:
-			/*
-			 * A NACK for a broadcast message makes no sense, these
-			 * seem to be spurious messages and are skipped.
-			 */
-			if (pulse8->tx_msg_is_bcast)
-				break;
-			WARN_ON(pulse8->tx_done_status);
-			pulse8->tx_done_status = CEC_TX_STATUS_NACK;
-			schedule_work(&pulse8->irq_work);
-			break;
-		case MSGCODE_TRANSMIT_FAILED_LINE:
-		case MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA:
-		case MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE:
-			WARN_ON(pulse8->tx_done_status);
-			pulse8->tx_done_status = CEC_TX_STATUS_ERROR;
-			schedule_work(&pulse8->irq_work);
-			break;
-		case MSGCODE_HIGH_ERROR:
-		case MSGCODE_LOW_ERROR:
-		case MSGCODE_RECEIVE_FAILED:
-		case MSGCODE_TIMEOUT_ERROR:
-			pulse8->new_rx_msg_len = 0;
-			break;
-		case MSGCODE_COMMAND_ACCEPTED:
-		case MSGCODE_COMMAND_REJECTED:
-		default:
-			if (pulse8->idx == 0)
-				break;
-			memcpy(pulse8->data, pulse8->buf, pulse8->idx);
-			pulse8->len = pulse8->idx;
-			complete(&pulse8->cmd_done);
-			break;
-		}
-		pulse8->idx = 0;
-		pulse8->started = false;
-		return IRQ_HANDLED;
-	} else if (data == MSGSTART) {
-		pulse8->idx = 0;
-		pulse8->started = true;
-		return IRQ_HANDLED;
-	}
-
-	if (pulse8->idx >= DATA_SIZE) {
-		dev_dbg(pulse8->dev,
-			"throwing away %d bytes of garbage\n", pulse8->idx);
-		pulse8->idx = 0;
-	}
-	pulse8->buf[pulse8->idx++] = data;
-	return IRQ_HANDLED;
-}
-
-static int pulse8_cec_adap_enable(struct cec_adapter *adap, bool enable)
-{
-	struct pulse8 *pulse8 = cec_get_drvdata(adap);
-	u8 cmd[16];
-	int err;
-
-	mutex_lock(&pulse8->lock);
-	cmd[0] = MSGCODE_SET_CONTROLLED;
-	cmd[1] = enable;
-	err = pulse8_send_and_wait(pulse8, cmd, 2,
-				   MSGCODE_COMMAND_ACCEPTED, 1);
-	if (!enable) {
-		pulse8->rx_msg_num = 0;
-		pulse8->tx_done_status = 0;
-	}
-	mutex_unlock(&pulse8->lock);
-	return enable ? err : 0;
-}
-
-static int pulse8_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr)
-{
-	struct pulse8 *pulse8 = cec_get_drvdata(adap);
-	u16 mask = 0;
-	u16 pa = adap->phys_addr;
-	u8 cmd[16];
-	int err = 0;
-
-	mutex_lock(&pulse8->lock);
-	if (log_addr != CEC_LOG_ADDR_INVALID)
-		mask = 1 << log_addr;
-	cmd[0] = MSGCODE_SET_ACK_MASK;
-	cmd[1] = mask >> 8;
-	cmd[2] = mask & 0xff;
-	err = pulse8_send_and_wait(pulse8, cmd, 3,
-				   MSGCODE_COMMAND_ACCEPTED, 0);
-	if ((err && mask != 0) || pulse8->restoring_config)
-		goto unlock;
-
-	cmd[0] = MSGCODE_SET_AUTO_ENABLED;
-	cmd[1] = log_addr == CEC_LOG_ADDR_INVALID ? 0 : 1;
-	err = pulse8_send_and_wait(pulse8, cmd, 2,
-				   MSGCODE_COMMAND_ACCEPTED, 0);
-	if (err)
-		goto unlock;
-	pulse8->autonomous = cmd[1];
-	if (log_addr == CEC_LOG_ADDR_INVALID)
-		goto unlock;
-
-	cmd[0] = MSGCODE_SET_DEVICE_TYPE;
-	cmd[1] = adap->log_addrs.primary_device_type[0];
-	err = pulse8_send_and_wait(pulse8, cmd, 2,
-				   MSGCODE_COMMAND_ACCEPTED, 0);
-	if (err)
-		goto unlock;
-
-	switch (adap->log_addrs.primary_device_type[0]) {
-	case CEC_OP_PRIM_DEVTYPE_TV:
-		mask = CEC_LOG_ADDR_MASK_TV;
-		break;
-	case CEC_OP_PRIM_DEVTYPE_RECORD:
-		mask = CEC_LOG_ADDR_MASK_RECORD;
-		break;
-	case CEC_OP_PRIM_DEVTYPE_TUNER:
-		mask = CEC_LOG_ADDR_MASK_TUNER;
-		break;
-	case CEC_OP_PRIM_DEVTYPE_PLAYBACK:
-		mask = CEC_LOG_ADDR_MASK_PLAYBACK;
-		break;
-	case CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM:
-		mask = CEC_LOG_ADDR_MASK_AUDIOSYSTEM;
-		break;
-	case CEC_OP_PRIM_DEVTYPE_SWITCH:
-		mask = CEC_LOG_ADDR_MASK_UNREGISTERED;
-		break;
-	case CEC_OP_PRIM_DEVTYPE_PROCESSOR:
-		mask = CEC_LOG_ADDR_MASK_SPECIFIC;
-		break;
-	default:
-		mask = 0;
-		break;
-	}
-	cmd[0] = MSGCODE_SET_LOGICAL_ADDRESS_MASK;
-	cmd[1] = mask >> 8;
-	cmd[2] = mask & 0xff;
-	err = pulse8_send_and_wait(pulse8, cmd, 3,
-				   MSGCODE_COMMAND_ACCEPTED, 0);
-	if (err)
-		goto unlock;
-
-	cmd[0] = MSGCODE_SET_DEFAULT_LOGICAL_ADDRESS;
-	cmd[1] = log_addr;
-	err = pulse8_send_and_wait(pulse8, cmd, 2,
-				   MSGCODE_COMMAND_ACCEPTED, 0);
-	if (err)
-		goto unlock;
-
-	cmd[0] = MSGCODE_SET_PHYSICAL_ADDRESS;
-	cmd[1] = pa >> 8;
-	cmd[2] = pa & 0xff;
-	err = pulse8_send_and_wait(pulse8, cmd, 3,
-				   MSGCODE_COMMAND_ACCEPTED, 0);
-	if (err)
-		goto unlock;
-
-	cmd[0] = MSGCODE_SET_HDMI_VERSION;
-	cmd[1] = adap->log_addrs.cec_version;
-	err = pulse8_send_and_wait(pulse8, cmd, 2,
-				   MSGCODE_COMMAND_ACCEPTED, 0);
-	if (err)
-		goto unlock;
-
-	if (adap->log_addrs.osd_name[0]) {
-		size_t osd_len = strlen(adap->log_addrs.osd_name);
-		char *osd_str = cmd + 1;
-
-		cmd[0] = MSGCODE_SET_OSD_NAME;
-		strscpy(cmd + 1, adap->log_addrs.osd_name, sizeof(cmd) - 1);
-		if (osd_len < 4) {
-			memset(osd_str + osd_len, ' ', 4 - osd_len);
-			osd_len = 4;
-			osd_str[osd_len] = '\0';
-			strscpy(adap->log_addrs.osd_name, osd_str,
-				sizeof(adap->log_addrs.osd_name));
-		}
-		err = pulse8_send_and_wait(pulse8, cmd, 1 + osd_len,
-					   MSGCODE_COMMAND_ACCEPTED, 0);
-		if (err)
-			goto unlock;
-	}
-
-unlock:
-	if (pulse8->restoring_config)
-		pulse8->restoring_config = false;
-	else
-		pulse8->config_pending = true;
-	mutex_unlock(&pulse8->lock);
-	return log_addr == CEC_LOG_ADDR_INVALID ? 0 : err;
-}
-
-static int pulse8_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
-				    u32 signal_free_time, struct cec_msg *msg)
-{
-	struct pulse8 *pulse8 = cec_get_drvdata(adap);
-
-	pulse8->tx_msg = *msg;
-	if (debug)
-		dev_info(pulse8->dev, "adap transmit %*ph\n",
-			 msg->len, msg->msg);
-	pulse8->tx_signal_free_time = signal_free_time;
-	schedule_work(&pulse8->tx_work);
-	return 0;
-}
-
-static void pulse8_cec_adap_free(struct cec_adapter *adap)
-{
-	struct pulse8 *pulse8 = cec_get_drvdata(adap);
-
-	cancel_delayed_work_sync(&pulse8->ping_eeprom_work);
-	cancel_work_sync(&pulse8->irq_work);
-	cancel_work_sync(&pulse8->tx_work);
-	kfree(pulse8);
-}
-
-static const struct cec_adap_ops pulse8_cec_adap_ops = {
-	.adap_enable = pulse8_cec_adap_enable,
-	.adap_log_addr = pulse8_cec_adap_log_addr,
-	.adap_transmit = pulse8_cec_adap_transmit,
-	.adap_free = pulse8_cec_adap_free,
-};
-
-static void pulse8_disconnect(struct serio *serio)
-{
-	struct pulse8 *pulse8 = serio_get_drvdata(serio);
-
-	cec_unregister_adapter(pulse8->adap);
-	pulse8->serio = NULL;
-	serio_set_drvdata(serio, NULL);
-	serio_close(serio);
-}
-
-static int pulse8_setup(struct pulse8 *pulse8, struct serio *serio,
-			struct cec_log_addrs *log_addrs, u16 *pa)
-{
-	u8 *data = pulse8->data + 1;
-	u8 cmd[2];
-	int err;
-	struct tm tm;
-	time64_t date;
-
-	pulse8->vers = 0;
-
-	cmd[0] = MSGCODE_FIRMWARE_VERSION;
-	err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 2);
-	if (err)
-		return err;
-	pulse8->vers = (data[0] << 8) | data[1];
-	dev_info(pulse8->dev, "Firmware version %04x\n", pulse8->vers);
-	if (pulse8->vers < 2) {
-		*pa = CEC_PHYS_ADDR_INVALID;
-		return 0;
-	}
-
-	cmd[0] = MSGCODE_GET_BUILDDATE;
-	err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 4);
-	if (err)
-		return err;
-	date = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
-	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);
-
-	dev_dbg(pulse8->dev, "Persistent config:\n");
-	cmd[0] = MSGCODE_GET_AUTO_ENABLED;
-	err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 1);
-	if (err)
-		return err;
-	pulse8->autonomous = data[0];
-	dev_dbg(pulse8->dev, "Autonomous mode: %s",
-		data[0] ? "on" : "off");
-
-	cmd[0] = MSGCODE_GET_DEVICE_TYPE;
-	err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 1);
-	if (err)
-		return err;
-	log_addrs->primary_device_type[0] = data[0];
-	dev_dbg(pulse8->dev, "Primary device type: %d\n", data[0]);
-	switch (log_addrs->primary_device_type[0]) {
-	case CEC_OP_PRIM_DEVTYPE_TV:
-		log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_TV;
-		log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_TV;
-		break;
-	case CEC_OP_PRIM_DEVTYPE_RECORD:
-		log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_RECORD;
-		log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_RECORD;
-		break;
-	case CEC_OP_PRIM_DEVTYPE_TUNER:
-		log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_TUNER;
-		log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_TUNER;
-		break;
-	case CEC_OP_PRIM_DEVTYPE_PLAYBACK:
-		log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_PLAYBACK;
-		log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_PLAYBACK;
-		break;
-	case CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM:
-		log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_PLAYBACK;
-		log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_AUDIOSYSTEM;
-		break;
-	case CEC_OP_PRIM_DEVTYPE_SWITCH:
-		log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_UNREGISTERED;
-		log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_SWITCH;
-		break;
-	case CEC_OP_PRIM_DEVTYPE_PROCESSOR:
-		log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_SPECIFIC;
-		log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_SWITCH;
-		break;
-	default:
-		log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_UNREGISTERED;
-		log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_SWITCH;
-		dev_info(pulse8->dev, "Unknown Primary Device Type: %d\n",
-			 log_addrs->primary_device_type[0]);
-		break;
-	}
-
-	cmd[0] = MSGCODE_GET_LOGICAL_ADDRESS_MASK;
-	err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 2);
-	if (err)
-		return err;
-	log_addrs->log_addr_mask = (data[0] << 8) | data[1];
-	dev_dbg(pulse8->dev, "Logical address ACK mask: %x\n",
-		log_addrs->log_addr_mask);
-	if (log_addrs->log_addr_mask)
-		log_addrs->num_log_addrs = 1;
-
-	cmd[0] = MSGCODE_GET_PHYSICAL_ADDRESS;
-	err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 1);
-	if (err)
-		return err;
-	*pa = (data[0] << 8) | data[1];
-	dev_dbg(pulse8->dev, "Physical address: %x.%x.%x.%x\n",
-		cec_phys_addr_exp(*pa));
-
-	cmd[0] = MSGCODE_GET_HDMI_VERSION;
-	err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 1);
-	if (err)
-		return err;
-	log_addrs->cec_version = data[0];
-	dev_dbg(pulse8->dev, "CEC version: %d\n", log_addrs->cec_version);
-
-	cmd[0] = MSGCODE_GET_OSD_NAME;
-	err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 0);
-	if (err)
-		return err;
-	strscpy(log_addrs->osd_name, data, sizeof(log_addrs->osd_name));
-	dev_dbg(pulse8->dev, "OSD name: %s\n", log_addrs->osd_name);
-
-	return 0;
-}
-
-static int pulse8_apply_persistent_config(struct pulse8 *pulse8,
-					  struct cec_log_addrs *log_addrs,
-					  u16 pa)
-{
-	int err;
-
-	err = cec_s_log_addrs(pulse8->adap, log_addrs, false);
-	if (err)
-		return err;
-
-	cec_s_phys_addr(pulse8->adap, pa, false);
-
-	return 0;
-}
-
-static void pulse8_ping_eeprom_work_handler(struct work_struct *work)
-{
-	struct pulse8 *pulse8 =
-		container_of(work, struct pulse8, ping_eeprom_work.work);
-	u8 cmd;
-
-	mutex_lock(&pulse8->lock);
-	cmd = MSGCODE_PING;
-	pulse8_send_and_wait(pulse8, &cmd, 1,
-			     MSGCODE_COMMAND_ACCEPTED, 0);
-
-	if (pulse8->vers < 2)
-		goto unlock;
-
-	if (pulse8->config_pending && persistent_config) {
-		dev_dbg(pulse8->dev, "writing pending config to EEPROM\n");
-		cmd = MSGCODE_WRITE_EEPROM;
-		if (pulse8_send_and_wait(pulse8, &cmd, 1,
-					 MSGCODE_COMMAND_ACCEPTED, 0))
-			dev_info(pulse8->dev, "failed to write pending config to EEPROM\n");
-		else
-			pulse8->config_pending = false;
-	}
-unlock:
-	schedule_delayed_work(&pulse8->ping_eeprom_work, PING_PERIOD);
-	mutex_unlock(&pulse8->lock);
-}
-
-static int pulse8_connect(struct serio *serio, struct serio_driver *drv)
-{
-	u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_PHYS_ADDR | CEC_CAP_MONITOR_ALL;
-	struct pulse8 *pulse8;
-	int err = -ENOMEM;
-	struct cec_log_addrs log_addrs = {};
-	u16 pa = CEC_PHYS_ADDR_INVALID;
-
-	pulse8 = kzalloc(sizeof(*pulse8), GFP_KERNEL);
-
-	if (!pulse8)
-		return -ENOMEM;
-
-	pulse8->serio = serio;
-	pulse8->adap = cec_allocate_adapter(&pulse8_cec_adap_ops, pulse8,
-					    dev_name(&serio->dev), caps, 1);
-	err = PTR_ERR_OR_ZERO(pulse8->adap);
-	if (err < 0)
-		goto free_device;
-
-	pulse8->dev = &serio->dev;
-	serio_set_drvdata(serio, pulse8);
-	INIT_WORK(&pulse8->irq_work, pulse8_irq_work_handler);
-	INIT_WORK(&pulse8->tx_work, pulse8_tx_work_handler);
-	INIT_DELAYED_WORK(&pulse8->ping_eeprom_work,
-			  pulse8_ping_eeprom_work_handler);
-	mutex_init(&pulse8->lock);
-	spin_lock_init(&pulse8->msg_lock);
-	pulse8->config_pending = false;
-
-	err = serio_open(serio, drv);
-	if (err)
-		goto delete_adap;
-
-	err = pulse8_setup(pulse8, serio, &log_addrs, &pa);
-	if (err)
-		goto close_serio;
-
-	err = cec_register_adapter(pulse8->adap, &serio->dev);
-	if (err < 0)
-		goto close_serio;
-
-	pulse8->dev = &pulse8->adap->devnode.dev;
-
-	if (persistent_config && pulse8->autonomous) {
-		err = pulse8_apply_persistent_config(pulse8, &log_addrs, pa);
-		if (err)
-			goto close_serio;
-		pulse8->restoring_config = true;
-	}
-
-	schedule_delayed_work(&pulse8->ping_eeprom_work, PING_PERIOD);
-
-	return 0;
-
-close_serio:
-	pulse8->serio = NULL;
-	serio_set_drvdata(serio, NULL);
-	serio_close(serio);
-delete_adap:
-	cec_delete_adapter(pulse8->adap);
-free_device:
-	kfree(pulse8);
-	return err;
-}
-
-static const struct serio_device_id pulse8_serio_ids[] = {
-	{
-		.type	= SERIO_RS232,
-		.proto	= SERIO_PULSE8_CEC,
-		.id	= SERIO_ANY,
-		.extra	= SERIO_ANY,
-	},
-	{ 0 }
-};
-
-MODULE_DEVICE_TABLE(serio, pulse8_serio_ids);
-
-static struct serio_driver pulse8_drv = {
-	.driver		= {
-		.name	= "pulse8-cec",
-	},
-	.description	= "Pulse Eight HDMI CEC driver",
-	.id_table	= pulse8_serio_ids,
-	.interrupt	= pulse8_interrupt,
-	.connect	= pulse8_connect,
-	.disconnect	= pulse8_disconnect,
-};
-
-module_serio_driver(pulse8_drv);
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c
index 275394bafe7d..63db04fe12d3 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c
@@ -564,7 +564,7 @@ static void pvr2_i2c_register_ir(struct pvr2_hdw *hdw)
 		strscpy(info.type, "ir_video", 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);
+		i2c_new_client_device(&hdw->i2c_adap, &info);
 		break;
 	case PVR2_IR_SCHEME_ZILOG:     /* HVR-1950 style */
 	case PVR2_IR_SCHEME_24XXX_MCE: /* 24xxx MCE device */
@@ -579,7 +579,7 @@ static void pvr2_i2c_register_ir(struct pvr2_hdw *hdw)
 		strscpy(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);
+		i2c_new_client_device(&hdw->i2c_adap, &info);
 		break;
 	default:
 		/* The device either doesn't support I2C-based IR or we
diff --git a/drivers/media/usb/rainshadow-cec/Kconfig b/drivers/media/usb/rainshadow-cec/Kconfig
deleted file mode 100644
index b481c5157d7e..000000000000
--- a/drivers/media/usb/rainshadow-cec/Kconfig
+++ /dev/null
@@ -1,12 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-config USB_RAINSHADOW_CEC
-	tristate "RainShadow Tech HDMI CEC"
-	depends on USB_ACM
-	select CEC_CORE
-	select SERIO
-	select SERIO_SERPORT
-	help
-	  This is a cec driver for the RainShadow Tech HDMI CEC device.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called rainshadow-cec.
diff --git a/drivers/media/usb/rainshadow-cec/Makefile b/drivers/media/usb/rainshadow-cec/Makefile
deleted file mode 100644
index 47b33c574c3e..000000000000
--- a/drivers/media/usb/rainshadow-cec/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_USB_RAINSHADOW_CEC) += rainshadow-cec.o
diff --git a/drivers/media/usb/rainshadow-cec/rainshadow-cec.c b/drivers/media/usb/rainshadow-cec/rainshadow-cec.c
deleted file mode 100644
index ee870ea1a886..000000000000
--- a/drivers/media/usb/rainshadow-cec/rainshadow-cec.c
+++ /dev/null
@@ -1,380 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * RainShadow Tech HDMI CEC driver
- *
- * Copyright 2016 Hans Verkuil <hverkuil@xs4all.nl
- */
-
-/*
- * Notes:
- *
- * The higher level protocols are currently disabled. This can be added
- * later, similar to how this is done for the Pulse Eight CEC driver.
- *
- * Documentation of the protocol is available here:
- *
- * http://rainshadowtech.com/doc/HDMICECtoUSBandRS232v2.0.pdf
- */
-
-#include <linux/completion.h>
-#include <linux/ctype.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/serio.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/time.h>
-#include <linux/workqueue.h>
-
-#include <media/cec.h>
-
-MODULE_AUTHOR("Hans Verkuil <hverkuil@xs4all.nl>");
-MODULE_DESCRIPTION("RainShadow Tech HDMI CEC driver");
-MODULE_LICENSE("GPL");
-
-#define DATA_SIZE 256
-
-struct rain {
-	struct device *dev;
-	struct serio *serio;
-	struct cec_adapter *adap;
-	struct completion cmd_done;
-	struct work_struct work;
-
-	/* Low-level ringbuffer, collecting incoming characters */
-	char buf[DATA_SIZE];
-	unsigned int buf_rd_idx;
-	unsigned int buf_wr_idx;
-	unsigned int buf_len;
-	spinlock_t buf_lock;
-
-	/* command buffer */
-	char cmd[DATA_SIZE];
-	unsigned int cmd_idx;
-	bool cmd_started;
-
-	/* reply to a command, only used to store the firmware version */
-	char cmd_reply[DATA_SIZE];
-
-	struct mutex write_lock;
-};
-
-static void rain_process_msg(struct rain *rain)
-{
-	struct cec_msg msg = {};
-	const char *cmd = rain->cmd + 3;
-	int stat = -1;
-
-	for (; *cmd; cmd++) {
-		if (!isxdigit(*cmd))
-			continue;
-		if (isxdigit(cmd[0]) && isxdigit(cmd[1])) {
-			if (msg.len == CEC_MAX_MSG_SIZE)
-				break;
-			if (hex2bin(msg.msg + msg.len, cmd, 1))
-				continue;
-			msg.len++;
-			cmd++;
-			continue;
-		}
-		if (!cmd[1])
-			stat = hex_to_bin(cmd[0]);
-		break;
-	}
-
-	if (rain->cmd[0] == 'R') {
-		if (stat == 1 || stat == 2)
-			cec_received_msg(rain->adap, &msg);
-		return;
-	}
-
-	switch (stat) {
-	case 1:
-		cec_transmit_attempt_done(rain->adap, CEC_TX_STATUS_OK);
-		break;
-	case 2:
-		cec_transmit_attempt_done(rain->adap, CEC_TX_STATUS_NACK);
-		break;
-	default:
-		cec_transmit_attempt_done(rain->adap, CEC_TX_STATUS_LOW_DRIVE);
-		break;
-	}
-}
-
-static void rain_irq_work_handler(struct work_struct *work)
-{
-	struct rain *rain =
-		container_of(work, struct rain, work);
-
-	while (true) {
-		unsigned long flags;
-		char data;
-
-		spin_lock_irqsave(&rain->buf_lock, flags);
-		if (!rain->buf_len) {
-			spin_unlock_irqrestore(&rain->buf_lock, flags);
-			break;
-		}
-
-		data = rain->buf[rain->buf_rd_idx];
-		rain->buf_len--;
-		rain->buf_rd_idx = (rain->buf_rd_idx + 1) & 0xff;
-
-		spin_unlock_irqrestore(&rain->buf_lock, flags);
-
-		if (!rain->cmd_started && data != '?')
-			continue;
-
-		switch (data) {
-		case '\r':
-			rain->cmd[rain->cmd_idx] = '\0';
-			dev_dbg(rain->dev, "received: %s\n", rain->cmd);
-			if (!memcmp(rain->cmd, "REC", 3) ||
-			    !memcmp(rain->cmd, "STA", 3)) {
-				rain_process_msg(rain);
-			} else {
-				strscpy(rain->cmd_reply, rain->cmd,
-					sizeof(rain->cmd_reply));
-				complete(&rain->cmd_done);
-			}
-			rain->cmd_idx = 0;
-			rain->cmd_started = false;
-			break;
-
-		case '\n':
-			rain->cmd_idx = 0;
-			rain->cmd_started = false;
-			break;
-
-		case '?':
-			rain->cmd_idx = 0;
-			rain->cmd_started = true;
-			break;
-
-		default:
-			if (rain->cmd_idx >= DATA_SIZE - 1) {
-				dev_dbg(rain->dev,
-					"throwing away %d bytes of garbage\n", rain->cmd_idx);
-				rain->cmd_idx = 0;
-			}
-			rain->cmd[rain->cmd_idx++] = data;
-			break;
-		}
-	}
-}
-
-static irqreturn_t rain_interrupt(struct serio *serio, unsigned char data,
-				    unsigned int flags)
-{
-	struct rain *rain = serio_get_drvdata(serio);
-
-	if (rain->buf_len == DATA_SIZE) {
-		dev_warn_once(rain->dev, "buffer overflow\n");
-		return IRQ_HANDLED;
-	}
-	spin_lock(&rain->buf_lock);
-	rain->buf_len++;
-	rain->buf[rain->buf_wr_idx] = data;
-	rain->buf_wr_idx = (rain->buf_wr_idx + 1) & 0xff;
-	spin_unlock(&rain->buf_lock);
-	schedule_work(&rain->work);
-	return IRQ_HANDLED;
-}
-
-static void rain_disconnect(struct serio *serio)
-{
-	struct rain *rain = serio_get_drvdata(serio);
-
-	cancel_work_sync(&rain->work);
-	cec_unregister_adapter(rain->adap);
-	dev_info(&serio->dev, "disconnected\n");
-	serio_close(serio);
-	serio_set_drvdata(serio, NULL);
-	kfree(rain);
-}
-
-static int rain_send(struct rain *rain, const char *command)
-{
-	int err = serio_write(rain->serio, '!');
-
-	dev_dbg(rain->dev, "send: %s\n", command);
-	while (!err && *command)
-		err = serio_write(rain->serio, *command++);
-	if (!err)
-		err = serio_write(rain->serio, '~');
-
-	return err;
-}
-
-static int rain_send_and_wait(struct rain *rain,
-			      const char *cmd, const char *reply)
-{
-	int err;
-
-	init_completion(&rain->cmd_done);
-
-	mutex_lock(&rain->write_lock);
-	err = rain_send(rain, cmd);
-	if (err)
-		goto err;
-
-	if (!wait_for_completion_timeout(&rain->cmd_done, HZ)) {
-		err = -ETIMEDOUT;
-		goto err;
-	}
-	if (reply && strncmp(rain->cmd_reply, reply, strlen(reply))) {
-		dev_dbg(rain->dev,
-			 "transmit of '%s': received '%s' instead of '%s'\n",
-			 cmd, rain->cmd_reply, reply);
-		err = -EIO;
-	}
-err:
-	mutex_unlock(&rain->write_lock);
-	return err;
-}
-
-static int rain_setup(struct rain *rain, struct serio *serio,
-			struct cec_log_addrs *log_addrs, u16 *pa)
-{
-	int err;
-
-	err = rain_send_and_wait(rain, "R", "REV");
-	if (err)
-		return err;
-	dev_info(rain->dev, "Firmware version %s\n", rain->cmd_reply + 4);
-
-	err = rain_send_and_wait(rain, "Q 1", "QTY");
-	if (err)
-		return err;
-	err = rain_send_and_wait(rain, "c0000", "CFG");
-	if (err)
-		return err;
-	return rain_send_and_wait(rain, "A F 0000", "ADR");
-}
-
-static int rain_cec_adap_enable(struct cec_adapter *adap, bool enable)
-{
-	return 0;
-}
-
-static int rain_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr)
-{
-	struct rain *rain = cec_get_drvdata(adap);
-	u8 cmd[16];
-
-	if (log_addr == CEC_LOG_ADDR_INVALID)
-		log_addr = CEC_LOG_ADDR_UNREGISTERED;
-	snprintf(cmd, sizeof(cmd), "A %x", log_addr);
-	return rain_send_and_wait(rain, cmd, "ADR");
-}
-
-static int rain_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
-				    u32 signal_free_time, struct cec_msg *msg)
-{
-	struct rain *rain = cec_get_drvdata(adap);
-	char cmd[2 * CEC_MAX_MSG_SIZE + 16];
-	unsigned int i;
-	int err;
-
-	if (msg->len == 1) {
-		snprintf(cmd, sizeof(cmd), "x%x", cec_msg_destination(msg));
-	} else {
-		char hex[3];
-
-		snprintf(cmd, sizeof(cmd), "x%x %02x ",
-			 cec_msg_destination(msg), msg->msg[1]);
-		for (i = 2; i < msg->len; i++) {
-			snprintf(hex, sizeof(hex), "%02x", msg->msg[i]);
-			strlcat(cmd, hex, sizeof(cmd));
-		}
-	}
-	mutex_lock(&rain->write_lock);
-	err = rain_send(rain, cmd);
-	mutex_unlock(&rain->write_lock);
-	return err;
-}
-
-static const struct cec_adap_ops rain_cec_adap_ops = {
-	.adap_enable = rain_cec_adap_enable,
-	.adap_log_addr = rain_cec_adap_log_addr,
-	.adap_transmit = rain_cec_adap_transmit,
-};
-
-static int rain_connect(struct serio *serio, struct serio_driver *drv)
-{
-	u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_PHYS_ADDR | CEC_CAP_MONITOR_ALL;
-	struct rain *rain;
-	int err = -ENOMEM;
-	struct cec_log_addrs log_addrs = {};
-	u16 pa = CEC_PHYS_ADDR_INVALID;
-
-	rain = kzalloc(sizeof(*rain), GFP_KERNEL);
-
-	if (!rain)
-		return -ENOMEM;
-
-	rain->serio = serio;
-	rain->adap = cec_allocate_adapter(&rain_cec_adap_ops, rain,
-					  dev_name(&serio->dev), caps, 1);
-	err = PTR_ERR_OR_ZERO(rain->adap);
-	if (err < 0)
-		goto free_device;
-
-	rain->dev = &serio->dev;
-	serio_set_drvdata(serio, rain);
-	INIT_WORK(&rain->work, rain_irq_work_handler);
-	mutex_init(&rain->write_lock);
-	spin_lock_init(&rain->buf_lock);
-
-	err = serio_open(serio, drv);
-	if (err)
-		goto delete_adap;
-
-	err = rain_setup(rain, serio, &log_addrs, &pa);
-	if (err)
-		goto close_serio;
-
-	err = cec_register_adapter(rain->adap, &serio->dev);
-	if (err < 0)
-		goto close_serio;
-
-	rain->dev = &rain->adap->devnode.dev;
-	return 0;
-
-close_serio:
-	serio_close(serio);
-delete_adap:
-	cec_delete_adapter(rain->adap);
-	serio_set_drvdata(serio, NULL);
-free_device:
-	kfree(rain);
-	return err;
-}
-
-static const struct serio_device_id rain_serio_ids[] = {
-	{
-		.type	= SERIO_RS232,
-		.proto	= SERIO_RAINSHADOW_CEC,
-		.id	= SERIO_ANY,
-		.extra	= SERIO_ANY,
-	},
-	{ 0 }
-};
-
-MODULE_DEVICE_TABLE(serio, rain_serio_ids);
-
-static struct serio_driver rain_drv = {
-	.driver		= {
-		.name	= "rainshadow-cec",
-	},
-	.description	= "RainShadow Tech HDMI CEC driver",
-	.id_table	= rain_serio_ids,
-	.interrupt	= rain_interrupt,
-	.connect	= rain_connect,
-	.disconnect	= rain_disconnect,
-};
-
-module_serio_driver(rain_drv);
diff --git a/drivers/media/usb/zr364xx/Kconfig b/drivers/media/usb/zr364xx/Kconfig
index 55b06c833667..49b4257487bb 100644
--- a/drivers/media/usb/zr364xx/Kconfig
+++ b/drivers/media/usb/zr364xx/Kconfig
@@ -7,7 +7,7 @@ config USB_ZR364XX
 	help
 	  Say Y here if you want to connect this type of camera to your
 	  computer's USB port.
-	  See <file:Documentation/media/v4l-drivers/zr364xx.rst> for more info
+	  See <file:Documentation/admin-guide/media/zr364xx.rst> for more info
 	  and list of supported cameras.
 
 	  To compile this driver as a module, choose M here: the
diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig
index 39e3fb30ba0b..3fa75352d04c 100644
--- a/drivers/media/v4l2-core/Kconfig
+++ b/drivers/media/v4l2-core/Kconfig
@@ -16,6 +16,15 @@ config VIDEO_V4L2_I2C
 	depends on I2C && VIDEO_V4L2
 	default y
 
+config VIDEO_V4L2_SUBDEV_API
+	bool "V4L2 sub-device userspace API"
+	depends on VIDEO_DEV && MEDIA_CONTROLLER
+	help
+	  Enables the V4L2 sub-device pad-level userspace API used to configure
+	  video format, size and frame rate between hardware blocks.
+
+	  This API is mostly used by camera interfaces in embedded platforms.
+
 config VIDEO_ADV_DEBUG
 	bool "Enable advanced debug functionality on V4L2 drivers"
 	help
@@ -31,20 +40,14 @@ config VIDEO_FIXED_MINOR_RANGES
 
 	  When in doubt, say N.
 
-config VIDEO_PCI_SKELETON
-	tristate "Skeleton PCI V4L2 driver"
-	depends on PCI
-	depends on SAMPLES
-	depends on VIDEO_V4L2 && VIDEOBUF2_CORE
-	depends on VIDEOBUF2_MEMOPS && VIDEOBUF2_DMA_CONTIG
-	help
-	  Enable build of the skeleton PCI driver, used as a reference
-	  when developing new drivers.
-
 # Used by drivers that need tuner.ko
 config VIDEO_TUNER
 	tristate
 
+# Used by drivers that need v4l2-jpeg.ko
+config V4L2_JPEG_HELPER
+	tristate
+
 # Used by drivers that need v4l2-mem2mem.ko
 config V4L2_MEM2MEM_DEV
 	tristate
diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile
index 786bd1ec4d1b..144564656d22 100644
--- a/drivers/media/v4l2-core/Makefile
+++ b/drivers/media/v4l2-core/Makefile
@@ -24,6 +24,8 @@ obj-$(CONFIG_V4L2_MEM2MEM_DEV) += v4l2-mem2mem.o
 
 obj-$(CONFIG_V4L2_FLASH_LED_CLASS) += v4l2-flash-led-class.o
 
+obj-$(CONFIG_V4L2_JPEG_HELPER) += v4l2-jpeg.o
+
 obj-$(CONFIG_VIDEOBUF_GEN) += videobuf-core.o
 obj-$(CONFIG_VIDEOBUF_DMA_SG) += videobuf-dma-sg.o
 obj-$(CONFIG_VIDEOBUF_DMA_CONTIG) += videobuf-dma-contig.o
diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
index d0e5ebc736f9..9e8eb45a5b03 100644
--- a/drivers/media/v4l2-core/v4l2-common.c
+++ b/drivers/media/v4l2-core/v4l2-common.c
@@ -250,9 +250,9 @@ const struct v4l2_format_info *v4l2_format_info(u32 format)
 		{ .format = V4L2_PIX_FMT_RGBA32,  .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 		{ .format = V4L2_PIX_FMT_ABGR32,  .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 		{ .format = V4L2_PIX_FMT_BGRA32,  .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
-		{ .format = V4L2_PIX_FMT_GREY,    .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 		{ .format = V4L2_PIX_FMT_RGB565,  .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 		{ .format = V4L2_PIX_FMT_RGB555,  .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
+		{ .format = V4L2_PIX_FMT_BGR666,  .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 
 		/* YUV packed formats */
 		{ .format = V4L2_PIX_FMT_YUYV,    .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 },
@@ -274,6 +274,7 @@ const struct v4l2_format_info *v4l2_format_info(u32 format)
 		{ .format = V4L2_PIX_FMT_YUV420,  .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 },
 		{ .format = V4L2_PIX_FMT_YVU420,  .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 },
 		{ .format = V4L2_PIX_FMT_YUV422P, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 1 },
+		{ .format = V4L2_PIX_FMT_GREY,    .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 
 		/* YUV planar formats, non contiguous variant */
 		{ .format = V4L2_PIX_FMT_YUV420M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 },
diff --git a/drivers/media/v4l2-core/v4l2-jpeg.c b/drivers/media/v4l2-core/v4l2-jpeg.c
new file mode 100644
index 000000000000..8947fd95c6f1
--- /dev/null
+++ b/drivers/media/v4l2-core/v4l2-jpeg.c
@@ -0,0 +1,632 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * V4L2 JPEG header parser helpers.
+ *
+ * Copyright (C) 2019 Pengutronix, Philipp Zabel <kernel@pengutronix.de>
+ *
+ * For reference, see JPEG ITU-T.81 (ISO/IEC 10918-1) [1]
+ *
+ * [1] https://www.w3.org/Graphics/JPEG/itu-t81.pdf
+ */
+
+#include <asm/unaligned.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <media/v4l2-jpeg.h>
+
+MODULE_DESCRIPTION("V4L2 JPEG header parser helpers");
+MODULE_AUTHOR("Philipp Zabel <kernel@pengutronix.de>");
+MODULE_LICENSE("GPL");
+
+/* Table B.1 - Marker code assignments */
+#define SOF0	0xffc0	/* start of frame */
+#define SOF1	0xffc1
+#define SOF2	0xffc2
+#define SOF3	0xffc3
+#define SOF5	0xffc5
+#define SOF7	0xffc7
+#define JPG	0xffc8	/* extensions */
+#define SOF9	0xffc9
+#define SOF11	0xffcb
+#define SOF13	0xffcd
+#define SOF15	0xffcf
+#define DHT	0xffc4	/* huffman table */
+#define DAC	0xffcc	/* arithmetic coding conditioning */
+#define RST0	0xffd0	/* restart */
+#define RST7	0xffd7
+#define SOI	0xffd8	/* start of image */
+#define EOI	0xffd9	/* end of image */
+#define SOS	0xffda	/* start of stream */
+#define DQT	0xffdb	/* quantization table */
+#define DNL	0xffdc	/* number of lines */
+#define DRI	0xffdd	/* restart interval */
+#define DHP	0xffde	/* hierarchical progression */
+#define EXP	0xffdf	/* expand reference */
+#define APP0	0xffe0	/* application data */
+#define APP15	0xffef
+#define JPG0	0xfff0	/* extensions */
+#define JPG13	0xfffd
+#define COM	0xfffe	/* comment */
+#define TEM	0xff01	/* temporary */
+
+/**
+ * struct jpeg_stream - JPEG byte stream
+ * @curr: current position in stream
+ * @end: end position, after last byte
+ */
+struct jpeg_stream {
+	u8 *curr;
+	u8 *end;
+};
+
+/* returns a value that fits into u8, or negative error */
+static int jpeg_get_byte(struct jpeg_stream *stream)
+{
+	if (stream->curr >= stream->end)
+		return -EINVAL;
+
+	return *stream->curr++;
+}
+
+/* returns a value that fits into u16, or negative error */
+static int jpeg_get_word_be(struct jpeg_stream *stream)
+{
+	u16 word;
+
+	if (stream->curr + sizeof(__be16) > stream->end)
+		return -EINVAL;
+
+	word = get_unaligned_be16(stream->curr);
+	stream->curr += sizeof(__be16);
+
+	return word;
+}
+
+static int jpeg_skip(struct jpeg_stream *stream, size_t len)
+{
+	if (stream->curr + len > stream->end)
+		return -EINVAL;
+
+	stream->curr += len;
+
+	return 0;
+}
+
+static int jpeg_next_marker(struct jpeg_stream *stream)
+{
+	int byte;
+	u16 marker = 0;
+
+	while ((byte = jpeg_get_byte(stream)) >= 0) {
+		marker = (marker << 8) | byte;
+		/* skip stuffing bytes and REServed markers */
+		if (marker == TEM || (marker > 0xffbf && marker < 0xffff))
+			return marker;
+	}
+
+	return byte;
+}
+
+/* this does not advance the current position in the stream */
+static int jpeg_reference_segment(struct jpeg_stream *stream,
+				  struct v4l2_jpeg_reference *segment)
+{
+	u16 len;
+
+	if (stream->curr + sizeof(__be16) > stream->end)
+		return -EINVAL;
+
+	len = get_unaligned_be16(stream->curr);
+	if (stream->curr + len > stream->end)
+		return -EINVAL;
+
+	segment->start = stream->curr;
+	segment->length = len;
+
+	return 0;
+}
+
+static int v4l2_jpeg_decode_subsampling(u8 nf, u8 h_v)
+{
+	if (nf == 1)
+		return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
+
+	/* no chroma subsampling for 4-component images */
+	if (nf == 4 && h_v != 0x11)
+		return -EINVAL;
+
+	switch (h_v) {
+	case 0x11:
+		return V4L2_JPEG_CHROMA_SUBSAMPLING_444;
+	case 0x21:
+		return V4L2_JPEG_CHROMA_SUBSAMPLING_422;
+	case 0x22:
+		return V4L2_JPEG_CHROMA_SUBSAMPLING_420;
+	case 0x41:
+		return V4L2_JPEG_CHROMA_SUBSAMPLING_411;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int jpeg_parse_frame_header(struct jpeg_stream *stream, u16 sof_marker,
+				   struct v4l2_jpeg_frame_header *frame_header)
+{
+	int len = jpeg_get_word_be(stream);
+
+	if (len < 0)
+		return len;
+	/* Lf = 8 + 3 * Nf, Nf >= 1 */
+	if (len < 8 + 3)
+		return -EINVAL;
+
+	if (frame_header) {
+		/* Table B.2 - Frame header parameter sizes and values */
+		int p, y, x, nf;
+		int i;
+
+		p = jpeg_get_byte(stream);
+		if (p < 0)
+			return p;
+		/*
+		 * Baseline DCT only supports 8-bit precision.
+		 * Extended sequential DCT also supports 12-bit precision.
+		 */
+		if (p != 8 && (p != 12 || sof_marker != SOF1))
+			return -EINVAL;
+
+		y = jpeg_get_word_be(stream);
+		if (y < 0)
+			return y;
+		if (y == 0)
+			return -EINVAL;
+
+		x = jpeg_get_word_be(stream);
+		if (x < 0)
+			return x;
+		if (x == 0)
+			return -EINVAL;
+
+		nf = jpeg_get_byte(stream);
+		if (nf < 0)
+			return nf;
+		/*
+		 * The spec allows 1 <= Nf <= 255, but we only support up to 4
+		 * components.
+		 */
+		if (nf < 1 || nf > V4L2_JPEG_MAX_COMPONENTS)
+			return -EINVAL;
+		if (len != 8 + 3 * nf)
+			return -EINVAL;
+
+		frame_header->precision = p;
+		frame_header->height = y;
+		frame_header->width = x;
+		frame_header->num_components = nf;
+
+		for (i = 0; i < nf; i++) {
+			struct v4l2_jpeg_frame_component_spec *component;
+			int c, h_v, tq;
+
+			c = jpeg_get_byte(stream);
+			if (c < 0)
+				return c;
+
+			h_v = jpeg_get_byte(stream);
+			if (h_v < 0)
+				return h_v;
+			if (i == 0) {
+				int subs;
+
+				subs = v4l2_jpeg_decode_subsampling(nf, h_v);
+				if (subs < 0)
+					return subs;
+				frame_header->subsampling = subs;
+			} else if (h_v != 0x11) {
+				/* all chroma sampling factors must be 1 */
+				return -EINVAL;
+			}
+
+			tq = jpeg_get_byte(stream);
+			if (tq < 0)
+				return tq;
+
+			component = &frame_header->component[i];
+			component->component_identifier = c;
+			component->horizontal_sampling_factor =
+				(h_v >> 4) & 0xf;
+			component->vertical_sampling_factor = h_v & 0xf;
+			component->quantization_table_selector = tq;
+		}
+	} else {
+		return jpeg_skip(stream, len - 2);
+	}
+
+	return 0;
+}
+
+static int jpeg_parse_scan_header(struct jpeg_stream *stream,
+				  struct v4l2_jpeg_scan_header *scan_header)
+{
+	size_t skip;
+	int len = jpeg_get_word_be(stream);
+
+	if (len < 0)
+		return len;
+	/* Ls = 8 + 3 * Ns, Ns >= 1 */
+	if (len < 6 + 2)
+		return -EINVAL;
+
+	if (scan_header) {
+		int ns;
+		int i;
+
+		ns = jpeg_get_byte(stream);
+		if (ns < 0)
+			return ns;
+		if (ns < 1 || ns > 4 || len != 6 + 2 * ns)
+			return -EINVAL;
+
+		scan_header->num_components = ns;
+
+		for (i = 0; i < ns; i++) {
+			struct v4l2_jpeg_scan_component_spec *component;
+			int cs, td_ta;
+
+			cs = jpeg_get_byte(stream);
+			if (cs < 0)
+				return cs;
+
+			td_ta = jpeg_get_byte(stream);
+			if (td_ta < 0)
+				return td_ta;
+
+			component = &scan_header->component[i];
+			component->component_selector = cs;
+			component->dc_entropy_coding_table_selector =
+				(td_ta >> 4) & 0xf;
+			component->ac_entropy_coding_table_selector =
+				td_ta & 0xf;
+		}
+
+		skip = 3; /* skip Ss, Se, Ah, and Al */
+	} else {
+		skip = len - 2;
+	}
+
+	return jpeg_skip(stream, skip);
+}
+
+/* B.2.4.1 Quantization table-specification syntax */
+static int jpeg_parse_quantization_tables(struct jpeg_stream *stream,
+					  u8 precision,
+					  struct v4l2_jpeg_reference *tables)
+{
+	int len = jpeg_get_word_be(stream);
+
+	if (len < 0)
+		return len;
+	/* Lq = 2 + n * 65 (for baseline DCT), n >= 1 */
+	if (len < 2 + 65)
+		return -EINVAL;
+
+	len -= 2;
+	while (len >= 65) {
+		u8 pq, tq, *qk;
+		int ret;
+		int pq_tq = jpeg_get_byte(stream);
+
+		if (pq_tq < 0)
+			return pq_tq;
+
+		/* quantization table element precision */
+		pq = (pq_tq >> 4) & 0xf;
+		/*
+		 * Only 8-bit Qk values for 8-bit sample precision. Extended
+		 * sequential DCT with 12-bit sample precision also supports
+		 * 16-bit Qk values.
+		 */
+		if (pq != 0 && (pq != 1 || precision != 12))
+			return -EINVAL;
+
+		/* quantization table destination identifier */
+		tq = pq_tq & 0xf;
+		if (tq > 3)
+			return -EINVAL;
+
+		/* quantization table element */
+		qk = stream->curr;
+		ret = jpeg_skip(stream, pq ? 128 : 64);
+		if (ret < 0)
+			return -EINVAL;
+
+		if (tables) {
+			tables[tq].start = qk;
+			tables[tq].length = pq ? 128 : 64;
+		}
+
+		len -= pq ? 129 : 65;
+	}
+
+	return 0;
+}
+
+/* B.2.4.2 Huffman table-specification syntax */
+static int jpeg_parse_huffman_tables(struct jpeg_stream *stream,
+				     struct v4l2_jpeg_reference *tables)
+{
+	int mt;
+	int len = jpeg_get_word_be(stream);
+
+	if (len < 0)
+		return len;
+	/* Table B.5 - Huffman table specification parameter sizes and values */
+	if (len < 2 + 17)
+		return -EINVAL;
+
+	for (len -= 2; len >= 17; len -= 17 + mt) {
+		u8 tc, th, *table;
+		int tc_th = jpeg_get_byte(stream);
+		int i, ret;
+
+		if (tc_th < 0)
+			return tc_th;
+
+		/* table class - 0 = DC, 1 = AC */
+		tc = (tc_th >> 4) & 0xf;
+		if (tc > 1)
+			return -EINVAL;
+
+		/* huffman table destination identifier */
+		th = tc_th & 0xf;
+		/* only two Huffman tables for baseline DCT */
+		if (th > 1)
+			return -EINVAL;
+
+		/* BITS - number of Huffman codes with length i */
+		table = stream->curr;
+		mt = 0;
+		for (i = 0; i < 16; i++) {
+			int li;
+
+			li = jpeg_get_byte(stream);
+			if (li < 0)
+				return li;
+
+			mt += li;
+		}
+		/* HUFFVAL - values associated with each Huffman code */
+		ret = jpeg_skip(stream, mt);
+		if (ret < 0)
+			return ret;
+
+		if (tables) {
+			tables[(tc << 1) | th].start = table;
+			tables[(tc << 1) | th].length = stream->curr - table;
+		}
+	}
+
+	return jpeg_skip(stream, len - 2);
+}
+
+/* B.2.4.4 Restart interval definition syntax */
+static int jpeg_parse_restart_interval(struct jpeg_stream *stream,
+				       u16 *restart_interval)
+{
+	int len = jpeg_get_word_be(stream);
+	int ri;
+
+	if (len < 0)
+		return len;
+	if (len != 4)
+		return -EINVAL;
+
+	ri = jpeg_get_word_be(stream);
+	if (ri < 0)
+		return ri;
+
+	*restart_interval = ri;
+
+	return 0;
+}
+
+static int jpeg_skip_segment(struct jpeg_stream *stream)
+{
+	int len = jpeg_get_word_be(stream);
+
+	if (len < 0)
+		return len;
+	if (len < 2)
+		return -EINVAL;
+
+	return jpeg_skip(stream, len - 2);
+}
+
+/**
+ * jpeg_parse_header - locate marker segments and optionally parse headers
+ * @buf: address of the JPEG buffer, should start with a SOI marker
+ * @len: length of the JPEG buffer
+ * @out: returns marker segment positions and optionally parsed headers
+ *
+ * The out->scan_header pointer must be initialized to NULL or point to a valid
+ * v4l2_jpeg_scan_header structure. The out->huffman_tables and
+ * out->quantization_tables pointers must be initialized to NULL or point to a
+ * valid array of 4 v4l2_jpeg_reference structures each.
+ *
+ * Returns 0 or negative error if parsing failed.
+ */
+int v4l2_jpeg_parse_header(void *buf, size_t len, struct v4l2_jpeg_header *out)
+{
+	struct jpeg_stream stream;
+	int marker;
+	int ret = 0;
+
+	stream.curr = buf;
+	stream.end = stream.curr + len;
+
+	out->num_dht = 0;
+	out->num_dqt = 0;
+
+	/* the first marker must be SOI */
+	marker = jpeg_next_marker(&stream);
+	if (marker < 0)
+		return marker;
+	if (marker != SOI)
+		return -EINVAL;
+
+	/* loop through marker segments */
+	while ((marker = jpeg_next_marker(&stream)) >= 0) {
+		switch (marker) {
+		/* baseline DCT, extended sequential DCT */
+		case SOF0 ... SOF1:
+			ret = jpeg_reference_segment(&stream, &out->sof);
+			if (ret < 0)
+				return ret;
+			ret = jpeg_parse_frame_header(&stream, marker,
+						      &out->frame);
+			break;
+		/* progressive, lossless */
+		case SOF2 ... SOF3:
+		/* differential coding */
+		case SOF5 ... SOF7:
+		/* arithmetic coding */
+		case SOF9 ... SOF11:
+		case SOF13 ... SOF15:
+		case DAC:
+		case TEM:
+			return -EINVAL;
+
+		case DHT:
+			ret = jpeg_reference_segment(&stream,
+					&out->dht[out->num_dht++ % 4]);
+			if (ret < 0)
+				return ret;
+			ret = jpeg_parse_huffman_tables(&stream,
+							out->huffman_tables);
+			break;
+		case DQT:
+			ret = jpeg_reference_segment(&stream,
+					&out->dqt[out->num_dqt++ % 4]);
+			if (ret < 0)
+				return ret;
+			ret = jpeg_parse_quantization_tables(&stream,
+					out->frame.precision,
+					out->quantization_tables);
+			break;
+		case DRI:
+			ret = jpeg_parse_restart_interval(&stream,
+							&out->restart_interval);
+			break;
+
+		case SOS:
+			ret = jpeg_reference_segment(&stream, &out->sos);
+			if (ret < 0)
+				return ret;
+			ret = jpeg_parse_scan_header(&stream, out->scan);
+			/*
+			 * stop parsing, the scan header marks the beginning of
+			 * the entropy coded segment
+			 */
+			out->ecs_offset = stream.curr - (u8 *)buf;
+			return ret;
+
+		/* markers without parameters */
+		case RST0 ... RST7: /* restart */
+		case SOI: /* start of image */
+		case EOI: /* end of image */
+			break;
+
+		/* skip unknown or unsupported marker segments */
+		default:
+			ret = jpeg_skip_segment(&stream);
+			break;
+		}
+		if (ret < 0)
+			return ret;
+	}
+
+	return marker;
+}
+EXPORT_SYMBOL_GPL(v4l2_jpeg_parse_header);
+
+/**
+ * v4l2_jpeg_parse_frame_header - parse frame header
+ * @buf: address of the frame header, after the SOF0 marker
+ * @len: length of the frame header
+ * @frame_header: returns the parsed frame header
+ *
+ * Returns 0 or negative error if parsing failed.
+ */
+int v4l2_jpeg_parse_frame_header(void *buf, size_t len,
+				 struct v4l2_jpeg_frame_header *frame_header)
+{
+	struct jpeg_stream stream;
+
+	stream.curr = buf;
+	stream.end = stream.curr + len;
+	return jpeg_parse_frame_header(&stream, SOF0, frame_header);
+}
+EXPORT_SYMBOL_GPL(v4l2_jpeg_parse_frame_header);
+
+/**
+ * v4l2_jpeg_parse_scan_header - parse scan header
+ * @buf: address of the scan header, after the SOS marker
+ * @len: length of the scan header
+ * @scan_header: returns the parsed scan header
+ *
+ * Returns 0 or negative error if parsing failed.
+ */
+int v4l2_jpeg_parse_scan_header(void *buf, size_t len,
+				struct v4l2_jpeg_scan_header *scan_header)
+{
+	struct jpeg_stream stream;
+
+	stream.curr = buf;
+	stream.end = stream.curr + len;
+	return jpeg_parse_scan_header(&stream, scan_header);
+}
+EXPORT_SYMBOL_GPL(v4l2_jpeg_parse_scan_header);
+
+/**
+ * v4l2_jpeg_parse_quantization_tables - parse quantization tables segment
+ * @buf: address of the quantization table segment, after the DQT marker
+ * @len: length of the quantization table segment
+ * @precision: sample precision (P) in bits per component
+ * @q_tables: returns four references into the buffer for the
+ *            four possible quantization table destinations
+ *
+ * Returns 0 or negative error if parsing failed.
+ */
+int v4l2_jpeg_parse_quantization_tables(void *buf, size_t len, u8 precision,
+					struct v4l2_jpeg_reference *q_tables)
+{
+	struct jpeg_stream stream;
+
+	stream.curr = buf;
+	stream.end = stream.curr + len;
+	return jpeg_parse_quantization_tables(&stream, precision, q_tables);
+}
+EXPORT_SYMBOL_GPL(v4l2_jpeg_parse_quantization_tables);
+
+/**
+ * v4l2_jpeg_parse_huffman_tables - parse huffman tables segment
+ * @buf: address of the Huffman table segment, after the DHT marker
+ * @len: length of the Huffman table segment
+ * @huffman_tables: returns four references into the buffer for the
+ *                  four possible Huffman table destinations, in
+ *                  the order DC0, DC1, AC0, AC1
+ *
+ * Returns 0 or negative error if parsing failed.
+ */
+int v4l2_jpeg_parse_huffman_tables(void *buf, size_t len,
+				   struct v4l2_jpeg_reference *huffman_tables)
+{
+	struct jpeg_stream stream;
+
+	stream.curr = buf;
+	stream.end = stream.curr + len;
+	return jpeg_parse_huffman_tables(&stream, huffman_tables);
+}
+EXPORT_SYMBOL_GPL(v4l2_jpeg_parse_huffman_tables);
diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
index 8986c31176e9..62ac9424c92a 100644
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
@@ -504,12 +504,21 @@ void v4l2_m2m_buf_done_and_job_finish(struct v4l2_m2m_dev *m2m_dev,
 
 	if (WARN_ON(!src_buf || !dst_buf))
 		goto unlock;
-	v4l2_m2m_buf_done(src_buf, state);
 	dst_buf->is_held = src_buf->flags & V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF;
 	if (!dst_buf->is_held) {
 		v4l2_m2m_dst_buf_remove(m2m_ctx);
 		v4l2_m2m_buf_done(dst_buf, state);
 	}
+	/*
+	 * If the request API is being used, returning the OUTPUT
+	 * (src) buffer will wake-up any process waiting on the
+	 * request file descriptor.
+	 *
+	 * Therefore, return the CAPTURE (dst) buffer first,
+	 * to avoid signalling the request file descriptor
+	 * before the CAPTURE buffer is done.
+	 */
+	v4l2_m2m_buf_done(src_buf, state);
 	schedule_next = _v4l2_m2m_job_finish(m2m_dev, m2m_ctx);
 unlock:
 	spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index c2dd322691d1..68aea22f2b89 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -5052,9 +5052,11 @@ GetLanConfigPages(MPT_ADAPTER *ioc)
  *	@ioc: Pointer to MPT_ADAPTER structure
  *	@persist_opcode: see below
  *
- *	MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
- *		devices not currently present.
- *	MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
+ *	===============================  ======================================
+ *	MPI_SAS_OP_CLEAR_NOT_PRESENT     Free all persist TargetID mappings for
+ *					 devices not currently present.
+ *	MPI_SAS_OP_CLEAR_ALL_PERSISTENT  Clear al persist TargetID mappings
+ *	===============================  ======================================
  *
  *	NOTE: Don't use not this function during interrupt time.
  *
diff --git a/drivers/misc/mic/Kconfig b/drivers/misc/mic/Kconfig
index 8f201d019f5a..3bfe72c59864 100644
--- a/drivers/misc/mic/Kconfig
+++ b/drivers/misc/mic/Kconfig
@@ -116,7 +116,7 @@ config MIC_COSM
 
 config VOP
 	tristate "VOP Driver"
-	depends on VOP_BUS
+	depends on VOP_BUS && VHOST_DPN
 	select VHOST_RING
 	select VIRTIO
 	help
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
index 5bd0ab8b236a..baa6314f69b4 100644
--- a/drivers/mmc/core/mmc_ops.c
+++ b/drivers/mmc/core/mmc_ops.c
@@ -878,7 +878,7 @@ static int mmc_send_hpi_cmd(struct mmc_card *card)
  *	Issued High Priority Interrupt, and check for card status
  *	until out-of prg-state.
  */
-int mmc_interrupt_hpi(struct mmc_card *card)
+static int mmc_interrupt_hpi(struct mmc_card *card)
 {
 	int err;
 	u32 status;
diff --git a/drivers/mmc/host/android-goldfish.c b/drivers/mmc/host/android-goldfish.c
index 914e17bab3be..ceb4924e02d0 100644
--- a/drivers/mmc/host/android-goldfish.c
+++ b/drivers/mmc/host/android-goldfish.c
@@ -27,7 +27,6 @@
 #include <linux/mutex.h>
 #include <linux/scatterlist.h>
 #include <linux/mmc/mmc.h>
-#include <linux/mmc/sdio.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/card.h>
 
@@ -404,14 +403,6 @@ static void goldfish_mmc_request(struct mmc_host *mmc, struct mmc_request *req)
 	host->mrq = req;
 	goldfish_mmc_prepare_data(host, req);
 	goldfish_mmc_start_command(host, req->cmd);
-
-	/*
-	 * This is to avoid accidentally being detected as an SDIO card
-	 * in mmc_attach_sdio().
-	 */
-	if (req->cmd->opcode == SD_IO_SEND_OP_COND &&
-	    req->cmd->flags == (MMC_RSP_SPI_R4 | MMC_RSP_R4 | MMC_CMD_BCR))
-		req->cmd->error = -EINVAL;
 }
 
 static void goldfish_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
@@ -482,6 +473,7 @@ static int goldfish_mmc_probe(struct platform_device *pdev)
 	mmc->f_max = 24000000;
 	mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
 	mmc->caps = MMC_CAP_4_BIT_DATA;
+	mmc->caps2 = MMC_CAP2_NO_SDIO;
 
 	/* Use scatterlist DMA to reduce per-transfer costs.
 	 * NOTE max_seg_size assumption that small blocks aren't
diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c
index 8823680ca42c..9bb1910268ca 100644
--- a/drivers/mmc/host/au1xmmc.c
+++ b/drivers/mmc/host/au1xmmc.c
@@ -259,7 +259,7 @@ static void au1xmmc_tasklet_finish(unsigned long param)
 	au1xmmc_finish_request(host);
 }
 
-static int au1xmmc_send_command(struct au1xmmc_host *host, int wait,
+static int au1xmmc_send_command(struct au1xmmc_host *host,
 				struct mmc_command *cmd, struct mmc_data *data)
 {
 	u32 mmccmd = (cmd->opcode << SD_CMD_CI_SHIFT);
@@ -302,9 +302,6 @@ static int au1xmmc_send_command(struct au1xmmc_host *host, int wait,
 	__raw_writel(cmd->arg, HOST_CMDARG(host));
 	wmb(); /* drain writebuffer */
 
-	if (wait)
-		IRQ_OFF(host, SD_CONFIG_CR);
-
 	__raw_writel((mmccmd | SD_CMD_GO), HOST_CMD(host));
 	wmb(); /* drain writebuffer */
 
@@ -312,19 +309,6 @@ static int au1xmmc_send_command(struct au1xmmc_host *host, int wait,
 	while (__raw_readl(HOST_CMD(host)) & SD_CMD_GO)
 		/* nop */;
 
-	/* Wait for the command to come back */
-	if (wait) {
-		u32 status = __raw_readl(HOST_STATUS(host));
-
-		while (!(status & SD_STATUS_CR))
-			status = __raw_readl(HOST_STATUS(host));
-
-		/* Clear the CR status */
-		__raw_writel(SD_STATUS_CR, HOST_STATUS(host));
-
-		IRQ_ON(host, SD_CONFIG_CR);
-	}
-
 	return 0;
 }
 
@@ -711,7 +695,7 @@ static void au1xmmc_request(struct mmc_host* mmc, struct mmc_request* mrq)
 	}
 
 	if (!ret)
-		ret = au1xmmc_send_command(host, 0, mrq->cmd, mrq->data);
+		ret = au1xmmc_send_command(host, mrq->cmd, mrq->data);
 
 	if (ret) {
 		mrq->cmd->error = ret;
diff --git a/drivers/mmc/host/renesas_sdhi.h b/drivers/mmc/host/renesas_sdhi.h
index 2a4c83a5f32e..12d8016672b0 100644
--- a/drivers/mmc/host/renesas_sdhi.h
+++ b/drivers/mmc/host/renesas_sdhi.h
@@ -61,6 +61,8 @@ struct renesas_sdhi {
 
 	/* Tuning values: 1 for success, 0 for failure */
 	DECLARE_BITMAP(taps, BITS_PER_LONG);
+	/* Sampling data comparison: 1 for match, 0 for mismatch */
+	DECLARE_BITMAP(smpcmp, BITS_PER_LONG);
 	unsigned int tap_num;
 	unsigned long tap_set;
 };
diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
index df826661366f..68432bb0255b 100644
--- a/drivers/mmc/host/renesas_sdhi_core.c
+++ b/drivers/mmc/host/renesas_sdhi_core.c
@@ -422,20 +422,16 @@ static int renesas_sdhi_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_io
 	return 0;
 }
 
-#define SH_MOBILE_SDHI_MAX_TAP 3
+#define SH_MOBILE_SDHI_MIN_TAP_ROW 3
 
 static int renesas_sdhi_select_tuning(struct tmio_mmc_host *host)
 {
 	struct renesas_sdhi *priv = host_to_priv(host);
-	unsigned long tap_cnt;  /* counter of tuning success */
-	unsigned long tap_start;/* start position of tuning success */
-	unsigned long tap_end;  /* end position of tuning success */
-	unsigned long ntap;     /* temporary counter of tuning success */
-	unsigned long i;
+	unsigned int tap_start = 0, tap_end = 0, tap_cnt = 0, rs, re, i;
+	unsigned int taps_size = priv->tap_num * 2, min_tap_row;
+	unsigned long *bitmap;
 
 	priv->doing_tune = false;
-
-	/* Clear SCC_RVSREQ */
 	sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_RVSREQ, 0);
 
 	/*
@@ -443,42 +439,42 @@ static int renesas_sdhi_select_tuning(struct tmio_mmc_host *host)
 	 * result requiring the tap to be good in both runs before
 	 * considering it for tuning selection.
 	 */
-	for (i = 0; i < priv->tap_num * 2; i++) {
+	for (i = 0; i < taps_size; i++) {
 		int offset = priv->tap_num * (i < priv->tap_num ? 1 : -1);
 
 		if (!test_bit(i, priv->taps))
 			clear_bit(i + offset, priv->taps);
+
+		if (!test_bit(i, priv->smpcmp))
+			clear_bit(i + offset, priv->smpcmp);
 	}
 
 	/*
-	 * Find the longest consecutive run of successful probes.  If that
-	 * is more than SH_MOBILE_SDHI_MAX_TAP probes long then use the
-	 * center index as the tap.
+	 * If all TAP are OK, the sampling clock position is selected by
+	 * identifying the change point of data.
 	 */
-	tap_cnt = 0;
-	ntap = 0;
-	tap_start = 0;
-	tap_end = 0;
-	for (i = 0; i < priv->tap_num * 2; i++) {
-		if (test_bit(i, priv->taps)) {
-			ntap++;
-		} else {
-			if (ntap > tap_cnt) {
-				tap_start = i - ntap;
-				tap_end = i - 1;
-				tap_cnt = ntap;
-			}
-			ntap = 0;
-		}
+	if (bitmap_full(priv->taps, taps_size)) {
+		bitmap = priv->smpcmp;
+		min_tap_row = 1;
+	} else {
+		bitmap = priv->taps;
+		min_tap_row = SH_MOBILE_SDHI_MIN_TAP_ROW;
 	}
 
-	if (ntap > tap_cnt) {
-		tap_start = i - ntap;
-		tap_end = i - 1;
-		tap_cnt = ntap;
+	/*
+	 * Find the longest consecutive run of successful probes. If that
+	 * is at least SH_MOBILE_SDHI_MIN_TAP_ROW probes long then use the
+	 * center index as the tap, otherwise bail out.
+	 */
+	bitmap_for_each_set_region(bitmap, rs, re, 0, taps_size) {
+		if (re - rs > tap_cnt) {
+			tap_end = re;
+			tap_start = rs;
+			tap_cnt = tap_end - tap_start;
+		}
 	}
 
-	if (tap_cnt >= SH_MOBILE_SDHI_MAX_TAP)
+	if (tap_cnt >= min_tap_row)
 		priv->tap_set = (tap_start + tap_end) / 2 % priv->tap_num;
 	else
 		return -EIO;
@@ -511,6 +507,7 @@ static int renesas_sdhi_execute_tuning(struct tmio_mmc_host *host, u32 opcode)
 
 	priv->doing_tune = true;
 	bitmap_zero(priv->taps, priv->tap_num * 2);
+	bitmap_zero(priv->smpcmp, priv->tap_num * 2);
 
 	/* Issue CMD19 twice for each tap */
 	for (i = 0; i < 2 * priv->tap_num; i++) {
@@ -519,6 +516,9 @@ static int renesas_sdhi_execute_tuning(struct tmio_mmc_host *host, u32 opcode)
 
 		if (mmc_send_tuning(host->mmc, opcode, NULL) == 0)
 			set_bit(i, priv->taps);
+
+		if (sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_SMPCMP) == 0)
+			set_bit(i, priv->smpcmp);
 	}
 
 	return renesas_sdhi_select_tuning(host);
@@ -933,10 +933,8 @@ int renesas_sdhi_probe(struct platform_device *pdev,
 			goto eirq;
 	}
 
-	dev_info(&pdev->dev, "%s base at 0x%08lx max clock rate %u MHz\n",
-		 mmc_hostname(host->mmc), (unsigned long)
-		 (platform_get_resource(pdev, IORESOURCE_MEM, 0)->start),
-		 host->mmc->f_max / 1000000);
+	dev_info(&pdev->dev, "%s base at %pa, max clock rate %u MHz\n",
+		 mmc_hostname(host->mmc), &res->start, host->mmc->f_max / 1000000);
 
 	return ret;
 
diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c
index 1e616ae56b13..444b2769ae2c 100644
--- a/drivers/mmc/host/s3cmci.c
+++ b/drivers/mmc/host/s3cmci.c
@@ -958,13 +958,6 @@ static int s3cmci_setup_data(struct s3cmci_host *host, struct mmc_data *data)
 {
 	u32 dcon, imsk, stoptries = 3;
 
-	/* write DCON register */
-
-	if (!data) {
-		writel(0, host->base + S3C2410_SDIDCON);
-		return 0;
-	}
-
 	if ((data->blksz & 3) != 0) {
 		/* We cannot deal with unaligned blocks with more than
 		 * one block being transferred. */
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 5ec8e4bf1ac7..38cd83118082 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -8,6 +8,7 @@
  *   Author: Wolfram Sang <kernel@pengutronix.de>
  */
 
+#include <linux/bitfield.h>
 #include <linux/io.h>
 #include <linux/iopoll.h>
 #include <linux/delay.h>
@@ -399,7 +400,8 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
 				val = SDHCI_SUPPORT_DDR50 | SDHCI_SUPPORT_SDR104
 					| SDHCI_SUPPORT_SDR50
 					| SDHCI_USE_SDR50_TUNING
-					| (SDHCI_TUNING_MODE_3 << SDHCI_RETUNING_MODE_SHIFT);
+					| FIELD_PREP(SDHCI_RETUNING_MODE_MASK,
+						     SDHCI_TUNING_MODE_3);
 
 			if (imx_data->socdata->flags & ESDHC_FLAG_HS400)
 				val |= SDHCI_SUPPORT_HS400;
diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c
index d4905c106c06..16e26c217a77 100644
--- a/drivers/mmc/host/sdhci-of-arasan.c
+++ b/drivers/mmc/host/sdhci-of-arasan.c
@@ -28,15 +28,26 @@
 #include "sdhci-pltfm.h"
 
 #define SDHCI_ARASAN_VENDOR_REGISTER	0x78
+
+#define SDHCI_ARASAN_ITAPDLY_REGISTER	0xF0F8
+#define SDHCI_ARASAN_OTAPDLY_REGISTER	0xF0FC
+
 #define SDHCI_ARASAN_CQE_BASE_ADDR	0x200
 #define VENDOR_ENHANCED_STROBE		BIT(0)
 
 #define PHY_CLK_TOO_SLOW_HZ		400000
 
+#define SDHCI_ITAPDLY_CHGWIN		0x200
+#define SDHCI_ITAPDLY_ENABLE		0x100
+#define SDHCI_OTAPDLY_ENABLE		0x40
+
 /* Default settings for ZynqMP Clock Phases */
 #define ZYNQMP_ICLK_PHASE {0, 63, 63, 0, 63,  0,   0, 183, 54,  0, 0}
 #define ZYNQMP_OCLK_PHASE {0, 72, 60, 0, 60, 72, 135, 48, 72, 135, 0}
 
+#define VERSAL_ICLK_PHASE {0, 132, 132, 0, 132, 0, 0, 162, 90, 0, 0}
+#define VERSAL_OCLK_PHASE {0,  60, 48, 0, 48, 72, 90, 36, 60, 90, 0}
+
 /*
  * On some SoCs the syscon area has a feature where the upper 16-bits of
  * each 32-bit register act as a write mask for the lower 16-bits.  This allows
@@ -62,13 +73,13 @@ struct sdhci_arasan_soc_ctl_field {
 /**
  * struct sdhci_arasan_soc_ctl_map - Map in syscon to corecfg registers
  *
- * It's up to the licensee of the Arsan IP block to make these available
- * somewhere if needed.  Presumably these will be scattered somewhere that's
- * accessible via the syscon API.
- *
  * @baseclkfreq:	Where to find corecfg_baseclkfreq
  * @clockmultiplier:	Where to find corecfg_clockmultiplier
  * @hiword_update:	If true, use HIWORD_UPDATE to access the syscon
+ *
+ * It's up to the licensee of the Arsan IP block to make these available
+ * somewhere if needed.  Presumably these will be scattered somewhere that's
+ * accessible via the syscon API.
  */
 struct sdhci_arasan_soc_ctl_map {
 	struct sdhci_arasan_soc_ctl_field	baseclkfreq;
@@ -77,7 +88,19 @@ struct sdhci_arasan_soc_ctl_map {
 };
 
 /**
- * struct sdhci_arasan_clk_data
+ * struct sdhci_arasan_clk_ops - Clock Operations for Arasan SD controller
+ *
+ * @sdcardclk_ops:	The output clock related operations
+ * @sampleclk_ops:	The sample clock related operations
+ */
+struct sdhci_arasan_clk_ops {
+	const struct clk_ops *sdcardclk_ops;
+	const struct clk_ops *sampleclk_ops;
+};
+
+/**
+ * struct sdhci_arasan_clk_data - Arasan Controller Clock Data.
+ *
  * @sdcardclk_hw:	Struct for the clock we might provide to a PHY.
  * @sdcardclk:		Pointer to normal 'struct clock' for sdcardclk_hw.
  * @sampleclk_hw:	Struct for the clock we might provide to a PHY.
@@ -103,14 +126,18 @@ struct sdhci_arasan_zynqmp_clk_data {
 };
 
 /**
- * struct sdhci_arasan_data
+ * struct sdhci_arasan_data - Arasan Controller Data
+ *
  * @host:		Pointer to the main SDHCI host structure.
  * @clk_ahb:		Pointer to the AHB clock
  * @phy:		Pointer to the generic phy
  * @is_phy_on:		True if the PHY is on; false if not.
+ * @has_cqe:		True if controller has command queuing engine.
  * @clk_data:		Struct for the Arasan Controller Clock Data.
+ * @clk_ops:		Struct for the Arasan Controller Clock Operations.
  * @soc_ctl_base:	Pointer to regmap for syscon for soc_ctl registers.
  * @soc_ctl_map:	Map to get offsets into soc_ctl registers.
+ * @quirks:		Arasan deviations from spec.
  */
 struct sdhci_arasan_data {
 	struct sdhci_host *host;
@@ -120,10 +147,11 @@ struct sdhci_arasan_data {
 
 	bool		has_cqe;
 	struct sdhci_arasan_clk_data clk_data;
+	const struct sdhci_arasan_clk_ops *clk_ops;
 
 	struct regmap	*soc_ctl_base;
 	const struct sdhci_arasan_soc_ctl_map *soc_ctl_map;
-	unsigned int	quirks; /* Arasan deviations from spec */
+	unsigned int	quirks;
 
 /* Controller does not have CD wired and will not function normally without */
 #define SDHCI_ARASAN_QUIRK_FORCE_CDTEST	BIT(0)
@@ -135,6 +163,7 @@ struct sdhci_arasan_data {
 struct sdhci_arasan_of_data {
 	const struct sdhci_arasan_soc_ctl_map *soc_ctl_map;
 	const struct sdhci_pltfm_data *pdata;
+	const struct sdhci_arasan_clk_ops *clk_ops;
 };
 
 static const struct sdhci_arasan_soc_ctl_map rk3399_soc_ctl_map = {
@@ -158,14 +187,16 @@ static const struct sdhci_arasan_soc_ctl_map intel_lgm_sdxc_soc_ctl_map = {
 /**
  * sdhci_arasan_syscon_write - Write to a field in soc_ctl registers
  *
+ * @host:	The sdhci_host
+ * @fld:	The field to write to
+ * @val:	The value to write
+ *
  * This function allows writing to fields in sdhci_arasan_soc_ctl_map.
  * Note that if a field is specified as not available (shift < 0) then
  * this function will silently return an error code.  It will be noisy
  * and print errors for any other (unexpected) errors.
  *
- * @host:	The sdhci_host
- * @fld:	The field to write to
- * @val:	The value to write
+ * Return: 0 on success and error value on error
  */
 static int sdhci_arasan_syscon_write(struct sdhci_host *host,
 				   const struct sdhci_arasan_soc_ctl_field *fld,
@@ -335,29 +366,6 @@ static const struct sdhci_ops sdhci_arasan_ops = {
 	.set_power = sdhci_set_power_and_bus_voltage,
 };
 
-static const struct sdhci_pltfm_data sdhci_arasan_pdata = {
-	.ops = &sdhci_arasan_ops,
-	.quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
-	.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
-			SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN |
-			SDHCI_QUIRK2_STOP_WITH_TC,
-};
-
-static struct sdhci_arasan_of_data sdhci_arasan_data = {
-	.pdata = &sdhci_arasan_pdata,
-};
-
-static const struct sdhci_pltfm_data sdhci_arasan_zynqmp_pdata = {
-	.ops = &sdhci_arasan_ops,
-	.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
-			SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN |
-			SDHCI_QUIRK2_STOP_WITH_TC,
-};
-
-static struct sdhci_arasan_of_data sdhci_arasan_zynqmp_data = {
-	.pdata = &sdhci_arasan_zynqmp_pdata,
-};
-
 static u32 sdhci_arasan_cqhci_irq(struct sdhci_host *host, u32 intmask)
 {
 	int cmd_error = 0;
@@ -414,28 +422,14 @@ static const struct sdhci_pltfm_data sdhci_arasan_cqe_pdata = {
 			SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN,
 };
 
-static struct sdhci_arasan_of_data sdhci_arasan_rk3399_data = {
-	.soc_ctl_map = &rk3399_soc_ctl_map,
-	.pdata = &sdhci_arasan_cqe_pdata,
-};
-
-static struct sdhci_arasan_of_data intel_lgm_emmc_data = {
-	.soc_ctl_map = &intel_lgm_emmc_soc_ctl_map,
-	.pdata = &sdhci_arasan_cqe_pdata,
-};
-
-static struct sdhci_arasan_of_data intel_lgm_sdxc_data = {
-	.soc_ctl_map = &intel_lgm_sdxc_soc_ctl_map,
-	.pdata = &sdhci_arasan_cqe_pdata,
-};
-
 #ifdef CONFIG_PM_SLEEP
 /**
  * sdhci_arasan_suspend - Suspend method for the driver
  * @dev:	Address of the device structure
- * Returns 0 on success and error value on error
  *
  * Put the device in a low power state.
+ *
+ * Return: 0 on success and error value on error
  */
 static int sdhci_arasan_suspend(struct device *dev)
 {
@@ -476,9 +470,10 @@ static int sdhci_arasan_suspend(struct device *dev)
 /**
  * sdhci_arasan_resume - Resume method for the driver
  * @dev:	Address of the device structure
- * Returns 0 on success and error value on error
  *
  * Resume operation after suspend
+ *
+ * Return: 0 on success and error value on error
  */
 static int sdhci_arasan_resume(struct device *dev)
 {
@@ -524,54 +519,19 @@ static int sdhci_arasan_resume(struct device *dev)
 static SIMPLE_DEV_PM_OPS(sdhci_arasan_dev_pm_ops, sdhci_arasan_suspend,
 			 sdhci_arasan_resume);
 
-static const struct of_device_id sdhci_arasan_of_match[] = {
-	/* SoC-specific compatible strings w/ soc_ctl_map */
-	{
-		.compatible = "rockchip,rk3399-sdhci-5.1",
-		.data = &sdhci_arasan_rk3399_data,
-	},
-	{
-		.compatible = "intel,lgm-sdhci-5.1-emmc",
-		.data = &intel_lgm_emmc_data,
-	},
-	{
-		.compatible = "intel,lgm-sdhci-5.1-sdxc",
-		.data = &intel_lgm_sdxc_data,
-	},
-	/* Generic compatible below here */
-	{
-		.compatible = "arasan,sdhci-8.9a",
-		.data = &sdhci_arasan_data,
-	},
-	{
-		.compatible = "arasan,sdhci-5.1",
-		.data = &sdhci_arasan_data,
-	},
-	{
-		.compatible = "arasan,sdhci-4.9a",
-		.data = &sdhci_arasan_data,
-	},
-	{
-		.compatible = "xlnx,zynqmp-8.9a",
-		.data = &sdhci_arasan_zynqmp_data,
-	},
-	{ /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, sdhci_arasan_of_match);
-
 /**
  * sdhci_arasan_sdcardclk_recalc_rate - Return the card clock rate
  *
+ * @hw:			Pointer to the hardware clock structure.
+ * @parent_rate:		The parent rate (should be rate of clk_xin).
+ *
  * Return the current actual rate of the SD card clock.  This can be used
  * to communicate with out PHY.
  *
- * @hw:			Pointer to the hardware clock structure.
- * @parent_rate		The parent rate (should be rate of clk_xin).
- * Returns the card clock rate.
+ * Return: The card clock rate.
  */
 static unsigned long sdhci_arasan_sdcardclk_recalc_rate(struct clk_hw *hw,
 						      unsigned long parent_rate)
-
 {
 	struct sdhci_arasan_clk_data *clk_data =
 		container_of(hw, struct sdhci_arasan_clk_data, sdcardclk_hw);
@@ -589,16 +549,16 @@ static const struct clk_ops arasan_sdcardclk_ops = {
 /**
  * sdhci_arasan_sampleclk_recalc_rate - Return the sampling clock rate
  *
+ * @hw:			Pointer to the hardware clock structure.
+ * @parent_rate:		The parent rate (should be rate of clk_xin).
+ *
  * Return the current actual rate of the sampling clock.  This can be used
  * to communicate with out PHY.
  *
- * @hw:			Pointer to the hardware clock structure.
- * @parent_rate		The parent rate (should be rate of clk_xin).
- * Returns the sample clock rate.
+ * Return: The sample clock rate.
  */
 static unsigned long sdhci_arasan_sampleclk_recalc_rate(struct clk_hw *hw,
 						      unsigned long parent_rate)
-
 {
 	struct sdhci_arasan_clk_data *clk_data =
 		container_of(hw, struct sdhci_arasan_clk_data, sampleclk_hw);
@@ -616,14 +576,14 @@ static const struct clk_ops arasan_sampleclk_ops = {
 /**
  * sdhci_zynqmp_sdcardclk_set_phase - Set the SD Output Clock Tap Delays
  *
+ * @hw:			Pointer to the hardware clock structure.
+ * @degrees:		The clock phase shift between 0 - 359.
+ *
  * Set the SD Output Clock Tap Delays for Output path
  *
- * @hw:			Pointer to the hardware clock structure.
- * @degrees		The clock phase shift between 0 - 359.
  * Return: 0 on success and error value on error
  */
 static int sdhci_zynqmp_sdcardclk_set_phase(struct clk_hw *hw, int degrees)
-
 {
 	struct sdhci_arasan_clk_data *clk_data =
 		container_of(hw, struct sdhci_arasan_clk_data, sdcardclk_hw);
@@ -688,14 +648,14 @@ static const struct clk_ops zynqmp_sdcardclk_ops = {
 /**
  * sdhci_zynqmp_sampleclk_set_phase - Set the SD Input Clock Tap Delays
  *
+ * @hw:			Pointer to the hardware clock structure.
+ * @degrees:		The clock phase shift between 0 - 359.
+ *
  * Set the SD Input Clock Tap Delays for Input path
  *
- * @hw:			Pointer to the hardware clock structure.
- * @degrees		The clock phase shift between 0 - 359.
  * Return: 0 on success and error value on error
  */
 static int sdhci_zynqmp_sampleclk_set_phase(struct clk_hw *hw, int degrees)
-
 {
 	struct sdhci_arasan_clk_data *clk_data =
 		container_of(hw, struct sdhci_arasan_clk_data, sampleclk_hw);
@@ -757,6 +717,154 @@ static const struct clk_ops zynqmp_sampleclk_ops = {
 	.set_phase = sdhci_zynqmp_sampleclk_set_phase,
 };
 
+/**
+ * sdhci_versal_sdcardclk_set_phase - Set the SD Output Clock Tap Delays
+ *
+ * @hw:			Pointer to the hardware clock structure.
+ * @degrees:		The clock phase shift between 0 - 359.
+ *
+ * Set the SD Output Clock Tap Delays for Output path
+ *
+ * Return: 0 on success and error value on error
+ */
+static int sdhci_versal_sdcardclk_set_phase(struct clk_hw *hw, int degrees)
+{
+	struct sdhci_arasan_clk_data *clk_data =
+		container_of(hw, struct sdhci_arasan_clk_data, sdcardclk_hw);
+	struct sdhci_arasan_data *sdhci_arasan =
+		container_of(clk_data, struct sdhci_arasan_data, clk_data);
+	struct sdhci_host *host = sdhci_arasan->host;
+	u8 tap_delay, tap_max = 0;
+	int ret;
+
+	/*
+	 * This is applicable for SDHCI_SPEC_300 and above
+	 * Versal does not set phase for <=25MHz clock.
+	 * If degrees is zero, no need to do anything.
+	 */
+	if (host->version < SDHCI_SPEC_300 ||
+	    host->timing == MMC_TIMING_LEGACY ||
+	    host->timing == MMC_TIMING_UHS_SDR12 || !degrees)
+		return 0;
+
+	switch (host->timing) {
+	case MMC_TIMING_MMC_HS:
+	case MMC_TIMING_SD_HS:
+	case MMC_TIMING_UHS_SDR25:
+	case MMC_TIMING_UHS_DDR50:
+	case MMC_TIMING_MMC_DDR52:
+		/* For 50MHz clock, 30 Taps are available */
+		tap_max = 30;
+		break;
+	case MMC_TIMING_UHS_SDR50:
+		/* For 100MHz clock, 15 Taps are available */
+		tap_max = 15;
+		break;
+	case MMC_TIMING_UHS_SDR104:
+	case MMC_TIMING_MMC_HS200:
+		/* For 200MHz clock, 8 Taps are available */
+		tap_max = 8;
+	default:
+		break;
+	}
+
+	tap_delay = (degrees * tap_max) / 360;
+
+	/* Set the Clock Phase */
+	if (tap_delay) {
+		u32 regval;
+
+		regval = sdhci_readl(host, SDHCI_ARASAN_OTAPDLY_REGISTER);
+		regval |= SDHCI_OTAPDLY_ENABLE;
+		sdhci_writel(host, regval, SDHCI_ARASAN_OTAPDLY_REGISTER);
+		regval |= tap_delay;
+		sdhci_writel(host, regval, SDHCI_ARASAN_OTAPDLY_REGISTER);
+	}
+
+	return ret;
+}
+
+static const struct clk_ops versal_sdcardclk_ops = {
+	.recalc_rate = sdhci_arasan_sdcardclk_recalc_rate,
+	.set_phase = sdhci_versal_sdcardclk_set_phase,
+};
+
+/**
+ * sdhci_versal_sampleclk_set_phase - Set the SD Input Clock Tap Delays
+ *
+ * @hw:			Pointer to the hardware clock structure.
+ * @degrees:		The clock phase shift between 0 - 359.
+ *
+ * Set the SD Input Clock Tap Delays for Input path
+ *
+ * Return: 0 on success and error value on error
+ */
+static int sdhci_versal_sampleclk_set_phase(struct clk_hw *hw, int degrees)
+{
+	struct sdhci_arasan_clk_data *clk_data =
+		container_of(hw, struct sdhci_arasan_clk_data, sampleclk_hw);
+	struct sdhci_arasan_data *sdhci_arasan =
+		container_of(clk_data, struct sdhci_arasan_data, clk_data);
+	struct sdhci_host *host = sdhci_arasan->host;
+	u8 tap_delay, tap_max = 0;
+	int ret;
+
+	/*
+	 * This is applicable for SDHCI_SPEC_300 and above
+	 * Versal does not set phase for <=25MHz clock.
+	 * If degrees is zero, no need to do anything.
+	 */
+	if (host->version < SDHCI_SPEC_300 ||
+	    host->timing == MMC_TIMING_LEGACY ||
+	    host->timing == MMC_TIMING_UHS_SDR12 || !degrees)
+		return 0;
+
+	switch (host->timing) {
+	case MMC_TIMING_MMC_HS:
+	case MMC_TIMING_SD_HS:
+	case MMC_TIMING_UHS_SDR25:
+	case MMC_TIMING_UHS_DDR50:
+	case MMC_TIMING_MMC_DDR52:
+		/* For 50MHz clock, 120 Taps are available */
+		tap_max = 120;
+		break;
+	case MMC_TIMING_UHS_SDR50:
+		/* For 100MHz clock, 60 Taps are available */
+		tap_max = 60;
+		break;
+	case MMC_TIMING_UHS_SDR104:
+	case MMC_TIMING_MMC_HS200:
+		/* For 200MHz clock, 30 Taps are available */
+		tap_max = 30;
+	default:
+		break;
+	}
+
+	tap_delay = (degrees * tap_max) / 360;
+
+	/* Set the Clock Phase */
+	if (tap_delay) {
+		u32 regval;
+
+		regval = sdhci_readl(host, SDHCI_ARASAN_ITAPDLY_REGISTER);
+		regval |= SDHCI_ITAPDLY_CHGWIN;
+		sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER);
+		regval |= SDHCI_ITAPDLY_ENABLE;
+		sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER);
+		regval |= tap_delay;
+		sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER);
+		regval &= ~SDHCI_ITAPDLY_CHGWIN;
+		sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER);
+	}
+
+	return ret;
+}
+
+static const struct clk_ops versal_sampleclk_ops = {
+	.recalc_rate = sdhci_arasan_sampleclk_recalc_rate,
+	.set_phase = sdhci_versal_sampleclk_set_phase,
+};
+
 static void arasan_zynqmp_dll_reset(struct sdhci_host *host, u32 deviceid)
 {
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -804,6 +912,9 @@ static int arasan_zynqmp_execute_tuning(struct mmc_host *mmc, u32 opcode)
 /**
  * sdhci_arasan_update_clockmultiplier - Set corecfg_clockmultiplier
  *
+ * @host:		The sdhci_host
+ * @value:		The value to write
+ *
  * The corecfg_clockmultiplier is supposed to contain clock multiplier
  * value of programmable clock generator.
  *
@@ -815,8 +926,6 @@ static int arasan_zynqmp_execute_tuning(struct mmc_host *mmc, u32 opcode)
  * - The value of corecfg_clockmultiplier should sync with that of corresponding
  *   value reading from sdhci_capability_register. So this function is called
  *   once at probe time and never called again.
- *
- * @host:		The sdhci_host
  */
 static void sdhci_arasan_update_clockmultiplier(struct sdhci_host *host,
 						u32 value)
@@ -843,6 +952,8 @@ static void sdhci_arasan_update_clockmultiplier(struct sdhci_host *host,
 /**
  * sdhci_arasan_update_baseclkfreq - Set corecfg_baseclkfreq
  *
+ * @host:		The sdhci_host
+ *
  * The corecfg_baseclkfreq is supposed to contain the MHz of clk_xin.  This
  * function can be used to make that happen.
  *
@@ -854,8 +965,6 @@ static void sdhci_arasan_update_clockmultiplier(struct sdhci_host *host,
  * - It's assumed that clk_xin is not dynamic and that we use the SDHCI divider
  *   to achieve lower clock rates.  That means that this function is called once
  *   at probe time and never called again.
- *
- * @host:		The sdhci_host
  */
 static void sdhci_arasan_update_baseclkfreq(struct sdhci_host *host)
 {
@@ -919,10 +1028,10 @@ static void arasan_dt_read_clk_phase(struct device *dev,
 /**
  * arasan_dt_parse_clk_phases - Read Clock Delay values from DT
  *
- * Called at initialization to parse the values of Clock Delays.
- *
  * @dev:		Pointer to our struct device.
  * @clk_data:		Pointer to the Clock Data structure
+ *
+ * Called at initialization to parse the values of Clock Delays.
  */
 static void arasan_dt_parse_clk_phases(struct device *dev,
 				       struct sdhci_arasan_clk_data *clk_data)
@@ -954,6 +1063,16 @@ static void arasan_dt_parse_clk_phases(struct device *dev,
 		}
 	}
 
+	if (of_device_is_compatible(dev->of_node, "xlnx,versal-8.9a")) {
+		iclk_phase = (int [MMC_TIMING_MMC_HS400 + 1]) VERSAL_ICLK_PHASE;
+		oclk_phase = (int [MMC_TIMING_MMC_HS400 + 1]) VERSAL_OCLK_PHASE;
+
+		for (i = 0; i <= MMC_TIMING_MMC_HS400; i++) {
+			clk_data->clk_phase_in[i] = iclk_phase[i];
+			clk_data->clk_phase_out[i] = oclk_phase[i];
+		}
+	}
+
 	arasan_dt_read_clk_phase(dev, clk_data, MMC_TIMING_LEGACY,
 				 "clk-phase-legacy");
 	arasan_dt_read_clk_phase(dev, clk_data, MMC_TIMING_MMC_HS,
@@ -978,17 +1097,120 @@ static void arasan_dt_parse_clk_phases(struct device *dev,
 				 "clk-phase-mmc-hs400");
 }
 
+static const struct sdhci_pltfm_data sdhci_arasan_pdata = {
+	.ops = &sdhci_arasan_ops,
+	.quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
+	.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
+			SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN |
+			SDHCI_QUIRK2_STOP_WITH_TC,
+};
+
+static const struct sdhci_arasan_clk_ops arasan_clk_ops = {
+	.sdcardclk_ops = &arasan_sdcardclk_ops,
+	.sampleclk_ops = &arasan_sampleclk_ops,
+};
+
+static struct sdhci_arasan_of_data sdhci_arasan_generic_data = {
+	.pdata = &sdhci_arasan_pdata,
+	.clk_ops = &arasan_clk_ops,
+};
+
+static struct sdhci_arasan_of_data sdhci_arasan_rk3399_data = {
+	.soc_ctl_map = &rk3399_soc_ctl_map,
+	.pdata = &sdhci_arasan_cqe_pdata,
+	.clk_ops = &arasan_clk_ops,
+};
+
+static struct sdhci_arasan_of_data intel_lgm_emmc_data = {
+	.soc_ctl_map = &intel_lgm_emmc_soc_ctl_map,
+	.pdata = &sdhci_arasan_cqe_pdata,
+	.clk_ops = &arasan_clk_ops,
+};
+
+static struct sdhci_arasan_of_data intel_lgm_sdxc_data = {
+	.soc_ctl_map = &intel_lgm_sdxc_soc_ctl_map,
+	.pdata = &sdhci_arasan_cqe_pdata,
+	.clk_ops = &arasan_clk_ops,
+};
+
+static const struct sdhci_pltfm_data sdhci_arasan_zynqmp_pdata = {
+	.ops = &sdhci_arasan_ops,
+	.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
+			SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN |
+			SDHCI_QUIRK2_STOP_WITH_TC,
+};
+
+static const struct sdhci_arasan_clk_ops zynqmp_clk_ops = {
+	.sdcardclk_ops = &zynqmp_sdcardclk_ops,
+	.sampleclk_ops = &zynqmp_sampleclk_ops,
+};
+
+static struct sdhci_arasan_of_data sdhci_arasan_zynqmp_data = {
+	.pdata = &sdhci_arasan_zynqmp_pdata,
+	.clk_ops = &zynqmp_clk_ops,
+};
+
+static const struct sdhci_arasan_clk_ops versal_clk_ops = {
+	.sdcardclk_ops = &versal_sdcardclk_ops,
+	.sampleclk_ops = &versal_sampleclk_ops,
+};
+
+static struct sdhci_arasan_of_data sdhci_arasan_versal_data = {
+	.pdata = &sdhci_arasan_zynqmp_pdata,
+	.clk_ops = &versal_clk_ops,
+};
+
+static const struct of_device_id sdhci_arasan_of_match[] = {
+	/* SoC-specific compatible strings w/ soc_ctl_map */
+	{
+		.compatible = "rockchip,rk3399-sdhci-5.1",
+		.data = &sdhci_arasan_rk3399_data,
+	},
+	{
+		.compatible = "intel,lgm-sdhci-5.1-emmc",
+		.data = &intel_lgm_emmc_data,
+	},
+	{
+		.compatible = "intel,lgm-sdhci-5.1-sdxc",
+		.data = &intel_lgm_sdxc_data,
+	},
+	/* Generic compatible below here */
+	{
+		.compatible = "arasan,sdhci-8.9a",
+		.data = &sdhci_arasan_generic_data,
+	},
+	{
+		.compatible = "arasan,sdhci-5.1",
+		.data = &sdhci_arasan_generic_data,
+	},
+	{
+		.compatible = "arasan,sdhci-4.9a",
+		.data = &sdhci_arasan_generic_data,
+	},
+	{
+		.compatible = "xlnx,zynqmp-8.9a",
+		.data = &sdhci_arasan_zynqmp_data,
+	},
+	{
+		.compatible = "xlnx,versal-8.9a",
+		.data = &sdhci_arasan_versal_data,
+	},
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, sdhci_arasan_of_match);
+
 /**
  * sdhci_arasan_register_sdcardclk - Register the sdcardclk for a PHY to use
  *
+ * @sdhci_arasan:	Our private data structure.
+ * @clk_xin:		Pointer to the functional clock
+ * @dev:		Pointer to our struct device.
+ *
  * Some PHY devices need to know what the actual card clock is.  In order for
  * them to find out, we'll provide a clock through the common clock framework
  * for them to query.
  *
- * @sdhci_arasan:	Our private data structure.
- * @clk_xin:		Pointer to the functional clock
- * @dev:		Pointer to our struct device.
- * Returns 0 on success and error value on error
+ * Return: 0 on success and error value on error
  */
 static int
 sdhci_arasan_register_sdcardclk(struct sdhci_arasan_data *sdhci_arasan,
@@ -1012,10 +1234,7 @@ sdhci_arasan_register_sdcardclk(struct sdhci_arasan_data *sdhci_arasan,
 	sdcardclk_init.parent_names = &parent_clk_name;
 	sdcardclk_init.num_parents = 1;
 	sdcardclk_init.flags = CLK_GET_RATE_NOCACHE;
-	if (of_device_is_compatible(np, "xlnx,zynqmp-8.9a"))
-		sdcardclk_init.ops = &zynqmp_sdcardclk_ops;
-	else
-		sdcardclk_init.ops = &arasan_sdcardclk_ops;
+	sdcardclk_init.ops = sdhci_arasan->clk_ops->sdcardclk_ops;
 
 	clk_data->sdcardclk_hw.init = &sdcardclk_init;
 	clk_data->sdcardclk =
@@ -1033,14 +1252,15 @@ sdhci_arasan_register_sdcardclk(struct sdhci_arasan_data *sdhci_arasan,
 /**
  * sdhci_arasan_register_sampleclk - Register the sampleclk for a PHY to use
  *
+ * @sdhci_arasan:	Our private data structure.
+ * @clk_xin:		Pointer to the functional clock
+ * @dev:		Pointer to our struct device.
+ *
  * Some PHY devices need to know what the actual card clock is.  In order for
  * them to find out, we'll provide a clock through the common clock framework
  * for them to query.
  *
- * @sdhci_arasan:	Our private data structure.
- * @clk_xin:		Pointer to the functional clock
- * @dev:		Pointer to our struct device.
- * Returns 0 on success and error value on error
+ * Return: 0 on success and error value on error
  */
 static int
 sdhci_arasan_register_sampleclk(struct sdhci_arasan_data *sdhci_arasan,
@@ -1064,10 +1284,7 @@ sdhci_arasan_register_sampleclk(struct sdhci_arasan_data *sdhci_arasan,
 	sampleclk_init.parent_names = &parent_clk_name;
 	sampleclk_init.num_parents = 1;
 	sampleclk_init.flags = CLK_GET_RATE_NOCACHE;
-	if (of_device_is_compatible(np, "xlnx,zynqmp-8.9a"))
-		sampleclk_init.ops = &zynqmp_sampleclk_ops;
-	else
-		sampleclk_init.ops = &arasan_sampleclk_ops;
+	sampleclk_init.ops = sdhci_arasan->clk_ops->sampleclk_ops;
 
 	clk_data->sampleclk_hw.init = &sampleclk_init;
 	clk_data->sampleclk =
@@ -1085,10 +1302,10 @@ sdhci_arasan_register_sampleclk(struct sdhci_arasan_data *sdhci_arasan,
 /**
  * sdhci_arasan_unregister_sdclk - Undoes sdhci_arasan_register_sdclk()
  *
+ * @dev:		Pointer to our struct device.
+ *
  * Should be called any time we're exiting and sdhci_arasan_register_sdclk()
  * returned success.
- *
- * @dev:		Pointer to our struct device.
  */
 static void sdhci_arasan_unregister_sdclk(struct device *dev)
 {
@@ -1103,6 +1320,10 @@ static void sdhci_arasan_unregister_sdclk(struct device *dev)
 /**
  * sdhci_arasan_register_sdclk - Register the sdcardclk for a PHY to use
  *
+ * @sdhci_arasan:	Our private data structure.
+ * @clk_xin:		Pointer to the functional clock
+ * @dev:		Pointer to our struct device.
+ *
  * Some PHY devices need to know what the actual card clock is.  In order for
  * them to find out, we'll provide a clock through the common clock framework
  * for them to query.
@@ -1115,10 +1336,7 @@ static void sdhci_arasan_unregister_sdclk(struct device *dev)
  * to create nice clean device tree bindings and later (if needed) we can try
  * re-architecting SDHCI if we see some benefit to it.
  *
- * @sdhci_arasan:	Our private data structure.
- * @clk_xin:		Pointer to the functional clock
- * @dev:		Pointer to our struct device.
- * Returns 0 on success and error value on error
+ * Return: 0 on success and error value on error
  */
 static int sdhci_arasan_register_sdclk(struct sdhci_arasan_data *sdhci_arasan,
 				       struct clk *clk_xin,
@@ -1215,6 +1433,7 @@ static int sdhci_arasan_probe(struct platform_device *pdev)
 	sdhci_arasan->host = host;
 
 	sdhci_arasan->soc_ctl_map = data->soc_ctl_map;
+	sdhci_arasan->clk_ops = data->clk_ops;
 
 	node = of_parse_phandle(pdev->dev.of_node, "arasan,soc-ctl-syscon", 0);
 	if (node) {
diff --git a/drivers/mmc/host/sdhci-of-at91.c b/drivers/mmc/host/sdhci-of-at91.c
index c79bff5e2280..25f4e0f4f53b 100644
--- a/drivers/mmc/host/sdhci-of-at91.c
+++ b/drivers/mmc/host/sdhci-of-at91.c
@@ -6,6 +6,7 @@
  *		 2015 Ludovic Desroches <ludovic.desroches@atmel.com>
  */
 
+#include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/err.h>
@@ -179,9 +180,9 @@ static int sdhci_at91_set_clks_presets(struct device *dev)
 	clk_mul = gck_rate / clk_base_rate - 1;
 
 	caps0 &= ~SDHCI_CLOCK_V3_BASE_MASK;
-	caps0 |= (clk_base << SDHCI_CLOCK_BASE_SHIFT) & SDHCI_CLOCK_V3_BASE_MASK;
+	caps0 |= FIELD_PREP(SDHCI_CLOCK_V3_BASE_MASK, clk_base);
 	caps1 &= ~SDHCI_CLOCK_MUL_MASK;
-	caps1 |= (clk_mul << SDHCI_CLOCK_MUL_SHIFT) & SDHCI_CLOCK_MUL_MASK;
+	caps1 |= FIELD_PREP(SDHCI_CLOCK_MUL_MASK, clk_mul);
 	/* Set capabilities in r/w mode. */
 	writel(SDMMC_CACR_KEY | SDMMC_CACR_CAPWREN, host->ioaddr + SDMMC_CACR);
 	writel(caps0, host->ioaddr + SDHCI_CAPABILITIES);
diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c
index 525de2454a4d..a98c9476bfc8 100644
--- a/drivers/mmc/host/sdhci-pci-core.c
+++ b/drivers/mmc/host/sdhci-pci-core.c
@@ -249,12 +249,8 @@ static int ricoh_probe(struct sdhci_pci_chip *chip)
 static int ricoh_mmc_probe_slot(struct sdhci_pci_slot *slot)
 {
 	slot->host->caps =
-		((0x21 << SDHCI_TIMEOUT_CLK_SHIFT)
-			& SDHCI_TIMEOUT_CLK_MASK) |
-
-		((0x21 << SDHCI_CLOCK_BASE_SHIFT)
-			& SDHCI_CLOCK_BASE_MASK) |
-
+		FIELD_PREP(SDHCI_TIMEOUT_CLK_MASK, 0x21) |
+		FIELD_PREP(SDHCI_CLOCK_BASE_MASK, 0x21) |
 		SDHCI_TIMEOUT_CLK_UNIT |
 		SDHCI_CAN_VDD_330 |
 		SDHCI_CAN_DO_HISPD |
diff --git a/drivers/mmc/host/sdhci-sprd.c b/drivers/mmc/host/sdhci-sprd.c
index 2ab42c59e4f8..60c3a4c620f9 100644
--- a/drivers/mmc/host/sdhci-sprd.c
+++ b/drivers/mmc/host/sdhci-sprd.c
@@ -556,7 +556,8 @@ static int sdhci_sprd_probe(struct platform_device *pdev)
 		sdhci_sprd_voltage_switch;
 
 	host->mmc->caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED |
-		MMC_CAP_ERASE | MMC_CAP_CMD23 | MMC_CAP_WAIT_WHILE_BUSY;
+		MMC_CAP_WAIT_WHILE_BUSY;
+
 	ret = mmc_of_parse(host->mmc);
 	if (ret)
 		goto pltfm_free;
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 3f716466fcfd..344a7e0e33fe 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -4117,11 +4117,9 @@ int sdhci_setup_host(struct sdhci_host *host)
 	}
 
 	if (host->version >= SDHCI_SPEC_300)
-		host->max_clk = (host->caps & SDHCI_CLOCK_V3_BASE_MASK)
-			>> SDHCI_CLOCK_BASE_SHIFT;
+		host->max_clk = FIELD_GET(SDHCI_CLOCK_V3_BASE_MASK, host->caps);
 	else
-		host->max_clk = (host->caps & SDHCI_CLOCK_BASE_MASK)
-			>> SDHCI_CLOCK_BASE_SHIFT;
+		host->max_clk = FIELD_GET(SDHCI_CLOCK_BASE_MASK, host->caps);
 
 	host->max_clk *= 1000000;
 	if (host->max_clk == 0 || host->quirks &
@@ -4139,8 +4137,7 @@ int sdhci_setup_host(struct sdhci_host *host)
 	 * In case of Host Controller v3.00, find out whether clock
 	 * multiplier is supported.
 	 */
-	host->clk_mul = (host->caps1 & SDHCI_CLOCK_MUL_MASK) >>
-			SDHCI_CLOCK_MUL_SHIFT;
+	host->clk_mul = FIELD_GET(SDHCI_CLOCK_MUL_MASK, host->caps1);
 
 	/*
 	 * In case the value in Clock Multiplier is 0, then programmable
@@ -4173,8 +4170,7 @@ int sdhci_setup_host(struct sdhci_host *host)
 		mmc->f_max = max_clk;
 
 	if (!(host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)) {
-		host->timeout_clk = (host->caps & SDHCI_TIMEOUT_CLK_MASK) >>
-					SDHCI_TIMEOUT_CLK_SHIFT;
+		host->timeout_clk = FIELD_GET(SDHCI_TIMEOUT_CLK_MASK, host->caps);
 
 		if (host->caps & SDHCI_TIMEOUT_CLK_UNIT)
 			host->timeout_clk *= 1000;
@@ -4326,8 +4322,8 @@ int sdhci_setup_host(struct sdhci_host *host)
 		mmc->caps |= MMC_CAP_DRIVER_TYPE_D;
 
 	/* Initial value for re-tuning timer count */
-	host->tuning_count = (host->caps1 & SDHCI_RETUNING_TIMER_COUNT_MASK) >>
-			     SDHCI_RETUNING_TIMER_COUNT_SHIFT;
+	host->tuning_count = FIELD_GET(SDHCI_RETUNING_TIMER_COUNT_MASK,
+				       host->caps1);
 
 	/*
 	 * In case Re-tuning Timer is not disabled, the actual value of
@@ -4337,8 +4333,7 @@ int sdhci_setup_host(struct sdhci_host *host)
 		host->tuning_count = 1 << (host->tuning_count - 1);
 
 	/* Re-tuning mode supported by the Host Controller */
-	host->tuning_mode = (host->caps1 & SDHCI_RETUNING_MODE_MASK) >>
-			     SDHCI_RETUNING_MODE_SHIFT;
+	host->tuning_mode = FIELD_GET(SDHCI_RETUNING_MODE_MASK, host->caps1);
 
 	ocr_avail = 0;
 
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 79dffbb731d3..d7f1441b0fc3 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -200,12 +200,10 @@
 #define  SDHCI_CTRL_PRESET_VAL_ENABLE	0x8000
 
 #define SDHCI_CAPABILITIES	0x40
-#define  SDHCI_TIMEOUT_CLK_MASK	0x0000003F
-#define  SDHCI_TIMEOUT_CLK_SHIFT 0
+#define  SDHCI_TIMEOUT_CLK_MASK		GENMASK(5, 0)
 #define  SDHCI_TIMEOUT_CLK_UNIT	0x00000080
-#define  SDHCI_CLOCK_BASE_MASK	0x00003F00
-#define  SDHCI_CLOCK_V3_BASE_MASK	0x0000FF00
-#define  SDHCI_CLOCK_BASE_SHIFT	8
+#define  SDHCI_CLOCK_BASE_MASK		GENMASK(13, 8)
+#define  SDHCI_CLOCK_V3_BASE_MASK	GENMASK(15, 8)
 #define  SDHCI_MAX_BLOCK_MASK	0x00030000
 #define  SDHCI_MAX_BLOCK_SHIFT  16
 #define  SDHCI_CAN_DO_8BIT	0x00040000
@@ -220,24 +218,20 @@
 #define  SDHCI_CAN_64BIT_V4	0x08000000
 #define  SDHCI_CAN_64BIT	0x10000000
 
+#define SDHCI_CAPABILITIES_1	0x44
 #define  SDHCI_SUPPORT_SDR50	0x00000001
 #define  SDHCI_SUPPORT_SDR104	0x00000002
 #define  SDHCI_SUPPORT_DDR50	0x00000004
 #define  SDHCI_DRIVER_TYPE_A	0x00000010
 #define  SDHCI_DRIVER_TYPE_C	0x00000020
 #define  SDHCI_DRIVER_TYPE_D	0x00000040
-#define  SDHCI_RETUNING_TIMER_COUNT_MASK	0x00000F00
-#define  SDHCI_RETUNING_TIMER_COUNT_SHIFT	8
+#define  SDHCI_RETUNING_TIMER_COUNT_MASK	GENMASK(11, 8)
 #define  SDHCI_USE_SDR50_TUNING			0x00002000
-#define  SDHCI_RETUNING_MODE_MASK		0x0000C000
-#define  SDHCI_RETUNING_MODE_SHIFT		14
-#define  SDHCI_CLOCK_MUL_MASK	0x00FF0000
-#define  SDHCI_CLOCK_MUL_SHIFT	16
+#define  SDHCI_RETUNING_MODE_MASK		GENMASK(15, 14)
+#define  SDHCI_CLOCK_MUL_MASK			GENMASK(23, 16)
 #define  SDHCI_CAN_DO_ADMA3	0x08000000
 #define  SDHCI_SUPPORT_HS400	0x80000000 /* Non-standard */
 
-#define SDHCI_CAPABILITIES_1	0x44
-
 #define SDHCI_MAX_CURRENT		0x48
 #define  SDHCI_MAX_CURRENT_LIMIT	0xFF
 #define  SDHCI_MAX_CURRENT_330_MASK	0x0000FF
diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c
index 740179f42cf2..67f917d6ecd3 100644
--- a/drivers/mmc/host/wbsd.c
+++ b/drivers/mmc/host/wbsd.c
@@ -28,6 +28,8 @@
 #include <linux/pnp.h>
 #include <linux/highmem.h>
 #include <linux/mmc/host.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/sd.h>
 #include <linux/scatterlist.h>
 #include <linux/slab.h>
 
@@ -770,22 +772,22 @@ static void wbsd_request(struct mmc_host *mmc, struct mmc_request *mrq)
 		 * interrupts.
 		 */
 		switch (cmd->opcode) {
-		case 11:
-		case 17:
-		case 18:
-		case 20:
-		case 24:
-		case 25:
-		case 26:
-		case 27:
-		case 30:
-		case 42:
-		case 56:
+		case SD_SWITCH_VOLTAGE:
+		case MMC_READ_SINGLE_BLOCK:
+		case MMC_READ_MULTIPLE_BLOCK:
+		case MMC_WRITE_DAT_UNTIL_STOP:
+		case MMC_WRITE_BLOCK:
+		case MMC_WRITE_MULTIPLE_BLOCK:
+		case MMC_PROGRAM_CID:
+		case MMC_PROGRAM_CSD:
+		case MMC_SEND_WRITE_PROT:
+		case MMC_LOCK_UNLOCK:
+		case MMC_GEN_CMD:
 			break;
 
 		/* ACMDs. We don't keep track of state, so we just treat them
 		 * like any other command. */
-		case 51:
+		case SD_APP_SEND_SCR:
 			break;
 
 		default:
diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile
index 7ddb742de1fe..653923896205 100644
--- a/drivers/mtd/spi-nor/Makefile
+++ b/drivers/mtd/spi-nor/Makefile
@@ -18,3 +18,5 @@ spi-nor-objs			+= winbond.o
 spi-nor-objs			+= xilinx.o
 spi-nor-objs			+= xmc.o
 obj-$(CONFIG_MTD_SPI_NOR)	+= spi-nor.o
+
+obj-$(CONFIG_MTD_SPI_NOR)	+= controllers/
diff --git a/drivers/net/caif/Kconfig b/drivers/net/caif/Kconfig
index 9db0570c5beb..661c25eb1c46 100644
--- a/drivers/net/caif/Kconfig
+++ b/drivers/net/caif/Kconfig
@@ -50,7 +50,7 @@ config CAIF_HSI
 
 config CAIF_VIRTIO
 	tristate "CAIF virtio transport driver"
-	depends on CAIF && HAS_DMA
+	depends on CAIF && HAS_DMA && VHOST_DPN
 	select VHOST_RING
 	select VIRTIO
 	select GENERIC_ALLOCATOR
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 2d0d91db0ddb..5c444cd722bd 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -66,58 +66,6 @@ static const struct mt7530_mib_desc mt7530_mib[] = {
 	MIB_DESC(1, 0xb8, "RxArlDrop"),
 };
 
-static int
-mt7623_trgmii_write(struct mt7530_priv *priv,  u32 reg, u32 val)
-{
-	int ret;
-
-	ret =  regmap_write(priv->ethernet, TRGMII_BASE(reg), val);
-	if (ret < 0)
-		dev_err(priv->dev,
-			"failed to priv write register\n");
-	return ret;
-}
-
-static u32
-mt7623_trgmii_read(struct mt7530_priv *priv, u32 reg)
-{
-	int ret;
-	u32 val;
-
-	ret = regmap_read(priv->ethernet, TRGMII_BASE(reg), &val);
-	if (ret < 0) {
-		dev_err(priv->dev,
-			"failed to priv read register\n");
-		return ret;
-	}
-
-	return val;
-}
-
-static void
-mt7623_trgmii_rmw(struct mt7530_priv *priv, u32 reg,
-		  u32 mask, u32 set)
-{
-	u32 val;
-
-	val = mt7623_trgmii_read(priv, reg);
-	val &= ~mask;
-	val |= set;
-	mt7623_trgmii_write(priv, reg, val);
-}
-
-static void
-mt7623_trgmii_set(struct mt7530_priv *priv, u32 reg, u32 val)
-{
-	mt7623_trgmii_rmw(priv, reg, 0, val);
-}
-
-static void
-mt7623_trgmii_clear(struct mt7530_priv *priv, u32 reg, u32 val)
-{
-	mt7623_trgmii_rmw(priv, reg, val, 0);
-}
-
 static int
 core_read_mmd_indirect(struct mt7530_priv *priv, int prtad, int devad)
 {
@@ -530,27 +478,6 @@ mt7530_pad_clk_setup(struct dsa_switch *ds, int mode)
 		for (i = 0 ; i < NUM_TRGMII_CTRL; i++)
 			mt7530_rmw(priv, MT7530_TRGMII_RD(i),
 				   RD_TAP_MASK, RD_TAP(16));
-	else
-		if (priv->id != ID_MT7621)
-			mt7623_trgmii_set(priv, GSW_INTF_MODE,
-					  INTF_MODE_TRGMII);
-
-	return 0;
-}
-
-static int
-mt7623_pad_clk_setup(struct dsa_switch *ds)
-{
-	struct mt7530_priv *priv = ds->priv;
-	int i;
-
-	for (i = 0 ; i < NUM_TRGMII_CTRL; i++)
-		mt7623_trgmii_write(priv, GSW_TRGMII_TD_ODT(i),
-				    TD_DM_DRVP(8) | TD_DM_DRVN(8));
-
-	mt7623_trgmii_set(priv, GSW_TRGMII_RCK_CTRL, RX_RST | RXC_DQSISEL);
-	mt7623_trgmii_clear(priv, GSW_TRGMII_RCK_CTRL, RX_RST);
-
 	return 0;
 }
 
@@ -846,8 +773,9 @@ mt7530_port_set_vlan_unaware(struct dsa_switch *ds, int port)
 	 */
 	mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
 		   MT7530_PORT_MATRIX_MODE);
-	mt7530_rmw(priv, MT7530_PVC_P(port), VLAN_ATTR_MASK,
-		   VLAN_ATTR(MT7530_VLAN_TRANSPARENT));
+	mt7530_rmw(priv, MT7530_PVC_P(port), VLAN_ATTR_MASK | PVC_EG_TAG_MASK,
+		   VLAN_ATTR(MT7530_VLAN_TRANSPARENT) |
+		   PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
 
 	for (i = 0; i < MT7530_NUM_PORTS; i++) {
 		if (dsa_is_user_port(ds, i) &&
@@ -863,8 +791,8 @@ mt7530_port_set_vlan_unaware(struct dsa_switch *ds, int port)
 	if (all_user_ports_removed) {
 		mt7530_write(priv, MT7530_PCR_P(MT7530_CPU_PORT),
 			     PCR_MATRIX(dsa_user_ports(priv->ds)));
-		mt7530_write(priv, MT7530_PVC_P(MT7530_CPU_PORT),
-			     PORT_SPEC_TAG);
+		mt7530_write(priv, MT7530_PVC_P(MT7530_CPU_PORT), PORT_SPEC_TAG
+			     | PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
 	}
 }
 
@@ -890,8 +818,9 @@ mt7530_port_set_vlan_aware(struct dsa_switch *ds, int port)
 	/* Set the port as a user port which is to be able to recognize VID
 	 * from incoming packets before fetching entry within the VLAN table.
 	 */
-	mt7530_rmw(priv, MT7530_PVC_P(port), VLAN_ATTR_MASK,
-		   VLAN_ATTR(MT7530_VLAN_USER));
+	mt7530_rmw(priv, MT7530_PVC_P(port), VLAN_ATTR_MASK | PVC_EG_TAG_MASK,
+		   VLAN_ATTR(MT7530_VLAN_USER) |
+		   PVC_EG_TAG(MT7530_VLAN_EG_DISABLED));
 }
 
 static void
@@ -1303,10 +1232,6 @@ mt7530_setup(struct dsa_switch *ds)
 	dn = dsa_to_port(ds, MT7530_CPU_PORT)->master->dev.of_node->parent;
 
 	if (priv->id == ID_MT7530) {
-		priv->ethernet = syscon_node_to_regmap(dn);
-		if (IS_ERR(priv->ethernet))
-			return PTR_ERR(priv->ethernet);
-
 		regulator_set_voltage(priv->core_pwr, 1000000, 1000000);
 		ret = regulator_enable(priv->core_pwr);
 		if (ret < 0) {
@@ -1380,6 +1305,10 @@ mt7530_setup(struct dsa_switch *ds)
 			mt7530_cpu_port_enable(priv, i);
 		else
 			mt7530_port_disable(ds, i);
+
+		/* Enable consistent egress tag */
+		mt7530_rmw(priv, MT7530_PVC_P(i), PVC_EG_TAG_MASK,
+			   PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
 	}
 
 	/* Setup port 5 */
@@ -1468,14 +1397,6 @@ static void mt7530_phylink_mac_config(struct dsa_switch *ds, int port,
 		/* Setup TX circuit incluing relevant PAD and driving */
 		mt7530_pad_clk_setup(ds, state->interface);
 
-		if (priv->id == ID_MT7530) {
-			/* Setup RX circuit, relevant PAD and driving on the
-			 * host which must be placed after the setup on the
-			 * device side is all finished.
-			 */
-			mt7623_pad_clk_setup(ds);
-		}
-
 		priv->p6_interface = state->interface;
 		break;
 	default:
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index ef9b52f3152b..979bb6374678 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -172,9 +172,16 @@ enum mt7530_port_mode {
 /* Register for port vlan control */
 #define MT7530_PVC_P(x)			(0x2010 + ((x) * 0x100))
 #define  PORT_SPEC_TAG			BIT(5)
+#define  PVC_EG_TAG(x)			(((x) & 0x7) << 8)
+#define  PVC_EG_TAG_MASK		PVC_EG_TAG(7)
 #define  VLAN_ATTR(x)			(((x) & 0x3) << 6)
 #define  VLAN_ATTR_MASK			VLAN_ATTR(3)
 
+enum mt7530_vlan_port_eg_tag {
+	MT7530_VLAN_EG_DISABLED = 0,
+	MT7530_VLAN_EG_CONSISTENT = 1,
+};
+
 enum mt7530_vlan_port_attr {
 	MT7530_VLAN_USER = 0,
 	MT7530_VLAN_TRANSPARENT = 3,
@@ -277,7 +284,6 @@ enum mt7530_vlan_port_attr {
 
 /* Registers for TRGMII on the both side */
 #define MT7530_TRGMII_RCK_CTRL		0x7a00
-#define GSW_TRGMII_RCK_CTRL		0x300
 #define  RX_RST				BIT(31)
 #define  RXC_DQSISEL			BIT(30)
 #define  DQSI1_TAP_MASK			(0x7f << 8)
@@ -286,31 +292,24 @@ enum mt7530_vlan_port_attr {
 #define  DQSI0_TAP(x)			((x) & 0x7f)
 
 #define MT7530_TRGMII_RCK_RTT		0x7a04
-#define GSW_TRGMII_RCK_RTT		0x304
 #define  DQS1_GATE			BIT(31)
 #define  DQS0_GATE			BIT(30)
 
 #define MT7530_TRGMII_RD(x)		(0x7a10 + (x) * 8)
-#define GSW_TRGMII_RD(x)		(0x310 + (x) * 8)
 #define  BSLIP_EN			BIT(31)
 #define  EDGE_CHK			BIT(30)
 #define  RD_TAP_MASK			0x7f
 #define  RD_TAP(x)			((x) & 0x7f)
 
-#define GSW_TRGMII_TXCTRL		0x340
 #define MT7530_TRGMII_TXCTRL		0x7a40
 #define  TRAIN_TXEN			BIT(31)
 #define  TXC_INV			BIT(30)
 #define  TX_RST				BIT(28)
 
 #define MT7530_TRGMII_TD_ODT(i)		(0x7a54 + 8 * (i))
-#define GSW_TRGMII_TD_ODT(i)		(0x354 + 8 * (i))
 #define  TD_DM_DRVP(x)			((x) & 0xf)
 #define  TD_DM_DRVN(x)			(((x) & 0xf) << 4)
 
-#define GSW_INTF_MODE			0x390
-#define  INTF_MODE_TRGMII		BIT(1)
-
 #define MT7530_TRGMII_TCK_CTRL		0x7a78
 #define  TCK_TAP(x)			(((x) & 0xf) << 8)
 
@@ -443,7 +442,6 @@ static const char *p5_intf_modes(unsigned int p5_interface)
  * @ds:			The pointer to the dsa core structure
  * @bus:		The bus used for the device and built-in PHY
  * @rstc:		The pointer to reset control used by MCM
- * @ethernet:		The regmap used for access TRGMII-based registers
  * @core_pwr:		The power supplied into the core
  * @io_pwr:		The power supplied into the I/O
  * @reset:		The descriptor for GPIO line tied to its reset pin
@@ -460,7 +458,6 @@ struct mt7530_priv {
 	struct dsa_switch	*ds;
 	struct mii_bus		*bus;
 	struct reset_control	*rstc;
-	struct regmap		*ethernet;
 	struct regulator	*core_pwr;
 	struct regulator	*io_pwr;
 	struct gpio_desc	*reset;
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 221593261e8f..dd8a5666a584 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -709,7 +709,8 @@ static void mv88e6xxx_mac_link_down(struct dsa_switch *ds, int port,
 	ops = chip->info->ops;
 
 	mv88e6xxx_reg_lock(chip);
-	if (!mv88e6xxx_port_ppu_updates(chip, port) && ops->port_set_link)
+	if ((!mv88e6xxx_port_ppu_updates(chip, port) ||
+	     mode == MLO_AN_FIXED) && ops->port_set_link)
 		err = ops->port_set_link(chip, port, LINK_FORCED_DOWN);
 	mv88e6xxx_reg_unlock(chip);
 
@@ -731,7 +732,7 @@ static void mv88e6xxx_mac_link_up(struct dsa_switch *ds, int port,
 	ops = chip->info->ops;
 
 	mv88e6xxx_reg_lock(chip);
-	if (!mv88e6xxx_port_ppu_updates(chip, port)) {
+	if (!mv88e6xxx_port_ppu_updates(chip, port) || mode == MLO_AN_FIXED) {
 		/* FIXME: for an automedia port, should we force the link
 		 * down here - what if the link comes up due to "other" media
 		 * while we're bringing the port up, how is the exclusivity
diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c
index 79ca3aadb864..d0a3764ff0cf 100644
--- a/drivers/net/dsa/ocelot/felix.c
+++ b/drivers/net/dsa/ocelot/felix.c
@@ -46,11 +46,8 @@ static int felix_fdb_add(struct dsa_switch *ds, int port,
 			 const unsigned char *addr, u16 vid)
 {
 	struct ocelot *ocelot = ds->priv;
-	bool vlan_aware;
 
-	vlan_aware = dsa_port_is_vlan_filtering(dsa_to_port(ds, port));
-
-	return ocelot_fdb_add(ocelot, port, addr, vid, vlan_aware);
+	return ocelot_fdb_add(ocelot, port, addr, vid);
 }
 
 static int felix_fdb_del(struct dsa_switch *ds, int port,
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
index b71f9b04a51e..a87264f95f1a 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
@@ -514,7 +514,7 @@ static void xgbe_isr_task(unsigned long data)
 				xgbe_disable_rx_tx_ints(pdata);
 
 				/* Turn on polling */
-				__napi_schedule_irqoff(&pdata->napi);
+				__napi_schedule(&pdata->napi);
 			}
 		} else {
 			/* Don't clear Rx/Tx status if doing per channel DMA
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
index 239f678a94ed..2a3480fc1d91 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
@@ -3742,7 +3742,7 @@ int t4_phy_fw_ver(struct adapter *adap, int *phy_fw_ver)
 		 FW_PARAMS_PARAM_Z_V(FW_PARAMS_PARAM_DEV_PHYFW_VERSION));
 	ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 1,
 			      &param, &val);
-	if (ret < 0)
+	if (ret)
 		return ret;
 	*phy_fw_ver = val;
 	return 0;
diff --git a/drivers/net/ethernet/dec/tulip/tulip_core.c b/drivers/net/ethernet/dec/tulip/tulip_core.c
index 48ea658aa1a6..15efc294f513 100644
--- a/drivers/net/ethernet/dec/tulip/tulip_core.c
+++ b/drivers/net/ethernet/dec/tulip/tulip_core.c
@@ -1277,7 +1277,7 @@ static const struct net_device_ops tulip_netdev_ops = {
 #endif
 };
 
-const struct pci_device_id early_486_chipsets[] = {
+static const struct pci_device_id early_486_chipsets[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82424) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_496) },
 	{ },
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
index bd898f5b4da5..e74dd1f86bba 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -488,6 +488,12 @@ struct fec_enet_priv_rx_q {
 	struct  sk_buff *rx_skbuff[RX_RING_SIZE];
 };
 
+struct fec_stop_mode_gpr {
+	struct regmap *gpr;
+	u8 reg;
+	u8 bit;
+};
+
 /* The FEC buffer descriptors track the ring buffers.  The rx_bd_base and
  * tx_bd_base always point to the base of the buffer descriptors.  The
  * cur_rx and cur_tx point to the currently available buffer.
@@ -562,6 +568,7 @@ struct fec_enet_private {
 	int hwts_tx_en;
 	struct delayed_work time_keep;
 	struct regulator *reg_phy;
+	struct fec_stop_mode_gpr stop_gpr;
 
 	unsigned int tx_align;
 	unsigned int rx_align;
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index c1c267b61647..dc6f8763a5d4 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -62,6 +62,8 @@
 #include <linux/if_vlan.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/prefetch.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
 #include <soc/imx/cpuidle.h>
 
 #include <asm/cacheflush.h>
@@ -84,6 +86,56 @@ static void fec_enet_itr_coal_init(struct net_device *ndev);
 #define FEC_ENET_OPD_V	0xFFF0
 #define FEC_MDIO_PM_TIMEOUT  100 /* ms */
 
+struct fec_devinfo {
+	u32 quirks;
+	u8 stop_gpr_reg;
+	u8 stop_gpr_bit;
+};
+
+static const struct fec_devinfo fec_imx25_info = {
+	.quirks = FEC_QUIRK_USE_GASKET | FEC_QUIRK_MIB_CLEAR |
+		  FEC_QUIRK_HAS_FRREG,
+};
+
+static const struct fec_devinfo fec_imx27_info = {
+	.quirks = FEC_QUIRK_MIB_CLEAR | FEC_QUIRK_HAS_FRREG,
+};
+
+static const struct fec_devinfo fec_imx28_info = {
+	.quirks = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME |
+		  FEC_QUIRK_SINGLE_MDIO | FEC_QUIRK_HAS_RACC |
+		  FEC_QUIRK_HAS_FRREG,
+};
+
+static const struct fec_devinfo fec_imx6q_info = {
+	.quirks = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT |
+		  FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
+		  FEC_QUIRK_HAS_VLAN | FEC_QUIRK_ERR006358 |
+		  FEC_QUIRK_HAS_RACC,
+	.stop_gpr_reg = 0x34,
+	.stop_gpr_bit = 27,
+};
+
+static const struct fec_devinfo fec_mvf600_info = {
+	.quirks = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_RACC,
+};
+
+static const struct fec_devinfo fec_imx6x_info = {
+	.quirks = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT |
+		  FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
+		  FEC_QUIRK_HAS_VLAN | FEC_QUIRK_HAS_AVB |
+		  FEC_QUIRK_ERR007885 | FEC_QUIRK_BUG_CAPTURE |
+		  FEC_QUIRK_HAS_RACC | FEC_QUIRK_HAS_COALESCE,
+};
+
+static const struct fec_devinfo fec_imx6ul_info = {
+	.quirks = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT |
+		  FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
+		  FEC_QUIRK_HAS_VLAN | FEC_QUIRK_ERR007885 |
+		  FEC_QUIRK_BUG_CAPTURE | FEC_QUIRK_HAS_RACC |
+		  FEC_QUIRK_HAS_COALESCE,
+};
+
 static struct platform_device_id fec_devtype[] = {
 	{
 		/* keep it for coldfire */
@@ -91,39 +143,25 @@ static struct platform_device_id fec_devtype[] = {
 		.driver_data = 0,
 	}, {
 		.name = "imx25-fec",
-		.driver_data = FEC_QUIRK_USE_GASKET | FEC_QUIRK_MIB_CLEAR |
-			       FEC_QUIRK_HAS_FRREG,
+		.driver_data = (kernel_ulong_t)&fec_imx25_info,
 	}, {
 		.name = "imx27-fec",
-		.driver_data = FEC_QUIRK_MIB_CLEAR | FEC_QUIRK_HAS_FRREG,
+		.driver_data = (kernel_ulong_t)&fec_imx27_info,
 	}, {
 		.name = "imx28-fec",
-		.driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME |
-				FEC_QUIRK_SINGLE_MDIO | FEC_QUIRK_HAS_RACC |
-				FEC_QUIRK_HAS_FRREG,
+		.driver_data = (kernel_ulong_t)&fec_imx28_info,
 	}, {
 		.name = "imx6q-fec",
-		.driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT |
-				FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
-				FEC_QUIRK_HAS_VLAN | FEC_QUIRK_ERR006358 |
-				FEC_QUIRK_HAS_RACC,
+		.driver_data = (kernel_ulong_t)&fec_imx6q_info,
 	}, {
 		.name = "mvf600-fec",
-		.driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_RACC,
+		.driver_data = (kernel_ulong_t)&fec_mvf600_info,
 	}, {
 		.name = "imx6sx-fec",
-		.driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT |
-				FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
-				FEC_QUIRK_HAS_VLAN | FEC_QUIRK_HAS_AVB |
-				FEC_QUIRK_ERR007885 | FEC_QUIRK_BUG_CAPTURE |
-				FEC_QUIRK_HAS_RACC | FEC_QUIRK_HAS_COALESCE,
+		.driver_data = (kernel_ulong_t)&fec_imx6x_info,
 	}, {
 		.name = "imx6ul-fec",
-		.driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT |
-				FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
-				FEC_QUIRK_HAS_VLAN | FEC_QUIRK_ERR007885 |
-				FEC_QUIRK_BUG_CAPTURE | FEC_QUIRK_HAS_RACC |
-				FEC_QUIRK_HAS_COALESCE,
+		.driver_data = (kernel_ulong_t)&fec_imx6ul_info,
 	}, {
 		/* sentinel */
 	}
@@ -1092,11 +1130,28 @@ fec_restart(struct net_device *ndev)
 
 }
 
+static void fec_enet_stop_mode(struct fec_enet_private *fep, bool enabled)
+{
+	struct fec_platform_data *pdata = fep->pdev->dev.platform_data;
+	struct fec_stop_mode_gpr *stop_gpr = &fep->stop_gpr;
+
+	if (stop_gpr->gpr) {
+		if (enabled)
+			regmap_update_bits(stop_gpr->gpr, stop_gpr->reg,
+					   BIT(stop_gpr->bit),
+					   BIT(stop_gpr->bit));
+		else
+			regmap_update_bits(stop_gpr->gpr, stop_gpr->reg,
+					   BIT(stop_gpr->bit), 0);
+	} else if (pdata && pdata->sleep_mode_enable) {
+		pdata->sleep_mode_enable(enabled);
+	}
+}
+
 static void
 fec_stop(struct net_device *ndev)
 {
 	struct fec_enet_private *fep = netdev_priv(ndev);
-	struct fec_platform_data *pdata = fep->pdev->dev.platform_data;
 	u32 rmii_mode = readl(fep->hwp + FEC_R_CNTRL) & (1 << 8);
 	u32 val;
 
@@ -1125,9 +1180,7 @@ fec_stop(struct net_device *ndev)
 		val = readl(fep->hwp + FEC_ECNTRL);
 		val |= (FEC_ECR_MAGICEN | FEC_ECR_SLEEP);
 		writel(val, fep->hwp + FEC_ECNTRL);
-
-		if (pdata && pdata->sleep_mode_enable)
-			pdata->sleep_mode_enable(true);
+		fec_enet_stop_mode(fep, true);
 	}
 	writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
 
@@ -3398,6 +3451,37 @@ static int fec_enet_get_irq_cnt(struct platform_device *pdev)
 	return irq_cnt;
 }
 
+static int fec_enet_init_stop_mode(struct fec_enet_private *fep,
+				   struct fec_devinfo *dev_info,
+				   struct device_node *np)
+{
+	struct device_node *gpr_np;
+	int ret = 0;
+
+	if (!dev_info)
+		return 0;
+
+	gpr_np = of_parse_phandle(np, "gpr", 0);
+	if (!gpr_np)
+		return 0;
+
+	fep->stop_gpr.gpr = syscon_node_to_regmap(gpr_np);
+	if (IS_ERR(fep->stop_gpr.gpr)) {
+		dev_err(&fep->pdev->dev, "could not find gpr regmap\n");
+		ret = PTR_ERR(fep->stop_gpr.gpr);
+		fep->stop_gpr.gpr = NULL;
+		goto out;
+	}
+
+	fep->stop_gpr.reg = dev_info->stop_gpr_reg;
+	fep->stop_gpr.bit = dev_info->stop_gpr_bit;
+
+out:
+	of_node_put(gpr_np);
+
+	return ret;
+}
+
 static int
 fec_probe(struct platform_device *pdev)
 {
@@ -3413,6 +3497,7 @@ fec_probe(struct platform_device *pdev)
 	int num_rx_qs;
 	char irq_name[8];
 	int irq_cnt;
+	struct fec_devinfo *dev_info;
 
 	fec_enet_get_queue_num(pdev, &num_tx_qs, &num_rx_qs);
 
@@ -3430,7 +3515,9 @@ fec_probe(struct platform_device *pdev)
 	of_id = of_match_device(fec_dt_ids, &pdev->dev);
 	if (of_id)
 		pdev->id_entry = of_id->data;
-	fep->quirks = pdev->id_entry->driver_data;
+	dev_info = (struct fec_devinfo *)pdev->id_entry->driver_data;
+	if (dev_info)
+		fep->quirks = dev_info->quirks;
 
 	fep->netdev = ndev;
 	fep->num_rx_queues = num_rx_qs;
@@ -3464,6 +3551,10 @@ fec_probe(struct platform_device *pdev)
 	if (of_get_property(np, "fsl,magic-packet", NULL))
 		fep->wol_flag |= FEC_WOL_HAS_MAGIC_PACKET;
 
+	ret = fec_enet_init_stop_mode(fep, dev_info, np);
+	if (ret)
+		goto failed_stop_mode;
+
 	phy_node = of_parse_phandle(np, "phy-handle", 0);
 	if (!phy_node && of_phy_is_fixed_link(np)) {
 		ret = of_phy_register_fixed_link(np);
@@ -3632,6 +3723,7 @@ fec_probe(struct platform_device *pdev)
 	if (of_phy_is_fixed_link(np))
 		of_phy_deregister_fixed_link(np);
 	of_node_put(phy_node);
+failed_stop_mode:
 failed_phy:
 	dev_id--;
 failed_ioremap:
@@ -3709,7 +3801,6 @@ static int __maybe_unused fec_resume(struct device *dev)
 {
 	struct net_device *ndev = dev_get_drvdata(dev);
 	struct fec_enet_private *fep = netdev_priv(ndev);
-	struct fec_platform_data *pdata = fep->pdev->dev.platform_data;
 	int ret;
 	int val;
 
@@ -3727,8 +3818,8 @@ static int __maybe_unused fec_resume(struct device *dev)
 			goto failed_clk;
 		}
 		if (fep->wol_flag & FEC_WOL_FLAG_ENABLE) {
-			if (pdata && pdata->sleep_mode_enable)
-				pdata->sleep_mode_enable(false);
+			fec_enet_stop_mode(fep, false);
+
 			val = readl(fep->hwp + FEC_ECNTRL);
 			val &= ~(FEC_ECR_MAGICEN | FEC_ECR_SLEEP);
 			writel(val, fep->hwp + FEC_ECNTRL);
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index 5be61f73b6ab..51889770958d 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -5383,7 +5383,7 @@ static int __init mvneta_driver_init(void)
 {
 	int ret;
 
-	ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN, "net/mvmeta:online",
+	ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN, "net/mvneta:online",
 				      mvneta_cpu_online,
 				      mvneta_cpu_down_prepare);
 	if (ret < 0)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 8d28f90acfe7..09047109d0da 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -65,6 +65,17 @@ u32 mtk_r32(struct mtk_eth *eth, unsigned reg)
 	return __raw_readl(eth->base + reg);
 }
 
+u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned reg)
+{
+	u32 val;
+
+	val = mtk_r32(eth, reg);
+	val &= ~mask;
+	val |= set;
+	mtk_w32(eth, val, reg);
+	return reg;
+}
+
 static int mtk_mdio_busy_wait(struct mtk_eth *eth)
 {
 	unsigned long t_start = jiffies;
@@ -193,7 +204,7 @@ static void mtk_mac_config(struct phylink_config *config, unsigned int mode,
 	struct mtk_mac *mac = container_of(config, struct mtk_mac,
 					   phylink_config);
 	struct mtk_eth *eth = mac->hw;
-	u32 mcr_cur, mcr_new, sid;
+	u32 mcr_cur, mcr_new, sid, i;
 	int val, ge_mode, err;
 
 	/* MT76x8 has no hardware settings between for the MAC */
@@ -255,6 +266,17 @@ static void mtk_mac_config(struct phylink_config *config, unsigned int mode,
 				    PHY_INTERFACE_MODE_TRGMII)
 					mtk_gmac0_rgmii_adjust(mac->hw,
 							       state->speed);
+
+				/* mt7623_pad_clk_setup */
+				for (i = 0 ; i < NUM_TRGMII_CTRL; i++)
+					mtk_w32(mac->hw,
+						TD_DM_DRVP(8) | TD_DM_DRVN(8),
+						TRGMII_TD_ODT(i));
+
+				/* Assert/release MT7623 RXC reset */
+				mtk_m32(mac->hw, 0, RXC_RST | RXC_DQSISEL,
+					TRGMII_RCK_CTRL);
+				mtk_m32(mac->hw, RXC_RST, 0, TRGMII_RCK_CTRL);
 			}
 		}
 
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index 85830fe14a1b..454cfcd465fd 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -352,10 +352,13 @@
 #define DQSI0(x)		((x << 0) & GENMASK(6, 0))
 #define DQSI1(x)		((x << 8) & GENMASK(14, 8))
 #define RXCTL_DMWTLAT(x)	((x << 16) & GENMASK(18, 16))
+#define RXC_RST			BIT(31)
 #define RXC_DQSISEL		BIT(30)
 #define RCK_CTRL_RGMII_1000	(RXC_DQSISEL | RXCTL_DMWTLAT(2) | DQSI1(16))
 #define RCK_CTRL_RGMII_10_100	RXCTL_DMWTLAT(2)
 
+#define NUM_TRGMII_CTRL		5
+
 /* TRGMII RXC control register */
 #define TRGMII_TCK_CTRL		0x10340
 #define TXCTL_DMWTLAT(x)	((x << 16) & GENMASK(18, 16))
@@ -363,6 +366,11 @@
 #define TCK_CTRL_RGMII_1000	TXCTL_DMWTLAT(2)
 #define TCK_CTRL_RGMII_10_100	(TXC_INV | TXCTL_DMWTLAT(2))
 
+/* TRGMII TX Drive Strength */
+#define TRGMII_TD_ODT(i)	(0x10354 + 8 * (i))
+#define  TD_DM_DRVP(x)		((x) & 0xf)
+#define  TD_DM_DRVN(x)		(((x) & 0xf) << 4)
+
 /* TRGMII Interface mode register */
 #define INTF_MODE		0x10390
 #define TRGMII_INTF_DIS		BIT(0)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
index bdeb291f6b67..e94f0c4d74a7 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
@@ -23,7 +23,10 @@ static int mlx5_devlink_flash_update(struct devlink *devlink,
 	if (err)
 		return err;
 
-	return mlx5_firmware_flash(dev, fw, extack);
+	err = mlx5_firmware_flash(dev, fw, extack);
+	release_firmware(fw);
+
+	return err;
 }
 
 static u8 mlx5_fw_ver_major(u32 version)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c
index ad3e3a65d403..16416eaac39e 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c
@@ -67,11 +67,9 @@ struct mlx5_ct_ft {
 	struct nf_flowtable *nf_ft;
 	struct mlx5_tc_ct_priv *ct_priv;
 	struct rhashtable ct_entries_ht;
-	struct list_head ct_entries_list;
 };
 
 struct mlx5_ct_entry {
-	struct list_head list;
 	u16 zone;
 	struct rhash_head node;
 	struct flow_rule *flow_rule;
@@ -617,8 +615,6 @@ mlx5_tc_ct_block_flow_offload_add(struct mlx5_ct_ft *ft,
 	if (err)
 		goto err_insert;
 
-	list_add(&entry->list, &ft->ct_entries_list);
-
 	return 0;
 
 err_insert:
@@ -646,7 +642,6 @@ mlx5_tc_ct_block_flow_offload_del(struct mlx5_ct_ft *ft,
 	WARN_ON(rhashtable_remove_fast(&ft->ct_entries_ht,
 				       &entry->node,
 				       cts_ht_params));
-	list_del(&entry->list);
 	kfree(entry);
 
 	return 0;
@@ -818,7 +813,6 @@ mlx5_tc_ct_add_ft_cb(struct mlx5_tc_ct_priv *ct_priv, u16 zone,
 	ft->zone = zone;
 	ft->nf_ft = nf_ft;
 	ft->ct_priv = ct_priv;
-	INIT_LIST_HEAD(&ft->ct_entries_list);
 	refcount_set(&ft->refcount, 1);
 
 	err = rhashtable_init(&ft->ct_entries_ht, &cts_ht_params);
@@ -847,12 +841,12 @@ mlx5_tc_ct_add_ft_cb(struct mlx5_tc_ct_priv *ct_priv, u16 zone,
 }
 
 static void
-mlx5_tc_ct_flush_ft(struct mlx5_tc_ct_priv *ct_priv, struct mlx5_ct_ft *ft)
+mlx5_tc_ct_flush_ft_entry(void *ptr, void *arg)
 {
-	struct mlx5_ct_entry *entry;
+	struct mlx5_tc_ct_priv *ct_priv = arg;
+	struct mlx5_ct_entry *entry = ptr;
 
-	list_for_each_entry(entry, &ft->ct_entries_list, list)
-		mlx5_tc_ct_entry_del_rules(ft->ct_priv, entry);
+	mlx5_tc_ct_entry_del_rules(ct_priv, entry);
 }
 
 static void
@@ -863,9 +857,10 @@ mlx5_tc_ct_del_ft_cb(struct mlx5_tc_ct_priv *ct_priv, struct mlx5_ct_ft *ft)
 
 	nf_flow_table_offload_del_cb(ft->nf_ft,
 				     mlx5_tc_ct_block_flow_offload, ft);
-	mlx5_tc_ct_flush_ft(ct_priv, ft);
 	rhashtable_remove_fast(&ct_priv->zone_ht, &ft->node, zone_params);
-	rhashtable_destroy(&ft->ct_entries_ht);
+	rhashtable_free_and_destroy(&ft->ct_entries_ht,
+				    mlx5_tc_ct_flush_ft_entry,
+				    ct_priv);
 	kfree(ft);
 }
 
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index dd7f338425eb..f02150a97ac8 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -5526,8 +5526,8 @@ static void mlx5e_remove(struct mlx5_core_dev *mdev, void *vpriv)
 #ifdef CONFIG_MLX5_CORE_EN_DCB
 	mlx5e_dcbnl_delete_app(priv);
 #endif
-	mlx5e_devlink_port_unregister(priv);
 	unregister_netdev(priv->netdev);
+	mlx5e_devlink_port_unregister(priv);
 	mlx5e_detach(mdev, vpriv);
 	mlx5e_destroy_netdev(priv);
 }
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
index 2a0243e4af75..55457f268495 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
@@ -2050,29 +2050,30 @@ static int register_devlink_port(struct mlx5_core_dev *dev,
 	struct mlx5_eswitch_rep *rep = rpriv->rep;
 	struct netdev_phys_item_id ppid = {};
 	unsigned int dl_port_index = 0;
+	u16 pfnum;
 
 	if (!is_devlink_port_supported(dev, rpriv))
 		return 0;
 
 	mlx5e_rep_get_port_parent_id(rpriv->netdev, &ppid);
+	pfnum = PCI_FUNC(dev->pdev->devfn);
 
 	if (rep->vport == MLX5_VPORT_UPLINK) {
 		devlink_port_attrs_set(&rpriv->dl_port,
 				       DEVLINK_PORT_FLAVOUR_PHYSICAL,
-				       PCI_FUNC(dev->pdev->devfn), false, 0,
+				       pfnum, false, 0,
 				       &ppid.id[0], ppid.id_len);
 		dl_port_index = vport_to_devlink_port_index(dev, rep->vport);
 	} else if (rep->vport == MLX5_VPORT_PF) {
 		devlink_port_attrs_pci_pf_set(&rpriv->dl_port,
 					      &ppid.id[0], ppid.id_len,
-					      dev->pdev->devfn);
+					      pfnum);
 		dl_port_index = rep->vport;
 	} else if (mlx5_eswitch_is_vf_vport(dev->priv.eswitch,
 					    rpriv->rep->vport)) {
 		devlink_port_attrs_pci_vf_set(&rpriv->dl_port,
 					      &ppid.id[0], ppid.id_len,
-					      dev->pdev->devfn,
-					      rep->vport - 1);
+					      pfnum, rep->vport - 1);
 		dl_port_index = vport_to_devlink_port_index(dev, rep->vport);
 	}
 
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
index 438128dde187..a574c588269a 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
@@ -1343,7 +1343,8 @@ mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
 	if (err)
 		return err;
 
-	if (attr->action & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR) {
+	if (attr->action & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR &&
+	    !(attr->ct_attr.ct_action & TCA_CT_ACT_CLEAR)) {
 		err = mlx5e_attach_mod_hdr(priv, flow, parse_attr);
 		dealloc_mod_hdr_actions(&parse_attr->mod_hdr_acts);
 		if (err)
@@ -3558,12 +3559,13 @@ static int add_vlan_pop_action(struct mlx5e_priv *priv,
 			       struct mlx5_esw_flow_attr *attr,
 			       u32 *action)
 {
-	int nest_level = attr->parse_attr->filter_dev->lower_level;
 	struct flow_action_entry vlan_act = {
 		.id = FLOW_ACTION_VLAN_POP,
 	};
-	int err = 0;
+	int nest_level, err = 0;
 
+	nest_level = attr->parse_attr->filter_dev->lower_level -
+						priv->netdev->lower_level;
 	while (nest_level--) {
 		err = parse_tc_vlan_action(priv, &vlan_act, attr, action);
 		if (err)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
index 39f42f985fbd..c1848b57f61c 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
@@ -403,7 +403,6 @@ enum {
 	MLX5_ESW_ATTR_FLAG_VLAN_HANDLED  = BIT(0),
 	MLX5_ESW_ATTR_FLAG_SLOW_PATH     = BIT(1),
 	MLX5_ESW_ATTR_FLAG_NO_IN_PORT    = BIT(2),
-	MLX5_ESW_ATTR_FLAG_HAIRPIN	 = BIT(3),
 };
 
 struct mlx5_esw_flow_attr {
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
index f171eb2234b0..b2e38e0cde97 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
@@ -300,7 +300,6 @@ mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw,
 	bool split = !!(attr->split_count);
 	struct mlx5_flow_handle *rule;
 	struct mlx5_flow_table *fdb;
-	bool hairpin = false;
 	int j, i = 0;
 
 	if (esw->mode != MLX5_ESWITCH_OFFLOADS)
@@ -398,21 +397,16 @@ mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw,
 		goto err_esw_get;
 	}
 
-	if (mlx5_eswitch_termtbl_required(esw, attr, &flow_act, spec)) {
+	if (mlx5_eswitch_termtbl_required(esw, attr, &flow_act, spec))
 		rule = mlx5_eswitch_add_termtbl_rule(esw, fdb, spec, attr,
 						     &flow_act, dest, i);
-		hairpin = true;
-	} else {
+	else
 		rule = mlx5_add_flow_rules(fdb, spec, &flow_act, dest, i);
-	}
 	if (IS_ERR(rule))
 		goto err_add_rule;
 	else
 		atomic64_inc(&esw->offloads.num_flows);
 
-	if (hairpin)
-		attr->flags |= MLX5_ESW_ATTR_FLAG_HAIRPIN;
-
 	return rule;
 
 err_add_rule:
@@ -501,7 +495,7 @@ __mlx5_eswitch_del_rule(struct mlx5_eswitch *esw,
 
 	mlx5_del_flow_rules(rule);
 
-	if (attr->flags & MLX5_ESW_ATTR_FLAG_HAIRPIN) {
+	if (!(attr->flags & MLX5_ESW_ATTR_FLAG_SLOW_PATH)) {
 		/* unref the term table */
 		for (i = 0; i < MLX5_MAX_FLOW_FWD_VPORTS; i++) {
 			if (attr->dests[i].termtbl)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/health.c b/drivers/net/ethernet/mellanox/mlx5/core/health.c
index fa1665caac46..f99e1752d4e5 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/health.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/health.c
@@ -243,7 +243,7 @@ void mlx5_error_sw_reset(struct mlx5_core_dev *dev)
 		if (mlx5_get_nic_state(dev) == MLX5_NIC_IFC_DISABLED)
 			break;
 
-		cond_resched();
+		msleep(20);
 	} while (!time_after(jiffies, end));
 
 	if (mlx5_get_nic_state(dev) != MLX5_NIC_IFC_DISABLED) {
diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c
index b4731df186f4..a8c48a4a708f 100644
--- a/drivers/net/ethernet/mscc/ocelot.c
+++ b/drivers/net/ethernet/mscc/ocelot.c
@@ -183,44 +183,47 @@ static void ocelot_vlan_mode(struct ocelot *ocelot, int port,
 	ocelot_write(ocelot, val, ANA_VLANMASK);
 }
 
-void ocelot_port_vlan_filtering(struct ocelot *ocelot, int port,
-				bool vlan_aware)
+static int ocelot_port_set_native_vlan(struct ocelot *ocelot, int port,
+				       u16 vid)
 {
 	struct ocelot_port *ocelot_port = ocelot->ports[port];
-	u32 val;
+	u32 val = 0;
 
-	if (vlan_aware)
-		val = ANA_PORT_VLAN_CFG_VLAN_AWARE_ENA |
-		      ANA_PORT_VLAN_CFG_VLAN_POP_CNT(1);
-	else
-		val = 0;
-	ocelot_rmw_gix(ocelot, val,
-		       ANA_PORT_VLAN_CFG_VLAN_AWARE_ENA |
-		       ANA_PORT_VLAN_CFG_VLAN_POP_CNT_M,
-		       ANA_PORT_VLAN_CFG, port);
+	if (ocelot_port->vid != vid) {
+		/* Always permit deleting the native VLAN (vid = 0) */
+		if (ocelot_port->vid && vid) {
+			dev_err(ocelot->dev,
+				"Port already has a native VLAN: %d\n",
+				ocelot_port->vid);
+			return -EBUSY;
+		}
+		ocelot_port->vid = vid;
+	}
+
+	ocelot_rmw_gix(ocelot, REW_PORT_VLAN_CFG_PORT_VID(vid),
+		       REW_PORT_VLAN_CFG_PORT_VID_M,
+		       REW_PORT_VLAN_CFG, port);
 
-	if (vlan_aware && !ocelot_port->vid)
+	if (ocelot_port->vlan_aware && !ocelot_port->vid)
 		/* If port is vlan-aware and tagged, drop untagged and priority
 		 * tagged frames.
 		 */
 		val = ANA_PORT_DROP_CFG_DROP_UNTAGGED_ENA |
 		      ANA_PORT_DROP_CFG_DROP_PRIO_S_TAGGED_ENA |
 		      ANA_PORT_DROP_CFG_DROP_PRIO_C_TAGGED_ENA;
-	else
-		val = 0;
 	ocelot_rmw_gix(ocelot, val,
 		       ANA_PORT_DROP_CFG_DROP_UNTAGGED_ENA |
 		       ANA_PORT_DROP_CFG_DROP_PRIO_S_TAGGED_ENA |
 		       ANA_PORT_DROP_CFG_DROP_PRIO_C_TAGGED_ENA,
 		       ANA_PORT_DROP_CFG, port);
 
-	if (vlan_aware) {
+	if (ocelot_port->vlan_aware) {
 		if (ocelot_port->vid)
 			/* Tag all frames except when VID == DEFAULT_VLAN */
-			val |= REW_TAG_CFG_TAG_CFG(1);
+			val = REW_TAG_CFG_TAG_CFG(1);
 		else
 			/* Tag all frames */
-			val |= REW_TAG_CFG_TAG_CFG(3);
+			val = REW_TAG_CFG_TAG_CFG(3);
 	} else {
 		/* Port tagging disabled. */
 		val = REW_TAG_CFG_TAG_CFG(0);
@@ -228,31 +231,31 @@ void ocelot_port_vlan_filtering(struct ocelot *ocelot, int port,
 	ocelot_rmw_gix(ocelot, val,
 		       REW_TAG_CFG_TAG_CFG_M,
 		       REW_TAG_CFG, port);
+
+	return 0;
 }
-EXPORT_SYMBOL(ocelot_port_vlan_filtering);
 
-static int ocelot_port_set_native_vlan(struct ocelot *ocelot, int port,
-				       u16 vid)
+void ocelot_port_vlan_filtering(struct ocelot *ocelot, int port,
+				bool vlan_aware)
 {
 	struct ocelot_port *ocelot_port = ocelot->ports[port];
+	u32 val;
 
-	if (ocelot_port->vid != vid) {
-		/* Always permit deleting the native VLAN (vid = 0) */
-		if (ocelot_port->vid && vid) {
-			dev_err(ocelot->dev,
-				"Port already has a native VLAN: %d\n",
-				ocelot_port->vid);
-			return -EBUSY;
-		}
-		ocelot_port->vid = vid;
-	}
+	ocelot_port->vlan_aware = vlan_aware;
 
-	ocelot_rmw_gix(ocelot, REW_PORT_VLAN_CFG_PORT_VID(vid),
-		       REW_PORT_VLAN_CFG_PORT_VID_M,
-		       REW_PORT_VLAN_CFG, port);
+	if (vlan_aware)
+		val = ANA_PORT_VLAN_CFG_VLAN_AWARE_ENA |
+		      ANA_PORT_VLAN_CFG_VLAN_POP_CNT(1);
+	else
+		val = 0;
+	ocelot_rmw_gix(ocelot, val,
+		       ANA_PORT_VLAN_CFG_VLAN_AWARE_ENA |
+		       ANA_PORT_VLAN_CFG_VLAN_POP_CNT_M,
+		       ANA_PORT_VLAN_CFG, port);
 
-	return 0;
+	ocelot_port_set_native_vlan(ocelot, port, ocelot_port->vid);
 }
+EXPORT_SYMBOL(ocelot_port_vlan_filtering);
 
 /* Default vlan to clasify for untagged frames (may be zero) */
 static void ocelot_port_set_pvid(struct ocelot *ocelot, int port, u16 pvid)
@@ -873,12 +876,12 @@ static void ocelot_get_stats64(struct net_device *dev,
 }
 
 int ocelot_fdb_add(struct ocelot *ocelot, int port,
-		   const unsigned char *addr, u16 vid, bool vlan_aware)
+		   const unsigned char *addr, u16 vid)
 {
 	struct ocelot_port *ocelot_port = ocelot->ports[port];
 
 	if (!vid) {
-		if (!vlan_aware)
+		if (!ocelot_port->vlan_aware)
 			/* If the bridge is not VLAN aware and no VID was
 			 * provided, set it to pvid to ensure the MAC entry
 			 * matches incoming untagged packets
@@ -905,7 +908,7 @@ static int ocelot_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
 	struct ocelot *ocelot = priv->port.ocelot;
 	int port = priv->chip_port;
 
-	return ocelot_fdb_add(ocelot, port, addr, vid, priv->vlan_aware);
+	return ocelot_fdb_add(ocelot, port, addr, vid);
 }
 
 int ocelot_fdb_del(struct ocelot *ocelot, int port,
@@ -1496,8 +1499,8 @@ static int ocelot_port_attr_set(struct net_device *dev,
 		ocelot_port_attr_ageing_set(ocelot, port, attr->u.ageing_time);
 		break;
 	case SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING:
-		priv->vlan_aware = attr->u.vlan_filtering;
-		ocelot_port_vlan_filtering(ocelot, port, priv->vlan_aware);
+		ocelot_port_vlan_filtering(ocelot, port,
+					   attr->u.vlan_filtering);
 		break;
 	case SWITCHDEV_ATTR_ID_BRIDGE_MC_DISABLED:
 		ocelot_port_attr_mc_set(ocelot, port, !attr->u.mc_disabled);
@@ -1868,7 +1871,6 @@ static int ocelot_netdevice_port_event(struct net_device *dev,
 			} else {
 				err = ocelot_port_bridge_leave(ocelot, port,
 							       info->upper_dev);
-				priv->vlan_aware = false;
 			}
 		}
 		if (netif_is_lag_master(info->upper_dev)) {
diff --git a/drivers/net/ethernet/mscc/ocelot.h b/drivers/net/ethernet/mscc/ocelot.h
index e34ef8380eb3..641af929497f 100644
--- a/drivers/net/ethernet/mscc/ocelot.h
+++ b/drivers/net/ethernet/mscc/ocelot.h
@@ -56,8 +56,6 @@ struct ocelot_port_private {
 	struct phy_device *phy;
 	u8 chip_port;
 
-	u8 vlan_aware;
-
 	struct phy *serdes;
 
 	struct ocelot_port_tc tc;
diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c
index 0ec6b8e8b549..67e62603fe3b 100644
--- a/drivers/net/ethernet/neterion/s2io.c
+++ b/drivers/net/ethernet/neterion/s2io.c
@@ -5155,7 +5155,7 @@ static int do_s2io_delete_unicast_mc(struct s2io_nic *sp, u64 addr)
 /* read mac entries from CAM */
 static u64 do_s2io_read_unicast_mc(struct s2io_nic *sp, int offset)
 {
-	u64 tmp64 = 0xffffffffffff0000ULL, val64;
+	u64 tmp64, val64;
 	struct XENA_dev_config __iomem *bar0 = sp->bar0;
 
 	/* read mac addr */
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index 4b8a76098ca3..5acf4f46c268 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -2127,6 +2127,8 @@ static void ionic_lif_handle_fw_up(struct ionic_lif *lif)
 	if (lif->registered)
 		ionic_lif_set_netdev_info(lif);
 
+	ionic_rx_filter_replay(lif);
+
 	if (netif_running(lif->netdev)) {
 		err = ionic_txrx_alloc(lif);
 		if (err)
@@ -2206,9 +2208,9 @@ static void ionic_lif_deinit(struct ionic_lif *lif)
 	if (!test_bit(IONIC_LIF_F_FW_RESET, lif->state)) {
 		cancel_work_sync(&lif->deferred.work);
 		cancel_work_sync(&lif->tx_timeout_work);
+		ionic_rx_filters_deinit(lif);
 	}
 
-	ionic_rx_filters_deinit(lif);
 	if (lif->netdev->features & NETIF_F_RXHASH)
 		ionic_lif_rss_deinit(lif);
 
@@ -2339,24 +2341,30 @@ static int ionic_station_set(struct ionic_lif *lif)
 	err = ionic_adminq_post_wait(lif, &ctx);
 	if (err)
 		return err;
-
+	netdev_dbg(lif->netdev, "found initial MAC addr %pM\n",
+		   ctx.comp.lif_getattr.mac);
 	if (is_zero_ether_addr(ctx.comp.lif_getattr.mac))
 		return 0;
 
-	memcpy(addr.sa_data, ctx.comp.lif_getattr.mac, netdev->addr_len);
-	addr.sa_family = AF_INET;
-	err = eth_prepare_mac_addr_change(netdev, &addr);
-	if (err) {
-		netdev_warn(lif->netdev, "ignoring bad MAC addr from NIC %pM - err %d\n",
-			    addr.sa_data, err);
-		return 0;
-	}
+	if (!ether_addr_equal(ctx.comp.lif_getattr.mac, netdev->dev_addr)) {
+		memcpy(addr.sa_data, ctx.comp.lif_getattr.mac, netdev->addr_len);
+		addr.sa_family = AF_INET;
+		err = eth_prepare_mac_addr_change(netdev, &addr);
+		if (err) {
+			netdev_warn(lif->netdev, "ignoring bad MAC addr from NIC %pM - err %d\n",
+				    addr.sa_data, err);
+			return 0;
+		}
 
-	netdev_dbg(lif->netdev, "deleting station MAC addr %pM\n",
-		   netdev->dev_addr);
-	ionic_lif_addr(lif, netdev->dev_addr, false);
+		if (!is_zero_ether_addr(netdev->dev_addr)) {
+			netdev_dbg(lif->netdev, "deleting station MAC addr %pM\n",
+				   netdev->dev_addr);
+			ionic_lif_addr(lif, netdev->dev_addr, false);
+		}
+
+		eth_commit_mac_addr_change(netdev, &addr);
+	}
 
-	eth_commit_mac_addr_change(netdev, &addr);
 	netdev_dbg(lif->netdev, "adding station MAC addr %pM\n",
 		   netdev->dev_addr);
 	ionic_lif_addr(lif, netdev->dev_addr, true);
@@ -2421,9 +2429,11 @@ static int ionic_lif_init(struct ionic_lif *lif)
 	if (err)
 		goto err_out_notifyq_deinit;
 
-	err = ionic_rx_filters_init(lif);
-	if (err)
-		goto err_out_notifyq_deinit;
+	if (!test_bit(IONIC_LIF_F_FW_RESET, lif->state)) {
+		err = ionic_rx_filters_init(lif);
+		if (err)
+			goto err_out_notifyq_deinit;
+	}
 
 	err = ionic_station_set(lif);
 	if (err)
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_rx_filter.c b/drivers/net/ethernet/pensando/ionic/ionic_rx_filter.c
index 7a093f148ee5..80eeb7696e01 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_rx_filter.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_rx_filter.c
@@ -2,6 +2,7 @@
 /* Copyright(c) 2017 - 2019 Pensando Systems, Inc */
 
 #include <linux/netdevice.h>
+#include <linux/dynamic_debug.h>
 #include <linux/etherdevice.h>
 
 #include "ionic.h"
@@ -17,17 +18,49 @@ void ionic_rx_filter_free(struct ionic_lif *lif, struct ionic_rx_filter *f)
 	devm_kfree(dev, f);
 }
 
-int ionic_rx_filter_del(struct ionic_lif *lif, struct ionic_rx_filter *f)
+void ionic_rx_filter_replay(struct ionic_lif *lif)
 {
-	struct ionic_admin_ctx ctx = {
-		.work = COMPLETION_INITIALIZER_ONSTACK(ctx.work),
-		.cmd.rx_filter_del = {
-			.opcode = IONIC_CMD_RX_FILTER_DEL,
-			.filter_id = cpu_to_le32(f->filter_id),
-		},
-	};
-
-	return ionic_adminq_post_wait(lif, &ctx);
+	struct ionic_rx_filter_add_cmd *ac;
+	struct ionic_admin_ctx ctx;
+	struct ionic_rx_filter *f;
+	struct hlist_head *head;
+	struct hlist_node *tmp;
+	unsigned int i;
+	int err;
+
+	ac = &ctx.cmd.rx_filter_add;
+
+	for (i = 0; i < IONIC_RX_FILTER_HLISTS; i++) {
+		head = &lif->rx_filters.by_id[i];
+		hlist_for_each_entry_safe(f, tmp, head, by_id) {
+			ctx.work = COMPLETION_INITIALIZER_ONSTACK(ctx.work);
+			memcpy(ac, &f->cmd, sizeof(f->cmd));
+			dev_dbg(&lif->netdev->dev, "replay filter command:\n");
+			dynamic_hex_dump("cmd ", DUMP_PREFIX_OFFSET, 16, 1,
+					 &ctx.cmd, sizeof(ctx.cmd), true);
+
+			err = ionic_adminq_post_wait(lif, &ctx);
+			if (err) {
+				switch (le16_to_cpu(ac->match)) {
+				case IONIC_RX_FILTER_MATCH_VLAN:
+					netdev_info(lif->netdev, "Replay failed - %d: vlan %d\n",
+						    err,
+						    le16_to_cpu(ac->vlan.vlan));
+					break;
+				case IONIC_RX_FILTER_MATCH_MAC:
+					netdev_info(lif->netdev, "Replay failed - %d: mac %pM\n",
+						    err, ac->mac.addr);
+					break;
+				case IONIC_RX_FILTER_MATCH_MAC_VLAN:
+					netdev_info(lif->netdev, "Replay failed - %d: vlan %d mac %pM\n",
+						    err,
+						    le16_to_cpu(ac->vlan.vlan),
+						    ac->mac.addr);
+					break;
+				}
+			}
+		}
+	}
 }
 
 int ionic_rx_filters_init(struct ionic_lif *lif)
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_rx_filter.h b/drivers/net/ethernet/pensando/ionic/ionic_rx_filter.h
index b6aec9c19918..cf8f4c0a961c 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_rx_filter.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_rx_filter.h
@@ -24,7 +24,7 @@ struct ionic_rx_filters {
 };
 
 void ionic_rx_filter_free(struct ionic_lif *lif, struct ionic_rx_filter *f);
-int ionic_rx_filter_del(struct ionic_lif *lif, struct ionic_rx_filter *f);
+void ionic_rx_filter_replay(struct ionic_lif *lif);
 int ionic_rx_filters_init(struct ionic_lif *lif);
 void ionic_rx_filters_deinit(struct ionic_lif *lif);
 int ionic_rx_filter_save(struct ionic_lif *lif, u32 flow_id, u16 rxq_index,
diff --git a/drivers/net/ethernet/smsc/Kconfig b/drivers/net/ethernet/smsc/Kconfig
index 9e1c3752b200..64ca1b36b91e 100644
--- a/drivers/net/ethernet/smsc/Kconfig
+++ b/drivers/net/ethernet/smsc/Kconfig
@@ -37,7 +37,6 @@ config SMC91X
 	tristate "SMC 91C9x/91C1xxx support"
 	select CRC32
 	select MII
-	depends on !OF || GPIOLIB
 	depends on ARM || ARM64 || ATARI_ETHERNAT || COLDFIRE || \
 		   MIPS || NIOS2 || SUPERH || XTENSA || H8300
 	---help---
diff --git a/drivers/net/ethernet/smsc/smc91x.c b/drivers/net/ethernet/smsc/smc91x.c
index 90410f9d3b1a..605dc17290ef 100644
--- a/drivers/net/ethernet/smsc/smc91x.c
+++ b/drivers/net/ethernet/smsc/smc91x.c
@@ -2190,6 +2190,7 @@ static const struct of_device_id smc91x_match[] = {
 };
 MODULE_DEVICE_TABLE(of, smc91x_match);
 
+#if defined(CONFIG_GPIOLIB)
 /**
  * of_try_set_control_gpio - configure a gpio if it exists
  */
@@ -2214,6 +2215,15 @@ static int try_toggle_control_gpio(struct device *dev,
 
 	return 0;
 }
+#else
+static int try_toggle_control_gpio(struct device *dev,
+				   struct gpio_desc **desc,
+				   const char *name, int index,
+				   int value, unsigned int nsdelay)
+{
+	return 0;
+}
+#endif
 #endif
 
 /*
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
index e0212d2fc2a1..fa32cd5b418e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
@@ -241,6 +241,8 @@ static int socfpga_set_phy_mode_common(int phymode, u32 *val)
 	switch (phymode) {
 	case PHY_INTERFACE_MODE_RGMII:
 	case PHY_INTERFACE_MODE_RGMII_ID:
+	case PHY_INTERFACE_MODE_RGMII_RXID:
+	case PHY_INTERFACE_MODE_RGMII_TXID:
 		*val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII;
 		break;
 	case PHY_INTERFACE_MODE_MII:
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
index 7d40760e9ba8..0e1ca2cba3c7 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
@@ -150,6 +150,8 @@ static int sun7i_gmac_probe(struct platform_device *pdev)
 	plat_dat->init = sun7i_gmac_init;
 	plat_dat->exit = sun7i_gmac_exit;
 	plat_dat->fix_mac_speed = sun7i_fix_speed;
+	plat_dat->tx_fifo_size = 4096;
+	plat_dat->rx_fifo_size = 16384;
 
 	ret = sun7i_gmac_init(pdev, plat_dat->bsp_priv);
 	if (ret)
diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
index f71c15c39492..2bf56733ba94 100644
--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
@@ -1372,7 +1372,7 @@ static int am65_cpsw_nuss_init_tx_chns(struct am65_cpsw_common *common)
 err:
 	i = devm_add_action(dev, am65_cpsw_nuss_free_tx_chns, common);
 	if (i) {
-		dev_err(dev, "failed to add free_tx_chns action %d", i);
+		dev_err(dev, "Failed to add free_tx_chns action %d\n", i);
 		return i;
 	}
 
@@ -1481,7 +1481,7 @@ static int am65_cpsw_nuss_init_rx_chns(struct am65_cpsw_common *common)
 err:
 	i = devm_add_action(dev, am65_cpsw_nuss_free_rx_chns, common);
 	if (i) {
-		dev_err(dev, "failed to add free_rx_chns action %d", i);
+		dev_err(dev, "Failed to add free_rx_chns action %d\n", i);
 		return i;
 	}
 
@@ -1691,7 +1691,7 @@ static int am65_cpsw_nuss_init_ndev_2g(struct am65_cpsw_common *common)
 	ret = devm_add_action_or_reset(dev, am65_cpsw_pcpu_stats_free,
 				       ndev_priv->stats);
 	if (ret) {
-		dev_err(dev, "failed to add percpu stat free action %d", ret);
+		dev_err(dev, "Failed to add percpu stat free action %d\n", ret);
 		return ret;
 	}
 
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index ca68aa1df801..41f5cf0bb997 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -636,9 +636,12 @@ void netvsc_device_remove(struct hv_device *device)
 
 	RCU_INIT_POINTER(net_device_ctx->nvdev, NULL);
 
-	/* And disassociate NAPI context from device */
-	for (i = 0; i < net_device->num_chn; i++)
+	/* Disable NAPI and disassociate its context from the device. */
+	for (i = 0; i < net_device->num_chn; i++) {
+		/* See also vmbus_reset_channel_cb(). */
+		napi_disable(&net_device->chan_table[i].napi);
 		netif_napi_del(&net_device->chan_table[i].napi);
+	}
 
 	/*
 	 * At this point, no one should be accessing net_device
diff --git a/drivers/net/ipa/ipa_modem.c b/drivers/net/ipa/ipa_modem.c
index 55c9329a4b1d..ed10818dd99f 100644
--- a/drivers/net/ipa/ipa_modem.c
+++ b/drivers/net/ipa/ipa_modem.c
@@ -297,14 +297,13 @@ static void ipa_modem_crashed(struct ipa *ipa)
 
 	ret = ipa_endpoint_modem_exception_reset_all(ipa);
 	if (ret)
-		dev_err(dev, "error %d resetting exception endpoint",
-			ret);
+		dev_err(dev, "error %d resetting exception endpoint\n", ret);
 
 	ipa_endpoint_modem_pause_all(ipa, false);
 
 	ret = ipa_modem_stop(ipa);
 	if (ret)
-		dev_err(dev, "error %d stopping modem", ret);
+		dev_err(dev, "error %d stopping modem\n", ret);
 
 	/* Now prepare for the next modem boot */
 	ret = ipa_mem_zero_modem(ipa);
diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
index 0d580d81d910..a183250ff66a 100644
--- a/drivers/net/macsec.c
+++ b/drivers/net/macsec.c
@@ -3809,7 +3809,7 @@ static int macsec_changelink(struct net_device *dev, struct nlattr *tb[],
 			     struct netlink_ext_ack *extack)
 {
 	struct macsec_dev *macsec = macsec_priv(dev);
-	struct macsec_tx_sa tx_sc;
+	struct macsec_tx_sc tx_sc;
 	struct macsec_secy secy;
 	int ret;
 
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index 4714ca0e0d4b..7fc8e10c5f33 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -1263,6 +1263,30 @@ static int marvell_read_status_page_an(struct phy_device *phydev,
 	int lpa;
 	int err;
 
+	if (!(status & MII_M1011_PHY_STATUS_RESOLVED)) {
+		phydev->link = 0;
+		return 0;
+	}
+
+	if (status & MII_M1011_PHY_STATUS_FULLDUPLEX)
+		phydev->duplex = DUPLEX_FULL;
+	else
+		phydev->duplex = DUPLEX_HALF;
+
+	switch (status & MII_M1011_PHY_STATUS_SPD_MASK) {
+	case MII_M1011_PHY_STATUS_1000:
+		phydev->speed = SPEED_1000;
+		break;
+
+	case MII_M1011_PHY_STATUS_100:
+		phydev->speed = SPEED_100;
+		break;
+
+	default:
+		phydev->speed = SPEED_10;
+		break;
+	}
+
 	if (!fiber) {
 		err = genphy_read_lpa(phydev);
 		if (err < 0)
@@ -1291,28 +1315,6 @@ static int marvell_read_status_page_an(struct phy_device *phydev,
 		}
 	}
 
-	if (!(status & MII_M1011_PHY_STATUS_RESOLVED))
-		return 0;
-
-	if (status & MII_M1011_PHY_STATUS_FULLDUPLEX)
-		phydev->duplex = DUPLEX_FULL;
-	else
-		phydev->duplex = DUPLEX_HALF;
-
-	switch (status & MII_M1011_PHY_STATUS_SPD_MASK) {
-	case MII_M1011_PHY_STATUS_1000:
-		phydev->speed = SPEED_1000;
-		break;
-
-	case MII_M1011_PHY_STATUS_100:
-		phydev->speed = SPEED_100;
-		break;
-
-	default:
-		phydev->speed = SPEED_10;
-		break;
-	}
-
 	return 0;
 }
 
diff --git a/drivers/net/phy/marvell10g.c b/drivers/net/phy/marvell10g.c
index 7621badae64d..95e3f4644aeb 100644
--- a/drivers/net/phy/marvell10g.c
+++ b/drivers/net/phy/marvell10g.c
@@ -33,6 +33,8 @@
 #define MV_PHY_ALASKA_NBT_QUIRK_REV	(MARVELL_PHY_ID_88X3310 | 0xa)
 
 enum {
+	MV_PMA_FW_VER0		= 0xc011,
+	MV_PMA_FW_VER1		= 0xc012,
 	MV_PMA_BOOT		= 0xc050,
 	MV_PMA_BOOT_FATAL	= BIT(0),
 
@@ -73,7 +75,8 @@ enum {
 
 	/* Vendor2 MMD registers */
 	MV_V2_PORT_CTRL		= 0xf001,
-	MV_V2_PORT_CTRL_PWRDOWN = 0x0800,
+	MV_V2_PORT_CTRL_SWRST	= BIT(15),
+	MV_V2_PORT_CTRL_PWRDOWN = BIT(11),
 	MV_V2_TEMP_CTRL		= 0xf08a,
 	MV_V2_TEMP_CTRL_MASK	= 0xc000,
 	MV_V2_TEMP_CTRL_SAMPLE	= 0x0000,
@@ -83,6 +86,8 @@ enum {
 };
 
 struct mv3310_priv {
+	u32 firmware_ver;
+
 	struct device *hwmon_dev;
 	char *hwmon_name;
 };
@@ -235,8 +240,17 @@ static int mv3310_power_down(struct phy_device *phydev)
 
 static int mv3310_power_up(struct phy_device *phydev)
 {
-	return phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL,
-				  MV_V2_PORT_CTRL_PWRDOWN);
+	struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
+	int ret;
+
+	ret = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL,
+				 MV_V2_PORT_CTRL_PWRDOWN);
+
+	if (priv->firmware_ver < 0x00030000)
+		return ret;
+
+	return phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL,
+				MV_V2_PORT_CTRL_SWRST);
 }
 
 static int mv3310_reset(struct phy_device *phydev, u32 unit)
@@ -355,6 +369,22 @@ static int mv3310_probe(struct phy_device *phydev)
 
 	dev_set_drvdata(&phydev->mdio.dev, priv);
 
+	ret = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MV_PMA_FW_VER0);
+	if (ret < 0)
+		return ret;
+
+	priv->firmware_ver = ret << 16;
+
+	ret = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MV_PMA_FW_VER1);
+	if (ret < 0)
+		return ret;
+
+	priv->firmware_ver |= ret;
+
+	phydev_info(phydev, "Firmware version %u.%u.%u.%u\n",
+		    priv->firmware_ver >> 24, (priv->firmware_ver >> 16) & 255,
+		    (priv->firmware_ver >> 8) & 255, priv->firmware_ver & 255);
+
 	/* Powering down the port when not in use saves about 600mW */
 	ret = mv3310_power_down(phydev);
 	if (ret)
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 522760c8bca6..7a4eb3f2cb74 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -464,7 +464,7 @@ static struct class mdio_bus_class = {
 
 /**
  * mdio_find_bus - Given the name of a mdiobus, find the mii_bus.
- * @mdio_bus_np: Pointer to the mii_bus.
+ * @mdio_name: The name of a mdiobus.
  *
  * Returns a reference to the mii_bus, or NULL if none found.  The
  * embedded struct device will have its reference count incremented,
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 05d20343b816..3a4d83fa52dc 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -1204,7 +1204,7 @@ static struct phy_driver ksphy_driver[] = {
 	.driver_data	= &ksz9021_type,
 	.probe		= kszphy_probe,
 	.config_init	= ksz9131_config_init,
-	.read_status	= ksz9031_read_status,
+	.read_status	= genphy_read_status,
 	.ack_interrupt	= kszphy_ack_interrupt,
 	.config_intr	= kszphy_config_intr,
 	.get_sset_count = kszphy_get_sset_count,
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 07476c6510f2..44889eba1dbc 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1888,6 +1888,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
 
 	skb_reset_network_header(skb);
 	skb_probe_transport_header(skb);
+	skb_record_rx_queue(skb, tfile->queue_index);
 
 	if (skb_xdp) {
 		struct bpf_prog *xdp_prog;
@@ -2459,6 +2460,7 @@ static int tun_xdp_one(struct tun_struct *tun,
 	skb->protocol = eth_type_trans(skb, tun->dev);
 	skb_reset_network_header(skb);
 	skb_probe_transport_header(skb);
+	skb_record_rx_queue(skb, tfile->queue_index);
 
 	if (skb_xdp) {
 		err = do_xdp_generic(xdp_prog, skb);
@@ -2470,7 +2472,6 @@ static int tun_xdp_one(struct tun_struct *tun,
 	    !tfile->detached)
 		rxhash = __skb_get_hash_symmetric(skb);
 
-	skb_record_rx_queue(skb, tfile->queue_index);
 	netif_receive_skb(skb);
 
 	/* No need for get_cpu_ptr() here since this function is
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index f26cc6989dad..52472bbcee1f 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -723,10 +723,7 @@ static int ath10k_init_sdio(struct ath10k *ar, enum ath10k_firmware_mode mode)
 	if (ret)
 		return ret;
 
-	/* Data transfer is not initiated, when reduced Tx completion
-	 * is used for SDIO. disable it until fixed
-	 */
-	param &= ~HI_ACS_FLAGS_SDIO_REDUCE_TX_COMPL_SET;
+	param |= HI_ACS_FLAGS_SDIO_REDUCE_TX_COMPL_SET;
 
 	/* Alternate credit size of 1544 as used by SDIO firmware is
 	 * not big enough for mac80211 / native wifi frames. disable it
diff --git a/drivers/net/wireless/ath/ath10k/hif.h b/drivers/net/wireless/ath/ath10k/hif.h
index 496ee34a4d78..0dd8973d0acf 100644
--- a/drivers/net/wireless/ath/ath10k/hif.h
+++ b/drivers/net/wireless/ath/ath10k/hif.h
@@ -56,6 +56,8 @@ struct ath10k_hif_ops {
 
 	int (*swap_mailbox)(struct ath10k *ar);
 
+	int (*get_htt_tx_complete)(struct ath10k *ar);
+
 	int (*map_service_to_pipe)(struct ath10k *ar, u16 service_id,
 				   u8 *ul_pipe, u8 *dl_pipe);
 
@@ -144,6 +146,13 @@ static inline int ath10k_hif_swap_mailbox(struct ath10k *ar)
 	return 0;
 }
 
+static inline int ath10k_hif_get_htt_tx_complete(struct ath10k *ar)
+{
+	if (ar->hif.ops->get_htt_tx_complete)
+		return ar->hif.ops->get_htt_tx_complete(ar);
+	return 0;
+}
+
 static inline int ath10k_hif_map_service_to_pipe(struct ath10k *ar,
 						 u16 service_id,
 						 u8 *ul_pipe, u8 *dl_pipe)
diff --git a/drivers/net/wireless/ath/ath10k/htc.c b/drivers/net/wireless/ath/ath10k/htc.c
index 2248d6c022f4..61ee413d902a 100644
--- a/drivers/net/wireless/ath/ath10k/htc.c
+++ b/drivers/net/wireless/ath/ath10k/htc.c
@@ -660,6 +660,16 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc)
 	return 0;
 }
 
+void ath10k_htc_change_tx_credit_flow(struct ath10k_htc *htc,
+				      enum ath10k_htc_ep_id eid,
+				      bool enable)
+{
+	struct ath10k *ar = htc->ar;
+	struct ath10k_htc_ep *ep = &ar->htc.endpoint[eid];
+
+	ep->tx_credit_flow_enabled = enable;
+}
+
 int ath10k_htc_connect_service(struct ath10k_htc *htc,
 			       struct ath10k_htc_svc_conn_req *conn_req,
 			       struct ath10k_htc_svc_conn_resp *conn_resp)
diff --git a/drivers/net/wireless/ath/ath10k/htc.h b/drivers/net/wireless/ath/ath10k/htc.h
index 065c82d9d689..14e5c3f712c1 100644
--- a/drivers/net/wireless/ath/ath10k/htc.h
+++ b/drivers/net/wireless/ath/ath10k/htc.h
@@ -386,6 +386,9 @@ int ath10k_htc_start(struct ath10k_htc *htc);
 int ath10k_htc_connect_service(struct ath10k_htc *htc,
 			       struct ath10k_htc_svc_conn_req  *conn_req,
 			       struct ath10k_htc_svc_conn_resp *conn_resp);
+void ath10k_htc_change_tx_credit_flow(struct ath10k_htc *htc,
+				      enum ath10k_htc_ep_id eid,
+				      bool enable);
 int ath10k_htc_send(struct ath10k_htc *htc, enum ath10k_htc_ep_id eid,
 		    struct sk_buff *packet);
 struct sk_buff *ath10k_htc_alloc_skb(struct ath10k *ar, int size);
diff --git a/drivers/net/wireless/ath/ath10k/htt.c b/drivers/net/wireless/ath/ath10k/htt.c
index 7b75200ceae5..4354bf285ff1 100644
--- a/drivers/net/wireless/ath/ath10k/htt.c
+++ b/drivers/net/wireless/ath/ath10k/htt.c
@@ -10,6 +10,7 @@
 #include "htt.h"
 #include "core.h"
 #include "debug.h"
+#include "hif.h"
 
 static const enum htt_t2h_msg_type htt_main_t2h_msg_types[] = {
 	[HTT_MAIN_T2H_MSG_TYPE_VERSION_CONF] = HTT_T2H_MSG_TYPE_VERSION_CONF,
@@ -153,6 +154,10 @@ int ath10k_htt_connect(struct ath10k_htt *htt)
 
 	htt->eid = conn_resp.eid;
 
+	htt->disable_tx_comp = ath10k_hif_get_htt_tx_complete(htt->ar);
+	if (htt->disable_tx_comp)
+		ath10k_htc_change_tx_credit_flow(&htt->ar->htc, htt->eid, true);
+
 	return 0;
 }
 
diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h
index 4a12564fc30e..b88c2f3787d8 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -150,9 +150,19 @@ enum htt_data_tx_desc_flags1 {
 	HTT_DATA_TX_DESC_FLAGS1_MORE_IN_BATCH    = 1 << 12,
 	HTT_DATA_TX_DESC_FLAGS1_CKSUM_L3_OFFLOAD = 1 << 13,
 	HTT_DATA_TX_DESC_FLAGS1_CKSUM_L4_OFFLOAD = 1 << 14,
-	HTT_DATA_TX_DESC_FLAGS1_RSVD1            = 1 << 15
+	HTT_DATA_TX_DESC_FLAGS1_TX_COMPLETE      = 1 << 15
 };
 
+#define HTT_TX_CREDIT_DELTA_ABS_M      0xffff0000
+#define HTT_TX_CREDIT_DELTA_ABS_S      16
+#define HTT_TX_CREDIT_DELTA_ABS_GET(word) \
+	    (((word) & HTT_TX_CREDIT_DELTA_ABS_M) >> HTT_TX_CREDIT_DELTA_ABS_S)
+
+#define HTT_TX_CREDIT_SIGN_BIT_M       0x00000100
+#define HTT_TX_CREDIT_SIGN_BIT_S       8
+#define HTT_TX_CREDIT_SIGN_BIT_GET(word) \
+	    (((word) & HTT_TX_CREDIT_SIGN_BIT_M) >> HTT_TX_CREDIT_SIGN_BIT_S)
+
 enum htt_data_tx_ext_tid {
 	HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST = 16,
 	HTT_DATA_TX_EXT_TID_MGMT                = 17,
@@ -2021,6 +2031,7 @@ struct ath10k_htt {
 	bool tx_mem_allocated;
 	const struct ath10k_htt_tx_ops *tx_ops;
 	const struct ath10k_htt_rx_ops *rx_ops;
+	bool disable_tx_comp;
 };
 
 struct ath10k_htt_tx_ops {
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index f883f2a724dd..64e45bfa5d05 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -3789,6 +3789,9 @@ bool ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
 	}
 	case HTT_T2H_MSG_TYPE_MGMT_TX_COMPLETION: {
 		struct htt_tx_done tx_done = {};
+		struct ath10k_htt *htt = &ar->htt;
+		struct ath10k_htc *htc = &ar->htc;
+		struct ath10k_htc_ep *ep = &ar->htc.endpoint[htt->eid];
 		int status = __le32_to_cpu(resp->mgmt_tx_completion.status);
 		int info = __le32_to_cpu(resp->mgmt_tx_completion.info);
 
@@ -3814,6 +3817,12 @@ bool ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
 			break;
 		}
 
+		if (htt->disable_tx_comp) {
+			spin_lock_bh(&htc->tx_lock);
+			ep->tx_credits++;
+			spin_unlock_bh(&htc->tx_lock);
+		}
+
 		status = ath10k_txrx_tx_unref(htt, &tx_done);
 		if (!status) {
 			spin_lock_bh(&htt->tx_lock);
@@ -3888,8 +3897,31 @@ bool ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
 		skb_queue_tail(&htt->rx_in_ord_compl_q, skb);
 		return false;
 	}
-	case HTT_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND:
+	case HTT_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND: {
+		struct ath10k_htt *htt = &ar->htt;
+		struct ath10k_htc *htc = &ar->htc;
+		struct ath10k_htc_ep *ep = &ar->htc.endpoint[htt->eid];
+		u32 msg_word = __le32_to_cpu(*(__le32 *)resp);
+		int htt_credit_delta;
+
+		htt_credit_delta = HTT_TX_CREDIT_DELTA_ABS_GET(msg_word);
+		if (HTT_TX_CREDIT_SIGN_BIT_GET(msg_word))
+			htt_credit_delta = -htt_credit_delta;
+
+		ath10k_dbg(ar, ATH10K_DBG_HTT,
+			   "htt credit update delta %d\n",
+			   htt_credit_delta);
+
+		if (htt->disable_tx_comp) {
+			spin_lock_bh(&htc->tx_lock);
+			ep->tx_credits += htt_credit_delta;
+			spin_unlock_bh(&htc->tx_lock);
+			ath10k_dbg(ar, ATH10K_DBG_HTT,
+				   "htt credit total %d\n",
+				   ep->tx_credits);
+		}
 		break;
+	}
 	case HTT_T2H_MSG_TYPE_CHAN_CHANGE: {
 		u32 phymode = __le32_to_cpu(resp->chan_change.phymode);
 		u32 freq = __le32_to_cpu(resp->chan_change.freq);
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index e9d12ea708b6..bcecf05fe2fd 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -543,7 +543,39 @@ void ath10k_htt_tx_free(struct ath10k_htt *htt)
 
 void ath10k_htt_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb)
 {
+	struct ath10k_htt *htt = &ar->htt;
+	struct htt_tx_done tx_done = {0};
+	struct htt_cmd_hdr *htt_hdr;
+	struct htt_data_tx_desc *desc_hdr = NULL;
+	u16 flags1 = 0;
+	u8 msg_type = 0;
+
+	if (htt->disable_tx_comp) {
+		htt_hdr = (struct htt_cmd_hdr *)skb->data;
+		msg_type = htt_hdr->msg_type;
+
+		if (msg_type == HTT_H2T_MSG_TYPE_TX_FRM) {
+			desc_hdr = (struct htt_data_tx_desc *)
+				(skb->data + sizeof(*htt_hdr));
+			flags1 = __le16_to_cpu(desc_hdr->flags1);
+		}
+	}
+
 	dev_kfree_skb_any(skb);
+
+	if ((!htt->disable_tx_comp) || (msg_type != HTT_H2T_MSG_TYPE_TX_FRM))
+		return;
+
+	ath10k_dbg(ar, ATH10K_DBG_HTT,
+		   "htt tx complete msdu id:%u ,flags1:%x\n",
+		   __le16_to_cpu(desc_hdr->id), flags1);
+
+	if (flags1 & HTT_DATA_TX_DESC_FLAGS1_TX_COMPLETE)
+		return;
+
+	tx_done.status = HTT_TX_COMPL_STATE_ACK;
+	tx_done.msdu_id = __le16_to_cpu(desc_hdr->id);
+	ath10k_txrx_tx_unref(&ar->htt, &tx_done);
 }
 
 void ath10k_htt_hif_tx_complete(struct ath10k *ar, struct sk_buff *skb)
@@ -1279,6 +1311,9 @@ static int ath10k_htt_tx_hl(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txm
 		flags0 |= SM(ATH10K_HW_TXRX_MGMT,
 			     HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE);
 		flags0 |= HTT_DATA_TX_DESC_FLAGS0_MAC_HDR_PRESENT;
+
+		if (htt->disable_tx_comp)
+			flags1 |= HTT_DATA_TX_DESC_FLAGS1_TX_COMPLETE;
 		break;
 	}
 
diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h
index 970c736ac6bb..2a7af5861788 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -765,7 +765,7 @@ ath10k_is_rssi_enable(struct ath10k_hw_params *hw,
 #define TARGET_TLV_NUM_TDLS_VDEVS		1
 #define TARGET_TLV_NUM_TIDS			((TARGET_TLV_NUM_PEERS) * 2)
 #define TARGET_TLV_NUM_MSDU_DESC		(1024 + 32)
-#define TARGET_TLV_NUM_MSDU_DESC_HL		64
+#define TARGET_TLV_NUM_MSDU_DESC_HL		1024
 #define TARGET_TLV_NUM_WOW_PATTERNS		22
 #define TARGET_TLV_MGMT_NUM_MSDU_DESC		(50)
 
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 2d03b8dd3b8c..a59a7a5631a8 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -2505,6 +2505,30 @@ ath10k_peer_assoc_h_vht_limit(u16 tx_mcs_set,
 	return tx_mcs_set;
 }
 
+static u32 get_160mhz_nss_from_maxrate(int rate)
+{
+	u32 nss;
+
+	switch (rate) {
+	case 780:
+		nss = 1;
+		break;
+	case 1560:
+		nss = 2;
+		break;
+	case 2106:
+		nss = 3; /* not support MCS9 from spec*/
+		break;
+	case 3120:
+		nss = 4;
+		break;
+	default:
+		 nss = 1;
+	}
+
+	return nss;
+}
+
 static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
 				    struct ieee80211_vif *vif,
 				    struct ieee80211_sta *sta,
@@ -2512,6 +2536,7 @@ static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
 {
 	const struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
 	struct ath10k_vif *arvif = (void *)vif->drv_priv;
+	struct ath10k_hw_params *hw = &ar->hw_params;
 	struct cfg80211_chan_def def;
 	enum nl80211_band band;
 	const u16 *vht_mcs_mask;
@@ -2578,22 +2603,38 @@ static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
 	arg->peer_vht_rates.tx_mcs_set = ath10k_peer_assoc_h_vht_limit(
 		__le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map), vht_mcs_mask);
 
-	ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x\n",
-		   sta->addr, arg->peer_max_mpdu, arg->peer_flags);
+	/* Configure bandwidth-NSS mapping to FW
+	 * for the chip's tx chains setting on 160Mhz bw
+	 */
+	if (arg->peer_phymode == MODE_11AC_VHT160 ||
+	    arg->peer_phymode == MODE_11AC_VHT80_80) {
+		u32 rx_nss;
+		u32 max_rate;
 
-	if (arg->peer_vht_rates.rx_max_rate &&
-	    (sta->vht_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK)) {
-		switch (arg->peer_vht_rates.rx_max_rate) {
-		case 1560:
-			/* Must be 2x2 at 160Mhz is all it can do. */
-			arg->peer_bw_rxnss_override = 2;
-			break;
-		case 780:
-			/* Can only do 1x1 at 160Mhz (Long Guard Interval) */
-			arg->peer_bw_rxnss_override = 1;
-			break;
+		max_rate = arg->peer_vht_rates.rx_max_rate;
+		rx_nss = get_160mhz_nss_from_maxrate(max_rate);
+
+		if (rx_nss == 0)
+			rx_nss = arg->peer_num_spatial_streams;
+		else
+			rx_nss = min(arg->peer_num_spatial_streams, rx_nss);
+
+		max_rate = hw->vht160_mcs_tx_highest;
+		rx_nss = min(rx_nss, get_160mhz_nss_from_maxrate(max_rate));
+
+		arg->peer_bw_rxnss_override =
+			FIELD_PREP(WMI_PEER_NSS_MAP_ENABLE, 1) |
+			FIELD_PREP(WMI_PEER_NSS_160MHZ_MASK, (rx_nss - 1));
+
+		if (arg->peer_phymode == MODE_11AC_VHT80_80) {
+			arg->peer_bw_rxnss_override |=
+			FIELD_PREP(WMI_PEER_NSS_80_80MHZ_MASK, (rx_nss - 1));
 		}
 	}
+	ath10k_dbg(ar, ATH10K_DBG_MAC,
+		   "mac vht peer %pM max_mpdu %d flags 0x%x peer_rx_nss_override 0x%x\n",
+		   sta->addr, arg->peer_max_mpdu,
+		   arg->peer_flags, arg->peer_bw_rxnss_override);
 }
 
 static void ath10k_peer_assoc_h_qos(struct ath10k *ar,
@@ -2745,9 +2786,9 @@ static int ath10k_peer_assoc_prepare(struct ath10k *ar,
 	ath10k_peer_assoc_h_crypto(ar, vif, sta, arg);
 	ath10k_peer_assoc_h_rates(ar, vif, sta, arg);
 	ath10k_peer_assoc_h_ht(ar, vif, sta, arg);
+	ath10k_peer_assoc_h_phymode(ar, vif, sta, arg);
 	ath10k_peer_assoc_h_vht(ar, vif, sta, arg);
 	ath10k_peer_assoc_h_qos(ar, vif, sta, arg);
-	ath10k_peer_assoc_h_phymode(ar, vif, sta, arg);
 
 	return 0;
 }
@@ -4563,13 +4604,6 @@ static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar)
 		vht_cap.cap |= val;
 	}
 
-	/* Currently the firmware seems to be buggy, don't enable 80+80
-	 * mode until that's resolved.
-	 */
-	if ((ar->vht_cap_info & IEEE80211_VHT_CAP_SHORT_GI_160) &&
-	    (ar->vht_cap_info & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) == 0)
-		vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
-
 	mcs_map = 0;
 	for (i = 0; i < 8; i++) {
 		if ((i < ar->num_rf_chains) && (ar->cfg_tx_chainmask & BIT(i)))
@@ -8625,7 +8659,9 @@ static const struct ieee80211_iface_combination ath10k_10_4_if_comb[] = {
 		.radar_detect_widths =	BIT(NL80211_CHAN_WIDTH_20_NOHT) |
 					BIT(NL80211_CHAN_WIDTH_20) |
 					BIT(NL80211_CHAN_WIDTH_40) |
-					BIT(NL80211_CHAN_WIDTH_80),
+					BIT(NL80211_CHAN_WIDTH_80) |
+					BIT(NL80211_CHAN_WIDTH_80P80) |
+					BIT(NL80211_CHAN_WIDTH_160),
 #endif
 	},
 };
@@ -8643,7 +8679,9 @@ ieee80211_iface_combination ath10k_10_4_bcn_int_if_comb[] = {
 		.radar_detect_widths =  BIT(NL80211_CHAN_WIDTH_20_NOHT) |
 					BIT(NL80211_CHAN_WIDTH_20) |
 					BIT(NL80211_CHAN_WIDTH_40) |
-					BIT(NL80211_CHAN_WIDTH_80),
+					BIT(NL80211_CHAN_WIDTH_80) |
+					BIT(NL80211_CHAN_WIDTH_80P80) |
+					BIT(NL80211_CHAN_WIDTH_160),
 #endif
 	},
 };
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index ded7a220a4aa..cd1c5d60261f 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -2074,6 +2074,7 @@ static void ath10k_pci_hif_stop(struct ath10k *ar)
 	ath10k_pci_irq_sync(ar);
 	napi_synchronize(&ar->napi);
 	napi_disable(&ar->napi);
+	cancel_work_sync(&ar_pci->dump_work);
 
 	/* Most likely the device has HTT Rx ring configured. The only way to
 	 * prevent the device from accessing (and possible corrupting) host
diff --git a/drivers/net/wireless/ath/ath10k/sdio.c b/drivers/net/wireless/ath/ath10k/sdio.c
index 1f709b65c29b..5a0db342e5ad 100644
--- a/drivers/net/wireless/ath/ath10k/sdio.c
+++ b/drivers/net/wireless/ath/ath10k/sdio.c
@@ -1752,6 +1752,28 @@ static int ath10k_sdio_hif_swap_mailbox(struct ath10k *ar)
 	return 0;
 }
 
+static int ath10k_sdio_get_htt_tx_complete(struct ath10k *ar)
+{
+	u32 addr, val;
+	int ret;
+
+	addr = host_interest_item_address(HI_ITEM(hi_acs_flags));
+
+	ret = ath10k_sdio_hif_diag_read32(ar, addr, &val);
+	if (ret) {
+		ath10k_warn(ar,
+			    "unable to read hi_acs_flags for htt tx comple : %d\n", ret);
+		return ret;
+	}
+
+	ret = (val & HI_ACS_FLAGS_SDIO_REDUCE_TX_COMPL_FW_ACK);
+
+	ath10k_dbg(ar, ATH10K_DBG_SDIO, "sdio reduce tx complete fw%sack\n",
+		   ret ? " " : " not ");
+
+	return ret;
+}
+
 /* HIF start/stop */
 
 static int ath10k_sdio_hif_start(struct ath10k *ar)
@@ -2026,6 +2048,7 @@ static const struct ath10k_hif_ops ath10k_sdio_hif_ops = {
 	.start			= ath10k_sdio_hif_start,
 	.stop			= ath10k_sdio_hif_stop,
 	.swap_mailbox		= ath10k_sdio_hif_swap_mailbox,
+	.get_htt_tx_complete	= ath10k_sdio_get_htt_tx_complete,
 	.map_service_to_pipe	= ath10k_sdio_hif_map_service_to_pipe,
 	.get_default_pipe	= ath10k_sdio_hif_get_default_pipe,
 	.send_complete_check	= ath10k_sdio_hif_send_complete_check,
diff --git a/drivers/net/wireless/ath/ath10k/sdio.h b/drivers/net/wireless/ath/ath10k/sdio.h
index 33195f49acab..1c987494ad22 100644
--- a/drivers/net/wireless/ath/ath10k/sdio.h
+++ b/drivers/net/wireless/ath/ath10k/sdio.h
@@ -37,7 +37,7 @@
 	(ATH10K_SDIO_MAX_BUFFER_SIZE - sizeof(struct ath10k_htc_hdr))
 
 #define ATH10K_HIF_MBOX_NUM_MAX                 4
-#define ATH10K_SDIO_BUS_REQUEST_MAX_NUM         64
+#define ATH10K_SDIO_BUS_REQUEST_MAX_NUM         1024
 
 #define ATH10K_SDIO_HIF_COMMUNICATION_TIMEOUT_HZ (100 * HZ)
 
@@ -98,6 +98,7 @@
 #define ATH10K_FIFO_TIMEOUT_AND_CHIP_CONTROL_DISABLE_SLEEP_OFF 0xFFFEFFFF
 #define ATH10K_FIFO_TIMEOUT_AND_CHIP_CONTROL_DISABLE_SLEEP_ON 0x10000
 
+/* TODO: remove this and use skb->cb instead, much cleaner approach */
 struct ath10k_sdio_bus_request {
 	struct list_head list;
 
diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c
index 39abf8b12903..f46b9083bbf1 100644
--- a/drivers/net/wireless/ath/ath10k/txrx.c
+++ b/drivers/net/wireless/ath/ath10k/txrx.c
@@ -84,9 +84,11 @@ int ath10k_txrx_tx_unref(struct ath10k_htt *htt,
 		wake_up(&htt->empty_tx_wq);
 	spin_unlock_bh(&htt->tx_lock);
 
+	rcu_read_lock();
 	if (txq && txq->sta && skb_cb->airtime_est)
 		ieee80211_sta_register_airtime(txq->sta, txq->tid,
 					       skb_cb->airtime_est, 0);
+	rcu_read_unlock();
 
 	if (ar->bus_param.dev_type != ATH10K_DEV_TYPE_HL)
 		dma_unmap_single(dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
index 4e68debda9bf..e1ab900f2662 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
@@ -2123,7 +2123,7 @@ ath10k_wmi_tlv_op_gen_vdev_start(struct ath10k *ar,
 	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_CHANNEL);
 	tlv->len = __cpu_to_le16(sizeof(*ch));
 	ch = (void *)tlv->value;
-	ath10k_wmi_put_wmi_channel(ch, &arg->channel);
+	ath10k_wmi_put_wmi_channel(ar, ch, &arg->channel);
 
 	ptr += sizeof(*tlv);
 	ptr += sizeof(*ch);
@@ -2763,7 +2763,7 @@ ath10k_wmi_tlv_op_gen_scan_chan_list(struct ath10k *ar,
 		tlv->len = __cpu_to_le16(sizeof(*ci));
 		ci = (void *)tlv->value;
 
-		ath10k_wmi_put_wmi_channel(ci, ch);
+		ath10k_wmi_put_wmi_channel(ar, ci, ch);
 
 		chans += sizeof(*tlv);
 		chans += sizeof(*ci);
@@ -3450,7 +3450,7 @@ ath10k_wmi_tlv_op_gen_tdls_peer_update(struct ath10k *ar,
 		tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_CHANNEL);
 		tlv->len = __cpu_to_le16(sizeof(*chan));
 		chan = (void *)tlv->value;
-		ath10k_wmi_put_wmi_channel(chan, &chan_arg[i]);
+		ath10k_wmi_put_wmi_channel(ar, chan, &chan_arg[i]);
 
 		ptr += sizeof(*tlv);
 		ptr += sizeof(*chan);
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 2ea77bb880b1..4a3a698fe059 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -1694,10 +1694,11 @@ static const struct wmi_peer_flags_map wmi_10_2_peer_flags_map = {
 	.bw160 = WMI_10_2_PEER_160MHZ,
 };
 
-void ath10k_wmi_put_wmi_channel(struct wmi_channel *ch,
+void ath10k_wmi_put_wmi_channel(struct ath10k *ar, struct wmi_channel *ch,
 				const struct wmi_channel_arg *arg)
 {
 	u32 flags = 0;
+	struct ieee80211_channel *chan = NULL;
 
 	memset(ch, 0, sizeof(*ch));
 
@@ -1714,12 +1715,39 @@ void ath10k_wmi_put_wmi_channel(struct wmi_channel *ch,
 	if (arg->chan_radar)
 		flags |= WMI_CHAN_FLAG_DFS;
 
+	ch->band_center_freq2 = 0;
 	ch->mhz = __cpu_to_le32(arg->freq);
 	ch->band_center_freq1 = __cpu_to_le32(arg->band_center_freq1);
-	if (arg->mode == MODE_11AC_VHT80_80)
+	if (arg->mode == MODE_11AC_VHT80_80) {
 		ch->band_center_freq2 = __cpu_to_le32(arg->band_center_freq2);
-	else
-		ch->band_center_freq2 = 0;
+		chan = ieee80211_get_channel(ar->hw->wiphy,
+					     arg->band_center_freq2 - 10);
+	}
+
+	if (arg->mode == MODE_11AC_VHT160) {
+		u32 band_center_freq1;
+		u32 band_center_freq2;
+
+		if (arg->freq > arg->band_center_freq1) {
+			band_center_freq1 = arg->band_center_freq1 + 40;
+			band_center_freq2 = arg->band_center_freq1 - 40;
+		} else {
+			band_center_freq1 = arg->band_center_freq1 - 40;
+			band_center_freq2 = arg->band_center_freq1 + 40;
+		}
+
+		ch->band_center_freq1 =
+					__cpu_to_le32(band_center_freq1);
+		/* Minus 10 to get a defined 5G channel frequency*/
+		chan = ieee80211_get_channel(ar->hw->wiphy,
+					     band_center_freq2 - 10);
+		/* The center frequency of the entire VHT160 */
+		ch->band_center_freq2 = __cpu_to_le32(arg->band_center_freq1);
+	}
+
+	if (chan && chan->flags & IEEE80211_CHAN_RADAR)
+		flags |= WMI_CHAN_FLAG_DFS_CFREQ2;
+
 	ch->min_power = arg->min_power;
 	ch->max_power = arg->max_power;
 	ch->reg_power = arg->max_reg_power;
@@ -7165,7 +7193,7 @@ ath10k_wmi_op_gen_vdev_start(struct ath10k *ar,
 		memcpy(cmd->ssid.ssid, arg->ssid, arg->ssid_len);
 	}
 
-	ath10k_wmi_put_wmi_channel(&cmd->chan, &arg->channel);
+	ath10k_wmi_put_wmi_channel(ar, &cmd->chan, &arg->channel);
 
 	ath10k_dbg(ar, ATH10K_DBG_WMI,
 		   "wmi vdev %s id 0x%x flags: 0x%0X, freq %d, mode %d, ch_flags: 0x%0X, max_power: %d\n",
@@ -7537,7 +7565,7 @@ ath10k_wmi_op_gen_scan_chan_list(struct ath10k *ar,
 		ch = &arg->channels[i];
 		ci = &cmd->chan_info[i];
 
-		ath10k_wmi_put_wmi_channel(ci, ch);
+		ath10k_wmi_put_wmi_channel(ar, ci, ch);
 	}
 
 	return skb;
@@ -7628,12 +7656,8 @@ ath10k_wmi_peer_assoc_fill_10_4(struct ath10k *ar, void *buf,
 	struct wmi_10_4_peer_assoc_complete_cmd *cmd = buf;
 
 	ath10k_wmi_peer_assoc_fill_10_2(ar, buf, arg);
-	if (arg->peer_bw_rxnss_override)
-		cmd->peer_bw_rxnss_override =
-			__cpu_to_le32((arg->peer_bw_rxnss_override - 1) |
-				      BIT(PEER_BW_RXNSS_OVERRIDE_OFFSET));
-	else
-		cmd->peer_bw_rxnss_override = 0;
+	cmd->peer_bw_rxnss_override =
+		__cpu_to_le32(arg->peer_bw_rxnss_override);
 }
 
 static int
@@ -8945,7 +8969,7 @@ ath10k_wmi_10_4_gen_tdls_peer_update(struct ath10k *ar,
 
 	for (i = 0; i < cap->peer_chan_len; i++) {
 		chan = (struct wmi_channel *)&peer_cap->peer_chan_list[i];
-		ath10k_wmi_put_wmi_channel(chan, &chan_arg[i]);
+		ath10k_wmi_put_wmi_channel(ar, chan, &chan_arg[i]);
 	}
 
 	ath10k_dbg(ar, ATH10K_DBG_WMI,
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index 6df415778374..209070714d1a 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -2094,7 +2094,8 @@ enum wmi_channel_change_cause {
 
 /* Indicate reason for channel switch */
 #define WMI_CHANNEL_CHANGE_CAUSE_CSA (1 << 13)
-
+/* DFS required on channel for 2nd segment of VHT160 and VHT80+80*/
+#define WMI_CHAN_FLAG_DFS_CFREQ2  (1 << 15)
 #define WMI_MAX_SPATIAL_STREAM        3 /* default max ss */
 
 /* HT Capabilities*/
@@ -6508,7 +6509,10 @@ struct wmi_10_2_peer_assoc_complete_cmd {
 	__le32 info0; /* WMI_PEER_ASSOC_INFO0_ */
 } __packed;
 
-#define PEER_BW_RXNSS_OVERRIDE_OFFSET  31
+/* NSS Mapping to FW */
+#define WMI_PEER_NSS_MAP_ENABLE	BIT(31)
+#define WMI_PEER_NSS_160MHZ_MASK	GENMASK(2, 0)
+#define WMI_PEER_NSS_80_80MHZ_MASK	GENMASK(5, 3)
 
 struct wmi_10_4_peer_assoc_complete_cmd {
 	struct wmi_10_2_peer_assoc_complete_cmd cmd;
@@ -7348,7 +7352,7 @@ void ath10k_wmi_put_start_scan_common(struct wmi_start_scan_common *cmn,
 				      const struct wmi_start_scan_arg *arg);
 void ath10k_wmi_set_wmm_param(struct wmi_wmm_params *params,
 			      const struct wmi_wmm_params_arg *arg);
-void ath10k_wmi_put_wmi_channel(struct wmi_channel *ch,
+void ath10k_wmi_put_wmi_channel(struct ath10k *ar, struct wmi_channel *ch,
 				const struct wmi_channel_arg *arg);
 int ath10k_wmi_start_scan_verify(const struct wmi_start_scan_arg *arg);
 
diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c
index 59342d2797ca..3b2b76d602f2 100644
--- a/drivers/net/wireless/ath/ath11k/ahb.c
+++ b/drivers/net/wireless/ath/ath11k/ahb.c
@@ -788,7 +788,7 @@ static int ath11k_ahb_ext_irq_config(struct ath11k_base *ab)
 			irq = platform_get_irq_byname(ab->pdev,
 						      irq_name[irq_idx]);
 			ab->irq_num[irq_idx] = irq;
-			irq_set_status_flags(irq, IRQ_NOAUTOEN);
+			irq_set_status_flags(irq, IRQ_NOAUTOEN | IRQ_DISABLE_UNLAZY);
 			ret = request_irq(irq, ath11k_ahb_ext_interrupt_handler,
 					  IRQF_TRIGGER_RISING,
 					  irq_name[irq_idx], irq_grp);
diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h
index 6e7b8ecd09a6..b4c3e0418eef 100644
--- a/drivers/net/wireless/ath/ath11k/core.h
+++ b/drivers/net/wireless/ath/ath11k/core.h
@@ -341,6 +341,11 @@ struct ath11k_sta {
 	u8 rssi_comb;
 	struct ath11k_htt_tx_stats *tx_stats;
 	struct ath11k_rx_peer_stats *rx_stats;
+
+#ifdef CONFIG_MAC80211_DEBUGFS
+	/* protected by conf_mutex */
+	bool aggr_mode;
+#endif
 };
 
 #define ATH11K_NUM_CHANS 41
@@ -650,6 +655,7 @@ struct ath11k_base {
 		/* protected by data_lock */
 		u32 fw_crash_counter;
 	} stats;
+	u32 pktlog_defs_checksum;
 };
 
 struct ath11k_fw_stats_pdev {
diff --git a/drivers/net/wireless/ath/ath11k/debug.h b/drivers/net/wireless/ath/ath11k/debug.h
index 97e7306c506d..4a3ff8227187 100644
--- a/drivers/net/wireless/ath/ath11k/debug.h
+++ b/drivers/net/wireless/ath/ath11k/debug.h
@@ -112,6 +112,12 @@ enum ath11k_pktlog_enum {
 	ATH11K_PKTLOG_TYPE_LITE_RX      = 24,
 };
 
+enum ath11k_dbg_aggr_mode {
+	ATH11K_DBG_AGGR_MODE_AUTO,
+	ATH11K_DBG_AGGR_MODE_MANUAL,
+	ATH11K_DBG_AGGR_MODE_MAX,
+};
+
 __printf(2, 3) void ath11k_info(struct ath11k_base *ab, const char *fmt, ...);
 __printf(2, 3) void ath11k_err(struct ath11k_base *ab, const char *fmt, ...);
 __printf(2, 3) void ath11k_warn(struct ath11k_base *ab, const char *fmt, ...);
diff --git a/drivers/net/wireless/ath/ath11k/debugfs_sta.c b/drivers/net/wireless/ath/ath11k/debugfs_sta.c
index 389dac219238..68963cfc5097 100644
--- a/drivers/net/wireless/ath/ath11k/debugfs_sta.c
+++ b/drivers/net/wireless/ath/ath11k/debugfs_sta.c
@@ -533,6 +533,222 @@ static const struct file_operations fops_peer_pktlog = {
 	.llseek = default_llseek,
 };
 
+static ssize_t ath11k_dbg_sta_write_delba(struct file *file,
+					  const char __user *user_buf,
+					  size_t count, loff_t *ppos)
+{
+	struct ieee80211_sta *sta = file->private_data;
+	struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
+	struct ath11k *ar = arsta->arvif->ar;
+	u32 tid, initiator, reason;
+	int ret;
+	char buf[64] = {0};
+
+	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
+				     user_buf, count);
+	if (ret <= 0)
+		return ret;
+
+	ret = sscanf(buf, "%u %u %u", &tid, &initiator, &reason);
+	if (ret != 3)
+		return -EINVAL;
+
+	/* Valid TID values are 0 through 15 */
+	if (tid > HAL_DESC_REO_NON_QOS_TID - 1)
+		return -EINVAL;
+
+	mutex_lock(&ar->conf_mutex);
+	if (ar->state != ATH11K_STATE_ON ||
+	    arsta->aggr_mode != ATH11K_DBG_AGGR_MODE_MANUAL) {
+		ret = count;
+		goto out;
+	}
+
+	ret = ath11k_wmi_delba_send(ar, arsta->arvif->vdev_id, sta->addr,
+				    tid, initiator, reason);
+	if (ret) {
+		ath11k_warn(ar->ab, "failed to send delba: vdev_id %u peer %pM tid %u initiator %u reason %u\n",
+			    arsta->arvif->vdev_id, sta->addr, tid, initiator,
+			    reason);
+	}
+	ret = count;
+out:
+	mutex_unlock(&ar->conf_mutex);
+	return ret;
+}
+
+static const struct file_operations fops_delba = {
+	.write = ath11k_dbg_sta_write_delba,
+	.open = simple_open,
+	.owner = THIS_MODULE,
+	.llseek = default_llseek,
+};
+
+static ssize_t ath11k_dbg_sta_write_addba_resp(struct file *file,
+					       const char __user *user_buf,
+					       size_t count, loff_t *ppos)
+{
+	struct ieee80211_sta *sta = file->private_data;
+	struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
+	struct ath11k *ar = arsta->arvif->ar;
+	u32 tid, status;
+	int ret;
+	char buf[64] = {0};
+
+	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
+				     user_buf, count);
+	if (ret <= 0)
+		return ret;
+
+	ret = sscanf(buf, "%u %u", &tid, &status);
+	if (ret != 2)
+		return -EINVAL;
+
+	/* Valid TID values are 0 through 15 */
+	if (tid > HAL_DESC_REO_NON_QOS_TID - 1)
+		return -EINVAL;
+
+	mutex_lock(&ar->conf_mutex);
+	if (ar->state != ATH11K_STATE_ON ||
+	    arsta->aggr_mode != ATH11K_DBG_AGGR_MODE_MANUAL) {
+		ret = count;
+		goto out;
+	}
+
+	ret = ath11k_wmi_addba_set_resp(ar, arsta->arvif->vdev_id, sta->addr,
+					tid, status);
+	if (ret) {
+		ath11k_warn(ar->ab, "failed to send addba response: vdev_id %u peer %pM tid %u status%u\n",
+			    arsta->arvif->vdev_id, sta->addr, tid, status);
+	}
+	ret = count;
+out:
+	mutex_unlock(&ar->conf_mutex);
+	return ret;
+}
+
+static const struct file_operations fops_addba_resp = {
+	.write = ath11k_dbg_sta_write_addba_resp,
+	.open = simple_open,
+	.owner = THIS_MODULE,
+	.llseek = default_llseek,
+};
+
+static ssize_t ath11k_dbg_sta_write_addba(struct file *file,
+					  const char __user *user_buf,
+					  size_t count, loff_t *ppos)
+{
+	struct ieee80211_sta *sta = file->private_data;
+	struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
+	struct ath11k *ar = arsta->arvif->ar;
+	u32 tid, buf_size;
+	int ret;
+	char buf[64] = {0};
+
+	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
+				     user_buf, count);
+	if (ret <= 0)
+		return ret;
+
+	ret = sscanf(buf, "%u %u", &tid, &buf_size);
+	if (ret != 2)
+		return -EINVAL;
+
+	/* Valid TID values are 0 through 15 */
+	if (tid > HAL_DESC_REO_NON_QOS_TID - 1)
+		return -EINVAL;
+
+	mutex_lock(&ar->conf_mutex);
+	if (ar->state != ATH11K_STATE_ON ||
+	    arsta->aggr_mode != ATH11K_DBG_AGGR_MODE_MANUAL) {
+		ret = count;
+		goto out;
+	}
+
+	ret = ath11k_wmi_addba_send(ar, arsta->arvif->vdev_id, sta->addr,
+				    tid, buf_size);
+	if (ret) {
+		ath11k_warn(ar->ab, "failed to send addba request: vdev_id %u peer %pM tid %u buf_size %u\n",
+			    arsta->arvif->vdev_id, sta->addr, tid, buf_size);
+	}
+
+	ret = count;
+out:
+	mutex_unlock(&ar->conf_mutex);
+	return ret;
+}
+
+static const struct file_operations fops_addba = {
+	.write = ath11k_dbg_sta_write_addba,
+	.open = simple_open,
+	.owner = THIS_MODULE,
+	.llseek = default_llseek,
+};
+
+static ssize_t ath11k_dbg_sta_read_aggr_mode(struct file *file,
+					     char __user *user_buf,
+					     size_t count, loff_t *ppos)
+{
+	struct ieee80211_sta *sta = file->private_data;
+	struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
+	struct ath11k *ar = arsta->arvif->ar;
+	char buf[64];
+	int len = 0;
+
+	mutex_lock(&ar->conf_mutex);
+	len = scnprintf(buf, sizeof(buf) - len,
+			"aggregation mode: %s\n\n%s\n%s\n",
+			(arsta->aggr_mode == ATH11K_DBG_AGGR_MODE_AUTO) ?
+			"auto" : "manual", "auto = 0", "manual = 1");
+	mutex_unlock(&ar->conf_mutex);
+
+	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t ath11k_dbg_sta_write_aggr_mode(struct file *file,
+					      const char __user *user_buf,
+					      size_t count, loff_t *ppos)
+{
+	struct ieee80211_sta *sta = file->private_data;
+	struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
+	struct ath11k *ar = arsta->arvif->ar;
+	u32 aggr_mode;
+	int ret;
+
+	if (kstrtouint_from_user(user_buf, count, 0, &aggr_mode))
+		return -EINVAL;
+
+	if (aggr_mode >= ATH11K_DBG_AGGR_MODE_MAX)
+		return -EINVAL;
+
+	mutex_lock(&ar->conf_mutex);
+	if (ar->state != ATH11K_STATE_ON ||
+	    aggr_mode == arsta->aggr_mode) {
+		ret = count;
+		goto out;
+	}
+
+	ret = ath11k_wmi_addba_clear_resp(ar, arsta->arvif->vdev_id, sta->addr);
+	if (ret) {
+		ath11k_warn(ar->ab, "failed to clear addba session ret: %d\n",
+			    ret);
+		goto out;
+	}
+
+	arsta->aggr_mode = aggr_mode;
+out:
+	mutex_unlock(&ar->conf_mutex);
+	return ret;
+}
+
+static const struct file_operations fops_aggr_mode = {
+	.read = ath11k_dbg_sta_read_aggr_mode,
+	.write = ath11k_dbg_sta_write_aggr_mode,
+	.open = simple_open,
+	.owner = THIS_MODULE,
+	.llseek = default_llseek,
+};
+
 void ath11k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 			    struct ieee80211_sta *sta, struct dentry *dir)
 {
@@ -550,4 +766,9 @@ void ath11k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 
 	debugfs_create_file("peer_pktlog", 0644, dir, sta,
 			    &fops_peer_pktlog);
+
+	debugfs_create_file("aggr_mode", 0644, dir, sta, &fops_aggr_mode);
+	debugfs_create_file("addba", 0200, dir, sta, &fops_addba);
+	debugfs_create_file("addba_resp", 0200, dir, sta, &fops_addba_resp);
+	debugfs_create_file("delba", 0200, dir, sta, &fops_delba);
 }
diff --git a/drivers/net/wireless/ath/ath11k/dp.h b/drivers/net/wireless/ath/ath11k/dp.h
index 551f9c9fb847..d4e19dc4bce1 100644
--- a/drivers/net/wireless/ath/ath11k/dp.h
+++ b/drivers/net/wireless/ath/ath11k/dp.h
@@ -169,8 +169,8 @@ struct ath11k_pdev_dp {
 
 #define DP_WBM_RELEASE_RING_SIZE	64
 #define DP_TCL_DATA_RING_SIZE		512
-#define DP_TX_COMP_RING_SIZE		8192
-#define DP_TX_IDR_SIZE			(DP_TX_COMP_RING_SIZE << 1)
+#define DP_TX_COMP_RING_SIZE		32768
+#define DP_TX_IDR_SIZE			DP_TX_COMP_RING_SIZE
 #define DP_TCL_CMD_RING_SIZE		32
 #define DP_TCL_STATUS_RING_SIZE		32
 #define DP_REO_DST_RING_MAX		4
diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c
index f74a0e74bf3e..203fd44ff352 100644
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
@@ -1491,7 +1491,8 @@ static void ath11k_htt_pktlog(struct ath11k_base *ab, struct sk_buff *skb)
 		return;
 	}
 
-	trace_ath11k_htt_pktlog(ar, data->payload, hdr->size);
+	trace_ath11k_htt_pktlog(ar, data->payload, hdr->size,
+				ar->ab->pktlog_defs_checksum);
 }
 
 static void ath11k_htt_backpressure_event_handler(struct ath11k_base *ab,
@@ -2402,12 +2403,12 @@ int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id,
 
 try_again:
 	while ((rx_desc = ath11k_hal_srng_dst_get_next_entry(ab, srng))) {
-		struct hal_reo_dest_ring *desc = (struct hal_reo_dest_ring *)rx_desc;
+		struct hal_reo_dest_ring desc = *(struct hal_reo_dest_ring *)rx_desc;
 		enum hal_reo_dest_ring_push_reason push_reason;
 		u32 cookie;
 
 		cookie = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE,
-				   desc->buf_addr_info.info1);
+				   desc.buf_addr_info.info1);
 		buf_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_BUF_ID,
 				   cookie);
 		mac_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_PDEV_ID, cookie);
@@ -2435,7 +2436,7 @@ int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id,
 		total_msdu_reaped++;
 
 		push_reason = FIELD_GET(HAL_REO_DEST_RING_INFO0_PUSH_REASON,
-					desc->info0);
+					desc.info0);
 		if (push_reason !=
 		    HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION) {
 			dev_kfree_skb_any(msdu);
@@ -2443,15 +2444,15 @@ int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id,
 			continue;
 		}
 
-		rxcb->is_first_msdu = !!(desc->rx_msdu_info.info0 &
+		rxcb->is_first_msdu = !!(desc.rx_msdu_info.info0 &
 					 RX_MSDU_DESC_INFO0_FIRST_MSDU_IN_MPDU);
-		rxcb->is_last_msdu = !!(desc->rx_msdu_info.info0 &
+		rxcb->is_last_msdu = !!(desc.rx_msdu_info.info0 &
 					RX_MSDU_DESC_INFO0_LAST_MSDU_IN_MPDU);
-		rxcb->is_continuation = !!(desc->rx_msdu_info.info0 &
+		rxcb->is_continuation = !!(desc.rx_msdu_info.info0 &
 					   RX_MSDU_DESC_INFO0_MSDU_CONTINUATION);
 		rxcb->mac_id = mac_id;
 		rxcb->tid = FIELD_GET(HAL_REO_DEST_RING_INFO0_RX_QUEUE_NUM,
-				      desc->info0);
+				      desc.info0);
 
 		__skb_queue_tail(&msdu_list, msdu);
 
diff --git a/drivers/net/wireless/ath/ath11k/hal.h b/drivers/net/wireless/ath/ath11k/hal.h
index 7722822a0456..780a3e11b609 100644
--- a/drivers/net/wireless/ath/ath11k/hal.h
+++ b/drivers/net/wireless/ath/ath11k/hal.h
@@ -599,7 +599,7 @@ struct hal_srng {
 /* Interrupt mitigation - timer threshold in us */
 #define HAL_SRNG_INT_TIMER_THRESHOLD_TX 1000
 #define HAL_SRNG_INT_TIMER_THRESHOLD_RX 500
-#define HAL_SRNG_INT_TIMER_THRESHOLD_OTHER 1000
+#define HAL_SRNG_INT_TIMER_THRESHOLD_OTHER 256
 
 /* HW SRNG configuration table */
 struct hal_srng_config {
diff --git a/drivers/net/wireless/ath/ath11k/peer.c b/drivers/net/wireless/ath/ath11k/peer.c
index f43deacc01bd..297172538620 100644
--- a/drivers/net/wireless/ath/ath11k/peer.c
+++ b/drivers/net/wireless/ath/ath11k/peer.c
@@ -17,7 +17,26 @@ struct ath11k_peer *ath11k_peer_find(struct ath11k_base *ab, int vdev_id,
 	list_for_each_entry(peer, &ab->peers, list) {
 		if (peer->vdev_id != vdev_id)
 			continue;
-		if (memcmp(peer->addr, addr, ETH_ALEN))
+		if (!ether_addr_equal(peer->addr, addr))
+			continue;
+
+		return peer;
+	}
+
+	return NULL;
+}
+
+static struct ath11k_peer *ath11k_peer_find_by_pdev_idx(struct ath11k_base *ab,
+							u8 pdev_idx, const u8 *addr)
+{
+	struct ath11k_peer *peer;
+
+	lockdep_assert_held(&ab->base_lock);
+
+	list_for_each_entry(peer, &ab->peers, list) {
+		if (peer->pdev_idx != pdev_idx)
+			continue;
+		if (!ether_addr_equal(peer->addr, addr))
 			continue;
 
 		return peer;
@@ -34,7 +53,7 @@ struct ath11k_peer *ath11k_peer_find_by_addr(struct ath11k_base *ab,
 	lockdep_assert_held(&ab->base_lock);
 
 	list_for_each_entry(peer, &ab->peers, list) {
-		if (memcmp(peer->addr, addr, ETH_ALEN))
+		if (!ether_addr_equal(peer->addr, addr))
 			continue;
 
 		return peer;
@@ -200,6 +219,17 @@ int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif,
 		return -ENOBUFS;
 	}
 
+	spin_lock_bh(&ar->ab->base_lock);
+	peer = ath11k_peer_find_by_pdev_idx(ar->ab, ar->pdev_idx, param->peer_addr);
+	if (peer) {
+		spin_unlock_bh(&ar->ab->base_lock);
+		ath11k_info(ar->ab,
+			    "ignoring the peer %pM creation on same pdev idx %d\n",
+			    param->peer_addr, ar->pdev_idx);
+		return -EINVAL;
+	}
+	spin_unlock_bh(&ar->ab->base_lock);
+
 	ret = ath11k_wmi_send_peer_create_cmd(ar, param);
 	if (ret) {
 		ath11k_warn(ar->ab,
@@ -225,6 +255,7 @@ int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif,
 		return -ENOENT;
 	}
 
+	peer->pdev_idx = ar->pdev_idx;
 	peer->sta = sta;
 	arvif->ast_hash = peer->ast_hash;
 
diff --git a/drivers/net/wireless/ath/ath11k/peer.h b/drivers/net/wireless/ath/ath11k/peer.h
index ccca1523a6ea..5d125ce8984e 100644
--- a/drivers/net/wireless/ath/ath11k/peer.h
+++ b/drivers/net/wireless/ath/ath11k/peer.h
@@ -13,6 +13,7 @@ struct ath11k_peer {
 	u8 addr[ETH_ALEN];
 	int peer_id;
 	u16 ast_hash;
+	u8 pdev_idx;
 
 	/* protected by ab->data_lock */
 	struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1];
diff --git a/drivers/net/wireless/ath/ath11k/thermal.h b/drivers/net/wireless/ath/ath11k/thermal.h
index 459b8d49c184..f9af55f3682d 100644
--- a/drivers/net/wireless/ath/ath11k/thermal.h
+++ b/drivers/net/wireless/ath/ath11k/thermal.h
@@ -36,12 +36,13 @@ static inline int ath11k_thermal_register(struct ath11k_base *sc)
 	return 0;
 }
 
-static inline void ath11k_thermal_unregister(struct ath11k *ar)
+static inline void ath11k_thermal_unregister(struct ath11k_base *sc)
 {
 }
 
 static inline int ath11k_thermal_set_throttling(struct ath11k *ar, u32 throttle_state)
 {
+	return 0;
 }
 
 static inline void ath11k_thermal_event_temperature(struct ath11k *ar,
diff --git a/drivers/net/wireless/ath/ath11k/trace.h b/drivers/net/wireless/ath/ath11k/trace.h
index 8700a622be7b..66d0aae7816c 100644
--- a/drivers/net/wireless/ath/ath11k/trace.h
+++ b/drivers/net/wireless/ath/ath11k/trace.h
@@ -21,14 +21,16 @@ static inline void trace_ ## name(proto) {}
 #define TRACE_SYSTEM ath11k
 
 TRACE_EVENT(ath11k_htt_pktlog,
-	    TP_PROTO(struct ath11k *ar, const void *buf, u16 buf_len),
+	    TP_PROTO(struct ath11k *ar, const void *buf, u16 buf_len,
+		     u32 pktlog_checksum),
 
-	TP_ARGS(ar, buf, buf_len),
+	TP_ARGS(ar, buf, buf_len, pktlog_checksum),
 
 	TP_STRUCT__entry(
 		__string(device, dev_name(ar->ab->dev))
 		__string(driver, dev_driver_string(ar->ab->dev))
 		__field(u16, buf_len)
+		__field(u32, pktlog_checksum)
 		__dynamic_array(u8, pktlog, buf_len)
 	),
 
@@ -36,14 +38,16 @@ TRACE_EVENT(ath11k_htt_pktlog,
 		__assign_str(device, dev_name(ar->ab->dev));
 		__assign_str(driver, dev_driver_string(ar->ab->dev));
 		__entry->buf_len = buf_len;
+		__entry->pktlog_checksum = pktlog_checksum;
 		memcpy(__get_dynamic_array(pktlog), buf, buf_len);
 	),
 
 	TP_printk(
-		"%s %s size %hu",
+		"%s %s size %hu pktlog_checksum %d",
 		__get_str(driver),
 		__get_str(device),
-		__entry->buf_len
+		__entry->buf_len,
+		__entry->pktlog_checksum
 	 )
 );
 
diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
index e7ce36966d6a..c2a972377687 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.c
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
@@ -87,8 +87,8 @@ static const struct wmi_tlv_policy wmi_tlv_policies[] = {
 		= { .min_len = sizeof(struct wmi_pdev_bss_chan_info_event) },
 	[WMI_TAG_VDEV_INSTALL_KEY_COMPLETE_EVENT]
 		= { .min_len = sizeof(struct wmi_vdev_install_key_compl_event) },
-	[WMI_TAG_READY_EVENT]
-		= {.min_len = sizeof(struct wmi_ready_event) },
+	[WMI_TAG_READY_EVENT] = {
+		.min_len = sizeof(struct wmi_ready_event_min) },
 	[WMI_TAG_SERVICE_AVAILABLE_EVENT]
 		= {.min_len = sizeof(struct wmi_service_available_event) },
 	[WMI_TAG_PEER_ASSOC_CONF_EVENT]
@@ -2368,6 +2368,146 @@ int ath11k_wmi_send_dfs_phyerr_offload_enable_cmd(struct ath11k *ar,
 	return ret;
 }
 
+int ath11k_wmi_delba_send(struct ath11k *ar, u32 vdev_id, const u8 *mac,
+			  u32 tid, u32 initiator, u32 reason)
+{
+	struct ath11k_pdev_wmi *wmi = ar->wmi;
+	struct wmi_delba_send_cmd *cmd;
+	struct sk_buff *skb;
+	int ret;
+
+	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
+	if (!skb)
+		return -ENOMEM;
+
+	cmd = (struct wmi_delba_send_cmd *)skb->data;
+	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_DELBA_SEND_CMD) |
+			FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
+	cmd->vdev_id = vdev_id;
+	ether_addr_copy(cmd->peer_macaddr.addr, mac);
+	cmd->tid = tid;
+	cmd->initiator = initiator;
+	cmd->reasoncode = reason;
+
+	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
+		   "wmi delba send vdev_id 0x%X mac_addr %pM tid %u initiator %u reason %u\n",
+		   vdev_id, mac, tid, initiator, reason);
+
+	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_DELBA_SEND_CMDID);
+
+	if (ret) {
+		ath11k_warn(ar->ab,
+			    "failed to send WMI_DELBA_SEND_CMDID cmd\n");
+		dev_kfree_skb(skb);
+	}
+
+	return ret;
+}
+
+int ath11k_wmi_addba_set_resp(struct ath11k *ar, u32 vdev_id, const u8 *mac,
+			      u32 tid, u32 status)
+{
+	struct ath11k_pdev_wmi *wmi = ar->wmi;
+	struct wmi_addba_setresponse_cmd *cmd;
+	struct sk_buff *skb;
+	int ret;
+
+	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
+	if (!skb)
+		return -ENOMEM;
+
+	cmd = (struct wmi_addba_setresponse_cmd *)skb->data;
+	cmd->tlv_header =
+		FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ADDBA_SETRESPONSE_CMD) |
+		FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
+	cmd->vdev_id = vdev_id;
+	ether_addr_copy(cmd->peer_macaddr.addr, mac);
+	cmd->tid = tid;
+	cmd->statuscode = status;
+
+	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
+		   "wmi addba set resp vdev_id 0x%X mac_addr %pM tid %u status %u\n",
+		   vdev_id, mac, tid, status);
+
+	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_ADDBA_SET_RESP_CMDID);
+
+	if (ret) {
+		ath11k_warn(ar->ab,
+			    "failed to send WMI_ADDBA_SET_RESP_CMDID cmd\n");
+		dev_kfree_skb(skb);
+	}
+
+	return ret;
+}
+
+int ath11k_wmi_addba_send(struct ath11k *ar, u32 vdev_id, const u8 *mac,
+			  u32 tid, u32 buf_size)
+{
+	struct ath11k_pdev_wmi *wmi = ar->wmi;
+	struct wmi_addba_send_cmd *cmd;
+	struct sk_buff *skb;
+	int ret;
+
+	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
+	if (!skb)
+		return -ENOMEM;
+
+	cmd = (struct wmi_addba_send_cmd *)skb->data;
+	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ADDBA_SEND_CMD) |
+		FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
+	cmd->vdev_id = vdev_id;
+	ether_addr_copy(cmd->peer_macaddr.addr, mac);
+	cmd->tid = tid;
+	cmd->buffersize = buf_size;
+
+	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
+		   "wmi addba send vdev_id 0x%X mac_addr %pM tid %u bufsize %u\n",
+		   vdev_id, mac, tid, buf_size);
+
+	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_ADDBA_SEND_CMDID);
+
+	if (ret) {
+		ath11k_warn(ar->ab,
+			    "failed to send WMI_ADDBA_SEND_CMDID cmd\n");
+		dev_kfree_skb(skb);
+	}
+
+	return ret;
+}
+
+int ath11k_wmi_addba_clear_resp(struct ath11k *ar, u32 vdev_id, const u8 *mac)
+{
+	struct ath11k_pdev_wmi *wmi = ar->wmi;
+	struct wmi_addba_clear_resp_cmd *cmd;
+	struct sk_buff *skb;
+	int ret;
+
+	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
+	if (!skb)
+		return -ENOMEM;
+
+	cmd = (struct wmi_addba_clear_resp_cmd *)skb->data;
+	cmd->tlv_header =
+		FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ADDBA_CLEAR_RESP_CMD) |
+		FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
+	cmd->vdev_id = vdev_id;
+	ether_addr_copy(cmd->peer_macaddr.addr, mac);
+
+	ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
+		   "wmi addba clear resp vdev_id 0x%X mac_addr %pM\n",
+		   vdev_id, mac);
+
+	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_ADDBA_CLEAR_RESP_CMDID);
+
+	if (ret) {
+		ath11k_warn(ar->ab,
+			    "failed to send WMI_ADDBA_CLEAR_RESP_CMDID cmd\n");
+		dev_kfree_skb(skb);
+	}
+
+	return ret;
+}
+
 int ath11k_wmi_pdev_peer_pktlog_filter(struct ath11k *ar, u8 *addr, u8 enable)
 {
 	struct ath11k_pdev_wmi *wmi = ar->wmi;
@@ -2779,7 +2919,7 @@ int ath11k_wmi_send_bss_color_change_enable_cmd(struct ath11k *ar, u32 vdev_id,
 	ret = ath11k_wmi_cmd_send(wmi, skb,
 				  WMI_BSS_COLOR_CHANGE_ENABLE_CMDID);
 	if (ret) {
-		ath11k_warn(ab, "Failed to send WMI_TWT_DIeABLE_CMDID");
+		ath11k_warn(ab, "Failed to send WMI_BSS_COLOR_CHANGE_ENABLE_CMDID");
 		dev_kfree_skb(skb);
 	}
 	return ret;
@@ -3105,7 +3245,7 @@ int ath11k_wmi_cmd_init(struct ath11k_base *ab)
 	config.beacon_tx_offload_max_vdev = ab->num_radios * TARGET_MAX_BCN_OFFLD;
 	config.rx_batchmode = TARGET_RX_BATCHMODE;
 	config.peer_map_unmap_v2_support = 1;
-	config.twt_ap_pdev_count = 2;
+	config.twt_ap_pdev_count = ab->num_radios;
 	config.twt_ap_sta_count = 1000;
 
 	memcpy(&wmi_sc->wlan_resource_config, &config, sizeof(config));
@@ -3740,8 +3880,9 @@ static int wmi_process_mgmt_tx_comp(struct ath11k *ar, u32 desc_id,
 
 	ieee80211_tx_status_irqsafe(ar->hw, msdu);
 
-	WARN_ON_ONCE(atomic_read(&ar->num_pending_mgmt_tx) == 0);
-	atomic_dec(&ar->num_pending_mgmt_tx);
+	/* WARN when we received this event without doing any mgmt tx */
+	if (atomic_dec_if_positive(&ar->num_pending_mgmt_tx) < 0)
+		WARN_ON_ONCE(1);
 
 	return 0;
 }
@@ -4851,7 +4992,7 @@ static int ath11k_wmi_tlv_rdy_parse(struct ath11k_base *ab, u16 tag, u16 len,
 				    const void *ptr, void *data)
 {
 	struct wmi_tlv_rdy_parse *rdy_parse = data;
-	struct wmi_ready_event *fixed_param;
+	struct wmi_ready_event fixed_param;
 	struct wmi_mac_addr *addr_list;
 	struct ath11k_pdev *pdev;
 	u32 num_mac_addr;
@@ -4859,11 +5000,16 @@ static int ath11k_wmi_tlv_rdy_parse(struct ath11k_base *ab, u16 tag, u16 len,
 
 	switch (tag) {
 	case WMI_TAG_READY_EVENT:
-		fixed_param = (struct wmi_ready_event *)ptr;
-		ab->wlan_init_status = fixed_param->status;
-		rdy_parse->num_extra_mac_addr = fixed_param->num_extra_mac_addr;
-
-		ether_addr_copy(ab->mac_addr, fixed_param->mac_addr.addr);
+		memset(&fixed_param, 0, sizeof(fixed_param));
+		memcpy(&fixed_param, (struct wmi_ready_event *)ptr,
+		       min_t(u16, sizeof(fixed_param), len));
+		ab->wlan_init_status = fixed_param.ready_event_min.status;
+		rdy_parse->num_extra_mac_addr =
+			fixed_param.ready_event_min.num_extra_mac_addr;
+
+		ether_addr_copy(ab->mac_addr,
+				fixed_param.ready_event_min.mac_addr.addr);
+		ab->pktlog_defs_checksum = fixed_param.pktlog_defs_checksum;
 		ab->wmi_ready = true;
 		break;
 	case WMI_TAG_ARRAY_FIXED_STRUCT:
diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h
index 510f9c6bc1d7..ba05935b715a 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.h
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
@@ -2345,7 +2345,7 @@ struct wmi_mac_addr {
 	} __packed;
 } __packed;
 
-struct wmi_ready_event {
+struct wmi_ready_event_min {
 	struct wmi_abi_version fw_abi_vers;
 	struct wmi_mac_addr mac_addr;
 	u32 status;
@@ -2355,6 +2355,12 @@ struct wmi_ready_event {
 	u32 num_extra_peers;
 } __packed;
 
+struct wmi_ready_event {
+	struct wmi_ready_event_min ready_event_min;
+	u32 max_ast_index;
+	u32 pktlog_defs_checksum;
+} __packed;
+
 struct wmi_service_available_event {
 	u32 wmi_service_segment_offset;
 	u32 wmi_service_segment_bitmap[WMI_SERVICE_SEGMENT_BM_SIZE32];
@@ -3649,6 +3655,37 @@ struct wmi_therm_throt_level_config_info {
 	u32 prio;
 } __packed;
 
+struct wmi_delba_send_cmd {
+	u32 tlv_header;
+	u32 vdev_id;
+	struct wmi_mac_addr peer_macaddr;
+	u32 tid;
+	u32 initiator;
+	u32 reasoncode;
+} __packed;
+
+struct wmi_addba_setresponse_cmd {
+	u32 tlv_header;
+	u32 vdev_id;
+	struct wmi_mac_addr peer_macaddr;
+	u32 tid;
+	u32 statuscode;
+} __packed;
+
+struct wmi_addba_send_cmd {
+	u32 tlv_header;
+	u32 vdev_id;
+	struct wmi_mac_addr peer_macaddr;
+	u32 tid;
+	u32 buffersize;
+} __packed;
+
+struct wmi_addba_clear_resp_cmd {
+	u32 tlv_header;
+	u32 vdev_id;
+	struct wmi_mac_addr peer_macaddr;
+} __packed;
+
 struct wmi_pdev_pktlog_filter_info {
 	u32 tlv_header;
 	struct wmi_mac_addr peer_macaddr;
@@ -4822,6 +4859,13 @@ int ath11k_wmi_send_scan_chan_list_cmd(struct ath11k *ar,
 				       struct scan_chan_list_params *chan_list);
 int ath11k_wmi_send_dfs_phyerr_offload_enable_cmd(struct ath11k *ar,
 						  u32 pdev_id);
+int ath11k_wmi_addba_clear_resp(struct ath11k *ar, u32 vdev_id, const u8 *mac);
+int ath11k_wmi_addba_send(struct ath11k *ar, u32 vdev_id, const u8 *mac,
+			  u32 tid, u32 buf_size);
+int ath11k_wmi_addba_set_resp(struct ath11k *ar, u32 vdev_id, const u8 *mac,
+			      u32 tid, u32 status);
+int ath11k_wmi_delba_send(struct ath11k *ar, u32 vdev_id, const u8 *mac,
+			  u32 tid, u32 initiator, u32 reason);
 int ath11k_wmi_send_bcn_offload_control_cmd(struct ath11k *ar,
 					    u32 vdev_id, u32 bcn_ctrl_op);
 int
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index dd0c32379375..4ed21dad6a8e 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -612,6 +612,11 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
 			hif_dev->remain_skb = nskb;
 			spin_unlock(&hif_dev->rx_lock);
 		} else {
+			if (pool_index == MAX_PKT_NUM_IN_TRANSFER) {
+				dev_err(&hif_dev->udev->dev,
+					"ath9k_htc: over RX MAX_PKT_NUM\n");
+				goto err;
+			}
 			nskb = __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC);
 			if (!nskb) {
 				dev_err(&hif_dev->udev->dev,
@@ -638,9 +643,9 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
 
 static void ath9k_hif_usb_rx_cb(struct urb *urb)
 {
-	struct sk_buff *skb = (struct sk_buff *) urb->context;
-	struct hif_device_usb *hif_dev =
-		usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
+	struct rx_buf *rx_buf = (struct rx_buf *)urb->context;
+	struct hif_device_usb *hif_dev = rx_buf->hif_dev;
+	struct sk_buff *skb = rx_buf->skb;
 	int ret;
 
 	if (!skb)
@@ -680,14 +685,15 @@ static void ath9k_hif_usb_rx_cb(struct urb *urb)
 	return;
 free:
 	kfree_skb(skb);
+	kfree(rx_buf);
 }
 
 static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
 {
-	struct sk_buff *skb = (struct sk_buff *) urb->context;
+	struct rx_buf *rx_buf = (struct rx_buf *)urb->context;
+	struct hif_device_usb *hif_dev = rx_buf->hif_dev;
+	struct sk_buff *skb = rx_buf->skb;
 	struct sk_buff *nskb;
-	struct hif_device_usb *hif_dev =
-		usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
 	int ret;
 
 	if (!skb)
@@ -745,6 +751,7 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
 	return;
 free:
 	kfree_skb(skb);
+	kfree(rx_buf);
 	urb->context = NULL;
 }
 
@@ -790,7 +797,7 @@ static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev)
 	init_usb_anchor(&hif_dev->mgmt_submitted);
 
 	for (i = 0; i < MAX_TX_URB_NUM; i++) {
-		tx_buf = kzalloc(sizeof(struct tx_buf), GFP_KERNEL);
+		tx_buf = kzalloc(sizeof(*tx_buf), GFP_KERNEL);
 		if (!tx_buf)
 			goto err;
 
@@ -827,8 +834,9 @@ static void ath9k_hif_usb_dealloc_rx_urbs(struct hif_device_usb *hif_dev)
 
 static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev)
 {
-	struct urb *urb = NULL;
+	struct rx_buf *rx_buf = NULL;
 	struct sk_buff *skb = NULL;
+	struct urb *urb = NULL;
 	int i, ret;
 
 	init_usb_anchor(&hif_dev->rx_submitted);
@@ -836,6 +844,12 @@ static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev)
 
 	for (i = 0; i < MAX_RX_URB_NUM; i++) {
 
+		rx_buf = kzalloc(sizeof(*rx_buf), GFP_KERNEL);
+		if (!rx_buf) {
+			ret = -ENOMEM;
+			goto err_rxb;
+		}
+
 		/* Allocate URB */
 		urb = usb_alloc_urb(0, GFP_KERNEL);
 		if (urb == NULL) {
@@ -850,11 +864,14 @@ static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev)
 			goto err_skb;
 		}
 
+		rx_buf->hif_dev = hif_dev;
+		rx_buf->skb = skb;
+
 		usb_fill_bulk_urb(urb, hif_dev->udev,
 				  usb_rcvbulkpipe(hif_dev->udev,
 						  USB_WLAN_RX_PIPE),
 				  skb->data, MAX_RX_BUF_SIZE,
-				  ath9k_hif_usb_rx_cb, skb);
+				  ath9k_hif_usb_rx_cb, rx_buf);
 
 		/* Anchor URB */
 		usb_anchor_urb(urb, &hif_dev->rx_submitted);
@@ -880,6 +897,8 @@ static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev)
 err_skb:
 	usb_free_urb(urb);
 err_urb:
+	kfree(rx_buf);
+err_rxb:
 	ath9k_hif_usb_dealloc_rx_urbs(hif_dev);
 	return ret;
 }
@@ -891,14 +910,21 @@ static void ath9k_hif_usb_dealloc_reg_in_urbs(struct hif_device_usb *hif_dev)
 
 static int ath9k_hif_usb_alloc_reg_in_urbs(struct hif_device_usb *hif_dev)
 {
-	struct urb *urb = NULL;
+	struct rx_buf *rx_buf = NULL;
 	struct sk_buff *skb = NULL;
+	struct urb *urb = NULL;
 	int i, ret;
 
 	init_usb_anchor(&hif_dev->reg_in_submitted);
 
 	for (i = 0; i < MAX_REG_IN_URB_NUM; i++) {
 
+		rx_buf = kzalloc(sizeof(*rx_buf), GFP_KERNEL);
+		if (!rx_buf) {
+			ret = -ENOMEM;
+			goto err_rxb;
+		}
+
 		/* Allocate URB */
 		urb = usb_alloc_urb(0, GFP_KERNEL);
 		if (urb == NULL) {
@@ -913,11 +939,14 @@ static int ath9k_hif_usb_alloc_reg_in_urbs(struct hif_device_usb *hif_dev)
 			goto err_skb;
 		}
 
+		rx_buf->hif_dev = hif_dev;
+		rx_buf->skb = skb;
+
 		usb_fill_int_urb(urb, hif_dev->udev,
 				  usb_rcvintpipe(hif_dev->udev,
 						  USB_REG_IN_PIPE),
 				  skb->data, MAX_REG_IN_BUF_SIZE,
-				  ath9k_hif_usb_reg_in_cb, skb, 1);
+				  ath9k_hif_usb_reg_in_cb, rx_buf, 1);
 
 		/* Anchor URB */
 		usb_anchor_urb(urb, &hif_dev->reg_in_submitted);
@@ -943,6 +972,8 @@ static int ath9k_hif_usb_alloc_reg_in_urbs(struct hif_device_usb *hif_dev)
 err_skb:
 	usb_free_urb(urb);
 err_urb:
+	kfree(rx_buf);
+err_rxb:
 	ath9k_hif_usb_dealloc_reg_in_urbs(hif_dev);
 	return ret;
 }
@@ -973,7 +1004,7 @@ static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev)
 	return -ENOMEM;
 }
 
-static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev)
+void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev)
 {
 	usb_kill_anchored_urbs(&hif_dev->regout_submitted);
 	ath9k_hif_usb_dealloc_reg_in_urbs(hif_dev);
@@ -1341,8 +1372,9 @@ static void ath9k_hif_usb_disconnect(struct usb_interface *interface)
 
 	if (hif_dev->flags & HIF_USB_READY) {
 		ath9k_htc_hw_deinit(hif_dev->htc_handle, unplugged);
-		ath9k_htc_hw_free(hif_dev->htc_handle);
 		ath9k_hif_usb_dev_deinit(hif_dev);
+		ath9k_destoy_wmi(hif_dev->htc_handle->drv_priv);
+		ath9k_htc_hw_free(hif_dev->htc_handle);
 	}
 
 	usb_set_intfdata(interface, NULL);
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h
index 7846916aa01d..5985aa15ca93 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.h
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.h
@@ -86,6 +86,11 @@ struct tx_buf {
 	struct list_head list;
 };
 
+struct rx_buf {
+	struct sk_buff *skb;
+	struct hif_device_usb *hif_dev;
+};
+
 #define HIF_USB_TX_STOP  BIT(0)
 #define HIF_USB_TX_FLUSH BIT(1)
 
@@ -133,5 +138,6 @@ struct hif_device_usb {
 
 int ath9k_hif_usb_init(void);
 void ath9k_hif_usb_exit(void);
+void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev);
 
 #endif /* HTC_USB_H */
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index d961095ab01f..40a065028ebe 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -931,8 +931,9 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv,
 int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
 			   u16 devid, char *product, u32 drv_info)
 {
-	struct ieee80211_hw *hw;
+	struct hif_device_usb *hif_dev;
 	struct ath9k_htc_priv *priv;
+	struct ieee80211_hw *hw;
 	int ret;
 
 	hw = ieee80211_alloc_hw(sizeof(struct ath9k_htc_priv), &ath9k_htc_ops);
@@ -967,7 +968,10 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
 	return 0;
 
 err_init:
-	ath9k_deinit_wmi(priv);
+	ath9k_stop_wmi(priv);
+	hif_dev = (struct hif_device_usb *)htc_handle->hif_dev;
+	ath9k_hif_usb_dealloc_urbs(hif_dev);
+	ath9k_destoy_wmi(priv);
 err_free:
 	ieee80211_free_hw(hw);
 	return ret;
@@ -982,7 +986,7 @@ void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug)
 			htc_handle->drv_priv->ah->ah_flags |= AH_UNPLUGGED;
 
 		ath9k_deinit_device(htc_handle->drv_priv);
-		ath9k_deinit_wmi(htc_handle->drv_priv);
+		ath9k_stop_wmi(htc_handle->drv_priv);
 		ieee80211_free_hw(htc_handle->drv_priv->hw);
 	}
 }
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c
index d091c8ebdcf0..d2e062eaf561 100644
--- a/drivers/net/wireless/ath/ath9k/htc_hst.c
+++ b/drivers/net/wireless/ath/ath9k/htc_hst.c
@@ -113,6 +113,9 @@ static void htc_process_conn_rsp(struct htc_target *target,
 
 	if (svc_rspmsg->status == HTC_SERVICE_SUCCESS) {
 		epid = svc_rspmsg->endpoint_id;
+		if (epid < 0 || epid >= ENDPOINT_MAX)
+			return;
+
 		service_id = be16_to_cpu(svc_rspmsg->service_id);
 		max_msglen = be16_to_cpu(svc_rspmsg->max_msg_len);
 		endpoint = &target->endpoint[epid];
@@ -170,7 +173,6 @@ static int htc_config_pipe_credits(struct htc_target *target)
 	time_left = wait_for_completion_timeout(&target->cmd_wait, HZ);
 	if (!time_left) {
 		dev_err(target->dev, "HTC credit config timeout\n");
-		kfree_skb(skb);
 		return -ETIMEDOUT;
 	}
 
@@ -206,7 +208,6 @@ static int htc_setup_complete(struct htc_target *target)
 	time_left = wait_for_completion_timeout(&target->cmd_wait, HZ);
 	if (!time_left) {
 		dev_err(target->dev, "HTC start timeout\n");
-		kfree_skb(skb);
 		return -ETIMEDOUT;
 	}
 
@@ -279,7 +280,6 @@ int htc_connect_service(struct htc_target *target,
 	if (!time_left) {
 		dev_err(target->dev, "Service connection timeout for: %d\n",
 			service_connreq->service_id);
-		kfree_skb(skb);
 		return -ETIMEDOUT;
 	}
 
diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c
index cdc146091194..e7a3127395be 100644
--- a/drivers/net/wireless/ath/ath9k/wmi.c
+++ b/drivers/net/wireless/ath/ath9k/wmi.c
@@ -112,14 +112,17 @@ struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv)
 	return wmi;
 }
 
-void ath9k_deinit_wmi(struct ath9k_htc_priv *priv)
+void ath9k_stop_wmi(struct ath9k_htc_priv *priv)
 {
 	struct wmi *wmi = priv->wmi;
 
 	mutex_lock(&wmi->op_mutex);
 	wmi->stopped = true;
 	mutex_unlock(&wmi->op_mutex);
+}
 
+void ath9k_destoy_wmi(struct ath9k_htc_priv *priv)
+{
 	kfree(priv->wmi);
 }
 
@@ -336,7 +339,6 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
 		ath_dbg(common, WMI, "Timeout waiting for WMI command: %s\n",
 			wmi_cmd_to_name(cmd_id));
 		mutex_unlock(&wmi->op_mutex);
-		kfree_skb(skb);
 		return -ETIMEDOUT;
 	}
 
diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h
index 380175d5ecd7..d8b912206232 100644
--- a/drivers/net/wireless/ath/ath9k/wmi.h
+++ b/drivers/net/wireless/ath/ath9k/wmi.h
@@ -179,7 +179,6 @@ struct wmi {
 };
 
 struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv);
-void ath9k_deinit_wmi(struct ath9k_htc_priv *priv);
 int ath9k_wmi_connect(struct htc_target *htc, struct wmi *wmi,
 		      enum htc_endpoint_id *wmi_ctrl_epid);
 int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
@@ -189,6 +188,8 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
 void ath9k_wmi_event_tasklet(unsigned long data);
 void ath9k_fatal_work(struct work_struct *work);
 void ath9k_wmi_event_drain(struct ath9k_htc_priv *priv);
+void ath9k_stop_wmi(struct ath9k_htc_priv *priv);
+void ath9k_destoy_wmi(struct ath9k_htc_priv *priv);
 
 #define WMI_CMD(_wmi_cmd)						\
 	do {								\
diff --git a/drivers/net/wireless/broadcom/b43legacy/xmit.c b/drivers/net/wireless/broadcom/b43legacy/xmit.c
index e9b23c2e5bd4..efd63f4ce74f 100644
--- a/drivers/net/wireless/broadcom/b43legacy/xmit.c
+++ b/drivers/net/wireless/broadcom/b43legacy/xmit.c
@@ -558,6 +558,7 @@ void b43legacy_rx(struct b43legacy_wldev *dev,
 	default:
 		b43legacywarn(dev->wl, "Unexpected value for chanstat (0x%X)\n",
 		       chanstat);
+		goto drop;
 	}
 
 	memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index b684a5b6d904..22a17ae09e94 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -961,7 +961,7 @@ static const struct sdio_device_id brcmf_sdmmc_ids[] = {
 	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43340),
 	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43341),
 	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43362),
- 	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43364),
+	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43364),
 	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4335_4339),
 	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4339),
 	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43430),
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/commonring.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/commonring.c
index 49db54d23e03..e44236cb210e 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/commonring.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/commonring.c
@@ -180,14 +180,8 @@ brcmf_commonring_reserve_for_write_multiple(struct brcmf_commonring *commonring,
 
 int brcmf_commonring_write_complete(struct brcmf_commonring *commonring)
 {
-	void *address;
-
-	address = commonring->buf_addr;
-	address += (commonring->f_ptr * commonring->item_len);
-	if (commonring->f_ptr > commonring->w_ptr) {
-		address = commonring->buf_addr;
+	if (commonring->f_ptr > commonring->w_ptr)
 		commonring->f_ptr = 0;
-	}
 
 	commonring->f_ptr = commonring->w_ptr;
 
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
index 23627c953a5e..436f501be937 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
@@ -729,9 +729,18 @@ static int brcmf_net_mon_stop(struct net_device *ndev)
 	return err;
 }
 
+static netdev_tx_t brcmf_net_mon_start_xmit(struct sk_buff *skb,
+					    struct net_device *ndev)
+{
+	dev_kfree_skb_any(skb);
+
+	return NETDEV_TX_OK;
+}
+
 static const struct net_device_ops brcmf_netdev_ops_mon = {
 	.ndo_open = brcmf_net_mon_open,
 	.ndo_stop = brcmf_net_mon_stop,
+	.ndo_start_xmit = brcmf_net_mon_start_xmit,
 };
 
 int brcmf_net_mon_attach(struct brcmf_if *ifp)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
index 5da0dda0d899..0dcefbd0c000 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
@@ -285,13 +285,14 @@ void brcmf_feat_attach(struct brcmf_pub *drvr)
 	if (!err)
 		ifp->drvr->feat_flags |= BIT(BRCMF_FEAT_SCAN_RANDOM_MAC);
 
+	brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_FWSUP, "sup_wpa");
+
 	if (drvr->settings->feature_disable) {
 		brcmf_dbg(INFO, "Features: 0x%02x, disable: 0x%02x\n",
 			  ifp->drvr->feat_flags,
 			  drvr->settings->feature_disable);
 		ifp->drvr->feat_flags &= ~drvr->settings->feature_disable;
 	}
-	brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_FWSUP, "sup_wpa");
 
 	brcmf_feat_firmware_overrides(drvr);
 
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c
index 8e8b685cfe09..648efcbc819f 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c
@@ -1431,6 +1431,7 @@ int brcms_up(struct brcms_info *wl)
  * precondition: perimeter lock has been acquired
  */
 void brcms_down(struct brcms_info *wl)
+	__must_hold(&wl->lock)
 {
 	uint callbacks, ret_val = 0;
 
@@ -1717,6 +1718,7 @@ int brcms_check_firmwares(struct brcms_info *wl)
  * precondition: perimeter lock has been acquired
  */
 bool brcms_rfkill_set_hw_state(struct brcms_info *wl)
+	__must_hold(&wl->lock)
 {
 	bool blocked = brcms_c_check_radio_disabled(wl->wlc);
 
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c
index 7f2c15c799d2..d88f8d456b94 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c
@@ -3768,17 +3768,14 @@ static void brcms_c_set_ps_ctrl(struct brcms_c_info *wlc)
  * Write this BSS config's MAC address to core.
  * Updates RXE match engine.
  */
-static int brcms_c_set_mac(struct brcms_bss_cfg *bsscfg)
+static void brcms_c_set_mac(struct brcms_bss_cfg *bsscfg)
 {
-	int err = 0;
 	struct brcms_c_info *wlc = bsscfg->wlc;
 
 	/* enter the MAC addr into the RXE match registers */
 	brcms_c_set_addrmatch(wlc, RCM_MAC_OFFSET, wlc->pub->cur_etheraddr);
 
 	brcms_c_ampdu_macaddr_upd(wlc);
-
-	return err;
 }
 
 /* Write the BSS config's BSSID address to core (set_bssid in d11procs.tcl).
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/stf.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/stf.c
index 0ab865de1491..79d4a7a4da8b 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/stf.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/stf.c
@@ -304,9 +304,8 @@ int brcms_c_stf_txchain_set(struct brcms_c_info *wlc, s32 int_val, bool force)
  * update wlc->stf->ss_opmode which represents the operational stf_ss mode
  * we're using
  */
-int brcms_c_stf_ss_update(struct brcms_c_info *wlc, struct brcms_band *band)
+void brcms_c_stf_ss_update(struct brcms_c_info *wlc, struct brcms_band *band)
 {
-	int ret_code = 0;
 	u8 prev_stf_ss;
 	u8 upd_stf_ss;
 
@@ -325,7 +324,7 @@ int brcms_c_stf_ss_update(struct brcms_c_info *wlc, struct brcms_band *band)
 				    PHY_TXC1_MODE_SISO : PHY_TXC1_MODE_CDD;
 	} else {
 		if (wlc->band != band)
-			return ret_code;
+			return;
 		upd_stf_ss = (wlc->stf->txstreams == 1) ?
 				PHY_TXC1_MODE_SISO : band->band_stf_ss_mode;
 	}
@@ -333,8 +332,6 @@ int brcms_c_stf_ss_update(struct brcms_c_info *wlc, struct brcms_band *band)
 		wlc->stf->ss_opmode = upd_stf_ss;
 		brcms_b_band_stf_ss_set(wlc->hw, upd_stf_ss);
 	}
-
-	return ret_code;
 }
 
 int brcms_c_stf_attach(struct brcms_c_info *wlc)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/stf.h b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/stf.h
index ba9493009a33..aa4ab53bf634 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/stf.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/stf.h
@@ -25,7 +25,7 @@ void brcms_c_stf_detach(struct brcms_c_info *wlc);
 void brcms_c_tempsense_upd(struct brcms_c_info *wlc);
 void brcms_c_stf_ss_algo_channel_get(struct brcms_c_info *wlc,
 				     u16 *ss_algo_channel, u16 chanspec);
-int brcms_c_stf_ss_update(struct brcms_c_info *wlc, struct brcms_band *band);
+void brcms_c_stf_ss_update(struct brcms_c_info *wlc, struct brcms_band *band);
 void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc);
 int brcms_c_stf_txchain_set(struct brcms_c_info *wlc, s32 int_val, bool force);
 bool brcms_c_stf_stbc_rx_set(struct brcms_c_info *wlc, s32 int_val);
diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2200.c b/drivers/net/wireless/intel/ipw2x00/ipw2200.c
index 60b5e08dd6df..923be3781c92 100644
--- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c
@@ -7042,23 +7042,22 @@ static int ipw_qos_association(struct ipw_priv *priv,
 * off the network from the associated setting, adjust the QoS
 * setting
 */
-static int ipw_qos_association_resp(struct ipw_priv *priv,
+static void ipw_qos_association_resp(struct ipw_priv *priv,
 				    struct libipw_network *network)
 {
-	int ret = 0;
 	unsigned long flags;
 	u32 size = sizeof(struct libipw_qos_parameters);
 	int set_qos_param = 0;
 
 	if ((priv == NULL) || (network == NULL) ||
 	    (priv->assoc_network == NULL))
-		return ret;
+		return;
 
 	if (!(priv->status & STATUS_ASSOCIATED))
-		return ret;
+		return;
 
 	if ((priv->ieee->iw_mode != IW_MODE_INFRA))
-		return ret;
+		return;
 
 	spin_lock_irqsave(&priv->ieee->lock, flags);
 	if (network->flags & NETWORK_HAS_QOS_PARAMETERS) {
@@ -7088,8 +7087,6 @@ static int ipw_qos_association_resp(struct ipw_priv *priv,
 
 	if (set_qos_param == 1)
 		schedule_work(&priv->qos_activate);
-
-	return ret;
 }
 
 static u32 ipw_qos_get_burst_duration(struct ipw_priv *priv)
@@ -10643,10 +10640,8 @@ static void ipw_bg_link_down(struct work_struct *work)
 	mutex_unlock(&priv->mutex);
 }
 
-static int ipw_setup_deferred_work(struct ipw_priv *priv)
+static void ipw_setup_deferred_work(struct ipw_priv *priv)
 {
-	int ret = 0;
-
 	init_waitqueue_head(&priv->wait_command_queue);
 	init_waitqueue_head(&priv->wait_state);
 
@@ -10680,8 +10675,6 @@ static int ipw_setup_deferred_work(struct ipw_priv *priv)
 
 	tasklet_init(&priv->irq_tasklet,
 		     ipw_irq_tasklet, (unsigned long)priv);
-
-	return ret;
 }
 
 static void shim__set_security(struct net_device *dev,
@@ -11662,11 +11655,7 @@ static int ipw_pci_probe(struct pci_dev *pdev,
 	IPW_DEBUG_INFO("pci_resource_len = 0x%08x\n", length);
 	IPW_DEBUG_INFO("pci_resource_base = %p\n", base);
 
-	err = ipw_setup_deferred_work(priv);
-	if (err) {
-		IPW_ERROR("Unable to setup deferred work\n");
-		goto out_iounmap;
-	}
+	ipw_setup_deferred_work(priv);
 
 	ipw_sw_reset(priv, 1);
 
diff --git a/drivers/net/wireless/intersil/hostap/hostap_proc.c b/drivers/net/wireless/intersil/hostap/hostap_proc.c
index a2ee4693eaed..97c270845fd1 100644
--- a/drivers/net/wireless/intersil/hostap/hostap_proc.c
+++ b/drivers/net/wireless/intersil/hostap/hostap_proc.c
@@ -149,6 +149,7 @@ static int prism2_bss_list_proc_show(struct seq_file *m, void *v)
 }
 
 static void *prism2_bss_list_proc_start(struct seq_file *m, loff_t *_pos)
+	__acquires(&local->lock)
 {
 	local_info_t *local = PDE_DATA(file_inode(m->file));
 	spin_lock_bh(&local->lock);
@@ -162,6 +163,7 @@ static void *prism2_bss_list_proc_next(struct seq_file *m, void *v, loff_t *_pos
 }
 
 static void prism2_bss_list_proc_stop(struct seq_file *m, void *v)
+	__releases(&local->lock)
 {
 	local_info_t *local = PDE_DATA(file_inode(m->file));
 	spin_unlock_bh(&local->lock);
diff --git a/drivers/net/wireless/intersil/orinoco/spectrum_cs.c b/drivers/net/wireless/intersil/orinoco/spectrum_cs.c
index b60048c95e0a..291ef97ed45e 100644
--- a/drivers/net/wireless/intersil/orinoco/spectrum_cs.c
+++ b/drivers/net/wireless/intersil/orinoco/spectrum_cs.c
@@ -278,12 +278,11 @@ static int
 spectrum_cs_suspend(struct pcmcia_device *link)
 {
 	struct orinoco_private *priv = link->priv;
-	int err = 0;
 
 	/* Mark the device as stopped, to block IO until later */
 	orinoco_down(priv);
 
-	return err;
+	return 0;
 }
 
 static int
diff --git a/drivers/net/wireless/intersil/p54/p54usb.c b/drivers/net/wireless/intersil/p54/p54usb.c
index b94764c88750..ff0e30c0c14c 100644
--- a/drivers/net/wireless/intersil/p54/p54usb.c
+++ b/drivers/net/wireless/intersil/p54/p54usb.c
@@ -61,6 +61,7 @@ static const struct usb_device_id p54u_table[] = {
 	{USB_DEVICE(0x0db0, 0x6826)},	/* MSI UB54G (MS-6826) */
 	{USB_DEVICE(0x107b, 0x55f2)},	/* Gateway WGU-210 (Gemtek) */
 	{USB_DEVICE(0x124a, 0x4023)},	/* Shuttle PN15, Airvast WM168g, IOGear GWU513 */
+	{USB_DEVICE(0x124a, 0x4026)},	/* AirVasT USB wireless device */
 	{USB_DEVICE(0x1435, 0x0210)},	/* Inventel UR054G */
 	{USB_DEVICE(0x15a9, 0x0002)},	/* Gemtek WUBI-100GW 802.11g */
 	{USB_DEVICE(0x1630, 0x0005)},	/* 2Wire 802.11g USB (v1) / Z-Com */
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 7fe8207db6ae..f1c08b31c564 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -1068,6 +1068,47 @@ static int hwsim_unicast_netgroup(struct mac80211_hwsim_data *data,
 	return res;
 }
 
+static void mac80211_hwsim_config_mac_nl(struct ieee80211_hw *hw,
+					 const u8 *addr, bool add)
+{
+	struct mac80211_hwsim_data *data = hw->priv;
+	u32 _portid = READ_ONCE(data->wmediumd);
+	struct sk_buff *skb;
+	void *msg_head;
+
+	if (!_portid && !hwsim_virtio_enabled)
+		return;
+
+	skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_ATOMIC);
+	if (!skb)
+		return;
+
+	msg_head = genlmsg_put(skb, 0, 0, &hwsim_genl_family, 0,
+			       add ? HWSIM_CMD_ADD_MAC_ADDR :
+				     HWSIM_CMD_DEL_MAC_ADDR);
+	if (!msg_head) {
+		pr_debug("mac80211_hwsim: problem with msg_head\n");
+		goto nla_put_failure;
+	}
+
+	if (nla_put(skb, HWSIM_ATTR_ADDR_TRANSMITTER,
+		    ETH_ALEN, data->addresses[1].addr))
+		goto nla_put_failure;
+
+	if (nla_put(skb, HWSIM_ATTR_ADDR_RECEIVER, ETH_ALEN, addr))
+		goto nla_put_failure;
+
+	genlmsg_end(skb, msg_head);
+
+	if (hwsim_virtio_enabled)
+		hwsim_tx_virtio(data, skb);
+	else
+		hwsim_unicast_netgroup(data, skb, _portid);
+	return;
+nla_put_failure:
+	nlmsg_free(skb);
+}
+
 static inline u16 trans_tx_rate_flags_ieee2hwsim(struct ieee80211_tx_rate *rate)
 {
 	u16 result = 0;
@@ -1545,6 +1586,9 @@ static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw,
 		  vif->addr);
 	hwsim_set_magic(vif);
 
+	if (vif->type != NL80211_IFTYPE_MONITOR)
+		mac80211_hwsim_config_mac_nl(hw, vif->addr, true);
+
 	vif->cab_queue = 0;
 	vif->hw_queue[IEEE80211_AC_VO] = 0;
 	vif->hw_queue[IEEE80211_AC_VI] = 1;
@@ -1584,6 +1628,8 @@ static void mac80211_hwsim_remove_interface(
 		  vif->addr);
 	hwsim_check_magic(vif);
 	hwsim_clear_magic(vif);
+	if (vif->type != NL80211_IFTYPE_MONITOR)
+		mac80211_hwsim_config_mac_nl(hw, vif->addr, false);
 }
 
 static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
@@ -2104,6 +2150,8 @@ static void hw_scan_work(struct work_struct *work)
 		hwsim->hw_scan_vif = NULL;
 		hwsim->tmp_chan = NULL;
 		mutex_unlock(&hwsim->mutex);
+		mac80211_hwsim_config_mac_nl(hwsim->hw, hwsim->scan_addr,
+					     false);
 		return;
 	}
 
@@ -2177,6 +2225,7 @@ static int mac80211_hwsim_hw_scan(struct ieee80211_hw *hw,
 	memset(hwsim->survey_data, 0, sizeof(hwsim->survey_data));
 	mutex_unlock(&hwsim->mutex);
 
+	mac80211_hwsim_config_mac_nl(hw, hwsim->scan_addr, true);
 	wiphy_dbg(hw->wiphy, "hwsim hw_scan request\n");
 
 	ieee80211_queue_delayed_work(hwsim->hw, &hwsim->hw_scan, 0);
@@ -2220,6 +2269,7 @@ static void mac80211_hwsim_sw_scan(struct ieee80211_hw *hw,
 	pr_debug("hwsim sw_scan request, prepping stuff\n");
 
 	memcpy(hwsim->scan_addr, mac_addr, ETH_ALEN);
+	mac80211_hwsim_config_mac_nl(hw, hwsim->scan_addr, true);
 	hwsim->scanning = true;
 	memset(hwsim->survey_data, 0, sizeof(hwsim->survey_data));
 
@@ -2236,6 +2286,7 @@ static void mac80211_hwsim_sw_scan_complete(struct ieee80211_hw *hw,
 
 	pr_debug("hwsim sw_scan_complete\n");
 	hwsim->scanning = false;
+	mac80211_hwsim_config_mac_nl(hw, hwsim->scan_addr, false);
 	eth_zero_addr(hwsim->scan_addr);
 
 	mutex_unlock(&hwsim->mutex);
@@ -3669,9 +3720,9 @@ static int hwsim_new_radio_nl(struct sk_buff *msg, struct genl_info *info)
 	}
 
 	if (info->attrs[HWSIM_ATTR_RADIO_NAME]) {
-		hwname = kasprintf(GFP_KERNEL, "%.*s",
-				   nla_len(info->attrs[HWSIM_ATTR_RADIO_NAME]),
-				   (char *)nla_data(info->attrs[HWSIM_ATTR_RADIO_NAME]));
+		hwname = kstrndup((char *)nla_data(info->attrs[HWSIM_ATTR_RADIO_NAME]),
+				  nla_len(info->attrs[HWSIM_ATTR_RADIO_NAME]),
+				  GFP_KERNEL);
 		if (!hwname)
 			return -ENOMEM;
 		param.hwname = hwname;
@@ -3691,9 +3742,9 @@ static int hwsim_del_radio_nl(struct sk_buff *msg, struct genl_info *info)
 	if (info->attrs[HWSIM_ATTR_RADIO_ID]) {
 		idx = nla_get_u32(info->attrs[HWSIM_ATTR_RADIO_ID]);
 	} else if (info->attrs[HWSIM_ATTR_RADIO_NAME]) {
-		hwname = kasprintf(GFP_KERNEL, "%.*s",
-				   nla_len(info->attrs[HWSIM_ATTR_RADIO_NAME]),
-				   (char *)nla_data(info->attrs[HWSIM_ATTR_RADIO_NAME]));
+		hwname = kstrndup((char *)nla_data(info->attrs[HWSIM_ATTR_RADIO_NAME]),
+				  nla_len(info->attrs[HWSIM_ATTR_RADIO_NAME]),
+				  GFP_KERNEL);
 		if (!hwname)
 			return -ENOMEM;
 	} else
diff --git a/drivers/net/wireless/mac80211_hwsim.h b/drivers/net/wireless/mac80211_hwsim.h
index 28ade92adcb4..9dceed77c5d6 100644
--- a/drivers/net/wireless/mac80211_hwsim.h
+++ b/drivers/net/wireless/mac80211_hwsim.h
@@ -75,6 +75,12 @@ enum hwsim_tx_control_flags {
  * @HWSIM_CMD_DEL_RADIO: destroy a radio, reply is multicasted
  * @HWSIM_CMD_GET_RADIO: fetch information about existing radios, uses:
  *	%HWSIM_ATTR_RADIO_ID
+ * @HWSIM_CMD_ADD_MAC_ADDR: add a receive MAC address (given in the
+ *	%HWSIM_ATTR_ADDR_RECEIVER attribute) to a device identified by
+ *	%HWSIM_ATTR_ADDR_TRANSMITTER. This lets wmediumd forward frames
+ *	to this receiver address for a given station.
+ * @HWSIM_CMD_DEL_MAC_ADDR: remove the MAC address again, the attributes
+ *	are the same as to @HWSIM_CMD_ADD_MAC_ADDR.
  * @__HWSIM_CMD_MAX: enum limit
  */
 enum {
@@ -85,6 +91,8 @@ enum {
 	HWSIM_CMD_NEW_RADIO,
 	HWSIM_CMD_DEL_RADIO,
 	HWSIM_CMD_GET_RADIO,
+	HWSIM_CMD_ADD_MAC_ADDR,
+	HWSIM_CMD_DEL_MAC_ADDR,
 	__HWSIM_CMD_MAX,
 };
 #define HWSIM_CMD_MAX (_HWSIM_CMD_MAX - 1)
diff --git a/drivers/net/wireless/marvell/libertas/cmd.h b/drivers/net/wireless/marvell/libertas/cmd.h
index 80878561cb90..3c193074662b 100644
--- a/drivers/net/wireless/marvell/libertas/cmd.h
+++ b/drivers/net/wireless/marvell/libertas/cmd.h
@@ -76,7 +76,7 @@ void lbs_mac_event_disconnected(struct lbs_private *priv,
 
 /* Events */
 
-int lbs_process_event(struct lbs_private *priv, u32 event);
+void lbs_process_event(struct lbs_private *priv, u32 event);
 
 
 /* Actual commands */
diff --git a/drivers/net/wireless/marvell/libertas/cmdresp.c b/drivers/net/wireless/marvell/libertas/cmdresp.c
index b73d08381398..cb515c5584c1 100644
--- a/drivers/net/wireless/marvell/libertas/cmdresp.c
+++ b/drivers/net/wireless/marvell/libertas/cmdresp.c
@@ -220,9 +220,8 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len)
 	return ret;
 }
 
-int lbs_process_event(struct lbs_private *priv, u32 event)
+void lbs_process_event(struct lbs_private *priv, u32 event)
 {
-	int ret = 0;
 	struct cmd_header cmd;
 
 	switch (event) {
@@ -351,6 +350,4 @@ int lbs_process_event(struct lbs_private *priv, u32 event)
 		netdev_alert(priv->dev, "EVENT: unknown event id %d\n", event);
 		break;
 	}
-
-	return ret;
 }
diff --git a/drivers/net/wireless/marvell/libertas/mesh.c b/drivers/net/wireless/marvell/libertas/mesh.c
index 44c8a550da4c..f5b78257d551 100644
--- a/drivers/net/wireless/marvell/libertas/mesh.c
+++ b/drivers/net/wireless/marvell/libertas/mesh.c
@@ -828,10 +828,8 @@ static void lbs_persist_config_remove(struct net_device *dev)
  * Check mesh FW version and appropriately send the mesh start
  * command
  */
-int lbs_init_mesh(struct lbs_private *priv)
+void lbs_init_mesh(struct lbs_private *priv)
 {
-	int ret = 0;
-
 	/* Determine mesh_fw_ver from fwrelease and fwcapinfo */
 	/* 5.0.16p0 9.0.0.p0 is known to NOT support any mesh */
 	/* 5.110.22 have mesh command with 0xa3 command id */
@@ -870,8 +868,6 @@ int lbs_init_mesh(struct lbs_private *priv)
 
 	/* Stop meshing until interface is brought up */
 	lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_STOP, 1);
-
-	return ret;
 }
 
 void lbs_start_mesh(struct lbs_private *priv)
diff --git a/drivers/net/wireless/marvell/libertas/mesh.h b/drivers/net/wireless/marvell/libertas/mesh.h
index 1561018f226f..d49717b20c09 100644
--- a/drivers/net/wireless/marvell/libertas/mesh.h
+++ b/drivers/net/wireless/marvell/libertas/mesh.h
@@ -16,7 +16,7 @@
 
 struct net_device;
 
-int lbs_init_mesh(struct lbs_private *priv);
+void lbs_init_mesh(struct lbs_private *priv);
 void lbs_start_mesh(struct lbs_private *priv);
 int lbs_deinit_mesh(struct lbs_private *priv);
 
diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c
index dbb241106d8a..eb67b66b846b 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c
@@ -286,7 +286,7 @@ static int pearl_skb2rbd_attach(struct qtnf_pcie_pearl_state *ps, u16 index)
 	struct sk_buff *skb;
 	dma_addr_t paddr;
 
-	skb = __netdev_alloc_skb_ip_align(NULL, SKB_BUF_SIZE, GFP_ATOMIC);
+	skb = netdev_alloc_skb_ip_align(NULL, SKB_BUF_SIZE);
 	if (!skb) {
 		priv->rx_skb[index] = NULL;
 		return -ENOMEM;
diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/topaz_pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pcie/topaz_pcie.c
index dbf3c5fd751f..d1b850aa4657 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/pcie/topaz_pcie.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/topaz_pcie.c
@@ -247,7 +247,7 @@ topaz_skb2rbd_attach(struct qtnf_pcie_topaz_state *ts, u16 index, u32 wrap)
 	struct sk_buff *skb;
 	dma_addr_t paddr;
 
-	skb = __netdev_alloc_skb_ip_align(NULL, SKB_BUF_SIZE, GFP_ATOMIC);
+	skb = netdev_alloc_skb_ip_align(NULL, SKB_BUF_SIZE);
 	if (!skb) {
 		ts->base.rx_skb[index] = NULL;
 		return -ENOMEM;
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hal_btc.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hal_btc.c
index 680198280f8f..652d8ff9cccb 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hal_btc.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hal_btc.c
@@ -131,7 +131,7 @@ static bool rtl8723e_dm_bt_is_same_coexist_state(struct ieee80211_hw *hw)
 	    (rtlpriv->btcoexist.previous_state_h ==
 	     rtlpriv->btcoexist.cstate_h)) {
 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
-			 "[DM][BT], Coexist state do not chang!!\n");
+			 "[DM][BT], Coexist state do not change!!\n");
 		return true;
 	} else {
 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c
index 05c430b3489c..245da96dfddc 100644
--- a/drivers/net/wireless/realtek/rtw88/fw.c
+++ b/drivers/net/wireless/realtek/rtw88/fw.c
@@ -2,6 +2,8 @@
 /* Copyright(c) 2018-2019  Realtek Corporation
  */
 
+#include <linux/iopoll.h>
+
 #include "main.h"
 #include "coex.h"
 #include "fw.h"
@@ -193,8 +195,8 @@ static void rtw_fw_send_h2c_command(struct rtw_dev *rtwdev,
 	u8 box;
 	u8 box_state;
 	u32 box_reg, box_ex_reg;
-	u32 h2c_wait;
 	int idx;
+	int ret;
 
 	rtw_dbg(rtwdev, RTW_DBG_FW,
 		"send H2C content %02x%02x%02x%02x %02x%02x%02x%02x\n",
@@ -226,12 +228,11 @@ static void rtw_fw_send_h2c_command(struct rtw_dev *rtwdev,
 		goto out;
 	}
 
-	h2c_wait = 20;
-	do {
-		box_state = rtw_read8(rtwdev, REG_HMETFR);
-	} while ((box_state >> box) & 0x1 && --h2c_wait > 0);
+	ret = read_poll_timeout(rtw_read8, box_state,
+				!((box_state >> box) & 0x1), 100, 3000, false,
+				rtwdev, REG_HMETFR);
 
-	if (!h2c_wait) {
+	if (ret) {
 		rtw_err(rtwdev, "failed to send h2c command\n");
 		goto out;
 	}
@@ -630,8 +631,8 @@ void rtw_fw_set_pg_info(struct rtw_dev *rtwdev)
 	rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
 }
 
-u8 rtw_get_rsvd_page_probe_req_location(struct rtw_dev *rtwdev,
-					struct cfg80211_ssid *ssid)
+static u8 rtw_get_rsvd_page_probe_req_location(struct rtw_dev *rtwdev,
+					       struct cfg80211_ssid *ssid)
 {
 	struct rtw_rsvd_page *rsvd_pkt;
 	u8 location = 0;
@@ -647,8 +648,8 @@ u8 rtw_get_rsvd_page_probe_req_location(struct rtw_dev *rtwdev,
 	return location;
 }
 
-u16 rtw_get_rsvd_page_probe_req_size(struct rtw_dev *rtwdev,
-				     struct cfg80211_ssid *ssid)
+static u16 rtw_get_rsvd_page_probe_req_size(struct rtw_dev *rtwdev,
+					    struct cfg80211_ssid *ssid)
 {
 	struct rtw_rsvd_page *rsvd_pkt;
 	u16 size = 0;
diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c
index d7d02e4c0184..a2e6ef4ad9ee 100644
--- a/drivers/net/wireless/realtek/rtw88/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c
@@ -754,6 +754,37 @@ static int rtw_ops_set_bitrate_mask(struct ieee80211_hw *hw,
 	return 0;
 }
 
+static int rtw_ops_set_antenna(struct ieee80211_hw *hw,
+			       u32 tx_antenna,
+			       u32 rx_antenna)
+{
+	struct rtw_dev *rtwdev = hw->priv;
+	struct rtw_chip_info *chip = rtwdev->chip;
+	int ret;
+
+	if (!chip->ops->set_antenna)
+		return -EOPNOTSUPP;
+
+	mutex_lock(&rtwdev->mutex);
+	ret = chip->ops->set_antenna(rtwdev, tx_antenna, rx_antenna);
+	mutex_unlock(&rtwdev->mutex);
+
+	return ret;
+}
+
+static int rtw_ops_get_antenna(struct ieee80211_hw *hw,
+			       u32 *tx_antenna,
+			       u32 *rx_antenna)
+{
+	struct rtw_dev *rtwdev = hw->priv;
+	struct rtw_hal *hal = &rtwdev->hal;
+
+	*tx_antenna = hal->antenna_tx;
+	*rx_antenna = hal->antenna_rx;
+
+	return 0;
+}
+
 #ifdef CONFIG_PM
 static int rtw_ops_suspend(struct ieee80211_hw *hw,
 			   struct cfg80211_wowlan *wowlan)
@@ -815,6 +846,8 @@ const struct ieee80211_ops rtw_ops = {
 	.sta_statistics		= rtw_ops_sta_statistics,
 	.flush			= rtw_ops_flush,
 	.set_bitrate_mask	= rtw_ops_set_bitrate_mask,
+	.set_antenna		= rtw_ops_set_antenna,
+	.get_antenna		= rtw_ops_get_antenna,
 #ifdef CONFIG_PM
 	.suspend		= rtw_ops_suspend,
 	.resume			= rtw_ops_resume,
diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
index 7640e97706f5..1e1d2c774287 100644
--- a/drivers/net/wireless/realtek/rtw88/main.c
+++ b/drivers/net/wireless/realtek/rtw88/main.c
@@ -1450,6 +1450,7 @@ EXPORT_SYMBOL(rtw_core_deinit);
 
 int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw)
 {
+	struct rtw_hal *hal = &rtwdev->hal;
 	int max_tx_headroom = 0;
 	int ret;
 
@@ -1478,6 +1479,8 @@ int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw)
 				     BIT(NL80211_IFTYPE_AP) |
 				     BIT(NL80211_IFTYPE_ADHOC) |
 				     BIT(NL80211_IFTYPE_MESH_POINT);
+	hw->wiphy->available_antennas_tx = hal->antenna_tx;
+	hw->wiphy->available_antennas_rx = hal->antenna_rx;
 
 	hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS |
 			    WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
index c6b590fdb573..c9edcabd7c42 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -798,8 +798,9 @@ struct rtw_chip_ops {
 	void (*set_tx_power_index)(struct rtw_dev *rtwdev);
 	int (*rsvd_page_dump)(struct rtw_dev *rtwdev, u8 *buf, u32 offset,
 			      u32 size);
-	void (*set_antenna)(struct rtw_dev *rtwdev, u8 antenna_tx,
-			    u8 antenna_rx);
+	int (*set_antenna)(struct rtw_dev *rtwdev,
+			   u32 antenna_tx,
+			   u32 antenna_rx);
 	void (*cfg_ldo25)(struct rtw_dev *rtwdev, bool enable);
 	void (*false_alarm_statistics)(struct rtw_dev *rtwdev);
 	void (*phy_calibration)(struct rtw_dev *rtwdev);
@@ -1567,8 +1568,8 @@ struct rtw_hal {
 	u8 sec_ch_offset;
 	u8 rf_type;
 	u8 rf_path_num;
-	u8 antenna_tx;
-	u8 antenna_rx;
+	u32 antenna_tx;
+	u32 antenna_rx;
 	u8 bfee_sts_cap;
 
 	/* protect tx power section */
diff --git a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/realtek/rtw88/pci.c
index e37c71495c0d..1af87eb2e53a 100644
--- a/drivers/net/wireless/realtek/rtw88/pci.c
+++ b/drivers/net/wireless/realtek/rtw88/pci.c
@@ -1338,22 +1338,17 @@ static void rtw_pci_phy_cfg(struct rtw_dev *rtwdev)
 	rtw_pci_link_cfg(rtwdev);
 }
 
-#ifdef CONFIG_PM
-static int rtw_pci_suspend(struct device *dev)
+static int __maybe_unused rtw_pci_suspend(struct device *dev)
 {
 	return 0;
 }
 
-static int rtw_pci_resume(struct device *dev)
+static int __maybe_unused rtw_pci_resume(struct device *dev)
 {
 	return 0;
 }
 
 static SIMPLE_DEV_PM_OPS(rtw_pm_ops, rtw_pci_suspend, rtw_pci_resume);
-#define RTW_PM_OPS (&rtw_pm_ops)
-#else
-#define RTW_PM_OPS NULL
-#endif
 
 static int rtw_pci_claim(struct rtw_dev *rtwdev, struct pci_dev *pdev)
 {
@@ -1582,7 +1577,7 @@ static struct pci_driver rtw_pci_driver = {
 	.id_table = rtw_pci_id_table,
 	.probe = rtw_pci_probe,
 	.remove = rtw_pci_remove,
-	.driver.pm = RTW_PM_OPS,
+	.driver.pm = &rtw_pm_ops,
 };
 module_pci_driver(rtw_pci_driver);
 
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c
index 4dd7d4143b04..c02f3a730369 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c
@@ -998,8 +998,9 @@ static bool rtw8822b_check_rf_path(u8 antenna)
 	}
 }
 
-static void rtw8822b_set_antenna(struct rtw_dev *rtwdev, u8 antenna_tx,
-				 u8 antenna_rx)
+static int rtw8822b_set_antenna(struct rtw_dev *rtwdev,
+				u32 antenna_tx,
+				u32 antenna_rx)
 {
 	struct rtw_hal *hal = &rtwdev->hal;
 
@@ -1007,16 +1008,21 @@ static void rtw8822b_set_antenna(struct rtw_dev *rtwdev, u8 antenna_tx,
 		antenna_tx, antenna_rx);
 
 	if (!rtw8822b_check_rf_path(antenna_tx)) {
-		rtw_info(rtwdev, "unsupport tx path, set to default path ab\n");
-		antenna_tx = BB_PATH_AB;
+		rtw_info(rtwdev, "unsupport tx path 0x%x\n", antenna_tx);
+		return -EINVAL;
 	}
+
 	if (!rtw8822b_check_rf_path(antenna_rx)) {
-		rtw_info(rtwdev, "unsupport rx path, set to default path ab\n");
-		antenna_rx = BB_PATH_AB;
+		rtw_info(rtwdev, "unsupport rx path 0x%x\n", antenna_rx);
+		return -EINVAL;
 	}
+
 	hal->antenna_tx = antenna_tx;
 	hal->antenna_rx = antenna_rx;
+
 	rtw8822b_config_trx_mode(rtwdev, antenna_tx, antenna_rx, false);
+
+	return 0;
 }
 
 static void rtw8822b_cfg_ldo25(struct rtw_dev *rtwdev, bool enable)
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
index dc07e6be38e8..c99b1de54bfc 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
@@ -1890,6 +1890,40 @@ static void rtw8822c_set_tx_power_index(struct rtw_dev *rtwdev)
 	}
 }
 
+static int rtw8822c_set_antenna(struct rtw_dev *rtwdev,
+				u32 antenna_tx,
+				u32 antenna_rx)
+{
+	struct rtw_hal *hal = &rtwdev->hal;
+
+	switch (antenna_tx) {
+	case BB_PATH_A:
+	case BB_PATH_B:
+	case BB_PATH_AB:
+		break;
+	default:
+		rtw_info(rtwdev, "unsupport tx path 0x%x\n", antenna_tx);
+		return -EINVAL;
+	}
+
+	/* path B only is not available for RX */
+	switch (antenna_rx) {
+	case BB_PATH_A:
+	case BB_PATH_AB:
+		break;
+	default:
+		rtw_info(rtwdev, "unsupport rx path 0x%x\n", antenna_rx);
+		return -EINVAL;
+	}
+
+	hal->antenna_tx = antenna_tx;
+	hal->antenna_rx = antenna_rx;
+
+	rtw8822c_config_trx_mode(rtwdev, antenna_tx, antenna_rx, false);
+
+	return 0;
+}
+
 static void rtw8822c_cfg_ldo25(struct rtw_dev *rtwdev, bool enable)
 {
 	u8 ldo_pwr;
@@ -3794,6 +3828,7 @@ static struct rtw_chip_ops rtw8822c_ops = {
 	.read_rf		= rtw_phy_read_rf,
 	.write_rf		= rtw_phy_write_rf_reg_mix,
 	.set_tx_power_index	= rtw8822c_set_tx_power_index,
+	.set_antenna		= rtw8822c_set_antenna,
 	.cfg_ldo25		= rtw8822c_cfg_ldo25,
 	.false_alarm_statistics	= rtw8822c_false_alarm_statistics,
 	.dpk_track		= rtw8822c_dpk_track,
diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
index 440088293aff..5c0adb0efc5d 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
@@ -832,7 +832,7 @@ static void rsi_mac80211_bss_info_changed(struct ieee80211_hw *hw,
 		common->cqm_info.last_cqm_event_rssi = 0;
 		common->cqm_info.rssi_thold = bss_conf->cqm_rssi_thold;
 		common->cqm_info.rssi_hyst = bss_conf->cqm_rssi_hyst;
-		rsi_dbg(INFO_ZONE, "RSSI throld & hysteresis are: %d %d\n",
+		rsi_dbg(INFO_ZONE, "RSSI threshold & hysteresis are: %d %d\n",
 			common->cqm_info.rssi_thold,
 			common->cqm_info.rssi_hyst);
 	}
diff --git a/drivers/net/wireless/st/cw1200/cw1200_spi.c b/drivers/net/wireless/st/cw1200/cw1200_spi.c
index ef01caac629c..271ed2ce2d7f 100644
--- a/drivers/net/wireless/st/cw1200/cw1200_spi.c
+++ b/drivers/net/wireless/st/cw1200/cw1200_spi.c
@@ -268,15 +268,11 @@ static int cw1200_spi_irq_subscribe(struct hwbus_priv *self)
 	return ret;
 }
 
-static int cw1200_spi_irq_unsubscribe(struct hwbus_priv *self)
+static void cw1200_spi_irq_unsubscribe(struct hwbus_priv *self)
 {
-	int ret = 0;
-
 	pr_debug("SW IRQ unsubscribe\n");
 	disable_irq_wake(self->func->irq);
 	free_irq(self->func->irq, self);
-
-	return ret;
 }
 
 static int cw1200_spi_off(const struct cw1200_platform_data_spi *pdata)
diff --git a/drivers/ntb/core.c b/drivers/ntb/core.c
index 2581ab724c34..f8f75a504a58 100644
--- a/drivers/ntb/core.c
+++ b/drivers/ntb/core.c
@@ -214,10 +214,8 @@ int ntb_default_port_number(struct ntb_dev *ntb)
 	case NTB_TOPO_B2B_DSD:
 		return NTB_PORT_SEC_DSD;
 	default:
-		break;
+		return 0;
 	}
-
-	return -EINVAL;
 }
 EXPORT_SYMBOL(ntb_default_port_number);
 
@@ -240,10 +238,8 @@ int ntb_default_peer_port_number(struct ntb_dev *ntb, int pidx)
 	case NTB_TOPO_B2B_DSD:
 		return NTB_PORT_PRI_USD;
 	default:
-		break;
+		return 0;
 	}
-
-	return -EINVAL;
 }
 EXPORT_SYMBOL(ntb_default_peer_port_number);
 
@@ -315,4 +311,3 @@ static void __exit ntb_driver_exit(void)
 	bus_unregister(&ntb_bus);
 }
 module_exit(ntb_driver_exit);
-
diff --git a/drivers/ntb/hw/amd/ntb_hw_amd.c b/drivers/ntb/hw/amd/ntb_hw_amd.c
index 9e310e1ad4d0..88e1db65be02 100644
--- a/drivers/ntb/hw/amd/ntb_hw_amd.c
+++ b/drivers/ntb/hw/amd/ntb_hw_amd.c
@@ -1191,10 +1191,6 @@ static int amd_ntb_init_pci(struct amd_ntb_dev *ndev,
 			goto err_dma_mask;
 		dev_warn(&pdev->dev, "Cannot DMA consistent highmem\n");
 	}
-	rc = dma_coerce_mask_and_coherent(&ndev->ntb.dev,
-					  dma_get_mask(&pdev->dev));
-	if (rc)
-		goto err_dma_mask;
 
 	ndev->self_mmio = pci_iomap(pdev, 0, 0);
 	if (!ndev->self_mmio) {
diff --git a/drivers/ntb/hw/idt/ntb_hw_idt.c b/drivers/ntb/hw/idt/ntb_hw_idt.c
index edae52384b8a..d54261f50851 100644
--- a/drivers/ntb/hw/idt/ntb_hw_idt.c
+++ b/drivers/ntb/hw/idt/ntb_hw_idt.c
@@ -2660,12 +2660,6 @@ static int idt_init_pci(struct idt_ntb_dev *ndev)
 		dev_warn(&pdev->dev,
 			"Cannot set consistent DMA highmem bit mask\n");
 	}
-	ret = dma_coerce_mask_and_coherent(&ndev->ntb.dev,
-					   dma_get_mask(&pdev->dev));
-	if (ret != 0) {
-		dev_err(&pdev->dev, "Failed to set NTB device DMA bit mask\n");
-		return ret;
-	}
 
 	/*
 	 * Enable the device advanced error reporting. It's not critical to
diff --git a/drivers/ntb/hw/intel/ntb_hw_gen1.c b/drivers/ntb/hw/intel/ntb_hw_gen1.c
index bb57ec239029..e0530129bbba 100644
--- a/drivers/ntb/hw/intel/ntb_hw_gen1.c
+++ b/drivers/ntb/hw/intel/ntb_hw_gen1.c
@@ -1783,10 +1783,6 @@ static int intel_ntb_init_pci(struct intel_ntb_dev *ndev, struct pci_dev *pdev)
 			goto err_dma_mask;
 		dev_warn(&pdev->dev, "Cannot DMA consistent highmem\n");
 	}
-	rc = dma_coerce_mask_and_coherent(&ndev->ntb.dev,
-					  dma_get_mask(&pdev->dev));
-	if (rc)
-		goto err_dma_mask;
 
 	ndev->self_mmio = pci_iomap(pdev, 0, 0);
 	if (!ndev->self_mmio) {
diff --git a/drivers/ntb/test/ntb_perf.c b/drivers/ntb/test/ntb_perf.c
index 972f6d984f6d..c72dae6c4c94 100644
--- a/drivers/ntb/test/ntb_perf.c
+++ b/drivers/ntb/test/ntb_perf.c
@@ -159,6 +159,8 @@ struct perf_peer {
 	/* NTB connection setup service */
 	struct work_struct	service;
 	unsigned long		sts;
+
+	struct completion init_comp;
 };
 #define to_peer_service(__work) \
 	container_of(__work, struct perf_peer, service)
@@ -547,6 +549,7 @@ static int perf_setup_outbuf(struct perf_peer *peer)
 
 	/* Initialization is finally done */
 	set_bit(PERF_STS_DONE, &peer->sts);
+	complete_all(&peer->init_comp);
 
 	return 0;
 }
@@ -557,7 +560,7 @@ static void perf_free_inbuf(struct perf_peer *peer)
 		return;
 
 	(void)ntb_mw_clear_trans(peer->perf->ntb, peer->pidx, peer->gidx);
-	dma_free_coherent(&peer->perf->ntb->dev, peer->inbuf_size,
+	dma_free_coherent(&peer->perf->ntb->pdev->dev, peer->inbuf_size,
 			  peer->inbuf, peer->inbuf_xlat);
 	peer->inbuf = NULL;
 }
@@ -586,8 +589,8 @@ static int perf_setup_inbuf(struct perf_peer *peer)
 
 	perf_free_inbuf(peer);
 
-	peer->inbuf = dma_alloc_coherent(&perf->ntb->dev, peer->inbuf_size,
-					 &peer->inbuf_xlat, GFP_KERNEL);
+	peer->inbuf = dma_alloc_coherent(&perf->ntb->pdev->dev,
+			peer->inbuf_size, &peer->inbuf_xlat, GFP_KERNEL);
 	if (!peer->inbuf) {
 		dev_err(&perf->ntb->dev, "Failed to alloc inbuf of %pa\n",
 			&peer->inbuf_size);
@@ -637,6 +640,7 @@ static void perf_service_work(struct work_struct *work)
 		perf_setup_outbuf(peer);
 
 	if (test_and_clear_bit(PERF_CMD_CLEAR, &peer->sts)) {
+		init_completion(&peer->init_comp);
 		clear_bit(PERF_STS_DONE, &peer->sts);
 		if (test_bit(0, &peer->perf->busy_flag) &&
 		    peer == peer->perf->test_peer) {
@@ -653,7 +657,7 @@ static int perf_init_service(struct perf_ctx *perf)
 {
 	u64 mask;
 
-	if (ntb_peer_mw_count(perf->ntb) < perf->pcnt + 1) {
+	if (ntb_peer_mw_count(perf->ntb) < perf->pcnt) {
 		dev_err(&perf->ntb->dev, "Not enough memory windows\n");
 		return -EINVAL;
 	}
@@ -1010,8 +1014,8 @@ static void perf_clear_test(struct perf_thread *pthr)
 				   pthr->perf->test_peer->dma_dst_addr,
 				   pthr->perf->test_peer->outbuf_size,
 				   DMA_FROM_DEVICE, 0);
-	if (pthr->dma_chan)
-		dma_release_channel(pthr->dma_chan);
+
+	dma_release_channel(pthr->dma_chan);
 
 no_dma_notify:
 	atomic_dec(&perf->tsync);
@@ -1083,8 +1087,9 @@ static int perf_submit_test(struct perf_peer *peer)
 	struct perf_thread *pthr;
 	int tidx, ret;
 
-	if (!test_bit(PERF_STS_DONE, &peer->sts))
-		return -ENOLINK;
+	ret = wait_for_completion_interruptible(&peer->init_comp);
+	if (ret < 0)
+		return ret;
 
 	if (test_and_set_bit_lock(0, &perf->busy_flag))
 		return -EBUSY;
@@ -1455,10 +1460,21 @@ static int perf_init_peers(struct perf_ctx *perf)
 			peer->gidx = pidx;
 		}
 		INIT_WORK(&peer->service, perf_service_work);
+		init_completion(&peer->init_comp);
 	}
 	if (perf->gidx == -1)
 		perf->gidx = pidx;
 
+	/*
+	 * Hardware with only two ports may not have unique port
+	 * numbers. In this case, the gidxs should all be zero.
+	 */
+	if (perf->pcnt == 1 &&  ntb_port_number(perf->ntb) == 0 &&
+	    ntb_peer_port_number(perf->ntb, 0) == 0) {
+		perf->gidx = 0;
+		perf->peers[0].gidx = 0;
+	}
+
 	for (pidx = 0; pidx < perf->pcnt; pidx++) {
 		ret = perf_setup_peer_mw(&perf->peers[pidx]);
 		if (ret)
@@ -1554,4 +1570,3 @@ static void __exit perf_exit(void)
 	destroy_workqueue(perf_wq);
 }
 module_exit(perf_exit);
-
diff --git a/drivers/ntb/test/ntb_pingpong.c b/drivers/ntb/test/ntb_pingpong.c
index 04dd46647db3..2164e8492772 100644
--- a/drivers/ntb/test/ntb_pingpong.c
+++ b/drivers/ntb/test/ntb_pingpong.c
@@ -121,15 +121,14 @@ static int pp_find_next_peer(struct pp_ctx *pp)
 	link = ntb_link_is_up(pp->ntb, NULL, NULL);
 
 	/* Find next available peer */
-	if (link & pp->nmask) {
+	if (link & pp->nmask)
 		pidx = __ffs64(link & pp->nmask);
-		out_db = BIT_ULL(pidx + 1);
-	} else if (link & pp->pmask) {
+	else if (link & pp->pmask)
 		pidx = __ffs64(link & pp->pmask);
-		out_db = BIT_ULL(pidx);
-	} else {
+	else
 		return -ENODEV;
-	}
+
+	out_db = BIT_ULL(ntb_peer_port_number(pp->ntb, pidx));
 
 	spin_lock(&pp->lock);
 	pp->out_pidx = pidx;
@@ -303,7 +302,7 @@ static void pp_init_flds(struct pp_ctx *pp)
 			break;
 	}
 
-	pp->in_db = BIT_ULL(pidx);
+	pp->in_db = BIT_ULL(lport);
 	pp->pmask = GENMASK_ULL(pidx, 0) >> 1;
 	pp->nmask = GENMASK_ULL(pcnt - 1, pidx);
 
@@ -432,4 +431,3 @@ static void __exit pp_exit(void)
 	debugfs_remove_recursive(pp_dbgfs_topdir);
 }
 module_exit(pp_exit);
-
diff --git a/drivers/ntb/test/ntb_tool.c b/drivers/ntb/test/ntb_tool.c
index 69da758fe64c..b7bf3f863d79 100644
--- a/drivers/ntb/test/ntb_tool.c
+++ b/drivers/ntb/test/ntb_tool.c
@@ -504,7 +504,7 @@ static ssize_t tool_peer_link_read(struct file *filep, char __user *ubuf,
 	buf[1] = '\n';
 	buf[2] = '\0';
 
-	return simple_read_from_buffer(ubuf, size, offp, buf, 3);
+	return simple_read_from_buffer(ubuf, size, offp, buf, 2);
 }
 
 static TOOL_FOPS_RDWR(tool_peer_link_fops,
@@ -590,7 +590,7 @@ static int tool_setup_mw(struct tool_ctx *tc, int pidx, int widx,
 	inmw->size = min_t(resource_size_t, req_size, size);
 	inmw->size = round_up(inmw->size, addr_align);
 	inmw->size = round_up(inmw->size, size_align);
-	inmw->mm_base = dma_alloc_coherent(&tc->ntb->dev, inmw->size,
+	inmw->mm_base = dma_alloc_coherent(&tc->ntb->pdev->dev, inmw->size,
 					   &inmw->dma_base, GFP_KERNEL);
 	if (!inmw->mm_base)
 		return -ENOMEM;
@@ -612,7 +612,7 @@ static int tool_setup_mw(struct tool_ctx *tc, int pidx, int widx,
 	return 0;
 
 err_free_dma:
-	dma_free_coherent(&tc->ntb->dev, inmw->size, inmw->mm_base,
+	dma_free_coherent(&tc->ntb->pdev->dev, inmw->size, inmw->mm_base,
 			  inmw->dma_base);
 	inmw->mm_base = NULL;
 	inmw->dma_base = 0;
@@ -629,7 +629,7 @@ static void tool_free_mw(struct tool_ctx *tc, int pidx, int widx)
 
 	if (inmw->mm_base != NULL) {
 		ntb_mw_clear_trans(tc->ntb, pidx, widx);
-		dma_free_coherent(&tc->ntb->dev, inmw->size,
+		dma_free_coherent(&tc->ntb->pdev->dev, inmw->size,
 				  inmw->mm_base, inmw->dma_base);
 	}
 
@@ -1690,4 +1690,3 @@ static void __exit tool_exit(void)
 	debugfs_remove_recursive(tool_dbgfs_topdir);
 }
 module_exit(tool_exit);
-
diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c
index 08fd823edac9..fe64430b438a 100644
--- a/drivers/of/dynamic.c
+++ b/drivers/of/dynamic.c
@@ -286,7 +286,6 @@ int of_detach_node(struct device_node *np)
 {
 	struct of_reconfig_data rd;
 	unsigned long flags;
-	int rc = 0;
 
 	memset(&rd, 0, sizeof(rd));
 	rd.dn = np;
@@ -301,7 +300,7 @@ int of_detach_node(struct device_node *np)
 
 	of_reconfig_notify(OF_RECONFIG_DETACH_NODE, &rd);
 
-	return rc;
+	return 0;
 }
 EXPORT_SYMBOL_GPL(of_detach_node);
 
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index c9219fddf44b..50bbe0edf538 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -261,6 +261,8 @@ static struct property *dup_and_fixup_symbol_prop(
 
 	of_property_set_flag(new_prop, OF_DYNAMIC);
 
+	kfree(target_path);
+
 	return new_prop;
 
 err_free_new_prop:
diff --git a/drivers/of/property.c b/drivers/of/property.c
index b4916dcc9e72..252e4f600155 100644
--- a/drivers/of/property.c
+++ b/drivers/of/property.c
@@ -1206,6 +1206,7 @@ DEFINE_SIMPLE_PROP(interrupt_parent, "interrupt-parent", NULL)
 DEFINE_SIMPLE_PROP(dmas, "dmas", "#dma-cells")
 DEFINE_SIMPLE_PROP(power_domains, "power-domains", "#power-domain-cells")
 DEFINE_SIMPLE_PROP(hwlocks, "hwlocks", "#hwlock-cells")
+DEFINE_SIMPLE_PROP(extcon, "extcon", NULL)
 DEFINE_SUFFIX_PROP(regulators, "-supply", NULL)
 DEFINE_SUFFIX_PROP(gpio, "-gpio", "#gpio-cells")
 DEFINE_SUFFIX_PROP(gpios, "-gpios", "#gpio-cells")
@@ -1230,6 +1231,7 @@ static const struct supplier_bindings of_supplier_bindings[] = {
 	{ .parse_prop = parse_dmas, },
 	{ .parse_prop = parse_power_domains, },
 	{ .parse_prop = parse_hwlocks, },
+	{ .parse_prop = parse_extcon, },
 	{ .parse_prop = parse_regulators, },
 	{ .parse_prop = parse_gpio, },
 	{ .parse_prop = parse_gpios, },
diff --git a/drivers/of/unittest-data/overlay_bad_add_dup_prop.dts b/drivers/of/unittest-data/overlay_bad_add_dup_prop.dts
index c190da54f175..6327d1ffb963 100644
--- a/drivers/of/unittest-data/overlay_bad_add_dup_prop.dts
+++ b/drivers/of/unittest-data/overlay_bad_add_dup_prop.dts
@@ -3,22 +3,37 @@
 /plugin/;
 
 /*
- * &electric_1/motor-1 and &spin_ctrl_1 are the same node:
- *   /testcase-data-2/substation@100/motor-1
+ * &electric_1/motor-1/electric and &spin_ctrl_1/electric are the same node:
+ *   /testcase-data-2/substation@100/motor-1/electric
  *
  * Thus the property "rpm_avail" in each fragment will
  * result in an attempt to update the same property twice.
  * This will result in an error and the overlay apply
  * will fail.
+ *
+ * The previous version of this test did not include the extra
+ * level of node 'electric'.  That resulted in the 'rpm_avail'
+ * property being located in the pre-existing node 'motor-1'.
+ * Modifying a property results in a WARNING that a memory leak
+ * will occur if the overlay is removed.  Since the overlay apply
+ * fails, the memory leak does actually occur, and kmemleak will
+ * further report the memory leak if CONFIG_DEBUG_KMEMLEAK is
+ * enabled.  Adding the overlay node 'electric' avoids the
+ * memory leak and thus people who use kmemleak will not
+ * have to debug this non-problem again.
  */
 
 &electric_1 {
 
 	motor-1 {
-		rpm_avail = < 100 >;
+		electric {
+			rpm_avail = < 100 >;
+		};
 	};
 };
 
 &spin_ctrl_1 {
-		rpm_avail = < 100 200 >;
+		electric {
+			rpm_avail = < 100 200 >;
+		};
 };
diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c
index 7e27670c3616..398de04fd19c 100644
--- a/drivers/of/unittest.c
+++ b/drivers/of/unittest.c
@@ -861,6 +861,10 @@ static void __init of_unittest_changeset(void)
 	unittest(!of_changeset_revert(&chgset), "revert failed\n");
 
 	of_changeset_destroy(&chgset);
+
+	of_node_put(n1);
+	of_node_put(n2);
+	of_node_put(n21);
 #endif
 }
 
@@ -1243,10 +1247,13 @@ static void __init of_unittest_platform_populate(void)
 
 	of_platform_populate(np, match, NULL, &test_bus->dev);
 	for_each_child_of_node(np, child) {
-		for_each_child_of_node(child, grandchild)
-			unittest(of_find_device_by_node(grandchild),
+		for_each_child_of_node(child, grandchild) {
+			pdev = of_find_device_by_node(grandchild);
+			unittest(pdev,
 				 "Could not create device for node '%pOFn'\n",
 				 grandchild);
+			of_dev_put(pdev);
+		}
 	}
 
 	of_platform_depopulate(&test_bus->dev);
@@ -3087,8 +3094,11 @@ static __init void of_unittest_overlay_high_level(void)
 				goto err_unlock;
 			}
 			if (__of_add_property(of_symbols, new_prop)) {
+				kfree(new_prop->name);
+				kfree(new_prop->value);
+				kfree(new_prop);
 				/* "name" auto-generated by unflatten */
-				if (!strcmp(new_prop->name, "name"))
+				if (!strcmp(prop->name, "name"))
 					continue;
 				unittest(0, "duplicate property '%s' in overlay_base node __symbols__",
 					 prop->name);
@@ -3171,21 +3181,21 @@ static __init void of_unittest_overlay_high_level(void)
 		   "OF: overlay: ERROR: multiple fragments add and/or delete node /testcase-data-2/substation@100/motor-1/controller");
 
 	EXPECT_BEGIN(KERN_ERR,
-		     "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data-2/substation@100/motor-1/rpm_avail");
+		     "OF: overlay: ERROR: multiple fragments add and/or delete node /testcase-data-2/substation@100/motor-1/electric");
 	EXPECT_BEGIN(KERN_ERR,
-		     "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data-2/substation@100/motor-1/rpm_avail");
+		     "OF: overlay: ERROR: multiple fragments add, update, and/or delete property /testcase-data-2/substation@100/motor-1/electric/rpm_avail");
 	EXPECT_BEGIN(KERN_ERR,
-		     "OF: overlay: ERROR: multiple fragments add, update, and/or delete property /testcase-data-2/substation@100/motor-1/rpm_avail");
+		     "OF: overlay: ERROR: multiple fragments add, update, and/or delete property /testcase-data-2/substation@100/motor-1/electric/name");
 
 	unittest(overlay_data_apply("overlay_bad_add_dup_prop", NULL),
 		 "Adding overlay 'overlay_bad_add_dup_prop' failed\n");
 
 	EXPECT_END(KERN_ERR,
-		   "OF: overlay: ERROR: multiple fragments add, update, and/or delete property /testcase-data-2/substation@100/motor-1/rpm_avail");
+		     "OF: overlay: ERROR: multiple fragments add, update, and/or delete property /testcase-data-2/substation@100/motor-1/electric/name");
 	EXPECT_END(KERN_ERR,
-		   "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data-2/substation@100/motor-1/rpm_avail");
+		     "OF: overlay: ERROR: multiple fragments add, update, and/or delete property /testcase-data-2/substation@100/motor-1/electric/rpm_avail");
 	EXPECT_END(KERN_ERR,
-		   "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data-2/substation@100/motor-1/rpm_avail");
+		     "OF: overlay: ERROR: multiple fragments add and/or delete node /testcase-data-2/substation@100/motor-1/electric");
 
 	unittest(overlay_data_apply("overlay_bad_phandle", NULL),
 		 "Adding overlay 'overlay_bad_phandle' failed\n");
diff --git a/drivers/opp/core.c b/drivers/opp/core.c
index ba43e6a3dc0a..e4f01e7771a2 100644
--- a/drivers/opp/core.c
+++ b/drivers/opp/core.c
@@ -819,6 +819,8 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq)
 	if (unlikely(!target_freq)) {
 		if (opp_table->required_opp_tables) {
 			ret = _set_required_opps(dev, opp_table, NULL);
+		} else if (!_get_opp_count(opp_table)) {
+			return 0;
 		} else {
 			dev_err(dev, "target frequency can't be 0\n");
 			ret = -EINVAL;
@@ -849,6 +851,18 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq)
 		goto put_opp_table;
 	}
 
+	/*
+	 * For IO devices which require an OPP on some platforms/SoCs
+	 * while just needing to scale the clock on some others
+	 * we look for empty OPP tables with just a clock handle and
+	 * scale only the clk. This makes dev_pm_opp_set_rate()
+	 * equivalent to a clk_set_rate()
+	 */
+	if (!_get_opp_count(opp_table)) {
+		ret = _generic_set_opp_clk_only(dev, clk, freq);
+		goto put_opp_table;
+	}
+
 	temp_freq = old_freq;
 	old_opp = _find_freq_ceil(opp_table, &temp_freq);
 	if (IS_ERR(old_opp)) {
diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
index e15022ff63e3..222ff5639ebe 100644
--- a/drivers/pci/controller/pci-hyperv.c
+++ b/drivers/pci/controller/pci-hyperv.c
@@ -1356,11 +1356,11 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
 {
 	struct irq_cfg *cfg = irqd_cfg(data);
 	struct hv_pcibus_device *hbus;
+	struct vmbus_channel *channel;
 	struct hv_pci_dev *hpdev;
 	struct pci_bus *pbus;
 	struct pci_dev *pdev;
 	struct cpumask *dest;
-	unsigned long flags;
 	struct compose_comp_ctxt comp;
 	struct tran_int_desc *int_desc;
 	struct {
@@ -1378,6 +1378,7 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
 	dest = irq_data_get_effective_affinity_mask(data);
 	pbus = pdev->bus;
 	hbus = container_of(pbus->sysdata, struct hv_pcibus_device, sysdata);
+	channel = hbus->hdev->channel;
 	hpdev = get_pcichild_wslot(hbus, devfn_to_wslot(pdev->devfn));
 	if (!hpdev)
 		goto return_null_message;
@@ -1435,43 +1436,52 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
 		goto free_int_desc;
 	}
 
+	/*
+	 * Prevents hv_pci_onchannelcallback() from running concurrently
+	 * in the tasklet.
+	 */
+	tasklet_disable(&channel->callback_event);
+
 	/*
 	 * Since this function is called with IRQ locks held, can't
 	 * do normal wait for completion; instead poll.
 	 */
 	while (!try_wait_for_completion(&comp.comp_pkt.host_event)) {
+		unsigned long flags;
+
 		/* 0xFFFF means an invalid PCI VENDOR ID. */
 		if (hv_pcifront_get_vendor_id(hpdev) == 0xFFFF) {
 			dev_err_once(&hbus->hdev->device,
 				     "the device has gone\n");
-			goto free_int_desc;
+			goto enable_tasklet;
 		}
 
 		/*
-		 * When the higher level interrupt code calls us with
-		 * interrupt disabled, we must poll the channel by calling
-		 * the channel callback directly when channel->target_cpu is
-		 * the current CPU. When the higher level interrupt code
-		 * calls us with interrupt enabled, let's add the
-		 * local_irq_save()/restore() to avoid race:
-		 * hv_pci_onchannelcallback() can also run in tasklet.
+		 * Make sure that the ring buffer data structure doesn't get
+		 * freed while we dereference the ring buffer pointer.  Test
+		 * for the channel's onchannel_callback being NULL within a
+		 * sched_lock critical section.  See also the inline comments
+		 * in vmbus_reset_channel_cb().
 		 */
-		local_irq_save(flags);
-
-		if (hbus->hdev->channel->target_cpu == smp_processor_id())
-			hv_pci_onchannelcallback(hbus);
-
-		local_irq_restore(flags);
+		spin_lock_irqsave(&channel->sched_lock, flags);
+		if (unlikely(channel->onchannel_callback == NULL)) {
+			spin_unlock_irqrestore(&channel->sched_lock, flags);
+			goto enable_tasklet;
+		}
+		hv_pci_onchannelcallback(hbus);
+		spin_unlock_irqrestore(&channel->sched_lock, flags);
 
 		if (hpdev->state == hv_pcichild_ejecting) {
 			dev_err_once(&hbus->hdev->device,
 				     "the device is being ejected\n");
-			goto free_int_desc;
+			goto enable_tasklet;
 		}
 
 		udelay(100);
 	}
 
+	tasklet_enable(&channel->callback_event);
+
 	if (comp.comp_pkt.completion_status < 0) {
 		dev_err(&hbus->hdev->device,
 			"Request for interrupt failed: 0x%x",
@@ -1495,6 +1505,8 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
 	put_pcichild(hpdev);
 	return;
 
+enable_tasklet:
+	tasklet_enable(&channel->callback_event);
 free_int_desc:
 	kfree(int_desc);
 drop_reference:
diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c
index b73b10bce0df..e8e444eeb1cd 100644
--- a/drivers/pci/p2pdma.c
+++ b/drivers/pci/p2pdma.c
@@ -282,6 +282,8 @@ static const struct pci_p2pdma_whitelist_entry {
 } pci_p2pdma_whitelist[] = {
 	/* AMD ZEN */
 	{PCI_VENDOR_ID_AMD,	0x1450,	0},
+	{PCI_VENDOR_ID_AMD,	0x15d0,	0},
+	{PCI_VENDOR_ID_AMD,	0x1630,	0},
 
 	/* Intel Xeon E5/Core i7 */
 	{PCI_VENDOR_ID_INTEL,	0x3c00, REQ_SAME_HOST_BRIDGE},
diff --git a/drivers/phy/tegra/Kconfig b/drivers/phy/tegra/Kconfig
index a208aca4ba7b..c591c958f1eb 100644
--- a/drivers/phy/tegra/Kconfig
+++ b/drivers/phy/tegra/Kconfig
@@ -1,7 +1,8 @@
 # SPDX-License-Identifier: GPL-2.0-only
 config PHY_TEGRA_XUSB
 	tristate "NVIDIA Tegra XUSB pad controller driver"
-	depends on ARCH_TEGRA
+	depends on ARCH_TEGRA && USB_SUPPORT
+	select USB_COMMON
 	select USB_CONN_GPIO
 	select USB_PHY
 	help
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 834c59950d1c..f646f070d98f 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -172,15 +172,22 @@ config PINCTRL_GEMINI
 	select GENERIC_PINCONF
 	select MFD_SYSCON
 
+config PINCTRL_MCP23S08_I2C
+	tristate
+	select REGMAP_I2C
+
+config PINCTRL_MCP23S08_SPI
+	tristate
+	select REGMAP_SPI
+
 config PINCTRL_MCP23S08
 	tristate "Microchip MCP23xxx I/O expander"
 	depends on SPI_MASTER || I2C
-	depends on I2C || I2C=n
 	select GPIOLIB
 	select GPIOLIB_IRQCHIP
-	select REGMAP_I2C if I2C
-	select REGMAP_SPI if SPI_MASTER
 	select GENERIC_PINCONF
+	select PINCTRL_MCP23S08_I2C if I2C
+	select PINCTRL_MCP23S08_SPI if SPI_MASTER
 	help
 	  SPI/I2C driver for Microchip MCP23S08 / MCP23S17 / MCP23S18 /
 	  MCP23008 / MCP23017 / MCP23018 I/O expanders.
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 0b36a1cfca8a..1731b2154df9 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -21,6 +21,8 @@ obj-$(CONFIG_PINCTRL_DIGICOLOR)	+= pinctrl-digicolor.o
 obj-$(CONFIG_PINCTRL_FALCON)	+= pinctrl-falcon.o
 obj-$(CONFIG_PINCTRL_GEMINI)	+= pinctrl-gemini.o
 obj-$(CONFIG_PINCTRL_MAX77620)	+= pinctrl-max77620.o
+obj-$(CONFIG_PINCTRL_MCP23S08_I2C)	+= pinctrl-mcp23s08_i2c.o
+obj-$(CONFIG_PINCTRL_MCP23S08_SPI)	+= pinctrl-mcp23s08_spi.o
 obj-$(CONFIG_PINCTRL_MCP23S08)	+= pinctrl-mcp23s08.o
 obj-$(CONFIG_PINCTRL_MESON)	+= meson/
 obj-$(CONFIG_PINCTRL_OXNAS)	+= pinctrl-oxnas.o
diff --git a/drivers/pinctrl/actions/pinctrl-s700.c b/drivers/pinctrl/actions/pinctrl-s700.c
index 47a4ccd9fed4..f579a6593f37 100644
--- a/drivers/pinctrl/actions/pinctrl-s700.c
+++ b/drivers/pinctrl/actions/pinctrl-s700.c
@@ -1435,7 +1435,7 @@ static const char * const sd2_groups[] = {
 static const char * const i2c0_groups[] = {
 	"uart0_rx_mfp",
 	"uart0_tx_mfp",
-	"i2c0_mfp_mfp",
+	"i2c0_mfp",
 };
 
 static const char * const i2c1_groups[] = {
diff --git a/drivers/pinctrl/freescale/Kconfig b/drivers/pinctrl/freescale/Kconfig
index c784663b00ad..4ca44dd69e53 100644
--- a/drivers/pinctrl/freescale/Kconfig
+++ b/drivers/pinctrl/freescale/Kconfig
@@ -165,6 +165,13 @@ config PINCTRL_IMX8QXP
 	help
 	  Say Y here to enable the imx8qxp pinctrl driver
 
+config PINCTRL_IMX8DXL
+	bool "IMX8DXL pinctrl driver"
+	depends on IMX_SCU && ARCH_MXC && ARM64
+	select PINCTRL_IMX_SCU
+	help
+	  Say Y here to enable the imx8dxl pinctrl driver
+
 config PINCTRL_VF610
 	bool "Freescale Vybrid VF610 pinctrl driver"
 	depends on SOC_VF610
diff --git a/drivers/pinctrl/freescale/Makefile b/drivers/pinctrl/freescale/Makefile
index 0ebd3af21e4d..c61722565289 100644
--- a/drivers/pinctrl/freescale/Makefile
+++ b/drivers/pinctrl/freescale/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_PINCTRL_IMX8MP)	+= pinctrl-imx8mp.o
 obj-$(CONFIG_PINCTRL_IMX8MQ)	+= pinctrl-imx8mq.o
 obj-$(CONFIG_PINCTRL_IMX8QM)	+= pinctrl-imx8qm.o
 obj-$(CONFIG_PINCTRL_IMX8QXP)	+= pinctrl-imx8qxp.o
+obj-$(CONFIG_PINCTRL_IMX8DXL)	+= pinctrl-imx8dxl.o
 obj-$(CONFIG_PINCTRL_VF610)	+= pinctrl-vf610.o
 obj-$(CONFIG_PINCTRL_MXS)	+= pinctrl-mxs.o
 obj-$(CONFIG_PINCTRL_IMX23)	+= pinctrl-imx23.o
diff --git a/drivers/pinctrl/freescale/pinctrl-imx8dxl.c b/drivers/pinctrl/freescale/pinctrl-imx8dxl.c
new file mode 100644
index 000000000000..7f32e57b7f6a
--- /dev/null
+++ b/drivers/pinctrl/freescale/pinctrl-imx8dxl.c
@@ -0,0 +1,193 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019~2020 NXP
+ */
+
+#include <dt-bindings/pinctrl/pads-imx8dxl.h>
+#include <linux/err.h>
+#include <linux/firmware/imx/sci.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-imx.h"
+
+static const struct pinctrl_pin_desc imx8dxl_pinctrl_pads[] = {
+	IMX_PINCTRL_PIN(IMX8DXL_PCIE_CTRL0_PERST_B),
+	IMX_PINCTRL_PIN(IMX8DXL_PCIE_CTRL0_CLKREQ_B),
+	IMX_PINCTRL_PIN(IMX8DXL_PCIE_CTRL0_WAKE_B),
+	IMX_PINCTRL_PIN(IMX8DXL_COMP_CTL_GPIO_1V8_3V3_PCIESEP),
+	IMX_PINCTRL_PIN(IMX8DXL_USB_SS3_TC0),
+	IMX_PINCTRL_PIN(IMX8DXL_USB_SS3_TC1),
+	IMX_PINCTRL_PIN(IMX8DXL_USB_SS3_TC2),
+	IMX_PINCTRL_PIN(IMX8DXL_USB_SS3_TC3),
+	IMX_PINCTRL_PIN(IMX8DXL_COMP_CTL_GPIO_3V3_USB3IO),
+	IMX_PINCTRL_PIN(IMX8DXL_EMMC0_CLK),
+	IMX_PINCTRL_PIN(IMX8DXL_EMMC0_CMD),
+	IMX_PINCTRL_PIN(IMX8DXL_EMMC0_DATA0),
+	IMX_PINCTRL_PIN(IMX8DXL_EMMC0_DATA1),
+	IMX_PINCTRL_PIN(IMX8DXL_EMMC0_DATA2),
+	IMX_PINCTRL_PIN(IMX8DXL_EMMC0_DATA3),
+	IMX_PINCTRL_PIN(IMX8DXL_EMMC0_DATA4),
+	IMX_PINCTRL_PIN(IMX8DXL_EMMC0_DATA5),
+	IMX_PINCTRL_PIN(IMX8DXL_EMMC0_DATA6),
+	IMX_PINCTRL_PIN(IMX8DXL_EMMC0_DATA7),
+	IMX_PINCTRL_PIN(IMX8DXL_EMMC0_STROBE),
+	IMX_PINCTRL_PIN(IMX8DXL_EMMC0_RESET_B),
+	IMX_PINCTRL_PIN(IMX8DXL_COMP_CTL_GPIO_1V8_3V3_SD1FIX0),
+	IMX_PINCTRL_PIN(IMX8DXL_USDHC1_RESET_B),
+	IMX_PINCTRL_PIN(IMX8DXL_USDHC1_VSELECT),
+	IMX_PINCTRL_PIN(IMX8DXL_CTL_NAND_RE_P_N),
+	IMX_PINCTRL_PIN(IMX8DXL_USDHC1_WP),
+	IMX_PINCTRL_PIN(IMX8DXL_USDHC1_CD_B),
+	IMX_PINCTRL_PIN(IMX8DXL_CTL_NAND_DQS_P_N),
+	IMX_PINCTRL_PIN(IMX8DXL_COMP_CTL_GPIO_1V8_3V3_VSELSEP),
+	IMX_PINCTRL_PIN(IMX8DXL_ENET0_RGMII_TXC),
+	IMX_PINCTRL_PIN(IMX8DXL_ENET0_RGMII_TX_CTL),
+	IMX_PINCTRL_PIN(IMX8DXL_ENET0_RGMII_TXD0),
+	IMX_PINCTRL_PIN(IMX8DXL_ENET0_RGMII_TXD1),
+	IMX_PINCTRL_PIN(IMX8DXL_ENET0_RGMII_TXD2),
+	IMX_PINCTRL_PIN(IMX8DXL_ENET0_RGMII_TXD3),
+	IMX_PINCTRL_PIN(IMX8DXL_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB0),
+	IMX_PINCTRL_PIN(IMX8DXL_ENET0_RGMII_RXC),
+	IMX_PINCTRL_PIN(IMX8DXL_ENET0_RGMII_RX_CTL),
+	IMX_PINCTRL_PIN(IMX8DXL_ENET0_RGMII_RXD0),
+	IMX_PINCTRL_PIN(IMX8DXL_ENET0_RGMII_RXD1),
+	IMX_PINCTRL_PIN(IMX8DXL_ENET0_RGMII_RXD2),
+	IMX_PINCTRL_PIN(IMX8DXL_ENET0_RGMII_RXD3),
+	IMX_PINCTRL_PIN(IMX8DXL_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB1),
+	IMX_PINCTRL_PIN(IMX8DXL_ENET0_REFCLK_125M_25M),
+	IMX_PINCTRL_PIN(IMX8DXL_ENET0_MDIO),
+	IMX_PINCTRL_PIN(IMX8DXL_ENET0_MDC),
+	IMX_PINCTRL_PIN(IMX8DXL_COMP_CTL_GPIO_1V8_3V3_GPIOCT),
+	IMX_PINCTRL_PIN(IMX8DXL_ENET1_RGMII_TXC),
+	IMX_PINCTRL_PIN(IMX8DXL_ENET1_RGMII_TXD2),
+	IMX_PINCTRL_PIN(IMX8DXL_ENET1_RGMII_TX_CTL),
+	IMX_PINCTRL_PIN(IMX8DXL_ENET1_RGMII_TXD3),
+	IMX_PINCTRL_PIN(IMX8DXL_ENET1_RGMII_RXC),
+	IMX_PINCTRL_PIN(IMX8DXL_ENET1_RGMII_RXD3),
+	IMX_PINCTRL_PIN(IMX8DXL_ENET1_RGMII_RXD2),
+	IMX_PINCTRL_PIN(IMX8DXL_ENET1_RGMII_RXD1),
+	IMX_PINCTRL_PIN(IMX8DXL_ENET1_RGMII_TXD0),
+	IMX_PINCTRL_PIN(IMX8DXL_ENET1_RGMII_TXD1),
+	IMX_PINCTRL_PIN(IMX8DXL_ENET1_RGMII_RXD0),
+	IMX_PINCTRL_PIN(IMX8DXL_ENET1_RGMII_RX_CTL),
+	IMX_PINCTRL_PIN(IMX8DXL_ENET1_REFCLK_125M_25M),
+	IMX_PINCTRL_PIN(IMX8DXL_COMP_CTL_GPIO_1V8_3V3_GPIORHB),
+	IMX_PINCTRL_PIN(IMX8DXL_SPI3_SCK),
+	IMX_PINCTRL_PIN(IMX8DXL_SPI3_SDO),
+	IMX_PINCTRL_PIN(IMX8DXL_SPI3_SDI),
+	IMX_PINCTRL_PIN(IMX8DXL_SPI3_CS0),
+	IMX_PINCTRL_PIN(IMX8DXL_SPI3_CS1),
+	IMX_PINCTRL_PIN(IMX8DXL_MCLK_IN1),
+	IMX_PINCTRL_PIN(IMX8DXL_MCLK_IN0),
+	IMX_PINCTRL_PIN(IMX8DXL_MCLK_OUT0),
+	IMX_PINCTRL_PIN(IMX8DXL_UART1_TX),
+	IMX_PINCTRL_PIN(IMX8DXL_UART1_RX),
+	IMX_PINCTRL_PIN(IMX8DXL_UART1_RTS_B),
+	IMX_PINCTRL_PIN(IMX8DXL_UART1_CTS_B),
+	IMX_PINCTRL_PIN(IMX8DXL_COMP_CTL_GPIO_1V8_3V3_GPIORHK),
+	IMX_PINCTRL_PIN(IMX8DXL_SPI0_SCK),
+	IMX_PINCTRL_PIN(IMX8DXL_SPI0_SDI),
+	IMX_PINCTRL_PIN(IMX8DXL_SPI0_SDO),
+	IMX_PINCTRL_PIN(IMX8DXL_SPI0_CS1),
+	IMX_PINCTRL_PIN(IMX8DXL_SPI0_CS0),
+	IMX_PINCTRL_PIN(IMX8DXL_COMP_CTL_GPIO_1V8_3V3_GPIORHT),
+	IMX_PINCTRL_PIN(IMX8DXL_ADC_IN1),
+	IMX_PINCTRL_PIN(IMX8DXL_ADC_IN0),
+	IMX_PINCTRL_PIN(IMX8DXL_ADC_IN3),
+	IMX_PINCTRL_PIN(IMX8DXL_ADC_IN2),
+	IMX_PINCTRL_PIN(IMX8DXL_ADC_IN5),
+	IMX_PINCTRL_PIN(IMX8DXL_ADC_IN4),
+	IMX_PINCTRL_PIN(IMX8DXL_FLEXCAN0_RX),
+	IMX_PINCTRL_PIN(IMX8DXL_FLEXCAN0_TX),
+	IMX_PINCTRL_PIN(IMX8DXL_FLEXCAN1_RX),
+	IMX_PINCTRL_PIN(IMX8DXL_FLEXCAN1_TX),
+	IMX_PINCTRL_PIN(IMX8DXL_FLEXCAN2_RX),
+	IMX_PINCTRL_PIN(IMX8DXL_FLEXCAN2_TX),
+	IMX_PINCTRL_PIN(IMX8DXL_UART0_RX),
+	IMX_PINCTRL_PIN(IMX8DXL_UART0_TX),
+	IMX_PINCTRL_PIN(IMX8DXL_UART2_TX),
+	IMX_PINCTRL_PIN(IMX8DXL_UART2_RX),
+	IMX_PINCTRL_PIN(IMX8DXL_COMP_CTL_GPIO_1V8_3V3_GPIOLH),
+	IMX_PINCTRL_PIN(IMX8DXL_JTAG_TRST_B),
+	IMX_PINCTRL_PIN(IMX8DXL_PMIC_I2C_SCL),
+	IMX_PINCTRL_PIN(IMX8DXL_PMIC_I2C_SDA),
+	IMX_PINCTRL_PIN(IMX8DXL_PMIC_INT_B),
+	IMX_PINCTRL_PIN(IMX8DXL_SCU_GPIO0_00),
+	IMX_PINCTRL_PIN(IMX8DXL_SCU_GPIO0_01),
+	IMX_PINCTRL_PIN(IMX8DXL_SCU_PMIC_STANDBY),
+	IMX_PINCTRL_PIN(IMX8DXL_SCU_BOOT_MODE1),
+	IMX_PINCTRL_PIN(IMX8DXL_SCU_BOOT_MODE0),
+	IMX_PINCTRL_PIN(IMX8DXL_SCU_BOOT_MODE2),
+	IMX_PINCTRL_PIN(IMX8DXL_SNVS_TAMPER_OUT1),
+	IMX_PINCTRL_PIN(IMX8DXL_SNVS_TAMPER_OUT2),
+	IMX_PINCTRL_PIN(IMX8DXL_SNVS_TAMPER_OUT3),
+	IMX_PINCTRL_PIN(IMX8DXL_SNVS_TAMPER_OUT4),
+	IMX_PINCTRL_PIN(IMX8DXL_SNVS_TAMPER_IN0),
+	IMX_PINCTRL_PIN(IMX8DXL_SNVS_TAMPER_IN1),
+	IMX_PINCTRL_PIN(IMX8DXL_SNVS_TAMPER_IN2),
+	IMX_PINCTRL_PIN(IMX8DXL_SNVS_TAMPER_IN3),
+	IMX_PINCTRL_PIN(IMX8DXL_SPI1_SCK),
+	IMX_PINCTRL_PIN(IMX8DXL_SPI1_SDO),
+	IMX_PINCTRL_PIN(IMX8DXL_SPI1_SDI),
+	IMX_PINCTRL_PIN(IMX8DXL_SPI1_CS0),
+	IMX_PINCTRL_PIN(IMX8DXL_COMP_CTL_GPIO_1V8_3V3_GPIORHD),
+	IMX_PINCTRL_PIN(IMX8DXL_QSPI0A_DATA1),
+	IMX_PINCTRL_PIN(IMX8DXL_QSPI0A_DATA0),
+	IMX_PINCTRL_PIN(IMX8DXL_QSPI0A_DATA3),
+	IMX_PINCTRL_PIN(IMX8DXL_QSPI0A_DATA2),
+	IMX_PINCTRL_PIN(IMX8DXL_QSPI0A_SS0_B),
+	IMX_PINCTRL_PIN(IMX8DXL_QSPI0A_DQS),
+	IMX_PINCTRL_PIN(IMX8DXL_QSPI0A_SCLK),
+	IMX_PINCTRL_PIN(IMX8DXL_COMP_CTL_GPIO_1V8_3V3_QSPI0A),
+	IMX_PINCTRL_PIN(IMX8DXL_QSPI0B_SCLK),
+	IMX_PINCTRL_PIN(IMX8DXL_QSPI0B_DQS),
+	IMX_PINCTRL_PIN(IMX8DXL_QSPI0B_DATA1),
+	IMX_PINCTRL_PIN(IMX8DXL_QSPI0B_DATA0),
+	IMX_PINCTRL_PIN(IMX8DXL_QSPI0B_DATA3),
+	IMX_PINCTRL_PIN(IMX8DXL_QSPI0B_DATA2),
+	IMX_PINCTRL_PIN(IMX8DXL_QSPI0B_SS0_B),
+	IMX_PINCTRL_PIN(IMX8DXL_COMP_CTL_GPIO_1V8_3V3_QSPI0B)
+};
+
+
+static struct imx_pinctrl_soc_info imx8dxl_pinctrl_info = {
+	.pins = imx8dxl_pinctrl_pads,
+	.npins = ARRAY_SIZE(imx8dxl_pinctrl_pads),
+	.flags = IMX_USE_SCU,
+};
+
+static const struct of_device_id imx8dxl_pinctrl_of_match[] = {
+	{ .compatible = "fsl,imx8dxl-iomuxc", },
+	{ /* sentinel */ }
+};
+
+static int imx8dxl_pinctrl_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = imx_pinctrl_sc_ipc_init(pdev);
+	if (ret)
+		return ret;
+
+	return imx_pinctrl_probe(pdev, &imx8dxl_pinctrl_info);
+}
+
+static struct platform_driver imx8dxl_pinctrl_driver = {
+	.driver = {
+		.name = "fsl,imx8dxl-iomuxc",
+		.of_match_table = of_match_ptr(imx8dxl_pinctrl_of_match),
+		.suppress_bind_attrs = true,
+	},
+	.probe = imx8dxl_pinctrl_probe,
+};
+
+static int __init imx8dxl_pinctrl_init(void)
+{
+	return platform_driver_register(&imx8dxl_pinctrl_driver);
+}
+arch_initcall(imx8dxl_pinctrl_init);
diff --git a/drivers/pinctrl/intel/Kconfig b/drivers/pinctrl/intel/Kconfig
index ee440ec4c94c..787833e343a4 100644
--- a/drivers/pinctrl/intel/Kconfig
+++ b/drivers/pinctrl/intel/Kconfig
@@ -111,6 +111,14 @@ config PINCTRL_ICELAKE
 	  This pinctrl driver provides an interface that allows configuring
 	  of Intel Ice Lake PCH pins and using them as GPIOs.
 
+config PINCTRL_JASPERLAKE
+	tristate "Intel Jasper Lake PCH pinctrl and GPIO driver"
+	depends on ACPI
+	select PINCTRL_INTEL
+	help
+	  This pinctrl driver provides an interface that allows configuring
+	  of Intel Jasper Lake PCH pins and using them as GPIOs.
+
 config PINCTRL_LEWISBURG
 	tristate "Intel Lewisburg pinctrl and GPIO driver"
 	depends on ACPI
diff --git a/drivers/pinctrl/intel/Makefile b/drivers/pinctrl/intel/Makefile
index f60f99cfa7aa..f6f63eb8100f 100644
--- a/drivers/pinctrl/intel/Makefile
+++ b/drivers/pinctrl/intel/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_PINCTRL_CEDARFORK)		+= pinctrl-cedarfork.o
 obj-$(CONFIG_PINCTRL_DENVERTON)		+= pinctrl-denverton.o
 obj-$(CONFIG_PINCTRL_GEMINILAKE)	+= pinctrl-geminilake.o
 obj-$(CONFIG_PINCTRL_ICELAKE)		+= pinctrl-icelake.o
+obj-$(CONFIG_PINCTRL_JASPERLAKE)	+= pinctrl-jasperlake.o
 obj-$(CONFIG_PINCTRL_LEWISBURG)		+= pinctrl-lewisburg.o
 obj-$(CONFIG_PINCTRL_SUNRISEPOINT)	+= pinctrl-sunrisepoint.o
 obj-$(CONFIG_PINCTRL_TIGERLAKE)		+= pinctrl-tigerlake.o
diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c
index b409642f168d..0ff7c55173da 100644
--- a/drivers/pinctrl/intel/pinctrl-baytrail.c
+++ b/drivers/pinctrl/intel/pinctrl-baytrail.c
@@ -1286,6 +1286,7 @@ static const struct gpio_chip byt_gpio_chip = {
 	.direction_output	= byt_gpio_direction_output,
 	.get			= byt_gpio_get,
 	.set			= byt_gpio_set,
+	.set_config		= gpiochip_generic_config,
 	.dbg_show		= byt_gpio_dbg_show,
 };
 
@@ -1505,8 +1506,7 @@ static int byt_gpio_probe(struct intel_pinctrl *vg)
 {
 	struct platform_device *pdev = to_platform_device(vg->dev);
 	struct gpio_chip *gc;
-	struct resource *irq_rc;
-	int ret;
+	int irq, ret;
 
 	/* Set up gpio chip */
 	vg->chip	= byt_gpio_chip;
@@ -1526,8 +1526,8 @@ static int byt_gpio_probe(struct intel_pinctrl *vg)
 #endif
 
 	/* set up interrupts  */
-	irq_rc = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (irq_rc && irq_rc->start) {
+	irq = platform_get_irq_optional(pdev, 0);
+	if (irq > 0) {
 		struct gpio_irq_chip *girq;
 
 		vg->irqchip.name = "BYT-GPIO",
@@ -1547,7 +1547,7 @@ static int byt_gpio_probe(struct intel_pinctrl *vg)
 					     sizeof(*girq->parents), GFP_KERNEL);
 		if (!girq->parents)
 			return -ENOMEM;
-		girq->parents[0] = (unsigned int)irq_rc->start;
+		girq->parents[0] = irq;
 		girq->default_type = IRQ_TYPE_NONE;
 		girq->handler = handle_bad_irq;
 	}
diff --git a/drivers/pinctrl/intel/pinctrl-cannonlake.c b/drivers/pinctrl/intel/pinctrl-cannonlake.c
index f51b27bbf9f1..515f57a0d180 100644
--- a/drivers/pinctrl/intel/pinctrl-cannonlake.c
+++ b/drivers/pinctrl/intel/pinctrl-cannonlake.c
@@ -30,8 +30,6 @@
 		.gpio_base = (g),			\
 	}
 
-#define CNL_NO_GPIO	-1
-
 #define CNL_COMMUNITY(b, s, e, o, g)			\
 	{						\
 		.barno = (b),				\
@@ -377,27 +375,27 @@ static const struct intel_padgroup cnlh_community0_gpps[] = {
 };
 
 static const struct intel_padgroup cnlh_community1_gpps[] = {
-	CNL_GPP(0, 51, 74, 64),			/* GPP_C */
-	CNL_GPP(1, 75, 98, 96),			/* GPP_D */
-	CNL_GPP(2, 99, 106, 128),		/* GPP_G */
-	CNL_GPP(3, 107, 114, CNL_NO_GPIO),	/* AZA */
-	CNL_GPP(4, 115, 146, 160),		/* vGPIO_0 */
-	CNL_GPP(5, 147, 154, CNL_NO_GPIO),	/* vGPIO_1 */
+	CNL_GPP(0, 51, 74, 64),				/* GPP_C */
+	CNL_GPP(1, 75, 98, 96),				/* GPP_D */
+	CNL_GPP(2, 99, 106, 128),			/* GPP_G */
+	CNL_GPP(3, 107, 114, INTEL_GPIO_BASE_NOMAP),	/* AZA */
+	CNL_GPP(4, 115, 146, 160),			/* vGPIO_0 */
+	CNL_GPP(5, 147, 154, INTEL_GPIO_BASE_NOMAP),	/* vGPIO_1 */
 };
 
 static const struct intel_padgroup cnlh_community3_gpps[] = {
-	CNL_GPP(0, 155, 178, 192),		/* GPP_K */
-	CNL_GPP(1, 179, 202, 224),		/* GPP_H */
-	CNL_GPP(2, 203, 215, 256),		/* GPP_E */
-	CNL_GPP(3, 216, 239, 288),		/* GPP_F */
-	CNL_GPP(4, 240, 248, CNL_NO_GPIO),	/* SPI */
+	CNL_GPP(0, 155, 178, 192),			/* GPP_K */
+	CNL_GPP(1, 179, 202, 224),			/* GPP_H */
+	CNL_GPP(2, 203, 215, 256),			/* GPP_E */
+	CNL_GPP(3, 216, 239, 288),			/* GPP_F */
+	CNL_GPP(4, 240, 248, INTEL_GPIO_BASE_NOMAP),	/* SPI */
 };
 
 static const struct intel_padgroup cnlh_community4_gpps[] = {
-	CNL_GPP(0, 249, 259, CNL_NO_GPIO),	/* CPU */
-	CNL_GPP(1, 260, 268, CNL_NO_GPIO),	/* JTAG */
-	CNL_GPP(2, 269, 286, 320),		/* GPP_I */
-	CNL_GPP(3, 287, 298, 352),		/* GPP_J */
+	CNL_GPP(0, 249, 259, INTEL_GPIO_BASE_NOMAP),	/* CPU */
+	CNL_GPP(1, 260, 268, INTEL_GPIO_BASE_NOMAP),	/* JTAG */
+	CNL_GPP(2, 269, 286, 320),			/* GPP_I */
+	CNL_GPP(3, 287, 298, 352),			/* GPP_J */
 };
 
 static const unsigned int cnlh_spi0_pins[] = { 40, 41, 42, 43 };
@@ -790,25 +788,25 @@ static const struct intel_function cnllp_functions[] = {
 };
 
 static const struct intel_padgroup cnllp_community0_gpps[] = {
-	CNL_GPP(0, 0, 24, 0),			/* GPP_A */
-	CNL_GPP(1, 25, 50, 32),			/* GPP_B */
-	CNL_GPP(2, 51, 58, 64),			/* GPP_G */
-	CNL_GPP(3, 59, 67, CNL_NO_GPIO),	/* SPI */
+	CNL_GPP(0, 0, 24, 0),				/* GPP_A */
+	CNL_GPP(1, 25, 50, 32),				/* GPP_B */
+	CNL_GPP(2, 51, 58, 64),				/* GPP_G */
+	CNL_GPP(3, 59, 67, INTEL_GPIO_BASE_NOMAP),	/* SPI */
 };
 
 static const struct intel_padgroup cnllp_community1_gpps[] = {
-	CNL_GPP(0, 68, 92, 96),			/* GPP_D */
-	CNL_GPP(1, 93, 116, 128),		/* GPP_F */
-	CNL_GPP(2, 117, 140, 160),		/* GPP_H */
-	CNL_GPP(3, 141, 172, 192),		/* vGPIO */
-	CNL_GPP(4, 173, 180, 224),		/* vGPIO */
+	CNL_GPP(0, 68, 92, 96),				/* GPP_D */
+	CNL_GPP(1, 93, 116, 128),			/* GPP_F */
+	CNL_GPP(2, 117, 140, 160),			/* GPP_H */
+	CNL_GPP(3, 141, 172, 192),			/* vGPIO */
+	CNL_GPP(4, 173, 180, 224),			/* vGPIO */
 };
 
 static const struct intel_padgroup cnllp_community4_gpps[] = {
-	CNL_GPP(0, 181, 204, 256),		/* GPP_C */
-	CNL_GPP(1, 205, 228, 288),		/* GPP_E */
-	CNL_GPP(2, 229, 237, CNL_NO_GPIO),	/* JTAG */
-	CNL_GPP(3, 238, 243, CNL_NO_GPIO),	/* HVCMOS */
+	CNL_GPP(0, 181, 204, 256),			/* GPP_C */
+	CNL_GPP(1, 205, 228, 288),			/* GPP_E */
+	CNL_GPP(2, 229, 237, INTEL_GPIO_BASE_NOMAP),	/* JTAG */
+	CNL_GPP(3, 238, 243, INTEL_GPIO_BASE_NOMAP),	/* HVCMOS */
 };
 
 static const struct intel_community cnllp_communities[] = {
diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c
index 4c74fdde576d..53f2775f7184 100644
--- a/drivers/pinctrl/intel/pinctrl-cherryview.c
+++ b/drivers/pinctrl/intel/pinctrl-cherryview.c
@@ -35,18 +35,18 @@
 
 #define CHV_PADCTRL0			0x000
 #define CHV_PADCTRL0_INTSEL_SHIFT	28
-#define CHV_PADCTRL0_INTSEL_MASK	(0xf << CHV_PADCTRL0_INTSEL_SHIFT)
+#define CHV_PADCTRL0_INTSEL_MASK	GENMASK(31, 28)
 #define CHV_PADCTRL0_TERM_UP		BIT(23)
 #define CHV_PADCTRL0_TERM_SHIFT		20
-#define CHV_PADCTRL0_TERM_MASK		(7 << CHV_PADCTRL0_TERM_SHIFT)
+#define CHV_PADCTRL0_TERM_MASK		GENMASK(22, 20)
 #define CHV_PADCTRL0_TERM_20K		1
 #define CHV_PADCTRL0_TERM_5K		2
 #define CHV_PADCTRL0_TERM_1K		4
 #define CHV_PADCTRL0_PMODE_SHIFT	16
-#define CHV_PADCTRL0_PMODE_MASK		(0xf << CHV_PADCTRL0_PMODE_SHIFT)
+#define CHV_PADCTRL0_PMODE_MASK		GENMASK(19, 16)
 #define CHV_PADCTRL0_GPIOEN		BIT(15)
 #define CHV_PADCTRL0_GPIOCFG_SHIFT	8
-#define CHV_PADCTRL0_GPIOCFG_MASK	(7 << CHV_PADCTRL0_GPIOCFG_SHIFT)
+#define CHV_PADCTRL0_GPIOCFG_MASK	GENMASK(10, 8)
 #define CHV_PADCTRL0_GPIOCFG_GPIO	0
 #define CHV_PADCTRL0_GPIOCFG_GPO	1
 #define CHV_PADCTRL0_GPIOCFG_GPI	2
@@ -57,57 +57,16 @@
 #define CHV_PADCTRL1			0x004
 #define CHV_PADCTRL1_CFGLOCK		BIT(31)
 #define CHV_PADCTRL1_INVRXTX_SHIFT	4
-#define CHV_PADCTRL1_INVRXTX_MASK	(0xf << CHV_PADCTRL1_INVRXTX_SHIFT)
-#define CHV_PADCTRL1_INVRXTX_TXENABLE	(2 << CHV_PADCTRL1_INVRXTX_SHIFT)
+#define CHV_PADCTRL1_INVRXTX_MASK	GENMASK(7, 4)
+#define CHV_PADCTRL1_INVRXTX_RXDATA	BIT(6)
+#define CHV_PADCTRL1_INVRXTX_TXENABLE	BIT(5)
 #define CHV_PADCTRL1_ODEN		BIT(3)
-#define CHV_PADCTRL1_INVRXTX_RXDATA	(4 << CHV_PADCTRL1_INVRXTX_SHIFT)
-#define CHV_PADCTRL1_INTWAKECFG_MASK	7
+#define CHV_PADCTRL1_INTWAKECFG_MASK	GENMASK(2, 0)
 #define CHV_PADCTRL1_INTWAKECFG_FALLING	1
 #define CHV_PADCTRL1_INTWAKECFG_RISING	2
 #define CHV_PADCTRL1_INTWAKECFG_BOTH	3
 #define CHV_PADCTRL1_INTWAKECFG_LEVEL	4
 
-/**
- * struct chv_alternate_function - A per group or per pin alternate function
- * @pin: Pin number (only used in per pin configs)
- * @mode: Mode the pin should be set in
- * @invert_oe: Invert OE for this pin
- */
-struct chv_alternate_function {
-	unsigned int pin;
-	u8 mode;
-	bool invert_oe;
-};
-
-/**
- * struct chv_pincgroup - describes a CHV pin group
- * @name: Name of the group
- * @pins: An array of pins in this group
- * @npins: Number of pins in this group
- * @altfunc: Alternate function applied to all pins in this group
- * @overrides: Alternate function override per pin or %NULL if not used
- * @noverrides: Number of per pin alternate function overrides if
- *              @overrides != NULL.
- */
-struct chv_pingroup {
-	const char *name;
-	const unsigned int *pins;
-	size_t npins;
-	struct chv_alternate_function altfunc;
-	const struct chv_alternate_function *overrides;
-	size_t noverrides;
-};
-
-/**
- * struct chv_gpio_pinrange - A range of pins that can be used as GPIOs
- * @base: Start pin number
- * @npins: Number of pins in this range
- */
-struct chv_gpio_pinrange {
-	unsigned int base;
-	unsigned int npins;
-};
-
 /**
  * struct chv_community - A community specific configuration
  * @uid: ACPI _UID used to match the community
@@ -117,8 +76,8 @@ struct chv_gpio_pinrange {
  * @ngroups: Number of groups
  * @functions: All functions in this community
  * @nfunctions: Number of functions
- * @gpio_ranges: An array of GPIO ranges in this community
- * @ngpio_ranges: Number of GPIO ranges
+ * @gpps: Pad groups
+ * @ngpps: Number of pad groups in this community
  * @nirqs: Total number of IRQs this community can generate
  * @acpi_space_id: An address space ID for ACPI OpRegion handler
  */
@@ -126,12 +85,12 @@ struct chv_community {
 	const char *uid;
 	const struct pinctrl_pin_desc *pins;
 	size_t npins;
-	const struct chv_pingroup *groups;
+	const struct intel_pingroup *groups;
 	size_t ngroups;
 	const struct intel_function *functions;
 	size_t nfunctions;
-	const struct chv_gpio_pinrange *gpio_ranges;
-	size_t ngpio_ranges;
+	const struct intel_padgroup *gpps;
+	size_t ngpps;
 	size_t nirqs;
 	acpi_adr_space_type acpi_space_id;
 };
@@ -173,37 +132,14 @@ struct chv_pinctrl {
 	struct chv_pin_context *saved_pin_context;
 };
 
-#define ALTERNATE_FUNCTION(p, m, i)		\
-	{					\
-		.pin = (p),			\
-		.mode = (m),			\
-		.invert_oe = (i),		\
-	}
+#define	PINMODE_INVERT_OE	BIT(15)
 
-#define PIN_GROUP_WITH_ALT(n, p, m, i)		\
-	{					\
-		.name = (n),			\
-		.pins = (p),			\
-		.npins = ARRAY_SIZE((p)),	\
-		.altfunc.mode = (m),		\
-		.altfunc.invert_oe = (i),	\
-	}
+#define PINMODE(m, i)		((m) | ((i) * PINMODE_INVERT_OE))
 
-#define PIN_GROUP_WITH_OVERRIDE(n, p, m, i, o)	\
-	{					\
-		.name = (n),			\
-		.pins = (p),			\
-		.npins = ARRAY_SIZE((p)),	\
-		.altfunc.mode = (m),		\
-		.altfunc.invert_oe = (i),	\
-		.overrides = (o),		\
-		.noverrides = ARRAY_SIZE((o)),	\
-	}
-
-#define GPIO_PINRANGE(start, end)		\
+#define CHV_GPP(start, end)		\
 	{					\
 		.base = (start),		\
-		.npins = (end) - (start) + 1,	\
+		.size = (end) - (start) + 1,	\
 	}
 
 static const struct pinctrl_pin_desc southwest_pins[] = {
@@ -288,40 +224,37 @@ static const unsigned southwest_i2c6_pins[] = { 47, 51 };
 static const unsigned southwest_i2c_nfc_pins[] = { 49, 52 };
 static const unsigned southwest_spi3_pins[] = { 76, 79, 80, 81, 82 };
 
-/* LPE I2S TXD pins need to have invert_oe set */
-static const struct chv_alternate_function southwest_lpe_altfuncs[] = {
-	ALTERNATE_FUNCTION(30, 1, true),
-	ALTERNATE_FUNCTION(34, 1, true),
-	ALTERNATE_FUNCTION(97, 1, true),
+/* Some of LPE I2S TXD pins need to have OE inversion set */
+static const unsigned int southwest_lpe_altfuncs[] = {
+	PINMODE(1, 1), PINMODE(1, 0), PINMODE(1, 0), PINMODE(1, 0), /* 30, 31, 32, 33 */
+	PINMODE(1, 1), PINMODE(1, 0), PINMODE(1, 0), PINMODE(1, 0), /* 34, 35, 36, 37 */
+	PINMODE(1, 0), PINMODE(1, 0), PINMODE(1, 0), PINMODE(1, 1), /* 92, 94, 96, 97 */
 };
 
 /*
  * Two spi3 chipselects are available in different mode than the main spi3
- * functionality, which is using mode 1.
+ * functionality, which is using mode 2.
  */
-static const struct chv_alternate_function southwest_spi3_altfuncs[] = {
-	ALTERNATE_FUNCTION(76, 3, false),
-	ALTERNATE_FUNCTION(80, 3, false),
+static const unsigned int southwest_spi3_altfuncs[] = {
+	PINMODE(3, 0), PINMODE(2, 0), PINMODE(3, 0), PINMODE(2, 0), /* 76, 79, 80, 81 */
+	PINMODE(2, 0),						    /* 82 */
 };
 
-static const struct chv_pingroup southwest_groups[] = {
-	PIN_GROUP_WITH_ALT("uart0_grp", southwest_uart0_pins, 2, false),
-	PIN_GROUP_WITH_ALT("uart1_grp", southwest_uart1_pins, 1, false),
-	PIN_GROUP_WITH_ALT("uart2_grp", southwest_uart2_pins, 1, false),
-	PIN_GROUP_WITH_ALT("hda_grp", southwest_hda_pins, 2, false),
-	PIN_GROUP_WITH_ALT("i2c0_grp", southwest_i2c0_pins, 1, true),
-	PIN_GROUP_WITH_ALT("i2c1_grp", southwest_i2c1_pins, 1, true),
-	PIN_GROUP_WITH_ALT("i2c2_grp", southwest_i2c2_pins, 1, true),
-	PIN_GROUP_WITH_ALT("i2c3_grp", southwest_i2c3_pins, 1, true),
-	PIN_GROUP_WITH_ALT("i2c4_grp", southwest_i2c4_pins, 1, true),
-	PIN_GROUP_WITH_ALT("i2c5_grp", southwest_i2c5_pins, 1, true),
-	PIN_GROUP_WITH_ALT("i2c6_grp", southwest_i2c6_pins, 1, true),
-	PIN_GROUP_WITH_ALT("i2c_nfc_grp", southwest_i2c_nfc_pins, 2, true),
-
-	PIN_GROUP_WITH_OVERRIDE("lpe_grp", southwest_lpe_pins, 1, false,
-				southwest_lpe_altfuncs),
-	PIN_GROUP_WITH_OVERRIDE("spi3_grp", southwest_spi3_pins, 2, false,
-				southwest_spi3_altfuncs),
+static const struct intel_pingroup southwest_groups[] = {
+	PIN_GROUP("uart0_grp", southwest_uart0_pins, PINMODE(2, 0)),
+	PIN_GROUP("uart1_grp", southwest_uart1_pins, PINMODE(1, 0)),
+	PIN_GROUP("uart2_grp", southwest_uart2_pins, PINMODE(1, 0)),
+	PIN_GROUP("hda_grp", southwest_hda_pins, PINMODE(2, 0)),
+	PIN_GROUP("i2c0_grp", southwest_i2c0_pins, PINMODE(1, 1)),
+	PIN_GROUP("i2c1_grp", southwest_i2c1_pins, PINMODE(1, 1)),
+	PIN_GROUP("i2c2_grp", southwest_i2c2_pins, PINMODE(1, 1)),
+	PIN_GROUP("i2c3_grp", southwest_i2c3_pins, PINMODE(1, 1)),
+	PIN_GROUP("i2c4_grp", southwest_i2c4_pins, PINMODE(1, 1)),
+	PIN_GROUP("i2c5_grp", southwest_i2c5_pins, PINMODE(1, 1)),
+	PIN_GROUP("i2c6_grp", southwest_i2c6_pins, PINMODE(1, 1)),
+	PIN_GROUP("i2c_nfc_grp", southwest_i2c_nfc_pins, PINMODE(2, 1)),
+	PIN_GROUP("lpe_grp", southwest_lpe_pins, southwest_lpe_altfuncs),
+	PIN_GROUP("spi3_grp", southwest_spi3_pins, southwest_spi3_altfuncs),
 };
 
 static const char * const southwest_uart0_groups[] = { "uart0_grp" };
@@ -360,14 +293,14 @@ static const struct intel_function southwest_functions[] = {
 	FUNCTION("spi3", southwest_spi3_groups),
 };
 
-static const struct chv_gpio_pinrange southwest_gpio_ranges[] = {
-	GPIO_PINRANGE(0, 7),
-	GPIO_PINRANGE(15, 22),
-	GPIO_PINRANGE(30, 37),
-	GPIO_PINRANGE(45, 52),
-	GPIO_PINRANGE(60, 67),
-	GPIO_PINRANGE(75, 82),
-	GPIO_PINRANGE(90, 97),
+static const struct intel_padgroup southwest_gpps[] = {
+	CHV_GPP(0, 7),
+	CHV_GPP(15, 22),
+	CHV_GPP(30, 37),
+	CHV_GPP(45, 52),
+	CHV_GPP(60, 67),
+	CHV_GPP(75, 82),
+	CHV_GPP(90, 97),
 };
 
 static const struct chv_community southwest_community = {
@@ -378,8 +311,8 @@ static const struct chv_community southwest_community = {
 	.ngroups = ARRAY_SIZE(southwest_groups),
 	.functions = southwest_functions,
 	.nfunctions = ARRAY_SIZE(southwest_functions),
-	.gpio_ranges = southwest_gpio_ranges,
-	.ngpio_ranges = ARRAY_SIZE(southwest_gpio_ranges),
+	.gpps = southwest_gpps,
+	.ngpps = ARRAY_SIZE(southwest_gpps),
 	/*
 	 * Southwest community can generate GPIO interrupts only for the
 	 * first 8 interrupts. The upper half (8-15) can only be used to
@@ -455,20 +388,20 @@ static const struct pinctrl_pin_desc north_pins[] = {
 	PINCTRL_PIN(72, "PANEL0_VDDEN"),
 };
 
-static const struct chv_gpio_pinrange north_gpio_ranges[] = {
-	GPIO_PINRANGE(0, 8),
-	GPIO_PINRANGE(15, 27),
-	GPIO_PINRANGE(30, 41),
-	GPIO_PINRANGE(45, 56),
-	GPIO_PINRANGE(60, 72),
+static const struct intel_padgroup north_gpps[] = {
+	CHV_GPP(0, 8),
+	CHV_GPP(15, 27),
+	CHV_GPP(30, 41),
+	CHV_GPP(45, 56),
+	CHV_GPP(60, 72),
 };
 
 static const struct chv_community north_community = {
 	.uid = "2",
 	.pins = north_pins,
 	.npins = ARRAY_SIZE(north_pins),
-	.gpio_ranges = north_gpio_ranges,
-	.ngpio_ranges = ARRAY_SIZE(north_gpio_ranges),
+	.gpps = north_gpps,
+	.ngpps = ARRAY_SIZE(north_gpps),
 	/*
 	 * North community can generate GPIO interrupts only for the first
 	 * 8 interrupts. The upper half (8-15) can only be used to trigger
@@ -506,17 +439,17 @@ static const struct pinctrl_pin_desc east_pins[] = {
 	PINCTRL_PIN(26, "MF_ISH_I2C1_SDA"),
 };
 
-static const struct chv_gpio_pinrange east_gpio_ranges[] = {
-	GPIO_PINRANGE(0, 11),
-	GPIO_PINRANGE(15, 26),
+static const struct intel_padgroup east_gpps[] = {
+	CHV_GPP(0, 11),
+	CHV_GPP(15, 26),
 };
 
 static const struct chv_community east_community = {
 	.uid = "3",
 	.pins = east_pins,
 	.npins = ARRAY_SIZE(east_pins),
-	.gpio_ranges = east_gpio_ranges,
-	.ngpio_ranges = ARRAY_SIZE(east_gpio_ranges),
+	.gpps = east_gpps,
+	.ngpps = ARRAY_SIZE(east_gpps),
 	.nirqs = 16,
 	.acpi_space_id = 0x93,
 };
@@ -596,14 +529,14 @@ static const unsigned southeast_sdmmc3_pins[] = {
 static const unsigned southeast_spi1_pins[] = { 60, 61, 62, 64, 66 };
 static const unsigned southeast_spi2_pins[] = { 2, 3, 4, 6, 7 };
 
-static const struct chv_pingroup southeast_groups[] = {
-	PIN_GROUP_WITH_ALT("pwm0_grp", southeast_pwm0_pins, 1, false),
-	PIN_GROUP_WITH_ALT("pwm1_grp", southeast_pwm1_pins, 1, false),
-	PIN_GROUP_WITH_ALT("sdmmc1_grp", southeast_sdmmc1_pins, 1, false),
-	PIN_GROUP_WITH_ALT("sdmmc2_grp", southeast_sdmmc2_pins, 1, false),
-	PIN_GROUP_WITH_ALT("sdmmc3_grp", southeast_sdmmc3_pins, 1, false),
-	PIN_GROUP_WITH_ALT("spi1_grp", southeast_spi1_pins, 1, false),
-	PIN_GROUP_WITH_ALT("spi2_grp", southeast_spi2_pins, 4, false),
+static const struct intel_pingroup southeast_groups[] = {
+	PIN_GROUP("pwm0_grp", southeast_pwm0_pins, PINMODE(1, 0)),
+	PIN_GROUP("pwm1_grp", southeast_pwm1_pins, PINMODE(1, 0)),
+	PIN_GROUP("sdmmc1_grp", southeast_sdmmc1_pins, PINMODE(1, 0)),
+	PIN_GROUP("sdmmc2_grp", southeast_sdmmc2_pins, PINMODE(1, 0)),
+	PIN_GROUP("sdmmc3_grp", southeast_sdmmc3_pins, PINMODE(1, 0)),
+	PIN_GROUP("spi1_grp", southeast_spi1_pins, PINMODE(1, 0)),
+	PIN_GROUP("spi2_grp", southeast_spi2_pins, PINMODE(4, 0)),
 };
 
 static const char * const southeast_pwm0_groups[] = { "pwm0_grp" };
@@ -624,13 +557,13 @@ static const struct intel_function southeast_functions[] = {
 	FUNCTION("spi2", southeast_spi2_groups),
 };
 
-static const struct chv_gpio_pinrange southeast_gpio_ranges[] = {
-	GPIO_PINRANGE(0, 7),
-	GPIO_PINRANGE(15, 26),
-	GPIO_PINRANGE(30, 35),
-	GPIO_PINRANGE(45, 52),
-	GPIO_PINRANGE(60, 69),
-	GPIO_PINRANGE(75, 85),
+static const struct intel_padgroup southeast_gpps[] = {
+	CHV_GPP(0, 7),
+	CHV_GPP(15, 26),
+	CHV_GPP(30, 35),
+	CHV_GPP(45, 52),
+	CHV_GPP(60, 69),
+	CHV_GPP(75, 85),
 };
 
 static const struct chv_community southeast_community = {
@@ -641,8 +574,8 @@ static const struct chv_community southeast_community = {
 	.ngroups = ARRAY_SIZE(southeast_groups),
 	.functions = southeast_functions,
 	.nfunctions = ARRAY_SIZE(southeast_functions),
-	.gpio_ranges = southeast_gpio_ranges,
-	.ngpio_ranges = ARRAY_SIZE(southeast_gpio_ranges),
+	.gpps = southeast_gpps,
+	.ngpps = ARRAY_SIZE(southeast_gpps),
 	.nirqs = 16,
 	.acpi_space_id = 0x94,
 };
@@ -789,7 +722,7 @@ static int chv_pinmux_set_mux(struct pinctrl_dev *pctldev,
 			      unsigned int function, unsigned int group)
 {
 	struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
-	const struct chv_pingroup *grp;
+	const struct intel_pingroup *grp;
 	unsigned long flags;
 	int i;
 
@@ -808,22 +741,21 @@ static int chv_pinmux_set_mux(struct pinctrl_dev *pctldev,
 	}
 
 	for (i = 0; i < grp->npins; i++) {
-		const struct chv_alternate_function *altfunc = &grp->altfunc;
 		int pin = grp->pins[i];
 		void __iomem *reg;
+		unsigned int mode;
+		bool invert_oe;
 		u32 value;
 
 		/* Check if there is pin-specific config */
-		if (grp->overrides) {
-			int j;
-
-			for (j = 0; j < grp->noverrides; j++) {
-				if (grp->overrides[j].pin == pin) {
-					altfunc = &grp->overrides[j];
-					break;
-				}
-			}
-		}
+		if (grp->modes)
+			mode = grp->modes[i];
+		else
+			mode = grp->mode;
+
+		/* Extract OE inversion */
+		invert_oe = mode & PINMODE_INVERT_OE;
+		mode &= ~PINMODE_INVERT_OE;
 
 		reg = chv_padreg(pctrl, pin, CHV_PADCTRL0);
 		value = readl(reg);
@@ -831,18 +763,18 @@ static int chv_pinmux_set_mux(struct pinctrl_dev *pctldev,
 		value &= ~CHV_PADCTRL0_GPIOEN;
 		/* Set to desired mode */
 		value &= ~CHV_PADCTRL0_PMODE_MASK;
-		value |= altfunc->mode << CHV_PADCTRL0_PMODE_SHIFT;
+		value |= mode << CHV_PADCTRL0_PMODE_SHIFT;
 		chv_writel(value, reg);
 
 		/* Update for invert_oe */
 		reg = chv_padreg(pctrl, pin, CHV_PADCTRL1);
 		value = readl(reg) & ~CHV_PADCTRL1_INVRXTX_MASK;
-		if (altfunc->invert_oe)
+		if (invert_oe)
 			value |= CHV_PADCTRL1_INVRXTX_TXENABLE;
 		chv_writel(value, reg);
 
 		dev_dbg(pctrl->dev, "configured pin %u mode %u OE %sinverted\n",
-			pin, altfunc->mode, altfunc->invert_oe ? "" : "not ");
+			pin, mode, invert_oe ? "" : "not ");
 	}
 
 	raw_spin_unlock_irqrestore(&chv_lock, flags);
@@ -1590,14 +1522,14 @@ static int chv_gpio_add_pin_ranges(struct gpio_chip *chip)
 {
 	struct chv_pinctrl *pctrl = gpiochip_get_data(chip);
 	const struct chv_community *community = pctrl->community;
-	const struct chv_gpio_pinrange *range;
+	const struct intel_padgroup *gpp;
 	int ret, i;
 
-	for (i = 0; i < community->ngpio_ranges; i++) {
-		range = &community->gpio_ranges[i];
+	for (i = 0; i < community->ngpps; i++) {
+		gpp = &community->gpps[i];
 		ret = gpiochip_add_pin_range(chip, dev_name(pctrl->dev),
-					     range->base, range->base,
-					     range->npins);
+					     gpp->base, gpp->base,
+					     gpp->size);
 		if (ret) {
 			dev_err(pctrl->dev, "failed to add GPIO pin range\n");
 			return ret;
@@ -1609,7 +1541,7 @@ static int chv_gpio_add_pin_ranges(struct gpio_chip *chip)
 
 static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq)
 {
-	const struct chv_gpio_pinrange *range;
+	const struct intel_padgroup *gpp;
 	struct gpio_chip *chip = &pctrl->chip;
 	bool need_valid_mask = !dmi_check_system(chv_no_valid_mask);
 	const struct chv_community *community = pctrl->community;
@@ -1657,12 +1589,12 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq)
 	}
 
 	if (!need_valid_mask) {
-		for (i = 0; i < community->ngpio_ranges; i++) {
-			range = &community->gpio_ranges[i];
+		for (i = 0; i < community->ngpps; i++) {
+			gpp = &community->gpps[i];
 
 			irq_domain_associate_many(chip->irq.domain, irq_base,
-						  range->base, range->npins);
-			irq_base += range->npins;
+						  gpp->base, gpp->size);
+			irq_base += gpp->size;
 		}
 	}
 
diff --git a/drivers/pinctrl/intel/pinctrl-icelake.c b/drivers/pinctrl/intel/pinctrl-icelake.c
index 6489e9bbb61f..429b5a83acf0 100644
--- a/drivers/pinctrl/intel/pinctrl-icelake.c
+++ b/drivers/pinctrl/intel/pinctrl-icelake.c
@@ -29,8 +29,6 @@
 		.gpio_base = (g),			\
 	}
 
-#define ICL_NO_GPIO	-1
-
 #define ICL_COMMUNITY(b, s, e, g)			\
 	{						\
 		.barno = (b),				\
@@ -305,29 +303,29 @@ static const struct pinctrl_pin_desc icllp_pins[] = {
 };
 
 static const struct intel_padgroup icllp_community0_gpps[] = {
-	ICL_GPP(0, 0, 7, 0),			/* GPP_G */
-	ICL_GPP(1, 8, 33, 32),			/* GPP_B */
-	ICL_GPP(2, 34, 58, 64),			/* GPP_A */
+	ICL_GPP(0, 0, 7, 0),				/* GPP_G */
+	ICL_GPP(1, 8, 33, 32),				/* GPP_B */
+	ICL_GPP(2, 34, 58, 64),				/* GPP_A */
 };
 
 static const struct intel_padgroup icllp_community1_gpps[] = {
-	ICL_GPP(0, 59, 82, 96),			/* GPP_H */
-	ICL_GPP(1, 83, 103, 128),		/* GPP_D */
-	ICL_GPP(2, 104, 123, 160),		/* GPP_F */
-	ICL_GPP(3, 124, 152, 192),		/* vGPIO */
+	ICL_GPP(0, 59, 82, 96),				/* GPP_H */
+	ICL_GPP(1, 83, 103, 128),			/* GPP_D */
+	ICL_GPP(2, 104, 123, 160),			/* GPP_F */
+	ICL_GPP(3, 124, 152, 192),			/* vGPIO */
 };
 
 static const struct intel_padgroup icllp_community4_gpps[] = {
-	ICL_GPP(0, 153, 176, 224),		/* GPP_C */
-	ICL_GPP(1, 177, 182, ICL_NO_GPIO),	/* HVCMOS */
-	ICL_GPP(2, 183, 206, 256),		/* GPP_E */
-	ICL_GPP(3, 207, 215, ICL_NO_GPIO),	/* JTAG */
+	ICL_GPP(0, 153, 176, 224),			/* GPP_C */
+	ICL_GPP(1, 177, 182, INTEL_GPIO_BASE_NOMAP),	/* HVCMOS */
+	ICL_GPP(2, 183, 206, 256),			/* GPP_E */
+	ICL_GPP(3, 207, 215, INTEL_GPIO_BASE_NOMAP),	/* JTAG */
 };
 
 static const struct intel_padgroup icllp_community5_gpps[] = {
-	ICL_GPP(0, 216, 223, 288),		/* GPP_R */
-	ICL_GPP(1, 224, 231, 320),		/* GPP_S */
-	ICL_GPP(2, 232, 240, ICL_NO_GPIO),	/* SPI */
+	ICL_GPP(0, 216, 223, 288),			/* GPP_R */
+	ICL_GPP(1, 224, 231, 320),			/* GPP_S */
+	ICL_GPP(2, 232, 240, INTEL_GPIO_BASE_NOMAP),	/* SPI */
 };
 
 static const struct intel_community icllp_communities[] = {
diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c
index 74fdfd2b9ff5..6a274e20d926 100644
--- a/drivers/pinctrl/intel/pinctrl-intel.c
+++ b/drivers/pinctrl/intel/pinctrl-intel.c
@@ -798,7 +798,7 @@ static int intel_gpio_to_pin(struct intel_pinctrl *pctrl, unsigned int offset,
 		for (j = 0; j < comm->ngpps; j++) {
 			const struct intel_padgroup *pgrp = &comm->gpps[j];
 
-			if (pgrp->gpio_base < 0)
+			if (pgrp->gpio_base == INTEL_GPIO_BASE_NOMAP)
 				continue;
 
 			if (offset >= pgrp->gpio_base &&
@@ -1138,7 +1138,7 @@ static int intel_gpio_add_community_ranges(struct intel_pinctrl *pctrl,
 	for (i = 0; i < community->ngpps; i++) {
 		const struct intel_padgroup *gpp = &community->gpps[i];
 
-		if (gpp->gpio_base < 0)
+		if (gpp->gpio_base == INTEL_GPIO_BASE_NOMAP)
 			continue;
 
 		ret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev),
@@ -1180,7 +1180,7 @@ static unsigned int intel_gpio_ngpio(const struct intel_pinctrl *pctrl)
 		for (j = 0; j < community->ngpps; j++) {
 			const struct intel_padgroup *gpp = &community->gpps[j];
 
-			if (gpp->gpio_base < 0)
+			if (gpp->gpio_base == INTEL_GPIO_BASE_NOMAP)
 				continue;
 
 			if (gpp->gpio_base + gpp->size > ngpio)
@@ -1276,8 +1276,18 @@ static int intel_pinctrl_add_padgroups(struct intel_pinctrl *pctrl,
 		if (gpps[i].size > 32)
 			return -EINVAL;
 
-		if (!gpps[i].gpio_base)
-			gpps[i].gpio_base = gpps[i].base;
+		/* Special treatment for GPIO base */
+		switch (gpps[i].gpio_base) {
+			case INTEL_GPIO_BASE_MATCH:
+				gpps[i].gpio_base = gpps[i].base;
+				break;
+			case INTEL_GPIO_BASE_ZERO:
+				gpps[i].gpio_base = 0;
+				break;
+			case INTEL_GPIO_BASE_NOMAP:
+			default:
+				break;
+		}
 
 		gpps[i].padown_num = padown_num;
 
@@ -1596,7 +1606,7 @@ static void intel_restore_hostown(struct intel_pinctrl *pctrl, unsigned int c,
 	struct device *dev = pctrl->dev;
 	u32 requested;
 
-	if (padgrp->gpio_base < 0)
+	if (padgrp->gpio_base == INTEL_GPIO_BASE_NOMAP)
 		return;
 
 	requested = intel_gpio_is_requested(&pctrl->chip, padgrp->gpio_base, padgrp->size);
diff --git a/drivers/pinctrl/intel/pinctrl-intel.h b/drivers/pinctrl/intel/pinctrl-intel.h
index c6f066f6d3fb..87fc0555ef90 100644
--- a/drivers/pinctrl/intel/pinctrl-intel.h
+++ b/drivers/pinctrl/intel/pinctrl-intel.h
@@ -53,8 +53,7 @@ struct intel_function {
  * @reg_num: GPI_IS register number
  * @base: Starting pin of this group
  * @size: Size of this group (maximum is 32).
- * @gpio_base: Starting GPIO base of this group (%0 if matches with @base,
- *	       and %-1 if no GPIO mapping should be created)
+ * @gpio_base: Starting GPIO base of this group
  * @padown_num: PAD_OWN register number (assigned by the core driver)
  *
  * If pad groups of a community are not the same size, use this structure
@@ -68,6 +67,19 @@ struct intel_padgroup {
 	unsigned int padown_num;
 };
 
+/**
+ * enum - Special treatment for GPIO base in pad group
+ *
+ * @INTEL_GPIO_BASE_ZERO:	force GPIO base to be 0
+ * @INTEL_GPIO_BASE_NOMAP:	no GPIO mapping should be created
+ * @INTEL_GPIO_BASE_MATCH:	matches with starting pin number
+ */
+enum {
+	INTEL_GPIO_BASE_ZERO	= -2,
+	INTEL_GPIO_BASE_NOMAP	= -1,
+	INTEL_GPIO_BASE_MATCH	= 0,
+};
+
 /**
  * struct intel_community - Intel pin community description
  * @barno: MMIO BAR number where registers for this community reside
diff --git a/drivers/pinctrl/intel/pinctrl-jasperlake.c b/drivers/pinctrl/intel/pinctrl-jasperlake.c
new file mode 100644
index 000000000000..9bd0e8e6310c
--- /dev/null
+++ b/drivers/pinctrl/intel/pinctrl-jasperlake.c
@@ -0,0 +1,344 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Intel Jasper Lake PCH pinctrl/GPIO driver
+ *
+ * Copyright (C) 2020, Intel Corporation
+ * Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+ */
+
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-intel.h"
+
+#define JSL_PAD_OWN	0x020
+#define JSL_PADCFGLOCK	0x080
+#define JSL_HOSTSW_OWN	0x0b0
+#define JSL_GPI_IS	0x100
+#define JSL_GPI_IE	0x120
+
+#define JSL_GPP(r, s, e, g)				\
+	{						\
+		.reg_num = (r),				\
+		.base = (s),				\
+		.size = ((e) - (s) + 1),		\
+		.gpio_base = (g),			\
+	}
+
+#define JSL_COMMUNITY(b, s, e, g)			\
+	{						\
+		.barno = (b),				\
+		.padown_offset = JSL_PAD_OWN,		\
+		.padcfglock_offset = JSL_PADCFGLOCK,	\
+		.hostown_offset = JSL_HOSTSW_OWN,	\
+		.is_offset = JSL_GPI_IS,		\
+		.ie_offset = JSL_GPI_IE,		\
+		.pin_base = (s),			\
+		.npins = ((e) - (s) + 1),		\
+		.gpps = (g),				\
+		.ngpps = ARRAY_SIZE(g),			\
+	}
+
+/* Jasper Lake */
+static const struct pinctrl_pin_desc jsl_pins[] = {
+	/* GPP_F */
+	PINCTRL_PIN(0, "CNV_BRI_DT_UART0_RTSB"),
+	PINCTRL_PIN(1, "CNV_BRI_RSP_UART0_RXD"),
+	PINCTRL_PIN(2, "EMMC_HIP_MON"),
+	PINCTRL_PIN(3, "CNV_RGI_RSP_UART0_CTSB"),
+	PINCTRL_PIN(4, "CNV_RF_RESET_B"),
+	PINCTRL_PIN(5, "MODEM_CLKREQ"),
+	PINCTRL_PIN(6, "CNV_PA_BLANKING"),
+	PINCTRL_PIN(7, "EMMC_CMD"),
+	PINCTRL_PIN(8, "EMMC_DATA0"),
+	PINCTRL_PIN(9, "EMMC_DATA1"),
+	PINCTRL_PIN(10, "EMMC_DATA2"),
+	PINCTRL_PIN(11, "EMMC_DATA3"),
+	PINCTRL_PIN(12, "EMMC_DATA4"),
+	PINCTRL_PIN(13, "EMMC_DATA5"),
+	PINCTRL_PIN(14, "EMMC_DATA6"),
+	PINCTRL_PIN(15, "EMMC_DATA7"),
+	PINCTRL_PIN(16, "EMMC_RCLK"),
+	PINCTRL_PIN(17, "EMMC_CLK"),
+	PINCTRL_PIN(18, "EMMC_RESETB"),
+	PINCTRL_PIN(19, "A4WP_PRESENT"),
+	/* GPP_B */
+	PINCTRL_PIN(20, "CORE_VID_0"),
+	PINCTRL_PIN(21, "CORE_VID_1"),
+	PINCTRL_PIN(22, "VRALERTB"),
+	PINCTRL_PIN(23, "CPU_GP_2"),
+	PINCTRL_PIN(24, "CPU_GP_3"),
+	PINCTRL_PIN(25, "SRCCLKREQB_0"),
+	PINCTRL_PIN(26, "SRCCLKREQB_1"),
+	PINCTRL_PIN(27, "SRCCLKREQB_2"),
+	PINCTRL_PIN(28, "SRCCLKREQB_3"),
+	PINCTRL_PIN(29, "SRCCLKREQB_4"),
+	PINCTRL_PIN(30, "SRCCLKREQB_5"),
+	PINCTRL_PIN(31, "PMCALERTB"),
+	PINCTRL_PIN(32, "SLP_S0B"),
+	PINCTRL_PIN(33, "PLTRSTB"),
+	PINCTRL_PIN(34, "SPKR"),
+	PINCTRL_PIN(35, "GSPI0_CS0B"),
+	PINCTRL_PIN(36, "GSPI0_CLK"),
+	PINCTRL_PIN(37, "GSPI0_MISO"),
+	PINCTRL_PIN(38, "GSPI0_MOSI"),
+	PINCTRL_PIN(39, "GSPI1_CS0B"),
+	PINCTRL_PIN(40, "GSPI1_CLK"),
+	PINCTRL_PIN(41, "GSPI1_MISO"),
+	PINCTRL_PIN(42, "GSPI1_MOSI"),
+	PINCTRL_PIN(43, "DDSP_HPD_A"),
+	PINCTRL_PIN(44, "GSPI0_CLK_LOOPBK"),
+	PINCTRL_PIN(45, "GSPI1_CLK_LOOPBK"),
+	/* GPP_A */
+	PINCTRL_PIN(46, "ESPI_IO_0"),
+	PINCTRL_PIN(47, "ESPI_IO_1"),
+	PINCTRL_PIN(48, "ESPI_IO_2"),
+	PINCTRL_PIN(49, "ESPI_IO_3"),
+	PINCTRL_PIN(50, "ESPI_CSB"),
+	PINCTRL_PIN(51, "ESPI_CLK"),
+	PINCTRL_PIN(52, "ESPI_RESETB"),
+	PINCTRL_PIN(53, "SMBCLK"),
+	PINCTRL_PIN(54, "SMBDATA"),
+	PINCTRL_PIN(55, "SMBALERTB"),
+	PINCTRL_PIN(56, "CPU_GP_0"),
+	PINCTRL_PIN(57, "CPU_GP_1"),
+	PINCTRL_PIN(58, "USB2_OCB_1"),
+	PINCTRL_PIN(59, "USB2_OCB_2"),
+	PINCTRL_PIN(60, "USB2_OCB_3"),
+	PINCTRL_PIN(61, "DDSP_HPD_A_TIME_SYNC_0"),
+	PINCTRL_PIN(62, "DDSP_HPD_B"),
+	PINCTRL_PIN(63, "DDSP_HPD_C"),
+	PINCTRL_PIN(64, "USB2_OCB_0"),
+	PINCTRL_PIN(65, "PCHHOTB"),
+	PINCTRL_PIN(66, "ESPI_CLK_LOOPBK"),
+	/* GPP_S */
+	PINCTRL_PIN(67, "SNDW1_CLK"),
+	PINCTRL_PIN(68, "SNDW1_DATA"),
+	PINCTRL_PIN(69, "SNDW2_CLK"),
+	PINCTRL_PIN(70, "SNDW2_DATA"),
+	PINCTRL_PIN(71, "SNDW1_CLK"),
+	PINCTRL_PIN(72, "SNDW1_DATA"),
+	PINCTRL_PIN(73, "SNDW4_CLK_DMIC_CLK_0"),
+	PINCTRL_PIN(74, "SNDW4_DATA_DMIC_DATA_0"),
+	/* GPP_R */
+	PINCTRL_PIN(75, "HDA_BCLK"),
+	PINCTRL_PIN(76, "HDA_SYNC"),
+	PINCTRL_PIN(77, "HDA_SDO"),
+	PINCTRL_PIN(78, "HDA_SDI_0"),
+	PINCTRL_PIN(79, "HDA_RSTB"),
+	PINCTRL_PIN(80, "HDA_SDI_1"),
+	PINCTRL_PIN(81, "I2S1_SFRM"),
+	PINCTRL_PIN(82, "I2S1_TXD"),
+	/* GPP_H */
+	PINCTRL_PIN(83, "GPPC_H_0"),
+	PINCTRL_PIN(84, "SD_PWR_EN_B"),
+	PINCTRL_PIN(85, "MODEM_CLKREQ"),
+	PINCTRL_PIN(86, "SX_EXIT_HOLDOFFB"),
+	PINCTRL_PIN(87, "I2C2_SDA"),
+	PINCTRL_PIN(88, "I2C2_SCL"),
+	PINCTRL_PIN(89, "I2C3_SDA"),
+	PINCTRL_PIN(90, "I2C3_SCL"),
+	PINCTRL_PIN(91, "I2C4_SDA"),
+	PINCTRL_PIN(92, "I2C4_SCL"),
+	PINCTRL_PIN(93, "CPU_VCCIO_PWR_GATEB"),
+	PINCTRL_PIN(94, "I2S2_SCLK"),
+	PINCTRL_PIN(95, "I2S2_SFRM"),
+	PINCTRL_PIN(96, "I2S2_TXD"),
+	PINCTRL_PIN(97, "I2S2_RXD"),
+	PINCTRL_PIN(98, "I2S1_SCLK"),
+	PINCTRL_PIN(99, "GPPC_H_16"),
+	PINCTRL_PIN(100, "GPPC_H_17"),
+	PINCTRL_PIN(101, "GPPC_H_18"),
+	PINCTRL_PIN(102, "GPPC_H_19"),
+	PINCTRL_PIN(103, "GPPC_H_20"),
+	PINCTRL_PIN(104, "GPPC_H_21"),
+	PINCTRL_PIN(105, "GPPC_H_22"),
+	PINCTRL_PIN(106, "GPPC_H_23"),
+	/* GPP_D */
+	PINCTRL_PIN(107, "SPI1_CSB"),
+	PINCTRL_PIN(108, "SPI1_CLK"),
+	PINCTRL_PIN(109, "SPI1_MISO_IO_1"),
+	PINCTRL_PIN(110, "SPI1_MOSI_IO_0"),
+	PINCTRL_PIN(111, "ISH_I2C0_SDA"),
+	PINCTRL_PIN(112, "ISH_I2C0_SCL"),
+	PINCTRL_PIN(113, "ISH_I2C1_SDA"),
+	PINCTRL_PIN(114, "ISH_I2C1_SCL"),
+	PINCTRL_PIN(115, "ISH_SPI_CSB"),
+	PINCTRL_PIN(116, "ISH_SPI_CLK"),
+	PINCTRL_PIN(117, "ISH_SPI_MISO"),
+	PINCTRL_PIN(118, "ISH_SPI_MOSI"),
+	PINCTRL_PIN(119, "ISH_UART0_RXD"),
+	PINCTRL_PIN(120, "ISH_UART0_TXD"),
+	PINCTRL_PIN(121, "ISH_UART0_RTSB"),
+	PINCTRL_PIN(122, "ISH_UART0_CTSB"),
+	PINCTRL_PIN(123, "SPI1_IO_2"),
+	PINCTRL_PIN(124, "SPI1_IO_3"),
+	PINCTRL_PIN(125, "I2S_MCLK"),
+	PINCTRL_PIN(126, "CNV_MFUART2_RXD"),
+	PINCTRL_PIN(127, "CNV_MFUART2_TXD"),
+	PINCTRL_PIN(128, "CNV_PA_BLANKING"),
+	PINCTRL_PIN(129, "I2C5_SDA"),
+	PINCTRL_PIN(130, "I2C5_SCL"),
+	PINCTRL_PIN(131, "GSPI2_CLK_LOOPBK"),
+	PINCTRL_PIN(132, "SPI1_CLK_LOOPBK"),
+	/* vGPIO */
+	PINCTRL_PIN(133, "CNV_BTEN"),
+	PINCTRL_PIN(134, "CNV_WCEN"),
+	PINCTRL_PIN(135, "CNV_BT_HOST_WAKEB"),
+	PINCTRL_PIN(136, "CNV_BT_IF_SELECT"),
+	PINCTRL_PIN(137, "vCNV_BT_UART_TXD"),
+	PINCTRL_PIN(138, "vCNV_BT_UART_RXD"),
+	PINCTRL_PIN(139, "vCNV_BT_UART_CTS_B"),
+	PINCTRL_PIN(140, "vCNV_BT_UART_RTS_B"),
+	PINCTRL_PIN(141, "vCNV_MFUART1_TXD"),
+	PINCTRL_PIN(142, "vCNV_MFUART1_RXD"),
+	PINCTRL_PIN(143, "vCNV_MFUART1_CTS_B"),
+	PINCTRL_PIN(144, "vCNV_MFUART1_RTS_B"),
+	PINCTRL_PIN(145, "vUART0_TXD"),
+	PINCTRL_PIN(146, "vUART0_RXD"),
+	PINCTRL_PIN(147, "vUART0_CTS_B"),
+	PINCTRL_PIN(148, "vUART0_RTS_B"),
+	PINCTRL_PIN(149, "vISH_UART0_TXD"),
+	PINCTRL_PIN(150, "vISH_UART0_RXD"),
+	PINCTRL_PIN(151, "vISH_UART0_CTS_B"),
+	PINCTRL_PIN(152, "vISH_UART0_RTS_B"),
+	PINCTRL_PIN(153, "vCNV_BT_I2S_BCLK"),
+	PINCTRL_PIN(154, "vCNV_BT_I2S_WS_SYNC"),
+	PINCTRL_PIN(155, "vCNV_BT_I2S_SDO"),
+	PINCTRL_PIN(156, "vCNV_BT_I2S_SDI"),
+	PINCTRL_PIN(157, "vI2S2_SCLK"),
+	PINCTRL_PIN(158, "vI2S2_SFRM"),
+	PINCTRL_PIN(159, "vI2S2_TXD"),
+	PINCTRL_PIN(160, "vI2S2_RXD"),
+	PINCTRL_PIN(161, "vSD3_CD_B"),
+	/* GPP_C */
+	PINCTRL_PIN(162, "GPPC_C_0"),
+	PINCTRL_PIN(163, "GPPC_C_1"),
+	PINCTRL_PIN(164, "GPPC_C_2"),
+	PINCTRL_PIN(165, "GPPC_C_3"),
+	PINCTRL_PIN(166, "GPPC_C_4"),
+	PINCTRL_PIN(167, "GPPC_C_5"),
+	PINCTRL_PIN(168, "SUSWARNB_SUSPWRDNACK"),
+	PINCTRL_PIN(169, "SUSACKB"),
+	PINCTRL_PIN(170, "UART0_RXD"),
+	PINCTRL_PIN(171, "UART0_TXD"),
+	PINCTRL_PIN(172, "UART0_RTSB"),
+	PINCTRL_PIN(173, "UART0_CTSB"),
+	PINCTRL_PIN(174, "UART1_RXD"),
+	PINCTRL_PIN(175, "UART1_TXD"),
+	PINCTRL_PIN(176, "UART1_RTSB"),
+	PINCTRL_PIN(177, "UART1_CTSB"),
+	PINCTRL_PIN(178, "I2C0_SDA"),
+	PINCTRL_PIN(179, "I2C0_SCL"),
+	PINCTRL_PIN(180, "I2C1_SDA"),
+	PINCTRL_PIN(181, "I2C1_SCL"),
+	PINCTRL_PIN(182, "UART2_RXD"),
+	PINCTRL_PIN(183, "UART2_TXD"),
+	PINCTRL_PIN(184, "UART2_RTSB"),
+	PINCTRL_PIN(185, "UART2_CTSB"),
+	/* HVCMOS */
+	PINCTRL_PIN(186, "L_BKLTEN"),
+	PINCTRL_PIN(187, "L_BKLTCTL"),
+	PINCTRL_PIN(188, "L_VDDEN"),
+	PINCTRL_PIN(189, "SYS_PWROK"),
+	PINCTRL_PIN(190, "SYS_RESETB"),
+	PINCTRL_PIN(191, "MLK_RSTB"),
+	/* GPP_E */
+	PINCTRL_PIN(192, "ISH_GP_0"),
+	PINCTRL_PIN(193, "ISH_GP_1"),
+	PINCTRL_PIN(194, "IMGCLKOUT_1"),
+	PINCTRL_PIN(195, "ISH_GP_2"),
+	PINCTRL_PIN(196, "IMGCLKOUT_2"),
+	PINCTRL_PIN(197, "SATA_LEDB"),
+	PINCTRL_PIN(198, "IMGCLKOUT_3"),
+	PINCTRL_PIN(199, "ISH_GP_3"),
+	PINCTRL_PIN(200, "ISH_GP_4"),
+	PINCTRL_PIN(201, "ISH_GP_5"),
+	PINCTRL_PIN(202, "ISH_GP_6"),
+	PINCTRL_PIN(203, "ISH_GP_7"),
+	PINCTRL_PIN(204, "IMGCLKOUT_4"),
+	PINCTRL_PIN(205, "DDPA_CTRLCLK"),
+	PINCTRL_PIN(206, "DDPA_CTRLDATA"),
+	PINCTRL_PIN(207, "DDPB_CTRLCLK"),
+	PINCTRL_PIN(208, "DDPB_CTRLDATA"),
+	PINCTRL_PIN(209, "DDPC_CTRLCLK"),
+	PINCTRL_PIN(210, "DDPC_CTRLDATA"),
+	PINCTRL_PIN(211, "IMGCLKOUT_5"),
+	PINCTRL_PIN(212, "CNV_BRI_DT"),
+	PINCTRL_PIN(213, "CNV_BRI_RSP"),
+	PINCTRL_PIN(214, "CNV_RGI_DT"),
+	PINCTRL_PIN(215, "CNV_RGI_RSP"),
+	/* GPP_G */
+	PINCTRL_PIN(216, "SD3_CMD"),
+	PINCTRL_PIN(217, "SD3_D0"),
+	PINCTRL_PIN(218, "SD3_D1"),
+	PINCTRL_PIN(219, "SD3_D2"),
+	PINCTRL_PIN(220, "SD3_D3"),
+	PINCTRL_PIN(221, "SD3_CDB"),
+	PINCTRL_PIN(222, "SD3_CLK"),
+	PINCTRL_PIN(223, "SD3_WP"),
+};
+
+static const struct intel_padgroup jsl_community0_gpps[] = {
+	JSL_GPP(0, 0, 19, 320),				/* GPP_F */
+	JSL_GPP(1, 20, 45, 32),				/* GPP_B */
+	JSL_GPP(2, 46, 66, 64),				/* GPP_A */
+	JSL_GPP(3, 67, 74, 96),				/* GPP_S */
+	JSL_GPP(4, 75, 82, 128),			/* GPP_R */
+};
+
+static const struct intel_padgroup jsl_community1_gpps[] = {
+	JSL_GPP(0, 83, 106, 160),			/* GPP_H */
+	JSL_GPP(1, 107, 132, 192),			/* GPP_D */
+	JSL_GPP(2, 133, 161, 224),			/* vGPIO */
+	JSL_GPP(3, 162, 185, 256),			/* GPP_C */
+};
+
+static const struct intel_padgroup jsl_community4_gpps[] = {
+	JSL_GPP(0, 186, 191, INTEL_GPIO_BASE_NOMAP),	/* HVCMOS */
+	JSL_GPP(1, 192, 215, 288),			/* GPP_E */
+};
+
+static const struct intel_padgroup jsl_community5_gpps[] = {
+	JSL_GPP(0, 216, 223, INTEL_GPIO_BASE_ZERO),	/* GPP_G */
+};
+
+static const struct intel_community jsl_communities[] = {
+	JSL_COMMUNITY(0, 0, 82, jsl_community0_gpps),
+	JSL_COMMUNITY(1, 83, 185, jsl_community1_gpps),
+	JSL_COMMUNITY(2, 186, 215, jsl_community4_gpps),
+	JSL_COMMUNITY(3, 216, 223, jsl_community5_gpps),
+};
+
+static const struct intel_pinctrl_soc_data jsl_soc_data = {
+	.pins = jsl_pins,
+	.npins = ARRAY_SIZE(jsl_pins),
+	.communities = jsl_communities,
+	.ncommunities = ARRAY_SIZE(jsl_communities),
+};
+
+static const struct acpi_device_id jsl_pinctrl_acpi_match[] = {
+	{ "INT34C8", (kernel_ulong_t)&jsl_soc_data },
+	{ }
+};
+MODULE_DEVICE_TABLE(acpi, jsl_pinctrl_acpi_match);
+
+static INTEL_PINCTRL_PM_OPS(jsl_pinctrl_pm_ops);
+
+static struct platform_driver jsl_pinctrl_driver = {
+	.probe = intel_pinctrl_probe_by_hid,
+	.driver = {
+		.name = "jasperlake-pinctrl",
+		.acpi_match_table = jsl_pinctrl_acpi_match,
+		.pm = &jsl_pinctrl_pm_ops,
+	},
+};
+
+module_platform_driver(jsl_pinctrl_driver);
+
+MODULE_AUTHOR("Andy Shevchenko <andriy.shevchenko@linux.intel.com>");
+MODULE_DESCRIPTION("Intel Jasper Lake PCH pinctrl/GPIO driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
index e928742c7181..a45b8f2182fd 100644
--- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c
+++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
@@ -794,11 +794,11 @@ static int lp_gpio_probe(struct platform_device *pdev)
 	const struct intel_pinctrl_soc_data *soc;
 	struct intel_pinctrl *lg;
 	struct gpio_chip *gc;
-	struct resource *io_rc, *irq_rc;
 	struct device *dev = &pdev->dev;
+	struct resource *io_rc;
 	void __iomem *regs;
 	unsigned int i;
-	int ret;
+	int irq, ret;
 
 	soc = (const struct intel_pinctrl_soc_data *)device_get_match_data(dev);
 	if (!soc)
@@ -870,8 +870,8 @@ static int lp_gpio_probe(struct platform_device *pdev)
 	gc->parent = dev;
 
 	/* set up interrupts  */
-	irq_rc = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (irq_rc && irq_rc->start) {
+	irq = platform_get_irq_optional(pdev, 0);
+	if (irq > 0) {
 		struct gpio_irq_chip *girq;
 
 		girq = &gc->irq;
@@ -884,7 +884,7 @@ static int lp_gpio_probe(struct platform_device *pdev)
 					     GFP_KERNEL);
 		if (!girq->parents)
 			return -ENOMEM;
-		girq->parents[0] = (unsigned int)irq_rc->start;
+		girq->parents[0] = irq;
 		girq->default_type = IRQ_TYPE_NONE;
 		girq->handler = handle_bad_irq;
 	}
diff --git a/drivers/pinctrl/intel/pinctrl-sunrisepoint.c b/drivers/pinctrl/intel/pinctrl-sunrisepoint.c
index 330c8f077b73..4d7a86a5a37b 100644
--- a/drivers/pinctrl/intel/pinctrl-sunrisepoint.c
+++ b/drivers/pinctrl/intel/pinctrl-sunrisepoint.c
@@ -15,17 +15,18 @@
 
 #include "pinctrl-intel.h"
 
-#define SPT_PAD_OWN	0x020
-#define SPT_PADCFGLOCK	0x0a0
-#define SPT_HOSTSW_OWN	0x0d0
-#define SPT_GPI_IS	0x100
-#define SPT_GPI_IE	0x120
+#define SPT_PAD_OWN		0x020
+#define SPT_H_PADCFGLOCK	0x090
+#define SPT_LP_PADCFGLOCK	0x0a0
+#define SPT_HOSTSW_OWN		0x0d0
+#define SPT_GPI_IS		0x100
+#define SPT_GPI_IE		0x120
 
 #define SPT_COMMUNITY(b, s, e)				\
 	{						\
 		.barno = (b),				\
 		.padown_offset = SPT_PAD_OWN,		\
-		.padcfglock_offset = SPT_PADCFGLOCK,	\
+		.padcfglock_offset = SPT_LP_PADCFGLOCK,	\
 		.hostown_offset = SPT_HOSTSW_OWN,	\
 		.is_offset = SPT_GPI_IS,		\
 		.ie_offset = SPT_GPI_IE,		\
@@ -47,7 +48,7 @@
 	{						\
 		.barno = (b),				\
 		.padown_offset = SPT_PAD_OWN,		\
-		.padcfglock_offset = SPT_PADCFGLOCK,	\
+		.padcfglock_offset = SPT_H_PADCFGLOCK,	\
 		.hostown_offset = SPT_HOSTSW_OWN,	\
 		.is_offset = SPT_GPI_IS,		\
 		.ie_offset = SPT_GPI_IE,		\
diff --git a/drivers/pinctrl/intel/pinctrl-tigerlake.c b/drivers/pinctrl/intel/pinctrl-tigerlake.c
index 08a86f6fdea6..bcfd7548e282 100644
--- a/drivers/pinctrl/intel/pinctrl-tigerlake.c
+++ b/drivers/pinctrl/intel/pinctrl-tigerlake.c
@@ -21,8 +21,6 @@
 #define TGL_GPI_IS	0x100
 #define TGL_GPI_IE	0x120
 
-#define TGL_NO_GPIO	-1
-
 #define TGL_GPP(r, s, e, g)				\
 	{						\
 		.reg_num = (r),				\
@@ -342,30 +340,30 @@ static const struct pinctrl_pin_desc tgllp_pins[] = {
 };
 
 static const struct intel_padgroup tgllp_community0_gpps[] = {
-	TGL_GPP(0, 0, 25, 0),			/* GPP_B */
-	TGL_GPP(1, 26, 41, 32),			/* GPP_T */
-	TGL_GPP(2, 42, 66, 64),			/* GPP_A */
+	TGL_GPP(0, 0, 25, 0),				/* GPP_B */
+	TGL_GPP(1, 26, 41, 32),				/* GPP_T */
+	TGL_GPP(2, 42, 66, 64),				/* GPP_A */
 };
 
 static const struct intel_padgroup tgllp_community1_gpps[] = {
-	TGL_GPP(0, 67, 74, 96),			/* GPP_S */
-	TGL_GPP(1, 75, 98, 128),		/* GPP_H */
-	TGL_GPP(2, 99, 119, 160),		/* GPP_D */
-	TGL_GPP(3, 120, 143, 192),		/* GPP_U */
-	TGL_GPP(4, 144, 170, 224),		/* vGPIO */
+	TGL_GPP(0, 67, 74, 96),				/* GPP_S */
+	TGL_GPP(1, 75, 98, 128),			/* GPP_H */
+	TGL_GPP(2, 99, 119, 160),			/* GPP_D */
+	TGL_GPP(3, 120, 143, 192),			/* GPP_U */
+	TGL_GPP(4, 144, 170, 224),			/* vGPIO */
 };
 
 static const struct intel_padgroup tgllp_community4_gpps[] = {
-	TGL_GPP(0, 171, 194, 256),		/* GPP_C */
-	TGL_GPP(1, 195, 219, 288),		/* GPP_F */
-	TGL_GPP(2, 220, 225, TGL_NO_GPIO),	/* HVCMOS */
-	TGL_GPP(3, 226, 250, 320),		/* GPP_E */
-	TGL_GPP(4, 251, 259, TGL_NO_GPIO),	/* JTAG */
+	TGL_GPP(0, 171, 194, 256),			/* GPP_C */
+	TGL_GPP(1, 195, 219, 288),			/* GPP_F */
+	TGL_GPP(2, 220, 225, INTEL_GPIO_BASE_NOMAP),	/* HVCMOS */
+	TGL_GPP(3, 226, 250, 320),			/* GPP_E */
+	TGL_GPP(4, 251, 259, INTEL_GPIO_BASE_NOMAP),	/* JTAG */
 };
 
 static const struct intel_padgroup tgllp_community5_gpps[] = {
-	TGL_GPP(0, 260, 267, 352),		/* GPP_R */
-	TGL_GPP(1, 268, 276, TGL_NO_GPIO),	/* SPI */
+	TGL_GPP(0, 260, 267, 352),			/* GPP_R */
+	TGL_GPP(1, 268, 276, INTEL_GPIO_BASE_NOMAP),	/* SPI */
 };
 
 static const struct intel_community tgllp_communities[] = {
diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig
index 701f9af63f5e..f32d3644c509 100644
--- a/drivers/pinctrl/mediatek/Kconfig
+++ b/drivers/pinctrl/mediatek/Kconfig
@@ -3,10 +3,12 @@ menu "MediaTek pinctrl drivers"
 	depends on ARCH_MEDIATEK || COMPILE_TEST
 
 config EINT_MTK
-	bool "MediaTek External Interrupt Support"
+	tristate "MediaTek External Interrupt Support"
 	depends on PINCTRL_MTK || PINCTRL_MTK_MOORE || PINCTRL_MTK_PARIS || COMPILE_TEST
 	select GPIOLIB
 	select IRQ_DOMAIN
+	default y if PINCTRL_MTK || PINCTRL_MTK_MOORE
+	default PINCTRL_MTK_PARIS
 
 config PINCTRL_MTK
 	bool
@@ -17,6 +19,9 @@ config PINCTRL_MTK
 	select EINT_MTK
 	select OF_GPIO
 
+config PINCTRL_MTK_V2
+	tristate
+
 config PINCTRL_MTK_MOORE
 	bool
 	depends on OF
@@ -25,15 +30,17 @@ config PINCTRL_MTK_MOORE
 	select GENERIC_PINMUX_FUNCTIONS
 	select GPIOLIB
 	select OF_GPIO
+	select PINCTRL_MTK_V2
 
 config PINCTRL_MTK_PARIS
-	bool
+	tristate
 	depends on OF
 	select PINMUX
 	select GENERIC_PINCONF
 	select GPIOLIB
 	select EINT_MTK
 	select OF_GPIO
+	select PINCTRL_MTK_V2
 
 # For ARMv7 SoCs
 config PINCTRL_MT2701
@@ -80,7 +87,7 @@ config PINCTRL_MT2712
 	select PINCTRL_MTK
 
 config PINCTRL_MT6765
-	bool "Mediatek MT6765 pin control"
+	tristate "Mediatek MT6765 pin control"
 	depends on OF
 	depends on ARM64 || COMPILE_TEST
 	default ARM64 && ARCH_MEDIATEK
diff --git a/drivers/pinctrl/mediatek/Makefile b/drivers/pinctrl/mediatek/Makefile
index a74325abd877..4b7132876e71 100644
--- a/drivers/pinctrl/mediatek/Makefile
+++ b/drivers/pinctrl/mediatek/Makefile
@@ -2,8 +2,9 @@
 # Core
 obj-$(CONFIG_EINT_MTK)		+= mtk-eint.o
 obj-$(CONFIG_PINCTRL_MTK)	+= pinctrl-mtk-common.o
-obj-$(CONFIG_PINCTRL_MTK_MOORE) += pinctrl-moore.o pinctrl-mtk-common-v2.o
-obj-$(CONFIG_PINCTRL_MTK_PARIS) += pinctrl-paris.o pinctrl-mtk-common-v2.o
+obj-$(CONFIG_PINCTRL_MTK_V2)	+= pinctrl-mtk-common-v2.o
+obj-$(CONFIG_PINCTRL_MTK_MOORE) += pinctrl-moore.o
+obj-$(CONFIG_PINCTRL_MTK_PARIS) += pinctrl-paris.o
 
 # SoC Drivers
 obj-$(CONFIG_PINCTRL_MT2701)	+= pinctrl-mt2701.o
diff --git a/drivers/pinctrl/mediatek/mtk-eint.c b/drivers/pinctrl/mediatek/mtk-eint.c
index 7e526bcf5e0b..22736f60c16c 100644
--- a/drivers/pinctrl/mediatek/mtk-eint.c
+++ b/drivers/pinctrl/mediatek/mtk-eint.c
@@ -15,6 +15,7 @@
 #include <linux/io.h>
 #include <linux/irqchip/chained_irq.h>
 #include <linux/irqdomain.h>
+#include <linux/module.h>
 #include <linux/of_irq.h>
 #include <linux/platform_device.h>
 
@@ -379,6 +380,7 @@ int mtk_eint_do_suspend(struct mtk_eint *eint)
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mtk_eint_do_suspend);
 
 int mtk_eint_do_resume(struct mtk_eint *eint)
 {
@@ -386,6 +388,7 @@ int mtk_eint_do_resume(struct mtk_eint *eint)
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mtk_eint_do_resume);
 
 int mtk_eint_set_debounce(struct mtk_eint *eint, unsigned long eint_num,
 			  unsigned int debounce)
@@ -440,6 +443,7 @@ int mtk_eint_set_debounce(struct mtk_eint *eint, unsigned long eint_num,
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mtk_eint_set_debounce);
 
 int mtk_eint_find_irq(struct mtk_eint *eint, unsigned long eint_n)
 {
@@ -451,6 +455,7 @@ int mtk_eint_find_irq(struct mtk_eint *eint, unsigned long eint_n)
 
 	return irq;
 }
+EXPORT_SYMBOL_GPL(mtk_eint_find_irq);
 
 int mtk_eint_do_init(struct mtk_eint *eint)
 {
@@ -495,3 +500,7 @@ int mtk_eint_do_init(struct mtk_eint *eint)
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mtk_eint_do_init);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("MediaTek EINT Driver");
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
index 905dae8c3fd8..2c59d3936256 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt6765.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
@@ -6,6 +6,7 @@
  *
  */
 
+#include <linux/module.h>
 #include "pinctrl-mtk-mt6765.h"
 #include "pinctrl-paris.h"
 
@@ -1103,3 +1104,6 @@ static int __init mt6765_pinctrl_init(void)
 	return platform_driver_register(&mt6765_pinctrl_driver);
 }
 arch_initcall(mt6765_pinctrl_init);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("MediaTek MT6765 Pinctrl Driver");
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
index d3169a87e1b3..6ea40b501328 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
@@ -12,6 +12,7 @@
 #include <linux/gpio/driver.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/module.h>
 #include <linux/of_irq.h>
 
 #include "mtk-eint.h"
@@ -204,6 +205,7 @@ int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mtk_hw_set_value);
 
 int mtk_hw_get_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
 		     int field, int *value)
@@ -223,6 +225,7 @@ int mtk_hw_get_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mtk_hw_get_value);
 
 static int mtk_xt_find_eint_num(struct mtk_pinctrl *hw, unsigned long eint_n)
 {
@@ -361,6 +364,7 @@ int mtk_build_eint(struct mtk_pinctrl *hw, struct platform_device *pdev)
 
 	return mtk_eint_do_init(hw->eint);
 }
+EXPORT_SYMBOL_GPL(mtk_build_eint);
 
 /* Revision 0 */
 int mtk_pinconf_bias_disable_set(struct mtk_pinctrl *hw,
@@ -380,6 +384,7 @@ int mtk_pinconf_bias_disable_set(struct mtk_pinctrl *hw,
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mtk_pinconf_bias_disable_set);
 
 int mtk_pinconf_bias_disable_get(struct mtk_pinctrl *hw,
 				 const struct mtk_pin_desc *desc, int *res)
@@ -402,6 +407,7 @@ int mtk_pinconf_bias_disable_get(struct mtk_pinctrl *hw,
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mtk_pinconf_bias_disable_get);
 
 int mtk_pinconf_bias_set(struct mtk_pinctrl *hw,
 			 const struct mtk_pin_desc *desc, bool pullup)
@@ -421,6 +427,7 @@ int mtk_pinconf_bias_set(struct mtk_pinctrl *hw,
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mtk_pinconf_bias_set);
 
 int mtk_pinconf_bias_get(struct mtk_pinctrl *hw,
 			 const struct mtk_pin_desc *desc, bool pullup, int *res)
@@ -440,6 +447,7 @@ int mtk_pinconf_bias_get(struct mtk_pinctrl *hw,
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mtk_pinconf_bias_get);
 
 /* Revision 1 */
 int mtk_pinconf_bias_disable_set_rev1(struct mtk_pinctrl *hw,
@@ -454,6 +462,7 @@ int mtk_pinconf_bias_disable_set_rev1(struct mtk_pinctrl *hw,
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mtk_pinconf_bias_disable_set_rev1);
 
 int mtk_pinconf_bias_disable_get_rev1(struct mtk_pinctrl *hw,
 				      const struct mtk_pin_desc *desc, int *res)
@@ -471,6 +480,7 @@ int mtk_pinconf_bias_disable_get_rev1(struct mtk_pinctrl *hw,
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mtk_pinconf_bias_disable_get_rev1);
 
 int mtk_pinconf_bias_set_rev1(struct mtk_pinctrl *hw,
 			      const struct mtk_pin_desc *desc, bool pullup)
@@ -490,6 +500,7 @@ int mtk_pinconf_bias_set_rev1(struct mtk_pinctrl *hw,
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mtk_pinconf_bias_set_rev1);
 
 int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw,
 			      const struct mtk_pin_desc *desc, bool pullup,
@@ -515,6 +526,7 @@ int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw,
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mtk_pinconf_bias_get_rev1);
 
 /* Combo for the following pull register type:
  * 1. PU + PD
@@ -715,6 +727,7 @@ int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
 out:
 	return err;
 }
+EXPORT_SYMBOL_GPL(mtk_pinconf_bias_set_combo);
 
 int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw,
 			      const struct mtk_pin_desc *desc,
@@ -735,6 +748,7 @@ int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw,
 out:
 	return err;
 }
+EXPORT_SYMBOL_GPL(mtk_pinconf_bias_get_combo);
 
 /* Revision 0 */
 int mtk_pinconf_drive_set(struct mtk_pinctrl *hw,
@@ -764,6 +778,7 @@ int mtk_pinconf_drive_set(struct mtk_pinctrl *hw,
 
 	return err;
 }
+EXPORT_SYMBOL_GPL(mtk_pinconf_drive_set);
 
 int mtk_pinconf_drive_get(struct mtk_pinctrl *hw,
 			  const struct mtk_pin_desc *desc, int *val)
@@ -788,6 +803,7 @@ int mtk_pinconf_drive_get(struct mtk_pinctrl *hw,
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mtk_pinconf_drive_get);
 
 /* Revision 1 */
 int mtk_pinconf_drive_set_rev1(struct mtk_pinctrl *hw,
@@ -809,6 +825,7 @@ int mtk_pinconf_drive_set_rev1(struct mtk_pinctrl *hw,
 
 	return err;
 }
+EXPORT_SYMBOL_GPL(mtk_pinconf_drive_set_rev1);
 
 int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
 			       const struct mtk_pin_desc *desc, int *val)
@@ -826,18 +843,21 @@ int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mtk_pinconf_drive_get_rev1);
 
 int mtk_pinconf_drive_set_raw(struct mtk_pinctrl *hw,
 			       const struct mtk_pin_desc *desc, u32 arg)
 {
 	return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV, arg);
 }
+EXPORT_SYMBOL_GPL(mtk_pinconf_drive_set_raw);
 
 int mtk_pinconf_drive_get_raw(struct mtk_pinctrl *hw,
 			       const struct mtk_pin_desc *desc, int *val)
 {
 	return mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV, val);
 }
+EXPORT_SYMBOL_GPL(mtk_pinconf_drive_get_raw);
 
 int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
 			     const struct mtk_pin_desc *desc, bool pullup,
@@ -878,6 +898,7 @@ int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
 
 	return err;
 }
+EXPORT_SYMBOL_GPL(mtk_pinconf_adv_pull_set);
 
 int mtk_pinconf_adv_pull_get(struct mtk_pinctrl *hw,
 			     const struct mtk_pin_desc *desc, bool pullup,
@@ -920,6 +941,7 @@ int mtk_pinconf_adv_pull_get(struct mtk_pinctrl *hw,
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mtk_pinconf_adv_pull_get);
 
 int mtk_pinconf_adv_drive_set(struct mtk_pinctrl *hw,
 			      const struct mtk_pin_desc *desc, u32 arg)
@@ -946,6 +968,7 @@ int mtk_pinconf_adv_drive_set(struct mtk_pinctrl *hw,
 
 	return err;
 }
+EXPORT_SYMBOL_GPL(mtk_pinconf_adv_drive_set);
 
 int mtk_pinconf_adv_drive_get(struct mtk_pinctrl *hw,
 			      const struct mtk_pin_desc *desc, u32 *val)
@@ -969,3 +992,4 @@ int mtk_pinconf_adv_drive_get(struct mtk_pinctrl *hw,
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mtk_pinconf_adv_drive_get);
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
index 3853ec3a2a8e..90a432bf9fed 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -10,6 +10,7 @@
  */
 
 #include <linux/gpio/driver.h>
+#include <linux/module.h>
 #include <dt-bindings/pinctrl/mt65xx.h>
 #include "pinctrl-paris.h"
 
@@ -164,8 +165,6 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
 	case MTK_PIN_CONFIG_PU_ADV:
 	case MTK_PIN_CONFIG_PD_ADV:
 		if (hw->soc->adv_pull_get) {
-			bool pullup;
-
 			pullup = param == MTK_PIN_CONFIG_PU_ADV;
 			err = hw->soc->adv_pull_get(hw, desc, pullup, &ret);
 		} else
@@ -633,6 +632,7 @@ ssize_t mtk_pctrl_show_one_pin(struct mtk_pinctrl *hw,
 
 	return len;
 }
+EXPORT_SYMBOL_GPL(mtk_pctrl_show_one_pin);
 
 #define PIN_DBG_BUF_SZ 96
 static void mtk_pctrl_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
@@ -1021,6 +1021,7 @@ int mtk_paris_pinctrl_probe(struct platform_device *pdev,
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mtk_paris_pinctrl_probe);
 
 static int mtk_paris_pinctrl_suspend(struct device *device)
 {
@@ -1040,3 +1041,6 @@ const struct dev_pm_ops mtk_paris_pinctrl_pm_ops = {
 	.suspend_noirq = mtk_paris_pinctrl_suspend,
 	.resume_noirq = mtk_paris_pinctrl_resume,
 };
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("MediaTek Pinctrl Common Driver V2 Paris");
diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
index ca7bbe4164c0..ba25c4654391 100644
--- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c
+++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
@@ -1343,8 +1343,6 @@ static const struct nmk_cfg_param nmk_cfg_params[] = {
 
 static int nmk_dt_pin_config(int index, int val, unsigned long *config)
 {
-	int ret = 0;
-
 	if (nmk_cfg_params[index].choice == NULL)
 		*config = nmk_cfg_params[index].config;
 	else {
@@ -1354,7 +1352,7 @@ static int nmk_dt_pin_config(int index, int val, unsigned long *config)
 				nmk_cfg_params[index].choice[val];
 		}
 	}
-	return ret;
+	return 0;
 }
 
 static const char *nmk_find_pin_name(struct pinctrl_dev *pctldev, const char *pin_name)
diff --git a/drivers/pinctrl/pinctrl-mcp23s08.c b/drivers/pinctrl/pinctrl-mcp23s08.c
index 3a235487e38d..cb545557dcd4 100644
--- a/drivers/pinctrl/pinctrl-mcp23s08.c
+++ b/drivers/pinctrl/pinctrl-mcp23s08.c
@@ -1,34 +1,23 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /* MCP23S08 SPI/I2C GPIO driver */
 
+#include <linux/bitops.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
 #include <linux/mutex.h>
+#include <linux/mod_devicetable.h>
 #include <linux/module.h>
+#include <linux/export.h>
 #include <linux/gpio/driver.h>
-#include <linux/i2c.h>
-#include <linux/spi/spi.h>
-#include <linux/spi/mcp23s08.h>
 #include <linux/slab.h>
 #include <asm/byteorder.h>
 #include <linux/interrupt.h>
-#include <linux/of_device.h>
 #include <linux/regmap.h>
 #include <linux/pinctrl/pinctrl.h>
 #include <linux/pinctrl/pinconf.h>
 #include <linux/pinctrl/pinconf-generic.h>
 
-/*
- * MCP types supported by driver
- */
-#define MCP_TYPE_S08	0
-#define MCP_TYPE_S17	1
-#define MCP_TYPE_008	2
-#define MCP_TYPE_017	3
-#define MCP_TYPE_S18    4
-#define MCP_TYPE_018    5
-
-#define MCP_MAX_DEV_PER_CS	8
+#include "pinctrl-mcp23s08.h"
 
 /* Registers are all 8 bits wide.
  *
@@ -53,31 +42,6 @@
 #define MCP_GPIO	0x09
 #define MCP_OLAT	0x0a
 
-struct mcp23s08;
-
-struct mcp23s08 {
-	u8			addr;
-	bool			irq_active_high;
-	bool			reg_shift;
-
-	u16			irq_rise;
-	u16			irq_fall;
-	int			irq;
-	bool			irq_controller;
-	int			cached_gpio;
-	/* lock protects regmap access with bypass/cache flags */
-	struct mutex		lock;
-
-	struct gpio_chip	chip;
-	struct irq_chip		irq_chip;
-
-	struct regmap		*regmap;
-	struct device		*dev;
-
-	struct pinctrl_dev	*pctldev;
-	struct pinctrl_desc	pinctrl_desc;
-};
-
 static const struct reg_default mcp23x08_defaults[] = {
 	{.reg = MCP_IODIR,		.def = 0xff},
 	{.reg = MCP_IPOL,		.def = 0x00},
@@ -109,7 +73,7 @@ static const struct regmap_access_table mcp23x08_precious_table = {
 	.n_yes_ranges = 1,
 };
 
-static const struct regmap_config mcp23x08_regmap = {
+const struct regmap_config mcp23x08_regmap = {
 	.reg_bits = 8,
 	.val_bits = 8,
 
@@ -121,6 +85,7 @@ static const struct regmap_config mcp23x08_regmap = {
 	.cache_type = REGCACHE_FLAT,
 	.max_register = MCP_OLAT,
 };
+EXPORT_SYMBOL_GPL(mcp23x08_regmap);
 
 static const struct reg_default mcp23x16_defaults[] = {
 	{.reg = MCP_IODIR << 1,		.def = 0xffff},
@@ -153,7 +118,7 @@ static const struct regmap_access_table mcp23x16_precious_table = {
 	.n_yes_ranges = 1,
 };
 
-static const struct regmap_config mcp23x17_regmap = {
+const struct regmap_config mcp23x17_regmap = {
 	.reg_bits = 8,
 	.val_bits = 16,
 
@@ -166,6 +131,7 @@ static const struct regmap_config mcp23x17_regmap = {
 	.cache_type = REGCACHE_FLAT,
 	.val_format_endian = REGMAP_ENDIAN_LITTLE,
 };
+EXPORT_SYMBOL_GPL(mcp23x17_regmap);
 
 static int mcp_read(struct mcp23s08 *mcp, unsigned int reg, unsigned int *val)
 {
@@ -309,80 +275,6 @@ static const struct pinconf_ops mcp_pinconf_ops = {
 
 /*----------------------------------------------------------------------*/
 
-#ifdef CONFIG_SPI_MASTER
-
-static int mcp23sxx_spi_write(void *context, const void *data, size_t count)
-{
-	struct mcp23s08 *mcp = context;
-	struct spi_device *spi = to_spi_device(mcp->dev);
-	struct spi_message m;
-	struct spi_transfer t[2] = { { .tx_buf = &mcp->addr, .len = 1, },
-				     { .tx_buf = data, .len = count, }, };
-
-	spi_message_init(&m);
-	spi_message_add_tail(&t[0], &m);
-	spi_message_add_tail(&t[1], &m);
-
-	return spi_sync(spi, &m);
-}
-
-static int mcp23sxx_spi_gather_write(void *context,
-				const void *reg, size_t reg_size,
-				const void *val, size_t val_size)
-{
-	struct mcp23s08 *mcp = context;
-	struct spi_device *spi = to_spi_device(mcp->dev);
-	struct spi_message m;
-	struct spi_transfer t[3] = { { .tx_buf = &mcp->addr, .len = 1, },
-				     { .tx_buf = reg, .len = reg_size, },
-				     { .tx_buf = val, .len = val_size, }, };
-
-	spi_message_init(&m);
-	spi_message_add_tail(&t[0], &m);
-	spi_message_add_tail(&t[1], &m);
-	spi_message_add_tail(&t[2], &m);
-
-	return spi_sync(spi, &m);
-}
-
-static int mcp23sxx_spi_read(void *context, const void *reg, size_t reg_size,
-				void *val, size_t val_size)
-{
-	struct mcp23s08 *mcp = context;
-	struct spi_device *spi = to_spi_device(mcp->dev);
-	u8 tx[2];
-
-	if (reg_size != 1)
-		return -EINVAL;
-
-	tx[0] = mcp->addr | 0x01;
-	tx[1] = *((u8 *) reg);
-
-	return spi_write_then_read(spi, tx, sizeof(tx), val, val_size);
-}
-
-static const struct regmap_bus mcp23sxx_spi_regmap = {
-	.write = mcp23sxx_spi_write,
-	.gather_write = mcp23sxx_spi_gather_write,
-	.read = mcp23sxx_spi_read,
-};
-
-#endif /* CONFIG_SPI_MASTER */
-
-/*----------------------------------------------------------------------*/
-
-/* A given spi_device can represent up to eight mcp23sxx chips
- * sharing the same chipselect but using different addresses
- * (e.g. chips #0 and #3 might be populated, but not #1 or $2).
- * Driver data holds all the per-chip data.
- */
-struct mcp23s08_driver_data {
-	unsigned		ngpio;
-	struct mcp23s08		*mcp[8];
-	struct mcp23s08		chip[];
-};
-
-
 static int mcp23s08_direction_input(struct gpio_chip *chip, unsigned offset)
 {
 	struct mcp23s08	*mcp = gpiochip_get_data(chip);
@@ -562,7 +454,6 @@ static int mcp23s08_irq_set_type(struct irq_data *data, unsigned int type)
 	struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
 	struct mcp23s08 *mcp = gpiochip_get_data(gc);
 	unsigned int pos = data->hwirq;
-	int status = 0;
 
 	if ((type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) {
 		mcp_set_bit(mcp, MCP_INTCON, pos, false);
@@ -585,7 +476,7 @@ static int mcp23s08_irq_set_type(struct irq_data *data, unsigned int type)
 	} else
 		return -EINVAL;
 
-	return status;
+	return 0;
 }
 
 static void mcp23s08_irq_bus_lock(struct irq_data *data)
@@ -656,21 +547,25 @@ static int mcp23s08_irqchip_setup(struct mcp23s08 *mcp)
 
 /*----------------------------------------------------------------------*/
 
-static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
-			      void *data, unsigned addr, unsigned type,
-			      unsigned int base, int cs)
+int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
+		       unsigned int addr, unsigned int type, unsigned int base)
 {
 	int status, ret;
 	bool mirror = false;
 	bool open_drain = false;
-	struct regmap_config *one_regmap_config = NULL;
-	int raw_chip_address = (addr & ~0x40) >> 1;
 
 	mutex_init(&mcp->lock);
 
 	mcp->dev = dev;
 	mcp->addr = addr;
+
 	mcp->irq_active_high = false;
+	mcp->irq_chip.name = dev_name(dev);
+	mcp->irq_chip.irq_mask = mcp23s08_irq_mask;
+	mcp->irq_chip.irq_unmask = mcp23s08_irq_unmask;
+	mcp->irq_chip.irq_set_type = mcp23s08_irq_set_type;
+	mcp->irq_chip.irq_bus_lock = mcp23s08_irq_bus_lock;
+	mcp->irq_chip.irq_bus_sync_unlock = mcp23s08_irq_bus_unlock;
 
 	mcp->chip.direction_input = mcp23s08_direction_input;
 	mcp->chip.get = mcp23s08_get;
@@ -681,83 +576,6 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
 	mcp->chip.of_node = dev->of_node;
 #endif
 
-	switch (type) {
-#ifdef CONFIG_SPI_MASTER
-	case MCP_TYPE_S08:
-	case MCP_TYPE_S17:
-		switch (type) {
-		case MCP_TYPE_S08:
-			one_regmap_config =
-				devm_kmemdup(dev, &mcp23x08_regmap,
-					sizeof(struct regmap_config), GFP_KERNEL);
-			mcp->reg_shift = 0;
-			mcp->chip.ngpio = 8;
-			mcp->chip.label = devm_kasprintf(dev, GFP_KERNEL,
-					"mcp23s08.%d", raw_chip_address);
-			break;
-		case MCP_TYPE_S17:
-			one_regmap_config =
-				devm_kmemdup(dev, &mcp23x17_regmap,
-					sizeof(struct regmap_config), GFP_KERNEL);
-			mcp->reg_shift = 1;
-			mcp->chip.ngpio = 16;
-			mcp->chip.label = devm_kasprintf(dev, GFP_KERNEL,
-					"mcp23s17.%d", raw_chip_address);
-			break;
-		}
-		if (!one_regmap_config)
-			return -ENOMEM;
-
-		one_regmap_config->name = devm_kasprintf(dev, GFP_KERNEL, "%d", raw_chip_address);
-		mcp->regmap = devm_regmap_init(dev, &mcp23sxx_spi_regmap, mcp,
-					       one_regmap_config);
-		break;
-
-	case MCP_TYPE_S18:
-		one_regmap_config =
-			devm_kmemdup(dev, &mcp23x17_regmap,
-				sizeof(struct regmap_config), GFP_KERNEL);
-		if (!one_regmap_config)
-			return -ENOMEM;
-		mcp->regmap = devm_regmap_init(dev, &mcp23sxx_spi_regmap, mcp,
-					       one_regmap_config);
-		mcp->reg_shift = 1;
-		mcp->chip.ngpio = 16;
-		mcp->chip.label = "mcp23s18";
-		break;
-#endif /* CONFIG_SPI_MASTER */
-
-#if IS_ENABLED(CONFIG_I2C)
-	case MCP_TYPE_008:
-		mcp->regmap = devm_regmap_init_i2c(data, &mcp23x08_regmap);
-		mcp->reg_shift = 0;
-		mcp->chip.ngpio = 8;
-		mcp->chip.label = "mcp23008";
-		break;
-
-	case MCP_TYPE_017:
-		mcp->regmap = devm_regmap_init_i2c(data, &mcp23x17_regmap);
-		mcp->reg_shift = 1;
-		mcp->chip.ngpio = 16;
-		mcp->chip.label = "mcp23017";
-		break;
-
-	case MCP_TYPE_018:
-		mcp->regmap = devm_regmap_init_i2c(data, &mcp23x17_regmap);
-		mcp->reg_shift = 1;
-		mcp->chip.ngpio = 16;
-		mcp->chip.label = "mcp23018";
-		break;
-#endif /* CONFIG_I2C */
-
-	default:
-		dev_err(dev, "invalid device type (%d)\n", type);
-		return -EINVAL;
-	}
-
-	if (IS_ERR(mcp->regmap))
-		return PTR_ERR(mcp->regmap);
-
 	mcp->chip.base = base;
 	mcp->chip.can_sleep = true;
 	mcp->chip.parent = dev;
@@ -816,14 +634,6 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
 			goto fail;
 	}
 
-	if (one_regmap_config) {
-		mcp->pinctrl_desc.name = devm_kasprintf(dev, GFP_KERNEL,
-				"mcp23xxx-pinctrl.%d", raw_chip_address);
-		if (!mcp->pinctrl_desc.name)
-			return -ENOMEM;
-	} else {
-		mcp->pinctrl_desc.name = "mcp23xxx-pinctrl";
-	}
 	mcp->pinctrl_desc.pctlops = &mcp_pinctrl_ops;
 	mcp->pinctrl_desc.confops = &mcp_pinconf_ops;
 	mcp->pinctrl_desc.npins = mcp->chip.ngpio;
@@ -847,291 +657,4 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
 		dev_dbg(dev, "can't setup chip %d, --> %d\n", addr, ret);
 	return ret;
 }
-
-/*----------------------------------------------------------------------*/
-
-#ifdef CONFIG_OF
-#ifdef CONFIG_SPI_MASTER
-static const struct of_device_id mcp23s08_spi_of_match[] = {
-	{
-		.compatible = "microchip,mcp23s08",
-		.data = (void *) MCP_TYPE_S08,
-	},
-	{
-		.compatible = "microchip,mcp23s17",
-		.data = (void *) MCP_TYPE_S17,
-	},
-	{
-		.compatible = "microchip,mcp23s18",
-		.data = (void *) MCP_TYPE_S18,
-	},
-/* NOTE: The use of the mcp prefix is deprecated and will be removed. */
-	{
-		.compatible = "mcp,mcp23s08",
-		.data = (void *) MCP_TYPE_S08,
-	},
-	{
-		.compatible = "mcp,mcp23s17",
-		.data = (void *) MCP_TYPE_S17,
-	},
-	{ },
-};
-MODULE_DEVICE_TABLE(of, mcp23s08_spi_of_match);
-#endif
-
-#if IS_ENABLED(CONFIG_I2C)
-static const struct of_device_id mcp23s08_i2c_of_match[] = {
-	{
-		.compatible = "microchip,mcp23008",
-		.data = (void *) MCP_TYPE_008,
-	},
-	{
-		.compatible = "microchip,mcp23017",
-		.data = (void *) MCP_TYPE_017,
-	},
-	{
-		.compatible = "microchip,mcp23018",
-		.data = (void *) MCP_TYPE_018,
-	},
-/* NOTE: The use of the mcp prefix is deprecated and will be removed. */
-	{
-		.compatible = "mcp,mcp23008",
-		.data = (void *) MCP_TYPE_008,
-	},
-	{
-		.compatible = "mcp,mcp23017",
-		.data = (void *) MCP_TYPE_017,
-	},
-	{ },
-};
-MODULE_DEVICE_TABLE(of, mcp23s08_i2c_of_match);
-#endif
-#endif /* CONFIG_OF */
-
-
-#if IS_ENABLED(CONFIG_I2C)
-
-static int mcp230xx_probe(struct i2c_client *client,
-				    const struct i2c_device_id *id)
-{
-	struct mcp23s08_platform_data *pdata, local_pdata;
-	struct mcp23s08 *mcp;
-	int status;
-
-	pdata = dev_get_platdata(&client->dev);
-	if (!pdata) {
-		pdata = &local_pdata;
-		pdata->base = -1;
-	}
-
-	mcp = devm_kzalloc(&client->dev, sizeof(*mcp), GFP_KERNEL);
-	if (!mcp)
-		return -ENOMEM;
-
-	mcp->irq = client->irq;
-	mcp->irq_chip.name = dev_name(&client->dev);
-	mcp->irq_chip.irq_mask = mcp23s08_irq_mask;
-	mcp->irq_chip.irq_unmask = mcp23s08_irq_unmask;
-	mcp->irq_chip.irq_set_type = mcp23s08_irq_set_type;
-	mcp->irq_chip.irq_bus_lock = mcp23s08_irq_bus_lock;
-	mcp->irq_chip.irq_bus_sync_unlock = mcp23s08_irq_bus_unlock;
-
-	status = mcp23s08_probe_one(mcp, &client->dev, client, client->addr,
-				    id->driver_data, pdata->base, 0);
-	if (status)
-		return status;
-
-	i2c_set_clientdata(client, mcp);
-
-	return 0;
-}
-
-static const struct i2c_device_id mcp230xx_id[] = {
-	{ "mcp23008", MCP_TYPE_008 },
-	{ "mcp23017", MCP_TYPE_017 },
-	{ "mcp23018", MCP_TYPE_018 },
-	{ },
-};
-MODULE_DEVICE_TABLE(i2c, mcp230xx_id);
-
-static struct i2c_driver mcp230xx_driver = {
-	.driver = {
-		.name	= "mcp230xx",
-		.of_match_table = of_match_ptr(mcp23s08_i2c_of_match),
-	},
-	.probe		= mcp230xx_probe,
-	.id_table	= mcp230xx_id,
-};
-
-static int __init mcp23s08_i2c_init(void)
-{
-	return i2c_add_driver(&mcp230xx_driver);
-}
-
-static void mcp23s08_i2c_exit(void)
-{
-	i2c_del_driver(&mcp230xx_driver);
-}
-
-#else
-
-static int __init mcp23s08_i2c_init(void) { return 0; }
-static void mcp23s08_i2c_exit(void) { }
-
-#endif /* CONFIG_I2C */
-
-/*----------------------------------------------------------------------*/
-
-#ifdef CONFIG_SPI_MASTER
-
-static int mcp23s08_probe(struct spi_device *spi)
-{
-	struct mcp23s08_platform_data	*pdata, local_pdata;
-	unsigned			addr;
-	int				chips = 0;
-	struct mcp23s08_driver_data	*data;
-	int				status, type;
-	unsigned			ngpio = 0;
-	const struct			of_device_id *match;
-
-	match = of_match_device(of_match_ptr(mcp23s08_spi_of_match), &spi->dev);
-	if (match)
-		type = (int)(uintptr_t)match->data;
-	else
-		type = spi_get_device_id(spi)->driver_data;
-
-	pdata = dev_get_platdata(&spi->dev);
-	if (!pdata) {
-		pdata = &local_pdata;
-		pdata->base = -1;
-
-		status = device_property_read_u32(&spi->dev,
-			"microchip,spi-present-mask", &pdata->spi_present_mask);
-		if (status) {
-			status = device_property_read_u32(&spi->dev,
-				"mcp,spi-present-mask",
-				&pdata->spi_present_mask);
-
-			if (status) {
-				dev_err(&spi->dev, "missing spi-present-mask");
-				return -ENODEV;
-			}
-		}
-	}
-
-	if (!pdata->spi_present_mask || pdata->spi_present_mask > 0xff) {
-		dev_err(&spi->dev, "invalid spi-present-mask");
-		return -ENODEV;
-	}
-
-	for (addr = 0; addr < MCP_MAX_DEV_PER_CS; addr++) {
-		if (pdata->spi_present_mask & BIT(addr))
-			chips++;
-	}
-
-	if (!chips)
-		return -ENODEV;
-
-	data = devm_kzalloc(&spi->dev,
-			    struct_size(data, chip, chips), GFP_KERNEL);
-	if (!data)
-		return -ENOMEM;
-
-	spi_set_drvdata(spi, data);
-
-	for (addr = 0; addr < MCP_MAX_DEV_PER_CS; addr++) {
-		if (!(pdata->spi_present_mask & BIT(addr)))
-			continue;
-		chips--;
-		data->mcp[addr] = &data->chip[chips];
-		data->mcp[addr]->irq = spi->irq;
-		data->mcp[addr]->irq_chip.name = dev_name(&spi->dev);
-		data->mcp[addr]->irq_chip.irq_mask = mcp23s08_irq_mask;
-		data->mcp[addr]->irq_chip.irq_unmask = mcp23s08_irq_unmask;
-		data->mcp[addr]->irq_chip.irq_set_type = mcp23s08_irq_set_type;
-		data->mcp[addr]->irq_chip.irq_bus_lock = mcp23s08_irq_bus_lock;
-		data->mcp[addr]->irq_chip.irq_bus_sync_unlock =
-			mcp23s08_irq_bus_unlock;
-		status = mcp23s08_probe_one(data->mcp[addr], &spi->dev, spi,
-					    0x40 | (addr << 1), type,
-					    pdata->base, addr);
-		if (status < 0)
-			return status;
-
-		if (pdata->base != -1)
-			pdata->base += data->mcp[addr]->chip.ngpio;
-		ngpio += data->mcp[addr]->chip.ngpio;
-	}
-	data->ngpio = ngpio;
-
-	return 0;
-}
-
-static const struct spi_device_id mcp23s08_ids[] = {
-	{ "mcp23s08", MCP_TYPE_S08 },
-	{ "mcp23s17", MCP_TYPE_S17 },
-	{ "mcp23s18", MCP_TYPE_S18 },
-	{ },
-};
-MODULE_DEVICE_TABLE(spi, mcp23s08_ids);
-
-static struct spi_driver mcp23s08_driver = {
-	.probe		= mcp23s08_probe,
-	.id_table	= mcp23s08_ids,
-	.driver = {
-		.name	= "mcp23s08",
-		.of_match_table = of_match_ptr(mcp23s08_spi_of_match),
-	},
-};
-
-static int __init mcp23s08_spi_init(void)
-{
-	return spi_register_driver(&mcp23s08_driver);
-}
-
-static void mcp23s08_spi_exit(void)
-{
-	spi_unregister_driver(&mcp23s08_driver);
-}
-
-#else
-
-static int __init mcp23s08_spi_init(void) { return 0; }
-static void mcp23s08_spi_exit(void) { }
-
-#endif /* CONFIG_SPI_MASTER */
-
-/*----------------------------------------------------------------------*/
-
-static int __init mcp23s08_init(void)
-{
-	int ret;
-
-	ret = mcp23s08_spi_init();
-	if (ret)
-		goto spi_fail;
-
-	ret = mcp23s08_i2c_init();
-	if (ret)
-		goto i2c_fail;
-
-	return 0;
-
- i2c_fail:
-	mcp23s08_spi_exit();
- spi_fail:
-	return ret;
-}
-/* register after spi/i2c postcore initcall and before
- * subsys initcalls that may rely on these GPIOs
- */
-subsys_initcall(mcp23s08_init);
-
-static void __exit mcp23s08_exit(void)
-{
-	mcp23s08_spi_exit();
-	mcp23s08_i2c_exit();
-}
-module_exit(mcp23s08_exit);
-
-MODULE_LICENSE("GPL");
+EXPORT_SYMBOL_GPL(mcp23s08_probe_one);
diff --git a/drivers/pinctrl/pinctrl-mcp23s08.h b/drivers/pinctrl/pinctrl-mcp23s08.h
new file mode 100644
index 000000000000..90dc27081a3c
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-mcp23s08.h
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* MCP23S08 SPI/I2C GPIO driver */
+
+#include <linux/gpio/driver.h>
+#include <linux/irq.h>
+#include <linux/mutex.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/types.h>
+
+/*
+ * MCP types supported by driver
+ */
+#define MCP_TYPE_S08	1
+#define MCP_TYPE_S17	2
+#define MCP_TYPE_008	3
+#define MCP_TYPE_017	4
+#define MCP_TYPE_S18	5
+#define MCP_TYPE_018	6
+
+struct device;
+struct regmap;
+
+struct pinctrl_dev;
+
+struct mcp23s08 {
+	u8			addr;
+	bool			irq_active_high;
+	bool			reg_shift;
+
+	u16			irq_rise;
+	u16			irq_fall;
+	int			irq;
+	bool			irq_controller;
+	int			cached_gpio;
+	/* lock protects regmap access with bypass/cache flags */
+	struct mutex		lock;
+
+	struct gpio_chip	chip;
+	struct irq_chip		irq_chip;
+
+	struct regmap		*regmap;
+	struct device		*dev;
+
+	struct pinctrl_dev	*pctldev;
+	struct pinctrl_desc	pinctrl_desc;
+};
+
+extern const struct regmap_config mcp23x08_regmap;
+extern const struct regmap_config mcp23x17_regmap;
+
+int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
+		       unsigned int addr, unsigned int type, unsigned int base);
diff --git a/drivers/pinctrl/pinctrl-mcp23s08_i2c.c b/drivers/pinctrl/pinctrl-mcp23s08_i2c.c
new file mode 100644
index 000000000000..e0b001c8c08c
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-mcp23s08_i2c.c
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* MCP23S08 I2C GPIO driver */
+
+#include <linux/i2c.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+
+#include "pinctrl-mcp23s08.h"
+
+static int mcp230xx_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+	struct device *dev = &client->dev;
+	unsigned int type = id->driver_data;
+	struct mcp23s08 *mcp;
+	int ret;
+
+	mcp = devm_kzalloc(dev, sizeof(*mcp), GFP_KERNEL);
+	if (!mcp)
+		return -ENOMEM;
+
+	switch (type) {
+	case MCP_TYPE_008:
+		mcp->regmap = devm_regmap_init_i2c(client, &mcp23x08_regmap);
+		mcp->reg_shift = 0;
+		mcp->chip.ngpio = 8;
+		mcp->chip.label = "mcp23008";
+		break;
+
+	case MCP_TYPE_017:
+		mcp->regmap = devm_regmap_init_i2c(client, &mcp23x17_regmap);
+		mcp->reg_shift = 1;
+		mcp->chip.ngpio = 16;
+		mcp->chip.label = "mcp23017";
+		break;
+
+	case MCP_TYPE_018:
+		mcp->regmap = devm_regmap_init_i2c(client, &mcp23x17_regmap);
+		mcp->reg_shift = 1;
+		mcp->chip.ngpio = 16;
+		mcp->chip.label = "mcp23018";
+		break;
+
+	default:
+		dev_err(dev, "invalid device type (%d)\n", type);
+		return -EINVAL;
+	}
+
+	if (IS_ERR(mcp->regmap))
+		return PTR_ERR(mcp->regmap);
+
+	mcp->irq = client->irq;
+	mcp->pinctrl_desc.name = "mcp23xxx-pinctrl";
+
+	ret = mcp23s08_probe_one(mcp, dev, client->addr, type, -1);
+	if (ret)
+		return ret;
+
+	i2c_set_clientdata(client, mcp);
+
+	return 0;
+}
+
+static const struct i2c_device_id mcp230xx_id[] = {
+	{ "mcp23008", MCP_TYPE_008 },
+	{ "mcp23017", MCP_TYPE_017 },
+	{ "mcp23018", MCP_TYPE_018 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, mcp230xx_id);
+
+static const struct of_device_id mcp23s08_i2c_of_match[] = {
+	{
+		.compatible = "microchip,mcp23008",
+		.data = (void *) MCP_TYPE_008,
+	},
+	{
+		.compatible = "microchip,mcp23017",
+		.data = (void *) MCP_TYPE_017,
+	},
+	{
+		.compatible = "microchip,mcp23018",
+		.data = (void *) MCP_TYPE_018,
+	},
+/* NOTE: The use of the mcp prefix is deprecated and will be removed. */
+	{
+		.compatible = "mcp,mcp23008",
+		.data = (void *) MCP_TYPE_008,
+	},
+	{
+		.compatible = "mcp,mcp23017",
+		.data = (void *) MCP_TYPE_017,
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(of, mcp23s08_i2c_of_match);
+
+static struct i2c_driver mcp230xx_driver = {
+	.driver = {
+		.name	= "mcp230xx",
+		.of_match_table = mcp23s08_i2c_of_match,
+	},
+	.probe		= mcp230xx_probe,
+	.id_table	= mcp230xx_id,
+};
+
+static int __init mcp23s08_i2c_init(void)
+{
+	return i2c_add_driver(&mcp230xx_driver);
+}
+
+/*
+ * Register after I²C postcore initcall and before
+ * subsys initcalls that may rely on these GPIOs.
+ */
+subsys_initcall(mcp23s08_i2c_init);
+
+static void mcp23s08_i2c_exit(void)
+{
+	i2c_del_driver(&mcp230xx_driver);
+}
+module_exit(mcp23s08_i2c_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/pinctrl/pinctrl-mcp23s08_spi.c b/drivers/pinctrl/pinctrl-mcp23s08_spi.c
new file mode 100644
index 000000000000..e06fb885fd2b
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-mcp23s08_spi.c
@@ -0,0 +1,262 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* MCP23S08 SPI GPIO driver */
+
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/property.h>
+#include <linux/regmap.h>
+#include <linux/spi/spi.h>
+
+#include "pinctrl-mcp23s08.h"
+
+#define MCP_MAX_DEV_PER_CS	8
+
+/*
+ * A given spi_device can represent up to eight mcp23sxx chips
+ * sharing the same chipselect but using different addresses
+ * (e.g. chips #0 and #3 might be populated, but not #1 or #2).
+ * Driver data holds all the per-chip data.
+ */
+struct mcp23s08_driver_data {
+	unsigned		ngpio;
+	struct mcp23s08		*mcp[8];
+	struct mcp23s08		chip[];
+};
+
+static int mcp23sxx_spi_write(void *context, const void *data, size_t count)
+{
+	struct mcp23s08 *mcp = context;
+	struct spi_device *spi = to_spi_device(mcp->dev);
+	struct spi_message m;
+	struct spi_transfer t[2] = { { .tx_buf = &mcp->addr, .len = 1, },
+				     { .tx_buf = data, .len = count, }, };
+
+	spi_message_init(&m);
+	spi_message_add_tail(&t[0], &m);
+	spi_message_add_tail(&t[1], &m);
+
+	return spi_sync(spi, &m);
+}
+
+static int mcp23sxx_spi_gather_write(void *context,
+				const void *reg, size_t reg_size,
+				const void *val, size_t val_size)
+{
+	struct mcp23s08 *mcp = context;
+	struct spi_device *spi = to_spi_device(mcp->dev);
+	struct spi_message m;
+	struct spi_transfer t[3] = { { .tx_buf = &mcp->addr, .len = 1, },
+				     { .tx_buf = reg, .len = reg_size, },
+				     { .tx_buf = val, .len = val_size, }, };
+
+	spi_message_init(&m);
+	spi_message_add_tail(&t[0], &m);
+	spi_message_add_tail(&t[1], &m);
+	spi_message_add_tail(&t[2], &m);
+
+	return spi_sync(spi, &m);
+}
+
+static int mcp23sxx_spi_read(void *context, const void *reg, size_t reg_size,
+				void *val, size_t val_size)
+{
+	struct mcp23s08 *mcp = context;
+	struct spi_device *spi = to_spi_device(mcp->dev);
+	u8 tx[2];
+
+	if (reg_size != 1)
+		return -EINVAL;
+
+	tx[0] = mcp->addr | 0x01;
+	tx[1] = *((u8 *) reg);
+
+	return spi_write_then_read(spi, tx, sizeof(tx), val, val_size);
+}
+
+static const struct regmap_bus mcp23sxx_spi_regmap = {
+	.write = mcp23sxx_spi_write,
+	.gather_write = mcp23sxx_spi_gather_write,
+	.read = mcp23sxx_spi_read,
+};
+
+static int mcp23s08_spi_regmap_init(struct mcp23s08 *mcp, struct device *dev,
+				    unsigned int addr, unsigned int type)
+{
+	const struct regmap_config *config;
+	struct regmap_config *copy;
+	const char *name;
+
+	switch (type) {
+	case MCP_TYPE_S08:
+		mcp->reg_shift = 0;
+		mcp->chip.ngpio = 8;
+		mcp->chip.label = devm_kasprintf(dev, GFP_KERNEL, "mcp23s08.%d", addr);
+
+		config = &mcp23x08_regmap;
+		name = devm_kasprintf(dev, GFP_KERNEL, "%d", addr);
+		break;
+
+	case MCP_TYPE_S17:
+		mcp->reg_shift = 1;
+		mcp->chip.ngpio = 16;
+		mcp->chip.label = devm_kasprintf(dev, GFP_KERNEL, "mcp23s17.%d", addr);
+
+		config = &mcp23x17_regmap;
+		name = devm_kasprintf(dev, GFP_KERNEL, "%d", addr);
+		break;
+
+	case MCP_TYPE_S18:
+		mcp->reg_shift = 1;
+		mcp->chip.ngpio = 16;
+		mcp->chip.label = "mcp23s18";
+
+		config = &mcp23x17_regmap;
+		name = config->name;
+		break;
+
+	default:
+		dev_err(dev, "invalid device type (%d)\n", type);
+		return -EINVAL;
+	}
+
+	copy = devm_kmemdup(dev, &config, sizeof(config), GFP_KERNEL);
+	if (!copy)
+		return -ENOMEM;
+
+	copy->name = name;
+
+	mcp->regmap = devm_regmap_init(dev, &mcp23sxx_spi_regmap, mcp, copy);
+	if (IS_ERR(mcp->regmap))
+		return PTR_ERR(mcp->regmap);
+
+	return 0;
+}
+
+static int mcp23s08_probe(struct spi_device *spi)
+{
+	struct device *dev = &spi->dev;
+	struct mcp23s08_driver_data *data;
+	unsigned long spi_present_mask;
+	const void *match;
+	unsigned int addr;
+	unsigned int ngpio = 0;
+	int chips;
+	int type;
+	int ret;
+	u32 v;
+
+	match = device_get_match_data(dev);
+	if (match)
+		type = (int)(uintptr_t)match;
+	else
+		type = spi_get_device_id(spi)->driver_data;
+
+	ret = device_property_read_u32(dev, "microchip,spi-present-mask", &v);
+	if (ret) {
+		ret = device_property_read_u32(dev, "mcp,spi-present-mask", &v);
+		if (ret) {
+			dev_err(dev, "missing spi-present-mask");
+			return ret;
+		}
+	}
+	spi_present_mask = v;
+
+	if (!spi_present_mask || spi_present_mask >= BIT(MCP_MAX_DEV_PER_CS)) {
+		dev_err(dev, "invalid spi-present-mask");
+		return -ENODEV;
+	}
+
+	chips = hweight_long(spi_present_mask);
+
+	data = devm_kzalloc(dev, struct_size(data, chip, chips), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	spi_set_drvdata(spi, data);
+
+	for_each_set_bit(addr, &spi_present_mask, MCP_MAX_DEV_PER_CS) {
+		data->mcp[addr] = &data->chip[--chips];
+		data->mcp[addr]->irq = spi->irq;
+
+		ret = mcp23s08_spi_regmap_init(data->mcp[addr], dev, addr, type);
+		if (ret)
+			return ret;
+
+		data->mcp[addr]->pinctrl_desc.name = devm_kasprintf(dev, GFP_KERNEL,
+								    "mcp23xxx-pinctrl.%d",
+								    addr);
+		if (!data->mcp[addr]->pinctrl_desc.name)
+			return -ENOMEM;
+
+		ret = mcp23s08_probe_one(data->mcp[addr], dev, 0x40 | (addr << 1), type, -1);
+		if (ret < 0)
+			return ret;
+
+		ngpio += data->mcp[addr]->chip.ngpio;
+	}
+	data->ngpio = ngpio;
+
+	return 0;
+}
+
+static const struct spi_device_id mcp23s08_ids[] = {
+	{ "mcp23s08", MCP_TYPE_S08 },
+	{ "mcp23s17", MCP_TYPE_S17 },
+	{ "mcp23s18", MCP_TYPE_S18 },
+	{ }
+};
+MODULE_DEVICE_TABLE(spi, mcp23s08_ids);
+
+static const struct of_device_id mcp23s08_spi_of_match[] = {
+	{
+		.compatible = "microchip,mcp23s08",
+		.data = (void *) MCP_TYPE_S08,
+	},
+	{
+		.compatible = "microchip,mcp23s17",
+		.data = (void *) MCP_TYPE_S17,
+	},
+	{
+		.compatible = "microchip,mcp23s18",
+		.data = (void *) MCP_TYPE_S18,
+	},
+/* NOTE: The use of the mcp prefix is deprecated and will be removed. */
+	{
+		.compatible = "mcp,mcp23s08",
+		.data = (void *) MCP_TYPE_S08,
+	},
+	{
+		.compatible = "mcp,mcp23s17",
+		.data = (void *) MCP_TYPE_S17,
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(of, mcp23s08_spi_of_match);
+
+static struct spi_driver mcp23s08_driver = {
+	.probe		= mcp23s08_probe,
+	.id_table	= mcp23s08_ids,
+	.driver = {
+		.name	= "mcp23s08",
+		.of_match_table = mcp23s08_spi_of_match,
+	},
+};
+
+static int __init mcp23s08_spi_init(void)
+{
+	return spi_register_driver(&mcp23s08_driver);
+}
+
+/*
+ * Register after SPI postcore initcall and before
+ * subsys initcalls that may rely on these GPIOs.
+ */
+subsys_initcall(mcp23s08_spi_init);
+
+static void mcp23s08_spi_exit(void)
+{
+	spi_unregister_driver(&mcp23s08_driver);
+}
+module_exit(mcp23s08_spi_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c
index 9a398a211d30..29259fee09ba 100644
--- a/drivers/pinctrl/qcom/pinctrl-msm.c
+++ b/drivers/pinctrl/qcom/pinctrl-msm.c
@@ -23,7 +23,6 @@
 #include <linux/pm.h>
 #include <linux/log2.h>
 #include <linux/qcom_scm.h>
-#include <linux/io.h>
 
 #include <linux/soc/qcom/irq.h>
 
@@ -697,7 +696,7 @@ static void msm_gpio_update_dual_edge_pos(struct msm_pinctrl *pctrl,
 
 		pol = msm_readl_intr_cfg(pctrl, g);
 		pol ^= BIT(g->intr_polarity_bit);
-		msm_writel_intr_cfg(val, pctrl, g);
+		msm_writel_intr_cfg(pol, pctrl, g);
 
 		val2 = msm_readl_io(pctrl, g) & BIT(g->in_bit);
 		intstat = msm_readl_intr_status(pctrl, g);
diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c
index 0599f5127b01..5126a5a6d4c0 100644
--- a/drivers/pinctrl/samsung/pinctrl-exynos.c
+++ b/drivers/pinctrl/samsung/pinctrl-exynos.c
@@ -40,6 +40,8 @@ struct exynos_irq_chip {
 	u32 eint_pend;
 	u32 eint_wake_mask_value;
 	u32 eint_wake_mask_reg;
+	void (*set_eint_wakeup_mask)(struct samsung_pinctrl_drv_data *drvdata,
+				     struct exynos_irq_chip *irq_chip);
 };
 
 static inline struct exynos_irq_chip *to_exynos_irq_chip(struct irq_chip *chip)
@@ -342,6 +344,47 @@ static int exynos_wkup_irq_set_wake(struct irq_data *irqd, unsigned int on)
 	return 0;
 }
 
+static void
+exynos_pinctrl_set_eint_wakeup_mask(struct samsung_pinctrl_drv_data *drvdata,
+				    struct exynos_irq_chip *irq_chip)
+{
+	struct regmap *pmu_regs;
+
+	if (!drvdata->retention_ctrl || !drvdata->retention_ctrl->priv) {
+		dev_warn(drvdata->dev,
+			 "No retention data configured bank with external wakeup interrupt. Wake-up mask will not be set.\n");
+		return;
+	}
+
+	pmu_regs = drvdata->retention_ctrl->priv;
+	dev_info(drvdata->dev,
+		 "Setting external wakeup interrupt mask: 0x%x\n",
+		 irq_chip->eint_wake_mask_value);
+
+	regmap_write(pmu_regs, irq_chip->eint_wake_mask_reg,
+		     irq_chip->eint_wake_mask_value);
+}
+
+static void
+s5pv210_pinctrl_set_eint_wakeup_mask(struct samsung_pinctrl_drv_data *drvdata,
+				    struct exynos_irq_chip *irq_chip)
+
+{
+	void __iomem *clk_base;
+
+	if (!drvdata->retention_ctrl || !drvdata->retention_ctrl->priv) {
+		dev_warn(drvdata->dev,
+			 "No retention data configured bank with external wakeup interrupt. Wake-up mask will not be set.\n");
+		return;
+	}
+
+
+	clk_base = (void __iomem *) drvdata->retention_ctrl->priv;
+
+	__raw_writel(irq_chip->eint_wake_mask_value,
+		     clk_base + irq_chip->eint_wake_mask_reg);
+}
+
 /*
  * irq_chip for wakeup interrupts
  */
@@ -360,8 +403,9 @@ static const struct exynos_irq_chip s5pv210_wkup_irq_chip __initconst = {
 	.eint_mask = EXYNOS_WKUP_EMASK_OFFSET,
 	.eint_pend = EXYNOS_WKUP_EPEND_OFFSET,
 	.eint_wake_mask_value = EXYNOS_EINT_WAKEUP_MASK_DISABLED,
-	/* Only difference with exynos4210_wkup_irq_chip: */
+	/* Only differences with exynos4210_wkup_irq_chip: */
 	.eint_wake_mask_reg = S5PV210_EINT_WAKEUP_MASK,
+	.set_eint_wakeup_mask = s5pv210_pinctrl_set_eint_wakeup_mask,
 };
 
 static const struct exynos_irq_chip exynos4210_wkup_irq_chip __initconst = {
@@ -380,6 +424,7 @@ static const struct exynos_irq_chip exynos4210_wkup_irq_chip __initconst = {
 	.eint_pend = EXYNOS_WKUP_EPEND_OFFSET,
 	.eint_wake_mask_value = EXYNOS_EINT_WAKEUP_MASK_DISABLED,
 	.eint_wake_mask_reg = EXYNOS_EINT_WAKEUP_MASK,
+	.set_eint_wakeup_mask = exynos_pinctrl_set_eint_wakeup_mask,
 };
 
 static const struct exynos_irq_chip exynos7_wkup_irq_chip __initconst = {
@@ -398,6 +443,7 @@ static const struct exynos_irq_chip exynos7_wkup_irq_chip __initconst = {
 	.eint_pend = EXYNOS7_WKUP_EPEND_OFFSET,
 	.eint_wake_mask_value = EXYNOS_EINT_WAKEUP_MASK_DISABLED,
 	.eint_wake_mask_reg = EXYNOS5433_EINT_WAKEUP_MASK,
+	.set_eint_wakeup_mask = exynos_pinctrl_set_eint_wakeup_mask,
 };
 
 /* list of external wakeup controllers supported */
@@ -574,27 +620,6 @@ int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
 	return 0;
 }
 
-static void
-exynos_pinctrl_set_eint_wakeup_mask(struct samsung_pinctrl_drv_data *drvdata,
-				    struct exynos_irq_chip *irq_chip)
-{
-	struct regmap *pmu_regs;
-
-	if (!drvdata->retention_ctrl || !drvdata->retention_ctrl->priv) {
-		dev_warn(drvdata->dev,
-			 "No retention data configured bank with external wakeup interrupt. Wake-up mask will not be set.\n");
-		return;
-	}
-
-	pmu_regs = drvdata->retention_ctrl->priv;
-	dev_info(drvdata->dev,
-		 "Setting external wakeup interrupt mask: 0x%x\n",
-		 irq_chip->eint_wake_mask_value);
-
-	regmap_write(pmu_regs, irq_chip->eint_wake_mask_reg,
-		     irq_chip->eint_wake_mask_value);
-}
-
 static void exynos_pinctrl_suspend_bank(
 				struct samsung_pinctrl_drv_data *drvdata,
 				struct samsung_pin_bank *bank)
@@ -626,8 +651,8 @@ void exynos_pinctrl_suspend(struct samsung_pinctrl_drv_data *drvdata)
 		else if (bank->eint_type == EINT_TYPE_WKUP) {
 			if (!irq_chip) {
 				irq_chip = bank->irq_chip;
-				exynos_pinctrl_set_eint_wakeup_mask(drvdata,
-								    irq_chip);
+				irq_chip->set_eint_wakeup_mask(drvdata,
+							       irq_chip);
 			} else if (bank->irq_chip != irq_chip) {
 				dev_warn(drvdata->dev,
 					 "More than one external wakeup interrupt chip configured (bank: %s). This is not supported by hardware nor by driver.\n",
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun8i-a23-r.c b/drivers/pinctrl/sunxi/pinctrl-sun8i-a23-r.c
index 8a08c4afc6a8..9e5b61449999 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sun8i-a23-r.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sun8i-a23-r.c
@@ -103,8 +103,11 @@ static int sun8i_a23_r_pinctrl_probe(struct platform_device *pdev)
 
 	rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
 	if (IS_ERR(rstc)) {
-		dev_err(&pdev->dev, "Reset controller missing\n");
-		return PTR_ERR(rstc);
+		ret = PTR_ERR(rstc);
+		if (ret == -EPROBE_DEFER)
+			return ret;
+		dev_err(&pdev->dev, "Reset controller missing err=%d\n", ret);
+		return ret;
 	}
 
 	ret = reset_control_deassert(rstc);
diff --git a/drivers/platform/chrome/Kconfig b/drivers/platform/chrome/Kconfig
index 03ea5129ed0c..a484ab2c91ff 100644
--- a/drivers/platform/chrome/Kconfig
+++ b/drivers/platform/chrome/Kconfig
@@ -217,6 +217,7 @@ config CROS_EC_SYSFS
 config CROS_EC_TYPEC
 	tristate "ChromeOS EC Type-C Connector Control"
 	depends on MFD_CROS_EC_DEV && TYPEC
+	depends on CROS_USBPD_NOTIFY
 	default MFD_CROS_EC_DEV
 	help
 	  If you say Y here, you get support for accessing Type C connector
diff --git a/drivers/platform/chrome/chromeos_pstore.c b/drivers/platform/chrome/chromeos_pstore.c
index d13770785fb5..82dea8cb5da1 100644
--- a/drivers/platform/chrome/chromeos_pstore.c
+++ b/drivers/platform/chrome/chromeos_pstore.c
@@ -57,6 +57,7 @@ static struct ramoops_platform_data chromeos_ramoops_data = {
 	.record_size	= 0x40000,
 	.console_size	= 0x20000,
 	.ftrace_size	= 0x20000,
+	.pmsg_size	= 0x20000,
 	.dump_oops	= 1,
 };
 
diff --git a/drivers/platform/chrome/cros_ec_ishtp.c b/drivers/platform/chrome/cros_ec_ishtp.c
index 93a71e93a2f1..ed794a7ddba9 100644
--- a/drivers/platform/chrome/cros_ec_ishtp.c
+++ b/drivers/platform/chrome/cros_ec_ishtp.c
@@ -48,7 +48,8 @@ static const guid_t cros_ish_guid =
 struct header {
 	u8 channel;
 	u8 status;
-	u8 reserved[2];
+	u8 token;
+	u8 reserved;
 } __packed;
 
 struct cros_ish_out_msg {
@@ -90,6 +91,7 @@ static DECLARE_RWSEM(init_lock);
  * data exceeds this value, we log an error.
  * @size: Actual size of data received from firmware.
  * @error: 0 for success, negative error code for a failure in process_recv().
+ * @token: Expected token for response that we are waiting on.
  * @received: Set to true on receiving a valid firmware	response to host command
  * @wait_queue: Wait queue for host to wait for firmware response.
  */
@@ -98,6 +100,7 @@ struct response_info {
 	size_t max_size;
 	size_t size;
 	int error;
+	u8 token;
 	bool received;
 	wait_queue_head_t wait_queue;
 };
@@ -162,6 +165,7 @@ static int ish_send(struct ishtp_cl_data *client_data,
 		    u8 *out_msg, size_t out_size,
 		    u8 *in_msg, size_t in_size)
 {
+	static u8 next_token;
 	int rv;
 	struct header *out_hdr = (struct header *)out_msg;
 	struct ishtp_cl *cros_ish_cl = client_data->cros_ish_cl;
@@ -174,8 +178,11 @@ static int ish_send(struct ishtp_cl_data *client_data,
 	client_data->response.data = in_msg;
 	client_data->response.max_size = in_size;
 	client_data->response.error = 0;
+	client_data->response.token = next_token++;
 	client_data->response.received = false;
 
+	out_hdr->token = client_data->response.token;
+
 	rv = ishtp_cl_send(cros_ish_cl, out_msg, out_size);
 	if (rv) {
 		dev_err(cl_data_to_dev(client_data),
@@ -249,17 +256,23 @@ static void process_recv(struct ishtp_cl *cros_ish_cl,
 
 	switch (in_msg->hdr.channel) {
 	case CROS_EC_COMMAND:
-		/* Sanity check */
-		if (!client_data->response.data) {
+		if (client_data->response.received) {
 			dev_err(dev,
-				"Receiving buffer is null. Should be allocated by calling function\n");
-			client_data->response.error = -EINVAL;
-			goto error_wake_up;
+				"Previous firmware message not yet processed\n");
+			goto end_error;
 		}
 
-		if (client_data->response.received) {
+		if (client_data->response.token != in_msg->hdr.token) {
+			dev_err_ratelimited(dev,
+					    "Dropping old response token %d\n",
+					    in_msg->hdr.token);
+			goto end_error;
+		}
+
+		/* Sanity check */
+		if (!client_data->response.data) {
 			dev_err(dev,
-				"Previous firmware message not yet processed\n");
+				"Receiving buffer is null. Should be allocated by calling function\n");
 			client_data->response.error = -EINVAL;
 			goto error_wake_up;
 		}
@@ -289,21 +302,28 @@ static void process_recv(struct ishtp_cl *cros_ish_cl,
 		memcpy(client_data->response.data,
 		       rb_in_proc->buffer.data, data_len);
 
+error_wake_up:
+		/* Free the buffer since we copied data or didn't need it */
+		ishtp_cl_io_rb_recycle(rb_in_proc);
+		rb_in_proc = NULL;
+
 		/* Set flag before waking up the caller */
 		client_data->response.received = true;
-error_wake_up:
+
 		/* Wake the calling thread */
 		wake_up_interruptible(&client_data->response.wait_queue);
 
 		break;
 
 	case CROS_MKBP_EVENT:
+		/* Free the buffer. This is just an event without data */
+		ishtp_cl_io_rb_recycle(rb_in_proc);
+		rb_in_proc = NULL;
 		/*
 		 * Set timestamp from beginning of function since we actually
 		 * got an incoming MKBP event
 		 */
 		client_data->ec_dev->last_event_time = timestamp;
-		/* The event system doesn't send any data in buffer */
 		schedule_work(&client_data->work_ec_evt);
 
 		break;
@@ -313,8 +333,9 @@ static void process_recv(struct ishtp_cl *cros_ish_cl,
 	}
 
 end_error:
-	/* Free the buffer */
-	ishtp_cl_io_rb_recycle(rb_in_proc);
+	/* Free the buffer if we already haven't */
+	if (rb_in_proc)
+		ishtp_cl_io_rb_recycle(rb_in_proc);
 
 	up_read(&init_lock);
 }
diff --git a/drivers/platform/chrome/cros_ec_sensorhub_ring.c b/drivers/platform/chrome/cros_ec_sensorhub_ring.c
index 230e6cf3da2f..c48e5b38a441 100644
--- a/drivers/platform/chrome/cros_ec_sensorhub_ring.c
+++ b/drivers/platform/chrome/cros_ec_sensorhub_ring.c
@@ -40,7 +40,7 @@ cros_sensorhub_send_sample(struct cros_ec_sensorhub *sensorhub,
 	int id = sample->sensor_id;
 	struct iio_dev *indio_dev;
 
-	if (id > sensorhub->sensor_num)
+	if (id >= sensorhub->sensor_num)
 		return -EINVAL;
 
 	cb = sensorhub->push_data[id].push_data_cb;
@@ -820,7 +820,7 @@ static void cros_ec_sensorhub_ring_handler(struct cros_ec_sensorhub *sensorhub)
 	if (fifo_info->count > sensorhub->fifo_size ||
 	    fifo_info->size != sensorhub->fifo_size) {
 		dev_warn(sensorhub->dev,
-			 "Mismatch EC data: count %d, size %d - expected %d",
+			 "Mismatch EC data: count %d, size %d - expected %d\n",
 			 fifo_info->count, fifo_info->size,
 			 sensorhub->fifo_size);
 		goto error;
@@ -851,14 +851,14 @@ static void cros_ec_sensorhub_ring_handler(struct cros_ec_sensorhub *sensorhub)
 		}
 		if (number_data > fifo_info->count - i) {
 			dev_warn(sensorhub->dev,
-				 "Invalid EC data: too many entry received: %d, expected %d",
+				 "Invalid EC data: too many entry received: %d, expected %d\n",
 				 number_data, fifo_info->count - i);
 			break;
 		}
 		if (out + number_data >
 		    sensorhub->ring + fifo_info->count) {
 			dev_warn(sensorhub->dev,
-				 "Too many samples: %d (%zd data) to %d entries for expected %d entries",
+				 "Too many samples: %d (%zd data) to %d entries for expected %d entries\n",
 				 i, out - sensorhub->ring, i + number_data,
 				 fifo_info->count);
 			break;
diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chrome/cros_ec_typec.c
index 874269c07073..eda57db26f8d 100644
--- a/drivers/platform/chrome/cros_ec_typec.c
+++ b/drivers/platform/chrome/cros_ec_typec.c
@@ -11,11 +11,22 @@
 #include <linux/of.h>
 #include <linux/platform_data/cros_ec_commands.h>
 #include <linux/platform_data/cros_ec_proto.h>
+#include <linux/platform_data/cros_usbpd_notify.h>
 #include <linux/platform_device.h>
 #include <linux/usb/typec.h>
 
 #define DRV_NAME "cros-ec-typec"
 
+/* Per port data. */
+struct cros_typec_port {
+	struct typec_port *port;
+	/* Initial capabilities for the port. */
+	struct typec_capability caps;
+	struct typec_partner *partner;
+	/* Port partner PD identity info. */
+	struct usb_pd_identity p_identity;
+};
+
 /* Platform-specific data for the Chrome OS EC Type C controller. */
 struct cros_typec_data {
 	struct device *dev;
@@ -23,9 +34,8 @@ struct cros_typec_data {
 	int num_ports;
 	unsigned int cmd_ver;
 	/* Array of ports, indexed by port number. */
-	struct typec_port *ports[EC_USB_PD_MAX_PORTS];
-	/* Initial capabilities for each port. */
-	struct typec_capability *caps[EC_USB_PD_MAX_PORTS];
+	struct cros_typec_port *ports[EC_USB_PD_MAX_PORTS];
+	struct notifier_block nb;
 };
 
 static int cros_typec_parse_port_props(struct typec_capability *cap,
@@ -74,14 +84,25 @@ static int cros_typec_parse_port_props(struct typec_capability *cap,
 	return 0;
 }
 
+static void cros_unregister_ports(struct cros_typec_data *typec)
+{
+	int i;
+
+	for (i = 0; i < typec->num_ports; i++) {
+		if (!typec->ports[i])
+			continue;
+		typec_unregister_port(typec->ports[i]->port);
+	}
+}
+
 static int cros_typec_init_ports(struct cros_typec_data *typec)
 {
 	struct device *dev = typec->dev;
 	struct typec_capability *cap;
 	struct fwnode_handle *fwnode;
+	struct cros_typec_port *cros_port;
 	const char *port_prop;
 	int ret;
-	int i;
 	int nports;
 	u32 port_num = 0;
 
@@ -113,22 +134,23 @@ static int cros_typec_init_ports(struct cros_typec_data *typec)
 
 		dev_dbg(dev, "Registering port %d\n", port_num);
 
-		cap = devm_kzalloc(dev, sizeof(*cap), GFP_KERNEL);
-		if (!cap) {
+		cros_port = devm_kzalloc(dev, sizeof(*cros_port), GFP_KERNEL);
+		if (!cros_port) {
 			ret = -ENOMEM;
 			goto unregister_ports;
 		}
 
-		typec->caps[port_num] = cap;
+		typec->ports[port_num] = cros_port;
+		cap = &cros_port->caps;
 
 		ret = cros_typec_parse_port_props(cap, fwnode, dev);
 		if (ret < 0)
 			goto unregister_ports;
 
-		typec->ports[port_num] = typec_register_port(dev, cap);
-		if (IS_ERR(typec->ports[port_num])) {
+		cros_port->port = typec_register_port(dev, cap);
+		if (IS_ERR(cros_port->port)) {
 			dev_err(dev, "Failed to register port %d\n", port_num);
-			ret = PTR_ERR(typec->ports[port_num]);
+			ret = PTR_ERR(cros_port->port);
 			goto unregister_ports;
 		}
 	}
@@ -136,8 +158,7 @@ static int cros_typec_init_ports(struct cros_typec_data *typec)
 	return 0;
 
 unregister_ports:
-	for (i = 0; i < typec->num_ports; i++)
-		typec_unregister_port(typec->ports[i]);
+	cros_unregister_ports(typec);
 	return ret;
 }
 
@@ -172,10 +193,34 @@ static int cros_typec_ec_command(struct cros_typec_data *typec,
 	return ret;
 }
 
+static int cros_typec_add_partner(struct cros_typec_data *typec, int port_num,
+				  bool pd_en)
+{
+	struct cros_typec_port *port = typec->ports[port_num];
+	struct typec_partner_desc p_desc = {
+		.usb_pd = pd_en,
+	};
+	int ret = 0;
+
+	/*
+	 * Fill an initial PD identity, which will then be updated with info
+	 * from the EC.
+	 */
+	p_desc.identity = &port->p_identity;
+
+	port->partner = typec_register_partner(port->port, &p_desc);
+	if (IS_ERR(port->partner)) {
+		ret = PTR_ERR(port->partner);
+		port->partner = NULL;
+	}
+
+	return ret;
+}
+
 static void cros_typec_set_port_params_v0(struct cros_typec_data *typec,
 		int port_num, struct ec_response_usb_pd_control *resp)
 {
-	struct typec_port *port = typec->ports[port_num];
+	struct typec_port *port = typec->ports[port_num]->port;
 	enum typec_orientation polarity;
 
 	if (!resp->enabled)
@@ -192,8 +237,10 @@ static void cros_typec_set_port_params_v0(struct cros_typec_data *typec,
 static void cros_typec_set_port_params_v1(struct cros_typec_data *typec,
 		int port_num, struct ec_response_usb_pd_control_v1 *resp)
 {
-	struct typec_port *port = typec->ports[port_num];
+	struct typec_port *port = typec->ports[port_num]->port;
 	enum typec_orientation polarity;
+	bool pd_en;
+	int ret;
 
 	if (!(resp->enabled & PD_CTRL_RESP_ENABLED_CONNECTED))
 		polarity = TYPEC_ORIENTATION_NONE;
@@ -208,6 +255,25 @@ static void cros_typec_set_port_params_v1(struct cros_typec_data *typec,
 			TYPEC_SOURCE : TYPEC_SINK);
 	typec_set_vconn_role(port, resp->role & PD_CTRL_RESP_ROLE_VCONN ?
 			TYPEC_SOURCE : TYPEC_SINK);
+
+	/* Register/remove partners when a connect/disconnect occurs. */
+	if (resp->enabled & PD_CTRL_RESP_ENABLED_CONNECTED) {
+		if (typec->ports[port_num]->partner)
+			return;
+
+		pd_en = resp->enabled & PD_CTRL_RESP_ENABLED_PD_CAPABLE;
+		ret = cros_typec_add_partner(typec, port_num, pd_en);
+		if (!ret)
+			dev_warn(typec->dev,
+				 "Failed to register partner on port: %d\n",
+				 port_num);
+	} else {
+		if (!typec->ports[port_num]->partner)
+			return;
+
+		typec_unregister_partner(typec->ports[port_num]->partner);
+		typec->ports[port_num]->partner = NULL;
+	}
 }
 
 static int cros_typec_port_update(struct cros_typec_data *typec, int port_num)
@@ -272,6 +338,22 @@ static int cros_typec_get_cmd_version(struct cros_typec_data *typec)
 	return 0;
 }
 
+static int cros_ec_typec_event(struct notifier_block *nb,
+			       unsigned long host_event, void *_notify)
+{
+	struct cros_typec_data *typec = container_of(nb, struct cros_typec_data,
+						     nb);
+	int ret, i;
+
+	for (i = 0; i < typec->num_ports; i++) {
+		ret = cros_typec_port_update(typec, i);
+		if (ret < 0)
+			dev_warn(typec->dev, "Update failed for port: %d\n", i);
+	}
+
+	return NOTIFY_OK;
+}
+
 #ifdef CONFIG_ACPI
 static const struct acpi_device_id cros_typec_acpi_id[] = {
 	{ "GOOG0014", 0 },
@@ -332,12 +414,15 @@ static int cros_typec_probe(struct platform_device *pdev)
 			goto unregister_ports;
 	}
 
+	typec->nb.notifier_call = cros_ec_typec_event;
+	ret = cros_usbpd_register_notify(&typec->nb);
+	if (ret < 0)
+		goto unregister_ports;
+
 	return 0;
 
 unregister_ports:
-	for (i = 0; i < typec->num_ports; i++)
-		if (typec->ports[i])
-			typec_unregister_port(typec->ports[i]);
+	cros_unregister_ports(typec);
 	return ret;
 }
 
diff --git a/drivers/platform/chrome/wilco_ec/debugfs.c b/drivers/platform/chrome/wilco_ec/debugfs.c
index df5a5f6c3ec6..a812788a0bdc 100644
--- a/drivers/platform/chrome/wilco_ec/debugfs.c
+++ b/drivers/platform/chrome/wilco_ec/debugfs.c
@@ -208,7 +208,12 @@ static int send_ec_cmd(struct wilco_ec_device *ec, u8 sub_cmd, u8 *out_val)
  */
 static int h1_gpio_get(void *arg, u64 *val)
 {
-	return send_ec_cmd(arg, SUB_CMD_H1_GPIO, (u8 *)val);
+	int ret;
+
+	ret = send_ec_cmd(arg, SUB_CMD_H1_GPIO, (u8 *)val);
+	if (ret == 0)
+		*val &= 0xFF;
+	return ret;
 }
 
 DEFINE_DEBUGFS_ATTRIBUTE(fops_h1_gpio, h1_gpio_get, NULL, "0x%02llx\n");
diff --git a/drivers/power/supply/88pm860x_battery.c b/drivers/power/supply/88pm860x_battery.c
index 5ca047b3f58f..1308f3a185f3 100644
--- a/drivers/power/supply/88pm860x_battery.c
+++ b/drivers/power/supply/88pm860x_battery.c
@@ -919,16 +919,12 @@ static int pm860x_battery_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	info->irq_cc = platform_get_irq(pdev, 0);
-	if (info->irq_cc <= 0) {
-		dev_err(&pdev->dev, "No IRQ resource!\n");
+	if (info->irq_cc <= 0)
 		return -EINVAL;
-	}
 
 	info->irq_batt = platform_get_irq(pdev, 1);
-	if (info->irq_batt <= 0) {
-		dev_err(&pdev->dev, "No IRQ resource!\n");
+	if (info->irq_batt <= 0)
 		return -EINVAL;
-	}
 
 	info->chip = chip;
 	info->i2c =
diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
index f3424fdce341..d37ec0d03237 100644
--- a/drivers/power/supply/Kconfig
+++ b/drivers/power/supply/Kconfig
@@ -577,7 +577,7 @@ config CHARGER_BQ24257
 	tristate "TI BQ24250/24251/24257 battery charger driver"
 	depends on I2C
 	depends on GPIOLIB || COMPILE_TEST
-	depends on REGMAP_I2C
+	select REGMAP_I2C
 	help
 	  Say Y to enable support for the TI BQ24250, BQ24251, and BQ24257 battery
 	  chargers.
diff --git a/drivers/power/supply/axp288_fuel_gauge.c b/drivers/power/supply/axp288_fuel_gauge.c
index f40fa0e63b6e..148eb8105803 100644
--- a/drivers/power/supply/axp288_fuel_gauge.c
+++ b/drivers/power/supply/axp288_fuel_gauge.c
@@ -717,6 +717,12 @@ static const struct dmi_system_id axp288_fuel_gauge_blacklist[] = {
 			DMI_MATCH(DMI_PRODUCT_NAME, "STK1A32SC"),
 		},
 	},
+	{
+		/* Meegopad T02 */
+		.matches = {
+			DMI_MATCH(DMI_PRODUCT_NAME, "MEEGOPAD T02"),
+		},
+	},
 	{
 		/* Meegopad T08 */
 		.matches = {
diff --git a/drivers/power/supply/max14656_charger_detector.c b/drivers/power/supply/max14656_charger_detector.c
index 3bbb8b4c8ae7..137f9fafce8c 100644
--- a/drivers/power/supply/max14656_charger_detector.c
+++ b/drivers/power/supply/max14656_charger_detector.c
@@ -139,10 +139,9 @@ static void max14656_irq_worker(struct work_struct *work)
 
 	u8 buf[REG_TOTAL_NUM];
 	u8 chg_type;
-	int ret = 0;
 
-	ret = max14656_read_block_reg(chip->client, MAX14656_DEVICE_ID,
-				      REG_TOTAL_NUM, buf);
+	max14656_read_block_reg(chip->client, MAX14656_DEVICE_ID,
+				REG_TOTAL_NUM, buf);
 
 	if ((buf[MAX14656_STATUS_1] & STATUS1_VB_VALID_MASK) &&
 		(buf[MAX14656_STATUS_1] & STATUS1_CHG_TYPE_MASK)) {
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index eebbc917ac97..c13d146cdde5 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -232,6 +232,16 @@ config PWM_IMX_TPM
 	  To compile this driver as a module, choose M here: the module
 	  will be called pwm-imx-tpm.
 
+config PWM_IQS620A
+	tristate "Azoteq IQS620A PWM support"
+	depends on MFD_IQS62X || COMPILE_TEST
+	help
+	  Generic PWM framework driver for the Azoteq IQS620A multi-function
+	  sensor.
+
+	  To compile this driver as a module, choose M here: the module will
+	  be called pwm-iqs620a.
+
 config PWM_JZ4740
 	tristate "Ingenic JZ47xx PWM support"
 	depends on MACH_INGENIC
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index 9a475073dafc..a59c710e98c7 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_PWM_IMG)		+= pwm-img.o
 obj-$(CONFIG_PWM_IMX1)		+= pwm-imx1.o
 obj-$(CONFIG_PWM_IMX27)		+= pwm-imx27.o
 obj-$(CONFIG_PWM_IMX_TPM)	+= pwm-imx-tpm.o
+obj-$(CONFIG_PWM_IQS620A)	+= pwm-iqs620a.o
 obj-$(CONFIG_PWM_JZ4740)	+= pwm-jz4740.o
 obj-$(CONFIG_PWM_LP3943)	+= pwm-lp3943.o
 obj-$(CONFIG_PWM_LPC18XX_SCT)	+= pwm-lpc18xx-sct.o
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index 9973c442b455..bca04965bfe6 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -537,7 +537,7 @@ static void pwm_apply_state_debug(struct pwm_device *pwm,
 
 	if (!state->enabled && s2.enabled && s2.duty_cycle > 0)
 		dev_warn(chip->dev,
-			 "requested disabled, but yielded enabled with duty > 0");
+			 "requested disabled, but yielded enabled with duty > 0\n");
 
 	/* reapply the state that the driver reported being configured. */
 	err = chip->ops->apply(chip, pwm, &s1);
diff --git a/drivers/pwm/pwm-iqs620a.c b/drivers/pwm/pwm-iqs620a.c
new file mode 100644
index 000000000000..674f0e238ba0
--- /dev/null
+++ b/drivers/pwm/pwm-iqs620a.c
@@ -0,0 +1,270 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Azoteq IQS620A PWM Generator
+ *
+ * Copyright (C) 2019 Jeff LaBundy <jeff@labundy.com>
+ *
+ * Limitations:
+ * - The period is fixed to 1 ms and is generated continuously despite changes
+ *   to the duty cycle or enable/disable state.
+ * - Changes to the duty cycle or enable/disable state take effect immediately
+ *   and may result in a glitch during the period in which the change is made.
+ * - The device cannot generate a 0% duty cycle. For duty cycles below 1 / 256
+ *   ms, the output is disabled and relies upon an external pull-down resistor
+ *   to hold the GPIO3/LTX pin low.
+ */
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/mfd/iqs62x.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/notifier.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+#define IQS620_PWR_SETTINGS			0xD2
+#define IQS620_PWR_SETTINGS_PWM_OUT		BIT(7)
+
+#define IQS620_PWM_DUTY_CYCLE			0xD8
+
+#define IQS620_PWM_PERIOD_NS			1000000
+
+struct iqs620_pwm_private {
+	struct iqs62x_core *iqs62x;
+	struct pwm_chip chip;
+	struct notifier_block notifier;
+	struct mutex lock;
+	bool out_en;
+	u8 duty_val;
+};
+
+static int iqs620_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+			    const struct pwm_state *state)
+{
+	struct iqs620_pwm_private *iqs620_pwm;
+	struct iqs62x_core *iqs62x;
+	int duty_scale, ret;
+
+	if (state->polarity != PWM_POLARITY_NORMAL)
+		return -ENOTSUPP;
+
+	if (state->period < IQS620_PWM_PERIOD_NS)
+		return -EINVAL;
+
+	iqs620_pwm = container_of(chip, struct iqs620_pwm_private, chip);
+	iqs62x = iqs620_pwm->iqs62x;
+
+	/*
+	 * The duty cycle generated by the device is calculated as follows:
+	 *
+	 * duty_cycle = (IQS620_PWM_DUTY_CYCLE + 1) / 256 * 1 ms
+	 *
+	 * ...where IQS620_PWM_DUTY_CYCLE is a register value between 0 and 255
+	 * (inclusive). Therefore the lowest duty cycle the device can generate
+	 * while the output is enabled is 1 / 256 ms.
+	 *
+	 * For lower duty cycles (e.g. 0), the PWM output is simply disabled to
+	 * allow an external pull-down resistor to hold the GPIO3/LTX pin low.
+	 */
+	duty_scale = state->duty_cycle * 256 / IQS620_PWM_PERIOD_NS;
+
+	mutex_lock(&iqs620_pwm->lock);
+
+	if (!state->enabled || !duty_scale) {
+		ret = regmap_update_bits(iqs62x->regmap, IQS620_PWR_SETTINGS,
+					 IQS620_PWR_SETTINGS_PWM_OUT, 0);
+		if (ret)
+			goto err_mutex;
+	}
+
+	if (duty_scale) {
+		u8 duty_val = min(duty_scale - 1, 0xFF);
+
+		ret = regmap_write(iqs62x->regmap, IQS620_PWM_DUTY_CYCLE,
+				   duty_val);
+		if (ret)
+			goto err_mutex;
+
+		iqs620_pwm->duty_val = duty_val;
+	}
+
+	if (state->enabled && duty_scale) {
+		ret = regmap_update_bits(iqs62x->regmap, IQS620_PWR_SETTINGS,
+					 IQS620_PWR_SETTINGS_PWM_OUT, 0xFF);
+		if (ret)
+			goto err_mutex;
+	}
+
+	iqs620_pwm->out_en = state->enabled;
+
+err_mutex:
+	mutex_unlock(&iqs620_pwm->lock);
+
+	return ret;
+}
+
+static void iqs620_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
+				 struct pwm_state *state)
+{
+	struct iqs620_pwm_private *iqs620_pwm;
+
+	iqs620_pwm = container_of(chip, struct iqs620_pwm_private, chip);
+
+	mutex_lock(&iqs620_pwm->lock);
+
+	/*
+	 * Since the device cannot generate a 0% duty cycle, requests to do so
+	 * cause subsequent calls to iqs620_pwm_get_state to report the output
+	 * as disabled with duty cycle equal to that which was in use prior to
+	 * the request. This is not ideal, but is the best compromise based on
+	 * the capabilities of the device.
+	 */
+	state->enabled = iqs620_pwm->out_en;
+	state->duty_cycle = DIV_ROUND_UP((iqs620_pwm->duty_val + 1) *
+					 IQS620_PWM_PERIOD_NS, 256);
+
+	mutex_unlock(&iqs620_pwm->lock);
+
+	state->period = IQS620_PWM_PERIOD_NS;
+}
+
+static int iqs620_pwm_notifier(struct notifier_block *notifier,
+			       unsigned long event_flags, void *context)
+{
+	struct iqs620_pwm_private *iqs620_pwm;
+	struct iqs62x_core *iqs62x;
+	int ret;
+
+	if (!(event_flags & BIT(IQS62X_EVENT_SYS_RESET)))
+		return NOTIFY_DONE;
+
+	iqs620_pwm = container_of(notifier, struct iqs620_pwm_private,
+				  notifier);
+	iqs62x = iqs620_pwm->iqs62x;
+
+	mutex_lock(&iqs620_pwm->lock);
+
+	/*
+	 * The parent MFD driver already prints an error message in the event
+	 * of a device reset, so nothing else is printed here unless there is
+	 * an additional failure.
+	 */
+	ret = regmap_write(iqs62x->regmap, IQS620_PWM_DUTY_CYCLE,
+			   iqs620_pwm->duty_val);
+	if (ret)
+		goto err_mutex;
+
+	ret = regmap_update_bits(iqs62x->regmap, IQS620_PWR_SETTINGS,
+				 IQS620_PWR_SETTINGS_PWM_OUT,
+				 iqs620_pwm->out_en ? 0xFF : 0);
+
+err_mutex:
+	mutex_unlock(&iqs620_pwm->lock);
+
+	if (ret) {
+		dev_err(iqs620_pwm->chip.dev,
+			"Failed to re-initialize device: %d\n", ret);
+		return NOTIFY_BAD;
+	}
+
+	return NOTIFY_OK;
+}
+
+static const struct pwm_ops iqs620_pwm_ops = {
+	.apply = iqs620_pwm_apply,
+	.get_state = iqs620_pwm_get_state,
+	.owner = THIS_MODULE,
+};
+
+static void iqs620_pwm_notifier_unregister(void *context)
+{
+	struct iqs620_pwm_private *iqs620_pwm = context;
+	int ret;
+
+	ret = blocking_notifier_chain_unregister(&iqs620_pwm->iqs62x->nh,
+						 &iqs620_pwm->notifier);
+	if (ret)
+		dev_err(iqs620_pwm->chip.dev,
+			"Failed to unregister notifier: %d\n", ret);
+}
+
+static int iqs620_pwm_probe(struct platform_device *pdev)
+{
+	struct iqs62x_core *iqs62x = dev_get_drvdata(pdev->dev.parent);
+	struct iqs620_pwm_private *iqs620_pwm;
+	unsigned int val;
+	int ret;
+
+	iqs620_pwm = devm_kzalloc(&pdev->dev, sizeof(*iqs620_pwm), GFP_KERNEL);
+	if (!iqs620_pwm)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, iqs620_pwm);
+	iqs620_pwm->iqs62x = iqs62x;
+
+	ret = regmap_read(iqs62x->regmap, IQS620_PWR_SETTINGS, &val);
+	if (ret)
+		return ret;
+	iqs620_pwm->out_en = val & IQS620_PWR_SETTINGS_PWM_OUT;
+
+	ret = regmap_read(iqs62x->regmap, IQS620_PWM_DUTY_CYCLE, &val);
+	if (ret)
+		return ret;
+	iqs620_pwm->duty_val = val;
+
+	iqs620_pwm->chip.dev = &pdev->dev;
+	iqs620_pwm->chip.ops = &iqs620_pwm_ops;
+	iqs620_pwm->chip.base = -1;
+	iqs620_pwm->chip.npwm = 1;
+
+	mutex_init(&iqs620_pwm->lock);
+
+	iqs620_pwm->notifier.notifier_call = iqs620_pwm_notifier;
+	ret = blocking_notifier_chain_register(&iqs620_pwm->iqs62x->nh,
+					       &iqs620_pwm->notifier);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to register notifier: %d\n", ret);
+		return ret;
+	}
+
+	ret = devm_add_action_or_reset(&pdev->dev,
+				       iqs620_pwm_notifier_unregister,
+				       iqs620_pwm);
+	if (ret)
+		return ret;
+
+	ret = pwmchip_add(&iqs620_pwm->chip);
+	if (ret)
+		dev_err(&pdev->dev, "Failed to add device: %d\n", ret);
+
+	return ret;
+}
+
+static int iqs620_pwm_remove(struct platform_device *pdev)
+{
+	struct iqs620_pwm_private *iqs620_pwm = platform_get_drvdata(pdev);
+	int ret;
+
+	ret = pwmchip_remove(&iqs620_pwm->chip);
+	if (ret)
+		dev_err(&pdev->dev, "Failed to remove device: %d\n", ret);
+
+	return ret;
+}
+
+static struct platform_driver iqs620_pwm_platform_driver = {
+	.driver = {
+		.name = "iqs620a-pwm",
+	},
+	.probe = iqs620_pwm_probe,
+	.remove = iqs620_pwm_remove,
+};
+module_platform_driver(iqs620_pwm_platform_driver);
+
+MODULE_AUTHOR("Jeff LaBundy <jeff@labundy.com>");
+MODULE_DESCRIPTION("Azoteq IQS620A PWM Generator");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:iqs620a-pwm");
diff --git a/drivers/ras/cec.c b/drivers/ras/cec.c
index c09cf55e2d20..569d9ad2c594 100644
--- a/drivers/ras/cec.c
+++ b/drivers/ras/cec.c
@@ -309,7 +309,7 @@ static bool sanity_check(struct ce_array *ca)
 	return ret;
 }
 
-int cec_add_elem(u64 pfn)
+static int cec_add_elem(u64 pfn)
 {
 	struct ce_array *ca = &ce_arr;
 	unsigned int to = 0;
@@ -527,7 +527,33 @@ static int __init create_debugfs_nodes(void)
 	return 1;
 }
 
-void __init cec_init(void)
+static int cec_notifier(struct notifier_block *nb, unsigned long val,
+			void *data)
+{
+	struct mce *m = (struct mce *)data;
+
+	if (!m)
+		return NOTIFY_DONE;
+
+	/* We eat only correctable DRAM errors with usable addresses. */
+	if (mce_is_memory_error(m) &&
+	    mce_is_correctable(m)  &&
+	    mce_usable_address(m)) {
+		if (!cec_add_elem(m->addr >> PAGE_SHIFT)) {
+			m->kflags |= MCE_HANDLED_CEC;
+			return NOTIFY_OK;
+		}
+	}
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block cec_nb = {
+	.notifier_call	= cec_notifier,
+	.priority	= MCE_PRIO_CEC,
+};
+
+static void __init cec_init(void)
 {
 	if (ce_arr.disabled)
 		return;
@@ -546,8 +572,11 @@ void __init cec_init(void)
 	INIT_DELAYED_WORK(&cec_work, cec_work_fn);
 	schedule_delayed_work(&cec_work, CEC_DECAY_DEFAULT_INTERVAL);
 
+	mce_register_decode_chain(&cec_nb);
+
 	pr_info("Correctable Errors collector initialized.\n");
 }
+late_initcall(cec_init);
 
 int __init parse_cec_param(char *str)
 {
diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c
index f60e1b26c2d2..716ca5bb178e 100644
--- a/drivers/regulator/ab8500.c
+++ b/drivers/regulator/ab8500.c
@@ -139,17 +139,6 @@ static const unsigned int ldo_vintcore_voltages[] = {
 	1350000,
 };
 
-static const unsigned int ldo_sdio_voltages[] = {
-	1160000,
-	1050000,
-	1100000,
-	1500000,
-	1800000,
-	2200000,
-	2910000,
-	3050000,
-};
-
 static const unsigned int fixed_1200000_voltage[] = {
 	1200000,
 };
@@ -166,10 +155,6 @@ static const unsigned int fixed_2050000_voltage[] = {
 	2050000,
 };
 
-static const unsigned int fixed_3300000_voltage[] = {
-	3300000,
-};
-
 static const unsigned int ldo_vana_voltages[] = {
 	1050000,
 	1075000,
@@ -192,13 +177,6 @@ static const unsigned int ldo_vaudio_voltages[] = {
 	2600000,	/* Duplicated in Vaudio and IsoUicc Control register. */
 };
 
-static const unsigned int ldo_vdmic_voltages[] = {
-	1800000,
-	1900000,
-	2000000,
-	2850000,
-};
-
 static DEFINE_MUTEX(shared_mode_mutex);
 static struct ab8500_shared_mode ldo_anamic1_shared;
 static struct ab8500_shared_mode ldo_anamic2_shared;
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index c340505150b6..ad143004c32b 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -5496,6 +5496,7 @@ static void regulator_summary_show_subtree(struct seq_file *s,
 		seq_printf(s, "%*s%-*s ",
 			   (level + 1) * 3 + 1, "",
 			   30 - (level + 1) * 3,
+			   consumer->supply_name ? consumer->supply_name :
 			   consumer->dev ? dev_name(consumer->dev) : "deviceless");
 
 		switch (rdev->desc->type) {
diff --git a/drivers/regulator/qcom_rpm-regulator.c b/drivers/regulator/qcom_rpm-regulator.c
index 7fc97f23fcf4..1ee8ec686ed3 100644
--- a/drivers/regulator/qcom_rpm-regulator.c
+++ b/drivers/regulator/qcom_rpm-regulator.c
@@ -604,16 +604,6 @@ static const struct qcom_rpm_reg pm8921_smps = {
 	.supports_force_mode_bypass = false,
 };
 
-static const struct qcom_rpm_reg pm8921_ftsmps = {
-	.desc.linear_ranges = ftsmps_ranges,
-	.desc.n_linear_ranges = ARRAY_SIZE(ftsmps_ranges),
-	.desc.n_voltages = 101,
-	.desc.ops = &uV_ops,
-	.parts = &rpm8960_smps_parts,
-	.supports_force_mode_auto = true,
-	.supports_force_mode_bypass = false,
-};
-
 static const struct qcom_rpm_reg pm8921_ncp = {
 	.desc.linear_ranges = ncp_ranges,
 	.desc.n_linear_ranges = ARRAY_SIZE(ncp_ranges),
diff --git a/drivers/regulator/tps80031-regulator.c b/drivers/regulator/tps80031-regulator.c
index 85a6a8ca8c1b..a29e65230132 100644
--- a/drivers/regulator/tps80031-regulator.c
+++ b/drivers/regulator/tps80031-regulator.c
@@ -271,7 +271,7 @@ static int tps80031_vbus_is_enabled(struct regulator_dev *rdev)
 {
 	struct tps80031_regulator *ri = rdev_get_drvdata(rdev);
 	struct device *parent = to_tps80031_dev(rdev);
-	int ret = -EIO;
+	int ret;
 	uint8_t ctrl1 = 0;
 	uint8_t ctrl3 = 0;
 
@@ -322,7 +322,7 @@ static int tps80031_vbus_disable(struct regulator_dev *rdev)
 {
 	struct tps80031_regulator *ri = rdev_get_drvdata(rdev);
 	struct device *parent = to_tps80031_dev(rdev);
-	int ret = 0;
+	int ret;
 
 	if (ri->config_flags & TPS80031_VBUS_DISCHRG_EN_PDN) {
 		ret = tps80031_write(parent, TPS80031_SLAVE_ID2,
@@ -530,7 +530,8 @@ static int tps80031_regulator_config(struct device *parent,
 	case TPS80031_REGULATOR_LDOUSB:
 		if (ri->config_flags & (TPS80031_USBLDO_INPUT_VSYS |
 			TPS80031_USBLDO_INPUT_PMID)) {
-			unsigned val = 0;
+			unsigned val;
+
 			if (ri->config_flags & TPS80031_USBLDO_INPUT_VSYS)
 				val = MISC2_LDOUSB_IN_VSYS;
 			else
diff --git a/drivers/remoteproc/mtk_common.h b/drivers/remoteproc/mtk_common.h
index deb20096146a..0066c83636d0 100644
--- a/drivers/remoteproc/mtk_common.h
+++ b/drivers/remoteproc/mtk_common.h
@@ -68,7 +68,7 @@ struct mtk_scp {
 	wait_queue_head_t ack_wq;
 
 	void __iomem *cpu_addr;
-	phys_addr_t phys_addr;
+	dma_addr_t dma_addr;
 	size_t dram_size;
 
 	struct rproc_subdev *rpmsg_subdev;
diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c
index ea3743e7e794..2bead57c9cf9 100644
--- a/drivers/remoteproc/mtk_scp.c
+++ b/drivers/remoteproc/mtk_scp.c
@@ -330,7 +330,7 @@ static void *scp_da_to_va(struct rproc *rproc, u64 da, size_t len)
 		if (offset >= 0 && (offset + len) < scp->sram_size)
 			return (void __force *)scp->sram_base + offset;
 	} else {
-		offset = da - scp->phys_addr;
+		offset = da - scp->dma_addr;
 		if (offset >= 0 && (offset + len) < scp->dram_size)
 			return (void __force *)scp->cpu_addr + offset;
 	}
@@ -451,7 +451,7 @@ static int scp_map_memory_region(struct mtk_scp *scp)
 	/* Reserved SCP code size */
 	scp->dram_size = MAX_CODE_SIZE;
 	scp->cpu_addr = dma_alloc_coherent(scp->dev, scp->dram_size,
-					   &scp->phys_addr, GFP_KERNEL);
+					   &scp->dma_addr, GFP_KERNEL);
 	if (!scp->cpu_addr)
 		return -ENOMEM;
 
@@ -461,7 +461,7 @@ static int scp_map_memory_region(struct mtk_scp *scp)
 static void scp_unmap_memory_region(struct mtk_scp *scp)
 {
 	dma_free_coherent(scp->dev, scp->dram_size, scp->cpu_addr,
-			  scp->phys_addr);
+			  scp->dma_addr);
 	of_reserved_mem_device_release(scp->dev);
 }
 
diff --git a/drivers/remoteproc/qcom_q6v5_mss.c b/drivers/remoteproc/qcom_q6v5_mss.c
index ce49c3236ff7..5475d4f808a8 100644
--- a/drivers/remoteproc/qcom_q6v5_mss.c
+++ b/drivers/remoteproc/qcom_q6v5_mss.c
@@ -367,7 +367,7 @@ static int q6v5_pds_enable(struct q6v5 *qproc, struct device **pds,
 	}
 
 	return ret;
-};
+}
 
 static void q6v5_pds_disable(struct q6v5 *qproc, struct device **pds,
 			     size_t pd_count)
@@ -1527,7 +1527,7 @@ static int q6v5_pds_attach(struct device *dev, struct device **devs,
 		dev_pm_domain_detach(devs[i], false);
 
 	return ret;
-};
+}
 
 static void q6v5_pds_detach(struct q6v5 *qproc, struct device **pds,
 			    size_t pd_count)
@@ -1675,7 +1675,7 @@ static int q6v5_probe(struct platform_device *pdev)
 	ret = of_property_read_string_index(pdev->dev.of_node, "firmware-name",
 					    1, &qproc->hexagon_mdt_image);
 	if (ret < 0 && ret != -EINVAL)
-		return ret;
+		goto free_rproc;
 
 	platform_set_drvdata(pdev, qproc);
 
@@ -1766,17 +1766,23 @@ static int q6v5_probe(struct platform_device *pdev)
 	qproc->sysmon = qcom_add_sysmon_subdev(rproc, "modem", 0x12);
 	if (IS_ERR(qproc->sysmon)) {
 		ret = PTR_ERR(qproc->sysmon);
-		goto detach_proxy_pds;
+		goto remove_subdevs;
 	}
 
 	ret = rproc_add(rproc);
 	if (ret)
-		goto detach_proxy_pds;
+		goto remove_sysmon_subdev;
 
 	return 0;
 
-detach_proxy_pds:
+remove_sysmon_subdev:
+	qcom_remove_sysmon_subdev(qproc->sysmon);
+remove_subdevs:
 	qcom_remove_ipa_notify_subdev(qproc->rproc, &qproc->ipa_notify_subdev);
+	qcom_remove_ssr_subdev(rproc, &qproc->ssr_subdev);
+	qcom_remove_smd_subdev(rproc, &qproc->smd_subdev);
+	qcom_remove_glink_subdev(rproc, &qproc->glink_subdev);
+detach_proxy_pds:
 	q6v5_pds_detach(qproc, qproc->proxy_pds, qproc->proxy_pd_count);
 detach_active_pds:
 	q6v5_pds_detach(qproc, qproc->active_pds, qproc->active_pd_count);
@@ -1789,19 +1795,20 @@ static int q6v5_probe(struct platform_device *pdev)
 static int q6v5_remove(struct platform_device *pdev)
 {
 	struct q6v5 *qproc = platform_get_drvdata(pdev);
+	struct rproc *rproc = qproc->rproc;
 
-	rproc_del(qproc->rproc);
+	rproc_del(rproc);
 
 	qcom_remove_sysmon_subdev(qproc->sysmon);
-	qcom_remove_ipa_notify_subdev(qproc->rproc, &qproc->ipa_notify_subdev);
-	qcom_remove_glink_subdev(qproc->rproc, &qproc->glink_subdev);
-	qcom_remove_smd_subdev(qproc->rproc, &qproc->smd_subdev);
-	qcom_remove_ssr_subdev(qproc->rproc, &qproc->ssr_subdev);
+	qcom_remove_ipa_notify_subdev(rproc, &qproc->ipa_notify_subdev);
+	qcom_remove_ssr_subdev(rproc, &qproc->ssr_subdev);
+	qcom_remove_smd_subdev(rproc, &qproc->smd_subdev);
+	qcom_remove_glink_subdev(rproc, &qproc->glink_subdev);
 
-	q6v5_pds_detach(qproc, qproc->active_pds, qproc->active_pd_count);
 	q6v5_pds_detach(qproc, qproc->proxy_pds, qproc->proxy_pd_count);
+	q6v5_pds_detach(qproc, qproc->active_pds, qproc->active_pd_count);
 
-	rproc_free(qproc->rproc);
+	rproc_free(rproc);
 
 	return 0;
 }
diff --git a/drivers/remoteproc/remoteproc_debugfs.c b/drivers/remoteproc/remoteproc_debugfs.c
index d734cadb16e3..732770e92b99 100644
--- a/drivers/remoteproc/remoteproc_debugfs.c
+++ b/drivers/remoteproc/remoteproc_debugfs.c
@@ -269,17 +269,7 @@ static int rproc_rsc_table_show(struct seq_file *seq, void *p)
 	return 0;
 }
 
-static int rproc_rsc_table_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, rproc_rsc_table_show, inode->i_private);
-}
-
-static const struct file_operations rproc_rsc_table_ops = {
-	.open		= rproc_rsc_table_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(rproc_rsc_table);
 
 /* Expose carveout content via debugfs */
 static int rproc_carveouts_show(struct seq_file *seq, void *p)
@@ -299,17 +289,7 @@ static int rproc_carveouts_show(struct seq_file *seq, void *p)
 	return 0;
 }
 
-static int rproc_carveouts_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, rproc_carveouts_show, inode->i_private);
-}
-
-static const struct file_operations rproc_carveouts_ops = {
-	.open		= rproc_carveouts_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(rproc_carveouts);
 
 void rproc_remove_trace_file(struct dentry *tfile)
 {
@@ -354,9 +334,9 @@ void rproc_create_debug_dir(struct rproc *rproc)
 	debugfs_create_file("crash", 0200, rproc->dbg_dir,
 			    rproc, &rproc_crash_ops);
 	debugfs_create_file("resource_table", 0400, rproc->dbg_dir,
-			    rproc, &rproc_rsc_table_ops);
+			    rproc, &rproc_rsc_table_fops);
 	debugfs_create_file("carveout_memories", 0400, rproc->dbg_dir,
-			    rproc, &rproc_carveouts_ops);
+			    rproc, &rproc_carveouts_fops);
 }
 
 void __init rproc_init_debugfs(void)
diff --git a/drivers/remoteproc/remoteproc_sysfs.c b/drivers/remoteproc/remoteproc_sysfs.c
index 7f8536b73295..52b871327b55 100644
--- a/drivers/remoteproc/remoteproc_sysfs.c
+++ b/drivers/remoteproc/remoteproc_sysfs.c
@@ -4,6 +4,7 @@
  */
 
 #include <linux/remoteproc.h>
+#include <linux/slab.h>
 
 #include "remoteproc_internal.h"
 
diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
index 6a66dbf2df40..0bdd56f02f18 100644
--- a/drivers/remoteproc/stm32_rproc.c
+++ b/drivers/remoteproc/stm32_rproc.c
@@ -19,6 +19,7 @@
 #include <linux/regmap.h>
 #include <linux/remoteproc.h>
 #include <linux/reset.h>
+#include <linux/slab.h>
 #include <linux/workqueue.h>
 
 #include "remoteproc_internal.h"
diff --git a/drivers/reset/hisilicon/hi6220_reset.c b/drivers/reset/hisilicon/hi6220_reset.c
index 24e6d420b26b..19926506d033 100644
--- a/drivers/reset/hisilicon/hi6220_reset.c
+++ b/drivers/reset/hisilicon/hi6220_reset.c
@@ -33,6 +33,7 @@
 enum hi6220_reset_ctrl_type {
 	PERIPHERAL,
 	MEDIA,
+	AO,
 };
 
 struct hi6220_reset_data {
@@ -92,6 +93,65 @@ static const struct reset_control_ops hi6220_media_reset_ops = {
 	.deassert = hi6220_media_deassert,
 };
 
+#define AO_SCTRL_SC_PW_CLKEN0     0x800
+#define AO_SCTRL_SC_PW_CLKDIS0    0x804
+
+#define AO_SCTRL_SC_PW_RSTEN0     0x810
+#define AO_SCTRL_SC_PW_RSTDIS0    0x814
+
+#define AO_SCTRL_SC_PW_ISOEN0     0x820
+#define AO_SCTRL_SC_PW_ISODIS0    0x824
+#define AO_MAX_INDEX              12
+
+static int hi6220_ao_assert(struct reset_controller_dev *rc_dev,
+			       unsigned long idx)
+{
+	struct hi6220_reset_data *data = to_reset_data(rc_dev);
+	struct regmap *regmap = data->regmap;
+	int ret;
+
+	ret = regmap_write(regmap, AO_SCTRL_SC_PW_RSTEN0, BIT(idx));
+	if (ret)
+		return ret;
+
+	ret = regmap_write(regmap, AO_SCTRL_SC_PW_ISOEN0, BIT(idx));
+	if (ret)
+		return ret;
+
+	ret = regmap_write(regmap, AO_SCTRL_SC_PW_CLKDIS0, BIT(idx));
+	return ret;
+}
+
+static int hi6220_ao_deassert(struct reset_controller_dev *rc_dev,
+				 unsigned long idx)
+{
+	struct hi6220_reset_data *data = to_reset_data(rc_dev);
+	struct regmap *regmap = data->regmap;
+	int ret;
+
+	/*
+	 * It was suggested to disable isolation before enabling
+	 * the clocks and deasserting reset, to avoid glitches.
+	 * But this order is preserved to keep it matching the
+	 * vendor code.
+	 */
+	ret = regmap_write(regmap, AO_SCTRL_SC_PW_RSTDIS0, BIT(idx));
+	if (ret)
+		return ret;
+
+	ret = regmap_write(regmap, AO_SCTRL_SC_PW_ISODIS0, BIT(idx));
+	if (ret)
+		return ret;
+
+	ret = regmap_write(regmap, AO_SCTRL_SC_PW_CLKEN0, BIT(idx));
+	return ret;
+}
+
+static const struct reset_control_ops hi6220_ao_reset_ops = {
+	.assert = hi6220_ao_assert,
+	.deassert = hi6220_ao_deassert,
+};
+
 static int hi6220_reset_probe(struct platform_device *pdev)
 {
 	struct device_node *np = pdev->dev.of_node;
@@ -117,9 +177,12 @@ static int hi6220_reset_probe(struct platform_device *pdev)
 	if (type == MEDIA) {
 		data->rc_dev.ops = &hi6220_media_reset_ops;
 		data->rc_dev.nr_resets = MEDIA_MAX_INDEX;
-	} else {
+	} else if (type == PERIPHERAL) {
 		data->rc_dev.ops = &hi6220_peripheral_reset_ops;
 		data->rc_dev.nr_resets = PERIPH_MAX_INDEX;
+	} else {
+		data->rc_dev.ops = &hi6220_ao_reset_ops;
+		data->rc_dev.nr_resets = AO_MAX_INDEX;
 	}
 
 	return reset_controller_register(&data->rc_dev);
@@ -134,6 +197,10 @@ static const struct of_device_id hi6220_reset_match[] = {
 		.compatible = "hisilicon,hi6220-mediactrl",
 		.data = (void *)MEDIA,
 	},
+	{
+		.compatible = "hisilicon,hi6220-aoctrl",
+		.data = (void *)AO,
+	},
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, hi6220_reset_match);
diff --git a/drivers/reset/reset-imx7.c b/drivers/reset/reset-imx7.c
index 1443a55a0c29..d170fe663210 100644
--- a/drivers/reset/reset-imx7.c
+++ b/drivers/reset/reset-imx7.c
@@ -15,6 +15,7 @@
 #include <linux/regmap.h>
 #include <dt-bindings/reset/imx7-reset.h>
 #include <dt-bindings/reset/imx8mq-reset.h>
+#include <dt-bindings/reset/imx8mp-reset.h>
 
 struct imx7_src_signal {
 	unsigned int offset, bit;
@@ -145,6 +146,18 @@ enum imx8mq_src_registers {
 	SRC_DDRC2_RCR		= 0x1004,
 };
 
+enum imx8mp_src_registers {
+	SRC_SUPERMIX_RCR	= 0x0018,
+	SRC_AUDIOMIX_RCR	= 0x001c,
+	SRC_MLMIX_RCR		= 0x0028,
+	SRC_GPU2D_RCR		= 0x0038,
+	SRC_GPU3D_RCR		= 0x003c,
+	SRC_VPU_G1_RCR		= 0x0048,
+	SRC_VPU_G2_RCR		= 0x004c,
+	SRC_VPUVC8KE_RCR	= 0x0050,
+	SRC_NOC_RCR		= 0x0054,
+};
+
 static const struct imx7_src_signal imx8mq_src_signals[IMX8MQ_RESET_NUM] = {
 	[IMX8MQ_RESET_A53_CORE_POR_RESET0]	= { SRC_A53RCR0, BIT(0) },
 	[IMX8MQ_RESET_A53_CORE_POR_RESET1]	= { SRC_A53RCR0, BIT(1) },
@@ -253,6 +266,93 @@ static const struct imx7_src_variant variant_imx8mq = {
 	},
 };
 
+static const struct imx7_src_signal imx8mp_src_signals[IMX8MP_RESET_NUM] = {
+	[IMX8MP_RESET_A53_CORE_POR_RESET0]	= { SRC_A53RCR0, BIT(0) },
+	[IMX8MP_RESET_A53_CORE_POR_RESET1]	= { SRC_A53RCR0, BIT(1) },
+	[IMX8MP_RESET_A53_CORE_POR_RESET2]	= { SRC_A53RCR0, BIT(2) },
+	[IMX8MP_RESET_A53_CORE_POR_RESET3]	= { SRC_A53RCR0, BIT(3) },
+	[IMX8MP_RESET_A53_CORE_RESET0]		= { SRC_A53RCR0, BIT(4) },
+	[IMX8MP_RESET_A53_CORE_RESET1]		= { SRC_A53RCR0, BIT(5) },
+	[IMX8MP_RESET_A53_CORE_RESET2]		= { SRC_A53RCR0, BIT(6) },
+	[IMX8MP_RESET_A53_CORE_RESET3]		= { SRC_A53RCR0, BIT(7) },
+	[IMX8MP_RESET_A53_DBG_RESET0]		= { SRC_A53RCR0, BIT(8) },
+	[IMX8MP_RESET_A53_DBG_RESET1]		= { SRC_A53RCR0, BIT(9) },
+	[IMX8MP_RESET_A53_DBG_RESET2]		= { SRC_A53RCR0, BIT(10) },
+	[IMX8MP_RESET_A53_DBG_RESET3]		= { SRC_A53RCR0, BIT(11) },
+	[IMX8MP_RESET_A53_ETM_RESET0]		= { SRC_A53RCR0, BIT(12) },
+	[IMX8MP_RESET_A53_ETM_RESET1]		= { SRC_A53RCR0, BIT(13) },
+	[IMX8MP_RESET_A53_ETM_RESET2]		= { SRC_A53RCR0, BIT(14) },
+	[IMX8MP_RESET_A53_ETM_RESET3]		= { SRC_A53RCR0, BIT(15) },
+	[IMX8MP_RESET_A53_SOC_DBG_RESET]	= { SRC_A53RCR0, BIT(20) },
+	[IMX8MP_RESET_A53_L2RESET]		= { SRC_A53RCR0, BIT(21) },
+	[IMX8MP_RESET_SW_NON_SCLR_M7C_RST]	= { SRC_M4RCR, BIT(0) },
+	[IMX8MP_RESET_OTG1_PHY_RESET]		= { SRC_USBOPHY1_RCR, BIT(0) },
+	[IMX8MP_RESET_OTG2_PHY_RESET]		= { SRC_USBOPHY2_RCR, BIT(0) },
+	[IMX8MP_RESET_SUPERMIX_RESET]		= { SRC_SUPERMIX_RCR, BIT(0) },
+	[IMX8MP_RESET_AUDIOMIX_RESET]		= { SRC_AUDIOMIX_RCR, BIT(0) },
+	[IMX8MP_RESET_MLMIX_RESET]		= { SRC_MLMIX_RCR, BIT(0) },
+	[IMX8MP_RESET_PCIEPHY]			= { SRC_PCIEPHY_RCR, BIT(2) },
+	[IMX8MP_RESET_PCIEPHY_PERST]		= { SRC_PCIEPHY_RCR, BIT(3) },
+	[IMX8MP_RESET_PCIE_CTRL_APPS_EN]	= { SRC_PCIEPHY_RCR, BIT(6) },
+	[IMX8MP_RESET_PCIE_CTRL_APPS_TURNOFF]	= { SRC_PCIEPHY_RCR, BIT(11) },
+	[IMX8MP_RESET_HDMI_PHY_APB_RESET]	= { SRC_HDMI_RCR, BIT(0) },
+	[IMX8MP_RESET_MEDIA_RESET]		= { SRC_DISP_RCR, BIT(0) },
+	[IMX8MP_RESET_GPU2D_RESET]		= { SRC_GPU2D_RCR, BIT(0) },
+	[IMX8MP_RESET_GPU3D_RESET]		= { SRC_GPU3D_RCR, BIT(0) },
+	[IMX8MP_RESET_GPU_RESET]		= { SRC_GPU_RCR, BIT(0) },
+	[IMX8MP_RESET_VPU_RESET]		= { SRC_VPU_RCR, BIT(0) },
+	[IMX8MP_RESET_VPU_G1_RESET]		= { SRC_VPU_G1_RCR, BIT(0) },
+	[IMX8MP_RESET_VPU_G2_RESET]		= { SRC_VPU_G2_RCR, BIT(0) },
+	[IMX8MP_RESET_VPUVC8KE_RESET]		= { SRC_VPUVC8KE_RCR, BIT(0) },
+	[IMX8MP_RESET_NOC_RESET]		= { SRC_NOC_RCR, BIT(0) },
+};
+
+static int imx8mp_reset_set(struct reset_controller_dev *rcdev,
+			    unsigned long id, bool assert)
+{
+	struct imx7_src *imx7src = to_imx7_src(rcdev);
+	const unsigned int bit = imx7src->signals[id].bit;
+	unsigned int value = assert ? bit : 0;
+
+	switch (id) {
+	case IMX8MP_RESET_PCIEPHY:
+		/*
+		 * wait for more than 10us to release phy g_rst and
+		 * btnrst
+		 */
+		if (!assert)
+			udelay(10);
+		break;
+
+	case IMX8MP_RESET_PCIE_CTRL_APPS_EN:
+		value = assert ? 0 : bit;
+		break;
+	}
+
+	return imx7_reset_update(imx7src, id, value);
+}
+
+static int imx8mp_reset_assert(struct reset_controller_dev *rcdev,
+			       unsigned long id)
+{
+	return imx8mp_reset_set(rcdev, id, true);
+}
+
+static int imx8mp_reset_deassert(struct reset_controller_dev *rcdev,
+				 unsigned long id)
+{
+	return imx8mp_reset_set(rcdev, id, false);
+}
+
+static const struct imx7_src_variant variant_imx8mp = {
+	.signals = imx8mp_src_signals,
+	.signals_num = ARRAY_SIZE(imx8mp_src_signals),
+	.ops = {
+		.assert   = imx8mp_reset_assert,
+		.deassert = imx8mp_reset_deassert,
+	},
+};
+
 static int imx7_reset_probe(struct platform_device *pdev)
 {
 	struct imx7_src *imx7src;
@@ -283,6 +383,7 @@ static int imx7_reset_probe(struct platform_device *pdev)
 static const struct of_device_id imx7_reset_dt_ids[] = {
 	{ .compatible = "fsl,imx7d-src", .data = &variant_imx7 },
 	{ .compatible = "fsl,imx8mq-src", .data = &variant_imx8mq },
+	{ .compatible = "fsl,imx8mp-src", .data = &variant_imx8mp },
 	{ /* sentinel */ },
 };
 
diff --git a/drivers/rpmsg/mtk_rpmsg.c b/drivers/rpmsg/mtk_rpmsg.c
index 232aa4e40133..83f2b8804ee9 100644
--- a/drivers/rpmsg/mtk_rpmsg.c
+++ b/drivers/rpmsg/mtk_rpmsg.c
@@ -8,6 +8,7 @@
 #include <linux/platform_device.h>
 #include <linux/remoteproc.h>
 #include <linux/rpmsg/mtk_rpmsg.h>
+#include <linux/slab.h>
 #include <linux/workqueue.h>
 
 #include "rpmsg_internal.h"
diff --git a/drivers/rpmsg/rpmsg_core.c b/drivers/rpmsg/rpmsg_core.c
index e330ec4dfc33..a6361cad608b 100644
--- a/drivers/rpmsg/rpmsg_core.c
+++ b/drivers/rpmsg/rpmsg_core.c
@@ -284,7 +284,7 @@ int rpmsg_trysend_offchannel(struct rpmsg_endpoint *ept, u32 src, u32 dst,
 EXPORT_SYMBOL(rpmsg_trysend_offchannel);
 
 /*
- * match an rpmsg channel with a channel info struct.
+ * match a rpmsg channel with a channel info struct.
  * this is used to make sure we're not creating rpmsg devices for channels
  * that already exist.
  */
diff --git a/drivers/rtc/rtc-fsl-ftm-alarm.c b/drivers/rtc/rtc-fsl-ftm-alarm.c
index 756af62b0486..23c811da4801 100644
--- a/drivers/rtc/rtc-fsl-ftm-alarm.c
+++ b/drivers/rtc/rtc-fsl-ftm-alarm.c
@@ -268,10 +268,8 @@ static int ftm_rtc_probe(struct platform_device *pdev)
 	}
 
 	irq = platform_get_irq(pdev, 0);
-	if (irq < 0) {
-		dev_err(&pdev->dev, "can't get irq number\n");
+	if (irq < 0)
 		return irq;
-	}
 
 	ret = devm_request_irq(&pdev->dev, irq, ftm_rtc_alarm_interrupt,
 			       IRQF_NO_SUSPEND, dev_name(&pdev->dev), rtc);
diff --git a/drivers/rtc/rtc-lpc24xx.c b/drivers/rtc/rtc-lpc24xx.c
index 00ef16ba9480..eec881a81067 100644
--- a/drivers/rtc/rtc-lpc24xx.c
+++ b/drivers/rtc/rtc-lpc24xx.c
@@ -205,10 +205,8 @@ static int lpc24xx_rtc_probe(struct platform_device *pdev)
 		return PTR_ERR(rtc->rtc_base);
 
 	irq = platform_get_irq(pdev, 0);
-	if (irq < 0) {
-		dev_warn(&pdev->dev, "can't get interrupt resource\n");
+	if (irq < 0)
 		return irq;
-	}
 
 	rtc->clk_rtc = devm_clk_get(&pdev->dev, "rtc");
 	if (IS_ERR(rtc->clk_rtc)) {
diff --git a/drivers/rtc/rtc-mt2712.c b/drivers/rtc/rtc-mt2712.c
index 581b8731fb8a..f6bdbabd7202 100644
--- a/drivers/rtc/rtc-mt2712.c
+++ b/drivers/rtc/rtc-mt2712.c
@@ -328,10 +328,8 @@ static int mt2712_rtc_probe(struct platform_device *pdev)
 	mt2712_rtc_hw_init(mt2712_rtc);
 
 	mt2712_rtc->irq = platform_get_irq(pdev, 0);
-	if (mt2712_rtc->irq < 0) {
-		dev_err(&pdev->dev, "No IRQ resource\n");
+	if (mt2712_rtc->irq < 0)
 		return mt2712_rtc->irq;
-	}
 
 	platform_set_drvdata(pdev, mt2712_rtc);
 
diff --git a/drivers/rtc/rtc-rc5t619.c b/drivers/rtc/rtc-rc5t619.c
index 24e386ecbc7e..dd1a20977478 100644
--- a/drivers/rtc/rtc-rc5t619.c
+++ b/drivers/rtc/rtc-rc5t619.c
@@ -356,10 +356,8 @@ static int rc5t619_rtc_probe(struct platform_device *pdev)
 	int err;
 
 	rtc = devm_kzalloc(dev, sizeof(*rtc), GFP_KERNEL);
-	if (IS_ERR(rtc)) {
-		err = PTR_ERR(rtc);
+	if (!rtc)
 		return -ENOMEM;
-	}
 
 	rtc->rn5t618 = rn5t618;
 
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 17feff174f57..2017c43dac1b 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -127,7 +127,7 @@ config CHR_DEV_SG
 
 	  For scanners, look at SANE (<http://www.sane-project.org/>). For CD
 	  writer software look at Cdrtools
-	  (<http://cdrecord.berlios.de/private/cdrecord.html>)
+	  (<http://cdrtools.sourceforge.net/>)
 	  and for burning a "disk at once": CDRDAO
 	  (<http://cdrdao.sourceforge.net/>). Cdparanoia is a high
 	  quality digital reader of audio CDs (<http://www.xiph.org/paranoia/>).
diff --git a/drivers/scsi/bfa/bfa_core.c b/drivers/scsi/bfa/bfa_core.c
index 0f554ebb8f2c..fb4c469bd89f 100644
--- a/drivers/scsi/bfa/bfa_core.c
+++ b/drivers/scsi/bfa/bfa_core.c
@@ -708,7 +708,7 @@ bfa_reqq_resume(struct bfa_s *bfa, int qid)
 	}
 }
 
-bfa_boolean_t
+static bfa_boolean_t
 bfa_isr_rspq(struct bfa_s *bfa, int qid)
 {
 	struct bfi_msg_s *m;
diff --git a/drivers/scsi/bfa/bfa_fcpim.c b/drivers/scsi/bfa/bfa_fcpim.c
index 284baa3b0c8e..766f2b5ed2ab 100644
--- a/drivers/scsi/bfa/bfa_fcpim.c
+++ b/drivers/scsi/bfa/bfa_fcpim.c
@@ -436,7 +436,7 @@ bfa_fcpim_port_iostats(struct bfa_s *bfa,
 	return BFA_STATUS_OK;
 }
 
-void
+static void
 bfa_ioim_profile_comp(struct bfa_ioim_s *ioim)
 {
 	struct bfa_itnim_latency_s *io_lat =
@@ -453,7 +453,7 @@ bfa_ioim_profile_comp(struct bfa_ioim_s *ioim)
 	io_lat->avg[idx] += val;
 }
 
-void
+static void
 bfa_ioim_profile_start(struct bfa_ioim_s *ioim)
 {
 	ioim->start_time = jiffies;
diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c
index 7c3eadc58b98..e09bf0729deb 100644
--- a/drivers/scsi/bfa/bfa_fcs_lport.c
+++ b/drivers/scsi/bfa/bfa_fcs_lport.c
@@ -1283,7 +1283,7 @@ bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s *port)
 	n2n_port->reply_oxid = 0;
 }
 
-void
+static void
 bfa_fcport_get_loop_attr(struct bfa_fcs_lport_s *port)
 {
 	int i = 0, j = 0, bit = 0, alpa_bit = 0;
diff --git a/drivers/scsi/bfa/bfa_ioc_ct.c b/drivers/scsi/bfa/bfa_ioc_ct.c
index 18b58b2f304f..6fd3383ee538 100644
--- a/drivers/scsi/bfa/bfa_ioc_ct.c
+++ b/drivers/scsi/bfa/bfa_ioc_ct.c
@@ -364,7 +364,7 @@ bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix)
 	writel(r32, rb + FNC_PERS_REG);
 }
 
-bfa_boolean_t
+static bfa_boolean_t
 bfa_ioc_ct2_lpu_read_stat(struct bfa_ioc_s *ioc)
 {
 	u32	r32;
@@ -744,7 +744,7 @@ bfa_ioc_ct2_mem_init(void __iomem *rb)
 	writel(0, (rb + CT2_MBIST_CTL_REG));
 }
 
-void
+static void
 bfa_ioc_ct2_mac_reset(void __iomem *rb)
 {
 	/* put port0, port1 MAC & AHB in reset */
diff --git a/drivers/scsi/bfa/bfa_svc.c b/drivers/scsi/bfa/bfa_svc.c
index 6d2131441f0a..d8a9e40fa257 100644
--- a/drivers/scsi/bfa/bfa_svc.c
+++ b/drivers/scsi/bfa/bfa_svc.c
@@ -4284,7 +4284,7 @@ bfa_fcport_dportdisable(struct bfa_s *bfa)
 	bfa_port_set_dportenabled(&bfa->modules.port, BFA_FALSE);
 }
 
-void
+static void
 bfa_fcport_ddportenable(struct bfa_s *bfa)
 {
 	/*
@@ -4293,7 +4293,7 @@ bfa_fcport_ddportenable(struct bfa_s *bfa)
 	bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DDPORTENABLE);
 }
 
-void
+static void
 bfa_fcport_ddportdisable(struct bfa_s *bfa)
 {
 	/*
diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c
index eb0c76338295..bc5d84f87d8f 100644
--- a/drivers/scsi/bfa/bfad.c
+++ b/drivers/scsi/bfa/bfad.c
@@ -50,7 +50,7 @@ int		pcie_max_read_reqsz;
 int		bfa_debugfs_enable = 1;
 int		msix_disable_cb = 0, msix_disable_ct = 0;
 int		max_xfer_size = BFAD_MAX_SECTORS >> 1;
-int		max_rport_logins = BFA_FCS_MAX_RPORT_LOGINS;
+static int	max_rport_logins = BFA_FCS_MAX_RPORT_LOGINS;
 
 /* Firmware releated */
 u32	bfi_image_cb_size, bfi_image_ct_size, bfi_image_ct2_size;
diff --git a/drivers/scsi/bfa/bfad_attr.c b/drivers/scsi/bfa/bfad_attr.c
index fbfce02e5b93..5ae1e3f78910 100644
--- a/drivers/scsi/bfa/bfad_attr.c
+++ b/drivers/scsi/bfa/bfad_attr.c
@@ -437,7 +437,7 @@ bfad_im_vport_create(struct fc_vport *fc_vport, bool disable)
 	return status;
 }
 
-int
+static int
 bfad_im_issue_fc_host_lip(struct Scsi_Host *shost)
 {
 	struct bfad_im_port_s *im_port =
@@ -562,7 +562,7 @@ bfad_im_vport_disable(struct fc_vport *fc_vport, bool disable)
 	return 0;
 }
 
-void
+static void
 bfad_im_vport_set_symbolic_name(struct fc_vport *fc_vport)
 {
 	struct bfad_vport_s *vport = (struct bfad_vport_s *)fc_vport->dd_data;
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index fe03410268e6..7f150d52b4a6 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -329,8 +329,8 @@ static void gdth_scsi_done(struct scsi_cmnd *scp)
 		scp->scsi_done(scp);
 }
 
-int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd,
-                   int timeout, u32 *info)
+static int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd,
+			  char *cmnd, int timeout, u32 *info)
 {
     gdth_ha_str *ha = shost_priv(sdev->host);
     struct scsi_cmnd *scp;
diff --git a/drivers/scsi/hisi_sas/Kconfig b/drivers/scsi/hisi_sas/Kconfig
index 90a17452a50d..13ed9073fc72 100644
--- a/drivers/scsi/hisi_sas/Kconfig
+++ b/drivers/scsi/hisi_sas/Kconfig
@@ -6,6 +6,7 @@ config SCSI_HISI_SAS
 	select SCSI_SAS_LIBSAS
 	select BLK_DEV_INTEGRITY
 	depends on ATA
+	select SATA_HOST
 	help
 		This driver supports HiSilicon's SAS HBA, including support based
 		on platform device
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index d48a8fa997b9..0db37b4f7265 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -1164,7 +1164,7 @@ static void ipr_update_ata_class(struct ipr_resource_entry *res, unsigned int pr
 	default:
 		res->ata_class = ATA_DEV_UNKNOWN;
 		break;
-	};
+	}
 }
 
 /**
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
index c5a828a041e0..5d716d388707 100644
--- a/drivers/scsi/libsas/sas_ata.c
+++ b/drivers/scsi/libsas/sas_ata.c
@@ -160,6 +160,7 @@ static void sas_ata_task_done(struct sas_task *task)
 }
 
 static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc)
+	__must_hold(ap->lock)
 {
 	struct sas_task *task;
 	struct scatterlist *sg;
diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c
index 8443f2f35be2..8f918df631bf 100644
--- a/drivers/scsi/megaraid/megaraid_mbox.c
+++ b/drivers/scsi/megaraid/megaraid_mbox.c
@@ -302,8 +302,8 @@ static struct pci_driver megaraid_pci_driver = {
 // definitions for the device attributes for exporting logical drive number
 // for a scsi address (Host, Channel, Id, Lun)
 
-DEVICE_ATTR(megaraid_mbox_app_hndl, S_IRUSR, megaraid_sysfs_show_app_hndl,
-		NULL);
+static DEVICE_ATTR(megaraid_mbox_app_hndl, S_IRUSR, megaraid_sysfs_show_app_hndl,
+		   NULL);
 
 // Host template initializer for megaraid mbox sysfs device attributes
 static struct device_attribute *megaraid_shost_attrs[] = {
@@ -312,7 +312,7 @@ static struct device_attribute *megaraid_shost_attrs[] = {
 };
 
 
-DEVICE_ATTR(megaraid_mbox_ld, S_IRUSR, megaraid_sysfs_show_ldnum, NULL);
+static DEVICE_ATTR(megaraid_mbox_ld, S_IRUSR, megaraid_sysfs_show_ldnum, NULL);
 
 // Host template initializer for megaraid mbox sysfs device attributes
 static struct device_attribute *megaraid_sdev_attrs[] = {
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index babe85d7b537..fb9c3ceed508 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -81,7 +81,7 @@ int smp_affinity_enable = 1;
 module_param(smp_affinity_enable, int, 0444);
 MODULE_PARM_DESC(smp_affinity_enable, "SMP affinity feature enable/disable Default: enable(1)");
 
-int rdpq_enable = 1;
+static int rdpq_enable = 1;
 module_param(rdpq_enable, int, 0444);
 MODULE_PARM_DESC(rdpq_enable, "Allocate reply queue in chunks for large queue depth enable/disable Default: enable(1)");
 
@@ -89,7 +89,7 @@ unsigned int dual_qdepth_disable;
 module_param(dual_qdepth_disable, int, 0444);
 MODULE_PARM_DESC(dual_qdepth_disable, "Disable dual queue depth feature. Default: 0");
 
-unsigned int scmd_timeout = MEGASAS_DEFAULT_CMD_TIMEOUT;
+static unsigned int scmd_timeout = MEGASAS_DEFAULT_CMD_TIMEOUT;
 module_param(scmd_timeout, int, 0444);
 MODULE_PARM_DESC(scmd_timeout, "scsi command timeout (10-90s), default 90s. See megasas_reset_timer.");
 
diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c
index 89c3685f5163..3b3d04d7671f 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fp.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fp.c
@@ -85,7 +85,7 @@ u32 mega_mod64(u64 dividend, u32 divisor)
  *
  * @return quotient
  **/
-u64 mega_div64_32(uint64_t dividend, uint32_t divisor)
+static u64 mega_div64_32(uint64_t dividend, uint32_t divisor)
 {
 	u32 remainder;
 	u64 d;
@@ -367,7 +367,7 @@ u8 MR_ValidateMapInfo(struct megasas_instance *instance, u64 map_id)
 	return 1;
 }
 
-u32 MR_GetSpanBlock(u32 ld, u64 row, u64 *span_blk,
+static u32 MR_GetSpanBlock(u32 ld, u64 row, u64 *span_blk,
 		    struct MR_DRV_RAID_MAP_ALL *map)
 {
 	struct MR_SPAN_BLOCK_INFO *pSpanBlock = MR_LdSpanInfoGet(ld, map);
@@ -417,7 +417,7 @@ u32 MR_GetSpanBlock(u32 ld, u64 row, u64 *span_blk,
 *    div_error	   - Devide error code.
 */
 
-u32 mr_spanset_get_span_block(struct megasas_instance *instance,
+static u32 mr_spanset_get_span_block(struct megasas_instance *instance,
 		u32 ld, u64 row, u64 *span_blk, struct MR_DRV_RAID_MAP_ALL *map)
 {
 	struct fusion_context *fusion = instance->ctrl_context;
@@ -642,7 +642,7 @@ static u32 get_arm_from_strip(struct megasas_instance *instance,
 }
 
 /* This Function will return Phys arm */
-u8 get_arm(struct megasas_instance *instance, u32 ld, u8 span, u64 stripe,
+static u8 get_arm(struct megasas_instance *instance, u32 ld, u8 span, u64 stripe,
 		struct MR_DRV_RAID_MAP_ALL *map)
 {
 	struct MR_LD_RAID  *raid = MR_LdRaidGet(ld, map);
@@ -785,7 +785,7 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld,
 *    span          - Span number
 *    block         - Absolute Block number in the physical disk
 */
-u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow,
+static u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow,
 		u16 stripRef, struct IO_REQUEST_INFO *io_info,
 		struct RAID_CONTEXT *pRAID_Context,
 		struct MR_DRV_RAID_MAP_ALL *map)
@@ -1342,7 +1342,7 @@ void mr_update_load_balance_params(struct MR_DRV_RAID_MAP_ALL *drv_map,
 	}
 }
 
-u8 megasas_get_best_arm_pd(struct megasas_instance *instance,
+static u8 megasas_get_best_arm_pd(struct megasas_instance *instance,
 			   struct LD_LOAD_BALANCE_INFO *lbInfo,
 			   struct IO_REQUEST_INFO *io_info,
 			   struct MR_DRV_RAID_MAP_ALL *drv_map)
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index b2ad96564484..bec3d4cca74f 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -176,7 +176,7 @@ static inline bool megasas_check_same_4gb_region
  * megasas_enable_intr_fusion -	Enables interrupts
  * @regs:			MFI register set
  */
-void
+static void
 megasas_enable_intr_fusion(struct megasas_instance *instance)
 {
 	struct megasas_register_set __iomem *regs;
@@ -198,7 +198,7 @@ megasas_enable_intr_fusion(struct megasas_instance *instance)
  * megasas_disable_intr_fusion - Disables interrupt
  * @regs:			 MFI register set
  */
-void
+static void
 megasas_disable_intr_fusion(struct megasas_instance *instance)
 {
 	u32 mask = 0xFFFFFFFF;
@@ -4230,7 +4230,7 @@ void  megasas_reset_reply_desc(struct megasas_instance *instance)
  * megasas_refire_mgmt_cmd :	Re-fire management commands
  * @instance:				Controller's soft instance
 */
-void megasas_refire_mgmt_cmd(struct megasas_instance *instance,
+static void megasas_refire_mgmt_cmd(struct megasas_instance *instance,
 			     bool return_ioctl)
 {
 	int j;
diff --git a/drivers/scsi/qedf/qedf_els.c b/drivers/scsi/qedf/qedf_els.c
index 87e169dcebdb..542ba9454257 100644
--- a/drivers/scsi/qedf/qedf_els.c
+++ b/drivers/scsi/qedf/qedf_els.c
@@ -388,14 +388,10 @@ void qedf_restart_rport(struct qedf_rport *fcport)
 		mutex_lock(&lport->disc.disc_mutex);
 		/* Recreate the rport and log back in */
 		rdata = fc_rport_create(lport, port_id);
-		if (rdata) {
-			mutex_unlock(&lport->disc.disc_mutex);
+		mutex_unlock(&lport->disc.disc_mutex);
+		if (rdata)
 			fc_rport_login(rdata);
-			fcport->rdata = rdata;
-		} else {
-			mutex_unlock(&lport->disc.disc_mutex);
-			fcport->rdata = NULL;
-		}
+		fcport->rdata = rdata;
 	}
 	clear_bit(QEDF_RPORT_IN_RESET, &fcport->flags);
 }
diff --git a/drivers/scsi/qedi/qedi_iscsi.c b/drivers/scsi/qedi/qedi_iscsi.c
index 1f4a5fb00a05..b867a143d263 100644
--- a/drivers/scsi/qedi/qedi_iscsi.c
+++ b/drivers/scsi/qedi/qedi_iscsi.c
@@ -836,6 +836,11 @@ qedi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr,
 		return ERR_PTR(ret);
 	}
 
+	if (atomic_read(&qedi->link_state) != QEDI_LINK_UP) {
+		QEDI_WARN(&qedi->dbg_ctx, "qedi link down\n");
+		return ERR_PTR(-ENXIO);
+	}
+
 	ep = iscsi_create_endpoint(sizeof(struct qedi_endpoint));
 	if (!ep) {
 		QEDI_ERR(&qedi->dbg_ctx, "endpoint create fail\n");
@@ -870,12 +875,6 @@ qedi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr,
 		QEDI_ERR(&qedi->dbg_ctx, "Invalid endpoint\n");
 	}
 
-	if (atomic_read(&qedi->link_state) != QEDI_LINK_UP) {
-		QEDI_WARN(&qedi->dbg_ctx, "qedi link down\n");
-		ret = -ENXIO;
-		goto ep_conn_exit;
-	}
-
 	ret = qedi_alloc_sq(qedi, qedi_ep);
 	if (ret)
 		goto ep_conn_exit;
@@ -1001,7 +1000,8 @@ static void qedi_ep_disconnect(struct iscsi_endpoint *ep)
 	if (qedi_ep->state == EP_STATE_OFLDCONN_START)
 		goto ep_exit_recover;
 
-	flush_work(&qedi_ep->offload_work);
+	if (qedi_ep->state != EP_STATE_OFLDCONN_NONE)
+		flush_work(&qedi_ep->offload_work);
 
 	if (qedi_ep->conn) {
 		qedi_conn = qedi_ep->conn;
@@ -1065,6 +1065,9 @@ static void qedi_ep_disconnect(struct iscsi_endpoint *ep)
 		break;
 	}
 
+	if (!abrt_conn)
+		wait_delay += qedi->pf_params.iscsi_pf_params.two_msl_timer;
+
 	qedi_ep->state = EP_STATE_DISCONN_START;
 	ret = qedi_ops->destroy_conn(qedi->cdev, qedi_ep->handle, abrt_conn);
 	if (ret) {
diff --git a/drivers/scsi/qedi/qedi_main.c b/drivers/scsi/qedi/qedi_main.c
index b995b19865ca..b9a5c842a76e 100644
--- a/drivers/scsi/qedi/qedi_main.c
+++ b/drivers/scsi/qedi/qedi_main.c
@@ -28,6 +28,10 @@
 #include "qedi_gbl.h"
 #include "qedi_iscsi.h"
 
+static uint qedi_qed_debug;
+module_param(qedi_qed_debug, uint, 0644);
+MODULE_PARM_DESC(qedi_qed_debug, " QED debug level 0 (default)");
+
 static uint qedi_fw_debug;
 module_param(qedi_fw_debug, uint, 0644);
 MODULE_PARM_DESC(qedi_fw_debug, " Firmware debug level 0(default) to 3");
@@ -921,7 +925,7 @@ static void qedi_get_boot_tgt_info(struct nvm_iscsi_block *block,
 	ipv6_en = !!(block->generic.ctrl_flags &
 		     NVM_ISCSI_CFG_GEN_IPV6_ENABLED);
 
-	snprintf(tgt->iscsi_name, sizeof(tgt->iscsi_name), "%s\n",
+	snprintf(tgt->iscsi_name, sizeof(tgt->iscsi_name), "%s",
 		 block->target[index].target_name.byte);
 
 	tgt->ipv6_en = ipv6_en;
@@ -1360,7 +1364,7 @@ static int qedi_request_msix_irq(struct qedi_ctx *qedi)
 	u16 idx;
 
 	cpu = cpumask_first(cpu_online_mask);
-	for (i = 0; i < MIN_NUM_CPUS_MSIX(qedi); i++) {
+	for (i = 0; i < qedi->int_info.msix_cnt; i++) {
 		idx = i * qedi->dev_info.common.num_hwfns +
 			  qedi_ops->common->get_affin_hwfn_idx(qedi->cdev);
 
@@ -2422,7 +2426,6 @@ static int __qedi_probe(struct pci_dev *pdev, int mode)
 {
 	struct qedi_ctx *qedi;
 	struct qed_ll2_params params;
-	u32 dp_module = 0;
 	u8 dp_level = 0;
 	bool is_vf = false;
 	char host_buf[16];
@@ -2445,7 +2448,7 @@ static int __qedi_probe(struct pci_dev *pdev, int mode)
 
 	memset(&qed_params, 0, sizeof(qed_params));
 	qed_params.protocol = QED_PROTOCOL_ISCSI;
-	qed_params.dp_module = dp_module;
+	qed_params.dp_module = qedi_qed_debug;
 	qed_params.dp_level = dp_level;
 	qed_params.is_vf = is_vf;
 	qedi->cdev = qedi_ops->common->probe(pdev, &qed_params);
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
index 3337cd341d21..441a45349349 100644
--- a/drivers/scsi/qla1280.c
+++ b/drivers/scsi/qla1280.c
@@ -526,7 +526,7 @@ static struct pci_device_id qla1280_pci_tbl[] = {
 };
 MODULE_DEVICE_TABLE(pci, qla1280_pci_tbl);
 
-DEFINE_MUTEX(qla1280_firmware_mutex);
+static DEFINE_MUTEX(qla1280_firmware_mutex);
 
 struct qla_fw {
 	char *fwname;
@@ -535,7 +535,7 @@ struct qla_fw {
 
 #define QL_NUM_FW_IMAGES 3
 
-struct qla_fw qla1280_fw_tbl[QL_NUM_FW_IMAGES] = {
+static struct qla_fw qla1280_fw_tbl[QL_NUM_FW_IMAGES] = {
 	{"qlogic/1040.bin",  NULL},	/* image 0 */
 	{"qlogic/1280.bin",  NULL},	/* image 1 */
 	{"qlogic/12160.bin", NULL},	/* image 2 */
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index f301a8048b2f..b23f6f621f74 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -778,16 +778,16 @@ qla2300_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
 
 	if (rval == QLA_SUCCESS) {
 		dmp_reg = &reg->flash_address;
-		for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++, dmp_reg++)
+		for (cnt = 0; cnt < ARRAY_SIZE(fw->pbiu_reg); cnt++, dmp_reg++)
 			fw->pbiu_reg[cnt] = htons(RD_REG_WORD(dmp_reg));
 
 		dmp_reg = &reg->u.isp2300.req_q_in;
-		for (cnt = 0; cnt < sizeof(fw->risc_host_reg) / 2;
+		for (cnt = 0; cnt < ARRAY_SIZE(fw->risc_host_reg);
 		    cnt++, dmp_reg++)
 			fw->risc_host_reg[cnt] = htons(RD_REG_WORD(dmp_reg));
 
 		dmp_reg = &reg->u.isp2300.mailbox0;
-		for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2;
+		for (cnt = 0; cnt < ARRAY_SIZE(fw->mailbox_reg);
 		    cnt++, dmp_reg++)
 			fw->mailbox_reg[cnt] = htons(RD_REG_WORD(dmp_reg));
 
@@ -799,7 +799,7 @@ qla2300_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
 
 		WRT_REG_WORD(&reg->ctrl_status, 0x00);
 		dmp_reg = &reg->risc_hw;
-		for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2;
+		for (cnt = 0; cnt < ARRAY_SIZE(fw->risc_hdw_reg);
 		    cnt++, dmp_reg++)
 			fw->risc_hdw_reg[cnt] = htons(RD_REG_WORD(dmp_reg));
 
@@ -860,12 +860,12 @@ qla2300_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
 	/* Get RISC SRAM. */
 	if (rval == QLA_SUCCESS)
 		rval = qla2xxx_dump_ram(ha, 0x800, fw->risc_ram,
-		    sizeof(fw->risc_ram) / 2, &nxt);
+					ARRAY_SIZE(fw->risc_ram), &nxt);
 
 	/* Get stack SRAM. */
 	if (rval == QLA_SUCCESS)
 		rval = qla2xxx_dump_ram(ha, 0x10000, fw->stack_ram,
-		    sizeof(fw->stack_ram) / 2, &nxt);
+					ARRAY_SIZE(fw->stack_ram), &nxt);
 
 	/* Get data SRAM. */
 	if (rval == QLA_SUCCESS)
@@ -944,7 +944,7 @@ qla2100_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
 	}
 	if (rval == QLA_SUCCESS) {
 		dmp_reg = &reg->flash_address;
-		for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++, dmp_reg++)
+		for (cnt = 0; cnt < ARRAY_SIZE(fw->pbiu_reg); cnt++, dmp_reg++)
 			fw->pbiu_reg[cnt] = htons(RD_REG_WORD(dmp_reg));
 
 		dmp_reg = &reg->u.isp2100.mailbox0;
@@ -956,12 +956,12 @@ qla2100_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
 		}
 
 		dmp_reg = &reg->u.isp2100.unused_2[0];
-		for (cnt = 0; cnt < sizeof(fw->dma_reg) / 2; cnt++, dmp_reg++)
+		for (cnt = 0; cnt < ARRAY_SIZE(fw->dma_reg); cnt++, dmp_reg++)
 			fw->dma_reg[cnt] = htons(RD_REG_WORD(dmp_reg));
 
 		WRT_REG_WORD(&reg->ctrl_status, 0x00);
 		dmp_reg = &reg->risc_hw;
-		for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++, dmp_reg++)
+		for (cnt = 0; cnt < ARRAY_SIZE(fw->risc_hdw_reg); cnt++, dmp_reg++)
 			fw->risc_hdw_reg[cnt] = htons(RD_REG_WORD(dmp_reg));
 
 		WRT_REG_WORD(&reg->pcr, 0x2000);
@@ -1041,7 +1041,7 @@ qla2100_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
  		WRT_MAILBOX_REG(ha, reg, 0, MBC_READ_RAM_WORD);
 		clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
 	}
-	for (cnt = 0; cnt < sizeof(fw->risc_ram) / 2 && rval == QLA_SUCCESS;
+	for (cnt = 0; cnt < ARRAY_SIZE(fw->risc_ram) && rval == QLA_SUCCESS;
 	    cnt++, risc_address++) {
  		WRT_MAILBOX_REG(ha, reg, 1, risc_address);
 		WRT_REG_WORD(&reg->hccr, HCCR_SET_HOST_INT);
@@ -1145,7 +1145,7 @@ qla24xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
 
 	/* Host interface registers. */
 	dmp_reg = &reg->flash_addr;
-	for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++, dmp_reg++)
+	for (cnt = 0; cnt < ARRAY_SIZE(fw->host_reg); cnt++, dmp_reg++)
 		fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg));
 
 	/* Disable interrupts. */
@@ -1178,7 +1178,7 @@ qla24xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
 
 	/* Mailbox registers. */
 	mbx_reg = &reg->mailbox0;
-	for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++, mbx_reg++)
+	for (cnt = 0; cnt < ARRAY_SIZE(fw->mailbox_reg); cnt++, mbx_reg++)
 		fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg));
 
 	/* Transfer sequence registers. */
@@ -1421,7 +1421,7 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
 
 	/* Host interface registers. */
 	dmp_reg = &reg->flash_addr;
-	for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++, dmp_reg++)
+	for (cnt = 0; cnt < ARRAY_SIZE(fw->host_reg); cnt++, dmp_reg++)
 		fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg));
 
 	/* Disable interrupts. */
@@ -1470,7 +1470,7 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
 
 	/* Mailbox registers. */
 	mbx_reg = &reg->mailbox0;
-	for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++, mbx_reg++)
+	for (cnt = 0; cnt < ARRAY_SIZE(fw->mailbox_reg); cnt++, mbx_reg++)
 		fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg));
 
 	/* Transfer sequence registers. */
@@ -1745,7 +1745,7 @@ qla81xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
 
 	/* Host interface registers. */
 	dmp_reg = &reg->flash_addr;
-	for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++, dmp_reg++)
+	for (cnt = 0; cnt < ARRAY_SIZE(fw->host_reg); cnt++, dmp_reg++)
 		fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg));
 
 	/* Disable interrupts. */
@@ -1794,7 +1794,7 @@ qla81xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
 
 	/* Mailbox registers. */
 	mbx_reg = &reg->mailbox0;
-	for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++, mbx_reg++)
+	for (cnt = 0; cnt < ARRAY_SIZE(fw->mailbox_reg); cnt++, mbx_reg++)
 		fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg));
 
 	/* Transfer sequence registers. */
@@ -2093,7 +2093,7 @@ qla83xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
 
 	/* Host interface registers. */
 	dmp_reg = &reg->flash_addr;
-	for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++, dmp_reg++)
+	for (cnt = 0; cnt < ARRAY_SIZE(fw->host_reg); cnt++, dmp_reg++)
 		fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg));
 
 	/* Disable interrupts. */
@@ -2142,7 +2142,7 @@ qla83xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
 
 	/* Mailbox registers. */
 	mbx_reg = &reg->mailbox0;
-	for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++, mbx_reg++)
+	for (cnt = 0; cnt < ARRAY_SIZE(fw->mailbox_reg); cnt++, mbx_reg++)
 		fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg));
 
 	/* Transfer sequence registers. */
@@ -2539,7 +2539,6 @@ ql_dbg(uint level, scsi_qla_host_t *vha, uint id, const char *fmt, ...)
 {
 	va_list va;
 	struct va_format vaf;
-	char pbuf[64];
 
 	va_start(va, fmt);
 
@@ -2547,6 +2546,8 @@ ql_dbg(uint level, scsi_qla_host_t *vha, uint id, const char *fmt, ...)
 	vaf.va = &va;
 
 	if (!ql_mask_match(level)) {
+		char pbuf[64];
+
 		if (vha != NULL) {
 			const struct pci_dev *pdev = vha->hw->pdev;
 			/* <module-name> <msg-id>:<host> Message */
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 5b2deaa730bf..40bdb4d074d8 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -3611,8 +3611,6 @@ qla24xx_detect_sfp(scsi_qla_host_t *vha)
 			ha->lr_distance = LR_DISTANCE_5K;
 	}
 
-	if (!vha->flags.init_done)
-		rc = QLA_SUCCESS;
 out:
 	ql_dbg(ql_dbg_async, vha, 0x507b,
 	    "SFP detect: %s-Range SFP %s (nvr=%x ll=%x lr=%x lrd=%x).\n",
@@ -5081,6 +5079,54 @@ qla2x00_configure_loop(scsi_qla_host_t *vha)
 	return (rval);
 }
 
+static int qla2x00_configure_n2n_loop(scsi_qla_host_t *vha)
+{
+	struct qla_hw_data *ha = vha->hw;
+	unsigned long flags;
+	fc_port_t *fcport;
+	int rval;
+
+	if (test_and_clear_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags)) {
+		/* borrowing */
+		u32 *bp, sz;
+
+		memset(ha->init_cb, 0, ha->init_cb_size);
+		sz = min_t(int, sizeof(struct els_plogi_payload),
+			   ha->init_cb_size);
+		rval = qla24xx_get_port_login_templ(vha, ha->init_cb_dma,
+						    ha->init_cb, sz);
+		if (rval == QLA_SUCCESS) {
+			__be32 *q = &ha->plogi_els_payld.data[0];
+
+			bp = (uint32_t *)ha->init_cb;
+			cpu_to_be32_array(q, bp, sz / 4);
+			memcpy(bp, q, sizeof(ha->plogi_els_payld.data));
+		} else {
+			ql_dbg(ql_dbg_init, vha, 0x00d1,
+			       "PLOGI ELS param read fail.\n");
+			goto skip_login;
+		}
+	}
+
+	list_for_each_entry(fcport, &vha->vp_fcports, list) {
+		if (fcport->n2n_flag) {
+			qla24xx_fcport_handle_login(vha, fcport);
+			return QLA_SUCCESS;
+		}
+	}
+
+skip_login:
+	spin_lock_irqsave(&vha->work_lock, flags);
+	vha->scan.scan_retry++;
+	spin_unlock_irqrestore(&vha->work_lock, flags);
+
+	if (vha->scan.scan_retry < MAX_SCAN_RETRIES) {
+		set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
+		set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
+	}
+	return QLA_FUNCTION_FAILED;
+}
+
 /*
  * qla2x00_configure_local_loop
  *	Updates Fibre Channel Device Database with local loop devices.
@@ -5098,7 +5144,6 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
 	int		found_devs;
 	int		found;
 	fc_port_t	*fcport, *new_fcport;
-
 	uint16_t	index;
 	uint16_t	entries;
 	struct gid_list_info *gid;
@@ -5108,47 +5153,8 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
 	unsigned long flags;
 
 	/* Inititae N2N login. */
-	if (N2N_TOPO(ha)) {
-		if (test_and_clear_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags)) {
-			/* borrowing */
-			u32 *bp, sz;
-
-			memset(ha->init_cb, 0, ha->init_cb_size);
-			sz = min_t(int, sizeof(struct els_plogi_payload),
-			    ha->init_cb_size);
-			rval = qla24xx_get_port_login_templ(vha,
-			    ha->init_cb_dma, (void *)ha->init_cb, sz);
-			if (rval == QLA_SUCCESS) {
-				__be32 *q = &ha->plogi_els_payld.data[0];
-
-				bp = (uint32_t *)ha->init_cb;
-				cpu_to_be32_array(q, bp, sz / 4);
-
-				memcpy(bp, q, sizeof(ha->plogi_els_payld.data));
-			} else {
-				ql_dbg(ql_dbg_init, vha, 0x00d1,
-				    "PLOGI ELS param read fail.\n");
-				goto skip_login;
-			}
-		}
-
-		list_for_each_entry(fcport, &vha->vp_fcports, list) {
-			if (fcport->n2n_flag) {
-				qla24xx_fcport_handle_login(vha, fcport);
-				return QLA_SUCCESS;
-			}
-		}
-skip_login:
-		spin_lock_irqsave(&vha->work_lock, flags);
-		vha->scan.scan_retry++;
-		spin_unlock_irqrestore(&vha->work_lock, flags);
-
-		if (vha->scan.scan_retry < MAX_SCAN_RETRIES) {
-			set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
-			set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
-		}
-		return QLA_FUNCTION_FAILED;
-	}
+	if (N2N_TOPO(ha))
+		return qla2x00_configure_n2n_loop(vha);
 
 	found_devs = 0;
 	new_fcport = NULL;
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 8d7a905f6247..8a78d395bbc8 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -87,7 +87,6 @@ qla24xx_process_abts(struct scsi_qla_host *vha, void *pkt)
 	}
 
 	/* terminate exchange */
-	memset(rsp_els, 0, sizeof(*rsp_els));
 	rsp_els->entry_type = ELS_IOCB_TYPE;
 	rsp_els->entry_count = 1;
 	rsp_els->nport_handle = ~0;
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 9fd83d1bffe0..4ed90437e8c4 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -4894,8 +4894,6 @@ qla25xx_set_els_cmds_supported(scsi_qla_host_t *vha)
 		return QLA_MEMORY_ALLOC_FAILED;
 	}
 
-	memset(els_cmd_map, 0, ELS_CMD_MAP_SIZE);
-
 	els_cmd_map[index] |= 1 << bit;
 
 	mcp->mb[0] = MBC_SET_RNID_PARAMS;
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 4e6af592f018..20472aaaf630 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -685,8 +685,10 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
 	hp->flags = input_size;	/* structure abuse ... */
 	hp->pack_id = old_hdr.pack_id;
 	hp->usr_ptr = NULL;
-	if (copy_from_user(cmnd, buf, cmd_size))
+	if (copy_from_user(cmnd, buf, cmd_size)) {
+		sg_remove_request(sfp, srp);
 		return -EFAULT;
+	}
 	/*
 	 * SG_DXFER_TO_FROM_DEV is functionally equivalent to SG_DXFER_FROM_DEV,
 	 * but is is possible that the app intended SG_DXFER_TO_DEV, because there
@@ -793,8 +795,10 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp,
 			"sg_common_write:  scsi opcode=0x%02x, cmd_size=%d\n",
 			(int) cmnd[0], (int) hp->cmd_len));
 
-	if (hp->dxfer_len >= SZ_256M)
+	if (hp->dxfer_len >= SZ_256M) {
+		sg_remove_request(sfp, srp);
 		return -EINVAL;
+	}
 
 	k = sg_start_req(srp, cmnd);
 	if (k) {
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index fb41636519ee..a680592b9d32 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -621,6 +621,63 @@ static inline struct storvsc_device *get_in_stor_device(
 
 }
 
+void storvsc_change_target_cpu(struct vmbus_channel *channel, u32 old, u32 new)
+{
+	struct storvsc_device *stor_device;
+	struct vmbus_channel *cur_chn;
+	bool old_is_alloced = false;
+	struct hv_device *device;
+	unsigned long flags;
+	int cpu;
+
+	device = channel->primary_channel ?
+			channel->primary_channel->device_obj
+				: channel->device_obj;
+	stor_device = get_out_stor_device(device);
+	if (!stor_device)
+		return;
+
+	/* See storvsc_do_io() -> get_og_chn(). */
+	spin_lock_irqsave(&device->channel->lock, flags);
+
+	/*
+	 * Determines if the storvsc device has other channels assigned to
+	 * the "old" CPU to update the alloced_cpus mask and the stor_chns
+	 * array.
+	 */
+	if (device->channel != channel && device->channel->target_cpu == old) {
+		cur_chn = device->channel;
+		old_is_alloced = true;
+		goto old_is_alloced;
+	}
+	list_for_each_entry(cur_chn, &device->channel->sc_list, sc_list) {
+		if (cur_chn == channel)
+			continue;
+		if (cur_chn->target_cpu == old) {
+			old_is_alloced = true;
+			goto old_is_alloced;
+		}
+	}
+
+old_is_alloced:
+	if (old_is_alloced)
+		WRITE_ONCE(stor_device->stor_chns[old], cur_chn);
+	else
+		cpumask_clear_cpu(old, &stor_device->alloced_cpus);
+
+	/* "Flush" the stor_chns array. */
+	for_each_possible_cpu(cpu) {
+		if (stor_device->stor_chns[cpu] && !cpumask_test_cpu(
+					cpu, &stor_device->alloced_cpus))
+			WRITE_ONCE(stor_device->stor_chns[cpu], NULL);
+	}
+
+	WRITE_ONCE(stor_device->stor_chns[new], channel);
+	cpumask_set_cpu(new, &stor_device->alloced_cpus);
+
+	spin_unlock_irqrestore(&device->channel->lock, flags);
+}
+
 static void handle_sc_creation(struct vmbus_channel *new_sc)
 {
 	struct hv_device *device = new_sc->primary_channel->device_obj;
@@ -648,6 +705,8 @@ static void handle_sc_creation(struct vmbus_channel *new_sc)
 		return;
 	}
 
+	new_sc->change_target_cpu_callback = storvsc_change_target_cpu;
+
 	/* Add the sub-channel to the array of available channels. */
 	stor_device->stor_chns[new_sc->target_cpu] = new_sc;
 	cpumask_set_cpu(new_sc->target_cpu, &stor_device->alloced_cpus);
@@ -876,6 +935,8 @@ static int storvsc_channel_init(struct hv_device *device, bool is_fc)
 	if (stor_device->stor_chns == NULL)
 		return -ENOMEM;
 
+	device->channel->change_target_cpu_callback = storvsc_change_target_cpu;
+
 	stor_device->stor_chns[device->channel->target_cpu] = device->channel;
 	cpumask_set_cpu(device->channel->target_cpu,
 			&stor_device->alloced_cpus);
@@ -1248,8 +1309,10 @@ static struct vmbus_channel *get_og_chn(struct storvsc_device *stor_device,
 	const struct cpumask *node_mask;
 	int num_channels, tgt_cpu;
 
-	if (stor_device->num_sc == 0)
+	if (stor_device->num_sc == 0) {
+		stor_device->stor_chns[q_num] = stor_device->device->channel;
 		return stor_device->device->channel;
+	}
 
 	/*
 	 * Our channel array is sparsley populated and we
@@ -1258,7 +1321,6 @@ static struct vmbus_channel *get_og_chn(struct storvsc_device *stor_device,
 	 * The strategy is simple:
 	 * I. Ensure NUMA locality
 	 * II. Distribute evenly (best effort)
-	 * III. Mapping is persistent.
 	 */
 
 	node_mask = cpumask_of_node(cpu_to_node(q_num));
@@ -1268,8 +1330,10 @@ static struct vmbus_channel *get_og_chn(struct storvsc_device *stor_device,
 		if (cpumask_test_cpu(tgt_cpu, node_mask))
 			num_channels++;
 	}
-	if (num_channels == 0)
+	if (num_channels == 0) {
+		stor_device->stor_chns[q_num] = stor_device->device->channel;
 		return stor_device->device->channel;
+	}
 
 	hash_qnum = q_num;
 	while (hash_qnum >= num_channels)
@@ -1295,6 +1359,7 @@ static int storvsc_do_io(struct hv_device *device,
 	struct storvsc_device *stor_device;
 	struct vstor_packet *vstor_packet;
 	struct vmbus_channel *outgoing_channel, *channel;
+	unsigned long flags;
 	int ret = 0;
 	const struct cpumask *node_mask;
 	int tgt_cpu;
@@ -1308,10 +1373,11 @@ static int storvsc_do_io(struct hv_device *device,
 
 	request->device  = device;
 	/*
-	 * Select an an appropriate channel to send the request out.
+	 * Select an appropriate channel to send the request out.
 	 */
-	if (stor_device->stor_chns[q_num] != NULL) {
-		outgoing_channel = stor_device->stor_chns[q_num];
+	/* See storvsc_change_target_cpu(). */
+	outgoing_channel = READ_ONCE(stor_device->stor_chns[q_num]);
+	if (outgoing_channel != NULL) {
 		if (outgoing_channel->target_cpu == q_num) {
 			/*
 			 * Ideally, we want to pick a different channel if
@@ -1324,7 +1390,10 @@ static int storvsc_do_io(struct hv_device *device,
 					continue;
 				if (tgt_cpu == q_num)
 					continue;
-				channel = stor_device->stor_chns[tgt_cpu];
+				channel = READ_ONCE(
+					stor_device->stor_chns[tgt_cpu]);
+				if (channel == NULL)
+					continue;
 				if (hv_get_avail_to_write_percent(
 							&channel->outbound)
 						> ring_avail_percent_lowater) {
@@ -1350,7 +1419,10 @@ static int storvsc_do_io(struct hv_device *device,
 			for_each_cpu(tgt_cpu, &stor_device->alloced_cpus) {
 				if (cpumask_test_cpu(tgt_cpu, node_mask))
 					continue;
-				channel = stor_device->stor_chns[tgt_cpu];
+				channel = READ_ONCE(
+					stor_device->stor_chns[tgt_cpu]);
+				if (channel == NULL)
+					continue;
 				if (hv_get_avail_to_write_percent(
 							&channel->outbound)
 						> ring_avail_percent_lowater) {
@@ -1360,7 +1432,14 @@ static int storvsc_do_io(struct hv_device *device,
 			}
 		}
 	} else {
+		spin_lock_irqsave(&device->channel->lock, flags);
+		outgoing_channel = stor_device->stor_chns[q_num];
+		if (outgoing_channel != NULL) {
+			spin_unlock_irqrestore(&device->channel->lock, flags);
+			goto found_channel;
+		}
 		outgoing_channel = get_og_chn(stor_device, q_num);
+		spin_unlock_irqrestore(&device->channel->lock, flags);
 	}
 
 found_channel:
diff --git a/drivers/soc/imx/soc-imx8m.c b/drivers/soc/imx/soc-imx8m.c
index 719e1f189ebf..7b0759adb47d 100644
--- a/drivers/soc/imx/soc-imx8m.c
+++ b/drivers/soc/imx/soc-imx8m.c
@@ -53,11 +53,11 @@ static u32 __init imx8mq_soc_revision(void)
 	struct device_node *np;
 	void __iomem *ocotp_base;
 	u32 magic;
-	u32 rev = 0;
+	u32 rev;
 
 	np = of_find_compatible_node(NULL, NULL, "fsl,imx8mq-ocotp");
 	if (!np)
-		goto out;
+		return 0;
 
 	ocotp_base = of_iomap(np, 0);
 	WARN_ON(!ocotp_base);
@@ -78,9 +78,8 @@ static u32 __init imx8mq_soc_revision(void)
 	soc_uid |= readl_relaxed(ocotp_base + OCOTP_UID_LOW);
 
 	iounmap(ocotp_base);
-
-out:
 	of_node_put(np);
+
 	return rev;
 }
 
diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
index 2114b563478c..e84513318725 100644
--- a/drivers/soc/mediatek/Kconfig
+++ b/drivers/soc/mediatek/Kconfig
@@ -44,4 +44,12 @@ config MTK_SCPSYS
 	  Say yes here to add support for the MediaTek SCPSYS power domain
 	  driver.
 
+config MTK_MMSYS
+	bool "MediaTek MMSYS Support"
+	depends on COMMON_CLK_MT8173_MMSYS
+	default COMMON_CLK_MT8173_MMSYS
+	help
+	  Say yes here to add support for the MediaTek Multimedia
+	  Subsystem (MMSYS).
+
 endmenu
diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
index b01733074ad6..01f9f873634a 100644
--- a/drivers/soc/mediatek/Makefile
+++ b/drivers/soc/mediatek/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o
 obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
 obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
 obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
+obj-$(CONFIG_MTK_MMSYS) += mtk-mmsys.o
diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
new file mode 100644
index 000000000000..05e322c9c301
--- /dev/null
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -0,0 +1,337 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: James Liao <jamesjj.liao@mediatek.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/device.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/soc/mediatek/mtk-mmsys.h>
+
+#include "../../gpu/drm/mediatek/mtk_drm_ddp.h"
+#include "../../gpu/drm/mediatek/mtk_drm_ddp_comp.h"
+
+#define DISP_REG_CONFIG_DISP_OVL0_MOUT_EN	0x040
+#define DISP_REG_CONFIG_DISP_OVL1_MOUT_EN	0x044
+#define DISP_REG_CONFIG_DISP_OD_MOUT_EN		0x048
+#define DISP_REG_CONFIG_DISP_GAMMA_MOUT_EN	0x04c
+#define DISP_REG_CONFIG_DISP_UFOE_MOUT_EN	0x050
+#define DISP_REG_CONFIG_DISP_COLOR0_SEL_IN	0x084
+#define DISP_REG_CONFIG_DISP_COLOR1_SEL_IN	0x088
+#define DISP_REG_CONFIG_DSIE_SEL_IN		0x0a4
+#define DISP_REG_CONFIG_DSIO_SEL_IN		0x0a8
+#define DISP_REG_CONFIG_DPI_SEL_IN		0x0ac
+#define DISP_REG_CONFIG_DISP_RDMA2_SOUT		0x0b8
+#define DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN	0x0c4
+#define DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN	0x0c8
+#define DISP_REG_CONFIG_MMSYS_CG_CON0		0x100
+
+#define DISP_REG_CONFIG_DISP_OVL_MOUT_EN	0x030
+#define DISP_REG_CONFIG_OUT_SEL			0x04c
+#define DISP_REG_CONFIG_DSI_SEL			0x050
+#define DISP_REG_CONFIG_DPI_SEL			0x064
+
+#define OVL0_MOUT_EN_COLOR0			0x1
+#define OD_MOUT_EN_RDMA0			0x1
+#define OD1_MOUT_EN_RDMA1			BIT(16)
+#define UFOE_MOUT_EN_DSI0			0x1
+#define COLOR0_SEL_IN_OVL0			0x1
+#define OVL1_MOUT_EN_COLOR1			0x1
+#define GAMMA_MOUT_EN_RDMA1			0x1
+#define RDMA0_SOUT_DPI0				0x2
+#define RDMA0_SOUT_DPI1				0x3
+#define RDMA0_SOUT_DSI1				0x1
+#define RDMA0_SOUT_DSI2				0x4
+#define RDMA0_SOUT_DSI3				0x5
+#define RDMA1_SOUT_DPI0				0x2
+#define RDMA1_SOUT_DPI1				0x3
+#define RDMA1_SOUT_DSI1				0x1
+#define RDMA1_SOUT_DSI2				0x4
+#define RDMA1_SOUT_DSI3				0x5
+#define RDMA2_SOUT_DPI0				0x2
+#define RDMA2_SOUT_DPI1				0x3
+#define RDMA2_SOUT_DSI1				0x1
+#define RDMA2_SOUT_DSI2				0x4
+#define RDMA2_SOUT_DSI3				0x5
+#define DPI0_SEL_IN_RDMA1			0x1
+#define DPI0_SEL_IN_RDMA2			0x3
+#define DPI1_SEL_IN_RDMA1			(0x1 << 8)
+#define DPI1_SEL_IN_RDMA2			(0x3 << 8)
+#define DSI0_SEL_IN_RDMA1			0x1
+#define DSI0_SEL_IN_RDMA2			0x4
+#define DSI1_SEL_IN_RDMA1			0x1
+#define DSI1_SEL_IN_RDMA2			0x4
+#define DSI2_SEL_IN_RDMA1			(0x1 << 16)
+#define DSI2_SEL_IN_RDMA2			(0x4 << 16)
+#define DSI3_SEL_IN_RDMA1			(0x1 << 16)
+#define DSI3_SEL_IN_RDMA2			(0x4 << 16)
+#define COLOR1_SEL_IN_OVL1			0x1
+
+#define OVL_MOUT_EN_RDMA			0x1
+#define BLS_TO_DSI_RDMA1_TO_DPI1		0x8
+#define BLS_TO_DPI_RDMA1_TO_DSI			0x2
+#define DSI_SEL_IN_BLS				0x0
+#define DPI_SEL_IN_BLS				0x0
+#define DSI_SEL_IN_RDMA				0x1
+
+struct mtk_mmsys_driver_data {
+	const char *clk_driver;
+};
+
+static const struct mtk_mmsys_driver_data mt8173_mmsys_driver_data = {
+	.clk_driver = "clk-mt8173-mm",
+};
+
+static unsigned int mtk_mmsys_ddp_mout_en(enum mtk_ddp_comp_id cur,
+					  enum mtk_ddp_comp_id next,
+					  unsigned int *addr)
+{
+	unsigned int value;
+
+	if (cur == DDP_COMPONENT_OVL0 && next == DDP_COMPONENT_COLOR0) {
+		*addr = DISP_REG_CONFIG_DISP_OVL0_MOUT_EN;
+		value = OVL0_MOUT_EN_COLOR0;
+	} else if (cur == DDP_COMPONENT_OVL0 && next == DDP_COMPONENT_RDMA0) {
+		*addr = DISP_REG_CONFIG_DISP_OVL_MOUT_EN;
+		value = OVL_MOUT_EN_RDMA;
+	} else if (cur == DDP_COMPONENT_OD0 && next == DDP_COMPONENT_RDMA0) {
+		*addr = DISP_REG_CONFIG_DISP_OD_MOUT_EN;
+		value = OD_MOUT_EN_RDMA0;
+	} else if (cur == DDP_COMPONENT_UFOE && next == DDP_COMPONENT_DSI0) {
+		*addr = DISP_REG_CONFIG_DISP_UFOE_MOUT_EN;
+		value = UFOE_MOUT_EN_DSI0;
+	} else if (cur == DDP_COMPONENT_OVL1 && next == DDP_COMPONENT_COLOR1) {
+		*addr = DISP_REG_CONFIG_DISP_OVL1_MOUT_EN;
+		value = OVL1_MOUT_EN_COLOR1;
+	} else if (cur == DDP_COMPONENT_GAMMA && next == DDP_COMPONENT_RDMA1) {
+		*addr = DISP_REG_CONFIG_DISP_GAMMA_MOUT_EN;
+		value = GAMMA_MOUT_EN_RDMA1;
+	} else if (cur == DDP_COMPONENT_OD1 && next == DDP_COMPONENT_RDMA1) {
+		*addr = DISP_REG_CONFIG_DISP_OD_MOUT_EN;
+		value = OD1_MOUT_EN_RDMA1;
+	} else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DPI0) {
+		*addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
+		value = RDMA0_SOUT_DPI0;
+	} else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DPI1) {
+		*addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
+		value = RDMA0_SOUT_DPI1;
+	} else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DSI1) {
+		*addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
+		value = RDMA0_SOUT_DSI1;
+	} else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DSI2) {
+		*addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
+		value = RDMA0_SOUT_DSI2;
+	} else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DSI3) {
+		*addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
+		value = RDMA0_SOUT_DSI3;
+	} else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI1) {
+		*addr = DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN;
+		value = RDMA1_SOUT_DSI1;
+	} else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI2) {
+		*addr = DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN;
+		value = RDMA1_SOUT_DSI2;
+	} else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI3) {
+		*addr = DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN;
+		value = RDMA1_SOUT_DSI3;
+	} else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DPI0) {
+		*addr = DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN;
+		value = RDMA1_SOUT_DPI0;
+	} else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DPI1) {
+		*addr = DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN;
+		value = RDMA1_SOUT_DPI1;
+	} else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DPI0) {
+		*addr = DISP_REG_CONFIG_DISP_RDMA2_SOUT;
+		value = RDMA2_SOUT_DPI0;
+	} else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DPI1) {
+		*addr = DISP_REG_CONFIG_DISP_RDMA2_SOUT;
+		value = RDMA2_SOUT_DPI1;
+	} else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI1) {
+		*addr = DISP_REG_CONFIG_DISP_RDMA2_SOUT;
+		value = RDMA2_SOUT_DSI1;
+	} else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI2) {
+		*addr = DISP_REG_CONFIG_DISP_RDMA2_SOUT;
+		value = RDMA2_SOUT_DSI2;
+	} else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI3) {
+		*addr = DISP_REG_CONFIG_DISP_RDMA2_SOUT;
+		value = RDMA2_SOUT_DSI3;
+	} else {
+		value = 0;
+	}
+
+	return value;
+}
+
+static unsigned int mtk_mmsys_ddp_sel_in(enum mtk_ddp_comp_id cur,
+					 enum mtk_ddp_comp_id next,
+					 unsigned int *addr)
+{
+	unsigned int value;
+
+	if (cur == DDP_COMPONENT_OVL0 && next == DDP_COMPONENT_COLOR0) {
+		*addr = DISP_REG_CONFIG_DISP_COLOR0_SEL_IN;
+		value = COLOR0_SEL_IN_OVL0;
+	} else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DPI0) {
+		*addr = DISP_REG_CONFIG_DPI_SEL_IN;
+		value = DPI0_SEL_IN_RDMA1;
+	} else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DPI1) {
+		*addr = DISP_REG_CONFIG_DPI_SEL_IN;
+		value = DPI1_SEL_IN_RDMA1;
+	} else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI0) {
+		*addr = DISP_REG_CONFIG_DSIE_SEL_IN;
+		value = DSI0_SEL_IN_RDMA1;
+	} else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI1) {
+		*addr = DISP_REG_CONFIG_DSIO_SEL_IN;
+		value = DSI1_SEL_IN_RDMA1;
+	} else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI2) {
+		*addr = DISP_REG_CONFIG_DSIE_SEL_IN;
+		value = DSI2_SEL_IN_RDMA1;
+	} else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI3) {
+		*addr = DISP_REG_CONFIG_DSIO_SEL_IN;
+		value = DSI3_SEL_IN_RDMA1;
+	} else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DPI0) {
+		*addr = DISP_REG_CONFIG_DPI_SEL_IN;
+		value = DPI0_SEL_IN_RDMA2;
+	} else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DPI1) {
+		*addr = DISP_REG_CONFIG_DPI_SEL_IN;
+		value = DPI1_SEL_IN_RDMA2;
+	} else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI0) {
+		*addr = DISP_REG_CONFIG_DSIE_SEL_IN;
+		value = DSI0_SEL_IN_RDMA2;
+	} else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI1) {
+		*addr = DISP_REG_CONFIG_DSIO_SEL_IN;
+		value = DSI1_SEL_IN_RDMA2;
+	} else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI2) {
+		*addr = DISP_REG_CONFIG_DSIE_SEL_IN;
+		value = DSI2_SEL_IN_RDMA2;
+	} else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI3) {
+		*addr = DISP_REG_CONFIG_DSIE_SEL_IN;
+		value = DSI3_SEL_IN_RDMA2;
+	} else if (cur == DDP_COMPONENT_OVL1 && next == DDP_COMPONENT_COLOR1) {
+		*addr = DISP_REG_CONFIG_DISP_COLOR1_SEL_IN;
+		value = COLOR1_SEL_IN_OVL1;
+	} else if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DSI0) {
+		*addr = DISP_REG_CONFIG_DSI_SEL;
+		value = DSI_SEL_IN_BLS;
+	} else {
+		value = 0;
+	}
+
+	return value;
+}
+
+static void mtk_mmsys_ddp_sout_sel(void __iomem *config_regs,
+				   enum mtk_ddp_comp_id cur,
+				   enum mtk_ddp_comp_id next)
+{
+	if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DSI0) {
+		writel_relaxed(BLS_TO_DSI_RDMA1_TO_DPI1,
+			       config_regs + DISP_REG_CONFIG_OUT_SEL);
+	} else if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DPI0) {
+		writel_relaxed(BLS_TO_DPI_RDMA1_TO_DSI,
+			       config_regs + DISP_REG_CONFIG_OUT_SEL);
+		writel_relaxed(DSI_SEL_IN_RDMA,
+			       config_regs + DISP_REG_CONFIG_DSI_SEL);
+		writel_relaxed(DPI_SEL_IN_BLS,
+			       config_regs + DISP_REG_CONFIG_DPI_SEL);
+	}
+}
+
+void mtk_mmsys_ddp_connect(struct device *dev,
+			   enum mtk_ddp_comp_id cur,
+			   enum mtk_ddp_comp_id next)
+{
+	void __iomem *config_regs = dev_get_drvdata(dev);
+	unsigned int addr, value, reg;
+
+	value = mtk_mmsys_ddp_mout_en(cur, next, &addr);
+	if (value) {
+		reg = readl_relaxed(config_regs + addr) | value;
+		writel_relaxed(reg, config_regs + addr);
+	}
+
+	mtk_mmsys_ddp_sout_sel(config_regs, cur, next);
+
+	value = mtk_mmsys_ddp_sel_in(cur, next, &addr);
+	if (value) {
+		reg = readl_relaxed(config_regs + addr) | value;
+		writel_relaxed(reg, config_regs + addr);
+	}
+}
+EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_connect);
+
+void mtk_mmsys_ddp_disconnect(struct device *dev,
+			      enum mtk_ddp_comp_id cur,
+			      enum mtk_ddp_comp_id next)
+{
+	void __iomem *config_regs = dev_get_drvdata(dev);
+	unsigned int addr, value, reg;
+
+	value = mtk_mmsys_ddp_mout_en(cur, next, &addr);
+	if (value) {
+		reg = readl_relaxed(config_regs + addr) & ~value;
+		writel_relaxed(reg, config_regs + addr);
+	}
+
+	value = mtk_mmsys_ddp_sel_in(cur, next, &addr);
+	if (value) {
+		reg = readl_relaxed(config_regs + addr) & ~value;
+		writel_relaxed(reg, config_regs + addr);
+	}
+}
+EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_disconnect);
+
+static int mtk_mmsys_probe(struct platform_device *pdev)
+{
+	const struct mtk_mmsys_driver_data *data;
+	struct device *dev = &pdev->dev;
+	struct platform_device *clks;
+	struct platform_device *drm;
+	void __iomem *config_regs;
+	struct resource *mem;
+	int ret;
+
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	config_regs = devm_ioremap_resource(dev, mem);
+	if (IS_ERR(config_regs)) {
+		ret = PTR_ERR(config_regs);
+		dev_err(dev, "Failed to ioremap mmsys-config resource: %d\n",
+			ret);
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, config_regs);
+
+	data = of_device_get_match_data(&pdev->dev);
+
+	clks = platform_device_register_data(&pdev->dev, data->clk_driver,
+					     PLATFORM_DEVID_AUTO, NULL, 0);
+	if (IS_ERR(clks))
+		return PTR_ERR(clks);
+
+	drm = platform_device_register_data(&pdev->dev, "mediatek-drm",
+					    PLATFORM_DEVID_AUTO, NULL, 0);
+	if (IS_ERR(drm))
+		return PTR_ERR(drm);
+
+	return 0;
+}
+
+static const struct of_device_id of_match_mtk_mmsys[] = {
+	{
+		.compatible = "mediatek,mt8173-mmsys",
+		.data = &mt8173_mmsys_driver_data,
+	},
+	{ }
+};
+
+static struct platform_driver mtk_mmsys_drv = {
+	.driver = {
+		.name = "mtk-mmsys",
+		.of_match_table = of_match_mtk_mmsys,
+	},
+	.probe = mtk_mmsys_probe,
+};
+
+builtin_platform_driver(mtk_mmsys_drv);
diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index bf42a17a45de..19332ea40234 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -117,7 +117,7 @@ config QCOM_RPMH
 	  help apply the aggregated state on the resource.
 
 config QCOM_RPMHPD
-	bool "Qualcomm RPMh Power domain driver"
+	tristate "Qualcomm RPMh Power domain driver"
 	depends on QCOM_RPMH && QCOM_COMMAND_DB
 	help
 	  QCOM RPMh Power domain driver to support power-domains with
@@ -126,8 +126,8 @@ config QCOM_RPMHPD
 	  for the voltage rail.
 
 config QCOM_RPMPD
-	bool "Qualcomm RPM Power domain driver"
-	depends on QCOM_SMD_RPM=y
+	tristate "Qualcomm RPM Power domain driver"
+	depends on QCOM_SMD_RPM
 	help
 	  QCOM RPM Power domain driver to support power-domains with
 	  performance states. The driver communicates a performance state
diff --git a/drivers/soc/qcom/cmd-db.c b/drivers/soc/qcom/cmd-db.c
index f6c3d17b05c7..8b2b7357b6da 100644
--- a/drivers/soc/qcom/cmd-db.c
+++ b/drivers/soc/qcom/cmd-db.c
@@ -1,12 +1,13 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. */
 
+#include <linux/debugfs.h>
 #include <linux/kernel.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
-#include <linux/of_platform.h>
 #include <linux/of_reserved_mem.h>
 #include <linux/platform_device.h>
+#include <linux/seq_file.h>
 #include <linux/types.h>
 
 #include <soc/qcom/cmd-db.h>
@@ -236,6 +237,77 @@ enum cmd_db_hw_type cmd_db_read_slave_id(const char *id)
 }
 EXPORT_SYMBOL(cmd_db_read_slave_id);
 
+#ifdef CONFIG_DEBUG_FS
+static int cmd_db_debugfs_dump(struct seq_file *seq, void *p)
+{
+	int i, j;
+	const struct rsc_hdr *rsc;
+	const struct entry_header *ent;
+	const char *name;
+	u16 len, version;
+	u8 major, minor;
+
+	seq_puts(seq, "Command DB DUMP\n");
+
+	for (i = 0; i < MAX_SLV_ID; i++) {
+		rsc = &cmd_db_header->header[i];
+		if (!rsc->slv_id)
+			break;
+
+		switch (rsc->slv_id) {
+		case CMD_DB_HW_ARC:
+			name = "ARC";
+			break;
+		case CMD_DB_HW_VRM:
+			name = "VRM";
+			break;
+		case CMD_DB_HW_BCM:
+			name = "BCM";
+			break;
+		default:
+			name = "Unknown";
+			break;
+		}
+
+		version = le16_to_cpu(rsc->version);
+		major = version >> 8;
+		minor = version;
+
+		seq_printf(seq, "Slave %s (v%u.%u)\n", name, major, minor);
+		seq_puts(seq, "-------------------------\n");
+
+		ent = rsc_to_entry_header(rsc);
+		for (j = 0; j < le16_to_cpu(rsc->cnt); j++, ent++) {
+			seq_printf(seq, "0x%08x: %*pEp", le32_to_cpu(ent->addr),
+				   sizeof(ent->id), ent->id);
+
+			len = le16_to_cpu(ent->len);
+			if (len) {
+				seq_printf(seq, " [%*ph]",
+					   len, rsc_offset(rsc, ent));
+			}
+			seq_putc(seq, '\n');
+		}
+	}
+
+	return 0;
+}
+
+static int open_cmd_db_debugfs(struct inode *inode, struct file *file)
+{
+	return single_open(file, cmd_db_debugfs_dump, inode->i_private);
+}
+#endif
+
+static const struct file_operations cmd_db_debugfs_ops = {
+#ifdef CONFIG_DEBUG_FS
+	.open = open_cmd_db_debugfs,
+#endif
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
 static int cmd_db_dev_probe(struct platform_device *pdev)
 {
 	struct reserved_mem *rmem;
@@ -259,12 +331,14 @@ static int cmd_db_dev_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
+	debugfs_create_file("cmd-db", 0400, NULL, NULL, &cmd_db_debugfs_ops);
+
 	return 0;
 }
 
 static const struct of_device_id cmd_db_match_table[] = {
 	{ .compatible = "qcom,cmd-db" },
-	{ },
+	{ }
 };
 
 static struct platform_driver cmd_db_dev_driver = {
diff --git a/drivers/soc/qcom/rpmh-internal.h b/drivers/soc/qcom/rpmh-internal.h
index 6eec32b97f83..dba8510c0669 100644
--- a/drivers/soc/qcom/rpmh-internal.h
+++ b/drivers/soc/qcom/rpmh-internal.h
@@ -22,16 +22,24 @@ struct rsc_drv;
  * struct tcs_group: group of Trigger Command Sets (TCS) to send state requests
  * to the controller
  *
- * @drv:       the controller
- * @type:      type of the TCS in this group - active, sleep, wake
- * @mask:      mask of the TCSes relative to all the TCSes in the RSC
- * @offset:    start of the TCS group relative to the TCSes in the RSC
- * @num_tcs:   number of TCSes in this type
- * @ncpt:      number of commands in each TCS
- * @lock:      lock for synchronizing this TCS writes
- * @req:       requests that are sent from the TCS
- * @cmd_cache: flattened cache of cmds in sleep/wake TCS
- * @slots:     indicates which of @cmd_addr are occupied
+ * @drv:       The controller.
+ * @type:      Type of the TCS in this group - active, sleep, wake.
+ * @mask:      Mask of the TCSes relative to all the TCSes in the RSC.
+ * @offset:    Start of the TCS group relative to the TCSes in the RSC.
+ * @num_tcs:   Number of TCSes in this type.
+ * @ncpt:      Number of commands in each TCS.
+ * @lock:      Lock for synchronizing this TCS writes.
+ * @req:       Requests that are sent from the TCS; only used for ACTIVE_ONLY
+ *             transfers (could be on a wake/sleep TCS if we are borrowing for
+ *             an ACTIVE_ONLY transfer).
+ *             Start: grab drv->lock, set req, set tcs_in_use, drop drv->lock,
+ *                    trigger
+ *             End: get irq, access req,
+ *                  grab drv->lock, clear tcs_in_use, drop drv->lock
+ * @slots:     Indicates which of @cmd_addr are occupied; only used for
+ *             SLEEP / WAKE TCSs.  Things are tightly packed in the
+ *             case that (ncpt < MAX_CMDS_PER_TCS).  That is if ncpt = 2 and
+ *             MAX_CMDS_PER_TCS = 16 then bit[2] = the first bit in 2nd TCS.
  */
 struct tcs_group {
 	struct rsc_drv *drv;
@@ -42,7 +50,6 @@ struct tcs_group {
 	int ncpt;
 	spinlock_t lock;
 	const struct tcs_request *req[MAX_TCS_PER_TYPE];
-	u32 *cmd_cache;
 	DECLARE_BITMAP(slots, MAX_TCS_SLOTS);
 };
 
@@ -84,30 +91,48 @@ struct rpmh_ctrlr {
  * struct rsc_drv: the Direct Resource Voter (DRV) of the
  * Resource State Coordinator controller (RSC)
  *
- * @name:       controller identifier
- * @tcs_base:   start address of the TCS registers in this controller
- * @id:         instance id in the controller (Direct Resource Voter)
- * @num_tcs:    number of TCSes in this DRV
- * @tcs:        TCS groups
- * @tcs_in_use: s/w state of the TCS
- * @lock:       synchronize state of the controller
- * @client:     handle to the DRV's client.
+ * @name:               Controller identifier.
+ * @tcs_base:           Start address of the TCS registers in this controller.
+ * @id:                 Instance id in the controller (Direct Resource Voter).
+ * @num_tcs:            Number of TCSes in this DRV.
+ * @rsc_pm:             CPU PM notifier for controller.
+ *                      Used when solver mode is not present.
+ * @cpus_entered_pm:    CPU mask for cpus in idle power collapse.
+ *                      Used when solver mode is not present.
+ * @tcs:                TCS groups.
+ * @tcs_in_use:         S/W state of the TCS; only set for ACTIVE_ONLY
+ *                      transfers, but might show a sleep/wake TCS in use if
+ *                      it was borrowed for an active_only transfer.  You
+ *                      must hold both the lock in this struct and the
+ *                      tcs_lock for the TCS in order to mark a TCS as
+ *                      in-use, but you only need the lock in this structure
+ *                      (aka the drv->lock) to mark one freed.
+ * @lock:               Synchronize state of the controller.  If you will be
+ *                      grabbing this lock and a tcs_lock at the same time,
+ *                      grab the tcs_lock first so we always have a
+ *                      consistent lock ordering.
+ * @pm_lock:            Synchronize during PM notifications.
+ *                      Used when solver mode is not present.
+ * @client:             Handle to the DRV's client.
  */
 struct rsc_drv {
 	const char *name;
 	void __iomem *tcs_base;
 	int id;
 	int num_tcs;
+	struct notifier_block rsc_pm;
+	struct cpumask cpus_entered_pm;
 	struct tcs_group tcs[TCS_TYPE_NR];
 	DECLARE_BITMAP(tcs_in_use, MAX_TCS_NR);
 	spinlock_t lock;
+	spinlock_t pm_lock;
 	struct rpmh_ctrlr client;
 };
 
 int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg);
 int rpmh_rsc_write_ctrl_data(struct rsc_drv *drv,
 			     const struct tcs_request *msg);
-int rpmh_rsc_invalidate(struct rsc_drv *drv);
+void rpmh_rsc_invalidate(struct rsc_drv *drv);
 
 void rpmh_tx_done(const struct tcs_request *msg, int r);
 int rpmh_flush(struct rpmh_ctrlr *ctrlr);
diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c
index b71822131f59..732316bb67dc 100644
--- a/drivers/soc/qcom/rpmh-rsc.c
+++ b/drivers/soc/qcom/rpmh-rsc.c
@@ -6,6 +6,7 @@
 #define pr_fmt(fmt) "%s " fmt, KBUILD_MODNAME
 
 #include <linux/atomic.h>
+#include <linux/cpu_pm.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
@@ -30,21 +31,41 @@
 #define RSC_DRV_TCS_OFFSET		672
 #define RSC_DRV_CMD_OFFSET		20
 
-/* DRV Configuration Information Register */
+/* DRV HW Solver Configuration Information Register */
+#define DRV_SOLVER_CONFIG		0x04
+#define DRV_HW_SOLVER_MASK		1
+#define DRV_HW_SOLVER_SHIFT		24
+
+/* DRV TCS Configuration Information Register */
 #define DRV_PRNT_CHLD_CONFIG		0x0C
 #define DRV_NUM_TCS_MASK		0x3F
 #define DRV_NUM_TCS_SHIFT		6
 #define DRV_NCPT_MASK			0x1F
 #define DRV_NCPT_SHIFT			27
 
-/* Register offsets */
+/* Offsets for common TCS Registers, one bit per TCS */
 #define RSC_DRV_IRQ_ENABLE		0x00
 #define RSC_DRV_IRQ_STATUS		0x04
-#define RSC_DRV_IRQ_CLEAR		0x08
-#define RSC_DRV_CMD_WAIT_FOR_CMPL	0x10
+#define RSC_DRV_IRQ_CLEAR		0x08	/* w/o; write 1 to clear */
+
+/*
+ * Offsets for per TCS Registers.
+ *
+ * TCSes start at 0x10 from tcs_base and are stored one after another.
+ * Multiply tcs_id by RSC_DRV_TCS_OFFSET to find a given TCS and add one
+ * of the below to find a register.
+ */
+#define RSC_DRV_CMD_WAIT_FOR_CMPL	0x10	/* 1 bit per command */
 #define RSC_DRV_CONTROL			0x14
-#define RSC_DRV_STATUS			0x18
-#define RSC_DRV_CMD_ENABLE		0x1C
+#define RSC_DRV_STATUS			0x18	/* zero if tcs is busy */
+#define RSC_DRV_CMD_ENABLE		0x1C	/* 1 bit per command */
+
+/*
+ * Offsets for per command in a TCS.
+ *
+ * Commands (up to 16) start at 0x30 in a TCS; multiply command index
+ * by RSC_DRV_CMD_OFFSET and add one of the below to find a register.
+ */
 #define RSC_DRV_CMD_MSGID		0x30
 #define RSC_DRV_CMD_ADDR		0x34
 #define RSC_DRV_CMD_DATA		0x38
@@ -61,28 +82,87 @@
 #define CMD_STATUS_ISSUED		BIT(8)
 #define CMD_STATUS_COMPL		BIT(16)
 
-static u32 read_tcs_reg(struct rsc_drv *drv, int reg, int tcs_id, int cmd_id)
+/*
+ * Here's a high level overview of how all the registers in RPMH work
+ * together:
+ *
+ * - The main rpmh-rsc address is the base of a register space that can
+ *   be used to find overall configuration of the hardware
+ *   (DRV_PRNT_CHLD_CONFIG). Also found within the rpmh-rsc register
+ *   space are all the TCS blocks. The offset of the TCS blocks is
+ *   specified in the device tree by "qcom,tcs-offset" and used to
+ *   compute tcs_base.
+ * - TCS blocks come one after another. Type, count, and order are
+ *   specified by the device tree as "qcom,tcs-config".
+ * - Each TCS block has some registers, then space for up to 16 commands.
+ *   Note that though address space is reserved for 16 commands, fewer
+ *   might be present. See ncpt (num cmds per TCS).
+ *
+ * Here's a picture:
+ *
+ *  +---------------------------------------------------+
+ *  |RSC                                                |
+ *  | ctrl                                              |
+ *  |                                                   |
+ *  | Drvs:                                             |
+ *  | +-----------------------------------------------+ |
+ *  | |DRV0                                           | |
+ *  | | ctrl/config                                   | |
+ *  | | IRQ                                           | |
+ *  | |                                               | |
+ *  | | TCSes:                                        | |
+ *  | | +------------------------------------------+  | |
+ *  | | |TCS0  |  |  |  |  |  |  |  |  |  |  |  |  |  | |
+ *  | | | ctrl | 0| 1| 2| 3| 4| 5| .| .| .| .|14|15|  | |
+ *  | | |      |  |  |  |  |  |  |  |  |  |  |  |  |  | |
+ *  | | +------------------------------------------+  | |
+ *  | | +------------------------------------------+  | |
+ *  | | |TCS1  |  |  |  |  |  |  |  |  |  |  |  |  |  | |
+ *  | | | ctrl | 0| 1| 2| 3| 4| 5| .| .| .| .|14|15|  | |
+ *  | | |      |  |  |  |  |  |  |  |  |  |  |  |  |  | |
+ *  | | +------------------------------------------+  | |
+ *  | | +------------------------------------------+  | |
+ *  | | |TCS2  |  |  |  |  |  |  |  |  |  |  |  |  |  | |
+ *  | | | ctrl | 0| 1| 2| 3| 4| 5| .| .| .| .|14|15|  | |
+ *  | | |      |  |  |  |  |  |  |  |  |  |  |  |  |  | |
+ *  | | +------------------------------------------+  | |
+ *  | |                    ......                     | |
+ *  | +-----------------------------------------------+ |
+ *  | +-----------------------------------------------+ |
+ *  | |DRV1                                           | |
+ *  | | (same as DRV0)                                | |
+ *  | +-----------------------------------------------+ |
+ *  |                      ......                       |
+ *  +---------------------------------------------------+
+ */
+
+static u32 read_tcs_cmd(struct rsc_drv *drv, int reg, int tcs_id, int cmd_id)
 {
-	return readl_relaxed(drv->tcs_base + reg + RSC_DRV_TCS_OFFSET * tcs_id +
+	return readl_relaxed(drv->tcs_base + RSC_DRV_TCS_OFFSET * tcs_id + reg +
 			     RSC_DRV_CMD_OFFSET * cmd_id);
 }
 
+static u32 read_tcs_reg(struct rsc_drv *drv, int reg, int tcs_id)
+{
+	return readl_relaxed(drv->tcs_base + RSC_DRV_TCS_OFFSET * tcs_id + reg);
+}
+
 static void write_tcs_cmd(struct rsc_drv *drv, int reg, int tcs_id, int cmd_id,
 			  u32 data)
 {
-	writel_relaxed(data, drv->tcs_base + reg + RSC_DRV_TCS_OFFSET * tcs_id +
+	writel_relaxed(data, drv->tcs_base + RSC_DRV_TCS_OFFSET * tcs_id + reg +
 		       RSC_DRV_CMD_OFFSET * cmd_id);
 }
 
 static void write_tcs_reg(struct rsc_drv *drv, int reg, int tcs_id, u32 data)
 {
-	writel_relaxed(data, drv->tcs_base + reg + RSC_DRV_TCS_OFFSET * tcs_id);
+	writel_relaxed(data, drv->tcs_base + RSC_DRV_TCS_OFFSET * tcs_id + reg);
 }
 
 static void write_tcs_reg_sync(struct rsc_drv *drv, int reg, int tcs_id,
 			       u32 data)
 {
-	writel(data, drv->tcs_base + reg + RSC_DRV_TCS_OFFSET * tcs_id);
+	writel(data, drv->tcs_base + RSC_DRV_TCS_OFFSET * tcs_id + reg);
 	for (;;) {
 		if (data == readl(drv->tcs_base + reg +
 				  RSC_DRV_TCS_OFFSET * tcs_id))
@@ -91,64 +171,84 @@ static void write_tcs_reg_sync(struct rsc_drv *drv, int reg, int tcs_id,
 	}
 }
 
+/**
+ * tcs_is_free() - Return if a TCS is totally free.
+ * @drv:    The RSC controller.
+ * @tcs_id: The global ID of this TCS.
+ *
+ * Returns true if nobody has claimed this TCS (by setting tcs_in_use).
+ *
+ * Context: Must be called with the drv->lock held or the tcs_lock for the TCS
+ *          being tested. If only the tcs_lock is held then it is possible that
+ *          this function will return that a tcs is still busy when it has been
+ *          recently been freed but it will never return free when a TCS is
+ *          actually in use.
+ *
+ * Return: true if the given TCS is free.
+ */
 static bool tcs_is_free(struct rsc_drv *drv, int tcs_id)
 {
-	return !test_bit(tcs_id, drv->tcs_in_use) &&
-	       read_tcs_reg(drv, RSC_DRV_STATUS, tcs_id, 0);
-}
-
-static struct tcs_group *get_tcs_of_type(struct rsc_drv *drv, int type)
-{
-	return &drv->tcs[type];
+	return !test_bit(tcs_id, drv->tcs_in_use);
 }
 
-static int tcs_invalidate(struct rsc_drv *drv, int type)
+/**
+ * tcs_invalidate() - Invalidate all TCSes of the given type (sleep or wake).
+ * @drv:  The RSC controller.
+ * @type: SLEEP_TCS or WAKE_TCS
+ *
+ * This will clear the "slots" variable of the given tcs_group and also
+ * tell the hardware to forget about all entries.
+ *
+ * The caller must ensure that no other RPMH actions are happening when this
+ * function is called, since otherwise the device may immediately become
+ * used again even before this function exits.
+ */
+static void tcs_invalidate(struct rsc_drv *drv, int type)
 {
 	int m;
-	struct tcs_group *tcs;
-
-	tcs = get_tcs_of_type(drv, type);
+	struct tcs_group *tcs = &drv->tcs[type];
 
-	spin_lock(&tcs->lock);
-	if (bitmap_empty(tcs->slots, MAX_TCS_SLOTS)) {
-		spin_unlock(&tcs->lock);
-		return 0;
-	}
+	/* Caller ensures nobody else is running so no lock */
+	if (bitmap_empty(tcs->slots, MAX_TCS_SLOTS))
+		return;
 
 	for (m = tcs->offset; m < tcs->offset + tcs->num_tcs; m++) {
-		if (!tcs_is_free(drv, m)) {
-			spin_unlock(&tcs->lock);
-			return -EAGAIN;
-		}
 		write_tcs_reg_sync(drv, RSC_DRV_CMD_ENABLE, m, 0);
 		write_tcs_reg_sync(drv, RSC_DRV_CMD_WAIT_FOR_CMPL, m, 0);
 	}
 	bitmap_zero(tcs->slots, MAX_TCS_SLOTS);
-	spin_unlock(&tcs->lock);
-
-	return 0;
 }
 
 /**
- * rpmh_rsc_invalidate - Invalidate sleep and wake TCSes
+ * rpmh_rsc_invalidate() - Invalidate sleep and wake TCSes.
+ * @drv: The RSC controller.
  *
- * @drv: the RSC controller
+ * The caller must ensure that no other RPMH actions are happening when this
+ * function is called, since otherwise the device may immediately become
+ * used again even before this function exits.
  */
-int rpmh_rsc_invalidate(struct rsc_drv *drv)
+void rpmh_rsc_invalidate(struct rsc_drv *drv)
 {
-	int ret;
-
-	ret = tcs_invalidate(drv, SLEEP_TCS);
-	if (!ret)
-		ret = tcs_invalidate(drv, WAKE_TCS);
-
-	return ret;
+	tcs_invalidate(drv, SLEEP_TCS);
+	tcs_invalidate(drv, WAKE_TCS);
 }
 
+/**
+ * get_tcs_for_msg() - Get the tcs_group used to send the given message.
+ * @drv: The RSC controller.
+ * @msg: The message we want to send.
+ *
+ * This is normally pretty straightforward except if we are trying to send
+ * an ACTIVE_ONLY message but don't have any active_only TCSes.
+ *
+ * Called without drv->lock held and with no tcs_lock locks held.
+ *
+ * Return: A pointer to a tcs_group or an ERR_PTR.
+ */
 static struct tcs_group *get_tcs_for_msg(struct rsc_drv *drv,
 					 const struct tcs_request *msg)
 {
-	int type, ret;
+	int type;
 	struct tcs_group *tcs;
 
 	switch (msg->state) {
@@ -168,24 +268,33 @@ static struct tcs_group *get_tcs_for_msg(struct rsc_drv *drv,
 	/*
 	 * If we are making an active request on a RSC that does not have a
 	 * dedicated TCS for active state use, then re-purpose a wake TCS to
-	 * send active votes.
-	 * NOTE: The driver must be aware that this RSC does not have a
-	 * dedicated AMC, and therefore would invalidate the sleep and wake
-	 * TCSes before making an active state request.
+	 * send active votes. This is safe because we ensure any active-only
+	 * transfers have finished before we use it (maybe by running from
+	 * the last CPU in PM code).
 	 */
-	tcs = get_tcs_of_type(drv, type);
-	if (msg->state == RPMH_ACTIVE_ONLY_STATE && !tcs->num_tcs) {
-		tcs = get_tcs_of_type(drv, WAKE_TCS);
-		if (tcs->num_tcs) {
-			ret = rpmh_rsc_invalidate(drv);
-			if (ret)
-				return ERR_PTR(ret);
-		}
-	}
+	tcs = &drv->tcs[type];
+	if (msg->state == RPMH_ACTIVE_ONLY_STATE && !tcs->num_tcs)
+		tcs = &drv->tcs[WAKE_TCS];
 
 	return tcs;
 }
 
+/**
+ * get_req_from_tcs() - Get a stashed request that was xfering on the given TCS.
+ * @drv:    The RSC controller.
+ * @tcs_id: The global ID of this TCS.
+ *
+ * For ACTIVE_ONLY transfers we want to call back into the client when the
+ * transfer finishes. To do this we need the "request" that the client
+ * originally provided us. This function grabs the request that we stashed
+ * when we started the transfer.
+ *
+ * This only makes sense for ACTIVE_ONLY transfers since those are the only
+ * ones we track sending (the only ones we enable interrupts for and the only
+ * ones we call back to the client for).
+ *
+ * Return: The stashed request.
+ */
 static const struct tcs_request *get_req_from_tcs(struct rsc_drv *drv,
 						  int tcs_id)
 {
@@ -202,7 +311,76 @@ static const struct tcs_request *get_req_from_tcs(struct rsc_drv *drv,
 }
 
 /**
- * tcs_tx_done: TX Done interrupt handler
+ * __tcs_set_trigger() - Start xfer on a TCS or unset trigger on a borrowed TCS
+ * @drv:     The controller.
+ * @tcs_id:  The global ID of this TCS.
+ * @trigger: If true then untrigger/retrigger. If false then just untrigger.
+ *
+ * In the normal case we only ever call with "trigger=true" to start a
+ * transfer. That will un-trigger/disable the TCS from the last transfer
+ * then trigger/enable for this transfer.
+ *
+ * If we borrowed a wake TCS for an active-only transfer we'll also call
+ * this function with "trigger=false" to just do the un-trigger/disable
+ * before using the TCS for wake purposes again.
+ *
+ * Note that the AP is only in charge of triggering active-only transfers.
+ * The AP never triggers sleep/wake values using this function.
+ */
+static void __tcs_set_trigger(struct rsc_drv *drv, int tcs_id, bool trigger)
+{
+	u32 enable;
+
+	/*
+	 * HW req: Clear the DRV_CONTROL and enable TCS again
+	 * While clearing ensure that the AMC mode trigger is cleared
+	 * and then the mode enable is cleared.
+	 */
+	enable = read_tcs_reg(drv, RSC_DRV_CONTROL, tcs_id);
+	enable &= ~TCS_AMC_MODE_TRIGGER;
+	write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable);
+	enable &= ~TCS_AMC_MODE_ENABLE;
+	write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable);
+
+	if (trigger) {
+		/* Enable the AMC mode on the TCS and then trigger the TCS */
+		enable = TCS_AMC_MODE_ENABLE;
+		write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable);
+		enable |= TCS_AMC_MODE_TRIGGER;
+		write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable);
+	}
+}
+
+/**
+ * enable_tcs_irq() - Enable or disable interrupts on the given TCS.
+ * @drv:     The controller.
+ * @tcs_id:  The global ID of this TCS.
+ * @enable:  If true then enable; if false then disable
+ *
+ * We only ever call this when we borrow a wake TCS for an active-only
+ * transfer. For active-only TCSes interrupts are always left enabled.
+ */
+static void enable_tcs_irq(struct rsc_drv *drv, int tcs_id, bool enable)
+{
+	u32 data;
+
+	data = readl_relaxed(drv->tcs_base + RSC_DRV_IRQ_ENABLE);
+	if (enable)
+		data |= BIT(tcs_id);
+	else
+		data &= ~BIT(tcs_id);
+	writel_relaxed(data, drv->tcs_base + RSC_DRV_IRQ_ENABLE);
+}
+
+/**
+ * tcs_tx_done() - TX Done interrupt handler.
+ * @irq: The IRQ number (ignored).
+ * @p:   Pointer to "struct rsc_drv".
+ *
+ * Called for ACTIVE_ONLY transfers (those are the only ones we enable the
+ * IRQ for) when a transfer is done.
+ *
+ * Return: IRQ_HANDLED
  */
 static irqreturn_t tcs_tx_done(int irq, void *p)
 {
@@ -212,7 +390,7 @@ static irqreturn_t tcs_tx_done(int irq, void *p)
 	const struct tcs_request *req;
 	struct tcs_cmd *cmd;
 
-	irq_status = read_tcs_reg(drv, RSC_DRV_IRQ_STATUS, 0, 0);
+	irq_status = readl_relaxed(drv->tcs_base + RSC_DRV_IRQ_STATUS);
 
 	for_each_set_bit(i, &irq_status, BITS_PER_LONG) {
 		req = get_req_from_tcs(drv, i);
@@ -226,7 +404,7 @@ static irqreturn_t tcs_tx_done(int irq, void *p)
 			u32 sts;
 
 			cmd = &req->cmds[j];
-			sts = read_tcs_reg(drv, RSC_DRV_CMD_STATUS, i, j);
+			sts = read_tcs_cmd(drv, RSC_DRV_CMD_STATUS, i, j);
 			if (!(sts & CMD_STATUS_ISSUED) ||
 			   ((req->wait_for_compl || cmd->wait) &&
 			   !(sts & CMD_STATUS_COMPL))) {
@@ -237,13 +415,28 @@ static irqreturn_t tcs_tx_done(int irq, void *p)
 		}
 
 		trace_rpmh_tx_done(drv, i, req, err);
+
+		/*
+		 * If wake tcs was re-purposed for sending active
+		 * votes, clear AMC trigger & enable modes and
+		 * disable interrupt for this TCS
+		 */
+		if (!drv->tcs[ACTIVE_TCS].num_tcs)
+			__tcs_set_trigger(drv, i, false);
 skip:
 		/* Reclaim the TCS */
 		write_tcs_reg(drv, RSC_DRV_CMD_ENABLE, i, 0);
 		write_tcs_reg(drv, RSC_DRV_CMD_WAIT_FOR_CMPL, i, 0);
-		write_tcs_reg(drv, RSC_DRV_IRQ_CLEAR, 0, BIT(i));
+		writel_relaxed(BIT(i), drv->tcs_base + RSC_DRV_IRQ_CLEAR);
 		spin_lock(&drv->lock);
 		clear_bit(i, drv->tcs_in_use);
+		/*
+		 * Disable interrupt for WAKE TCS to avoid being
+		 * spammed with interrupts coming when the solver
+		 * sends its wake votes.
+		 */
+		if (!drv->tcs[ACTIVE_TCS].num_tcs)
+			enable_tcs_irq(drv, i, false);
 		spin_unlock(&drv->lock);
 		if (req)
 			rpmh_tx_done(req, err);
@@ -252,6 +445,16 @@ static irqreturn_t tcs_tx_done(int irq, void *p)
 	return IRQ_HANDLED;
 }
 
+/**
+ * __tcs_buffer_write() - Write to TCS hardware from a request; don't trigger.
+ * @drv:    The controller.
+ * @tcs_id: The global ID of this TCS.
+ * @cmd_id: The index within the TCS to start writing.
+ * @msg:    The message we want to send, which will contain several addr/data
+ *          pairs to program (but few enough that they all fit in one TCS).
+ *
+ * This is used for all types of transfers (active, sleep, and wake).
+ */
 static void __tcs_buffer_write(struct rsc_drv *drv, int tcs_id, int cmd_id,
 			       const struct tcs_request *msg)
 {
@@ -265,7 +468,7 @@ static void __tcs_buffer_write(struct rsc_drv *drv, int tcs_id, int cmd_id,
 	cmd_msgid |= msg->wait_for_compl ? CMD_MSGID_RESP_REQ : 0;
 	cmd_msgid |= CMD_MSGID_WRITE;
 
-	cmd_complete = read_tcs_reg(drv, RSC_DRV_CMD_WAIT_FOR_CMPL, tcs_id, 0);
+	cmd_complete = read_tcs_reg(drv, RSC_DRV_CMD_WAIT_FOR_CMPL, tcs_id);
 
 	for (i = 0, j = cmd_id; i < msg->num_cmds; i++, j++) {
 		cmd = &msg->cmds[i];
@@ -281,32 +484,30 @@ static void __tcs_buffer_write(struct rsc_drv *drv, int tcs_id, int cmd_id,
 	}
 
 	write_tcs_reg(drv, RSC_DRV_CMD_WAIT_FOR_CMPL, tcs_id, cmd_complete);
-	cmd_enable |= read_tcs_reg(drv, RSC_DRV_CMD_ENABLE, tcs_id, 0);
+	cmd_enable |= read_tcs_reg(drv, RSC_DRV_CMD_ENABLE, tcs_id);
 	write_tcs_reg(drv, RSC_DRV_CMD_ENABLE, tcs_id, cmd_enable);
 }
 
-static void __tcs_trigger(struct rsc_drv *drv, int tcs_id)
-{
-	u32 enable;
-
-	/*
-	 * HW req: Clear the DRV_CONTROL and enable TCS again
-	 * While clearing ensure that the AMC mode trigger is cleared
-	 * and then the mode enable is cleared.
-	 */
-	enable = read_tcs_reg(drv, RSC_DRV_CONTROL, tcs_id, 0);
-	enable &= ~TCS_AMC_MODE_TRIGGER;
-	write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable);
-	enable &= ~TCS_AMC_MODE_ENABLE;
-	write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable);
-
-	/* Enable the AMC mode on the TCS and then trigger the TCS */
-	enable = TCS_AMC_MODE_ENABLE;
-	write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable);
-	enable |= TCS_AMC_MODE_TRIGGER;
-	write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable);
-}
-
+/**
+ * check_for_req_inflight() - Look to see if conflicting cmds are in flight.
+ * @drv: The controller.
+ * @tcs: A pointer to the tcs_group used for ACTIVE_ONLY transfers.
+ * @msg: The message we want to send, which will contain several addr/data
+ *       pairs to program (but few enough that they all fit in one TCS).
+ *
+ * This will walk through the TCSes in the group and check if any of them
+ * appear to be sending to addresses referenced in the message. If it finds
+ * one it'll return -EBUSY.
+ *
+ * Only for use for active-only transfers.
+ *
+ * Must be called with the drv->lock held since that protects tcs_in_use.
+ *
+ * Return: 0 if nothing in flight or -EBUSY if we should try again later.
+ *         The caller must re-enable interrupts between tries since that's
+ *         the only way tcs_is_free() will ever return true and the only way
+ *         RSC_DRV_CMD_ENABLE will ever be cleared.
+ */
 static int check_for_req_inflight(struct rsc_drv *drv, struct tcs_group *tcs,
 				  const struct tcs_request *msg)
 {
@@ -319,10 +520,10 @@ static int check_for_req_inflight(struct rsc_drv *drv, struct tcs_group *tcs,
 		if (tcs_is_free(drv, tcs_id))
 			continue;
 
-		curr_enabled = read_tcs_reg(drv, RSC_DRV_CMD_ENABLE, tcs_id, 0);
+		curr_enabled = read_tcs_reg(drv, RSC_DRV_CMD_ENABLE, tcs_id);
 
 		for_each_set_bit(j, &curr_enabled, MAX_CMDS_PER_TCS) {
-			addr = read_tcs_reg(drv, RSC_DRV_CMD_ADDR, tcs_id, j);
+			addr = read_tcs_cmd(drv, RSC_DRV_CMD_ADDR, tcs_id, j);
 			for (k = 0; k < msg->num_cmds; k++) {
 				if (addr == msg->cmds[k].addr)
 					return -EBUSY;
@@ -333,6 +534,15 @@ static int check_for_req_inflight(struct rsc_drv *drv, struct tcs_group *tcs,
 	return 0;
 }
 
+/**
+ * find_free_tcs() - Find free tcs in the given tcs_group; only for active.
+ * @tcs: A pointer to the active-only tcs_group (or the wake tcs_group if
+ *       we borrowed it because there are zero active-only ones).
+ *
+ * Must be called with the drv->lock held since that protects tcs_in_use.
+ *
+ * Return: The first tcs that's free.
+ */
 static int find_free_tcs(struct tcs_group *tcs)
 {
 	int i;
@@ -345,6 +555,20 @@ static int find_free_tcs(struct tcs_group *tcs)
 	return -EBUSY;
 }
 
+/**
+ * tcs_write() - Store messages into a TCS right now, or return -EBUSY.
+ * @drv: The controller.
+ * @msg: The data to be sent.
+ *
+ * Grabs a TCS for ACTIVE_ONLY transfers and writes the messages to it.
+ *
+ * If there are no free TCSes for ACTIVE_ONLY transfers or if a command for
+ * the same address is already transferring returns -EBUSY which means the
+ * client should retry shortly.
+ *
+ * Return: 0 on success, -EBUSY if client should retry, or an error.
+ *         Client should have interrupts enabled for a bit before retrying.
+ */
 static int tcs_write(struct rsc_drv *drv, const struct tcs_request *msg)
 {
 	struct tcs_group *tcs;
@@ -377,10 +601,20 @@ static int tcs_write(struct rsc_drv *drv, const struct tcs_request *msg)
 
 	tcs->req[tcs_id - tcs->offset] = msg;
 	set_bit(tcs_id, drv->tcs_in_use);
+	if (msg->state == RPMH_ACTIVE_ONLY_STATE && tcs->type != ACTIVE_TCS) {
+		/*
+		 * Clear previously programmed WAKE commands in selected
+		 * repurposed TCS to avoid triggering them. tcs->slots will be
+		 * cleaned from rpmh_flush() by invoking rpmh_rsc_invalidate()
+		 */
+		write_tcs_reg_sync(drv, RSC_DRV_CMD_ENABLE, tcs_id, 0);
+		write_tcs_reg_sync(drv, RSC_DRV_CMD_WAIT_FOR_CMPL, tcs_id, 0);
+		enable_tcs_irq(drv, tcs_id, true);
+	}
 	spin_unlock(&drv->lock);
 
 	__tcs_buffer_write(drv, tcs_id, 0, msg);
-	__tcs_trigger(drv, tcs_id);
+	__tcs_set_trigger(drv, tcs_id, true);
 
 done_write:
 	spin_unlock_irqrestore(&tcs->lock, flags);
@@ -388,25 +622,31 @@ static int tcs_write(struct rsc_drv *drv, const struct tcs_request *msg)
 }
 
 /**
- * rpmh_rsc_send_data: Validate the incoming message and write to the
- * appropriate TCS block.
+ * rpmh_rsc_send_data() - Write / trigger active-only message.
+ * @drv: The controller.
+ * @msg: The data to be sent.
  *
- * @drv: the controller
- * @msg: the data to be sent
+ * NOTES:
+ * - This is only used for "ACTIVE_ONLY" since the limitations of this
+ *   function don't make sense for sleep/wake cases.
+ * - To do the transfer, we will grab a whole TCS for ourselves--we don't
+ *   try to share. If there are none available we'll wait indefinitely
+ *   for a free one.
+ * - This function will not wait for the commands to be finished, only for
+ *   data to be programmed into the RPMh. See rpmh_tx_done() which will
+ *   be called when the transfer is fully complete.
+ * - This function must be called with interrupts enabled. If the hardware
+ *   is busy doing someone else's transfer we need that transfer to fully
+ *   finish so that we can have the hardware, and to fully finish it needs
+ *   the interrupt handler to run. If the interrupts is set to run on the
+ *   active CPU this can never happen if interrupts are disabled.
  *
  * Return: 0 on success, -EINVAL on error.
- * Note: This call blocks until a valid data is written to the TCS.
  */
 int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg)
 {
 	int ret;
 
-	if (!msg || !msg->cmds || !msg->num_cmds ||
-	    msg->num_cmds > MAX_RPMH_PAYLOAD) {
-		WARN_ON(1);
-		return -EINVAL;
-	}
-
 	do {
 		ret = tcs_write(drv, msg);
 		if (ret == -EBUSY) {
@@ -419,43 +659,30 @@ int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg)
 	return ret;
 }
 
-static int find_match(const struct tcs_group *tcs, const struct tcs_cmd *cmd,
-		      int len)
-{
-	int i, j;
-
-	/* Check for already cached commands */
-	for_each_set_bit(i, tcs->slots, MAX_TCS_SLOTS) {
-		if (tcs->cmd_cache[i] != cmd[0].addr)
-			continue;
-		if (i + len >= tcs->num_tcs * tcs->ncpt)
-			goto seq_err;
-		for (j = 0; j < len; j++) {
-			if (tcs->cmd_cache[i + j] != cmd[j].addr)
-				goto seq_err;
-		}
-		return i;
-	}
-
-	return -ENODATA;
-
-seq_err:
-	WARN(1, "Message does not match previous sequence.\n");
-	return -EINVAL;
-}
-
+/**
+ * find_slots() - Find a place to write the given message.
+ * @tcs:    The tcs group to search.
+ * @msg:    The message we want to find room for.
+ * @tcs_id: If we return 0 from the function, we return the global ID of the
+ *          TCS to write to here.
+ * @cmd_id: If we return 0 from the function, we return the index of
+ *          the command array of the returned TCS where the client should
+ *          start writing the message.
+ *
+ * Only for use on sleep/wake TCSes since those are the only ones we maintain
+ * tcs->slots for.
+ *
+ * Must be called with the tcs_lock for the group held.
+ *
+ * Return: -ENOMEM if there was no room, else 0.
+ */
 static int find_slots(struct tcs_group *tcs, const struct tcs_request *msg,
 		      int *tcs_id, int *cmd_id)
 {
 	int slot, offset;
 	int i = 0;
 
-	/* Find if we already have the msg in our TCS */
-	slot = find_match(tcs, msg->cmds, msg->num_cmds);
-	if (slot >= 0)
-		goto copy_data;
-
-	/* Do over, until we can fit the full payload in a TCS */
+	/* Do over, until we can fit the full payload in a single TCS */
 	do {
 		slot = bitmap_find_next_zero_area(tcs->slots, MAX_TCS_SLOTS,
 						  i, msg->num_cmds, 0);
@@ -464,11 +691,7 @@ static int find_slots(struct tcs_group *tcs, const struct tcs_request *msg,
 		i += tcs->ncpt;
 	} while (slot + msg->num_cmds - 1 >= i);
 
-copy_data:
 	bitmap_set(tcs->slots, slot, msg->num_cmds);
-	/* Copy the addresses of the resources over to the slots */
-	for (i = 0; i < msg->num_cmds; i++)
-		tcs->cmd_cache[slot + i] = msg->cmds[i].addr;
 
 	offset = slot / tcs->ncpt;
 	*tcs_id = offset + tcs->offset;
@@ -477,7 +700,17 @@ static int find_slots(struct tcs_group *tcs, const struct tcs_request *msg,
 	return 0;
 }
 
-static int tcs_ctrl_write(struct rsc_drv *drv, const struct tcs_request *msg)
+/**
+ * rpmh_rsc_write_ctrl_data() - Write request to controller but don't trigger.
+ * @drv: The controller.
+ * @msg: The data to be written to the controller.
+ *
+ * This should only be called for for sleep/wake state, never active-only
+ * state.
+ *
+ * Return: 0 if no error; else -error.
+ */
+int rpmh_rsc_write_ctrl_data(struct rsc_drv *drv, const struct tcs_request *msg)
 {
 	struct tcs_group *tcs;
 	int tcs_id = 0, cmd_id = 0;
@@ -499,30 +732,100 @@ static int tcs_ctrl_write(struct rsc_drv *drv, const struct tcs_request *msg)
 }
 
 /**
- * rpmh_rsc_write_ctrl_data: Write request to the controller
+ * rpmh_rsc_ctrlr_is_busy() - Check if any of the AMCs are busy.
+ * @drv: The controller
  *
- * @drv: the controller
- * @msg: the data to be written to the controller
+ * Checks if any of the AMCs are busy in handling ACTIVE sets.
+ * This is called from the last cpu powering down before flushing
+ * SLEEP and WAKE sets. If AMCs are busy, controller can not enter
+ * power collapse, so deny from the last cpu's pm notification.
  *
- * There is no response returned for writing the request to the controller.
+ * Return:
+ * * False		- AMCs are idle
+ * * True		- AMCs are busy
  */
-int rpmh_rsc_write_ctrl_data(struct rsc_drv *drv, const struct tcs_request *msg)
+static bool rpmh_rsc_ctrlr_is_busy(struct rsc_drv *drv)
 {
-	if (!msg || !msg->cmds || !msg->num_cmds ||
-	    msg->num_cmds > MAX_RPMH_PAYLOAD) {
-		pr_err("Payload error\n");
-		return -EINVAL;
+	int m;
+	struct tcs_group *tcs = &drv->tcs[ACTIVE_TCS];
+
+	/*
+	 * If we made an active request on a RSC that does not have a
+	 * dedicated TCS for active state use, then re-purposed wake TCSes
+	 * should be checked for not busy, because we used wake TCSes for
+	 * active requests in this case.
+	 *
+	 * Since this is called from the last cpu, need not take drv or tcs
+	 * lock before checking tcs_is_free().
+	 */
+	if (!tcs->num_tcs)
+		tcs = &drv->tcs[WAKE_TCS];
+
+	for (m = tcs->offset; m < tcs->offset + tcs->num_tcs; m++) {
+		if (!tcs_is_free(drv, m))
+			return true;
 	}
 
-	/* Data sent to this API will not be sent immediately */
-	if (msg->state == RPMH_ACTIVE_ONLY_STATE)
-		return -EINVAL;
+	return false;
+}
+
+/**
+ * rpmh_rsc_cpu_pm_callback() - Check if any of the AMCs are busy.
+ * @nfb:    Pointer to the notifier block in struct rsc_drv.
+ * @action: CPU_PM_ENTER, CPU_PM_ENTER_FAILED, or CPU_PM_EXIT.
+ * @v:      Unused
+ *
+ * This function is given to cpu_pm_register_notifier so we can be informed
+ * about when CPUs go down. When all CPUs go down we know no more active
+ * transfers will be started so we write sleep/wake sets. This function gets
+ * called from cpuidle code paths and also at system suspend time.
+ *
+ * If its last CPU going down and AMCs are not busy then writes cached sleep
+ * and wake messages to TCSes. The firmware then takes care of triggering
+ * them when entering deepest low power modes.
+ *
+ * Return: See cpu_pm_register_notifier()
+ */
+static int rpmh_rsc_cpu_pm_callback(struct notifier_block *nfb,
+				    unsigned long action, void *v)
+{
+	struct rsc_drv *drv = container_of(nfb, struct rsc_drv, rsc_pm);
+	int ret = NOTIFY_OK;
+
+	spin_lock(&drv->pm_lock);
 
-	return tcs_ctrl_write(drv, msg);
+	switch (action) {
+	case CPU_PM_ENTER:
+		cpumask_set_cpu(smp_processor_id(), &drv->cpus_entered_pm);
+
+		if (!cpumask_equal(&drv->cpus_entered_pm, cpu_online_mask))
+			goto exit;
+		break;
+	case CPU_PM_ENTER_FAILED:
+	case CPU_PM_EXIT:
+		cpumask_clear_cpu(smp_processor_id(), &drv->cpus_entered_pm);
+		goto exit;
+	}
+
+	ret = rpmh_rsc_ctrlr_is_busy(drv);
+	if (ret) {
+		ret = NOTIFY_BAD;
+		goto exit;
+	}
+
+	ret = rpmh_flush(&drv->client);
+	if (ret)
+		ret = NOTIFY_BAD;
+	else
+		ret = NOTIFY_OK;
+
+exit:
+	spin_unlock(&drv->pm_lock);
+	return ret;
 }
 
 static int rpmh_probe_tcs_config(struct platform_device *pdev,
-				 struct rsc_drv *drv)
+				 struct rsc_drv *drv, void __iomem *base)
 {
 	struct tcs_type_config {
 		u32 type;
@@ -532,15 +835,6 @@ static int rpmh_probe_tcs_config(struct platform_device *pdev,
 	u32 config, max_tcs, ncpt, offset;
 	int i, ret, n, st = 0;
 	struct tcs_group *tcs;
-	struct resource *res;
-	void __iomem *base;
-	char drv_id[10] = {0};
-
-	snprintf(drv_id, ARRAY_SIZE(drv_id), "drv-%d", drv->id);
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, drv_id);
-	base = devm_ioremap_resource(&pdev->dev, res);
-	if (IS_ERR(base))
-		return PTR_ERR(base);
 
 	ret = of_property_read_u32(dn, "qcom,tcs-offset", &offset);
 	if (ret)
@@ -596,19 +890,6 @@ static int rpmh_probe_tcs_config(struct platform_device *pdev,
 		tcs->mask = ((1 << tcs->num_tcs) - 1) << st;
 		tcs->offset = st;
 		st += tcs->num_tcs;
-
-		/*
-		 * Allocate memory to cache sleep and wake requests to
-		 * avoid reading TCS register memory.
-		 */
-		if (tcs->type == ACTIVE_TCS)
-			continue;
-
-		tcs->cmd_cache = devm_kcalloc(&pdev->dev,
-					      tcs->num_tcs * ncpt, sizeof(u32),
-					      GFP_KERNEL);
-		if (!tcs->cmd_cache)
-			return -ENOMEM;
 	}
 
 	drv->num_tcs = st;
@@ -620,7 +901,11 @@ static int rpmh_rsc_probe(struct platform_device *pdev)
 {
 	struct device_node *dn = pdev->dev.of_node;
 	struct rsc_drv *drv;
+	struct resource *res;
+	char drv_id[10] = {0};
 	int ret, irq;
+	u32 solver_config;
+	void __iomem *base;
 
 	/*
 	 * Even though RPMh doesn't directly use cmd-db, all of its children
@@ -646,7 +931,13 @@ static int rpmh_rsc_probe(struct platform_device *pdev)
 	if (!drv->name)
 		drv->name = dev_name(&pdev->dev);
 
-	ret = rpmh_probe_tcs_config(pdev, drv);
+	snprintf(drv_id, ARRAY_SIZE(drv_id), "drv-%d", drv->id);
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, drv_id);
+	base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	ret = rpmh_probe_tcs_config(pdev, drv, base);
 	if (ret)
 		return ret;
 
@@ -663,8 +954,23 @@ static int rpmh_rsc_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	/*
+	 * CPU PM notification are not required for controllers that support
+	 * 'HW solver' mode where they can be in autonomous mode executing low
+	 * power mode to power down.
+	 */
+	solver_config = readl_relaxed(base + DRV_SOLVER_CONFIG);
+	solver_config &= DRV_HW_SOLVER_MASK << DRV_HW_SOLVER_SHIFT;
+	solver_config = solver_config >> DRV_HW_SOLVER_SHIFT;
+	if (!solver_config) {
+		drv->rsc_pm.notifier_call = rpmh_rsc_cpu_pm_callback;
+		spin_lock_init(&drv->pm_lock);
+		cpu_pm_register_notifier(&drv->rsc_pm);
+	}
+
 	/* Enable the active TCS to send requests immediately */
-	write_tcs_reg(drv, RSC_DRV_IRQ_ENABLE, 0, drv->tcs[ACTIVE_TCS].mask);
+	writel_relaxed(drv->tcs[ACTIVE_TCS].mask,
+		       drv->tcs_base + RSC_DRV_IRQ_ENABLE);
 
 	spin_lock_init(&drv->client.cache_lock);
 	INIT_LIST_HEAD(&drv->client.cache);
diff --git a/drivers/soc/qcom/rpmh.c b/drivers/soc/qcom/rpmh.c
index eb0ded059d2e..3abbb08cd6e1 100644
--- a/drivers/soc/qcom/rpmh.c
+++ b/drivers/soc/qcom/rpmh.c
@@ -9,6 +9,7 @@
 #include <linux/jiffies.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
+#include <linux/lockdep.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
@@ -119,6 +120,7 @@ static struct cache_req *cache_rpm_request(struct rpmh_ctrlr *ctrlr,
 {
 	struct cache_req *req;
 	unsigned long flags;
+	u32 old_sleep_val, old_wake_val;
 
 	spin_lock_irqsave(&ctrlr->cache_lock, flags);
 	req = __find_req(ctrlr, cmd->addr);
@@ -133,26 +135,27 @@ static struct cache_req *cache_rpm_request(struct rpmh_ctrlr *ctrlr,
 
 	req->addr = cmd->addr;
 	req->sleep_val = req->wake_val = UINT_MAX;
-	INIT_LIST_HEAD(&req->list);
 	list_add_tail(&req->list, &ctrlr->cache);
 
 existing:
+	old_sleep_val = req->sleep_val;
+	old_wake_val = req->wake_val;
+
 	switch (state) {
 	case RPMH_ACTIVE_ONLY_STATE:
-		if (req->sleep_val != UINT_MAX)
-			req->wake_val = cmd->data;
-		break;
 	case RPMH_WAKE_ONLY_STATE:
 		req->wake_val = cmd->data;
 		break;
 	case RPMH_SLEEP_STATE:
 		req->sleep_val = cmd->data;
 		break;
-	default:
-		break;
 	}
 
-	ctrlr->dirty = true;
+	ctrlr->dirty = (req->sleep_val != old_sleep_val ||
+			req->wake_val != old_wake_val) &&
+			req->sleep_val != UINT_MAX &&
+			req->wake_val != UINT_MAX;
+
 unlock:
 	spin_unlock_irqrestore(&ctrlr->cache_lock, flags);
 
@@ -287,6 +290,7 @@ static void cache_batch(struct rpmh_ctrlr *ctrlr, struct batch_cache_req *req)
 
 	spin_lock_irqsave(&ctrlr->cache_lock, flags);
 	list_add_tail(&req->list, &ctrlr->batch_cache);
+	ctrlr->dirty = true;
 	spin_unlock_irqrestore(&ctrlr->cache_lock, flags);
 }
 
@@ -294,12 +298,10 @@ static int flush_batch(struct rpmh_ctrlr *ctrlr)
 {
 	struct batch_cache_req *req;
 	const struct rpmh_request *rpm_msg;
-	unsigned long flags;
 	int ret = 0;
 	int i;
 
 	/* Send Sleep/Wake requests to the controller, expect no response */
-	spin_lock_irqsave(&ctrlr->cache_lock, flags);
 	list_for_each_entry(req, &ctrlr->batch_cache, list) {
 		for (i = 0; i < req->count; i++) {
 			rpm_msg = req->rpm_msgs + i;
@@ -309,23 +311,10 @@ static int flush_batch(struct rpmh_ctrlr *ctrlr)
 				break;
 		}
 	}
-	spin_unlock_irqrestore(&ctrlr->cache_lock, flags);
 
 	return ret;
 }
 
-static void invalidate_batch(struct rpmh_ctrlr *ctrlr)
-{
-	struct batch_cache_req *req, *tmp;
-	unsigned long flags;
-
-	spin_lock_irqsave(&ctrlr->cache_lock, flags);
-	list_for_each_entry_safe(req, tmp, &ctrlr->batch_cache, list)
-		kfree(req);
-	INIT_LIST_HEAD(&ctrlr->batch_cache);
-	spin_unlock_irqrestore(&ctrlr->cache_lock, flags);
-}
-
 /**
  * rpmh_write_batch: Write multiple sets of RPMH commands and wait for the
  * batch to finish.
@@ -442,36 +431,37 @@ static int send_single(struct rpmh_ctrlr *ctrlr, enum rpmh_state state,
 }
 
 /**
- * rpmh_flush: Flushes the buffered active and sleep sets to TCS
+ * rpmh_flush() - Flushes the buffered sleep and wake sets to TCSes
  *
- * @ctrlr: controller making request to flush cached data
+ * @ctrlr: Controller making request to flush cached data
  *
- * Return: -EBUSY if the controller is busy, probably waiting on a response
- * to a RPMH request sent earlier.
+ * This function is called from sleep code on the last CPU
+ * (thus no spinlock needed).
  *
- * This function is always called from the sleep code from the last CPU
- * that is powering down the entire system. Since no other RPMH API would be
- * executing at this time, it is safe to run lockless.
+ * Return:
+ * * 0          - Success
+ * * Error code - Otherwise
  */
 int rpmh_flush(struct rpmh_ctrlr *ctrlr)
 {
 	struct cache_req *p;
 	int ret;
 
+	lockdep_assert_irqs_disabled();
+
 	if (!ctrlr->dirty) {
 		pr_debug("Skipping flush, TCS has latest data.\n");
 		return 0;
 	}
 
+	/* Invalidate the TCSes first to avoid stale data */
+	rpmh_rsc_invalidate(ctrlr_to_drv(ctrlr));
+
 	/* First flush the cached batch requests */
 	ret = flush_batch(ctrlr);
 	if (ret)
 		return ret;
 
-	/*
-	 * Nobody else should be calling this function other than system PM,
-	 * hence we can run without locks.
-	 */
 	list_for_each_entry(p, &ctrlr->cache, list) {
 		if (!is_req_valid(p)) {
 			pr_debug("%s: skipping RPMH req: a:%#x s:%#x w:%#x",
@@ -494,25 +484,25 @@ int rpmh_flush(struct rpmh_ctrlr *ctrlr)
 }
 
 /**
- * rpmh_invalidate: Invalidate all sleep and active sets
- * sets.
+ * rpmh_invalidate: Invalidate sleep and wake sets in batch_cache
  *
  * @dev: The device making the request
  *
- * Invalidate the sleep and active values in the TCS blocks.
+ * Invalidate the sleep and wake values in batch_cache.
  */
 int rpmh_invalidate(const struct device *dev)
 {
 	struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(dev);
-	int ret;
+	struct batch_cache_req *req, *tmp;
+	unsigned long flags;
 
-	invalidate_batch(ctrlr);
+	spin_lock_irqsave(&ctrlr->cache_lock, flags);
+	list_for_each_entry_safe(req, tmp, &ctrlr->batch_cache, list)
+		kfree(req);
+	INIT_LIST_HEAD(&ctrlr->batch_cache);
 	ctrlr->dirty = true;
+	spin_unlock_irqrestore(&ctrlr->cache_lock, flags);
 
-	do {
-		ret = rpmh_rsc_invalidate(ctrlr_to_drv(ctrlr));
-	} while (ret == -EAGAIN);
-
-	return ret;
+	return 0;
 }
 EXPORT_SYMBOL(rpmh_invalidate);
diff --git a/drivers/soc/qcom/rpmhpd.c b/drivers/soc/qcom/rpmhpd.c
index 4d264d0672c4..0bb12d5870a7 100644
--- a/drivers/soc/qcom/rpmhpd.c
+++ b/drivers/soc/qcom/rpmhpd.c
@@ -4,6 +4,7 @@
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/pm_domain.h>
 #include <linux/slab.h>
@@ -189,6 +190,7 @@ static const struct of_device_id rpmhpd_match_table[] = {
 	{ .compatible = "qcom,sm8150-rpmhpd", .data = &sm8150_desc },
 	{ }
 };
+MODULE_DEVICE_TABLE(of, rpmhpd_match_table);
 
 static int rpmhpd_send_corner(struct rpmhpd *pd, int state,
 			      unsigned int corner, bool sync)
@@ -460,3 +462,6 @@ static int __init rpmhpd_init(void)
 	return platform_driver_register(&rpmhpd_driver);
 }
 core_initcall(rpmhpd_init);
+
+MODULE_DESCRIPTION("Qualcomm Technologies, Inc. RPMh Power Domain Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/soc/qcom/rpmpd.c b/drivers/soc/qcom/rpmpd.c
index 2b1834c5609a..f2168e4259b2 100644
--- a/drivers/soc/qcom/rpmpd.c
+++ b/drivers/soc/qcom/rpmpd.c
@@ -4,6 +4,7 @@
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/pm_domain.h>
 #include <linux/of.h>
@@ -226,6 +227,7 @@ static const struct of_device_id rpmpd_match_table[] = {
 	{ .compatible = "qcom,qcs404-rpmpd", .data = &qcs404_desc },
 	{ }
 };
+MODULE_DEVICE_TABLE(of, rpmpd_match_table);
 
 static int rpmpd_send_enable(struct rpmpd *pd, bool enable)
 {
@@ -422,3 +424,6 @@ static int __init rpmpd_init(void)
 	return platform_driver_register(&rpmpd_driver);
 }
 core_initcall(rpmpd_init);
+
+MODULE_DESCRIPTION("Qualcomm Technologies, Inc. RPM Power Domain Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/soc/qcom/smp2p.c b/drivers/soc/qcom/smp2p.c
index c7300d54e444..07183d731d74 100644
--- a/drivers/soc/qcom/smp2p.c
+++ b/drivers/soc/qcom/smp2p.c
@@ -474,10 +474,8 @@ static int qcom_smp2p_probe(struct platform_device *pdev)
 		goto report_read_failure;
 
 	irq = platform_get_irq(pdev, 0);
-	if (irq < 0) {
-		dev_err(&pdev->dev, "unable to acquire smp2p interrupt\n");
+	if (irq < 0)
 		return irq;
-	}
 
 	smp2p->mbox_client.dev = &pdev->dev;
 	smp2p->mbox_client.knows_txdone = true;
diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c
index ebb49aee179b..08a4b8ae1764 100644
--- a/drivers/soc/qcom/socinfo.c
+++ b/drivers/soc/qcom/socinfo.c
@@ -430,6 +430,8 @@ static int qcom_socinfo_probe(struct platform_device *pdev)
 	qs->attr.family = "Snapdragon";
 	qs->attr.machine = socinfo_machine(&pdev->dev,
 					   le32_to_cpu(info->id));
+	qs->attr.soc_id = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%u",
+					 le32_to_cpu(info->id));
 	qs->attr.revision = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%u.%u",
 					   SOCINFO_MAJOR(le32_to_cpu(info->ver)),
 					   SOCINFO_MINOR(le32_to_cpu(info->ver)));
diff --git a/drivers/spi/spi-axi-spi-engine.c b/drivers/spi/spi-axi-spi-engine.c
index eb9b78a90dcf..af86e6d6e16b 100644
--- a/drivers/spi/spi-axi-spi-engine.c
+++ b/drivers/spi/spi-axi-spi-engine.c
@@ -489,22 +489,6 @@ static int spi_engine_probe(struct platform_device *pdev)
 
 	spin_lock_init(&spi_engine->lock);
 
-	spi_engine->base = devm_platform_ioremap_resource(pdev, 0);
-	if (IS_ERR(spi_engine->base)) {
-		ret = PTR_ERR(spi_engine->base);
-		goto err_put_master;
-	}
-
-	version = readl(spi_engine->base + SPI_ENGINE_REG_VERSION);
-	if (SPI_ENGINE_VERSION_MAJOR(version) != 1) {
-		dev_err(&pdev->dev, "Unsupported peripheral version %u.%u.%c\n",
-			SPI_ENGINE_VERSION_MAJOR(version),
-			SPI_ENGINE_VERSION_MINOR(version),
-			SPI_ENGINE_VERSION_PATCH(version));
-		ret = -ENODEV;
-		goto err_put_master;
-	}
-
 	spi_engine->clk = devm_clk_get(&pdev->dev, "s_axi_aclk");
 	if (IS_ERR(spi_engine->clk)) {
 		ret = PTR_ERR(spi_engine->clk);
@@ -525,6 +509,22 @@ static int spi_engine_probe(struct platform_device *pdev)
 	if (ret)
 		goto err_clk_disable;
 
+	spi_engine->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(spi_engine->base)) {
+		ret = PTR_ERR(spi_engine->base);
+		goto err_ref_clk_disable;
+	}
+
+	version = readl(spi_engine->base + SPI_ENGINE_REG_VERSION);
+	if (SPI_ENGINE_VERSION_MAJOR(version) != 1) {
+		dev_err(&pdev->dev, "Unsupported peripheral version %u.%u.%c\n",
+			SPI_ENGINE_VERSION_MAJOR(version),
+			SPI_ENGINE_VERSION_MINOR(version),
+			SPI_ENGINE_VERSION_PATCH(version));
+		ret = -ENODEV;
+		goto err_ref_clk_disable;
+	}
+
 	writel_relaxed(0x00, spi_engine->base + SPI_ENGINE_REG_RESET);
 	writel_relaxed(0xff, spi_engine->base + SPI_ENGINE_REG_INT_PENDING);
 	writel_relaxed(0x00, spi_engine->base + SPI_ENGINE_REG_INT_ENABLE);
diff --git a/drivers/spi/spi-ep93xx.c b/drivers/spi/spi-ep93xx.c
index 4e1ccd4e52b6..8c854b187b1d 100644
--- a/drivers/spi/spi-ep93xx.c
+++ b/drivers/spi/spi-ep93xx.c
@@ -31,7 +31,8 @@
 #include <linux/platform_data/spi-ep93xx.h>
 
 #define SSPCR0			0x0000
-#define SSPCR0_MODE_SHIFT	6
+#define SSPCR0_SPO		BIT(6)
+#define SSPCR0_SPH		BIT(7)
 #define SSPCR0_SCR_SHIFT	8
 
 #define SSPCR1			0x0004
@@ -159,7 +160,10 @@ static int ep93xx_spi_chip_setup(struct spi_master *master,
 		return err;
 
 	cr0 = div_scr << SSPCR0_SCR_SHIFT;
-	cr0 |= (spi->mode & (SPI_CPHA | SPI_CPOL)) << SSPCR0_MODE_SHIFT;
+	if (spi->mode & SPI_CPOL)
+		cr0 |= SSPCR0_SPO;
+	if (spi->mode & SPI_CPHA)
+		cr0 |= SSPCR0_SPH;
 	cr0 |= dss;
 
 	dev_dbg(&master->dev, "setup: mode %d, cpsr %d, scr %d, dss %d\n",
diff --git a/drivers/spi/spi-fsl-lpspi.c b/drivers/spi/spi-fsl-lpspi.c
index 8b41b70f6f5c..511211b82430 100644
--- a/drivers/spi/spi-fsl-lpspi.c
+++ b/drivers/spi/spi-fsl-lpspi.c
@@ -186,14 +186,13 @@ static bool fsl_lpspi_can_dma(struct spi_controller *controller,
 
 	bytes_per_word = fsl_lpspi_bytes_per_word(transfer->bits_per_word);
 
-	switch (bytes_per_word)
-	{
-		case 1:
-		case 2:
-		case 4:
-			break;
-		default:
-			return false;
+	switch (bytes_per_word) {
+	case 1:
+	case 2:
+	case 4:
+		break;
+	default:
+		return false;
 	}
 
 	return true;
diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c
index 3b81772fea0d..67f022b8c81d 100644
--- a/drivers/spi/spi-fsl-spi.c
+++ b/drivers/spi/spi-fsl-spi.c
@@ -588,7 +588,7 @@ static void fsl_spi_grlib_probe(struct device *dev)
 	pdata->cs_control = fsl_spi_grlib_cs_control;
 }
 
-static struct spi_master * fsl_spi_probe(struct device *dev,
+static struct spi_master *fsl_spi_probe(struct device *dev,
 		struct resource *mem, unsigned int irq)
 {
 	struct fsl_spi_platform_data *pdata = dev_get_platdata(dev);
diff --git a/drivers/spi/spi-mtk-nor.c b/drivers/spi/spi-mtk-nor.c
index c15a9910549f..7bc302b50396 100644
--- a/drivers/spi/spi-mtk-nor.c
+++ b/drivers/spi/spi-mtk-nor.c
@@ -391,7 +391,7 @@ static int mtk_nor_pp_unbuffered(struct mtk_nor *sp,
 	return mtk_nor_cmd_exec(sp, MTK_NOR_CMD_WRITE, 6 * BITS_PER_BYTE);
 }
 
-int mtk_nor_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
+static int mtk_nor_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
 {
 	struct mtk_nor *sp = spi_controller_get_devdata(mem->spi->master);
 	int ret;
diff --git a/drivers/spi/spi-sc18is602.c b/drivers/spi/spi-sc18is602.c
index 5497eeb3bf3e..ee0f3edf49cd 100644
--- a/drivers/spi/spi-sc18is602.c
+++ b/drivers/spi/spi-sc18is602.c
@@ -345,6 +345,6 @@ static struct i2c_driver sc18is602_driver = {
 
 module_i2c_driver(sc18is602_driver);
 
-MODULE_DESCRIPTION("SC18IC602/603 SPI Master Driver");
+MODULE_DESCRIPTION("SC18IS602/603 SPI Master Driver");
 MODULE_AUTHOR("Guenter Roeck");
 MODULE_LICENSE("GPL");
diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c
index 1c11a00a2c36..b2579af0e3eb 100644
--- a/drivers/spi/spi-sh-msiof.c
+++ b/drivers/spi/spi-sh-msiof.c
@@ -1398,7 +1398,7 @@ static int sh_msiof_spi_resume(struct device *dev)
 
 static SIMPLE_DEV_PM_OPS(sh_msiof_spi_pm_ops, sh_msiof_spi_suspend,
 			 sh_msiof_spi_resume);
-#define DEV_PM_OPS	&sh_msiof_spi_pm_ops
+#define DEV_PM_OPS	(&sh_msiof_spi_pm_ops)
 #else
 #define DEV_PM_OPS	NULL
 #endif /* CONFIG_PM_SLEEP */
diff --git a/drivers/spi/spi-sprd-adi.c b/drivers/spi/spi-sprd-adi.c
index 87dadb6b8ebf..88e6543648cb 100644
--- a/drivers/spi/spi-sprd-adi.c
+++ b/drivers/spi/spi-sprd-adi.c
@@ -319,7 +319,7 @@ static int sprd_adi_transfer_one(struct spi_controller *ctlr,
 
 static void sprd_adi_set_wdt_rst_mode(struct sprd_adi *sadi)
 {
-#ifdef CONFIG_SPRD_WATCHDOG
+#if IS_ENABLED(CONFIG_SPRD_WATCHDOG)
 	u32 val;
 
 	/* Set default watchdog reboot mode */
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index c92c89467e7e..c083ee3995e4 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -1075,7 +1075,7 @@ static int spi_transfer_wait(struct spi_controller *ctlr,
 {
 	struct spi_statistics *statm = &ctlr->statistics;
 	struct spi_statistics *stats = &msg->spi->statistics;
-	unsigned long long ms = 1;
+	unsigned long long ms;
 
 	if (spi_controller_is_slave(ctlr)) {
 		if (wait_for_completion_interruptible(&ctlr->xfer_completion)) {
@@ -2111,6 +2111,7 @@ static int acpi_spi_add_resource(struct acpi_resource *ares, void *data)
 			}
 
 			lookup->max_speed_hz = sb->connection_speed;
+			lookup->bits_per_word = sb->data_bit_length;
 
 			if (sb->clock_phase == ACPI_SPI_SECOND_PHASE)
 				lookup->mode |= SPI_CPHA;
diff --git a/drivers/staging/android/ion/ion_page_pool.c b/drivers/staging/android/ion/ion_page_pool.c
index f85ec5b16b65..0198b886d906 100644
--- a/drivers/staging/android/ion/ion_page_pool.c
+++ b/drivers/staging/android/ion/ion_page_pool.c
@@ -37,7 +37,7 @@ static void ion_page_pool_add(struct ion_page_pool *pool, struct page *page)
 	}
 
 	mod_node_page_state(page_pgdat(page), NR_KERNEL_MISC_RECLAIMABLE,
-							1 << pool->order);
+			    1 << pool->order);
 	mutex_unlock(&pool->mutex);
 }
 
@@ -57,7 +57,7 @@ static struct page *ion_page_pool_remove(struct ion_page_pool *pool, bool high)
 
 	list_del(&page->lru);
 	mod_node_page_state(page_pgdat(page), NR_KERNEL_MISC_RECLAIMABLE,
-							-(1 << pool->order));
+			    -(1 << pool->order));
 	return page;
 }
 
diff --git a/drivers/staging/axis-fifo/axis-fifo.c b/drivers/staging/axis-fifo/axis-fifo.c
index 5801067e7c1b..2bb1c2e9cb57 100644
--- a/drivers/staging/axis-fifo/axis-fifo.c
+++ b/drivers/staging/axis-fifo/axis-fifo.c
@@ -383,8 +383,9 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf,
 		mutex_lock(&fifo->read_lock);
 		ret = wait_event_interruptible_timeout(fifo->read_queue,
 			ioread32(fifo->base_addr + XLLF_RDFO_OFFSET),
-			(read_timeout >= 0) ? msecs_to_jiffies(read_timeout) :
-				MAX_SCHEDULE_TIMEOUT);
+				 (read_timeout >= 0) ?
+				  msecs_to_jiffies(read_timeout) :
+				  MAX_SCHEDULE_TIMEOUT);
 
 		if (ret <= 0) {
 			if (ret == 0) {
@@ -525,9 +526,10 @@ static ssize_t axis_fifo_write(struct file *f, const char __user *buf,
 		mutex_lock(&fifo->write_lock);
 		ret = wait_event_interruptible_timeout(fifo->write_queue,
 			ioread32(fifo->base_addr + XLLF_TDFV_OFFSET)
-				>= words_to_write,
-			(write_timeout >= 0) ? msecs_to_jiffies(write_timeout) :
-				MAX_SCHEDULE_TIMEOUT);
+				 >= words_to_write,
+				 (write_timeout >= 0) ?
+				  msecs_to_jiffies(write_timeout) :
+				  MAX_SCHEDULE_TIMEOUT);
 
 		if (ret <= 0) {
 			if (ret == 0) {
diff --git a/drivers/staging/comedi/comedi_internal.h b/drivers/staging/comedi/comedi_internal.h
index 515f293a5d26..1d54a0dba347 100644
--- a/drivers/staging/comedi/comedi_internal.h
+++ b/drivers/staging/comedi/comedi_internal.h
@@ -32,8 +32,8 @@ void comedi_buf_map_get(struct comedi_buf_map *bm);
 int comedi_buf_map_put(struct comedi_buf_map *bm);
 int comedi_buf_map_access(struct comedi_buf_map *bm, unsigned long offset,
 			  void *buf, int len, int write);
-struct comedi_buf_map *comedi_buf_map_from_subdev_get(
-		struct comedi_subdevice *s);
+struct comedi_buf_map *
+comedi_buf_map_from_subdev_get(struct comedi_subdevice *s);
 unsigned int comedi_buf_write_n_available(struct comedi_subdevice *s);
 unsigned int comedi_buf_write_n_allocated(struct comedi_subdevice *s);
 void comedi_device_cancel_all(struct comedi_device *dev);
diff --git a/drivers/staging/comedi/drivers/dt2815.c b/drivers/staging/comedi/drivers/dt2815.c
index 83026ba63d1c..78a7c1b3448a 100644
--- a/drivers/staging/comedi/drivers/dt2815.c
+++ b/drivers/staging/comedi/drivers/dt2815.c
@@ -92,6 +92,7 @@ static int dt2815_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
 	int ret;
 
 	for (i = 0; i < insn->n; i++) {
+		/* FIXME: lo bit 0 chooses voltage output or current output */
 		lo = ((data[i] & 0x0f) << 4) | (chan << 1) | 0x01;
 		hi = (data[i] & 0xff0) >> 4;
 
@@ -105,6 +106,8 @@ static int dt2815_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
 		if (ret)
 			return ret;
 
+		outb(hi, dev->iobase + DT2815_DATA);
+
 		devpriv->ao_readback[chan] = data[i];
 	}
 	return i;
diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
index 676d1ad1b50d..546ad376df99 100644
--- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
+++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
@@ -1094,7 +1094,8 @@ static int swdev_port_obj_del(struct net_device *netdev,
 
 static int
 ethsw_switchdev_port_attr_set_event(struct net_device *netdev,
-		struct switchdev_notifier_port_attr_info *port_attr_info)
+				    struct switchdev_notifier_port_attr_info
+				    *port_attr_info)
 {
 	int err;
 
@@ -1277,7 +1278,8 @@ static int port_switchdev_event(struct notifier_block *unused,
 
 static int
 ethsw_switchdev_port_obj_event(unsigned long event, struct net_device *netdev,
-			struct switchdev_notifier_port_obj_info *port_obj_info)
+			       struct switchdev_notifier_port_obj_info
+			       *port_obj_info)
 {
 	int err = -EOPNOTSUPP;
 
diff --git a/drivers/staging/gasket/gasket_sysfs.c b/drivers/staging/gasket/gasket_sysfs.c
index a2d67c28f530..5f0e089573a2 100644
--- a/drivers/staging/gasket/gasket_sysfs.c
+++ b/drivers/staging/gasket/gasket_sysfs.c
@@ -228,8 +228,7 @@ int gasket_sysfs_create_entries(struct device *device,
 	}
 
 	mutex_lock(&mapping->mutex);
-	for (i = 0; strcmp(attrs[i].attr.attr.name, GASKET_ARRAY_END_MARKER);
-		i++) {
+	for (i = 0; attrs[i].attr.attr.name != NULL; i++) {
 		if (mapping->attribute_count == GASKET_SYSFS_MAX_NODES) {
 			dev_err(device,
 				"Maximum number of sysfs nodes reached for device\n");
diff --git a/drivers/staging/gasket/gasket_sysfs.h b/drivers/staging/gasket/gasket_sysfs.h
index 1d0eed66a7f4..ab5aa351d555 100644
--- a/drivers/staging/gasket/gasket_sysfs.h
+++ b/drivers/staging/gasket/gasket_sysfs.h
@@ -30,10 +30,6 @@
  */
 #define GASKET_SYSFS_MAX_NODES 196
 
-/* End markers for sysfs struct arrays. */
-#define GASKET_ARRAY_END_TOKEN GASKET_RESERVED_ARRAY_END
-#define GASKET_ARRAY_END_MARKER __stringify(GASKET_ARRAY_END_TOKEN)
-
 /*
  * Terminator struct for a gasket_sysfs_attr array. Must be at the end of
  * all gasket_sysfs_attribute arrays.
diff --git a/drivers/staging/gdm724x/gdm_lte.c b/drivers/staging/gdm724x/gdm_lte.c
index 354727f0a1fc..eb309190f5be 100644
--- a/drivers/staging/gdm724x/gdm_lte.c
+++ b/drivers/staging/gdm724x/gdm_lte.c
@@ -172,7 +172,7 @@ static int gdm_lte_emulate_arp(struct sk_buff *skb_in, u32 nic_type)
 
 static __sum16 icmp6_checksum(struct ipv6hdr *ipv6, u16 *ptr, int len)
 {
-	unsigned short *w = ptr;
+	unsigned short *w;
 	__wsum sum = 0;
 	int i;
 	u16 pa;
diff --git a/drivers/staging/greybus/hid.c b/drivers/staging/greybus/hid.c
index 04bfd9110502..ed706f39e87a 100644
--- a/drivers/staging/greybus/hid.c
+++ b/drivers/staging/greybus/hid.c
@@ -290,9 +290,8 @@ static int gb_hid_parse(struct hid_device *hid)
 	}
 
 	rdesc = kzalloc(rsize, GFP_KERNEL);
-	if (!rdesc) {
+	if (!rdesc)
 		return -ENOMEM;
-	}
 
 	ret = gb_hid_get_report_desc(ghid, rdesc);
 	if (ret) {
diff --git a/drivers/staging/greybus/light.c b/drivers/staging/greybus/light.c
index d6ba25f21d80..d2672b65c3f4 100644
--- a/drivers/staging/greybus/light.c
+++ b/drivers/staging/greybus/light.c
@@ -1026,7 +1026,8 @@ static int gb_lights_light_config(struct gb_lights *glights, u8 id)
 
 	light->channels_count = conf.channel_count;
 	light->name = kstrndup(conf.name, NAMES_MAX, GFP_KERNEL);
-
+	if (!light->name)
+		return -ENOMEM;
 	light->channels = kcalloc(light->channels_count,
 				  sizeof(struct gb_channel), GFP_KERNEL);
 	if (!light->channels)
diff --git a/drivers/staging/media/hantro/Kconfig b/drivers/staging/media/hantro/Kconfig
index 99aed9a5b0b9..68e5b06cdab7 100644
--- a/drivers/staging/media/hantro/Kconfig
+++ b/drivers/staging/media/hantro/Kconfig
@@ -2,8 +2,9 @@
 config VIDEO_HANTRO
 	tristate "Hantro VPU driver"
 	depends on ARCH_MXC || ARCH_ROCKCHIP || COMPILE_TEST
-	depends on VIDEO_DEV && VIDEO_V4L2 && MEDIA_CONTROLLER
-	depends on MEDIA_CONTROLLER_REQUEST_API
+	depends on VIDEO_DEV && VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select MEDIA_CONTROLLER_REQUEST_API
 	select VIDEOBUF2_DMA_CONTIG
 	select VIDEOBUF2_VMALLOC
 	select V4L2_MEM2MEM_DEV
diff --git a/drivers/staging/media/hantro/Makefile b/drivers/staging/media/hantro/Makefile
index 68c29a9c4946..743ce08eb184 100644
--- a/drivers/staging/media/hantro/Makefile
+++ b/drivers/staging/media/hantro/Makefile
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
 obj-$(CONFIG_VIDEO_HANTRO) += hantro-vpu.o
 
 hantro-vpu-y += \
diff --git a/drivers/staging/media/hantro/hantro.h b/drivers/staging/media/hantro/hantro.h
index 327ddef45345..3005207fc6fb 100644
--- a/drivers/staging/media/hantro/hantro.h
+++ b/drivers/staging/media/hantro/hantro.h
@@ -26,10 +26,6 @@
 
 #include "hantro_hw.h"
 
-#define MB_DIM			16
-#define MB_WIDTH(w)		DIV_ROUND_UP(w, MB_DIM)
-#define MB_HEIGHT(h)		DIV_ROUND_UP(h, MB_DIM)
-
 struct hantro_ctx;
 struct hantro_codec_ops;
 
@@ -421,7 +417,8 @@ hantro_get_dst_buf(struct hantro_ctx *ctx)
 }
 
 static inline bool
-hantro_needs_postproc(struct hantro_ctx *ctx, const struct hantro_fmt *fmt)
+hantro_needs_postproc(const struct hantro_ctx *ctx,
+		      const struct hantro_fmt *fmt)
 {
 	return !hantro_is_encoder_ctx(ctx) && fmt->fourcc != V4L2_PIX_FMT_NV12;
 }
diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c
index ace13973e2d0..0db8ad455160 100644
--- a/drivers/staging/media/hantro/hantro_drv.c
+++ b/drivers/staging/media/hantro/hantro_drv.c
@@ -80,15 +80,6 @@ hantro_enc_buf_finish(struct hantro_ctx *ctx, struct vb2_buffer *buf,
 	return 0;
 }
 
-static int
-hantro_dec_buf_finish(struct hantro_ctx *ctx, struct vb2_buffer *buf,
-		      unsigned int bytesused)
-{
-	/* For decoders set bytesused as per the output picture. */
-	buf->planes[0].bytesused = ctx->dst_fmt.plane_fmt[0].sizeimage;
-	return 0;
-}
-
 static void hantro_job_finish(struct hantro_dev *vpu,
 			      struct hantro_ctx *ctx,
 			      unsigned int bytesused,
@@ -101,8 +92,8 @@ static void hantro_job_finish(struct hantro_dev *vpu,
 	pm_runtime_put_autosuspend(vpu->dev);
 	clk_bulk_disable(vpu->variant->num_clocks, vpu->clocks);
 
-	src = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
-	dst = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
+	src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
+	dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
 
 	if (WARN_ON(!src))
 		return;
@@ -112,14 +103,14 @@ static void hantro_job_finish(struct hantro_dev *vpu,
 	src->sequence = ctx->sequence_out++;
 	dst->sequence = ctx->sequence_cap++;
 
-	ret = ctx->buf_finish(ctx, &dst->vb2_buf, bytesused);
-	if (ret)
-		result = VB2_BUF_STATE_ERROR;
-
-	v4l2_m2m_buf_done(src, result);
-	v4l2_m2m_buf_done(dst, result);
+	if (ctx->buf_finish) {
+		ret = ctx->buf_finish(ctx, &dst->vb2_buf, bytesused);
+		if (ret)
+			result = VB2_BUF_STATE_ERROR;
+	}
 
-	v4l2_m2m_job_finish(vpu->m2m_dev, ctx->fh.m2m_ctx);
+	v4l2_m2m_buf_done_and_job_finish(ctx->dev->m2m_dev, ctx->fh.m2m_ctx,
+					 result);
 }
 
 void hantro_irq_done(struct hantro_dev *vpu, unsigned int bytesused,
@@ -431,7 +422,6 @@ static int hantro_open(struct file *filp)
 		ctx->buf_finish = hantro_enc_buf_finish;
 	} else if (func->id == MEDIA_ENT_F_PROC_VIDEO_DECODER) {
 		allowed_codecs = vpu->variant->codec & HANTRO_DECODERS;
-		ctx->buf_finish = hantro_dec_buf_finish;
 	} else {
 		ret = -ENODEV;
 		goto err_ctx_free;
diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h
index 7dfc9bad7297..4053d8710e04 100644
--- a/drivers/staging/media/hantro/hantro_hw.h
+++ b/drivers/staging/media/hantro/hantro_hw.h
@@ -18,6 +18,10 @@
 
 #define DEC_8190_ALIGN_MASK	0x07U
 
+#define MB_DIM			16
+#define MB_WIDTH(w)		DIV_ROUND_UP(w, MB_DIM)
+#define MB_HEIGHT(h)		DIV_ROUND_UP(h, MB_DIM)
+
 struct hantro_dev;
 struct hantro_ctx;
 struct hantro_buf;
@@ -176,6 +180,33 @@ void hantro_g1_h264_dec_run(struct hantro_ctx *ctx);
 int hantro_h264_dec_init(struct hantro_ctx *ctx);
 void hantro_h264_dec_exit(struct hantro_ctx *ctx);
 
+static inline size_t
+hantro_h264_mv_size(unsigned int width, unsigned int height)
+{
+	/*
+	 * A decoded 8-bit 4:2:0 NV12 frame may need memory for up to
+	 * 448 bytes per macroblock with additional 32 bytes on
+	 * multi-core variants.
+	 *
+	 * The H264 decoder needs extra space on the output buffers
+	 * to store motion vectors. This is needed for reference
+	 * frames and only if the format is non-post-processed NV12.
+	 *
+	 * Memory layout is as follow:
+	 *
+	 * +---------------------------+
+	 * | Y-plane   256 bytes x MBs |
+	 * +---------------------------+
+	 * | UV-plane  128 bytes x MBs |
+	 * +---------------------------+
+	 * | MV buffer  64 bytes x MBs |
+	 * +---------------------------+
+	 * | MC sync          32 bytes |
+	 * +---------------------------+
+	 */
+	return 64 * MB_WIDTH(width) * MB_WIDTH(height) + 32;
+}
+
 void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx);
 void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx);
 void hantro_mpeg2_dec_copy_qtable(u8 *qtable,
diff --git a/drivers/staging/media/hantro/hantro_v4l2.c b/drivers/staging/media/hantro/hantro_v4l2.c
index f4ae2cee0f18..f28a94e2fa93 100644
--- a/drivers/staging/media/hantro/hantro_v4l2.c
+++ b/drivers/staging/media/hantro/hantro_v4l2.c
@@ -30,6 +30,11 @@
 #include "hantro_hw.h"
 #include "hantro_v4l2.h"
 
+static int hantro_set_fmt_out(struct hantro_ctx *ctx,
+			      struct v4l2_pix_format_mplane *pix_mp);
+static int hantro_set_fmt_cap(struct hantro_ctx *ctx,
+			      struct v4l2_pix_format_mplane *pix_mp);
+
 static const struct hantro_fmt *
 hantro_get_formats(const struct hantro_ctx *ctx, unsigned int *num_fmts)
 {
@@ -227,12 +232,12 @@ static int vidioc_g_fmt_cap_mplane(struct file *file, void *priv,
 	return 0;
 }
 
-static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f,
-			  bool capture)
+static int hantro_try_fmt(const struct hantro_ctx *ctx,
+			  struct v4l2_pix_format_mplane *pix_mp,
+			  enum v4l2_buf_type type)
 {
-	struct hantro_ctx *ctx = fh_to_ctx(priv);
-	struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
 	const struct hantro_fmt *fmt, *vpu_fmt;
+	bool capture = !V4L2_TYPE_IS_OUTPUT(type);
 	bool coded;
 
 	coded = capture == hantro_is_encoder_ctx(ctx);
@@ -246,7 +251,7 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f,
 	fmt = hantro_find_format(ctx, pix_mp->pixelformat);
 	if (!fmt) {
 		fmt = hantro_get_default_fmt(ctx, coded);
-		f->fmt.pix_mp.pixelformat = fmt->fourcc;
+		pix_mp->pixelformat = fmt->fourcc;
 	}
 
 	if (coded) {
@@ -273,32 +278,11 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f,
 		/* Fill remaining fields */
 		v4l2_fill_pixfmt_mp(pix_mp, fmt->fourcc, pix_mp->width,
 				    pix_mp->height);
-		/*
-		 * A decoded 8-bit 4:2:0 NV12 frame may need memory for up to
-		 * 448 bytes per macroblock with additional 32 bytes on
-		 * multi-core variants.
-		 *
-		 * The H264 decoder needs extra space on the output buffers
-		 * to store motion vectors. This is needed for reference
-		 * frames and only if the format is non-post-processed NV12.
-		 *
-		 * Memory layout is as follow:
-		 *
-		 * +---------------------------+
-		 * | Y-plane   256 bytes x MBs |
-		 * +---------------------------+
-		 * | UV-plane  128 bytes x MBs |
-		 * +---------------------------+
-		 * | MV buffer  64 bytes x MBs |
-		 * +---------------------------+
-		 * | MC sync          32 bytes |
-		 * +---------------------------+
-		 */
 		if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_H264_SLICE &&
 		    !hantro_needs_postproc(ctx, fmt))
 			pix_mp->plane_fmt[0].sizeimage +=
-				64 * MB_WIDTH(pix_mp->width) *
-				     MB_WIDTH(pix_mp->height) + 32;
+				hantro_h264_mv_size(pix_mp->width,
+						    pix_mp->height);
 	} else if (!pix_mp->plane_fmt[0].sizeimage) {
 		/*
 		 * For coded formats the application can specify
@@ -315,13 +299,13 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f,
 static int vidioc_try_fmt_cap_mplane(struct file *file, void *priv,
 				     struct v4l2_format *f)
 {
-	return vidioc_try_fmt(file, priv, f, true);
+	return hantro_try_fmt(fh_to_ctx(priv), &f->fmt.pix_mp, f->type);
 }
 
 static int vidioc_try_fmt_out_mplane(struct file *file, void *priv,
 				     struct v4l2_format *f)
 {
-	return vidioc_try_fmt(file, priv, f, false);
+	return hantro_try_fmt(fh_to_ctx(priv), &f->fmt.pix_mp, f->type);
 }
 
 static void
@@ -355,11 +339,12 @@ hantro_reset_encoded_fmt(struct hantro_ctx *ctx)
 	}
 
 	hantro_reset_fmt(fmt, vpu_fmt);
-	fmt->num_planes = 1;
 	fmt->width = vpu_fmt->frmsize.min_width;
 	fmt->height = vpu_fmt->frmsize.min_height;
-	fmt->plane_fmt[0].sizeimage = vpu_fmt->header_size +
-				fmt->width * fmt->height * vpu_fmt->max_depth;
+	if (hantro_is_encoder_ctx(ctx))
+		hantro_set_fmt_cap(ctx, fmt);
+	else
+		hantro_set_fmt_out(ctx, fmt);
 }
 
 static void
@@ -381,9 +366,12 @@ hantro_reset_raw_fmt(struct hantro_ctx *ctx)
 	}
 
 	hantro_reset_fmt(raw_fmt, raw_vpu_fmt);
-	v4l2_fill_pixfmt_mp(raw_fmt, raw_vpu_fmt->fourcc,
-			    encoded_fmt->width,
-			    encoded_fmt->height);
+	raw_fmt->width = encoded_fmt->width;
+	raw_fmt->width = encoded_fmt->width;
+	if (hantro_is_encoder_ctx(ctx))
+		hantro_set_fmt_out(ctx, raw_fmt);
+	else
+		hantro_set_fmt_cap(ctx, raw_fmt);
 }
 
 void hantro_reset_fmts(struct hantro_ctx *ctx)
@@ -409,15 +397,15 @@ hantro_update_requires_request(struct hantro_ctx *ctx, u32 fourcc)
 	}
 }
 
-static int
-vidioc_s_fmt_out_mplane(struct file *file, void *priv, struct v4l2_format *f)
+static int hantro_set_fmt_out(struct hantro_ctx *ctx,
+			      struct v4l2_pix_format_mplane *pix_mp)
 {
-	struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
-	struct hantro_ctx *ctx = fh_to_ctx(priv);
-	struct vb2_queue *vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
+	struct vb2_queue *vq;
 	int ret;
 
-	ret = vidioc_try_fmt_out_mplane(file, priv, f);
+	vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
+			     V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+	ret = hantro_try_fmt(ctx, pix_mp, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
 	if (ret)
 		return ret;
 
@@ -479,16 +467,15 @@ vidioc_s_fmt_out_mplane(struct file *file, void *priv, struct v4l2_format *f)
 	return 0;
 }
 
-static int vidioc_s_fmt_cap_mplane(struct file *file, void *priv,
-				   struct v4l2_format *f)
+static int hantro_set_fmt_cap(struct hantro_ctx *ctx,
+			      struct v4l2_pix_format_mplane *pix_mp)
 {
-	struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
-	struct hantro_ctx *ctx = fh_to_ctx(priv);
 	struct vb2_queue *vq;
 	int ret;
 
 	/* Change not allowed if queue is busy. */
-	vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
+	vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
+			     V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
 	if (vb2_is_busy(vq))
 		return -EBUSY;
 
@@ -509,7 +496,7 @@ static int vidioc_s_fmt_cap_mplane(struct file *file, void *priv,
 			return -EBUSY;
 	}
 
-	ret = vidioc_try_fmt_cap_mplane(file, priv, f);
+	ret = hantro_try_fmt(ctx, pix_mp, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
 	if (ret)
 		return ret;
 
@@ -543,6 +530,18 @@ static int vidioc_s_fmt_cap_mplane(struct file *file, void *priv,
 	return 0;
 }
 
+static int
+vidioc_s_fmt_out_mplane(struct file *file, void *priv, struct v4l2_format *f)
+{
+	return hantro_set_fmt_out(fh_to_ctx(priv), &f->fmt.pix_mp);
+}
+
+static int
+vidioc_s_fmt_cap_mplane(struct file *file, void *priv, struct v4l2_format *f)
+{
+	return hantro_set_fmt_cap(fh_to_ctx(priv), &f->fmt.pix_mp);
+}
+
 const struct v4l2_ioctl_ops hantro_ioctl_ops = {
 	.vidioc_querycap = vidioc_querycap,
 	.vidioc_enum_framesizes = vidioc_enum_framesizes,
@@ -608,7 +607,7 @@ hantro_queue_setup(struct vb2_queue *vq, unsigned int *num_buffers,
 }
 
 static int
-hantro_buf_plane_check(struct vb2_buffer *vb, const struct hantro_fmt *vpu_fmt,
+hantro_buf_plane_check(struct vb2_buffer *vb,
 		       struct v4l2_pix_format_mplane *pixfmt)
 {
 	unsigned int sz;
@@ -630,12 +629,18 @@ static int hantro_buf_prepare(struct vb2_buffer *vb)
 {
 	struct vb2_queue *vq = vb->vb2_queue;
 	struct hantro_ctx *ctx = vb2_get_drv_priv(vq);
+	struct v4l2_pix_format_mplane *pix_fmt;
+	int ret;
 
 	if (V4L2_TYPE_IS_OUTPUT(vq->type))
-		return hantro_buf_plane_check(vb, ctx->vpu_src_fmt,
-						  &ctx->src_fmt);
-
-	return hantro_buf_plane_check(vb, ctx->vpu_dst_fmt, &ctx->dst_fmt);
+		pix_fmt = &ctx->src_fmt;
+	else
+		pix_fmt = &ctx->dst_fmt;
+	ret = hantro_buf_plane_check(vb, pix_fmt);
+	if (ret)
+		return ret;
+	vb2_set_plane_payload(vb, 0, pix_fmt->plane_fmt[0].sizeimage);
+	return 0;
 }
 
 static void hantro_buf_queue(struct vb2_buffer *vb)
diff --git a/drivers/staging/media/imx/Kconfig b/drivers/staging/media/imx/Kconfig
index 8f1ae50a4abd..f555aac8a9d5 100644
--- a/drivers/staging/media/imx/Kconfig
+++ b/drivers/staging/media/imx/Kconfig
@@ -2,8 +2,9 @@
 config VIDEO_IMX_MEDIA
 	tristate "i.MX5/6 V4L2 media core driver"
 	depends on ARCH_MXC || COMPILE_TEST
-	depends on MEDIA_CONTROLLER && VIDEO_V4L2 && IMX_IPUV3_CORE
-	depends on VIDEO_V4L2_SUBDEV_API
+	depends on VIDEO_V4L2 && IMX_IPUV3_CORE
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	depends on HAS_DMA
 	select VIDEOBUF2_DMA_CONTIG
 	select V4L2_FWNODE
diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c
index fbc1a924652a..e2403b448b6d 100644
--- a/drivers/staging/media/imx/imx7-mipi-csis.c
+++ b/drivers/staging/media/imx/imx7-mipi-csis.c
@@ -14,32 +14,29 @@
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
-#include <linux/irq.h>
 #include <linux/kernel.h>
-#include <linux/mfd/syscon.h>
 #include <linux/module.h>
-#include <linux/of_graph.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
-#include <linux/reset.h>
 #include <linux/regulator/consumer.h>
+#include <linux/reset.h>
 #include <linux/spinlock.h>
 
 #include <media/v4l2-device.h>
 #include <media/v4l2-fwnode.h>
 #include <media/v4l2-subdev.h>
 
-#include "imx-media.h"
+#define CSIS_DRIVER_NAME			"imx7-mipi-csis"
+#define CSIS_SUBDEV_NAME			CSIS_DRIVER_NAME
 
-#define CSIS_DRIVER_NAME	"imx7-mipi-csis"
-#define CSIS_SUBDEV_NAME	CSIS_DRIVER_NAME
+#define CSIS_PAD_SINK				0
+#define CSIS_PAD_SOURCE				1
+#define CSIS_PADS_NUM				2
 
-#define CSIS_PAD_SINK		0
-#define CSIS_PAD_SOURCE		1
-#define CSIS_PADS_NUM		2
-
-#define MIPI_CSIS_DEF_PIX_WIDTH		640
-#define MIPI_CSIS_DEF_PIX_HEIGHT	480
+#define MIPI_CSIS_DEF_PIX_WIDTH			640
+#define MIPI_CSIS_DEF_PIX_HEIGHT		480
 
 /* Register map definition */
 
@@ -64,42 +61,42 @@
 #define MIPI_CSIS_CLK_CTRL_WCLK_SRC		BIT(0)
 
 /* CSIS Interrupt mask */
-#define MIPI_CSIS_INTMSK		0x10
-#define MIPI_CSIS_INTMSK_EVEN_BEFORE	BIT(31)
-#define MIPI_CSIS_INTMSK_EVEN_AFTER	BIT(30)
-#define MIPI_CSIS_INTMSK_ODD_BEFORE	BIT(29)
-#define MIPI_CSIS_INTMSK_ODD_AFTER	BIT(28)
-#define MIPI_CSIS_INTMSK_FRAME_START	BIT(24)
-#define MIPI_CSIS_INTMSK_FRAME_END	BIT(20)
-#define MIPI_CSIS_INTMSK_ERR_SOT_HS	BIT(16)
-#define MIPI_CSIS_INTMSK_ERR_LOST_FS	BIT(12)
-#define MIPI_CSIS_INTMSK_ERR_LOST_FE	BIT(8)
-#define MIPI_CSIS_INTMSK_ERR_OVER	BIT(4)
-#define MIPI_CSIS_INTMSK_ERR_WRONG_CFG	BIT(3)
-#define MIPI_CSIS_INTMSK_ERR_ECC	BIT(2)
-#define MIPI_CSIS_INTMSK_ERR_CRC	BIT(1)
-#define MIPI_CSIS_INTMSK_ERR_UNKNOWN	BIT(0)
+#define MIPI_CSIS_INTMSK			0x10
+#define MIPI_CSIS_INTMSK_EVEN_BEFORE		BIT(31)
+#define MIPI_CSIS_INTMSK_EVEN_AFTER		BIT(30)
+#define MIPI_CSIS_INTMSK_ODD_BEFORE		BIT(29)
+#define MIPI_CSIS_INTMSK_ODD_AFTER		BIT(28)
+#define MIPI_CSIS_INTMSK_FRAME_START		BIT(24)
+#define MIPI_CSIS_INTMSK_FRAME_END		BIT(20)
+#define MIPI_CSIS_INTMSK_ERR_SOT_HS		BIT(16)
+#define MIPI_CSIS_INTMSK_ERR_LOST_FS		BIT(12)
+#define MIPI_CSIS_INTMSK_ERR_LOST_FE		BIT(8)
+#define MIPI_CSIS_INTMSK_ERR_OVER		BIT(4)
+#define MIPI_CSIS_INTMSK_ERR_WRONG_CFG		BIT(3)
+#define MIPI_CSIS_INTMSK_ERR_ECC		BIT(2)
+#define MIPI_CSIS_INTMSK_ERR_CRC		BIT(1)
+#define MIPI_CSIS_INTMSK_ERR_UNKNOWN		BIT(0)
 
 /* CSIS Interrupt source */
-#define MIPI_CSIS_INTSRC		0x14
-#define MIPI_CSIS_INTSRC_EVEN_BEFORE	BIT(31)
-#define MIPI_CSIS_INTSRC_EVEN_AFTER	BIT(30)
-#define MIPI_CSIS_INTSRC_EVEN		BIT(30)
-#define MIPI_CSIS_INTSRC_ODD_BEFORE	BIT(29)
-#define MIPI_CSIS_INTSRC_ODD_AFTER	BIT(28)
-#define MIPI_CSIS_INTSRC_ODD		(0x3 << 28)
-#define MIPI_CSIS_INTSRC_NON_IMAGE_DATA	(0xf << 28)
-#define MIPI_CSIS_INTSRC_FRAME_START	BIT(24)
-#define MIPI_CSIS_INTSRC_FRAME_END	BIT(20)
-#define MIPI_CSIS_INTSRC_ERR_SOT_HS	BIT(16)
-#define MIPI_CSIS_INTSRC_ERR_LOST_FS	BIT(12)
-#define MIPI_CSIS_INTSRC_ERR_LOST_FE	BIT(8)
-#define MIPI_CSIS_INTSRC_ERR_OVER	BIT(4)
-#define MIPI_CSIS_INTSRC_ERR_WRONG_CFG	BIT(3)
-#define MIPI_CSIS_INTSRC_ERR_ECC	BIT(2)
-#define MIPI_CSIS_INTSRC_ERR_CRC	BIT(1)
-#define MIPI_CSIS_INTSRC_ERR_UNKNOWN	BIT(0)
-#define MIPI_CSIS_INTSRC_ERRORS		0xfffff
+#define MIPI_CSIS_INTSRC			0x14
+#define MIPI_CSIS_INTSRC_EVEN_BEFORE		BIT(31)
+#define MIPI_CSIS_INTSRC_EVEN_AFTER		BIT(30)
+#define MIPI_CSIS_INTSRC_EVEN			BIT(30)
+#define MIPI_CSIS_INTSRC_ODD_BEFORE		BIT(29)
+#define MIPI_CSIS_INTSRC_ODD_AFTER		BIT(28)
+#define MIPI_CSIS_INTSRC_ODD			(0x3 << 28)
+#define MIPI_CSIS_INTSRC_NON_IMAGE_DATA		(0xf << 28)
+#define MIPI_CSIS_INTSRC_FRAME_START		BIT(24)
+#define MIPI_CSIS_INTSRC_FRAME_END		BIT(20)
+#define MIPI_CSIS_INTSRC_ERR_SOT_HS		BIT(16)
+#define MIPI_CSIS_INTSRC_ERR_LOST_FS		BIT(12)
+#define MIPI_CSIS_INTSRC_ERR_LOST_FE		BIT(8)
+#define MIPI_CSIS_INTSRC_ERR_OVER		BIT(4)
+#define MIPI_CSIS_INTSRC_ERR_WRONG_CFG		BIT(3)
+#define MIPI_CSIS_INTSRC_ERR_ECC		BIT(2)
+#define MIPI_CSIS_INTSRC_ERR_CRC		BIT(1)
+#define MIPI_CSIS_INTSRC_ERR_UNKNOWN		BIT(0)
+#define MIPI_CSIS_INTSRC_ERRORS			0xfffff
 
 /* D-PHY status control */
 #define MIPI_CSIS_DPHYSTATUS			0x20
@@ -121,19 +118,19 @@
 #define MIPI_CSIS_DPHYCTRL_ENABLE		(0x1f << 0)
 
 /* D-PHY Master and Slave Control register Low */
-#define MIPI_CSIS_DPHYBCTRL_L		0x30
+#define MIPI_CSIS_DPHYBCTRL_L			0x30
 /* D-PHY Master and Slave Control register High */
-#define MIPI_CSIS_DPHYBCTRL_H		0x34
+#define MIPI_CSIS_DPHYBCTRL_H			0x34
 /* D-PHY Slave Control register Low */
-#define MIPI_CSIS_DPHYSCTRL_L		0x38
+#define MIPI_CSIS_DPHYSCTRL_L			0x38
 /* D-PHY Slave Control register High */
-#define MIPI_CSIS_DPHYSCTRL_H		0x3c
+#define MIPI_CSIS_DPHYSCTRL_H			0x3c
 
 /* ISP Configuration register */
-#define MIPI_CSIS_ISPCONFIG_CH0		0x40
-#define MIPI_CSIS_ISPCONFIG_CH1		0x50
-#define MIPI_CSIS_ISPCONFIG_CH2		0x60
-#define MIPI_CSIS_ISPCONFIG_CH3		0x70
+#define MIPI_CSIS_ISPCONFIG_CH0			0x40
+#define MIPI_CSIS_ISPCONFIG_CH1			0x50
+#define MIPI_CSIS_ISPCONFIG_CH2			0x60
+#define MIPI_CSIS_ISPCONFIG_CH3			0x70
 
 #define MIPI_CSIS_ISPCFG_MEM_FULL_GAP_MSK	(0xff << 24)
 #define MIPI_CSIS_ISPCFG_MEM_FULL_GAP(x)	((x) << 24)
@@ -143,35 +140,36 @@
 #define MIPI_CSIS_ISPCFG_FMT_RAW8		(0x2a << 2)
 #define MIPI_CSIS_ISPCFG_FMT_RAW10		(0x2b << 2)
 #define MIPI_CSIS_ISPCFG_FMT_RAW12		(0x2c << 2)
+#define MIPI_CSIS_ISPCFG_FMT_RAW14		(0x2d << 2)
 
 /* User defined formats, x = 1...4 */
-#define MIPI_CSIS_ISPCFG_FMT_USER(x)	((0x30 + (x) - 1) << 2)
-#define MIPI_CSIS_ISPCFG_FMT_MASK	(0x3f << 2)
+#define MIPI_CSIS_ISPCFG_FMT_USER(x)		((0x30 + (x) - 1) << 2)
+#define MIPI_CSIS_ISPCFG_FMT_MASK		(0x3f << 2)
 
 /* ISP Image Resolution register */
-#define MIPI_CSIS_ISPRESOL_CH0		0x44
-#define MIPI_CSIS_ISPRESOL_CH1		0x54
-#define MIPI_CSIS_ISPRESOL_CH2		0x64
-#define MIPI_CSIS_ISPRESOL_CH3		0x74
-#define CSIS_MAX_PIX_WIDTH		0xffff
-#define CSIS_MAX_PIX_HEIGHT		0xffff
+#define MIPI_CSIS_ISPRESOL_CH0			0x44
+#define MIPI_CSIS_ISPRESOL_CH1			0x54
+#define MIPI_CSIS_ISPRESOL_CH2			0x64
+#define MIPI_CSIS_ISPRESOL_CH3			0x74
+#define CSIS_MAX_PIX_WIDTH			0xffff
+#define CSIS_MAX_PIX_HEIGHT			0xffff
 
 /* ISP SYNC register */
-#define MIPI_CSIS_ISPSYNC_CH0		0x48
-#define MIPI_CSIS_ISPSYNC_CH1		0x58
-#define MIPI_CSIS_ISPSYNC_CH2		0x68
-#define MIPI_CSIS_ISPSYNC_CH3		0x78
+#define MIPI_CSIS_ISPSYNC_CH0			0x48
+#define MIPI_CSIS_ISPSYNC_CH1			0x58
+#define MIPI_CSIS_ISPSYNC_CH2			0x68
+#define MIPI_CSIS_ISPSYNC_CH3			0x78
 
 #define MIPI_CSIS_ISPSYNC_HSYNC_LINTV_OFFSET	18
 #define MIPI_CSIS_ISPSYNC_VSYNC_SINTV_OFFSET	12
 #define MIPI_CSIS_ISPSYNC_VSYNC_EINTV_OFFSET	0
 
 /* Non-image packet data buffers */
-#define MIPI_CSIS_PKTDATA_ODD		0x2000
-#define MIPI_CSIS_PKTDATA_EVEN		0x3000
-#define MIPI_CSIS_PKTDATA_SIZE		SZ_4K
+#define MIPI_CSIS_PKTDATA_ODD			0x2000
+#define MIPI_CSIS_PKTDATA_EVEN			0x3000
+#define MIPI_CSIS_PKTDATA_SIZE			SZ_4K
 
-#define DEFAULT_SCLK_CSIS_FREQ		166000000UL
+#define DEFAULT_SCLK_CSIS_FREQ			166000000UL
 
 enum {
 	ST_POWERED	= 1,
@@ -253,45 +251,102 @@ struct csi_state {
 
 	struct csis_hw_reset hw_reset;
 	struct regulator *mipi_phy_regulator;
-	bool sink_linked;
 };
 
 struct csis_pix_format {
-	unsigned int pix_width_alignment;
 	u32 code;
 	u32 fmt_reg;
-	u8 data_alignment;
+	u8 width;
 };
 
 static const struct csis_pix_format mipi_csis_formats[] = {
+	/* YUV formats. */
 	{
-		.code = MEDIA_BUS_FMT_SBGGR10_1X10,
-		.fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW10,
-		.data_alignment = 16,
-	}, {
-		.code = MEDIA_BUS_FMT_VYUY8_2X8,
+		.code = MEDIA_BUS_FMT_UYVY8_2X8,
 		.fmt_reg = MIPI_CSIS_ISPCFG_FMT_YCBCR422_8BIT,
-		.data_alignment = 16,
+		.width = 8,
 	}, {
+		.code = MEDIA_BUS_FMT_UYVY10_2X10,
+		.fmt_reg = MIPI_CSIS_ISPCFG_FMT_YCBCR422_8BIT,
+		.width = 10,
+	},
+	/* RAW (Bayer and greyscale) formats. */
+	{
 		.code = MEDIA_BUS_FMT_SBGGR8_1X8,
 		.fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW8,
-		.data_alignment = 8,
+		.width = 8,
 	}, {
-		.code = MEDIA_BUS_FMT_YUYV8_2X8,
-		.fmt_reg = MIPI_CSIS_ISPCFG_FMT_YCBCR422_8BIT,
-		.data_alignment = 16,
+		.code = MEDIA_BUS_FMT_SGBRG8_1X8,
+		.fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW8,
+		.width = 8,
+	}, {
+		.code = MEDIA_BUS_FMT_SGRBG8_1X8,
+		.fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW8,
+		.width = 8,
+	}, {
+		.code = MEDIA_BUS_FMT_SRGGB8_1X8,
+		.fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW8,
+		.width = 8,
 	}, {
 		.code = MEDIA_BUS_FMT_Y8_1X8,
 		.fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW8,
-		.data_alignment = 8,
+		.width = 8,
+	}, {
+		.code = MEDIA_BUS_FMT_SBGGR10_1X10,
+		.fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW10,
+		.width = 10,
+	}, {
+		.code = MEDIA_BUS_FMT_SGBRG10_1X10,
+		.fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW10,
+		.width = 10,
+	}, {
+		.code = MEDIA_BUS_FMT_SGRBG10_1X10,
+		.fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW10,
+		.width = 10,
+	}, {
+		.code = MEDIA_BUS_FMT_SRGGB10_1X10,
+		.fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW10,
+		.width = 10,
 	}, {
 		.code = MEDIA_BUS_FMT_Y10_1X10,
 		.fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW10,
-		.data_alignment = 16,
+		.width = 10,
+	}, {
+		.code = MEDIA_BUS_FMT_SBGGR12_1X12,
+		.fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW12,
+		.width = 12,
+	}, {
+		.code = MEDIA_BUS_FMT_SGBRG12_1X12,
+		.fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW12,
+		.width = 12,
+	}, {
+		.code = MEDIA_BUS_FMT_SGRBG12_1X12,
+		.fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW12,
+		.width = 12,
+	}, {
+		.code = MEDIA_BUS_FMT_SRGGB12_1X12,
+		.fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW12,
+		.width = 12,
 	}, {
 		.code = MEDIA_BUS_FMT_Y12_1X12,
 		.fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW12,
-		.data_alignment = 16,
+		.width = 12,
+	}, {
+		.code = MEDIA_BUS_FMT_SBGGR14_1X14,
+		.fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW14,
+		.width = 14,
+	}, {
+		.code = MEDIA_BUS_FMT_SGBRG14_1X14,
+		.fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW14,
+		.width = 14,
+	}, {
+		.code = MEDIA_BUS_FMT_SGRBG14_1X14,
+		.fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW14,
+		.width = 14,
+	}, {
+		.code = MEDIA_BUS_FMT_SRGGB14_1X14,
+		.fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW14,
+		.width = 14,
 	}
 };
 
@@ -405,7 +460,8 @@ static void __mipi_csis_set_format(struct csi_state *state)
 
 	/* Color format */
 	val = mipi_csis_read(state, MIPI_CSIS_ISPCONFIG_CH0);
-	val = (val & ~MIPI_CSIS_ISPCFG_FMT_MASK) | state->csis_fmt->fmt_reg;
+	val &= ~(MIPI_CSIS_ISPCFG_ALIGN_32BIT | MIPI_CSIS_ISPCFG_FMT_MASK);
+	val |= state->csis_fmt->fmt_reg;
 	mipi_csis_write(state, MIPI_CSIS_ISPCONFIG_CH0, val);
 
 	/* Pixel resolution */
@@ -437,13 +493,6 @@ static void mipi_csis_set_params(struct csi_state *state)
 
 	mipi_csis_set_hsync_settle(state, state->hs_settle);
 
-	val = mipi_csis_read(state, MIPI_CSIS_ISPCONFIG_CH0);
-	if (state->csis_fmt->data_alignment == 32)
-		val |= MIPI_CSIS_ISPCFG_ALIGN_32BIT;
-	else
-		val &= ~MIPI_CSIS_ISPCFG_ALIGN_32BIT;
-	mipi_csis_write(state, MIPI_CSIS_ISPCONFIG_CH0, val);
-
 	val = (0 << MIPI_CSIS_ISPSYNC_HSYNC_LINTV_OFFSET) |
 		(0 << MIPI_CSIS_ISPSYNC_VSYNC_SINTV_OFFSET) |
 		(0 << MIPI_CSIS_ISPSYNC_VSYNC_EINTV_OFFSET);
@@ -622,17 +671,7 @@ static int mipi_csis_link_setup(struct media_entity *entity,
 
 	mutex_lock(&state->lock);
 
-	if (local_pad->flags & MEDIA_PAD_FL_SOURCE) {
-		if (flags & MEDIA_LNK_FL_ENABLED) {
-			if (state->sink_linked) {
-				ret = -EBUSY;
-				goto out;
-			}
-			state->sink_linked = true;
-		} else {
-			state->sink_linked = false;
-		}
-	} else {
+	if (local_pad->flags & MEDIA_PAD_FL_SINK) {
 		if (flags & MEDIA_LNK_FL_ENABLED) {
 			if (state->src_sd) {
 				ret = -EBUSY;
@@ -649,48 +688,6 @@ static int mipi_csis_link_setup(struct media_entity *entity,
 	return ret;
 }
 
-static int mipi_csis_init_cfg(struct v4l2_subdev *mipi_sd,
-			      struct v4l2_subdev_pad_config *cfg)
-{
-	struct v4l2_mbus_framefmt *mf;
-	unsigned int i;
-	int ret;
-
-	for (i = 0; i < CSIS_PADS_NUM; i++) {
-		mf = v4l2_subdev_get_try_format(mipi_sd, cfg, i);
-
-		ret = imx_media_init_mbus_fmt(mf, MIPI_CSIS_DEF_PIX_HEIGHT,
-					      MIPI_CSIS_DEF_PIX_WIDTH, 0,
-					      V4L2_FIELD_NONE, NULL);
-		if (ret < 0)
-			return ret;
-	}
-
-	return 0;
-}
-
-static struct csis_pix_format const *
-mipi_csis_try_format(struct v4l2_subdev *mipi_sd, struct v4l2_mbus_framefmt *mf)
-{
-	struct csi_state *state = mipi_sd_to_csis_state(mipi_sd);
-	struct csis_pix_format const *csis_fmt;
-
-	csis_fmt = find_csis_format(mf->code);
-	if (!csis_fmt)
-		csis_fmt = &mipi_csis_formats[0];
-
-	v4l_bound_align_image(&mf->width, 1, CSIS_MAX_PIX_WIDTH,
-			      csis_fmt->pix_width_alignment,
-			      &mf->height, 1, CSIS_MAX_PIX_HEIGHT, 1,
-			      0);
-
-	state->format_mbus.code = csis_fmt->code;
-	state->format_mbus.width = mf->width;
-	state->format_mbus.height = mf->height;
-
-	return csis_fmt;
-}
-
 static struct v4l2_mbus_framefmt *
 mipi_csis_get_format(struct csi_state *state,
 		     struct v4l2_subdev_pad_config *cfg,
@@ -703,53 +700,160 @@ mipi_csis_get_format(struct csi_state *state,
 	return &state->format_mbus;
 }
 
-static int mipi_csis_set_fmt(struct v4l2_subdev *mipi_sd,
+static int mipi_csis_init_cfg(struct v4l2_subdev *mipi_sd,
+			      struct v4l2_subdev_pad_config *cfg)
+{
+	struct csi_state *state = mipi_sd_to_csis_state(mipi_sd);
+	struct v4l2_mbus_framefmt *fmt_sink;
+	struct v4l2_mbus_framefmt *fmt_source;
+	enum v4l2_subdev_format_whence which;
+
+	which = cfg ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
+	fmt_sink = mipi_csis_get_format(state, cfg, which, CSIS_PAD_SINK);
+
+	fmt_sink->code = MEDIA_BUS_FMT_UYVY8_2X8;
+	fmt_sink->width = MIPI_CSIS_DEF_PIX_WIDTH;
+	fmt_sink->height = MIPI_CSIS_DEF_PIX_HEIGHT;
+	fmt_sink->field = V4L2_FIELD_NONE;
+
+	fmt_sink->colorspace = V4L2_COLORSPACE_SMPTE170M;
+	fmt_sink->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt_sink->colorspace);
+	fmt_sink->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt_sink->colorspace);
+	fmt_sink->quantization =
+		V4L2_MAP_QUANTIZATION_DEFAULT(false, fmt_sink->colorspace,
+					      fmt_sink->ycbcr_enc);
+
+	/*
+	 * When called from mipi_csis_subdev_init() to initialize the active
+	 * configuration, cfg is NULL, which indicates there's no source pad
+	 * configuration to set.
+	 */
+	if (!cfg)
+		return 0;
+
+	fmt_source = mipi_csis_get_format(state, cfg, which, CSIS_PAD_SOURCE);
+	*fmt_source = *fmt_sink;
+
+	return 0;
+}
+
+static int mipi_csis_get_fmt(struct v4l2_subdev *mipi_sd,
 			     struct v4l2_subdev_pad_config *cfg,
 			     struct v4l2_subdev_format *sdformat)
 {
 	struct csi_state *state = mipi_sd_to_csis_state(mipi_sd);
-	struct csis_pix_format const *csis_fmt;
 	struct v4l2_mbus_framefmt *fmt;
 
-	if (sdformat->pad >= CSIS_PADS_NUM)
-		return -EINVAL;
-
+	mutex_lock(&state->lock);
 	fmt = mipi_csis_get_format(state, cfg, sdformat->which, sdformat->pad);
+	sdformat->format = *fmt;
+	mutex_unlock(&state->lock);
 
-	mutex_lock(&state->lock);
-	if (sdformat->pad == CSIS_PAD_SOURCE) {
-		sdformat->format = *fmt;
-		goto unlock;
-	}
+	return 0;
+}
 
-	csis_fmt = mipi_csis_try_format(mipi_sd, &sdformat->format);
+static int mipi_csis_enum_mbus_code(struct v4l2_subdev *mipi_sd,
+				    struct v4l2_subdev_pad_config *cfg,
+				    struct v4l2_subdev_mbus_code_enum *code)
+{
+	struct csi_state *state = mipi_sd_to_csis_state(mipi_sd);
 
-	sdformat->format = *fmt;
+	/*
+	 * The CSIS can't transcode in any way, the source format is identical
+	 * to the sink format.
+	 */
+	if (code->pad == CSIS_PAD_SOURCE) {
+		struct v4l2_mbus_framefmt *fmt;
 
-	if (csis_fmt && sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE)
-		state->csis_fmt = csis_fmt;
-	else
-		cfg->try_fmt = sdformat->format;
+		if (code->index > 0)
+			return -EINVAL;
 
-unlock:
-	mutex_unlock(&state->lock);
+		fmt = mipi_csis_get_format(state, cfg, code->which, code->pad);
+		code->code = fmt->code;
+		return 0;
+	}
+
+	if (code->pad != CSIS_PAD_SINK)
+		return -EINVAL;
+
+	if (code->index >= ARRAY_SIZE(mipi_csis_formats))
+		return -EINVAL;
+
+	code->code = mipi_csis_formats[code->index].code;
 
 	return 0;
 }
 
-static int mipi_csis_get_fmt(struct v4l2_subdev *mipi_sd,
+static int mipi_csis_set_fmt(struct v4l2_subdev *mipi_sd,
 			     struct v4l2_subdev_pad_config *cfg,
 			     struct v4l2_subdev_format *sdformat)
 {
 	struct csi_state *state = mipi_sd_to_csis_state(mipi_sd);
+	struct csis_pix_format const *csis_fmt;
 	struct v4l2_mbus_framefmt *fmt;
+	unsigned int align;
 
-	mutex_lock(&state->lock);
+	/*
+	 * The CSIS can't transcode in any way, the source format can't be
+	 * modified.
+	 */
+	if (sdformat->pad == CSIS_PAD_SOURCE)
+		return mipi_csis_get_fmt(mipi_sd, cfg, sdformat);
+
+	if (sdformat->pad != CSIS_PAD_SINK)
+		return -EINVAL;
 
 	fmt = mipi_csis_get_format(state, cfg, sdformat->which, sdformat->pad);
 
+	mutex_lock(&state->lock);
+
+	/* Validate the media bus code and clamp the size. */
+	csis_fmt = find_csis_format(sdformat->format.code);
+	if (!csis_fmt)
+		csis_fmt = &mipi_csis_formats[0];
+
+	fmt->code = csis_fmt->code;
+	fmt->width = sdformat->format.width;
+	fmt->height = sdformat->format.height;
+
+	/*
+	 * The total number of bits per line must be a multiple of 8. We thus
+	 * need to align the width for formats that are not multiples of 8
+	 * bits.
+	 */
+	switch (csis_fmt->width % 8) {
+	case 0:
+		align = 1;
+		break;
+	case 4:
+		align = 2;
+		break;
+	case 2:
+	case 6:
+		align = 4;
+		break;
+	case 1:
+	case 3:
+	case 5:
+	case 7:
+		align = 8;
+		break;
+	}
+
+	v4l_bound_align_image(&fmt->width, 1, CSIS_MAX_PIX_WIDTH, align,
+			      &fmt->height, 1, CSIS_MAX_PIX_HEIGHT, 1, 0);
+
 	sdformat->format = *fmt;
 
+	/* Propagate the format from sink to source. */
+	fmt = mipi_csis_get_format(state, cfg, sdformat->which,
+				   CSIS_PAD_SOURCE);
+	*fmt = sdformat->format;
+
+	/* Store the CSIS format descriptor for active formats. */
+	if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+		state->csis_fmt = csis_fmt;
+
 	mutex_unlock(&state->lock);
 
 	return 0;
@@ -809,6 +913,7 @@ static const struct v4l2_subdev_video_ops mipi_csis_video_ops = {
 
 static const struct v4l2_subdev_pad_ops mipi_csis_pad_ops = {
 	.init_cfg		= mipi_csis_init_cfg,
+	.enum_mbus_code		= mipi_csis_enum_mbus_code,
 	.get_fmt		= mipi_csis_get_fmt,
 	.set_fmt		= mipi_csis_set_fmt,
 };
@@ -883,10 +988,7 @@ static int mipi_csis_subdev_init(struct v4l2_subdev *mipi_sd,
 	mipi_sd->dev = &pdev->dev;
 
 	state->csis_fmt = &mipi_csis_formats[0];
-	state->format_mbus.code = mipi_csis_formats[0].code;
-	state->format_mbus.width = MIPI_CSIS_DEF_PIX_WIDTH;
-	state->format_mbus.height = MIPI_CSIS_DEF_PIX_HEIGHT;
-	state->format_mbus.field = V4L2_FIELD_NONE;
+	mipi_csis_init_cfg(mipi_sd, NULL);
 
 	v4l2_set_subdevdata(mipi_sd, &pdev->dev);
 
diff --git a/drivers/staging/media/ipu3/Kconfig b/drivers/staging/media/ipu3/Kconfig
index 4b51c67eac88..3e9640523e50 100644
--- a/drivers/staging/media/ipu3/Kconfig
+++ b/drivers/staging/media/ipu3/Kconfig
@@ -2,8 +2,9 @@
 config VIDEO_IPU3_IMGU
 	tristate "Intel ipu3-imgu driver"
 	depends on PCI && VIDEO_V4L2
-	depends on MEDIA_CONTROLLER && VIDEO_V4L2_SUBDEV_API
 	depends on X86
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select IOMMU_IOVA
 	select VIDEOBUF2_DMA_SG
 	help
diff --git a/drivers/staging/media/ipu3/TODO b/drivers/staging/media/ipu3/TODO
index 52063b651810..4bcb665cb5f7 100644
--- a/drivers/staging/media/ipu3/TODO
+++ b/drivers/staging/media/ipu3/TODO
@@ -8,8 +8,6 @@ staging directory.
 - IPU3 driver documentation (Laurent)
   Comments on configuring v4l2 subdevs for CIO2 and ImgU.
 
-- Switch to yavta from v4l2n in driver docs.
-
 - Elaborate the functionality of different selection rectangles in driver
   documentation. This may require driver changes as well.
 
diff --git a/drivers/staging/media/ipu3/ipu3-css-params.c b/drivers/staging/media/ipu3/ipu3-css-params.c
index 4533dacad4be..fbd53d7c097c 100644
--- a/drivers/staging/media/ipu3/ipu3-css-params.c
+++ b/drivers/staging/media/ipu3/ipu3-css-params.c
@@ -49,14 +49,13 @@ imgu_css_scaler_setup_lut(unsigned int taps, unsigned int input_width,
 	int tap, phase, phase_sum_left, phase_sum_right;
 	int exponent = imgu_css_scaler_get_exp(output_width, input_width);
 	int mantissa = (1 << exponent) * output_width;
-	unsigned int phase_step;
+	unsigned int phase_step, phase_taps;
 
 	if (input_width == output_width) {
 		for (phase = 0; phase < IMGU_SCALER_PHASES; phase++) {
-			for (tap = 0; tap < taps; tap++) {
-				coeff_lut[phase * IMGU_SCALER_FILTER_TAPS + tap]
-					= 0;
-			}
+			phase_taps = phase * IMGU_SCALER_FILTER_TAPS;
+			for (tap = 0; tap < taps; tap++)
+				coeff_lut[phase_taps + tap] = 0;
 		}
 
 		info->phase_step = IMGU_SCALER_PHASES *
@@ -71,6 +70,7 @@ imgu_css_scaler_setup_lut(unsigned int taps, unsigned int input_width,
 	}
 
 	for (phase = 0; phase < IMGU_SCALER_PHASES; phase++) {
+		phase_taps = phase * IMGU_SCALER_FILTER_TAPS;
 		for (tap = 0; tap < taps; tap++) {
 			/* flip table to for convolution reverse indexing */
 			s64 coeff = coeffs[coeffs_size -
@@ -81,9 +81,7 @@ imgu_css_scaler_setup_lut(unsigned int taps, unsigned int input_width,
 			/* Add +"0.5" */
 			coeff += 1 << (IMGU_SCALER_COEFF_BITS - 1);
 			coeff >>= IMGU_SCALER_COEFF_BITS;
-
-			coeff_lut[phase * IMGU_SCALER_FILTER_TAPS + tap] =
-				coeff;
+			coeff_lut[phase_taps + tap] = coeff;
 		}
 	}
 
diff --git a/drivers/staging/media/ipu3/ipu3-mmu.c b/drivers/staging/media/ipu3/ipu3-mmu.c
index 5f3ff964f3e7..cb9bf5fb29a5 100644
--- a/drivers/staging/media/ipu3/ipu3-mmu.c
+++ b/drivers/staging/media/ipu3/ipu3-mmu.c
@@ -174,8 +174,10 @@ static u32 *imgu_mmu_get_l2pt(struct imgu_mmu *mmu, u32 l1pt_idx)
 	spin_lock_irqsave(&mmu->lock, flags);
 
 	l2pt = mmu->l2pts[l1pt_idx];
-	if (l2pt)
-		goto done;
+	if (l2pt) {
+		spin_unlock_irqrestore(&mmu->lock, flags);
+		return l2pt;
+	}
 
 	spin_unlock_irqrestore(&mmu->lock, flags);
 
@@ -190,8 +192,9 @@ static u32 *imgu_mmu_get_l2pt(struct imgu_mmu *mmu, u32 l1pt_idx)
 
 	l2pt = mmu->l2pts[l1pt_idx];
 	if (l2pt) {
+		spin_unlock_irqrestore(&mmu->lock, flags);
 		imgu_mmu_free_page_table(new_l2pt);
-		goto done;
+		return l2pt;
 	}
 
 	l2pt = new_l2pt;
@@ -200,7 +203,6 @@ static u32 *imgu_mmu_get_l2pt(struct imgu_mmu *mmu, u32 l1pt_idx)
 	pteval = IPU3_ADDR2PTE(virt_to_phys(new_l2pt));
 	mmu->l1pt[l1pt_idx] = pteval;
 
-done:
 	spin_unlock_irqrestore(&mmu->lock, flags);
 	return l2pt;
 }
diff --git a/drivers/staging/media/ipu3/ipu3-v4l2.c b/drivers/staging/media/ipu3/ipu3-v4l2.c
index 09c8ede1457c..afbb4636e714 100644
--- a/drivers/staging/media/ipu3/ipu3-v4l2.c
+++ b/drivers/staging/media/ipu3/ipu3-v4l2.c
@@ -152,7 +152,6 @@ static int imgu_subdev_set_fmt(struct v4l2_subdev *sd,
 	struct imgu_v4l2_subdev *imgu_sd = container_of(sd,
 							struct imgu_v4l2_subdev,
 							subdev);
-
 	struct v4l2_mbus_framefmt *mf;
 	u32 pad = fmt->pad;
 	unsigned int pipe = imgu_sd->pipe;
@@ -367,8 +366,10 @@ static void imgu_vb2_buf_queue(struct vb2_buffer *vb)
 
 	vb2_set_plane_payload(vb, 0, need_bytes);
 
+	mutex_lock(&imgu->streaming_lock);
 	if (imgu->streaming)
 		imgu_queue_buffers(imgu, false, node->pipe);
+	mutex_unlock(&imgu->streaming_lock);
 
 	dev_dbg(&imgu->pci_dev->dev, "%s for pipe %u node %u", __func__,
 		node->pipe, node->id);
@@ -468,10 +469,13 @@ static int imgu_vb2_start_streaming(struct vb2_queue *vq, unsigned int count)
 	dev_dbg(dev, "%s node name %s pipe %u id %u", __func__,
 		node->name, node->pipe, node->id);
 
+	mutex_lock(&imgu->streaming_lock);
 	if (imgu->streaming) {
 		r = -EBUSY;
+		mutex_unlock(&imgu->streaming_lock);
 		goto fail_return_bufs;
 	}
+	mutex_unlock(&imgu->streaming_lock);
 
 	if (!node->enabled) {
 		dev_err(dev, "IMGU node is not enabled");
@@ -485,7 +489,6 @@ static int imgu_vb2_start_streaming(struct vb2_queue *vq, unsigned int count)
 	if (r < 0)
 		goto fail_return_bufs;
 
-
 	if (!imgu_all_nodes_streaming(imgu, node))
 		return 0;
 
@@ -498,9 +501,11 @@ static int imgu_vb2_start_streaming(struct vb2_queue *vq, unsigned int count)
 
 	/* Start streaming of the whole pipeline now */
 	dev_dbg(dev, "IMGU streaming is ready to start");
+	mutex_lock(&imgu->streaming_lock);
 	r = imgu_s_stream(imgu, true);
 	if (!r)
 		imgu->streaming = true;
+	mutex_unlock(&imgu->streaming_lock);
 
 	return 0;
 
@@ -532,6 +537,7 @@ static void imgu_vb2_stop_streaming(struct vb2_queue *vq)
 		dev_err(&imgu->pci_dev->dev,
 			"failed to stop subdev streaming\n");
 
+	mutex_lock(&imgu->streaming_lock);
 	/* Was this the first node with streaming disabled? */
 	if (imgu->streaming && imgu_all_nodes_streaming(imgu, node)) {
 		/* Yes, really stop streaming now */
@@ -542,6 +548,8 @@ static void imgu_vb2_stop_streaming(struct vb2_queue *vq)
 	}
 
 	imgu_return_all_buffers(imgu, node, VB2_BUF_STATE_ERROR);
+	mutex_unlock(&imgu->streaming_lock);
+
 	media_pipeline_stop(&node->vdev.entity);
 }
 
@@ -1292,19 +1300,17 @@ static void imgu_v4l2_nodes_cleanup_pipe(struct imgu_device *imgu,
 
 static int imgu_v4l2_nodes_setup_pipe(struct imgu_device *imgu, int pipe)
 {
-	int i, r;
+	int i;
 
 	for (i = 0; i < IMGU_NODE_NUM; i++) {
-		r = imgu_v4l2_node_setup(imgu, pipe, i);
-		if (r)
-			goto cleanup;
-	}
+		int r = imgu_v4l2_node_setup(imgu, pipe, i);
 
+		if (r) {
+			imgu_v4l2_nodes_cleanup_pipe(imgu, pipe, i);
+			return r;
+		}
+	}
 	return 0;
-
-cleanup:
-	imgu_v4l2_nodes_cleanup_pipe(imgu, pipe, i);
-	return r;
 }
 
 static void imgu_v4l2_subdev_cleanup(struct imgu_device *imgu, unsigned int i)
diff --git a/drivers/staging/media/ipu3/ipu3.c b/drivers/staging/media/ipu3/ipu3.c
index 4d53aad31483..a25a997cfd7e 100644
--- a/drivers/staging/media/ipu3/ipu3.c
+++ b/drivers/staging/media/ipu3/ipu3.c
@@ -675,6 +675,7 @@ static int imgu_pci_probe(struct pci_dev *pci_dev,
 		return r;
 
 	mutex_init(&imgu->lock);
+	mutex_init(&imgu->streaming_lock);
 	atomic_set(&imgu->qbuf_barrier, 0);
 	init_waitqueue_head(&imgu->buf_drain_wq);
 
@@ -738,6 +739,7 @@ static int imgu_pci_probe(struct pci_dev *pci_dev,
 out_css_powerdown:
 	imgu_css_set_powerdown(&pci_dev->dev, imgu->base);
 out_mutex_destroy:
+	mutex_destroy(&imgu->streaming_lock);
 	mutex_destroy(&imgu->lock);
 
 	return r;
@@ -755,6 +757,7 @@ static void imgu_pci_remove(struct pci_dev *pci_dev)
 	imgu_css_set_powerdown(&pci_dev->dev, imgu->base);
 	imgu_dmamap_exit(imgu);
 	imgu_mmu_exit(imgu->mmu);
+	mutex_destroy(&imgu->streaming_lock);
 	mutex_destroy(&imgu->lock);
 }
 
diff --git a/drivers/staging/media/ipu3/ipu3.h b/drivers/staging/media/ipu3/ipu3.h
index 73b123b2b8a2..8cd6a0077d99 100644
--- a/drivers/staging/media/ipu3/ipu3.h
+++ b/drivers/staging/media/ipu3/ipu3.h
@@ -146,6 +146,10 @@ struct imgu_device {
 	 * vid_buf.list and css->queue
 	 */
 	struct mutex lock;
+
+	/* Lock to protect writes to streaming flag in this struct */
+	struct mutex streaming_lock;
+
 	/* Forbid streaming and buffer queuing during system suspend. */
 	atomic_t qbuf_barrier;
 	/* Indicate if system suspend take place while imgu is streaming. */
diff --git a/drivers/staging/media/omap4iss/Kconfig b/drivers/staging/media/omap4iss/Kconfig
index 4dcbc5065821..6c254907a27b 100644
--- a/drivers/staging/media/omap4iss/Kconfig
+++ b/drivers/staging/media/omap4iss/Kconfig
@@ -2,8 +2,10 @@
 
 config VIDEO_OMAP4
 	tristate "OMAP 4 Camera support"
-	depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && I2C
+	depends on VIDEO_V4L2  && I2C
 	depends on ARCH_OMAP4 || COMPILE_TEST
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select MFD_SYSCON
 	select VIDEOBUF2_DMA_CONTIG
 	help
diff --git a/drivers/staging/media/rkisp1/Kconfig b/drivers/staging/media/rkisp1/Kconfig
index b859a493caba..5ecbefa0f5ec 100644
--- a/drivers/staging/media/rkisp1/Kconfig
+++ b/drivers/staging/media/rkisp1/Kconfig
@@ -2,8 +2,10 @@
 
 config VIDEO_ROCKCHIP_ISP1
 	tristate "Rockchip Image Signal Processing v1 Unit driver"
-	depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on VIDEO_V4L2
 	depends on ARCH_ROCKCHIP || COMPILE_TEST
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
 	select VIDEOBUF2_DMA_CONTIG
 	select VIDEOBUF2_VMALLOC
 	select V4L2_FWNODE
diff --git a/drivers/staging/media/rkisp1/Makefile b/drivers/staging/media/rkisp1/Makefile
index 69ca59c7ef34..ab32a77db8f7 100644
--- a/drivers/staging/media/rkisp1/Makefile
+++ b/drivers/staging/media/rkisp1/Makefile
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
 obj-$(CONFIG_VIDEO_ROCKCHIP_ISP1) += rockchip-isp1.o
 rockchip-isp1-objs += 	rkisp1-capture.o \
 			rkisp1-common.o \
diff --git a/drivers/staging/media/soc_camera/soc-camera.rst b/drivers/staging/media/soc_camera/soc-camera.rst
new file mode 100644
index 000000000000..7c39711aebf8
--- /dev/null
+++ b/drivers/staging/media/soc_camera/soc-camera.rst
@@ -0,0 +1,171 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+The Soc-Camera Drivers
+======================
+
+Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+
+Terminology
+-----------
+
+The following terms are used in this document:
+ - camera / camera device / camera sensor - a video-camera sensor chip, capable
+   of connecting to a variety of systems and interfaces, typically uses i2c for
+   control and configuration, and a parallel or a serial bus for data.
+ - camera host - an interface, to which a camera is connected. Typically a
+   specialised interface, present on many SoCs, e.g. PXA27x and PXA3xx, SuperH,
+   i.MX27, i.MX31.
+ - camera host bus - a connection between a camera host and a camera. Can be
+   parallel or serial, consists of data and control lines, e.g. clock, vertical
+   and horizontal synchronization signals.
+
+Purpose of the soc-camera subsystem
+-----------------------------------
+
+The soc-camera subsystem initially provided a unified API between camera host
+drivers and camera sensor drivers. Later the soc-camera sensor API has been
+replaced with the V4L2 standard subdev API. This also made camera driver re-use
+with non-soc-camera hosts possible. The camera host API to the soc-camera core
+has been preserved.
+
+Soc-camera implements a V4L2 interface to the user, currently only the "mmap"
+method is supported by host drivers. However, the soc-camera core also provides
+support for the "read" method.
+
+The subsystem has been designed to support multiple camera host interfaces and
+multiple cameras per interface, although most applications have only one camera
+sensor.
+
+Existing drivers
+----------------
+
+As of 3.7 there are seven host drivers in the mainline: atmel-isi.c,
+mx1_camera.c (broken, scheduled for removal), mx2_camera.c, mx3_camera.c,
+omap1_camera.c, pxa_camera.c, sh_mobile_ceu_camera.c, and multiple sensor
+drivers under drivers/media/i2c/soc_camera/.
+
+Camera host API
+---------------
+
+A host camera driver is registered using the
+
+.. code-block:: none
+
+	soc_camera_host_register(struct soc_camera_host *);
+
+function. The host object can be initialized as follows:
+
+.. code-block:: none
+
+	struct soc_camera_host	*ici;
+	ici->drv_name		= DRV_NAME;
+	ici->ops		= &camera_host_ops;
+	ici->priv		= pcdev;
+	ici->v4l2_dev.dev	= &pdev->dev;
+	ici->nr			= pdev->id;
+
+All camera host methods are passed in a struct soc_camera_host_ops:
+
+.. code-block:: none
+
+	static struct soc_camera_host_ops camera_host_ops = {
+		.owner		= THIS_MODULE,
+		.add		= camera_add_device,
+		.remove		= camera_remove_device,
+		.set_fmt	= camera_set_fmt_cap,
+		.try_fmt	= camera_try_fmt_cap,
+		.init_videobuf2	= camera_init_videobuf2,
+		.poll		= camera_poll,
+		.querycap	= camera_querycap,
+		.set_bus_param	= camera_set_bus_param,
+		/* The rest of host operations are optional */
+	};
+
+.add and .remove methods are called when a sensor is attached to or detached
+from the host. .set_bus_param is used to configure physical connection
+parameters between the host and the sensor. .init_videobuf2 is called by
+soc-camera core when a video-device is opened, the host driver would typically
+call vb2_queue_init() in this method. Further video-buffer management is
+implemented completely by the specific camera host driver. If the host driver
+supports non-standard pixel format conversion, it should implement a
+.get_formats and, possibly, a .put_formats operations. See below for more
+details about format conversion. The rest of the methods are called from
+respective V4L2 operations.
+
+Camera API
+----------
+
+Sensor drivers can use struct soc_camera_link, typically provided by the
+platform, and used to specify to which camera host bus the sensor is connected,
+and optionally provide platform .power and .reset methods for the camera. This
+struct is provided to the camera driver via the I2C client device platform data
+and can be obtained, using the soc_camera_i2c_to_link() macro. Care should be
+taken, when using soc_camera_vdev_to_subdev() and when accessing struct
+soc_camera_device, using v4l2_get_subdev_hostdata(): both only work, when
+running on an soc-camera host. The actual camera driver operation is implemented
+using the V4L2 subdev API. Additionally soc-camera camera drivers can use
+auxiliary soc-camera helper functions like soc_camera_power_on() and
+soc_camera_power_off(), which switch regulators, provided by the platform and call
+board-specific power switching methods. soc_camera_apply_board_flags() takes
+camera bus configuration capability flags and applies any board transformations,
+e.g. signal polarity inversion. soc_mbus_get_fmtdesc() can be used to obtain a
+pixel format descriptor, corresponding to a certain media-bus pixel format code.
+soc_camera_limit_side() can be used to restrict beginning and length of a frame
+side, based on camera capabilities.
+
+VIDIOC_S_CROP and VIDIOC_S_FMT behaviour
+----------------------------------------
+
+Above user ioctls modify image geometry as follows:
+
+VIDIOC_S_CROP: sets location and sizes of the sensor window. Unit is one sensor
+pixel. Changing sensor window sizes preserves any scaling factors, therefore
+user window sizes change as well.
+
+VIDIOC_S_FMT: sets user window. Should preserve previously set sensor window as
+much as possible by modifying scaling factors. If the sensor window cannot be
+preserved precisely, it may be changed too.
+
+In soc-camera there are two locations, where scaling and cropping can take
+place: in the camera driver and in the host driver. User ioctls are first passed
+to the host driver, which then generally passes them down to the camera driver.
+It is more efficient to perform scaling and cropping in the camera driver to
+save camera bus bandwidth and maximise the framerate. However, if the camera
+driver failed to set the required parameters with sufficient precision, the host
+driver may decide to also use its own scaling and cropping to fulfill the user's
+request.
+
+Camera drivers are interfaced to the soc-camera core and to host drivers over
+the v4l2-subdev API, which is completely functional, it doesn't pass any data.
+Therefore all camera drivers shall reply to .g_fmt() requests with their current
+output geometry. This is necessary to correctly configure the camera bus.
+.s_fmt() and .try_fmt() have to be implemented too. Sensor window and scaling
+factors have to be maintained by camera drivers internally. According to the
+V4L2 API all capture drivers must support the VIDIOC_CROPCAP ioctl, hence we
+rely on camera drivers implementing .cropcap(). If the camera driver does not
+support cropping, it may choose to not implement .s_crop(), but to enable
+cropping support by the camera host driver at least the .g_crop method must be
+implemented.
+
+User window geometry is kept in .user_width and .user_height fields in struct
+soc_camera_device and used by the soc-camera core and host drivers. The core
+updates these fields upon successful completion of a .s_fmt() call, but if these
+fields change elsewhere, e.g. during .s_crop() processing, the host driver is
+responsible for updating them.
+
+Format conversion
+-----------------
+
+V4L2 distinguishes between pixel formats, as they are stored in memory, and as
+they are transferred over a media bus. Soc-camera provides support to
+conveniently manage these formats. A table of standard transformations is
+maintained by soc-camera core, which describes, what FOURCC pixel format will
+be obtained, if a media-bus pixel format is stored in memory according to
+certain rules. E.g. if MEDIA_BUS_FMT_YUYV8_2X8 data is sampled with 8 bits per
+sample and stored in memory in the little-endian order with no gaps between
+bytes, data in memory will represent the V4L2_PIX_FMT_YUYV FOURCC format. These
+standard transformations will be used by soc-camera or by camera host drivers to
+configure camera drivers to produce the FOURCC format, requested by the user,
+using the VIDIOC_S_FMT ioctl(). Apart from those standard format conversions,
+host drivers can also provide their own conversion rules by implementing a
+.get_formats and, if required, a .put_formats methods.
diff --git a/drivers/staging/media/sunxi/cedrus/Kconfig b/drivers/staging/media/sunxi/cedrus/Kconfig
index 17733e9a088f..da369950bbf2 100644
--- a/drivers/staging/media/sunxi/cedrus/Kconfig
+++ b/drivers/staging/media/sunxi/cedrus/Kconfig
@@ -1,10 +1,11 @@
 # SPDX-License-Identifier: GPL-2.0
 config VIDEO_SUNXI_CEDRUS
 	tristate "Allwinner Cedrus VPU driver"
-	depends on VIDEO_DEV && VIDEO_V4L2 && MEDIA_CONTROLLER
+	depends on VIDEO_DEV && VIDEO_V4L2
 	depends on HAS_DMA
 	depends on OF
-	depends on MEDIA_CONTROLLER_REQUEST_API
+	select MEDIA_CONTROLLER
+	select MEDIA_CONTROLLER_REQUEST_API
 	select SUNXI_SRAM
 	select VIDEOBUF2_DMA_CONTIG
 	select V4L2_MEM2MEM_DEV
diff --git a/drivers/staging/mt7621-dts/mt7621.dtsi b/drivers/staging/mt7621-dts/mt7621.dtsi
index 9e5cf68731bb..82aa93634eda 100644
--- a/drivers/staging/mt7621-dts/mt7621.dtsi
+++ b/drivers/staging/mt7621-dts/mt7621.dtsi
@@ -523,11 +523,10 @@ pcie: pcie@1e140000 {
 			0x01000000 0 0x00000000 0x1e160000 0 0x00010000 /* io space */
 		>;
 
-		#interrupt-cells = <1>;
-		interrupt-map-mask = <0xF0000 0 0 1>;
-		interrupt-map = <0x10000 0 0 1 &gic GIC_SHARED 4 IRQ_TYPE_LEVEL_HIGH>,
-				<0x20000 0 0 1 &gic GIC_SHARED 24 IRQ_TYPE_LEVEL_HIGH>,
-				<0x30000 0 0 1 &gic GIC_SHARED 25 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SHARED 4 IRQ_TYPE_LEVEL_HIGH
+				GIC_SHARED 24 IRQ_TYPE_LEVEL_HIGH
+				GIC_SHARED 25 IRQ_TYPE_LEVEL_HIGH>;
 
 		status = "disabled";
 
diff --git a/drivers/staging/mt7621-pci-phy/mediatek,mt7621-pci-phy.txt b/drivers/staging/mt7621-pci-phy/mediatek,mt7621-pci-phy.txt
deleted file mode 100644
index a369d715378b..000000000000
--- a/drivers/staging/mt7621-pci-phy/mediatek,mt7621-pci-phy.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-Mediatek Mt7621 PCIe PHY
-
-Required properties:
-- compatible: must be "mediatek,mt7621-pci-phy"
-- reg: base address and length of the PCIe PHY block
-- #phy-cells: must be <1> for pcie0_phy and for pcie1_phy.
-
-Example:
-	pcie0_phy: pcie-phy@1e149000 {
-		compatible = "mediatek,mt7621-pci-phy";
-		reg = <0x1e149000 0x0700>;
-		#phy-cells = <1>;
-	};
-
-	pcie1_phy: pcie-phy@1e14a000 {
-		compatible = "mediatek,mt7621-pci-phy";
-		reg = <0x1e14a000 0x0700>;
-		#phy-cells = <1>;
-	};
-
-	/* users of the PCIe phy */
-
-	pcie: pcie@1e140000 {
-		...
-		...
-		phys = <&pcie0_phy 0>, <&pcie0_phy 1>, <&pcie1_phy 0>;
-		phy-names = "pcie-phy0", "pcie-phy1", "pcie-phy2";
-	};
diff --git a/drivers/staging/mt7621-pci-phy/mediatek,mt7621-pci-phy.yaml b/drivers/staging/mt7621-pci-phy/mediatek,mt7621-pci-phy.yaml
new file mode 100644
index 000000000000..cf32bbc45b5d
--- /dev/null
+++ b/drivers/staging/mt7621-pci-phy/mediatek,mt7621-pci-phy.yaml
@@ -0,0 +1,36 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/phy/mediatek,mt7621-pci-phy.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Mediatek Mt7621 PCIe PHY Device Tree Bindings
+
+maintainers:
+  - Sergio Paracuellos <sergio.paracuellos@gmail.com>
+
+properties:
+  compatible:
+    const: mediatek,mt7621-pci-phy
+
+  reg:
+    maxItems: 1
+
+  "#phy-cells":
+    const: 1
+    description: selects if the phy is dual-ported
+
+required:
+  - compatible
+  - reg
+  - "#phy-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    pcie0_phy: pcie-phy@1e149000 {
+      compatible = "mediatek,mt7621-pci-phy";
+      reg = <0x1e149000 0x0700>;
+      #phy-cells = <1>;
+    };
diff --git a/drivers/staging/mt7621-pci/pci-mt7621.c b/drivers/staging/mt7621-pci/pci-mt7621.c
index f58e3a51fc71..36207243a71b 100644
--- a/drivers/staging/mt7621-pci/pci-mt7621.c
+++ b/drivers/staging/mt7621-pci/pci-mt7621.c
@@ -97,6 +97,7 @@
  * @pcie_rst: pointer to port reset control
  * @gpio_rst: gpio reset
  * @slot: port slot
+ * @irq: GIC irq
  * @enabled: indicates if port is enabled
  */
 struct mt7621_pcie_port {
@@ -107,6 +108,7 @@ struct mt7621_pcie_port {
 	struct reset_control *pcie_rst;
 	struct gpio_desc *gpio_rst;
 	u32 slot;
+	int irq;
 	bool enabled;
 };
 
@@ -120,6 +122,7 @@ struct mt7621_pcie_port {
  * @dev: Pointer to PCIe device
  * @io_map_base: virtual memory base address for io
  * @ports: pointer to PCIe port information
+ * @irq_map: irq mapping info according pcie link status
  * @resets_inverted: depends on chip revision
  * reset lines are inverted.
  */
@@ -135,6 +138,7 @@ struct mt7621_pcie {
 	} offset;
 	unsigned long io_map_base;
 	struct list_head ports;
+	int irq_map[PCIE_P2P_MAX];
 	bool resets_inverted;
 };
 
@@ -279,6 +283,16 @@ static void setup_cm_memory_region(struct mt7621_pcie *pcie)
 	}
 }
 
+static int mt7621_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
+{
+	struct mt7621_pcie *pcie = pdev->bus->sysdata;
+	struct device *dev = pcie->dev;
+	int irq = pcie->irq_map[slot];
+
+	dev_info(dev, "bus=%d slot=%d irq=%d\n", pdev->bus->number, slot, irq);
+	return irq;
+}
+
 static int mt7621_pci_parse_request_of_pci_ranges(struct mt7621_pcie *pcie)
 {
 	struct device *dev = pcie->dev;
@@ -330,6 +344,7 @@ static int mt7621_pcie_parse_port(struct mt7621_pcie *pcie,
 {
 	struct mt7621_pcie_port *port;
 	struct device *dev = pcie->dev;
+	struct platform_device *pdev = to_platform_device(dev);
 	struct device_node *pnode = dev->of_node;
 	struct resource regs;
 	char name[10];
@@ -371,6 +386,12 @@ static int mt7621_pcie_parse_port(struct mt7621_pcie *pcie,
 	port->slot = slot;
 	port->pcie = pcie;
 
+	port->irq = platform_get_irq(pdev, slot);
+	if (port->irq < 0) {
+		dev_err(dev, "Failed to get IRQ for PCIe%d\n", slot);
+		return -ENXIO;
+	}
+
 	INIT_LIST_HEAD(&port->list);
 	list_add_tail(&port->list, &pcie->ports);
 
@@ -502,17 +523,25 @@ static void mt7621_pcie_init_ports(struct mt7621_pcie *pcie)
 
 	mt7621_pcie_reset_ep_deassert(pcie);
 
+	tmp = NULL;
 	list_for_each_entry(port, &pcie->ports, list) {
 		u32 slot = port->slot;
 
 		if (!mt7621_pcie_port_is_linkup(port)) {
 			dev_err(dev, "pcie%d no card, disable it (RST & CLK)\n",
 				slot);
-			if (slot != 1)
-				phy_power_off(port->phy);
 			mt7621_control_assert(port);
 			mt7621_pcie_port_clk_disable(port);
 			port->enabled = false;
+
+			if (slot == 0) {
+				tmp = port;
+				continue;
+			}
+
+			if (slot == 1 && tmp && !tmp->enabled)
+				phy_power_off(tmp->phy);
+
 		}
 	}
 }
@@ -577,13 +606,15 @@ static int mt7621_pcie_init_virtual_bridges(struct mt7621_pcie *pcie)
 {
 	u32 pcie_link_status = 0;
 	u32 n;
-	int i;
+	int i = 0;
 	u32 p2p_br_devnum[PCIE_P2P_MAX];
+	int irqs[PCIE_P2P_MAX];
 	struct mt7621_pcie_port *port;
 
 	list_for_each_entry(port, &pcie->ports, list) {
 		u32 slot = port->slot;
 
+		irqs[i++] = port->irq;
 		if (port->enabled)
 			pcie_link_status |= BIT(slot);
 	}
@@ -606,6 +637,15 @@ static int mt7621_pcie_init_virtual_bridges(struct mt7621_pcie *pcie)
 		 (p2p_br_devnum[1] << PCIE_P2P_BR_DEVNUM1_SHIFT) |
 		 (p2p_br_devnum[2] << PCIE_P2P_BR_DEVNUM2_SHIFT));
 
+	/* Assign IRQs */
+	n = 0;
+	for (i = 0; i < PCIE_P2P_MAX; i++)
+		if (pcie_link_status & BIT(i))
+			pcie->irq_map[n++] = irqs[i];
+
+	for (i = n; i < PCIE_P2P_MAX; i++)
+		pcie->irq_map[i] = -1;
+
 	return 0;
 }
 
@@ -630,7 +670,7 @@ static int mt7621_pcie_register_host(struct pci_host_bridge *host,
 	host->busnr = pcie->busn.start;
 	host->dev.parent = pcie->dev;
 	host->ops = &mt7621_pci_ops;
-	host->map_irq = of_irq_parse_and_map_pci;
+	host->map_irq = mt7621_map_irq;
 	host->swizzle_irq = pci_common_swizzle;
 	host->sysdata = pcie;
 
diff --git a/drivers/staging/rtl8188eu/core/rtw_ap.c b/drivers/staging/rtl8188eu/core/rtw_ap.c
index 93283c7deec4..817793b9aff2 100644
--- a/drivers/staging/rtl8188eu/core/rtw_ap.c
+++ b/drivers/staging/rtl8188eu/core/rtw_ap.c
@@ -264,8 +264,10 @@ void expire_timeout_chk(struct adapter *padapter)
 			list_del_init(&psta->asoc_list);
 			pstapriv->asoc_list_cnt--;
 
-			DBG_88E("asoc expire %pM, state = 0x%x\n", (psta->hwaddr), psta->state);
-			updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
+			DBG_88E("asoc expire %pM, state = 0x%x\n",
+				(psta->hwaddr), psta->state);
+			updated = ap_free_sta(padapter, psta, true,
+					      WLAN_REASON_DEAUTH_LEAVING);
 		} else {
 			/* TODO: Aging mechanism to digest frames in sleep_q to avoid running out of xmitframe */
 			if (psta->sleepq_len > (NR_XMITFRAME / pstapriv->asoc_list_cnt) &&
@@ -294,16 +296,21 @@ void expire_timeout_chk(struct adapter *padapter)
 		for (i = 0; i < chk_alive_num; i++) {
 			int ret = _FAIL;
 
-			psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]);
+			psta = rtw_get_stainfo_by_offset(pstapriv,
+							 chk_alive_list[i]);
 
-			if (psta->state & WIFI_SLEEP_STATE)
-				ret = issue_nulldata(padapter, psta->hwaddr, 0, 1, 50);
-			else
-				ret = issue_nulldata(padapter, psta->hwaddr, 0, 3, 50);
+			if (psta->state & WIFI_SLEEP_STATE) {
+				ret = issue_nulldata(padapter, psta->hwaddr,
+						     0, 1, 50);
+			} else {
+				ret = issue_nulldata(padapter, psta->hwaddr,
+						     0, 3, 50);
+			}
 
 			psta->keep_alive_trycnt++;
 			if (ret == _SUCCESS) {
-				DBG_88E("asoc check, sta(%pM) is alive\n", (psta->hwaddr));
+				DBG_88E("asoc check, sta(%pM) is alive\n",
+					(psta->hwaddr));
 				psta->expire_to = pstapriv->expire_to;
 				psta->keep_alive_trycnt = 0;
 				continue;
@@ -315,11 +322,13 @@ void expire_timeout_chk(struct adapter *padapter)
 
 			psta->keep_alive_trycnt = 0;
 
-			DBG_88E("asoc expire %pM, state = 0x%x\n", (psta->hwaddr), psta->state);
+			DBG_88E("asoc expire %pM, state = 0x%x\n",
+				psta->hwaddr, psta->state);
 			spin_lock_bh(&pstapriv->asoc_list_lock);
 			list_del_init(&psta->asoc_list);
 			pstapriv->asoc_list_cnt--;
-			updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
+			updated = ap_free_sta(padapter, psta, true,
+					      WLAN_REASON_DEAUTH_LEAVING);
 			spin_unlock_bh(&pstapriv->asoc_list_lock);
 		}
 
@@ -431,7 +440,8 @@ static void update_bmc_sta(struct adapter *padapter)
 		supportRateNum = rtw_get_rateset_len((u8 *)&pcur_network->SupportedRates);
 		network_type = rtw_check_network_type((u8 *)&pcur_network->SupportedRates);
 
-		memcpy(psta->bssrateset, &pcur_network->SupportedRates, supportRateNum);
+		memcpy(psta->bssrateset, &pcur_network->SupportedRates,
+		       supportRateNum);
 		psta->bssratelen = supportRateNum;
 
 		/* b/g mode ra_bitmap */
@@ -445,7 +455,8 @@ static void update_bmc_sta(struct adapter *padapter)
 		tx_ra_bitmap = 0xf;
 
 		raid = networktype_to_raid(network_type);
-		init_rate = get_highest_rate_idx(tx_ra_bitmap & 0x0fffffff) & 0x3f;
+		init_rate = get_highest_rate_idx(tx_ra_bitmap & 0x0fffffff) &
+			    0x3f;
 
 		/* ap mode */
 		rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, true);
@@ -456,7 +467,8 @@ static void update_bmc_sta(struct adapter *padapter)
 			arg = psta->mac_id & 0x1f;
 			arg |= BIT(7);
 			tx_ra_bitmap |= ((raid << 28) & 0xf0000000);
-			DBG_88E("%s, mask = 0x%x, arg = 0x%x\n", __func__, tx_ra_bitmap, arg);
+			DBG_88E("%s, mask = 0x%x, arg = 0x%x\n", __func__,
+				tx_ra_bitmap, arg);
 
 			/* bitmap[0:27] = tx_rate_bitmap */
 			/* bitmap[28:31]= Rate Adaptive id */
@@ -647,7 +659,8 @@ static void start_bss_network(struct adapter *padapter, u8 *pbuf)
 	rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
 
 	/* Beacon Control related register */
-	rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&bcn_interval));
+	rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL,
+			  (u8 *)(&bcn_interval));
 
 	UpdateBrateTbl(padapter, pnetwork->SupportedRates);
 	rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, pnetwork->SupportedRates);
@@ -657,7 +670,10 @@ static void start_bss_network(struct adapter *padapter, u8 *pbuf)
 		Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, true);
 	}
 	/* set channel, bwmode */
-	p = rtw_get_ie((pnetwork->ies + sizeof(struct ndis_802_11_fixed_ie)), _HT_ADD_INFO_IE_, &ie_len, (pnetwork->ie_length - sizeof(struct ndis_802_11_fixed_ie)));
+	p = rtw_get_ie(pnetwork->ies + sizeof(struct ndis_802_11_fixed_ie),
+		       _HT_ADD_INFO_IE_, &ie_len,
+		       pnetwork->ie_length -
+		       sizeof(struct ndis_802_11_fixed_ie));
 	if (p && ie_len) {
 		pht_info = (struct HT_info_element *)(p + 2);
 
@@ -682,7 +698,8 @@ static void start_bss_network(struct adapter *padapter, u8 *pbuf)
 	 */
 	set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
 
-	DBG_88E("CH =%d, BW =%d, offset =%d\n", cur_channel, cur_bwmode, cur_ch_offset);
+	DBG_88E("CH =%d, BW =%d, offset =%d\n", cur_channel, cur_bwmode,
+		cur_ch_offset);
 
 	/*  */
 	pmlmeext->cur_channel = cur_channel;
@@ -771,17 +788,19 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf,  int len)
 	cap = get_unaligned_le16(ie);
 
 	/* SSID */
-	p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SSID_IE_, &ie_len, (pbss_network->ie_length - _BEACON_IE_OFFSET_));
+	p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SSID_IE_, &ie_len,
+		       pbss_network->ie_length - _BEACON_IE_OFFSET_);
 	if (p && ie_len > 0) {
 		memset(&pbss_network->ssid, 0, sizeof(struct ndis_802_11_ssid));
-		memcpy(pbss_network->ssid.ssid, (p + 2), ie_len);
+		memcpy(pbss_network->ssid.ssid, p + 2, ie_len);
 		pbss_network->ssid.ssid_length = ie_len;
 	}
 
 	/* channel */
 	channel = 0;
 	pbss_network->Configuration.Length = 0;
-	p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _DSSET_IE_, &ie_len, (pbss_network->ie_length - _BEACON_IE_OFFSET_));
+	p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _DSSET_IE_, &ie_len,
+		       (pbss_network->ie_length - _BEACON_IE_OFFSET_));
 	if (p && ie_len > 0)
 		channel = *(p + 2);
 
@@ -789,14 +808,16 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf,  int len)
 
 	memset(supportRate, 0, NDIS_802_11_LENGTH_RATES_EX);
 	/*  get supported rates */
-	p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_, &ie_len, (pbss_network->ie_length - _BEACON_IE_OFFSET_));
+	p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_, &ie_len,
+		       pbss_network->ie_length - _BEACON_IE_OFFSET_);
 	if (p) {
 		memcpy(supportRate, p + 2, ie_len);
 		supportRateNum = ie_len;
 	}
 
 	/* get ext_supported rates */
-	p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _EXT_SUPPORTEDRATES_IE_, &ie_len, pbss_network->ie_length - _BEACON_IE_OFFSET_);
+	p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _EXT_SUPPORTEDRATES_IE_,
+		       &ie_len, pbss_network->ie_length - _BEACON_IE_OFFSET_);
 	if (p) {
 		memcpy(supportRate + supportRateNum, p + 2, ie_len);
 		supportRateNum += ie_len;
@@ -807,7 +828,8 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf,  int len)
 	rtw_set_supported_rate(pbss_network->SupportedRates, network_type);
 
 	/* parsing ERP_IE */
-	p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _ERPINFO_IE_, &ie_len, (pbss_network->ie_length - _BEACON_IE_OFFSET_));
+	p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _ERPINFO_IE_, &ie_len,
+		       pbss_network->ie_length - _BEACON_IE_OFFSET_);
 	if (p && ie_len > 0)
 		ERP_IE_handler(padapter, (struct ndis_802_11_var_ie *)p);
 
@@ -824,7 +846,8 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf,  int len)
 	pairwise_cipher = 0;
 	psecuritypriv->wpa2_group_cipher = _NO_PRIVACY_;
 	psecuritypriv->wpa2_pairwise_cipher = _NO_PRIVACY_;
-	p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _RSN_IE_2_, &ie_len, (pbss_network->ie_length - _BEACON_IE_OFFSET_));
+	p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _RSN_IE_2_, &ie_len,
+		       pbss_network->ie_length - _BEACON_IE_OFFSET_);
 	if (p && ie_len > 0) {
 		if (rtw_parse_wpa2_ie(p, ie_len + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
 			psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
@@ -844,7 +867,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf,  int len)
 	psecuritypriv->wpa_pairwise_cipher = _NO_PRIVACY_;
 	for (p = ie + _BEACON_IE_OFFSET_;; p += (ie_len + 2)) {
 		p = rtw_get_ie(p, _SSN_IE_1_, &ie_len,
-			       (pbss_network->ie_length - _BEACON_IE_OFFSET_ - (ie_len + 2)));
+			       pbss_network->ie_length - _BEACON_IE_OFFSET_ - (ie_len + 2));
 		if ((p) && (!memcmp(p + 2, OUI1, 4))) {
 			if (rtw_parse_wpa_ie(p, ie_len + 2, &group_cipher,
 					     &pairwise_cipher, NULL) == _SUCCESS) {
@@ -869,7 +892,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf,  int len)
 	if (pregistrypriv->wmm_enable) {
 		for (p = ie + _BEACON_IE_OFFSET_;; p += (ie_len + 2)) {
 			p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len,
-				       (pbss_network->ie_length - _BEACON_IE_OFFSET_ - (ie_len + 2)));
+				       pbss_network->ie_length - _BEACON_IE_OFFSET_ - (ie_len + 2));
 			if ((p) && !memcmp(p + 2, WMM_PARA_IE, 6)) {
 				pmlmepriv->qospriv.qos_option = 1;
 
@@ -892,7 +915,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf,  int len)
 	}
 	/* parsing HT_CAP_IE */
 	p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len,
-		       (pbss_network->ie_length - _BEACON_IE_OFFSET_));
+		       pbss_network->ie_length - _BEACON_IE_OFFSET_);
 	if (p && ie_len > 0) {
 		struct ieee80211_ht_cap *pht_cap = (struct ieee80211_ht_cap *)(p + 2);
 
@@ -916,7 +939,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf,  int len)
 
 	/* parsing HT_INFO_IE */
 	p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len,
-		       (pbss_network->ie_length - _BEACON_IE_OFFSET_));
+		       pbss_network->ie_length - _BEACON_IE_OFFSET_);
 	if (p && ie_len > 0)
 		pHT_info_ie = p;
 	switch (network_type) {
@@ -1226,17 +1249,17 @@ void update_beacon(struct adapter *padapter, u8 ie_id, u8 *oui, u8 tx)
 }
 
 /*
-op_mode
-Set to 0 (HT pure) under the following conditions
-	- all STAs in the BSS are 20/40 MHz HT in 20/40 MHz BSS or
-	- all STAs in the BSS are 20 MHz HT in 20 MHz BSS
-Set to 1 (HT non-member protection) if there may be non-HT STAs
-	in both the primary and the secondary channel
-Set to 2 if only HT STAs are associated in BSS,
-	however and at least one 20 MHz HT STA is associated
-Set to 3 (HT mixed mode) when one or more non-HT STAs are associated
-	(currently non-GF HT station is considered as non-HT STA also)
-*/
+ * op_mode
+ * Set to 0 (HT pure) under the following conditions
+ *	- all STAs in the BSS are 20/40 MHz HT in 20/40 MHz BSS or
+ *	- all STAs in the BSS are 20 MHz HT in 20 MHz BSS
+ * Set to 1 (HT non-member protection) if there may be non-HT STAs
+ *	  in both the primary and the secondary channel
+ * Set to 2 if only HT STAs are associated in BSS,
+ *	  however and at least one 20 MHz HT STA is associated
+ * Set to 3 (HT mixed mode) when one or more non-HT STAs are associated
+ *	  (currently non-GF HT station is considered as non-HT STA also)
+ */
 static int rtw_ht_operation_update(struct adapter *padapter)
 {
 	u16 cur_op_mode, new_op_mode;
diff --git a/drivers/staging/rtl8188eu/core/rtw_efuse.c b/drivers/staging/rtl8188eu/core/rtw_efuse.c
index c525682d0edf..9bb3ec0cd62f 100644
--- a/drivers/staging/rtl8188eu/core/rtw_efuse.c
+++ b/drivers/staging/rtl8188eu/core/rtw_efuse.c
@@ -370,28 +370,27 @@ static u16 Efuse_GetCurrentSize(struct adapter *pAdapter)
 
 	while (efuse_OneByteRead(pAdapter, efuse_addr, &efuse_data) &&
 	       AVAILABLE_EFUSE_ADDR(efuse_addr)) {
-		if (efuse_data != 0xFF) {
-			if ((efuse_data & 0x1F) == 0x0F) {		/* extended header */
-				hoffset = efuse_data;
+		if (efuse_data == 0xFF)
+			break;
+		if ((efuse_data & 0x1F) == 0x0F) { /* extended header */
+			hoffset = efuse_data;
+			efuse_addr++;
+			efuse_OneByteRead(pAdapter, efuse_addr, &efuse_data);
+			if ((efuse_data & 0x0F) == 0x0F) {
 				efuse_addr++;
-				efuse_OneByteRead(pAdapter, efuse_addr, &efuse_data);
-				if ((efuse_data & 0x0F) == 0x0F) {
-					efuse_addr++;
-					continue;
-				} else {
-					hoffset = ((hoffset & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
-					hworden = efuse_data & 0x0F;
-				}
+				continue;
 			} else {
-				hoffset = (efuse_data >> 4) & 0x0F;
-				hworden =  efuse_data & 0x0F;
+				hoffset = ((hoffset & 0xE0) >> 5) |
+					  ((efuse_data & 0xF0) >> 1);
+				hworden = efuse_data & 0x0F;
 			}
-			word_cnts = Efuse_CalculateWordCnts(hworden);
-			/* read next header */
-			efuse_addr = efuse_addr + (word_cnts * 2) + 1;
 		} else {
-			break;
+			hoffset = (efuse_data >> 4) & 0x0F;
+			hworden =  efuse_data & 0x0F;
 		}
+		word_cnts = Efuse_CalculateWordCnts(hworden);
+		/* read next header */
+		efuse_addr = efuse_addr + (word_cnts * 2) + 1;
 	}
 
 	rtw_hal_set_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_addr);
diff --git a/drivers/staging/rtl8188eu/core/rtw_ieee80211.c b/drivers/staging/rtl8188eu/core/rtw_ieee80211.c
index e186982d5908..caf600eba03b 100644
--- a/drivers/staging/rtl8188eu/core/rtw_ieee80211.c
+++ b/drivers/staging/rtl8188eu/core/rtw_ieee80211.c
@@ -253,11 +253,11 @@ int rtw_generate_ie(struct registry_priv *pregistrypriv)
 	}
 
 	/* DS parameter set */
-	ie = rtw_set_ie(ie, _DSSET_IE_, 1, (u8 *)&(pdev_network->Configuration.DSConfig), &sz);
+	ie = rtw_set_ie(ie, _DSSET_IE_, 1, (u8 *)&pdev_network->Configuration.DSConfig, &sz);
 
 	/* IBSS Parameter Set */
 
-	ie = rtw_set_ie(ie, _IBSS_PARA_IE_, 2, (u8 *)&(pdev_network->Configuration.ATIMWindow), &sz);
+	ie = rtw_set_ie(ie, _IBSS_PARA_IE_, 2, (u8 *)&pdev_network->Configuration.ATIMWindow, &sz);
 
 	if (rateLen > 8)
 		ie = rtw_set_ie(ie, _EXT_SUPPORTEDRATES_IE_, (rateLen - 8), (pdev_network->SupportedRates + 8), &sz);
diff --git a/drivers/staging/rtl8188eu/core/rtw_led.c b/drivers/staging/rtl8188eu/core/rtw_led.c
index d1406cc99768..32dccae186ca 100644
--- a/drivers/staging/rtl8188eu/core/rtw_led.c
+++ b/drivers/staging/rtl8188eu/core/rtw_led.c
@@ -90,7 +90,6 @@ static void SwLedBlink1(struct LED_871x *pLed)
 {
 	struct adapter *padapter = pLed->padapter;
 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-	u8 bStopBlinking = false;
 
 	/*  Change LED according to BlinkingLedState specified. */
 	if (pLed->BlinkingLedState == RTW_LED_ON) {
@@ -128,9 +127,7 @@ static void SwLedBlink1(struct LED_871x *pLed)
 		break;
 	case LED_BLINK_SCAN:
 		pLed->BlinkTimes--;
-		if (pLed->BlinkTimes == 0)
-			bStopBlinking = true;
-		if (bStopBlinking) {
+		if (pLed->BlinkTimes == 0) {
 			if (check_fwstate(pmlmepriv, _FW_LINKED)) {
 				pLed->bLedLinkBlinkInProgress = true;
 				pLed->CurrLedState = LED_BLINK_NORMAL;
@@ -164,9 +161,7 @@ static void SwLedBlink1(struct LED_871x *pLed)
 		break;
 	case LED_BLINK_TXRX:
 		pLed->BlinkTimes--;
-		if (pLed->BlinkTimes == 0)
-			bStopBlinking = true;
-		if (bStopBlinking) {
+		if (pLed->BlinkTimes == 0) {
 			if (check_fwstate(pmlmepriv, _FW_LINKED)) {
 				pLed->bLedLinkBlinkInProgress = true;
 				pLed->CurrLedState = LED_BLINK_NORMAL;
@@ -188,7 +183,6 @@ static void SwLedBlink1(struct LED_871x *pLed)
 					  msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
 				RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState));
 			}
-			pLed->BlinkTimes = 0;
 			pLed->bLedBlinkInProgress = false;
 		} else {
 			if (pLed->bLedOn)
@@ -208,12 +202,7 @@ static void SwLedBlink1(struct LED_871x *pLed)
 			  msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
 		break;
 	case LED_BLINK_WPS_STOP:	/* WPS success */
-		if (pLed->BlinkingLedState == RTW_LED_ON)
-			bStopBlinking = false;
-		else
-			bStopBlinking = true;
-
-		if (bStopBlinking) {
+		if (pLed->BlinkingLedState != RTW_LED_ON) {
 			pLed->bLedLinkBlinkInProgress = true;
 			pLed->CurrLedState = LED_BLINK_NORMAL;
 			if (pLed->bLedOn)
diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
index 04897cd48370..8d035f67ef61 100644
--- a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
+++ b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
@@ -1781,7 +1781,7 @@ static void issue_action_BSSCoexistPacket(struct adapter *padapter)
 
 			p = rtw_get_ie(pbss_network->ies + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pbss_network->ie_length - _FIXED_IE_LENGTH_);
 			if (!p || len == 0) { /* non-HT */
-				if ((pbss_network->Configuration.DSConfig <= 0) || (pbss_network->Configuration.DSConfig > 14))
+				if (pbss_network->Configuration.DSConfig <= 0)
 					continue;
 
 				ICS[0][pbss_network->Configuration.DSConfig] = 1;
@@ -1932,11 +1932,11 @@ static void site_survey(struct adapter *padapter)
 				if (pmlmeext->sitesurvey_res.ssid[i].ssid_length) {
 					/* todo: to issue two probe req??? */
 					issue_probereq(padapter,
-					&(pmlmeext->sitesurvey_res.ssid[i]),
+					&pmlmeext->sitesurvey_res.ssid[i],
 								NULL, false);
 					/* msleep(SURVEY_TO>>1); */
 					issue_probereq(padapter,
-					&(pmlmeext->sitesurvey_res.ssid[i]),
+					&pmlmeext->sitesurvey_res.ssid[i],
 								NULL, false);
 				}
 			}
diff --git a/drivers/staging/rtl8188eu/hal/odm.c b/drivers/staging/rtl8188eu/hal/odm.c
index 698377ea60ee..b3cc40527730 100644
--- a/drivers/staging/rtl8188eu/hal/odm.c
+++ b/drivers/staging/rtl8188eu/hal/odm.c
@@ -193,7 +193,7 @@ void ODM_DMWatchdog(struct odm_dm_struct *pDM_Odm)
 	odm_DIG(pDM_Odm);
 	odm_CCKPacketDetectionThresh(pDM_Odm);
 
-	if (*(pDM_Odm->pbPowerSaving))
+	if (*pDM_Odm->pbPowerSaving)
 		return;
 
 	odm_RefreshRateAdaptiveMask(pDM_Odm);
@@ -229,13 +229,13 @@ void odm_CommonInfoSelfUpdate(struct odm_dm_struct *pDM_Odm)
 	u8 i;
 	struct sta_info *pEntry;
 
-	if (*(pDM_Odm->pBandWidth) == ODM_BW40M) {
-		if (*(pDM_Odm->pSecChOffset) == 1)
-			pDM_Odm->ControlChannel = *(pDM_Odm->pChannel) - 2;
-		else if (*(pDM_Odm->pSecChOffset) == 2)
-			pDM_Odm->ControlChannel = *(pDM_Odm->pChannel) + 2;
+	if (*pDM_Odm->pBandWidth == ODM_BW40M) {
+		if (*pDM_Odm->pSecChOffset == 1)
+			pDM_Odm->ControlChannel = *pDM_Odm->pChannel - 2;
+		else if (*pDM_Odm->pSecChOffset == 2)
+			pDM_Odm->ControlChannel = *pDM_Odm->pChannel + 2;
 	} else {
-		pDM_Odm->ControlChannel = *(pDM_Odm->pChannel);
+		pDM_Odm->ControlChannel = *pDM_Odm->pChannel;
 	}
 
 	for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) {
@@ -270,16 +270,16 @@ void odm_CmnInfoInit_Debug(struct odm_dm_struct *pDM_Odm)
 void odm_CmnInfoHook_Debug(struct odm_dm_struct *pDM_Odm)
 {
 	ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("odm_CmnInfoHook_Debug==>\n"));
-	ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pNumTxBytesUnicast=%llu\n", *(pDM_Odm->pNumTxBytesUnicast)));
-	ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pNumRxBytesUnicast=%llu\n", *(pDM_Odm->pNumRxBytesUnicast)));
-	ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pWirelessMode=0x%x\n", *(pDM_Odm->pWirelessMode)));
-	ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pSecChOffset=%d\n", *(pDM_Odm->pSecChOffset)));
-	ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pSecurity=%d\n", *(pDM_Odm->pSecurity)));
-	ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pBandWidth=%d\n", *(pDM_Odm->pBandWidth)));
-	ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pChannel=%d\n", *(pDM_Odm->pChannel)));
-
-	ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pbScanInProcess=%d\n", *(pDM_Odm->pbScanInProcess)));
-	ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pbPowerSaving=%d\n", *(pDM_Odm->pbPowerSaving)));
+	ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pNumTxBytesUnicast=%llu\n", *pDM_Odm->pNumTxBytesUnicast));
+	ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pNumRxBytesUnicast=%llu\n", *pDM_Odm->pNumRxBytesUnicast));
+	ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pWirelessMode=0x%x\n", *pDM_Odm->pWirelessMode));
+	ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pSecChOffset=%d\n", *pDM_Odm->pSecChOffset));
+	ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pSecurity=%d\n", *pDM_Odm->pSecurity));
+	ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pBandWidth=%d\n", *pDM_Odm->pBandWidth));
+	ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pChannel=%d\n", *pDM_Odm->pChannel));
+
+	ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pbScanInProcess=%d\n", *pDM_Odm->pbScanInProcess));
+	ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pbPowerSaving=%d\n", *pDM_Odm->pbPowerSaving));
 }
 
 void odm_CmnInfoUpdate_Debug(struct odm_dm_struct *pDM_Odm)
@@ -348,7 +348,7 @@ void odm_DIG(struct odm_dm_struct *pDM_Odm)
 		return;
 	}
 
-	if (*(pDM_Odm->pbScanInProcess)) {
+	if (*pDM_Odm->pbScanInProcess) {
 		ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG() Return: In Scan Progress\n"));
 		return;
 	}
@@ -508,7 +508,7 @@ void odm_FalseAlarmCounterStatistics(struct odm_dm_struct *pDM_Odm)
 {
 	struct adapter *adapter = pDM_Odm->Adapter;
 	u32 ret_value;
-	struct false_alarm_stats *FalseAlmCnt = &(pDM_Odm->FalseAlmCnt);
+	struct false_alarm_stats *FalseAlmCnt = &pDM_Odm->FalseAlmCnt;
 
 	if (!(pDM_Odm->SupportAbility & ODM_BB_FA_CNT))
 		return;
@@ -581,7 +581,7 @@ void odm_FalseAlarmCounterStatistics(struct odm_dm_struct *pDM_Odm)
 void odm_CCKPacketDetectionThresh(struct odm_dm_struct *pDM_Odm)
 {
 	u8 CurCCK_CCAThres;
-	struct false_alarm_stats *FalseAlmCnt = &(pDM_Odm->FalseAlmCnt);
+	struct false_alarm_stats *FalseAlmCnt = &pDM_Odm->FalseAlmCnt;
 
 	if (!(pDM_Odm->SupportAbility & (ODM_BB_CCK_PD | ODM_BB_FA_CNT)))
 		return;
@@ -739,7 +739,7 @@ u32 ODM_Get_Rate_Bitmap(struct odm_dm_struct *pDM_Odm, u32 macid, u32 ra_mask, u
 		} else if (rssi_level == DM_RATR_STA_MIDDLE) {
 			rate_bitmap = 0x000ff000;
 		} else {
-			if (*(pDM_Odm->pBandWidth) == ODM_BW40M)
+			if (*pDM_Odm->pBandWidth == ODM_BW40M)
 				rate_bitmap = 0x000ff015;
 			else
 				rate_bitmap = 0x000ff005;
@@ -945,7 +945,7 @@ void odm_TXPowerTrackingInit(struct odm_dm_struct *pDM_Odm)
 {
 	pDM_Odm->RFCalibrateInfo.bTXPowerTracking = true;
 	pDM_Odm->RFCalibrateInfo.TXPowercount = 0;
-	if (*(pDM_Odm->mp_mode) != 1)
+	if (*pDM_Odm->mp_mode != 1)
 		pDM_Odm->RFCalibrateInfo.TxPowerTrackControl = true;
 	MSG_88E("pDM_Odm TxPowerTrackControl = %d\n", pDM_Odm->RFCalibrateInfo.TxPowerTrackControl);
 
@@ -1035,11 +1035,11 @@ void odm_EdcaTurboCheckCE(struct odm_dm_struct *pDM_Odm)
 	u64	cur_tx_bytes = 0;
 	u64	cur_rx_bytes = 0;
 	u8	bbtchange = false;
-	struct xmit_priv		*pxmitpriv = &(Adapter->xmitpriv);
-	struct recv_priv		*precvpriv = &(Adapter->recvpriv);
+	struct xmit_priv		*pxmitpriv = &Adapter->xmitpriv;
+	struct recv_priv		*precvpriv = &Adapter->recvpriv;
 	struct registry_priv	*pregpriv = &Adapter->registrypriv;
-	struct mlme_ext_priv	*pmlmeext = &(Adapter->mlmeextpriv);
-	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
+	struct mlme_ext_priv	*pmlmeext = &Adapter->mlmeextpriv;
+	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
 
 	if (pregpriv->wifi_spec == 1) /*  (pmlmeinfo->HT_enable == 0)) */
 		goto dm_CheckEdcaTurbo_EXIT;
diff --git a/drivers/staging/rtl8188eu/hal/phy.c b/drivers/staging/rtl8188eu/hal/phy.c
index b9025815b682..5eca3625d5a8 100644
--- a/drivers/staging/rtl8188eu/hal/phy.c
+++ b/drivers/staging/rtl8188eu/hal/phy.c
@@ -345,8 +345,8 @@ static void dm_txpwr_track_setpwr(struct odm_dm_struct *dm_odm)
 {
 	if (dm_odm->BbSwingFlagOfdm || dm_odm->BbSwingFlagCck) {
 		ODM_RT_TRACE(dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
-			     ("dm_txpwr_track_setpwr CH=%d\n", *(dm_odm->pChannel)));
-		phy_set_tx_power_level(dm_odm->Adapter, *(dm_odm->pChannel));
+			     ("dm_txpwr_track_setpwr CH=%d\n", *dm_odm->pChannel));
+		phy_set_tx_power_level(dm_odm->Adapter, *dm_odm->pChannel);
 		dm_odm->BbSwingFlagOfdm = false;
 		dm_odm->BbSwingFlagCck = false;
 	}
@@ -975,7 +975,7 @@ static void phy_iq_calibrate(struct adapter *adapt, s32 result[][8],
 
 	u32 retry_count = 9;
 
-	if (*(dm_odm->mp_mode) == 1)
+	if (*dm_odm->mp_mode == 1)
 		retry_count = 9;
 	else
 		retry_count = 2;
@@ -1320,7 +1320,7 @@ void rtl88eu_phy_lc_calibrate(struct adapter *adapt)
 	if (singletone || carrier_sup)
 		return;
 
-	while (*(dm_odm->pbScanInProcess) && timecount < timeout) {
+	while (*dm_odm->pbScanInProcess && timecount < timeout) {
 		mdelay(50);
 		timecount += 50;
 	}
diff --git a/drivers/staging/rtl8188eu/hal/rf.c b/drivers/staging/rtl8188eu/hal/rf.c
index 00a9f692bb06..6702f263c770 100644
--- a/drivers/staging/rtl8188eu/hal/rf.c
+++ b/drivers/staging/rtl8188eu/hal/rf.c
@@ -79,7 +79,7 @@ void rtl88eu_phy_rf6052_set_cck_txpower(struct adapter *adapt, u8 *powerlevel)
 		}
 	}
 	for (idx1 = RF_PATH_A; idx1 <= RF_PATH_B; idx1++) {
-		ptr = (u8 *)(&(tx_agc[idx1]));
+		ptr = (u8 *)(&tx_agc[idx1]);
 		for (idx2 = 0; idx2 < 4; idx2++) {
 			if (*ptr > RF6052_MAX_TX_PWR)
 				*ptr = RF6052_MAX_TX_PWR;
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c b/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c
index 371e746915dd..176716d3e903 100644
--- a/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c
+++ b/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c
@@ -256,7 +256,7 @@ static void ConstructBeacon(struct adapter *adapt, u8 *pframe, u32 *pLength)
 	pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, min_t(u32, rate_len, 8), cur_network->SupportedRates, &pktlen);
 
 	/*  DS parameter set */
-	pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
+	pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&cur_network->Configuration.DSConfig, &pktlen);
 
 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
 		u32 ATIMWindow;
diff --git a/drivers/staging/rtl8188eu/include/osdep_service.h b/drivers/staging/rtl8188eu/include/osdep_service.h
index c0114ad79788..0d3e4a6e7e85 100644
--- a/drivers/staging/rtl8188eu/include/osdep_service.h
+++ b/drivers/staging/rtl8188eu/include/osdep_service.h
@@ -50,7 +50,7 @@ struct	__queue	{
 
 static inline struct list_head *get_list_head(struct __queue *queue)
 {
-	return &(queue->queue);
+	return &queue->queue;
 }
 
 static inline int rtw_netif_queue_stopped(struct net_device *pnetdev)
diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
index 9a89791720e0..d5968ef9f43d 100644
--- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
+++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
@@ -93,7 +93,7 @@ static char *translate_scan(struct adapter *padapter,
 			    struct wlan_network *pnetwork,
 			    char *start, char *stop)
 {
-	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 	struct iw_event iwe;
 	u16 cap;
 	__le16 le_tmp;
@@ -417,7 +417,7 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
 				ret = -EOPNOTSUPP;
 				goto exit;
 			}
-			memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
+			memcpy(&psecuritypriv->dot11DefKey[wep_key_idx].skey[0], pwep->KeyMaterial, pwep->KeyLength);
 			psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
 			rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0);
 		}
@@ -444,8 +444,8 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
 					memcpy(psta->dot118021x_UncstKey.skey,  param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16));
 
 					if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */
-						memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
-						memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
+						memcpy(psta->dot11tkiptxmickey.skey, &param->u.crypt.key[16], 8);
+						memcpy(psta->dot11tkiprxmickey.skey, &param->u.crypt.key[24], 8);
 						padapter->securitypriv.busetkipkey = false;
 					}
 
@@ -454,8 +454,8 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
 					rtw_setstakey_cmd(padapter, (unsigned char *)psta, true);
 				} else { /* group key */
 					memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16 ));
-					memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
-					memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
+					memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey, &param->u.crypt.key[16], 8);
+					memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey, &param->u.crypt.key[24], 8);
 					padapter->securitypriv.binstallGrpkey = true;
 					DBG_88E(" ~~~~set sta key:groupkey\n");
 
@@ -620,7 +620,7 @@ static int rtw_wx_get_name(struct net_device *dev,
 	u32 ht_ielen = 0;
 	char *p;
 	u8 ht_cap = false;
-	struct	mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
+	struct	mlme_priv	*pmlmepriv = &padapter->mlmepriv;
 	struct wlan_bssid_ex  *pcur_bss = &pmlmepriv->cur_network.network;
 	NDIS_802_11_RATES_EX *prates = NULL;
 
@@ -669,7 +669,7 @@ static int rtw_wx_get_freq(struct net_device *dev,
 			     union iwreq_data *wrqu, char *extra)
 {
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-	struct	mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
+	struct	mlme_priv	*pmlmepriv = &padapter->mlmepriv;
 	struct wlan_bssid_ex  *pcur_bss = &pmlmepriv->cur_network.network;
 
 	if (check_fwstate(pmlmepriv, _FW_LINKED)) {
@@ -738,7 +738,7 @@ static int rtw_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
 			     union iwreq_data *wrqu, char *b)
 {
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-	struct	mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
+	struct	mlme_priv	*pmlmepriv = &padapter->mlmepriv;
 
 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, (" rtw_wx_get_mode\n"));
 
@@ -938,10 +938,10 @@ static int rtw_wx_set_wap(struct net_device *dev,
 	uint ret = 0;
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
 	struct sockaddr *temp = (struct sockaddr *)awrq;
-	struct	mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
+	struct	mlme_priv	*pmlmepriv = &padapter->mlmepriv;
 	struct list_head *phead;
 	u8 *dst_bssid, *src_bssid;
-	struct __queue *queue	= &(pmlmepriv->scanned_queue);
+	struct __queue *queue	= &pmlmepriv->scanned_queue;
 	struct	wlan_network	*pnetwork = NULL;
 	enum ndis_802_11_auth_mode	authmode;
 
@@ -1002,7 +1002,7 @@ static int rtw_wx_get_wap(struct net_device *dev,
 			    union iwreq_data *wrqu, char *extra)
 {
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-	struct	mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
+	struct	mlme_priv	*pmlmepriv = &padapter->mlmepriv;
 	struct wlan_bssid_ex  *pcur_bss = &pmlmepriv->cur_network.network;
 
 	wrqu->ap_addr.sa_family = ARPHRD_ETHER;
@@ -1188,8 +1188,8 @@ static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
 {
 	struct list_head *plist, *phead;
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-	struct	mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
-	struct __queue *queue	= &(pmlmepriv->scanned_queue);
+	struct	mlme_priv	*pmlmepriv = &padapter->mlmepriv;
+	struct __queue *queue	= &pmlmepriv->scanned_queue;
 	struct	wlan_network	*pnetwork = NULL;
 	char *ev = extra;
 	char *stop = ev + wrqu->data.length;
@@ -1217,7 +1217,7 @@ static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
 			break;
 	}
 
-	spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
+	spin_lock_bh(&pmlmepriv->scanned_queue.lock);
 
 	phead = get_list_head(queue);
 	plist = phead->next;
@@ -1358,7 +1358,7 @@ static int rtw_wx_get_essid(struct net_device *dev,
 {
 	u32 len;
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-	struct	mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
+	struct	mlme_priv	*pmlmepriv = &padapter->mlmepriv;
 	struct wlan_bssid_ex  *pcur_bss = &pmlmepriv->cur_network.network;
 
 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_essid\n"));
@@ -1564,7 +1564,7 @@ static int rtw_wx_set_enc(struct net_device *dev,
 	struct ndis_802_11_wep	 wep;
 	enum ndis_802_11_auth_mode authmode;
 
-	struct iw_point *erq = &(wrqu->encoding);
+	struct iw_point *erq = &wrqu->encoding;
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
 	struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
 
@@ -1675,8 +1675,8 @@ static int rtw_wx_get_enc(struct net_device *dev,
 {
 	uint key;
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-	struct iw_point *erq = &(wrqu->encoding);
-	struct	mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
+	struct iw_point *erq = &wrqu->encoding;
+	struct	mlme_priv	*pmlmepriv = &padapter->mlmepriv;
 
 	if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
 		if (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
@@ -1759,7 +1759,7 @@ static int rtw_wx_set_auth(struct net_device *dev,
 			     union iwreq_data *wrqu, char *extra)
 {
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-	struct iw_param *param = (struct iw_param *)&(wrqu->param);
+	struct iw_param *param = (struct iw_param *)&wrqu->param;
 	int ret = 0;
 
 	switch (param->flags & IW_AUTH_INDEX) {
@@ -2012,14 +2012,9 @@ static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)
 	if (!p->pointer || p->length != sizeof(struct ieee_param))
 		return -EINVAL;
 
-	param = (struct ieee_param *)rtw_malloc(p->length);
-	if (!param)
-		return -ENOMEM;
-
-	if (copy_from_user(param, p->pointer, p->length)) {
-		kfree(param);
-		return -EFAULT;
-	}
+	param = memdup_user(p->pointer, p->length);
+	if (IS_ERR(param))
+		return PTR_ERR(param);
 
 	switch (param->cmd) {
 	case IEEE_CMD_SET_WPA_PARAM:
@@ -2093,7 +2088,7 @@ static int set_group_key(struct adapter *padapter, u8 *key, u8 alg, int keyid)
 	u8 keylen;
 	struct cmd_obj *pcmd;
 	struct setkey_parm *psetkeyparm;
-	struct cmd_priv	*pcmdpriv = &(padapter->cmdpriv);
+	struct cmd_priv	*pcmdpriv = &padapter->cmdpriv;
 	int res = _SUCCESS;
 
 	DBG_88E("%s\n", __func__);
@@ -2130,7 +2125,7 @@ static int set_group_key(struct adapter *padapter, u8 *key, u8 alg, int keyid)
 		keylen = 16;
 	}
 
-	memcpy(&(psetkeyparm->key[0]), key, keylen);
+	memcpy(&psetkeyparm->key[0], key, keylen);
 
 	pcmd->cmdcode = _SetKey_CMD_;
 	pcmd->parmbuf = (u8 *)psetkeyparm;
@@ -2173,7 +2168,7 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param,
 	struct sta_info *psta = NULL, *pbcmc_sta = NULL;
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
-	struct security_priv *psecuritypriv = &(padapter->securitypriv);
+	struct security_priv *psecuritypriv = &padapter->securitypriv;
 	struct sta_priv *pstapriv = &padapter->stapriv;
 
 	DBG_88E("%s\n", __func__);
@@ -2245,7 +2240,7 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param,
 
 			psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
 
-			memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
+			memcpy(&psecuritypriv->dot11DefKey[wep_key_idx].skey[0], pwep->KeyMaterial, pwep->KeyLength);
 
 			psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
 
@@ -2256,7 +2251,7 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param,
 			/* don't update "psecuritypriv->dot11PrivacyAlgrthm" and */
 			/* psecuritypriv->dot11PrivacyKeyIndex = keyid", but can rtw_set_key to cam */
 
-			memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
+			memcpy(&psecuritypriv->dot11DefKey[wep_key_idx].skey[0], pwep->KeyMaterial, pwep->KeyLength);
 
 			psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
 
@@ -2283,8 +2278,8 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param,
 				memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
 					    param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16));
 				/* set mic key */
-				memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
-				memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
+				memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &param->u.crypt.key[16], 8);
+				memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &param->u.crypt.key[24], 8);
 
 				psecuritypriv->busetkipkey = true;
 			} else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
@@ -2326,8 +2321,8 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param,
 					psta->dot118021XPrivacy = _TKIP_;
 
 					/* set mic key */
-					memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
-					memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
+					memcpy(psta->dot11tkiptxmickey.skey, &param->u.crypt.key[16], 8);
+					memcpy(psta->dot11tkiprxmickey.skey, &param->u.crypt.key[24], 8);
 
 					psecuritypriv->busetkipkey = true;
 				} else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
@@ -2357,8 +2352,8 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param,
 						    param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16));
 
 					/* set mic key */
-					memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
-					memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
+					memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &param->u.crypt.key[16], 8);
+					memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &param->u.crypt.key[24], 8);
 
 					psecuritypriv->busetkipkey = true;
 				} else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
@@ -2398,7 +2393,7 @@ static int rtw_set_beacon(struct net_device *dev, struct ieee_param *param, int
 {
 	int ret = 0;
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 	struct sta_priv *pstapriv = &padapter->stapriv;
 	unsigned char *pbuf = param->u.bcn_ie.buf;
 
@@ -2436,7 +2431,7 @@ static int rtw_add_sta(struct net_device *dev, struct ieee_param *param)
 	int ret = 0;
 	struct sta_info *psta = NULL;
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 	struct sta_priv *pstapriv = &padapter->stapriv;
 
 	DBG_88E("rtw_add_sta(aid =%d) =%pM\n", param->u.add_sta.aid, (param->sta_addr));
@@ -2489,7 +2484,7 @@ static int rtw_del_sta(struct net_device *dev, struct ieee_param *param)
 {
 	struct sta_info *psta = NULL;
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 	struct sta_priv *pstapriv = &padapter->stapriv;
 	int updated = 0;
 
@@ -2524,7 +2519,7 @@ static int rtw_ioctl_get_sta_data(struct net_device *dev, struct ieee_param *par
 	int ret = 0;
 	struct sta_info *psta = NULL;
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 	struct sta_priv *pstapriv = &padapter->stapriv;
 	struct ieee_param_ex *param_ex = (struct ieee_param_ex *)param;
 	struct sta_data *psta_data = (struct sta_data *)param_ex->data;
@@ -2580,7 +2575,7 @@ static int rtw_get_sta_wpaie(struct net_device *dev, struct ieee_param *param)
 	int ret = 0;
 	struct sta_info *psta = NULL;
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 	struct sta_priv *pstapriv = &padapter->stapriv;
 
 	DBG_88E("rtw_get_sta_wpaie, sta_addr: %pM\n", (param->sta_addr));
@@ -2616,8 +2611,8 @@ static int rtw_set_wps_beacon(struct net_device *dev, struct ieee_param *param,
 {
 	unsigned char wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
-	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
+	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
 	int ie_len;
 
 	DBG_88E("%s, len =%d\n", __func__, len);
@@ -2651,7 +2646,7 @@ static int rtw_set_wps_beacon(struct net_device *dev, struct ieee_param *param,
 static int rtw_set_wps_probe_resp(struct net_device *dev, struct ieee_param *param, int len)
 {
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 	int ie_len;
 
 	DBG_88E("%s, len =%d\n", __func__, len);
@@ -2680,7 +2675,7 @@ static int rtw_set_wps_probe_resp(struct net_device *dev, struct ieee_param *par
 static int rtw_set_wps_assoc_resp(struct net_device *dev, struct ieee_param *param, int len)
 {
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 	int ie_len;
 
 	DBG_88E("%s, len =%d\n", __func__, len);
@@ -2710,9 +2705,9 @@ static int rtw_set_wps_assoc_resp(struct net_device *dev, struct ieee_param *par
 static int rtw_set_hidden_ssid(struct net_device *dev, struct ieee_param *param, int len)
 {
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
-	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
-	struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
+	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
 
 	u8 value;
 
@@ -2734,7 +2729,7 @@ static int rtw_set_hidden_ssid(struct net_device *dev, struct ieee_param *param,
 static int rtw_ioctl_acl_remove_sta(struct net_device *dev, struct ieee_param *param, int len)
 {
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 
 	if (!check_fwstate(pmlmepriv, WIFI_AP_STATE))
 		return -EINVAL;
@@ -2748,7 +2743,7 @@ static int rtw_ioctl_acl_remove_sta(struct net_device *dev, struct ieee_param *p
 static int rtw_ioctl_acl_add_sta(struct net_device *dev, struct ieee_param *param, int len)
 {
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 
 	if (!check_fwstate(pmlmepriv, WIFI_AP_STATE))
 		return -EINVAL;
@@ -2762,7 +2757,7 @@ static int rtw_ioctl_acl_add_sta(struct net_device *dev, struct ieee_param *para
 static int rtw_ioctl_set_macaddr_acl(struct net_device *dev, struct ieee_param *param, int len)
 {
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 
 	if (!check_fwstate(pmlmepriv, WIFI_AP_STATE))
 		return -EINVAL;
@@ -2789,14 +2784,9 @@ static int rtw_hostapd_ioctl(struct net_device *dev, struct iw_point *p)
 	if (!p->pointer || p->length != sizeof(struct ieee_param))
 		return -EINVAL;
 
-	param = (struct ieee_param *)rtw_malloc(p->length);
-	if (!param)
-		return -ENOMEM;
-
-	if (copy_from_user(param, p->pointer, p->length)) {
-		kfree(param);
-		return -EFAULT;
-	}
+	param = memdup_user(p->pointer, p->length);
+	if (IS_ERR(param))
+		return PTR_ERR(param);
 
 	switch (param->cmd) {
 	case RTL871X_HOSTAPD_FLUSH:
@@ -2882,7 +2872,7 @@ static int rtw_wx_set_priv(struct net_device *dev,
 	/* added for wps2.0 @20110524 */
 	if (dwrq->flags == 0x8766 && len > 8) {
 		u32 cp_sz;
-		struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+		struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 		u8 *probereq_wpsie = ext;
 		int probereq_wpsie_len = len;
 		u8 wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
diff --git a/drivers/staging/rtl8188eu/os_dep/rtw_android.c b/drivers/staging/rtl8188eu/os_dep/rtw_android.c
index daf6db354982..bf86d03820ca 100644
--- a/drivers/staging/rtl8188eu/os_dep/rtw_android.c
+++ b/drivers/staging/rtl8188eu/os_dep/rtw_android.c
@@ -77,7 +77,7 @@ static int rtw_android_get_rssi(struct net_device *net, char *command,
 				int total_len)
 {
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(net);
-	struct	mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
+	struct	mlme_priv	*pmlmepriv = &padapter->mlmepriv;
 	struct	wlan_network	*pcur_network = &pmlmepriv->cur_network;
 	int bytes_written = 0;
 
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c
index 20e494186c9e..43494a2b6f05 100644
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c
+++ b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c
@@ -2444,7 +2444,7 @@ static void _rtl92e_dm_init_dynamic_tx_power(struct net_device *dev)
 static void _rtl92e_dm_dynamic_tx_power(struct net_device *dev)
 {
 	struct r8192_priv *priv = rtllib_priv(dev);
-	unsigned int txhipower_threshhold = 0;
+	unsigned int txhipower_threshold = 0;
 	unsigned int txlowpower_threshold = 0;
 
 	if (priv->rtllib->bdynamic_txpower_enable != true) {
@@ -2454,10 +2454,10 @@ static void _rtl92e_dm_dynamic_tx_power(struct net_device *dev)
 	}
 	if ((priv->rtllib->pHTInfo->IOTPeer == HT_IOT_PEER_ATHEROS) &&
 	    (priv->rtllib->mode == IEEE_G)) {
-		txhipower_threshhold = TX_POWER_ATHEROAP_THRESH_HIGH;
+		txhipower_threshold = TX_POWER_ATHEROAP_THRESH_HIGH;
 		txlowpower_threshold = TX_POWER_ATHEROAP_THRESH_LOW;
 	} else {
-		txhipower_threshhold = TX_POWER_NEAR_FIELD_THRESH_HIGH;
+		txhipower_threshold = TX_POWER_NEAR_FIELD_THRESH_HIGH;
 		txlowpower_threshold = TX_POWER_NEAR_FIELD_THRESH_LOW;
 	}
 
@@ -2465,7 +2465,7 @@ static void _rtl92e_dm_dynamic_tx_power(struct net_device *dev)
 		 priv->undecorated_smoothed_pwdb);
 
 	if (priv->rtllib->state == RTLLIB_LINKED) {
-		if (priv->undecorated_smoothed_pwdb >= txhipower_threshhold) {
+		if (priv->undecorated_smoothed_pwdb >= txhipower_threshold) {
 			priv->bDynamicTxHighPower = true;
 			priv->bDynamicTxLowPower = false;
 		} else {
diff --git a/drivers/staging/rtl8712/rtl871x_xmit.c b/drivers/staging/rtl8712/rtl871x_xmit.c
index f0b85338b567..2f0d0ffa6fae 100644
--- a/drivers/staging/rtl8712/rtl871x_xmit.c
+++ b/drivers/staging/rtl8712/rtl871x_xmit.c
@@ -71,12 +71,13 @@ int _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv,
 	_init_queue(&pxmitpriv->apsd_queue);
 	_init_queue(&pxmitpriv->free_xmit_queue);
 	/*
-	 * Please allocate memory with the sz = (struct xmit_frame) * NR_XMITFRAME,
+	 * Please allocate memory with sz = (struct xmit_frame) * NR_XMITFRAME,
 	 * and initialize free_xmit_frame below.
 	 * Please also apply  free_txobj to link_up all the xmit_frames...
 	 */
 	pxmitpriv->pallocated_frame_buf =
-		kmalloc(NR_XMITFRAME * sizeof(struct xmit_frame) + 4, GFP_ATOMIC);
+		kmalloc(NR_XMITFRAME * sizeof(struct xmit_frame) + 4,
+			GFP_ATOMIC);
 	if (!pxmitpriv->pallocated_frame_buf) {
 		pxmitpriv->pxmit_frame_buf = NULL;
 		return -ENOMEM;
@@ -126,8 +127,8 @@ int _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv,
 	pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
 	for (i = 0; i < NR_XMITBUFF; i++) {
 		INIT_LIST_HEAD(&pxmitbuf->list);
-		pxmitbuf->pallocated_buf = kmalloc(MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ,
-						   GFP_ATOMIC);
+		pxmitbuf->pallocated_buf =
+			kmalloc(MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ, GFP_ATOMIC);
 		if (!pxmitbuf->pallocated_buf)
 			return -ENOMEM;
 		pxmitbuf->pbuf = pxmitbuf->pallocated_buf + XMITBUF_ALIGN_SZ -
@@ -350,7 +351,7 @@ static int xmitframe_addmic(struct _adapter *padapter,
 	struct	sta_info *stainfo;
 	struct	qos_priv *pqospriv = &(padapter->mlmepriv.qospriv);
 	struct	pkt_attrib  *pattrib = &pxmitframe->attrib;
-	struct	security_priv *psecuritypriv = &padapter->securitypriv;
+	struct	security_priv *psecpriv = &padapter->securitypriv;
 	struct	xmit_priv *pxmitpriv = &padapter->xmitpriv;
 	u8 priority[4] = {0x0, 0x0, 0x0, 0x0};
 	bool bmcst = is_multicast_ether_addr(pattrib->ra);
@@ -368,15 +369,14 @@ static int xmitframe_addmic(struct _adapter *padapter,
 					   0x0, 0x0};
 			pframe = pxmitframe->buf_addr + TXDESC_OFFSET;
 			if (bmcst) {
-				if (!memcmp(psecuritypriv->XGrptxmickey
-				   [psecuritypriv->XGrpKeyid].skey,
+				if (!memcmp(psecpriv->XGrptxmickey
+				   [psecpriv->XGrpKeyid].skey,
 				   null_key, 16))
 					return -ENOMEM;
 				/*start to calculate the mic code*/
 				r8712_secmicsetkey(&micdata,
-					 psecuritypriv->
-					 XGrptxmickey[psecuritypriv->
-					XGrpKeyid].skey);
+					psecpriv->XGrptxmickey
+					[psecpriv->XGrpKeyid].skey);
 			} else {
 				if (!memcmp(&stainfo->tkiptxmickey.skey[0],
 					    null_key, 16))
@@ -416,7 +416,7 @@ static int xmitframe_addmic(struct _adapter *padapter,
 					length = pattrib->last_txcmdsz -
 						  pattrib->hdrlen -
 						  pattrib->iv_len -
-						  ((psecuritypriv->sw_encrypt)
+						  ((psecpriv->sw_encrypt)
 						  ? pattrib->icv_len : 0);
 					r8712_secmicappend(&micdata, payload,
 							   length);
@@ -424,7 +424,7 @@ static int xmitframe_addmic(struct _adapter *padapter,
 				} else {
 					length = pxmitpriv->frag_len -
 					    pattrib->hdrlen - pattrib->iv_len -
-					    ((psecuritypriv->sw_encrypt) ?
+					    ((psecpriv->sw_encrypt) ?
 					    pattrib->icv_len : 0);
 					r8712_secmicappend(&micdata, payload,
 							   length);
@@ -477,75 +477,72 @@ static int make_wlanhdr(struct _adapter *padapter, u8 *hdr,
 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 	struct qos_priv *pqospriv = &pmlmepriv->qospriv;
 	__le16 *fctrl = &pwlanhdr->frame_ctl;
+	u8 *bssid;
 
 	memset(hdr, 0, WLANHDR_OFFSET);
 	SetFrameSubType(fctrl, pattrib->subtype);
-	if (pattrib->subtype & WIFI_DATA_TYPE) {
-		if (check_fwstate(pmlmepriv,  WIFI_STATION_STATE)) {
-			/* to_ds = 1, fr_ds = 0; */
-			SetToDs(fctrl);
-			memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv),
-				ETH_ALEN);
-			memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
-			memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN);
-		} else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
-			/* to_ds = 0, fr_ds = 1; */
-			SetFrDs(fctrl);
-			memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
-			memcpy(pwlanhdr->addr2, get_bssid(pmlmepriv),
-				ETH_ALEN);
-			memcpy(pwlanhdr->addr3, pattrib->src, ETH_ALEN);
-		} else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
-			   check_fwstate(pmlmepriv,
-					 WIFI_ADHOC_MASTER_STATE)) {
-			memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
-			memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
-			memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv),
-				ETH_ALEN);
-		} else if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
-			memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
-			memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
-			memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv),
-				ETH_ALEN);
-		} else {
-			return -EINVAL;
-		}
+	if (!(pattrib->subtype & WIFI_DATA_TYPE))
+		return 0;
 
-		if (pattrib->encrypt)
-			SetPrivacy(fctrl);
-		if (pqospriv->qos_option) {
-			qc = (unsigned short *)(hdr + pattrib->hdrlen - 2);
-			if (pattrib->priority)
-				SetPriority(qc, pattrib->priority);
-			SetAckpolicy(qc, pattrib->ack_policy);
-		}
-		/* TODO: fill HT Control Field */
-		/* Update Seq Num will be handled by f/w */
-		{
-			struct sta_info *psta;
-			bool bmcst = is_multicast_ether_addr(pattrib->ra);
-
-			if (pattrib->psta) {
-				psta = pattrib->psta;
-			} else {
-				if (bmcst)
-					psta = r8712_get_bcmc_stainfo(padapter);
-				else
-					psta =
-					 r8712_get_stainfo(&padapter->stapriv,
-					 pattrib->ra);
-			}
-			if (psta) {
-				psta->sta_xmitpriv.txseq_tid
-						  [pattrib->priority]++;
-				psta->sta_xmitpriv.txseq_tid[pattrib->priority]
-						   &= 0xFFF;
-				pattrib->seqnum = psta->sta_xmitpriv.
-						  txseq_tid[pattrib->priority];
-				SetSeqNum(hdr, pattrib->seqnum);
-			}
+	bssid = get_bssid(pmlmepriv);
+
+	if (check_fwstate(pmlmepriv,  WIFI_STATION_STATE)) {
+		/* to_ds = 1, fr_ds = 0; */
+		SetToDs(fctrl);
+		ether_addr_copy(pwlanhdr->addr1, bssid);
+		ether_addr_copy(pwlanhdr->addr2, pattrib->src);
+		ether_addr_copy(pwlanhdr->addr3, pattrib->dst);
+	} else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
+		/* to_ds = 0, fr_ds = 1; */
+		SetFrDs(fctrl);
+		ether_addr_copy(pwlanhdr->addr1, pattrib->dst);
+		ether_addr_copy(pwlanhdr->addr2, bssid);
+		ether_addr_copy(pwlanhdr->addr3, pattrib->src);
+	} else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
+		   check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
+		ether_addr_copy(pwlanhdr->addr1, pattrib->dst);
+		ether_addr_copy(pwlanhdr->addr2, pattrib->src);
+		ether_addr_copy(pwlanhdr->addr3, bssid);
+	} else if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
+		ether_addr_copy(pwlanhdr->addr1, pattrib->dst);
+		ether_addr_copy(pwlanhdr->addr2, pattrib->src);
+		ether_addr_copy(pwlanhdr->addr3, bssid);
+	} else {
+		return -EINVAL;
+	}
+
+	if (pattrib->encrypt)
+		SetPrivacy(fctrl);
+	if (pqospriv->qos_option) {
+		qc = (unsigned short *)(hdr + pattrib->hdrlen - 2);
+		if (pattrib->priority)
+			SetPriority(qc, pattrib->priority);
+		SetAckpolicy(qc, pattrib->ack_policy);
+	}
+	/* TODO: fill HT Control Field */
+	/* Update Seq Num will be handled by f/w */
+	{
+		struct sta_info *psta;
+		bool bmcst = is_multicast_ether_addr(pattrib->ra);
+
+		if (pattrib->psta)
+			psta = pattrib->psta;
+		else if (bmcst)
+			psta = r8712_get_bcmc_stainfo(padapter);
+		else
+			psta = r8712_get_stainfo(&padapter->stapriv,
+						 pattrib->ra);
+
+		if (psta) {
+			u16 *txtid = psta->sta_xmitpriv.txseq_tid;
+
+			txtid[pattrib->priority]++;
+			txtid[pattrib->priority] &= 0xFFF;
+			pattrib->seqnum = txtid[pattrib->priority];
+			SetSeqNum(hdr, pattrib->seqnum);
 		}
 	}
+
 	return 0;
 }
 
@@ -589,7 +586,7 @@ sint r8712_xmitframe_coalesce(struct _adapter *padapter, _pkt *pkt,
 	addr_t addr;
 	u8 *pframe, *mem_start, *ptxdesc;
 	struct sta_info		*psta;
-	struct security_priv	*psecuritypriv = &padapter->securitypriv;
+	struct security_priv	*psecpriv = &padapter->securitypriv;
 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
 	struct xmit_priv	*pxmitpriv = &padapter->xmitpriv;
 	struct pkt_attrib	*pattrib = &pxmitframe->attrib;
@@ -632,15 +629,13 @@ sint r8712_xmitframe_coalesce(struct _adapter *padapter, _pkt *pkt,
 				case _WEP40_:
 				case _WEP104_:
 					WEP_IV(pattrib->iv, psta->txpn,
-					       (u8)psecuritypriv->
-					       PrivacyKeyIndex);
+					       (u8)psecpriv->PrivacyKeyIndex);
 					break;
 				case _TKIP_:
 					if (bmcst)
 						TKIP_IV(pattrib->iv,
 						    psta->txpn,
-						    (u8)psecuritypriv->
-						    XGrpKeyid);
+						    (u8)psecpriv->XGrpKeyid);
 					else
 						TKIP_IV(pattrib->iv, psta->txpn,
 							0);
@@ -648,8 +643,7 @@ sint r8712_xmitframe_coalesce(struct _adapter *padapter, _pkt *pkt,
 				case _AES_:
 					if (bmcst)
 						AES_IV(pattrib->iv, psta->txpn,
-						    (u8)psecuritypriv->
-						    XGrpKeyid);
+						    (u8)psecpriv->XGrpKeyid);
 					else
 						AES_IV(pattrib->iv, psta->txpn,
 						       0);
diff --git a/drivers/staging/rtl8712/rtl871x_xmit.h b/drivers/staging/rtl8712/rtl871x_xmit.h
index f227828094bf..c0c0c781fe17 100644
--- a/drivers/staging/rtl8712/rtl871x_xmit.h
+++ b/drivers/staging/rtl8712/rtl871x_xmit.h
@@ -115,7 +115,7 @@ struct pkt_attrib {
 	u8	icv_len;
 	unsigned char iv[8];
 	unsigned char icv[8];
-	u8	dst[ETH_ALEN];
+	u8	dst[ETH_ALEN] __aligned(2);	/* for ether_addr_copy */
 	u8	src[ETH_ALEN];
 	u8	ta[ETH_ALEN];
 	u8	ra[ETH_ALEN];
diff --git a/drivers/staging/rtl8723bs/hal/hal_com_phycfg.c b/drivers/staging/rtl8723bs/hal/hal_com_phycfg.c
index 767e2a784f78..10250642d30a 100644
--- a/drivers/staging/rtl8723bs/hal/hal_com_phycfg.c
+++ b/drivers/staging/rtl8723bs/hal/hal_com_phycfg.c
@@ -1816,7 +1816,7 @@ static void phy_CrossReferenceHTAndVHTTxPowerLimit(struct adapter *padapter)
 	s8 tempPwrLmt = 0;
 
 	for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
-		for (bw = 0; bw < MAX_5G_BANDWITH_NUM; ++bw) {
+		for (bw = 0; bw < MAX_5G_BANDWIDTH_NUM; ++bw) {
 			for (channel = 0; channel < CHANNEL_MAX_NUMBER_5G; ++channel) {
 				for (rateSection = 0; rateSection < MAX_RATE_SECTION_NUM; ++rateSection) {
 					tempPwrLmt = pHalData->TxPwrLimit_5G[regulation][bw][rateSection][channel][ODM_RF_PATH_A];
@@ -1877,7 +1877,7 @@ void PHY_ConvertTxPowerLimitToPowerIndex(struct adapter *Adapter)
 	phy_CrossReferenceHTAndVHTTxPowerLimit(Adapter);
 
 	for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
-		for (bw = 0; bw < MAX_2_4G_BANDWITH_NUM; ++bw) {
+		for (bw = 0; bw < MAX_2_4G_BANDWIDTH_NUM; ++bw) {
 			for (channel = 0; channel < CHANNEL_MAX_NUMBER_2G; ++channel) {
 				for (rateSection = 0; rateSection < MAX_RATE_SECTION_NUM; ++rateSection) {
 					tempPwrLmt = pHalData->TxPwrLimit_2_4G[regulation][bw][rateSection][channel][ODM_RF_PATH_A];
@@ -1920,7 +1920,7 @@ void PHY_InitTxPowerLimit(struct adapter *Adapter)
 	/* DBG_871X("=====> PHY_InitTxPowerLimit()!\n"); */
 
 	for (i = 0; i < MAX_REGULATION_NUM; ++i) {
-		for (j = 0; j < MAX_2_4G_BANDWITH_NUM; ++j)
+		for (j = 0; j < MAX_2_4G_BANDWIDTH_NUM; ++j)
 			for (k = 0; k < MAX_RATE_SECTION_NUM; ++k)
 				for (m = 0; m < CHANNEL_MAX_NUMBER_2G; ++m)
 					for (l = 0; l < MAX_RF_PATH_NUM; ++l)
@@ -1928,7 +1928,7 @@ void PHY_InitTxPowerLimit(struct adapter *Adapter)
 	}
 
 	for (i = 0; i < MAX_REGULATION_NUM; ++i) {
-		for (j = 0; j < MAX_5G_BANDWITH_NUM; ++j)
+		for (j = 0; j < MAX_5G_BANDWIDTH_NUM; ++j)
 			for (k = 0; k < MAX_RATE_SECTION_NUM; ++k)
 				for (m = 0; m < CHANNEL_MAX_NUMBER_5G; ++m)
 					for (l = 0; l < MAX_RF_PATH_NUM; ++l)
diff --git a/drivers/staging/rtl8723bs/hal/odm.h b/drivers/staging/rtl8723bs/hal/odm.h
index b77d1fe33a28..16e8f66a3171 100644
--- a/drivers/staging/rtl8723bs/hal/odm.h
+++ b/drivers/staging/rtl8723bs/hal/odm.h
@@ -541,7 +541,7 @@ typedef enum tag_Operation_Mode_Definition {
 
 /*  ODM_CMNINFO_WM_MODE */
 typedef enum tag_Wireless_Mode_Definition {
-	ODM_WM_UNKNOW     = 0x0,
+	ODM_WM_UNKNOWN    = 0x0,
 	ODM_WM_B          = BIT0,
 	ODM_WM_G          = BIT1,
 	ODM_WM_A          = BIT2,
diff --git a/drivers/staging/rtl8723bs/hal/odm_RegDefine11N.h b/drivers/staging/rtl8723bs/hal/odm_RegDefine11N.h
index f2c0707aad4c..1c6c08000e27 100644
--- a/drivers/staging/rtl8723bs/hal/odm_RegDefine11N.h
+++ b/drivers/staging/rtl8723bs/hal/odm_RegDefine11N.h
@@ -31,8 +31,8 @@
 #define	ODM_REG_TX_ANT_CTRL_11N			0x80C
 #define	ODM_REG_BB_PWR_SAV5_11N		0x818
 #define	ODM_REG_CCK_RPT_FORMAT_11N		0x824
-#define	ODM_REG_RX_DEFUALT_A_11N		0x858
-#define	ODM_REG_RX_DEFUALT_B_11N		0x85A
+#define	ODM_REG_RX_DEFAULT_A_11N		0x858
+#define	ODM_REG_RX_DEFAULT_B_11N		0x85A
 #define	ODM_REG_BB_PWR_SAV3_11N		0x85C
 #define	ODM_REG_ANTSEL_CTRL_11N			0x860
 #define	ODM_REG_RX_ANT_CTRL_11N			0x864
diff --git a/drivers/staging/rtl8723bs/include/hal_data.h b/drivers/staging/rtl8723bs/include/hal_data.h
index e5e667df6154..fa5d70016f05 100644
--- a/drivers/staging/rtl8723bs/include/hal_data.h
+++ b/drivers/staging/rtl8723bs/include/hal_data.h
@@ -56,9 +56,9 @@ enum RT_AMPDU_BURST {
 /*  Tx Power Limit Table Size */
 #define MAX_REGULATION_NUM			4
 #define MAX_RF_PATH_NUM_IN_POWER_LIMIT_TABLE	4
-#define MAX_2_4G_BANDWITH_NUM			4
+#define MAX_2_4G_BANDWIDTH_NUM			4
 #define MAX_RATE_SECTION_NUM			10
-#define MAX_5G_BANDWITH_NUM			4
+#define MAX_5G_BANDWIDTH_NUM			4
 
 #define MAX_BASE_NUM_IN_PHY_REG_PG_2_4G		10 /*   CCK:1, OFDM:1, HT:4, VHT:4 */
 #define MAX_BASE_NUM_IN_PHY_REG_PG_5G		9 /*  OFDM:1, HT:4, VHT:4 */
@@ -280,14 +280,14 @@ struct hal_com_data {
 
 	/*  Power Limit Table for 2.4G */
 	s8	TxPwrLimit_2_4G[MAX_REGULATION_NUM]
-						[MAX_2_4G_BANDWITH_NUM]
+						[MAX_2_4G_BANDWIDTH_NUM]
 	                                [MAX_RATE_SECTION_NUM]
 	                                [CHANNEL_MAX_NUMBER_2G]
 						[MAX_RF_PATH_NUM];
 
 	/*  Power Limit Table for 5G */
 	s8	TxPwrLimit_5G[MAX_REGULATION_NUM]
-						[MAX_5G_BANDWITH_NUM]
+						[MAX_5G_BANDWIDTH_NUM]
 						[MAX_RATE_SECTION_NUM]
 						[CHANNEL_MAX_NUMBER_5G]
 						[MAX_RF_PATH_NUM];
diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c
index 59568d18ce23..e478290b60a8 100644
--- a/drivers/staging/sm750fb/sm750.c
+++ b/drivers/staging/sm750fb/sm750.c
@@ -709,7 +709,9 @@ static int sm750fb_set_drv(struct lynxfb_par *par)
 		} else {
 			output->paths = sm750_crt;
 			crtc->channel = sm750_primary;
-			/* not consider of padding stuffs for oScreen,need fix */
+			/* not consider of padding stuffs for oScreen,
+			 * need fix
+			 */
 			crtc->oScreen = sm750_dev->vidmem_size >> 1;
 			crtc->vScreen = sm750_dev->pvMem + crtc->oScreen;
 		}
diff --git a/drivers/staging/unisys/visorhba/visorhba_main.c b/drivers/staging/unisys/visorhba/visorhba_main.c
index dd979ee4dcf1..99c57ceeb357 100644
--- a/drivers/staging/unisys/visorhba/visorhba_main.c
+++ b/drivers/staging/unisys/visorhba/visorhba_main.c
@@ -292,7 +292,7 @@ static void cleanup_scsitaskmgmt_handles(struct idr *idrtable,
  * @tasktype: Type of taskmgmt command
  * @scsidev:  Scsidev that issued command
  *
- * Create a cmdrsp packet and send it to the Serivce Partition
+ * Create a cmdrsp packet and send it to the Service Partition
  * that will service this request.
  *
  * Return: Int representing whether command was queued successfully or not
diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
index 597acef35d0b..6d554d49fd3f 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
@@ -369,8 +369,7 @@ static void buffer_cb(struct vchiq_mmal_instance *instance,
 
 	if (dev->capture.vc_start_timestamp != -1 && pts) {
 		ktime_t timestamp;
-		s64 runtime_us = pts -
-		    dev->capture.vc_start_timestamp;
+		s64 runtime_us = pts - dev->capture.vc_start_timestamp;
 		timestamp = ktime_add_us(dev->capture.kernel_start_ts,
 					 runtime_us);
 		v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
@@ -420,9 +419,8 @@ static int enable_camera(struct bm2835_mmal_dev *dev)
 			return -EINVAL;
 		}
 
-		ret = vchiq_mmal_component_enable(
-				dev->instance,
-				dev->component[COMP_CAMERA]);
+		ret = vchiq_mmal_component_enable(dev->instance,
+						  dev->component[COMP_CAMERA]);
 		if (ret < 0) {
 			v4l2_err(&dev->v4l2_dev,
 				 "Failed enabling camera, ret %d\n", ret);
@@ -451,10 +449,8 @@ static int disable_camera(struct bm2835_mmal_dev *dev)
 
 		v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
 			 "Disabling camera\n");
-		ret =
-		    vchiq_mmal_component_disable(
-				dev->instance,
-				dev->component[COMP_CAMERA]);
+		ret = vchiq_mmal_component_disable(dev->instance,
+						   dev->component[COMP_CAMERA]);
 		if (ret < 0) {
 			v4l2_err(&dev->v4l2_dev,
 				 "Failed disabling camera, ret %d\n", ret);
@@ -555,8 +551,8 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count)
 
 	/* enable the camera port */
 	dev->capture.port->cb_ctx = dev;
-	ret =
-	    vchiq_mmal_port_enable(dev->instance, dev->capture.port, buffer_cb);
+	ret = vchiq_mmal_port_enable(dev->instance, dev->capture.port,
+				     buffer_cb);
 	if (ret) {
 		v4l2_err(&dev->v4l2_dev,
 			 "Failed to enable capture port - error %d. Disabling camera port again\n",
@@ -668,7 +664,7 @@ static int set_overlay_params(struct bm2835_mmal_dev *dev,
 			MMAL_DISPLAY_SET_ALPHA |
 			MMAL_DISPLAY_SET_DEST_RECT |
 			MMAL_DISPLAY_SET_FULLSCREEN,
-		.layer = PREVIEW_LAYER,
+		.layer = 2,
 		.alpha = dev->overlay.global_alpha,
 		.fullscreen = 0,
 		.dest_rect = {
@@ -767,16 +763,14 @@ static int vidioc_overlay(struct file *file, void *f, unsigned int on)
 	    (!on && !dev->component[COMP_PREVIEW]->enabled))
 		return 0;	/* already in requested state */
 
-	src =
-	    &dev->component[COMP_CAMERA]->output[CAM_PORT_PREVIEW];
+	src = &dev->component[COMP_CAMERA]->output[CAM_PORT_PREVIEW];
 
 	if (!on) {
 		/* disconnect preview ports and disable component */
 		ret = vchiq_mmal_port_disable(dev->instance, src);
 		if (!ret)
-			ret =
-			    vchiq_mmal_port_connect_tunnel(dev->instance, src,
-							   NULL);
+			ret = vchiq_mmal_port_connect_tunnel(dev->instance, src,
+							     NULL);
 		if (ret >= 0)
 			ret = vchiq_mmal_component_disable(
 					dev->instance,
@@ -800,9 +794,8 @@ static int vidioc_overlay(struct file *file, void *f, unsigned int on)
 	if (enable_camera(dev) < 0)
 		return -EINVAL;
 
-	ret = vchiq_mmal_component_enable(
-			dev->instance,
-			dev->component[COMP_PREVIEW]);
+	ret = vchiq_mmal_component_enable(dev->instance,
+					  dev->component[COMP_PREVIEW]);
 	if (ret < 0)
 		return ret;
 
@@ -1001,6 +994,141 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 	return 0;
 }
 
+
+static int mmal_setup_video_component(struct bm2835_mmal_dev *dev,
+				      struct v4l2_format *f)
+{
+	bool overlay_enabled = !!dev->component[COMP_PREVIEW]->enabled;
+	struct vchiq_mmal_port *preview_port;
+	int ret;
+
+	preview_port = &dev->component[COMP_CAMERA]->output[CAM_PORT_PREVIEW];
+
+	/* Preview and encode ports need to match on resolution */
+	if (overlay_enabled) {
+		/* Need to disable the overlay before we can update
+		 * the resolution
+		 */
+		ret = vchiq_mmal_port_disable(dev->instance, preview_port);
+		if (!ret) {
+			ret = vchiq_mmal_port_connect_tunnel(dev->instance,
+							     preview_port,
+							     NULL);
+		}
+	}
+	preview_port->es.video.width = f->fmt.pix.width;
+	preview_port->es.video.height = f->fmt.pix.height;
+	preview_port->es.video.crop.x = 0;
+	preview_port->es.video.crop.y = 0;
+	preview_port->es.video.crop.width = f->fmt.pix.width;
+	preview_port->es.video.crop.height = f->fmt.pix.height;
+	preview_port->es.video.frame_rate.num =
+				  dev->capture.timeperframe.denominator;
+	preview_port->es.video.frame_rate.den =
+				  dev->capture.timeperframe.numerator;
+	ret = vchiq_mmal_port_set_format(dev->instance, preview_port);
+
+	if (overlay_enabled) {
+		ret = vchiq_mmal_port_connect_tunnel(dev->instance,
+				preview_port,
+				&dev->component[COMP_PREVIEW]->input[0]);
+		if (ret)
+			return ret;
+
+		ret = vchiq_mmal_port_enable(dev->instance, preview_port, NULL);
+	}
+
+	return ret;
+}
+
+static int mmal_setup_encode_component(struct bm2835_mmal_dev *dev,
+				       struct v4l2_format *f,
+				       struct vchiq_mmal_port *port,
+				       struct vchiq_mmal_port *camera_port,
+				       struct vchiq_mmal_component *component)
+{
+	struct mmal_fmt *mfmt = get_format(f);
+	int ret;
+
+	v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
+		 "vid_cap - set up encode comp\n");
+
+	/* configure buffering */
+	camera_port->current_buffer.size = camera_port->recommended_buffer.size;
+	camera_port->current_buffer.num = camera_port->recommended_buffer.num;
+
+	ret = vchiq_mmal_port_connect_tunnel(dev->instance, camera_port,
+					     &component->input[0]);
+	if (ret) {
+		v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
+			 "%s failed to create connection\n", __func__);
+		/* ensure capture is not going to be tried */
+		dev->capture.port = NULL;
+		return ret;
+	}
+
+	port->es.video.width = f->fmt.pix.width;
+	port->es.video.height = f->fmt.pix.height;
+	port->es.video.crop.x = 0;
+	port->es.video.crop.y = 0;
+	port->es.video.crop.width = f->fmt.pix.width;
+	port->es.video.crop.height = f->fmt.pix.height;
+	port->es.video.frame_rate.num =
+		  dev->capture.timeperframe.denominator;
+	port->es.video.frame_rate.den =
+		  dev->capture.timeperframe.numerator;
+
+	port->format.encoding = mfmt->mmal;
+	port->format.encoding_variant = 0;
+	/* Set any encoding specific parameters */
+	switch (mfmt->mmal_component) {
+	case COMP_VIDEO_ENCODE:
+		port->format.bitrate = dev->capture.encode_bitrate;
+		break;
+	case COMP_IMAGE_ENCODE:
+		/* Could set EXIF parameters here */
+		break;
+	default:
+		break;
+	}
+
+	ret = vchiq_mmal_port_set_format(dev->instance, port);
+	if (ret) {
+		v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
+			 "%s failed to set format %dx%d fmt %08X\n",
+			 __func__,
+			 f->fmt.pix.width,
+			 f->fmt.pix.height,
+			 f->fmt.pix.pixelformat);
+		return ret;
+	}
+
+	ret = vchiq_mmal_component_enable(dev->instance, component);
+	if (ret) {
+		v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
+			 "%s Failed to enable encode components\n", __func__);
+		return ret;
+	}
+
+	/* configure buffering */
+	port->current_buffer.num = 1;
+	port->current_buffer.size = f->fmt.pix.sizeimage;
+	if (port->format.encoding == MMAL_ENCODING_JPEG) {
+		v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
+			 "JPG - buf size now %d was %d\n",
+			 f->fmt.pix.sizeimage,
+			 port->current_buffer.size);
+		port->current_buffer.size =
+		    (f->fmt.pix.sizeimage < (100 << 10)) ?
+		    (100 << 10) : f->fmt.pix.sizeimage;
+	}
+	v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
+		 "vid_cap - cur_buf.size set to %d\n", f->fmt.pix.sizeimage);
+	port->current_buffer.alignment = 0;
+
+	return 0;
+}
+
 static int mmal_setup_components(struct bm2835_mmal_dev *dev,
 				 struct v4l2_format *f)
 {
@@ -1075,8 +1203,7 @@ static int mmal_setup_components(struct bm2835_mmal_dev *dev,
 	}
 
 	remove_padding = mfmt->remove_padding;
-	vchiq_mmal_port_parameter_set(dev->instance,
-				      camera_port,
+	vchiq_mmal_port_parameter_set(dev->instance, camera_port,
 				      MMAL_PARAMETER_NO_IMAGE_PADDING,
 				      &remove_padding, sizeof(remove_padding));
 
@@ -1096,46 +1223,7 @@ static int mmal_setup_components(struct bm2835_mmal_dev *dev,
 	if (!ret &&
 	    camera_port ==
 	    &dev->component[COMP_CAMERA]->output[CAM_PORT_VIDEO]) {
-		bool overlay_enabled =
-		    !!dev->component[COMP_PREVIEW]->enabled;
-		struct vchiq_mmal_port *preview_port =
-		    &dev->component[COMP_CAMERA]->output[CAM_PORT_PREVIEW];
-		/* Preview and encode ports need to match on resolution */
-		if (overlay_enabled) {
-			/* Need to disable the overlay before we can update
-			 * the resolution
-			 */
-			ret =
-			    vchiq_mmal_port_disable(dev->instance,
-						    preview_port);
-			if (!ret)
-				ret =
-				    vchiq_mmal_port_connect_tunnel(
-						dev->instance,
-						preview_port,
-						NULL);
-		}
-		preview_port->es.video.width = f->fmt.pix.width;
-		preview_port->es.video.height = f->fmt.pix.height;
-		preview_port->es.video.crop.x = 0;
-		preview_port->es.video.crop.y = 0;
-		preview_port->es.video.crop.width = f->fmt.pix.width;
-		preview_port->es.video.crop.height = f->fmt.pix.height;
-		preview_port->es.video.frame_rate.num =
-					  dev->capture.timeperframe.denominator;
-		preview_port->es.video.frame_rate.den =
-					  dev->capture.timeperframe.numerator;
-		ret = vchiq_mmal_port_set_format(dev->instance, preview_port);
-		if (overlay_enabled) {
-			ret = vchiq_mmal_port_connect_tunnel(
-				dev->instance,
-				preview_port,
-				&dev->component[COMP_PREVIEW]->input[0]);
-			if (!ret)
-				ret = vchiq_mmal_port_enable(dev->instance,
-							     preview_port,
-							     NULL);
-		}
+		ret = mmal_setup_video_component(dev, f);
 	}
 
 	if (ret) {
@@ -1145,128 +1233,39 @@ static int mmal_setup_components(struct bm2835_mmal_dev *dev,
 			 f->fmt.pix.pixelformat);
 		/* ensure capture is not going to be tried */
 		dev->capture.port = NULL;
-	} else {
-		if (encode_component) {
-			v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
-				 "vid_cap - set up encode comp\n");
+		return ret;
+	}
 
-			/* configure buffering */
-			camera_port->current_buffer.size =
-			    camera_port->recommended_buffer.size;
-			camera_port->current_buffer.num =
-			    camera_port->recommended_buffer.num;
+	if (encode_component) {
+		ret = mmal_setup_encode_component(dev, f, port,
+						  camera_port,
+						  encode_component);
 
-			ret =
-			    vchiq_mmal_port_connect_tunnel(
-					dev->instance,
-					camera_port,
-					&encode_component->input[0]);
-			if (ret) {
-				v4l2_dbg(1, bcm2835_v4l2_debug,
-					 &dev->v4l2_dev,
-					 "%s failed to create connection\n",
-					 __func__);
-				/* ensure capture is not going to be tried */
-				dev->capture.port = NULL;
-			} else {
-				port->es.video.width = f->fmt.pix.width;
-				port->es.video.height = f->fmt.pix.height;
-				port->es.video.crop.x = 0;
-				port->es.video.crop.y = 0;
-				port->es.video.crop.width = f->fmt.pix.width;
-				port->es.video.crop.height = f->fmt.pix.height;
-				port->es.video.frame_rate.num =
-					  dev->capture.timeperframe.denominator;
-				port->es.video.frame_rate.den =
-					  dev->capture.timeperframe.numerator;
-
-				port->format.encoding = mfmt->mmal;
-				port->format.encoding_variant = 0;
-				/* Set any encoding specific parameters */
-				switch (mfmt->mmal_component) {
-				case COMP_VIDEO_ENCODE:
-					port->format.bitrate =
-					    dev->capture.encode_bitrate;
-					break;
-				case COMP_IMAGE_ENCODE:
-					/* Could set EXIF parameters here */
-					break;
-				default:
-					break;
-				}
-				ret = vchiq_mmal_port_set_format(dev->instance,
-								 port);
-				if (ret)
-					v4l2_dbg(1, bcm2835_v4l2_debug,
-						 &dev->v4l2_dev,
-						 "%s failed to set format %dx%d fmt %08X\n",
-						 __func__,
-						 f->fmt.pix.width,
-						 f->fmt.pix.height,
-						 f->fmt.pix.pixelformat
-						 );
-			}
+		if (ret)
+			return ret;
+	} else {
+		/* configure buffering */
+		camera_port->current_buffer.num = 1;
+		camera_port->current_buffer.size = f->fmt.pix.sizeimage;
+		camera_port->current_buffer.alignment = 0;
+	}
 
-			if (!ret) {
-				ret = vchiq_mmal_component_enable(
-						dev->instance,
-						encode_component);
-				if (ret) {
-					v4l2_dbg(1, bcm2835_v4l2_debug,
-						 &dev->v4l2_dev,
-						 "%s Failed to enable encode components\n",
-						 __func__);
-				}
-			}
-			if (!ret) {
-				/* configure buffering */
-				port->current_buffer.num = 1;
-				port->current_buffer.size =
-				    f->fmt.pix.sizeimage;
-				if (port->format.encoding ==
-				    MMAL_ENCODING_JPEG) {
-					v4l2_dbg(1, bcm2835_v4l2_debug,
-						 &dev->v4l2_dev,
-						 "JPG - buf size now %d was %d\n",
-						 f->fmt.pix.sizeimage,
-						 port->current_buffer.size);
-					port->current_buffer.size =
-					    (f->fmt.pix.sizeimage <
-					     (100 << 10)) ?
-					    (100 << 10) : f->fmt.pix.sizeimage;
-				}
-				v4l2_dbg(1, bcm2835_v4l2_debug,
-					 &dev->v4l2_dev,
-					 "vid_cap - cur_buf.size set to %d\n",
-					 f->fmt.pix.sizeimage);
-				port->current_buffer.alignment = 0;
-			}
-		} else {
-			/* configure buffering */
-			camera_port->current_buffer.num = 1;
-			camera_port->current_buffer.size = f->fmt.pix.sizeimage;
-			camera_port->current_buffer.alignment = 0;
-		}
+	dev->capture.fmt = mfmt;
+	dev->capture.stride = f->fmt.pix.bytesperline;
+	dev->capture.width = camera_port->es.video.crop.width;
+	dev->capture.height = camera_port->es.video.crop.height;
+	dev->capture.buffersize = port->current_buffer.size;
 
-		if (!ret) {
-			dev->capture.fmt = mfmt;
-			dev->capture.stride = f->fmt.pix.bytesperline;
-			dev->capture.width = camera_port->es.video.crop.width;
-			dev->capture.height = camera_port->es.video.crop.height;
-			dev->capture.buffersize = port->current_buffer.size;
-
-			/* select port for capture */
-			dev->capture.port = port;
-			dev->capture.camera_port = camera_port;
-			dev->capture.encode_component = encode_component;
-			v4l2_dbg(1, bcm2835_v4l2_debug,
-				 &dev->v4l2_dev,
-				"Set dev->capture.fmt %08X, %dx%d, stride %d, size %d",
-				port->format.encoding,
-				dev->capture.width, dev->capture.height,
-				dev->capture.stride, dev->capture.buffersize);
-		}
-	}
+	/* select port for capture */
+	dev->capture.port = port;
+	dev->capture.camera_port = camera_port;
+	dev->capture.encode_component = encode_component;
+	v4l2_dbg(1, bcm2835_v4l2_debug,
+		 &dev->v4l2_dev,
+		"Set dev->capture.fmt %08X, %dx%d, stride %d, size %d",
+		port->format.encoding,
+		dev->capture.width, dev->capture.height,
+		dev->capture.stride, dev->capture.buffersize);
 
 	/* todo: Need to convert the vchiq/mmal error into a v4l2 error. */
 	return ret;
@@ -1658,9 +1657,8 @@ static int mmal_init(struct bm2835_mmal_dev *dev)
 	dev->capture.enc_level = V4L2_MPEG_VIDEO_H264_LEVEL_4_0;
 
 	/* get the preview component ready */
-	ret = vchiq_mmal_component_init(
-			dev->instance, "ril.video_render",
-			&dev->component[COMP_PREVIEW]);
+	ret = vchiq_mmal_component_init(dev->instance, "ril.video_render",
+					&dev->component[COMP_PREVIEW]);
 	if (ret < 0)
 		goto unreg_camera;
 
@@ -1672,9 +1670,8 @@ static int mmal_init(struct bm2835_mmal_dev *dev)
 	}
 
 	/* get the image encoder component ready */
-	ret = vchiq_mmal_component_init(
-		dev->instance, "ril.image_encode",
-		&dev->component[COMP_IMAGE_ENCODE]);
+	ret = vchiq_mmal_component_init(dev->instance, "ril.image_encode",
+					&dev->component[COMP_IMAGE_ENCODE]);
 	if (ret < 0)
 		goto unreg_preview;
 
@@ -1734,15 +1731,13 @@ static int mmal_init(struct bm2835_mmal_dev *dev)
 
 unreg_vid_encoder:
 	pr_err("Cleanup: Destroy video encoder\n");
-	vchiq_mmal_component_finalise(
-		dev->instance,
-		dev->component[COMP_VIDEO_ENCODE]);
+	vchiq_mmal_component_finalise(dev->instance,
+				      dev->component[COMP_VIDEO_ENCODE]);
 
 unreg_image_encoder:
 	pr_err("Cleanup: Destroy image encoder\n");
-	vchiq_mmal_component_finalise(
-		dev->instance,
-		dev->component[COMP_IMAGE_ENCODE]);
+	vchiq_mmal_component_finalise(dev->instance,
+				      dev->component[COMP_IMAGE_ENCODE]);
 
 unreg_preview:
 	pr_err("Cleanup: Destroy video render\n");
@@ -1775,8 +1770,7 @@ static int bm2835_mmal_init_device(struct bm2835_mmal_dev *dev,
 	/* video device needs to be able to access instance data */
 	video_set_drvdata(vfd, dev);
 
-	ret = video_register_device(vfd,
-				    VFL_TYPE_VIDEO,
+	ret = video_register_device(vfd, VFL_TYPE_VIDEO,
 				    video_nr[dev->camera_num]);
 	if (ret < 0)
 		return ret;
diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h
index b5fce38de038..75524adff0f5 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h
+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h
@@ -30,79 +30,77 @@ enum {
 	CAM_PORT_COUNT
 };
 
-#define PREVIEW_LAYER      2
-
 extern int bcm2835_v4l2_debug;
 
 struct bm2835_mmal_dev {
 	/* v4l2 devices */
-	struct v4l2_device     v4l2_dev;
-	struct video_device    vdev;
-	struct mutex           mutex;
+	struct v4l2_device v4l2_dev;
+	struct video_device vdev;
+	struct mutex mutex;
 
 	/* controls */
-	struct v4l2_ctrl_handler  ctrl_handler;
-	struct v4l2_ctrl          *ctrls[V4L2_CTRL_COUNT];
-	enum v4l2_scene_mode	  scene_mode;
-	struct mmal_colourfx      colourfx;
-	int                       hflip;
-	int                       vflip;
-	int			  red_gain;
-	int			  blue_gain;
+	struct v4l2_ctrl_handler ctrl_handler;
+	struct v4l2_ctrl *ctrls[V4L2_CTRL_COUNT];
+	enum v4l2_scene_mode scene_mode;
+	struct mmal_colourfx colourfx;
+	int hflip;
+	int vflip;
+	int red_gain;
+	int blue_gain;
 	enum mmal_parameter_exposuremode exposure_mode_user;
 	enum v4l2_exposure_auto_type exposure_mode_v4l2_user;
 	/* active exposure mode may differ if selected via a scene mode */
 	enum mmal_parameter_exposuremode exposure_mode_active;
 	enum mmal_parameter_exposuremeteringmode metering_mode;
-	unsigned int		  manual_shutter_speed;
-	bool			  exp_auto_priority;
+	unsigned int manual_shutter_speed;
+	bool exp_auto_priority;
 	bool manual_iso_enabled;
 	u32 iso;
 
 	/* allocated mmal instance and components */
-	struct vchiq_mmal_instance   *instance;
-	struct vchiq_mmal_component  *component[COMP_COUNT];
+	struct vchiq_mmal_instance *instance;
+	struct vchiq_mmal_component *component[COMP_COUNT];
 	int camera_use_count;
 
 	struct v4l2_window overlay;
 
 	struct {
-		unsigned int     width;  /* width */
-		unsigned int     height;  /* height */
-		unsigned int     stride;  /* stride */
-		unsigned int     buffersize; /* buffer size with padding */
-		struct mmal_fmt  *fmt;
+		unsigned int width;  /* width */
+		unsigned int height;  /* height */
+		unsigned int stride;  /* stride */
+		unsigned int buffersize; /* buffer size with padding */
+		struct mmal_fmt *fmt;
 		struct v4l2_fract timeperframe;
 
 		/* H264 encode bitrate */
-		int         encode_bitrate;
+		int encode_bitrate;
 		/* H264 bitrate mode. CBR/VBR */
-		int         encode_bitrate_mode;
+		int encode_bitrate_mode;
 		/* H264 profile */
 		enum v4l2_mpeg_video_h264_profile enc_profile;
 		/* H264 level */
 		enum v4l2_mpeg_video_h264_level enc_level;
 		/* JPEG Q-factor */
-		int         q_factor;
+		int q_factor;
 
-		struct vb2_queue	vb_vidq;
+		struct vb2_queue vb_vidq;
 
 		/* VC start timestamp for streaming */
-		s64         vc_start_timestamp;
+		s64 vc_start_timestamp;
 		/* Kernel start timestamp for streaming */
 		ktime_t kernel_start_ts;
 		/* Sequence number of last buffer */
-		u32		sequence;
+		u32 sequence;
 
-		struct vchiq_mmal_port  *port; /* port being used for capture */
+		struct vchiq_mmal_port *port; /* port being used for capture */
 		/* camera port being used for capture */
-		struct vchiq_mmal_port  *camera_port;
+		struct vchiq_mmal_port *camera_port;
 		/* component being used for encode */
 		struct vchiq_mmal_component *encode_component;
 		/* number of frames remaining which driver should capture */
-		unsigned int  frame_count;
+		unsigned int frame_count;
 		/* last frame completion */
-		struct completion  frame_cmplt;
+		struct completion frame_cmplt;
 
 	} capture;
 
diff --git a/drivers/staging/vc04_services/bcm2835-camera/controls.c b/drivers/staging/vc04_services/bcm2835-camera/controls.c
index 5137fcf203d6..b096a12387f7 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/controls.c
+++ b/drivers/staging/vc04_services/bcm2835-camera/controls.c
@@ -135,8 +135,8 @@ static const struct v4l2_to_mmal_effects_setting
 };
 
 struct v4l2_mmal_scene_config {
-	enum v4l2_scene_mode			v4l2_scene;
-	enum mmal_parameter_exposuremode	exposure_mode;
+	enum v4l2_scene_mode v4l2_scene;
+	enum mmal_parameter_exposuremode exposure_mode;
 	enum mmal_parameter_exposuremeteringmode metering_mode;
 };
 
@@ -377,11 +377,9 @@ static int ctrl_set_metering_mode(struct bm2835_mmal_dev *dev,
 		dev->metering_mode = MMAL_PARAM_EXPOSUREMETERINGMODE_SPOT;
 		break;
 
-	/* todo matrix weighting not added to Linux API till 3.9
-	 * case V4L2_EXPOSURE_METERING_MATRIX:
-	 *	dev->metering_mode = MMAL_PARAM_EXPOSUREMETERINGMODE_MATRIX;
-	 *	break;
-	 */
+	case V4L2_EXPOSURE_METERING_MATRIX:
+		dev->metering_mode = MMAL_PARAM_EXPOSUREMETERINGMODE_MATRIX;
+		break;
 	}
 
 	if (dev->scene_mode == V4L2_SCENE_MODE_NONE) {
@@ -516,42 +514,41 @@ static int ctrl_set_image_effect(struct bm2835_mmal_dev *dev,
 	struct mmal_parameter_imagefx_parameters imagefx;
 
 	for (i = 0; i < ARRAY_SIZE(v4l2_to_mmal_effects_values); i++) {
-		if (ctrl->val == v4l2_to_mmal_effects_values[i].v4l2_effect) {
-			imagefx.effect =
-				v4l2_to_mmal_effects_values[i].mmal_effect;
-			imagefx.num_effect_params =
-				v4l2_to_mmal_effects_values[i].num_effect_params;
-
-			if (imagefx.num_effect_params > MMAL_MAX_IMAGEFX_PARAMETERS)
-				imagefx.num_effect_params = MMAL_MAX_IMAGEFX_PARAMETERS;
-
-			for (j = 0; j < imagefx.num_effect_params; j++)
-				imagefx.effect_parameter[j] =
-					v4l2_to_mmal_effects_values[i].effect_params[j];
-
-			dev->colourfx.enable =
-				v4l2_to_mmal_effects_values[i].col_fx_enable;
-			if (!v4l2_to_mmal_effects_values[i].col_fx_fixed_cbcr) {
-				dev->colourfx.u =
-					v4l2_to_mmal_effects_values[i].u;
-				dev->colourfx.v =
-					v4l2_to_mmal_effects_values[i].v;
-			}
+		if (ctrl->val != v4l2_to_mmal_effects_values[i].v4l2_effect)
+			continue;
+
+		imagefx.effect =
+			v4l2_to_mmal_effects_values[i].mmal_effect;
+		imagefx.num_effect_params =
+			v4l2_to_mmal_effects_values[i].num_effect_params;
 
-			control = &dev->component[COMP_CAMERA]->control;
+		if (imagefx.num_effect_params > MMAL_MAX_IMAGEFX_PARAMETERS)
+			imagefx.num_effect_params = MMAL_MAX_IMAGEFX_PARAMETERS;
 
-			ret = vchiq_mmal_port_parameter_set(
-					dev->instance, control,
-					MMAL_PARAMETER_IMAGE_EFFECT_PARAMETERS,
-					&imagefx, sizeof(imagefx));
-			if (ret)
-				goto exit;
+		for (j = 0; j < imagefx.num_effect_params; j++)
+			imagefx.effect_parameter[j] =
+				v4l2_to_mmal_effects_values[i].effect_params[j];
 
-			ret = vchiq_mmal_port_parameter_set(
-					dev->instance, control,
-					MMAL_PARAMETER_COLOUR_EFFECT,
-					&dev->colourfx, sizeof(dev->colourfx));
+		dev->colourfx.enable =
+			v4l2_to_mmal_effects_values[i].col_fx_enable;
+		if (!v4l2_to_mmal_effects_values[i].col_fx_fixed_cbcr) {
+			dev->colourfx.u = v4l2_to_mmal_effects_values[i].u;
+			dev->colourfx.v = v4l2_to_mmal_effects_values[i].v;
 		}
+
+		control = &dev->component[COMP_CAMERA]->control;
+
+		ret = vchiq_mmal_port_parameter_set(
+				dev->instance, control,
+				MMAL_PARAMETER_IMAGE_EFFECT_PARAMETERS,
+				&imagefx, sizeof(imagefx));
+		if (ret)
+			goto exit;
+
+		ret = vchiq_mmal_port_parameter_set(
+				dev->instance, control,
+				MMAL_PARAMETER_COLOUR_EFFECT,
+				&dev->colourfx, sizeof(dev->colourfx));
 	}
 
 exit:
@@ -841,8 +838,7 @@ static int ctrl_set_scene_mode(struct bm2835_mmal_dev *dev,
 		enum mmal_parameter_exposuremeteringmode metering_mode;
 
 		for (i = 0; i < ARRAY_SIZE(scene_configs); i++) {
-			if (scene_configs[i].v4l2_scene ==
-				ctrl->val) {
+			if (scene_configs[i].v4l2_scene == ctrl->val) {
 				scene = &scene_configs[i];
 				break;
 			}
@@ -1045,8 +1041,8 @@ static const struct bm2835_mmal_v4l2_ctrl v4l2_ctrls[V4L2_CTRL_COUNT] = {
 	{
 		.id = V4L2_CID_EXPOSURE_METERING,
 		.type = MMAL_CONTROL_TYPE_STD_MENU,
-		.min = ~0x7,
-		.max = V4L2_EXPOSURE_METERING_SPOT,
+		.min = ~0xf,
+		.max = V4L2_EXPOSURE_METERING_MATRIX,
 		.def = V4L2_EXPOSURE_METERING_AVERAGE,
 		.step = 0,
 		.imenu = NULL,
@@ -1282,21 +1278,18 @@ int set_framerate_params(struct bm2835_mmal_dev *dev)
 	struct mmal_parameter_fps_range fps_range;
 	int ret;
 
+	fps_range.fps_high.num = dev->capture.timeperframe.denominator;
+	fps_range.fps_high.den = dev->capture.timeperframe.numerator;
+
 	if ((dev->exposure_mode_active != MMAL_PARAM_EXPOSUREMODE_OFF) &&
 	    (dev->exp_auto_priority)) {
-		/* Variable FPS. Define min FPS as 1fps.
-		 * Max as max defined FPS.
-		 */
+		/* Variable FPS. Define min FPS as 1fps. */
 		fps_range.fps_low.num = 1;
 		fps_range.fps_low.den = 1;
-		fps_range.fps_high.num = dev->capture.timeperframe.denominator;
-		fps_range.fps_high.den = dev->capture.timeperframe.numerator;
 	} else {
 		/* Fixed FPS - set min and max to be the same */
-		fps_range.fps_low.num = fps_range.fps_high.num =
-			dev->capture.timeperframe.denominator;
-		fps_range.fps_low.den = fps_range.fps_high.den =
-			dev->capture.timeperframe.numerator;
+		fps_range.fps_low.num = fps_range.fps_high.num;
+		fps_range.fps_low.den = fps_range.fps_high.den;
 	}
 
 	v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
diff --git a/drivers/staging/vc04_services/bcm2835-camera/mmal-common.h b/drivers/staging/vc04_services/bcm2835-camera/mmal-common.h
index ff5398737b4a..ce88fac7c24b 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-common.h
+++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-common.h
@@ -26,13 +26,13 @@ struct mmal_msg_context;
 
 /* mapping between v4l and mmal video modes */
 struct mmal_fmt {
-	u32   fourcc;          /* v4l2 format id */
-	int   flags;           /* v4l2 flags field */
-	u32   mmal;
-	int   depth;
-	u32   mmal_component;  /* MMAL component index to be used to encode */
-	u32   ybbp;            /* depth of first Y plane for planar formats */
-	bool  remove_padding;  /* Does the GPU have to remove padding,
+	u32 fourcc;          /* v4l2 format id */
+	int flags;           /* v4l2 flags field */
+	u32 mmal;
+	int depth;
+	u32 mmal_component;  /* MMAL component index to be used to encode */
+	u32 ybbp;            /* depth of first Y plane for planar formats */
+	bool remove_padding;   /* Does the GPU have to remove padding,
 				* or can we do hide padding via bytesperline.
 				*/
 };
@@ -40,10 +40,10 @@ struct mmal_fmt {
 /* buffer for one video frame */
 struct mmal_buffer {
 	/* v4l buffer data -- must be first */
-	struct vb2_v4l2_buffer	vb;
+	struct vb2_v4l2_buffer vb;
 
 	/* list of buffers available */
-	struct list_head	list;
+	struct list_head list;
 
 	void *buffer; /* buffer pointer */
 	unsigned long buffer_size; /* size of allocated buffer */
diff --git a/drivers/staging/vc04_services/bcm2835-camera/mmal-parameters.h b/drivers/staging/vc04_services/bcm2835-camera/mmal-parameters.h
index 80a99128f5f3..f4ac5a6149ea 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-parameters.h
+++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-parameters.h
@@ -724,11 +724,11 @@ struct mmal_parameter_imagefx_parameters {
 #define MMAL_PARAMETER_CAMERA_INFO_MAX_STR_LEN 16
 
 struct mmal_parameter_camera_info_camera_t {
-	u32    port_id;
-	u32    max_width;
-	u32    max_height;
-	u32    lens_present;
-	u8     camera_name[MMAL_PARAMETER_CAMERA_INFO_MAX_STR_LEN];
+	u32 port_id;
+	u32 max_width;
+	u32 max_height;
+	u32 lens_present;
+	u8 camera_name[MMAL_PARAMETER_CAMERA_INFO_MAX_STR_LEN];
 };
 
 enum mmal_parameter_camera_info_flash_type_t {
@@ -744,8 +744,8 @@ struct mmal_parameter_camera_info_flash_t {
 };
 
 struct mmal_parameter_camera_info_t {
-	u32                            num_cameras;
-	u32                            num_flashes;
+	u32 num_cameras;
+	u32 num_flashes;
 	struct mmal_parameter_camera_info_camera_t
 				cameras[MMAL_PARAMETER_CAMERA_INFO_MAX_CAMERAS];
 	struct mmal_parameter_camera_info_flash_t
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
index a1ea9777a444..2d3e114f4a66 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
@@ -2353,7 +2353,7 @@ vchiq_use_internal(struct vchiq_state *state, struct vchiq_service *service,
 	enum vchiq_status ret = VCHIQ_SUCCESS;
 	char entity[16];
 	int *entity_uc;
-	int local_uc, local_entity_uc;
+	int local_uc;
 
 	if (!arm_state)
 		goto out;
@@ -2377,7 +2377,7 @@ vchiq_use_internal(struct vchiq_state *state, struct vchiq_service *service,
 
 	write_lock_bh(&arm_state->susp_res_lock);
 	local_uc = ++arm_state->videocore_use_count;
-	local_entity_uc = ++(*entity_uc);
+	++(*entity_uc);
 
 	vchiq_log_trace(vchiq_susp_log_level,
 		"%s %s count %d, state count %d",
diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c
index b4cdc0b7fee7..6b25d75d2501 100644
--- a/drivers/staging/vt6655/baseband.c
+++ b/drivers/staging/vt6655/baseband.c
@@ -12,12 +12,10 @@
  * Date: Aug.22, 2002
  *
  * Functions:
- *      BBuGetFrameTime        - Calculate data frame transmitting time
- *      BBvCalculateParameter   - Calculate PhyLength, PhyService and Phy Signal
- *                               parameter for baseband Tx
- *      BBbReadEmbedded         - Embedded read baseband register via MAC
- *      BBbWriteEmbedded        - Embedded write baseband register via MAC
- *      BBbVT3253Init          - VIA VT3253 baseband chip init code
+ *      bb_get_frame_time	 - Calculate data frame transmitting time
+ *      bb_read_embedded	 - Embedded read baseband register via MAC
+ *      bb_write_embedded	 - Embedded write baseband register via MAC
+ *      bb_vt3253_init		 - VIA VT3253 baseband chip init code
  *
  * Revision History:
  *      06-10-2003 Bryan YC Fan:  Re-write codes to support VT3253 spec.
@@ -1695,53 +1693,53 @@ static const unsigned short awcFrameTime[MAX_RATE] = {
  *
  * Parameters:
  *  In:
- *      byPreambleType  - Preamble Type
- *      byPktType        - PK_TYPE_11A, PK_TYPE_11B, PK_TYPE_11GB, PK_TYPE_11GA
- *      cbFrameLength   - Baseband Type
- *      wRate           - Tx Rate
+ *      by_preamble_type  - Preamble Type
+ *      by_pkt_type        - PK_TYPE_11A, PK_TYPE_11B, PK_TYPE_11GB, PK_TYPE_11GA
+ *      cb_frame_length   - Baseband Type
+ *      tx_rate           - Tx Rate
  *  Out:
  *
  * Return Value: FrameTime
  *
  */
-unsigned int BBuGetFrameTime(unsigned char byPreambleType,
-			     unsigned char byPktType,
-			     unsigned int cbFrameLength, unsigned short wRate)
+unsigned int bb_get_frame_time(unsigned char by_preamble_type,
+			       unsigned char by_pkt_type,
+			       unsigned int cb_frame_length,
+			       unsigned short tx_rate)
 {
-	unsigned int uFrameTime;
-	unsigned int uPreamble;
-	unsigned int uTmp;
-	unsigned int uRateIdx = (unsigned int)wRate;
-	unsigned int uRate = 0;
+	unsigned int frame_time;
+	unsigned int preamble;
+	unsigned int tmp;
+	unsigned int rate_idx = (unsigned int)tx_rate;
+	unsigned int rate = 0;
 
-	if (uRateIdx > RATE_54M)
+	if (rate_idx > RATE_54M)
 		return 0;
 
-	uRate = (unsigned int)awcFrameTime[uRateIdx];
+	rate = (unsigned int)awcFrameTime[rate_idx];
 
-	if (uRateIdx <= 3) {          /* CCK mode */
-		if (byPreambleType == 1) /* Short */
-			uPreamble = 96;
+	if (rate_idx <= 3) {		    /* CCK mode */
+		if (by_preamble_type == 1) /* Short */
+			preamble = 96;
 		else
-			uPreamble = 192;
-
-		uFrameTime = (cbFrameLength * 80) / uRate;  /* ????? */
-		uTmp = (uFrameTime * uRate) / 80;
-		if (cbFrameLength != uTmp)
-			uFrameTime++;
+			preamble = 192;
+		frame_time = (cb_frame_length * 80) / rate;  /* ????? */
+		tmp = (frame_time * rate) / 80;
+		if (cb_frame_length != tmp)
+			frame_time++;
 
-		return uPreamble + uFrameTime;
+		return preamble + frame_time;
 	}
-	uFrameTime = (cbFrameLength * 8 + 22) / uRate; /* ???????? */
-	uTmp = ((uFrameTime * uRate) - 22) / 8;
-	if (cbFrameLength != uTmp)
-		uFrameTime++;
+	frame_time = (cb_frame_length * 8 + 22) / rate; /* ???????? */
+	tmp = ((frame_time * rate) - 22) / 8;
+	if (cb_frame_length != tmp)
+		frame_time++;
 
-	uFrameTime = uFrameTime * 4;    /* ??????? */
-	if (byPktType != PK_TYPE_11A)
-		uFrameTime += 6;     /* ?????? */
+	frame_time = frame_time * 4;    /* ??????? */
+	if (by_pkt_type != PK_TYPE_11A)
+		frame_time += 6;     /* ?????? */
 
-	return 20 + uFrameTime; /* ?????? */
+	return 20 + frame_time; /* ?????? */
 }
 
 /*
@@ -1899,34 +1897,34 @@ void vnt_get_phy_field(struct vnt_private *priv, u32 frame_length,
  * Parameters:
  *  In:
  *      iobase      - I/O base address
- *      byBBAddr    - address of register in Baseband
+ *      by_bb_addr  - address of register in Baseband
  *  Out:
- *      pbyData     - data read
+ *      pby_data    - data read
  *
  * Return Value: true if succeeded; false if failed.
  *
  */
-bool BBbReadEmbedded(struct vnt_private *priv,
-		     unsigned char byBBAddr, unsigned char *pbyData)
+bool bb_read_embedded(struct vnt_private *priv, unsigned char by_bb_addr,
+		      unsigned char *pby_data)
 {
 	void __iomem *iobase = priv->PortOffset;
 	unsigned short ww;
-	unsigned char byValue;
+	unsigned char by_value;
 
 	/* BB reg offset */
-	VNSvOutPortB(iobase + MAC_REG_BBREGADR, byBBAddr);
+	VNSvOutPortB(iobase + MAC_REG_BBREGADR, by_bb_addr);
 
 	/* turn on REGR */
 	MACvRegBitsOn(iobase, MAC_REG_BBREGCTL, BBREGCTL_REGR);
 	/* W_MAX_TIMEOUT is the timeout period */
 	for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
-		VNSvInPortB(iobase + MAC_REG_BBREGCTL, &byValue);
-		if (byValue & BBREGCTL_DONE)
+		VNSvInPortB(iobase + MAC_REG_BBREGCTL, &by_value);
+		if (by_value & BBREGCTL_DONE)
 			break;
 	}
 
 	/* get BB data */
-	VNSvInPortB(iobase + MAC_REG_BBREGDATA, pbyData);
+	VNSvInPortB(iobase + MAC_REG_BBREGDATA, pby_data);
 
 	if (ww == W_MAX_TIMEOUT) {
 		pr_debug(" DBG_PORT80(0x30)\n");
@@ -1941,32 +1939,32 @@ bool BBbReadEmbedded(struct vnt_private *priv,
  * Parameters:
  *  In:
  *      iobase      - I/O base address
- *      byBBAddr    - address of register in Baseband
- *      byData      - data to write
+ *      by_bb_addr  - address of register in Baseband
+ *      by_data     - data to write
  *  Out:
  *      none
  *
  * Return Value: true if succeeded; false if failed.
  *
  */
-bool BBbWriteEmbedded(struct vnt_private *priv,
-		      unsigned char byBBAddr, unsigned char byData)
+bool bb_write_embedded(struct vnt_private *priv, unsigned char by_bb_addr,
+		       unsigned char by_data)
 {
 	void __iomem *iobase = priv->PortOffset;
 	unsigned short ww;
-	unsigned char byValue;
+	unsigned char by_value;
 
 	/* BB reg offset */
-	VNSvOutPortB(iobase + MAC_REG_BBREGADR, byBBAddr);
+	VNSvOutPortB(iobase + MAC_REG_BBREGADR, by_bb_addr);
 	/* set BB data */
-	VNSvOutPortB(iobase + MAC_REG_BBREGDATA, byData);
+	VNSvOutPortB(iobase + MAC_REG_BBREGDATA, by_data);
 
 	/* turn on BBREGCTL_REGW */
 	MACvRegBitsOn(iobase, MAC_REG_BBREGCTL, BBREGCTL_REGW);
 	/* W_MAX_TIMEOUT is the timeout period */
 	for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
-		VNSvInPortB(iobase + MAC_REG_BBREGCTL, &byValue);
-		if (byValue & BBREGCTL_DONE)
+		VNSvInPortB(iobase + MAC_REG_BBREGCTL, &by_value);
+		if (by_value & BBREGCTL_DONE)
 			break;
 	}
 
@@ -1992,29 +1990,29 @@ bool BBbWriteEmbedded(struct vnt_private *priv,
  *
  */
 
-bool BBbVT3253Init(struct vnt_private *priv)
+bool bb_vt3253_init(struct vnt_private *priv)
 {
-	bool bResult = true;
+	bool result = true;
 	int        ii;
 	void __iomem *iobase = priv->PortOffset;
-	unsigned char byRFType = priv->byRFType;
-	unsigned char byLocalID = priv->byLocalID;
+	unsigned char by_rf_type = priv->byRFType;
+	unsigned char by_local_id = priv->byLocalID;
 
-	if (byRFType == RF_RFMD2959) {
-		if (byLocalID <= REV_ID_VT3253_A1) {
+	if (by_rf_type == RF_RFMD2959) {
+		if (by_local_id <= REV_ID_VT3253_A1) {
 			for (ii = 0; ii < CB_VT3253_INIT_FOR_RFMD; ii++)
-				bResult &= BBbWriteEmbedded(priv,
+				result &= bb_write_embedded(priv,
 					byVT3253InitTab_RFMD[ii][0],
 					byVT3253InitTab_RFMD[ii][1]);
 
 		} else {
 			for (ii = 0; ii < CB_VT3253B0_INIT_FOR_RFMD; ii++)
-				bResult &= BBbWriteEmbedded(priv,
+				result &= bb_write_embedded(priv,
 					byVT3253B0_RFMD[ii][0],
 					byVT3253B0_RFMD[ii][1]);
 
 			for (ii = 0; ii < CB_VT3253B0_AGC_FOR_RFMD2959; ii++)
-				bResult &= BBbWriteEmbedded(priv,
+				result &= bb_write_embedded(priv,
 					byVT3253B0_AGC4_RFMD2959[ii][0],
 					byVT3253B0_AGC4_RFMD2959[ii][1]);
 
@@ -2029,14 +2027,14 @@ bool BBbVT3253Init(struct vnt_private *priv)
 		priv->ldBmThreshold[1] = -50;
 		priv->ldBmThreshold[2] = 0;
 		priv->ldBmThreshold[3] = 0;
-	} else if ((byRFType == RF_AIROHA) || (byRFType == RF_AL2230S)) {
+	} else if ((by_rf_type == RF_AIROHA) || (by_rf_type == RF_AL2230S)) {
 		for (ii = 0; ii < CB_VT3253B0_INIT_FOR_AIROHA2230; ii++)
-			bResult &= BBbWriteEmbedded(priv,
+			result &= bb_write_embedded(priv,
 				byVT3253B0_AIROHA2230[ii][0],
 				byVT3253B0_AIROHA2230[ii][1]);
 
 		for (ii = 0; ii < CB_VT3253B0_AGC; ii++)
-			bResult &= BBbWriteEmbedded(priv,
+			result &= bb_write_embedded(priv,
 				byVT3253B0_AGC[ii][0], byVT3253B0_AGC[ii][1]);
 
 		priv->abyBBVGA[0] = 0x1C;
@@ -2047,14 +2045,14 @@ bool BBbVT3253Init(struct vnt_private *priv)
 		priv->ldBmThreshold[1] = -48;
 		priv->ldBmThreshold[2] = 0;
 		priv->ldBmThreshold[3] = 0;
-	} else if (byRFType == RF_UW2451) {
+	} else if (by_rf_type == RF_UW2451) {
 		for (ii = 0; ii < CB_VT3253B0_INIT_FOR_UW2451; ii++)
-			bResult &= BBbWriteEmbedded(priv,
+			result &= bb_write_embedded(priv,
 				byVT3253B0_UW2451[ii][0],
 				byVT3253B0_UW2451[ii][1]);
 
 		for (ii = 0; ii < CB_VT3253B0_AGC; ii++)
-			bResult &= BBbWriteEmbedded(priv,
+			result &= bb_write_embedded(priv,
 				byVT3253B0_AGC[ii][0],
 				byVT3253B0_AGC[ii][1]);
 
@@ -2069,9 +2067,9 @@ bool BBbVT3253Init(struct vnt_private *priv)
 		priv->ldBmThreshold[1] = -50;
 		priv->ldBmThreshold[2] = 0;
 		priv->ldBmThreshold[3] = 0;
-	} else if (byRFType == RF_UW2452) {
+	} else if (by_rf_type == RF_UW2452) {
 		for (ii = 0; ii < CB_VT3253B0_INIT_FOR_UW2451; ii++)
-			bResult &= BBbWriteEmbedded(priv,
+			result &= bb_write_embedded(priv,
 				byVT3253B0_UW2451[ii][0],
 				byVT3253B0_UW2451[ii][1]);
 
@@ -2080,7 +2078,7 @@ bool BBbVT3253Init(struct vnt_private *priv)
 		 * 0x45->0x41(VC1/VC2 define, make the ANT_A, ANT_B inverted)
 		 */
 
-		/*bResult &= BBbWriteEmbedded(iobase,0x09,0x41);*/
+		/*bResult &= bb_write_embedded(iobase,0x09,0x41);*/
 
 		/* Init ANT B select,
 		 * RX Config CR10 = 0x28->0x2A,
@@ -2088,23 +2086,23 @@ bool BBbVT3253Init(struct vnt_private *priv)
 		 * make the ANT_A, ANT_B inverted)
 		 */
 
-		/*bResult &= BBbWriteEmbedded(iobase,0x0a,0x28);*/
+		/*bResult &= bb_write_embedded(iobase,0x0a,0x28);*/
 		/* Select VC1/VC2, CR215 = 0x02->0x06 */
-		bResult &= BBbWriteEmbedded(priv, 0xd7, 0x06);
+		result &= bb_write_embedded(priv, 0xd7, 0x06);
 
 		/* {{RobertYu:20050125, request by Jack */
-		bResult &= BBbWriteEmbedded(priv, 0x90, 0x20);
-		bResult &= BBbWriteEmbedded(priv, 0x97, 0xeb);
+		result &= bb_write_embedded(priv, 0x90, 0x20);
+		result &= bb_write_embedded(priv, 0x97, 0xeb);
 		/* }} */
 
 		/* {{RobertYu:20050221, request by Jack */
-		bResult &= BBbWriteEmbedded(priv, 0xa6, 0x00);
-		bResult &= BBbWriteEmbedded(priv, 0xa8, 0x30);
+		result &= bb_write_embedded(priv, 0xa6, 0x00);
+		result &= bb_write_embedded(priv, 0xa8, 0x30);
 		/* }} */
-		bResult &= BBbWriteEmbedded(priv, 0xb0, 0x58);
+		result &= bb_write_embedded(priv, 0xb0, 0x58);
 
 		for (ii = 0; ii < CB_VT3253B0_AGC; ii++)
-			bResult &= BBbWriteEmbedded(priv,
+			result &= bb_write_embedded(priv,
 				byVT3253B0_AGC[ii][0], byVT3253B0_AGC[ii][1]);
 
 		priv->abyBBVGA[0] = 0x14;
@@ -2117,14 +2115,14 @@ bool BBbVT3253Init(struct vnt_private *priv)
 		priv->ldBmThreshold[3] = 0;
 		/* }} RobertYu */
 
-	} else if (byRFType == RF_VT3226) {
+	} else if (by_rf_type == RF_VT3226) {
 		for (ii = 0; ii < CB_VT3253B0_INIT_FOR_AIROHA2230; ii++)
-			bResult &= BBbWriteEmbedded(priv,
+			result &= bb_write_embedded(priv,
 				byVT3253B0_AIROHA2230[ii][0],
 				byVT3253B0_AIROHA2230[ii][1]);
 
 		for (ii = 0; ii < CB_VT3253B0_AGC; ii++)
-			bResult &= BBbWriteEmbedded(priv,
+			result &= bb_write_embedded(priv,
 				byVT3253B0_AGC[ii][0], byVT3253B0_AGC[ii][1]);
 
 		priv->abyBBVGA[0] = 0x1C;
@@ -2138,9 +2136,9 @@ bool BBbVT3253Init(struct vnt_private *priv)
 		/* Fix VT3226 DFC system timing issue */
 		MACvSetRFLE_LatchBase(iobase);
 		/* {{ RobertYu: 20050104 */
-	} else if (byRFType == RF_AIROHA7230) {
+	} else if (by_rf_type == RF_AIROHA7230) {
 		for (ii = 0; ii < CB_VT3253B0_INIT_FOR_AIROHA2230; ii++)
-			bResult &= BBbWriteEmbedded(priv,
+			result &= bb_write_embedded(priv,
 				byVT3253B0_AIROHA2230[ii][0],
 				byVT3253B0_AIROHA2230[ii][1]);
 
@@ -2148,17 +2146,17 @@ bool BBbVT3253Init(struct vnt_private *priv)
 		/* Init ANT B select,TX Config CR09 = 0x61->0x45,
 		 * 0x45->0x41(VC1/VC2 define, make the ANT_A, ANT_B inverted)
 		 */
-		/*bResult &= BBbWriteEmbedded(iobase,0x09,0x41);*/
+		/* bResult &= bb_write_embedded(iobase,0x09,0x41);*/
 		/* Init ANT B select,RX Config CR10 = 0x28->0x2A,
 		 * 0x2A->0x28(VC1/VC2 define, make the ANT_A, ANT_B inverted)
 		 */
-		/*bResult &= BBbWriteEmbedded(iobase,0x0a,0x28);*/
+		/* bResult &= BBbWriteEmbedded(iobase,0x0a,0x28);*/
 		/* Select VC1/VC2, CR215 = 0x02->0x06 */
-		bResult &= BBbWriteEmbedded(priv, 0xd7, 0x06);
+		result &= bb_write_embedded(priv, 0xd7, 0x06);
 		/* }} */
 
 		for (ii = 0; ii < CB_VT3253B0_AGC; ii++)
-			bResult &= BBbWriteEmbedded(priv,
+			result &= bb_write_embedded(priv,
 				byVT3253B0_AGC[ii][0], byVT3253B0_AGC[ii][1]);
 
 		priv->abyBBVGA[0] = 0x1C;
@@ -2176,12 +2174,12 @@ bool BBbVT3253Init(struct vnt_private *priv)
 		priv->abyBBVGA[0] = 0x1C;
 	}
 
-	if (byLocalID > REV_ID_VT3253_A1) {
-		BBbWriteEmbedded(priv, 0x04, 0x7F);
-		BBbWriteEmbedded(priv, 0x0D, 0x01);
+	if (by_local_id > REV_ID_VT3253_A1) {
+		bb_write_embedded(priv, 0x04, 0x7F);
+		bb_write_embedded(priv, 0x0D, 0x01);
 	}
 
-	return bResult;
+	return result;
 }
 
 /*
@@ -2197,42 +2195,42 @@ bool BBbVT3253Init(struct vnt_private *priv)
  *
  */
 void
-BBvSetShortSlotTime(struct vnt_private *priv)
+bb_set_short_slot_time(struct vnt_private *priv)
 {
-	unsigned char byBBRxConf = 0;
-	unsigned char byBBVGA = 0;
+	unsigned char by_bb_rx_conf = 0;
+	unsigned char by_bb_vga = 0;
 
-	BBbReadEmbedded(priv, 0x0A, &byBBRxConf); /* CR10 */
+	bb_read_embedded(priv, 0x0A, &by_bb_rx_conf); /* CR10 */
 
 	if (priv->bShortSlotTime)
-		byBBRxConf &= 0xDF; /* 1101 1111 */
+		by_bb_rx_conf &= 0xDF; /* 1101 1111 */
 	else
-		byBBRxConf |= 0x20; /* 0010 0000 */
+		by_bb_rx_conf |= 0x20; /* 0010 0000 */
 
 	/* patch for 3253B0 Baseband with Cardbus module */
-	BBbReadEmbedded(priv, 0xE7, &byBBVGA);
-	if (byBBVGA == priv->abyBBVGA[0])
-		byBBRxConf |= 0x20; /* 0010 0000 */
+	bb_read_embedded(priv, 0xE7, &by_bb_vga);
+	if (by_bb_vga == priv->abyBBVGA[0])
+		by_bb_rx_conf |= 0x20; /* 0010 0000 */
 
-	BBbWriteEmbedded(priv, 0x0A, byBBRxConf); /* CR10 */
+	bb_write_embedded(priv, 0x0A, by_bb_rx_conf); /* CR10 */
 }
 
-void BBvSetVGAGainOffset(struct vnt_private *priv, unsigned char byData)
+void bb_set_vga_gain_offset(struct vnt_private *priv, unsigned char by_data)
 {
-	unsigned char byBBRxConf = 0;
+	unsigned char by_bb_rx_conf = 0;
 
-	BBbWriteEmbedded(priv, 0xE7, byData);
+	bb_write_embedded(priv, 0xE7, by_data);
 
-	BBbReadEmbedded(priv, 0x0A, &byBBRxConf); /* CR10 */
+	bb_read_embedded(priv, 0x0A, &by_bb_rx_conf); /* CR10 */
 	/* patch for 3253B0 Baseband with Cardbus module */
-	if (byData == priv->abyBBVGA[0])
-		byBBRxConf |= 0x20; /* 0010 0000 */
+	if (by_data == priv->abyBBVGA[0])
+		by_bb_rx_conf |= 0x20; /* 0010 0000 */
 	else if (priv->bShortSlotTime)
-		byBBRxConf &= 0xDF; /* 1101 1111 */
+		by_bb_rx_conf &= 0xDF; /* 1101 1111 */
 	else
-		byBBRxConf |= 0x20; /* 0010 0000 */
-	priv->byBBVGACurrent = byData;
-	BBbWriteEmbedded(priv, 0x0A, byBBRxConf); /* CR10 */
+		by_bb_rx_conf |= 0x20; /* 0010 0000 */
+	priv->byBBVGACurrent = by_data;
+	bb_write_embedded(priv, 0x0A, by_bb_rx_conf); /* CR10 */
 }
 
 /*
@@ -2248,12 +2246,12 @@ void BBvSetVGAGainOffset(struct vnt_private *priv, unsigned char byData)
  *
  */
 void
-BBvSoftwareReset(struct vnt_private *priv)
+bb_software_reset(struct vnt_private *priv)
 {
-	BBbWriteEmbedded(priv, 0x50, 0x40);
-	BBbWriteEmbedded(priv, 0x50, 0);
-	BBbWriteEmbedded(priv, 0x9C, 0x01);
-	BBbWriteEmbedded(priv, 0x9C, 0);
+	bb_write_embedded(priv, 0x50, 0x40);
+	bb_write_embedded(priv, 0x50, 0);
+	bb_write_embedded(priv, 0x9C, 0x01);
+	bb_write_embedded(priv, 0x9C, 0);
 }
 
 /*
@@ -2269,13 +2267,13 @@ BBvSoftwareReset(struct vnt_private *priv)
  *
  */
 void
-BBvPowerSaveModeON(struct vnt_private *priv)
+bb_power_save_mode_on(struct vnt_private *priv)
 {
-	unsigned char byOrgData;
+	unsigned char by_org_data;
 
-	BBbReadEmbedded(priv, 0x0D, &byOrgData);
-	byOrgData |= BIT(0);
-	BBbWriteEmbedded(priv, 0x0D, byOrgData);
+	bb_read_embedded(priv, 0x0D, &by_org_data);
+	by_org_data |= BIT(0);
+	bb_write_embedded(priv, 0x0D, by_org_data);
 }
 
 /*
@@ -2291,13 +2289,13 @@ BBvPowerSaveModeON(struct vnt_private *priv)
  *
  */
 void
-BBvPowerSaveModeOFF(struct vnt_private *priv)
+bb_power_save_mode_off(struct vnt_private *priv)
 {
-	unsigned char byOrgData;
+	unsigned char by_org_data;
 
-	BBbReadEmbedded(priv, 0x0D, &byOrgData);
-	byOrgData &= ~(BIT(0));
-	BBbWriteEmbedded(priv, 0x0D, byOrgData);
+	bb_read_embedded(priv, 0x0D, &by_org_data);
+	by_org_data &= ~(BIT(0));
+	bb_write_embedded(priv, 0x0D, by_org_data);
 }
 
 /*
@@ -2306,7 +2304,7 @@ BBvPowerSaveModeOFF(struct vnt_private *priv)
  * Parameters:
  *  In:
  *      priv          - Device Structure
- *      byAntennaMode    - Antenna Mode
+ *      by_antenna_mode    - Antenna Mode
  *  Out:
  *      none
  *
@@ -2315,22 +2313,22 @@ BBvPowerSaveModeOFF(struct vnt_private *priv)
  */
 
 void
-BBvSetTxAntennaMode(struct vnt_private *priv, unsigned char byAntennaMode)
+bb_set_tx_antenna_mode(struct vnt_private *priv, unsigned char by_antenna_mode)
 {
-	unsigned char byBBTxConf;
+	unsigned char by_bb_tx_conf;
 
-	BBbReadEmbedded(priv, 0x09, &byBBTxConf); /* CR09 */
-	if (byAntennaMode == ANT_DIVERSITY) {
+	bb_read_embedded(priv, 0x09, &by_bb_tx_conf); /* CR09 */
+	if (by_antenna_mode == ANT_DIVERSITY) {
 		/* bit 1 is diversity */
-		byBBTxConf |= 0x02;
-	} else if (byAntennaMode == ANT_A) {
+		by_bb_tx_conf |= 0x02;
+	} else if (by_antenna_mode == ANT_A) {
 		/* bit 2 is ANTSEL */
-		byBBTxConf &= 0xF9; /* 1111 1001 */
-	} else if (byAntennaMode == ANT_B) {
-		byBBTxConf &= 0xFD; /* 1111 1101 */
-		byBBTxConf |= 0x04;
+		by_bb_tx_conf &= 0xF9; /* 1111 1001 */
+	} else if (by_antenna_mode == ANT_B) {
+		by_bb_tx_conf &= 0xFD; /* 1111 1101 */
+		by_bb_tx_conf |= 0x04;
 	}
-	BBbWriteEmbedded(priv, 0x09, byBBTxConf); /* CR09 */
+	bb_write_embedded(priv, 0x09, by_bb_tx_conf); /* CR09 */
 }
 
 /*
@@ -2339,7 +2337,7 @@ BBvSetTxAntennaMode(struct vnt_private *priv, unsigned char byAntennaMode)
  * Parameters:
  *  In:
  *      priv          - Device Structure
- *      byAntennaMode    - Antenna Mode
+ *      by_antenna_mode   - Antenna Mode
  *  Out:
  *      none
  *
@@ -2348,25 +2346,25 @@ BBvSetTxAntennaMode(struct vnt_private *priv, unsigned char byAntennaMode)
  */
 
 void
-BBvSetRxAntennaMode(struct vnt_private *priv, unsigned char byAntennaMode)
+bb_set_rx_antenna_mode(struct vnt_private *priv, unsigned char by_antenna_mode)
 {
-	unsigned char byBBRxConf;
+	unsigned char by_bb_rx_conf;
 
-	BBbReadEmbedded(priv, 0x0A, &byBBRxConf); /* CR10 */
-	if (byAntennaMode == ANT_DIVERSITY) {
-		byBBRxConf |= 0x01;
+	bb_read_embedded(priv, 0x0A, &by_bb_rx_conf); /* CR10 */
+	if (by_antenna_mode == ANT_DIVERSITY) {
+		by_bb_rx_conf |= 0x01;
 
-	} else if (byAntennaMode == ANT_A) {
-		byBBRxConf &= 0xFC; /* 1111 1100 */
-	} else if (byAntennaMode == ANT_B) {
-		byBBRxConf &= 0xFE; /* 1111 1110 */
-		byBBRxConf |= 0x02;
+	} else if (by_antenna_mode == ANT_A) {
+		by_bb_rx_conf &= 0xFC; /* 1111 1100 */
+	} else if (by_antenna_mode == ANT_B) {
+		by_bb_rx_conf &= 0xFE; /* 1111 1110 */
+		by_bb_rx_conf |= 0x02;
 	}
-	BBbWriteEmbedded(priv, 0x0A, byBBRxConf); /* CR10 */
+	bb_write_embedded(priv, 0x0A, by_bb_rx_conf); /* CR10 */
 }
 
 /*
- * Description: BBvSetDeepSleep
+ * Description: bb_set_deep_sleep
  *
  * Parameters:
  *  In:
@@ -2378,15 +2376,9 @@ BBvSetRxAntennaMode(struct vnt_private *priv, unsigned char byAntennaMode)
  *
  */
 void
-BBvSetDeepSleep(struct vnt_private *priv, unsigned char byLocalID)
+bb_set_deep_sleep(struct vnt_private *priv, unsigned char by_local_id)
 {
-	BBbWriteEmbedded(priv, 0x0C, 0x17); /* CR12 */
-	BBbWriteEmbedded(priv, 0x0D, 0xB9); /* CR13 */
+	bb_write_embedded(priv, 0x0C, 0x17); /* CR12 */
+	bb_write_embedded(priv, 0x0D, 0xB9); /* CR13 */
 }
 
-void
-BBvExitDeepSleep(struct vnt_private *priv, unsigned char byLocalID)
-{
-	BBbWriteEmbedded(priv, 0x0C, 0x00); /* CR12 */
-	BBbWriteEmbedded(priv, 0x0D, 0x01); /* CR13 */
-}
diff --git a/drivers/staging/vt6655/baseband.h b/drivers/staging/vt6655/baseband.h
index 0cc2e07829c5..9354ce724446 100644
--- a/drivers/staging/vt6655/baseband.h
+++ b/drivers/staging/vt6655/baseband.h
@@ -46,30 +46,31 @@
 #define TOP_RATE_2M         0x00200000
 #define TOP_RATE_1M         0x00100000
 
-unsigned int BBuGetFrameTime(unsigned char byPreambleType,
-			     unsigned char byPktType,
-			     unsigned int cbFrameLength,
-			     unsigned short wRate);
+unsigned int bb_get_frame_time(unsigned char by_preamble_type,
+			       unsigned char by_pkt_type,
+			       unsigned int cb_frame_length,
+			       unsigned short w_rate);
 
 void vnt_get_phy_field(struct vnt_private *priv, u32 frame_length,
 		       u16 tx_rate, u8 pkt_type, struct vnt_phy_field *phy);
 
-bool BBbReadEmbedded(struct vnt_private *priv, unsigned char byBBAddr,
-		     unsigned char *pbyData);
-bool BBbWriteEmbedded(struct vnt_private *priv, unsigned char byBBAddr,
-		      unsigned char byData);
+bool bb_read_embedded(struct vnt_private *priv, unsigned char by_bb_addr,
+		      unsigned char *pby_data);
+bool bb_write_embedded(struct vnt_private *priv, unsigned char by_bb_addr,
+		       unsigned char by_data);
 
-void BBvSetShortSlotTime(struct vnt_private *priv);
-void BBvSetVGAGainOffset(struct vnt_private *priv, unsigned char byData);
+void bb_set_short_slot_time(struct vnt_private *priv);
+void bb_set_vga_gain_offset(struct vnt_private *priv, unsigned char by_data);
 
 /* VT3253 Baseband */
-bool BBbVT3253Init(struct vnt_private *priv);
-void BBvSoftwareReset(struct vnt_private *priv);
-void BBvPowerSaveModeON(struct vnt_private *priv);
-void BBvPowerSaveModeOFF(struct vnt_private *priv);
-void BBvSetTxAntennaMode(struct vnt_private *priv, unsigned char byAntennaMode);
-void BBvSetRxAntennaMode(struct vnt_private *priv, unsigned char byAntennaMode);
-void BBvSetDeepSleep(struct vnt_private *priv, unsigned char byLocalID);
-void BBvExitDeepSleep(struct vnt_private *priv, unsigned char byLocalID);
+bool bb_vt3253_init(struct vnt_private *priv);
+void bb_software_reset(struct vnt_private *priv);
+void bb_power_save_mode_on(struct vnt_private *priv);
+void bb_power_save_mode_off(struct vnt_private *priv);
+void bb_set_tx_antenna_mode(struct vnt_private *priv,
+			    unsigned char by_antenna_mode);
+void bb_set_rx_antenna_mode(struct vnt_private *priv,
+			    unsigned char by_antenna_mode);
+void bb_set_deep_sleep(struct vnt_private *priv, unsigned char by_local_id);
 
 #endif /* __BASEBAND_H__ */
diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c
index e65c9825ea5a..6148310c06d6 100644
--- a/drivers/staging/vt6655/card.c
+++ b/drivers/staging/vt6655/card.c
@@ -11,15 +11,12 @@
  *      CARDvUpdateBasicTopRate - Update BasicTopRate
  *      CARDbAddBasicRate - Add to BasicRateSet
  *      CARDbIsOFDMinBasicRate - Check if any OFDM rate is in BasicRateSet
- *      CARDvSetLoopbackMode - Set Loopback mode
- *      CARDbSoftwareReset - Sortware reset NIC
  *      CARDqGetTSFOffset - Calculate TSFOffset
  *      CARDbGetCurrentTSF - Read Current NIC TSF counter
  *      CARDqGetNextTBTT - Calculate Next Beacon TSF counter
  *      CARDvSetFirstNextTBTT - Set NIC Beacon time
  *      CARDvUpdateNextTBTT - Sync. NIC Beacon time
  *      CARDbRadioPowerOff - Turn Off NIC Radio Power
- *      CARDbRadioPowerOn - Turn On NIC Radio Power
  *
  * Revision History:
  *      06-10-2003 Bryan YC Fan:  Re-write codes to support VT3253 spec.
@@ -198,22 +195,22 @@ bool CARDbSetPhyParameter(struct vnt_private *priv, u8 bb_type)
 			priv->abyBBVGA[0] = 0x20;
 			priv->abyBBVGA[2] = 0x10;
 			priv->abyBBVGA[3] = 0x10;
-			BBbReadEmbedded(priv, 0xE7, &byData);
+			bb_read_embedded(priv, 0xE7, &byData);
 			if (byData == 0x1C)
-				BBbWriteEmbedded(priv, 0xE7, priv->abyBBVGA[0]);
+				bb_write_embedded(priv, 0xE7, priv->abyBBVGA[0]);
 
 		} else if (priv->byRFType == RF_UW2452) {
 			MACvSetBBType(priv->PortOffset, BB_TYPE_11A);
 			priv->abyBBVGA[0] = 0x18;
-			BBbReadEmbedded(priv, 0xE7, &byData);
+			bb_read_embedded(priv, 0xE7, &byData);
 			if (byData == 0x14) {
-				BBbWriteEmbedded(priv, 0xE7, priv->abyBBVGA[0]);
-				BBbWriteEmbedded(priv, 0xE1, 0x57);
+				bb_write_embedded(priv, 0xE7, priv->abyBBVGA[0]);
+				bb_write_embedded(priv, 0xE1, 0x57);
 			}
 		} else {
 			MACvSetBBType(priv->PortOffset, BB_TYPE_11A);
 		}
-		BBbWriteEmbedded(priv, 0x88, 0x03);
+		bb_write_embedded(priv, 0x88, 0x03);
 		bySlot = C_SLOT_SHORT;
 		bySIFS = C_SIFS_A;
 		byDIFS = C_SIFS_A + 2 * C_SLOT_SHORT;
@@ -224,19 +221,19 @@ bool CARDbSetPhyParameter(struct vnt_private *priv, u8 bb_type)
 			priv->abyBBVGA[0] = 0x1C;
 			priv->abyBBVGA[2] = 0x00;
 			priv->abyBBVGA[3] = 0x00;
-			BBbReadEmbedded(priv, 0xE7, &byData);
+			bb_read_embedded(priv, 0xE7, &byData);
 			if (byData == 0x20)
-				BBbWriteEmbedded(priv, 0xE7, priv->abyBBVGA[0]);
+				bb_write_embedded(priv, 0xE7, priv->abyBBVGA[0]);
 
 		} else if (priv->byRFType == RF_UW2452) {
 			priv->abyBBVGA[0] = 0x14;
-			BBbReadEmbedded(priv, 0xE7, &byData);
+			bb_read_embedded(priv, 0xE7, &byData);
 			if (byData == 0x18) {
-				BBbWriteEmbedded(priv, 0xE7, priv->abyBBVGA[0]);
-				BBbWriteEmbedded(priv, 0xE1, 0xD3);
+				bb_write_embedded(priv, 0xE7, priv->abyBBVGA[0]);
+				bb_write_embedded(priv, 0xE1, 0xD3);
 			}
 		}
-		BBbWriteEmbedded(priv, 0x88, 0x02);
+		bb_write_embedded(priv, 0x88, 0x02);
 		bySlot = C_SLOT_LONG;
 		bySIFS = C_SIFS_BG;
 		byDIFS = C_SIFS_BG + 2 * C_SLOT_LONG;
@@ -247,19 +244,19 @@ bool CARDbSetPhyParameter(struct vnt_private *priv, u8 bb_type)
 			priv->abyBBVGA[0] = 0x1C;
 			priv->abyBBVGA[2] = 0x00;
 			priv->abyBBVGA[3] = 0x00;
-			BBbReadEmbedded(priv, 0xE7, &byData);
+			bb_read_embedded(priv, 0xE7, &byData);
 			if (byData == 0x20)
-				BBbWriteEmbedded(priv, 0xE7, priv->abyBBVGA[0]);
+				bb_write_embedded(priv, 0xE7, priv->abyBBVGA[0]);
 
 		} else if (priv->byRFType == RF_UW2452) {
 			priv->abyBBVGA[0] = 0x14;
-			BBbReadEmbedded(priv, 0xE7, &byData);
+			bb_read_embedded(priv, 0xE7, &byData);
 			if (byData == 0x18) {
-				BBbWriteEmbedded(priv, 0xE7, priv->abyBBVGA[0]);
-				BBbWriteEmbedded(priv, 0xE1, 0xD3);
+				bb_write_embedded(priv, 0xE7, priv->abyBBVGA[0]);
+				bb_write_embedded(priv, 0xE1, 0xD3);
 			}
 		}
-		BBbWriteEmbedded(priv, 0x88, 0x08);
+		bb_write_embedded(priv, 0x88, 0x08);
 		bySIFS = C_SIFS_BG;
 
 		if (priv->bShortSlotTime) {
@@ -310,7 +307,7 @@ bool CARDbSetPhyParameter(struct vnt_private *priv, u8 bb_type)
 		priv->bySlot = bySlot;
 		VNSvOutPortB(priv->PortOffset + MAC_REG_SLOT, priv->bySlot);
 
-		BBvSetShortSlotTime(priv);
+		bb_set_short_slot_time(priv);
 	}
 	if (priv->byCWMaxMin != byCWMaxMin) {
 		priv->byCWMaxMin = byCWMaxMin;
@@ -431,7 +428,7 @@ void CARDbRadioPowerOff(struct vnt_private *priv)
 
 	MACvRegBitsOff(priv->PortOffset, MAC_REG_HOSTCR, HOSTCR_RXON);
 
-	BBvSetDeepSleep(priv, priv->byLocalID);
+	bb_set_deep_sleep(priv, priv->byLocalID);
 
 	priv->bRadioOff = true;
 	pr_debug("chester power off\n");
@@ -439,60 +436,6 @@ void CARDbRadioPowerOff(struct vnt_private *priv)
 		      LED_ACTSET);  /* LED issue */
 }
 
-/*
- * Description: Turn on Radio power
- *
- * Parameters:
- *  In:
- *      priv         - The adapter to be turned on
- *  Out:
- *      none
- *
- * Return Value: true if success; otherwise false
- */
-bool CARDbRadioPowerOn(struct vnt_private *priv)
-{
-	bool bResult = true;
-
-	pr_debug("chester power on\n");
-	if (priv->bRadioControlOff) {
-		if (priv->bHWRadioOff)
-			pr_debug("chester bHWRadioOff\n");
-		if (priv->bRadioControlOff)
-			pr_debug("chester bRadioControlOff\n");
-		return false; }
-
-	if (!priv->bRadioOff) {
-		pr_debug("chester pbRadioOff\n");
-		return true; }
-
-	BBvExitDeepSleep(priv, priv->byLocalID);
-
-	MACvRegBitsOn(priv->PortOffset, MAC_REG_HOSTCR, HOSTCR_RXON);
-
-	switch (priv->byRFType) {
-	case RF_RFMD2959:
-		MACvWordRegBitsOn(priv->PortOffset, MAC_REG_SOFTPWRCTL,
-				  SOFTPWRCTL_TXPEINV);
-		MACvWordRegBitsOff(priv->PortOffset, MAC_REG_SOFTPWRCTL,
-				   SOFTPWRCTL_SWPE1);
-		break;
-
-	case RF_AIROHA:
-	case RF_AL2230S:
-	case RF_AIROHA7230:
-		MACvWordRegBitsOn(priv->PortOffset, MAC_REG_SOFTPWRCTL,
-				  (SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPE3));
-		break;
-	}
-
-	priv->bRadioOff = false;
-	pr_debug("chester power on\n");
-	MACvRegBitsOff(priv->PortOffset, MAC_REG_GPIOCTL0,
-		       LED_ACTSET); /* LED issue */
-	return bResult;
-}
-
 void CARDvSafeResetTx(struct vnt_private *priv)
 {
 	unsigned int uu;
@@ -815,54 +758,6 @@ unsigned char CARDbyGetPktType(struct vnt_private *priv)
 		return PK_TYPE_11GB;
 }
 
-/*
- * Description: Set NIC Loopback mode
- *
- * Parameters:
- *  In:
- *      priv         - The adapter to be set
- *      wLoopbackMode   - Loopback mode to be set
- *  Out:
- *      none
- *
- * Return Value: none
- */
-void CARDvSetLoopbackMode(struct vnt_private *priv,
-			  unsigned short wLoopbackMode)
-{
-	switch (wLoopbackMode) {
-	case CARD_LB_NONE:
-	case CARD_LB_MAC:
-	case CARD_LB_PHY:
-		break;
-	default:
-		break;
-	}
-	/* set MAC loopback */
-	MACvSetLoopbackMode(priv, LOBYTE(wLoopbackMode));
-	/* set Baseband loopback */
-}
-
-/*
- * Description: Software Reset NIC
- *
- * Parameters:
- *  In:
- *      priv         - The adapter to be reset
- *  Out:
- *      none
- *
- * Return Value: none
- */
-bool CARDbSoftwareReset(struct vnt_private *priv)
-{
-	/* reset MAC */
-	if (!MACbSafeSoftwareReset(priv))
-		return false;
-
-	return true;
-}
-
 /*
  * Description: Calculate TSF offset of two TSF input
  *              Get TSF Offset from RxBCN's TSF and local TSF
diff --git a/drivers/staging/vt6655/card.h b/drivers/staging/vt6655/card.h
index 337266add6b2..568a2ddd6588 100644
--- a/drivers/staging/vt6655/card.h
+++ b/drivers/staging/vt6655/card.h
@@ -44,9 +44,6 @@ struct vnt_private;
 void CARDvSetRSPINF(struct vnt_private *priv, u8 bb_type);
 void CARDvUpdateBasicTopRate(struct vnt_private *priv);
 bool CARDbIsOFDMinBasicRate(struct vnt_private *priv);
-void CARDvSetLoopbackMode(struct vnt_private *priv,
-			  unsigned short wLoopbackMode);
-bool CARDbSoftwareReset(struct vnt_private *priv);
 void CARDvSetFirstNextTBTT(struct vnt_private *priv,
 			   unsigned short wBeaconInterval);
 void CARDvUpdateNextTBTT(struct vnt_private *priv, u64 qwTSF,
@@ -58,7 +55,6 @@ unsigned char CARDbyGetPktType(struct vnt_private *priv);
 void CARDvSafeResetTx(struct vnt_private *priv);
 void CARDvSafeResetRx(struct vnt_private *priv);
 void CARDbRadioPowerOff(struct vnt_private *priv);
-bool CARDbRadioPowerOn(struct vnt_private *priv);
 bool CARDbSetPhyParameter(struct vnt_private *priv, u8 bb_type);
 bool CARDbUpdateTSF(struct vnt_private *priv, unsigned char byRxRate,
 		    u64 qwBSSTimestamp);
diff --git a/drivers/staging/vt6655/channel.c b/drivers/staging/vt6655/channel.c
index dec6f0f23b88..62a85c1ca6c4 100644
--- a/drivers/staging/vt6655/channel.c
+++ b/drivers/staging/vt6655/channel.c
@@ -173,7 +173,7 @@ bool set_channel(struct vnt_private *priv, struct ieee80211_channel *ch)
 	    priv->byBBVGACurrent != priv->abyBBVGA[0]) {
 		priv->byBBVGACurrent = priv->abyBBVGA[0];
 
-		BBvSetVGAGainOffset(priv, priv->byBBVGACurrent);
+		bb_set_vga_gain_offset(priv, priv->byBBVGACurrent);
 	}
 
 	/* clear NAV */
@@ -195,7 +195,7 @@ bool set_channel(struct vnt_private *priv, struct ieee80211_channel *ch)
 	if (priv->bEnablePSMode)
 		RFvWriteWakeProgSyn(priv, priv->byRFType, ch->hw_value);
 
-	BBvSoftwareReset(priv);
+	bb_software_reset(priv);
 
 	if (priv->byLocalID > REV_ID_VT3253_B1) {
 		unsigned long flags;
diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c
index 5c86cc60eb5c..5889023d19c4 100644
--- a/drivers/staging/vt6655/device_main.c
+++ b/drivers/staging/vt6655/device_main.c
@@ -21,14 +21,14 @@
  *   device_alloc_rx_buf - rx buffer pre-allocated function
  *   device_free_rx_buf - free rx buffer function
  *   device_free_tx_buf - free tx buffer function
- *   device_init_rd0_ring- initial rd dma0 ring
- *   device_init_rd1_ring- initial rd dma1 ring
- *   device_init_td0_ring- initial tx dma0 ring buffer
- *   device_init_td1_ring- initial tx dma1 ring buffer
- *   device_init_registers- initial MAC & BBP & RF internal registers.
- *   device_init_rings- initial tx/rx ring buffer
- *   device_free_rings- free all allocated ring buffer
- *   device_tx_srv- tx interrupt service function
+ *   device_init_rd0_ring - initial rd dma0 ring
+ *   device_init_rd1_ring - initial rd dma1 ring
+ *   device_init_td0_ring - initial tx dma0 ring buffer
+ *   device_init_td1_ring - initial tx dma1 ring buffer
+ *   device_init_registers - initial MAC & BBP & RF internal registers.
+ *   device_init_rings - initial tx/rx ring buffer
+ *   device_free_rings - free all allocated ring buffer
+ *   device_tx_srv - tx interrupt service function
  *
  * Revision History:
  */
@@ -202,7 +202,7 @@ static void device_init_registers(struct vnt_private *priv)
 	unsigned char byOFDMPwrdBm = 0;
 
 	MACbShutdown(priv);
-	BBvSoftwareReset(priv);
+	bb_software_reset(priv);
 
 	/* Do MACbSoftwareReset in MACvInitialize */
 	MACbSoftwareReset(priv);
@@ -279,8 +279,8 @@ static void device_init_registers(struct vnt_private *priv)
 	}
 
 	/* Set initial antenna mode */
-	BBvSetTxAntennaMode(priv, priv->byTxAntennaMode);
-	BBvSetRxAntennaMode(priv, priv->byRxAntennaMode);
+	bb_set_tx_antenna_mode(priv, priv->byTxAntennaMode);
+	bb_set_rx_antenna_mode(priv, priv->byRxAntennaMode);
 
 	/* zonetype initial */
 	priv->byOriginalZonetype = priv->abyEEPROM[EEP_OFS_ZONETYPE];
@@ -357,16 +357,16 @@ static void device_init_registers(struct vnt_private *priv)
 	VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
 
 	/* initialize BBP registers */
-	BBbVT3253Init(priv);
+	bb_vt3253_init(priv);
 
 	if (priv->bUpdateBBVGA) {
 		priv->byBBVGACurrent = priv->abyBBVGA[0];
 		priv->byBBVGANew = priv->byBBVGACurrent;
-		BBvSetVGAGainOffset(priv, priv->abyBBVGA[0]);
+		bb_set_vga_gain_offset(priv, priv->abyBBVGA[0]);
 	}
 
-	BBvSetRxAntennaMode(priv, priv->byRxAntennaMode);
-	BBvSetTxAntennaMode(priv, priv->byTxAntennaMode);
+	bb_set_rx_antenna_mode(priv, priv->byRxAntennaMode);
+	bb_set_tx_antenna_mode(priv, priv->byTxAntennaMode);
 
 	/* Set BB and packet type at the same time. */
 	/* Set Short Slot Time, xIFS, and RSPINF. */
@@ -1001,7 +1001,7 @@ static void vnt_check_bb_vga(struct vnt_private *priv)
 
 	if (priv->uBBVGADiffCount == 1) {
 		/* first VGA diff gain */
-		BBvSetVGAGainOffset(priv, priv->byBBVGANew);
+		bb_set_vga_gain_offset(priv, priv->byBBVGANew);
 
 		dev_dbg(&priv->pcid->dev,
 			"First RSSI[%d] NewGain[%d] OldGain[%d] Count[%d]\n",
@@ -1017,7 +1017,7 @@ static void vnt_check_bb_vga(struct vnt_private *priv)
 			priv->byBBVGACurrent,
 			(int)priv->uBBVGADiffCount);
 
-		BBvSetVGAGainOffset(priv, priv->byBBVGANew);
+		bb_set_vga_gain_offset(priv, priv->byBBVGANew);
 	}
 }
 
@@ -1445,7 +1445,7 @@ static void vnt_bss_info_changed(struct ieee80211_hw *hw,
 			priv->bShortSlotTime = false;
 
 		CARDbSetPhyParameter(priv, priv->byBBType);
-		BBvSetVGAGainOffset(priv, priv->abyBBVGA[0]);
+		bb_set_vga_gain_offset(priv, priv->abyBBVGA[0]);
 	}
 
 	if (changed & BSS_CHANGED_TXPOWER)
diff --git a/drivers/staging/vt6655/rf.c b/drivers/staging/vt6655/rf.c
index d6ca6e5551a7..747d79265a7c 100644
--- a/drivers/staging/vt6655/rf.c
+++ b/drivers/staging/vt6655/rf.c
@@ -419,7 +419,7 @@ static bool s_bAL7230Init(struct vnt_private *priv)
 
 	MACvWordRegBitsOn(iobase, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPECTI  |
 							 SOFTPWRCTL_TXPEINV));
-	BBvPowerSaveModeOFF(priv); /* RobertYu:20050106, have DC value for Calibration */
+	bb_power_save_mode_off(priv); /* RobertYu:20050106, have DC value for Calibration */
 
 	for (ii = 0; ii < CB_AL7230_INIT_SEQ; ii++)
 		ret &= IFRFbWriteEmbedded(priv, dwAL7230InitTable[ii]);
@@ -443,7 +443,7 @@ static bool s_bAL7230Init(struct vnt_private *priv)
 							 SOFTPWRCTL_SWPECTI  |
 							 SOFTPWRCTL_TXPEINV));
 
-	BBvPowerSaveModeON(priv); /* RobertYu:20050106 */
+	bb_power_save_mode_on(priv); /* RobertYu:20050106 */
 
 	/* PE1: TX_ON, PE2: RX_ON, PE3: PLLON */
 	/* 3-wire control for power saving mode */
diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c
index 37fcc42ed000..2f9c2ead3cb8 100644
--- a/drivers/staging/vt6655/rxtx.c
+++ b/drivers/staging/vt6655/rxtx.c
@@ -165,11 +165,11 @@ s_uGetTxRsvTime(
 {
 	unsigned int uDataTime, uAckTime;
 
-	uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wRate);
+	uDataTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, cbFrameLength, wRate);
 	if (byPktType == PK_TYPE_11B) /* llb,CCK mode */
-		uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopCCKBasicRate);
+		uAckTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopCCKBasicRate);
 	else /* 11g 2.4G OFDM mode & 11a 5G OFDM mode */
-		uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopOFDMBasicRate);
+		uAckTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopOFDMBasicRate);
 
 	if (bNeedAck)
 		return uDataTime + pDevice->uSIFS + uAckTime;
@@ -195,24 +195,28 @@ s_uGetRTSCTSRsvTime(
 	unsigned short wCurrentRate
 )
 {
-	unsigned int uRrvTime, uRTSTime, uCTSTime, uAckTime, uDataTime;
+	unsigned int uRrvTime = 0;
+	unsigned int uRTSTime = 0;
+	unsigned int uCTSTime = 0;
+	unsigned int uAckTime = 0;
+	unsigned int uDataTime = 0;
 
-	uRrvTime = uRTSTime = uCTSTime = uAckTime = uDataTime = 0;
-
-	uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wCurrentRate);
+	uDataTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, cbFrameLength, wCurrentRate);
 	if (byRTSRsvType == 0) { /* RTSTxRrvTime_bb */
-		uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
-		uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
+		uRTSTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
+		uAckTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
+		uCTSTime = uAckTime;
 	} else if (byRTSRsvType == 1) { /* RTSTxRrvTime_ba, only in 2.4GHZ */
-		uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
-		uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
-		uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
+		uRTSTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
+		uCTSTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
+		uAckTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
 	} else if (byRTSRsvType == 2) { /* RTSTxRrvTime_aa */
-		uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopOFDMBasicRate);
-		uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
+		uRTSTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 20, pDevice->byTopOFDMBasicRate);
+		uAckTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
+		uCTSTime = uAckTime;
 	} else if (byRTSRsvType == 3) { /* CTSTxRrvTime_ba, only in 2.4GHZ */
-		uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
-		uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
+		uCTSTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
+		uAckTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
 		uRrvTime = uCTSTime + uAckTime + uDataTime + 2 * pDevice->uSIFS;
 		return cpu_to_le16((u16)uRrvTime);
 	}
@@ -239,136 +243,125 @@ s_uGetDataDuration(
 )
 {
 	bool bLastFrag = false;
-	unsigned int uAckTime = 0, uNextPktTime = 0;
+	unsigned int uAckTime = 0, uNextPktTime = 0, len;
 
 	if (uFragIdx == (uMACfragNum - 1))
 		bLastFrag = true;
 
+	if (uFragIdx == (uMACfragNum - 2))
+		len = cbLastFragmentSize;
+	else
+		len = cbFrameLength;
+
 	switch (byDurType) {
 	case DATADUR_B:    /* DATADUR_B */
 		if (((uMACfragNum == 1)) || bLastFrag) {/* Non Frag or Last Frag */
 			if (bNeedAck) {
-				uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
+				uAckTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
 				return pDevice->uSIFS + uAckTime;
 			} else {
 				return 0;
 			}
 		} else {/* First Frag or Mid Frag */
-			if (uFragIdx == (uMACfragNum - 2))
-				uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
-			else
-				uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
+			uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, len, wRate, bNeedAck);
 
 			if (bNeedAck) {
-				uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
-				return pDevice->uSIFS + uAckTime + uNextPktTime;
-			} else {
-				return pDevice->uSIFS + uNextPktTime;
+				uAckTime = bb_get_frame_time(pDevice->byPreambleType,
+							     byPktType, 14,
+							     pDevice->byTopCCKBasicRate);
 			}
+			return pDevice->uSIFS + uAckTime + uNextPktTime;
 		}
 		break;
 
 	case DATADUR_A:    /* DATADUR_A */
 		if (((uMACfragNum == 1)) || bLastFrag) {/* Non Frag or Last Frag */
 			if (bNeedAck) {
-				uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
+				uAckTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
 				return pDevice->uSIFS + uAckTime;
 			} else {
 				return 0;
 			}
 		} else {/* First Frag or Mid Frag */
-			if (uFragIdx == (uMACfragNum - 2))
-				uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
-			else
-				uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
+			uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, len,
+						       wRate, bNeedAck);
 
 			if (bNeedAck) {
-				uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
-				return pDevice->uSIFS + uAckTime + uNextPktTime;
-			} else {
-				return pDevice->uSIFS + uNextPktTime;
+				uAckTime = bb_get_frame_time(pDevice->byPreambleType,
+							     byPktType, 14,
+							     pDevice->byTopOFDMBasicRate);
 			}
+			return pDevice->uSIFS + uAckTime + uNextPktTime;
 		}
 		break;
 
 	case DATADUR_A_F0:    /* DATADUR_A_F0 */
 		if (((uMACfragNum == 1)) || bLastFrag) {/* Non Frag or Last Frag */
 			if (bNeedAck) {
-				uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
+				uAckTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
 				return pDevice->uSIFS + uAckTime;
 			} else {
 				return 0;
 			}
 		} else { /* First Frag or Mid Frag */
+			if (wRate < RATE_18M)
+				wRate = RATE_18M;
+			else if (wRate > RATE_54M)
+				wRate = RATE_54M;
+
 			if (byFBOption == AUTO_FB_0) {
-				if (wRate < RATE_18M)
-					wRate = RATE_18M;
-				else if (wRate > RATE_54M)
-					wRate = RATE_54M;
-
-				if (uFragIdx == (uMACfragNum - 2))
-					uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
-				else
-					uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
-
-			} else { /* (byFBOption == AUTO_FB_1) */
-				if (wRate < RATE_18M)
-					wRate = RATE_18M;
-				else if (wRate > RATE_54M)
-					wRate = RATE_54M;
-
-				if (uFragIdx == (uMACfragNum - 2))
-					uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
-				else
-					uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
+				uNextPktTime = s_uGetTxRsvTime(pDevice,
+							       byPktType, len,
+							       wFB_Opt0[FB_RATE0][wRate - RATE_18M],
+							       bNeedAck);
+			} else {
+				uNextPktTime = s_uGetTxRsvTime(pDevice,
+							       byPktType, len,
+							       wFB_Opt1[FB_RATE0][wRate - RATE_18M],
+							       bNeedAck);
 			}
 
 			if (bNeedAck) {
-				uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
-				return pDevice->uSIFS + uAckTime + uNextPktTime;
-			} else {
-				return pDevice->uSIFS + uNextPktTime;
+				uAckTime = bb_get_frame_time(pDevice->byPreambleType,
+							     byPktType, 14,
+							     pDevice->byTopOFDMBasicRate);
 			}
+			return pDevice->uSIFS + uAckTime + uNextPktTime;
 		}
 		break;
 
 	case DATADUR_A_F1:    /* DATADUR_A_F1 */
 		if (((uMACfragNum == 1)) || bLastFrag) { /* Non Frag or Last Frag */
 			if (bNeedAck) {
-				uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
+				uAckTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
 				return pDevice->uSIFS + uAckTime;
 			} else {
 				return 0;
 			}
 		} else { /* First Frag or Mid Frag */
+			if (wRate < RATE_18M)
+				wRate = RATE_18M;
+			else if (wRate > RATE_54M)
+				wRate = RATE_54M;
+
 			if (byFBOption == AUTO_FB_0) {
-				if (wRate < RATE_18M)
-					wRate = RATE_18M;
-				else if (wRate > RATE_54M)
-					wRate = RATE_54M;
-
-				if (uFragIdx == (uMACfragNum - 2))
-					uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
-				else
-					uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
-
-			} else { /* (byFBOption == AUTO_FB_1) */
-				if (wRate < RATE_18M)
-					wRate = RATE_18M;
-				else if (wRate > RATE_54M)
-					wRate = RATE_54M;
-
-				if (uFragIdx == (uMACfragNum - 2))
-					uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
-				else
-					uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
+				uNextPktTime = s_uGetTxRsvTime(pDevice,
+							       byPktType, len,
+							       wFB_Opt0[FB_RATE0][wRate - RATE_18M],
+							       bNeedAck);
+			} else {
+				uNextPktTime = s_uGetTxRsvTime(pDevice,
+							       byPktType, len,
+							       wFB_Opt1[FB_RATE0][wRate - RATE_18M],
+							       bNeedAck);
 			}
+
 			if (bNeedAck) {
-				uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
-				return pDevice->uSIFS + uAckTime + uNextPktTime;
-			} else {
-				return pDevice->uSIFS + uNextPktTime;
+				uAckTime = bb_get_frame_time(pDevice->byPreambleType,
+							     byPktType, 14,
+							     pDevice->byTopOFDMBasicRate);
 			}
+			return pDevice->uSIFS + uAckTime + uNextPktTime;
 		}
 		break;
 
@@ -396,17 +389,17 @@ s_uGetRTSCTSDuration(
 
 	switch (byDurType) {
 	case RTSDUR_BB:    /* RTSDuration_bb */
-		uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
+		uCTSTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
 		uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
 		break;
 
 	case RTSDUR_BA:    /* RTSDuration_ba */
-		uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
+		uCTSTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
 		uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
 		break;
 
 	case RTSDUR_AA:    /* RTSDuration_aa */
-		uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
+		uCTSTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
 		uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
 		break;
 
@@ -415,7 +408,7 @@ s_uGetRTSCTSDuration(
 		break;
 
 	case RTSDUR_BA_F0: /* RTSDuration_ba_f0 */
-		uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
+		uCTSTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
 		if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
 			uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
 		else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
@@ -424,7 +417,7 @@ s_uGetRTSCTSDuration(
 		break;
 
 	case RTSDUR_AA_F0: /* RTSDuration_aa_f0 */
-		uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
+		uCTSTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
 		if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
 			uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
 		else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
@@ -433,7 +426,7 @@ s_uGetRTSCTSDuration(
 		break;
 
 	case RTSDUR_BA_F1: /* RTSDuration_ba_f1 */
-		uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
+		uCTSTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
 		if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
 			uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
 		else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
@@ -442,7 +435,7 @@ s_uGetRTSCTSDuration(
 		break;
 
 	case RTSDUR_AA_F1: /* RTSDuration_aa_f1 */
-		uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
+		uCTSTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
 		if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
 			uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
 		else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
@@ -1040,16 +1033,14 @@ s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
 	bool bRTS = (bool)(fifo_ctl & FIFOCTL_RTS);
 	struct vnt_tx_desc *ptdCurr;
 	unsigned int cbHeaderLength = 0;
-	void *pvRrvTime;
-	struct vnt_mic_hdr *pMICHDR;
-	void *pvRTS;
-	void *pvCTS;
-	void *pvTxDataHd;
+	void *pvRrvTime = NULL;
+	struct vnt_mic_hdr *pMICHDR = NULL;
+	void *pvRTS = NULL;
+	void *pvCTS = NULL;
+	void *pvTxDataHd = NULL;
 	unsigned short wTxBufSize;   /* FFinfo size */
 	unsigned char byFBOption = AUTO_FB_NONE;
 
-	pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
-
 	cbFrameSize = skb->len + 4;
 
 	if (info->control.hw_key) {
diff --git a/drivers/staging/vt6656/baseband.c b/drivers/staging/vt6656/baseband.c
index a19a563d8bcc..e0352405e4cf 100644
--- a/drivers/staging/vt6656/baseband.c
+++ b/drivers/staging/vt6656/baseband.c
@@ -115,6 +115,86 @@ static const u16 vnt_frame_time[MAX_RATE] = {
 	10, 20, 55, 110, 24, 36, 48, 72, 96, 144, 192, 216
 };
 
+struct vnt_threshold {
+	u8 bb_pre_ed_rssi;
+	u8 cr_201;
+	u8 cr_206;
+};
+
+static const struct vnt_threshold al2230_vnt_threshold[] = {
+	{0, 0x00, 0x30},	/* Max sensitivity */
+	{68, 0x00, 0x36},
+	{67, 0x00, 0x43},
+	{66, 0x00, 0x51},
+	{65, 0x00, 0x62},
+	{64, 0x00, 0x79},
+	{63, 0x00, 0x93},
+	{62, 0x00, 0xb9},
+	{61, 0x00, 0xe3},
+	{60, 0x01, 0x18},
+	{59, 0x01, 0x54},
+	{58, 0x01, 0xa0},
+	{57, 0x02, 0x20},
+	{56, 0x02, 0xa0},
+	{55, 0x03, 0x00},
+	{53, 0x06, 0x00},
+	{51, 0x09, 0x00},
+	{49, 0x0e, 0x00},
+	{47, 0x15, 0x00},
+	{46, 0x1a, 0x00},
+	{45, 0xff, 0x00}
+};
+
+static const struct vnt_threshold vt3226_vnt_threshold[] = {
+	{0, 0x00, 0x24},	/* Max sensitivity */
+	{68, 0x00, 0x2d},
+	{67, 0x00, 0x36},
+	{66, 0x00, 0x43},
+	{65, 0x00, 0x52},
+	{64, 0x00, 0x68},
+	{63, 0x00, 0x80},
+	{62, 0x00, 0x9c},
+	{61, 0x00, 0xc0},
+	{60, 0x00, 0xea},
+	{59, 0x01, 0x30},
+	{58, 0x01, 0x70},
+	{57, 0x01, 0xb0},
+	{56, 0x02, 0x30},
+	{55, 0x02, 0xc0},
+	{53, 0x04, 0x00},
+	{51, 0x07, 0x00},
+	{49, 0x0a, 0x00},
+	{47, 0x11, 0x00},
+	{45, 0x18, 0x00},
+	{43, 0x26, 0x00},
+	{42, 0x36, 0x00},
+	{41, 0xff, 0x00}
+};
+
+static const struct vnt_threshold vt3342_vnt_threshold[] = {
+	{0, 0x00, 0x38},	/* Max sensitivity */
+	{66, 0x00, 0x43},
+	{65, 0x00, 0x52},
+	{64, 0x00, 0x68},
+	{63, 0x00, 0x80},
+	{62, 0x00, 0x9c},
+	{61, 0x00, 0xc0},
+	{60, 0x00, 0xea},
+	{59, 0x01, 0x30},
+	{58, 0x01, 0x70},
+	{57, 0x01, 0xb0},
+	{56, 0x02, 0x30},
+	{55, 0x02, 0xc0},
+	{53, 0x04, 0x00},
+	{51, 0x07, 0x00},
+	{49, 0x0a, 0x00},
+	{47, 0x11, 0x00},
+	{45, 0x18, 0x00},
+	{43, 0x26, 0x00},
+	{42, 0x36, 0x00},
+	{41, 0xff, 0x00}
+};
+
 /*
  * Description: Calculate data frame transmitting time
  *
@@ -134,7 +214,7 @@ unsigned int vnt_get_frame_time(u8 preamble_type, u8 pkt_type,
 {
 	unsigned int frame_time;
 	unsigned int preamble;
-	unsigned int rate = 0;
+	unsigned int rate;
 
 	if (tx_rate > RATE_54M)
 		return 0;
@@ -142,7 +222,7 @@ unsigned int vnt_get_frame_time(u8 preamble_type, u8 pkt_type,
 	rate = (unsigned int)vnt_frame_time[tx_rate];
 
 	if (tx_rate <= 3) {
-		if (preamble_type == 1)
+		if (preamble_type == PREAMBLE_SHORT)
 			preamble = 96;
 		else
 			preamble = 192;
@@ -198,7 +278,7 @@ void vnt_get_phy_field(struct vnt_private *priv, u32 frame_length,
 	case RATE_2M:
 		count = bit_count / 2;
 
-		if (preamble_type == 1)
+		if (preamble_type == PREAMBLE_SHORT)
 			phy->signal = 0x09;
 		else
 			phy->signal = 0x01;
@@ -207,7 +287,7 @@ void vnt_get_phy_field(struct vnt_private *priv, u32 frame_length,
 	case RATE_5M:
 		count = DIV_ROUND_UP(bit_count * 10, 55);
 
-		if (preamble_type == 1)
+		if (preamble_type == PREAMBLE_SHORT)
 			phy->signal = 0x0a;
 		else
 			phy->signal = 0x02;
@@ -224,7 +304,7 @@ void vnt_get_phy_field(struct vnt_private *priv, u32 frame_length,
 				ext_bit = true;
 		}
 
-		if (preamble_type == 1)
+		if (preamble_type == PREAMBLE_SHORT)
 			phy->signal = 0x0b;
 		else
 			phy->signal = 0x03;
@@ -352,7 +432,7 @@ int vnt_set_antenna_mode(struct vnt_private *priv, u8 antenna_mode)
 
 int vnt_vt3184_init(struct vnt_private *priv)
 {
-	int ret = 0;
+	int ret;
 	u16 length;
 	u8 *addr;
 	u8 data;
@@ -366,23 +446,15 @@ int vnt_vt3184_init(struct vnt_private *priv)
 
 	dev_dbg(&priv->usb->dev, "RF Type %d\n", priv->rf_type);
 
-	if (priv->rf_type == RF_AL2230 ||
-	    priv->rf_type == RF_AL2230S) {
+	if ((priv->rf_type == RF_AL2230) ||
+	    (priv->rf_type == RF_AL2230S) ||
+	    (priv->rf_type == RF_AIROHA7230)) {
 		priv->bb_rx_conf = vnt_vt3184_al2230[10];
 		length = sizeof(vnt_vt3184_al2230);
 		addr = vnt_vt3184_al2230;
 
-		priv->bb_vga[0] = 0x1C;
-		priv->bb_vga[1] = 0x10;
-		priv->bb_vga[2] = 0x0;
-		priv->bb_vga[3] = 0x0;
-
-	} else if (priv->rf_type == RF_AIROHA7230) {
-		priv->bb_rx_conf = vnt_vt3184_al2230[10];
-		length = sizeof(vnt_vt3184_al2230);
-		addr = vnt_vt3184_al2230;
-
-		addr[0xd7] = 0x06;
+		if (priv->rf_type == RF_AIROHA7230)
+			addr[0xd7] = 0x06;
 
 		priv->bb_vga[0] = 0x1c;
 		priv->bb_vga[1] = 0x10;
@@ -390,22 +462,8 @@ int vnt_vt3184_init(struct vnt_private *priv)
 		priv->bb_vga[3] = 0x0;
 
 	} else if ((priv->rf_type == RF_VT3226) ||
-			(priv->rf_type == RF_VT3226D0)) {
-		priv->bb_rx_conf = vnt_vt3184_vt3226d0[10];
-		length = sizeof(vnt_vt3184_vt3226d0);
-		addr = vnt_vt3184_vt3226d0;
-
-		priv->bb_vga[0] = 0x20;
-		priv->bb_vga[1] = 0x10;
-		priv->bb_vga[2] = 0x0;
-		priv->bb_vga[3] = 0x0;
-
-		/* Fix VT3226 DFC system timing issue */
-		ret = vnt_mac_reg_bits_on(priv, MAC_REG_SOFTPWRCTL2,
-					  SOFTPWRCTL_RFLEOPT);
-		if (ret)
-			goto end;
-	} else if (priv->rf_type == RF_VT3342A0) {
+		   (priv->rf_type == RF_VT3226D0) ||
+		   (priv->rf_type == RF_VT3342A0)) {
 		priv->bb_rx_conf = vnt_vt3184_vt3226d0[10];
 		length = sizeof(vnt_vt3184_vt3226d0);
 		addr = vnt_vt3184_vt3226d0;
@@ -435,19 +493,13 @@ int vnt_vt3184_init(struct vnt_private *priv)
 	if (ret)
 		goto end;
 
-	if (priv->rf_type == RF_VT3226 ||
-	    priv->rf_type == RF_VT3342A0) {
-		ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_MACREG,
-					 MAC_REG_ITRTMSET, 0x23);
-		if (ret)
-			goto end;
+	if ((priv->rf_type == RF_VT3226) ||
+	    (priv->rf_type == RF_VT3342A0) ||
+	    (priv->rf_type == RF_VT3226D0)) {
+		data = (priv->rf_type == RF_VT3226D0) ? 0x11 : 0x23;
 
-		ret = vnt_mac_reg_bits_on(priv, MAC_REG_PAPEDELAY, BIT(0));
-		if (ret)
-			goto end;
-	} else if (priv->rf_type == RF_VT3226D0) {
 		ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_MACREG,
-					 MAC_REG_ITRTMSET, 0x11);
+					 MAC_REG_ITRTMSET, data);
 		if (ret)
 			goto end;
 
@@ -572,254 +624,42 @@ int vnt_exit_deep_sleep(struct vnt_private *priv)
 
 void vnt_update_pre_ed_threshold(struct vnt_private *priv, int scanning)
 {
-	u8 cr_201 = 0x0, cr_206 = 0x0;
+	const struct vnt_threshold *threshold = NULL;
+	u8 length;
+	u8 cr_201, cr_206;
 	u8 ed_inx = priv->bb_pre_ed_index;
 
 	switch (priv->rf_type) {
 	case RF_AL2230:
 	case RF_AL2230S:
 	case RF_AIROHA7230:
-		if (scanning) { /* Max sensitivity */
-			ed_inx = 0;
-			cr_206 = 0x30;
-			break;
-		}
-
-		if (priv->bb_pre_ed_rssi <= 45) {
-			ed_inx = 20;
-			cr_201 = 0xff;
-		} else if (priv->bb_pre_ed_rssi <= 46) {
-			ed_inx = 19;
-			cr_201 = 0x1a;
-		} else if (priv->bb_pre_ed_rssi <= 47) {
-			ed_inx = 18;
-			cr_201 = 0x15;
-		} else if (priv->bb_pre_ed_rssi <= 49) {
-			ed_inx = 17;
-			cr_201 = 0xe;
-		} else if (priv->bb_pre_ed_rssi <= 51) {
-			ed_inx = 16;
-			cr_201 = 0x9;
-		} else if (priv->bb_pre_ed_rssi <= 53) {
-			ed_inx = 15;
-			cr_201 = 0x6;
-		} else if (priv->bb_pre_ed_rssi <= 55) {
-			ed_inx = 14;
-			cr_201 = 0x3;
-		} else if (priv->bb_pre_ed_rssi <= 56) {
-			ed_inx = 13;
-			cr_201 = 0x2;
-			cr_206 = 0xa0;
-		} else if (priv->bb_pre_ed_rssi <= 57) {
-			ed_inx = 12;
-			cr_201 = 0x2;
-			cr_206 = 0x20;
-		} else if (priv->bb_pre_ed_rssi <= 58) {
-			ed_inx = 11;
-			cr_201 = 0x1;
-			cr_206 = 0xa0;
-		} else if (priv->bb_pre_ed_rssi <= 59) {
-			ed_inx = 10;
-			cr_201 = 0x1;
-			cr_206 = 0x54;
-		} else if (priv->bb_pre_ed_rssi <= 60) {
-			ed_inx = 9;
-			cr_201 = 0x1;
-			cr_206 = 0x18;
-		} else if (priv->bb_pre_ed_rssi <= 61) {
-			ed_inx = 8;
-			cr_206 = 0xe3;
-		} else if (priv->bb_pre_ed_rssi <= 62) {
-			ed_inx = 7;
-			cr_206 = 0xb9;
-		} else if (priv->bb_pre_ed_rssi <= 63) {
-			ed_inx = 6;
-			cr_206 = 0x93;
-		} else if (priv->bb_pre_ed_rssi <= 64) {
-			ed_inx = 5;
-			cr_206 = 0x79;
-		} else if (priv->bb_pre_ed_rssi <= 65) {
-			ed_inx = 4;
-			cr_206 = 0x62;
-		} else if (priv->bb_pre_ed_rssi <= 66) {
-			ed_inx = 3;
-			cr_206 = 0x51;
-		} else if (priv->bb_pre_ed_rssi <= 67) {
-			ed_inx = 2;
-			cr_206 = 0x43;
-		} else if (priv->bb_pre_ed_rssi <= 68) {
-			ed_inx = 1;
-			cr_206 = 0x36;
-		} else {
-			ed_inx = 0;
-			cr_206 = 0x30;
-		}
+		threshold = al2230_vnt_threshold;
+		length = ARRAY_SIZE(al2230_vnt_threshold);
 		break;
 
 	case RF_VT3226:
 	case RF_VT3226D0:
-		if (scanning)	{ /* Max sensitivity */
-			ed_inx = 0;
-			cr_206 = 0x24;
-			break;
-		}
-
-		if (priv->bb_pre_ed_rssi <= 41) {
-			ed_inx = 22;
-			cr_201 = 0xff;
-		} else if (priv->bb_pre_ed_rssi <= 42) {
-			ed_inx = 21;
-			cr_201 = 0x36;
-		} else if (priv->bb_pre_ed_rssi <= 43) {
-			ed_inx = 20;
-			cr_201 = 0x26;
-		} else if (priv->bb_pre_ed_rssi <= 45) {
-			ed_inx = 19;
-			cr_201 = 0x18;
-		} else if (priv->bb_pre_ed_rssi <= 47) {
-			ed_inx = 18;
-			cr_201 = 0x11;
-		} else if (priv->bb_pre_ed_rssi <= 49) {
-			ed_inx = 17;
-			cr_201 = 0xa;
-		} else if (priv->bb_pre_ed_rssi <= 51) {
-			ed_inx = 16;
-			cr_201 = 0x7;
-		} else if (priv->bb_pre_ed_rssi <= 53) {
-			ed_inx = 15;
-			cr_201 = 0x4;
-		} else if (priv->bb_pre_ed_rssi <= 55) {
-			ed_inx = 14;
-			cr_201 = 0x2;
-			cr_206 = 0xc0;
-		} else if (priv->bb_pre_ed_rssi <= 56) {
-			ed_inx = 13;
-			cr_201 = 0x2;
-			cr_206 = 0x30;
-		} else if (priv->bb_pre_ed_rssi <= 57) {
-			ed_inx = 12;
-			cr_201 = 0x1;
-			cr_206 = 0xb0;
-		} else if (priv->bb_pre_ed_rssi <= 58) {
-			ed_inx = 11;
-			cr_201 = 0x1;
-			cr_206 = 0x70;
-		} else if (priv->bb_pre_ed_rssi <= 59) {
-			ed_inx = 10;
-			cr_201 = 0x1;
-			cr_206 = 0x30;
-		} else if (priv->bb_pre_ed_rssi <= 60) {
-			ed_inx = 9;
-			cr_206 = 0xea;
-		} else if (priv->bb_pre_ed_rssi <= 61) {
-			ed_inx = 8;
-			cr_206 = 0xc0;
-		} else if (priv->bb_pre_ed_rssi <= 62) {
-			ed_inx = 7;
-			cr_206 = 0x9c;
-		} else if (priv->bb_pre_ed_rssi <= 63) {
-			ed_inx = 6;
-			cr_206 = 0x80;
-		} else if (priv->bb_pre_ed_rssi <= 64) {
-			ed_inx = 5;
-			cr_206 = 0x68;
-		} else if (priv->bb_pre_ed_rssi <= 65) {
-			ed_inx = 4;
-			cr_206 = 0x52;
-		} else if (priv->bb_pre_ed_rssi <= 66) {
-			ed_inx = 3;
-			cr_206 = 0x43;
-		} else if (priv->bb_pre_ed_rssi <= 67) {
-			ed_inx = 2;
-			cr_206 = 0x36;
-		} else if (priv->bb_pre_ed_rssi <= 68) {
-			ed_inx = 1;
-			cr_206 = 0x2d;
-		} else {
-			ed_inx = 0;
-			cr_206 = 0x24;
-		}
+		threshold = vt3226_vnt_threshold;
+		length = ARRAY_SIZE(vt3226_vnt_threshold);
 		break;
 
 	case RF_VT3342A0:
-		if (scanning) { /* need Max sensitivity */
-			ed_inx = 0;
-			cr_206 = 0x38;
-			break;
-		}
-
-		if (priv->bb_pre_ed_rssi <= 41) {
-			ed_inx = 20;
-			cr_201 = 0xff;
-		} else if (priv->bb_pre_ed_rssi <= 42) {
-			ed_inx = 19;
-			cr_201 = 0x36;
-		} else if (priv->bb_pre_ed_rssi <= 43) {
-			ed_inx = 18;
-			cr_201 = 0x26;
-		} else if (priv->bb_pre_ed_rssi <= 45) {
-			ed_inx = 17;
-			cr_201 = 0x18;
-		} else if (priv->bb_pre_ed_rssi <= 47) {
-			ed_inx = 16;
-			cr_201 = 0x11;
-		} else if (priv->bb_pre_ed_rssi <= 49) {
-			ed_inx = 15;
-			cr_201 = 0xa;
-		} else if (priv->bb_pre_ed_rssi <= 51) {
-			ed_inx = 14;
-			cr_201 = 0x7;
-		} else if (priv->bb_pre_ed_rssi <= 53) {
-			ed_inx = 13;
-			cr_201 = 0x4;
-		} else if (priv->bb_pre_ed_rssi <= 55) {
-			ed_inx = 12;
-			cr_201 = 0x2;
-			cr_206 = 0xc0;
-		} else if (priv->bb_pre_ed_rssi <= 56) {
-			ed_inx = 11;
-			cr_201 = 0x2;
-			cr_206 = 0x30;
-		} else if (priv->bb_pre_ed_rssi <= 57) {
-			ed_inx = 10;
-			cr_201 = 0x1;
-			cr_206 = 0xb0;
-		} else if (priv->bb_pre_ed_rssi <= 58) {
-			ed_inx = 9;
-			cr_201 = 0x1;
-			cr_206 = 0x70;
-		} else if (priv->bb_pre_ed_rssi <= 59) {
-			ed_inx = 8;
-			cr_201 = 0x1;
-			cr_206 = 0x30;
-		} else if (priv->bb_pre_ed_rssi <= 60) {
-			ed_inx = 7;
-			cr_206 = 0xea;
-		} else if (priv->bb_pre_ed_rssi <= 61) {
-			ed_inx = 6;
-			cr_206 = 0xc0;
-		} else if (priv->bb_pre_ed_rssi <= 62) {
-			ed_inx = 5;
-			cr_206 = 0x9c;
-		} else if (priv->bb_pre_ed_rssi <= 63) {
-			ed_inx = 4;
-			cr_206 = 0x80;
-		} else if (priv->bb_pre_ed_rssi <= 64) {
-			ed_inx = 3;
-			cr_206 = 0x68;
-		} else if (priv->bb_pre_ed_rssi <= 65) {
-			ed_inx = 2;
-			cr_206 = 0x52;
-		} else if (priv->bb_pre_ed_rssi <= 66) {
-			ed_inx = 1;
-			cr_206 = 0x43;
-		} else {
-			ed_inx = 0;
-			cr_206 = 0x38;
-		}
+		threshold = vt3342_vnt_threshold;
+		length = ARRAY_SIZE(vt3342_vnt_threshold);
 		break;
 	}
 
+	if (!threshold)
+		return;
+
+	for (ed_inx = scanning ? 0 : length - 1; ed_inx > 0; ed_inx--) {
+		if (priv->bb_pre_ed_rssi <= threshold[ed_inx].bb_pre_ed_rssi)
+			break;
+	}
+
+	cr_201 = threshold[ed_inx].cr_201;
+	cr_206 = threshold[ed_inx].cr_206;
+
 	if (ed_inx == priv->bb_pre_ed_index && !scanning)
 		return;
 
@@ -828,9 +668,6 @@ void vnt_update_pre_ed_threshold(struct vnt_private *priv, int scanning)
 	dev_dbg(&priv->usb->dev, "%s bb_pre_ed_rssi %d\n",
 		__func__, priv->bb_pre_ed_rssi);
 
-	if (!cr_201 && !cr_206)
-		return;
-
 	vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0xc9, cr_201);
 	vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0xce, cr_206);
 }
diff --git a/drivers/staging/vt6656/card.c b/drivers/staging/vt6656/card.c
index dc3ab10eb630..9bd37e57c727 100644
--- a/drivers/staging/vt6656/card.c
+++ b/drivers/staging/vt6656/card.c
@@ -74,167 +74,25 @@ void vnt_set_channel(struct vnt_private *priv, u32 connection_channel)
 			   (u8)(connection_channel | 0x80));
 }
 
-/*
- * Description: Get CCK mode basic rate
- *
- * Parameters:
- *  In:
- *      priv		- The adapter to be set
- *      rate_idx	- Receiving data rate
- *  Out:
- *      none
- *
- * Return Value: response Control frame rate
- *
- */
-static u16 vnt_get_cck_rate(struct vnt_private *priv, u16 rate_idx)
-{
-	u16 ui = rate_idx;
-
-	while (ui > RATE_1M) {
-		if (priv->basic_rates & (1 << ui))
-			return ui;
-		ui--;
-	}
-
-	return RATE_1M;
-}
-
-/*
- * Description: Get OFDM mode basic rate
- *
- * Parameters:
- *  In:
- *      priv		- The adapter to be set
- *      rate_idx	- Receiving data rate
- *  Out:
- *      none
- *
- * Return Value: response Control frame rate
- *
- */
-static u16 vnt_get_ofdm_rate(struct vnt_private *priv, u16 rate_idx)
-{
-	u16 ui = rate_idx;
-
-	dev_dbg(&priv->usb->dev, "%s basic rate: %d\n",
-		__func__,  priv->basic_rates);
-
-	if (!vnt_ofdm_min_rate(priv)) {
-		dev_dbg(&priv->usb->dev, "%s (NO OFDM) %d\n",
-			__func__, rate_idx);
-		if (rate_idx > RATE_24M)
-			rate_idx = RATE_24M;
-		return rate_idx;
-	}
-
-	while (ui > RATE_11M) {
-		if (priv->basic_rates & (1 << ui)) {
-			dev_dbg(&priv->usb->dev, "%s rate: %d\n",
-				__func__, ui);
-			return ui;
-		}
-		ui--;
-	}
+static const u8 vnt_rspinf_b_short_table[] = {
+	0x70, 0x00, 0x00, 0x00, 0x38, 0x00, 0x09, 0x00,
+	0x15, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0b, 0x80
+};
 
-	dev_dbg(&priv->usb->dev, "%s basic rate: 24M\n", __func__);
+static const u8 vnt_rspinf_b_long_table[] = {
+	0x70, 0x00, 0x00, 0x00, 0x38, 0x00, 0x01, 0x00,
+	0x15, 0x00, 0x02, 0x00, 0x0b, 0x00, 0x03, 0x80
+};
 
-	return RATE_24M;
-}
+static const u8 vnt_rspinf_a_table[] = {
+	0x9b, 0x18, 0x9f, 0x10, 0x9a, 0x0a, 0x9e, 0x08, 0x99,
+	0x08, 0x9d, 0x04, 0x98, 0x04, 0x9c, 0x04, 0x9c, 0x04
+};
 
-/*
- * Description: Calculate TxRate and RsvTime fields for RSPINF in OFDM mode.
- *
- * Parameters:
- * In:
- *	rate	- Tx Rate
- *	bb_type	- Tx Packet type
- * Out:
- *	tx_rate	- pointer to RSPINF TxRate field
- *	rsv_time- pointer to RSPINF RsvTime field
- *
- * Return Value: none
- *
- */
-static void vnt_calculate_ofdm_rate(u16 rate, u8 bb_type,
-				    u8 *tx_rate, u8 *rsv_time)
-{
-	switch (rate) {
-	case RATE_6M:
-		if (bb_type == BB_TYPE_11A) {
-			*tx_rate = 0x9b;
-			*rsv_time = 24;
-		} else {
-			*tx_rate = 0x8b;
-			*rsv_time = 30;
-		}
-		break;
-	case RATE_9M:
-		if (bb_type == BB_TYPE_11A) {
-			*tx_rate = 0x9f;
-			*rsv_time = 16;
-		} else {
-			*tx_rate = 0x8f;
-			*rsv_time = 22;
-		}
-		break;
-	case RATE_12M:
-		if (bb_type == BB_TYPE_11A) {
-			*tx_rate = 0x9a;
-			*rsv_time = 12;
-		} else {
-			*tx_rate = 0x8a;
-			*rsv_time = 18;
-		}
-		break;
-	case RATE_18M:
-		if (bb_type == BB_TYPE_11A) {
-			*tx_rate = 0x9e;
-			*rsv_time = 8;
-		} else {
-			*tx_rate = 0x8e;
-			*rsv_time = 14;
-		}
-		break;
-	case RATE_36M:
-		if (bb_type == BB_TYPE_11A) {
-			*tx_rate = 0x9d;
-			*rsv_time = 4;
-		} else {
-			*tx_rate = 0x8d;
-			*rsv_time = 10;
-		}
-		break;
-	case RATE_48M:
-		if (bb_type == BB_TYPE_11A) {
-			*tx_rate = 0x98;
-			*rsv_time = 4;
-		} else {
-			*tx_rate = 0x88;
-			*rsv_time = 10;
-		}
-		break;
-	case RATE_54M:
-		if (bb_type == BB_TYPE_11A) {
-			*tx_rate = 0x9c;
-			*rsv_time = 4;
-		} else {
-			*tx_rate = 0x8c;
-			*rsv_time = 10;
-		}
-		break;
-	case RATE_24M:
-	default:
-		if (bb_type == BB_TYPE_11A) {
-			*tx_rate = 0x99;
-			*rsv_time = 8;
-		} else {
-			*tx_rate = 0x89;
-			*rsv_time = 14;
-		}
-		break;
-	}
-}
+static const u8 vnt_rspinf_gb_table[] = {
+	0x8b, 0x1e, 0x8f, 0x16, 0x8a, 0x12, 0x8e, 0x0e, 0x89,
+	0x0e, 0x8d, 0x0a, 0x88, 0x0a, 0x8c, 0x0a, 0x8c, 0x0a
+};
 
 /*
  * Description: Set RSPINF
@@ -251,82 +109,32 @@ static void vnt_calculate_ofdm_rate(u16 rate, u8 bb_type,
 
 void vnt_set_rspinf(struct vnt_private *priv, u8 bb_type)
 {
-	struct vnt_phy_field phy[4];
-	u8 tx_rate[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; /* For OFDM */
-	u8 rsv_time[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
-	u8 data[34];
-	int i;
-
-	/*RSPINF_b_1*/
-	vnt_get_phy_field(priv, 14, vnt_get_cck_rate(priv, RATE_1M),
-			  PK_TYPE_11B, &phy[0]);
+	const u8 *data;
+	u16 len;
 
-	/*RSPINF_b_2*/
-	vnt_get_phy_field(priv, 14, vnt_get_cck_rate(priv, RATE_2M),
-			  PK_TYPE_11B, &phy[1]);
-
-	/*RSPINF_b_5*/
-	vnt_get_phy_field(priv, 14, vnt_get_cck_rate(priv, RATE_5M),
-			  PK_TYPE_11B, &phy[2]);
-
-	/*RSPINF_b_11*/
-	vnt_get_phy_field(priv, 14, vnt_get_cck_rate(priv, RATE_11M),
-			  PK_TYPE_11B, &phy[3]);
-
-	/*RSPINF_a_6*/
-	vnt_calculate_ofdm_rate(RATE_6M, bb_type, &tx_rate[0], &rsv_time[0]);
-
-	/*RSPINF_a_9*/
-	vnt_calculate_ofdm_rate(RATE_9M, bb_type, &tx_rate[1], &rsv_time[1]);
-
-	/*RSPINF_a_12*/
-	vnt_calculate_ofdm_rate(RATE_12M, bb_type, &tx_rate[2], &rsv_time[2]);
-
-	/*RSPINF_a_18*/
-	vnt_calculate_ofdm_rate(RATE_18M, bb_type, &tx_rate[3], &rsv_time[3]);
-
-	/*RSPINF_a_24*/
-	vnt_calculate_ofdm_rate(RATE_24M, bb_type, &tx_rate[4], &rsv_time[4]);
-
-	/*RSPINF_a_36*/
-	vnt_calculate_ofdm_rate(vnt_get_ofdm_rate(priv, RATE_36M),
-				bb_type, &tx_rate[5], &rsv_time[5]);
-
-	/*RSPINF_a_48*/
-	vnt_calculate_ofdm_rate(vnt_get_ofdm_rate(priv, RATE_48M),
-				bb_type, &tx_rate[6], &rsv_time[6]);
-
-	/*RSPINF_a_54*/
-	vnt_calculate_ofdm_rate(vnt_get_ofdm_rate(priv, RATE_54M),
-				bb_type, &tx_rate[7], &rsv_time[7]);
-
-	/*RSPINF_a_72*/
-	vnt_calculate_ofdm_rate(vnt_get_ofdm_rate(priv, RATE_54M),
-				bb_type, &tx_rate[8], &rsv_time[8]);
-
-	put_unaligned(phy[0].len, (u16 *)&data[0]);
-	data[2] = phy[0].signal;
-	data[3] = phy[0].service;
-
-	put_unaligned(phy[1].len, (u16 *)&data[4]);
-	data[6] = phy[1].signal;
-	data[7] = phy[1].service;
-
-	put_unaligned(phy[2].len, (u16 *)&data[8]);
-	data[10] = phy[2].signal;
-	data[11] = phy[2].service;
+	if (priv->preamble_type) {
+		data = vnt_rspinf_b_short_table;
+		len = ARRAY_SIZE(vnt_rspinf_b_short_table);
+	} else {
+		data = vnt_rspinf_b_long_table;
+		len = ARRAY_SIZE(vnt_rspinf_b_long_table);
+	}
 
-	put_unaligned(phy[3].len, (u16 *)&data[12]);
-	data[14] = phy[3].signal;
-	data[15] = phy[3].service;
+	 /* RSPINF_b_1 to RSPINF_b_11 */
+	vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_RSPINF_B_1,
+			MESSAGE_REQUEST_MACREG, len, data);
 
-	for (i = 0; i < 9; i++) {
-		data[16 + i * 2] = tx_rate[i];
-		data[16 + i * 2 + 1] = rsv_time[i];
+	if (bb_type == BB_TYPE_11A) {
+		data = vnt_rspinf_a_table;
+		len = ARRAY_SIZE(vnt_rspinf_a_table);
+	} else {
+		data = vnt_rspinf_gb_table;
+		len = ARRAY_SIZE(vnt_rspinf_gb_table);
 	}
 
-	vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_RSPINF_B_1,
-			MESSAGE_REQUEST_MACREG, 34, &data[0]);
+	/* RSPINF_a_6 to RSPINF_a_72 */
+	vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_RSPINF_A_6,
+			MESSAGE_REQUEST_MACREG, len, data);
 }
 
 /*
@@ -723,9 +531,13 @@ int vnt_radio_power_on(struct vnt_private *priv)
 {
 	int ret = 0;
 
-	vnt_exit_deep_sleep(priv);
+	ret = vnt_exit_deep_sleep(priv);
+	if (ret)
+		return ret;
 
-	vnt_mac_reg_bits_on(priv, MAC_REG_HOSTCR, HOSTCR_RXON);
+	ret = vnt_mac_reg_bits_on(priv, MAC_REG_HOSTCR, HOSTCR_RXON);
+	if (ret)
+		return ret;
 
 	switch (priv->rf_type) {
 	case RF_AL2230:
@@ -734,14 +546,14 @@ int vnt_radio_power_on(struct vnt_private *priv)
 	case RF_VT3226:
 	case RF_VT3226D0:
 	case RF_VT3342A0:
-		vnt_mac_reg_bits_on(priv, MAC_REG_SOFTPWRCTL,
-				    (SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPE3));
-		break;
+		ret = vnt_mac_reg_bits_on(priv, MAC_REG_SOFTPWRCTL,
+					  (SOFTPWRCTL_SWPE2 |
+					   SOFTPWRCTL_SWPE3));
+		if (ret)
+			return ret;
 	}
 
-	vnt_mac_reg_bits_off(priv, MAC_REG_GPIOCTL1, GPIO3_INTMD);
-
-	return ret;
+	return vnt_mac_reg_bits_off(priv, MAC_REG_GPIOCTL1, GPIO3_INTMD);
 }
 
 void vnt_set_bss_mode(struct vnt_private *priv)
diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h
index e6ee9411f080..41226cd599c6 100644
--- a/drivers/staging/vt6656/device.h
+++ b/drivers/staging/vt6656/device.h
@@ -344,7 +344,6 @@ struct vnt_private {
 	u8 ofdm_pwr_tbl[14];
 	u8 ofdm_a_pwr_tbl[42];
 
-	u16 current_rate;
 	u16 tx_rate_fb0;
 	u16 tx_rate_fb1;
 
diff --git a/drivers/staging/vt6656/mac.h b/drivers/staging/vt6656/mac.h
index c532b27de37f..b01d9ee8677e 100644
--- a/drivers/staging/vt6656/mac.h
+++ b/drivers/staging/vt6656/mac.h
@@ -177,7 +177,7 @@
 #define EnCFG_BBType_a		0x00
 #define EnCFG_BBType_b		BIT(0)
 #define EnCFG_BBType_g		BIT(1)
-#define EnCFG_BBType_MASK	(BIT(0) | BIT(1))
+#define EnCFG_BBType_MASK	(EnCFG_BBType_b | EnCFG_BBType_g)
 #define EnCFG_ProtectMd		BIT(5)
 
 /* Bits in the EnhanceCFG_1 register */
diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c
index 8e7269c87ea9..3c76d3cb5bbe 100644
--- a/drivers/staging/vt6656/main_usb.c
+++ b/drivers/staging/vt6656/main_usb.c
@@ -99,7 +99,7 @@ static void vnt_set_options(struct vnt_private *priv)
 	priv->op_mode = NL80211_IFTYPE_UNSPECIFIED;
 	priv->bb_type = BBP_TYPE_DEF;
 	priv->packet_type = priv->bb_type;
-	priv->preamble_type = 0;
+	priv->preamble_type = PREAMBLE_LONG;
 	priv->exist_sw_net_addr = false;
 }
 
@@ -685,15 +685,8 @@ static int vnt_config(struct ieee80211_hw *hw, u32 changed)
 			priv->bb_type = BB_TYPE_11G;
 	}
 
-	if (changed & IEEE80211_CONF_CHANGE_POWER) {
-		if (priv->bb_type == BB_TYPE_11B)
-			priv->current_rate = RATE_1M;
-		else
-			priv->current_rate = RATE_54M;
-
-		vnt_rf_setpower(priv, priv->current_rate,
-				conf->chandef.chan->hw_value);
-	}
+	if (changed & IEEE80211_CONF_CHANGE_POWER)
+		vnt_rf_setpower(priv, conf->chandef.chan);
 
 	return 0;
 }
@@ -721,10 +714,10 @@ static void vnt_bss_info_changed(struct ieee80211_hw *hw,
 	if (changed & BSS_CHANGED_ERP_PREAMBLE) {
 		if (conf->use_short_preamble) {
 			vnt_mac_enable_barker_preamble_mode(priv);
-			priv->preamble_type = true;
+			priv->preamble_type = PREAMBLE_SHORT;
 		} else {
 			vnt_mac_disable_barker_preamble_mode(priv);
-			priv->preamble_type = false;
+			priv->preamble_type = PREAMBLE_LONG;
 		}
 	}
 
@@ -747,9 +740,8 @@ static void vnt_bss_info_changed(struct ieee80211_hw *hw,
 		vnt_update_pre_ed_threshold(priv, false);
 	}
 
-	if (changed & BSS_CHANGED_TXPOWER)
-		vnt_rf_setpower(priv, priv->current_rate,
-				conf->chandef.chan->hw_value);
+	if (changed & (BSS_CHANGED_TXPOWER | BSS_CHANGED_BANDWIDTH))
+		vnt_rf_setpower(priv, conf->chandef.chan);
 
 	if (changed & BSS_CHANGED_BEACON_ENABLED) {
 		dev_dbg(&priv->usb->dev,
diff --git a/drivers/staging/vt6656/rf.c b/drivers/staging/vt6656/rf.c
index 43237b7e1dbe..a00179bd4c2e 100644
--- a/drivers/staging/vt6656/rf.c
+++ b/drivers/staging/vt6656/rf.c
@@ -27,7 +27,6 @@
 #include "usbpipe.h"
 
 #define CB_AL2230_INIT_SEQ    15
-#define AL2230_PWR_IDX_LEN    64
 
 #define CB_AL7230_INIT_SEQ    16
 #define AL7230_PWR_IDX_LEN    64
@@ -518,74 +517,6 @@ static u8 vt3342_channel_table1[CB_MAX_CHANNEL][3] = {
 	{0x03, 0x00, 0x04}
 };
 
-/* Power Table */
-static const u32 al2230_power_table[AL2230_PWR_IDX_LEN] = {
-	0x04040900,
-	0x04041900,
-	0x04042900,
-	0x04043900,
-	0x04044900,
-	0x04045900,
-	0x04046900,
-	0x04047900,
-	0x04048900,
-	0x04049900,
-	0x0404a900,
-	0x0404b900,
-	0x0404c900,
-	0x0404d900,
-	0x0404e900,
-	0x0404f900,
-	0x04050900,
-	0x04051900,
-	0x04052900,
-	0x04053900,
-	0x04054900,
-	0x04055900,
-	0x04056900,
-	0x04057900,
-	0x04058900,
-	0x04059900,
-	0x0405a900,
-	0x0405b900,
-	0x0405c900,
-	0x0405d900,
-	0x0405e900,
-	0x0405f900,
-	0x04060900,
-	0x04061900,
-	0x04062900,
-	0x04063900,
-	0x04064900,
-	0x04065900,
-	0x04066900,
-	0x04067900,
-	0x04068900,
-	0x04069900,
-	0x0406a900,
-	0x0406b900,
-	0x0406c900,
-	0x0406d900,
-	0x0406e900,
-	0x0406f900,
-	0x04070900,
-	0x04071900,
-	0x04072900,
-	0x04073900,
-	0x04074900,
-	0x04075900,
-	0x04076900,
-	0x04077900,
-	0x04078900,
-	0x04079900,
-	0x0407a900,
-	0x0407b900,
-	0x0407c900,
-	0x0407d900,
-	0x0407e900,
-	0x0407f900
-};
-
 /*
  * Description: Write to IF/RF, by embedded programming
  */
@@ -606,42 +537,6 @@ int vnt_rf_write_embedded(struct vnt_private *priv, u32 data)
 	return true;
 }
 
-/* Set Tx power by rate and channel number */
-int vnt_rf_setpower(struct vnt_private *priv, u32 rate, u32 channel)
-{
-	u8 power = priv->cck_pwr;
-
-	if (channel == 0)
-		return -EINVAL;
-
-	switch (rate) {
-	case RATE_1M:
-	case RATE_2M:
-	case RATE_5M:
-	case RATE_11M:
-		channel--;
-
-		if (channel < sizeof(priv->cck_pwr_tbl))
-			power = priv->cck_pwr_tbl[channel];
-		break;
-	case RATE_6M:
-	case RATE_9M:
-	case RATE_12M:
-	case RATE_18M:
-	case RATE_24M:
-	case RATE_36M:
-	case RATE_48M:
-	case RATE_54M:
-		if (channel > CB_MAX_CHANNEL_24G)
-			power = priv->ofdm_a_pwr_tbl[channel - 15];
-		else
-			power = priv->ofdm_pwr_tbl[channel - 1];
-		break;
-	}
-
-	return vnt_rf_set_txpower(priv, power, rate);
-}
-
 static u8 vnt_rf_addpower(struct vnt_private *priv)
 {
 	s32 rssi = -priv->current_rssi;
@@ -669,7 +564,8 @@ static u8 vnt_rf_addpower(struct vnt_private *priv)
 }
 
 /* Set Tx power by power level and rate */
-int vnt_rf_set_txpower(struct vnt_private *priv, u8 power, u32 rate)
+static int vnt_rf_set_txpower(struct vnt_private *priv, u8 power,
+			      struct ieee80211_channel *ch)
 {
 	u32 power_setting = 0;
 	int ret = true;
@@ -685,23 +581,21 @@ int vnt_rf_set_txpower(struct vnt_private *priv, u8 power, u32 rate)
 
 	switch (priv->rf_type) {
 	case RF_AL2230:
-		if (power >= AL2230_PWR_IDX_LEN)
-			return false;
+		power_setting = 0x0404090 | (power << 12);
 
-		ret &= vnt_rf_write_embedded(priv, al2230_power_table[power]);
+		ret &= vnt_rf_write_embedded(priv, power_setting);
 
-		if (rate <= RATE_11M)
+		if (ch->flags & IEEE80211_CHAN_NO_OFDM)
 			ret &= vnt_rf_write_embedded(priv, 0x0001b400);
 		else
 			ret &= vnt_rf_write_embedded(priv, 0x0005a400);
 		break;
 	case RF_AL2230S:
-		if (power >= AL2230_PWR_IDX_LEN)
-			return false;
+		power_setting = 0x0404090 | (power << 12);
 
-		ret &= vnt_rf_write_embedded(priv, al2230_power_table[power]);
+		ret &= vnt_rf_write_embedded(priv, power_setting);
 
-		if (rate <= RATE_11M) {
+		if (ch->flags & IEEE80211_CHAN_NO_OFDM) {
 			ret &= vnt_rf_write_embedded(priv, 0x040c1400);
 			ret &= vnt_rf_write_embedded(priv, 0x00299b00);
 		} else {
@@ -711,7 +605,7 @@ int vnt_rf_set_txpower(struct vnt_private *priv, u8 power, u32 rate)
 		break;
 
 	case RF_AIROHA7230:
-		if (rate <= RATE_11M)
+		if (ch->flags & IEEE80211_CHAN_NO_OFDM)
 			ret &= vnt_rf_write_embedded(priv, 0x111bb900);
 		else
 			ret &= vnt_rf_write_embedded(priv, 0x221bb900);
@@ -741,8 +635,8 @@ int vnt_rf_set_txpower(struct vnt_private *priv, u8 power, u32 rate)
 		if (power >= VT3226_PWR_IDX_LEN)
 			return false;
 
-		if (rate <= RATE_11M) {
-			u16 hw_value = priv->hw->conf.chandef.chan->hw_value;
+		if (ch->flags & IEEE80211_CHAN_NO_OFDM) {
+			u16 hw_value = ch->hw_value;
 
 			power_setting = ((0x3f - power) << 20) | (0xe07 << 8);
 
@@ -787,6 +681,36 @@ int vnt_rf_set_txpower(struct vnt_private *priv, u8 power, u32 rate)
 	return ret;
 }
 
+/* Set Tx power by channel number type */
+int vnt_rf_setpower(struct vnt_private *priv,
+		    struct ieee80211_channel *ch)
+{
+	u16 channel;
+	u8 power = priv->cck_pwr;
+
+	if (!ch)
+		return -EINVAL;
+
+	/* set channel number to array number */
+	channel = ch->hw_value - 1;
+
+	if (ch->flags & IEEE80211_CHAN_NO_OFDM) {
+		if (channel < ARRAY_SIZE(priv->cck_pwr_tbl))
+			power = priv->cck_pwr_tbl[channel];
+	} else if (ch->band == NL80211_BAND_5GHZ) {
+		/* remove 14 channels to array size */
+		channel -= 14;
+
+		if (channel < ARRAY_SIZE(priv->ofdm_a_pwr_tbl))
+			power = priv->ofdm_a_pwr_tbl[channel];
+	} else {
+		if (channel < ARRAY_SIZE(priv->ofdm_pwr_tbl))
+			power = priv->ofdm_pwr_tbl[channel];
+	}
+
+	return vnt_rf_set_txpower(priv, power, ch);
+}
+
 /* Convert rssi to dbm */
 void vnt_rf_rssi_to_dbm(struct vnt_private *priv, u8 rssi, long *dbm)
 {
diff --git a/drivers/staging/vt6656/rf.h b/drivers/staging/vt6656/rf.h
index 7494546d71b8..493faaf4e2b5 100644
--- a/drivers/staging/vt6656/rf.h
+++ b/drivers/staging/vt6656/rf.h
@@ -41,8 +41,7 @@
 #define	VNT_RF_REG_LEN      0x17 /* 24 bit length */
 
 int vnt_rf_write_embedded(struct vnt_private *priv, u32 data);
-int vnt_rf_setpower(struct vnt_private *priv, u32 rate, u32 channel);
-int vnt_rf_set_txpower(struct vnt_private *priv, u8 power, u32 rate);
+int vnt_rf_setpower(struct vnt_private *priv, struct ieee80211_channel *ch);
 void vnt_rf_rssi_to_dbm(struct vnt_private *priv, u8 rssi, long *dbm);
 int vnt_rf_table_download(struct vnt_private *priv);
 
diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c
index 9439d190f431..8363d54cd821 100644
--- a/drivers/staging/vt6656/rxtx.c
+++ b/drivers/staging/vt6656/rxtx.c
@@ -547,7 +547,7 @@ int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb)
 	struct vnt_tx_fifo_head *tx_buffer_head;
 	struct vnt_usb_send_context *tx_context;
 	unsigned long flags;
-	u16 tx_bytes, tx_header_size, tx_body_size, current_rate, duration_id;
+	u16 tx_bytes, tx_header_size, tx_body_size, duration_id;
 	u8 pkt_type;
 	bool need_rts = false;
 	bool need_mic = false;
@@ -556,14 +556,7 @@ int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb)
 
 	rate = ieee80211_get_tx_rate(priv->hw, info);
 
-	current_rate = rate->hw_value;
-	if (priv->current_rate != current_rate &&
-	    !(priv->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) {
-		priv->current_rate = current_rate;
-		vnt_schedule_command(priv, WLAN_CMD_SETPOWER);
-	}
-
-	if (current_rate > RATE_11M) {
+	if (rate->hw_value > RATE_11M) {
 		if (info->band == NL80211_BAND_5GHZ) {
 			pkt_type = PK_TYPE_11A;
 		} else {
@@ -593,7 +586,7 @@ int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb)
 	tx_context->pkt_type = pkt_type;
 	tx_context->need_ack = false;
 	tx_context->frame_len = skb->len + 4;
-	tx_context->tx_rate = current_rate;
+	tx_context->tx_rate =  rate->hw_value;
 
 	spin_unlock_irqrestore(&priv->lock, flags);
 
@@ -666,7 +659,7 @@ int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb)
 		tx_context->frame_len += tx_key->icv_len;
 	}
 
-	tx_buffer_head->current_rate = cpu_to_le16(current_rate);
+	tx_buffer_head->current_rate = cpu_to_le16(rate->hw_value);
 
 	duration_id = vnt_generate_tx_parameter(tx_context, tx_buffer, &mic_hdr,
 						need_mic, need_rts);
diff --git a/drivers/staging/vt6656/usbpipe.c b/drivers/staging/vt6656/usbpipe.c
index eae211e5860f..91b62c3dff7b 100644
--- a/drivers/staging/vt6656/usbpipe.c
+++ b/drivers/staging/vt6656/usbpipe.c
@@ -207,7 +207,8 @@ static void vnt_int_process_data(struct vnt_private *priv)
 				priv->wake_up_count =
 					priv->hw->conf.listen_interval;
 
-			--priv->wake_up_count;
+			if (priv->wake_up_count)
+				--priv->wake_up_count;
 
 			/* Turn on wake up to listen next beacon */
 			if (priv->wake_up_count == 1)
diff --git a/drivers/staging/vt6656/wcmd.c b/drivers/staging/vt6656/wcmd.c
index 2c5250ca2801..0ccc87da394e 100644
--- a/drivers/staging/vt6656/wcmd.c
+++ b/drivers/staging/vt6656/wcmd.c
@@ -122,8 +122,7 @@ void vnt_run_command(struct work_struct *work)
 
 	case WLAN_CMD_SETPOWER_START:
 
-		vnt_rf_setpower(priv, priv->current_rate,
-				priv->hw->conf.chandef.chan->hw_value);
+		vnt_rf_setpower(priv, priv->hw->conf.chandef.chan);
 
 		break;
 
diff --git a/drivers/staging/wfx/Makefile b/drivers/staging/wfx/Makefile
index 0d9c1ed092f6..0e0cc982ceab 100644
--- a/drivers/staging/wfx/Makefile
+++ b/drivers/staging/wfx/Makefile
@@ -7,6 +7,7 @@ wfx-y := \
 	bh.o \
 	hwio.o \
 	fwio.o \
+	hif_tx_mib.o \
 	hif_tx.o \
 	hif_rx.o \
 	queue.o \
diff --git a/drivers/staging/wfx/bh.c b/drivers/staging/wfx/bh.c
index 9fcab00a3733..ba7fa0a7cd9a 100644
--- a/drivers/staging/wfx/bh.c
+++ b/drivers/staging/wfx/bh.c
@@ -108,8 +108,6 @@ static int rx_helper(struct wfx_dev *wdev, size_t read_len, int *is_cnf)
 			release_count = 1;
 		WARN(wdev->hif.tx_buffers_used < release_count, "corrupted buffer counter");
 		wdev->hif.tx_buffers_used -= release_count;
-		if (!wdev->hif.tx_buffers_used)
-			wake_up(&wdev->hif.tx_buffers_empty);
 	}
 	_trace_hif_recv(hif, wdev->hif.tx_buffers_used);
 
@@ -123,6 +121,8 @@ static int rx_helper(struct wfx_dev *wdev, size_t read_len, int *is_cnf)
 	skb_put(skb, hif->len);
 	// wfx_handle_rx takes care on SKB livetime
 	wfx_handle_rx(wdev, skb);
+	if (!wdev->hif.tx_buffers_used)
+		wake_up(&wdev->hif.tx_buffers_empty);
 
 	return piggyback;
 
diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c
index 42183c70d4df..c30e4f5b6e2d 100644
--- a/drivers/staging/wfx/data_tx.c
+++ b/drivers/staging/wfx/data_tx.c
@@ -6,6 +6,7 @@
  * Copyright (c) 2010, ST-Ericsson
  */
 #include <net/mac80211.h>
+#include <linux/etherdevice.h>
 
 #include "data_tx.h"
 #include "wfx.h"
@@ -16,9 +17,6 @@
 #include "traces.h"
 #include "hif_tx_mib.h"
 
-#define WFX_INVALID_RATE_ID    15
-#define WFX_LINK_ID_GC_TIMEOUT ((unsigned long)(10 * HZ))
-
 static int wfx_get_hw_rate(struct wfx_dev *wdev,
 			   const struct ieee80211_tx_rate *rate)
 {
@@ -51,59 +49,6 @@ static void wfx_tx_policy_build(struct wfx_vif *wvif, struct tx_policy *policy,
 		if (rates[i].idx < 0)
 			break;
 	count = i;
-
-	/* HACK!!! Device has problems (at least) switching from
-	 * 54Mbps CTS to 1Mbps. This switch takes enormous amount
-	 * of time (100-200 ms), leading to valuable throughput drop.
-	 * As a workaround, additional g-rates are injected to the
-	 * policy.
-	 */
-	if (count == 2 && !(rates[0].flags & IEEE80211_TX_RC_MCS) &&
-	    rates[0].idx > 4 && rates[0].count > 2 &&
-	    rates[1].idx < 2) {
-		int mid_rate = (rates[0].idx + 4) >> 1;
-
-		/* Decrease number of retries for the initial rate */
-		rates[0].count -= 2;
-
-		if (mid_rate != 4) {
-			/* Keep fallback rate at 1Mbps. */
-			rates[3] = rates[1];
-
-			/* Inject 1 transmission on lowest g-rate */
-			rates[2].idx = 4;
-			rates[2].count = 1;
-			rates[2].flags = rates[1].flags;
-
-			/* Inject 1 transmission on mid-rate */
-			rates[1].idx = mid_rate;
-			rates[1].count = 1;
-
-			/* Fallback to 1 Mbps is a really bad thing,
-			 * so let's try to increase probability of
-			 * successful transmission on the lowest g rate
-			 * even more
-			 */
-			if (rates[0].count >= 3) {
-				--rates[0].count;
-				++rates[2].count;
-			}
-
-			/* Adjust amount of rates defined */
-			count += 2;
-		} else {
-			/* Keep fallback rate at 1Mbps. */
-			rates[2] = rates[1];
-
-			/* Inject 2 transmissions on lowest g-rate */
-			rates[1].idx = 4;
-			rates[1].count = 2;
-
-			/* Adjust amount of rates defined */
-			count += 1;
-		}
-	}
-
 	for (i = 0; i < IEEE80211_TX_MAX_RATES; ++i) {
 		int rateid;
 		u8 count;
@@ -171,7 +116,7 @@ static int wfx_tx_policy_get(struct wfx_vif *wvif,
 	if (list_empty(&cache->free)) {
 		WARN(1, "unable to get a valid Tx policy");
 		spin_unlock_bh(&cache->lock);
-		return WFX_INVALID_RATE_ID;
+		return HIF_TX_RETRY_POLICY_INVALID;
 	}
 	idx = wfx_tx_policy_find(cache, &wanted);
 	if (idx >= 0) {
@@ -189,10 +134,8 @@ static int wfx_tx_policy_get(struct wfx_vif *wvif,
 		idx = entry - cache->cache;
 	}
 	wfx_tx_policy_use(cache, &cache->cache[idx]);
-	if (list_empty(&cache->free)) {
-		/* Lock TX queues. */
-		wfx_tx_queues_lock(wvif->wdev);
-	}
+	if (list_empty(&cache->free))
+		ieee80211_stop_queues(wvif->wdev->hw);
 	spin_unlock_bh(&cache->lock);
 	return idx;
 }
@@ -202,15 +145,13 @@ static void wfx_tx_policy_put(struct wfx_vif *wvif, int idx)
 	int usage, locked;
 	struct tx_policy_cache *cache = &wvif->tx_policy_cache;
 
-	if (idx == WFX_INVALID_RATE_ID)
+	if (idx == HIF_TX_RETRY_POLICY_INVALID)
 		return;
 	spin_lock_bh(&cache->lock);
 	locked = list_empty(&cache->free);
 	usage = wfx_tx_policy_release(cache, &cache->cache[idx]);
-	if (locked && !usage) {
-		/* Unlock TX queues. */
-		wfx_tx_queues_unlock(wvif->wdev);
-	}
+	if (locked && !usage)
+		ieee80211_wake_queues(wvif->wdev->hw);
 	spin_unlock_bh(&cache->lock);
 }
 
@@ -222,11 +163,11 @@ static int wfx_tx_policy_upload(struct wfx_vif *wvif)
 
 	do {
 		spin_lock_bh(&wvif->tx_policy_cache.lock);
-		for (i = 0; i < HIF_MIB_NUM_TX_RATE_RETRY_POLICIES; ++i)
+		for (i = 0; i < HIF_TX_RETRY_POLICY_MAX; ++i)
 			if (!policies[i].uploaded &&
 			    memzcmp(policies[i].rates, sizeof(policies[i].rates)))
 				break;
-		if (i < HIF_MIB_NUM_TX_RATE_RETRY_POLICIES) {
+		if (i < HIF_TX_RETRY_POLICY_MAX) {
 			policies[i].uploaded = true;
 			memcpy(tmp_rates, policies[i].rates, sizeof(tmp_rates));
 			spin_unlock_bh(&wvif->tx_policy_cache.lock);
@@ -234,7 +175,7 @@ static int wfx_tx_policy_upload(struct wfx_vif *wvif)
 		} else {
 			spin_unlock_bh(&wvif->tx_policy_cache.lock);
 		}
-	} while (i < HIF_MIB_NUM_TX_RATE_RETRY_POLICIES);
+	} while (i < HIF_TX_RETRY_POLICY_MAX);
 	return 0;
 }
 
@@ -244,9 +185,7 @@ void wfx_tx_policy_upload_work(struct work_struct *work)
 		container_of(work, struct wfx_vif, tx_policy_upload_work);
 
 	wfx_tx_policy_upload(wvif);
-
 	wfx_tx_unlock(wvif->wdev);
-	wfx_tx_queues_unlock(wvif->wdev);
 }
 
 void wfx_tx_policy_init(struct wfx_vif *wvif)
@@ -260,7 +199,7 @@ void wfx_tx_policy_init(struct wfx_vif *wvif)
 	INIT_LIST_HEAD(&cache->used);
 	INIT_LIST_HEAD(&cache->free);
 
-	for (i = 0; i < HIF_MIB_NUM_TX_RATE_RETRY_POLICIES; ++i)
+	for (i = 0; i < HIF_TX_RETRY_POLICY_MAX; ++i)
 		list_add(&cache->cache[i].link, &cache->free);
 }
 
@@ -281,15 +220,9 @@ static void wfx_tx_manage_pm(struct wfx_vif *wvif, struct ieee80211_hdr *hdr,
 			     struct wfx_tx_priv *tx_priv,
 			     struct ieee80211_sta *sta)
 {
-	u32 mask = ~BIT(tx_priv->raw_link_id);
 	struct wfx_sta_priv *sta_priv;
 	int tid = ieee80211_get_tid(hdr);
 
-	spin_lock_bh(&wvif->ps_state_lock);
-	if (ieee80211_is_auth(hdr->frame_control))
-		wvif->sta_asleep_mask &= mask;
-	spin_unlock_bh(&wvif->ps_state_lock);
-
 	if (sta) {
 		sta_priv = (struct wfx_sta_priv *)&sta->drv_priv;
 		spin_lock_bh(&sta_priv->lock);
@@ -299,9 +232,8 @@ static void wfx_tx_manage_pm(struct wfx_vif *wvif, struct ieee80211_hdr *hdr,
 	}
 }
 
-static u8 wfx_tx_get_raw_link_id(struct wfx_vif *wvif,
-				 struct ieee80211_sta *sta,
-				 struct ieee80211_hdr *hdr)
+static u8 wfx_tx_get_link_id(struct wfx_vif *wvif, struct ieee80211_sta *sta,
+			     struct ieee80211_hdr *hdr)
 {
 	struct wfx_sta_priv *sta_priv =
 		sta ? (struct wfx_sta_priv *)&sta->drv_priv : NULL;
@@ -313,7 +245,7 @@ static u8 wfx_tx_get_raw_link_id(struct wfx_vif *wvif,
 		return 0;
 	if (is_multicast_ether_addr(da))
 		return 0;
-	return WFX_LINK_ID_NO_ASSOC;
+	return HIF_LINK_ID_NOT_ASSOCIATED;
 }
 
 static void wfx_tx_fixup_rates(struct ieee80211_tx_rate *rates)
@@ -375,19 +307,13 @@ static u8 wfx_tx_get_rate_id(struct wfx_vif *wvif,
 
 	rate_id = wfx_tx_policy_get(wvif,
 				    tx_info->driver_rates, &tx_policy_renew);
-	if (rate_id == WFX_INVALID_RATE_ID)
+	if (rate_id == HIF_TX_RETRY_POLICY_INVALID)
 		dev_warn(wvif->wdev->dev, "unable to get a valid Tx policy");
 
 	if (tx_policy_renew) {
-		/* FIXME: It's not so optimal to stop TX queues every now and
-		 * then.  Better to reimplement task scheduling with a counter.
-		 */
 		wfx_tx_lock(wvif->wdev);
-		wfx_tx_queues_lock(wvif->wdev);
-		if (!schedule_work(&wvif->tx_policy_upload_work)) {
-			wfx_tx_queues_unlock(wvif->wdev);
+		if (!schedule_work(&wvif->tx_policy_upload_work))
 			wfx_tx_unlock(wvif->wdev);
-		}
 	}
 	return rate_id;
 }
@@ -429,7 +355,7 @@ static int wfx_tx_inner(struct wfx_vif *wvif, struct ieee80211_sta *sta,
 	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
 	struct ieee80211_key_conf *hw_key = tx_info->control.hw_key;
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-	int queue_id = tx_info->hw_queue;
+	int queue_id = skb_get_queue_mapping(skb);
 	size_t offset = (size_t)skb->data & 3;
 	int wmsg_len = sizeof(struct hif_msg) +
 			sizeof(struct hif_req_tx) + offset;
@@ -441,14 +367,8 @@ static int wfx_tx_inner(struct wfx_vif *wvif, struct ieee80211_sta *sta,
 	memset(tx_info->rate_driver_data, 0, sizeof(struct wfx_tx_priv));
 	// Fill tx_priv
 	tx_priv = (struct wfx_tx_priv *)tx_info->rate_driver_data;
-	tx_priv->raw_link_id = wfx_tx_get_raw_link_id(wvif, sta, hdr);
-	tx_priv->link_id = tx_priv->raw_link_id;
 	if (ieee80211_has_protected(hdr->frame_control))
 		tx_priv->hw_key = hw_key;
-	if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM)
-		tx_priv->link_id = WFX_LINK_ID_AFTER_DTIM;
-	if (sta && (sta->uapsd_queues & BIT(queue_id)))
-		tx_priv->link_id = WFX_LINK_ID_UAPSD;
 
 	// Fill hif_msg
 	WARN(skb_headroom(skb) < wmsg_len, "not enough space in skb");
@@ -478,7 +398,7 @@ static int wfx_tx_inner(struct wfx_vif *wvif, struct ieee80211_sta *sta,
 	req->data_flags.fc_offset = offset;
 	if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM)
 		req->data_flags.after_dtim = 1;
-	req->queue_id.peer_sta_id = tx_priv->raw_link_id;
+	req->queue_id.peer_sta_id = wfx_tx_get_link_id(wvif, sta, hdr);
 	// Queue index are inverted between firmware and Linux
 	req->queue_id.queue_id = 3 - queue_id;
 	req->ht_tx_parameters = wfx_tx_get_tx_parms(wvif->wdev, tx_info);
@@ -486,7 +406,7 @@ static int wfx_tx_inner(struct wfx_vif *wvif, struct ieee80211_sta *sta,
 
 	// Auxiliary operations
 	wfx_tx_manage_pm(wvif, hdr, tx_priv, sta);
-	wfx_tx_queue_put(wvif->wdev, &wvif->wdev->tx_queue[queue_id], skb);
+	wfx_tx_queues_put(wvif->wdev, skb);
 	if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM)
 		schedule_work(&wvif->update_tim_work);
 	wfx_bh_request_tx(wvif->wdev);
@@ -528,6 +448,43 @@ void wfx_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
 	ieee80211_tx_status_irqsafe(wdev->hw, skb);
 }
 
+static void wfx_notify_buffered_tx(struct wfx_vif *wvif, struct sk_buff *skb)
+{
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+	struct ieee80211_sta *sta;
+	struct wfx_sta_priv *sta_priv;
+	int tid = ieee80211_get_tid(hdr);
+
+	rcu_read_lock(); // protect sta
+	sta = ieee80211_find_sta(wvif->vif, hdr->addr1);
+	if (sta) {
+		sta_priv = (struct wfx_sta_priv *)&sta->drv_priv;
+		spin_lock_bh(&sta_priv->lock);
+		WARN(!sta_priv->buffered[tid], "inconsistent notification");
+		sta_priv->buffered[tid]--;
+		if (!sta_priv->buffered[tid])
+			ieee80211_sta_set_buffered(sta, tid, false);
+		spin_unlock_bh(&sta_priv->lock);
+	}
+	rcu_read_unlock();
+}
+
+static void wfx_skb_dtor(struct wfx_dev *wdev, struct sk_buff *skb)
+{
+	struct hif_msg *hif = (struct hif_msg *)skb->data;
+	struct hif_req_tx *req = (struct hif_req_tx *)hif->body;
+	struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface);
+	unsigned int offset = sizeof(struct hif_req_tx) +
+				sizeof(struct hif_msg) +
+				req->data_flags.fc_offset;
+
+	WARN_ON(!wvif);
+	skb_pull(skb, offset);
+	wfx_notify_buffered_tx(wvif, skb);
+	wfx_tx_policy_put(wvif, req->tx_flags.retry_policy_index);
+	ieee80211_tx_status_irqsafe(wdev->hw, skb);
+}
+
 void wfx_tx_confirm_cb(struct wfx_vif *wvif, const struct hif_cnf_tx *arg)
 {
 	int i;
@@ -611,42 +568,39 @@ void wfx_tx_confirm_cb(struct wfx_vif *wvif, const struct hif_cnf_tx *arg)
 		    arg->packet_id == wvif->bss_loss_confirm_id)
 			wfx_cqm_bssloss_sm(wvif, 0, 0, 1);
 	}
-	wfx_pending_remove(wvif->wdev, skb);
+	wfx_skb_dtor(wvif->wdev, skb);
 }
 
-static void wfx_notify_buffered_tx(struct wfx_vif *wvif, struct sk_buff *skb)
+void wfx_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+	       u32 queues, bool drop)
 {
-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-	struct ieee80211_sta *sta;
-	struct wfx_sta_priv *sta_priv;
-	int tid = ieee80211_get_tid(hdr);
+	struct wfx_dev *wdev = hw->priv;
+	struct sk_buff_head dropped;
+	struct wfx_queue *queue;
+	struct sk_buff *skb;
+	int vif_id = -1;
+	int i;
 
-	rcu_read_lock(); // protect sta
-	sta = ieee80211_find_sta(wvif->vif, hdr->addr1);
-	if (sta) {
-		sta_priv = (struct wfx_sta_priv *)&sta->drv_priv;
-		spin_lock_bh(&sta_priv->lock);
-		WARN(!sta_priv->buffered[tid], "inconsistent notification");
-		sta_priv->buffered[tid]--;
-		if (!sta_priv->buffered[tid])
-			ieee80211_sta_set_buffered(sta, tid, false);
-		spin_unlock_bh(&sta_priv->lock);
+	if (vif)
+		vif_id = ((struct wfx_vif *)vif->drv_priv)->id;
+	skb_queue_head_init(&dropped);
+	for (i = 0; i < IEEE80211_NUM_ACS; i++) {
+		if (!(BIT(i) & queues))
+			continue;
+		queue = &wdev->tx_queue[i];
+		if (drop)
+			wfx_tx_queue_drop(wdev, queue, vif_id, &dropped);
+		if (wdev->chip_frozen)
+			continue;
+		if (wait_event_timeout(wdev->tx_dequeue,
+				       wfx_tx_queue_empty(wdev, queue, vif_id),
+				       msecs_to_jiffies(1000)) <= 0)
+			dev_warn(wdev->dev, "frames queued while flushing tx queues?");
 	}
-	rcu_read_unlock();
+	wfx_tx_flush(wdev);
+	if (wdev->chip_frozen)
+		wfx_pending_drop(wdev, &dropped);
+	while ((skb = skb_dequeue(&dropped)) != NULL)
+		wfx_skb_dtor(wdev, skb);
 }
 
-void wfx_skb_dtor(struct wfx_dev *wdev, struct sk_buff *skb)
-{
-	struct hif_msg *hif = (struct hif_msg *)skb->data;
-	struct hif_req_tx *req = (struct hif_req_tx *)hif->body;
-	struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface);
-	unsigned int offset = sizeof(struct hif_req_tx) +
-				sizeof(struct hif_msg) +
-				req->data_flags.fc_offset;
-
-	WARN_ON(!wvif);
-	skb_pull(skb, offset);
-	wfx_notify_buffered_tx(wvif, skb);
-	wfx_tx_policy_put(wvif, req->tx_flags.retry_policy_index);
-	ieee80211_tx_status_irqsafe(wdev->hw, skb);
-}
diff --git a/drivers/staging/wfx/data_tx.h b/drivers/staging/wfx/data_tx.h
index c545dd75449b..a308af3d68ad 100644
--- a/drivers/staging/wfx/data_tx.h
+++ b/drivers/staging/wfx/data_tx.h
@@ -26,7 +26,7 @@ struct tx_policy {
 };
 
 struct tx_policy_cache {
-	struct tx_policy cache[HIF_MIB_NUM_TX_RATE_RETRY_POLICIES];
+	struct tx_policy cache[HIF_TX_RETRY_POLICY_MAX];
 	// FIXME: use a trees and drop hash from tx_policy
 	struct list_head used;
 	struct list_head free;
@@ -36,8 +36,6 @@ struct tx_policy_cache {
 struct wfx_tx_priv {
 	ktime_t xmit_timestamp;
 	struct ieee80211_key_conf *hw_key;
-	u8 link_id;
-	u8 raw_link_id;
 } __packed;
 
 void wfx_tx_policy_init(struct wfx_vif *wvif);
@@ -46,7 +44,8 @@ void wfx_tx_policy_upload_work(struct work_struct *work);
 void wfx_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
 	    struct sk_buff *skb);
 void wfx_tx_confirm_cb(struct wfx_vif *wvif, const struct hif_cnf_tx *arg);
-void wfx_skb_dtor(struct wfx_dev *wdev, struct sk_buff *skb);
+void wfx_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+	       u32 queues, bool drop);
 
 static inline struct wfx_tx_priv *wfx_skb_tx_priv(struct sk_buff *skb)
 {
diff --git a/drivers/staging/wfx/hif_api_cmd.h b/drivers/staging/wfx/hif_api_cmd.h
index 071b71e2a107..6f70801949bb 100644
--- a/drivers/staging/wfx/hif_api_cmd.h
+++ b/drivers/staging/wfx/hif_api_cmd.h
@@ -10,56 +10,54 @@
 
 #include "hif_api_general.h"
 
-#define HIF_NUM_AC                             4
-
 #define HIF_API_SSID_SIZE                      API_SSID_SIZE
 
 enum hif_requests_ids {
-	HIF_REQ_ID_RESET                             = 0x0a,
-	HIF_REQ_ID_READ_MIB                          = 0x05,
-	HIF_REQ_ID_WRITE_MIB                         = 0x06,
-	HIF_REQ_ID_START_SCAN                        = 0x07,
-	HIF_REQ_ID_STOP_SCAN                         = 0x08,
-	HIF_REQ_ID_TX                                = 0x04,
-	HIF_REQ_ID_JOIN                              = 0x0b,
-	HIF_REQ_ID_SET_PM_MODE                       = 0x10,
-	HIF_REQ_ID_SET_BSS_PARAMS                    = 0x11,
-	HIF_REQ_ID_ADD_KEY                           = 0x0c,
-	HIF_REQ_ID_REMOVE_KEY                        = 0x0d,
-	HIF_REQ_ID_EDCA_QUEUE_PARAMS                 = 0x13,
-	HIF_REQ_ID_START                             = 0x17,
-	HIF_REQ_ID_BEACON_TRANSMIT                   = 0x18,
-	HIF_REQ_ID_UPDATE_IE                         = 0x1b,
-	HIF_REQ_ID_MAP_LINK                          = 0x1c,
+	HIF_REQ_ID_RESET                = 0x0a,
+	HIF_REQ_ID_READ_MIB             = 0x05,
+	HIF_REQ_ID_WRITE_MIB            = 0x06,
+	HIF_REQ_ID_START_SCAN           = 0x07,
+	HIF_REQ_ID_STOP_SCAN            = 0x08,
+	HIF_REQ_ID_TX                   = 0x04,
+	HIF_REQ_ID_JOIN                 = 0x0b,
+	HIF_REQ_ID_SET_PM_MODE          = 0x10,
+	HIF_REQ_ID_SET_BSS_PARAMS       = 0x11,
+	HIF_REQ_ID_ADD_KEY              = 0x0c,
+	HIF_REQ_ID_REMOVE_KEY           = 0x0d,
+	HIF_REQ_ID_EDCA_QUEUE_PARAMS    = 0x13,
+	HIF_REQ_ID_START                = 0x17,
+	HIF_REQ_ID_BEACON_TRANSMIT      = 0x18,
+	HIF_REQ_ID_UPDATE_IE            = 0x1b,
+	HIF_REQ_ID_MAP_LINK             = 0x1c,
 };
 
 enum hif_confirmations_ids {
-	HIF_CNF_ID_RESET                             = 0x0a,
-	HIF_CNF_ID_READ_MIB                          = 0x05,
-	HIF_CNF_ID_WRITE_MIB                         = 0x06,
-	HIF_CNF_ID_START_SCAN                        = 0x07,
-	HIF_CNF_ID_STOP_SCAN                         = 0x08,
-	HIF_CNF_ID_TX                                = 0x04,
-	HIF_CNF_ID_MULTI_TRANSMIT                    = 0x1e,
-	HIF_CNF_ID_JOIN                              = 0x0b,
-	HIF_CNF_ID_SET_PM_MODE                       = 0x10,
-	HIF_CNF_ID_SET_BSS_PARAMS                    = 0x11,
-	HIF_CNF_ID_ADD_KEY                           = 0x0c,
-	HIF_CNF_ID_REMOVE_KEY                        = 0x0d,
-	HIF_CNF_ID_EDCA_QUEUE_PARAMS                 = 0x13,
-	HIF_CNF_ID_START                             = 0x17,
-	HIF_CNF_ID_BEACON_TRANSMIT                   = 0x18,
-	HIF_CNF_ID_UPDATE_IE                         = 0x1b,
-	HIF_CNF_ID_MAP_LINK                          = 0x1c,
+	HIF_CNF_ID_RESET                = 0x0a,
+	HIF_CNF_ID_READ_MIB             = 0x05,
+	HIF_CNF_ID_WRITE_MIB            = 0x06,
+	HIF_CNF_ID_START_SCAN           = 0x07,
+	HIF_CNF_ID_STOP_SCAN            = 0x08,
+	HIF_CNF_ID_TX                   = 0x04,
+	HIF_CNF_ID_MULTI_TRANSMIT       = 0x1e,
+	HIF_CNF_ID_JOIN                 = 0x0b,
+	HIF_CNF_ID_SET_PM_MODE          = 0x10,
+	HIF_CNF_ID_SET_BSS_PARAMS       = 0x11,
+	HIF_CNF_ID_ADD_KEY              = 0x0c,
+	HIF_CNF_ID_REMOVE_KEY           = 0x0d,
+	HIF_CNF_ID_EDCA_QUEUE_PARAMS    = 0x13,
+	HIF_CNF_ID_START                = 0x17,
+	HIF_CNF_ID_BEACON_TRANSMIT      = 0x18,
+	HIF_CNF_ID_UPDATE_IE            = 0x1b,
+	HIF_CNF_ID_MAP_LINK             = 0x1c,
 };
 
 enum hif_indications_ids {
-	HIF_IND_ID_RX                                = 0x84,
-	HIF_IND_ID_SCAN_CMPL                         = 0x86,
-	HIF_IND_ID_JOIN_COMPLETE                     = 0x8f,
-	HIF_IND_ID_SET_PM_MODE_CMPL                  = 0x89,
-	HIF_IND_ID_SUSPEND_RESUME_TX                 = 0x8c,
-	HIF_IND_ID_EVENT                             = 0x85
+	HIF_IND_ID_RX                   = 0x84,
+	HIF_IND_ID_SCAN_CMPL            = 0x86,
+	HIF_IND_ID_JOIN_COMPLETE        = 0x8f,
+	HIF_IND_ID_SET_PM_MODE_CMPL     = 0x89,
+	HIF_IND_ID_SUSPEND_RESUME_TX    = 0x8c,
+	HIF_IND_ID_EVENT                = 0x85
 };
 
 union hif_commands_ids {
@@ -69,26 +67,26 @@ union hif_commands_ids {
 };
 
 enum hif_status {
-	HIF_STATUS_SUCCESS                         = 0x0,
-	HIF_STATUS_FAILURE                         = 0x1,
-	HIF_INVALID_PARAMETER                      = 0x2,
-	HIF_STATUS_WARNING                         = 0x3,
-	HIF_ERROR_UNSUPPORTED_MSG_ID               = 0x4,
-	HIF_STATUS_DECRYPTFAILURE                  = 0x10,
-	HIF_STATUS_MICFAILURE                      = 0x11,
-	HIF_STATUS_NO_KEY_FOUND                    = 0x12,
-	HIF_STATUS_RETRY_EXCEEDED                  = 0x13,
-	HIF_STATUS_TX_LIFETIME_EXCEEDED            = 0x14,
-	HIF_REQUEUE                                = 0x15,
-	HIF_STATUS_REFUSED                         = 0x16,
-	HIF_STATUS_BUSY                            = 0x17
+	HIF_STATUS_SUCCESS              = 0x0,
+	HIF_STATUS_FAILURE              = 0x1,
+	HIF_INVALID_PARAMETER           = 0x2,
+	HIF_STATUS_WARNING              = 0x3,
+	HIF_ERROR_UNSUPPORTED_MSG_ID    = 0x4,
+	HIF_STATUS_DECRYPTFAILURE       = 0x10,
+	HIF_STATUS_MICFAILURE           = 0x11,
+	HIF_STATUS_NO_KEY_FOUND         = 0x12,
+	HIF_STATUS_RETRY_EXCEEDED       = 0x13,
+	HIF_STATUS_TX_LIFETIME_EXCEEDED = 0x14,
+	HIF_REQUEUE                     = 0x15,
+	HIF_STATUS_REFUSED              = 0x16,
+	HIF_STATUS_BUSY                 = 0x17
 };
 
 struct hif_reset_flags {
-	u8    reset_stat:1;
-	u8    reset_all_int:1;
-	u8    reserved1:6;
-	u8    reserved2[3];
+	u8     reset_stat:1;
+	u8     reset_all_int:1;
+	u8     reserved1:6;
+	u8     reserved2[3];
 } __packed;
 
 struct hif_req_reset {
@@ -96,117 +94,101 @@ struct hif_req_reset {
 } __packed;
 
 struct hif_req_read_mib {
-	u16   mib_id;
-	u16   reserved;
+	__le16 mib_id;
+	__le16 reserved;
 } __packed;
 
 struct hif_cnf_read_mib {
-	u32   status;
-	u16   mib_id;
-	u16   length;
-	u8    mib_data[];
+	__le32 status;
+	__le16 mib_id;
+	__le16 length;
+	u8     mib_data[];
 } __packed;
 
 struct hif_req_write_mib {
-	u16   mib_id;
-	u16   length;
-	u8    mib_data[];
+	__le16 mib_id;
+	__le16 length;
+	u8     mib_data[];
 } __packed;
 
 struct hif_cnf_write_mib {
-	u32   status;
+	__le32 status;
 } __packed;
 
 struct hif_ie_flags {
-	u8    beacon:1;
-	u8    probe_resp:1;
-	u8    probe_req:1;
-	u8    reserved1:5;
-	u8    reserved2;
+	u8     beacon:1;
+	u8     probe_resp:1;
+	u8     probe_req:1;
+	u8     reserved1:5;
+	u8     reserved2;
 } __packed;
 
 struct hif_ie_tlv {
-	u8    type;
-	u8    length;
-	u8    data[];
+	u8     type;
+	u8     length;
+	u8     data[];
 } __packed;
 
 struct hif_req_update_ie {
 	struct hif_ie_flags ie_flags;
-	u16   num_ies;
+	__le16 num_ies;
 	struct hif_ie_tlv ie[];
 } __packed;
 
 struct hif_cnf_update_ie {
-	u32   status;
+	__le32 status;
 } __packed;
 
 struct hif_scan_type {
-	u8    type:1;
-	u8    mode:1;
-	u8    reserved:6;
+	u8     type:1;
+	u8     mode:1;
+	u8     reserved:6;
 } __packed;
 
 struct hif_scan_flags {
-	u8    fbg:1;
-	u8    reserved1:1;
-	u8    pre:1;
-	u8    reserved2:5;
+	u8     fbg:1;
+	u8     reserved1:1;
+	u8     pre:1;
+	u8     reserved2:5;
 } __packed;
 
 struct hif_auto_scan_param {
-	u16   interval;
-	u8    reserved;
+	__le16 interval;
+	u8     reserved;
 	s8     rssi_thr;
 } __packed;
 
 struct hif_ssid_def {
-	u32   ssid_length;
-	u8    ssid[HIF_API_SSID_SIZE];
+	__le32 ssid_length;
+	u8     ssid[HIF_API_SSID_SIZE];
 } __packed;
 
 #define HIF_API_MAX_NB_SSIDS                           2
 #define HIF_API_MAX_NB_CHANNELS                       14
 
-struct hif_req_start_scan {
-	u8    band;
-	struct hif_scan_type scan_type;
-	struct hif_scan_flags scan_flags;
-	u8    max_transmit_rate;
-	struct hif_auto_scan_param auto_scan_param;
-	u8    num_of_probe_requests;
-	u8    probe_delay;
-	u8    num_of_ssids;
-	u8    num_of_channels;
-	u32   min_channel_time;
-	u32   max_channel_time;
-	s32    tx_power_level;
-	u8    ssid_and_channel_lists[];
-} __packed;
-
 struct hif_req_start_scan_alt {
-	u8    band;
+	u8     band;
 	struct hif_scan_type scan_type;
 	struct hif_scan_flags scan_flags;
-	u8    max_transmit_rate;
+	u8     max_transmit_rate;
 	struct hif_auto_scan_param auto_scan_param;
-	u8    num_of_probe_requests;
-	u8    probe_delay;
-	u8    num_of_ssids;
-	u8    num_of_channels;
-	u32   min_channel_time;
-	u32   max_channel_time;
-	s32    tx_power_level;
+	u8     num_of_probe_requests;
+	u8     probe_delay;
+	u8     num_of_ssids;
+	u8     num_of_channels;
+	__le32 min_channel_time;
+	__le32 max_channel_time;
+	__le32 tx_power_level; // signed value
 	struct hif_ssid_def ssid_def[HIF_API_MAX_NB_SSIDS];
-	u8    channel_list[];
+	u8     channel_list[];
 } __packed;
 
 struct hif_cnf_start_scan {
-	u32   status;
+	__le32 status;
 } __packed;
 
 struct hif_cnf_stop_scan {
-	u32   status;
+	__le32 status;
 } __packed;
 
 enum hif_pm_mode_status {
@@ -216,10 +198,10 @@ enum hif_pm_mode_status {
 };
 
 struct hif_ind_scan_cmpl {
-	u32   status;
-	u8    pm_mode;
-	u8    num_channels_completed;
-	u16   reserved;
+	__le32 status;
+	u8     pm_mode;
+	u8     num_channels_completed;
+	__le16 reserved;
 } __packed;
 
 enum hif_queue_id {
@@ -241,46 +223,46 @@ enum hif_stbc {
 };
 
 struct hif_queue {
-	u8    queue_id:2;
-	u8    peer_sta_id:4;
-	u8    reserved:2;
+	u8     queue_id:2;
+	u8     peer_sta_id:4;
+	u8     reserved:2;
 } __packed;
 
 struct hif_data_flags {
-	u8    more:1;
-	u8    fc_offset:3;
-	u8    after_dtim:1;
-	u8    reserved:3;
+	u8     more:1;
+	u8     fc_offset:3;
+	u8     after_dtim:1;
+	u8     reserved:3;
 } __packed;
 
 struct hif_tx_flags {
-	u8    start_exp:1;
-	u8    reserved:3;
-	u8    retry_policy_index:4;
+	u8     start_exp:1;
+	u8     reserved:3;
+	u8     retry_policy_index:4;
 } __packed;
 
 struct hif_ht_tx_parameters {
-	u8    frame_format:4;
-	u8    fec_coding:1;
-	u8    short_gi:1;
-	u8    reserved1:1;
-	u8    stbc:1;
-	u8    reserved2;
-	u8    aggregation:1;
-	u8    reserved3:7;
-	u8    reserved4;
+	u8     frame_format:4;
+	u8     fec_coding:1;
+	u8     short_gi:1;
+	u8     reserved1:1;
+	u8     stbc:1;
+	u8     reserved2;
+	u8     aggregation:1;
+	u8     reserved3:7;
+	u8     reserved4;
 } __packed;
 
 struct hif_req_tx {
-	u32   packet_id;
-	u8    max_tx_rate;
+	__le32 packet_id;
+	u8     max_tx_rate;
 	struct hif_queue queue_id;
 	struct hif_data_flags data_flags;
 	struct hif_tx_flags tx_flags;
-	u32   reserved;
-	u32   expire_time;
+	__le32 reserved;
+	__le32 expire_time;
 	struct hif_ht_tx_parameters ht_tx_parameters;
-	u8    frame[];
+	u8     frame[];
 } __packed;
 
 enum hif_qos_ackplcy {
@@ -291,26 +273,26 @@ enum hif_qos_ackplcy {
 };
 
 struct hif_tx_result_flags {
-	u8    aggr:1;
-	u8    requeue:1;
-	u8    ack_policy:2;
-	u8    txop_limit:1;
-	u8    reserved1:3;
-	u8    reserved2;
+	u8     aggr:1;
+	u8     requeue:1;
+	u8     ack_policy:2;
+	u8     txop_limit:1;
+	u8     reserved1:3;
+	u8     reserved2;
 } __packed;
 
 struct hif_cnf_tx {
-	u32   status;
-	u32   packet_id;
-	u8    txed_rate;
-	u8    ack_failures;
+	__le32 status;
+	__le32 packet_id;
+	u8     txed_rate;
+	u8     ack_failures;
 	struct hif_tx_result_flags tx_result_flags;
-	u32   media_delay;
-	u32   tx_queue_delay;
+	__le32 media_delay;
+	__le32 tx_queue_delay;
 } __packed;
 
 struct hif_cnf_multi_transmit {
-	u32   num_tx_confs;
+	__le32 num_tx_confs;
 	struct hif_cnf_tx   tx_conf_payload[];
 } __packed;
 
@@ -323,147 +305,147 @@ enum hif_ri_flags_encrypt {
 };
 
 struct hif_rx_flags {
-	u8    encryp:3;
-	u8    in_aggr:1;
-	u8    first_aggr:1;
-	u8    last_aggr:1;
-	u8    defrag:1;
-	u8    beacon:1;
-	u8    tim:1;
-	u8    bitmap:1;
-	u8    match_ssid:1;
-	u8    match_bssid:1;
-	u8    more:1;
-	u8    reserved1:1;
-	u8    ht:1;
-	u8    stbc:1;
-	u8    match_uc_addr:1;
-	u8    match_mc_addr:1;
-	u8    match_bc_addr:1;
-	u8    key_type:1;
-	u8    key_index:4;
-	u8    reserved2:1;
-	u8    peer_sta_id:4;
-	u8    reserved3:2;
-	u8    reserved4:1;
+	u8     encryp:3;
+	u8     in_aggr:1;
+	u8     first_aggr:1;
+	u8     last_aggr:1;
+	u8     defrag:1;
+	u8     beacon:1;
+	u8     tim:1;
+	u8     bitmap:1;
+	u8     match_ssid:1;
+	u8     match_bssid:1;
+	u8     more:1;
+	u8     reserved1:1;
+	u8     ht:1;
+	u8     stbc:1;
+	u8     match_uc_addr:1;
+	u8     match_mc_addr:1;
+	u8     match_bc_addr:1;
+	u8     key_type:1;
+	u8     key_index:4;
+	u8     reserved2:1;
+	u8     peer_sta_id:4;
+	u8     reserved3:2;
+	u8     reserved4:1;
 } __packed;
 
 struct hif_ind_rx {
-	u32   status;
-	u16   channel_number;
-	u8    rxed_rate;
-	u8    rcpi_rssi;
+	__le32 status;
+	__le16 channel_number;
+	u8     rxed_rate;
+	u8     rcpi_rssi;
 	struct hif_rx_flags rx_flags;
-	u8    frame[];
+	u8     frame[];
 } __packed;
 
 
 struct hif_req_edca_queue_params {
-	u8    queue_id;
-	u8    reserved1;
-	u8    aifsn;
-	u8    reserved2;
-	u16   cw_min;
-	u16   cw_max;
-	u16   tx_op_limit;
-	u16   allowed_medium_time;
-	u32   reserved3;
+	u8     queue_id;
+	u8     reserved1;
+	u8     aifsn;
+	u8     reserved2;
+	__le16 cw_min;
+	__le16 cw_max;
+	__le16 tx_op_limit;
+	__le16 allowed_medium_time;
+	__le32 reserved3;
 } __packed;
 
 struct hif_cnf_edca_queue_params {
-	u32   status;
+	__le32 status;
 } __packed;
 
 struct hif_join_flags {
-	u8    reserved1:2;
-	u8    force_no_beacon:1;
-	u8    force_with_ind:1;
-	u8    reserved2:4;
+	u8     reserved1:2;
+	u8     force_no_beacon:1;
+	u8     force_with_ind:1;
+	u8     reserved2:4;
 } __packed;
 
 struct hif_req_join {
-	u8    infrastructure_bss_mode:1;
-	u8    reserved1:7;
-	u8    band;
-	u16   channel_number;
-	u8    bssid[ETH_ALEN];
-	u16   atim_window;
-	u8    short_preamble:1;
-	u8    reserved2:7;
-	u8    probe_for_join;
-	u8    reserved3;
+	u8     infrastructure_bss_mode:1;
+	u8     reserved1:7;
+	u8     band;
+	__le16 channel_number;
+	u8     bssid[ETH_ALEN];
+	__le16 atim_window;
+	u8     short_preamble:1;
+	u8     reserved2:7;
+	u8     probe_for_join;
+	u8     reserved3;
 	struct hif_join_flags join_flags;
-	u32   ssid_length;
-	u8    ssid[HIF_API_SSID_SIZE];
-	u32   beacon_interval;
-	u32   basic_rate_set;
+	__le32 ssid_length;
+	u8     ssid[HIF_API_SSID_SIZE];
+	__le32 beacon_interval;
+	__le32 basic_rate_set;
 } __packed;
 
 struct hif_cnf_join {
-	u32   status;
+	__le32 status;
 } __packed;
 
 struct hif_ind_join_complete {
-	u32   status;
+	__le32 status;
 } __packed;
 
 struct hif_bss_flags {
-	u8    lost_count_only:1;
-	u8    reserved:7;
+	u8     lost_count_only:1;
+	u8     reserved:7;
 } __packed;
 
 struct hif_req_set_bss_params {
 	struct hif_bss_flags bss_flags;
-	u8    beacon_lost_count;
-	u16   aid;
-	u32   operational_rate_set;
+	u8     beacon_lost_count;
+	__le16 aid;
+	__le32 operational_rate_set;
 } __packed;
 
 struct hif_cnf_set_bss_params {
-	u32   status;
+	__le32 status;
 } __packed;
 
 struct hif_pm_mode {
-	u8    enter_psm:1;
-	u8    reserved:6;
-	u8    fast_psm:1;
+	u8     enter_psm:1;
+	u8     reserved:6;
+	u8     fast_psm:1;
 } __packed;
 
 struct hif_req_set_pm_mode {
 	struct hif_pm_mode pm_mode;
-	u8    fast_psm_idle_period;
-	u8    ap_psm_change_period;
-	u8    min_auto_ps_poll_period;
+	u8     fast_psm_idle_period;
+	u8     ap_psm_change_period;
+	u8     min_auto_ps_poll_period;
 } __packed;
 
 struct hif_cnf_set_pm_mode {
-	u32   status;
+	__le32 status;
 } __packed;
 
 struct hif_ind_set_pm_mode_cmpl {
-	u32   status;
-	u8    pm_mode;
-	u8    reserved[3];
+	__le32 status;
+	u8     pm_mode;
+	u8     reserved[3];
 } __packed;
 
 
 struct hif_req_start {
-	u8    mode;
-	u8    band;
-	u16   channel_number;
-	u32   reserved1;
-	u32   beacon_interval;
-	u8    dtim_period;
-	u8    short_preamble:1;
-	u8    reserved2:7;
-	u8    reserved3;
-	u8    ssid_length;
-	u8    ssid[HIF_API_SSID_SIZE];
-	u32   basic_rate_set;
+	u8     mode;
+	u8     band;
+	__le16 channel_number;
+	__le32 reserved1;
+	__le32 beacon_interval;
+	u8     dtim_period;
+	u8     short_preamble:1;
+	u8     reserved2:7;
+	u8     reserved3;
+	u8     ssid_length;
+	u8     ssid[HIF_API_SSID_SIZE];
+	__le32 basic_rate_set;
 } __packed;
 
 struct hif_cnf_start {
-	u32   status;
+	__le32 status;
 } __packed;
 
 enum hif_beacon {
@@ -472,46 +454,49 @@ enum hif_beacon {
 };
 
 struct hif_req_beacon_transmit {
-	u8    enable_beaconing;
-	u8    reserved[3];
+	u8     enable_beaconing;
+	u8     reserved[3];
 } __packed;
 
 struct hif_cnf_beacon_transmit {
-	u32   status;
+	__le32 status;
 } __packed;
 
+#define HIF_LINK_ID_MAX            14
+#define HIF_LINK_ID_NOT_ASSOCIATED (HIF_LINK_ID_MAX + 1)
+
 enum hif_sta_map_direction {
 	HIF_STA_MAP                       = 0x0,
 	HIF_STA_UNMAP                     = 0x1
 };
 
 struct hif_map_link_flags {
-	u8    map_direction:1;
-	u8    mfpc:1;
-	u8    reserved:6;
+	u8     map_direction:1;
+	u8     mfpc:1;
+	u8     reserved:6;
 } __packed;
 
 struct hif_req_map_link {
-	u8    mac_addr[ETH_ALEN];
+	u8     mac_addr[ETH_ALEN];
 	struct hif_map_link_flags map_link_flags;
-	u8    peer_sta_id;
+	u8     peer_sta_id;
 } __packed;
 
 struct hif_cnf_map_link {
-	u32   status;
+	__le32 status;
 } __packed;
 
 struct hif_suspend_resume_flags {
-	u8    resume:1;
-	u8    reserved1:2;
-	u8    bc_mc_only:1;
-	u8    reserved2:4;
-	u8    reserved3;
+	u8     resume:1;
+	u8     reserved1:2;
+	u8     bc_mc_only:1;
+	u8     reserved2:4;
+	u8     reserved3;
 } __packed;
 
 struct hif_ind_suspend_resume_tx {
 	struct hif_suspend_resume_flags suspend_resume_flags;
-	u16   peer_sta_set;
+	__le16 peer_sta_set;
 } __packed;
 
 
@@ -541,102 +526,102 @@ enum hif_key_type {
 };
 
 struct hif_wep_pairwise_key {
-	u8    peer_address[ETH_ALEN];
-	u8    reserved;
-	u8    key_length;
-	u8    key_data[HIF_API_WEP_KEY_DATA_SIZE];
+	u8     peer_address[ETH_ALEN];
+	u8     reserved;
+	u8     key_length;
+	u8     key_data[HIF_API_WEP_KEY_DATA_SIZE];
 } __packed;
 
 struct hif_wep_group_key {
-	u8    key_id;
-	u8    key_length;
-	u8    reserved[2];
-	u8    key_data[HIF_API_WEP_KEY_DATA_SIZE];
+	u8     key_id;
+	u8     key_length;
+	u8     reserved[2];
+	u8     key_data[HIF_API_WEP_KEY_DATA_SIZE];
 } __packed;
 
 struct hif_tkip_pairwise_key {
-	u8    peer_address[ETH_ALEN];
-	u8    reserved[2];
-	u8    tkip_key_data[HIF_API_TKIP_KEY_DATA_SIZE];
-	u8    rx_mic_key[HIF_API_RX_MIC_KEY_SIZE];
-	u8    tx_mic_key[HIF_API_TX_MIC_KEY_SIZE];
+	u8     peer_address[ETH_ALEN];
+	u8     reserved[2];
+	u8     tkip_key_data[HIF_API_TKIP_KEY_DATA_SIZE];
+	u8     rx_mic_key[HIF_API_RX_MIC_KEY_SIZE];
+	u8     tx_mic_key[HIF_API_TX_MIC_KEY_SIZE];
 } __packed;
 
 struct hif_tkip_group_key {
-	u8    tkip_key_data[HIF_API_TKIP_KEY_DATA_SIZE];
-	u8    rx_mic_key[HIF_API_RX_MIC_KEY_SIZE];
-	u8    key_id;
-	u8    reserved[3];
-	u8    rx_sequence_counter[HIF_API_RX_SEQUENCE_COUNTER_SIZE];
+	u8     tkip_key_data[HIF_API_TKIP_KEY_DATA_SIZE];
+	u8     rx_mic_key[HIF_API_RX_MIC_KEY_SIZE];
+	u8     key_id;
+	u8     reserved[3];
+	u8     rx_sequence_counter[HIF_API_RX_SEQUENCE_COUNTER_SIZE];
 } __packed;
 
 struct hif_aes_pairwise_key {
-	u8    peer_address[ETH_ALEN];
-	u8    reserved[2];
-	u8    aes_key_data[HIF_API_AES_KEY_DATA_SIZE];
+	u8     peer_address[ETH_ALEN];
+	u8     reserved[2];
+	u8     aes_key_data[HIF_API_AES_KEY_DATA_SIZE];
 } __packed;
 
 struct hif_aes_group_key {
-	u8    aes_key_data[HIF_API_AES_KEY_DATA_SIZE];
-	u8    key_id;
-	u8    reserved[3];
-	u8    rx_sequence_counter[HIF_API_RX_SEQUENCE_COUNTER_SIZE];
+	u8     aes_key_data[HIF_API_AES_KEY_DATA_SIZE];
+	u8     key_id;
+	u8     reserved[3];
+	u8     rx_sequence_counter[HIF_API_RX_SEQUENCE_COUNTER_SIZE];
 } __packed;
 
 struct hif_wapi_pairwise_key {
-	u8    peer_address[ETH_ALEN];
-	u8    key_id;
-	u8    reserved;
-	u8    wapi_key_data[HIF_API_WAPI_KEY_DATA_SIZE];
-	u8    mic_key_data[HIF_API_MIC_KEY_DATA_SIZE];
+	u8     peer_address[ETH_ALEN];
+	u8     key_id;
+	u8     reserved;
+	u8     wapi_key_data[HIF_API_WAPI_KEY_DATA_SIZE];
+	u8     mic_key_data[HIF_API_MIC_KEY_DATA_SIZE];
 } __packed;
 
 struct hif_wapi_group_key {
-	u8    wapi_key_data[HIF_API_WAPI_KEY_DATA_SIZE];
-	u8    mic_key_data[HIF_API_MIC_KEY_DATA_SIZE];
-	u8    key_id;
-	u8    reserved[3];
+	u8     wapi_key_data[HIF_API_WAPI_KEY_DATA_SIZE];
+	u8     mic_key_data[HIF_API_MIC_KEY_DATA_SIZE];
+	u8     key_id;
+	u8     reserved[3];
 } __packed;
 
 struct hif_igtk_group_key {
-	u8    igtk_key_data[HIF_API_IGTK_KEY_DATA_SIZE];
-	u8    key_id;
-	u8    reserved[3];
-	u8    ipn[HIF_API_IPN_SIZE];
+	u8     igtk_key_data[HIF_API_IGTK_KEY_DATA_SIZE];
+	u8     key_id;
+	u8     reserved[3];
+	u8     ipn[HIF_API_IPN_SIZE];
 } __packed;
 
 union hif_privacy_key_data {
-	struct hif_wep_pairwise_key                       wep_pairwise_key;
-	struct hif_wep_group_key                          wep_group_key;
-	struct hif_tkip_pairwise_key                      tkip_pairwise_key;
-	struct hif_tkip_group_key                         tkip_group_key;
-	struct hif_aes_pairwise_key                       aes_pairwise_key;
-	struct hif_aes_group_key                          aes_group_key;
-	struct hif_wapi_pairwise_key                      wapi_pairwise_key;
-	struct hif_wapi_group_key                         wapi_group_key;
-	struct hif_igtk_group_key                         igtk_group_key;
+	struct hif_wep_pairwise_key  wep_pairwise_key;
+	struct hif_wep_group_key     wep_group_key;
+	struct hif_tkip_pairwise_key tkip_pairwise_key;
+	struct hif_tkip_group_key    tkip_group_key;
+	struct hif_aes_pairwise_key  aes_pairwise_key;
+	struct hif_aes_group_key     aes_group_key;
+	struct hif_wapi_pairwise_key wapi_pairwise_key;
+	struct hif_wapi_group_key    wapi_group_key;
+	struct hif_igtk_group_key    igtk_group_key;
 };
 
 struct hif_req_add_key {
-	u8    type;
-	u8    entry_index;
-	u8    int_id:2;
-	u8    reserved1:6;
-	u8    reserved2;
+	u8     type;
+	u8     entry_index;
+	u8     int_id:2;
+	u8     reserved1:6;
+	u8     reserved2;
 	union hif_privacy_key_data key;
 } __packed;
 
 struct hif_cnf_add_key {
-	u32   status;
+	__le32 status;
 } __packed;
 
 struct hif_req_remove_key {
-	u8    entry_index;
-	u8    reserved[3];
+	u8     entry_index;
+	u8     reserved[3];
 } __packed;
 
 struct hif_cnf_remove_key {
-	u32   status;
+	__le32 status;
 } __packed;
 
 enum hif_event_ind {
@@ -656,13 +641,13 @@ enum hif_ps_mode_error {
 };
 
 union hif_event_data {
-	u8    rcpi_rssi;
-	u32   ps_mode_error;
-	u32   peer_sta_set;
+	u8     rcpi_rssi;
+	__le32 ps_mode_error;
+	__le32 peer_sta_set;
 };
 
 struct hif_ind_event {
-	u32   event_id;
+	__le32 event_id;
 	union hif_event_data event_data;
 } __packed;
 
diff --git a/drivers/staging/wfx/hif_api_general.h b/drivers/staging/wfx/hif_api_general.h
index a069c3a21b4d..275354eb6b6a 100644
--- a/drivers/staging/wfx/hif_api_general.h
+++ b/drivers/staging/wfx/hif_api_general.h
@@ -17,13 +17,13 @@
 #define __packed __attribute__((__packed__))
 #endif
 
-#define API_SSID_SIZE                       32
+#define API_SSID_SIZE             32
 
-#define HIF_ID_IS_INDICATION               0x80
-#define HIF_COUNTER_MAX                    7
+#define HIF_ID_IS_INDICATION      0x80
+#define HIF_COUNTER_MAX           7
 
 struct hif_msg {
-	u16    len;
+	__le16 len;
 	u8     id;
 	u8     reserved:1;
 	u8     interface:2;
@@ -33,38 +33,38 @@ struct hif_msg {
 } __packed;
 
 enum hif_general_requests_ids {
-	HIF_REQ_ID_CONFIGURATION                         = 0x09,
-	HIF_REQ_ID_CONTROL_GPIO                          = 0x26,
-	HIF_REQ_ID_SET_SL_MAC_KEY                        = 0x27,
-	HIF_REQ_ID_SL_EXCHANGE_PUB_KEYS                  = 0x28,
-	HIF_REQ_ID_SL_CONFIGURE                          = 0x29,
-	HIF_REQ_ID_PREVENT_ROLLBACK                      = 0x2a,
-	HIF_REQ_ID_PTA_SETTINGS                          = 0x2b,
-	HIF_REQ_ID_PTA_PRIORITY                          = 0x2c,
-	HIF_REQ_ID_PTA_STATE                             = 0x2d,
-	HIF_REQ_ID_SHUT_DOWN                             = 0x32,
+	HIF_REQ_ID_CONFIGURATION        = 0x09,
+	HIF_REQ_ID_CONTROL_GPIO         = 0x26,
+	HIF_REQ_ID_SET_SL_MAC_KEY       = 0x27,
+	HIF_REQ_ID_SL_EXCHANGE_PUB_KEYS = 0x28,
+	HIF_REQ_ID_SL_CONFIGURE         = 0x29,
+	HIF_REQ_ID_PREVENT_ROLLBACK     = 0x2a,
+	HIF_REQ_ID_PTA_SETTINGS         = 0x2b,
+	HIF_REQ_ID_PTA_PRIORITY         = 0x2c,
+	HIF_REQ_ID_PTA_STATE            = 0x2d,
+	HIF_REQ_ID_SHUT_DOWN            = 0x32,
 };
 
 enum hif_general_confirmations_ids {
-	HIF_CNF_ID_CONFIGURATION                         = 0x09,
-	HIF_CNF_ID_CONTROL_GPIO                          = 0x26,
-	HIF_CNF_ID_SET_SL_MAC_KEY                        = 0x27,
-	HIF_CNF_ID_SL_EXCHANGE_PUB_KEYS                  = 0x28,
-	HIF_CNF_ID_SL_CONFIGURE                          = 0x29,
-	HIF_CNF_ID_PREVENT_ROLLBACK                      = 0x2a,
-	HIF_CNF_ID_PTA_SETTINGS                          = 0x2b,
-	HIF_CNF_ID_PTA_PRIORITY                          = 0x2c,
-	HIF_CNF_ID_PTA_STATE                             = 0x2d,
-	HIF_CNF_ID_SHUT_DOWN                             = 0x32,
+	HIF_CNF_ID_CONFIGURATION        = 0x09,
+	HIF_CNF_ID_CONTROL_GPIO         = 0x26,
+	HIF_CNF_ID_SET_SL_MAC_KEY       = 0x27,
+	HIF_CNF_ID_SL_EXCHANGE_PUB_KEYS = 0x28,
+	HIF_CNF_ID_SL_CONFIGURE         = 0x29,
+	HIF_CNF_ID_PREVENT_ROLLBACK     = 0x2a,
+	HIF_CNF_ID_PTA_SETTINGS         = 0x2b,
+	HIF_CNF_ID_PTA_PRIORITY         = 0x2c,
+	HIF_CNF_ID_PTA_STATE            = 0x2d,
+	HIF_CNF_ID_SHUT_DOWN            = 0x32,
 };
 
 enum hif_general_indications_ids {
-	HIF_IND_ID_EXCEPTION                             = 0xe0,
-	HIF_IND_ID_STARTUP                               = 0xe1,
-	HIF_IND_ID_WAKEUP                                = 0xe2,
-	HIF_IND_ID_GENERIC                               = 0xe3,
-	HIF_IND_ID_ERROR                                 = 0xe4,
-	HIF_IND_ID_SL_EXCHANGE_PUB_KEYS                  = 0xe5
+	HIF_IND_ID_EXCEPTION            = 0xe0,
+	HIF_IND_ID_STARTUP              = 0xe1,
+	HIF_IND_ID_WAKEUP               = 0xe2,
+	HIF_IND_ID_GENERIC              = 0xe3,
+	HIF_IND_ID_ERROR                = 0xe4,
+	HIF_IND_ID_SL_EXCHANGE_PUB_KEYS = 0xe5
 };
 
 enum hif_hi_status {
@@ -84,188 +84,175 @@ enum hif_hi_status {
 };
 
 enum hif_api_rate_index {
-	API_RATE_INDEX_B_1MBPS                   = 0,
-	API_RATE_INDEX_B_2MBPS                   = 1,
-	API_RATE_INDEX_B_5P5MBPS                 = 2,
-	API_RATE_INDEX_B_11MBPS                  = 3,
-	API_RATE_INDEX_PBCC_22MBPS               = 4,
-	API_RATE_INDEX_PBCC_33MBPS               = 5,
-	API_RATE_INDEX_G_6MBPS                   = 6,
-	API_RATE_INDEX_G_9MBPS                   = 7,
-	API_RATE_INDEX_G_12MBPS                  = 8,
-	API_RATE_INDEX_G_18MBPS                  = 9,
-	API_RATE_INDEX_G_24MBPS                  = 10,
-	API_RATE_INDEX_G_36MBPS                  = 11,
-	API_RATE_INDEX_G_48MBPS                  = 12,
-	API_RATE_INDEX_G_54MBPS                  = 13,
-	API_RATE_INDEX_N_6P5MBPS                 = 14,
-	API_RATE_INDEX_N_13MBPS                  = 15,
-	API_RATE_INDEX_N_19P5MBPS                = 16,
-	API_RATE_INDEX_N_26MBPS                  = 17,
-	API_RATE_INDEX_N_39MBPS                  = 18,
-	API_RATE_INDEX_N_52MBPS                  = 19,
-	API_RATE_INDEX_N_58P5MBPS                = 20,
-	API_RATE_INDEX_N_65MBPS                  = 21,
-	API_RATE_NUM_ENTRIES                     = 22
+	API_RATE_INDEX_B_1MBPS     = 0,
+	API_RATE_INDEX_B_2MBPS     = 1,
+	API_RATE_INDEX_B_5P5MBPS   = 2,
+	API_RATE_INDEX_B_11MBPS    = 3,
+	API_RATE_INDEX_PBCC_22MBPS = 4,
+	API_RATE_INDEX_PBCC_33MBPS = 5,
+	API_RATE_INDEX_G_6MBPS     = 6,
+	API_RATE_INDEX_G_9MBPS     = 7,
+	API_RATE_INDEX_G_12MBPS    = 8,
+	API_RATE_INDEX_G_18MBPS    = 9,
+	API_RATE_INDEX_G_24MBPS    = 10,
+	API_RATE_INDEX_G_36MBPS    = 11,
+	API_RATE_INDEX_G_48MBPS    = 12,
+	API_RATE_INDEX_G_54MBPS    = 13,
+	API_RATE_INDEX_N_6P5MBPS   = 14,
+	API_RATE_INDEX_N_13MBPS    = 15,
+	API_RATE_INDEX_N_19P5MBPS  = 16,
+	API_RATE_INDEX_N_26MBPS    = 17,
+	API_RATE_INDEX_N_39MBPS    = 18,
+	API_RATE_INDEX_N_52MBPS    = 19,
+	API_RATE_INDEX_N_58P5MBPS  = 20,
+	API_RATE_INDEX_N_65MBPS    = 21,
+	API_RATE_NUM_ENTRIES       = 22
 };
 
 
 enum hif_fw_type {
-	HIF_FW_TYPE_ETF                             = 0x0,
-	HIF_FW_TYPE_WFM                             = 0x1,
-	HIF_FW_TYPE_WSM                             = 0x2
+	HIF_FW_TYPE_ETF  = 0x0,
+	HIF_FW_TYPE_WFM  = 0x1,
+	HIF_FW_TYPE_WSM  = 0x2
 };
 
 struct hif_capabilities {
-	u8    link_mode:2;
-	u8    reserved1:6;
-	u8    reserved2;
-	u8    reserved3;
-	u8    reserved4;
+	u8     link_mode:2;
+	u8     reserved1:6;
+	u8     reserved2;
+	u8     reserved3;
+	u8     reserved4;
 } __packed;
 
 struct hif_otp_regul_sel_mode_info {
-	u8    region_sel_mode:4;
-	u8    reserved:4;
+	u8     region_sel_mode:4;
+	u8     reserved:4;
 } __packed;
 
 struct hif_otp_phy_info {
-	u8    phy1_region:3;
-	u8    phy0_region:3;
-	u8    otp_phy_ver:2;
+	u8     phy1_region:3;
+	u8     phy0_region:3;
+	u8     otp_phy_ver:2;
 } __packed;
 
-#define API_OPN_SIZE                                    14
-#define API_UID_SIZE                                    8
-#define API_DISABLED_CHANNEL_LIST_SIZE                  2
-#define API_FIRMWARE_LABEL_SIZE                         128
-
 struct hif_ind_startup {
-	u32   status;
-	u16   hardware_id;
-	u8    opn[API_OPN_SIZE];
-	u8    uid[API_UID_SIZE];
-	u16   num_inp_ch_bufs;
-	u16   size_inp_ch_buf;
-	u8    num_links_ap;
-	u8    num_interfaces;
-	u8    mac_addr[2][ETH_ALEN];
-	u8    api_version_minor;
-	u8    api_version_major;
+	__le32 status;
+	__le16 hardware_id;
+	u8     opn[14];
+	u8     uid[8];
+	__le16 num_inp_ch_bufs;
+	__le16 size_inp_ch_buf;
+	u8     num_links_ap;
+	u8     num_interfaces;
+	u8     mac_addr[2][ETH_ALEN];
+	u8     api_version_minor;
+	u8     api_version_major;
 	struct hif_capabilities capabilities;
-	u8    firmware_build;
-	u8    firmware_minor;
-	u8    firmware_major;
-	u8    firmware_type;
-	u8    disabled_channel_list[API_DISABLED_CHANNEL_LIST_SIZE];
+	u8     firmware_build;
+	u8     firmware_minor;
+	u8     firmware_major;
+	u8     firmware_type;
+	u8     disabled_channel_list[2];
 	struct hif_otp_regul_sel_mode_info regul_sel_mode_info;
 	struct hif_otp_phy_info otp_phy_info;
-	u32   supported_rate_mask;
-	u8    firmware_label[API_FIRMWARE_LABEL_SIZE];
+	__le32 supported_rate_mask;
+	u8     firmware_label[128];
 } __packed;
 
 struct hif_ind_wakeup {
 } __packed;
 
 struct hif_req_configuration {
-	u16   length;
-	u8    pds_data[];
+	__le16 length;
+	u8     pds_data[];
 } __packed;
 
 struct hif_cnf_configuration {
-	u32   status;
+	__le32 status;
 } __packed;
 
 enum hif_gpio_mode {
-	HIF_GPIO_MODE_D0                            = 0x0,
-	HIF_GPIO_MODE_D1                            = 0x1,
-	HIF_GPIO_MODE_OD0                           = 0x2,
-	HIF_GPIO_MODE_OD1                           = 0x3,
-	HIF_GPIO_MODE_TRISTATE                      = 0x4,
-	HIF_GPIO_MODE_TOGGLE                        = 0x5,
-	HIF_GPIO_MODE_READ                          = 0x6
+	HIF_GPIO_MODE_D0       = 0x0,
+	HIF_GPIO_MODE_D1       = 0x1,
+	HIF_GPIO_MODE_OD0      = 0x2,
+	HIF_GPIO_MODE_OD1      = 0x3,
+	HIF_GPIO_MODE_TRISTATE = 0x4,
+	HIF_GPIO_MODE_TOGGLE   = 0x5,
+	HIF_GPIO_MODE_READ     = 0x6
 };
 
 struct hif_req_control_gpio {
-	u8 gpio_label;
-	u8 gpio_mode;
+	u8     gpio_label;
+	u8     gpio_mode;
 } __packed;
 
-enum hif_gpio_error {
-	HIF_GPIO_ERROR_0                            = 0x0,
-	HIF_GPIO_ERROR_1                            = 0x1,
-	HIF_GPIO_ERROR_2                            = 0x2
-};
-
 struct hif_cnf_control_gpio {
-	u32 status;
-	u32 value;
+	__le32 status;
+	__le32 value;
 } __packed;
 
 enum hif_generic_indication_type {
-	HIF_GENERIC_INDICATION_TYPE_RAW               = 0x0,
-	HIF_GENERIC_INDICATION_TYPE_STRING            = 0x1,
-	HIF_GENERIC_INDICATION_TYPE_RX_STATS          = 0x2
+	HIF_GENERIC_INDICATION_TYPE_RAW      = 0x0,
+	HIF_GENERIC_INDICATION_TYPE_STRING   = 0x1,
+	HIF_GENERIC_INDICATION_TYPE_RX_STATS = 0x2
 };
 
 struct hif_rx_stats {
-	u32   nb_rx_frame;
-	u32   nb_crc_frame;
-	u32   per_total;
-	u32   throughput;
-	u32   nb_rx_by_rate[API_RATE_NUM_ENTRIES];
-	u16   per[API_RATE_NUM_ENTRIES];
-	s16    snr[API_RATE_NUM_ENTRIES];
-	s16    rssi[API_RATE_NUM_ENTRIES];
-	s16    cfo[API_RATE_NUM_ENTRIES];
-	u32   date;
-	u32   pwr_clk_freq;
-	u8    is_ext_pwr_clk;
+	__le32 nb_rx_frame;
+	__le32 nb_crc_frame;
+	__le32 per_total;
+	__le32 throughput;
+	__le32 nb_rx_by_rate[API_RATE_NUM_ENTRIES];
+	__le16 per[API_RATE_NUM_ENTRIES];
+	__le16 snr[API_RATE_NUM_ENTRIES];  // signed value
+	__le16 rssi[API_RATE_NUM_ENTRIES]; // signed value
+	__le16 cfo[API_RATE_NUM_ENTRIES];  // signed value
+	__le32 date;
+	__le32 pwr_clk_freq;
+	u8     is_ext_pwr_clk;
 	s8     current_temp;
 } __packed;
 
 union hif_indication_data {
-	struct hif_rx_stats                                   rx_stats;
-	u8                                       raw_data[1];
+	struct hif_rx_stats rx_stats;
+	u8     raw_data[1];
 };
 
 struct hif_ind_generic {
-	u32 indication_type;
+	__le32 indication_type;
 	union hif_indication_data indication_data;
 } __packed;
 
 
-#define HIF_EXCEPTION_DATA_SIZE            124
-
 struct hif_ind_exception {
-	u8    data[HIF_EXCEPTION_DATA_SIZE];
+	u8     data[124];
 } __packed;
 
 
 enum hif_error {
-	HIF_ERROR_FIRMWARE_ROLLBACK             = 0x0,
-	HIF_ERROR_FIRMWARE_DEBUG_ENABLED        = 0x1,
-	HIF_ERROR_OUTDATED_SESSION_KEY          = 0x2,
-	HIF_ERROR_INVALID_SESSION_KEY           = 0x3,
-	HIF_ERROR_OOR_VOLTAGE                   = 0x4,
-	HIF_ERROR_PDS_VERSION                   = 0x5,
-	HIF_ERROR_OOR_TEMPERATURE               = 0x6,
-	HIF_ERROR_REQ_DURING_KEY_EXCHANGE       = 0x7,
-	HIF_ERROR_MULTI_TX_CNF_SECURELINK       = 0x8,
-	HIF_ERROR_SECURELINK_OVERFLOW           = 0x9,
-	HIF_ERROR_SECURELINK_DECRYPTION         = 0xa
+	HIF_ERROR_FIRMWARE_ROLLBACK       = 0x0,
+	HIF_ERROR_FIRMWARE_DEBUG_ENABLED  = 0x1,
+	HIF_ERROR_OUTDATED_SESSION_KEY    = 0x2,
+	HIF_ERROR_INVALID_SESSION_KEY     = 0x3,
+	HIF_ERROR_OOR_VOLTAGE             = 0x4,
+	HIF_ERROR_PDS_VERSION             = 0x5,
+	HIF_ERROR_OOR_TEMPERATURE         = 0x6,
+	HIF_ERROR_REQ_DURING_KEY_EXCHANGE = 0x7,
+	HIF_ERROR_MULTI_TX_CNF_SECURELINK = 0x8,
+	HIF_ERROR_SECURELINK_OVERFLOW     = 0x9,
+	HIF_ERROR_SECURELINK_DECRYPTION   = 0xa
 };
 
 struct hif_ind_error {
-	u32   type;
-	u8    data[];
+	__le32 type;
+	u8     data[];
 } __packed;
 
 enum hif_secure_link_state {
-	SEC_LINK_UNAVAILABLE                    = 0x0,
-	SEC_LINK_RESERVED                       = 0x1,
-	SEC_LINK_EVAL                           = 0x2,
-	SEC_LINK_ENFORCED                       = 0x3
+	SEC_LINK_UNAVAILABLE = 0x0,
+	SEC_LINK_RESERVED    = 0x1,
+	SEC_LINK_EVAL        = 0x2,
+	SEC_LINK_ENFORCED    = 0x3
 };
 
 enum hif_sl_encryption_type {
@@ -282,156 +269,70 @@ struct hif_sl_msg_hdr {
 
 struct hif_sl_msg {
 	struct hif_sl_msg_hdr hdr;
-	u16        len;
-	u8         payload[];
+	__le16 len;
+	u8     payload[];
 } __packed;
 
-#define AES_CCM_TAG_SIZE     16
+#define AES_CCM_TAG_SIZE          16
 
 struct hif_sl_tag {
-	u8 tag[16];
+	u8     tag[16];
 } __packed;
 
 enum hif_sl_mac_key_dest {
-	SL_MAC_KEY_DEST_OTP                        = 0x78,
-	SL_MAC_KEY_DEST_RAM                        = 0x87
+	SL_MAC_KEY_DEST_OTP = 0x78,
+	SL_MAC_KEY_DEST_RAM = 0x87
 };
 
-#define API_KEY_VALUE_SIZE      32
+#define API_KEY_VALUE_SIZE        32
 
 struct hif_req_set_sl_mac_key {
-	u8    otp_or_ram;
-	u8    key_value[API_KEY_VALUE_SIZE];
+	u8     otp_or_ram;
+	u8     key_value[API_KEY_VALUE_SIZE];
 } __packed;
 
 struct hif_cnf_set_sl_mac_key {
-	u32   status;
+	__le32 status;
 } __packed;
 
-#define API_HOST_PUB_KEY_SIZE                           32
-#define API_HOST_PUB_KEY_MAC_SIZE                       64
-
 enum hif_sl_session_key_alg {
-	HIF_SL_CURVE25519                                = 0x01,
-	HIF_SL_KDF                                       = 0x02
+	HIF_SL_CURVE25519 = 0x01,
+	HIF_SL_KDF        = 0x02
 };
 
+#define API_HOST_PUB_KEY_SIZE     32
+#define API_HOST_PUB_KEY_MAC_SIZE 64
+
 struct hif_req_sl_exchange_pub_keys {
-	u8    algorithm:2;
-	u8    reserved1:6;
-	u8    reserved2[3];
-	u8    host_pub_key[API_HOST_PUB_KEY_SIZE];
-	u8    host_pub_key_mac[API_HOST_PUB_KEY_MAC_SIZE];
+	u8     algorithm:2;
+	u8     reserved1:6;
+	u8     reserved2[3];
+	u8     host_pub_key[API_HOST_PUB_KEY_SIZE];
+	u8     host_pub_key_mac[API_HOST_PUB_KEY_MAC_SIZE];
 } __packed;
 
 struct hif_cnf_sl_exchange_pub_keys {
-	u32   status;
+	__le32 status;
 } __packed;
 
-#define API_NCP_PUB_KEY_SIZE                            32
-#define API_NCP_PUB_KEY_MAC_SIZE                        64
+#define API_NCP_PUB_KEY_SIZE      32
+#define API_NCP_PUB_KEY_MAC_SIZE  64
 
 struct hif_ind_sl_exchange_pub_keys {
-	u32   status;
-	u8    ncp_pub_key[API_NCP_PUB_KEY_SIZE];
-	u8    ncp_pub_key_mac[API_NCP_PUB_KEY_MAC_SIZE];
+	__le32 status;
+	u8     ncp_pub_key[API_NCP_PUB_KEY_SIZE];
+	u8     ncp_pub_key_mac[API_NCP_PUB_KEY_MAC_SIZE];
 } __packed;
 
-#define API_ENCR_BMP_SIZE        32
-
 struct hif_req_sl_configure {
-	u8    encr_bmp[API_ENCR_BMP_SIZE];
-	u8    disable_session_key_protection:1;
-	u8    reserved1:7;
-	u8    reserved2[3];
+	u8     encr_bmp[32];
+	u8     disable_session_key_protection:1;
+	u8     reserved1:7;
+	u8     reserved2[3];
 } __packed;
 
 struct hif_cnf_sl_configure {
-	u32 status;
-} __packed;
-
-struct hif_req_prevent_rollback {
-	u32   magic_word;
-} __packed;
-
-struct hif_cnf_prevent_rollback {
-	u32    status;
-} __packed;
-
-enum hif_pta_mode {
-	PTA_1W_WLAN_MASTER = 0,
-	PTA_1W_COEX_MASTER = 1,
-	PTA_2W             = 2,
-	PTA_3W             = 3,
-	PTA_4W             = 4
-};
-
-enum hif_signal_level {
-	SIGNAL_LOW  = 0,
-	SIGNAL_HIGH = 1
-};
-
-enum hif_coex_type {
-	COEX_TYPE_GENERIC = 0,
-	COEX_TYPE_BLE     = 1
-};
-
-enum hif_grant_state {
-	NO_GRANT = 0,
-	GRANT    = 1
-};
-
-struct hif_req_pta_settings {
-	u8 pta_mode;
-	u8 request_signal_active_level;
-	u8 priority_signal_active_level;
-	u8 freq_signal_active_level;
-	u8 grant_signal_active_level;
-	u8 coex_type;
-	u8 default_grant_state;
-	u8 simultaneous_rx_accesses;
-	u8 priority_sampling_time;
-	u8 tx_rx_sampling_time;
-	u8 freq_sampling_time;
-	u8 grant_valid_time;
-	u8 fem_control_time;
-	u8 first_slot_time;
-	u16 periodic_tx_rx_sampling_time;
-	u16 coex_quota;
-	u16 wlan_quota;
-} __packed;
-
-struct hif_cnf_pta_settings {
-	u32 status;
-} __packed;
-
-enum hif_pta_priority {
-	HIF_PTA_PRIORITY_COEX_MAXIMIZED = 0x00000562,
-	HIF_PTA_PRIORITY_COEX_HIGH      = 0x00000462,
-	HIF_PTA_PRIORITY_BALANCED       = 0x00001461,
-	HIF_PTA_PRIORITY_WLAN_HIGH      = 0x00001851,
-	HIF_PTA_PRIORITY_WLAN_MAXIMIZED = 0x00001A51
-};
-
-struct hif_req_pta_priority {
-	u32 priority;
-} __packed;
-
-struct hif_cnf_pta_priority {
-	u32 status;
-} __packed;
-
-enum hif_pta_state {
-	PTA_OFF = 0,
-	PTA_ON  = 1
-};
-
-struct hif_req_pta_state {
-	u32 pta_state;
-} __packed;
-
-struct hif_cnf_pta_state {
-	u32 status;
+	__le32 status;
 } __packed;
 
 #endif
diff --git a/drivers/staging/wfx/hif_api_mib.h b/drivers/staging/wfx/hif_api_mib.h
index 0c67cd4c1593..9f30cf503ad5 100644
--- a/drivers/staging/wfx/hif_api_mib.h
+++ b/drivers/staging/wfx/hif_api_mib.h
@@ -10,175 +10,88 @@
 
 #include "hif_api_general.h"
 
-#define HIF_API_IPV4_ADDRESS_SIZE                       4
-#define HIF_API_IPV6_ADDRESS_SIZE                       16
+#define HIF_API_IPV4_ADDRESS_SIZE 4
+#define HIF_API_IPV6_ADDRESS_SIZE 16
 
 enum hif_mib_ids {
-	HIF_MIB_ID_GL_OPERATIONAL_POWER_MODE       = 0x2000,
-	HIF_MIB_ID_GL_BLOCK_ACK_INFO               = 0x2001,
-	HIF_MIB_ID_GL_SET_MULTI_MSG                = 0x2002,
-	HIF_MIB_ID_CCA_CONFIG                      = 0x2003,
-	HIF_MIB_ID_ETHERTYPE_DATAFRAME_CONDITION   = 0x2010,
-	HIF_MIB_ID_PORT_DATAFRAME_CONDITION        = 0x2011,
-	HIF_MIB_ID_MAGIC_DATAFRAME_CONDITION       = 0x2012,
-	HIF_MIB_ID_MAC_ADDR_DATAFRAME_CONDITION    = 0x2013,
-	HIF_MIB_ID_IPV4_ADDR_DATAFRAME_CONDITION   = 0x2014,
-	HIF_MIB_ID_IPV6_ADDR_DATAFRAME_CONDITION   = 0x2015,
-	HIF_MIB_ID_UC_MC_BC_DATAFRAME_CONDITION    = 0x2016,
-	HIF_MIB_ID_CONFIG_DATA_FILTER              = 0x2017,
-	HIF_MIB_ID_SET_DATA_FILTERING              = 0x2018,
-	HIF_MIB_ID_ARP_IP_ADDRESSES_TABLE          = 0x2019,
-	HIF_MIB_ID_NS_IP_ADDRESSES_TABLE           = 0x201A,
-	HIF_MIB_ID_RX_FILTER                       = 0x201B,
-	HIF_MIB_ID_BEACON_FILTER_TABLE             = 0x201C,
-	HIF_MIB_ID_BEACON_FILTER_ENABLE            = 0x201D,
-	HIF_MIB_ID_GRP_SEQ_COUNTER                 = 0x2030,
-	HIF_MIB_ID_TSF_COUNTER                     = 0x2031,
-	HIF_MIB_ID_STATISTICS_TABLE                = 0x2032,
-	HIF_MIB_ID_COUNTERS_TABLE                  = 0x2033,
-	HIF_MIB_ID_MAX_TX_POWER_LEVEL              = 0x2034,
-	HIF_MIB_ID_EXTENDED_COUNTERS_TABLE         = 0x2035,
-	HIF_MIB_ID_DOT11_MAC_ADDRESS               = 0x2040,
+	HIF_MIB_ID_GL_OPERATIONAL_POWER_MODE        = 0x2000,
+	HIF_MIB_ID_GL_BLOCK_ACK_INFO                = 0x2001,
+	HIF_MIB_ID_GL_SET_MULTI_MSG                 = 0x2002,
+	HIF_MIB_ID_CCA_CONFIG                       = 0x2003,
+	HIF_MIB_ID_ETHERTYPE_DATAFRAME_CONDITION    = 0x2010,
+	HIF_MIB_ID_PORT_DATAFRAME_CONDITION         = 0x2011,
+	HIF_MIB_ID_MAGIC_DATAFRAME_CONDITION        = 0x2012,
+	HIF_MIB_ID_MAC_ADDR_DATAFRAME_CONDITION     = 0x2013,
+	HIF_MIB_ID_IPV4_ADDR_DATAFRAME_CONDITION    = 0x2014,
+	HIF_MIB_ID_IPV6_ADDR_DATAFRAME_CONDITION    = 0x2015,
+	HIF_MIB_ID_UC_MC_BC_DATAFRAME_CONDITION     = 0x2016,
+	HIF_MIB_ID_CONFIG_DATA_FILTER               = 0x2017,
+	HIF_MIB_ID_SET_DATA_FILTERING               = 0x2018,
+	HIF_MIB_ID_ARP_IP_ADDRESSES_TABLE           = 0x2019,
+	HIF_MIB_ID_NS_IP_ADDRESSES_TABLE            = 0x201A,
+	HIF_MIB_ID_RX_FILTER                        = 0x201B,
+	HIF_MIB_ID_BEACON_FILTER_TABLE              = 0x201C,
+	HIF_MIB_ID_BEACON_FILTER_ENABLE             = 0x201D,
+	HIF_MIB_ID_GRP_SEQ_COUNTER                  = 0x2030,
+	HIF_MIB_ID_TSF_COUNTER                      = 0x2031,
+	HIF_MIB_ID_STATISTICS_TABLE                 = 0x2032,
+	HIF_MIB_ID_COUNTERS_TABLE                   = 0x2033,
+	HIF_MIB_ID_MAX_TX_POWER_LEVEL               = 0x2034,
+	HIF_MIB_ID_EXTENDED_COUNTERS_TABLE          = 0x2035,
+	HIF_MIB_ID_DOT11_MAC_ADDRESS                = 0x2040,
 	HIF_MIB_ID_DOT11_MAX_TRANSMIT_MSDU_LIFETIME = 0x2041,
-	HIF_MIB_ID_DOT11_MAX_RECEIVE_LIFETIME      = 0x2042,
-	HIF_MIB_ID_DOT11_WEP_DEFAULT_KEY_ID        = 0x2043,
-	HIF_MIB_ID_DOT11_RTS_THRESHOLD             = 0x2044,
-	HIF_MIB_ID_SLOT_TIME                       = 0x2045,
-	HIF_MIB_ID_CURRENT_TX_POWER_LEVEL          = 0x2046,
-	HIF_MIB_ID_NON_ERP_PROTECTION              = 0x2047,
-	HIF_MIB_ID_TEMPLATE_FRAME                  = 0x2048,
-	HIF_MIB_ID_BEACON_WAKEUP_PERIOD            = 0x2049,
-	HIF_MIB_ID_RCPI_RSSI_THRESHOLD             = 0x204A,
-	HIF_MIB_ID_BLOCK_ACK_POLICY                = 0x204B,
-	HIF_MIB_ID_OVERRIDE_INTERNAL_TX_RATE       = 0x204C,
-	HIF_MIB_ID_SET_ASSOCIATION_MODE            = 0x204D,
-	HIF_MIB_ID_SET_UAPSD_INFORMATION           = 0x204E,
-	HIF_MIB_ID_SET_TX_RATE_RETRY_POLICY        = 0x204F,
-	HIF_MIB_ID_PROTECTED_MGMT_POLICY           = 0x2050,
-	HIF_MIB_ID_SET_HT_PROTECTION               = 0x2051,
-	HIF_MIB_ID_KEEP_ALIVE_PERIOD               = 0x2052,
-	HIF_MIB_ID_ARP_KEEP_ALIVE_PERIOD           = 0x2053,
-	HIF_MIB_ID_INACTIVITY_TIMER                = 0x2054,
-	HIF_MIB_ID_INTERFACE_PROTECTION            = 0x2055,
-	HIF_MIB_ID_BEACON_STATS                    = 0x2056,
+	HIF_MIB_ID_DOT11_MAX_RECEIVE_LIFETIME       = 0x2042,
+	HIF_MIB_ID_DOT11_WEP_DEFAULT_KEY_ID         = 0x2043,
+	HIF_MIB_ID_DOT11_RTS_THRESHOLD              = 0x2044,
+	HIF_MIB_ID_SLOT_TIME                        = 0x2045,
+	HIF_MIB_ID_CURRENT_TX_POWER_LEVEL           = 0x2046,
+	HIF_MIB_ID_NON_ERP_PROTECTION               = 0x2047,
+	HIF_MIB_ID_TEMPLATE_FRAME                   = 0x2048,
+	HIF_MIB_ID_BEACON_WAKEUP_PERIOD             = 0x2049,
+	HIF_MIB_ID_RCPI_RSSI_THRESHOLD              = 0x204A,
+	HIF_MIB_ID_BLOCK_ACK_POLICY                 = 0x204B,
+	HIF_MIB_ID_OVERRIDE_INTERNAL_TX_RATE        = 0x204C,
+	HIF_MIB_ID_SET_ASSOCIATION_MODE             = 0x204D,
+	HIF_MIB_ID_SET_UAPSD_INFORMATION            = 0x204E,
+	HIF_MIB_ID_SET_TX_RATE_RETRY_POLICY         = 0x204F,
+	HIF_MIB_ID_PROTECTED_MGMT_POLICY            = 0x2050,
+	HIF_MIB_ID_SET_HT_PROTECTION                = 0x2051,
+	HIF_MIB_ID_KEEP_ALIVE_PERIOD                = 0x2052,
+	HIF_MIB_ID_ARP_KEEP_ALIVE_PERIOD            = 0x2053,
+	HIF_MIB_ID_INACTIVITY_TIMER                 = 0x2054,
+	HIF_MIB_ID_INTERFACE_PROTECTION             = 0x2055,
+	HIF_MIB_ID_BEACON_STATS                     = 0x2056,
 };
 
-#define HIF_OP_POWER_MODE_MASK                     0xf
-
 enum hif_op_power_mode {
-	HIF_OP_POWER_MODE_ACTIVE                   = 0x0,
-	HIF_OP_POWER_MODE_DOZE                     = 0x1,
-	HIF_OP_POWER_MODE_QUIESCENT                = 0x2
+	HIF_OP_POWER_MODE_ACTIVE    = 0x0,
+	HIF_OP_POWER_MODE_DOZE      = 0x1,
+	HIF_OP_POWER_MODE_QUIESCENT = 0x2
 };
 
 struct hif_mib_gl_operational_power_mode {
-	u8    power_mode:4;
-	u8    reserved1:3;
-	u8    wup_ind_activation:1;
-	u8    reserved2[3];
-} __packed;
-
-struct hif_mib_gl_block_ack_info {
-	u8    rx_buffer_size;
-	u8    rx_max_num_agreements;
-	u8    tx_buffer_size;
-	u8    tx_max_num_agreements;
+	u8     power_mode:4;
+	u8     reserved1:3;
+	u8     wup_ind_activation:1;
+	u8     reserved2[3];
 } __packed;
 
 struct hif_mib_gl_set_multi_msg {
-	u8    enable_multi_tx_conf:1;
-	u8    reserved1:7;
-	u8    reserved2[3];
-} __packed;
-
-enum hif_cca_thr_mode {
-	HIF_CCA_THR_MODE_RELATIVE = 0x0,
-	HIF_CCA_THR_MODE_ABSOLUTE = 0x1
-};
-
-struct hif_mib_gl_cca_config {
-	u8  cca_thr_mode;
-	u8  reserved[3];
-} __packed;
-
-#define MAX_NUMBER_DATA_FILTERS             0xA
-
-#define MAX_NUMBER_IPV4_ADDR_CONDITIONS     0x4
-#define MAX_NUMBER_IPV6_ADDR_CONDITIONS     0x4
-#define MAX_NUMBER_MAC_ADDR_CONDITIONS      0x4
-#define MAX_NUMBER_UC_MC_BC_CONDITIONS      0x4
-#define MAX_NUMBER_ETHER_TYPE_CONDITIONS    0x4
-#define MAX_NUMBER_PORT_CONDITIONS          0x4
-#define MAX_NUMBER_MAGIC_CONDITIONS         0x4
-#define MAX_NUMBER_ARP_CONDITIONS           0x2
-#define MAX_NUMBER_NS_CONDITIONS            0x2
-
-struct hif_mib_ethertype_data_frame_condition {
-	u8    condition_idx;
-	u8    reserved;
-	u16   ether_type;
-} __packed;
-
-enum hif_udp_tcp_protocol {
-	HIF_PROTOCOL_UDP                       = 0x0,
-	HIF_PROTOCOL_TCP                       = 0x1,
-	HIF_PROTOCOL_BOTH_UDP_TCP              = 0x2
-};
-
-enum hif_which_port {
-	HIF_PORT_DST                           = 0x0,
-	HIF_PORT_SRC                           = 0x1,
-	HIF_PORT_SRC_OR_DST                    = 0x2
-};
-
-struct hif_mib_ports_data_frame_condition {
-	u8    condition_idx;
-	u8    protocol;
-	u8    which_port;
-	u8    reserved1;
-	u16   port_number;
-	u8    reserved2[2];
-} __packed;
-
-#define HIF_API_MAGIC_PATTERN_SIZE                 32
-
-struct hif_mib_magic_data_frame_condition {
-	u8    condition_idx;
-	u8    offset;
-	u8    magic_pattern_length;
-	u8    reserved;
-	u8    magic_pattern[HIF_API_MAGIC_PATTERN_SIZE];
+	u8     enable_multi_tx_conf:1;
+	u8     reserved1:7;
+	u8     reserved2[3];
 } __packed;
 
 enum hif_mac_addr_type {
-	HIF_MAC_ADDR_A1                            = 0x0,
-	HIF_MAC_ADDR_A2                            = 0x1,
-	HIF_MAC_ADDR_A3                            = 0x2
+	HIF_MAC_ADDR_A1 = 0x0,
+	HIF_MAC_ADDR_A2 = 0x1,
+	HIF_MAC_ADDR_A3 = 0x2
 };
 
 struct hif_mib_mac_addr_data_frame_condition {
-	u8    condition_idx;
-	u8    address_type;
-	u8    mac_address[ETH_ALEN];
-} __packed;
-
-enum hif_ip_addr_mode {
-	HIF_IP_ADDR_SRC                            = 0x0,
-	HIF_IP_ADDR_DST                            = 0x1
-};
-
-struct hif_mib_ipv4_addr_data_frame_condition {
-	u8    condition_idx;
-	u8    address_mode;
-	u8    reserved[2];
-	u8    i_pv4_address[HIF_API_IPV4_ADDRESS_SIZE];
-} __packed;
-
-struct hif_mib_ipv6_addr_data_frame_condition {
-	u8    condition_idx;
-	u8    address_mode;
-	u8    reserved[2];
-	u8    i_pv6_address[HIF_API_IPV6_ADDRESS_SIZE];
+	u8     condition_idx;
+	u8     address_type;
+	u8     mac_address[ETH_ALEN];
 } __packed;
 
 #define HIF_FILTER_UNICAST   0x1
@@ -186,365 +99,295 @@ struct hif_mib_ipv6_addr_data_frame_condition {
 #define HIF_FILTER_BROADCAST 0x4
 
 struct hif_mib_uc_mc_bc_data_frame_condition {
-	u8    condition_idx;
-	u8    allowed_frames;
-	u8    reserved[2];
+	u8     condition_idx;
+	u8     allowed_frames;
+	u8     reserved[2];
 } __packed;
 
 struct hif_mib_config_data_filter {
-	u8    filter_idx;
-	u8    enable;
-	u8    reserved1[2];
-	u8    eth_type_cond;
-	u8    port_cond;
-	u8    magic_cond;
-	u8    mac_cond;
-	u8    ipv4_cond;
-	u8    ipv6_cond;
-	u8    uc_mc_bc_cond;
-	u8    reserved2;
+	u8     filter_idx;
+	u8     enable;
+	u8     reserved1[2];
+	u8     eth_type_cond;
+	u8     port_cond;
+	u8     magic_cond;
+	u8     mac_cond;
+	u8     ipv4_cond;
+	u8     ipv6_cond;
+	u8     uc_mc_bc_cond;
+	u8     reserved2;
 } __packed;
 
 struct hif_mib_set_data_filtering {
-	u8    invert_matching:1;
-	u8    reserved1:7;
-	u8    enable:1;
-	u8    reserved2:7;
-	u8    reserved3[2];
+	u8     invert_matching:1;
+	u8     reserved1:7;
+	u8     enable:1;
+	u8     reserved2:7;
+	u8     reserved3[2];
 } __packed;
 
 enum hif_arp_ns_frame_treatment {
-	HIF_ARP_NS_FILTERING_DISABLE                  = 0x0,
-	HIF_ARP_NS_FILTERING_ENABLE                   = 0x1,
-	HIF_ARP_NS_REPLY_ENABLE                       = 0x2
+	HIF_ARP_NS_FILTERING_DISABLE = 0x0,
+	HIF_ARP_NS_FILTERING_ENABLE  = 0x1,
+	HIF_ARP_NS_REPLY_ENABLE      = 0x2
 };
 
 struct hif_mib_arp_ip_addr_table {
-	u8    condition_idx;
-	u8    arp_enable;
-	u8    reserved[2];
-	u8    ipv4_address[HIF_API_IPV4_ADDRESS_SIZE];
-} __packed;
-
-struct hif_mib_ns_ip_addr_table {
-	u8    condition_idx;
-	u8    ns_enable;
-	u8    reserved[2];
-	u8    ipv6_address[HIF_API_IPV6_ADDRESS_SIZE];
+	u8     condition_idx;
+	u8     arp_enable;
+	u8     reserved[2];
+	u8     ipv4_address[HIF_API_IPV4_ADDRESS_SIZE];
 } __packed;
 
 struct hif_mib_rx_filter {
-	u8    reserved1:1;
-	u8    bssid_filter:1;
-	u8    reserved2:1;
-	u8    fwd_probe_req:1;
-	u8    keep_alive_filter:1;
-	u8    reserved3:3;
-	u8    reserved4[3];
+	u8     reserved1:1;
+	u8     bssid_filter:1;
+	u8     reserved2:1;
+	u8     fwd_probe_req:1;
+	u8     keep_alive_filter:1;
+	u8     reserved3:3;
+	u8     reserved4[3];
 } __packed;
 
-#define HIF_API_OUI_SIZE                                3
-#define HIF_API_MATCH_DATA_SIZE                         3
-
 struct hif_ie_table_entry {
-	u8    ie_id;
-	u8    has_changed:1;
-	u8    no_longer:1;
-	u8    has_appeared:1;
-	u8    reserved:1;
-	u8    num_match_data:4;
-	u8    oui[HIF_API_OUI_SIZE];
-	u8    match_data[HIF_API_MATCH_DATA_SIZE];
+	u8     ie_id;
+	u8     has_changed:1;
+	u8     no_longer:1;
+	u8     has_appeared:1;
+	u8     reserved:1;
+	u8     num_match_data:4;
+	u8     oui[3];
+	u8     match_data[3];
 } __packed;
 
 struct hif_mib_bcn_filter_table {
-	u32   num_of_info_elmts;
+	__le32 num_of_info_elmts;
 	struct hif_ie_table_entry ie_table[];
 } __packed;
 
 enum hif_beacon_filter {
-	HIF_BEACON_FILTER_DISABLE                  = 0x0,
-	HIF_BEACON_FILTER_ENABLE                   = 0x1,
-	HIF_BEACON_FILTER_AUTO_ERP                 = 0x2
+	HIF_BEACON_FILTER_DISABLE  = 0x0,
+	HIF_BEACON_FILTER_ENABLE   = 0x1,
+	HIF_BEACON_FILTER_AUTO_ERP = 0x2
 };
 
 struct hif_mib_bcn_filter_enable {
-	u32   enable;
-	u32   bcn_count;
-} __packed;
-
-struct hif_mib_group_seq_counter {
-	u32   bits4716;
-	u16   bits1500;
-	u16   reserved;
-} __packed;
-
-struct hif_mib_tsf_counter {
-	u32   tsf_counterlo;
-	u32   tsf_counterhi;
-} __packed;
-
-struct hif_mib_stats_table {
-	s16    latest_snr;
-	u8    latest_rcpi;
-	s8     latest_rssi;
+	__le32 enable;
+	__le32 bcn_count;
 } __packed;
 
 struct hif_mib_extended_count_table {
-	u32   count_plcp_errors;
-	u32   count_fcs_errors;
-	u32   count_tx_packets;
-	u32   count_rx_packets;
-	u32   count_rx_packet_errors;
-	u32   count_rx_decryption_failures;
-	u32   count_rx_mic_failures;
-	u32   count_rx_no_key_failures;
-	u32   count_tx_multicast_frames;
-	u32   count_tx_frames_success;
-	u32   count_tx_frame_failures;
-	u32   count_tx_frames_retried;
-	u32   count_tx_frames_multi_retried;
-	u32   count_rx_frame_duplicates;
-	u32   count_rts_success;
-	u32   count_rts_failures;
-	u32   count_ack_failures;
-	u32   count_rx_multicast_frames;
-	u32   count_rx_frames_success;
-	u32   count_rx_cmacicv_errors;
-	u32   count_rx_cmac_replays;
-	u32   count_rx_mgmt_ccmp_replays;
-	u32   count_rx_bipmic_errors;
-	u32   count_rx_beacon;
-	u32   count_miss_beacon;
-	u32   reserved[15];
+	__le32 count_plcp_errors;
+	__le32 count_fcs_errors;
+	__le32 count_tx_packets;
+	__le32 count_rx_packets;
+	__le32 count_rx_packet_errors;
+	__le32 count_rx_decryption_failures;
+	__le32 count_rx_mic_failures;
+	__le32 count_rx_no_key_failures;
+	__le32 count_tx_multicast_frames;
+	__le32 count_tx_frames_success;
+	__le32 count_tx_frame_failures;
+	__le32 count_tx_frames_retried;
+	__le32 count_tx_frames_multi_retried;
+	__le32 count_rx_frame_duplicates;
+	__le32 count_rts_success;
+	__le32 count_rts_failures;
+	__le32 count_ack_failures;
+	__le32 count_rx_multicast_frames;
+	__le32 count_rx_frames_success;
+	__le32 count_rx_cmacicv_errors;
+	__le32 count_rx_cmac_replays;
+	__le32 count_rx_mgmt_ccmp_replays;
+	__le32 count_rx_bipmic_errors;
+	__le32 count_rx_beacon;
+	__le32 count_miss_beacon;
+	__le32 reserved[15];
 } __packed;
 
 struct hif_mib_count_table {
-	u32   count_plcp_errors;
-	u32   count_fcs_errors;
-	u32   count_tx_packets;
-	u32   count_rx_packets;
-	u32   count_rx_packet_errors;
-	u32   count_rx_decryption_failures;
-	u32   count_rx_mic_failures;
-	u32   count_rx_no_key_failures;
-	u32   count_tx_multicast_frames;
-	u32   count_tx_frames_success;
-	u32   count_tx_frame_failures;
-	u32   count_tx_frames_retried;
-	u32   count_tx_frames_multi_retried;
-	u32   count_rx_frame_duplicates;
-	u32   count_rts_success;
-	u32   count_rts_failures;
-	u32   count_ack_failures;
-	u32   count_rx_multicast_frames;
-	u32   count_rx_frames_success;
-	u32   count_rx_cmacicv_errors;
-	u32   count_rx_cmac_replays;
-	u32   count_rx_mgmt_ccmp_replays;
-	u32   count_rx_bipmic_errors;
-} __packed;
-
-struct hif_mib_max_tx_power_level {
-	s32       max_tx_power_level_rf_port1;
-	s32       max_tx_power_level_rf_port2;
-} __packed;
-
-struct hif_mib_beacon_stats {
-	s32     latest_tbtt_diff;
-	u32    reserved[4];
+	__le32 count_plcp_errors;
+	__le32 count_fcs_errors;
+	__le32 count_tx_packets;
+	__le32 count_rx_packets;
+	__le32 count_rx_packet_errors;
+	__le32 count_rx_decryption_failures;
+	__le32 count_rx_mic_failures;
+	__le32 count_rx_no_key_failures;
+	__le32 count_tx_multicast_frames;
+	__le32 count_tx_frames_success;
+	__le32 count_tx_frame_failures;
+	__le32 count_tx_frames_retried;
+	__le32 count_tx_frames_multi_retried;
+	__le32 count_rx_frame_duplicates;
+	__le32 count_rts_success;
+	__le32 count_rts_failures;
+	__le32 count_ack_failures;
+	__le32 count_rx_multicast_frames;
+	__le32 count_rx_frames_success;
+	__le32 count_rx_cmacicv_errors;
+	__le32 count_rx_cmac_replays;
+	__le32 count_rx_mgmt_ccmp_replays;
+	__le32 count_rx_bipmic_errors;
 } __packed;
 
 struct hif_mib_mac_address {
-	u8    mac_addr[ETH_ALEN];
-	u16   reserved;
-} __packed;
-
-struct hif_mib_dot11_max_transmit_msdu_lifetime {
-	u32   max_life_time;
-} __packed;
-
-struct hif_mib_dot11_max_receive_lifetime {
-	u32   max_life_time;
+	u8     mac_addr[ETH_ALEN];
+	__le16 reserved;
 } __packed;
 
 struct hif_mib_wep_default_key_id {
-	u8    wep_default_key_id;
-	u8    reserved[3];
+	u8     wep_default_key_id;
+	u8     reserved[3];
 } __packed;
 
 struct hif_mib_dot11_rts_threshold {
-	u32   threshold;
+	__le32 threshold;
 } __packed;
 
 struct hif_mib_slot_time {
-	u32   slot_time;
+	__le32 slot_time;
 } __packed;
 
 struct hif_mib_current_tx_power_level {
-	s32   power_level;
+	__le32 power_level; // signed value
 } __packed;
 
 struct hif_mib_non_erp_protection {
-	u8   use_cts_to_self:1;
-	u8   reserved1:7;
-	u8   reserved2[3];
+	u8     use_cts_to_self:1;
+	u8     reserved1:7;
+	u8     reserved2[3];
 } __packed;
 
 enum hif_tmplt {
-	HIF_TMPLT_PRBREQ                           = 0x0,
-	HIF_TMPLT_BCN                              = 0x1,
-	HIF_TMPLT_NULL                             = 0x2,
-	HIF_TMPLT_QOSNUL                           = 0x3,
-	HIF_TMPLT_PSPOLL                           = 0x4,
-	HIF_TMPLT_PRBRES                           = 0x5,
-	HIF_TMPLT_ARP                              = 0x6,
-	HIF_TMPLT_NA                               = 0x7
+	HIF_TMPLT_PRBREQ = 0x0,
+	HIF_TMPLT_BCN    = 0x1,
+	HIF_TMPLT_NULL   = 0x2,
+	HIF_TMPLT_QOSNUL = 0x3,
+	HIF_TMPLT_PSPOLL = 0x4,
+	HIF_TMPLT_PRBRES = 0x5,
+	HIF_TMPLT_ARP    = 0x6,
+	HIF_TMPLT_NA     = 0x7
 };
 
-#define HIF_API_MAX_TEMPLATE_FRAME_SIZE                              700
+#define HIF_API_MAX_TEMPLATE_FRAME_SIZE 700
 
 struct hif_mib_template_frame {
-	u8    frame_type;
-	u8    init_rate:7;
-	u8    mode:1;
-	u16   frame_length;
-	u8    frame[HIF_API_MAX_TEMPLATE_FRAME_SIZE];
+	u8     frame_type;
+	u8     init_rate:7;
+	u8     mode:1;
+	__le16 frame_length;
+	u8     frame[];
 } __packed;
 
 struct hif_mib_beacon_wake_up_period {
-	u8    wakeup_period_min;
-	u8    receive_dtim:1;
-	u8    reserved1:7;
-	u8    wakeup_period_max;
-	u8    reserved2;
+	u8     wakeup_period_min;
+	u8     receive_dtim:1;
+	u8     reserved1:7;
+	u8     wakeup_period_max;
+	u8     reserved2;
 } __packed;
 
 struct hif_mib_rcpi_rssi_threshold {
-	u8    detection:1;
-	u8    rcpi_rssi:1;
-	u8    upperthresh:1;
-	u8    lowerthresh:1;
-	u8    reserved:4;
-	u8    lower_threshold;
-	u8    upper_threshold;
-	u8    rolling_average_count;
+	u8     detection:1;
+	u8     rcpi_rssi:1;
+	u8     upperthresh:1;
+	u8     lowerthresh:1;
+	u8     reserved:4;
+	u8     lower_threshold;
+	u8     upper_threshold;
+	u8     rolling_average_count;
 } __packed;
 
 #define DEFAULT_BA_MAX_RX_BUFFER_SIZE 16
 
 struct hif_mib_block_ack_policy {
-	u8    block_ack_tx_tid_policy;
-	u8    reserved1;
-	u8    block_ack_rx_tid_policy;
-	u8    block_ack_rx_max_buffer_size;
-} __packed;
-
-struct hif_mib_override_int_rate {
-	u8    internal_tx_rate;
-	u8    non_erp_internal_tx_rate;
-	u8    reserved[2];
+	u8     block_ack_tx_tid_policy;
+	u8     reserved1;
+	u8     block_ack_rx_tid_policy;
+	u8     block_ack_rx_max_buffer_size;
 } __packed;
 
 enum hif_mpdu_start_spacing {
-	HIF_MPDU_START_SPACING_NO_RESTRIC          = 0x0,
-	HIF_MPDU_START_SPACING_QUARTER             = 0x1,
-	HIF_MPDU_START_SPACING_HALF                = 0x2,
-	HIF_MPDU_START_SPACING_ONE                 = 0x3,
-	HIF_MPDU_START_SPACING_TWO                 = 0x4,
-	HIF_MPDU_START_SPACING_FOUR                = 0x5,
-	HIF_MPDU_START_SPACING_EIGHT               = 0x6,
-	HIF_MPDU_START_SPACING_SIXTEEN             = 0x7
+	HIF_MPDU_START_SPACING_NO_RESTRIC = 0x0,
+	HIF_MPDU_START_SPACING_QUARTER    = 0x1,
+	HIF_MPDU_START_SPACING_HALF       = 0x2,
+	HIF_MPDU_START_SPACING_ONE        = 0x3,
+	HIF_MPDU_START_SPACING_TWO        = 0x4,
+	HIF_MPDU_START_SPACING_FOUR       = 0x5,
+	HIF_MPDU_START_SPACING_EIGHT      = 0x6,
+	HIF_MPDU_START_SPACING_SIXTEEN    = 0x7
 };
 
 struct hif_mib_set_association_mode {
-	u8    preambtype_use:1;
-	u8    mode:1;
-	u8    rateset:1;
-	u8    spacing:1;
-	u8    reserved1:4;
-	u8    short_preamble:1;
-	u8    reserved2:7;
-	u8    greenfield:1;
-	u8    reserved3:7;
-	u8    mpdu_start_spacing;
-	u32   basic_rate_set;
+	u8     preambtype_use:1;
+	u8     mode:1;
+	u8     rateset:1;
+	u8     spacing:1;
+	u8     reserved1:4;
+	u8     short_preamble:1;
+	u8     reserved2:7;
+	u8     greenfield:1;
+	u8     reserved3:7;
+	u8     mpdu_start_spacing;
+	__le32 basic_rate_set;
 } __packed;
 
 struct hif_mib_set_uapsd_information {
-	u8    trig_bckgrnd:1;
-	u8    trig_be:1;
-	u8    trig_video:1;
-	u8    trig_voice:1;
-	u8    reserved1:4;
-	u8    deliv_bckgrnd:1;
-	u8    deliv_be:1;
-	u8    deliv_video:1;
-	u8    deliv_voice:1;
-	u8    reserved2:4;
-	u16   min_auto_trigger_interval;
-	u16   max_auto_trigger_interval;
-	u16   auto_trigger_step;
+	u8     trig_bckgrnd:1;
+	u8     trig_be:1;
+	u8     trig_video:1;
+	u8     trig_voice:1;
+	u8     reserved1:4;
+	u8     deliv_bckgrnd:1;
+	u8     deliv_be:1;
+	u8     deliv_video:1;
+	u8     deliv_voice:1;
+	u8     reserved2:4;
+	__le16 min_auto_trigger_interval;
+	__le16 max_auto_trigger_interval;
+	__le16 auto_trigger_step;
 } __packed;
 
 struct hif_mib_tx_rate_retry_policy {
-	u8    policy_index;
-	u8    short_retry_count;
-	u8    long_retry_count;
-	u8    first_rate_sel:2;
-	u8    terminate:1;
-	u8    count_init:1;
-	u8    reserved1:4;
-	u8    rate_recovery_count;
-	u8    reserved2[3];
-	u8    rates[12];
+	u8     policy_index;
+	u8     short_retry_count;
+	u8     long_retry_count;
+	u8     first_rate_sel:2;
+	u8     terminate:1;
+	u8     count_init:1;
+	u8     reserved1:4;
+	u8     rate_recovery_count;
+	u8     reserved2[3];
+	u8     rates[12];
 } __packed;
 
-#define HIF_MIB_NUM_TX_RATE_RETRY_POLICIES    15
+#define HIF_TX_RETRY_POLICY_MAX     15
+#define HIF_TX_RETRY_POLICY_INVALID HIF_TX_RETRY_POLICY_MAX
 
 struct hif_mib_set_tx_rate_retry_policy {
-	u8    num_tx_rate_policies;
-	u8    reserved[3];
+	u8     num_tx_rate_policies;
+	u8     reserved[3];
 	struct hif_mib_tx_rate_retry_policy tx_rate_retry_policy[];
 } __packed;
 
 struct hif_mib_protected_mgmt_policy {
-	u8   pmf_enable:1;
-	u8   unpmf_allowed:1;
-	u8   host_enc_auth_frames:1;
-	u8   reserved1:5;
-	u8   reserved2[3];
+	u8     pmf_enable:1;
+	u8     unpmf_allowed:1;
+	u8     host_enc_auth_frames:1;
+	u8     reserved1:5;
+	u8     reserved2[3];
 } __packed;
 
 struct hif_mib_set_ht_protection {
-	u8   dual_cts_prot:1;
-	u8   reserved1:7;
-	u8   reserved2[3];
+	u8     dual_cts_prot:1;
+	u8     reserved1:7;
+	u8     reserved2[3];
 } __packed;
 
 struct hif_mib_keep_alive_period {
-	u16   keep_alive_period;
-	u8    reserved[2];
-} __packed;
-
-struct hif_mib_arp_keep_alive_period {
-	u16   arp_keep_alive_period;
-	u8    encr_type;
-	u8    reserved;
-	u8    sender_ipv4_address[HIF_API_IPV4_ADDRESS_SIZE];
-	u8    target_ipv4_address[HIF_API_IPV4_ADDRESS_SIZE];
-} __packed;
-
-struct hif_mib_inactivity_timer {
-	u8    min_active_time;
-	u8    max_active_time;
-	u16   reserved;
-} __packed;
-
-struct hif_mib_interface_protection {
-	u8   use_cts_prot:1;
-	u8   reserved1:7;
-	u8   reserved2[3];
+	__le16 keep_alive_period;
+	u8     reserved[2];
 } __packed;
 
 #endif
diff --git a/drivers/staging/wfx/hif_tx.c b/drivers/staging/wfx/hif_tx.c
index 77bca43aca42..f49ab67e1a6d 100644
--- a/drivers/staging/wfx/hif_tx.c
+++ b/drivers/staging/wfx/hif_tx.c
@@ -296,7 +296,10 @@ int hif_join(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf,
 	struct hif_msg *hif;
 	struct hif_req_join *body = wfx_alloc_hif(sizeof(*body), &hif);
 
+	WARN_ON(!conf->beacon_int);
 	WARN_ON(!conf->basic_rates);
+	WARN_ON(sizeof(body->ssid) < ssidlen);
+	WARN(!conf->ibss_joined && !ssidlen, "joining an unknown BSS");
 	body->infrastructure_bss_mode = !conf->ibss_joined;
 	body->short_preamble = conf->use_short_preamble;
 	if (channel && channel->flags & IEEE80211_CHAN_NO_IR)
@@ -308,7 +311,7 @@ int hif_join(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf,
 	body->basic_rate_set =
 		cpu_to_le32(wfx_rate_mask_to_hw(wvif->wdev, conf->basic_rates));
 	memcpy(body->bssid, conf->bssid, sizeof(body->bssid));
-	if (!conf->ibss_joined && ssid) {
+	if (ssid) {
 		body->ssid_length = cpu_to_le32(ssidlen);
 		memcpy(body->ssid, ssid, ssidlen);
 	}
@@ -428,6 +431,7 @@ int hif_start(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf,
 	struct hif_msg *hif;
 	struct hif_req_start *body = wfx_alloc_hif(sizeof(*body), &hif);
 
+	WARN_ON(!conf->beacon_int);
 	body->dtim_period = conf->dtim_period;
 	body->short_preamble = conf->use_short_preamble;
 	body->channel_number = cpu_to_le16(channel->hw_value);
diff --git a/drivers/staging/wfx/hif_tx_mib.c b/drivers/staging/wfx/hif_tx_mib.c
new file mode 100644
index 000000000000..41f3090d29be
--- /dev/null
+++ b/drivers/staging/wfx/hif_tx_mib.c
@@ -0,0 +1,397 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Implementation of host-to-chip MIBs of WFxxx Split Mac (WSM) API.
+ *
+ * Copyright (c) 2017-2019, Silicon Laboratories, Inc.
+ * Copyright (c) 2010, ST-Ericsson
+ * Copyright (C) 2010, ST-Ericsson SA
+ */
+
+#include <linux/etherdevice.h>
+
+#include "wfx.h"
+#include "hif_tx.h"
+#include "hif_tx_mib.h"
+#include "hif_api_mib.h"
+
+int hif_set_output_power(struct wfx_vif *wvif, int val)
+{
+	struct hif_mib_current_tx_power_level arg = {
+		.power_level = cpu_to_le32(val * 10),
+	};
+
+	return hif_write_mib(wvif->wdev, wvif->id,
+			     HIF_MIB_ID_CURRENT_TX_POWER_LEVEL,
+			     &arg, sizeof(arg));
+}
+
+int hif_set_beacon_wakeup_period(struct wfx_vif *wvif,
+				 unsigned int dtim_interval,
+				 unsigned int listen_interval)
+{
+	struct hif_mib_beacon_wake_up_period val = {
+		.wakeup_period_min = dtim_interval,
+		.receive_dtim = 0,
+		.wakeup_period_max = cpu_to_le16(listen_interval),
+	};
+
+	if (dtim_interval > 0xFF || listen_interval > 0xFFFF)
+		return -EINVAL;
+	return hif_write_mib(wvif->wdev, wvif->id,
+			     HIF_MIB_ID_BEACON_WAKEUP_PERIOD,
+			     &val, sizeof(val));
+}
+
+int hif_set_rcpi_rssi_threshold(struct wfx_vif *wvif,
+				int rssi_thold, int rssi_hyst)
+{
+	struct hif_mib_rcpi_rssi_threshold arg = {
+		.rolling_average_count = 8,
+		.detection = 1,
+	};
+
+	if (!rssi_thold && !rssi_hyst) {
+		arg.upperthresh = 1;
+		arg.lowerthresh = 1;
+	} else {
+		arg.upper_threshold = rssi_thold + rssi_hyst;
+		arg.upper_threshold = (arg.upper_threshold + 110) * 2;
+		arg.lower_threshold = rssi_thold;
+		arg.lower_threshold = (arg.lower_threshold + 110) * 2;
+	}
+
+	return hif_write_mib(wvif->wdev, wvif->id,
+			     HIF_MIB_ID_RCPI_RSSI_THRESHOLD, &arg, sizeof(arg));
+}
+
+int hif_get_counters_table(struct wfx_dev *wdev,
+			   struct hif_mib_extended_count_table *arg)
+{
+	if (wfx_api_older_than(wdev, 1, 3)) {
+		// extended_count_table is wider than count_table
+		memset(arg, 0xFF, sizeof(*arg));
+		return hif_read_mib(wdev, 0, HIF_MIB_ID_COUNTERS_TABLE,
+				    arg, sizeof(struct hif_mib_count_table));
+	} else {
+		return hif_read_mib(wdev, 0,
+				    HIF_MIB_ID_EXTENDED_COUNTERS_TABLE, arg,
+				sizeof(struct hif_mib_extended_count_table));
+	}
+}
+
+int hif_set_macaddr(struct wfx_vif *wvif, u8 *mac)
+{
+	struct hif_mib_mac_address msg = { };
+
+	if (mac)
+		ether_addr_copy(msg.mac_addr, mac);
+	return hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_DOT11_MAC_ADDRESS,
+			     &msg, sizeof(msg));
+}
+
+int hif_set_rx_filter(struct wfx_vif *wvif,
+		      bool filter_bssid, bool fwd_probe_req)
+{
+	struct hif_mib_rx_filter val = { };
+
+	if (filter_bssid)
+		val.bssid_filter = 1;
+	if (fwd_probe_req)
+		val.fwd_probe_req = 1;
+	return hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_RX_FILTER,
+			     &val, sizeof(val));
+}
+
+int hif_set_beacon_filter_table(struct wfx_vif *wvif, int tbl_len,
+				const struct hif_ie_table_entry *tbl)
+{
+	int ret;
+	struct hif_mib_bcn_filter_table *val;
+	int buf_len = struct_size(val, ie_table, tbl_len);
+
+	val = kzalloc(buf_len, GFP_KERNEL);
+	if (!val)
+		return -ENOMEM;
+	val->num_of_info_elmts = cpu_to_le32(tbl_len);
+	memcpy(val->ie_table, tbl, tbl_len * sizeof(*tbl));
+	ret = hif_write_mib(wvif->wdev, wvif->id,
+			    HIF_MIB_ID_BEACON_FILTER_TABLE, val, buf_len);
+	kfree(val);
+	return ret;
+}
+
+int hif_beacon_filter_control(struct wfx_vif *wvif,
+			      int enable, int beacon_count)
+{
+	struct hif_mib_bcn_filter_enable arg = {
+		.enable = cpu_to_le32(enable),
+		.bcn_count = cpu_to_le32(beacon_count),
+	};
+	return hif_write_mib(wvif->wdev, wvif->id,
+			     HIF_MIB_ID_BEACON_FILTER_ENABLE,
+			     &arg, sizeof(arg));
+}
+
+int hif_set_operational_mode(struct wfx_dev *wdev, enum hif_op_power_mode mode)
+{
+	struct hif_mib_gl_operational_power_mode val = {
+		.power_mode = mode,
+		.wup_ind_activation = 1,
+	};
+
+	return hif_write_mib(wdev, -1, HIF_MIB_ID_GL_OPERATIONAL_POWER_MODE,
+			     &val, sizeof(val));
+}
+
+int hif_set_template_frame(struct wfx_vif *wvif, struct sk_buff *skb,
+			   u8 frame_type, int init_rate)
+{
+	struct hif_mib_template_frame *arg;
+
+	WARN(skb->len > HIF_API_MAX_TEMPLATE_FRAME_SIZE, "frame is too big");
+	skb_push(skb, 4);
+	arg = (struct hif_mib_template_frame *)skb->data;
+	skb_pull(skb, 4);
+	arg->init_rate = init_rate;
+	arg->frame_type = frame_type;
+	arg->frame_length = cpu_to_le16(skb->len);
+	return hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_TEMPLATE_FRAME,
+			     arg, sizeof(*arg) + skb->len);
+}
+
+int hif_set_mfp(struct wfx_vif *wvif, bool capable, bool required)
+{
+	struct hif_mib_protected_mgmt_policy val = { };
+
+	WARN(required && !capable, "incoherent arguments");
+	if (capable) {
+		val.pmf_enable = 1;
+		val.host_enc_auth_frames = 1;
+	}
+	if (!required)
+		val.unpmf_allowed = 1;
+	return hif_write_mib(wvif->wdev, wvif->id,
+			     HIF_MIB_ID_PROTECTED_MGMT_POLICY,
+			     &val, sizeof(val));
+}
+
+int hif_set_block_ack_policy(struct wfx_vif *wvif,
+			     u8 tx_tid_policy, u8 rx_tid_policy)
+{
+	struct hif_mib_block_ack_policy val = {
+		.block_ack_tx_tid_policy = tx_tid_policy,
+		.block_ack_rx_tid_policy = rx_tid_policy,
+	};
+
+	return hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_BLOCK_ACK_POLICY,
+			     &val, sizeof(val));
+}
+
+int hif_set_association_mode(struct wfx_vif *wvif,
+			     struct ieee80211_bss_conf *info)
+{
+	int basic_rates = wfx_rate_mask_to_hw(wvif->wdev, info->basic_rates);
+	struct ieee80211_sta *sta = NULL;
+	struct hif_mib_set_association_mode val = {
+		.preambtype_use = 1,
+		.mode = 1,
+		.rateset = 1,
+		.spacing = 1,
+		.short_preamble = info->use_short_preamble,
+		.basic_rate_set = cpu_to_le32(basic_rates)
+	};
+
+	rcu_read_lock(); // protect sta
+	if (info->bssid && !info->ibss_joined)
+		sta = ieee80211_find_sta(wvif->vif, info->bssid);
+
+	// FIXME: it is strange to not retrieve all information from bss_info
+	if (sta && sta->ht_cap.ht_supported) {
+		val.mpdu_start_spacing = sta->ht_cap.ampdu_density;
+		if (!(info->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT))
+			val.greenfield = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD);
+	}
+	rcu_read_unlock();
+
+	return hif_write_mib(wvif->wdev, wvif->id,
+			     HIF_MIB_ID_SET_ASSOCIATION_MODE, &val, sizeof(val));
+}
+
+int hif_set_tx_rate_retry_policy(struct wfx_vif *wvif,
+				 int policy_index, uint8_t *rates)
+{
+	struct hif_mib_set_tx_rate_retry_policy *arg;
+	size_t size = struct_size(arg, tx_rate_retry_policy, 1);
+	int ret;
+
+	arg = kzalloc(size, GFP_KERNEL);
+	arg->num_tx_rate_policies = 1;
+	arg->tx_rate_retry_policy[0].policy_index = policy_index;
+	arg->tx_rate_retry_policy[0].short_retry_count = 255;
+	arg->tx_rate_retry_policy[0].long_retry_count = 255;
+	arg->tx_rate_retry_policy[0].first_rate_sel = 1;
+	arg->tx_rate_retry_policy[0].terminate = 1;
+	arg->tx_rate_retry_policy[0].count_init = 1;
+	memcpy(&arg->tx_rate_retry_policy[0].rates, rates,
+	       sizeof(arg->tx_rate_retry_policy[0].rates));
+	ret = hif_write_mib(wvif->wdev, wvif->id,
+			    HIF_MIB_ID_SET_TX_RATE_RETRY_POLICY, arg, size);
+	kfree(arg);
+	return ret;
+}
+
+int hif_set_mac_addr_condition(struct wfx_vif *wvif,
+			       int idx, const u8 *mac_addr)
+{
+	struct hif_mib_mac_addr_data_frame_condition val = {
+		.condition_idx = idx,
+		.address_type = HIF_MAC_ADDR_A1,
+	};
+
+	ether_addr_copy(val.mac_address, mac_addr);
+	return hif_write_mib(wvif->wdev, wvif->id,
+			     HIF_MIB_ID_MAC_ADDR_DATAFRAME_CONDITION,
+			     &val, sizeof(val));
+}
+
+int hif_set_uc_mc_bc_condition(struct wfx_vif *wvif, int idx, u8 allowed_frames)
+{
+	struct hif_mib_uc_mc_bc_data_frame_condition val = {
+		.condition_idx = idx,
+		.allowed_frames = allowed_frames,
+	};
+
+	return hif_write_mib(wvif->wdev, wvif->id,
+			     HIF_MIB_ID_UC_MC_BC_DATAFRAME_CONDITION,
+			     &val, sizeof(val));
+}
+
+int hif_set_config_data_filter(struct wfx_vif *wvif, bool enable, int idx,
+			       int mac_filters, int frames_types_filters)
+{
+	struct hif_mib_config_data_filter val = {
+		.enable = enable,
+		.filter_idx = idx,
+		.mac_cond = mac_filters,
+		.uc_mc_bc_cond = frames_types_filters,
+	};
+
+	return hif_write_mib(wvif->wdev, wvif->id,
+			     HIF_MIB_ID_CONFIG_DATA_FILTER, &val, sizeof(val));
+}
+
+int hif_set_data_filtering(struct wfx_vif *wvif, bool enable, bool invert)
+{
+	struct hif_mib_set_data_filtering val = {
+		.enable = enable,
+		.invert_matching = invert,
+	};
+
+	return hif_write_mib(wvif->wdev, wvif->id,
+			     HIF_MIB_ID_SET_DATA_FILTERING, &val, sizeof(val));
+}
+
+int hif_keep_alive_period(struct wfx_vif *wvif, int period)
+{
+	struct hif_mib_keep_alive_period arg = {
+		.keep_alive_period = cpu_to_le16(period),
+	};
+
+	return hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_KEEP_ALIVE_PERIOD,
+			     &arg, sizeof(arg));
+};
+
+int hif_set_arp_ipv4_filter(struct wfx_vif *wvif, int idx, __be32 *addr)
+{
+	struct hif_mib_arp_ip_addr_table arg = {
+		.condition_idx = idx,
+		.arp_enable = HIF_ARP_NS_FILTERING_DISABLE,
+	};
+
+	if (addr) {
+		// Caution: type of addr is __be32
+		memcpy(arg.ipv4_address, addr, sizeof(arg.ipv4_address));
+		arg.arp_enable = HIF_ARP_NS_FILTERING_ENABLE;
+	}
+	return hif_write_mib(wvif->wdev, wvif->id,
+			     HIF_MIB_ID_ARP_IP_ADDRESSES_TABLE,
+			     &arg, sizeof(arg));
+}
+
+int hif_use_multi_tx_conf(struct wfx_dev *wdev, bool enable)
+{
+	struct hif_mib_gl_set_multi_msg arg = {
+		.enable_multi_tx_conf = enable,
+	};
+
+	return hif_write_mib(wdev, -1, HIF_MIB_ID_GL_SET_MULTI_MSG,
+			     &arg, sizeof(arg));
+}
+
+int hif_set_uapsd_info(struct wfx_vif *wvif, unsigned long val)
+{
+	struct hif_mib_set_uapsd_information arg = { };
+
+	if (val & BIT(IEEE80211_AC_VO))
+		arg.trig_voice = 1;
+	if (val & BIT(IEEE80211_AC_VI))
+		arg.trig_video = 1;
+	if (val & BIT(IEEE80211_AC_BE))
+		arg.trig_be = 1;
+	if (val & BIT(IEEE80211_AC_BK))
+		arg.trig_bckgrnd = 1;
+	return hif_write_mib(wvif->wdev, wvif->id,
+			     HIF_MIB_ID_SET_UAPSD_INFORMATION,
+			     &arg, sizeof(arg));
+}
+
+int hif_erp_use_protection(struct wfx_vif *wvif, bool enable)
+{
+	struct hif_mib_non_erp_protection arg = {
+		.use_cts_to_self = enable,
+	};
+
+	return hif_write_mib(wvif->wdev, wvif->id,
+			     HIF_MIB_ID_NON_ERP_PROTECTION, &arg, sizeof(arg));
+}
+
+int hif_slot_time(struct wfx_vif *wvif, int val)
+{
+	struct hif_mib_slot_time arg = {
+		.slot_time = cpu_to_le32(val),
+	};
+
+	return hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_SLOT_TIME,
+			     &arg, sizeof(arg));
+}
+
+int hif_dual_cts_protection(struct wfx_vif *wvif, bool enable)
+{
+	struct hif_mib_set_ht_protection arg = {
+		.dual_cts_prot = enable,
+	};
+
+	return hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_SET_HT_PROTECTION,
+			     &arg, sizeof(arg));
+}
+
+int hif_wep_default_key_id(struct wfx_vif *wvif, int val)
+{
+	struct hif_mib_wep_default_key_id arg = {
+		.wep_default_key_id = val,
+	};
+
+	return hif_write_mib(wvif->wdev, wvif->id,
+			     HIF_MIB_ID_DOT11_WEP_DEFAULT_KEY_ID,
+			     &arg, sizeof(arg));
+}
+
+int hif_rts_threshold(struct wfx_vif *wvif, int val)
+{
+	struct hif_mib_dot11_rts_threshold arg = {
+		.threshold = cpu_to_le32(val >= 0 ? val : 0xFFFF),
+	};
+
+	return hif_write_mib(wvif->wdev, wvif->id,
+			     HIF_MIB_ID_DOT11_RTS_THRESHOLD, &arg, sizeof(arg));
+}
diff --git a/drivers/staging/wfx/hif_tx_mib.h b/drivers/staging/wfx/hif_tx_mib.h
index 26b1406f9f6c..0f8b3bd9f14e 100644
--- a/drivers/staging/wfx/hif_tx_mib.h
+++ b/drivers/staging/wfx/hif_tx_mib.h
@@ -9,398 +9,51 @@
 #ifndef WFX_HIF_TX_MIB_H
 #define WFX_HIF_TX_MIB_H
 
-#include <linux/etherdevice.h>
-
-#include "wfx.h"
-#include "hif_tx.h"
 #include "hif_api_mib.h"
 
-static inline int hif_set_output_power(struct wfx_vif *wvif, int val)
-{
-	struct hif_mib_current_tx_power_level arg = {
-		.power_level = cpu_to_le32(val * 10),
-	};
-
-	return hif_write_mib(wvif->wdev, wvif->id,
-			     HIF_MIB_ID_CURRENT_TX_POWER_LEVEL,
-			     &arg, sizeof(arg));
-}
-
-static inline int hif_set_beacon_wakeup_period(struct wfx_vif *wvif,
-					       unsigned int dtim_interval,
-					       unsigned int listen_interval)
-{
-	struct hif_mib_beacon_wake_up_period val = {
-		.wakeup_period_min = dtim_interval,
-		.receive_dtim = 0,
-		.wakeup_period_max = cpu_to_le16(listen_interval),
-	};
-
-	if (dtim_interval > 0xFF || listen_interval > 0xFFFF)
-		return -EINVAL;
-	return hif_write_mib(wvif->wdev, wvif->id,
-			     HIF_MIB_ID_BEACON_WAKEUP_PERIOD,
-			     &val, sizeof(val));
-}
-
-static inline int hif_set_rcpi_rssi_threshold(struct wfx_vif *wvif,
-					      int rssi_thold, int rssi_hyst)
-{
-	struct hif_mib_rcpi_rssi_threshold arg = {
-		.rolling_average_count = 8,
-		.detection = 1,
-	};
-
-	if (!rssi_thold && !rssi_hyst) {
-		arg.upperthresh = 1;
-		arg.lowerthresh = 1;
-	} else {
-		arg.upper_threshold = rssi_thold + rssi_hyst;
-		arg.upper_threshold = (arg.upper_threshold + 110) * 2;
-		arg.lower_threshold = rssi_thold;
-		arg.lower_threshold = (arg.lower_threshold + 110) * 2;
-	}
-
-	return hif_write_mib(wvif->wdev, wvif->id,
-			     HIF_MIB_ID_RCPI_RSSI_THRESHOLD, &arg, sizeof(arg));
-}
-
-static inline int hif_get_counters_table(struct wfx_dev *wdev,
-					 struct hif_mib_extended_count_table *arg)
-{
-	if (wfx_api_older_than(wdev, 1, 3)) {
-		// extended_count_table is wider than count_table
-		memset(arg, 0xFF, sizeof(*arg));
-		return hif_read_mib(wdev, 0, HIF_MIB_ID_COUNTERS_TABLE,
-				    arg, sizeof(struct hif_mib_count_table));
-	} else {
-		return hif_read_mib(wdev, 0,
-				    HIF_MIB_ID_EXTENDED_COUNTERS_TABLE, arg,
-				sizeof(struct hif_mib_extended_count_table));
-	}
-}
-
-static inline int hif_set_macaddr(struct wfx_vif *wvif, u8 *mac)
-{
-	struct hif_mib_mac_address msg = { };
-
-	if (mac)
-		ether_addr_copy(msg.mac_addr, mac);
-	return hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_DOT11_MAC_ADDRESS,
-			     &msg, sizeof(msg));
-}
-
-static inline int hif_set_rx_filter(struct wfx_vif *wvif, bool filter_bssid,
-				    bool fwd_probe_req)
-{
-	struct hif_mib_rx_filter val = { };
-
-	if (filter_bssid)
-		val.bssid_filter = 1;
-	if (fwd_probe_req)
-		val.fwd_probe_req = 1;
-	return hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_RX_FILTER,
-			     &val, sizeof(val));
-}
-
-static inline int hif_set_beacon_filter_table(struct wfx_vif *wvif,
-					      int tbl_len,
-					      struct hif_ie_table_entry *tbl)
-{
-	int ret;
-	struct hif_mib_bcn_filter_table *val;
-	int buf_len = struct_size(val, ie_table, tbl_len);
-
-	val = kzalloc(buf_len, GFP_KERNEL);
-	if (!val)
-		return -ENOMEM;
-	val->num_of_info_elmts = cpu_to_le32(tbl_len);
-	memcpy(val->ie_table, tbl, tbl_len * sizeof(*tbl));
-	ret = hif_write_mib(wvif->wdev, wvif->id,
-			    HIF_MIB_ID_BEACON_FILTER_TABLE, val, buf_len);
-	kfree(val);
-	return ret;
-}
-
-static inline int hif_beacon_filter_control(struct wfx_vif *wvif,
-					    int enable, int beacon_count)
-{
-	struct hif_mib_bcn_filter_enable arg = {
-		.enable = cpu_to_le32(enable),
-		.bcn_count = cpu_to_le32(beacon_count),
-	};
-	return hif_write_mib(wvif->wdev, wvif->id,
-			     HIF_MIB_ID_BEACON_FILTER_ENABLE,
-			     &arg, sizeof(arg));
-}
-
-static inline int hif_set_operational_mode(struct wfx_dev *wdev,
-					   enum hif_op_power_mode mode)
-{
-	struct hif_mib_gl_operational_power_mode val = {
-		.power_mode = mode,
-		.wup_ind_activation = 1,
-	};
-
-	return hif_write_mib(wdev, -1, HIF_MIB_ID_GL_OPERATIONAL_POWER_MODE,
-			     &val, sizeof(val));
-}
-
-static inline int hif_set_template_frame(struct wfx_vif *wvif,
-					 struct sk_buff *skb,
-					 u8 frame_type, int init_rate)
-{
-	struct hif_mib_template_frame *arg;
-
-	skb_push(skb, 4);
-	arg = (struct hif_mib_template_frame *)skb->data;
-	skb_pull(skb, 4);
-	arg->init_rate = init_rate;
-	arg->frame_type = frame_type;
-	arg->frame_length = cpu_to_le16(skb->len);
-	return hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_TEMPLATE_FRAME,
-			     arg, sizeof(*arg));
-}
-
-static inline int hif_set_mfp(struct wfx_vif *wvif, bool capable, bool required)
-{
-	struct hif_mib_protected_mgmt_policy val = { };
-
-	WARN(required && !capable, "incoherent arguments");
-	if (capable) {
-		val.pmf_enable = 1;
-		val.host_enc_auth_frames = 1;
-	}
-	if (!required)
-		val.unpmf_allowed = 1;
-	return hif_write_mib(wvif->wdev, wvif->id,
-			     HIF_MIB_ID_PROTECTED_MGMT_POLICY,
-			     &val, sizeof(val));
-}
-
-static inline int hif_set_block_ack_policy(struct wfx_vif *wvif,
-					   u8 tx_tid_policy, u8 rx_tid_policy)
-{
-	struct hif_mib_block_ack_policy val = {
-		.block_ack_tx_tid_policy = tx_tid_policy,
-		.block_ack_rx_tid_policy = rx_tid_policy,
-	};
-
-	return hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_BLOCK_ACK_POLICY,
-			     &val, sizeof(val));
-}
-
-static inline int hif_set_association_mode(struct wfx_vif *wvif,
-					   struct ieee80211_bss_conf *info)
-{
-	int basic_rates = wfx_rate_mask_to_hw(wvif->wdev, info->basic_rates);
-	struct ieee80211_sta *sta = NULL;
-	struct hif_mib_set_association_mode val = {
-		.preambtype_use = 1,
-		.mode = 1,
-		.rateset = 1,
-		.spacing = 1,
-		.short_preamble = info->use_short_preamble,
-		.basic_rate_set = cpu_to_le32(basic_rates)
-	};
-
-	rcu_read_lock(); // protect sta
-	if (info->bssid && !info->ibss_joined)
-		sta = ieee80211_find_sta(wvif->vif, info->bssid);
-
-	// FIXME: it is strange to not retrieve all information from bss_info
-	if (sta && sta->ht_cap.ht_supported) {
-		val.mpdu_start_spacing = sta->ht_cap.ampdu_density;
-		if (!(info->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT))
-			val.greenfield = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD);
-	}
-	rcu_read_unlock();
-
-	return hif_write_mib(wvif->wdev, wvif->id,
-			     HIF_MIB_ID_SET_ASSOCIATION_MODE, &val, sizeof(val));
-}
-
-static inline int hif_set_tx_rate_retry_policy(struct wfx_vif *wvif,
-					       int policy_index, uint8_t *rates)
-{
-	struct hif_mib_set_tx_rate_retry_policy *arg;
-	size_t size = struct_size(arg, tx_rate_retry_policy, 1);
-	int ret;
-
-	arg = kzalloc(size, GFP_KERNEL);
-	arg->num_tx_rate_policies = 1;
-	arg->tx_rate_retry_policy[0].policy_index = policy_index;
-	arg->tx_rate_retry_policy[0].short_retry_count = 255;
-	arg->tx_rate_retry_policy[0].long_retry_count = 255;
-	arg->tx_rate_retry_policy[0].first_rate_sel = 1;
-	arg->tx_rate_retry_policy[0].terminate = 1;
-	arg->tx_rate_retry_policy[0].count_init = 1;
-	memcpy(&arg->tx_rate_retry_policy[0].rates, rates,
-	       sizeof(arg->tx_rate_retry_policy[0].rates));
-	ret = hif_write_mib(wvif->wdev, wvif->id,
-			    HIF_MIB_ID_SET_TX_RATE_RETRY_POLICY, arg, size);
-	kfree(arg);
-	return ret;
-}
-
-static inline int hif_set_mac_addr_condition(struct wfx_vif *wvif,
-					     int idx, const u8 *mac_addr)
-{
-	struct hif_mib_mac_addr_data_frame_condition val = {
-		.condition_idx = idx,
-		.address_type = HIF_MAC_ADDR_A1,
-	};
-
-	ether_addr_copy(val.mac_address, mac_addr);
-	return hif_write_mib(wvif->wdev, wvif->id,
-			     HIF_MIB_ID_MAC_ADDR_DATAFRAME_CONDITION,
-			     &val, sizeof(val));
-}
-
-static inline int hif_set_uc_mc_bc_condition(struct wfx_vif *wvif,
-					     int idx, u8 allowed_frames)
-{
-	struct hif_mib_uc_mc_bc_data_frame_condition val = {
-		.condition_idx = idx,
-		.allowed_frames = allowed_frames,
-	};
-
-	return hif_write_mib(wvif->wdev, wvif->id,
-			     HIF_MIB_ID_UC_MC_BC_DATAFRAME_CONDITION,
-			     &val, sizeof(val));
-}
-
-static inline int hif_set_config_data_filter(struct wfx_vif *wvif, bool enable,
-					     int idx, int mac_filters,
-					     int frames_types_filters)
-{
-	struct hif_mib_config_data_filter val = {
-		.enable = enable,
-		.filter_idx = idx,
-		.mac_cond = mac_filters,
-		.uc_mc_bc_cond = frames_types_filters,
-	};
-
-	return hif_write_mib(wvif->wdev, wvif->id,
-			     HIF_MIB_ID_CONFIG_DATA_FILTER, &val, sizeof(val));
-}
-
-static inline int hif_set_data_filtering(struct wfx_vif *wvif,
-					 bool enable, bool invert)
-{
-	struct hif_mib_set_data_filtering val = {
-		.enable = enable,
-		.invert_matching = invert,
-	};
-
-	return hif_write_mib(wvif->wdev, wvif->id,
-			     HIF_MIB_ID_SET_DATA_FILTERING, &val, sizeof(val));
-}
-
-static inline int hif_keep_alive_period(struct wfx_vif *wvif, int period)
-{
-	struct hif_mib_keep_alive_period arg = {
-		.keep_alive_period = cpu_to_le16(period),
-	};
-
-	return hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_KEEP_ALIVE_PERIOD,
-			     &arg, sizeof(arg));
-};
-
-static inline int hif_set_arp_ipv4_filter(struct wfx_vif *wvif, int idx,
-					  __be32 *addr)
-{
-	struct hif_mib_arp_ip_addr_table arg = {
-		.condition_idx = idx,
-		.arp_enable = HIF_ARP_NS_FILTERING_DISABLE,
-	};
-
-	if (addr) {
-		// Caution: type of addr is __be32
-		memcpy(arg.ipv4_address, addr, sizeof(arg.ipv4_address));
-		arg.arp_enable = HIF_ARP_NS_FILTERING_ENABLE;
-	}
-	return hif_write_mib(wvif->wdev, wvif->id,
-			     HIF_MIB_ID_ARP_IP_ADDRESSES_TABLE,
-			     &arg, sizeof(arg));
-}
-
-static inline int hif_use_multi_tx_conf(struct wfx_dev *wdev, bool enable)
-{
-	struct hif_mib_gl_set_multi_msg arg = {
-		.enable_multi_tx_conf = enable,
-	};
-
-	return hif_write_mib(wdev, -1, HIF_MIB_ID_GL_SET_MULTI_MSG,
-			     &arg, sizeof(arg));
-}
-
-static inline int hif_set_uapsd_info(struct wfx_vif *wvif, unsigned long val)
-{
-	struct hif_mib_set_uapsd_information arg = { };
-
-	if (val & BIT(IEEE80211_AC_VO))
-		arg.trig_voice = 1;
-	if (val & BIT(IEEE80211_AC_VI))
-		arg.trig_video = 1;
-	if (val & BIT(IEEE80211_AC_BE))
-		arg.trig_be = 1;
-	if (val & BIT(IEEE80211_AC_BK))
-		arg.trig_bckgrnd = 1;
-	return hif_write_mib(wvif->wdev, wvif->id,
-			     HIF_MIB_ID_SET_UAPSD_INFORMATION,
-			     &arg, sizeof(arg));
-}
-
-static inline int hif_erp_use_protection(struct wfx_vif *wvif, bool enable)
-{
-	struct hif_mib_non_erp_protection arg = {
-		.use_cts_to_self = enable,
-	};
-
-	return hif_write_mib(wvif->wdev, wvif->id,
-			     HIF_MIB_ID_NON_ERP_PROTECTION, &arg, sizeof(arg));
-}
-
-static inline int hif_slot_time(struct wfx_vif *wvif, int val)
-{
-	struct hif_mib_slot_time arg = {
-		.slot_time = cpu_to_le32(val),
-	};
-
-	return hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_SLOT_TIME,
-			     &arg, sizeof(arg));
-}
-
-static inline int hif_dual_cts_protection(struct wfx_vif *wvif, bool enable)
-{
-	struct hif_mib_set_ht_protection arg = {
-		.dual_cts_prot = enable,
-	};
-
-	return hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_SET_HT_PROTECTION,
-			     &arg, sizeof(arg));
-}
-
-static inline int hif_wep_default_key_id(struct wfx_vif *wvif, int val)
-{
-	struct hif_mib_wep_default_key_id arg = {
-		.wep_default_key_id = val,
-	};
-
-	return hif_write_mib(wvif->wdev, wvif->id,
-			     HIF_MIB_ID_DOT11_WEP_DEFAULT_KEY_ID,
-			     &arg, sizeof(arg));
-}
-
-static inline int hif_rts_threshold(struct wfx_vif *wvif, int val)
-{
-	struct hif_mib_dot11_rts_threshold arg = {
-		.threshold = cpu_to_le32(val >= 0 ? val : 0xFFFF),
-	};
-
-	return hif_write_mib(wvif->wdev, wvif->id,
-			     HIF_MIB_ID_DOT11_RTS_THRESHOLD, &arg, sizeof(arg));
-}
+struct wfx_vif;
+struct sk_buff;
+
+int hif_set_output_power(struct wfx_vif *wvif, int val);
+int hif_set_beacon_wakeup_period(struct wfx_vif *wvif,
+				 unsigned int dtim_interval,
+				 unsigned int listen_interval);
+int hif_set_rcpi_rssi_threshold(struct wfx_vif *wvif,
+				int rssi_thold, int rssi_hyst);
+int hif_get_counters_table(struct wfx_dev *wdev,
+			   struct hif_mib_extended_count_table *arg);
+int hif_set_macaddr(struct wfx_vif *wvif, u8 *mac);
+int hif_set_rx_filter(struct wfx_vif *wvif,
+		      bool filter_bssid, bool fwd_probe_req);
+int hif_set_beacon_filter_table(struct wfx_vif *wvif, int tbl_len,
+				const struct hif_ie_table_entry *tbl);
+int hif_beacon_filter_control(struct wfx_vif *wvif,
+			      int enable, int beacon_count);
+int hif_set_operational_mode(struct wfx_dev *wdev, enum hif_op_power_mode mode);
+int hif_set_template_frame(struct wfx_vif *wvif, struct sk_buff *skb,
+			   u8 frame_type, int init_rate);
+int hif_set_mfp(struct wfx_vif *wvif, bool capable, bool required);
+int hif_set_block_ack_policy(struct wfx_vif *wvif,
+			     u8 tx_tid_policy, u8 rx_tid_policy);
+int hif_set_association_mode(struct wfx_vif *wvif,
+			     struct ieee80211_bss_conf *info);
+int hif_set_tx_rate_retry_policy(struct wfx_vif *wvif,
+				 int policy_index, uint8_t *rates);
+int hif_set_mac_addr_condition(struct wfx_vif *wvif,
+			       int idx, const u8 *mac_addr);
+int hif_set_uc_mc_bc_condition(struct wfx_vif *wvif,
+			       int idx, u8 allowed_frames);
+int hif_set_config_data_filter(struct wfx_vif *wvif, bool enable, int idx,
+			       int mac_filters, int frames_types_filters);
+int hif_set_data_filtering(struct wfx_vif *wvif, bool enable, bool invert);
+int hif_keep_alive_period(struct wfx_vif *wvif, int period);
+int hif_set_arp_ipv4_filter(struct wfx_vif *wvif, int idx, __be32 *addr);
+int hif_use_multi_tx_conf(struct wfx_dev *wdev, bool enable);
+int hif_set_uapsd_info(struct wfx_vif *wvif, unsigned long val);
+int hif_erp_use_protection(struct wfx_vif *wvif, bool enable);
+int hif_slot_time(struct wfx_vif *wvif, int val);
+int hif_dual_cts_protection(struct wfx_vif *wvif, bool enable);
+int hif_wep_default_key_id(struct wfx_vif *wvif, int val);
+int hif_rts_threshold(struct wfx_vif *wvif, int val);
 
 #endif
diff --git a/drivers/staging/wfx/key.c b/drivers/staging/wfx/key.c
index 96adfa330604..7b79b6175372 100644
--- a/drivers/staging/wfx/key.c
+++ b/drivers/staging/wfx/key.c
@@ -5,6 +5,7 @@
  * Copyright (c) 2017-2019, Silicon Laboratories, Inc.
  * Copyright (c) 2010, ST-Ericsson
  */
+#include <linux/etherdevice.h>
 #include <net/mac80211.h>
 
 #include "key.h"
diff --git a/drivers/staging/wfx/main.c b/drivers/staging/wfx/main.c
index 3c4c240229ad..b8a01ba0d381 100644
--- a/drivers/staging/wfx/main.c
+++ b/drivers/staging/wfx/main.c
@@ -133,12 +133,15 @@ static const struct ieee80211_ops wfx_ops = {
 	.remove_interface	= wfx_remove_interface,
 	.config                 = wfx_config,
 	.tx			= wfx_tx,
+	.join_ibss		= wfx_join_ibss,
+	.leave_ibss		= wfx_leave_ibss,
 	.conf_tx		= wfx_conf_tx,
 	.hw_scan		= wfx_hw_scan,
 	.cancel_hw_scan		= wfx_cancel_hw_scan,
+	.start_ap		= wfx_start_ap,
+	.stop_ap		= wfx_stop_ap,
 	.sta_add		= wfx_sta_add,
 	.sta_remove		= wfx_sta_remove,
-	.sta_notify		= wfx_sta_notify,
 	.set_tim		= wfx_set_tim,
 	.set_key		= wfx_set_key,
 	.set_rts_threshold	= wfx_set_rts_threshold,
@@ -268,7 +271,6 @@ static void wfx_free_common(void *data)
 
 	mutex_destroy(&wdev->rx_stats_lock);
 	mutex_destroy(&wdev->conf_mutex);
-	wfx_tx_queues_deinit(wdev);
 	ieee80211_free_hw(wdev->hw);
 }
 
@@ -315,7 +317,7 @@ struct wfx_dev *wfx_init_common(struct device *dev,
 	hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
 	hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
 	hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
-	hw->wiphy->max_ap_assoc_sta = WFX_MAX_STA_IN_AP_MODE;
+	hw->wiphy->max_ap_assoc_sta = HIF_LINK_ID_MAX;
 	hw->wiphy->max_scan_ssids = 2;
 	hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
 	hw->wiphy->n_iface_combinations = ARRAY_SIZE(wfx_iface_combinations);
diff --git a/drivers/staging/wfx/queue.c b/drivers/staging/wfx/queue.c
index 39d9127ce4b9..e6d7d0e45156 100644
--- a/drivers/staging/wfx/queue.c
+++ b/drivers/staging/wfx/queue.c
@@ -30,15 +30,23 @@ void wfx_tx_unlock(struct wfx_dev *wdev)
 void wfx_tx_flush(struct wfx_dev *wdev)
 {
 	int ret;
+	int i;
 
 	// Do not wait for any reply if chip is frozen
 	if (wdev->chip_frozen)
 		return;
 
+	wfx_tx_lock(wdev);
 	mutex_lock(&wdev->hif_cmd.lock);
 	ret = wait_event_timeout(wdev->hif.tx_buffers_empty,
 				 !wdev->hif.tx_buffers_used,
 				 msecs_to_jiffies(3000));
+	if (ret) {
+		for (i = 0; i < IEEE80211_NUM_ACS; i++)
+			WARN(atomic_read(&wdev->tx_queue[i].pending_frames),
+			     "there are still %d pending frames on queue %d",
+			     atomic_read(&wdev->tx_queue[i].pending_frames), i);
+	}
 	if (!ret) {
 		dev_warn(wdev->dev, "cannot flush tx buffers (%d still busy)\n",
 			 wdev->hif.tx_buffers_used);
@@ -47,6 +55,7 @@ void wfx_tx_flush(struct wfx_dev *wdev)
 		wdev->chip_frozen = 1;
 	}
 	mutex_unlock(&wdev->hif_cmd.lock);
+	wfx_tx_unlock(wdev);
 }
 
 void wfx_tx_lock_flush(struct wfx_dev *wdev)
@@ -55,261 +64,155 @@ void wfx_tx_lock_flush(struct wfx_dev *wdev)
 	wfx_tx_flush(wdev);
 }
 
-void wfx_tx_queues_lock(struct wfx_dev *wdev)
+void wfx_tx_queues_init(struct wfx_dev *wdev)
 {
 	int i;
-	struct wfx_queue *queue;
 
+	skb_queue_head_init(&wdev->tx_pending);
+	init_waitqueue_head(&wdev->tx_dequeue);
 	for (i = 0; i < IEEE80211_NUM_ACS; ++i) {
-		queue = &wdev->tx_queue[i];
-		spin_lock_bh(&queue->queue.lock);
-		if (queue->tx_locked_cnt++ == 0)
-			ieee80211_stop_queue(wdev->hw, queue->queue_id);
-		spin_unlock_bh(&queue->queue.lock);
+		skb_queue_head_init(&wdev->tx_queue[i].normal);
+		skb_queue_head_init(&wdev->tx_queue[i].cab);
 	}
 }
 
-void wfx_tx_queues_unlock(struct wfx_dev *wdev)
+void wfx_tx_queues_check_empty(struct wfx_dev *wdev)
 {
 	int i;
-	struct wfx_queue *queue;
 
+	WARN_ON(!skb_queue_empty_lockless(&wdev->tx_pending));
 	for (i = 0; i < IEEE80211_NUM_ACS; ++i) {
-		queue = &wdev->tx_queue[i];
-		spin_lock_bh(&queue->queue.lock);
-		WARN(!queue->tx_locked_cnt, "queue already unlocked");
-		if (--queue->tx_locked_cnt == 0)
-			ieee80211_wake_queue(wdev->hw, queue->queue_id);
-		spin_unlock_bh(&queue->queue.lock);
+		WARN_ON(atomic_read(&wdev->tx_queue[i].pending_frames));
+		WARN_ON(!skb_queue_empty_lockless(&wdev->tx_queue[i].normal));
+		WARN_ON(!skb_queue_empty_lockless(&wdev->tx_queue[i].cab));
 	}
 }
 
-/* If successful, LOCKS the TX queue! */
-void wfx_tx_queues_wait_empty_vif(struct wfx_vif *wvif)
+static bool __wfx_tx_queue_empty(struct wfx_dev *wdev,
+				 struct sk_buff_head *skb_queue, int vif_id)
 {
-	int i;
-	bool done;
-	struct wfx_queue *queue;
-	struct sk_buff *item;
-	struct wfx_dev *wdev = wvif->wdev;
-	struct hif_msg *hif;
-
-	if (wvif->wdev->chip_frozen) {
-		wfx_tx_lock_flush(wdev);
-		wfx_tx_queues_clear(wdev);
-		return;
-	}
+	struct hif_msg *hif_msg;
+	struct sk_buff *skb;
 
-	do {
-		done = true;
-		wfx_tx_lock_flush(wdev);
-		for (i = 0; i < IEEE80211_NUM_ACS && done; ++i) {
-			queue = &wdev->tx_queue[i];
-			spin_lock_bh(&queue->queue.lock);
-			skb_queue_walk(&queue->queue, item) {
-				hif = (struct hif_msg *) item->data;
-				if (hif->interface == wvif->id)
-					done = false;
-			}
-			spin_unlock_bh(&queue->queue.lock);
+	spin_lock_bh(&skb_queue->lock);
+	skb_queue_walk(skb_queue, skb) {
+		hif_msg = (struct hif_msg *)skb->data;
+		if (vif_id < 0 || hif_msg->interface == vif_id) {
+			spin_unlock_bh(&skb_queue->lock);
+			return false;
 		}
-		if (!done) {
-			wfx_tx_unlock(wdev);
-			msleep(20);
-		}
-	} while (!done);
-}
-
-static void wfx_tx_queue_clear(struct wfx_dev *wdev, struct wfx_queue *queue,
-			       struct sk_buff_head *gc_list)
-{
-	int i;
-	struct sk_buff *item;
-	struct wfx_queue_stats *stats = &wdev->tx_queue_stats;
-
-	spin_lock_bh(&queue->queue.lock);
-	while ((item = __skb_dequeue(&queue->queue)) != NULL)
-		skb_queue_head(gc_list, item);
-	spin_lock_nested(&stats->pending.lock, 1);
-	for (i = 0; i < ARRAY_SIZE(stats->link_map_cache); ++i) {
-		stats->link_map_cache[i] -= queue->link_map_cache[i];
-		queue->link_map_cache[i] = 0;
 	}
-	spin_unlock(&stats->pending.lock);
-	spin_unlock_bh(&queue->queue.lock);
+	spin_unlock_bh(&skb_queue->lock);
+	return true;
 }
 
-void wfx_tx_queues_clear(struct wfx_dev *wdev)
+bool wfx_tx_queue_empty(struct wfx_dev *wdev,
+			struct wfx_queue *queue, int vif_id)
 {
-	int i;
-	struct sk_buff *item;
-	struct sk_buff_head gc_list;
-	struct wfx_queue_stats *stats = &wdev->tx_queue_stats;
-
-	skb_queue_head_init(&gc_list);
-	for (i = 0; i < IEEE80211_NUM_ACS; ++i)
-		wfx_tx_queue_clear(wdev, &wdev->tx_queue[i], &gc_list);
-	wake_up(&stats->wait_link_id_empty);
-	while ((item = skb_dequeue(&gc_list)) != NULL)
-		wfx_skb_dtor(wdev, item);
+	return __wfx_tx_queue_empty(wdev, &queue->normal, vif_id) &&
+	       __wfx_tx_queue_empty(wdev, &queue->cab, vif_id);
 }
 
-void wfx_tx_queues_init(struct wfx_dev *wdev)
+static void __wfx_tx_queue_drop(struct wfx_dev *wdev,
+				struct sk_buff_head *skb_queue, int vif_id,
+				struct sk_buff_head *dropped)
 {
-	int i;
-
-	memset(&wdev->tx_queue_stats, 0, sizeof(wdev->tx_queue_stats));
-	memset(wdev->tx_queue, 0, sizeof(wdev->tx_queue));
-	skb_queue_head_init(&wdev->tx_queue_stats.pending);
-	init_waitqueue_head(&wdev->tx_queue_stats.wait_link_id_empty);
-
-	for (i = 0; i < IEEE80211_NUM_ACS; ++i) {
-		wdev->tx_queue[i].queue_id = i;
-		skb_queue_head_init(&wdev->tx_queue[i].queue);
+	struct sk_buff *skb, *tmp;
+	struct hif_msg *hif_msg;
+
+	spin_lock_bh(&skb_queue->lock);
+	skb_queue_walk_safe(skb_queue, skb, tmp) {
+		hif_msg = (struct hif_msg *)skb->data;
+		if (vif_id < 0 || hif_msg->interface == vif_id) {
+			__skb_unlink(skb, skb_queue);
+			skb_queue_head(dropped, skb);
+		}
 	}
+	spin_unlock_bh(&skb_queue->lock);
 }
 
-void wfx_tx_queues_deinit(struct wfx_dev *wdev)
-{
-	WARN_ON(!skb_queue_empty(&wdev->tx_queue_stats.pending));
-	wfx_tx_queues_clear(wdev);
-}
-
-int wfx_tx_queue_get_num_queued(struct wfx_queue *queue, u32 link_id_map)
+void wfx_tx_queue_drop(struct wfx_dev *wdev, struct wfx_queue *queue,
+		       int vif_id, struct sk_buff_head *dropped)
 {
-	int ret, i;
-
-	if (!link_id_map)
-		return 0;
-
-	spin_lock_bh(&queue->queue.lock);
-	if (link_id_map == (u32)-1) {
-		ret = skb_queue_len(&queue->queue);
-	} else {
-		ret = 0;
-		for (i = 0; i < ARRAY_SIZE(queue->link_map_cache); i++)
-			if (link_id_map & BIT(i))
-				ret += queue->link_map_cache[i];
-	}
-	spin_unlock_bh(&queue->queue.lock);
-	return ret;
+	__wfx_tx_queue_drop(wdev, &queue->cab, vif_id, dropped);
+	__wfx_tx_queue_drop(wdev, &queue->normal, vif_id, dropped);
+	wake_up(&wdev->tx_dequeue);
 }
 
-void wfx_tx_queue_put(struct wfx_dev *wdev, struct wfx_queue *queue,
-		      struct sk_buff *skb)
+void wfx_tx_queues_put(struct wfx_dev *wdev, struct sk_buff *skb)
 {
-	struct wfx_queue_stats *stats = &wdev->tx_queue_stats;
-	struct wfx_tx_priv *tx_priv = wfx_skb_tx_priv(skb);
-
-	WARN(tx_priv->link_id >= ARRAY_SIZE(stats->link_map_cache), "invalid link-id value");
-	spin_lock_bh(&queue->queue.lock);
-	__skb_queue_tail(&queue->queue, skb);
-
-	++queue->link_map_cache[tx_priv->link_id];
-
-	spin_lock_nested(&stats->pending.lock, 1);
-	++stats->link_map_cache[tx_priv->link_id];
-	spin_unlock(&stats->pending.lock);
-	spin_unlock_bh(&queue->queue.lock);
-}
+	struct wfx_queue *queue = &wdev->tx_queue[skb_get_queue_mapping(skb)];
+	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
 
-static struct sk_buff *wfx_tx_queue_get(struct wfx_dev *wdev,
-					struct wfx_queue *queue,
-					u32 link_id_map)
-{
-	struct sk_buff *skb = NULL;
-	struct sk_buff *item;
-	struct wfx_queue_stats *stats = &wdev->tx_queue_stats;
-	struct wfx_tx_priv *tx_priv;
-	bool wakeup_stats = false;
-
-	spin_lock_bh(&queue->queue.lock);
-	skb_queue_walk(&queue->queue, item) {
-		tx_priv = wfx_skb_tx_priv(item);
-		if (link_id_map & BIT(tx_priv->link_id)) {
-			skb = item;
-			break;
-		}
-	}
-	if (skb) {
-		tx_priv = wfx_skb_tx_priv(skb);
-		tx_priv->xmit_timestamp = ktime_get();
-		__skb_unlink(skb, &queue->queue);
-		--queue->link_map_cache[tx_priv->link_id];
-
-		spin_lock_nested(&stats->pending.lock, 1);
-		__skb_queue_tail(&stats->pending, skb);
-		if (!--stats->link_map_cache[tx_priv->link_id])
-			wakeup_stats = true;
-		spin_unlock(&stats->pending.lock);
-	}
-	spin_unlock_bh(&queue->queue.lock);
-	if (wakeup_stats)
-		wake_up(&stats->wait_link_id_empty);
-	return skb;
+	if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM)
+		skb_queue_tail(&queue->cab, skb);
+	else
+		skb_queue_tail(&queue->normal, skb);
 }
 
 int wfx_pending_requeue(struct wfx_dev *wdev, struct sk_buff *skb)
 {
-	struct wfx_queue_stats *stats = &wdev->tx_queue_stats;
-	struct wfx_tx_priv *tx_priv = wfx_skb_tx_priv(skb);
 	struct wfx_queue *queue = &wdev->tx_queue[skb_get_queue_mapping(skb)];
 
 	WARN_ON(skb_get_queue_mapping(skb) > 3);
-	spin_lock_bh(&queue->queue.lock);
-	++queue->link_map_cache[tx_priv->link_id];
-
-	spin_lock_nested(&stats->pending.lock, 1);
-	++stats->link_map_cache[tx_priv->link_id];
-	__skb_unlink(skb, &stats->pending);
-	spin_unlock(&stats->pending.lock);
-	__skb_queue_tail(&queue->queue, skb);
-	spin_unlock_bh(&queue->queue.lock);
+	WARN_ON(!atomic_read(&queue->pending_frames));
+
+	atomic_dec(&queue->pending_frames);
+	skb_unlink(skb, &wdev->tx_pending);
+	wfx_tx_queues_put(wdev, skb);
 	return 0;
 }
 
-int wfx_pending_remove(struct wfx_dev *wdev, struct sk_buff *skb)
+void wfx_pending_drop(struct wfx_dev *wdev, struct sk_buff_head *dropped)
 {
-	struct wfx_queue_stats *stats = &wdev->tx_queue_stats;
-
-	spin_lock_bh(&stats->pending.lock);
-	__skb_unlink(skb, &stats->pending);
-	spin_unlock_bh(&stats->pending.lock);
-	wfx_skb_dtor(wdev, skb);
+	struct wfx_queue *queue;
+	struct sk_buff *skb;
 
-	return 0;
+	WARN(!wdev->chip_frozen, "%s should only be used to recover a frozen device",
+	     __func__);
+	while ((skb = skb_dequeue(&wdev->tx_pending)) != NULL) {
+		queue = &wdev->tx_queue[skb_get_queue_mapping(skb)];
+		WARN_ON(skb_get_queue_mapping(skb) > 3);
+		WARN_ON(!atomic_read(&queue->pending_frames));
+		atomic_dec(&queue->pending_frames);
+		skb_queue_head(dropped, skb);
+	}
 }
 
 struct sk_buff *wfx_pending_get(struct wfx_dev *wdev, u32 packet_id)
 {
-	struct sk_buff *skb;
+	struct wfx_queue *queue;
 	struct hif_req_tx *req;
-	struct wfx_queue_stats *stats = &wdev->tx_queue_stats;
+	struct sk_buff *skb;
 
-	spin_lock_bh(&stats->pending.lock);
-	skb_queue_walk(&stats->pending, skb) {
+	spin_lock_bh(&wdev->tx_pending.lock);
+	skb_queue_walk(&wdev->tx_pending, skb) {
 		req = wfx_skb_txreq(skb);
 		if (req->packet_id == packet_id) {
-			spin_unlock_bh(&stats->pending.lock);
+			spin_unlock_bh(&wdev->tx_pending.lock);
+			queue = &wdev->tx_queue[skb_get_queue_mapping(skb)];
+			WARN_ON(skb_get_queue_mapping(skb) > 3);
+			WARN_ON(!atomic_read(&queue->pending_frames));
+			atomic_dec(&queue->pending_frames);
+			skb_unlink(skb, &wdev->tx_pending);
 			return skb;
 		}
 	}
-	spin_unlock_bh(&stats->pending.lock);
+	spin_unlock_bh(&wdev->tx_pending.lock);
 	WARN(1, "cannot find packet in pending queue");
 	return NULL;
 }
 
 void wfx_pending_dump_old_frames(struct wfx_dev *wdev, unsigned int limit_ms)
 {
-	struct wfx_queue_stats *stats = &wdev->tx_queue_stats;
 	ktime_t now = ktime_get();
 	struct wfx_tx_priv *tx_priv;
 	struct hif_req_tx *req;
 	struct sk_buff *skb;
 	bool first = true;
 
-	spin_lock_bh(&stats->pending.lock);
-	skb_queue_walk(&stats->pending, skb) {
+	spin_lock_bh(&wdev->tx_pending.lock);
+	skb_queue_walk(&wdev->tx_pending, skb) {
 		tx_priv = wfx_skb_tx_priv(skb);
 		req = wfx_skb_txreq(skb);
 		if (ktime_after(now, ktime_add_ms(tx_priv->xmit_timestamp,
@@ -324,7 +227,7 @@ void wfx_pending_dump_old_frames(struct wfx_dev *wdev, unsigned int limit_ms)
 				 ktime_ms_delta(now, tx_priv->xmit_timestamp));
 		}
 	}
-	spin_unlock_bh(&stats->pending.lock);
+	spin_unlock_bh(&wdev->tx_pending.lock);
 }
 
 unsigned int wfx_pending_get_pkt_us_delay(struct wfx_dev *wdev,
@@ -336,29 +239,32 @@ unsigned int wfx_pending_get_pkt_us_delay(struct wfx_dev *wdev,
 	return ktime_us_delta(now, tx_priv->xmit_timestamp);
 }
 
-bool wfx_tx_queues_is_empty(struct wfx_dev *wdev)
+bool wfx_tx_queues_has_cab(struct wfx_vif *wvif)
 {
+	struct wfx_dev *wdev = wvif->wdev;
 	int i;
-	struct sk_buff_head *queue;
-	bool ret = true;
 
-	for (i = 0; i < IEEE80211_NUM_ACS; i++) {
-		queue = &wdev->tx_queue[i].queue;
-		spin_lock_bh(&queue->lock);
-		if (!skb_queue_empty(queue))
-			ret = false;
-		spin_unlock_bh(&queue->lock);
-	}
-	return ret;
+	if (wvif->vif->type != NL80211_IFTYPE_AP)
+		return false;
+	for (i = 0; i < IEEE80211_NUM_ACS; ++i)
+		// Note: since only AP can have mcast frames in queue and only
+		// one vif can be AP, all queued frames has same interface id
+		if (!skb_queue_empty_lockless(&wdev->tx_queue[i].cab))
+			return true;
+	return false;
 }
 
-static bool hif_handle_tx_data(struct wfx_vif *wvif, struct sk_buff *skb,
-			       struct wfx_queue *queue)
+static bool wfx_handle_tx_data(struct wfx_dev *wdev, struct sk_buff *skb)
 {
 	struct hif_req_tx *req = wfx_skb_txreq(skb);
 	struct ieee80211_key_conf *hw_key = wfx_skb_tx_priv(skb)->hw_key;
 	struct ieee80211_hdr *frame =
 		(struct ieee80211_hdr *)(req->frame + req->data_flags.fc_offset);
+	struct wfx_vif *wvif =
+		wdev_to_wvif(wdev, ((struct hif_msg *)skb->data)->interface);
+
+	if (!wvif)
+		return false;
 
 	// FIXME: mac80211 is smart enough to handle BSS loss. Driver should not
 	// try to do anything about that.
@@ -377,97 +283,63 @@ static bool hif_handle_tx_data(struct wfx_vif *wvif, struct sk_buff *skb,
 	    hw_key && hw_key->keyidx != wvif->wep_default_key_id &&
 	    (hw_key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
 	     hw_key->cipher == WLAN_CIPHER_SUITE_WEP104)) {
-		wfx_tx_lock(wvif->wdev);
+		wfx_tx_lock(wdev);
 		WARN_ON(wvif->wep_pending_skb);
 		wvif->wep_default_key_id = hw_key->keyidx;
 		wvif->wep_pending_skb = skb;
 		if (!schedule_work(&wvif->wep_key_work))
-			wfx_tx_unlock(wvif->wdev);
+			wfx_tx_unlock(wdev);
 		return true;
 	} else {
 		return false;
 	}
 }
 
-static int wfx_get_prio_queue(struct wfx_vif *wvif,
-				 u32 tx_allowed_mask, int *total)
+static struct sk_buff *wfx_tx_queues_get_skb(struct wfx_dev *wdev)
 {
-	static const int urgent = BIT(WFX_LINK_ID_AFTER_DTIM) |
-		BIT(WFX_LINK_ID_UAPSD);
-	const struct ieee80211_tx_queue_params *edca;
-	unsigned int score, best = -1;
-	int winner = -1;
-	int i;
-
-	/* search for a winner using edca params */
-	for (i = 0; i < IEEE80211_NUM_ACS; ++i) {
-		int queued;
-
-		edca = &wvif->edca_params[i];
-		queued = wfx_tx_queue_get_num_queued(&wvif->wdev->tx_queue[i],
-				tx_allowed_mask);
-		if (!queued)
-			continue;
-		*total += queued;
-		score = ((edca->aifs + edca->cw_min) << 16) +
-			((edca->cw_max - edca->cw_min) *
-			 (get_random_int() & 0xFFFF));
-		if (score < best && (winner < 0 || i != 3)) {
-			best = score;
-			winner = i;
-		}
-	}
-
-	/* override winner if bursting */
-	if (winner >= 0 && wvif->wdev->tx_burst_idx >= 0 &&
-	    winner != wvif->wdev->tx_burst_idx &&
-	    !wfx_tx_queue_get_num_queued(&wvif->wdev->tx_queue[winner],
-					 tx_allowed_mask & urgent) &&
-	    wfx_tx_queue_get_num_queued(&wvif->wdev->tx_queue[wvif->wdev->tx_burst_idx], tx_allowed_mask))
-		winner = wvif->wdev->tx_burst_idx;
-
-	return winner;
-}
-
-static int wfx_tx_queue_mask_get(struct wfx_vif *wvif,
-				     struct wfx_queue **queue_p,
-				     u32 *tx_allowed_mask_p)
-{
-	int idx;
-	u32 tx_allowed_mask;
-	int total = 0;
-
-	/* Search for unicast traffic */
-	tx_allowed_mask = ~wvif->sta_asleep_mask;
-	tx_allowed_mask |= BIT(WFX_LINK_ID_UAPSD);
-	if (wvif->sta_asleep_mask)
-		tx_allowed_mask &= ~BIT(WFX_LINK_ID_AFTER_DTIM);
-	else
-		tx_allowed_mask |= BIT(WFX_LINK_ID_AFTER_DTIM);
-	idx = wfx_get_prio_queue(wvif, tx_allowed_mask, &total);
-	if (idx < 0)
-		return -ENOENT;
-
-	*queue_p = &wvif->wdev->tx_queue[idx];
-	*tx_allowed_mask_p = tx_allowed_mask;
-	return 0;
-}
-
-struct hif_msg *wfx_tx_queues_get_after_dtim(struct wfx_vif *wvif)
-{
-	struct wfx_dev *wdev = wvif->wdev;
-	struct ieee80211_tx_info *tx_info;
+	struct wfx_queue *sorted_queues[IEEE80211_NUM_ACS];
+	struct wfx_vif *wvif;
 	struct hif_msg *hif;
 	struct sk_buff *skb;
-	int i;
+	int i, j;
 
-	for (i = 0; i < IEEE80211_NUM_ACS; ++i) {
-		skb_queue_walk(&wdev->tx_queue[i].queue, skb) {
-			tx_info = IEEE80211_SKB_CB(skb);
+	// bubble sort
+	for (i = 0; i < IEEE80211_NUM_ACS; i++) {
+		sorted_queues[i] = &wdev->tx_queue[i];
+		for (j = i; j > 0; j--)
+			if (atomic_read(&sorted_queues[j]->pending_frames) >
+			    atomic_read(&sorted_queues[j - 1]->pending_frames))
+				swap(sorted_queues[j - 1], sorted_queues[j]);
+	}
+	wvif = NULL;
+	while ((wvif = wvif_iterate(wdev, wvif)) != NULL) {
+		if (!wvif->after_dtim_tx_allowed)
+			continue;
+		for (i = 0; i < IEEE80211_NUM_ACS; i++) {
+			skb = skb_dequeue(&sorted_queues[i]->cab);
+			if (!skb)
+				continue;
+			// Note: since only AP can have mcast frames in queue
+			// and only one vif can be AP, all queued frames has
+			// same interface id
 			hif = (struct hif_msg *)skb->data;
-			if ((tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) &&
-			    (hif->interface == wvif->id))
-				return (struct hif_msg *)skb->data;
+			WARN_ON(hif->interface != wvif->id);
+			WARN_ON(sorted_queues[i] !=
+				&wdev->tx_queue[skb_get_queue_mapping(skb)]);
+			atomic_inc(&sorted_queues[i]->pending_frames);
+			return skb;
+		}
+		// No more multicast to sent
+		wvif->after_dtim_tx_allowed = false;
+		schedule_work(&wvif->update_tim_work);
+	}
+	for (i = 0; i < IEEE80211_NUM_ACS; i++) {
+		skb = skb_dequeue(&sorted_queues[i]->normal);
+		if (skb) {
+			WARN_ON(sorted_queues[i] !=
+				&wdev->tx_queue[skb_get_queue_mapping(skb)]);
+			atomic_inc(&sorted_queues[i]->pending_frames);
+			return skb;
 		}
 	}
 	return NULL;
@@ -475,90 +347,23 @@ struct hif_msg *wfx_tx_queues_get_after_dtim(struct wfx_vif *wvif)
 
 struct hif_msg *wfx_tx_queues_get(struct wfx_dev *wdev)
 {
+	struct wfx_tx_priv *tx_priv;
 	struct sk_buff *skb;
-	struct hif_msg *hif = NULL;
-	struct wfx_queue *queue = NULL;
-	struct wfx_queue *vif_queue = NULL;
-	u32 tx_allowed_mask = 0;
-	u32 vif_tx_allowed_mask = 0;
-	struct wfx_vif *wvif;
-	int not_found;
-	int burst;
-	int i;
 
 	if (atomic_read(&wdev->tx_lock))
 		return NULL;
 
-	wvif = NULL;
-	while ((wvif = wvif_iterate(wdev, wvif)) != NULL) {
-		if (wvif->after_dtim_tx_allowed) {
-			for (i = 0; i < IEEE80211_NUM_ACS; ++i) {
-				skb = wfx_tx_queue_get(wvif->wdev,
-						       &wdev->tx_queue[i],
-						       BIT(WFX_LINK_ID_AFTER_DTIM));
-				if (skb) {
-					hif = (struct hif_msg *)skb->data;
-					// Cannot happen since only one vif can
-					// be AP at time
-					WARN_ON(wvif->id != hif->interface);
-					return hif;
-				}
-			}
-			// No more multicast to sent
-			wvif->after_dtim_tx_allowed = false;
-			schedule_work(&wvif->update_tim_work);
-		}
-	}
-
 	for (;;) {
-		int ret = -ENOENT;
-		int queue_num;
-
-		wvif = NULL;
-		while ((wvif = wvif_iterate(wdev, wvif)) != NULL) {
-			spin_lock_bh(&wvif->ps_state_lock);
-
-			not_found = wfx_tx_queue_mask_get(wvif, &vif_queue,
-							  &vif_tx_allowed_mask);
-
-			spin_unlock_bh(&wvif->ps_state_lock);
-
-			if (!not_found) {
-				if (queue && queue != vif_queue)
-					dev_info(wdev->dev, "vifs disagree about queue priority\n");
-				tx_allowed_mask |= vif_tx_allowed_mask;
-				queue = vif_queue;
-				ret = 0;
-			}
-		}
-
-		if (ret)
-			return NULL;
-
-		queue_num = queue - wdev->tx_queue;
-
-		skb = wfx_tx_queue_get(wdev, queue, tx_allowed_mask);
+		skb = wfx_tx_queues_get_skb(wdev);
 		if (!skb)
+			return NULL;
+		skb_queue_tail(&wdev->tx_pending, skb);
+		wake_up(&wdev->tx_dequeue);
+		// FIXME: is it useful?
+		if (wfx_handle_tx_data(wdev, skb))
 			continue;
-		hif = (struct hif_msg *)skb->data;
-		wvif = wdev_to_wvif(wdev, hif->interface);
-		WARN_ON(!wvif);
-
-		if (hif_handle_tx_data(wvif, skb, queue))
-			continue;  /* Handled by WSM */
-
-		/* allow bursting if txop is set */
-		if (wvif->edca_params[queue_num].txop)
-			burst = wfx_tx_queue_get_num_queued(queue, tx_allowed_mask) + 1;
-		else
-			burst = 1;
-
-		/* store index of bursting queue */
-		if (burst > 1)
-			wdev->tx_burst_idx = queue_num;
-		else
-			wdev->tx_burst_idx = -1;
-
-		return hif;
+		tx_priv = wfx_skb_tx_priv(skb);
+		tx_priv->xmit_timestamp = ktime_get();
+		return (struct hif_msg *)skb->data;
 	}
 }
diff --git a/drivers/staging/wfx/queue.h b/drivers/staging/wfx/queue.h
index 90bb060d1204..1020dfde399b 100644
--- a/drivers/staging/wfx/queue.h
+++ b/drivers/staging/wfx/queue.h
@@ -9,29 +9,17 @@
 #define WFX_QUEUE_H
 
 #include <linux/skbuff.h>
+#include <linux/atomic.h>
 
 #include "hif_api_cmd.h"
 
-#define WFX_MAX_STA_IN_AP_MODE    14
-#define WFX_LINK_ID_NO_ASSOC      15
-#define WFX_LINK_ID_AFTER_DTIM    (WFX_LINK_ID_NO_ASSOC + 1)
-#define WFX_LINK_ID_UAPSD         (WFX_LINK_ID_NO_ASSOC + 2)
-#define WFX_LINK_ID_MAX           (WFX_LINK_ID_NO_ASSOC + 3)
-
 struct wfx_dev;
 struct wfx_vif;
 
 struct wfx_queue {
-	struct sk_buff_head	queue;
-	int			tx_locked_cnt;
-	int			link_map_cache[WFX_LINK_ID_MAX];
-	u8			queue_id;
-};
-
-struct wfx_queue_stats {
-	int			link_map_cache[WFX_LINK_ID_MAX];
-	struct sk_buff_head	pending;
-	wait_queue_head_t	wait_link_id_empty;
+	struct sk_buff_head	normal;
+	struct sk_buff_head	cab; // Content After (DTIM) Beacon
+	atomic_t		pending_frames;
 };
 
 void wfx_tx_lock(struct wfx_dev *wdev);
@@ -40,21 +28,18 @@ void wfx_tx_flush(struct wfx_dev *wdev);
 void wfx_tx_lock_flush(struct wfx_dev *wdev);
 
 void wfx_tx_queues_init(struct wfx_dev *wdev);
-void wfx_tx_queues_deinit(struct wfx_dev *wdev);
-void wfx_tx_queues_lock(struct wfx_dev *wdev);
-void wfx_tx_queues_unlock(struct wfx_dev *wdev);
-void wfx_tx_queues_clear(struct wfx_dev *wdev);
-bool wfx_tx_queues_is_empty(struct wfx_dev *wdev);
-void wfx_tx_queues_wait_empty_vif(struct wfx_vif *wvif);
+void wfx_tx_queues_check_empty(struct wfx_dev *wdev);
+bool wfx_tx_queues_has_cab(struct wfx_vif *wvif);
+void wfx_tx_queues_put(struct wfx_dev *wdev, struct sk_buff *skb);
 struct hif_msg *wfx_tx_queues_get(struct wfx_dev *wdev);
-struct hif_msg *wfx_tx_queues_get_after_dtim(struct wfx_vif *wvif);
 
-void wfx_tx_queue_put(struct wfx_dev *wdev, struct wfx_queue *queue,
-		      struct sk_buff *skb);
-int wfx_tx_queue_get_num_queued(struct wfx_queue *queue, u32 link_id_map);
+bool wfx_tx_queue_empty(struct wfx_dev *wdev, struct wfx_queue *queue,
+			int vif_id);
+void wfx_tx_queue_drop(struct wfx_dev *wdev, struct wfx_queue *queue,
+		       int vif_id, struct sk_buff_head *dropped);
 
 struct sk_buff *wfx_pending_get(struct wfx_dev *wdev, u32 packet_id);
-int wfx_pending_remove(struct wfx_dev *wdev, struct sk_buff *skb);
+void wfx_pending_drop(struct wfx_dev *wdev, struct sk_buff_head *dropped);
 int wfx_pending_requeue(struct wfx_dev *wdev, struct sk_buff *skb);
 unsigned int wfx_pending_get_pkt_us_delay(struct wfx_dev *wdev,
 					  struct sk_buff *skb);
diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c
index 6e1e50048651..0c7f4eef045c 100644
--- a/drivers/staging/wfx/scan.c
+++ b/drivers/staging/wfx/scan.c
@@ -86,8 +86,8 @@ void wfx_hw_scan_work(struct work_struct *work)
 	struct ieee80211_scan_request *hw_req = wvif->scan_req;
 	int chan_cur, ret;
 
-	mutex_lock(&wvif->scan_lock);
 	mutex_lock(&wvif->wdev->conf_mutex);
+	mutex_lock(&wvif->scan_lock);
 	update_probe_tmpl(wvif, &hw_req->req);
 	wfx_fwd_probe_req(wvif, true);
 	chan_cur = 0;
@@ -96,8 +96,8 @@ void wfx_hw_scan_work(struct work_struct *work)
 		if (ret > 0)
 			chan_cur += ret;
 	} while (ret > 0 && chan_cur < hw_req->req.n_channels);
-	mutex_unlock(&wvif->wdev->conf_mutex);
 	mutex_unlock(&wvif->scan_lock);
+	mutex_unlock(&wvif->wdev->conf_mutex);
 	__ieee80211_scan_completed_compat(wvif->wdev->hw, ret < 0);
 }
 
diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index 9d430346a58b..f1df7717d5f4 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -5,6 +5,7 @@
  * Copyright (c) 2017-2019, Silicon Laboratories, Inc.
  * Copyright (c) 2010, ST-Ericsson
  */
+#include <linux/etherdevice.h>
 #include <net/mac80211.h>
 
 #include "sta.h"
@@ -147,7 +148,7 @@ void wfx_update_filtering(struct wfx_vif *wvif)
 	int bf_enable;
 	int bf_count;
 	int n_filter_ies;
-	struct hif_ie_table_entry filter_ies[] = {
+	const struct hif_ie_table_entry filter_ies[] = {
 		{
 			.ie_id        = WLAN_EID_VENDOR_SPECIFIC,
 			.has_changed  = 1,
@@ -241,6 +242,7 @@ void wfx_configure_filter(struct ieee80211_hw *hw,
 
 	*total_flags &= FIF_OTHER_BSS | FIF_FCSFAIL | FIF_PROBE_REQ;
 
+	mutex_lock(&wdev->conf_mutex);
 	while ((wvif = wvif_iterate(wdev, wvif)) != NULL) {
 		mutex_lock(&wvif->scan_lock);
 		wvif->filter_bssid = (*total_flags &
@@ -250,6 +252,7 @@ void wfx_configure_filter(struct ieee80211_hw *hw,
 		wfx_update_filtering(wvif);
 		mutex_unlock(&wvif->scan_lock);
 	}
+	mutex_unlock(&wdev->conf_mutex);
 }
 
 static int wfx_update_pm(struct wfx_vif *wvif)
@@ -298,7 +301,6 @@ int wfx_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 
 	mutex_lock(&wdev->conf_mutex);
 	assign_bit(queue, &wvif->uapsd_mask, params->uapsd);
-	memcpy(&wvif->edca_params[queue], params, sizeof(*params));
 	hif_set_edca_queue_params(wvif, queue, params);
 	if (wvif->vif->type == NL80211_IFTYPE_STATION &&
 	    old_uapsd != wvif->uapsd_mask) {
@@ -319,29 +321,6 @@ int wfx_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
 	return 0;
 }
 
-static int __wfx_flush(struct wfx_dev *wdev, bool drop)
-{
-	for (;;) {
-		if (drop)
-			wfx_tx_queues_clear(wdev);
-		if (wait_event_timeout(wdev->tx_queue_stats.wait_link_id_empty,
-				       wfx_tx_queues_is_empty(wdev),
-				       2 * HZ) <= 0)
-			return -ETIMEDOUT;
-		wfx_tx_flush(wdev);
-		if (wfx_tx_queues_is_empty(wdev))
-			return 0;
-		dev_warn(wdev->dev, "frames queued while flushing tx queues");
-	}
-}
-
-void wfx_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-		  u32 queues, bool drop)
-{
-	// FIXME: only flush requested vif and queues
-	__wfx_flush(hw->priv, drop);
-}
-
 /* WSM callbacks */
 
 static void wfx_event_report_rssi(struct wfx_vif *wvif, u8 raw_rcpi_rssi)
@@ -375,14 +354,12 @@ static void wfx_event_handler_work(struct work_struct *work)
 	list_for_each_entry(event, &list, link) {
 		switch (event->evt.event_id) {
 		case HIF_EVENT_IND_BSSLOST:
-			cancel_work_sync(&wvif->unjoin_work);
 			mutex_lock(&wvif->scan_lock);
 			wfx_cqm_bssloss_sm(wvif, 1, 0, 0);
 			mutex_unlock(&wvif->scan_lock);
 			break;
 		case HIF_EVENT_IND_BSSREGAINED:
 			wfx_cqm_bssloss_sm(wvif, 0, 0, 0);
-			cancel_work_sync(&wvif->unjoin_work);
 			break;
 		case HIF_EVENT_IND_RCPI_RSSI:
 			wfx_event_report_rssi(wvif,
@@ -422,38 +399,32 @@ static void wfx_bss_params_work(struct work_struct *work)
 	mutex_unlock(&wvif->wdev->conf_mutex);
 }
 
+// Call it with wdev->conf_mutex locked
 static void wfx_do_unjoin(struct wfx_vif *wvif)
 {
-	mutex_lock(&wvif->wdev->conf_mutex);
-
 	if (!wvif->state)
-		goto done;
+		return;
 
 	if (wvif->state == WFX_STATE_AP)
-		goto done;
+		return;
 
 	cancel_work_sync(&wvif->update_filtering_work);
 	wvif->state = WFX_STATE_PASSIVE;
 
 	/* Unjoin is a reset. */
-	wfx_tx_flush(wvif->wdev);
-	hif_keep_alive_period(wvif, 0);
+	wfx_tx_lock_flush(wvif->wdev);
 	hif_reset(wvif, false);
 	wfx_tx_policy_init(wvif);
-	hif_set_macaddr(wvif, wvif->vif->addr);
+	if (wvif_count(wvif->wdev) <= 1)
+		hif_set_block_ack_policy(wvif, 0xFF, 0xFF);
 	wfx_free_event_queue(wvif);
 	cancel_work_sync(&wvif->event_handler_work);
 	wfx_cqm_bssloss_sm(wvif, 0, 0, 0);
 
-	/* Disable Block ACKs */
-	hif_set_block_ack_policy(wvif, 0, 0);
-
 	wvif->disable_beacon_filter = false;
 	wfx_update_filtering(wvif);
 	memset(&wvif->bss_params, 0, sizeof(wvif->bss_params));
-
-done:
-	mutex_unlock(&wvif->wdev->conf_mutex);
+	wfx_tx_unlock(wvif->wdev);
 }
 
 static void wfx_set_mfp(struct wfx_vif *wvif,
@@ -498,9 +469,6 @@ static void wfx_do_join(struct wfx_vif *wvif)
 
 	wfx_tx_lock_flush(wvif->wdev);
 
-	if (wvif->state)
-		wfx_do_unjoin(wvif);
-
 	bss = cfg80211_get_bss(wvif->wdev->hw->wiphy, wvif->channel,
 			       conf->bssid, NULL, 0,
 			       IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY);
@@ -509,14 +477,8 @@ static void wfx_do_join(struct wfx_vif *wvif)
 		return;
 	}
 
-	mutex_lock(&wvif->wdev->conf_mutex);
-
-	/* Sanity check beacon interval */
-	if (!wvif->beacon_int)
-		wvif->beacon_int = 1;
-
 	rcu_read_lock(); // protect ssidie
-	if (!conf->ibss_joined)
+	if (bss)
 		ssidie = ieee80211_bss_get_ie(bss, WLAN_EID_SSID);
 	if (ssidie) {
 		ssidlen = ssidie[1];
@@ -524,28 +486,20 @@ static void wfx_do_join(struct wfx_vif *wvif)
 	}
 	rcu_read_unlock();
 
-	wfx_tx_flush(wvif->wdev);
-
-	if (wvif_count(wvif->wdev) <= 1)
-		hif_set_block_ack_policy(wvif, 0xFF, 0xFF);
-
 	wfx_set_mfp(wvif, bss);
+	cfg80211_put_bss(wvif->wdev->hw->wiphy, bss);
 
-	wvif->wdev->tx_burst_idx = -1;
 	ret = hif_join(wvif, conf, wvif->channel, ssid, ssidlen);
 	if (ret) {
 		ieee80211_connection_loss(wvif->vif);
 		wvif->join_complete_status = -1;
-		/* Tx lock still held, unjoin will clear it. */
-		if (!schedule_work(&wvif->unjoin_work))
-			wfx_tx_unlock(wvif->wdev);
+		wfx_do_unjoin(wvif);
 	} else {
 		wvif->join_complete_status = 0;
 		if (wvif->vif->type == NL80211_IFTYPE_ADHOC)
 			wvif->state = WFX_STATE_IBSS;
 		else
 			wvif->state = WFX_STATE_PRE_STA;
-		wfx_tx_unlock(wvif->wdev);
 
 		/* Upload keys */
 		wfx_upload_keys(wvif);
@@ -556,19 +510,8 @@ static void wfx_do_join(struct wfx_vif *wvif)
 		 * receives at least one
 		 */
 		wvif->disable_beacon_filter = true;
+		wfx_update_filtering(wvif);
 	}
-	wfx_update_filtering(wvif);
-
-	mutex_unlock(&wvif->wdev->conf_mutex);
-	if (bss)
-		cfg80211_put_bss(wvif->wdev->hw->wiphy, bss);
-}
-
-static void wfx_unjoin_work(struct work_struct *work)
-{
-	struct wfx_vif *wvif = container_of(work, struct wfx_vif, unjoin_work);
-
-	wfx_do_unjoin(wvif);
 	wfx_tx_unlock(wvif->wdev);
 }
 
@@ -588,14 +531,9 @@ int wfx_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 	sta_priv->link_id = ffz(wvif->link_id_map);
 	wvif->link_id_map |= BIT(sta_priv->link_id);
 	WARN_ON(!sta_priv->link_id);
-	WARN_ON(sta_priv->link_id >= WFX_MAX_STA_IN_AP_MODE);
+	WARN_ON(sta_priv->link_id >= HIF_LINK_ID_MAX);
 	hif_map_link(wvif, sta->addr, 0, sta_priv->link_id);
 
-	spin_lock_bh(&wvif->ps_state_lock);
-	if ((sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK) ==
-					IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
-		wvif->sta_asleep_mask |= BIT(sta_priv->link_id);
-	spin_unlock_bh(&wvif->ps_state_lock);
 	return 0;
 }
 
@@ -619,50 +557,10 @@ int wfx_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 	return 0;
 }
 
-static int wfx_start_ap(struct wfx_vif *wvif)
-{
-	int ret;
-
-	wvif->beacon_int = wvif->vif->bss_conf.beacon_int;
-	wvif->wdev->tx_burst_idx = -1;
-	ret = hif_start(wvif, &wvif->vif->bss_conf, wvif->channel);
-	if (ret)
-		return ret;
-	ret = wfx_upload_keys(wvif);
-	if (ret)
-		return ret;
-	if (wvif_count(wvif->wdev) <= 1)
-		hif_set_block_ack_policy(wvif, 0xFF, 0xFF);
-	wvif->state = WFX_STATE_AP;
-	wfx_update_filtering(wvif);
-	return 0;
-}
-
-static int wfx_update_beaconing(struct wfx_vif *wvif)
-{
-	if (wvif->vif->type != NL80211_IFTYPE_AP)
-		return 0;
-	if (wvif->state == WFX_STATE_AP &&
-	    wvif->beacon_int == wvif->vif->bss_conf.beacon_int)
-		return 0;
-	wfx_tx_lock_flush(wvif->wdev);
-	hif_reset(wvif, false);
-	wfx_tx_policy_init(wvif);
-	wvif->state = WFX_STATE_PASSIVE;
-	wfx_start_ap(wvif);
-	wfx_tx_unlock(wvif->wdev);
-	return 0;
-}
-
 static int wfx_upload_ap_templates(struct wfx_vif *wvif)
 {
 	struct sk_buff *skb;
 
-	if (wvif->vif->type == NL80211_IFTYPE_STATION ||
-	    wvif->vif->type == NL80211_IFTYPE_MONITOR ||
-	    wvif->vif->type == NL80211_IFTYPE_UNSPECIFIED)
-		return 0;
-
 	skb = ieee80211_beacon_get(wvif->wdev->hw, wvif->vif);
 	if (!skb)
 		return -ENOMEM;
@@ -679,12 +577,35 @@ static int wfx_upload_ap_templates(struct wfx_vif *wvif)
 	return 0;
 }
 
+int wfx_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+{
+	struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv;
+
+	wfx_upload_keys(wvif);
+	wvif->state = WFX_STATE_AP;
+	wfx_update_filtering(wvif);
+	wfx_upload_ap_templates(wvif);
+	wfx_fwd_probe_req(wvif, false);
+	hif_start(wvif, &vif->bss_conf, wvif->channel);
+	return 0;
+}
+
+void wfx_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+{
+	struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv;
+
+	hif_reset(wvif, false);
+	wfx_tx_policy_init(wvif);
+	if (wvif_count(wvif->wdev) <= 1)
+		hif_set_block_ack_policy(wvif, 0xFF, 0xFF);
+	wvif->state = WFX_STATE_PASSIVE;
+}
+
 static void wfx_join_finalize(struct wfx_vif *wvif,
 			      struct ieee80211_bss_conf *info)
 {
 	struct ieee80211_sta *sta = NULL;
 
-	wvif->beacon_int = info->beacon_int;
 	rcu_read_lock(); // protect sta
 	if (info->bssid && !info->ibss_joined)
 		sta = ieee80211_find_sta(wvif->vif, info->bssid);
@@ -701,7 +622,6 @@ static void wfx_join_finalize(struct wfx_vif *wvif,
 		hif_dual_cts_protection(wvif, false);
 
 	wfx_cqm_bssloss_sm(wvif, 0, 0, 0);
-	cancel_work_sync(&wvif->unjoin_work);
 
 	wvif->bss_params.beacon_lost_count = 20;
 	wvif->bss_params.aid = info->aid;
@@ -709,7 +629,8 @@ static void wfx_join_finalize(struct wfx_vif *wvif,
 	hif_set_association_mode(wvif, info);
 
 	if (!info->ibss_joined) {
-		hif_keep_alive_period(wvif, 30 /* sec */);
+		wvif->state = WFX_STATE_STA;
+		hif_keep_alive_period(wvif, 0);
 		hif_set_bss_params(wvif, &wvif->bss_params);
 		hif_set_beacon_wakeup_period(wvif, info->dtim_period,
 					     info->dtim_period);
@@ -717,6 +638,35 @@ static void wfx_join_finalize(struct wfx_vif *wvif,
 	}
 }
 
+int wfx_join_ibss(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+{
+	struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv;
+
+	wfx_upload_ap_templates(wvif);
+	wfx_do_join(wvif);
+	return 0;
+}
+
+void wfx_leave_ibss(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+{
+	struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv;
+
+	wfx_do_unjoin(wvif);
+}
+
+void wfx_enable_beacon(struct wfx_vif *wvif, bool enable)
+{
+	// Driver has Content After DTIM Beacon in queue. Driver is waiting for
+	// a signal from the firmware. Since we are going to stop to send
+	// beacons, this signal will never happens. See also
+	// wfx_suspend_resume_mc()
+	if (!enable && wfx_tx_queues_has_cab(wvif)) {
+		wvif->after_dtim_tx_allowed = true;
+		wfx_bh_request_tx(wvif->wdev);
+	}
+	hif_beacon_transmit(wvif, enable);
+}
+
 void wfx_bss_info_changed(struct ieee80211_hw *hw,
 			     struct ieee80211_vif *vif,
 			     struct ieee80211_bss_conf *info,
@@ -724,7 +674,6 @@ void wfx_bss_info_changed(struct ieee80211_hw *hw,
 {
 	struct wfx_dev *wdev = hw->priv;
 	struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv;
-	bool do_join = false;
 	int i;
 
 	mutex_lock(&wdev->conf_mutex);
@@ -742,20 +691,19 @@ void wfx_bss_info_changed(struct ieee80211_hw *hw,
 		}
 	}
 
-	if (changed & BSS_CHANGED_BEACON ||
-	    changed & BSS_CHANGED_AP_PROBE_RESP ||
-	    changed & BSS_CHANGED_BSSID ||
-	    changed & BSS_CHANGED_SSID ||
-	    changed & BSS_CHANGED_IBSS) {
-		wvif->beacon_int = info->beacon_int;
-		wfx_update_beaconing(wvif);
-		wfx_upload_ap_templates(wvif);
-		wfx_fwd_probe_req(wvif, false);
+	if (changed & BSS_CHANGED_BASIC_RATES ||
+	    changed & BSS_CHANGED_BEACON_INT ||
+	    changed & BSS_CHANGED_BSSID) {
+		if (vif->type == NL80211_IFTYPE_STATION)
+			wfx_do_join(wvif);
 	}
 
-	if (changed & BSS_CHANGED_BEACON_ENABLED &&
-	    wvif->state != WFX_STATE_IBSS)
-		hif_beacon_transmit(wvif, info->enable_beacon);
+	if (changed & BSS_CHANGED_AP_PROBE_RESP ||
+	    changed & BSS_CHANGED_BEACON)
+		wfx_upload_ap_templates(wvif);
+
+	if (changed & BSS_CHANGED_BEACON_ENABLED)
+		wfx_enable_beacon(wvif, info->enable_beacon);
 
 	if (changed & BSS_CHANGED_BEACON_INFO)
 		hif_set_beacon_wakeup_period(wvif, info->dtim_period,
@@ -768,66 +716,27 @@ void wfx_bss_info_changed(struct ieee80211_hw *hw,
 		wfx_tx_unlock(wdev);
 	}
 
-	if (changed & BSS_CHANGED_ASSOC && !info->assoc &&
-	    (wvif->state == WFX_STATE_STA || wvif->state == WFX_STATE_IBSS)) {
-		/* Shedule unjoin work */
-		wfx_tx_lock(wdev);
-		if (!schedule_work(&wvif->unjoin_work))
-			wfx_tx_unlock(wdev);
-	} else {
-		if (changed & BSS_CHANGED_BEACON_INT) {
-			if (info->ibss_joined)
-				do_join = true;
-			else if (wvif->state == WFX_STATE_AP)
-				wfx_update_beaconing(wvif);
-		}
-
-		if (changed & BSS_CHANGED_BSSID)
-			do_join = true;
-
-		if (changed & BSS_CHANGED_ASSOC ||
-		    changed & BSS_CHANGED_BSSID ||
-		    changed & BSS_CHANGED_IBSS ||
-		    changed & BSS_CHANGED_BASIC_RATES ||
-		    changed & BSS_CHANGED_HT) {
-			if (info->assoc) {
-				if (wvif->state < WFX_STATE_PRE_STA) {
-					ieee80211_connection_loss(vif);
-					mutex_unlock(&wdev->conf_mutex);
-					return;
-				} else if (wvif->state == WFX_STATE_PRE_STA) {
-					wvif->state = WFX_STATE_STA;
-				}
-			} else {
-				do_join = true;
-			}
-
-			if (info->assoc || info->ibss_joined)
-				wfx_join_finalize(wvif, info);
-			else
-				memset(&wvif->bss_params, 0,
-				       sizeof(wvif->bss_params));
-		}
+	if (changed & BSS_CHANGED_ASSOC) {
+		if (info->assoc || info->ibss_joined)
+			wfx_join_finalize(wvif, info);
+		else if (!info->assoc && vif->type == NL80211_IFTYPE_STATION)
+			wfx_do_unjoin(wvif);
+		else
+			dev_warn(wdev->dev, "%s: misunderstood change: ASSOC\n",
+				 __func__);
 	}
 
-	if (changed & BSS_CHANGED_ASSOC ||
-	    changed & BSS_CHANGED_ERP_CTS_PROT ||
-	    changed & BSS_CHANGED_ERP_PREAMBLE) {
-		u8 erp_ie[3] = { WLAN_EID_ERP_INFO, 1, 0 };
+	if (changed & BSS_CHANGED_KEEP_ALIVE)
+		hif_keep_alive_period(wvif, info->max_idle_period *
+					    USEC_PER_TU / USEC_PER_MSEC);
 
+	if (changed & BSS_CHANGED_ERP_CTS_PROT)
 		hif_erp_use_protection(wvif, info->use_cts_prot);
-		if (info->use_cts_prot)
-			erp_ie[2] |= WLAN_ERP_USE_PROTECTION;
-		if (info->use_short_preamble)
-			erp_ie[2] |= WLAN_ERP_BARKER_PREAMBLE;
-		if (wvif->vif->type != NL80211_IFTYPE_STATION)
-			hif_update_ie_beacon(wvif, erp_ie, sizeof(erp_ie));
-	}
 
-	if (changed & BSS_CHANGED_ASSOC || changed & BSS_CHANGED_ERP_SLOT)
+	if (changed & BSS_CHANGED_ERP_SLOT)
 		hif_slot_time(wvif, info->use_short_slot ? 9 : 20);
 
-	if (changed & BSS_CHANGED_ASSOC || changed & BSS_CHANGED_CQM)
+	if (changed & BSS_CHANGED_CQM)
 		hif_set_rcpi_rssi_threshold(wvif, info->cqm_rssi_thold,
 					    info->cqm_rssi_hyst);
 
@@ -838,31 +747,6 @@ void wfx_bss_info_changed(struct ieee80211_hw *hw,
 		wfx_update_pm(wvif);
 
 	mutex_unlock(&wdev->conf_mutex);
-
-	if (do_join)
-		wfx_do_join(wvif);
-}
-
-static void wfx_ps_notify_sta(struct wfx_vif *wvif,
-			      enum sta_notify_cmd notify_cmd, int link_id)
-{
-	spin_lock_bh(&wvif->ps_state_lock);
-	if (notify_cmd == STA_NOTIFY_SLEEP)
-		wvif->sta_asleep_mask |= BIT(link_id);
-	else // notify_cmd == STA_NOTIFY_AWAKE
-		wvif->sta_asleep_mask &= ~BIT(link_id);
-	spin_unlock_bh(&wvif->ps_state_lock);
-	if (notify_cmd == STA_NOTIFY_AWAKE)
-		wfx_bh_request_tx(wvif->wdev);
-}
-
-void wfx_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-		    enum sta_notify_cmd notify_cmd, struct ieee80211_sta *sta)
-{
-	struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv;
-	struct wfx_sta_priv *sta_priv = (struct wfx_sta_priv *) &sta->drv_priv;
-
-	wfx_ps_notify_sta(wvif, notify_cmd, sta_priv->link_id);
 }
 
 static int wfx_update_tim(struct wfx_vif *wvif)
@@ -873,10 +757,8 @@ static int wfx_update_tim(struct wfx_vif *wvif)
 
 	skb = ieee80211_beacon_get_tim(wvif->wdev->hw, wvif->vif,
 				       &tim_offset, &tim_length);
-	if (!skb) {
-		__wfx_flush(wvif->wdev, true);
+	if (!skb)
 		return -ENOENT;
-	}
 	tim_ptr = skb->data + tim_offset;
 
 	if (tim_offset && tim_length >= 6) {
@@ -886,7 +768,7 @@ static int wfx_update_tim(struct wfx_vif *wvif)
 		tim_ptr[2] = 0;
 
 		/* Set/reset aid0 bit */
-		if (wfx_tx_queues_get_after_dtim(wvif))
+		if (wfx_tx_queues_has_cab(wvif))
 			tim_ptr[4] |= 1;
 		else
 			tim_ptr[4] &= ~1;
@@ -917,7 +799,7 @@ int wfx_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set)
 
 void wfx_suspend_resume_mc(struct wfx_vif *wvif, enum sta_notify_cmd notify_cmd)
 {
-	WARN(!wfx_tx_queues_get_after_dtim(wvif), "incorrect sequence");
+	WARN(!wfx_tx_queues_has_cab(wvif), "incorrect sequence");
 	WARN(wvif->after_dtim_tx_allowed, "incorrect sequence");
 	wvif->after_dtim_tx_allowed = true;
 	wfx_bh_request_tx(wvif->wdev);
@@ -1021,7 +903,6 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 	wvif->wdev = wdev;
 
 	wvif->link_id_map = 1; // link-id 0 is reserved for multicast
-	spin_lock_init(&wvif->ps_state_lock);
 	INIT_WORK(&wvif->update_tim_work, wfx_update_tim_work);
 
 	memset(&wvif->bss_params, 0, sizeof(wvif->bss_params));
@@ -1040,7 +921,6 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 	complete(&wvif->set_pm_mode_complete);
 	INIT_WORK(&wvif->update_filtering_work, wfx_update_filtering_work);
 	INIT_WORK(&wvif->bss_params_work, wfx_bss_params_work);
-	INIT_WORK(&wvif->unjoin_work, wfx_unjoin_work);
 	INIT_WORK(&wvif->tx_policy_upload_work, wfx_tx_policy_upload_work);
 
 	mutex_init(&wvif->scan_lock);
@@ -1080,12 +960,9 @@ void wfx_remove_interface(struct ieee80211_hw *hw,
 	case WFX_STATE_PRE_STA:
 	case WFX_STATE_STA:
 	case WFX_STATE_IBSS:
-		wfx_tx_lock_flush(wdev);
-		if (!schedule_work(&wvif->unjoin_work))
-			wfx_tx_unlock(wdev);
+		wfx_do_unjoin(wvif);
 		break;
 	case WFX_STATE_AP:
-		wvif->sta_asleep_mask = 0;
 		/* reset.link_id = 0; */
 		hif_reset(wvif, false);
 		break;
@@ -1094,14 +971,11 @@ void wfx_remove_interface(struct ieee80211_hw *hw,
 	}
 
 	wvif->state = WFX_STATE_PASSIVE;
-	wfx_tx_queues_wait_empty_vif(wvif);
-	wfx_tx_unlock(wdev);
 
 	/* FIXME: In add to reset MAC address, try to reset interface */
 	hif_set_macaddr(wvif, NULL);
 
 	wfx_cqm_bssloss_sm(wvif, 0, 0, 0);
-	cancel_work_sync(&wvif->unjoin_work);
 	wfx_free_event_queue(wvif);
 
 	wdev->vif[wvif->id] = NULL;
@@ -1129,10 +1003,5 @@ void wfx_stop(struct ieee80211_hw *hw)
 {
 	struct wfx_dev *wdev = hw->priv;
 
-	wfx_tx_lock_flush(wdev);
-	mutex_lock(&wdev->conf_mutex);
-	wfx_tx_queues_clear(wdev);
-	mutex_unlock(&wdev->conf_mutex);
-	wfx_tx_unlock(wdev);
-	WARN(atomic_read(&wdev->tx_lock), "tx_lock is locked");
+	wfx_tx_queues_check_empty(wdev);
 }
diff --git a/drivers/staging/wfx/sta.h b/drivers/staging/wfx/sta.h
index cf99a8a74a81..3002d89dc871 100644
--- a/drivers/staging/wfx/sta.h
+++ b/drivers/staging/wfx/sta.h
@@ -54,8 +54,10 @@ void wfx_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
 
 int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
 void wfx_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
-void wfx_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-	       u32 queues, bool drop);
+int wfx_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
+void wfx_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
+int wfx_join_ibss(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
+void wfx_leave_ibss(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
 int wfx_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 		u16 queue, const struct ieee80211_tx_queue_params *params);
 void wfx_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h
index 8b85bb1abb9c..41d67dc091a6 100644
--- a/drivers/staging/wfx/wfx.h
+++ b/drivers/staging/wfx/wfx.h
@@ -50,8 +50,8 @@ struct wfx_dev {
 
 	struct wfx_hif_cmd	hif_cmd;
 	struct wfx_queue	tx_queue[4];
-	struct wfx_queue_stats	tx_queue_stats;
-	int			tx_burst_idx;
+	struct sk_buff_head	tx_pending;
+	wait_queue_head_t	tx_dequeue;
 	atomic_t		tx_lock;
 
 	atomic_t		packet_id;
@@ -86,23 +86,18 @@ struct wfx_vif {
 	struct tx_policy_cache	tx_policy_cache;
 	struct work_struct	tx_policy_upload_work;
 
-	u32			sta_asleep_mask;
-	spinlock_t		ps_state_lock;
 	struct work_struct	update_tim_work;
 
-	int			beacon_int;
 	bool			filter_bssid;
 	bool			fwd_probe_req;
 	bool			disable_beacon_filter;
 	struct work_struct	update_filtering_work;
 
 	unsigned long		uapsd_mask;
-	struct ieee80211_tx_queue_params edca_params[IEEE80211_NUM_ACS];
 	struct hif_req_set_bss_params bss_params;
 	struct work_struct	bss_params_work;
 
 	int			join_complete_status;
-	struct work_struct	unjoin_work;
 
 	/* avoid some operations in parallel with scan */
 	struct mutex		scan_lock;
diff --git a/drivers/target/target_core_fabric_lib.c b/drivers/target/target_core_fabric_lib.c
index 6b4b354c88aa..1e031d81e59e 100644
--- a/drivers/target/target_core_fabric_lib.c
+++ b/drivers/target/target_core_fabric_lib.c
@@ -63,7 +63,7 @@ static int fc_get_pr_transport_id(
 	 * encoded TransportID.
 	 */
 	ptr = &se_nacl->initiatorname[0];
-	for (i = 0; i < 24; ) {
+	for (i = 0; i < 23; ) {
 		if (!strncmp(&ptr[i], ":", 1)) {
 			i++;
 			continue;
@@ -341,7 +341,8 @@ static char *iscsi_parse_pr_out_transport_id(
 			*p = tolower(*p);
 			p++;
 		}
-	}
+	} else
+		*port_nexus_ptr = NULL;
 
 	return &buf[4];
 }
diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c
index 0b9dfa6b17bc..f769bb1e3735 100644
--- a/drivers/target/target_core_user.c
+++ b/drivers/target/target_core_user.c
@@ -2073,6 +2073,7 @@ static void tcmu_reset_ring(struct tcmu_dev *udev, u8 err_level)
 	mb->cmd_tail = 0;
 	mb->cmd_head = 0;
 	tcmu_flush_dcache_range(mb, sizeof(*mb));
+	clear_bit(TCMU_DEV_BIT_BROKEN, &udev->flags);
 
 	del_timer(&udev->cmd_timer);
 
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 91af271e9bb0..e53314ea9e25 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -273,6 +273,16 @@ config IMX8MM_THERMAL
 	  cpufreq is used as the cooling device to throttle CPUs when the passive
 	  trip is crossed.
 
+config K3_THERMAL
+	tristate "Texas Instruments K3 thermal support"
+	depends on ARCH_K3 || COMPILE_TEST
+	help
+	  If you say yes here you get thermal support for the Texas Instruments
+	  K3 SoC family. The current chip supported is:
+	  - AM654
+
+	  This includes temperature reading functionality.
+
 config MAX77620_THERMAL
 	tristate "Temperature sensor driver for Maxim MAX77620 PMIC"
 	depends on MFD_MAX77620
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 8c8ed7b79915..86c506410cc0 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -28,6 +28,7 @@ thermal_sys-$(CONFIG_CLOCK_THERMAL)	+= clock_cooling.o
 # devfreq cooling
 thermal_sys-$(CONFIG_DEVFREQ_THERMAL) += devfreq_cooling.o
 
+obj-$(CONFIG_K3_THERMAL)	+= k3_bandgap.o
 # platform thermal drivers
 obj-y				+= broadcom/
 obj-$(CONFIG_THERMAL_MMIO)		+= thermal_mmio.o
diff --git a/drivers/thermal/devfreq_cooling.c b/drivers/thermal/devfreq_cooling.c
index a87d4fa031c8..f7f32e98331b 100644
--- a/drivers/thermal/devfreq_cooling.c
+++ b/drivers/thermal/devfreq_cooling.c
@@ -24,11 +24,13 @@
 #include <linux/idr.h>
 #include <linux/slab.h>
 #include <linux/pm_opp.h>
+#include <linux/pm_qos.h>
 #include <linux/thermal.h>
 
 #include <trace/events/thermal.h>
 
-#define SCALE_ERROR_MITIGATION 100
+#define HZ_PER_KHZ		1000
+#define SCALE_ERROR_MITIGATION	100
 
 static DEFINE_IDA(devfreq_ida);
 
@@ -54,6 +56,8 @@ static DEFINE_IDA(devfreq_ida);
  *		The 'res_util' range is from 100 to (power_table[state] * 100)
  *		for the corresponding 'state'.
  * @capped_state:	index to cooling state with in dynamic power budget
+ * @req_max_freq:	PM QoS request for limiting the maximum frequency
+ *			of the devfreq device.
  */
 struct devfreq_cooling_device {
 	int id;
@@ -66,49 +70,9 @@ struct devfreq_cooling_device {
 	struct devfreq_cooling_power *power_ops;
 	u32 res_util;
 	int capped_state;
+	struct dev_pm_qos_request req_max_freq;
 };
 
-/**
- * partition_enable_opps() - disable all opps above a given state
- * @dfc:	Pointer to devfreq we are operating on
- * @cdev_state:	cooling device state we're setting
- *
- * Go through the OPPs of the device, enabling all OPPs until
- * @cdev_state and disabling those frequencies above it.
- */
-static int partition_enable_opps(struct devfreq_cooling_device *dfc,
-				 unsigned long cdev_state)
-{
-	int i;
-	struct device *dev = dfc->devfreq->dev.parent;
-
-	for (i = 0; i < dfc->freq_table_size; i++) {
-		struct dev_pm_opp *opp;
-		int ret = 0;
-		unsigned int freq = dfc->freq_table[i];
-		bool want_enable = i >= cdev_state ? true : false;
-
-		opp = dev_pm_opp_find_freq_exact(dev, freq, !want_enable);
-
-		if (PTR_ERR(opp) == -ERANGE)
-			continue;
-		else if (IS_ERR(opp))
-			return PTR_ERR(opp);
-
-		dev_pm_opp_put(opp);
-
-		if (want_enable)
-			ret = dev_pm_opp_enable(dev, freq);
-		else
-			ret = dev_pm_opp_disable(dev, freq);
-
-		if (ret)
-			return ret;
-	}
-
-	return 0;
-}
-
 static int devfreq_cooling_get_max_state(struct thermal_cooling_device *cdev,
 					 unsigned long *state)
 {
@@ -135,7 +99,7 @@ static int devfreq_cooling_set_cur_state(struct thermal_cooling_device *cdev,
 	struct devfreq_cooling_device *dfc = cdev->devdata;
 	struct devfreq *df = dfc->devfreq;
 	struct device *dev = df->dev.parent;
-	int ret;
+	unsigned long freq;
 
 	if (state == dfc->cooling_state)
 		return 0;
@@ -145,9 +109,10 @@ static int devfreq_cooling_set_cur_state(struct thermal_cooling_device *cdev,
 	if (state >= dfc->freq_table_size)
 		return -EINVAL;
 
-	ret = partition_enable_opps(dfc, state);
-	if (ret)
-		return ret;
+	freq = dfc->freq_table[state];
+
+	dev_pm_qos_update_request(&dfc->req_max_freq,
+				  DIV_ROUND_UP(freq, HZ_PER_KHZ));
 
 	dfc->cooling_state = state;
 
@@ -530,9 +495,15 @@ of_devfreq_cooling_register_power(struct device_node *np, struct devfreq *df,
 	if (err)
 		goto free_dfc;
 
-	err = ida_simple_get(&devfreq_ida, 0, 0, GFP_KERNEL);
+	err = dev_pm_qos_add_request(df->dev.parent, &dfc->req_max_freq,
+				     DEV_PM_QOS_MAX_FREQUENCY,
+				     PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE);
 	if (err < 0)
 		goto free_tables;
+
+	err = ida_simple_get(&devfreq_ida, 0, 0, GFP_KERNEL);
+	if (err < 0)
+		goto remove_qos_req;
 	dfc->id = err;
 
 	snprintf(dev_name, sizeof(dev_name), "thermal-devfreq-%d", dfc->id);
@@ -553,6 +524,10 @@ of_devfreq_cooling_register_power(struct device_node *np, struct devfreq *df,
 
 release_ida:
 	ida_simple_remove(&devfreq_ida, dfc->id);
+
+remove_qos_req:
+	dev_pm_qos_remove_request(&dfc->req_max_freq);
+
 free_tables:
 	kfree(dfc->power_table);
 	kfree(dfc->freq_table);
@@ -601,6 +576,7 @@ void devfreq_cooling_unregister(struct thermal_cooling_device *cdev)
 
 	thermal_cooling_device_unregister(dfc->cdev);
 	ida_simple_remove(&devfreq_ida, dfc->id);
+	dev_pm_qos_remove_request(&dfc->req_max_freq);
 	kfree(dfc->power_table);
 	kfree(dfc->freq_table);
 
diff --git a/drivers/thermal/imx_sc_thermal.c b/drivers/thermal/imx_sc_thermal.c
index a8723b1eb8b0..b2b68c943738 100644
--- a/drivers/thermal/imx_sc_thermal.c
+++ b/drivers/thermal/imx_sc_thermal.c
@@ -14,6 +14,7 @@
 #include <linux/thermal.h>
 
 #include "thermal_core.h"
+#include "thermal_hwmon.h"
 
 #define IMX_SC_MISC_FUNC_GET_TEMP	13
 
@@ -115,6 +116,9 @@ static int imx_sc_thermal_probe(struct platform_device *pdev)
 			ret = PTR_ERR(sensor->tzd);
 			break;
 		}
+
+		if (devm_thermal_add_hwmon_sysfs(sensor->tzd))
+			dev_warn(&pdev->dev, "failed to add hwmon sysfs attributes\n");
 	}
 
 	of_node_put(sensor_np);
diff --git a/drivers/thermal/intel/int340x_thermal/int3400_thermal.c b/drivers/thermal/intel/int340x_thermal/int3400_thermal.c
index ceef89c956bd..e802922a13cf 100644
--- a/drivers/thermal/intel/int340x_thermal/int3400_thermal.c
+++ b/drivers/thermal/intel/int340x_thermal/int3400_thermal.c
@@ -271,6 +271,8 @@ static int int3400_thermal_set_mode(struct thermal_zone_device *thermal,
 
 static struct thermal_zone_device_ops int3400_thermal_ops = {
 	.get_temp = int3400_thermal_get_temp,
+	.get_mode = int3400_thermal_get_mode,
+	.set_mode = int3400_thermal_set_mode,
 };
 
 static struct thermal_zone_params int3400_thermal_params = {
@@ -309,9 +311,6 @@ static int int3400_thermal_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, priv);
 
-	int3400_thermal_ops.get_mode = int3400_thermal_get_mode;
-	int3400_thermal_ops.set_mode = int3400_thermal_set_mode;
-
 	priv->thermal = thermal_zone_device_register("INT3400 Thermal", 0, 0,
 						priv, &int3400_thermal_ops,
 						&int3400_thermal_params, 0, 0);
diff --git a/drivers/thermal/k3_bandgap.c b/drivers/thermal/k3_bandgap.c
new file mode 100644
index 000000000000..35f41e8a0b75
--- /dev/null
+++ b/drivers/thermal/k3_bandgap.c
@@ -0,0 +1,264 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * TI Bandgap temperature sensor driver for K3 SoC Family
+ *
+ * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/pm_runtime.h>
+#include <linux/thermal.h>
+#include <linux/types.h>
+
+#define K3_VTM_DEVINFO_PWR0_OFFSET		0x4
+#define K3_VTM_DEVINFO_PWR0_TEMPSENS_CT_MASK	0xf0
+#define K3_VTM_TMPSENS0_CTRL_OFFSET	0x80
+#define K3_VTM_REGS_PER_TS			0x10
+#define K3_VTM_TS_STAT_DTEMP_MASK	0x3ff
+#define K3_VTM_TMPSENS_CTRL_CBIASSEL	BIT(0)
+#define K3_VTM_TMPSENS_CTRL_SOC		BIT(5)
+#define K3_VTM_TMPSENS_CTRL_CLRZ		BIT(6)
+#define K3_VTM_TMPSENS_CTRL_CLKON_REQ	BIT(7)
+
+#define K3_VTM_ADC_BEGIN_VAL		540
+#define K3_VTM_ADC_END_VAL		944
+
+static const int k3_adc_to_temp[] = {
+	-40000, -40000, -40000, -40000, -39800, -39400, -39000, -38600, -38200,
+	-37800, -37400, -37000, -36600, -36200, -35800, -35300, -34700, -34200,
+	-33800, -33400, -33000, -32600, -32200, -31800, -31400, -31000, -30600,
+	-30200, -29800, -29400, -29000, -28600, -28200, -27700, -27100, -26600,
+	-26200, -25800, -25400, -25000, -24600, -24200, -23800, -23400, -23000,
+	-22600, -22200, -21800, -21400, -21000, -20500, -19900, -19400, -19000,
+	-18600, -18200, -17800, -17400, -17000, -16600, -16200, -15800, -15400,
+	-15000, -14600, -14200, -13800, -13400, -13000, -12500, -11900, -11400,
+	-11000, -10600, -10200, -9800, -9400, -9000, -8600, -8200, -7800, -7400,
+	-7000, -6600, -6200, -5800, -5400, -5000, -4500, -3900, -3400, -3000,
+	-2600, -2200, -1800, -1400, -1000, -600, -200, 200, 600, 1000, 1400,
+	1800, 2200, 2600, 3000, 3400, 3900, 4500, 5000, 5400, 5800, 6200, 6600,
+	7000, 7400, 7800, 8200, 8600, 9000, 9400, 9800, 10200, 10600, 11000,
+	11400, 11800, 12200, 12700, 13300, 13800, 14200, 14600, 15000, 15400,
+	15800, 16200, 16600, 17000, 17400, 17800, 18200, 18600, 19000, 19400,
+	19800, 20200, 20600, 21000, 21400, 21900, 22500, 23000, 23400, 23800,
+	24200, 24600, 25000, 25400, 25800, 26200, 26600, 27000, 27400, 27800,
+	28200, 28600, 29000, 29400, 29800, 30200, 30600, 31000, 31400, 31900,
+	32500, 33000, 33400, 33800, 34200, 34600, 35000, 35400, 35800, 36200,
+	36600, 37000, 37400, 37800, 38200, 38600, 39000, 39400, 39800, 40200,
+	40600, 41000, 41400, 41800, 42200, 42600, 43100, 43700, 44200, 44600,
+	45000, 45400, 45800, 46200, 46600, 47000, 47400, 47800, 48200, 48600,
+	49000, 49400, 49800, 50200, 50600, 51000, 51400, 51800, 52200, 52600,
+	53000, 53400, 53800, 54200, 54600, 55000, 55400, 55900, 56500, 57000,
+	57400, 57800, 58200, 58600, 59000, 59400, 59800, 60200, 60600, 61000,
+	61400, 61800, 62200, 62600, 63000, 63400, 63800, 64200, 64600, 65000,
+	65400, 65800, 66200, 66600, 67000, 67400, 67800, 68200, 68600, 69000,
+	69400, 69800, 70200, 70600, 71000, 71500, 72100, 72600, 73000, 73400,
+	73800, 74200, 74600, 75000, 75400, 75800, 76200, 76600, 77000, 77400,
+	77800, 78200, 78600, 79000, 79400, 79800, 80200, 80600, 81000, 81400,
+	81800, 82200, 82600, 83000, 83400, 83800, 84200, 84600, 85000, 85400,
+	85800, 86200, 86600, 87000, 87400, 87800, 88200, 88600, 89000, 89400,
+	89800, 90200, 90600, 91000, 91400, 91800, 92200, 92600, 93000, 93400,
+	93800, 94200, 94600, 95000, 95400, 95800, 96200, 96600, 97000, 97500,
+	98100, 98600, 99000, 99400, 99800, 100200, 100600, 101000, 101400,
+	101800, 102200, 102600, 103000, 103400, 103800, 104200, 104600, 105000,
+	105400, 105800, 106200, 106600, 107000, 107400, 107800, 108200, 108600,
+	109000, 109400, 109800, 110200, 110600, 111000, 111400, 111800, 112200,
+	112600, 113000, 113400, 113800, 114200, 114600, 115000, 115400, 115800,
+	116200, 116600, 117000, 117400, 117800, 118200, 118600, 119000, 119400,
+	119800, 120200, 120600, 121000, 121400, 121800, 122200, 122600, 123000,
+	123400, 123800, 124200, 124600, 124900, 125000,
+};
+
+struct k3_bandgap {
+	void __iomem *base;
+	const struct k3_bandgap_data *conf;
+};
+
+/* common data structures */
+struct k3_thermal_data {
+	struct thermal_zone_device *tzd;
+	struct k3_bandgap *bgp;
+	int sensor_id;
+	u32 ctrl_offset;
+	u32 stat_offset;
+};
+
+static unsigned int vtm_get_best_value(unsigned int s0, unsigned int s1,
+				       unsigned int s2)
+{
+	int d01 = abs(s0 - s1);
+	int d02 = abs(s0 - s2);
+	int d12 = abs(s1 - s2);
+
+	if (d01 <= d02 && d01 <= d12)
+		return (s0 + s1) / 2;
+
+	if (d02 <= d01 && d02 <= d12)
+		return (s0 + s2) / 2;
+
+	return (s1 + s2) / 2;
+}
+
+static int k3_bgp_read_temp(struct k3_thermal_data *devdata,
+			    int *temp)
+{
+	struct k3_bandgap *bgp;
+	unsigned int dtemp, s0, s1, s2;
+
+	bgp = devdata->bgp;
+
+	/*
+	 * Errata is applicable for am654 pg 1.0 silicon. There
+	 * is a variation of the order for 8-10 degree centigrade.
+	 * Work around that by getting the average of two closest
+	 * readings out of three readings everytime we want to
+	 * report temperatures.
+	 *
+	 * Errata workaround.
+	 */
+	s0 = readl(bgp->base + devdata->stat_offset) &
+		K3_VTM_TS_STAT_DTEMP_MASK;
+	s1 = readl(bgp->base + devdata->stat_offset) &
+		K3_VTM_TS_STAT_DTEMP_MASK;
+	s2 = readl(bgp->base + devdata->stat_offset) &
+		K3_VTM_TS_STAT_DTEMP_MASK;
+	dtemp = vtm_get_best_value(s0, s1, s2);
+
+	if (dtemp < K3_VTM_ADC_BEGIN_VAL || dtemp > K3_VTM_ADC_END_VAL)
+		return -EINVAL;
+
+	*temp = k3_adc_to_temp[dtemp - K3_VTM_ADC_BEGIN_VAL];
+
+	return 0;
+}
+
+static int k3_thermal_get_temp(void *devdata, int *temp)
+{
+	struct k3_thermal_data *data = devdata;
+	int ret = 0;
+
+	ret = k3_bgp_read_temp(data, temp);
+	if (ret)
+		return ret;
+
+	return ret;
+}
+
+static const struct thermal_zone_of_device_ops k3_of_thermal_ops = {
+	.get_temp = k3_thermal_get_temp,
+};
+
+static const struct of_device_id of_k3_bandgap_match[];
+
+static int k3_bandgap_probe(struct platform_device *pdev)
+{
+	int ret = 0, cnt, val, id;
+	struct resource *res;
+	struct device *dev = &pdev->dev;
+	struct k3_bandgap *bgp;
+	struct k3_thermal_data *data;
+
+	if (ARRAY_SIZE(k3_adc_to_temp) != (K3_VTM_ADC_END_VAL + 1 -
+						K3_VTM_ADC_BEGIN_VAL))
+		return -EINVAL;
+
+	bgp = devm_kzalloc(&pdev->dev, sizeof(*bgp), GFP_KERNEL);
+	if (!bgp)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	bgp->base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(bgp->base))
+		return PTR_ERR(bgp->base);
+
+	pm_runtime_enable(dev);
+	ret = pm_runtime_get_sync(dev);
+	if (ret < 0) {
+		pm_runtime_put_noidle(dev);
+		pm_runtime_disable(dev);
+		return ret;
+	}
+
+	/* Get the sensor count in the VTM */
+	val = readl(bgp->base + K3_VTM_DEVINFO_PWR0_OFFSET);
+	cnt = val & K3_VTM_DEVINFO_PWR0_TEMPSENS_CT_MASK;
+	cnt >>= __ffs(K3_VTM_DEVINFO_PWR0_TEMPSENS_CT_MASK);
+
+	data = devm_kcalloc(dev, cnt, sizeof(*data), GFP_KERNEL);
+	if (!data) {
+		ret = -ENOMEM;
+		goto err_alloc;
+	}
+
+	/* Register the thermal sensors */
+	for (id = 0; id < cnt; id++) {
+		data[id].sensor_id = id;
+		data[id].bgp = bgp;
+		data[id].ctrl_offset = K3_VTM_TMPSENS0_CTRL_OFFSET +
+					id * K3_VTM_REGS_PER_TS;
+		data[id].stat_offset = data[id].ctrl_offset + 0x8;
+
+		val = readl(data[id].bgp->base + data[id].ctrl_offset);
+		val |= (K3_VTM_TMPSENS_CTRL_SOC |
+			K3_VTM_TMPSENS_CTRL_CLRZ |
+			K3_VTM_TMPSENS_CTRL_CLKON_REQ);
+		val &= ~K3_VTM_TMPSENS_CTRL_CBIASSEL;
+		writel(val, data[id].bgp->base + data[id].ctrl_offset);
+
+		data[id].tzd =
+		devm_thermal_zone_of_sensor_register(dev, id,
+						     &data[id],
+						     &k3_of_thermal_ops);
+		if (IS_ERR(data[id].tzd)) {
+			dev_err(dev, "thermal zone device is NULL\n");
+			ret = PTR_ERR(data[id].tzd);
+			goto err_alloc;
+		}
+	}
+
+	platform_set_drvdata(pdev, bgp);
+
+	return 0;
+
+err_alloc:
+	pm_runtime_put_sync(dev);
+	pm_runtime_disable(dev);
+
+	return ret;
+}
+
+static int k3_bandgap_remove(struct platform_device *pdev)
+{
+	pm_runtime_put_sync(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
+
+	return 0;
+}
+
+static const struct of_device_id of_k3_bandgap_match[] = {
+	{
+		.compatible = "ti,am654-vtm",
+	},
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, of_k3_bandgap_match);
+
+static struct platform_driver k3_bandgap_sensor_driver = {
+	.probe = k3_bandgap_probe,
+	.remove = k3_bandgap_remove,
+	.driver = {
+		.name = "k3-soc-thermal",
+		.of_match_table	= of_k3_bandgap_match,
+	},
+};
+
+module_platform_driver(k3_bandgap_sensor_driver);
+
+MODULE_DESCRIPTION("K3 bandgap temperature sensor driver");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("J Keerthy <j-keerthy@ti.com>");
diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c
index 7c1a8bccdcba..15a71ecc916c 100644
--- a/drivers/thermal/rockchip_thermal.c
+++ b/drivers/thermal/rockchip_thermal.c
@@ -1241,10 +1241,8 @@ static int rockchip_thermal_probe(struct platform_device *pdev)
 		return -ENXIO;
 
 	irq = platform_get_irq(pdev, 0);
-	if (irq < 0) {
-		dev_err(&pdev->dev, "no irq resource?\n");
+	if (irq < 0)
 		return -EINVAL;
-	}
 
 	thermal = devm_kzalloc(&pdev->dev, sizeof(struct rockchip_thermal_data),
 			       GFP_KERNEL);
diff --git a/drivers/thermal/st/st_thermal_memmap.c b/drivers/thermal/st/st_thermal_memmap.c
index a824b78dabf8..a0114452d11f 100644
--- a/drivers/thermal/st/st_thermal_memmap.c
+++ b/drivers/thermal/st/st_thermal_memmap.c
@@ -94,10 +94,8 @@ static int st_mmap_register_enable_irq(struct st_thermal_sensor *sensor)
 	int ret;
 
 	sensor->irq = platform_get_irq(pdev, 0);
-	if (sensor->irq < 0) {
-		dev_err(dev, "failed to register IRQ\n");
+	if (sensor->irq < 0)
 		return sensor->irq;
-	}
 
 	ret = devm_request_threaded_irq(dev, sensor->irq,
 					NULL, st_mmap_thermal_trip_handler,
diff --git a/drivers/thermal/st/stm_thermal.c b/drivers/thermal/st/stm_thermal.c
index 9314e3df6a42..331e2b768df5 100644
--- a/drivers/thermal/st/stm_thermal.c
+++ b/drivers/thermal/st/stm_thermal.c
@@ -385,10 +385,8 @@ static int stm_register_irq(struct stm_thermal_sensor *sensor)
 	int ret;
 
 	sensor->irq = platform_get_irq(pdev, 0);
-	if (sensor->irq < 0) {
-		dev_err(dev, "%s: Unable to find IRQ\n", __func__);
+	if (sensor->irq < 0)
 		return sensor->irq;
-	}
 
 	ret = devm_request_threaded_irq(dev, sensor->irq,
 					NULL,
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index 9a321dc548c8..c06550930979 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -447,12 +447,6 @@ static void update_temperature(struct thermal_zone_device *tz)
 	mutex_unlock(&tz->lock);
 
 	trace_thermal_temperature(tz);
-	if (tz->last_temperature == THERMAL_TEMP_INVALID)
-		dev_dbg(&tz->device, "last_temperature N/A, current_temperature=%d\n",
-			tz->temperature);
-	else
-		dev_dbg(&tz->device, "last_temperature=%d, current_temperature=%d\n",
-			tz->last_temperature, tz->temperature);
 }
 
 static void thermal_zone_device_init(struct thermal_zone_device *tz)
diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h
index a9bf00e91d64..c95689586e19 100644
--- a/drivers/thermal/thermal_core.h
+++ b/drivers/thermal/thermal_core.h
@@ -12,6 +12,17 @@
 #include <linux/device.h>
 #include <linux/thermal.h>
 
+/* Default Thermal Governor */
+#if defined(CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE)
+#define DEFAULT_THERMAL_GOVERNOR       "step_wise"
+#elif defined(CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE)
+#define DEFAULT_THERMAL_GOVERNOR       "fair_share"
+#elif defined(CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE)
+#define DEFAULT_THERMAL_GOVERNOR       "user_space"
+#elif defined(CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR)
+#define DEFAULT_THERMAL_GOVERNOR       "power_allocator"
+#endif
+
 /* Initial state of a cooling device during binding */
 #define THERMAL_NO_TARGET -1UL
 
@@ -30,6 +41,44 @@ extern struct thermal_governor *__governor_thermal_table_end[];
 	     __governor < __governor_thermal_table_end;	\
 	     __governor++)
 
+struct thermal_attr {
+	struct device_attribute attr;
+	char name[THERMAL_NAME_LENGTH];
+};
+
+static inline bool cdev_is_power_actor(struct thermal_cooling_device *cdev)
+{
+	return cdev->ops->get_requested_power && cdev->ops->state2power &&
+		cdev->ops->power2state;
+}
+
+int power_actor_get_max_power(struct thermal_cooling_device *cdev,
+			      struct thermal_zone_device *tz, u32 *max_power);
+int power_actor_get_min_power(struct thermal_cooling_device *cdev,
+			      struct thermal_zone_device *tz, u32 *min_power);
+int power_actor_set_power(struct thermal_cooling_device *cdev,
+			  struct thermal_instance *ti, u32 power);
+/**
+ * struct thermal_trip - representation of a point in temperature domain
+ * @np: pointer to struct device_node that this trip point was created from
+ * @temperature: temperature value in miliCelsius
+ * @hysteresis: relative hysteresis in miliCelsius
+ * @type: trip point type
+ */
+struct thermal_trip {
+	struct device_node *np;
+	int temperature;
+	int hysteresis;
+	enum thermal_trip_type type;
+};
+
+int get_tz_trend(struct thermal_zone_device *tz, int trip);
+
+struct thermal_instance *
+get_thermal_instance(struct thermal_zone_device *tz,
+		     struct thermal_cooling_device *cdev,
+		     int trip);
+
 /*
  * This structure is used to describe the behavior of
  * a certain cooling device on a certain trip point
@@ -69,6 +118,9 @@ void thermal_zone_device_unbind_exception(struct thermal_zone_device *,
 int thermal_zone_device_set_policy(struct thermal_zone_device *, char *);
 int thermal_build_list_of_policies(char *buf);
 
+/* Helpers */
+void thermal_zone_set_trips(struct thermal_zone_device *tz);
+
 /* sysfs I/F */
 int thermal_zone_create_device_groups(struct thermal_zone_device *, int);
 void thermal_zone_destroy_device_groups(struct thermal_zone_device *);
diff --git a/drivers/thermal/thermal_helpers.c b/drivers/thermal/thermal_helpers.c
index 2ba756af76b7..59eaf2d0fdb3 100644
--- a/drivers/thermal/thermal_helpers.c
+++ b/drivers/thermal/thermal_helpers.c
@@ -113,6 +113,18 @@ int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp)
 }
 EXPORT_SYMBOL_GPL(thermal_zone_get_temp);
 
+/**
+ * thermal_zone_set_trips - Computes the next trip points for the driver
+ * @tz: a pointer to a thermal zone device structure
+ *
+ * The function computes the next temperature boundaries by browsing
+ * the trip points. The result is the closer low and high trip points
+ * to the current temperature. These values are passed to the backend
+ * driver to let it set its own notification mechanism (usually an
+ * interrupt).
+ *
+ * It does not return a value
+ */
 void thermal_zone_set_trips(struct thermal_zone_device *tz)
 {
 	int low = -INT_MAX;
@@ -161,7 +173,6 @@ void thermal_zone_set_trips(struct thermal_zone_device *tz)
 exit:
 	mutex_unlock(&tz->lock);
 }
-EXPORT_SYMBOL_GPL(thermal_zone_set_trips);
 
 void thermal_cdev_update(struct thermal_cooling_device *cdev)
 {
diff --git a/drivers/thermal/ti-soc-thermal/ti-bandgap.c b/drivers/thermal/ti-soc-thermal/ti-bandgap.c
index 263b0420fbe4..ab19ceff6e2a 100644
--- a/drivers/thermal/ti-soc-thermal/ti-bandgap.c
+++ b/drivers/thermal/ti-soc-thermal/ti-bandgap.c
@@ -772,10 +772,9 @@ static int ti_bandgap_talert_init(struct ti_bandgap *bgp,
 	int ret;
 
 	bgp->irq = platform_get_irq(pdev, 0);
-	if (bgp->irq < 0) {
-		dev_err(&pdev->dev, "get_irq failed\n");
+	if (bgp->irq < 0)
 		return bgp->irq;
-	}
+
 	ret = request_threaded_irq(bgp->irq, NULL,
 				   ti_bandgap_talert_irq_handler,
 				   IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c
index a2ce99051c51..1ba4050f68ac 100644
--- a/drivers/thunderbolt/switch.c
+++ b/drivers/thunderbolt/switch.c
@@ -348,12 +348,6 @@ static int tb_switch_nvm_read(void *priv, unsigned int offset, void *val,
 	return ret;
 }
 
-static int tb_switch_nvm_no_read(void *priv, unsigned int offset, void *val,
-				 size_t bytes)
-{
-	return -EPERM;
-}
-
 static int tb_switch_nvm_write(void *priv, unsigned int offset, void *val,
 			       size_t bytes)
 {
@@ -399,7 +393,6 @@ static struct nvmem_device *register_nvmem(struct tb_switch *sw, int id,
 		config.read_only = true;
 	} else {
 		config.name = "nvm_non_active";
-		config.reg_read = tb_switch_nvm_no_read;
 		config.reg_write = tb_switch_nvm_write;
 		config.root_only = true;
 	}
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index c073aa7001c4..bb000b8f44cc 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -870,9 +870,16 @@ static void sci_receive_chars(struct uart_port *port)
 				tty_insert_flip_char(tport, c, TTY_NORMAL);
 		} else {
 			for (i = 0; i < count; i++) {
-				char c = serial_port_in(port, SCxRDR);
-
-				status = serial_port_in(port, SCxSR);
+				char c;
+
+				if (port->type == PORT_SCIF ||
+				    port->type == PORT_HSCIF) {
+					status = serial_port_in(port, SCxSR);
+					c = serial_port_in(port, SCxRDR);
+				} else {
+					c = serial_port_in(port, SCxRDR);
+					status = serial_port_in(port, SCxSR);
+				}
 				if (uart_handle_sysrq_char(port, c)) {
 					count--; i--;
 					continue;
@@ -1345,7 +1352,7 @@ static int sci_dma_rx_submit(struct sci_port *s, bool port_lock_held)
 {
 	struct dma_chan *chan = s->chan_rx;
 	struct uart_port *port = &s->port;
-	unsigned long flags;
+	unsigned long uninitialized_var(flags);
 	int i;
 
 	for (i = 0; i < 2; i++) {
@@ -2965,10 +2972,7 @@ static int sci_init_single(struct platform_device *dev,
 	port->fifosize		= sci_port->params->fifosize;
 
 	if (port->type == PORT_SCI) {
-		if (sci_port->reg_size >= 0x20)
-			port->regshift = 2;
-		else
-			port->regshift = 1;
+		port->regshift = sci_port->reg_size >> 4;
 	}
 
 	/*
diff --git a/drivers/tty/serial/sunhv.c b/drivers/tty/serial/sunhv.c
index eafada8fb6fa..e35073e93a5b 100644
--- a/drivers/tty/serial/sunhv.c
+++ b/drivers/tty/serial/sunhv.c
@@ -567,6 +567,9 @@ static int hv_probe(struct platform_device *op)
 	sunserial_console_match(&sunhv_console, op->dev.of_node,
 				&sunhv_reg, port->line, false);
 
+	/* We need to initialize lock even for non-registered console */
+	spin_lock_init(&port->lock);
+
 	err = uart_add_one_port(&sunhv_reg, port);
 	if (err)
 		goto out_unregister_driver;
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index 6b26f767768e..ac137b6a1dc1 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -26,13 +26,15 @@
 
 #define CDNS_UART_TTY_NAME	"ttyPS"
 #define CDNS_UART_NAME		"xuartps"
+#define CDNS_UART_MAJOR		0	/* use dynamic node allocation */
+#define CDNS_UART_MINOR		0	/* works best with devtmpfs */
+#define CDNS_UART_NR_PORTS	16
 #define CDNS_UART_FIFO_SIZE	64	/* FIFO size */
 #define CDNS_UART_REGISTER_SPACE	0x1000
 #define TX_TIMEOUT		500000
 
 /* Rx Trigger level */
 static int rx_trigger_level = 56;
-static int uartps_major;
 module_param(rx_trigger_level, uint, 0444);
 MODULE_PARM_DESC(rx_trigger_level, "Rx trigger level, 1-63 bytes");
 
@@ -188,7 +190,6 @@ MODULE_PARM_DESC(rx_timeout, "Rx timeout, 1-255");
  * @pclk:		APB clock
  * @cdns_uart_driver:	Pointer to UART driver
  * @baud:		Current baud rate
- * @id:			Port ID
  * @clk_rate_change_nb:	Notifier block for clock changes
  * @quirks:		Flags for RXBS support.
  */
@@ -198,7 +199,6 @@ struct cdns_uart {
 	struct clk		*pclk;
 	struct uart_driver	*cdns_uart_driver;
 	unsigned int		baud;
-	int			id;
 	struct notifier_block	clk_rate_change_nb;
 	u32			quirks;
 	bool cts_override;
@@ -1133,6 +1133,8 @@ static const struct uart_ops cdns_uart_ops = {
 #endif
 };
 
+static struct uart_driver cdns_uart_uart_driver;
+
 #ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
 /**
  * cdns_uart_console_putchar - write the character to the FIFO buffer
@@ -1272,6 +1274,16 @@ static int cdns_uart_console_setup(struct console *co, char *options)
 
 	return uart_set_options(port, co, baud, parity, bits, flow);
 }
+
+static struct console cdns_uart_console = {
+	.name	= CDNS_UART_TTY_NAME,
+	.write	= cdns_uart_console_write,
+	.device	= uart_console_device,
+	.setup	= cdns_uart_console_setup,
+	.flags	= CON_PRINTBUFFER,
+	.index	= -1, /* Specified on the cmdline (e.g. console=ttyPS ) */
+	.data	= &cdns_uart_uart_driver,
+};
 #endif /* CONFIG_SERIAL_XILINX_PS_UART_CONSOLE */
 
 #ifdef CONFIG_PM_SLEEP
@@ -1403,89 +1415,8 @@ static const struct of_device_id cdns_uart_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, cdns_uart_of_match);
 
-/*
- * Maximum number of instances without alias IDs but if there is alias
- * which target "< MAX_UART_INSTANCES" range this ID can't be used.
- */
-#define MAX_UART_INSTANCES	32
-
-/* Stores static aliases list */
-static DECLARE_BITMAP(alias_bitmap, MAX_UART_INSTANCES);
-static int alias_bitmap_initialized;
-
-/* Stores actual bitmap of allocated IDs with alias IDs together */
-static DECLARE_BITMAP(bitmap, MAX_UART_INSTANCES);
-/* Protect bitmap operations to have unique IDs */
-static DEFINE_MUTEX(bitmap_lock);
-
-static int cdns_get_id(struct platform_device *pdev)
-{
-	int id, ret;
-
-	mutex_lock(&bitmap_lock);
-
-	/* Alias list is stable that's why get alias bitmap only once */
-	if (!alias_bitmap_initialized) {
-		ret = of_alias_get_alias_list(cdns_uart_of_match, "serial",
-					      alias_bitmap, MAX_UART_INSTANCES);
-		if (ret && ret != -EOVERFLOW) {
-			mutex_unlock(&bitmap_lock);
-			return ret;
-		}
-
-		alias_bitmap_initialized++;
-	}
-
-	/* Make sure that alias ID is not taken by instance without alias */
-	bitmap_or(bitmap, bitmap, alias_bitmap, MAX_UART_INSTANCES);
-
-	dev_dbg(&pdev->dev, "Alias bitmap: %*pb\n",
-		MAX_UART_INSTANCES, bitmap);
-
-	/* Look for a serialN alias */
-	id = of_alias_get_id(pdev->dev.of_node, "serial");
-	if (id < 0) {
-		dev_warn(&pdev->dev,
-			 "No serial alias passed. Using the first free id\n");
-
-		/*
-		 * Start with id 0 and check if there is no serial0 alias
-		 * which points to device which is compatible with this driver.
-		 * If alias exists then try next free position.
-		 */
-		id = 0;
-
-		for (;;) {
-			dev_info(&pdev->dev, "Checking id %d\n", id);
-			id = find_next_zero_bit(bitmap, MAX_UART_INSTANCES, id);
-
-			/* No free empty instance */
-			if (id == MAX_UART_INSTANCES) {
-				dev_err(&pdev->dev, "No free ID\n");
-				mutex_unlock(&bitmap_lock);
-				return -EINVAL;
-			}
-
-			dev_dbg(&pdev->dev, "The empty id is %d\n", id);
-			/* Check if ID is empty */
-			if (!test_and_set_bit(id, bitmap)) {
-				/* Break the loop if bit is taken */
-				dev_dbg(&pdev->dev,
-					"Selected ID %d allocation passed\n",
-					id);
-				break;
-			}
-			dev_dbg(&pdev->dev,
-				"Selected ID %d allocation failed\n", id);
-			/* if taking bit fails then try next one */
-			id++;
-		}
-	}
-
-	mutex_unlock(&bitmap_lock);
-
-	return id;
-}
+/* Temporary variable for storing number of instances */
+static int instances;
 
 /**
  * cdns_uart_probe - Platform driver probe
@@ -1495,16 +1426,11 @@ static int cdns_get_id(struct platform_device *pdev)
  */
 static int cdns_uart_probe(struct platform_device *pdev)
 {
-	int rc, irq;
+	int rc, id, irq;
 	struct uart_port *port;
 	struct resource *res;
 	struct cdns_uart *cdns_uart_data;
 	const struct of_device_id *match;
-	struct uart_driver *cdns_uart_uart_driver;
-	char *driver_name;
-#ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
-	struct console *cdns_uart_console;
-#endif
 
 	cdns_uart_data = devm_kzalloc(&pdev->dev, sizeof(*cdns_uart_data),
 			GFP_KERNEL);
@@ -1514,64 +1440,35 @@ static int cdns_uart_probe(struct platform_device *pdev)
 	if (!port)
 		return -ENOMEM;
 
-	cdns_uart_uart_driver = devm_kzalloc(&pdev->dev,
-					     sizeof(*cdns_uart_uart_driver),
-					     GFP_KERNEL);
-	if (!cdns_uart_uart_driver)
-		return -ENOMEM;
-
-	cdns_uart_data->id = cdns_get_id(pdev);
-	if (cdns_uart_data->id < 0)
-		return cdns_uart_data->id;
+	/* Look for a serialN alias */
+	id = of_alias_get_id(pdev->dev.of_node, "serial");
+	if (id < 0)
+		id = 0;
 
-	/* There is a need to use unique driver name */
-	driver_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s%d",
-				     CDNS_UART_NAME, cdns_uart_data->id);
-	if (!driver_name) {
-		rc = -ENOMEM;
-		goto err_out_id;
+	if (id >= CDNS_UART_NR_PORTS) {
+		dev_err(&pdev->dev, "Cannot get uart_port structure\n");
+		return -ENODEV;
 	}
 
-	cdns_uart_uart_driver->owner = THIS_MODULE;
-	cdns_uart_uart_driver->driver_name = driver_name;
-	cdns_uart_uart_driver->dev_name	= CDNS_UART_TTY_NAME;
-	cdns_uart_uart_driver->major = uartps_major;
-	cdns_uart_uart_driver->minor = cdns_uart_data->id;
-	cdns_uart_uart_driver->nr = 1;
-
+	if (!cdns_uart_uart_driver.state) {
+		cdns_uart_uart_driver.owner = THIS_MODULE;
+		cdns_uart_uart_driver.driver_name = CDNS_UART_NAME;
+		cdns_uart_uart_driver.dev_name = CDNS_UART_TTY_NAME;
+		cdns_uart_uart_driver.major = CDNS_UART_MAJOR;
+		cdns_uart_uart_driver.minor = CDNS_UART_MINOR;
+		cdns_uart_uart_driver.nr = CDNS_UART_NR_PORTS;
 #ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
-	cdns_uart_console = devm_kzalloc(&pdev->dev, sizeof(*cdns_uart_console),
-					 GFP_KERNEL);
-	if (!cdns_uart_console) {
-		rc = -ENOMEM;
-		goto err_out_id;
-	}
-
-	strncpy(cdns_uart_console->name, CDNS_UART_TTY_NAME,
-		sizeof(cdns_uart_console->name));
-	cdns_uart_console->index = cdns_uart_data->id;
-	cdns_uart_console->write = cdns_uart_console_write;
-	cdns_uart_console->device = uart_console_device;
-	cdns_uart_console->setup = cdns_uart_console_setup;
-	cdns_uart_console->flags = CON_PRINTBUFFER;
-	cdns_uart_console->data = cdns_uart_uart_driver;
-	cdns_uart_uart_driver->cons = cdns_uart_console;
+		cdns_uart_uart_driver.cons = &cdns_uart_console;
 #endif
 
-	rc = uart_register_driver(cdns_uart_uart_driver);
-	if (rc < 0) {
-		dev_err(&pdev->dev, "Failed to register driver\n");
-		goto err_out_id;
+		rc = uart_register_driver(&cdns_uart_uart_driver);
+		if (rc < 0) {
+			dev_err(&pdev->dev, "Failed to register driver\n");
+			return rc;
+		}
 	}
 
-	cdns_uart_data->cdns_uart_driver = cdns_uart_uart_driver;
-
-	/*
-	 * Setting up proper name_base needs to be done after uart
-	 * registration because tty_driver structure is not filled.
-	 * name_base is 0 by default.
-	 */
-	cdns_uart_uart_driver->tty_driver->name_base = cdns_uart_data->id;
+	cdns_uart_data->cdns_uart_driver = &cdns_uart_uart_driver;
 
 	match = of_match_node(cdns_uart_of_match, pdev->dev.of_node);
 	if (match && match->data) {
@@ -1649,6 +1546,7 @@ static int cdns_uart_probe(struct platform_device *pdev)
 	port->ops	= &cdns_uart_ops;
 	port->fifosize	= CDNS_UART_FIFO_SIZE;
 	port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_XILINX_PS_UART_CONSOLE);
+	port->line	= id;
 
 	/*
 	 * Register the port.
@@ -1680,7 +1578,7 @@ static int cdns_uart_probe(struct platform_device *pdev)
 		console_port = port;
 #endif
 
-	rc = uart_add_one_port(cdns_uart_uart_driver, port);
+	rc = uart_add_one_port(&cdns_uart_uart_driver, port);
 	if (rc) {
 		dev_err(&pdev->dev,
 			"uart_add_one_port() failed; err=%i\n", rc);
@@ -1690,13 +1588,15 @@ static int cdns_uart_probe(struct platform_device *pdev)
 #ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
 	/* This is not port which is used for console that's why clean it up */
 	if (console_port == port &&
-	    !(cdns_uart_uart_driver->cons->flags & CON_ENABLED))
+	    !(cdns_uart_uart_driver.cons->flags & CON_ENABLED))
 		console_port = NULL;
 #endif
 
-	uartps_major = cdns_uart_uart_driver->tty_driver->major;
 	cdns_uart_data->cts_override = of_property_read_bool(pdev->dev.of_node,
 							     "cts-override");
+
+	instances++;
+
 	return 0;
 
 err_out_pm_disable:
@@ -1712,12 +1612,8 @@ static int cdns_uart_probe(struct platform_device *pdev)
 err_out_clk_dis_pclk:
 	clk_disable_unprepare(cdns_uart_data->pclk);
 err_out_unregister_driver:
-	uart_unregister_driver(cdns_uart_data->cdns_uart_driver);
-err_out_id:
-	mutex_lock(&bitmap_lock);
-	if (cdns_uart_data->id < MAX_UART_INSTANCES)
-		clear_bit(cdns_uart_data->id, bitmap);
-	mutex_unlock(&bitmap_lock);
+	if (!instances)
+		uart_unregister_driver(cdns_uart_data->cdns_uart_driver);
 	return rc;
 }
 
@@ -1740,10 +1636,6 @@ static int cdns_uart_remove(struct platform_device *pdev)
 #endif
 	rc = uart_remove_one_port(cdns_uart_data->cdns_uart_driver, port);
 	port->mapbase = 0;
-	mutex_lock(&bitmap_lock);
-	if (cdns_uart_data->id < MAX_UART_INSTANCES)
-		clear_bit(cdns_uart_data->id, bitmap);
-	mutex_unlock(&bitmap_lock);
 	clk_disable_unprepare(cdns_uart_data->uartclk);
 	clk_disable_unprepare(cdns_uart_data->pclk);
 	pm_runtime_disable(&pdev->dev);
@@ -1756,13 +1648,8 @@ static int cdns_uart_remove(struct platform_device *pdev)
 		console_port = NULL;
 #endif
 
-	/* If this is last instance major number should be initialized */
-	mutex_lock(&bitmap_lock);
-	if (bitmap_empty(bitmap, MAX_UART_INSTANCES))
-		uartps_major = 0;
-	mutex_unlock(&bitmap_lock);
-
-	uart_unregister_driver(cdns_uart_data->cdns_uart_driver);
+	if (!--instances)
+		uart_unregister_driver(cdns_uart_data->cdns_uart_driver);
 	return rc;
 }
 
diff --git a/drivers/usb/chipidea/Kconfig b/drivers/usb/chipidea/Kconfig
index d53db520e209..8bafcfc6080d 100644
--- a/drivers/usb/chipidea/Kconfig
+++ b/drivers/usb/chipidea/Kconfig
@@ -18,17 +18,6 @@ config USB_CHIPIDEA
 
 if USB_CHIPIDEA
 
-config USB_CHIPIDEA_OF
-	tristate
-	depends on OF
-	default USB_CHIPIDEA
-
-config USB_CHIPIDEA_PCI
-	tristate
-	depends on USB_PCI
-	depends on NOP_USB_XCEIV
-	default USB_CHIPIDEA
-
 config USB_CHIPIDEA_UDC
 	bool "ChipIdea device controller"
 	depends on USB_GADGET
@@ -43,4 +32,30 @@ config USB_CHIPIDEA_HOST
 	help
 	  Say Y here to enable host controller functionality of the
 	  ChipIdea driver.
+
+config USB_CHIPIDEA_PCI
+	tristate "Enable PCI glue driver" if EMBEDDED
+	depends on USB_PCI
+	depends on NOP_USB_XCEIV
+	default USB_CHIPIDEA
+
+config USB_CHIPIDEA_MSM
+	tristate "Enable MSM hsusb glue driver" if EMBEDDED
+	default USB_CHIPIDEA
+
+config USB_CHIPIDEA_IMX
+	tristate "Enable i.MX USB glue driver" if EMBEDDED
+	depends on OF
+	default USB_CHIPIDEA
+
+config USB_CHIPIDEA_GENERIC
+	tristate "Enable generic USB2 glue driver" if EMBEDDED
+	default USB_CHIPIDEA
+
+config USB_CHIPIDEA_TEGRA
+	tristate "Enable Tegra UDC glue driver" if EMBEDDED
+	depends on OF
+	depends on USB_CHIPIDEA_UDC
+	default USB_CHIPIDEA
+
 endif
diff --git a/drivers/usb/chipidea/Makefile b/drivers/usb/chipidea/Makefile
index 12df94f78f72..fae779a23866 100644
--- a/drivers/usb/chipidea/Makefile
+++ b/drivers/usb/chipidea/Makefile
@@ -8,11 +8,8 @@ ci_hdrc-$(CONFIG_USB_OTG_FSM)		+= otg_fsm.o
 
 # Glue/Bridge layers go here
 
-obj-$(CONFIG_USB_CHIPIDEA)	+= ci_hdrc_usb2.o
-obj-$(CONFIG_USB_CHIPIDEA)	+= ci_hdrc_msm.o
-obj-$(CONFIG_USB_CHIPIDEA)	+= ci_hdrc_zevio.o
-
-obj-$(CONFIG_USB_CHIPIDEA_PCI)	+= ci_hdrc_pci.o
-
-obj-$(CONFIG_USB_CHIPIDEA_OF)	+= usbmisc_imx.o ci_hdrc_imx.o
-obj-$(CONFIG_USB_CHIPIDEA_OF)	+= ci_hdrc_tegra.o
+obj-$(CONFIG_USB_CHIPIDEA_GENERIC)	+= ci_hdrc_usb2.o
+obj-$(CONFIG_USB_CHIPIDEA_MSM)		+= ci_hdrc_msm.o
+obj-$(CONFIG_USB_CHIPIDEA_PCI)		+= ci_hdrc_pci.o
+obj-$(CONFIG_USB_CHIPIDEA_IMX)		+= ci_hdrc_imx.o usbmisc_imx.o
+obj-$(CONFIG_USB_CHIPIDEA_TEGRA)	+= ci_hdrc_tegra.o
diff --git a/drivers/usb/chipidea/ci_hdrc_usb2.c b/drivers/usb/chipidea/ci_hdrc_usb2.c
index c044fba463e4..93c864759135 100644
--- a/drivers/usb/chipidea/ci_hdrc_usb2.c
+++ b/drivers/usb/chipidea/ci_hdrc_usb2.c
@@ -28,13 +28,19 @@ static const struct ci_hdrc_platform_data ci_default_pdata = {
 	.flags		= CI_HDRC_DISABLE_STREAMING,
 };
 
-static struct ci_hdrc_platform_data ci_zynq_pdata = {
+static const struct ci_hdrc_platform_data ci_zynq_pdata = {
 	.capoffset	= DEF_CAPOFFSET,
 };
 
+static const struct ci_hdrc_platform_data ci_zevio_pdata = {
+	.capoffset	= DEF_CAPOFFSET,
+	.flags		= CI_HDRC_REGS_SHARED | CI_HDRC_FORCE_FULLSPEED,
+};
+
 static const struct of_device_id ci_hdrc_usb2_of_match[] = {
-	{ .compatible = "chipidea,usb2"},
-	{ .compatible = "xlnx,zynq-usb-2.20a", .data = &ci_zynq_pdata},
+	{ .compatible = "chipidea,usb2" },
+	{ .compatible = "xlnx,zynq-usb-2.20a", .data = &ci_zynq_pdata },
+	{ .compatible = "lsi,zevio-usb", .data = &ci_zevio_pdata },
 	{ }
 };
 MODULE_DEVICE_TABLE(of, ci_hdrc_usb2_of_match);
@@ -64,13 +70,14 @@ static int ci_hdrc_usb2_probe(struct platform_device *pdev)
 	if (!priv)
 		return -ENOMEM;
 
-	priv->clk = devm_clk_get(dev, NULL);
-	if (!IS_ERR(priv->clk)) {
-		ret = clk_prepare_enable(priv->clk);
-		if (ret) {
-			dev_err(dev, "failed to enable the clock: %d\n", ret);
-			return ret;
-		}
+	priv->clk = devm_clk_get_optional(dev, NULL);
+	if (IS_ERR(priv->clk))
+		return PTR_ERR(priv->clk);;
+
+	ret = clk_prepare_enable(priv->clk);
+	if (ret) {
+		dev_err(dev, "failed to enable the clock: %d\n", ret);
+		return ret;
 	}
 
 	ci_pdata->name = dev_name(dev);
@@ -94,8 +101,7 @@ static int ci_hdrc_usb2_probe(struct platform_device *pdev)
 	return 0;
 
 clk_err:
-	if (!IS_ERR(priv->clk))
-		clk_disable_unprepare(priv->clk);
+	clk_disable_unprepare(priv->clk);
 	return ret;
 }
 
diff --git a/drivers/usb/chipidea/ci_hdrc_zevio.c b/drivers/usb/chipidea/ci_hdrc_zevio.c
deleted file mode 100644
index e1634da4a4b1..000000000000
--- a/drivers/usb/chipidea/ci_hdrc_zevio.c
+++ /dev/null
@@ -1,67 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- *	Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au>
- *
- * Based off drivers/usb/chipidea/ci_hdrc_msm.c
- */
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/usb/gadget.h>
-#include <linux/usb/chipidea.h>
-
-#include "ci.h"
-
-static struct ci_hdrc_platform_data ci_hdrc_zevio_platdata = {
-	.name			= "ci_hdrc_zevio",
-	.flags			= CI_HDRC_REGS_SHARED | CI_HDRC_FORCE_FULLSPEED,
-	.capoffset		= DEF_CAPOFFSET,
-};
-
-static int ci_hdrc_zevio_probe(struct platform_device *pdev)
-{
-	struct platform_device *ci_pdev;
-
-	dev_dbg(&pdev->dev, "ci_hdrc_zevio_probe\n");
-
-	ci_pdev = ci_hdrc_add_device(&pdev->dev,
-				pdev->resource, pdev->num_resources,
-				&ci_hdrc_zevio_platdata);
-
-	if (IS_ERR(ci_pdev)) {
-		dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
-		return PTR_ERR(ci_pdev);
-	}
-
-	platform_set_drvdata(pdev, ci_pdev);
-
-	return 0;
-}
-
-static int ci_hdrc_zevio_remove(struct platform_device *pdev)
-{
-	struct platform_device *ci_pdev = platform_get_drvdata(pdev);
-
-	ci_hdrc_remove_device(ci_pdev);
-
-	return 0;
-}
-
-static const struct of_device_id ci_hdrc_zevio_dt_ids[] = {
-	{ .compatible = "lsi,zevio-usb", },
-	{ /* sentinel */ }
-};
-
-static struct platform_driver ci_hdrc_zevio_driver = {
-	.probe = ci_hdrc_zevio_probe,
-	.remove = ci_hdrc_zevio_remove,
-	.driver = {
-		.name = "zevio_usb",
-		.of_match_table = ci_hdrc_zevio_dt_ids,
-	},
-};
-
-MODULE_DEVICE_TABLE(of, ci_hdrc_zevio_dt_ids);
-module_platform_driver(ci_hdrc_zevio_driver);
-
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index ae0bdc036464..ea8ac4a54a8d 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -3,42 +3,16 @@
  * core.c - ChipIdea USB IP core family device controller
  *
  * Copyright (C) 2008 Chipidea - MIPS Technologies, Inc. All rights reserved.
+ * Copyright (C) 2020 NXP
  *
  * Author: David Lopo
- */
-
-/*
- * Description: ChipIdea USB IP core family device controller
- *
- * This driver is composed of several blocks:
- * - HW:     hardware interface
- * - DBG:    debug facilities (optional)
- * - UTIL:   utilities
- * - ISR:    interrupts handling
- * - ENDPT:  endpoint operations (Gadget API)
- * - GADGET: gadget operations (Gadget API)
- * - BUS:    bus glue code, bus abstraction layer
- *
- * Compile Options
- * - STALL_IN:  non-empty bulk-in pipes cannot be halted
- *              if defined mass storage compliance succeeds but with warnings
- *              => case 4: Hi >  Dn
- *              => case 5: Hi >  Di
- *              => case 8: Hi <> Do
- *              if undefined usbtest 13 fails
- * - TRACE:     enable function tracing (depends on DEBUG)
- *
- * Main Features
- * - Chapter 9 & Mass Storage Compliance with Gadget File Storage
- * - Chapter 9 Compliance with Gadget Zero (STALL_IN undefined)
- * - Normal & LPM support
- *
- * USBTEST Report
- * - OK: 0-12, 13 (STALL_IN defined) & 14
- * - Not Supported: 15 & 16 (ISO)
+ *	   Peter Chen <peter.chen@nxp.com>
  *
- * TODO List
- * - Suspend & Remote Wakeup
+ * Main Features:
+ * - Four transfers are supported, usbtest is passed
+ * - USB Certification for gadget: CH9 and Mass Storage are passed
+ * - Low power mode
+ * - USB wakeup
  */
 #include <linux/delay.h>
 #include <linux/device.h>
@@ -272,7 +246,7 @@ static int hw_device_init(struct ci_hdrc *ci, void __iomem *base)
 	ci->rev = ci_get_revision(ci);
 
 	dev_dbg(ci->dev,
-		"ChipIdea HDRC found, revision: %d, lpm: %d; cap: %p op: %p\n",
+		"revision: %d, lpm: %d; cap: %px op: %px\n",
 		ci->rev, ci->hw_bank.lpm, ci->hw_bank.cap, ci->hw_bank.op);
 
 	/* setup lock mode ? */
diff --git a/drivers/usb/chipidea/udc.h b/drivers/usb/chipidea/udc.h
index ebb11b625bb8..32b56f84f77a 100644
--- a/drivers/usb/chipidea/udc.h
+++ b/drivers/usb/chipidea/udc.h
@@ -67,10 +67,7 @@ struct td_node {
  * struct ci_hw_req - usb request representation
  * @req: request structure for gadget drivers
  * @queue: link to QH list
- * @ptr: transfer descriptor for this request
- * @dma: dma address for the transfer descriptor
- * @zptr: transfer descriptor for the zero packet
- * @zdma: dma address of the zero packet's transfer descriptor
+ * @tds: link to TD list
  */
 struct ci_hw_req {
 	struct usb_request	req;
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 84d6f7df09a4..ded8d93834ca 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -412,9 +412,12 @@ static void acm_ctrl_irq(struct urb *urb)
 
 exit:
 	retval = usb_submit_urb(urb, GFP_ATOMIC);
-	if (retval && retval != -EPERM)
+	if (retval && retval != -EPERM && retval != -ENODEV)
 		dev_err(&acm->control->dev,
 			"%s - usb_submit_urb failed: %d\n", __func__, retval);
+	else
+		dev_vdbg(&acm->control->dev,
+			"control resubmission terminated %d\n", retval);
 }
 
 static int acm_submit_read_urb(struct acm *acm, int index, gfp_t mem_flags)
@@ -430,6 +433,8 @@ static int acm_submit_read_urb(struct acm *acm, int index, gfp_t mem_flags)
 			dev_err(&acm->data->dev,
 				"urb %d failed submission with %d\n",
 				index, res);
+		} else {
+			dev_vdbg(&acm->data->dev, "intended failure %d\n", res);
 		}
 		set_bit(index, &acm->read_urbs_free);
 		return res;
@@ -471,6 +476,7 @@ static void acm_read_bulk_callback(struct urb *urb)
 	int status = urb->status;
 	bool stopped = false;
 	bool stalled = false;
+	bool cooldown = false;
 
 	dev_vdbg(&acm->data->dev, "got urb %d, len %d, status %d\n",
 		rb->index, urb->actual_length, status);
@@ -497,6 +503,14 @@ static void acm_read_bulk_callback(struct urb *urb)
 			__func__, status);
 		stopped = true;
 		break;
+	case -EOVERFLOW:
+	case -EPROTO:
+		dev_dbg(&acm->data->dev,
+			"%s - cooling babbling device\n", __func__);
+		usb_mark_last_busy(acm->dev);
+		set_bit(rb->index, &acm->urbs_in_error_delay);
+		cooldown = true;
+		break;
 	default:
 		dev_dbg(&acm->data->dev,
 			"%s - nonzero urb status received: %d\n",
@@ -518,9 +532,11 @@ static void acm_read_bulk_callback(struct urb *urb)
 	 */
 	smp_mb__after_atomic();
 
-	if (stopped || stalled) {
+	if (stopped || stalled || cooldown) {
 		if (stalled)
 			schedule_work(&acm->work);
+		else if (cooldown)
+			schedule_delayed_work(&acm->dwork, HZ / 2);
 		return;
 	}
 
@@ -557,14 +573,20 @@ static void acm_softint(struct work_struct *work)
 	struct acm *acm = container_of(work, struct acm, work);
 
 	if (test_bit(EVENT_RX_STALL, &acm->flags)) {
-		if (!(usb_autopm_get_interface(acm->data))) {
+		smp_mb(); /* against acm_suspend() */
+		if (!acm->susp_count) {
 			for (i = 0; i < acm->rx_buflimit; i++)
 				usb_kill_urb(acm->read_urbs[i]);
 			usb_clear_halt(acm->dev, acm->in);
 			acm_submit_read_urbs(acm, GFP_KERNEL);
-			usb_autopm_put_interface(acm->data);
+			clear_bit(EVENT_RX_STALL, &acm->flags);
 		}
-		clear_bit(EVENT_RX_STALL, &acm->flags);
+	}
+
+	if (test_and_clear_bit(ACM_ERROR_DELAY, &acm->flags)) {
+		for (i = 0; i < ACM_NR; i++) 
+			if (test_and_clear_bit(i, &acm->urbs_in_error_delay))
+					acm_submit_read_urb(acm, i, GFP_NOIO);
 	}
 
 	if (test_and_clear_bit(EVENT_TTY_WAKEUP, &acm->flags))
@@ -1333,6 +1355,7 @@ static int acm_probe(struct usb_interface *intf,
 	acm->readsize = readsize;
 	acm->rx_buflimit = num_rx_buf;
 	INIT_WORK(&acm->work, acm_softint);
+	INIT_DELAYED_WORK(&acm->dwork, acm_softint);
 	init_waitqueue_head(&acm->wioctl);
 	spin_lock_init(&acm->write_lock);
 	spin_lock_init(&acm->read_lock);
@@ -1542,6 +1565,7 @@ static void acm_disconnect(struct usb_interface *intf)
 
 	acm_kill_urbs(acm);
 	cancel_work_sync(&acm->work);
+	cancel_delayed_work_sync(&acm->dwork);
 
 	tty_unregister_device(acm_tty_driver, acm->minor);
 
@@ -1584,6 +1608,8 @@ static int acm_suspend(struct usb_interface *intf, pm_message_t message)
 
 	acm_kill_urbs(acm);
 	cancel_work_sync(&acm->work);
+	cancel_delayed_work_sync(&acm->dwork);
+	acm->urbs_in_error_delay = 0;
 
 	return 0;
 }
diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h
index ca1c026382c2..cd5e9d8ab237 100644
--- a/drivers/usb/class/cdc-acm.h
+++ b/drivers/usb/class/cdc-acm.h
@@ -109,8 +109,11 @@ struct acm {
 #		define EVENT_TTY_WAKEUP	0
 #		define EVENT_RX_STALL	1
 #		define ACM_THROTTLED	2
+#		define ACM_ERROR_DELAY	3
+	unsigned long urbs_in_error_delay;		/* these need to be restarted after a delay */
 	struct usb_cdc_line_coding line;		/* bits, stop, parity */
-	struct work_struct work;			/* work queue entry for line discipline waking up */
+	struct work_struct work;			/* work queue entry for various purposes*/
+	struct delayed_work dwork;			/* for cool downs needed in error recovery */
 	unsigned int ctrlin;				/* input control lines (DCD, DSR, RI, break, overruns) */
 	unsigned int ctrlout;				/* output control lines (DTR, RTS) */
 	struct async_icount iocount;			/* counters for control line changes */
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index aa45840d8273..de624c47e190 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -31,6 +31,7 @@
 #include <linux/types.h>
 #include <linux/genalloc.h>
 #include <linux/io.h>
+#include <linux/kcov.h>
 
 #include <linux/phy/phy.h>
 #include <linux/usb.h>
@@ -1645,7 +1646,9 @@ static void __usb_hcd_giveback_urb(struct urb *urb)
 
 	/* pass ownership to the completion handler */
 	urb->status = status;
+	kcov_remote_start_usb((u64)urb->dev->bus->busnum);
 	urb->complete(urb);
+	kcov_remote_stop();
 
 	usb_anchor_resume_wakeups(anchor);
 	atomic_dec(&urb->use_count);
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index d5f834f16993..a48678a0c83a 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -589,12 +589,13 @@ void usb_sg_cancel(struct usb_sg_request *io)
 	int i, retval;
 
 	spin_lock_irqsave(&io->lock, flags);
-	if (io->status) {
+	if (io->status || io->count == 0) {
 		spin_unlock_irqrestore(&io->lock, flags);
 		return;
 	}
 	/* shut everything down */
 	io->status = -ECONNRESET;
+	io->count++;		/* Keep the request alive until we're done */
 	spin_unlock_irqrestore(&io->lock, flags);
 
 	for (i = io->entries - 1; i >= 0; --i) {
@@ -608,6 +609,12 @@ void usb_sg_cancel(struct usb_sg_request *io)
 			dev_warn(&io->dev->dev, "%s, unlink --> %d\n",
 				 __func__, retval);
 	}
+
+	spin_lock_irqsave(&io->lock, flags);
+	io->count--;
+	if (!io->count)
+		complete(&io->complete);
+	spin_unlock_irqrestore(&io->lock, flags);
 }
 EXPORT_SYMBOL_GPL(usb_sg_cancel);
 
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index da30b5664ff3..3e8efe759c3e 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -430,6 +430,10 @@ static const struct usb_device_id usb_quirk_list[] = {
 	/* Corsair K70 LUX */
 	{ USB_DEVICE(0x1b1c, 0x1b36), .driver_info = USB_QUIRK_DELAY_INIT },
 
+	/* Corsair K70 RGB RAPDIFIRE */
+	{ USB_DEVICE(0x1b1c, 0x1b38), .driver_info = USB_QUIRK_DELAY_INIT |
+	  USB_QUIRK_DELAY_CTRL_MSG },
+
 	/* MIDI keyboard WORLDE MINI */
 	{ USB_DEVICE(0x1c75, 0x0204), .driver_info =
 			USB_QUIRK_CONFIG_INTF_STRINGS },
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 6846eb0cba13..4c171a8e215f 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -307,10 +307,14 @@
 
 /* Global TX Fifo Size Register */
 #define DWC31_GTXFIFOSIZ_TXFRAMNUM	BIT(15)		/* DWC_usb31 only */
-#define DWC31_GTXFIFOSIZ_TXFDEF(n)	((n) & 0x7fff)	/* DWC_usb31 only */
-#define DWC3_GTXFIFOSIZ_TXFDEF(n)	((n) & 0xffff)
+#define DWC31_GTXFIFOSIZ_TXFDEP(n)	((n) & 0x7fff)	/* DWC_usb31 only */
+#define DWC3_GTXFIFOSIZ_TXFDEP(n)	((n) & 0xffff)
 #define DWC3_GTXFIFOSIZ_TXFSTADDR(n)	((n) & 0xffff0000)
 
+/* Global RX Fifo Size Register */
+#define DWC31_GRXFIFOSIZ_RXFDEP(n)	((n) & 0x7fff)	/* DWC_usb31 only */
+#define DWC3_GRXFIFOSIZ_RXFDEP(n)	((n) & 0xffff)
+
 /* Global Event Size Registers */
 #define DWC3_GEVNTSIZ_INTMASK		BIT(31)
 #define DWC3_GEVNTSIZ_SIZE(n)		((n) & 0xffff)
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 4d3c79d90a6e..aca2077258c8 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1728,7 +1728,6 @@ static int __dwc3_gadget_wakeup(struct dwc3 *dwc)
 	u32			reg;
 
 	u8			link_state;
-	u8			speed;
 
 	/*
 	 * According to the Databook Remote wakeup request should
@@ -1738,16 +1737,13 @@ static int __dwc3_gadget_wakeup(struct dwc3 *dwc)
 	 */
 	reg = dwc3_readl(dwc->regs, DWC3_DSTS);
 
-	speed = reg & DWC3_DSTS_CONNECTSPD;
-	if ((speed == DWC3_DSTS_SUPERSPEED) ||
-	    (speed == DWC3_DSTS_SUPERSPEED_PLUS))
-		return 0;
-
 	link_state = DWC3_DSTS_USBLNKST(reg);
 
 	switch (link_state) {
+	case DWC3_LINK_STATE_RESET:
 	case DWC3_LINK_STATE_RX_DET:	/* in HS, means Early Suspend */
 	case DWC3_LINK_STATE_U3:	/* in HS, means SUSPEND */
+	case DWC3_LINK_STATE_RESUME:
 		break;
 	default:
 		return -EINVAL;
@@ -2227,7 +2223,6 @@ static int dwc3_gadget_init_in_endpoint(struct dwc3_ep *dep)
 {
 	struct dwc3 *dwc = dep->dwc;
 	int mdwidth;
-	int kbytes;
 	int size;
 
 	mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0);
@@ -2236,24 +2231,24 @@ static int dwc3_gadget_init_in_endpoint(struct dwc3_ep *dep)
 
 	size = dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(dep->number >> 1));
 	if (dwc3_is_usb31(dwc))
-		size = DWC31_GTXFIFOSIZ_TXFDEF(size);
+		size = DWC31_GTXFIFOSIZ_TXFDEP(size);
 	else
-		size = DWC3_GTXFIFOSIZ_TXFDEF(size);
+		size = DWC3_GTXFIFOSIZ_TXFDEP(size);
 
 	/* FIFO Depth is in MDWDITH bytes. Multiply */
 	size *= mdwidth;
 
-	kbytes = size / 1024;
-	if (kbytes == 0)
-		kbytes = 1;
-
 	/*
-	 * FIFO sizes account an extra MDWIDTH * (kbytes + 1) bytes for
-	 * internal overhead. We don't really know how these are used,
-	 * but documentation say it exists.
+	 * To meet performance requirement, a minimum TxFIFO size of 3x
+	 * MaxPacketSize is recommended for endpoints that support burst and a
+	 * minimum TxFIFO size of 2x MaxPacketSize for endpoints that don't
+	 * support burst. Use those numbers and we can calculate the max packet
+	 * limit as below.
 	 */
-	size -= mdwidth * (kbytes + 1);
-	size /= kbytes;
+	if (dwc->maximum_speed >= USB_SPEED_SUPER)
+		size /= 3;
+	else
+		size /= 2;
 
 	usb_ep_set_maxpacket_limit(&dep->endpoint, size);
 
@@ -2271,8 +2266,39 @@ static int dwc3_gadget_init_in_endpoint(struct dwc3_ep *dep)
 static int dwc3_gadget_init_out_endpoint(struct dwc3_ep *dep)
 {
 	struct dwc3 *dwc = dep->dwc;
+	int mdwidth;
+	int size;
+
+	mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0);
+
+	/* MDWIDTH is represented in bits, convert to bytes */
+	mdwidth /= 8;
+
+	/* All OUT endpoints share a single RxFIFO space */
+	size = dwc3_readl(dwc->regs, DWC3_GRXFIFOSIZ(0));
+	if (dwc3_is_usb31(dwc))
+		size = DWC31_GRXFIFOSIZ_RXFDEP(size);
+	else
+		size = DWC3_GRXFIFOSIZ_RXFDEP(size);
+
+	/* FIFO depth is in MDWDITH bytes */
+	size *= mdwidth;
 
-	usb_ep_set_maxpacket_limit(&dep->endpoint, 1024);
+	/*
+	 * To meet performance requirement, a minimum recommended RxFIFO size
+	 * is defined as follow:
+	 * RxFIFO size >= (3 x MaxPacketSize) +
+	 * (3 x 8 bytes setup packets size) + (16 bytes clock crossing margin)
+	 *
+	 * Then calculate the max packet limit as below.
+	 */
+	size -= (3 * 8) + 16;
+	if (size < 0)
+		size = 0;
+	else
+		size /= 3;
+
+	usb_ep_set_maxpacket_limit(&dep->endpoint, size);
 	dep->endpoint.max_streams = 15;
 	dep->endpoint.ops = &dwc3_gadget_ep_ops;
 	list_add_tail(&dep->endpoint.ep_list,
diff --git a/drivers/usb/early/xhci-dbc.c b/drivers/usb/early/xhci-dbc.c
index 971c6b92484a..171280c80228 100644
--- a/drivers/usb/early/xhci-dbc.c
+++ b/drivers/usb/early/xhci-dbc.c
@@ -728,19 +728,19 @@ static void xdbc_handle_tx_event(struct xdbc_trb *evt_trb)
 	case COMP_USB_TRANSACTION_ERROR:
 	case COMP_STALL_ERROR:
 	default:
-		if (ep_id == XDBC_EPID_OUT)
+		if (ep_id == XDBC_EPID_OUT || ep_id == XDBC_EPID_OUT_INTEL)
 			xdbc.flags |= XDBC_FLAGS_OUT_STALL;
-		if (ep_id == XDBC_EPID_IN)
+		if (ep_id == XDBC_EPID_IN || ep_id == XDBC_EPID_IN_INTEL)
 			xdbc.flags |= XDBC_FLAGS_IN_STALL;
 
 		xdbc_trace("endpoint %d stalled\n", ep_id);
 		break;
 	}
 
-	if (ep_id == XDBC_EPID_IN) {
+	if (ep_id == XDBC_EPID_IN || ep_id == XDBC_EPID_IN_INTEL) {
 		xdbc.flags &= ~XDBC_FLAGS_IN_PROCESS;
 		xdbc_bulk_transfer(NULL, XDBC_MAX_PACKET, true);
-	} else if (ep_id == XDBC_EPID_OUT) {
+	} else if (ep_id == XDBC_EPID_OUT || ep_id == XDBC_EPID_OUT_INTEL) {
 		xdbc.flags &= ~XDBC_FLAGS_OUT_PROCESS;
 	} else {
 		xdbc_trace("invalid endpoint id %d\n", ep_id);
diff --git a/drivers/usb/early/xhci-dbc.h b/drivers/usb/early/xhci-dbc.h
index 673686eeddd7..6e2b7266a695 100644
--- a/drivers/usb/early/xhci-dbc.h
+++ b/drivers/usb/early/xhci-dbc.h
@@ -120,8 +120,22 @@ struct xdbc_ring {
 	u32			cycle_state;
 };
 
-#define XDBC_EPID_OUT		2
-#define XDBC_EPID_IN		3
+/*
+ * These are the "Endpoint ID" (also known as "Context Index") values for the
+ * OUT Transfer Ring and the IN Transfer Ring of a Debug Capability Context data
+ * structure.
+ * According to the "eXtensible Host Controller Interface for Universal Serial
+ * Bus (xHCI)" specification, section "7.6.3.2 Endpoint Contexts and Transfer
+ * Rings", these should be 0 and 1, and those are the values AMD machines give
+ * you; but Intel machines seem to use the formula from section "4.5.1 Device
+ * Context Index", which is supposed to be used for the Device Context only.
+ * Luckily the values from Intel don't overlap with those from AMD, so we can
+ * just test for both.
+ */
+#define XDBC_EPID_OUT		0
+#define XDBC_EPID_IN		1
+#define XDBC_EPID_OUT_INTEL	2
+#define XDBC_EPID_IN_INTEL	3
 
 struct xdbc_state {
 	u16			vendor;
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
index c81023b195c3..10f01f974f67 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -1813,6 +1813,10 @@ static void ffs_data_reset(struct ffs_data *ffs)
 	ffs->state = FFS_READ_DESCRIPTORS;
 	ffs->setup_state = FFS_NO_SETUP;
 	ffs->flags = 0;
+
+	ffs->ms_os_descs_ext_prop_count = 0;
+	ffs->ms_os_descs_ext_prop_name_len = 0;
+	ffs->ms_os_descs_ext_prop_data_len = 0;
 }
 
 
diff --git a/drivers/usb/gadget/legacy/raw_gadget.c b/drivers/usb/gadget/legacy/raw_gadget.c
index 76406343fbe5..ca7d95bf7397 100644
--- a/drivers/usb/gadget/legacy/raw_gadget.c
+++ b/drivers/usb/gadget/legacy/raw_gadget.c
@@ -81,6 +81,7 @@ static int raw_event_queue_add(struct raw_event_queue *queue,
 static struct usb_raw_event *raw_event_queue_fetch(
 				struct raw_event_queue *queue)
 {
+	int ret;
 	unsigned long flags;
 	struct usb_raw_event *event;
 
@@ -89,11 +90,18 @@ static struct usb_raw_event *raw_event_queue_fetch(
 	 * there's at least one event queued by decrementing the semaphore,
 	 * and then take the lock to protect queue struct fields.
 	 */
-	if (down_interruptible(&queue->sema))
-		return NULL;
+	ret = down_interruptible(&queue->sema);
+	if (ret)
+		return ERR_PTR(ret);
 	spin_lock_irqsave(&queue->lock, flags);
-	if (WARN_ON(!queue->size))
-		return NULL;
+	/*
+	 * queue->size must have the same value as queue->sema counter (before
+	 * the down_interruptible() call above), so this check is a fail-safe.
+	 */
+	if (WARN_ON(!queue->size)) {
+		spin_unlock_irqrestore(&queue->lock, flags);
+		return ERR_PTR(-ENODEV);
+	}
 	event = queue->events[0];
 	queue->size--;
 	memmove(&queue->events[0], &queue->events[1],
@@ -392,9 +400,8 @@ static int raw_ioctl_init(struct raw_dev *dev, unsigned long value)
 	char *udc_device_name;
 	unsigned long flags;
 
-	ret = copy_from_user(&arg, (void __user *)value, sizeof(arg));
-	if (ret)
-		return ret;
+	if (copy_from_user(&arg, (void __user *)value, sizeof(arg)))
+		return -EFAULT;
 
 	switch (arg.speed) {
 	case USB_SPEED_UNKNOWN:
@@ -501,15 +508,13 @@ static int raw_ioctl_run(struct raw_dev *dev, unsigned long value)
 
 static int raw_ioctl_event_fetch(struct raw_dev *dev, unsigned long value)
 {
-	int ret = 0;
 	struct usb_raw_event arg;
 	unsigned long flags;
 	struct usb_raw_event *event;
 	uint32_t length;
 
-	ret = copy_from_user(&arg, (void __user *)value, sizeof(arg));
-	if (ret)
-		return ret;
+	if (copy_from_user(&arg, (void __user *)value, sizeof(arg)))
+		return -EFAULT;
 
 	spin_lock_irqsave(&dev->lock, flags);
 	if (dev->state != STATE_DEV_RUNNING) {
@@ -525,25 +530,31 @@ static int raw_ioctl_event_fetch(struct raw_dev *dev, unsigned long value)
 	spin_unlock_irqrestore(&dev->lock, flags);
 
 	event = raw_event_queue_fetch(&dev->queue);
-	if (!event) {
+	if (PTR_ERR(event) == -EINTR) {
 		dev_dbg(&dev->gadget->dev, "event fetching interrupted\n");
 		return -EINTR;
 	}
+	if (IS_ERR(event)) {
+		dev_err(&dev->gadget->dev, "failed to fetch event\n");
+		spin_lock_irqsave(&dev->lock, flags);
+		dev->state = STATE_DEV_FAILED;
+		spin_unlock_irqrestore(&dev->lock, flags);
+		return -ENODEV;
+	}
 	length = min(arg.length, event->length);
-	ret = copy_to_user((void __user *)value, event,
-				sizeof(*event) + length);
-	return ret;
+	if (copy_to_user((void __user *)value, event, sizeof(*event) + length))
+		return -EFAULT;
+
+	return 0;
 }
 
 static void *raw_alloc_io_data(struct usb_raw_ep_io *io, void __user *ptr,
 				bool get_from_user)
 {
-	int ret;
 	void *data;
 
-	ret = copy_from_user(io, ptr, sizeof(*io));
-	if (ret)
-		return ERR_PTR(ret);
+	if (copy_from_user(io, ptr, sizeof(*io)))
+		return ERR_PTR(-EFAULT);
 	if (io->ep >= USB_RAW_MAX_ENDPOINTS)
 		return ERR_PTR(-EINVAL);
 	if (!usb_raw_io_flags_valid(io->flags))
@@ -658,12 +669,13 @@ static int raw_ioctl_ep0_read(struct raw_dev *dev, unsigned long value)
 	if (IS_ERR(data))
 		return PTR_ERR(data);
 	ret = raw_process_ep0_io(dev, &io, data, false);
-	if (ret < 0) {
-		kfree(data);
-		return ret;
-	}
+	if (ret)
+		goto free;
+
 	length = min(io.length, (unsigned int)ret);
-	ret = copy_to_user((void __user *)(value + sizeof(io)), data, length);
+	if (copy_to_user((void __user *)(value + sizeof(io)), data, length))
+		ret = -EFAULT;
+free:
 	kfree(data);
 	return ret;
 }
@@ -952,12 +964,13 @@ static int raw_ioctl_ep_read(struct raw_dev *dev, unsigned long value)
 	if (IS_ERR(data))
 		return PTR_ERR(data);
 	ret = raw_process_ep_io(dev, &io, data, false);
-	if (ret < 0) {
-		kfree(data);
-		return ret;
-	}
+	if (ret)
+		goto free;
+
 	length = min(io.length, (unsigned int)ret);
-	ret = copy_to_user((void __user *)(value + sizeof(io)), data, length);
+	if (copy_to_user((void __user *)(value + sizeof(io)), data, length))
+		ret = -EFAULT;
+free:
 	kfree(data);
 	return ret;
 }
diff --git a/drivers/usb/gadget/udc/bdc/bdc_ep.c b/drivers/usb/gadget/udc/bdc/bdc_ep.c
index a4d9b5e1e50e..d49c6dc1082d 100644
--- a/drivers/usb/gadget/udc/bdc/bdc_ep.c
+++ b/drivers/usb/gadget/udc/bdc/bdc_ep.c
@@ -540,7 +540,7 @@ static void bdc_req_complete(struct bdc_ep *ep, struct bdc_req *req,
 {
 	struct bdc *bdc = ep->bdc;
 
-	if (req == NULL  || &req->queue == NULL || &req->usb_req == NULL)
+	if (req == NULL)
 		return;
 
 	dev_dbg(bdc->dev, "%s ep:%s status:%d\n", __func__, ep->name, status);
diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c
index 3670fda02c34..d592071119ba 100644
--- a/drivers/usb/storage/uas.c
+++ b/drivers/usb/storage/uas.c
@@ -81,6 +81,19 @@ static void uas_free_streams(struct uas_dev_info *devinfo);
 static void uas_log_cmd_state(struct scsi_cmnd *cmnd, const char *prefix,
 				int status);
 
+/*
+ * This driver needs its own workqueue, as we need to control memory allocation.
+ *
+ * In the course of error handling and power management uas_wait_for_pending_cmnds()
+ * needs to flush pending work items. In these contexts we cannot allocate memory
+ * by doing block IO as we would deadlock. For the same reason we cannot wait
+ * for anything allocating memory not heeding these constraints.
+ *
+ * So we have to control all work items that can be on the workqueue we flush.
+ * Hence we cannot share a queue and need our own.
+ */
+static struct workqueue_struct *workqueue;
+
 static void uas_do_work(struct work_struct *work)
 {
 	struct uas_dev_info *devinfo =
@@ -109,7 +122,7 @@ static void uas_do_work(struct work_struct *work)
 		if (!err)
 			cmdinfo->state &= ~IS_IN_WORK_LIST;
 		else
-			schedule_work(&devinfo->work);
+			queue_work(workqueue, &devinfo->work);
 	}
 out:
 	spin_unlock_irqrestore(&devinfo->lock, flags);
@@ -134,7 +147,7 @@ static void uas_add_work(struct uas_cmd_info *cmdinfo)
 
 	lockdep_assert_held(&devinfo->lock);
 	cmdinfo->state |= IS_IN_WORK_LIST;
-	schedule_work(&devinfo->work);
+	queue_work(workqueue, &devinfo->work);
 }
 
 static void uas_zap_pending(struct uas_dev_info *devinfo, int result)
@@ -190,6 +203,9 @@ static void uas_log_cmd_state(struct scsi_cmnd *cmnd, const char *prefix,
 	struct uas_cmd_info *ci = (void *)&cmnd->SCp;
 	struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
 
+	if (status == -ENODEV) /* too late */
+		return;
+
 	scmd_printk(KERN_INFO, cmnd,
 		    "%s %d uas-tag %d inflight:%s%s%s%s%s%s%s%s%s%s%s%s ",
 		    prefix, status, cmdinfo->uas_tag,
@@ -1226,7 +1242,31 @@ static struct usb_driver uas_driver = {
 	.id_table = uas_usb_ids,
 };
 
-module_usb_driver(uas_driver);
+static int __init uas_init(void)
+{
+	int rv;
+
+	workqueue = alloc_workqueue("uas", WQ_MEM_RECLAIM, 0);
+	if (!workqueue)
+		return -ENOMEM;
+
+	rv = usb_register(&uas_driver);
+	if (rv) {
+		destroy_workqueue(workqueue);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static void __exit uas_exit(void)
+{
+	usb_deregister(&uas_driver);
+	destroy_workqueue(workqueue);
+}
+
+module_init(uas_init);
+module_exit(uas_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_IMPORT_NS(USB_STORAGE);
diff --git a/drivers/usb/typec/mux/pi3usb30532.c b/drivers/usb/typec/mux/pi3usb30532.c
index 46457c133d2b..7afe275b17d0 100644
--- a/drivers/usb/typec/mux/pi3usb30532.c
+++ b/drivers/usb/typec/mux/pi3usb30532.c
@@ -114,8 +114,8 @@ pi3usb30532_mux_set(struct typec_mux *mux, struct typec_mux_state *state)
 static int pi3usb30532_probe(struct i2c_client *client)
 {
 	struct device *dev = &client->dev;
-	struct typec_switch_desc sw_desc;
-	struct typec_mux_desc mux_desc;
+	struct typec_switch_desc sw_desc = { };
+	struct typec_mux_desc mux_desc = { };
 	struct pi3usb30532 *pi;
 	int ret;
 
diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c
index de3576e6530a..82b19ebd7838 100644
--- a/drivers/usb/typec/tcpm/tcpm.c
+++ b/drivers/usb/typec/tcpm/tcpm.c
@@ -3794,6 +3794,14 @@ static void _tcpm_cc_change(struct tcpm_port *port, enum typec_cc_status cc1,
 		 */
 		break;
 
+	case PORT_RESET:
+	case PORT_RESET_WAIT_OFF:
+		/*
+		 * State set back to default mode once the timer completes.
+		 * Ignore CC changes here.
+		 */
+		break;
+
 	default:
 		if (tcpm_port_is_disconnected(port))
 			tcpm_set_state(port, unattached_state(port), 0);
@@ -3855,6 +3863,15 @@ static void _tcpm_pd_vbus_on(struct tcpm_port *port)
 	case SRC_TRY_DEBOUNCE:
 		/* Do nothing, waiting for sink detection */
 		break;
+
+	case PORT_RESET:
+	case PORT_RESET_WAIT_OFF:
+		/*
+		 * State set back to default mode once the timer completes.
+		 * Ignore vbus changes here.
+		 */
+		break;
+
 	default:
 		break;
 	}
@@ -3908,10 +3925,19 @@ static void _tcpm_pd_vbus_off(struct tcpm_port *port)
 	case PORT_RESET_WAIT_OFF:
 		tcpm_set_state(port, tcpm_default_state(port), 0);
 		break;
+
 	case SRC_TRY_WAIT:
 	case SRC_TRY_DEBOUNCE:
 		/* Do nothing, waiting for sink detection */
 		break;
+
+	case PORT_RESET:
+		/*
+		 * State set back to default mode once the timer completes.
+		 * Ignore vbus changes here.
+		 */
+		break;
+
 	default:
 		if (port->pwr_role == TYPEC_SINK &&
 		    port->attached)
diff --git a/drivers/vdpa/Kconfig b/drivers/vdpa/Kconfig
index 7db1460104b7..e8140065c8a5 100644
--- a/drivers/vdpa/Kconfig
+++ b/drivers/vdpa/Kconfig
@@ -1,21 +1,16 @@
 # SPDX-License-Identifier: GPL-2.0-only
-config VDPA
-	tristate
+menuconfig VDPA
+	tristate "vDPA drivers"
 	help
 	  Enable this module to support vDPA device that uses a
 	  datapath which complies with virtio specifications with
 	  vendor specific control path.
 
-menuconfig VDPA_MENU
-	bool "VDPA drivers"
-	default n
-
-if VDPA_MENU
+if VDPA
 
 config VDPA_SIM
 	tristate "vDPA device simulator"
-	depends on RUNTIME_TESTING_MENU
-	select VDPA
+	depends on RUNTIME_TESTING_MENU && HAS_DMA && VHOST_DPN
 	select VHOST_RING
 	default n
 	help
@@ -24,9 +19,8 @@ config VDPA_SIM
 	  development of vDPA.
 
 config IFCVF
-	tristate "Intel IFC VF VDPA driver"
+	tristate "Intel IFC VF vDPA driver"
 	depends on PCI_MSI
-	select VDPA
 	default n
 	help
 	  This kernel module can drive Intel IFC VF NIC to offload
@@ -34,4 +28,4 @@ config IFCVF
 	  To compile this driver as a module, choose M here: the module will
 	  be called ifcvf.
 
-endif # VDPA_MENU
+endif # VDPA
diff --git a/drivers/vdpa/ifcvf/ifcvf_base.c b/drivers/vdpa/ifcvf/ifcvf_base.c
index b61b06ea26d3..e24371d644b5 100644
--- a/drivers/vdpa/ifcvf/ifcvf_base.c
+++ b/drivers/vdpa/ifcvf/ifcvf_base.c
@@ -301,12 +301,10 @@ int ifcvf_set_vq_state(struct ifcvf_hw *hw, u16 qid, u64 num)
 
 static int ifcvf_hw_enable(struct ifcvf_hw *hw)
 {
-	struct ifcvf_lm_cfg __iomem *ifcvf_lm;
 	struct virtio_pci_common_cfg __iomem *cfg;
 	struct ifcvf_adapter *ifcvf;
 	u32 i;
 
-	ifcvf_lm = (struct ifcvf_lm_cfg __iomem *)hw->lm_cfg;
 	ifcvf = vf_to_adapter(hw);
 	cfg = hw->common_cfg;
 	ifc_iowrite16(IFCVF_MSI_CONFIG_OFF, &cfg->msix_config);
diff --git a/drivers/vdpa/ifcvf/ifcvf_main.c b/drivers/vdpa/ifcvf/ifcvf_main.c
index 8d54dc5b08d2..abf6a061cab6 100644
--- a/drivers/vdpa/ifcvf/ifcvf_main.c
+++ b/drivers/vdpa/ifcvf/ifcvf_main.c
@@ -31,11 +31,9 @@ static irqreturn_t ifcvf_intr_handler(int irq, void *arg)
 static int ifcvf_start_datapath(void *private)
 {
 	struct ifcvf_hw *vf = ifcvf_private_to_vf(private);
-	struct ifcvf_adapter *ifcvf;
 	u8 status;
 	int ret;
 
-	ifcvf = vf_to_adapter(vf);
 	vf->nr_vring = IFCVF_MAX_QUEUE_PAIRS * 2;
 	ret = ifcvf_start_hw(vf);
 	if (ret < 0) {
@@ -228,7 +226,7 @@ static u32 ifcvf_vdpa_get_vendor_id(struct vdpa_device *vdpa_dev)
 	return IFCVF_SUBSYS_VENDOR_ID;
 }
 
-static u16 ifcvf_vdpa_get_vq_align(struct vdpa_device *vdpa_dev)
+static u32 ifcvf_vdpa_get_vq_align(struct vdpa_device *vdpa_dev)
 {
 	return IFCVF_QUEUE_ALIGNMENT;
 }
diff --git a/drivers/vdpa/vdpa.c b/drivers/vdpa/vdpa.c
index e9ed6a2b635b..ff6562f602e0 100644
--- a/drivers/vdpa/vdpa.c
+++ b/drivers/vdpa/vdpa.c
@@ -116,7 +116,7 @@ EXPORT_SYMBOL_GPL(__vdpa_alloc_device);
 
 /**
  * vdpa_register_device - register a vDPA device
- * Callers must have a succeed call of vdpa_init_device() before.
+ * Callers must have a succeed call of vdpa_alloc_device() before.
  * @vdev: the vdpa device to be registered to vDPA bus
  *
  * Returns an error when fail to add to vDPA bus
diff --git a/drivers/vdpa/vdpa_sim/vdpa_sim.c b/drivers/vdpa/vdpa_sim/vdpa_sim.c
index 6e8a0cf2fdeb..7957d2d41fc4 100644
--- a/drivers/vdpa/vdpa_sim/vdpa_sim.c
+++ b/drivers/vdpa/vdpa_sim/vdpa_sim.c
@@ -435,7 +435,7 @@ static u64 vdpasim_get_vq_state(struct vdpa_device *vdpa, u16 idx)
 	return vrh->last_avail_idx;
 }
 
-static u16 vdpasim_get_vq_align(struct vdpa_device *vdpa)
+static u32 vdpasim_get_vq_align(struct vdpa_device *vdpa)
 {
 	return VDPASIM_QUEUE_ALIGN;
 }
@@ -488,7 +488,7 @@ static u8 vdpasim_get_status(struct vdpa_device *vdpa)
 	status = vdpasim->status;
 	spin_unlock(&vdpasim->lock);
 
-	return vdpasim->status;
+	return status;
 }
 
 static void vdpasim_set_status(struct vdpa_device *vdpa, u8 status)
diff --git a/drivers/vhost/Kconfig b/drivers/vhost/Kconfig
index 362b832f5338..c4f273793595 100644
--- a/drivers/vhost/Kconfig
+++ b/drivers/vhost/Kconfig
@@ -3,6 +3,8 @@ config VHOST_IOTLB
 	tristate
 	help
 	  Generic IOTLB implementation for vhost and vringh.
+	  This option is selected by any driver which needs to support
+	  an IOMMU in software.
 
 config VHOST_RING
 	tristate
@@ -11,6 +13,15 @@ config VHOST_RING
 	  This option is selected by any driver which needs to access
 	  the host side of a virtio ring.
 
+config VHOST_DPN
+	bool
+	depends on !ARM || AEABI
+	default y
+	help
+	  Anything selecting VHOST or VHOST_RING must depend on VHOST_DPN.
+	  This excludes the deprecated ARM ABI since that forces a 4 byte
+	  alignment on all structs - incompatible with virtio spec requirements.
+
 config VHOST
 	tristate
 	select VHOST_IOTLB
@@ -26,7 +37,7 @@ if VHOST_MENU
 
 config VHOST_NET
 	tristate "Host kernel accelerator for virtio net"
-	depends on NET && EVENTFD && (TUN || !TUN) && (TAP || !TAP)
+	depends on NET && EVENTFD && (TUN || !TUN) && (TAP || !TAP) && VHOST_DPN
 	select VHOST
 	---help---
 	  This kernel module can be loaded in host kernel to accelerate
@@ -38,7 +49,7 @@ config VHOST_NET
 
 config VHOST_SCSI
 	tristate "VHOST_SCSI TCM fabric driver"
-	depends on TARGET_CORE && EVENTFD
+	depends on TARGET_CORE && EVENTFD && VHOST_DPN
 	select VHOST
 	default n
 	---help---
@@ -47,7 +58,7 @@ config VHOST_SCSI
 
 config VHOST_VSOCK
 	tristate "vhost virtio-vsock driver"
-	depends on VSOCKETS && EVENTFD
+	depends on VSOCKETS && EVENTFD && VHOST_DPN
 	select VHOST
 	select VIRTIO_VSOCKETS_COMMON
 	default n
@@ -61,9 +72,9 @@ config VHOST_VSOCK
 
 config VHOST_VDPA
 	tristate "Vhost driver for vDPA-based backend"
-	depends on EVENTFD
+	depends on EVENTFD && VHOST_DPN
 	select VHOST
-	select VDPA
+	depends on VDPA
 	help
 	  This kernel module can be loaded in host kernel to accelerate
 	  guest virtio devices with the vDPA-based backends.
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 87469d67ede8..2927f02cc7e1 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -424,7 +424,7 @@ static void vhost_net_disable_vq(struct vhost_net *n,
 	struct vhost_net_virtqueue *nvq =
 		container_of(vq, struct vhost_net_virtqueue, vq);
 	struct vhost_poll *poll = n->poll + (nvq - n->vqs);
-	if (!vq->private_data)
+	if (!vhost_vq_get_backend(vq))
 		return;
 	vhost_poll_stop(poll);
 }
@@ -437,7 +437,7 @@ static int vhost_net_enable_vq(struct vhost_net *n,
 	struct vhost_poll *poll = n->poll + (nvq - n->vqs);
 	struct socket *sock;
 
-	sock = vq->private_data;
+	sock = vhost_vq_get_backend(vq);
 	if (!sock)
 		return 0;
 
@@ -524,7 +524,7 @@ static void vhost_net_busy_poll(struct vhost_net *net,
 		return;
 
 	vhost_disable_notify(&net->dev, vq);
-	sock = rvq->private_data;
+	sock = vhost_vq_get_backend(rvq);
 
 	busyloop_timeout = poll_rx ? rvq->busyloop_timeout:
 				     tvq->busyloop_timeout;
@@ -570,8 +570,10 @@ static int vhost_net_tx_get_vq_desc(struct vhost_net *net,
 
 	if (r == tvq->num && tvq->busyloop_timeout) {
 		/* Flush batched packets first */
-		if (!vhost_sock_zcopy(tvq->private_data))
-			vhost_tx_batch(net, tnvq, tvq->private_data, msghdr);
+		if (!vhost_sock_zcopy(vhost_vq_get_backend(tvq)))
+			vhost_tx_batch(net, tnvq,
+				       vhost_vq_get_backend(tvq),
+				       msghdr);
 
 		vhost_net_busy_poll(net, rvq, tvq, busyloop_intr, false);
 
@@ -685,7 +687,7 @@ static int vhost_net_build_xdp(struct vhost_net_virtqueue *nvq,
 	struct vhost_virtqueue *vq = &nvq->vq;
 	struct vhost_net *net = container_of(vq->dev, struct vhost_net,
 					     dev);
-	struct socket *sock = vq->private_data;
+	struct socket *sock = vhost_vq_get_backend(vq);
 	struct page_frag *alloc_frag = &net->page_frag;
 	struct virtio_net_hdr *gso;
 	struct xdp_buff *xdp = &nvq->xdp[nvq->batched_xdp];
@@ -952,7 +954,7 @@ static void handle_tx(struct vhost_net *net)
 	struct socket *sock;
 
 	mutex_lock_nested(&vq->mutex, VHOST_NET_VQ_TX);
-	sock = vq->private_data;
+	sock = vhost_vq_get_backend(vq);
 	if (!sock)
 		goto out;
 
@@ -1121,7 +1123,7 @@ static void handle_rx(struct vhost_net *net)
 	int recv_pkts = 0;
 
 	mutex_lock_nested(&vq->mutex, VHOST_NET_VQ_RX);
-	sock = vq->private_data;
+	sock = vhost_vq_get_backend(vq);
 	if (!sock)
 		goto out;
 
@@ -1345,9 +1347,9 @@ static struct socket *vhost_net_stop_vq(struct vhost_net *n,
 		container_of(vq, struct vhost_net_virtqueue, vq);
 
 	mutex_lock(&vq->mutex);
-	sock = vq->private_data;
+	sock = vhost_vq_get_backend(vq);
 	vhost_net_disable_vq(n, vq);
-	vq->private_data = NULL;
+	vhost_vq_set_backend(vq, NULL);
 	vhost_net_buf_unproduce(nvq);
 	nvq->rx_ring = NULL;
 	mutex_unlock(&vq->mutex);
@@ -1521,7 +1523,7 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
 	}
 
 	/* start polling new socket */
-	oldsock = vq->private_data;
+	oldsock = vhost_vq_get_backend(vq);
 	if (sock != oldsock) {
 		ubufs = vhost_net_ubuf_alloc(vq,
 					     sock && vhost_sock_zcopy(sock));
@@ -1531,7 +1533,7 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
 		}
 
 		vhost_net_disable_vq(n, vq);
-		vq->private_data = sock;
+		vhost_vq_set_backend(vq, sock);
 		vhost_net_buf_unproduce(nvq);
 		r = vhost_vq_init_access(vq);
 		if (r)
@@ -1568,7 +1570,7 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
 	return 0;
 
 err_used:
-	vq->private_data = oldsock;
+	vhost_vq_set_backend(vq, oldsock);
 	vhost_net_enable_vq(n, vq);
 	if (ubufs)
 		vhost_net_ubuf_put_wait_and_free(ubufs);
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index 7653667a8cdc..c39952243fd3 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -452,7 +452,7 @@ vhost_scsi_do_evt_work(struct vhost_scsi *vs, struct vhost_scsi_evt *evt)
 	unsigned out, in;
 	int head, ret;
 
-	if (!vq->private_data) {
+	if (!vhost_vq_get_backend(vq)) {
 		vs->vs_events_missed = true;
 		return;
 	}
@@ -892,7 +892,7 @@ vhost_scsi_get_req(struct vhost_virtqueue *vq, struct vhost_scsi_ctx *vc,
 	} else {
 		struct vhost_scsi_tpg **vs_tpg, *tpg;
 
-		vs_tpg = vq->private_data;	/* validated at handler entry */
+		vs_tpg = vhost_vq_get_backend(vq);	/* validated at handler entry */
 
 		tpg = READ_ONCE(vs_tpg[*vc->target]);
 		if (unlikely(!tpg)) {
@@ -929,7 +929,7 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq)
 	 * We can handle the vq only after the endpoint is setup by calling the
 	 * VHOST_SCSI_SET_ENDPOINT ioctl.
 	 */
-	vs_tpg = vq->private_data;
+	vs_tpg = vhost_vq_get_backend(vq);
 	if (!vs_tpg)
 		goto out;
 
@@ -1184,7 +1184,7 @@ vhost_scsi_ctl_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq)
 	 * We can handle the vq only after the endpoint is setup by calling the
 	 * VHOST_SCSI_SET_ENDPOINT ioctl.
 	 */
-	if (!vq->private_data)
+	if (!vhost_vq_get_backend(vq))
 		goto out;
 
 	memset(&vc, 0, sizeof(vc));
@@ -1322,7 +1322,7 @@ static void vhost_scsi_evt_handle_kick(struct vhost_work *work)
 	struct vhost_scsi *vs = container_of(vq->dev, struct vhost_scsi, dev);
 
 	mutex_lock(&vq->mutex);
-	if (!vq->private_data)
+	if (!vhost_vq_get_backend(vq))
 		goto out;
 
 	if (vs->vs_events_missed)
@@ -1460,7 +1460,7 @@ vhost_scsi_set_endpoint(struct vhost_scsi *vs,
 		for (i = 0; i < VHOST_SCSI_MAX_VQ; i++) {
 			vq = &vs->vqs[i].vq;
 			mutex_lock(&vq->mutex);
-			vq->private_data = vs_tpg;
+			vhost_vq_set_backend(vq, vs_tpg);
 			vhost_vq_init_access(vq);
 			mutex_unlock(&vq->mutex);
 		}
@@ -1547,7 +1547,7 @@ vhost_scsi_clear_endpoint(struct vhost_scsi *vs,
 		for (i = 0; i < VHOST_SCSI_MAX_VQ; i++) {
 			vq = &vs->vqs[i].vq;
 			mutex_lock(&vq->mutex);
-			vq->private_data = NULL;
+			vhost_vq_set_backend(vq, NULL);
 			mutex_unlock(&vq->mutex);
 		}
 	}
diff --git a/drivers/vhost/test.c b/drivers/vhost/test.c
index e37c92d4d7ad..9a3a09005e03 100644
--- a/drivers/vhost/test.c
+++ b/drivers/vhost/test.c
@@ -49,7 +49,7 @@ static void handle_vq(struct vhost_test *n)
 	void *private;
 
 	mutex_lock(&vq->mutex);
-	private = vq->private_data;
+	private = vhost_vq_get_backend(vq);
 	if (!private) {
 		mutex_unlock(&vq->mutex);
 		return;
@@ -120,7 +120,7 @@ static int vhost_test_open(struct inode *inode, struct file *f)
 	vqs[VHOST_TEST_VQ] = &n->vqs[VHOST_TEST_VQ];
 	n->vqs[VHOST_TEST_VQ].handle_kick = handle_vq_kick;
 	vhost_dev_init(dev, vqs, VHOST_TEST_VQ_MAX, UIO_MAXIOV,
-		       VHOST_TEST_PKT_WEIGHT, VHOST_TEST_WEIGHT);
+		       VHOST_TEST_PKT_WEIGHT, VHOST_TEST_WEIGHT, NULL);
 
 	f->private_data = n;
 
@@ -133,8 +133,8 @@ static void *vhost_test_stop_vq(struct vhost_test *n,
 	void *private;
 
 	mutex_lock(&vq->mutex);
-	private = vq->private_data;
-	vq->private_data = NULL;
+	private = vhost_vq_get_backend(vq);
+	vhost_vq_set_backend(vq, NULL);
 	mutex_unlock(&vq->mutex);
 	return private;
 }
@@ -198,8 +198,8 @@ static long vhost_test_run(struct vhost_test *n, int test)
 		priv = test ? n : NULL;
 
 		/* start polling new socket */
-		oldpriv = vq->private_data;
-		vq->private_data = priv;
+		oldpriv = vhost_vq_get_backend(vq);
+		vhost_vq_set_backend(vq, priv);
 
 		r = vhost_vq_init_access(&n->vqs[index]);
 
@@ -225,7 +225,7 @@ static long vhost_test_reset_owner(struct vhost_test *n)
 {
 	void *priv = NULL;
 	long err;
-	struct vhost_umem *umem;
+	struct vhost_iotlb *umem;
 
 	mutex_lock(&n->dev.mutex);
 	err = vhost_dev_check_owner(&n->dev);
diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
index 421f02a8530a..0968361e3b77 100644
--- a/drivers/vhost/vdpa.c
+++ b/drivers/vhost/vdpa.c
@@ -296,7 +296,6 @@ static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, unsigned int cmd,
 	struct vdpa_callback cb;
 	struct vhost_virtqueue *vq;
 	struct vhost_vring_state s;
-	u8 status;
 	u32 idx;
 	long r;
 
@@ -310,8 +309,6 @@ static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, unsigned int cmd,
 	idx = array_index_nospec(idx, v->nvqs);
 	vq = &v->vqs[idx];
 
-	status = ops->get_status(vdpa);
-
 	if (cmd == VHOST_VDPA_SET_VRING_ENABLE) {
 		if (copy_from_user(&s, argp, sizeof(s)))
 			return -EFAULT;
@@ -678,8 +675,6 @@ static int vhost_vdpa_open(struct inode *inode, struct file *filep)
 	int nvqs, i, r, opened;
 
 	v = container_of(inode->i_cdev, struct vhost_vdpa, cdev);
-	if (!v)
-		return -ENODEV;
 
 	opened = atomic_cmpxchg(&v->opened, 0, 1);
 	if (opened)
diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
index 181382185bbc..f8403bd46b85 100644
--- a/drivers/vhost/vhost.h
+++ b/drivers/vhost/vhost.h
@@ -231,6 +231,33 @@ enum {
 			 (1ULL << VIRTIO_F_VERSION_1)
 };
 
+/**
+ * vhost_vq_set_backend - Set backend.
+ *
+ * @vq            Virtqueue.
+ * @private_data  The private data.
+ *
+ * Context: Need to call with vq->mutex acquired.
+ */
+static inline void vhost_vq_set_backend(struct vhost_virtqueue *vq,
+					void *private_data)
+{
+	vq->private_data = private_data;
+}
+
+/**
+ * vhost_vq_get_backend - Get backend.
+ *
+ * @vq            Virtqueue.
+ *
+ * Context: Need to call with vq->mutex acquired.
+ * Return: Private data previously set with vhost_vq_set_backend.
+ */
+static inline void *vhost_vq_get_backend(struct vhost_virtqueue *vq)
+{
+	return vq->private_data;
+}
+
 static inline bool vhost_has_feature(struct vhost_virtqueue *vq, int bit)
 {
 	return vq->acked_features & (1ULL << bit);
diff --git a/drivers/vhost/vringh.c b/drivers/vhost/vringh.c
index ee0491f579ac..ba8e0d6cfd97 100644
--- a/drivers/vhost/vringh.c
+++ b/drivers/vhost/vringh.c
@@ -13,9 +13,11 @@
 #include <linux/uaccess.h>
 #include <linux/slab.h>
 #include <linux/export.h>
+#if IS_REACHABLE(CONFIG_VHOST_IOTLB)
 #include <linux/bvec.h>
 #include <linux/highmem.h>
 #include <linux/vhost_iotlb.h>
+#endif
 #include <uapi/linux/virtio_config.h>
 
 static __printf(1,2) __cold void vringh_bad(const char *fmt, ...)
@@ -1059,6 +1061,8 @@ int vringh_need_notify_kern(struct vringh *vrh)
 }
 EXPORT_SYMBOL(vringh_need_notify_kern);
 
+#if IS_REACHABLE(CONFIG_VHOST_IOTLB)
+
 static int iotlb_translate(const struct vringh *vrh,
 			   u64 addr, u64 len, struct bio_vec iov[],
 			   int iov_size, u32 perm)
@@ -1416,5 +1420,6 @@ int vringh_need_notify_iotlb(struct vringh *vrh)
 }
 EXPORT_SYMBOL(vringh_need_notify_iotlb);
 
+#endif
 
 MODULE_LICENSE("GPL");
diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index 97669484a3f6..e36aaf9ba7bd 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -91,7 +91,7 @@ vhost_transport_do_send_pkt(struct vhost_vsock *vsock,
 
 	mutex_lock(&vq->mutex);
 
-	if (!vq->private_data)
+	if (!vhost_vq_get_backend(vq))
 		goto out;
 
 	/* Avoid further vmexits, we're already processing the virtqueue */
@@ -440,7 +440,7 @@ static void vhost_vsock_handle_tx_kick(struct vhost_work *work)
 
 	mutex_lock(&vq->mutex);
 
-	if (!vq->private_data)
+	if (!vhost_vq_get_backend(vq))
 		goto out;
 
 	vhost_disable_notify(&vsock->dev, vq);
@@ -533,8 +533,8 @@ static int vhost_vsock_start(struct vhost_vsock *vsock)
 			goto err_vq;
 		}
 
-		if (!vq->private_data) {
-			vq->private_data = vsock;
+		if (!vhost_vq_get_backend(vq)) {
+			vhost_vq_set_backend(vq, vsock);
 			ret = vhost_vq_init_access(vq);
 			if (ret)
 				goto err_vq;
@@ -547,14 +547,14 @@ static int vhost_vsock_start(struct vhost_vsock *vsock)
 	return 0;
 
 err_vq:
-	vq->private_data = NULL;
+	vhost_vq_set_backend(vq, NULL);
 	mutex_unlock(&vq->mutex);
 
 	for (i = 0; i < ARRAY_SIZE(vsock->vqs); i++) {
 		vq = &vsock->vqs[i];
 
 		mutex_lock(&vq->mutex);
-		vq->private_data = NULL;
+		vhost_vq_set_backend(vq, NULL);
 		mutex_unlock(&vq->mutex);
 	}
 err:
@@ -577,7 +577,7 @@ static int vhost_vsock_stop(struct vhost_vsock *vsock)
 		struct vhost_virtqueue *vq = &vsock->vqs[i];
 
 		mutex_lock(&vq->mutex);
-		vq->private_data = NULL;
+		vhost_vq_set_backend(vq, NULL);
 		mutex_unlock(&vq->mutex);
 	}
 
diff --git a/drivers/video/fbdev/atmel_lcdfb.c b/drivers/video/fbdev/atmel_lcdfb.c
index d567f5d56c13..1e252192569a 100644
--- a/drivers/video/fbdev/atmel_lcdfb.c
+++ b/drivers/video/fbdev/atmel_lcdfb.c
@@ -1114,7 +1114,6 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
 
 	sinfo->irq_base = platform_get_irq(pdev, 0);
 	if (sinfo->irq_base < 0) {
-		dev_err(dev, "unable to get irq\n");
 		ret = sinfo->irq_base;
 		goto stop_clk;
 	}
diff --git a/drivers/video/fbdev/aty/atyfb_base.c b/drivers/video/fbdev/aty/atyfb_base.c
index 175d2598f28e..49d192869cf5 100644
--- a/drivers/video/fbdev/aty/atyfb_base.c
+++ b/drivers/video/fbdev/aty/atyfb_base.c
@@ -126,7 +126,7 @@
 #ifdef DEBUG
 #define DPRINTK(fmt, args...)	printk(KERN_DEBUG "atyfb: " fmt, ## args)
 #else
-#define DPRINTK(fmt, args...)
+#define DPRINTK(fmt, args...)	no_printk(fmt, ##args)
 #endif
 
 #define PRINTKI(fmt, args...)	printk(KERN_INFO "atyfb: " fmt, ## args)
diff --git a/drivers/video/fbdev/core/fbmon.c b/drivers/video/fbdev/core/fbmon.c
index 8e2e19f3bf44..d62a1e43864e 100644
--- a/drivers/video/fbdev/core/fbmon.c
+++ b/drivers/video/fbdev/core/fbmon.c
@@ -44,7 +44,7 @@
 #ifdef DEBUG
 #define DPRINTK(fmt, args...) printk(fmt,## args)
 #else
-#define DPRINTK(fmt, args...)
+#define DPRINTK(fmt, args...) no_printk(fmt, ##args)
 #endif
 
 #define FBMON_FIX_HEADER  1
diff --git a/drivers/video/fbdev/cyber2000fb.c b/drivers/video/fbdev/cyber2000fb.c
index 460826a7ad55..513f58f28b0f 100644
--- a/drivers/video/fbdev/cyber2000fb.c
+++ b/drivers/video/fbdev/cyber2000fb.c
@@ -1160,12 +1160,14 @@ EXPORT_SYMBOL(cyber2000fb_detach);
 #define DDC_SDA_IN	(1 << 6)
 
 static void cyber2000fb_enable_ddc(struct cfb_info *cfb)
+	__acquires(&cfb->reg_b0_lock)
 {
 	spin_lock(&cfb->reg_b0_lock);
 	cyber2000fb_writew(0x1bf, 0x3ce, cfb);
 }
 
 static void cyber2000fb_disable_ddc(struct cfb_info *cfb)
+	__releases(&cfb->reg_b0_lock)
 {
 	cyber2000fb_writew(0x0bf, 0x3ce, cfb);
 	spin_unlock(&cfb->reg_b0_lock);
diff --git a/drivers/video/fbdev/matrox/g450_pll.c b/drivers/video/fbdev/matrox/g450_pll.c
index c15f8a57498e..ff8e321a22ce 100644
--- a/drivers/video/fbdev/matrox/g450_pll.c
+++ b/drivers/video/fbdev/matrox/g450_pll.c
@@ -333,11 +333,9 @@ static int __g450_setclk(struct matrox_fb_info *minfo, unsigned int fout,
 			 unsigned int *deltaarray)
 {
 	unsigned int mnpcount;
-	unsigned int pixel_vco;
 	const struct matrox_pll_limits* pi;
 	struct matrox_pll_cache* ci;
 
-	pixel_vco = 0;
 	switch (pll) {
 		case M_PIXEL_PLL_A:
 		case M_PIXEL_PLL_B:
@@ -420,7 +418,6 @@ static int __g450_setclk(struct matrox_fb_info *minfo, unsigned int fout,
 				
 				mnp = matroxfb_DAC_in(minfo, M1064_XPIXPLLCM) << 16;
 				mnp |= matroxfb_DAC_in(minfo, M1064_XPIXPLLCN) << 8;
-				pixel_vco = g450_mnp2vco(minfo, mnp);
 				matroxfb_DAC_unlock_irqrestore(flags);
 			}
 			pi = &minfo->limits.video;
@@ -441,25 +438,6 @@ static int __g450_setclk(struct matrox_fb_info *minfo, unsigned int fout,
 			unsigned int delta;
 
 			vco = g450_mnp2vco(minfo, mnp);
-#if 0			
-			if (pll == M_VIDEO_PLL) {
-				unsigned int big, small;
-
-				if (vco < pixel_vco) {
-					small = vco;
-					big = pixel_vco;
-				} else {
-					small = pixel_vco;
-					big = vco;
-				}
-				while (big > small) {
-					big >>= 1;
-				}
-				if (big == small) {
-					continue;
-				}
-			}
-#endif			
 			delta = pll_freq_delta(fout, g450_vco2f(mnp, vco));
 			for (idx = mnpcount; idx > 0; idx--) {
 				/* == is important; due to nextpll algorithm we get
diff --git a/drivers/video/fbdev/matrox/matroxfb_base.h b/drivers/video/fbdev/matrox/matroxfb_base.h
index f85ad25659e5..759dee996af1 100644
--- a/drivers/video/fbdev/matrox/matroxfb_base.h
+++ b/drivers/video/fbdev/matrox/matroxfb_base.h
@@ -86,7 +86,7 @@
 #ifdef DEBUG
 #define dprintk(X...)	printk(X)
 #else
-#define dprintk(X...)
+#define dprintk(X...)	no_printk(X)
 #endif
 
 #ifndef PCI_SS_VENDOR_ID_SIEMENS_NIXDORF
diff --git a/drivers/video/fbdev/mb862xx/mb862xxfb_accel.c b/drivers/video/fbdev/mb862xx/mb862xxfb_accel.c
index 42569264801f..d40b806461ca 100644
--- a/drivers/video/fbdev/mb862xx/mb862xxfb_accel.c
+++ b/drivers/video/fbdev/mb862xx/mb862xxfb_accel.c
@@ -184,7 +184,6 @@ static void mb86290fb_imageblit16(u32 *cmd, u16 step, u16 dx, u16 dy,
 static void mb86290fb_imageblit(struct fb_info *info,
 				const struct fb_image *image)
 {
-	int mdr;
 	u32 *cmd = NULL;
 	void (*cmdfn) (u32 *, u16, u16, u16, u16, u16, u32, u32,
 		       const struct fb_image *, struct fb_info *) = NULL;
@@ -196,7 +195,6 @@ static void mb86290fb_imageblit(struct fb_info *info,
 	u16 dx = image->dx, dy = image->dy;
 	int x2, y2, vxres, vyres;
 
-	mdr = (GDC_ROP_COPY << 9);
 	x2 = image->dx + image->width;
 	y2 = image->dy + image->height;
 	vxres = info->var.xres_virtual;
diff --git a/drivers/video/fbdev/mx3fb.c b/drivers/video/fbdev/mx3fb.c
index 4af28e4421e5..603731a5a72e 100644
--- a/drivers/video/fbdev/mx3fb.c
+++ b/drivers/video/fbdev/mx3fb.c
@@ -509,7 +509,7 @@ static int sdc_init_panel(struct mx3fb_data *mx3fb, enum ipu_panel panel,
 			  uint16_t h_start_width, uint16_t h_sync_width,
 			  uint16_t h_end_width, uint16_t v_start_width,
 			  uint16_t v_sync_width, uint16_t v_end_width,
-			  struct ipu_di_signal_cfg sig)
+			  const struct ipu_di_signal_cfg *sig)
 {
 	unsigned long lock_flags;
 	uint32_t reg;
@@ -591,17 +591,17 @@ static int sdc_init_panel(struct mx3fb_data *mx3fb, enum ipu_panel panel,
 
 	/* DI settings */
 	old_conf = mx3fb_read_reg(mx3fb, DI_DISP_IF_CONF) & 0x78FFFFFF;
-	old_conf |= sig.datamask_en << DI_D3_DATAMSK_SHIFT |
-		sig.clksel_en << DI_D3_CLK_SEL_SHIFT |
-		sig.clkidle_en << DI_D3_CLK_IDLE_SHIFT;
+	old_conf |= sig->datamask_en << DI_D3_DATAMSK_SHIFT |
+		sig->clksel_en << DI_D3_CLK_SEL_SHIFT |
+		sig->clkidle_en << DI_D3_CLK_IDLE_SHIFT;
 	mx3fb_write_reg(mx3fb, old_conf, DI_DISP_IF_CONF);
 
 	old_conf = mx3fb_read_reg(mx3fb, DI_DISP_SIG_POL) & 0xE0FFFFFF;
-	old_conf |= sig.data_pol << DI_D3_DATA_POL_SHIFT |
-		sig.clk_pol << DI_D3_CLK_POL_SHIFT |
-		sig.enable_pol << DI_D3_DRDY_SHARP_POL_SHIFT |
-		sig.Hsync_pol << DI_D3_HSYNC_POL_SHIFT |
-		sig.Vsync_pol << DI_D3_VSYNC_POL_SHIFT;
+	old_conf |= sig->data_pol << DI_D3_DATA_POL_SHIFT |
+		sig->clk_pol << DI_D3_CLK_POL_SHIFT |
+		sig->enable_pol << DI_D3_DRDY_SHARP_POL_SHIFT |
+		sig->Hsync_pol << DI_D3_HSYNC_POL_SHIFT |
+		sig->Vsync_pol << DI_D3_VSYNC_POL_SHIFT;
 	mx3fb_write_reg(mx3fb, old_conf, DI_DISP_SIG_POL);
 
 	map = &di_mappings[mx3fb->disp_data_fmt];
@@ -855,7 +855,7 @@ static int __set_par(struct fb_info *fbi, bool lock)
 				   fbi->var.upper_margin,
 				   fbi->var.vsync_len,
 				   fbi->var.lower_margin +
-				   fbi->var.vsync_len, sig_cfg) != 0) {
+				   fbi->var.vsync_len, &sig_cfg) != 0) {
 			dev_err(fbi->device,
 				"mx3fb: Error initializing panel.\n");
 			return -EINVAL;
diff --git a/drivers/video/fbdev/omap/omapfb_main.c b/drivers/video/fbdev/omap/omapfb_main.c
index e8a304f84ea8..1a9d6242916e 100644
--- a/drivers/video/fbdev/omap/omapfb_main.c
+++ b/drivers/video/fbdev/omap/omapfb_main.c
@@ -1247,7 +1247,7 @@ static ssize_t omapfb_show_caps_num(struct device *dev,
 	size = 0;
 	while (size < PAGE_SIZE && plane < OMAPFB_PLANE_NUM) {
 		omapfb_get_caps(fbdev, plane, &caps);
-		size += snprintf(&buf[size], PAGE_SIZE - size,
+		size += scnprintf(&buf[size], PAGE_SIZE - size,
 			"plane#%d %#010x %#010x %#010x\n",
 			plane, caps.ctrl, caps.plane_color, caps.wnd_color);
 		plane++;
@@ -1268,28 +1268,28 @@ static ssize_t omapfb_show_caps_text(struct device *dev,
 	size = 0;
 	while (size < PAGE_SIZE && plane < OMAPFB_PLANE_NUM) {
 		omapfb_get_caps(fbdev, plane, &caps);
-		size += snprintf(&buf[size], PAGE_SIZE - size,
+		size += scnprintf(&buf[size], PAGE_SIZE - size,
 				 "plane#%d:\n", plane);
 		for (i = 0; i < ARRAY_SIZE(ctrl_caps) &&
 		     size < PAGE_SIZE; i++) {
 			if (ctrl_caps[i].flag & caps.ctrl)
-				size += snprintf(&buf[size], PAGE_SIZE - size,
+				size += scnprintf(&buf[size], PAGE_SIZE - size,
 					" %s\n", ctrl_caps[i].name);
 		}
-		size += snprintf(&buf[size], PAGE_SIZE - size,
+		size += scnprintf(&buf[size], PAGE_SIZE - size,
 				 " plane colors:\n");
 		for (i = 0; i < ARRAY_SIZE(color_caps) &&
 		     size < PAGE_SIZE; i++) {
 			if (color_caps[i].flag & caps.plane_color)
-				size += snprintf(&buf[size], PAGE_SIZE - size,
+				size += scnprintf(&buf[size], PAGE_SIZE - size,
 					"  %s\n", color_caps[i].name);
 		}
-		size += snprintf(&buf[size], PAGE_SIZE - size,
+		size += scnprintf(&buf[size], PAGE_SIZE - size,
 				 " window colors:\n");
 		for (i = 0; i < ARRAY_SIZE(color_caps) &&
 		     size < PAGE_SIZE; i++) {
 			if (color_caps[i].flag & caps.wnd_color)
-				size += snprintf(&buf[size], PAGE_SIZE - size,
+				size += scnprintf(&buf[size], PAGE_SIZE - size,
 					"  %s\n", color_caps[i].name);
 		}
 
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/dispc.c b/drivers/video/fbdev/omap2/omapfb/dss/dispc.c
index ce37da85cc45..4a16798b2ecd 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/dispc.c
+++ b/drivers/video/fbdev/omap2/omapfb/dss/dispc.c
@@ -557,11 +557,6 @@ u32 dispc_mgr_get_sync_lost_irq(enum omap_channel channel)
 }
 EXPORT_SYMBOL(dispc_mgr_get_sync_lost_irq);
 
-u32 dispc_wb_get_framedone_irq(void)
-{
-	return DISPC_IRQ_FRAMEDONEWB;
-}
-
 bool dispc_mgr_go_busy(enum omap_channel channel)
 {
 	return mgr_fld_read(channel, DISPC_MGR_FLD_GO) == 1;
@@ -579,30 +574,6 @@ void dispc_mgr_go(enum omap_channel channel)
 }
 EXPORT_SYMBOL(dispc_mgr_go);
 
-bool dispc_wb_go_busy(void)
-{
-	return REG_GET(DISPC_CONTROL2, 6, 6) == 1;
-}
-
-void dispc_wb_go(void)
-{
-	enum omap_plane plane = OMAP_DSS_WB;
-	bool enable, go;
-
-	enable = REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0) == 1;
-
-	if (!enable)
-		return;
-
-	go = REG_GET(DISPC_CONTROL2, 6, 6) == 1;
-	if (go) {
-		DSSERR("GO bit not down for WB\n");
-		return;
-	}
-
-	REG_FLD_MOD(DISPC_CONTROL2, 1, 6, 6);
-}
-
 static void dispc_ovl_write_firh_reg(enum omap_plane plane, int reg, u32 value)
 {
 	dispc_write_reg(DISPC_OVL_FIR_COEF_H(plane, reg), value);
@@ -1028,13 +999,6 @@ static enum omap_channel dispc_ovl_get_channel_out(enum omap_plane plane)
 	}
 }
 
-void dispc_wb_set_channel_in(enum dss_writeback_channel channel)
-{
-	enum omap_plane plane = OMAP_DSS_WB;
-
-	REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), channel, 18, 16);
-}
-
 static void dispc_ovl_set_burst_size(enum omap_plane plane,
 		enum omap_burst_size burst_size)
 {
@@ -2805,74 +2769,6 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
 }
 EXPORT_SYMBOL(dispc_ovl_setup);
 
-int dispc_wb_setup(const struct omap_dss_writeback_info *wi,
-		bool mem_to_mem, const struct omap_video_timings *mgr_timings)
-{
-	int r;
-	u32 l;
-	enum omap_plane plane = OMAP_DSS_WB;
-	const int pos_x = 0, pos_y = 0;
-	const u8 zorder = 0, global_alpha = 0;
-	const bool replication = false;
-	bool truncation;
-	int in_width = mgr_timings->x_res;
-	int in_height = mgr_timings->y_res;
-	enum omap_overlay_caps caps =
-		OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA;
-
-	DSSDBG("dispc_wb_setup, pa %x, pa_uv %x, %d,%d -> %dx%d, cmode %x, "
-		"rot %d, mir %d\n", wi->paddr, wi->p_uv_addr, in_width,
-		in_height, wi->width, wi->height, wi->color_mode, wi->rotation,
-		wi->mirror);
-
-	r = dispc_ovl_setup_common(plane, caps, wi->paddr, wi->p_uv_addr,
-		wi->buf_width, pos_x, pos_y, in_width, in_height, wi->width,
-		wi->height, wi->color_mode, wi->rotation, wi->mirror, zorder,
-		wi->pre_mult_alpha, global_alpha, wi->rotation_type,
-		replication, mgr_timings, mem_to_mem);
-
-	switch (wi->color_mode) {
-	case OMAP_DSS_COLOR_RGB16:
-	case OMAP_DSS_COLOR_RGB24P:
-	case OMAP_DSS_COLOR_ARGB16:
-	case OMAP_DSS_COLOR_RGBA16:
-	case OMAP_DSS_COLOR_RGB12U:
-	case OMAP_DSS_COLOR_ARGB16_1555:
-	case OMAP_DSS_COLOR_XRGB16_1555:
-	case OMAP_DSS_COLOR_RGBX16:
-		truncation = true;
-		break;
-	default:
-		truncation = false;
-		break;
-	}
-
-	/* setup extra DISPC_WB_ATTRIBUTES */
-	l = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane));
-	l = FLD_MOD(l, truncation, 10, 10);	/* TRUNCATIONENABLE */
-	l = FLD_MOD(l, mem_to_mem, 19, 19);	/* WRITEBACKMODE */
-	if (mem_to_mem)
-		l = FLD_MOD(l, 1, 26, 24);	/* CAPTUREMODE */
-	else
-		l = FLD_MOD(l, 0, 26, 24);	/* CAPTUREMODE */
-	dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), l);
-
-	if (mem_to_mem) {
-		/* WBDELAYCOUNT */
-		REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane), 0, 7, 0);
-	} else {
-		int wbdelay;
-
-		wbdelay = min(mgr_timings->vfp + mgr_timings->vsw +
-			mgr_timings->vbp, 255);
-
-		/* WBDELAYCOUNT */
-		REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane), wbdelay, 7, 0);
-	}
-
-	return r;
-}
-
 int dispc_ovl_enable(enum omap_plane plane, bool enable)
 {
 	DSSDBG("dispc_enable_plane %d, %d\n", plane, enable);
@@ -2903,16 +2799,6 @@ bool dispc_mgr_is_enabled(enum omap_channel channel)
 }
 EXPORT_SYMBOL(dispc_mgr_is_enabled);
 
-void dispc_wb_enable(bool enable)
-{
-	dispc_ovl_enable(OMAP_DSS_WB, enable);
-}
-
-bool dispc_wb_is_enabled(void)
-{
-	return dispc_ovl_enabled(OMAP_DSS_WB);
-}
-
 static void dispc_lcd_enable_signal_polarity(bool act_high)
 {
 	if (!dss_has_feature(FEAT_LCDENABLEPOL))
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/dss.h b/drivers/video/fbdev/omap2/omapfb/dss/dss.h
index a2269008590f..21cfcbf74a6d 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/dss.h
+++ b/drivers/video/fbdev/omap2/omapfb/dss/dss.h
@@ -89,17 +89,6 @@ enum dss_dsi_content_type {
 	DSS_DSI_CONTENT_GENERIC,
 };
 
-enum dss_writeback_channel {
-	DSS_WB_LCD1_MGR =	0,
-	DSS_WB_LCD2_MGR =	1,
-	DSS_WB_TV_MGR =		2,
-	DSS_WB_OVL0 =		3,
-	DSS_WB_OVL1 =		4,
-	DSS_WB_OVL2 =		5,
-	DSS_WB_OVL3 =		6,
-	DSS_WB_LCD3_MGR =	7,
-};
-
 enum dss_pll_id {
 	DSS_PLL_DSI1,
 	DSS_PLL_DSI2,
@@ -403,15 +392,6 @@ int dispc_mgr_get_clock_div(enum omap_channel channel,
 		struct dispc_clock_info *cinfo);
 void dispc_set_tv_pclk(unsigned long pclk);
 
-u32 dispc_wb_get_framedone_irq(void);
-bool dispc_wb_go_busy(void);
-void dispc_wb_go(void);
-void dispc_wb_enable(bool enable);
-bool dispc_wb_is_enabled(void);
-void dispc_wb_set_channel_in(enum dss_writeback_channel channel);
-int dispc_wb_setup(const struct omap_dss_writeback_info *wi,
-		bool mem_to_mem, const struct omap_video_timings *timings);
-
 u32 dispc_read_irqstatus(void);
 void dispc_clear_irqstatus(u32 mask);
 u32 dispc_read_irqenable(void);
diff --git a/drivers/video/fbdev/omap2/omapfb/omapfb-sysfs.c b/drivers/video/fbdev/omap2/omapfb/omapfb-sysfs.c
index 4a5db170ef59..2d39dbfa742e 100644
--- a/drivers/video/fbdev/omap2/omapfb/omapfb-sysfs.c
+++ b/drivers/video/fbdev/omap2/omapfb/omapfb-sysfs.c
@@ -147,11 +147,11 @@ static ssize_t show_overlays(struct device *dev,
 			if (ovl == fbdev->overlays[ovlnum])
 				break;
 
-		l += snprintf(buf + l, PAGE_SIZE - l, "%s%d",
+		l += scnprintf(buf + l, PAGE_SIZE - l, "%s%d",
 				t == 0 ? "" : ",", ovlnum);
 	}
 
-	l += snprintf(buf + l, PAGE_SIZE - l, "\n");
+	l += scnprintf(buf + l, PAGE_SIZE - l, "\n");
 
 	omapfb_unlock(fbdev);
 	unlock_fb_info(fbi);
@@ -328,11 +328,11 @@ static ssize_t show_overlays_rotate(struct device *dev,
 	lock_fb_info(fbi);
 
 	for (t = 0; t < ofbi->num_overlays; t++) {
-		l += snprintf(buf + l, PAGE_SIZE - l, "%s%d",
+		l += scnprintf(buf + l, PAGE_SIZE - l, "%s%d",
 				t == 0 ? "" : ",", ofbi->rotation[t]);
 	}
 
-	l += snprintf(buf + l, PAGE_SIZE - l, "\n");
+	l += scnprintf(buf + l, PAGE_SIZE - l, "\n");
 
 	unlock_fb_info(fbi);
 
diff --git a/drivers/video/fbdev/pm2fb.c b/drivers/video/fbdev/pm2fb.c
index fe2cadeb1b66..c7c98d8e2359 100644
--- a/drivers/video/fbdev/pm2fb.c
+++ b/drivers/video/fbdev/pm2fb.c
@@ -54,7 +54,7 @@
 #define DPRINTK(a, b...)	\
 	printk(KERN_DEBUG "pm2fb: %s: " a, __func__ , ## b)
 #else
-#define DPRINTK(a, b...)
+#define DPRINTK(a, b...)	no_printk(a, ##b)
 #endif
 
 #define PM2_PIXMAP_SIZE	(1600 * 4)
diff --git a/drivers/video/fbdev/pm3fb.c b/drivers/video/fbdev/pm3fb.c
index 2f5e23c8f8ec..7497bd36334c 100644
--- a/drivers/video/fbdev/pm3fb.c
+++ b/drivers/video/fbdev/pm3fb.c
@@ -44,7 +44,7 @@
 #define DPRINTK(a, b...)	\
 	printk(KERN_DEBUG "pm3fb: %s: " a, __func__ , ## b)
 #else
-#define DPRINTK(a, b...)
+#define DPRINTK(a, b...)	no_printk(a, ##b)
 #endif
 
 #define PM3_PIXMAP_SIZE	(2048 * 4)
@@ -306,7 +306,7 @@ static void pm3fb_init_engine(struct fb_info *info)
 					   PM3PixelSize_GLOBAL_32BIT);
 			break;
 		default:
-			DPRINTK(1, "Unsupported depth %d\n",
+			DPRINTK("Unsupported depth %d\n",
 				info->var.bits_per_pixel);
 			break;
 		}
@@ -349,8 +349,8 @@ static void pm3fb_init_engine(struct fb_info *info)
 					   (1 << 10) | (0 << 3));
 			break;
 		default:
-			DPRINTK(1, "Unsupported depth %d\n",
-				info->current_par->depth);
+			DPRINTK("Unsupported depth %d\n",
+				info->var.bits_per_pixel);
 			break;
 		}
 	}
diff --git a/drivers/video/fbdev/savage/savagefb.h b/drivers/video/fbdev/savage/savagefb.h
index aba04afe712d..3314d5b6b43b 100644
--- a/drivers/video/fbdev/savage/savagefb.h
+++ b/drivers/video/fbdev/savage/savagefb.h
@@ -21,7 +21,7 @@
 #ifdef SAVAGEFB_DEBUG
 # define DBG(x)		printk (KERN_DEBUG "savagefb: %s\n", (x));
 #else
-# define DBG(x)
+# define DBG(x)		no_printk(x)
 # define SavagePrintRegs(...)
 #endif
 
diff --git a/drivers/video/fbdev/uvesafb.c b/drivers/video/fbdev/uvesafb.c
index 53d08d1b56f5..1b385cf76110 100644
--- a/drivers/video/fbdev/uvesafb.c
+++ b/drivers/video/fbdev/uvesafb.c
@@ -1560,7 +1560,7 @@ static ssize_t uvesafb_show_vbe_modes(struct device *dev,
 	int ret = 0, i;
 
 	for (i = 0; i < par->vbe_modes_cnt && ret < PAGE_SIZE; i++) {
-		ret += snprintf(buf + ret, PAGE_SIZE - ret,
+		ret += scnprintf(buf + ret, PAGE_SIZE - ret,
 			"%dx%d-%d, 0x%.4x\n",
 			par->vbe_modes[i].x_res, par->vbe_modes[i].y_res,
 			par->vbe_modes[i].depth, par->vbe_modes[i].mode_id);
diff --git a/drivers/video/fbdev/via/debug.h b/drivers/video/fbdev/via/debug.h
index 6a320bd76936..80fdfe4171c5 100644
--- a/drivers/video/fbdev/via/debug.h
+++ b/drivers/video/fbdev/via/debug.h
@@ -7,6 +7,8 @@
 #ifndef __DEBUG_H__
 #define __DEBUG_H__
 
+#include <linux/printk.h>
+
 #ifndef VIAFB_DEBUG
 #define VIAFB_DEBUG 0
 #endif
@@ -14,14 +16,14 @@
 #if VIAFB_DEBUG
 #define DEBUG_MSG(f, a...)   printk(f, ## a)
 #else
-#define DEBUG_MSG(f, a...)
+#define DEBUG_MSG(f, a...)   no_printk(f, ## a)
 #endif
 
 #define VIAFB_WARN 0
 #if VIAFB_WARN
 #define WARN_MSG(f, a...)   printk(f, ## a)
 #else
-#define WARN_MSG(f, a...)
+#define WARN_MSG(f, a...)   no_printk(f, ## a)
 #endif
 
 #endif /* __DEBUG_H__ */
diff --git a/drivers/video/fbdev/via/viafbdev.c b/drivers/video/fbdev/via/viafbdev.c
index 852673c40a2f..22deb340a048 100644
--- a/drivers/video/fbdev/via/viafbdev.c
+++ b/drivers/video/fbdev/via/viafbdev.c
@@ -1144,7 +1144,7 @@ static ssize_t viafb_dvp0_proc_write(struct file *file,
 		if (value != NULL) {
 			if (kstrtou8(value, 0, &reg_val) < 0)
 				return -EINVAL;
-			DEBUG_MSG(KERN_INFO "DVP0:reg_val[%l]=:%x\n", i,
+			DEBUG_MSG(KERN_INFO "DVP0:reg_val[%lu]=:%x\n", i,
 				  reg_val);
 			switch (i) {
 			case 0:
diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
index 2bbf94b15bba..69a32dfc318a 100644
--- a/drivers/virtio/Kconfig
+++ b/drivers/virtio/Kconfig
@@ -45,7 +45,7 @@ config VIRTIO_PCI_LEGACY
 
 config VIRTIO_VDPA
 	tristate "vDPA driver for virtio devices"
-	select VDPA
+	depends on VDPA
 	select VIRTIO
 	help
 	  This driver provides support for virtio based paravirtual
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
index 0ef16566c3f3..51086a5afdd4 100644
--- a/drivers/virtio/virtio_balloon.c
+++ b/drivers/virtio/virtio_balloon.c
@@ -165,7 +165,7 @@ static void tell_host(struct virtio_balloon *vb, struct virtqueue *vq)
 
 }
 
-int virtballoon_free_page_report(struct page_reporting_dev_info *pr_dev_info,
+static int virtballoon_free_page_report(struct page_reporting_dev_info *pr_dev_info,
 				   struct scatterlist *sg, unsigned int nents)
 {
 	struct virtio_balloon *vb =
@@ -580,7 +580,7 @@ static u32 virtio_balloon_cmd_id_received(struct virtio_balloon *vb)
 	if (test_and_clear_bit(VIRTIO_BALLOON_CONFIG_READ_CMD_ID,
 			       &vb->config_read_bitmap))
 		virtio_cread(vb->vdev, struct virtio_balloon_config,
-			     free_page_report_cmd_id,
+			     free_page_hint_cmd_id,
 			     &vb->cmd_id_received_cache);
 
 	return vb->cmd_id_received_cache;
diff --git a/drivers/virtio/virtio_input.c b/drivers/virtio/virtio_input.c
index 5ae529671b3d..efaf65b0f42d 100644
--- a/drivers/virtio/virtio_input.c
+++ b/drivers/virtio/virtio_input.c
@@ -3,6 +3,7 @@
 #include <linux/virtio.h>
 #include <linux/virtio_config.h>
 #include <linux/input.h>
+#include <linux/slab.h>
 
 #include <uapi/linux/virtio_ids.h>
 #include <uapi/linux/virtio_input.h>
diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c
index 97d5725fd9a2..9d16aaffca9d 100644
--- a/drivers/virtio/virtio_mmio.c
+++ b/drivers/virtio/virtio_mmio.c
@@ -466,10 +466,8 @@ static int vm_find_vqs(struct virtio_device *vdev, unsigned nvqs,
 	int irq = platform_get_irq(vm_dev->pdev, 0);
 	int i, err, queue_idx = 0;
 
-	if (irq < 0) {
-		dev_err(&vdev->dev, "Cannot get IRQ resource\n");
+	if (irq < 0)
 		return irq;
-	}
 
 	err = request_irq(irq, vm_interrupt, IRQF_SHARED,
 			dev_name(&vdev->dev), vm_dev);
diff --git a/drivers/virtio/virtio_pci_modern.c b/drivers/virtio/virtio_pci_modern.c
index 7abcc50838b8..db93cedd262f 100644
--- a/drivers/virtio/virtio_pci_modern.c
+++ b/drivers/virtio/virtio_pci_modern.c
@@ -16,6 +16,7 @@
 
 #include <linux/delay.h>
 #define VIRTIO_PCI_NO_LEGACY
+#define VIRTIO_RING_NO_LEGACY
 #include "virtio_pci_common.h"
 
 /*
diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c
index 53e04926a7b2..190d26e2e75f 100644
--- a/drivers/watchdog/sp805_wdt.c
+++ b/drivers/watchdog/sp805_wdt.c
@@ -137,10 +137,14 @@ wdt_restart(struct watchdog_device *wdd, unsigned long mode, void *cmd)
 {
 	struct sp805_wdt *wdt = watchdog_get_drvdata(wdd);
 
+	writel_relaxed(UNLOCK, wdt->base + WDTLOCK);
 	writel_relaxed(0, wdt->base + WDTCONTROL);
 	writel_relaxed(0, wdt->base + WDTLOAD);
 	writel_relaxed(INT_ENABLE | RESET_ENABLE, wdt->base + WDTCONTROL);
 
+	/* Flush posted writes. */
+	readl_relaxed(wdt->base + WDTLOCK);
+
 	return 0;
 }
 
diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c
index 385843256865..040d2a43e8e3 100644
--- a/drivers/xen/xenbus/xenbus_client.c
+++ b/drivers/xen/xenbus/xenbus_client.c
@@ -448,7 +448,14 @@ EXPORT_SYMBOL_GPL(xenbus_free_evtchn);
 int xenbus_map_ring_valloc(struct xenbus_device *dev, grant_ref_t *gnt_refs,
 			   unsigned int nr_grefs, void **vaddr)
 {
-	return ring_ops->map(dev, gnt_refs, nr_grefs, vaddr);
+	int err;
+
+	err = ring_ops->map(dev, gnt_refs, nr_grefs, vaddr);
+	/* Some hypervisors are buggy and can return 1. */
+	if (err > 0)
+		err = GNTST_general_error;
+
+	return err;
 }
 EXPORT_SYMBOL_GPL(xenbus_map_ring_valloc);
 
diff --git a/fs/afs/dir.c b/fs/afs/dir.c
index 5c794f4b051a..d1e1caa23c8b 100644
--- a/fs/afs/dir.c
+++ b/fs/afs/dir.c
@@ -1032,7 +1032,7 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags)
 	struct dentry *parent;
 	struct inode *inode;
 	struct key *key;
-	afs_dataversion_t dir_version;
+	afs_dataversion_t dir_version, invalid_before;
 	long de_version;
 	int ret;
 
@@ -1084,8 +1084,8 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags)
 	if (de_version == (long)dir_version)
 		goto out_valid_noupdate;
 
-	dir_version = dir->invalid_before;
-	if (de_version - (long)dir_version >= 0)
+	invalid_before = dir->invalid_before;
+	if (de_version - (long)invalid_before >= 0)
 		goto out_valid;
 
 	_debug("dir modified");
@@ -1275,6 +1275,7 @@ static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
 	struct afs_fs_cursor fc;
 	struct afs_vnode *dvnode = AFS_FS_I(dir);
 	struct key *key;
+	afs_dataversion_t data_version;
 	int ret;
 
 	mode |= S_IFDIR;
@@ -1295,7 +1296,7 @@ static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
 
 	ret = -ERESTARTSYS;
 	if (afs_begin_vnode_operation(&fc, dvnode, key, true)) {
-		afs_dataversion_t data_version = dvnode->status.data_version + 1;
+		data_version = dvnode->status.data_version + 1;
 
 		while (afs_select_fileserver(&fc)) {
 			fc.cb_break = afs_calc_vnode_cb_break(dvnode);
@@ -1316,10 +1317,14 @@ static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
 		goto error_key;
 	}
 
-	if (ret == 0 &&
-	    test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags))
-		afs_edit_dir_add(dvnode, &dentry->d_name, &iget_data.fid,
-				 afs_edit_dir_for_create);
+	if (ret == 0) {
+		down_write(&dvnode->validate_lock);
+		if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) &&
+		    dvnode->status.data_version == data_version)
+			afs_edit_dir_add(dvnode, &dentry->d_name, &iget_data.fid,
+					 afs_edit_dir_for_create);
+		up_write(&dvnode->validate_lock);
+	}
 
 	key_put(key);
 	kfree(scb);
@@ -1360,6 +1365,7 @@ static int afs_rmdir(struct inode *dir, struct dentry *dentry)
 	struct afs_fs_cursor fc;
 	struct afs_vnode *dvnode = AFS_FS_I(dir), *vnode = NULL;
 	struct key *key;
+	afs_dataversion_t data_version;
 	int ret;
 
 	_enter("{%llx:%llu},{%pd}",
@@ -1391,7 +1397,7 @@ static int afs_rmdir(struct inode *dir, struct dentry *dentry)
 
 	ret = -ERESTARTSYS;
 	if (afs_begin_vnode_operation(&fc, dvnode, key, true)) {
-		afs_dataversion_t data_version = dvnode->status.data_version + 1;
+		data_version = dvnode->status.data_version + 1;
 
 		while (afs_select_fileserver(&fc)) {
 			fc.cb_break = afs_calc_vnode_cb_break(dvnode);
@@ -1404,9 +1410,12 @@ static int afs_rmdir(struct inode *dir, struct dentry *dentry)
 		ret = afs_end_vnode_operation(&fc);
 		if (ret == 0) {
 			afs_dir_remove_subdir(dentry);
-			if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags))
+			down_write(&dvnode->validate_lock);
+			if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) &&
+			    dvnode->status.data_version == data_version)
 				afs_edit_dir_remove(dvnode, &dentry->d_name,
 						    afs_edit_dir_for_rmdir);
+			up_write(&dvnode->validate_lock);
 		}
 	}
 
@@ -1544,10 +1553,15 @@ static int afs_unlink(struct inode *dir, struct dentry *dentry)
 		ret = afs_end_vnode_operation(&fc);
 		if (ret == 0 && !(scb[1].have_status || scb[1].have_error))
 			ret = afs_dir_remove_link(dvnode, dentry, key);
-		if (ret == 0 &&
-		    test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags))
-			afs_edit_dir_remove(dvnode, &dentry->d_name,
-					    afs_edit_dir_for_unlink);
+
+		if (ret == 0) {
+			down_write(&dvnode->validate_lock);
+			if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) &&
+			    dvnode->status.data_version == data_version)
+				afs_edit_dir_remove(dvnode, &dentry->d_name,
+						    afs_edit_dir_for_unlink);
+			up_write(&dvnode->validate_lock);
+		}
 	}
 
 	if (need_rehash && ret < 0 && ret != -ENOENT)
@@ -1573,6 +1587,7 @@ static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
 	struct afs_status_cb *scb;
 	struct afs_vnode *dvnode = AFS_FS_I(dir);
 	struct key *key;
+	afs_dataversion_t data_version;
 	int ret;
 
 	mode |= S_IFREG;
@@ -1597,7 +1612,7 @@ static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
 
 	ret = -ERESTARTSYS;
 	if (afs_begin_vnode_operation(&fc, dvnode, key, true)) {
-		afs_dataversion_t data_version = dvnode->status.data_version + 1;
+		data_version = dvnode->status.data_version + 1;
 
 		while (afs_select_fileserver(&fc)) {
 			fc.cb_break = afs_calc_vnode_cb_break(dvnode);
@@ -1618,9 +1633,12 @@ static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
 		goto error_key;
 	}
 
-	if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags))
+	down_write(&dvnode->validate_lock);
+	if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) &&
+	    dvnode->status.data_version == data_version)
 		afs_edit_dir_add(dvnode, &dentry->d_name, &iget_data.fid,
 				 afs_edit_dir_for_create);
+	up_write(&dvnode->validate_lock);
 
 	kfree(scb);
 	key_put(key);
@@ -1648,6 +1666,7 @@ static int afs_link(struct dentry *from, struct inode *dir,
 	struct afs_vnode *dvnode = AFS_FS_I(dir);
 	struct afs_vnode *vnode = AFS_FS_I(d_inode(from));
 	struct key *key;
+	afs_dataversion_t data_version;
 	int ret;
 
 	_enter("{%llx:%llu},{%llx:%llu},{%pd}",
@@ -1672,7 +1691,7 @@ static int afs_link(struct dentry *from, struct inode *dir,
 
 	ret = -ERESTARTSYS;
 	if (afs_begin_vnode_operation(&fc, dvnode, key, true)) {
-		afs_dataversion_t data_version = dvnode->status.data_version + 1;
+		data_version = dvnode->status.data_version + 1;
 
 		if (mutex_lock_interruptible_nested(&vnode->io_lock, 1) < 0) {
 			afs_end_vnode_operation(&fc);
@@ -1702,9 +1721,12 @@ static int afs_link(struct dentry *from, struct inode *dir,
 		goto error_key;
 	}
 
-	if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags))
+	down_write(&dvnode->validate_lock);
+	if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) &&
+	    dvnode->status.data_version == data_version)
 		afs_edit_dir_add(dvnode, &dentry->d_name, &vnode->fid,
 				 afs_edit_dir_for_link);
+	up_write(&dvnode->validate_lock);
 
 	key_put(key);
 	kfree(scb);
@@ -1732,6 +1754,7 @@ static int afs_symlink(struct inode *dir, struct dentry *dentry,
 	struct afs_status_cb *scb;
 	struct afs_vnode *dvnode = AFS_FS_I(dir);
 	struct key *key;
+	afs_dataversion_t data_version;
 	int ret;
 
 	_enter("{%llx:%llu},{%pd},%s",
@@ -1759,7 +1782,7 @@ static int afs_symlink(struct inode *dir, struct dentry *dentry,
 
 	ret = -ERESTARTSYS;
 	if (afs_begin_vnode_operation(&fc, dvnode, key, true)) {
-		afs_dataversion_t data_version = dvnode->status.data_version + 1;
+		data_version = dvnode->status.data_version + 1;
 
 		while (afs_select_fileserver(&fc)) {
 			fc.cb_break = afs_calc_vnode_cb_break(dvnode);
@@ -1780,9 +1803,12 @@ static int afs_symlink(struct inode *dir, struct dentry *dentry,
 		goto error_key;
 	}
 
-	if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags))
+	down_write(&dvnode->validate_lock);
+	if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) &&
+	    dvnode->status.data_version == data_version)
 		afs_edit_dir_add(dvnode, &dentry->d_name, &iget_data.fid,
 				 afs_edit_dir_for_symlink);
+	up_write(&dvnode->validate_lock);
 
 	key_put(key);
 	kfree(scb);
@@ -1812,6 +1838,8 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
 	struct dentry *tmp = NULL, *rehash = NULL;
 	struct inode *new_inode;
 	struct key *key;
+	afs_dataversion_t orig_data_version;
+	afs_dataversion_t new_data_version;
 	bool new_negative = d_is_negative(new_dentry);
 	int ret;
 
@@ -1890,10 +1918,6 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
 
 	ret = -ERESTARTSYS;
 	if (afs_begin_vnode_operation(&fc, orig_dvnode, key, true)) {
-		afs_dataversion_t orig_data_version;
-		afs_dataversion_t new_data_version;
-		struct afs_status_cb *new_scb = &scb[1];
-
 		orig_data_version = orig_dvnode->status.data_version + 1;
 
 		if (orig_dvnode != new_dvnode) {
@@ -1904,7 +1928,6 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
 			new_data_version = new_dvnode->status.data_version + 1;
 		} else {
 			new_data_version = orig_data_version;
-			new_scb = &scb[0];
 		}
 
 		while (afs_select_fileserver(&fc)) {
@@ -1912,7 +1935,7 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
 			fc.cb_break_2 = afs_calc_vnode_cb_break(new_dvnode);
 			afs_fs_rename(&fc, old_dentry->d_name.name,
 				      new_dvnode, new_dentry->d_name.name,
-				      &scb[0], new_scb);
+				      &scb[0], &scb[1]);
 		}
 
 		afs_vnode_commit_status(&fc, orig_dvnode, fc.cb_break,
@@ -1930,18 +1953,25 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
 	if (ret == 0) {
 		if (rehash)
 			d_rehash(rehash);
-		if (test_bit(AFS_VNODE_DIR_VALID, &orig_dvnode->flags))
-		    afs_edit_dir_remove(orig_dvnode, &old_dentry->d_name,
-					afs_edit_dir_for_rename_0);
+		down_write(&orig_dvnode->validate_lock);
+		if (test_bit(AFS_VNODE_DIR_VALID, &orig_dvnode->flags) &&
+		    orig_dvnode->status.data_version == orig_data_version)
+			afs_edit_dir_remove(orig_dvnode, &old_dentry->d_name,
+					    afs_edit_dir_for_rename_0);
+		if (orig_dvnode != new_dvnode) {
+			up_write(&orig_dvnode->validate_lock);
 
-		if (!new_negative &&
-		    test_bit(AFS_VNODE_DIR_VALID, &new_dvnode->flags))
-			afs_edit_dir_remove(new_dvnode, &new_dentry->d_name,
-					    afs_edit_dir_for_rename_1);
+			down_write(&new_dvnode->validate_lock);
+		}
+		if (test_bit(AFS_VNODE_DIR_VALID, &new_dvnode->flags) &&
+		    orig_dvnode->status.data_version == new_data_version) {
+			if (!new_negative)
+				afs_edit_dir_remove(new_dvnode, &new_dentry->d_name,
+						    afs_edit_dir_for_rename_1);
 
-		if (test_bit(AFS_VNODE_DIR_VALID, &new_dvnode->flags))
 			afs_edit_dir_add(new_dvnode, &new_dentry->d_name,
 					 &vnode->fid, afs_edit_dir_for_rename_2);
+		}
 
 		new_inode = d_inode(new_dentry);
 		if (new_inode) {
@@ -1957,14 +1987,10 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
 		 * Note that if we ever implement RENAME_EXCHANGE, we'll have
 		 * to update both dentries with opposing dir versions.
 		 */
-		if (new_dvnode != orig_dvnode) {
-			afs_update_dentry_version(&fc, old_dentry, &scb[1]);
-			afs_update_dentry_version(&fc, new_dentry, &scb[1]);
-		} else {
-			afs_update_dentry_version(&fc, old_dentry, &scb[0]);
-			afs_update_dentry_version(&fc, new_dentry, &scb[0]);
-		}
+		afs_update_dentry_version(&fc, old_dentry, &scb[1]);
+		afs_update_dentry_version(&fc, new_dentry, &scb[1]);
 		d_move(old_dentry, new_dentry);
+		up_write(&new_dvnode->validate_lock);
 		goto error_tmp;
 	}
 
diff --git a/fs/afs/dir_silly.c b/fs/afs/dir_silly.c
index 361088a5edb9..d94e2b7cddff 100644
--- a/fs/afs/dir_silly.c
+++ b/fs/afs/dir_silly.c
@@ -21,6 +21,7 @@ static int afs_do_silly_rename(struct afs_vnode *dvnode, struct afs_vnode *vnode
 {
 	struct afs_fs_cursor fc;
 	struct afs_status_cb *scb;
+	afs_dataversion_t dir_data_version;
 	int ret = -ERESTARTSYS;
 
 	_enter("%pd,%pd", old, new);
@@ -31,7 +32,7 @@ static int afs_do_silly_rename(struct afs_vnode *dvnode, struct afs_vnode *vnode
 
 	trace_afs_silly_rename(vnode, false);
 	if (afs_begin_vnode_operation(&fc, dvnode, key, true)) {
-		afs_dataversion_t dir_data_version = dvnode->status.data_version + 1;
+		dir_data_version = dvnode->status.data_version + 1;
 
 		while (afs_select_fileserver(&fc)) {
 			fc.cb_break = afs_calc_vnode_cb_break(dvnode);
@@ -54,12 +55,15 @@ static int afs_do_silly_rename(struct afs_vnode *dvnode, struct afs_vnode *vnode
 			dvnode->silly_key = key_get(key);
 		}
 
-		if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags))
+		down_write(&dvnode->validate_lock);
+		if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) &&
+		    dvnode->status.data_version == dir_data_version) {
 			afs_edit_dir_remove(dvnode, &old->d_name,
 					    afs_edit_dir_for_silly_0);
-		if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags))
 			afs_edit_dir_add(dvnode, &new->d_name,
 					 &vnode->fid, afs_edit_dir_for_silly_1);
+		}
+		up_write(&dvnode->validate_lock);
 	}
 
 	kfree(scb);
@@ -181,10 +185,14 @@ static int afs_do_silly_unlink(struct afs_vnode *dvnode, struct afs_vnode *vnode
 				clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags);
 			}
 		}
-		if (ret == 0 &&
-		    test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags))
-			afs_edit_dir_remove(dvnode, &dentry->d_name,
-					    afs_edit_dir_for_unlink);
+		if (ret == 0) {
+			down_write(&dvnode->validate_lock);
+			if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) &&
+			    dvnode->status.data_version == dir_data_version)
+				afs_edit_dir_remove(dvnode, &dentry->d_name,
+						    afs_edit_dir_for_unlink);
+			up_write(&dvnode->validate_lock);
+		}
 	}
 
 	kfree(scb);
diff --git a/fs/afs/fsclient.c b/fs/afs/fsclient.c
index 1f9c5d8e6fe5..68fc46634346 100644
--- a/fs/afs/fsclient.c
+++ b/fs/afs/fsclient.c
@@ -65,6 +65,7 @@ static int xdr_decode_AFSFetchStatus(const __be32 **_bp,
 	bool inline_error = (call->operation_ID == afs_FS_InlineBulkStatus);
 	u64 data_version, size;
 	u32 type, abort_code;
+	int ret;
 
 	abort_code = ntohl(xdr->abort_code);
 
@@ -78,7 +79,7 @@ static int xdr_decode_AFSFetchStatus(const __be32 **_bp,
 			 */
 			status->abort_code = abort_code;
 			scb->have_error = true;
-			return 0;
+			goto good;
 		}
 
 		pr_warn("Unknown AFSFetchStatus version %u\n", ntohl(xdr->if_version));
@@ -87,7 +88,8 @@ static int xdr_decode_AFSFetchStatus(const __be32 **_bp,
 
 	if (abort_code != 0 && inline_error) {
 		status->abort_code = abort_code;
-		return 0;
+		scb->have_error = true;
+		goto good;
 	}
 
 	type = ntohl(xdr->type);
@@ -123,13 +125,16 @@ static int xdr_decode_AFSFetchStatus(const __be32 **_bp,
 	data_version |= (u64)ntohl(xdr->data_version_hi) << 32;
 	status->data_version = data_version;
 	scb->have_status = true;
-
+good:
+	ret = 0;
+advance:
 	*_bp = (const void *)*_bp + sizeof(*xdr);
-	return 0;
+	return ret;
 
 bad:
 	xdr_dump_bad(*_bp);
-	return afs_protocol_error(call, -EBADMSG, afs_eproto_bad_status);
+	ret = afs_protocol_error(call, -EBADMSG, afs_eproto_bad_status);
+	goto advance;
 }
 
 static time64_t xdr_decode_expiry(struct afs_call *call, u32 expiry)
@@ -981,16 +986,16 @@ static int afs_deliver_fs_rename(struct afs_call *call)
 	if (ret < 0)
 		return ret;
 
-	/* unmarshall the reply once we've received all of it */
+	/* If the two dirs are the same, we have two copies of the same status
+	 * report, so we just decode it twice.
+	 */
 	bp = call->buffer;
 	ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_dir_scb);
 	if (ret < 0)
 		return ret;
-	if (call->out_dir_scb != call->out_scb) {
-		ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb);
-		if (ret < 0)
-			return ret;
-	}
+	ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb);
+	if (ret < 0)
+		return ret;
 	xdr_decode_AFSVolSync(&bp, call->out_volsync);
 
 	_leave(" = 0 [done]");
diff --git a/fs/afs/yfsclient.c b/fs/afs/yfsclient.c
index a26126ac7bf1..b5b45c57e1b1 100644
--- a/fs/afs/yfsclient.c
+++ b/fs/afs/yfsclient.c
@@ -165,15 +165,15 @@ static void xdr_dump_bad(const __be32 *bp)
 	int i;
 
 	pr_notice("YFS XDR: Bad status record\n");
-	for (i = 0; i < 5 * 4 * 4; i += 16) {
+	for (i = 0; i < 6 * 4 * 4; i += 16) {
 		memcpy(x, bp, 16);
 		bp += 4;
 		pr_notice("%03x: %08x %08x %08x %08x\n",
 			  i, ntohl(x[0]), ntohl(x[1]), ntohl(x[2]), ntohl(x[3]));
 	}
 
-	memcpy(x, bp, 4);
-	pr_notice("0x50: %08x\n", ntohl(x[0]));
+	memcpy(x, bp, 8);
+	pr_notice("0x60: %08x %08x\n", ntohl(x[0]), ntohl(x[1]));
 }
 
 /*
@@ -186,13 +186,14 @@ static int xdr_decode_YFSFetchStatus(const __be32 **_bp,
 	const struct yfs_xdr_YFSFetchStatus *xdr = (const void *)*_bp;
 	struct afs_file_status *status = &scb->status;
 	u32 type;
+	int ret;
 
 	status->abort_code = ntohl(xdr->abort_code);
 	if (status->abort_code != 0) {
 		if (status->abort_code == VNOVNODE)
 			status->nlink = 0;
 		scb->have_error = true;
-		return 0;
+		goto good;
 	}
 
 	type = ntohl(xdr->type);
@@ -220,13 +221,16 @@ static int xdr_decode_YFSFetchStatus(const __be32 **_bp,
 	status->size		= xdr_to_u64(xdr->size);
 	status->data_version	= xdr_to_u64(xdr->data_version);
 	scb->have_status	= true;
-
+good:
+	ret = 0;
+advance:
 	*_bp += xdr_size(xdr);
-	return 0;
+	return ret;
 
 bad:
 	xdr_dump_bad(*_bp);
-	return afs_protocol_error(call, -EBADMSG, afs_eproto_bad_status);
+	ret = afs_protocol_error(call, -EBADMSG, afs_eproto_bad_status);
+	goto advance;
 }
 
 /*
@@ -1153,11 +1157,9 @@ static int yfs_deliver_fs_rename(struct afs_call *call)
 	ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
 	if (ret < 0)
 		return ret;
-	if (call->out_dir_scb != call->out_scb) {
-		ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
-		if (ret < 0)
-			return ret;
-	}
+	ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
+	if (ret < 0)
+		return ret;
 
 	xdr_decode_YFSVolSync(&bp, call->out_volsync);
 	_leave(" = 0 [done]");
diff --git a/fs/aio.c b/fs/aio.c
index 5f3d3d814928..94f2b9256c0c 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -1287,12 +1287,9 @@ static long read_events(struct kioctx *ctx, long min_nr, long nr,
 	 * the ringbuffer empty. So in practice we should be ok, but it's
 	 * something to be aware of when touching this code.
 	 */
-	if (until == 0)
-		aio_read_events(ctx, min_nr, nr, event, &ret);
-	else
-		wait_event_interruptible_hrtimeout(ctx->wait,
-				aio_read_events(ctx, min_nr, nr, event, &ret),
-				until);
+	wait_event_interruptible_hrtimeout(ctx->wait,
+			aio_read_events(ctx, min_nr, nr, event, &ret),
+			until);
 	return ret;
 }
 
diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c
index 786849fcc319..47f66c6a7d7f 100644
--- a/fs/btrfs/block-group.c
+++ b/fs/btrfs/block-group.c
@@ -3370,6 +3370,7 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info)
 			    space_info->bytes_reserved > 0 ||
 			    space_info->bytes_may_use > 0))
 			btrfs_dump_space_info(info, space_info, 0, 0);
+		WARN_ON(space_info->reclaim_size > 0);
 		list_del(&space_info->list);
 		btrfs_sysfs_remove_space_info(space_info);
 	}
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 8a144f9cb7ac..719e68ab552c 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -2097,6 +2097,21 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
 
 	atomic_inc(&root->log_batch);
 
+	/*
+	 * If the inode needs a full sync, make sure we use a full range to
+	 * avoid log tree corruption, due to hole detection racing with ordered
+	 * extent completion for adjacent ranges and races between logging and
+	 * completion of ordered extents for adjancent ranges - both races
+	 * could lead to file extent items in the log with overlapping ranges.
+	 * Do this while holding the inode lock, to avoid races with other
+	 * tasks.
+	 */
+	if (test_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
+		     &BTRFS_I(inode)->runtime_flags)) {
+		start = 0;
+		end = LLONG_MAX;
+	}
+
 	/*
 	 * Before we acquired the inode's lock, someone may have dirtied more
 	 * pages in the target range. We need to make sure that writeback for
diff --git a/fs/btrfs/reflink.c b/fs/btrfs/reflink.c
index d1973141d3bb..040009d1cc31 100644
--- a/fs/btrfs/reflink.c
+++ b/fs/btrfs/reflink.c
@@ -264,6 +264,7 @@ static int clone_copy_inline_extent(struct inode *dst,
 			    size);
 	inode_add_bytes(dst, datal);
 	set_bit(BTRFS_INODE_NEEDS_FULL_SYNC, &BTRFS_I(dst)->runtime_flags);
+	ret = btrfs_inode_set_file_extent_range(BTRFS_I(dst), 0, aligned_end);
 out:
 	if (!ret && !trans) {
 		/*
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index f65595602aa8..7e362a6935fd 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -611,8 +611,8 @@ static int should_ignore_root(struct btrfs_root *root)
 	if (!reloc_root)
 		return 0;
 
-	if (btrfs_root_last_snapshot(&reloc_root->root_item) ==
-	    root->fs_info->running_transaction->transid - 1)
+	if (btrfs_header_generation(reloc_root->commit_root) ==
+	    root->fs_info->running_transaction->transid)
 		return 0;
 	/*
 	 * if there is reloc tree and it was created in previous
diff --git a/fs/btrfs/space-info.c b/fs/btrfs/space-info.c
index 8b0fe053a25d..ff17a4420358 100644
--- a/fs/btrfs/space-info.c
+++ b/fs/btrfs/space-info.c
@@ -361,6 +361,16 @@ int btrfs_can_overcommit(struct btrfs_fs_info *fs_info,
 	return 0;
 }
 
+static void remove_ticket(struct btrfs_space_info *space_info,
+			  struct reserve_ticket *ticket)
+{
+	if (!list_empty(&ticket->list)) {
+		list_del_init(&ticket->list);
+		ASSERT(space_info->reclaim_size >= ticket->bytes);
+		space_info->reclaim_size -= ticket->bytes;
+	}
+}
+
 /*
  * This is for space we already have accounted in space_info->bytes_may_use, so
  * basically when we're returning space from block_rsv's.
@@ -388,9 +398,7 @@ void btrfs_try_granting_tickets(struct btrfs_fs_info *fs_info,
 			btrfs_space_info_update_bytes_may_use(fs_info,
 							      space_info,
 							      ticket->bytes);
-			list_del_init(&ticket->list);
-			ASSERT(space_info->reclaim_size >= ticket->bytes);
-			space_info->reclaim_size -= ticket->bytes;
+			remove_ticket(space_info, ticket);
 			ticket->bytes = 0;
 			space_info->tickets_id++;
 			wake_up(&ticket->wait);
@@ -899,7 +907,7 @@ static bool maybe_fail_all_tickets(struct btrfs_fs_info *fs_info,
 			btrfs_info(fs_info, "failing ticket with %llu bytes",
 				   ticket->bytes);
 
-		list_del_init(&ticket->list);
+		remove_ticket(space_info, ticket);
 		ticket->error = -ENOSPC;
 		wake_up(&ticket->wait);
 
@@ -1063,7 +1071,7 @@ static void wait_reserve_ticket(struct btrfs_fs_info *fs_info,
 			 * despite getting an error, resulting in a space leak
 			 * (bytes_may_use counter of our space_info).
 			 */
-			list_del_init(&ticket->list);
+			remove_ticket(space_info, ticket);
 			ticket->error = -EINTR;
 			break;
 		}
@@ -1121,7 +1129,7 @@ static int handle_reserve_ticket(struct btrfs_fs_info *fs_info,
 		 * either the async reclaim job deletes the ticket from the list
 		 * or we delete it ourselves at wait_reserve_ticket().
 		 */
-		list_del_init(&ticket->list);
+		remove_ticket(space_info, ticket);
 		if (!ret)
 			ret = -ENOSPC;
 	}
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 58c111474ba5..ec36a7c6ba3d 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -96,8 +96,8 @@ enum {
 static int btrfs_log_inode(struct btrfs_trans_handle *trans,
 			   struct btrfs_root *root, struct btrfs_inode *inode,
 			   int inode_only,
-			   u64 start,
-			   u64 end,
+			   const loff_t start,
+			   const loff_t end,
 			   struct btrfs_log_ctx *ctx);
 static int link_to_fixup_dir(struct btrfs_trans_handle *trans,
 			     struct btrfs_root *root,
@@ -4533,15 +4533,13 @@ static int btrfs_log_all_xattrs(struct btrfs_trans_handle *trans,
 static int btrfs_log_holes(struct btrfs_trans_handle *trans,
 			   struct btrfs_root *root,
 			   struct btrfs_inode *inode,
-			   struct btrfs_path *path,
-			   const u64 start,
-			   const u64 end)
+			   struct btrfs_path *path)
 {
 	struct btrfs_fs_info *fs_info = root->fs_info;
 	struct btrfs_key key;
 	const u64 ino = btrfs_ino(inode);
 	const u64 i_size = i_size_read(&inode->vfs_inode);
-	u64 prev_extent_end = start;
+	u64 prev_extent_end = 0;
 	int ret;
 
 	if (!btrfs_fs_incompat(fs_info, NO_HOLES) || i_size == 0)
@@ -4549,21 +4547,14 @@ static int btrfs_log_holes(struct btrfs_trans_handle *trans,
 
 	key.objectid = ino;
 	key.type = BTRFS_EXTENT_DATA_KEY;
-	key.offset = start;
+	key.offset = 0;
 
 	ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
 	if (ret < 0)
 		return ret;
 
-	if (ret > 0 && path->slots[0] > 0) {
-		btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0] - 1);
-		if (key.objectid == ino && key.type == BTRFS_EXTENT_DATA_KEY)
-			path->slots[0]--;
-	}
-
 	while (true) {
 		struct extent_buffer *leaf = path->nodes[0];
-		u64 extent_end;
 
 		if (path->slots[0] >= btrfs_header_nritems(path->nodes[0])) {
 			ret = btrfs_next_leaf(root, path);
@@ -4580,18 +4571,9 @@ static int btrfs_log_holes(struct btrfs_trans_handle *trans,
 		if (key.objectid != ino || key.type != BTRFS_EXTENT_DATA_KEY)
 			break;
 
-		extent_end = btrfs_file_extent_end(path);
-		if (extent_end <= start)
-			goto next_slot;
-
 		/* We have a hole, log it. */
 		if (prev_extent_end < key.offset) {
-			u64 hole_len;
-
-			if (key.offset >= end)
-				hole_len = end - prev_extent_end;
-			else
-				hole_len = key.offset - prev_extent_end;
+			const u64 hole_len = key.offset - prev_extent_end;
 
 			/*
 			 * Release the path to avoid deadlocks with other code
@@ -4621,20 +4603,16 @@ static int btrfs_log_holes(struct btrfs_trans_handle *trans,
 			leaf = path->nodes[0];
 		}
 
-		prev_extent_end = min(extent_end, end);
-		if (extent_end >= end)
-			break;
-next_slot:
+		prev_extent_end = btrfs_file_extent_end(path);
 		path->slots[0]++;
 		cond_resched();
 	}
 
-	if (prev_extent_end < end && prev_extent_end < i_size) {
+	if (prev_extent_end < i_size) {
 		u64 hole_len;
 
 		btrfs_release_path(path);
-		hole_len = min(ALIGN(i_size, fs_info->sectorsize), end);
-		hole_len -= prev_extent_end;
+		hole_len = ALIGN(i_size - prev_extent_end, fs_info->sectorsize);
 		ret = btrfs_insert_file_extent(trans, root->log_root,
 					       ino, prev_extent_end, 0, 0,
 					       hole_len, 0, hole_len,
@@ -4971,8 +4949,6 @@ static int copy_inode_items_to_log(struct btrfs_trans_handle *trans,
 				   const u64 logged_isize,
 				   const bool recursive_logging,
 				   const int inode_only,
-				   const u64 start,
-				   const u64 end,
 				   struct btrfs_log_ctx *ctx,
 				   bool *need_log_inode_item)
 {
@@ -4981,21 +4957,6 @@ static int copy_inode_items_to_log(struct btrfs_trans_handle *trans,
 	int ins_nr = 0;
 	int ret;
 
-	/*
-	 * We must make sure we don't copy extent items that are entirely out of
-	 * the range [start, end - 1]. This is not just an optimization to avoid
-	 * copying but also needed to avoid a corruption where we end up with
-	 * file extent items in the log tree that have overlapping ranges - this
-	 * can happen if we race with ordered extent completion for ranges that
-	 * are outside our target range. For example we copy an extent item and
-	 * when we move to the next leaf, that extent was trimmed and a new one
-	 * covering a subrange of it, but with a higher key, was inserted - we
-	 * would then copy this other extent too, resulting in a log tree with
-	 * 2 extent items that represent overlapping ranges.
-	 *
-	 * We can copy the entire extents at the range bondaries however, even
-	 * if they cover an area outside the target range. That's ok.
-	 */
 	while (1) {
 		ret = btrfs_search_forward(root, min_key, path, trans->transid);
 		if (ret < 0)
@@ -5063,29 +5024,6 @@ static int copy_inode_items_to_log(struct btrfs_trans_handle *trans,
 			goto next_slot;
 		}
 
-		if (min_key->type == BTRFS_EXTENT_DATA_KEY) {
-			const u64 extent_end = btrfs_file_extent_end(path);
-
-			if (extent_end <= start) {
-				if (ins_nr > 0) {
-					ret = copy_items(trans, inode, dst_path,
-							 path, ins_start_slot,
-							 ins_nr, inode_only,
-							 logged_isize);
-					if (ret < 0)
-						return ret;
-					ins_nr = 0;
-				}
-				goto next_slot;
-			}
-			if (extent_end >= end) {
-				ins_nr++;
-				if (ins_nr == 1)
-					ins_start_slot = path->slots[0];
-				break;
-			}
-		}
-
 		if (ins_nr && ins_start_slot + ins_nr == path->slots[0]) {
 			ins_nr++;
 			goto next_slot;
@@ -5151,8 +5089,8 @@ static int copy_inode_items_to_log(struct btrfs_trans_handle *trans,
 static int btrfs_log_inode(struct btrfs_trans_handle *trans,
 			   struct btrfs_root *root, struct btrfs_inode *inode,
 			   int inode_only,
-			   u64 start,
-			   u64 end,
+			   const loff_t start,
+			   const loff_t end,
 			   struct btrfs_log_ctx *ctx)
 {
 	struct btrfs_fs_info *fs_info = root->fs_info;
@@ -5180,9 +5118,6 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
 		return -ENOMEM;
 	}
 
-	start = ALIGN_DOWN(start, fs_info->sectorsize);
-	end = ALIGN(end, fs_info->sectorsize);
-
 	min_key.objectid = ino;
 	min_key.type = BTRFS_INODE_ITEM_KEY;
 	min_key.offset = 0;
@@ -5298,8 +5233,8 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
 
 	err = copy_inode_items_to_log(trans, inode, &min_key, &max_key,
 				      path, dst_path, logged_isize,
-				      recursive_logging, inode_only,
-				      start, end, ctx, &need_log_inode_item);
+				      recursive_logging, inode_only, ctx,
+				      &need_log_inode_item);
 	if (err)
 		goto out_unlock;
 
@@ -5312,7 +5247,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
 	if (max_key.type >= BTRFS_EXTENT_DATA_KEY && !fast_search) {
 		btrfs_release_path(path);
 		btrfs_release_path(dst_path);
-		err = btrfs_log_holes(trans, root, inode, path, start, end);
+		err = btrfs_log_holes(trans, root, inode, path);
 		if (err)
 			goto out_unlock;
 	}
diff --git a/fs/buffer.c b/fs/buffer.c
index f73276d746bb..36cb5aa0ed60 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -990,10 +990,20 @@ grow_dev_page(struct block_device *bdev, sector_t block,
 			end_block = init_page_buffers(page, bdev,
 						(sector_t)index << sizebits,
 						size);
+#ifdef CONFIG_DEBUG_AID_FOR_SYZBOT
+			current->getblk_executed |= 0x01;
+#endif
 			goto done;
 		}
-		if (!try_to_free_buffers(page))
+		if (!try_to_free_buffers(page)) {
+#ifdef CONFIG_DEBUG_AID_FOR_SYZBOT
+			current->getblk_executed |= 0x02;
+#endif
 			goto failed;
+		}
+#ifdef CONFIG_DEBUG_AID_FOR_SYZBOT
+		current->getblk_executed |= 0x04;
+#endif
 	}
 
 	/*
@@ -1013,6 +1023,9 @@ grow_dev_page(struct block_device *bdev, sector_t block,
 	spin_unlock(&inode->i_mapping->private_lock);
 done:
 	ret = (block < end_block) ? 1 : -ENXIO;
+#ifdef CONFIG_DEBUG_AID_FOR_SYZBOT
+	current->getblk_executed |= 0x08;
+#endif
 failed:
 	unlock_page(page);
 	put_page(page);
@@ -1068,6 +1081,12 @@ __getblk_slow(struct block_device *bdev, sector_t block,
 		return NULL;
 	}
 
+#ifdef CONFIG_DEBUG_AID_FOR_SYZBOT
+	current->getblk_stamp = jiffies;
+	current->getblk_executed = 0;
+	current->getblk_bh_count = 0;
+	current->getblk_bh_state = 0;
+#endif
 	for (;;) {
 		struct buffer_head *bh;
 		int ret;
@@ -1079,6 +1098,24 @@ __getblk_slow(struct block_device *bdev, sector_t block,
 		ret = grow_buffers(bdev, block, size, gfp);
 		if (ret < 0)
 			return NULL;
+
+#ifdef CONFIG_DEBUG_AID_FOR_SYZBOT
+		if (!time_after(jiffies, current->getblk_stamp + 3 * HZ))
+			continue;
+		printk(KERN_ERR "%s(%u): getblk(): executed=%x bh_count=%d bh_state=%lx bdev_super_blocksize=%ld size=%u bdev_super_blocksize_bits=%d bdev_inode_blkbits=%d\n",
+		       current->comm, current->pid, current->getblk_executed,
+		       current->getblk_bh_count, current->getblk_bh_state,
+		       IS_ERR_OR_NULL(bdev->bd_super) ? -1L :
+		       bdev->bd_super->s_blocksize, size,
+		       IS_ERR_OR_NULL(bdev->bd_super) ? -1 :
+		       bdev->bd_super->s_blocksize_bits,
+		       IS_ERR_OR_NULL(bdev->bd_inode) ? -1 :
+		       bdev->bd_inode->i_blkbits);
+		current->getblk_executed = 0;
+		current->getblk_bh_count = 0;
+		current->getblk_bh_state = 0;
+		current->getblk_stamp = jiffies;
+#endif
 	}
 }
 
@@ -1371,6 +1408,17 @@ void __breadahead(struct block_device *bdev, sector_t block, unsigned size)
 }
 EXPORT_SYMBOL(__breadahead);
 
+void __breadahead_gfp(struct block_device *bdev, sector_t block, unsigned size,
+		      gfp_t gfp)
+{
+	struct buffer_head *bh = __getblk_gfp(bdev, block, size, gfp);
+	if (likely(bh)) {
+		ll_rw_block(REQ_OP_READ, REQ_RAHEAD, 1, &bh);
+		brelse(bh);
+	}
+}
+EXPORT_SYMBOL(__breadahead_gfp);
+
 /**
  *  __bread_gfp() - reads a specified block and returns the bh
  *  @bdev: the block_device to read from
@@ -3191,6 +3239,11 @@ EXPORT_SYMBOL(sync_dirty_buffer);
  */
 static inline int buffer_busy(struct buffer_head *bh)
 {
+#ifdef CONFIG_DEBUG_AID_FOR_SYZBOT
+	current->getblk_executed |= 0x80;
+	current->getblk_bh_count = atomic_read(&bh->b_count);
+	current->getblk_bh_state = bh->b_state;
+#endif
 	return atomic_read(&bh->b_count) |
 		(bh->b_state & ((1 << BH_Dirty) | (1 << BH_Lock)));
 }
@@ -3229,11 +3282,18 @@ int try_to_free_buffers(struct page *page)
 	int ret = 0;
 
 	BUG_ON(!PageLocked(page));
-	if (PageWriteback(page))
+	if (PageWriteback(page)) {
+#ifdef CONFIG_DEBUG_AID_FOR_SYZBOT
+		current->getblk_executed |= 0x10;
+#endif
 		return 0;
+	}
 
 	if (mapping == NULL) {		/* can this still happen? */
 		ret = drop_buffers(page, &buffers_to_free);
+#ifdef CONFIG_DEBUG_AID_FOR_SYZBOT
+		current->getblk_executed |= 0x20;
+#endif
 		goto out;
 	}
 
@@ -3257,6 +3317,9 @@ int try_to_free_buffers(struct page *page)
 	if (ret)
 		cancel_dirty_page(page);
 	spin_unlock(&mapping->private_lock);
+#ifdef CONFIG_DEBUG_AID_FOR_SYZBOT
+	current->getblk_executed |= 0x40;
+#endif
 out:
 	if (buffers_to_free) {
 		struct buffer_head *bh = buffers_to_free;
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
index d594c2627430..4c4202c93b71 100644
--- a/fs/ceph/dir.c
+++ b/fs/ceph/dir.c
@@ -1051,8 +1051,8 @@ static void ceph_async_unlink_cb(struct ceph_mds_client *mdsc,
 
 	/* If op failed, mark everyone involved for errors */
 	if (result) {
-		int pathlen;
-		u64 base;
+		int pathlen = 0;
+		u64 base = 0;
 		char *path = ceph_mdsc_build_path(req->r_dentry, &pathlen,
 						  &base, 0);
 
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index 4a5ccbb7e808..afdfca965a7f 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -527,8 +527,8 @@ static void ceph_async_create_cb(struct ceph_mds_client *mdsc,
 
 	if (result) {
 		struct dentry *dentry = req->r_dentry;
-		int pathlen;
-		u64 base;
+		int pathlen = 0;
+		u64 base = 0;
 		char *path = ceph_mdsc_build_path(req->r_dentry, &pathlen,
 						  &base, 0);
 
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h
index 4e5be79bf080..903d9edfd4bf 100644
--- a/fs/ceph/mds_client.h
+++ b/fs/ceph/mds_client.h
@@ -521,7 +521,7 @@ extern void ceph_mdsc_pre_umount(struct ceph_mds_client *mdsc);
 
 static inline void ceph_mdsc_free_path(char *path, int len)
 {
-	if (path)
+	if (!IS_ERR_OR_NULL(path))
 		__putname(path - (PATH_MAX - 1 - len));
 }
 
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 140efc1a9374..182b864b3075 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -594,6 +594,8 @@ decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr)
 			       cifs_max_pending);
 	set_credits(server, server->maxReq);
 	server->maxBuf = le16_to_cpu(rsp->MaxBufSize);
+	/* set up max_read for readpages check */
+	server->max_read = server->maxBuf;
 	/* even though we do not use raw we might as well set this
 	accurately, in case we ever find a need for it */
 	if ((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) {
@@ -755,6 +757,8 @@ CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
 	set_credits(server, server->maxReq);
 	/* probably no need to store and check maxvcs */
 	server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize);
+	/* set up max_read for readpages check */
+	server->max_read = server->maxBuf;
 	server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
 	cifs_dbg(NOISY, "Max buf = %d\n", ses->server->maxBuf);
 	server->capabilities = le32_to_cpu(pSMBr->Capabilities);
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 8fbbdcdad8ff..390d2b15ef6e 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -61,7 +61,7 @@ static void cifs_set_ops(struct inode *inode)
 		}
 
 		/* check if server can support readpages */
-		if (cifs_sb_master_tcon(cifs_sb)->ses->server->maxBuf <
+		if (cifs_sb_master_tcon(cifs_sb)->ses->server->max_read <
 				PAGE_SIZE + MAX_CIFS_HDR_SIZE)
 			inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
 		else
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index 47d3e382ecaa..b30aa3cdd845 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -1552,6 +1552,21 @@ SMB2_sess_auth_rawntlmssp_authenticate(struct SMB2_sess_data *sess_data)
 	}
 
 	rc = SMB2_sess_establish_session(sess_data);
+#ifdef CONFIG_CIFS_DEBUG_DUMP_KEYS
+	if (ses->server->dialect < SMB30_PROT_ID) {
+		cifs_dbg(VFS, "%s: dumping generated SMB2 session keys\n", __func__);
+		/*
+		 * The session id is opaque in terms of endianness, so we can't
+		 * print it as a long long. we dump it as we got it on the wire
+		 */
+		cifs_dbg(VFS, "Session Id    %*ph\n", (int)sizeof(ses->Suid),
+			 &ses->Suid);
+		cifs_dbg(VFS, "Session Key   %*ph\n",
+			 SMB2_NTLMV2_SESSKEY_SIZE, ses->auth_key.response);
+		cifs_dbg(VFS, "Signing Key   %*ph\n",
+			 SMB3_SIGN_KEY_SIZE, ses->auth_key.response);
+	}
+#endif
 out:
 	kfree(ntlmssp_blob);
 	SMB2_sess_free_buffer(sess_data);
diff --git a/fs/cifs/smb2transport.c b/fs/cifs/smb2transport.c
index 1a6c227ada8f..c0348e3b1695 100644
--- a/fs/cifs/smb2transport.c
+++ b/fs/cifs/smb2transport.c
@@ -660,8 +660,8 @@ smb2_verify_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
 		return rc;
 
 	if (memcmp(server_response_sig, shdr->Signature, SMB2_SIGNATURE_SIZE)) {
-		dump_stack();
-		cifs_dbg(VFS, "sign fail cmd 0x%x message id 0x%llx\n", shdr->Command, shdr->MessageId);
+		cifs_dbg(VFS, "sign fail cmd 0x%x message id 0x%llx\n",
+			shdr->Command, shdr->MessageId);
 		return -EACCES;
 	} else
 		return 0;
diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h
index 5eead7fdc7a6..1c077b7bb43d 100644
--- a/fs/erofs/internal.h
+++ b/fs/erofs/internal.h
@@ -46,6 +46,17 @@ typedef u64 erofs_off_t;
 /* data type for filesystem-wide blocks number */
 typedef u32 erofs_blk_t;
 
+struct erofs_fs_context {
+#ifdef CONFIG_EROFS_FS_ZIP
+	/* current strategy of how to use managed cache */
+	unsigned char cache_strategy;
+
+	/* threshold for decompression synchronously */
+	unsigned int max_sync_decompress_pages;
+#endif
+	unsigned int mount_opt;
+};
+
 struct erofs_sb_info {
 #ifdef CONFIG_EROFS_FS_ZIP
 	/* list for all registered superblocks, mainly for shrinker */
@@ -55,14 +66,8 @@ struct erofs_sb_info {
 	/* managed XArray arranged in physical block number */
 	struct xarray managed_pslots;
 
-	/* threshold for decompression synchronously */
-	unsigned int max_sync_decompress_pages;
-
 	unsigned int shrinker_run_no;
 
-	/* current strategy of how to use managed cache */
-	unsigned char cache_strategy;
-
 	/* pseudo inode to manage cached pages */
 	struct inode *managed_cache;
 #endif	/* CONFIG_EROFS_FS_ZIP */
@@ -88,7 +93,7 @@ struct erofs_sb_info {
 	u32 feature_compat;
 	u32 feature_incompat;
 
-	unsigned int mount_opt;
+	struct erofs_fs_context ctx;	/* options */
 };
 
 #define EROFS_SB(sb) ((struct erofs_sb_info *)(sb)->s_fs_info)
@@ -98,17 +103,17 @@ struct erofs_sb_info {
 #define EROFS_MOUNT_XATTR_USER		0x00000010
 #define EROFS_MOUNT_POSIX_ACL		0x00000020
 
-#define clear_opt(sbi, option)	((sbi)->mount_opt &= ~EROFS_MOUNT_##option)
-#define set_opt(sbi, option)	((sbi)->mount_opt |= EROFS_MOUNT_##option)
-#define test_opt(sbi, option)	((sbi)->mount_opt & EROFS_MOUNT_##option)
+#define clear_opt(ctx, option)	((ctx)->mount_opt &= ~EROFS_MOUNT_##option)
+#define set_opt(ctx, option)	((ctx)->mount_opt |= EROFS_MOUNT_##option)
+#define test_opt(ctx, option)	((ctx)->mount_opt & EROFS_MOUNT_##option)
 
-#ifdef CONFIG_EROFS_FS_ZIP
 enum {
 	EROFS_ZIP_CACHE_DISABLED,
 	EROFS_ZIP_CACHE_READAHEAD,
 	EROFS_ZIP_CACHE_READAROUND
 };
 
+#ifdef CONFIG_EROFS_FS_ZIP
 #define EROFS_LOCKED_MAGIC     (INT_MIN | 0xE0F510CCL)
 
 /* basic unit of the workstation of a super_block */
diff --git a/fs/erofs/super.c b/fs/erofs/super.c
index b514c67e5fc2..2c0bad903fa6 100644
--- a/fs/erofs/super.c
+++ b/fs/erofs/super.c
@@ -10,6 +10,8 @@
 #include <linux/parser.h>
 #include <linux/seq_file.h>
 #include <linux/crc32c.h>
+#include <linux/fs_context.h>
+#include <linux/fs_parser.h>
 #include "xattr.h"
 
 #define CREATE_TRACE_POINTS
@@ -192,53 +194,18 @@ static int erofs_read_superblock(struct super_block *sb)
 	return ret;
 }
 
-#ifdef CONFIG_EROFS_FS_ZIP
-static int erofs_build_cache_strategy(struct super_block *sb,
-				      substring_t *args)
-{
-	struct erofs_sb_info *sbi = EROFS_SB(sb);
-	const char *cs = match_strdup(args);
-	int err = 0;
-
-	if (!cs) {
-		erofs_err(sb, "Not enough memory to store cache strategy");
-		return -ENOMEM;
-	}
-
-	if (!strcmp(cs, "disabled")) {
-		sbi->cache_strategy = EROFS_ZIP_CACHE_DISABLED;
-	} else if (!strcmp(cs, "readahead")) {
-		sbi->cache_strategy = EROFS_ZIP_CACHE_READAHEAD;
-	} else if (!strcmp(cs, "readaround")) {
-		sbi->cache_strategy = EROFS_ZIP_CACHE_READAROUND;
-	} else {
-		erofs_err(sb, "Unrecognized cache strategy \"%s\"", cs);
-		err = -EINVAL;
-	}
-	kfree(cs);
-	return err;
-}
-#else
-static int erofs_build_cache_strategy(struct super_block *sb,
-				      substring_t *args)
-{
-	erofs_info(sb, "EROFS compression is disabled, so cache strategy is ignored");
-	return 0;
-}
-#endif
-
 /* set up default EROFS parameters */
-static void erofs_default_options(struct erofs_sb_info *sbi)
+static void erofs_default_options(struct erofs_fs_context *ctx)
 {
 #ifdef CONFIG_EROFS_FS_ZIP
-	sbi->cache_strategy = EROFS_ZIP_CACHE_READAROUND;
-	sbi->max_sync_decompress_pages = 3;
+	ctx->cache_strategy = EROFS_ZIP_CACHE_READAROUND;
+	ctx->max_sync_decompress_pages = 3;
 #endif
 #ifdef CONFIG_EROFS_FS_XATTR
-	set_opt(sbi, XATTR_USER);
+	set_opt(ctx, XATTR_USER);
 #endif
 #ifdef CONFIG_EROFS_FS_POSIX_ACL
-	set_opt(sbi, POSIX_ACL);
+	set_opt(ctx, POSIX_ACL);
 #endif
 }
 
@@ -251,73 +218,62 @@ enum {
 	Opt_err
 };
 
-static match_table_t erofs_tokens = {
-	{Opt_user_xattr, "user_xattr"},
-	{Opt_nouser_xattr, "nouser_xattr"},
-	{Opt_acl, "acl"},
-	{Opt_noacl, "noacl"},
-	{Opt_cache_strategy, "cache_strategy=%s"},
-	{Opt_err, NULL}
+static const struct constant_table erofs_param_cache_strategy[] = {
+	{"disabled",	EROFS_ZIP_CACHE_DISABLED},
+	{"readahead",	EROFS_ZIP_CACHE_READAHEAD},
+	{"readaround",	EROFS_ZIP_CACHE_READAROUND},
+	{}
 };
 
-static int erofs_parse_options(struct super_block *sb, char *options)
-{
-	substring_t args[MAX_OPT_ARGS];
-	char *p;
-	int err;
-
-	if (!options)
-		return 0;
-
-	while ((p = strsep(&options, ","))) {
-		int token;
+static const struct fs_parameter_spec erofs_fs_parameters[] = {
+	fsparam_flag_no("user_xattr",	Opt_user_xattr),
+	fsparam_flag_no("acl",		Opt_acl),
+	fsparam_enum("cache_strategy",	Opt_cache_strategy,
+		     erofs_param_cache_strategy),
+	{}
+};
 
-		if (!*p)
-			continue;
+static int erofs_fc_parse_param(struct fs_context *fc,
+				struct fs_parameter *param)
+{
+	struct erofs_fs_context *ctx __maybe_unused = fc->fs_private;
+	struct fs_parse_result result;
+	int opt;
 
-		args[0].to = args[0].from = NULL;
-		token = match_token(p, erofs_tokens, args);
+	opt = fs_parse(fc, erofs_fs_parameters, param, &result);
+	if (opt < 0)
+		return opt;
 
-		switch (token) {
+	switch (opt) {
+	case Opt_user_xattr:
 #ifdef CONFIG_EROFS_FS_XATTR
-		case Opt_user_xattr:
-			set_opt(EROFS_SB(sb), XATTR_USER);
-			break;
-		case Opt_nouser_xattr:
-			clear_opt(EROFS_SB(sb), XATTR_USER);
-			break;
+		if (result.boolean)
+			set_opt(ctx, XATTR_USER);
+		else
+			clear_opt(ctx, XATTR_USER);
 #else
-		case Opt_user_xattr:
-			erofs_info(sb, "user_xattr options not supported");
-			break;
-		case Opt_nouser_xattr:
-			erofs_info(sb, "nouser_xattr options not supported");
-			break;
+		errorfc(fc, "{,no}user_xattr options not supported");
 #endif
+		break;
+	case Opt_acl:
 #ifdef CONFIG_EROFS_FS_POSIX_ACL
-		case Opt_acl:
-			set_opt(EROFS_SB(sb), POSIX_ACL);
-			break;
-		case Opt_noacl:
-			clear_opt(EROFS_SB(sb), POSIX_ACL);
-			break;
+		if (result.boolean)
+			set_opt(ctx, POSIX_ACL);
+		else
+			clear_opt(ctx, POSIX_ACL);
 #else
-		case Opt_acl:
-			erofs_info(sb, "acl options not supported");
-			break;
-		case Opt_noacl:
-			erofs_info(sb, "noacl options not supported");
-			break;
+		errorfc(fc, "{,no}acl options not supported");
 #endif
-		case Opt_cache_strategy:
-			err = erofs_build_cache_strategy(sb, args);
-			if (err)
-				return err;
-			break;
-		default:
-			erofs_err(sb, "Unrecognized mount option \"%s\" or missing value", p);
-			return -EINVAL;
-		}
+		break;
+	case Opt_cache_strategy:
+#ifdef CONFIG_EROFS_FS_ZIP
+		ctx->cache_strategy = result.uint_32;
+#else
+		errorfc(fc, "compression not supported, cache_strategy ignored");
+#endif
+		break;
+	default:
+		return -ENOPARAM;
 	}
 	return 0;
 }
@@ -381,10 +337,11 @@ static int erofs_init_managed_cache(struct super_block *sb)
 static int erofs_init_managed_cache(struct super_block *sb) { return 0; }
 #endif
 
-static int erofs_fill_super(struct super_block *sb, void *data, int silent)
+static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc)
 {
 	struct inode *inode;
 	struct erofs_sb_info *sbi;
+	struct erofs_fs_context *ctx = fc->fs_private;
 	int err;
 
 	sb->s_magic = EROFS_SUPER_MAGIC;
@@ -412,18 +369,14 @@ static int erofs_fill_super(struct super_block *sb, void *data, int silent)
 #ifdef CONFIG_EROFS_FS_XATTR
 	sb->s_xattr = erofs_xattr_handlers;
 #endif
-	/* set erofs default mount options */
-	erofs_default_options(sbi);
 
-	err = erofs_parse_options(sb, data);
-	if (err)
-		return err;
-
-	if (test_opt(sbi, POSIX_ACL))
+	if (test_opt(ctx, POSIX_ACL))
 		sb->s_flags |= SB_POSIXACL;
 	else
 		sb->s_flags &= ~SB_POSIXACL;
 
+	sbi->ctx = *ctx;
+
 #ifdef CONFIG_EROFS_FS_ZIP
 	xa_init(&sbi->managed_pslots);
 #endif
@@ -450,15 +403,58 @@ static int erofs_fill_super(struct super_block *sb, void *data, int silent)
 	if (err)
 		return err;
 
-	erofs_info(sb, "mounted with opts: %s, root inode @ nid %llu.",
-		   (char *)data, ROOT_NID(sbi));
+	erofs_info(sb, "mounted with root inode @ nid %llu.", ROOT_NID(sbi));
+	return 0;
+}
+
+static int erofs_fc_get_tree(struct fs_context *fc)
+{
+	return get_tree_bdev(fc, erofs_fc_fill_super);
+}
+
+static int erofs_fc_reconfigure(struct fs_context *fc)
+{
+	struct super_block *sb = fc->root->d_sb;
+	struct erofs_sb_info *sbi = EROFS_SB(sb);
+	struct erofs_fs_context *ctx = fc->fs_private;
+
+	DBG_BUGON(!sb_rdonly(sb));
+
+	if (test_opt(ctx, POSIX_ACL))
+		fc->sb_flags |= SB_POSIXACL;
+	else
+		fc->sb_flags &= ~SB_POSIXACL;
+
+	sbi->ctx = *ctx;
+
+	fc->sb_flags |= SB_RDONLY;
 	return 0;
 }
 
-static struct dentry *erofs_mount(struct file_system_type *fs_type, int flags,
-				  const char *dev_name, void *data)
+static void erofs_fc_free(struct fs_context *fc)
+{
+	kfree(fc->fs_private);
+}
+
+static const struct fs_context_operations erofs_context_ops = {
+	.parse_param	= erofs_fc_parse_param,
+	.get_tree       = erofs_fc_get_tree,
+	.reconfigure    = erofs_fc_reconfigure,
+	.free		= erofs_fc_free,
+};
+
+static int erofs_init_fs_context(struct fs_context *fc)
 {
-	return mount_bdev(fs_type, flags, dev_name, data, erofs_fill_super);
+	fc->fs_private = kzalloc(sizeof(struct erofs_fs_context), GFP_KERNEL);
+	if (!fc->fs_private)
+		return -ENOMEM;
+
+	/* set default mount options */
+	erofs_default_options(fc->fs_private);
+
+	fc->ops = &erofs_context_ops;
+
+	return 0;
 }
 
 /*
@@ -497,7 +493,7 @@ static void erofs_put_super(struct super_block *sb)
 static struct file_system_type erofs_fs_type = {
 	.owner          = THIS_MODULE,
 	.name           = "erofs",
-	.mount          = erofs_mount,
+	.init_fs_context = erofs_init_fs_context,
 	.kill_sb        = erofs_kill_sb,
 	.fs_flags       = FS_REQUIRES_DEV,
 };
@@ -578,61 +574,38 @@ static int erofs_statfs(struct dentry *dentry, struct kstatfs *buf)
 static int erofs_show_options(struct seq_file *seq, struct dentry *root)
 {
 	struct erofs_sb_info *sbi __maybe_unused = EROFS_SB(root->d_sb);
+	struct erofs_fs_context *ctx __maybe_unused = &sbi->ctx;
 
 #ifdef CONFIG_EROFS_FS_XATTR
-	if (test_opt(sbi, XATTR_USER))
+	if (test_opt(ctx, XATTR_USER))
 		seq_puts(seq, ",user_xattr");
 	else
 		seq_puts(seq, ",nouser_xattr");
 #endif
 #ifdef CONFIG_EROFS_FS_POSIX_ACL
-	if (test_opt(sbi, POSIX_ACL))
+	if (test_opt(ctx, POSIX_ACL))
 		seq_puts(seq, ",acl");
 	else
 		seq_puts(seq, ",noacl");
 #endif
 #ifdef CONFIG_EROFS_FS_ZIP
-	if (sbi->cache_strategy == EROFS_ZIP_CACHE_DISABLED) {
+	if (ctx->cache_strategy == EROFS_ZIP_CACHE_DISABLED) {
 		seq_puts(seq, ",cache_strategy=disabled");
-	} else if (sbi->cache_strategy == EROFS_ZIP_CACHE_READAHEAD) {
+	} else if (ctx->cache_strategy == EROFS_ZIP_CACHE_READAHEAD) {
 		seq_puts(seq, ",cache_strategy=readahead");
-	} else if (sbi->cache_strategy == EROFS_ZIP_CACHE_READAROUND) {
+	} else if (ctx->cache_strategy == EROFS_ZIP_CACHE_READAROUND) {
 		seq_puts(seq, ",cache_strategy=readaround");
 	}
 #endif
 	return 0;
 }
 
-static int erofs_remount(struct super_block *sb, int *flags, char *data)
-{
-	struct erofs_sb_info *sbi = EROFS_SB(sb);
-	unsigned int org_mnt_opt = sbi->mount_opt;
-	int err;
-
-	DBG_BUGON(!sb_rdonly(sb));
-	err = erofs_parse_options(sb, data);
-	if (err)
-		goto out;
-
-	if (test_opt(sbi, POSIX_ACL))
-		sb->s_flags |= SB_POSIXACL;
-	else
-		sb->s_flags &= ~SB_POSIXACL;
-
-	*flags |= SB_RDONLY;
-	return 0;
-out:
-	sbi->mount_opt = org_mnt_opt;
-	return err;
-}
-
 const struct super_operations erofs_sops = {
 	.put_super = erofs_put_super,
 	.alloc_inode = erofs_alloc_inode,
 	.free_inode = erofs_free_inode,
 	.statfs = erofs_statfs,
 	.show_options = erofs_show_options,
-	.remount_fs = erofs_remount,
 };
 
 module_init(erofs_module_init);
diff --git a/fs/erofs/xattr.c b/fs/erofs/xattr.c
index b766c3ee5fa8..87e437e7b34f 100644
--- a/fs/erofs/xattr.c
+++ b/fs/erofs/xattr.c
@@ -422,7 +422,7 @@ static int shared_getxattr(struct inode *inode, struct getxattr_iter *it)
 
 static bool erofs_xattr_user_list(struct dentry *dentry)
 {
-	return test_opt(EROFS_SB(dentry->d_sb), XATTR_USER);
+	return test_opt(&EROFS_SB(dentry->d_sb)->ctx, XATTR_USER);
 }
 
 static bool erofs_xattr_trusted_list(struct dentry *dentry)
@@ -469,7 +469,7 @@ static int erofs_xattr_generic_get(const struct xattr_handler *handler,
 
 	switch (handler->flags) {
 	case EROFS_XATTR_INDEX_USER:
-		if (!test_opt(sbi, XATTR_USER))
+		if (!test_opt(&sbi->ctx, XATTR_USER))
 			return -EOPNOTSUPP;
 		break;
 	case EROFS_XATTR_INDEX_TRUSTED:
diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c
index c4b6c9aa87ec..5086b1218aac 100644
--- a/fs/erofs/zdata.c
+++ b/fs/erofs/zdata.c
@@ -615,7 +615,7 @@ static int z_erofs_do_read_page(struct z_erofs_decompress_frontend *fe,
 		goto err_out;
 
 	/* preload all compressed pages (maybe downgrade role if necessary) */
-	if (should_alloc_managed_pages(fe, sbi->cache_strategy, map->m_la))
+	if (should_alloc_managed_pages(fe, sbi->ctx.cache_strategy, map->m_la))
 		cache_strategy = DELAYEDALLOC;
 	else
 		cache_strategy = DONTALLOC;
@@ -1302,7 +1302,7 @@ static int z_erofs_readpage(struct file *file, struct page *page)
 static bool should_decompress_synchronously(struct erofs_sb_info *sbi,
 					    unsigned int nr)
 {
-	return nr <= sbi->max_sync_decompress_pages;
+	return nr <= sbi->ctx.max_sync_decompress_pages;
 }
 
 static int z_erofs_readpages(struct file *filp, struct address_space *mapping,
diff --git a/fs/exec.c b/fs/exec.c
index 06b4c550af5d..a10e3941196d 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1817,11 +1817,17 @@ static int __do_execve_file(int fd, struct filename *filename,
 	check_unsafe_exec(bprm);
 	current->in_execve = 1;
 
-	if (!file)
+	if (!file) {
 		file = do_open_execat(fd, filename, flags);
-	retval = PTR_ERR(file);
-	if (IS_ERR(file))
-		goto out_unmark;
+		retval = PTR_ERR(file);
+		if (IS_ERR(file))
+			goto out_unmark;
+	} else {
+		retval = deny_write_access(file);
+		if (retval)
+			goto out_unmark;
+		get_file(file);
+	}
 
 	sched_exec();
 
diff --git a/fs/exfat/Kconfig b/fs/exfat/Kconfig
index 2d3636dc5b8c..5a65071b5ecf 100644
--- a/fs/exfat/Kconfig
+++ b/fs/exfat/Kconfig
@@ -16,6 +16,7 @@ config EXFAT_DEFAULT_IOCHARSET
 	depends on EXFAT_FS
 	help
 	  Set this to the default input/output character set to use for
-	  converting between the encoding is used for user visible filename and
-	  UTF-16 character that exfat filesystem use, and can be overridden with
-	  the "iocharset" mount option for exFAT filesystems.
+	  converting between the encoding that is used for user visible
+	  filenames and the UTF-16 character encoding that the exFAT
+	  filesystem uses.  This can be overridden with the "iocharset" mount
+	  option for the exFAT filesystems.
diff --git a/fs/exfat/balloc.c b/fs/exfat/balloc.c
index 6a04cc02565a..4055eb00ea9b 100644
--- a/fs/exfat/balloc.c
+++ b/fs/exfat/balloc.c
@@ -58,9 +58,8 @@ static int exfat_allocate_bitmap(struct super_block *sb,
 	need_map_size = ((EXFAT_DATA_CLUSTER_COUNT(sbi) - 1) / BITS_PER_BYTE)
 		+ 1;
 	if (need_map_size != map_size) {
-		exfat_msg(sb, KERN_ERR,
-				"bogus allocation bitmap size(need : %u, cur : %lld)",
-				need_map_size, map_size);
+		exfat_err(sb, "bogus allocation bitmap size(need : %u, cur : %lld)",
+			  need_map_size, map_size);
 		/*
 		 * Only allowed when bogus allocation
 		 * bitmap size is large
@@ -91,7 +90,6 @@ static int exfat_allocate_bitmap(struct super_block *sb,
 		}
 	}
 
-	sbi->pbr_bh = NULL;
 	return 0;
 }
 
@@ -137,8 +135,6 @@ void exfat_free_bitmap(struct exfat_sb_info *sbi)
 {
 	int i;
 
-	brelse(sbi->pbr_bh);
-
 	for (i = 0; i < sbi->map_sectors; i++)
 		__brelse(sbi->vol_amap[i]);
 
@@ -195,8 +191,7 @@ void exfat_clear_bitmap(struct inode *inode, unsigned int clu)
 			(1 << sbi->sect_per_clus_bits), GFP_NOFS, 0);
 
 		if (ret_discard == -EOPNOTSUPP) {
-			exfat_msg(sb, KERN_ERR,
-				"discard not supported by device, disabling");
+			exfat_err(sb, "discard not supported by device, disabling");
 			opts->discard = 0;
 		}
 	}
diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c
index 4b91afb0f051..53ae965da7ec 100644
--- a/fs/exfat/dir.c
+++ b/fs/exfat/dir.c
@@ -720,9 +720,8 @@ static int exfat_dir_readahead(struct super_block *sb, sector_t sec)
 		return 0;
 
 	if (sec < sbi->data_start_sector) {
-		exfat_msg(sb, KERN_ERR,
-			"requested sector is invalid(sect:%llu, root:%llu)",
-			(unsigned long long)sec, sbi->data_start_sector);
+		exfat_err(sb, "requested sector is invalid(sect:%llu, root:%llu)",
+			  (unsigned long long)sec, sbi->data_start_sector);
 		return -EIO;
 	}
 
@@ -750,7 +749,7 @@ struct exfat_dentry *exfat_get_dentry(struct super_block *sb,
 	sector_t sec;
 
 	if (p_dir->dir == DIR_DELETED) {
-		exfat_msg(sb, KERN_ERR, "abnormal access to deleted dentry\n");
+		exfat_err(sb, "abnormal access to deleted dentry");
 		return NULL;
 	}
 
@@ -853,7 +852,7 @@ struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb,
 	struct buffer_head *bh;
 
 	if (p_dir->dir == DIR_DELETED) {
-		exfat_msg(sb, KERN_ERR, "access to deleted dentry\n");
+		exfat_err(sb, "access to deleted dentry");
 		return NULL;
 	}
 
diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h
index 67d4e46fb810..4ced4c0d9ad9 100644
--- a/fs/exfat/exfat_fs.h
+++ b/fs/exfat/exfat_fs.h
@@ -492,8 +492,6 @@ int exfat_nls_to_utf16(struct super_block *sb,
 		struct exfat_uni_name *uniname, int *p_lossy);
 int exfat_create_upcase_table(struct super_block *sb);
 void exfat_free_upcase_table(struct exfat_sb_info *sbi);
-unsigned short exfat_high_surrogate(unicode_t u);
-unsigned short exfat_low_surrogate(unicode_t u);
 
 /* exfat/misc.c */
 void __exfat_fs_error(struct super_block *sb, int report, const char *fmt, ...)
@@ -505,6 +503,13 @@ void __exfat_fs_error(struct super_block *sb, int report, const char *fmt, ...)
 		fmt, ## args)
 void exfat_msg(struct super_block *sb, const char *lv, const char *fmt, ...)
 		__printf(3, 4) __cold;
+#define exfat_err(sb, fmt, ...)						\
+	exfat_msg(sb, KERN_ERR, fmt, ##__VA_ARGS__)
+#define exfat_warn(sb, fmt, ...)					\
+	exfat_msg(sb, KERN_WARNING, fmt, ##__VA_ARGS__)
+#define exfat_info(sb, fmt, ...)					\
+	exfat_msg(sb, KERN_INFO, fmt, ##__VA_ARGS__)
+
 void exfat_get_entry_time(struct exfat_sb_info *sbi, struct timespec64 *ts,
 		u8 tz, __le16 time, __le16 date, u8 time_ms);
 void exfat_set_entry_time(struct exfat_sb_info *sbi, struct timespec64 *ts,
diff --git a/fs/exfat/fatent.c b/fs/exfat/fatent.c
index a855b1769a96..267e5e09eb13 100644
--- a/fs/exfat/fatent.c
+++ b/fs/exfat/fatent.c
@@ -170,8 +170,7 @@ int exfat_free_cluster(struct inode *inode, struct exfat_chain *p_chain)
 
 	/* check cluster validation */
 	if (p_chain->dir < 2 && p_chain->dir >= sbi->num_clusters) {
-		exfat_msg(sb, KERN_ERR, "invalid start cluster (%u)",
-				p_chain->dir);
+		exfat_err(sb, "invalid start cluster (%u)", p_chain->dir);
 		return -EIO;
 	}
 
@@ -305,8 +304,7 @@ int exfat_zeroed_cluster(struct inode *dir, unsigned int clu)
 	return 0;
 
 release_bhs:
-	exfat_msg(sb, KERN_ERR, "failed zeroed sect %llu\n",
-		(unsigned long long)blknr);
+	exfat_err(sb, "failed zeroed sect %llu\n", (unsigned long long)blknr);
 	for (i = 0; i < n; i++)
 		bforget(bhs[i]);
 	return err;
@@ -337,9 +335,8 @@ int exfat_alloc_cluster(struct inode *inode, unsigned int num_alloc,
 	/* find new cluster */
 	if (hint_clu == EXFAT_EOF_CLUSTER) {
 		if (sbi->clu_srch_ptr < EXFAT_FIRST_CLUSTER) {
-			exfat_msg(sb, KERN_ERR,
-				"sbi->clu_srch_ptr is invalid (%u)\n",
-				sbi->clu_srch_ptr);
+			exfat_err(sb, "sbi->clu_srch_ptr is invalid (%u)\n",
+				  sbi->clu_srch_ptr);
 			sbi->clu_srch_ptr = EXFAT_FIRST_CLUSTER;
 		}
 
@@ -350,7 +347,7 @@ int exfat_alloc_cluster(struct inode *inode, unsigned int num_alloc,
 
 	/* check cluster validation */
 	if (hint_clu < EXFAT_FIRST_CLUSTER && hint_clu >= sbi->num_clusters) {
-		exfat_msg(sb, KERN_ERR, "hint_cluster is invalid (%u)\n",
+		exfat_err(sb, "hint_cluster is invalid (%u)",
 			hint_clu);
 		hint_clu = EXFAT_FIRST_CLUSTER;
 		if (p_chain->flags == ALLOC_NO_FAT_CHAIN) {
diff --git a/fs/exfat/misc.c b/fs/exfat/misc.c
index 14a3300848f6..d32beb172e2a 100644
--- a/fs/exfat/misc.c
+++ b/fs/exfat/misc.c
@@ -32,7 +32,7 @@ void __exfat_fs_error(struct super_block *sb, int report, const char *fmt, ...)
 		va_start(args, fmt);
 		vaf.fmt = fmt;
 		vaf.va = &args;
-		exfat_msg(sb, KERN_ERR, "error, %pV\n", &vaf);
+		exfat_err(sb, "error, %pV", &vaf);
 		va_end(args);
 	}
 
@@ -41,7 +41,7 @@ void __exfat_fs_error(struct super_block *sb, int report, const char *fmt, ...)
 			sb->s_id);
 	} else if (opts->errors == EXFAT_ERRORS_RO && !sb_rdonly(sb)) {
 		sb->s_flags |= SB_RDONLY;
-		exfat_msg(sb, KERN_ERR, "Filesystem has been set read-only");
+		exfat_err(sb, "Filesystem has been set read-only");
 	}
 }
 
diff --git a/fs/exfat/namei.c b/fs/exfat/namei.c
index a8681d91f569..549274fef9ac 100644
--- a/fs/exfat/namei.c
+++ b/fs/exfat/namei.c
@@ -147,16 +147,10 @@ static int exfat_utf8_d_hash(const struct dentry *dentry, struct qstr *qstr)
 			return charlen;
 
 		/*
-		 * Convert to UTF-16: code points above U+FFFF are encoded as
-		 * surrogate pairs.
 		 * exfat_toupper() works only for code points up to the U+FFFF.
 		 */
-		if (u > 0xFFFF) {
-			hash = partial_name_hash(exfat_high_surrogate(u), hash);
-			hash = partial_name_hash(exfat_low_surrogate(u), hash);
-		} else {
-			hash = partial_name_hash(exfat_toupper(sb, u), hash);
-		}
+		hash = partial_name_hash(u <= 0xFFFF ? exfat_toupper(sb, u) : u,
+					 hash);
 	}
 
 	qstr->hash = end_name_hash(hash);
@@ -185,14 +179,9 @@ static int exfat_utf8_d_cmp(const struct dentry *dentry, unsigned int len,
 		if (u_a <= 0xFFFF && u_b <= 0xFFFF) {
 			if (exfat_toupper(sb, u_a) != exfat_toupper(sb, u_b))
 				return 1;
-		} else if (u_a > 0xFFFF && u_b > 0xFFFF) {
-			if (exfat_low_surrogate(u_a) !=
-					exfat_low_surrogate(u_b) ||
-			    exfat_high_surrogate(u_a) !=
-					exfat_high_surrogate(u_b))
-				return 1;
 		} else {
-			return 1;
+			if (u_a != u_b)
+				return 1;
 		}
 	}
 
@@ -776,8 +765,8 @@ static struct dentry *exfat_lookup(struct inode *dir, struct dentry *dentry,
 		if (d_unhashed(alias)) {
 			WARN_ON(alias->d_name.hash_len !=
 				dentry->d_name.hash_len);
-			exfat_msg(sb, KERN_INFO,
-				"rehashed a dentry(%p) in read lookup", alias);
+			exfat_info(sb, "rehashed a dentry(%p) in read lookup",
+				   alias);
 			d_drop(dentry);
 			d_rehash(alias);
 		} else if (!S_ISDIR(i_mode)) {
@@ -822,7 +811,7 @@ static int exfat_unlink(struct inode *dir, struct dentry *dentry)
 	exfat_chain_dup(&cdir, &ei->dir);
 	entry = ei->entry;
 	if (ei->dir.dir == DIR_DELETED) {
-		exfat_msg(sb, KERN_ERR, "abnormal access to deleted dentry");
+		exfat_err(sb, "abnormal access to deleted dentry");
 		err = -ENOENT;
 		goto unlock;
 	}
@@ -974,7 +963,7 @@ static int exfat_rmdir(struct inode *dir, struct dentry *dentry)
 	entry = ei->entry;
 
 	if (ei->dir.dir == DIR_DELETED) {
-		exfat_msg(sb, KERN_ERR, "abnormal access to deleted dentry");
+		exfat_err(sb, "abnormal access to deleted dentry");
 		err = -ENOENT;
 		goto unlock;
 	}
@@ -986,9 +975,8 @@ static int exfat_rmdir(struct inode *dir, struct dentry *dentry)
 	err = exfat_check_dir_empty(sb, &clu_to_free);
 	if (err) {
 		if (err == -EIO)
-			exfat_msg(sb, KERN_ERR,
-				"failed to exfat_check_dir_empty : err(%d)",
-				err);
+			exfat_err(sb, "failed to exfat_check_dir_empty : err(%d)",
+				  err);
 		goto unlock;
 	}
 
@@ -1009,9 +997,7 @@ static int exfat_rmdir(struct inode *dir, struct dentry *dentry)
 
 	err = exfat_remove_entries(dir, &cdir, entry, 0, num_entries);
 	if (err) {
-		exfat_msg(sb, KERN_ERR,
-				"failed to exfat_remove_entries : err(%d)",
-				err);
+		exfat_err(sb, "failed to exfat_remove_entries : err(%d)", err);
 		goto unlock;
 	}
 	ei->dir.dir = DIR_DELETED;
@@ -1238,8 +1224,7 @@ static int __exfat_rename(struct inode *old_parent_inode,
 		return -EINVAL;
 
 	if (ei->dir.dir == DIR_DELETED) {
-		exfat_msg(sb, KERN_ERR,
-				"abnormal access to deleted source dentry");
+		exfat_err(sb, "abnormal access to deleted source dentry");
 		return -ENOENT;
 	}
 
@@ -1261,8 +1246,7 @@ static int __exfat_rename(struct inode *old_parent_inode,
 		new_ei = EXFAT_I(new_inode);
 
 		if (new_ei->dir.dir == DIR_DELETED) {
-			exfat_msg(sb, KERN_ERR,
-				"abnormal access to deleted target dentry");
+			exfat_err(sb, "abnormal access to deleted target dentry");
 			goto out;
 		}
 
@@ -1423,8 +1407,7 @@ static int exfat_rename(struct inode *old_dir, struct dentry *old_dentry,
 			if (S_ISDIR(new_inode->i_mode))
 				drop_nlink(new_inode);
 		} else {
-			exfat_msg(sb, KERN_WARNING,
-					"abnormal access to an inode dropped");
+			exfat_warn(sb, "abnormal access to an inode dropped");
 			WARN_ON(new_inode->i_nlink == 0);
 		}
 		new_inode->i_ctime = EXFAT_I(new_inode)->i_crtime =
diff --git a/fs/exfat/nls.c b/fs/exfat/nls.c
index 6d1c3ae130ff..1ebda90cbdd7 100644
--- a/fs/exfat/nls.c
+++ b/fs/exfat/nls.c
@@ -503,16 +503,14 @@ static int exfat_utf8_to_utf16(struct super_block *sb,
 	unilen = utf8s_to_utf16s(p_cstring, len, UTF16_HOST_ENDIAN,
 			(wchar_t *)uniname, MAX_NAME_LENGTH + 2);
 	if (unilen < 0) {
-		exfat_msg(sb, KERN_ERR,
-			"failed to %s (err : %d) nls len : %d",
-			__func__, unilen, len);
+		exfat_err(sb, "failed to %s (err : %d) nls len : %d",
+			  __func__, unilen, len);
 		return unilen;
 	}
 
 	if (unilen > MAX_NAME_LENGTH) {
-		exfat_msg(sb, KERN_ERR,
-			"failed to %s (estr:ENAMETOOLONG) nls len : %d, unilen : %d > %d",
-			__func__, len, unilen, MAX_NAME_LENGTH);
+		exfat_err(sb, "failed to %s (estr:ENAMETOOLONG) nls len : %d, unilen : %d > %d",
+			  __func__, len, unilen, MAX_NAME_LENGTH);
 		return -ENAMETOOLONG;
 	}
 
@@ -537,22 +535,9 @@ static int exfat_utf8_to_utf16(struct super_block *sb,
 	return unilen;
 }
 
-#define PLANE_SIZE	0x00010000
 #define SURROGATE_MASK	0xfffff800
 #define SURROGATE_PAIR	0x0000d800
 #define SURROGATE_LOW	0x00000400
-#define SURROGATE_BITS	0x000003ff
-
-unsigned short exfat_high_surrogate(unicode_t u)
-{
-	return ((u - PLANE_SIZE) >> 10) + SURROGATE_PAIR;
-}
-
-unsigned short exfat_low_surrogate(unicode_t u)
-{
-	return ((u - PLANE_SIZE) & SURROGATE_BITS) | SURROGATE_PAIR |
-		SURROGATE_LOW;
-}
 
 static int __exfat_utf16_to_nls(struct super_block *sb,
 		struct exfat_uni_name *p_uniname, unsigned char *p_cstring,
@@ -687,9 +672,8 @@ static int exfat_load_upcase_table(struct super_block *sb,
 
 		bh = sb_bread(sb, sector);
 		if (!bh) {
-			exfat_msg(sb, KERN_ERR,
-				"failed to read sector(0x%llx)\n",
-				(unsigned long long)sector);
+			exfat_err(sb, "failed to read sector(0x%llx)\n",
+				  (unsigned long long)sector);
 			ret = -EIO;
 			goto free_table;
 		}
@@ -722,9 +706,8 @@ static int exfat_load_upcase_table(struct super_block *sb,
 	if (index >= 0xFFFF && utbl_checksum == checksum)
 		return 0;
 
-	exfat_msg(sb, KERN_ERR,
-			"failed to load upcase table (idx : 0x%08x, chksum : 0x%08x, utbl_chksum : 0x%08x)\n",
-			index, checksum, utbl_checksum);
+	exfat_err(sb, "failed to load upcase table (idx : 0x%08x, chksum : 0x%08x, utbl_chksum : 0x%08x)",
+		  index, checksum, utbl_checksum);
 	ret = -EINVAL;
 free_table:
 	exfat_free_upcase_table(sbi);
diff --git a/fs/exfat/super.c b/fs/exfat/super.c
index 16ed202ef527..45f23ebfc741 100644
--- a/fs/exfat/super.c
+++ b/fs/exfat/super.c
@@ -49,6 +49,7 @@ static void exfat_put_super(struct super_block *sb)
 		sync_blockdev(sb->s_bdev);
 	exfat_set_vol_flags(sb, VOL_CLEAN);
 	exfat_free_bitmap(sbi);
+	brelse(sbi->pbr_bh);
 	mutex_unlock(&sbi->s_lock);
 
 	call_rcu(&sbi->rcu, exfat_delayed_free);
@@ -100,8 +101,8 @@ static int exfat_statfs(struct dentry *dentry, struct kstatfs *buf)
 int exfat_set_vol_flags(struct super_block *sb, unsigned short new_flag)
 {
 	struct exfat_sb_info *sbi = EXFAT_SB(sb);
-	struct pbr64 *bpb;
-	bool sync = 0;
+	struct pbr64 *bpb = (struct pbr64 *)sbi->pbr_bh->b_data;
+	bool sync;
 
 	/* flags are not changed */
 	if (sbi->vol_flag == new_flag)
@@ -115,15 +116,6 @@ int exfat_set_vol_flags(struct super_block *sb, unsigned short new_flag)
 	if (sb_rdonly(sb))
 		return 0;
 
-	if (!sbi->pbr_bh) {
-		sbi->pbr_bh = sb_bread(sb, 0);
-		if (!sbi->pbr_bh) {
-			exfat_msg(sb, KERN_ERR, "failed to read boot sector");
-			return -ENOMEM;
-		}
-	}
-
-	bpb = (struct pbr64 *)sbi->pbr_bh->b_data;
 	bpb->bsx.vol_flags = cpu_to_le16(new_flag);
 
 	if (new_flag == VOL_DIRTY && !buffer_dirty(sbi->pbr_bh))
@@ -159,7 +151,6 @@ static int exfat_show_options(struct seq_file *m, struct dentry *root)
 		seq_puts(m, ",iocharset=utf8");
 	else if (sbi->nls_io)
 		seq_printf(m, ",iocharset=%s", sbi->nls_io->charset);
-	seq_printf(m, ",bps=%ld", sb->s_blocksize);
 	if (opts->errors == EXFAT_ERRORS_CONT)
 		seq_puts(m, ",errors=continue");
 	else if (opts->errors == EXFAT_ERRORS_PANIC)
@@ -355,49 +346,43 @@ static int exfat_read_root(struct inode *inode)
 	return 0;
 }
 
-static struct pbr *exfat_read_pbr_with_logical_sector(struct super_block *sb,
-		struct buffer_head **prev_bh)
+static struct pbr *exfat_read_pbr_with_logical_sector(struct super_block *sb)
 {
-	struct pbr *p_pbr = (struct pbr *) (*prev_bh)->b_data;
+	struct exfat_sb_info *sbi = EXFAT_SB(sb);
+	struct pbr *p_pbr = (struct pbr *) (sbi->pbr_bh)->b_data;
 	unsigned short logical_sect = 0;
 
 	logical_sect = 1 << p_pbr->bsx.f64.sect_size_bits;
 
 	if (!is_power_of_2(logical_sect) ||
 	    logical_sect < 512 || logical_sect > 4096) {
-		exfat_msg(sb, KERN_ERR, "bogus logical sector size %u",
-				logical_sect);
+		exfat_err(sb, "bogus logical sector size %u", logical_sect);
 		return NULL;
 	}
 
 	if (logical_sect < sb->s_blocksize) {
-		exfat_msg(sb, KERN_ERR,
-			"logical sector size too small for device (logical sector size = %u)",
-			logical_sect);
+		exfat_err(sb, "logical sector size too small for device (logical sector size = %u)",
+			  logical_sect);
 		return NULL;
 	}
 
 	if (logical_sect > sb->s_blocksize) {
-		struct buffer_head *bh = NULL;
-
-		__brelse(*prev_bh);
-		*prev_bh = NULL;
+		brelse(sbi->pbr_bh);
+		sbi->pbr_bh = NULL;
 
 		if (!sb_set_blocksize(sb, logical_sect)) {
-			exfat_msg(sb, KERN_ERR,
-				"unable to set blocksize %u", logical_sect);
+			exfat_err(sb, "unable to set blocksize %u",
+				  logical_sect);
 			return NULL;
 		}
-		bh = sb_bread(sb, 0);
-		if (!bh) {
-			exfat_msg(sb, KERN_ERR,
-				"unable to read boot sector (logical sector size = %lu)",
-				sb->s_blocksize);
+		sbi->pbr_bh = sb_bread(sb, 0);
+		if (!sbi->pbr_bh) {
+			exfat_err(sb, "unable to read boot sector (logical sector size = %lu)",
+				  sb->s_blocksize);
 			return NULL;
 		}
 
-		*prev_bh = bh;
-		p_pbr = (struct pbr *) bh->b_data;
+		p_pbr = (struct pbr *)sbi->pbr_bh->b_data;
 	}
 	return p_pbr;
 }
@@ -408,32 +393,31 @@ static int __exfat_fill_super(struct super_block *sb)
 	int ret;
 	struct pbr *p_pbr;
 	struct pbr64 *p_bpb;
-	struct buffer_head *bh;
 	struct exfat_sb_info *sbi = EXFAT_SB(sb);
 
 	/* set block size to read super block */
 	sb_min_blocksize(sb, 512);
 
 	/* read boot sector */
-	bh = sb_bread(sb, 0);
-	if (!bh) {
-		exfat_msg(sb, KERN_ERR, "unable to read boot sector");
+	sbi->pbr_bh = sb_bread(sb, 0);
+	if (!sbi->pbr_bh) {
+		exfat_err(sb, "unable to read boot sector");
 		return -EIO;
 	}
 
 	/* PRB is read */
-	p_pbr = (struct pbr *)bh->b_data;
+	p_pbr = (struct pbr *)sbi->pbr_bh->b_data;
 
 	/* check the validity of PBR */
 	if (le16_to_cpu((p_pbr->signature)) != PBR_SIGNATURE) {
-		exfat_msg(sb, KERN_ERR, "invalid boot record signature");
+		exfat_err(sb, "invalid boot record signature");
 		ret = -EINVAL;
 		goto free_bh;
 	}
 
 
 	/* check logical sector size */
-	p_pbr = exfat_read_pbr_with_logical_sector(sb, &bh);
+	p_pbr = exfat_read_pbr_with_logical_sector(sb);
 	if (!p_pbr) {
 		ret = -EIO;
 		goto free_bh;
@@ -451,7 +435,7 @@ static int __exfat_fill_super(struct super_block *sb)
 
 	p_bpb = (struct pbr64 *)p_pbr;
 	if (!p_bpb->bsx.num_fats) {
-		exfat_msg(sb, KERN_ERR, "bogus number of FAT structure");
+		exfat_err(sb, "bogus number of FAT structure");
 		ret = -EINVAL;
 		goto free_bh;
 	}
@@ -481,8 +465,7 @@ static int __exfat_fill_super(struct super_block *sb)
 
 	if (le16_to_cpu(p_bpb->bsx.vol_flags) & VOL_DIRTY) {
 		sbi->vol_flag |= VOL_DIRTY;
-		exfat_msg(sb, KERN_WARNING,
-			"Volume was not properly unmounted. Some data may be corrupt. Please run fsck.");
+		exfat_warn(sb, "Volume was not properly unmounted. Some data may be corrupt. Please run fsck.");
 	}
 
 	/* exFAT file size is limited by a disk volume size */
@@ -491,19 +474,19 @@ static int __exfat_fill_super(struct super_block *sb)
 
 	ret = exfat_create_upcase_table(sb);
 	if (ret) {
-		exfat_msg(sb, KERN_ERR, "failed to load upcase table");
+		exfat_err(sb, "failed to load upcase table");
 		goto free_bh;
 	}
 
 	ret = exfat_load_bitmap(sb);
 	if (ret) {
-		exfat_msg(sb, KERN_ERR, "failed to load alloc-bitmap");
+		exfat_err(sb, "failed to load alloc-bitmap");
 		goto free_upcase_table;
 	}
 
 	ret = exfat_count_used_clusters(sb, &sbi->used_clusters);
 	if (ret) {
-		exfat_msg(sb, KERN_ERR, "failed to scan clusters");
+		exfat_err(sb, "failed to scan clusters");
 		goto free_alloc_bitmap;
 	}
 
@@ -514,7 +497,7 @@ static int __exfat_fill_super(struct super_block *sb)
 free_upcase_table:
 	exfat_free_upcase_table(sbi);
 free_bh:
-	brelse(bh);
+	brelse(sbi->pbr_bh);
 	return ret;
 }
 
@@ -531,10 +514,10 @@ static int exfat_fill_super(struct super_block *sb, struct fs_context *fc)
 	if (opts->discard) {
 		struct request_queue *q = bdev_get_queue(sb->s_bdev);
 
-		if (!blk_queue_discard(q))
-			exfat_msg(sb, KERN_WARNING,
-				"mounting with \"discard\" option, but the device does not support discard");
-		opts->discard = 0;
+		if (!blk_queue_discard(q)) {
+			exfat_warn(sb, "mounting with \"discard\" option, but the device does not support discard");
+			opts->discard = 0;
+		}
 	}
 
 	sb->s_flags |= SB_NODIRATIME;
@@ -547,7 +530,7 @@ static int exfat_fill_super(struct super_block *sb, struct fs_context *fc)
 
 	err = __exfat_fill_super(sb);
 	if (err) {
-		exfat_msg(sb, KERN_ERR, "failed to recognize exfat type");
+		exfat_err(sb, "failed to recognize exfat type");
 		goto check_nls_io;
 	}
 
@@ -559,8 +542,8 @@ static int exfat_fill_super(struct super_block *sb, struct fs_context *fc)
 	else {
 		sbi->nls_io = load_nls(sbi->options.iocharset);
 		if (!sbi->nls_io) {
-			exfat_msg(sb, KERN_ERR, "IO charset %s not found",
-					sbi->options.iocharset);
+			exfat_err(sb, "IO charset %s not found",
+				  sbi->options.iocharset);
 			err = -EINVAL;
 			goto free_table;
 		}
@@ -573,7 +556,7 @@ static int exfat_fill_super(struct super_block *sb, struct fs_context *fc)
 
 	root_inode = new_inode(sb);
 	if (!root_inode) {
-		exfat_msg(sb, KERN_ERR, "failed to allocate root inode.");
+		exfat_err(sb, "failed to allocate root inode");
 		err = -ENOMEM;
 		goto free_table;
 	}
@@ -582,7 +565,7 @@ static int exfat_fill_super(struct super_block *sb, struct fs_context *fc)
 	inode_set_iversion(root_inode, 1);
 	err = exfat_read_root(root_inode);
 	if (err) {
-		exfat_msg(sb, KERN_ERR, "failed to initialize root inode.");
+		exfat_err(sb, "failed to initialize root inode");
 		goto put_inode;
 	}
 
@@ -591,7 +574,7 @@ static int exfat_fill_super(struct super_block *sb, struct fs_context *fc)
 
 	sb->s_root = d_make_root(root_inode);
 	if (!sb->s_root) {
-		exfat_msg(sb, KERN_ERR, "failed to get the root dentry");
+		exfat_err(sb, "failed to get the root dentry");
 		err = -ENOMEM;
 		goto put_inode;
 	}
@@ -605,6 +588,7 @@ static int exfat_fill_super(struct super_block *sb, struct fs_context *fc)
 free_table:
 	exfat_free_upcase_table(sbi);
 	exfat_free_bitmap(sbi);
+	brelse(sbi->pbr_bh);
 
 check_nls_io:
 	unload_nls(sbi->nls_io);
@@ -717,6 +701,7 @@ static void __exit exit_exfat_fs(void)
 module_init(init_exfat_fs);
 module_exit(exit_exfat_fs);
 
+MODULE_ALIAS_FS("exfat");
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("exFAT filesystem support");
 MODULE_AUTHOR("Samsung Electronics Co., Ltd.");
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index 0e0a4d6209c7..a32e5f7b5385 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -410,7 +410,7 @@ static int ext4_validate_block_bitmap(struct super_block *sb,
  * Read the bitmap for a given block_group,and validate the
  * bits for block/inode/inode tables are set in the bitmaps
  *
- * Return buffer_head on success or NULL in case of failure.
+ * Return buffer_head on success or an ERR_PTR in case of failure.
  */
 struct buffer_head *
 ext4_read_block_bitmap_nowait(struct super_block *sb, ext4_group_t block_group)
@@ -502,7 +502,7 @@ ext4_read_block_bitmap_nowait(struct super_block *sb, ext4_group_t block_group)
 	return ERR_PTR(err);
 }
 
-/* Returns 0 on success, 1 on error */
+/* Returns 0 on success, -errno on error */
 int ext4_wait_block_bitmap(struct super_block *sb, ext4_group_t block_group,
 			   struct buffer_head *bh)
 {
diff --git a/fs/ext4/ext4_jbd2.c b/fs/ext4/ext4_jbd2.c
index 7f16e1af8d5c..0c76cdd44d90 100644
--- a/fs/ext4/ext4_jbd2.c
+++ b/fs/ext4/ext4_jbd2.c
@@ -338,9 +338,6 @@ int __ext4_handle_dirty_metadata(const char *where, unsigned int line,
 		if (inode && inode_needs_sync(inode)) {
 			sync_dirty_buffer(bh);
 			if (buffer_req(bh) && !buffer_uptodate(bh)) {
-				struct ext4_super_block *es;
-
-				es = EXT4_SB(inode->i_sb)->s_es;
 				ext4_error_inode_err(inode, where, line,
 						     bh->b_blocknr, EIO,
 					"IO error syncing itable block");
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 031752cfb6f7..f2b577b315a0 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -3374,8 +3374,8 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
 		(unsigned long long)map->m_lblk, map_len);
 
 	sbi = EXT4_SB(inode->i_sb);
-	eof_block = (inode->i_size + inode->i_sb->s_blocksize - 1) >>
-		inode->i_sb->s_blocksize_bits;
+	eof_block = (EXT4_I(inode)->i_disksize + inode->i_sb->s_blocksize - 1)
+			>> inode->i_sb->s_blocksize_bits;
 	if (eof_block < map->m_lblk + map_len)
 		eof_block = map->m_lblk + map_len;
 
@@ -3627,8 +3627,8 @@ static int ext4_split_convert_extents(handle_t *handle,
 		  __func__, inode->i_ino,
 		  (unsigned long long)map->m_lblk, map->m_len);
 
-	eof_block = (inode->i_size + inode->i_sb->s_blocksize - 1) >>
-		inode->i_sb->s_blocksize_bits;
+	eof_block = (EXT4_I(inode)->i_disksize + inode->i_sb->s_blocksize - 1)
+			>> inode->i_sb->s_blocksize_bits;
 	if (eof_block < map->m_lblk + map->m_len)
 		eof_block = map->m_lblk + map->m_len;
 	/*
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index b420c9dc444d..4b8c9a9bdf0c 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -113,7 +113,7 @@ static int ext4_validate_inode_bitmap(struct super_block *sb,
  * Read the inode allocation bitmap for a given block_group, reading
  * into the specified slot in the superblock's bitmap cache.
  *
- * Return buffer_head of bitmap on success or NULL.
+ * Return buffer_head of bitmap on success, or an ERR_PTR on error.
  */
 static struct buffer_head *
 ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group)
@@ -662,7 +662,7 @@ static int find_group_other(struct super_block *sb, struct inode *parent,
  * block has been written back to disk.  (Yes, these values are
  * somewhat arbitrary...)
  */
-#define RECENTCY_MIN	5
+#define RECENTCY_MIN	60
 #define RECENTCY_DIRTY	300
 
 static int recently_deleted(struct super_block *sb, ext4_group_t group, int ino)
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index e416096fc081..2a4aae6acdcb 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1973,7 +1973,7 @@ static int ext4_writepage(struct page *page,
 	bool keep_towrite = false;
 
 	if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb)))) {
-		ext4_invalidatepage(page, 0, PAGE_SIZE);
+		inode->i_mapping->a_ops->invalidatepage(page, 0, PAGE_SIZE);
 		unlock_page(page);
 		return -EIO;
 	}
@@ -4364,7 +4364,7 @@ static int __ext4_get_inode_loc(struct inode *inode,
 			if (end > table)
 				end = table;
 			while (b <= end)
-				sb_breadahead(sb, b++);
+				sb_breadahead_unmovable(sb, b++);
 		}
 
 		/*
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index 87c85be4c12e..30d5d97548c4 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -1943,7 +1943,8 @@ void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac,
 	int free;
 
 	free = e4b->bd_info->bb_free;
-	BUG_ON(free <= 0);
+	if (WARN_ON(free <= 0))
+		return;
 
 	i = e4b->bd_info->bb_first_free;
 
@@ -1966,7 +1967,8 @@ void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac,
 		}
 
 		mb_find_extent(e4b, i, ac->ac_g_ex.fe_len, &ex);
-		BUG_ON(ex.fe_len <= 0);
+		if (WARN_ON(ex.fe_len <= 0))
+			break;
 		if (free < ex.fe_len) {
 			ext4_grp_locked_error(sb, e4b->bd_group, 0, 0,
 					"%d free clusters as per "
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 9728e7b0e84f..6fe32f9aa889 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -596,7 +596,6 @@ void __ext4_error_file(struct file *file, const char *function,
 {
 	va_list args;
 	struct va_format vaf;
-	struct ext4_super_block *es;
 	struct inode *inode = file_inode(file);
 	char pathname[80], *path;
 
@@ -604,7 +603,6 @@ void __ext4_error_file(struct file *file, const char *function,
 		return;
 
 	trace_ext4_error(inode->i_sb, function, line);
-	es = EXT4_SB(inode->i_sb)->s_es;
 	if (ext4_error_ratelimit(inode->i_sb)) {
 		path = file_path(file, pathname, sizeof(pathname));
 		if (IS_ERR(path))
@@ -1728,6 +1726,7 @@ static int clear_qf_name(struct super_block *sb, int qtype)
 #define MOPT_NO_EXT3	0x0200
 #define MOPT_EXT4_ONLY	(MOPT_NO_EXT2 | MOPT_NO_EXT3)
 #define MOPT_STRING	0x0400
+#define MOPT_NO_REMOUNT	0x0800
 
 static const struct mount_opts {
 	int	token;
@@ -1777,12 +1776,12 @@ static const struct mount_opts {
 	{Opt_min_batch_time, 0, MOPT_GTE0},
 	{Opt_inode_readahead_blks, 0, MOPT_GTE0},
 	{Opt_init_itable, 0, MOPT_GTE0},
-	{Opt_dax, EXT4_MOUNT_DAX, MOPT_SET},
+	{Opt_dax, EXT4_MOUNT_DAX, MOPT_SET | MOPT_NO_REMOUNT},
 	{Opt_stripe, 0, MOPT_GTE0},
 	{Opt_resuid, 0, MOPT_GTE0},
 	{Opt_resgid, 0, MOPT_GTE0},
-	{Opt_journal_dev, 0, MOPT_NO_EXT2 | MOPT_GTE0},
-	{Opt_journal_path, 0, MOPT_NO_EXT2 | MOPT_STRING},
+	{Opt_journal_dev, 0, MOPT_NO_EXT2 | MOPT_GTE0 | MOPT_NO_REMOUNT},
+	{Opt_journal_path, 0, MOPT_NO_EXT2 | MOPT_STRING | MOPT_NO_REMOUNT},
 	{Opt_journal_ioprio, 0, MOPT_NO_EXT2 | MOPT_GTE0},
 	{Opt_data_journal, EXT4_MOUNT_JOURNAL_DATA, MOPT_NO_EXT2 | MOPT_DATAJ},
 	{Opt_data_ordered, EXT4_MOUNT_ORDERED_DATA, MOPT_NO_EXT2 | MOPT_DATAJ},
@@ -1819,7 +1818,7 @@ static const struct mount_opts {
 	{Opt_jqfmt_vfsv1, QFMT_VFS_V1, MOPT_QFMT},
 	{Opt_max_dir_size_kb, 0, MOPT_GTE0},
 	{Opt_test_dummy_encryption, 0, MOPT_GTE0},
-	{Opt_nombcache, EXT4_MOUNT_NO_MBCACHE, MOPT_SET},
+	{Opt_nombcache, EXT4_MOUNT_NO_MBCACHE, MOPT_SET | MOPT_NO_REMOUNT},
 	{Opt_err, 0, 0}
 };
 
@@ -1917,6 +1916,12 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token,
 			 "Mount option \"%s\" incompatible with ext3", opt);
 		return -1;
 	}
+	if ((m->flags & MOPT_NO_REMOUNT) && is_remount) {
+		ext4_msg(sb, KERN_ERR,
+			 "Mount option \"%s\" not supported when remounting",
+			 opt);
+		return -1;
+	}
 
 	if (args->from && !(m->flags & MOPT_STRING) && match_int(args, &arg))
 		return -1;
@@ -1996,11 +2001,6 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token,
 		}
 		sbi->s_resgid = gid;
 	} else if (token == Opt_journal_dev) {
-		if (is_remount) {
-			ext4_msg(sb, KERN_ERR,
-				 "Cannot specify journal on remount");
-			return -1;
-		}
 		*journal_devnum = arg;
 	} else if (token == Opt_journal_path) {
 		char *journal_path;
@@ -2008,11 +2008,6 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token,
 		struct path path;
 		int error;
 
-		if (is_remount) {
-			ext4_msg(sb, KERN_ERR,
-				 "Cannot specify journal on remount");
-			return -1;
-		}
 		journal_path = match_strdup(&args[0]);
 		if (!journal_path) {
 			ext4_msg(sb, KERN_ERR, "error: could not dup "
@@ -4340,7 +4335,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 	/* Pre-read the descriptors into the buffer cache */
 	for (i = 0; i < db_count; i++) {
 		block = descriptor_loc(sb, logical_sb_block, i);
-		sb_breadahead(sb, block);
+		sb_breadahead_unmovable(sb, block);
 	}
 
 	for (i = 0; i < db_count; i++) {
@@ -5429,18 +5424,6 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
 		}
 	}
 
-	if ((sbi->s_mount_opt ^ old_opts.s_mount_opt) & EXT4_MOUNT_NO_MBCACHE) {
-		ext4_msg(sb, KERN_ERR, "can't enable nombcache during remount");
-		err = -EINVAL;
-		goto restore_opts;
-	}
-
-	if ((sbi->s_mount_opt ^ old_opts.s_mount_opt) & EXT4_MOUNT_DAX) {
-		ext4_msg(sb, KERN_WARNING, "warning: refusing change of "
-			"dax flag with busy inodes while remounting");
-		sbi->s_mount_opt ^= EXT4_MOUNT_DAX;
-	}
-
 	if (sbi->s_mount_flags & EXT4_MF_FS_ABORTED)
 		ext4_abort(sb, EXT4_ERR_ESHUTDOWN, "Abort forced by user");
 
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 852890b72d6a..5ba649e17c72 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -86,6 +86,8 @@ static struct page *__get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index,
 		return ERR_PTR(err);
 	}
 
+	f2fs_update_iostat(sbi, FS_META_READ_IO, F2FS_BLKSIZE);
+
 	lock_page(page);
 	if (unlikely(page->mapping != mapping)) {
 		f2fs_put_page(page, 1);
@@ -220,6 +222,7 @@ int f2fs_ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages,
 		.is_por = (type == META_POR),
 	};
 	struct blk_plug plug;
+	int err;
 
 	if (unlikely(type == META_POR))
 		fio.op_flags &= ~REQ_META;
@@ -263,8 +266,11 @@ int f2fs_ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages,
 		}
 
 		fio.page = page;
-		f2fs_submit_page_bio(&fio);
-		f2fs_put_page(page, 0);
+		err = f2fs_submit_page_bio(&fio);
+		f2fs_put_page(page, err ? 1 : 0);
+
+		if (!err)
+			f2fs_update_iostat(sbi, FS_META_READ_IO, F2FS_BLKSIZE);
 	}
 out:
 	blk_finish_plug(&plug);
diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
index df7b2d15eacd..faaa35828901 100644
--- a/fs/f2fs/compress.c
+++ b/fs/f2fs/compress.c
@@ -985,7 +985,7 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc,
 	loff_t psize;
 	int i, err;
 
-	if (!f2fs_trylock_op(sbi))
+	if (!IS_NOQUOTA(inode) && !f2fs_trylock_op(sbi))
 		return -EAGAIN;
 
 	set_new_dnode(&dn, cc->inode, NULL, NULL, 0);
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index cdf2f626bea7..a5505aba2a1f 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -513,6 +513,28 @@ void f2fs_submit_bio(struct f2fs_sb_info *sbi,
 	__submit_bio(sbi, bio, type);
 }
 
+static void __attach_data_io_flag(struct f2fs_io_info *fio)
+{
+	struct f2fs_sb_info *sbi = fio->sbi;
+	unsigned int temp_mask = (1 << NR_TEMP_TYPE) - 1;
+	unsigned int fua_flag = sbi->data_io_flag & temp_mask;
+	unsigned int meta_flag = (sbi->data_io_flag >> NR_TEMP_TYPE) &
+								temp_mask;
+	/*
+	 * data io flag bits per temp:
+	 *      REQ_META     |      REQ_FUA      |
+	 *    5 |    4 |   3 |    2 |    1 |   0 |
+	 * Cold | Warm | Hot | Cold | Warm | Hot |
+	 */
+	if (fio->type != DATA)
+		return;
+
+	if ((1 << fio->temp) & meta_flag)
+		fio->op_flags |= REQ_META;
+	if ((1 << fio->temp) & fua_flag)
+		fio->op_flags |= REQ_FUA;
+}
+
 static void __submit_merged_bio(struct f2fs_bio_info *io)
 {
 	struct f2fs_io_info *fio = &io->fio;
@@ -520,6 +542,7 @@ static void __submit_merged_bio(struct f2fs_bio_info *io)
 	if (!io->bio)
 		return;
 
+	__attach_data_io_flag(fio);
 	bio_set_op_attrs(io->bio, fio->op, fio->op_flags);
 
 	if (is_read_io(fio->op))
@@ -1010,6 +1033,7 @@ static int f2fs_submit_page_read(struct inode *inode, struct page *page,
 	}
 	ClearPageError(page);
 	inc_page_count(sbi, F2FS_RD_DATA);
+	f2fs_update_iostat(sbi, FS_DATA_READ_IO, F2FS_BLKSIZE);
 	__submit_bio(sbi, bio, DATA);
 	return 0;
 }
@@ -2015,6 +2039,7 @@ static int f2fs_read_single_page(struct inode *inode, struct page *page,
 		goto submit_and_realloc;
 
 	inc_page_count(F2FS_I_SB(inode), F2FS_RD_DATA);
+	f2fs_update_iostat(F2FS_I_SB(inode), FS_DATA_READ_IO, F2FS_BLKSIZE);
 	ClearPageError(page);
 	*last_block_in_bio = block_nr;
 	goto out;
@@ -2150,6 +2175,7 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,
 			goto submit_and_realloc;
 
 		inc_page_count(sbi, F2FS_RD_DATA);
+		f2fs_update_iostat(sbi, FS_DATA_READ_IO, F2FS_BLKSIZE);
 		ClearPageError(page);
 		*last_block_in_bio = blkaddr;
 	}
@@ -2633,8 +2659,8 @@ int f2fs_write_single_data_page(struct page *page, int *submitted,
 			f2fs_available_free_memory(sbi, BASE_CHECK))))
 		goto redirty_out;
 
-	/* Dentry blocks are controlled by checkpoint */
-	if (S_ISDIR(inode->i_mode)) {
+	/* Dentry/quota blocks are controlled by checkpoint */
+	if (S_ISDIR(inode->i_mode) || IS_NOQUOTA(inode)) {
 		fio.need_lock = LOCK_DONE;
 		err = f2fs_do_write_data_page(&fio);
 		goto done;
@@ -3503,6 +3529,9 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
 		} else if (err < 0) {
 			f2fs_write_failed(mapping, offset + count);
 		}
+	} else {
+		if (err > 0)
+			f2fs_update_iostat(sbi, APP_DIRECT_READ_IO, err);
 	}
 
 out:
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index ba470d5687fe..3b9603266a2a 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1088,8 +1088,9 @@ enum cp_reason_type {
 };
 
 enum iostat_type {
-	APP_DIRECT_IO,			/* app direct IOs */
-	APP_BUFFERED_IO,		/* app buffered IOs */
+	/* WRITE IO */
+	APP_DIRECT_IO,			/* app direct write IOs */
+	APP_BUFFERED_IO,		/* app buffered write IOs */
 	APP_WRITE_IO,			/* app write IOs */
 	APP_MAPPED_IO,			/* app mapped IOs */
 	FS_DATA_IO,			/* data IOs from kworker/fsync/reclaimer */
@@ -1100,6 +1101,17 @@ enum iostat_type {
 	FS_CP_DATA_IO,			/* data IOs from checkpoint */
 	FS_CP_NODE_IO,			/* node IOs from checkpoint */
 	FS_CP_META_IO,			/* meta IOs from checkpoint */
+
+	/* READ IO */
+	APP_DIRECT_READ_IO,		/* app direct read IOs */
+	APP_BUFFERED_READ_IO,		/* app buffered read IOs */
+	APP_READ_IO,			/* app read IOs */
+	APP_MAPPED_READ_IO,		/* app mapped read IOs */
+	FS_DATA_READ_IO,		/* data read IOs */
+	FS_NODE_READ_IO,		/* node read IOs */
+	FS_META_READ_IO,		/* meta read IOs */
+
+	/* other */
 	FS_DISCARD,			/* discard */
 	NR_IO_TYPE,
 };
@@ -1504,8 +1516,14 @@ struct f2fs_sb_info {
 
 	/* For app/fs IO statistics */
 	spinlock_t iostat_lock;
-	unsigned long long write_iostat[NR_IO_TYPE];
+	unsigned long long rw_iostat[NR_IO_TYPE];
+	unsigned long long prev_rw_iostat[NR_IO_TYPE];
 	bool iostat_enable;
+	unsigned long iostat_next_period;
+	unsigned int iostat_period_ms;
+
+	/* to attach REQ_META|REQ_FUA flags */
+	unsigned int data_io_flag;
 
 	/* For sysfs suppport */
 	struct kobject s_kobj;
@@ -2996,29 +3014,45 @@ static inline int get_inline_xattr_addrs(struct inode *inode)
 		sizeof((f2fs_inode)->field))			\
 		<= (F2FS_OLD_ATTRIBUTE_SIZE + (extra_isize)))	\
 
+#define DEFAULT_IOSTAT_PERIOD_MS	3000
+#define MIN_IOSTAT_PERIOD_MS		100
+/* maximum period of iostat tracing is 1 day */
+#define MAX_IOSTAT_PERIOD_MS		8640000
+
 static inline void f2fs_reset_iostat(struct f2fs_sb_info *sbi)
 {
 	int i;
 
 	spin_lock(&sbi->iostat_lock);
-	for (i = 0; i < NR_IO_TYPE; i++)
-		sbi->write_iostat[i] = 0;
+	for (i = 0; i < NR_IO_TYPE; i++) {
+		sbi->rw_iostat[i] = 0;
+		sbi->prev_rw_iostat[i] = 0;
+	}
 	spin_unlock(&sbi->iostat_lock);
 }
 
+extern void f2fs_record_iostat(struct f2fs_sb_info *sbi);
+
 static inline void f2fs_update_iostat(struct f2fs_sb_info *sbi,
 			enum iostat_type type, unsigned long long io_bytes)
 {
 	if (!sbi->iostat_enable)
 		return;
 	spin_lock(&sbi->iostat_lock);
-	sbi->write_iostat[type] += io_bytes;
+	sbi->rw_iostat[type] += io_bytes;
 
 	if (type == APP_WRITE_IO || type == APP_DIRECT_IO)
-		sbi->write_iostat[APP_BUFFERED_IO] =
-			sbi->write_iostat[APP_WRITE_IO] -
-			sbi->write_iostat[APP_DIRECT_IO];
+		sbi->rw_iostat[APP_BUFFERED_IO] =
+			sbi->rw_iostat[APP_WRITE_IO] -
+			sbi->rw_iostat[APP_DIRECT_IO];
+
+	if (type == APP_READ_IO || type == APP_DIRECT_READ_IO)
+		sbi->rw_iostat[APP_BUFFERED_READ_IO] =
+			sbi->rw_iostat[APP_READ_IO] -
+			sbi->rw_iostat[APP_DIRECT_READ_IO];
 	spin_unlock(&sbi->iostat_lock);
+
+	f2fs_record_iostat(sbi);
 }
 
 #define __is_large_section(sbi)		((sbi)->segs_per_sec > 1)
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 6ab8f621a3c5..a0a4413d6083 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -40,6 +40,10 @@ static vm_fault_t f2fs_filemap_fault(struct vm_fault *vmf)
 	ret = filemap_fault(vmf);
 	up_read(&F2FS_I(inode)->i_mmap_sem);
 
+	if (!ret)
+		f2fs_update_iostat(F2FS_I_SB(inode), APP_MAPPED_READ_IO,
+							F2FS_BLKSIZE);
+
 	trace_f2fs_filemap_fault(inode, vmf->pgoff, (unsigned long)ret);
 
 	return ret;
@@ -3510,11 +3514,17 @@ static ssize_t f2fs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
 {
 	struct file *file = iocb->ki_filp;
 	struct inode *inode = file_inode(file);
+	int ret;
 
 	if (!f2fs_is_compress_backend_ready(inode))
 		return -EOPNOTSUPP;
 
-	return generic_file_read_iter(iocb, iter);
+	ret = generic_file_read_iter(iocb, iter);
+
+	if (ret > 0)
+		f2fs_update_iostat(F2FS_I_SB(inode), APP_READ_IO, ret);
+
+	return ret;
 }
 
 static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 26248c8936db..28a8c79c8bdc 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -737,6 +737,9 @@ static int ra_data_block(struct inode *inode, pgoff_t index)
 		goto put_encrypted_page;
 	f2fs_put_page(fio.encrypted_page, 0);
 	f2fs_put_page(page, 1);
+
+	f2fs_update_iostat(sbi, FS_DATA_READ_IO, F2FS_BLKSIZE);
+
 	return 0;
 put_encrypted_page:
 	f2fs_put_page(fio.encrypted_page, 1);
@@ -840,6 +843,9 @@ static int move_data_block(struct inode *inode, block_t bidx,
 			f2fs_put_page(mpage, 1);
 			goto up_out;
 		}
+
+		f2fs_update_iostat(fio.sbi, FS_DATA_READ_IO, F2FS_BLKSIZE);
+
 		lock_page(mpage);
 		if (unlikely(mpage->mapping != META_MAPPING(fio.sbi) ||
 						!PageUptodate(mpage))) {
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index ecbd6bd14a49..4da0d8713df5 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -1300,7 +1300,13 @@ static int read_node_page(struct page *page, int op_flags)
 	}
 
 	fio.new_blkaddr = fio.old_blkaddr = ni.blk_addr;
-	return f2fs_submit_page_bio(&fio);
+
+	err = f2fs_submit_page_bio(&fio);
+
+	if (!err)
+		f2fs_update_iostat(sbi, FS_NODE_READ_IO, F2FS_BLKSIZE);
+
+	return err;
 }
 
 /*
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index b7a9421472a7..1c48ec866b8c 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -1029,9 +1029,9 @@ static void f2fs_submit_discard_endio(struct bio *bio)
 	struct discard_cmd *dc = (struct discard_cmd *)bio->bi_private;
 	unsigned long flags;
 
-	dc->error = blk_status_to_errno(bio->bi_status);
-
 	spin_lock_irqsave(&dc->lock, flags);
+	if (!dc->error)
+		dc->error = blk_status_to_errno(bio->bi_status);
 	dc->bio_ref--;
 	if (!dc->bio_ref && dc->state == D_SUBMIT) {
 		dc->state = D_DONE;
@@ -1101,7 +1101,6 @@ static void __init_discard_policy(struct f2fs_sb_info *sbi,
 	} else if (discard_type == DPOLICY_FSTRIM) {
 		dpolicy->io_aware = false;
 	} else if (discard_type == DPOLICY_UMOUNT) {
-		dpolicy->max_requests = UINT_MAX;
 		dpolicy->io_aware = false;
 		/* we need to issue all to keep CP_TRIMMED_FLAG */
 		dpolicy->granularity = 1;
@@ -1215,8 +1214,10 @@ static int __submit_discard_cmd(struct f2fs_sb_info *sbi,
 		len = total_len;
 	}
 
-	if (!err && len)
+	if (!err && len) {
+		dcc->undiscard_blks -= len;
 		__update_discard_tree_range(sbi, bdev, lstart, start, len);
+	}
 	return err;
 }
 
@@ -1463,6 +1464,8 @@ static unsigned int __issue_discard_cmd_orderly(struct f2fs_sb_info *sbi,
 
 	return issued;
 }
+static unsigned int __wait_all_discard_cmd(struct f2fs_sb_info *sbi,
+					struct discard_policy *dpolicy);
 
 static int __issue_discard_cmd(struct f2fs_sb_info *sbi,
 					struct discard_policy *dpolicy)
@@ -1471,12 +1474,14 @@ static int __issue_discard_cmd(struct f2fs_sb_info *sbi,
 	struct list_head *pend_list;
 	struct discard_cmd *dc, *tmp;
 	struct blk_plug plug;
-	int i, issued = 0;
+	int i, issued;
 	bool io_interrupted = false;
 
 	if (dpolicy->timeout)
 		f2fs_update_time(sbi, UMOUNT_DISCARD_TIMEOUT);
 
+retry:
+	issued = 0;
 	for (i = MAX_PLIST_NUM - 1; i >= 0; i--) {
 		if (dpolicy->timeout &&
 				f2fs_time_over(sbi, UMOUNT_DISCARD_TIMEOUT))
@@ -1523,6 +1528,11 @@ static int __issue_discard_cmd(struct f2fs_sb_info *sbi,
 			break;
 	}
 
+	if (dpolicy->type == DPOLICY_UMOUNT && issued) {
+		__wait_all_discard_cmd(sbi, dpolicy);
+		goto retry;
+	}
+
 	if (!issued && io_interrupted)
 		issued = -1;
 
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index f2dfc21c6abb..438296e17183 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -3424,6 +3424,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
 	/* init iostat info */
 	spin_lock_init(&sbi->iostat_lock);
 	sbi->iostat_enable = false;
+	sbi->iostat_period_ms = DEFAULT_IOSTAT_PERIOD_MS;
 
 	for (i = 0; i < NR_PAGE_TYPE; i++) {
 		int n = (i == META) ? 1: NR_TEMP_TYPE;
diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index e3bbbef9b4f0..eaf8088548f0 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -15,6 +15,7 @@
 #include "f2fs.h"
 #include "segment.h"
 #include "gc.h"
+#include <trace/events/f2fs.h>
 
 static struct proc_dir_entry *f2fs_proc_root;
 
@@ -372,7 +373,6 @@ static ssize_t __sbi_store(struct f2fs_attr *a,
 		return count;
 	}
 
-
 	if (!strcmp(a->attr.name, "iostat_enable")) {
 		sbi->iostat_enable = !!t;
 		if (!sbi->iostat_enable)
@@ -380,6 +380,15 @@ static ssize_t __sbi_store(struct f2fs_attr *a,
 		return count;
 	}
 
+	if (!strcmp(a->attr.name, "iostat_period_ms")) {
+		if (t < MIN_IOSTAT_PERIOD_MS || t > MAX_IOSTAT_PERIOD_MS)
+			return -EINVAL;
+		spin_lock(&sbi->iostat_lock);
+		sbi->iostat_period_ms = (unsigned int)t;
+		spin_unlock(&sbi->iostat_lock);
+		return count;
+	}
+
 	*ui = (unsigned int)t;
 
 	return count;
@@ -536,6 +545,7 @@ F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_idle_interval, interval_time[GC_TIME]);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info,
 		umount_discard_timeout, interval_time[UMOUNT_DISCARD_TIMEOUT]);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, iostat_enable, iostat_enable);
+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, iostat_period_ms, iostat_period_ms);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, readdir_ra, readdir_ra);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_pin_file_thresh, gc_pin_file_threshold);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_super_block, extension_list, extension_list);
@@ -543,6 +553,7 @@ F2FS_RW_ATTR(F2FS_SBI, f2fs_super_block, extension_list, extension_list);
 F2FS_RW_ATTR(FAULT_INFO_RATE, f2fs_fault_info, inject_rate, inject_rate);
 F2FS_RW_ATTR(FAULT_INFO_TYPE, f2fs_fault_info, inject_type, inject_type);
 #endif
+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, data_io_flag, data_io_flag);
 F2FS_GENERAL_RO_ATTR(dirty_segments);
 F2FS_GENERAL_RO_ATTR(free_segments);
 F2FS_GENERAL_RO_ATTR(lifetime_write_kbytes);
@@ -615,6 +626,7 @@ static struct attribute *f2fs_attrs[] = {
 	ATTR_LIST(gc_idle_interval),
 	ATTR_LIST(umount_discard_timeout),
 	ATTR_LIST(iostat_enable),
+	ATTR_LIST(iostat_period_ms),
 	ATTR_LIST(readdir_ra),
 	ATTR_LIST(gc_pin_file_thresh),
 	ATTR_LIST(extension_list),
@@ -622,6 +634,7 @@ static struct attribute *f2fs_attrs[] = {
 	ATTR_LIST(inject_rate),
 	ATTR_LIST(inject_type),
 #endif
+	ATTR_LIST(data_io_flag),
 	ATTR_LIST(dirty_segments),
 	ATTR_LIST(free_segments),
 	ATTR_LIST(unusable),
@@ -750,6 +763,33 @@ static int __maybe_unused segment_bits_seq_show(struct seq_file *seq,
 	return 0;
 }
 
+void f2fs_record_iostat(struct f2fs_sb_info *sbi)
+{
+	unsigned long long iostat_diff[NR_IO_TYPE];
+	int i;
+
+	if (time_is_after_jiffies(sbi->iostat_next_period))
+		return;
+
+	/* Need double check under the lock */
+	spin_lock(&sbi->iostat_lock);
+	if (time_is_after_jiffies(sbi->iostat_next_period)) {
+		spin_unlock(&sbi->iostat_lock);
+		return;
+	}
+	sbi->iostat_next_period = jiffies +
+				msecs_to_jiffies(sbi->iostat_period_ms);
+
+	for (i = 0; i < NR_IO_TYPE; i++) {
+		iostat_diff[i] = sbi->rw_iostat[i] -
+				sbi->prev_rw_iostat[i];
+		sbi->prev_rw_iostat[i] = sbi->rw_iostat[i];
+	}
+	spin_unlock(&sbi->iostat_lock);
+
+	trace_f2fs_iostat(sbi, iostat_diff);
+}
+
 static int __maybe_unused iostat_info_seq_show(struct seq_file *seq,
 					       void *offset)
 {
@@ -762,33 +802,51 @@ static int __maybe_unused iostat_info_seq_show(struct seq_file *seq,
 
 	seq_printf(seq, "time:		%-16llu\n", now);
 
-	/* print app IOs */
+	/* print app write IOs */
 	seq_printf(seq, "app buffered:	%-16llu\n",
-				sbi->write_iostat[APP_BUFFERED_IO]);
+				sbi->rw_iostat[APP_BUFFERED_IO]);
 	seq_printf(seq, "app direct:	%-16llu\n",
-				sbi->write_iostat[APP_DIRECT_IO]);
+				sbi->rw_iostat[APP_DIRECT_IO]);
 	seq_printf(seq, "app mapped:	%-16llu\n",
-				sbi->write_iostat[APP_MAPPED_IO]);
+				sbi->rw_iostat[APP_MAPPED_IO]);
 
-	/* print fs IOs */
+	/* print fs write IOs */
 	seq_printf(seq, "fs data:	%-16llu\n",
-				sbi->write_iostat[FS_DATA_IO]);
+				sbi->rw_iostat[FS_DATA_IO]);
 	seq_printf(seq, "fs node:	%-16llu\n",
-				sbi->write_iostat[FS_NODE_IO]);
+				sbi->rw_iostat[FS_NODE_IO]);
 	seq_printf(seq, "fs meta:	%-16llu\n",
-				sbi->write_iostat[FS_META_IO]);
+				sbi->rw_iostat[FS_META_IO]);
 	seq_printf(seq, "fs gc data:	%-16llu\n",
-				sbi->write_iostat[FS_GC_DATA_IO]);
+				sbi->rw_iostat[FS_GC_DATA_IO]);
 	seq_printf(seq, "fs gc node:	%-16llu\n",
-				sbi->write_iostat[FS_GC_NODE_IO]);
+				sbi->rw_iostat[FS_GC_NODE_IO]);
 	seq_printf(seq, "fs cp data:	%-16llu\n",
-				sbi->write_iostat[FS_CP_DATA_IO]);
+				sbi->rw_iostat[FS_CP_DATA_IO]);
 	seq_printf(seq, "fs cp node:	%-16llu\n",
-				sbi->write_iostat[FS_CP_NODE_IO]);
+				sbi->rw_iostat[FS_CP_NODE_IO]);
 	seq_printf(seq, "fs cp meta:	%-16llu\n",
-				sbi->write_iostat[FS_CP_META_IO]);
+				sbi->rw_iostat[FS_CP_META_IO]);
+
+	/* print app read IOs */
+	seq_printf(seq, "app buffered:	%-16llu\n",
+				sbi->rw_iostat[APP_BUFFERED_READ_IO]);
+	seq_printf(seq, "app direct:	%-16llu\n",
+				sbi->rw_iostat[APP_DIRECT_READ_IO]);
+	seq_printf(seq, "app mapped:	%-16llu\n",
+				sbi->rw_iostat[APP_MAPPED_READ_IO]);
+
+	/* print fs read IOs */
+	seq_printf(seq, "fs data:	%-16llu\n",
+				sbi->rw_iostat[FS_DATA_READ_IO]);
+	seq_printf(seq, "fs node:	%-16llu\n",
+				sbi->rw_iostat[FS_NODE_READ_IO]);
+	seq_printf(seq, "fs meta:	%-16llu\n",
+				sbi->rw_iostat[FS_META_READ_IO]);
+
+	/* print other IOs */
 	seq_printf(seq, "fs discard:	%-16llu\n",
-				sbi->write_iostat[FS_DISCARD]);
+				sbi->rw_iostat[FS_DISCARD]);
 
 	return 0;
 }
diff --git a/fs/io_uring.c b/fs/io_uring.c
index 5190bfb6a665..b15519c3fb3f 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -2756,7 +2756,7 @@ static int io_splice_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
 
 static bool io_splice_punt(struct file *file)
 {
-	if (get_pipe_info(file))
+	if (get_pipe_info(file, true))
 		return false;
 	if (!io_file_supports_async(file))
 		return true;
@@ -3266,7 +3266,7 @@ static int io_madvise(struct io_kiocb *req, bool force_nonblock)
 	if (force_nonblock)
 		return -EAGAIN;
 
-	ret = do_madvise(ma->addr, ma->len, ma->advice);
+	ret = do_madvise(NULL, req->work.mm, ma->addr, ma->len, ma->advice);
 	if (ret < 0)
 		req_set_fail_links(req);
 	io_cqring_add_event(req, ret);
diff --git a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c
index 3acc954f7c04..837d42f61464 100644
--- a/fs/jfs/jfs_dtree.c
+++ b/fs/jfs/jfs_dtree.c
@@ -2964,7 +2964,7 @@ struct jfs_dirent {
 	loff_t position;
 	int ino;
 	u16 name_len;
-	char name[0];
+	char name[];
 };
 
 /*
diff --git a/fs/jfs/jfs_xattr.h b/fs/jfs/jfs_xattr.h
index f0558b3348da..c50167a7bc50 100644
--- a/fs/jfs/jfs_xattr.h
+++ b/fs/jfs/jfs_xattr.h
@@ -17,12 +17,12 @@ struct jfs_ea {
 	u8 flag;	/* Unused? */
 	u8 namelen;	/* Length of name */
 	__le16 valuelen;	/* Length of value */
-	char name[0];	/* Attribute name (includes null-terminator) */
+	char name[];	/* Attribute name (includes null-terminator) */
 };			/* Value immediately follows name */
 
 struct jfs_ea_list {
 	__le32 size;		/* overall size */
-	struct jfs_ea ea[0];	/* Variable length list */
+	struct jfs_ea ea[];	/* Variable length list */
 };
 
 /* Macros for defining maxiumum number of bytes supported for EAs */
diff --git a/fs/namespace.c b/fs/namespace.c
index a28e4db075ed..e6aed405611d 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -669,9 +669,6 @@ bool __is_local_mountpoint(struct dentry *dentry)
 	struct mount *mnt;
 	bool is_covered = false;
 
-	if (!d_mountpoint(dentry))
-		goto out;
-
 	down_read(&namespace_sem);
 	list_for_each_entry(mnt, &ns->list, mnt_list) {
 		is_covered = (mnt->mnt_mountpoint == dentry);
@@ -679,7 +676,7 @@ bool __is_local_mountpoint(struct dentry *dentry)
 			break;
 	}
 	up_read(&namespace_sem);
-out:
+
 	return is_covered;
 }
 
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index f2dc35c22964..b8d78f393365 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -2023,6 +2023,7 @@ pnfs_update_layout(struct inode *ino,
 			goto lookup_again;
 		}
 
+		spin_unlock(&ino->i_lock);
 		first = true;
 		status = nfs4_select_rw_stateid(ctx->state,
 					iomode == IOMODE_RW ? FMODE_WRITE : FMODE_READ,
@@ -2032,12 +2033,12 @@ pnfs_update_layout(struct inode *ino,
 			trace_pnfs_update_layout(ino, pos, count,
 					iomode, lo, lseg,
 					PNFS_UPDATE_LAYOUT_INVALID_OPEN);
-			spin_unlock(&ino->i_lock);
 			nfs4_schedule_stateid_recovery(server, ctx->state);
 			pnfs_clear_first_layoutget(lo);
 			pnfs_put_layout_hdr(lo);
 			goto lookup_again;
 		}
+		spin_lock(&ino->i_lock);
 	} else {
 		nfs4_stateid_copy(&stateid, &lo->plh_stateid);
 	}
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index c3b11a715082..5cf91322de0f 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -1312,6 +1312,7 @@ nfsd4_run_cb_work(struct work_struct *work)
 		container_of(work, struct nfsd4_callback, cb_work);
 	struct nfs4_client *clp = cb->cb_clp;
 	struct rpc_clnt *clnt;
+	int flags;
 
 	if (cb->cb_need_restart) {
 		cb->cb_need_restart = false;
@@ -1340,7 +1341,8 @@ nfsd4_run_cb_work(struct work_struct *work)
 	}
 
 	cb->cb_msg.rpc_cred = clp->cl_cb_cred;
-	rpc_call_async(clnt, &cb->cb_msg, RPC_TASK_SOFT | RPC_TASK_SOFTCONN,
+	flags = clp->cl_minorversion ? RPC_TASK_NOCONNECT : RPC_TASK_SOFTCONN;
+	rpc_call_async(clnt, &cb->cb_msg, RPC_TASK_SOFT | flags,
 			cb->cb_ops ? &nfsd4_cb_ops : &nfsd4_cb_probe_ops, cb);
 }
 
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index e32ecedece0f..c107caa56525 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -267,6 +267,8 @@ find_or_allocate_block(struct nfs4_lockowner *lo, struct knfsd_fh *fh,
 	if (!nbl) {
 		nbl= kmalloc(sizeof(*nbl), GFP_KERNEL);
 		if (nbl) {
+			INIT_LIST_HEAD(&nbl->nbl_list);
+			INIT_LIST_HEAD(&nbl->nbl_lru);
 			fh_copy_shallow(&nbl->nbl_fh, fh);
 			locks_init_lock(&nbl->nbl_lock);
 			nfsd4_init_cb(&nbl->nbl_cb, lo->lo_owner.so_client,
diff --git a/fs/pipe.c b/fs/pipe.c
index 16fb72e9abf7..620a113f92eb 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -24,6 +24,7 @@
 #include <linux/syscalls.h>
 #include <linux/fcntl.h>
 #include <linux/memcontrol.h>
+#include <linux/watch_queue.h>
 
 #include <linux/uaccess.h>
 #include <asm/ioctls.h>
@@ -313,14 +314,44 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to)
 		unsigned int tail = pipe->tail;
 		unsigned int mask = pipe->ring_size - 1;
 
+#ifdef CONFIG_WATCH_QUEUE
+		if (pipe->note_loss) {
+			struct watch_notification n;
+
+			if (total_len < 8) {
+				if (ret == 0)
+					ret = -ENOBUFS;
+				break;
+			}
+
+			n.type = WATCH_TYPE_META;
+			n.subtype = WATCH_META_LOSS_NOTIFICATION;
+			n.info = watch_sizeof(n);
+			if (copy_to_iter(&n, sizeof(n), to) != sizeof(n)) {
+				if (ret == 0)
+					ret = -EFAULT;
+				break;
+			}
+			ret += sizeof(n);
+			total_len -= sizeof(n);
+			pipe->note_loss = false;
+		}
+#endif
+
 		if (!pipe_empty(head, tail)) {
 			struct pipe_buffer *buf = &pipe->bufs[tail & mask];
 			size_t chars = buf->len;
 			size_t written;
 			int error;
 
-			if (chars > total_len)
+			if (chars > total_len) {
+				if (buf->flags & PIPE_BUF_FLAG_WHOLE) {
+					if (ret == 0)
+						ret = -ENOBUFS;
+					break;
+				}
 				chars = total_len;
+			}
 
 			error = pipe_buf_confirm(pipe, buf);
 			if (error) {
@@ -348,6 +379,10 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to)
 			if (!buf->len) {
 				pipe_buf_release(pipe, buf);
 				spin_lock_irq(&pipe->rd_wait.lock);
+#ifdef CONFIG_WATCH_QUEUE
+				if (buf->flags & PIPE_BUF_FLAG_LOSS)
+					pipe->note_loss = true;
+#endif
 				tail++;
 				pipe->tail = tail;
 				spin_unlock_irq(&pipe->rd_wait.lock);
@@ -459,6 +494,13 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from)
 		goto out;
 	}
 
+#ifdef CONFIG_WATCH_QUEUE
+	if (pipe->watch_queue) {
+		ret = -EXDEV;
+		goto out;
+	}
+#endif
+
 	/*
 	 * Only wake up if the pipe started out empty, since
 	 * otherwise there should be no readers waiting.
@@ -628,22 +670,37 @@ static long pipe_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 	int count, head, tail, mask;
 
 	switch (cmd) {
-		case FIONREAD:
-			__pipe_lock(pipe);
-			count = 0;
-			head = pipe->head;
-			tail = pipe->tail;
-			mask = pipe->ring_size - 1;
+	case FIONREAD:
+		__pipe_lock(pipe);
+		count = 0;
+		head = pipe->head;
+		tail = pipe->tail;
+		mask = pipe->ring_size - 1;
 
-			while (tail != head) {
-				count += pipe->bufs[tail & mask].len;
-				tail++;
-			}
-			__pipe_unlock(pipe);
+		while (tail != head) {
+			count += pipe->bufs[tail & mask].len;
+			tail++;
+		}
+		__pipe_unlock(pipe);
+
+		return put_user(count, (int __user *)arg);
 
-			return put_user(count, (int __user *)arg);
-		default:
-			return -ENOIOCTLCMD;
+#ifdef CONFIG_WATCH_QUEUE
+	case IOC_WATCH_QUEUE_SET_SIZE: {
+		int ret;
+		__pipe_lock(pipe);
+		ret = watch_queue_set_size(pipe, arg);
+		__pipe_unlock(pipe);
+		return ret;
+	}
+
+	case IOC_WATCH_QUEUE_SET_FILTER:
+		return watch_queue_set_filter(
+			pipe, (struct watch_notification_filter __user *)arg);
+#endif
+
+	default:
+		return -ENOIOCTLCMD;
 	}
 }
 
@@ -754,27 +811,27 @@ pipe_fasync(int fd, struct file *filp, int on)
 	return retval;
 }
 
-static unsigned long account_pipe_buffers(struct user_struct *user,
-                                 unsigned long old, unsigned long new)
+unsigned long account_pipe_buffers(struct user_struct *user,
+				   unsigned long old, unsigned long new)
 {
 	return atomic_long_add_return(new - old, &user->pipe_bufs);
 }
 
-static bool too_many_pipe_buffers_soft(unsigned long user_bufs)
+bool too_many_pipe_buffers_soft(unsigned long user_bufs)
 {
 	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)
+bool too_many_pipe_buffers_hard(unsigned long user_bufs)
 {
 	unsigned long hard_limit = READ_ONCE(pipe_user_pages_hard);
 
 	return hard_limit && user_bufs > hard_limit;
 }
 
-static bool is_unprivileged_user(void)
+bool pipe_is_unprivileged_user(void)
 {
 	return !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN);
 }
@@ -796,12 +853,12 @@ struct pipe_inode_info *alloc_pipe_info(void)
 
 	user_bufs = account_pipe_buffers(user, 0, pipe_bufs);
 
-	if (too_many_pipe_buffers_soft(user_bufs) && is_unprivileged_user()) {
+	if (too_many_pipe_buffers_soft(user_bufs) && pipe_is_unprivileged_user()) {
 		user_bufs = account_pipe_buffers(user, pipe_bufs, 1);
 		pipe_bufs = 1;
 	}
 
-	if (too_many_pipe_buffers_hard(user_bufs) && is_unprivileged_user())
+	if (too_many_pipe_buffers_hard(user_bufs) && pipe_is_unprivileged_user())
 		goto out_revert_acct;
 
 	pipe->bufs = kcalloc(pipe_bufs, sizeof(struct pipe_buffer),
@@ -813,6 +870,7 @@ struct pipe_inode_info *alloc_pipe_info(void)
 		pipe->r_counter = pipe->w_counter = 1;
 		pipe->max_usage = pipe_bufs;
 		pipe->ring_size = pipe_bufs;
+		pipe->nr_accounted = pipe_bufs;
 		pipe->user = user;
 		mutex_init(&pipe->mutex);
 		return pipe;
@@ -830,7 +888,14 @@ void free_pipe_info(struct pipe_inode_info *pipe)
 {
 	int i;
 
-	(void) account_pipe_buffers(pipe->user, pipe->ring_size, 0);
+#ifdef CONFIG_WATCH_QUEUE
+	if (pipe->watch_queue) {
+		watch_queue_clear(pipe->watch_queue);
+		put_watch_queue(pipe->watch_queue);
+	}
+#endif
+
+	(void) account_pipe_buffers(pipe->user, pipe->nr_accounted, 0);
 	free_uid(pipe->user);
 	for (i = 0; i < pipe->ring_size; i++) {
 		struct pipe_buffer *buf = pipe->bufs + i;
@@ -906,6 +971,17 @@ int create_pipe_files(struct file **res, int flags)
 	if (!inode)
 		return -ENFILE;
 
+	if (flags & O_NOTIFICATION_PIPE) {
+#ifdef CONFIG_WATCH_QUEUE
+		if (watch_queue_init(inode->i_pipe) < 0) {
+			iput(inode);
+			return -ENOMEM;
+		}
+#else
+		return -ENOPKG;
+#endif
+	}
+
 	f = alloc_file_pseudo(inode, pipe_mnt, "",
 				O_WRONLY | (flags & (O_NONBLOCK | O_DIRECT)),
 				&pipefifo_fops);
@@ -936,7 +1012,7 @@ static int __do_pipe_flags(int *fd, struct file **files, int flags)
 	int error;
 	int fdw, fdr;
 
-	if (flags & ~(O_CLOEXEC | O_NONBLOCK | O_DIRECT))
+	if (flags & ~(O_CLOEXEC | O_NONBLOCK | O_DIRECT | O_NOTIFICATION_PIPE))
 		return -EINVAL;
 
 	error = create_pipe_files(files, flags);
@@ -1184,42 +1260,12 @@ unsigned int round_pipe_size(unsigned long size)
 }
 
 /*
- * Allocate a new array of pipe buffers and copy the info over. Returns the
- * pipe size if successful, or return -ERROR on error.
+ * Resize the pipe ring to a number of slots.
  */
-static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long arg)
+int pipe_resize_ring(struct pipe_inode_info *pipe, unsigned int nr_slots)
 {
 	struct pipe_buffer *bufs;
-	unsigned int size, nr_slots, head, tail, mask, n;
-	unsigned long user_bufs;
-	long ret = 0;
-
-	size = round_pipe_size(arg);
-	nr_slots = size >> PAGE_SHIFT;
-
-	if (!nr_slots)
-		return -EINVAL;
-
-	/*
-	 * If trying to increase the pipe capacity, check that an
-	 * unprivileged user is not trying to exceed various limits
-	 * (soft limit check here, hard limit check just below).
-	 * Decreasing the pipe capacity is always permitted, even
-	 * if the user is currently over a limit.
-	 */
-	if (nr_slots > pipe->ring_size &&
-			size > pipe_max_size && !capable(CAP_SYS_RESOURCE))
-		return -EPERM;
-
-	user_bufs = account_pipe_buffers(pipe->user, pipe->ring_size, nr_slots);
-
-	if (nr_slots > pipe->ring_size &&
-			(too_many_pipe_buffers_hard(user_bufs) ||
-			 too_many_pipe_buffers_soft(user_bufs)) &&
-			is_unprivileged_user()) {
-		ret = -EPERM;
-		goto out_revert_acct;
-	}
+	unsigned int head, tail, mask, n;
 
 	/*
 	 * We can shrink the pipe, if arg is greater than the ring occupancy.
@@ -1231,17 +1277,13 @@ static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long arg)
 	head = pipe->head;
 	tail = pipe->tail;
 	n = pipe_occupancy(pipe->head, pipe->tail);
-	if (nr_slots < n) {
-		ret = -EBUSY;
-		goto out_revert_acct;
-	}
+	if (nr_slots < n)
+		return -EBUSY;
 
 	bufs = kcalloc(nr_slots, sizeof(*bufs),
 		       GFP_KERNEL_ACCOUNT | __GFP_NOWARN);
-	if (unlikely(!bufs)) {
-		ret = -ENOMEM;
-		goto out_revert_acct;
-	}
+	if (unlikely(!bufs))
+		return -ENOMEM;
 
 	/*
 	 * The pipe array wraps around, so just start the new one at zero
@@ -1269,16 +1311,68 @@ static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long arg)
 	kfree(pipe->bufs);
 	pipe->bufs = bufs;
 	pipe->ring_size = nr_slots;
-	pipe->max_usage = nr_slots;
+	if (pipe->max_usage > nr_slots)
+		pipe->max_usage = nr_slots;
 	pipe->tail = tail;
 	pipe->head = head;
 
 	/* This might have made more room for writers */
 	wake_up_interruptible(&pipe->wr_wait);
+	return 0;
+}
+
+/*
+ * Allocate a new array of pipe buffers and copy the info over. Returns the
+ * pipe size if successful, or return -ERROR on error.
+ */
+static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long arg)
+{
+	unsigned long user_bufs;
+	unsigned int nr_slots, size;
+	long ret = 0;
+
+#ifdef CONFIG_WATCH_QUEUE
+	if (pipe->watch_queue)
+		return -EBUSY;
+#endif
+
+	size = round_pipe_size(arg);
+	nr_slots = size >> PAGE_SHIFT;
+
+	if (!nr_slots)
+		return -EINVAL;
+
+	/*
+	 * If trying to increase the pipe capacity, check that an
+	 * unprivileged user is not trying to exceed various limits
+	 * (soft limit check here, hard limit check just below).
+	 * Decreasing the pipe capacity is always permitted, even
+	 * if the user is currently over a limit.
+	 */
+	if (nr_slots > pipe->max_usage &&
+			size > pipe_max_size && !capable(CAP_SYS_RESOURCE))
+		return -EPERM;
+
+	user_bufs = account_pipe_buffers(pipe->user, pipe->nr_accounted, nr_slots);
+
+	if (nr_slots > pipe->max_usage &&
+			(too_many_pipe_buffers_hard(user_bufs) ||
+			 too_many_pipe_buffers_soft(user_bufs)) &&
+			pipe_is_unprivileged_user()) {
+		ret = -EPERM;
+		goto out_revert_acct;
+	}
+
+	ret = pipe_resize_ring(pipe, nr_slots);
+	if (ret < 0)
+		goto out_revert_acct;
+
+	pipe->max_usage = nr_slots;
+	pipe->nr_accounted = nr_slots;
 	return pipe->max_usage * PAGE_SIZE;
 
 out_revert_acct:
-	(void) account_pipe_buffers(pipe->user, nr_slots, pipe->ring_size);
+	(void) account_pipe_buffers(pipe->user, nr_slots, pipe->nr_accounted);
 	return ret;
 }
 
@@ -1287,9 +1381,17 @@ static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long arg)
  * location, so checking ->i_pipe is not enough to verify that this is a
  * pipe.
  */
-struct pipe_inode_info *get_pipe_info(struct file *file)
+struct pipe_inode_info *get_pipe_info(struct file *file, bool for_splice)
 {
-	return file->f_op == &pipefifo_fops ? file->private_data : NULL;
+	struct pipe_inode_info *pipe = file->private_data;
+
+	if (file->f_op != &pipefifo_fops || !pipe)
+		return NULL;
+#ifdef CONFIG_WATCH_QUEUE
+	if (for_splice && pipe->watch_queue)
+		return NULL;
+#endif
+	return pipe;
 }
 
 long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg)
@@ -1297,7 +1399,7 @@ long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg)
 	struct pipe_inode_info *pipe;
 	long ret;
 
-	pipe = get_pipe_info(file);
+	pipe = get_pipe_info(file, false);
 	if (!pipe)
 		return -EBADF;
 
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 6042b646ab27..788b19a0edc5 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -2758,6 +2758,15 @@ static const struct pid_entry smack_attr_dir_stuff[] = {
 LSM_DIR_OPS(smack);
 #endif
 
+#ifdef CONFIG_SECURITY_APPARMOR
+static const struct pid_entry apparmor_attr_dir_stuff[] = {
+	ATTR("apparmor", "current",	0666),
+	ATTR("apparmor", "prev",	0444),
+	ATTR("apparmor", "exec",	0666),
+};
+LSM_DIR_OPS(apparmor);
+#endif
+
 static const struct pid_entry attr_dir_stuff[] = {
 	ATTR(NULL, "current",		0666),
 	ATTR(NULL, "prev",		0444),
@@ -2769,6 +2778,10 @@ static const struct pid_entry attr_dir_stuff[] = {
 	DIR("smack",			0555,
 	    proc_smack_attr_dir_inode_ops, proc_smack_attr_dir_ops),
 #endif
+#ifdef CONFIG_SECURITY_APPARMOR
+	DIR("apparmor",			0555,
+	    proc_apparmor_attr_dir_inode_ops, proc_apparmor_attr_dir_ops),
+#endif
 };
 
 static int proc_attr_dir_readdir(struct file *file, struct dir_context *ctx)
diff --git a/fs/proc/page.c b/fs/proc/page.c
index f909243d4a66..f3b39a7d2bf3 100644
--- a/fs/proc/page.c
+++ b/fs/proc/page.c
@@ -115,7 +115,10 @@ u64 stable_page_flags(struct page *page)
 	 * it differentiates a memory hole from a page with no flags
 	 */
 	if (!page)
-		return 1 << KPF_NOPAGE;
+		return BIT_ULL(KPF_NOPAGE);
+
+	if (pfn_zone_device_reserved(page_to_pfn(page)))
+		return BIT_ULL(KPF_RESERVED);
 
 	k = page->flags;
 	u = 0;
@@ -127,22 +130,22 @@ u64 stable_page_flags(struct page *page)
 	 * simple test in page_mapped() is not enough.
 	 */
 	if (!PageSlab(page) && page_mapped(page))
-		u |= 1 << KPF_MMAP;
+		u |= BIT_ULL(KPF_MMAP);
 	if (PageAnon(page))
-		u |= 1 << KPF_ANON;
+		u |= BIT_ULL(KPF_ANON);
 	if (PageKsm(page))
-		u |= 1 << KPF_KSM;
+		u |= BIT_ULL(KPF_KSM);
 
 	/*
 	 * compound pages: export both head/tail info
 	 * they together define a compound page's start/end pos and order
 	 */
 	if (PageHead(page))
-		u |= 1 << KPF_COMPOUND_HEAD;
+		u |= BIT_ULL(KPF_COMPOUND_HEAD);
 	if (PageTail(page))
-		u |= 1 << KPF_COMPOUND_TAIL;
+		u |= BIT_ULL(KPF_COMPOUND_TAIL);
 	if (PageHuge(page))
-		u |= 1 << KPF_HUGE;
+		u |= BIT_ULL(KPF_HUGE);
 	/*
 	 * PageTransCompound can be true for non-huge compound pages (slab
 	 * pages or pages allocated by drivers with __GFP_COMP) because it
@@ -153,14 +156,13 @@ u64 stable_page_flags(struct page *page)
 		struct page *head = compound_head(page);
 
 		if (PageLRU(head) || PageAnon(head))
-			u |= 1 << KPF_THP;
+			u |= BIT_ULL(KPF_THP);
 		else if (is_huge_zero_page(head)) {
-			u |= 1 << KPF_ZERO_PAGE;
-			u |= 1 << KPF_THP;
+			u |= BIT_ULL(KPF_ZERO_PAGE);
+			u |= BIT_ULL(KPF_THP);
 		}
 	} else if (is_zero_pfn(page_to_pfn(page)))
-		u |= 1 << KPF_ZERO_PAGE;
-
+		u |= BIT_ULL(KPF_ZERO_PAGE);
 
 	/*
 	 * Caveats on high order pages: page->_refcount will only be set
@@ -168,23 +170,23 @@ u64 stable_page_flags(struct page *page)
 	 * SLOB won't set PG_slab at all on compound pages.
 	 */
 	if (PageBuddy(page))
-		u |= 1 << KPF_BUDDY;
+		u |= BIT_ULL(KPF_BUDDY);
 	else if (page_count(page) == 0 && is_free_buddy_page(page))
-		u |= 1 << KPF_BUDDY;
+		u |= BIT_ULL(KPF_BUDDY);
 
 	if (PageOffline(page))
-		u |= 1 << KPF_OFFLINE;
+		u |= BIT_ULL(KPF_OFFLINE);
 	if (PageTable(page))
-		u |= 1 << KPF_PGTABLE;
+		u |= BIT_ULL(KPF_PGTABLE);
 
 	if (page_is_idle(page))
-		u |= 1 << KPF_IDLE;
+		u |= BIT_ULL(KPF_IDLE);
 
 	u |= kpf_copy_bit(k, KPF_LOCKED,	PG_locked);
 
 	u |= kpf_copy_bit(k, KPF_SLAB,		PG_slab);
 	if (PageTail(page) && PageSlab(compound_head(page)))
-		u |= 1 << KPF_SLAB;
+		u |= BIT_ULL(KPF_SLAB);
 
 	u |= kpf_copy_bit(k, KPF_ERROR,		PG_error);
 	u |= kpf_copy_bit(k, KPF_DIRTY,		PG_dirty);
@@ -197,7 +199,7 @@ u64 stable_page_flags(struct page *page)
 	u |= kpf_copy_bit(k, KPF_RECLAIM,	PG_reclaim);
 
 	if (PageSwapCache(page))
-		u |= 1 << KPF_SWAPCACHE;
+		u |= BIT_ULL(KPF_SWAPCACHE);
 	u |= kpf_copy_bit(k, KPF_SWAPBACKED,	PG_swapbacked);
 
 	u |= kpf_copy_bit(k, KPF_UNEVICTABLE,	PG_unevictable);
diff --git a/fs/proc/root.c b/fs/proc/root.c
index 2633f10446c3..cdbe9293ea55 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -196,6 +196,13 @@ static void proc_kill_sb(struct super_block *sb)
 	if (ns->proc_thread_self)
 		dput(ns->proc_thread_self);
 	kill_anon_super(sb);
+
+	/* Make the pid namespace safe for the next mount of proc */
+	ns->proc_self = NULL;
+	ns->proc_thread_self = NULL;
+	ns->pid_gid = GLOBAL_ROOT_GID;
+	ns->hide_pid = 0;
+
 	put_pid_ns(ns);
 }
 
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c
index ee179a81b3da..55c1dc329bd2 100644
--- a/fs/ramfs/inode.c
+++ b/fs/ramfs/inode.c
@@ -147,6 +147,17 @@ static int ramfs_symlink(struct inode * dir, struct dentry *dentry, const char *
 	return error;
 }
 
+static int ramfs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
+{
+	struct inode *inode;
+
+	inode = ramfs_get_inode(dir->i_sb, dir, mode, 0);
+	if (!inode)
+		return -ENOSPC;
+	d_tmpfile(dentry, inode);
+	return 0;
+}
+
 static const struct inode_operations ramfs_dir_inode_operations = {
 	.create		= ramfs_create,
 	.lookup		= simple_lookup,
@@ -157,6 +168,7 @@ static const struct inode_operations ramfs_dir_inode_operations = {
 	.rmdir		= simple_rmdir,
 	.mknod		= ramfs_mknod,
 	.rename		= simple_rename,
+	.tmpfile	= ramfs_tmpfile,
 };
 
 /*
diff --git a/fs/splice.c b/fs/splice.c
index 4735defc46ee..86129b5cf7ea 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -1118,8 +1118,8 @@ long do_splice(struct file *in, loff_t __user *off_in,
 	loff_t offset;
 	long ret;
 
-	ipipe = get_pipe_info(in);
-	opipe = get_pipe_info(out);
+	ipipe = get_pipe_info(in, true);
+	opipe = get_pipe_info(out, true);
 
 	if (ipipe && opipe) {
 		if (off_in || off_out)
@@ -1278,7 +1278,7 @@ static int pipe_to_user(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
 static long vmsplice_to_user(struct file *file, struct iov_iter *iter,
 			     unsigned int flags)
 {
-	struct pipe_inode_info *pipe = get_pipe_info(file);
+	struct pipe_inode_info *pipe = get_pipe_info(file, true);
 	struct splice_desc sd = {
 		.total_len = iov_iter_count(iter),
 		.flags = flags,
@@ -1313,7 +1313,7 @@ static long vmsplice_to_pipe(struct file *file, struct iov_iter *iter,
 	if (flags & SPLICE_F_GIFT)
 		buf_flag = PIPE_BUF_FLAG_GIFT;
 
-	pipe = get_pipe_info(file);
+	pipe = get_pipe_info(file, true);
 	if (!pipe)
 		return -EBADF;
 
@@ -1766,8 +1766,8 @@ static int link_pipe(struct pipe_inode_info *ipipe,
 static long do_tee(struct file *in, struct file *out, size_t len,
 		   unsigned int flags)
 {
-	struct pipe_inode_info *ipipe = get_pipe_info(in);
-	struct pipe_inode_info *opipe = get_pipe_info(out);
+	struct pipe_inode_info *ipipe = get_pipe_info(in, true);
+	struct pipe_inode_info *opipe = get_pipe_info(out, true);
 	int ret = -EINVAL;
 
 	/*
diff --git a/fs/super.c b/fs/super.c
index cd352530eca9..7e3491b96e1d 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -361,7 +361,7 @@ EXPORT_SYMBOL(deactivate_locked_super);
  */
 void deactivate_super(struct super_block *s)
 {
-        if (!atomic_add_unless(&s->s_active, -1, 1)) {
+	if (!atomic_add_unless(&s->s_active, -1, 1)) {
 		down_write(&s->s_umount);
 		deactivate_locked_super(s);
 	}
diff --git a/fs/xattr.c b/fs/xattr.c
index e13265e65871..91608d9bfc6a 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -876,6 +876,9 @@ int simple_xattr_set(struct simple_xattrs *xattrs, const char *name,
 	struct simple_xattr *new_xattr = NULL;
 	int err = 0;
 
+	if (removed_size)
+		*removed_size = -1;
+
 	/* value == NULL means remove */
 	if (value) {
 		new_xattr = simple_xattr_alloc(value, size);
@@ -914,9 +917,6 @@ int simple_xattr_set(struct simple_xattrs *xattrs, const char *name,
 		list_add(&new_xattr->list, &xattrs->head);
 		xattr = NULL;
 	}
-
-	if (removed_size)
-		*removed_size = -1;
 out:
 	spin_unlock(&xattrs->lock);
 	if (xattr) {
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index a7be7a9e5c1a..8bf1d15be3f6 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -911,7 +911,12 @@ xfs_eofblocks_worker(
 {
 	struct xfs_mount *mp = container_of(to_delayed_work(work),
 				struct xfs_mount, m_eofblocks_work);
+
+	if (!sb_start_write_trylock(mp->m_super))
+		return;
 	xfs_icache_free_eofblocks(mp, NULL);
+	sb_end_write(mp->m_super);
+
 	xfs_queue_eofblocks(mp);
 }
 
@@ -938,7 +943,12 @@ xfs_cowblocks_worker(
 {
 	struct xfs_mount *mp = container_of(to_delayed_work(work),
 				struct xfs_mount, m_cowblocks_work);
+
+	if (!sb_start_write_trylock(mp->m_super))
+		return;
 	xfs_icache_free_cowblocks(mp, NULL);
+	sb_end_write(mp->m_super);
+
 	xfs_queue_cowblocks(mp);
 }
 
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index cdfb3cd9a25b..309958186d33 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -2363,7 +2363,10 @@ xfs_file_ioctl(
 		if (error)
 			return error;
 
-		return xfs_icache_free_eofblocks(mp, &keofb);
+		sb_start_write(mp->m_super);
+		error = xfs_icache_free_eofblocks(mp, &keofb);
+		sb_end_write(mp->m_super);
+		return error;
 	}
 
 	default:
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 50c43422fa17..b2e4598fdf7d 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -167,8 +167,12 @@ typedef struct xfs_mount {
 	struct xfs_kobj		m_error_meta_kobj;
 	struct xfs_error_cfg	m_error_cfg[XFS_ERR_CLASS_MAX][XFS_ERR_ERRNO_MAX];
 	struct xstats		m_stats;	/* per-fs stats */
-	struct ratelimit_state	m_flush_inodes_ratelimit;
 
+	/*
+	 * Workqueue item so that we can coalesce multiple inode flush attempts
+	 * into a single flush.
+	 */
+	struct work_struct	m_flush_inodes_work;
 	struct workqueue_struct *m_buf_workqueue;
 	struct workqueue_struct	*m_unwritten_workqueue;
 	struct workqueue_struct	*m_cil_workqueue;
diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c
index b0ce04ffd3cd..107bf2a2f344 100644
--- a/fs/xfs/xfs_reflink.c
+++ b/fs/xfs/xfs_reflink.c
@@ -1051,6 +1051,7 @@ xfs_reflink_remap_extent(
 		uirec.br_startblock = irec->br_startblock + rlen;
 		uirec.br_startoff = irec->br_startoff + rlen;
 		uirec.br_blockcount = unmap_len - rlen;
+		uirec.br_state = irec->br_state;
 		unmap_len = rlen;
 
 		/* If this isn't a real mapping, we're done. */
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index abf06bf9c3f3..424bb9a2d532 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -516,6 +516,20 @@ xfs_destroy_mount_workqueues(
 	destroy_workqueue(mp->m_buf_workqueue);
 }
 
+static void
+xfs_flush_inodes_worker(
+	struct work_struct	*work)
+{
+	struct xfs_mount	*mp = container_of(work, struct xfs_mount,
+						   m_flush_inodes_work);
+	struct super_block	*sb = mp->m_super;
+
+	if (down_read_trylock(&sb->s_umount)) {
+		sync_inodes_sb(sb);
+		up_read(&sb->s_umount);
+	}
+}
+
 /*
  * Flush all dirty data to disk. Must not be called while holding an XFS_ILOCK
  * or a page lock. We use sync_inodes_sb() here to ensure we block while waiting
@@ -526,15 +540,15 @@ void
 xfs_flush_inodes(
 	struct xfs_mount	*mp)
 {
-	struct super_block	*sb = mp->m_super;
-
-	if (!__ratelimit(&mp->m_flush_inodes_ratelimit))
+	/*
+	 * If flush_work() returns true then that means we waited for a flush
+	 * which was already in progress.  Don't bother running another scan.
+	 */
+	if (flush_work(&mp->m_flush_inodes_work))
 		return;
 
-	if (down_read_trylock(&sb->s_umount)) {
-		sync_inodes_sb(sb);
-		up_read(&sb->s_umount);
-	}
+	queue_work(mp->m_sync_workqueue, &mp->m_flush_inodes_work);
+	flush_work(&mp->m_flush_inodes_work);
 }
 
 /* Catch misguided souls that try to use this interface on XFS */
@@ -1369,17 +1383,6 @@ xfs_fc_fill_super(
 	if (error)
 		goto out_free_names;
 
-	/*
-	 * Cap the number of invocations of xfs_flush_inodes to 16 for every
-	 * quarter of a second.  The magic numbers here were determined by
-	 * observation neither to cause stalls in writeback when there are a
-	 * lot of IO threads and the fs is near ENOSPC, nor cause any fstest
-	 * regressions.  YMMV.
-	 */
-	ratelimit_state_init(&mp->m_flush_inodes_ratelimit, HZ / 4, 16);
-	ratelimit_set_flags(&mp->m_flush_inodes_ratelimit,
-			RATELIMIT_MSG_ON_RELEASE);
-
 	error = xfs_init_mount_workqueues(mp);
 	if (error)
 		goto out_close_devices;
@@ -1752,6 +1755,7 @@ static int xfs_init_fs_context(
 	spin_lock_init(&mp->m_perag_lock);
 	mutex_init(&mp->m_growlock);
 	atomic_set(&mp->m_active_trans, 0);
+	INIT_WORK(&mp->m_flush_inodes_work, xfs_flush_inodes_worker);
 	INIT_DELAYED_WORK(&mp->m_reclaim_work, xfs_reclaim_worker);
 	INIT_DELAYED_WORK(&mp->m_eofblocks_work, xfs_eofblocks_worker);
 	INIT_DELAYED_WORK(&mp->m_cowblocks_work, xfs_cowblocks_worker);
diff --git a/include/asm-generic/atomic-instrumented.h b/include/asm-generic/atomic-instrumented.h
index e8730c6b9fe2..379986e40159 100644
--- a/include/asm-generic/atomic-instrumented.h
+++ b/include/asm-generic/atomic-instrumented.h
@@ -18,1623 +18,1624 @@
 #define _ASM_GENERIC_ATOMIC_INSTRUMENTED_H
 
 #include <linux/build_bug.h>
-#include <linux/kasan-checks.h>
+#include <linux/compiler.h>
+#include <linux/instrumented.h>
 
-static inline int
+static __always_inline int
 atomic_read(const atomic_t *v)
 {
-	kasan_check_read(v, sizeof(*v));
+	instrument_atomic_read(v, sizeof(*v));
 	return arch_atomic_read(v);
 }
 #define atomic_read atomic_read
 
 #if defined(arch_atomic_read_acquire)
-static inline int
+static __always_inline int
 atomic_read_acquire(const atomic_t *v)
 {
-	kasan_check_read(v, sizeof(*v));
+	instrument_atomic_read(v, sizeof(*v));
 	return arch_atomic_read_acquire(v);
 }
 #define atomic_read_acquire atomic_read_acquire
 #endif
 
-static inline void
+static __always_inline void
 atomic_set(atomic_t *v, int i)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	arch_atomic_set(v, i);
 }
 #define atomic_set atomic_set
 
 #if defined(arch_atomic_set_release)
-static inline void
+static __always_inline void
 atomic_set_release(atomic_t *v, int i)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	arch_atomic_set_release(v, i);
 }
 #define atomic_set_release atomic_set_release
 #endif
 
-static inline void
+static __always_inline void
 atomic_add(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	arch_atomic_add(i, v);
 }
 #define atomic_add atomic_add
 
 #if !defined(arch_atomic_add_return_relaxed) || defined(arch_atomic_add_return)
-static inline int
+static __always_inline int
 atomic_add_return(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_add_return(i, v);
 }
 #define atomic_add_return atomic_add_return
 #endif
 
 #if defined(arch_atomic_add_return_acquire)
-static inline int
+static __always_inline int
 atomic_add_return_acquire(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_add_return_acquire(i, v);
 }
 #define atomic_add_return_acquire atomic_add_return_acquire
 #endif
 
 #if defined(arch_atomic_add_return_release)
-static inline int
+static __always_inline int
 atomic_add_return_release(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_add_return_release(i, v);
 }
 #define atomic_add_return_release atomic_add_return_release
 #endif
 
 #if defined(arch_atomic_add_return_relaxed)
-static inline int
+static __always_inline int
 atomic_add_return_relaxed(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_add_return_relaxed(i, v);
 }
 #define atomic_add_return_relaxed atomic_add_return_relaxed
 #endif
 
 #if !defined(arch_atomic_fetch_add_relaxed) || defined(arch_atomic_fetch_add)
-static inline int
+static __always_inline int
 atomic_fetch_add(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_fetch_add(i, v);
 }
 #define atomic_fetch_add atomic_fetch_add
 #endif
 
 #if defined(arch_atomic_fetch_add_acquire)
-static inline int
+static __always_inline int
 atomic_fetch_add_acquire(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_fetch_add_acquire(i, v);
 }
 #define atomic_fetch_add_acquire atomic_fetch_add_acquire
 #endif
 
 #if defined(arch_atomic_fetch_add_release)
-static inline int
+static __always_inline int
 atomic_fetch_add_release(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_fetch_add_release(i, v);
 }
 #define atomic_fetch_add_release atomic_fetch_add_release
 #endif
 
 #if defined(arch_atomic_fetch_add_relaxed)
-static inline int
+static __always_inline int
 atomic_fetch_add_relaxed(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_fetch_add_relaxed(i, v);
 }
 #define atomic_fetch_add_relaxed atomic_fetch_add_relaxed
 #endif
 
-static inline void
+static __always_inline void
 atomic_sub(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	arch_atomic_sub(i, v);
 }
 #define atomic_sub atomic_sub
 
 #if !defined(arch_atomic_sub_return_relaxed) || defined(arch_atomic_sub_return)
-static inline int
+static __always_inline int
 atomic_sub_return(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_sub_return(i, v);
 }
 #define atomic_sub_return atomic_sub_return
 #endif
 
 #if defined(arch_atomic_sub_return_acquire)
-static inline int
+static __always_inline int
 atomic_sub_return_acquire(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_sub_return_acquire(i, v);
 }
 #define atomic_sub_return_acquire atomic_sub_return_acquire
 #endif
 
 #if defined(arch_atomic_sub_return_release)
-static inline int
+static __always_inline int
 atomic_sub_return_release(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_sub_return_release(i, v);
 }
 #define atomic_sub_return_release atomic_sub_return_release
 #endif
 
 #if defined(arch_atomic_sub_return_relaxed)
-static inline int
+static __always_inline int
 atomic_sub_return_relaxed(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_sub_return_relaxed(i, v);
 }
 #define atomic_sub_return_relaxed atomic_sub_return_relaxed
 #endif
 
 #if !defined(arch_atomic_fetch_sub_relaxed) || defined(arch_atomic_fetch_sub)
-static inline int
+static __always_inline int
 atomic_fetch_sub(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_fetch_sub(i, v);
 }
 #define atomic_fetch_sub atomic_fetch_sub
 #endif
 
 #if defined(arch_atomic_fetch_sub_acquire)
-static inline int
+static __always_inline int
 atomic_fetch_sub_acquire(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_fetch_sub_acquire(i, v);
 }
 #define atomic_fetch_sub_acquire atomic_fetch_sub_acquire
 #endif
 
 #if defined(arch_atomic_fetch_sub_release)
-static inline int
+static __always_inline int
 atomic_fetch_sub_release(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_fetch_sub_release(i, v);
 }
 #define atomic_fetch_sub_release atomic_fetch_sub_release
 #endif
 
 #if defined(arch_atomic_fetch_sub_relaxed)
-static inline int
+static __always_inline int
 atomic_fetch_sub_relaxed(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_fetch_sub_relaxed(i, v);
 }
 #define atomic_fetch_sub_relaxed atomic_fetch_sub_relaxed
 #endif
 
 #if defined(arch_atomic_inc)
-static inline void
+static __always_inline void
 atomic_inc(atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	arch_atomic_inc(v);
 }
 #define atomic_inc atomic_inc
 #endif
 
 #if defined(arch_atomic_inc_return)
-static inline int
+static __always_inline int
 atomic_inc_return(atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_inc_return(v);
 }
 #define atomic_inc_return atomic_inc_return
 #endif
 
 #if defined(arch_atomic_inc_return_acquire)
-static inline int
+static __always_inline int
 atomic_inc_return_acquire(atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_inc_return_acquire(v);
 }
 #define atomic_inc_return_acquire atomic_inc_return_acquire
 #endif
 
 #if defined(arch_atomic_inc_return_release)
-static inline int
+static __always_inline int
 atomic_inc_return_release(atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_inc_return_release(v);
 }
 #define atomic_inc_return_release atomic_inc_return_release
 #endif
 
 #if defined(arch_atomic_inc_return_relaxed)
-static inline int
+static __always_inline int
 atomic_inc_return_relaxed(atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_inc_return_relaxed(v);
 }
 #define atomic_inc_return_relaxed atomic_inc_return_relaxed
 #endif
 
 #if defined(arch_atomic_fetch_inc)
-static inline int
+static __always_inline int
 atomic_fetch_inc(atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_fetch_inc(v);
 }
 #define atomic_fetch_inc atomic_fetch_inc
 #endif
 
 #if defined(arch_atomic_fetch_inc_acquire)
-static inline int
+static __always_inline int
 atomic_fetch_inc_acquire(atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_fetch_inc_acquire(v);
 }
 #define atomic_fetch_inc_acquire atomic_fetch_inc_acquire
 #endif
 
 #if defined(arch_atomic_fetch_inc_release)
-static inline int
+static __always_inline int
 atomic_fetch_inc_release(atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_fetch_inc_release(v);
 }
 #define atomic_fetch_inc_release atomic_fetch_inc_release
 #endif
 
 #if defined(arch_atomic_fetch_inc_relaxed)
-static inline int
+static __always_inline int
 atomic_fetch_inc_relaxed(atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_fetch_inc_relaxed(v);
 }
 #define atomic_fetch_inc_relaxed atomic_fetch_inc_relaxed
 #endif
 
 #if defined(arch_atomic_dec)
-static inline void
+static __always_inline void
 atomic_dec(atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	arch_atomic_dec(v);
 }
 #define atomic_dec atomic_dec
 #endif
 
 #if defined(arch_atomic_dec_return)
-static inline int
+static __always_inline int
 atomic_dec_return(atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_dec_return(v);
 }
 #define atomic_dec_return atomic_dec_return
 #endif
 
 #if defined(arch_atomic_dec_return_acquire)
-static inline int
+static __always_inline int
 atomic_dec_return_acquire(atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_dec_return_acquire(v);
 }
 #define atomic_dec_return_acquire atomic_dec_return_acquire
 #endif
 
 #if defined(arch_atomic_dec_return_release)
-static inline int
+static __always_inline int
 atomic_dec_return_release(atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_dec_return_release(v);
 }
 #define atomic_dec_return_release atomic_dec_return_release
 #endif
 
 #if defined(arch_atomic_dec_return_relaxed)
-static inline int
+static __always_inline int
 atomic_dec_return_relaxed(atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_dec_return_relaxed(v);
 }
 #define atomic_dec_return_relaxed atomic_dec_return_relaxed
 #endif
 
 #if defined(arch_atomic_fetch_dec)
-static inline int
+static __always_inline int
 atomic_fetch_dec(atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_fetch_dec(v);
 }
 #define atomic_fetch_dec atomic_fetch_dec
 #endif
 
 #if defined(arch_atomic_fetch_dec_acquire)
-static inline int
+static __always_inline int
 atomic_fetch_dec_acquire(atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_fetch_dec_acquire(v);
 }
 #define atomic_fetch_dec_acquire atomic_fetch_dec_acquire
 #endif
 
 #if defined(arch_atomic_fetch_dec_release)
-static inline int
+static __always_inline int
 atomic_fetch_dec_release(atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_fetch_dec_release(v);
 }
 #define atomic_fetch_dec_release atomic_fetch_dec_release
 #endif
 
 #if defined(arch_atomic_fetch_dec_relaxed)
-static inline int
+static __always_inline int
 atomic_fetch_dec_relaxed(atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_fetch_dec_relaxed(v);
 }
 #define atomic_fetch_dec_relaxed atomic_fetch_dec_relaxed
 #endif
 
-static inline void
+static __always_inline void
 atomic_and(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	arch_atomic_and(i, v);
 }
 #define atomic_and atomic_and
 
 #if !defined(arch_atomic_fetch_and_relaxed) || defined(arch_atomic_fetch_and)
-static inline int
+static __always_inline int
 atomic_fetch_and(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_fetch_and(i, v);
 }
 #define atomic_fetch_and atomic_fetch_and
 #endif
 
 #if defined(arch_atomic_fetch_and_acquire)
-static inline int
+static __always_inline int
 atomic_fetch_and_acquire(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_fetch_and_acquire(i, v);
 }
 #define atomic_fetch_and_acquire atomic_fetch_and_acquire
 #endif
 
 #if defined(arch_atomic_fetch_and_release)
-static inline int
+static __always_inline int
 atomic_fetch_and_release(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_fetch_and_release(i, v);
 }
 #define atomic_fetch_and_release atomic_fetch_and_release
 #endif
 
 #if defined(arch_atomic_fetch_and_relaxed)
-static inline int
+static __always_inline int
 atomic_fetch_and_relaxed(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_fetch_and_relaxed(i, v);
 }
 #define atomic_fetch_and_relaxed atomic_fetch_and_relaxed
 #endif
 
 #if defined(arch_atomic_andnot)
-static inline void
+static __always_inline void
 atomic_andnot(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	arch_atomic_andnot(i, v);
 }
 #define atomic_andnot atomic_andnot
 #endif
 
 #if defined(arch_atomic_fetch_andnot)
-static inline int
+static __always_inline int
 atomic_fetch_andnot(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_fetch_andnot(i, v);
 }
 #define atomic_fetch_andnot atomic_fetch_andnot
 #endif
 
 #if defined(arch_atomic_fetch_andnot_acquire)
-static inline int
+static __always_inline int
 atomic_fetch_andnot_acquire(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_fetch_andnot_acquire(i, v);
 }
 #define atomic_fetch_andnot_acquire atomic_fetch_andnot_acquire
 #endif
 
 #if defined(arch_atomic_fetch_andnot_release)
-static inline int
+static __always_inline int
 atomic_fetch_andnot_release(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_fetch_andnot_release(i, v);
 }
 #define atomic_fetch_andnot_release atomic_fetch_andnot_release
 #endif
 
 #if defined(arch_atomic_fetch_andnot_relaxed)
-static inline int
+static __always_inline int
 atomic_fetch_andnot_relaxed(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_fetch_andnot_relaxed(i, v);
 }
 #define atomic_fetch_andnot_relaxed atomic_fetch_andnot_relaxed
 #endif
 
-static inline void
+static __always_inline void
 atomic_or(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	arch_atomic_or(i, v);
 }
 #define atomic_or atomic_or
 
 #if !defined(arch_atomic_fetch_or_relaxed) || defined(arch_atomic_fetch_or)
-static inline int
+static __always_inline int
 atomic_fetch_or(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_fetch_or(i, v);
 }
 #define atomic_fetch_or atomic_fetch_or
 #endif
 
 #if defined(arch_atomic_fetch_or_acquire)
-static inline int
+static __always_inline int
 atomic_fetch_or_acquire(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_fetch_or_acquire(i, v);
 }
 #define atomic_fetch_or_acquire atomic_fetch_or_acquire
 #endif
 
 #if defined(arch_atomic_fetch_or_release)
-static inline int
+static __always_inline int
 atomic_fetch_or_release(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_fetch_or_release(i, v);
 }
 #define atomic_fetch_or_release atomic_fetch_or_release
 #endif
 
 #if defined(arch_atomic_fetch_or_relaxed)
-static inline int
+static __always_inline int
 atomic_fetch_or_relaxed(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_fetch_or_relaxed(i, v);
 }
 #define atomic_fetch_or_relaxed atomic_fetch_or_relaxed
 #endif
 
-static inline void
+static __always_inline void
 atomic_xor(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	arch_atomic_xor(i, v);
 }
 #define atomic_xor atomic_xor
 
 #if !defined(arch_atomic_fetch_xor_relaxed) || defined(arch_atomic_fetch_xor)
-static inline int
+static __always_inline int
 atomic_fetch_xor(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_fetch_xor(i, v);
 }
 #define atomic_fetch_xor atomic_fetch_xor
 #endif
 
 #if defined(arch_atomic_fetch_xor_acquire)
-static inline int
+static __always_inline int
 atomic_fetch_xor_acquire(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_fetch_xor_acquire(i, v);
 }
 #define atomic_fetch_xor_acquire atomic_fetch_xor_acquire
 #endif
 
 #if defined(arch_atomic_fetch_xor_release)
-static inline int
+static __always_inline int
 atomic_fetch_xor_release(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_fetch_xor_release(i, v);
 }
 #define atomic_fetch_xor_release atomic_fetch_xor_release
 #endif
 
 #if defined(arch_atomic_fetch_xor_relaxed)
-static inline int
+static __always_inline int
 atomic_fetch_xor_relaxed(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_fetch_xor_relaxed(i, v);
 }
 #define atomic_fetch_xor_relaxed atomic_fetch_xor_relaxed
 #endif
 
 #if !defined(arch_atomic_xchg_relaxed) || defined(arch_atomic_xchg)
-static inline int
+static __always_inline int
 atomic_xchg(atomic_t *v, int i)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_xchg(v, i);
 }
 #define atomic_xchg atomic_xchg
 #endif
 
 #if defined(arch_atomic_xchg_acquire)
-static inline int
+static __always_inline int
 atomic_xchg_acquire(atomic_t *v, int i)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_xchg_acquire(v, i);
 }
 #define atomic_xchg_acquire atomic_xchg_acquire
 #endif
 
 #if defined(arch_atomic_xchg_release)
-static inline int
+static __always_inline int
 atomic_xchg_release(atomic_t *v, int i)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_xchg_release(v, i);
 }
 #define atomic_xchg_release atomic_xchg_release
 #endif
 
 #if defined(arch_atomic_xchg_relaxed)
-static inline int
+static __always_inline int
 atomic_xchg_relaxed(atomic_t *v, int i)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_xchg_relaxed(v, i);
 }
 #define atomic_xchg_relaxed atomic_xchg_relaxed
 #endif
 
 #if !defined(arch_atomic_cmpxchg_relaxed) || defined(arch_atomic_cmpxchg)
-static inline int
+static __always_inline int
 atomic_cmpxchg(atomic_t *v, int old, int new)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_cmpxchg(v, old, new);
 }
 #define atomic_cmpxchg atomic_cmpxchg
 #endif
 
 #if defined(arch_atomic_cmpxchg_acquire)
-static inline int
+static __always_inline int
 atomic_cmpxchg_acquire(atomic_t *v, int old, int new)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_cmpxchg_acquire(v, old, new);
 }
 #define atomic_cmpxchg_acquire atomic_cmpxchg_acquire
 #endif
 
 #if defined(arch_atomic_cmpxchg_release)
-static inline int
+static __always_inline int
 atomic_cmpxchg_release(atomic_t *v, int old, int new)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_cmpxchg_release(v, old, new);
 }
 #define atomic_cmpxchg_release atomic_cmpxchg_release
 #endif
 
 #if defined(arch_atomic_cmpxchg_relaxed)
-static inline int
+static __always_inline int
 atomic_cmpxchg_relaxed(atomic_t *v, int old, int new)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_cmpxchg_relaxed(v, old, new);
 }
 #define atomic_cmpxchg_relaxed atomic_cmpxchg_relaxed
 #endif
 
 #if defined(arch_atomic_try_cmpxchg)
-static inline bool
+static __always_inline bool
 atomic_try_cmpxchg(atomic_t *v, int *old, int new)
 {
-	kasan_check_write(v, sizeof(*v));
-	kasan_check_write(old, sizeof(*old));
+	instrument_atomic_write(v, sizeof(*v));
+	instrument_atomic_write(old, sizeof(*old));
 	return arch_atomic_try_cmpxchg(v, old, new);
 }
 #define atomic_try_cmpxchg atomic_try_cmpxchg
 #endif
 
 #if defined(arch_atomic_try_cmpxchg_acquire)
-static inline bool
+static __always_inline bool
 atomic_try_cmpxchg_acquire(atomic_t *v, int *old, int new)
 {
-	kasan_check_write(v, sizeof(*v));
-	kasan_check_write(old, sizeof(*old));
+	instrument_atomic_write(v, sizeof(*v));
+	instrument_atomic_write(old, sizeof(*old));
 	return arch_atomic_try_cmpxchg_acquire(v, old, new);
 }
 #define atomic_try_cmpxchg_acquire atomic_try_cmpxchg_acquire
 #endif
 
 #if defined(arch_atomic_try_cmpxchg_release)
-static inline bool
+static __always_inline bool
 atomic_try_cmpxchg_release(atomic_t *v, int *old, int new)
 {
-	kasan_check_write(v, sizeof(*v));
-	kasan_check_write(old, sizeof(*old));
+	instrument_atomic_write(v, sizeof(*v));
+	instrument_atomic_write(old, sizeof(*old));
 	return arch_atomic_try_cmpxchg_release(v, old, new);
 }
 #define atomic_try_cmpxchg_release atomic_try_cmpxchg_release
 #endif
 
 #if defined(arch_atomic_try_cmpxchg_relaxed)
-static inline bool
+static __always_inline bool
 atomic_try_cmpxchg_relaxed(atomic_t *v, int *old, int new)
 {
-	kasan_check_write(v, sizeof(*v));
-	kasan_check_write(old, sizeof(*old));
+	instrument_atomic_write(v, sizeof(*v));
+	instrument_atomic_write(old, sizeof(*old));
 	return arch_atomic_try_cmpxchg_relaxed(v, old, new);
 }
 #define atomic_try_cmpxchg_relaxed atomic_try_cmpxchg_relaxed
 #endif
 
 #if defined(arch_atomic_sub_and_test)
-static inline bool
+static __always_inline bool
 atomic_sub_and_test(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_sub_and_test(i, v);
 }
 #define atomic_sub_and_test atomic_sub_and_test
 #endif
 
 #if defined(arch_atomic_dec_and_test)
-static inline bool
+static __always_inline bool
 atomic_dec_and_test(atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_dec_and_test(v);
 }
 #define atomic_dec_and_test atomic_dec_and_test
 #endif
 
 #if defined(arch_atomic_inc_and_test)
-static inline bool
+static __always_inline bool
 atomic_inc_and_test(atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_inc_and_test(v);
 }
 #define atomic_inc_and_test atomic_inc_and_test
 #endif
 
 #if defined(arch_atomic_add_negative)
-static inline bool
+static __always_inline bool
 atomic_add_negative(int i, atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_add_negative(i, v);
 }
 #define atomic_add_negative atomic_add_negative
 #endif
 
 #if defined(arch_atomic_fetch_add_unless)
-static inline int
+static __always_inline int
 atomic_fetch_add_unless(atomic_t *v, int a, int u)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_fetch_add_unless(v, a, u);
 }
 #define atomic_fetch_add_unless atomic_fetch_add_unless
 #endif
 
 #if defined(arch_atomic_add_unless)
-static inline bool
+static __always_inline bool
 atomic_add_unless(atomic_t *v, int a, int u)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_add_unless(v, a, u);
 }
 #define atomic_add_unless atomic_add_unless
 #endif
 
 #if defined(arch_atomic_inc_not_zero)
-static inline bool
+static __always_inline bool
 atomic_inc_not_zero(atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_inc_not_zero(v);
 }
 #define atomic_inc_not_zero atomic_inc_not_zero
 #endif
 
 #if defined(arch_atomic_inc_unless_negative)
-static inline bool
+static __always_inline bool
 atomic_inc_unless_negative(atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_inc_unless_negative(v);
 }
 #define atomic_inc_unless_negative atomic_inc_unless_negative
 #endif
 
 #if defined(arch_atomic_dec_unless_positive)
-static inline bool
+static __always_inline bool
 atomic_dec_unless_positive(atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_dec_unless_positive(v);
 }
 #define atomic_dec_unless_positive atomic_dec_unless_positive
 #endif
 
 #if defined(arch_atomic_dec_if_positive)
-static inline int
+static __always_inline int
 atomic_dec_if_positive(atomic_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic_dec_if_positive(v);
 }
 #define atomic_dec_if_positive atomic_dec_if_positive
 #endif
 
-static inline s64
+static __always_inline s64
 atomic64_read(const atomic64_t *v)
 {
-	kasan_check_read(v, sizeof(*v));
+	instrument_atomic_read(v, sizeof(*v));
 	return arch_atomic64_read(v);
 }
 #define atomic64_read atomic64_read
 
 #if defined(arch_atomic64_read_acquire)
-static inline s64
+static __always_inline s64
 atomic64_read_acquire(const atomic64_t *v)
 {
-	kasan_check_read(v, sizeof(*v));
+	instrument_atomic_read(v, sizeof(*v));
 	return arch_atomic64_read_acquire(v);
 }
 #define atomic64_read_acquire atomic64_read_acquire
 #endif
 
-static inline void
+static __always_inline void
 atomic64_set(atomic64_t *v, s64 i)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	arch_atomic64_set(v, i);
 }
 #define atomic64_set atomic64_set
 
 #if defined(arch_atomic64_set_release)
-static inline void
+static __always_inline void
 atomic64_set_release(atomic64_t *v, s64 i)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	arch_atomic64_set_release(v, i);
 }
 #define atomic64_set_release atomic64_set_release
 #endif
 
-static inline void
+static __always_inline void
 atomic64_add(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	arch_atomic64_add(i, v);
 }
 #define atomic64_add atomic64_add
 
 #if !defined(arch_atomic64_add_return_relaxed) || defined(arch_atomic64_add_return)
-static inline s64
+static __always_inline s64
 atomic64_add_return(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_add_return(i, v);
 }
 #define atomic64_add_return atomic64_add_return
 #endif
 
 #if defined(arch_atomic64_add_return_acquire)
-static inline s64
+static __always_inline s64
 atomic64_add_return_acquire(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_add_return_acquire(i, v);
 }
 #define atomic64_add_return_acquire atomic64_add_return_acquire
 #endif
 
 #if defined(arch_atomic64_add_return_release)
-static inline s64
+static __always_inline s64
 atomic64_add_return_release(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_add_return_release(i, v);
 }
 #define atomic64_add_return_release atomic64_add_return_release
 #endif
 
 #if defined(arch_atomic64_add_return_relaxed)
-static inline s64
+static __always_inline s64
 atomic64_add_return_relaxed(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_add_return_relaxed(i, v);
 }
 #define atomic64_add_return_relaxed atomic64_add_return_relaxed
 #endif
 
 #if !defined(arch_atomic64_fetch_add_relaxed) || defined(arch_atomic64_fetch_add)
-static inline s64
+static __always_inline s64
 atomic64_fetch_add(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_fetch_add(i, v);
 }
 #define atomic64_fetch_add atomic64_fetch_add
 #endif
 
 #if defined(arch_atomic64_fetch_add_acquire)
-static inline s64
+static __always_inline s64
 atomic64_fetch_add_acquire(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_fetch_add_acquire(i, v);
 }
 #define atomic64_fetch_add_acquire atomic64_fetch_add_acquire
 #endif
 
 #if defined(arch_atomic64_fetch_add_release)
-static inline s64
+static __always_inline s64
 atomic64_fetch_add_release(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_fetch_add_release(i, v);
 }
 #define atomic64_fetch_add_release atomic64_fetch_add_release
 #endif
 
 #if defined(arch_atomic64_fetch_add_relaxed)
-static inline s64
+static __always_inline s64
 atomic64_fetch_add_relaxed(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_fetch_add_relaxed(i, v);
 }
 #define atomic64_fetch_add_relaxed atomic64_fetch_add_relaxed
 #endif
 
-static inline void
+static __always_inline void
 atomic64_sub(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	arch_atomic64_sub(i, v);
 }
 #define atomic64_sub atomic64_sub
 
 #if !defined(arch_atomic64_sub_return_relaxed) || defined(arch_atomic64_sub_return)
-static inline s64
+static __always_inline s64
 atomic64_sub_return(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_sub_return(i, v);
 }
 #define atomic64_sub_return atomic64_sub_return
 #endif
 
 #if defined(arch_atomic64_sub_return_acquire)
-static inline s64
+static __always_inline s64
 atomic64_sub_return_acquire(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_sub_return_acquire(i, v);
 }
 #define atomic64_sub_return_acquire atomic64_sub_return_acquire
 #endif
 
 #if defined(arch_atomic64_sub_return_release)
-static inline s64
+static __always_inline s64
 atomic64_sub_return_release(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_sub_return_release(i, v);
 }
 #define atomic64_sub_return_release atomic64_sub_return_release
 #endif
 
 #if defined(arch_atomic64_sub_return_relaxed)
-static inline s64
+static __always_inline s64
 atomic64_sub_return_relaxed(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_sub_return_relaxed(i, v);
 }
 #define atomic64_sub_return_relaxed atomic64_sub_return_relaxed
 #endif
 
 #if !defined(arch_atomic64_fetch_sub_relaxed) || defined(arch_atomic64_fetch_sub)
-static inline s64
+static __always_inline s64
 atomic64_fetch_sub(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_fetch_sub(i, v);
 }
 #define atomic64_fetch_sub atomic64_fetch_sub
 #endif
 
 #if defined(arch_atomic64_fetch_sub_acquire)
-static inline s64
+static __always_inline s64
 atomic64_fetch_sub_acquire(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_fetch_sub_acquire(i, v);
 }
 #define atomic64_fetch_sub_acquire atomic64_fetch_sub_acquire
 #endif
 
 #if defined(arch_atomic64_fetch_sub_release)
-static inline s64
+static __always_inline s64
 atomic64_fetch_sub_release(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_fetch_sub_release(i, v);
 }
 #define atomic64_fetch_sub_release atomic64_fetch_sub_release
 #endif
 
 #if defined(arch_atomic64_fetch_sub_relaxed)
-static inline s64
+static __always_inline s64
 atomic64_fetch_sub_relaxed(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_fetch_sub_relaxed(i, v);
 }
 #define atomic64_fetch_sub_relaxed atomic64_fetch_sub_relaxed
 #endif
 
 #if defined(arch_atomic64_inc)
-static inline void
+static __always_inline void
 atomic64_inc(atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	arch_atomic64_inc(v);
 }
 #define atomic64_inc atomic64_inc
 #endif
 
 #if defined(arch_atomic64_inc_return)
-static inline s64
+static __always_inline s64
 atomic64_inc_return(atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_inc_return(v);
 }
 #define atomic64_inc_return atomic64_inc_return
 #endif
 
 #if defined(arch_atomic64_inc_return_acquire)
-static inline s64
+static __always_inline s64
 atomic64_inc_return_acquire(atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_inc_return_acquire(v);
 }
 #define atomic64_inc_return_acquire atomic64_inc_return_acquire
 #endif
 
 #if defined(arch_atomic64_inc_return_release)
-static inline s64
+static __always_inline s64
 atomic64_inc_return_release(atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_inc_return_release(v);
 }
 #define atomic64_inc_return_release atomic64_inc_return_release
 #endif
 
 #if defined(arch_atomic64_inc_return_relaxed)
-static inline s64
+static __always_inline s64
 atomic64_inc_return_relaxed(atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_inc_return_relaxed(v);
 }
 #define atomic64_inc_return_relaxed atomic64_inc_return_relaxed
 #endif
 
 #if defined(arch_atomic64_fetch_inc)
-static inline s64
+static __always_inline s64
 atomic64_fetch_inc(atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_fetch_inc(v);
 }
 #define atomic64_fetch_inc atomic64_fetch_inc
 #endif
 
 #if defined(arch_atomic64_fetch_inc_acquire)
-static inline s64
+static __always_inline s64
 atomic64_fetch_inc_acquire(atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_fetch_inc_acquire(v);
 }
 #define atomic64_fetch_inc_acquire atomic64_fetch_inc_acquire
 #endif
 
 #if defined(arch_atomic64_fetch_inc_release)
-static inline s64
+static __always_inline s64
 atomic64_fetch_inc_release(atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_fetch_inc_release(v);
 }
 #define atomic64_fetch_inc_release atomic64_fetch_inc_release
 #endif
 
 #if defined(arch_atomic64_fetch_inc_relaxed)
-static inline s64
+static __always_inline s64
 atomic64_fetch_inc_relaxed(atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_fetch_inc_relaxed(v);
 }
 #define atomic64_fetch_inc_relaxed atomic64_fetch_inc_relaxed
 #endif
 
 #if defined(arch_atomic64_dec)
-static inline void
+static __always_inline void
 atomic64_dec(atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	arch_atomic64_dec(v);
 }
 #define atomic64_dec atomic64_dec
 #endif
 
 #if defined(arch_atomic64_dec_return)
-static inline s64
+static __always_inline s64
 atomic64_dec_return(atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_dec_return(v);
 }
 #define atomic64_dec_return atomic64_dec_return
 #endif
 
 #if defined(arch_atomic64_dec_return_acquire)
-static inline s64
+static __always_inline s64
 atomic64_dec_return_acquire(atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_dec_return_acquire(v);
 }
 #define atomic64_dec_return_acquire atomic64_dec_return_acquire
 #endif
 
 #if defined(arch_atomic64_dec_return_release)
-static inline s64
+static __always_inline s64
 atomic64_dec_return_release(atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_dec_return_release(v);
 }
 #define atomic64_dec_return_release atomic64_dec_return_release
 #endif
 
 #if defined(arch_atomic64_dec_return_relaxed)
-static inline s64
+static __always_inline s64
 atomic64_dec_return_relaxed(atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_dec_return_relaxed(v);
 }
 #define atomic64_dec_return_relaxed atomic64_dec_return_relaxed
 #endif
 
 #if defined(arch_atomic64_fetch_dec)
-static inline s64
+static __always_inline s64
 atomic64_fetch_dec(atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_fetch_dec(v);
 }
 #define atomic64_fetch_dec atomic64_fetch_dec
 #endif
 
 #if defined(arch_atomic64_fetch_dec_acquire)
-static inline s64
+static __always_inline s64
 atomic64_fetch_dec_acquire(atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_fetch_dec_acquire(v);
 }
 #define atomic64_fetch_dec_acquire atomic64_fetch_dec_acquire
 #endif
 
 #if defined(arch_atomic64_fetch_dec_release)
-static inline s64
+static __always_inline s64
 atomic64_fetch_dec_release(atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_fetch_dec_release(v);
 }
 #define atomic64_fetch_dec_release atomic64_fetch_dec_release
 #endif
 
 #if defined(arch_atomic64_fetch_dec_relaxed)
-static inline s64
+static __always_inline s64
 atomic64_fetch_dec_relaxed(atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_fetch_dec_relaxed(v);
 }
 #define atomic64_fetch_dec_relaxed atomic64_fetch_dec_relaxed
 #endif
 
-static inline void
+static __always_inline void
 atomic64_and(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	arch_atomic64_and(i, v);
 }
 #define atomic64_and atomic64_and
 
 #if !defined(arch_atomic64_fetch_and_relaxed) || defined(arch_atomic64_fetch_and)
-static inline s64
+static __always_inline s64
 atomic64_fetch_and(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_fetch_and(i, v);
 }
 #define atomic64_fetch_and atomic64_fetch_and
 #endif
 
 #if defined(arch_atomic64_fetch_and_acquire)
-static inline s64
+static __always_inline s64
 atomic64_fetch_and_acquire(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_fetch_and_acquire(i, v);
 }
 #define atomic64_fetch_and_acquire atomic64_fetch_and_acquire
 #endif
 
 #if defined(arch_atomic64_fetch_and_release)
-static inline s64
+static __always_inline s64
 atomic64_fetch_and_release(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_fetch_and_release(i, v);
 }
 #define atomic64_fetch_and_release atomic64_fetch_and_release
 #endif
 
 #if defined(arch_atomic64_fetch_and_relaxed)
-static inline s64
+static __always_inline s64
 atomic64_fetch_and_relaxed(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_fetch_and_relaxed(i, v);
 }
 #define atomic64_fetch_and_relaxed atomic64_fetch_and_relaxed
 #endif
 
 #if defined(arch_atomic64_andnot)
-static inline void
+static __always_inline void
 atomic64_andnot(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	arch_atomic64_andnot(i, v);
 }
 #define atomic64_andnot atomic64_andnot
 #endif
 
 #if defined(arch_atomic64_fetch_andnot)
-static inline s64
+static __always_inline s64
 atomic64_fetch_andnot(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_fetch_andnot(i, v);
 }
 #define atomic64_fetch_andnot atomic64_fetch_andnot
 #endif
 
 #if defined(arch_atomic64_fetch_andnot_acquire)
-static inline s64
+static __always_inline s64
 atomic64_fetch_andnot_acquire(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_fetch_andnot_acquire(i, v);
 }
 #define atomic64_fetch_andnot_acquire atomic64_fetch_andnot_acquire
 #endif
 
 #if defined(arch_atomic64_fetch_andnot_release)
-static inline s64
+static __always_inline s64
 atomic64_fetch_andnot_release(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_fetch_andnot_release(i, v);
 }
 #define atomic64_fetch_andnot_release atomic64_fetch_andnot_release
 #endif
 
 #if defined(arch_atomic64_fetch_andnot_relaxed)
-static inline s64
+static __always_inline s64
 atomic64_fetch_andnot_relaxed(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_fetch_andnot_relaxed(i, v);
 }
 #define atomic64_fetch_andnot_relaxed atomic64_fetch_andnot_relaxed
 #endif
 
-static inline void
+static __always_inline void
 atomic64_or(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	arch_atomic64_or(i, v);
 }
 #define atomic64_or atomic64_or
 
 #if !defined(arch_atomic64_fetch_or_relaxed) || defined(arch_atomic64_fetch_or)
-static inline s64
+static __always_inline s64
 atomic64_fetch_or(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_fetch_or(i, v);
 }
 #define atomic64_fetch_or atomic64_fetch_or
 #endif
 
 #if defined(arch_atomic64_fetch_or_acquire)
-static inline s64
+static __always_inline s64
 atomic64_fetch_or_acquire(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_fetch_or_acquire(i, v);
 }
 #define atomic64_fetch_or_acquire atomic64_fetch_or_acquire
 #endif
 
 #if defined(arch_atomic64_fetch_or_release)
-static inline s64
+static __always_inline s64
 atomic64_fetch_or_release(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_fetch_or_release(i, v);
 }
 #define atomic64_fetch_or_release atomic64_fetch_or_release
 #endif
 
 #if defined(arch_atomic64_fetch_or_relaxed)
-static inline s64
+static __always_inline s64
 atomic64_fetch_or_relaxed(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_fetch_or_relaxed(i, v);
 }
 #define atomic64_fetch_or_relaxed atomic64_fetch_or_relaxed
 #endif
 
-static inline void
+static __always_inline void
 atomic64_xor(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	arch_atomic64_xor(i, v);
 }
 #define atomic64_xor atomic64_xor
 
 #if !defined(arch_atomic64_fetch_xor_relaxed) || defined(arch_atomic64_fetch_xor)
-static inline s64
+static __always_inline s64
 atomic64_fetch_xor(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_fetch_xor(i, v);
 }
 #define atomic64_fetch_xor atomic64_fetch_xor
 #endif
 
 #if defined(arch_atomic64_fetch_xor_acquire)
-static inline s64
+static __always_inline s64
 atomic64_fetch_xor_acquire(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_fetch_xor_acquire(i, v);
 }
 #define atomic64_fetch_xor_acquire atomic64_fetch_xor_acquire
 #endif
 
 #if defined(arch_atomic64_fetch_xor_release)
-static inline s64
+static __always_inline s64
 atomic64_fetch_xor_release(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_fetch_xor_release(i, v);
 }
 #define atomic64_fetch_xor_release atomic64_fetch_xor_release
 #endif
 
 #if defined(arch_atomic64_fetch_xor_relaxed)
-static inline s64
+static __always_inline s64
 atomic64_fetch_xor_relaxed(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_fetch_xor_relaxed(i, v);
 }
 #define atomic64_fetch_xor_relaxed atomic64_fetch_xor_relaxed
 #endif
 
 #if !defined(arch_atomic64_xchg_relaxed) || defined(arch_atomic64_xchg)
-static inline s64
+static __always_inline s64
 atomic64_xchg(atomic64_t *v, s64 i)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_xchg(v, i);
 }
 #define atomic64_xchg atomic64_xchg
 #endif
 
 #if defined(arch_atomic64_xchg_acquire)
-static inline s64
+static __always_inline s64
 atomic64_xchg_acquire(atomic64_t *v, s64 i)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_xchg_acquire(v, i);
 }
 #define atomic64_xchg_acquire atomic64_xchg_acquire
 #endif
 
 #if defined(arch_atomic64_xchg_release)
-static inline s64
+static __always_inline s64
 atomic64_xchg_release(atomic64_t *v, s64 i)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_xchg_release(v, i);
 }
 #define atomic64_xchg_release atomic64_xchg_release
 #endif
 
 #if defined(arch_atomic64_xchg_relaxed)
-static inline s64
+static __always_inline s64
 atomic64_xchg_relaxed(atomic64_t *v, s64 i)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_xchg_relaxed(v, i);
 }
 #define atomic64_xchg_relaxed atomic64_xchg_relaxed
 #endif
 
 #if !defined(arch_atomic64_cmpxchg_relaxed) || defined(arch_atomic64_cmpxchg)
-static inline s64
+static __always_inline s64
 atomic64_cmpxchg(atomic64_t *v, s64 old, s64 new)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_cmpxchg(v, old, new);
 }
 #define atomic64_cmpxchg atomic64_cmpxchg
 #endif
 
 #if defined(arch_atomic64_cmpxchg_acquire)
-static inline s64
+static __always_inline s64
 atomic64_cmpxchg_acquire(atomic64_t *v, s64 old, s64 new)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_cmpxchg_acquire(v, old, new);
 }
 #define atomic64_cmpxchg_acquire atomic64_cmpxchg_acquire
 #endif
 
 #if defined(arch_atomic64_cmpxchg_release)
-static inline s64
+static __always_inline s64
 atomic64_cmpxchg_release(atomic64_t *v, s64 old, s64 new)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_cmpxchg_release(v, old, new);
 }
 #define atomic64_cmpxchg_release atomic64_cmpxchg_release
 #endif
 
 #if defined(arch_atomic64_cmpxchg_relaxed)
-static inline s64
+static __always_inline s64
 atomic64_cmpxchg_relaxed(atomic64_t *v, s64 old, s64 new)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_cmpxchg_relaxed(v, old, new);
 }
 #define atomic64_cmpxchg_relaxed atomic64_cmpxchg_relaxed
 #endif
 
 #if defined(arch_atomic64_try_cmpxchg)
-static inline bool
+static __always_inline bool
 atomic64_try_cmpxchg(atomic64_t *v, s64 *old, s64 new)
 {
-	kasan_check_write(v, sizeof(*v));
-	kasan_check_write(old, sizeof(*old));
+	instrument_atomic_write(v, sizeof(*v));
+	instrument_atomic_write(old, sizeof(*old));
 	return arch_atomic64_try_cmpxchg(v, old, new);
 }
 #define atomic64_try_cmpxchg atomic64_try_cmpxchg
 #endif
 
 #if defined(arch_atomic64_try_cmpxchg_acquire)
-static inline bool
+static __always_inline bool
 atomic64_try_cmpxchg_acquire(atomic64_t *v, s64 *old, s64 new)
 {
-	kasan_check_write(v, sizeof(*v));
-	kasan_check_write(old, sizeof(*old));
+	instrument_atomic_write(v, sizeof(*v));
+	instrument_atomic_write(old, sizeof(*old));
 	return arch_atomic64_try_cmpxchg_acquire(v, old, new);
 }
 #define atomic64_try_cmpxchg_acquire atomic64_try_cmpxchg_acquire
 #endif
 
 #if defined(arch_atomic64_try_cmpxchg_release)
-static inline bool
+static __always_inline bool
 atomic64_try_cmpxchg_release(atomic64_t *v, s64 *old, s64 new)
 {
-	kasan_check_write(v, sizeof(*v));
-	kasan_check_write(old, sizeof(*old));
+	instrument_atomic_write(v, sizeof(*v));
+	instrument_atomic_write(old, sizeof(*old));
 	return arch_atomic64_try_cmpxchg_release(v, old, new);
 }
 #define atomic64_try_cmpxchg_release atomic64_try_cmpxchg_release
 #endif
 
 #if defined(arch_atomic64_try_cmpxchg_relaxed)
-static inline bool
+static __always_inline bool
 atomic64_try_cmpxchg_relaxed(atomic64_t *v, s64 *old, s64 new)
 {
-	kasan_check_write(v, sizeof(*v));
-	kasan_check_write(old, sizeof(*old));
+	instrument_atomic_write(v, sizeof(*v));
+	instrument_atomic_write(old, sizeof(*old));
 	return arch_atomic64_try_cmpxchg_relaxed(v, old, new);
 }
 #define atomic64_try_cmpxchg_relaxed atomic64_try_cmpxchg_relaxed
 #endif
 
 #if defined(arch_atomic64_sub_and_test)
-static inline bool
+static __always_inline bool
 atomic64_sub_and_test(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_sub_and_test(i, v);
 }
 #define atomic64_sub_and_test atomic64_sub_and_test
 #endif
 
 #if defined(arch_atomic64_dec_and_test)
-static inline bool
+static __always_inline bool
 atomic64_dec_and_test(atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_dec_and_test(v);
 }
 #define atomic64_dec_and_test atomic64_dec_and_test
 #endif
 
 #if defined(arch_atomic64_inc_and_test)
-static inline bool
+static __always_inline bool
 atomic64_inc_and_test(atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_inc_and_test(v);
 }
 #define atomic64_inc_and_test atomic64_inc_and_test
 #endif
 
 #if defined(arch_atomic64_add_negative)
-static inline bool
+static __always_inline bool
 atomic64_add_negative(s64 i, atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_add_negative(i, v);
 }
 #define atomic64_add_negative atomic64_add_negative
 #endif
 
 #if defined(arch_atomic64_fetch_add_unless)
-static inline s64
+static __always_inline s64
 atomic64_fetch_add_unless(atomic64_t *v, s64 a, s64 u)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_fetch_add_unless(v, a, u);
 }
 #define atomic64_fetch_add_unless atomic64_fetch_add_unless
 #endif
 
 #if defined(arch_atomic64_add_unless)
-static inline bool
+static __always_inline bool
 atomic64_add_unless(atomic64_t *v, s64 a, s64 u)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_add_unless(v, a, u);
 }
 #define atomic64_add_unless atomic64_add_unless
 #endif
 
 #if defined(arch_atomic64_inc_not_zero)
-static inline bool
+static __always_inline bool
 atomic64_inc_not_zero(atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_inc_not_zero(v);
 }
 #define atomic64_inc_not_zero atomic64_inc_not_zero
 #endif
 
 #if defined(arch_atomic64_inc_unless_negative)
-static inline bool
+static __always_inline bool
 atomic64_inc_unless_negative(atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_inc_unless_negative(v);
 }
 #define atomic64_inc_unless_negative atomic64_inc_unless_negative
 #endif
 
 #if defined(arch_atomic64_dec_unless_positive)
-static inline bool
+static __always_inline bool
 atomic64_dec_unless_positive(atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_dec_unless_positive(v);
 }
 #define atomic64_dec_unless_positive atomic64_dec_unless_positive
 #endif
 
 #if defined(arch_atomic64_dec_if_positive)
-static inline s64
+static __always_inline s64
 atomic64_dec_if_positive(atomic64_t *v)
 {
-	kasan_check_write(v, sizeof(*v));
+	instrument_atomic_write(v, sizeof(*v));
 	return arch_atomic64_dec_if_positive(v);
 }
 #define atomic64_dec_if_positive atomic64_dec_if_positive
@@ -1644,7 +1645,7 @@ atomic64_dec_if_positive(atomic64_t *v)
 #define xchg(ptr, ...)						\
 ({									\
 	typeof(ptr) __ai_ptr = (ptr);					\
-	kasan_check_write(__ai_ptr, sizeof(*__ai_ptr));		\
+	instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr));		\
 	arch_xchg(__ai_ptr, __VA_ARGS__);				\
 })
 #endif
@@ -1653,7 +1654,7 @@ atomic64_dec_if_positive(atomic64_t *v)
 #define xchg_acquire(ptr, ...)						\
 ({									\
 	typeof(ptr) __ai_ptr = (ptr);					\
-	kasan_check_write(__ai_ptr, sizeof(*__ai_ptr));		\
+	instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr));		\
 	arch_xchg_acquire(__ai_ptr, __VA_ARGS__);				\
 })
 #endif
@@ -1662,7 +1663,7 @@ atomic64_dec_if_positive(atomic64_t *v)
 #define xchg_release(ptr, ...)						\
 ({									\
 	typeof(ptr) __ai_ptr = (ptr);					\
-	kasan_check_write(__ai_ptr, sizeof(*__ai_ptr));		\
+	instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr));		\
 	arch_xchg_release(__ai_ptr, __VA_ARGS__);				\
 })
 #endif
@@ -1671,7 +1672,7 @@ atomic64_dec_if_positive(atomic64_t *v)
 #define xchg_relaxed(ptr, ...)						\
 ({									\
 	typeof(ptr) __ai_ptr = (ptr);					\
-	kasan_check_write(__ai_ptr, sizeof(*__ai_ptr));		\
+	instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr));		\
 	arch_xchg_relaxed(__ai_ptr, __VA_ARGS__);				\
 })
 #endif
@@ -1680,7 +1681,7 @@ atomic64_dec_if_positive(atomic64_t *v)
 #define cmpxchg(ptr, ...)						\
 ({									\
 	typeof(ptr) __ai_ptr = (ptr);					\
-	kasan_check_write(__ai_ptr, sizeof(*__ai_ptr));		\
+	instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr));		\
 	arch_cmpxchg(__ai_ptr, __VA_ARGS__);				\
 })
 #endif
@@ -1689,7 +1690,7 @@ atomic64_dec_if_positive(atomic64_t *v)
 #define cmpxchg_acquire(ptr, ...)						\
 ({									\
 	typeof(ptr) __ai_ptr = (ptr);					\
-	kasan_check_write(__ai_ptr, sizeof(*__ai_ptr));		\
+	instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr));		\
 	arch_cmpxchg_acquire(__ai_ptr, __VA_ARGS__);				\
 })
 #endif
@@ -1698,7 +1699,7 @@ atomic64_dec_if_positive(atomic64_t *v)
 #define cmpxchg_release(ptr, ...)						\
 ({									\
 	typeof(ptr) __ai_ptr = (ptr);					\
-	kasan_check_write(__ai_ptr, sizeof(*__ai_ptr));		\
+	instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr));		\
 	arch_cmpxchg_release(__ai_ptr, __VA_ARGS__);				\
 })
 #endif
@@ -1707,7 +1708,7 @@ atomic64_dec_if_positive(atomic64_t *v)
 #define cmpxchg_relaxed(ptr, ...)						\
 ({									\
 	typeof(ptr) __ai_ptr = (ptr);					\
-	kasan_check_write(__ai_ptr, sizeof(*__ai_ptr));		\
+	instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr));		\
 	arch_cmpxchg_relaxed(__ai_ptr, __VA_ARGS__);				\
 })
 #endif
@@ -1716,7 +1717,7 @@ atomic64_dec_if_positive(atomic64_t *v)
 #define cmpxchg64(ptr, ...)						\
 ({									\
 	typeof(ptr) __ai_ptr = (ptr);					\
-	kasan_check_write(__ai_ptr, sizeof(*__ai_ptr));		\
+	instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr));		\
 	arch_cmpxchg64(__ai_ptr, __VA_ARGS__);				\
 })
 #endif
@@ -1725,7 +1726,7 @@ atomic64_dec_if_positive(atomic64_t *v)
 #define cmpxchg64_acquire(ptr, ...)						\
 ({									\
 	typeof(ptr) __ai_ptr = (ptr);					\
-	kasan_check_write(__ai_ptr, sizeof(*__ai_ptr));		\
+	instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr));		\
 	arch_cmpxchg64_acquire(__ai_ptr, __VA_ARGS__);				\
 })
 #endif
@@ -1734,7 +1735,7 @@ atomic64_dec_if_positive(atomic64_t *v)
 #define cmpxchg64_release(ptr, ...)						\
 ({									\
 	typeof(ptr) __ai_ptr = (ptr);					\
-	kasan_check_write(__ai_ptr, sizeof(*__ai_ptr));		\
+	instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr));		\
 	arch_cmpxchg64_release(__ai_ptr, __VA_ARGS__);				\
 })
 #endif
@@ -1743,7 +1744,7 @@ atomic64_dec_if_positive(atomic64_t *v)
 #define cmpxchg64_relaxed(ptr, ...)						\
 ({									\
 	typeof(ptr) __ai_ptr = (ptr);					\
-	kasan_check_write(__ai_ptr, sizeof(*__ai_ptr));		\
+	instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr));		\
 	arch_cmpxchg64_relaxed(__ai_ptr, __VA_ARGS__);				\
 })
 #endif
@@ -1751,28 +1752,28 @@ atomic64_dec_if_positive(atomic64_t *v)
 #define cmpxchg_local(ptr, ...)						\
 ({									\
 	typeof(ptr) __ai_ptr = (ptr);					\
-	kasan_check_write(__ai_ptr, sizeof(*__ai_ptr));		\
+	instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr));		\
 	arch_cmpxchg_local(__ai_ptr, __VA_ARGS__);				\
 })
 
 #define cmpxchg64_local(ptr, ...)						\
 ({									\
 	typeof(ptr) __ai_ptr = (ptr);					\
-	kasan_check_write(__ai_ptr, sizeof(*__ai_ptr));		\
+	instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr));		\
 	arch_cmpxchg64_local(__ai_ptr, __VA_ARGS__);				\
 })
 
 #define sync_cmpxchg(ptr, ...)						\
 ({									\
 	typeof(ptr) __ai_ptr = (ptr);					\
-	kasan_check_write(__ai_ptr, sizeof(*__ai_ptr));		\
+	instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr));		\
 	arch_sync_cmpxchg(__ai_ptr, __VA_ARGS__);				\
 })
 
 #define cmpxchg_double(ptr, ...)						\
 ({									\
 	typeof(ptr) __ai_ptr = (ptr);					\
-	kasan_check_write(__ai_ptr, 2 * sizeof(*__ai_ptr));		\
+	instrument_atomic_write(__ai_ptr, 2 * sizeof(*__ai_ptr));		\
 	arch_cmpxchg_double(__ai_ptr, __VA_ARGS__);				\
 })
 
@@ -1780,9 +1781,9 @@ atomic64_dec_if_positive(atomic64_t *v)
 #define cmpxchg_double_local(ptr, ...)						\
 ({									\
 	typeof(ptr) __ai_ptr = (ptr);					\
-	kasan_check_write(__ai_ptr, 2 * sizeof(*__ai_ptr));		\
+	instrument_atomic_write(__ai_ptr, 2 * sizeof(*__ai_ptr));		\
 	arch_cmpxchg_double_local(__ai_ptr, __VA_ARGS__);				\
 })
 
 #endif /* _ASM_GENERIC_ATOMIC_INSTRUMENTED_H */
-// b29b625d5de9280f680e42c7be859b55b15e5f6a
+// 89bf97f3a7509b740845e51ddf31055b48a81f40
diff --git a/include/asm-generic/atomic-long.h b/include/asm-generic/atomic-long.h
index 881c7e27af28..073cf40f431b 100644
--- a/include/asm-generic/atomic-long.h
+++ b/include/asm-generic/atomic-long.h
@@ -6,6 +6,7 @@
 #ifndef _ASM_GENERIC_ATOMIC_LONG_H
 #define _ASM_GENERIC_ATOMIC_LONG_H
 
+#include <linux/compiler.h>
 #include <asm/types.h>
 
 #ifdef CONFIG_64BIT
@@ -22,493 +23,493 @@ typedef atomic_t atomic_long_t;
 
 #ifdef CONFIG_64BIT
 
-static inline long
+static __always_inline long
 atomic_long_read(const atomic_long_t *v)
 {
 	return atomic64_read(v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_read_acquire(const atomic_long_t *v)
 {
 	return atomic64_read_acquire(v);
 }
 
-static inline void
+static __always_inline void
 atomic_long_set(atomic_long_t *v, long i)
 {
 	atomic64_set(v, i);
 }
 
-static inline void
+static __always_inline void
 atomic_long_set_release(atomic_long_t *v, long i)
 {
 	atomic64_set_release(v, i);
 }
 
-static inline void
+static __always_inline void
 atomic_long_add(long i, atomic_long_t *v)
 {
 	atomic64_add(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_add_return(long i, atomic_long_t *v)
 {
 	return atomic64_add_return(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_add_return_acquire(long i, atomic_long_t *v)
 {
 	return atomic64_add_return_acquire(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_add_return_release(long i, atomic_long_t *v)
 {
 	return atomic64_add_return_release(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_add_return_relaxed(long i, atomic_long_t *v)
 {
 	return atomic64_add_return_relaxed(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_add(long i, atomic_long_t *v)
 {
 	return atomic64_fetch_add(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_add_acquire(long i, atomic_long_t *v)
 {
 	return atomic64_fetch_add_acquire(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_add_release(long i, atomic_long_t *v)
 {
 	return atomic64_fetch_add_release(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_add_relaxed(long i, atomic_long_t *v)
 {
 	return atomic64_fetch_add_relaxed(i, v);
 }
 
-static inline void
+static __always_inline void
 atomic_long_sub(long i, atomic_long_t *v)
 {
 	atomic64_sub(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_sub_return(long i, atomic_long_t *v)
 {
 	return atomic64_sub_return(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_sub_return_acquire(long i, atomic_long_t *v)
 {
 	return atomic64_sub_return_acquire(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_sub_return_release(long i, atomic_long_t *v)
 {
 	return atomic64_sub_return_release(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_sub_return_relaxed(long i, atomic_long_t *v)
 {
 	return atomic64_sub_return_relaxed(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_sub(long i, atomic_long_t *v)
 {
 	return atomic64_fetch_sub(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_sub_acquire(long i, atomic_long_t *v)
 {
 	return atomic64_fetch_sub_acquire(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_sub_release(long i, atomic_long_t *v)
 {
 	return atomic64_fetch_sub_release(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_sub_relaxed(long i, atomic_long_t *v)
 {
 	return atomic64_fetch_sub_relaxed(i, v);
 }
 
-static inline void
+static __always_inline void
 atomic_long_inc(atomic_long_t *v)
 {
 	atomic64_inc(v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_inc_return(atomic_long_t *v)
 {
 	return atomic64_inc_return(v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_inc_return_acquire(atomic_long_t *v)
 {
 	return atomic64_inc_return_acquire(v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_inc_return_release(atomic_long_t *v)
 {
 	return atomic64_inc_return_release(v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_inc_return_relaxed(atomic_long_t *v)
 {
 	return atomic64_inc_return_relaxed(v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_inc(atomic_long_t *v)
 {
 	return atomic64_fetch_inc(v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_inc_acquire(atomic_long_t *v)
 {
 	return atomic64_fetch_inc_acquire(v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_inc_release(atomic_long_t *v)
 {
 	return atomic64_fetch_inc_release(v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_inc_relaxed(atomic_long_t *v)
 {
 	return atomic64_fetch_inc_relaxed(v);
 }
 
-static inline void
+static __always_inline void
 atomic_long_dec(atomic_long_t *v)
 {
 	atomic64_dec(v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_dec_return(atomic_long_t *v)
 {
 	return atomic64_dec_return(v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_dec_return_acquire(atomic_long_t *v)
 {
 	return atomic64_dec_return_acquire(v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_dec_return_release(atomic_long_t *v)
 {
 	return atomic64_dec_return_release(v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_dec_return_relaxed(atomic_long_t *v)
 {
 	return atomic64_dec_return_relaxed(v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_dec(atomic_long_t *v)
 {
 	return atomic64_fetch_dec(v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_dec_acquire(atomic_long_t *v)
 {
 	return atomic64_fetch_dec_acquire(v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_dec_release(atomic_long_t *v)
 {
 	return atomic64_fetch_dec_release(v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_dec_relaxed(atomic_long_t *v)
 {
 	return atomic64_fetch_dec_relaxed(v);
 }
 
-static inline void
+static __always_inline void
 atomic_long_and(long i, atomic_long_t *v)
 {
 	atomic64_and(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_and(long i, atomic_long_t *v)
 {
 	return atomic64_fetch_and(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_and_acquire(long i, atomic_long_t *v)
 {
 	return atomic64_fetch_and_acquire(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_and_release(long i, atomic_long_t *v)
 {
 	return atomic64_fetch_and_release(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_and_relaxed(long i, atomic_long_t *v)
 {
 	return atomic64_fetch_and_relaxed(i, v);
 }
 
-static inline void
+static __always_inline void
 atomic_long_andnot(long i, atomic_long_t *v)
 {
 	atomic64_andnot(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_andnot(long i, atomic_long_t *v)
 {
 	return atomic64_fetch_andnot(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_andnot_acquire(long i, atomic_long_t *v)
 {
 	return atomic64_fetch_andnot_acquire(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_andnot_release(long i, atomic_long_t *v)
 {
 	return atomic64_fetch_andnot_release(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_andnot_relaxed(long i, atomic_long_t *v)
 {
 	return atomic64_fetch_andnot_relaxed(i, v);
 }
 
-static inline void
+static __always_inline void
 atomic_long_or(long i, atomic_long_t *v)
 {
 	atomic64_or(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_or(long i, atomic_long_t *v)
 {
 	return atomic64_fetch_or(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_or_acquire(long i, atomic_long_t *v)
 {
 	return atomic64_fetch_or_acquire(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_or_release(long i, atomic_long_t *v)
 {
 	return atomic64_fetch_or_release(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_or_relaxed(long i, atomic_long_t *v)
 {
 	return atomic64_fetch_or_relaxed(i, v);
 }
 
-static inline void
+static __always_inline void
 atomic_long_xor(long i, atomic_long_t *v)
 {
 	atomic64_xor(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_xor(long i, atomic_long_t *v)
 {
 	return atomic64_fetch_xor(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_xor_acquire(long i, atomic_long_t *v)
 {
 	return atomic64_fetch_xor_acquire(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_xor_release(long i, atomic_long_t *v)
 {
 	return atomic64_fetch_xor_release(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_xor_relaxed(long i, atomic_long_t *v)
 {
 	return atomic64_fetch_xor_relaxed(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_xchg(atomic_long_t *v, long i)
 {
 	return atomic64_xchg(v, i);
 }
 
-static inline long
+static __always_inline long
 atomic_long_xchg_acquire(atomic_long_t *v, long i)
 {
 	return atomic64_xchg_acquire(v, i);
 }
 
-static inline long
+static __always_inline long
 atomic_long_xchg_release(atomic_long_t *v, long i)
 {
 	return atomic64_xchg_release(v, i);
 }
 
-static inline long
+static __always_inline long
 atomic_long_xchg_relaxed(atomic_long_t *v, long i)
 {
 	return atomic64_xchg_relaxed(v, i);
 }
 
-static inline long
+static __always_inline long
 atomic_long_cmpxchg(atomic_long_t *v, long old, long new)
 {
 	return atomic64_cmpxchg(v, old, new);
 }
 
-static inline long
+static __always_inline long
 atomic_long_cmpxchg_acquire(atomic_long_t *v, long old, long new)
 {
 	return atomic64_cmpxchg_acquire(v, old, new);
 }
 
-static inline long
+static __always_inline long
 atomic_long_cmpxchg_release(atomic_long_t *v, long old, long new)
 {
 	return atomic64_cmpxchg_release(v, old, new);
 }
 
-static inline long
+static __always_inline long
 atomic_long_cmpxchg_relaxed(atomic_long_t *v, long old, long new)
 {
 	return atomic64_cmpxchg_relaxed(v, old, new);
 }
 
-static inline bool
+static __always_inline bool
 atomic_long_try_cmpxchg(atomic_long_t *v, long *old, long new)
 {
 	return atomic64_try_cmpxchg(v, (s64 *)old, new);
 }
 
-static inline bool
+static __always_inline bool
 atomic_long_try_cmpxchg_acquire(atomic_long_t *v, long *old, long new)
 {
 	return atomic64_try_cmpxchg_acquire(v, (s64 *)old, new);
 }
 
-static inline bool
+static __always_inline bool
 atomic_long_try_cmpxchg_release(atomic_long_t *v, long *old, long new)
 {
 	return atomic64_try_cmpxchg_release(v, (s64 *)old, new);
 }
 
-static inline bool
+static __always_inline bool
 atomic_long_try_cmpxchg_relaxed(atomic_long_t *v, long *old, long new)
 {
 	return atomic64_try_cmpxchg_relaxed(v, (s64 *)old, new);
 }
 
-static inline bool
+static __always_inline bool
 atomic_long_sub_and_test(long i, atomic_long_t *v)
 {
 	return atomic64_sub_and_test(i, v);
 }
 
-static inline bool
+static __always_inline bool
 atomic_long_dec_and_test(atomic_long_t *v)
 {
 	return atomic64_dec_and_test(v);
 }
 
-static inline bool
+static __always_inline bool
 atomic_long_inc_and_test(atomic_long_t *v)
 {
 	return atomic64_inc_and_test(v);
 }
 
-static inline bool
+static __always_inline bool
 atomic_long_add_negative(long i, atomic_long_t *v)
 {
 	return atomic64_add_negative(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_add_unless(atomic_long_t *v, long a, long u)
 {
 	return atomic64_fetch_add_unless(v, a, u);
 }
 
-static inline bool
+static __always_inline bool
 atomic_long_add_unless(atomic_long_t *v, long a, long u)
 {
 	return atomic64_add_unless(v, a, u);
 }
 
-static inline bool
+static __always_inline bool
 atomic_long_inc_not_zero(atomic_long_t *v)
 {
 	return atomic64_inc_not_zero(v);
 }
 
-static inline bool
+static __always_inline bool
 atomic_long_inc_unless_negative(atomic_long_t *v)
 {
 	return atomic64_inc_unless_negative(v);
 }
 
-static inline bool
+static __always_inline bool
 atomic_long_dec_unless_positive(atomic_long_t *v)
 {
 	return atomic64_dec_unless_positive(v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_dec_if_positive(atomic_long_t *v)
 {
 	return atomic64_dec_if_positive(v);
@@ -516,493 +517,493 @@ atomic_long_dec_if_positive(atomic_long_t *v)
 
 #else /* CONFIG_64BIT */
 
-static inline long
+static __always_inline long
 atomic_long_read(const atomic_long_t *v)
 {
 	return atomic_read(v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_read_acquire(const atomic_long_t *v)
 {
 	return atomic_read_acquire(v);
 }
 
-static inline void
+static __always_inline void
 atomic_long_set(atomic_long_t *v, long i)
 {
 	atomic_set(v, i);
 }
 
-static inline void
+static __always_inline void
 atomic_long_set_release(atomic_long_t *v, long i)
 {
 	atomic_set_release(v, i);
 }
 
-static inline void
+static __always_inline void
 atomic_long_add(long i, atomic_long_t *v)
 {
 	atomic_add(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_add_return(long i, atomic_long_t *v)
 {
 	return atomic_add_return(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_add_return_acquire(long i, atomic_long_t *v)
 {
 	return atomic_add_return_acquire(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_add_return_release(long i, atomic_long_t *v)
 {
 	return atomic_add_return_release(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_add_return_relaxed(long i, atomic_long_t *v)
 {
 	return atomic_add_return_relaxed(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_add(long i, atomic_long_t *v)
 {
 	return atomic_fetch_add(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_add_acquire(long i, atomic_long_t *v)
 {
 	return atomic_fetch_add_acquire(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_add_release(long i, atomic_long_t *v)
 {
 	return atomic_fetch_add_release(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_add_relaxed(long i, atomic_long_t *v)
 {
 	return atomic_fetch_add_relaxed(i, v);
 }
 
-static inline void
+static __always_inline void
 atomic_long_sub(long i, atomic_long_t *v)
 {
 	atomic_sub(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_sub_return(long i, atomic_long_t *v)
 {
 	return atomic_sub_return(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_sub_return_acquire(long i, atomic_long_t *v)
 {
 	return atomic_sub_return_acquire(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_sub_return_release(long i, atomic_long_t *v)
 {
 	return atomic_sub_return_release(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_sub_return_relaxed(long i, atomic_long_t *v)
 {
 	return atomic_sub_return_relaxed(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_sub(long i, atomic_long_t *v)
 {
 	return atomic_fetch_sub(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_sub_acquire(long i, atomic_long_t *v)
 {
 	return atomic_fetch_sub_acquire(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_sub_release(long i, atomic_long_t *v)
 {
 	return atomic_fetch_sub_release(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_sub_relaxed(long i, atomic_long_t *v)
 {
 	return atomic_fetch_sub_relaxed(i, v);
 }
 
-static inline void
+static __always_inline void
 atomic_long_inc(atomic_long_t *v)
 {
 	atomic_inc(v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_inc_return(atomic_long_t *v)
 {
 	return atomic_inc_return(v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_inc_return_acquire(atomic_long_t *v)
 {
 	return atomic_inc_return_acquire(v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_inc_return_release(atomic_long_t *v)
 {
 	return atomic_inc_return_release(v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_inc_return_relaxed(atomic_long_t *v)
 {
 	return atomic_inc_return_relaxed(v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_inc(atomic_long_t *v)
 {
 	return atomic_fetch_inc(v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_inc_acquire(atomic_long_t *v)
 {
 	return atomic_fetch_inc_acquire(v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_inc_release(atomic_long_t *v)
 {
 	return atomic_fetch_inc_release(v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_inc_relaxed(atomic_long_t *v)
 {
 	return atomic_fetch_inc_relaxed(v);
 }
 
-static inline void
+static __always_inline void
 atomic_long_dec(atomic_long_t *v)
 {
 	atomic_dec(v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_dec_return(atomic_long_t *v)
 {
 	return atomic_dec_return(v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_dec_return_acquire(atomic_long_t *v)
 {
 	return atomic_dec_return_acquire(v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_dec_return_release(atomic_long_t *v)
 {
 	return atomic_dec_return_release(v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_dec_return_relaxed(atomic_long_t *v)
 {
 	return atomic_dec_return_relaxed(v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_dec(atomic_long_t *v)
 {
 	return atomic_fetch_dec(v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_dec_acquire(atomic_long_t *v)
 {
 	return atomic_fetch_dec_acquire(v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_dec_release(atomic_long_t *v)
 {
 	return atomic_fetch_dec_release(v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_dec_relaxed(atomic_long_t *v)
 {
 	return atomic_fetch_dec_relaxed(v);
 }
 
-static inline void
+static __always_inline void
 atomic_long_and(long i, atomic_long_t *v)
 {
 	atomic_and(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_and(long i, atomic_long_t *v)
 {
 	return atomic_fetch_and(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_and_acquire(long i, atomic_long_t *v)
 {
 	return atomic_fetch_and_acquire(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_and_release(long i, atomic_long_t *v)
 {
 	return atomic_fetch_and_release(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_and_relaxed(long i, atomic_long_t *v)
 {
 	return atomic_fetch_and_relaxed(i, v);
 }
 
-static inline void
+static __always_inline void
 atomic_long_andnot(long i, atomic_long_t *v)
 {
 	atomic_andnot(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_andnot(long i, atomic_long_t *v)
 {
 	return atomic_fetch_andnot(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_andnot_acquire(long i, atomic_long_t *v)
 {
 	return atomic_fetch_andnot_acquire(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_andnot_release(long i, atomic_long_t *v)
 {
 	return atomic_fetch_andnot_release(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_andnot_relaxed(long i, atomic_long_t *v)
 {
 	return atomic_fetch_andnot_relaxed(i, v);
 }
 
-static inline void
+static __always_inline void
 atomic_long_or(long i, atomic_long_t *v)
 {
 	atomic_or(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_or(long i, atomic_long_t *v)
 {
 	return atomic_fetch_or(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_or_acquire(long i, atomic_long_t *v)
 {
 	return atomic_fetch_or_acquire(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_or_release(long i, atomic_long_t *v)
 {
 	return atomic_fetch_or_release(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_or_relaxed(long i, atomic_long_t *v)
 {
 	return atomic_fetch_or_relaxed(i, v);
 }
 
-static inline void
+static __always_inline void
 atomic_long_xor(long i, atomic_long_t *v)
 {
 	atomic_xor(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_xor(long i, atomic_long_t *v)
 {
 	return atomic_fetch_xor(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_xor_acquire(long i, atomic_long_t *v)
 {
 	return atomic_fetch_xor_acquire(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_xor_release(long i, atomic_long_t *v)
 {
 	return atomic_fetch_xor_release(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_xor_relaxed(long i, atomic_long_t *v)
 {
 	return atomic_fetch_xor_relaxed(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_xchg(atomic_long_t *v, long i)
 {
 	return atomic_xchg(v, i);
 }
 
-static inline long
+static __always_inline long
 atomic_long_xchg_acquire(atomic_long_t *v, long i)
 {
 	return atomic_xchg_acquire(v, i);
 }
 
-static inline long
+static __always_inline long
 atomic_long_xchg_release(atomic_long_t *v, long i)
 {
 	return atomic_xchg_release(v, i);
 }
 
-static inline long
+static __always_inline long
 atomic_long_xchg_relaxed(atomic_long_t *v, long i)
 {
 	return atomic_xchg_relaxed(v, i);
 }
 
-static inline long
+static __always_inline long
 atomic_long_cmpxchg(atomic_long_t *v, long old, long new)
 {
 	return atomic_cmpxchg(v, old, new);
 }
 
-static inline long
+static __always_inline long
 atomic_long_cmpxchg_acquire(atomic_long_t *v, long old, long new)
 {
 	return atomic_cmpxchg_acquire(v, old, new);
 }
 
-static inline long
+static __always_inline long
 atomic_long_cmpxchg_release(atomic_long_t *v, long old, long new)
 {
 	return atomic_cmpxchg_release(v, old, new);
 }
 
-static inline long
+static __always_inline long
 atomic_long_cmpxchg_relaxed(atomic_long_t *v, long old, long new)
 {
 	return atomic_cmpxchg_relaxed(v, old, new);
 }
 
-static inline bool
+static __always_inline bool
 atomic_long_try_cmpxchg(atomic_long_t *v, long *old, long new)
 {
 	return atomic_try_cmpxchg(v, (int *)old, new);
 }
 
-static inline bool
+static __always_inline bool
 atomic_long_try_cmpxchg_acquire(atomic_long_t *v, long *old, long new)
 {
 	return atomic_try_cmpxchg_acquire(v, (int *)old, new);
 }
 
-static inline bool
+static __always_inline bool
 atomic_long_try_cmpxchg_release(atomic_long_t *v, long *old, long new)
 {
 	return atomic_try_cmpxchg_release(v, (int *)old, new);
 }
 
-static inline bool
+static __always_inline bool
 atomic_long_try_cmpxchg_relaxed(atomic_long_t *v, long *old, long new)
 {
 	return atomic_try_cmpxchg_relaxed(v, (int *)old, new);
 }
 
-static inline bool
+static __always_inline bool
 atomic_long_sub_and_test(long i, atomic_long_t *v)
 {
 	return atomic_sub_and_test(i, v);
 }
 
-static inline bool
+static __always_inline bool
 atomic_long_dec_and_test(atomic_long_t *v)
 {
 	return atomic_dec_and_test(v);
 }
 
-static inline bool
+static __always_inline bool
 atomic_long_inc_and_test(atomic_long_t *v)
 {
 	return atomic_inc_and_test(v);
 }
 
-static inline bool
+static __always_inline bool
 atomic_long_add_negative(long i, atomic_long_t *v)
 {
 	return atomic_add_negative(i, v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_fetch_add_unless(atomic_long_t *v, long a, long u)
 {
 	return atomic_fetch_add_unless(v, a, u);
 }
 
-static inline bool
+static __always_inline bool
 atomic_long_add_unless(atomic_long_t *v, long a, long u)
 {
 	return atomic_add_unless(v, a, u);
 }
 
-static inline bool
+static __always_inline bool
 atomic_long_inc_not_zero(atomic_long_t *v)
 {
 	return atomic_inc_not_zero(v);
 }
 
-static inline bool
+static __always_inline bool
 atomic_long_inc_unless_negative(atomic_long_t *v)
 {
 	return atomic_inc_unless_negative(v);
 }
 
-static inline bool
+static __always_inline bool
 atomic_long_dec_unless_positive(atomic_long_t *v)
 {
 	return atomic_dec_unless_positive(v);
 }
 
-static inline long
+static __always_inline long
 atomic_long_dec_if_positive(atomic_long_t *v)
 {
 	return atomic_dec_if_positive(v);
@@ -1010,4 +1011,4 @@ atomic_long_dec_if_positive(atomic_long_t *v)
 
 #endif /* CONFIG_64BIT */
 #endif /* _ASM_GENERIC_ATOMIC_LONG_H */
-// 77558968132ce4f911ad53f6f52ce423006f6268
+// a624200981f552b2c6be4f32fe44da8289f30d87
diff --git a/include/asm-generic/bitops/instrumented-atomic.h b/include/asm-generic/bitops/instrumented-atomic.h
index 18ce3c9e8eec..fb2cb33a4013 100644
--- a/include/asm-generic/bitops/instrumented-atomic.h
+++ b/include/asm-generic/bitops/instrumented-atomic.h
@@ -11,7 +11,7 @@
 #ifndef _ASM_GENERIC_BITOPS_INSTRUMENTED_ATOMIC_H
 #define _ASM_GENERIC_BITOPS_INSTRUMENTED_ATOMIC_H
 
-#include <linux/kasan-checks.h>
+#include <linux/instrumented.h>
 
 /**
  * set_bit - Atomically set a bit in memory
@@ -25,7 +25,7 @@
  */
 static inline void set_bit(long nr, volatile unsigned long *addr)
 {
-	kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+	instrument_atomic_write(addr + BIT_WORD(nr), sizeof(long));
 	arch_set_bit(nr, addr);
 }
 
@@ -38,7 +38,7 @@ static inline void set_bit(long nr, volatile unsigned long *addr)
  */
 static inline void clear_bit(long nr, volatile unsigned long *addr)
 {
-	kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+	instrument_atomic_write(addr + BIT_WORD(nr), sizeof(long));
 	arch_clear_bit(nr, addr);
 }
 
@@ -54,7 +54,7 @@ static inline void clear_bit(long nr, volatile unsigned long *addr)
  */
 static inline void change_bit(long nr, volatile unsigned long *addr)
 {
-	kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+	instrument_atomic_write(addr + BIT_WORD(nr), sizeof(long));
 	arch_change_bit(nr, addr);
 }
 
@@ -67,7 +67,7 @@ static inline void change_bit(long nr, volatile unsigned long *addr)
  */
 static inline bool test_and_set_bit(long nr, volatile unsigned long *addr)
 {
-	kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+	instrument_atomic_write(addr + BIT_WORD(nr), sizeof(long));
 	return arch_test_and_set_bit(nr, addr);
 }
 
@@ -80,7 +80,7 @@ static inline bool test_and_set_bit(long nr, volatile unsigned long *addr)
  */
 static inline bool test_and_clear_bit(long nr, volatile unsigned long *addr)
 {
-	kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+	instrument_atomic_write(addr + BIT_WORD(nr), sizeof(long));
 	return arch_test_and_clear_bit(nr, addr);
 }
 
@@ -93,7 +93,7 @@ static inline bool test_and_clear_bit(long nr, volatile unsigned long *addr)
  */
 static inline bool test_and_change_bit(long nr, volatile unsigned long *addr)
 {
-	kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+	instrument_atomic_write(addr + BIT_WORD(nr), sizeof(long));
 	return arch_test_and_change_bit(nr, addr);
 }
 
diff --git a/include/asm-generic/bitops/instrumented-lock.h b/include/asm-generic/bitops/instrumented-lock.h
index ec53fdeea9ec..b9bec468ae03 100644
--- a/include/asm-generic/bitops/instrumented-lock.h
+++ b/include/asm-generic/bitops/instrumented-lock.h
@@ -11,7 +11,7 @@
 #ifndef _ASM_GENERIC_BITOPS_INSTRUMENTED_LOCK_H
 #define _ASM_GENERIC_BITOPS_INSTRUMENTED_LOCK_H
 
-#include <linux/kasan-checks.h>
+#include <linux/instrumented.h>
 
 /**
  * clear_bit_unlock - Clear a bit in memory, for unlock
@@ -22,7 +22,7 @@
  */
 static inline void clear_bit_unlock(long nr, volatile unsigned long *addr)
 {
-	kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+	instrument_atomic_write(addr + BIT_WORD(nr), sizeof(long));
 	arch_clear_bit_unlock(nr, addr);
 }
 
@@ -37,7 +37,7 @@ static inline void clear_bit_unlock(long nr, volatile unsigned long *addr)
  */
 static inline void __clear_bit_unlock(long nr, volatile unsigned long *addr)
 {
-	kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+	instrument_write(addr + BIT_WORD(nr), sizeof(long));
 	arch___clear_bit_unlock(nr, addr);
 }
 
@@ -52,7 +52,7 @@ static inline void __clear_bit_unlock(long nr, volatile unsigned long *addr)
  */
 static inline bool test_and_set_bit_lock(long nr, volatile unsigned long *addr)
 {
-	kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+	instrument_atomic_write(addr + BIT_WORD(nr), sizeof(long));
 	return arch_test_and_set_bit_lock(nr, addr);
 }
 
@@ -71,7 +71,7 @@ static inline bool test_and_set_bit_lock(long nr, volatile unsigned long *addr)
 static inline bool
 clear_bit_unlock_is_negative_byte(long nr, volatile unsigned long *addr)
 {
-	kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+	instrument_atomic_write(addr + BIT_WORD(nr), sizeof(long));
 	return arch_clear_bit_unlock_is_negative_byte(nr, addr);
 }
 /* Let everybody know we have it. */
diff --git a/include/asm-generic/bitops/instrumented-non-atomic.h b/include/asm-generic/bitops/instrumented-non-atomic.h
index 95ff28d128a1..20f788a25ef9 100644
--- a/include/asm-generic/bitops/instrumented-non-atomic.h
+++ b/include/asm-generic/bitops/instrumented-non-atomic.h
@@ -11,7 +11,7 @@
 #ifndef _ASM_GENERIC_BITOPS_INSTRUMENTED_NON_ATOMIC_H
 #define _ASM_GENERIC_BITOPS_INSTRUMENTED_NON_ATOMIC_H
 
-#include <linux/kasan-checks.h>
+#include <linux/instrumented.h>
 
 /**
  * __set_bit - Set a bit in memory
@@ -24,7 +24,7 @@
  */
 static inline void __set_bit(long nr, volatile unsigned long *addr)
 {
-	kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+	instrument_write(addr + BIT_WORD(nr), sizeof(long));
 	arch___set_bit(nr, addr);
 }
 
@@ -39,7 +39,7 @@ static inline void __set_bit(long nr, volatile unsigned long *addr)
  */
 static inline void __clear_bit(long nr, volatile unsigned long *addr)
 {
-	kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+	instrument_write(addr + BIT_WORD(nr), sizeof(long));
 	arch___clear_bit(nr, addr);
 }
 
@@ -54,7 +54,7 @@ static inline void __clear_bit(long nr, volatile unsigned long *addr)
  */
 static inline void __change_bit(long nr, volatile unsigned long *addr)
 {
-	kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+	instrument_write(addr + BIT_WORD(nr), sizeof(long));
 	arch___change_bit(nr, addr);
 }
 
@@ -68,7 +68,7 @@ static inline void __change_bit(long nr, volatile unsigned long *addr)
  */
 static inline bool __test_and_set_bit(long nr, volatile unsigned long *addr)
 {
-	kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+	instrument_write(addr + BIT_WORD(nr), sizeof(long));
 	return arch___test_and_set_bit(nr, addr);
 }
 
@@ -82,7 +82,7 @@ static inline bool __test_and_set_bit(long nr, volatile unsigned long *addr)
  */
 static inline bool __test_and_clear_bit(long nr, volatile unsigned long *addr)
 {
-	kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+	instrument_write(addr + BIT_WORD(nr), sizeof(long));
 	return arch___test_and_clear_bit(nr, addr);
 }
 
@@ -96,7 +96,7 @@ static inline bool __test_and_clear_bit(long nr, volatile unsigned long *addr)
  */
 static inline bool __test_and_change_bit(long nr, volatile unsigned long *addr)
 {
-	kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+	instrument_write(addr + BIT_WORD(nr), sizeof(long));
 	return arch___test_and_change_bit(nr, addr);
 }
 
@@ -107,7 +107,7 @@ static inline bool __test_and_change_bit(long nr, volatile unsigned long *addr)
  */
 static inline bool test_bit(long nr, const volatile unsigned long *addr)
 {
-	kasan_check_read(addr + BIT_WORD(nr), sizeof(long));
+	instrument_atomic_read(addr + BIT_WORD(nr), sizeof(long));
 	return arch_test_bit(nr, addr);
 }
 
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
index b3f1082cc435..1c4fd950f091 100644
--- a/include/asm-generic/mshyperv.h
+++ b/include/asm-generic/mshyperv.h
@@ -163,7 +163,7 @@ static inline int cpumask_to_vpset(struct hv_vpset *vpset,
 	return nr_bank;
 }
 
-void hyperv_report_panic(struct pt_regs *regs, long err);
+void hyperv_report_panic(struct pt_regs *regs, long err, bool in_die);
 void hyperv_report_panic_msg(phys_addr_t pa, size_t size);
 bool hv_is_hyperv_initialized(void);
 bool hv_is_hibernation_supported(void);
diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h
index 3ed5dee899fd..7402f852d3c4 100644
--- a/include/drm/drm_client.h
+++ b/include/drm/drm_client.h
@@ -188,6 +188,6 @@ int drm_client_modeset_dpms(struct drm_client_dev *client, int mode);
 	drm_for_each_connector_iter(connector, iter) \
 		if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
 
-int drm_client_debugfs_init(struct drm_minor *minor);
+void drm_client_debugfs_init(struct drm_minor *minor);
 
 #endif
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 19ae6bb5c85b..fd543d1db9b2 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1617,9 +1617,9 @@ struct drm_tile_group {
 };
 
 struct drm_tile_group *drm_mode_create_tile_group(struct drm_device *dev,
-						  char topology[8]);
+						  const char topology[8]);
 struct drm_tile_group *drm_mode_get_tile_group(struct drm_device *dev,
-					       char topology[8]);
+					       const char topology[8]);
 void drm_mode_put_tile_group(struct drm_device *dev,
 			     struct drm_tile_group *tg);
 
diff --git a/include/drm/drm_debugfs.h b/include/drm/drm_debugfs.h
index 7501e323d383..2188dc83957f 100644
--- a/include/drm/drm_debugfs.h
+++ b/include/drm/drm_debugfs.h
@@ -80,18 +80,16 @@ struct drm_info_node {
 };
 
 #if defined(CONFIG_DEBUG_FS)
-int drm_debugfs_create_files(const struct drm_info_list *files,
-			     int count, struct dentry *root,
-			     struct drm_minor *minor);
+void drm_debugfs_create_files(const struct drm_info_list *files,
+			      int count, struct dentry *root,
+			      struct drm_minor *minor);
 int drm_debugfs_remove_files(const struct drm_info_list *files,
 			     int count, struct drm_minor *minor);
 #else
-static inline int drm_debugfs_create_files(const struct drm_info_list *files,
-					   int count, struct dentry *root,
-					   struct drm_minor *minor)
-{
-	return 0;
-}
+static inline void drm_debugfs_create_files(const struct drm_info_list *files,
+					    int count, struct dentry *root,
+					    struct drm_minor *minor)
+{}
 
 static inline int drm_debugfs_remove_files(const struct drm_info_list *files,
 					   int count, struct drm_minor *minor)
diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h
index bb60a949f416..a55874db9dd4 100644
--- a/include/drm/drm_device.h
+++ b/include/drm/drm_device.h
@@ -67,15 +67,33 @@ struct drm_device {
 	/** @dev: Device structure of bus-device */
 	struct device *dev;
 
+	/**
+	 * @managed:
+	 *
+	 * Managed resources linked to the lifetime of this &drm_device as
+	 * tracked by @ref.
+	 */
+	struct {
+		/** @managed.resources: managed resources list */
+		struct list_head resources;
+		/** @managed.final_kfree: pointer for final kfree() call */
+		void *final_kfree;
+		/** @managed.lock: protects @managed.resources */
+		spinlock_t lock;
+	} managed;
+
 	/** @driver: DRM driver managing the device */
 	struct drm_driver *driver;
 
 	/**
 	 * @dev_private:
 	 *
-	 * DRM driver private data. Instead of using this pointer it is
-	 * recommended that drivers use drm_dev_init() and embed struct
-	 * &drm_device in their larger per-device structure.
+	 * DRM driver private data. This is deprecated and should be left set to
+	 * NULL.
+	 *
+	 * Instead of using this pointer it is recommended that drivers use
+	 * drm_dev_init() and embed struct &drm_device in their larger
+	 * per-device structure.
 	 */
 	void *dev_private;
 
diff --git a/include/drm/drm_displayid.h b/include/drm/drm_displayid.h
index 9d3b745c3107..27bdd273fc4e 100644
--- a/include/drm/drm_displayid.h
+++ b/include/drm/drm_displayid.h
@@ -97,7 +97,7 @@ struct displayid_detailed_timing_block {
 	     (idx) + sizeof(struct displayid_block) <= (length) && \
 	     (idx) + sizeof(struct displayid_block) + (block)->num_bytes <= (length) && \
 	     (block)->num_bytes > 0; \
-	     (idx) += (block)->num_bytes + sizeof(struct displayid_block), \
+	     (idx) += sizeof(struct displayid_block) + (block)->num_bytes, \
 	     (block) = (struct displayid_block *)&(displayid)[idx])
 
 #endif
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index c6119e4c169a..3beb2aac8c4c 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -701,7 +701,16 @@
 # define DP_TEST_CRC_SUPPORTED		    (1 << 5)
 # define DP_TEST_COUNT_MASK		    0xf
 
-#define DP_TEST_PHY_PATTERN                 0x248
+#define DP_PHY_TEST_PATTERN                 0x248
+# define DP_PHY_TEST_PATTERN_SEL_MASK       0x7
+# define DP_PHY_TEST_PATTERN_NONE           0x0
+# define DP_PHY_TEST_PATTERN_D10_2          0x1
+# define DP_PHY_TEST_PATTERN_ERROR_COUNT    0x2
+# define DP_PHY_TEST_PATTERN_PRBS7          0x3
+# define DP_PHY_TEST_PATTERN_80BIT_CUSTOM   0x4
+# define DP_PHY_TEST_PATTERN_CP2520         0x5
+
+#define DP_TEST_HBR2_SCRAMBLER_RESET        0x24A
 #define DP_TEST_80BIT_CUSTOM_PATTERN_7_0    0x250
 #define	DP_TEST_80BIT_CUSTOM_PATTERN_15_8   0x251
 #define	DP_TEST_80BIT_CUSTOM_PATTERN_23_16  0x252
@@ -1209,6 +1218,136 @@ struct dp_sdp {
 #define EDP_VSC_PSR_UPDATE_RFB		(1<<1)
 #define EDP_VSC_PSR_CRC_VALUES_VALID	(1<<2)
 
+/**
+ * enum dp_pixelformat - drm DP Pixel encoding formats
+ *
+ * This enum is used to indicate DP VSC SDP Pixel encoding formats.
+ * It is based on DP 1.4 spec [Table 2-117: VSC SDP Payload for DB16 through
+ * DB18]
+ *
+ * @DP_PIXELFORMAT_RGB: RGB pixel encoding format
+ * @DP_PIXELFORMAT_YUV444: YCbCr 4:4:4 pixel encoding format
+ * @DP_PIXELFORMAT_YUV422: YCbCr 4:2:2 pixel encoding format
+ * @DP_PIXELFORMAT_YUV420: YCbCr 4:2:0 pixel encoding format
+ * @DP_PIXELFORMAT_Y_ONLY: Y Only pixel encoding format
+ * @DP_PIXELFORMAT_RAW: RAW pixel encoding format
+ * @DP_PIXELFORMAT_RESERVED: Reserved pixel encoding format
+ */
+enum dp_pixelformat {
+	DP_PIXELFORMAT_RGB = 0,
+	DP_PIXELFORMAT_YUV444 = 0x1,
+	DP_PIXELFORMAT_YUV422 = 0x2,
+	DP_PIXELFORMAT_YUV420 = 0x3,
+	DP_PIXELFORMAT_Y_ONLY = 0x4,
+	DP_PIXELFORMAT_RAW = 0x5,
+	DP_PIXELFORMAT_RESERVED = 0x6,
+};
+
+/**
+ * enum dp_colorimetry - drm DP Colorimetry formats
+ *
+ * This enum is used to indicate DP VSC SDP Colorimetry formats.
+ * It is based on DP 1.4 spec [Table 2-117: VSC SDP Payload for DB16 through
+ * DB18] and a name of enum member follows DRM_MODE_COLORIMETRY definition.
+ *
+ * @DP_COLORIMETRY_DEFAULT: sRGB (IEC 61966-2-1) or
+ *                          ITU-R BT.601 colorimetry format
+ * @DP_COLORIMETRY_RGB_WIDE_FIXED: RGB wide gamut fixed point colorimetry format
+ * @DP_COLORIMETRY_BT709_YCC: ITU-R BT.709 colorimetry format
+ * @DP_COLORIMETRY_RGB_WIDE_FLOAT: RGB wide gamut floating point
+ *                                 (scRGB (IEC 61966-2-2)) colorimetry format
+ * @DP_COLORIMETRY_XVYCC_601: xvYCC601 colorimetry format
+ * @DP_COLORIMETRY_OPRGB: OpRGB colorimetry format
+ * @DP_COLORIMETRY_XVYCC_709: xvYCC709 colorimetry format
+ * @DP_COLORIMETRY_DCI_P3_RGB: DCI-P3 (SMPTE RP 431-2) colorimetry format
+ * @DP_COLORIMETRY_SYCC_601: sYCC601 colorimetry format
+ * @DP_COLORIMETRY_RGB_CUSTOM: RGB Custom Color Profile colorimetry format
+ * @DP_COLORIMETRY_OPYCC_601: opYCC601 colorimetry format
+ * @DP_COLORIMETRY_BT2020_RGB: ITU-R BT.2020 R' G' B' colorimetry format
+ * @DP_COLORIMETRY_BT2020_CYCC: ITU-R BT.2020 Y'c C'bc C'rc colorimetry format
+ * @DP_COLORIMETRY_BT2020_YCC: ITU-R BT.2020 Y' C'b C'r colorimetry format
+ */
+enum dp_colorimetry {
+	DP_COLORIMETRY_DEFAULT = 0,
+	DP_COLORIMETRY_RGB_WIDE_FIXED = 0x1,
+	DP_COLORIMETRY_BT709_YCC = 0x1,
+	DP_COLORIMETRY_RGB_WIDE_FLOAT = 0x2,
+	DP_COLORIMETRY_XVYCC_601 = 0x2,
+	DP_COLORIMETRY_OPRGB = 0x3,
+	DP_COLORIMETRY_XVYCC_709 = 0x3,
+	DP_COLORIMETRY_DCI_P3_RGB = 0x4,
+	DP_COLORIMETRY_SYCC_601 = 0x4,
+	DP_COLORIMETRY_RGB_CUSTOM = 0x5,
+	DP_COLORIMETRY_OPYCC_601 = 0x5,
+	DP_COLORIMETRY_BT2020_RGB = 0x6,
+	DP_COLORIMETRY_BT2020_CYCC = 0x6,
+	DP_COLORIMETRY_BT2020_YCC = 0x7,
+};
+
+/**
+ * enum dp_dynamic_range - drm DP Dynamic Range
+ *
+ * This enum is used to indicate DP VSC SDP Dynamic Range.
+ * It is based on DP 1.4 spec [Table 2-117: VSC SDP Payload for DB16 through
+ * DB18]
+ *
+ * @DP_DYNAMIC_RANGE_VESA: VESA range
+ * @DP_DYNAMIC_RANGE_CTA: CTA range
+ */
+enum dp_dynamic_range {
+	DP_DYNAMIC_RANGE_VESA = 0,
+	DP_DYNAMIC_RANGE_CTA = 1,
+};
+
+/**
+ * enum dp_content_type - drm DP Content Type
+ *
+ * This enum is used to indicate DP VSC SDP Content Types.
+ * It is based on DP 1.4 spec [Table 2-117: VSC SDP Payload for DB16 through
+ * DB18]
+ * CTA-861-G defines content types and expected processing by a sink device
+ *
+ * @DP_CONTENT_TYPE_NOT_DEFINED: Not defined type
+ * @DP_CONTENT_TYPE_GRAPHICS: Graphics type
+ * @DP_CONTENT_TYPE_PHOTO: Photo type
+ * @DP_CONTENT_TYPE_VIDEO: Video type
+ * @DP_CONTENT_TYPE_GAME: Game type
+ */
+enum dp_content_type {
+	DP_CONTENT_TYPE_NOT_DEFINED = 0x00,
+	DP_CONTENT_TYPE_GRAPHICS = 0x01,
+	DP_CONTENT_TYPE_PHOTO = 0x02,
+	DP_CONTENT_TYPE_VIDEO = 0x03,
+	DP_CONTENT_TYPE_GAME = 0x04,
+};
+
+/**
+ * struct drm_dp_vsc_sdp - drm DP VSC SDP
+ *
+ * This structure represents a DP VSC SDP of drm
+ * It is based on DP 1.4 spec [Table 2-116: VSC SDP Header Bytes] and
+ * [Table 2-117: VSC SDP Payload for DB16 through DB18]
+ *
+ * @sdp_type: secondary-data packet type
+ * @revision: revision number
+ * @length: number of valid data bytes
+ * @pixelformat: pixel encoding format
+ * @colorimetry: colorimetry format
+ * @bpc: bit per color
+ * @dynamic_range: dynamic range information
+ * @content_type: CTA-861-G defines content types and expected processing by a sink device
+ */
+struct drm_dp_vsc_sdp {
+	unsigned char sdp_type;
+	unsigned char revision;
+	unsigned char length;
+	enum dp_pixelformat pixelformat;
+	enum dp_colorimetry colorimetry;
+	int bpc;
+	enum dp_dynamic_range dynamic_range;
+	enum dp_content_type content_type;
+};
+
 int drm_dp_psr_setup_time(const u8 psr_cap[EDP_PSR_RECEIVER_CAP_SIZE]);
 
 static inline int
@@ -1548,6 +1687,13 @@ enum drm_dp_quirk {
 	 * capabilities advertised.
 	 */
 	DP_QUIRK_FORCE_DPCD_BACKLIGHT,
+	/**
+	 * @DP_DPCD_QUIRK_CAN_DO_MAX_LINK_RATE_3_24_GBPS:
+	 *
+	 * The device supports a link rate of 3.24 Gbps (multiplier 0xc) despite
+	 * the DP_MAX_LINK_RATE register reporting a lower max multiplier.
+	 */
+	DP_DPCD_QUIRK_CAN_DO_MAX_LINK_RATE_3_24_GBPS,
 };
 
 /**
@@ -1598,4 +1744,26 @@ static inline void drm_dp_cec_unset_edid(struct drm_dp_aux *aux)
 
 #endif
 
+/**
+ * struct drm_dp_phy_test_params - DP Phy Compliance parameters
+ * @link_rate: Requested Link rate from DPCD 0x219
+ * @num_lanes: Number of lanes requested by sing through DPCD 0x220
+ * @phy_pattern: DP Phy test pattern from DPCD 0x248
+ * @hb2_reset: DP HBR2_COMPLIANCE_SCRAMBLER_RESET from DCPD 0x24A and 0x24B
+ * @custom80: DP Test_80BIT_CUSTOM_PATTERN from DPCDs 0x250 through 0x259
+ * @enhanced_frame_cap: flag for enhanced frame capability.
+ */
+struct drm_dp_phy_test_params {
+	int link_rate;
+	u8 num_lanes;
+	u8 phy_pattern;
+	u8 hbr2_reset[2];
+	u8 custom80[10];
+	bool enhanced_frame_cap;
+};
+
+int drm_dp_get_phy_test_pattern(struct drm_dp_aux *aux,
+				struct drm_dp_phy_test_params *data);
+int drm_dp_set_phy_test_pattern(struct drm_dp_aux *aux,
+				struct drm_dp_phy_test_params *data, u8 dp_rev);
 #endif /* _DRM_DP_HELPER_H_ */
diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
index 3cde42b333c3..2d7c26592c05 100644
--- a/include/drm/drm_dp_mst_helper.h
+++ b/include/drm/drm_dp_mst_helper.h
@@ -157,9 +157,38 @@ struct drm_dp_mst_port {
 	 */
 	bool has_audio;
 
+	/**
+	 * @fec_capable: bool indicating if FEC can be supported up to that
+	 * point in the MST topology.
+	 */
 	bool fec_capable;
 };
 
+/* sideband msg header - not bit struct */
+struct drm_dp_sideband_msg_hdr {
+	u8 lct;
+	u8 lcr;
+	u8 rad[8];
+	bool broadcast;
+	bool path_msg;
+	u8 msg_len;
+	bool somt;
+	bool eomt;
+	bool seqno;
+};
+
+struct drm_dp_sideband_msg_rx {
+	u8 chunk[48];
+	u8 msg[256];
+	u8 curchunk_len;
+	u8 curchunk_idx; /* chunk we are parsing now */
+	u8 curchunk_hdrlen;
+	u8 curlen; /* total length of the msg */
+	bool have_somt;
+	bool have_eomt;
+	struct drm_dp_sideband_msg_hdr initial_hdr;
+};
+
 /**
  * struct drm_dp_mst_branch - MST branch device.
  * @rad: Relative Address to talk to this branch device.
@@ -232,24 +261,16 @@ struct drm_dp_mst_branch {
 	int last_seqno;
 	bool link_address_sent;
 
+	/**
+	 * @down_rep_recv: Message receiver state for down replies.
+	 */
+	struct drm_dp_sideband_msg_rx down_rep_recv[2];
+
 	/* global unique identifier to identify branch devices */
 	u8 guid[16];
 };
 
 
-/* sideband msg header - not bit struct */
-struct drm_dp_sideband_msg_hdr {
-	u8 lct;
-	u8 lcr;
-	u8 rad[8];
-	bool broadcast;
-	bool path_msg;
-	u8 msg_len;
-	bool somt;
-	bool eomt;
-	bool seqno;
-};
-
 struct drm_dp_nak_reply {
 	u8 guid[16];
 	u8 reason;
@@ -306,18 +327,6 @@ struct drm_dp_remote_i2c_write_ack_reply {
 };
 
 
-struct drm_dp_sideband_msg_rx {
-	u8 chunk[48];
-	u8 msg[256];
-	u8 curchunk_len;
-	u8 curchunk_idx; /* chunk we are parsing now */
-	u8 curchunk_hdrlen;
-	u8 curlen; /* total length of the msg */
-	bool have_somt;
-	bool have_eomt;
-	struct drm_dp_sideband_msg_hdr initial_hdr;
-};
-
 #define DRM_DP_MAX_SDP_STREAMS 16
 struct drm_dp_allocate_payload {
 	u8 port_number;
@@ -479,8 +488,6 @@ struct drm_dp_mst_topology_mgr;
 struct drm_dp_mst_topology_cbs {
 	/* create a connector for a port */
 	struct drm_connector *(*add_connector)(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, const char *path);
-	void (*destroy_connector)(struct drm_dp_mst_topology_mgr *mgr,
-				  struct drm_connector *connector);
 };
 
 #define DP_MAX_PAYLOAD (sizeof(unsigned long) * 8)
@@ -555,10 +562,6 @@ struct drm_dp_mst_topology_mgr {
 	 */
 	int conn_base_id;
 
-	/**
-	 * @down_rep_recv: Message receiver state for down replies.
-	 */
-	struct drm_dp_sideband_msg_rx down_rep_recv;
 	/**
 	 * @up_req_recv: Message receiver state for up requests.
 	 */
@@ -589,11 +592,6 @@ struct drm_dp_mst_topology_mgr {
 	 */
 	bool payload_id_table_cleared : 1;
 
-	/**
-	 * @is_waiting_for_dwn_reply: whether we're waiting for a down reply.
-	 */
-	bool is_waiting_for_dwn_reply : 1;
-
 	/**
 	 * @mst_primary: Pointer to the primary/first branch device.
 	 */
@@ -734,8 +732,6 @@ drm_dp_mst_detect_port(struct drm_connector *connector,
 		       struct drm_dp_mst_topology_mgr *mgr,
 		       struct drm_dp_mst_port *port);
 
-bool drm_dp_mst_port_has_audio(struct drm_dp_mst_topology_mgr *mgr,
-					struct drm_dp_mst_port *port);
 struct edid *drm_dp_mst_get_edid(struct drm_connector *connector, struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port);
 
 
diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
index 97109df5beac..e0ea577559ff 100644
--- a/include/drm/drm_drv.h
+++ b/include/drm/drm_drv.h
@@ -262,9 +262,11 @@ struct drm_driver {
 	 * @release:
 	 *
 	 * Optional callback for destroying device data after the final
-	 * reference is released, i.e. the device is being destroyed. Drivers
-	 * using this callback are responsible for calling drm_dev_fini()
-	 * to finalize the device and then freeing the struct themselves.
+	 * reference is released, i.e. the device is being destroyed.
+	 *
+	 * This is deprecated, clean up all memory allocations associated with a
+	 * &drm_device using drmm_add_action(), drmm_kmalloc() and related
+	 * managed resources functions.
 	 */
 	void (*release) (struct drm_device *);
 
@@ -323,7 +325,7 @@ struct drm_driver {
 	 *
 	 * Allows drivers to create driver-specific debugfs files.
 	 */
-	int (*debugfs_init)(struct drm_minor *minor);
+	void (*debugfs_init)(struct drm_minor *minor);
 
 	/**
 	 * @gem_free_object: deconstructor for drm_gem_objects
@@ -620,7 +622,6 @@ int drm_dev_init(struct drm_device *dev,
 int devm_drm_dev_init(struct device *parent,
 		      struct drm_device *dev,
 		      struct drm_driver *driver);
-void drm_dev_fini(struct drm_device *dev);
 
 struct drm_device *drm_dev_alloc(struct drm_driver *driver,
 				 struct device *parent);
diff --git a/include/drm/drm_encoder.h b/include/drm/drm_encoder.h
index 4370e039c015..a60f5f1555ac 100644
--- a/include/drm/drm_encoder.h
+++ b/include/drm/drm_encoder.h
@@ -142,7 +142,7 @@ struct drm_encoder {
 	 * the bits for all &drm_crtc objects this encoder can be connected to
 	 * before calling drm_dev_register().
 	 *
-	 * In reality almost every driver gets this wrong.
+	 * You will get a WARN if you get this wrong in the driver.
 	 *
 	 * Note that since CRTC objects can't be hotplugged the assigned indices
 	 * are stable and hence known before registering all objects.
@@ -159,7 +159,11 @@ struct drm_encoder {
 	 * encoders can be used in a cloned configuration, they both should have
 	 * each another bits set.
 	 *
-	 * In reality almost every driver gets this wrong.
+	 * As an exception to the above rule if the driver doesn't implement
+	 * any cloning it can leave @possible_clones set to 0. The core will
+	 * automagically fix this up by setting the bit for the encoder itself.
+	 *
+	 * You will get a WARN if you get this wrong in the driver.
 	 *
 	 * Note that since encoder objects can't be hotplugged the assigned indices
 	 * are stable and hence known before registering all objects.
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
index 208dbf87afa3..306aa3a60be9 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -269,7 +269,8 @@ int drm_fb_helper_debug_leave(struct fb_info *info);
 void drm_fb_helper_lastclose(struct drm_device *dev);
 void drm_fb_helper_output_poll_changed(struct drm_device *dev);
 
-int drm_fbdev_generic_setup(struct drm_device *dev, unsigned int preferred_bpp);
+void drm_fbdev_generic_setup(struct drm_device *dev,
+			     unsigned int preferred_bpp);
 #else
 static inline void drm_fb_helper_prepare(struct drm_device *dev,
 					struct drm_fb_helper *helper,
@@ -443,10 +444,9 @@ static inline void drm_fb_helper_output_poll_changed(struct drm_device *dev)
 {
 }
 
-static inline int
+static inline void
 drm_fbdev_generic_setup(struct drm_device *dev, unsigned int preferred_bpp)
 {
-	return 0;
 }
 
 #endif
diff --git a/include/drm/drm_file.h b/include/drm/drm_file.h
index 5aaf1c4593a9..716990bace10 100644
--- a/include/drm/drm_file.h
+++ b/include/drm/drm_file.h
@@ -201,6 +201,17 @@ struct drm_file {
 	 */
 	bool writeback_connectors;
 
+	/**
+	 * @was_master:
+	 *
+	 * This client has or had, master capability. Protected by struct
+	 * &drm_device.master_mutex.
+	 *
+	 * This is used to ensure that CAP_SYS_ADMIN is not enforced, if the
+	 * client is or was master in the past.
+	 */
+	bool was_master;
+
 	/**
 	 * @is_master:
 	 *
diff --git a/include/drm/drm_framebuffer.h b/include/drm/drm_framebuffer.h
index c0e0256e3e98..be658ebbec72 100644
--- a/include/drm/drm_framebuffer.h
+++ b/include/drm/drm_framebuffer.h
@@ -297,4 +297,42 @@ int drm_framebuffer_plane_width(int width,
 int drm_framebuffer_plane_height(int height,
 				 const struct drm_framebuffer *fb, int plane);
 
+/**
+ * struct drm_afbc_framebuffer - a special afbc frame buffer object
+ *
+ * A derived class of struct drm_framebuffer, dedicated for afbc use cases.
+ */
+struct drm_afbc_framebuffer {
+	/**
+	 * @base: base framebuffer structure.
+	 */
+	struct drm_framebuffer base;
+	/**
+	 * @block_width: width of a single afbc block
+	 */
+	u32 block_width;
+	/**
+	 * @block_height: height of a single afbc block
+	 */
+	u32 block_height;
+	/**
+	 * @aligned_width: aligned frame buffer width
+	 */
+	u32 aligned_width;
+	/**
+	 * @aligned_height: aligned frame buffer height
+	 */
+	u32 aligned_height;
+	/**
+	 * @offset: offset of the first afbc header
+	 */
+	u32 offset;
+	/**
+	 * @afbc_size: minimum size of afbc buffer
+	 */
+	u32 afbc_size;
+};
+
+#define fb_to_afbc_fb(x) container_of(x, struct drm_afbc_framebuffer, base)
+
 #endif
diff --git a/include/drm/drm_gem_framebuffer_helper.h b/include/drm/drm_gem_framebuffer_helper.h
index d9f13fd25b0a..6b013154911d 100644
--- a/include/drm/drm_gem_framebuffer_helper.h
+++ b/include/drm/drm_gem_framebuffer_helper.h
@@ -1,6 +1,7 @@
 #ifndef __DRM_GEM_FB_HELPER_H__
 #define __DRM_GEM_FB_HELPER_H__
 
+struct drm_afbc_framebuffer;
 struct drm_device;
 struct drm_fb_helper_surface_size;
 struct drm_file;
@@ -12,12 +13,19 @@ struct drm_plane;
 struct drm_plane_state;
 struct drm_simple_display_pipe;
 
+#define AFBC_VENDOR_AND_TYPE_MASK	GENMASK_ULL(63, 52)
+
 struct drm_gem_object *drm_gem_fb_get_obj(struct drm_framebuffer *fb,
 					  unsigned int plane);
 void drm_gem_fb_destroy(struct drm_framebuffer *fb);
 int drm_gem_fb_create_handle(struct drm_framebuffer *fb, struct drm_file *file,
 			     unsigned int *handle);
 
+int drm_gem_fb_init_with_funcs(struct drm_device *dev,
+			       struct drm_framebuffer *fb,
+			       struct drm_file *file,
+			       const struct drm_mode_fb_cmd2 *mode_cmd,
+			       const struct drm_framebuffer_funcs *funcs);
 struct drm_framebuffer *
 drm_gem_fb_create_with_funcs(struct drm_device *dev, struct drm_file *file,
 			     const struct drm_mode_fb_cmd2 *mode_cmd,
@@ -29,6 +37,13 @@ struct drm_framebuffer *
 drm_gem_fb_create_with_dirty(struct drm_device *dev, struct drm_file *file,
 			     const struct drm_mode_fb_cmd2 *mode_cmd);
 
+#define drm_is_afbc(modifier) \
+	(((modifier) & AFBC_VENDOR_AND_TYPE_MASK) == DRM_FORMAT_MOD_ARM_AFBC(0))
+
+int drm_gem_fb_afbc_init(struct drm_device *dev,
+			 const struct drm_mode_fb_cmd2 *mode_cmd,
+			 struct drm_afbc_framebuffer *afbc_fb);
+
 int drm_gem_fb_prepare_fb(struct drm_plane *plane,
 			  struct drm_plane_state *state);
 int drm_gem_fb_simple_display_pipe_prepare_fb(struct drm_simple_display_pipe *pipe,
diff --git a/include/drm/drm_gem_vram_helper.h b/include/drm/drm_gem_vram_helper.h
index 0f6e47213d8d..b63bcd1b996d 100644
--- a/include/drm/drm_gem_vram_helper.h
+++ b/include/drm/drm_gem_vram_helper.h
@@ -196,7 +196,7 @@ static inline struct drm_vram_mm *drm_vram_mm_of_bdev(
 	return container_of(bdev, struct drm_vram_mm, bdev);
 }
 
-int drm_vram_mm_debugfs_init(struct drm_minor *minor);
+void drm_vram_mm_debugfs_init(struct drm_minor *minor);
 
 /*
  * Helpers for integration with struct drm_device
diff --git a/include/drm/drm_legacy.h b/include/drm/drm_legacy.h
index aed382c17b26..852d7451eeb1 100644
--- a/include/drm/drm_legacy.h
+++ b/include/drm/drm_legacy.h
@@ -194,11 +194,26 @@ void drm_legacy_idlelock_release(struct drm_lock_data *lock);
 
 #ifdef CONFIG_PCI
 
+struct drm_dma_handle *drm_pci_alloc(struct drm_device *dev, size_t size,
+				     size_t align);
+void drm_pci_free(struct drm_device *dev, struct drm_dma_handle *dmah);
+
 int drm_legacy_pci_init(struct drm_driver *driver, struct pci_driver *pdriver);
 void drm_legacy_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver);
 
 #else
 
+static inline struct drm_dma_handle *drm_pci_alloc(struct drm_device *dev,
+						   size_t size, size_t align)
+{
+	return NULL;
+}
+
+static inline void drm_pci_free(struct drm_device *dev,
+				struct drm_dma_handle *dmah)
+{
+}
+
 static inline int drm_legacy_pci_init(struct drm_driver *driver,
 				      struct pci_driver *pdriver)
 {
diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h
new file mode 100644
index 000000000000..ca4114633bf9
--- /dev/null
+++ b/include/drm/drm_managed.h
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#ifndef _DRM_MANAGED_H_
+#define _DRM_MANAGED_H_
+
+#include <linux/gfp.h>
+#include <linux/overflow.h>
+#include <linux/types.h>
+
+struct drm_device;
+
+typedef void (*drmres_release_t)(struct drm_device *dev, void *res);
+
+/**
+ * drmm_add_action - add a managed release action to a &drm_device
+ * @dev: DRM device
+ * @action: function which should be called when @dev is released
+ * @data: opaque pointer, passed to @action
+ *
+ * This function adds the @release action with optional parameter @data to the
+ * list of cleanup actions for @dev. The cleanup actions will be run in reverse
+ * order in the final drm_dev_put() call for @dev.
+ */
+#define drmm_add_action(dev, action, data) \
+	__drmm_add_action(dev, action, data, #action)
+
+int __must_check __drmm_add_action(struct drm_device *dev,
+				   drmres_release_t action,
+				   void *data, const char *name);
+
+/**
+ * drmm_add_action_or_reset - add a managed release action to a &drm_device
+ * @dev: DRM device
+ * @action: function which should be called when @dev is released
+ * @data: opaque pointer, passed to @action
+ *
+ * Similar to drmm_add_action(), with the only difference that upon failure
+ * @action is directly called for any cleanup work necessary on failures.
+ */
+#define drmm_add_action_or_reset(dev, action, data) \
+	__drmm_add_action_or_reset(dev, action, data, #action)
+
+int __must_check __drmm_add_action_or_reset(struct drm_device *dev,
+					    drmres_release_t action,
+					    void *data, const char *name);
+
+void drmm_add_final_kfree(struct drm_device *dev, void *container);
+
+void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp) __malloc;
+
+/**
+ * drmm_kzalloc - &drm_device managed kzalloc()
+ * @dev: DRM device
+ * @size: size of the memory allocation
+ * @gfp: GFP allocation flags
+ *
+ * This is a &drm_device managed version of kzalloc(). The allocated memory is
+ * automatically freed on the final drm_dev_put(). Memory can also be freed
+ * before the final drm_dev_put() by calling drmm_kfree().
+ */
+static inline void *drmm_kzalloc(struct drm_device *dev, size_t size, gfp_t gfp)
+{
+	return drmm_kmalloc(dev, size, gfp | __GFP_ZERO);
+}
+
+/**
+ * drmm_kmalloc_array - &drm_device managed kmalloc_array()
+ * @dev: DRM device
+ * @n: number of array elements to allocate
+ * @size: size of array member
+ * @flags: GFP allocation flags
+ *
+ * This is a &drm_device managed version of kmalloc_array(). The allocated
+ * memory is automatically freed on the final drm_dev_put() and works exactly
+ * like a memory allocation obtained by drmm_kmalloc().
+ */
+static inline void *drmm_kmalloc_array(struct drm_device *dev,
+				       size_t n, size_t size, gfp_t flags)
+{
+	size_t bytes;
+
+	if (unlikely(check_mul_overflow(n, size, &bytes)))
+		return NULL;
+
+	return drmm_kmalloc(dev, bytes, flags);
+}
+
+/**
+ * drmm_kcalloc - &drm_device managed kcalloc()
+ * @dev: DRM device
+ * @n: number of array elements to allocate
+ * @size: size of array member
+ * @flags: GFP allocation flags
+ *
+ * This is a &drm_device managed version of kcalloc(). The allocated memory is
+ * automatically freed on the final drm_dev_put() and works exactly like a
+ * memory allocation obtained by drmm_kmalloc().
+ */
+static inline void *drmm_kcalloc(struct drm_device *dev,
+				 size_t n, size_t size, gfp_t flags)
+{
+	return drmm_kmalloc_array(dev, n, size, flags | __GFP_ZERO);
+}
+
+char *drmm_kstrdup(struct drm_device *dev, const char *s, gfp_t gfp);
+
+void drmm_kfree(struct drm_device *dev, void *data);
+
+#endif
diff --git a/include/drm/drm_mipi_dbi.h b/include/drm/drm_mipi_dbi.h
index 33f325f5af2b..4d0e49c0ed2c 100644
--- a/include/drm/drm_mipi_dbi.h
+++ b/include/drm/drm_mipi_dbi.h
@@ -152,7 +152,6 @@ int mipi_dbi_dev_init_with_formats(struct mipi_dbi_dev *dbidev,
 int mipi_dbi_dev_init(struct mipi_dbi_dev *dbidev,
 		      const struct drm_simple_display_pipe_funcs *funcs,
 		      const struct drm_display_mode *mode, unsigned int rotation);
-void mipi_dbi_release(struct drm_device *drm);
 void mipi_dbi_pipe_update(struct drm_simple_display_pipe *pipe,
 			  struct drm_plane_state *old_state);
 void mipi_dbi_enable_flush(struct mipi_dbi_dev *dbidev,
@@ -170,7 +169,8 @@ int mipi_dbi_spi_transfer(struct spi_device *spi, u32 speed_hz,
 
 int mipi_dbi_command_read(struct mipi_dbi *dbi, u8 cmd, u8 *val);
 int mipi_dbi_command_buf(struct mipi_dbi *dbi, u8 cmd, u8 *data, size_t len);
-int mipi_dbi_command_stackbuf(struct mipi_dbi *dbi, u8 cmd, u8 *data, size_t len);
+int mipi_dbi_command_stackbuf(struct mipi_dbi *dbi, u8 cmd, const u8 *data,
+			      size_t len);
 int mipi_dbi_buf_copy(void *dst, struct drm_framebuffer *fb,
 		      struct drm_rect *clip, bool swap);
 /**
@@ -187,12 +187,12 @@ int mipi_dbi_buf_copy(void *dst, struct drm_framebuffer *fb,
  */
 #define mipi_dbi_command(dbi, cmd, seq...) \
 ({ \
-	u8 d[] = { seq }; \
+	const u8 d[] = { seq }; \
 	mipi_dbi_command_stackbuf(dbi, cmd, d, ARRAY_SIZE(d)); \
 })
 
 #ifdef CONFIG_DEBUG_FS
-int mipi_dbi_debugfs_init(struct drm_minor *minor);
+void mipi_dbi_debugfs_init(struct drm_minor *minor);
 #else
 #define mipi_dbi_debugfs_init		NULL
 #endif
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index 3bcbe30339f0..6c3ef49b46b3 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -929,7 +929,23 @@ struct drm_mode_config {
 	const struct drm_mode_config_helper_funcs *helper_private;
 };
 
-void drm_mode_config_init(struct drm_device *dev);
+int __must_check drmm_mode_config_init(struct drm_device *dev);
+
+/**
+ * drm_mode_config_init - DRM mode_configuration structure initialization
+ * @dev: DRM device
+ *
+ * This is the unmanaged version of drmm_mode_config_init() for drivers which
+ * still explicitly call drm_mode_config_cleanup().
+ *
+ * FIXME: This function is deprecated and drivers should be converted over to
+ * drmm_mode_config_init().
+ */
+static inline int drm_mode_config_init(struct drm_device *dev)
+{
+	return drmm_mode_config_init(dev);
+}
+
 void drm_mode_config_reset(struct drm_device *dev);
 void drm_mode_config_cleanup(struct drm_device *dev);
 
diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
index 7c20b1c8b6a7..421a30f08463 100644
--- a/include/drm/drm_modeset_helper_vtables.h
+++ b/include/drm/drm_modeset_helper_vtables.h
@@ -1075,8 +1075,35 @@ struct drm_connector_helper_funcs {
 	void (*atomic_commit)(struct drm_connector *connector,
 			      struct drm_connector_state *state);
 
+	/**
+	 * @prepare_writeback_job:
+	 *
+	 * As writeback jobs contain a framebuffer, drivers may need to
+	 * prepare and clean them up the same way they can prepare and
+	 * clean up framebuffers for planes. This optional connector operation
+	 * is used to support the preparation of writeback jobs. The job
+	 * prepare operation is called from drm_atomic_helper_prepare_planes()
+	 * for struct &drm_writeback_connector connectors only.
+	 *
+	 * This operation is optional.
+	 *
+	 * This callback is used by the atomic modeset helpers.
+	 */
 	int (*prepare_writeback_job)(struct drm_writeback_connector *connector,
 				     struct drm_writeback_job *job);
+	/**
+	 * @cleanup_writeback_job:
+	 *
+	 * This optional connector operation is used to support the
+	 * cleanup of writeback jobs. The job cleanup operation is called
+	 * from the existing drm_writeback_cleanup_job() function, invoked
+	 * both when destroying the job as part of an aborted commit, or when
+	 * the job completes.
+	 *
+	 * This operation is optional.
+	 *
+	 * This callback is used by the atomic modeset helpers.
+	 */
 	void (*cleanup_writeback_job)(struct drm_writeback_connector *connector,
 				      struct drm_writeback_job *job);
 };
diff --git a/include/drm/drm_pci.h b/include/drm/drm_pci.h
deleted file mode 100644
index 3941b0255ecf..000000000000
--- a/include/drm/drm_pci.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Internal Header for the Direct Rendering Manager
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * Copyright (c) 2009-2010, Code Aurora Forum.
- * All rights reserved.
- *
- * Author: Rickard E. (Rik) Faith <faith@valinux.com>
- * Author: Gareth Hughes <gareth@valinux.com>
- *
- * 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 (including the next
- * paragraph) 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
- * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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 _DRM_PCI_H_
-#define _DRM_PCI_H_
-
-#include <linux/pci.h>
-
-struct drm_dma_handle;
-struct drm_device;
-struct drm_driver;
-struct drm_master;
-
-#ifdef CONFIG_PCI
-
-struct drm_dma_handle *drm_pci_alloc(struct drm_device *dev, size_t size,
-				     size_t align);
-void drm_pci_free(struct drm_device *dev, struct drm_dma_handle * dmah);
-
-#else
-
-static inline struct drm_dma_handle *drm_pci_alloc(struct drm_device *dev,
-						   size_t size, size_t align)
-{
-	return NULL;
-}
-
-static inline void drm_pci_free(struct drm_device *dev,
-				struct drm_dma_handle *dmah)
-{
-}
-
-#endif
-
-#endif /* _DRM_PCI_H_ */
diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index ca7cee8e728a..1c9417430d08 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -313,6 +313,10 @@ enum drm_debug_category {
 	 * @DRM_UT_DP: Used in the DP code.
 	 */
 	DRM_UT_DP		= 0x100,
+	/**
+	 * @DRM_UT_DRMRES: Used in the drm managed resources code.
+	 */
+	DRM_UT_DRMRES		= 0x200,
 };
 
 static inline bool drm_debug_enabled(enum drm_debug_category category)
@@ -442,6 +446,8 @@ void drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
 	drm_dev_dbg((drm)->dev, DRM_UT_LEASE, fmt, ##__VA_ARGS__)
 #define drm_dbg_dp(drm, fmt, ...)					\
 	drm_dev_dbg((drm)->dev, DRM_UT_DP, fmt, ##__VA_ARGS__)
+#define drm_dbg_drmres(drm, fmt, ...)					\
+	drm_dev_dbg((drm)->dev, DRM_UT_DRMRES, fmt, ##__VA_ARGS__)
 
 
 /*
diff --git a/include/drm/drm_writeback.h b/include/drm/drm_writeback.h
index 777c14c847f0..9697d2714d2a 100644
--- a/include/drm/drm_writeback.h
+++ b/include/drm/drm_writeback.h
@@ -15,7 +15,13 @@
 #include <drm/drm_encoder.h>
 #include <linux/workqueue.h>
 
+/**
+ * struct drm_writeback_connector - DRM writeback connector
+ */
 struct drm_writeback_connector {
+	/**
+	 * @base: base drm_connector object
+	 */
 	struct drm_connector base;
 
 	/**
@@ -78,6 +84,9 @@ struct drm_writeback_connector {
 	char timeline_name[32];
 };
 
+/**
+ * struct drm_writeback_job - DRM writeback job
+ */
 struct drm_writeback_job {
 	/**
 	 * @connector:
diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h
index 26b04ff62676..a21b3b92135a 100644
--- a/include/drm/gpu_scheduler.h
+++ b/include/drm/gpu_scheduler.h
@@ -56,6 +56,7 @@ enum drm_sched_priority {
  *              Jobs from this entity can be scheduled on any scheduler
  *              on this list.
  * @num_sched_list: number of drm_gpu_schedulers in the sched_list.
+ * @priority: priority of the entity
  * @rq_lock: lock to modify the runqueue to which this entity belongs.
  * @job_queue: the list of jobs of this entity.
  * @fence_seq: a linearly increasing seqno incremented with each
diff --git a/include/drm/i915_pciids.h b/include/drm/i915_pciids.h
index 1d2c12219f44..662d8351c87a 100644
--- a/include/drm/i915_pciids.h
+++ b/include/drm/i915_pciids.h
@@ -593,12 +593,16 @@
 
 /* TGL */
 #define INTEL_TGL_12_IDS(info) \
-	INTEL_VGA_DEVICE(0x9A49, info), \
 	INTEL_VGA_DEVICE(0x9A40, info), \
+	INTEL_VGA_DEVICE(0x9A49, info), \
 	INTEL_VGA_DEVICE(0x9A59, info), \
 	INTEL_VGA_DEVICE(0x9A60, info), \
 	INTEL_VGA_DEVICE(0x9A68, info), \
 	INTEL_VGA_DEVICE(0x9A70, info), \
-	INTEL_VGA_DEVICE(0x9A78, info)
+	INTEL_VGA_DEVICE(0x9A78, info), \
+	INTEL_VGA_DEVICE(0x9AC0, info), \
+	INTEL_VGA_DEVICE(0x9AC9, info), \
+	INTEL_VGA_DEVICE(0x9AD9, info), \
+	INTEL_VGA_DEVICE(0x9AF8, info)
 
 #endif /* _I915_PCIIDS_H */
diff --git a/include/drm/ttm/ttm_debug.h b/include/drm/ttm/ttm_debug.h
deleted file mode 100644
index b5e460fa5086..000000000000
--- a/include/drm/ttm/ttm_debug.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/**************************************************************************
- *
- * Copyright (c) 2017 Advanced Micro Devices, Inc.
- * 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, sub license, 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 (including the
- * next paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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: Tom St Denis <tom.stdenis@amd.com>
- */
-extern void ttm_trace_dma_map(struct device *dev, struct ttm_dma_tt *tt);
-extern void ttm_trace_dma_unmap(struct device *dev, struct ttm_dma_tt *tt);
diff --git a/include/dt-bindings/clock/imx7ulp-clock.h b/include/dt-bindings/clock/imx7ulp-clock.h
index 38145bdcd975..b58370d146e2 100644
--- a/include/dt-bindings/clock/imx7ulp-clock.h
+++ b/include/dt-bindings/clock/imx7ulp-clock.h
@@ -58,7 +58,10 @@
 #define IMX7ULP_CLK_HSRUN_SYS_SEL	44
 #define IMX7ULP_CLK_HSRUN_CORE_DIV	45
 
-#define IMX7ULP_CLK_SCG1_END		46
+#define IMX7ULP_CLK_CORE		46
+#define IMX7ULP_CLK_HSRUN_CORE		47
+
+#define IMX7ULP_CLK_SCG1_END		48
 
 /* PCC2 */
 #define IMX7ULP_CLK_DMA1		0
diff --git a/include/dt-bindings/pinctrl/pads-imx8dxl.h b/include/dt-bindings/pinctrl/pads-imx8dxl.h
new file mode 100644
index 000000000000..b1d7b84c3e0a
--- /dev/null
+++ b/include/dt-bindings/pinctrl/pads-imx8dxl.h
@@ -0,0 +1,639 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2019~2020 NXP
+ */
+
+#ifndef _IMX8DXL_PADS_H
+#define _IMX8DXL_PADS_H
+
+/* pin id */
+#define IMX8DXL_PCIE_CTRL0_PERST_B                  0
+#define IMX8DXL_PCIE_CTRL0_CLKREQ_B                 1
+#define IMX8DXL_PCIE_CTRL0_WAKE_B                   2
+#define IMX8DXL_COMP_CTL_GPIO_1V8_3V3_PCIESEP       3
+#define IMX8DXL_USB_SS3_TC0                         4
+#define IMX8DXL_USB_SS3_TC1                         5
+#define IMX8DXL_USB_SS3_TC2                         6
+#define IMX8DXL_USB_SS3_TC3                         7
+#define IMX8DXL_COMP_CTL_GPIO_3V3_USB3IO            8
+#define IMX8DXL_EMMC0_CLK                           9
+#define IMX8DXL_EMMC0_CMD                           10
+#define IMX8DXL_EMMC0_DATA0                         11
+#define IMX8DXL_EMMC0_DATA1                         12
+#define IMX8DXL_EMMC0_DATA2                         13
+#define IMX8DXL_EMMC0_DATA3                         14
+#define IMX8DXL_EMMC0_DATA4                         15
+#define IMX8DXL_EMMC0_DATA5                         16
+#define IMX8DXL_EMMC0_DATA6                         17
+#define IMX8DXL_EMMC0_DATA7                         18
+#define IMX8DXL_EMMC0_STROBE                        19
+#define IMX8DXL_EMMC0_RESET_B                       20
+#define IMX8DXL_COMP_CTL_GPIO_1V8_3V3_SD1FIX0       21
+#define IMX8DXL_USDHC1_RESET_B                      22
+#define IMX8DXL_USDHC1_VSELECT                      23
+#define IMX8DXL_CTL_NAND_RE_P_N                     24
+#define IMX8DXL_USDHC1_WP                           25
+#define IMX8DXL_USDHC1_CD_B                         26
+#define IMX8DXL_CTL_NAND_DQS_P_N                    27
+#define IMX8DXL_COMP_CTL_GPIO_1V8_3V3_VSELSEP       28
+#define IMX8DXL_ENET0_RGMII_TXC                     29
+#define IMX8DXL_ENET0_RGMII_TX_CTL                  30
+#define IMX8DXL_ENET0_RGMII_TXD0                    31
+#define IMX8DXL_ENET0_RGMII_TXD1                    32
+#define IMX8DXL_ENET0_RGMII_TXD2                    33
+#define IMX8DXL_ENET0_RGMII_TXD3                    34
+#define IMX8DXL_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB0   35
+#define IMX8DXL_ENET0_RGMII_RXC                     36
+#define IMX8DXL_ENET0_RGMII_RX_CTL                  37
+#define IMX8DXL_ENET0_RGMII_RXD0                    38
+#define IMX8DXL_ENET0_RGMII_RXD1                    39
+#define IMX8DXL_ENET0_RGMII_RXD2                    40
+#define IMX8DXL_ENET0_RGMII_RXD3                    41
+#define IMX8DXL_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB1   42
+#define IMX8DXL_ENET0_REFCLK_125M_25M               43
+#define IMX8DXL_ENET0_MDIO                          44
+#define IMX8DXL_ENET0_MDC                           45
+#define IMX8DXL_COMP_CTL_GPIO_1V8_3V3_GPIOCT        46
+#define IMX8DXL_ENET1_RGMII_TXC                     47
+#define IMX8DXL_ENET1_RGMII_TXD2                    48
+#define IMX8DXL_ENET1_RGMII_TX_CTL                  49
+#define IMX8DXL_ENET1_RGMII_TXD3                    50
+#define IMX8DXL_ENET1_RGMII_RXC                     51
+#define IMX8DXL_ENET1_RGMII_RXD3                    52
+#define IMX8DXL_ENET1_RGMII_RXD2                    53
+#define IMX8DXL_ENET1_RGMII_RXD1                    54
+#define IMX8DXL_ENET1_RGMII_TXD0                    55
+#define IMX8DXL_ENET1_RGMII_TXD1                    56
+#define IMX8DXL_ENET1_RGMII_RXD0                    57
+#define IMX8DXL_ENET1_RGMII_RX_CTL                  58
+#define IMX8DXL_ENET1_REFCLK_125M_25M               59
+#define IMX8DXL_COMP_CTL_GPIO_1V8_3V3_GPIORHB       60
+#define IMX8DXL_SPI3_SCK                            61
+#define IMX8DXL_SPI3_SDO                            62
+#define IMX8DXL_SPI3_SDI                            63
+#define IMX8DXL_SPI3_CS0                            64
+#define IMX8DXL_SPI3_CS1                            65
+#define IMX8DXL_MCLK_IN1                            66
+#define IMX8DXL_MCLK_IN0                            67
+#define IMX8DXL_MCLK_OUT0                           68
+#define IMX8DXL_UART1_TX                            69
+#define IMX8DXL_UART1_RX                            70
+#define IMX8DXL_UART1_RTS_B                         71
+#define IMX8DXL_UART1_CTS_B                         72
+#define IMX8DXL_COMP_CTL_GPIO_1V8_3V3_GPIORHK       73
+#define IMX8DXL_SPI0_SCK                            74
+#define IMX8DXL_SPI0_SDI                            75
+#define IMX8DXL_SPI0_SDO                            76
+#define IMX8DXL_SPI0_CS1                            77
+#define IMX8DXL_SPI0_CS0                            78
+#define IMX8DXL_COMP_CTL_GPIO_1V8_3V3_GPIORHT       79
+#define IMX8DXL_ADC_IN1                             80
+#define IMX8DXL_ADC_IN0                             81
+#define IMX8DXL_ADC_IN3                             82
+#define IMX8DXL_ADC_IN2                             83
+#define IMX8DXL_ADC_IN5                             84
+#define IMX8DXL_ADC_IN4                             85
+#define IMX8DXL_FLEXCAN0_RX                         86
+#define IMX8DXL_FLEXCAN0_TX                         87
+#define IMX8DXL_FLEXCAN1_RX                         88
+#define IMX8DXL_FLEXCAN1_TX                         89
+#define IMX8DXL_FLEXCAN2_RX                         90
+#define IMX8DXL_FLEXCAN2_TX                         91
+#define IMX8DXL_UART0_RX                            92
+#define IMX8DXL_UART0_TX                            93
+#define IMX8DXL_UART2_TX                            94
+#define IMX8DXL_UART2_RX                            95
+#define IMX8DXL_COMP_CTL_GPIO_1V8_3V3_GPIOLH        96
+#define IMX8DXL_JTAG_TRST_B                         97
+#define IMX8DXL_PMIC_I2C_SCL                        98
+#define IMX8DXL_PMIC_I2C_SDA                        99
+#define IMX8DXL_PMIC_INT_B                          100
+#define IMX8DXL_SCU_GPIO0_00                        101
+#define IMX8DXL_SCU_GPIO0_01                        102
+#define IMX8DXL_SCU_PMIC_STANDBY                    103
+#define IMX8DXL_SCU_BOOT_MODE1                      104
+#define IMX8DXL_SCU_BOOT_MODE0                      105
+#define IMX8DXL_SCU_BOOT_MODE2                      106
+#define IMX8DXL_SNVS_TAMPER_OUT1                    107
+#define IMX8DXL_SNVS_TAMPER_OUT2                    108
+#define IMX8DXL_SNVS_TAMPER_OUT3                    109
+#define IMX8DXL_SNVS_TAMPER_OUT4                    110
+#define IMX8DXL_SNVS_TAMPER_IN0                     111
+#define IMX8DXL_SNVS_TAMPER_IN1                     112
+#define IMX8DXL_SNVS_TAMPER_IN2                     113
+#define IMX8DXL_SNVS_TAMPER_IN3                     114
+#define IMX8DXL_SPI1_SCK                            115
+#define IMX8DXL_SPI1_SDO                            116
+#define IMX8DXL_SPI1_SDI                            117
+#define IMX8DXL_SPI1_CS0                            118
+#define IMX8DXL_COMP_CTL_GPIO_1V8_3V3_GPIORHD       119
+#define IMX8DXL_QSPI0A_DATA1                        120
+#define IMX8DXL_QSPI0A_DATA0                        121
+#define IMX8DXL_QSPI0A_DATA3                        122
+#define IMX8DXL_QSPI0A_DATA2                        123
+#define IMX8DXL_QSPI0A_SS0_B                        124
+#define IMX8DXL_QSPI0A_DQS                          125
+#define IMX8DXL_QSPI0A_SCLK                         126
+#define IMX8DXL_COMP_CTL_GPIO_1V8_3V3_QSPI0A        127
+#define IMX8DXL_QSPI0B_SCLK                         128
+#define IMX8DXL_QSPI0B_DQS                          129
+#define IMX8DXL_QSPI0B_DATA1                        130
+#define IMX8DXL_QSPI0B_DATA0                        131
+#define IMX8DXL_QSPI0B_DATA3                        132
+#define IMX8DXL_QSPI0B_DATA2                        133
+#define IMX8DXL_QSPI0B_SS0_B                        134
+#define IMX8DXL_COMP_CTL_GPIO_1V8_3V3_QSPI0B        135
+
+/* format: <pin_id mux_mode> */
+#define IMX8DXL_PCIE_CTRL0_PERST_B_HSIO_PCIE0_PERST_B              IMX8DXL_PCIE_CTRL0_PERST_B            0
+#define IMX8DXL_PCIE_CTRL0_PERST_B_LSIO_GPIO4_IO00                 IMX8DXL_PCIE_CTRL0_PERST_B            4
+#define IMX8DXL_PCIE_CTRL0_PERST_B_LSIO_GPIO7_IO00                 IMX8DXL_PCIE_CTRL0_PERST_B            5
+#define IMX8DXL_PCIE_CTRL0_CLKREQ_B_HSIO_PCIE0_CLKREQ_B            IMX8DXL_PCIE_CTRL0_CLKREQ_B           0
+#define IMX8DXL_PCIE_CTRL0_CLKREQ_B_LSIO_GPIO4_IO01                IMX8DXL_PCIE_CTRL0_CLKREQ_B           4
+#define IMX8DXL_PCIE_CTRL0_CLKREQ_B_LSIO_GPIO7_IO01                IMX8DXL_PCIE_CTRL0_CLKREQ_B           5
+#define IMX8DXL_PCIE_CTRL0_WAKE_B_HSIO_PCIE0_WAKE_B                IMX8DXL_PCIE_CTRL0_WAKE_B             0
+#define IMX8DXL_PCIE_CTRL0_WAKE_B_LSIO_GPIO4_IO02                  IMX8DXL_PCIE_CTRL0_WAKE_B             4
+#define IMX8DXL_PCIE_CTRL0_WAKE_B_LSIO_GPIO7_IO02                  IMX8DXL_PCIE_CTRL0_WAKE_B             5
+#define IMX8DXL_USB_SS3_TC0_ADMA_I2C1_SCL                          IMX8DXL_USB_SS3_TC0                   0
+#define IMX8DXL_USB_SS3_TC0_CONN_USB_OTG1_PWR                      IMX8DXL_USB_SS3_TC0                   1
+#define IMX8DXL_USB_SS3_TC0_CONN_USB_OTG2_PWR                      IMX8DXL_USB_SS3_TC0                   2
+#define IMX8DXL_USB_SS3_TC0_LSIO_GPIO4_IO03                        IMX8DXL_USB_SS3_TC0                   4
+#define IMX8DXL_USB_SS3_TC0_LSIO_GPIO7_IO03                        IMX8DXL_USB_SS3_TC0                   5
+#define IMX8DXL_USB_SS3_TC1_ADMA_I2C1_SCL                          IMX8DXL_USB_SS3_TC1                   0
+#define IMX8DXL_USB_SS3_TC1_CONN_USB_OTG2_PWR                      IMX8DXL_USB_SS3_TC1                   1
+#define IMX8DXL_USB_SS3_TC1_LSIO_GPIO4_IO04                        IMX8DXL_USB_SS3_TC1                   4
+#define IMX8DXL_USB_SS3_TC1_LSIO_GPIO7_IO04                        IMX8DXL_USB_SS3_TC1                   5
+#define IMX8DXL_USB_SS3_TC2_ADMA_I2C1_SDA                          IMX8DXL_USB_SS3_TC2                   0
+#define IMX8DXL_USB_SS3_TC2_CONN_USB_OTG1_OC                       IMX8DXL_USB_SS3_TC2                   1
+#define IMX8DXL_USB_SS3_TC2_CONN_USB_OTG2_OC                       IMX8DXL_USB_SS3_TC2                   2
+#define IMX8DXL_USB_SS3_TC2_LSIO_GPIO4_IO05                        IMX8DXL_USB_SS3_TC2                   4
+#define IMX8DXL_USB_SS3_TC2_LSIO_GPIO7_IO05                        IMX8DXL_USB_SS3_TC2                   5
+#define IMX8DXL_USB_SS3_TC3_ADMA_I2C1_SDA                          IMX8DXL_USB_SS3_TC3                   0
+#define IMX8DXL_USB_SS3_TC3_CONN_USB_OTG2_OC                       IMX8DXL_USB_SS3_TC3                   1
+#define IMX8DXL_USB_SS3_TC3_LSIO_GPIO4_IO06                        IMX8DXL_USB_SS3_TC3                   4
+#define IMX8DXL_USB_SS3_TC3_LSIO_GPIO7_IO06                        IMX8DXL_USB_SS3_TC3                   5
+#define IMX8DXL_EMMC0_CLK_CONN_EMMC0_CLK                           IMX8DXL_EMMC0_CLK                     0
+#define IMX8DXL_EMMC0_CLK_CONN_NAND_READY_B                        IMX8DXL_EMMC0_CLK                     1
+#define IMX8DXL_EMMC0_CLK_LSIO_GPIO4_IO07                          IMX8DXL_EMMC0_CLK                     4
+#define IMX8DXL_EMMC0_CMD_CONN_EMMC0_CMD                           IMX8DXL_EMMC0_CMD                     0
+#define IMX8DXL_EMMC0_CMD_CONN_NAND_DQS                            IMX8DXL_EMMC0_CMD                     1
+#define IMX8DXL_EMMC0_CMD_LSIO_GPIO4_IO08                          IMX8DXL_EMMC0_CMD                     4
+#define IMX8DXL_EMMC0_DATA0_CONN_EMMC0_DATA0                       IMX8DXL_EMMC0_DATA0                   0
+#define IMX8DXL_EMMC0_DATA0_CONN_NAND_DATA00                       IMX8DXL_EMMC0_DATA0                   1
+#define IMX8DXL_EMMC0_DATA0_LSIO_GPIO4_IO09                        IMX8DXL_EMMC0_DATA0                   4
+#define IMX8DXL_EMMC0_DATA1_CONN_EMMC0_DATA1                       IMX8DXL_EMMC0_DATA1                   0
+#define IMX8DXL_EMMC0_DATA1_CONN_NAND_DATA01                       IMX8DXL_EMMC0_DATA1                   1
+#define IMX8DXL_EMMC0_DATA1_LSIO_GPIO4_IO10                        IMX8DXL_EMMC0_DATA1                   4
+#define IMX8DXL_EMMC0_DATA2_CONN_EMMC0_DATA2                       IMX8DXL_EMMC0_DATA2                   0
+#define IMX8DXL_EMMC0_DATA2_CONN_NAND_DATA02                       IMX8DXL_EMMC0_DATA2                   1
+#define IMX8DXL_EMMC0_DATA2_LSIO_GPIO4_IO11                        IMX8DXL_EMMC0_DATA2                   4
+#define IMX8DXL_EMMC0_DATA3_CONN_EMMC0_DATA3                       IMX8DXL_EMMC0_DATA3                   0
+#define IMX8DXL_EMMC0_DATA3_CONN_NAND_DATA03                       IMX8DXL_EMMC0_DATA3                   1
+#define IMX8DXL_EMMC0_DATA3_LSIO_GPIO4_IO12                        IMX8DXL_EMMC0_DATA3                   4
+#define IMX8DXL_EMMC0_DATA4_CONN_EMMC0_DATA4                       IMX8DXL_EMMC0_DATA4                   0
+#define IMX8DXL_EMMC0_DATA4_CONN_NAND_DATA04                       IMX8DXL_EMMC0_DATA4                   1
+#define IMX8DXL_EMMC0_DATA4_LSIO_GPIO4_IO13                        IMX8DXL_EMMC0_DATA4                   4
+#define IMX8DXL_EMMC0_DATA5_CONN_EMMC0_DATA5                       IMX8DXL_EMMC0_DATA5                   0
+#define IMX8DXL_EMMC0_DATA5_CONN_NAND_DATA05                       IMX8DXL_EMMC0_DATA5                   1
+#define IMX8DXL_EMMC0_DATA5_LSIO_GPIO4_IO14                        IMX8DXL_EMMC0_DATA5                   4
+#define IMX8DXL_EMMC0_DATA6_CONN_EMMC0_DATA6                       IMX8DXL_EMMC0_DATA6                   0
+#define IMX8DXL_EMMC0_DATA6_CONN_NAND_DATA06                       IMX8DXL_EMMC0_DATA6                   1
+#define IMX8DXL_EMMC0_DATA6_LSIO_GPIO4_IO15                        IMX8DXL_EMMC0_DATA6                   4
+#define IMX8DXL_EMMC0_DATA7_CONN_EMMC0_DATA7                       IMX8DXL_EMMC0_DATA7                   0
+#define IMX8DXL_EMMC0_DATA7_CONN_NAND_DATA07                       IMX8DXL_EMMC0_DATA7                   1
+#define IMX8DXL_EMMC0_DATA7_LSIO_GPIO4_IO16                        IMX8DXL_EMMC0_DATA7                   4
+#define IMX8DXL_EMMC0_STROBE_CONN_EMMC0_STROBE                     IMX8DXL_EMMC0_STROBE                  0
+#define IMX8DXL_EMMC0_STROBE_CONN_NAND_CLE                         IMX8DXL_EMMC0_STROBE                  1
+#define IMX8DXL_EMMC0_STROBE_LSIO_GPIO4_IO17                       IMX8DXL_EMMC0_STROBE                  4
+#define IMX8DXL_EMMC0_RESET_B_CONN_EMMC0_RESET_B                   IMX8DXL_EMMC0_RESET_B                 0
+#define IMX8DXL_EMMC0_RESET_B_CONN_NAND_WP_B                       IMX8DXL_EMMC0_RESET_B                 1
+#define IMX8DXL_EMMC0_RESET_B_LSIO_GPIO4_IO18                      IMX8DXL_EMMC0_RESET_B                 4
+#define IMX8DXL_USDHC1_RESET_B_CONN_USDHC1_RESET_B                 IMX8DXL_USDHC1_RESET_B                0
+#define IMX8DXL_USDHC1_RESET_B_CONN_NAND_RE_N                      IMX8DXL_USDHC1_RESET_B                1
+#define IMX8DXL_USDHC1_RESET_B_ADMA_SPI2_SCK                       IMX8DXL_USDHC1_RESET_B                2
+#define IMX8DXL_USDHC1_RESET_B_CONN_NAND_WE_B                      IMX8DXL_USDHC1_RESET_B                3
+#define IMX8DXL_USDHC1_RESET_B_LSIO_GPIO4_IO19                     IMX8DXL_USDHC1_RESET_B                4
+#define IMX8DXL_USDHC1_RESET_B_LSIO_GPIO7_IO08                     IMX8DXL_USDHC1_RESET_B                5
+#define IMX8DXL_USDHC1_VSELECT_CONN_USDHC1_VSELECT                 IMX8DXL_USDHC1_VSELECT                0
+#define IMX8DXL_USDHC1_VSELECT_CONN_NAND_RE_P                      IMX8DXL_USDHC1_VSELECT                1
+#define IMX8DXL_USDHC1_VSELECT_ADMA_SPI2_SDO                       IMX8DXL_USDHC1_VSELECT                2
+#define IMX8DXL_USDHC1_VSELECT_CONN_NAND_RE_B                      IMX8DXL_USDHC1_VSELECT                3
+#define IMX8DXL_USDHC1_VSELECT_LSIO_GPIO4_IO20                     IMX8DXL_USDHC1_VSELECT                4
+#define IMX8DXL_USDHC1_VSELECT_LSIO_GPIO7_IO09                     IMX8DXL_USDHC1_VSELECT                5
+#define IMX8DXL_USDHC1_WP_CONN_USDHC1_WP                           IMX8DXL_USDHC1_WP                     0
+#define IMX8DXL_USDHC1_WP_CONN_NAND_DQS_N                          IMX8DXL_USDHC1_WP                     1
+#define IMX8DXL_USDHC1_WP_ADMA_SPI2_SDI                            IMX8DXL_USDHC1_WP                     2
+#define IMX8DXL_USDHC1_WP_CONN_NAND_ALE                            IMX8DXL_USDHC1_WP                     3
+#define IMX8DXL_USDHC1_WP_LSIO_GPIO4_IO21                          IMX8DXL_USDHC1_WP                     4
+#define IMX8DXL_USDHC1_WP_LSIO_GPIO7_IO10                          IMX8DXL_USDHC1_WP                     5
+#define IMX8DXL_USDHC1_CD_B_CONN_USDHC1_CD_B                       IMX8DXL_USDHC1_CD_B                   0
+#define IMX8DXL_USDHC1_CD_B_CONN_NAND_DQS_P                        IMX8DXL_USDHC1_CD_B                   1
+#define IMX8DXL_USDHC1_CD_B_ADMA_SPI2_CS0                          IMX8DXL_USDHC1_CD_B                   2
+#define IMX8DXL_USDHC1_CD_B_CONN_NAND_DQS                          IMX8DXL_USDHC1_CD_B                   3
+#define IMX8DXL_USDHC1_CD_B_LSIO_GPIO4_IO22                        IMX8DXL_USDHC1_CD_B                   4
+#define IMX8DXL_USDHC1_CD_B_LSIO_GPIO7_IO11                        IMX8DXL_USDHC1_CD_B                   5
+#define IMX8DXL_ENET0_RGMII_TXC_CONN_ENET0_RGMII_TXC               IMX8DXL_ENET0_RGMII_TXC               0
+#define IMX8DXL_ENET0_RGMII_TXC_CONN_ENET0_RCLK50M_OUT             IMX8DXL_ENET0_RGMII_TXC               1
+#define IMX8DXL_ENET0_RGMII_TXC_CONN_ENET0_RCLK50M_IN              IMX8DXL_ENET0_RGMII_TXC               2
+#define IMX8DXL_ENET0_RGMII_TXC_CONN_NAND_CE1_B                    IMX8DXL_ENET0_RGMII_TXC               3
+#define IMX8DXL_ENET0_RGMII_TXC_LSIO_GPIO4_IO29                    IMX8DXL_ENET0_RGMII_TXC               4
+#define IMX8DXL_ENET0_RGMII_TXC_CONN_USDHC2_CLK                    IMX8DXL_ENET0_RGMII_TXC               5
+#define IMX8DXL_ENET0_RGMII_TX_CTL_CONN_ENET0_RGMII_TX_CTL         IMX8DXL_ENET0_RGMII_TX_CTL            0
+#define IMX8DXL_ENET0_RGMII_TX_CTL_CONN_USDHC1_RESET_B             IMX8DXL_ENET0_RGMII_TX_CTL            3
+#define IMX8DXL_ENET0_RGMII_TX_CTL_LSIO_GPIO4_IO30                 IMX8DXL_ENET0_RGMII_TX_CTL            4
+#define IMX8DXL_ENET0_RGMII_TX_CTL_CONN_USDHC2_CMD                 IMX8DXL_ENET0_RGMII_TX_CTL            5
+#define IMX8DXL_ENET0_RGMII_TXD0_CONN_ENET0_RGMII_TXD0             IMX8DXL_ENET0_RGMII_TXD0              0
+#define IMX8DXL_ENET0_RGMII_TXD0_CONN_USDHC1_VSELECT               IMX8DXL_ENET0_RGMII_TXD0              3
+#define IMX8DXL_ENET0_RGMII_TXD0_LSIO_GPIO4_IO31                   IMX8DXL_ENET0_RGMII_TXD0              4
+#define IMX8DXL_ENET0_RGMII_TXD0_CONN_USDHC2_DATA0                 IMX8DXL_ENET0_RGMII_TXD0              5
+#define IMX8DXL_ENET0_RGMII_TXD1_CONN_ENET0_RGMII_TXD1             IMX8DXL_ENET0_RGMII_TXD1              0
+#define IMX8DXL_ENET0_RGMII_TXD1_CONN_USDHC1_WP                    IMX8DXL_ENET0_RGMII_TXD1              3
+#define IMX8DXL_ENET0_RGMII_TXD1_LSIO_GPIO5_IO00                   IMX8DXL_ENET0_RGMII_TXD1              4
+#define IMX8DXL_ENET0_RGMII_TXD1_CONN_USDHC2_DATA1                 IMX8DXL_ENET0_RGMII_TXD1              5
+#define IMX8DXL_ENET0_RGMII_TXD2_CONN_ENET0_RGMII_TXD2             IMX8DXL_ENET0_RGMII_TXD2              0
+#define IMX8DXL_ENET0_RGMII_TXD2_CONN_NAND_CE0_B                   IMX8DXL_ENET0_RGMII_TXD2              2
+#define IMX8DXL_ENET0_RGMII_TXD2_CONN_USDHC1_CD_B                  IMX8DXL_ENET0_RGMII_TXD2              3
+#define IMX8DXL_ENET0_RGMII_TXD2_LSIO_GPIO5_IO01                   IMX8DXL_ENET0_RGMII_TXD2              4
+#define IMX8DXL_ENET0_RGMII_TXD2_CONN_USDHC2_DATA2                 IMX8DXL_ENET0_RGMII_TXD2              5
+#define IMX8DXL_ENET0_RGMII_TXD3_CONN_ENET0_RGMII_TXD3             IMX8DXL_ENET0_RGMII_TXD3              0
+#define IMX8DXL_ENET0_RGMII_TXD3_CONN_NAND_RE_B                    IMX8DXL_ENET0_RGMII_TXD3              2
+#define IMX8DXL_ENET0_RGMII_TXD3_LSIO_GPIO5_IO02                   IMX8DXL_ENET0_RGMII_TXD3              4
+#define IMX8DXL_ENET0_RGMII_TXD3_CONN_USDHC2_DATA3                 IMX8DXL_ENET0_RGMII_TXD3              5
+#define IMX8DXL_ENET0_RGMII_RXC_CONN_ENET0_RGMII_RXC               IMX8DXL_ENET0_RGMII_RXC               0
+#define IMX8DXL_ENET0_RGMII_RXC_CONN_NAND_WE_B                     IMX8DXL_ENET0_RGMII_RXC               2
+#define IMX8DXL_ENET0_RGMII_RXC_CONN_USDHC1_CLK                    IMX8DXL_ENET0_RGMII_RXC               3
+#define IMX8DXL_ENET0_RGMII_RXC_LSIO_GPIO5_IO03                    IMX8DXL_ENET0_RGMII_RXC               4
+#define IMX8DXL_ENET0_RGMII_RX_CTL_CONN_ENET0_RGMII_RX_CTL         IMX8DXL_ENET0_RGMII_RX_CTL            0
+#define IMX8DXL_ENET0_RGMII_RX_CTL_CONN_USDHC1_CMD                 IMX8DXL_ENET0_RGMII_RX_CTL            3
+#define IMX8DXL_ENET0_RGMII_RX_CTL_LSIO_GPIO5_IO04                 IMX8DXL_ENET0_RGMII_RX_CTL            4
+#define IMX8DXL_ENET0_RGMII_RXD0_CONN_ENET0_RGMII_RXD0             IMX8DXL_ENET0_RGMII_RXD0              0
+#define IMX8DXL_ENET0_RGMII_RXD0_CONN_USDHC1_DATA0                 IMX8DXL_ENET0_RGMII_RXD0              3
+#define IMX8DXL_ENET0_RGMII_RXD0_LSIO_GPIO5_IO05                   IMX8DXL_ENET0_RGMII_RXD0              4
+#define IMX8DXL_ENET0_RGMII_RXD1_CONN_ENET0_RGMII_RXD1             IMX8DXL_ENET0_RGMII_RXD1              0
+#define IMX8DXL_ENET0_RGMII_RXD1_CONN_USDHC1_DATA1                 IMX8DXL_ENET0_RGMII_RXD1              3
+#define IMX8DXL_ENET0_RGMII_RXD1_LSIO_GPIO5_IO06                   IMX8DXL_ENET0_RGMII_RXD1              4
+#define IMX8DXL_ENET0_RGMII_RXD2_CONN_ENET0_RGMII_RXD2             IMX8DXL_ENET0_RGMII_RXD2              0
+#define IMX8DXL_ENET0_RGMII_RXD2_CONN_ENET0_RMII_RX_ER             IMX8DXL_ENET0_RGMII_RXD2              1
+#define IMX8DXL_ENET0_RGMII_RXD2_CONN_USDHC1_DATA2                 IMX8DXL_ENET0_RGMII_RXD2              3
+#define IMX8DXL_ENET0_RGMII_RXD2_LSIO_GPIO5_IO07                   IMX8DXL_ENET0_RGMII_RXD2              4
+#define IMX8DXL_ENET0_RGMII_RXD3_CONN_ENET0_RGMII_RXD3             IMX8DXL_ENET0_RGMII_RXD3              0
+#define IMX8DXL_ENET0_RGMII_RXD3_CONN_NAND_ALE                     IMX8DXL_ENET0_RGMII_RXD3              2
+#define IMX8DXL_ENET0_RGMII_RXD3_CONN_USDHC1_DATA3                 IMX8DXL_ENET0_RGMII_RXD3              3
+#define IMX8DXL_ENET0_RGMII_RXD3_LSIO_GPIO5_IO08                   IMX8DXL_ENET0_RGMII_RXD3              4
+#define IMX8DXL_ENET0_REFCLK_125M_25M_CONN_ENET0_REFCLK_125M_25M   IMX8DXL_ENET0_REFCLK_125M_25M         0
+#define IMX8DXL_ENET0_REFCLK_125M_25M_CONN_ENET0_PPS               IMX8DXL_ENET0_REFCLK_125M_25M         1
+#define IMX8DXL_ENET0_REFCLK_125M_25M_CONN_EQOS_PPS_IN             IMX8DXL_ENET0_REFCLK_125M_25M         2
+#define IMX8DXL_ENET0_REFCLK_125M_25M_CONN_EQOS_PPS_OUT            IMX8DXL_ENET0_REFCLK_125M_25M         3
+#define IMX8DXL_ENET0_REFCLK_125M_25M_LSIO_GPIO5_IO09              IMX8DXL_ENET0_REFCLK_125M_25M         4
+#define IMX8DXL_ENET0_MDIO_CONN_ENET0_MDIO                         IMX8DXL_ENET0_MDIO                    0
+#define IMX8DXL_ENET0_MDIO_ADMA_I2C3_SDA                           IMX8DXL_ENET0_MDIO                    1
+#define IMX8DXL_ENET0_MDIO_CONN_EQOS_MDIO                          IMX8DXL_ENET0_MDIO                    2
+#define IMX8DXL_ENET0_MDIO_LSIO_GPIO5_IO10                         IMX8DXL_ENET0_MDIO                    4
+#define IMX8DXL_ENET0_MDIO_LSIO_GPIO7_IO16                         IMX8DXL_ENET0_MDIO                    5
+#define IMX8DXL_ENET0_MDC_CONN_ENET0_MDC                           IMX8DXL_ENET0_MDC                     0
+#define IMX8DXL_ENET0_MDC_ADMA_I2C3_SCL                            IMX8DXL_ENET0_MDC                     1
+#define IMX8DXL_ENET0_MDC_CONN_EQOS_MDC                            IMX8DXL_ENET0_MDC                     2
+#define IMX8DXL_ENET0_MDC_LSIO_GPIO5_IO11                          IMX8DXL_ENET0_MDC                     4
+#define IMX8DXL_ENET0_MDC_LSIO_GPIO7_IO17                          IMX8DXL_ENET0_MDC                     5
+#define IMX8DXL_ENET1_RGMII_TXC_LSIO_GPIO0_IO00                    IMX8DXL_ENET1_RGMII_TXC               0
+#define IMX8DXL_ENET1_RGMII_TXC_CONN_EQOS_RCLK50M_OUT              IMX8DXL_ENET1_RGMII_TXC               1
+#define IMX8DXL_ENET1_RGMII_TXC_ADMA_LCDIF_D00                     IMX8DXL_ENET1_RGMII_TXC               2
+#define IMX8DXL_ENET1_RGMII_TXC_CONN_EQOS_RGMII_TXC                IMX8DXL_ENET1_RGMII_TXC               3
+#define IMX8DXL_ENET1_RGMII_TXC_CONN_EQOS_RCLK50M_IN               IMX8DXL_ENET1_RGMII_TXC               4
+#define IMX8DXL_ENET1_RGMII_TXD2_ADMA_LCDIF_D01                    IMX8DXL_ENET1_RGMII_TXD2              2
+#define IMX8DXL_ENET1_RGMII_TXD2_CONN_EQOS_RGMII_TXD2              IMX8DXL_ENET1_RGMII_TXD2              3
+#define IMX8DXL_ENET1_RGMII_TXD2_LSIO_GPIO0_IO01                   IMX8DXL_ENET1_RGMII_TXD2              4
+#define IMX8DXL_ENET1_RGMII_TX_CTL_ADMA_LCDIF_D02                  IMX8DXL_ENET1_RGMII_TX_CTL            2
+#define IMX8DXL_ENET1_RGMII_TX_CTL_CONN_EQOS_RGMII_TX_CTL          IMX8DXL_ENET1_RGMII_TX_CTL            3
+#define IMX8DXL_ENET1_RGMII_TX_CTL_LSIO_GPIO0_IO02                 IMX8DXL_ENET1_RGMII_TX_CTL            4
+#define IMX8DXL_ENET1_RGMII_TXD3_ADMA_LCDIF_D03                    IMX8DXL_ENET1_RGMII_TXD3              2
+#define IMX8DXL_ENET1_RGMII_TXD3_CONN_EQOS_RGMII_TXD3              IMX8DXL_ENET1_RGMII_TXD3              3
+#define IMX8DXL_ENET1_RGMII_TXD3_LSIO_GPIO0_IO03                   IMX8DXL_ENET1_RGMII_TXD3              4
+#define IMX8DXL_ENET1_RGMII_RXC_ADMA_LCDIF_D04                     IMX8DXL_ENET1_RGMII_RXC               2
+#define IMX8DXL_ENET1_RGMII_RXC_CONN_EQOS_RGMII_RXC                IMX8DXL_ENET1_RGMII_RXC               3
+#define IMX8DXL_ENET1_RGMII_RXC_LSIO_GPIO0_IO04                    IMX8DXL_ENET1_RGMII_RXC               4
+#define IMX8DXL_ENET1_RGMII_RXD3_ADMA_LCDIF_D05                    IMX8DXL_ENET1_RGMII_RXD3              2
+#define IMX8DXL_ENET1_RGMII_RXD3_CONN_EQOS_RGMII_RXD3              IMX8DXL_ENET1_RGMII_RXD3              3
+#define IMX8DXL_ENET1_RGMII_RXD3_LSIO_GPIO0_IO05                   IMX8DXL_ENET1_RGMII_RXD3              4
+#define IMX8DXL_ENET1_RGMII_RXD2_ADMA_LCDIF_D06                    IMX8DXL_ENET1_RGMII_RXD2              2
+#define IMX8DXL_ENET1_RGMII_RXD2_CONN_EQOS_RGMII_RXD2              IMX8DXL_ENET1_RGMII_RXD2              3
+#define IMX8DXL_ENET1_RGMII_RXD2_LSIO_GPIO0_IO06                   IMX8DXL_ENET1_RGMII_RXD2              4
+#define IMX8DXL_ENET1_RGMII_RXD2_LSIO_GPIO6_IO00                   IMX8DXL_ENET1_RGMII_RXD2              5
+#define IMX8DXL_ENET1_RGMII_RXD1_ADMA_LCDIF_D07                    IMX8DXL_ENET1_RGMII_RXD1              2
+#define IMX8DXL_ENET1_RGMII_RXD1_CONN_EQOS_RGMII_RXD1              IMX8DXL_ENET1_RGMII_RXD1              3
+#define IMX8DXL_ENET1_RGMII_RXD1_LSIO_GPIO0_IO07                   IMX8DXL_ENET1_RGMII_RXD1              4
+#define IMX8DXL_ENET1_RGMII_RXD1_LSIO_GPIO6_IO01                   IMX8DXL_ENET1_RGMII_RXD1              5
+#define IMX8DXL_ENET1_RGMII_TXD0_ADMA_LCDIF_D08                    IMX8DXL_ENET1_RGMII_TXD0              2
+#define IMX8DXL_ENET1_RGMII_TXD0_CONN_EQOS_RGMII_TXD0              IMX8DXL_ENET1_RGMII_TXD0              3
+#define IMX8DXL_ENET1_RGMII_TXD0_LSIO_GPIO0_IO08                   IMX8DXL_ENET1_RGMII_TXD0              4
+#define IMX8DXL_ENET1_RGMII_TXD0_LSIO_GPIO6_IO02                   IMX8DXL_ENET1_RGMII_TXD0              5
+#define IMX8DXL_ENET1_RGMII_TXD1_ADMA_LCDIF_D09                    IMX8DXL_ENET1_RGMII_TXD1              2
+#define IMX8DXL_ENET1_RGMII_TXD1_CONN_EQOS_RGMII_TXD1              IMX8DXL_ENET1_RGMII_TXD1              3
+#define IMX8DXL_ENET1_RGMII_TXD1_LSIO_GPIO0_IO09                   IMX8DXL_ENET1_RGMII_TXD1              4
+#define IMX8DXL_ENET1_RGMII_TXD1_LSIO_GPIO6_IO03                   IMX8DXL_ENET1_RGMII_TXD1              5
+#define IMX8DXL_ENET1_RGMII_RXD0_ADMA_SPDIF0_RX                    IMX8DXL_ENET1_RGMII_RXD0              0
+#define IMX8DXL_ENET1_RGMII_RXD0_ADMA_MQS_R                        IMX8DXL_ENET1_RGMII_RXD0              1
+#define IMX8DXL_ENET1_RGMII_RXD0_ADMA_LCDIF_D10                    IMX8DXL_ENET1_RGMII_RXD0              2
+#define IMX8DXL_ENET1_RGMII_RXD0_CONN_EQOS_RGMII_RXD0              IMX8DXL_ENET1_RGMII_RXD0              3
+#define IMX8DXL_ENET1_RGMII_RXD0_LSIO_GPIO0_IO10                   IMX8DXL_ENET1_RGMII_RXD0              4
+#define IMX8DXL_ENET1_RGMII_RXD0_LSIO_GPIO6_IO04                   IMX8DXL_ENET1_RGMII_RXD0              5
+#define IMX8DXL_ENET1_RGMII_RX_CTL_ADMA_SPDIF0_TX                  IMX8DXL_ENET1_RGMII_RX_CTL            0
+#define IMX8DXL_ENET1_RGMII_RX_CTL_ADMA_MQS_L                      IMX8DXL_ENET1_RGMII_RX_CTL            1
+#define IMX8DXL_ENET1_RGMII_RX_CTL_ADMA_LCDIF_D11                  IMX8DXL_ENET1_RGMII_RX_CTL            2
+#define IMX8DXL_ENET1_RGMII_RX_CTL_CONN_EQOS_RGMII_RX_CTL          IMX8DXL_ENET1_RGMII_RX_CTL            3
+#define IMX8DXL_ENET1_RGMII_RX_CTL_LSIO_GPIO0_IO11                 IMX8DXL_ENET1_RGMII_RX_CTL            4
+#define IMX8DXL_ENET1_RGMII_RX_CTL_LSIO_GPIO6_IO05                 IMX8DXL_ENET1_RGMII_RX_CTL            5
+#define IMX8DXL_ENET1_REFCLK_125M_25M_ADMA_SPDIF0_EXT_CLK          IMX8DXL_ENET1_REFCLK_125M_25M         0
+#define IMX8DXL_ENET1_REFCLK_125M_25M_ADMA_LCDIF_D12               IMX8DXL_ENET1_REFCLK_125M_25M         2
+#define IMX8DXL_ENET1_REFCLK_125M_25M_CONN_EQOS_REFCLK_125M_25M    IMX8DXL_ENET1_REFCLK_125M_25M         3
+#define IMX8DXL_ENET1_REFCLK_125M_25M_LSIO_GPIO0_IO12              IMX8DXL_ENET1_REFCLK_125M_25M         4
+#define IMX8DXL_ENET1_REFCLK_125M_25M_LSIO_GPIO6_IO06              IMX8DXL_ENET1_REFCLK_125M_25M         5
+#define IMX8DXL_SPI3_SCK_ADMA_SPI3_SCK                             IMX8DXL_SPI3_SCK                      0
+#define IMX8DXL_SPI3_SCK_ADMA_LCDIF_D13                            IMX8DXL_SPI3_SCK                      2
+#define IMX8DXL_SPI3_SCK_LSIO_GPIO0_IO13                           IMX8DXL_SPI3_SCK                      4
+#define IMX8DXL_SPI3_SCK_ADMA_LCDIF_D00                            IMX8DXL_SPI3_SCK                      5
+#define IMX8DXL_SPI3_SDO_ADMA_SPI3_SDO                             IMX8DXL_SPI3_SDO                      0
+#define IMX8DXL_SPI3_SDO_ADMA_LCDIF_D14                            IMX8DXL_SPI3_SDO                      2
+#define IMX8DXL_SPI3_SDO_LSIO_GPIO0_IO14                           IMX8DXL_SPI3_SDO                      4
+#define IMX8DXL_SPI3_SDO_ADMA_LCDIF_D01                            IMX8DXL_SPI3_SDO                      5
+#define IMX8DXL_SPI3_SDI_ADMA_SPI3_SDI                             IMX8DXL_SPI3_SDI                      0
+#define IMX8DXL_SPI3_SDI_ADMA_LCDIF_D15                            IMX8DXL_SPI3_SDI                      2
+#define IMX8DXL_SPI3_SDI_LSIO_GPIO0_IO15                           IMX8DXL_SPI3_SDI                      4
+#define IMX8DXL_SPI3_SDI_ADMA_LCDIF_D02                            IMX8DXL_SPI3_SDI                      5
+#define IMX8DXL_SPI3_CS0_ADMA_SPI3_CS0                             IMX8DXL_SPI3_CS0                      0
+#define IMX8DXL_SPI3_CS0_ADMA_ACM_MCLK_OUT1                        IMX8DXL_SPI3_CS0                      1
+#define IMX8DXL_SPI3_CS0_ADMA_LCDIF_HSYNC                          IMX8DXL_SPI3_CS0                      2
+#define IMX8DXL_SPI3_CS0_LSIO_GPIO0_IO16                           IMX8DXL_SPI3_CS0                      4
+#define IMX8DXL_SPI3_CS0_ADMA_LCDIF_CS                             IMX8DXL_SPI3_CS0                      5
+#define IMX8DXL_SPI3_CS1_ADMA_SPI3_CS1                             IMX8DXL_SPI3_CS1                      0
+#define IMX8DXL_SPI3_CS1_ADMA_I2C3_SCL                             IMX8DXL_SPI3_CS1                      1
+#define IMX8DXL_SPI3_CS1_ADMA_LCDIF_RESET                          IMX8DXL_SPI3_CS1                      2
+#define IMX8DXL_SPI3_CS1_ADMA_SPI2_CS0                             IMX8DXL_SPI3_CS1                      3
+#define IMX8DXL_SPI3_CS1_ADMA_LCDIF_D16                            IMX8DXL_SPI3_CS1                      4
+#define IMX8DXL_SPI3_CS1_ADMA_LCDIF_RD_E                           IMX8DXL_SPI3_CS1                      5
+#define IMX8DXL_MCLK_IN1_ADMA_ACM_MCLK_IN1                         IMX8DXL_MCLK_IN1                      0
+#define IMX8DXL_MCLK_IN1_ADMA_I2C3_SDA                             IMX8DXL_MCLK_IN1                      1
+#define IMX8DXL_MCLK_IN1_ADMA_LCDIF_EN                             IMX8DXL_MCLK_IN1                      2
+#define IMX8DXL_MCLK_IN1_ADMA_SPI2_SCK                             IMX8DXL_MCLK_IN1                      3
+#define IMX8DXL_MCLK_IN1_ADMA_LCDIF_D17                            IMX8DXL_MCLK_IN1                      4
+#define IMX8DXL_MCLK_IN1_ADMA_LCDIF_D03                            IMX8DXL_MCLK_IN1                      5
+#define IMX8DXL_MCLK_IN0_ADMA_ACM_MCLK_IN0                         IMX8DXL_MCLK_IN0                      0
+#define IMX8DXL_MCLK_IN0_ADMA_LCDIF_VSYNC                          IMX8DXL_MCLK_IN0                      2
+#define IMX8DXL_MCLK_IN0_ADMA_SPI2_SDI                             IMX8DXL_MCLK_IN0                      3
+#define IMX8DXL_MCLK_IN0_LSIO_GPIO0_IO19                           IMX8DXL_MCLK_IN0                      4
+#define IMX8DXL_MCLK_IN0_ADMA_LCDIF_RS                             IMX8DXL_MCLK_IN0                      5
+#define IMX8DXL_MCLK_OUT0_ADMA_ACM_MCLK_OUT0                       IMX8DXL_MCLK_OUT0                     0
+#define IMX8DXL_MCLK_OUT0_ADMA_LCDIF_CLK                           IMX8DXL_MCLK_OUT0                     2
+#define IMX8DXL_MCLK_OUT0_ADMA_SPI2_SDO                            IMX8DXL_MCLK_OUT0                     3
+#define IMX8DXL_MCLK_OUT0_LSIO_GPIO0_IO20                          IMX8DXL_MCLK_OUT0                     4
+#define IMX8DXL_MCLK_OUT0_ADMA_LCDIF_WR_RWN                        IMX8DXL_MCLK_OUT0                     5
+#define IMX8DXL_UART1_TX_ADMA_UART1_TX                             IMX8DXL_UART1_TX                      0
+#define IMX8DXL_UART1_TX_LSIO_PWM0_OUT                             IMX8DXL_UART1_TX                      1
+#define IMX8DXL_UART1_TX_LSIO_GPT0_CAPTURE                         IMX8DXL_UART1_TX                      2
+#define IMX8DXL_UART1_TX_LSIO_GPIO0_IO21                           IMX8DXL_UART1_TX                      4
+#define IMX8DXL_UART1_TX_ADMA_LCDIF_D04                            IMX8DXL_UART1_TX                      5
+#define IMX8DXL_UART1_RX_ADMA_UART1_RX                             IMX8DXL_UART1_RX                      0
+#define IMX8DXL_UART1_RX_LSIO_PWM1_OUT                             IMX8DXL_UART1_RX                      1
+#define IMX8DXL_UART1_RX_LSIO_GPT0_COMPARE                         IMX8DXL_UART1_RX                      2
+#define IMX8DXL_UART1_RX_LSIO_GPT1_CLK                             IMX8DXL_UART1_RX                      3
+#define IMX8DXL_UART1_RX_LSIO_GPIO0_IO22                           IMX8DXL_UART1_RX                      4
+#define IMX8DXL_UART1_RX_ADMA_LCDIF_D05                            IMX8DXL_UART1_RX                      5
+#define IMX8DXL_UART1_RTS_B_ADMA_UART1_RTS_B                       IMX8DXL_UART1_RTS_B                   0
+#define IMX8DXL_UART1_RTS_B_LSIO_PWM2_OUT                          IMX8DXL_UART1_RTS_B                   1
+#define IMX8DXL_UART1_RTS_B_ADMA_LCDIF_D16                         IMX8DXL_UART1_RTS_B                   2
+#define IMX8DXL_UART1_RTS_B_LSIO_GPT1_CAPTURE                      IMX8DXL_UART1_RTS_B                   3
+#define IMX8DXL_UART1_RTS_B_LSIO_GPT0_CLK                          IMX8DXL_UART1_RTS_B                   4
+#define IMX8DXL_UART1_RTS_B_ADMA_LCDIF_D06                         IMX8DXL_UART1_RTS_B                   5
+#define IMX8DXL_UART1_CTS_B_ADMA_UART1_CTS_B                       IMX8DXL_UART1_CTS_B                   0
+#define IMX8DXL_UART1_CTS_B_LSIO_PWM3_OUT                          IMX8DXL_UART1_CTS_B                   1
+#define IMX8DXL_UART1_CTS_B_ADMA_LCDIF_D17                         IMX8DXL_UART1_CTS_B                   2
+#define IMX8DXL_UART1_CTS_B_LSIO_GPT1_COMPARE                      IMX8DXL_UART1_CTS_B                   3
+#define IMX8DXL_UART1_CTS_B_LSIO_GPIO0_IO24                        IMX8DXL_UART1_CTS_B                   4
+#define IMX8DXL_UART1_CTS_B_ADMA_LCDIF_D07                         IMX8DXL_UART1_CTS_B                   5
+#define IMX8DXL_SPI0_SCK_ADMA_SPI0_SCK                             IMX8DXL_SPI0_SCK                      0
+#define IMX8DXL_SPI0_SCK_ADMA_SAI0_TXC                             IMX8DXL_SPI0_SCK                      1
+#define IMX8DXL_SPI0_SCK_M40_I2C0_SCL                              IMX8DXL_SPI0_SCK                      2
+#define IMX8DXL_SPI0_SCK_M40_GPIO0_IO00                            IMX8DXL_SPI0_SCK                      3
+#define IMX8DXL_SPI0_SCK_LSIO_GPIO1_IO04                           IMX8DXL_SPI0_SCK                      4
+#define IMX8DXL_SPI0_SCK_ADMA_LCDIF_D08                            IMX8DXL_SPI0_SCK                      5
+#define IMX8DXL_SPI0_SDI_ADMA_SPI0_SDI                             IMX8DXL_SPI0_SDI                      0
+#define IMX8DXL_SPI0_SDI_ADMA_SAI0_TXD                             IMX8DXL_SPI0_SDI                      1
+#define IMX8DXL_SPI0_SDI_M40_TPM0_CH0                              IMX8DXL_SPI0_SDI                      2
+#define IMX8DXL_SPI0_SDI_M40_GPIO0_IO02                            IMX8DXL_SPI0_SDI                      3
+#define IMX8DXL_SPI0_SDI_LSIO_GPIO1_IO05                           IMX8DXL_SPI0_SDI                      4
+#define IMX8DXL_SPI0_SDI_ADMA_LCDIF_D09                            IMX8DXL_SPI0_SDI                      5
+#define IMX8DXL_SPI0_SDO_ADMA_SPI0_SDO                             IMX8DXL_SPI0_SDO                      0
+#define IMX8DXL_SPI0_SDO_ADMA_SAI0_TXFS                            IMX8DXL_SPI0_SDO                      1
+#define IMX8DXL_SPI0_SDO_M40_I2C0_SDA                              IMX8DXL_SPI0_SDO                      2
+#define IMX8DXL_SPI0_SDO_M40_GPIO0_IO01                            IMX8DXL_SPI0_SDO                      3
+#define IMX8DXL_SPI0_SDO_LSIO_GPIO1_IO06                           IMX8DXL_SPI0_SDO                      4
+#define IMX8DXL_SPI0_SDO_ADMA_LCDIF_D10                            IMX8DXL_SPI0_SDO                      5
+#define IMX8DXL_SPI0_CS1_ADMA_SPI0_CS1                             IMX8DXL_SPI0_CS1                      0
+#define IMX8DXL_SPI0_CS1_ADMA_SAI0_RXC                             IMX8DXL_SPI0_CS1                      1
+#define IMX8DXL_SPI0_CS1_ADMA_SAI1_TXD                             IMX8DXL_SPI0_CS1                      2
+#define IMX8DXL_SPI0_CS1_ADMA_LCD_PWM0_OUT                         IMX8DXL_SPI0_CS1                      3
+#define IMX8DXL_SPI0_CS1_LSIO_GPIO1_IO07                           IMX8DXL_SPI0_CS1                      4
+#define IMX8DXL_SPI0_CS1_ADMA_LCDIF_D11                            IMX8DXL_SPI0_CS1                      5
+#define IMX8DXL_SPI0_CS0_ADMA_SPI0_CS0                             IMX8DXL_SPI0_CS0                      0
+#define IMX8DXL_SPI0_CS0_ADMA_SAI0_RXD                             IMX8DXL_SPI0_CS0                      1
+#define IMX8DXL_SPI0_CS0_M40_TPM0_CH1                              IMX8DXL_SPI0_CS0                      2
+#define IMX8DXL_SPI0_CS0_M40_GPIO0_IO03                            IMX8DXL_SPI0_CS0                      3
+#define IMX8DXL_SPI0_CS0_LSIO_GPIO1_IO08                           IMX8DXL_SPI0_CS0                      4
+#define IMX8DXL_SPI0_CS0_ADMA_LCDIF_D12                            IMX8DXL_SPI0_CS0                      5
+#define IMX8DXL_ADC_IN1_ADMA_ADC_IN1                               IMX8DXL_ADC_IN1                       0
+#define IMX8DXL_ADC_IN1_M40_I2C0_SDA                               IMX8DXL_ADC_IN1                       1
+#define IMX8DXL_ADC_IN1_M40_GPIO0_IO01                             IMX8DXL_ADC_IN1                       2
+#define IMX8DXL_ADC_IN1_ADMA_I2C0_SDA                              IMX8DXL_ADC_IN1                       3
+#define IMX8DXL_ADC_IN1_LSIO_GPIO1_IO09                            IMX8DXL_ADC_IN1                       4
+#define IMX8DXL_ADC_IN1_ADMA_LCDIF_D13                             IMX8DXL_ADC_IN1                       5
+#define IMX8DXL_ADC_IN0_ADMA_ADC_IN0                               IMX8DXL_ADC_IN0                       0
+#define IMX8DXL_ADC_IN0_M40_I2C0_SCL                               IMX8DXL_ADC_IN0                       1
+#define IMX8DXL_ADC_IN0_M40_GPIO0_IO00                             IMX8DXL_ADC_IN0                       2
+#define IMX8DXL_ADC_IN0_ADMA_I2C0_SCL                              IMX8DXL_ADC_IN0                       3
+#define IMX8DXL_ADC_IN0_LSIO_GPIO1_IO10                            IMX8DXL_ADC_IN0                       4
+#define IMX8DXL_ADC_IN0_ADMA_LCDIF_D14                             IMX8DXL_ADC_IN0                       5
+#define IMX8DXL_ADC_IN3_ADMA_ADC_IN3                               IMX8DXL_ADC_IN3                       0
+#define IMX8DXL_ADC_IN3_M40_UART0_TX                               IMX8DXL_ADC_IN3                       1
+#define IMX8DXL_ADC_IN3_M40_GPIO0_IO03                             IMX8DXL_ADC_IN3                       2
+#define IMX8DXL_ADC_IN3_ADMA_ACM_MCLK_OUT0                         IMX8DXL_ADC_IN3                       3
+#define IMX8DXL_ADC_IN3_LSIO_GPIO1_IO11                            IMX8DXL_ADC_IN3                       4
+#define IMX8DXL_ADC_IN3_ADMA_LCDIF_D15                             IMX8DXL_ADC_IN3                       5
+#define IMX8DXL_ADC_IN2_ADMA_ADC_IN2                               IMX8DXL_ADC_IN2                       0
+#define IMX8DXL_ADC_IN2_M40_UART0_RX                               IMX8DXL_ADC_IN2                       1
+#define IMX8DXL_ADC_IN2_M40_GPIO0_IO02                             IMX8DXL_ADC_IN2                       2
+#define IMX8DXL_ADC_IN2_ADMA_ACM_MCLK_IN0                          IMX8DXL_ADC_IN2                       3
+#define IMX8DXL_ADC_IN2_LSIO_GPIO1_IO12                            IMX8DXL_ADC_IN2                       4
+#define IMX8DXL_ADC_IN2_ADMA_LCDIF_D16                             IMX8DXL_ADC_IN2                       5
+#define IMX8DXL_ADC_IN5_ADMA_ADC_IN5                               IMX8DXL_ADC_IN5                       0
+#define IMX8DXL_ADC_IN5_M40_TPM0_CH1                               IMX8DXL_ADC_IN5                       1
+#define IMX8DXL_ADC_IN5_M40_GPIO0_IO05                             IMX8DXL_ADC_IN5                       2
+#define IMX8DXL_ADC_IN5_ADMA_LCDIF_LCDBUSY                         IMX8DXL_ADC_IN5                       3
+#define IMX8DXL_ADC_IN5_LSIO_GPIO1_IO13                            IMX8DXL_ADC_IN5                       4
+#define IMX8DXL_ADC_IN5_ADMA_LCDIF_D17                             IMX8DXL_ADC_IN5                       5
+#define IMX8DXL_ADC_IN4_ADMA_ADC_IN4                               IMX8DXL_ADC_IN4                       0
+#define IMX8DXL_ADC_IN4_M40_TPM0_CH0                               IMX8DXL_ADC_IN4                       1
+#define IMX8DXL_ADC_IN4_M40_GPIO0_IO04                             IMX8DXL_ADC_IN4                       2
+#define IMX8DXL_ADC_IN4_ADMA_LCDIF_LCDRESET                        IMX8DXL_ADC_IN4                       3
+#define IMX8DXL_ADC_IN4_LSIO_GPIO1_IO14                            IMX8DXL_ADC_IN4                       4
+#define IMX8DXL_FLEXCAN0_RX_ADMA_FLEXCAN0_RX                       IMX8DXL_FLEXCAN0_RX                   0
+#define IMX8DXL_FLEXCAN0_RX_ADMA_SAI2_RXC                          IMX8DXL_FLEXCAN0_RX                   1
+#define IMX8DXL_FLEXCAN0_RX_ADMA_UART0_RTS_B                       IMX8DXL_FLEXCAN0_RX                   2
+#define IMX8DXL_FLEXCAN0_RX_ADMA_SAI1_TXC                          IMX8DXL_FLEXCAN0_RX                   3
+#define IMX8DXL_FLEXCAN0_RX_LSIO_GPIO1_IO15                        IMX8DXL_FLEXCAN0_RX                   4
+#define IMX8DXL_FLEXCAN0_RX_LSIO_GPIO6_IO08                        IMX8DXL_FLEXCAN0_RX                   5
+#define IMX8DXL_FLEXCAN0_TX_ADMA_FLEXCAN0_TX                       IMX8DXL_FLEXCAN0_TX                   0
+#define IMX8DXL_FLEXCAN0_TX_ADMA_SAI2_RXD                          IMX8DXL_FLEXCAN0_TX                   1
+#define IMX8DXL_FLEXCAN0_TX_ADMA_UART0_CTS_B                       IMX8DXL_FLEXCAN0_TX                   2
+#define IMX8DXL_FLEXCAN0_TX_ADMA_SAI1_TXFS                         IMX8DXL_FLEXCAN0_TX                   3
+#define IMX8DXL_FLEXCAN0_TX_LSIO_GPIO1_IO16                        IMX8DXL_FLEXCAN0_TX                   4
+#define IMX8DXL_FLEXCAN0_TX_LSIO_GPIO6_IO09                        IMX8DXL_FLEXCAN0_TX                   5
+#define IMX8DXL_FLEXCAN1_RX_ADMA_FLEXCAN1_RX                       IMX8DXL_FLEXCAN1_RX                   0
+#define IMX8DXL_FLEXCAN1_RX_ADMA_SAI2_RXFS                         IMX8DXL_FLEXCAN1_RX                   1
+#define IMX8DXL_FLEXCAN1_RX_ADMA_FTM_CH2                           IMX8DXL_FLEXCAN1_RX                   2
+#define IMX8DXL_FLEXCAN1_RX_ADMA_SAI1_TXD                          IMX8DXL_FLEXCAN1_RX                   3
+#define IMX8DXL_FLEXCAN1_RX_LSIO_GPIO1_IO17                        IMX8DXL_FLEXCAN1_RX                   4
+#define IMX8DXL_FLEXCAN1_RX_LSIO_GPIO6_IO10                        IMX8DXL_FLEXCAN1_RX                   5
+#define IMX8DXL_FLEXCAN1_TX_ADMA_FLEXCAN1_TX                       IMX8DXL_FLEXCAN1_TX                   0
+#define IMX8DXL_FLEXCAN1_TX_ADMA_SAI3_RXC                          IMX8DXL_FLEXCAN1_TX                   1
+#define IMX8DXL_FLEXCAN1_TX_ADMA_DMA0_REQ_IN0                      IMX8DXL_FLEXCAN1_TX                   2
+#define IMX8DXL_FLEXCAN1_TX_ADMA_SAI1_RXD                          IMX8DXL_FLEXCAN1_TX                   3
+#define IMX8DXL_FLEXCAN1_TX_LSIO_GPIO1_IO18                        IMX8DXL_FLEXCAN1_TX                   4
+#define IMX8DXL_FLEXCAN1_TX_LSIO_GPIO6_IO11                        IMX8DXL_FLEXCAN1_TX                   5
+#define IMX8DXL_FLEXCAN2_RX_ADMA_FLEXCAN2_RX                       IMX8DXL_FLEXCAN2_RX                   0
+#define IMX8DXL_FLEXCAN2_RX_ADMA_SAI3_RXD                          IMX8DXL_FLEXCAN2_RX                   1
+#define IMX8DXL_FLEXCAN2_RX_ADMA_UART3_RX                          IMX8DXL_FLEXCAN2_RX                   2
+#define IMX8DXL_FLEXCAN2_RX_ADMA_SAI1_RXFS                         IMX8DXL_FLEXCAN2_RX                   3
+#define IMX8DXL_FLEXCAN2_RX_LSIO_GPIO1_IO19                        IMX8DXL_FLEXCAN2_RX                   4
+#define IMX8DXL_FLEXCAN2_RX_LSIO_GPIO6_IO12                        IMX8DXL_FLEXCAN2_RX                   5
+#define IMX8DXL_FLEXCAN2_TX_ADMA_FLEXCAN2_TX                       IMX8DXL_FLEXCAN2_TX                   0
+#define IMX8DXL_FLEXCAN2_TX_ADMA_SAI3_RXFS                         IMX8DXL_FLEXCAN2_TX                   1
+#define IMX8DXL_FLEXCAN2_TX_ADMA_UART3_TX                          IMX8DXL_FLEXCAN2_TX                   2
+#define IMX8DXL_FLEXCAN2_TX_ADMA_SAI1_RXC                          IMX8DXL_FLEXCAN2_TX                   3
+#define IMX8DXL_FLEXCAN2_TX_LSIO_GPIO1_IO20                        IMX8DXL_FLEXCAN2_TX                   4
+#define IMX8DXL_FLEXCAN2_TX_LSIO_GPIO6_IO13                        IMX8DXL_FLEXCAN2_TX                   5
+#define IMX8DXL_UART0_RX_ADMA_UART0_RX                             IMX8DXL_UART0_RX                      0
+#define IMX8DXL_UART0_RX_ADMA_MQS_R                                IMX8DXL_UART0_RX                      1
+#define IMX8DXL_UART0_RX_ADMA_FLEXCAN0_RX                          IMX8DXL_UART0_RX                      2
+#define IMX8DXL_UART0_RX_SCU_UART0_RX                              IMX8DXL_UART0_RX                      3
+#define IMX8DXL_UART0_RX_LSIO_GPIO1_IO21                           IMX8DXL_UART0_RX                      4
+#define IMX8DXL_UART0_RX_LSIO_GPIO6_IO14                           IMX8DXL_UART0_RX                      5
+#define IMX8DXL_UART0_TX_ADMA_UART0_TX                             IMX8DXL_UART0_TX                      0
+#define IMX8DXL_UART0_TX_ADMA_MQS_L                                IMX8DXL_UART0_TX                      1
+#define IMX8DXL_UART0_TX_ADMA_FLEXCAN0_TX                          IMX8DXL_UART0_TX                      2
+#define IMX8DXL_UART0_TX_SCU_UART0_TX                              IMX8DXL_UART0_TX                      3
+#define IMX8DXL_UART0_TX_LSIO_GPIO1_IO22                           IMX8DXL_UART0_TX                      4
+#define IMX8DXL_UART0_TX_LSIO_GPIO6_IO15                           IMX8DXL_UART0_TX                      5
+#define IMX8DXL_UART2_TX_ADMA_UART2_TX                             IMX8DXL_UART2_TX                      0
+#define IMX8DXL_UART2_TX_ADMA_FTM_CH1                              IMX8DXL_UART2_TX                      1
+#define IMX8DXL_UART2_TX_ADMA_FLEXCAN1_TX                          IMX8DXL_UART2_TX                      2
+#define IMX8DXL_UART2_TX_LSIO_GPIO1_IO23                           IMX8DXL_UART2_TX                      4
+#define IMX8DXL_UART2_TX_LSIO_GPIO6_IO16                           IMX8DXL_UART2_TX                      5
+#define IMX8DXL_UART2_RX_ADMA_UART2_RX                             IMX8DXL_UART2_RX                      0
+#define IMX8DXL_UART2_RX_ADMA_FTM_CH0                              IMX8DXL_UART2_RX                      1
+#define IMX8DXL_UART2_RX_ADMA_FLEXCAN1_RX                          IMX8DXL_UART2_RX                      2
+#define IMX8DXL_UART2_RX_LSIO_GPIO1_IO24                           IMX8DXL_UART2_RX                      4
+#define IMX8DXL_UART2_RX_LSIO_GPIO6_IO17                           IMX8DXL_UART2_RX                      5
+#define IMX8DXL_JTAG_TRST_B_SCU_JTAG_TRST_B                        IMX8DXL_JTAG_TRST_B                   0
+#define IMX8DXL_JTAG_TRST_B_SCU_WDOG0_WDOG_OUT                     IMX8DXL_JTAG_TRST_B                   1
+#define IMX8DXL_PMIC_I2C_SCL_SCU_PMIC_I2C_SCL                      IMX8DXL_PMIC_I2C_SCL                  0
+#define IMX8DXL_PMIC_I2C_SCL_SCU_GPIO0_IOXX_PMIC_A35_ON            IMX8DXL_PMIC_I2C_SCL                  1
+#define IMX8DXL_PMIC_I2C_SCL_LSIO_GPIO2_IO01                       IMX8DXL_PMIC_I2C_SCL                  4
+#define IMX8DXL_PMIC_I2C_SDA_SCU_PMIC_I2C_SDA                      IMX8DXL_PMIC_I2C_SDA                  0
+#define IMX8DXL_PMIC_I2C_SDA_SCU_GPIO0_IOXX_PMIC_GPU_ON            IMX8DXL_PMIC_I2C_SDA                  1
+#define IMX8DXL_PMIC_I2C_SDA_LSIO_GPIO2_IO02                       IMX8DXL_PMIC_I2C_SDA                  4
+#define IMX8DXL_PMIC_INT_B_SCU_DSC_PMIC_INT_B                      IMX8DXL_PMIC_INT_B                    0
+#define IMX8DXL_SCU_GPIO0_00_SCU_GPIO0_IO00                        IMX8DXL_SCU_GPIO0_00                  0
+#define IMX8DXL_SCU_GPIO0_00_SCU_UART0_RX                          IMX8DXL_SCU_GPIO0_00                  1
+#define IMX8DXL_SCU_GPIO0_00_M40_UART0_RX                          IMX8DXL_SCU_GPIO0_00                  2
+#define IMX8DXL_SCU_GPIO0_00_ADMA_UART3_RX                         IMX8DXL_SCU_GPIO0_00                  3
+#define IMX8DXL_SCU_GPIO0_00_LSIO_GPIO2_IO03                       IMX8DXL_SCU_GPIO0_00                  4
+#define IMX8DXL_SCU_GPIO0_01_SCU_GPIO0_IO01                        IMX8DXL_SCU_GPIO0_01                  0
+#define IMX8DXL_SCU_GPIO0_01_SCU_UART0_TX                          IMX8DXL_SCU_GPIO0_01                  1
+#define IMX8DXL_SCU_GPIO0_01_M40_UART0_TX                          IMX8DXL_SCU_GPIO0_01                  2
+#define IMX8DXL_SCU_GPIO0_01_ADMA_UART3_TX                         IMX8DXL_SCU_GPIO0_01                  3
+#define IMX8DXL_SCU_GPIO0_01_SCU_WDOG0_WDOG_OUT                    IMX8DXL_SCU_GPIO0_01                  4
+#define IMX8DXL_SCU_PMIC_STANDBY_SCU_DSC_PMIC_STANDBY              IMX8DXL_SCU_PMIC_STANDBY              0
+#define IMX8DXL_SCU_BOOT_MODE1_SCU_DSC_BOOT_MODE1                  IMX8DXL_SCU_BOOT_MODE1                0
+#define IMX8DXL_SCU_BOOT_MODE0_SCU_DSC_BOOT_MODE0                  IMX8DXL_SCU_BOOT_MODE0                0
+#define IMX8DXL_SCU_BOOT_MODE2_SCU_DSC_BOOT_MODE2                  IMX8DXL_SCU_BOOT_MODE2                0
+#define IMX8DXL_SCU_BOOT_MODE2_SCU_DSC_RTC_CLOCK_OUTPUT_32K        IMX8DXL_SCU_BOOT_MODE2                1
+#define IMX8DXL_SNVS_TAMPER_OUT1_LSIO_GPIO2_IO05_IN                IMX8DXL_SNVS_TAMPER_OUT1              4
+#define IMX8DXL_SNVS_TAMPER_OUT1_LSIO_GPIO6_IO19_IN                IMX8DXL_SNVS_TAMPER_OUT1              5
+#define IMX8DXL_SNVS_TAMPER_OUT2_LSIO_GPIO2_IO06_IN                IMX8DXL_SNVS_TAMPER_OUT2              4
+#define IMX8DXL_SNVS_TAMPER_OUT2_LSIO_GPIO6_IO20_IN                IMX8DXL_SNVS_TAMPER_OUT2              5
+#define IMX8DXL_SNVS_TAMPER_OUT3_ADMA_SAI2_RXC                     IMX8DXL_SNVS_TAMPER_OUT3              2
+#define IMX8DXL_SNVS_TAMPER_OUT3_LSIO_GPIO2_IO07_IN                IMX8DXL_SNVS_TAMPER_OUT3              4
+#define IMX8DXL_SNVS_TAMPER_OUT3_LSIO_GPIO6_IO21_IN                IMX8DXL_SNVS_TAMPER_OUT3              5
+#define IMX8DXL_SNVS_TAMPER_OUT4_ADMA_SAI2_RXD                     IMX8DXL_SNVS_TAMPER_OUT4              2
+#define IMX8DXL_SNVS_TAMPER_OUT4_LSIO_GPIO2_IO08_IN                IMX8DXL_SNVS_TAMPER_OUT4              4
+#define IMX8DXL_SNVS_TAMPER_OUT4_LSIO_GPIO6_IO22_IN                IMX8DXL_SNVS_TAMPER_OUT4              5
+#define IMX8DXL_SNVS_TAMPER_IN0_ADMA_SAI2_RXFS                     IMX8DXL_SNVS_TAMPER_IN0               2
+#define IMX8DXL_SNVS_TAMPER_IN0_LSIO_GPIO2_IO09_IN                 IMX8DXL_SNVS_TAMPER_IN0               4
+#define IMX8DXL_SNVS_TAMPER_IN0_LSIO_GPIO6_IO23_IN                 IMX8DXL_SNVS_TAMPER_IN0               5
+#define IMX8DXL_SNVS_TAMPER_IN1_ADMA_SAI3_RXC                      IMX8DXL_SNVS_TAMPER_IN1               2
+#define IMX8DXL_SNVS_TAMPER_IN1_LSIO_GPIO2_IO10_IN                 IMX8DXL_SNVS_TAMPER_IN1               4
+#define IMX8DXL_SNVS_TAMPER_IN1_LSIO_GPIO6_IO24_IN                 IMX8DXL_SNVS_TAMPER_IN1               5
+#define IMX8DXL_SNVS_TAMPER_IN2_ADMA_SAI3_RXD                      IMX8DXL_SNVS_TAMPER_IN2               2
+#define IMX8DXL_SNVS_TAMPER_IN2_LSIO_GPIO2_IO11_IN                 IMX8DXL_SNVS_TAMPER_IN2               4
+#define IMX8DXL_SNVS_TAMPER_IN2_LSIO_GPIO6_IO25_IN                 IMX8DXL_SNVS_TAMPER_IN2               5
+#define IMX8DXL_SNVS_TAMPER_IN3_ADMA_SAI3_RXFS                     IMX8DXL_SNVS_TAMPER_IN3               2
+#define IMX8DXL_SNVS_TAMPER_IN3_LSIO_GPIO2_IO12_IN                 IMX8DXL_SNVS_TAMPER_IN3               4
+#define IMX8DXL_SNVS_TAMPER_IN3_LSIO_GPIO6_IO26_IN                 IMX8DXL_SNVS_TAMPER_IN3               5
+#define IMX8DXL_SPI1_SCK_ADMA_I2C2_SDA                             IMX8DXL_SPI1_SCK                      2
+#define IMX8DXL_SPI1_SCK_ADMA_SPI1_SCK                             IMX8DXL_SPI1_SCK                      3
+#define IMX8DXL_SPI1_SCK_LSIO_GPIO3_IO00                           IMX8DXL_SPI1_SCK                      4
+#define IMX8DXL_SPI1_SDO_ADMA_I2C2_SCL                             IMX8DXL_SPI1_SDO                      2
+#define IMX8DXL_SPI1_SDO_ADMA_SPI1_SDO                             IMX8DXL_SPI1_SDO                      3
+#define IMX8DXL_SPI1_SDO_LSIO_GPIO3_IO01                           IMX8DXL_SPI1_SDO                      4
+#define IMX8DXL_SPI1_SDI_ADMA_I2C3_SCL                             IMX8DXL_SPI1_SDI                      2
+#define IMX8DXL_SPI1_SDI_ADMA_SPI1_SDI                             IMX8DXL_SPI1_SDI                      3
+#define IMX8DXL_SPI1_SDI_LSIO_GPIO3_IO02                           IMX8DXL_SPI1_SDI                      4
+#define IMX8DXL_SPI1_CS0_ADMA_I2C3_SDA                             IMX8DXL_SPI1_CS0                      2
+#define IMX8DXL_SPI1_CS0_ADMA_SPI1_CS0                             IMX8DXL_SPI1_CS0                      3
+#define IMX8DXL_SPI1_CS0_LSIO_GPIO3_IO03                           IMX8DXL_SPI1_CS0                      4
+#define IMX8DXL_QSPI0A_DATA1_LSIO_QSPI0A_DATA1                     IMX8DXL_QSPI0A_DATA1                  0
+#define IMX8DXL_QSPI0A_DATA1_LSIO_GPIO3_IO10                       IMX8DXL_QSPI0A_DATA1                  4
+#define IMX8DXL_QSPI0A_DATA0_LSIO_QSPI0A_DATA0                     IMX8DXL_QSPI0A_DATA0                  0
+#define IMX8DXL_QSPI0A_DATA0_LSIO_GPIO3_IO09                       IMX8DXL_QSPI0A_DATA0                  4
+#define IMX8DXL_QSPI0A_DATA3_LSIO_QSPI0A_DATA3                     IMX8DXL_QSPI0A_DATA3                  0
+#define IMX8DXL_QSPI0A_DATA3_LSIO_GPIO3_IO12                       IMX8DXL_QSPI0A_DATA3                  4
+#define IMX8DXL_QSPI0A_DATA2_LSIO_QSPI0A_DATA2                     IMX8DXL_QSPI0A_DATA2                  0
+#define IMX8DXL_QSPI0A_DATA2_LSIO_GPIO3_IO11                       IMX8DXL_QSPI0A_DATA2                  4
+#define IMX8DXL_QSPI0A_SS0_B_LSIO_QSPI0A_SS0_B                     IMX8DXL_QSPI0A_SS0_B                  0
+#define IMX8DXL_QSPI0A_SS0_B_LSIO_GPIO3_IO14                       IMX8DXL_QSPI0A_SS0_B                  4
+#define IMX8DXL_QSPI0A_DQS_LSIO_QSPI0A_DQS                         IMX8DXL_QSPI0A_DQS                    0
+#define IMX8DXL_QSPI0A_DQS_LSIO_GPIO3_IO13                         IMX8DXL_QSPI0A_DQS                    4
+#define IMX8DXL_QSPI0A_SCLK_LSIO_QSPI0A_SCLK                       IMX8DXL_QSPI0A_SCLK                   0
+#define IMX8DXL_QSPI0A_SCLK_LSIO_GPIO3_IO16                        IMX8DXL_QSPI0A_SCLK                   4
+#define IMX8DXL_QSPI0B_SCLK_LSIO_QSPI0B_SCLK                       IMX8DXL_QSPI0B_SCLK                   0
+#define IMX8DXL_QSPI0B_SCLK_LSIO_GPIO3_IO17                        IMX8DXL_QSPI0B_SCLK                   4
+#define IMX8DXL_QSPI0B_DQS_LSIO_QSPI0B_DQS                         IMX8DXL_QSPI0B_DQS                    0
+#define IMX8DXL_QSPI0B_DQS_LSIO_GPIO3_IO22                         IMX8DXL_QSPI0B_DQS                    4
+#define IMX8DXL_QSPI0B_DATA1_LSIO_QSPI0B_DATA1                     IMX8DXL_QSPI0B_DATA1                  0
+#define IMX8DXL_QSPI0B_DATA1_LSIO_GPIO3_IO19                       IMX8DXL_QSPI0B_DATA1                  4
+#define IMX8DXL_QSPI0B_DATA0_LSIO_QSPI0B_DATA0                     IMX8DXL_QSPI0B_DATA0                  0
+#define IMX8DXL_QSPI0B_DATA0_LSIO_GPIO3_IO18                       IMX8DXL_QSPI0B_DATA0                  4
+#define IMX8DXL_QSPI0B_DATA3_LSIO_QSPI0B_DATA3                     IMX8DXL_QSPI0B_DATA3                  0
+#define IMX8DXL_QSPI0B_DATA3_LSIO_GPIO3_IO21                       IMX8DXL_QSPI0B_DATA3                  4
+#define IMX8DXL_QSPI0B_DATA2_LSIO_QSPI0B_DATA2                     IMX8DXL_QSPI0B_DATA2                  0
+#define IMX8DXL_QSPI0B_DATA2_LSIO_GPIO3_IO20                       IMX8DXL_QSPI0B_DATA2                  4
+#define IMX8DXL_QSPI0B_SS0_B_LSIO_QSPI0B_SS0_B                     IMX8DXL_QSPI0B_SS0_B                  0
+#define IMX8DXL_QSPI0B_SS0_B_LSIO_GPIO3_IO23                       IMX8DXL_QSPI0B_SS0_B                  4
+#define IMX8DXL_QSPI0B_SS0_B_LSIO_QSPI0A_SS1_B                     IMX8DXL_QSPI0B_SS0_B                  5
+
+#define IMX8DXL_COMP_CTL_GPIO_1V8_3V3_PCIESEP_PAD          IMX8DXL_COMP_CTL_GPIO_1V8_3V3_PCIESEP         0
+#define IMX8DXL_COMP_CTL_GPIO_3V3_USB3IO_PAD               IMX8DXL_COMP_CTL_GPIO_3V3_USB3IO              0
+#define IMX8DXL_COMP_CTL_GPIO_1V8_3V3_SD1FIX0_PAD          IMX8DXL_COMP_CTL_GPIO_1V8_3V3_SD1FIX0         0
+#define IMX8DXL_COMP_CTL_GPIO_1V8_3V3_VSELSEP_PAD          IMX8DXL_COMP_CTL_GPIO_1V8_3V3_VSELSEP         0
+#define IMX8DXL_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB0_PAD      IMX8DXL_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB0     0
+#define IMX8DXL_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB1_PAD      IMX8DXL_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB1     0
+#define IMX8DXL_COMP_CTL_GPIO_1V8_3V3_GPIOCT_PAD           IMX8DXL_COMP_CTL_GPIO_1V8_3V3_GPIOCT          0
+#define IMX8DXL_COMP_CTL_GPIO_1V8_3V3_GPIORHB_PAD          IMX8DXL_COMP_CTL_GPIO_1V8_3V3_GPIORHB         0
+#define IMX8DXL_COMP_CTL_GPIO_1V8_3V3_GPIORHK_PAD          IMX8DXL_COMP_CTL_GPIO_1V8_3V3_GPIORHK         0
+#define IMX8DXL_COMP_CTL_GPIO_1V8_3V3_GPIORHT_PAD          IMX8DXL_COMP_CTL_GPIO_1V8_3V3_GPIORHT         0
+#define IMX8DXL_COMP_CTL_GPIO_1V8_3V3_GPIOLH_PAD           IMX8DXL_COMP_CTL_GPIO_1V8_3V3_GPIOLH          0
+#define IMX8DXL_COMP_CTL_GPIO_1V8_3V3_GPIORHD_PAD          IMX8DXL_COMP_CTL_GPIO_1V8_3V3_GPIORHD         0
+#define IMX8DXL_COMP_CTL_GPIO_1V8_3V3_QSPI0A_PAD           IMX8DXL_COMP_CTL_GPIO_1V8_3V3_QSPI0A          0
+#define IMX8DXL_COMP_CTL_GPIO_1V8_3V3_QSPI0B_PAD           IMX8DXL_COMP_CTL_GPIO_1V8_3V3_QSPI0B          0
+
+#endif
diff --git a/include/dt-bindings/reset/amlogic,meson-gxbb-reset.h b/include/dt-bindings/reset/amlogic,meson-gxbb-reset.h
index ea5058618863..883bfd3bcbad 100644
--- a/include/dt-bindings/reset/amlogic,meson-gxbb-reset.h
+++ b/include/dt-bindings/reset/amlogic,meson-gxbb-reset.h
@@ -69,7 +69,7 @@
 #define RESET_SYS_CPU_L2		58
 #define RESET_SYS_CPU_P			59
 #define RESET_SYS_CPU_MBIST		60
-/*					61	*/
+#define RESET_ACODEC			61
 /*					62	*/
 /*					63	*/
 /*	RESET2					*/
diff --git a/include/dt-bindings/reset/imx8mp-reset.h b/include/dt-bindings/reset/imx8mp-reset.h
new file mode 100644
index 000000000000..2e8c9104b666
--- /dev/null
+++ b/include/dt-bindings/reset/imx8mp-reset.h
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright 2020 NXP
+ */
+
+#ifndef DT_BINDING_RESET_IMX8MP_H
+#define DT_BINDING_RESET_IMX8MP_H
+
+#define IMX8MP_RESET_A53_CORE_POR_RESET0	0
+#define IMX8MP_RESET_A53_CORE_POR_RESET1	1
+#define IMX8MP_RESET_A53_CORE_POR_RESET2	2
+#define IMX8MP_RESET_A53_CORE_POR_RESET3	3
+#define IMX8MP_RESET_A53_CORE_RESET0		4
+#define IMX8MP_RESET_A53_CORE_RESET1		5
+#define IMX8MP_RESET_A53_CORE_RESET2		6
+#define IMX8MP_RESET_A53_CORE_RESET3		7
+#define IMX8MP_RESET_A53_DBG_RESET0		8
+#define IMX8MP_RESET_A53_DBG_RESET1		9
+#define IMX8MP_RESET_A53_DBG_RESET2		10
+#define IMX8MP_RESET_A53_DBG_RESET3		11
+#define IMX8MP_RESET_A53_ETM_RESET0		12
+#define IMX8MP_RESET_A53_ETM_RESET1		13
+#define IMX8MP_RESET_A53_ETM_RESET2		14
+#define IMX8MP_RESET_A53_ETM_RESET3		15
+#define IMX8MP_RESET_A53_SOC_DBG_RESET		16
+#define IMX8MP_RESET_A53_L2RESET		17
+#define IMX8MP_RESET_SW_NON_SCLR_M7C_RST	18
+#define IMX8MP_RESET_OTG1_PHY_RESET		19
+#define IMX8MP_RESET_OTG2_PHY_RESET		20
+#define IMX8MP_RESET_SUPERMIX_RESET		21
+#define IMX8MP_RESET_AUDIOMIX_RESET		22
+#define IMX8MP_RESET_MLMIX_RESET		23
+#define IMX8MP_RESET_PCIEPHY			24
+#define IMX8MP_RESET_PCIEPHY_PERST		25
+#define IMX8MP_RESET_PCIE_CTRL_APPS_EN		26
+#define IMX8MP_RESET_PCIE_CTRL_APPS_TURNOFF	27
+#define IMX8MP_RESET_HDMI_PHY_APB_RESET		28
+#define IMX8MP_RESET_MEDIA_RESET		29
+#define IMX8MP_RESET_GPU2D_RESET		30
+#define IMX8MP_RESET_GPU3D_RESET		31
+#define IMX8MP_RESET_GPU_RESET			32
+#define IMX8MP_RESET_VPU_RESET			33
+#define IMX8MP_RESET_VPU_G1_RESET		34
+#define IMX8MP_RESET_VPU_G2_RESET		35
+#define IMX8MP_RESET_VPUVC8KE_RESET		36
+#define IMX8MP_RESET_NOC_RESET			37
+
+#define IMX8MP_RESET_NUM			38
+
+#endif
diff --git a/include/dt-bindings/reset/imx8mq-reset.h b/include/dt-bindings/reset/imx8mq-reset.h
index 9a301082d361..a5b570737582 100644
--- a/include/dt-bindings/reset/imx8mq-reset.h
+++ b/include/dt-bindings/reset/imx8mq-reset.h
@@ -28,36 +28,36 @@
 #define IMX8MQ_RESET_A53_L2RESET		17
 #define IMX8MQ_RESET_SW_NON_SCLR_M4C_RST	18
 #define IMX8MQ_RESET_OTG1_PHY_RESET		19
-#define IMX8MQ_RESET_OTG2_PHY_RESET		20
-#define IMX8MQ_RESET_MIPI_DSI_RESET_BYTE_N	21
-#define IMX8MQ_RESET_MIPI_DSI_RESET_N		22
-#define IMX8MQ_RESET_MIPI_DSI_DPI_RESET_N	23
-#define IMX8MQ_RESET_MIPI_DSI_ESC_RESET_N	24
-#define IMX8MQ_RESET_MIPI_DSI_PCLK_RESET_N	25
-#define IMX8MQ_RESET_PCIEPHY			26
-#define IMX8MQ_RESET_PCIEPHY_PERST		27
-#define IMX8MQ_RESET_PCIE_CTRL_APPS_EN		28
-#define IMX8MQ_RESET_PCIE_CTRL_APPS_TURNOFF	29
-#define IMX8MQ_RESET_HDMI_PHY_APB_RESET		30	/* i.MX8MM does NOT support */
+#define IMX8MQ_RESET_OTG2_PHY_RESET		20	/* i.MX8MN does NOT support */
+#define IMX8MQ_RESET_MIPI_DSI_RESET_BYTE_N	21	/* i.MX8MN does NOT support */
+#define IMX8MQ_RESET_MIPI_DSI_RESET_N		22	/* i.MX8MN does NOT support */
+#define IMX8MQ_RESET_MIPI_DSI_DPI_RESET_N	23	/* i.MX8MN does NOT support */
+#define IMX8MQ_RESET_MIPI_DSI_ESC_RESET_N	24	/* i.MX8MN does NOT support */
+#define IMX8MQ_RESET_MIPI_DSI_PCLK_RESET_N	25	/* i.MX8MN does NOT support */
+#define IMX8MQ_RESET_PCIEPHY			26	/* i.MX8MN does NOT support */
+#define IMX8MQ_RESET_PCIEPHY_PERST		27	/* i.MX8MN does NOT support */
+#define IMX8MQ_RESET_PCIE_CTRL_APPS_EN		28	/* i.MX8MN does NOT support */
+#define IMX8MQ_RESET_PCIE_CTRL_APPS_TURNOFF	29	/* i.MX8MN does NOT support */
+#define IMX8MQ_RESET_HDMI_PHY_APB_RESET		30	/* i.MX8MM/i.MX8MN does NOT support */
 #define IMX8MQ_RESET_DISP_RESET			31
 #define IMX8MQ_RESET_GPU_RESET			32
-#define IMX8MQ_RESET_VPU_RESET			33
-#define IMX8MQ_RESET_PCIEPHY2			34	/* i.MX8MM does NOT support */
-#define IMX8MQ_RESET_PCIEPHY2_PERST		35	/* i.MX8MM does NOT support */
-#define IMX8MQ_RESET_PCIE2_CTRL_APPS_EN		36	/* i.MX8MM does NOT support */
-#define IMX8MQ_RESET_PCIE2_CTRL_APPS_TURNOFF	37	/* i.MX8MM does NOT support */
-#define IMX8MQ_RESET_MIPI_CSI1_CORE_RESET	38	/* i.MX8MM does NOT support */
-#define IMX8MQ_RESET_MIPI_CSI1_PHY_REF_RESET	39	/* i.MX8MM does NOT support */
-#define IMX8MQ_RESET_MIPI_CSI1_ESC_RESET	40	/* i.MX8MM does NOT support */
-#define IMX8MQ_RESET_MIPI_CSI2_CORE_RESET	41	/* i.MX8MM does NOT support */
-#define IMX8MQ_RESET_MIPI_CSI2_PHY_REF_RESET	42	/* i.MX8MM does NOT support */
-#define IMX8MQ_RESET_MIPI_CSI2_ESC_RESET	43	/* i.MX8MM does NOT support */
-#define IMX8MQ_RESET_DDRC1_PRST			44
-#define IMX8MQ_RESET_DDRC1_CORE_RESET		45
-#define IMX8MQ_RESET_DDRC1_PHY_RESET		46
-#define IMX8MQ_RESET_DDRC2_PRST			47	/* i.MX8MM does NOT support */
-#define IMX8MQ_RESET_DDRC2_CORE_RESET		48	/* i.MX8MM does NOT support */
-#define IMX8MQ_RESET_DDRC2_PHY_RESET		49	/* i.MX8MM does NOT support */
+#define IMX8MQ_RESET_VPU_RESET			33	/* i.MX8MN does NOT support */
+#define IMX8MQ_RESET_PCIEPHY2			34	/* i.MX8MM/i.MX8MN does NOT support */
+#define IMX8MQ_RESET_PCIEPHY2_PERST		35	/* i.MX8MM/i.MX8MN does NOT support */
+#define IMX8MQ_RESET_PCIE2_CTRL_APPS_EN		36	/* i.MX8MM/i.MX8MN does NOT support */
+#define IMX8MQ_RESET_PCIE2_CTRL_APPS_TURNOFF	37	/* i.MX8MM/i.MX8MN does NOT support */
+#define IMX8MQ_RESET_MIPI_CSI1_CORE_RESET	38	/* i.MX8MM/i.MX8MN does NOT support */
+#define IMX8MQ_RESET_MIPI_CSI1_PHY_REF_RESET	39	/* i.MX8MM/i.MX8MN does NOT support */
+#define IMX8MQ_RESET_MIPI_CSI1_ESC_RESET	40	/* i.MX8MM/i.MX8MN does NOT support */
+#define IMX8MQ_RESET_MIPI_CSI2_CORE_RESET	41	/* i.MX8MM/i.MX8MN does NOT support */
+#define IMX8MQ_RESET_MIPI_CSI2_PHY_REF_RESET	42	/* i.MX8MM/i.MX8MN does NOT support */
+#define IMX8MQ_RESET_MIPI_CSI2_ESC_RESET	43	/* i.MX8MM/i.MX8MN does NOT support */
+#define IMX8MQ_RESET_DDRC1_PRST			44	/* i.MX8MN does NOT support */
+#define IMX8MQ_RESET_DDRC1_CORE_RESET		45	/* i.MX8MN does NOT support */
+#define IMX8MQ_RESET_DDRC1_PHY_RESET		46	/* i.MX8MN does NOT support */
+#define IMX8MQ_RESET_DDRC2_PRST			47	/* i.MX8MM/i.MX8MN does NOT support */
+#define IMX8MQ_RESET_DDRC2_CORE_RESET		48	/* i.MX8MM/i.MX8MN does NOT support */
+#define IMX8MQ_RESET_DDRC2_PHY_RESET		49	/* i.MX8MM/i.MX8MN does NOT support */
 
 #define IMX8MQ_RESET_NUM			50
 
diff --git a/include/dt-bindings/reset/realtek,rtd1195.h b/include/dt-bindings/reset/realtek,rtd1195.h
new file mode 100644
index 000000000000..27902abf935b
--- /dev/null
+++ b/include/dt-bindings/reset/realtek,rtd1195.h
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */
+/*
+ * Realtek RTD1195 reset controllers
+ *
+ * Copyright (c) 2017 Andreas Färber
+ */
+#ifndef DT_BINDINGS_RESET_RTD1195_H
+#define DT_BINDINGS_RESET_RTD1195_H
+
+/* soft reset 1 */
+#define RTD1195_RSTN_MISC		0
+#define RTD1195_RSTN_RNG		1
+#define RTD1195_RSTN_USB3_POW		2
+#define RTD1195_RSTN_GSPI		3
+#define RTD1195_RSTN_USB3_P0_MDIO	4
+#define RTD1195_RSTN_VE_H265		5
+#define RTD1195_RSTN_USB		6
+#define RTD1195_RSTN_USB_PHY0		8
+#define RTD1195_RSTN_USB_PHY1		9
+#define RTD1195_RSTN_HDMIRX		11
+#define RTD1195_RSTN_HDMI		12
+#define RTD1195_RSTN_ETN		14
+#define RTD1195_RSTN_AIO		15
+#define RTD1195_RSTN_GPU		16
+#define RTD1195_RSTN_VE_H264		17
+#define RTD1195_RSTN_VE_JPEG		18
+#define RTD1195_RSTN_TVE		19
+#define RTD1195_RSTN_VO			20
+#define RTD1195_RSTN_LVDS		21
+#define RTD1195_RSTN_SE			22
+#define RTD1195_RSTN_DCU		23
+#define RTD1195_RSTN_DC_PHY		24
+#define RTD1195_RSTN_CP			25
+#define RTD1195_RSTN_MD			26
+#define RTD1195_RSTN_TP			27
+#define RTD1195_RSTN_AE			28
+#define RTD1195_RSTN_NF			29
+#define RTD1195_RSTN_MIPI		30
+
+/* soft reset 2 */
+#define RTD1195_RSTN_ACPU		0
+#define RTD1195_RSTN_VCPU		1
+#define RTD1195_RSTN_PCR		9
+#define RTD1195_RSTN_CR			10
+#define RTD1195_RSTN_EMMC		11
+#define RTD1195_RSTN_SDIO		12
+#define RTD1195_RSTN_I2C_5		18
+#define RTD1195_RSTN_RTC		20
+#define RTD1195_RSTN_I2C_4		23
+#define RTD1195_RSTN_I2C_3		24
+#define RTD1195_RSTN_I2C_2		25
+#define RTD1195_RSTN_I2C_1		26
+#define RTD1195_RSTN_UR1		28
+
+/* soft reset 3 */
+#define RTD1195_RSTN_SB2		0
+
+/* iso soft reset */
+#define RTD1195_ISO_RSTN_VFD		0
+#define RTD1195_ISO_RSTN_IR		1
+#define RTD1195_ISO_RSTN_CEC0		2
+#define RTD1195_ISO_RSTN_CEC1		3
+#define RTD1195_ISO_RSTN_DP		4
+#define RTD1195_ISO_RSTN_CBUSTX		5
+#define RTD1195_ISO_RSTN_CBUSRX		6
+#define RTD1195_ISO_RSTN_EFUSE		7
+#define RTD1195_ISO_RSTN_UR0		8
+#define RTD1195_ISO_RSTN_GMAC		9
+#define RTD1195_ISO_RSTN_GPHY		10
+#define RTD1195_ISO_RSTN_I2C_0		11
+#define RTD1195_ISO_RSTN_I2C_6		12
+#define RTD1195_ISO_RSTN_CBUS		13
+
+#endif
diff --git a/include/dt-bindings/reset/realtek,rtd1295.h b/include/dt-bindings/reset/realtek,rtd1295.h
index 2c0cb6afe816..dd89e4c80264 100644
--- a/include/dt-bindings/reset/realtek,rtd1295.h
+++ b/include/dt-bindings/reset/realtek,rtd1295.h
@@ -75,6 +75,9 @@
 #define RTD1295_RSTN_CBUS_TX		30
 #define RTD1295_RSTN_SDS_PHY		31
 
+/* soft reset 3 */
+#define RTD1295_RSTN_SB2		0
+
 /* soft reset 4 */
 #define RTD1295_RSTN_DCPHY_CRT		0
 #define RTD1295_RSTN_DCPHY_ALERT_RX	1
diff --git a/include/linux/atomic-fallback.h b/include/linux/atomic-fallback.h
index a7d240e465c0..656b5489b673 100644
--- a/include/linux/atomic-fallback.h
+++ b/include/linux/atomic-fallback.h
@@ -6,6 +6,8 @@
 #ifndef _LINUX_ATOMIC_FALLBACK_H
 #define _LINUX_ATOMIC_FALLBACK_H
 
+#include <linux/compiler.h>
+
 #ifndef xchg_relaxed
 #define xchg_relaxed		xchg
 #define xchg_acquire		xchg
@@ -76,7 +78,7 @@
 #endif /* cmpxchg64_relaxed */
 
 #ifndef atomic_read_acquire
-static inline int
+static __always_inline int
 atomic_read_acquire(const atomic_t *v)
 {
 	return smp_load_acquire(&(v)->counter);
@@ -85,7 +87,7 @@ atomic_read_acquire(const atomic_t *v)
 #endif
 
 #ifndef atomic_set_release
-static inline void
+static __always_inline void
 atomic_set_release(atomic_t *v, int i)
 {
 	smp_store_release(&(v)->counter, i);
@@ -100,7 +102,7 @@ atomic_set_release(atomic_t *v, int i)
 #else /* atomic_add_return_relaxed */
 
 #ifndef atomic_add_return_acquire
-static inline int
+static __always_inline int
 atomic_add_return_acquire(int i, atomic_t *v)
 {
 	int ret = atomic_add_return_relaxed(i, v);
@@ -111,7 +113,7 @@ atomic_add_return_acquire(int i, atomic_t *v)
 #endif
 
 #ifndef atomic_add_return_release
-static inline int
+static __always_inline int
 atomic_add_return_release(int i, atomic_t *v)
 {
 	__atomic_release_fence();
@@ -121,7 +123,7 @@ atomic_add_return_release(int i, atomic_t *v)
 #endif
 
 #ifndef atomic_add_return
-static inline int
+static __always_inline int
 atomic_add_return(int i, atomic_t *v)
 {
 	int ret;
@@ -142,7 +144,7 @@ atomic_add_return(int i, atomic_t *v)
 #else /* atomic_fetch_add_relaxed */
 
 #ifndef atomic_fetch_add_acquire
-static inline int
+static __always_inline int
 atomic_fetch_add_acquire(int i, atomic_t *v)
 {
 	int ret = atomic_fetch_add_relaxed(i, v);
@@ -153,7 +155,7 @@ atomic_fetch_add_acquire(int i, atomic_t *v)
 #endif
 
 #ifndef atomic_fetch_add_release
-static inline int
+static __always_inline int
 atomic_fetch_add_release(int i, atomic_t *v)
 {
 	__atomic_release_fence();
@@ -163,7 +165,7 @@ atomic_fetch_add_release(int i, atomic_t *v)
 #endif
 
 #ifndef atomic_fetch_add
-static inline int
+static __always_inline int
 atomic_fetch_add(int i, atomic_t *v)
 {
 	int ret;
@@ -184,7 +186,7 @@ atomic_fetch_add(int i, atomic_t *v)
 #else /* atomic_sub_return_relaxed */
 
 #ifndef atomic_sub_return_acquire
-static inline int
+static __always_inline int
 atomic_sub_return_acquire(int i, atomic_t *v)
 {
 	int ret = atomic_sub_return_relaxed(i, v);
@@ -195,7 +197,7 @@ atomic_sub_return_acquire(int i, atomic_t *v)
 #endif
 
 #ifndef atomic_sub_return_release
-static inline int
+static __always_inline int
 atomic_sub_return_release(int i, atomic_t *v)
 {
 	__atomic_release_fence();
@@ -205,7 +207,7 @@ atomic_sub_return_release(int i, atomic_t *v)
 #endif
 
 #ifndef atomic_sub_return
-static inline int
+static __always_inline int
 atomic_sub_return(int i, atomic_t *v)
 {
 	int ret;
@@ -226,7 +228,7 @@ atomic_sub_return(int i, atomic_t *v)
 #else /* atomic_fetch_sub_relaxed */
 
 #ifndef atomic_fetch_sub_acquire
-static inline int
+static __always_inline int
 atomic_fetch_sub_acquire(int i, atomic_t *v)
 {
 	int ret = atomic_fetch_sub_relaxed(i, v);
@@ -237,7 +239,7 @@ atomic_fetch_sub_acquire(int i, atomic_t *v)
 #endif
 
 #ifndef atomic_fetch_sub_release
-static inline int
+static __always_inline int
 atomic_fetch_sub_release(int i, atomic_t *v)
 {
 	__atomic_release_fence();
@@ -247,7 +249,7 @@ atomic_fetch_sub_release(int i, atomic_t *v)
 #endif
 
 #ifndef atomic_fetch_sub
-static inline int
+static __always_inline int
 atomic_fetch_sub(int i, atomic_t *v)
 {
 	int ret;
@@ -262,7 +264,7 @@ atomic_fetch_sub(int i, atomic_t *v)
 #endif /* atomic_fetch_sub_relaxed */
 
 #ifndef atomic_inc
-static inline void
+static __always_inline void
 atomic_inc(atomic_t *v)
 {
 	atomic_add(1, v);
@@ -278,7 +280,7 @@ atomic_inc(atomic_t *v)
 #endif /* atomic_inc_return */
 
 #ifndef atomic_inc_return
-static inline int
+static __always_inline int
 atomic_inc_return(atomic_t *v)
 {
 	return atomic_add_return(1, v);
@@ -287,7 +289,7 @@ atomic_inc_return(atomic_t *v)
 #endif
 
 #ifndef atomic_inc_return_acquire
-static inline int
+static __always_inline int
 atomic_inc_return_acquire(atomic_t *v)
 {
 	return atomic_add_return_acquire(1, v);
@@ -296,7 +298,7 @@ atomic_inc_return_acquire(atomic_t *v)
 #endif
 
 #ifndef atomic_inc_return_release
-static inline int
+static __always_inline int
 atomic_inc_return_release(atomic_t *v)
 {
 	return atomic_add_return_release(1, v);
@@ -305,7 +307,7 @@ atomic_inc_return_release(atomic_t *v)
 #endif
 
 #ifndef atomic_inc_return_relaxed
-static inline int
+static __always_inline int
 atomic_inc_return_relaxed(atomic_t *v)
 {
 	return atomic_add_return_relaxed(1, v);
@@ -316,7 +318,7 @@ atomic_inc_return_relaxed(atomic_t *v)
 #else /* atomic_inc_return_relaxed */
 
 #ifndef atomic_inc_return_acquire
-static inline int
+static __always_inline int
 atomic_inc_return_acquire(atomic_t *v)
 {
 	int ret = atomic_inc_return_relaxed(v);
@@ -327,7 +329,7 @@ atomic_inc_return_acquire(atomic_t *v)
 #endif
 
 #ifndef atomic_inc_return_release
-static inline int
+static __always_inline int
 atomic_inc_return_release(atomic_t *v)
 {
 	__atomic_release_fence();
@@ -337,7 +339,7 @@ atomic_inc_return_release(atomic_t *v)
 #endif
 
 #ifndef atomic_inc_return
-static inline int
+static __always_inline int
 atomic_inc_return(atomic_t *v)
 {
 	int ret;
@@ -359,7 +361,7 @@ atomic_inc_return(atomic_t *v)
 #endif /* atomic_fetch_inc */
 
 #ifndef atomic_fetch_inc
-static inline int
+static __always_inline int
 atomic_fetch_inc(atomic_t *v)
 {
 	return atomic_fetch_add(1, v);
@@ -368,7 +370,7 @@ atomic_fetch_inc(atomic_t *v)
 #endif
 
 #ifndef atomic_fetch_inc_acquire
-static inline int
+static __always_inline int
 atomic_fetch_inc_acquire(atomic_t *v)
 {
 	return atomic_fetch_add_acquire(1, v);
@@ -377,7 +379,7 @@ atomic_fetch_inc_acquire(atomic_t *v)
 #endif
 
 #ifndef atomic_fetch_inc_release
-static inline int
+static __always_inline int
 atomic_fetch_inc_release(atomic_t *v)
 {
 	return atomic_fetch_add_release(1, v);
@@ -386,7 +388,7 @@ atomic_fetch_inc_release(atomic_t *v)
 #endif
 
 #ifndef atomic_fetch_inc_relaxed
-static inline int
+static __always_inline int
 atomic_fetch_inc_relaxed(atomic_t *v)
 {
 	return atomic_fetch_add_relaxed(1, v);
@@ -397,7 +399,7 @@ atomic_fetch_inc_relaxed(atomic_t *v)
 #else /* atomic_fetch_inc_relaxed */
 
 #ifndef atomic_fetch_inc_acquire
-static inline int
+static __always_inline int
 atomic_fetch_inc_acquire(atomic_t *v)
 {
 	int ret = atomic_fetch_inc_relaxed(v);
@@ -408,7 +410,7 @@ atomic_fetch_inc_acquire(atomic_t *v)
 #endif
 
 #ifndef atomic_fetch_inc_release
-static inline int
+static __always_inline int
 atomic_fetch_inc_release(atomic_t *v)
 {
 	__atomic_release_fence();
@@ -418,7 +420,7 @@ atomic_fetch_inc_release(atomic_t *v)
 #endif
 
 #ifndef atomic_fetch_inc
-static inline int
+static __always_inline int
 atomic_fetch_inc(atomic_t *v)
 {
 	int ret;
@@ -433,7 +435,7 @@ atomic_fetch_inc(atomic_t *v)
 #endif /* atomic_fetch_inc_relaxed */
 
 #ifndef atomic_dec
-static inline void
+static __always_inline void
 atomic_dec(atomic_t *v)
 {
 	atomic_sub(1, v);
@@ -449,7 +451,7 @@ atomic_dec(atomic_t *v)
 #endif /* atomic_dec_return */
 
 #ifndef atomic_dec_return
-static inline int
+static __always_inline int
 atomic_dec_return(atomic_t *v)
 {
 	return atomic_sub_return(1, v);
@@ -458,7 +460,7 @@ atomic_dec_return(atomic_t *v)
 #endif
 
 #ifndef atomic_dec_return_acquire
-static inline int
+static __always_inline int
 atomic_dec_return_acquire(atomic_t *v)
 {
 	return atomic_sub_return_acquire(1, v);
@@ -467,7 +469,7 @@ atomic_dec_return_acquire(atomic_t *v)
 #endif
 
 #ifndef atomic_dec_return_release
-static inline int
+static __always_inline int
 atomic_dec_return_release(atomic_t *v)
 {
 	return atomic_sub_return_release(1, v);
@@ -476,7 +478,7 @@ atomic_dec_return_release(atomic_t *v)
 #endif
 
 #ifndef atomic_dec_return_relaxed
-static inline int
+static __always_inline int
 atomic_dec_return_relaxed(atomic_t *v)
 {
 	return atomic_sub_return_relaxed(1, v);
@@ -487,7 +489,7 @@ atomic_dec_return_relaxed(atomic_t *v)
 #else /* atomic_dec_return_relaxed */
 
 #ifndef atomic_dec_return_acquire
-static inline int
+static __always_inline int
 atomic_dec_return_acquire(atomic_t *v)
 {
 	int ret = atomic_dec_return_relaxed(v);
@@ -498,7 +500,7 @@ atomic_dec_return_acquire(atomic_t *v)
 #endif
 
 #ifndef atomic_dec_return_release
-static inline int
+static __always_inline int
 atomic_dec_return_release(atomic_t *v)
 {
 	__atomic_release_fence();
@@ -508,7 +510,7 @@ atomic_dec_return_release(atomic_t *v)
 #endif
 
 #ifndef atomic_dec_return
-static inline int
+static __always_inline int
 atomic_dec_return(atomic_t *v)
 {
 	int ret;
@@ -530,7 +532,7 @@ atomic_dec_return(atomic_t *v)
 #endif /* atomic_fetch_dec */
 
 #ifndef atomic_fetch_dec
-static inline int
+static __always_inline int
 atomic_fetch_dec(atomic_t *v)
 {
 	return atomic_fetch_sub(1, v);
@@ -539,7 +541,7 @@ atomic_fetch_dec(atomic_t *v)
 #endif
 
 #ifndef atomic_fetch_dec_acquire
-static inline int
+static __always_inline int
 atomic_fetch_dec_acquire(atomic_t *v)
 {
 	return atomic_fetch_sub_acquire(1, v);
@@ -548,7 +550,7 @@ atomic_fetch_dec_acquire(atomic_t *v)
 #endif
 
 #ifndef atomic_fetch_dec_release
-static inline int
+static __always_inline int
 atomic_fetch_dec_release(atomic_t *v)
 {
 	return atomic_fetch_sub_release(1, v);
@@ -557,7 +559,7 @@ atomic_fetch_dec_release(atomic_t *v)
 #endif
 
 #ifndef atomic_fetch_dec_relaxed
-static inline int
+static __always_inline int
 atomic_fetch_dec_relaxed(atomic_t *v)
 {
 	return atomic_fetch_sub_relaxed(1, v);
@@ -568,7 +570,7 @@ atomic_fetch_dec_relaxed(atomic_t *v)
 #else /* atomic_fetch_dec_relaxed */
 
 #ifndef atomic_fetch_dec_acquire
-static inline int
+static __always_inline int
 atomic_fetch_dec_acquire(atomic_t *v)
 {
 	int ret = atomic_fetch_dec_relaxed(v);
@@ -579,7 +581,7 @@ atomic_fetch_dec_acquire(atomic_t *v)
 #endif
 
 #ifndef atomic_fetch_dec_release
-static inline int
+static __always_inline int
 atomic_fetch_dec_release(atomic_t *v)
 {
 	__atomic_release_fence();
@@ -589,7 +591,7 @@ atomic_fetch_dec_release(atomic_t *v)
 #endif
 
 #ifndef atomic_fetch_dec
-static inline int
+static __always_inline int
 atomic_fetch_dec(atomic_t *v)
 {
 	int ret;
@@ -610,7 +612,7 @@ atomic_fetch_dec(atomic_t *v)
 #else /* atomic_fetch_and_relaxed */
 
 #ifndef atomic_fetch_and_acquire
-static inline int
+static __always_inline int
 atomic_fetch_and_acquire(int i, atomic_t *v)
 {
 	int ret = atomic_fetch_and_relaxed(i, v);
@@ -621,7 +623,7 @@ atomic_fetch_and_acquire(int i, atomic_t *v)
 #endif
 
 #ifndef atomic_fetch_and_release
-static inline int
+static __always_inline int
 atomic_fetch_and_release(int i, atomic_t *v)
 {
 	__atomic_release_fence();
@@ -631,7 +633,7 @@ atomic_fetch_and_release(int i, atomic_t *v)
 #endif
 
 #ifndef atomic_fetch_and
-static inline int
+static __always_inline int
 atomic_fetch_and(int i, atomic_t *v)
 {
 	int ret;
@@ -646,7 +648,7 @@ atomic_fetch_and(int i, atomic_t *v)
 #endif /* atomic_fetch_and_relaxed */
 
 #ifndef atomic_andnot
-static inline void
+static __always_inline void
 atomic_andnot(int i, atomic_t *v)
 {
 	atomic_and(~i, v);
@@ -662,7 +664,7 @@ atomic_andnot(int i, atomic_t *v)
 #endif /* atomic_fetch_andnot */
 
 #ifndef atomic_fetch_andnot
-static inline int
+static __always_inline int
 atomic_fetch_andnot(int i, atomic_t *v)
 {
 	return atomic_fetch_and(~i, v);
@@ -671,7 +673,7 @@ atomic_fetch_andnot(int i, atomic_t *v)
 #endif
 
 #ifndef atomic_fetch_andnot_acquire
-static inline int
+static __always_inline int
 atomic_fetch_andnot_acquire(int i, atomic_t *v)
 {
 	return atomic_fetch_and_acquire(~i, v);
@@ -680,7 +682,7 @@ atomic_fetch_andnot_acquire(int i, atomic_t *v)
 #endif
 
 #ifndef atomic_fetch_andnot_release
-static inline int
+static __always_inline int
 atomic_fetch_andnot_release(int i, atomic_t *v)
 {
 	return atomic_fetch_and_release(~i, v);
@@ -689,7 +691,7 @@ atomic_fetch_andnot_release(int i, atomic_t *v)
 #endif
 
 #ifndef atomic_fetch_andnot_relaxed
-static inline int
+static __always_inline int
 atomic_fetch_andnot_relaxed(int i, atomic_t *v)
 {
 	return atomic_fetch_and_relaxed(~i, v);
@@ -700,7 +702,7 @@ atomic_fetch_andnot_relaxed(int i, atomic_t *v)
 #else /* atomic_fetch_andnot_relaxed */
 
 #ifndef atomic_fetch_andnot_acquire
-static inline int
+static __always_inline int
 atomic_fetch_andnot_acquire(int i, atomic_t *v)
 {
 	int ret = atomic_fetch_andnot_relaxed(i, v);
@@ -711,7 +713,7 @@ atomic_fetch_andnot_acquire(int i, atomic_t *v)
 #endif
 
 #ifndef atomic_fetch_andnot_release
-static inline int
+static __always_inline int
 atomic_fetch_andnot_release(int i, atomic_t *v)
 {
 	__atomic_release_fence();
@@ -721,7 +723,7 @@ atomic_fetch_andnot_release(int i, atomic_t *v)
 #endif
 
 #ifndef atomic_fetch_andnot
-static inline int
+static __always_inline int
 atomic_fetch_andnot(int i, atomic_t *v)
 {
 	int ret;
@@ -742,7 +744,7 @@ atomic_fetch_andnot(int i, atomic_t *v)
 #else /* atomic_fetch_or_relaxed */
 
 #ifndef atomic_fetch_or_acquire
-static inline int
+static __always_inline int
 atomic_fetch_or_acquire(int i, atomic_t *v)
 {
 	int ret = atomic_fetch_or_relaxed(i, v);
@@ -753,7 +755,7 @@ atomic_fetch_or_acquire(int i, atomic_t *v)
 #endif
 
 #ifndef atomic_fetch_or_release
-static inline int
+static __always_inline int
 atomic_fetch_or_release(int i, atomic_t *v)
 {
 	__atomic_release_fence();
@@ -763,7 +765,7 @@ atomic_fetch_or_release(int i, atomic_t *v)
 #endif
 
 #ifndef atomic_fetch_or
-static inline int
+static __always_inline int
 atomic_fetch_or(int i, atomic_t *v)
 {
 	int ret;
@@ -784,7 +786,7 @@ atomic_fetch_or(int i, atomic_t *v)
 #else /* atomic_fetch_xor_relaxed */
 
 #ifndef atomic_fetch_xor_acquire
-static inline int
+static __always_inline int
 atomic_fetch_xor_acquire(int i, atomic_t *v)
 {
 	int ret = atomic_fetch_xor_relaxed(i, v);
@@ -795,7 +797,7 @@ atomic_fetch_xor_acquire(int i, atomic_t *v)
 #endif
 
 #ifndef atomic_fetch_xor_release
-static inline int
+static __always_inline int
 atomic_fetch_xor_release(int i, atomic_t *v)
 {
 	__atomic_release_fence();
@@ -805,7 +807,7 @@ atomic_fetch_xor_release(int i, atomic_t *v)
 #endif
 
 #ifndef atomic_fetch_xor
-static inline int
+static __always_inline int
 atomic_fetch_xor(int i, atomic_t *v)
 {
 	int ret;
@@ -826,7 +828,7 @@ atomic_fetch_xor(int i, atomic_t *v)
 #else /* atomic_xchg_relaxed */
 
 #ifndef atomic_xchg_acquire
-static inline int
+static __always_inline int
 atomic_xchg_acquire(atomic_t *v, int i)
 {
 	int ret = atomic_xchg_relaxed(v, i);
@@ -837,7 +839,7 @@ atomic_xchg_acquire(atomic_t *v, int i)
 #endif
 
 #ifndef atomic_xchg_release
-static inline int
+static __always_inline int
 atomic_xchg_release(atomic_t *v, int i)
 {
 	__atomic_release_fence();
@@ -847,7 +849,7 @@ atomic_xchg_release(atomic_t *v, int i)
 #endif
 
 #ifndef atomic_xchg
-static inline int
+static __always_inline int
 atomic_xchg(atomic_t *v, int i)
 {
 	int ret;
@@ -868,7 +870,7 @@ atomic_xchg(atomic_t *v, int i)
 #else /* atomic_cmpxchg_relaxed */
 
 #ifndef atomic_cmpxchg_acquire
-static inline int
+static __always_inline int
 atomic_cmpxchg_acquire(atomic_t *v, int old, int new)
 {
 	int ret = atomic_cmpxchg_relaxed(v, old, new);
@@ -879,7 +881,7 @@ atomic_cmpxchg_acquire(atomic_t *v, int old, int new)
 #endif
 
 #ifndef atomic_cmpxchg_release
-static inline int
+static __always_inline int
 atomic_cmpxchg_release(atomic_t *v, int old, int new)
 {
 	__atomic_release_fence();
@@ -889,7 +891,7 @@ atomic_cmpxchg_release(atomic_t *v, int old, int new)
 #endif
 
 #ifndef atomic_cmpxchg
-static inline int
+static __always_inline int
 atomic_cmpxchg(atomic_t *v, int old, int new)
 {
 	int ret;
@@ -911,7 +913,7 @@ atomic_cmpxchg(atomic_t *v, int old, int new)
 #endif /* atomic_try_cmpxchg */
 
 #ifndef atomic_try_cmpxchg
-static inline bool
+static __always_inline bool
 atomic_try_cmpxchg(atomic_t *v, int *old, int new)
 {
 	int r, o = *old;
@@ -924,7 +926,7 @@ atomic_try_cmpxchg(atomic_t *v, int *old, int new)
 #endif
 
 #ifndef atomic_try_cmpxchg_acquire
-static inline bool
+static __always_inline bool
 atomic_try_cmpxchg_acquire(atomic_t *v, int *old, int new)
 {
 	int r, o = *old;
@@ -937,7 +939,7 @@ atomic_try_cmpxchg_acquire(atomic_t *v, int *old, int new)
 #endif
 
 #ifndef atomic_try_cmpxchg_release
-static inline bool
+static __always_inline bool
 atomic_try_cmpxchg_release(atomic_t *v, int *old, int new)
 {
 	int r, o = *old;
@@ -950,7 +952,7 @@ atomic_try_cmpxchg_release(atomic_t *v, int *old, int new)
 #endif
 
 #ifndef atomic_try_cmpxchg_relaxed
-static inline bool
+static __always_inline bool
 atomic_try_cmpxchg_relaxed(atomic_t *v, int *old, int new)
 {
 	int r, o = *old;
@@ -965,7 +967,7 @@ atomic_try_cmpxchg_relaxed(atomic_t *v, int *old, int new)
 #else /* atomic_try_cmpxchg_relaxed */
 
 #ifndef atomic_try_cmpxchg_acquire
-static inline bool
+static __always_inline bool
 atomic_try_cmpxchg_acquire(atomic_t *v, int *old, int new)
 {
 	bool ret = atomic_try_cmpxchg_relaxed(v, old, new);
@@ -976,7 +978,7 @@ atomic_try_cmpxchg_acquire(atomic_t *v, int *old, int new)
 #endif
 
 #ifndef atomic_try_cmpxchg_release
-static inline bool
+static __always_inline bool
 atomic_try_cmpxchg_release(atomic_t *v, int *old, int new)
 {
 	__atomic_release_fence();
@@ -986,7 +988,7 @@ atomic_try_cmpxchg_release(atomic_t *v, int *old, int new)
 #endif
 
 #ifndef atomic_try_cmpxchg
-static inline bool
+static __always_inline bool
 atomic_try_cmpxchg(atomic_t *v, int *old, int new)
 {
 	bool ret;
@@ -1010,7 +1012,7 @@ atomic_try_cmpxchg(atomic_t *v, int *old, int new)
  * true if the result is zero, or false for all
  * other cases.
  */
-static inline bool
+static __always_inline bool
 atomic_sub_and_test(int i, atomic_t *v)
 {
 	return atomic_sub_return(i, v) == 0;
@@ -1027,7 +1029,7 @@ atomic_sub_and_test(int i, atomic_t *v)
  * returns true if the result is 0, or false for all other
  * cases.
  */
-static inline bool
+static __always_inline bool
 atomic_dec_and_test(atomic_t *v)
 {
 	return atomic_dec_return(v) == 0;
@@ -1044,7 +1046,7 @@ atomic_dec_and_test(atomic_t *v)
  * and returns true if the result is zero, or false for all
  * other cases.
  */
-static inline bool
+static __always_inline bool
 atomic_inc_and_test(atomic_t *v)
 {
 	return atomic_inc_return(v) == 0;
@@ -1062,7 +1064,7 @@ atomic_inc_and_test(atomic_t *v)
  * if the result is negative, or false when
  * result is greater than or equal to zero.
  */
-static inline bool
+static __always_inline bool
 atomic_add_negative(int i, atomic_t *v)
 {
 	return atomic_add_return(i, v) < 0;
@@ -1080,7 +1082,7 @@ atomic_add_negative(int i, atomic_t *v)
  * Atomically adds @a to @v, so long as @v was not already @u.
  * Returns original value of @v
  */
-static inline int
+static __always_inline int
 atomic_fetch_add_unless(atomic_t *v, int a, int u)
 {
 	int c = atomic_read(v);
@@ -1105,7 +1107,7 @@ atomic_fetch_add_unless(atomic_t *v, int a, int u)
  * Atomically adds @a to @v, if @v was not already @u.
  * Returns true if the addition was done.
  */
-static inline bool
+static __always_inline bool
 atomic_add_unless(atomic_t *v, int a, int u)
 {
 	return atomic_fetch_add_unless(v, a, u) != u;
@@ -1121,7 +1123,7 @@ atomic_add_unless(atomic_t *v, int a, int u)
  * Atomically increments @v by 1, if @v is non-zero.
  * Returns true if the increment was done.
  */
-static inline bool
+static __always_inline bool
 atomic_inc_not_zero(atomic_t *v)
 {
 	return atomic_add_unless(v, 1, 0);
@@ -1130,7 +1132,7 @@ atomic_inc_not_zero(atomic_t *v)
 #endif
 
 #ifndef atomic_inc_unless_negative
-static inline bool
+static __always_inline bool
 atomic_inc_unless_negative(atomic_t *v)
 {
 	int c = atomic_read(v);
@@ -1146,7 +1148,7 @@ atomic_inc_unless_negative(atomic_t *v)
 #endif
 
 #ifndef atomic_dec_unless_positive
-static inline bool
+static __always_inline bool
 atomic_dec_unless_positive(atomic_t *v)
 {
 	int c = atomic_read(v);
@@ -1162,7 +1164,7 @@ atomic_dec_unless_positive(atomic_t *v)
 #endif
 
 #ifndef atomic_dec_if_positive
-static inline int
+static __always_inline int
 atomic_dec_if_positive(atomic_t *v)
 {
 	int dec, c = atomic_read(v);
@@ -1186,7 +1188,7 @@ atomic_dec_if_positive(atomic_t *v)
 #endif
 
 #ifndef atomic64_read_acquire
-static inline s64
+static __always_inline s64
 atomic64_read_acquire(const atomic64_t *v)
 {
 	return smp_load_acquire(&(v)->counter);
@@ -1195,7 +1197,7 @@ atomic64_read_acquire(const atomic64_t *v)
 #endif
 
 #ifndef atomic64_set_release
-static inline void
+static __always_inline void
 atomic64_set_release(atomic64_t *v, s64 i)
 {
 	smp_store_release(&(v)->counter, i);
@@ -1210,7 +1212,7 @@ atomic64_set_release(atomic64_t *v, s64 i)
 #else /* atomic64_add_return_relaxed */
 
 #ifndef atomic64_add_return_acquire
-static inline s64
+static __always_inline s64
 atomic64_add_return_acquire(s64 i, atomic64_t *v)
 {
 	s64 ret = atomic64_add_return_relaxed(i, v);
@@ -1221,7 +1223,7 @@ atomic64_add_return_acquire(s64 i, atomic64_t *v)
 #endif
 
 #ifndef atomic64_add_return_release
-static inline s64
+static __always_inline s64
 atomic64_add_return_release(s64 i, atomic64_t *v)
 {
 	__atomic_release_fence();
@@ -1231,7 +1233,7 @@ atomic64_add_return_release(s64 i, atomic64_t *v)
 #endif
 
 #ifndef atomic64_add_return
-static inline s64
+static __always_inline s64
 atomic64_add_return(s64 i, atomic64_t *v)
 {
 	s64 ret;
@@ -1252,7 +1254,7 @@ atomic64_add_return(s64 i, atomic64_t *v)
 #else /* atomic64_fetch_add_relaxed */
 
 #ifndef atomic64_fetch_add_acquire
-static inline s64
+static __always_inline s64
 atomic64_fetch_add_acquire(s64 i, atomic64_t *v)
 {
 	s64 ret = atomic64_fetch_add_relaxed(i, v);
@@ -1263,7 +1265,7 @@ atomic64_fetch_add_acquire(s64 i, atomic64_t *v)
 #endif
 
 #ifndef atomic64_fetch_add_release
-static inline s64
+static __always_inline s64
 atomic64_fetch_add_release(s64 i, atomic64_t *v)
 {
 	__atomic_release_fence();
@@ -1273,7 +1275,7 @@ atomic64_fetch_add_release(s64 i, atomic64_t *v)
 #endif
 
 #ifndef atomic64_fetch_add
-static inline s64
+static __always_inline s64
 atomic64_fetch_add(s64 i, atomic64_t *v)
 {
 	s64 ret;
@@ -1294,7 +1296,7 @@ atomic64_fetch_add(s64 i, atomic64_t *v)
 #else /* atomic64_sub_return_relaxed */
 
 #ifndef atomic64_sub_return_acquire
-static inline s64
+static __always_inline s64
 atomic64_sub_return_acquire(s64 i, atomic64_t *v)
 {
 	s64 ret = atomic64_sub_return_relaxed(i, v);
@@ -1305,7 +1307,7 @@ atomic64_sub_return_acquire(s64 i, atomic64_t *v)
 #endif
 
 #ifndef atomic64_sub_return_release
-static inline s64
+static __always_inline s64
 atomic64_sub_return_release(s64 i, atomic64_t *v)
 {
 	__atomic_release_fence();
@@ -1315,7 +1317,7 @@ atomic64_sub_return_release(s64 i, atomic64_t *v)
 #endif
 
 #ifndef atomic64_sub_return
-static inline s64
+static __always_inline s64
 atomic64_sub_return(s64 i, atomic64_t *v)
 {
 	s64 ret;
@@ -1336,7 +1338,7 @@ atomic64_sub_return(s64 i, atomic64_t *v)
 #else /* atomic64_fetch_sub_relaxed */
 
 #ifndef atomic64_fetch_sub_acquire
-static inline s64
+static __always_inline s64
 atomic64_fetch_sub_acquire(s64 i, atomic64_t *v)
 {
 	s64 ret = atomic64_fetch_sub_relaxed(i, v);
@@ -1347,7 +1349,7 @@ atomic64_fetch_sub_acquire(s64 i, atomic64_t *v)
 #endif
 
 #ifndef atomic64_fetch_sub_release
-static inline s64
+static __always_inline s64
 atomic64_fetch_sub_release(s64 i, atomic64_t *v)
 {
 	__atomic_release_fence();
@@ -1357,7 +1359,7 @@ atomic64_fetch_sub_release(s64 i, atomic64_t *v)
 #endif
 
 #ifndef atomic64_fetch_sub
-static inline s64
+static __always_inline s64
 atomic64_fetch_sub(s64 i, atomic64_t *v)
 {
 	s64 ret;
@@ -1372,7 +1374,7 @@ atomic64_fetch_sub(s64 i, atomic64_t *v)
 #endif /* atomic64_fetch_sub_relaxed */
 
 #ifndef atomic64_inc
-static inline void
+static __always_inline void
 atomic64_inc(atomic64_t *v)
 {
 	atomic64_add(1, v);
@@ -1388,7 +1390,7 @@ atomic64_inc(atomic64_t *v)
 #endif /* atomic64_inc_return */
 
 #ifndef atomic64_inc_return
-static inline s64
+static __always_inline s64
 atomic64_inc_return(atomic64_t *v)
 {
 	return atomic64_add_return(1, v);
@@ -1397,7 +1399,7 @@ atomic64_inc_return(atomic64_t *v)
 #endif
 
 #ifndef atomic64_inc_return_acquire
-static inline s64
+static __always_inline s64
 atomic64_inc_return_acquire(atomic64_t *v)
 {
 	return atomic64_add_return_acquire(1, v);
@@ -1406,7 +1408,7 @@ atomic64_inc_return_acquire(atomic64_t *v)
 #endif
 
 #ifndef atomic64_inc_return_release
-static inline s64
+static __always_inline s64
 atomic64_inc_return_release(atomic64_t *v)
 {
 	return atomic64_add_return_release(1, v);
@@ -1415,7 +1417,7 @@ atomic64_inc_return_release(atomic64_t *v)
 #endif
 
 #ifndef atomic64_inc_return_relaxed
-static inline s64
+static __always_inline s64
 atomic64_inc_return_relaxed(atomic64_t *v)
 {
 	return atomic64_add_return_relaxed(1, v);
@@ -1426,7 +1428,7 @@ atomic64_inc_return_relaxed(atomic64_t *v)
 #else /* atomic64_inc_return_relaxed */
 
 #ifndef atomic64_inc_return_acquire
-static inline s64
+static __always_inline s64
 atomic64_inc_return_acquire(atomic64_t *v)
 {
 	s64 ret = atomic64_inc_return_relaxed(v);
@@ -1437,7 +1439,7 @@ atomic64_inc_return_acquire(atomic64_t *v)
 #endif
 
 #ifndef atomic64_inc_return_release
-static inline s64
+static __always_inline s64
 atomic64_inc_return_release(atomic64_t *v)
 {
 	__atomic_release_fence();
@@ -1447,7 +1449,7 @@ atomic64_inc_return_release(atomic64_t *v)
 #endif
 
 #ifndef atomic64_inc_return
-static inline s64
+static __always_inline s64
 atomic64_inc_return(atomic64_t *v)
 {
 	s64 ret;
@@ -1469,7 +1471,7 @@ atomic64_inc_return(atomic64_t *v)
 #endif /* atomic64_fetch_inc */
 
 #ifndef atomic64_fetch_inc
-static inline s64
+static __always_inline s64
 atomic64_fetch_inc(atomic64_t *v)
 {
 	return atomic64_fetch_add(1, v);
@@ -1478,7 +1480,7 @@ atomic64_fetch_inc(atomic64_t *v)
 #endif
 
 #ifndef atomic64_fetch_inc_acquire
-static inline s64
+static __always_inline s64
 atomic64_fetch_inc_acquire(atomic64_t *v)
 {
 	return atomic64_fetch_add_acquire(1, v);
@@ -1487,7 +1489,7 @@ atomic64_fetch_inc_acquire(atomic64_t *v)
 #endif
 
 #ifndef atomic64_fetch_inc_release
-static inline s64
+static __always_inline s64
 atomic64_fetch_inc_release(atomic64_t *v)
 {
 	return atomic64_fetch_add_release(1, v);
@@ -1496,7 +1498,7 @@ atomic64_fetch_inc_release(atomic64_t *v)
 #endif
 
 #ifndef atomic64_fetch_inc_relaxed
-static inline s64
+static __always_inline s64
 atomic64_fetch_inc_relaxed(atomic64_t *v)
 {
 	return atomic64_fetch_add_relaxed(1, v);
@@ -1507,7 +1509,7 @@ atomic64_fetch_inc_relaxed(atomic64_t *v)
 #else /* atomic64_fetch_inc_relaxed */
 
 #ifndef atomic64_fetch_inc_acquire
-static inline s64
+static __always_inline s64
 atomic64_fetch_inc_acquire(atomic64_t *v)
 {
 	s64 ret = atomic64_fetch_inc_relaxed(v);
@@ -1518,7 +1520,7 @@ atomic64_fetch_inc_acquire(atomic64_t *v)
 #endif
 
 #ifndef atomic64_fetch_inc_release
-static inline s64
+static __always_inline s64
 atomic64_fetch_inc_release(atomic64_t *v)
 {
 	__atomic_release_fence();
@@ -1528,7 +1530,7 @@ atomic64_fetch_inc_release(atomic64_t *v)
 #endif
 
 #ifndef atomic64_fetch_inc
-static inline s64
+static __always_inline s64
 atomic64_fetch_inc(atomic64_t *v)
 {
 	s64 ret;
@@ -1543,7 +1545,7 @@ atomic64_fetch_inc(atomic64_t *v)
 #endif /* atomic64_fetch_inc_relaxed */
 
 #ifndef atomic64_dec
-static inline void
+static __always_inline void
 atomic64_dec(atomic64_t *v)
 {
 	atomic64_sub(1, v);
@@ -1559,7 +1561,7 @@ atomic64_dec(atomic64_t *v)
 #endif /* atomic64_dec_return */
 
 #ifndef atomic64_dec_return
-static inline s64
+static __always_inline s64
 atomic64_dec_return(atomic64_t *v)
 {
 	return atomic64_sub_return(1, v);
@@ -1568,7 +1570,7 @@ atomic64_dec_return(atomic64_t *v)
 #endif
 
 #ifndef atomic64_dec_return_acquire
-static inline s64
+static __always_inline s64
 atomic64_dec_return_acquire(atomic64_t *v)
 {
 	return atomic64_sub_return_acquire(1, v);
@@ -1577,7 +1579,7 @@ atomic64_dec_return_acquire(atomic64_t *v)
 #endif
 
 #ifndef atomic64_dec_return_release
-static inline s64
+static __always_inline s64
 atomic64_dec_return_release(atomic64_t *v)
 {
 	return atomic64_sub_return_release(1, v);
@@ -1586,7 +1588,7 @@ atomic64_dec_return_release(atomic64_t *v)
 #endif
 
 #ifndef atomic64_dec_return_relaxed
-static inline s64
+static __always_inline s64
 atomic64_dec_return_relaxed(atomic64_t *v)
 {
 	return atomic64_sub_return_relaxed(1, v);
@@ -1597,7 +1599,7 @@ atomic64_dec_return_relaxed(atomic64_t *v)
 #else /* atomic64_dec_return_relaxed */
 
 #ifndef atomic64_dec_return_acquire
-static inline s64
+static __always_inline s64
 atomic64_dec_return_acquire(atomic64_t *v)
 {
 	s64 ret = atomic64_dec_return_relaxed(v);
@@ -1608,7 +1610,7 @@ atomic64_dec_return_acquire(atomic64_t *v)
 #endif
 
 #ifndef atomic64_dec_return_release
-static inline s64
+static __always_inline s64
 atomic64_dec_return_release(atomic64_t *v)
 {
 	__atomic_release_fence();
@@ -1618,7 +1620,7 @@ atomic64_dec_return_release(atomic64_t *v)
 #endif
 
 #ifndef atomic64_dec_return
-static inline s64
+static __always_inline s64
 atomic64_dec_return(atomic64_t *v)
 {
 	s64 ret;
@@ -1640,7 +1642,7 @@ atomic64_dec_return(atomic64_t *v)
 #endif /* atomic64_fetch_dec */
 
 #ifndef atomic64_fetch_dec
-static inline s64
+static __always_inline s64
 atomic64_fetch_dec(atomic64_t *v)
 {
 	return atomic64_fetch_sub(1, v);
@@ -1649,7 +1651,7 @@ atomic64_fetch_dec(atomic64_t *v)
 #endif
 
 #ifndef atomic64_fetch_dec_acquire
-static inline s64
+static __always_inline s64
 atomic64_fetch_dec_acquire(atomic64_t *v)
 {
 	return atomic64_fetch_sub_acquire(1, v);
@@ -1658,7 +1660,7 @@ atomic64_fetch_dec_acquire(atomic64_t *v)
 #endif
 
 #ifndef atomic64_fetch_dec_release
-static inline s64
+static __always_inline s64
 atomic64_fetch_dec_release(atomic64_t *v)
 {
 	return atomic64_fetch_sub_release(1, v);
@@ -1667,7 +1669,7 @@ atomic64_fetch_dec_release(atomic64_t *v)
 #endif
 
 #ifndef atomic64_fetch_dec_relaxed
-static inline s64
+static __always_inline s64
 atomic64_fetch_dec_relaxed(atomic64_t *v)
 {
 	return atomic64_fetch_sub_relaxed(1, v);
@@ -1678,7 +1680,7 @@ atomic64_fetch_dec_relaxed(atomic64_t *v)
 #else /* atomic64_fetch_dec_relaxed */
 
 #ifndef atomic64_fetch_dec_acquire
-static inline s64
+static __always_inline s64
 atomic64_fetch_dec_acquire(atomic64_t *v)
 {
 	s64 ret = atomic64_fetch_dec_relaxed(v);
@@ -1689,7 +1691,7 @@ atomic64_fetch_dec_acquire(atomic64_t *v)
 #endif
 
 #ifndef atomic64_fetch_dec_release
-static inline s64
+static __always_inline s64
 atomic64_fetch_dec_release(atomic64_t *v)
 {
 	__atomic_release_fence();
@@ -1699,7 +1701,7 @@ atomic64_fetch_dec_release(atomic64_t *v)
 #endif
 
 #ifndef atomic64_fetch_dec
-static inline s64
+static __always_inline s64
 atomic64_fetch_dec(atomic64_t *v)
 {
 	s64 ret;
@@ -1720,7 +1722,7 @@ atomic64_fetch_dec(atomic64_t *v)
 #else /* atomic64_fetch_and_relaxed */
 
 #ifndef atomic64_fetch_and_acquire
-static inline s64
+static __always_inline s64
 atomic64_fetch_and_acquire(s64 i, atomic64_t *v)
 {
 	s64 ret = atomic64_fetch_and_relaxed(i, v);
@@ -1731,7 +1733,7 @@ atomic64_fetch_and_acquire(s64 i, atomic64_t *v)
 #endif
 
 #ifndef atomic64_fetch_and_release
-static inline s64
+static __always_inline s64
 atomic64_fetch_and_release(s64 i, atomic64_t *v)
 {
 	__atomic_release_fence();
@@ -1741,7 +1743,7 @@ atomic64_fetch_and_release(s64 i, atomic64_t *v)
 #endif
 
 #ifndef atomic64_fetch_and
-static inline s64
+static __always_inline s64
 atomic64_fetch_and(s64 i, atomic64_t *v)
 {
 	s64 ret;
@@ -1756,7 +1758,7 @@ atomic64_fetch_and(s64 i, atomic64_t *v)
 #endif /* atomic64_fetch_and_relaxed */
 
 #ifndef atomic64_andnot
-static inline void
+static __always_inline void
 atomic64_andnot(s64 i, atomic64_t *v)
 {
 	atomic64_and(~i, v);
@@ -1772,7 +1774,7 @@ atomic64_andnot(s64 i, atomic64_t *v)
 #endif /* atomic64_fetch_andnot */
 
 #ifndef atomic64_fetch_andnot
-static inline s64
+static __always_inline s64
 atomic64_fetch_andnot(s64 i, atomic64_t *v)
 {
 	return atomic64_fetch_and(~i, v);
@@ -1781,7 +1783,7 @@ atomic64_fetch_andnot(s64 i, atomic64_t *v)
 #endif
 
 #ifndef atomic64_fetch_andnot_acquire
-static inline s64
+static __always_inline s64
 atomic64_fetch_andnot_acquire(s64 i, atomic64_t *v)
 {
 	return atomic64_fetch_and_acquire(~i, v);
@@ -1790,7 +1792,7 @@ atomic64_fetch_andnot_acquire(s64 i, atomic64_t *v)
 #endif
 
 #ifndef atomic64_fetch_andnot_release
-static inline s64
+static __always_inline s64
 atomic64_fetch_andnot_release(s64 i, atomic64_t *v)
 {
 	return atomic64_fetch_and_release(~i, v);
@@ -1799,7 +1801,7 @@ atomic64_fetch_andnot_release(s64 i, atomic64_t *v)
 #endif
 
 #ifndef atomic64_fetch_andnot_relaxed
-static inline s64
+static __always_inline s64
 atomic64_fetch_andnot_relaxed(s64 i, atomic64_t *v)
 {
 	return atomic64_fetch_and_relaxed(~i, v);
@@ -1810,7 +1812,7 @@ atomic64_fetch_andnot_relaxed(s64 i, atomic64_t *v)
 #else /* atomic64_fetch_andnot_relaxed */
 
 #ifndef atomic64_fetch_andnot_acquire
-static inline s64
+static __always_inline s64
 atomic64_fetch_andnot_acquire(s64 i, atomic64_t *v)
 {
 	s64 ret = atomic64_fetch_andnot_relaxed(i, v);
@@ -1821,7 +1823,7 @@ atomic64_fetch_andnot_acquire(s64 i, atomic64_t *v)
 #endif
 
 #ifndef atomic64_fetch_andnot_release
-static inline s64
+static __always_inline s64
 atomic64_fetch_andnot_release(s64 i, atomic64_t *v)
 {
 	__atomic_release_fence();
@@ -1831,7 +1833,7 @@ atomic64_fetch_andnot_release(s64 i, atomic64_t *v)
 #endif
 
 #ifndef atomic64_fetch_andnot
-static inline s64
+static __always_inline s64
 atomic64_fetch_andnot(s64 i, atomic64_t *v)
 {
 	s64 ret;
@@ -1852,7 +1854,7 @@ atomic64_fetch_andnot(s64 i, atomic64_t *v)
 #else /* atomic64_fetch_or_relaxed */
 
 #ifndef atomic64_fetch_or_acquire
-static inline s64
+static __always_inline s64
 atomic64_fetch_or_acquire(s64 i, atomic64_t *v)
 {
 	s64 ret = atomic64_fetch_or_relaxed(i, v);
@@ -1863,7 +1865,7 @@ atomic64_fetch_or_acquire(s64 i, atomic64_t *v)
 #endif
 
 #ifndef atomic64_fetch_or_release
-static inline s64
+static __always_inline s64
 atomic64_fetch_or_release(s64 i, atomic64_t *v)
 {
 	__atomic_release_fence();
@@ -1873,7 +1875,7 @@ atomic64_fetch_or_release(s64 i, atomic64_t *v)
 #endif
 
 #ifndef atomic64_fetch_or
-static inline s64
+static __always_inline s64
 atomic64_fetch_or(s64 i, atomic64_t *v)
 {
 	s64 ret;
@@ -1894,7 +1896,7 @@ atomic64_fetch_or(s64 i, atomic64_t *v)
 #else /* atomic64_fetch_xor_relaxed */
 
 #ifndef atomic64_fetch_xor_acquire
-static inline s64
+static __always_inline s64
 atomic64_fetch_xor_acquire(s64 i, atomic64_t *v)
 {
 	s64 ret = atomic64_fetch_xor_relaxed(i, v);
@@ -1905,7 +1907,7 @@ atomic64_fetch_xor_acquire(s64 i, atomic64_t *v)
 #endif
 
 #ifndef atomic64_fetch_xor_release
-static inline s64
+static __always_inline s64
 atomic64_fetch_xor_release(s64 i, atomic64_t *v)
 {
 	__atomic_release_fence();
@@ -1915,7 +1917,7 @@ atomic64_fetch_xor_release(s64 i, atomic64_t *v)
 #endif
 
 #ifndef atomic64_fetch_xor
-static inline s64
+static __always_inline s64
 atomic64_fetch_xor(s64 i, atomic64_t *v)
 {
 	s64 ret;
@@ -1936,7 +1938,7 @@ atomic64_fetch_xor(s64 i, atomic64_t *v)
 #else /* atomic64_xchg_relaxed */
 
 #ifndef atomic64_xchg_acquire
-static inline s64
+static __always_inline s64
 atomic64_xchg_acquire(atomic64_t *v, s64 i)
 {
 	s64 ret = atomic64_xchg_relaxed(v, i);
@@ -1947,7 +1949,7 @@ atomic64_xchg_acquire(atomic64_t *v, s64 i)
 #endif
 
 #ifndef atomic64_xchg_release
-static inline s64
+static __always_inline s64
 atomic64_xchg_release(atomic64_t *v, s64 i)
 {
 	__atomic_release_fence();
@@ -1957,7 +1959,7 @@ atomic64_xchg_release(atomic64_t *v, s64 i)
 #endif
 
 #ifndef atomic64_xchg
-static inline s64
+static __always_inline s64
 atomic64_xchg(atomic64_t *v, s64 i)
 {
 	s64 ret;
@@ -1978,7 +1980,7 @@ atomic64_xchg(atomic64_t *v, s64 i)
 #else /* atomic64_cmpxchg_relaxed */
 
 #ifndef atomic64_cmpxchg_acquire
-static inline s64
+static __always_inline s64
 atomic64_cmpxchg_acquire(atomic64_t *v, s64 old, s64 new)
 {
 	s64 ret = atomic64_cmpxchg_relaxed(v, old, new);
@@ -1989,7 +1991,7 @@ atomic64_cmpxchg_acquire(atomic64_t *v, s64 old, s64 new)
 #endif
 
 #ifndef atomic64_cmpxchg_release
-static inline s64
+static __always_inline s64
 atomic64_cmpxchg_release(atomic64_t *v, s64 old, s64 new)
 {
 	__atomic_release_fence();
@@ -1999,7 +2001,7 @@ atomic64_cmpxchg_release(atomic64_t *v, s64 old, s64 new)
 #endif
 
 #ifndef atomic64_cmpxchg
-static inline s64
+static __always_inline s64
 atomic64_cmpxchg(atomic64_t *v, s64 old, s64 new)
 {
 	s64 ret;
@@ -2021,7 +2023,7 @@ atomic64_cmpxchg(atomic64_t *v, s64 old, s64 new)
 #endif /* atomic64_try_cmpxchg */
 
 #ifndef atomic64_try_cmpxchg
-static inline bool
+static __always_inline bool
 atomic64_try_cmpxchg(atomic64_t *v, s64 *old, s64 new)
 {
 	s64 r, o = *old;
@@ -2034,7 +2036,7 @@ atomic64_try_cmpxchg(atomic64_t *v, s64 *old, s64 new)
 #endif
 
 #ifndef atomic64_try_cmpxchg_acquire
-static inline bool
+static __always_inline bool
 atomic64_try_cmpxchg_acquire(atomic64_t *v, s64 *old, s64 new)
 {
 	s64 r, o = *old;
@@ -2047,7 +2049,7 @@ atomic64_try_cmpxchg_acquire(atomic64_t *v, s64 *old, s64 new)
 #endif
 
 #ifndef atomic64_try_cmpxchg_release
-static inline bool
+static __always_inline bool
 atomic64_try_cmpxchg_release(atomic64_t *v, s64 *old, s64 new)
 {
 	s64 r, o = *old;
@@ -2060,7 +2062,7 @@ atomic64_try_cmpxchg_release(atomic64_t *v, s64 *old, s64 new)
 #endif
 
 #ifndef atomic64_try_cmpxchg_relaxed
-static inline bool
+static __always_inline bool
 atomic64_try_cmpxchg_relaxed(atomic64_t *v, s64 *old, s64 new)
 {
 	s64 r, o = *old;
@@ -2075,7 +2077,7 @@ atomic64_try_cmpxchg_relaxed(atomic64_t *v, s64 *old, s64 new)
 #else /* atomic64_try_cmpxchg_relaxed */
 
 #ifndef atomic64_try_cmpxchg_acquire
-static inline bool
+static __always_inline bool
 atomic64_try_cmpxchg_acquire(atomic64_t *v, s64 *old, s64 new)
 {
 	bool ret = atomic64_try_cmpxchg_relaxed(v, old, new);
@@ -2086,7 +2088,7 @@ atomic64_try_cmpxchg_acquire(atomic64_t *v, s64 *old, s64 new)
 #endif
 
 #ifndef atomic64_try_cmpxchg_release
-static inline bool
+static __always_inline bool
 atomic64_try_cmpxchg_release(atomic64_t *v, s64 *old, s64 new)
 {
 	__atomic_release_fence();
@@ -2096,7 +2098,7 @@ atomic64_try_cmpxchg_release(atomic64_t *v, s64 *old, s64 new)
 #endif
 
 #ifndef atomic64_try_cmpxchg
-static inline bool
+static __always_inline bool
 atomic64_try_cmpxchg(atomic64_t *v, s64 *old, s64 new)
 {
 	bool ret;
@@ -2120,7 +2122,7 @@ atomic64_try_cmpxchg(atomic64_t *v, s64 *old, s64 new)
  * true if the result is zero, or false for all
  * other cases.
  */
-static inline bool
+static __always_inline bool
 atomic64_sub_and_test(s64 i, atomic64_t *v)
 {
 	return atomic64_sub_return(i, v) == 0;
@@ -2137,7 +2139,7 @@ atomic64_sub_and_test(s64 i, atomic64_t *v)
  * returns true if the result is 0, or false for all other
  * cases.
  */
-static inline bool
+static __always_inline bool
 atomic64_dec_and_test(atomic64_t *v)
 {
 	return atomic64_dec_return(v) == 0;
@@ -2154,7 +2156,7 @@ atomic64_dec_and_test(atomic64_t *v)
  * and returns true if the result is zero, or false for all
  * other cases.
  */
-static inline bool
+static __always_inline bool
 atomic64_inc_and_test(atomic64_t *v)
 {
 	return atomic64_inc_return(v) == 0;
@@ -2172,7 +2174,7 @@ atomic64_inc_and_test(atomic64_t *v)
  * if the result is negative, or false when
  * result is greater than or equal to zero.
  */
-static inline bool
+static __always_inline bool
 atomic64_add_negative(s64 i, atomic64_t *v)
 {
 	return atomic64_add_return(i, v) < 0;
@@ -2190,7 +2192,7 @@ atomic64_add_negative(s64 i, atomic64_t *v)
  * Atomically adds @a to @v, so long as @v was not already @u.
  * Returns original value of @v
  */
-static inline s64
+static __always_inline s64
 atomic64_fetch_add_unless(atomic64_t *v, s64 a, s64 u)
 {
 	s64 c = atomic64_read(v);
@@ -2215,7 +2217,7 @@ atomic64_fetch_add_unless(atomic64_t *v, s64 a, s64 u)
  * Atomically adds @a to @v, if @v was not already @u.
  * Returns true if the addition was done.
  */
-static inline bool
+static __always_inline bool
 atomic64_add_unless(atomic64_t *v, s64 a, s64 u)
 {
 	return atomic64_fetch_add_unless(v, a, u) != u;
@@ -2231,7 +2233,7 @@ atomic64_add_unless(atomic64_t *v, s64 a, s64 u)
  * Atomically increments @v by 1, if @v is non-zero.
  * Returns true if the increment was done.
  */
-static inline bool
+static __always_inline bool
 atomic64_inc_not_zero(atomic64_t *v)
 {
 	return atomic64_add_unless(v, 1, 0);
@@ -2240,7 +2242,7 @@ atomic64_inc_not_zero(atomic64_t *v)
 #endif
 
 #ifndef atomic64_inc_unless_negative
-static inline bool
+static __always_inline bool
 atomic64_inc_unless_negative(atomic64_t *v)
 {
 	s64 c = atomic64_read(v);
@@ -2256,7 +2258,7 @@ atomic64_inc_unless_negative(atomic64_t *v)
 #endif
 
 #ifndef atomic64_dec_unless_positive
-static inline bool
+static __always_inline bool
 atomic64_dec_unless_positive(atomic64_t *v)
 {
 	s64 c = atomic64_read(v);
@@ -2272,7 +2274,7 @@ atomic64_dec_unless_positive(atomic64_t *v)
 #endif
 
 #ifndef atomic64_dec_if_positive
-static inline s64
+static __always_inline s64
 atomic64_dec_if_positive(atomic64_t *v)
 {
 	s64 dec, c = atomic64_read(v);
@@ -2292,4 +2294,4 @@ atomic64_dec_if_positive(atomic64_t *v)
 #define atomic64_cond_read_relaxed(v, c) smp_cond_load_relaxed(&(v)->counter, (c))
 
 #endif /* _LINUX_ATOMIC_FALLBACK_H */
-// 25de4a2804d70f57e994fe3b419148658bb5378a
+// baaf45f4c24ed88ceae58baca39d7fd80bb8101b
diff --git a/include/linux/bio.h b/include/linux/bio.h
index c1c0f9ea4e63..a0ee494a6329 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -319,7 +319,7 @@ struct bio_integrity_payload {
 	struct work_struct	bip_work;	/* I/O completion */
 
 	struct bio_vec		*bip_vec;
-	struct bio_vec		bip_inline_vecs[0];/* embedded bvec array */
+	struct bio_vec		bip_inline_vecs[];/* embedded bvec array */
 };
 
 #if defined(CONFIG_BLK_DEV_INTEGRITY)
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h
index f389d7c724bd..b45148ba3291 100644
--- a/include/linux/blk-mq.h
+++ b/include/linux/blk-mq.h
@@ -173,7 +173,7 @@ struct blk_mq_hw_ctx {
 	 * blocking (BLK_MQ_F_BLOCKING). Must be the last member - see also
 	 * blk_mq_hw_ctx_size().
 	 */
-	struct srcu_struct	srcu[0];
+	struct srcu_struct	srcu[];
 };
 
 /**
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index 70254ae11769..31eb92876be7 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -198,7 +198,7 @@ struct bio {
 	 * double allocations for a small number of bio_vecs. This member
 	 * MUST obviously be kept at the very end of the bio.
 	 */
-	struct bio_vec		bi_inline_vecs[0];
+	struct bio_vec		bi_inline_vecs[];
 };
 
 #define BIO_RESET_BYTES		offsetof(struct bio, bi_max_vecs)
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index e0b020eaf32e..15b765a181b8 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -189,6 +189,8 @@ struct buffer_head *__getblk_gfp(struct block_device *bdev, sector_t block,
 void __brelse(struct buffer_head *);
 void __bforget(struct buffer_head *);
 void __breadahead(struct block_device *, sector_t block, unsigned int size);
+void __breadahead_gfp(struct block_device *, sector_t block, unsigned int size,
+		  gfp_t gfp);
 struct buffer_head *__bread_gfp(struct block_device *,
 				sector_t block, unsigned size, gfp_t gfp);
 void invalidate_bh_lrus(void);
@@ -319,6 +321,12 @@ sb_breadahead(struct super_block *sb, sector_t block)
 	__breadahead(sb->s_bdev, block, sb->s_blocksize);
 }
 
+static inline void
+sb_breadahead_unmovable(struct super_block *sb, sector_t block)
+{
+	__breadahead_gfp(sb->s_bdev, block, sb->s_blocksize, 0);
+}
+
 static inline struct buffer_head *
 sb_getblk(struct super_block *sb, sector_t block)
 {
diff --git a/include/linux/can/dev/peak_canfd.h b/include/linux/can/dev/peak_canfd.h
index 511a37302fea..5fd627e9da19 100644
--- a/include/linux/can/dev/peak_canfd.h
+++ b/include/linux/can/dev/peak_canfd.h
@@ -189,7 +189,7 @@ struct __packed pucan_rx_msg {
 	u8	client;
 	__le16	flags;
 	__le32	can_id;
-	u8	d[0];
+	u8	d[];
 };
 
 /* uCAN error types */
@@ -266,7 +266,7 @@ struct __packed pucan_tx_msg {
 	u8	client;
 	__le16	flags;
 	__le32	can_id;
-	u8	d[0];
+	u8	d[];
 };
 
 /* build the cmd opcode_channel field with respect to the correct endianness */
diff --git a/include/linux/compiler-clang.h b/include/linux/compiler-clang.h
index 333a6695a918..2cb42d8bdedc 100644
--- a/include/linux/compiler-clang.h
+++ b/include/linux/compiler-clang.h
@@ -16,7 +16,7 @@
 #define KASAN_ABI_VERSION 5
 
 #if __has_feature(address_sanitizer) || __has_feature(hwaddress_sanitizer)
-/* emulate gcc's __SANITIZE_ADDRESS__ flag */
+/* Emulate GCC's __SANITIZE_ADDRESS__ flag */
 #define __SANITIZE_ADDRESS__
 #define __no_sanitize_address \
 		__attribute__((no_sanitize("address", "hwaddress")))
@@ -24,6 +24,15 @@
 #define __no_sanitize_address
 #endif
 
+#if __has_feature(thread_sanitizer)
+/* emulate gcc's __SANITIZE_THREAD__ flag */
+#define __SANITIZE_THREAD__
+#define __no_sanitize_thread \
+		__attribute__((no_sanitize("thread")))
+#else
+#define __no_sanitize_thread
+#endif
+
 /*
  * Not all versions of clang implement the the type-generic versions
  * of the builtin overflow checkers. Fortunately, clang implements
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
index d7ee4c6bad48..cf294faec2f8 100644
--- a/include/linux/compiler-gcc.h
+++ b/include/linux/compiler-gcc.h
@@ -145,6 +145,12 @@
 #define __no_sanitize_address
 #endif
 
+#if defined(__SANITIZE_THREAD__) && __has_attribute(__no_sanitize_thread__)
+#define __no_sanitize_thread __attribute__((no_sanitize_thread))
+#else
+#define __no_sanitize_thread
+#endif
+
 #if GCC_VERSION >= 50100
 #define COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW 1
 #endif
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 034b0a644efc..cce2c92567b5 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -178,6 +178,7 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val,
 #endif
 
 #include <uapi/linux/types.h>
+#include <linux/kcsan-checks.h>
 
 #define __READ_ONCE_SIZE						\
 ({									\
@@ -193,12 +194,6 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val,
 	}								\
 })
 
-static __always_inline
-void __read_once_size(const volatile void *p, void *res, int size)
-{
-	__READ_ONCE_SIZE;
-}
-
 #ifdef CONFIG_KASAN
 /*
  * We can't declare function 'inline' because __no_sanitize_address confilcts
@@ -207,18 +202,47 @@ void __read_once_size(const volatile void *p, void *res, int size)
  * '__maybe_unused' allows us to avoid defined-but-not-used warnings.
  */
 # define __no_kasan_or_inline __no_sanitize_address notrace __maybe_unused
+# define __no_sanitize_or_inline __no_kasan_or_inline
 #else
 # define __no_kasan_or_inline __always_inline
 #endif
 
-static __no_kasan_or_inline
+#define __no_kcsan __no_sanitize_thread
+#ifdef __SANITIZE_THREAD__
+/*
+ * Rely on __SANITIZE_THREAD__ instead of CONFIG_KCSAN, to avoid not inlining in
+ * compilation units where instrumentation is disabled. The attribute 'noinline'
+ * is required for older compilers, where implicit inlining of very small
+ * functions renders __no_sanitize_thread ineffective.
+ */
+# define __no_kcsan_or_inline __no_kcsan noinline notrace __maybe_unused
+# define __no_sanitize_or_inline __no_kcsan_or_inline
+#else
+# define __no_kcsan_or_inline __always_inline
+#endif
+
+#ifndef __no_sanitize_or_inline
+#define __no_sanitize_or_inline __always_inline
+#endif
+
+static __no_kcsan_or_inline
+void __read_once_size(const volatile void *p, void *res, int size)
+{
+	kcsan_check_atomic_read(p, size);
+	__READ_ONCE_SIZE;
+}
+
+static __no_sanitize_or_inline
 void __read_once_size_nocheck(const volatile void *p, void *res, int size)
 {
 	__READ_ONCE_SIZE;
 }
 
-static __always_inline void __write_once_size(volatile void *p, void *res, int size)
+static __no_kcsan_or_inline
+void __write_once_size(volatile void *p, void *res, int size)
 {
+	kcsan_check_atomic_write(p, size);
+
 	switch (size) {
 	case 1: *(volatile __u8 *)p = *(__u8 *)res; break;
 	case 2: *(volatile __u16 *)p = *(__u16 *)res; break;
@@ -289,6 +313,26 @@ unsigned long read_word_at_a_time(const void *addr)
 	__u.__val;					\
 })
 
+/**
+ * data_race - mark an expression as containing intentional data races
+ *
+ * This data_race() macro is useful for situations in which data races
+ * should be forgiven.  One example is diagnostic code that accesses
+ * shared variables but is not a part of the core synchronization design.
+ *
+ * This macro *does not* affect normal code generation, but is a hint
+ * to tooling that data races here are to be ignored.
+ */
+#define data_race(expr)                                                        \
+	({                                                                     \
+		typeof(({ expr; })) __val;                                     \
+		kcsan_disable_current();                                       \
+		__val = ({ expr; });                                           \
+		kcsan_enable_current();                                        \
+		__val;                                                         \
+	})
+#else
+
 #endif /* __KERNEL__ */
 
 /*
diff --git a/include/linux/console.h b/include/linux/console.h
index 7a140f4e5d0c..75dd20650fbe 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -134,7 +134,7 @@ static inline int con_debug_leave(void)
  */
 
 #define CON_PRINTBUFFER	(1)
-#define CON_CONSDEV	(2) /* Last on the command line */
+#define CON_CONSDEV	(2) /* Preferred console, /dev/console */
 #define CON_ENABLED	(4)
 #define CON_BOOT	(8)
 #define CON_ANYTIME	(16) /* Safe to call when cpu is offline */
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index 193cc9dbf448..e3e9f0e3a878 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -100,10 +100,12 @@ union coresight_dev_subtype {
 };
 
 /**
- * struct coresight_platform_data - data harvested from the DT specification
- * @nr_inport:	number of input ports for this component.
- * @nr_outport:	number of output ports for this component.
- * @conns:	Array of nr_outport connections from this component
+ * struct coresight_platform_data - data harvested from the firmware
+ * specification.
+ *
+ * @nr_inport:	Number of elements for the input connections.
+ * @nr_outport:	Number of elements for the output connections.
+ * @conns:	Sparse array of nr_outport connections from this component.
  */
 struct coresight_platform_data {
 	int nr_inport;
@@ -140,12 +142,28 @@ struct coresight_desc {
  * @chid_fwnode: remote component's fwnode handle.
  * @child_dev:	a @coresight_device representation of the component
 		connected to @outport.
+ * @link: Representation of the connection as a sysfs link.
  */
 struct coresight_connection {
 	int outport;
 	int child_port;
 	struct fwnode_handle *child_fwnode;
 	struct coresight_device *child_dev;
+	struct coresight_sysfs_link *link;
+};
+
+/**
+ * struct coresight_sysfs_link - representation of a connection in sysfs.
+ * @orig:		Originating (master) coresight device for the link.
+ * @orig_name:		Name to use for the link orig->target.
+ * @target:		Target (slave) coresight device for the link.
+ * @target_name:	Name to use for the link target->orig.
+ */
+struct coresight_sysfs_link {
+	struct coresight_device *orig;
+	const char *orig_name;
+	struct coresight_device *target;
+	const char *target_name;
 };
 
 /**
@@ -165,6 +183,9 @@ struct coresight_connection {
  * @ea:		Device attribute for sink representation under PMU directory.
  * @ect_dev:	Associated cross trigger device. Not part of the trace data
  *		path or connections.
+ * @nr_links:   number of sysfs links created to other components from this
+ *		device. These will appear in the "connections" group.
+ * @has_conns_grp: Have added a "connections" group for sysfs links.
  */
 struct coresight_device {
 	struct coresight_platform_data *pdata;
@@ -180,6 +201,9 @@ struct coresight_device {
 	struct dev_ext_attribute *ea;
 	/* cross trigger handling */
 	struct coresight_device *ect_dev;
+	/* sysfs links between components */
+	int nr_links;
+	bool has_conns_grp;
 };
 
 /*
diff --git a/include/linux/cpu_rmap.h b/include/linux/cpu_rmap.h
index 02edeafcb2bf..be8aea04d023 100644
--- a/include/linux/cpu_rmap.h
+++ b/include/linux/cpu_rmap.h
@@ -28,7 +28,7 @@ struct cpu_rmap {
 	struct {
 		u16	index;
 		u16	dist;
-	}		near[0];
+	}		near[];
 };
 #define CPU_RMAP_DIST_INF 0xffff
 
diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h
index 4664fc1871de..bc156285d097 100644
--- a/include/linux/crash_dump.h
+++ b/include/linux/crash_dump.h
@@ -97,8 +97,6 @@ extern void unregister_oldmem_pfn_is_ram(void);
 static inline bool is_kdump_kernel(void) { return 0; }
 #endif /* CONFIG_CRASH_DUMP */
 
-extern unsigned long saved_max_pfn;
-
 /* Device Dump information to be filled by drivers */
 struct vmcoredd_data {
 	char dump_name[VMCOREDD_MAX_NAME_BYTES]; /* Unique name of the dump */
diff --git a/include/linux/device_cgroup.h b/include/linux/device_cgroup.h
index fa35b52e0002..9a72214496e5 100644
--- a/include/linux/device_cgroup.h
+++ b/include/linux/device_cgroup.h
@@ -1,6 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 #include <linux/fs.h>
-#include <linux/bpf-cgroup.h>
 
 #define DEVCG_ACC_MKNOD 1
 #define DEVCG_ACC_READ  2
@@ -11,16 +10,10 @@
 #define DEVCG_DEV_CHAR  2
 #define DEVCG_DEV_ALL   4  /* this represents all devices */
 
-#ifdef CONFIG_CGROUP_DEVICE
-int devcgroup_check_permission(short type, u32 major, u32 minor,
-			       short access);
-#else
-static inline int devcgroup_check_permission(short type, u32 major, u32 minor,
-					     short access)
-{ return 0; }
-#endif
 
 #if defined(CONFIG_CGROUP_DEVICE) || defined(CONFIG_CGROUP_BPF)
+int devcgroup_check_permission(short type, u32 major, u32 minor,
+			       short access);
 static inline int devcgroup_inode_permission(struct inode *inode, int mask)
 {
 	short type, access = 0;
@@ -61,6 +54,9 @@ static inline int devcgroup_inode_mknod(int mode, dev_t dev)
 }
 
 #else
+static inline int devcgroup_check_permission(short type, u32 major, u32 minor,
+			       short access)
+{ return 0; }
 static inline int devcgroup_inode_permission(struct inode *inode, int mask)
 { return 0; }
 static inline int devcgroup_inode_mknod(int mode, dev_t dev)
diff --git a/include/linux/digsig.h b/include/linux/digsig.h
index 594fc66a395a..2ace69e41088 100644
--- a/include/linux/digsig.h
+++ b/include/linux/digsig.h
@@ -29,7 +29,7 @@ struct pubkey_hdr {
 	uint32_t	timestamp;	/* key made, always 0 for now */
 	uint8_t		algo;
 	uint8_t		nmpi;
-	char		mpi[0];
+	char		mpi[];
 } __packed;
 
 struct signature_hdr {
@@ -39,7 +39,7 @@ struct signature_hdr {
 	uint8_t		hash;
 	uint8_t		keyid[8];
 	uint8_t		nmpi;
-	char		mpi[0];
+	char		mpi[];
 } __packed;
 
 #if defined(CONFIG_SIGNATURE) || defined(CONFIG_SIGNATURE_MODULE)
diff --git a/include/linux/dirent.h b/include/linux/dirent.h
index fc61f3cff72f..99002220cd45 100644
--- a/include/linux/dirent.h
+++ b/include/linux/dirent.h
@@ -7,7 +7,7 @@ struct linux_dirent64 {
 	s64		d_off;
 	unsigned short	d_reclen;
 	unsigned char	d_type;
-	char		d_name[0];
+	char		d_name[];
 };
 
 #endif
diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
index 1ade486fc2bb..82e0a4a64601 100644
--- a/include/linux/dma-buf.h
+++ b/include/linux/dma-buf.h
@@ -334,6 +334,14 @@ struct dma_buf {
  * Attachment operations implemented by the importer.
  */
 struct dma_buf_attach_ops {
+	/**
+	 * @allow_peer2peer:
+	 *
+	 * If this is set to true the importer must be able to handle peer
+	 * resources without struct pages.
+	 */
+	bool allow_peer2peer;
+
 	/**
 	 * @move_notify
 	 *
@@ -362,6 +370,7 @@ struct dma_buf_attach_ops {
  * @node: list of dma_buf_attachment, protected by dma_resv lock of the dmabuf.
  * @sgt: cached mapping.
  * @dir: direction of cached mapping.
+ * @peer2peer: true if the importer can handle peer resources without pages.
  * @priv: exporter specific attachment data.
  * @importer_ops: importer operations for this attachment, if provided
  * dma_buf_map/unmap_attachment() must be called with the dma_resv lock held.
@@ -382,6 +391,7 @@ struct dma_buf_attachment {
 	struct list_head node;
 	struct sg_table *sgt;
 	enum dma_data_direction dir;
+	bool peer2peer;
 	const struct dma_buf_attach_ops *importer_ops;
 	void *importer_priv;
 	void *priv;
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 21065c04c4ac..31e58ec9f741 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -83,9 +83,9 @@ enum dma_transfer_direction {
 /**
  * Interleaved Transfer Request
  * ----------------------------
- * A chunk is collection of contiguous bytes to be transfered.
+ * A chunk is collection of contiguous bytes to be transferred.
  * The gap(in bytes) between two chunks is called inter-chunk-gap(ICG).
- * ICGs may or maynot change between chunks.
+ * ICGs may or may not change between chunks.
  * A FRAME is the smallest series of contiguous {chunk,icg} pairs,
  *  that when repeated an integral number of times, specifies the transfer.
  * A transfer template is specification of a Frame, the number of times
@@ -1069,7 +1069,7 @@ static inline int dmaengine_terminate_all(struct dma_chan *chan)
  * dmaengine_synchronize() needs to be called before it is safe to free
  * any memory that is accessed by previously submitted descriptors or before
  * freeing any resources accessed from within the completion callback of any
- * perviously submitted descriptors.
+ * previously submitted descriptors.
  *
  * This function can be called from atomic context as well as from within a
  * complete callback of a descriptor submitted on the same channel.
@@ -1091,7 +1091,7 @@ static inline int dmaengine_terminate_async(struct dma_chan *chan)
  *
  * Synchronizes to the DMA channel termination to the current context. When this
  * function returns it is guaranteed that all transfers for previously issued
- * descriptors have stopped and and it is safe to free the memory assoicated
+ * descriptors have stopped and it is safe to free the memory associated
  * with them. Furthermore it is guaranteed that all complete callback functions
  * for a previously submitted descriptor have finished running and it is safe to
  * free resources accessed from within the complete callbacks.
diff --git a/include/linux/edac.h b/include/linux/edac.h
index 0f20b986b0ab..6eb7d55d7c3d 100644
--- a/include/linux/edac.h
+++ b/include/linux/edac.h
@@ -31,14 +31,6 @@ struct device;
 extern int edac_op_state;
 
 struct bus_type *edac_get_sysfs_subsys(void);
-int edac_get_report_status(void);
-void edac_set_report_status(int new);
-
-enum {
-	EDAC_REPORTING_ENABLED,
-	EDAC_REPORTING_DISABLED,
-	EDAC_REPORTING_FORCE
-};
 
 static inline void opstate_init(void)
 {
diff --git a/include/linux/enclosure.h b/include/linux/enclosure.h
index 564e96f625ff..1c630e2c2756 100644
--- a/include/linux/enclosure.h
+++ b/include/linux/enclosure.h
@@ -101,7 +101,7 @@ struct enclosure_device {
 	struct device edev;
 	struct enclosure_component_callbacks *cb;
 	int components;
-	struct enclosure_component component[0];
+	struct enclosure_component component[];
 };
 
 static inline struct enclosure_device *
diff --git a/include/linux/energy_model.h b/include/linux/energy_model.h
index d249b88a4d5a..ade6486a3382 100644
--- a/include/linux/energy_model.h
+++ b/include/linux/energy_model.h
@@ -36,7 +36,7 @@ struct em_cap_state {
 struct em_perf_domain {
 	struct em_cap_state *table;
 	int nr_cap_states;
-	unsigned long cpus[0];
+	unsigned long cpus[];
 };
 
 #ifdef CONFIG_ENERGY_MODEL
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index c1d379bf6ee1..a23b26eab479 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -35,7 +35,7 @@ struct compat_ethtool_rxnfc {
 	compat_u64			data;
 	struct compat_ethtool_rx_flow_spec fs;
 	u32				rule_cnt;
-	u32				rule_locs[0];
+	u32				rule_locs[];
 };
 
 #endif /* CONFIG_COMPAT */
@@ -462,7 +462,7 @@ int ethtool_check_ops(const struct ethtool_ops *ops);
 
 struct ethtool_rx_flow_rule {
 	struct flow_rule	*rule;
-	unsigned long		priv[0];
+	unsigned long		priv[];
 };
 
 struct ethtool_rx_flow_spec_input {
diff --git a/include/linux/genalloc.h b/include/linux/genalloc.h
index 5b14a0f38124..0bd581003cd5 100644
--- a/include/linux/genalloc.h
+++ b/include/linux/genalloc.h
@@ -76,7 +76,7 @@ struct gen_pool_chunk {
 	void *owner;			/* private data to retrieve at alloc time */
 	unsigned long start_addr;	/* start address of memory chunk */
 	unsigned long end_addr;		/* end address of memory chunk (inclusive) */
-	unsigned long bits[0];		/* bitmap for allocating memory chunk */
+	unsigned long bits[];		/* bitmap for allocating memory chunk */
 };
 
 /*
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index 4aba4c86c626..4612e0734852 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -110,6 +110,9 @@ struct vm_area_struct;
  * the caller guarantees the allocation will allow more memory to be freed
  * very shortly e.g. process exiting or swapping. Users either should
  * be the MM or co-ordinating closely with the VM (e.g. swap over NFS).
+ * Users of this flag have to be extremely careful to not deplete the reserve
+ * completely and implement a throttling mechanism which controls the
+ * consumption of the reserve based on the amount of freed memory.
  *
  * %__GFP_NOMEMALLOC is used to explicitly forbid access to emergency reserves.
  * This takes precedence over the %__GFP_MEMALLOC flag if both are set.
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 692c89ccf5df..cd64ab7bb3b7 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -425,7 +425,7 @@ enum vmbus_channel_message_type {
 	CHANNELMSG_19				= 19,
 	CHANNELMSG_20				= 20,
 	CHANNELMSG_TL_CONNECT_REQUEST		= 21,
-	CHANNELMSG_22				= 22,
+	CHANNELMSG_MODIFYCHANNEL		= 22,
 	CHANNELMSG_TL_CONNECT_RESULT		= 23,
 	CHANNELMSG_COUNT
 };
@@ -620,6 +620,13 @@ struct vmbus_channel_tl_connect_request {
 	guid_t host_service_id;
 } __packed;
 
+/* Modify Channel parameters, cf. vmbus_send_modifychannel() */
+struct vmbus_channel_modifychannel {
+	struct vmbus_channel_message_header header;
+	u32 child_relid;
+	u32 target_vp;
+} __packed;
+
 struct vmbus_channel_version_response {
 	struct vmbus_channel_message_header header;
 	u8 version_supported;
@@ -689,11 +696,6 @@ union hv_connection_id {
 	} u;
 };
 
-enum hv_numa_policy {
-	HV_BALANCED = 0,
-	HV_LOCALIZED,
-};
-
 enum vmbus_device_type {
 	HV_IDE = 0,
 	HV_SCSI,
@@ -771,6 +773,15 @@ struct vmbus_channel {
 	void (*onchannel_callback)(void *context);
 	void *channel_callback_context;
 
+	void (*change_target_cpu_callback)(struct vmbus_channel *channel,
+			u32 old, u32 new);
+
+	/*
+	 * Synchronize channel scheduling and channel removal; see the inline
+	 * comments in vmbus_chan_sched() and vmbus_reset_channel_cb().
+	 */
+	spinlock_t sched_lock;
+
 	/*
 	 * A channel can be marked for one of three modes of reading:
 	 *   BATCHED - callback called from taslket and should read
@@ -802,10 +813,6 @@ struct vmbus_channel {
 	u32 target_vp;
 	/* The corresponding CPUID in the guest */
 	u32 target_cpu;
-	/*
-	 * State to manage the CPU affiliation of channels.
-	 */
-	struct cpumask alloced_cpus_in_node;
 	int numa_node;
 	/*
 	 * Support for sub-channels. For high performance devices,
@@ -854,11 +861,6 @@ struct vmbus_channel {
 	 * Support per-channel state for use by vmbus drivers.
 	 */
 	void *per_channel_state;
-	/*
-	 * To support per-cpu lookup mapping of relid to channel,
-	 * link up channels based on their CPU affinity.
-	 */
-	struct list_head percpu_list;
 
 	/*
 	 * Defer freeing channel until after all cpu's have
@@ -897,18 +899,6 @@ struct vmbus_channel {
 	 */
 	bool low_latency;
 
-	/*
-	 * NUMA distribution policy:
-	 * We support two policies:
-	 * 1) Balanced: Here all performance critical channels are
-	 *    distributed evenly amongst all the NUMA nodes.
-	 *    This policy will be the default policy.
-	 * 2) Localized: All channels of a given instance of a
-	 *    performance critical service will be assigned CPUs
-	 *    within a selected NUMA node.
-	 */
-	enum hv_numa_policy affinity_policy;
-
 	bool probe_done;
 
 	/*
@@ -964,12 +954,6 @@ static inline bool is_sub_channel(const struct vmbus_channel *c)
 	return c->offermsg.offer.sub_channel_index != 0;
 }
 
-static inline void set_channel_affinity_state(struct vmbus_channel *c,
-					      enum hv_numa_policy policy)
-{
-	c->affinity_policy = policy;
-}
-
 static inline void set_channel_read_mode(struct vmbus_channel *c,
 					enum hv_callback_mode mode)
 {
@@ -1017,7 +1001,7 @@ static inline void clear_low_latency_mode(struct vmbus_channel *c)
 	c->low_latency = false;
 }
 
-void vmbus_onmessage(void *context);
+void vmbus_onmessage(struct vmbus_channel_message_header *hdr);
 
 int vmbus_request_offers(void);
 
@@ -1531,6 +1515,7 @@ extern __u32 vmbus_proto_version;
 
 int vmbus_send_tl_connect_request(const guid_t *shv_guest_servie_id,
 				  const guid_t *shv_host_servie_id);
+int vmbus_send_modifychannel(u32 child_relid, u32 target_vp);
 void vmbus_set_event(struct vmbus_channel *channel);
 
 /* Get the start of the ring buffer. */
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index 456fc17ecb1c..45d36ba4826b 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -461,12 +461,6 @@ i2c_new_scanned_device(struct i2c_adapter *adap,
 		       unsigned short const *addr_list,
 		       int (*probe)(struct i2c_adapter *adap, unsigned short addr));
 
-struct i2c_client *
-i2c_new_probed_device(struct i2c_adapter *adap,
-		       struct i2c_board_info *info,
-		       unsigned short const *addr_list,
-		       int (*probe)(struct i2c_adapter *adap, unsigned short addr));
-
 /* Common custom probe functions */
 int i2c_probe_func_quick_read(struct i2c_adapter *adap, unsigned short addr);
 
diff --git a/include/linux/igmp.h b/include/linux/igmp.h
index 463047d0190b..faa6586a5783 100644
--- a/include/linux/igmp.h
+++ b/include/linux/igmp.h
@@ -38,7 +38,7 @@ struct ip_sf_socklist {
 	unsigned int		sl_max;
 	unsigned int		sl_count;
 	struct rcu_head		rcu;
-	__be32			sl_addr[0];
+	__be32			sl_addr[];
 };
 
 #define IP_SFLSIZE(count)	(sizeof(struct ip_sf_socklist) + \
diff --git a/include/linux/ihex.h b/include/linux/ihex.h
index 98cb5ce0b0a0..b824877e6d1b 100644
--- a/include/linux/ihex.h
+++ b/include/linux/ihex.h
@@ -18,7 +18,7 @@
 struct ihex_binrec {
 	__be32 addr;
 	__be16 len;
-	uint8_t data[0];
+	uint8_t data[];
 } __attribute__((packed));
 
 static inline uint16_t ihex_binrec_size(const struct ihex_binrec *p)
diff --git a/include/linux/instrumented.h b/include/linux/instrumented.h
new file mode 100644
index 000000000000..43e6ea591975
--- /dev/null
+++ b/include/linux/instrumented.h
@@ -0,0 +1,109 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/*
+ * This header provides generic wrappers for memory access instrumentation that
+ * the compiler cannot emit for: KASAN, KCSAN.
+ */
+#ifndef _LINUX_INSTRUMENTED_H
+#define _LINUX_INSTRUMENTED_H
+
+#include <linux/compiler.h>
+#include <linux/kasan-checks.h>
+#include <linux/kcsan-checks.h>
+#include <linux/types.h>
+
+/**
+ * instrument_read - instrument regular read access
+ *
+ * Instrument a regular read access. The instrumentation should be inserted
+ * before the actual read happens.
+ *
+ * @ptr address of access
+ * @size size of access
+ */
+static __always_inline void instrument_read(const volatile void *v, size_t size)
+{
+	kasan_check_read(v, size);
+	kcsan_check_read(v, size);
+}
+
+/**
+ * instrument_write - instrument regular write access
+ *
+ * Instrument a regular write access. The instrumentation should be inserted
+ * before the actual write happens.
+ *
+ * @ptr address of access
+ * @size size of access
+ */
+static __always_inline void instrument_write(const volatile void *v, size_t size)
+{
+	kasan_check_write(v, size);
+	kcsan_check_write(v, size);
+}
+
+/**
+ * instrument_atomic_read - instrument atomic read access
+ *
+ * Instrument an atomic read access. The instrumentation should be inserted
+ * before the actual read happens.
+ *
+ * @ptr address of access
+ * @size size of access
+ */
+static __always_inline void instrument_atomic_read(const volatile void *v, size_t size)
+{
+	kasan_check_read(v, size);
+	kcsan_check_atomic_read(v, size);
+}
+
+/**
+ * instrument_atomic_write - instrument atomic write access
+ *
+ * Instrument an atomic write access. The instrumentation should be inserted
+ * before the actual write happens.
+ *
+ * @ptr address of access
+ * @size size of access
+ */
+static __always_inline void instrument_atomic_write(const volatile void *v, size_t size)
+{
+	kasan_check_write(v, size);
+	kcsan_check_atomic_write(v, size);
+}
+
+/**
+ * instrument_copy_to_user - instrument reads of copy_to_user
+ *
+ * Instrument reads from kernel memory, that are due to copy_to_user (and
+ * variants). The instrumentation must be inserted before the accesses.
+ *
+ * @to destination address
+ * @from source address
+ * @n number of bytes to copy
+ */
+static __always_inline void
+instrument_copy_to_user(void __user *to, const void *from, unsigned long n)
+{
+	kasan_check_read(from, n);
+	kcsan_check_read(from, n);
+}
+
+/**
+ * instrument_copy_from_user - instrument writes of copy_from_user
+ *
+ * Instrument writes to kernel memory, that are due to copy_from_user (and
+ * variants). The instrumentation should be inserted before the accesses.
+ *
+ * @to destination address
+ * @from source address
+ * @n number of bytes to copy
+ */
+static __always_inline void
+instrument_copy_from_user(const void *to, const void __user *from, unsigned long n)
+{
+	kasan_check_write(to, n);
+	kcsan_check_write(to, n);
+}
+
+#endif /* _LINUX_INSTRUMENTED_H */
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 9315fbb87db3..8d5bc2c237d7 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -573,8 +573,6 @@ enum {
 #define IRQ_DEFAULT_INIT_FLAGS	ARCH_IRQ_INIT_FLAGS
 
 struct irqaction;
-extern int setup_irq(unsigned int irq, struct irqaction *new);
-extern void remove_irq(unsigned int irq, struct irqaction *act);
 extern int setup_percpu_irq(unsigned int irq, struct irqaction *new);
 extern void remove_percpu_irq(unsigned int irq, struct irqaction *act);
 
@@ -1043,7 +1041,7 @@ struct irq_chip_generic {
 	unsigned long		unused;
 	struct irq_domain	*domain;
 	struct list_head	list;
-	struct irq_chip_type	chip_types[0];
+	struct irq_chip_type	chip_types[];
 };
 
 /**
@@ -1079,7 +1077,7 @@ struct irq_domain_chip_generic {
 	unsigned int		irq_flags_to_clear;
 	unsigned int		irq_flags_to_set;
 	enum irq_gc_flags	gc_flags;
-	struct irq_chip_generic	*gc[0];
+	struct irq_chip_generic	*gc[];
 };
 
 /* Generic chip callback functions */
diff --git a/include/linux/kcsan-checks.h b/include/linux/kcsan-checks.h
new file mode 100644
index 000000000000..ef95ddc49182
--- /dev/null
+++ b/include/linux/kcsan-checks.h
@@ -0,0 +1,419 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _LINUX_KCSAN_CHECKS_H
+#define _LINUX_KCSAN_CHECKS_H
+
+/* Note: Only include what is already included by compiler.h. */
+#include <linux/compiler_attributes.h>
+#include <linux/types.h>
+
+/*
+ * ACCESS TYPE MODIFIERS
+ *
+ *   <none>: normal read access;
+ *   WRITE : write access;
+ *   ATOMIC: access is atomic;
+ *   ASSERT: access is not a regular access, but an assertion;
+ *   SCOPED: access is a scoped access;
+ */
+#define KCSAN_ACCESS_WRITE  0x1
+#define KCSAN_ACCESS_ATOMIC 0x2
+#define KCSAN_ACCESS_ASSERT 0x4
+#define KCSAN_ACCESS_SCOPED 0x8
+
+/*
+ * __kcsan_*: Always calls into the runtime when KCSAN is enabled. This may be used
+ * even in compilation units that selectively disable KCSAN, but must use KCSAN
+ * to validate access to an address. Never use these in header files!
+ */
+#ifdef CONFIG_KCSAN
+/**
+ * __kcsan_check_access - check generic access for races
+ *
+ * @ptr: address of access
+ * @size: size of access
+ * @type: access type modifier
+ */
+void __kcsan_check_access(const volatile void *ptr, size_t size, int type);
+
+/**
+ * kcsan_disable_current - disable KCSAN for the current context
+ *
+ * Supports nesting.
+ */
+void kcsan_disable_current(void);
+
+/**
+ * kcsan_enable_current - re-enable KCSAN for the current context
+ *
+ * Supports nesting.
+ */
+void kcsan_enable_current(void);
+
+/**
+ * kcsan_nestable_atomic_begin - begin nestable atomic region
+ *
+ * Accesses within the atomic region may appear to race with other accesses but
+ * should be considered atomic.
+ */
+void kcsan_nestable_atomic_begin(void);
+
+/**
+ * kcsan_nestable_atomic_end - end nestable atomic region
+ */
+void kcsan_nestable_atomic_end(void);
+
+/**
+ * kcsan_flat_atomic_begin - begin flat atomic region
+ *
+ * Accesses within the atomic region may appear to race with other accesses but
+ * should be considered atomic.
+ */
+void kcsan_flat_atomic_begin(void);
+
+/**
+ * kcsan_flat_atomic_end - end flat atomic region
+ */
+void kcsan_flat_atomic_end(void);
+
+/**
+ * kcsan_atomic_next - consider following accesses as atomic
+ *
+ * Force treating the next n memory accesses for the current context as atomic
+ * operations.
+ *
+ * @n: number of following memory accesses to treat as atomic.
+ */
+void kcsan_atomic_next(int n);
+
+/**
+ * kcsan_set_access_mask - set access mask
+ *
+ * Set the access mask for all accesses for the current context if non-zero.
+ * Only value changes to bits set in the mask will be reported.
+ *
+ * @mask: bitmask
+ */
+void kcsan_set_access_mask(unsigned long mask);
+
+/* Scoped access information. */
+struct kcsan_scoped_access {
+	struct list_head list;
+	const volatile void *ptr;
+	size_t size;
+	int type;
+};
+/*
+ * Automatically call kcsan_end_scoped_access() when kcsan_scoped_access goes
+ * out of scope; relies on attribute "cleanup", which is supported by all
+ * compilers that support KCSAN.
+ */
+#define __kcsan_cleanup_scoped                                                 \
+	__maybe_unused __attribute__((__cleanup__(kcsan_end_scoped_access)))
+
+/**
+ * kcsan_begin_scoped_access - begin scoped access
+ *
+ * Begin scoped access and initialize @sa, which will cause KCSAN to
+ * continuously check the memory range in the current thread until
+ * kcsan_end_scoped_access() is called for @sa.
+ *
+ * Scoped accesses are implemented by appending @sa to an internal list for the
+ * current execution context, and then checked on every call into the KCSAN
+ * runtime.
+ *
+ * @ptr: address of access
+ * @size: size of access
+ * @type: access type modifier
+ * @sa: struct kcsan_scoped_access to use for the scope of the access
+ */
+struct kcsan_scoped_access *
+kcsan_begin_scoped_access(const volatile void *ptr, size_t size, int type,
+			  struct kcsan_scoped_access *sa);
+
+/**
+ * kcsan_end_scoped_access - end scoped access
+ *
+ * End a scoped access, which will stop KCSAN checking the memory range.
+ * Requires that kcsan_begin_scoped_access() was previously called once for @sa.
+ *
+ * @sa: a previously initialized struct kcsan_scoped_access
+ */
+void kcsan_end_scoped_access(struct kcsan_scoped_access *sa);
+
+
+#else /* CONFIG_KCSAN */
+
+static inline void __kcsan_check_access(const volatile void *ptr, size_t size,
+					int type) { }
+
+static inline void kcsan_disable_current(void)		{ }
+static inline void kcsan_enable_current(void)		{ }
+static inline void kcsan_nestable_atomic_begin(void)	{ }
+static inline void kcsan_nestable_atomic_end(void)	{ }
+static inline void kcsan_flat_atomic_begin(void)	{ }
+static inline void kcsan_flat_atomic_end(void)		{ }
+static inline void kcsan_atomic_next(int n)		{ }
+static inline void kcsan_set_access_mask(unsigned long mask) { }
+
+struct kcsan_scoped_access { };
+#define __kcsan_cleanup_scoped __maybe_unused
+static inline struct kcsan_scoped_access *
+kcsan_begin_scoped_access(const volatile void *ptr, size_t size, int type,
+			  struct kcsan_scoped_access *sa) { return sa; }
+static inline void kcsan_end_scoped_access(struct kcsan_scoped_access *sa) { }
+
+#endif /* CONFIG_KCSAN */
+
+/*
+ * kcsan_*: Only calls into the runtime when the particular compilation unit has
+ * KCSAN instrumentation enabled. May be used in header files.
+ */
+#ifdef __SANITIZE_THREAD__
+#define kcsan_check_access __kcsan_check_access
+#else
+static inline void kcsan_check_access(const volatile void *ptr, size_t size,
+				      int type) { }
+#endif
+
+/**
+ * __kcsan_check_read - check regular read access for races
+ *
+ * @ptr: address of access
+ * @size: size of access
+ */
+#define __kcsan_check_read(ptr, size) __kcsan_check_access(ptr, size, 0)
+
+/**
+ * __kcsan_check_write - check regular write access for races
+ *
+ * @ptr: address of access
+ * @size: size of access
+ */
+#define __kcsan_check_write(ptr, size)                                         \
+	__kcsan_check_access(ptr, size, KCSAN_ACCESS_WRITE)
+
+/**
+ * kcsan_check_read - check regular read access for races
+ *
+ * @ptr: address of access
+ * @size: size of access
+ */
+#define kcsan_check_read(ptr, size) kcsan_check_access(ptr, size, 0)
+
+/**
+ * kcsan_check_write - check regular write access for races
+ *
+ * @ptr: address of access
+ * @size: size of access
+ */
+#define kcsan_check_write(ptr, size)                                           \
+	kcsan_check_access(ptr, size, KCSAN_ACCESS_WRITE)
+
+/*
+ * Check for atomic accesses: if atomic accesses are not ignored, this simply
+ * aliases to kcsan_check_access(), otherwise becomes a no-op.
+ */
+#ifdef CONFIG_KCSAN_IGNORE_ATOMICS
+#define kcsan_check_atomic_read(...)	do { } while (0)
+#define kcsan_check_atomic_write(...)	do { } while (0)
+#else
+#define kcsan_check_atomic_read(ptr, size)                                     \
+	kcsan_check_access(ptr, size, KCSAN_ACCESS_ATOMIC)
+#define kcsan_check_atomic_write(ptr, size)                                    \
+	kcsan_check_access(ptr, size, KCSAN_ACCESS_ATOMIC | KCSAN_ACCESS_WRITE)
+#endif
+
+/**
+ * ASSERT_EXCLUSIVE_WRITER - assert no concurrent writes to @var
+ *
+ * Assert that there are no concurrent writes to @var; other readers are
+ * allowed. This assertion can be used to specify properties of concurrent code,
+ * where violation cannot be detected as a normal data race.
+ *
+ * For example, if we only have a single writer, but multiple concurrent
+ * readers, to avoid data races, all these accesses must be marked; even
+ * concurrent marked writes racing with the single writer are bugs.
+ * Unfortunately, due to being marked, they are no longer data races. For cases
+ * like these, we can use the macro as follows:
+ *
+ * .. code-block:: c
+ *
+ *	void writer(void) {
+ *		spin_lock(&update_foo_lock);
+ *		ASSERT_EXCLUSIVE_WRITER(shared_foo);
+ *		WRITE_ONCE(shared_foo, ...);
+ *		spin_unlock(&update_foo_lock);
+ *	}
+ *	void reader(void) {
+ *		// update_foo_lock does not need to be held!
+ *		... = READ_ONCE(shared_foo);
+ *	}
+ *
+ * Note: ASSERT_EXCLUSIVE_WRITER_SCOPED(), if applicable, performs more thorough
+ * checking if a clear scope where no concurrent writes are expected exists.
+ *
+ * @var: variable to assert on
+ */
+#define ASSERT_EXCLUSIVE_WRITER(var)                                           \
+	__kcsan_check_access(&(var), sizeof(var), KCSAN_ACCESS_ASSERT)
+
+/*
+ * Helper macros for implementation of for ASSERT_EXCLUSIVE_*_SCOPED(). @id is
+ * expected to be unique for the scope in which instances of kcsan_scoped_access
+ * are declared.
+ */
+#define __kcsan_scoped_name(c, suffix) __kcsan_scoped_##c##suffix
+#define __ASSERT_EXCLUSIVE_SCOPED(var, type, id)                               \
+	struct kcsan_scoped_access __kcsan_scoped_name(id, _)                  \
+		__kcsan_cleanup_scoped;                                        \
+	struct kcsan_scoped_access *__kcsan_scoped_name(id, _dummy_p)          \
+		__maybe_unused = kcsan_begin_scoped_access(                    \
+			&(var), sizeof(var), KCSAN_ACCESS_SCOPED | (type),     \
+			&__kcsan_scoped_name(id, _))
+
+/**
+ * ASSERT_EXCLUSIVE_WRITER_SCOPED - assert no concurrent writes to @var in scope
+ *
+ * Scoped variant of ASSERT_EXCLUSIVE_WRITER().
+ *
+ * Assert that there are no concurrent writes to @var for the duration of the
+ * scope in which it is introduced. This provides a better way to fully cover
+ * the enclosing scope, compared to multiple ASSERT_EXCLUSIVE_WRITER(), and
+ * increases the likelihood for KCSAN to detect racing accesses.
+ *
+ * For example, it allows finding race-condition bugs that only occur due to
+ * state changes within the scope itself:
+ *
+ * .. code-block:: c
+ *
+ *	void writer(void) {
+ *		spin_lock(&update_foo_lock);
+ *		{
+ *			ASSERT_EXCLUSIVE_WRITER_SCOPED(shared_foo);
+ *			WRITE_ONCE(shared_foo, 42);
+ *			...
+ *			// shared_foo should still be 42 here!
+ *		}
+ *		spin_unlock(&update_foo_lock);
+ *	}
+ *	void buggy(void) {
+ *		if (READ_ONCE(shared_foo) == 42)
+ *			WRITE_ONCE(shared_foo, 1); // bug!
+ *	}
+ *
+ * @var: variable to assert on
+ */
+#define ASSERT_EXCLUSIVE_WRITER_SCOPED(var)                                    \
+	__ASSERT_EXCLUSIVE_SCOPED(var, KCSAN_ACCESS_ASSERT, __COUNTER__)
+
+/**
+ * ASSERT_EXCLUSIVE_ACCESS - assert no concurrent accesses to @var
+ *
+ * Assert that there are no concurrent accesses to @var (no readers nor
+ * writers). This assertion can be used to specify properties of concurrent
+ * code, where violation cannot be detected as a normal data race.
+ *
+ * For example, where exclusive access is expected after determining no other
+ * users of an object are left, but the object is not actually freed. We can
+ * check that this property actually holds as follows:
+ *
+ * .. code-block:: c
+ *
+ *	if (refcount_dec_and_test(&obj->refcnt)) {
+ *		ASSERT_EXCLUSIVE_ACCESS(*obj);
+ *		do_some_cleanup(obj);
+ *		release_for_reuse(obj);
+ *	}
+ *
+ * Note: ASSERT_EXCLUSIVE_ACCESS_SCOPED(), if applicable, performs more thorough
+ * checking if a clear scope where no concurrent accesses are expected exists.
+ *
+ * Note: For cases where the object is freed, `KASAN <kasan.html>`_ is a better
+ * fit to detect use-after-free bugs.
+ *
+ * @var: variable to assert on
+ */
+#define ASSERT_EXCLUSIVE_ACCESS(var)                                           \
+	__kcsan_check_access(&(var), sizeof(var), KCSAN_ACCESS_WRITE | KCSAN_ACCESS_ASSERT)
+
+/**
+ * ASSERT_EXCLUSIVE_ACCESS_SCOPED - assert no concurrent accesses to @var in scope
+ *
+ * Scoped variant of ASSERT_EXCLUSIVE_ACCESS().
+ *
+ * Assert that there are no concurrent accesses to @var (no readers nor writers)
+ * for the entire duration of the scope in which it is introduced. This provides
+ * a better way to fully cover the enclosing scope, compared to multiple
+ * ASSERT_EXCLUSIVE_ACCESS(), and increases the likelihood for KCSAN to detect
+ * racing accesses.
+ *
+ * @var: variable to assert on
+ */
+#define ASSERT_EXCLUSIVE_ACCESS_SCOPED(var)                                    \
+	__ASSERT_EXCLUSIVE_SCOPED(var, KCSAN_ACCESS_WRITE | KCSAN_ACCESS_ASSERT, __COUNTER__)
+
+/**
+ * ASSERT_EXCLUSIVE_BITS - assert no concurrent writes to subset of bits in @var
+ *
+ * Bit-granular variant of ASSERT_EXCLUSIVE_WRITER().
+ *
+ * Assert that there are no concurrent writes to a subset of bits in @var;
+ * concurrent readers are permitted. This assertion captures more detailed
+ * bit-level properties, compared to the other (word granularity) assertions.
+ * Only the bits set in @mask are checked for concurrent modifications, while
+ * ignoring the remaining bits, i.e. concurrent writes (or reads) to ~mask bits
+ * are ignored.
+ *
+ * Use this for variables, where some bits must not be modified concurrently,
+ * yet other bits are expected to be modified concurrently.
+ *
+ * For example, variables where, after initialization, some bits are read-only,
+ * but other bits may still be modified concurrently. A reader may wish to
+ * assert that this is true as follows:
+ *
+ * .. code-block:: c
+ *
+ *	ASSERT_EXCLUSIVE_BITS(flags, READ_ONLY_MASK);
+ *	foo = (READ_ONCE(flags) & READ_ONLY_MASK) >> READ_ONLY_SHIFT;
+ *
+ * Note: The access that immediately follows ASSERT_EXCLUSIVE_BITS() is assumed
+ * to access the masked bits only, and KCSAN optimistically assumes it is
+ * therefore safe, even in the presence of data races, and marking it with
+ * READ_ONCE() is optional from KCSAN's point-of-view. We caution, however, that
+ * it may still be advisable to do so, since we cannot reason about all compiler
+ * optimizations when it comes to bit manipulations (on the reader and writer
+ * side). If you are sure nothing can go wrong, we can write the above simply
+ * as:
+ *
+ * .. code-block:: c
+ *
+ *	ASSERT_EXCLUSIVE_BITS(flags, READ_ONLY_MASK);
+ *	foo = (flags & READ_ONLY_MASK) >> READ_ONLY_SHIFT;
+ *
+ * Another example, where this may be used, is when certain bits of @var may
+ * only be modified when holding the appropriate lock, but other bits may still
+ * be modified concurrently. Writers, where other bits may change concurrently,
+ * could use the assertion as follows:
+ *
+ * .. code-block:: c
+ *
+ *	spin_lock(&foo_lock);
+ *	ASSERT_EXCLUSIVE_BITS(flags, FOO_MASK);
+ *	old_flags = flags;
+ *	new_flags = (old_flags & ~FOO_MASK) | (new_foo << FOO_SHIFT);
+ *	if (cmpxchg(&flags, old_flags, new_flags) != old_flags) { ... }
+ *	spin_unlock(&foo_lock);
+ *
+ * @var: variable to assert on
+ * @mask: only check for modifications to bits set in @mask
+ */
+#define ASSERT_EXCLUSIVE_BITS(var, mask)                                       \
+	do {                                                                   \
+		kcsan_set_access_mask(mask);                                   \
+		__kcsan_check_access(&(var), sizeof(var), KCSAN_ACCESS_ASSERT);\
+		kcsan_set_access_mask(0);                                      \
+		kcsan_atomic_next(1);                                          \
+	} while (0)
+
+#endif /* _LINUX_KCSAN_CHECKS_H */
diff --git a/include/linux/kcsan.h b/include/linux/kcsan.h
new file mode 100644
index 000000000000..53340d8789f9
--- /dev/null
+++ b/include/linux/kcsan.h
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _LINUX_KCSAN_H
+#define _LINUX_KCSAN_H
+
+#include <linux/kcsan-checks.h>
+#include <linux/types.h>
+
+#ifdef CONFIG_KCSAN
+
+/*
+ * Context for each thread of execution: for tasks, this is stored in
+ * task_struct, and interrupts access internal per-CPU storage.
+ */
+struct kcsan_ctx {
+	int disable_count; /* disable counter */
+	int atomic_next; /* number of following atomic ops */
+
+	/*
+	 * We distinguish between: (a) nestable atomic regions that may contain
+	 * other nestable regions; and (b) flat atomic regions that do not keep
+	 * track of nesting. Both (a) and (b) are entirely independent of each
+	 * other, and a flat region may be started in a nestable region or
+	 * vice-versa.
+	 *
+	 * This is required because, for example, in the annotations for
+	 * seqlocks, we declare seqlock writer critical sections as (a) nestable
+	 * atomic regions, but reader critical sections as (b) flat atomic
+	 * regions, but have encountered cases where seqlock reader critical
+	 * sections are contained within writer critical sections (the opposite
+	 * may be possible, too).
+	 *
+	 * To support these cases, we independently track the depth of nesting
+	 * for (a), and whether the leaf level is flat for (b).
+	 */
+	int atomic_nest_count;
+	bool in_flat_atomic;
+
+	/*
+	 * Access mask for all accesses if non-zero.
+	 */
+	unsigned long access_mask;
+
+	/* List of scoped accesses. */
+	struct list_head scoped_accesses;
+};
+
+/**
+ * kcsan_init - initialize KCSAN runtime
+ */
+void kcsan_init(void);
+
+#else /* CONFIG_KCSAN */
+
+static inline void kcsan_init(void)			{ }
+
+#endif /* CONFIG_KCSAN */
+
+#endif /* _LINUX_KCSAN_H */
diff --git a/include/linux/key.h b/include/linux/key.h
index 6cf8e71cf8b7..b99b40db08fc 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -176,6 +176,9 @@ struct key {
 		struct list_head graveyard_link;
 		struct rb_node	serial_node;
 	};
+#ifdef CONFIG_KEY_NOTIFICATIONS
+	struct watch_list	*watchers;	/* Entities watching this key for changes */
+#endif
 	struct rw_semaphore	sem;		/* change vs change sem */
 	struct key_user		*user;		/* owner of this key */
 	void			*security;	/* security data for this key */
diff --git a/include/linux/list.h b/include/linux/list.h
index aff44d34f4e4..2e8e8257aac6 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -536,6 +536,17 @@ static inline void list_splice_tail_init(struct list_head *list,
 #define list_next_entry(pos, member) \
 	list_entry((pos)->member.next, typeof(*(pos)), member)
 
+/**
+ * list_next_entry_safe - get the next element in list [once]
+ * @pos:	the type * to cursor
+ * @member:	the name of the list_head within the struct.
+ *
+ * Like list_next_entry() but prevents the compiler from reloading the
+ * next element.
+ */
+#define list_next_entry_safe(pos, member) \
+	list_entry(READ_ONCE((pos)->member.next), typeof(*(pos)), member)
+
 /**
  * list_prev_entry - get the prev element in list
  * @pos:	the type * to cursor
@@ -544,6 +555,17 @@ static inline void list_splice_tail_init(struct list_head *list,
 #define list_prev_entry(pos, member) \
 	list_entry((pos)->member.prev, typeof(*(pos)), member)
 
+/**
+ * list_prev_entry_safe - get the prev element in list [once]
+ * @pos:	the type * to cursor
+ * @member:	the name of the list_head within the struct.
+ *
+ * Like list_prev_entry() but prevents the compiler from reloading the
+ * previous element.
+ */
+#define list_prev_entry_safe(pos, member) \
+	list_entry(READ_ONCE((pos)->member.prev), typeof(*(pos)), member)
+
 /**
  * list_for_each	-	iterate over a list
  * @pos:	the &struct list_head to use as a loop cursor.
@@ -686,9 +708,9 @@ static inline void list_splice_tail_init(struct list_head *list,
  */
 #define list_for_each_entry_safe(pos, n, head, member)			\
 	for (pos = list_first_entry(head, typeof(*pos), member),	\
-		n = list_next_entry(pos, member);			\
+		n = list_next_entry_safe(pos, member);			\
 	     &pos->member != (head); 					\
-	     pos = n, n = list_next_entry(n, member))
+	     pos = n, n = list_next_entry_safe(n, member))
 
 /**
  * list_for_each_entry_safe_continue - continue list iteration safe against removal
@@ -700,11 +722,11 @@ static inline void list_splice_tail_init(struct list_head *list,
  * Iterate over list of given type, continuing after current point,
  * safe against removal of list entry.
  */
-#define list_for_each_entry_safe_continue(pos, n, head, member) 		\
-	for (pos = list_next_entry(pos, member), 				\
-		n = list_next_entry(pos, member);				\
-	     &pos->member != (head);						\
-	     pos = n, n = list_next_entry(n, member))
+#define list_for_each_entry_safe_continue(pos, n, head, member) 	\
+	for (pos = list_next_entry(pos, member), 			\
+		n = list_next_entry_safe(pos, member);			\
+	     &pos->member != (head);					\
+	     pos = n, n = list_next_entry_safe(n, member))
 
 /**
  * list_for_each_entry_safe_from - iterate over list from current point safe against removal
@@ -716,10 +738,10 @@ static inline void list_splice_tail_init(struct list_head *list,
  * Iterate over list of given type from current point, safe against
  * removal of list entry.
  */
-#define list_for_each_entry_safe_from(pos, n, head, member) 			\
-	for (n = list_next_entry(pos, member);					\
-	     &pos->member != (head);						\
-	     pos = n, n = list_next_entry(n, member))
+#define list_for_each_entry_safe_from(pos, n, head, member) 		\
+	for (n = list_next_entry_safe(pos, member);			\
+	     &pos->member != (head);					\
+	     pos = n, n = list_next_entry_safe(n, member))
 
 /**
  * list_for_each_entry_safe_reverse - iterate backwards over list safe against removal
@@ -733,9 +755,9 @@ static inline void list_splice_tail_init(struct list_head *list,
  */
 #define list_for_each_entry_safe_reverse(pos, n, head, member)		\
 	for (pos = list_last_entry(head, typeof(*pos), member),		\
-		n = list_prev_entry(pos, member);			\
+		n = list_prev_entry_safe(pos, member);			\
 	     &pos->member != (head); 					\
-	     pos = n, n = list_prev_entry(n, member))
+	     pos = n, n = list_prev_entry_safe(n, member))
 
 /**
  * list_safe_reset_next - reset a stale list_for_each_entry_safe loop
@@ -750,7 +772,7 @@ static inline void list_splice_tail_init(struct list_head *list,
  * completing the current iteration of the loop body.
  */
 #define list_safe_reset_next(pos, n, member)				\
-	n = list_next_entry(pos, member)
+	n = list_next_entry_safe(pos, member)
 
 /*
  * Double linked lists with a single pointer list head.
diff --git a/include/linux/list_lru.h b/include/linux/list_lru.h
index d5ceb2839a2d..9dcaa3e582c9 100644
--- a/include/linux/list_lru.h
+++ b/include/linux/list_lru.h
@@ -34,7 +34,7 @@ struct list_lru_one {
 struct list_lru_memcg {
 	struct rcu_head		rcu;
 	/* array of per cgroup lists, indexed by memcg_cache_id */
-	struct list_lru_one	*lru[0];
+	struct list_lru_one	*lru[];
 };
 
 struct list_lru_node {
diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h
index 99d629fd9944..28f23b341c1c 100644
--- a/include/linux/lsm_audit.h
+++ b/include/linux/lsm_audit.h
@@ -75,6 +75,7 @@ struct common_audit_data {
 #define LSM_AUDIT_DATA_IBPKEY	13
 #define LSM_AUDIT_DATA_IBENDPORT 14
 #define LSM_AUDIT_DATA_LOCKDOWN 15
+#define LSM_AUDIT_DATA_NOTIFICATION 16
 	union 	{
 		struct path path;
 		struct dentry *dentry;
diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index 9cd4455528e5..4f8d63fd1327 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -252,6 +252,16 @@ LSM_HOOK(int, 0, inode_notifysecctx, struct inode *inode, void *ctx, u32 ctxlen)
 LSM_HOOK(int, 0, inode_setsecctx, struct dentry *dentry, void *ctx, u32 ctxlen)
 LSM_HOOK(int, 0, inode_getsecctx, struct inode *inode, void **ctx,
 	 u32 *ctxlen)
+#ifdef CONFIG_KEY_NOTIFICATIONS
+LSM_HOOK(int, 0, watch_key, struct key *key)
+#endif
+#ifdef CONFIG_DEVICE_NOTIFICATIONS
+LSM_HOOK(int, 0, watch_devices, void)
+#endif
+#ifdef CONFIG_WATCH_QUEUE
+LSM_HOOK(int, 0, post_notification, const struct cred *w_cred,
+	 const struct cred *cred, struct watch_notification *n)
+#endif
 
 #ifdef CONFIG_SECURITY_NETWORK
 LSM_HOOK(int, 0, unix_stream_connect, struct sock *sock, struct sock *other,
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 988ca0df7824..23bd89a3d369 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -1437,6 +1437,24 @@
  *	@ctx is a pointer in which to place the allocated security context.
  *	@ctxlen points to the place to put the length of @ctx.
  *
+ * Security hooks for the general notification queue:
+ *
+ * @watch_key:
+ *	Check to see if a process is allowed to watch for event notifications
+ *	from a key or keyring.
+ *	@key: The key to watch.
+ *
+ * @watch_devices:
+ *	Check to see if a process is allowed to watch for event notifications
+ *	from devices (as a global set).
+ *
+ * @post_notification:
+ *	Check to see if a watch notification can be posted to a particular
+ *	queue.
+ *	@w_cred: The credentials of the whoever set the watch.
+ *	@cred: The event-triggerer's credentials
+ *	@n: The notification being posted
+ *
  * Security hooks for using the eBPF maps and programs functionalities through
  * eBPF syscalls.
  *
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index 1b4150ff64be..d630af1a4e17 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -106,7 +106,7 @@ struct lruvec_stat {
  */
 struct memcg_shrinker_map {
 	struct rcu_head rcu;
-	unsigned long map[0];
+	unsigned long map[];
 };
 
 /*
@@ -148,7 +148,7 @@ struct mem_cgroup_threshold_ary {
 	/* Size of entries[] */
 	unsigned int size;
 	/* Array of thresholds */
-	struct mem_cgroup_threshold entries[0];
+	struct mem_cgroup_threshold entries[];
 };
 
 struct mem_cgroup_thresholds {
@@ -533,7 +533,7 @@ unsigned long mem_cgroup_get_zone_lru_size(struct lruvec *lruvec,
 	struct mem_cgroup_per_node *mz;
 
 	mz = container_of(lruvec, struct mem_cgroup_per_node, lruvec);
-	return mz->lru_zone_size[zone_idx][lru];
+	return READ_ONCE(mz->lru_zone_size[zone_idx][lru]);
 }
 
 void mem_cgroup_handle_over_high(void);
diff --git a/include/linux/memremap.h b/include/linux/memremap.h
index 5f5b2df06e61..fac75e5a723b 100644
--- a/include/linux/memremap.h
+++ b/include/linux/memremap.h
@@ -125,6 +125,7 @@ static inline struct vmem_altmap *pgmap_altmap(struct dev_pagemap *pgmap)
 }
 
 #ifdef CONFIG_ZONE_DEVICE
+bool pfn_zone_device_reserved(unsigned long pfn);
 void *memremap_pages(struct dev_pagemap *pgmap, int nid);
 void memunmap_pages(struct dev_pagemap *pgmap);
 void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap);
@@ -136,6 +137,11 @@ unsigned long vmem_altmap_offset(struct vmem_altmap *altmap);
 void vmem_altmap_free(struct vmem_altmap *altmap, unsigned long nr_pfns);
 unsigned long memremap_compat_align(void);
 #else
+static inline bool pfn_zone_device_reserved(unsigned long pfn)
+{
+	return false;
+}
+
 static inline void *devm_memremap_pages(struct device *dev,
 		struct dev_pagemap *pgmap)
 {
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 5a323422d783..b095b502eafc 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1050,6 +1050,7 @@ vm_fault_t finish_mkwrite_fault(struct vm_fault *vmf);
 
 static inline enum zone_type page_zonenum(const struct page *page)
 {
+	ASSERT_EXCLUSIVE_BITS(page->flags, ZONES_MASK << ZONES_PGSHIFT);
 	return (page->flags >> ZONES_PGSHIFT) & ZONES_MASK;
 }
 
@@ -2542,7 +2543,8 @@ extern int __do_munmap(struct mm_struct *, unsigned long, size_t,
 		       struct list_head *uf, bool downgrade);
 extern int do_munmap(struct mm_struct *, unsigned long, size_t,
 		     struct list_head *uf);
-extern int do_madvise(unsigned long start, size_t len_in, int behavior);
+extern int do_madvise(struct task_struct *target_task, struct mm_struct *mm,
+		unsigned long start, size_t len_in, int behavior);
 
 static inline unsigned long
 do_mmap_pgoff(struct file *file, unsigned long addr,
diff --git a/include/linux/mmdebug.h b/include/linux/mmdebug.h
index 2ad72d2c8cc5..5339aa14b749 100644
--- a/include/linux/mmdebug.h
+++ b/include/linux/mmdebug.h
@@ -64,4 +64,9 @@ void dump_mm(const struct mm_struct *mm);
 #define VM_BUG_ON_PGFLAGS(cond, page) BUILD_BUG_ON_INVALID(cond)
 #endif
 
+#ifdef CONFIG_DEBUG_VM_PGTABLE
+void debug_vm_pgtable(void);
+#else
+static inline void debug_vm_pgtable(void) { }
+#endif
 #endif
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 4c2ddd0941a7..4b3d0a4945df 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -532,6 +532,8 @@ enum dmi_field {
 	DMI_BIOS_VENDOR,
 	DMI_BIOS_VERSION,
 	DMI_BIOS_DATE,
+	DMI_BIOS_RELEASE,
+	DMI_EC_FIRMWARE_RELEASE,
 	DMI_SYS_VENDOR,
 	DMI_PRODUCT_NAME,
 	DMI_PRODUCT_VERSION,
diff --git a/include/linux/nmi.h b/include/linux/nmi.h
index 9003e29cde46..8406df72ae5a 100644
--- a/include/linux/nmi.h
+++ b/include/linux/nmi.h
@@ -84,6 +84,7 @@ static inline void reset_hung_task_detector(void) { }
 #if defined(CONFIG_HARDLOCKUP_DETECTOR)
 extern void hardlockup_detector_disable(void);
 extern unsigned int hardlockup_panic;
+extern atomic_t hardlockup_detected;
 #else
 static inline void hardlockup_detector_disable(void) {}
 #endif
diff --git a/include/linux/ntb.h b/include/linux/ntb.h
index 8c13538aeffe..a07252f78770 100644
--- a/include/linux/ntb.h
+++ b/include/linux/ntb.h
@@ -478,7 +478,7 @@ void ntb_unregister_client(struct ntb_client *client);
 int ntb_register_device(struct ntb_dev *ntb);
 
 /**
- * ntb_register_device() - unregister a ntb device
+ * ntb_unregister_device() - unregister a ntb device
  * @ntb:	NTB device context.
  *
  * The device will be removed from the list of ntb devices.  If the ntb device
diff --git a/include/linux/pid.h b/include/linux/pid.h
index cc896f0fc4e3..d7d2d01a96e1 100644
--- a/include/linux/pid.h
+++ b/include/linux/pid.h
@@ -77,6 +77,7 @@ extern const struct file_operations pidfd_fops;
 struct file;
 
 extern struct pid *pidfd_pid(const struct file *file);
+struct pid *pidfd_get_pid(unsigned int fd);
 
 static inline struct pid *get_pid(struct pid *pid)
 {
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h
index ae58fad7f1e0..6626f511de6f 100644
--- a/include/linux/pipe_fs_i.h
+++ b/include/linux/pipe_fs_i.h
@@ -8,6 +8,10 @@
 #define PIPE_BUF_FLAG_ATOMIC	0x02	/* was atomically mapped */
 #define PIPE_BUF_FLAG_GIFT	0x04	/* page is a gift */
 #define PIPE_BUF_FLAG_PACKET	0x08	/* read() as a packet */
+#define PIPE_BUF_FLAG_WHOLE	0x10	/* read() must return entire buffer or error */
+#ifdef CONFIG_WATCH_QUEUE
+#define PIPE_BUF_FLAG_LOSS	0x20	/* Message loss happened after this buffer */
+#endif
 
 /**
  *	struct pipe_buffer - a linux kernel pipe buffer
@@ -33,8 +37,10 @@ struct pipe_buffer {
  *	@wr_wait: writer wait point in case of full pipe
  *	@head: The point of buffer production
  *	@tail: The point of buffer consumption
+ *	@note_loss: The next read() should insert a data-lost message
  *	@max_usage: The maximum number of slots that may be used in the ring
  *	@ring_size: total number of buffers (should be a power of 2)
+ *	@nr_accounted: The amount this pipe accounts for in user->pipe_bufs
  *	@tmp_page: cached released page
  *	@readers: number of current readers of this pipe
  *	@writers: number of current writers of this pipe
@@ -45,6 +51,7 @@ struct pipe_buffer {
  *	@fasync_writers: writer side fasync
  *	@bufs: the circular array of pipe buffers
  *	@user: the user who created this pipe
+ *	@watch_queue: If this pipe is a watch_queue, this is the stuff for that
  **/
 struct pipe_inode_info {
 	struct mutex mutex;
@@ -53,6 +60,10 @@ struct pipe_inode_info {
 	unsigned int tail;
 	unsigned int max_usage;
 	unsigned int ring_size;
+#ifdef CONFIG_WATCH_QUEUE
+	bool note_loss;
+#endif
+	unsigned int nr_accounted;
 	unsigned int readers;
 	unsigned int writers;
 	unsigned int files;
@@ -63,6 +74,9 @@ struct pipe_inode_info {
 	struct fasync_struct *fasync_writers;
 	struct pipe_buffer *bufs;
 	struct user_struct *user;
+#ifdef CONFIG_WATCH_QUEUE
+	struct watch_queue *watch_queue;
+#endif
 };
 
 /*
@@ -237,9 +251,20 @@ void pipe_buf_mark_unmergeable(struct pipe_buffer *buf);
 
 extern const struct pipe_buf_operations nosteal_pipe_buf_ops;
 
+#ifdef CONFIG_WATCH_QUEUE
+unsigned long account_pipe_buffers(struct user_struct *user,
+				   unsigned long old, unsigned long new);
+bool too_many_pipe_buffers_soft(unsigned long user_bufs);
+bool too_many_pipe_buffers_hard(unsigned long user_bufs);
+bool pipe_is_unprivileged_user(void);
+#endif
+
 /* for F_SETPIPE_SZ and F_GETPIPE_SZ */
+#ifdef CONFIG_WATCH_QUEUE
+int pipe_resize_ring(struct pipe_inode_info *pipe, unsigned int nr_slots);
+#endif
 long pipe_fcntl(struct file *, unsigned int, unsigned long arg);
-struct pipe_inode_info *get_pipe_info(struct file *file);
+struct pipe_inode_info *get_pipe_info(struct file *file, bool for_splice);
 
 int create_pipe_files(struct file **, int);
 unsigned int round_pipe_size(unsigned long size);
diff --git a/include/linux/platform_data/wilco-ec.h b/include/linux/platform_data/wilco-ec.h
index 25f46a939637..3e268e636b5b 100644
--- a/include/linux/platform_data/wilco-ec.h
+++ b/include/linux/platform_data/wilco-ec.h
@@ -83,7 +83,7 @@ struct wilco_ec_response {
 	u16 result;
 	u16 data_size;
 	u8 reserved[2];
-	u8 data[0];
+	u8 data[];
 } __packed;
 
 /**
diff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h
index 540595a321a7..90797f1b421d 100644
--- a/include/linux/posix_acl.h
+++ b/include/linux/posix_acl.h
@@ -28,7 +28,7 @@ struct posix_acl {
 	refcount_t		a_refcount;
 	struct rcu_head		a_rcu;
 	unsigned int		a_count;
-	struct posix_acl_entry	a_entries[0];
+	struct posix_acl_entry	a_entries[];
 };
 
 #define FOREACH_ACL_ENTRY(pa, acl, pe) \
diff --git a/include/linux/ras.h b/include/linux/ras.h
index 7c3debb47c87..1f4048bf2674 100644
--- a/include/linux/ras.h
+++ b/include/linux/ras.h
@@ -17,12 +17,7 @@ static inline int ras_add_daemon_trace(void) { return 0; }
 #endif
 
 #ifdef CONFIG_RAS_CEC
-void __init cec_init(void);
 int __init parse_cec_param(char *str);
-int cec_add_elem(u64 pfn);
-#else
-static inline void __init cec_init(void)	{ }
-static inline int cec_add_elem(u64 pfn)		{ return -ENODEV; }
 #endif
 
 #ifdef CONFIG_RAS
diff --git a/include/linux/rculist.h b/include/linux/rculist.h
index 8214cdc715f2..277da7393c3c 100644
--- a/include/linux/rculist.h
+++ b/include/linux/rculist.h
@@ -248,6 +248,8 @@ static inline void __list_splice_init_rcu(struct list_head *list,
 	 */
 
 	sync();
+	ASSERT_EXCLUSIVE_ACCESS(*first);
+	ASSERT_EXCLUSIVE_ACCESS(*last);
 
 	/*
 	 * Readers are finished with the source list, so perform splice.
@@ -371,7 +373,7 @@ static inline void list_splice_tail_init_rcu(struct list_head *list,
  * @pos:	the type * to use as a loop cursor.
  * @head:	the head for your list.
  * @member:	the name of the list_head within the struct.
- * @cond...:	optional lockdep expression if called from non-RCU protection.
+ * @cond:	optional lockdep expression if called from non-RCU protection.
  *
  * This list-traversal primitive may safely run concurrently with
  * the _rcu list-mutation primitives such as list_add_rcu()
@@ -646,7 +648,7 @@ static inline void hlist_add_behind_rcu(struct hlist_node *n,
  * @pos:	the type * to use as a loop cursor.
  * @head:	the head for your list.
  * @member:	the name of the hlist_node within the struct.
- * @cond...:	optional lockdep expression if called from non-RCU protection.
+ * @cond:	optional lockdep expression if called from non-RCU protection.
  *
  * This list-traversal primitive may safely run concurrently with
  * the _rcu list-mutation primitives such as hlist_add_head_rcu()
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 2678a37c3169..659cbfa7581a 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -37,6 +37,7 @@
 /* Exported common interfaces */
 void call_rcu(struct rcu_head *head, rcu_callback_t func);
 void rcu_barrier_tasks(void);
+void rcu_barrier_tasks_rude(void);
 void synchronize_rcu(void);
 
 #ifdef CONFIG_PREEMPT_RCU
@@ -129,25 +130,57 @@ static inline void rcu_init_nohz(void) { }
  * Note a quasi-voluntary context switch for RCU-tasks's benefit.
  * This is a macro rather than an inline function to avoid #include hell.
  */
-#ifdef CONFIG_TASKS_RCU
-#define rcu_tasks_qs(t) \
-	do { \
-		if (READ_ONCE((t)->rcu_tasks_holdout)) \
-			WRITE_ONCE((t)->rcu_tasks_holdout, false); \
+#ifdef CONFIG_TASKS_RCU_GENERIC
+
+# ifdef CONFIG_TASKS_RCU
+# define rcu_tasks_classic_qs(t, preempt)				\
+	do {								\
+		if (!(preempt) && READ_ONCE((t)->rcu_tasks_holdout))	\
+			WRITE_ONCE((t)->rcu_tasks_holdout, false);	\
 	} while (0)
-#define rcu_note_voluntary_context_switch(t) rcu_tasks_qs(t)
 void call_rcu_tasks(struct rcu_head *head, rcu_callback_t func);
 void synchronize_rcu_tasks(void);
+# else
+# define rcu_tasks_classic_qs(t, preempt) do { } while (0)
+# define call_rcu_tasks call_rcu
+# define synchronize_rcu_tasks synchronize_rcu
+# endif
+
+# ifdef CONFIG_TASKS_RCU_TRACE
+# define rcu_tasks_trace_qs(t)						\
+	do {								\
+		if (!likely(READ_ONCE((t)->trc_reader_checked)) &&	\
+		    !unlikely(READ_ONCE((t)->trc_reader_nesting))) {	\
+			smp_store_release(&(t)->trc_reader_checked, true); \
+			smp_mb(); /* Readers partitioned by store. */	\
+		}							\
+	} while (0)
+# else
+# define rcu_tasks_trace_qs(t) do { } while (0)
+# endif
+
+#define rcu_tasks_qs(t, preempt)					\
+do {									\
+	rcu_tasks_classic_qs((t), (preempt));				\
+	rcu_tasks_trace_qs((t));					\
+} while (0)
+
+# ifdef CONFIG_TASKS_RUDE_RCU
+void call_rcu_tasks_rude(struct rcu_head *head, rcu_callback_t func);
+void synchronize_rcu_tasks_rude(void);
+# endif
+
+#define rcu_note_voluntary_context_switch(t) rcu_tasks_qs(t, false)
 void exit_tasks_rcu_start(void);
 void exit_tasks_rcu_finish(void);
-#else /* #ifdef CONFIG_TASKS_RCU */
-#define rcu_tasks_qs(t)	do { } while (0)
+#else /* #ifdef CONFIG_TASKS_RCU_GENERIC */
+#define rcu_tasks_qs(t, preempt) do { } while (0)
 #define rcu_note_voluntary_context_switch(t) do { } while (0)
 #define call_rcu_tasks call_rcu
 #define synchronize_rcu_tasks synchronize_rcu
 static inline void exit_tasks_rcu_start(void) { }
 static inline void exit_tasks_rcu_finish(void) { }
-#endif /* #else #ifdef CONFIG_TASKS_RCU */
+#endif /* #else #ifdef CONFIG_TASKS_RCU_GENERIC */
 
 /**
  * cond_resched_tasks_rcu_qs - Report potential quiescent states to RCU
@@ -158,7 +191,7 @@ static inline void exit_tasks_rcu_finish(void) { }
  */
 #define cond_resched_tasks_rcu_qs() \
 do { \
-	rcu_tasks_qs(current); \
+	rcu_tasks_qs(current, false); \
 	cond_resched(); \
 } while (0)
 
diff --git a/include/linux/rcupdate_trace.h b/include/linux/rcupdate_trace.h
new file mode 100644
index 000000000000..4c25a41f8b27
--- /dev/null
+++ b/include/linux/rcupdate_trace.h
@@ -0,0 +1,88 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Read-Copy Update mechanism for mutual exclusion, adapted for tracing.
+ *
+ * Copyright (C) 2020 Paul E. McKenney.
+ */
+
+#ifndef __LINUX_RCUPDATE_TRACE_H
+#define __LINUX_RCUPDATE_TRACE_H
+
+#include <linux/sched.h>
+#include <linux/rcupdate.h>
+
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+
+extern struct lockdep_map rcu_trace_lock_map;
+
+static inline int rcu_read_lock_trace_held(void)
+{
+	return lock_is_held(&rcu_trace_lock_map);
+}
+
+#else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
+
+static inline int rcu_read_lock_trace_held(void)
+{
+	return 1;
+}
+
+#endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */
+
+#ifdef CONFIG_TASKS_TRACE_RCU
+
+void rcu_read_unlock_trace_special(struct task_struct *t, int nesting);
+
+/**
+ * rcu_read_lock_trace - mark beginning of RCU-trace read-side critical section
+ *
+ * When synchronize_rcu_trace() is invoked by one task, then that task
+ * is guaranteed to block until all other tasks exit their read-side
+ * critical sections.  Similarly, if call_rcu_trace() is invoked on one
+ * task while other tasks are within RCU read-side critical sections,
+ * invocation of the corresponding RCU callback is deferred until after
+ * the all the other tasks exit their critical sections.
+ *
+ * For more details, please see the documentation for rcu_read_lock().
+ */
+static inline void rcu_read_lock_trace(void)
+{
+	struct task_struct *t = current;
+
+	WRITE_ONCE(t->trc_reader_nesting, READ_ONCE(t->trc_reader_nesting) + 1);
+	if (IS_ENABLED(CONFIG_TASKS_TRACE_RCU_READ_MB) &&
+	    t->trc_reader_special.b.need_mb)
+		smp_mb(); // Pairs with update-side barriers
+	rcu_lock_acquire(&rcu_trace_lock_map);
+}
+
+/**
+ * rcu_read_unlock_trace - mark end of RCU-trace read-side critical section
+ *
+ * Pairs with a preceding call to rcu_read_lock_trace(), and nesting is
+ * allowed.  Invoking a rcu_read_unlock_trace() when there is no matching
+ * rcu_read_lock_trace() is verboten, and will result in lockdep complaints.
+ *
+ * For more details, please see the documentation for rcu_read_unlock().
+ */
+static inline void rcu_read_unlock_trace(void)
+{
+	int nesting;
+	struct task_struct *t = current;
+
+	rcu_lock_release(&rcu_trace_lock_map);
+	nesting = READ_ONCE(t->trc_reader_nesting) - 1;
+	if (likely(!READ_ONCE(t->trc_reader_special.s)) || nesting) {
+		WRITE_ONCE(t->trc_reader_nesting, nesting);
+		return;  // We assume shallow reader nesting.
+	}
+	rcu_read_unlock_trace_special(t, nesting);
+}
+
+void call_rcu_tasks_trace(struct rcu_head *rhp, rcu_callback_t func);
+void synchronize_rcu_tasks_trace(void);
+void rcu_barrier_tasks_trace(void);
+
+#endif /* #ifdef CONFIG_TASKS_TRACE_RCU */
+
+#endif /* __LINUX_RCUPDATE_TRACE_H */
diff --git a/include/linux/rcupdate_wait.h b/include/linux/rcupdate_wait.h
index c0578ba23c1a..699b938358bf 100644
--- a/include/linux/rcupdate_wait.h
+++ b/include/linux/rcupdate_wait.h
@@ -31,4 +31,23 @@ do {									\
 
 #define wait_rcu_gp(...) _wait_rcu_gp(false, __VA_ARGS__)
 
+/**
+ * synchronize_rcu_mult - Wait concurrently for multiple grace periods
+ * @...: List of call_rcu() functions for different grace periods to wait on
+ *
+ * This macro waits concurrently for multiple types of RCU grace periods.
+ * For example, synchronize_rcu_mult(call_rcu, call_rcu_tasks) would wait
+ * on concurrent RCU and RCU-tasks grace periods.  Waiting on a given SRCU
+ * domain requires you to write a wrapper function for that SRCU domain's
+ * call_srcu() function, with this wrapper supplying the pointer to the
+ * corresponding srcu_struct.
+ *
+ * The first argument tells Tiny RCU's _wait_rcu_gp() not to
+ * bother waiting for RCU.  The reason for this is because anywhere
+ * synchronize_rcu_mult() can be called is automatically already a full
+ * grace period.
+ */
+#define synchronize_rcu_mult(...) \
+	_wait_rcu_gp(IS_ENABLED(CONFIG_TINY_RCU), __VA_ARGS__)
+
 #endif /* _LINUX_SCHED_RCUPDATE_WAIT_H */
diff --git a/include/linux/rcutiny.h b/include/linux/rcutiny.h
index 045c28b71f4f..3465ba704a11 100644
--- a/include/linux/rcutiny.h
+++ b/include/linux/rcutiny.h
@@ -49,7 +49,7 @@ static inline void rcu_softirq_qs(void)
 #define rcu_note_context_switch(preempt) \
 	do { \
 		rcu_qs(); \
-		rcu_tasks_qs(current); \
+		rcu_tasks_qs(current, (preempt)); \
 	} while (0)
 
 static inline int rcu_needs_cpu(u64 basemono, u64 *nextevt)
@@ -87,6 +87,7 @@ static inline bool rcu_inkernel_boot_has_ended(void) { return true; }
 static inline bool rcu_is_watching(void) { return true; }
 static inline void rcu_momentary_dyntick_idle(void) { }
 static inline void kfree_rcu_scheduler_running(void) { }
+static inline bool rcu_gp_might_be_stalled(void) { return false; }
 
 /* Avoid RCU read-side critical sections leaking across. */
 static inline void rcu_all_qs(void) { barrier(); }
diff --git a/include/linux/rcutree.h b/include/linux/rcutree.h
index 45f3f66bb04d..fbc26274af4d 100644
--- a/include/linux/rcutree.h
+++ b/include/linux/rcutree.h
@@ -39,6 +39,7 @@ void rcu_barrier(void);
 bool rcu_eqs_special_set(int cpu);
 void rcu_momentary_dyntick_idle(void);
 void kfree_rcu_scheduler_running(void);
+bool rcu_gp_might_be_stalled(void);
 unsigned long get_state_synchronize_rcu(void);
 void cond_synchronize_rcu(unsigned long oldstate);
 
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 40b07168fd8e..91420af1c30d 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -21,6 +21,7 @@
 struct module;
 struct clk;
 struct device;
+struct device_node;
 struct i2c_client;
 struct i3c_device;
 struct irq_domain;
@@ -71,6 +72,13 @@ struct reg_sequence {
 	unsigned int delay_us;
 };
 
+#define REG_SEQ(_reg, _def, _delay_us) {		\
+				.reg = _reg,		\
+				.def = _def,		\
+				.delay_us = _delay_us,	\
+				}
+#define REG_SEQ0(_reg, _def)	REG_SEQ(_reg, _def, 0)
+
 #define	regmap_update_bits(map, reg, mask, val) \
 	regmap_update_bits_base(map, reg, mask, val, NULL, false, false)
 #define	regmap_update_bits_async(map, reg, mask, val)\
@@ -1310,12 +1318,21 @@ struct regmap_irq_chip_data;
 int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
 			int irq_base, const struct regmap_irq_chip *chip,
 			struct regmap_irq_chip_data **data);
+int regmap_add_irq_chip_np(struct device_node *np, struct regmap *map, int irq,
+			   int irq_flags, int irq_base,
+			   const struct regmap_irq_chip *chip,
+			   struct regmap_irq_chip_data **data);
 void regmap_del_irq_chip(int irq, struct regmap_irq_chip_data *data);
 
 int devm_regmap_add_irq_chip(struct device *dev, struct regmap *map, int irq,
 			     int irq_flags, int irq_base,
 			     const struct regmap_irq_chip *chip,
 			     struct regmap_irq_chip_data **data);
+int devm_regmap_add_irq_chip_np(struct device *dev, struct device_node *np,
+				struct regmap *map, int irq, int irq_flags,
+				int irq_base,
+				const struct regmap_irq_chip *chip,
+				struct regmap_irq_chip_data **data);
 void devm_regmap_del_irq_chip(struct device *dev, int irq,
 			      struct regmap_irq_chip_data *data);
 
diff --git a/include/linux/rio.h b/include/linux/rio.h
index 317bace5ac64..2cd637268b4f 100644
--- a/include/linux/rio.h
+++ b/include/linux/rio.h
@@ -100,7 +100,7 @@ struct rio_switch {
 	u32 port_ok;
 	struct rio_switch_ops *ops;
 	spinlock_t lock;
-	struct rio_dev *nextdev[0];
+	struct rio_dev *nextdev[];
 };
 
 /**
@@ -201,7 +201,7 @@ struct rio_dev {
 	u8 hopcount;
 	struct rio_dev *prev;
 	atomic_t state;
-	struct rio_switch rswitch[0];	/* RIO switch info */
+	struct rio_switch rswitch[];	/* RIO switch info */
 };
 
 #define rio_dev_g(n) list_entry(n, struct rio_dev, global_list)
diff --git a/include/linux/rslib.h b/include/linux/rslib.h
index 5974cedd008c..238bb85243d3 100644
--- a/include/linux/rslib.h
+++ b/include/linux/rslib.h
@@ -54,7 +54,7 @@ struct rs_codec {
  */
 struct rs_control {
 	struct rs_codec	*codec;
-	uint16_t	buffers[0];
+	uint16_t	buffers[];
 };
 
 /* General purpose RS codec, 8-bit data width, symbol width 1-15 bit  */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 4418f5cb8324..36306c7d2afc 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -31,6 +31,7 @@
 #include <linux/task_io_accounting.h>
 #include <linux/posix-timers.h>
 #include <linux/rseq.h>
+#include <linux/kcsan.h>
 
 /* task_struct member predeclarations (sorted alphabetically): */
 struct audit_context;
@@ -613,7 +614,7 @@ union rcu_special {
 		u8			blocked;
 		u8			need_qs;
 		u8			exp_hint; /* Hint for performance. */
-		u8			deferred_qs;
+		u8			need_mb; /* Readers need smp_mb(). */
 	} b; /* Bits. */
 	u32 s; /* Set of bits. */
 };
@@ -724,6 +725,14 @@ struct task_struct {
 	struct list_head		rcu_tasks_holdout_list;
 #endif /* #ifdef CONFIG_TASKS_RCU */
 
+#ifdef CONFIG_TASKS_TRACE_RCU
+	int				trc_reader_nesting;
+	int				trc_ipi_to_cpu;
+	union rcu_special		trc_reader_special;
+	bool				trc_reader_checked;
+	struct list_head		trc_holdout_list;
+#endif /* #ifdef CONFIG_TASKS_TRACE_RCU */
+
 	struct sched_info		sched_info;
 
 	struct list_head		tasks;
@@ -911,6 +920,7 @@ struct task_struct {
 #ifdef CONFIG_DETECT_HUNG_TASK
 	unsigned long			last_switch_count;
 	unsigned long			last_switch_time;
+	unsigned long			killed_time;
 #endif
 	/* Filesystem information: */
 	struct fs_struct		*fs;
@@ -1187,6 +1197,9 @@ struct task_struct {
 #ifdef CONFIG_KASAN
 	unsigned int			kasan_depth;
 #endif
+#ifdef CONFIG_KCSAN
+	struct kcsan_ctx		kcsan_ctx;
+#endif
 
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
 	/* Index of current stored address in ret_stack: */
@@ -1237,6 +1250,9 @@ struct task_struct {
 
 	/* KCOV sequence number: */
 	int				kcov_sequence;
+
+	/* Collect coverage from softirq context: */
+	unsigned int			kcov_softirq;
 #endif
 
 #ifdef CONFIG_MEMCG
@@ -1289,6 +1305,13 @@ struct task_struct {
 	unsigned long			prev_lowest_stack;
 #endif
 
+#ifdef CONFIG_DEBUG_AID_FOR_SYZBOT
+	unsigned long			getblk_stamp;
+	unsigned int			getblk_executed;
+	unsigned int			getblk_bh_count;
+	unsigned long			getblk_bh_state;
+#endif
+
 	/*
 	 * New fields for task_struct should be added above here, so that
 	 * they are included in the randomized portion of task_struct.
diff --git a/include/linux/sched/topology.h b/include/linux/sched/topology.h
index af9319e4cfb9..95253ad792b0 100644
--- a/include/linux/sched/topology.h
+++ b/include/linux/sched/topology.h
@@ -142,7 +142,7 @@ struct sched_domain {
 	 * by attaching extra space to the end of the structure,
 	 * depending on how many CPUs the kernel has booted up with)
 	 */
-	unsigned long span[0];
+	unsigned long span[];
 };
 
 static inline struct cpumask *sched_domain_span(struct sched_domain *sd)
diff --git a/include/linux/security.h b/include/linux/security.h
index a8d9310472df..fe2c5669d4e7 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -56,6 +56,8 @@ struct mm_struct;
 struct fs_context;
 struct fs_parameter;
 enum fs_value_type;
+struct watch;
+struct watch_notification;
 
 /* Default (no) options for the capable function */
 #define CAP_OPT_NONE 0x0
@@ -1275,6 +1277,35 @@ static inline int security_locked_down(enum lockdown_reason what)
 }
 #endif	/* CONFIG_SECURITY */
 
+#if defined(CONFIG_SECURITY) && defined(CONFIG_KEY_NOTIFICATIONS)
+int security_watch_key(struct key *key);
+#else
+static inline int security_watch_key(struct key *key)
+{
+	return 0;
+}
+#endif
+#if defined(CONFIG_SECURITY) && defined(CONFIG_DEVICE_NOTIFICATIONS)
+int security_watch_devices(void);
+#else
+static inline int security_watch_devices(void)
+{
+	return 0;
+}
+#endif
+#if defined(CONFIG_SECURITY) && defined(CONFIG_WATCH_QUEUE)
+int security_post_notification(const struct cred *w_cred,
+			       const struct cred *cred,
+			       struct watch_notification *n);
+#else
+static inline int security_post_notification(const struct cred *w_cred,
+					     const struct cred *cred,
+					     struct watch_notification *n)
+{
+	return 0;
+}
+#endif
+
 #ifdef CONFIG_SECURITY_NETWORK
 
 int security_unix_stream_connect(struct sock *sock, struct sock *other, struct sock *newsk);
diff --git a/include/linux/seqlock.h b/include/linux/seqlock.h
index 0491d963d47e..8b97204f35a7 100644
--- a/include/linux/seqlock.h
+++ b/include/linux/seqlock.h
@@ -37,8 +37,24 @@
 #include <linux/preempt.h>
 #include <linux/lockdep.h>
 #include <linux/compiler.h>
+#include <linux/kcsan-checks.h>
 #include <asm/processor.h>
 
+/*
+ * The seqlock interface does not prescribe a precise sequence of read
+ * begin/retry/end. For readers, typically there is a call to
+ * read_seqcount_begin() and read_seqcount_retry(), however, there are more
+ * esoteric cases which do not follow this pattern.
+ *
+ * As a consequence, we take the following best-effort approach for raw usage
+ * via seqcount_t under KCSAN: upon beginning a seq-reader critical section,
+ * pessimistically mark the next KCSAN_SEQLOCK_REGION_MAX memory accesses as
+ * atomics; if there is a matching read_seqcount_retry() call, no following
+ * memory operations are considered atomic. Usage of seqlocks via seqlock_t
+ * interface is not affected.
+ */
+#define KCSAN_SEQLOCK_REGION_MAX 1000
+
 /*
  * Version using sequence counter only.
  * This can be used when code has its own mutex protecting the
@@ -115,6 +131,7 @@ static inline unsigned __read_seqcount_begin(const seqcount_t *s)
 		cpu_relax();
 		goto repeat;
 	}
+	kcsan_atomic_next(KCSAN_SEQLOCK_REGION_MAX);
 	return ret;
 }
 
@@ -131,6 +148,7 @@ static inline unsigned raw_read_seqcount(const seqcount_t *s)
 {
 	unsigned ret = READ_ONCE(s->sequence);
 	smp_rmb();
+	kcsan_atomic_next(KCSAN_SEQLOCK_REGION_MAX);
 	return ret;
 }
 
@@ -183,6 +201,7 @@ static inline unsigned raw_seqcount_begin(const seqcount_t *s)
 {
 	unsigned ret = READ_ONCE(s->sequence);
 	smp_rmb();
+	kcsan_atomic_next(KCSAN_SEQLOCK_REGION_MAX);
 	return ret & ~1;
 }
 
@@ -202,7 +221,8 @@ static inline unsigned raw_seqcount_begin(const seqcount_t *s)
  */
 static inline int __read_seqcount_retry(const seqcount_t *s, unsigned start)
 {
-	return unlikely(s->sequence != start);
+	kcsan_atomic_next(0);
+	return unlikely(READ_ONCE(s->sequence) != start);
 }
 
 /**
@@ -225,6 +245,7 @@ static inline int read_seqcount_retry(const seqcount_t *s, unsigned start)
 
 static inline void raw_write_seqcount_begin(seqcount_t *s)
 {
+	kcsan_nestable_atomic_begin();
 	s->sequence++;
 	smp_wmb();
 }
@@ -233,6 +254,7 @@ static inline void raw_write_seqcount_end(seqcount_t *s)
 {
 	smp_wmb();
 	s->sequence++;
+	kcsan_nestable_atomic_end();
 }
 
 /**
@@ -243,6 +265,13 @@ static inline void raw_write_seqcount_end(seqcount_t *s)
  * usual consistency guarantee. It is one wmb cheaper, because we can
  * collapse the two back-to-back wmb()s.
  *
+ * Note that writes surrounding the barrier should be declared atomic (e.g.
+ * via WRITE_ONCE): a) to ensure the writes become visible to other threads
+ * atomically, avoiding compiler optimizations; b) to document which writes are
+ * meant to propagate to the reader critical section. This is necessary because
+ * neither writes before and after the barrier are enclosed in a seq-writer
+ * critical section that would ensure readers are aware of ongoing writes.
+ *
  *      seqcount_t seq;
  *      bool X = true, Y = false;
  *
@@ -262,18 +291,20 @@ static inline void raw_write_seqcount_end(seqcount_t *s)
  *
  *      void write(void)
  *      {
- *              Y = true;
+ *              WRITE_ONCE(Y, true);
  *
  *              raw_write_seqcount_barrier(seq);
  *
- *              X = false;
+ *              WRITE_ONCE(X, false);
  *      }
  */
 static inline void raw_write_seqcount_barrier(seqcount_t *s)
 {
+	kcsan_nestable_atomic_begin();
 	s->sequence++;
 	smp_wmb();
 	s->sequence++;
+	kcsan_nestable_atomic_end();
 }
 
 static inline int raw_read_seqcount_latch(seqcount_t *s)
@@ -398,7 +429,9 @@ static inline void write_seqcount_end(seqcount_t *s)
 static inline void write_seqcount_invalidate(seqcount_t *s)
 {
 	smp_wmb();
+	kcsan_nestable_atomic_begin();
 	s->sequence+=2;
+	kcsan_nestable_atomic_end();
 }
 
 typedef struct {
@@ -430,11 +463,21 @@ typedef struct {
  */
 static inline unsigned read_seqbegin(const seqlock_t *sl)
 {
-	return read_seqcount_begin(&sl->seqcount);
+	unsigned ret = read_seqcount_begin(&sl->seqcount);
+
+	kcsan_atomic_next(0);  /* non-raw usage, assume closing read_seqretry() */
+	kcsan_flat_atomic_begin();
+	return ret;
 }
 
 static inline unsigned read_seqretry(const seqlock_t *sl, unsigned start)
 {
+	/*
+	 * Assume not nested: read_seqretry() may be called multiple times when
+	 * completing read critical section.
+	 */
+	kcsan_flat_atomic_end();
+
 	return read_seqcount_retry(&sl->seqcount, start);
 }
 
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 3a2ac7072dbb..3000c526f552 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -4162,7 +4162,7 @@ struct skb_ext {
 	refcount_t refcnt;
 	u8 offset[SKB_EXT_NUM]; /* in chunks of 8 bytes */
 	u8 chunks;		/* same */
-	char data[0] __aligned(8);
+	char data[] __aligned(8);
 };
 
 struct skb_ext *__skb_ext_alloc(void);
diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h
new file mode 100644
index 000000000000..7bab5d9a3d31
--- /dev/null
+++ b/include/linux/soc/mediatek/mtk-mmsys.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ */
+
+#ifndef __MTK_MMSYS_H
+#define __MTK_MMSYS_H
+
+enum mtk_ddp_comp_id;
+struct device;
+
+void mtk_mmsys_ddp_connect(struct device *dev,
+			   enum mtk_ddp_comp_id cur,
+			   enum mtk_ddp_comp_id next);
+
+void mtk_mmsys_ddp_disconnect(struct device *dev,
+			      enum mtk_ddp_comp_id cur,
+			      enum mtk_ddp_comp_id next);
+
+#endif /* __MTK_MMSYS_H */
diff --git a/include/linux/spi/mcp23s08.h b/include/linux/spi/mcp23s08.h
deleted file mode 100644
index 738a45b435f2..000000000000
--- a/include/linux/spi/mcp23s08.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-struct mcp23s08_platform_data {
-	/* For mcp23s08, up to 4 slaves (numbered 0..3) can share one SPI
-	 * chipselect, each providing 1 gpio_chip instance with 8 gpios.
-	 * For mpc23s17, up to 8 slaves (numbered 0..7) can share one SPI
-	 * chipselect, each providing 1 gpio_chip (port A + port B) with
-	 * 16 gpios.
-	 */
-	u32 spi_present_mask;
-
-	/* "base" is the number of the first GPIO or -1 for dynamic
-	 * assignment. If there are gaps in chip addressing the GPIO
-	 * numbers are sequential .. so for example if only slaves 0
-	 * and 3 are present, their GPIOs range from base to base+15
-	 * (or base+31 for s17 variant).
-	 */
-	unsigned	base;
-};
diff --git a/include/linux/sunrpc/svc_rdma.h b/include/linux/sunrpc/svc_rdma.h
index 78fe2ac6dc6c..cbcfbd0521e3 100644
--- a/include/linux/sunrpc/svc_rdma.h
+++ b/include/linux/sunrpc/svc_rdma.h
@@ -170,6 +170,7 @@ extern bool svc_rdma_post_recvs(struct svcxprt_rdma *rdma);
 extern void svc_rdma_recv_ctxt_put(struct svcxprt_rdma *rdma,
 				   struct svc_rdma_recv_ctxt *ctxt);
 extern void svc_rdma_flush_recv_queues(struct svcxprt_rdma *rdma);
+extern void svc_rdma_release_rqst(struct svc_rqst *rqstp);
 extern int svc_rdma_recvfrom(struct svc_rqst *);
 
 /* svc_rdma_rw.c */
diff --git a/include/linux/swap.h b/include/linux/swap.h
index b835d8dbea0e..e1bbf7a16b27 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -275,7 +275,7 @@ struct swap_info_struct {
 					 */
 	struct work_struct discard_work; /* discard worker */
 	struct swap_cluster_list discard_clusters; /* discard clusters list */
-	struct plist_node avail_lists[0]; /*
+	struct plist_node avail_lists[]; /*
 					   * entries in swap_avail_heads, one
 					   * entry per node.
 					   * Must be last as the number of the
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 1815065d52f3..f5ada20e2943 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -876,6 +876,9 @@ asmlinkage long sys_munlockall(void);
 asmlinkage long sys_mincore(unsigned long start, size_t len,
 				unsigned char __user * vec);
 asmlinkage long sys_madvise(unsigned long start, size_t len, int behavior);
+
+asmlinkage long sys_process_madvise(int which, pid_t pid, unsigned long start,
+			size_t len, int behavior, unsigned long flags);
 asmlinkage long sys_remap_file_pages(unsigned long start, unsigned long size,
 			unsigned long prot, unsigned long pgoff,
 			unsigned long flags);
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index c91b1e344d56..216185bb3014 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -32,20 +32,10 @@
 /* use value, which < 0K, to indicate an invalid/uninitialized temperature */
 #define THERMAL_TEMP_INVALID	-274000
 
-/* Default Thermal Governor */
-#if defined(CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE)
-#define DEFAULT_THERMAL_GOVERNOR       "step_wise"
-#elif defined(CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE)
-#define DEFAULT_THERMAL_GOVERNOR       "fair_share"
-#elif defined(CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE)
-#define DEFAULT_THERMAL_GOVERNOR       "user_space"
-#elif defined(CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR)
-#define DEFAULT_THERMAL_GOVERNOR       "power_allocator"
-#endif
-
 struct thermal_zone_device;
 struct thermal_cooling_device;
 struct thermal_instance;
+struct thermal_attr;
 
 enum thermal_device_mode {
 	THERMAL_DEVICE_DISABLED = 0,
@@ -130,11 +120,6 @@ struct thermal_cooling_device {
 	struct list_head node;
 };
 
-struct thermal_attr {
-	struct device_attribute attr;
-	char name[THERMAL_NAME_LENGTH];
-};
-
 /**
  * struct thermal_zone_device - structure for a thermal zone
  * @id:		unique id number for each thermal zone
@@ -347,21 +332,6 @@ struct thermal_zone_of_device_ops {
 	int (*set_trip_temp)(void *, int, int);
 };
 
-/**
- * struct thermal_trip - representation of a point in temperature domain
- * @np: pointer to struct device_node that this trip point was created from
- * @temperature: temperature value in miliCelsius
- * @hysteresis: relative hysteresis in miliCelsius
- * @type: trip point type
- */
-
-struct thermal_trip {
-	struct device_node *np;
-	int temperature;
-	int hysteresis;
-	enum thermal_trip_type type;
-};
-
 /* Function declarations */
 #ifdef CONFIG_THERMAL_OF
 int thermal_zone_of_get_sensor_id(struct device_node *tz_np,
@@ -413,19 +383,7 @@ void devm_thermal_zone_of_sensor_unregister(struct device *dev,
 
 #endif
 
-#if IS_ENABLED(CONFIG_THERMAL)
-static inline bool cdev_is_power_actor(struct thermal_cooling_device *cdev)
-{
-	return cdev->ops->get_requested_power && cdev->ops->state2power &&
-		cdev->ops->power2state;
-}
-
-int power_actor_get_max_power(struct thermal_cooling_device *,
-			      struct thermal_zone_device *tz, u32 *max_power);
-int power_actor_get_min_power(struct thermal_cooling_device *,
-			      struct thermal_zone_device *tz, u32 *min_power);
-int power_actor_set_power(struct thermal_cooling_device *,
-			  struct thermal_instance *, u32);
+#ifdef CONFIG_THERMAL
 struct thermal_zone_device *thermal_zone_device_register(const char *, int, int,
 		void *, struct thermal_zone_device_ops *,
 		struct thermal_zone_params *, int, int);
@@ -439,7 +397,6 @@ int thermal_zone_unbind_cooling_device(struct thermal_zone_device *, int,
 				       struct thermal_cooling_device *);
 void thermal_zone_device_update(struct thermal_zone_device *,
 				enum thermal_notify_event);
-void thermal_zone_set_trips(struct thermal_zone_device *);
 
 struct thermal_cooling_device *thermal_cooling_device_register(const char *,
 		void *, const struct thermal_cooling_device_ops *);
@@ -457,24 +414,9 @@ int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp);
 int thermal_zone_get_slope(struct thermal_zone_device *tz);
 int thermal_zone_get_offset(struct thermal_zone_device *tz);
 
-int get_tz_trend(struct thermal_zone_device *, int);
-struct thermal_instance *get_thermal_instance(struct thermal_zone_device *,
-		struct thermal_cooling_device *, int);
 void thermal_cdev_update(struct thermal_cooling_device *);
 void thermal_notify_framework(struct thermal_zone_device *, int);
 #else
-static inline bool cdev_is_power_actor(struct thermal_cooling_device *cdev)
-{ return false; }
-static inline int power_actor_get_max_power(struct thermal_cooling_device *cdev,
-			      struct thermal_zone_device *tz, u32 *max_power)
-{ return 0; }
-static inline int power_actor_get_min_power(struct thermal_cooling_device *cdev,
-					    struct thermal_zone_device *tz,
-					    u32 *min_power)
-{ return -ENODEV; }
-static inline int power_actor_set_power(struct thermal_cooling_device *cdev,
-			  struct thermal_instance *tz, u32 power)
-{ return 0; }
 static inline struct thermal_zone_device *thermal_zone_device_register(
 	const char *type, int trips, int mask, void *devdata,
 	struct thermal_zone_device_ops *ops,
@@ -484,21 +426,6 @@ static inline struct thermal_zone_device *thermal_zone_device_register(
 static inline void thermal_zone_device_unregister(
 	struct thermal_zone_device *tz)
 { }
-static inline int thermal_zone_bind_cooling_device(
-	struct thermal_zone_device *tz, int trip,
-	struct thermal_cooling_device *cdev,
-	unsigned long upper, unsigned long lower,
-	unsigned int weight)
-{ return -ENODEV; }
-static inline int thermal_zone_unbind_cooling_device(
-	struct thermal_zone_device *tz, int trip,
-	struct thermal_cooling_device *cdev)
-{ return -ENODEV; }
-static inline void thermal_zone_device_update(struct thermal_zone_device *tz,
-					      enum thermal_notify_event event)
-{ }
-static inline void thermal_zone_set_trips(struct thermal_zone_device *tz)
-{ }
 static inline struct thermal_cooling_device *
 thermal_cooling_device_register(char *type, void *devdata,
 	const struct thermal_cooling_device_ops *ops)
@@ -530,12 +457,7 @@ static inline int thermal_zone_get_slope(
 static inline int thermal_zone_get_offset(
 		struct thermal_zone_device *tz)
 { return -ENODEV; }
-static inline int get_tz_trend(struct thermal_zone_device *tz, int trip)
-{ return -ENODEV; }
-static inline struct thermal_instance *
-get_thermal_instance(struct thermal_zone_device *tz,
-	struct thermal_cooling_device *cdev, int trip)
-{ return ERR_PTR(-ENODEV); }
+
 static inline void thermal_cdev_update(struct thermal_cooling_device *cdev)
 { }
 static inline void thermal_notify_framework(struct thermal_zone_device *tz,
diff --git a/include/linux/ti_wilink_st.h b/include/linux/ti_wilink_st.h
index eb6cbdf10e50..44a7f9169ac6 100644
--- a/include/linux/ti_wilink_st.h
+++ b/include/linux/ti_wilink_st.h
@@ -295,7 +295,7 @@ struct bts_header {
 	u32 magic;
 	u32 version;
 	u8 future[24];
-	u8 actions[0];
+	u8 actions[];
 } __attribute__ ((packed));
 
 /**
@@ -305,7 +305,7 @@ struct bts_header {
 struct bts_action {
 	u16 type;
 	u16 size;
-	u8 data[0];
+	u8 data[];
 } __attribute__ ((packed));
 
 struct bts_action_send {
@@ -315,7 +315,7 @@ struct bts_action_send {
 struct bts_action_wait {
 	u32 msec;
 	u32 size;
-	u8 data[0];
+	u8 data[];
 } __attribute__ ((packed));
 
 struct bts_action_delay {
diff --git a/include/linux/torture.h b/include/linux/torture.h
index 6241f59e2d6f..629b66e6c161 100644
--- a/include/linux/torture.h
+++ b/include/linux/torture.h
@@ -89,7 +89,7 @@ void _torture_stop_kthread(char *m, struct task_struct **tp);
 #ifdef CONFIG_PREEMPTION
 #define torture_preempt_schedule() preempt_schedule()
 #else
-#define torture_preempt_schedule()
+#define torture_preempt_schedule()	do { } while (0)
 #endif
 
 #endif /* __LINUX_TORTURE_H */
diff --git a/include/linux/tpm_eventlog.h b/include/linux/tpm_eventlog.h
index 131ea1bad458..c253461b1c4e 100644
--- a/include/linux/tpm_eventlog.h
+++ b/include/linux/tpm_eventlog.h
@@ -28,7 +28,7 @@ struct tcpa_event {
 	u32 event_type;
 	u8 pcr_value[20];	/* SHA1 */
 	u32 event_size;
-	u8 event_data[0];
+	u8 event_data[];
 };
 
 enum tcpa_event_types {
@@ -55,7 +55,7 @@ enum tcpa_event_types {
 struct tcpa_pc_event {
 	u32 event_id;
 	u32 event_size;
-	u8 event_data[0];
+	u8 event_data[];
 };
 
 enum tcpa_pc_event_ids {
@@ -102,7 +102,7 @@ struct tcg_pcr_event {
 
 struct tcg_event_field {
 	u32 event_size;
-	u8 event[0];
+	u8 event[];
 } __packed;
 
 struct tcg_pcr_event2_head {
diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h
index 67f016010aad..8a215c5c1aed 100644
--- a/include/linux/uaccess.h
+++ b/include/linux/uaccess.h
@@ -2,9 +2,9 @@
 #ifndef __LINUX_UACCESS_H__
 #define __LINUX_UACCESS_H__
 
+#include <linux/instrumented.h>
 #include <linux/sched.h>
 #include <linux/thread_info.h>
-#include <linux/kasan-checks.h>
 
 #define uaccess_kernel() segment_eq(get_fs(), KERNEL_DS)
 
@@ -58,7 +58,7 @@
 static __always_inline __must_check unsigned long
 __copy_from_user_inatomic(void *to, const void __user *from, unsigned long n)
 {
-	kasan_check_write(to, n);
+	instrument_copy_from_user(to, from, n);
 	check_object_size(to, n, false);
 	return raw_copy_from_user(to, from, n);
 }
@@ -67,7 +67,7 @@ static __always_inline __must_check unsigned long
 __copy_from_user(void *to, const void __user *from, unsigned long n)
 {
 	might_fault();
-	kasan_check_write(to, n);
+	instrument_copy_from_user(to, from, n);
 	check_object_size(to, n, false);
 	return raw_copy_from_user(to, from, n);
 }
@@ -88,7 +88,7 @@ __copy_from_user(void *to, const void __user *from, unsigned long n)
 static __always_inline __must_check unsigned long
 __copy_to_user_inatomic(void __user *to, const void *from, unsigned long n)
 {
-	kasan_check_read(from, n);
+	instrument_copy_to_user(to, from, n);
 	check_object_size(from, n, true);
 	return raw_copy_to_user(to, from, n);
 }
@@ -97,7 +97,7 @@ static __always_inline __must_check unsigned long
 __copy_to_user(void __user *to, const void *from, unsigned long n)
 {
 	might_fault();
-	kasan_check_read(from, n);
+	instrument_copy_to_user(to, from, n);
 	check_object_size(from, n, true);
 	return raw_copy_to_user(to, from, n);
 }
@@ -109,7 +109,7 @@ _copy_from_user(void *to, const void __user *from, unsigned long n)
 	unsigned long res = n;
 	might_fault();
 	if (likely(access_ok(from, n))) {
-		kasan_check_write(to, n);
+		instrument_copy_from_user(to, from, n);
 		res = raw_copy_from_user(to, from, n);
 	}
 	if (unlikely(res))
@@ -127,7 +127,7 @@ _copy_to_user(void __user *to, const void *from, unsigned long n)
 {
 	might_fault();
 	if (access_ok(to, n)) {
-		kasan_check_read(from, n);
+		instrument_copy_to_user(to, from, n);
 		n = raw_copy_to_user(to, from, n);
 	}
 	return n;
diff --git a/include/linux/vdpa.h b/include/linux/vdpa.h
index 733acfb7ef84..5453af87a33e 100644
--- a/include/linux/vdpa.h
+++ b/include/linux/vdpa.h
@@ -164,7 +164,7 @@ struct vdpa_config_ops {
 	u64 (*get_vq_state)(struct vdpa_device *vdev, u16 idx);
 
 	/* Device ops */
-	u16 (*get_vq_align)(struct vdpa_device *vdev);
+	u32 (*get_vq_align)(struct vdpa_device *vdev);
 	u64 (*get_features)(struct vdpa_device *vdev);
 	int (*set_features)(struct vdpa_device *vdev, u64 features);
 	void (*set_config_cb)(struct vdpa_device *vdev,
diff --git a/include/linux/vringh.h b/include/linux/vringh.h
index bd0503ca6f8f..9e2763d7c159 100644
--- a/include/linux/vringh.h
+++ b/include/linux/vringh.h
@@ -14,8 +14,10 @@
 #include <linux/virtio_byteorder.h>
 #include <linux/uio.h>
 #include <linux/slab.h>
+#if IS_REACHABLE(CONFIG_VHOST_IOTLB)
 #include <linux/dma-direction.h>
 #include <linux/vhost_iotlb.h>
+#endif
 #include <asm/barrier.h>
 
 /* virtio_ring with information needed for host access. */
@@ -254,6 +256,8 @@ static inline __virtio64 cpu_to_vringh64(const struct vringh *vrh, u64 val)
 	return __cpu_to_virtio64(vringh_is_little_endian(vrh), val);
 }
 
+#if IS_REACHABLE(CONFIG_VHOST_IOTLB)
+
 void vringh_set_iotlb(struct vringh *vrh, struct vhost_iotlb *iotlb);
 
 int vringh_init_iotlb(struct vringh *vrh, u64 features,
@@ -284,4 +288,6 @@ void vringh_notify_disable_iotlb(struct vringh *vrh);
 
 int vringh_need_notify_iotlb(struct vringh *vrh);
 
+#endif /* CONFIG_VHOST_IOTLB */
+
 #endif /* _LINUX_VRINGH_H */
diff --git a/include/linux/wait.h b/include/linux/wait.h
index feeb6be5cad6..74935bc9757b 100644
--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -544,7 +544,7 @@ do {										\
 ({										\
 	int __ret = 0;								\
 	might_sleep();								\
-	if (!(condition))							\
+	if (!(condition) && (timeout))						\
 		__ret = __wait_event_hrtimeout(wq_head, condition, timeout,	\
 					       TASK_UNINTERRUPTIBLE);		\
 	__ret;									\
@@ -570,7 +570,7 @@ do {										\
 ({										\
 	long __ret = 0;								\
 	might_sleep();								\
-	if (!(condition))							\
+	if (!(condition) && (timeout))						\
 		__ret = __wait_event_hrtimeout(wq, condition, timeout,		\
 					       TASK_INTERRUPTIBLE);		\
 	__ret;									\
@@ -1149,4 +1149,6 @@ int autoremove_wake_function(struct wait_queue_entry *wq_entry, unsigned mode, i
 		(wait)->flags = 0;						\
 	} while (0)
 
+bool try_invoke_on_locked_down_task(struct task_struct *p, bool (*func)(struct task_struct *t, void *arg), void *arg);
+
 #endif /* _LINUX_WAIT_H */
diff --git a/include/linux/watch_queue.h b/include/linux/watch_queue.h
new file mode 100644
index 000000000000..5e08db2adc31
--- /dev/null
+++ b/include/linux/watch_queue.h
@@ -0,0 +1,127 @@
+// SPDX-License-Identifier: GPL-2.0
+/* User-mappable watch queue
+ *
+ * Copyright (C) 2020 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * See Documentation/watch_queue.rst
+ */
+
+#ifndef _LINUX_WATCH_QUEUE_H
+#define _LINUX_WATCH_QUEUE_H
+
+#include <uapi/linux/watch_queue.h>
+#include <linux/kref.h>
+#include <linux/rcupdate.h>
+
+#ifdef CONFIG_WATCH_QUEUE
+
+struct cred;
+
+struct watch_type_filter {
+	enum watch_notification_type type;
+	__u32		subtype_filter[1];	/* Bitmask of subtypes to filter on */
+	__u32		info_filter;		/* Filter on watch_notification::info */
+	__u32		info_mask;		/* Mask of relevant bits in info_filter */
+};
+
+struct watch_filter {
+	union {
+		struct rcu_head	rcu;
+		unsigned long	type_filter[2];	/* Bitmask of accepted types */
+	};
+	u32			nr_filters;	/* Number of filters */
+	struct watch_type_filter filters[];
+};
+
+struct watch_queue {
+	struct rcu_head		rcu;
+	struct watch_filter __rcu *filter;
+	struct pipe_inode_info	*pipe;		/* The pipe we're using as a buffer */
+	struct hlist_head	watches;	/* Contributory watches */
+	struct page		**notes;	/* Preallocated notifications */
+	unsigned long		*notes_bitmap;	/* Allocation bitmap for notes */
+	struct kref		usage;		/* Object usage count */
+	spinlock_t		lock;
+	unsigned int		nr_notes;	/* Number of notes */
+	unsigned int		nr_pages;	/* Number of pages in notes[] */
+	bool			defunct;	/* T when queues closed */
+};
+
+/*
+ * Representation of a watch on an object.
+ */
+struct watch {
+	union {
+		struct rcu_head	rcu;
+		u32		info_id;	/* ID to be OR'd in to info field */
+	};
+	struct watch_queue __rcu *queue;	/* Queue to post events to */
+	struct hlist_node	queue_node;	/* Link in queue->watches */
+	struct watch_list __rcu	*watch_list;
+	struct hlist_node	list_node;	/* Link in watch_list->watchers */
+	const struct cred	*cred;		/* Creds of the owner of the watch */
+	void			*private;	/* Private data for the watched object */
+	u64			id;		/* Internal identifier */
+	struct kref		usage;		/* Object usage count */
+};
+
+/*
+ * List of watches on an object.
+ */
+struct watch_list {
+	struct rcu_head		rcu;
+	struct hlist_head	watchers;
+	void (*release_watch)(struct watch *);
+	spinlock_t		lock;
+};
+
+extern void __post_watch_notification(struct watch_list *,
+				      struct watch_notification *,
+				      const struct cred *,
+				      u64);
+extern struct watch_queue *get_watch_queue(int);
+extern void put_watch_queue(struct watch_queue *);
+extern void init_watch(struct watch *, struct watch_queue *);
+extern int add_watch_to_object(struct watch *, struct watch_list *);
+extern int remove_watch_from_object(struct watch_list *, struct watch_queue *, u64, bool);
+extern long watch_queue_set_size(struct pipe_inode_info *, unsigned int);
+extern long watch_queue_set_filter(struct pipe_inode_info *,
+				   struct watch_notification_filter __user *);
+extern int watch_queue_init(struct pipe_inode_info *);
+extern void watch_queue_clear(struct watch_queue *);
+
+static inline void init_watch_list(struct watch_list *wlist,
+				   void (*release_watch)(struct watch *))
+{
+	INIT_HLIST_HEAD(&wlist->watchers);
+	spin_lock_init(&wlist->lock);
+	wlist->release_watch = release_watch;
+}
+
+static inline void post_watch_notification(struct watch_list *wlist,
+					   struct watch_notification *n,
+					   const struct cred *cred,
+					   u64 id)
+{
+	if (unlikely(wlist))
+		__post_watch_notification(wlist, n, cred, id);
+}
+
+static inline void remove_watch_list(struct watch_list *wlist, u64 id)
+{
+	if (wlist) {
+		remove_watch_from_object(wlist, NULL, id, true);
+		kfree_rcu(wlist, rcu);
+	}
+}
+
+/**
+ * watch_sizeof - Calculate the information part of the size of a watch record,
+ * given the structure size.
+ */
+#define watch_sizeof(STRUCT) (sizeof(STRUCT) << WATCH_INFO_LENGTH__SHIFT)
+
+#endif
+
+#endif /* _LINUX_WATCH_QUEUE_H */
diff --git a/include/linux/xarray.h b/include/linux/xarray.h
index 14c893433139..3b213c6d17fb 100644
--- a/include/linux/xarray.h
+++ b/include/linux/xarray.h
@@ -1491,6 +1491,7 @@ static inline bool xas_retry(struct xa_state *xas, const void *entry)
 
 void *xas_load(struct xa_state *);
 void *xas_store(struct xa_state *, void *entry);
+void *__xas_store(struct xa_state *, void *entry);
 void *xas_find(struct xa_state *, unsigned long max);
 void *xas_find_conflict(struct xa_state *);
 
@@ -1663,7 +1664,10 @@ static inline void *xas_next_marked(struct xa_state *xas, unsigned long max,
 	entry = xa_entry(xas->xa, node, offset);
 	if (!entry)
 		return xas_find_marked(xas, max, mark);
-	return entry;
+	if (!xa_is_retry(entry))
+		return entry;
+	xas_reset(xas);
+	return xas_find_marked(xas, max, mark);
 }
 
 /*
@@ -1786,4 +1790,21 @@ static inline void *xas_next(struct xa_state *xas)
 	return xa_entry(xas->xa, node, xas->xa_offset);
 }
 
+/**
+ * xas_for_each_contig() - Iterate over contiguous entries in an XArray.
+ * @xas: XArray operation state.
+ * @entry: Entry retrieved from the array.
+ * @max: Maximum index to retrieve from array.
+ *
+ * The loop body will be executed for each contiguous entry in the array
+ * between the current xas position and @max, inclusive.  @entry will
+ * be set to the entry retrieved from the XArray.  It is safe to delete
+ * entries from the array in the loop body.  You should hold either the
+ * RCU lock or the xa_lock while iterating.  If you need to drop the lock,
+ * call xas_pause() first.
+ */
+#define xas_for_each_contig(xas, entry, max) \
+	for (entry = xas.xa_index <= max ? xas_load(xas) : NULL; entry; \
+	     entry = xas.xa_index <= max ? xas_next(xas) : NULL)
+
 #endif /* _LINUX_XARRAY_H */
diff --git a/include/linux/xattr.h b/include/linux/xattr.h
index 4cf6e11f4a3c..47eaa34f8761 100644
--- a/include/linux/xattr.h
+++ b/include/linux/xattr.h
@@ -73,7 +73,7 @@ struct simple_xattr {
 	struct list_head list;
 	char *name;
 	size_t size;
-	char value[0];
+	char value[];
 };
 
 /*
diff --git a/include/media/v4l2-jpeg.h b/include/media/v4l2-jpeg.h
new file mode 100644
index 000000000000..ddba2a56c321
--- /dev/null
+++ b/include/media/v4l2-jpeg.h
@@ -0,0 +1,135 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * V4L2 JPEG helpers header
+ *
+ * Copyright (C) 2019 Pengutronix, Philipp Zabel <kernel@pengutronix.de>
+ *
+ * For reference, see JPEG ITU-T.81 (ISO/IEC 10918-1)
+ */
+
+#ifndef _V4L2_JPEG_H
+#define _V4L2_JPEG_H
+
+#include <linux/v4l2-controls.h>
+
+#define V4L2_JPEG_MAX_COMPONENTS	4
+#define V4L2_JPEG_MAX_TABLES		4
+
+/**
+ * struct v4l2_jpeg_reference - reference into the JPEG buffer
+ * @start: pointer to the start of the referenced segment or table
+ * @length: size of the referenced segment or table
+ *
+ * Wnen referencing marker segments, start points right after the marker code,
+ * and length is the size of the segment parameters, excluding the marker code.
+ */
+struct v4l2_jpeg_reference {
+	u8 *start;
+	size_t length;
+};
+
+/* B.2.2 Frame header syntax */
+
+/**
+ * struct v4l2_jpeg_frame_component_spec - frame component-specification
+ * @component_identifier: C[i]
+ * @horizontal_sampling_factor: H[i]
+ * @vertical_sampling_factor: V[i]
+ * @quantization_table_selector: quantization table destination selector Tq[i]
+ */
+struct v4l2_jpeg_frame_component_spec {
+	u8 component_identifier;
+	u8 horizontal_sampling_factor;
+	u8 vertical_sampling_factor;
+	u8 quantization_table_selector;
+};
+
+/**
+ * struct v4l2_jpeg_frame_header - JPEG frame header
+ * @height: Y
+ * @width: X
+ * @precision: P
+ * @num_components: Nf
+ * @component: component-specification, see v4l2_jpeg_frame_component_spec
+ * @subsampling: decoded subsampling from component-specification
+ */
+struct v4l2_jpeg_frame_header {
+	u16 height;
+	u16 width;
+	u8 precision;
+	u8 num_components;
+	struct v4l2_jpeg_frame_component_spec component[V4L2_JPEG_MAX_COMPONENTS];
+	enum v4l2_jpeg_chroma_subsampling subsampling;
+};
+
+/* B.2.3 Scan header syntax */
+
+/**
+ * struct v4l2_jpeg_scan_component_spec - scan component-specification
+ * @component_selector: Cs[j]
+ * @dc_entropy_coding_table_selector: Td[j]
+ * @ac_entropy_coding_table_selector: Ta[j]
+ */
+struct v4l2_jpeg_scan_component_spec {
+	u8 component_selector;
+	u8 dc_entropy_coding_table_selector;
+	u8 ac_entropy_coding_table_selector;
+};
+
+/**
+ * struct v4l2_jpeg_scan_header - JPEG scan header
+ * @num_components: Ns
+ * @component: component-specification, see v4l2_jpeg_scan_component_spec
+ */
+struct v4l2_jpeg_scan_header {
+	u8 num_components;				/* Ns */
+	struct v4l2_jpeg_scan_component_spec component[V4L2_JPEG_MAX_COMPONENTS];
+	/* Ss, Se, Ah, and Al are not used by any driver */
+};
+
+/**
+ * struct v4l2_jpeg_header - parsed JPEG header
+ * @sof: pointer to frame header and size
+ * @sos: pointer to scan header and size
+ * @dht: pointers to huffman tables and sizes
+ * @dqt: pointers to quantization tables and sizes
+ * @frame: parsed frame header
+ * @scan: pointer to parsed scan header, optional
+ * @quantization_tables: references to four quantization tables, optional
+ * @huffman_tables: references to four Huffman tables in DC0, DC1, AC0, AC1
+ *                  order, optional
+ * @restart_interval: number of MCU per restart interval, Ri
+ * @ecs_offset: buffer offset in bytes to the entropy coded segment
+ *
+ * When this structure is passed to v4l2_jpeg_parse_header, the optional scan,
+ * quantization_tables, and huffman_tables pointers must be initialized to NULL
+ * or point at valid memory.
+ */
+struct v4l2_jpeg_header {
+	struct v4l2_jpeg_reference sof;
+	struct v4l2_jpeg_reference sos;
+	unsigned int num_dht;
+	struct v4l2_jpeg_reference dht[V4L2_JPEG_MAX_TABLES];
+	unsigned int num_dqt;
+	struct v4l2_jpeg_reference dqt[V4L2_JPEG_MAX_TABLES];
+
+	struct v4l2_jpeg_frame_header frame;
+	struct v4l2_jpeg_scan_header *scan;
+	struct v4l2_jpeg_reference *quantization_tables;
+	struct v4l2_jpeg_reference *huffman_tables;
+	u16 restart_interval;
+	size_t ecs_offset;
+};
+
+int v4l2_jpeg_parse_header(void *buf, size_t len, struct v4l2_jpeg_header *out);
+
+int v4l2_jpeg_parse_frame_header(void *buf, size_t len,
+				 struct v4l2_jpeg_frame_header *frame_header);
+int v4l2_jpeg_parse_scan_header(void *buf, size_t len,
+				struct v4l2_jpeg_scan_header *scan_header);
+int v4l2_jpeg_parse_quantization_tables(void *buf, size_t len, u8 precision,
+					struct v4l2_jpeg_reference *q_tables);
+int v4l2_jpeg_parse_huffman_tables(void *buf, size_t len,
+				   struct v4l2_jpeg_reference *huffman_tables);
+
+#endif
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 1576353a2773..3fa7b1e3c5d9 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -139,6 +139,14 @@ struct bt_voice {
 #define BT_PHY_LE_CODED_TX	0x00002000
 #define BT_PHY_LE_CODED_RX	0x00004000
 
+#define BT_MODE			15
+
+#define BT_MODE_BASIC		0x00
+#define BT_MODE_ERTM		0x01
+#define BT_MODE_STREAMING	0x02
+#define BT_MODE_LE_FLOWCTL	0x03
+#define BT_MODE_EXT_FLOWCTL	0x04
+
 __printf(1, 2)
 void bt_info(const char *fmt, ...);
 __printf(1, 2)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 5f60e135aeb6..1da8cec8e210 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -53,6 +53,9 @@
 #define HCI_NOTIFY_CONN_ADD		1
 #define HCI_NOTIFY_CONN_DEL		2
 #define HCI_NOTIFY_VOICE_SETTING	3
+#define HCI_NOTIFY_ENABLE_SCO_CVSD	4
+#define HCI_NOTIFY_ENABLE_SCO_TRANSP	5
+#define HCI_NOTIFY_DISABLE_SCO		6
 
 /* HCI bus types */
 #define HCI_VIRTUAL	0
@@ -65,6 +68,7 @@
 #define HCI_SPI		7
 #define HCI_I2C		8
 #define HCI_SMD		9
+#define HCI_VIRTIO	10
 
 /* HCI controller types */
 #define HCI_PRIMARY	0x00
@@ -294,6 +298,7 @@ enum {
 	HCI_FORCE_STATIC_ADDR,
 	HCI_LL_RPA_RESOLUTION,
 	HCI_CMD_PENDING,
+	HCI_FORCE_NO_MITM,
 
 	__HCI_NUM_FLAGS,
 };
@@ -455,12 +460,11 @@ enum {
 #define HCI_LE_SLAVE_FEATURES		0x08
 #define HCI_LE_PING			0x10
 #define HCI_LE_DATA_LEN_EXT		0x20
-#define HCI_LE_PHY_2M			0x01
-#define HCI_LE_PHY_CODED		0x08
-#define HCI_LE_EXT_ADV			0x10
+#define HCI_LE_LL_PRIVACY		0x40
 #define HCI_LE_EXT_SCAN_POLICY		0x80
 #define HCI_LE_PHY_2M			0x01
 #define HCI_LE_PHY_CODED		0x08
+#define HCI_LE_EXT_ADV			0x10
 #define HCI_LE_CHAN_SEL_ALG2		0x40
 #define HCI_LE_CIS_MASTER		0x10
 #define HCI_LE_CIS_SLAVE		0x20
@@ -1272,6 +1276,13 @@ struct hci_rp_read_data_block_size {
 
 #define HCI_OP_READ_LOCAL_CODECS	0x100b
 
+#define HCI_OP_READ_LOCAL_PAIRING_OPTS	0x100c
+struct hci_rp_read_local_pairing_opts {
+	__u8     status;
+	__u8     pairing_opts;
+	__u8     max_key_size;
+} __packed;
+
 #define HCI_OP_READ_PAGE_SCAN_ACTIVITY	0x0c1b
 struct hci_rp_read_page_scan_activity {
 	__u8     status;
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index d4e28773d378..239ab72f16c6 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -312,6 +312,8 @@ struct hci_dev {
 	__u16		conn_info_max_age;
 	__u16		auth_payload_timeout;
 	__u8		min_enc_key_size;
+	__u8		max_enc_key_size;
+	__u8		pairing_opts;
 	__u8		ssp_debug_mode;
 	__u8		hw_error_code;
 	__u32		clock;
@@ -484,6 +486,11 @@ struct hci_dev {
 	struct led_trigger	*power_led;
 #endif
 
+#if IS_ENABLED(CONFIG_BT_MSFTEXT)
+	__u16			msft_opcode;
+	void			*msft_data;
+#endif
+
 	int (*open)(struct hci_dev *hdev);
 	int (*close)(struct hci_dev *hdev);
 	int (*flush)(struct hci_dev *hdev);
@@ -638,6 +645,7 @@ extern struct mutex hci_cb_list_lock;
 	do {							\
 		hci_dev_clear_flag(hdev, HCI_LE_SCAN);		\
 		hci_dev_clear_flag(hdev, HCI_LE_ADV);		\
+		hci_dev_clear_flag(hdev, HCI_LL_RPA_RESOLUTION);\
 		hci_dev_clear_flag(hdev, HCI_PERIODIC_INQ);	\
 	} while (0)
 
@@ -1116,6 +1124,14 @@ int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb);
 int hci_recv_diag(struct hci_dev *hdev, struct sk_buff *skb);
 __printf(2, 3) void hci_set_hw_info(struct hci_dev *hdev, const char *fmt, ...);
 __printf(2, 3) void hci_set_fw_info(struct hci_dev *hdev, const char *fmt, ...);
+
+static inline void hci_set_msft_opcode(struct hci_dev *hdev, __u16 opcode)
+{
+#if IS_ENABLED(CONFIG_BT_MSFTEXT)
+	hdev->msft_opcode = opcode;
+#endif
+}
+
 int hci_dev_open(__u16 dev);
 int hci_dev_close(__u16 dev);
 int hci_dev_do_close(struct hci_dev *hdev);
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index f41cd87550dc..65dd6fd1fff3 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -674,6 +674,13 @@ struct mgmt_cp_set_blocked_keys {
 
 #define MGMT_OP_SET_WIDEBAND_SPEECH	0x0047
 
+#define MGMT_OP_READ_SECURITY_INFO	0x0048
+#define MGMT_READ_SECURITY_INFO_SIZE	0
+struct mgmt_rp_read_security_info {
+	__le16   sec_len;
+	__u8     sec[0];
+} __packed;
+
 #define MGMT_EV_CMD_COMPLETE		0x0001
 struct mgmt_ev_cmd_complete {
 	__le16	opcode;
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index c78bd4ff9e33..70e48f66dac8 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -905,6 +905,8 @@ struct survey_info {
  *	protocol frames.
  * @control_port_over_nl80211: TRUE if userspace expects to exchange control
  *	port frames over NL80211 instead of the network interface.
+ * @control_port_no_preauth: disables pre-auth rx over the nl80211 control
+ *	port for mac80211
  * @wep_keys: static WEP keys, if not NULL points to an array of
  *	CFG80211_MAX_WEP_KEYS WEP keys
  * @wep_tx_key: key index (0..3) of the default TX static WEP key
@@ -1222,6 +1224,7 @@ struct sta_txpwr {
  * @he_capa: HE capabilities of station
  * @he_capa_len: the length of the HE capabilities
  * @airtime_weight: airtime scheduler weight for this station
+ * @txpwr: transmit power for an associated station
  */
 struct station_parameters {
 	const u8 *supported_rates;
@@ -4666,6 +4669,9 @@ struct wiphy_iftype_akm_suites {
  * @txq_memory_limit: configuration internal TX queue memory limit
  * @txq_quantum: configuration of internal TX queue scheduler quantum
  *
+ * @tx_queue_len: allow setting transmit queue len for drivers not using
+ *	wake_tx_queue
+ *
  * @support_mbssid: can HW support association with nontransmitted AP
  * @support_only_he_mbssid: don't parse MBSSID elements if it is not
  *	HE AP, in order to avoid compatibility issues.
@@ -4681,6 +4687,10 @@ struct wiphy_iftype_akm_suites {
  *	supported by the driver for each peer
  * @tid_config_support.max_retry: maximum supported retry count for
  *	long/short retry configuration
+ *
+ * @max_data_retry_count: maximum supported per TID retry count for
+ *	configuration through the %NL80211_TID_CONFIG_ATTR_RETRY_SHORT and
+ *	%NL80211_TID_CONFIG_ATTR_RETRY_LONG attributes
  */
 struct wiphy {
 	/* assign these fields before you register the wiphy */
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index f7543c095b33..9947eb1e9eb6 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -254,6 +254,7 @@ static inline bool ipv6_anycast_destination(const struct dst_entry *dst,
 
 	return rt->rt6i_flags & RTF_ANYCAST ||
 		(rt->rt6i_dst.plen < 127 &&
+		 !(rt->rt6i_flags & (RTF_GATEWAY | RTF_NONEXTHOP)) &&
 		 ipv6_addr_equal(&rt->rt6i_dst.addr, daddr));
 }
 
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index 6eb627b3c99b..4ff7c81e6717 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -901,7 +901,7 @@ static inline void nft_set_elem_update_expr(const struct nft_set_ext *ext,
 {
 	struct nft_expr *expr;
 
-	if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPR)) {
+	if (__nft_set_ext_exists(ext, NFT_SET_EXT_EXPR)) {
 		expr = nft_set_ext_expr(ext);
 		expr->ops->eval(expr, regs, pkt);
 	}
diff --git a/include/net/sock.h b/include/net/sock.h
index 6d84784d33fa..3e8c6d4b4b59 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -2553,9 +2553,9 @@ sk_is_refcounted(struct sock *sk)
 }
 
 /**
- * skb_steal_sock
- * @skb to steal the socket from
- * @refcounted is set to true if the socket is reference-counted
+ * skb_steal_sock - steal a socket from an sk_buff
+ * @skb: sk_buff to steal the socket from
+ * @refcounted: is set to true if the socket is reference-counted
  */
 static inline struct sock *
 skb_steal_sock(struct sk_buff *skb, bool *refcounted)
diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h
index ebffcb36a7e3..6d6a3947c8b7 100644
--- a/include/soc/mscc/ocelot.h
+++ b/include/soc/mscc/ocelot.h
@@ -476,6 +476,8 @@ struct ocelot_port {
 
 	void __iomem			*regs;
 
+	bool				vlan_aware;
+
 	/* Ingress default VLAN (pvid) */
 	u16				pvid;
 
@@ -610,7 +612,7 @@ int ocelot_port_bridge_leave(struct ocelot *ocelot, int port,
 int ocelot_fdb_dump(struct ocelot *ocelot, int port,
 		    dsa_fdb_dump_cb_t *cb, void *data);
 int ocelot_fdb_add(struct ocelot *ocelot, int port,
-		   const unsigned char *addr, u16 vid, bool vlan_aware);
+		   const unsigned char *addr, u16 vid);
 int ocelot_fdb_del(struct ocelot *ocelot, int port,
 		   const unsigned char *addr, u16 vid);
 int ocelot_vlan_add(struct ocelot *ocelot, int port, u16 vid, bool pvid,
diff --git a/include/soc/qcom/cmd-db.h b/include/soc/qcom/cmd-db.h
index af9722223925..c8bb56e6852a 100644
--- a/include/soc/qcom/cmd-db.h
+++ b/include/soc/qcom/cmd-db.h
@@ -4,6 +4,7 @@
 #ifndef __QCOM_COMMAND_DB_H__
 #define __QCOM_COMMAND_DB_H__
 
+#include <linux/err.h>
 
 enum cmd_db_hw_type {
 	CMD_DB_HW_INVALID = 0,
diff --git a/include/sound/hda_codec.h b/include/sound/hda_codec.h
index 3ee8036f5436..225154a4f2ed 100644
--- a/include/sound/hda_codec.h
+++ b/include/sound/hda_codec.h
@@ -494,6 +494,11 @@ void snd_hda_update_power_acct(struct hda_codec *codec);
 static inline void snd_hda_set_power_save(struct hda_bus *bus, int delay) {}
 #endif
 
+static inline bool hda_codec_need_resume(struct hda_codec *codec)
+{
+	return !codec->relaxed_resume && codec->jacktbl.used;
+}
+
 #ifdef CONFIG_SND_HDA_PATCH_LOADER
 /*
  * patch firmware
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 13458e4fbb13..946f88a6c63d 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -790,6 +790,9 @@ struct snd_soc_dai_link {
 	const struct snd_soc_pcm_stream *params;
 	unsigned int num_params;
 
+	struct snd_soc_dapm_widget *playback_widget;
+	struct snd_soc_dapm_widget *capture_widget;
+
 	unsigned int dai_fmt;           /* format to set on init */
 
 	enum snd_soc_dpcm_trigger trigger[2]; /* trigger type for DPCM */
diff --git a/include/trace/events/f2fs.h b/include/trace/events/f2fs.h
index d97adfc327f0..417a486f5c8a 100644
--- a/include/trace/events/f2fs.h
+++ b/include/trace/events/f2fs.h
@@ -1812,6 +1812,77 @@ DEFINE_EVENT(f2fs_zip_end, f2fs_decompress_pages_end,
 	TP_ARGS(inode, cluster_idx, compressed_size, ret)
 );
 
+TRACE_EVENT(f2fs_iostat,
+
+	TP_PROTO(struct f2fs_sb_info *sbi, unsigned long long *iostat),
+
+	TP_ARGS(sbi, iostat),
+
+	TP_STRUCT__entry(
+		__field(dev_t,	dev)
+		__field(unsigned long long,	app_dio)
+		__field(unsigned long long,	app_bio)
+		__field(unsigned long long,	app_wio)
+		__field(unsigned long long,	app_mio)
+		__field(unsigned long long,	fs_dio)
+		__field(unsigned long long,	fs_nio)
+		__field(unsigned long long,	fs_mio)
+		__field(unsigned long long,	fs_gc_dio)
+		__field(unsigned long long,	fs_gc_nio)
+		__field(unsigned long long,	fs_cp_dio)
+		__field(unsigned long long,	fs_cp_nio)
+		__field(unsigned long long,	fs_cp_mio)
+		__field(unsigned long long,	app_drio)
+		__field(unsigned long long,	app_brio)
+		__field(unsigned long long,	app_rio)
+		__field(unsigned long long,	app_mrio)
+		__field(unsigned long long,	fs_drio)
+		__field(unsigned long long,	fs_nrio)
+		__field(unsigned long long,	fs_mrio)
+		__field(unsigned long long,	fs_discard)
+	),
+
+	TP_fast_assign(
+		__entry->dev		= sbi->sb->s_dev;
+		__entry->app_dio	= iostat[APP_DIRECT_IO];
+		__entry->app_bio	= iostat[APP_BUFFERED_IO];
+		__entry->app_wio	= iostat[APP_WRITE_IO];
+		__entry->app_mio	= iostat[APP_MAPPED_IO];
+		__entry->fs_dio		= iostat[FS_DATA_IO];
+		__entry->fs_nio		= iostat[FS_NODE_IO];
+		__entry->fs_mio		= iostat[FS_META_IO];
+		__entry->fs_gc_dio	= iostat[FS_GC_DATA_IO];
+		__entry->fs_gc_nio	= iostat[FS_GC_NODE_IO];
+		__entry->fs_cp_dio	= iostat[FS_CP_DATA_IO];
+		__entry->fs_cp_nio	= iostat[FS_CP_NODE_IO];
+		__entry->fs_cp_mio	= iostat[FS_CP_META_IO];
+		__entry->app_drio	= iostat[APP_DIRECT_READ_IO];
+		__entry->app_brio	= iostat[APP_BUFFERED_READ_IO];
+		__entry->app_rio	= iostat[APP_READ_IO];
+		__entry->app_mrio	= iostat[APP_MAPPED_READ_IO];
+		__entry->fs_drio	= iostat[FS_DATA_READ_IO];
+		__entry->fs_nrio	= iostat[FS_NODE_READ_IO];
+		__entry->fs_mrio	= iostat[FS_META_READ_IO];
+		__entry->fs_discard	= iostat[FS_DISCARD];
+	),
+
+	TP_printk("dev = (%d,%d), "
+		"app [write=%llu (direct=%llu, buffered=%llu), mapped=%llu], "
+		"fs [data=%llu, node=%llu, meta=%llu, discard=%llu], "
+		"gc [data=%llu, node=%llu], "
+		"cp [data=%llu, node=%llu, meta=%llu], "
+		"app [read=%llu (direct=%llu, buffered=%llu), mapped=%llu], "
+		"fs [data=%llu, node=%llu, meta=%llu]",
+		show_dev(__entry->dev), __entry->app_wio, __entry->app_dio,
+		__entry->app_bio, __entry->app_mio, __entry->fs_dio,
+		__entry->fs_nio, __entry->fs_mio, __entry->fs_discard,
+		__entry->fs_gc_dio, __entry->fs_gc_nio, __entry->fs_cp_dio,
+		__entry->fs_cp_nio, __entry->fs_cp_mio,
+		__entry->app_rio, __entry->app_drio, __entry->app_brio,
+		__entry->app_mrio, __entry->fs_drio, __entry->fs_nrio,
+		__entry->fs_mrio)
+);
+
 #endif /* _TRACE_F2FS_H */
 
  /* This part must be outside protection */
diff --git a/include/trace/events/rpcrdma.h b/include/trace/events/rpcrdma.h
index 051f26fedc4d..596e0a803477 100644
--- a/include/trace/events/rpcrdma.h
+++ b/include/trace/events/rpcrdma.h
@@ -1695,17 +1695,15 @@ DECLARE_EVENT_CLASS(svcrdma_sendcomp_event,
 
 TRACE_EVENT(svcrdma_post_send,
 	TP_PROTO(
-		const struct ib_send_wr *wr,
-		int status
+		const struct ib_send_wr *wr
 	),
 
-	TP_ARGS(wr, status),
+	TP_ARGS(wr),
 
 	TP_STRUCT__entry(
 		__field(const void *, cqe)
 		__field(unsigned int, num_sge)
 		__field(u32, inv_rkey)
-		__field(int, status)
 	),
 
 	TP_fast_assign(
@@ -1713,12 +1711,11 @@ TRACE_EVENT(svcrdma_post_send,
 		__entry->num_sge = wr->num_sge;
 		__entry->inv_rkey = (wr->opcode == IB_WR_SEND_WITH_INV) ?
 					wr->ex.invalidate_rkey : 0;
-		__entry->status = status;
 	),
 
-	TP_printk("cqe=%p num_sge=%u inv_rkey=0x%08x status=%d",
+	TP_printk("cqe=%p num_sge=%u inv_rkey=0x%08x",
 		__entry->cqe, __entry->num_sge,
-		__entry->inv_rkey, __entry->status
+		__entry->inv_rkey
 	)
 );
 
@@ -1783,26 +1780,23 @@ TRACE_EVENT(svcrdma_wc_receive,
 TRACE_EVENT(svcrdma_post_rw,
 	TP_PROTO(
 		const void *cqe,
-		int sqecount,
-		int status
+		int sqecount
 	),
 
-	TP_ARGS(cqe, sqecount, status),
+	TP_ARGS(cqe, sqecount),
 
 	TP_STRUCT__entry(
 		__field(const void *, cqe)
 		__field(int, sqecount)
-		__field(int, status)
 	),
 
 	TP_fast_assign(
 		__entry->cqe = cqe;
 		__entry->sqecount = sqecount;
-		__entry->status = status;
 	),
 
-	TP_printk("cqe=%p sqecount=%d status=%d",
-		__entry->cqe, __entry->sqecount, __entry->status
+	TP_printk("cqe=%p sqecount=%d",
+		__entry->cqe, __entry->sqecount
 	)
 );
 
@@ -1870,6 +1864,34 @@ DECLARE_EVENT_CLASS(svcrdma_sendqueue_event,
 DEFINE_SQ_EVENT(full);
 DEFINE_SQ_EVENT(retry);
 
+TRACE_EVENT(svcrdma_sq_post_err,
+	TP_PROTO(
+		const struct svcxprt_rdma *rdma,
+		int status
+	),
+
+	TP_ARGS(rdma, status),
+
+	TP_STRUCT__entry(
+		__field(int, avail)
+		__field(int, depth)
+		__field(int, status)
+		__string(addr, rdma->sc_xprt.xpt_remotebuf)
+	),
+
+	TP_fast_assign(
+		__entry->avail = atomic_read(&rdma->sc_sq_avail);
+		__entry->depth = rdma->sc_sq_depth;
+		__entry->status = status;
+		__assign_str(addr, rdma->sc_xprt.xpt_remotebuf);
+	),
+
+	TP_printk("addr=%s sc_sq_avail=%d/%d status=%d",
+		__get_str(addr), __entry->avail, __entry->depth,
+		__entry->status
+	)
+);
+
 #endif /* _TRACE_RPCRDMA_H */
 
 #include <trace/define_trace.h>
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index 3a3201e4618e..fa289b91410e 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -855,9 +855,11 @@ __SYSCALL(__NR_clone3, sys_clone3)
 __SYSCALL(__NR_openat2, sys_openat2)
 #define __NR_pidfd_getfd 438
 __SYSCALL(__NR_pidfd_getfd, sys_pidfd_getfd)
+#define __NR_process_madvise 439
+__SYSCALL(__NR_process_madvise, sys_process_madvise)
 
 #undef __NR_syscalls
-#define __NR_syscalls 439
+#define __NR_syscalls 440
 
 /*
  * 32 bit systems traditionally used different
diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
index 65f69723cbdc..68f96c23b91b 100644
--- a/include/uapi/drm/amdgpu_drm.h
+++ b/include/uapi/drm/amdgpu_drm.h
@@ -133,6 +133,11 @@ extern "C" {
  * releasing the memory
  */
 #define AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE	(1 << 9)
+/* Flag that BO will be encrypted and that the TMZ bit should be
+ * set in the PTEs when mapping this buffer via GPUVM or
+ * accessing it with various hw blocks
+ */
+#define AMDGPU_GEM_CREATE_ENCRYPTED		(1 << 10)
 
 struct drm_amdgpu_gem_create_in  {
 	/** the requested memory size */
@@ -555,7 +560,7 @@ struct drm_amdgpu_cs_in {
 	/**  Handle of resource list associated with CS */
 	__u32		bo_list_handle;
 	__u32		num_chunks;
-	__u32		_pad;
+	__u32		flags;
 	/** this points to __u64 * which point to cs chunks */
 	__u64		chunks;
 };
@@ -589,6 +594,14 @@ union drm_amdgpu_cs {
  */
 #define AMDGPU_IB_FLAG_RESET_GDS_MAX_WAVE_ID (1 << 4)
 
+/* Flag the IB as secure (TMZ)
+ */
+#define AMDGPU_IB_FLAGS_SECURE  (1 << 5)
+
+/* Tell KMD to flush and invalidate caches
+ */
+#define AMDGPU_IB_FLAG_EMIT_MEM_SYNC  (1 << 6)
+
 struct drm_amdgpu_cs_chunk_ib {
 	__u32 _pad;
 	/** AMDGPU_IB_FLAG_* */
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 2813e579b480..14b67cd6b54b 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -1969,6 +1969,30 @@ enum drm_i915_perf_property_id {
 	 */
 	DRM_I915_PERF_PROP_HOLD_PREEMPTION,
 
+	/**
+	 * Specifying this pins all contexts to the specified SSEU power
+	 * configuration for the duration of the recording.
+	 *
+	 * This parameter's value is a pointer to a struct
+	 * drm_i915_gem_context_param_sseu.
+	 *
+	 * This property is available in perf revision 4.
+	 */
+	DRM_I915_PERF_PROP_GLOBAL_SSEU,
+
+	/**
+	 * This optional parameter specifies the timer interval in nanoseconds
+	 * at which the i915 driver will check the OA buffer for available data.
+	 * Minimum allowed value is 100 microseconds. A default value is used by
+	 * the driver if this parameter is not specified. Note that larger timer
+	 * values will reduce cpu consumption during OA perf captures. However,
+	 * excessively large values would potentially result in OA buffer
+	 * overwrites as captures reach end of the OA buffer.
+	 *
+	 * This property is available in perf revision 5.
+	 */
+	DRM_I915_PERF_PROP_POLL_OA_PERIOD,
+
 	DRM_I915_PERF_PROP_MAX /* non-ABI */
 };
 
diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h
index 8134924cfc17..e6b6cb0f8bc6 100644
--- a/include/uapi/linux/btrfs.h
+++ b/include/uapi/linux/btrfs.h
@@ -36,12 +36,10 @@ struct btrfs_ioctl_vol_args {
 #define BTRFS_DEVICE_PATH_NAME_MAX	1024
 #define BTRFS_SUBVOL_NAME_MAX 		4039
 
-/*
- * Deprecated since 5.7:
- *
- * BTRFS_SUBVOL_CREATE_ASYNC	(1ULL << 0)
- */
-
+#ifndef __KERNEL__
+/* Deprecated since 5.7 */
+# define BTRFS_SUBVOL_CREATE_ASYNC	(1ULL << 0)
+#endif
 #define BTRFS_SUBVOL_RDONLY		(1ULL << 1)
 #define BTRFS_SUBVOL_QGROUP_INHERIT	(1ULL << 2)
 
diff --git a/include/uapi/linux/dlm_device.h b/include/uapi/linux/dlm_device.h
index f880d2831160..e83954c69fff 100644
--- a/include/uapi/linux/dlm_device.h
+++ b/include/uapi/linux/dlm_device.h
@@ -45,13 +45,13 @@ struct dlm_lock_params {
 	void __user *bastaddr;
 	struct dlm_lksb __user *lksb;
 	char lvb[DLM_USER_LVB_LEN];
-	char name[0];
+	char name[];
 };
 
 struct dlm_lspace_params {
 	__u32 flags;
 	__u32 minor;
-	char name[0];
+	char name[];
 };
 
 struct dlm_purge_params {
diff --git a/include/uapi/linux/fiemap.h b/include/uapi/linux/fiemap.h
index 8c0bc24d5d95..7a900b2377b6 100644
--- a/include/uapi/linux/fiemap.h
+++ b/include/uapi/linux/fiemap.h
@@ -34,7 +34,7 @@ struct fiemap {
 	__u32 fm_mapped_extents;/* number of extents that were mapped (out) */
 	__u32 fm_extent_count;  /* size of fm_extents array (in) */
 	__u32 fm_reserved;
-	struct fiemap_extent fm_extents[0]; /* array of mapped extents (out) */
+	struct fiemap_extent fm_extents[]; /* array of mapped extents (out) */
 };
 
 #define FIEMAP_MAX_OFFSET	(~0ULL)
diff --git a/include/uapi/linux/keyctl.h b/include/uapi/linux/keyctl.h
index ed3d5893830d..4c8884eea808 100644
--- a/include/uapi/linux/keyctl.h
+++ b/include/uapi/linux/keyctl.h
@@ -69,6 +69,7 @@
 #define KEYCTL_RESTRICT_KEYRING		29	/* Restrict keys allowed to link to a keyring */
 #define KEYCTL_MOVE			30	/* Move keys between keyrings */
 #define KEYCTL_CAPABILITIES		31	/* Find capabilities of keyrings subsystem */
+#define KEYCTL_WATCH_KEY		32	/* Watch a key or ring of keys for changes */
 
 /* keyctl structures */
 struct keyctl_dh_params {
@@ -130,5 +131,6 @@ struct keyctl_pkey_params {
 #define KEYCTL_CAPS0_MOVE		0x80 /* KEYCTL_MOVE supported */
 #define KEYCTL_CAPS1_NS_KEYRING_NAME	0x01 /* Keyring names are per-user_namespace */
 #define KEYCTL_CAPS1_NS_KEY_TAG		0x02 /* Key indexing can include a namespace tag */
+#define KEYCTL_CAPS1_NOTIFICATIONS	0x04 /* Keys generate watchable notifications */
 
 #endif /*  _LINUX_KEYCTL_H */
diff --git a/include/uapi/linux/kfd_ioctl.h b/include/uapi/linux/kfd_ioctl.h
index 20917c59f39c..4f6676428c5c 100644
--- a/include/uapi/linux/kfd_ioctl.h
+++ b/include/uapi/linux/kfd_ioctl.h
@@ -410,6 +410,20 @@ struct kfd_ioctl_unmap_memory_from_gpu_args {
 	__u32 n_success;		/* to/from KFD */
 };
 
+/* Allocate GWS for specific queue
+ *
+ * @queue_id:    queue's id that GWS is allocated for
+ * @num_gws:     how many GWS to allocate
+ * @first_gws:   index of the first GWS allocated.
+ *               only support contiguous GWS allocation
+ */
+struct kfd_ioctl_alloc_queue_gws_args {
+	__u32 queue_id;		/* to KFD */
+	__u32 num_gws;		/* to KFD */
+	__u32 first_gws;	/* from KFD */
+	__u32 pad;
+};
+
 struct kfd_ioctl_get_dmabuf_info_args {
 	__u64 size;		/* from KFD */
 	__u64 metadata_ptr;	/* to KFD */
@@ -529,7 +543,10 @@ enum kfd_mmio_remap {
 #define AMDKFD_IOC_IMPORT_DMABUF		\
 		AMDKFD_IOWR(0x1D, struct kfd_ioctl_import_dmabuf_args)
 
+#define AMDKFD_IOC_ALLOC_QUEUE_GWS		\
+		AMDKFD_IOWR(0x1E, struct kfd_ioctl_alloc_queue_gws_args)
+
 #define AMDKFD_COMMAND_START		0x01
-#define AMDKFD_COMMAND_END		0x1E
+#define AMDKFD_COMMAND_END		0x1F
 
 #endif
diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index 30f2a87270dc..4565456c0ef4 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -276,6 +276,7 @@ enum nft_rule_compat_attributes {
  * @NFT_SET_TIMEOUT: set uses timeouts
  * @NFT_SET_EVAL: set can be updated from the evaluation path
  * @NFT_SET_OBJECT: set contains stateful objects
+ * @NFT_SET_CONCAT: set contains a concatenation
  */
 enum nft_set_flags {
 	NFT_SET_ANONYMOUS		= 0x1,
@@ -285,6 +286,7 @@ enum nft_set_flags {
 	NFT_SET_TIMEOUT			= 0x10,
 	NFT_SET_EVAL			= 0x20,
 	NFT_SET_OBJECT			= 0x40,
+	NFT_SET_CONCAT			= 0x80,
 };
 
 /**
diff --git a/include/uapi/linux/netfilter/xt_IDLETIMER.h b/include/uapi/linux/netfilter/xt_IDLETIMER.h
index 434e6506abaa..49ddcdc61c09 100644
--- a/include/uapi/linux/netfilter/xt_IDLETIMER.h
+++ b/include/uapi/linux/netfilter/xt_IDLETIMER.h
@@ -48,6 +48,7 @@ struct idletimer_tg_info_v1 {
 
 	char label[MAX_IDLETIMER_LABEL_SIZE];
 
+	__u8 send_nl_msg;   /* unused: for compatibility with Android */
 	__u8 timer_type;
 
 	/* for kernel module internal use only */
diff --git a/include/uapi/linux/virtio_balloon.h b/include/uapi/linux/virtio_balloon.h
index 19974392d324..dc3e656470dd 100644
--- a/include/uapi/linux/virtio_balloon.h
+++ b/include/uapi/linux/virtio_balloon.h
@@ -48,8 +48,15 @@ struct virtio_balloon_config {
 	__u32 num_pages;
 	/* Number of pages we've actually got in balloon. */
 	__u32 actual;
-	/* Free page report command id, readonly by guest */
-	__u32 free_page_report_cmd_id;
+	/*
+	 * Free page hint command id, readonly by guest.
+	 * Was previously named free_page_report_cmd_id so we
+	 * need to carry that name for legacy support.
+	 */
+	union {
+		__u32 free_page_hint_cmd_id;
+		__u32 free_page_report_cmd_id;	/* deprecated */
+	};
 	/* Stores PAGE_POISON if page poisoning is in use */
 	__u32 poison_val;
 };
diff --git a/include/uapi/linux/virtio_ring.h b/include/uapi/linux/virtio_ring.h
index 559f42e73315..9223c3a5c46a 100644
--- a/include/uapi/linux/virtio_ring.h
+++ b/include/uapi/linux/virtio_ring.h
@@ -135,6 +135,8 @@ struct vring {
 #define VRING_USED_ALIGN_SIZE 4
 #define VRING_DESC_ALIGN_SIZE 16
 
+#ifndef VIRTIO_RING_NO_LEGACY
+
 /* The standard layout for the ring is a continuous chunk of memory which looks
  * like this.  We assume num is a power of 2.
  *
@@ -181,6 +183,8 @@ static inline unsigned vring_size(unsigned int num, unsigned long align)
 		+ sizeof(__virtio16) * 3 + sizeof(struct vring_used_elem) * num;
 }
 
+#endif /* VIRTIO_RING_NO_LEGACY */
+
 /* The following is used with USED_EVENT_IDX and AVAIL_EVENT_IDX */
 /* Assuming a given event_idx value from the other side, if
  * we have just incremented index from old to new_idx,
diff --git a/include/uapi/linux/watch_queue.h b/include/uapi/linux/watch_queue.h
new file mode 100644
index 000000000000..c3d8320b5d3a
--- /dev/null
+++ b/include/uapi/linux/watch_queue.h
@@ -0,0 +1,104 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _UAPI_LINUX_WATCH_QUEUE_H
+#define _UAPI_LINUX_WATCH_QUEUE_H
+
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/ioctl.h>
+
+#define O_NOTIFICATION_PIPE	O_EXCL	/* Parameter to pipe2() selecting notification pipe */
+
+#define IOC_WATCH_QUEUE_SET_SIZE	_IO('W', 0x60)	/* Set the size in pages */
+#define IOC_WATCH_QUEUE_SET_FILTER	_IO('W', 0x61)	/* Set the filter */
+
+enum watch_notification_type {
+	WATCH_TYPE_META		= 0,	/* Special record */
+	WATCH_TYPE_KEY_NOTIFY	= 1,	/* Key change event notification */
+	WATCH_TYPE__NR		= 2
+};
+
+enum watch_meta_notification_subtype {
+	WATCH_META_REMOVAL_NOTIFICATION	= 0,	/* Watched object was removed */
+	WATCH_META_LOSS_NOTIFICATION	= 1,	/* Data loss occurred */
+};
+
+/*
+ * Notification record header.  This is aligned to 64-bits so that subclasses
+ * can contain __u64 fields.
+ */
+struct watch_notification {
+	__u32			type:24;	/* enum watch_notification_type */
+	__u32			subtype:8;	/* Type-specific subtype (filterable) */
+	__u32			info;
+#define WATCH_INFO_LENGTH	0x0000007f	/* Length of record */
+#define WATCH_INFO_LENGTH__SHIFT 0
+#define WATCH_INFO_ID		0x0000ff00	/* ID of watchpoint */
+#define WATCH_INFO_ID__SHIFT	8
+#define WATCH_INFO_TYPE_INFO	0xffff0000	/* Type-specific info */
+#define WATCH_INFO_TYPE_INFO__SHIFT 16
+#define WATCH_INFO_FLAG_0	0x00010000	/* Type-specific info, flag bit 0 */
+#define WATCH_INFO_FLAG_1	0x00020000	/* ... */
+#define WATCH_INFO_FLAG_2	0x00040000
+#define WATCH_INFO_FLAG_3	0x00080000
+#define WATCH_INFO_FLAG_4	0x00100000
+#define WATCH_INFO_FLAG_5	0x00200000
+#define WATCH_INFO_FLAG_6	0x00400000
+#define WATCH_INFO_FLAG_7	0x00800000
+};
+
+/*
+ * Notification filtering rules (IOC_WATCH_QUEUE_SET_FILTER).
+ */
+struct watch_notification_type_filter {
+	__u32	type;			/* Type to apply filter to */
+	__u32	info_filter;		/* Filter on watch_notification::info */
+	__u32	info_mask;		/* Mask of relevant bits in info_filter */
+	__u32	subtype_filter[8];	/* Bitmask of subtypes to filter on */
+};
+
+struct watch_notification_filter {
+	__u32	nr_filters;		/* Number of filters */
+	__u32	__reserved;		/* Must be 0 */
+	struct watch_notification_type_filter filters[];
+};
+
+
+/*
+ * Extended watch removal notification.  This is used optionally if the type
+ * wants to indicate an identifier for the object being watched, if there is
+ * such.  This can be distinguished by the length.
+ *
+ * type -> WATCH_TYPE_META
+ * subtype -> WATCH_META_REMOVAL_NOTIFICATION
+ */
+struct watch_notification_removal {
+	struct watch_notification watch;
+	__u64	id;		/* Type-dependent identifier */
+};
+
+/*
+ * Type of key/keyring change notification.
+ */
+enum key_notification_subtype {
+	NOTIFY_KEY_INSTANTIATED	= 0, /* Key was instantiated (aux is error code) */
+	NOTIFY_KEY_UPDATED	= 1, /* Key was updated */
+	NOTIFY_KEY_LINKED	= 2, /* Key (aux) was added to watched keyring */
+	NOTIFY_KEY_UNLINKED	= 3, /* Key (aux) was removed from watched keyring */
+	NOTIFY_KEY_CLEARED	= 4, /* Keyring was cleared */
+	NOTIFY_KEY_REVOKED	= 5, /* Key was revoked */
+	NOTIFY_KEY_INVALIDATED	= 6, /* Key was invalidated */
+	NOTIFY_KEY_SETATTR	= 7, /* Key's attributes got changed */
+};
+
+/*
+ * Key/keyring notification record.
+ * - watch.type = WATCH_TYPE_KEY_NOTIFY
+ * - watch.subtype = enum key_notification_type
+ */
+struct key_notification {
+	struct watch_notification watch;
+	__u32	key_id;		/* The key/keyring affected */
+	__u32	aux;		/* Per-type auxiliary data */
+};
+
+#endif /* _UAPI_LINUX_WATCH_QUEUE_H */
diff --git a/init/Kconfig b/init/Kconfig
index 9e22ee8fbd75..492bb7000aa4 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -342,6 +342,18 @@ config POSIX_MQUEUE_SYSCTL
 	depends on SYSCTL
 	default y
 
+config WATCH_QUEUE
+	bool "General notification queue"
+	default n
+	help
+
+	  This is a general notification queue for the kernel to pass events to
+	  userspace by splicing them into pipes.  It can be used in conjunction
+	  with watches for key/keyring change notifications and device
+	  notifications.
+
+	  See Documentation/watch_queue.rst
+
 config CROSS_MEMORY_ATTACH
 	bool "Enable process_vm_readv/writev syscalls"
 	depends on MMU
diff --git a/init/init_task.c b/init/init_task.c
index bd403ed3e418..537c70cc0d0f 100644
--- a/init/init_task.c
+++ b/init/init_task.c
@@ -141,6 +141,11 @@ struct task_struct init_task
 	.rcu_tasks_holdout_list = LIST_HEAD_INIT(init_task.rcu_tasks_holdout_list),
 	.rcu_tasks_idle_cpu = -1,
 #endif
+#ifdef CONFIG_TASKS_TRACE_RCU
+	.trc_reader_nesting = 0,
+	.trc_reader_special.s = 0,
+	.trc_holdout_list = LIST_HEAD_INIT(init_task.trc_holdout_list),
+#endif
 #ifdef CONFIG_CPUSETS
 	.mems_allowed_seq = SEQCNT_ZERO(init_task.mems_allowed_seq),
 #endif
@@ -162,6 +167,16 @@ struct task_struct init_task
 #ifdef CONFIG_KASAN
 	.kasan_depth	= 1,
 #endif
+#ifdef CONFIG_KCSAN
+	.kcsan_ctx = {
+		.disable_count		= 0,
+		.atomic_next		= 0,
+		.atomic_nest_count	= 0,
+		.in_flat_atomic		= false,
+		.access_mask		= 0,
+		.scoped_accesses	= {LIST_POISON1, NULL},
+	},
+#endif
 #ifdef CONFIG_TRACE_IRQFLAGS
 	.softirqs_enabled = 1,
 #endif
diff --git a/init/main.c b/init/main.c
index a48617f2e5e5..89a2dd0d9372 100644
--- a/init/main.c
+++ b/init/main.c
@@ -54,6 +54,7 @@
 #include <linux/delayacct.h>
 #include <linux/unistd.h>
 #include <linux/utsname.h>
+#include <linux/mmdebug.h>
 #include <linux/rmap.h>
 #include <linux/mempolicy.h>
 #include <linux/key.h>
@@ -94,6 +95,7 @@
 #include <linux/rodata_test.h>
 #include <linux/jump_label.h>
 #include <linux/mem_encrypt.h>
+#include <linux/kcsan.h>
 
 #include <asm/io.h>
 #include <asm/bugs.h>
@@ -998,6 +1000,7 @@ asmlinkage __visible void __init start_kernel(void)
 	acpi_subsystem_init();
 	arch_post_acpi_subsys_init();
 	sfi_init_late();
+	kcsan_init();
 
 	/* Do the rest non-__init'ed, we're now alive */
 	arch_call_rest_init();
@@ -1357,6 +1360,7 @@ static int __ref kernel_init(void *unused)
 	kernel_init_freeable();
 	/* need to finish all async __init code before freeing the memory */
 	async_synchronize_full();
+	debug_vm_pgtable();
 	ftrace_free_init_mem();
 	free_initmem();
 	mark_readonly();
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index dc8307bf2d74..beff0cfcd1e8 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -142,6 +142,7 @@ struct mqueue_inode_info {
 
 	struct sigevent notify;
 	struct pid *notify_owner;
+	u32 notify_self_exec_id;
 	struct user_namespace *notify_user_ns;
 	struct user_struct *user;	/* user who created, for accounting */
 	struct sock *notify_sock;
@@ -773,28 +774,44 @@ static void __do_notify(struct mqueue_inode_info *info)
 	 * synchronously. */
 	if (info->notify_owner &&
 	    info->attr.mq_curmsgs == 1) {
-		struct kernel_siginfo sig_i;
 		switch (info->notify.sigev_notify) {
 		case SIGEV_NONE:
 			break;
-		case SIGEV_SIGNAL:
-			/* sends signal */
+		case SIGEV_SIGNAL: {
+			struct kernel_siginfo sig_i;
+			struct task_struct *task;
+
+			/* do_mq_notify() accepts sigev_signo == 0, why?? */
+			if (!info->notify.sigev_signo)
+				break;
 
 			clear_siginfo(&sig_i);
 			sig_i.si_signo = info->notify.sigev_signo;
 			sig_i.si_errno = 0;
 			sig_i.si_code = SI_MESGQ;
 			sig_i.si_value = info->notify.sigev_value;
-			/* map current pid/uid into info->owner's namespaces */
 			rcu_read_lock();
+			/* map current pid/uid into info->owner's namespaces */
 			sig_i.si_pid = task_tgid_nr_ns(current,
 						ns_of_pid(info->notify_owner));
-			sig_i.si_uid = from_kuid_munged(info->notify_user_ns, current_uid());
+			sig_i.si_uid = from_kuid_munged(info->notify_user_ns,
+						current_uid());
+			/*
+			 * We can't use kill_pid_info(), this signal should
+			 * bypass check_kill_permission(). It is from kernel
+			 * but si_fromuser() can't know this.
+			 * We do check the self_exec_id, to avoid sending
+			 * signals to programs that don't expect them.
+			 */
+			task = pid_task(info->notify_owner, PIDTYPE_TGID);
+			if (task && task->self_exec_id ==
+						info->notify_self_exec_id) {
+				do_send_sig_info(info->notify.sigev_signo,
+						&sig_i, task, PIDTYPE_TGID);
+			}
 			rcu_read_unlock();
-
-			kill_pid_info(info->notify.sigev_signo,
-				      &sig_i, info->notify_owner);
 			break;
+		}
 		case SIGEV_THREAD:
 			set_cookie(info->notify_cookie, NOTIFY_WOKENUP);
 			netlink_sendskb(info->notify_sock, info->notify_cookie);
@@ -1383,6 +1400,7 @@ static int do_mq_notify(mqd_t mqdes, const struct sigevent *notification)
 			info->notify.sigev_signo = notification->sigev_signo;
 			info->notify.sigev_value = notification->sigev_value;
 			info->notify.sigev_notify = SIGEV_SIGNAL;
+			info->notify_self_exec_id = current->self_exec_id;
 			break;
 		}
 
diff --git a/kernel/Makefile b/kernel/Makefile
index 4cb4130ced32..a42ac3a58994 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -23,6 +23,9 @@ endif
 # Prevents flicker of uninteresting __do_softirq()/__local_bh_disable_ip()
 # in coverage traces.
 KCOV_INSTRUMENT_softirq.o := n
+# Avoid KCSAN instrumentation in softirq ("No shared variables, all the data
+# are CPU local" => assume no data races), to reduce overhead in interrupts.
+KCSAN_SANITIZE_softirq.o = n
 # These are called from save_stack_trace() on slub debug path,
 # and produce insane amounts of uninteresting coverage.
 KCOV_INSTRUMENT_module.o := n
@@ -31,6 +34,7 @@ KCOV_INSTRUMENT_stacktrace.o := n
 # Don't self-instrument.
 KCOV_INSTRUMENT_kcov.o := n
 KASAN_SANITIZE_kcov.o := n
+KCSAN_SANITIZE_kcov.o := n
 CFLAGS_kcov.o := $(call cc-option, -fno-conserve-stack -fno-stack-protector)
 
 # cond_syscall is currently not LTO compatible
@@ -103,6 +107,7 @@ obj-$(CONFIG_TRACEPOINTS) += trace/
 obj-$(CONFIG_IRQ_WORK) += irq_work.o
 obj-$(CONFIG_CPU_PM) += cpu_pm.o
 obj-$(CONFIG_BPF) += bpf/
+obj-$(CONFIG_KCSAN) += kcsan/
 
 obj-$(CONFIG_PERF_EVENTS) += events/
 
@@ -115,11 +120,13 @@ obj-$(CONFIG_TORTURE_TEST) += torture.o
 
 obj-$(CONFIG_HAS_IOMEM) += iomem.o
 obj-$(CONFIG_RSEQ) += rseq.o
+obj-$(CONFIG_WATCH_QUEUE) += watch_queue.o
 
 obj-$(CONFIG_SYSCTL_KUNIT_TEST) += sysctl-test.o
 
 obj-$(CONFIG_GCC_PLUGIN_STACKLEAK) += stackleak.o
 KASAN_SANITIZE_stackleak.o := n
+KCSAN_SANITIZE_stackleak.o := n
 KCOV_INSTRUMENT_stackleak.o := n
 
 $(obj)/configs.o: $(obj)/config_data.gz
diff --git a/kernel/bpf/bpf_lru_list.h b/kernel/bpf/bpf_lru_list.h
index f02504640e18..6b12f06ee18c 100644
--- a/kernel/bpf/bpf_lru_list.h
+++ b/kernel/bpf/bpf_lru_list.h
@@ -30,7 +30,7 @@ struct bpf_lru_node {
 struct bpf_lru_list {
 	struct list_head lists[NR_BPF_LRU_LIST_T];
 	unsigned int counts[NR_BPF_LRU_LIST_COUNT];
-	/* The next inacitve list rotation starts from here */
+	/* The next inactive list rotation starts from here */
 	struct list_head *next_inactive_rotation;
 
 	raw_spinlock_t lock ____cacheline_aligned_in_smp;
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 64783da34202..d85f37239540 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -586,9 +586,7 @@ static void bpf_map_mmap_open(struct vm_area_struct *vma)
 {
 	struct bpf_map *map = vma->vm_file->private_data;
 
-	bpf_map_inc_with_uref(map);
-
-	if (vma->vm_flags & VM_WRITE) {
+	if (vma->vm_flags & VM_MAYWRITE) {
 		mutex_lock(&map->freeze_mutex);
 		map->writecnt++;
 		mutex_unlock(&map->freeze_mutex);
@@ -600,13 +598,11 @@ static void bpf_map_mmap_close(struct vm_area_struct *vma)
 {
 	struct bpf_map *map = vma->vm_file->private_data;
 
-	if (vma->vm_flags & VM_WRITE) {
+	if (vma->vm_flags & VM_MAYWRITE) {
 		mutex_lock(&map->freeze_mutex);
 		map->writecnt--;
 		mutex_unlock(&map->freeze_mutex);
 	}
-
-	bpf_map_put_with_uref(map);
 }
 
 static const struct vm_operations_struct bpf_map_default_vmops = {
@@ -635,14 +631,16 @@ static int bpf_map_mmap(struct file *filp, struct vm_area_struct *vma)
 	/* set default open/close callbacks */
 	vma->vm_ops = &bpf_map_default_vmops;
 	vma->vm_private_data = map;
+	vma->vm_flags &= ~VM_MAYEXEC;
+	if (!(vma->vm_flags & VM_WRITE))
+		/* disallow re-mapping with PROT_WRITE */
+		vma->vm_flags &= ~VM_MAYWRITE;
 
 	err = map->ops->map_mmap(map, vma);
 	if (err)
 		goto out;
 
-	bpf_map_inc_with_uref(map);
-
-	if (vma->vm_flags & VM_WRITE)
+	if (vma->vm_flags & VM_MAYWRITE)
 		map->writecnt++;
 out:
 	mutex_unlock(&map->freeze_mutex);
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 04c6630cc18f..38cfcf701eeb 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -1255,8 +1255,7 @@ static void __mark_reg_unknown(const struct bpf_verifier_env *env,
 	reg->type = SCALAR_VALUE;
 	reg->var_off = tnum_unknown;
 	reg->frameno = 0;
-	reg->precise = env->subprog_cnt > 1 || !env->allow_ptr_leaks ?
-		       true : false;
+	reg->precise = env->subprog_cnt > 1 || !env->allow_ptr_leaks;
 	__mark_reg_unbounded(reg);
 }
 
diff --git a/kernel/cgroup/rstat.c b/kernel/cgroup/rstat.c
index 6f87352f8219..41ca996568df 100644
--- a/kernel/cgroup/rstat.c
+++ b/kernel/cgroup/rstat.c
@@ -33,12 +33,9 @@ void cgroup_rstat_updated(struct cgroup *cgrp, int cpu)
 		return;
 
 	/*
-	 * Paired with the one in cgroup_rstat_cpu_pop_updated().  Either we
-	 * see NULL updated_next or they see our updated stat.
-	 */
-	smp_mb();
-
-	/*
+	 * Speculative already-on-list test. This may race leading to
+	 * temporary inaccuracies, which is fine.
+	 *
 	 * Because @parent's updated_children is terminated with @parent
 	 * instead of NULL, we can tell whether @cgrp is on the list by
 	 * testing the next pointer for NULL.
@@ -134,13 +131,6 @@ static struct cgroup *cgroup_rstat_cpu_pop_updated(struct cgroup *pos,
 		*nextp = rstatc->updated_next;
 		rstatc->updated_next = NULL;
 
-		/*
-		 * Paired with the one in cgroup_rstat_cpu_updated().
-		 * Either they see NULL updated_next or we see their
-		 * updated stat.
-		 */
-		smp_mb();
-
 		return pos;
 	}
 
diff --git a/kernel/crash_dump.c b/kernel/crash_dump.c
index 9c23ae074b40..92da32275af5 100644
--- a/kernel/crash_dump.c
+++ b/kernel/crash_dump.c
@@ -5,12 +5,6 @@
 #include <linux/errno.h>
 #include <linux/export.h>
 
-/*
- * If we have booted due to a crash, max_pfn will be a very low value. We need
- * to know the amount of memory that the previous kernel used.
- */
-unsigned long saved_max_pfn;
-
 /*
  * stores the physical address of elf header of crash image
  *
diff --git a/kernel/exit.c b/kernel/exit.c
index 389a88cb3081..e93c6197a827 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -1464,23 +1464,6 @@ static long do_wait(struct wait_opts *wo)
 	return retval;
 }
 
-static struct pid *pidfd_get_pid(unsigned int fd)
-{
-	struct fd f;
-	struct pid *pid;
-
-	f = fdget(fd);
-	if (!f.file)
-		return ERR_PTR(-EBADF);
-
-	pid = pidfd_pid(f.file);
-	if (!IS_ERR(pid))
-		get_pid(pid);
-
-	fdput(f);
-	return pid;
-}
-
 static long kernel_waitid(int which, pid_t upid, struct waitid_info *infop,
 			  int options, struct rusage *ru)
 {
diff --git a/kernel/fork.c b/kernel/fork.c
index 4385f3d639f2..0c7a2d23b273 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -359,7 +359,13 @@ struct vm_area_struct *vm_area_dup(struct vm_area_struct *orig)
 	struct vm_area_struct *new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
 
 	if (new) {
-		*new = *orig;
+		ASSERT_EXCLUSIVE_WRITER(orig->vm_flags);
+		ASSERT_EXCLUSIVE_WRITER(orig->vm_file);
+		/*
+		 * orig->shared.rb may be modified concurrently, but the clone
+		 * will be reinitialized.
+		 */
+		*new = data_race(*orig);
 		INIT_LIST_HEAD(&new->anon_vma_chain);
 		new->vm_next = new->vm_prev = NULL;
 	}
@@ -1683,6 +1689,11 @@ static inline void rcu_copy_process(struct task_struct *p)
 	INIT_LIST_HEAD(&p->rcu_tasks_holdout_list);
 	p->rcu_tasks_idle_cpu = -1;
 #endif /* #ifdef CONFIG_TASKS_RCU */
+#ifdef CONFIG_TASKS_TRACE_RCU
+	p->trc_reader_nesting = 0;
+	p->trc_reader_special.s = 0;
+	INIT_LIST_HEAD(&p->trc_holdout_list);
+#endif /* #ifdef CONFIG_TASKS_TRACE_RCU */
 }
 
 struct pid *pidfd_pid(const struct file *file)
@@ -2605,6 +2616,14 @@ noinline static int copy_clone_args_from_user(struct kernel_clone_args *kargs,
 	struct clone_args args;
 	pid_t *kset_tid = kargs->set_tid;
 
+	BUILD_BUG_ON(offsetofend(struct clone_args, tls) !=
+		     CLONE_ARGS_SIZE_VER0);
+	BUILD_BUG_ON(offsetofend(struct clone_args, set_tid_size) !=
+		     CLONE_ARGS_SIZE_VER1);
+	BUILD_BUG_ON(offsetofend(struct clone_args, cgroup) !=
+		     CLONE_ARGS_SIZE_VER2);
+	BUILD_BUG_ON(sizeof(struct clone_args) != CLONE_ARGS_SIZE_VER2);
+
 	if (unlikely(usize > PAGE_SIZE))
 		return -E2BIG;
 	if (unlikely(usize < CLONE_ARGS_SIZE_VER0))
@@ -2631,7 +2650,8 @@ noinline static int copy_clone_args_from_user(struct kernel_clone_args *kargs,
 		     !valid_signal(args.exit_signal)))
 		return -EINVAL;
 
-	if ((args.flags & CLONE_INTO_CGROUP) && args.cgroup < 0)
+	if ((args.flags & CLONE_INTO_CGROUP) &&
+	    (args.cgroup > INT_MAX || usize < CLONE_ARGS_SIZE_VER2))
 		return -EINVAL;
 
 	*kargs = (struct kernel_clone_args){
diff --git a/kernel/hung_task.c b/kernel/hung_task.c
index 14a625c16cb3..69f54848af79 100644
--- a/kernel/hung_task.c
+++ b/kernel/hung_task.c
@@ -142,6 +142,47 @@ static void check_hung_task(struct task_struct *t, unsigned long timeout)
 	touch_nmi_watchdog();
 }
 
+static void check_killed_task(struct task_struct *t, unsigned long timeout)
+{
+	unsigned long stamp = t->killed_time;
+
+	/*
+	 * Ensure the task is not frozen.
+	 * Also, skip vfork and any other user process that freezer should skip.
+	 */
+	if (unlikely(t->flags & (PF_FROZEN | PF_FREEZER_SKIP)))
+		return;
+	/*
+	 * Skip threads which are already inside do_exit(), for exit_mm() etc.
+	 * might take many seconds.
+	 */
+	if (t->flags & PF_EXITING)
+		return;
+	if (!stamp) {
+		stamp = jiffies;
+		if (!stamp)
+			stamp++;
+		t->killed_time = stamp;
+		return;
+	}
+	if (time_is_after_jiffies(stamp + timeout * HZ))
+		return;
+	trace_sched_process_hang(t);
+	if (sysctl_hung_task_panic) {
+		console_verbose();
+		hung_task_call_panic = true;
+	}
+	/*
+	 * This thread failed to terminate for more than
+	 * sysctl_hung_task_timeout_secs seconds, complain:
+	 */
+	pr_err("INFO: task %s:%d can't die for more than %ld seconds.\n",
+	       t->comm, t->pid, (jiffies - stamp) / HZ);
+	sched_show_task(t);
+	hung_task_show_lock = true;
+	touch_nmi_watchdog();
+}
+
 /*
  * To avoid extending the RCU grace period for an unbounded amount of time,
  * periodically exit the critical section and enter a new one.
@@ -193,6 +234,9 @@ static void check_hung_uninterruptible_tasks(unsigned long timeout)
 				goto unlock;
 			last_break = jiffies;
 		}
+		/* Check threads which are about to terminate. */
+		if (unlikely(fatal_signal_pending(t)))
+			check_killed_task(t, timeout);
 		/* use "==" to skip the TASK_KILLABLE tasks waiting on NFS */
 		if (t->state == TASK_UNINTERRUPTIBLE)
 			check_hung_task(t, timeout);
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index fe40c658f86f..453a8a0f4804 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -1690,34 +1690,6 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
 	return ret;
 }
 
-/**
- *	setup_irq - setup an interrupt
- *	@irq: Interrupt line to setup
- *	@act: irqaction for the interrupt
- *
- * Used to statically setup interrupts in the early boot process.
- */
-int setup_irq(unsigned int irq, struct irqaction *act)
-{
-	int retval;
-	struct irq_desc *desc = irq_to_desc(irq);
-
-	if (!desc || WARN_ON(irq_settings_is_per_cpu_devid(desc)))
-		return -EINVAL;
-
-	retval = irq_chip_pm_get(&desc->irq_data);
-	if (retval < 0)
-		return retval;
-
-	retval = __setup_irq(irq, desc, act);
-
-	if (retval)
-		irq_chip_pm_put(&desc->irq_data);
-
-	return retval;
-}
-EXPORT_SYMBOL_GPL(setup_irq);
-
 /*
  * Internal function to unregister an irqaction - used to free
  * regular and special interrupts that are part of the architecture.
@@ -1858,22 +1830,6 @@ static struct irqaction *__free_irq(struct irq_desc *desc, void *dev_id)
 	return action;
 }
 
-/**
- *	remove_irq - free an interrupt
- *	@irq: Interrupt line to free
- *	@act: irqaction for the interrupt
- *
- * Used to remove interrupts statically setup by the early boot process.
- */
-void remove_irq(unsigned int irq, struct irqaction *act)
-{
-	struct irq_desc *desc = irq_to_desc(irq);
-
-	if (desc && !WARN_ON(irq_settings_is_per_cpu_devid(desc)))
-		__free_irq(desc, act->dev_id);
-}
-EXPORT_SYMBOL_GPL(remove_irq);
-
 /**
  *	free_irq - free an interrupt allocated with request_irq
  *	@irq: Interrupt line to free
diff --git a/kernel/kcov.c b/kernel/kcov.c
index f50354202dbe..0980fc608770 100644
--- a/kernel/kcov.c
+++ b/kernel/kcov.c
@@ -86,6 +86,18 @@ static DEFINE_SPINLOCK(kcov_remote_lock);
 static DEFINE_HASHTABLE(kcov_remote_map, 4);
 static struct list_head kcov_remote_areas = LIST_HEAD_INIT(kcov_remote_areas);
 
+struct kcov_percpu_data {
+	void			*irq_area;
+
+	unsigned int		saved_mode;
+	unsigned int		saved_size;
+	void			*saved_area;
+	struct kcov		*saved_kcov;
+	int			saved_sequence;
+};
+
+DEFINE_PER_CPU(struct kcov_percpu_data, kcov_percpu_data);
+
 /* Must be called with kcov_remote_lock locked. */
 static struct kcov_remote *kcov_remote_find(u64 handle)
 {
@@ -98,6 +110,7 @@ static struct kcov_remote *kcov_remote_find(u64 handle)
 	return NULL;
 }
 
+/* Must be called with kcov_remote_lock locked. */
 static struct kcov_remote *kcov_remote_add(struct kcov *kcov, u64 handle)
 {
 	struct kcov_remote *remote;
@@ -119,16 +132,13 @@ static struct kcov_remote_area *kcov_remote_area_get(unsigned int size)
 	struct kcov_remote_area *area;
 	struct list_head *pos;
 
-	kcov_debug("size = %u\n", size);
 	list_for_each(pos, &kcov_remote_areas) {
 		area = list_entry(pos, struct kcov_remote_area, list);
 		if (area->size == size) {
 			list_del(&area->list);
-			kcov_debug("rv = %px\n", area);
 			return area;
 		}
 	}
-	kcov_debug("rv = NULL\n");
 	return NULL;
 }
 
@@ -136,7 +146,6 @@ static struct kcov_remote_area *kcov_remote_area_get(unsigned int size)
 static void kcov_remote_area_put(struct kcov_remote_area *area,
 					unsigned int size)
 {
-	kcov_debug("area = %px, size = %u\n", area, size);
 	INIT_LIST_HEAD(&area->list);
 	area->size = size;
 	list_add(&area->list, &kcov_remote_areas);
@@ -148,9 +157,10 @@ static notrace bool check_kcov_mode(enum kcov_mode needed_mode, struct task_stru
 
 	/*
 	 * We are interested in code coverage as a function of a syscall inputs,
-	 * so we ignore code executed in interrupts.
+	 * so we ignore code executed in interrupts, unless we are in a remote
+	 * coverage collection section in a softirq.
 	 */
-	if (!in_task())
+	if (!in_task() && !(in_serving_softirq() && t->kcov_softirq))
 		return false;
 	mode = READ_ONCE(t->kcov_mode);
 	/*
@@ -312,23 +322,26 @@ void notrace __sanitizer_cov_trace_switch(u64 val, u64 *cases)
 EXPORT_SYMBOL(__sanitizer_cov_trace_switch);
 #endif /* ifdef CONFIG_KCOV_ENABLE_COMPARISONS */
 
-static void kcov_start(struct task_struct *t, unsigned int size,
-			void *area, enum kcov_mode mode, int sequence)
+static void kcov_start(struct task_struct *t, struct kcov *kcov,
+			unsigned int size, void *area, enum kcov_mode mode,
+			int sequence)
 {
 	kcov_debug("t = %px, size = %u, area = %px\n", t, size, area);
+	t->kcov = kcov;
 	/* Cache in task struct for performance. */
 	t->kcov_size = size;
 	t->kcov_area = area;
+	t->kcov_sequence = sequence;
 	/* See comment in check_kcov_mode(). */
 	barrier();
 	WRITE_ONCE(t->kcov_mode, mode);
-	t->kcov_sequence = sequence;
 }
 
 static void kcov_stop(struct task_struct *t)
 {
 	WRITE_ONCE(t->kcov_mode, KCOV_MODE_DISABLED);
 	barrier();
+	t->kcov = NULL;
 	t->kcov_size = 0;
 	t->kcov_area = NULL;
 }
@@ -336,7 +349,6 @@ static void kcov_stop(struct task_struct *t)
 static void kcov_task_reset(struct task_struct *t)
 {
 	kcov_stop(t);
-	t->kcov = NULL;
 	t->kcov_sequence = 0;
 	t->kcov_handle = 0;
 }
@@ -361,18 +373,18 @@ static void kcov_remote_reset(struct kcov *kcov)
 	int bkt;
 	struct kcov_remote *remote;
 	struct hlist_node *tmp;
+	unsigned long flags;
 
-	spin_lock(&kcov_remote_lock);
+	spin_lock_irqsave(&kcov_remote_lock, flags);
 	hash_for_each_safe(kcov_remote_map, bkt, tmp, remote, hnode) {
 		if (remote->kcov != kcov)
 			continue;
-		kcov_debug("removing handle %llx\n", remote->handle);
 		hash_del(&remote->hnode);
 		kfree(remote);
 	}
 	/* Do reset before unlock to prevent races with kcov_remote_start(). */
 	kcov_reset(kcov);
-	spin_unlock(&kcov_remote_lock);
+	spin_unlock_irqrestore(&kcov_remote_lock, flags);
 }
 
 static void kcov_disable(struct task_struct *t, struct kcov *kcov)
@@ -401,12 +413,13 @@ static void kcov_put(struct kcov *kcov)
 void kcov_task_exit(struct task_struct *t)
 {
 	struct kcov *kcov;
+	unsigned long flags;
 
 	kcov = t->kcov;
 	if (kcov == NULL)
 		return;
 
-	spin_lock(&kcov->lock);
+	spin_lock_irqsave(&kcov->lock, flags);
 	kcov_debug("t = %px, kcov->t = %px\n", t, kcov->t);
 	/*
 	 * For KCOV_ENABLE devices we want to make sure that t->kcov->t == t,
@@ -430,12 +443,12 @@ void kcov_task_exit(struct task_struct *t)
 	 * By combining all three checks into one we get:
 	 */
 	if (WARN_ON(kcov->t != t)) {
-		spin_unlock(&kcov->lock);
+		spin_unlock_irqrestore(&kcov->lock, flags);
 		return;
 	}
 	/* Just to not leave dangling references behind. */
 	kcov_disable(t, kcov);
-	spin_unlock(&kcov->lock);
+	spin_unlock_irqrestore(&kcov->lock, flags);
 	kcov_put(kcov);
 }
 
@@ -446,12 +459,13 @@ static int kcov_mmap(struct file *filep, struct vm_area_struct *vma)
 	struct kcov *kcov = vma->vm_file->private_data;
 	unsigned long size, off;
 	struct page *page;
+	unsigned long flags;
 
 	area = vmalloc_user(vma->vm_end - vma->vm_start);
 	if (!area)
 		return -ENOMEM;
 
-	spin_lock(&kcov->lock);
+	spin_lock_irqsave(&kcov->lock, flags);
 	size = kcov->size * sizeof(unsigned long);
 	if (kcov->mode != KCOV_MODE_INIT || vma->vm_pgoff != 0 ||
 	    vma->vm_end - vma->vm_start != size) {
@@ -461,7 +475,7 @@ static int kcov_mmap(struct file *filep, struct vm_area_struct *vma)
 	if (!kcov->area) {
 		kcov->area = area;
 		vma->vm_flags |= VM_DONTEXPAND;
-		spin_unlock(&kcov->lock);
+		spin_unlock_irqrestore(&kcov->lock, flags);
 		for (off = 0; off < size; off += PAGE_SIZE) {
 			page = vmalloc_to_page(kcov->area + off);
 			if (vm_insert_page(vma, vma->vm_start + off, page))
@@ -470,7 +484,7 @@ static int kcov_mmap(struct file *filep, struct vm_area_struct *vma)
 		return 0;
 	}
 exit:
-	spin_unlock(&kcov->lock);
+	spin_unlock_irqrestore(&kcov->lock, flags);
 	vfree(area);
 	return res;
 }
@@ -550,10 +564,10 @@ static int kcov_ioctl_locked(struct kcov *kcov, unsigned int cmd,
 	int mode, i;
 	struct kcov_remote_arg *remote_arg;
 	struct kcov_remote *remote;
+	unsigned long flags;
 
 	switch (cmd) {
 	case KCOV_INIT_TRACE:
-		kcov_debug("KCOV_INIT_TRACE\n");
 		/*
 		 * Enable kcov in trace mode and setup buffer size.
 		 * Must happen before anything else.
@@ -572,7 +586,6 @@ static int kcov_ioctl_locked(struct kcov *kcov, unsigned int cmd,
 		kcov->mode = KCOV_MODE_INIT;
 		return 0;
 	case KCOV_ENABLE:
-		kcov_debug("KCOV_ENABLE\n");
 		/*
 		 * Enable coverage for the current task.
 		 * At this point user must have been enabled trace mode,
@@ -590,15 +603,13 @@ static int kcov_ioctl_locked(struct kcov *kcov, unsigned int cmd,
 			return mode;
 		kcov_fault_in_area(kcov);
 		kcov->mode = mode;
-		kcov_start(t, kcov->size, kcov->area, kcov->mode,
+		kcov_start(t, kcov, kcov->size, kcov->area, kcov->mode,
 				kcov->sequence);
-		t->kcov = kcov;
 		kcov->t = t;
 		/* Put either in kcov_task_exit() or in KCOV_DISABLE. */
 		kcov_get(kcov);
 		return 0;
 	case KCOV_DISABLE:
-		kcov_debug("KCOV_DISABLE\n");
 		/* Disable coverage for the current task. */
 		unused = arg;
 		if (unused != 0 || current->kcov != kcov)
@@ -610,7 +621,6 @@ static int kcov_ioctl_locked(struct kcov *kcov, unsigned int cmd,
 		kcov_put(kcov);
 		return 0;
 	case KCOV_REMOTE_ENABLE:
-		kcov_debug("KCOV_REMOTE_ENABLE\n");
 		if (kcov->mode != KCOV_MODE_INIT || !kcov->area)
 			return -EINVAL;
 		t = current;
@@ -627,41 +637,42 @@ static int kcov_ioctl_locked(struct kcov *kcov, unsigned int cmd,
 		kcov->t = t;
 		kcov->remote = true;
 		kcov->remote_size = remote_arg->area_size;
-		spin_lock(&kcov_remote_lock);
+		spin_lock_irqsave(&kcov_remote_lock, flags);
 		for (i = 0; i < remote_arg->num_handles; i++) {
-			kcov_debug("handle %llx\n", remote_arg->handles[i]);
 			if (!kcov_check_handle(remote_arg->handles[i],
 						false, true, false)) {
-				spin_unlock(&kcov_remote_lock);
+				spin_unlock_irqrestore(&kcov_remote_lock,
+							flags);
 				kcov_disable(t, kcov);
 				return -EINVAL;
 			}
 			remote = kcov_remote_add(kcov, remote_arg->handles[i]);
 			if (IS_ERR(remote)) {
-				spin_unlock(&kcov_remote_lock);
+				spin_unlock_irqrestore(&kcov_remote_lock,
+							flags);
 				kcov_disable(t, kcov);
 				return PTR_ERR(remote);
 			}
 		}
 		if (remote_arg->common_handle) {
-			kcov_debug("common handle %llx\n",
-					remote_arg->common_handle);
 			if (!kcov_check_handle(remote_arg->common_handle,
 						true, false, false)) {
-				spin_unlock(&kcov_remote_lock);
+				spin_unlock_irqrestore(&kcov_remote_lock,
+							flags);
 				kcov_disable(t, kcov);
 				return -EINVAL;
 			}
 			remote = kcov_remote_add(kcov,
 					remote_arg->common_handle);
 			if (IS_ERR(remote)) {
-				spin_unlock(&kcov_remote_lock);
+				spin_unlock_irqrestore(&kcov_remote_lock,
+							flags);
 				kcov_disable(t, kcov);
 				return PTR_ERR(remote);
 			}
 			t->kcov_handle = remote_arg->common_handle;
 		}
-		spin_unlock(&kcov_remote_lock);
+		spin_unlock_irqrestore(&kcov_remote_lock, flags);
 		/* Put either in kcov_task_exit() or in KCOV_DISABLE. */
 		kcov_get(kcov);
 		return 0;
@@ -677,6 +688,7 @@ static long kcov_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
 	struct kcov_remote_arg *remote_arg = NULL;
 	unsigned int remote_num_handles;
 	unsigned long remote_arg_size;
+	unsigned long flags;
 
 	if (cmd == KCOV_REMOTE_ENABLE) {
 		if (get_user(remote_num_handles, (unsigned __user *)(arg +
@@ -697,9 +709,9 @@ static long kcov_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
 	}
 
 	kcov = filep->private_data;
-	spin_lock(&kcov->lock);
+	spin_lock_irqsave(&kcov->lock, flags);
 	res = kcov_ioctl_locked(kcov, cmd, arg);
-	spin_unlock(&kcov->lock);
+	spin_unlock_irqrestore(&kcov->lock, flags);
 
 	kfree(remote_arg);
 
@@ -716,8 +728,8 @@ static const struct file_operations kcov_fops = {
 
 /*
  * kcov_remote_start() and kcov_remote_stop() can be used to annotate a section
- * of code in a kernel background thread to allow kcov to be used to collect
- * coverage from that part of code.
+ * of code in a kernel background thread or in a softirq to allow kcov to be
+ * used to collect coverage from that part of code.
  *
  * The handle argument of kcov_remote_start() identifies a code section that is
  * used for coverage collection. A userspace process passes this handle to
@@ -728,9 +740,9 @@ static const struct file_operations kcov_fops = {
  * the type of the kernel thread whose code is being annotated.
  *
  * For global kernel threads that are spawned in a limited number of instances
- * (e.g. one USB hub_event() worker thread is spawned per USB HCD), each
- * instance must be assigned a unique 4-byte instance id. The instance id is
- * then combined with a 1-byte subsystem id to get a handle via
+ * (e.g. one USB hub_event() worker thread is spawned per USB HCD) and for
+ * softirqs, each instance must be assigned a unique 4-byte instance id. The
+ * instance id is then combined with a 1-byte subsystem id to get a handle via
  * kcov_remote_handle(subsystem_id, instance_id).
  *
  * For local kernel threads that are spawned from system calls handler when a
@@ -749,70 +761,136 @@ static const struct file_operations kcov_fops = {
  *
  * See Documentation/dev-tools/kcov.rst for more details.
  *
- * Internally, this function looks up the kcov device associated with the
+ * Internally, kcov_remote_start() looks up the kcov device associated with the
  * provided handle, allocates an area for coverage collection, and saves the
  * pointers to kcov and area into the current task_struct to allow coverage to
  * be collected via __sanitizer_cov_trace_pc()
  * In turns kcov_remote_stop() clears those pointers from task_struct to stop
  * collecting coverage and copies all collected coverage into the kcov area.
  */
+
+static inline bool kcov_mode_enabled(unsigned int mode)
+{
+	return (mode & ~KCOV_IN_CTXSW) != KCOV_MODE_DISABLED;
+}
+
+void kcov_remote_softirq_start(struct task_struct *t)
+{
+	struct kcov_percpu_data *data = this_cpu_ptr(&kcov_percpu_data);
+	unsigned int mode;
+
+	mode = READ_ONCE(t->kcov_mode);
+	barrier();
+	if (kcov_mode_enabled(mode)) {
+		data->saved_mode = mode;
+		data->saved_size = t->kcov_size;
+		data->saved_area = t->kcov_area;
+		data->saved_sequence = t->kcov_sequence;
+		data->saved_kcov = t->kcov;
+		kcov_stop(t);
+	}
+}
+
+void kcov_remote_softirq_stop(struct task_struct *t)
+{
+	struct kcov_percpu_data *data = this_cpu_ptr(&kcov_percpu_data);
+
+	if (data->saved_kcov) {
+		kcov_start(t, data->saved_kcov, data->saved_size,
+				data->saved_area, data->saved_mode,
+				data->saved_sequence);
+		data->saved_mode = 0;
+		data->saved_size = 0;
+		data->saved_area = NULL;
+		data->saved_sequence = 0;
+		data->saved_kcov = NULL;
+	}
+}
+
 void kcov_remote_start(u64 handle)
 {
+	struct task_struct *t = current;
 	struct kcov_remote *remote;
+	struct kcov *kcov;
+	unsigned int mode;
 	void *area;
-	struct task_struct *t;
 	unsigned int size;
-	enum kcov_mode mode;
 	int sequence;
+	unsigned long flags;
 
 	if (WARN_ON(!kcov_check_handle(handle, true, true, true)))
 		return;
-	if (WARN_ON(!in_task()))
+	if (!in_task() && !in_serving_softirq())
 		return;
-	t = current;
+
+	local_irq_save(flags);
+
 	/*
-	 * Check that kcov_remote_start is not called twice
-	 * nor called by user tasks (with enabled kcov).
+	 * Check that kcov_remote_start() is not called twice in background
+	 * threads nor called by user tasks (with enabled kcov).
 	 */
-	if (WARN_ON(t->kcov))
+	mode = READ_ONCE(t->kcov_mode);
+	if (WARN_ON(in_task() && kcov_mode_enabled(mode))) {
+		local_irq_restore(flags);
 		return;
-
-	kcov_debug("handle = %llx\n", handle);
+	}
+	/*
+	 * Check that kcov_remote_start() is not called twice in softirqs.
+	 * Note, that kcov_remote_start() can be called from a softirq that
+	 * happened while collecting coverage from a background thread.
+	 */
+	if (WARN_ON(in_serving_softirq() && t->kcov_softirq)) {
+		local_irq_restore(flags);
+		return;
+	}
 
 	spin_lock(&kcov_remote_lock);
 	remote = kcov_remote_find(handle);
 	if (!remote) {
-		kcov_debug("no remote found");
-		spin_unlock(&kcov_remote_lock);
+		spin_unlock_irqrestore(&kcov_remote_lock, flags);
 		return;
 	}
+	kcov_debug("handle = %llx, context: %s\n", handle,
+			in_task() ? "task" : "softirq");
+	kcov = remote->kcov;
 	/* Put in kcov_remote_stop(). */
-	kcov_get(remote->kcov);
-	t->kcov = remote->kcov;
+	kcov_get(kcov);
 	/*
 	 * Read kcov fields before unlock to prevent races with
 	 * KCOV_DISABLE / kcov_remote_reset().
 	 */
-	size = remote->kcov->remote_size;
-	mode = remote->kcov->mode;
-	sequence = remote->kcov->sequence;
-	area = kcov_remote_area_get(size);
-	spin_unlock(&kcov_remote_lock);
+	mode = kcov->mode;
+	sequence = kcov->sequence;
+	if (in_task()) {
+		size = kcov->remote_size;
+		area = kcov_remote_area_get(size);
+	} else {
+		size = CONFIG_KCOV_IRQ_AREA_SIZE;
+		area = this_cpu_ptr(&kcov_percpu_data)->irq_area;
+	}
+	spin_unlock_irqrestore(&kcov_remote_lock, flags);
 
+	/* Can only happen when in_task(). */
 	if (!area) {
 		area = vmalloc(size * sizeof(unsigned long));
 		if (!area) {
-			t->kcov = NULL;
-			kcov_put(remote->kcov);
+			kcov_put(kcov);
 			return;
 		}
 	}
+
+	local_irq_save(flags);
+
 	/* Reset coverage size. */
 	*(u64 *)area = 0;
 
-	kcov_debug("area = %px, size = %u", area, size);
+	if (in_serving_softirq()) {
+		kcov_remote_softirq_start(t);
+		t->kcov_softirq = 1;
+	}
+	kcov_start(t, kcov, size, area, mode, sequence);
 
-	kcov_start(t, size, area, mode, sequence);
+	local_irq_restore(flags);
 
 }
 EXPORT_SYMBOL(kcov_remote_start);
@@ -876,34 +954,58 @@ static void kcov_move_area(enum kcov_mode mode, void *dst_area,
 void kcov_remote_stop(void)
 {
 	struct task_struct *t = current;
-	struct kcov *kcov = t->kcov;
-	void *area = t->kcov_area;
-	unsigned int size = t->kcov_size;
-	int sequence = t->kcov_sequence;
+	struct kcov *kcov;
+	unsigned int mode;
+	void *area;
+	unsigned int size;
+	int sequence;
+	unsigned long flags;
 
-	if (!kcov) {
-		kcov_debug("no kcov found\n");
+	if (!in_task() && !in_serving_softirq())
+		return;
+
+	local_irq_save(flags);
+
+	mode = READ_ONCE(t->kcov_mode);
+	barrier();
+	if (!kcov_mode_enabled(mode)) {
+		local_irq_restore(flags);
+		return;
+	}
+	kcov = t->kcov;
+	area = t->kcov_area;
+	size = t->kcov_size;
+	sequence = t->kcov_sequence;
+
+	if (WARN_ON(!in_serving_softirq() && t->kcov_softirq)) {
+		local_irq_restore(flags);
 		return;
 	}
 
 	kcov_stop(t);
-	t->kcov = NULL;
+	if (in_serving_softirq()) {
+		t->kcov_softirq = 0;
+		kcov_remote_softirq_stop(t);
+	}
 
 	spin_lock(&kcov->lock);
 	/*
 	 * KCOV_DISABLE could have been called between kcov_remote_start()
-	 * and kcov_remote_stop(), hence the check.
+	 * and kcov_remote_stop(), hence the sequence check.
 	 */
-	kcov_debug("move if: %d == %d && %d\n",
-		sequence, kcov->sequence, (int)kcov->remote);
 	if (sequence == kcov->sequence && kcov->remote)
 		kcov_move_area(kcov->mode, kcov->area, kcov->size, area);
 	spin_unlock(&kcov->lock);
 
-	spin_lock(&kcov_remote_lock);
-	kcov_remote_area_put(area, size);
-	spin_unlock(&kcov_remote_lock);
+	if (in_task()) {
+		spin_lock(&kcov_remote_lock);
+		kcov_remote_area_put(area, size);
+		spin_unlock(&kcov_remote_lock);
+	}
+
+	local_irq_restore(flags);
 
+	/* Get in kcov_remote_start(). */
 	kcov_put(kcov);
 }
 EXPORT_SYMBOL(kcov_remote_stop);
@@ -917,6 +1019,16 @@ EXPORT_SYMBOL(kcov_common_handle);
 
 static int __init kcov_init(void)
 {
+	int cpu;
+
+	for_each_possible_cpu(cpu) {
+		void *area = vmalloc(CONFIG_KCOV_IRQ_AREA_SIZE *
+				sizeof(unsigned long));
+		if (!area)
+			return -ENOMEM;
+		per_cpu_ptr(&kcov_percpu_data, cpu)->irq_area = area;
+	}
+
 	/*
 	 * The kcov debugfs file won't ever get removed and thus,
 	 * there is no need to protect it against removal races. The
diff --git a/kernel/kcsan/Makefile b/kernel/kcsan/Makefile
new file mode 100644
index 000000000000..d4999b38d1be
--- /dev/null
+++ b/kernel/kcsan/Makefile
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: GPL-2.0
+KCSAN_SANITIZE := n
+KCOV_INSTRUMENT := n
+UBSAN_SANITIZE := n
+
+CFLAGS_REMOVE_core.o = $(CC_FLAGS_FTRACE)
+CFLAGS_REMOVE_debugfs.o = $(CC_FLAGS_FTRACE)
+CFLAGS_REMOVE_report.o = $(CC_FLAGS_FTRACE)
+
+CFLAGS_core.o := $(call cc-option,-fno-conserve-stack,) \
+	$(call cc-option,-fno-stack-protector,)
+
+obj-y := core.o debugfs.o report.o
+obj-$(CONFIG_KCSAN_SELFTEST) += test.o
diff --git a/kernel/kcsan/atomic.h b/kernel/kcsan/atomic.h
new file mode 100644
index 000000000000..be9e625227f3
--- /dev/null
+++ b/kernel/kcsan/atomic.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _KERNEL_KCSAN_ATOMIC_H
+#define _KERNEL_KCSAN_ATOMIC_H
+
+#include <linux/jiffies.h>
+#include <linux/sched.h>
+
+/*
+ * Special rules for certain memory where concurrent conflicting accesses are
+ * common, however, the current convention is to not mark them; returns true if
+ * access to @ptr should be considered atomic. Called from slow-path.
+ */
+static bool kcsan_is_atomic_special(const volatile void *ptr)
+{
+	/* volatile globals that have been observed in data races. */
+	return ptr == &jiffies || ptr == &current->state;
+}
+
+#endif /* _KERNEL_KCSAN_ATOMIC_H */
diff --git a/kernel/kcsan/core.c b/kernel/kcsan/core.c
new file mode 100644
index 000000000000..a572aae61b98
--- /dev/null
+++ b/kernel/kcsan/core.c
@@ -0,0 +1,800 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/atomic.h>
+#include <linux/bug.h>
+#include <linux/delay.h>
+#include <linux/export.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/moduleparam.h>
+#include <linux/percpu.h>
+#include <linux/preempt.h>
+#include <linux/random.h>
+#include <linux/sched.h>
+#include <linux/uaccess.h>
+
+#include "atomic.h"
+#include "encoding.h"
+#include "kcsan.h"
+
+static bool kcsan_early_enable = IS_ENABLED(CONFIG_KCSAN_EARLY_ENABLE);
+unsigned int kcsan_udelay_task = CONFIG_KCSAN_UDELAY_TASK;
+unsigned int kcsan_udelay_interrupt = CONFIG_KCSAN_UDELAY_INTERRUPT;
+static long kcsan_skip_watch = CONFIG_KCSAN_SKIP_WATCH;
+static bool kcsan_interrupt_watcher = IS_ENABLED(CONFIG_KCSAN_INTERRUPT_WATCHER);
+
+#ifdef MODULE_PARAM_PREFIX
+#undef MODULE_PARAM_PREFIX
+#endif
+#define MODULE_PARAM_PREFIX "kcsan."
+module_param_named(early_enable, kcsan_early_enable, bool, 0);
+module_param_named(udelay_task, kcsan_udelay_task, uint, 0644);
+module_param_named(udelay_interrupt, kcsan_udelay_interrupt, uint, 0644);
+module_param_named(skip_watch, kcsan_skip_watch, long, 0644);
+module_param_named(interrupt_watcher, kcsan_interrupt_watcher, bool, 0444);
+
+bool kcsan_enabled;
+
+/* Per-CPU kcsan_ctx for interrupts */
+static DEFINE_PER_CPU(struct kcsan_ctx, kcsan_cpu_ctx) = {
+	.disable_count		= 0,
+	.atomic_next		= 0,
+	.atomic_nest_count	= 0,
+	.in_flat_atomic		= false,
+	.access_mask		= 0,
+	.scoped_accesses	= {LIST_POISON1, NULL},
+};
+
+/*
+ * Helper macros to index into adjacent slots, starting from address slot
+ * itself, followed by the right and left slots.
+ *
+ * The purpose is 2-fold:
+ *
+ *	1. if during insertion the address slot is already occupied, check if
+ *	   any adjacent slots are free;
+ *	2. accesses that straddle a slot boundary due to size that exceeds a
+ *	   slot's range may check adjacent slots if any watchpoint matches.
+ *
+ * Note that accesses with very large size may still miss a watchpoint; however,
+ * given this should be rare, this is a reasonable trade-off to make, since this
+ * will avoid:
+ *
+ *	1. excessive contention between watchpoint checks and setup;
+ *	2. larger number of simultaneous watchpoints without sacrificing
+ *	   performance.
+ *
+ * Example: SLOT_IDX values for KCSAN_CHECK_ADJACENT=1, where i is [0, 1, 2]:
+ *
+ *   slot=0:  [ 1,  2,  0]
+ *   slot=9:  [10, 11,  9]
+ *   slot=63: [64, 65, 63]
+ */
+#define SLOT_IDX(slot, i) (slot + ((i + KCSAN_CHECK_ADJACENT) % NUM_SLOTS))
+
+/*
+ * SLOT_IDX_FAST is used in the fast-path. Not first checking the address's primary
+ * slot (middle) is fine if we assume that races occur rarely. The set of
+ * indices {SLOT_IDX(slot, i) | i in [0, NUM_SLOTS)} is equivalent to
+ * {SLOT_IDX_FAST(slot, i) | i in [0, NUM_SLOTS)}.
+ */
+#define SLOT_IDX_FAST(slot, i) (slot + i)
+
+/*
+ * Watchpoints, with each entry encoded as defined in encoding.h: in order to be
+ * able to safely update and access a watchpoint without introducing locking
+ * overhead, we encode each watchpoint as a single atomic long. The initial
+ * zero-initialized state matches INVALID_WATCHPOINT.
+ *
+ * Add NUM_SLOTS-1 entries to account for overflow; this helps avoid having to
+ * use more complicated SLOT_IDX_FAST calculation with modulo in the fast-path.
+ */
+static atomic_long_t watchpoints[CONFIG_KCSAN_NUM_WATCHPOINTS + NUM_SLOTS-1];
+
+/*
+ * Instructions to skip watching counter, used in should_watch(). We use a
+ * per-CPU counter to avoid excessive contention.
+ */
+static DEFINE_PER_CPU(long, kcsan_skip);
+
+static __always_inline atomic_long_t *find_watchpoint(unsigned long addr,
+						      size_t size,
+						      bool expect_write,
+						      long *encoded_watchpoint)
+{
+	const int slot = watchpoint_slot(addr);
+	const unsigned long addr_masked = addr & WATCHPOINT_ADDR_MASK;
+	atomic_long_t *watchpoint;
+	unsigned long wp_addr_masked;
+	size_t wp_size;
+	bool is_write;
+	int i;
+
+	BUILD_BUG_ON(CONFIG_KCSAN_NUM_WATCHPOINTS < NUM_SLOTS);
+
+	for (i = 0; i < NUM_SLOTS; ++i) {
+		watchpoint = &watchpoints[SLOT_IDX_FAST(slot, i)];
+		*encoded_watchpoint = atomic_long_read(watchpoint);
+		if (!decode_watchpoint(*encoded_watchpoint, &wp_addr_masked,
+				       &wp_size, &is_write))
+			continue;
+
+		if (expect_write && !is_write)
+			continue;
+
+		/* Check if the watchpoint matches the access. */
+		if (matching_access(wp_addr_masked, wp_size, addr_masked, size))
+			return watchpoint;
+	}
+
+	return NULL;
+}
+
+static inline atomic_long_t *
+insert_watchpoint(unsigned long addr, size_t size, bool is_write)
+{
+	const int slot = watchpoint_slot(addr);
+	const long encoded_watchpoint = encode_watchpoint(addr, size, is_write);
+	atomic_long_t *watchpoint;
+	int i;
+
+	/* Check slot index logic, ensuring we stay within array bounds. */
+	BUILD_BUG_ON(SLOT_IDX(0, 0) != KCSAN_CHECK_ADJACENT);
+	BUILD_BUG_ON(SLOT_IDX(0, KCSAN_CHECK_ADJACENT+1) != 0);
+	BUILD_BUG_ON(SLOT_IDX(CONFIG_KCSAN_NUM_WATCHPOINTS-1, KCSAN_CHECK_ADJACENT) != ARRAY_SIZE(watchpoints)-1);
+	BUILD_BUG_ON(SLOT_IDX(CONFIG_KCSAN_NUM_WATCHPOINTS-1, KCSAN_CHECK_ADJACENT+1) != ARRAY_SIZE(watchpoints) - NUM_SLOTS);
+
+	for (i = 0; i < NUM_SLOTS; ++i) {
+		long expect_val = INVALID_WATCHPOINT;
+
+		/* Try to acquire this slot. */
+		watchpoint = &watchpoints[SLOT_IDX(slot, i)];
+		if (atomic_long_try_cmpxchg_relaxed(watchpoint, &expect_val, encoded_watchpoint))
+			return watchpoint;
+	}
+
+	return NULL;
+}
+
+/*
+ * Return true if watchpoint was successfully consumed, false otherwise.
+ *
+ * This may return false if:
+ *
+ *	1. another thread already consumed the watchpoint;
+ *	2. the thread that set up the watchpoint already removed it;
+ *	3. the watchpoint was removed and then re-used.
+ */
+static __always_inline bool
+try_consume_watchpoint(atomic_long_t *watchpoint, long encoded_watchpoint)
+{
+	return atomic_long_try_cmpxchg_relaxed(watchpoint, &encoded_watchpoint, CONSUMED_WATCHPOINT);
+}
+
+/* Return true if watchpoint was not touched, false if already consumed. */
+static inline bool consume_watchpoint(atomic_long_t *watchpoint)
+{
+	return atomic_long_xchg_relaxed(watchpoint, CONSUMED_WATCHPOINT) != CONSUMED_WATCHPOINT;
+}
+
+/* Remove the watchpoint -- its slot may be reused after. */
+static inline void remove_watchpoint(atomic_long_t *watchpoint)
+{
+	atomic_long_set(watchpoint, INVALID_WATCHPOINT);
+}
+
+static __always_inline struct kcsan_ctx *get_ctx(void)
+{
+	/*
+	 * In interrupts, use raw_cpu_ptr to avoid unnecessary checks, that would
+	 * also result in calls that generate warnings in uaccess regions.
+	 */
+	return in_task() ? &current->kcsan_ctx : raw_cpu_ptr(&kcsan_cpu_ctx);
+}
+
+/* Check scoped accesses; never inline because this is a slow-path! */
+static noinline void kcsan_check_scoped_accesses(void)
+{
+	struct kcsan_ctx *ctx = get_ctx();
+	struct list_head *prev_save = ctx->scoped_accesses.prev;
+	struct kcsan_scoped_access *scoped_access;
+
+	ctx->scoped_accesses.prev = NULL;  /* Avoid recursion. */
+	list_for_each_entry(scoped_access, &ctx->scoped_accesses, list)
+		__kcsan_check_access(scoped_access->ptr, scoped_access->size, scoped_access->type);
+	ctx->scoped_accesses.prev = prev_save;
+}
+
+/* Rules for generic atomic accesses. Called from fast-path. */
+static __always_inline bool
+is_atomic(const volatile void *ptr, size_t size, int type, struct kcsan_ctx *ctx)
+{
+	if (type & KCSAN_ACCESS_ATOMIC)
+		return true;
+
+	/*
+	 * Unless explicitly declared atomic, never consider an assertion access
+	 * as atomic. This allows using them also in atomic regions, such as
+	 * seqlocks, without implicitly changing their semantics.
+	 */
+	if (type & KCSAN_ACCESS_ASSERT)
+		return false;
+
+	if (IS_ENABLED(CONFIG_KCSAN_ASSUME_PLAIN_WRITES_ATOMIC) &&
+	    (type & KCSAN_ACCESS_WRITE) && size <= sizeof(long) &&
+	    IS_ALIGNED((unsigned long)ptr, size))
+		return true; /* Assume aligned writes up to word size are atomic. */
+
+	if (ctx->atomic_next > 0) {
+		/*
+		 * Because we do not have separate contexts for nested
+		 * interrupts, in case atomic_next is set, we simply assume that
+		 * the outer interrupt set atomic_next. In the worst case, we
+		 * will conservatively consider operations as atomic. This is a
+		 * reasonable trade-off to make, since this case should be
+		 * extremely rare; however, even if extremely rare, it could
+		 * lead to false positives otherwise.
+		 */
+		if ((hardirq_count() >> HARDIRQ_SHIFT) < 2)
+			--ctx->atomic_next; /* in task, or outer interrupt */
+		return true;
+	}
+
+	return ctx->atomic_nest_count > 0 || ctx->in_flat_atomic;
+}
+
+static __always_inline bool
+should_watch(const volatile void *ptr, size_t size, int type, struct kcsan_ctx *ctx)
+{
+	/*
+	 * Never set up watchpoints when memory operations are atomic.
+	 *
+	 * Need to check this first, before kcsan_skip check below: (1) atomics
+	 * should not count towards skipped instructions, and (2) to actually
+	 * decrement kcsan_atomic_next for consecutive instruction stream.
+	 */
+	if (is_atomic(ptr, size, type, ctx))
+		return false;
+
+	if (this_cpu_dec_return(kcsan_skip) >= 0)
+		return false;
+
+	/*
+	 * NOTE: If we get here, kcsan_skip must always be reset in slow path
+	 * via reset_kcsan_skip() to avoid underflow.
+	 */
+
+	/* this operation should be watched */
+	return true;
+}
+
+static inline void reset_kcsan_skip(void)
+{
+	long skip_count = kcsan_skip_watch -
+			  (IS_ENABLED(CONFIG_KCSAN_SKIP_WATCH_RANDOMIZE) ?
+				   prandom_u32_max(kcsan_skip_watch) :
+				   0);
+	this_cpu_write(kcsan_skip, skip_count);
+}
+
+static __always_inline bool kcsan_is_enabled(void)
+{
+	return READ_ONCE(kcsan_enabled) && get_ctx()->disable_count == 0;
+}
+
+static inline unsigned int get_delay(void)
+{
+	unsigned int delay = in_task() ? kcsan_udelay_task : kcsan_udelay_interrupt;
+	return delay - (IS_ENABLED(CONFIG_KCSAN_DELAY_RANDOMIZE) ?
+				prandom_u32_max(delay) :
+				0);
+}
+
+/*
+ * Pull everything together: check_access() below contains the performance
+ * critical operations; the fast-path (including check_access) functions should
+ * all be inlinable by the instrumentation functions.
+ *
+ * The slow-path (kcsan_found_watchpoint, kcsan_setup_watchpoint) are
+ * non-inlinable -- note that, we prefix these with "kcsan_" to ensure they can
+ * be filtered from the stacktrace, as well as give them unique names for the
+ * UACCESS whitelist of objtool. Each function uses user_access_save/restore(),
+ * since they do not access any user memory, but instrumentation is still
+ * emitted in UACCESS regions.
+ */
+
+static noinline void kcsan_found_watchpoint(const volatile void *ptr,
+					    size_t size,
+					    int type,
+					    atomic_long_t *watchpoint,
+					    long encoded_watchpoint)
+{
+	unsigned long flags;
+	bool consumed;
+
+	if (!kcsan_is_enabled())
+		return;
+
+	/*
+	 * The access_mask check relies on value-change comparison. To avoid
+	 * reporting a race where e.g. the writer set up the watchpoint, but the
+	 * reader has access_mask!=0, we have to ignore the found watchpoint.
+	 */
+	if (get_ctx()->access_mask != 0)
+		return;
+
+	/*
+	 * Consume the watchpoint as soon as possible, to minimize the chances
+	 * of !consumed. Consuming the watchpoint must always be guarded by
+	 * kcsan_is_enabled() check, as otherwise we might erroneously
+	 * triggering reports when disabled.
+	 */
+	consumed = try_consume_watchpoint(watchpoint, encoded_watchpoint);
+
+	/* keep this after try_consume_watchpoint */
+	flags = user_access_save();
+
+	if (consumed) {
+		kcsan_report(ptr, size, type, KCSAN_VALUE_CHANGE_MAYBE,
+			     KCSAN_REPORT_CONSUMED_WATCHPOINT,
+			     watchpoint - watchpoints);
+	} else {
+		/*
+		 * The other thread may not print any diagnostics, as it has
+		 * already removed the watchpoint, or another thread consumed
+		 * the watchpoint before this thread.
+		 */
+		kcsan_counter_inc(KCSAN_COUNTER_REPORT_RACES);
+	}
+
+	if ((type & KCSAN_ACCESS_ASSERT) != 0)
+		kcsan_counter_inc(KCSAN_COUNTER_ASSERT_FAILURES);
+	else
+		kcsan_counter_inc(KCSAN_COUNTER_DATA_RACES);
+
+	user_access_restore(flags);
+}
+
+static noinline void
+kcsan_setup_watchpoint(const volatile void *ptr, size_t size, int type)
+{
+	const bool is_write = (type & KCSAN_ACCESS_WRITE) != 0;
+	const bool is_assert = (type & KCSAN_ACCESS_ASSERT) != 0;
+	atomic_long_t *watchpoint;
+	union {
+		u8 _1;
+		u16 _2;
+		u32 _4;
+		u64 _8;
+	} expect_value;
+	unsigned long access_mask;
+	enum kcsan_value_change value_change = KCSAN_VALUE_CHANGE_MAYBE;
+	unsigned long ua_flags = user_access_save();
+	unsigned long irq_flags = 0;
+
+	/*
+	 * Always reset kcsan_skip counter in slow-path to avoid underflow; see
+	 * should_watch().
+	 */
+	reset_kcsan_skip();
+
+	if (!kcsan_is_enabled())
+		goto out;
+
+	/*
+	 * Special atomic rules: unlikely to be true, so we check them here in
+	 * the slow-path, and not in the fast-path in is_atomic(). Call after
+	 * kcsan_is_enabled(), as we may access memory that is not yet
+	 * initialized during early boot.
+	 */
+	if (!is_assert && kcsan_is_atomic_special(ptr))
+		goto out;
+
+	if (!check_encodable((unsigned long)ptr, size)) {
+		kcsan_counter_inc(KCSAN_COUNTER_UNENCODABLE_ACCESSES);
+		goto out;
+	}
+
+	if (!kcsan_interrupt_watcher)
+		/* Use raw to avoid lockdep recursion via IRQ flags tracing. */
+		raw_local_irq_save(irq_flags);
+
+	watchpoint = insert_watchpoint((unsigned long)ptr, size, is_write);
+	if (watchpoint == NULL) {
+		/*
+		 * Out of capacity: the size of 'watchpoints', and the frequency
+		 * with which should_watch() returns true should be tweaked so
+		 * that this case happens very rarely.
+		 */
+		kcsan_counter_inc(KCSAN_COUNTER_NO_CAPACITY);
+		goto out_unlock;
+	}
+
+	kcsan_counter_inc(KCSAN_COUNTER_SETUP_WATCHPOINTS);
+	kcsan_counter_inc(KCSAN_COUNTER_USED_WATCHPOINTS);
+
+	/*
+	 * Read the current value, to later check and infer a race if the data
+	 * was modified via a non-instrumented access, e.g. from a device.
+	 */
+	expect_value._8 = 0;
+	switch (size) {
+	case 1:
+		expect_value._1 = READ_ONCE(*(const u8 *)ptr);
+		break;
+	case 2:
+		expect_value._2 = READ_ONCE(*(const u16 *)ptr);
+		break;
+	case 4:
+		expect_value._4 = READ_ONCE(*(const u32 *)ptr);
+		break;
+	case 8:
+		expect_value._8 = READ_ONCE(*(const u64 *)ptr);
+		break;
+	default:
+		break; /* ignore; we do not diff the values */
+	}
+
+	if (IS_ENABLED(CONFIG_KCSAN_DEBUG)) {
+		kcsan_disable_current();
+		pr_err("KCSAN: watching %s, size: %zu, addr: %px [slot: %d, encoded: %lx]\n",
+		       is_write ? "write" : "read", size, ptr,
+		       watchpoint_slot((unsigned long)ptr),
+		       encode_watchpoint((unsigned long)ptr, size, is_write));
+		kcsan_enable_current();
+	}
+
+	/*
+	 * Delay this thread, to increase probability of observing a racy
+	 * conflicting access.
+	 */
+	udelay(get_delay());
+
+	/*
+	 * Re-read value, and check if it is as expected; if not, we infer a
+	 * racy access.
+	 */
+	access_mask = get_ctx()->access_mask;
+	switch (size) {
+	case 1:
+		expect_value._1 ^= READ_ONCE(*(const u8 *)ptr);
+		if (access_mask)
+			expect_value._1 &= (u8)access_mask;
+		break;
+	case 2:
+		expect_value._2 ^= READ_ONCE(*(const u16 *)ptr);
+		if (access_mask)
+			expect_value._2 &= (u16)access_mask;
+		break;
+	case 4:
+		expect_value._4 ^= READ_ONCE(*(const u32 *)ptr);
+		if (access_mask)
+			expect_value._4 &= (u32)access_mask;
+		break;
+	case 8:
+		expect_value._8 ^= READ_ONCE(*(const u64 *)ptr);
+		if (access_mask)
+			expect_value._8 &= (u64)access_mask;
+		break;
+	default:
+		break; /* ignore; we do not diff the values */
+	}
+
+	/* Were we able to observe a value-change? */
+	if (expect_value._8 != 0)
+		value_change = KCSAN_VALUE_CHANGE_TRUE;
+
+	/* Check if this access raced with another. */
+	if (!consume_watchpoint(watchpoint)) {
+		/*
+		 * Depending on the access type, map a value_change of MAYBE to
+		 * TRUE (always report) or FALSE (never report).
+		 */
+		if (value_change == KCSAN_VALUE_CHANGE_MAYBE) {
+			if (access_mask != 0) {
+				/*
+				 * For access with access_mask, we require a
+				 * value-change, as it is likely that races on
+				 * ~access_mask bits are expected.
+				 */
+				value_change = KCSAN_VALUE_CHANGE_FALSE;
+			} else if (size > 8 || is_assert) {
+				/* Always assume a value-change. */
+				value_change = KCSAN_VALUE_CHANGE_TRUE;
+			}
+		}
+
+		/*
+		 * No need to increment 'data_races' counter, as the racing
+		 * thread already did.
+		 *
+		 * Count 'assert_failures' for each failed ASSERT access,
+		 * therefore both this thread and the racing thread may
+		 * increment this counter.
+		 */
+		if (is_assert && value_change == KCSAN_VALUE_CHANGE_TRUE)
+			kcsan_counter_inc(KCSAN_COUNTER_ASSERT_FAILURES);
+
+		kcsan_report(ptr, size, type, value_change, KCSAN_REPORT_RACE_SIGNAL,
+			     watchpoint - watchpoints);
+	} else if (value_change == KCSAN_VALUE_CHANGE_TRUE) {
+		/* Inferring a race, since the value should not have changed. */
+
+		kcsan_counter_inc(KCSAN_COUNTER_RACES_UNKNOWN_ORIGIN);
+		if (is_assert)
+			kcsan_counter_inc(KCSAN_COUNTER_ASSERT_FAILURES);
+
+		if (IS_ENABLED(CONFIG_KCSAN_REPORT_RACE_UNKNOWN_ORIGIN) || is_assert)
+			kcsan_report(ptr, size, type, KCSAN_VALUE_CHANGE_TRUE,
+				     KCSAN_REPORT_RACE_UNKNOWN_ORIGIN,
+				     watchpoint - watchpoints);
+	}
+
+	/*
+	 * Remove watchpoint; must be after reporting, since the slot may be
+	 * reused after this point.
+	 */
+	remove_watchpoint(watchpoint);
+	kcsan_counter_dec(KCSAN_COUNTER_USED_WATCHPOINTS);
+out_unlock:
+	if (!kcsan_interrupt_watcher)
+		raw_local_irq_restore(irq_flags);
+out:
+	user_access_restore(ua_flags);
+}
+
+static __always_inline void check_access(const volatile void *ptr, size_t size,
+					 int type)
+{
+	const bool is_write = (type & KCSAN_ACCESS_WRITE) != 0;
+	atomic_long_t *watchpoint;
+	long encoded_watchpoint;
+
+	/*
+	 * Do nothing for 0 sized check; this comparison will be optimized out
+	 * for constant sized instrumentation (__tsan_{read,write}N).
+	 */
+	if (unlikely(size == 0))
+		return;
+
+	/*
+	 * Avoid user_access_save in fast-path: find_watchpoint is safe without
+	 * user_access_save, as the address that ptr points to is only used to
+	 * check if a watchpoint exists; ptr is never dereferenced.
+	 */
+	watchpoint = find_watchpoint((unsigned long)ptr, size, !is_write,
+				     &encoded_watchpoint);
+	/*
+	 * It is safe to check kcsan_is_enabled() after find_watchpoint in the
+	 * slow-path, as long as no state changes that cause a race to be
+	 * detected and reported have occurred until kcsan_is_enabled() is
+	 * checked.
+	 */
+
+	if (unlikely(watchpoint != NULL))
+		kcsan_found_watchpoint(ptr, size, type, watchpoint,
+				       encoded_watchpoint);
+	else {
+		struct kcsan_ctx *ctx = get_ctx(); /* Call only once in fast-path. */
+
+		if (unlikely(should_watch(ptr, size, type, ctx)))
+			kcsan_setup_watchpoint(ptr, size, type);
+		else if (unlikely(ctx->scoped_accesses.prev))
+			kcsan_check_scoped_accesses();
+	}
+}
+
+/* === Public interface ===================================================== */
+
+void __init kcsan_init(void)
+{
+	BUG_ON(!in_task());
+
+	kcsan_debugfs_init();
+
+	/*
+	 * We are in the init task, and no other tasks should be running;
+	 * WRITE_ONCE without memory barrier is sufficient.
+	 */
+	if (kcsan_early_enable)
+		WRITE_ONCE(kcsan_enabled, true);
+}
+
+/* === Exported interface =================================================== */
+
+void kcsan_disable_current(void)
+{
+	++get_ctx()->disable_count;
+}
+EXPORT_SYMBOL(kcsan_disable_current);
+
+void kcsan_enable_current(void)
+{
+	if (get_ctx()->disable_count-- == 0) {
+		/*
+		 * Warn if kcsan_enable_current() calls are unbalanced with
+		 * kcsan_disable_current() calls, which causes disable_count to
+		 * become negative and should not happen.
+		 */
+		kcsan_disable_current(); /* restore to 0, KCSAN still enabled */
+		kcsan_disable_current(); /* disable to generate warning */
+		WARN(1, "Unbalanced %s()", __func__);
+		kcsan_enable_current();
+	}
+}
+EXPORT_SYMBOL(kcsan_enable_current);
+
+void kcsan_nestable_atomic_begin(void)
+{
+	/*
+	 * Do *not* check and warn if we are in a flat atomic region: nestable
+	 * and flat atomic regions are independent from each other.
+	 * See include/linux/kcsan.h: struct kcsan_ctx comments for more
+	 * comments.
+	 */
+
+	++get_ctx()->atomic_nest_count;
+}
+EXPORT_SYMBOL(kcsan_nestable_atomic_begin);
+
+void kcsan_nestable_atomic_end(void)
+{
+	if (get_ctx()->atomic_nest_count-- == 0) {
+		/*
+		 * Warn if kcsan_nestable_atomic_end() calls are unbalanced with
+		 * kcsan_nestable_atomic_begin() calls, which causes
+		 * atomic_nest_count to become negative and should not happen.
+		 */
+		kcsan_nestable_atomic_begin(); /* restore to 0 */
+		kcsan_disable_current(); /* disable to generate warning */
+		WARN(1, "Unbalanced %s()", __func__);
+		kcsan_enable_current();
+	}
+}
+EXPORT_SYMBOL(kcsan_nestable_atomic_end);
+
+void kcsan_flat_atomic_begin(void)
+{
+	get_ctx()->in_flat_atomic = true;
+}
+EXPORT_SYMBOL(kcsan_flat_atomic_begin);
+
+void kcsan_flat_atomic_end(void)
+{
+	get_ctx()->in_flat_atomic = false;
+}
+EXPORT_SYMBOL(kcsan_flat_atomic_end);
+
+void kcsan_atomic_next(int n)
+{
+	get_ctx()->atomic_next = n;
+}
+EXPORT_SYMBOL(kcsan_atomic_next);
+
+void kcsan_set_access_mask(unsigned long mask)
+{
+	get_ctx()->access_mask = mask;
+}
+EXPORT_SYMBOL(kcsan_set_access_mask);
+
+struct kcsan_scoped_access *
+kcsan_begin_scoped_access(const volatile void *ptr, size_t size, int type,
+			  struct kcsan_scoped_access *sa)
+{
+	struct kcsan_ctx *ctx = get_ctx();
+
+	__kcsan_check_access(ptr, size, type);
+
+	ctx->disable_count++; /* Disable KCSAN, in case list debugging is on. */
+
+	INIT_LIST_HEAD(&sa->list);
+	sa->ptr = ptr;
+	sa->size = size;
+	sa->type = type;
+
+	if (!ctx->scoped_accesses.prev) /* Lazy initialize list head. */
+		INIT_LIST_HEAD(&ctx->scoped_accesses);
+	list_add(&sa->list, &ctx->scoped_accesses);
+
+	ctx->disable_count--;
+	return sa;
+}
+EXPORT_SYMBOL(kcsan_begin_scoped_access);
+
+void kcsan_end_scoped_access(struct kcsan_scoped_access *sa)
+{
+	struct kcsan_ctx *ctx = get_ctx();
+
+	if (WARN(!ctx->scoped_accesses.prev, "Unbalanced %s()?", __func__))
+		return;
+
+	ctx->disable_count++; /* Disable KCSAN, in case list debugging is on. */
+
+	list_del(&sa->list);
+	if (list_empty(&ctx->scoped_accesses))
+		/*
+		 * Ensure we do not enter kcsan_check_scoped_accesses()
+		 * slow-path if unnecessary, and avoids requiring list_empty()
+		 * in the fast-path (to avoid a READ_ONCE() and potential
+		 * uaccess warning).
+		 */
+		ctx->scoped_accesses.prev = NULL;
+
+	ctx->disable_count--;
+
+	__kcsan_check_access(sa->ptr, sa->size, sa->type);
+}
+EXPORT_SYMBOL(kcsan_end_scoped_access);
+
+void __kcsan_check_access(const volatile void *ptr, size_t size, int type)
+{
+	check_access(ptr, size, type);
+}
+EXPORT_SYMBOL(__kcsan_check_access);
+
+/*
+ * KCSAN uses the same instrumentation that is emitted by supported compilers
+ * for ThreadSanitizer (TSAN).
+ *
+ * When enabled, the compiler emits instrumentation calls (the functions
+ * prefixed with "__tsan" below) for all loads and stores that it generated;
+ * inline asm is not instrumented.
+ *
+ * Note that, not all supported compiler versions distinguish aligned/unaligned
+ * accesses, but e.g. recent versions of Clang do. We simply alias the unaligned
+ * version to the generic version, which can handle both.
+ */
+
+#define DEFINE_TSAN_READ_WRITE(size)                                           \
+	void __tsan_read##size(void *ptr)                                      \
+	{                                                                      \
+		check_access(ptr, size, 0);                                    \
+	}                                                                      \
+	EXPORT_SYMBOL(__tsan_read##size);                                      \
+	void __tsan_unaligned_read##size(void *ptr)                            \
+		__alias(__tsan_read##size);                                    \
+	EXPORT_SYMBOL(__tsan_unaligned_read##size);                            \
+	void __tsan_write##size(void *ptr)                                     \
+	{                                                                      \
+		check_access(ptr, size, KCSAN_ACCESS_WRITE);                   \
+	}                                                                      \
+	EXPORT_SYMBOL(__tsan_write##size);                                     \
+	void __tsan_unaligned_write##size(void *ptr)                           \
+		__alias(__tsan_write##size);                                   \
+	EXPORT_SYMBOL(__tsan_unaligned_write##size)
+
+DEFINE_TSAN_READ_WRITE(1);
+DEFINE_TSAN_READ_WRITE(2);
+DEFINE_TSAN_READ_WRITE(4);
+DEFINE_TSAN_READ_WRITE(8);
+DEFINE_TSAN_READ_WRITE(16);
+
+void __tsan_read_range(void *ptr, size_t size)
+{
+	check_access(ptr, size, 0);
+}
+EXPORT_SYMBOL(__tsan_read_range);
+
+void __tsan_write_range(void *ptr, size_t size)
+{
+	check_access(ptr, size, KCSAN_ACCESS_WRITE);
+}
+EXPORT_SYMBOL(__tsan_write_range);
+
+/*
+ * The below are not required by KCSAN, but can still be emitted by the
+ * compiler.
+ */
+void __tsan_func_entry(void *call_pc)
+{
+}
+EXPORT_SYMBOL(__tsan_func_entry);
+void __tsan_func_exit(void)
+{
+}
+EXPORT_SYMBOL(__tsan_func_exit);
+void __tsan_init(void)
+{
+}
+EXPORT_SYMBOL(__tsan_init);
diff --git a/kernel/kcsan/debugfs.c b/kernel/kcsan/debugfs.c
new file mode 100644
index 000000000000..1a08664a7fab
--- /dev/null
+++ b/kernel/kcsan/debugfs.c
@@ -0,0 +1,349 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/atomic.h>
+#include <linux/bsearch.h>
+#include <linux/bug.h>
+#include <linux/debugfs.h>
+#include <linux/init.h>
+#include <linux/kallsyms.h>
+#include <linux/sched.h>
+#include <linux/seq_file.h>
+#include <linux/slab.h>
+#include <linux/sort.h>
+#include <linux/string.h>
+#include <linux/uaccess.h>
+
+#include "kcsan.h"
+
+/*
+ * Statistics counters.
+ */
+static atomic_long_t counters[KCSAN_COUNTER_COUNT];
+
+/*
+ * Addresses for filtering functions from reporting. This list can be used as a
+ * whitelist or blacklist.
+ */
+static struct {
+	unsigned long	*addrs;		/* array of addresses */
+	size_t		size;		/* current size */
+	int		used;		/* number of elements used */
+	bool		sorted;		/* if elements are sorted */
+	bool		whitelist;	/* if list is a blacklist or whitelist */
+} report_filterlist = {
+	.addrs		= NULL,
+	.size		= 8,		/* small initial size */
+	.used		= 0,
+	.sorted		= false,
+	.whitelist	= false,	/* default is blacklist */
+};
+static DEFINE_SPINLOCK(report_filterlist_lock);
+
+static const char *counter_to_name(enum kcsan_counter_id id)
+{
+	switch (id) {
+	case KCSAN_COUNTER_USED_WATCHPOINTS:		return "used_watchpoints";
+	case KCSAN_COUNTER_SETUP_WATCHPOINTS:		return "setup_watchpoints";
+	case KCSAN_COUNTER_DATA_RACES:			return "data_races";
+	case KCSAN_COUNTER_ASSERT_FAILURES:		return "assert_failures";
+	case KCSAN_COUNTER_NO_CAPACITY:			return "no_capacity";
+	case KCSAN_COUNTER_REPORT_RACES:		return "report_races";
+	case KCSAN_COUNTER_RACES_UNKNOWN_ORIGIN:	return "races_unknown_origin";
+	case KCSAN_COUNTER_UNENCODABLE_ACCESSES:	return "unencodable_accesses";
+	case KCSAN_COUNTER_ENCODING_FALSE_POSITIVES:	return "encoding_false_positives";
+	case KCSAN_COUNTER_COUNT:
+		BUG();
+	}
+	return NULL;
+}
+
+void kcsan_counter_inc(enum kcsan_counter_id id)
+{
+	atomic_long_inc(&counters[id]);
+}
+
+void kcsan_counter_dec(enum kcsan_counter_id id)
+{
+	atomic_long_dec(&counters[id]);
+}
+
+/*
+ * The microbenchmark allows benchmarking KCSAN core runtime only. To run
+ * multiple threads, pipe 'microbench=<iters>' from multiple tasks into the
+ * debugfs file. This will not generate any conflicts, and tests fast-path only.
+ */
+static noinline void microbenchmark(unsigned long iters)
+{
+	const struct kcsan_ctx ctx_save = current->kcsan_ctx;
+	const bool was_enabled = READ_ONCE(kcsan_enabled);
+	cycles_t cycles;
+
+	/* We may have been called from an atomic region; reset context. */
+	memset(&current->kcsan_ctx, 0, sizeof(current->kcsan_ctx));
+	/*
+	 * Disable to benchmark fast-path for all accesses, and (expected
+	 * negligible) call into slow-path, but never set up watchpoints.
+	 */
+	WRITE_ONCE(kcsan_enabled, false);
+
+	pr_info("KCSAN: %s begin | iters: %lu\n", __func__, iters);
+
+	cycles = get_cycles();
+	while (iters--) {
+		unsigned long addr = iters & ((PAGE_SIZE << 8) - 1);
+		int type = !(iters & 0x7f) ? KCSAN_ACCESS_ATOMIC :
+				(!(iters & 0xf) ? KCSAN_ACCESS_WRITE : 0);
+		__kcsan_check_access((void *)addr, sizeof(long), type);
+	}
+	cycles = get_cycles() - cycles;
+
+	pr_info("KCSAN: %s end   | cycles: %llu\n", __func__, cycles);
+
+	WRITE_ONCE(kcsan_enabled, was_enabled);
+	/* restore context */
+	current->kcsan_ctx = ctx_save;
+}
+
+/*
+ * Simple test to create conflicting accesses. Write 'test=<iters>' to KCSAN's
+ * debugfs file from multiple tasks to generate real conflicts and show reports.
+ */
+static long test_dummy;
+static long test_flags;
+static long test_scoped;
+static noinline void test_thread(unsigned long iters)
+{
+	const long CHANGE_BITS = 0xff00ff00ff00ff00L;
+	const struct kcsan_ctx ctx_save = current->kcsan_ctx;
+	cycles_t cycles;
+
+	/* We may have been called from an atomic region; reset context. */
+	memset(&current->kcsan_ctx, 0, sizeof(current->kcsan_ctx));
+
+	pr_info("KCSAN: %s begin | iters: %lu\n", __func__, iters);
+	pr_info("test_dummy@%px, test_flags@%px, test_scoped@%px,\n",
+		&test_dummy, &test_flags, &test_scoped);
+
+	cycles = get_cycles();
+	while (iters--) {
+		/* These all should generate reports. */
+		__kcsan_check_read(&test_dummy, sizeof(test_dummy));
+		ASSERT_EXCLUSIVE_WRITER(test_dummy);
+		ASSERT_EXCLUSIVE_ACCESS(test_dummy);
+
+		ASSERT_EXCLUSIVE_BITS(test_flags, ~CHANGE_BITS); /* no report */
+		__kcsan_check_read(&test_flags, sizeof(test_flags)); /* no report */
+
+		ASSERT_EXCLUSIVE_BITS(test_flags, CHANGE_BITS); /* report */
+		__kcsan_check_read(&test_flags, sizeof(test_flags)); /* no report */
+
+		/* not actually instrumented */
+		WRITE_ONCE(test_dummy, iters);  /* to observe value-change */
+		__kcsan_check_write(&test_dummy, sizeof(test_dummy));
+
+		test_flags ^= CHANGE_BITS; /* generate value-change */
+		__kcsan_check_write(&test_flags, sizeof(test_flags));
+
+		BUG_ON(current->kcsan_ctx.scoped_accesses.prev);
+		{
+			/* Should generate reports anywhere in this block. */
+			ASSERT_EXCLUSIVE_WRITER_SCOPED(test_scoped);
+			ASSERT_EXCLUSIVE_ACCESS_SCOPED(test_scoped);
+			BUG_ON(!current->kcsan_ctx.scoped_accesses.prev);
+			/* Unrelated accesses. */
+			__kcsan_check_access(&cycles, sizeof(cycles), 0);
+			__kcsan_check_access(&cycles, sizeof(cycles), KCSAN_ACCESS_ATOMIC);
+		}
+		BUG_ON(current->kcsan_ctx.scoped_accesses.prev);
+	}
+	cycles = get_cycles() - cycles;
+
+	pr_info("KCSAN: %s end   | cycles: %llu\n", __func__, cycles);
+
+	/* restore context */
+	current->kcsan_ctx = ctx_save;
+}
+
+static int cmp_filterlist_addrs(const void *rhs, const void *lhs)
+{
+	const unsigned long a = *(const unsigned long *)rhs;
+	const unsigned long b = *(const unsigned long *)lhs;
+
+	return a < b ? -1 : a == b ? 0 : 1;
+}
+
+bool kcsan_skip_report_debugfs(unsigned long func_addr)
+{
+	unsigned long symbolsize, offset;
+	unsigned long flags;
+	bool ret = false;
+
+	if (!kallsyms_lookup_size_offset(func_addr, &symbolsize, &offset))
+		return false;
+	func_addr -= offset; /* Get function start */
+
+	spin_lock_irqsave(&report_filterlist_lock, flags);
+	if (report_filterlist.used == 0)
+		goto out;
+
+	/* Sort array if it is unsorted, and then do a binary search. */
+	if (!report_filterlist.sorted) {
+		sort(report_filterlist.addrs, report_filterlist.used,
+		     sizeof(unsigned long), cmp_filterlist_addrs, NULL);
+		report_filterlist.sorted = true;
+	}
+	ret = !!bsearch(&func_addr, report_filterlist.addrs,
+			report_filterlist.used, sizeof(unsigned long),
+			cmp_filterlist_addrs);
+	if (report_filterlist.whitelist)
+		ret = !ret;
+
+out:
+	spin_unlock_irqrestore(&report_filterlist_lock, flags);
+	return ret;
+}
+
+static void set_report_filterlist_whitelist(bool whitelist)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&report_filterlist_lock, flags);
+	report_filterlist.whitelist = whitelist;
+	spin_unlock_irqrestore(&report_filterlist_lock, flags);
+}
+
+/* Returns 0 on success, error-code otherwise. */
+static ssize_t insert_report_filterlist(const char *func)
+{
+	unsigned long flags;
+	unsigned long addr = kallsyms_lookup_name(func);
+	ssize_t ret = 0;
+
+	if (!addr) {
+		pr_err("KCSAN: could not find function: '%s'\n", func);
+		return -ENOENT;
+	}
+
+	spin_lock_irqsave(&report_filterlist_lock, flags);
+
+	if (report_filterlist.addrs == NULL) {
+		/* initial allocation */
+		report_filterlist.addrs =
+			kmalloc_array(report_filterlist.size,
+				      sizeof(unsigned long), GFP_KERNEL);
+		if (report_filterlist.addrs == NULL) {
+			ret = -ENOMEM;
+			goto out;
+		}
+	} else if (report_filterlist.used == report_filterlist.size) {
+		/* resize filterlist */
+		size_t new_size = report_filterlist.size * 2;
+		unsigned long *new_addrs =
+			krealloc(report_filterlist.addrs,
+				 new_size * sizeof(unsigned long), GFP_KERNEL);
+
+		if (new_addrs == NULL) {
+			/* leave filterlist itself untouched */
+			ret = -ENOMEM;
+			goto out;
+		}
+
+		report_filterlist.size = new_size;
+		report_filterlist.addrs = new_addrs;
+	}
+
+	/* Note: deduplicating should be done in userspace. */
+	report_filterlist.addrs[report_filterlist.used++] =
+		kallsyms_lookup_name(func);
+	report_filterlist.sorted = false;
+
+out:
+	spin_unlock_irqrestore(&report_filterlist_lock, flags);
+
+	return ret;
+}
+
+static int show_info(struct seq_file *file, void *v)
+{
+	int i;
+	unsigned long flags;
+
+	/* show stats */
+	seq_printf(file, "enabled: %i\n", READ_ONCE(kcsan_enabled));
+	for (i = 0; i < KCSAN_COUNTER_COUNT; ++i)
+		seq_printf(file, "%s: %ld\n", counter_to_name(i),
+			   atomic_long_read(&counters[i]));
+
+	/* show filter functions, and filter type */
+	spin_lock_irqsave(&report_filterlist_lock, flags);
+	seq_printf(file, "\n%s functions: %s\n",
+		   report_filterlist.whitelist ? "whitelisted" : "blacklisted",
+		   report_filterlist.used == 0 ? "none" : "");
+	for (i = 0; i < report_filterlist.used; ++i)
+		seq_printf(file, " %ps\n", (void *)report_filterlist.addrs[i]);
+	spin_unlock_irqrestore(&report_filterlist_lock, flags);
+
+	return 0;
+}
+
+static int debugfs_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, show_info, NULL);
+}
+
+static ssize_t
+debugfs_write(struct file *file, const char __user *buf, size_t count, loff_t *off)
+{
+	char kbuf[KSYM_NAME_LEN];
+	char *arg;
+	int read_len = count < (sizeof(kbuf) - 1) ? count : (sizeof(kbuf) - 1);
+
+	if (copy_from_user(kbuf, buf, read_len))
+		return -EFAULT;
+	kbuf[read_len] = '\0';
+	arg = strstrip(kbuf);
+
+	if (!strcmp(arg, "on")) {
+		WRITE_ONCE(kcsan_enabled, true);
+	} else if (!strcmp(arg, "off")) {
+		WRITE_ONCE(kcsan_enabled, false);
+	} else if (!strncmp(arg, "microbench=", sizeof("microbench=") - 1)) {
+		unsigned long iters;
+
+		if (kstrtoul(&arg[sizeof("microbench=") - 1], 0, &iters))
+			return -EINVAL;
+		microbenchmark(iters);
+	} else if (!strncmp(arg, "test=", sizeof("test=") - 1)) {
+		unsigned long iters;
+
+		if (kstrtoul(&arg[sizeof("test=") - 1], 0, &iters))
+			return -EINVAL;
+		test_thread(iters);
+	} else if (!strcmp(arg, "whitelist")) {
+		set_report_filterlist_whitelist(true);
+	} else if (!strcmp(arg, "blacklist")) {
+		set_report_filterlist_whitelist(false);
+	} else if (arg[0] == '!') {
+		ssize_t ret = insert_report_filterlist(&arg[1]);
+
+		if (ret < 0)
+			return ret;
+	} else {
+		return -EINVAL;
+	}
+
+	return count;
+}
+
+static const struct file_operations debugfs_ops =
+{
+	.read	 = seq_read,
+	.open	 = debugfs_open,
+	.write	 = debugfs_write,
+	.release = single_release
+};
+
+void __init kcsan_debugfs_init(void)
+{
+	debugfs_create_file("kcsan", 0644, NULL, NULL, &debugfs_ops);
+}
diff --git a/kernel/kcsan/encoding.h b/kernel/kcsan/encoding.h
new file mode 100644
index 000000000000..f03562aaf2eb
--- /dev/null
+++ b/kernel/kcsan/encoding.h
@@ -0,0 +1,95 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _KERNEL_KCSAN_ENCODING_H
+#define _KERNEL_KCSAN_ENCODING_H
+
+#include <linux/bits.h>
+#include <linux/log2.h>
+#include <linux/mm.h>
+
+#include "kcsan.h"
+
+#define SLOT_RANGE PAGE_SIZE
+
+#define INVALID_WATCHPOINT  0
+#define CONSUMED_WATCHPOINT 1
+
+/*
+ * The maximum useful size of accesses for which we set up watchpoints is the
+ * max range of slots we check on an access.
+ */
+#define MAX_ENCODABLE_SIZE (SLOT_RANGE * (1 + KCSAN_CHECK_ADJACENT))
+
+/*
+ * Number of bits we use to store size info.
+ */
+#define WATCHPOINT_SIZE_BITS bits_per(MAX_ENCODABLE_SIZE)
+/*
+ * This encoding for addresses discards the upper (1 for is-write + SIZE_BITS);
+ * however, most 64-bit architectures do not use the full 64-bit address space.
+ * Also, in order for a false positive to be observable 2 things need to happen:
+ *
+ *	1. different addresses but with the same encoded address race;
+ *	2. and both map onto the same watchpoint slots;
+ *
+ * Both these are assumed to be very unlikely. However, in case it still happens
+ * happens, the report logic will filter out the false positive (see report.c).
+ */
+#define WATCHPOINT_ADDR_BITS (BITS_PER_LONG-1 - WATCHPOINT_SIZE_BITS)
+
+/*
+ * Masks to set/retrieve the encoded data.
+ */
+#define WATCHPOINT_WRITE_MASK BIT(BITS_PER_LONG-1)
+#define WATCHPOINT_SIZE_MASK                                                   \
+	GENMASK(BITS_PER_LONG-2, BITS_PER_LONG-2 - WATCHPOINT_SIZE_BITS)
+#define WATCHPOINT_ADDR_MASK                                                   \
+	GENMASK(BITS_PER_LONG-3 - WATCHPOINT_SIZE_BITS, 0)
+
+static inline bool check_encodable(unsigned long addr, size_t size)
+{
+	return size <= MAX_ENCODABLE_SIZE;
+}
+
+static inline long
+encode_watchpoint(unsigned long addr, size_t size, bool is_write)
+{
+	return (long)((is_write ? WATCHPOINT_WRITE_MASK : 0) |
+		      (size << WATCHPOINT_ADDR_BITS) |
+		      (addr & WATCHPOINT_ADDR_MASK));
+}
+
+static __always_inline bool decode_watchpoint(long watchpoint,
+					      unsigned long *addr_masked,
+					      size_t *size,
+					      bool *is_write)
+{
+	if (watchpoint == INVALID_WATCHPOINT ||
+	    watchpoint == CONSUMED_WATCHPOINT)
+		return false;
+
+	*addr_masked =    (unsigned long)watchpoint & WATCHPOINT_ADDR_MASK;
+	*size	     =   ((unsigned long)watchpoint & WATCHPOINT_SIZE_MASK) >> WATCHPOINT_ADDR_BITS;
+	*is_write    = !!((unsigned long)watchpoint & WATCHPOINT_WRITE_MASK);
+
+	return true;
+}
+
+/*
+ * Return watchpoint slot for an address.
+ */
+static __always_inline int watchpoint_slot(unsigned long addr)
+{
+	return (addr / PAGE_SIZE) % CONFIG_KCSAN_NUM_WATCHPOINTS;
+}
+
+static __always_inline bool matching_access(unsigned long addr1, size_t size1,
+					    unsigned long addr2, size_t size2)
+{
+	unsigned long end_range1 = addr1 + size1 - 1;
+	unsigned long end_range2 = addr2 + size2 - 1;
+
+	return addr1 <= end_range2 && addr2 <= end_range1;
+}
+
+#endif /* _KERNEL_KCSAN_ENCODING_H */
diff --git a/kernel/kcsan/kcsan.h b/kernel/kcsan/kcsan.h
new file mode 100644
index 000000000000..763d6d08d94b
--- /dev/null
+++ b/kernel/kcsan/kcsan.h
@@ -0,0 +1,142 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/*
+ * The Kernel Concurrency Sanitizer (KCSAN) infrastructure. For more info please
+ * see Documentation/dev-tools/kcsan.rst.
+ */
+
+#ifndef _KERNEL_KCSAN_KCSAN_H
+#define _KERNEL_KCSAN_KCSAN_H
+
+#include <linux/kcsan.h>
+
+/* The number of adjacent watchpoints to check. */
+#define KCSAN_CHECK_ADJACENT 1
+#define NUM_SLOTS (1 + 2*KCSAN_CHECK_ADJACENT)
+
+extern unsigned int kcsan_udelay_task;
+extern unsigned int kcsan_udelay_interrupt;
+
+/*
+ * Globally enable and disable KCSAN.
+ */
+extern bool kcsan_enabled;
+
+/*
+ * Initialize debugfs file.
+ */
+void kcsan_debugfs_init(void);
+
+enum kcsan_counter_id {
+	/*
+	 * Number of watchpoints currently in use.
+	 */
+	KCSAN_COUNTER_USED_WATCHPOINTS,
+
+	/*
+	 * Total number of watchpoints set up.
+	 */
+	KCSAN_COUNTER_SETUP_WATCHPOINTS,
+
+	/*
+	 * Total number of data races.
+	 */
+	KCSAN_COUNTER_DATA_RACES,
+
+	/*
+	 * Total number of ASSERT failures due to races. If the observed race is
+	 * due to two conflicting ASSERT type accesses, then both will be
+	 * counted.
+	 */
+	KCSAN_COUNTER_ASSERT_FAILURES,
+
+	/*
+	 * Number of times no watchpoints were available.
+	 */
+	KCSAN_COUNTER_NO_CAPACITY,
+
+	/*
+	 * A thread checking a watchpoint raced with another checking thread;
+	 * only one will be reported.
+	 */
+	KCSAN_COUNTER_REPORT_RACES,
+
+	/*
+	 * Observed data value change, but writer thread unknown.
+	 */
+	KCSAN_COUNTER_RACES_UNKNOWN_ORIGIN,
+
+	/*
+	 * The access cannot be encoded to a valid watchpoint.
+	 */
+	KCSAN_COUNTER_UNENCODABLE_ACCESSES,
+
+	/*
+	 * Watchpoint encoding caused a watchpoint to fire on mismatching
+	 * accesses.
+	 */
+	KCSAN_COUNTER_ENCODING_FALSE_POSITIVES,
+
+	KCSAN_COUNTER_COUNT, /* number of counters */
+};
+
+/*
+ * Increment/decrement counter with given id; avoid calling these in fast-path.
+ */
+extern void kcsan_counter_inc(enum kcsan_counter_id id);
+extern void kcsan_counter_dec(enum kcsan_counter_id id);
+
+/*
+ * Returns true if data races in the function symbol that maps to func_addr
+ * (offsets are ignored) should *not* be reported.
+ */
+extern bool kcsan_skip_report_debugfs(unsigned long func_addr);
+
+/*
+ * Value-change states.
+ */
+enum kcsan_value_change {
+	/*
+	 * Did not observe a value-change, however, it is valid to report the
+	 * race, depending on preferences.
+	 */
+	KCSAN_VALUE_CHANGE_MAYBE,
+
+	/*
+	 * Did not observe a value-change, and it is invalid to report the race.
+	 */
+	KCSAN_VALUE_CHANGE_FALSE,
+
+	/*
+	 * The value was observed to change, and the race should be reported.
+	 */
+	KCSAN_VALUE_CHANGE_TRUE,
+};
+
+enum kcsan_report_type {
+	/*
+	 * The thread that set up the watchpoint and briefly stalled was
+	 * signalled that another thread triggered the watchpoint.
+	 */
+	KCSAN_REPORT_RACE_SIGNAL,
+
+	/*
+	 * A thread found and consumed a matching watchpoint.
+	 */
+	KCSAN_REPORT_CONSUMED_WATCHPOINT,
+
+	/*
+	 * No other thread was observed to race with the access, but the data
+	 * value before and after the stall differs.
+	 */
+	KCSAN_REPORT_RACE_UNKNOWN_ORIGIN,
+};
+
+/*
+ * Print a race report from thread that encountered the race.
+ */
+extern void kcsan_report(const volatile void *ptr, size_t size, int access_type,
+			 enum kcsan_value_change value_change,
+			 enum kcsan_report_type type, int watchpoint_idx);
+
+#endif /* _KERNEL_KCSAN_KCSAN_H */
diff --git a/kernel/kcsan/report.c b/kernel/kcsan/report.c
new file mode 100644
index 000000000000..ac5f8345bae9
--- /dev/null
+++ b/kernel/kcsan/report.c
@@ -0,0 +1,634 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/debug_locks.h>
+#include <linux/delay.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/lockdep.h>
+#include <linux/preempt.h>
+#include <linux/printk.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/stacktrace.h>
+
+#include "kcsan.h"
+#include "encoding.h"
+
+/*
+ * Max. number of stack entries to show in the report.
+ */
+#define NUM_STACK_ENTRIES 64
+
+/* Common access info. */
+struct access_info {
+	const volatile void	*ptr;
+	size_t			size;
+	int			access_type;
+	int			task_pid;
+	int			cpu_id;
+};
+
+/*
+ * Other thread info: communicated from other racing thread to thread that set
+ * up the watchpoint, which then prints the complete report atomically.
+ */
+struct other_info {
+	struct access_info	ai;
+	unsigned long		stack_entries[NUM_STACK_ENTRIES];
+	int			num_stack_entries;
+
+	/*
+	 * Optionally pass @current. Typically we do not need to pass @current
+	 * via @other_info since just @task_pid is sufficient. Passing @current
+	 * has additional overhead.
+	 *
+	 * To safely pass @current, we must either use get_task_struct/
+	 * put_task_struct, or stall the thread that populated @other_info.
+	 *
+	 * We cannot rely on get_task_struct/put_task_struct in case
+	 * release_report() races with a task being released, and would have to
+	 * free it in release_report(). This may result in deadlock if we want
+	 * to use KCSAN on the allocators.
+	 *
+	 * Since we also want to reliably print held locks for
+	 * CONFIG_KCSAN_VERBOSE, the current implementation stalls the thread
+	 * that populated @other_info until it has been consumed.
+	 */
+	struct task_struct	*task;
+};
+
+/*
+ * To never block any producers of struct other_info, we need as many elements
+ * as we have watchpoints (upper bound on concurrent races to report).
+ */
+static struct other_info other_infos[CONFIG_KCSAN_NUM_WATCHPOINTS + NUM_SLOTS-1];
+
+/*
+ * Information about reported races; used to rate limit reporting.
+ */
+struct report_time {
+	/*
+	 * The last time the race was reported.
+	 */
+	unsigned long time;
+
+	/*
+	 * The frames of the 2 threads; if only 1 thread is known, one frame
+	 * will be 0.
+	 */
+	unsigned long frame1;
+	unsigned long frame2;
+};
+
+/*
+ * Since we also want to be able to debug allocators with KCSAN, to avoid
+ * deadlock, report_times cannot be dynamically resized with krealloc in
+ * rate_limit_report.
+ *
+ * Therefore, we use a fixed-size array, which at most will occupy a page. This
+ * still adequately rate limits reports, assuming that a) number of unique data
+ * races is not excessive, and b) occurrence of unique races within the
+ * same time window is limited.
+ */
+#define REPORT_TIMES_MAX (PAGE_SIZE / sizeof(struct report_time))
+#define REPORT_TIMES_SIZE                                                      \
+	(CONFIG_KCSAN_REPORT_ONCE_IN_MS > REPORT_TIMES_MAX ?                   \
+		 REPORT_TIMES_MAX :                                            \
+		 CONFIG_KCSAN_REPORT_ONCE_IN_MS)
+static struct report_time report_times[REPORT_TIMES_SIZE];
+
+/*
+ * Spinlock serializing report generation, and access to @other_infos. Although
+ * it could make sense to have a finer-grained locking story for @other_infos,
+ * report generation needs to be serialized either way, so not much is gained.
+ */
+static DEFINE_RAW_SPINLOCK(report_lock);
+
+/*
+ * Checks if the race identified by thread frames frame1 and frame2 has
+ * been reported since (now - KCSAN_REPORT_ONCE_IN_MS).
+ */
+static bool rate_limit_report(unsigned long frame1, unsigned long frame2)
+{
+	struct report_time *use_entry = &report_times[0];
+	unsigned long invalid_before;
+	int i;
+
+	BUILD_BUG_ON(CONFIG_KCSAN_REPORT_ONCE_IN_MS != 0 && REPORT_TIMES_SIZE == 0);
+
+	if (CONFIG_KCSAN_REPORT_ONCE_IN_MS == 0)
+		return false;
+
+	invalid_before = jiffies - msecs_to_jiffies(CONFIG_KCSAN_REPORT_ONCE_IN_MS);
+
+	/* Check if a matching race report exists. */
+	for (i = 0; i < REPORT_TIMES_SIZE; ++i) {
+		struct report_time *rt = &report_times[i];
+
+		/*
+		 * Must always select an entry for use to store info as we
+		 * cannot resize report_times; at the end of the scan, use_entry
+		 * will be the oldest entry, which ideally also happened before
+		 * KCSAN_REPORT_ONCE_IN_MS ago.
+		 */
+		if (time_before(rt->time, use_entry->time))
+			use_entry = rt;
+
+		/*
+		 * Initially, no need to check any further as this entry as well
+		 * as following entries have never been used.
+		 */
+		if (rt->time == 0)
+			break;
+
+		/* Check if entry expired. */
+		if (time_before(rt->time, invalid_before))
+			continue; /* before KCSAN_REPORT_ONCE_IN_MS ago */
+
+		/* Reported recently, check if race matches. */
+		if ((rt->frame1 == frame1 && rt->frame2 == frame2) ||
+		    (rt->frame1 == frame2 && rt->frame2 == frame1))
+			return true;
+	}
+
+	use_entry->time = jiffies;
+	use_entry->frame1 = frame1;
+	use_entry->frame2 = frame2;
+	return false;
+}
+
+/*
+ * Special rules to skip reporting.
+ */
+static bool
+skip_report(enum kcsan_value_change value_change, unsigned long top_frame)
+{
+	/* Should never get here if value_change==FALSE. */
+	WARN_ON_ONCE(value_change == KCSAN_VALUE_CHANGE_FALSE);
+
+	/*
+	 * The first call to skip_report always has value_change==TRUE, since we
+	 * cannot know the value written of an instrumented access. For the 2nd
+	 * call there are 6 cases with CONFIG_KCSAN_REPORT_VALUE_CHANGE_ONLY:
+	 *
+	 * 1. read watchpoint, conflicting write (value_change==TRUE): report;
+	 * 2. read watchpoint, conflicting write (value_change==MAYBE): skip;
+	 * 3. write watchpoint, conflicting write (value_change==TRUE): report;
+	 * 4. write watchpoint, conflicting write (value_change==MAYBE): skip;
+	 * 5. write watchpoint, conflicting read (value_change==MAYBE): skip;
+	 * 6. write watchpoint, conflicting read (value_change==TRUE): report;
+	 *
+	 * Cases 1-4 are intuitive and expected; case 5 ensures we do not report
+	 * data races where the write may have rewritten the same value; case 6
+	 * is possible either if the size is larger than what we check value
+	 * changes for or the access type is KCSAN_ACCESS_ASSERT.
+	 */
+	if (IS_ENABLED(CONFIG_KCSAN_REPORT_VALUE_CHANGE_ONLY) &&
+	    value_change == KCSAN_VALUE_CHANGE_MAYBE) {
+		/*
+		 * The access is a write, but the data value did not change.
+		 *
+		 * We opt-out of this filter for certain functions at request of
+		 * maintainers.
+		 */
+		char buf[64];
+		int len = scnprintf(buf, sizeof(buf), "%ps", (void *)top_frame);
+
+		if (!strnstr(buf, "rcu_", len) &&
+		    !strnstr(buf, "_rcu", len) &&
+		    !strnstr(buf, "_srcu", len))
+			return true;
+	}
+
+	return kcsan_skip_report_debugfs(top_frame);
+}
+
+static const char *get_access_type(int type)
+{
+	if (type & KCSAN_ACCESS_ASSERT) {
+		if (type & KCSAN_ACCESS_SCOPED) {
+			if (type & KCSAN_ACCESS_WRITE)
+				return "assert no accesses (scoped)";
+			else
+				return "assert no writes (scoped)";
+		} else {
+			if (type & KCSAN_ACCESS_WRITE)
+				return "assert no accesses";
+			else
+				return "assert no writes";
+		}
+	}
+
+	switch (type) {
+	case 0:
+		return "read";
+	case KCSAN_ACCESS_ATOMIC:
+		return "read (marked)";
+	case KCSAN_ACCESS_WRITE:
+		return "write";
+	case KCSAN_ACCESS_WRITE | KCSAN_ACCESS_ATOMIC:
+		return "write (marked)";
+	case KCSAN_ACCESS_SCOPED:
+		return "read (scoped)";
+	case KCSAN_ACCESS_SCOPED | KCSAN_ACCESS_ATOMIC:
+		return "read (marked, scoped)";
+	case KCSAN_ACCESS_SCOPED | KCSAN_ACCESS_WRITE:
+		return "write (scoped)";
+	case KCSAN_ACCESS_SCOPED | KCSAN_ACCESS_WRITE | KCSAN_ACCESS_ATOMIC:
+		return "write (marked, scoped)";
+	default:
+		BUG();
+	}
+}
+
+static const char *get_bug_type(int type)
+{
+	return (type & KCSAN_ACCESS_ASSERT) != 0 ? "assert: race" : "data-race";
+}
+
+/* Return thread description: in task or interrupt. */
+static const char *get_thread_desc(int task_id)
+{
+	if (task_id != -1) {
+		static char buf[32]; /* safe: protected by report_lock */
+
+		snprintf(buf, sizeof(buf), "task %i", task_id);
+		return buf;
+	}
+	return "interrupt";
+}
+
+/* Helper to skip KCSAN-related functions in stack-trace. */
+static int get_stack_skipnr(const unsigned long stack_entries[], int num_entries)
+{
+	char buf[64];
+	char *cur;
+	int len, skip;
+
+	for (skip = 0; skip < num_entries; ++skip) {
+		len = scnprintf(buf, sizeof(buf), "%ps", (void *)stack_entries[skip]);
+
+		/* Never show tsan_* or {read,write}_once_size. */
+		if (strnstr(buf, "tsan_", len) ||
+		    strnstr(buf, "_once_size", len))
+			continue;
+
+		cur = strnstr(buf, "kcsan_", len);
+		if (cur) {
+			cur += sizeof("kcsan_") - 1;
+			if (strncmp(cur, "test", sizeof("test") - 1))
+				continue; /* KCSAN runtime function. */
+			/* KCSAN related test. */
+		}
+
+		/*
+		 * No match for runtime functions -- @skip entries to skip to
+		 * get to first frame of interest.
+		 */
+		break;
+	}
+
+	return skip;
+}
+
+/* Compares symbolized strings of addr1 and addr2. */
+static int sym_strcmp(void *addr1, void *addr2)
+{
+	char buf1[64];
+	char buf2[64];
+
+	snprintf(buf1, sizeof(buf1), "%pS", addr1);
+	snprintf(buf2, sizeof(buf2), "%pS", addr2);
+
+	return strncmp(buf1, buf2, sizeof(buf1));
+}
+
+static void print_verbose_info(struct task_struct *task)
+{
+	if (!task)
+		return;
+
+	pr_err("\n");
+	debug_show_held_locks(task);
+	print_irqtrace_events(task);
+}
+
+/*
+ * Returns true if a report was generated, false otherwise.
+ */
+static bool print_report(enum kcsan_value_change value_change,
+			 enum kcsan_report_type type,
+			 const struct access_info *ai,
+			 const struct other_info *other_info)
+{
+	unsigned long stack_entries[NUM_STACK_ENTRIES] = { 0 };
+	int num_stack_entries = stack_trace_save(stack_entries, NUM_STACK_ENTRIES, 1);
+	int skipnr = get_stack_skipnr(stack_entries, num_stack_entries);
+	unsigned long this_frame = stack_entries[skipnr];
+	unsigned long other_frame = 0;
+	int other_skipnr = 0; /* silence uninit warnings */
+
+	/*
+	 * Must check report filter rules before starting to print.
+	 */
+	if (skip_report(KCSAN_VALUE_CHANGE_TRUE, stack_entries[skipnr]))
+		return false;
+
+	if (type == KCSAN_REPORT_RACE_SIGNAL) {
+		other_skipnr = get_stack_skipnr(other_info->stack_entries,
+						other_info->num_stack_entries);
+		other_frame = other_info->stack_entries[other_skipnr];
+
+		/* @value_change is only known for the other thread */
+		if (skip_report(value_change, other_frame))
+			return false;
+	}
+
+	if (rate_limit_report(this_frame, other_frame))
+		return false;
+
+	/* Print report header. */
+	pr_err("==================================================================\n");
+	switch (type) {
+	case KCSAN_REPORT_RACE_SIGNAL: {
+		int cmp;
+
+		/*
+		 * Order functions lexographically for consistent bug titles.
+		 * Do not print offset of functions to keep title short.
+		 */
+		cmp = sym_strcmp((void *)other_frame, (void *)this_frame);
+		pr_err("BUG: KCSAN: %s in %ps / %ps\n",
+		       get_bug_type(ai->access_type | other_info->ai.access_type),
+		       (void *)(cmp < 0 ? other_frame : this_frame),
+		       (void *)(cmp < 0 ? this_frame : other_frame));
+	} break;
+
+	case KCSAN_REPORT_RACE_UNKNOWN_ORIGIN:
+		pr_err("BUG: KCSAN: %s in %pS\n", get_bug_type(ai->access_type),
+		       (void *)this_frame);
+		break;
+
+	default:
+		BUG();
+	}
+
+	pr_err("\n");
+
+	/* Print information about the racing accesses. */
+	switch (type) {
+	case KCSAN_REPORT_RACE_SIGNAL:
+		pr_err("%s to 0x%px of %zu bytes by %s on cpu %i:\n",
+		       get_access_type(other_info->ai.access_type), other_info->ai.ptr,
+		       other_info->ai.size, get_thread_desc(other_info->ai.task_pid),
+		       other_info->ai.cpu_id);
+
+		/* Print the other thread's stack trace. */
+		stack_trace_print(other_info->stack_entries + other_skipnr,
+				  other_info->num_stack_entries - other_skipnr,
+				  0);
+
+		if (IS_ENABLED(CONFIG_KCSAN_VERBOSE))
+			print_verbose_info(other_info->task);
+
+		pr_err("\n");
+		pr_err("%s to 0x%px of %zu bytes by %s on cpu %i:\n",
+		       get_access_type(ai->access_type), ai->ptr, ai->size,
+		       get_thread_desc(ai->task_pid), ai->cpu_id);
+		break;
+
+	case KCSAN_REPORT_RACE_UNKNOWN_ORIGIN:
+		pr_err("race at unknown origin, with %s to 0x%px of %zu bytes by %s on cpu %i:\n",
+		       get_access_type(ai->access_type), ai->ptr, ai->size,
+		       get_thread_desc(ai->task_pid), ai->cpu_id);
+		break;
+
+	default:
+		BUG();
+	}
+	/* Print stack trace of this thread. */
+	stack_trace_print(stack_entries + skipnr, num_stack_entries - skipnr,
+			  0);
+
+	if (IS_ENABLED(CONFIG_KCSAN_VERBOSE))
+		print_verbose_info(current);
+
+	/* Print report footer. */
+	pr_err("\n");
+	pr_err("Reported by Kernel Concurrency Sanitizer on:\n");
+	dump_stack_print_info(KERN_DEFAULT);
+	pr_err("==================================================================\n");
+
+	return true;
+}
+
+static void release_report(unsigned long *flags, struct other_info *other_info)
+{
+	if (other_info)
+		/*
+		 * Use size to denote valid/invalid, since KCSAN entirely
+		 * ignores 0-sized accesses.
+		 */
+		other_info->ai.size = 0;
+
+	raw_spin_unlock_irqrestore(&report_lock, *flags);
+}
+
+/*
+ * Sets @other_info->task and awaits consumption of @other_info.
+ *
+ * Precondition: report_lock is held.
+ * Postcondition: report_lock is held.
+ */
+static void set_other_info_task_blocking(unsigned long *flags,
+					 const struct access_info *ai,
+					 struct other_info *other_info)
+{
+	/*
+	 * We may be instrumenting a code-path where current->state is already
+	 * something other than TASK_RUNNING.
+	 */
+	const bool is_running = current->state == TASK_RUNNING;
+	/*
+	 * To avoid deadlock in case we are in an interrupt here and this is a
+	 * race with a task on the same CPU (KCSAN_INTERRUPT_WATCHER), provide a
+	 * timeout to ensure this works in all contexts.
+	 *
+	 * Await approximately the worst case delay of the reporting thread (if
+	 * we are not interrupted).
+	 */
+	int timeout = max(kcsan_udelay_task, kcsan_udelay_interrupt);
+
+	other_info->task = current;
+	do {
+		if (is_running) {
+			/*
+			 * Let lockdep know the real task is sleeping, to print
+			 * the held locks (recall we turned lockdep off, so
+			 * locking/unlocking @report_lock won't be recorded).
+			 */
+			set_current_state(TASK_UNINTERRUPTIBLE);
+		}
+		raw_spin_unlock_irqrestore(&report_lock, *flags);
+		/*
+		 * We cannot call schedule() since we also cannot reliably
+		 * determine if sleeping here is permitted -- see in_atomic().
+		 */
+
+		udelay(1);
+		raw_spin_lock_irqsave(&report_lock, *flags);
+		if (timeout-- < 0) {
+			/*
+			 * Abort. Reset @other_info->task to NULL, since it
+			 * appears the other thread is still going to consume
+			 * it. It will result in no verbose info printed for
+			 * this task.
+			 */
+			other_info->task = NULL;
+			break;
+		}
+		/*
+		 * If invalid, or @ptr nor @current matches, then @other_info
+		 * has been consumed and we may continue. If not, retry.
+		 */
+	} while (other_info->ai.size && other_info->ai.ptr == ai->ptr &&
+		 other_info->task == current);
+	if (is_running)
+		set_current_state(TASK_RUNNING);
+}
+
+/* Populate @other_info; requires that the provided @other_info not in use. */
+static void prepare_report_producer(unsigned long *flags,
+				    const struct access_info *ai,
+				    struct other_info *other_info)
+{
+	raw_spin_lock_irqsave(&report_lock, *flags);
+
+	/*
+	 * The same @other_infos entry cannot be used concurrently, because
+	 * there is a one-to-one mapping to watchpoint slots (@watchpoints in
+	 * core.c), and a watchpoint is only released for reuse after reporting
+	 * is done by the consumer of @other_info. Therefore, it is impossible
+	 * for another concurrent prepare_report_producer() to set the same
+	 * @other_info, and are guaranteed exclusivity for the @other_infos
+	 * entry pointed to by @other_info.
+	 *
+	 * To check this property holds, size should never be non-zero here,
+	 * because every consumer of struct other_info resets size to 0 in
+	 * release_report().
+	 */
+	WARN_ON(other_info->ai.size);
+
+	other_info->ai = *ai;
+	other_info->num_stack_entries = stack_trace_save(other_info->stack_entries, NUM_STACK_ENTRIES, 2);
+
+	if (IS_ENABLED(CONFIG_KCSAN_VERBOSE))
+		set_other_info_task_blocking(flags, ai, other_info);
+
+	raw_spin_unlock_irqrestore(&report_lock, *flags);
+}
+
+/* Awaits producer to fill @other_info and then returns. */
+static bool prepare_report_consumer(unsigned long *flags,
+				    const struct access_info *ai,
+				    struct other_info *other_info)
+{
+
+	raw_spin_lock_irqsave(&report_lock, *flags);
+	while (!other_info->ai.size) { /* Await valid @other_info. */
+		raw_spin_unlock_irqrestore(&report_lock, *flags);
+		cpu_relax();
+		raw_spin_lock_irqsave(&report_lock, *flags);
+	}
+
+	/* Should always have a matching access based on watchpoint encoding. */
+	if (WARN_ON(!matching_access((unsigned long)other_info->ai.ptr & WATCHPOINT_ADDR_MASK, other_info->ai.size,
+				     (unsigned long)ai->ptr & WATCHPOINT_ADDR_MASK, ai->size)))
+		goto discard;
+
+	if (!matching_access((unsigned long)other_info->ai.ptr, other_info->ai.size,
+			     (unsigned long)ai->ptr, ai->size)) {
+		/*
+		 * If the actual accesses to not match, this was a false
+		 * positive due to watchpoint encoding.
+		 */
+		kcsan_counter_inc(KCSAN_COUNTER_ENCODING_FALSE_POSITIVES);
+		goto discard;
+	}
+
+	return true;
+
+discard:
+	release_report(flags, other_info);
+	return false;
+}
+
+/*
+ * Depending on the report type either sets @other_info and returns false, or
+ * awaits @other_info and returns true. If @other_info is not required for the
+ * report type, simply acquires @report_lock and returns true.
+ */
+static noinline bool prepare_report(unsigned long *flags,
+				    enum kcsan_report_type type,
+				    const struct access_info *ai,
+				    struct other_info *other_info)
+{
+	switch (type) {
+	case KCSAN_REPORT_CONSUMED_WATCHPOINT:
+		prepare_report_producer(flags, ai, other_info);
+		return false;
+	case KCSAN_REPORT_RACE_SIGNAL:
+		return prepare_report_consumer(flags, ai, other_info);
+	default:
+		/* @other_info not required; just acquire @report_lock. */
+		raw_spin_lock_irqsave(&report_lock, *flags);
+		return true;
+	}
+}
+
+void kcsan_report(const volatile void *ptr, size_t size, int access_type,
+		  enum kcsan_value_change value_change,
+		  enum kcsan_report_type type, int watchpoint_idx)
+{
+	unsigned long flags = 0;
+	const struct access_info ai = {
+		.ptr		= ptr,
+		.size		= size,
+		.access_type	= access_type,
+		.task_pid	= in_task() ? task_pid_nr(current) : -1,
+		.cpu_id		= raw_smp_processor_id()
+	};
+	struct other_info *other_info = type == KCSAN_REPORT_RACE_UNKNOWN_ORIGIN
+					? NULL : &other_infos[watchpoint_idx];
+
+	kcsan_disable_current();
+	if (WARN_ON(watchpoint_idx < 0 || watchpoint_idx >= ARRAY_SIZE(other_infos)))
+		goto out;
+
+	/*
+	 * With TRACE_IRQFLAGS, lockdep's IRQ trace state becomes corrupted if
+	 * we do not turn off lockdep here; this could happen due to recursion
+	 * into lockdep via KCSAN if we detect a race in utilities used by
+	 * lockdep.
+	 */
+	lockdep_off();
+
+	if (prepare_report(&flags, type, &ai, other_info)) {
+		/*
+		 * Never report if value_change is FALSE, only if we it is
+		 * either TRUE or MAYBE. In case of MAYBE, further filtering may
+		 * be done once we know the full stack trace in print_report().
+		 */
+		bool reported = value_change != KCSAN_VALUE_CHANGE_FALSE &&
+				print_report(value_change, type, &ai, other_info);
+
+		if (reported && panic_on_warn)
+			panic("panic_on_warn set ...\n");
+
+		release_report(&flags, other_info);
+	}
+
+	lockdep_on();
+out:
+	kcsan_enable_current();
+}
diff --git a/kernel/kcsan/test.c b/kernel/kcsan/test.c
new file mode 100644
index 000000000000..d26a052d3383
--- /dev/null
+++ b/kernel/kcsan/test.c
@@ -0,0 +1,131 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/printk.h>
+#include <linux/random.h>
+#include <linux/types.h>
+
+#include "encoding.h"
+
+#define ITERS_PER_TEST 2000
+
+/* Test requirements. */
+static bool test_requires(void)
+{
+	/* random should be initialized for the below tests */
+	return prandom_u32() + prandom_u32() != 0;
+}
+
+/*
+ * Test watchpoint encode and decode: check that encoding some access's info,
+ * and then subsequent decode preserves the access's info.
+ */
+static bool test_encode_decode(void)
+{
+	int i;
+
+	for (i = 0; i < ITERS_PER_TEST; ++i) {
+		size_t size = prandom_u32_max(MAX_ENCODABLE_SIZE) + 1;
+		bool is_write = !!prandom_u32_max(2);
+		unsigned long addr;
+
+		prandom_bytes(&addr, sizeof(addr));
+		if (WARN_ON(!check_encodable(addr, size)))
+			return false;
+
+		/* Encode and decode */
+		{
+			const long encoded_watchpoint =
+				encode_watchpoint(addr, size, is_write);
+			unsigned long verif_masked_addr;
+			size_t verif_size;
+			bool verif_is_write;
+
+			/* Check special watchpoints */
+			if (WARN_ON(decode_watchpoint(
+				    INVALID_WATCHPOINT, &verif_masked_addr,
+				    &verif_size, &verif_is_write)))
+				return false;
+			if (WARN_ON(decode_watchpoint(
+				    CONSUMED_WATCHPOINT, &verif_masked_addr,
+				    &verif_size, &verif_is_write)))
+				return false;
+
+			/* Check decoding watchpoint returns same data */
+			if (WARN_ON(!decode_watchpoint(
+				    encoded_watchpoint, &verif_masked_addr,
+				    &verif_size, &verif_is_write)))
+				return false;
+			if (WARN_ON(verif_masked_addr !=
+				    (addr & WATCHPOINT_ADDR_MASK)))
+				goto fail;
+			if (WARN_ON(verif_size != size))
+				goto fail;
+			if (WARN_ON(is_write != verif_is_write))
+				goto fail;
+
+			continue;
+fail:
+			pr_err("%s fail: %s %zu bytes @ %lx -> encoded: %lx -> %s %zu bytes @ %lx\n",
+			       __func__, is_write ? "write" : "read", size,
+			       addr, encoded_watchpoint,
+			       verif_is_write ? "write" : "read", verif_size,
+			       verif_masked_addr);
+			return false;
+		}
+	}
+
+	return true;
+}
+
+/* Test access matching function. */
+static bool test_matching_access(void)
+{
+	if (WARN_ON(!matching_access(10, 1, 10, 1)))
+		return false;
+	if (WARN_ON(!matching_access(10, 2, 11, 1)))
+		return false;
+	if (WARN_ON(!matching_access(10, 1, 9, 2)))
+		return false;
+	if (WARN_ON(matching_access(10, 1, 11, 1)))
+		return false;
+	if (WARN_ON(matching_access(9, 1, 10, 1)))
+		return false;
+
+	/*
+	 * An access of size 0 could match another access, as demonstrated here.
+	 * Rather than add more comparisons to 'matching_access()', which would
+	 * end up in the fast-path for *all* checks, check_access() simply
+	 * returns for all accesses of size 0.
+	 */
+	if (WARN_ON(!matching_access(8, 8, 12, 0)))
+		return false;
+
+	return true;
+}
+
+static int __init kcsan_selftest(void)
+{
+	int passed = 0;
+	int total = 0;
+
+#define RUN_TEST(do_test)                                                      \
+	do {                                                                   \
+		++total;                                                       \
+		if (do_test())                                                 \
+			++passed;                                              \
+		else                                                           \
+			pr_err("KCSAN selftest: " #do_test " failed");         \
+	} while (0)
+
+	RUN_TEST(test_requires);
+	RUN_TEST(test_encode_decode);
+	RUN_TEST(test_matching_access);
+
+	pr_info("KCSAN selftest: %d/%d tests passed\n", passed, total);
+	if (passed != total)
+		panic("KCSAN selftests failed");
+	return 0;
+}
+postcore_initcall(kcsan_selftest);
diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
index c19c0dad1ebe..ba1d91e868ca 100644
--- a/kernel/kexec_core.c
+++ b/kernel/kexec_core.c
@@ -12,6 +12,7 @@
 #include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/kexec.h>
+#include <linux/memory.h>
 #include <linux/mutex.h>
 #include <linux/list.h>
 #include <linux/highmem.h>
@@ -22,10 +23,12 @@
 #include <linux/elf.h>
 #include <linux/elfcore.h>
 #include <linux/utsname.h>
+#include <linux/notifier.h>
 #include <linux/numa.h>
 #include <linux/suspend.h>
 #include <linux/device.h>
 #include <linux/freezer.h>
+#include <linux/pfn.h>
 #include <linux/pm.h>
 #include <linux/cpu.h>
 #include <linux/uaccess.h>
@@ -1219,3 +1222,56 @@ void __weak arch_kexec_protect_crashkres(void)
 
 void __weak arch_kexec_unprotect_crashkres(void)
 {}
+
+/*
+ * If user-space wants to offline memory that is in use by a loaded kexec
+ * image, it should unload the image first.
+ */
+static int mem_remove_cb(struct notifier_block *nb, unsigned long action,
+			 void *data)
+{
+	int rv = NOTIFY_OK, i;
+	struct memory_notify *arg = data;
+	unsigned long pfn = arg->start_pfn;
+	unsigned long nr_segments, sstart, send;
+	unsigned long end_pfn = arg->start_pfn + arg->nr_pages;
+
+	might_sleep();
+
+	if (action != MEM_GOING_OFFLINE)
+		return NOTIFY_DONE;
+
+	mutex_lock(&kexec_mutex);
+	if (kexec_image) {
+		nr_segments = kexec_image->nr_segments;
+
+		for (i = 0; i < nr_segments; i++) {
+			sstart = PFN_DOWN(kexec_image->segment[i].mem);
+			send = PFN_UP(kexec_image->segment[i].mem +
+				      kexec_image->segment[i].memsz);
+
+			if ((pfn <= sstart && sstart < end_pfn) ||
+			    (pfn <= send && send < end_pfn)) {
+				pr_warn("Memory region in use\n");
+				rv = NOTIFY_BAD;
+				break;
+			}
+		}
+	}
+	mutex_unlock(&kexec_mutex);
+
+	return rv;
+}
+
+static struct notifier_block mem_remove_nb = {
+	.notifier_call = mem_remove_cb,
+};
+
+static int __init register_mem_remove_cb(void)
+{
+	if (IS_ENABLED(CONFIG_MEMORY_HOTPLUG))
+		return register_memory_notifier(&mem_remove_nb);
+
+	return 0;
+}
+device_initcall(register_mem_remove_cb);
diff --git a/kernel/locking/Makefile b/kernel/locking/Makefile
index 45452facff3b..6d11cfb9b41f 100644
--- a/kernel/locking/Makefile
+++ b/kernel/locking/Makefile
@@ -5,6 +5,9 @@ KCOV_INSTRUMENT		:= n
 
 obj-y += mutex.o semaphore.o rwsem.o percpu-rwsem.o
 
+# Avoid recursion lockdep -> KCSAN -> ... -> lockdep.
+KCSAN_SANITIZE_lockdep.o := n
+
 ifdef CONFIG_FUNCTION_TRACER
 CFLAGS_REMOVE_lockdep.o = $(CC_FLAGS_FTRACE)
 CFLAGS_REMOVE_lockdep_proc.o = $(CC_FLAGS_FTRACE)
diff --git a/kernel/locking/locktorture.c b/kernel/locking/locktorture.c
index 5efbfc68ce99..8ff6f50e06a0 100644
--- a/kernel/locking/locktorture.c
+++ b/kernel/locking/locktorture.c
@@ -631,13 +631,13 @@ static int lock_torture_writer(void *arg)
 		cxt.cur_ops->writelock();
 		if (WARN_ON_ONCE(lock_is_write_held))
 			lwsp->n_lock_fail++;
-		lock_is_write_held = 1;
+		lock_is_write_held = true;
 		if (WARN_ON_ONCE(lock_is_read_held))
 			lwsp->n_lock_fail++; /* rare, but... */
 
 		lwsp->n_lock_acquired++;
 		cxt.cur_ops->write_delay(&rand);
-		lock_is_write_held = 0;
+		lock_is_write_held = false;
 		cxt.cur_ops->writeunlock();
 
 		stutter_wait("lock_torture_writer");
@@ -665,13 +665,13 @@ static int lock_torture_reader(void *arg)
 			schedule_timeout_uninterruptible(1);
 
 		cxt.cur_ops->readlock();
-		lock_is_read_held = 1;
+		lock_is_read_held = true;
 		if (WARN_ON_ONCE(lock_is_write_held))
 			lrsp->n_lock_fail++; /* rare, but... */
 
 		lrsp->n_lock_acquired++;
 		cxt.cur_ops->read_delay(&rand);
-		lock_is_read_held = 0;
+		lock_is_read_held = false;
 		cxt.cur_ops->readunlock();
 
 		stutter_wait("lock_torture_reader");
@@ -686,7 +686,7 @@ static int lock_torture_reader(void *arg)
 static void __torture_print_stats(char *page,
 				  struct lock_stress_stats *statp, bool write)
 {
-	bool fail = 0;
+	bool fail = false;
 	int i, n_stress;
 	long max = 0, min = statp ? statp[0].n_lock_acquired : 0;
 	long long sum = 0;
@@ -904,7 +904,7 @@ static int __init lock_torture_init(void)
 
 	/* Initialize the statistics so that each run gets its own numbers. */
 	if (nwriters_stress) {
-		lock_is_write_held = 0;
+		lock_is_write_held = false;
 		cxt.lwsa = kmalloc_array(cxt.nrealwriters_stress,
 					 sizeof(*cxt.lwsa),
 					 GFP_KERNEL);
@@ -935,7 +935,7 @@ static int __init lock_torture_init(void)
 		}
 
 		if (nreaders_stress) {
-			lock_is_read_held = 0;
+			lock_is_read_held = false;
 			cxt.lrsa = kmalloc_array(cxt.nrealreaders_stress,
 						 sizeof(*cxt.lrsa),
 						 GFP_KERNEL);
diff --git a/kernel/pid.c b/kernel/pid.c
index c835b844aca7..13bf76a6d569 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -500,6 +500,23 @@ struct pid *find_ge_pid(int nr, struct pid_namespace *ns)
 	return idr_get_next(&ns->idr, &nr);
 }
 
+struct pid *pidfd_get_pid(unsigned int fd)
+{
+	struct fd f;
+	struct pid *pid;
+
+	f = fdget(fd);
+	if (!f.file)
+		return ERR_PTR(-EBADF);
+
+	pid = pidfd_pid(f.file);
+	if (!IS_ERR(pid))
+		get_pid(pid);
+
+	fdput(f);
+	return pid;
+}
+
 /**
  * pidfd_create() - Create a new pid file descriptor.
  *
diff --git a/kernel/printk/console_cmdline.h b/kernel/printk/console_cmdline.h
index 11f19c466af5..3ca74ad391d6 100644
--- a/kernel/printk/console_cmdline.h
+++ b/kernel/printk/console_cmdline.h
@@ -6,6 +6,7 @@ struct console_cmdline
 {
 	char	name[16];			/* Name of the driver	    */
 	int	index;				/* Minor dev. to use	    */
+	bool	user_specified;			/* Specified by command line vs. platform */
 	char	*options;			/* Options for the driver   */
 #ifdef CONFIG_A11Y_BRAILLE_CONSOLE
 	char	*brl_options;			/* Options for braille driver */
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 9a9b6156270b..11c646e88cd4 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -280,6 +280,7 @@ static struct console *exclusive_console;
 static struct console_cmdline console_cmdline[MAX_CMDLINECONSOLES];
 
 static int preferred_console = -1;
+static bool has_preferred_console;
 int console_set_on_cmdline;
 EXPORT_SYMBOL(console_set_on_cmdline);
 
@@ -2140,7 +2141,7 @@ asmlinkage __visible void early_printk(const char *fmt, ...)
 #endif
 
 static int __add_preferred_console(char *name, int idx, char *options,
-				   char *brl_options)
+				   char *brl_options, bool user_specified)
 {
 	struct console_cmdline *c;
 	int i;
@@ -2155,6 +2156,8 @@ static int __add_preferred_console(char *name, int idx, char *options,
 		if (strcmp(c->name, name) == 0 && c->index == idx) {
 			if (!brl_options)
 				preferred_console = i;
+			if (user_specified)
+				c->user_specified = true;
 			return 0;
 		}
 	}
@@ -2164,6 +2167,7 @@ static int __add_preferred_console(char *name, int idx, char *options,
 		preferred_console = i;
 	strlcpy(c->name, name, sizeof(c->name));
 	c->options = options;
+	c->user_specified = user_specified;
 	braille_set_options(c, brl_options);
 
 	c->index = idx;
@@ -2218,7 +2222,7 @@ static int __init console_setup(char *str)
 	idx = simple_strtoul(s, NULL, 10);
 	*s = 0;
 
-	__add_preferred_console(buf, idx, options, brl_options);
+	__add_preferred_console(buf, idx, options, brl_options, true);
 	console_set_on_cmdline = 1;
 	return 1;
 }
@@ -2239,7 +2243,7 @@ __setup("console=", console_setup);
  */
 int add_preferred_console(char *name, int idx, char *options)
 {
-	return __add_preferred_console(name, idx, options, NULL);
+	return __add_preferred_console(name, idx, options, NULL, false);
 }
 
 bool console_suspend_enabled = true;
@@ -2438,9 +2442,9 @@ void console_unlock(void)
 		printk_safe_enter_irqsave(flags);
 		raw_spin_lock(&logbuf_lock);
 		if (console_seq < log_first_seq) {
-			len = sprintf(text,
-				      "** %llu printk messages dropped **\n",
-				      log_first_seq - console_seq);
+			len = snprintf(text, sizeof(text),
+				       "** %llu printk messages dropped **\n",
+				       log_first_seq - console_seq);
 
 			/* messages are gone, move to first one */
 			console_seq = log_first_seq;
@@ -2651,6 +2655,63 @@ static int __init keep_bootcon_setup(char *str)
 
 early_param("keep_bootcon", keep_bootcon_setup);
 
+/*
+ * This is called by register_console() to try to match
+ * the newly registered console with any of the ones selected
+ * by either the command line or add_preferred_console() and
+ * setup/enable it.
+ *
+ * Care need to be taken with consoles that are statically
+ * enabled such as netconsole
+ */
+static int try_enable_new_console(struct console *newcon, bool user_specified)
+{
+	struct console_cmdline *c;
+	int i;
+
+	for (i = 0, c = console_cmdline;
+	     i < MAX_CMDLINECONSOLES && c->name[0];
+	     i++, c++) {
+		if (c->user_specified != user_specified)
+			continue;
+		if (!newcon->match ||
+		    newcon->match(newcon, c->name, c->index, c->options) != 0) {
+			/* default matching */
+			BUILD_BUG_ON(sizeof(c->name) != sizeof(newcon->name));
+			if (strcmp(c->name, newcon->name) != 0)
+				continue;
+			if (newcon->index >= 0 &&
+			    newcon->index != c->index)
+				continue;
+			if (newcon->index < 0)
+				newcon->index = c->index;
+
+			if (_braille_register_console(newcon, c))
+				return 0;
+
+			if (newcon->setup &&
+			    newcon->setup(newcon, c->options) != 0)
+				return -EIO;
+		}
+		newcon->flags |= CON_ENABLED;
+		if (i == preferred_console) {
+			newcon->flags |= CON_CONSDEV;
+			has_preferred_console = true;
+		}
+		return 0;
+	}
+
+	/*
+	 * Some consoles, such as pstore and netconsole, can be enabled even
+	 * without matching. Accept the pre-enabled consoles only when match()
+	 * and setup() had a change to be called.
+	 */
+	if (newcon->flags & CON_ENABLED && c->user_specified ==	user_specified)
+		return 0;
+
+	return -ENOENT;
+}
+
 /*
  * The console driver calls this routine during kernel initialization
  * to register the console printing procedure with printk() and to
@@ -2672,11 +2733,9 @@ early_param("keep_bootcon", keep_bootcon_setup);
  */
 void register_console(struct console *newcon)
 {
-	int i;
 	unsigned long flags;
 	struct console *bcon = NULL;
-	struct console_cmdline *c;
-	static bool has_preferred;
+	int err;
 
 	for_each_console(bcon) {
 		if (WARN(bcon == newcon, "console '%s%d' already registered\n",
@@ -2701,15 +2760,15 @@ void register_console(struct console *newcon)
 	if (console_drivers && console_drivers->flags & CON_BOOT)
 		bcon = console_drivers;
 
-	if (!has_preferred || bcon || !console_drivers)
-		has_preferred = preferred_console >= 0;
+	if (!has_preferred_console || bcon || !console_drivers)
+		has_preferred_console = preferred_console >= 0;
 
 	/*
 	 *	See if we want to use this console driver. If we
 	 *	didn't select a console we take the first one
 	 *	that registers here.
 	 */
-	if (!has_preferred) {
+	if (!has_preferred_console) {
 		if (newcon->index < 0)
 			newcon->index = 0;
 		if (newcon->setup == NULL ||
@@ -2717,47 +2776,20 @@ void register_console(struct console *newcon)
 			newcon->flags |= CON_ENABLED;
 			if (newcon->device) {
 				newcon->flags |= CON_CONSDEV;
-				has_preferred = true;
+				has_preferred_console = true;
 			}
 		}
 	}
 
-	/*
-	 *	See if this console matches one we selected on
-	 *	the command line.
-	 */
-	for (i = 0, c = console_cmdline;
-	     i < MAX_CMDLINECONSOLES && c->name[0];
-	     i++, c++) {
-		if (!newcon->match ||
-		    newcon->match(newcon, c->name, c->index, c->options) != 0) {
-			/* default matching */
-			BUILD_BUG_ON(sizeof(c->name) != sizeof(newcon->name));
-			if (strcmp(c->name, newcon->name) != 0)
-				continue;
-			if (newcon->index >= 0 &&
-			    newcon->index != c->index)
-				continue;
-			if (newcon->index < 0)
-				newcon->index = c->index;
-
-			if (_braille_register_console(newcon, c))
-				return;
-
-			if (newcon->setup &&
-			    newcon->setup(newcon, c->options) != 0)
-				break;
-		}
+	/* See if this console matches one we selected on the command line */
+	err = try_enable_new_console(newcon, true);
 
-		newcon->flags |= CON_ENABLED;
-		if (i == preferred_console) {
-			newcon->flags |= CON_CONSDEV;
-			has_preferred = true;
-		}
-		break;
-	}
+	/* If not, try to match against the platform default(s) */
+	if (err == -ENOENT)
+		err = try_enable_new_console(newcon, false);
 
-	if (!(newcon->flags & CON_ENABLED))
+	/* printk() messages are not printed to the Braille console. */
+	if (err || newcon->flags & CON_BRL)
 		return;
 
 	/*
@@ -2779,6 +2811,8 @@ void register_console(struct console *newcon)
 		console_drivers = newcon;
 		if (newcon->next)
 			newcon->next->flags &= ~CON_CONSDEV;
+		/* Ensure this flag is always set for the head of the list */
+		newcon->flags |= CON_CONSDEV;
 	} else {
 		newcon->next = console_drivers->next;
 		console_drivers->next = newcon;
diff --git a/kernel/rcu/Kconfig b/kernel/rcu/Kconfig
index 1cc940fef17c..0ebe15a84985 100644
--- a/kernel/rcu/Kconfig
+++ b/kernel/rcu/Kconfig
@@ -70,13 +70,37 @@ config TREE_SRCU
 	help
 	  This option selects the full-fledged version of SRCU.
 
+config TASKS_RCU_GENERIC
+	def_bool TASKS_RCU || TASKS_RUDE_RCU || TASKS_TRACE_RCU
+	select SRCU
+	help
+	  This option enables generic infrastructure code supporting
+	  task-based RCU implementations.  Not for manual selection.
+
 config TASKS_RCU
 	def_bool PREEMPTION
-	select SRCU
 	help
 	  This option enables a task-based RCU implementation that uses
 	  only voluntary context switch (not preemption!), idle, and
-	  user-mode execution as quiescent states.
+	  user-mode execution as quiescent states.  Not for manual selection.
+
+config TASKS_RUDE_RCU
+	def_bool 0
+	help
+	  This option enables a task-based RCU implementation that uses
+	  only context switch (including preemption) and user-mode
+	  execution as quiescent states.  It forces IPIs and context
+	  switches on all online CPUs, including idle ones, so use
+	  with caution.
+
+config TASKS_TRACE_RCU
+	def_bool 0
+	help
+	  This option enables a task-based RCU implementation that uses
+	  explicit rcu_read_lock_trace() read-side markers, and allows
+	  these readers to appear in the idle loop as well as on the CPU
+	  hotplug code paths.  It can force IPIs on online CPUs, including
+	  idle ones, so use with caution.
 
 config RCU_STALL_COMMON
 	def_bool TREE_RCU
@@ -210,4 +234,22 @@ config RCU_NOCB_CPU
 	  Say Y here if you want to help to debug reduced OS jitter.
 	  Say N here if you are unsure.
 
+config TASKS_TRACE_RCU_READ_MB
+	bool "Tasks Trace RCU readers use memory barriers in user and idle"
+	depends on RCU_EXPERT
+	default PREEMPT_RT || NR_CPUS < 8
+	help
+	  Use this option to further reduce the number of IPIs sent
+	  to CPUs executing in userspace or idle during tasks trace
+	  RCU grace periods.  Given that a reasonable setting of
+	  the rcupdate.rcu_task_ipi_delay kernel boot parameter
+	  eliminates such IPIs for many workloads, proper setting
+	  of this Kconfig option is important mostly for aggressive
+	  real-time installations and for battery-powered devices,
+	  hence the default chosen above.
+
+	  Say Y here if you hate IPIs.
+	  Say N here if you hate read-side memory barriers.
+	  Take the default if you are unsure.
+
 endmenu # "RCU Subsystem"
diff --git a/kernel/rcu/Kconfig.debug b/kernel/rcu/Kconfig.debug
index 4aa02eee8f6c..a4db41d9a401 100644
--- a/kernel/rcu/Kconfig.debug
+++ b/kernel/rcu/Kconfig.debug
@@ -9,15 +9,10 @@ config PROVE_RCU
 	def_bool PROVE_LOCKING
 
 config PROVE_RCU_LIST
-	bool "RCU list lockdep debugging"
-	depends on PROVE_RCU && RCU_EXPERT
-	default n
+	def_bool PROVE_RCU
 	help
-	  Enable RCU lockdep checking for list usages. By default it is
-	  turned off since there are several list RCU users that still
-	  need to be converted to pass a lockdep expression. To prevent
-	  false-positive splats, we keep it default disabled but once all
-	  users are converted, we can remove this config option.
+	  Enable RCU lockdep checking for list usages. It is default
+	  enabled with CONFIG_PROVE_RCU.
 
 config TORTURE_TEST
 	tristate
@@ -29,6 +24,8 @@ config RCU_PERF_TEST
 	select TORTURE_TEST
 	select SRCU
 	select TASKS_RCU
+	select TASKS_RUDE_RCU
+	select TASKS_TRACE_RCU
 	default n
 	help
 	  This option provides a kernel module that runs performance
@@ -46,6 +43,8 @@ config RCU_TORTURE_TEST
 	select TORTURE_TEST
 	select SRCU
 	select TASKS_RCU
+	select TASKS_RUDE_RCU
+	select TASKS_TRACE_RCU
 	default n
 	help
 	  This option provides a kernel module that runs torture tests
diff --git a/kernel/rcu/rcu.h b/kernel/rcu/rcu.h
index 00ddc92c5774..cf66a3ccd757 100644
--- a/kernel/rcu/rcu.h
+++ b/kernel/rcu/rcu.h
@@ -431,6 +431,7 @@ bool rcu_gp_is_expedited(void);  /* Internal RCU use. */
 void rcu_expedite_gp(void);
 void rcu_unexpedite_gp(void);
 void rcupdate_announce_bootup_oddness(void);
+void show_rcu_tasks_gp_kthreads(void);
 void rcu_request_urgent_qs_task(struct task_struct *t);
 #endif /* #else #ifdef CONFIG_TINY_RCU */
 
@@ -441,6 +442,8 @@ void rcu_request_urgent_qs_task(struct task_struct *t);
 enum rcutorture_type {
 	RCU_FLAVOR,
 	RCU_TASKS_FLAVOR,
+	RCU_TASKS_RUDE_FLAVOR,
+	RCU_TASKS_TRACING_FLAVOR,
 	RCU_TRIVIAL_FLAVOR,
 	SRCU_FLAVOR,
 	INVALID_RCU_FLAVOR
@@ -454,6 +457,7 @@ void do_trace_rcu_torture_read(const char *rcutorturename,
 			       unsigned long secs,
 			       unsigned long c_old,
 			       unsigned long c);
+void rcu_gp_set_torture_wait(int duration);
 #else
 static inline void rcutorture_get_gp_data(enum rcutorture_type test_type,
 					  int *flags, unsigned long *gp_seq)
@@ -471,6 +475,7 @@ void do_trace_rcu_torture_read(const char *rcutorturename,
 #define do_trace_rcu_torture_read(rcutorturename, rhp, secs, c_old, c) \
 	do { } while (0)
 #endif
+static inline void rcu_gp_set_torture_wait(int duration) { }
 #endif
 
 #if IS_ENABLED(CONFIG_RCU_TORTURE_TEST) || IS_MODULE(CONFIG_RCU_TORTURE_TEST)
@@ -498,6 +503,7 @@ void srcutorture_get_gp_data(enum rcutorture_type test_type,
 #endif
 
 #ifdef CONFIG_TINY_RCU
+static inline bool rcu_dynticks_zero_in_eqs(int cpu, int *vp) { return false; }
 static inline unsigned long rcu_get_gp_seq(void) { return 0; }
 static inline unsigned long rcu_exp_batches_completed(void) { return 0; }
 static inline unsigned long
@@ -507,6 +513,7 @@ static inline void show_rcu_gp_kthreads(void) { }
 static inline int rcu_get_gp_kthreads_prio(void) { return 0; }
 static inline void rcu_fwd_progress_check(unsigned long j) { }
 #else /* #ifdef CONFIG_TINY_RCU */
+bool rcu_dynticks_zero_in_eqs(int cpu, int *vp);
 unsigned long rcu_get_gp_seq(void);
 unsigned long rcu_exp_batches_completed(void);
 unsigned long srcu_batches_completed(struct srcu_struct *sp);
diff --git a/kernel/rcu/rcuperf.c b/kernel/rcu/rcuperf.c
index a4a8d097d84d..16dd1e6b7c09 100644
--- a/kernel/rcu/rcuperf.c
+++ b/kernel/rcu/rcuperf.c
@@ -88,6 +88,7 @@ torture_param(bool, shutdown, RCUPERF_SHUTDOWN,
 torture_param(int, verbose, 1, "Enable verbose debugging printk()s");
 torture_param(int, writer_holdoff, 0, "Holdoff (us) between GPs, zero to disable");
 torture_param(int, kfree_rcu_test, 0, "Do we run a kfree_rcu() perf test?");
+torture_param(int, kfree_mult, 1, "Multiple of kfree_obj size to allocate.");
 
 static char *perf_type = "rcu";
 module_param(perf_type, charp, 0444);
@@ -635,7 +636,7 @@ kfree_perf_thread(void *arg)
 		}
 
 		for (i = 0; i < kfree_alloc_num; i++) {
-			alloc_ptr = kmalloc(sizeof(struct kfree_obj), GFP_KERNEL);
+			alloc_ptr = kmalloc(kfree_mult * sizeof(struct kfree_obj), GFP_KERNEL);
 			if (!alloc_ptr)
 				return -ENOMEM;
 
@@ -722,6 +723,8 @@ kfree_perf_init(void)
 		schedule_timeout_uninterruptible(1);
 	}
 
+	pr_alert("kfree object size=%lu\n", kfree_mult * sizeof(struct kfree_obj));
+
 	kfree_reader_tasks = kcalloc(kfree_nrealthreads, sizeof(kfree_reader_tasks[0]),
 			       GFP_KERNEL);
 	if (kfree_reader_tasks == NULL) {
diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
index 5453bd557f43..efb792e13fca 100644
--- a/kernel/rcu/rcutorture.c
+++ b/kernel/rcu/rcutorture.c
@@ -20,7 +20,7 @@
 #include <linux/err.h>
 #include <linux/spinlock.h>
 #include <linux/smp.h>
-#include <linux/rcupdate.h>
+#include <linux/rcupdate_wait.h>
 #include <linux/interrupt.h>
 #include <linux/sched/signal.h>
 #include <uapi/linux/sched/types.h>
@@ -45,12 +45,25 @@
 #include <linux/sched/sysctl.h>
 #include <linux/oom.h>
 #include <linux/tick.h>
+#include <linux/rcupdate_trace.h>
 
 #include "rcu.h"
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Paul E. McKenney <paulmck@linux.ibm.com> and Josh Triplett <josh@joshtriplett.org>");
 
+#ifndef data_race
+#define data_race(expr)							\
+	({								\
+		expr;							\
+	})
+#endif
+#ifndef ASSERT_EXCLUSIVE_WRITER
+#define ASSERT_EXCLUSIVE_WRITER(var) do { } while (0)
+#endif
+#ifndef ASSERT_EXCLUSIVE_ACCESS
+#define ASSERT_EXCLUSIVE_ACCESS(var) do { } while (0)
+#endif
 
 /* Bits for ->extendables field, extendables param, and related definitions. */
 #define RCUTORTURE_RDR_SHIFT	 8	/* Put SRCU index in upper bits. */
@@ -102,6 +115,9 @@ torture_param(int, stall_cpu, 0, "Stall duration (s), zero to disable.");
 torture_param(int, stall_cpu_holdoff, 10,
 	     "Time to wait before starting stall (s).");
 torture_param(int, stall_cpu_irqsoff, 0, "Disable interrupts while stalling.");
+torture_param(int, stall_cpu_block, 0, "Sleep while stalling.");
+torture_param(int, stall_gp_kthread, 0,
+	      "Grace-period kthread stall duration (s).");
 torture_param(int, stat_interval, 60,
 	     "Number of seconds between stats printk()s");
 torture_param(int, stutter, 5, "Number of seconds to run/halt test");
@@ -665,6 +681,11 @@ static void rcu_tasks_torture_deferred_free(struct rcu_torture *p)
 	call_rcu_tasks(&p->rtort_rcu, rcu_torture_cb);
 }
 
+static void synchronize_rcu_mult_test(void)
+{
+	synchronize_rcu_mult(call_rcu_tasks, call_rcu);
+}
+
 static struct rcu_torture_ops tasks_ops = {
 	.ttype		= RCU_TASKS_FLAVOR,
 	.init		= rcu_sync_torture_init,
@@ -674,7 +695,7 @@ static struct rcu_torture_ops tasks_ops = {
 	.get_gp_seq	= rcu_no_completed,
 	.deferred_free	= rcu_tasks_torture_deferred_free,
 	.sync		= synchronize_rcu_tasks,
-	.exp_sync	= synchronize_rcu_tasks,
+	.exp_sync	= synchronize_rcu_mult_test,
 	.call		= call_rcu_tasks,
 	.cb_barrier	= rcu_barrier_tasks,
 	.fqs		= NULL,
@@ -725,6 +746,72 @@ static struct rcu_torture_ops trivial_ops = {
 	.name		= "trivial"
 };
 
+/*
+ * Definitions for rude RCU-tasks torture testing.
+ */
+
+static void rcu_tasks_rude_torture_deferred_free(struct rcu_torture *p)
+{
+	call_rcu_tasks_rude(&p->rtort_rcu, rcu_torture_cb);
+}
+
+static struct rcu_torture_ops tasks_rude_ops = {
+	.ttype		= RCU_TASKS_RUDE_FLAVOR,
+	.init		= rcu_sync_torture_init,
+	.readlock	= rcu_torture_read_lock_trivial,
+	.read_delay	= rcu_read_delay,  /* just reuse rcu's version. */
+	.readunlock	= rcu_torture_read_unlock_trivial,
+	.get_gp_seq	= rcu_no_completed,
+	.deferred_free	= rcu_tasks_rude_torture_deferred_free,
+	.sync		= synchronize_rcu_tasks_rude,
+	.exp_sync	= synchronize_rcu_tasks_rude,
+	.call		= call_rcu_tasks_rude,
+	.cb_barrier	= rcu_barrier_tasks_rude,
+	.fqs		= NULL,
+	.stats		= NULL,
+	.irq_capable	= 1,
+	.name		= "tasks-rude"
+};
+
+/*
+ * Definitions for tracing RCU-tasks torture testing.
+ */
+
+static int tasks_tracing_torture_read_lock(void)
+{
+	rcu_read_lock_trace();
+	return 0;
+}
+
+static void tasks_tracing_torture_read_unlock(int idx)
+{
+	rcu_read_unlock_trace();
+}
+
+static void rcu_tasks_tracing_torture_deferred_free(struct rcu_torture *p)
+{
+	call_rcu_tasks_trace(&p->rtort_rcu, rcu_torture_cb);
+}
+
+static struct rcu_torture_ops tasks_tracing_ops = {
+	.ttype		= RCU_TASKS_TRACING_FLAVOR,
+	.init		= rcu_sync_torture_init,
+	.readlock	= tasks_tracing_torture_read_lock,
+	.read_delay	= srcu_read_delay,  /* just reuse srcu's version. */
+	.readunlock	= tasks_tracing_torture_read_unlock,
+	.get_gp_seq	= rcu_no_completed,
+	.deferred_free	= rcu_tasks_tracing_torture_deferred_free,
+	.sync		= synchronize_rcu_tasks_trace,
+	.exp_sync	= synchronize_rcu_tasks_trace,
+	.call		= call_rcu_tasks_trace,
+	.cb_barrier	= rcu_barrier_tasks_trace,
+	.fqs		= NULL,
+	.stats		= NULL,
+	.irq_capable	= 1,
+	.slow_gps	= 1,
+	.name		= "tasks-tracing"
+};
+
 static unsigned long rcutorture_seq_diff(unsigned long new, unsigned long old)
 {
 	if (!cur_ops->gp_diff)
@@ -734,7 +821,7 @@ static unsigned long rcutorture_seq_diff(unsigned long new, unsigned long old)
 
 static bool __maybe_unused torturing_tasks(void)
 {
-	return cur_ops == &tasks_ops;
+	return cur_ops == &tasks_ops || cur_ops == &tasks_rude_ops;
 }
 
 /*
@@ -833,7 +920,7 @@ static int rcu_torture_boost(void *arg)
 
 		/* Wait for the next test interval. */
 		oldstarttime = boost_starttime;
-		while (ULONG_CMP_LT(jiffies, oldstarttime)) {
+		while (time_before(jiffies, oldstarttime)) {
 			schedule_timeout_interruptible(oldstarttime - jiffies);
 			stutter_wait("rcu_torture_boost");
 			if (torture_must_stop())
@@ -843,7 +930,7 @@ static int rcu_torture_boost(void *arg)
 		/* Do one boost-test interval. */
 		endtime = oldstarttime + test_boost_duration * HZ;
 		call_rcu_time = jiffies;
-		while (ULONG_CMP_LT(jiffies, endtime)) {
+		while (time_before(jiffies, endtime)) {
 			/* If we don't have a callback in flight, post one. */
 			if (!smp_load_acquire(&rbi.inflight)) {
 				/* RCU core before ->inflight = 1. */
@@ -914,7 +1001,7 @@ rcu_torture_fqs(void *arg)
 	VERBOSE_TOROUT_STRING("rcu_torture_fqs task started");
 	do {
 		fqs_resume_time = jiffies + fqs_stutter * HZ;
-		while (ULONG_CMP_LT(jiffies, fqs_resume_time) &&
+		while (time_before(jiffies, fqs_resume_time) &&
 		       !kthread_should_stop()) {
 			schedule_timeout_interruptible(1);
 		}
@@ -1147,6 +1234,7 @@ static void rcutorture_one_extend(int *readstate, int newstate,
 				  struct torture_random_state *trsp,
 				  struct rt_read_seg *rtrsp)
 {
+	unsigned long flags;
 	int idxnew = -1;
 	int idxold = *readstate;
 	int statesnew = ~*readstate & newstate;
@@ -1181,8 +1269,15 @@ static void rcutorture_one_extend(int *readstate, int newstate,
 		rcu_read_unlock_bh();
 	if (statesold & RCUTORTURE_RDR_SCHED)
 		rcu_read_unlock_sched();
-	if (statesold & RCUTORTURE_RDR_RCU)
+	if (statesold & RCUTORTURE_RDR_RCU) {
+		bool lockit = !statesnew && !(torture_random(trsp) & 0xffff);
+
+		if (lockit)
+			raw_spin_lock_irqsave(&current->pi_lock, flags);
 		cur_ops->readunlock(idxold >> RCUTORTURE_RDR_SHIFT);
+		if (lockit)
+			raw_spin_unlock_irqrestore(&current->pi_lock, flags);
+	}
 
 	/* Delay if neither beginning nor end and there was a change. */
 	if ((statesnew || statesold) && *readstate && newstate)
@@ -1283,6 +1378,7 @@ static bool rcu_torture_one_read(struct torture_random_state *trsp)
 				  rcu_read_lock_bh_held() ||
 				  rcu_read_lock_sched_held() ||
 				  srcu_read_lock_held(srcu_ctlp) ||
+				  rcu_read_lock_trace_held() ||
 				  torturing_tasks());
 	if (p == NULL) {
 		/* Wait for rcu_torture_writer to get underway */
@@ -1444,9 +1540,9 @@ rcu_torture_stats_print(void)
 		atomic_long_read(&n_rcu_torture_timers));
 	torture_onoff_stats();
 	pr_cont("barrier: %ld/%ld:%ld\n",
-		n_barrier_successes,
-		n_barrier_attempts,
-		n_rcu_torture_barrier_error);
+		data_race(n_barrier_successes),
+		data_race(n_barrier_attempts),
+		data_race(n_rcu_torture_barrier_error));
 
 	pr_alert("%s%s ", torture_type, TORTURE_FLAG);
 	if (atomic_read(&n_rcu_torture_mberror) ||
@@ -1536,6 +1632,7 @@ rcu_torture_print_module_parms(struct rcu_torture_ops *cur_ops, const char *tag)
 		 "test_boost=%d/%d test_boost_interval=%d "
 		 "test_boost_duration=%d shutdown_secs=%d "
 		 "stall_cpu=%d stall_cpu_holdoff=%d stall_cpu_irqsoff=%d "
+		 "stall_cpu_block=%d "
 		 "n_barrier_cbs=%d "
 		 "onoff_interval=%d onoff_holdoff=%d\n",
 		 torture_type, tag, nrealreaders, nfakewriters,
@@ -1544,6 +1641,7 @@ rcu_torture_print_module_parms(struct rcu_torture_ops *cur_ops, const char *tag)
 		 test_boost, cur_ops->can_boost,
 		 test_boost_interval, test_boost_duration, shutdown_secs,
 		 stall_cpu, stall_cpu_holdoff, stall_cpu_irqsoff,
+		 stall_cpu_block,
 		 n_barrier_cbs,
 		 onoff_interval, onoff_holdoff);
 }
@@ -1599,6 +1697,7 @@ static int rcutorture_booster_init(unsigned int cpu)
  */
 static int rcu_torture_stall(void *args)
 {
+	int idx;
 	unsigned long stop_at;
 
 	VERBOSE_TOROUT_STRING("rcu_torture_stall task started");
@@ -1607,26 +1706,37 @@ static int rcu_torture_stall(void *args)
 		schedule_timeout_interruptible(stall_cpu_holdoff * HZ);
 		VERBOSE_TOROUT_STRING("rcu_torture_stall end holdoff");
 	}
-	if (!kthread_should_stop()) {
+	if (!kthread_should_stop() && stall_gp_kthread > 0) {
+		VERBOSE_TOROUT_STRING("rcu_torture_stall begin GP stall");
+		rcu_gp_set_torture_wait(stall_gp_kthread * HZ);
+		for (idx = 0; idx < stall_gp_kthread + 2; idx++) {
+			if (kthread_should_stop())
+				break;
+			schedule_timeout_uninterruptible(HZ);
+		}
+	}
+	if (!kthread_should_stop() && stall_cpu > 0) {
+		VERBOSE_TOROUT_STRING("rcu_torture_stall begin CPU stall");
 		stop_at = ktime_get_seconds() + stall_cpu;
 		/* RCU CPU stall is expected behavior in following code. */
-		rcu_read_lock();
+		idx = cur_ops->readlock();
 		if (stall_cpu_irqsoff)
 			local_irq_disable();
-		else
+		else if (!stall_cpu_block)
 			preempt_disable();
 		pr_alert("rcu_torture_stall start on CPU %d.\n",
-			 smp_processor_id());
+			 raw_smp_processor_id());
 		while (ULONG_CMP_LT((unsigned long)ktime_get_seconds(),
 				    stop_at))
-			continue;  /* Induce RCU CPU stall warning. */
+			if (stall_cpu_block)
+				schedule_timeout_uninterruptible(HZ);
 		if (stall_cpu_irqsoff)
 			local_irq_enable();
-		else
+		else if (!stall_cpu_block)
 			preempt_enable();
-		rcu_read_unlock();
-		pr_alert("rcu_torture_stall end.\n");
+		cur_ops->readunlock(idx);
 	}
+	pr_alert("rcu_torture_stall end.\n");
 	torture_shutdown_absorb("rcu_torture_stall");
 	while (!kthread_should_stop())
 		schedule_timeout_interruptible(10 * HZ);
@@ -1636,7 +1746,7 @@ static int rcu_torture_stall(void *args)
 /* Spawn CPU-stall kthread, if stall_cpu specified. */
 static int __init rcu_torture_stall_init(void)
 {
-	if (stall_cpu <= 0)
+	if (stall_cpu <= 0 && stall_gp_kthread <= 0)
 		return 0;
 	return torture_create_kthread(rcu_torture_stall, NULL, stall_task);
 }
@@ -1692,8 +1802,8 @@ struct rcu_fwd {
 	unsigned long rcu_launder_gp_seq_start;
 };
 
-struct rcu_fwd *rcu_fwds;
-bool rcu_fwd_emergency_stop;
+static struct rcu_fwd *rcu_fwds;
+static bool rcu_fwd_emergency_stop;
 
 static void rcu_torture_fwd_cb_hist(struct rcu_fwd *rfp)
 {
@@ -2400,7 +2510,8 @@ rcu_torture_init(void)
 	int firsterr = 0;
 	static struct rcu_torture_ops *torture_ops[] = {
 		&rcu_ops, &rcu_busted_ops, &srcu_ops, &srcud_ops,
-		&busted_srcud_ops, &tasks_ops, &trivial_ops,
+		&busted_srcud_ops, &tasks_ops, &tasks_rude_ops,
+		&tasks_tracing_ops, &trivial_ops,
 	};
 
 	if (!torture_init_begin(torture_type, verbose))
diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c
index 0c71505f0e19..6d3ef700fb0e 100644
--- a/kernel/rcu/srcutree.c
+++ b/kernel/rcu/srcutree.c
@@ -29,6 +29,19 @@
 #include "rcu.h"
 #include "rcu_segcblist.h"
 
+#ifndef data_race
+#define data_race(expr)							\
+	({								\
+		expr;							\
+	})
+#endif
+#ifndef ASSERT_EXCLUSIVE_WRITER
+#define ASSERT_EXCLUSIVE_WRITER(var) do { } while (0)
+#endif
+#ifndef ASSERT_EXCLUSIVE_ACCESS
+#define ASSERT_EXCLUSIVE_ACCESS(var) do { } while (0)
+#endif
+
 /* Holdoff in nanoseconds for auto-expediting. */
 #define DEFAULT_SRCU_EXP_HOLDOFF (25 * 1000)
 static ulong exp_holdoff = DEFAULT_SRCU_EXP_HOLDOFF;
@@ -1268,8 +1281,8 @@ void srcu_torture_stats_print(struct srcu_struct *ssp, char *tt, char *tf)
 		struct srcu_data *sdp;
 
 		sdp = per_cpu_ptr(ssp->sda, cpu);
-		u0 = sdp->srcu_unlock_count[!idx];
-		u1 = sdp->srcu_unlock_count[idx];
+		u0 = data_race(sdp->srcu_unlock_count[!idx]);
+		u1 = data_race(sdp->srcu_unlock_count[idx]);
 
 		/*
 		 * Make sure that a lock is always counted if the corresponding
@@ -1277,8 +1290,8 @@ void srcu_torture_stats_print(struct srcu_struct *ssp, char *tt, char *tf)
 		 */
 		smp_rmb();
 
-		l0 = sdp->srcu_lock_count[!idx];
-		l1 = sdp->srcu_lock_count[idx];
+		l0 = data_race(sdp->srcu_lock_count[!idx]);
+		l1 = data_race(sdp->srcu_lock_count[idx]);
 
 		c0 = l0 - u0;
 		c1 = l1 - u1;
diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h
new file mode 100644
index 000000000000..234847f53fdb
--- /dev/null
+++ b/kernel/rcu/tasks.h
@@ -0,0 +1,1189 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Task-based RCU implementations.
+ *
+ * Copyright (C) 2020 Paul E. McKenney
+ */
+
+#ifdef CONFIG_TASKS_RCU_GENERIC
+
+////////////////////////////////////////////////////////////////////////
+//
+// Generic data structures.
+
+struct rcu_tasks;
+typedef void (*rcu_tasks_gp_func_t)(struct rcu_tasks *rtp);
+typedef void (*pregp_func_t)(void);
+typedef void (*pertask_func_t)(struct task_struct *t, struct list_head *hop);
+typedef void (*postscan_func_t)(struct list_head *hop);
+typedef void (*holdouts_func_t)(struct list_head *hop, bool ndrpt, bool *frptp);
+typedef void (*postgp_func_t)(struct rcu_tasks *rtp);
+
+/**
+ * Definition for a Tasks-RCU-like mechanism.
+ * @cbs_head: Head of callback list.
+ * @cbs_tail: Tail pointer for callback list.
+ * @cbs_wq: Wait queue allowning new callback to get kthread's attention.
+ * @cbs_lock: Lock protecting callback list.
+ * @kthread_ptr: This flavor's grace-period/callback-invocation kthread.
+ * @gp_func: This flavor's grace-period-wait function.
+ * @gp_state: Grace period's most recent state transition (debugging).
+ * @gp_jiffies: Time of last @gp_state transition.
+ * @gp_start: Most recent grace-period start in jiffies.
+ * @n_gps: Number of grace periods completed since boot.
+ * @n_ipis: Number of IPIs sent to encourage grace periods to end.
+ * @n_ipis_fails: Number of IPI-send failures.
+ * @pregp_func: This flavor's pre-grace-period function (optional).
+ * @pertask_func: This flavor's per-task scan function (optional).
+ * @postscan_func: This flavor's post-task scan function (optional).
+ * @holdout_func: This flavor's holdout-list scan function (optional).
+ * @postgp_func: This flavor's post-grace-period function (optional).
+ * @call_func: This flavor's call_rcu()-equivalent function.
+ * @name: This flavor's textual name.
+ * @kname: This flavor's kthread name.
+ */
+struct rcu_tasks {
+	struct rcu_head *cbs_head;
+	struct rcu_head **cbs_tail;
+	struct wait_queue_head cbs_wq;
+	raw_spinlock_t cbs_lock;
+	int gp_state;
+	unsigned long gp_jiffies;
+	unsigned long gp_start;
+	unsigned long n_gps;
+	unsigned long n_ipis;
+	unsigned long n_ipis_fails;
+	struct task_struct *kthread_ptr;
+	rcu_tasks_gp_func_t gp_func;
+	pregp_func_t pregp_func;
+	pertask_func_t pertask_func;
+	postscan_func_t postscan_func;
+	holdouts_func_t holdouts_func;
+	postgp_func_t postgp_func;
+	call_rcu_func_t call_func;
+	char *name;
+	char *kname;
+};
+
+#define DEFINE_RCU_TASKS(rt_name, gp, call, n)				\
+static struct rcu_tasks rt_name =					\
+{									\
+	.cbs_tail = &rt_name.cbs_head,					\
+	.cbs_wq = __WAIT_QUEUE_HEAD_INITIALIZER(rt_name.cbs_wq),	\
+	.cbs_lock = __RAW_SPIN_LOCK_UNLOCKED(rt_name.cbs_lock),		\
+	.gp_func = gp,							\
+	.call_func = call,						\
+	.name = n,							\
+	.kname = #rt_name,						\
+}
+
+/* Track exiting tasks in order to allow them to be waited for. */
+DEFINE_STATIC_SRCU(tasks_rcu_exit_srcu);
+
+/* Avoid IPIing CPUs early in the grace period. */
+#define RCU_TASK_IPI_DELAY (HZ / 2)
+static int rcu_task_ipi_delay __read_mostly = RCU_TASK_IPI_DELAY;
+module_param(rcu_task_ipi_delay, int, 0644);
+
+/* Control stall timeouts.  Disable with <= 0, otherwise jiffies till stall. */
+#define RCU_TASK_STALL_TIMEOUT (HZ * 60 * 10)
+static int rcu_task_stall_timeout __read_mostly = RCU_TASK_STALL_TIMEOUT;
+module_param(rcu_task_stall_timeout, int, 0644);
+
+/* RCU tasks grace-period state for debugging. */
+#define RTGS_INIT		 0
+#define RTGS_WAIT_WAIT_CBS	 1
+#define RTGS_WAIT_GP		 2
+#define RTGS_PRE_WAIT_GP	 3
+#define RTGS_SCAN_TASKLIST	 4
+#define RTGS_POST_SCAN_TASKLIST	 5
+#define RTGS_WAIT_SCAN_HOLDOUTS	 6
+#define RTGS_SCAN_HOLDOUTS	 7
+#define RTGS_POST_GP		 8
+#define RTGS_WAIT_READERS	 9
+#define RTGS_INVOKE_CBS		10
+#define RTGS_WAIT_CBS		11
+static const char * const rcu_tasks_gp_state_names[] = {
+	"RTGS_INIT",
+	"RTGS_WAIT_WAIT_CBS",
+	"RTGS_WAIT_GP",
+	"RTGS_PRE_WAIT_GP",
+	"RTGS_SCAN_TASKLIST",
+	"RTGS_POST_SCAN_TASKLIST",
+	"RTGS_WAIT_SCAN_HOLDOUTS",
+	"RTGS_SCAN_HOLDOUTS",
+	"RTGS_POST_GP",
+	"RTGS_WAIT_READERS",
+	"RTGS_INVOKE_CBS",
+	"RTGS_WAIT_CBS",
+};
+
+////////////////////////////////////////////////////////////////////////
+//
+// Generic code.
+
+/* Record grace-period phase and time. */
+static void set_tasks_gp_state(struct rcu_tasks *rtp, int newstate)
+{
+	rtp->gp_state = newstate;
+	rtp->gp_jiffies = jiffies;
+}
+
+/* Return state name. */
+static const char *tasks_gp_state_getname(struct rcu_tasks *rtp)
+{
+	int i = data_race(rtp->gp_state); // Let KCSAN detect update races
+	int j = READ_ONCE(i); // Prevent the compiler from reading twice
+
+	if (j >= ARRAY_SIZE(rcu_tasks_gp_state_names))
+		return "???";
+	return rcu_tasks_gp_state_names[j];
+}
+
+// Enqueue a callback for the specified flavor of Tasks RCU.
+static void call_rcu_tasks_generic(struct rcu_head *rhp, rcu_callback_t func,
+				   struct rcu_tasks *rtp)
+{
+	unsigned long flags;
+	bool needwake;
+
+	rhp->next = NULL;
+	rhp->func = func;
+	raw_spin_lock_irqsave(&rtp->cbs_lock, flags);
+	needwake = !rtp->cbs_head;
+	WRITE_ONCE(*rtp->cbs_tail, rhp);
+	rtp->cbs_tail = &rhp->next;
+	raw_spin_unlock_irqrestore(&rtp->cbs_lock, flags);
+	/* We can't create the thread unless interrupts are enabled. */
+	if (needwake && READ_ONCE(rtp->kthread_ptr))
+		wake_up(&rtp->cbs_wq);
+}
+
+// Wait for a grace period for the specified flavor of Tasks RCU.
+static void synchronize_rcu_tasks_generic(struct rcu_tasks *rtp)
+{
+	/* Complain if the scheduler has not started.  */
+	RCU_LOCKDEP_WARN(rcu_scheduler_active == RCU_SCHEDULER_INACTIVE,
+			 "synchronize_rcu_tasks called too soon");
+
+	/* Wait for the grace period. */
+	wait_rcu_gp(rtp->call_func);
+}
+
+/* RCU-tasks kthread that detects grace periods and invokes callbacks. */
+static int __noreturn rcu_tasks_kthread(void *arg)
+{
+	unsigned long flags;
+	struct rcu_head *list;
+	struct rcu_head *next;
+	struct rcu_tasks *rtp = arg;
+
+	/* Run on housekeeping CPUs by default.  Sysadm can move if desired. */
+	housekeeping_affine(current, HK_FLAG_RCU);
+	WRITE_ONCE(rtp->kthread_ptr, current); // Let GPs start!
+
+	/*
+	 * Each pass through the following loop makes one check for
+	 * newly arrived callbacks, and, if there are some, waits for
+	 * one RCU-tasks grace period and then invokes the callbacks.
+	 * This loop is terminated by the system going down.  ;-)
+	 */
+	for (;;) {
+
+		/* Pick up any new callbacks. */
+		raw_spin_lock_irqsave(&rtp->cbs_lock, flags);
+		smp_mb__after_spinlock(); // Order updates vs. GP.
+		list = rtp->cbs_head;
+		rtp->cbs_head = NULL;
+		rtp->cbs_tail = &rtp->cbs_head;
+		raw_spin_unlock_irqrestore(&rtp->cbs_lock, flags);
+
+		/* If there were none, wait a bit and start over. */
+		if (!list) {
+			wait_event_interruptible(rtp->cbs_wq,
+						 READ_ONCE(rtp->cbs_head));
+			if (!rtp->cbs_head) {
+				WARN_ON(signal_pending(current));
+				set_tasks_gp_state(rtp, RTGS_WAIT_WAIT_CBS);
+				schedule_timeout_interruptible(HZ/10);
+			}
+			continue;
+		}
+
+		// Wait for one grace period.
+		set_tasks_gp_state(rtp, RTGS_WAIT_GP);
+		rtp->gp_start = jiffies;
+		rtp->gp_func(rtp);
+		rtp->n_gps++;
+
+		/* Invoke the callbacks. */
+		set_tasks_gp_state(rtp, RTGS_INVOKE_CBS);
+		while (list) {
+			next = list->next;
+			local_bh_disable();
+			list->func(list);
+			local_bh_enable();
+			list = next;
+			cond_resched();
+		}
+		/* Paranoid sleep to keep this from entering a tight loop */
+		schedule_timeout_uninterruptible(HZ/10);
+
+		set_tasks_gp_state(rtp, RTGS_WAIT_CBS);
+	}
+}
+
+/* Spawn RCU-tasks grace-period kthread, e.g., at core_initcall() time. */
+static void __init rcu_spawn_tasks_kthread_generic(struct rcu_tasks *rtp)
+{
+	struct task_struct *t;
+
+	t = kthread_run(rcu_tasks_kthread, rtp, "%s_kthread", rtp->kname);
+	if (WARN_ONCE(IS_ERR(t), "%s: Could not start %s grace-period kthread, OOM is now expected behavior\n", __func__, rtp->name))
+		return;
+	smp_mb(); /* Ensure others see full kthread. */
+}
+
+#ifndef CONFIG_TINY_RCU
+
+/*
+ * Print any non-default Tasks RCU settings.
+ */
+static void __init rcu_tasks_bootup_oddness(void)
+{
+#if defined(CONFIG_TASKS_RCU) || defined(CONFIG_TASKS_TRACE_RCU)
+	if (rcu_task_stall_timeout != RCU_TASK_STALL_TIMEOUT)
+		pr_info("\tTasks-RCU CPU stall warnings timeout set to %d (rcu_task_stall_timeout).\n", rcu_task_stall_timeout);
+#endif /* #ifdef CONFIG_TASKS_RCU */
+#ifdef CONFIG_TASKS_RCU
+	pr_info("\tTrampoline variant of Tasks RCU enabled.\n");
+#endif /* #ifdef CONFIG_TASKS_RCU */
+#ifdef CONFIG_TASKS_RUDE_RCU
+	pr_info("\tRude variant of Tasks RCU enabled.\n");
+#endif /* #ifdef CONFIG_TASKS_RUDE_RCU */
+#ifdef CONFIG_TASKS_TRACE_RCU
+	pr_info("\tTracing variant of Tasks RCU enabled.\n");
+#endif /* #ifdef CONFIG_TASKS_TRACE_RCU */
+}
+
+#endif /* #ifndef CONFIG_TINY_RCU */
+
+/* Dump out rcutorture-relevant state common to all RCU-tasks flavors. */
+static void show_rcu_tasks_generic_gp_kthread(struct rcu_tasks *rtp, char *s)
+{
+	pr_info("%s: %s(%d) since %lu g:%lu i:%lu/%lu %c%c %s\n",
+		rtp->kname,
+		tasks_gp_state_getname(rtp), data_race(rtp->gp_state),
+		jiffies - data_race(rtp->gp_jiffies),
+		data_race(rtp->n_gps),
+		data_race(rtp->n_ipis_fails), data_race(rtp->n_ipis),
+		".k"[!!data_race(rtp->kthread_ptr)],
+		".C"[!!data_race(rtp->cbs_head)],
+		s);
+}
+
+static void exit_tasks_rcu_finish_trace(struct task_struct *t);
+
+#if defined(CONFIG_TASKS_RCU) || defined(CONFIG_TASKS_TRACE_RCU)
+
+////////////////////////////////////////////////////////////////////////
+//
+// Shared code between task-list-scanning variants of Tasks RCU.
+
+/* Wait for one RCU-tasks grace period. */
+static void rcu_tasks_wait_gp(struct rcu_tasks *rtp)
+{
+	struct task_struct *g, *t;
+	unsigned long lastreport;
+	LIST_HEAD(holdouts);
+	int fract;
+
+	set_tasks_gp_state(rtp, RTGS_PRE_WAIT_GP);
+	rtp->pregp_func();
+
+	/*
+	 * There were callbacks, so we need to wait for an RCU-tasks
+	 * grace period.  Start off by scanning the task list for tasks
+	 * that are not already voluntarily blocked.  Mark these tasks
+	 * and make a list of them in holdouts.
+	 */
+	set_tasks_gp_state(rtp, RTGS_SCAN_TASKLIST);
+	rcu_read_lock();
+	for_each_process_thread(g, t)
+		rtp->pertask_func(t, &holdouts);
+	rcu_read_unlock();
+
+	set_tasks_gp_state(rtp, RTGS_POST_SCAN_TASKLIST);
+	rtp->postscan_func(&holdouts);
+
+	/*
+	 * Each pass through the following loop scans the list of holdout
+	 * tasks, removing any that are no longer holdouts.  When the list
+	 * is empty, we are done.
+	 */
+	lastreport = jiffies;
+
+	/* Start off with HZ/10 wait and slowly back off to 1 HZ wait. */
+	fract = 10;
+
+	for (;;) {
+		bool firstreport;
+		bool needreport;
+		int rtst;
+
+		if (list_empty(&holdouts))
+			break;
+
+		/* Slowly back off waiting for holdouts */
+		set_tasks_gp_state(rtp, RTGS_WAIT_SCAN_HOLDOUTS);
+		schedule_timeout_interruptible(HZ/fract);
+
+		if (fract > 1)
+			fract--;
+
+		rtst = READ_ONCE(rcu_task_stall_timeout);
+		needreport = rtst > 0 && time_after(jiffies, lastreport + rtst);
+		if (needreport)
+			lastreport = jiffies;
+		firstreport = true;
+		WARN_ON(signal_pending(current));
+		set_tasks_gp_state(rtp, RTGS_SCAN_HOLDOUTS);
+		rtp->holdouts_func(&holdouts, needreport, &firstreport);
+	}
+
+	set_tasks_gp_state(rtp, RTGS_POST_GP);
+	rtp->postgp_func(rtp);
+}
+
+#endif /* #if defined(CONFIG_TASKS_RCU) || defined(CONFIG_TASKS_TRACE_RCU) */
+
+#ifdef CONFIG_TASKS_RCU
+
+////////////////////////////////////////////////////////////////////////
+//
+// Simple variant of RCU whose quiescent states are voluntary context
+// switch, cond_resched_rcu_qs(), user-space execution, and idle.
+// As such, grace periods can take one good long time.  There are no
+// read-side primitives similar to rcu_read_lock() and rcu_read_unlock()
+// because this implementation is intended to get the system into a safe
+// state for some of the manipulations involved in tracing and the like.
+// Finally, this implementation does not support high call_rcu_tasks()
+// rates from multiple CPUs.  If this is required, per-CPU callback lists
+// will be needed.
+
+/* Pre-grace-period preparation. */
+static void rcu_tasks_pregp_step(void)
+{
+	/*
+	 * Wait for all pre-existing t->on_rq and t->nvcsw transitions
+	 * to complete.  Invoking synchronize_rcu() suffices because all
+	 * these transitions occur with interrupts disabled.  Without this
+	 * synchronize_rcu(), a read-side critical section that started
+	 * before the grace period might be incorrectly seen as having
+	 * started after the grace period.
+	 *
+	 * This synchronize_rcu() also dispenses with the need for a
+	 * memory barrier on the first store to t->rcu_tasks_holdout,
+	 * as it forces the store to happen after the beginning of the
+	 * grace period.
+	 */
+	synchronize_rcu();
+}
+
+/* Per-task initial processing. */
+static void rcu_tasks_pertask(struct task_struct *t, struct list_head *hop)
+{
+	if (t != current && READ_ONCE(t->on_rq) && !is_idle_task(t)) {
+		get_task_struct(t);
+		t->rcu_tasks_nvcsw = READ_ONCE(t->nvcsw);
+		WRITE_ONCE(t->rcu_tasks_holdout, true);
+		list_add(&t->rcu_tasks_holdout_list, hop);
+	}
+}
+
+/* Processing between scanning taskslist and draining the holdout list. */
+void rcu_tasks_postscan(struct list_head *hop)
+{
+	/*
+	 * Wait for tasks that are in the process of exiting.  This
+	 * does only part of the job, ensuring that all tasks that were
+	 * previously exiting reach the point where they have disabled
+	 * preemption, allowing the later synchronize_rcu() to finish
+	 * the job.
+	 */
+	synchronize_srcu(&tasks_rcu_exit_srcu);
+}
+
+/* See if tasks are still holding out, complain if so. */
+static void check_holdout_task(struct task_struct *t,
+			       bool needreport, bool *firstreport)
+{
+	int cpu;
+
+	if (!READ_ONCE(t->rcu_tasks_holdout) ||
+	    t->rcu_tasks_nvcsw != READ_ONCE(t->nvcsw) ||
+	    !READ_ONCE(t->on_rq) ||
+	    (IS_ENABLED(CONFIG_NO_HZ_FULL) &&
+	     !is_idle_task(t) && t->rcu_tasks_idle_cpu >= 0)) {
+		WRITE_ONCE(t->rcu_tasks_holdout, false);
+		list_del_init(&t->rcu_tasks_holdout_list);
+		put_task_struct(t);
+		return;
+	}
+	rcu_request_urgent_qs_task(t);
+	if (!needreport)
+		return;
+	if (*firstreport) {
+		pr_err("INFO: rcu_tasks detected stalls on tasks:\n");
+		*firstreport = false;
+	}
+	cpu = task_cpu(t);
+	pr_alert("%p: %c%c nvcsw: %lu/%lu holdout: %d idle_cpu: %d/%d\n",
+		 t, ".I"[is_idle_task(t)],
+		 "N."[cpu < 0 || !tick_nohz_full_cpu(cpu)],
+		 t->rcu_tasks_nvcsw, t->nvcsw, t->rcu_tasks_holdout,
+		 t->rcu_tasks_idle_cpu, cpu);
+	sched_show_task(t);
+}
+
+/* Scan the holdout lists for tasks no longer holding out. */
+static void check_all_holdout_tasks(struct list_head *hop,
+				    bool needreport, bool *firstreport)
+{
+	struct task_struct *t, *t1;
+
+	list_for_each_entry_safe(t, t1, hop, rcu_tasks_holdout_list) {
+		check_holdout_task(t, needreport, firstreport);
+		cond_resched();
+	}
+}
+
+/* Finish off the Tasks-RCU grace period. */
+static void rcu_tasks_postgp(struct rcu_tasks *rtp)
+{
+	/*
+	 * Because ->on_rq and ->nvcsw are not guaranteed to have a full
+	 * memory barriers prior to them in the schedule() path, memory
+	 * reordering on other CPUs could cause their RCU-tasks read-side
+	 * critical sections to extend past the end of the grace period.
+	 * However, because these ->nvcsw updates are carried out with
+	 * interrupts disabled, we can use synchronize_rcu() to force the
+	 * needed ordering on all such CPUs.
+	 *
+	 * This synchronize_rcu() also confines all ->rcu_tasks_holdout
+	 * accesses to be within the grace period, avoiding the need for
+	 * memory barriers for ->rcu_tasks_holdout accesses.
+	 *
+	 * In addition, this synchronize_rcu() waits for exiting tasks
+	 * to complete their final preempt_disable() region of execution,
+	 * cleaning up after the synchronize_srcu() above.
+	 */
+	synchronize_rcu();
+}
+
+void call_rcu_tasks(struct rcu_head *rhp, rcu_callback_t func);
+DEFINE_RCU_TASKS(rcu_tasks, rcu_tasks_wait_gp, call_rcu_tasks, "RCU Tasks");
+
+/**
+ * call_rcu_tasks() - Queue an RCU for invocation task-based grace period
+ * @rhp: structure to be used for queueing the RCU updates.
+ * @func: actual callback function to be invoked after the grace period
+ *
+ * The callback function will be invoked some time after a full grace
+ * period elapses, in other words after all currently executing RCU
+ * read-side critical sections have completed. call_rcu_tasks() assumes
+ * that the read-side critical sections end at a voluntary context
+ * switch (not a preemption!), cond_resched_rcu_qs(), entry into idle,
+ * or transition to usermode execution.  As such, there are no read-side
+ * primitives analogous to rcu_read_lock() and rcu_read_unlock() because
+ * this primitive is intended to determine that all tasks have passed
+ * through a safe state, not so much for data-strcuture synchronization.
+ *
+ * See the description of call_rcu() for more detailed information on
+ * memory ordering guarantees.
+ */
+void call_rcu_tasks(struct rcu_head *rhp, rcu_callback_t func)
+{
+	call_rcu_tasks_generic(rhp, func, &rcu_tasks);
+}
+EXPORT_SYMBOL_GPL(call_rcu_tasks);
+
+/**
+ * synchronize_rcu_tasks - wait until an rcu-tasks grace period has elapsed.
+ *
+ * Control will return to the caller some time after a full rcu-tasks
+ * grace period has elapsed, in other words after all currently
+ * executing rcu-tasks read-side critical sections have elapsed.  These
+ * read-side critical sections are delimited by calls to schedule(),
+ * cond_resched_tasks_rcu_qs(), idle execution, userspace execution, calls
+ * to synchronize_rcu_tasks(), and (in theory, anyway) cond_resched().
+ *
+ * This is a very specialized primitive, intended only for a few uses in
+ * tracing and other situations requiring manipulation of function
+ * preambles and profiling hooks.  The synchronize_rcu_tasks() function
+ * is not (yet) intended for heavy use from multiple CPUs.
+ *
+ * See the description of synchronize_rcu() for more detailed information
+ * on memory ordering guarantees.
+ */
+void synchronize_rcu_tasks(void)
+{
+	synchronize_rcu_tasks_generic(&rcu_tasks);
+}
+EXPORT_SYMBOL_GPL(synchronize_rcu_tasks);
+
+/**
+ * rcu_barrier_tasks - Wait for in-flight call_rcu_tasks() callbacks.
+ *
+ * Although the current implementation is guaranteed to wait, it is not
+ * obligated to, for example, if there are no pending callbacks.
+ */
+void rcu_barrier_tasks(void)
+{
+	/* There is only one callback queue, so this is easy.  ;-) */
+	synchronize_rcu_tasks();
+}
+EXPORT_SYMBOL_GPL(rcu_barrier_tasks);
+
+static int __init rcu_spawn_tasks_kthread(void)
+{
+	rcu_tasks.pregp_func = rcu_tasks_pregp_step;
+	rcu_tasks.pertask_func = rcu_tasks_pertask;
+	rcu_tasks.postscan_func = rcu_tasks_postscan;
+	rcu_tasks.holdouts_func = check_all_holdout_tasks;
+	rcu_tasks.postgp_func = rcu_tasks_postgp;
+	rcu_spawn_tasks_kthread_generic(&rcu_tasks);
+	return 0;
+}
+core_initcall(rcu_spawn_tasks_kthread);
+
+static void show_rcu_tasks_classic_gp_kthread(void)
+{
+	show_rcu_tasks_generic_gp_kthread(&rcu_tasks, "");
+}
+
+/* Do the srcu_read_lock() for the above synchronize_srcu().  */
+void exit_tasks_rcu_start(void) __acquires(&tasks_rcu_exit_srcu)
+{
+	preempt_disable();
+	current->rcu_tasks_idx = __srcu_read_lock(&tasks_rcu_exit_srcu);
+	preempt_enable();
+}
+
+/* Do the srcu_read_unlock() for the above synchronize_srcu().  */
+void exit_tasks_rcu_finish(void) __releases(&tasks_rcu_exit_srcu)
+{
+	struct task_struct *t = current;
+
+	preempt_disable();
+	__srcu_read_unlock(&tasks_rcu_exit_srcu, t->rcu_tasks_idx);
+	preempt_enable();
+	exit_tasks_rcu_finish_trace(t);
+}
+
+#else /* #ifdef CONFIG_TASKS_RCU */
+static void show_rcu_tasks_classic_gp_kthread(void) { }
+void exit_tasks_rcu_start(void) { }
+void exit_tasks_rcu_finish(void) { exit_tasks_rcu_finish_trace(current); }
+#endif /* #else #ifdef CONFIG_TASKS_RCU */
+
+#ifdef CONFIG_TASKS_RUDE_RCU
+
+////////////////////////////////////////////////////////////////////////
+//
+// "Rude" variant of Tasks RCU, inspired by Steve Rostedt's trick of
+// passing an empty function to schedule_on_each_cpu().  This approach
+// provides an asynchronous call_rcu_tasks_rude() API and batching
+// of concurrent calls to the synchronous synchronize_rcu_rude() API.
+// This sends IPIs far and wide and induces otherwise unnecessary context
+// switches on all online CPUs, whether idle or not.
+
+// Empty function to allow workqueues to force a context switch.
+static void rcu_tasks_be_rude(struct work_struct *work)
+{
+}
+
+// Wait for one rude RCU-tasks grace period.
+static void rcu_tasks_rude_wait_gp(struct rcu_tasks *rtp)
+{
+	rtp->n_ipis += cpumask_weight(cpu_online_mask);
+	schedule_on_each_cpu(rcu_tasks_be_rude);
+}
+
+void call_rcu_tasks_rude(struct rcu_head *rhp, rcu_callback_t func);
+DEFINE_RCU_TASKS(rcu_tasks_rude, rcu_tasks_rude_wait_gp, call_rcu_tasks_rude,
+		 "RCU Tasks Rude");
+
+/**
+ * call_rcu_tasks_rude() - Queue a callback rude task-based grace period
+ * @rhp: structure to be used for queueing the RCU updates.
+ * @func: actual callback function to be invoked after the grace period
+ *
+ * The callback function will be invoked some time after a full grace
+ * period elapses, in other words after all currently executing RCU
+ * read-side critical sections have completed. call_rcu_tasks_rude()
+ * assumes that the read-side critical sections end at context switch,
+ * cond_resched_rcu_qs(), or transition to usermode execution.  As such,
+ * there are no read-side primitives analogous to rcu_read_lock() and
+ * rcu_read_unlock() because this primitive is intended to determine
+ * that all tasks have passed through a safe state, not so much for
+ * data-strcuture synchronization.
+ *
+ * See the description of call_rcu() for more detailed information on
+ * memory ordering guarantees.
+ */
+void call_rcu_tasks_rude(struct rcu_head *rhp, rcu_callback_t func)
+{
+	call_rcu_tasks_generic(rhp, func, &rcu_tasks_rude);
+}
+EXPORT_SYMBOL_GPL(call_rcu_tasks_rude);
+
+/**
+ * synchronize_rcu_tasks_rude - wait for a rude rcu-tasks grace period
+ *
+ * Control will return to the caller some time after a rude rcu-tasks
+ * grace period has elapsed, in other words after all currently
+ * executing rcu-tasks read-side critical sections have elapsed.  These
+ * read-side critical sections are delimited by calls to schedule(),
+ * cond_resched_tasks_rcu_qs(), userspace execution, and (in theory,
+ * anyway) cond_resched().
+ *
+ * This is a very specialized primitive, intended only for a few uses in
+ * tracing and other situations requiring manipulation of function preambles
+ * and profiling hooks.  The synchronize_rcu_tasks_rude() function is not
+ * (yet) intended for heavy use from multiple CPUs.
+ *
+ * See the description of synchronize_rcu() for more detailed information
+ * on memory ordering guarantees.
+ */
+void synchronize_rcu_tasks_rude(void)
+{
+	synchronize_rcu_tasks_generic(&rcu_tasks_rude);
+}
+EXPORT_SYMBOL_GPL(synchronize_rcu_tasks_rude);
+
+/**
+ * rcu_barrier_tasks_rude - Wait for in-flight call_rcu_tasks_rude() callbacks.
+ *
+ * Although the current implementation is guaranteed to wait, it is not
+ * obligated to, for example, if there are no pending callbacks.
+ */
+void rcu_barrier_tasks_rude(void)
+{
+	/* There is only one callback queue, so this is easy.  ;-) */
+	synchronize_rcu_tasks_rude();
+}
+EXPORT_SYMBOL_GPL(rcu_barrier_tasks_rude);
+
+static int __init rcu_spawn_tasks_rude_kthread(void)
+{
+	rcu_spawn_tasks_kthread_generic(&rcu_tasks_rude);
+	return 0;
+}
+core_initcall(rcu_spawn_tasks_rude_kthread);
+
+static void show_rcu_tasks_rude_gp_kthread(void)
+{
+	show_rcu_tasks_generic_gp_kthread(&rcu_tasks_rude, "");
+}
+
+#else /* #ifdef CONFIG_TASKS_RUDE_RCU */
+static void show_rcu_tasks_rude_gp_kthread(void) {}
+#endif /* #else #ifdef CONFIG_TASKS_RUDE_RCU */
+
+////////////////////////////////////////////////////////////////////////
+//
+// Tracing variant of Tasks RCU.  This variant is designed to be used
+// to protect tracing hooks, including those of BPF.  This variant
+// therefore:
+//
+// 1.	Has explicit read-side markers to allow finite grace periods
+//	in the face of in-kernel loops for PREEMPT=n builds.
+//
+// 2.	Protects code in the idle loop, exception entry/exit, and
+//	CPU-hotplug code paths, similar to the capabilities of SRCU.
+//
+// 3.	Avoids expensive read-side instruction, having overhead similar
+//	to that of Preemptible RCU.
+//
+// There are of course downsides.  The grace-period code can send IPIs to
+// CPUs, even when those CPUs are in the idle loop or in nohz_full userspace.
+// It is necessary to scan the full tasklist, much as for Tasks RCU.  There
+// is a single callback queue guarded by a single lock, again, much as for
+// Tasks RCU.  If needed, these downsides can be at least partially remedied.
+//
+// Perhaps most important, this variant of RCU does not affect the vanilla
+// flavors, rcu_preempt and rcu_sched.  The fact that RCU Tasks Trace
+// readers can operate from idle, offline, and exception entry/exit in no
+// way allows rcu_preempt and rcu_sched readers to also do so.
+
+// The lockdep state must be outside of #ifdef to be useful.
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+static struct lock_class_key rcu_lock_trace_key;
+struct lockdep_map rcu_trace_lock_map =
+	STATIC_LOCKDEP_MAP_INIT("rcu_read_lock_trace", &rcu_lock_trace_key);
+EXPORT_SYMBOL_GPL(rcu_trace_lock_map);
+#endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
+
+#ifdef CONFIG_TASKS_TRACE_RCU
+
+atomic_t trc_n_readers_need_end;	// Number of waited-for readers.
+DECLARE_WAIT_QUEUE_HEAD(trc_wait);	// List of holdout tasks.
+
+// Record outstanding IPIs to each CPU.  No point in sending two...
+static DEFINE_PER_CPU(bool, trc_ipi_to_cpu);
+
+// The number of detections of task quiescent state relying on
+// heavyweight readers executing explicit memory barriers.
+unsigned long n_heavy_reader_attempts;
+unsigned long n_heavy_reader_updates;
+unsigned long n_heavy_reader_ofl_updates;
+
+void call_rcu_tasks_trace(struct rcu_head *rhp, rcu_callback_t func);
+DEFINE_RCU_TASKS(rcu_tasks_trace, rcu_tasks_wait_gp, call_rcu_tasks_trace,
+		 "RCU Tasks Trace");
+
+/*
+ * This irq_work handler allows rcu_read_unlock_trace() to be invoked
+ * while the scheduler locks are held.
+ */
+static void rcu_read_unlock_iw(struct irq_work *iwp)
+{
+	wake_up(&trc_wait);
+}
+static DEFINE_IRQ_WORK(rcu_tasks_trace_iw, rcu_read_unlock_iw);
+
+/* If we are the last reader, wake up the grace-period kthread. */
+void rcu_read_unlock_trace_special(struct task_struct *t, int nesting)
+{
+	int nq = t->trc_reader_special.b.need_qs;
+
+	if (IS_ENABLED(CONFIG_TASKS_TRACE_RCU_READ_MB) &&
+	    t->trc_reader_special.b.need_mb)
+		smp_mb(); // Pairs with update-side barriers.
+	// Update .need_qs before ->trc_reader_nesting for irq/NMI handlers.
+	if (nq)
+		WRITE_ONCE(t->trc_reader_special.b.need_qs, false);
+	WRITE_ONCE(t->trc_reader_nesting, nesting);
+	if (nq && atomic_dec_and_test(&trc_n_readers_need_end))
+		irq_work_queue(&rcu_tasks_trace_iw);
+}
+EXPORT_SYMBOL_GPL(rcu_read_unlock_trace_special);
+
+/* Add a task to the holdout list, if it is not already on the list. */
+static void trc_add_holdout(struct task_struct *t, struct list_head *bhp)
+{
+	if (list_empty(&t->trc_holdout_list)) {
+		get_task_struct(t);
+		list_add(&t->trc_holdout_list, bhp);
+	}
+}
+
+/* Remove a task from the holdout list, if it is in fact present. */
+static void trc_del_holdout(struct task_struct *t)
+{
+	if (!list_empty(&t->trc_holdout_list)) {
+		list_del_init(&t->trc_holdout_list);
+		put_task_struct(t);
+	}
+}
+
+/* IPI handler to check task state. */
+static void trc_read_check_handler(void *t_in)
+{
+	struct task_struct *t = current;
+	struct task_struct *texp = t_in;
+
+	// If the task is no longer running on this CPU, leave.
+	if (unlikely(texp != t)) {
+		if (WARN_ON_ONCE(atomic_dec_and_test(&trc_n_readers_need_end)))
+			wake_up(&trc_wait);
+		goto reset_ipi; // Already on holdout list, so will check later.
+	}
+
+	// If the task is not in a read-side critical section, and
+	// if this is the last reader, awaken the grace-period kthread.
+	if (likely(!t->trc_reader_nesting)) {
+		if (WARN_ON_ONCE(atomic_dec_and_test(&trc_n_readers_need_end)))
+			wake_up(&trc_wait);
+		// Mark as checked after decrement to avoid false
+		// positives on the above WARN_ON_ONCE().
+		WRITE_ONCE(t->trc_reader_checked, true);
+		goto reset_ipi;
+	}
+	WRITE_ONCE(t->trc_reader_checked, true);
+
+	// Get here if the task is in a read-side critical section.  Set
+	// its state so that it will awaken the grace-period kthread upon
+	// exit from that critical section.
+	WARN_ON_ONCE(t->trc_reader_special.b.need_qs);
+	WRITE_ONCE(t->trc_reader_special.b.need_qs, true);
+
+reset_ipi:
+	// Allow future IPIs to be sent on CPU and for task.
+	// Also order this IPI handler against any later manipulations of
+	// the intended task.
+	smp_store_release(&per_cpu(trc_ipi_to_cpu, smp_processor_id()), false); // ^^^
+	smp_store_release(&texp->trc_ipi_to_cpu, -1); // ^^^
+}
+
+/* Callback function for scheduler to check locked-down task.  */
+static bool trc_inspect_reader(struct task_struct *t, void *arg)
+{
+	int cpu = task_cpu(t);
+	bool in_qs = false;
+	bool ofl = cpu_is_offline(cpu);
+
+	if (task_curr(t)) {
+		WARN_ON_ONCE(ofl & !is_idle_task(t));
+
+		// If no chance of heavyweight readers, do it the hard way.
+		if (!ofl && !IS_ENABLED(CONFIG_TASKS_TRACE_RCU_READ_MB))
+			return false;
+
+		// If heavyweight readers are enabled on the remote task,
+		// we can inspect its state despite its currently running.
+		// However, we cannot safely change its state.
+		n_heavy_reader_attempts++;
+		if (!ofl && // Check for "running" idle tasks on offline CPUs.
+		    !rcu_dynticks_zero_in_eqs(cpu, &t->trc_reader_nesting))
+			return false; // No quiescent state, do it the hard way.
+		n_heavy_reader_updates++;
+		if (ofl)
+			n_heavy_reader_ofl_updates++;
+		in_qs = true;
+	} else {
+		in_qs = likely(!t->trc_reader_nesting);
+	}
+
+	// Mark as checked.  Because this is called from the grace-period
+	// kthread, also remove the task from the holdout list.
+	t->trc_reader_checked = true;
+	trc_del_holdout(t);
+
+	if (in_qs)
+		return true;  // Already in quiescent state, done!!!
+
+	// The task is in a read-side critical section, so set up its
+	// state so that it will awaken the grace-period kthread upon exit
+	// from that critical section.
+	atomic_inc(&trc_n_readers_need_end); // One more to wait on.
+	WARN_ON_ONCE(t->trc_reader_special.b.need_qs);
+	WRITE_ONCE(t->trc_reader_special.b.need_qs, true);
+	return true;
+}
+
+/* Attempt to extract the state for the specified task. */
+static void trc_wait_for_one_reader(struct task_struct *t,
+				    struct list_head *bhp)
+{
+	int cpu;
+
+	// If a previous IPI is still in flight, let it complete.
+	if (smp_load_acquire(&t->trc_ipi_to_cpu) != -1) // Order IPI
+		return;
+
+	// The current task had better be in a quiescent state.
+	if (t == current) {
+		t->trc_reader_checked = true;
+		trc_del_holdout(t);
+		WARN_ON_ONCE(t->trc_reader_nesting);
+		return;
+	}
+
+	// Attempt to nail down the task for inspection.
+	if (try_invoke_on_locked_down_task(t, trc_inspect_reader, NULL))
+		return;
+
+	// If currently running, send an IPI, either way, add to list.
+	trc_add_holdout(t, bhp);
+	if (task_curr(t) && time_after(jiffies, rcu_tasks_trace.gp_start + rcu_task_ipi_delay)) {
+		// The task is currently running, so try IPIing it.
+		cpu = task_cpu(t);
+
+		// If there is already an IPI outstanding, let it happen.
+		if (per_cpu(trc_ipi_to_cpu, cpu) || t->trc_ipi_to_cpu >= 0)
+			return;
+
+		atomic_inc(&trc_n_readers_need_end);
+		per_cpu(trc_ipi_to_cpu, cpu) = true;
+		t->trc_ipi_to_cpu = cpu;
+		rcu_tasks_trace.n_ipis++;
+		if (smp_call_function_single(cpu,
+					     trc_read_check_handler, t, 0)) {
+			// Just in case there is some other reason for
+			// failure than the target CPU being offline.
+			rcu_tasks_trace.n_ipis_fails++;
+			per_cpu(trc_ipi_to_cpu, cpu) = false;
+			t->trc_ipi_to_cpu = cpu;
+			if (atomic_dec_and_test(&trc_n_readers_need_end)) {
+				WARN_ON_ONCE(1);
+				wake_up(&trc_wait);
+			}
+		}
+	}
+}
+
+/* Initialize for a new RCU-tasks-trace grace period. */
+static void rcu_tasks_trace_pregp_step(void)
+{
+	int cpu;
+
+	// Allow for fast-acting IPIs.
+	atomic_set(&trc_n_readers_need_end, 1);
+
+	// There shouldn't be any old IPIs, but...
+	for_each_possible_cpu(cpu)
+		WARN_ON_ONCE(per_cpu(trc_ipi_to_cpu, cpu));
+
+	// Disable CPU hotplug across the tasklist scan.
+	// This also waits for all readers in CPU-hotplug code paths.
+	cpus_read_lock();
+}
+
+/* Do first-round processing for the specified task. */
+static void rcu_tasks_trace_pertask(struct task_struct *t,
+				    struct list_head *hop)
+{
+	WRITE_ONCE(t->trc_reader_special.b.need_qs, false);
+	WRITE_ONCE(t->trc_reader_checked, false);
+	t->trc_ipi_to_cpu = -1;
+	trc_wait_for_one_reader(t, hop);
+}
+
+/*
+ * Do intermediate processing between task and holdout scans and
+ * pick up the idle tasks.
+ */
+static void rcu_tasks_trace_postscan(struct list_head *hop)
+{
+	int cpu;
+
+	for_each_possible_cpu(cpu)
+		rcu_tasks_trace_pertask(idle_task(cpu), hop);
+
+	// Re-enable CPU hotplug now that the tasklist scan has completed.
+	cpus_read_unlock();
+
+	// Wait for late-stage exiting tasks to finish exiting.
+	// These might have passed the call to exit_tasks_rcu_finish().
+	synchronize_rcu();
+	// Any tasks that exit after this point will set ->trc_reader_checked.
+}
+
+/* Show the state of a task stalling the current RCU tasks trace GP. */
+static void show_stalled_task_trace(struct task_struct *t, bool *firstreport)
+{
+	int cpu;
+
+	if (*firstreport) {
+		pr_err("INFO: rcu_tasks_trace detected stalls on tasks:\n");
+		*firstreport = false;
+	}
+	// FIXME: This should attempt to use try_invoke_on_nonrunning_task().
+	cpu = task_cpu(t);
+	pr_alert("P%d: %c%c%c nesting: %d%c cpu: %d\n",
+		 t->pid,
+		 ".I"[READ_ONCE(t->trc_ipi_to_cpu) > 0],
+		 ".i"[is_idle_task(t)],
+		 ".N"[cpu > 0 && tick_nohz_full_cpu(cpu)],
+		 t->trc_reader_nesting,
+		 " N"[!!t->trc_reader_special.b.need_qs],
+		 cpu);
+	sched_show_task(t);
+}
+
+/* List stalled IPIs for RCU tasks trace. */
+static void show_stalled_ipi_trace(void)
+{
+	int cpu;
+
+	for_each_possible_cpu(cpu)
+		if (per_cpu(trc_ipi_to_cpu, cpu))
+			pr_alert("\tIPI outstanding to CPU %d\n", cpu);
+}
+
+/* Do one scan of the holdout list. */
+static void check_all_holdout_tasks_trace(struct list_head *hop,
+					  bool needreport, bool *firstreport)
+{
+	struct task_struct *g, *t;
+
+	// Disable CPU hotplug across the holdout list scan.
+	cpus_read_lock();
+
+	list_for_each_entry_safe(t, g, hop, trc_holdout_list) {
+		// If safe and needed, try to check the current task.
+		if (READ_ONCE(t->trc_ipi_to_cpu) == -1 &&
+		    !READ_ONCE(t->trc_reader_checked))
+			trc_wait_for_one_reader(t, hop);
+
+		// If check succeeded, remove this task from the list.
+		if (READ_ONCE(t->trc_reader_checked))
+			trc_del_holdout(t);
+		else if (needreport)
+			show_stalled_task_trace(t, firstreport);
+	}
+
+	// Re-enable CPU hotplug now that the holdout list scan has completed.
+	cpus_read_unlock();
+
+	if (needreport) {
+		if (firstreport)
+			pr_err("INFO: rcu_tasks_trace detected stalls? (Late IPI?)\n");
+		show_stalled_ipi_trace();
+	}
+}
+
+/* Wait for grace period to complete and provide ordering. */
+static void rcu_tasks_trace_postgp(struct rcu_tasks *rtp)
+{
+	bool firstreport;
+	struct task_struct *g, *t;
+	LIST_HEAD(holdouts);
+	long ret;
+
+	// Remove the safety count.
+	smp_mb__before_atomic();  // Order vs. earlier atomics
+	atomic_dec(&trc_n_readers_need_end);
+	smp_mb__after_atomic();  // Order vs. later atomics
+
+	// Wait for readers.
+	set_tasks_gp_state(rtp, RTGS_WAIT_READERS);
+	for (;;) {
+		ret = wait_event_idle_exclusive_timeout(
+				trc_wait,
+				atomic_read(&trc_n_readers_need_end) == 0,
+				READ_ONCE(rcu_task_stall_timeout));
+		if (ret)
+			break;  // Count reached zero.
+		// Stall warning time, so make a list of the offenders.
+		for_each_process_thread(g, t)
+			if (READ_ONCE(t->trc_reader_special.b.need_qs))
+				trc_add_holdout(t, &holdouts);
+		firstreport = true;
+		list_for_each_entry_safe(t, g, &holdouts, trc_holdout_list)
+			if (READ_ONCE(t->trc_reader_special.b.need_qs)) {
+				show_stalled_task_trace(t, &firstreport);
+				trc_del_holdout(t);
+			}
+		if (firstreport)
+			pr_err("INFO: rcu_tasks_trace detected stalls? (Counter/taskslist mismatch?)\n");
+		show_stalled_ipi_trace();
+		pr_err("\t%d holdouts\n", atomic_read(&trc_n_readers_need_end));
+	}
+	smp_mb(); // Caller's code must be ordered after wakeup.
+		  // Pairs with pretty much every ordering primitive.
+}
+
+/* Report any needed quiescent state for this exiting task. */
+static void exit_tasks_rcu_finish_trace(struct task_struct *t)
+{
+	WRITE_ONCE(t->trc_reader_checked, true);
+	WARN_ON_ONCE(t->trc_reader_nesting);
+	WRITE_ONCE(t->trc_reader_nesting, 0);
+	if (WARN_ON_ONCE(READ_ONCE(t->trc_reader_special.b.need_qs)))
+		rcu_read_unlock_trace_special(t, 0);
+}
+
+/**
+ * call_rcu_tasks_trace() - Queue a callback trace task-based grace period
+ * @rhp: structure to be used for queueing the RCU updates.
+ * @func: actual callback function to be invoked after the grace period
+ *
+ * The callback function will be invoked some time after a full grace
+ * period elapses, in other words after all currently executing RCU
+ * read-side critical sections have completed. call_rcu_tasks_trace()
+ * assumes that the read-side critical sections end at context switch,
+ * cond_resched_rcu_qs(), or transition to usermode execution.  As such,
+ * there are no read-side primitives analogous to rcu_read_lock() and
+ * rcu_read_unlock() because this primitive is intended to determine
+ * that all tasks have passed through a safe state, not so much for
+ * data-strcuture synchronization.
+ *
+ * See the description of call_rcu() for more detailed information on
+ * memory ordering guarantees.
+ */
+void call_rcu_tasks_trace(struct rcu_head *rhp, rcu_callback_t func)
+{
+	call_rcu_tasks_generic(rhp, func, &rcu_tasks_trace);
+}
+EXPORT_SYMBOL_GPL(call_rcu_tasks_trace);
+
+/**
+ * synchronize_rcu_tasks_trace - wait for a trace rcu-tasks grace period
+ *
+ * Control will return to the caller some time after a trace rcu-tasks
+ * grace period has elapsed, in other words after all currently
+ * executing rcu-tasks read-side critical sections have elapsed.  These
+ * read-side critical sections are delimited by calls to schedule(),
+ * cond_resched_tasks_rcu_qs(), userspace execution, and (in theory,
+ * anyway) cond_resched().
+ *
+ * This is a very specialized primitive, intended only for a few uses in
+ * tracing and other situations requiring manipulation of function preambles
+ * and profiling hooks.  The synchronize_rcu_tasks_trace() function is not
+ * (yet) intended for heavy use from multiple CPUs.
+ *
+ * See the description of synchronize_rcu() for more detailed information
+ * on memory ordering guarantees.
+ */
+void synchronize_rcu_tasks_trace(void)
+{
+	RCU_LOCKDEP_WARN(lock_is_held(&rcu_trace_lock_map), "Illegal synchronize_rcu_tasks_trace() in RCU Tasks Trace read-side critical section");
+	synchronize_rcu_tasks_generic(&rcu_tasks_trace);
+}
+EXPORT_SYMBOL_GPL(synchronize_rcu_tasks_trace);
+
+/**
+ * rcu_barrier_tasks_trace - Wait for in-flight call_rcu_tasks_trace() callbacks.
+ *
+ * Although the current implementation is guaranteed to wait, it is not
+ * obligated to, for example, if there are no pending callbacks.
+ */
+void rcu_barrier_tasks_trace(void)
+{
+	/* There is only one callback queue, so this is easy.  ;-) */
+	synchronize_rcu_tasks_trace();
+}
+EXPORT_SYMBOL_GPL(rcu_barrier_tasks_trace);
+
+static int __init rcu_spawn_tasks_trace_kthread(void)
+{
+	rcu_tasks_trace.pregp_func = rcu_tasks_trace_pregp_step;
+	rcu_tasks_trace.pertask_func = rcu_tasks_trace_pertask;
+	rcu_tasks_trace.postscan_func = rcu_tasks_trace_postscan;
+	rcu_tasks_trace.holdouts_func = check_all_holdout_tasks_trace;
+	rcu_tasks_trace.postgp_func = rcu_tasks_trace_postgp;
+	rcu_spawn_tasks_kthread_generic(&rcu_tasks_trace);
+	return 0;
+}
+core_initcall(rcu_spawn_tasks_trace_kthread);
+
+static void show_rcu_tasks_trace_gp_kthread(void)
+{
+	char buf[64];
+
+	sprintf(buf, "N%d h:%lu/%lu/%lu", atomic_read(&trc_n_readers_need_end),
+		data_race(n_heavy_reader_ofl_updates),
+		data_race(n_heavy_reader_updates),
+		data_race(n_heavy_reader_attempts));
+	show_rcu_tasks_generic_gp_kthread(&rcu_tasks_trace, buf);
+}
+
+#else /* #ifdef CONFIG_TASKS_TRACE_RCU */
+static void exit_tasks_rcu_finish_trace(struct task_struct *t) { }
+static inline void show_rcu_tasks_trace_gp_kthread(void) {}
+#endif /* #else #ifdef CONFIG_TASKS_TRACE_RCU */
+
+void show_rcu_tasks_gp_kthreads(void)
+{
+	show_rcu_tasks_classic_gp_kthread();
+	show_rcu_tasks_rude_gp_kthread();
+	show_rcu_tasks_trace_gp_kthread();
+}
+
+#else /* #ifdef CONFIG_TASKS_RCU_GENERIC */
+static inline void rcu_tasks_bootup_oddness(void) {}
+void show_rcu_tasks_gp_kthreads(void) {}
+#endif /* #else #ifdef CONFIG_TASKS_RCU_GENERIC */
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index 06548e2ebb72..f288477ee1c2 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -67,6 +67,19 @@
 #endif
 #define MODULE_PARAM_PREFIX "rcutree."
 
+#ifndef data_race
+#define data_race(expr)							\
+	({								\
+		expr;							\
+	})
+#endif
+#ifndef ASSERT_EXCLUSIVE_WRITER
+#define ASSERT_EXCLUSIVE_WRITER(var) do { } while (0)
+#endif
+#ifndef ASSERT_EXCLUSIVE_ACCESS
+#define ASSERT_EXCLUSIVE_ACCESS(var) do { } while (0)
+#endif
+
 /* Data structures. */
 
 /*
@@ -100,7 +113,7 @@ static struct rcu_state rcu_state = {
 static bool dump_tree;
 module_param(dump_tree, bool, 0444);
 /* By default, use RCU_SOFTIRQ instead of rcuc kthreads. */
-static bool use_softirq = 1;
+static bool use_softirq = true;
 module_param(use_softirq, bool, 0444);
 /* Control rcu_node-tree auto-balancing at boot time. */
 static bool rcu_fanout_exact;
@@ -225,7 +238,9 @@ void rcu_softirq_qs(void)
 
 /*
  * Record entry into an extended quiescent state.  This is only to be
- * called when not already in an extended quiescent state.
+ * called when not already in an extended quiescent state, that is,
+ * RCU is watching prior to the call to this function and is no longer
+ * watching upon return.
  */
 static void rcu_dynticks_eqs_enter(void)
 {
@@ -237,8 +252,9 @@ static void rcu_dynticks_eqs_enter(void)
 	 * critical sections, and we also must force ordering with the
 	 * next idle sojourn.
 	 */
+	rcu_dynticks_task_trace_enter();  // Before ->dynticks update!
 	seq = atomic_add_return(RCU_DYNTICK_CTRL_CTR, &rdp->dynticks);
-	/* Better be in an extended quiescent state! */
+	// RCU is no longer watching.  Better be in extended quiescent state!
 	WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) &&
 		     (seq & RCU_DYNTICK_CTRL_CTR));
 	/* Better not have special action (TLB flush) pending! */
@@ -248,7 +264,8 @@ static void rcu_dynticks_eqs_enter(void)
 
 /*
  * Record exit from an extended quiescent state.  This is only to be
- * called from an extended quiescent state.
+ * called from an extended quiescent state, that is, RCU is not watching
+ * prior to the call to this function and is watching upon return.
  */
 static void rcu_dynticks_eqs_exit(void)
 {
@@ -261,6 +278,8 @@ static void rcu_dynticks_eqs_exit(void)
 	 * critical section.
 	 */
 	seq = atomic_add_return(RCU_DYNTICK_CTRL_CTR, &rdp->dynticks);
+	// RCU is now watching.  Better not be in an extended quiescent state!
+	rcu_dynticks_task_trace_exit();  // After ->dynticks update!
 	WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) &&
 		     !(seq & RCU_DYNTICK_CTRL_CTR));
 	if (seq & RCU_DYNTICK_CTRL_MASK) {
@@ -332,6 +351,28 @@ static bool rcu_dynticks_in_eqs_since(struct rcu_data *rdp, int snap)
 	return snap != rcu_dynticks_snap(rdp);
 }
 
+/*
+ * Return true if the referenced integer is zero while the specified
+ * CPU remains within a single extended quiescent state.
+ */
+bool rcu_dynticks_zero_in_eqs(int cpu, int *vp)
+{
+	struct rcu_data *rdp = per_cpu_ptr(&rcu_data, cpu);
+	int snap;
+
+	// If not quiescent, force back to earlier extended quiescent state.
+	snap = atomic_read(&rdp->dynticks) & ~(RCU_DYNTICK_CTRL_MASK |
+					       RCU_DYNTICK_CTRL_CTR);
+
+	smp_rmb(); // Order ->dynticks and *vp reads.
+	if (READ_ONCE(*vp))
+		return false;  // Non-zero, so report failure;
+	smp_rmb(); // Order *vp read and ->dynticks re-read.
+
+	// If still in the same extended quiescent state, we are good!
+	return snap == (atomic_read(&rdp->dynticks) & ~RCU_DYNTICK_CTRL_MASK);
+}
+
 /*
  * Set the special (bottom) bit of the specified CPU so that it
  * will take special action (such as flushing its TLB) on the
@@ -571,6 +612,7 @@ static void rcu_eqs_enter(bool user)
 	WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) &&
 		     rdp->dynticks_nesting == 0);
 	if (rdp->dynticks_nesting != 1) {
+		// RCU will still be watching, so just do accounting and leave.
 		rdp->dynticks_nesting--;
 		return;
 	}
@@ -583,7 +625,9 @@ static void rcu_eqs_enter(bool user)
 	rcu_prepare_for_idle();
 	rcu_preempt_deferred_qs(current);
 	WRITE_ONCE(rdp->dynticks_nesting, 0); /* Avoid irq-access tearing. */
+	// RCU is watching here ...
 	rcu_dynticks_eqs_enter();
+	// ... but is no longer watching here.
 	rcu_dynticks_task_enter();
 }
 
@@ -663,7 +707,9 @@ static __always_inline void rcu_nmi_exit_common(bool irq)
 	if (irq)
 		rcu_prepare_for_idle();
 
+	// RCU is watching here ...
 	rcu_dynticks_eqs_enter();
+	// ... but is no longer watching here.
 
 	if (irq)
 		rcu_dynticks_task_enter();
@@ -738,11 +784,14 @@ static void rcu_eqs_exit(bool user)
 	oldval = rdp->dynticks_nesting;
 	WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && oldval < 0);
 	if (oldval) {
+		// RCU was already watching, so just do accounting and leave.
 		rdp->dynticks_nesting++;
 		return;
 	}
 	rcu_dynticks_task_exit();
+	// RCU is not watching here ...
 	rcu_dynticks_eqs_exit();
+	// ... but is watching here.
 	rcu_cleanup_after_idle();
 	trace_rcu_dyntick(TPS("End"), rdp->dynticks_nesting, 1, atomic_read(&rdp->dynticks));
 	WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && !user && !is_idle_task(current));
@@ -819,19 +868,28 @@ static __always_inline void rcu_nmi_enter_common(bool irq)
 		if (irq)
 			rcu_dynticks_task_exit();
 
+		// RCU is not watching here ...
 		rcu_dynticks_eqs_exit();
+		// ... but is watching here.
 
 		if (irq)
 			rcu_cleanup_after_idle();
 
 		incby = 1;
-	} else if (tick_nohz_full_cpu(rdp->cpu) &&
+	} else if (irq && tick_nohz_full_cpu(rdp->cpu) &&
 		   rdp->dynticks_nmi_nesting == DYNTICK_IRQ_NONIDLE &&
 		   READ_ONCE(rdp->rcu_urgent_qs) &&
 		   !READ_ONCE(rdp->rcu_forced_tick)) {
+		// We get here only if we had already exited the extended
+		// quiescent state and this was an interrupt (not an NMI).
+		// Therefore, (1) RCU is already watching and (2) The fact
+		// that we are in an interrupt handler and that the rcu_node
+		// lock is an irq-disabled lock prevents self-deadlock.
+		// So we can safely recheck under the lock.
 		raw_spin_lock_rcu_node(rdp->mynode);
-		// Recheck under lock.
 		if (rdp->rcu_urgent_qs && !rdp->rcu_forced_tick) {
+			// A nohz_full CPU is in the kernel and RCU
+			// needs a quiescent state.  Turn on the tick!
 			WRITE_ONCE(rdp->rcu_forced_tick, true);
 			tick_dep_set_cpu(rdp->cpu, TICK_DEP_BIT_RCU);
 		}
@@ -1217,7 +1275,7 @@ static bool rcu_start_this_gp(struct rcu_node *rnp_start, struct rcu_data *rdp,
 		trace_rcu_this_gp(rnp, rdp, gp_seq_req, TPS("NoGPkthread"));
 		goto unlock_out;
 	}
-	trace_rcu_grace_period(rcu_state.name, rcu_state.gp_seq, TPS("newreq"));
+	trace_rcu_grace_period(rcu_state.name, data_race(rcu_state.gp_seq), TPS("newreq"));
 	ret = true;  /* Caller must wake GP kthread. */
 unlock_out:
 	/* Push furthest requested GP to leaf node and rcu_data structure. */
@@ -1473,6 +1531,31 @@ static void rcu_gp_slow(int delay)
 		schedule_timeout_uninterruptible(delay);
 }
 
+static unsigned long sleep_duration;
+
+/* Allow rcutorture to stall the grace-period kthread. */
+void rcu_gp_set_torture_wait(int duration)
+{
+	if (IS_ENABLED(CONFIG_RCU_TORTURE_TEST) && duration > 0)
+		WRITE_ONCE(sleep_duration, duration);
+}
+EXPORT_SYMBOL_GPL(rcu_gp_set_torture_wait);
+
+/* Actually implement the aforementioned wait. */
+static void rcu_gp_torture_wait(void)
+{
+	unsigned long duration;
+
+	if (!IS_ENABLED(CONFIG_RCU_TORTURE_TEST))
+		return;
+	duration = xchg(&sleep_duration, 0UL);
+	if (duration > 0) {
+		pr_alert("%s: Waiting %lu jiffies\n", __func__, duration);
+		schedule_timeout_uninterruptible(duration);
+		pr_alert("%s: Wait complete\n", __func__);
+	}
+}
+
 /*
  * Initialize a new grace period.  Return false if no grace period required.
  */
@@ -1506,6 +1589,7 @@ static bool rcu_gp_init(void)
 	record_gp_stall_check_time();
 	/* Record GP times before starting GP, hence rcu_seq_start(). */
 	rcu_seq_start(&rcu_state.gp_seq);
+	ASSERT_EXCLUSIVE_WRITER(rcu_state.gp_seq);
 	trace_rcu_grace_period(rcu_state.name, rcu_state.gp_seq, TPS("start"));
 	raw_spin_unlock_irq_rcu_node(rnp);
 
@@ -1611,12 +1695,16 @@ static bool rcu_gp_fqs_check_wake(int *gfp)
 {
 	struct rcu_node *rnp = rcu_get_root();
 
-	/* Someone like call_rcu() requested a force-quiescent-state scan. */
+	// If under overload conditions, force an immediate FQS scan.
+	if (*gfp & RCU_GP_FLAG_OVLD)
+		return true;
+
+	// Someone like call_rcu() requested a force-quiescent-state scan.
 	*gfp = READ_ONCE(rcu_state.gp_flags);
 	if (*gfp & RCU_GP_FLAG_FQS)
 		return true;
 
-	/* The current grace period has completed. */
+	// The current grace period has completed.
 	if (!READ_ONCE(rnp->qsmask) && !rcu_preempt_blocked_readers_cgp(rnp))
 		return true;
 
@@ -1654,13 +1742,15 @@ static void rcu_gp_fqs(bool first_time)
 static void rcu_gp_fqs_loop(void)
 {
 	bool first_gp_fqs;
-	int gf;
+	int gf = 0;
 	unsigned long j;
 	int ret;
 	struct rcu_node *rnp = rcu_get_root();
 
 	first_gp_fqs = true;
 	j = READ_ONCE(jiffies_till_first_fqs);
+	if (rcu_state.cbovld)
+		gf = RCU_GP_FLAG_OVLD;
 	ret = 0;
 	for (;;) {
 		if (!ret) {
@@ -1673,6 +1763,7 @@ static void rcu_gp_fqs_loop(void)
 		rcu_state.gp_state = RCU_GP_WAIT_FQS;
 		ret = swait_event_idle_timeout_exclusive(
 				rcu_state.gp_wq, rcu_gp_fqs_check_wake(&gf), j);
+		rcu_gp_torture_wait();
 		rcu_state.gp_state = RCU_GP_DOING_FQS;
 		/* Locking provides needed memory barriers. */
 		/* If grace period done, leave loop. */
@@ -1680,12 +1771,16 @@ static void rcu_gp_fqs_loop(void)
 		    !rcu_preempt_blocked_readers_cgp(rnp))
 			break;
 		/* If time for quiescent-state forcing, do it. */
-		if (ULONG_CMP_GE(jiffies, rcu_state.jiffies_force_qs) ||
+		if (!time_after(rcu_state.jiffies_force_qs, jiffies) ||
 		    (gf & RCU_GP_FLAG_FQS)) {
 			trace_rcu_grace_period(rcu_state.name, rcu_state.gp_seq,
 					       TPS("fqsstart"));
 			rcu_gp_fqs(first_gp_fqs);
-			first_gp_fqs = false;
+			gf = 0;
+			if (first_gp_fqs) {
+				first_gp_fqs = false;
+				gf = rcu_state.cbovld ? RCU_GP_FLAG_OVLD : 0;
+			}
 			trace_rcu_grace_period(rcu_state.name, rcu_state.gp_seq,
 					       TPS("fqsend"));
 			cond_resched_tasks_rcu_qs();
@@ -1705,6 +1800,7 @@ static void rcu_gp_fqs_loop(void)
 				j = 1;
 			else
 				j = rcu_state.jiffies_force_qs - j;
+			gf = 0;
 		}
 	}
 }
@@ -1781,6 +1877,7 @@ static void rcu_gp_cleanup(void)
 	/* Declare grace period done, trace first to use old GP number. */
 	trace_rcu_grace_period(rcu_state.name, rcu_state.gp_seq, TPS("end"));
 	rcu_seq_end(&rcu_state.gp_seq);
+	ASSERT_EXCLUSIVE_WRITER(rcu_state.gp_seq);
 	rcu_state.gp_state = RCU_GP_IDLE;
 	/* Check for GP requests since above loop. */
 	rdp = this_cpu_ptr(&rcu_data);
@@ -1821,6 +1918,7 @@ static int __noreturn rcu_gp_kthread(void *unused)
 			swait_event_idle_exclusive(rcu_state.gp_wq,
 					 READ_ONCE(rcu_state.gp_flags) &
 					 RCU_GP_FLAG_INIT);
+			rcu_gp_torture_wait();
 			rcu_state.gp_state = RCU_GP_DONE_GPS;
 			/* Locking provides needed memory barrier. */
 			if (rcu_gp_init())
@@ -2811,6 +2909,8 @@ struct kfree_rcu_cpu {
 	struct delayed_work monitor_work;
 	bool monitor_todo;
 	bool initialized;
+	// Number of objects for which GP not started
+	int count;
 };
 
 static DEFINE_PER_CPU(struct kfree_rcu_cpu, krc);
@@ -2924,6 +3024,8 @@ static inline bool queue_kfree_rcu_work(struct kfree_rcu_cpu *krcp)
 				krcp->head = NULL;
 			}
 
+			WRITE_ONCE(krcp->count, 0);
+
 			/*
 			 * One work is per one batch, so there are two "free channels",
 			 * "bhead_free" and "head_free" the batch can handle. It can be
@@ -3060,6 +3162,8 @@ void kfree_call_rcu(struct rcu_head *head, rcu_callback_t func)
 		krcp->head = head;
 	}
 
+	WRITE_ONCE(krcp->count, krcp->count + 1);
+
 	// Set timer to drain after KFREE_DRAIN_JIFFIES.
 	if (rcu_scheduler_active == RCU_SCHEDULER_RUNNING &&
 	    !krcp->monitor_todo) {
@@ -3074,6 +3178,56 @@ void kfree_call_rcu(struct rcu_head *head, rcu_callback_t func)
 }
 EXPORT_SYMBOL_GPL(kfree_call_rcu);
 
+static unsigned long
+kfree_rcu_shrink_count(struct shrinker *shrink, struct shrink_control *sc)
+{
+	int cpu;
+	unsigned long count = 0;
+
+	/* Snapshot count of all CPUs */
+	for_each_online_cpu(cpu) {
+		struct kfree_rcu_cpu *krcp = per_cpu_ptr(&krc, cpu);
+
+		count += READ_ONCE(krcp->count);
+	}
+
+	return count;
+}
+
+static unsigned long
+kfree_rcu_shrink_scan(struct shrinker *shrink, struct shrink_control *sc)
+{
+	int cpu, freed = 0;
+	unsigned long flags;
+
+	for_each_online_cpu(cpu) {
+		int count;
+		struct kfree_rcu_cpu *krcp = per_cpu_ptr(&krc, cpu);
+
+		count = krcp->count;
+		spin_lock_irqsave(&krcp->lock, flags);
+		if (krcp->monitor_todo)
+			kfree_rcu_drain_unlock(krcp, flags);
+		else
+			spin_unlock_irqrestore(&krcp->lock, flags);
+
+		sc->nr_to_scan -= count;
+		freed += count;
+
+		if (sc->nr_to_scan <= 0)
+			break;
+	}
+
+	return freed;
+}
+
+static struct shrinker kfree_rcu_shrinker = {
+	.count_objects = kfree_rcu_shrink_count,
+	.scan_objects = kfree_rcu_shrink_scan,
+	.batch = 0,
+	.seeks = DEFAULT_SEEKS,
+};
+
 void __init kfree_rcu_scheduler_running(void)
 {
 	int cpu;
@@ -3599,6 +3753,7 @@ void rcu_cpu_starting(unsigned int cpu)
 	nbits = bitmap_weight(&oldmask, BITS_PER_LONG);
 	/* Allow lockless access for expedited grace periods. */
 	smp_store_release(&rcu_state.ncpus, rcu_state.ncpus + nbits); /* ^^^ */
+	ASSERT_EXCLUSIVE_WRITER(rcu_state.ncpus);
 	rcu_gpnum_ovf(rnp, rdp); /* Offline-induced counter wrap? */
 	rdp->rcu_onl_gp_seq = READ_ONCE(rcu_state.gp_seq);
 	rdp->rcu_onl_gp_flags = READ_ONCE(rcu_state.gp_flags);
@@ -3994,6 +4149,8 @@ static void __init kfree_rcu_batch_init(void)
 		INIT_DELAYED_WORK(&krcp->monitor_work, kfree_rcu_monitor);
 		krcp->initialized = true;
 	}
+	if (register_shrinker(&kfree_rcu_shrinker))
+		pr_err("Failed to register kfree_rcu() shrinker!\n");
 }
 
 void __init rcu_init(void)
diff --git a/kernel/rcu/tree.h b/kernel/rcu/tree.h
index 9dc2ec021da5..43991a40b084 100644
--- a/kernel/rcu/tree.h
+++ b/kernel/rcu/tree.h
@@ -359,6 +359,7 @@ struct rcu_state {
 /* Values for rcu_state structure's gp_flags field. */
 #define RCU_GP_FLAG_INIT 0x1	/* Need grace-period initialization. */
 #define RCU_GP_FLAG_FQS  0x2	/* Need grace-period quiescent-state forcing. */
+#define RCU_GP_FLAG_OVLD 0x4	/* Experiencing callback overload. */
 
 /* Values for rcu_state structure's gp_state field. */
 #define RCU_GP_IDLE	 0	/* Initial state and no GP in progress. */
@@ -454,6 +455,8 @@ static void rcu_bind_gp_kthread(void);
 static bool rcu_nohz_full_cpu(void);
 static void rcu_dynticks_task_enter(void);
 static void rcu_dynticks_task_exit(void);
+static void rcu_dynticks_task_trace_enter(void);
+static void rcu_dynticks_task_trace_exit(void);
 
 /* Forward declarations for tree_stall.h */
 static void record_gp_stall_check_time(void);
diff --git a/kernel/rcu/tree_exp.h b/kernel/rcu/tree_exp.h
index 1a617b9dffb0..72952edad1e4 100644
--- a/kernel/rcu/tree_exp.h
+++ b/kernel/rcu/tree_exp.h
@@ -150,7 +150,7 @@ static void __maybe_unused sync_exp_reset_tree(void)
 static bool sync_rcu_exp_done(struct rcu_node *rnp)
 {
 	raw_lockdep_assert_held_rcu_node(rnp);
-	return rnp->exp_tasks == NULL &&
+	return READ_ONCE(rnp->exp_tasks) == NULL &&
 	       READ_ONCE(rnp->expmask) == 0;
 }
 
@@ -373,7 +373,7 @@ static void sync_rcu_exp_select_node_cpus(struct work_struct *wp)
 	 * until such time as the ->expmask bits are cleared.
 	 */
 	if (rcu_preempt_has_tasks(rnp))
-		rnp->exp_tasks = rnp->blkd_tasks.next;
+		WRITE_ONCE(rnp->exp_tasks, rnp->blkd_tasks.next);
 	raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
 
 	/* IPI the remaining CPUs for expedited quiescent state. */
@@ -542,8 +542,8 @@ static void synchronize_rcu_expedited_wait(void)
 		}
 		pr_cont(" } %lu jiffies s: %lu root: %#lx/%c\n",
 			jiffies - jiffies_start, rcu_state.expedited_sequence,
-			READ_ONCE(rnp_root->expmask),
-			".T"[!!rnp_root->exp_tasks]);
+			data_race(rnp_root->expmask),
+			".T"[!!data_race(rnp_root->exp_tasks)]);
 		if (ndetected) {
 			pr_err("blocking rcu_node structures:");
 			rcu_for_each_node_breadth_first(rnp) {
@@ -553,8 +553,8 @@ static void synchronize_rcu_expedited_wait(void)
 					continue;
 				pr_cont(" l=%u:%d-%d:%#lx/%c",
 					rnp->level, rnp->grplo, rnp->grphi,
-					READ_ONCE(rnp->expmask),
-					".T"[!!rnp->exp_tasks]);
+					data_race(rnp->expmask),
+					".T"[!!data_race(rnp->exp_tasks)]);
 			}
 			pr_cont("\n");
 		}
@@ -639,6 +639,7 @@ static void wait_rcu_exp_gp(struct work_struct *wp)
  */
 static void rcu_exp_handler(void *unused)
 {
+	int depth = rcu_preempt_depth();
 	unsigned long flags;
 	struct rcu_data *rdp = this_cpu_ptr(&rcu_data);
 	struct rcu_node *rnp = rdp->mynode;
@@ -649,7 +650,7 @@ static void rcu_exp_handler(void *unused)
 	 * critical section.  If also enabled or idle, immediately
 	 * report the quiescent state, otherwise defer.
 	 */
-	if (!rcu_preempt_depth()) {
+	if (!depth) {
 		if (!(preempt_count() & (PREEMPT_MASK | SOFTIRQ_MASK)) ||
 		    rcu_dynticks_curr_cpu_in_eqs()) {
 			rcu_report_exp_rdp(rdp);
@@ -673,7 +674,7 @@ static void rcu_exp_handler(void *unused)
 	 * can have caused this quiescent state to already have been
 	 * reported, so we really do need to check ->expmask.
 	 */
-	if (rcu_preempt_depth() > 0) {
+	if (depth > 0) {
 		raw_spin_lock_irqsave_rcu_node(rnp, flags);
 		if (rnp->expmask & rdp->grpmask) {
 			rdp->exp_deferred_qs = true;
@@ -683,30 +684,8 @@ static void rcu_exp_handler(void *unused)
 		return;
 	}
 
-	/*
-	 * The final and least likely case is where the interrupted
-	 * code was just about to or just finished exiting the RCU-preempt
-	 * read-side critical section, and no, we can't tell which.
-	 * So either way, set ->deferred_qs to flag later code that
-	 * a quiescent state is required.
-	 *
-	 * If the CPU is fully enabled (or if some buggy RCU-preempt
-	 * read-side critical section is being used from idle), just
-	 * invoke rcu_preempt_deferred_qs() to immediately report the
-	 * quiescent state.  We cannot use rcu_read_unlock_special()
-	 * because we are in an interrupt handler, which will cause that
-	 * function to take an early exit without doing anything.
-	 *
-	 * Otherwise, force a context switch after the CPU enables everything.
-	 */
-	rdp->exp_deferred_qs = true;
-	if (!(preempt_count() & (PREEMPT_MASK | SOFTIRQ_MASK)) ||
-	    WARN_ON_ONCE(rcu_dynticks_curr_cpu_in_eqs())) {
-		rcu_preempt_deferred_qs(t);
-	} else {
-		set_tsk_need_resched(t);
-		set_preempt_need_resched();
-	}
+	// Finally, negative nesting depth should not happen.
+	WARN_ON_ONCE(1);
 }
 
 /* PREEMPTION=y, so no PREEMPTION=n expedited grace period to clean up after. */
@@ -721,17 +700,20 @@ static void sync_sched_exp_online_cleanup(int cpu)
  */
 static int rcu_print_task_exp_stall(struct rcu_node *rnp)
 {
-	struct task_struct *t;
+	unsigned long flags;
 	int ndetected = 0;
+	struct task_struct *t;
 
-	if (!rnp->exp_tasks)
+	if (!READ_ONCE(rnp->exp_tasks))
 		return 0;
+	raw_spin_lock_irqsave_rcu_node(rnp, flags);
 	t = list_entry(rnp->exp_tasks->prev,
 		       struct task_struct, rcu_node_entry);
 	list_for_each_entry_continue(t, &rnp->blkd_tasks, rcu_node_entry) {
 		pr_cont(" P%d", t->pid);
 		ndetected++;
 	}
+	raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
 	return ndetected;
 }
 
diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h
index 097635c41135..50caa3fcbad2 100644
--- a/kernel/rcu/tree_plugin.h
+++ b/kernel/rcu/tree_plugin.h
@@ -226,7 +226,7 @@ static void rcu_preempt_ctxt_queue(struct rcu_node *rnp, struct rcu_data *rdp)
 		WARN_ON_ONCE(rnp->completedqs == rnp->gp_seq);
 	}
 	if (!rnp->exp_tasks && (blkd_state & RCU_EXP_BLKD))
-		rnp->exp_tasks = &t->rcu_node_entry;
+		WRITE_ONCE(rnp->exp_tasks, &t->rcu_node_entry);
 	WARN_ON_ONCE(!(blkd_state & RCU_GP_BLKD) !=
 		     !(rnp->qsmask & rdp->grpmask));
 	WARN_ON_ONCE(!(blkd_state & RCU_EXP_BLKD) !=
@@ -331,6 +331,7 @@ void rcu_note_context_switch(bool preempt)
 	rcu_qs();
 	if (rdp->exp_deferred_qs)
 		rcu_report_exp_rdp(rdp);
+	rcu_tasks_qs(current, preempt);
 	trace_rcu_utilization(TPS("End context switch"));
 }
 EXPORT_SYMBOL_GPL(rcu_note_context_switch);
@@ -345,9 +346,7 @@ static int rcu_preempt_blocked_readers_cgp(struct rcu_node *rnp)
 	return READ_ONCE(rnp->gp_tasks) != NULL;
 }
 
-/* Bias and limit values for ->rcu_read_lock_nesting. */
-#define RCU_NEST_BIAS INT_MAX
-#define RCU_NEST_NMAX (-INT_MAX / 2)
+/* limit value for ->rcu_read_lock_nesting. */
 #define RCU_NEST_PMAX (INT_MAX / 2)
 
 static void rcu_preempt_read_enter(void)
@@ -355,9 +354,9 @@ static void rcu_preempt_read_enter(void)
 	current->rcu_read_lock_nesting++;
 }
 
-static void rcu_preempt_read_exit(void)
+static int rcu_preempt_read_exit(void)
 {
-	current->rcu_read_lock_nesting--;
+	return --current->rcu_read_lock_nesting;
 }
 
 static void rcu_preempt_depth_set(int val)
@@ -390,21 +389,15 @@ void __rcu_read_unlock(void)
 {
 	struct task_struct *t = current;
 
-	if (rcu_preempt_depth() != 1) {
-		rcu_preempt_read_exit();
-	} else {
+	if (rcu_preempt_read_exit() == 0) {
 		barrier();  /* critical section before exit code. */
-		rcu_preempt_depth_set(-RCU_NEST_BIAS);
-		barrier();  /* assign before ->rcu_read_unlock_special load */
 		if (unlikely(READ_ONCE(t->rcu_read_unlock_special.s)))
 			rcu_read_unlock_special(t);
-		barrier();  /* ->rcu_read_unlock_special load before assign */
-		rcu_preempt_depth_set(0);
 	}
 	if (IS_ENABLED(CONFIG_PROVE_LOCKING)) {
 		int rrln = rcu_preempt_depth();
 
-		WARN_ON_ONCE(rrln < 0 && rrln > RCU_NEST_NMAX);
+		WARN_ON_ONCE(rrln < 0 || rrln > RCU_NEST_PMAX);
 	}
 }
 EXPORT_SYMBOL_GPL(__rcu_read_unlock);
@@ -500,12 +493,12 @@ rcu_preempt_deferred_qs_irqrestore(struct task_struct *t, unsigned long flags)
 		if (&t->rcu_node_entry == rnp->gp_tasks)
 			WRITE_ONCE(rnp->gp_tasks, np);
 		if (&t->rcu_node_entry == rnp->exp_tasks)
-			rnp->exp_tasks = np;
+			WRITE_ONCE(rnp->exp_tasks, np);
 		if (IS_ENABLED(CONFIG_RCU_BOOST)) {
 			/* Snapshot ->boost_mtx ownership w/rnp->lock held. */
 			drop_boost_mutex = rt_mutex_owner(&rnp->boost_mtx) == t;
 			if (&t->rcu_node_entry == rnp->boost_tasks)
-				rnp->boost_tasks = np;
+				WRITE_ONCE(rnp->boost_tasks, np);
 		}
 
 		/*
@@ -556,7 +549,7 @@ static bool rcu_preempt_need_deferred_qs(struct task_struct *t)
 {
 	return (__this_cpu_read(rcu_data.exp_deferred_qs) ||
 		READ_ONCE(t->rcu_read_unlock_special.s)) &&
-	       rcu_preempt_depth() <= 0;
+	       rcu_preempt_depth() == 0;
 }
 
 /*
@@ -569,16 +562,11 @@ static bool rcu_preempt_need_deferred_qs(struct task_struct *t)
 static void rcu_preempt_deferred_qs(struct task_struct *t)
 {
 	unsigned long flags;
-	bool couldrecurse = rcu_preempt_depth() >= 0;
 
 	if (!rcu_preempt_need_deferred_qs(t))
 		return;
-	if (couldrecurse)
-		rcu_preempt_depth_set(rcu_preempt_depth() - RCU_NEST_BIAS);
 	local_irq_save(flags);
 	rcu_preempt_deferred_qs_irqrestore(t, flags);
-	if (couldrecurse)
-		rcu_preempt_depth_set(rcu_preempt_depth() + RCU_NEST_BIAS);
 }
 
 /*
@@ -615,19 +603,18 @@ static void rcu_read_unlock_special(struct task_struct *t)
 		struct rcu_data *rdp = this_cpu_ptr(&rcu_data);
 		struct rcu_node *rnp = rdp->mynode;
 
-		exp = (t->rcu_blocked_node && t->rcu_blocked_node->exp_tasks) ||
-		      (rdp->grpmask & READ_ONCE(rnp->expmask)) ||
-		      tick_nohz_full_cpu(rdp->cpu);
+		exp = (t->rcu_blocked_node &&
+		       READ_ONCE(t->rcu_blocked_node->exp_tasks)) ||
+		      (rdp->grpmask & READ_ONCE(rnp->expmask));
 		// Need to defer quiescent state until everything is enabled.
-		if (irqs_were_disabled && use_softirq &&
-		    (in_interrupt() ||
-		     (exp && !t->rcu_read_unlock_special.b.deferred_qs))) {
-			// Using softirq, safe to awaken, and we get
-			// no help from enabling irqs, unlike bh/preempt.
+		if (use_softirq && (in_irq() || (exp && !irqs_were_disabled))) {
+			// Using softirq, safe to awaken, and either the
+			// wakeup is free or there is an expedited GP.
 			raise_softirq_irqoff(RCU_SOFTIRQ);
 		} else {
 			// Enabling BH or preempt does reschedule, so...
-			// Also if no expediting or NO_HZ_FULL, slow is OK.
+			// Also if no expediting, slow is OK.
+			// Plus nohz_full CPUs eventually get tick enabled.
 			set_tsk_need_resched(current);
 			set_preempt_need_resched();
 			if (IS_ENABLED(CONFIG_IRQ_WORK) && irqs_were_disabled &&
@@ -640,7 +627,6 @@ static void rcu_read_unlock_special(struct task_struct *t)
 				irq_work_queue_on(&rdp->defer_qs_iw, rdp->cpu);
 			}
 		}
-		t->rcu_read_unlock_special.b.deferred_qs = true;
 		local_irq_restore(flags);
 		return;
 	}
@@ -699,7 +685,7 @@ static void rcu_flavor_sched_clock_irq(int user)
 	} else if (rcu_preempt_need_deferred_qs(t)) {
 		rcu_preempt_deferred_qs(t); /* Report deferred QS. */
 		return;
-	} else if (!rcu_preempt_depth()) {
+	} else if (!WARN_ON_ONCE(rcu_preempt_depth())) {
 		rcu_qs(); /* Report immediate QS. */
 		return;
 	}
@@ -760,8 +746,8 @@ dump_blkd_tasks(struct rcu_node *rnp, int ncheck)
 		pr_info("%s: %d:%d ->qsmask %#lx ->qsmaskinit %#lx ->qsmaskinitnext %#lx\n",
 			__func__, rnp1->grplo, rnp1->grphi, rnp1->qsmask, rnp1->qsmaskinit, rnp1->qsmaskinitnext);
 	pr_info("%s: ->gp_tasks %p ->boost_tasks %p ->exp_tasks %p\n",
-		__func__, READ_ONCE(rnp->gp_tasks), rnp->boost_tasks,
-		rnp->exp_tasks);
+		__func__, READ_ONCE(rnp->gp_tasks), data_race(rnp->boost_tasks),
+		READ_ONCE(rnp->exp_tasks));
 	pr_info("%s: ->blkd_tasks", __func__);
 	i = 0;
 	list_for_each(lhp, &rnp->blkd_tasks) {
@@ -854,8 +840,7 @@ void rcu_note_context_switch(bool preempt)
 	this_cpu_write(rcu_data.rcu_urgent_qs, false);
 	if (unlikely(raw_cpu_read(rcu_data.rcu_need_heavy_qs)))
 		rcu_momentary_dyntick_idle();
-	if (!preempt)
-		rcu_tasks_qs(current);
+	rcu_tasks_qs(current, preempt);
 out:
 	trace_rcu_utilization(TPS("End context switch"));
 }
@@ -1036,7 +1021,8 @@ static int rcu_boost_kthread(void *arg)
 	for (;;) {
 		WRITE_ONCE(rnp->boost_kthread_status, RCU_KTHREAD_WAITING);
 		trace_rcu_utilization(TPS("End boost kthread@rcu_wait"));
-		rcu_wait(rnp->boost_tasks || rnp->exp_tasks);
+		rcu_wait(READ_ONCE(rnp->boost_tasks) ||
+			 READ_ONCE(rnp->exp_tasks));
 		trace_rcu_utilization(TPS("Start boost kthread@rcu_wait"));
 		WRITE_ONCE(rnp->boost_kthread_status, RCU_KTHREAD_RUNNING);
 		more2boost = rcu_boost(rnp);
@@ -1079,9 +1065,9 @@ static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags)
 	    (rnp->gp_tasks != NULL &&
 	     rnp->boost_tasks == NULL &&
 	     rnp->qsmask == 0 &&
-	     (ULONG_CMP_GE(jiffies, rnp->boost_time) || rcu_state.cbovld))) {
+	     (!time_after(rnp->boost_time, jiffies) || rcu_state.cbovld))) {
 		if (rnp->exp_tasks == NULL)
-			rnp->boost_tasks = rnp->gp_tasks;
+			WRITE_ONCE(rnp->boost_tasks, rnp->gp_tasks);
 		raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
 		rcu_wake_cond(rnp->boost_kthread_task,
 			      READ_ONCE(rnp->boost_kthread_status));
@@ -2536,7 +2522,7 @@ static bool rcu_nohz_full_cpu(void)
 #ifdef CONFIG_NO_HZ_FULL
 	if (tick_nohz_full_cpu(smp_processor_id()) &&
 	    (!rcu_gp_in_progress() ||
-	     ULONG_CMP_LT(jiffies, READ_ONCE(rcu_state.gp_start) + HZ)))
+	     time_before(jiffies, READ_ONCE(rcu_state.gp_start) + HZ)))
 		return true;
 #endif /* #ifdef CONFIG_NO_HZ_FULL */
 	return false;
@@ -2567,3 +2553,21 @@ static void rcu_dynticks_task_exit(void)
 	WRITE_ONCE(current->rcu_tasks_idle_cpu, -1);
 #endif /* #if defined(CONFIG_TASKS_RCU) && defined(CONFIG_NO_HZ_FULL) */
 }
+
+/* Turn on heavyweight RCU tasks trace readers on idle/user entry. */
+static void rcu_dynticks_task_trace_enter(void)
+{
+#ifdef CONFIG_TASKS_RCU_TRACE
+	if (IS_ENABLED(CONFIG_TASKS_TRACE_RCU_READ_MB))
+		current->trc_reader_special.b.need_mb = true;
+#endif /* #ifdef CONFIG_TASKS_RCU_TRACE */
+}
+
+/* Turn off heavyweight RCU tasks trace readers on idle/user exit. */
+static void rcu_dynticks_task_trace_exit(void)
+{
+#ifdef CONFIG_TASKS_RCU_TRACE
+	if (IS_ENABLED(CONFIG_TASKS_TRACE_RCU_READ_MB))
+		current->trc_reader_special.b.need_mb = false;
+#endif /* #ifdef CONFIG_TASKS_RCU_TRACE */
+}
diff --git a/kernel/rcu/tree_stall.h b/kernel/rcu/tree_stall.h
index 119ed6afd20f..ae76bd329582 100644
--- a/kernel/rcu/tree_stall.h
+++ b/kernel/rcu/tree_stall.h
@@ -15,10 +15,12 @@
 int sysctl_panic_on_rcu_stall __read_mostly;
 
 #ifdef CONFIG_PROVE_RCU
-#define RCU_STALL_DELAY_DELTA	       (5 * HZ)
+#define RCU_STALL_DELAY_DELTA		(5 * HZ)
 #else
-#define RCU_STALL_DELAY_DELTA	       0
+#define RCU_STALL_DELAY_DELTA		0
 #endif
+#define RCU_STALL_MIGHT_DIV		8
+#define RCU_STALL_MIGHT_MIN		(2 * HZ)
 
 /* Limit-check stall timeouts specified at boottime and runtime. */
 int rcu_jiffies_till_stall_check(void)
@@ -40,6 +42,36 @@ int rcu_jiffies_till_stall_check(void)
 }
 EXPORT_SYMBOL_GPL(rcu_jiffies_till_stall_check);
 
+/**
+ * rcu_gp_might_be_stalled - Is it likely that the grace period is stalled?
+ *
+ * Returns @true if the current grace period is sufficiently old that
+ * it is reasonable to assume that it might be stalled.  This can be
+ * useful when deciding whether to allocate memory to enable RCU-mediated
+ * freeing on the one hand or just invoking synchronize_rcu() on the other.
+ * The latter is preferable when the grace period is stalled.
+ *
+ * Note that sampling of the .gp_start and .gp_seq fields must be done
+ * carefully to avoid false positives at the beginnings and ends of
+ * grace periods.
+ */
+bool rcu_gp_might_be_stalled(void)
+{
+	unsigned long d = rcu_jiffies_till_stall_check() / RCU_STALL_MIGHT_DIV;
+	unsigned long j = jiffies;
+
+	if (d < RCU_STALL_MIGHT_MIN)
+		d = RCU_STALL_MIGHT_MIN;
+	smp_mb(); // jiffies before .gp_seq to avoid false positives.
+	if (!rcu_gp_in_progress())
+		return false;
+	// Long delays at this point avoids false positive, but a delay
+	// of ULONG_MAX/4 jiffies voids your no-false-positive warranty.
+	smp_mb(); // .gp_seq before second .gp_start
+	// And ditto here.
+	return !time_before(j, READ_ONCE(rcu_state.gp_start) + d);
+}
+
 /* Don't do RCU CPU stall warnings during long sysrq printouts. */
 void rcu_sysrq_start(void)
 {
@@ -104,8 +136,8 @@ static void record_gp_stall_check_time(void)
 
 	WRITE_ONCE(rcu_state.gp_start, j);
 	j1 = rcu_jiffies_till_stall_check();
-	/* Record ->gp_start before ->jiffies_stall. */
-	smp_store_release(&rcu_state.jiffies_stall, j + j1); /* ^^^ */
+	smp_mb(); // ->gp_start before ->jiffies_stall and caller's ->gp_seq.
+	WRITE_ONCE(rcu_state.jiffies_stall, j + j1);
 	rcu_state.jiffies_resched = j + j1 / 2;
 	rcu_state.n_force_qs_gpstart = READ_ONCE(rcu_state.n_force_qs);
 }
@@ -192,14 +224,40 @@ static void rcu_print_detail_task_stall_rnp(struct rcu_node *rnp)
 	raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
 }
 
+// Communicate task state back to the RCU CPU stall warning request.
+struct rcu_stall_chk_rdr {
+	int nesting;
+	union rcu_special rs;
+	bool on_blkd_list;
+};
+
+/*
+ * Report out the state of a not-running task that is stalling the
+ * current RCU grace period.
+ */
+static bool check_slow_task(struct task_struct *t, void *arg)
+{
+	struct rcu_node *rnp;
+	struct rcu_stall_chk_rdr *rscrp = arg;
+
+	if (task_curr(t))
+		return false; // It is running, so decline to inspect it.
+	rscrp->nesting = t->rcu_read_lock_nesting;
+	rscrp->rs = t->rcu_read_unlock_special;
+	rnp = t->rcu_blocked_node;
+	rscrp->on_blkd_list = !list_empty(&t->rcu_node_entry);
+	return true;
+}
+
 /*
  * Scan the current list of tasks blocked within RCU read-side critical
  * sections, printing out the tid of each.
  */
 static int rcu_print_task_stall(struct rcu_node *rnp)
 {
-	struct task_struct *t;
 	int ndetected = 0;
+	struct rcu_stall_chk_rdr rscr;
+	struct task_struct *t;
 
 	if (!rcu_preempt_blocked_readers_cgp(rnp))
 		return 0;
@@ -208,7 +266,15 @@ static int rcu_print_task_stall(struct rcu_node *rnp)
 	t = list_entry(rnp->gp_tasks->prev,
 		       struct task_struct, rcu_node_entry);
 	list_for_each_entry_continue(t, &rnp->blkd_tasks, rcu_node_entry) {
-		pr_cont(" P%d", t->pid);
+		if (!try_invoke_on_locked_down_task(t, check_slow_task, &rscr))
+			pr_cont(" P%d", t->pid);
+		else
+			pr_cont(" P%d/%d:%c%c%c%c",
+				t->pid, rscr.nesting,
+				".b"[rscr.rs.b.blocked],
+				".q"[rscr.rs.b.need_qs],
+				".e"[rscr.rs.b.exp_hint],
+				".l"[rscr.on_blkd_list]);
 		ndetected++;
 	}
 	pr_cont("\n");
@@ -299,6 +365,16 @@ static const char *gp_state_getname(short gs)
 	return gp_state_names[gs];
 }
 
+/* Is the RCU grace-period kthread being starved of CPU time? */
+static bool rcu_is_gp_kthread_starving(unsigned long *jp)
+{
+	unsigned long j = jiffies - READ_ONCE(rcu_state.gp_activity);
+
+	if (jp)
+		*jp = j;
+	return j > 2 * HZ;
+}
+
 /*
  * Print out diagnostic information for the specified stalled CPU.
  *
@@ -313,6 +389,7 @@ static const char *gp_state_getname(short gs)
 static void print_cpu_stall_info(int cpu)
 {
 	unsigned long delta;
+	bool falsepositive;
 	char fast_no_hz[72];
 	struct rcu_data *rdp = per_cpu_ptr(&rcu_data, cpu);
 	char *ticks_title;
@@ -333,7 +410,9 @@ static void print_cpu_stall_info(int cpu)
 	}
 	print_cpu_stall_fast_no_hz(fast_no_hz, cpu);
 	delta = rcu_seq_ctr(rdp->mynode->gp_seq - rdp->rcu_iw_gp_seq);
-	pr_err("\t%d-%c%c%c%c: (%lu %s) idle=%03x/%ld/%#lx softirq=%u/%u fqs=%ld %s\n",
+	falsepositive = rcu_is_gp_kthread_starving(NULL) &&
+			rcu_dynticks_in_eqs(rcu_dynticks_snap(rdp));
+	pr_err("\t%d-%c%c%c%c: (%lu %s) idle=%03x/%ld/%#lx softirq=%u/%u fqs=%ld %s%s\n",
 	       cpu,
 	       "O."[!!cpu_online(cpu)],
 	       "o."[!!(rdp->grpmask & rdp->mynode->qsmaskinit)],
@@ -345,8 +424,9 @@ static void print_cpu_stall_info(int cpu)
 	       rcu_dynticks_snap(rdp) & 0xfff,
 	       rdp->dynticks_nesting, rdp->dynticks_nmi_nesting,
 	       rdp->softirq_snap, kstat_softirqs_cpu(RCU_SOFTIRQ, cpu),
-	       READ_ONCE(rcu_state.n_force_qs) - rcu_state.n_force_qs_gpstart,
-	       fast_no_hz);
+	       data_race(rcu_state.n_force_qs) - rcu_state.n_force_qs_gpstart,
+	       fast_no_hz,
+	       falsepositive ? " (false positive?)" : "");
 }
 
 /* Complain about starvation of grace-period kthread.  */
@@ -355,15 +435,15 @@ static void rcu_check_gp_kthread_starvation(void)
 	struct task_struct *gpk = rcu_state.gp_kthread;
 	unsigned long j;
 
-	j = jiffies - READ_ONCE(rcu_state.gp_activity);
-	if (j > 2 * HZ) {
+	if (rcu_is_gp_kthread_starving(&j)) {
 		pr_err("%s kthread starved for %ld jiffies! g%ld f%#x %s(%d) ->state=%#lx ->cpu=%d\n",
 		       rcu_state.name, j,
 		       (long)rcu_seq_current(&rcu_state.gp_seq),
-		       READ_ONCE(rcu_state.gp_flags),
+		       data_race(rcu_state.gp_flags),
 		       gp_state_getname(rcu_state.gp_state), rcu_state.gp_state,
 		       gpk ? gpk->state : ~0, gpk ? task_cpu(gpk) : -1);
 		if (gpk) {
+			pr_err("\tUnless %s kthread gets sufficient CPU time, OOM is now expected behavior.\n", rcu_state.name);
 			pr_err("RCU grace-period kthread stack dump:\n");
 			sched_show_task(gpk);
 			wake_up_process(gpk);
@@ -371,7 +451,7 @@ static void rcu_check_gp_kthread_starvation(void)
 	}
 }
 
-static void print_other_cpu_stall(unsigned long gp_seq)
+static void print_other_cpu_stall(unsigned long gp_seq, unsigned long gps)
 {
 	int cpu;
 	unsigned long flags;
@@ -408,7 +488,7 @@ static void print_other_cpu_stall(unsigned long gp_seq)
 	for_each_possible_cpu(cpu)
 		totqlen += rcu_get_n_cbs_cpu(cpu);
 	pr_cont("\t(detected by %d, t=%ld jiffies, g=%ld, q=%lu)\n",
-	       smp_processor_id(), (long)(jiffies - rcu_state.gp_start),
+	       smp_processor_id(), (long)(jiffies - gps),
 	       (long)rcu_seq_current(&rcu_state.gp_seq), totqlen);
 	if (ndetected) {
 		rcu_dump_cpu_stacks();
@@ -421,13 +501,11 @@ static void print_other_cpu_stall(unsigned long gp_seq)
 			pr_err("INFO: Stall ended before state dump start\n");
 		} else {
 			j = jiffies;
-			gpa = READ_ONCE(rcu_state.gp_activity);
+			gpa = data_race(rcu_state.gp_activity);
 			pr_err("All QSes seen, last %s kthread activity %ld (%ld-%ld), jiffies_till_next_fqs=%ld, root ->qsmask %#lx\n",
 			       rcu_state.name, j - gpa, j, gpa,
-			       READ_ONCE(jiffies_till_next_fqs),
+			       data_race(jiffies_till_next_fqs),
 			       rcu_get_root()->qsmask);
-			/* In this case, the current CPU might be at fault. */
-			sched_show_task(current);
 		}
 	}
 	/* Rewrite if needed in case of slow consoles. */
@@ -442,7 +520,7 @@ static void print_other_cpu_stall(unsigned long gp_seq)
 	rcu_force_quiescent_state();  /* Kick them all. */
 }
 
-static void print_cpu_stall(void)
+static void print_cpu_stall(unsigned long gps)
 {
 	int cpu;
 	unsigned long flags;
@@ -467,7 +545,7 @@ static void print_cpu_stall(void)
 	for_each_possible_cpu(cpu)
 		totqlen += rcu_get_n_cbs_cpu(cpu);
 	pr_cont("\t(t=%lu jiffies g=%ld q=%lu)\n",
-		jiffies - rcu_state.gp_start,
+		jiffies - gps,
 		(long)rcu_seq_current(&rcu_state.gp_seq), totqlen);
 
 	rcu_check_gp_kthread_starvation();
@@ -546,7 +624,7 @@ static void check_cpu_stall(struct rcu_data *rdp)
 	    cmpxchg(&rcu_state.jiffies_stall, js, jn) == js) {
 
 		/* We haven't checked in, so go dump stack. */
-		print_cpu_stall();
+		print_cpu_stall(gps);
 		if (rcu_cpu_stall_ftrace_dump)
 			rcu_ftrace_dump(DUMP_ALL);
 
@@ -555,7 +633,7 @@ static void check_cpu_stall(struct rcu_data *rdp)
 		   cmpxchg(&rcu_state.jiffies_stall, js, jn) == js) {
 
 		/* They had a few time units to dump stack, so complain. */
-		print_other_cpu_stall(gs2);
+		print_other_cpu_stall(gs2, gps);
 		if (rcu_cpu_stall_ftrace_dump)
 			rcu_ftrace_dump(DUMP_ALL);
 	}
@@ -581,23 +659,23 @@ void show_rcu_gp_kthreads(void)
 	struct task_struct *t = READ_ONCE(rcu_state.gp_kthread);
 
 	j = jiffies;
-	ja = j - READ_ONCE(rcu_state.gp_activity);
-	jr = j - READ_ONCE(rcu_state.gp_req_activity);
-	jw = j - READ_ONCE(rcu_state.gp_wake_time);
+	ja = j - data_race(rcu_state.gp_activity);
+	jr = j - data_race(rcu_state.gp_req_activity);
+	jw = j - data_race(rcu_state.gp_wake_time);
 	pr_info("%s: wait state: %s(%d) ->state: %#lx delta ->gp_activity %lu ->gp_req_activity %lu ->gp_wake_time %lu ->gp_wake_seq %ld ->gp_seq %ld ->gp_seq_needed %ld ->gp_flags %#x\n",
 		rcu_state.name, gp_state_getname(rcu_state.gp_state),
 		rcu_state.gp_state, t ? t->state : 0x1ffffL,
-		ja, jr, jw, (long)READ_ONCE(rcu_state.gp_wake_seq),
-		(long)READ_ONCE(rcu_state.gp_seq),
-		(long)READ_ONCE(rcu_get_root()->gp_seq_needed),
-		READ_ONCE(rcu_state.gp_flags));
+		ja, jr, jw, (long)data_race(rcu_state.gp_wake_seq),
+		(long)data_race(rcu_state.gp_seq),
+		(long)data_race(rcu_get_root()->gp_seq_needed),
+		data_race(rcu_state.gp_flags));
 	rcu_for_each_node_breadth_first(rnp) {
 		if (ULONG_CMP_GE(READ_ONCE(rcu_state.gp_seq),
 				 READ_ONCE(rnp->gp_seq_needed)))
 			continue;
 		pr_info("\trcu_node %d:%d ->gp_seq %ld ->gp_seq_needed %ld\n",
-			rnp->grplo, rnp->grphi, (long)READ_ONCE(rnp->gp_seq),
-			(long)READ_ONCE(rnp->gp_seq_needed));
+			rnp->grplo, rnp->grphi, (long)data_race(rnp->gp_seq),
+			(long)data_race(rnp->gp_seq_needed));
 		if (!rcu_is_leaf_node(rnp))
 			continue;
 		for_each_leaf_node_possible_cpu(rnp, cpu) {
@@ -607,7 +685,7 @@ void show_rcu_gp_kthreads(void)
 					 READ_ONCE(rdp->gp_seq_needed)))
 				continue;
 			pr_info("\tcpu %d ->gp_seq_needed %ld\n",
-				cpu, (long)READ_ONCE(rdp->gp_seq_needed));
+				cpu, (long)data_race(rdp->gp_seq_needed));
 		}
 	}
 	for_each_possible_cpu(cpu) {
@@ -615,7 +693,7 @@ void show_rcu_gp_kthreads(void)
 		if (rcu_segcblist_is_offloaded(&rdp->cblist))
 			show_rcu_nocb_state(rdp);
 	}
-	/* sched_show_task(rcu_state.gp_kthread); */
+	show_rcu_tasks_gp_kthreads();
 }
 EXPORT_SYMBOL_GPL(show_rcu_gp_kthreads);
 
diff --git a/kernel/rcu/update.c b/kernel/rcu/update.c
index 28a8bdc5072f..3ce63a91d956 100644
--- a/kernel/rcu/update.c
+++ b/kernel/rcu/update.c
@@ -41,6 +41,7 @@
 #include <linux/sched/isolation.h>
 #include <linux/kprobes.h>
 #include <linux/slab.h>
+#include <linux/irq_work.h>
 
 #define CREATE_TRACE_POINTS
 
@@ -51,6 +52,19 @@
 #endif
 #define MODULE_PARAM_PREFIX "rcupdate."
 
+#ifndef data_race
+#define data_race(expr)							\
+	({								\
+		expr;							\
+	})
+#endif
+#ifndef ASSERT_EXCLUSIVE_WRITER
+#define ASSERT_EXCLUSIVE_WRITER(var) do { } while (0)
+#endif
+#ifndef ASSERT_EXCLUSIVE_ACCESS
+#define ASSERT_EXCLUSIVE_ACCESS(var) do { } while (0)
+#endif
+
 #ifndef CONFIG_TINY_RCU
 module_param(rcu_expedited, int, 0);
 module_param(rcu_normal, int, 0);
@@ -63,12 +77,12 @@ module_param(rcu_normal_after_boot, int, 0);
  * rcu_read_lock_held_common() - might we be in RCU-sched read-side critical section?
  * @ret:	Best guess answer if lockdep cannot be relied on
  *
- * Returns true if lockdep must be ignored, in which case *ret contains
+ * Returns true if lockdep must be ignored, in which case ``*ret`` contains
  * the best guess described below.  Otherwise returns false, in which
- * case *ret tells the caller nothing and the caller should instead
+ * case ``*ret`` tells the caller nothing and the caller should instead
  * consult lockdep.
  *
- * If CONFIG_DEBUG_LOCK_ALLOC is selected, set *ret to nonzero iff in an
+ * If CONFIG_DEBUG_LOCK_ALLOC is selected, set ``*ret`` to nonzero iff in an
  * RCU-sched read-side critical section.  In absence of
  * CONFIG_DEBUG_LOCK_ALLOC, this assumes we are in an RCU-sched read-side
  * critical section unless it can prove otherwise.  Note that disabling
@@ -82,7 +96,7 @@ module_param(rcu_normal_after_boot, int, 0);
  *
  * Note that if the CPU is in the idle loop from an RCU point of view (ie:
  * that we are in the section between rcu_idle_enter() and rcu_idle_exit())
- * then rcu_read_lock_held() sets *ret to false even if the CPU did an
+ * then rcu_read_lock_held() sets ``*ret`` to false even if the CPU did an
  * rcu_read_lock().  The reason for this is that RCU ignores CPUs that are
  * in such a section, considering these as in extended quiescent state,
  * so such a CPU is effectively never in an RCU read-side critical section
@@ -98,15 +112,15 @@ module_param(rcu_normal_after_boot, int, 0);
 static bool rcu_read_lock_held_common(bool *ret)
 {
 	if (!debug_lockdep_rcu_enabled()) {
-		*ret = 1;
+		*ret = true;
 		return true;
 	}
 	if (!rcu_is_watching()) {
-		*ret = 0;
+		*ret = false;
 		return true;
 	}
 	if (!rcu_lockdep_current_cpu_online()) {
-		*ret = 0;
+		*ret = false;
 		return true;
 	}
 	return false;
@@ -501,370 +515,6 @@ int rcu_cpu_stall_suppress_at_boot __read_mostly; // !0 = suppress boot stalls.
 EXPORT_SYMBOL_GPL(rcu_cpu_stall_suppress_at_boot);
 module_param(rcu_cpu_stall_suppress_at_boot, int, 0444);
 
-#ifdef CONFIG_TASKS_RCU
-
-/*
- * Simple variant of RCU whose quiescent states are voluntary context
- * switch, cond_resched_rcu_qs(), user-space execution, and idle.
- * As such, grace periods can take one good long time.  There are no
- * read-side primitives similar to rcu_read_lock() and rcu_read_unlock()
- * because this implementation is intended to get the system into a safe
- * state for some of the manipulations involved in tracing and the like.
- * Finally, this implementation does not support high call_rcu_tasks()
- * rates from multiple CPUs.  If this is required, per-CPU callback lists
- * will be needed.
- */
-
-/* Global list of callbacks and associated lock. */
-static struct rcu_head *rcu_tasks_cbs_head;
-static struct rcu_head **rcu_tasks_cbs_tail = &rcu_tasks_cbs_head;
-static DECLARE_WAIT_QUEUE_HEAD(rcu_tasks_cbs_wq);
-static DEFINE_RAW_SPINLOCK(rcu_tasks_cbs_lock);
-
-/* Track exiting tasks in order to allow them to be waited for. */
-DEFINE_STATIC_SRCU(tasks_rcu_exit_srcu);
-
-/* Control stall timeouts.  Disable with <= 0, otherwise jiffies till stall. */
-#define RCU_TASK_STALL_TIMEOUT (HZ * 60 * 10)
-static int rcu_task_stall_timeout __read_mostly = RCU_TASK_STALL_TIMEOUT;
-module_param(rcu_task_stall_timeout, int, 0644);
-
-static struct task_struct *rcu_tasks_kthread_ptr;
-
-/**
- * call_rcu_tasks() - Queue an RCU for invocation task-based grace period
- * @rhp: structure to be used for queueing the RCU updates.
- * @func: actual callback function to be invoked after the grace period
- *
- * The callback function will be invoked some time after a full grace
- * period elapses, in other words after all currently executing RCU
- * read-side critical sections have completed. call_rcu_tasks() assumes
- * that the read-side critical sections end at a voluntary context
- * switch (not a preemption!), cond_resched_rcu_qs(), entry into idle,
- * or transition to usermode execution.  As such, there are no read-side
- * primitives analogous to rcu_read_lock() and rcu_read_unlock() because
- * this primitive is intended to determine that all tasks have passed
- * through a safe state, not so much for data-strcuture synchronization.
- *
- * See the description of call_rcu() for more detailed information on
- * memory ordering guarantees.
- */
-void call_rcu_tasks(struct rcu_head *rhp, rcu_callback_t func)
-{
-	unsigned long flags;
-	bool needwake;
-
-	rhp->next = NULL;
-	rhp->func = func;
-	raw_spin_lock_irqsave(&rcu_tasks_cbs_lock, flags);
-	needwake = !rcu_tasks_cbs_head;
-	WRITE_ONCE(*rcu_tasks_cbs_tail, rhp);
-	rcu_tasks_cbs_tail = &rhp->next;
-	raw_spin_unlock_irqrestore(&rcu_tasks_cbs_lock, flags);
-	/* We can't create the thread unless interrupts are enabled. */
-	if (needwake && READ_ONCE(rcu_tasks_kthread_ptr))
-		wake_up(&rcu_tasks_cbs_wq);
-}
-EXPORT_SYMBOL_GPL(call_rcu_tasks);
-
-/**
- * synchronize_rcu_tasks - wait until an rcu-tasks grace period has elapsed.
- *
- * Control will return to the caller some time after a full rcu-tasks
- * grace period has elapsed, in other words after all currently
- * executing rcu-tasks read-side critical sections have elapsed.  These
- * read-side critical sections are delimited by calls to schedule(),
- * cond_resched_tasks_rcu_qs(), idle execution, userspace execution, calls
- * to synchronize_rcu_tasks(), and (in theory, anyway) cond_resched().
- *
- * This is a very specialized primitive, intended only for a few uses in
- * tracing and other situations requiring manipulation of function
- * preambles and profiling hooks.  The synchronize_rcu_tasks() function
- * is not (yet) intended for heavy use from multiple CPUs.
- *
- * Note that this guarantee implies further memory-ordering guarantees.
- * On systems with more than one CPU, when synchronize_rcu_tasks() returns,
- * each CPU is guaranteed to have executed a full memory barrier since the
- * end of its last RCU-tasks read-side critical section whose beginning
- * preceded the call to synchronize_rcu_tasks().  In addition, each CPU
- * having an RCU-tasks read-side critical section that extends beyond
- * the return from synchronize_rcu_tasks() is guaranteed to have executed
- * a full memory barrier after the beginning of synchronize_rcu_tasks()
- * and before the beginning of that RCU-tasks read-side critical section.
- * Note that these guarantees include CPUs that are offline, idle, or
- * executing in user mode, as well as CPUs that are executing in the kernel.
- *
- * Furthermore, if CPU A invoked synchronize_rcu_tasks(), which returned
- * to its caller on CPU B, then both CPU A and CPU B are guaranteed
- * to have executed a full memory barrier during the execution of
- * synchronize_rcu_tasks() -- even if CPU A and CPU B are the same CPU
- * (but again only if the system has more than one CPU).
- */
-void synchronize_rcu_tasks(void)
-{
-	/* Complain if the scheduler has not started.  */
-	RCU_LOCKDEP_WARN(rcu_scheduler_active == RCU_SCHEDULER_INACTIVE,
-			 "synchronize_rcu_tasks called too soon");
-
-	/* Wait for the grace period. */
-	wait_rcu_gp(call_rcu_tasks);
-}
-EXPORT_SYMBOL_GPL(synchronize_rcu_tasks);
-
-/**
- * rcu_barrier_tasks - Wait for in-flight call_rcu_tasks() callbacks.
- *
- * Although the current implementation is guaranteed to wait, it is not
- * obligated to, for example, if there are no pending callbacks.
- */
-void rcu_barrier_tasks(void)
-{
-	/* There is only one callback queue, so this is easy.  ;-) */
-	synchronize_rcu_tasks();
-}
-EXPORT_SYMBOL_GPL(rcu_barrier_tasks);
-
-/* See if tasks are still holding out, complain if so. */
-static void check_holdout_task(struct task_struct *t,
-			       bool needreport, bool *firstreport)
-{
-	int cpu;
-
-	if (!READ_ONCE(t->rcu_tasks_holdout) ||
-	    t->rcu_tasks_nvcsw != READ_ONCE(t->nvcsw) ||
-	    !READ_ONCE(t->on_rq) ||
-	    (IS_ENABLED(CONFIG_NO_HZ_FULL) &&
-	     !is_idle_task(t) && t->rcu_tasks_idle_cpu >= 0)) {
-		WRITE_ONCE(t->rcu_tasks_holdout, false);
-		list_del_init(&t->rcu_tasks_holdout_list);
-		put_task_struct(t);
-		return;
-	}
-	rcu_request_urgent_qs_task(t);
-	if (!needreport)
-		return;
-	if (*firstreport) {
-		pr_err("INFO: rcu_tasks detected stalls on tasks:\n");
-		*firstreport = false;
-	}
-	cpu = task_cpu(t);
-	pr_alert("%p: %c%c nvcsw: %lu/%lu holdout: %d idle_cpu: %d/%d\n",
-		 t, ".I"[is_idle_task(t)],
-		 "N."[cpu < 0 || !tick_nohz_full_cpu(cpu)],
-		 t->rcu_tasks_nvcsw, t->nvcsw, t->rcu_tasks_holdout,
-		 t->rcu_tasks_idle_cpu, cpu);
-	sched_show_task(t);
-}
-
-/* RCU-tasks kthread that detects grace periods and invokes callbacks. */
-static int __noreturn rcu_tasks_kthread(void *arg)
-{
-	unsigned long flags;
-	struct task_struct *g, *t;
-	unsigned long lastreport;
-	struct rcu_head *list;
-	struct rcu_head *next;
-	LIST_HEAD(rcu_tasks_holdouts);
-	int fract;
-
-	/* Run on housekeeping CPUs by default.  Sysadm can move if desired. */
-	housekeeping_affine(current, HK_FLAG_RCU);
-
-	/*
-	 * Each pass through the following loop makes one check for
-	 * newly arrived callbacks, and, if there are some, waits for
-	 * one RCU-tasks grace period and then invokes the callbacks.
-	 * This loop is terminated by the system going down.  ;-)
-	 */
-	for (;;) {
-
-		/* Pick up any new callbacks. */
-		raw_spin_lock_irqsave(&rcu_tasks_cbs_lock, flags);
-		list = rcu_tasks_cbs_head;
-		rcu_tasks_cbs_head = NULL;
-		rcu_tasks_cbs_tail = &rcu_tasks_cbs_head;
-		raw_spin_unlock_irqrestore(&rcu_tasks_cbs_lock, flags);
-
-		/* If there were none, wait a bit and start over. */
-		if (!list) {
-			wait_event_interruptible(rcu_tasks_cbs_wq,
-						 READ_ONCE(rcu_tasks_cbs_head));
-			if (!rcu_tasks_cbs_head) {
-				WARN_ON(signal_pending(current));
-				schedule_timeout_interruptible(HZ/10);
-			}
-			continue;
-		}
-
-		/*
-		 * Wait for all pre-existing t->on_rq and t->nvcsw
-		 * transitions to complete.  Invoking synchronize_rcu()
-		 * suffices because all these transitions occur with
-		 * interrupts disabled.  Without this synchronize_rcu(),
-		 * a read-side critical section that started before the
-		 * grace period might be incorrectly seen as having started
-		 * after the grace period.
-		 *
-		 * This synchronize_rcu() also dispenses with the
-		 * need for a memory barrier on the first store to
-		 * ->rcu_tasks_holdout, as it forces the store to happen
-		 * after the beginning of the grace period.
-		 */
-		synchronize_rcu();
-
-		/*
-		 * There were callbacks, so we need to wait for an
-		 * RCU-tasks grace period.  Start off by scanning
-		 * the task list for tasks that are not already
-		 * voluntarily blocked.  Mark these tasks and make
-		 * a list of them in rcu_tasks_holdouts.
-		 */
-		rcu_read_lock();
-		for_each_process_thread(g, t) {
-			if (t != current && READ_ONCE(t->on_rq) &&
-			    !is_idle_task(t)) {
-				get_task_struct(t);
-				t->rcu_tasks_nvcsw = READ_ONCE(t->nvcsw);
-				WRITE_ONCE(t->rcu_tasks_holdout, true);
-				list_add(&t->rcu_tasks_holdout_list,
-					 &rcu_tasks_holdouts);
-			}
-		}
-		rcu_read_unlock();
-
-		/*
-		 * Wait for tasks that are in the process of exiting.
-		 * This does only part of the job, ensuring that all
-		 * tasks that were previously exiting reach the point
-		 * where they have disabled preemption, allowing the
-		 * later synchronize_rcu() to finish the job.
-		 */
-		synchronize_srcu(&tasks_rcu_exit_srcu);
-
-		/*
-		 * Each pass through the following loop scans the list
-		 * of holdout tasks, removing any that are no longer
-		 * holdouts.  When the list is empty, we are done.
-		 */
-		lastreport = jiffies;
-
-		/* Start off with HZ/10 wait and slowly back off to 1 HZ wait*/
-		fract = 10;
-
-		for (;;) {
-			bool firstreport;
-			bool needreport;
-			int rtst;
-			struct task_struct *t1;
-
-			if (list_empty(&rcu_tasks_holdouts))
-				break;
-
-			/* Slowly back off waiting for holdouts */
-			schedule_timeout_interruptible(HZ/fract);
-
-			if (fract > 1)
-				fract--;
-
-			rtst = READ_ONCE(rcu_task_stall_timeout);
-			needreport = rtst > 0 &&
-				     time_after(jiffies, lastreport + rtst);
-			if (needreport)
-				lastreport = jiffies;
-			firstreport = true;
-			WARN_ON(signal_pending(current));
-			list_for_each_entry_safe(t, t1, &rcu_tasks_holdouts,
-						rcu_tasks_holdout_list) {
-				check_holdout_task(t, needreport, &firstreport);
-				cond_resched();
-			}
-		}
-
-		/*
-		 * Because ->on_rq and ->nvcsw are not guaranteed
-		 * to have a full memory barriers prior to them in the
-		 * schedule() path, memory reordering on other CPUs could
-		 * cause their RCU-tasks read-side critical sections to
-		 * extend past the end of the grace period.  However,
-		 * because these ->nvcsw updates are carried out with
-		 * interrupts disabled, we can use synchronize_rcu()
-		 * to force the needed ordering on all such CPUs.
-		 *
-		 * This synchronize_rcu() also confines all
-		 * ->rcu_tasks_holdout accesses to be within the grace
-		 * period, avoiding the need for memory barriers for
-		 * ->rcu_tasks_holdout accesses.
-		 *
-		 * In addition, this synchronize_rcu() waits for exiting
-		 * tasks to complete their final preempt_disable() region
-		 * of execution, cleaning up after the synchronize_srcu()
-		 * above.
-		 */
-		synchronize_rcu();
-
-		/* Invoke the callbacks. */
-		while (list) {
-			next = list->next;
-			local_bh_disable();
-			list->func(list);
-			local_bh_enable();
-			list = next;
-			cond_resched();
-		}
-		/* Paranoid sleep to keep this from entering a tight loop */
-		schedule_timeout_uninterruptible(HZ/10);
-	}
-}
-
-/* Spawn rcu_tasks_kthread() at core_initcall() time. */
-static int __init rcu_spawn_tasks_kthread(void)
-{
-	struct task_struct *t;
-
-	t = kthread_run(rcu_tasks_kthread, NULL, "rcu_tasks_kthread");
-	if (WARN_ONCE(IS_ERR(t), "%s: Could not start Tasks-RCU grace-period kthread, OOM is now expected behavior\n", __func__))
-		return 0;
-	smp_mb(); /* Ensure others see full kthread. */
-	WRITE_ONCE(rcu_tasks_kthread_ptr, t);
-	return 0;
-}
-core_initcall(rcu_spawn_tasks_kthread);
-
-/* Do the srcu_read_lock() for the above synchronize_srcu().  */
-void exit_tasks_rcu_start(void) __acquires(&tasks_rcu_exit_srcu)
-{
-	preempt_disable();
-	current->rcu_tasks_idx = __srcu_read_lock(&tasks_rcu_exit_srcu);
-	preempt_enable();
-}
-
-/* Do the srcu_read_unlock() for the above synchronize_srcu().  */
-void exit_tasks_rcu_finish(void) __releases(&tasks_rcu_exit_srcu)
-{
-	preempt_disable();
-	__srcu_read_unlock(&tasks_rcu_exit_srcu, current->rcu_tasks_idx);
-	preempt_enable();
-}
-
-#endif /* #ifdef CONFIG_TASKS_RCU */
-
-#ifndef CONFIG_TINY_RCU
-
-/*
- * Print any non-default Tasks RCU settings.
- */
-static void __init rcu_tasks_bootup_oddness(void)
-{
-#ifdef CONFIG_TASKS_RCU
-	if (rcu_task_stall_timeout != RCU_TASK_STALL_TIMEOUT)
-		pr_info("\tTasks-RCU CPU stall warnings timeout set to %d (rcu_task_stall_timeout).\n", rcu_task_stall_timeout);
-	else
-		pr_info("\tTasks RCU enabled.\n");
-#endif /* #ifdef CONFIG_TASKS_RCU */
-}
-
-#endif /* #ifndef CONFIG_TINY_RCU */
-
 #ifdef CONFIG_PROVE_RCU
 
 /*
@@ -935,6 +585,8 @@ late_initcall(rcu_verify_early_boot_tests);
 void rcu_early_boot_tests(void) {}
 #endif /* CONFIG_PROVE_RCU */
 
+#include "tasks.h"
+
 #ifndef CONFIG_TINY_RCU
 
 /*
diff --git a/kernel/relay.c b/kernel/relay.c
index ade14fb7ce2e..07ee1a791d85 100644
--- a/kernel/relay.c
+++ b/kernel/relay.c
@@ -991,14 +991,14 @@ static void relay_file_read_consume(struct rchan_buf *buf,
 /*
  *	relay_file_read_avail - boolean, are there unconsumed bytes available?
  */
-static int relay_file_read_avail(struct rchan_buf *buf, size_t read_pos)
+static int relay_file_read_avail(struct rchan_buf *buf)
 {
 	size_t subbuf_size = buf->chan->subbuf_size;
 	size_t n_subbufs = buf->chan->n_subbufs;
 	size_t produced = buf->subbufs_produced;
 	size_t consumed = buf->subbufs_consumed;
 
-	relay_file_read_consume(buf, read_pos, 0);
+	relay_file_read_consume(buf, 0, 0);
 
 	consumed = buf->subbufs_consumed;
 
@@ -1059,23 +1059,20 @@ static size_t relay_file_read_subbuf_avail(size_t read_pos,
 
 /**
  *	relay_file_read_start_pos - find the first available byte to read
- *	@read_pos: file read position
  *	@buf: relay channel buffer
  *
- *	If the @read_pos is in the middle of padding, return the
+ *	If the read_pos is in the middle of padding, return the
  *	position of the first actually available byte, otherwise
  *	return the original value.
  */
-static size_t relay_file_read_start_pos(size_t read_pos,
-					struct rchan_buf *buf)
+static size_t relay_file_read_start_pos(struct rchan_buf *buf)
 {
 	size_t read_subbuf, padding, padding_start, padding_end;
 	size_t subbuf_size = buf->chan->subbuf_size;
 	size_t n_subbufs = buf->chan->n_subbufs;
 	size_t consumed = buf->subbufs_consumed % n_subbufs;
+	size_t read_pos = consumed * subbuf_size + buf->bytes_consumed;
 
-	if (!read_pos)
-		read_pos = consumed * subbuf_size + buf->bytes_consumed;
 	read_subbuf = read_pos / subbuf_size;
 	padding = buf->padding[read_subbuf];
 	padding_start = (read_subbuf + 1) * subbuf_size - padding;
@@ -1131,10 +1128,10 @@ static ssize_t relay_file_read(struct file *filp,
 	do {
 		void *from;
 
-		if (!relay_file_read_avail(buf, *ppos))
+		if (!relay_file_read_avail(buf))
 			break;
 
-		read_start = relay_file_read_start_pos(*ppos, buf);
+		read_start = relay_file_read_start_pos(buf);
 		avail = relay_file_read_subbuf_avail(read_start, buf);
 		if (!avail)
 			break;
diff --git a/kernel/sched/Makefile b/kernel/sched/Makefile
index 21fb5a5662b5..5fc9c9b70862 100644
--- a/kernel/sched/Makefile
+++ b/kernel/sched/Makefile
@@ -7,6 +7,12 @@ endif
 # that is not a function of syscall inputs. E.g. involuntary context switches.
 KCOV_INSTRUMENT := n
 
+# There are numerous data races here, however, most of them are due to plain accesses.
+# This would make it even harder for syzbot to find reproducers, because these
+# bugs trigger without specific input. Disable by default, but should re-enable
+# eventually.
+KCSAN_SANITIZE := n
+
 ifneq ($(CONFIG_SCHED_OMIT_FRAME_POINTER),y)
 # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
 # needed for x86 only.  Why this used to be enabled for all architectures is beyond
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 3a61a3b8eaa9..5ca567adfcb9 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -2566,6 +2566,8 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags)
 	 *
 	 * Pairs with the LOCK+smp_mb__after_spinlock() on rq->lock in
 	 * __schedule().  See the comment for smp_mb__after_spinlock().
+	 *
+	 * A similar smb_rmb() lives in try_invoke_on_locked_down_task().
 	 */
 	smp_rmb();
 	if (p->on_rq && ttwu_remote(p, wake_flags))
@@ -2639,6 +2641,52 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags)
 	return success;
 }
 
+/**
+ * try_invoke_on_locked_down_task - Invoke a function on task in fixed state
+ * @p: Process for which the function is to be invoked.
+ * @func: Function to invoke.
+ * @arg: Argument to function.
+ *
+ * If the specified task can be quickly locked into a definite state
+ * (either sleeping or on a given runqueue), arrange to keep it in that
+ * state while invoking @func(@arg).  This function can use ->on_rq and
+ * task_curr() to work out what the state is, if required.  Given that
+ * @func can be invoked with a runqueue lock held, it had better be quite
+ * lightweight.
+ *
+ * Returns:
+ *	@false if the task slipped out from under the locks.
+ *	@true if the task was locked onto a runqueue or is sleeping.
+ *		However, @func can override this by returning @false.
+ */
+bool try_invoke_on_locked_down_task(struct task_struct *p, bool (*func)(struct task_struct *t, void *arg), void *arg)
+{
+	bool ret = false;
+	struct rq_flags rf;
+	struct rq *rq;
+
+	lockdep_assert_irqs_enabled();
+	raw_spin_lock_irq(&p->pi_lock);
+	if (p->on_rq) {
+		rq = __task_rq_lock(p, &rf);
+		if (task_rq(p) == rq)
+			ret = func(p, arg);
+		rq_unlock(rq, &rf);
+	} else {
+		switch (p->state) {
+		case TASK_RUNNING:
+		case TASK_WAKING:
+			break;
+		default:
+			smp_rmb(); // See smp_rmb() comment in try_to_wake_up().
+			if (!p->on_rq)
+				ret = func(p, arg);
+		}
+	}
+	raw_spin_unlock_irq(&p->pi_lock);
+	return ret;
+}
+
 /**
  * wake_up_process - Wake up a specific process
  * @p: The process to be woken up.
diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c
index dac9104d126f..ff9435dee1df 100644
--- a/kernel/sched/cputime.c
+++ b/kernel/sched/cputime.c
@@ -1003,12 +1003,12 @@ u64 kcpustat_field(struct kernel_cpustat *kcpustat,
 		   enum cpu_usage_stat usage, int cpu)
 {
 	u64 *cpustat = kcpustat->cpustat;
+	u64 val = cpustat[usage];
 	struct rq *rq;
-	u64 val;
 	int err;
 
 	if (!vtime_accounting_enabled_cpu(cpu))
-		return cpustat[usage];
+		return val;
 
 	rq = cpu_rq(cpu);
 
diff --git a/kernel/sched/isolation.c b/kernel/sched/isolation.c
index 008d6ac2342b..808244f3ddd9 100644
--- a/kernel/sched/isolation.c
+++ b/kernel/sched/isolation.c
@@ -149,6 +149,9 @@ __setup("nohz_full=", housekeeping_nohz_full_setup);
 static int __init housekeeping_isolcpus_setup(char *str)
 {
 	unsigned int flags = 0;
+	bool illegal = false;
+	char *par;
+	int len;
 
 	while (isalpha(*str)) {
 		if (!strncmp(str, "nohz,", 5)) {
@@ -169,8 +172,22 @@ static int __init housekeeping_isolcpus_setup(char *str)
 			continue;
 		}
 
-		pr_warn("isolcpus: Error, unknown flag\n");
-		return 0;
+		/*
+		 * Skip unknown sub-parameter and validate that it is not
+		 * containing an invalid character.
+		 */
+		for (par = str, len = 0; *str && *str != ','; str++, len++) {
+			if (!isalpha(*str) && *str != '_')
+				illegal = true;
+		}
+
+		if (illegal) {
+			pr_warn("isolcpus: Invalid flag %.*s\n", len, par);
+			return 0;
+		}
+
+		pr_info("isolcpus: Skipped unknown flag %.*s\n", len, par);
+		str++;
 	}
 
 	/* Default behaviour for isolcpus without flags */
diff --git a/kernel/signal.c b/kernel/signal.c
index e58a6c619824..713104884414 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1510,15 +1510,15 @@ int kill_pid_usb_asyncio(int sig, int errno, sigval_t addr,
 	unsigned long flags;
 	int ret = -EINVAL;
 
+	if (!valid_signal(sig))
+		return ret;
+
 	clear_siginfo(&info);
 	info.si_signo = sig;
 	info.si_errno = errno;
 	info.si_code = SI_ASYNCIO;
 	*((sigval_t *)&info.si_pid) = addr;
 
-	if (!valid_signal(sig))
-		return ret;
-
 	rcu_read_lock();
 	p = pid_task(pid, PIDTYPE_PID);
 	if (!p) {
@@ -1557,12 +1557,8 @@ static int kill_something_info(int sig, struct kernel_siginfo *info, pid_t pid)
 {
 	int ret;
 
-	if (pid > 0) {
-		rcu_read_lock();
-		ret = kill_pid_info(sig, info, find_vpid(pid));
-		rcu_read_unlock();
-		return ret;
-	}
+	if (pid > 0)
+		return kill_proc_info(sig, info, pid);
 
 	/* -INT_MIN is undefined.  Exclude this case to avoid a UBSAN warning */
 	if (pid == INT_MIN)
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
index 3b69a560a7ac..6c7332776e8e 100644
--- a/kernel/sys_ni.c
+++ b/kernel/sys_ni.c
@@ -280,6 +280,7 @@ COND_SYSCALL(mlockall);
 COND_SYSCALL(munlockall);
 COND_SYSCALL(mincore);
 COND_SYSCALL(madvise);
+COND_SYSCALL(process_madvise);
 COND_SYSCALL(remap_file_pages);
 COND_SYSCALL(mbind);
 COND_SYSCALL_COMPAT(mbind);
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index 402eef84c859..ae69010d521a 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -158,6 +158,7 @@ config FUNCTION_TRACER
 	select CONTEXT_SWITCH_TRACER
 	select GLOB
 	select TASKS_RCU if PREEMPTION
+	select TASKS_RUDE_RCU
 	help
 	  Enable the kernel to trace every kernel function. This is done
 	  by using a compiler feature to insert a small, 5-byte No-Operation
diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile
index f9dcd19165fa..6b601d88bf71 100644
--- a/kernel/trace/Makefile
+++ b/kernel/trace/Makefile
@@ -6,6 +6,9 @@ ifdef CONFIG_FUNCTION_TRACER
 ORIG_CFLAGS := $(KBUILD_CFLAGS)
 KBUILD_CFLAGS = $(subst $(CC_FLAGS_FTRACE),,$(ORIG_CFLAGS))
 
+# Avoid recursion due to instrumentation.
+KCSAN_SANITIZE := n
+
 ifdef CONFIG_FTRACE_SELFTEST
 # selftest needs instrumentation
 CFLAGS_trace_selftest_dynamic.o = $(CC_FLAGS_FTRACE)
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 041694a1eb74..771eace959f3 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -160,17 +160,6 @@ static void ftrace_pid_func(unsigned long ip, unsigned long parent_ip,
 	op->saved_func(ip, parent_ip, op, regs);
 }
 
-static void ftrace_sync(struct work_struct *work)
-{
-	/*
-	 * This function is just a stub to implement a hard force
-	 * of synchronize_rcu(). This requires synchronizing
-	 * tasks even in userspace and idle.
-	 *
-	 * Yes, function tracing is rude.
-	 */
-}
-
 static void ftrace_sync_ipi(void *data)
 {
 	/* Probably not needed, but do it anyway */
@@ -256,7 +245,7 @@ static void update_ftrace_function(void)
 	 * Make sure all CPUs see this. Yes this is slow, but static
 	 * tracing is slow and nasty to have enabled.
 	 */
-	schedule_on_each_cpu(ftrace_sync);
+	synchronize_rcu_tasks_rude();
 	/* Now all cpus are using the list ops. */
 	function_trace_op = set_function_trace_op;
 	/* Make sure the function_trace_op is visible on all CPUs */
@@ -2932,7 +2921,7 @@ int ftrace_shutdown(struct ftrace_ops *ops, int command)
 		 * infrastructure to do the synchronization, thus we must do it
 		 * ourselves.
 		 */
-		schedule_on_each_cpu(ftrace_sync);
+		synchronize_rcu_tasks_rude();
 
 		/*
 		 * When the kernel is preeptive, tasks can be preempted
@@ -5887,7 +5876,7 @@ ftrace_graph_release(struct inode *inode, struct file *file)
 		 * infrastructure to do the synchronization, thus we must do it
 		 * ourselves.
 		 */
-		schedule_on_each_cpu(ftrace_sync);
+		synchronize_rcu_tasks_rude();
 
 		free_ftrace_hash(old_hash);
 	}
diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_events_trigger.c
index dd34a1b46a86..3a74736da363 100644
--- a/kernel/trace/trace_events_trigger.c
+++ b/kernel/trace/trace_events_trigger.c
@@ -1088,14 +1088,10 @@ register_snapshot_trigger(char *glob, struct event_trigger_ops *ops,
 			  struct event_trigger_data *data,
 			  struct trace_event_file *file)
 {
-	int ret = register_trigger(glob, ops, data, file);
-
-	if (ret > 0 && tracing_alloc_snapshot_instance(file->tr) != 0) {
-		unregister_trigger(glob, ops, data, file);
-		ret = 0;
-	}
+	if (tracing_alloc_snapshot_instance(file->tr) != 0)
+		return 0;
 
-	return ret;
+	return register_trigger(glob, ops, data, file);
 }
 
 static int
diff --git a/kernel/watch_queue.c b/kernel/watch_queue.c
new file mode 100644
index 000000000000..9a9699c06709
--- /dev/null
+++ b/kernel/watch_queue.c
@@ -0,0 +1,659 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Watch queue and general notification mechanism, built on pipes
+ *
+ * Copyright (C) 2020 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * See Documentation/watch_queue.rst
+ */
+
+#define pr_fmt(fmt) "watchq: " fmt
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/printk.h>
+#include <linux/miscdevice.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+#include <linux/poll.h>
+#include <linux/uaccess.h>
+#include <linux/vmalloc.h>
+#include <linux/file.h>
+#include <linux/security.h>
+#include <linux/cred.h>
+#include <linux/sched/signal.h>
+#include <linux/watch_queue.h>
+#include <linux/pipe_fs_i.h>
+
+MODULE_DESCRIPTION("Watch queue");
+MODULE_AUTHOR("Red Hat, Inc.");
+MODULE_LICENSE("GPL");
+
+#define WATCH_QUEUE_NOTE_SIZE 128
+#define WATCH_QUEUE_NOTES_PER_PAGE (PAGE_SIZE / WATCH_QUEUE_NOTE_SIZE)
+
+static void watch_queue_pipe_buf_release(struct pipe_inode_info *pipe,
+					 struct pipe_buffer *buf)
+{
+	struct watch_queue *wqueue = (struct watch_queue *)buf->private;
+	struct page *page;
+	unsigned int bit;
+
+	/* We need to work out which note within the page this refers to, but
+	 * the note might have been maximum size, so merely ANDing the offset
+	 * off doesn't work.  OTOH, the note must've been more than zero size.
+	 */
+	bit = buf->offset + buf->len;
+	if ((bit & (WATCH_QUEUE_NOTE_SIZE - 1)) == 0)
+		bit -= WATCH_QUEUE_NOTE_SIZE;
+	bit /= WATCH_QUEUE_NOTE_SIZE;
+
+	page = buf->page;
+	bit += page->index;
+
+	set_bit(bit, wqueue->notes_bitmap);
+}
+
+static int watch_queue_pipe_buf_steal(struct pipe_inode_info *pipe,
+				      struct pipe_buffer *buf)
+{
+	return -1; /* No. */
+}
+
+/* New data written to a pipe may be appended to a buffer with this type. */
+static const struct pipe_buf_operations watch_queue_pipe_buf_ops = {
+	.confirm	= generic_pipe_buf_confirm,
+	.release	= watch_queue_pipe_buf_release,
+	.steal		= watch_queue_pipe_buf_steal,
+	.get		= generic_pipe_buf_get,
+};
+
+/*
+ * Post a notification to a watch queue.
+ */
+static bool post_one_notification(struct watch_queue *wqueue,
+				  struct watch_notification *n)
+{
+	void *p;
+	struct pipe_inode_info *pipe = wqueue->pipe;
+	struct pipe_buffer *buf;
+	struct page *page;
+	unsigned int head, tail, mask, note, offset, len;
+	bool done = false;
+
+	if (!pipe)
+		return false;
+
+	spin_lock_irq(&pipe->rd_wait.lock);
+
+	if (wqueue->defunct)
+		goto out;
+
+	mask = pipe->ring_size - 1;
+	head = pipe->head;
+	tail = pipe->tail;
+	if (pipe_full(head, tail, pipe->ring_size))
+		goto lost;
+
+	note = find_first_bit(wqueue->notes_bitmap, wqueue->nr_notes);
+	if (note >= wqueue->nr_notes)
+		goto lost;
+
+	page = wqueue->notes[note / WATCH_QUEUE_NOTES_PER_PAGE];
+	offset = note % WATCH_QUEUE_NOTES_PER_PAGE * WATCH_QUEUE_NOTE_SIZE;
+	get_page(page);
+	len = n->info & WATCH_INFO_LENGTH;
+	p = kmap_atomic(page);
+	memcpy(p + offset, n, len);
+	kunmap_atomic(p);
+
+	buf = &pipe->bufs[head & mask];
+	buf->page = page;
+	buf->private = (unsigned long)wqueue;
+	buf->ops = &watch_queue_pipe_buf_ops;
+	buf->offset = offset;
+	buf->len = len;
+	buf->flags = PIPE_BUF_FLAG_WHOLE;
+	pipe->head = head + 1;
+
+	if (!test_and_clear_bit(note, wqueue->notes_bitmap)) {
+		spin_unlock_irq(&pipe->rd_wait.lock);
+		BUG();
+	}
+	wake_up_interruptible_sync_poll_locked(&pipe->rd_wait, EPOLLIN | EPOLLRDNORM);
+	done = true;
+
+out:
+	spin_unlock_irq(&pipe->rd_wait.lock);
+	if (done)
+		kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
+	return done;
+
+lost:
+	buf = &pipe->bufs[(head - 1) & mask];
+	buf->flags |= PIPE_BUF_FLAG_LOSS;
+	goto out;
+}
+
+/*
+ * Apply filter rules to a notification.
+ */
+static bool filter_watch_notification(const struct watch_filter *wf,
+				      const struct watch_notification *n)
+{
+	const struct watch_type_filter *wt;
+	unsigned int st_bits = sizeof(wt->subtype_filter[0]) * 8;
+	unsigned int st_index = n->subtype / st_bits;
+	unsigned int st_bit = 1U << (n->subtype % st_bits);
+	int i;
+
+	if (!test_bit(n->type, wf->type_filter))
+		return false;
+
+	for (i = 0; i < wf->nr_filters; i++) {
+		wt = &wf->filters[i];
+		if (n->type == wt->type &&
+		    (wt->subtype_filter[st_index] & st_bit) &&
+		    (n->info & wt->info_mask) == wt->info_filter)
+			return true;
+	}
+
+	return false; /* If there is a filter, the default is to reject. */
+}
+
+/**
+ * __post_watch_notification - Post an event notification
+ * @wlist: The watch list to post the event to.
+ * @n: The notification record to post.
+ * @cred: The creds of the process that triggered the notification.
+ * @id: The ID to match on the watch.
+ *
+ * Post a notification of an event into a set of watch queues and let the users
+ * know.
+ *
+ * The size of the notification should be set in n->info & WATCH_INFO_LENGTH and
+ * should be in units of sizeof(*n).
+ */
+void __post_watch_notification(struct watch_list *wlist,
+			       struct watch_notification *n,
+			       const struct cred *cred,
+			       u64 id)
+{
+	const struct watch_filter *wf;
+	struct watch_queue *wqueue;
+	struct watch *watch;
+
+	if (((n->info & WATCH_INFO_LENGTH) >> WATCH_INFO_LENGTH__SHIFT) == 0) {
+		WARN_ON(1);
+		return;
+	}
+
+	rcu_read_lock();
+
+	hlist_for_each_entry_rcu(watch, &wlist->watchers, list_node) {
+		if (watch->id != id)
+			continue;
+		n->info &= ~WATCH_INFO_ID;
+		n->info |= watch->info_id;
+
+		wqueue = rcu_dereference(watch->queue);
+		wf = rcu_dereference(wqueue->filter);
+		if (wf && !filter_watch_notification(wf, n))
+			continue;
+
+		if (security_post_notification(watch->cred, cred, n) < 0)
+			continue;
+
+		post_one_notification(wqueue, n);
+	}
+
+	rcu_read_unlock();
+}
+EXPORT_SYMBOL(__post_watch_notification);
+
+/*
+ * Allocate sufficient pages to preallocation for the requested number of
+ * notifications.
+ */
+long watch_queue_set_size(struct pipe_inode_info *pipe, unsigned int nr_notes)
+{
+	struct watch_queue *wqueue = pipe->watch_queue;
+	struct page **pages;
+	unsigned long *bitmap;
+	unsigned long user_bufs;
+	unsigned int bmsize;
+	int ret, i, nr_pages;
+
+	if (!wqueue)
+		return -ENODEV;
+	if (wqueue->notes)
+		return -EBUSY;
+
+	if (nr_notes < 1 ||
+	    nr_notes > 512) /* TODO: choose a better hard limit */
+		return -EINVAL;
+
+	nr_pages = (nr_notes + WATCH_QUEUE_NOTES_PER_PAGE - 1);
+	nr_pages /= WATCH_QUEUE_NOTES_PER_PAGE;
+	user_bufs = account_pipe_buffers(pipe->user, pipe->nr_accounted, nr_pages);
+
+	if (nr_pages > pipe->max_usage &&
+	    (too_many_pipe_buffers_hard(user_bufs) ||
+	     too_many_pipe_buffers_soft(user_bufs)) &&
+	    pipe_is_unprivileged_user()) {
+		ret = -EPERM;
+		goto error;
+	}
+
+	ret = pipe_resize_ring(pipe, nr_notes);
+	if (ret < 0)
+		goto error;
+
+	pages = kcalloc(sizeof(struct page *), nr_pages, GFP_KERNEL);
+	if (!pages)
+		goto error;
+
+	for (i = 0; i < nr_pages; i++) {
+		pages[i] = alloc_page(GFP_KERNEL);
+		if (!pages[i])
+			goto error_p;
+		pages[i]->index = i * WATCH_QUEUE_NOTES_PER_PAGE;
+	}
+
+	bmsize = (nr_notes + BITS_PER_LONG - 1) / BITS_PER_LONG;
+	bmsize *= sizeof(unsigned long);
+	bitmap = kmalloc(bmsize, GFP_KERNEL);
+	if (!bitmap)
+		goto error_p;
+
+	memset(bitmap, 0xff, bmsize);
+	wqueue->notes = pages;
+	wqueue->notes_bitmap = bitmap;
+	wqueue->nr_pages = nr_pages;
+	wqueue->nr_notes = nr_pages * WATCH_QUEUE_NOTES_PER_PAGE;
+	return 0;
+
+error_p:
+	for (i = 0; i < nr_pages; i++)
+		__free_page(pages[i]);
+	kfree(pages);
+error:
+	(void) account_pipe_buffers(pipe->user, nr_pages, pipe->nr_accounted);
+	return ret;
+}
+
+/*
+ * Set the filter on a watch queue.
+ */
+long watch_queue_set_filter(struct pipe_inode_info *pipe,
+			    struct watch_notification_filter __user *_filter)
+{
+	struct watch_notification_type_filter *tf;
+	struct watch_notification_filter filter;
+	struct watch_type_filter *q;
+	struct watch_filter *wfilter;
+	struct watch_queue *wqueue = pipe->watch_queue;
+	int ret, nr_filter = 0, i;
+
+	if (!wqueue)
+		return -ENODEV;
+
+	if (!_filter) {
+		/* Remove the old filter */
+		wfilter = NULL;
+		goto set;
+	}
+
+	/* Grab the user's filter specification */
+	if (copy_from_user(&filter, _filter, sizeof(filter)) != 0)
+		return -EFAULT;
+	if (filter.nr_filters == 0 ||
+	    filter.nr_filters > 16 ||
+	    filter.__reserved != 0)
+		return -EINVAL;
+
+	tf = memdup_user(_filter->filters, filter.nr_filters * sizeof(*tf));
+	if (IS_ERR(tf))
+		return PTR_ERR(tf);
+
+	ret = -EINVAL;
+	for (i = 0; i < filter.nr_filters; i++) {
+		if ((tf[i].info_filter & ~tf[i].info_mask) ||
+		    tf[i].info_mask & WATCH_INFO_LENGTH)
+			goto err_filter;
+		/* Ignore any unknown types */
+		if (tf[i].type >= sizeof(wfilter->type_filter) * 8)
+			continue;
+		nr_filter++;
+	}
+
+	/* Now we need to build the internal filter from only the relevant
+	 * user-specified filters.
+	 */
+	ret = -ENOMEM;
+	wfilter = kzalloc(struct_size(wfilter, filters, nr_filter), GFP_KERNEL);
+	if (!wfilter)
+		goto err_filter;
+	wfilter->nr_filters = nr_filter;
+
+	q = wfilter->filters;
+	for (i = 0; i < filter.nr_filters; i++) {
+		if (tf[i].type >= sizeof(wfilter->type_filter) * BITS_PER_LONG)
+			continue;
+
+		q->type			= tf[i].type;
+		q->info_filter		= tf[i].info_filter;
+		q->info_mask		= tf[i].info_mask;
+		q->subtype_filter[0]	= tf[i].subtype_filter[0];
+		__set_bit(q->type, wfilter->type_filter);
+		q++;
+	}
+
+	kfree(tf);
+set:
+	pipe_lock(pipe);
+	wfilter = rcu_replace_pointer(wqueue->filter, wfilter,
+				      lockdep_is_held(&pipe->mutex));
+	pipe_unlock(pipe);
+	if (wfilter)
+		kfree_rcu(wfilter, rcu);
+	return 0;
+
+err_filter:
+	kfree(tf);
+	return ret;
+}
+
+static void __put_watch_queue(struct kref *kref)
+{
+	struct watch_queue *wqueue =
+		container_of(kref, struct watch_queue, usage);
+	struct watch_filter *wfilter;
+	int i;
+
+	for (i = 0; i < wqueue->nr_pages; i++)
+		__free_page(wqueue->notes[i]);
+
+	wfilter = rcu_access_pointer(wqueue->filter);
+	if (wfilter)
+		kfree_rcu(wfilter, rcu);
+	kfree_rcu(wqueue, rcu);
+}
+
+/**
+ * put_watch_queue - Dispose of a ref on a watchqueue.
+ * @wqueue: The watch queue to unref.
+ */
+void put_watch_queue(struct watch_queue *wqueue)
+{
+	kref_put(&wqueue->usage, __put_watch_queue);
+}
+EXPORT_SYMBOL(put_watch_queue);
+
+static void free_watch(struct rcu_head *rcu)
+{
+	struct watch *watch = container_of(rcu, struct watch, rcu);
+
+	put_watch_queue(rcu_access_pointer(watch->queue));
+	put_cred(watch->cred);
+}
+
+static void __put_watch(struct kref *kref)
+{
+	struct watch *watch = container_of(kref, struct watch, usage);
+
+	call_rcu(&watch->rcu, free_watch);
+}
+
+/*
+ * Discard a watch.
+ */
+static void put_watch(struct watch *watch)
+{
+	kref_put(&watch->usage, __put_watch);
+}
+
+/**
+ * init_watch_queue - Initialise a watch
+ * @watch: The watch to initialise.
+ * @wqueue: The queue to assign.
+ *
+ * Initialise a watch and set the watch queue.
+ */
+void init_watch(struct watch *watch, struct watch_queue *wqueue)
+{
+	kref_init(&watch->usage);
+	INIT_HLIST_NODE(&watch->list_node);
+	INIT_HLIST_NODE(&watch->queue_node);
+	rcu_assign_pointer(watch->queue, wqueue);
+}
+
+/**
+ * add_watch_to_object - Add a watch on an object to a watch list
+ * @watch: The watch to add
+ * @wlist: The watch list to add to
+ *
+ * @watch->queue must have been set to point to the queue to post notifications
+ * to and the watch list of the object to be watched.  @watch->cred must also
+ * have been set to the appropriate credentials and a ref taken on them.
+ *
+ * The caller must pin the queue and the list both and must hold the list
+ * locked against racing watch additions/removals.
+ */
+int add_watch_to_object(struct watch *watch, struct watch_list *wlist)
+{
+	struct watch_queue *wqueue = rcu_access_pointer(watch->queue);
+	struct watch *w;
+
+	hlist_for_each_entry(w, &wlist->watchers, list_node) {
+		struct watch_queue *wq = rcu_access_pointer(w->queue);
+		if (wqueue == wq && watch->id == w->id)
+			return -EBUSY;
+	}
+
+	watch->cred = get_current_cred();
+	rcu_assign_pointer(watch->watch_list, wlist);
+
+	spin_lock_bh(&wqueue->lock);
+	kref_get(&wqueue->usage);
+	kref_get(&watch->usage);
+	hlist_add_head(&watch->queue_node, &wqueue->watches);
+	spin_unlock_bh(&wqueue->lock);
+
+	hlist_add_head(&watch->list_node, &wlist->watchers);
+	return 0;
+}
+EXPORT_SYMBOL(add_watch_to_object);
+
+/**
+ * remove_watch_from_object - Remove a watch or all watches from an object.
+ * @wlist: The watch list to remove from
+ * @wq: The watch queue of interest (ignored if @all is true)
+ * @id: The ID of the watch to remove (ignored if @all is true)
+ * @all: True to remove all objects
+ *
+ * Remove a specific watch or all watches from an object.  A notification is
+ * sent to the watcher to tell them that this happened.
+ */
+int remove_watch_from_object(struct watch_list *wlist, struct watch_queue *wq,
+			     u64 id, bool all)
+{
+	struct watch_notification_removal n;
+	struct watch_queue *wqueue;
+	struct watch *watch;
+	int ret = -EBADSLT;
+
+	rcu_read_lock();
+
+again:
+	spin_lock(&wlist->lock);
+	hlist_for_each_entry(watch, &wlist->watchers, list_node) {
+		if (all ||
+		    (watch->id == id && rcu_access_pointer(watch->queue) == wq))
+			goto found;
+	}
+	spin_unlock(&wlist->lock);
+	goto out;
+
+found:
+	ret = 0;
+	hlist_del_init_rcu(&watch->list_node);
+	rcu_assign_pointer(watch->watch_list, NULL);
+	spin_unlock(&wlist->lock);
+
+	/* We now own the reference on watch that used to belong to wlist. */
+
+	n.watch.type = WATCH_TYPE_META;
+	n.watch.subtype = WATCH_META_REMOVAL_NOTIFICATION;
+	n.watch.info = watch->info_id | watch_sizeof(n.watch);
+	n.id = id;
+	if (id != 0)
+		n.watch.info = watch->info_id | watch_sizeof(n);
+
+	wqueue = rcu_dereference(watch->queue);
+
+	/* We don't need the watch list lock for the next bit as RCU is
+	 * protecting *wqueue from deallocation.
+	 */
+	if (wqueue) {
+		post_one_notification(wqueue, &n.watch);
+
+		spin_lock_bh(&wqueue->lock);
+
+		if (!hlist_unhashed(&watch->queue_node)) {
+			hlist_del_init_rcu(&watch->queue_node);
+			put_watch(watch);
+		}
+
+		spin_unlock_bh(&wqueue->lock);
+	}
+
+	if (wlist->release_watch) {
+		void (*release_watch)(struct watch *);
+
+		release_watch = wlist->release_watch;
+		rcu_read_unlock();
+		(*release_watch)(watch);
+		rcu_read_lock();
+	}
+	put_watch(watch);
+
+	if (all && !hlist_empty(&wlist->watchers))
+		goto again;
+out:
+	rcu_read_unlock();
+	return ret;
+}
+EXPORT_SYMBOL(remove_watch_from_object);
+
+/*
+ * Remove all the watches that are contributory to a queue.  This has the
+ * potential to race with removal of the watches by the destruction of the
+ * objects being watched or with the distribution of notifications.
+ */
+void watch_queue_clear(struct watch_queue *wqueue)
+{
+	struct watch_list *wlist;
+	struct watch *watch;
+	bool release;
+
+	rcu_read_lock();
+	spin_lock_bh(&wqueue->lock);
+
+	/* Prevent new additions and prevent notifications from happening */
+	wqueue->defunct = true;
+
+	while (!hlist_empty(&wqueue->watches)) {
+		watch = hlist_entry(wqueue->watches.first, struct watch, queue_node);
+		hlist_del_init_rcu(&watch->queue_node);
+		/* We now own a ref on the watch. */
+		spin_unlock_bh(&wqueue->lock);
+
+		/* We can't do the next bit under the queue lock as we need to
+		 * get the list lock - which would cause a deadlock if someone
+		 * was removing from the opposite direction at the same time or
+		 * posting a notification.
+		 */
+		wlist = rcu_dereference(watch->watch_list);
+		if (wlist) {
+			void (*release_watch)(struct watch *);
+
+			spin_lock(&wlist->lock);
+
+			release = !hlist_unhashed(&watch->list_node);
+			if (release) {
+				hlist_del_init_rcu(&watch->list_node);
+				rcu_assign_pointer(watch->watch_list, NULL);
+
+				/* We now own a second ref on the watch. */
+			}
+
+			release_watch = wlist->release_watch;
+			spin_unlock(&wlist->lock);
+
+			if (release) {
+				if (release_watch) {
+					rcu_read_unlock();
+					/* This might need to call dput(), so
+					 * we have to drop all the locks.
+					 */
+					(*release_watch)(watch);
+					rcu_read_lock();
+				}
+				put_watch(watch);
+			}
+		}
+
+		put_watch(watch);
+		spin_lock_bh(&wqueue->lock);
+	}
+
+	spin_unlock_bh(&wqueue->lock);
+	rcu_read_unlock();
+}
+
+/**
+ * get_watch_queue - Get a watch queue from its file descriptor.
+ * @fd: The fd to query.
+ */
+struct watch_queue *get_watch_queue(int fd)
+{
+	struct pipe_inode_info *pipe;
+	struct watch_queue *wqueue = ERR_PTR(-EINVAL);
+	struct fd f;
+
+	f = fdget(fd);
+	if (f.file) {
+		pipe = get_pipe_info(f.file, false);
+		if (pipe && pipe->watch_queue) {
+			wqueue = pipe->watch_queue;
+			kref_get(&wqueue->usage);
+		}
+		fdput(f);
+	}
+
+	return wqueue;
+}
+EXPORT_SYMBOL(get_watch_queue);
+
+/*
+ * Initialise a watch queue
+ */
+int watch_queue_init(struct pipe_inode_info *pipe)
+{
+	struct watch_queue *wqueue;
+
+	wqueue = kzalloc(sizeof(*wqueue), GFP_KERNEL);
+	if (!wqueue)
+		return -ENOMEM;
+
+	wqueue->pipe = pipe;
+	kref_init(&wqueue->usage);
+	spin_lock_init(&wqueue->lock);
+	INIT_HLIST_HEAD(&wqueue->watches);
+
+	pipe->watch_queue = wqueue;
+	return 0;
+}
diff --git a/kernel/watchdog.c b/kernel/watchdog.c
index b6b1f54a7837..9f5c68fababe 100644
--- a/kernel/watchdog.c
+++ b/kernel/watchdog.c
@@ -92,6 +92,26 @@ static int __init hardlockup_all_cpu_backtrace_setup(char *str)
 }
 __setup("hardlockup_all_cpu_backtrace=", hardlockup_all_cpu_backtrace_setup);
 # endif /* CONFIG_SMP */
+
+atomic_t hardlockup_detected = ATOMIC_INIT(0);
+
+static inline void flush_hardlockup_messages(void)
+{
+	static atomic_t flushed = ATOMIC_INIT(0);
+
+	/* flush messages from hard lockup detector */
+	if (atomic_read(&hardlockup_detected) != atomic_read(&flushed)) {
+		atomic_set(&flushed, atomic_read(&hardlockup_detected));
+		printk_safe_flush();
+	}
+}
+
+#else /* CONFIG_HARDLOCKUP_DETECTOR */
+
+static inline void flush_hardlockup_messages(void)
+{
+}
+
 #endif /* CONFIG_HARDLOCKUP_DETECTOR */
 
 /*
@@ -370,6 +390,8 @@ static enum hrtimer_restart watchdog_timer_fn(struct hrtimer *hrtimer)
 	/* kick the hardlockup detector */
 	watchdog_interrupt_count();
 
+	flush_hardlockup_messages();
+
 	/* kick the softlockup detector */
 	if (completion_done(this_cpu_ptr(&softlockup_completion))) {
 		reinit_completion(this_cpu_ptr(&softlockup_completion));
diff --git a/kernel/watchdog_hld.c b/kernel/watchdog_hld.c
index 247bf0b1582c..a546bc54f6ff 100644
--- a/kernel/watchdog_hld.c
+++ b/kernel/watchdog_hld.c
@@ -154,6 +154,7 @@ static void watchdog_overflow_callback(struct perf_event *event,
 
 		if (hardlockup_panic)
 			nmi_panic(regs, "Hard LOCKUP");
+		atomic_inc(&hardlockup_detected);
 
 		__this_cpu_write(hard_watchdog_warn, true);
 		return;
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 50c1f5f08e6f..c61a04e569bd 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -242,6 +242,8 @@ config DEBUG_INFO_DWARF4
 config DEBUG_INFO_BTF
 	bool "Generate BTF typeinfo"
 	depends on DEBUG_INFO
+	depends on !DEBUG_INFO_SPLIT && !DEBUG_INFO_REDUCED
+	depends on !GCC_PLUGIN_RANDSTRUCT || COMPILE_TEST
 	help
 	  Generate deduplicated BTF type information from DWARF debug info.
 	  Turning this on expects presence of pahole tool, which will convert
@@ -651,6 +653,12 @@ config SCHED_STACK_END_CHECK
 	  data corruption or a sporadic crash at a later stage once the region
 	  is examined. The runtime overhead introduced is minimal.
 
+config ARCH_HAS_DEBUG_VM_PGTABLE
+	bool
+	help
+	  An architecture should select this when it can successfully
+	  build and run DEBUG_VM_PGTABLE.
+
 config DEBUG_VM
 	bool "Debug VM"
 	depends on DEBUG_KERNEL
@@ -686,6 +694,26 @@ config DEBUG_VM_PGFLAGS
 
 	  If unsure, say N.
 
+config DEBUG_VM_PGTABLE
+	bool "Debug arch page table for semantics compliance"
+	depends on MMU
+	depends on !IA64 && !ARM
+	depends on ARCH_HAS_DEBUG_VM_PGTABLE || EXPERT
+	default n if !ARCH_HAS_DEBUG_VM_PGTABLE
+	default y if DEBUG_VM
+	help
+	  This option provides a debug method which can be used to test
+	  architecture page table helper functions on various platforms in
+	  verifying if they comply with expected generic MM semantics. This
+	  will help architecture code in making sure that any changes or
+	  new additions of these helpers still conform to expected
+	  semantics of the generic MM. Platforms will have to opt in for
+	  this through ARCH_HAS_DEBUG_VM_PGTABLE. Although it can also be
+	  enabled through EXPERT without requiring code change. This test
+	  is disabled on IA64 and ARM platforms where it fails to build.
+
+	  If unsure, say N.
+
 config ARCH_HAS_DEBUG_VIRTUAL
 	bool
 
@@ -1512,6 +1540,8 @@ config PROVIDE_OHCI1394_DMA_INIT
 
 source "samples/Kconfig"
 
+source "lib/Kconfig.kcsan"
+
 config ARCH_HAS_DEVMEM_IS_ALLOWED
 	bool
 
@@ -1553,6 +1583,12 @@ config IO_STRICT_DEVMEM
 
 menu "$(SRCARCH) Debugging"
 
+config DEBUG_AID_FOR_SYZBOT
+       bool "Additional debug code for syzbot"
+       default n
+       help
+         This option is intended for testing by syzbot.
+
 source "arch/$(SRCARCH)/Kconfig.debug"
 
 endmenu
@@ -1767,6 +1803,15 @@ config KCOV_INSTRUMENT_ALL
 	  filesystem fuzzing with AFL) then you will want to enable coverage
 	  for more specific subsets of files, and should say n here.
 
+config KCOV_IRQ_AREA_SIZE
+	hex "Size of interrupt coverage collection area in words"
+	depends on KCOV
+	default 0x40000
+	help
+	  KCOV uses preallocated per-cpu areas to collect coverage from
+	  soft interrupts. This specifies the size of those areas in the
+	  number of unsigned long words.
+
 menuconfig RUNTIME_TESTING_MENU
 	bool "Runtime Testing"
 	def_bool y
diff --git a/lib/Kconfig.kcsan b/lib/Kconfig.kcsan
new file mode 100644
index 000000000000..689b6b81f272
--- /dev/null
+++ b/lib/Kconfig.kcsan
@@ -0,0 +1,181 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config HAVE_ARCH_KCSAN
+	bool
+
+menuconfig KCSAN
+	bool "KCSAN: dynamic data race detector"
+	depends on HAVE_ARCH_KCSAN && DEBUG_KERNEL && !KASAN
+	select STACKTRACE
+	help
+	  The Kernel Concurrency Sanitizer (KCSAN) is a dynamic
+	  data-race detector that relies on compile-time instrumentation.
+	  KCSAN uses a watchpoint-based sampling approach to detect races.
+
+	  While KCSAN's primary purpose is to detect data races, it
+	  also provides assertions to check data access constraints.
+	  These assertions can expose bugs that do not manifest as
+	  data races.
+
+	  See <file:Documentation/dev-tools/kcsan.rst> for more details.
+
+if KCSAN
+
+config KCSAN_VERBOSE
+	bool "Show verbose reports with more information about system state"
+	depends on PROVE_LOCKING
+	help
+	  If enabled, reports show more information about the system state that
+	  may help better analyze and debug races. This includes held locks and
+	  IRQ trace events.
+
+	  While this option should generally be benign, we call into more
+	  external functions on report generation; if a race report is
+	  generated from any one of them, system stability may suffer due to
+	  deadlocks or recursion.  If in doubt, say N.
+
+config KCSAN_DEBUG
+	bool "Debugging of KCSAN internals"
+
+config KCSAN_SELFTEST
+	bool "Perform short selftests on boot"
+	default y
+	help
+	  Run KCSAN selftests on boot. On test failure, causes the kernel to panic.
+
+config KCSAN_EARLY_ENABLE
+	bool "Early enable during boot"
+	default y
+	help
+	  If KCSAN should be enabled globally as soon as possible. KCSAN can
+	  later be enabled/disabled via debugfs.
+
+config KCSAN_NUM_WATCHPOINTS
+	int "Number of available watchpoints"
+	default 64
+	help
+	  Total number of available watchpoints. An address range maps into a
+	  specific watchpoint slot as specified in kernel/kcsan/encoding.h.
+	  Although larger number of watchpoints may not be usable due to
+	  limited number of CPUs, a larger value helps to improve performance
+	  due to reducing cache-line contention. The chosen default is a
+	  conservative value; we should almost never observe "no_capacity"
+	  events (see /sys/kernel/debug/kcsan).
+
+config KCSAN_UDELAY_TASK
+	int "Delay in microseconds (for tasks)"
+	default 80
+	help
+	  For tasks, the microsecond delay after setting up a watchpoint.
+
+config KCSAN_UDELAY_INTERRUPT
+	int "Delay in microseconds (for interrupts)"
+	default 20
+	help
+	  For interrupts, the microsecond delay after setting up a watchpoint.
+	  Interrupts have tighter latency requirements, and their delay should
+	  be lower than for tasks.
+
+config KCSAN_DELAY_RANDOMIZE
+	bool "Randomize above delays"
+	default y
+	help
+	  If delays should be randomized, where the maximum is KCSAN_UDELAY_*.
+	  If false, the chosen delays are always the KCSAN_UDELAY_* values
+	  as defined above.
+
+config KCSAN_SKIP_WATCH
+	int "Skip instructions before setting up watchpoint"
+	default 4000
+	help
+	  The number of per-CPU memory operations to skip, before another
+	  watchpoint is set up, i.e. one in KCSAN_WATCH_SKIP per-CPU
+	  memory operations are used to set up a watchpoint. A smaller value
+	  results in more aggressive race detection, whereas a larger value
+	  improves system performance at the cost of missing some races.
+
+config KCSAN_SKIP_WATCH_RANDOMIZE
+	bool "Randomize watchpoint instruction skip count"
+	default y
+	help
+	  If instruction skip count should be randomized, where the maximum is
+	  KCSAN_WATCH_SKIP. If false, the chosen value is always
+	  KCSAN_WATCH_SKIP.
+
+config KCSAN_INTERRUPT_WATCHER
+	bool "Interruptible watchers"
+	help
+	  If enabled, a task that set up a watchpoint may be interrupted while
+	  delayed. This option will allow KCSAN to detect races between
+	  interrupted tasks and other threads of execution on the same CPU.
+
+	  Currently disabled by default, because not all safe per-CPU access
+	  primitives and patterns may be accounted for, and therefore could
+	  result in false positives.
+
+config KCSAN_REPORT_ONCE_IN_MS
+	int "Duration in milliseconds, in which any given race is only reported once"
+	default 3000
+	help
+	  Any given race is only reported once in the defined time window.
+	  Different races may still generate reports within a duration that is
+	  smaller than the duration defined here. This allows rate limiting
+	  reporting to avoid flooding the console with reports.  Setting this
+	  to 0 disables rate limiting.
+
+# The main purpose of the below options is to control reported data races (e.g.
+# in fuzzer configs), and are not expected to be switched frequently by other
+# users. We could turn some of them into boot parameters, but given they should
+# not be switched normally, let's keep them here to simplify configuration.
+#
+# The defaults below are chosen to be very conservative, and may miss certain
+# bugs.
+
+config KCSAN_REPORT_RACE_UNKNOWN_ORIGIN
+	bool "Report races of unknown origin"
+	default y
+	help
+	  If KCSAN should report races where only one access is known, and the
+	  conflicting access is of unknown origin. This type of race is
+	  reported if it was only possible to infer a race due to a data value
+	  change while an access is being delayed on a watchpoint.
+
+config KCSAN_REPORT_VALUE_CHANGE_ONLY
+	bool "Only report races where watcher observed a data value change"
+	default y
+	help
+	  If enabled and a conflicting write is observed via a watchpoint, but
+	  the data value of the memory location was observed to remain
+	  unchanged, do not report the data race.
+
+config KCSAN_ASSUME_PLAIN_WRITES_ATOMIC
+	bool "Assume that plain aligned writes up to word size are atomic"
+	default y
+	help
+	  Assume that plain aligned writes up to word size are atomic by
+	  default, and also not subject to other unsafe compiler optimizations
+	  resulting in data races. This will cause KCSAN to not report data
+	  races due to conflicts where the only plain accesses are aligned
+	  writes up to word size: conflicts between marked reads and plain
+	  aligned writes up to word size will not be reported as data races;
+	  notice that data races between two conflicting plain aligned writes
+	  will also not be reported.
+
+config KCSAN_IGNORE_ATOMICS
+	bool "Do not instrument marked atomic accesses"
+	help
+	  Never instrument marked atomic accesses. This option can be used for
+	  additional filtering. Conflicting marked atomic reads and plain
+	  writes will never be reported as a data race, however, will cause
+	  plain reads and marked writes to result in "unknown origin" reports.
+	  If combined with CONFIG_KCSAN_REPORT_RACE_UNKNOWN_ORIGIN=n, data
+	  races where at least one access is marked atomic will never be
+	  reported.
+
+	  Similar to KCSAN_ASSUME_PLAIN_WRITES_ATOMIC, but including unaligned
+	  accesses, conflicting marked atomic reads and plain writes will not
+	  be reported as data races; however, unlike that option, data races
+	  due to two conflicting plain writes will be reported (aligned and
+	  unaligned, if CONFIG_KCSAN_ASSUME_PLAIN_WRITES_ATOMIC=n).
+
+endif # KCSAN
diff --git a/lib/Makefile b/lib/Makefile
index 685aee60de1d..ab68a8674360 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -25,6 +25,9 @@ KASAN_SANITIZE_string.o := n
 CFLAGS_string.o := $(call cc-option, -fno-stack-protector)
 endif
 
+# Used by KCSAN while enabled, avoid recursion.
+KCSAN_SANITIZE_random32.o := n
+
 lib-y := ctype.o string.o vsprintf.o cmdline.o \
 	 rbtree.o radix-tree.o timerqueue.o xarray.o \
 	 idr.o extable.o sha1.o irq_regs.o argv_split.o \
@@ -292,6 +295,7 @@ endif
 
 UBSAN_SANITIZE_ubsan.o := n
 KASAN_SANITIZE_ubsan.o := n
+KCSAN_SANITIZE_ubsan.o := n
 CFLAGS_ubsan.o := $(call cc-option, -fno-stack-protector) $(DISABLE_STACKLEAK_PLUGIN)
 
 obj-$(CONFIG_SBITMAP) += sbitmap.o
diff --git a/lib/cpumask.c b/lib/cpumask.c
index fb22fb266f93..2fecbcd8c160 100644
--- a/lib/cpumask.c
+++ b/lib/cpumask.c
@@ -6,6 +6,7 @@
 #include <linux/export.h>
 #include <linux/memblock.h>
 #include <linux/numa.h>
+#include <linux/spinlock.h>
 
 /**
  * cpumask_next - get the next cpu in a cpumask
@@ -192,18 +193,39 @@ void __init free_bootmem_cpumask_var(cpumask_var_t mask)
 }
 #endif
 
-/**
- * cpumask_local_spread - select the i'th cpu with local numa cpu's first
- * @i: index number
- * @node: local numa_node
- *
- * This function selects an online CPU according to a numa aware policy;
- * local cpus are returned first, followed by non-local ones, then it
- * wraps around.
- *
- * It's not very efficient, but useful for setup.
- */
-unsigned int cpumask_local_spread(unsigned int i, int node)
+static void calc_node_distance(int *node_dist, int node)
+{
+	int i;
+
+	for (i = 0; i < nr_node_ids; i++)
+		node_dist[i] = node_distance(node, i);
+}
+
+static int find_nearest_node(int *node_dist, bool *used)
+{
+	int i, min_dist = node_dist[0], node_id = -1;
+
+	/* Choose the first unused node to compare */
+	for (i = 0; i < nr_node_ids; i++) {
+		if (used[i] == 0) {
+			min_dist = node_dist[i];
+			node_id = i;
+			break;
+		}
+	}
+
+	/* Compare and return the nearest node */
+	for (i = 0; i < nr_node_ids; i++) {
+		if (node_dist[i] < min_dist && used[i] == 0) {
+			min_dist = node_dist[i];
+			node_id = i;
+		}
+	}
+
+	return node_id;
+}
+
+static unsigned int __cpumask_local_spread(unsigned int i, int node)
 {
 	int cpu;
 
@@ -231,6 +253,62 @@ unsigned int cpumask_local_spread(unsigned int i, int node)
 	}
 	BUG();
 }
+
+/**
+ * cpumask_local_spread - select the i'th cpu with local numa cpu's first
+ * @i: index number
+ * @node: local numa_node
+ *
+ * This function selects an online CPU according to a numa aware policy;
+ * local cpus are returned first, followed by the nearest non-local ones,
+ * then it wraps around.
+ *
+ * It's not very efficient, but useful for setup.
+ */
+unsigned int cpumask_local_spread(unsigned int i, int node)
+{
+	static DEFINE_SPINLOCK(spread_lock);
+	static int node_dist[MAX_NUMNODES];
+	static bool used[MAX_NUMNODES];
+	unsigned long flags;
+	int cpu, j, id;
+
+	/* Wrap: we always want a cpu. */
+	i %= num_online_cpus();
+
+	if (node == NUMA_NO_NODE) {
+		for_each_cpu(cpu, cpu_online_mask)
+			if (i-- == 0)
+				return cpu;
+	} else {
+		if (nr_node_ids > MAX_NUMNODES)
+			return __cpumask_local_spread(i, node);
+
+		spin_lock_irqsave(&spread_lock, flags);
+		memset(used, 0, nr_node_ids * sizeof(bool));
+		calc_node_distance(node_dist, node);
+		for (j = 0; j < nr_node_ids; j++) {
+			id = find_nearest_node(node_dist, used);
+			if (id < 0)
+				break;
+
+			for_each_cpu_and(cpu, cpumask_of_node(id),
+					 cpu_online_mask)
+				if (i-- == 0) {
+					spin_unlock_irqrestore(&spread_lock,
+							       flags);
+					return cpu;
+				}
+			used[id] = 1;
+		}
+		spin_unlock_irqrestore(&spread_lock, flags);
+
+		for_each_cpu(cpu, cpu_online_mask)
+			if (i-- == 0)
+				return cpu;
+	}
+	BUG();
+}
 EXPORT_SYMBOL(cpumask_local_spread);
 
 static DEFINE_PER_CPU(int, distribute_cpu_mask_prev);
diff --git a/lib/idr.c b/lib/idr.c
index c2cf2c52bbde..4d2eef0259d2 100644
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -470,6 +470,7 @@ int ida_alloc_range(struct ida *ida, unsigned int min, unsigned int max,
 	goto retry;
 nospc:
 	xas_unlock_irqrestore(&xas, flags);
+	kfree(alloc);
 	return -ENOSPC;
 }
 EXPORT_SYMBOL(ida_alloc_range);
diff --git a/lib/iov_iter.c b/lib/iov_iter.c
index 51595bf3af85..bf538c2bec77 100644
--- a/lib/iov_iter.c
+++ b/lib/iov_iter.c
@@ -8,6 +8,7 @@
 #include <linux/splice.h>
 #include <net/checksum.h>
 #include <linux/scatterlist.h>
+#include <linux/instrumented.h>
 
 #define PIPE_PARANOIA /* for now */
 
@@ -138,7 +139,7 @@
 static int copyout(void __user *to, const void *from, size_t n)
 {
 	if (access_ok(to, n)) {
-		kasan_check_read(from, n);
+		instrument_copy_to_user(to, from, n);
 		n = raw_copy_to_user(to, from, n);
 	}
 	return n;
@@ -147,7 +148,7 @@ static int copyout(void __user *to, const void *from, size_t n)
 static int copyin(void *to, const void __user *from, size_t n)
 {
 	if (access_ok(from, n)) {
-		kasan_check_write(to, n);
+		instrument_copy_from_user(to, from, n);
 		n = raw_copy_from_user(to, from, n);
 	}
 	return n;
@@ -639,7 +640,7 @@ EXPORT_SYMBOL(_copy_to_iter);
 static int copyout_mcsafe(void __user *to, const void *from, size_t n)
 {
 	if (access_ok(to, n)) {
-		kasan_check_read(from, n);
+		instrument_copy_to_user(to, from, n);
 		n = copy_to_user_mcsafe((__force void *) to, from, n);
 	}
 	return n;
diff --git a/lib/test_xarray.c b/lib/test_xarray.c
index d4f97925dbd8..a3910d59f790 100644
--- a/lib/test_xarray.c
+++ b/lib/test_xarray.c
@@ -393,6 +393,9 @@ static noinline void check_cmpxchg(struct xarray *xa)
 	XA_BUG_ON(xa, xa_cmpxchg(xa, 12345678, FIVE, LOTS, GFP_KERNEL) != FIVE);
 	XA_BUG_ON(xa, xa_cmpxchg(xa, 5, FIVE, NULL, GFP_KERNEL) != NULL);
 	XA_BUG_ON(xa, xa_cmpxchg(xa, 5, NULL, FIVE, GFP_KERNEL) != NULL);
+	XA_BUG_ON(xa, xa_insert(xa, 5, FIVE, GFP_KERNEL) != -EBUSY);
+	XA_BUG_ON(xa, xa_cmpxchg(xa, 5, FIVE, NULL, GFP_KERNEL) != FIVE);
+	XA_BUG_ON(xa, xa_insert(xa, 5, FIVE, GFP_KERNEL) == -EBUSY);
 	xa_erase_index(xa, 12345678);
 	xa_erase_index(xa, 5);
 	XA_BUG_ON(xa, !xa_empty(xa));
@@ -567,6 +570,20 @@ static noinline void check_multi_store_3(struct xarray *xa, unsigned long index,
 
 	xa_destroy(xa);
 }
+
+static noinline void check_multi_store_4(struct xarray *xa)
+{
+	XA_BUG_ON(xa, xa_marked(xa, XA_MARK_0));
+
+	xa_store_index(xa, 0, GFP_KERNEL);
+	xa_store_index(xa, 2, GFP_KERNEL);
+	xa_set_mark(xa, 0, XA_MARK_0);
+	xa_set_mark(xa, 2, XA_MARK_0);
+
+	xa_store_order(xa, 0, 2, NULL, GFP_KERNEL);
+	XA_BUG_ON(xa, xa_marked(xa, XA_MARK_0));
+	xa_destroy(xa);
+}
 #endif
 
 static noinline void check_multi_store(struct xarray *xa)
@@ -646,6 +663,9 @@ static noinline void check_multi_store(struct xarray *xa)
 		check_multi_store_3(xa, 0, i);
 		check_multi_store_3(xa, 1UL << i, i);
 	}
+	check_multi_store_4(xa);
+	xa_store_index(xa, 1000, GFP_KERNEL);
+	check_multi_store_4(xa);
 #endif
 }
 
diff --git a/lib/usercopy.c b/lib/usercopy.c
index cbb4d9ec00f2..4bb1c5e7a3eb 100644
--- a/lib/usercopy.c
+++ b/lib/usercopy.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
-#include <linux/uaccess.h>
 #include <linux/bitops.h>
+#include <linux/instrumented.h>
+#include <linux/uaccess.h>
 
 /* out-of-line parts */
 
@@ -10,7 +11,7 @@ unsigned long _copy_from_user(void *to, const void __user *from, unsigned long n
 	unsigned long res = n;
 	might_fault();
 	if (likely(access_ok(from, n))) {
-		kasan_check_write(to, n);
+		instrument_copy_from_user(to, from, n);
 		res = raw_copy_from_user(to, from, n);
 	}
 	if (unlikely(res))
@@ -25,7 +26,7 @@ unsigned long _copy_to_user(void __user *to, const void *from, unsigned long n)
 {
 	might_fault();
 	if (likely(access_ok(to, n))) {
-		kasan_check_read(from, n);
+		instrument_copy_to_user(to, from, n);
 		n = raw_copy_to_user(to, from, n);
 	}
 	return n;
diff --git a/lib/xarray.c b/lib/xarray.c
index e9e641d3c0c3..a75336666051 100644
--- a/lib/xarray.c
+++ b/lib/xarray.c
@@ -492,7 +492,6 @@ static void xas_delete_node(struct xa_state *xas)
 
 		if (!parent) {
 			xas->xa->xa_head = NULL;
-			xas->xa_node = XAS_BOUNDS;
 			return;
 		}
 
@@ -754,7 +753,7 @@ static void update_node(struct xa_state *xas, struct xa_node *node,
 }
 
 /**
- * xas_store() - Store this entry in the XArray.
+ * __xas_store() - Store this entry in the XArray without affecting the marks.
  * @xas: XArray operation state.
  * @entry: New entry.
  *
@@ -766,7 +765,7 @@ static void update_node(struct xa_state *xas, struct xa_node *node,
  *
  * Return: The old entry at this index.
  */
-void *xas_store(struct xa_state *xas, void *entry)
+void *__xas_store(struct xa_state *xas, void *entry)
 {
 	struct xa_node *node;
 	void __rcu **slot = &xas->xa->xa_head;
@@ -799,8 +798,6 @@ void *xas_store(struct xa_state *xas, void *entry)
 		if (xas->xa_sibs)
 			xas_squash_marks(xas);
 	}
-	if (!entry)
-		xas_init_marks(xas);
 
 	for (;;) {
 		/*
@@ -838,6 +835,29 @@ void *xas_store(struct xa_state *xas, void *entry)
 	update_node(xas, node, count, values);
 	return first;
 }
+EXPORT_SYMBOL_GPL(__xas_store);
+
+/**
+ * xas_store() - Store this entry in the XArray.
+ * @xas: XArray operation state.
+ * @entry: New entry.
+ *
+ * If @xas is operating on a multi-index entry, the entry returned by this
+ * function is essentially meaningless (it may be an internal entry or it
+ * may be %NULL, even if there are non-NULL entries at some of the indices
+ * covered by the range).  This is not a problem for any current users,
+ * and can be changed if needed.
+ *
+ * Return: The old entry at this index.
+ */
+void *xas_store(struct xa_state *xas, void *entry)
+{
+	void *curr = __xas_store(xas, entry);
+
+	if (!entry)
+		xas_init_marks(xas);
+	return curr;
+}
 EXPORT_SYMBOL_GPL(xas_store);
 
 /**
@@ -1162,6 +1182,7 @@ void *xas_find_marked(struct xa_state *xas, unsigned long max, xa_mark_t mark)
 		xas->xa_index = 1;
 		goto out;
 	} else if (xas_top(xas->xa_node)) {
+restart:
 		advance = false;
 		entry = xa_head(xas->xa);
 		xas->xa_node = NULL;
@@ -1208,8 +1229,14 @@ void *xas_find_marked(struct xa_state *xas, unsigned long max, xa_mark_t mark)
 		}
 
 		entry = xa_entry(xas->xa, xas->xa_node, xas->xa_offset);
-		if (!entry && !(xa_track_free(xas->xa) && mark == XA_FREE_MARK))
+		if (unlikely(!entry &&
+			     !(xa_track_free(xas->xa) &&
+			       mark == XA_FREE_MARK))) {
+			xas_advance(xas);
 			continue;
+		}
+		if (xa_is_retry(entry))
+			goto restart;
 		if (!xa_is_node(entry))
 			return entry;
 		xas->xa_node = xa_to_node(entry);
diff --git a/localversion-next b/localversion-next
new file mode 100644
index 000000000000..f4fae9d8a3dc
--- /dev/null
+++ b/localversion-next
@@ -0,0 +1 @@
+-next-20200417
diff --git a/mm/Makefile b/mm/Makefile
index fccd3756b25f..fa91e963c2f9 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -8,6 +8,14 @@ KASAN_SANITIZE_slab.o := n
 KASAN_SANITIZE_slub.o := n
 KCSAN_SANITIZE_kmemleak.o := n
 
+# These produce frequent data race reports: most of them are due to races on
+# the same word but accesses to different bits of that word. Re-enable KCSAN
+# for these when we have more consensus on what to do about them.
+KCSAN_SANITIZE_slab_common.o := n
+KCSAN_SANITIZE_slab.o := n
+KCSAN_SANITIZE_slub.o := n
+KCSAN_SANITIZE_page_alloc.o := n
+
 # These files are disabled because they produce non-interesting and/or
 # flaky coverage that is not a function of syscall inputs. E.g. slab is out of
 # free pages, or a task is migrated between nodes.
@@ -88,6 +96,7 @@ obj-$(CONFIG_HWPOISON_INJECT) += hwpoison-inject.o
 obj-$(CONFIG_DEBUG_KMEMLEAK) += kmemleak.o
 obj-$(CONFIG_DEBUG_KMEMLEAK_TEST) += kmemleak-test.o
 obj-$(CONFIG_DEBUG_RODATA_TEST) += rodata_test.o
+obj-$(CONFIG_DEBUG_VM_PGTABLE) += debug_vm_pgtable.o
 obj-$(CONFIG_PAGE_OWNER) += page_owner.o
 obj-$(CONFIG_CLEANCACHE) += cleancache.o
 obj-$(CONFIG_MEMORY_ISOLATION) += page_isolation.o
diff --git a/mm/debug_vm_pgtable.c b/mm/debug_vm_pgtable.c
new file mode 100644
index 000000000000..98990a515268
--- /dev/null
+++ b/mm/debug_vm_pgtable.c
@@ -0,0 +1,392 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * This kernel test validates architecture page table helpers and
+ * accessors and helps in verifying their continued compliance with
+ * expected generic MM semantics.
+ *
+ * Copyright (C) 2019 ARM Ltd.
+ *
+ * Author: Anshuman Khandual <anshuman.khandual@arm.com>
+ */
+#define pr_fmt(fmt) "debug_vm_pgtable: %s: " fmt, __func__
+
+#include <linux/gfp.h>
+#include <linux/highmem.h>
+#include <linux/hugetlb.h>
+#include <linux/kernel.h>
+#include <linux/kconfig.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/mm_types.h>
+#include <linux/module.h>
+#include <linux/pfn_t.h>
+#include <linux/printk.h>
+#include <linux/random.h>
+#include <linux/spinlock.h>
+#include <linux/swap.h>
+#include <linux/swapops.h>
+#include <linux/start_kernel.h>
+#include <linux/sched/mm.h>
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
+
+/*
+ * Basic operations
+ *
+ * mkold(entry)			= An old and not a young entry
+ * mkyoung(entry)		= A young and not an old entry
+ * mkdirty(entry)		= A dirty and not a clean entry
+ * mkclean(entry)		= A clean and not a dirty entry
+ * mkwrite(entry)		= A write and not a write protected entry
+ * wrprotect(entry)		= A write protected and not a write entry
+ * pxx_bad(entry)		= A mapped and non-table entry
+ * pxx_same(entry1, entry2)	= Both entries hold the exact same value
+ */
+#define VMFLAGS	(VM_READ|VM_WRITE|VM_EXEC)
+
+/*
+ * On s390 platform, the lower 4 bits are used to identify given page table
+ * entry type. But these bits might affect the ability to clear entries with
+ * pxx_clear() because of how dynamic page table folding works on s390. So
+ * while loading up the entries do not change the lower 4 bits. It does not
+ * have affect any other platform.
+ */
+#define S390_MASK_BITS	4
+#define RANDOM_ORVALUE	GENMASK(BITS_PER_LONG - 1, S390_MASK_BITS)
+#define RANDOM_NZVALUE	GENMASK(7, 0)
+
+static void __init pte_basic_tests(unsigned long pfn, pgprot_t prot)
+{
+	pte_t pte = pfn_pte(pfn, prot);
+
+	WARN_ON(!pte_same(pte, pte));
+	WARN_ON(!pte_young(pte_mkyoung(pte_mkold(pte))));
+	WARN_ON(!pte_dirty(pte_mkdirty(pte_mkclean(pte))));
+	WARN_ON(!pte_write(pte_mkwrite(pte_wrprotect(pte))));
+	WARN_ON(pte_young(pte_mkold(pte_mkyoung(pte))));
+	WARN_ON(pte_dirty(pte_mkclean(pte_mkdirty(pte))));
+	WARN_ON(pte_write(pte_wrprotect(pte_mkwrite(pte))));
+}
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+static void __init pmd_basic_tests(unsigned long pfn, pgprot_t prot)
+{
+	pmd_t pmd = pfn_pmd(pfn, prot);
+
+	WARN_ON(!pmd_same(pmd, pmd));
+	WARN_ON(!pmd_young(pmd_mkyoung(pmd_mkold(pmd))));
+	WARN_ON(!pmd_dirty(pmd_mkdirty(pmd_mkclean(pmd))));
+	WARN_ON(!pmd_write(pmd_mkwrite(pmd_wrprotect(pmd))));
+	WARN_ON(pmd_young(pmd_mkold(pmd_mkyoung(pmd))));
+	WARN_ON(pmd_dirty(pmd_mkclean(pmd_mkdirty(pmd))));
+	WARN_ON(pmd_write(pmd_wrprotect(pmd_mkwrite(pmd))));
+	/*
+	 * A huge page does not point to next level page table
+	 * entry. Hence this must qualify as pmd_bad().
+	 */
+	WARN_ON(!pmd_bad(pmd_mkhuge(pmd)));
+}
+
+#ifdef CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD
+static void __init pud_basic_tests(unsigned long pfn, pgprot_t prot)
+{
+	pud_t pud = pfn_pud(pfn, prot);
+
+	WARN_ON(!pud_same(pud, pud));
+	WARN_ON(!pud_young(pud_mkyoung(pud_mkold(pud))));
+	WARN_ON(!pud_write(pud_mkwrite(pud_wrprotect(pud))));
+	WARN_ON(pud_write(pud_wrprotect(pud_mkwrite(pud))));
+	WARN_ON(pud_young(pud_mkold(pud_mkyoung(pud))));
+
+	if (mm_pmd_folded(mm))
+		return;
+
+	/*
+	 * A huge page does not point to next level page table
+	 * entry. Hence this must qualify as pud_bad().
+	 */
+	WARN_ON(!pud_bad(pud_mkhuge(pud)));
+}
+#else
+static void __init pud_basic_tests(unsigned long pfn, pgprot_t prot) { }
+#endif
+#else
+static void __init pmd_basic_tests(unsigned long pfn, pgprot_t prot) { }
+static void __init pud_basic_tests(unsigned long pfn, pgprot_t prot) { }
+#endif
+
+static void __init p4d_basic_tests(unsigned long pfn, pgprot_t prot)
+{
+	p4d_t p4d;
+
+	memset(&p4d, RANDOM_NZVALUE, sizeof(p4d_t));
+	WARN_ON(!p4d_same(p4d, p4d));
+}
+
+static void __init pgd_basic_tests(unsigned long pfn, pgprot_t prot)
+{
+	pgd_t pgd;
+
+	memset(&pgd, RANDOM_NZVALUE, sizeof(pgd_t));
+	WARN_ON(!pgd_same(pgd, pgd));
+}
+
+#ifndef __PAGETABLE_PUD_FOLDED
+static void __init pud_clear_tests(struct mm_struct *mm, pud_t *pudp)
+{
+	pud_t pud = READ_ONCE(*pudp);
+
+	if (mm_pmd_folded(mm))
+		return;
+
+	pud = __pud(pud_val(pud) | RANDOM_ORVALUE);
+	WRITE_ONCE(*pudp, pud);
+	pud_clear(pudp);
+	pud = READ_ONCE(*pudp);
+	WARN_ON(!pud_none(pud));
+}
+
+static void __init pud_populate_tests(struct mm_struct *mm, pud_t *pudp,
+				      pmd_t *pmdp)
+{
+	pud_t pud;
+
+	if (mm_pmd_folded(mm))
+		return;
+	/*
+	 * This entry points to next level page table page.
+	 * Hence this must not qualify as pud_bad().
+	 */
+	pmd_clear(pmdp);
+	pud_clear(pudp);
+	pud_populate(mm, pudp, pmdp);
+	pud = READ_ONCE(*pudp);
+	WARN_ON(pud_bad(pud));
+}
+#else
+static void __init pud_clear_tests(struct mm_struct *mm, pud_t *pudp) { }
+static void __init pud_populate_tests(struct mm_struct *mm, pud_t *pudp,
+				      pmd_t *pmdp)
+{
+}
+#endif
+
+#ifndef __PAGETABLE_P4D_FOLDED
+static void __init p4d_clear_tests(struct mm_struct *mm, p4d_t *p4dp)
+{
+	p4d_t p4d = READ_ONCE(*p4dp);
+
+	if (mm_pud_folded(mm))
+		return;
+
+	p4d = __p4d(p4d_val(p4d) | RANDOM_ORVALUE);
+	WRITE_ONCE(*p4dp, p4d);
+	p4d_clear(p4dp);
+	p4d = READ_ONCE(*p4dp);
+	WARN_ON(!p4d_none(p4d));
+}
+
+static void __init p4d_populate_tests(struct mm_struct *mm, p4d_t *p4dp,
+				      pud_t *pudp)
+{
+	p4d_t p4d;
+
+	if (mm_pud_folded(mm))
+		return;
+
+	/*
+	 * This entry points to next level page table page.
+	 * Hence this must not qualify as p4d_bad().
+	 */
+	pud_clear(pudp);
+	p4d_clear(p4dp);
+	p4d_populate(mm, p4dp, pudp);
+	p4d = READ_ONCE(*p4dp);
+	WARN_ON(p4d_bad(p4d));
+}
+
+static void __init pgd_clear_tests(struct mm_struct *mm, pgd_t *pgdp)
+{
+	pgd_t pgd = READ_ONCE(*pgdp);
+
+	if (mm_p4d_folded(mm))
+		return;
+
+	pgd = __pgd(pgd_val(pgd) | RANDOM_ORVALUE);
+	WRITE_ONCE(*pgdp, pgd);
+	pgd_clear(pgdp);
+	pgd = READ_ONCE(*pgdp);
+	WARN_ON(!pgd_none(pgd));
+}
+
+static void __init pgd_populate_tests(struct mm_struct *mm, pgd_t *pgdp,
+				      p4d_t *p4dp)
+{
+	pgd_t pgd;
+
+	if (mm_p4d_folded(mm))
+		return;
+
+	/*
+	 * This entry points to next level page table page.
+	 * Hence this must not qualify as pgd_bad().
+	 */
+	p4d_clear(p4dp);
+	pgd_clear(pgdp);
+	pgd_populate(mm, pgdp, p4dp);
+	pgd = READ_ONCE(*pgdp);
+	WARN_ON(pgd_bad(pgd));
+}
+#else
+static void __init p4d_clear_tests(struct mm_struct *mm, p4d_t *p4dp) { }
+static void __init pgd_clear_tests(struct mm_struct *mm, pgd_t *pgdp) { }
+static void __init p4d_populate_tests(struct mm_struct *mm, p4d_t *p4dp,
+				      pud_t *pudp)
+{
+}
+static void __init pgd_populate_tests(struct mm_struct *mm, pgd_t *pgdp,
+				      p4d_t *p4dp)
+{
+}
+#endif
+
+static void __init pte_clear_tests(struct mm_struct *mm, pte_t *ptep,
+				   unsigned long vaddr)
+{
+	pte_t pte = READ_ONCE(*ptep);
+
+	pte = __pte(pte_val(pte) | RANDOM_ORVALUE);
+	set_pte_at(mm, vaddr, ptep, pte);
+	barrier();
+	pte_clear(mm, vaddr, ptep);
+	pte = READ_ONCE(*ptep);
+	WARN_ON(!pte_none(pte));
+}
+
+static void __init pmd_clear_tests(struct mm_struct *mm, pmd_t *pmdp)
+{
+	pmd_t pmd = READ_ONCE(*pmdp);
+
+	pmd = __pmd(pmd_val(pmd) | RANDOM_ORVALUE);
+	WRITE_ONCE(*pmdp, pmd);
+	pmd_clear(pmdp);
+	pmd = READ_ONCE(*pmdp);
+	WARN_ON(!pmd_none(pmd));
+}
+
+static void __init pmd_populate_tests(struct mm_struct *mm, pmd_t *pmdp,
+				      pgtable_t pgtable)
+{
+	pmd_t pmd;
+
+	/*
+	 * This entry points to next level page table page.
+	 * Hence this must not qualify as pmd_bad().
+	 */
+	pmd_clear(pmdp);
+	pmd_populate(mm, pmdp, pgtable);
+	pmd = READ_ONCE(*pmdp);
+	WARN_ON(pmd_bad(pmd));
+}
+
+static unsigned long __init get_random_vaddr(void)
+{
+	unsigned long random_vaddr, random_pages, total_user_pages;
+
+	total_user_pages = (TASK_SIZE - FIRST_USER_ADDRESS) / PAGE_SIZE;
+
+	random_pages = get_random_long() % total_user_pages;
+	random_vaddr = FIRST_USER_ADDRESS + random_pages * PAGE_SIZE;
+
+	return random_vaddr;
+}
+
+void __init debug_vm_pgtable(void)
+{
+	struct mm_struct *mm;
+	pgd_t *pgdp;
+	p4d_t *p4dp, *saved_p4dp;
+	pud_t *pudp, *saved_pudp;
+	pmd_t *pmdp, *saved_pmdp, pmd;
+	pte_t *ptep;
+	pgtable_t saved_ptep;
+	pgprot_t prot;
+	phys_addr_t paddr;
+	unsigned long vaddr, pte_aligned, pmd_aligned;
+	unsigned long pud_aligned, p4d_aligned, pgd_aligned;
+	spinlock_t *uninitialized_var(ptl);
+
+	pr_info("Validating architecture page table helpers\n");
+	prot = vm_get_page_prot(VMFLAGS);
+	vaddr = get_random_vaddr();
+	mm = mm_alloc();
+	if (!mm) {
+		pr_err("mm_struct allocation failed\n");
+		return;
+	}
+
+	/*
+	 * PFN for mapping at PTE level is determined from a standard kernel
+	 * text symbol. But pfns for higher page table levels are derived by
+	 * masking lower bits of this real pfn. These derived pfns might not
+	 * exist on the platform but that does not really matter as pfn_pxx()
+	 * helpers will still create appropriate entries for the test. This
+	 * helps avoid large memory block allocations to be used for mapping
+	 * at higher page table levels.
+	 */
+	paddr = __pa_symbol(&start_kernel);
+
+	pte_aligned = (paddr & PAGE_MASK) >> PAGE_SHIFT;
+	pmd_aligned = (paddr & PMD_MASK) >> PAGE_SHIFT;
+	pud_aligned = (paddr & PUD_MASK) >> PAGE_SHIFT;
+	p4d_aligned = (paddr & P4D_MASK) >> PAGE_SHIFT;
+	pgd_aligned = (paddr & PGDIR_MASK) >> PAGE_SHIFT;
+	WARN_ON(!pfn_valid(pte_aligned));
+
+	pgdp = pgd_offset(mm, vaddr);
+	p4dp = p4d_alloc(mm, pgdp, vaddr);
+	pudp = pud_alloc(mm, p4dp, vaddr);
+	pmdp = pmd_alloc(mm, pudp, vaddr);
+	ptep = pte_alloc_map_lock(mm, pmdp, vaddr, &ptl);
+
+	/*
+	 * Save all the page table page addresses as the page table
+	 * entries will be used for testing with random or garbage
+	 * values. These saved addresses will be used for freeing
+	 * page table pages.
+	 */
+	pmd = READ_ONCE(*pmdp);
+	saved_p4dp = p4d_offset(pgdp, 0UL);
+	saved_pudp = pud_offset(p4dp, 0UL);
+	saved_pmdp = pmd_offset(pudp, 0UL);
+	saved_ptep = pmd_pgtable(pmd);
+
+	pte_basic_tests(pte_aligned, prot);
+	pmd_basic_tests(pmd_aligned, prot);
+	pud_basic_tests(pud_aligned, prot);
+	p4d_basic_tests(p4d_aligned, prot);
+	pgd_basic_tests(pgd_aligned, prot);
+
+	pte_clear_tests(mm, ptep, vaddr);
+	pmd_clear_tests(mm, pmdp);
+	pud_clear_tests(mm, pudp);
+	p4d_clear_tests(mm, p4dp);
+	pgd_clear_tests(mm, pgdp);
+
+	pte_unmap_unlock(ptep, ptl);
+
+	pmd_populate_tests(mm, pmdp, saved_ptep);
+	pud_populate_tests(mm, pudp, saved_pmdp);
+	p4d_populate_tests(mm, p4dp, saved_pudp);
+	pgd_populate_tests(mm, pgdp, saved_p4dp);
+
+	p4d_free(mm, saved_p4dp);
+	pud_free(mm, saved_pudp);
+	pmd_free(mm, saved_pmdp);
+	pte_free(mm, saved_ptep);
+
+	mm_dec_nr_puds(mm);
+	mm_dec_nr_pmds(mm);
+	mm_dec_nr_ptes(mm);
+	mmdrop(mm);
+}
diff --git a/mm/filemap.c b/mm/filemap.c
index 23a051a7ef0f..8ce4c636b1ec 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2372,6 +2372,7 @@ static struct file *do_sync_mmap_readahead(struct vm_fault *vmf)
 	struct address_space *mapping = file->f_mapping;
 	struct file *fpin = NULL;
 	pgoff_t offset = vmf->pgoff;
+	unsigned int mmap_miss;
 
 	/* If we don't want any read-ahead, don't bother */
 	if (vmf->vma->vm_flags & VM_RAND_READ)
@@ -2387,14 +2388,15 @@ static struct file *do_sync_mmap_readahead(struct vm_fault *vmf)
 	}
 
 	/* Avoid banging the cache line if not needed */
-	if (ra->mmap_miss < MMAP_LOTSAMISS * 10)
-		ra->mmap_miss++;
+	mmap_miss = READ_ONCE(ra->mmap_miss);
+	if (mmap_miss < MMAP_LOTSAMISS * 10)
+		WRITE_ONCE(ra->mmap_miss, ++mmap_miss);
 
 	/*
 	 * Do we miss much more than hit in this file? If so,
 	 * stop bothering with read-ahead. It will only hurt.
 	 */
-	if (ra->mmap_miss > MMAP_LOTSAMISS)
+	if (mmap_miss > MMAP_LOTSAMISS)
 		return fpin;
 
 	/*
@@ -2420,13 +2422,15 @@ static struct file *do_async_mmap_readahead(struct vm_fault *vmf,
 	struct file_ra_state *ra = &file->f_ra;
 	struct address_space *mapping = file->f_mapping;
 	struct file *fpin = NULL;
+	unsigned int mmap_miss;
 	pgoff_t offset = vmf->pgoff;
 
 	/* If we don't want any read-ahead, don't bother */
 	if (vmf->vma->vm_flags & VM_RAND_READ || !ra->ra_pages)
 		return fpin;
-	if (ra->mmap_miss > 0)
-		ra->mmap_miss--;
+	mmap_miss = READ_ONCE(ra->mmap_miss);
+	if (mmap_miss)
+		WRITE_ONCE(ra->mmap_miss, --mmap_miss);
 	if (PageReadahead(page)) {
 		fpin = maybe_unlock_mmap_for_io(vmf, fpin);
 		page_cache_async_readahead(mapping, ra, file,
@@ -2593,6 +2597,7 @@ void filemap_map_pages(struct vm_fault *vmf,
 	unsigned long max_idx;
 	XA_STATE(xas, &mapping->i_pages, start_pgoff);
 	struct page *page;
+	unsigned int mmap_miss = READ_ONCE(file->f_ra.mmap_miss);
 
 	rcu_read_lock();
 	xas_for_each(&xas, page, end_pgoff) {
@@ -2629,8 +2634,8 @@ void filemap_map_pages(struct vm_fault *vmf,
 		if (page->index >= max_idx)
 			goto unlock;
 
-		if (file->f_ra.mmap_miss > 0)
-			file->f_ra.mmap_miss--;
+		if (mmap_miss > 0)
+			mmap_miss--;
 
 		vmf->address += (xas.xa_index - last_pgoff) << PAGE_SHIFT;
 		if (vmf->pte)
@@ -2650,6 +2655,7 @@ void filemap_map_pages(struct vm_fault *vmf,
 			break;
 	}
 	rcu_read_unlock();
+	WRITE_ONCE(file->f_ra.mmap_miss, mmap_miss);
 }
 EXPORT_SYMBOL(filemap_map_pages);
 
diff --git a/mm/frontswap.c b/mm/frontswap.c
index 60bb20e8a951..b8c14f298332 100644
--- a/mm/frontswap.c
+++ b/mm/frontswap.c
@@ -61,16 +61,16 @@ static u64 frontswap_failed_stores;
 static u64 frontswap_invalidates;
 
 static inline void inc_frontswap_loads(void) {
-	frontswap_loads++;
+	data_race(frontswap_loads++);
 }
 static inline void inc_frontswap_succ_stores(void) {
-	frontswap_succ_stores++;
+	data_race(frontswap_succ_stores++);
 }
 static inline void inc_frontswap_failed_stores(void) {
-	frontswap_failed_stores++;
+	data_race(frontswap_failed_stores++);
 }
 static inline void inc_frontswap_invalidates(void) {
-	frontswap_invalidates++;
+	data_race(frontswap_invalidates++);
 }
 #else
 static inline void inc_frontswap_loads(void) { }
diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index e362dc3d2028..5e252d91eb14 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -1169,8 +1169,10 @@ static bool update_checksum(struct kmemleak_object *object)
 	u32 old_csum = object->checksum;
 
 	kasan_disable_current();
+	kcsan_disable_current();
 	object->checksum = crc32(0, (void *)object->pointer, object->size);
 	kasan_enable_current();
+	kcsan_enable_current();
 
 	return object->checksum != old_csum;
 }
diff --git a/mm/list_lru.c b/mm/list_lru.c
index 4d5294c39bba..87b540f73323 100644
--- a/mm/list_lru.c
+++ b/mm/list_lru.c
@@ -180,7 +180,7 @@ unsigned long list_lru_count_one(struct list_lru *lru,
 
 	rcu_read_lock();
 	l = list_lru_from_memcg_idx(nlru, memcg_cache_id(memcg));
-	count = l->nr_items;
+	count = READ_ONCE(l->nr_items);
 	rcu_read_unlock();
 
 	return count;
diff --git a/mm/madvise.c b/mm/madvise.c
index 4bb30ed6c8d2..097506466fdc 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -17,6 +17,7 @@
 #include <linux/falloc.h>
 #include <linux/fadvise.h>
 #include <linux/sched.h>
+#include <linux/sched/mm.h>
 #include <linux/ksm.h>
 #include <linux/fs.h>
 #include <linux/file.h>
@@ -35,6 +36,7 @@
 struct madvise_walk_private {
 	struct mmu_gather *tlb;
 	bool pageout;
+	struct task_struct *target_task;
 };
 
 /*
@@ -254,6 +256,7 @@ static long madvise_willneed(struct vm_area_struct *vma,
 			     struct vm_area_struct **prev,
 			     unsigned long start, unsigned long end)
 {
+	struct mm_struct *mm = vma->vm_mm;
 	struct file *file = vma->vm_file;
 	loff_t offset;
 
@@ -288,12 +291,12 @@ static long madvise_willneed(struct vm_area_struct *vma,
 	 */
 	*prev = NULL;	/* tell sys_madvise we drop mmap_sem */
 	get_file(file);
-	up_read(&current->mm->mmap_sem);
+	up_read(&mm->mmap_sem);
 	offset = (loff_t)(start - vma->vm_start)
 			+ ((loff_t)vma->vm_pgoff << PAGE_SHIFT);
 	vfs_fadvise(file, offset, end - start, POSIX_FADV_WILLNEED);
 	fput(file);
-	down_read(&current->mm->mmap_sem);
+	down_read(&mm->mmap_sem);
 	return 0;
 }
 
@@ -314,6 +317,10 @@ static int madvise_cold_or_pageout_pte_range(pmd_t *pmd,
 	if (fatal_signal_pending(current))
 		return -EINTR;
 
+	if (private->target_task &&
+			fatal_signal_pending(private->target_task))
+		return -EINTR;
+
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 	if (pmd_trans_huge(*pmd)) {
 		pmd_t orig_pmd;
@@ -475,12 +482,14 @@ static const struct mm_walk_ops cold_walk_ops = {
 };
 
 static void madvise_cold_page_range(struct mmu_gather *tlb,
+			     struct task_struct *task,
 			     struct vm_area_struct *vma,
 			     unsigned long addr, unsigned long end)
 {
 	struct madvise_walk_private walk_private = {
 		.pageout = false,
 		.tlb = tlb,
+		.target_task = task,
 	};
 
 	tlb_start_vma(tlb, vma);
@@ -488,7 +497,8 @@ static void madvise_cold_page_range(struct mmu_gather *tlb,
 	tlb_end_vma(tlb, vma);
 }
 
-static long madvise_cold(struct vm_area_struct *vma,
+static long madvise_cold(struct task_struct *task,
+			struct vm_area_struct *vma,
 			struct vm_area_struct **prev,
 			unsigned long start_addr, unsigned long end_addr)
 {
@@ -501,19 +511,21 @@ static long madvise_cold(struct vm_area_struct *vma,
 
 	lru_add_drain();
 	tlb_gather_mmu(&tlb, mm, start_addr, end_addr);
-	madvise_cold_page_range(&tlb, vma, start_addr, end_addr);
+	madvise_cold_page_range(&tlb, task, vma, start_addr, end_addr);
 	tlb_finish_mmu(&tlb, start_addr, end_addr);
 
 	return 0;
 }
 
 static void madvise_pageout_page_range(struct mmu_gather *tlb,
+			     struct task_struct *task,
 			     struct vm_area_struct *vma,
 			     unsigned long addr, unsigned long end)
 {
 	struct madvise_walk_private walk_private = {
 		.pageout = true,
 		.tlb = tlb,
+		.target_task = task,
 	};
 
 	tlb_start_vma(tlb, vma);
@@ -537,7 +549,8 @@ static inline bool can_do_pageout(struct vm_area_struct *vma)
 		inode_permission(file_inode(vma->vm_file), MAY_WRITE) == 0;
 }
 
-static long madvise_pageout(struct vm_area_struct *vma,
+static long madvise_pageout(struct task_struct *task,
+			struct vm_area_struct *vma,
 			struct vm_area_struct **prev,
 			unsigned long start_addr, unsigned long end_addr)
 {
@@ -553,7 +566,7 @@ static long madvise_pageout(struct vm_area_struct *vma,
 
 	lru_add_drain();
 	tlb_gather_mmu(&tlb, mm, start_addr, end_addr);
-	madvise_pageout_page_range(&tlb, vma, start_addr, end_addr);
+	madvise_pageout_page_range(&tlb, task, vma, start_addr, end_addr);
 	tlb_finish_mmu(&tlb, start_addr, end_addr);
 
 	return 0;
@@ -682,7 +695,6 @@ static int madvise_free_pte_range(pmd_t *pmd, unsigned long addr,
 	if (nr_swap) {
 		if (current->mm == mm)
 			sync_mm_rss(mm);
-
 		add_mm_counter(mm, MM_SWAPENTS, nr_swap);
 	}
 	arch_leave_lazy_mmu_mode();
@@ -762,6 +774,8 @@ static long madvise_dontneed_free(struct vm_area_struct *vma,
 				  unsigned long start, unsigned long end,
 				  int behavior)
 {
+	struct mm_struct *mm = vma->vm_mm;
+
 	*prev = vma;
 	if (!can_madv_lru_vma(vma))
 		return -EINVAL;
@@ -769,8 +783,8 @@ static long madvise_dontneed_free(struct vm_area_struct *vma,
 	if (!userfaultfd_remove(vma, start, end)) {
 		*prev = NULL; /* mmap_sem has been dropped, prev is stale */
 
-		down_read(&current->mm->mmap_sem);
-		vma = find_vma(current->mm, start);
+		down_read(&mm->mmap_sem);
+		vma = find_vma(mm, start);
 		if (!vma)
 			return -ENOMEM;
 		if (start < vma->vm_start) {
@@ -824,6 +838,7 @@ static long madvise_remove(struct vm_area_struct *vma,
 	loff_t offset;
 	int error;
 	struct file *f;
+	struct mm_struct *mm = vma->vm_mm;
 
 	*prev = NULL;	/* tell sys_madvise we drop mmap_sem */
 
@@ -851,13 +866,13 @@ static long madvise_remove(struct vm_area_struct *vma,
 	get_file(f);
 	if (userfaultfd_remove(vma, start, end)) {
 		/* mmap_sem was not released by userfaultfd_remove() */
-		up_read(&current->mm->mmap_sem);
+		up_read(&mm->mmap_sem);
 	}
 	error = vfs_fallocate(f,
 				FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
 				offset, end - start);
 	fput(f);
-	down_read(&current->mm->mmap_sem);
+	down_read(&mm->mmap_sem);
 	return error;
 }
 
@@ -931,7 +946,8 @@ static int madvise_inject_error(int behavior,
 #endif
 
 static long
-madvise_vma(struct vm_area_struct *vma, struct vm_area_struct **prev,
+madvise_vma(struct task_struct *task, struct vm_area_struct *vma,
+		struct vm_area_struct **prev,
 		unsigned long start, unsigned long end, int behavior)
 {
 	switch (behavior) {
@@ -940,9 +956,9 @@ madvise_vma(struct vm_area_struct *vma, struct vm_area_struct **prev,
 	case MADV_WILLNEED:
 		return madvise_willneed(vma, prev, start, end);
 	case MADV_COLD:
-		return madvise_cold(vma, prev, start, end);
+		return madvise_cold(task, vma, prev, start, end);
 	case MADV_PAGEOUT:
-		return madvise_pageout(vma, prev, start, end);
+		return madvise_pageout(task, vma, prev, start, end);
 	case MADV_FREE:
 	case MADV_DONTNEED:
 		return madvise_dontneed_free(vma, prev, start, end, behavior);
@@ -989,6 +1005,22 @@ madvise_behavior_valid(int behavior)
 	}
 }
 
+static bool
+process_madvise_behavior_valid(int behavior)
+{
+	switch (behavior) {
+	case MADV_COLD:
+	case MADV_PAGEOUT:
+#ifdef CONFIG_KSM
+	case MADV_MERGEABLE:
+	case MADV_UNMERGEABLE:
+#endif
+		return true;
+	default:
+		return false;
+	}
+}
+
 /*
  * The madvise(2) system call.
  *
@@ -1036,6 +1068,11 @@ madvise_behavior_valid(int behavior)
  *  MADV_DONTDUMP - the application wants to prevent pages in the given range
  *		from being included in its core dump.
  *  MADV_DODUMP - cancel MADV_DONTDUMP: no longer exclude from core dump.
+ *  MADV_COLD - the application is not expected to use this memory soon,
+ *		deactivate pages in this range so that they can be reclaimed
+ *		easily if memory pressure hanppens.
+ *  MADV_PAGEOUT - the application is not expected to use this memory soon,
+ *		page out the pages in this range immediately.
  *
  * return values:
  *  zero    - success
@@ -1050,7 +1087,8 @@ madvise_behavior_valid(int behavior)
  *  -EBADF  - map exists, but area maps something that isn't a file.
  *  -EAGAIN - a kernel resource was temporarily unavailable.
  */
-int do_madvise(unsigned long start, size_t len_in, int behavior)
+int do_madvise(struct task_struct *target_task, struct mm_struct *mm,
+		unsigned long start, size_t len_in, int behavior)
 {
 	unsigned long end, tmp;
 	struct vm_area_struct *vma, *prev;
@@ -1088,10 +1126,12 @@ int do_madvise(unsigned long start, size_t len_in, int behavior)
 
 	write = madvise_need_mmap_write(behavior);
 	if (write) {
-		if (down_write_killable(&current->mm->mmap_sem))
+		if (down_write_killable(&mm->mmap_sem))
 			return -EINTR;
+		if (current->mm != mm && !mmget_still_valid(mm))
+			goto skip_mm;
 	} else {
-		down_read(&current->mm->mmap_sem);
+		down_read(&mm->mmap_sem);
 	}
 
 	/*
@@ -1099,7 +1139,7 @@ int do_madvise(unsigned long start, size_t len_in, int behavior)
 	 * ranges, just ignore them, but return -ENOMEM at the end.
 	 * - different from the way of handling in mlock etc.
 	 */
-	vma = find_vma_prev(current->mm, start, &prev);
+	vma = find_vma_prev(mm, start, &prev);
 	if (vma && start > vma->vm_start)
 		prev = vma;
 
@@ -1124,7 +1164,8 @@ int do_madvise(unsigned long start, size_t len_in, int behavior)
 			tmp = end;
 
 		/* Here vma->vm_start <= start < tmp <= (end|vma->vm_end). */
-		error = madvise_vma(vma, &prev, start, tmp, behavior);
+		error = madvise_vma(target_task, vma, &prev,
+					start, tmp, behavior);
 		if (error)
 			goto out;
 		start = tmp;
@@ -1136,19 +1177,76 @@ int do_madvise(unsigned long start, size_t len_in, int behavior)
 		if (prev)
 			vma = prev->vm_next;
 		else	/* madvise_remove dropped mmap_sem */
-			vma = find_vma(current->mm, start);
+			vma = find_vma(mm, start);
 	}
 out:
 	blk_finish_plug(&plug);
+skip_mm:
 	if (write)
-		up_write(&current->mm->mmap_sem);
+		up_write(&mm->mmap_sem);
 	else
-		up_read(&current->mm->mmap_sem);
+		up_read(&mm->mmap_sem);
 
 	return error;
 }
 
 SYSCALL_DEFINE3(madvise, unsigned long, start, size_t, len_in, int, behavior)
 {
-	return do_madvise(start, len_in, behavior);
+	return do_madvise(current, current->mm, start, len_in, behavior);
+}
+
+SYSCALL_DEFINE6(process_madvise, int, which, pid_t, upid, unsigned long, start,
+		size_t, len_in, int, behavior, unsigned long, flags)
+{
+	int ret;
+	struct pid *pid;
+	struct task_struct *task;
+	struct mm_struct *mm;
+
+	if (flags != 0)
+		return -EINVAL;
+
+	if (!process_madvise_behavior_valid(behavior))
+		return -EINVAL;
+
+	switch (which) {
+	case P_PID:
+		if (upid <= 0)
+			return -EINVAL;
+
+		pid = find_get_pid(upid);
+		if (!pid)
+			return -ESRCH;
+		break;
+	case P_PIDFD:
+		if (upid < 0)
+			return -EINVAL;
+
+		pid = pidfd_get_pid(upid);
+		if (IS_ERR(pid))
+			return PTR_ERR(pid);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	task = get_pid_task(pid, PIDTYPE_PID);
+	if (!task) {
+		ret = -ESRCH;
+		goto put_pid;
+	}
+
+	mm = mm_access(task, PTRACE_MODE_ATTACH_FSCREDS);
+	if (IS_ERR_OR_NULL(mm)) {
+		ret = IS_ERR(mm) ? PTR_ERR(mm) : -ESRCH;
+		goto release_task;
+	}
+
+	ret = do_madvise(task, mm, start, len_in, behavior);
+	mmput(mm);
+release_task:
+	put_task_struct(task);
+put_pid:
+	put_pid(pid);
+	return ret;
 }
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 5beea03dd58a..75a978307863 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -3688,7 +3688,7 @@ static int mem_cgroup_move_charge_write(struct cgroup_subsys_state *css,
 #define LRU_ALL	     ((1 << NR_LRU_LISTS) - 1)
 
 static unsigned long mem_cgroup_node_nr_lru_pages(struct mem_cgroup *memcg,
-					   int nid, unsigned int lru_mask)
+				int nid, unsigned int lru_mask, bool tree)
 {
 	struct lruvec *lruvec = mem_cgroup_lruvec(memcg, NODE_DATA(nid));
 	unsigned long nr = 0;
@@ -3699,13 +3699,17 @@ static unsigned long mem_cgroup_node_nr_lru_pages(struct mem_cgroup *memcg,
 	for_each_lru(lru) {
 		if (!(BIT(lru) & lru_mask))
 			continue;
-		nr += lruvec_page_state_local(lruvec, NR_LRU_BASE + lru);
+		if (tree)
+			nr += lruvec_page_state(lruvec, NR_LRU_BASE + lru);
+		else
+			nr += lruvec_page_state_local(lruvec, NR_LRU_BASE + lru);
 	}
 	return nr;
 }
 
 static unsigned long mem_cgroup_nr_lru_pages(struct mem_cgroup *memcg,
-					     unsigned int lru_mask)
+					     unsigned int lru_mask,
+					     bool tree)
 {
 	unsigned long nr = 0;
 	enum lru_list lru;
@@ -3713,7 +3717,10 @@ static unsigned long mem_cgroup_nr_lru_pages(struct mem_cgroup *memcg,
 	for_each_lru(lru) {
 		if (!(BIT(lru) & lru_mask))
 			continue;
-		nr += memcg_page_state_local(memcg, NR_LRU_BASE + lru);
+		if (tree)
+			nr += memcg_page_state(memcg, NR_LRU_BASE + lru);
+		else
+			nr += memcg_page_state_local(memcg, NR_LRU_BASE + lru);
 	}
 	return nr;
 }
@@ -3733,34 +3740,28 @@ static int memcg_numa_stat_show(struct seq_file *m, void *v)
 	};
 	const struct numa_stat *stat;
 	int nid;
-	unsigned long nr;
 	struct mem_cgroup *memcg = mem_cgroup_from_seq(m);
 
 	for (stat = stats; stat < stats + ARRAY_SIZE(stats); stat++) {
-		nr = mem_cgroup_nr_lru_pages(memcg, stat->lru_mask);
-		seq_printf(m, "%s=%lu", stat->name, nr);
-		for_each_node_state(nid, N_MEMORY) {
-			nr = mem_cgroup_node_nr_lru_pages(memcg, nid,
-							  stat->lru_mask);
-			seq_printf(m, " N%d=%lu", nid, nr);
-		}
+		seq_printf(m, "%s=%lu", stat->name,
+			   mem_cgroup_nr_lru_pages(memcg, stat->lru_mask,
+						   false));
+		for_each_node_state(nid, N_MEMORY)
+			seq_printf(m, " N%d=%lu", nid,
+				   mem_cgroup_node_nr_lru_pages(memcg, nid,
+							stat->lru_mask, false));
 		seq_putc(m, '\n');
 	}
 
 	for (stat = stats; stat < stats + ARRAY_SIZE(stats); stat++) {
-		struct mem_cgroup *iter;
-
-		nr = 0;
-		for_each_mem_cgroup_tree(iter, memcg)
-			nr += mem_cgroup_nr_lru_pages(iter, stat->lru_mask);
-		seq_printf(m, "hierarchical_%s=%lu", stat->name, nr);
-		for_each_node_state(nid, N_MEMORY) {
-			nr = 0;
-			for_each_mem_cgroup_tree(iter, memcg)
-				nr += mem_cgroup_node_nr_lru_pages(
-					iter, nid, stat->lru_mask);
-			seq_printf(m, " N%d=%lu", nid, nr);
-		}
+
+		seq_printf(m, "hierarchical_%s=%lu", stat->name,
+			   mem_cgroup_nr_lru_pages(memcg, stat->lru_mask,
+						   true));
+		for_each_node_state(nid, N_MEMORY)
+			seq_printf(m, " N%d=%lu", nid,
+				   mem_cgroup_node_nr_lru_pages(memcg, nid,
+							stat->lru_mask, true));
 		seq_putc(m, '\n');
 	}
 
diff --git a/mm/memory.c b/mm/memory.c
index f703fe8c8346..60c908fd1580 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -3125,8 +3125,8 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
 	if (!page) {
 		struct swap_info_struct *si = swp_swap_info(entry);
 
-		if (si->flags & SWP_SYNCHRONOUS_IO &&
-				__swap_count(entry) == 1) {
+		if (data_race(si->flags & SWP_SYNCHRONOUS_IO) &&
+		    __swap_count(entry) == 1) {
 			/* skip swapcache */
 			page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma,
 							vmf->address);
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index fc0aad0bc1f5..47cf6036eb31 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -42,6 +42,10 @@
 #include "internal.h"
 #include "shuffle.h"
 
+#ifndef MEMORY_HOTPLUG_RES_NAME
+#define MEMORY_HOTPLUG_RES_NAME "System RAM"
+#endif
+
 /*
  * online_page_callback contains pointer to current page onlining function.
  * Initially it is generic_online_page(). If it is required it could be
@@ -102,7 +106,7 @@ static struct resource *register_memory_resource(u64 start, u64 size)
 {
 	struct resource *res;
 	unsigned long flags =  IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
-	char *resource_name = "System RAM";
+	char *resource_name = MEMORY_HOTPLUG_RES_NAME;
 
 	/*
 	 * Make sure value parsed from 'mem=' only restricts memory adding
diff --git a/mm/mempool.c b/mm/mempool.c
index 85efab3da720..79bff63ecf27 100644
--- a/mm/mempool.c
+++ b/mm/mempool.c
@@ -489,7 +489,7 @@ void mempool_free(void *element, mempool_t *pool)
 	 * ensures that there will be frees which return elements to the
 	 * pool waking up the waiters.
 	 */
-	if (unlikely(pool->curr_nr < pool->min_nr)) {
+	if (unlikely(READ_ONCE(pool->curr_nr) < pool->min_nr)) {
 		spin_lock_irqsave(&pool->lock, flags);
 		if (likely(pool->curr_nr < pool->min_nr)) {
 			add_element(pool, element);
diff --git a/mm/memremap.c b/mm/memremap.c
index 03e38b7a38f1..8afcc54c8928 100644
--- a/mm/memremap.c
+++ b/mm/memremap.c
@@ -97,6 +97,26 @@ static unsigned long pfn_next(unsigned long pfn)
 	return pfn + 1;
 }
 
+/*
+ * This returns true if the page is reserved by ZONE_DEVICE driver.
+ */
+bool pfn_zone_device_reserved(unsigned long pfn)
+{
+	struct dev_pagemap *pgmap;
+	struct vmem_altmap *altmap;
+	bool ret = false;
+
+	pgmap = get_dev_pagemap(pfn, NULL);
+	if (!pgmap)
+		return ret;
+	altmap = pgmap_altmap(pgmap);
+	if (altmap && pfn < (altmap->base_pfn + altmap->reserve))
+		ret = true;
+	put_dev_pagemap(pgmap);
+
+	return ret;
+}
+
 #define for_each_device_pfn(pfn, map) \
 	for (pfn = pfn_first(map); pfn < pfn_end(map); pfn = pfn_next(pfn))
 
diff --git a/mm/mmap.c b/mm/mmap.c
index f609e9ec4a25..0681bd51801f 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1850,6 +1850,22 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
 	return error;
 }
 
+static inline unsigned long gap_start_offset(struct vm_unmapped_area_info *info,
+					unsigned long addr)
+{
+	/* get gap_start offset to adjust gap address to the
+	 * desired alignment
+	 */
+	return (info->align_offset - addr) & info->align_mask;
+}
+
+static inline unsigned long gap_end_offset(struct vm_unmapped_area_info *info,
+					unsigned long addr)
+{
+	/* get gap_end offset to adjust gap address to the desired alignment */
+	return (addr - info->align_offset) & info->align_mask;
+}
+
 static unsigned long unmapped_area(struct vm_unmapped_area_info *info)
 {
 	/*
@@ -1864,10 +1880,7 @@ static unsigned long unmapped_area(struct vm_unmapped_area_info *info)
 	struct vm_area_struct *vma;
 	unsigned long length, low_limit, high_limit, gap_start, gap_end;
 
-	/* Adjust search length to account for worst case alignment overhead */
-	length = info->length + info->align_mask;
-	if (length < info->length)
-		return -ENOMEM;
+	length = info->length;
 
 	/* Adjust search limits by the desired length */
 	if (info->high_limit < length)
@@ -1899,6 +1912,7 @@ static unsigned long unmapped_area(struct vm_unmapped_area_info *info)
 		}
 
 		gap_start = vma->vm_prev ? vm_end_gap(vma->vm_prev) : 0;
+		gap_start += gap_start_offset(info, gap_start);
 check_current:
 		/* Check if current node has a suitable gap */
 		if (gap_start > high_limit)
@@ -1927,6 +1941,7 @@ static unsigned long unmapped_area(struct vm_unmapped_area_info *info)
 				       struct vm_area_struct, vm_rb);
 			if (prev == vma->vm_rb.rb_left) {
 				gap_start = vm_end_gap(vma->vm_prev);
+				gap_start += gap_start_offset(info, gap_start);
 				gap_end = vm_start_gap(vma);
 				goto check_current;
 			}
@@ -1936,17 +1951,17 @@ static unsigned long unmapped_area(struct vm_unmapped_area_info *info)
 check_highest:
 	/* Check highest gap, which does not precede any rbtree node */
 	gap_start = mm->highest_vm_end;
+	gap_start += gap_start_offset(info, gap_start);
 	gap_end = ULONG_MAX;  /* Only for VM_BUG_ON below */
 	if (gap_start > high_limit)
 		return -ENOMEM;
 
 found:
 	/* We found a suitable gap. Clip it with the original low_limit. */
-	if (gap_start < info->low_limit)
+	if (gap_start < info->low_limit) {
 		gap_start = info->low_limit;
-
-	/* Adjust gap address to the desired alignment */
-	gap_start += (info->align_offset - gap_start) & info->align_mask;
+		gap_start += gap_start_offset(info, gap_start);
+	}
 
 	VM_BUG_ON(gap_start + info->length > info->high_limit);
 	VM_BUG_ON(gap_start + info->length > gap_end);
@@ -1959,16 +1974,14 @@ static unsigned long unmapped_area_topdown(struct vm_unmapped_area_info *info)
 	struct vm_area_struct *vma;
 	unsigned long length, low_limit, high_limit, gap_start, gap_end;
 
-	/* Adjust search length to account for worst case alignment overhead */
-	length = info->length + info->align_mask;
-	if (length < info->length)
-		return -ENOMEM;
+	length = info->length;
 
 	/*
 	 * Adjust search limits by the desired length.
 	 * See implementation comment at top of unmapped_area().
 	 */
 	gap_end = info->high_limit;
+	gap_end -= gap_end_offset(info, gap_end);
 	if (gap_end < length)
 		return -ENOMEM;
 	high_limit = gap_end - length;
@@ -2005,6 +2018,7 @@ static unsigned long unmapped_area_topdown(struct vm_unmapped_area_info *info)
 check_current:
 		/* Check if current node has a suitable gap */
 		gap_end = vm_start_gap(vma);
+		gap_end -= gap_end_offset(info, gap_end);
 		if (gap_end < low_limit)
 			return -ENOMEM;
 		if (gap_start <= high_limit &&
@@ -2039,13 +2053,14 @@ static unsigned long unmapped_area_topdown(struct vm_unmapped_area_info *info)
 
 found:
 	/* We found a suitable gap. Clip it with the original high_limit. */
-	if (gap_end > info->high_limit)
+	if (gap_end > info->high_limit) {
 		gap_end = info->high_limit;
+		gap_end -= gap_end_offset(info, gap_end);
+	}
 
 found_highest:
 	/* Compute highest gap address at the desired alignment */
 	gap_end -= info->length;
-	gap_end -= (gap_end - info->align_offset) & info->align_mask;
 
 	VM_BUG_ON(gap_end < info->low_limit);
 	VM_BUG_ON(gap_end < gap_start);
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 69827d4fa052..1385d786a01a 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -2759,6 +2759,20 @@ __rmqueue(struct zone *zone, unsigned int order, int migratetype,
 {
 	struct page *page;
 
+#ifdef CONFIG_CMA
+	/*
+	 * Balance movable allocations between regular and CMA areas by
+	 * allocating from CMA when over half of the zone's free memory
+	 * is in the CMA area.
+	 */
+	if (migratetype == MIGRATE_MOVABLE &&
+	    zone_page_state(zone, NR_FREE_CMA_PAGES) >
+	    zone_page_state(zone, NR_FREE_PAGES) / 2) {
+		page = __rmqueue_cma_fallback(zone, order);
+		if (page)
+			return page;
+	}
+#endif
 retry:
 	page = __rmqueue_smallest(zone, order, migratetype);
 	if (unlikely(!page)) {
diff --git a/mm/page_counter.c b/mm/page_counter.c
index c56db2d5e159..e3a205275a0b 100644
--- a/mm/page_counter.c
+++ b/mm/page_counter.c
@@ -77,8 +77,8 @@ void page_counter_charge(struct page_counter *counter, unsigned long nr_pages)
 		 * This is indeed racy, but we can live with some
 		 * inaccuracy in the watermark.
 		 */
-		if (new > c->watermark)
-			c->watermark = new;
+		if (new > READ_ONCE(c->watermark))
+			WRITE_ONCE(c->watermark, new);
 	}
 }
 
@@ -119,9 +119,10 @@ bool page_counter_try_charge(struct page_counter *counter,
 			propagate_protected_usage(counter, new);
 			/*
 			 * This is racy, but we can live with some
-			 * inaccuracy in the failcnt.
+			 * inaccuracy in the failcnt which is only used
+			 * to report stats.
 			 */
-			c->failcnt++;
+			data_race(c->failcnt++);
 			*fail = c;
 			goto failed;
 		}
@@ -130,8 +131,8 @@ bool page_counter_try_charge(struct page_counter *counter,
 		 * Just like with failcnt, we can live with some
 		 * inaccuracy in the watermark.
 		 */
-		if (new > c->watermark)
-			c->watermark = new;
+		if (new > READ_ONCE(c->watermark))
+			WRITE_ONCE(c->watermark, new);
 	}
 	return true;
 
diff --git a/mm/page_io.c b/mm/page_io.c
index 76965be1d40e..26935db0676c 100644
--- a/mm/page_io.c
+++ b/mm/page_io.c
@@ -86,7 +86,7 @@ static void swap_slot_free_notify(struct page *page)
 		return;
 
 	sis = page_swap_info(page);
-	if (!(sis->flags & SWP_BLKDEV))
+	if (data_race(!(sis->flags & SWP_BLKDEV)))
 		return;
 
 	/*
@@ -286,7 +286,7 @@ int __swap_writepage(struct page *page, struct writeback_control *wbc,
 	struct swap_info_struct *sis = page_swap_info(page);
 
 	VM_BUG_ON_PAGE(!PageSwapCache(page), page);
-	if (sis->flags & SWP_FS) {
+	if (data_race(sis->flags & SWP_FS)) {
 		struct kiocb kiocb;
 		struct file *swap_file = sis->swap_file;
 		struct address_space *mapping = swap_file->f_mapping;
@@ -377,7 +377,7 @@ int swap_readpage(struct page *page, bool synchronous)
 		goto out;
 	}
 
-	if (sis->flags & SWP_FS) {
+	if (data_race(sis->flags & SWP_FS)) {
 		struct file *swap_file = sis->swap_file;
 		struct address_space *mapping = swap_file->f_mapping;
 
@@ -439,7 +439,7 @@ int swap_set_page_dirty(struct page *page)
 {
 	struct swap_info_struct *sis = page_swap_info(page);
 
-	if (sis->flags & SWP_FS) {
+	if (data_race(sis->flags & SWP_FS)) {
 		struct address_space *mapping = sis->swap_file->f_mapping;
 
 		VM_BUG_ON_PAGE(!PageSwapCache(page), page);
diff --git a/mm/rmap.c b/mm/rmap.c
index f79a206b271a..2126fd4a254b 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -672,7 +672,7 @@ static bool should_defer_flush(struct mm_struct *mm, enum ttu_flags flags)
  */
 void flush_tlb_batched_pending(struct mm_struct *mm)
 {
-	if (mm->tlb_flush_batched) {
+	if (data_race(mm->tlb_flush_batched)) {
 		flush_tlb_mm(mm);
 
 		/*
diff --git a/mm/slob.c b/mm/slob.c
index fa53e9f73893..ac2aecfbc7a8 100644
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -524,6 +524,7 @@ void *__kmalloc_track_caller(size_t size, gfp_t gfp, unsigned long caller)
 {
 	return __do_kmalloc_node(size, gfp, NUMA_NO_NODE, caller);
 }
+EXPORT_SYMBOL(__kmalloc_track_caller);
 
 #ifdef CONFIG_NUMA
 void *__kmalloc_node_track_caller(size_t size, gfp_t gfp,
@@ -531,6 +532,7 @@ void *__kmalloc_node_track_caller(size_t size, gfp_t gfp,
 {
 	return __do_kmalloc_node(size, gfp, node, caller);
 }
+EXPORT_SYMBOL(__kmalloc_node_track_caller);
 #endif
 
 void kfree(const void *block)
diff --git a/mm/slub.c b/mm/slub.c
index 332d4b459a90..7002af0f013f 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -4385,6 +4385,7 @@ void *__kmalloc_track_caller(size_t size, gfp_t gfpflags, unsigned long caller)
 
 	return ret;
 }
+EXPORT_SYMBOL(__kmalloc_track_caller);
 
 #ifdef CONFIG_NUMA
 void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags,
@@ -4415,6 +4416,7 @@ void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags,
 
 	return ret;
 }
+EXPORT_SYMBOL(__kmalloc_node_track_caller);
 #endif
 
 #ifdef CONFIG_SYSFS
diff --git a/mm/swap.c b/mm/swap.c
index bf9a79fed62d..a37bd7b202ac 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -599,7 +599,8 @@ void lru_add_drain_cpu(int cpu)
 		__pagevec_lru_add(pvec);
 
 	pvec = &per_cpu(lru_rotate_pvecs, cpu);
-	if (pagevec_count(pvec)) {
+	/* Disabling interrupts below acts as a compiler barrier. */
+	if (data_race(pagevec_count(pvec))) {
 		unsigned long flags;
 
 		/* No harm done if a racing interrupt already did this */
@@ -744,7 +745,7 @@ void lru_add_drain_all(void)
 		struct work_struct *work = &per_cpu(lru_add_drain_work, cpu);
 
 		if (pagevec_count(&per_cpu(lru_add_pvec, cpu)) ||
-		    pagevec_count(&per_cpu(lru_rotate_pvecs, cpu)) ||
+		    data_race(pagevec_count(&per_cpu(lru_rotate_pvecs, cpu))) ||
 		    pagevec_count(&per_cpu(lru_deactivate_file_pvecs, cpu)) ||
 		    pagevec_count(&per_cpu(lru_deactivate_pvecs, cpu)) ||
 		    pagevec_count(&per_cpu(lru_lazyfree_pvecs, cpu)) ||
diff --git a/mm/swap_state.c b/mm/swap_state.c
index ebed37bbf7a3..c8e0fc5a5a3a 100644
--- a/mm/swap_state.c
+++ b/mm/swap_state.c
@@ -58,8 +58,8 @@ static bool enable_vma_readahead __read_mostly = true;
 #define GET_SWAP_RA_VAL(vma)					\
 	(atomic_long_read(&(vma)->swap_readahead_info) ? : 4)
 
-#define INC_CACHE_INFO(x)	do { swap_cache_info.x++; } while (0)
-#define ADD_CACHE_INFO(x, nr)	do { swap_cache_info.x += (nr); } while (0)
+#define INC_CACHE_INFO(x)	data_race(swap_cache_info.x++)
+#define ADD_CACHE_INFO(x, nr)	data_race(swap_cache_info.x += (nr))
 
 static struct {
 	unsigned long add_total;
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 5871a2aa86a5..6659ab563448 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -678,7 +678,7 @@ static void swap_range_alloc(struct swap_info_struct *si, unsigned long offset,
 	if (offset == si->lowest_bit)
 		si->lowest_bit += nr_entries;
 	if (end == si->highest_bit)
-		si->highest_bit -= nr_entries;
+		WRITE_ONCE(si->highest_bit, si->highest_bit - nr_entries);
 	si->inuse_pages += nr_entries;
 	if (si->inuse_pages == si->pages) {
 		si->lowest_bit = si->max;
@@ -710,7 +710,7 @@ static void swap_range_free(struct swap_info_struct *si, unsigned long offset,
 	if (end > si->highest_bit) {
 		bool was_full = !si->highest_bit;
 
-		si->highest_bit = end;
+		WRITE_ONCE(si->highest_bit, end);
 		if (was_full && (si->flags & SWP_WRITEOK))
 			add_to_avail_list(si);
 	}
@@ -843,7 +843,7 @@ static int scan_swap_map_slots(struct swap_info_struct *si,
 		else
 			goto done;
 	}
-	si->swap_map[offset] = usage;
+	WRITE_ONCE(si->swap_map[offset], usage);
 	inc_cluster_info_page(si, si->cluster_info, offset);
 	unlock_cluster(ci);
 
@@ -889,12 +889,13 @@ static int scan_swap_map_slots(struct swap_info_struct *si,
 
 scan:
 	spin_unlock(&si->lock);
-	while (++offset <= si->highest_bit) {
-		if (!si->swap_map[offset]) {
+	while (++offset <= READ_ONCE(si->highest_bit)) {
+		if (data_race(!si->swap_map[offset])) {
 			spin_lock(&si->lock);
 			goto checks;
 		}
-		if (vm_swap_full() && si->swap_map[offset] == SWAP_HAS_CACHE) {
+		if (vm_swap_full() &&
+		    READ_ONCE(si->swap_map[offset]) == SWAP_HAS_CACHE) {
 			spin_lock(&si->lock);
 			goto checks;
 		}
@@ -905,11 +906,12 @@ static int scan_swap_map_slots(struct swap_info_struct *si,
 	}
 	offset = si->lowest_bit;
 	while (offset < scan_base) {
-		if (!si->swap_map[offset]) {
+		if (data_race(!si->swap_map[offset])) {
 			spin_lock(&si->lock);
 			goto checks;
 		}
-		if (vm_swap_full() && si->swap_map[offset] == SWAP_HAS_CACHE) {
+		if (vm_swap_full() &&
+		    READ_ONCE(si->swap_map[offset]) == SWAP_HAS_CACHE) {
 			spin_lock(&si->lock);
 			goto checks;
 		}
@@ -1111,7 +1113,7 @@ static struct swap_info_struct *__swap_info_get(swp_entry_t entry)
 	p = swp_swap_info(entry);
 	if (!p)
 		goto bad_nofile;
-	if (!(p->flags & SWP_USED))
+	if (data_race(!(p->flags & SWP_USED)))
 		goto bad_device;
 	offset = swp_offset(entry);
 	if (offset >= p->max)
@@ -1137,7 +1139,7 @@ static struct swap_info_struct *_swap_info_get(swp_entry_t entry)
 	p = __swap_info_get(entry);
 	if (!p)
 		goto out;
-	if (!p->swap_map[swp_offset(entry)])
+	if (data_race(!p->swap_map[swp_offset(entry)]))
 		goto bad_free;
 	return p;
 
@@ -1206,7 +1208,10 @@ static unsigned char __swap_entry_free_locked(struct swap_info_struct *p,
 	}
 
 	usage = count | has_cache;
-	p->swap_map[offset] = usage ? : SWAP_HAS_CACHE;
+	if (usage)
+		WRITE_ONCE(p->swap_map[offset], usage);
+	else
+		WRITE_ONCE(p->swap_map[offset], SWAP_HAS_CACHE);
 
 	return usage;
 }
@@ -1258,7 +1263,7 @@ struct swap_info_struct *get_swap_device(swp_entry_t entry)
 		goto bad_nofile;
 
 	rcu_read_lock();
-	if (!(si->flags & SWP_VALID))
+	if (data_race(!(si->flags & SWP_VALID)))
 		goto unlock_out;
 	offset = swp_offset(entry);
 	if (offset >= si->max)
@@ -3436,7 +3441,7 @@ static int __swap_duplicate(swp_entry_t entry, unsigned char usage)
 	} else
 		err = -ENOENT;			/* unused swap entry */
 
-	p->swap_map[offset] = count | has_cache;
+	WRITE_ONCE(p->swap_map[offset], count | has_cache);
 
 unlock_out:
 	unlock_cluster_or_swap_info(p, ci);
diff --git a/mm/util.c b/mm/util.c
index 988d11e6c17c..cc89e2404e19 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -798,8 +798,12 @@ int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin)
 {
 	long allowed;
 
-	VM_WARN_ONCE(percpu_counter_read(&vm_committed_as) <
-			-(s64)vm_committed_as_batch * num_online_cpus(),
+	/*
+	 * A transient decrease in the value is unlikely, so no need
+	 * READ_ONCE() for vm_committed_as.count.
+	 */
+	VM_WARN_ONCE(data_race(percpu_counter_read(&vm_committed_as) <
+			-(s64)vm_committed_as_batch * num_online_cpus()),
 			"memory commitment underflow");
 
 	vm_acct_memory(pages);
diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig
index 165148c7c4ce..9e25c6570170 100644
--- a/net/bluetooth/Kconfig
+++ b/net/bluetooth/Kconfig
@@ -93,6 +93,21 @@ config BT_LEDS
 	  This option selects a few LED triggers for different
 	  Bluetooth events.
 
+config BT_MSFTEXT
+	bool "Enable Microsoft extensions"
+	depends on BT
+	help
+	  This options enables support for the Microsoft defined HCI
+	  vendor extensions.
+
+config BT_DEBUGFS
+	bool "Export Bluetooth internals in debugfs"
+	depends on BT && DEBUG_FS
+	default y
+	help
+	  Provide extensive information about internal Bluetooth states
+	  in debugfs.
+
 config BT_SELFTEST
 	bool "Bluetooth self testing support"
 	depends on BT && DEBUG_KERNEL
@@ -120,12 +135,4 @@ config BT_SELFTEST_SMP
 	  Run test cases for SMP cryptographic functionality, including both
 	  legacy SMP as well as the Secure Connections features.
 
-config BT_DEBUGFS
-	bool "Export Bluetooth internals in debugfs"
-	depends on BT && DEBUG_FS
-	default y
-	help
-	  Provide extensive information about internal Bluetooth states
-	  in debugfs.
-
 source "drivers/bluetooth/Kconfig"
diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile
index fda41c0b4781..41dd541a44a5 100644
--- a/net/bluetooth/Makefile
+++ b/net/bluetooth/Makefile
@@ -19,5 +19,6 @@ bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o \
 bluetooth-$(CONFIG_BT_BREDR) += sco.o
 bluetooth-$(CONFIG_BT_HS) += a2mp.o amp.o
 bluetooth-$(CONFIG_BT_LEDS) += leds.o
+bluetooth-$(CONFIG_BT_MSFTEXT) += msft.o
 bluetooth-$(CONFIG_BT_DEBUGFS) += hci_debugfs.o
 bluetooth-$(CONFIG_BT_SELFTEST) += selftest.o
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index e245bc155cc2..07c34c55fc50 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -122,8 +122,18 @@ static void hci_conn_cleanup(struct hci_conn *conn)
 
 	hci_conn_hash_del(hdev, conn);
 
-	if (hdev->notify)
-		hdev->notify(hdev, HCI_NOTIFY_CONN_DEL);
+	if (conn->type == SCO_LINK || conn->type == ESCO_LINK) {
+		switch (conn->setting & SCO_AIRMODE_MASK) {
+		case SCO_AIRMODE_CVSD:
+		case SCO_AIRMODE_TRANSP:
+			if (hdev->notify)
+				hdev->notify(hdev, HCI_NOTIFY_DISABLE_SCO);
+			break;
+		}
+	} else {
+		if (hdev->notify)
+			hdev->notify(hdev, HCI_NOTIFY_CONN_DEL);
+	}
 
 	hci_conn_del_sysfs(conn);
 
@@ -577,8 +587,15 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
 	hci_dev_hold(hdev);
 
 	hci_conn_hash_add(hdev, conn);
-	if (hdev->notify)
-		hdev->notify(hdev, HCI_NOTIFY_CONN_ADD);
+
+	/* The SCO and eSCO connections will only be notified when their
+	 * setup has been completed. This is different to ACL links which
+	 * can be notified right away.
+	 */
+	if (conn->type != SCO_LINK && conn->type != ESCO_LINK) {
+		if (hdev->notify)
+			hdev->notify(hdev, HCI_NOTIFY_CONN_ADD);
+	}
 
 	hci_conn_init_sysfs(conn);
 
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 2e7bc2da8371..51d399273276 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -44,6 +44,7 @@
 #include "hci_debugfs.h"
 #include "smp.h"
 #include "leds.h"
+#include "msft.h"
 
 static void hci_rx_work(struct work_struct *work);
 static void hci_cmd_work(struct work_struct *work);
@@ -637,6 +638,14 @@ static int hci_init3_req(struct hci_request *req, unsigned long opt)
 		if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT)
 			events[0] |= 0x40;	/* LE Data Length Change */
 
+		/* If the controller supports LL Privacy feature, enable
+		 * the corresponding event.
+		 */
+		if (hdev->le_features[0] & HCI_LE_LL_PRIVACY)
+			events[1] |= 0x02;	/* LE Enhanced Connection
+						 * Complete
+						 */
+
 		/* If the controller supports Extended Scanner Filter
 		 * Policies, enable the correspondig event.
 		 */
@@ -710,14 +719,6 @@ static int hci_init3_req(struct hci_request *req, unsigned long opt)
 						 * Report
 						 */
 
-		/* If the controller supports the LE Extended Create Connection
-		 * command, enable the corresponding event.
-		 */
-		if (use_ext_conn(hdev))
-			events[1] |= 0x02;      /* LE Enhanced Connection
-						 * Complete
-						 */
-
 		/* If the controller supports the LE Extended Advertising
 		 * command, enable the corresponding event.
 		 */
@@ -826,6 +827,10 @@ static int hci_init4_req(struct hci_request *req, unsigned long opt)
 	if (hdev->commands[29] & 0x20)
 		hci_req_add(req, HCI_OP_READ_LOCAL_CODECS, 0, NULL);
 
+	/* Read local pairing options if the HCI command is supported */
+	if (hdev->commands[41] & 0x08)
+		hci_req_add(req, HCI_OP_READ_LOCAL_PAIRING_OPTS, 0, NULL);
+
 	/* Get MWS transport configuration if the HCI command is supported */
 	if (hdev->commands[30] & 0x08)
 		hci_req_add(req, HCI_OP_GET_MWS_TRANSPORT_CONFIG, 0, NULL);
@@ -1563,6 +1568,8 @@ static int hci_dev_do_open(struct hci_dev *hdev)
 	    hci_dev_test_flag(hdev, HCI_VENDOR_DIAG) && hdev->set_diag)
 		ret = hdev->set_diag(hdev, true);
 
+	msft_do_open(hdev);
+
 	clear_bit(HCI_INIT, &hdev->flags);
 
 	if (!ret) {
@@ -1758,6 +1765,8 @@ int hci_dev_do_close(struct hci_dev *hdev)
 
 	hci_sock_dev_event(hdev, HCI_DEV_DOWN);
 
+	msft_do_close(hdev);
+
 	if (hdev->flush)
 		hdev->flush(hdev);
 
@@ -4240,6 +4249,54 @@ static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
 	}
 }
 
+/* Schedule SCO */
+static void hci_sched_sco(struct hci_dev *hdev)
+{
+	struct hci_conn *conn;
+	struct sk_buff *skb;
+	int quote;
+
+	BT_DBG("%s", hdev->name);
+
+	if (!hci_conn_num(hdev, SCO_LINK))
+		return;
+
+	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
+		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
+			BT_DBG("skb %p len %d", skb, skb->len);
+			hci_send_frame(hdev, skb);
+
+			conn->sent++;
+			if (conn->sent == ~0)
+				conn->sent = 0;
+		}
+	}
+}
+
+static void hci_sched_esco(struct hci_dev *hdev)
+{
+	struct hci_conn *conn;
+	struct sk_buff *skb;
+	int quote;
+
+	BT_DBG("%s", hdev->name);
+
+	if (!hci_conn_num(hdev, ESCO_LINK))
+		return;
+
+	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
+						     &quote))) {
+		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
+			BT_DBG("skb %p len %d", skb, skb->len);
+			hci_send_frame(hdev, skb);
+
+			conn->sent++;
+			if (conn->sent == ~0)
+				conn->sent = 0;
+		}
+	}
+}
+
 static void hci_sched_acl_pkt(struct hci_dev *hdev)
 {
 	unsigned int cnt = hdev->acl_cnt;
@@ -4271,6 +4328,10 @@ static void hci_sched_acl_pkt(struct hci_dev *hdev)
 			hdev->acl_cnt--;
 			chan->sent++;
 			chan->conn->sent++;
+
+			/* Send pending SCO packets right away */
+			hci_sched_sco(hdev);
+			hci_sched_esco(hdev);
 		}
 	}
 
@@ -4355,54 +4416,6 @@ static void hci_sched_acl(struct hci_dev *hdev)
 	}
 }
 
-/* Schedule SCO */
-static void hci_sched_sco(struct hci_dev *hdev)
-{
-	struct hci_conn *conn;
-	struct sk_buff *skb;
-	int quote;
-
-	BT_DBG("%s", hdev->name);
-
-	if (!hci_conn_num(hdev, SCO_LINK))
-		return;
-
-	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
-		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
-			BT_DBG("skb %p len %d", skb, skb->len);
-			hci_send_frame(hdev, skb);
-
-			conn->sent++;
-			if (conn->sent == ~0)
-				conn->sent = 0;
-		}
-	}
-}
-
-static void hci_sched_esco(struct hci_dev *hdev)
-{
-	struct hci_conn *conn;
-	struct sk_buff *skb;
-	int quote;
-
-	BT_DBG("%s", hdev->name);
-
-	if (!hci_conn_num(hdev, ESCO_LINK))
-		return;
-
-	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
-						     &quote))) {
-		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
-			BT_DBG("skb %p len %d", skb, skb->len);
-			hci_send_frame(hdev, skb);
-
-			conn->sent++;
-			if (conn->sent == ~0)
-				conn->sent = 0;
-		}
-	}
-}
-
 static void hci_sched_le(struct hci_dev *hdev)
 {
 	struct hci_chan *chan;
@@ -4437,6 +4450,10 @@ static void hci_sched_le(struct hci_dev *hdev)
 			cnt--;
 			chan->sent++;
 			chan->conn->sent++;
+
+			/* Send pending SCO packets right away */
+			hci_sched_sco(hdev);
+			hci_sched_esco(hdev);
 		}
 	}
 
@@ -4459,9 +4476,9 @@ static void hci_tx_work(struct work_struct *work)
 
 	if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
 		/* Schedule queues and send stuff to HCI driver */
-		hci_sched_acl(hdev);
 		hci_sched_sco(hdev);
 		hci_sched_esco(hdev);
+		hci_sched_acl(hdev);
 		hci_sched_le(hdev);
 	}
 
diff --git a/net/bluetooth/hci_debugfs.c b/net/bluetooth/hci_debugfs.c
index 6b1314c738b8..5e8af2658e44 100644
--- a/net/bluetooth/hci_debugfs.c
+++ b/net/bluetooth/hci_debugfs.c
@@ -1075,6 +1075,50 @@ DEFINE_SIMPLE_ATTRIBUTE(auth_payload_timeout_fops,
 			auth_payload_timeout_get,
 			auth_payload_timeout_set, "%llu\n");
 
+static ssize_t force_no_mitm_read(struct file *file,
+				  char __user *user_buf,
+				  size_t count, loff_t *ppos)
+{
+	struct hci_dev *hdev = file->private_data;
+	char buf[3];
+
+	buf[0] = hci_dev_test_flag(hdev, HCI_FORCE_NO_MITM) ? 'Y' : 'N';
+	buf[1] = '\n';
+	buf[2] = '\0';
+	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
+}
+
+static ssize_t force_no_mitm_write(struct file *file,
+				   const char __user *user_buf,
+				   size_t count, loff_t *ppos)
+{
+	struct hci_dev *hdev = file->private_data;
+	char buf[32];
+	size_t buf_size = min(count, (sizeof(buf) - 1));
+	bool enable;
+
+	if (copy_from_user(buf, user_buf, buf_size))
+		return -EFAULT;
+
+	buf[buf_size] = '\0';
+	if (strtobool(buf, &enable))
+		return -EINVAL;
+
+	if (enable == hci_dev_test_flag(hdev, HCI_FORCE_NO_MITM))
+		return -EALREADY;
+
+	hci_dev_change_flag(hdev, HCI_FORCE_NO_MITM);
+
+	return count;
+}
+
+static const struct file_operations force_no_mitm_fops = {
+	.open		= simple_open,
+	.read		= force_no_mitm_read,
+	.write		= force_no_mitm_write,
+	.llseek		= default_llseek,
+};
+
 DEFINE_QUIRK_ATTRIBUTE(quirk_strict_duplicate_filter,
 		       HCI_QUIRK_STRICT_DUPLICATE_FILTER);
 DEFINE_QUIRK_ATTRIBUTE(quirk_simultaneous_discovery,
@@ -1134,6 +1178,8 @@ void hci_debugfs_create_le(struct hci_dev *hdev)
 			    &max_key_size_fops);
 	debugfs_create_file("auth_payload_timeout", 0644, hdev->debugfs, hdev,
 			    &auth_payload_timeout_fops);
+	debugfs_create_file("force_no_mitm", 0644, hdev->debugfs, hdev,
+			    &force_no_mitm_fops);
 
 	debugfs_create_file("quirk_strict_duplicate_filter", 0644,
 			    hdev->debugfs, hdev,
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 0a591be8b0ae..966fc543c01d 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -35,6 +35,7 @@
 #include "a2mp.h"
 #include "amp.h"
 #include "smp.h"
+#include "msft.h"
 
 #define ZERO_KEY "\x00\x00\x00\x00\x00\x00\x00\x00" \
 		 "\x00\x00\x00\x00\x00\x00\x00\x00"
@@ -746,6 +747,23 @@ static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
 		bacpy(&hdev->setup_addr, &rp->bdaddr);
 }
 
+static void hci_cc_read_local_pairing_opts(struct hci_dev *hdev,
+					   struct sk_buff *skb)
+{
+	struct hci_rp_read_local_pairing_opts *rp = (void *) skb->data;
+
+	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
+
+	if (rp->status)
+		return;
+
+	if (hci_dev_test_flag(hdev, HCI_SETUP) ||
+	    hci_dev_test_flag(hdev, HCI_CONFIG)) {
+		hdev->pairing_opts = rp->pairing_opts;
+		hdev->max_enc_key_size = rp->max_key_size;
+	}
+}
+
 static void hci_cc_read_page_scan_activity(struct hci_dev *hdev,
 					   struct sk_buff *skb)
 {
@@ -2607,8 +2625,16 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	if (ev->status) {
 		hci_connect_cfm(conn, ev->status);
 		hci_conn_del(conn);
-	} else if (ev->link_type != ACL_LINK)
+	} else if (ev->link_type == SCO_LINK) {
+		switch (conn->setting & SCO_AIRMODE_MASK) {
+		case SCO_AIRMODE_CVSD:
+			if (hdev->notify)
+				hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_CVSD);
+			break;
+		}
+
 		hci_connect_cfm(conn, ev->status);
+	}
 
 unlock:
 	hci_dev_unlock(hdev);
@@ -3334,6 +3360,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb,
 		hci_cc_read_bd_addr(hdev, skb);
 		break;
 
+	case HCI_OP_READ_LOCAL_PAIRING_OPTS:
+		hci_cc_read_local_pairing_opts(hdev, skb);
+		break;
+
 	case HCI_OP_READ_PAGE_SCAN_ACTIVITY:
 		hci_cc_read_page_scan_activity(hdev, skb);
 		break;
@@ -4307,6 +4337,19 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
 		break;
 	}
 
+	bt_dev_dbg(hdev, "SCO connected with air mode: %02x", ev->air_mode);
+
+	switch (conn->setting & SCO_AIRMODE_MASK) {
+	case SCO_AIRMODE_CVSD:
+		if (hdev->notify)
+			hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_CVSD);
+		break;
+	case SCO_AIRMODE_TRANSP:
+		if (hdev->notify)
+			hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_TRANSP);
+		break;
+	}
+
 	hci_connect_cfm(conn, ev->status);
 	if (ev->status)
 		hci_conn_del(conn);
@@ -5269,7 +5312,7 @@ static struct hci_conn *check_pending_le_conn(struct hci_dev *hdev,
 		case HCI_AUTO_CONN_ALWAYS:
 			/* Devices advertising with ADV_IND or ADV_DIRECT_IND
 			 * are triggering a connection attempt. This means
-			 * that incoming connectioms from slave device are
+			 * that incoming connections from slave device are
 			 * accepted and also outgoing connections to slave
 			 * devices are established when found.
 			 */
@@ -5353,7 +5396,8 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
 
 	/* Adjust for actual length */
 	if (len != real_len) {
-		bt_dev_err_ratelimited(hdev, "advertising data len corrected");
+		bt_dev_err_ratelimited(hdev, "advertising data len corrected %u -> %u",
+				       len, real_len);
 		len = real_len;
 	}
 
@@ -6145,6 +6189,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
 		hci_num_comp_blocks_evt(hdev, skb);
 		break;
 
+	case HCI_EV_VENDOR:
+		msft_vendor_evt(hdev, skb);
+		break;
+
 	default:
 		BT_DBG("%s event 0x%2.2x", hdev->name, event);
 		break;
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
index 649e1e5ed446..9ea40106ef17 100644
--- a/net/bluetooth/hci_request.c
+++ b/net/bluetooth/hci_request.c
@@ -2723,6 +2723,8 @@ static int active_scan(struct hci_request *req, unsigned long opt)
 	uint16_t interval = opt;
 	struct hci_dev *hdev = req->hdev;
 	u8 own_addr_type;
+	/* White list is not used for discovery */
+	u8 filter_policy = 0x00;
 	int err;
 
 	BT_DBG("%s", hdev->name);
@@ -2744,7 +2746,7 @@ static int active_scan(struct hci_request *req, unsigned long opt)
 		own_addr_type = ADDR_LE_DEV_PUBLIC;
 
 	hci_req_start_scan(req, LE_SCAN_ACTIVE, interval, DISCOV_LE_SCAN_WIN,
-			   own_addr_type, 0);
+			   own_addr_type, filter_policy);
 	return 0;
 }
 
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 117ba20ea194..1cea42ee1e92 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -395,6 +395,24 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr,
 	return sizeof(struct sockaddr_l2);
 }
 
+static int l2cap_get_mode(struct l2cap_chan *chan)
+{
+	switch (chan->mode) {
+	case L2CAP_MODE_BASIC:
+		return BT_MODE_BASIC;
+	case L2CAP_MODE_ERTM:
+		return BT_MODE_ERTM;
+	case L2CAP_MODE_STREAMING:
+		return BT_MODE_STREAMING;
+	case L2CAP_MODE_LE_FLOWCTL:
+		return BT_MODE_LE_FLOWCTL;
+	case L2CAP_MODE_EXT_FLOWCTL:
+		return BT_MODE_EXT_FLOWCTL;
+	}
+
+	return -EINVAL;
+}
+
 static int l2cap_sock_getsockopt_old(struct socket *sock, int optname,
 				     char __user *optval, int __user *optlen)
 {
@@ -424,6 +442,20 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname,
 			break;
 		}
 
+		/* Only BR/EDR modes are supported here */
+		switch (chan->mode) {
+		case L2CAP_MODE_BASIC:
+		case L2CAP_MODE_ERTM:
+		case L2CAP_MODE_STREAMING:
+			break;
+		default:
+			err = -EINVAL;
+			break;
+		}
+
+		if (err < 0)
+			break;
+
 		memset(&opts, 0, sizeof(opts));
 		opts.imtu     = chan->imtu;
 		opts.omtu     = chan->omtu;
@@ -508,7 +540,7 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname,
 	struct bt_security sec;
 	struct bt_power pwr;
 	u32 phys;
-	int len, err = 0;
+	int len, mode, err = 0;
 
 	BT_DBG("sk %p", sk);
 
@@ -624,6 +656,27 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname,
 			err = -EFAULT;
 		break;
 
+	case BT_MODE:
+		if (!enable_ecred) {
+			err = -ENOPROTOOPT;
+			break;
+		}
+
+		if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
+			err = -EINVAL;
+			break;
+		}
+
+		mode = l2cap_get_mode(chan);
+		if (mode < 0) {
+			err = mode;
+			break;
+		}
+
+		if (put_user(mode, (u8 __user *) optval))
+			err = -EFAULT;
+		break;
+
 	default:
 		err = -ENOPROTOOPT;
 		break;
@@ -698,10 +751,8 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname,
 			break;
 		}
 
-		chan->mode = opts.mode;
-		switch (chan->mode) {
-		case L2CAP_MODE_LE_FLOWCTL:
-			break;
+		/* Only BR/EDR modes are supported here */
+		switch (opts.mode) {
 		case L2CAP_MODE_BASIC:
 			clear_bit(CONF_STATE2_DEVICE, &chan->conf_state);
 			break;
@@ -715,6 +766,11 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname,
 			break;
 		}
 
+		if (err < 0)
+			break;
+
+		chan->mode = opts.mode;
+
 		BT_DBG("mode 0x%2.2x", chan->mode);
 
 		chan->imtu = opts.imtu;
@@ -763,6 +819,45 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname,
 	return err;
 }
 
+static int l2cap_set_mode(struct l2cap_chan *chan, u8 mode)
+{
+	switch (mode) {
+	case BT_MODE_BASIC:
+		if (bdaddr_type_is_le(chan->src_type))
+			return -EINVAL;
+		mode = L2CAP_MODE_BASIC;
+		clear_bit(CONF_STATE2_DEVICE, &chan->conf_state);
+		break;
+	case BT_MODE_ERTM:
+		if (!disable_ertm || bdaddr_type_is_le(chan->src_type))
+			return -EINVAL;
+		mode = L2CAP_MODE_ERTM;
+		break;
+	case BT_MODE_STREAMING:
+		if (!disable_ertm || bdaddr_type_is_le(chan->src_type))
+			return -EINVAL;
+		mode = L2CAP_MODE_STREAMING;
+		break;
+	case BT_MODE_LE_FLOWCTL:
+		if (!bdaddr_type_is_le(chan->src_type))
+			return -EINVAL;
+		mode = L2CAP_MODE_LE_FLOWCTL;
+		break;
+	case BT_MODE_EXT_FLOWCTL:
+		/* TODO: Add support for ECRED PDUs to BR/EDR */
+		if (!bdaddr_type_is_le(chan->src_type))
+			return -EINVAL;
+		mode = L2CAP_MODE_EXT_FLOWCTL;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	chan->mode = mode;
+
+	return 0;
+}
+
 static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
 				 char __user *optval, unsigned int optlen)
 {
@@ -968,6 +1063,39 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
 
 		break;
 
+	case BT_MODE:
+		if (!enable_ecred) {
+			err = -ENOPROTOOPT;
+			break;
+		}
+
+		BT_DBG("sk->sk_state %u", sk->sk_state);
+
+		if (sk->sk_state != BT_BOUND) {
+			err = -EINVAL;
+			break;
+		}
+
+		if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
+			err = -EINVAL;
+			break;
+		}
+
+		if (get_user(opt, (u8 __user *) optval)) {
+			err = -EFAULT;
+			break;
+		}
+
+		BT_DBG("opt %u", opt);
+
+		err = l2cap_set_mode(chan, opt);
+		if (err)
+			break;
+
+		BT_DBG("mode 0x%2.2x", chan->mode);
+
+		break;
+
 	default:
 		err = -ENOPROTOOPT;
 		break;
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 6552003a170e..f8c0a4fc8090 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -38,7 +38,7 @@
 #include "mgmt_util.h"
 
 #define MGMT_VERSION	1
-#define MGMT_REVISION	16
+#define MGMT_REVISION	17
 
 static const u16 mgmt_commands[] = {
 	MGMT_OP_READ_INDEX_LIST,
@@ -108,6 +108,7 @@ static const u16 mgmt_commands[] = {
 	MGMT_OP_SET_APPEARANCE,
 	MGMT_OP_SET_BLOCKED_KEYS,
 	MGMT_OP_SET_WIDEBAND_SPEECH,
+	MGMT_OP_READ_SECURITY_INFO,
 };
 
 static const u16 mgmt_events[] = {
@@ -155,6 +156,7 @@ static const u16 mgmt_untrusted_commands[] = {
 	MGMT_OP_READ_CONFIG_INFO,
 	MGMT_OP_READ_EXT_INDEX_LIST,
 	MGMT_OP_READ_EXT_INFO,
+	MGMT_OP_READ_SECURITY_INFO,
 };
 
 static const u16 mgmt_untrusted_events[] = {
@@ -3659,6 +3661,55 @@ static int set_wideband_speech(struct sock *sk, struct hci_dev *hdev,
 	return err;
 }
 
+static int read_security_info(struct sock *sk, struct hci_dev *hdev,
+			      void *data, u16 data_len)
+{
+	char buf[16];
+	struct mgmt_rp_read_security_info *rp = (void *)buf;
+	u16 sec_len = 0;
+	u8 flags = 0;
+
+	bt_dev_dbg(hdev, "sock %p", sk);
+
+	memset(&buf, 0, sizeof(buf));
+
+	hci_dev_lock(hdev);
+
+	/* When the Read Simple Pairing Options command is supported, then
+	 * the remote public key validation is supported.
+	 */
+	if (hdev->commands[41] & 0x08)
+		flags |= 0x01;	/* Remote public key validation (BR/EDR) */
+
+	flags |= 0x02;		/* Remote public key validation (LE) */
+
+	/* When the Read Encryption Key Size command is supported, then the
+	 * encryption key size is enforced.
+	 */
+	if (hdev->commands[20] & 0x10)
+		flags |= 0x04;	/* Encryption key size enforcement (BR/EDR) */
+
+	flags |= 0x08;		/* Encryption key size enforcement (LE) */
+
+	sec_len = eir_append_data(rp->sec, sec_len, 0x01, &flags, 1);
+
+	/* When the Read Simple Pairing Options command is supported, then
+	 * also max encryption key size information is provided.
+	 */
+	if (hdev->commands[41] & 0x08)
+		sec_len = eir_append_le16(rp->sec, sec_len, 0x02,
+					  hdev->max_enc_key_size);
+
+	sec_len = eir_append_le16(rp->sec, sec_len, 0x03, SMP_MAX_ENC_KEY_SIZE);
+
+	rp->sec_len = cpu_to_le16(sec_len);
+
+	hci_dev_unlock(hdev);
+
+	return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_READ_SECURITY_INFO, 0,
+				 rp, sizeof(*rp) + sec_len);
+}
+
 static void read_local_oob_data_complete(struct hci_dev *hdev, u8 status,
 				         u16 opcode, struct sk_buff *skb)
 {
@@ -7099,6 +7150,8 @@ static const struct hci_mgmt_handler mgmt_handlers[] = {
 	{ set_blocked_keys,	   MGMT_OP_SET_BLOCKED_KEYS_SIZE,
 						HCI_MGMT_VAR_LEN },
 	{ set_wideband_speech,	   MGMT_SETTING_SIZE },
+	{ read_security_info,      MGMT_READ_SECURITY_INFO_SIZE,
+						HCI_MGMT_UNTRUSTED },
 };
 
 void mgmt_index_added(struct hci_dev *hdev)
diff --git a/net/bluetooth/msft.c b/net/bluetooth/msft.c
new file mode 100644
index 000000000000..d6c4e6b5ae77
--- /dev/null
+++ b/net/bluetooth/msft.c
@@ -0,0 +1,141 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2020 Google Corporation
+ */
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+
+#include "msft.h"
+
+#define MSFT_OP_READ_SUPPORTED_FEATURES		0x00
+struct msft_cp_read_supported_features {
+	__u8   sub_opcode;
+} __packed;
+struct msft_rp_read_supported_features {
+	__u8   status;
+	__u8   sub_opcode;
+	__le64 features;
+	__u8   evt_prefix_len;
+	__u8   evt_prefix[0];
+} __packed;
+
+struct msft_data {
+	__u64 features;
+	__u8  evt_prefix_len;
+	__u8  *evt_prefix;
+};
+
+static bool read_supported_features(struct hci_dev *hdev,
+				    struct msft_data *msft)
+{
+	struct msft_cp_read_supported_features cp;
+	struct msft_rp_read_supported_features *rp;
+	struct sk_buff *skb;
+
+	cp.sub_opcode = MSFT_OP_READ_SUPPORTED_FEATURES;
+
+	skb = __hci_cmd_sync(hdev, hdev->msft_opcode, sizeof(cp), &cp,
+			     HCI_CMD_TIMEOUT);
+	if (IS_ERR(skb)) {
+		bt_dev_err(hdev, "Failed to read MSFT supported features (%ld)",
+			   PTR_ERR(skb));
+		return false;
+	}
+
+	if (skb->len < sizeof(*rp)) {
+		bt_dev_err(hdev, "MSFT supported features length mismatch");
+		goto failed;
+	}
+
+	rp = (struct msft_rp_read_supported_features *)skb->data;
+
+	if (rp->sub_opcode != MSFT_OP_READ_SUPPORTED_FEATURES)
+		goto failed;
+
+	if (rp->evt_prefix_len > 0) {
+		msft->evt_prefix = kmemdup(rp->evt_prefix, rp->evt_prefix_len,
+					   GFP_KERNEL);
+		if (!msft->evt_prefix)
+			goto failed;
+	}
+
+	msft->evt_prefix_len = rp->evt_prefix_len;
+	msft->features = __le64_to_cpu(rp->features);
+
+	kfree_skb(skb);
+	return true;
+
+failed:
+	kfree_skb(skb);
+	return false;
+}
+
+void msft_do_open(struct hci_dev *hdev)
+{
+	struct msft_data *msft;
+
+	if (hdev->msft_opcode == HCI_OP_NOP)
+		return;
+
+	bt_dev_dbg(hdev, "Initialize MSFT extension");
+
+	msft = kzalloc(sizeof(*msft), GFP_KERNEL);
+	if (!msft)
+		return;
+
+	if (!read_supported_features(hdev, msft)) {
+		kfree(msft);
+		return;
+	}
+
+	hdev->msft_data = msft;
+}
+
+void msft_do_close(struct hci_dev *hdev)
+{
+	struct msft_data *msft = hdev->msft_data;
+
+	if (!msft)
+		return;
+
+	bt_dev_dbg(hdev, "Cleanup of MSFT extension");
+
+	hdev->msft_data = NULL;
+
+	kfree(msft->evt_prefix);
+	kfree(msft);
+}
+
+void msft_vendor_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct msft_data *msft = hdev->msft_data;
+	u8 event;
+
+	if (!msft)
+		return;
+
+	/* When the extension has defined an event prefix, check that it
+	 * matches, and otherwise just return.
+	 */
+	if (msft->evt_prefix_len > 0) {
+		if (skb->len < msft->evt_prefix_len)
+			return;
+
+		if (memcmp(skb->data, msft->evt_prefix, msft->evt_prefix_len))
+			return;
+
+		skb_pull(skb, msft->evt_prefix_len);
+	}
+
+	/* Every event starts at least with an event code and the rest of
+	 * the data is variable and depends on the event code.
+	 */
+	if (skb->len < 1)
+		return;
+
+	event = *skb->data;
+	skb_pull(skb, 1);
+
+	bt_dev_dbg(hdev, "MSFT vendor event %u", event);
+}
diff --git a/net/bluetooth/msft.h b/net/bluetooth/msft.h
new file mode 100644
index 000000000000..5aa9130e1f8a
--- /dev/null
+++ b/net/bluetooth/msft.h
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2020 Google Corporation
+ */
+
+#if IS_ENABLED(CONFIG_BT_MSFTEXT)
+
+void msft_do_open(struct hci_dev *hdev);
+void msft_do_close(struct hci_dev *hdev);
+void msft_vendor_evt(struct hci_dev *hdev, struct sk_buff *skb);
+
+#else
+
+static inline void msft_do_open(struct hci_dev *hdev) {}
+static inline void msft_do_close(struct hci_dev *hdev) {}
+static inline void msft_vendor_evt(struct hci_dev *hdev, struct sk_buff *skb) {}
+
+#endif
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 1476a91ce935..df22cbf94693 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -854,7 +854,7 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
 	struct l2cap_chan *chan = conn->smp;
 	struct smp_chan *smp = chan->data;
 	u32 passkey = 0;
-	int ret = 0;
+	int ret;
 
 	/* Initialize key for JUST WORKS */
 	memset(smp->tk, 0, sizeof(smp->tk));
@@ -883,9 +883,16 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
 	    hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
 		smp->method = JUST_WORKS;
 
-	/* If Just Works, Continue with Zero TK */
+	/* If Just Works, Continue with Zero TK and ask user-space for
+	 * confirmation */
 	if (smp->method == JUST_WORKS) {
-		set_bit(SMP_FLAG_TK_VALID, &smp->flags);
+		ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
+						hcon->type,
+						hcon->dst_type,
+						passkey, 1);
+		if (ret)
+			return ret;
+		set_bit(SMP_FLAG_WAIT_USER, &smp->flags);
 		return 0;
 	}
 
@@ -2194,7 +2201,7 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
 	if (err)
 		return SMP_UNSPECIFIED;
 
-	if (smp->method == JUST_WORKS || smp->method == REQ_OOB) {
+	if (smp->method == REQ_OOB) {
 		if (hcon->out) {
 			sc_dhkey_check(smp);
 			SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
@@ -2209,6 +2216,9 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
 	confirm_hint = 0;
 
 confirm:
+	if (smp->method == JUST_WORKS)
+		confirm_hint = 1;
+
 	err = mgmt_user_confirm_request(hcon->hdev, &hcon->dst, hcon->type,
 					hcon->dst_type, passkey, confirm_hint);
 	if (err)
@@ -2385,12 +2395,17 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
 			authreq |= SMP_AUTH_CT2;
 	}
 
-	/* Require MITM if IO Capability allows or the security level
-	 * requires it.
+	/* Don't attempt to set MITM if setting is overridden by debugfs
+	 * Needed to pass certification test SM/MAS/PKE/BV-01-C
 	 */
-	if (hcon->io_capability != HCI_IO_NO_INPUT_OUTPUT ||
-	    hcon->pending_sec_level > BT_SECURITY_MEDIUM)
-		authreq |= SMP_AUTH_MITM;
+	if (!hci_dev_test_flag(hcon->hdev, HCI_FORCE_NO_MITM)) {
+		/* Require MITM if IO Capability allows or the security level
+		 * requires it.
+		 */
+		if (hcon->io_capability != HCI_IO_NO_INPUT_OUTPUT ||
+		    hcon->pending_sec_level > BT_SECURITY_MEDIUM)
+			authreq |= SMP_AUTH_MITM;
+	}
 
 	if (hcon->role == HCI_ROLE_MASTER) {
 		struct smp_cmd_pairing cp;
diff --git a/net/core/dev.c b/net/core/dev.c
index 9c9e763bfe0e..522288177bbd 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4140,7 +4140,8 @@ EXPORT_SYMBOL(netdev_max_backlog);
 
 int netdev_tstamp_prequeue __read_mostly = 1;
 int netdev_budget __read_mostly = 300;
-unsigned int __read_mostly netdev_budget_usecs = 2000;
+/* Must be at least 2 jiffes to guarantee 1 jiffy timeout */
+unsigned int __read_mostly netdev_budget_usecs = 2 * USEC_PER_SEC / HZ;
 int weight_p __read_mostly = 64;           /* old backlog weight */
 int dev_weight_rx_bias __read_mostly = 1;  /* bias for backlog weight */
 int dev_weight_tx_bias __read_mostly = 1;  /* bias for output_queue quota */
@@ -8666,8 +8667,8 @@ int dev_change_xdp_fd(struct net_device *dev, struct netlink_ext_ack *extack,
 	const struct net_device_ops *ops = dev->netdev_ops;
 	enum bpf_netdev_command query;
 	u32 prog_id, expected_id = 0;
-	struct bpf_prog *prog = NULL;
 	bpf_op_t bpf_op, bpf_chk;
+	struct bpf_prog *prog;
 	bool offload;
 	int err;
 
@@ -8733,6 +8734,7 @@ int dev_change_xdp_fd(struct net_device *dev, struct netlink_ext_ack *extack,
 	} else {
 		if (!prog_id)
 			return 0;
+		prog = NULL;
 	}
 
 	err = dev_xdp_install(dev, bpf_op, extack, flags, prog);
diff --git a/net/core/filter.c b/net/core/filter.c
index 7628b947dbc3..7d6ceaa54d21 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -5925,7 +5925,7 @@ BPF_CALL_3(bpf_sk_assign, struct sk_buff *, skb, struct sock *, sk, u64, flags)
 		return -EOPNOTSUPP;
 	if (unlikely(dev_net(skb->dev) != sock_net(sk)))
 		return -ENETUNREACH;
-	if (unlikely(sk->sk_reuseport))
+	if (unlikely(sk_fullsock(sk) && sk->sk_reuseport))
 		return -ESOCKTNOSUPPORT;
 	if (sk_is_refcounted(sk) &&
 	    unlikely(!refcount_inc_not_zero(&sk->sk_refcnt)))
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index cf0215734ceb..4773ad6ec111 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -80,7 +80,7 @@ static ssize_t netdev_store(struct device *dev, struct device_attribute *attr,
 	struct net_device *netdev = to_net_dev(dev);
 	struct net *net = dev_net(netdev);
 	unsigned long new;
-	int ret = -EINVAL;
+	int ret;
 
 	if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
 		return -EPERM;
diff --git a/net/core/sock.c b/net/core/sock.c
index ce1d8dce9b7a..90509c37d291 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1872,7 +1872,7 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
 		 * as not suitable for copying when cloning.
 		 */
 		if (sk_user_data_is_nocopy(newsk))
-			RCU_INIT_POINTER(newsk->sk_user_data, NULL);
+			newsk->sk_user_data = NULL;
 
 		newsk->sk_err	   = 0;
 		newsk->sk_err_soft = 0;
diff --git a/net/dsa/port.c b/net/dsa/port.c
index 231b2d494f1c..a58fdd362574 100644
--- a/net/dsa/port.c
+++ b/net/dsa/port.c
@@ -670,11 +670,16 @@ int dsa_port_link_register_of(struct dsa_port *dp)
 {
 	struct dsa_switch *ds = dp->ds;
 	struct device_node *phy_np;
+	int port = dp->index;
 
 	if (!ds->ops->adjust_link) {
 		phy_np = of_parse_phandle(dp->dn, "phy-handle", 0);
-		if (of_phy_is_fixed_link(dp->dn) || phy_np)
+		if (of_phy_is_fixed_link(dp->dn) || phy_np) {
+			if (ds->ops->phylink_mac_link_down)
+				ds->ops->phylink_mac_link_down(ds, port,
+					MLO_AN_FIXED, PHY_INTERFACE_MODE_NA);
 			return dsa_port_phylink_register(dp);
+		}
 		return 0;
 	}
 
diff --git a/net/hsr/hsr_netlink.c b/net/hsr/hsr_netlink.c
index 5465a395da04..1decb25f6764 100644
--- a/net/hsr/hsr_netlink.c
+++ b/net/hsr/hsr_netlink.c
@@ -69,10 +69,16 @@ static int hsr_newlink(struct net *src_net, struct net_device *dev,
 	else
 		multicast_spec = nla_get_u8(data[IFLA_HSR_MULTICAST_SPEC]);
 
-	if (!data[IFLA_HSR_VERSION])
+	if (!data[IFLA_HSR_VERSION]) {
 		hsr_version = 0;
-	else
+	} else {
 		hsr_version = nla_get_u8(data[IFLA_HSR_VERSION]);
+		if (hsr_version > 1) {
+			NL_SET_ERR_MSG_MOD(extack,
+					   "Only versions 0..1 are supported");
+			return -EINVAL;
+		}
+	}
 
 	return hsr_dev_finalize(dev, link, multicast_spec, hsr_version, extack);
 }
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 30fa42f5997d..c0dd561aa190 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -614,12 +614,15 @@ struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, __be32 prefix,
 	return NULL;
 }
 
-static int ip_mc_config(struct sock *sk, bool join, const struct in_ifaddr *ifa)
+static int ip_mc_autojoin_config(struct net *net, bool join,
+				 const struct in_ifaddr *ifa)
 {
+#if defined(CONFIG_IP_MULTICAST)
 	struct ip_mreqn mreq = {
 		.imr_multiaddr.s_addr = ifa->ifa_address,
 		.imr_ifindex = ifa->ifa_dev->dev->ifindex,
 	};
+	struct sock *sk = net->ipv4.mc_autojoin_sk;
 	int ret;
 
 	ASSERT_RTNL();
@@ -632,6 +635,9 @@ static int ip_mc_config(struct sock *sk, bool join, const struct in_ifaddr *ifa)
 	release_sock(sk);
 
 	return ret;
+#else
+	return -EOPNOTSUPP;
+#endif
 }
 
 static int inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh,
@@ -675,7 +681,7 @@ static int inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh,
 			continue;
 
 		if (ipv4_is_multicast(ifa->ifa_address))
-			ip_mc_config(net->ipv4.mc_autojoin_sk, false, ifa);
+			ip_mc_autojoin_config(net, false, ifa);
 		__inet_del_ifa(in_dev, ifap, 1, nlh, NETLINK_CB(skb).portid);
 		return 0;
 	}
@@ -940,8 +946,7 @@ static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh,
 		 */
 		set_ifa_lifetime(ifa, valid_lft, prefered_lft);
 		if (ifa->ifa_flags & IFA_F_MCAUTOJOIN) {
-			int ret = ip_mc_config(net->ipv4.mc_autojoin_sk,
-					       true, ifa);
+			int ret = ip_mc_autojoin_config(net, true, ifa);
 
 			if (ret < 0) {
 				inet_free_ifa(ifa);
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 6d87de434377..776df97ac683 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1734,14 +1734,48 @@ int tcp_mmap(struct file *file, struct socket *sock,
 }
 EXPORT_SYMBOL(tcp_mmap);
 
+static int tcp_zerocopy_vm_insert_batch(struct vm_area_struct *vma,
+					struct page **pages,
+					unsigned long pages_to_map,
+					unsigned long *insert_addr,
+					u32 *length_with_pending,
+					u32 *seq,
+					struct tcp_zerocopy_receive *zc)
+{
+	unsigned long pages_remaining = pages_to_map;
+	int bytes_mapped;
+	int ret;
+
+	ret = vm_insert_pages(vma, *insert_addr, pages, &pages_remaining);
+	bytes_mapped = PAGE_SIZE * (pages_to_map - pages_remaining);
+	/* Even if vm_insert_pages fails, it may have partially succeeded in
+	 * mapping (some but not all of the pages).
+	 */
+	*seq += bytes_mapped;
+	*insert_addr += bytes_mapped;
+	if (ret) {
+		/* But if vm_insert_pages did fail, we have to unroll some state
+		 * we speculatively touched before.
+		 */
+		const int bytes_not_mapped = PAGE_SIZE * pages_remaining;
+		*length_with_pending -= bytes_not_mapped;
+		zc->recv_skip_hint += bytes_not_mapped;
+	}
+	return ret;
+}
+
 static int tcp_zerocopy_receive(struct sock *sk,
 				struct tcp_zerocopy_receive *zc)
 {
 	unsigned long address = (unsigned long)zc->address;
 	u32 length = 0, seq, offset, zap_len;
+	#define PAGE_BATCH_SIZE 8
+	struct page *pages[PAGE_BATCH_SIZE];
 	const skb_frag_t *frags = NULL;
 	struct vm_area_struct *vma;
 	struct sk_buff *skb = NULL;
+	unsigned long pg_idx = 0;
+	unsigned long curr_addr;
 	struct tcp_sock *tp;
 	int inq;
 	int ret;
@@ -1754,6 +1788,8 @@ static int tcp_zerocopy_receive(struct sock *sk,
 
 	sock_rps_record_flow(sk);
 
+	tp = tcp_sk(sk);
+
 	down_read(&current->mm->mmap_sem);
 
 	ret = -EINVAL;
@@ -1762,7 +1798,6 @@ static int tcp_zerocopy_receive(struct sock *sk,
 		goto out;
 	zc->length = min_t(unsigned long, zc->length, vma->vm_end - address);
 
-	tp = tcp_sk(sk);
 	seq = tp->copied_seq;
 	inq = tcp_inq(sk);
 	zc->length = min_t(u32, zc->length, inq);
@@ -1774,8 +1809,20 @@ static int tcp_zerocopy_receive(struct sock *sk,
 		zc->recv_skip_hint = zc->length;
 	}
 	ret = 0;
+	curr_addr = address;
 	while (length + PAGE_SIZE <= zc->length) {
 		if (zc->recv_skip_hint < PAGE_SIZE) {
+			/* If we're here, finish the current batch. */
+			if (pg_idx) {
+				ret = tcp_zerocopy_vm_insert_batch(vma, pages,
+								   pg_idx,
+								   &curr_addr,
+								   &length,
+								   &seq, zc);
+				if (ret)
+					goto out;
+				pg_idx = 0;
+			}
 			if (skb) {
 				if (zc->recv_skip_hint > 0)
 					break;
@@ -1784,7 +1831,6 @@ static int tcp_zerocopy_receive(struct sock *sk,
 			} else {
 				skb = tcp_recv_skb(sk, seq, &offset);
 			}
-
 			zc->recv_skip_hint = skb->len - offset;
 			offset -= skb_headlen(skb);
 			if ((int)offset < 0 || skb_has_frag_list(skb))
@@ -1808,14 +1854,24 @@ static int tcp_zerocopy_receive(struct sock *sk,
 			zc->recv_skip_hint -= remaining;
 			break;
 		}
-		ret = vm_insert_page(vma, address + length,
-				     skb_frag_page(frags));
-		if (ret)
-			break;
+		pages[pg_idx] = skb_frag_page(frags);
+		pg_idx++;
 		length += PAGE_SIZE;
-		seq += PAGE_SIZE;
 		zc->recv_skip_hint -= PAGE_SIZE;
 		frags++;
+		if (pg_idx == PAGE_BATCH_SIZE) {
+			ret = tcp_zerocopy_vm_insert_batch(vma, pages, pg_idx,
+							   &curr_addr, &length,
+							   &seq, zc);
+			if (ret)
+				goto out;
+			pg_idx = 0;
+		}
+	}
+	if (pg_idx) {
+		ret = tcp_zerocopy_vm_insert_batch(vma, pages, pg_idx,
+						   &curr_addr, &length, &seq,
+						   zc);
 	}
 out:
 	up_read(&current->mm->mmap_sem);
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 2688f3e82165..fc5000370030 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -229,6 +229,25 @@ static bool icmpv6_xrlim_allow(struct sock *sk, u8 type,
 	return res;
 }
 
+static bool icmpv6_rt_has_prefsrc(struct sock *sk, u8 type,
+				  struct flowi6 *fl6)
+{
+	struct net *net = sock_net(sk);
+	struct dst_entry *dst;
+	bool res = false;
+
+	dst = ip6_route_output(net, sk, fl6);
+	if (!dst->error) {
+		struct rt6_info *rt = (struct rt6_info *)dst;
+		struct in6_addr prefsrc;
+
+		rt6_get_prefsrc(rt, &prefsrc);
+		res = !ipv6_addr_any(&prefsrc);
+	}
+	dst_release(dst);
+	return res;
+}
+
 /*
  *	an inline helper for the "simple" if statement below
  *	checks if parameter problem report is caused by an
@@ -527,7 +546,7 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
 		saddr = force_saddr;
 	if (saddr) {
 		fl6.saddr = *saddr;
-	} else {
+	} else if (!icmpv6_rt_has_prefsrc(sk, type, &fl6)) {
 		/* select a more meaningful saddr from input if */
 		struct net_device *in_netdev;
 
diff --git a/net/ipv6/seg6.c b/net/ipv6/seg6.c
index 75421a472d25..4c7e0a27fa9c 100644
--- a/net/ipv6/seg6.c
+++ b/net/ipv6/seg6.c
@@ -434,7 +434,7 @@ static struct genl_family seg6_genl_family __ro_after_init = {
 
 int __init seg6_init(void)
 {
-	int err = -ENOMEM;
+	int err;
 
 	err = genl_register_family(&seg6_genl_family);
 	if (err)
diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c
index f5a9bdc4980c..ebb381c3f1b9 100644
--- a/net/l2tp/l2tp_netlink.c
+++ b/net/l2tp/l2tp_netlink.c
@@ -920,51 +920,51 @@ static const struct genl_ops l2tp_nl_ops[] = {
 		.cmd = L2TP_CMD_TUNNEL_CREATE,
 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 		.doit = l2tp_nl_cmd_tunnel_create,
-		.flags = GENL_ADMIN_PERM,
+		.flags = GENL_UNS_ADMIN_PERM,
 	},
 	{
 		.cmd = L2TP_CMD_TUNNEL_DELETE,
 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 		.doit = l2tp_nl_cmd_tunnel_delete,
-		.flags = GENL_ADMIN_PERM,
+		.flags = GENL_UNS_ADMIN_PERM,
 	},
 	{
 		.cmd = L2TP_CMD_TUNNEL_MODIFY,
 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 		.doit = l2tp_nl_cmd_tunnel_modify,
-		.flags = GENL_ADMIN_PERM,
+		.flags = GENL_UNS_ADMIN_PERM,
 	},
 	{
 		.cmd = L2TP_CMD_TUNNEL_GET,
 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 		.doit = l2tp_nl_cmd_tunnel_get,
 		.dumpit = l2tp_nl_cmd_tunnel_dump,
-		.flags = GENL_ADMIN_PERM,
+		.flags = GENL_UNS_ADMIN_PERM,
 	},
 	{
 		.cmd = L2TP_CMD_SESSION_CREATE,
 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 		.doit = l2tp_nl_cmd_session_create,
-		.flags = GENL_ADMIN_PERM,
+		.flags = GENL_UNS_ADMIN_PERM,
 	},
 	{
 		.cmd = L2TP_CMD_SESSION_DELETE,
 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 		.doit = l2tp_nl_cmd_session_delete,
-		.flags = GENL_ADMIN_PERM,
+		.flags = GENL_UNS_ADMIN_PERM,
 	},
 	{
 		.cmd = L2TP_CMD_SESSION_MODIFY,
 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 		.doit = l2tp_nl_cmd_session_modify,
-		.flags = GENL_ADMIN_PERM,
+		.flags = GENL_UNS_ADMIN_PERM,
 	},
 	{
 		.cmd = L2TP_CMD_SESSION_GET,
 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 		.doit = l2tp_nl_cmd_session_get,
 		.dumpit = l2tp_nl_cmd_session_dump,
-		.flags = GENL_ADMIN_PERM,
+		.flags = GENL_UNS_ADMIN_PERM,
 	},
 };
 
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 8345926193de..0e9ad60fb2b3 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -1069,7 +1069,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
 		local->hw.wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC;
 		if (hw->max_signal <= 0) {
 			result = -EINVAL;
-			goto fail_wiphy_register;
+			goto fail_workqueue;
 		}
 	}
 
@@ -1135,7 +1135,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
 
 	result = ieee80211_init_cipher_suites(local);
 	if (result < 0)
-		goto fail_wiphy_register;
+		goto fail_workqueue;
 
 	if (!local->ops->remain_on_channel)
 		local->hw.wiphy->max_remain_on_channel_duration = 5000;
@@ -1161,10 +1161,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
 
 	local->hw.wiphy->max_num_csa_counters = IEEE80211_MAX_CSA_COUNTERS_NUM;
 
-	result = wiphy_register(local->hw.wiphy);
-	if (result < 0)
-		goto fail_wiphy_register;
-
 	/*
 	 * We use the number of queues for feature tests (QoS, HT) internally
 	 * so restrict them appropriately.
@@ -1217,9 +1213,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
 		goto fail_flows;
 
 	rtnl_lock();
-
 	result = ieee80211_init_rate_ctrl_alg(local,
 					      hw->rate_control_algorithm);
+	rtnl_unlock();
 	if (result < 0) {
 		wiphy_debug(local->hw.wiphy,
 			    "Failed to initialize rate control algorithm\n");
@@ -1273,6 +1269,12 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
 		local->sband_allocated |= BIT(band);
 	}
 
+	result = wiphy_register(local->hw.wiphy);
+	if (result < 0)
+		goto fail_wiphy_register;
+
+	rtnl_lock();
+
 	/* add one default STA interface if supported */
 	if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION) &&
 	    !ieee80211_hw_check(hw, NO_AUTO_VIF)) {
@@ -1312,17 +1314,17 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
 #if defined(CONFIG_INET) || defined(CONFIG_IPV6)
  fail_ifa:
 #endif
+	wiphy_unregister(local->hw.wiphy);
+ fail_wiphy_register:
 	rtnl_lock();
 	rate_control_deinitialize(local);
 	ieee80211_remove_interfaces(local);
- fail_rate:
 	rtnl_unlock();
+ fail_rate:
  fail_flows:
 	ieee80211_led_exit(local);
 	destroy_workqueue(local->workqueue);
  fail_workqueue:
-	wiphy_unregister(local->hw.wiphy);
- fail_wiphy_register:
 	if (local->wiphy_ciphers_allocated)
 		kfree(local->hw.wiphy->cipher_suites);
 	kfree(local->int_scan_req);
@@ -1372,8 +1374,8 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
 	skb_queue_purge(&local->skb_queue_unreliable);
 	skb_queue_purge(&local->skb_queue_tdls_chsw);
 
-	destroy_workqueue(local->workqueue);
 	wiphy_unregister(local->hw.wiphy);
+	destroy_workqueue(local->workqueue);
 	ieee80211_led_exit(local);
 	kfree(local->int_scan_req);
 }
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index d09b3c789314..36978a0e5000 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -1257,15 +1257,15 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
 		    sdata->u.mesh.mshcfg.rssi_threshold < rx_status->signal)
 			mesh_neighbour_update(sdata, mgmt->sa, &elems,
 					      rx_status);
+
+		if (ifmsh->csa_role != IEEE80211_MESH_CSA_ROLE_INIT &&
+		    !sdata->vif.csa_active)
+			ieee80211_mesh_process_chnswitch(sdata, &elems, true);
 	}
 
 	if (ifmsh->sync_ops)
 		ifmsh->sync_ops->rx_bcn_presp(sdata,
 			stype, mgmt, &elems, rx_status);
-
-	if (ifmsh->csa_role != IEEE80211_MESH_CSA_ROLE_INIT &&
-	    !sdata->vif.csa_active)
-		ieee80211_mesh_process_chnswitch(sdata, &elems, true);
 }
 
 int ieee80211_mesh_finish_csa(struct ieee80211_sub_if_data *sdata)
@@ -1373,6 +1373,9 @@ static void mesh_rx_csa_frame(struct ieee80211_sub_if_data *sdata,
 	ieee802_11_parse_elems(pos, len - baselen, true, &elems,
 			       mgmt->bssid, NULL);
 
+	if (!mesh_matches_local(sdata, &elems))
+		return;
+
 	ifmsh->chsw_ttl = elems.mesh_chansw_params_ie->mesh_ttl;
 	if (!--ifmsh->chsw_ttl)
 		fwd_csa = false;
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 939a5045181a..9936e33ac351 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -97,12 +97,7 @@ static struct socket *__mptcp_tcp_fallback(struct mptcp_sock *msk)
 	if (likely(!__mptcp_needs_tcp_fallback(msk)))
 		return NULL;
 
-	if (msk->subflow) {
-		release_sock((struct sock *)msk);
-		return msk->subflow;
-	}
-
-	return NULL;
+	return msk->subflow;
 }
 
 static bool __mptcp_can_create_subflow(const struct mptcp_sock *msk)
@@ -734,9 +729,10 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 			goto out;
 	}
 
+fallback:
 	ssock = __mptcp_tcp_fallback(msk);
 	if (unlikely(ssock)) {
-fallback:
+		release_sock(sk);
 		pr_debug("fallback passthrough");
 		ret = sock_sendmsg(ssock, msg);
 		return ret >= 0 ? ret + copied : (copied ? copied : ret);
@@ -769,8 +765,14 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 		if (ret < 0)
 			break;
 		if (ret == 0 && unlikely(__mptcp_needs_tcp_fallback(msk))) {
+			/* Can happen for passive sockets:
+			 * 3WHS negotiated MPTCP, but first packet after is
+			 * plain TCP (e.g. due to middlebox filtering unknown
+			 * options).
+			 *
+			 * Fall back to TCP.
+			 */
 			release_sock(ssk);
-			ssock = __mptcp_tcp_fallback(msk);
 			goto fallback;
 		}
 
@@ -883,6 +885,7 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
 	ssock = __mptcp_tcp_fallback(msk);
 	if (unlikely(ssock)) {
 fallback:
+		release_sock(sk);
 		pr_debug("fallback-read subflow=%p",
 			 mptcp_subflow_ctx(ssock->sk));
 		copied = sock_recvmsg(ssock, msg, flags);
@@ -1467,12 +1470,11 @@ static int mptcp_setsockopt(struct sock *sk, int level, int optname,
 	 */
 	lock_sock(sk);
 	ssock = __mptcp_tcp_fallback(msk);
+	release_sock(sk);
 	if (ssock)
 		return tcp_setsockopt(ssock->sk, level, optname, optval,
 				      optlen);
 
-	release_sock(sk);
-
 	return -EOPNOTSUPP;
 }
 
@@ -1492,12 +1494,11 @@ static int mptcp_getsockopt(struct sock *sk, int level, int optname,
 	 */
 	lock_sock(sk);
 	ssock = __mptcp_tcp_fallback(msk);
+	release_sock(sk);
 	if (ssock)
 		return tcp_getsockopt(ssock->sk, level, optname, optval,
 				      option);
 
-	release_sock(sk);
-
 	return -EOPNOTSUPP;
 }
 
diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
index 8dd17589217d..340cb955af25 100644
--- a/net/netfilter/ipset/ip_set_core.c
+++ b/net/netfilter/ipset/ip_set_core.c
@@ -86,7 +86,8 @@ find_set_type(const char *name, u8 family, u8 revision)
 {
 	struct ip_set_type *type;
 
-	list_for_each_entry_rcu(type, &ip_set_type_list, list)
+	list_for_each_entry_rcu(type, &ip_set_type_list, list,
+				lockdep_is_held(&ip_set_type_mutex))
 		if (STRNCMP(type->name, name) &&
 		    (type->family == family ||
 		     type->family == NFPROTO_UNSPEC) &&
diff --git a/net/netfilter/nf_flow_table_core.c b/net/netfilter/nf_flow_table_core.c
index c0cb79495c35..4344e572b7f9 100644
--- a/net/netfilter/nf_flow_table_core.c
+++ b/net/netfilter/nf_flow_table_core.c
@@ -421,10 +421,12 @@ void nf_flow_table_offload_del_cb(struct nf_flowtable *flow_table,
 
 	down_write(&flow_table->flow_block_lock);
 	block_cb = flow_block_cb_lookup(block, cb, cb_priv);
-	if (block_cb)
+	if (block_cb) {
 		list_del(&block_cb->list);
-	else
+		flow_block_cb_free(block_cb);
+	} else {
 		WARN_ON(true);
+	}
 	up_write(&flow_table->flow_block_lock);
 }
 EXPORT_SYMBOL_GPL(nf_flow_table_offload_del_cb);
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 4471393da6d8..9780bd93b7e4 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -3542,6 +3542,7 @@ static int nf_tables_set_alloc_name(struct nft_ctx *ctx, struct nft_set *set,
 			continue;
 		if (!strcmp(set->name, i->name)) {
 			kfree(set->name);
+			set->name = NULL;
 			return -ENFILE;
 		}
 	}
@@ -3961,8 +3962,8 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
 		if (flags & ~(NFT_SET_ANONYMOUS | NFT_SET_CONSTANT |
 			      NFT_SET_INTERVAL | NFT_SET_TIMEOUT |
 			      NFT_SET_MAP | NFT_SET_EVAL |
-			      NFT_SET_OBJECT))
-			return -EINVAL;
+			      NFT_SET_OBJECT | NFT_SET_CONCAT))
+			return -EOPNOTSUPP;
 		/* Only one of these operations is supported */
 		if ((flags & (NFT_SET_MAP | NFT_SET_OBJECT)) ==
 			     (NFT_SET_MAP | NFT_SET_OBJECT))
@@ -4000,7 +4001,7 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
 		objtype = ntohl(nla_get_be32(nla[NFTA_SET_OBJ_TYPE]));
 		if (objtype == NFT_OBJECT_UNSPEC ||
 		    objtype > NFT_OBJECT_MAX)
-			return -EINVAL;
+			return -EOPNOTSUPP;
 	} else if (flags & NFT_SET_OBJECT)
 		return -EINVAL;
 	else
diff --git a/net/netfilter/nft_lookup.c b/net/netfilter/nft_lookup.c
index 1e70359d633c..f1363b8aabba 100644
--- a/net/netfilter/nft_lookup.c
+++ b/net/netfilter/nft_lookup.c
@@ -29,7 +29,7 @@ void nft_lookup_eval(const struct nft_expr *expr,
 {
 	const struct nft_lookup *priv = nft_expr_priv(expr);
 	const struct nft_set *set = priv->set;
-	const struct nft_set_ext *ext;
+	const struct nft_set_ext *ext = NULL;
 	bool found;
 
 	found = set->ops->lookup(nft_net(pkt), set, &regs->data[priv->sreg],
@@ -39,11 +39,13 @@ void nft_lookup_eval(const struct nft_expr *expr,
 		return;
 	}
 
-	if (set->flags & NFT_SET_MAP)
-		nft_data_copy(&regs->data[priv->dreg],
-			      nft_set_ext_data(ext), set->dlen);
+	if (ext) {
+		if (set->flags & NFT_SET_MAP)
+			nft_data_copy(&regs->data[priv->dreg],
+				      nft_set_ext_data(ext), set->dlen);
 
-	nft_set_elem_update_expr(ext, regs, pkt);
+		nft_set_elem_update_expr(ext, regs, pkt);
+	}
 }
 
 static const struct nla_policy nft_lookup_policy[NFTA_LOOKUP_MAX + 1] = {
diff --git a/net/netfilter/nft_set_bitmap.c b/net/netfilter/nft_set_bitmap.c
index 32f0fc8be3a4..2a81ea421819 100644
--- a/net/netfilter/nft_set_bitmap.c
+++ b/net/netfilter/nft_set_bitmap.c
@@ -81,7 +81,6 @@ static bool nft_bitmap_lookup(const struct net *net, const struct nft_set *set,
 	u32 idx, off;
 
 	nft_bitmap_location(set, key, &idx, &off);
-	*ext = NULL;
 
 	return nft_bitmap_active(priv->bitmap, idx, off, genmask);
 }
diff --git a/net/netfilter/nft_set_rbtree.c b/net/netfilter/nft_set_rbtree.c
index 3a5552e14f75..3ffef454d469 100644
--- a/net/netfilter/nft_set_rbtree.c
+++ b/net/netfilter/nft_set_rbtree.c
@@ -218,27 +218,26 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set,
 
 	/* Detect overlaps as we descend the tree. Set the flag in these cases:
 	 *
-	 * a1. |__ _ _?  >|__ _ _  (insert start after existing start)
-	 * a2. _ _ __>|  ?_ _ __|  (insert end before existing end)
-	 * a3. _ _ ___|  ?_ _ _>|  (insert end after existing end)
-	 * a4. >|__ _ _   _ _ __|  (insert start before existing end)
+	 * a1. _ _ __>|  ?_ _ __|  (insert end before existing end)
+	 * a2. _ _ ___|  ?_ _ _>|  (insert end after existing end)
+	 * a3. _ _ ___? >|_ _ __|  (insert start before existing end)
 	 *
 	 * and clear it later on, as we eventually reach the points indicated by
 	 * '?' above, in the cases described below. We'll always meet these
 	 * later, locally, due to tree ordering, and overlaps for the intervals
 	 * that are the closest together are always evaluated last.
 	 *
-	 * b1. |__ _ _!  >|__ _ _  (insert start after existing end)
-	 * b2. _ _ __>|  !_ _ __|  (insert end before existing start)
-	 * b3. !_____>|            (insert end after existing start)
+	 * b1. _ _ __>|  !_ _ __|  (insert end before existing start)
+	 * b2. _ _ ___|  !_ _ _>|  (insert end after existing start)
+	 * b3. _ _ ___! >|_ _ __|  (insert start after existing end)
 	 *
-	 * Case a4. resolves to b1.:
+	 * Case a3. resolves to b3.:
 	 * - if the inserted start element is the leftmost, because the '0'
 	 *   element in the tree serves as end element
 	 * - otherwise, if an existing end is found. Note that end elements are
 	 *   always inserted after corresponding start elements.
 	 *
-	 * For a new, rightmost pair of elements, we'll hit cases b1. and b3.,
+	 * For a new, rightmost pair of elements, we'll hit cases b3. and b2.,
 	 * in that order.
 	 *
 	 * The flag is also cleared in two special cases:
@@ -262,9 +261,9 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set,
 			p = &parent->rb_left;
 
 			if (nft_rbtree_interval_start(new)) {
-				overlap = nft_rbtree_interval_start(rbe) &&
-					  nft_set_elem_active(&rbe->ext,
-							      genmask);
+				if (nft_rbtree_interval_end(rbe) &&
+				    nft_set_elem_active(&rbe->ext, genmask))
+					overlap = false;
 			} else {
 				overlap = nft_rbtree_interval_end(rbe) &&
 					  nft_set_elem_active(&rbe->ext,
diff --git a/net/netfilter/xt_IDLETIMER.c b/net/netfilter/xt_IDLETIMER.c
index 75bd0e5dd312..7b2f359bfce4 100644
--- a/net/netfilter/xt_IDLETIMER.c
+++ b/net/netfilter/xt_IDLETIMER.c
@@ -346,6 +346,9 @@ static int idletimer_tg_checkentry_v1(const struct xt_tgchk_param *par)
 
 	pr_debug("checkentry targinfo%s\n", info->label);
 
+	if (info->send_nl_msg)
+		return -EOPNOTSUPP;
+
 	ret = idletimer_tg_helper((struct idletimer_tg_info *)info);
 	if(ret < 0)
 	{
diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c
index e22092e4a783..7ed31b5e77e4 100644
--- a/net/qrtr/qrtr.c
+++ b/net/qrtr/qrtr.c
@@ -906,20 +906,21 @@ static int qrtr_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
 
 	node = NULL;
 	if (addr->sq_node == QRTR_NODE_BCAST) {
-		enqueue_fn = qrtr_bcast_enqueue;
-		if (addr->sq_port != QRTR_PORT_CTRL) {
+		if (addr->sq_port != QRTR_PORT_CTRL &&
+		    qrtr_local_nid != QRTR_NODE_BCAST) {
 			release_sock(sk);
 			return -ENOTCONN;
 		}
+		enqueue_fn = qrtr_bcast_enqueue;
 	} else if (addr->sq_node == ipc->us.sq_node) {
 		enqueue_fn = qrtr_local_enqueue;
 	} else {
-		enqueue_fn = qrtr_node_enqueue;
 		node = qrtr_node_lookup(addr->sq_node);
 		if (!node) {
 			release_sock(sk);
 			return -ECONNRESET;
 		}
+		enqueue_fn = qrtr_node_enqueue;
 	}
 
 	plen = (len + 3) & ~3;
diff --git a/net/rds/message.c b/net/rds/message.c
index 50f13f1d4ae0..071a261fdaab 100644
--- a/net/rds/message.c
+++ b/net/rds/message.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 Oracle.  All rights reserved.
+ * Copyright (c) 2006, 2020 Oracle and/or its affiliates.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -162,12 +162,12 @@ static void rds_message_purge(struct rds_message *rm)
 	if (rm->rdma.op_active)
 		rds_rdma_free_op(&rm->rdma);
 	if (rm->rdma.op_rdma_mr)
-		rds_mr_put(rm->rdma.op_rdma_mr);
+		kref_put(&rm->rdma.op_rdma_mr->r_kref, __rds_put_mr_final);
 
 	if (rm->atomic.op_active)
 		rds_atomic_free_op(&rm->atomic);
 	if (rm->atomic.op_rdma_mr)
-		rds_mr_put(rm->atomic.op_rdma_mr);
+		kref_put(&rm->atomic.op_rdma_mr->r_kref, __rds_put_mr_final);
 }
 
 void rds_message_put(struct rds_message *rm)
@@ -308,26 +308,20 @@ struct rds_message *rds_message_alloc(unsigned int extra_len, gfp_t gfp)
 /*
  * RDS ops use this to grab SG entries from the rm's sg pool.
  */
-struct scatterlist *rds_message_alloc_sgs(struct rds_message *rm, int nents,
-					  int *ret)
+struct scatterlist *rds_message_alloc_sgs(struct rds_message *rm, int nents)
 {
 	struct scatterlist *sg_first = (struct scatterlist *) &rm[1];
 	struct scatterlist *sg_ret;
 
-	if (WARN_ON(!ret))
-		return NULL;
-
 	if (nents <= 0) {
 		pr_warn("rds: alloc sgs failed! nents <= 0\n");
-		*ret = -EINVAL;
-		return NULL;
+		return ERR_PTR(-EINVAL);
 	}
 
 	if (rm->m_used_sgs + nents > rm->m_total_sgs) {
 		pr_warn("rds: alloc sgs failed! total %d used %d nents %d\n",
 			rm->m_total_sgs, rm->m_used_sgs, nents);
-		*ret = -ENOMEM;
-		return NULL;
+		return ERR_PTR(-ENOMEM);
 	}
 
 	sg_ret = &sg_first[rm->m_used_sgs];
@@ -343,7 +337,6 @@ struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned in
 	unsigned int i;
 	int num_sgs = DIV_ROUND_UP(total_len, PAGE_SIZE);
 	int extra_bytes = num_sgs * sizeof(struct scatterlist);
-	int ret;
 
 	rm = rds_message_alloc(extra_bytes, GFP_NOWAIT);
 	if (!rm)
@@ -352,10 +345,10 @@ struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned in
 	set_bit(RDS_MSG_PAGEVEC, &rm->m_flags);
 	rm->m_inc.i_hdr.h_len = cpu_to_be32(total_len);
 	rm->data.op_nents = DIV_ROUND_UP(total_len, PAGE_SIZE);
-	rm->data.op_sg = rds_message_alloc_sgs(rm, num_sgs, &ret);
-	if (!rm->data.op_sg) {
+	rm->data.op_sg = rds_message_alloc_sgs(rm, num_sgs);
+	if (IS_ERR(rm->data.op_sg)) {
 		rds_message_put(rm);
-		return ERR_PTR(ret);
+		return ERR_CAST(rm->data.op_sg);
 	}
 
 	for (i = 0; i < rm->data.op_nents; ++i) {
diff --git a/net/rds/rdma.c b/net/rds/rdma.c
index 585e6b3b69ce..a7ae11846cd7 100644
--- a/net/rds/rdma.c
+++ b/net/rds/rdma.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2017 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2020 Oracle and/or its affiliates.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -84,7 +84,7 @@ static struct rds_mr *rds_mr_tree_walk(struct rb_root *root, u64 key,
 	if (insert) {
 		rb_link_node(&insert->r_rb_node, parent, p);
 		rb_insert_color(&insert->r_rb_node, root);
-		refcount_inc(&insert->r_refcount);
+		kref_get(&insert->r_kref);
 	}
 	return NULL;
 }
@@ -99,10 +99,7 @@ static void rds_destroy_mr(struct rds_mr *mr)
 	unsigned long flags;
 
 	rdsdebug("RDS: destroy mr key is %x refcnt %u\n",
-			mr->r_key, refcount_read(&mr->r_refcount));
-
-	if (test_and_set_bit(RDS_MR_DEAD, &mr->r_state))
-		return;
+		 mr->r_key, kref_read(&mr->r_kref));
 
 	spin_lock_irqsave(&rs->rs_rdma_lock, flags);
 	if (!RB_EMPTY_NODE(&mr->r_rb_node))
@@ -115,8 +112,10 @@ static void rds_destroy_mr(struct rds_mr *mr)
 		mr->r_trans->free_mr(trans_private, mr->r_invalidate);
 }
 
-void __rds_put_mr_final(struct rds_mr *mr)
+void __rds_put_mr_final(struct kref *kref)
 {
+	struct rds_mr *mr = container_of(kref, struct rds_mr, r_kref);
+
 	rds_destroy_mr(mr);
 	kfree(mr);
 }
@@ -140,8 +139,7 @@ void rds_rdma_drop_keys(struct rds_sock *rs)
 		rb_erase(&mr->r_rb_node, &rs->rs_rdma_keys);
 		RB_CLEAR_NODE(&mr->r_rb_node);
 		spin_unlock_irqrestore(&rs->rs_rdma_lock, flags);
-		rds_destroy_mr(mr);
-		rds_mr_put(mr);
+		kref_put(&mr->r_kref, __rds_put_mr_final);
 		spin_lock_irqsave(&rs->rs_rdma_lock, flags);
 	}
 	spin_unlock_irqrestore(&rs->rs_rdma_lock, flags);
@@ -242,7 +240,7 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args,
 		goto out;
 	}
 
-	refcount_set(&mr->r_refcount, 1);
+	kref_init(&mr->r_kref);
 	RB_CLEAR_NODE(&mr->r_rb_node);
 	mr->r_trans = rs->rs_transport;
 	mr->r_sock = rs;
@@ -343,7 +341,7 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args,
 
 	rdsdebug("RDS: get_mr key is %x\n", mr->r_key);
 	if (mr_ret) {
-		refcount_inc(&mr->r_refcount);
+		kref_get(&mr->r_kref);
 		*mr_ret = mr;
 	}
 
@@ -351,7 +349,7 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args,
 out:
 	kfree(pages);
 	if (mr)
-		rds_mr_put(mr);
+		kref_put(&mr->r_kref, __rds_put_mr_final);
 	return ret;
 }
 
@@ -434,13 +432,7 @@ int rds_free_mr(struct rds_sock *rs, char __user *optval, int optlen)
 	if (!mr)
 		return -EINVAL;
 
-	/*
-	 * call rds_destroy_mr() ourselves so that we're sure it's done by the time
-	 * we return.  If we let rds_mr_put() do it it might not happen until
-	 * someone else drops their ref.
-	 */
-	rds_destroy_mr(mr);
-	rds_mr_put(mr);
+	kref_put(&mr->r_kref, __rds_put_mr_final);
 	return 0;
 }
 
@@ -464,6 +456,14 @@ void rds_rdma_unuse(struct rds_sock *rs, u32 r_key, int force)
 		return;
 	}
 
+	/* Get a reference so that the MR won't go away before calling
+	 * sync_mr() below.
+	 */
+	kref_get(&mr->r_kref);
+
+	/* If it is going to be freed, remove it from the tree now so
+	 * that no other thread can find it and free it.
+	 */
 	if (mr->r_use_once || force) {
 		rb_erase(&mr->r_rb_node, &rs->rs_rdma_keys);
 		RB_CLEAR_NODE(&mr->r_rb_node);
@@ -477,12 +477,13 @@ void rds_rdma_unuse(struct rds_sock *rs, u32 r_key, int force)
 	if (mr->r_trans->sync_mr)
 		mr->r_trans->sync_mr(mr->r_trans_private, DMA_FROM_DEVICE);
 
+	/* Release the reference held above. */
+	kref_put(&mr->r_kref, __rds_put_mr_final);
+
 	/* If the MR was marked as invalidate, this will
 	 * trigger an async flush. */
-	if (zot_me) {
-		rds_destroy_mr(mr);
-		rds_mr_put(mr);
-	}
+	if (zot_me)
+		kref_put(&mr->r_kref, __rds_put_mr_final);
 }
 
 void rds_rdma_free_op(struct rm_rdma_op *ro)
@@ -490,7 +491,7 @@ void rds_rdma_free_op(struct rm_rdma_op *ro)
 	unsigned int i;
 
 	if (ro->op_odp_mr) {
-		rds_mr_put(ro->op_odp_mr);
+		kref_put(&ro->op_odp_mr->r_kref, __rds_put_mr_final);
 	} else {
 		for (i = 0; i < ro->op_nents; i++) {
 			struct page *page = sg_page(&ro->op_sg[i]);
@@ -664,9 +665,11 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm,
 	op->op_odp_mr = NULL;
 
 	WARN_ON(!nr_pages);
-	op->op_sg = rds_message_alloc_sgs(rm, nr_pages, &ret);
-	if (!op->op_sg)
+	op->op_sg = rds_message_alloc_sgs(rm, nr_pages);
+	if (IS_ERR(op->op_sg)) {
+		ret = PTR_ERR(op->op_sg);
 		goto out_pages;
+	}
 
 	if (op->op_notify || op->op_recverr) {
 		/* We allocate an uninitialized notifier here, because
@@ -730,7 +733,7 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm,
 				goto out_pages;
 			}
 			RB_CLEAR_NODE(&local_odp_mr->r_rb_node);
-			refcount_set(&local_odp_mr->r_refcount, 1);
+			kref_init(&local_odp_mr->r_kref);
 			local_odp_mr->r_trans = rs->rs_transport;
 			local_odp_mr->r_sock = rs;
 			local_odp_mr->r_trans_private =
@@ -827,7 +830,7 @@ int rds_cmsg_rdma_dest(struct rds_sock *rs, struct rds_message *rm,
 	if (!mr)
 		err = -EINVAL;	/* invalid r_key */
 	else
-		refcount_inc(&mr->r_refcount);
+		kref_get(&mr->r_kref);
 	spin_unlock_irqrestore(&rs->rs_rdma_lock, flags);
 
 	if (mr) {
@@ -905,9 +908,11 @@ int rds_cmsg_atomic(struct rds_sock *rs, struct rds_message *rm,
 	rm->atomic.op_silent = !!(args->flags & RDS_RDMA_SILENT);
 	rm->atomic.op_active = 1;
 	rm->atomic.op_recverr = rs->rs_recverr;
-	rm->atomic.op_sg = rds_message_alloc_sgs(rm, 1, &ret);
-	if (!rm->atomic.op_sg)
+	rm->atomic.op_sg = rds_message_alloc_sgs(rm, 1);
+	if (IS_ERR(rm->atomic.op_sg)) {
+		ret = PTR_ERR(rm->atomic.op_sg);
 		goto err;
+	}
 
 	/* verify 8 byte-aligned */
 	if (args->local_addr & 0x7) {
diff --git a/net/rds/rds.h b/net/rds/rds.h
index e4a603523083..6019b0c004a9 100644
--- a/net/rds/rds.h
+++ b/net/rds/rds.h
@@ -291,7 +291,7 @@ struct rds_incoming {
 
 struct rds_mr {
 	struct rb_node		r_rb_node;
-	refcount_t		r_refcount;
+	struct kref		r_kref;
 	u32			r_key;
 
 	/* A copy of the creation flags */
@@ -299,19 +299,11 @@ struct rds_mr {
 	unsigned int		r_invalidate:1;
 	unsigned int		r_write:1;
 
-	/* This is for RDS_MR_DEAD.
-	 * It would be nice & consistent to make this part of the above
-	 * bit field here, but we need to use test_and_set_bit.
-	 */
-	unsigned long		r_state;
 	struct rds_sock		*r_sock; /* back pointer to the socket that owns us */
 	struct rds_transport	*r_trans;
 	void			*r_trans_private;
 };
 
-/* Flags for mr->r_state */
-#define RDS_MR_DEAD		0
-
 static inline rds_rdma_cookie_t rds_rdma_make_cookie(u32 r_key, u32 offset)
 {
 	return r_key | (((u64) offset) << 32);
@@ -852,8 +844,7 @@ rds_conn_connecting(struct rds_connection *conn)
 
 /* message.c */
 struct rds_message *rds_message_alloc(unsigned int nents, gfp_t gfp);
-struct scatterlist *rds_message_alloc_sgs(struct rds_message *rm, int nents,
-					  int *ret);
+struct scatterlist *rds_message_alloc_sgs(struct rds_message *rm, int nents);
 int rds_message_copy_from_user(struct rds_message *rm, struct iov_iter *from,
 			       bool zcopy);
 struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned int total_len);
@@ -946,12 +937,7 @@ void rds_atomic_send_complete(struct rds_message *rm, int wc_status);
 int rds_cmsg_atomic(struct rds_sock *rs, struct rds_message *rm,
 		    struct cmsghdr *cmsg);
 
-void __rds_put_mr_final(struct rds_mr *mr);
-static inline void rds_mr_put(struct rds_mr *mr)
-{
-	if (refcount_dec_and_test(&mr->r_refcount))
-		__rds_put_mr_final(mr);
-}
+void __rds_put_mr_final(struct kref *kref);
 
 static inline bool rds_destroy_pending(struct rds_connection *conn)
 {
diff --git a/net/rds/send.c b/net/rds/send.c
index 82dcd8b84fe7..68e2bdb08fd0 100644
--- a/net/rds/send.c
+++ b/net/rds/send.c
@@ -1274,9 +1274,11 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len)
 
 	/* Attach data to the rm */
 	if (payload_len) {
-		rm->data.op_sg = rds_message_alloc_sgs(rm, num_sgs, &ret);
-		if (!rm->data.op_sg)
+		rm->data.op_sg = rds_message_alloc_sgs(rm, num_sgs);
+		if (IS_ERR(rm->data.op_sg)) {
+			ret = PTR_ERR(rm->data.op_sg);
 			goto out;
+		}
 		ret = rds_message_copy_from_user(rm, &msg->msg_iter, zcopy);
 		if (ret)
 			goto out;
diff --git a/net/rxrpc/local_object.c b/net/rxrpc/local_object.c
index a6c1349e965d..01135e54d95d 100644
--- a/net/rxrpc/local_object.c
+++ b/net/rxrpc/local_object.c
@@ -165,15 +165,6 @@ static int rxrpc_open_socket(struct rxrpc_local *local, struct net *net)
 			goto error;
 		}
 
-		/* we want to set the don't fragment bit */
-		opt = IPV6_PMTUDISC_DO;
-		ret = kernel_setsockopt(local->socket, SOL_IPV6, IPV6_MTU_DISCOVER,
-					(char *) &opt, sizeof(opt));
-		if (ret < 0) {
-			_debug("setsockopt failed");
-			goto error;
-		}
-
 		/* Fall through and set IPv4 options too otherwise we don't get
 		 * errors from IPv4 packets sent through the IPv6 socket.
 		 */
diff --git a/net/rxrpc/output.c b/net/rxrpc/output.c
index bad3d2420344..90e263c6aa69 100644
--- a/net/rxrpc/output.c
+++ b/net/rxrpc/output.c
@@ -474,41 +474,21 @@ int rxrpc_send_data_packet(struct rxrpc_call *call, struct sk_buff *skb,
 	skb->tstamp = ktime_get_real();
 
 	switch (conn->params.local->srx.transport.family) {
+	case AF_INET6:
 	case AF_INET:
 		opt = IP_PMTUDISC_DONT;
-		ret = kernel_setsockopt(conn->params.local->socket,
-					SOL_IP, IP_MTU_DISCOVER,
-					(char *)&opt, sizeof(opt));
-		if (ret == 0) {
-			ret = kernel_sendmsg(conn->params.local->socket, &msg,
-					     iov, 2, len);
-			conn->params.peer->last_tx_at = ktime_get_seconds();
-
-			opt = IP_PMTUDISC_DO;
-			kernel_setsockopt(conn->params.local->socket, SOL_IP,
-					  IP_MTU_DISCOVER,
-					  (char *)&opt, sizeof(opt));
-		}
-		break;
-
-#ifdef CONFIG_AF_RXRPC_IPV6
-	case AF_INET6:
-		opt = IPV6_PMTUDISC_DONT;
-		ret = kernel_setsockopt(conn->params.local->socket,
-					SOL_IPV6, IPV6_MTU_DISCOVER,
-					(char *)&opt, sizeof(opt));
-		if (ret == 0) {
-			ret = kernel_sendmsg(conn->params.local->socket, &msg,
-					     iov, 2, len);
-			conn->params.peer->last_tx_at = ktime_get_seconds();
-
-			opt = IPV6_PMTUDISC_DO;
-			kernel_setsockopt(conn->params.local->socket,
-					  SOL_IPV6, IPV6_MTU_DISCOVER,
-					  (char *)&opt, sizeof(opt));
-		}
+		kernel_setsockopt(conn->params.local->socket,
+				  SOL_IP, IP_MTU_DISCOVER,
+				  (char *)&opt, sizeof(opt));
+		ret = kernel_sendmsg(conn->params.local->socket, &msg,
+				     iov, 2, len);
+		conn->params.peer->last_tx_at = ktime_get_seconds();
+
+		opt = IP_PMTUDISC_DO;
+		kernel_setsockopt(conn->params.local->socket,
+				  SOL_IP, IP_MTU_DISCOVER,
+				  (char *)&opt, sizeof(opt));
 		break;
-#endif
 
 	default:
 		BUG();
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index f6a3b969ead0..55bd1429678f 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -1667,6 +1667,7 @@ int tcf_classify_ingress(struct sk_buff *skb,
 		skb_ext_del(skb, TC_SKB_EXT);
 
 		tp = rcu_dereference_bh(fchain->filter_chain);
+		last_executed_chain = fchain->index;
 	}
 
 	ret = __tcf_classify(skb, tp, orig_tp, res, compat_mode,
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index af0ddd28b081..baef5ee43dbb 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -529,7 +529,6 @@ void cache_purge(struct cache_detail *detail)
 {
 	struct cache_head *ch = NULL;
 	struct hlist_head *head = NULL;
-	struct hlist_node *tmp = NULL;
 	int i = 0;
 
 	spin_lock(&detail->hash_lock);
@@ -541,7 +540,9 @@ void cache_purge(struct cache_detail *detail)
 	dprintk("RPC: %d entries in %s cache\n", detail->entries, detail->name);
 	for (i = 0; i < detail->hash_size; i++) {
 		head = &detail->hash_table[i];
-		hlist_for_each_entry_safe(ch, tmp, head, cache_list) {
+		while (!hlist_empty(head)) {
+			ch = hlist_entry(head->first, struct cache_head,
+					 cache_list);
 			sunrpc_begin_cache_remove_entry(ch, detail);
 			spin_unlock(&detail->hash_lock);
 			sunrpc_end_cache_remove_entry(ch, detail);
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index e27e3532ec75..2284ff038dad 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -908,9 +908,6 @@ int svc_send(struct svc_rqst *rqstp)
 	if (!xprt)
 		goto out;
 
-	/* release the receive skb before sending the reply */
-	xprt->xpt_ops->xpo_release_rqst(rqstp);
-
 	/* calculate over-all length */
 	xb = &rqstp->rq_res;
 	xb->len = xb->head[0].iov_len +
@@ -1040,6 +1037,8 @@ static void svc_delete_xprt(struct svc_xprt *xprt)
 
 	dprintk("svc: svc_delete_xprt(%p)\n", xprt);
 	xprt->xpt_ops->xpo_detach(xprt);
+	if (xprt->xpt_bc_xprt)
+		xprt->xpt_bc_xprt->ops->close(xprt->xpt_bc_xprt);
 
 	spin_lock_bh(&serv->sv_lock);
 	list_del_init(&xprt->xpt_list);
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 519cf9c4f8fd..023514e392b3 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -527,6 +527,8 @@ static int svc_udp_sendto(struct svc_rqst *rqstp)
 	unsigned int uninitialized_var(sent);
 	int err;
 
+	svc_release_udp_skb(rqstp);
+
 	svc_set_cmsg_data(rqstp, cmh);
 
 	err = xprt_sock_sendmsg(svsk->sk_sock, &msg, xdr, 0, 0, &sent);
@@ -1076,6 +1078,8 @@ static int svc_tcp_sendto(struct svc_rqst *rqstp)
 	unsigned int uninitialized_var(sent);
 	int err;
 
+	svc_release_skb(rqstp);
+
 	err = xprt_sock_sendmsg(svsk->sk_sock, &msg, xdr, 0, marker, &sent);
 	xdr_free_bvec(xdr);
 	if (err < 0 || sent != (xdr->len + sizeof(marker)))
diff --git a/net/sunrpc/xprtrdma/svc_rdma_backchannel.c b/net/sunrpc/xprtrdma/svc_rdma_backchannel.c
index d510a3a15d4b..af7eb8d202ae 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_backchannel.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_backchannel.c
@@ -244,6 +244,8 @@ static void
 xprt_rdma_bc_close(struct rpc_xprt *xprt)
 {
 	dprintk("svcrdma: %s: xprt %p\n", __func__, xprt);
+
+	xprt_disconnect_done(xprt);
 	xprt->cwnd = RPC_CWNDSHIFT;
 }
 
diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
index 54469b72b25f..efa5fcb5793f 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
@@ -223,6 +223,26 @@ void svc_rdma_recv_ctxt_put(struct svcxprt_rdma *rdma,
 		svc_rdma_recv_ctxt_destroy(rdma, ctxt);
 }
 
+/**
+ * svc_rdma_release_rqst - Release transport-specific per-rqst resources
+ * @rqstp: svc_rqst being released
+ *
+ * Ensure that the recv_ctxt is released whether or not a Reply
+ * was sent. For example, the client could close the connection,
+ * or svc_process could drop an RPC, before the Reply is sent.
+ */
+void svc_rdma_release_rqst(struct svc_rqst *rqstp)
+{
+	struct svc_rdma_recv_ctxt *ctxt = rqstp->rq_xprt_ctxt;
+	struct svc_xprt *xprt = rqstp->rq_xprt;
+	struct svcxprt_rdma *rdma =
+		container_of(xprt, struct svcxprt_rdma, sc_xprt);
+
+	rqstp->rq_xprt_ctxt = NULL;
+	if (ctxt)
+		svc_rdma_recv_ctxt_put(rdma, ctxt);
+}
+
 static int __svc_rdma_post_recv(struct svcxprt_rdma *rdma,
 				struct svc_rdma_recv_ctxt *ctxt)
 {
@@ -820,6 +840,8 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp)
 	__be32 *p;
 	int ret;
 
+	rqstp->rq_xprt_ctxt = NULL;
+
 	spin_lock(&rdma_xprt->sc_rq_dto_lock);
 	ctxt = svc_rdma_next_recv_ctxt(&rdma_xprt->sc_read_complete_q);
 	if (ctxt) {
diff --git a/net/sunrpc/xprtrdma/svc_rdma_rw.c b/net/sunrpc/xprtrdma/svc_rdma_rw.c
index bd7c195d872e..23c2d3ce0dc9 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_rw.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_rw.c
@@ -323,8 +323,6 @@ static int svc_rdma_post_chunk_ctxt(struct svc_rdma_chunk_ctxt *cc)
 		if (atomic_sub_return(cc->cc_sqecount,
 				      &rdma->sc_sq_avail) > 0) {
 			ret = ib_post_send(rdma->sc_qp, first_wr, &bad_wr);
-			trace_svcrdma_post_rw(&cc->cc_cqe,
-					      cc->cc_sqecount, ret);
 			if (ret)
 				break;
 			return 0;
@@ -337,6 +335,7 @@ static int svc_rdma_post_chunk_ctxt(struct svc_rdma_chunk_ctxt *cc)
 		trace_svcrdma_sq_retry(rdma);
 	} while (1);
 
+	trace_svcrdma_sq_post_err(rdma, ret);
 	set_bit(XPT_CLOSE, &xprt->xpt_flags);
 
 	/* If even one was posted, there will be a completion. */
diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c
index 90cba3058f04..b6c8643867f2 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c
@@ -322,15 +322,17 @@ int svc_rdma_send(struct svcxprt_rdma *rdma, struct ib_send_wr *wr)
 		}
 
 		svc_xprt_get(&rdma->sc_xprt);
+		trace_svcrdma_post_send(wr);
 		ret = ib_post_send(rdma->sc_qp, wr, NULL);
-		trace_svcrdma_post_send(wr, ret);
-		if (ret) {
-			set_bit(XPT_CLOSE, &rdma->sc_xprt.xpt_flags);
-			svc_xprt_put(&rdma->sc_xprt);
-			wake_up(&rdma->sc_send_wait);
-		}
-		break;
+		if (ret)
+			break;
+		return 0;
 	}
+
+	trace_svcrdma_sq_post_err(rdma, ret);
+	set_bit(XPT_CLOSE, &rdma->sc_xprt.xpt_flags);
+	svc_xprt_put(&rdma->sc_xprt);
+	wake_up(&rdma->sc_send_wait);
 	return ret;
 }
 
@@ -924,12 +926,7 @@ int svc_rdma_sendto(struct svc_rqst *rqstp)
 	ret = svc_rdma_send_reply_msg(rdma, sctxt, rctxt, rqstp);
 	if (ret < 0)
 		goto err1;
-	ret = 0;
-
-out:
-	rqstp->rq_xprt_ctxt = NULL;
-	svc_rdma_recv_ctxt_put(rdma, rctxt);
-	return ret;
+	return 0;
 
  err2:
 	if (ret != -E2BIG && ret != -EINVAL)
@@ -938,16 +935,14 @@ int svc_rdma_sendto(struct svc_rqst *rqstp)
 	ret = svc_rdma_send_error_msg(rdma, sctxt, rqstp);
 	if (ret < 0)
 		goto err1;
-	ret = 0;
-	goto out;
+	return 0;
 
  err1:
 	svc_rdma_send_ctxt_put(rdma, sctxt);
  err0:
 	trace_svcrdma_send_failed(rqstp, ret);
 	set_bit(XPT_CLOSE, &xprt->xpt_flags);
-	ret = -ENOTCONN;
-	goto out;
+	return -ENOTCONN;
 }
 
 /**
diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c
index 8bb99980ae85..ea54785db4f8 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_transport.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c
@@ -71,7 +71,6 @@ static struct svc_xprt *svc_rdma_create(struct svc_serv *serv,
 					struct sockaddr *sa, int salen,
 					int flags);
 static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt);
-static void svc_rdma_release_rqst(struct svc_rqst *);
 static void svc_rdma_detach(struct svc_xprt *xprt);
 static void svc_rdma_free(struct svc_xprt *xprt);
 static int svc_rdma_has_wspace(struct svc_xprt *xprt);
@@ -552,10 +551,6 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
 	return NULL;
 }
 
-static void svc_rdma_release_rqst(struct svc_rqst *rqstp)
-{
-}
-
 /*
  * When connected, an svc_xprt has at least two references:
  *
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 0bda8a73e8a8..845d0be805ec 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -2584,6 +2584,7 @@ static int bc_send_request(struct rpc_rqst *req)
 
 static void bc_close(struct rpc_xprt *xprt)
 {
+	xprt_disconnect_done(xprt);
 }
 
 /*
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 467c53a1fb5c..d4675e922a8f 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -1065,7 +1065,7 @@ static void tipc_link_update_cwin(struct tipc_link *l, int released,
 	/* Enter fast recovery */
 	if (unlikely(retransmitted)) {
 		l->ssthresh = max_t(u16, l->window / 2, 300);
-		l->window = l->ssthresh;
+		l->window = min_t(u16, l->ssthresh, l->window);
 		return;
 	}
 	/* Enter slow start */
diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c
index 156efce50dbd..0e989005bdc2 100644
--- a/net/tls/tls_main.c
+++ b/net/tls/tls_main.c
@@ -56,9 +56,9 @@ enum {
 	TLS_NUM_PROTS,
 };
 
-static struct proto *saved_tcpv6_prot;
+static const struct proto *saved_tcpv6_prot;
 static DEFINE_MUTEX(tcpv6_prot_mutex);
-static struct proto *saved_tcpv4_prot;
+static const struct proto *saved_tcpv4_prot;
 static DEFINE_MUTEX(tcpv4_prot_mutex);
 static struct proto tls_prots[TLS_NUM_PROTS][TLS_NUM_CONFIG][TLS_NUM_CONFIG];
 static struct proto_ops tls_sw_proto_ops;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 5fa402144cda..692bcd35f809 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -644,10 +644,8 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
 	[NL80211_ATTR_HE_CAPABILITY] = { .type = NLA_BINARY,
 					 .len = NL80211_HE_MAX_CAPABILITY_LEN },
 
-	[NL80211_ATTR_FTM_RESPONDER] = {
-		.type = NLA_NESTED,
-		.validation_data = nl80211_ftm_responder_policy,
-	},
+	[NL80211_ATTR_FTM_RESPONDER] =
+		NLA_POLICY_NESTED(nl80211_ftm_responder_policy),
 	[NL80211_ATTR_TIMEOUT] = NLA_POLICY_MIN(NLA_U32, 1),
 	[NL80211_ATTR_PEER_MEASUREMENTS] =
 		NLA_POLICY_NESTED(nl80211_pmsr_attr_policy),
diff --git a/net/xdp/xdp_umem.c b/net/xdp/xdp_umem.c
index fa7bb5e060d0..ed7a6060f73c 100644
--- a/net/xdp/xdp_umem.c
+++ b/net/xdp/xdp_umem.c
@@ -343,7 +343,7 @@ static int xdp_umem_reg(struct xdp_umem *umem, struct xdp_umem_reg *mr)
 	u32 chunk_size = mr->chunk_size, headroom = mr->headroom;
 	unsigned int chunks, chunks_per_page;
 	u64 addr = mr->addr, size = mr->len;
-	int size_chk, err;
+	int err;
 
 	if (chunk_size < XDP_UMEM_MIN_CHUNK_SIZE || chunk_size > PAGE_SIZE) {
 		/* Strictly speaking we could support this, if:
@@ -382,8 +382,7 @@ static int xdp_umem_reg(struct xdp_umem *umem, struct xdp_umem_reg *mr)
 			return -EINVAL;
 	}
 
-	size_chk = chunk_size - headroom - XDP_PACKET_HEADROOM;
-	if (size_chk < 0)
+	if (headroom >= chunk_size - XDP_PACKET_HEADROOM)
 		return -EINVAL;
 
 	umem->address = (unsigned long)addr;
diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
index 356f90e4522b..c350108aa38d 100644
--- a/net/xdp/xsk.c
+++ b/net/xdp/xsk.c
@@ -131,8 +131,9 @@ static void __xsk_rcv_memcpy(struct xdp_umem *umem, u64 addr, void *from_buf,
 		u64 page_start = addr & ~(PAGE_SIZE - 1);
 		u64 first_len = PAGE_SIZE - (addr - page_start);
 
-		memcpy(to_buf, from_buf, first_len + metalen);
-		memcpy(next_pg_addr, from_buf + first_len, len - first_len);
+		memcpy(to_buf, from_buf, first_len);
+		memcpy(next_pg_addr, from_buf + first_len,
+		       len + metalen - first_len);
 
 		return;
 	}
diff --git a/samples/Kconfig b/samples/Kconfig
index 9d236c346de5..5c31971a5745 100644
--- a/samples/Kconfig
+++ b/samples/Kconfig
@@ -190,5 +190,11 @@ config SAMPLE_INTEL_MEI
 	help
 	  Build a sample program to work with mei device.
 
+config SAMPLE_WATCH_QUEUE
+	bool "Build example /dev/watch_queue notification consumer"
+	depends on HEADERS_INSTALL
+	help
+	  Build example userspace program to use the new mount_notify(),
+	  sb_notify() syscalls and the KEYCTL_WATCH_KEY keyctl() function.
 
 endif # SAMPLES
diff --git a/samples/Makefile b/samples/Makefile
index f8f847b4f61f..8617edf7f19a 100644
--- a/samples/Makefile
+++ b/samples/Makefile
@@ -24,3 +24,4 @@ obj-$(CONFIG_VIDEO_PCI_SKELETON)	+= v4l/
 obj-y					+= vfio-mdev/
 subdir-$(CONFIG_SAMPLE_VFS)		+= vfs
 obj-$(CONFIG_SAMPLE_INTEL_MEI)		+= mei/
+subdir-$(CONFIG_SAMPLE_WATCH_QUEUE)	+= watch_queue
diff --git a/samples/watch_queue/Makefile b/samples/watch_queue/Makefile
new file mode 100644
index 000000000000..eec00dd0a8df
--- /dev/null
+++ b/samples/watch_queue/Makefile
@@ -0,0 +1,7 @@
+# List of programs to build
+hostprogs-y := watch_test
+
+# Tell kbuild to always build the programs
+always := $(hostprogs-y)
+
+HOSTCFLAGS_watch_test.o += -I$(objtree)/usr/include
diff --git a/samples/watch_queue/watch_test.c b/samples/watch_queue/watch_test.c
new file mode 100644
index 000000000000..0eaff5dc04c3
--- /dev/null
+++ b/samples/watch_queue/watch_test.c
@@ -0,0 +1,186 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Use /dev/watch_queue to watch for notifications.
+ *
+ * Copyright (C) 2020 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ */
+
+#define _GNU_SOURCE
+#include <stdbool.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <limits.h>
+#include <linux/watch_queue.h>
+#include <linux/unistd.h>
+#include <linux/keyctl.h>
+
+#ifndef KEYCTL_WATCH_KEY
+#define KEYCTL_WATCH_KEY -1
+#endif
+#ifndef __NR_watch_devices
+#define __NR_watch_devices -1
+#endif
+
+#define BUF_SIZE 256
+
+static long keyctl_watch_key(int key, int watch_fd, int watch_id)
+{
+	return syscall(__NR_keyctl, KEYCTL_WATCH_KEY, key, watch_fd, watch_id);
+}
+
+static const char *key_subtypes[256] = {
+	[NOTIFY_KEY_INSTANTIATED]	= "instantiated",
+	[NOTIFY_KEY_UPDATED]		= "updated",
+	[NOTIFY_KEY_LINKED]		= "linked",
+	[NOTIFY_KEY_UNLINKED]		= "unlinked",
+	[NOTIFY_KEY_CLEARED]		= "cleared",
+	[NOTIFY_KEY_REVOKED]		= "revoked",
+	[NOTIFY_KEY_INVALIDATED]	= "invalidated",
+	[NOTIFY_KEY_SETATTR]		= "setattr",
+};
+
+static void saw_key_change(struct watch_notification *n, size_t len)
+{
+	struct key_notification *k = (struct key_notification *)n;
+
+	if (len != sizeof(struct key_notification)) {
+		fprintf(stderr, "Incorrect key message length\n");
+		return;
+	}
+
+	printf("KEY %08x change=%u[%s] aux=%u\n",
+	       k->key_id, n->subtype, key_subtypes[n->subtype], k->aux);
+}
+
+/*
+ * Consume and display events.
+ */
+static void consumer(int fd)
+{
+	unsigned char buffer[433], *p, *end;
+	union {
+		struct watch_notification n;
+		unsigned char buf1[128];
+	} n;
+	ssize_t buf_len;
+
+	for (;;) {
+		buf_len = read(fd, buffer, sizeof(buffer));
+		if (buf_len == -1) {
+			perror("read");
+			exit(1);
+		}
+
+		if (buf_len == 0) {
+			printf("-- END --\n");
+			return;
+		}
+
+		if (buf_len > sizeof(buffer)) {
+			fprintf(stderr, "Read buffer overrun: %zd\n", buf_len);
+			return;
+		}
+
+		printf("read() = %zd\n", buf_len);
+
+		p = buffer;
+		end = buffer + buf_len;
+		while (p < end) {
+			size_t largest, len;
+
+			largest = end - p;
+			if (largest > 128)
+				largest = 128;
+			if (largest < sizeof(struct watch_notification)) {
+				fprintf(stderr, "Short message header: %zu\n", largest);
+				return;
+			}
+			memcpy(&n, p, largest);
+
+			printf("NOTIFY[%03zx]: ty=%06x sy=%02x i=%08x\n",
+			       p - buffer, n.n.type, n.n.subtype, n.n.info);
+
+			len = n.n.info & WATCH_INFO_LENGTH;
+			if (len < sizeof(n.n) || len > largest) {
+				fprintf(stderr, "Bad message length: %zu/%zu\n", len, largest);
+				exit(1);
+			}
+
+			switch (n.n.type) {
+			case WATCH_TYPE_META:
+				switch (n.n.subtype) {
+				case WATCH_META_REMOVAL_NOTIFICATION:
+					printf("REMOVAL of watchpoint %08x\n",
+					       (n.n.info & WATCH_INFO_ID) >>
+					       WATCH_INFO_ID__SHIFT);
+					break;
+				case WATCH_META_LOSS_NOTIFICATION:
+					printf("-- LOSS --\n");
+					break;
+				default:
+					printf("other meta record\n");
+					break;
+				}
+				break;
+			case WATCH_TYPE_KEY_NOTIFY:
+				saw_key_change(&n.n, len);
+				break;
+			default:
+				printf("other type\n");
+				break;
+			}
+
+			p += len;
+		}
+	}
+}
+
+static struct watch_notification_filter filter = {
+	.nr_filters	= 1,
+	.filters = {
+		[0]	= {
+			.type			= WATCH_TYPE_KEY_NOTIFY,
+			.subtype_filter[0]	= UINT_MAX,
+		},
+	},
+};
+
+int main(int argc, char **argv)
+{
+	int pipefd[2], fd;
+
+	if (pipe2(pipefd, O_NOTIFICATION_PIPE) == -1) {
+		perror("pipe2");
+		exit(1);
+	}
+	fd = pipefd[0];
+
+	if (ioctl(fd, IOC_WATCH_QUEUE_SET_SIZE, BUF_SIZE) == -1) {
+		perror("/dev/watch_queue(size)");
+		exit(1);
+	}
+
+	if (ioctl(fd, IOC_WATCH_QUEUE_SET_FILTER, &filter) == -1) {
+		perror("/dev/watch_queue(filter)");
+		exit(1);
+	}
+
+	if (keyctl_watch_key(KEY_SPEC_SESSION_KEYRING, fd, 0x01) == -1) {
+		perror("keyctl");
+		exit(1);
+	}
+
+	if (keyctl_watch_key(KEY_SPEC_USER_KEYRING, fd, 0x02) == -1) {
+		perror("keyctl");
+		exit(1);
+	}
+
+	consumer(fd);
+	exit(0);
+}
diff --git a/scripts/Makefile.kcsan b/scripts/Makefile.kcsan
new file mode 100644
index 000000000000..caf1111a28ae
--- /dev/null
+++ b/scripts/Makefile.kcsan
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+ifdef CONFIG_KCSAN
+
+CFLAGS_KCSAN := -fsanitize=thread
+
+endif # CONFIG_KCSAN
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 97547108ee7f..b12dd5ba4896 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -149,6 +149,16 @@ _c_flags += $(if $(patsubst n%,, \
 	$(CFLAGS_KCOV))
 endif
 
+#
+# Enable KCSAN flags except some files or directories we don't want to check
+# (depends on variables KCSAN_SANITIZE_obj.o, KCSAN_SANITIZE)
+#
+ifeq ($(CONFIG_KCSAN),y)
+_c_flags += $(if $(patsubst n%,, \
+	$(KCSAN_SANITIZE_$(basetarget).o)$(KCSAN_SANITIZE)y), \
+	$(CFLAGS_KCSAN))
+endif
+
 # $(srctree)/$(src) for including checkin headers from generated source files
 # $(objtree)/$(obj) for including generated headers from checkin source files
 ifeq ($(KBUILD_EXTMOD),)
diff --git a/scripts/atomic/fallbacks/acquire b/scripts/atomic/fallbacks/acquire
index e38871e64db6..ea489acc285e 100755
--- a/scripts/atomic/fallbacks/acquire
+++ b/scripts/atomic/fallbacks/acquire
@@ -1,5 +1,5 @@
 cat <<EOF
-static inline ${ret}
+static __always_inline ${ret}
 ${atomic}_${pfx}${name}${sfx}_acquire(${params})
 {
 	${ret} ret = ${atomic}_${pfx}${name}${sfx}_relaxed(${args});
diff --git a/scripts/atomic/fallbacks/add_negative b/scripts/atomic/fallbacks/add_negative
index e6f4815637de..03cc2e07fac5 100755
--- a/scripts/atomic/fallbacks/add_negative
+++ b/scripts/atomic/fallbacks/add_negative
@@ -8,7 +8,7 @@ cat <<EOF
  * if the result is negative, or false when
  * result is greater than or equal to zero.
  */
-static inline bool
+static __always_inline bool
 ${atomic}_add_negative(${int} i, ${atomic}_t *v)
 {
 	return ${atomic}_add_return(i, v) < 0;
diff --git a/scripts/atomic/fallbacks/add_unless b/scripts/atomic/fallbacks/add_unless
index 792533885fbf..daf87a04c850 100755
--- a/scripts/atomic/fallbacks/add_unless
+++ b/scripts/atomic/fallbacks/add_unless
@@ -8,7 +8,7 @@ cat << EOF
  * Atomically adds @a to @v, if @v was not already @u.
  * Returns true if the addition was done.
  */
-static inline bool
+static __always_inline bool
 ${atomic}_add_unless(${atomic}_t *v, ${int} a, ${int} u)
 {
 	return ${atomic}_fetch_add_unless(v, a, u) != u;
diff --git a/scripts/atomic/fallbacks/andnot b/scripts/atomic/fallbacks/andnot
index 9f3a3216b5e3..14efce01225a 100755
--- a/scripts/atomic/fallbacks/andnot
+++ b/scripts/atomic/fallbacks/andnot
@@ -1,5 +1,5 @@
 cat <<EOF
-static inline ${ret}
+static __always_inline ${ret}
 ${atomic}_${pfx}andnot${sfx}${order}(${int} i, ${atomic}_t *v)
 {
 	${retstmt}${atomic}_${pfx}and${sfx}${order}(~i, v);
diff --git a/scripts/atomic/fallbacks/dec b/scripts/atomic/fallbacks/dec
index 10bbc82be31d..118282f3a5a3 100755
--- a/scripts/atomic/fallbacks/dec
+++ b/scripts/atomic/fallbacks/dec
@@ -1,5 +1,5 @@
 cat <<EOF
-static inline ${ret}
+static __always_inline ${ret}
 ${atomic}_${pfx}dec${sfx}${order}(${atomic}_t *v)
 {
 	${retstmt}${atomic}_${pfx}sub${sfx}${order}(1, v);
diff --git a/scripts/atomic/fallbacks/dec_and_test b/scripts/atomic/fallbacks/dec_and_test
index 0ce7103b3df2..f8967a891117 100755
--- a/scripts/atomic/fallbacks/dec_and_test
+++ b/scripts/atomic/fallbacks/dec_and_test
@@ -7,7 +7,7 @@ cat <<EOF
  * returns true if the result is 0, or false for all other
  * cases.
  */
-static inline bool
+static __always_inline bool
 ${atomic}_dec_and_test(${atomic}_t *v)
 {
 	return ${atomic}_dec_return(v) == 0;
diff --git a/scripts/atomic/fallbacks/dec_if_positive b/scripts/atomic/fallbacks/dec_if_positive
index c52eacec43c8..cfb380bd2da6 100755
--- a/scripts/atomic/fallbacks/dec_if_positive
+++ b/scripts/atomic/fallbacks/dec_if_positive
@@ -1,5 +1,5 @@
 cat <<EOF
-static inline ${ret}
+static __always_inline ${ret}
 ${atomic}_dec_if_positive(${atomic}_t *v)
 {
 	${int} dec, c = ${atomic}_read(v);
diff --git a/scripts/atomic/fallbacks/dec_unless_positive b/scripts/atomic/fallbacks/dec_unless_positive
index 8a2578f14268..69cb7aa01f9c 100755
--- a/scripts/atomic/fallbacks/dec_unless_positive
+++ b/scripts/atomic/fallbacks/dec_unless_positive
@@ -1,5 +1,5 @@
 cat <<EOF
-static inline bool
+static __always_inline bool
 ${atomic}_dec_unless_positive(${atomic}_t *v)
 {
 	${int} c = ${atomic}_read(v);
diff --git a/scripts/atomic/fallbacks/fence b/scripts/atomic/fallbacks/fence
index 82f68fa6931a..92a3a4691bab 100755
--- a/scripts/atomic/fallbacks/fence
+++ b/scripts/atomic/fallbacks/fence
@@ -1,5 +1,5 @@
 cat <<EOF
-static inline ${ret}
+static __always_inline ${ret}
 ${atomic}_${pfx}${name}${sfx}(${params})
 {
 	${ret} ret;
diff --git a/scripts/atomic/fallbacks/fetch_add_unless b/scripts/atomic/fallbacks/fetch_add_unless
index d2c091db7eae..fffbc0d16fdf 100755
--- a/scripts/atomic/fallbacks/fetch_add_unless
+++ b/scripts/atomic/fallbacks/fetch_add_unless
@@ -8,7 +8,7 @@ cat << EOF
  * Atomically adds @a to @v, so long as @v was not already @u.
  * Returns original value of @v
  */
-static inline ${int}
+static __always_inline ${int}
 ${atomic}_fetch_add_unless(${atomic}_t *v, ${int} a, ${int} u)
 {
 	${int} c = ${atomic}_read(v);
diff --git a/scripts/atomic/fallbacks/inc b/scripts/atomic/fallbacks/inc
index f866b3ad2353..10751cd62829 100755
--- a/scripts/atomic/fallbacks/inc
+++ b/scripts/atomic/fallbacks/inc
@@ -1,5 +1,5 @@
 cat <<EOF
-static inline ${ret}
+static __always_inline ${ret}
 ${atomic}_${pfx}inc${sfx}${order}(${atomic}_t *v)
 {
 	${retstmt}${atomic}_${pfx}add${sfx}${order}(1, v);
diff --git a/scripts/atomic/fallbacks/inc_and_test b/scripts/atomic/fallbacks/inc_and_test
index 4e2068869f7e..4acea9c93604 100755
--- a/scripts/atomic/fallbacks/inc_and_test
+++ b/scripts/atomic/fallbacks/inc_and_test
@@ -7,7 +7,7 @@ cat <<EOF
  * and returns true if the result is zero, or false for all
  * other cases.
  */
-static inline bool
+static __always_inline bool
 ${atomic}_inc_and_test(${atomic}_t *v)
 {
 	return ${atomic}_inc_return(v) == 0;
diff --git a/scripts/atomic/fallbacks/inc_not_zero b/scripts/atomic/fallbacks/inc_not_zero
index a7c45c8d107c..d9f7b97aab42 100755
--- a/scripts/atomic/fallbacks/inc_not_zero
+++ b/scripts/atomic/fallbacks/inc_not_zero
@@ -6,7 +6,7 @@ cat <<EOF
  * Atomically increments @v by 1, if @v is non-zero.
  * Returns true if the increment was done.
  */
-static inline bool
+static __always_inline bool
 ${atomic}_inc_not_zero(${atomic}_t *v)
 {
 	return ${atomic}_add_unless(v, 1, 0);
diff --git a/scripts/atomic/fallbacks/inc_unless_negative b/scripts/atomic/fallbacks/inc_unless_negative
index 0c266e71dbd4..177a7cb51eda 100755
--- a/scripts/atomic/fallbacks/inc_unless_negative
+++ b/scripts/atomic/fallbacks/inc_unless_negative
@@ -1,5 +1,5 @@
 cat <<EOF
-static inline bool
+static __always_inline bool
 ${atomic}_inc_unless_negative(${atomic}_t *v)
 {
 	${int} c = ${atomic}_read(v);
diff --git a/scripts/atomic/fallbacks/read_acquire b/scripts/atomic/fallbacks/read_acquire
index 75863b5203f7..12fa83cb3a6d 100755
--- a/scripts/atomic/fallbacks/read_acquire
+++ b/scripts/atomic/fallbacks/read_acquire
@@ -1,5 +1,5 @@
 cat <<EOF
-static inline ${ret}
+static __always_inline ${ret}
 ${atomic}_read_acquire(const ${atomic}_t *v)
 {
 	return smp_load_acquire(&(v)->counter);
diff --git a/scripts/atomic/fallbacks/release b/scripts/atomic/fallbacks/release
index 3f628a3802d9..730d2a6d3e07 100755
--- a/scripts/atomic/fallbacks/release
+++ b/scripts/atomic/fallbacks/release
@@ -1,5 +1,5 @@
 cat <<EOF
-static inline ${ret}
+static __always_inline ${ret}
 ${atomic}_${pfx}${name}${sfx}_release(${params})
 {
 	__atomic_release_fence();
diff --git a/scripts/atomic/fallbacks/set_release b/scripts/atomic/fallbacks/set_release
index 45bb5e0cfc08..e5d72c717434 100755
--- a/scripts/atomic/fallbacks/set_release
+++ b/scripts/atomic/fallbacks/set_release
@@ -1,5 +1,5 @@
 cat <<EOF
-static inline void
+static __always_inline void
 ${atomic}_set_release(${atomic}_t *v, ${int} i)
 {
 	smp_store_release(&(v)->counter, i);
diff --git a/scripts/atomic/fallbacks/sub_and_test b/scripts/atomic/fallbacks/sub_and_test
index 289ef17a2d7a..6cfe4ed49746 100755
--- a/scripts/atomic/fallbacks/sub_and_test
+++ b/scripts/atomic/fallbacks/sub_and_test
@@ -8,7 +8,7 @@ cat <<EOF
  * true if the result is zero, or false for all
  * other cases.
  */
-static inline bool
+static __always_inline bool
 ${atomic}_sub_and_test(${int} i, ${atomic}_t *v)
 {
 	return ${atomic}_sub_return(i, v) == 0;
diff --git a/scripts/atomic/fallbacks/try_cmpxchg b/scripts/atomic/fallbacks/try_cmpxchg
index 4ed85e2f5378..c7a26213b978 100755
--- a/scripts/atomic/fallbacks/try_cmpxchg
+++ b/scripts/atomic/fallbacks/try_cmpxchg
@@ -1,5 +1,5 @@
 cat <<EOF
-static inline bool
+static __always_inline bool
 ${atomic}_try_cmpxchg${order}(${atomic}_t *v, ${int} *old, ${int} new)
 {
 	${int} r, o = *old;
diff --git a/scripts/atomic/gen-atomic-fallback.sh b/scripts/atomic/gen-atomic-fallback.sh
index 1bd7c1707633..b6c6f5d306a7 100755
--- a/scripts/atomic/gen-atomic-fallback.sh
+++ b/scripts/atomic/gen-atomic-fallback.sh
@@ -149,6 +149,8 @@ cat << EOF
 #ifndef _LINUX_ATOMIC_FALLBACK_H
 #define _LINUX_ATOMIC_FALLBACK_H
 
+#include <linux/compiler.h>
+
 EOF
 
 for xchg in "xchg" "cmpxchg" "cmpxchg64"; do
diff --git a/scripts/atomic/gen-atomic-instrumented.sh b/scripts/atomic/gen-atomic-instrumented.sh
index e09812372b17..6afadf73da17 100755
--- a/scripts/atomic/gen-atomic-instrumented.sh
+++ b/scripts/atomic/gen-atomic-instrumented.sh
@@ -20,7 +20,7 @@ gen_param_check()
 	# We don't write to constant parameters
 	[ ${type#c} != ${type} ] && rw="read"
 
-	printf "\tkasan_check_${rw}(${name}, sizeof(*${name}));\n"
+	printf "\tinstrument_atomic_${rw}(${name}, sizeof(*${name}));\n"
 }
 
 #gen_param_check(arg...)
@@ -84,7 +84,7 @@ gen_proto_order_variant()
 	[ ! -z "${guard}" ] && printf "#if ${guard}\n"
 
 cat <<EOF
-static inline ${ret}
+static __always_inline ${ret}
 ${atomicname}(${params})
 {
 ${checks}
@@ -107,7 +107,7 @@ cat <<EOF
 #define ${xchg}(ptr, ...)						\\
 ({									\\
 	typeof(ptr) __ai_ptr = (ptr);					\\
-	kasan_check_write(__ai_ptr, ${mult}sizeof(*__ai_ptr));		\\
+	instrument_atomic_write(__ai_ptr, ${mult}sizeof(*__ai_ptr));		\\
 	arch_${xchg}(__ai_ptr, __VA_ARGS__);				\\
 })
 EOF
@@ -147,7 +147,8 @@ cat << EOF
 #define _ASM_GENERIC_ATOMIC_INSTRUMENTED_H
 
 #include <linux/build_bug.h>
-#include <linux/kasan-checks.h>
+#include <linux/compiler.h>
+#include <linux/instrumented.h>
 
 EOF
 
diff --git a/scripts/atomic/gen-atomic-long.sh b/scripts/atomic/gen-atomic-long.sh
index c240a7231b2e..e318d3f92e53 100755
--- a/scripts/atomic/gen-atomic-long.sh
+++ b/scripts/atomic/gen-atomic-long.sh
@@ -46,7 +46,7 @@ gen_proto_order_variant()
 	local retstmt="$(gen_ret_stmt "${meta}")"
 
 cat <<EOF
-static inline ${ret}
+static __always_inline ${ret}
 atomic_long_${name}(${params})
 {
 	${retstmt}${atomic}_${name}(${argscast});
@@ -64,6 +64,7 @@ cat << EOF
 #ifndef _ASM_GENERIC_ATOMIC_LONG_H
 #define _ASM_GENERIC_ATOMIC_LONG_H
 
+#include <linux/compiler.h>
 #include <asm/types.h>
 
 #ifdef CONFIG_64BIT
diff --git a/scripts/config b/scripts/config
index e0e39826dae9..eee5b7f3a092 100755
--- a/scripts/config
+++ b/scripts/config
@@ -7,6 +7,9 @@ myname=${0##*/}
 # If no prefix forced, use the default CONFIG_
 CONFIG_="${CONFIG_-CONFIG_}"
 
+# We use an uncommon delimiter for sed substitutions
+SED_DELIM=$(echo -en "\001")
+
 usage() {
 	cat >&2 <<EOL
 Manipulate options in a .config file from the command line.
@@ -83,7 +86,7 @@ txt_subst() {
 	local infile="$3"
 	local tmpfile="$infile.swp"
 
-	sed -e "s:$before:$after:" "$infile" >"$tmpfile"
+	sed -e "s$SED_DELIM$before$SED_DELIM$after$SED_DELIM" "$infile" >"$tmpfile"
 	# replace original file with the edited one
 	mv "$tmpfile" "$infile"
 }
diff --git a/scripts/documentation-file-ref-check b/scripts/documentation-file-ref-check
index 9a8cc10cffd0..c71832b2312b 100755
--- a/scripts/documentation-file-ref-check
+++ b/scripts/documentation-file-ref-check
@@ -25,7 +25,7 @@ my $fix = 0;
 my $warn = 0;
 
 if (! -d ".git") {
-	printf "Warning: can't check if file exists, as this is not a git tree";
+	printf "Warning: can't check if file exists, as this is not a git tree\n";
 	exit 0;
 }
 
diff --git a/scripts/gcc-plugins/Makefile b/scripts/gcc-plugins/Makefile
index f22858b2c3d6..80f354289eeb 100644
--- a/scripts/gcc-plugins/Makefile
+++ b/scripts/gcc-plugins/Makefile
@@ -4,6 +4,7 @@ GCC_PLUGINS_DIR := $(shell $(CC) -print-file-name=plugin)
 HOST_EXTRACXXFLAGS += -I$(GCC_PLUGINS_DIR)/include -I$(src) -std=gnu++98 -fno-rtti
 HOST_EXTRACXXFLAGS += -fno-exceptions -fasynchronous-unwind-tables -ggdb
 HOST_EXTRACXXFLAGS += -Wno-narrowing -Wno-unused-variable -Wno-c++11-compat
+HOST_EXTRACXXFLAGS += -Wno-format-diag
 
 $(obj)/randomize_layout_plugin.o: $(objtree)/$(obj)/randomize_layout_seed.h
 quiet_cmd_create_randomize_layout_seed = GENSEED $@
diff --git a/scripts/gcc-plugins/gcc-common.h b/scripts/gcc-plugins/gcc-common.h
index 17f06079a712..9ad76b7f3f10 100644
--- a/scripts/gcc-plugins/gcc-common.h
+++ b/scripts/gcc-plugins/gcc-common.h
@@ -35,7 +35,9 @@
 #include "ggc.h"
 #include "timevar.h"
 
+#if BUILDING_GCC_VERSION < 10000
 #include "params.h"
+#endif
 
 #if BUILDING_GCC_VERSION <= 4009
 #include "pointer-set.h"
@@ -847,6 +849,7 @@ static inline gimple gimple_build_assign_with_ops(enum tree_code subcode, tree l
 	return gimple_build_assign(lhs, subcode, op1, op2 PASS_MEM_STAT);
 }
 
+#if BUILDING_GCC_VERSION < 10000
 template <>
 template <>
 inline bool is_a_helper<const ggoto *>::test(const_gimple gs)
@@ -860,6 +863,7 @@ inline bool is_a_helper<const greturn *>::test(const_gimple gs)
 {
 	return gs->code == GIMPLE_RETURN;
 }
+#endif
 
 static inline gasm *as_a_gasm(gimple stmt)
 {
diff --git a/scripts/gcc-plugins/stackleak_plugin.c b/scripts/gcc-plugins/stackleak_plugin.c
index dbd37460c573..cc75eeba0be1 100644
--- a/scripts/gcc-plugins/stackleak_plugin.c
+++ b/scripts/gcc-plugins/stackleak_plugin.c
@@ -51,7 +51,6 @@ static void stackleak_add_track_stack(gimple_stmt_iterator *gsi, bool after)
 	gimple stmt;
 	gcall *stackleak_track_stack;
 	cgraph_node_ptr node;
-	int frequency;
 	basic_block bb;
 
 	/* Insert call to void stackleak_track_stack(void) */
@@ -68,9 +67,9 @@ static void stackleak_add_track_stack(gimple_stmt_iterator *gsi, bool after)
 	bb = gimple_bb(stackleak_track_stack);
 	node = cgraph_get_create_node(track_function_decl);
 	gcc_assert(node);
-	frequency = compute_call_stmt_bb_frequency(current_function_decl, bb);
 	cgraph_create_edge(cgraph_get_node(current_function_decl), node,
-			stackleak_track_stack, bb->count, frequency);
+			stackleak_track_stack, bb->count,
+			compute_call_stmt_bb_frequency(current_function_decl, bb));
 }
 
 static bool is_alloca(gimple stmt)
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index f2d73f04e71d..f746ca8fa403 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -853,7 +853,7 @@ sub output_function_rst(%) {
 
 	if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
 	    # pointer-to-function
-	    print $1 . $parameter . ") (" . $2;
+	    print $1 . $parameter . ") (" . $2 . ")";
 	} else {
 	    print $type . " " . $parameter;
 	}
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 02d5d79da284..9599e2a3f1e6 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -954,6 +954,8 @@ static const struct dmifield {
 	{ "bvn", DMI_BIOS_VENDOR },
 	{ "bvr", DMI_BIOS_VERSION },
 	{ "bd",  DMI_BIOS_DATE },
+	{ "br",  DMI_BIOS_RELEASE },
+	{ "efr", DMI_EC_FIRMWARE_RELEASE },
 	{ "svn", DMI_SYS_VENDOR },
 	{ "pn",  DMI_PRODUCT_NAME },
 	{ "pvr", DMI_PRODUCT_VERSION },
diff --git a/security/Makefile b/security/Makefile
index 22e73a3482bd..3baf435de541 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -30,7 +30,7 @@ obj-$(CONFIG_SECURITY_YAMA)		+= yama/
 obj-$(CONFIG_SECURITY_LOADPIN)		+= loadpin/
 obj-$(CONFIG_SECURITY_SAFESETID)       += safesetid/
 obj-$(CONFIG_SECURITY_LOCKDOWN_LSM)	+= lockdown/
-obj-$(CONFIG_CGROUP_DEVICE)		+= device_cgroup.o
+obj-$(CONFIG_CGROUPS)			+= device_cgroup.o
 obj-$(CONFIG_BPF_LSM)			+= bpf/
 
 # Object integrity file lists
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index 280741fc0f5f..39b54ecd98fe 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -340,38 +340,6 @@ static struct dentry *aafs_create_dir(const char *name, struct dentry *parent)
 			   NULL);
 }
 
-/**
- * aafs_create_symlink - create a symlink in the apparmorfs filesystem
- * @name: name of dentry to create
- * @parent: parent directory for this dentry
- * @target: if symlink, symlink target string
- * @private: private data
- * @iops: struct of inode_operations that should be used
- *
- * If @target parameter is %NULL, then the @iops parameter needs to be
- * setup to handle .readlink and .get_link inode_operations.
- */
-static struct dentry *aafs_create_symlink(const char *name,
-					  struct dentry *parent,
-					  const char *target,
-					  void *private,
-					  const struct inode_operations *iops)
-{
-	struct dentry *dent;
-	char *link = NULL;
-
-	if (target) {
-		if (!link)
-			return ERR_PTR(-ENOMEM);
-	}
-	dent = aafs_create(name, S_IFLNK | 0444, parent, private, link, NULL,
-			   iops);
-	if (IS_ERR(dent))
-		kfree(link);
-
-	return dent;
-}
-
 /**
  * aafs_remove - removes a file or directory from the apparmorfs filesystem
  *
@@ -623,7 +591,7 @@ static __poll_t ns_revision_poll(struct file *file, poll_table *pt)
 
 void __aa_bump_ns_revision(struct aa_ns *ns)
 {
-	WRITE_ONCE(ns->revision, ns->revision + 1);
+	WRITE_ONCE(ns->revision, READ_ONCE(ns->revision) + 1);
 	wake_up_interruptible(&ns->wait);
 }
 
@@ -1762,25 +1730,25 @@ int __aafs_profile_mkdir(struct aa_profile *profile, struct dentry *parent)
 	}
 
 	if (profile->rawdata) {
-		dent = aafs_create_symlink("raw_sha1", dir, NULL,
-					   profile->label.proxy,
-					   &rawdata_link_sha1_iops);
+		dent = aafs_create("raw_sha1", S_IFLNK | 0444, dir,
+				   profile->label.proxy, NULL, NULL,
+				   &rawdata_link_sha1_iops);
 		if (IS_ERR(dent))
 			goto fail;
 		aa_get_proxy(profile->label.proxy);
 		profile->dents[AAFS_PROF_RAW_HASH] = dent;
 
-		dent = aafs_create_symlink("raw_abi", dir, NULL,
-					   profile->label.proxy,
-					   &rawdata_link_abi_iops);
+		dent = aafs_create("raw_abi", S_IFLNK | 0444, dir,
+				   profile->label.proxy, NULL, NULL,
+				   &rawdata_link_abi_iops);
 		if (IS_ERR(dent))
 			goto fail;
 		aa_get_proxy(profile->label.proxy);
 		profile->dents[AAFS_PROF_RAW_ABI] = dent;
 
-		dent = aafs_create_symlink("raw_data", dir, NULL,
-					   profile->label.proxy,
-					   &rawdata_link_data_iops);
+		dent = aafs_create("raw_data", S_IFLNK | 0444, dir,
+				   profile->label.proxy, NULL, NULL,
+				   &rawdata_link_data_iops);
 		if (IS_ERR(dent))
 			goto fail;
 		aa_get_proxy(profile->label.proxy);
@@ -2363,6 +2331,8 @@ static struct aa_sfs_entry aa_sfs_entry_versions[] = {
 static struct aa_sfs_entry aa_sfs_entry_policy[] = {
 	AA_SFS_DIR("versions",			aa_sfs_entry_versions),
 	AA_SFS_FILE_BOOLEAN("set_load",		1),
+	/* number of out of band transitions supported */
+	AA_SFS_FILE_U64("outofband",		MAX_OOB_SUPPORTED),
 	{ }
 };
 
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index 6ceb74e0f789..0926553ca86f 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -320,8 +320,7 @@ static int aa_xattrs_match(const struct linux_binprm *bprm,
 	might_sleep();
 
 	/* transition from exec match to xattr set */
-	state = aa_dfa_null_transition(profile->xmatch, state);
-
+	state = aa_dfa_outofband_transition(profile->xmatch, state);
 	d = bprm->file->f_path.dentry;
 
 	for (i = 0; i < profile->xattr_count; i++) {
@@ -330,7 +329,13 @@ static int aa_xattrs_match(const struct linux_binprm *bprm,
 		if (size >= 0) {
 			u32 perm;
 
-			/* Check the xattr value, not just presence */
+			/*
+			 * Check the xattr presence before value. This ensure
+			 * that not present xattr can be distinguished from a 0
+			 * length value or rule that matches any value
+			 */
+			state = aa_dfa_null_transition(profile->xmatch, state);
+			/* Check xattr value */
 			state = aa_dfa_match_len(profile->xmatch, state, value,
 						 size);
 			perm = dfa_user_allow(profile->xmatch, state);
@@ -340,7 +345,7 @@ static int aa_xattrs_match(const struct linux_binprm *bprm,
 			}
 		}
 		/* transition to next element */
-		state = aa_dfa_null_transition(profile->xmatch, state);
+		state = aa_dfa_outofband_transition(profile->xmatch, state);
 		if (size < 0) {
 			/*
 			 * No xattr match, so verify if transition to
@@ -620,8 +625,6 @@ static struct aa_label *profile_transition(struct aa_profile *profile,
 					   bool *secure_exec)
 {
 	struct aa_label *new = NULL;
-	struct aa_profile *component;
-	struct label_it i;
 	const char *info = NULL, *name = NULL, *target = NULL;
 	unsigned int state = profile->file.start;
 	struct aa_perms perms = {};
@@ -670,21 +673,6 @@ static struct aa_label *profile_transition(struct aa_profile *profile,
 			info = "profile transition not found";
 			/* remove MAY_EXEC to audit as failure */
 			perms.allow &= ~MAY_EXEC;
-		} else {
-			/* verify that each component's xattr requirements are
-			 * met, and fail execution otherwise
-			 */
-			label_for_each(i, new, component) {
-				if (aa_xattrs_match(bprm, component, state) <
-				    0) {
-					error = -EACCES;
-					info = "required xattrs not present";
-					perms.allow &= ~MAY_EXEC;
-					aa_put_label(new);
-					new = NULL;
-					goto audit;
-				}
-			}
 		}
 	} else if (COMPLAIN_MODE(profile)) {
 		/* no exec permission - learning mode */
@@ -929,7 +917,8 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
 	 * aways results in a further reduction of permissions.
 	 */
 	if ((bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS) &&
-	    !unconfined(label) && !aa_label_is_subset(new, ctx->nnp)) {
+	    !unconfined(label) &&
+	    !aa_label_is_unconfined_subset(new, ctx->nnp)) {
 		error = -EPERM;
 		info = "no new privs";
 		goto audit;
@@ -1207,7 +1196,7 @@ int aa_change_hat(const char *hats[], int count, u64 token, int flags)
 		 * reduce restrictions.
 		 */
 		if (task_no_new_privs(current) && !unconfined(label) &&
-		    !aa_label_is_subset(new, ctx->nnp)) {
+		    !aa_label_is_unconfined_subset(new, ctx->nnp)) {
 			/* not an apparmor denial per se, so don't log it */
 			AA_DEBUG("no_new_privs - change_hat denied");
 			error = -EPERM;
@@ -1228,7 +1217,7 @@ int aa_change_hat(const char *hats[], int count, u64 token, int flags)
 		 * reduce restrictions.
 		 */
 		if (task_no_new_privs(current) && !unconfined(label) &&
-		    !aa_label_is_subset(previous, ctx->nnp)) {
+		    !aa_label_is_unconfined_subset(previous, ctx->nnp)) {
 			/* not an apparmor denial per se, so don't log it */
 			AA_DEBUG("no_new_privs - change_hat denied");
 			error = -EPERM;
@@ -1424,7 +1413,7 @@ int aa_change_profile(const char *fqname, int flags)
 		 * reduce restrictions.
 		 */
 		if (task_no_new_privs(current) && !unconfined(label) &&
-		    !aa_label_is_subset(new, ctx->nnp)) {
+		    !aa_label_is_unconfined_subset(new, ctx->nnp)) {
 			/* not an apparmor denial per se, so don't log it */
 			AA_DEBUG("no_new_privs - change_hat denied");
 			error = -EPERM;
diff --git a/security/apparmor/include/label.h b/security/apparmor/include/label.h
index 47942c4ba7ca..255764ab06e2 100644
--- a/security/apparmor/include/label.h
+++ b/security/apparmor/include/label.h
@@ -281,6 +281,7 @@ bool aa_label_init(struct aa_label *label, int size, gfp_t gfp);
 struct aa_label *aa_label_alloc(int size, struct aa_proxy *proxy, gfp_t gfp);
 
 bool aa_label_is_subset(struct aa_label *set, struct aa_label *sub);
+bool aa_label_is_unconfined_subset(struct aa_label *set, struct aa_label *sub);
 struct aa_profile *__aa_label_next_not_in_set(struct label_it *I,
 					     struct aa_label *set,
 					     struct aa_label *sub);
diff --git a/security/apparmor/include/match.h b/security/apparmor/include/match.h
index e23f4aadc1ff..884489590588 100644
--- a/security/apparmor/include/match.h
+++ b/security/apparmor/include/match.h
@@ -37,6 +37,10 @@
 
 #define YYTH_MAGIC	0x1B5E783D
 #define YYTH_FLAG_DIFF_ENCODE	1
+#define YYTH_FLAG_OOB_TRANS	2
+#define YYTH_FLAGS (YYTH_FLAG_DIFF_ENCODE | YYTH_FLAG_OOB_TRANS)
+
+#define MAX_OOB_SUPPORTED	1
 
 struct table_set_header {
 	u32 th_magic;		/* YYTH_MAGIC */
@@ -94,6 +98,7 @@ struct table_header {
 struct aa_dfa {
 	struct kref count;
 	u16 flags;
+	u32 max_oob;
 	struct table_header *tables[YYTD_ID_TSIZE];
 };
 
@@ -127,6 +132,8 @@ unsigned int aa_dfa_match(struct aa_dfa *dfa, unsigned int start,
 			  const char *str);
 unsigned int aa_dfa_next(struct aa_dfa *dfa, unsigned int state,
 			 const char c);
+unsigned int aa_dfa_outofband_transition(struct aa_dfa *dfa,
+					 unsigned int state);
 unsigned int aa_dfa_match_until(struct aa_dfa *dfa, unsigned int start,
 				const char *str, const char **retpos);
 unsigned int aa_dfa_matchn_until(struct aa_dfa *dfa, unsigned int start,
@@ -181,5 +188,9 @@ static inline void aa_put_dfa(struct aa_dfa *dfa)
 
 #define MATCH_FLAG_DIFF_ENCODE 0x80000000
 #define MARK_DIFF_ENCODE 0x40000000
+#define MATCH_FLAG_OOB_TRANSITION 0x20000000
+#define MATCH_FLAGS_MASK 0xff000000
+#define MATCH_FLAGS_VALID (MATCH_FLAG_DIFF_ENCODE | MATCH_FLAG_OOB_TRANSITION)
+#define MATCH_FLAGS_INVALID (MATCH_FLAGS_MASK & ~MATCH_FLAGS_VALID)
 
 #endif /* __AA_MATCH_H */
diff --git a/security/apparmor/label.c b/security/apparmor/label.c
index 470693239e64..ba3987242282 100644
--- a/security/apparmor/label.c
+++ b/security/apparmor/label.c
@@ -550,6 +550,39 @@ bool aa_label_is_subset(struct aa_label *set, struct aa_label *sub)
 	return __aa_label_next_not_in_set(&i, set, sub) == NULL;
 }
 
+/**
+ * aa_label_is_unconfined_subset - test if @sub is a subset of @set
+ * @set: label to test against
+ * @sub: label to test if is subset of @set
+ *
+ * This checks for subset but taking into account unconfined. IF
+ * @sub contains an unconfined profile that does not have a matching
+ * unconfined in @set then this will not cause the test to fail.
+ * Conversely we don't care about an unconfined in @set that is not in
+ * @sub
+ *
+ * Returns: true if @sub is special_subset of @set
+ *     else false
+ */
+bool aa_label_is_unconfined_subset(struct aa_label *set, struct aa_label *sub)
+{
+	struct label_it i = { };
+	struct aa_profile *p;
+
+	AA_BUG(!set);
+	AA_BUG(!sub);
+
+	if (sub == set)
+		return true;
+
+	do {
+		p = __aa_label_next_not_in_set(&i, set, sub);
+		if (p && !profile_unconfined(p))
+			break;
+	} while (p);
+
+	return p == NULL;
+}
 
 
 /**
@@ -1749,13 +1782,13 @@ void aa_label_seq_xprint(struct seq_file *f, struct aa_ns *ns,
 			AA_DEBUG("label print error");
 			return;
 		}
-		seq_printf(f, "%s", str);
+		seq_puts(f, str);
 		kfree(str);
 	} else if (display_mode(ns, label, flags))
 		seq_printf(f, "%s (%s)", label->hname,
 			   label_modename(ns, label, flags));
 	else
-		seq_printf(f, "%s", label->hname);
+		seq_puts(f, label->hname);
 }
 
 void aa_label_xprintk(struct aa_ns *ns, struct aa_label *label, int flags,
diff --git a/security/apparmor/match.c b/security/apparmor/match.c
index 525ce22dc0e9..e605b7d53fb4 100644
--- a/security/apparmor/match.c
+++ b/security/apparmor/match.c
@@ -202,6 +202,26 @@ static int verify_dfa(struct aa_dfa *dfa)
 		if (!(BASE_TABLE(dfa)[i] & MATCH_FLAG_DIFF_ENCODE) &&
 		    (DEFAULT_TABLE(dfa)[i] >= state_count))
 			goto out;
+		if (BASE_TABLE(dfa)[i] & MATCH_FLAGS_INVALID) {
+			pr_err("AppArmor DFA state with invalid match flags");
+			goto out;
+		}
+		if ((BASE_TABLE(dfa)[i] & MATCH_FLAG_DIFF_ENCODE)) {
+			if (!(dfa->flags & YYTH_FLAG_DIFF_ENCODE)) {
+				pr_err("AppArmor DFA diff encoded transition state without header flag");
+				goto out;
+			}
+		}
+		if ((BASE_TABLE(dfa)[i] & MATCH_FLAG_OOB_TRANSITION)) {
+			if (base_idx(BASE_TABLE(dfa)[i]) < dfa->max_oob) {
+				pr_err("AppArmor DFA out of bad transition out of range");
+				goto out;
+			}
+			if (!(dfa->flags & YYTH_FLAG_OOB_TRANS)) {
+				pr_err("AppArmor DFA out of bad transition state without header flag");
+				goto out;
+			}
+		}
 		if (base_idx(BASE_TABLE(dfa)[i]) + 255 >= trans_count) {
 			pr_err("AppArmor DFA next/check upper bounds error\n");
 			goto out;
@@ -304,9 +324,23 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags)
 		goto fail;
 
 	dfa->flags = ntohs(*(__be16 *) (data + 12));
-	if (dfa->flags != 0 && dfa->flags != YYTH_FLAG_DIFF_ENCODE)
+	if (dfa->flags & ~(YYTH_FLAGS))
 		goto fail;
 
+	/*
+	 * TODO: needed for dfa to support more than 1 oob
+	 * if (dfa->flags & YYTH_FLAGS_OOB_TRANS) {
+	 *	if (hsize < 16 + 4)
+	 *		goto fail;
+	 *	dfa->max_oob = ntol(*(__be32 *) (data + 16));
+	 *	if (dfa->max <= MAX_OOB_SUPPORTED) {
+	 *		pr_err("AppArmor DFA OOB greater than supported\n");
+	 *		goto fail;
+	 *	}
+	 * }
+	 */
+	dfa->max_oob = 1;
+
 	data += hsize;
 	size -= hsize;
 
@@ -495,6 +529,23 @@ unsigned int aa_dfa_next(struct aa_dfa *dfa, unsigned int state,
 	return state;
 }
 
+unsigned int aa_dfa_outofband_transition(struct aa_dfa *dfa, unsigned int state)
+{
+	u16 *def = DEFAULT_TABLE(dfa);
+	u32 *base = BASE_TABLE(dfa);
+	u16 *next = NEXT_TABLE(dfa);
+	u16 *check = CHECK_TABLE(dfa);
+	u32 b = (base)[(state)];
+
+	if (!(b & MATCH_FLAG_OOB_TRANSITION))
+		return DFA_NOMATCH;
+
+	/* No Equivalence class remapping for outofband transitions */
+	match_char(state, def, base, next, check, -1);
+
+	return state;
+}
+
 /**
  * aa_dfa_match_until - traverse @dfa until accept state or end of input
  * @dfa: the dfa to match @str against  (NOT NULL)
diff --git a/security/apparmor/path.c b/security/apparmor/path.c
index c6da542de27b..b02dfdbff7cd 100644
--- a/security/apparmor/path.c
+++ b/security/apparmor/path.c
@@ -142,7 +142,7 @@ static int d_namespace_path(const struct path *path, char *buf, char **name,
 			error = PTR_ERR(res);
 			*name = buf;
 			goto out;
-		};
+		}
 	} else if (!our_mnt(path->mnt))
 		connected = 0;
 
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
index 2d743c004bc4..2dfe0781b0a4 100644
--- a/security/apparmor/policy_unpack.c
+++ b/security/apparmor/policy_unpack.c
@@ -748,10 +748,14 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
 		goto fail;
 	if (tmp == PACKED_MODE_COMPLAIN || (e->version & FORCE_COMPLAIN_FLAG))
 		profile->mode = APPARMOR_COMPLAIN;
+	else if (tmp == PACKED_MODE_ENFORCE)
+		profile->mode = APPARMOR_ENFORCE;
 	else if (tmp == PACKED_MODE_KILL)
 		profile->mode = APPARMOR_KILL;
 	else if (tmp == PACKED_MODE_UNCONFINED)
 		profile->mode = APPARMOR_UNCONFINED;
+	else
+		goto fail;
 	if (!unpack_u32(e, &tmp, NULL))
 		goto fail;
 	if (tmp)
diff --git a/security/device_cgroup.c b/security/device_cgroup.c
index 7d0f8f7431ff..43ab0ad45c1b 100644
--- a/security/device_cgroup.c
+++ b/security/device_cgroup.c
@@ -15,6 +15,8 @@
 #include <linux/rcupdate.h>
 #include <linux/mutex.h>
 
+#ifdef CONFIG_CGROUP_DEVICE
+
 static DEFINE_MUTEX(devcgroup_mutex);
 
 enum devcg_behavior {
@@ -792,7 +794,7 @@ struct cgroup_subsys devices_cgrp_subsys = {
 };
 
 /**
- * __devcgroup_check_permission - checks if an inode operation is permitted
+ * devcgroup_legacy_check_permission - checks if an inode operation is permitted
  * @dev_cgroup: the dev cgroup to be tested against
  * @type: device type
  * @major: device major number
@@ -801,7 +803,7 @@ struct cgroup_subsys devices_cgrp_subsys = {
  *
  * returns 0 on success, -EPERM case the operation is not permitted
  */
-static int __devcgroup_check_permission(short type, u32 major, u32 minor,
+static int devcgroup_legacy_check_permission(short type, u32 major, u32 minor,
 					short access)
 {
 	struct dev_cgroup *dev_cgroup;
@@ -825,6 +827,10 @@ static int __devcgroup_check_permission(short type, u32 major, u32 minor,
 	return 0;
 }
 
+#endif /* CONFIG_CGROUP_DEVICE */
+
+#if defined(CONFIG_CGROUP_DEVICE) || defined(CONFIG_CGROUP_BPF)
+
 int devcgroup_check_permission(short type, u32 major, u32 minor, short access)
 {
 	int rc = BPF_CGROUP_RUN_PROG_DEVICE_CGROUP(type, major, minor, access);
@@ -832,6 +838,13 @@ int devcgroup_check_permission(short type, u32 major, u32 minor, short access)
 	if (rc)
 		return -EPERM;
 
-	return __devcgroup_check_permission(type, major, minor, access);
+	#ifdef CONFIG_CGROUP_DEVICE
+	return devcgroup_legacy_check_permission(type, major, minor, access);
+
+	#else /* CONFIG_CGROUP_DEVICE */
+	return 0;
+
+	#endif /* CONFIG_CGROUP_DEVICE */
 }
 EXPORT_SYMBOL(devcgroup_check_permission);
+#endif /* defined(CONFIG_CGROUP_DEVICE) || defined(CONFIG_CGROUP_BPF) */
diff --git a/security/keys/Kconfig b/security/keys/Kconfig
index 47c041563d41..d4dc5ea208af 100644
--- a/security/keys/Kconfig
+++ b/security/keys/Kconfig
@@ -116,3 +116,12 @@ config KEY_DH_OPERATIONS
 	 in the kernel.
 
 	 If you are unsure as to whether this is required, answer N.
+
+config KEY_NOTIFICATIONS
+	bool "Provide key/keyring change notifications"
+	depends on KEYS && WATCH_QUEUE
+	help
+	  This option provides support for getting change notifications on keys
+	  and keyrings on which the caller has View permission.  This makes use
+	  of the /dev/watch_queue misc device to handle the notification
+	  buffer and provides KEYCTL_WATCH_KEY to enable/disable watches.
diff --git a/security/keys/compat.c b/security/keys/compat.c
index b975f8f11124..6ee9d8f6a4a5 100644
--- a/security/keys/compat.c
+++ b/security/keys/compat.c
@@ -156,6 +156,9 @@ COMPAT_SYSCALL_DEFINE5(keyctl, u32, option,
 	case KEYCTL_CAPABILITIES:
 		return keyctl_capabilities(compat_ptr(arg2), arg3);
 
+	case KEYCTL_WATCH_KEY:
+		return keyctl_watch_key(arg2, arg3, arg4);
+
 	default:
 		return -EOPNOTSUPP;
 	}
diff --git a/security/keys/gc.c b/security/keys/gc.c
index 671dd730ecfc..3c90807476eb 100644
--- a/security/keys/gc.c
+++ b/security/keys/gc.c
@@ -131,6 +131,11 @@ static noinline void key_gc_unused_keys(struct list_head *keys)
 		kdebug("- %u", key->serial);
 		key_check(key);
 
+#ifdef CONFIG_KEY_NOTIFICATIONS
+		remove_watch_list(key->watchers, key->serial);
+		key->watchers = NULL;
+#endif
+
 		/* Throw away the key data if the key is instantiated */
 		if (state == KEY_IS_POSITIVE && key->type->destroy)
 			key->type->destroy(key);
diff --git a/security/keys/internal.h b/security/keys/internal.h
index 6d0ca48ae9a5..28e17f4f3328 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -15,6 +15,7 @@
 #include <linux/task_work.h>
 #include <linux/keyctl.h>
 #include <linux/refcount.h>
+#include <linux/watch_queue.h>
 #include <linux/compat.h>
 #include <linux/mm.h>
 #include <linux/vmalloc.h>
@@ -99,7 +100,8 @@ extern int __key_link_begin(struct key *keyring,
 			    const struct keyring_index_key *index_key,
 			    struct assoc_array_edit **_edit);
 extern int __key_link_check_live_key(struct key *keyring, struct key *key);
-extern void __key_link(struct key *key, struct assoc_array_edit **_edit);
+extern void __key_link(struct key *keyring, struct key *key,
+		       struct assoc_array_edit **_edit);
 extern void __key_link_end(struct key *keyring,
 			   const struct keyring_index_key *index_key,
 			   struct assoc_array_edit *edit);
@@ -183,6 +185,23 @@ extern int key_task_permission(const key_ref_t key_ref,
 			       const struct cred *cred,
 			       key_perm_t perm);
 
+static inline void notify_key(struct key *key,
+			      enum key_notification_subtype subtype, u32 aux)
+{
+#ifdef CONFIG_KEY_NOTIFICATIONS
+	struct key_notification n = {
+		.watch.type	= WATCH_TYPE_KEY_NOTIFY,
+		.watch.subtype	= subtype,
+		.watch.info	= watch_sizeof(n),
+		.key_id		= key_serial(key),
+		.aux		= aux,
+	};
+
+	post_watch_notification(key->watchers, &n.watch, current_cred(),
+				n.key_id);
+#endif
+}
+
 /*
  * Check to see whether permission is granted to use a key in the desired way.
  */
@@ -333,6 +352,15 @@ static inline long keyctl_pkey_e_d_s(int op,
 
 extern long keyctl_capabilities(unsigned char __user *_buffer, size_t buflen);
 
+#ifdef CONFIG_KEY_NOTIFICATIONS
+extern long keyctl_watch_key(key_serial_t, int, int);
+#else
+static inline long keyctl_watch_key(key_serial_t key_id, int watch_fd, int watch_id)
+{
+	return -EOPNOTSUPP;
+}
+#endif
+
 /*
  * Debugging key validation
  */
diff --git a/security/keys/key.c b/security/keys/key.c
index e959b3c96b48..e282c6179b21 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -444,6 +444,7 @@ static int __key_instantiate_and_link(struct key *key,
 			/* mark the key as being instantiated */
 			atomic_inc(&key->user->nikeys);
 			mark_key_instantiated(key, 0);
+			notify_key(key, NOTIFY_KEY_INSTANTIATED, 0);
 
 			if (test_and_clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags))
 				awaken = 1;
@@ -453,7 +454,7 @@ static int __key_instantiate_and_link(struct key *key,
 				if (test_bit(KEY_FLAG_KEEP, &keyring->flags))
 					set_bit(KEY_FLAG_KEEP, &key->flags);
 
-				__key_link(key, _edit);
+				__key_link(keyring, key, _edit);
 			}
 
 			/* disable the authorisation key */
@@ -601,6 +602,7 @@ int key_reject_and_link(struct key *key,
 		/* mark the key as being negatively instantiated */
 		atomic_inc(&key->user->nikeys);
 		mark_key_instantiated(key, -error);
+		notify_key(key, NOTIFY_KEY_INSTANTIATED, -error);
 		key->expiry = ktime_get_real_seconds() + timeout;
 		key_schedule_gc(key->expiry + key_gc_delay);
 
@@ -611,7 +613,7 @@ int key_reject_and_link(struct key *key,
 
 		/* and link it into the destination keyring */
 		if (keyring && link_ret == 0)
-			__key_link(key, &edit);
+			__key_link(keyring, key, &edit);
 
 		/* disable the authorisation key */
 		if (authkey)
@@ -764,9 +766,11 @@ static inline key_ref_t __key_update(key_ref_t key_ref,
 	down_write(&key->sem);
 
 	ret = key->type->update(key, prep);
-	if (ret == 0)
+	if (ret == 0) {
 		/* Updating a negative key positively instantiates it */
 		mark_key_instantiated(key, 0);
+		notify_key(key, NOTIFY_KEY_UPDATED, 0);
+	}
 
 	up_write(&key->sem);
 
@@ -1023,9 +1027,11 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen)
 	down_write(&key->sem);
 
 	ret = key->type->update(key, &prep);
-	if (ret == 0)
+	if (ret == 0) {
 		/* Updating a negative key positively instantiates it */
 		mark_key_instantiated(key, 0);
+		notify_key(key, NOTIFY_KEY_UPDATED, 0);
+	}
 
 	up_write(&key->sem);
 
@@ -1057,15 +1063,17 @@ void key_revoke(struct key *key)
 	 *   instantiated
 	 */
 	down_write_nested(&key->sem, 1);
-	if (!test_and_set_bit(KEY_FLAG_REVOKED, &key->flags) &&
-	    key->type->revoke)
-		key->type->revoke(key);
-
-	/* set the death time to no more than the expiry time */
-	time = ktime_get_real_seconds();
-	if (key->revoked_at == 0 || key->revoked_at > time) {
-		key->revoked_at = time;
-		key_schedule_gc(key->revoked_at + key_gc_delay);
+	if (!test_and_set_bit(KEY_FLAG_REVOKED, &key->flags)) {
+		notify_key(key, NOTIFY_KEY_REVOKED, 0);
+		if (key->type->revoke)
+			key->type->revoke(key);
+
+		/* set the death time to no more than the expiry time */
+		time = ktime_get_real_seconds();
+		if (key->revoked_at == 0 || key->revoked_at > time) {
+			key->revoked_at = time;
+			key_schedule_gc(key->revoked_at + key_gc_delay);
+		}
 	}
 
 	up_write(&key->sem);
@@ -1087,8 +1095,10 @@ void key_invalidate(struct key *key)
 
 	if (!test_bit(KEY_FLAG_INVALIDATED, &key->flags)) {
 		down_write_nested(&key->sem, 1);
-		if (!test_and_set_bit(KEY_FLAG_INVALIDATED, &key->flags))
+		if (!test_and_set_bit(KEY_FLAG_INVALIDATED, &key->flags)) {
+			notify_key(key, NOTIFY_KEY_INVALIDATED, 0);
 			key_schedule_gc_links();
+		}
 		up_write(&key->sem);
 	}
 }
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index 5e01192e222a..7d8de1c9a478 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -37,7 +37,9 @@ static const unsigned char keyrings_capabilities[2] = {
 	       KEYCTL_CAPS0_MOVE
 	       ),
 	[1] = (KEYCTL_CAPS1_NS_KEYRING_NAME |
-	       KEYCTL_CAPS1_NS_KEY_TAG),
+	       KEYCTL_CAPS1_NS_KEY_TAG |
+	       (IS_ENABLED(CONFIG_KEY_NOTIFICATIONS)	? KEYCTL_CAPS1_NOTIFICATIONS : 0)
+	       ),
 };
 
 static int key_get_type_from_user(char *type,
@@ -1039,6 +1041,7 @@ long keyctl_chown_key(key_serial_t id, uid_t user, gid_t group)
 	if (group != (gid_t) -1)
 		key->gid = gid;
 
+	notify_key(key, NOTIFY_KEY_SETATTR, 0);
 	ret = 0;
 
 error_put:
@@ -1089,6 +1092,7 @@ long keyctl_setperm_key(key_serial_t id, key_perm_t perm)
 	/* if we're not the sysadmin, we can only change a key that we own */
 	if (capable(CAP_SYS_ADMIN) || uid_eq(key->uid, current_fsuid())) {
 		key->perm = perm;
+		notify_key(key, NOTIFY_KEY_SETATTR, 0);
 		ret = 0;
 	}
 
@@ -1480,10 +1484,12 @@ long keyctl_set_timeout(key_serial_t id, unsigned timeout)
 okay:
 	key = key_ref_to_ptr(key_ref);
 	ret = 0;
-	if (test_bit(KEY_FLAG_KEEP, &key->flags))
+	if (test_bit(KEY_FLAG_KEEP, &key->flags)) {
 		ret = -EPERM;
-	else
+	} else {
 		key_set_timeout(key, timeout);
+		notify_key(key, NOTIFY_KEY_SETATTR, 0);
+	}
 	key_put(key);
 
 error:
@@ -1757,6 +1763,90 @@ long keyctl_restrict_keyring(key_serial_t id, const char __user *_type,
 	return ret;
 }
 
+#ifdef CONFIG_KEY_NOTIFICATIONS
+/*
+ * Watch for changes to a key.
+ *
+ * The caller must have View permission to watch a key or keyring.
+ */
+long keyctl_watch_key(key_serial_t id, int watch_queue_fd, int watch_id)
+{
+	struct watch_queue *wqueue;
+	struct watch_list *wlist = NULL;
+	struct watch *watch = NULL;
+	struct key *key;
+	key_ref_t key_ref;
+	long ret;
+
+	if (watch_id < -1 || watch_id > 0xff)
+		return -EINVAL;
+
+	key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE, KEY_NEED_VIEW);
+	if (IS_ERR(key_ref))
+		return PTR_ERR(key_ref);
+	key = key_ref_to_ptr(key_ref);
+
+	wqueue = get_watch_queue(watch_queue_fd);
+	if (IS_ERR(wqueue)) {
+		ret = PTR_ERR(wqueue);
+		goto err_key;
+	}
+
+	if (watch_id >= 0) {
+		ret = -ENOMEM;
+		if (!key->watchers) {
+			wlist = kzalloc(sizeof(*wlist), GFP_KERNEL);
+			if (!wlist)
+				goto err_wqueue;
+			init_watch_list(wlist, NULL);
+		}
+
+		watch = kzalloc(sizeof(*watch), GFP_KERNEL);
+		if (!watch)
+			goto err_wlist;
+
+		init_watch(watch, wqueue);
+		watch->id	= key->serial;
+		watch->info_id	= (u32)watch_id << WATCH_INFO_ID__SHIFT;
+
+		ret = security_watch_key(key);
+		if (ret < 0)
+			goto err_watch;
+
+		down_write(&key->sem);
+		if (!key->watchers) {
+			key->watchers = wlist;
+			wlist = NULL;
+		}
+
+		ret = add_watch_to_object(watch, key->watchers);
+		up_write(&key->sem);
+
+		if (ret == 0)
+			watch = NULL;
+	} else {
+		ret = -EBADSLT;
+		if (key->watchers) {
+			down_write(&key->sem);
+			ret = remove_watch_from_object(key->watchers,
+						       wqueue, key_serial(key),
+						       false);
+			up_write(&key->sem);
+		}
+	}
+
+err_watch:
+	kfree(watch);
+err_wlist:
+	kfree(wlist);
+err_wqueue:
+	put_watch_queue(wqueue);
+err_key:
+	key_put(key);
+	return ret;
+}
+#endif /* CONFIG_KEY_NOTIFICATIONS */
+
 /*
  * Get keyrings subsystem capabilities.
  */
@@ -1926,6 +2016,9 @@ SYSCALL_DEFINE5(keyctl, int, option, unsigned long, arg2, unsigned long, arg3,
 	case KEYCTL_CAPABILITIES:
 		return keyctl_capabilities((unsigned char __user *)arg2, (size_t)arg3);
 
+	case KEYCTL_WATCH_KEY:
+		return keyctl_watch_key((key_serial_t)arg2, (int)arg3, (int)arg4);
+
 	default:
 		return -EOPNOTSUPP;
 	}
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index 5ca620d31cd3..14abfe765b7e 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -1056,12 +1056,14 @@ int keyring_restrict(key_ref_t keyring_ref, const char *type,
 	down_write(&keyring->sem);
 	down_write(&keyring_serialise_restrict_sem);
 
-	if (keyring->restrict_link)
+	if (keyring->restrict_link) {
 		ret = -EEXIST;
-	else if (keyring_detect_restriction_cycle(keyring, restrict_link))
+	} else if (keyring_detect_restriction_cycle(keyring, restrict_link)) {
 		ret = -EDEADLK;
-	else
+	} else {
 		keyring->restrict_link = restrict_link;
+		notify_key(keyring, NOTIFY_KEY_SETATTR, 0);
+	}
 
 	up_write(&keyring_serialise_restrict_sem);
 	up_write(&keyring->sem);
@@ -1362,12 +1364,14 @@ int __key_link_check_live_key(struct key *keyring, struct key *key)
  * holds at most one link to any given key of a particular type+description
  * combination.
  */
-void __key_link(struct key *key, struct assoc_array_edit **_edit)
+void __key_link(struct key *keyring, struct key *key,
+		struct assoc_array_edit **_edit)
 {
 	__key_get(key);
 	assoc_array_insert_set_object(*_edit, keyring_key_to_ptr(key));
 	assoc_array_apply_edit(*_edit);
 	*_edit = NULL;
+	notify_key(keyring, NOTIFY_KEY_LINKED, key_serial(key));
 }
 
 /*
@@ -1451,7 +1455,7 @@ int key_link(struct key *keyring, struct key *key)
 	if (ret == 0)
 		ret = __key_link_check_live_key(keyring, key);
 	if (ret == 0)
-		__key_link(key, &edit);
+		__key_link(keyring, key, &edit);
 
 error_end:
 	__key_link_end(keyring, &key->index_key, edit);
@@ -1483,7 +1487,7 @@ static int __key_unlink_begin(struct key *keyring, struct key *key,
 	struct assoc_array_edit *edit;
 
 	BUG_ON(*_edit != NULL);
-	
+
 	edit = assoc_array_delete(&keyring->keys, &keyring_assoc_array_ops,
 				  &key->index_key);
 	if (IS_ERR(edit))
@@ -1503,6 +1507,7 @@ static void __key_unlink(struct key *keyring, struct key *key,
 			 struct assoc_array_edit **_edit)
 {
 	assoc_array_apply_edit(*_edit);
+	notify_key(keyring, NOTIFY_KEY_UNLINKED, key_serial(key));
 	*_edit = NULL;
 	key_payload_reserve(keyring, keyring->datalen - KEYQUOTA_LINK_BYTES);
 }
@@ -1621,7 +1626,7 @@ int key_move(struct key *key,
 		goto error;
 
 	__key_unlink(from_keyring, key, &from_edit);
-	__key_link(key, &to_edit);
+	__key_link(to_keyring, key, &to_edit);
 error:
 	__key_link_end(to_keyring, &key->index_key, to_edit);
 	__key_unlink_end(from_keyring, key, from_edit);
@@ -1655,6 +1660,7 @@ int keyring_clear(struct key *keyring)
 	} else {
 		if (edit)
 			assoc_array_apply_edit(edit);
+		notify_key(keyring, NOTIFY_KEY_CLEARED, 0);
 		key_payload_reserve(keyring, 0);
 		ret = 0;
 	}
diff --git a/security/keys/proc.c b/security/keys/proc.c
index 415f3f1c2da0..d0cde6685627 100644
--- a/security/keys/proc.c
+++ b/security/keys/proc.c
@@ -139,6 +139,8 @@ static void *proc_keys_next(struct seq_file *p, void *v, loff_t *_pos)
 	n = key_serial_next(p, v);
 	if (n)
 		*_pos = key_node_serial(n);
+	else
+		(*_pos)++;
 	return n;
 }
 
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index 957b9e3e1492..e1b9f1a80676 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -418,7 +418,7 @@ static int construct_alloc_key(struct keyring_search_context *ctx,
 		goto key_already_present;
 
 	if (dest_keyring)
-		__key_link(key, &edit);
+		__key_link(dest_keyring, key, &edit);
 
 	mutex_unlock(&key_construction_mutex);
 	if (dest_keyring)
@@ -437,7 +437,7 @@ static int construct_alloc_key(struct keyring_search_context *ctx,
 	if (dest_keyring) {
 		ret = __key_link_check_live_key(dest_keyring, key);
 		if (ret == 0)
-			__key_link(key, &edit);
+			__key_link(dest_keyring, key, &edit);
 		__key_link_end(dest_keyring, &ctx->index_key, edit);
 		if (ret < 0)
 			goto link_check_failed;
diff --git a/security/security.c b/security/security.c
index 7fed24b9d57e..43825cbcbe53 100644
--- a/security/security.c
+++ b/security/security.c
@@ -2007,6 +2007,29 @@ int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
 }
 EXPORT_SYMBOL(security_inode_getsecctx);
 
+#ifdef CONFIG_WATCH_QUEUE
+int security_post_notification(const struct cred *w_cred,
+			       const struct cred *cred,
+			       struct watch_notification *n)
+{
+	return call_int_hook(post_notification, 0, w_cred, cred, n);
+}
+#endif /* CONFIG_WATCH_QUEUE */
+
+#ifdef CONFIG_KEY_NOTIFICATIONS
+int security_watch_key(struct key *key)
+{
+	return call_int_hook(watch_key, 0, key);
+}
+#endif
+
+#ifdef CONFIG_DEVICE_NOTIFICATIONS
+int security_watch_devices(void)
+{
+	return call_int_hook(watch_devices, 0);
+}
+#endif
+
 #ifdef CONFIG_SECURITY_NETWORK
 
 int security_unix_stream_connect(struct sock *sock, struct sock *other, struct sock *newsk)
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 0b4e32161b77..1ae079bf81f4 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -6576,6 +6576,17 @@ static int selinux_key_getsecurity(struct key *key, char **_buffer)
 	*_buffer = context;
 	return rc;
 }
+
+#ifdef CONFIG_KEY_NOTIFICATIONS
+static int selinux_watch_key(struct key *key)
+{
+	struct key_security_struct *ksec = key->security;
+	u32 sid = current_sid();
+
+	return avc_has_perm(&selinux_state,
+			    sid, ksec->sid, SECCLASS_KEY, KEY_NEED_VIEW, NULL);
+}
+#endif
 #endif
 
 #ifdef CONFIG_SECURITY_INFINIBAND
@@ -7091,6 +7102,9 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
 	LSM_HOOK_INIT(key_free, selinux_key_free),
 	LSM_HOOK_INIT(key_permission, selinux_key_permission),
 	LSM_HOOK_INIT(key_getsecurity, selinux_key_getsecurity),
+#ifdef CONFIG_KEY_NOTIFICATIONS
+	LSM_HOOK_INIT(watch_key, selinux_watch_key),
+#endif
 #endif
 
 #ifdef CONFIG_AUDIT
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
index ec5e3d1da9ac..6a5d7d08933d 100644
--- a/security/selinux/ss/mls.c
+++ b/security/selinux/ss/mls.c
@@ -536,7 +536,7 @@ int mls_compute_sid(struct policydb *p,
 
 		/* Fallthrough */
 	case AVTAB_CHANGE:
-		if ((tclass == p->process_class) || (sock == true))
+		if ((tclass == p->process_class) || sock)
 			/* Use the process MLS attributes. */
 			return mls_context_cpy(newcontext, scontext);
 		else
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 70ecdc78efbd..c21b922e5ebe 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -1035,14 +1035,14 @@ static int str_read(char **strp, gfp_t flags, void *fp, u32 len)
 	if (!str)
 		return -ENOMEM;
 
-	/* it's expected the caller should free the str */
-	*strp = str;
-
 	rc = next_entry(str, fp, len);
-	if (rc)
+	if (rc) {
+		kfree(str);
 		return rc;
+	}
 
 	str[len] = '\0';
+	*strp = str;
 	return 0;
 }
 
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 8ad34fd031d1..3b592d17d2d3 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -1812,7 +1812,7 @@ static int security_compute_sid(struct selinux_state *state,
 	} else if (cladatum && cladatum->default_role == DEFAULT_TARGET) {
 		newcontext.role = tcontext->role;
 	} else {
-		if ((tclass == policydb->process_class) || (sock == true))
+		if ((tclass == policydb->process_class) || sock)
 			newcontext.role = scontext->role;
 		else
 			newcontext.role = OBJECT_R_VAL;
@@ -1824,7 +1824,7 @@ static int security_compute_sid(struct selinux_state *state,
 	} else if (cladatum && cladatum->default_type == DEFAULT_TARGET) {
 		newcontext.type = tcontext->type;
 	} else {
-		if ((tclass == policydb->process_class) || (sock == true)) {
+		if ((tclass == policydb->process_class) || sock) {
 			/* Use the type of process. */
 			newcontext.type = scontext->type;
 		} else {
diff --git a/security/selinux/ss/sidtab.c b/security/selinux/ss/sidtab.c
index f511ffccb131..98d5ea3fcde4 100644
--- a/security/selinux/ss/sidtab.c
+++ b/security/selinux/ss/sidtab.c
@@ -276,8 +276,7 @@ int sidtab_context_to_sid(struct sidtab *s, struct context *context,
 	if (*sid)
 		goto out_unlock;
 
-	/* read entries only after reading count */
-	count = smp_load_acquire(&s->count);
+	count = s->count;
 	convert = s->convert;
 
 	/* bail out if we already reached max entries */
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 8c61d175e195..2862fc383473 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -41,6 +41,7 @@
 #include <linux/parser.h>
 #include <linux/fs_context.h>
 #include <linux/fs_parser.h>
+#include <linux/watch_queue.h>
 #include "smack.h"
 
 #define TRANS_TRUE	"TRUE"
@@ -4265,7 +4266,7 @@ static int smack_key_permission(key_ref_t key_ref,
 	if (tkp == NULL)
 		return -EACCES;
 
-	if (smack_privileged_cred(CAP_MAC_OVERRIDE, cred))
+	if (smack_privileged(CAP_MAC_OVERRIDE))
 		return 0;
 
 #ifdef CONFIG_AUDIT
@@ -4311,8 +4312,81 @@ static int smack_key_getsecurity(struct key *key, char **_buffer)
 	return length;
 }
 
+
+#ifdef CONFIG_KEY_NOTIFICATIONS
+/**
+ * smack_watch_key - Smack access to watch a key for notifications.
+ * @key: The key to be watched
+ *
+ * Return 0 if the @watch->cred has permission to read from the key object and
+ * an error otherwise.
+ */
+static int smack_watch_key(struct key *key)
+{
+	struct smk_audit_info ad;
+	struct smack_known *tkp = smk_of_current();
+	int rc;
+
+	if (key == NULL)
+		return -EINVAL;
+	/*
+	 * If the key hasn't been initialized give it access so that
+	 * it may do so.
+	 */
+	if (key->security == NULL)
+		return 0;
+	/*
+	 * This should not occur
+	 */
+	if (tkp == NULL)
+		return -EACCES;
+
+	if (smack_privileged_cred(CAP_MAC_OVERRIDE, current_cred()))
+		return 0;
+
+#ifdef CONFIG_AUDIT
+	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_KEY);
+	ad.a.u.key_struct.key = key->serial;
+	ad.a.u.key_struct.key_desc = key->description;
+#endif
+	rc = smk_access(tkp, key->security, MAY_READ, &ad);
+	rc = smk_bu_note("key watch", tkp, key->security, MAY_READ, rc);
+	return rc;
+}
+#endif /* CONFIG_KEY_NOTIFICATIONS */
 #endif /* CONFIG_KEYS */
 
+#ifdef CONFIG_WATCH_QUEUE
+/**
+ * smack_post_notification - Smack access to post a notification to a queue
+ * @w_cred: The credentials of the watcher.
+ * @cred: The credentials of the event source (may be NULL).
+ * @n: The notification message to be posted.
+ */
+static int smack_post_notification(const struct cred *w_cred,
+				   const struct cred *cred,
+				   struct watch_notification *n)
+{
+	struct smk_audit_info ad;
+	struct smack_known *subj, *obj;
+	int rc;
+
+	/* Always let maintenance notifications through. */
+	if (n->type == WATCH_TYPE_META)
+		return 0;
+
+	if (!cred)
+		return 0;
+	subj = smk_of_task(smack_cred(cred));
+	obj = smk_of_task(smack_cred(w_cred));
+
+	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NOTIFICATION);
+	rc = smk_access(subj, obj, MAY_WRITE, &ad);
+	rc = smk_bu_note("notification", subj, obj, MAY_WRITE, rc);
+	return rc;
+}
+#endif /* CONFIG_WATCH_QUEUE */
+
 /*
  * Smack Audit hooks
  *
@@ -4701,8 +4775,15 @@ static struct security_hook_list smack_hooks[] __lsm_ro_after_init = {
 	LSM_HOOK_INIT(key_free, smack_key_free),
 	LSM_HOOK_INIT(key_permission, smack_key_permission),
 	LSM_HOOK_INIT(key_getsecurity, smack_key_getsecurity),
+#ifdef CONFIG_KEY_NOTIFICATIONS
+	LSM_HOOK_INIT(watch_key, smack_watch_key),
+#endif
 #endif /* CONFIG_KEYS */
 
+#ifdef CONFIG_WATCH_QUEUE
+	LSM_HOOK_INIT(post_notification, smack_post_notification),
+#endif
+
  /* Audit hooks */
 #ifdef CONFIG_AUDIT
 	LSM_HOOK_INIT(audit_rule_init, smack_audit_rule_init),
diff --git a/sound/hda/Kconfig b/sound/hda/Kconfig
index 4ca6b09056f3..3bc9224d5e4f 100644
--- a/sound/hda/Kconfig
+++ b/sound/hda/Kconfig
@@ -21,16 +21,17 @@ config SND_HDA_EXT_CORE
        select SND_HDA_CORE
 
 config SND_HDA_PREALLOC_SIZE
-	int "Pre-allocated buffer size for HD-audio driver" if !SND_DMA_SGBUF
+	int "Pre-allocated buffer size for HD-audio driver"
 	range 0 32768
-	default 0 if SND_DMA_SGBUF
+	default 2048 if SND_DMA_SGBUF
 	default 64 if !SND_DMA_SGBUF
 	help
 	  Specifies the default pre-allocated buffer-size in kB for the
 	  HD-audio driver.  A larger buffer (e.g. 2048) is preferred
 	  for systems using PulseAudio.  The default 64 is chosen just
 	  for compatibility reasons.
-	  On x86 systems, the default is zero as we need no preallocation.
+	  On x86 systems, the default is 2048 as a reasonable value for
+	  most of modern systems.
 
 	  Note that the pre-allocation size can be changed dynamically
 	  via a proc file (/proc/asound/card*/pcm*/sub*/prealloc), too.
diff --git a/sound/hda/intel-dsp-config.c b/sound/hda/intel-dsp-config.c
index be1df80ed013..1c1fdab2a55f 100644
--- a/sound/hda/intel-dsp-config.c
+++ b/sound/hda/intel-dsp-config.c
@@ -1,10 +1,13 @@
 // SPDX-License-Identifier: GPL-2.0
 // Copyright (c) 2019 Jaroslav Kysela <perex@perex.cz>
 
+#include <linux/acpi.h>
 #include <linux/bits.h>
 #include <linux/dmi.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/soundwire/sdw.h>
+#include <linux/soundwire/sdw_intel.h>
 #include <sound/core.h>
 #include <sound/intel-dsp-config.h>
 #include <sound/intel-nhlt.h>
@@ -14,9 +17,13 @@ static int dsp_driver;
 module_param(dsp_driver, int, 0444);
 MODULE_PARM_DESC(dsp_driver, "Force the DSP driver for Intel DSP (0=auto, 1=legacy, 2=SST, 3=SOF)");
 
-#define FLAG_SST		BIT(0)
-#define FLAG_SOF		BIT(1)
-#define FLAG_SOF_ONLY_IF_DMIC	BIT(16)
+#define FLAG_SST			BIT(0)
+#define FLAG_SOF			BIT(1)
+#define FLAG_SOF_ONLY_IF_DMIC		BIT(16)
+#define FLAG_SOF_ONLY_IF_SOUNDWIRE	BIT(17)
+
+#define FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE (FLAG_SOF_ONLY_IF_DMIC | \
+					    FLAG_SOF_ONLY_IF_SOUNDWIRE)
 
 struct config_entry {
 	u32 flags;
@@ -166,7 +173,7 @@ static const struct config_entry config_table[] = {
 		}
 	},
 	{
-		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
+		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
 		.device = 0x9dc8,
 	},
 #endif
@@ -187,7 +194,7 @@ static const struct config_entry config_table[] = {
 		}
 	},
 	{
-		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
+		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
 		.device = 0xa348,
 	},
 #endif
@@ -204,18 +211,50 @@ static const struct config_entry config_table[] = {
 					DMI_MATCH(DMI_SYS_VENDOR, "Google"),
 				}
 			},
+			{
+				.matches = {
+					DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
+					DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "09C6")
+				},
+			},
+			{
+				/* early version of SKU 09C6 */
+				.matches = {
+					DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
+					DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0983")
+				},
+			},
 			{}
 		}
 	},
 	{
-		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
+		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
 		.device = 0x02c8,
 	},
 #endif
 /* Cometlake-H */
 #if IS_ENABLED(CONFIG_SND_SOC_SOF_COMETLAKE_H)
 	{
-		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
+		.flags = FLAG_SOF,
+		.device = 0x06c8,
+		.dmi_table = (const struct dmi_system_id []) {
+			{
+				.matches = {
+					DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
+					DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "098F"),
+				},
+			},
+			{
+				.matches = {
+					DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
+					DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0990"),
+				},
+			},
+			{}
+		}
+	},
+	{
+		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
 		.device = 0x06c8,
 	},
 #endif
@@ -236,7 +275,7 @@ static const struct config_entry config_table[] = {
 		}
 	},
 	{
-		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
+		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
 		.device = 0x34c8,
 	},
 #endif
@@ -256,9 +295,8 @@ static const struct config_entry config_table[] = {
 			{}
 		}
 	},
-
 	{
-		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
+		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
 		.device = 0xa0c8,
 	},
 #endif
@@ -303,6 +341,28 @@ static int snd_intel_dsp_check_dmic(struct pci_dev *pci)
 	return ret;
 }
 
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE)
+static int snd_intel_dsp_check_soundwire(struct pci_dev *pci)
+{
+	struct sdw_intel_acpi_info info;
+	acpi_handle handle;
+	int ret;
+
+	handle = ACPI_HANDLE(&pci->dev);
+
+	ret = sdw_intel_acpi_scan(handle, &info);
+	if (ret < 0)
+		return ret;
+
+	return info.link_mask;
+}
+#else
+static int snd_intel_dsp_check_soundwire(struct pci_dev *pci)
+{
+	return 0;
+}
+#endif
+
 int snd_intel_dsp_driver_probe(struct pci_dev *pci)
 {
 	const struct config_entry *cfg;
@@ -336,14 +396,18 @@ int snd_intel_dsp_driver_probe(struct pci_dev *pci)
 		return SND_INTEL_DSP_DRIVER_ANY;
 
 	if (cfg->flags & FLAG_SOF) {
-		if (cfg->flags & FLAG_SOF_ONLY_IF_DMIC) {
-			if (snd_intel_dsp_check_dmic(pci)) {
-				dev_info(&pci->dev, "Digital mics found on Skylake+ platform, using SOF driver\n");
-				return SND_INTEL_DSP_DRIVER_SOF;
-			}
-		} else {
+		if (cfg->flags & FLAG_SOF_ONLY_IF_SOUNDWIRE &&
+		    snd_intel_dsp_check_soundwire(pci) > 0) {
+			dev_info(&pci->dev, "SoundWire enabled on CannonLake+ platform, using SOF driver\n");
+			return SND_INTEL_DSP_DRIVER_SOF;
+		}
+		if (cfg->flags & FLAG_SOF_ONLY_IF_DMIC &&
+		    snd_intel_dsp_check_dmic(pci)) {
+			dev_info(&pci->dev, "Digital mics found on Skylake+ platform, using SOF driver\n");
 			return SND_INTEL_DSP_DRIVER_SOF;
 		}
+		if (!(cfg->flags & FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE))
+			return SND_INTEL_DSP_DRIVER_SOF;
 	}
 
 	if (cfg->flags & FLAG_SST)
@@ -355,3 +419,4 @@ EXPORT_SYMBOL_GPL(snd_intel_dsp_driver_probe);
 
 MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("Intel DSP config driver");
+MODULE_IMPORT_NS(SOUNDWIRE_INTEL_INIT);
diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c
index 6e3177bcc709..015c0d676897 100644
--- a/sound/pci/ctxfi/cthw20k1.c
+++ b/sound/pci/ctxfi/cthw20k1.c
@@ -168,7 +168,7 @@ static int src_get_rsc_ctrl_blk(void **rblk)
 
 static int src_put_rsc_ctrl_blk(void *blk)
 {
-	kfree((struct src_rsc_ctrl_blk *)blk);
+	kfree(blk);
 
 	return 0;
 }
@@ -494,7 +494,7 @@ static int src_mgr_get_ctrl_blk(void **rblk)
 
 static int src_mgr_put_ctrl_blk(void *blk)
 {
-	kfree((struct src_mgr_ctrl_blk *)blk);
+	kfree(blk);
 
 	return 0;
 }
@@ -515,7 +515,7 @@ static int srcimp_mgr_get_ctrl_blk(void **rblk)
 
 static int srcimp_mgr_put_ctrl_blk(void *blk)
 {
-	kfree((struct srcimp_mgr_ctrl_blk *)blk);
+	kfree(blk);
 
 	return 0;
 }
@@ -702,7 +702,7 @@ static int amixer_rsc_get_ctrl_blk(void **rblk)
 
 static int amixer_rsc_put_ctrl_blk(void *blk)
 {
-	kfree((struct amixer_rsc_ctrl_blk *)blk);
+	kfree(blk);
 
 	return 0;
 }
@@ -909,7 +909,7 @@ static int dai_get_ctrl_blk(void **rblk)
 
 static int dai_put_ctrl_blk(void *blk)
 {
-	kfree((struct dai_ctrl_blk *)blk);
+	kfree(blk);
 
 	return 0;
 }
@@ -958,7 +958,7 @@ static int dao_get_ctrl_blk(void **rblk)
 
 static int dao_put_ctrl_blk(void *blk)
 {
-	kfree((struct dao_ctrl_blk *)blk);
+	kfree(blk);
 
 	return 0;
 }
@@ -1156,7 +1156,7 @@ static int daio_mgr_get_ctrl_blk(struct hw *hw, void **rblk)
 
 static int daio_mgr_put_ctrl_blk(void *blk)
 {
-	kfree((struct daio_mgr_ctrl_blk *)blk);
+	kfree(blk);
 
 	return 0;
 }
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index a34a2c9f4bcf..86a632bf4d50 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -2951,7 +2951,7 @@ static int hda_codec_runtime_resume(struct device *dev)
 static int hda_codec_force_resume(struct device *dev)
 {
 	struct hda_codec *codec = dev_to_hda_codec(dev);
-	bool forced_resume = !codec->relaxed_resume && codec->jacktbl.used;
+	bool forced_resume = hda_codec_need_resume(codec);
 	int ret;
 
 	/* The get/put pair below enforces the runtime resume even if the
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index bd093593f8fb..a5fab12defde 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1027,7 +1027,7 @@ static int azx_suspend(struct device *dev)
 	chip = card->private_data;
 	bus = azx_bus(chip);
 	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
-	__azx_runtime_suspend(chip);
+	pm_runtime_force_suspend(dev);
 	if (bus->irq >= 0) {
 		free_irq(bus->irq, chip);
 		bus->irq = -1;
@@ -1044,7 +1044,9 @@ static int azx_suspend(struct device *dev)
 static int azx_resume(struct device *dev)
 {
 	struct snd_card *card = dev_get_drvdata(dev);
+	struct hda_codec *codec;
 	struct azx *chip;
+	bool forced_resume = false;
 
 	if (!azx_is_pm_ready(card))
 		return 0;
@@ -1055,7 +1057,20 @@ static int azx_resume(struct device *dev)
 			chip->msi = 0;
 	if (azx_acquire_irq(chip, 1) < 0)
 		return -EIO;
-	__azx_runtime_resume(chip, false);
+
+	/* check for the forced resume */
+	list_for_each_codec(codec, &chip->bus) {
+		if (hda_codec_need_resume(codec)) {
+			forced_resume = true;
+			break;
+		}
+	}
+
+	if (forced_resume)
+		pm_runtime_get_noresume(dev);
+	pm_runtime_force_resume(dev);
+	if (forced_resume)
+		pm_runtime_put(dev);
 	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 
 	trace_azx_resume(chip);
@@ -1071,6 +1086,8 @@ static int azx_freeze_noirq(struct device *dev)
 	struct azx *chip = card->private_data;
 	struct pci_dev *pci = to_pci_dev(dev);
 
+	if (!azx_is_pm_ready(card))
+		return 0;
 	if (chip->driver_type == AZX_DRIVER_SKL)
 		pci_set_power_state(pci, PCI_D3hot);
 
@@ -1083,6 +1100,8 @@ static int azx_thaw_noirq(struct device *dev)
 	struct azx *chip = card->private_data;
 	struct pci_dev *pci = to_pci_dev(dev);
 
+	if (!azx_is_pm_ready(card))
+		return 0;
 	if (chip->driver_type == AZX_DRIVER_SKL)
 		pci_set_power_state(pci, PCI_D0);
 
@@ -1098,12 +1117,12 @@ static int azx_runtime_suspend(struct device *dev)
 	if (!azx_is_pm_ready(card))
 		return 0;
 	chip = card->private_data;
-	if (!azx_has_pm_runtime(chip))
-		return 0;
 
 	/* enable controller wake up event */
-	azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) |
-		  STATESTS_INT_MASK);
+	if (snd_power_get_state(card) == SNDRV_CTL_POWER_D0) {
+		azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) |
+			   STATESTS_INT_MASK);
+	}
 
 	__azx_runtime_suspend(chip);
 	trace_azx_runtime_suspend(chip);
@@ -1114,17 +1133,18 @@ static int azx_runtime_resume(struct device *dev)
 {
 	struct snd_card *card = dev_get_drvdata(dev);
 	struct azx *chip;
+	bool from_rt = snd_power_get_state(card) == SNDRV_CTL_POWER_D0;
 
 	if (!azx_is_pm_ready(card))
 		return 0;
 	chip = card->private_data;
-	if (!azx_has_pm_runtime(chip))
-		return 0;
-	__azx_runtime_resume(chip, true);
+	__azx_runtime_resume(chip, from_rt);
 
 	/* disable controller Wake Up event*/
-	azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) &
-			~STATESTS_INT_MASK);
+	if (from_rt) {
+		azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) &
+			   ~STATESTS_INT_MASK);
+	}
 
 	trace_azx_runtime_resume(chip);
 	return 0;
@@ -1199,10 +1219,8 @@ static void azx_vs_set_state(struct pci_dev *pci,
 		if (!disabled) {
 			dev_info(chip->card->dev,
 				 "Start delayed initialization\n");
-			if (azx_probe_continue(chip) < 0) {
+			if (azx_probe_continue(chip) < 0)
 				dev_err(chip->card->dev, "initialization error\n");
-				hda->init_failed = true;
-			}
 		}
 	} else {
 		dev_info(chip->card->dev, "%s via vga_switcheroo\n",
@@ -1335,12 +1353,15 @@ static int register_vga_switcheroo(struct azx *chip)
 /*
  * destructor
  */
-static int azx_free(struct azx *chip)
+static void azx_free(struct azx *chip)
 {
 	struct pci_dev *pci = chip->pci;
 	struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
 	struct hdac_bus *bus = azx_bus(chip);
 
+	if (hda->freed)
+		return;
+
 	if (azx_has_pm_runtime(chip) && chip->running)
 		pm_runtime_get_noresume(&pci->dev);
 	chip->running = 0;
@@ -1384,9 +1405,8 @@ static int azx_free(struct azx *chip)
 
 	if (chip->driver_caps & AZX_DCAPS_I915_COMPONENT)
 		snd_hdac_i915_exit(bus);
-	kfree(hda);
 
-	return 0;
+	hda->freed = 1;
 }
 
 static int azx_dev_disconnect(struct snd_device *device)
@@ -1402,7 +1422,8 @@ static int azx_dev_disconnect(struct snd_device *device)
 
 static int azx_dev_free(struct snd_device *device)
 {
-	return azx_free(device->device_data);
+	azx_free(device->device_data);
+	return 0;
 }
 
 #ifdef SUPPORT_VGA_SWITCHEROO
@@ -1769,7 +1790,7 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
 	if (err < 0)
 		return err;
 
-	hda = kzalloc(sizeof(*hda), GFP_KERNEL);
+	hda = devm_kzalloc(&pci->dev, sizeof(*hda), GFP_KERNEL);
 	if (!hda) {
 		pci_disable_device(pci);
 		return -ENOMEM;
@@ -1810,7 +1831,6 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
 
 	err = azx_bus_init(chip, model[dev]);
 	if (err < 0) {
-		kfree(hda);
 		pci_disable_device(pci);
 		return err;
 	}
@@ -2005,7 +2025,7 @@ static int azx_first_init(struct azx *chip)
 	/* codec detection */
 	if (!azx_bus(chip)->codec_mask) {
 		dev_err(card->dev, "no codecs found!\n");
-		return -ENODEV;
+		/* keep running the rest for the runtime PM */
 	}
 
 	if (azx_acquire_irq(chip, 0) < 0)
@@ -2027,24 +2047,15 @@ static void azx_firmware_cb(const struct firmware *fw, void *context)
 {
 	struct snd_card *card = context;
 	struct azx *chip = card->private_data;
-	struct pci_dev *pci = chip->pci;
-
-	if (!fw) {
-		dev_err(card->dev, "Cannot load firmware, aborting\n");
-		goto error;
-	}
 
-	chip->fw = fw;
+	if (fw)
+		chip->fw = fw;
+	else
+		dev_err(card->dev, "Cannot load firmware, continue without patching\n");
 	if (!chip->disabled) {
 		/* continue probing */
-		if (azx_probe_continue(chip))
-			goto error;
+		azx_probe_continue(chip);
 	}
-	return; /* OK */
-
- error:
-	snd_card_free(card);
-	pci_set_drvdata(pci, NULL);
 }
 #endif
 
@@ -2308,9 +2319,11 @@ static int azx_probe_continue(struct azx *chip)
 #endif
 
 	/* create codec instances */
-	err = azx_probe_codecs(chip, azx_max_codecs[chip->driver_type]);
-	if (err < 0)
-		goto out_free;
+	if (bus->codec_mask) {
+		err = azx_probe_codecs(chip, azx_max_codecs[chip->driver_type]);
+		if (err < 0)
+			goto out_free;
+	}
 
 #ifdef CONFIG_SND_HDA_PATCH_LOADER
 	if (chip->fw) {
@@ -2324,7 +2337,7 @@ static int azx_probe_continue(struct azx *chip)
 #endif
 	}
 #endif
-	if ((probe_only[dev] & 1) == 0) {
+	if (bus->codec_mask && !(probe_only[dev] & 1)) {
 		err = azx_codec_configure(chip);
 		if (err < 0)
 			goto out_free;
@@ -2341,17 +2354,23 @@ static int azx_probe_continue(struct azx *chip)
 
 	set_default_power_save(chip);
 
-	if (azx_has_pm_runtime(chip))
+	if (azx_has_pm_runtime(chip)) {
+		pm_runtime_use_autosuspend(&pci->dev);
+		pm_runtime_allow(&pci->dev);
 		pm_runtime_put_autosuspend(&pci->dev);
+	}
 
 out_free:
-	if (err < 0 || !hda->need_i915_power)
+	if (err < 0) {
+		azx_free(chip);
+		return err;
+	}
+
+	if (!hda->need_i915_power)
 		display_power(chip, false);
-	if (err < 0)
-		hda->init_failed = 1;
 	complete_all(&hda->probe_wait);
 	to_hda_bus(bus)->bus_probing = 0;
-	return err;
+	return 0;
 }
 
 static void azx_remove(struct pci_dev *pci)
diff --git a/sound/pci/hda/hda_intel.h b/sound/pci/hda/hda_intel.h
index 2acfff3da1a0..3fb119f09040 100644
--- a/sound/pci/hda/hda_intel.h
+++ b/sound/pci/hda/hda_intel.h
@@ -27,6 +27,7 @@ struct hda_intel {
 	unsigned int use_vga_switcheroo:1;
 	unsigned int vga_switcheroo_registered:1;
 	unsigned int init_failed:1; /* delayed init failed */
+	unsigned int freed:1; /* resources already released */
 
 	bool need_i915_power:1; /* the hda controller needs i915 power */
 };
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index de2826f90d34..dc5557d79c43 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -7378,6 +7378,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
 	SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
 	SND_PCI_QUIRK(0x1043, 0x17d1, "ASUS UX431FL", ALC294_FIXUP_ASUS_DUAL_SPK),
 	SND_PCI_QUIRK(0x1043, 0x18b1, "Asus MJ401TA", ALC256_FIXUP_ASUS_HEADSET_MIC),
+	SND_PCI_QUIRK(0x1043, 0x18f1, "Asus FX505DT", ALC256_FIXUP_ASUS_HEADSET_MIC),
 	SND_PCI_QUIRK(0x1043, 0x19ce, "ASUS B9450FA", ALC294_FIXUP_ASUS_HPE),
 	SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
 	SND_PCI_QUIRK(0x1043, 0x1a30, "ASUS X705UD", ALC256_FIXUP_ASUS_MIC),
diff --git a/sound/soc/amd/acp3x-rt5682-max9836.c b/sound/soc/amd/acp3x-rt5682-max9836.c
index 024a7ee54cd5..e499c00e0c66 100644
--- a/sound/soc/amd/acp3x-rt5682-max9836.c
+++ b/sound/soc/amd/acp3x-rt5682-max9836.c
@@ -89,9 +89,9 @@ static int acp3x_5682_init(struct snd_soc_pcm_runtime *rtd)
 	}
 
 	snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
-	snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
-	snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
-	snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
+	snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
+	snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
+	snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
 
 	ret = snd_soc_component_set_jack(component, &pco_jack, NULL);
 	if (ret) {
diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index fba9b749839d..f26b77faed59 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -142,14 +142,14 @@ static struct hdac_hdmi_pcm *
 hdac_hdmi_get_pcm_from_cvt(struct hdac_hdmi_priv *hdmi,
 			   struct hdac_hdmi_cvt *cvt)
 {
-	struct hdac_hdmi_pcm *pcm = NULL;
+	struct hdac_hdmi_pcm *pcm;
 
 	list_for_each_entry(pcm, &hdmi->pcm_list, head) {
 		if (pcm->cvt == cvt)
-			break;
+			return pcm;
 	}
 
-	return pcm;
+	return NULL;
 }
 
 static void hdac_hdmi_jack_report(struct hdac_hdmi_pcm *pcm,
diff --git a/sound/soc/codecs/madera.c b/sound/soc/codecs/madera.c
index 40de9d7811d1..a448d2a2918a 100644
--- a/sound/soc/codecs/madera.c
+++ b/sound/soc/codecs/madera.c
@@ -1903,7 +1903,6 @@ const struct soc_enum madera_isrc_fsh[] = {
 			      MADERA_ISRC4_FSH_SHIFT, 0xf,
 			      MADERA_RATE_ENUM_SIZE,
 			      madera_rate_text, madera_rate_val),
-
 };
 EXPORT_SYMBOL_GPL(madera_isrc_fsh);
 
@@ -1924,7 +1923,6 @@ const struct soc_enum madera_isrc_fsl[] = {
 			      MADERA_ISRC4_FSL_SHIFT, 0xf,
 			      MADERA_RATE_ENUM_SIZE,
 			      madera_rate_text, madera_rate_val),
-
 };
 EXPORT_SYMBOL_GPL(madera_isrc_fsl);
 
@@ -1938,7 +1936,6 @@ const struct soc_enum madera_asrc1_rate[] = {
 			      MADERA_ASYNC_RATE_ENUM_SIZE,
 			      madera_rate_text + MADERA_SYNC_RATE_ENUM_SIZE,
 			      madera_rate_val + MADERA_SYNC_RATE_ENUM_SIZE),
-
 };
 EXPORT_SYMBOL_GPL(madera_asrc1_rate);
 
@@ -1964,7 +1961,6 @@ const struct soc_enum madera_asrc2_rate[] = {
 			      MADERA_ASYNC_RATE_ENUM_SIZE,
 			      madera_rate_text + MADERA_SYNC_RATE_ENUM_SIZE,
 			      madera_rate_val + MADERA_SYNC_RATE_ENUM_SIZE),
-
 };
 EXPORT_SYMBOL_GPL(madera_asrc2_rate);
 
diff --git a/sound/soc/codecs/tas571x.c b/sound/soc/codecs/tas571x.c
index 1554631cb397..5b7f9fcf6cbf 100644
--- a/sound/soc/codecs/tas571x.c
+++ b/sound/soc/codecs/tas571x.c
@@ -820,8 +820,10 @@ static int tas571x_i2c_probe(struct i2c_client *client,
 
 	priv->regmap = devm_regmap_init(dev, NULL, client,
 					priv->chip->regmap_config);
-	if (IS_ERR(priv->regmap))
-		return PTR_ERR(priv->regmap);
+	if (IS_ERR(priv->regmap)) {
+		ret = PTR_ERR(priv->regmap);
+		goto disable_regs;
+	}
 
 	priv->pdn_gpio = devm_gpiod_get_optional(dev, "pdn", GPIOD_OUT_LOW);
 	if (IS_ERR(priv->pdn_gpio)) {
@@ -845,7 +847,7 @@ static int tas571x_i2c_probe(struct i2c_client *client,
 
 	ret = regmap_write(priv->regmap, TAS571X_OSC_TRIM_REG, 0);
 	if (ret)
-		return ret;
+		goto disable_regs;
 
 	usleep_range(50000, 60000);
 
@@ -861,12 +863,20 @@ static int tas571x_i2c_probe(struct i2c_client *client,
 		 */
 		ret = regmap_update_bits(priv->regmap, TAS571X_MVOL_REG, 1, 0);
 		if (ret)
-			return ret;
+			goto disable_regs;
 	}
 
-	return devm_snd_soc_register_component(&client->dev,
+	ret = devm_snd_soc_register_component(&client->dev,
 				      &priv->component_driver,
 				      &tas571x_dai, 1);
+	if (ret)
+		goto disable_regs;
+
+	return ret;
+
+disable_regs:
+	regulator_bulk_disable(priv->chip->num_supply_names, priv->supplies);
+	return ret;
 }
 
 static int tas571x_i2c_remove(struct i2c_client *client)
diff --git a/sound/soc/codecs/wsa881x.c b/sound/soc/codecs/wsa881x.c
index f2d6f2f81f14..d39d479e2378 100644
--- a/sound/soc/codecs/wsa881x.c
+++ b/sound/soc/codecs/wsa881x.c
@@ -394,6 +394,7 @@ static struct sdw_dpn_prop wsa_sink_dpn_prop[WSA881X_MAX_SWR_PORTS] = {
 		.min_ch = 1,
 		.max_ch = 1,
 		.simple_ch_prep_sm = true,
+		.read_only_wordlength = true,
 	}, {
 		/* COMP */
 		.num = 2,
@@ -401,6 +402,7 @@ static struct sdw_dpn_prop wsa_sink_dpn_prop[WSA881X_MAX_SWR_PORTS] = {
 		.min_ch = 1,
 		.max_ch = 1,
 		.simple_ch_prep_sm = true,
+		.read_only_wordlength = true,
 	}, {
 		/* BOOST */
 		.num = 3,
@@ -408,6 +410,7 @@ static struct sdw_dpn_prop wsa_sink_dpn_prop[WSA881X_MAX_SWR_PORTS] = {
 		.min_ch = 1,
 		.max_ch = 1,
 		.simple_ch_prep_sm = true,
+		.read_only_wordlength = true,
 	}, {
 		/* VISENSE */
 		.num = 4,
@@ -415,6 +418,7 @@ static struct sdw_dpn_prop wsa_sink_dpn_prop[WSA881X_MAX_SWR_PORTS] = {
 		.min_ch = 1,
 		.max_ch = 1,
 		.simple_ch_prep_sm = true,
+		.read_only_wordlength = true,
 	}
 };
 
diff --git a/sound/soc/intel/common/soc-acpi-intel-cml-match.c b/sound/soc/intel/common/soc-acpi-intel-cml-match.c
index bcedec6c6117..7d85bd5aff9f 100644
--- a/sound/soc/intel/common/soc-acpi-intel-cml-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-cml-match.c
@@ -113,14 +113,6 @@ static const struct snd_soc_acpi_adr_device rt1308_1_adr[] = {
 	}
 };
 
-static const struct snd_soc_acpi_adr_device rt1308_2_adr[] = {
-	{
-		.adr = 0x000210025D130800,
-		.num_endpoints = 1,
-		.endpoints = &single_endpoint,
-	}
-};
-
 static const struct snd_soc_acpi_adr_device rt1308_1_group1_adr[] = {
 	{
 		.adr = 0x000110025D130800,
diff --git a/sound/soc/intel/common/soc-acpi-intel-icl-match.c b/sound/soc/intel/common/soc-acpi-intel-icl-match.c
index ef8500349f2f..16ec9f382b0f 100644
--- a/sound/soc/intel/common/soc-acpi-intel-icl-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-icl-match.c
@@ -87,14 +87,6 @@ static const struct snd_soc_acpi_adr_device rt1308_1_adr[] = {
 	}
 };
 
-static const struct snd_soc_acpi_adr_device rt1308_2_adr[] = {
-	{
-		.adr = 0x000210025D130800,
-		.num_endpoints = 1,
-		.endpoints = &single_endpoint,
-	}
-};
-
 static const struct snd_soc_acpi_adr_device rt1308_1_group1_adr[] = {
 	{
 		.adr = 0x000110025D130800,
diff --git a/sound/soc/qcom/apq8096.c b/sound/soc/qcom/apq8096.c
index d55e3ad96716..287ad2aa27f3 100644
--- a/sound/soc/qcom/apq8096.c
+++ b/sound/soc/qcom/apq8096.c
@@ -116,10 +116,8 @@ static int apq8096_platform_probe(struct platform_device *pdev)
 	card->dev = dev;
 	dev_set_drvdata(dev, card);
 	ret = qcom_snd_parse_of(card);
-	if (ret) {
-		dev_err(dev, "Error parsing OF data\n");
+	if (ret)
 		goto err;
-	}
 
 	apq8096_add_be_ops(card);
 	ret = snd_soc_register_card(card);
diff --git a/sound/soc/qcom/sdm845.c b/sound/soc/qcom/sdm845.c
index b2de65c7f95c..68e9388ff46f 100644
--- a/sound/soc/qcom/sdm845.c
+++ b/sound/soc/qcom/sdm845.c
@@ -559,10 +559,8 @@ static int sdm845_snd_platform_probe(struct platform_device *pdev)
 	card->dev = dev;
 	dev_set_drvdata(dev, card);
 	ret = qcom_snd_parse_of(card);
-	if (ret) {
-		dev_err(dev, "Error parsing OF data\n");
+	if (ret)
 		goto parse_dt_fail;
-	}
 
 	data->card = card;
 	snd_soc_card_set_drvdata(card, data);
diff --git a/sound/soc/samsung/s3c-i2s-v2.c b/sound/soc/samsung/s3c-i2s-v2.c
index 358887848293..5e95c30fb2ba 100644
--- a/sound/soc/samsung/s3c-i2s-v2.c
+++ b/sound/soc/samsung/s3c-i2s-v2.c
@@ -656,60 +656,6 @@ void s3c_i2sv2_cleanup(struct snd_soc_dai *dai,
 }
 EXPORT_SYMBOL_GPL(s3c_i2sv2_cleanup);
 
-#ifdef CONFIG_PM
-static int s3c2412_i2s_suspend(struct snd_soc_dai *dai)
-{
-	struct s3c_i2sv2_info *i2s = to_info(dai);
-	u32 iismod;
-
-	if (dai->active) {
-		i2s->suspend_iismod = readl(i2s->regs + S3C2412_IISMOD);
-		i2s->suspend_iiscon = readl(i2s->regs + S3C2412_IISCON);
-		i2s->suspend_iispsr = readl(i2s->regs + S3C2412_IISPSR);
-
-		/* some basic suspend checks */
-
-		iismod = readl(i2s->regs + S3C2412_IISMOD);
-
-		if (iismod & S3C2412_IISCON_RXDMA_ACTIVE)
-			pr_warn("%s: RXDMA active?\n", __func__);
-
-		if (iismod & S3C2412_IISCON_TXDMA_ACTIVE)
-			pr_warn("%s: TXDMA active?\n", __func__);
-
-		if (iismod & S3C2412_IISCON_IIS_ACTIVE)
-			pr_warn("%s: IIS active\n", __func__);
-	}
-
-	return 0;
-}
-
-static int s3c2412_i2s_resume(struct snd_soc_dai *dai)
-{
-	struct s3c_i2sv2_info *i2s = to_info(dai);
-
-	pr_info("dai_active %d, IISMOD %08x, IISCON %08x\n",
-		dai->active, i2s->suspend_iismod, i2s->suspend_iiscon);
-
-	if (dai->active) {
-		writel(i2s->suspend_iiscon, i2s->regs + S3C2412_IISCON);
-		writel(i2s->suspend_iismod, i2s->regs + S3C2412_IISMOD);
-		writel(i2s->suspend_iispsr, i2s->regs + S3C2412_IISPSR);
-
-		writel(S3C2412_IISFIC_RXFLUSH | S3C2412_IISFIC_TXFLUSH,
-		       i2s->regs + S3C2412_IISFIC);
-
-		ndelay(250);
-		writel(0x0, i2s->regs + S3C2412_IISFIC);
-	}
-
-	return 0;
-}
-#else
-#define s3c2412_i2s_suspend NULL
-#define s3c2412_i2s_resume  NULL
-#endif
-
 int s3c_i2sv2_register_component(struct device *dev, int id,
 			   const struct snd_soc_component_driver *cmp_drv,
 			   struct snd_soc_dai_driver *dai_drv)
@@ -727,9 +673,6 @@ int s3c_i2sv2_register_component(struct device *dev, int id,
 	if (!ops->delay)
 		ops->delay = s3c2412_i2s_delay;
 
-	dai_drv->suspend = s3c2412_i2s_suspend;
-	dai_drv->resume = s3c2412_i2s_resume;
-
 	return devm_snd_soc_register_component(dev, cmp_drv, dai_drv, 1);
 }
 EXPORT_SYMBOL_GPL(s3c_i2sv2_register_component);
diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c
index 787a3f6e9f24..b35d828c1cfe 100644
--- a/sound/soc/samsung/s3c2412-i2s.c
+++ b/sound/soc/samsung/s3c2412-i2s.c
@@ -117,6 +117,60 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
 	return 0;
 }
 
+#ifdef CONFIG_PM
+static int s3c2412_i2s_suspend(struct snd_soc_component *component)
+{
+	struct s3c_i2sv2_info *i2s = snd_soc_component_get_drvdata(component);
+	u32 iismod;
+
+	if (component->active) {
+		i2s->suspend_iismod = readl(i2s->regs + S3C2412_IISMOD);
+		i2s->suspend_iiscon = readl(i2s->regs + S3C2412_IISCON);
+		i2s->suspend_iispsr = readl(i2s->regs + S3C2412_IISPSR);
+
+		/* some basic suspend checks */
+
+		iismod = readl(i2s->regs + S3C2412_IISMOD);
+
+		if (iismod & S3C2412_IISCON_RXDMA_ACTIVE)
+			pr_warn("%s: RXDMA active?\n", __func__);
+
+		if (iismod & S3C2412_IISCON_TXDMA_ACTIVE)
+			pr_warn("%s: TXDMA active?\n", __func__);
+
+		if (iismod & S3C2412_IISCON_IIS_ACTIVE)
+			pr_warn("%s: IIS active\n", __func__);
+	}
+
+	return 0;
+}
+
+static int s3c2412_i2s_resume(struct snd_soc_component *component)
+{
+	struct s3c_i2sv2_info *i2s = snd_soc_component_get_drvdata(component);
+
+	pr_info("component_active %d, IISMOD %08x, IISCON %08x\n",
+		component->active, i2s->suspend_iismod, i2s->suspend_iiscon);
+
+	if (component->active) {
+		writel(i2s->suspend_iiscon, i2s->regs + S3C2412_IISCON);
+		writel(i2s->suspend_iismod, i2s->regs + S3C2412_IISMOD);
+		writel(i2s->suspend_iispsr, i2s->regs + S3C2412_IISPSR);
+
+		writel(S3C2412_IISFIC_RXFLUSH | S3C2412_IISFIC_TXFLUSH,
+		       i2s->regs + S3C2412_IISFIC);
+
+		ndelay(250);
+		writel(0x0, i2s->regs + S3C2412_IISFIC);
+	}
+
+	return 0;
+}
+#else
+#define s3c2412_i2s_suspend NULL
+#define s3c2412_i2s_resume  NULL
+#endif
+
 #define S3C2412_I2S_RATES \
 	(SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \
 	SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
@@ -146,6 +200,8 @@ static struct snd_soc_dai_driver s3c2412_i2s_dai = {
 
 static const struct snd_soc_component_driver s3c2412_i2s_component = {
 	.name		= "s3c2412-i2s",
+	.suspend	= s3c2412_i2s_suspend,
+	.resume		= s3c2412_i2s_resume,
 };
 
 static int s3c2412_iis_dev_probe(struct platform_device *pdev)
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index fc5d089868df..d51fb3a39448 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -407,7 +407,7 @@ static void rsnd_ssi_config_init(struct rsnd_mod *mod,
 	 * We shouldn't exchange SWSP after running.
 	 * This means, parent needs to care it.
 	 */
-	if (rsnd_ssi_is_parent(mod, io))
+	if (rsnd_ssi_is_parent(mod, io) && !rsnd_ssi_multi_slaves(io))
 		goto init_end;
 
 	if (rsnd_io_is_play(io))
@@ -559,7 +559,7 @@ static int rsnd_ssi_start(struct rsnd_mod *mod,
 	 * EN is for data output.
 	 * SSI parent EN is not needed.
 	 */
-	if (rsnd_ssi_is_parent(mod, io))
+	if (rsnd_ssi_is_parent(mod, io) && !rsnd_ssi_multi_slaves(io))
 		return 0;
 
 	ssi->cr_en = EN;
@@ -582,7 +582,7 @@ static int rsnd_ssi_stop(struct rsnd_mod *mod,
 	if (!rsnd_ssi_is_run_mods(mod, io))
 		return 0;
 
-	if (rsnd_ssi_is_parent(mod, io))
+	if (rsnd_ssi_is_parent(mod, io) && !rsnd_ssi_multi_slaves(io))
 		return 0;
 
 	cr  =	ssi->cr_own	|
@@ -620,7 +620,7 @@ static int rsnd_ssi_irq(struct rsnd_mod *mod,
 	if (rsnd_is_gen1(priv))
 		return 0;
 
-	if (rsnd_ssi_is_parent(mod, io))
+	if (rsnd_ssi_is_parent(mod, io) && !rsnd_ssi_multi_slaves(io))
 		return 0;
 
 	if (!rsnd_ssi_is_run_mods(mod, io))
diff --git a/sound/soc/sh/rcar/ssiu.c b/sound/soc/sh/rcar/ssiu.c
index f35d88211887..9c7c3e7539c9 100644
--- a/sound/soc/sh/rcar/ssiu.c
+++ b/sound/soc/sh/rcar/ssiu.c
@@ -221,7 +221,7 @@ static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod,
 			i;
 
 		for_each_rsnd_mod_array(i, pos, io, rsnd_ssi_array) {
-			shift	= (i * 4) + 16;
+			shift	= (i * 4) + 20;
 			val	= (val & ~(0xF << shift)) |
 				rsnd_mod_id(pos) << shift;
 		}
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 679ed60d850e..a4143ca190d0 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -4165,6 +4165,8 @@ snd_soc_dapm_new_dai(struct snd_soc_card *card,
 	w = snd_soc_dapm_new_control_unlocked(&card->dapm, &template);
 	if (IS_ERR(w)) {
 		ret = PTR_ERR(w);
+		dev_err(rtd->dev, "ASoC: Failed to create %s widget: %d\n",
+			link_name, ret);
 		goto outfree_kcontrol_news;
 	}
 
@@ -4283,52 +4285,58 @@ int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card)
 	return 0;
 }
 
-static void dapm_add_valid_dai_widget(struct snd_soc_card *card,
-				      struct snd_soc_pcm_runtime *rtd,
-				      struct snd_soc_dai *codec_dai,
-				      struct snd_soc_dai *cpu_dai)
+static void dapm_connect_dai_routes(struct snd_soc_dapm_context *dapm,
+				    struct snd_soc_dai *src_dai,
+				    struct snd_soc_dapm_widget *src,
+				    struct snd_soc_dapm_widget *dai,
+				    struct snd_soc_dai *sink_dai,
+				    struct snd_soc_dapm_widget *sink)
 {
-	struct snd_soc_dapm_widget *playback = NULL, *capture = NULL;
-	struct snd_soc_dapm_widget *codec, *playback_cpu, *capture_cpu;
+	dev_dbg(dapm->dev, "connected DAI link %s:%s -> %s:%s\n",
+		src_dai->component->name, src->name,
+		sink_dai->component->name, sink->name);
+
+	if (dai) {
+		snd_soc_dapm_add_path(dapm, src, dai, NULL, NULL);
+		src = dai;
+	}
+
+	snd_soc_dapm_add_path(dapm, src, sink, NULL, NULL);
+}
+
+static void dapm_connect_dai_pair(struct snd_soc_card *card,
+				  struct snd_soc_pcm_runtime *rtd,
+				  struct snd_soc_dai *codec_dai,
+				  struct snd_soc_dai *cpu_dai)
+{
+	struct snd_soc_dai_link *dai_link = rtd->dai_link;
+	struct snd_soc_dapm_widget *dai, *codec, *playback_cpu, *capture_cpu;
 	struct snd_pcm_substream *substream;
 	struct snd_pcm_str *streams = rtd->pcm->streams;
 
-	if (rtd->dai_link->params) {
+	if (dai_link->params) {
 		playback_cpu = cpu_dai->capture_widget;
 		capture_cpu = cpu_dai->playback_widget;
 	} else {
-		playback = cpu_dai->playback_widget;
-		capture = cpu_dai->capture_widget;
-		playback_cpu = playback;
-		capture_cpu = capture;
+		playback_cpu = cpu_dai->playback_widget;
+		capture_cpu = cpu_dai->capture_widget;
 	}
 
 	/* connect BE DAI playback if widgets are valid */
 	codec = codec_dai->playback_widget;
 
 	if (playback_cpu && codec) {
-		if (!playback) {
+		if (dai_link->params && !dai_link->playback_widget) {
 			substream = streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
-			playback = snd_soc_dapm_new_dai(card, substream,
-							"playback");
-			if (IS_ERR(playback)) {
-				dev_err(rtd->dev,
-					"ASoC: Failed to create DAI %s: %ld\n",
-					codec_dai->name,
-					PTR_ERR(playback));
+			dai = snd_soc_dapm_new_dai(card, substream, "playback");
+			if (IS_ERR(dai))
 				goto capture;
-			}
-
-			snd_soc_dapm_add_path(&card->dapm, playback_cpu,
-					      playback, NULL, NULL);
+			dai_link->playback_widget = dai;
 		}
 
-		dev_dbg(rtd->dev, "connected DAI link %s:%s -> %s:%s\n",
-			cpu_dai->component->name, playback_cpu->name,
-			codec_dai->component->name, codec->name);
-
-		snd_soc_dapm_add_path(&card->dapm, playback, codec,
-				      NULL, NULL);
+		dapm_connect_dai_routes(&card->dapm, cpu_dai, playback_cpu,
+					dai_link->playback_widget,
+					codec_dai, codec);
 	}
 
 capture:
@@ -4336,52 +4344,20 @@ static void dapm_add_valid_dai_widget(struct snd_soc_card *card,
 	codec = codec_dai->capture_widget;
 
 	if (codec && capture_cpu) {
-		if (!capture) {
+		if (dai_link->params && !dai_link->capture_widget) {
 			substream = streams[SNDRV_PCM_STREAM_CAPTURE].substream;
-			capture = snd_soc_dapm_new_dai(card, substream,
-						       "capture");
-			if (IS_ERR(capture)) {
-				dev_err(rtd->dev,
-					"ASoC: Failed to create DAI %s: %ld\n",
-					codec_dai->name,
-					PTR_ERR(capture));
+			dai = snd_soc_dapm_new_dai(card, substream, "capture");
+			if (IS_ERR(dai))
 				return;
-			}
-
-			snd_soc_dapm_add_path(&card->dapm, capture,
-					      capture_cpu, NULL, NULL);
+			dai_link->capture_widget = dai;
 		}
 
-		dev_dbg(rtd->dev, "connected DAI link %s:%s -> %s:%s\n",
-			codec_dai->component->name, codec->name,
-			cpu_dai->component->name, capture_cpu->name);
-
-		snd_soc_dapm_add_path(&card->dapm, codec, capture,
-				      NULL, NULL);
+		dapm_connect_dai_routes(&card->dapm, codec_dai, codec,
+					dai_link->capture_widget,
+					cpu_dai, capture_cpu);
 	}
 }
 
-static void dapm_connect_dai_link_widgets(struct snd_soc_card *card,
-					  struct snd_soc_pcm_runtime *rtd)
-{
-	struct snd_soc_dai *codec_dai;
-	int i;
-
-	if (rtd->num_cpus == 1) {
-		for_each_rtd_codec_dais(rtd, i, codec_dai)
-			dapm_add_valid_dai_widget(card, rtd, codec_dai,
-						  rtd->cpu_dais[0]);
-	} else if (rtd->num_codecs == rtd->num_cpus) {
-		for_each_rtd_codec_dais(rtd, i, codec_dai)
-			dapm_add_valid_dai_widget(card, rtd, codec_dai,
-						  rtd->cpu_dais[i]);
-	} else {
-		dev_err(card->dev,
-			"N cpus to M codecs link is not supported yet\n");
-	}
-
-}
-
 static void soc_dapm_dai_stream_event(struct snd_soc_dai *dai, int stream,
 	int event)
 {
@@ -4422,6 +4398,8 @@ static void soc_dapm_dai_stream_event(struct snd_soc_dai *dai, int stream,
 void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card)
 {
 	struct snd_soc_pcm_runtime *rtd;
+	struct snd_soc_dai *codec_dai;
+	int i;
 
 	/* for each BE DAI link... */
 	for_each_card_rtds(card, rtd)  {
@@ -4432,7 +4410,18 @@ void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card)
 		if (rtd->dai_link->dynamic)
 			continue;
 
-		dapm_connect_dai_link_widgets(card, rtd);
+		if (rtd->num_cpus == 1) {
+			for_each_rtd_codec_dais(rtd, i, codec_dai)
+				dapm_connect_dai_pair(card, rtd, codec_dai,
+						      rtd->cpu_dais[0]);
+		} else if (rtd->num_codecs == rtd->num_cpus) {
+			for_each_rtd_codec_dais(rtd, i, codec_dai)
+				dapm_connect_dai_pair(card, rtd, codec_dai,
+						      rtd->cpu_dais[i]);
+		} else {
+			dev_err(card->dev,
+				"N cpus to M codecs link is not supported yet\n");
+		}
 	}
 }
 
diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c
index 87f75edba3dc..33e8d189ba2f 100644
--- a/sound/soc/soc-topology.c
+++ b/sound/soc/soc-topology.c
@@ -894,7 +894,13 @@ static int soc_tplg_dmixer_create(struct soc_tplg *tplg, unsigned int count,
 		}
 
 		/* create any TLV data */
-		soc_tplg_create_tlv(tplg, &kc, &mc->hdr);
+		err = soc_tplg_create_tlv(tplg, &kc, &mc->hdr);
+		if (err < 0) {
+			dev_err(tplg->dev, "ASoC: failed to create TLV %s\n",
+				mc->hdr.name);
+			kfree(sm);
+			continue;
+		}
 
 		/* pass control to driver for optional further init */
 		err = soc_tplg_init_kcontrol(tplg, &kc,
@@ -1118,6 +1124,7 @@ static int soc_tplg_kcontrol_elems_load(struct soc_tplg *tplg,
 	struct snd_soc_tplg_hdr *hdr)
 {
 	struct snd_soc_tplg_ctl_hdr *control_hdr;
+	int ret;
 	int i;
 
 	if (tplg->pass != SOC_TPLG_PASS_MIXER) {
@@ -1146,25 +1153,30 @@ static int soc_tplg_kcontrol_elems_load(struct soc_tplg *tplg,
 		case SND_SOC_TPLG_CTL_RANGE:
 		case SND_SOC_TPLG_DAPM_CTL_VOLSW:
 		case SND_SOC_TPLG_DAPM_CTL_PIN:
-			soc_tplg_dmixer_create(tplg, 1,
-					       le32_to_cpu(hdr->payload_size));
+			ret = soc_tplg_dmixer_create(tplg, 1,
+					le32_to_cpu(hdr->payload_size));
 			break;
 		case SND_SOC_TPLG_CTL_ENUM:
 		case SND_SOC_TPLG_CTL_ENUM_VALUE:
 		case SND_SOC_TPLG_DAPM_CTL_ENUM_DOUBLE:
 		case SND_SOC_TPLG_DAPM_CTL_ENUM_VIRT:
 		case SND_SOC_TPLG_DAPM_CTL_ENUM_VALUE:
-			soc_tplg_denum_create(tplg, 1,
-					      le32_to_cpu(hdr->payload_size));
+			ret = soc_tplg_denum_create(tplg, 1,
+					le32_to_cpu(hdr->payload_size));
 			break;
 		case SND_SOC_TPLG_CTL_BYTES:
-			soc_tplg_dbytes_create(tplg, 1,
-					       le32_to_cpu(hdr->payload_size));
+			ret = soc_tplg_dbytes_create(tplg, 1,
+					le32_to_cpu(hdr->payload_size));
 			break;
 		default:
 			soc_bind_err(tplg, control_hdr, i);
 			return -EINVAL;
 		}
+		if (ret < 0) {
+			dev_err(tplg->dev, "ASoC: invalid control\n");
+			return ret;
+		}
+
 	}
 
 	return 0;
@@ -1272,7 +1284,9 @@ static int soc_tplg_dapm_graph_elems_load(struct soc_tplg *tplg,
 		routes[i]->dobj.index = tplg->index;
 		list_add(&routes[i]->dobj.list, &tplg->comp->dobj_list);
 
-		soc_tplg_add_route(tplg, routes[i]);
+		ret = soc_tplg_add_route(tplg, routes[i]);
+		if (ret < 0)
+			break;
 
 		/* add route, but keep going if some fail */
 		snd_soc_dapm_add_routes(dapm, routes[i], 1);
@@ -1355,7 +1369,13 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_dmixer_create(
 		}
 
 		/* create any TLV data */
-		soc_tplg_create_tlv(tplg, &kc[i], &mc->hdr);
+		err = soc_tplg_create_tlv(tplg, &kc[i], &mc->hdr);
+		if (err < 0) {
+			dev_err(tplg->dev, "ASoC: failed to create TLV %s\n",
+				mc->hdr.name);
+			kfree(sm);
+			continue;
+		}
 
 		/* pass control to driver for optional further init */
 		err = soc_tplg_init_kcontrol(tplg, &kc[i],
@@ -1766,10 +1786,13 @@ static int soc_tplg_dapm_complete(struct soc_tplg *tplg)
 	return 0;
 }
 
-static void set_stream_info(struct snd_soc_pcm_stream *stream,
+static int set_stream_info(struct snd_soc_pcm_stream *stream,
 	struct snd_soc_tplg_stream_caps *caps)
 {
 	stream->stream_name = kstrdup(caps->name, GFP_KERNEL);
+	if (!stream->stream_name)
+		return -ENOMEM;
+
 	stream->channels_min = le32_to_cpu(caps->channels_min);
 	stream->channels_max = le32_to_cpu(caps->channels_max);
 	stream->rates = le32_to_cpu(caps->rates);
@@ -1777,6 +1800,8 @@ static void set_stream_info(struct snd_soc_pcm_stream *stream,
 	stream->rate_max = le32_to_cpu(caps->rate_max);
 	stream->formats = le64_to_cpu(caps->formats);
 	stream->sig_bits = le32_to_cpu(caps->sig_bits);
+
+	return 0;
 }
 
 static void set_dai_flags(struct snd_soc_dai_driver *dai_drv,
@@ -1812,20 +1837,29 @@ static int soc_tplg_dai_create(struct soc_tplg *tplg,
 	if (dai_drv == NULL)
 		return -ENOMEM;
 
-	if (strlen(pcm->dai_name))
+	if (strlen(pcm->dai_name)) {
 		dai_drv->name = kstrdup(pcm->dai_name, GFP_KERNEL);
+		if (!dai_drv->name) {
+			ret = -ENOMEM;
+			goto err;
+		}
+	}
 	dai_drv->id = le32_to_cpu(pcm->dai_id);
 
 	if (pcm->playback) {
 		stream = &dai_drv->playback;
 		caps = &pcm->caps[SND_SOC_TPLG_STREAM_PLAYBACK];
-		set_stream_info(stream, caps);
+		ret = set_stream_info(stream, caps);
+		if (ret < 0)
+			goto err;
 	}
 
 	if (pcm->capture) {
 		stream = &dai_drv->capture;
 		caps = &pcm->caps[SND_SOC_TPLG_STREAM_CAPTURE];
-		set_stream_info(stream, caps);
+		ret = set_stream_info(stream, caps);
+		if (ret < 0)
+			goto err;
 	}
 
 	if (pcm->compress)
@@ -1835,11 +1869,7 @@ static int soc_tplg_dai_create(struct soc_tplg *tplg,
 	ret = soc_tplg_dai_load(tplg, dai_drv, pcm, NULL);
 	if (ret < 0) {
 		dev_err(tplg->comp->dev, "ASoC: DAI loading failed\n");
-		kfree(dai_drv->playback.stream_name);
-		kfree(dai_drv->capture.stream_name);
-		kfree(dai_drv->name);
-		kfree(dai_drv);
-		return ret;
+		goto err;
 	}
 
 	dai_drv->dobj.index = tplg->index;
@@ -1860,6 +1890,14 @@ static int soc_tplg_dai_create(struct soc_tplg *tplg,
 		return ret;
 	}
 
+	return 0;
+
+err:
+	kfree(dai_drv->playback.stream_name);
+	kfree(dai_drv->capture.stream_name);
+	kfree(dai_drv->name);
+	kfree(dai_drv);
+
 	return ret;
 }
 
@@ -1916,11 +1954,20 @@ static int soc_tplg_fe_link_create(struct soc_tplg *tplg,
 	if (strlen(pcm->pcm_name)) {
 		link->name = kstrdup(pcm->pcm_name, GFP_KERNEL);
 		link->stream_name = kstrdup(pcm->pcm_name, GFP_KERNEL);
+		if (!link->name || !link->stream_name) {
+			ret = -ENOMEM;
+			goto err;
+		}
 	}
 	link->id = le32_to_cpu(pcm->pcm_id);
 
-	if (strlen(pcm->dai_name))
+	if (strlen(pcm->dai_name)) {
 		link->cpus->dai_name = kstrdup(pcm->dai_name, GFP_KERNEL);
+		if (!link->cpus->dai_name) {
+			ret = -ENOMEM;
+			goto err;
+		}
+	}
 
 	link->codecs->name = "snd-soc-dummy";
 	link->codecs->dai_name = "snd-soc-dummy-dai";
@@ -2088,7 +2135,9 @@ static int soc_tplg_pcm_elems_load(struct soc_tplg *tplg,
 			_pcm = pcm;
 		} else {
 			abi_match = false;
-			pcm_new_ver(tplg, pcm, &_pcm);
+			ret = pcm_new_ver(tplg, pcm, &_pcm);
+			if (ret < 0)
+				return ret;
 		}
 
 		/* create the FE DAIs and DAI links */
@@ -2436,13 +2485,17 @@ static int soc_tplg_dai_config(struct soc_tplg *tplg,
 	if (d->playback) {
 		stream = &dai_drv->playback;
 		caps = &d->caps[SND_SOC_TPLG_STREAM_PLAYBACK];
-		set_stream_info(stream, caps);
+		ret = set_stream_info(stream, caps);
+		if (ret < 0)
+			goto err;
 	}
 
 	if (d->capture) {
 		stream = &dai_drv->capture;
 		caps = &d->caps[SND_SOC_TPLG_STREAM_CAPTURE];
-		set_stream_info(stream, caps);
+		ret = set_stream_info(stream, caps);
+		if (ret < 0)
+			goto err;
 	}
 
 	if (d->flag_mask)
@@ -2454,10 +2507,15 @@ static int soc_tplg_dai_config(struct soc_tplg *tplg,
 	ret = soc_tplg_dai_load(tplg, dai_drv, NULL, dai);
 	if (ret < 0) {
 		dev_err(tplg->comp->dev, "ASoC: DAI loading failed\n");
-		return ret;
+		goto err;
 	}
 
 	return 0;
+
+err:
+	kfree(dai_drv->playback.stream_name);
+	kfree(dai_drv->capture.stream_name);
+	return ret;
 }
 
 /* load physical DAI elements */
@@ -2466,7 +2524,7 @@ static int soc_tplg_dai_elems_load(struct soc_tplg *tplg,
 {
 	struct snd_soc_tplg_dai *dai;
 	int count;
-	int i;
+	int i, ret;
 
 	count = le32_to_cpu(hdr->count);
 
@@ -2481,7 +2539,12 @@ static int soc_tplg_dai_elems_load(struct soc_tplg *tplg,
 			return -EINVAL;
 		}
 
-		soc_tplg_dai_config(tplg, dai);
+		ret = soc_tplg_dai_config(tplg, dai);
+		if (ret < 0) {
+			dev_err(tplg->dev, "ASoC: failed to configure DAI\n");
+			return ret;
+		}
+
 		tplg->pos += (sizeof(*dai) + le32_to_cpu(dai->priv.size));
 	}
 
diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c
index 0d0c9afd8791..34a7c3d6fb91 100644
--- a/sound/soc/stm/stm32_sai_sub.c
+++ b/sound/soc/stm/stm32_sai_sub.c
@@ -837,7 +837,7 @@ static int stm32_sai_set_config(struct snd_soc_dai *cpu_dai,
 		cr1 = SAI_XCR1_DS_SET(SAI_DATASIZE_32);
 		break;
 	default:
-		dev_err(cpu_dai->dev, "Data format not supported");
+		dev_err(cpu_dai->dev, "Data format not supported\n");
 		return -EINVAL;
 	}
 
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 721d12130d0c..e7b9040a54e6 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -1457,7 +1457,7 @@ static int mixer_ctl_connector_get(struct snd_kcontrol *kcontrol,
 		usb_audio_err(chip,
 			"cannot get connectors status: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
 			UAC_GET_CUR, validx, idx, cval->val_type);
-		return ret;
+		return filter_error(cval, ret);
 	}
 
 	ucontrol->value.integer.value[0] = val;
@@ -1771,11 +1771,15 @@ static void get_connector_control_name(struct usb_mixer_interface *mixer,
 
 /* Build a mixer control for a UAC connector control (jack-detect) */
 static void build_connector_control(struct usb_mixer_interface *mixer,
+				    const struct usbmix_name_map *imap,
 				    struct usb_audio_term *term, bool is_input)
 {
 	struct snd_kcontrol *kctl;
 	struct usb_mixer_elem_info *cval;
 
+	if (check_ignored_ctl(find_map(imap, term->id, 0)))
+		return;
+
 	cval = kzalloc(sizeof(*cval), GFP_KERNEL);
 	if (!cval)
 		return;
@@ -2109,8 +2113,9 @@ static int parse_audio_input_terminal(struct mixer_build *state, int unitid,
 	check_input_term(state, term_id, &iterm);
 
 	/* Check for jack detection. */
-	if (uac_v2v3_control_is_readable(bmctls, control))
-		build_connector_control(state->mixer, &iterm, true);
+	if ((iterm.type & 0xff00) != 0x0100 &&
+	    uac_v2v3_control_is_readable(bmctls, control))
+		build_connector_control(state->mixer, state->map, &iterm, true);
 
 	return 0;
 }
@@ -3071,13 +3076,13 @@ static int snd_usb_mixer_controls_badd(struct usb_mixer_interface *mixer,
 		memset(&iterm, 0, sizeof(iterm));
 		iterm.id = UAC3_BADD_IT_ID4;
 		iterm.type = UAC_BIDIR_TERMINAL_HEADSET;
-		build_connector_control(mixer, &iterm, true);
+		build_connector_control(mixer, map->map, &iterm, true);
 
 		/* Output Term - Insertion control */
 		memset(&oterm, 0, sizeof(oterm));
 		oterm.id = UAC3_BADD_OT_ID3;
 		oterm.type = UAC_BIDIR_TERMINAL_HEADSET;
-		build_connector_control(mixer, &oterm, false);
+		build_connector_control(mixer, map->map, &oterm, false);
 	}
 
 	return 0;
@@ -3106,7 +3111,7 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
 		if (map->id == state.chip->usb_id) {
 			state.map = map->map;
 			state.selector_map = map->selector_map;
-			mixer->ignore_ctl_error = map->ignore_ctl_error;
+			mixer->ignore_ctl_error |= map->ignore_ctl_error;
 			break;
 		}
 	}
@@ -3149,10 +3154,11 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
 			if (err < 0 && err != -EINVAL)
 				return err;
 
-			if (uac_v2v3_control_is_readable(le16_to_cpu(desc->bmControls),
+			if ((state.oterm.type & 0xff00) != 0x0100 &&
+			    uac_v2v3_control_is_readable(le16_to_cpu(desc->bmControls),
 							 UAC2_TE_CONNECTOR)) {
-				build_connector_control(state.mixer, &state.oterm,
-							false);
+				build_connector_control(state.mixer, state.map,
+							&state.oterm, false);
 			}
 		} else {  /* UAC_VERSION_3 */
 			struct uac3_output_terminal_descriptor *desc = p;
@@ -3174,10 +3180,11 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
 			if (err < 0 && err != -EINVAL)
 				return err;
 
-			if (uac_v2v3_control_is_readable(le32_to_cpu(desc->bmControls),
+			if ((state.oterm.type & 0xff00) != 0x0100 &&
+			    uac_v2v3_control_is_readable(le32_to_cpu(desc->bmControls),
 							 UAC3_TE_INSERTION)) {
-				build_connector_control(state.mixer, &state.oterm,
-							false);
+				build_connector_control(state.mixer, state.map,
+							&state.oterm, false);
 			}
 		}
 	}
diff --git a/sound/usb/mixer_maps.c b/sound/usb/mixer_maps.c
index 72b575c34860..b4e77000f441 100644
--- a/sound/usb/mixer_maps.c
+++ b/sound/usb/mixer_maps.c
@@ -360,9 +360,11 @@ static const struct usbmix_name_map corsair_virtuoso_map[] = {
 };
 
 /* Some mobos shipped with a dummy HD-audio show the invalid GET_MIN/GET_MAX
- * response for Input Gain Pad (id=19, control=12).  Skip it.
+ * response for Input Gain Pad (id=19, control=12) and the connector status
+ * for SPDIF terminal (id=18).  Skip them.
  */
 static const struct usbmix_name_map asus_rog_map[] = {
+	{ 18, NULL }, /* OT, connector control */
 	{ 19, NULL, 12 }, /* FU, Input Gain Pad */
 	{}
 };
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index 02b036b2aefb..f0302ad7f5a0 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -2181,6 +2181,421 @@ static int snd_rme_controls_create(struct usb_mixer_interface *mixer)
 	return 0;
 }
 
+/*
+ * RME Babyface Pro (FS)
+ *
+ * These devices exposes a couple of DSP functions via request to EP0.
+ * Switches are available via control registers, while routing is controlled
+ * by controlling the volume on each possible crossing point.
+ * Volume control is linear, from -inf (dec. 0) to +6dB (dec. 46341) with
+ * 0dB being at dec. 32768.
+ */
+enum {
+	SND_BBFPRO_CTL_REG1 = 0,
+	SND_BBFPRO_CTL_REG2
+};
+
+#define SND_BBFPRO_CTL_REG_MASK 1
+#define SND_BBFPRO_CTL_IDX_MASK 0xff
+#define SND_BBFPRO_CTL_IDX_SHIFT 1
+#define SND_BBFPRO_CTL_VAL_MASK 1
+#define SND_BBFPRO_CTL_VAL_SHIFT 9
+#define SND_BBFPRO_CTL_REG1_CLK_MASTER 0
+#define SND_BBFPRO_CTL_REG1_CLK_OPTICAL 1
+#define SND_BBFPRO_CTL_REG1_SPDIF_PRO 7
+#define SND_BBFPRO_CTL_REG1_SPDIF_EMPH 8
+#define SND_BBFPRO_CTL_REG1_SPDIF_OPTICAL 10
+#define SND_BBFPRO_CTL_REG2_48V_AN1 0
+#define SND_BBFPRO_CTL_REG2_48V_AN2 1
+#define SND_BBFPRO_CTL_REG2_SENS_IN3 2
+#define SND_BBFPRO_CTL_REG2_SENS_IN4 3
+#define SND_BBFPRO_CTL_REG2_PAD_AN1 4
+#define SND_BBFPRO_CTL_REG2_PAD_AN2 5
+
+#define SND_BBFPRO_MIXER_IDX_MASK 0x1ff
+#define SND_BBFPRO_MIXER_VAL_MASK 0x3ffff
+#define SND_BBFPRO_MIXER_VAL_SHIFT 9
+#define SND_BBFPRO_MIXER_VAL_MIN 0 // -inf
+#define SND_BBFPRO_MIXER_VAL_MAX 46341 // +6dB
+
+#define SND_BBFPRO_USBREQ_CTL_REG1 0x10
+#define SND_BBFPRO_USBREQ_CTL_REG2 0x17
+#define SND_BBFPRO_USBREQ_MIXER 0x12
+
+static int snd_bbfpro_ctl_update(struct usb_mixer_interface *mixer, u8 reg,
+				 u8 index, u8 value)
+{
+	int err;
+	u16 usb_req, usb_idx, usb_val;
+	struct snd_usb_audio *chip = mixer->chip;
+
+	err = snd_usb_lock_shutdown(chip);
+	if (err < 0)
+		return err;
+
+	if (reg == SND_BBFPRO_CTL_REG1) {
+		usb_req = SND_BBFPRO_USBREQ_CTL_REG1;
+		if (index == SND_BBFPRO_CTL_REG1_CLK_OPTICAL) {
+			usb_idx = 3;
+			usb_val = value ? 3 : 0;
+		} else {
+			usb_idx = 1 << index;
+			usb_val = value ? usb_idx : 0;
+		}
+	} else {
+		usb_req = SND_BBFPRO_USBREQ_CTL_REG2;
+		usb_idx = 1 << index;
+		usb_val = value ? usb_idx : 0;
+	}
+
+	err = snd_usb_ctl_msg(chip->dev,
+			      usb_sndctrlpipe(chip->dev, 0), usb_req,
+			      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			      usb_val, usb_idx, 0, 0);
+
+	snd_usb_unlock_shutdown(chip);
+	return err;
+}
+
+static int snd_bbfpro_ctl_get(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol)
+{
+	u8 reg, idx, val;
+	int pv;
+
+	pv = kcontrol->private_value;
+	reg = pv & SND_BBFPRO_CTL_REG_MASK;
+	idx = (pv >> SND_BBFPRO_CTL_IDX_SHIFT) & SND_BBFPRO_CTL_IDX_MASK;
+	val = kcontrol->private_value >> SND_BBFPRO_CTL_VAL_SHIFT;
+
+	if ((reg == SND_BBFPRO_CTL_REG1 &&
+	     idx == SND_BBFPRO_CTL_REG1_CLK_OPTICAL) ||
+	    (reg == SND_BBFPRO_CTL_REG2 &&
+	    (idx == SND_BBFPRO_CTL_REG2_SENS_IN3 ||
+	     idx == SND_BBFPRO_CTL_REG2_SENS_IN4))) {
+		ucontrol->value.enumerated.item[0] = val;
+	} else {
+		ucontrol->value.integer.value[0] = val;
+	}
+	return 0;
+}
+
+static int snd_bbfpro_ctl_info(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_info *uinfo)
+{
+	u8 reg, idx;
+	int pv;
+
+	pv = kcontrol->private_value;
+	reg = pv & SND_BBFPRO_CTL_REG_MASK;
+	idx = (pv >> SND_BBFPRO_CTL_IDX_SHIFT) & SND_BBFPRO_CTL_IDX_MASK;
+
+	if (reg == SND_BBFPRO_CTL_REG1 &&
+	    idx == SND_BBFPRO_CTL_REG1_CLK_OPTICAL) {
+		static const char * const texts[2] = {
+			"AutoSync",
+			"Internal"
+		};
+		return snd_ctl_enum_info(uinfo, 1, 2, texts);
+	} else if (reg == SND_BBFPRO_CTL_REG2 &&
+		   (idx == SND_BBFPRO_CTL_REG2_SENS_IN3 ||
+		    idx == SND_BBFPRO_CTL_REG2_SENS_IN4)) {
+		static const char * const texts[2] = {
+			"-10dBV",
+			"+4dBu"
+		};
+		return snd_ctl_enum_info(uinfo, 1, 2, texts);
+	}
+
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	return 0;
+}
+
+static int snd_bbfpro_ctl_put(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol)
+{
+	int err;
+	u8 reg, idx;
+	int old_value, pv, val;
+
+	struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
+	struct usb_mixer_interface *mixer = list->mixer;
+
+	pv = kcontrol->private_value;
+	reg = pv & SND_BBFPRO_CTL_REG_MASK;
+	idx = (pv >> SND_BBFPRO_CTL_IDX_SHIFT) & SND_BBFPRO_CTL_IDX_MASK;
+	old_value = (pv >> SND_BBFPRO_CTL_VAL_SHIFT) & SND_BBFPRO_CTL_VAL_MASK;
+
+	if ((reg == SND_BBFPRO_CTL_REG1 &&
+	     idx == SND_BBFPRO_CTL_REG1_CLK_OPTICAL) ||
+	    (reg == SND_BBFPRO_CTL_REG2 &&
+	    (idx == SND_BBFPRO_CTL_REG2_SENS_IN3 ||
+	     idx == SND_BBFPRO_CTL_REG2_SENS_IN4))) {
+		val = ucontrol->value.enumerated.item[0];
+	} else {
+		val = ucontrol->value.integer.value[0];
+	}
+
+	if (val > 1)
+		return -EINVAL;
+
+	if (val == old_value)
+		return 0;
+
+	kcontrol->private_value = reg
+		| ((idx & SND_BBFPRO_CTL_IDX_MASK) << SND_BBFPRO_CTL_IDX_SHIFT)
+		| ((val & SND_BBFPRO_CTL_VAL_MASK) << SND_BBFPRO_CTL_VAL_SHIFT);
+
+	err = snd_bbfpro_ctl_update(mixer, reg, idx, val);
+	return err < 0 ? err : 1;
+}
+
+static int snd_bbfpro_ctl_resume(struct usb_mixer_elem_list *list)
+{
+	u8 reg, idx;
+	int value, pv;
+
+	pv = list->kctl->private_value;
+	reg = pv & SND_BBFPRO_CTL_REG_MASK;
+	idx = (pv >> SND_BBFPRO_CTL_IDX_SHIFT) & SND_BBFPRO_CTL_IDX_MASK;
+	value = (pv >> SND_BBFPRO_CTL_VAL_SHIFT) & SND_BBFPRO_CTL_VAL_MASK;
+
+	return snd_bbfpro_ctl_update(list->mixer, reg, idx, value);
+}
+
+static int snd_bbfpro_vol_update(struct usb_mixer_interface *mixer, u16 index,
+				 u32 value)
+{
+	struct snd_usb_audio *chip = mixer->chip;
+	int err;
+	u16 idx;
+	u16 usb_idx, usb_val;
+	u32 v;
+
+	err = snd_usb_lock_shutdown(chip);
+	if (err < 0)
+		return err;
+
+	idx = index & SND_BBFPRO_MIXER_IDX_MASK;
+	// 18 bit linear volume, split so 2 bits end up in index.
+	v = value & SND_BBFPRO_MIXER_VAL_MASK;
+	usb_idx = idx | (v & 0x3) << 14;
+	usb_val = (v >> 2) & 0xffff;
+
+	err = snd_usb_ctl_msg(chip->dev,
+			      usb_sndctrlpipe(chip->dev, 0),
+			      SND_BBFPRO_USBREQ_MIXER,
+			      USB_DIR_OUT | USB_TYPE_VENDOR |
+			      USB_RECIP_DEVICE,
+			      usb_val, usb_idx, 0, 0);
+
+	snd_usb_unlock_shutdown(chip);
+	return err;
+}
+
+static int snd_bbfpro_vol_get(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol)
+{
+	ucontrol->value.integer.value[0] =
+		kcontrol->private_value >> SND_BBFPRO_MIXER_VAL_SHIFT;
+	return 0;
+}
+
+static int snd_bbfpro_vol_info(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 1;
+	uinfo->value.integer.min = SND_BBFPRO_MIXER_VAL_MIN;
+	uinfo->value.integer.max = SND_BBFPRO_MIXER_VAL_MAX;
+	return 0;
+}
+
+static int snd_bbfpro_vol_put(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol)
+{
+	int err;
+	u16 idx;
+	u32 new_val, old_value, uvalue;
+	struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
+	struct usb_mixer_interface *mixer = list->mixer;
+
+	uvalue = ucontrol->value.integer.value[0];
+	idx = kcontrol->private_value & SND_BBFPRO_MIXER_IDX_MASK;
+	old_value = kcontrol->private_value >> SND_BBFPRO_MIXER_VAL_SHIFT;
+
+	if (uvalue > SND_BBFPRO_MIXER_VAL_MAX)
+		return -EINVAL;
+
+	if (uvalue == old_value)
+		return 0;
+
+	new_val = uvalue & SND_BBFPRO_MIXER_VAL_MASK;
+
+	kcontrol->private_value = idx
+		| (new_val << SND_BBFPRO_MIXER_VAL_SHIFT);
+
+	err = snd_bbfpro_vol_update(mixer, idx, new_val);
+	return err < 0 ? err : 1;
+}
+
+static int snd_bbfpro_vol_resume(struct usb_mixer_elem_list *list)
+{
+	int pv = list->kctl->private_value;
+	u16 idx = pv & SND_BBFPRO_MIXER_IDX_MASK;
+	u32 val = (pv >> SND_BBFPRO_MIXER_VAL_SHIFT)
+		& SND_BBFPRO_MIXER_VAL_MASK;
+	return snd_bbfpro_vol_update(list->mixer, idx, val);
+}
+
+// Predfine elements
+static const struct snd_kcontrol_new snd_bbfpro_ctl_control = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.index = 0,
+	.info = snd_bbfpro_ctl_info,
+	.get = snd_bbfpro_ctl_get,
+	.put = snd_bbfpro_ctl_put
+};
+
+static const struct snd_kcontrol_new snd_bbfpro_vol_control = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.index = 0,
+	.info = snd_bbfpro_vol_info,
+	.get = snd_bbfpro_vol_get,
+	.put = snd_bbfpro_vol_put
+};
+
+static int snd_bbfpro_ctl_add(struct usb_mixer_interface *mixer, u8 reg,
+			      u8 index, char *name)
+{
+	struct snd_kcontrol_new knew = snd_bbfpro_ctl_control;
+
+	knew.name = name;
+	knew.private_value = (reg & SND_BBFPRO_CTL_REG_MASK)
+		| ((index & SND_BBFPRO_CTL_IDX_MASK)
+			<< SND_BBFPRO_CTL_IDX_SHIFT);
+
+	return add_single_ctl_with_resume(mixer, 0, snd_bbfpro_ctl_resume,
+		&knew, NULL);
+}
+
+static int snd_bbfpro_vol_add(struct usb_mixer_interface *mixer, u16 index,
+			      char *name)
+{
+	struct snd_kcontrol_new knew = snd_bbfpro_vol_control;
+
+	knew.name = name;
+	knew.private_value = index & SND_BBFPRO_MIXER_IDX_MASK;
+
+	return add_single_ctl_with_resume(mixer, 0, snd_bbfpro_vol_resume,
+		&knew, NULL);
+}
+
+static int snd_bbfpro_controls_create(struct usb_mixer_interface *mixer)
+{
+	int err, i, o;
+	char name[48];
+
+	static const char * const input[] = {
+		"AN1", "AN2", "IN3", "IN4", "AS1", "AS2", "ADAT3",
+		"ADAT4", "ADAT5", "ADAT6", "ADAT7", "ADAT8"};
+
+	static const char * const output[] = {
+		"AN1", "AN2", "PH3", "PH4", "AS1", "AS2", "ADAT3", "ADAT4",
+		"ADAT5", "ADAT6", "ADAT7", "ADAT8"};
+
+	for (o = 0 ; o < 12 ; ++o) {
+		for (i = 0 ; i < 12 ; ++i) {
+			// Line routing
+			snprintf(name, sizeof(name),
+				 "%s-%s-%s Playback Volume",
+				 (i < 2 ? "Mic" : "Line"),
+				 input[i], output[o]);
+			err = snd_bbfpro_vol_add(mixer, (26 * o + i), name);
+			if (err < 0)
+				return err;
+
+			// PCM routing... yes, it is output remapping
+			snprintf(name, sizeof(name),
+				 "PCM-%s-%s Playback Volume",
+				 output[i], output[o]);
+			err = snd_bbfpro_vol_add(mixer, (26 * o + 12 + i),
+						 name);
+			if (err < 0)
+				return err;
+		}
+	}
+
+	// Control Reg 1
+	err = snd_bbfpro_ctl_add(mixer, SND_BBFPRO_CTL_REG1,
+				 SND_BBFPRO_CTL_REG1_CLK_OPTICAL,
+				 "Sample Clock Source");
+	if (err < 0)
+		return err;
+
+	err = snd_bbfpro_ctl_add(mixer, SND_BBFPRO_CTL_REG1,
+				 SND_BBFPRO_CTL_REG1_SPDIF_PRO,
+				 "IEC958 Pro Mask");
+	if (err < 0)
+		return err;
+
+	err = snd_bbfpro_ctl_add(mixer, SND_BBFPRO_CTL_REG1,
+				 SND_BBFPRO_CTL_REG1_SPDIF_EMPH,
+				 "IEC958 Emphasis");
+	if (err < 0)
+		return err;
+
+	err = snd_bbfpro_ctl_add(mixer, SND_BBFPRO_CTL_REG1,
+				 SND_BBFPRO_CTL_REG1_SPDIF_OPTICAL,
+				 "IEC958 Switch");
+	if (err < 0)
+		return err;
+
+	// Control Reg 2
+	err = snd_bbfpro_ctl_add(mixer, SND_BBFPRO_CTL_REG2,
+				 SND_BBFPRO_CTL_REG2_48V_AN1,
+				 "Mic-AN1 48V");
+	if (err < 0)
+		return err;
+
+	err = snd_bbfpro_ctl_add(mixer, SND_BBFPRO_CTL_REG2,
+				 SND_BBFPRO_CTL_REG2_48V_AN2,
+				 "Mic-AN2 48V");
+	if (err < 0)
+		return err;
+
+	err = snd_bbfpro_ctl_add(mixer, SND_BBFPRO_CTL_REG2,
+				 SND_BBFPRO_CTL_REG2_SENS_IN3,
+				 "Line-IN3 Sens.");
+	if (err < 0)
+		return err;
+
+	err = snd_bbfpro_ctl_add(mixer, SND_BBFPRO_CTL_REG2,
+				 SND_BBFPRO_CTL_REG2_SENS_IN4,
+				 "Line-IN4 Sens.");
+	if (err < 0)
+		return err;
+
+	err = snd_bbfpro_ctl_add(mixer, SND_BBFPRO_CTL_REG2,
+				 SND_BBFPRO_CTL_REG2_PAD_AN1,
+				 "Mic-AN1 PAD");
+	if (err < 0)
+		return err;
+
+	err = snd_bbfpro_ctl_add(mixer, SND_BBFPRO_CTL_REG2,
+				 SND_BBFPRO_CTL_REG2_PAD_AN2,
+				 "Mic-AN2 PAD");
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
 int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
 {
 	int err = 0;
@@ -2282,6 +2697,9 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
 	case USB_ID(0x0194f, 0x010c): /* Presonus Studio 1810c */
 		err = snd_sc1810_init_mixer(mixer);
 		break;
+	case USB_ID(0x2a39, 0x3fb0): /* RME Babyface Pro FS */
+		err = snd_bbfpro_controls_create(mixer);
+		break;
 	}
 
 	return err;
diff --git a/tools/arch/x86/include/asm/cpufeatures.h b/tools/arch/x86/include/asm/cpufeatures.h
index f3327cb56edf..db189945e9b0 100644
--- a/tools/arch/x86/include/asm/cpufeatures.h
+++ b/tools/arch/x86/include/asm/cpufeatures.h
@@ -217,7 +217,7 @@
 #define X86_FEATURE_IBRS		( 7*32+25) /* Indirect Branch Restricted Speculation */
 #define X86_FEATURE_IBPB		( 7*32+26) /* Indirect Branch Prediction Barrier */
 #define X86_FEATURE_STIBP		( 7*32+27) /* Single Thread Indirect Branch Predictors */
-#define X86_FEATURE_ZEN			( 7*32+28) /* "" CPU is AMD family 0x17 (Zen) */
+#define X86_FEATURE_ZEN			( 7*32+28) /* "" CPU is AMD family 0x17 or above (Zen) */
 #define X86_FEATURE_L1TF_PTEINV		( 7*32+29) /* "" L1TF workaround PTE inversion */
 #define X86_FEATURE_IBRS_ENHANCED	( 7*32+30) /* Enhanced IBRS */
 #define X86_FEATURE_MSR_IA32_FEAT_CTL	( 7*32+31) /* "" MSR IA32_FEAT_CTL configured */
@@ -285,6 +285,7 @@
 #define X86_FEATURE_CQM_MBM_LOCAL	(11*32+ 3) /* LLC Local MBM monitoring */
 #define X86_FEATURE_FENCE_SWAPGS_USER	(11*32+ 4) /* "" LFENCE in user entry SWAPGS path */
 #define X86_FEATURE_FENCE_SWAPGS_KERNEL	(11*32+ 5) /* "" LFENCE in kernel entry SWAPGS path */
+#define X86_FEATURE_SPLIT_LOCK_DETECT	(11*32+ 6) /* #AC for split lock */
 
 /* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */
 #define X86_FEATURE_AVX512_BF16		(12*32+ 5) /* AVX512 BFLOAT16 instructions */
@@ -299,6 +300,7 @@
 #define X86_FEATURE_AMD_IBRS		(13*32+14) /* "" Indirect Branch Restricted Speculation */
 #define X86_FEATURE_AMD_STIBP		(13*32+15) /* "" Single Thread Indirect Branch Predictors */
 #define X86_FEATURE_AMD_STIBP_ALWAYS_ON	(13*32+17) /* "" Single Thread Indirect Branch Predictors always-on preferred */
+#define X86_FEATURE_AMD_PPIN		(13*32+23) /* Protected Processor Inventory Number */
 #define X86_FEATURE_AMD_SSBD		(13*32+24) /* "" Speculative Store Bypass Disable */
 #define X86_FEATURE_VIRT_SSBD		(13*32+25) /* Virtualized Speculative Store Bypass Disable */
 #define X86_FEATURE_AMD_SSB_NO		(13*32+26) /* "" Speculative Store Bypass is fixed in hardware. */
@@ -367,6 +369,7 @@
 #define X86_FEATURE_INTEL_STIBP		(18*32+27) /* "" Single Thread Indirect Branch Predictors */
 #define X86_FEATURE_FLUSH_L1D		(18*32+28) /* Flush L1D cache */
 #define X86_FEATURE_ARCH_CAPABILITIES	(18*32+29) /* IA32_ARCH_CAPABILITIES MSR (Intel) */
+#define X86_FEATURE_CORE_CAPABILITIES	(18*32+30) /* "" IA32_CORE_CAPABILITIES MSR */
 #define X86_FEATURE_SPEC_CTRL_SSBD	(18*32+31) /* "" Speculative Store Bypass Disable */
 
 /*
diff --git a/tools/arch/x86/include/asm/msr-index.h b/tools/arch/x86/include/asm/msr-index.h
index d5e517d1c3dd..12c9684d59ba 100644
--- a/tools/arch/x86/include/asm/msr-index.h
+++ b/tools/arch/x86/include/asm/msr-index.h
@@ -41,6 +41,10 @@
 
 /* Intel MSRs. Some also available on other CPUs */
 
+#define MSR_TEST_CTRL				0x00000033
+#define MSR_TEST_CTRL_SPLIT_LOCK_DETECT_BIT	29
+#define MSR_TEST_CTRL_SPLIT_LOCK_DETECT		BIT(MSR_TEST_CTRL_SPLIT_LOCK_DETECT_BIT)
+
 #define MSR_IA32_SPEC_CTRL		0x00000048 /* Speculation Control */
 #define SPEC_CTRL_IBRS			BIT(0)	   /* Indirect Branch Restricted Speculation */
 #define SPEC_CTRL_STIBP_SHIFT		1	   /* Single Thread Indirect Branch Predictor (STIBP) bit */
@@ -70,6 +74,11 @@
  */
 #define MSR_IA32_UMWAIT_CONTROL_TIME_MASK	(~0x03U)
 
+/* Abbreviated from Intel SDM name IA32_CORE_CAPABILITIES */
+#define MSR_IA32_CORE_CAPS			  0x000000cf
+#define MSR_IA32_CORE_CAPS_SPLIT_LOCK_DETECT_BIT  5
+#define MSR_IA32_CORE_CAPS_SPLIT_LOCK_DETECT	  BIT(MSR_IA32_CORE_CAPS_SPLIT_LOCK_DETECT_BIT)
+
 #define MSR_PKG_CST_CONFIG_CONTROL	0x000000e2
 #define NHM_C3_AUTO_DEMOTE		(1UL << 25)
 #define NHM_C1_AUTO_DEMOTE		(1UL << 26)
diff --git a/tools/bpf/bpftool/struct_ops.c b/tools/bpf/bpftool/struct_ops.c
index 2a7befbd11ad..0fe0d584c57e 100644
--- a/tools/bpf/bpftool/struct_ops.c
+++ b/tools/bpf/bpftool/struct_ops.c
@@ -591,6 +591,8 @@ int do_struct_ops(int argc, char **argv)
 
 	err = cmd_select(cmds, argc, argv, do_help);
 
-	btf__free(btf_vmlinux);
+	if (!IS_ERR(btf_vmlinux))
+		btf__free(btf_vmlinux);
+
 	return err;
 }
diff --git a/tools/include/linux/bits.h b/tools/include/linux/bits.h
index 669d69441a62..4671fbf28842 100644
--- a/tools/include/linux/bits.h
+++ b/tools/include/linux/bits.h
@@ -3,9 +3,9 @@
 #define __LINUX_BITS_H
 
 #include <linux/const.h>
+#include <vdso/bits.h>
 #include <asm/bitsperlong.h>
 
-#define BIT(nr)			(UL(1) << (nr))
 #define BIT_ULL(nr)		(ULL(1) << (nr))
 #define BIT_MASK(nr)		(UL(1) << ((nr) % BITS_PER_LONG))
 #define BIT_WORD(nr)		((nr) / BITS_PER_LONG)
@@ -18,12 +18,30 @@
  * position @h. For example
  * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
  */
-#define GENMASK(h, l) \
+#if !defined(__ASSEMBLY__) && \
+	(!defined(CONFIG_CC_IS_GCC) || CONFIG_GCC_VERSION >= 49000)
+#include <linux/build_bug.h>
+#define GENMASK_INPUT_CHECK(h, l) \
+	(BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
+		__builtin_constant_p((l) > (h)), (l) > (h), 0)))
+#else
+/*
+ * BUILD_BUG_ON_ZERO is not available in h files included from asm files,
+ * disable the input check if that is the case.
+ */
+#define GENMASK_INPUT_CHECK(h, l) 0
+#endif
+
+#define __GENMASK(h, l) \
 	(((~UL(0)) - (UL(1) << (l)) + 1) & \
 	 (~UL(0) >> (BITS_PER_LONG - 1 - (h))))
+#define GENMASK(h, l) \
+	(GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l))
 
-#define GENMASK_ULL(h, l) \
+#define __GENMASK_ULL(h, l) \
 	(((~ULL(0)) - (ULL(1) << (l)) + 1) & \
 	 (~ULL(0) >> (BITS_PER_LONG_LONG - 1 - (h))))
+#define GENMASK_ULL(h, l) \
+	(GENMASK_INPUT_CHECK(h, l) + __GENMASK_ULL(h, l))
 
 #endif	/* __LINUX_BITS_H */
diff --git a/tools/include/linux/build_bug.h b/tools/include/linux/build_bug.h
new file mode 100644
index 000000000000..cc7070c7439b
--- /dev/null
+++ b/tools/include/linux/build_bug.h
@@ -0,0 +1,82 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_BUILD_BUG_H
+#define _LINUX_BUILD_BUG_H
+
+#include <linux/compiler.h>
+
+#ifdef __CHECKER__
+#define BUILD_BUG_ON_ZERO(e) (0)
+#else /* __CHECKER__ */
+/*
+ * Force a compilation error if condition is true, but also produce a
+ * result (of value 0 and type int), 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) ((int)(sizeof(struct { int:(-!!(e)); })))
+#endif /* __CHECKER__ */
+
+/* Force a compilation error if a constant expression is not a power of 2 */
+#define __BUILD_BUG_ON_NOT_POWER_OF_2(n)	\
+	BUILD_BUG_ON(((n) & ((n) - 1)) != 0)
+#define BUILD_BUG_ON_NOT_POWER_OF_2(n)			\
+	BUILD_BUG_ON((n) == 0 || (((n) & ((n) - 1)) != 0))
+
+/*
+ * BUILD_BUG_ON_INVALID() permits the compiler to check the validity of the
+ * expression but avoids the generation of any code, even if that expression
+ * has side-effects.
+ */
+#define BUILD_BUG_ON_INVALID(e) ((void)(sizeof((__force long)(e))))
+
+/**
+ * BUILD_BUG_ON_MSG - break compile if a condition is true & emit supplied
+ *		      error message.
+ * @condition: the condition which the compiler should know is false.
+ *
+ * See BUILD_BUG_ON for description.
+ */
+#define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
+
+/**
+ * BUILD_BUG_ON - break compile if a condition is true.
+ * @condition: the condition which the compiler should know is false.
+ *
+ * If you have some code which relies on certain constants being equal, or
+ * some other compile-time-evaluated condition, you should use BUILD_BUG_ON to
+ * detect if someone changes it.
+ */
+#define BUILD_BUG_ON(condition) \
+	BUILD_BUG_ON_MSG(condition, "BUILD_BUG_ON failed: " #condition)
+
+/**
+ * BUILD_BUG - break compile if used.
+ *
+ * If you have some code that you expect the compiler to eliminate at
+ * build time, you should use BUILD_BUG to detect if it is
+ * unexpectedly used.
+ */
+#define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
+
+/**
+ * static_assert - check integer constant expression at build time
+ *
+ * static_assert() is a wrapper for the C11 _Static_assert, with a
+ * little macro magic to make the message optional (defaulting to the
+ * stringification of the tested expression).
+ *
+ * Contrary to BUILD_BUG_ON(), static_assert() can be used at global
+ * scope, but requires the expression to be an integer constant
+ * expression (i.e., it is not enough that __builtin_constant_p() is
+ * true for expr).
+ *
+ * Also note that BUILD_BUG_ON() fails the build if the condition is
+ * true, while static_assert() fails the build if the expression is
+ * false.
+ */
+#ifndef static_assert
+#define static_assert(expr, ...) __static_assert(expr, ##__VA_ARGS__, #expr)
+#define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
+#endif // static_assert
+
+#endif	/* _LINUX_BUILD_BUG_H */
diff --git a/tools/include/linux/compiler.h b/tools/include/linux/compiler.h
index 1827c2f973f9..180f7714a5f1 100644
--- a/tools/include/linux/compiler.h
+++ b/tools/include/linux/compiler.h
@@ -10,6 +10,32 @@
 # define __compiletime_error(message)
 #endif
 
+#ifdef __OPTIMIZE__
+# define __compiletime_assert(condition, msg, prefix, suffix)		\
+	do {								\
+		extern void prefix ## suffix(void) __compiletime_error(msg); \
+		if (!(condition))					\
+			prefix ## suffix();				\
+	} while (0)
+#else
+# define __compiletime_assert(condition, msg, prefix, suffix) do { } while (0)
+#endif
+
+#define _compiletime_assert(condition, msg, prefix, suffix) \
+	__compiletime_assert(condition, msg, prefix, suffix)
+
+/**
+ * compiletime_assert - break build and emit msg if condition is false
+ * @condition: a compile-time constant condition to check
+ * @msg:       a message to emit if condition is false
+ *
+ * In tradition of POSIX assert, this macro will break the build if the
+ * supplied condition is *false*, emitting the supplied error message if the
+ * compiler has support to do so.
+ */
+#define compiletime_assert(condition, msg) \
+	_compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
+
 /* Optimization barrier */
 /* The "volatile" is due to gcc bugs */
 #define barrier() __asm__ __volatile__("": : :"memory")
diff --git a/tools/include/linux/const.h b/tools/include/linux/const.h
index 7b55a55f5911..81b8aae5a855 100644
--- a/tools/include/linux/const.h
+++ b/tools/include/linux/const.h
@@ -1,9 +1,6 @@
 #ifndef _LINUX_CONST_H
 #define _LINUX_CONST_H
 
-#include <uapi/linux/const.h>
-
-#define UL(x)		(_UL(x))
-#define ULL(x)		(_ULL(x))
+#include <vdso/const.h>
 
 #endif /* _LINUX_CONST_H */
diff --git a/tools/include/linux/kernel.h b/tools/include/linux/kernel.h
index cba226948a0c..a7e54a08fb54 100644
--- a/tools/include/linux/kernel.h
+++ b/tools/include/linux/kernel.h
@@ -5,6 +5,7 @@
 #include <stdarg.h>
 #include <stddef.h>
 #include <assert.h>
+#include <linux/build_bug.h>
 #include <linux/compiler.h>
 #include <endian.h>
 #include <byteswap.h>
@@ -35,9 +36,6 @@
 	(type *)((char *)__mptr - offsetof(type, member)); })
 #endif
 
-#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
-#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
-
 #ifndef max
 #define max(x, y) ({				\
 	typeof(x) _max1 = (x);			\
diff --git a/tools/include/uapi/drm/drm.h b/tools/include/uapi/drm/drm.h
index 868bf7996c0f..808b48a93330 100644
--- a/tools/include/uapi/drm/drm.h
+++ b/tools/include/uapi/drm/drm.h
@@ -948,6 +948,8 @@ extern "C" {
 #define DRM_IOCTL_SYNCOBJ_TRANSFER	DRM_IOWR(0xCC, struct drm_syncobj_transfer)
 #define DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL	DRM_IOWR(0xCD, struct drm_syncobj_timeline_array)
 
+#define DRM_IOCTL_MODE_GETFB2		DRM_IOWR(0xCE, struct drm_mode_fb_cmd2)
+
 /**
  * Device specific ioctls should only be in their respective headers
  * The device specific ioctl range is from 0x40 to 0x9f.
diff --git a/tools/include/uapi/drm/i915_drm.h b/tools/include/uapi/drm/i915_drm.h
index 829c0a48577f..2813e579b480 100644
--- a/tools/include/uapi/drm/i915_drm.h
+++ b/tools/include/uapi/drm/i915_drm.h
@@ -1619,6 +1619,27 @@ struct drm_i915_gem_context_param {
  * By default, new contexts allow persistence.
  */
 #define I915_CONTEXT_PARAM_PERSISTENCE	0xb
+
+/*
+ * I915_CONTEXT_PARAM_RINGSIZE:
+ *
+ * Sets the size of the CS ringbuffer to use for logical ring contexts. This
+ * applies a limit of how many batches can be queued to HW before the caller
+ * is blocked due to lack of space for more commands.
+ *
+ * Only reliably possible to be set prior to first use, i.e. during
+ * construction. At any later point, the current execution must be flushed as
+ * the ring can only be changed while the context is idle. Note, the ringsize
+ * can be specified as a constructor property, see
+ * I915_CONTEXT_CREATE_EXT_SETPARAM, but can also be set later if required.
+ *
+ * Only applies to the current set of engine and lost when those engines
+ * are replaced by a new mapping (see I915_CONTEXT_PARAM_ENGINES).
+ *
+ * Must be between 4 - 512 KiB, in intervals of page size [4 KiB].
+ * Default is 16 KiB.
+ */
+#define I915_CONTEXT_PARAM_RINGSIZE	0xc
 /* Must be kept compact -- no holes and well documented */
 
 	__u64 value;
diff --git a/tools/include/uapi/linux/fscrypt.h b/tools/include/uapi/linux/fscrypt.h
index 0d8a6f47711c..a10e3cdc2839 100644
--- a/tools/include/uapi/linux/fscrypt.h
+++ b/tools/include/uapi/linux/fscrypt.h
@@ -163,6 +163,7 @@ struct fscrypt_get_key_status_arg {
 #define FS_IOC_REMOVE_ENCRYPTION_KEY		_IOWR('f', 24, struct fscrypt_remove_key_arg)
 #define FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS	_IOWR('f', 25, struct fscrypt_remove_key_arg)
 #define FS_IOC_GET_ENCRYPTION_KEY_STATUS	_IOWR('f', 26, struct fscrypt_get_key_status_arg)
+#define FS_IOC_GET_ENCRYPTION_NONCE		_IOR('f', 27, __u8[16])
 
 /**********************************************************************/
 
diff --git a/tools/include/uapi/linux/kvm.h b/tools/include/uapi/linux/kvm.h
index 4b95f9a31a2f..428c7dde6b4b 100644
--- a/tools/include/uapi/linux/kvm.h
+++ b/tools/include/uapi/linux/kvm.h
@@ -474,12 +474,17 @@ struct kvm_s390_mem_op {
 	__u32 size;		/* amount of bytes */
 	__u32 op;		/* type of operation */
 	__u64 buf;		/* buffer in userspace */
-	__u8 ar;		/* the access register number */
-	__u8 reserved[31];	/* should be set to 0 */
+	union {
+		__u8 ar;	/* the access register number */
+		__u32 sida_offset; /* offset into the sida */
+		__u8 reserved[32]; /* should be set to 0 */
+	};
 };
 /* types for kvm_s390_mem_op->op */
 #define KVM_S390_MEMOP_LOGICAL_READ	0
 #define KVM_S390_MEMOP_LOGICAL_WRITE	1
+#define KVM_S390_MEMOP_SIDA_READ	2
+#define KVM_S390_MEMOP_SIDA_WRITE	3
 /* flags for kvm_s390_mem_op->flags */
 #define KVM_S390_MEMOP_F_CHECK_ONLY		(1ULL << 0)
 #define KVM_S390_MEMOP_F_INJECT_EXCEPTION	(1ULL << 1)
@@ -1010,6 +1015,8 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_ARM_NISV_TO_USER 177
 #define KVM_CAP_ARM_INJECT_EXT_DABT 178
 #define KVM_CAP_S390_VCPU_RESETS 179
+#define KVM_CAP_S390_PROTECTED 180
+#define KVM_CAP_PPC_SECURE_GUEST 181
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -1478,6 +1485,39 @@ struct kvm_enc_region {
 #define KVM_S390_NORMAL_RESET	_IO(KVMIO,   0xc3)
 #define KVM_S390_CLEAR_RESET	_IO(KVMIO,   0xc4)
 
+struct kvm_s390_pv_sec_parm {
+	__u64 origin;
+	__u64 length;
+};
+
+struct kvm_s390_pv_unp {
+	__u64 addr;
+	__u64 size;
+	__u64 tweak;
+};
+
+enum pv_cmd_id {
+	KVM_PV_ENABLE,
+	KVM_PV_DISABLE,
+	KVM_PV_SET_SEC_PARMS,
+	KVM_PV_UNPACK,
+	KVM_PV_VERIFY,
+	KVM_PV_PREP_RESET,
+	KVM_PV_UNSHARE_ALL,
+};
+
+struct kvm_pv_cmd {
+	__u32 cmd;	/* Command to be executed */
+	__u16 rc;	/* Ultravisor return code */
+	__u16 rrc;	/* Ultravisor return reason code */
+	__u64 data;	/* Data or address */
+	__u32 flags;    /* flags for future extensions. Must be 0 for now */
+	__u32 reserved[3];
+};
+
+/* Available with KVM_CAP_S390_PROTECTED */
+#define KVM_S390_PV_COMMAND		_IOWR(KVMIO, 0xc5, struct kvm_pv_cmd)
+
 /* Secure Encrypted Virtualization command */
 enum sev_cmd_id {
 	/* Guest initialization commands */
@@ -1628,4 +1668,7 @@ struct kvm_hyperv_eventfd {
 #define KVM_HYPERV_CONN_ID_MASK		0x00ffffff
 #define KVM_HYPERV_EVENTFD_DEASSIGN	(1 << 0)
 
+#define KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE    (1 << 0)
+#define KVM_DIRTY_LOG_INITIALLY_SET            (1 << 1)
+
 #endif /* __LINUX_KVM_H */
diff --git a/tools/include/uapi/linux/mman.h b/tools/include/uapi/linux/mman.h
index fc1a64c3447b..923cc162609c 100644
--- a/tools/include/uapi/linux/mman.h
+++ b/tools/include/uapi/linux/mman.h
@@ -5,8 +5,9 @@
 #include <asm/mman.h>
 #include <asm-generic/hugetlb_encode.h>
 
-#define MREMAP_MAYMOVE	1
-#define MREMAP_FIXED	2
+#define MREMAP_MAYMOVE		1
+#define MREMAP_FIXED		2
+#define MREMAP_DONTUNMAP	4
 
 #define OVERCOMMIT_GUESS		0
 #define OVERCOMMIT_ALWAYS		1
diff --git a/tools/include/uapi/linux/sched.h b/tools/include/uapi/linux/sched.h
index 2e3bc22c6f20..3bac0a8ceab2 100644
--- a/tools/include/uapi/linux/sched.h
+++ b/tools/include/uapi/linux/sched.h
@@ -35,6 +35,7 @@
 
 /* Flags for the clone3() syscall. */
 #define CLONE_CLEAR_SIGHAND 0x100000000ULL /* Clear any signal handler and reset to SIG_DFL. */
+#define CLONE_INTO_CGROUP 0x200000000ULL /* Clone into a specific cgroup given the right permissions. */
 
 /*
  * cloning flags intersect with CSIGNAL so can be used with unshare and clone3
@@ -81,6 +82,8 @@
  * @set_tid_size: This defines the size of the array referenced
  *                in @set_tid. This cannot be larger than the
  *                kernel's limit of nested PID namespaces.
+ * @cgroup:       If CLONE_INTO_CGROUP is specified set this to
+ *                a file descriptor for the cgroup.
  *
  * The structure is versioned by size and thus extensible.
  * New struct members must go at the end of the struct and
@@ -97,11 +100,13 @@ struct clone_args {
 	__aligned_u64 tls;
 	__aligned_u64 set_tid;
 	__aligned_u64 set_tid_size;
+	__aligned_u64 cgroup;
 };
 #endif
 
 #define CLONE_ARGS_SIZE_VER0 64 /* sizeof first published struct */
 #define CLONE_ARGS_SIZE_VER1 80 /* sizeof second published struct */
+#define CLONE_ARGS_SIZE_VER2 88 /* sizeof third published struct */
 
 /*
  * Scheduling policies
diff --git a/tools/include/uapi/linux/vhost.h b/tools/include/uapi/linux/vhost.h
index 40d028eed645..9fe72e4b1373 100644
--- a/tools/include/uapi/linux/vhost.h
+++ b/tools/include/uapi/linux/vhost.h
@@ -116,4 +116,28 @@
 #define VHOST_VSOCK_SET_GUEST_CID	_IOW(VHOST_VIRTIO, 0x60, __u64)
 #define VHOST_VSOCK_SET_RUNNING		_IOW(VHOST_VIRTIO, 0x61, int)
 
+/* VHOST_VDPA specific defines */
+
+/* Get the device id. The device ids follow the same definition of
+ * the device id defined in virtio-spec.
+ */
+#define VHOST_VDPA_GET_DEVICE_ID	_IOR(VHOST_VIRTIO, 0x70, __u32)
+/* Get and set the status. The status bits follow the same definition
+ * of the device status defined in virtio-spec.
+ */
+#define VHOST_VDPA_GET_STATUS		_IOR(VHOST_VIRTIO, 0x71, __u8)
+#define VHOST_VDPA_SET_STATUS		_IOW(VHOST_VIRTIO, 0x72, __u8)
+/* Get and set the device config. The device config follows the same
+ * definition of the device config defined in virtio-spec.
+ */
+#define VHOST_VDPA_GET_CONFIG		_IOR(VHOST_VIRTIO, 0x73, \
+					     struct vhost_vdpa_config)
+#define VHOST_VDPA_SET_CONFIG		_IOW(VHOST_VIRTIO, 0x74, \
+					     struct vhost_vdpa_config)
+/* Enable/disable the ring. */
+#define VHOST_VDPA_SET_VRING_ENABLE	_IOW(VHOST_VIRTIO, 0x75, \
+					     struct vhost_vring_state)
+/* Get the max ring size. */
+#define VHOST_VDPA_GET_VRING_NUM	_IOR(VHOST_VIRTIO, 0x76, __u16)
+
 #endif
diff --git a/tools/include/vdso/bits.h b/tools/include/vdso/bits.h
new file mode 100644
index 000000000000..6d005a1f5d94
--- /dev/null
+++ b/tools/include/vdso/bits.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __VDSO_BITS_H
+#define __VDSO_BITS_H
+
+#include <vdso/const.h>
+
+#define BIT(nr)			(UL(1) << (nr))
+
+#endif	/* __VDSO_BITS_H */
diff --git a/tools/include/vdso/const.h b/tools/include/vdso/const.h
new file mode 100644
index 000000000000..94b385ad438d
--- /dev/null
+++ b/tools/include/vdso/const.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __VDSO_CONST_H
+#define __VDSO_CONST_H
+
+#include <uapi/linux/const.h>
+
+#define UL(x)		(_UL(x))
+#define ULL(x)		(_ULL(x))
+
+#endif /* __VDSO_CONST_H */
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index ff9174282a8c..8f480e29a6b0 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -178,6 +178,8 @@ struct bpf_capabilities {
 	__u32 array_mmap:1;
 	/* BTF_FUNC_GLOBAL is supported */
 	__u32 btf_func_global:1;
+	/* kernel support for expected_attach_type in BPF_PROG_LOAD */
+	__u32 exp_attach_type:1;
 };
 
 enum reloc_type {
@@ -194,6 +196,22 @@ struct reloc_desc {
 	int sym_off;
 };
 
+struct bpf_sec_def;
+
+typedef struct bpf_link *(*attach_fn_t)(const struct bpf_sec_def *sec,
+					struct bpf_program *prog);
+
+struct bpf_sec_def {
+	const char *sec;
+	size_t len;
+	enum bpf_prog_type prog_type;
+	enum bpf_attach_type expected_attach_type;
+	bool is_exp_attach_type_optional;
+	bool is_attachable;
+	bool is_attach_btf;
+	attach_fn_t attach_fn;
+};
+
 /*
  * bpf_prog should be a better name but it has been used in
  * linux/filter.h.
@@ -204,6 +222,7 @@ struct bpf_program {
 	char *name;
 	int prog_ifindex;
 	char *section_name;
+	const struct bpf_sec_def *sec_def;
 	/* section_name with / replaced by _; makes recursive pinning
 	 * in bpf_object__pin_programs easier
 	 */
@@ -3315,6 +3334,37 @@ static int bpf_object__probe_array_mmap(struct bpf_object *obj)
 	return 0;
 }
 
+static int
+bpf_object__probe_exp_attach_type(struct bpf_object *obj)
+{
+	struct bpf_load_program_attr attr;
+	struct bpf_insn insns[] = {
+		BPF_MOV64_IMM(BPF_REG_0, 0),
+		BPF_EXIT_INSN(),
+	};
+	int fd;
+
+	memset(&attr, 0, sizeof(attr));
+	/* use any valid combination of program type and (optional)
+	 * non-zero expected attach type (i.e., not a BPF_CGROUP_INET_INGRESS)
+	 * to see if kernel supports expected_attach_type field for
+	 * BPF_PROG_LOAD command
+	 */
+	attr.prog_type = BPF_PROG_TYPE_CGROUP_SOCK;
+	attr.expected_attach_type = BPF_CGROUP_INET_SOCK_CREATE;
+	attr.insns = insns;
+	attr.insns_cnt = ARRAY_SIZE(insns);
+	attr.license = "GPL";
+
+	fd = bpf_load_program_xattr(&attr, NULL, 0);
+	if (fd >= 0) {
+		obj->caps.exp_attach_type = 1;
+		close(fd);
+		return 1;
+	}
+	return 0;
+}
+
 static int
 bpf_object__probe_caps(struct bpf_object *obj)
 {
@@ -3325,6 +3375,7 @@ bpf_object__probe_caps(struct bpf_object *obj)
 		bpf_object__probe_btf_func_global,
 		bpf_object__probe_btf_datasec,
 		bpf_object__probe_array_mmap,
+		bpf_object__probe_exp_attach_type,
 	};
 	int i, ret;
 
@@ -4861,7 +4912,12 @@ load_program(struct bpf_program *prog, struct bpf_insn *insns, int insns_cnt,
 
 	memset(&load_attr, 0, sizeof(struct bpf_load_program_attr));
 	load_attr.prog_type = prog->type;
-	load_attr.expected_attach_type = prog->expected_attach_type;
+	/* old kernels might not support specifying expected_attach_type */
+	if (!prog->caps->exp_attach_type && prog->sec_def &&
+	    prog->sec_def->is_exp_attach_type_optional)
+		load_attr.expected_attach_type = 0;
+	else
+		load_attr.expected_attach_type = prog->expected_attach_type;
 	if (prog->caps->name)
 		load_attr.name = prog->name;
 	load_attr.insns = insns;
@@ -5062,6 +5118,8 @@ bpf_object__load_progs(struct bpf_object *obj, int log_level)
 	return 0;
 }
 
+static const struct bpf_sec_def *find_sec_def(const char *sec_name);
+
 static struct bpf_object *
 __bpf_object__open(const char *path, const void *obj_buf, size_t obj_buf_sz,
 		   const struct bpf_object_open_opts *opts)
@@ -5117,24 +5175,17 @@ __bpf_object__open(const char *path, const void *obj_buf, size_t obj_buf_sz,
 	bpf_object__elf_finish(obj);
 
 	bpf_object__for_each_program(prog, obj) {
-		enum bpf_prog_type prog_type;
-		enum bpf_attach_type attach_type;
-
-		if (prog->type != BPF_PROG_TYPE_UNSPEC)
-			continue;
-
-		err = libbpf_prog_type_by_name(prog->section_name, &prog_type,
-					       &attach_type);
-		if (err == -ESRCH)
+		prog->sec_def = find_sec_def(prog->section_name);
+		if (!prog->sec_def)
 			/* couldn't guess, but user might manually specify */
 			continue;
-		if (err)
-			goto out;
 
-		bpf_program__set_type(prog, prog_type);
-		bpf_program__set_expected_attach_type(prog, attach_type);
-		if (prog_type == BPF_PROG_TYPE_TRACING ||
-		    prog_type == BPF_PROG_TYPE_EXT)
+		bpf_program__set_type(prog, prog->sec_def->prog_type);
+		bpf_program__set_expected_attach_type(prog,
+				prog->sec_def->expected_attach_type);
+
+		if (prog->sec_def->prog_type == BPF_PROG_TYPE_TRACING ||
+		    prog->sec_def->prog_type == BPF_PROG_TYPE_EXT)
 			prog->attach_prog_fd = OPTS_GET(opts, attach_prog_fd, 0);
 	}
 
@@ -6223,23 +6274,32 @@ void bpf_program__set_expected_attach_type(struct bpf_program *prog,
 	prog->expected_attach_type = type;
 }
 
-#define BPF_PROG_SEC_IMPL(string, ptype, eatype, is_attachable, btf, atype) \
-	{ string, sizeof(string) - 1, ptype, eatype, is_attachable, btf, atype }
+#define BPF_PROG_SEC_IMPL(string, ptype, eatype, eatype_optional,	    \
+			  attachable, attach_btf)			    \
+	{								    \
+		.sec = string,						    \
+		.len = sizeof(string) - 1,				    \
+		.prog_type = ptype,					    \
+		.expected_attach_type = eatype,				    \
+		.is_exp_attach_type_optional = eatype_optional,		    \
+		.is_attachable = attachable,				    \
+		.is_attach_btf = attach_btf,				    \
+	}
 
 /* Programs that can NOT be attached. */
 #define BPF_PROG_SEC(string, ptype) BPF_PROG_SEC_IMPL(string, ptype, 0, 0, 0, 0)
 
 /* Programs that can be attached. */
 #define BPF_APROG_SEC(string, ptype, atype) \
-	BPF_PROG_SEC_IMPL(string, ptype, 0, 1, 0, atype)
+	BPF_PROG_SEC_IMPL(string, ptype, atype, true, 1, 0)
 
 /* Programs that must specify expected attach type at load time. */
 #define BPF_EAPROG_SEC(string, ptype, eatype) \
-	BPF_PROG_SEC_IMPL(string, ptype, eatype, 1, 0, eatype)
+	BPF_PROG_SEC_IMPL(string, ptype, eatype, false, 1, 0)
 
 /* Programs that use BTF to identify attach point */
 #define BPF_PROG_BTF(string, ptype, eatype) \
-	BPF_PROG_SEC_IMPL(string, ptype, eatype, 0, 1, 0)
+	BPF_PROG_SEC_IMPL(string, ptype, eatype, false, 0, 1)
 
 /* Programs that can be attached but attach type can't be identified by section
  * name. Kept for backward compatibility.
@@ -6253,11 +6313,6 @@ void bpf_program__set_expected_attach_type(struct bpf_program *prog,
 	__VA_ARGS__							    \
 }
 
-struct bpf_sec_def;
-
-typedef struct bpf_link *(*attach_fn_t)(const struct bpf_sec_def *sec,
-					struct bpf_program *prog);
-
 static struct bpf_link *attach_kprobe(const struct bpf_sec_def *sec,
 				      struct bpf_program *prog);
 static struct bpf_link *attach_tp(const struct bpf_sec_def *sec,
@@ -6269,17 +6324,6 @@ static struct bpf_link *attach_trace(const struct bpf_sec_def *sec,
 static struct bpf_link *attach_lsm(const struct bpf_sec_def *sec,
 				   struct bpf_program *prog);
 
-struct bpf_sec_def {
-	const char *sec;
-	size_t len;
-	enum bpf_prog_type prog_type;
-	enum bpf_attach_type expected_attach_type;
-	bool is_attachable;
-	bool is_attach_btf;
-	enum bpf_attach_type attach_type;
-	attach_fn_t attach_fn;
-};
-
 static const struct bpf_sec_def section_defs[] = {
 	BPF_PROG_SEC("socket",			BPF_PROG_TYPE_SOCKET_FILTER),
 	BPF_PROG_SEC("sk_reuseport",		BPF_PROG_TYPE_SK_REUSEPORT),
@@ -6713,7 +6757,7 @@ int libbpf_attach_type_by_name(const char *name,
 			continue;
 		if (!section_defs[i].is_attachable)
 			return -EINVAL;
-		*attach_type = section_defs[i].attach_type;
+		*attach_type = section_defs[i].expected_attach_type;
 		return 0;
 	}
 	pr_debug("failed to guess attach type based on ELF section name '%s'\n", name);
@@ -7542,7 +7586,6 @@ static struct bpf_link *attach_lsm(const struct bpf_sec_def *sec,
 struct bpf_link *
 bpf_program__attach_cgroup(struct bpf_program *prog, int cgroup_fd)
 {
-	const struct bpf_sec_def *sec_def;
 	enum bpf_attach_type attach_type;
 	char errmsg[STRERR_BUFSIZE];
 	struct bpf_link *link;
@@ -7561,11 +7604,6 @@ bpf_program__attach_cgroup(struct bpf_program *prog, int cgroup_fd)
 	link->detach = &bpf_link__detach_fd;
 
 	attach_type = bpf_program__get_expected_attach_type(prog);
-	if (!attach_type) {
-		sec_def = find_sec_def(bpf_program__title(prog, false));
-		if (sec_def)
-			attach_type = sec_def->attach_type;
-	}
 	link_fd = bpf_link_create(prog_fd, cgroup_fd, attach_type, NULL);
 	if (link_fd < 0) {
 		link_fd = -errno;
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index 44df1d3e7287..f1dacecb1619 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -458,7 +458,7 @@ struct xdp_link_info {
 
 struct bpf_xdp_set_link_opts {
 	size_t sz;
-	__u32 old_fd;
+	int old_fd;
 };
 #define bpf_xdp_set_link_opts__last_field old_fd
 
diff --git a/tools/lib/bpf/netlink.c b/tools/lib/bpf/netlink.c
index 18b5319025e1..0b709fd10bba 100644
--- a/tools/lib/bpf/netlink.c
+++ b/tools/lib/bpf/netlink.c
@@ -142,7 +142,7 @@ static int __bpf_set_link_xdp_fd_replace(int ifindex, int fd, int old_fd,
 		struct ifinfomsg ifinfo;
 		char             attrbuf[64];
 	} req;
-	__u32 nl_pid;
+	__u32 nl_pid = 0;
 
 	sock = libbpf_netlink_open(&nl_pid);
 	if (sock < 0)
@@ -288,7 +288,7 @@ int bpf_get_link_xdp_info(int ifindex, struct xdp_link_info *info,
 {
 	struct xdp_id_md xdp_id = {};
 	int sock, ret;
-	__u32 nl_pid;
+	__u32 nl_pid = 0;
 	__u32 mask;
 
 	if (flags & ~XDP_FLAGS_MASK || !info_size)
@@ -321,7 +321,7 @@ int bpf_get_link_xdp_info(int ifindex, struct xdp_link_info *info,
 
 static __u32 get_xdp_id(struct xdp_link_info *info, __u32 flags)
 {
-	if (info->attach_mode != XDP_ATTACHED_MULTI)
+	if (info->attach_mode != XDP_ATTACHED_MULTI && !flags)
 		return info->prog_id;
 	if (flags & XDP_FLAGS_DRV_MODE)
 		return info->drv_prog_id;
diff --git a/tools/memory-model/Documentation/explanation.txt b/tools/memory-model/Documentation/explanation.txt
index e91a2eb19592..993f800659c6 100644
--- a/tools/memory-model/Documentation/explanation.txt
+++ b/tools/memory-model/Documentation/explanation.txt
@@ -1987,28 +1987,36 @@ outcome undefined.
 
 In technical terms, the compiler is allowed to assume that when the
 program executes, there will not be any data races.  A "data race"
-occurs when two conflicting memory accesses execute concurrently;
-two memory accesses "conflict" if:
+occurs when there are two memory accesses such that:
 
-	they access the same location,
+1.	they access the same location,
 
-	they occur on different CPUs (or in different threads on the
-	same CPU),
+2.	at least one of them is a store,
 
-	at least one of them is a plain access,
+3.	at least one of them is plain,
 
-	and at least one of them is a store.
+4.	they occur on different CPUs (or in different threads on the
+	same CPU), and
 
-The LKMM tries to determine whether a program contains two conflicting
-accesses which may execute concurrently; if it does then the LKMM says
-there is a potential data race and makes no predictions about the
-program's outcome.
+5.	they execute concurrently.
 
-Determining whether two accesses conflict is easy; you can see that
-all the concepts involved in the definition above are already part of
-the memory model.  The hard part is telling whether they may execute
-concurrently.  The LKMM takes a conservative attitude, assuming that
-accesses may be concurrent unless it can prove they cannot.
+In the literature, two accesses are said to "conflict" if they satisfy
+1 and 2 above.  We'll go a little farther and say that two accesses
+are "race candidates" if they satisfy 1 - 4.  Thus, whether or not two
+race candidates actually do race in a given execution depends on
+whether they are concurrent.
+
+The LKMM tries to determine whether a program contains race candidates
+which may execute concurrently; if it does then the LKMM says there is
+a potential data race and makes no predictions about the program's
+outcome.
+
+Determining whether two accesses are race candidates is easy; you can
+see that all the concepts involved in the definition above are already
+part of the memory model.  The hard part is telling whether they may
+execute concurrently.  The LKMM takes a conservative attitude,
+assuming that accesses may be concurrent unless it can prove they
+are not.
 
 If two memory accesses aren't concurrent then one must execute before
 the other.  Therefore the LKMM decides two accesses aren't concurrent
@@ -2171,8 +2179,8 @@ again, now using plain accesses for buf:
 	}
 
 This program does not contain a data race.  Although the U and V
-accesses conflict, the LKMM can prove they are not concurrent as
-follows:
+accesses are race candidates, the LKMM can prove they are not
+concurrent as follows:
 
 	The smp_wmb() fence in P0 is both a compiler barrier and a
 	cumul-fence.  It guarantees that no matter what hash of
@@ -2326,12 +2334,11 @@ could now perform the load of x before the load of ptr (there might be
 a control dependency but no address dependency at the machine level).
 
 Finally, it turns out there is a situation in which a plain write does
-not need to be w-post-bounded: when it is separated from the
-conflicting access by a fence.  At first glance this may seem
-impossible.  After all, to be conflicting the second access has to be
-on a different CPU from the first, and fences don't link events on
-different CPUs.  Well, normal fences don't -- but rcu-fence can!
-Here's an example:
+not need to be w-post-bounded: when it is separated from the other
+race-candidate access by a fence.  At first glance this may seem
+impossible.  After all, to be race candidates the two accesses must
+be on different CPUs, and fences don't link events on different CPUs.
+Well, normal fences don't -- but rcu-fence can!  Here's an example:
 
 	int x, y;
 
@@ -2367,7 +2374,7 @@ concurrent and there is no race, even though P1's plain store to y
 isn't w-post-bounded by any marked accesses.
 
 Putting all this material together yields the following picture.  For
-two conflicting stores W and W', where W ->co W', the LKMM says the
+race-candidate stores W and W', where W ->co W', the LKMM says the
 stores don't race if W can be linked to W' by a
 
 	w-post-bounded ; vis ; w-pre-bounded
@@ -2380,8 +2387,8 @@ sequence, and if W' is plain then they also have to be linked by a
 
 	w-post-bounded ; vis ; r-pre-bounded
 
-sequence.  For a conflicting load R and store W, the LKMM says the two
-accesses don't race if R can be linked to W by an
+sequence.  For race-candidate load R and store W, the LKMM says the
+two accesses don't race if R can be linked to W by an
 
 	r-post-bounded ; xb* ; w-pre-bounded
 
@@ -2413,20 +2420,20 @@ is, the rules governing the memory subsystem's choice of a store to
 satisfy a load request and its determination of where a store will
 fall in the coherence order):
 
-	If R and W conflict and it is possible to link R to W by one
-	of the xb* sequences listed above, then W ->rfe R is not
-	allowed (i.e., a load cannot read from a store that it
+	If R and W are race candidates and it is possible to link R to
+	W by one of the xb* sequences listed above, then W ->rfe R is
+	not allowed (i.e., a load cannot read from a store that it
 	executes before, even if one or both is plain).
 
-	If W and R conflict and it is possible to link W to R by one
-	of the vis sequences listed above, then R ->fre W is not
-	allowed (i.e., if a store is visible to a load then the load
-	must read from that store or one coherence-after it).
+	If W and R are race candidates and it is possible to link W to
+	R by one of the vis sequences listed above, then R ->fre W is
+	not allowed (i.e., if a store is visible to a load then the
+	load must read from that store or one coherence-after it).
 
-	If W and W' conflict and it is possible to link W to W' by one
-	of the vis sequences listed above, then W' ->co W is not
-	allowed (i.e., if one store is visible to a second then the
-	second must come after the first in the coherence order).
+	If W and W' are race candidates and it is possible to link W
+	to W' by one of the vis sequences listed above, then W' ->co W
+	is not allowed (i.e., if one store is visible to a second then
+	the second must come after the first in the coherence order).
 
 This is the extent to which the LKMM deals with plain accesses.
 Perhaps it could say more (for example, plain accesses might
diff --git a/tools/memory-model/Documentation/references.txt b/tools/memory-model/Documentation/references.txt
index b177f3e4a614..ecbbaa5396d4 100644
--- a/tools/memory-model/Documentation/references.txt
+++ b/tools/memory-model/Documentation/references.txt
@@ -73,6 +73,18 @@ o	Christopher Pulte, Shaked Flur, Will Deacon, Jon French,
 Linux-kernel memory model
 =========================
 
+o	Jade Alglave, Will Deacon, Boqun Feng, David Howells, Daniel
+	Lustig, Luc Maranget, Paul E. McKenney, Andrea Parri, Nicholas
+	Piggin, Alan Stern, Akira Yokosawa, and Peter Zijlstra.
+	2019. "Calibrating your fear of big bad optimizing compilers"
+	Linux Weekly News.  https://lwn.net/Articles/799218/
+
+o	Jade Alglave, Will Deacon, Boqun Feng, David Howells, Daniel
+	Lustig, Luc Maranget, Paul E. McKenney, Andrea Parri, Nicholas
+	Piggin, Alan Stern, Akira Yokosawa, and Peter Zijlstra.
+	2019. "Who's afraid of a big bad optimizing compiler?"
+	Linux Weekly News.  https://lwn.net/Articles/793253/
+
 o	Jade Alglave, Luc Maranget, Paul E. McKenney, Andrea Parri, and
 	Alan Stern.  2018. "Frightening small children and disconcerting
 	grown-ups: Concurrency in the Linux kernel". In Proceedings of
@@ -88,6 +100,11 @@ o	Jade Alglave, Luc Maranget, Paul E. McKenney, Andrea Parri, and
 	Alan Stern.  2017.  "A formal kernel memory-ordering model (part 2)"
 	Linux Weekly News.  https://lwn.net/Articles/720550/
 
+o	Jade Alglave, Luc Maranget, Paul E. McKenney, Andrea Parri, and
+	Alan Stern.  2017-2019.  "A Formal Model of Linux-Kernel Memory
+	Ordering" (backup material for the LWN articles)
+	https://mirrors.edge.kernel.org/pub/linux/kernel/people/paulmck/LWNLinuxMM/
+
 
 Memory-model tooling
 ====================
@@ -110,5 +127,5 @@ Memory-model comparisons
 ========================
 
 o	Paul E. McKenney, Ulrich Weigand, Andrea Parri, and Boqun
-	Feng. 2016. "Linux-Kernel Memory Model". (6 June 2016).
-	http://open-std.org/JTC1/SC22/WG21/docs/papers/2016/p0124r2.html.
+	Feng. 2018. "Linux-Kernel Memory Model". (27 September 2018).
+	http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0124r6.html.
diff --git a/tools/memory-model/README b/tools/memory-model/README
index fc07b52f2028..b9c562e92981 100644
--- a/tools/memory-model/README
+++ b/tools/memory-model/README
@@ -207,11 +207,15 @@ The Linux-kernel memory model (LKMM) has the following limitations:
 		case as a store release.
 
 	b.	The "unless" RMW operations are not currently modeled:
-		atomic_long_add_unless(), atomic_add_unless(),
-		atomic_inc_unless_negative(), and
-		atomic_dec_unless_positive().  These can be emulated
+		atomic_long_add_unless(), atomic_inc_unless_negative(),
+		and atomic_dec_unless_positive().  These can be emulated
 		in litmus tests, for example, by using atomic_cmpxchg().
 
+		One exception of this limitation is atomic_add_unless(),
+		which is provided directly by herd7 (so no corresponding
+		definition in linux-kernel.def).  atomic_add_unless() is
+		modeled by herd7 therefore it can be used in litmus tests.
+
 	c.	The call_rcu() function is not modeled.  It can be
 		emulated in litmus tests by adding another process that
 		invokes synchronize_rcu() and the body of the callback
diff --git a/tools/memory-model/litmus-tests/.gitignore b/tools/memory-model/litmus-tests/.gitignore
index c492a1ddad91..19c379cf069d 100644
--- a/tools/memory-model/litmus-tests/.gitignore
+++ b/tools/memory-model/litmus-tests/.gitignore
@@ -1,2 +1,2 @@
 # SPDX-License-Identifier: GPL-2.0-only
-*.litmus.out
+*.litmus.*
diff --git a/tools/memory-model/litmus-tests/MP+onceassign+derefonce.litmus b/tools/memory-model/litmus-tests/MP+onceassign+derefonce.litmus
deleted file mode 100644
index 97731b4bbdd8..000000000000
--- a/tools/memory-model/litmus-tests/MP+onceassign+derefonce.litmus
+++ /dev/null
@@ -1,34 +0,0 @@
-C MP+onceassign+derefonce
-
-(*
- * Result: Never
- *
- * This litmus test demonstrates that rcu_assign_pointer() and
- * rcu_dereference() suffice to ensure that an RCU reader will not see
- * pre-initialization garbage when it traverses an RCU-protected data
- * structure containing a newly inserted element.
- *)
-
-{
-y=z;
-z=0;
-}
-
-P0(int *x, int **y)
-{
-	WRITE_ONCE(*x, 1);
-	rcu_assign_pointer(*y, x);
-}
-
-P1(int *x, int **y)
-{
-	int *r0;
-	int r1;
-
-	rcu_read_lock();
-	r0 = rcu_dereference(*y);
-	r1 = READ_ONCE(*r0);
-	rcu_read_unlock();
-}
-
-exists (1:r0=x /\ 1:r1=0)
diff --git a/tools/memory-model/litmus-tests/README b/tools/memory-model/litmus-tests/README
index 681f9067fa9e..79e1b1ed4929 100644
--- a/tools/memory-model/litmus-tests/README
+++ b/tools/memory-model/litmus-tests/README
@@ -63,9 +63,6 @@ LB+poonceonces.litmus
 	As above, but with store-release replaced with WRITE_ONCE()
 	and load-acquire replaced with READ_ONCE().
 
-MP+onceassign+derefonce.litmus
-	As below, but with rcu_assign_pointer() and an rcu_dereference().
-
 MP+polockmbonce+poacquiresilsil.litmus
 	Protect the access with a lock and an smp_mb__after_spinlock()
 	in one process, and use an acquire load followed by a pair of
diff --git a/tools/memory-model/scripts/README b/tools/memory-model/scripts/README
index 095c7eb36f9f..cc2c4e5be9ec 100644
--- a/tools/memory-model/scripts/README
+++ b/tools/memory-model/scripts/README
@@ -27,6 +27,14 @@ checklitmushist.sh
 checklitmus.sh
 
 	Check a single litmus test against its "Result:" expected result.
+	Not intended to for manual use.
+
+checktheselitmus.sh
+
+	Check the specified list of litmus tests against their "Result:"
+	expected results.  This takes optional parseargs.sh arguments,
+	followed by "--" followed by pathnames starting from the current
+	directory.
 
 cmplitmushist.sh
 
@@ -43,10 +51,10 @@ initlitmushist.sh
 
 judgelitmus.sh
 
-	Given a .litmus file and its .litmus.out herd7 output, check the
-	.litmus.out file against the .litmus file's "Result:" comment to
-	judge whether the test ran correctly.  Not normally run manually,
-	provided instead for use by other scripts.
+	Given a .litmus file and its herd7 output, check the output file
+	against the .litmus file's "Result:" comment to judge whether
+	the test ran correctly.  Not normally run manually, provided
+	instead for use by other scripts.
 
 newlitmushist.sh
 
diff --git a/tools/memory-model/scripts/checkalllitmus.sh b/tools/memory-model/scripts/checkalllitmus.sh
index 3c0c7fbbd223..2d3ee850a839 100755
--- a/tools/memory-model/scripts/checkalllitmus.sh
+++ b/tools/memory-model/scripts/checkalllitmus.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 # SPDX-License-Identifier: GPL-2.0+
 #
 # Run herd7 tests on all .litmus files in the litmus-tests directory
@@ -8,6 +8,11 @@
 # "^^^".  It also outputs verification results to a file whose name is
 # that of the specified litmus test, but with ".out" appended.
 #
+# If the --hw argument is specified, this script translates the .litmus
+# C-language file to the specified type of assembly and verifies that.
+# But in this case, litmus tests using complex synchronization (such as
+# locking, RCU, and SRCU) are cheerfully ignored.
+#
 # Usage:
 #	checkalllitmus.sh
 #
@@ -17,7 +22,7 @@
 #
 # Copyright IBM Corporation, 2018
 #
-# Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+# Author: Paul E. McKenney <paulmck@linux.ibm.com>
 
 . scripts/parseargs.sh
 
@@ -30,29 +35,23 @@ else
 	exit 255
 fi
 
-# Create any new directories that have appeared in the github litmus
-# repo since the last run.
+# Create any new directories that have appeared in the litmus-tests
+# directory since the last run.
 if test "$LKMM_DESTDIR" != "."
 then
 	find $litmusdir -type d -print |
 	( cd "$LKMM_DESTDIR"; sed -e 's/^/mkdir -p /' | sh )
 fi
 
-# Find the checklitmus script.  If it is not where we expect it, then
-# assume that the caller has the PATH environment variable set
-# appropriately.
-if test -x scripts/checklitmus.sh
-then
-	clscript=scripts/checklitmus.sh
-else
-	clscript=checklitmus.sh
-fi
-
 # Run the script on all the litmus tests in the specified directory
 ret=0
 for i in $litmusdir/*.litmus
 do
-	if ! $clscript $i
+	if test -n "$LKMM_HW_MAP_FILE" && ! scripts/simpletest.sh $i
+	then
+		continue
+	fi
+	if ! scripts/checklitmus.sh $i
 	then
 		ret=1
 	fi
diff --git a/tools/memory-model/scripts/checkghlitmus.sh b/tools/memory-model/scripts/checkghlitmus.sh
index 6589fbb6f653..cedd0290b73f 100755
--- a/tools/memory-model/scripts/checkghlitmus.sh
+++ b/tools/memory-model/scripts/checkghlitmus.sh
@@ -10,6 +10,7 @@
 # parseargs.sh scripts for arguments.
 
 . scripts/parseargs.sh
+. scripts/hwfnseg.sh
 
 T=/tmp/checkghlitmus.sh.$$
 trap 'rm -rf $T' 0
@@ -32,19 +33,19 @@ then
 	( cd "$LKMM_DESTDIR"; sed -e 's/^/mkdir -p /' | sh )
 fi
 
-# Create a list of the C-language litmus tests previously run.
-( cd $LKMM_DESTDIR; find litmus -name '*.litmus.out' -print ) |
-	sed -e 's/\.out$//' |
+# Create a list of the specified litmus tests previously run.
+( cd $LKMM_DESTDIR; find litmus -name "*.litmus${hwfnseg}.out" -print ) |
+	sed -e "s/${hwfnseg}"'\.out$//' |
 	xargs -r egrep -l '^ \* Result: (Never|Sometimes|Always|DEADLOCK)' |
 	xargs -r grep -L "^P${LKMM_PROCS}"> $T/list-C-already
 
 # Create a list of C-language litmus tests with "Result:" commands and
 # no more than the specified number of processes.
-find litmus -name '*.litmus' -exec grep -l -m 1 "^C " {} \; > $T/list-C
+find litmus -name '*.litmus' -print | mselect7 -arch C > $T/list-C
 xargs < $T/list-C -r egrep -l '^ \* Result: (Never|Sometimes|Always|DEADLOCK)' > $T/list-C-result
 xargs < $T/list-C-result -r grep -L "^P${LKMM_PROCS}" > $T/list-C-result-short
 
-# Form list of tests without corresponding .litmus.out files
+# Form list of tests without corresponding .out files
 sort $T/list-C-already $T/list-C-result-short | uniq -u > $T/list-C-needed
 
 # Run any needed tests.
diff --git a/tools/memory-model/scripts/checklitmus.sh b/tools/memory-model/scripts/checklitmus.sh
index 11461ed40b5e..4c1d0cf0ddad 100755
--- a/tools/memory-model/scripts/checklitmus.sh
+++ b/tools/memory-model/scripts/checklitmus.sh
@@ -1,10 +1,8 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0+
 #
-# Run a herd7 test and invokes judgelitmus.sh to check the result against
-# a "Result:" comment within the litmus test.  It also outputs verification
-# results to a file whose name is that of the specified litmus test, but
-# with ".out" appended.
+# Invokes runlitmus.sh and judgelitmus.sh on its arguments to run the
+# specified litmus test and pass judgment on the results.
 #
 # Usage:
 #	checklitmus.sh file.litmus
@@ -15,20 +13,7 @@
 #
 # Copyright IBM Corporation, 2018
 #
-# Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+# Author: Paul E. McKenney <paulmck@linux.ibm.com>
 
-litmus=$1
-herdoptions=${LKMM_HERD_OPTIONS--conf linux-kernel.cfg}
-
-if test -f "$litmus" -a -r "$litmus"
-then
-	:
-else
-	echo ' --- ' error: \"$litmus\" is not a readable file
-	exit 255
-fi
-
-echo Herd options: $herdoptions > $LKMM_DESTDIR/$litmus.out
-/usr/bin/time $LKMM_TIMEOUT_CMD herd7 $herdoptions $litmus >> $LKMM_DESTDIR/$litmus.out 2>&1
-
-scripts/judgelitmus.sh $litmus
+scripts/runlitmus.sh $1
+scripts/judgelitmus.sh $1
diff --git a/tools/memory-model/scripts/checklitmushist.sh b/tools/memory-model/scripts/checklitmushist.sh
index 1d210ffb7c8a..406ecfc0aee4 100755
--- a/tools/memory-model/scripts/checklitmushist.sh
+++ b/tools/memory-model/scripts/checklitmushist.sh
@@ -12,7 +12,7 @@
 #
 # Copyright IBM Corporation, 2018
 #
-# Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+# Author: Paul E. McKenney <paulmck@linux.ibm.com>
 
 . scripts/parseargs.sh
 
diff --git a/tools/memory-model/scripts/checktheselitmus.sh b/tools/memory-model/scripts/checktheselitmus.sh
new file mode 100755
index 000000000000..10eeb5ecea6d
--- /dev/null
+++ b/tools/memory-model/scripts/checktheselitmus.sh
@@ -0,0 +1,43 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Invokes checklitmus.sh on its arguments to run the specified litmus
+# test and pass judgment on the results.
+#
+# Usage:
+#	checktheselitmus.sh -- [ file1.litmus [ file2.litmus ... ] ]
+#
+# Run this in the directory containing the memory model, specifying the
+# pathname of the litmus test to check.  The usual parseargs.sh arguments
+# can be specified prior to the "--".
+#
+# This script is intended for use with pathnames that start from the
+# tools/memory-model directory.  If some of the pathnames instead start at
+# the root directory, they all must do so and the "--destdir /" parseargs.sh
+# argument must be specified prior to the "--".  Alternatively, some other
+# "--destdir" argument can be supplied as long as the needed subdirectories
+# are populated.
+#
+# Copyright IBM Corporation, 2018
+#
+# Author: Paul E. McKenney <paulmck@linux.ibm.com>
+
+. scripts/parseargs.sh
+
+ret=0
+for i in "$@"
+do
+	if scripts/checklitmus.sh $i
+	then
+		:
+	else
+		ret=1
+	fi
+done
+if test "$ret" -ne 0
+then
+	echo " ^^^ VERIFICATION MISMATCHES" 1>&2
+else
+	echo All litmus tests verified as was expected. 1>&2
+fi
+exit $ret
diff --git a/tools/memory-model/scripts/cmplitmushist.sh b/tools/memory-model/scripts/cmplitmushist.sh
index 0f498aeeccf5..ca1ac8b64614 100755
--- a/tools/memory-model/scripts/cmplitmushist.sh
+++ b/tools/memory-model/scripts/cmplitmushist.sh
@@ -12,12 +12,49 @@ trap 'rm -rf $T' 0
 mkdir $T
 
 # comparetest oldpath newpath
+badmacnam=0
+timedout=0
 perfect=0
 obsline=0
 noobsline=0
 obsresult=0
 badcompare=0
 comparetest () {
+	if grep -q ': Unknown macro ' $1 || grep -q ': Unknown macro ' $2
+	then
+		if grep -q ': Unknown macro ' $1
+		then
+			badname=`grep ': Unknown macro ' $1 |
+				sed -e 's/^.*: Unknown macro //' |
+				sed -e 's/ (User error).*$//'`
+			echo 'Current LKMM version does not know "'$badname'"' $1
+		fi
+		if grep -q ': Unknown macro ' $2
+		then
+			badname=`grep ': Unknown macro ' $2 |
+				sed -e 's/^.*: Unknown macro //' |
+				sed -e 's/ (User error).*$//'`
+			echo 'Current LKMM version does not know "'$badname'"' $2
+		fi
+		badmacnam=`expr "$badmacnam" + 1`
+		return 0
+	elif grep -q '^Command exited with non-zero status 124' $1 ||
+	     grep -q '^Command exited with non-zero status 124' $2
+	then
+		if grep -q '^Command exited with non-zero status 124' $1 &&
+		   grep -q '^Command exited with non-zero status 124' $2
+		then
+			echo Both runs timed out: $2
+		elif grep -q '^Command exited with non-zero status 124' $1
+		then
+			echo Old run timed out: $2
+		elif grep -q '^Command exited with non-zero status 124' $2
+		then
+			echo New run timed out: $2
+		fi
+		timedout=`expr "$timedout" + 1`
+		return 0
+	fi
 	grep -v 'maxresident)k\|minor)pagefaults\|^Time' $1 > $T/oldout
 	grep -v 'maxresident)k\|minor)pagefaults\|^Time' $2 > $T/newout
 	if cmp -s $T/oldout $T/newout && grep -q '^Observation' $1
@@ -38,7 +75,7 @@ comparetest () {
 			return 0
 		fi
 	else
-		echo Missing Observation line "(e.g., herd7 timeout)": $2
+		echo Missing Observation line "(e.g., syntax error)": $2
 		noobsline=`expr "$noobsline" + 1`
 		return 0
 	fi
@@ -72,12 +109,20 @@ then
 fi
 if test "$noobsline" -ne 0
 then
-	echo Missing Observation line "(e.g., herd7 timeout)": $noobsline 1>&2
+	echo Missing Observation line "(e.g., syntax error)": $noobsline 1>&2
 fi
 if test "$obsresult" -ne 0
 then
 	echo Matching Observation Always/Sometimes/Never result: $obsresult 1>&2
 fi
+if test "$timedout" -ne 0
+then
+	echo "!!!" Timed out: $timedout 1>&2
+fi
+if test "$badmacnam" -ne 0
+then
+	echo "!!!" Unknown primitive: $badmacnam 1>&2
+fi
 if test "$badcompare" -ne 0
 then
 	echo "!!!" Result changed: $badcompare 1>&2
diff --git a/tools/memory-model/scripts/hwfnseg.sh b/tools/memory-model/scripts/hwfnseg.sh
new file mode 100755
index 000000000000..580c3281181c
--- /dev/null
+++ b/tools/memory-model/scripts/hwfnseg.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Generate the hardware extension to the litmus-test filename, or the
+# empty string if this is an LKMM run.  The extension is placed in
+# the shell variable hwfnseg.
+#
+# Usage:
+#	. hwfnseg.sh
+#
+# Copyright IBM Corporation, 2019
+#
+# Author: Paul E. McKenney <paulmck@linux.ibm.com>
+
+if test -z "$LKMM_HW_MAP_FILE"
+then
+	hwfnseg=
+else
+	hwfnseg=".$LKMM_HW_MAP_FILE"
+fi
diff --git a/tools/memory-model/scripts/initlitmushist.sh b/tools/memory-model/scripts/initlitmushist.sh
index 956b6957484d..31ea782955d3 100755
--- a/tools/memory-model/scripts/initlitmushist.sh
+++ b/tools/memory-model/scripts/initlitmushist.sh
@@ -60,7 +60,7 @@ fi
 
 # Create a list of the C-language litmus tests with no more than the
 # specified number of processes (per the --procs argument).
-find litmus -name '*.litmus' -exec grep -l -m 1 "^C " {} \; > $T/list-C
+find litmus -name '*.litmus' -print | mselect7 -arch C > $T/list-C
 xargs < $T/list-C -r grep -L "^P${LKMM_PROCS}" > $T/list-C-short
 
 scripts/runlitmushist.sh < $T/list-C-short
diff --git a/tools/memory-model/scripts/judgelitmus.sh b/tools/memory-model/scripts/judgelitmus.sh
index 0cc63875e395..1ec5d89fcfbb 100755
--- a/tools/memory-model/scripts/judgelitmus.sh
+++ b/tools/memory-model/scripts/judgelitmus.sh
@@ -1,9 +1,22 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0+
 #
-# Given a .litmus test and the corresponding .litmus.out file, check
-# the .litmus.out file against the "Result:" comment to judge whether
-# the test ran correctly.
+# Given a .litmus test and the corresponding litmus output file, check
+# the .litmus.out file against the "Result:" comment to judge whether the
+# test ran correctly.  If the --hw argument is omitted, check against the
+# LKMM output, which is assumed to be in file.litmus.out. If either a
+# "DATARACE" marker in the "Result:" comment or a "Flag data-race" marker
+# in the LKMM output is present, the other must also be as well, at least
+# for litmus tests having a "Result:" comment. In this case, a failure of
+# the Always/Sometimes/Never portion of the "Result:" prediction will be
+# noted, but forgiven.
+#
+# If the --hw argument is provided, this is assumed to be a hardware
+# test, and the output is assumed to be in file.litmus.HW.out, where
+# "HW" is the --hw argument. In addition, non-Sometimes verification
+# results will be noted, but forgiven.  Furthermore, if there is no
+# "Result:" comment but there is an LKMM .litmus.out file, the observation
+# in that file will be used to judge the assembly-language verification.
 #
 # Usage:
 #	judgelitmus.sh file.litmus
@@ -13,7 +26,7 @@
 #
 # Copyright IBM Corporation, 2018
 #
-# Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+# Author: Paul E. McKenney <paulmck@linux.ibm.com>
 
 litmus=$1
 
@@ -24,55 +37,120 @@ else
 	echo ' --- ' error: \"$litmus\" is not a readable file
 	exit 255
 fi
-if test -f "$LKMM_DESTDIR/$litmus".out -a -r "$LKMM_DESTDIR/$litmus".out
+if test -z "$LKMM_HW_MAP_FILE"
+then
+	litmusout=$litmus.out
+	lkmmout=
+else
+	litmusout="`echo $litmus |
+		sed -e 's/\.litmus$/.litmus.'${LKMM_HW_MAP_FILE}'/'`.out"
+	lkmmout=$litmus.out
+fi
+if test -f "$LKMM_DESTDIR/$litmusout" -a -r "$LKMM_DESTDIR/$litmusout"
 then
 	:
 else
-	echo ' --- ' error: \"$LKMM_DESTDIR/$litmus\".out is not a readable file
+	echo ' --- ' error: \"$LKMM_DESTDIR/$litmusout is not a readable file
 	exit 255
 fi
-if grep -q '^ \* Result: ' $litmus
+if grep -q '^Flag data-race$' "$LKMM_DESTDIR/$litmusout"
+then
+	datarace_modeled=1
+fi
+if grep -q '^[( ]\* Result: ' $litmus
+then
+	outcome=`grep -m 1 '^[( ]\* Result: ' $litmus | awk '{ print $3 }'`
+	if grep -m1 '^[( ]\* Result: .* DATARACE' $litmus
+	then
+		datarace_predicted=1
+	fi
+	if test -n "$datarace_predicted" -a -z "$datarace_modeled" -a -z "$LKMM_HW_MAP_FILE"
+	then
+		echo '!!! Predicted data race not modeled' $litmus
+		exit 252
+	elif test -z "$datarace_predicted" -a -n "$datarace_modeled"
+	then
+		# Note that hardware models currently don't model data races
+		echo '!!! Unexpected data race modeled' $litmus
+		exit 253
+	fi
+elif test -n "$LKMM_HW_MAP_FILE" && grep -q '^Observation' $LKMM_DESTDIR/$lkmmout > /dev/null 2>&1
 then
-	outcome=`grep -m 1 '^ \* Result: ' $litmus | awk '{ print $3 }'`
+	outcome=`grep -m 1 '^Observation ' $LKMM_DESTDIR/$lkmmout | awk '{ print $3 }'`
 else
 	outcome=specified
 fi
 
-grep '^Observation' $LKMM_DESTDIR/$litmus.out
-if grep -q '^Observation' $LKMM_DESTDIR/$litmus.out
+grep '^Observation' $LKMM_DESTDIR/$litmusout
+if grep -q '^Observation' $LKMM_DESTDIR/$litmusout
 then
 	:
+elif grep ': Unknown macro ' $LKMM_DESTDIR/$litmusout
+then
+	badname=`grep ': Unknown macro ' $LKMM_DESTDIR/$litmusout |
+		sed -e 's/^.*: Unknown macro //' |
+		sed -e 's/ (User error).*$//'`
+	badmsg=' !!! Current LKMM version does not know "'$badname'"'" $litmus"
+	echo $badmsg
+	if ! grep -q '!!!' $LKMM_DESTDIR/$litmusout
+	then
+		echo ' !!! '$badmsg >> $LKMM_DESTDIR/$litmusout 2>&1
+	fi
+	exit 254
+elif grep '^Command exited with non-zero status 124' $LKMM_DESTDIR/$litmusout
+then
+	echo ' !!! Timeout' $litmus
+	if ! grep -q '!!!' $LKMM_DESTDIR/$litmusout
+	then
+		echo ' !!! Timeout' >> $LKMM_DESTDIR/$litmusout 2>&1
+	fi
+	exit 124
 else
 	echo ' !!! Verification error' $litmus
-	if ! grep -q '!!!' $LKMM_DESTDIR/$litmus.out
+	if ! grep -q '!!!' $LKMM_DESTDIR/$litmusout
 	then
-		echo ' !!! Verification error' >> $LKMM_DESTDIR/$litmus.out 2>&1
+		echo ' !!! Verification error' >> $LKMM_DESTDIR/$litmusout 2>&1
 	fi
 	exit 255
 fi
 if test "$outcome" = DEADLOCK
 then
-	if grep '^Observation' $LKMM_DESTDIR/$litmus.out | grep -q 'Never 0 0$'
+	if grep '^Observation' $LKMM_DESTDIR/$litmusout | grep -q 'Never 0 0$'
 	then
 		ret=0
 	else
 		echo " !!! Unexpected non-$outcome verification" $litmus
-		if ! grep -q '!!!' $LKMM_DESTDIR/$litmus.out
+		if ! grep -q '!!!' $LKMM_DESTDIR/$litmusout
 		then
-			echo " !!! Unexpected non-$outcome verification" >> $LKMM_DESTDIR/$litmus.out 2>&1
+			echo " !!! Unexpected non-$outcome verification" >> $LKMM_DESTDIR/$litmusout 2>&1
 		fi
 		ret=1
 	fi
-elif grep '^Observation' $LKMM_DESTDIR/$litmus.out | grep -q $outcome || test "$outcome" = Maybe
+elif grep '^Observation' $LKMM_DESTDIR/$litmusout | grep -q 'Never 0 0$'
+then
+	echo " !!! Unexpected non-$outcome deadlock" $litmus
+	if ! grep -q '!!!' $LKMM_DESTDIR/$litmusout
+	then
+		echo " !!! Unexpected non-$outcome deadlock" $litmus >> $LKMM_DESTDIR/$litmusout 2>&1
+	fi
+	ret=1
+elif grep '^Observation' $LKMM_DESTDIR/$litmusout | grep -q $outcome || test "$outcome" = Maybe
 then
 	ret=0
 else
-	echo " !!! Unexpected non-$outcome verification" $litmus
-	if ! grep -q '!!!' $LKMM_DESTDIR/$litmus.out
+	if test \( -n "$LKMM_HW_MAP_FILE" -a "$outcome" = Sometimes \) -o -n "$datarace_modeled"
 	then
-		echo " !!! Unexpected non-$outcome verification" >> $LKMM_DESTDIR/$litmus.out 2>&1
+		flag="--- Forgiven"
+		ret=0
+	else
+		flag="!!! Unexpected"
+		ret=1
+	fi
+	echo " $flag non-$outcome verification" $litmus
+	if ! grep -qe "$flag" $LKMM_DESTDIR/$litmusout
+	then
+		echo " $flag non-$outcome verification" >> $LKMM_DESTDIR/$litmusout 2>&1
 	fi
-	ret=1
 fi
-tail -2 $LKMM_DESTDIR/$litmus.out | head -1
+tail -2 $LKMM_DESTDIR/$litmusout | head -1
 exit $ret
diff --git a/tools/memory-model/scripts/newlitmushist.sh b/tools/memory-model/scripts/newlitmushist.sh
index 991f8f814881..25235e2049cf 100755
--- a/tools/memory-model/scripts/newlitmushist.sh
+++ b/tools/memory-model/scripts/newlitmushist.sh
@@ -12,7 +12,7 @@
 #
 # Copyright IBM Corporation, 2018
 #
-# Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+# Author: Paul E. McKenney <paulmck@linux.ibm.com>
 
 . scripts/parseargs.sh
 
@@ -43,7 +43,7 @@ fi
 
 # Form full list of litmus tests with no more than the specified
 # number of processes (per the --procs argument).
-find litmus -name '*.litmus' -exec grep -l -m 1 "^C " {} \; > $T/list-C-all
+find litmus -name '*.litmus' -print | mselect7 -arch C > $T/list-C-all
 xargs < $T/list-C-all -r grep -L "^P${LKMM_PROCS}" > $T/list-C-short
 
 # Form list of new tests.  Note: This does not handle litmus-test deletion!
diff --git a/tools/memory-model/scripts/parseargs.sh b/tools/memory-model/scripts/parseargs.sh
index 40f52080fdbd..08ded5909860 100755
--- a/tools/memory-model/scripts/parseargs.sh
+++ b/tools/memory-model/scripts/parseargs.sh
@@ -1,7 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0+
 #
-# the corresponding .litmus.out file, and does not judge the result.
+# Parse arguments common to the various scripts.
 #
 # . scripts/parseargs.sh
 #
@@ -9,7 +9,7 @@
 #
 # Copyright IBM Corporation, 2018
 #
-# Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+# Author: Paul E. McKenney <paulmck@linux.ibm.com>
 
 T=/tmp/parseargs.sh.$$
 mkdir $T
@@ -27,6 +27,7 @@ initparam () {
 
 initparam LKMM_DESTDIR "."
 initparam LKMM_HERD_OPTIONS "-conf linux-kernel.cfg"
+initparam LKMM_HW_MAP_FILE ""
 initparam LKMM_JOBS `getconf _NPROCESSORS_ONLN`
 initparam LKMM_PROCS "3"
 initparam LKMM_TIMEOUT "1m"
@@ -37,10 +38,11 @@ usagehelp () {
 	echo "Usage $scriptname [ arguments ]"
 	echo "      --destdir path (place for .litmus.out, default by .litmus)"
 	echo "      --herdopts -conf linux-kernel.cfg ..."
+	echo "      --hw AArch64"
 	echo "      --jobs N (number of jobs, default one per CPU)"
 	echo "      --procs N (litmus tests with at most this many processes)"
 	echo "      --timeout N (herd7 timeout (e.g., 10s, 1m, 2hr, 1d, '')"
-	echo "Defaults: --destdir '$LKMM_DESTDIR_DEF' --herdopts '$LKMM_HERD_OPTIONS_DEF' --jobs '$LKMM_JOBS_DEF' --procs '$LKMM_PROCS_DEF' --timeout '$LKMM_TIMEOUT_DEF'"
+	echo "Defaults: --destdir '$LKMM_DESTDIR_DEF' --herdopts '$LKMM_HERD_OPTIONS_DEF' --hw '$LKMM_HW_MAP_FILE' --jobs '$LKMM_JOBS_DEF' --procs '$LKMM_PROCS_DEF' --timeout '$LKMM_TIMEOUT_DEF'"
 	exit 1
 }
 
@@ -81,7 +83,7 @@ do
 			echo "Cannot create directory --destdir '$LKMM_DESTDIR'"
 			usage
 		fi
-		if test -d "$LKMM_DESTDIR" -a -w "$LKMM_DESTDIR" -a -x "$LKMM_DESTDIR"
+		if test -d "$LKMM_DESTDIR" -a -x "$LKMM_DESTDIR"
 		then
 			:
 		else
@@ -95,6 +97,11 @@ do
 		LKMM_HERD_OPTIONS="$2"
 		shift
 		;;
+	--hw)
+		checkarg --hw "(.map file architecture name)" "$#" "$2" '^[A-Za-z0-9_-]\+' '^--'
+		LKMM_HW_MAP_FILE="$2"
+		shift
+		;;
 	-j[1-9]*)
 		njobs="`echo $1 | sed -e 's/^-j//'`"
 		trailchars="`echo $njobs | sed -e 's/[0-9]\+\(.*\)$/\1/'`"
@@ -106,7 +113,7 @@ do
 		LKMM_JOBS="`echo $njobs | sed -e 's/^\([0-9]\+\).*$/\1/'`"
 		;;
 	--jobs|--job|-j)
-		checkarg --jobs "(number)" "$#" "$2" '^[1-9][0-9]\+$' '^--'
+		checkarg --jobs "(number)" "$#" "$2" '^[1-9][0-9]*$' '^--'
 		LKMM_JOBS="$2"
 		shift
 		;;
@@ -120,6 +127,10 @@ do
 		LKMM_TIMEOUT="$2"
 		shift
 		;;
+	--)
+		shift
+		break
+		;;
 	*)
 		echo Unknown argument $1
 		usage
diff --git a/tools/memory-model/scripts/runlitmus.sh b/tools/memory-model/scripts/runlitmus.sh
new file mode 100755
index 000000000000..94608d4b6502
--- /dev/null
+++ b/tools/memory-model/scripts/runlitmus.sh
@@ -0,0 +1,80 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Without the -hw argument, runs a herd7 test and outputs verification
+# results to a file whose name is that of the specified litmus test,
+# but with ".out" appended.
+#
+# If the --hw argument is specified, this script translates the .litmus
+# C-language file to the specified type of assembly and verifies that.
+# But in this case, litmus tests using complex synchronization (such as
+# locking, RCU, and SRCU) are cheerfully ignored.
+#
+# Either way, return the status of the herd7 command.
+#
+# Usage:
+#	runlitmus.sh file.litmus
+#
+# Run this in the directory containing the memory model, specifying the
+# pathname of the litmus test to check.  The caller is expected to have
+# properly set up the LKMM environment variables.
+#
+# Copyright IBM Corporation, 2019
+#
+# Author: Paul E. McKenney <paulmck@linux.ibm.com>
+
+litmus=$1
+if test -f "$litmus" -a -r "$litmus"
+then
+	:
+else
+	echo ' !!! ' error: \"$litmus\" is not a readable file
+	exit 255
+fi
+
+if test -z "$LKMM_HW_MAP_FILE" -o ! -e $LKMM_DESTDIR/$litmus.out
+then
+	# LKMM run
+	herdoptions=${LKMM_HERD_OPTIONS--conf linux-kernel.cfg}
+	echo Herd options: $herdoptions > $LKMM_DESTDIR/$litmus.out
+	/usr/bin/time $LKMM_TIMEOUT_CMD herd7 $herdoptions $litmus >> $LKMM_DESTDIR/$litmus.out 2>&1
+	ret=$?
+	if test -z "$LKMM_HW_MAP_FILE"
+	then
+		exit $ret
+	fi
+	echo " --- " Automatically generated LKMM output for '"'--hw $LKMM_HW_MAP_FILE'"' run
+fi
+
+# Hardware run
+
+T=/tmp/checklitmushw.sh.$$
+trap 'rm -rf $T' 0 2
+mkdir $T
+
+# Generate filenames
+mapfile="Linux2${LKMM_HW_MAP_FILE}.map"
+themefile="$T/${LKMM_HW_MAP_FILE}.theme"
+herdoptions="-model $LKMM_HW_CAT_FILE"
+hwlitmus=`echo $litmus | sed -e 's/\.litmus$/.litmus.'${LKMM_HW_MAP_FILE}'/'`
+hwlitmusfile=`echo $hwlitmus | sed -e 's,^.*/,,'`
+
+# Don't run on litmus tests with complex synchronization
+if ! scripts/simpletest.sh $litmus
+then
+	echo ' --- ' error: \"$litmus\" contains locking, RCU, or SRCU
+	exit 254
+fi
+
+# Generate the assembly code and run herd7 on it.
+gen_theme7 -n 10 -map $mapfile -call Linux.call > $themefile
+jingle7 -v -theme $themefile $litmus > $LKMM_DESTDIR/$hwlitmus 2> $T/$hwlitmusfile.jingle7.out
+if grep -q "Generated 0 tests" $T/$hwlitmusfile.jingle7.out
+then
+	echo ' !!! ' jingle7 failed, errors in $hwlitmus.err
+	cp $T/$hwlitmusfile.jingle7.out $LKMM_DESTDIR/$hwlitmus.err
+	exit 253
+fi
+/usr/bin/time $LKMM_TIMEOUT_CMD herd7 -unroll 0 $LKMM_DESTDIR/$hwlitmus > $LKMM_DESTDIR/$hwlitmus.out 2>&1
+
+exit $?
diff --git a/tools/memory-model/scripts/runlitmushist.sh b/tools/memory-model/scripts/runlitmushist.sh
index 6ed376f495bb..c6c2bdc67a50 100755
--- a/tools/memory-model/scripts/runlitmushist.sh
+++ b/tools/memory-model/scripts/runlitmushist.sh
@@ -13,7 +13,9 @@
 #
 # Copyright IBM Corporation, 2018
 #
-# Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+# Author: Paul E. McKenney <paulmck@linux.ibm.com>
+
+. scripts/hwfnseg.sh
 
 T=/tmp/runlitmushist.sh.$$
 trap 'rm -rf $T' 0
@@ -30,15 +32,12 @@ fi
 # Prefixes for per-CPU scripts
 for ((i=0;i<$LKMM_JOBS;i++))
 do
-	echo dir="$LKMM_DESTDIR" > $T/$i.sh
 	echo T=$T >> $T/$i.sh
-	echo herdoptions=\"$LKMM_HERD_OPTIONS\" >> $T/$i.sh
 	cat << '___EOF___' >> $T/$i.sh
 	runtest () {
-		echo ' ... ' /usr/bin/time $LKMM_TIMEOUT_CMD herd7 $herdoptions $1 '>' $dir/$1.out '2>&1'
-		if /usr/bin/time $LKMM_TIMEOUT_CMD herd7 $herdoptions $1 > $dir/$1.out 2>&1
+		if scripts/runlitmus.sh $1
 		then
-			if ! grep -q '^Observation ' $dir/$1.out
+			if ! grep -q '^Observation ' $LKMM_DESTDIR/$1$2.out
 			then
 				echo ' !!! Herd failed, no Observation:' $1
 			fi
@@ -47,10 +46,16 @@ do
 			if test "$exitcode" -eq 124
 			then
 				exitmsg="timed out"
+			elif test "$exitcode" -eq 253
+			then
+				exitmsg=
 			else
 				exitmsg="failed, exit code $exitcode"
 			fi
-			echo ' !!! Herd' ${exitmsg}: $1
+			if test -n "$exitmsg"
+			then
+				echo ' !!! Herd' ${exitmsg}: $1
+			fi
 		fi
 	}
 ___EOF___
@@ -59,11 +64,13 @@ done
 awk -v q="'" -v b='\\' '
 {
 	print "echo `grep " q "^P[0-9]" b "+(" q " " $0 " | tail -1 | sed -e " q "s/^P" b "([0-9]" b "+" b ")(.*$/" b "1/" q "` " $0
-}' | bash |
-sort -k1n |
-awk -v ncpu=$LKMM_JOBS -v t=$T '
+}' | sh | sort -k1n |
+awk -v dq='"' -v hwfnseg="$hwfnseg" -v ncpu="$LKMM_JOBS" -v t="$T" '
 {
-	print "runtest " $2 >> t "/" NR % ncpu ".sh";
+	print "if test -z " dq hwfnseg dq " || scripts/simpletest.sh " dq $2 dq
+	print "then"
+	print "\techo runtest " dq $2 dq " " hwfnseg " >> " t "/" NR % ncpu ".sh";
+	print "fi"
 }
 
 END {
diff --git a/tools/memory-model/scripts/simpletest.sh b/tools/memory-model/scripts/simpletest.sh
new file mode 100755
index 000000000000..7edc5d361665
--- /dev/null
+++ b/tools/memory-model/scripts/simpletest.sh
@@ -0,0 +1,35 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Give zero status if this is a simple test and non-zero otherwise.
+# Simple tests do not contain locking, RCU, or SRCU.
+#
+# Usage:
+#	simpletest.sh file.litmus
+#
+# Copyright IBM Corporation, 2019
+#
+# Author: Paul E. McKenney <paulmck@linux.ibm.com>
+
+
+litmus=$1
+
+if test -f "$litmus" -a -r "$litmus"
+then
+	:
+else
+	echo ' --- ' error: \"$litmus\" is not a readable file
+	exit 255
+fi
+exclude="^[[:space:]]*\("
+exclude="${exclude}spin_lock(\|spin_unlock(\|spin_trylock(\|spin_is_locked("
+exclude="${exclude}\|rcu_read_lock(\|rcu_read_unlock("
+exclude="${exclude}\|synchronize_rcu(\|synchronize_rcu_expedited("
+exclude="${exclude}\|srcu_read_lock(\|srcu_read_unlock("
+exclude="${exclude}\|synchronize_srcu(\|synchronize_srcu_expedited("
+exclude="${exclude}\)"
+if grep -q $exclude $litmus
+then
+	exit 255
+fi
+exit 0
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 8dd01f986fbb..16525d824001 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -477,6 +477,26 @@ static const char *uaccess_safe_builtin[] = {
 	"__asan_report_store4_noabort",
 	"__asan_report_store8_noabort",
 	"__asan_report_store16_noabort",
+	/* KCSAN */
+	"__kcsan_check_access",
+	"kcsan_found_watchpoint",
+	"kcsan_setup_watchpoint",
+	"kcsan_check_scoped_accesses",
+	/* KCSAN/TSAN */
+	"__tsan_func_entry",
+	"__tsan_func_exit",
+	"__tsan_read_range",
+	"__tsan_write_range",
+	"__tsan_read1",
+	"__tsan_read2",
+	"__tsan_read4",
+	"__tsan_read8",
+	"__tsan_read16",
+	"__tsan_write1",
+	"__tsan_write2",
+	"__tsan_write4",
+	"__tsan_write8",
+	"__tsan_write16",
 	/* KCOV */
 	"write_comp_data",
 	"__sanitizer_cov_trace_pc",
@@ -1050,10 +1070,7 @@ static struct rela *find_jump_table(struct objtool_file *file,
 	 * it.
 	 */
 	for (;
-	     &insn->list != &file->insn_list &&
-	     insn->sec == func->sec &&
-	     insn->offset >= func->offset;
-
+	     &insn->list != &file->insn_list && insn->func && insn->func->pfunc == func;
 	     insn = insn->first_jump_src ?: list_prev_entry(insn, list)) {
 
 		if (insn != orig_insn && insn->type == INSN_JUMP_DYNAMIC)
@@ -2008,8 +2025,8 @@ static int validate_return(struct symbol *func, struct instruction *insn, struct
 	}
 
 	if (state->bp_scratch) {
-		WARN("%s uses BP as a scratch register",
-		     func->name);
+		WARN_FUNC("BP used as a scratch register",
+			  insn->sec, insn->offset);
 		return 1;
 	}
 
@@ -2364,14 +2381,27 @@ static bool ignore_unreachable_insn(struct instruction *insn)
 	    !strcmp(insn->sec->name, ".altinstr_aux"))
 		return true;
 
+	if (!insn->func)
+		return false;
+
+	/*
+	 * CONFIG_UBSAN_TRAP inserts a UD2 when it sees
+	 * __builtin_unreachable().  The BUG() macro has an unreachable() after
+	 * the UD2, which causes GCC's undefined trap logic to emit another UD2
+	 * (or occasionally a JMP to UD2).
+	 */
+	if (list_prev_entry(insn, list)->dead_end &&
+	    (insn->type == INSN_BUG ||
+	     (insn->type == INSN_JUMP_UNCONDITIONAL &&
+	      insn->jump_dest && insn->jump_dest->type == INSN_BUG)))
+		return true;
+
 	/*
 	 * Check if this (or a subsequent) instruction is related to
 	 * CONFIG_UBSAN or CONFIG_KASAN.
 	 *
 	 * End the search at 5 instructions to avoid going into the weeds.
 	 */
-	if (!insn->func)
-		return false;
 	for (i = 0; i < 5; i++) {
 
 		if (is_kasan_insn(insn) || is_ubsan_insn(insn))
diff --git a/tools/objtool/orc_dump.c b/tools/objtool/orc_dump.c
index 13ccf775a83a..ba4cbb1cdd63 100644
--- a/tools/objtool/orc_dump.c
+++ b/tools/objtool/orc_dump.c
@@ -66,7 +66,7 @@ int orc_dump(const char *_objname)
 	char *name;
 	size_t nr_sections;
 	Elf64_Addr orc_ip_addr = 0;
-	size_t shstrtab_idx;
+	size_t shstrtab_idx, strtab_idx = 0;
 	Elf *elf;
 	Elf_Scn *scn;
 	GElf_Shdr sh;
@@ -127,6 +127,8 @@ int orc_dump(const char *_objname)
 
 		if (!strcmp(name, ".symtab")) {
 			symtab = data;
+		} else if (!strcmp(name, ".strtab")) {
+			strtab_idx = i;
 		} else if (!strcmp(name, ".orc_unwind")) {
 			orc = data->d_buf;
 			orc_size = sh.sh_size;
@@ -138,7 +140,7 @@ int orc_dump(const char *_objname)
 		}
 	}
 
-	if (!symtab || !orc || !orc_ip)
+	if (!symtab || !strtab_idx || !orc || !orc_ip)
 		return 0;
 
 	if (orc_size % sizeof(*orc) != 0) {
@@ -159,21 +161,29 @@ int orc_dump(const char *_objname)
 				return -1;
 			}
 
-			scn = elf_getscn(elf, sym.st_shndx);
-			if (!scn) {
-				WARN_ELF("elf_getscn");
-				return -1;
-			}
-
-			if (!gelf_getshdr(scn, &sh)) {
-				WARN_ELF("gelf_getshdr");
-				return -1;
-			}
-
-			name = elf_strptr(elf, shstrtab_idx, sh.sh_name);
-			if (!name || !*name) {
-				WARN_ELF("elf_strptr");
-				return -1;
+			if (GELF_ST_TYPE(sym.st_info) == STT_SECTION) {
+				scn = elf_getscn(elf, sym.st_shndx);
+				if (!scn) {
+					WARN_ELF("elf_getscn");
+					return -1;
+				}
+
+				if (!gelf_getshdr(scn, &sh)) {
+					WARN_ELF("gelf_getshdr");
+					return -1;
+				}
+
+				name = elf_strptr(elf, shstrtab_idx, sh.sh_name);
+				if (!name) {
+					WARN_ELF("elf_strptr");
+					return -1;
+				}
+			} else {
+				name = elf_strptr(elf, strtab_idx, sym.st_name);
+				if (!name) {
+					WARN_ELF("elf_strptr");
+					return -1;
+				}
 			}
 
 			printf("%s+%llx:", name, (unsigned long long)rela.r_addend);
diff --git a/tools/objtool/orc_gen.c b/tools/objtool/orc_gen.c
index 41e4a2754da4..4c0dabd28000 100644
--- a/tools/objtool/orc_gen.c
+++ b/tools/objtool/orc_gen.c
@@ -88,11 +88,6 @@ static int create_orc_entry(struct elf *elf, struct section *u_sec, struct secti
 	struct orc_entry *orc;
 	struct rela *rela;
 
-	if (!insn_sec->sym) {
-		WARN("missing symbol for section %s", insn_sec->name);
-		return -1;
-	}
-
 	/* populate ORC data */
 	orc = (struct orc_entry *)u_sec->data->d_buf + idx;
 	memcpy(orc, o, sizeof(*orc));
@@ -105,8 +100,32 @@ static int create_orc_entry(struct elf *elf, struct section *u_sec, struct secti
 	}
 	memset(rela, 0, sizeof(*rela));
 
-	rela->sym = insn_sec->sym;
-	rela->addend = insn_off;
+	if (insn_sec->sym) {
+		rela->sym = insn_sec->sym;
+		rela->addend = insn_off;
+	} else {
+		/*
+		 * The Clang assembler doesn't produce section symbols, so we
+		 * have to reference the function symbol instead:
+		 */
+		rela->sym = find_symbol_containing(insn_sec, insn_off);
+		if (!rela->sym) {
+			/*
+			 * Hack alert.  This happens when we need to reference
+			 * the NOP pad insn immediately after the function.
+			 */
+			rela->sym = find_symbol_containing(insn_sec,
+							   insn_off - 1);
+		}
+		if (!rela->sym) {
+			WARN("missing symbol for insn at offset 0x%lx\n",
+			     insn_off);
+			return -1;
+		}
+
+		rela->addend = insn_off - rela->sym->offset;
+	}
+
 	rela->type = R_X86_64_PC32;
 	rela->offset = idx * sizeof(int);
 	rela->sec = ip_relasec;
diff --git a/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl b/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl
index 44d510bc9b78..37b844f839bc 100644
--- a/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl
+++ b/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl
@@ -8,357 +8,357 @@
 #
 # The abi is "common", "64" or "x32" for this file.
 #
-0	common	read			__x64_sys_read
-1	common	write			__x64_sys_write
-2	common	open			__x64_sys_open
-3	common	close			__x64_sys_close
-4	common	stat			__x64_sys_newstat
-5	common	fstat			__x64_sys_newfstat
-6	common	lstat			__x64_sys_newlstat
-7	common	poll			__x64_sys_poll
-8	common	lseek			__x64_sys_lseek
-9	common	mmap			__x64_sys_mmap
-10	common	mprotect		__x64_sys_mprotect
-11	common	munmap			__x64_sys_munmap
-12	common	brk			__x64_sys_brk
-13	64	rt_sigaction		__x64_sys_rt_sigaction
-14	common	rt_sigprocmask		__x64_sys_rt_sigprocmask
-15	64	rt_sigreturn		__x64_sys_rt_sigreturn/ptregs
-16	64	ioctl			__x64_sys_ioctl
-17	common	pread64			__x64_sys_pread64
-18	common	pwrite64		__x64_sys_pwrite64
-19	64	readv			__x64_sys_readv
-20	64	writev			__x64_sys_writev
-21	common	access			__x64_sys_access
-22	common	pipe			__x64_sys_pipe
-23	common	select			__x64_sys_select
-24	common	sched_yield		__x64_sys_sched_yield
-25	common	mremap			__x64_sys_mremap
-26	common	msync			__x64_sys_msync
-27	common	mincore			__x64_sys_mincore
-28	common	madvise			__x64_sys_madvise
-29	common	shmget			__x64_sys_shmget
-30	common	shmat			__x64_sys_shmat
-31	common	shmctl			__x64_sys_shmctl
-32	common	dup			__x64_sys_dup
-33	common	dup2			__x64_sys_dup2
-34	common	pause			__x64_sys_pause
-35	common	nanosleep		__x64_sys_nanosleep
-36	common	getitimer		__x64_sys_getitimer
-37	common	alarm			__x64_sys_alarm
-38	common	setitimer		__x64_sys_setitimer
-39	common	getpid			__x64_sys_getpid
-40	common	sendfile		__x64_sys_sendfile64
-41	common	socket			__x64_sys_socket
-42	common	connect			__x64_sys_connect
-43	common	accept			__x64_sys_accept
-44	common	sendto			__x64_sys_sendto
-45	64	recvfrom		__x64_sys_recvfrom
-46	64	sendmsg			__x64_sys_sendmsg
-47	64	recvmsg			__x64_sys_recvmsg
-48	common	shutdown		__x64_sys_shutdown
-49	common	bind			__x64_sys_bind
-50	common	listen			__x64_sys_listen
-51	common	getsockname		__x64_sys_getsockname
-52	common	getpeername		__x64_sys_getpeername
-53	common	socketpair		__x64_sys_socketpair
-54	64	setsockopt		__x64_sys_setsockopt
-55	64	getsockopt		__x64_sys_getsockopt
-56	common	clone			__x64_sys_clone/ptregs
-57	common	fork			__x64_sys_fork/ptregs
-58	common	vfork			__x64_sys_vfork/ptregs
-59	64	execve			__x64_sys_execve/ptregs
-60	common	exit			__x64_sys_exit
-61	common	wait4			__x64_sys_wait4
-62	common	kill			__x64_sys_kill
-63	common	uname			__x64_sys_newuname
-64	common	semget			__x64_sys_semget
-65	common	semop			__x64_sys_semop
-66	common	semctl			__x64_sys_semctl
-67	common	shmdt			__x64_sys_shmdt
-68	common	msgget			__x64_sys_msgget
-69	common	msgsnd			__x64_sys_msgsnd
-70	common	msgrcv			__x64_sys_msgrcv
-71	common	msgctl			__x64_sys_msgctl
-72	common	fcntl			__x64_sys_fcntl
-73	common	flock			__x64_sys_flock
-74	common	fsync			__x64_sys_fsync
-75	common	fdatasync		__x64_sys_fdatasync
-76	common	truncate		__x64_sys_truncate
-77	common	ftruncate		__x64_sys_ftruncate
-78	common	getdents		__x64_sys_getdents
-79	common	getcwd			__x64_sys_getcwd
-80	common	chdir			__x64_sys_chdir
-81	common	fchdir			__x64_sys_fchdir
-82	common	rename			__x64_sys_rename
-83	common	mkdir			__x64_sys_mkdir
-84	common	rmdir			__x64_sys_rmdir
-85	common	creat			__x64_sys_creat
-86	common	link			__x64_sys_link
-87	common	unlink			__x64_sys_unlink
-88	common	symlink			__x64_sys_symlink
-89	common	readlink		__x64_sys_readlink
-90	common	chmod			__x64_sys_chmod
-91	common	fchmod			__x64_sys_fchmod
-92	common	chown			__x64_sys_chown
-93	common	fchown			__x64_sys_fchown
-94	common	lchown			__x64_sys_lchown
-95	common	umask			__x64_sys_umask
-96	common	gettimeofday		__x64_sys_gettimeofday
-97	common	getrlimit		__x64_sys_getrlimit
-98	common	getrusage		__x64_sys_getrusage
-99	common	sysinfo			__x64_sys_sysinfo
-100	common	times			__x64_sys_times
-101	64	ptrace			__x64_sys_ptrace
-102	common	getuid			__x64_sys_getuid
-103	common	syslog			__x64_sys_syslog
-104	common	getgid			__x64_sys_getgid
-105	common	setuid			__x64_sys_setuid
-106	common	setgid			__x64_sys_setgid
-107	common	geteuid			__x64_sys_geteuid
-108	common	getegid			__x64_sys_getegid
-109	common	setpgid			__x64_sys_setpgid
-110	common	getppid			__x64_sys_getppid
-111	common	getpgrp			__x64_sys_getpgrp
-112	common	setsid			__x64_sys_setsid
-113	common	setreuid		__x64_sys_setreuid
-114	common	setregid		__x64_sys_setregid
-115	common	getgroups		__x64_sys_getgroups
-116	common	setgroups		__x64_sys_setgroups
-117	common	setresuid		__x64_sys_setresuid
-118	common	getresuid		__x64_sys_getresuid
-119	common	setresgid		__x64_sys_setresgid
-120	common	getresgid		__x64_sys_getresgid
-121	common	getpgid			__x64_sys_getpgid
-122	common	setfsuid		__x64_sys_setfsuid
-123	common	setfsgid		__x64_sys_setfsgid
-124	common	getsid			__x64_sys_getsid
-125	common	capget			__x64_sys_capget
-126	common	capset			__x64_sys_capset
-127	64	rt_sigpending		__x64_sys_rt_sigpending
-128	64	rt_sigtimedwait		__x64_sys_rt_sigtimedwait
-129	64	rt_sigqueueinfo		__x64_sys_rt_sigqueueinfo
-130	common	rt_sigsuspend		__x64_sys_rt_sigsuspend
-131	64	sigaltstack		__x64_sys_sigaltstack
-132	common	utime			__x64_sys_utime
-133	common	mknod			__x64_sys_mknod
+0	common	read			sys_read
+1	common	write			sys_write
+2	common	open			sys_open
+3	common	close			sys_close
+4	common	stat			sys_newstat
+5	common	fstat			sys_newfstat
+6	common	lstat			sys_newlstat
+7	common	poll			sys_poll
+8	common	lseek			sys_lseek
+9	common	mmap			sys_mmap
+10	common	mprotect		sys_mprotect
+11	common	munmap			sys_munmap
+12	common	brk			sys_brk
+13	64	rt_sigaction		sys_rt_sigaction
+14	common	rt_sigprocmask		sys_rt_sigprocmask
+15	64	rt_sigreturn		sys_rt_sigreturn
+16	64	ioctl			sys_ioctl
+17	common	pread64			sys_pread64
+18	common	pwrite64		sys_pwrite64
+19	64	readv			sys_readv
+20	64	writev			sys_writev
+21	common	access			sys_access
+22	common	pipe			sys_pipe
+23	common	select			sys_select
+24	common	sched_yield		sys_sched_yield
+25	common	mremap			sys_mremap
+26	common	msync			sys_msync
+27	common	mincore			sys_mincore
+28	common	madvise			sys_madvise
+29	common	shmget			sys_shmget
+30	common	shmat			sys_shmat
+31	common	shmctl			sys_shmctl
+32	common	dup			sys_dup
+33	common	dup2			sys_dup2
+34	common	pause			sys_pause
+35	common	nanosleep		sys_nanosleep
+36	common	getitimer		sys_getitimer
+37	common	alarm			sys_alarm
+38	common	setitimer		sys_setitimer
+39	common	getpid			sys_getpid
+40	common	sendfile		sys_sendfile64
+41	common	socket			sys_socket
+42	common	connect			sys_connect
+43	common	accept			sys_accept
+44	common	sendto			sys_sendto
+45	64	recvfrom		sys_recvfrom
+46	64	sendmsg			sys_sendmsg
+47	64	recvmsg			sys_recvmsg
+48	common	shutdown		sys_shutdown
+49	common	bind			sys_bind
+50	common	listen			sys_listen
+51	common	getsockname		sys_getsockname
+52	common	getpeername		sys_getpeername
+53	common	socketpair		sys_socketpair
+54	64	setsockopt		sys_setsockopt
+55	64	getsockopt		sys_getsockopt
+56	common	clone			sys_clone
+57	common	fork			sys_fork
+58	common	vfork			sys_vfork
+59	64	execve			sys_execve
+60	common	exit			sys_exit
+61	common	wait4			sys_wait4
+62	common	kill			sys_kill
+63	common	uname			sys_newuname
+64	common	semget			sys_semget
+65	common	semop			sys_semop
+66	common	semctl			sys_semctl
+67	common	shmdt			sys_shmdt
+68	common	msgget			sys_msgget
+69	common	msgsnd			sys_msgsnd
+70	common	msgrcv			sys_msgrcv
+71	common	msgctl			sys_msgctl
+72	common	fcntl			sys_fcntl
+73	common	flock			sys_flock
+74	common	fsync			sys_fsync
+75	common	fdatasync		sys_fdatasync
+76	common	truncate		sys_truncate
+77	common	ftruncate		sys_ftruncate
+78	common	getdents		sys_getdents
+79	common	getcwd			sys_getcwd
+80	common	chdir			sys_chdir
+81	common	fchdir			sys_fchdir
+82	common	rename			sys_rename
+83	common	mkdir			sys_mkdir
+84	common	rmdir			sys_rmdir
+85	common	creat			sys_creat
+86	common	link			sys_link
+87	common	unlink			sys_unlink
+88	common	symlink			sys_symlink
+89	common	readlink		sys_readlink
+90	common	chmod			sys_chmod
+91	common	fchmod			sys_fchmod
+92	common	chown			sys_chown
+93	common	fchown			sys_fchown
+94	common	lchown			sys_lchown
+95	common	umask			sys_umask
+96	common	gettimeofday		sys_gettimeofday
+97	common	getrlimit		sys_getrlimit
+98	common	getrusage		sys_getrusage
+99	common	sysinfo			sys_sysinfo
+100	common	times			sys_times
+101	64	ptrace			sys_ptrace
+102	common	getuid			sys_getuid
+103	common	syslog			sys_syslog
+104	common	getgid			sys_getgid
+105	common	setuid			sys_setuid
+106	common	setgid			sys_setgid
+107	common	geteuid			sys_geteuid
+108	common	getegid			sys_getegid
+109	common	setpgid			sys_setpgid
+110	common	getppid			sys_getppid
+111	common	getpgrp			sys_getpgrp
+112	common	setsid			sys_setsid
+113	common	setreuid		sys_setreuid
+114	common	setregid		sys_setregid
+115	common	getgroups		sys_getgroups
+116	common	setgroups		sys_setgroups
+117	common	setresuid		sys_setresuid
+118	common	getresuid		sys_getresuid
+119	common	setresgid		sys_setresgid
+120	common	getresgid		sys_getresgid
+121	common	getpgid			sys_getpgid
+122	common	setfsuid		sys_setfsuid
+123	common	setfsgid		sys_setfsgid
+124	common	getsid			sys_getsid
+125	common	capget			sys_capget
+126	common	capset			sys_capset
+127	64	rt_sigpending		sys_rt_sigpending
+128	64	rt_sigtimedwait		sys_rt_sigtimedwait
+129	64	rt_sigqueueinfo		sys_rt_sigqueueinfo
+130	common	rt_sigsuspend		sys_rt_sigsuspend
+131	64	sigaltstack		sys_sigaltstack
+132	common	utime			sys_utime
+133	common	mknod			sys_mknod
 134	64	uselib
-135	common	personality		__x64_sys_personality
-136	common	ustat			__x64_sys_ustat
-137	common	statfs			__x64_sys_statfs
-138	common	fstatfs			__x64_sys_fstatfs
-139	common	sysfs			__x64_sys_sysfs
-140	common	getpriority		__x64_sys_getpriority
-141	common	setpriority		__x64_sys_setpriority
-142	common	sched_setparam		__x64_sys_sched_setparam
-143	common	sched_getparam		__x64_sys_sched_getparam
-144	common	sched_setscheduler	__x64_sys_sched_setscheduler
-145	common	sched_getscheduler	__x64_sys_sched_getscheduler
-146	common	sched_get_priority_max	__x64_sys_sched_get_priority_max
-147	common	sched_get_priority_min	__x64_sys_sched_get_priority_min
-148	common	sched_rr_get_interval	__x64_sys_sched_rr_get_interval
-149	common	mlock			__x64_sys_mlock
-150	common	munlock			__x64_sys_munlock
-151	common	mlockall		__x64_sys_mlockall
-152	common	munlockall		__x64_sys_munlockall
-153	common	vhangup			__x64_sys_vhangup
-154	common	modify_ldt		__x64_sys_modify_ldt
-155	common	pivot_root		__x64_sys_pivot_root
-156	64	_sysctl			__x64_sys_sysctl
-157	common	prctl			__x64_sys_prctl
-158	common	arch_prctl		__x64_sys_arch_prctl
-159	common	adjtimex		__x64_sys_adjtimex
-160	common	setrlimit		__x64_sys_setrlimit
-161	common	chroot			__x64_sys_chroot
-162	common	sync			__x64_sys_sync
-163	common	acct			__x64_sys_acct
-164	common	settimeofday		__x64_sys_settimeofday
-165	common	mount			__x64_sys_mount
-166	common	umount2			__x64_sys_umount
-167	common	swapon			__x64_sys_swapon
-168	common	swapoff			__x64_sys_swapoff
-169	common	reboot			__x64_sys_reboot
-170	common	sethostname		__x64_sys_sethostname
-171	common	setdomainname		__x64_sys_setdomainname
-172	common	iopl			__x64_sys_iopl/ptregs
-173	common	ioperm			__x64_sys_ioperm
+135	common	personality		sys_personality
+136	common	ustat			sys_ustat
+137	common	statfs			sys_statfs
+138	common	fstatfs			sys_fstatfs
+139	common	sysfs			sys_sysfs
+140	common	getpriority		sys_getpriority
+141	common	setpriority		sys_setpriority
+142	common	sched_setparam		sys_sched_setparam
+143	common	sched_getparam		sys_sched_getparam
+144	common	sched_setscheduler	sys_sched_setscheduler
+145	common	sched_getscheduler	sys_sched_getscheduler
+146	common	sched_get_priority_max	sys_sched_get_priority_max
+147	common	sched_get_priority_min	sys_sched_get_priority_min
+148	common	sched_rr_get_interval	sys_sched_rr_get_interval
+149	common	mlock			sys_mlock
+150	common	munlock			sys_munlock
+151	common	mlockall		sys_mlockall
+152	common	munlockall		sys_munlockall
+153	common	vhangup			sys_vhangup
+154	common	modify_ldt		sys_modify_ldt
+155	common	pivot_root		sys_pivot_root
+156	64	_sysctl			sys_sysctl
+157	common	prctl			sys_prctl
+158	common	arch_prctl		sys_arch_prctl
+159	common	adjtimex		sys_adjtimex
+160	common	setrlimit		sys_setrlimit
+161	common	chroot			sys_chroot
+162	common	sync			sys_sync
+163	common	acct			sys_acct
+164	common	settimeofday		sys_settimeofday
+165	common	mount			sys_mount
+166	common	umount2			sys_umount
+167	common	swapon			sys_swapon
+168	common	swapoff			sys_swapoff
+169	common	reboot			sys_reboot
+170	common	sethostname		sys_sethostname
+171	common	setdomainname		sys_setdomainname
+172	common	iopl			sys_iopl
+173	common	ioperm			sys_ioperm
 174	64	create_module
-175	common	init_module		__x64_sys_init_module
-176	common	delete_module		__x64_sys_delete_module
+175	common	init_module		sys_init_module
+176	common	delete_module		sys_delete_module
 177	64	get_kernel_syms
 178	64	query_module
-179	common	quotactl		__x64_sys_quotactl
+179	common	quotactl		sys_quotactl
 180	64	nfsservctl
 181	common	getpmsg
 182	common	putpmsg
 183	common	afs_syscall
 184	common	tuxcall
 185	common	security
-186	common	gettid			__x64_sys_gettid
-187	common	readahead		__x64_sys_readahead
-188	common	setxattr		__x64_sys_setxattr
-189	common	lsetxattr		__x64_sys_lsetxattr
-190	common	fsetxattr		__x64_sys_fsetxattr
-191	common	getxattr		__x64_sys_getxattr
-192	common	lgetxattr		__x64_sys_lgetxattr
-193	common	fgetxattr		__x64_sys_fgetxattr
-194	common	listxattr		__x64_sys_listxattr
-195	common	llistxattr		__x64_sys_llistxattr
-196	common	flistxattr		__x64_sys_flistxattr
-197	common	removexattr		__x64_sys_removexattr
-198	common	lremovexattr		__x64_sys_lremovexattr
-199	common	fremovexattr		__x64_sys_fremovexattr
-200	common	tkill			__x64_sys_tkill
-201	common	time			__x64_sys_time
-202	common	futex			__x64_sys_futex
-203	common	sched_setaffinity	__x64_sys_sched_setaffinity
-204	common	sched_getaffinity	__x64_sys_sched_getaffinity
+186	common	gettid			sys_gettid
+187	common	readahead		sys_readahead
+188	common	setxattr		sys_setxattr
+189	common	lsetxattr		sys_lsetxattr
+190	common	fsetxattr		sys_fsetxattr
+191	common	getxattr		sys_getxattr
+192	common	lgetxattr		sys_lgetxattr
+193	common	fgetxattr		sys_fgetxattr
+194	common	listxattr		sys_listxattr
+195	common	llistxattr		sys_llistxattr
+196	common	flistxattr		sys_flistxattr
+197	common	removexattr		sys_removexattr
+198	common	lremovexattr		sys_lremovexattr
+199	common	fremovexattr		sys_fremovexattr
+200	common	tkill			sys_tkill
+201	common	time			sys_time
+202	common	futex			sys_futex
+203	common	sched_setaffinity	sys_sched_setaffinity
+204	common	sched_getaffinity	sys_sched_getaffinity
 205	64	set_thread_area
-206	64	io_setup		__x64_sys_io_setup
-207	common	io_destroy		__x64_sys_io_destroy
-208	common	io_getevents		__x64_sys_io_getevents
-209	64	io_submit		__x64_sys_io_submit
-210	common	io_cancel		__x64_sys_io_cancel
+206	64	io_setup		sys_io_setup
+207	common	io_destroy		sys_io_destroy
+208	common	io_getevents		sys_io_getevents
+209	64	io_submit		sys_io_submit
+210	common	io_cancel		sys_io_cancel
 211	64	get_thread_area
-212	common	lookup_dcookie		__x64_sys_lookup_dcookie
-213	common	epoll_create		__x64_sys_epoll_create
+212	common	lookup_dcookie		sys_lookup_dcookie
+213	common	epoll_create		sys_epoll_create
 214	64	epoll_ctl_old
 215	64	epoll_wait_old
-216	common	remap_file_pages	__x64_sys_remap_file_pages
-217	common	getdents64		__x64_sys_getdents64
-218	common	set_tid_address		__x64_sys_set_tid_address
-219	common	restart_syscall		__x64_sys_restart_syscall
-220	common	semtimedop		__x64_sys_semtimedop
-221	common	fadvise64		__x64_sys_fadvise64
-222	64	timer_create		__x64_sys_timer_create
-223	common	timer_settime		__x64_sys_timer_settime
-224	common	timer_gettime		__x64_sys_timer_gettime
-225	common	timer_getoverrun	__x64_sys_timer_getoverrun
-226	common	timer_delete		__x64_sys_timer_delete
-227	common	clock_settime		__x64_sys_clock_settime
-228	common	clock_gettime		__x64_sys_clock_gettime
-229	common	clock_getres		__x64_sys_clock_getres
-230	common	clock_nanosleep		__x64_sys_clock_nanosleep
-231	common	exit_group		__x64_sys_exit_group
-232	common	epoll_wait		__x64_sys_epoll_wait
-233	common	epoll_ctl		__x64_sys_epoll_ctl
-234	common	tgkill			__x64_sys_tgkill
-235	common	utimes			__x64_sys_utimes
+216	common	remap_file_pages	sys_remap_file_pages
+217	common	getdents64		sys_getdents64
+218	common	set_tid_address		sys_set_tid_address
+219	common	restart_syscall		sys_restart_syscall
+220	common	semtimedop		sys_semtimedop
+221	common	fadvise64		sys_fadvise64
+222	64	timer_create		sys_timer_create
+223	common	timer_settime		sys_timer_settime
+224	common	timer_gettime		sys_timer_gettime
+225	common	timer_getoverrun	sys_timer_getoverrun
+226	common	timer_delete		sys_timer_delete
+227	common	clock_settime		sys_clock_settime
+228	common	clock_gettime		sys_clock_gettime
+229	common	clock_getres		sys_clock_getres
+230	common	clock_nanosleep		sys_clock_nanosleep
+231	common	exit_group		sys_exit_group
+232	common	epoll_wait		sys_epoll_wait
+233	common	epoll_ctl		sys_epoll_ctl
+234	common	tgkill			sys_tgkill
+235	common	utimes			sys_utimes
 236	64	vserver
-237	common	mbind			__x64_sys_mbind
-238	common	set_mempolicy		__x64_sys_set_mempolicy
-239	common	get_mempolicy		__x64_sys_get_mempolicy
-240	common	mq_open			__x64_sys_mq_open
-241	common	mq_unlink		__x64_sys_mq_unlink
-242	common	mq_timedsend		__x64_sys_mq_timedsend
-243	common	mq_timedreceive		__x64_sys_mq_timedreceive
-244	64	mq_notify		__x64_sys_mq_notify
-245	common	mq_getsetattr		__x64_sys_mq_getsetattr
-246	64	kexec_load		__x64_sys_kexec_load
-247	64	waitid			__x64_sys_waitid
-248	common	add_key			__x64_sys_add_key
-249	common	request_key		__x64_sys_request_key
-250	common	keyctl			__x64_sys_keyctl
-251	common	ioprio_set		__x64_sys_ioprio_set
-252	common	ioprio_get		__x64_sys_ioprio_get
-253	common	inotify_init		__x64_sys_inotify_init
-254	common	inotify_add_watch	__x64_sys_inotify_add_watch
-255	common	inotify_rm_watch	__x64_sys_inotify_rm_watch
-256	common	migrate_pages		__x64_sys_migrate_pages
-257	common	openat			__x64_sys_openat
-258	common	mkdirat			__x64_sys_mkdirat
-259	common	mknodat			__x64_sys_mknodat
-260	common	fchownat		__x64_sys_fchownat
-261	common	futimesat		__x64_sys_futimesat
-262	common	newfstatat		__x64_sys_newfstatat
-263	common	unlinkat		__x64_sys_unlinkat
-264	common	renameat		__x64_sys_renameat
-265	common	linkat			__x64_sys_linkat
-266	common	symlinkat		__x64_sys_symlinkat
-267	common	readlinkat		__x64_sys_readlinkat
-268	common	fchmodat		__x64_sys_fchmodat
-269	common	faccessat		__x64_sys_faccessat
-270	common	pselect6		__x64_sys_pselect6
-271	common	ppoll			__x64_sys_ppoll
-272	common	unshare			__x64_sys_unshare
-273	64	set_robust_list		__x64_sys_set_robust_list
-274	64	get_robust_list		__x64_sys_get_robust_list
-275	common	splice			__x64_sys_splice
-276	common	tee			__x64_sys_tee
-277	common	sync_file_range		__x64_sys_sync_file_range
-278	64	vmsplice		__x64_sys_vmsplice
-279	64	move_pages		__x64_sys_move_pages
-280	common	utimensat		__x64_sys_utimensat
-281	common	epoll_pwait		__x64_sys_epoll_pwait
-282	common	signalfd		__x64_sys_signalfd
-283	common	timerfd_create		__x64_sys_timerfd_create
-284	common	eventfd			__x64_sys_eventfd
-285	common	fallocate		__x64_sys_fallocate
-286	common	timerfd_settime		__x64_sys_timerfd_settime
-287	common	timerfd_gettime		__x64_sys_timerfd_gettime
-288	common	accept4			__x64_sys_accept4
-289	common	signalfd4		__x64_sys_signalfd4
-290	common	eventfd2		__x64_sys_eventfd2
-291	common	epoll_create1		__x64_sys_epoll_create1
-292	common	dup3			__x64_sys_dup3
-293	common	pipe2			__x64_sys_pipe2
-294	common	inotify_init1		__x64_sys_inotify_init1
-295	64	preadv			__x64_sys_preadv
-296	64	pwritev			__x64_sys_pwritev
-297	64	rt_tgsigqueueinfo	__x64_sys_rt_tgsigqueueinfo
-298	common	perf_event_open		__x64_sys_perf_event_open
-299	64	recvmmsg		__x64_sys_recvmmsg
-300	common	fanotify_init		__x64_sys_fanotify_init
-301	common	fanotify_mark		__x64_sys_fanotify_mark
-302	common	prlimit64		__x64_sys_prlimit64
-303	common	name_to_handle_at	__x64_sys_name_to_handle_at
-304	common	open_by_handle_at	__x64_sys_open_by_handle_at
-305	common	clock_adjtime		__x64_sys_clock_adjtime
-306	common	syncfs			__x64_sys_syncfs
-307	64	sendmmsg		__x64_sys_sendmmsg
-308	common	setns			__x64_sys_setns
-309	common	getcpu			__x64_sys_getcpu
-310	64	process_vm_readv	__x64_sys_process_vm_readv
-311	64	process_vm_writev	__x64_sys_process_vm_writev
-312	common	kcmp			__x64_sys_kcmp
-313	common	finit_module		__x64_sys_finit_module
-314	common	sched_setattr		__x64_sys_sched_setattr
-315	common	sched_getattr		__x64_sys_sched_getattr
-316	common	renameat2		__x64_sys_renameat2
-317	common	seccomp			__x64_sys_seccomp
-318	common	getrandom		__x64_sys_getrandom
-319	common	memfd_create		__x64_sys_memfd_create
-320	common	kexec_file_load		__x64_sys_kexec_file_load
-321	common	bpf			__x64_sys_bpf
-322	64	execveat		__x64_sys_execveat/ptregs
-323	common	userfaultfd		__x64_sys_userfaultfd
-324	common	membarrier		__x64_sys_membarrier
-325	common	mlock2			__x64_sys_mlock2
-326	common	copy_file_range		__x64_sys_copy_file_range
-327	64	preadv2			__x64_sys_preadv2
-328	64	pwritev2		__x64_sys_pwritev2
-329	common	pkey_mprotect		__x64_sys_pkey_mprotect
-330	common	pkey_alloc		__x64_sys_pkey_alloc
-331	common	pkey_free		__x64_sys_pkey_free
-332	common	statx			__x64_sys_statx
-333	common	io_pgetevents		__x64_sys_io_pgetevents
-334	common	rseq			__x64_sys_rseq
+237	common	mbind			sys_mbind
+238	common	set_mempolicy		sys_set_mempolicy
+239	common	get_mempolicy		sys_get_mempolicy
+240	common	mq_open			sys_mq_open
+241	common	mq_unlink		sys_mq_unlink
+242	common	mq_timedsend		sys_mq_timedsend
+243	common	mq_timedreceive		sys_mq_timedreceive
+244	64	mq_notify		sys_mq_notify
+245	common	mq_getsetattr		sys_mq_getsetattr
+246	64	kexec_load		sys_kexec_load
+247	64	waitid			sys_waitid
+248	common	add_key			sys_add_key
+249	common	request_key		sys_request_key
+250	common	keyctl			sys_keyctl
+251	common	ioprio_set		sys_ioprio_set
+252	common	ioprio_get		sys_ioprio_get
+253	common	inotify_init		sys_inotify_init
+254	common	inotify_add_watch	sys_inotify_add_watch
+255	common	inotify_rm_watch	sys_inotify_rm_watch
+256	common	migrate_pages		sys_migrate_pages
+257	common	openat			sys_openat
+258	common	mkdirat			sys_mkdirat
+259	common	mknodat			sys_mknodat
+260	common	fchownat		sys_fchownat
+261	common	futimesat		sys_futimesat
+262	common	newfstatat		sys_newfstatat
+263	common	unlinkat		sys_unlinkat
+264	common	renameat		sys_renameat
+265	common	linkat			sys_linkat
+266	common	symlinkat		sys_symlinkat
+267	common	readlinkat		sys_readlinkat
+268	common	fchmodat		sys_fchmodat
+269	common	faccessat		sys_faccessat
+270	common	pselect6		sys_pselect6
+271	common	ppoll			sys_ppoll
+272	common	unshare			sys_unshare
+273	64	set_robust_list		sys_set_robust_list
+274	64	get_robust_list		sys_get_robust_list
+275	common	splice			sys_splice
+276	common	tee			sys_tee
+277	common	sync_file_range		sys_sync_file_range
+278	64	vmsplice		sys_vmsplice
+279	64	move_pages		sys_move_pages
+280	common	utimensat		sys_utimensat
+281	common	epoll_pwait		sys_epoll_pwait
+282	common	signalfd		sys_signalfd
+283	common	timerfd_create		sys_timerfd_create
+284	common	eventfd			sys_eventfd
+285	common	fallocate		sys_fallocate
+286	common	timerfd_settime		sys_timerfd_settime
+287	common	timerfd_gettime		sys_timerfd_gettime
+288	common	accept4			sys_accept4
+289	common	signalfd4		sys_signalfd4
+290	common	eventfd2		sys_eventfd2
+291	common	epoll_create1		sys_epoll_create1
+292	common	dup3			sys_dup3
+293	common	pipe2			sys_pipe2
+294	common	inotify_init1		sys_inotify_init1
+295	64	preadv			sys_preadv
+296	64	pwritev			sys_pwritev
+297	64	rt_tgsigqueueinfo	sys_rt_tgsigqueueinfo
+298	common	perf_event_open		sys_perf_event_open
+299	64	recvmmsg		sys_recvmmsg
+300	common	fanotify_init		sys_fanotify_init
+301	common	fanotify_mark		sys_fanotify_mark
+302	common	prlimit64		sys_prlimit64
+303	common	name_to_handle_at	sys_name_to_handle_at
+304	common	open_by_handle_at	sys_open_by_handle_at
+305	common	clock_adjtime		sys_clock_adjtime
+306	common	syncfs			sys_syncfs
+307	64	sendmmsg		sys_sendmmsg
+308	common	setns			sys_setns
+309	common	getcpu			sys_getcpu
+310	64	process_vm_readv	sys_process_vm_readv
+311	64	process_vm_writev	sys_process_vm_writev
+312	common	kcmp			sys_kcmp
+313	common	finit_module		sys_finit_module
+314	common	sched_setattr		sys_sched_setattr
+315	common	sched_getattr		sys_sched_getattr
+316	common	renameat2		sys_renameat2
+317	common	seccomp			sys_seccomp
+318	common	getrandom		sys_getrandom
+319	common	memfd_create		sys_memfd_create
+320	common	kexec_file_load		sys_kexec_file_load
+321	common	bpf			sys_bpf
+322	64	execveat		sys_execveat
+323	common	userfaultfd		sys_userfaultfd
+324	common	membarrier		sys_membarrier
+325	common	mlock2			sys_mlock2
+326	common	copy_file_range		sys_copy_file_range
+327	64	preadv2			sys_preadv2
+328	64	pwritev2		sys_pwritev2
+329	common	pkey_mprotect		sys_pkey_mprotect
+330	common	pkey_alloc		sys_pkey_alloc
+331	common	pkey_free		sys_pkey_free
+332	common	statx			sys_statx
+333	common	io_pgetevents		sys_io_pgetevents
+334	common	rseq			sys_rseq
 # don't use numbers 387 through 423, add new calls after the last
 # 'common' entry
-424	common	pidfd_send_signal	__x64_sys_pidfd_send_signal
-425	common	io_uring_setup		__x64_sys_io_uring_setup
-426	common	io_uring_enter		__x64_sys_io_uring_enter
-427	common	io_uring_register	__x64_sys_io_uring_register
-428	common	open_tree		__x64_sys_open_tree
-429	common	move_mount		__x64_sys_move_mount
-430	common	fsopen			__x64_sys_fsopen
-431	common	fsconfig		__x64_sys_fsconfig
-432	common	fsmount			__x64_sys_fsmount
-433	common	fspick			__x64_sys_fspick
-434	common	pidfd_open		__x64_sys_pidfd_open
-435	common	clone3			__x64_sys_clone3/ptregs
-437	common	openat2			__x64_sys_openat2
-438	common	pidfd_getfd		__x64_sys_pidfd_getfd
+424	common	pidfd_send_signal	sys_pidfd_send_signal
+425	common	io_uring_setup		sys_io_uring_setup
+426	common	io_uring_enter		sys_io_uring_enter
+427	common	io_uring_register	sys_io_uring_register
+428	common	open_tree		sys_open_tree
+429	common	move_mount		sys_move_mount
+430	common	fsopen			sys_fsopen
+431	common	fsconfig		sys_fsconfig
+432	common	fsmount			sys_fsmount
+433	common	fspick			sys_fspick
+434	common	pidfd_open		sys_pidfd_open
+435	common	clone3			sys_clone3
+437	common	openat2			sys_openat2
+438	common	pidfd_getfd		sys_pidfd_getfd
 
 #
 # x32-specific system call numbers start at 512 to avoid cache impact
@@ -366,39 +366,39 @@
 # on-the-fly for compat_sys_*() compatibility system calls if X86_X32
 # is defined.
 #
-512	x32	rt_sigaction		__x32_compat_sys_rt_sigaction
-513	x32	rt_sigreturn		sys32_x32_rt_sigreturn
-514	x32	ioctl			__x32_compat_sys_ioctl
-515	x32	readv			__x32_compat_sys_readv
-516	x32	writev			__x32_compat_sys_writev
-517	x32	recvfrom		__x32_compat_sys_recvfrom
-518	x32	sendmsg			__x32_compat_sys_sendmsg
-519	x32	recvmsg			__x32_compat_sys_recvmsg
-520	x32	execve			__x32_compat_sys_execve/ptregs
-521	x32	ptrace			__x32_compat_sys_ptrace
-522	x32	rt_sigpending		__x32_compat_sys_rt_sigpending
-523	x32	rt_sigtimedwait		__x32_compat_sys_rt_sigtimedwait_time64
-524	x32	rt_sigqueueinfo		__x32_compat_sys_rt_sigqueueinfo
-525	x32	sigaltstack		__x32_compat_sys_sigaltstack
-526	x32	timer_create		__x32_compat_sys_timer_create
-527	x32	mq_notify		__x32_compat_sys_mq_notify
-528	x32	kexec_load		__x32_compat_sys_kexec_load
-529	x32	waitid			__x32_compat_sys_waitid
-530	x32	set_robust_list		__x32_compat_sys_set_robust_list
-531	x32	get_robust_list		__x32_compat_sys_get_robust_list
-532	x32	vmsplice		__x32_compat_sys_vmsplice
-533	x32	move_pages		__x32_compat_sys_move_pages
-534	x32	preadv			__x32_compat_sys_preadv64
-535	x32	pwritev			__x32_compat_sys_pwritev64
-536	x32	rt_tgsigqueueinfo	__x32_compat_sys_rt_tgsigqueueinfo
-537	x32	recvmmsg		__x32_compat_sys_recvmmsg_time64
-538	x32	sendmmsg		__x32_compat_sys_sendmmsg
-539	x32	process_vm_readv	__x32_compat_sys_process_vm_readv
-540	x32	process_vm_writev	__x32_compat_sys_process_vm_writev
-541	x32	setsockopt		__x32_compat_sys_setsockopt
-542	x32	getsockopt		__x32_compat_sys_getsockopt
-543	x32	io_setup		__x32_compat_sys_io_setup
-544	x32	io_submit		__x32_compat_sys_io_submit
-545	x32	execveat		__x32_compat_sys_execveat/ptregs
-546	x32	preadv2			__x32_compat_sys_preadv64v2
-547	x32	pwritev2		__x32_compat_sys_pwritev64v2
+512	x32	rt_sigaction		compat_sys_rt_sigaction
+513	x32	rt_sigreturn		compat_sys_x32_rt_sigreturn
+514	x32	ioctl			compat_sys_ioctl
+515	x32	readv			compat_sys_readv
+516	x32	writev			compat_sys_writev
+517	x32	recvfrom		compat_sys_recvfrom
+518	x32	sendmsg			compat_sys_sendmsg
+519	x32	recvmsg			compat_sys_recvmsg
+520	x32	execve			compat_sys_execve
+521	x32	ptrace			compat_sys_ptrace
+522	x32	rt_sigpending		compat_sys_rt_sigpending
+523	x32	rt_sigtimedwait		compat_sys_rt_sigtimedwait_time64
+524	x32	rt_sigqueueinfo		compat_sys_rt_sigqueueinfo
+525	x32	sigaltstack		compat_sys_sigaltstack
+526	x32	timer_create		compat_sys_timer_create
+527	x32	mq_notify		compat_sys_mq_notify
+528	x32	kexec_load		compat_sys_kexec_load
+529	x32	waitid			compat_sys_waitid
+530	x32	set_robust_list		compat_sys_set_robust_list
+531	x32	get_robust_list		compat_sys_get_robust_list
+532	x32	vmsplice		compat_sys_vmsplice
+533	x32	move_pages		compat_sys_move_pages
+534	x32	preadv			compat_sys_preadv64
+535	x32	pwritev			compat_sys_pwritev64
+536	x32	rt_tgsigqueueinfo	compat_sys_rt_tgsigqueueinfo
+537	x32	recvmmsg		compat_sys_recvmmsg_time64
+538	x32	sendmmsg		compat_sys_sendmmsg
+539	x32	process_vm_readv	compat_sys_process_vm_readv
+540	x32	process_vm_writev	compat_sys_process_vm_writev
+541	x32	setsockopt		compat_sys_setsockopt
+542	x32	getsockopt		compat_sys_getsockopt
+543	x32	io_setup		compat_sys_io_setup
+544	x32	io_submit		compat_sys_io_submit
+545	x32	execveat		compat_sys_execveat
+546	x32	preadv2			compat_sys_preadv64v2
+547	x32	pwritev2		compat_sys_pwritev64v2
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index bfb21d049e6c..cf147db4e5ca 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -22,7 +22,9 @@ include/uapi/linux/usbdevice_fs.h
 include/uapi/linux/vhost.h
 include/uapi/sound/asound.h
 include/linux/bits.h
+include/vdso/bits.h
 include/linux/const.h
+include/vdso/const.h
 include/linux/hash.h
 include/uapi/linux/hw_breakpoint.h
 arch/x86/include/asm/disabled-features.h
@@ -115,6 +117,7 @@ check arch/x86/lib/memcpy_64.S        '-I "^EXPORT_SYMBOL" -I "^#include <asm/ex
 check arch/x86/lib/memset_64.S        '-I "^EXPORT_SYMBOL" -I "^#include <asm/export.h>" -I"^SYM_FUNC_START\(_LOCAL\)*(memset_\(erms\|orig\))"'
 check include/uapi/asm-generic/mman.h '-I "^#include <\(uapi/\)*asm-generic/mman-common\(-tools\)*.h>"'
 check include/uapi/linux/mman.h       '-I "^#include <\(uapi/\)*asm/mman.h>"'
+check include/linux/build_bug.h       '-I "^#\(ifndef\|endif\)\( \/\/\)* static_assert$"'
 check include/linux/ctype.h	      '-I "isdigit("'
 check lib/ctype.c		      '-I "^EXPORT_SYMBOL" -I "^#include <linux/export.h>" -B'
 check arch/x86/include/asm/inat.h     '-I "^#include [\"<]\(asm/\)*inat_types.h[\">]"'
diff --git a/tools/perf/trace/beauty/clone.c b/tools/perf/trace/beauty/clone.c
index 062ca849c8fd..f4db894e0af6 100644
--- a/tools/perf/trace/beauty/clone.c
+++ b/tools/perf/trace/beauty/clone.c
@@ -46,6 +46,7 @@ static size_t clone__scnprintf_flags(unsigned long flags, char *bf, size_t size,
 	P_FLAG(NEWNET);
 	P_FLAG(IO);
 	P_FLAG(CLEAR_SIGHAND);
+	P_FLAG(INTO_CGROUP);
 #undef P_FLAG
 
 	if (flags)
diff --git a/tools/perf/trace/beauty/mmap.c b/tools/perf/trace/beauty/mmap.c
index 9fa771a90d79..862c8331dded 100644
--- a/tools/perf/trace/beauty/mmap.c
+++ b/tools/perf/trace/beauty/mmap.c
@@ -69,6 +69,7 @@ static size_t syscall_arg__scnprintf_mremap_flags(char *bf, size_t size,
 
 	P_MREMAP_FLAG(MAYMOVE);
 	P_MREMAP_FLAG(FIXED);
+	P_MREMAP_FLAG(DONTUNMAP);
 #undef P_MREMAP_FLAG
 
 	if (flags)
diff --git a/tools/perf/util/setup.py b/tools/perf/util/setup.py
index 347b2c0789e4..c5e3e9a68162 100644
--- a/tools/perf/util/setup.py
+++ b/tools/perf/util/setup.py
@@ -21,6 +21,8 @@ if cc_is_clang:
             vars[var] = sub("-fstack-clash-protection", "", vars[var])
         if not clang_has_option("-fstack-protector-strong"):
             vars[var] = sub("-fstack-protector-strong", "", vars[var])
+        if not clang_has_option("-fno-semantic-interposition"):
+            vars[var] = sub("-fno-semantic-interposition", "", vars[var])
 
 from distutils.core import setup, Extension
 
diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c
index 0fd713d3674f..03ecb8cd0eec 100644
--- a/tools/perf/util/stat-shadow.c
+++ b/tools/perf/util/stat-shadow.c
@@ -803,8 +803,11 @@ static void generic_metric(struct perf_stat_config *config,
 				     out->force_header ?
 				     (metric_name ? metric_name : name) : "", 0);
 		}
-	} else
-		print_metric(config, ctxp, NULL, NULL, "", 0);
+	} else {
+		print_metric(config, ctxp, NULL, NULL,
+			     out->force_header ?
+			     (metric_name ? metric_name : name) : "", 0);
+	}
 
 	for (i = 1; i < pctx.num_ids; i++)
 		zfree(&pctx.ids[i].name);
diff --git a/tools/spi/Makefile b/tools/spi/Makefile
index 2249a1546cc1..ada881afb489 100644
--- a/tools/spi/Makefile
+++ b/tools/spi/Makefile
@@ -52,7 +52,9 @@ $(OUTPUT)spidev_fdx: $(SPIDEV_FDX_IN)
 clean:
 	rm -f $(ALL_PROGRAMS)
 	rm -rf $(OUTPUT)include/
-	find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.d' -delete
+	find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete
+	find $(if $(OUTPUT),$(OUTPUT),.) -name '\.*.o.d' -delete
+	find $(if $(OUTPUT),$(OUTPUT),.) -name '\.*.o.cmd' -delete
 
 install: $(ALL_PROGRAMS)
 	install -d -m 755 $(DESTDIR)$(bindir);		\
diff --git a/tools/testing/radix-tree/idr-test.c b/tools/testing/radix-tree/idr-test.c
index 8995092d541e..3b796dd5e577 100644
--- a/tools/testing/radix-tree/idr-test.c
+++ b/tools/testing/radix-tree/idr-test.c
@@ -523,8 +523,27 @@ static void *ida_random_fn(void *arg)
 	return NULL;
 }
 
+static void *ida_leak_fn(void *arg)
+{
+	struct ida *ida = arg;
+	time_t s = time(NULL);
+	int i, ret;
+
+	rcu_register_thread();
+
+	do for (i = 0; i < 1000; i++) {
+		ret = ida_alloc_range(ida, 128, 128, GFP_KERNEL);
+		if (ret >= 0)
+			ida_free(ida, 128);
+	} while (time(NULL) < s + 2);
+
+	rcu_unregister_thread();
+	return NULL;
+}
+
 void ida_thread_tests(void)
 {
+	DEFINE_IDA(ida);
 	pthread_t threads[20];
 	int i;
 
@@ -536,6 +555,16 @@ void ida_thread_tests(void)
 
 	while (i--)
 		pthread_join(threads[i], NULL);
+
+	for (i = 0; i < ARRAY_SIZE(threads); i++)
+		if (pthread_create(&threads[i], NULL, ida_leak_fn, &ida)) {
+			perror("creating ida thread");
+			exit(1);
+		}
+
+	while (i--)
+		pthread_join(threads[i], NULL);
+	assert(ida_is_empty(&ida));
 }
 
 void ida_tests(void)
diff --git a/tools/testing/selftests/bpf/prog_tests/mmap.c b/tools/testing/selftests/bpf/prog_tests/mmap.c
index 16a814eb4d64..56d80adcf4bd 100644
--- a/tools/testing/selftests/bpf/prog_tests/mmap.c
+++ b/tools/testing/selftests/bpf/prog_tests/mmap.c
@@ -19,15 +19,16 @@ void test_mmap(void)
 	const size_t map_sz = roundup_page(sizeof(struct map_data));
 	const int zero = 0, one = 1, two = 2, far = 1500;
 	const long page_size = sysconf(_SC_PAGE_SIZE);
-	int err, duration = 0, i, data_map_fd;
+	int err, duration = 0, i, data_map_fd, data_map_id, tmp_fd;
 	struct bpf_map *data_map, *bss_map;
 	void *bss_mmaped = NULL, *map_mmaped = NULL, *tmp1, *tmp2;
 	struct test_mmap__bss *bss_data;
+	struct bpf_map_info map_info;
+	__u32 map_info_sz = sizeof(map_info);
 	struct map_data *map_data;
 	struct test_mmap *skel;
 	__u64 val = 0;
 
-
 	skel = test_mmap__open_and_load();
 	if (CHECK(!skel, "skel_open_and_load", "skeleton open/load failed\n"))
 		return;
@@ -36,6 +37,14 @@ void test_mmap(void)
 	data_map = skel->maps.data_map;
 	data_map_fd = bpf_map__fd(data_map);
 
+	/* get map's ID */
+	memset(&map_info, 0, map_info_sz);
+	err = bpf_obj_get_info_by_fd(data_map_fd, &map_info, &map_info_sz);
+	if (CHECK(err, "map_get_info", "failed %d\n", errno))
+		goto cleanup;
+	data_map_id = map_info.id;
+
+	/* mmap BSS map */
 	bss_mmaped = mmap(NULL, bss_sz, PROT_READ | PROT_WRITE, MAP_SHARED,
 			  bpf_map__fd(bss_map), 0);
 	if (CHECK(bss_mmaped == MAP_FAILED, "bss_mmap",
@@ -98,6 +107,10 @@ void test_mmap(void)
 		  "data_map freeze succeeded: err=%d, errno=%d\n", err, errno))
 		goto cleanup;
 
+	err = mprotect(map_mmaped, map_sz, PROT_READ);
+	if (CHECK(err, "mprotect_ro", "mprotect to r/o failed %d\n", errno))
+		goto cleanup;
+
 	/* unmap R/W mapping */
 	err = munmap(map_mmaped, map_sz);
 	map_mmaped = NULL;
@@ -111,6 +124,12 @@ void test_mmap(void)
 		map_mmaped = NULL;
 		goto cleanup;
 	}
+	err = mprotect(map_mmaped, map_sz, PROT_WRITE);
+	if (CHECK(!err, "mprotect_wr", "mprotect() succeeded unexpectedly!\n"))
+		goto cleanup;
+	err = mprotect(map_mmaped, map_sz, PROT_EXEC);
+	if (CHECK(!err, "mprotect_ex", "mprotect() succeeded unexpectedly!\n"))
+		goto cleanup;
 	map_data = map_mmaped;
 
 	/* map/unmap in a loop to test ref counting */
@@ -197,6 +216,45 @@ void test_mmap(void)
 	CHECK_FAIL(map_data->val[far] != 3 * 321);
 
 	munmap(tmp2, 4 * page_size);
+
+	tmp1 = mmap(NULL, map_sz, PROT_READ, MAP_SHARED, data_map_fd, 0);
+	if (CHECK(tmp1 == MAP_FAILED, "last_mmap", "failed %d\n", errno))
+		goto cleanup;
+
+	test_mmap__destroy(skel);
+	skel = NULL;
+	CHECK_FAIL(munmap(bss_mmaped, bss_sz));
+	bss_mmaped = NULL;
+	CHECK_FAIL(munmap(map_mmaped, map_sz));
+	map_mmaped = NULL;
+
+	/* map should be still held by active mmap */
+	tmp_fd = bpf_map_get_fd_by_id(data_map_id);
+	if (CHECK(tmp_fd < 0, "get_map_by_id", "failed %d\n", errno)) {
+		munmap(tmp1, map_sz);
+		goto cleanup;
+	}
+	close(tmp_fd);
+
+	/* this should release data map finally */
+	munmap(tmp1, map_sz);
+
+	/* we need to wait for RCU grace period */
+	for (i = 0; i < 10000; i++) {
+		__u32 id = data_map_id - 1;
+		if (bpf_map_get_next_id(id, &id) || id > data_map_id)
+			break;
+		usleep(1);
+	}
+
+	/* should fail to get map FD by non-existing ID */
+	tmp_fd = bpf_map_get_fd_by_id(data_map_id);
+	if (CHECK(tmp_fd >= 0, "get_map_by_id_after",
+		  "unexpectedly succeeded %d\n", tmp_fd)) {
+		close(tmp_fd);
+		goto cleanup;
+	}
+
 cleanup:
 	if (bss_mmaped)
 		CHECK_FAIL(munmap(bss_mmaped, bss_sz));
diff --git a/tools/testing/selftests/bpf/prog_tests/section_names.c b/tools/testing/selftests/bpf/prog_tests/section_names.c
index 9d9351dc2ded..713167449c98 100644
--- a/tools/testing/selftests/bpf/prog_tests/section_names.c
+++ b/tools/testing/selftests/bpf/prog_tests/section_names.c
@@ -43,18 +43,18 @@ static struct sec_name_test tests[] = {
 	{"lwt_seg6local", {0, BPF_PROG_TYPE_LWT_SEG6LOCAL, 0}, {-EINVAL, 0} },
 	{
 		"cgroup_skb/ingress",
-		{0, BPF_PROG_TYPE_CGROUP_SKB, 0},
+		{0, BPF_PROG_TYPE_CGROUP_SKB, BPF_CGROUP_INET_INGRESS},
 		{0, BPF_CGROUP_INET_INGRESS},
 	},
 	{
 		"cgroup_skb/egress",
-		{0, BPF_PROG_TYPE_CGROUP_SKB, 0},
+		{0, BPF_PROG_TYPE_CGROUP_SKB, BPF_CGROUP_INET_EGRESS},
 		{0, BPF_CGROUP_INET_EGRESS},
 	},
 	{"cgroup/skb", {0, BPF_PROG_TYPE_CGROUP_SKB, 0}, {-EINVAL, 0} },
 	{
 		"cgroup/sock",
-		{0, BPF_PROG_TYPE_CGROUP_SOCK, 0},
+		{0, BPF_PROG_TYPE_CGROUP_SOCK, BPF_CGROUP_INET_SOCK_CREATE},
 		{0, BPF_CGROUP_INET_SOCK_CREATE},
 	},
 	{
@@ -69,26 +69,38 @@ static struct sec_name_test tests[] = {
 	},
 	{
 		"cgroup/dev",
-		{0, BPF_PROG_TYPE_CGROUP_DEVICE, 0},
+		{0, BPF_PROG_TYPE_CGROUP_DEVICE, BPF_CGROUP_DEVICE},
 		{0, BPF_CGROUP_DEVICE},
 	},
-	{"sockops", {0, BPF_PROG_TYPE_SOCK_OPS, 0}, {0, BPF_CGROUP_SOCK_OPS} },
+	{
+		"sockops",
+		{0, BPF_PROG_TYPE_SOCK_OPS, BPF_CGROUP_SOCK_OPS},
+		{0, BPF_CGROUP_SOCK_OPS},
+	},
 	{
 		"sk_skb/stream_parser",
-		{0, BPF_PROG_TYPE_SK_SKB, 0},
+		{0, BPF_PROG_TYPE_SK_SKB, BPF_SK_SKB_STREAM_PARSER},
 		{0, BPF_SK_SKB_STREAM_PARSER},
 	},
 	{
 		"sk_skb/stream_verdict",
-		{0, BPF_PROG_TYPE_SK_SKB, 0},
+		{0, BPF_PROG_TYPE_SK_SKB, BPF_SK_SKB_STREAM_VERDICT},
 		{0, BPF_SK_SKB_STREAM_VERDICT},
 	},
 	{"sk_skb", {0, BPF_PROG_TYPE_SK_SKB, 0}, {-EINVAL, 0} },
-	{"sk_msg", {0, BPF_PROG_TYPE_SK_MSG, 0}, {0, BPF_SK_MSG_VERDICT} },
-	{"lirc_mode2", {0, BPF_PROG_TYPE_LIRC_MODE2, 0}, {0, BPF_LIRC_MODE2} },
+	{
+		"sk_msg",
+		{0, BPF_PROG_TYPE_SK_MSG, BPF_SK_MSG_VERDICT},
+		{0, BPF_SK_MSG_VERDICT},
+	},
+	{
+		"lirc_mode2",
+		{0, BPF_PROG_TYPE_LIRC_MODE2, BPF_LIRC_MODE2},
+		{0, BPF_LIRC_MODE2},
+	},
 	{
 		"flow_dissector",
-		{0, BPF_PROG_TYPE_FLOW_DISSECTOR, 0},
+		{0, BPF_PROG_TYPE_FLOW_DISSECTOR, BPF_FLOW_DISSECTOR},
 		{0, BPF_FLOW_DISSECTOR},
 	},
 	{
@@ -158,17 +170,17 @@ static void test_prog_type_by_name(const struct sec_name_test *test)
 				      &expected_attach_type);
 
 	CHECK(rc != test->expected_load.rc, "check_code",
-	      "prog: unexpected rc=%d for %s", rc, test->sec_name);
+	      "prog: unexpected rc=%d for %s\n", rc, test->sec_name);
 
 	if (rc)
 		return;
 
 	CHECK(prog_type != test->expected_load.prog_type, "check_prog_type",
-	      "prog: unexpected prog_type=%d for %s",
+	      "prog: unexpected prog_type=%d for %s\n",
 	      prog_type, test->sec_name);
 
 	CHECK(expected_attach_type != test->expected_load.expected_attach_type,
-	      "check_attach_type", "prog: unexpected expected_attach_type=%d for %s",
+	      "check_attach_type", "prog: unexpected expected_attach_type=%d for %s\n",
 	      expected_attach_type, test->sec_name);
 }
 
@@ -180,13 +192,13 @@ static void test_attach_type_by_name(const struct sec_name_test *test)
 	rc = libbpf_attach_type_by_name(test->sec_name, &attach_type);
 
 	CHECK(rc != test->expected_attach.rc, "check_ret",
-	      "attach: unexpected rc=%d for %s", rc, test->sec_name);
+	      "attach: unexpected rc=%d for %s\n", rc, test->sec_name);
 
 	if (rc)
 		return;
 
 	CHECK(attach_type != test->expected_attach.attach_type,
-	      "check_attach_type", "attach: unexpected attach_type=%d for %s",
+	      "check_attach_type", "attach: unexpected attach_type=%d for %s\n",
 	      attach_type, test->sec_name);
 }
 
diff --git a/tools/testing/selftests/bpf/prog_tests/test_lsm.c b/tools/testing/selftests/bpf/prog_tests/test_lsm.c
index 1e4c258de09d..b17eb2045c1d 100644
--- a/tools/testing/selftests/bpf/prog_tests/test_lsm.c
+++ b/tools/testing/selftests/bpf/prog_tests/test_lsm.c
@@ -15,7 +15,10 @@
 
 char *CMD_ARGS[] = {"true", NULL};
 
-int heap_mprotect(void)
+#define GET_PAGE_ADDR(ADDR, PAGE_SIZE)					\
+	(char *)(((unsigned long) (ADDR + PAGE_SIZE)) & ~(PAGE_SIZE-1))
+
+int stack_mprotect(void)
 {
 	void *buf;
 	long sz;
@@ -25,12 +28,9 @@ int heap_mprotect(void)
 	if (sz < 0)
 		return sz;
 
-	buf = memalign(sz, 2 * sz);
-	if (buf == NULL)
-		return -ENOMEM;
-
-	ret = mprotect(buf, sz, PROT_READ | PROT_WRITE | PROT_EXEC);
-	free(buf);
+	buf = alloca(sz * 3);
+	ret = mprotect(GET_PAGE_ADDR(buf, sz), sz,
+		       PROT_READ | PROT_WRITE | PROT_EXEC);
 	return ret;
 }
 
@@ -73,8 +73,8 @@ void test_test_lsm(void)
 
 	skel->bss->monitored_pid = getpid();
 
-	err = heap_mprotect();
-	if (CHECK(errno != EPERM, "heap_mprotect", "want errno=EPERM, got %d\n",
+	err = stack_mprotect();
+	if (CHECK(errno != EPERM, "stack_mprotect", "want err=EPERM, got %d\n",
 		  errno))
 		goto close_prog;
 
diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_attach.c b/tools/testing/selftests/bpf/prog_tests/xdp_attach.c
index 05b294d6b923..15ef3531483e 100644
--- a/tools/testing/selftests/bpf/prog_tests/xdp_attach.c
+++ b/tools/testing/selftests/bpf/prog_tests/xdp_attach.c
@@ -6,19 +6,34 @@
 
 void test_xdp_attach(void)
 {
+	__u32 duration = 0, id1, id2, id0 = 0, len;
 	struct bpf_object *obj1, *obj2, *obj3;
 	const char *file = "./test_xdp.o";
+	struct bpf_prog_info info = {};
 	int err, fd1, fd2, fd3;
-	__u32 duration = 0;
 	DECLARE_LIBBPF_OPTS(bpf_xdp_set_link_opts, opts,
 			    .old_fd = -1);
 
+	len = sizeof(info);
+
 	err = bpf_prog_load(file, BPF_PROG_TYPE_XDP, &obj1, &fd1);
 	if (CHECK_FAIL(err))
 		return;
+	err = bpf_obj_get_info_by_fd(fd1, &info, &len);
+	if (CHECK_FAIL(err))
+		goto out_1;
+	id1 = info.id;
+
 	err = bpf_prog_load(file, BPF_PROG_TYPE_XDP, &obj2, &fd2);
 	if (CHECK_FAIL(err))
 		goto out_1;
+
+	memset(&info, 0, sizeof(info));
+	err = bpf_obj_get_info_by_fd(fd2, &info, &len);
+	if (CHECK_FAIL(err))
+		goto out_2;
+	id2 = info.id;
+
 	err = bpf_prog_load(file, BPF_PROG_TYPE_XDP, &obj3, &fd3);
 	if (CHECK_FAIL(err))
 		goto out_2;
@@ -28,6 +43,11 @@ void test_xdp_attach(void)
 	if (CHECK(err, "load_ok", "initial load failed"))
 		goto out_close;
 
+	err = bpf_get_link_xdp_id(IFINDEX_LO, &id0, 0);
+	if (CHECK(err || id0 != id1, "id1_check",
+		  "loaded prog id %u != id1 %u, err %d", id0, id1, err))
+		goto out_close;
+
 	err = bpf_set_link_xdp_fd_opts(IFINDEX_LO, fd2, XDP_FLAGS_REPLACE,
 				       &opts);
 	if (CHECK(!err, "load_fail", "load with expected id didn't fail"))
@@ -37,6 +57,10 @@ void test_xdp_attach(void)
 	err = bpf_set_link_xdp_fd_opts(IFINDEX_LO, fd2, 0, &opts);
 	if (CHECK(err, "replace_ok", "replace valid old_fd failed"))
 		goto out;
+	err = bpf_get_link_xdp_id(IFINDEX_LO, &id0, 0);
+	if (CHECK(err || id0 != id2, "id2_check",
+		  "loaded prog id %u != id2 %u, err %d", id0, id2, err))
+		goto out_close;
 
 	err = bpf_set_link_xdp_fd_opts(IFINDEX_LO, fd3, 0, &opts);
 	if (CHECK(!err, "replace_fail", "replace invalid old_fd didn't fail"))
@@ -51,6 +75,10 @@ void test_xdp_attach(void)
 	if (CHECK(err, "remove_ok", "remove valid old_fd failed"))
 		goto out;
 
+	err = bpf_get_link_xdp_id(IFINDEX_LO, &id0, 0);
+	if (CHECK(err || id0 != 0, "unload_check",
+		  "loaded prog id %u != 0, err %d", id0, err))
+		goto out_close;
 out:
 	bpf_set_link_xdp_fd(IFINDEX_LO, -1, 0);
 out_close:
diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_info.c b/tools/testing/selftests/bpf/prog_tests/xdp_info.c
new file mode 100644
index 000000000000..d2d7a283d72f
--- /dev/null
+++ b/tools/testing/selftests/bpf/prog_tests/xdp_info.c
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/if_link.h>
+#include <test_progs.h>
+
+#define IFINDEX_LO 1
+
+void test_xdp_info(void)
+{
+	__u32 len = sizeof(struct bpf_prog_info), duration = 0, prog_id;
+	const char *file = "./xdp_dummy.o";
+	struct bpf_prog_info info = {};
+	struct bpf_object *obj;
+	int err, prog_fd;
+
+	/* Get prog_id for XDP_ATTACHED_NONE mode */
+
+	err = bpf_get_link_xdp_id(IFINDEX_LO, &prog_id, 0);
+	if (CHECK(err, "get_xdp_none", "errno=%d\n", errno))
+		return;
+	if (CHECK(prog_id, "prog_id_none", "unexpected prog_id=%u\n", prog_id))
+		return;
+
+	err = bpf_get_link_xdp_id(IFINDEX_LO, &prog_id, XDP_FLAGS_SKB_MODE);
+	if (CHECK(err, "get_xdp_none_skb", "errno=%d\n", errno))
+		return;
+	if (CHECK(prog_id, "prog_id_none_skb", "unexpected prog_id=%u\n",
+		  prog_id))
+		return;
+
+	/* Setup prog */
+
+	err = bpf_prog_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd);
+	if (CHECK_FAIL(err))
+		return;
+
+	err = bpf_obj_get_info_by_fd(prog_fd, &info, &len);
+	if (CHECK(err, "get_prog_info", "errno=%d\n", errno))
+		goto out_close;
+
+	err = bpf_set_link_xdp_fd(IFINDEX_LO, prog_fd, XDP_FLAGS_SKB_MODE);
+	if (CHECK(err, "set_xdp_skb", "errno=%d\n", errno))
+		goto out_close;
+
+	/* Get prog_id for single prog mode */
+
+	err = bpf_get_link_xdp_id(IFINDEX_LO, &prog_id, 0);
+	if (CHECK(err, "get_xdp", "errno=%d\n", errno))
+		goto out;
+	if (CHECK(prog_id != info.id, "prog_id", "prog_id not available\n"))
+		goto out;
+
+	err = bpf_get_link_xdp_id(IFINDEX_LO, &prog_id, XDP_FLAGS_SKB_MODE);
+	if (CHECK(err, "get_xdp_skb", "errno=%d\n", errno))
+		goto out;
+	if (CHECK(prog_id != info.id, "prog_id_skb", "prog_id not available\n"))
+		goto out;
+
+	err = bpf_get_link_xdp_id(IFINDEX_LO, &prog_id, XDP_FLAGS_DRV_MODE);
+	if (CHECK(err, "get_xdp_drv", "errno=%d\n", errno))
+		goto out;
+	if (CHECK(prog_id, "prog_id_drv", "unexpected prog_id=%u\n", prog_id))
+		goto out;
+
+out:
+	bpf_set_link_xdp_fd(IFINDEX_LO, -1, 0);
+out_close:
+	bpf_object__close(obj);
+}
diff --git a/tools/testing/selftests/bpf/progs/lsm.c b/tools/testing/selftests/bpf/progs/lsm.c
index a4e3c223028d..b4598d4bc4f7 100644
--- a/tools/testing/selftests/bpf/progs/lsm.c
+++ b/tools/testing/selftests/bpf/progs/lsm.c
@@ -23,12 +23,12 @@ int BPF_PROG(test_int_hook, struct vm_area_struct *vma,
 		return ret;
 
 	__u32 pid = bpf_get_current_pid_tgid() >> 32;
-	int is_heap = 0;
+	int is_stack = 0;
 
-	is_heap = (vma->vm_start >= vma->vm_mm->start_brk &&
-		   vma->vm_end <= vma->vm_mm->brk);
+	is_stack = (vma->vm_start <= vma->vm_mm->start_stack &&
+		    vma->vm_end >= vma->vm_mm->start_stack);
 
-	if (is_heap && monitored_pid == pid) {
+	if (is_stack && monitored_pid == pid) {
 		mprotect_count++;
 		ret = -EPERM;
 	}
diff --git a/tools/testing/selftests/bpf/verifier/bounds.c b/tools/testing/selftests/bpf/verifier/bounds.c
index 4d0d09574bf4..a253a064e6e0 100644
--- a/tools/testing/selftests/bpf/verifier/bounds.c
+++ b/tools/testing/selftests/bpf/verifier/bounds.c
@@ -501,7 +501,7 @@
 	.result = REJECT
 },
 {
-	"bounds check mixed 32bit and 64bit arithmatic. test1",
+	"bounds check mixed 32bit and 64bit arithmetic. test1",
 	.insns = {
 	BPF_MOV64_IMM(BPF_REG_0, 0),
 	BPF_MOV64_IMM(BPF_REG_1, -1),
@@ -520,7 +520,7 @@
 	.result = ACCEPT
 },
 {
-	"bounds check mixed 32bit and 64bit arithmatic. test2",
+	"bounds check mixed 32bit and 64bit arithmetic. test2",
 	.insns = {
 	BPF_MOV64_IMM(BPF_REG_0, 0),
 	BPF_MOV64_IMM(BPF_REG_1, -1),
diff --git a/tools/testing/selftests/ftrace/config b/tools/testing/selftests/ftrace/config
index c2c8de4fafff..e59d985eeff0 100644
--- a/tools/testing/selftests/ftrace/config
+++ b/tools/testing/selftests/ftrace/config
@@ -11,5 +11,6 @@ CONFIG_PREEMPTIRQ_DELAY_TEST=m
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_SAMPLES=y
+CONFIG_SAMPLE_FTRACE_DIRECT=m
 CONFIG_SAMPLE_TRACE_PRINTK=m
 CONFIG_KALLSYMS_ALL=y
diff --git a/tools/testing/selftests/ipc/msgque.c b/tools/testing/selftests/ipc/msgque.c
index 4c156aeab6b8..5ec4d9e18806 100644
--- a/tools/testing/selftests/ipc/msgque.c
+++ b/tools/testing/selftests/ipc/msgque.c
@@ -137,7 +137,7 @@ int dump_queue(struct msgque_data *msgque)
 	for (kern_id = 0; kern_id < 256; kern_id++) {
 		ret = msgctl(kern_id, MSG_STAT, &ds);
 		if (ret < 0) {
-			if (errno == -EINVAL)
+			if (errno == EINVAL)
 				continue;
 			printf("Failed to get stats for IPC queue with id %d\n",
 					kern_id);
diff --git a/tools/testing/selftests/kselftest/runner.sh b/tools/testing/selftests/kselftest/runner.sh
index e84d901f8567..676b3a8b114d 100644
--- a/tools/testing/selftests/kselftest/runner.sh
+++ b/tools/testing/selftests/kselftest/runner.sh
@@ -33,7 +33,7 @@ tap_timeout()
 {
 	# Make sure tests will time out if utility is available.
 	if [ -x /usr/bin/timeout ] ; then
-		/usr/bin/timeout "$kselftest_timeout" "$1"
+		/usr/bin/timeout --foreground "$kselftest_timeout" "$1"
 	else
 		"$1"
 	fi
diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h
index 2902f6a78f8a..2bb8c81fc0b4 100644
--- a/tools/testing/selftests/kselftest_harness.h
+++ b/tools/testing/selftests/kselftest_harness.h
@@ -705,7 +705,7 @@ static void __timeout_handler(int sig, siginfo_t *info, void *ucontext)
 	/* Sanity check handler execution environment. */
 	if (!t) {
 		fprintf(TH_LOG_STREAM,
-			"no active test in SIGARLM handler!?\n");
+			"no active test in SIGALRM handler!?\n");
 		abort();
 	}
 	if (sig != SIGALRM || sig != info->si_signo) {
@@ -731,7 +731,7 @@ void __wait_for_test(struct __test_metadata *t)
 	if (sigaction(SIGALRM, &action, &saved_action)) {
 		t->passed = 0;
 		fprintf(TH_LOG_STREAM,
-			"%s: unable to install SIGARLM handler\n",
+			"%s: unable to install SIGALRM handler\n",
 			t->name);
 		return;
 	}
@@ -743,7 +743,7 @@ void __wait_for_test(struct __test_metadata *t)
 	if (sigaction(SIGALRM, &saved_action, NULL)) {
 		t->passed = 0;
 		fprintf(TH_LOG_STREAM,
-			"%s: unable to uninstall SIGARLM handler\n",
+			"%s: unable to uninstall SIGALRM handler\n",
 			t->name);
 		return;
 	}
diff --git a/tools/testing/selftests/memfd/Makefile b/tools/testing/selftests/memfd/Makefile
index 0a15f9e23431..187b14cad00c 100644
--- a/tools/testing/selftests/memfd/Makefile
+++ b/tools/testing/selftests/memfd/Makefile
@@ -4,8 +4,9 @@ CFLAGS += -I../../../../include/uapi/
 CFLAGS += -I../../../../include/
 CFLAGS += -I../../../../usr/include/
 
-TEST_GEN_PROGS := memfd_test fuse_test fuse_mnt
+TEST_GEN_PROGS := memfd_test
 TEST_PROGS := run_fuse_test.sh run_hugetlbfs_test.sh
+TEST_GEN_FILES := fuse_test fuse_mnt
 
 fuse_mnt.o: CFLAGS += $(shell pkg-config fuse --cflags)
 
diff --git a/tools/testing/selftests/ntb/ntb_test.sh b/tools/testing/selftests/ntb/ntb_test.sh
index 9c60337317c6..020137b61407 100755
--- a/tools/testing/selftests/ntb/ntb_test.sh
+++ b/tools/testing/selftests/ntb/ntb_test.sh
@@ -241,7 +241,7 @@ function get_files_count()
 	split_remote $LOC
 
 	if [[ "$REMOTE" == "" ]]; then
-		echo $(ls -1 "$LOC"/${NAME}* 2>/dev/null | wc -l)
+		echo $(ls -1 "$VPATH"/${NAME}* 2>/dev/null | wc -l)
 	else
 		echo $(ssh "$REMOTE" "ls -1 \"$VPATH\"/${NAME}* | \
 		       wc -l" 2> /dev/null)
diff --git a/tools/testing/selftests/rcutorture/bin/kcsan-collapse.sh b/tools/testing/selftests/rcutorture/bin/kcsan-collapse.sh
new file mode 100755
index 000000000000..e5cc6b2f195e
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/bin/kcsan-collapse.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0+
+#
+# If this was a KCSAN run, collapse the reports in the various console.log
+# files onto pairs of functions.
+#
+# Usage: kcsan-collapse.sh resultsdir
+#
+# Copyright (C) 2020 Facebook, Inc.
+#
+# Authors: Paul E. McKenney <paulmck@kernel.org>
+
+if test -z "$TORTURE_KCONFIG_KCSAN_ARG"
+then
+	exit 0
+fi
+cat $1/*/console.log |
+	grep "BUG: KCSAN: " |
+	sed -e 's/^\[[^]]*] //' |
+	sort |
+	uniq -c |
+	sort -k1nr > $1/kcsan.sum
diff --git a/tools/testing/selftests/rcutorture/bin/kvm-recheck-rcu.sh b/tools/testing/selftests/rcutorture/bin/kvm-recheck-rcu.sh
index 9d9a41625dd9..1706cd4466b4 100755
--- a/tools/testing/selftests/rcutorture/bin/kvm-recheck-rcu.sh
+++ b/tools/testing/selftests/rcutorture/bin/kvm-recheck-rcu.sh
@@ -41,7 +41,21 @@ else
 		title="$title ($ngpsps/s)"
 	fi
 	echo $title $stopstate $fwdprog
-	nclosecalls=`grep --binary-files=text 'torture: Reader Batch' $i/console.log | tail -1 | awk '{for (i=NF-8;i<=NF;i++) sum+=$i; } END {print sum}'`
+	nclosecalls=`grep --binary-files=text 'torture: Reader Batch' $i/console.log | tail -1 | \
+		awk -v sum=0 '
+		{
+			for (i = 0; i <= NF; i++) {
+				sum += $i;
+				if ($i ~ /Batch:/) {
+					sum = 0;
+					i = i + 2;
+				}
+			}
+		}
+
+		END {
+			print sum
+		}'`
 	if test -z "$nclosecalls"
 	then
 		exit 0
diff --git a/tools/testing/selftests/rcutorture/bin/kvm-recheck.sh b/tools/testing/selftests/rcutorture/bin/kvm-recheck.sh
index 0326f4a5ff9c..736f04749b90 100755
--- a/tools/testing/selftests/rcutorture/bin/kvm-recheck.sh
+++ b/tools/testing/selftests/rcutorture/bin/kvm-recheck.sh
@@ -70,6 +70,15 @@ do
 			fi
 		fi
 	done
+	if test -f "$rd/kcsan.sum"
+	then
+		if test -s "$rd/kcsan.sum"
+		then
+			echo KCSAN summary in $rd/kcsan.sum
+		else
+			echo Clean KCSAN run in $rd
+		fi
+	fi
 done
 EDITOR=echo kvm-find-errors.sh "${@: -1}" > $T 2>&1
 ret=$?
diff --git a/tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh b/tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh
index e0352304b98b..6ff611c630d1 100755
--- a/tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh
+++ b/tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh
@@ -44,30 +44,32 @@ then
 fi
 echo ' ---' `date`: Starting build
 echo ' ---' Kconfig fragment at: $config_template >> $resdir/log
-touch $resdir/ConfigFragment.input $resdir/ConfigFragment
-if test -r "$config_dir/CFcommon"
-then
-	echo " --- $config_dir/CFcommon" >> $resdir/ConfigFragment.input
-	cat < $config_dir/CFcommon >> $resdir/ConfigFragment.input
-	config_override.sh $config_dir/CFcommon $config_template > $T/Kc1
-	grep '#CHECK#' $config_dir/CFcommon >> $resdir/ConfigFragment
-else
-	cp $config_template $T/Kc1
-fi
-echo " --- $config_template" >> $resdir/ConfigFragment.input
-cat $config_template >> $resdir/ConfigFragment.input
-grep '#CHECK#' $config_template >> $resdir/ConfigFragment
-if test -n "$TORTURE_KCONFIG_ARG"
-then
-	echo $TORTURE_KCONFIG_ARG | tr -s " " "\012" > $T/cmdline
-	echo " --- --kconfig argument" >> $resdir/ConfigFragment.input
-	cat $T/cmdline >> $resdir/ConfigFragment.input
-	config_override.sh $T/Kc1 $T/cmdline > $T/Kc2
-	# Note that "#CHECK#" is not permitted on commandline.
-else
-	cp $T/Kc1 $T/Kc2
-fi
-cat $T/Kc2 >> $resdir/ConfigFragment
+touch $resdir/ConfigFragment.input
+
+# Combine additional Kconfig options into an existing set such that
+# newer options win.  The first argument is the Kconfig source ID, the
+# second the to-be-updated file within $T, and the third and final the
+# list of additional Kconfig options.  Note that a $2.tmp file is
+# created when doing the update.
+config_override_param () {
+	if test -n "$3"
+	then
+		echo $3 | sed -e 's/^ *//' -e 's/ *$//' | tr -s " " "\012" > $T/Kconfig_args
+		echo " --- $1" >> $resdir/ConfigFragment.input
+		cat $T/Kconfig_args >> $resdir/ConfigFragment.input
+		config_override.sh $T/$2 $T/Kconfig_args > $T/$2.tmp
+		mv $T/$2.tmp $T/$2
+		# Note that "#CHECK#" is not permitted on commandline.
+	fi
+}
+
+echo > $T/KcList
+config_override_param "$config_dir/CFcommon" KcList "`cat $config_dir/CFcommon 2> /dev/null`"
+config_override_param "$config_template" KcList "`cat $config_template 2> /dev/null`"
+config_override_param "--kasan options" KcList "$TORTURE_KCONFIG_KASAN_ARG"
+config_override_param "--kcsan options" KcList "$TORTURE_KCONFIG_KCSAN_ARG"
+config_override_param "--kconfig argument" KcList "$TORTURE_KCONFIG_ARG"
+cp $T/KcList $resdir/ConfigFragment
 
 base_resdir=`echo $resdir | sed -e 's/\.[0-9]\+$//'`
 if test "$base_resdir" != "$resdir" -a -f $base_resdir/bzImage -a -f $base_resdir/vmlinux
@@ -80,7 +82,7 @@ then
 	ln -s $base_resdir/.config $resdir  # for kvm-recheck.sh
 	# Arch-independent indicator
 	touch $resdir/builtkernel
-elif kvm-build.sh $T/Kc2 $resdir
+elif kvm-build.sh $T/KcList $resdir
 then
 	# Had to build a kernel for this test.
 	QEMU="`identify_qemu vmlinux`"
diff --git a/tools/testing/selftests/rcutorture/bin/kvm.sh b/tools/testing/selftests/rcutorture/bin/kvm.sh
index 2315e2ec12d6..c279cf9cb010 100755
--- a/tools/testing/selftests/rcutorture/bin/kvm.sh
+++ b/tools/testing/selftests/rcutorture/bin/kvm.sh
@@ -31,6 +31,8 @@ TORTURE_DEFCONFIG=defconfig
 TORTURE_BOOT_IMAGE=""
 TORTURE_INITRD="$KVM/initrd"; export TORTURE_INITRD
 TORTURE_KCONFIG_ARG=""
+TORTURE_KCONFIG_KASAN_ARG=""
+TORTURE_KCONFIG_KCSAN_ARG=""
 TORTURE_KMAKE_ARG=""
 TORTURE_QEMU_MEM=512
 TORTURE_SHUTDOWN_GRACE=180
@@ -133,6 +135,12 @@ do
 		TORTURE_KCONFIG_ARG="$2"
 		shift
 		;;
+	--kasan)
+		TORTURE_KCONFIG_KASAN_ARG="CONFIG_DEBUG_INFO=y CONFIG_KASAN=y"; export TORTURE_KCONFIG_KASAN_ARG
+		;;
+	--kcsan)
+		TORTURE_KCONFIG_KCSAN_ARG="CONFIG_DEBUG_INFO=y CONFIG_KCSAN=y CONFIG_KCSAN_ASSUME_PLAIN_WRITES_ATOMIC=n CONFIG_KCSAN_REPORT_VALUE_CHANGE_ONLY=n CONFIG_KCSAN_REPORT_ONCE_IN_MS=100000 CONFIG_KCSAN_VERBOSE=y CONFIG_KCSAN_INTERRUPT_WATCHER=y"; export TORTURE_KCONFIG_KCSAN_ARG
+		;;
 	--kmake-arg)
 		checkarg --kmake-arg "(kernel make arguments)" $# "$2" '.*' '^error$'
 		TORTURE_KMAKE_ARG="$2"
@@ -310,6 +318,8 @@ TORTURE_BUILDONLY="$TORTURE_BUILDONLY"; export TORTURE_BUILDONLY
 TORTURE_DEFCONFIG="$TORTURE_DEFCONFIG"; export TORTURE_DEFCONFIG
 TORTURE_INITRD="$TORTURE_INITRD"; export TORTURE_INITRD
 TORTURE_KCONFIG_ARG="$TORTURE_KCONFIG_ARG"; export TORTURE_KCONFIG_ARG
+TORTURE_KCONFIG_KASAN_ARG="$TORTURE_KCONFIG_KASAN_ARG"; export TORTURE_KCONFIG_KASAN_ARG
+TORTURE_KCONFIG_KCSAN_ARG="$TORTURE_KCONFIG_KCSAN_ARG"; export TORTURE_KCONFIG_KCSAN_ARG
 TORTURE_KMAKE_ARG="$TORTURE_KMAKE_ARG"; export TORTURE_KMAKE_ARG
 TORTURE_QEMU_CMD="$TORTURE_QEMU_CMD"; export TORTURE_QEMU_CMD
 TORTURE_QEMU_INTERACTIVE="$TORTURE_QEMU_INTERACTIVE"; export TORTURE_QEMU_INTERACTIVE
@@ -464,6 +474,7 @@ echo
 echo
 echo " --- `date` Test summary:"
 echo Results directory: $resdir/$ds
+kcsan-collapse.sh $resdir/$ds
 kvm-recheck.sh $resdir/$ds
 ___EOF___
 
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/CFLIST b/tools/testing/selftests/rcutorture/configs/rcu/CFLIST
index c3c1fb5a9e1f..f2b20db9e296 100644
--- a/tools/testing/selftests/rcutorture/configs/rcu/CFLIST
+++ b/tools/testing/selftests/rcutorture/configs/rcu/CFLIST
@@ -14,3 +14,6 @@ TINY02
 TASKS01
 TASKS02
 TASKS03
+RUDE01
+TRACE01
+TRACE02
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/RUDE01 b/tools/testing/selftests/rcutorture/configs/rcu/RUDE01
new file mode 100644
index 000000000000..bafe94cbd739
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/configs/rcu/RUDE01
@@ -0,0 +1,10 @@
+CONFIG_SMP=y
+CONFIG_NR_CPUS=2
+CONFIG_HOTPLUG_CPU=y
+CONFIG_PREEMPT_NONE=n
+CONFIG_PREEMPT_VOLUNTARY=n
+CONFIG_PREEMPT=y
+CONFIG_DEBUG_LOCK_ALLOC=y
+CONFIG_PROVE_LOCKING=y
+#CHECK#CONFIG_PROVE_RCU=y
+CONFIG_RCU_EXPERT=y
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/RUDE01.boot b/tools/testing/selftests/rcutorture/configs/rcu/RUDE01.boot
new file mode 100644
index 000000000000..9363708c9075
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/configs/rcu/RUDE01.boot
@@ -0,0 +1 @@
+rcutorture.torture_type=tasks-rude
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TRACE01 b/tools/testing/selftests/rcutorture/configs/rcu/TRACE01
new file mode 100644
index 000000000000..12e7661b86f5
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/configs/rcu/TRACE01
@@ -0,0 +1,11 @@
+CONFIG_SMP=y
+CONFIG_NR_CPUS=4
+CONFIG_HOTPLUG_CPU=y
+CONFIG_PREEMPT_NONE=y
+CONFIG_PREEMPT_VOLUNTARY=n
+CONFIG_PREEMPT=n
+CONFIG_DEBUG_LOCK_ALLOC=y
+CONFIG_PROVE_LOCKING=y
+#CHECK#CONFIG_PROVE_RCU=y
+CONFIG_TASKS_TRACE_RCU_READ_MB=y
+CONFIG_RCU_EXPERT=y
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TRACE01.boot b/tools/testing/selftests/rcutorture/configs/rcu/TRACE01.boot
new file mode 100644
index 000000000000..9675ad632dcc
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/configs/rcu/TRACE01.boot
@@ -0,0 +1 @@
+rcutorture.torture_type=tasks-tracing
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TRACE02 b/tools/testing/selftests/rcutorture/configs/rcu/TRACE02
new file mode 100644
index 000000000000..b69ed6673c41
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/configs/rcu/TRACE02
@@ -0,0 +1,11 @@
+CONFIG_SMP=y
+CONFIG_NR_CPUS=4
+CONFIG_HOTPLUG_CPU=y
+CONFIG_PREEMPT_NONE=n
+CONFIG_PREEMPT_VOLUNTARY=n
+CONFIG_PREEMPT=y
+CONFIG_DEBUG_LOCK_ALLOC=n
+CONFIG_PROVE_LOCKING=n
+#CHECK#CONFIG_PROVE_RCU=n
+CONFIG_TASKS_TRACE_RCU_READ_MB=n
+CONFIG_RCU_EXPERT=y
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TRACE02.boot b/tools/testing/selftests/rcutorture/configs/rcu/TRACE02.boot
new file mode 100644
index 000000000000..9675ad632dcc
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/configs/rcu/TRACE02.boot
@@ -0,0 +1 @@
+rcutorture.torture_type=tasks-tracing
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TREE10 b/tools/testing/selftests/rcutorture/configs/rcu/TREE10
index 2debe7891aeb..7311f84a5876 100644
--- a/tools/testing/selftests/rcutorture/configs/rcu/TREE10
+++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE10
@@ -1,5 +1,5 @@
 CONFIG_SMP=y
-CONFIG_NR_CPUS=100
+CONFIG_NR_CPUS=56
 CONFIG_PREEMPT_NONE=y
 CONFIG_PREEMPT_VOLUNTARY=n
 CONFIG_PREEMPT=n
diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c
index 89fb3e0b552e..c0aa46ce14f6 100644
--- a/tools/testing/selftests/seccomp/seccomp_bpf.c
+++ b/tools/testing/selftests/seccomp/seccomp_bpf.c
@@ -2803,12 +2803,13 @@ TEST(syscall_restart)
 			 offsetof(struct seccomp_data, nr)),
 
 #ifdef __NR_sigreturn
-		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_sigreturn, 6, 0),
+		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_sigreturn, 7, 0),
 #endif
-		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_read, 5, 0),
-		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_exit, 4, 0),
-		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_rt_sigreturn, 3, 0),
-		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_nanosleep, 4, 0),
+		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_read, 6, 0),
+		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_exit, 5, 0),
+		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_rt_sigreturn, 4, 0),
+		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_nanosleep, 5, 0),
+		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_clock_nanosleep, 4, 0),
 		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_restart_syscall, 4, 0),
 
 		/* Allow __NR_write for easy logging. */
@@ -2895,7 +2896,8 @@ TEST(syscall_restart)
 	ASSERT_EQ(PTRACE_EVENT_SECCOMP, (status >> 16));
 	ASSERT_EQ(0, ptrace(PTRACE_GETEVENTMSG, child_pid, NULL, &msg));
 	ASSERT_EQ(0x100, msg);
-	EXPECT_EQ(__NR_nanosleep, get_syscall(_metadata, child_pid));
+	ret = get_syscall(_metadata, child_pid);
+	EXPECT_TRUE(ret == __NR_nanosleep || ret == __NR_clock_nanosleep);
 
 	/* Might as well check siginfo for sanity while we're here. */
 	ASSERT_EQ(0, ptrace(PTRACE_GETSIGINFO, child_pid, NULL, &info));
diff --git a/tools/testing/selftests/tc-testing/tdc.py b/tools/testing/selftests/tc-testing/tdc.py
index e566c70e64a1..a3e43189d940 100755
--- a/tools/testing/selftests/tc-testing/tdc.py
+++ b/tools/testing/selftests/tc-testing/tdc.py
@@ -713,9 +713,8 @@ def set_operation_mode(pm, parser, args, remaining):
         exit(0)
 
     if args.list:
-        if args.list:
-            list_test_cases(alltests)
-            exit(0)
+        list_test_cases(alltests)
+        exit(0)
 
     if len(alltests):
         req_plugins = pm.get_required_plugins(alltests)
diff --git a/tools/testing/selftests/tpm2/test_smoke.sh b/tools/testing/selftests/tpm2/test_smoke.sh
index b630c7b5950a..8155c2ea7ccb 100755
--- a/tools/testing/selftests/tpm2/test_smoke.sh
+++ b/tools/testing/selftests/tpm2/test_smoke.sh
@@ -1,17 +1,8 @@
 #!/bin/bash
 # SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
-self.flags = flags
 
-# Kselftest framework requirement - SKIP code is 4.
-ksft_skip=4
-
-
-if [ -f /dev/tpm0 ] ; then
-	python -m unittest -v tpm2_tests.SmokeTest
-	python -m unittest -v tpm2_tests.AsyncTest
-else
-	exit $ksft_skip
-fi
+python -m unittest -v tpm2_tests.SmokeTest
+python -m unittest -v tpm2_tests.AsyncTest
 
 CLEAR_CMD=$(which tpm2_clear)
 if [ -n $CLEAR_CMD ]; then
diff --git a/tools/testing/selftests/tpm2/test_space.sh b/tools/testing/selftests/tpm2/test_space.sh
index 180b469c53b4..a6f5e346635e 100755
--- a/tools/testing/selftests/tpm2/test_space.sh
+++ b/tools/testing/selftests/tpm2/test_space.sh
@@ -1,11 +1,4 @@
 #!/bin/bash
 # SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
 
-# Kselftest framework requirement - SKIP code is 4.
-ksft_skip=4
-
-if [ -f /dev/tpmrm0 ] ; then
-	python -m unittest -v tpm2_tests.SpaceTest
-else
-	exit $ksft_skip
-fi
+python -m unittest -v tpm2_tests.SpaceTest
diff --git a/tools/testing/selftests/vm/Makefile b/tools/testing/selftests/vm/Makefile
index d31db052dff6..6998877f707e 100644
--- a/tools/testing/selftests/vm/Makefile
+++ b/tools/testing/selftests/vm/Makefile
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 # Makefile for vm selftests
 uname_M := $(shell uname -m 2>/dev/null || echo not)
-ARCH ?= $(shell echo $(uname_M) | sed -e 's/aarch64.*/arm64/')
+MACHINE ?= $(shell echo $(uname_M) | sed -e 's/aarch64.*/arm64/')
 
 CFLAGS = -Wall -I ../../../../usr/include $(EXTRA_CFLAGS)
 LDLIBS = -lrt
@@ -20,7 +20,7 @@ TEST_GEN_FILES += thuge-gen
 TEST_GEN_FILES += transhuge-stress
 TEST_GEN_FILES += userfaultfd
 
-ifneq (,$(filter $(ARCH),arm64 ia64 mips64 parisc64 ppc64 riscv64 s390x sh64 sparc64 x86_64))
+ifneq (,$(filter $(MACHINE),arm64 ia64 mips64 parisc64 ppc64 ppc64le riscv64 s390x sh64 sparc64 x86_64))
 TEST_GEN_FILES += va_128TBswitch
 TEST_GEN_FILES += virtual_address_range
 TEST_GEN_FILES += write_to_hugetlbfs
diff --git a/tools/testing/selftests/vm/run_vmtests b/tools/testing/selftests/vm/run_vmtests
index 665009ebfba4..76ca5e7a3951 100755
--- a/tools/testing/selftests/vm/run_vmtests
+++ b/tools/testing/selftests/vm/run_vmtests
@@ -59,7 +59,7 @@ else
 fi
 
 #filter 64bit architectures
-ARCH64STR="arm64 ia64 mips64 parisc64 ppc64 riscv64 s390x sh64 sparc64 x86_64"
+ARCH64STR="arm64 ia64 mips64 parisc64 ppc64 ppc64le riscv64 s390x sh64 sparc64 x86_64"
 if [ -z $ARCH ]; then
   ARCH=`uname -m 2>/dev/null | sed -e 's/aarch64.*/arm64/'`
 fi
diff --git a/tools/testing/selftests/wireguard/qemu/debug.config b/tools/testing/selftests/wireguard/qemu/debug.config
index 5909e7ef2a5c..807fa7dc60b8 100644
--- a/tools/testing/selftests/wireguard/qemu/debug.config
+++ b/tools/testing/selftests/wireguard/qemu/debug.config
@@ -58,7 +58,6 @@ CONFIG_RCU_EQS_DEBUG=y
 CONFIG_USER_STACKTRACE_SUPPORT=y
 CONFIG_DEBUG_SG=y
 CONFIG_DEBUG_NOTIFIERS=y
-CONFIG_DOUBLEFAULT=y
 CONFIG_X86_DEBUG_FPU=y
 CONFIG_DEBUG_SECTION_MISMATCH=y
 CONFIG_DEBUG_PAGEALLOC=y
diff --git a/tools/virtio/Makefile b/tools/virtio/Makefile
index f33f32f1d208..b587b9a7a124 100644
--- a/tools/virtio/Makefile
+++ b/tools/virtio/Makefile
@@ -4,7 +4,7 @@ test: virtio_test vringh_test
 virtio_test: virtio_ring.o virtio_test.o
 vringh_test: vringh_test.o vringh.o virtio_ring.o
 
-CFLAGS += -g -O2 -Werror -Wall -I. -I../include/ -I ../../usr/include/ -Wno-pointer-sign -fno-strict-overflow -fno-strict-aliasing -fno-common -MMD -U_FORTIFY_SOURCE
+CFLAGS += -g -O2 -Werror -Wall -I. -I../include/ -I ../../usr/include/ -Wno-pointer-sign -fno-strict-overflow -fno-strict-aliasing -fno-common -MMD -U_FORTIFY_SOURCE -include ../../include/linux/kconfig.h
 vpath %.c ../../drivers/virtio ../../drivers/vhost
 mod:
 	${MAKE} -C `pwd`/../.. M=`pwd`/vhost_test V=${V}
@@ -22,7 +22,8 @@ OOT_CONFIGS=\
 	CONFIG_VHOST=m \
 	CONFIG_VHOST_NET=n \
 	CONFIG_VHOST_SCSI=n \
-	CONFIG_VHOST_VSOCK=n
+	CONFIG_VHOST_VSOCK=n \
+	CONFIG_VHOST_RING=n
 OOT_BUILD=KCFLAGS="-I "${OOT_VHOST} ${MAKE} -C ${OOT_KSRC} V=${V}
 oot-build:
 	echo "UNSUPPORTED! Don't use the resulting modules in production!"
diff --git a/tools/virtio/asm/barrier.h b/tools/virtio/asm/barrier.h
index d0351f83aebe..04d563fc9b95 100644
--- a/tools/virtio/asm/barrier.h
+++ b/tools/virtio/asm/barrier.h
@@ -1,4 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0 */
+#include <stdlib.h>
 #if defined(__i386__) || defined(__x86_64__)
 #define barrier() asm volatile("" ::: "memory")
 #define virt_mb() __sync_synchronize()
diff --git a/tools/virtio/generated/autoconf.h b/tools/virtio/generated/autoconf.h
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/tools/virtio/linux/compiler.h b/tools/virtio/linux/compiler.h
index 903dc9c4bd11..2c51bccb97bb 100644
--- a/tools/virtio/linux/compiler.h
+++ b/tools/virtio/linux/compiler.h
@@ -7,4 +7,5 @@
 
 #define READ_ONCE(var) (*((volatile typeof(var) *)(&(var))))
 
+#define __aligned(x) __attribute((__aligned__(x)))
 #endif
